jsii-docgen
Version:
generates api docs for jsii modules
583 lines • 81.3 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.defaultTypeFormatter = exports.defaultLinkFormatter = exports.defaultAnchorFormatter = exports.MarkdownRenderer = void 0;
const markdown_doc_1 = require("./markdown-doc");
const schema_1 = require("../schema");
const transpile_1 = require("../transpile/transpile");
/**
* Generates `MarkdownDocument` instances from `API.json` or its parts.
*
* This class can be used in two ways:
*
* 1. Instantiate it via the constructor with `options`, which requires
* passing in some global context about the module and language you are
* generated for. (This context can be found in the top-level `metadata`
* field of API.json.) Then, call a `visitXxx` method to generate a
* `MarkdownDocument` for the appropriate part of the schema.
*
* 2. Generate a `MarkdownDocument` from the complete `API.json` using the
* `fromSchema` static method (no instantiation needed). Global context is
* automatically inferred from the API.json.
*
* Both choices allow customizing the output via `MarkdownFormattingOptions`.
*/
class MarkdownRenderer {
static fromSchema(schema, options) {
const documentation = new markdown_doc_1.MarkdownDocument();
if (schema.version !== schema_1.CURRENT_SCHEMA_VERSION) {
throw new Error(`Unexpected schema version: ${schema.version}`);
}
if (schema.readme) {
const md = new markdown_doc_1.MarkdownDocument();
md.lines(schema.readme);
documentation.section(md);
}
if (schema.apiReference) {
const renderer = new MarkdownRenderer({
anchorFormatter: options.anchorFormatter,
linkFormatter: options.linkFormatter,
typeFormatter: options.typeFormatter,
language: transpile_1.Language.fromString(schema.language),
...schema.metadata,
});
documentation.section(renderer.visitApiReference(schema.apiReference, options.header));
}
return documentation;
}
static fromSubmodules(submodules, fileSuffix, options) {
const documentation = new markdown_doc_1.MarkdownDocument();
const renderer = new MarkdownRenderer({
anchorFormatter: options.anchorFormatter,
linkFormatter: options.linkFormatter,
typeFormatter: options.typeFormatter,
language: options.language,
packageName: options.packageName,
packageVersion: options.packageVersion,
});
const apiRef = renderer.visitSubmodules(submodules, fileSuffix);
documentation.section(apiRef);
return documentation;
}
constructor(options) {
var _a, _b, _c;
this.anchorFormatter = (_a = options.anchorFormatter) !== null && _a !== void 0 ? _a : exports.defaultAnchorFormatter;
this.linkFormatter = (_b = options.linkFormatter) !== null && _b !== void 0 ? _b : exports.defaultLinkFormatter;
this.typeFormatter = (_c = options.typeFormatter) !== null && _c !== void 0 ? _c : exports.defaultTypeFormatter;
this.language = options.language;
this.metadata = {
packageName: options.packageName,
packageVersion: options.packageVersion,
submodule: options.submodule,
};
}
visitSubmodules(submodules, fileSuffix) {
const md = new markdown_doc_1.MarkdownDocument({ header: { title: 'Submodules' }, id: 'submodules' });
md.lines('The following submodules are available:');
md.lines('');
for (const submodule of submodules) {
md.lines(`- [${(0, transpile_1.submoduleRelName)(submodule)}](./${(0, transpile_1.submoduleRelName)(submodule)}.${fileSuffix})`);
}
md.lines('');
return md;
}
visitApiReference(apiRef, header = { title: 'API Reference', id: 'api-reference' }) {
const md = new markdown_doc_1.MarkdownDocument({ header: { title: header.title }, id: header.id });
md.section(this.visitConstructs(apiRef.constructs));
md.section(this.visitStructs(apiRef.structs));
md.section(this.visitClasses(apiRef.classes));
md.section(this.visitInterfaces(apiRef.interfaces));
md.section(this.visitEnums(apiRef.enums));
return md;
}
visitConstructs(constructs) {
if (constructs.length === 0) {
return markdown_doc_1.MarkdownDocument.EMPTY;
}
const md = new markdown_doc_1.MarkdownDocument({ header: { title: 'Constructs' } });
for (const construct of constructs) {
md.section(this.visitConstruct(construct));
}
return md;
}
visitStructs(structs) {
if (structs.length === 0) {
return markdown_doc_1.MarkdownDocument.EMPTY;
}
const md = new markdown_doc_1.MarkdownDocument({ header: { title: 'Structs' } });
for (const struct of structs) {
md.section(this.visitStruct(struct));
}
return md;
}
visitClasses(classes) {
if (classes.length === 0) {
return markdown_doc_1.MarkdownDocument.EMPTY;
}
const md = new markdown_doc_1.MarkdownDocument({ header: { title: 'Classes' } });
for (const klass of classes) {
md.section(this.visitClass(klass));
}
return md;
}
visitInterfaces(ifaces) {
if (ifaces.length === 0) {
return markdown_doc_1.MarkdownDocument.EMPTY;
}
const md = new markdown_doc_1.MarkdownDocument({ header: { title: 'Protocols' } });
for (const iface of ifaces) {
md.section(this.visitInterface(iface));
}
return md;
}
visitEnums(enums) {
if (enums.length === 0) {
return markdown_doc_1.MarkdownDocument.EMPTY;
}
const md = new markdown_doc_1.MarkdownDocument({ header: { title: 'Enums' } });
for (const enu of enums) {
md.section(this.visitEnum(enu));
}
return md;
}
visitConstruct(construct) {
return this.visitClass(construct);
}
visitStruct(struct) {
const md = new markdown_doc_1.MarkdownDocument({
id: this.anchorFormatter({
id: struct.id,
displayName: struct.displayName,
fqn: struct.fqn,
...this.metadata,
}),
header: { title: struct.displayName },
});
if (struct.docs) {
md.docs(struct.docs, this.language);
}
const initializer = new markdown_doc_1.MarkdownDocument({
id: this.anchorFormatter({
id: `${struct.id}.Initializer`,
displayName: 'Initializer',
fqn: `${struct.fqn}.Initializer`,
...this.metadata,
}),
header: { title: 'Initializer' },
});
if (struct.usage) {
initializer.code(this.language.toString(), struct.usage);
}
md.section(initializer);
md.section(this.visitProperties(struct.properties));
return md;
}
visitClass(klass) {
const md = new markdown_doc_1.MarkdownDocument({
id: this.anchorFormatter({
id: klass.id,
displayName: klass.displayName,
fqn: klass.fqn,
...this.metadata,
}),
header: { title: klass.displayName },
});
if (klass.interfaces.length > 0) {
const ifaces = [];
for (const iface of klass.interfaces) {
ifaces.push(this.linkFormatter(iface, this.metadata));
}
md.bullet(`${markdown_doc_1.MarkdownDocument.italic('Implements:')} ${ifaces.join(', ')}`);
md.lines('');
}
if (klass.docs) {
md.docs(klass.docs, this.language);
}
if (klass.initializer) {
md.section(this.visitInitializer(klass.initializer));
}
md.section(this.visitInstanceMethods(klass.instanceMethods));
md.section(this.visitStaticFunctions(klass.staticMethods));
md.section(this.visitProperties(klass.properties));
md.section(this.visitConstants(klass.constants));
return md;
}
visitInterface(iface) {
const md = new markdown_doc_1.MarkdownDocument({
id: this.anchorFormatter({
id: iface.id,
displayName: iface.displayName,
fqn: iface.fqn,
...this.metadata,
}),
header: { title: iface.displayName },
});
if (iface.interfaces.length > 0) {
const bases = [];
for (const base of iface.interfaces) {
bases.push(this.linkFormatter(base, this.metadata));
}
md.bullet(`${markdown_doc_1.MarkdownDocument.italic('Extends:')} ${bases.join(', ')}`);
md.lines('');
}
if (iface.implementations.length > 0) {
const impls = [];
for (const impl of iface.implementations) {
impls.push(this.linkFormatter(impl, this.metadata));
}
md.bullet(`${markdown_doc_1.MarkdownDocument.italic('Implemented By:')} ${impls.join(', ')}`);
md.lines('');
}
if (iface.docs) {
md.docs(iface.docs, this.language);
}
md.section(this.visitInstanceMethods(iface.instanceMethods));
md.section(this.visitProperties(iface.properties));
return md;
}
visitEnum(enu) {
const md = new markdown_doc_1.MarkdownDocument({
id: this.anchorFormatter({
id: enu.id,
displayName: enu.displayName,
fqn: enu.fqn,
...this.metadata,
}),
header: { title: enu.displayName },
});
if (enu.docs) {
md.docs(enu.docs, this.language);
}
md.section(this.visitEnumMembers(enu.members));
return md;
}
visitEnumMembers(enus) {
if (enus.length === 0) {
return markdown_doc_1.MarkdownDocument.EMPTY;
}
const md = new markdown_doc_1.MarkdownDocument({ header: { title: 'Members' } });
md.table(this.createTable(enus));
md.split();
for (const enu of enus) {
md.section(this.visitEnumMember(enu));
}
return md;
}
visitProperties(properties) {
if (properties.length === 0) {
return markdown_doc_1.MarkdownDocument.EMPTY;
}
const md = new markdown_doc_1.MarkdownDocument({ header: { title: 'Properties' } });
md.table(this.createTableWithTypes(properties));
md.split();
for (const prop of properties) {
md.section(this.visitProperty(prop));
}
return md;
}
visitInitializer(init) {
const md = new markdown_doc_1.MarkdownDocument({
id: this.anchorFormatter({
id: init.id,
displayName: init.displayName,
fqn: init.fqn,
...this.metadata,
}),
header: {
title: 'Initializers',
},
});
if (init.usage) {
md.code(this.language.toString(), init.usage);
}
md.table(this.createTableWithTypes(init.parameters));
md.split();
for (const param of init.parameters) {
md.section(this.visitParameter(param));
}
return md;
}
visitInstanceMethods(methods) {
if (methods.length === 0) {
return markdown_doc_1.MarkdownDocument.EMPTY;
}
const md = new markdown_doc_1.MarkdownDocument({ header: { title: 'Methods' } });
md.table(this.createTable(methods));
md.split();
for (const method of methods) {
md.section(this.visitInstanceMethod(method));
}
return md;
}
visitStaticFunctions(methods) {
if (methods.length === 0) {
return markdown_doc_1.MarkdownDocument.EMPTY;
}
const md = new markdown_doc_1.MarkdownDocument({ header: { title: 'Static Functions' } });
md.table(this.createTable(methods));
md.split();
for (const method of methods) {
md.section(this.visitStaticFunction(method));
}
return md;
}
visitConstants(constants) {
if (constants.length === 0) {
return markdown_doc_1.MarkdownDocument.EMPTY;
}
const md = new markdown_doc_1.MarkdownDocument({ header: { title: 'Constants' } });
md.table(this.createTableWithTypes(constants));
md.split();
for (const con of constants) {
md.section(this.visitConstant(con));
}
return md;
}
visitEnumMember(em) {
const md = new markdown_doc_1.MarkdownDocument({
id: this.anchorFormatter({
id: em.id,
displayName: em.displayName,
fqn: em.fqn,
...this.metadata,
}),
header: {
title: em.displayName,
pre: true,
strike: em.docs.deprecated,
},
});
if (em.docs.deprecated) {
md.bullet(`${markdown_doc_1.MarkdownDocument.italic('Deprecated:')} ${em.docs.deprecationReason}`);
md.lines('');
}
if (em.docs) {
md.docs(em.docs, this.language);
}
md.split();
md.lines('');
return md;
}
visitProperty(prop) {
const optionality = prop.optional
? 'Optional'
: 'Required';
const md = new markdown_doc_1.MarkdownDocument({
id: this.anchorFormatter({
id: prop.id,
displayName: prop.displayName,
fqn: prop.fqn,
...this.metadata,
}),
header: {
title: prop.displayName,
sup: optionality,
pre: true,
strike: prop.docs.deprecated,
},
});
if (prop.docs.deprecated) {
md.bullet(`${markdown_doc_1.MarkdownDocument.italic('Deprecated:')} ${prop.docs.deprecationReason}`);
md.lines('');
}
if (prop.usage) {
md.code(this.language.toString(), prop.usage);
}
const metadata = {
Type: this.typeFormatter(prop.type, this.metadata, this.linkFormatter),
};
if (prop.default) {
const sanitized = markdown_doc_1.MarkdownDocument.sanitize(prop.default);
metadata.Default = markdown_doc_1.MarkdownDocument.removeNewlines(sanitized);
}
for (const [key, value] of Object.entries(metadata)) {
md.bullet(`${markdown_doc_1.MarkdownDocument.italic(`${key}:`)} ${value}`);
}
md.lines('');
if (prop.docs) {
md.docs(prop.docs, this.language);
}
md.split();
return md;
}
visitParameter(parameter) {
const optionality = parameter.optional ? 'Optional' : 'Required';
const md = new markdown_doc_1.MarkdownDocument({
id: this.anchorFormatter({
id: parameter.id,
displayName: parameter.displayName,
fqn: parameter.fqn,
...this.metadata,
}),
header: {
title: parameter.displayName,
sup: optionality,
pre: true,
strike: parameter.docs.deprecated,
},
});
if (parameter.docs.deprecated) {
md.bullet(`${markdown_doc_1.MarkdownDocument.italic('Deprecated:')} ${parameter.docs.deprecationReason}`);
md.lines('');
}
const metadata = {
Type: this.typeFormatter(parameter.type, this.metadata, this.linkFormatter),
};
if (parameter.default) {
const sanitized = markdown_doc_1.MarkdownDocument.sanitize(parameter.default);
metadata.Default = markdown_doc_1.MarkdownDocument.removeNewlines(sanitized);
}
for (const [key, value] of Object.entries(metadata)) {
md.bullet(`${markdown_doc_1.MarkdownDocument.italic(`${key}:`)} ${value}`);
}
md.lines('');
if (parameter.docs) {
md.docs(parameter.docs, this.language);
}
md.split();
return md;
}
visitInstanceMethod(method) {
const md = new markdown_doc_1.MarkdownDocument({
id: this.anchorFormatter({
id: method.id,
displayName: method.displayName,
fqn: method.fqn,
...this.metadata,
}),
header: {
title: method.displayName,
pre: true,
strike: method.docs.deprecated,
},
});
if (method.usage) {
md.code(this.language.toString(), method.usage);
}
if (method.docs) {
md.docs(method.docs, this.language);
}
for (const param of method.parameters) {
md.section(this.visitParameter(param));
}
return md;
}
visitStaticFunction(method) {
const md = new markdown_doc_1.MarkdownDocument({
id: this.anchorFormatter({
id: method.id,
displayName: method.displayName,
fqn: method.fqn,
...this.metadata,
}),
header: {
title: method.displayName,
pre: true,
strike: method.docs.deprecated,
},
});
if (method.usage) {
md.code(this.language.toString(), method.usage);
}
if (method.docs) {
md.docs(method.docs, this.language);
}
for (const param of method.parameters) {
md.section(this.visitParameter(param));
}
return md;
}
visitConstant(constant) {
return this.visitProperty(constant);
}
createTable(items) {
var _a, _b, _c;
const tableRows = [];
tableRows.push(['Name', 'Description'].map(markdown_doc_1.MarkdownDocument.bold));
for (const item of items) {
const link = markdown_doc_1.MarkdownDocument.pre(this.linkFormatter({
fqn: item.fqn,
displayName: item.displayName,
id: item.id,
...this.metadata,
}, this.metadata));
const description = ((_a = item.docs) === null || _a === void 0 ? void 0 : _a.summary) && ((_b = item.docs) === null || _b === void 0 ? void 0 : _b.summary.length) > 0
? (_c = item.docs) === null || _c === void 0 ? void 0 : _c.summary
: markdown_doc_1.MarkdownDocument.italic('No description.');
tableRows.push([link, description]);
}
return tableRows;
}
createTableWithTypes(items) {
var _a, _b, _c;
const tableRows = [];
tableRows.push(['Name', 'Type', 'Description'].map(markdown_doc_1.MarkdownDocument.bold));
for (const item of items) {
const link = markdown_doc_1.MarkdownDocument.pre(this.linkFormatter({
fqn: item.fqn,
displayName: item.displayName,
id: item.id,
...this.metadata,
}, this.metadata));
const type = markdown_doc_1.MarkdownDocument.pre(this.typeFormatter(item.type, this.metadata, this.linkFormatter));
const description = ((_a = item.docs) === null || _a === void 0 ? void 0 : _a.summary) && ((_b = item.docs) === null || _b === void 0 ? void 0 : _b.summary.length) > 0
? (_c = item.docs) === null || _c === void 0 ? void 0 : _c.summary
: markdown_doc_1.MarkdownDocument.italic('No description.');
tableRows.push([link, type, description]);
}
return tableRows;
}
}
exports.MarkdownRenderer = MarkdownRenderer;
function sanitize(str) {
return str.replace(/ /g, '-');
}
const defaultAnchorFormatter = (type) => {
// HTML5 allows any character in IDs /except/ whitespace
return sanitize(type.id);
};
exports.defaultAnchorFormatter = defaultAnchorFormatter;
const defaultLinkFormatter = (type, metadata) => {
if (type.packageName === metadata.packageName && type.submodule === metadata.submodule) {
return `<a href="#${sanitize(type.id)}">${type.displayName}</a>`;
}
else {
// do not display a link if the type isn't in this document
return type.fqn;
}
};
exports.defaultLinkFormatter = defaultLinkFormatter;
function isJsiiType(value) {
return (value !== null
&& typeof value === 'object'
&& (value === null || value === void 0 ? void 0 : value.fqn)
&& (value === null || value === void 0 ? void 0 : value.id)
&& (value === null || value === void 0 ? void 0 : value.displayName));
}
const defaultTypeFormatter = (type, metadata, linkFormatter) => {
var _a;
let result = type.formattingPattern;
const typeRefs = [];
for (const typeRef of (_a = type.types) !== null && _a !== void 0 ? _a : []) {
if (isJsiiType(typeRef)) {
typeRefs.push(linkFormatter(typeRef, metadata));
}
else {
typeRefs.push((0, exports.defaultTypeFormatter)(typeRef, metadata, linkFormatter));
}
}
// substitute referred types into the original string
const placeholderMatcher = /\%/g;
for (const typeRef of typeRefs) {
const matches = placeholderMatcher.exec(result);
if (!matches) {
// it's possible the number of %'s doesn't match the number of types provided
// e.g. csharp unions are currently rendered to `{ name: 'object', types: [type1, type2] }`
continue;
}
const insertionIdx = matches.index;
result = result.substring(0, insertionIdx) + typeRef + result.substring(insertionIdx + 1);
}
return result;
};
exports.defaultTypeFormatter = defaultTypeFormatter;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWFya2Rvd24tcmVuZGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2RvY2dlbi9yZW5kZXIvbWFya2Rvd24tcmVuZGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUNBLGlEQUFrRDtBQUNsRCxzQ0FBNFI7QUFDNVIsc0RBQW9FO0FBb0VwRTs7Ozs7Ozs7Ozs7Ozs7OztHQWdCRztBQUNILE1BQWEsZ0JBQWdCO0lBQ3BCLE1BQU0sQ0FBQyxVQUFVLENBQUMsTUFBYyxFQUFFLE9BQWtDO1FBQ3pFLE1BQU0sYUFBYSxHQUFHLElBQUksK0JBQWdCLEVBQUUsQ0FBQztRQUU3QyxJQUFJLE1BQU0sQ0FBQyxPQUFPLEtBQUssK0JBQXNCLEVBQUUsQ0FBQztZQUM5QyxNQUFNLElBQUksS0FBSyxDQUFDLDhCQUE4QixNQUFNLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQztRQUNsRSxDQUFDO1FBRUQsSUFBSSxNQUFNLENBQUMsTUFBTSxFQUFFLENBQUM7WUFDbEIsTUFBTSxFQUFFLEdBQUcsSUFBSSwrQkFBZ0IsRUFBRSxDQUFDO1lBQ2xDLEVBQUUsQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQ3hCLGFBQWEsQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDLENBQUM7UUFDNUIsQ0FBQztRQUVELElBQUksTUFBTSxDQUFDLFlBQVksRUFBRSxDQUFDO1lBQ3hCLE1BQU0sUUFBUSxHQUFHLElBQUksZ0JBQWdCLENBQUM7Z0JBQ3BDLGVBQWUsRUFBRSxPQUFPLENBQUMsZUFBZTtnQkFDeEMsYUFBYSxFQUFFLE9BQU8sQ0FBQyxhQUFhO2dCQUNwQyxhQUFhLEVBQUUsT0FBTyxDQUFDLGFBQWE7Z0JBQ3BDLFFBQVEsRUFBRSxvQkFBUSxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDO2dCQUM5QyxHQUFHLE1BQU0sQ0FBQyxRQUFRO2FBQ25CLENBQUMsQ0FBQztZQUVILGFBQWEsQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLGlCQUFpQixDQUFDLE1BQU0sQ0FBQyxZQUFZLEVBQUUsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUM7UUFDekYsQ0FBQztRQUVELE9BQU8sYUFBYSxDQUFDO0lBQ3ZCLENBQUM7SUFFTSxNQUFNLENBQUMsY0FBYyxDQUFDLFVBQXdDLEVBQUUsVUFBa0IsRUFBRSxPQUFnQztRQUN6SCxNQUFNLGFBQWEsR0FBRyxJQUFJLCtCQUFnQixFQUFFLENBQUM7UUFFN0MsTUFBTSxRQUFRLEdBQUcsSUFBSSxnQkFBZ0IsQ0FBQztZQUNwQyxlQUFlLEVBQUUsT0FBTyxDQUFDLGVBQWU7WUFDeEMsYUFBYSxFQUFFLE9BQU8sQ0FBQyxhQUFhO1lBQ3BDLGFBQWEsRUFBRSxPQUFPLENBQUMsYUFBYTtZQUNwQyxRQUFRLEVBQUUsT0FBTyxDQUFDLFFBQVE7WUFDMUIsV0FBVyxFQUFFLE9BQU8sQ0FBQyxXQUFXO1lBQ2hDLGNBQWMsRUFBRSxPQUFPLENBQUMsY0FBYztTQUN2QyxDQUFDLENBQUM7UUFFSCxNQUFNLE1BQU0sR0FBRyxRQUFRLENBQUMsZUFBZSxDQUFDLFVBQVUsRUFBRSxVQUFVLENBQUMsQ0FBQztRQUNoRSxhQUFhLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBRTlCLE9BQU8sYUFBYSxDQUFDO0lBQ3ZCLENBQUM7SUFRRCxZQUFZLE9BQWdDOztRQUMxQyxJQUFJLENBQUMsZUFBZSxHQUFHLE1BQUEsT0FBTyxDQUFDLGVBQWUsbUNBQUksOEJBQXNCLENBQUM7UUFDekUsSUFBSSxDQUFDLGFBQWEsR0FBRyxNQUFBLE9BQU8sQ0FBQyxhQUFhLG1DQUFJLDRCQUFvQixDQUFDO1FBQ25FLElBQUksQ0FBQyxhQUFhLEdBQUcsTUFBQSxPQUFPLENBQUMsYUFBYSxtQ0FBSSw0QkFBb0IsQ0FBQztRQUNuRSxJQUFJLENBQUMsUUFBUSxHQUFHLE9BQU8sQ0FBQyxRQUFRLENBQUM7UUFDakMsSUFBSSxDQUFDLFFBQVEsR0FBRztZQUNkLFdBQVcsRUFBRSxPQUFPLENBQUMsV0FBVztZQUNoQyxjQUFjLEVBQUUsT0FBTyxDQUFDLGNBQWM7WUFDdEMsU0FBUyxFQUFFLE9BQU8sQ0FBQyxTQUFTO1NBQzdCLENBQUM7SUFDSixDQUFDO0lBRU0sZUFBZSxDQUFDLFVBQXdDLEVBQUUsVUFBa0I7UUFDakYsTUFBTSxFQUFFLEdBQUcsSUFBSSwrQkFBZ0IsQ0FBQyxFQUFFLE1BQU0sRUFBRSxFQUFFLEtBQUssRUFBRSxZQUFZLEVBQUUsRUFBRSxFQUFFLEVBQUUsWUFBWSxFQUFFLENBQUMsQ0FBQztRQUN2RixFQUFFLENBQUMsS0FBSyxDQUFDLHlDQUF5QyxDQUFDLENBQUM7UUFDcEQsRUFBRSxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUNiLEtBQUssTUFBTSxTQUFTLElBQUksVUFBVSxFQUFFLENBQUM7WUFDbkMsRUFBRSxDQUFDLEtBQUssQ0FBQyxNQUFNLElBQUEsNEJBQWdCLEVBQUMsU0FBUyxDQUFDLE9BQU8sSUFBQSw0QkFBZ0IsRUFBQyxTQUFTLENBQUMsSUFBSSxVQUFVLEdBQUcsQ0FBQyxDQUFDO1FBQ2pHLENBQUM7UUFDRCxFQUFFLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBQ2IsT0FBTyxFQUFFLENBQUM7SUFDWixDQUFDO0lBRU0saUJBQWlCLENBQ3RCLE1BQTBCLEVBQzFCLFNBQXdDLEVBQUUsS0FBSyxFQUFFLGVBQWUsRUFBRSxFQUFFLEVBQUUsZUFBZSxFQUFFO1FBRXZGLE1BQU0sRUFBRSxHQUFHLElBQUksK0JBQWdCLENBQUMsRUFBRSxNQUFNLEVBQUUsRUFBRSxLQUFLLEVBQUUsTUFBTSxDQUFDLEtBQUssRUFBRSxFQUFFLEVBQUUsRUFBRSxNQUFNLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQztRQUNwRixFQUFFLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxlQUFlLENBQUMsTUFBTSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUM7UUFDcEQsRUFBRSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDO1FBQzlDLEVBQUUsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQztRQUM5QyxFQUFFLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxlQUFlLENBQUMsTUFBTSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUM7UUFDcEQsRUFBRSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO1FBQzFDLE9BQU8sRUFBRSxDQUFDO0lBQ1osQ0FBQztJQUVNLGVBQWUsQ0FDcEIsVUFBNkI7UUFFN0IsSUFBSSxVQUFVLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRSxDQUFDO1lBQzVCLE9BQU8sK0JBQWdCLENBQUMsS0FBSyxDQUFDO1FBQ2hDLENBQUM7UUFFRCxNQUFNLEVBQUUsR0FBRyxJQUFJLCtCQUFnQixDQUFDLEVBQUUsTUFBTSxFQUFFLEVBQUUsS0FBSyxFQUFFLFlBQVksRUFBRSxFQUFFLENBQUMsQ0FBQztRQUNyRSxLQUFLLE1BQU0sU0FBUyxJQUFJLFVBQVUsRUFBRSxDQUFDO1lBQ25DLEVBQUUsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDO1FBQzdDLENBQUM7UUFDRCxPQUFPLEVBQUUsQ0FBQztJQUNaLENBQUM7SUFFTSxZQUFZLENBQ2pCLE9BQXVCO1FBRXZCLElBQUksT0FBTyxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUUsQ0FBQztZQUN6QixPQUFPLCtCQUFnQixDQUFDLEtBQUssQ0FBQztRQUNoQyxDQUFDO1FBRUQsTUFBTSxFQUFFLEdBQUcsSUFBSSwrQkFBZ0IsQ0FBQyxFQUFFLE1BQU0sRUFBRSxFQUFFLEtBQUssRUFBRSxTQUFTLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFDbEUsS0FBSyxNQUFNLE1BQU0sSUFBSSxPQUFPLEVBQUUsQ0FBQztZQUM3QixFQUFFLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQztRQUN2QyxDQUFDO1FBQ0QsT0FBTyxFQUFFLENBQUM7SUFDWixDQUFDO0lBRU0sWUFBWSxDQUNqQixPQUFzQjtRQUV0QixJQUFJLE9BQU8sQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFLENBQUM7WUFDekIsT0FBTywrQkFBZ0IsQ0FBQyxLQUFLLENBQUM7UUFDaEMsQ0FBQztRQUVELE1BQU0sRUFBRSxHQUFHLElBQUksK0JBQWdCLENBQUMsRUFBRSxNQUFNLEVBQUUsRUFBRSxLQUFLLEVBQUUsU0FBUyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBQ2xFLEtBQUssTUFBTSxLQUFLLElBQUksT0FBTyxFQUFFLENBQUM7WUFDNUIsRUFBRSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUM7UUFDckMsQ0FBQztRQUNELE9BQU8sRUFBRSxDQUFDO0lBQ1osQ0FBQztJQUVNLGVBQWUsQ0FDcEIsTUFBeUI7UUFFekIsSUFBSSxNQUFNLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRSxDQUFDO1lBQ3hCLE9BQU8sK0JBQWdCLENBQUMsS0FBSyxDQUFDO1FBQ2hDLENBQUM7UUFFRCxNQUFNLEVBQUUsR0FBRyxJQUFJLCtCQUFnQixDQUFDLEVBQUUsTUFBTSxFQUFFLEVBQUUsS0FBSyxFQUFFLFdBQVcsRUFBRSxFQUFFLENBQUMsQ0FBQztRQUNwRSxLQUFLLE1BQU0sS0FBSyxJQUFJLE1BQU0sRUFBRSxDQUFDO1lBQzNCLEVBQUUsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO1FBQ3pDLENBQUM7UUFDRCxPQUFPLEVBQUUsQ0FBQztJQUNaLENBQUM7SUFFTSxVQUFVLENBQ2YsS0FBbUI7UUFFbkIsSUFBSSxLQUFLLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRSxDQUFDO1lBQ3ZCLE9BQU8sK0JBQWdCLENBQUMsS0FBSyxDQUFDO1FBQ2hDLENBQUM7UUFFRCxNQUFNLEVBQUUsR0FBRyxJQUFJLCtCQUFnQixDQUFDLEVBQUUsTUFBTSxFQUFFLEVBQUUsS0FBSyxFQUFFLE9BQU8sRUFBRSxFQUFFLENBQUMsQ0FBQztRQUNoRSxLQUFLLE1BQU0sR0FBRyxJQUFJLEtBQUssRUFBRSxDQUFDO1lBQ3hCLEVBQUUsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO1FBQ2xDLENBQUM7UUFDRCxPQUFPLEVBQUUsQ0FBQztJQUNaLENBQUM7SUFFTSxjQUFjLENBQ25CLFNBQTBCO1FBRTFCLE9BQU8sSUFBSSxDQUFDLFVBQVUsQ0FBQyxTQUFTLENBQUMsQ0FBQztJQUNwQyxDQUFDO0lBRU0sV0FBVyxDQUNoQixNQUFvQjtRQUVwQixNQUFNLEVBQUUsR0FBRyxJQUFJLCtCQUFnQixDQUFDO1lBQzlCLEVBQUUsRUFBRSxJQUFJLENBQUMsZUFBZSxDQUFDO2dCQUN2QixFQUFFLEVBQUUsTUFBTSxDQUFDLEVBQUU7Z0JBQ2IsV0FBVyxFQUFFLE1BQU0sQ0FBQyxXQUFXO2dCQUMvQixHQUFHLEVBQUUsTUFBTSxDQUFDLEdBQUc7Z0JBQ2YsR0FBRyxJQUFJLENBQUMsUUFBUTthQUNqQixDQUFDO1lBQ0YsTUFBTSxFQUFFLEVBQUUsS0FBSyxFQUFFLE1BQU0sQ0FBQyxXQUFXLEVBQUU7U0FDdEMsQ0FBQyxDQUFDO1FBRUgsSUFBSSxNQUFNLENBQUMsSUFBSSxFQUFFLENBQUM7WUFDaEIsRUFBRSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUN0QyxDQUFDO1FBRUQsTUFBTSxXQUFXLEdBQUcsSUFBSSwrQkFBZ0IsQ0FBQztZQUN2QyxFQUFFLEVBQUUsSUFBSSxDQUFDLGVBQWUsQ0FBQztnQkFDdkIsRUFBRSxFQUFFLEdBQUcsTUFBTSxDQUFDLEVBQUUsY0FBYztnQkFDOUIsV0FBVyxFQUFFLGFBQWE7Z0JBQzFCLEdBQUcsRUFBRSxHQUFHLE1BQU0sQ0FBQyxHQUFHLGNBQWM7Z0JBQ2hDLEdBQUcsSUFBSSxDQUFDLFFBQVE7YUFDakIsQ0FBQztZQUNGLE1BQU0sRUFBRSxFQUFFLEtBQUssRUFBRSxhQUFhLEVBQUU7U0FDakMsQ0FBQyxDQUFDO1FBRUgsSUFBSSxNQUFNLENBQUMsS0FBSyxFQUFFLENBQUM7WUFDakIsV0FBVyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLFFBQVEsRUFBRSxFQUFFLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUMzRCxDQUFDO1FBRUQsRUFBRSxDQUFDLE9BQU8sQ0FBQyxXQUFXLENBQUMsQ0FBQztRQUN4QixFQUFFLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxlQUFlLENBQUMsTUFBTSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUM7UUFDcEQsT0FBTyxFQUFFLENBQUM7SUFDWixDQUFDO0lBRU0sVUFBVSxDQUNmLEtBQWtCO1FBRWxCLE1BQU0sRUFBRSxHQUFHLElBQUksK0JBQWdCLENBQUM7WUFDOUIsRUFBRSxFQUFFLElBQUksQ0FBQyxlQUFlLENBQUM7Z0JBQ3ZCLEVBQUUsRUFBRSxLQUFLLENBQUMsRUFBRTtnQkFDWixXQUFXLEVBQUUsS0FBSyxDQUFDLFdBQVc7Z0JBQzlCLEdBQUcsRUFBRSxLQUFLLENBQUMsR0FBRztnQkFDZCxHQUFHLElBQUksQ0FBQyxRQUFRO2FBQ2pCLENBQUM7WUFDRixNQUFNLEVBQUUsRUFBRSxLQUFLLEVBQUUsS0FBSyxDQUFDLFdBQVcsRUFBRTtTQUNyQyxDQUFDLENBQUM7UUFFSCxJQUFJLEtBQUssQ0FBQyxVQUFVLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxDQUFDO1lBQ2hDLE1BQU0sTUFBTSxHQUFHLEVBQUUsQ0FBQztZQUNsQixLQUFLLE1BQU0sS0FBSyxJQUFJLEtBQUssQ0FBQyxVQUFVLEVBQUUsQ0FBQztnQkFDckMsTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLEtBQUssRUFBRSxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQztZQUN4RCxDQUFDO1lBQ0QsRUFBRSxDQUFDLE1BQU0sQ0FBQyxHQUFHLCtCQUFnQixDQUFDLE1BQU0sQ0FBQyxhQUFhLENBQUMsSUFBSSxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQztZQUM1RSxFQUFFLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBQ2YsQ0FBQztRQUVELElBQUksS0FBSyxDQUFDLElBQUksRUFBRSxDQUFDO1lBQ2YsRUFBRSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUNyQyxDQUFDO1FBRUQsSUFBSSxLQUFLLENBQUMsV0FBVyxFQUFFLENBQUM7WUFDdEIsRUFBRSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsS0FBSyxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUM7UUFDdkQsQ0FBQztRQUVELEVBQUUsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLG9CQUFvQixDQUFDLEtBQUssQ0FBQyxlQUFlLENBQUMsQ0FBQyxDQUFDO1FBQzdELEVBQUUsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLG9CQUFvQixDQUFDLEtBQUssQ0FBQyxhQUFhLENBQUMsQ0FBQyxDQUFDO1FBQzNELEVBQUUsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQztRQUNuRCxFQUFFLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxjQUFjLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUM7UUFDakQsT0FBTyxFQUFFLENBQUM7SUFDWixDQUFDO0lBRU0sY0FBYyxDQUNuQixLQUFzQjtRQUV0QixNQUFNLEVBQUUsR0FBRyxJQUFJLCtCQUFnQixDQUFDO1lBQzlCLEVBQUUsRUFBRSxJQUFJLENBQUMsZUFBZSxDQUFDO2dCQUN2QixFQUFFLEVBQUUsS0FBSyxDQUFDLEVBQUU7Z0JBQ1osV0FBVyxFQUFFLEtBQUssQ0FBQyxXQUFXO2dCQUM5QixHQUFHLEVBQUUsS0FBSyxDQUFDLEdBQUc7Z0JBQ2QsR0FBRyxJQUFJLENBQUMsUUFBUTthQUNqQixDQUFDO1lBQ0YsTUFBTSxFQUFFLEVBQUUsS0FBSyxFQUFFLEtBQUssQ0FBQyxXQUFXLEVBQUU7U0FDckMsQ0FBQyxDQUFDO1FBRUgsSUFBSSxLQUFLLENBQUMsVUFBVSxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQztZQUNoQyxNQUFNLEtBQUssR0FBRyxFQUFFLENBQUM7WUFDakIsS0FBSyxNQUFNLElBQUksSUFBSSxLQUFLLENBQUMsVUFBVSxFQUFFLENBQUM7Z0JBQ3BDLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUM7WUFDdEQsQ0FBQztZQUNELEVBQUUsQ0FBQyxNQUFNLENBQUMsR0FBRywrQkFBZ0IsQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDLElBQUksS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUM7WUFDeEUsRUFBRSxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUNmLENBQUM7UUFFRCxJQUFJLEtBQUssQ0FBQyxlQUFlLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxDQUFDO1lBQ3JDLE1BQU0sS0FBSyxHQUFHLEVBQUUsQ0FBQztZQUNqQixLQUFLLE1BQU0sSUFBSSxJQUFJLEtBQUssQ0FBQyxlQUFlLEVBQUUsQ0FBQztnQkFDekMsS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQztZQUN0RCxDQUFDO1lBQ0QsRUFBRSxDQUFDLE1BQU0sQ0FBQyxHQUFHLCtCQUFnQixDQUFDLE1BQU0sQ0FBQyxpQkFBaUIsQ0FBQyxJQUFJLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1lBQy9FLEVBQUUsQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLENBQUM7UUFDZixDQUFDO1FBRUQsSUFBSSxLQUFLLENBQUMsSUFBSSxFQUFFLENBQUM7WUFDZixFQUFFLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBQ3JDLENBQUM7UUFFRCxFQUFFLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxLQUFLLENBQUMsZUFBZSxDQUFDLENBQUMsQ0FBQztRQUM3RCxFQUFFLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxlQUFlLENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUM7UUFDbkQsT0FBTyxFQUFFLENBQUM7SUFDWixDQUFDO0lBRU0sU0FBUyxDQUNkLEdBQWU7UUFFZixNQUFNLEVBQUUsR0FBRyxJQUFJLCtCQUFnQixDQUFDO1lBQzlCLEVBQUUsRUFBRSxJQUFJLENBQUMsZUFBZSxDQUFDO2dCQUN2QixFQUFFLEVBQUUsR0FBRyxDQUFDLEVBQUU7Z0JBQ1YsV0FBVyxFQUFFLEdBQUcsQ0FBQyxXQUFXO2dCQUM1QixHQUFHLEVBQUUsR0FBRyxDQUFDLEdBQUc7Z0JBQ1osR0FBRyxJQUFJLENBQUMsUUFBUTthQUNqQixDQUFDO1lBQ0YsTUFBTSxFQUFFLEVBQUUsS0FBSyxFQUFFLEdBQUcsQ0FBQyxXQUFXLEVBQUU7U0FDbkMsQ0FBQyxDQUFDO1FBRUgsSUFBSSxHQUFHLENBQUMsSUFBSSxFQUFFLENBQUM7WUFDYixFQUFFLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBQ25DLENBQUM7UUFFRCxFQUFFLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQztRQUUvQyxPQUFPLEVBQUUsQ0FBQztJQUNaLENBQUM7SUFFTSxnQkFBZ0IsQ0FDckIsSUFBd0I7UUFFeEIsSUFBSSxJQUFJLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRSxDQUFDO1lBQ3RCLE9BQU8sK0JBQWdCLENBQUMsS0FBSyxDQUFDO1FBQ2hDLENBQUM7UUFFRCxNQUFNLEVBQUUsR0FBRyxJQUFJLCtCQUFnQixDQUFDLEVBQUUsTUFBTSxFQUFFLEVBQUUsS0FBSyxFQUFFLFNBQVMsRUFBRSxFQUFFLENBQUMsQ0FBQztRQUVsRSxFQUFFLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQztRQUNqQyxFQUFFLENBQUMsS0FBSyxFQUFFLENBQUM7UUFFWCxLQUFLLE1BQU0sR0FBRyxJQUFJLElBQUksRUFBRSxDQUFDO1lBQ3ZCLEVBQUUsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO1FBQ3hDLENBQUM7UUFDRCxPQUFPLEVBQUUsQ0FBQztJQUNaLENBQUM7SUFFTSxlQUFlLENBQ3BCLFVBQTRCO1FBRTVCLElBQUksVUFBVSxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUUsQ0FBQztZQUM1QixPQUFPLCtCQUFnQixDQUFDLEtBQUssQ0FBQztRQUNoQyxDQUFDO1FBRUQsTUFBTSxFQUFFLEdBQUcsSUFBSSwrQkFBZ0IsQ0FBQyxFQUFFLE1BQU0sRUFBRSxFQUFFLEtBQUssRUFBRSxZQUFZLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFFckUsRUFBRSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsb0JBQW9CLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQztRQUNoRCxFQUFFLENBQUMsS0FBSyxFQUFFLENBQUM7UUFFWCxLQUFLLE1BQU0sSUFBSSxJQUFJLFVBQVUsRUFBRSxDQUFDO1lBQzlCLEVBQUUsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO1FBQ3ZDLENBQUM7UUFFRCxPQUFPLEVBQUUsQ0FBQztJQUNaLENBQUM7SUFFTSxnQkFBZ0IsQ0FDckIsSUFBdUI7UUFFdkIsTUFBTSxFQUFFLEdBQUcsSUFBSSwrQkFBZ0IsQ0FBQztZQUM5QixFQUFFLEVBQUUsSUFBSSxDQUFDLGVBQWUsQ0FBQztnQkFDdkIsRUFBRSxFQUFFLElBQUksQ0FBQyxFQUFFO2dCQUNYLFdBQVcsRUFBRSxJQUFJLENBQUMsV0FBVztnQkFDN0IsR0FBRyxFQUFFLElBQUksQ0FBQyxHQUFHO2dCQUNiLEdBQUcsSUFBSSxDQUFDLFFBQVE7YUFDakIsQ0FBQztZQUNGLE1BQU0sRUFBRTtnQkFDTixLQUFLLEVBQUUsY0FBYzthQUN0QjtTQUNGLENBQUMsQ0FBQztRQUVILElBQUksSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO1lBQ2YsRUFBRSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLFFBQVEsRUFBRSxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUNoRCxDQUFDO1FBRUQsRUFBRSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsb0JBQW9CLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUM7UUFDckQsRUFBRSxDQUFDLEtBQUssRUFBRSxDQUFDO1FBRVgsS0FBSyxNQUFNLEtBQUssSUFBSSxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7WUFDcEMsRUFBRSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUM7UUFDekMsQ0FBQztRQUVELE9BQU8sRUFBRSxDQUFDO0lBQ1osQ0FBQztJQUVNLG9CQUFvQixDQUN6QixPQUF1QjtRQUV2QixJQUFJLE9BQU8sQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFLENBQUM7WUFDekIsT0FBTywrQkFBZ0IsQ0FBQyxLQUFLLENBQUM7UUFDaEMsQ0FBQztRQUVELE1BQU0sRUFBRSxHQUFHLElBQUksK0JBQWdCLENBQUMsRUFBRSxNQUFNLEVBQUUsRUFBRSxLQUFLLEVBQUUsU0FBUyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBRWxFLEVBQUUsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDO1FBQ3BDLEVBQUUsQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUVYLEtBQUssTUFBTSxNQUFNLElBQUksT0FBTyxFQUFFLENBQUM7WUFDN0IsRUFBRSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsbUJBQW1CLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQztRQUMvQyxDQUFDO1FBQ0QsT0FBTyxFQUFFLENBQUM7SUFDWixDQUFDO0lBRU0sb0JBQW9CLENBQ3pCLE9BQXVCO1FBRXZCLElBQUksT0FBTyxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUUsQ0FBQztZQUN6QixPQUFPLCtCQUFnQixDQUFDLEtBQUssQ0FBQztRQUNoQyxDQUFDO1FBRUQsTUFBTSxFQUFFLEdBQUcsSUFBSSwrQkFBZ0IsQ0FBQyxFQUFFLE1BQU0sRUFBRSxFQUFFLEtBQUssRUFBRSxrQkFBa0IsRUFBRSxFQUFFLENBQUMsQ0FBQztRQUUzRSxFQUFFLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQztRQUNwQyxFQUFFLENBQUMsS0FBSyxFQUFFLENBQUM7UUFFWCxLQUFLLE1BQU0sTUFBTSxJQUFJLE9BQU8sRUFBRSxDQUFDO1lBQzdCLEVBQUUsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLG1CQUFtQixDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUM7UUFDL0MsQ0FBQztRQUNELE9BQU8sRUFBRSxDQUFDO0lBQ1osQ0FBQztJQUVNLGNBQWMsQ0FDbkIsU0FBMkI7UUFFM0IsSUFBSSxTQUFTLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRSxDQUFDO1lBQzNCLE9BQU8sK0JBQWdCLENBQUMsS0FBSyxDQUFDO1FBQ2hDLENBQUM7UUFFRCxNQUFNLEVBQUUsR0FBRyxJQUFJLCtCQUFnQixDQUFDLEVBQUUsTUFBTSxFQUFFLEVBQUUsS0FBSyxFQUFFLFdBQVcsRUFBRSxFQUFFLENBQUMsQ0FBQztRQUVwRSxFQUFFLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDO1FBQy9DLEVBQUUsQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUVYLEtBQUssTUFBTSxHQUFHLElBQUksU0FBUyxFQUFFLENBQUM7WUFDNUIsRUFBRSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7UUFDdEMsQ0FBQztRQUVELE9BQU8sRUFBRSxDQUFDO0lBQ1osQ0FBQztJQUVNLGVBQWUsQ0FDcEIsRUFBb0I7UUFFcEIsTUFBTSxFQUFFLEdBQUcsSUFBSSwrQkFBZ0IsQ0FBQztZQUM5QixFQUFFLEVBQUUsSUFBSSxDQUFDLGVBQWUsQ0FBQztnQkFDdkIsRUFBRSxFQUFFLEVBQUUsQ0FBQyxFQUFFO2dCQUNULFdBQVcsRUFBRSxFQUFFLENBQUMsV0FBVztnQkFDM0IsR0FBRyxFQUFFLEVBQUUsQ0FBQyxHQUFHO2dCQUNYLEdBQUcsSUFBSSxDQUFDLFFBQVE7YUFDakIsQ0FBQztZQUNGLE1BQU0sRUFBRTtnQkFDTixLQUFLLEVBQUUsRUFBRSxDQUFDLFdBQVc7Z0JBQ3JCLEdBQUcsRUFBRSxJQUFJO2dCQUNULE1BQU0sRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLFVBQVU7YUFDM0I7U0FDRixDQUFDLENBQUM7UUFFSCxJQUFJLEVBQUUsQ0FBQyxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7WUFDdkIsRUFBRSxDQUFDLE1BQU0sQ0FDUCxHQUFHLCtCQUFnQixDQUFDLE1BQU0sQ0FBQyxhQUFhLENBQUMsSUFBSSxFQUFFLENBQUMsSUFBSSxDQUFDLGlCQUFpQixFQUFFLENBQ3pFLENBQUM7WUFDRixFQUFFLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBQ2YsQ0FBQztRQUVELElBQUksRUFBRSxDQUFDLElBQUksRUFBRSxDQUFDO1lBQ1osRUFBRSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUNsQyxDQUFDO1FBRUQsRUFBRSxDQUFDLEtBQUssRUFBRSxDQUFDO1FBQ1gsRUFBRSxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUViLE9BQU8sRUFBRSxDQUFDO0lBQ1osQ0FBQztJQUVNLGFBQWEsQ0FDbEIsSUFBb0I7UUFFcEIsTUFBTSxXQUFXLEdBQUcsSUFBSSxDQUFDLFFBQVE7WUFDL0IsQ0FBQyxDQUFDLFVBQVU7WUFDWixDQUFDLENBQUMsVUFBVSxDQUFDO1FBRWYsTUFBTSxFQUFFLEdBQUcsSUFBSSwrQkFBZ0IsQ0FBQztZQUM5QixFQUFFLEVBQUUsSUFBSSxDQUFDLGVBQWUsQ0FBQztnQkFDdkIsRUFBRSxFQUFFLElBQUksQ0FBQyxFQUFFO2dCQUNYLFdBQVcsRUFBRSxJQUFJLENBQUMsV0FBVztnQkFDN0IsR0FBRyxFQUFFLElBQUksQ0FBQyxHQUFHO2dCQUNiLEdBQUcsSUFBSSxDQUFDLFFBQVE7YUFDakIsQ0FBQztZQUNGLE1BQU0sRUFBRTtnQkFDTixLQUFLLEVBQUUsSUFBSSxDQUFDLFdBQVc7Z0JBQ3ZCLEdBQUcsRUFBRSxXQUFXO2dCQUNoQixHQUFHLEVBQUUsSUFBSTtnQkFDVCxNQUFNLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxVQUFVO2FBQzdCO1NBQ0YsQ0FBQyxDQUFDO1FBRUgsSUFBSSxJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDO1lBQ3pCLEVBQUUsQ0FBQyxNQUFNLENBQ1AsR0FBRywrQkFBZ0IsQ0FBQyxNQUFNLENBQUMsYUFBYSxDQUFDLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxpQkFBaUIsRUFBRSxDQUMzRSxDQUFDO1lBQ0YsRUFBRSxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUNmLENBQUM7UUFFRCxJQUFJLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUNmLEVBQUUsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxRQUFRLEVBQUUsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDaEQsQ0FBQztRQUVELE1BQU0sUUFBUSxHQUEyQjtZQUN2QyxJQUFJLEVBQUUsSUFBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxRQUFRLEVBQUUsSUFBSSxDQUFDLGFBQWEsQ0FBQztTQUN2RSxDQUFDO1FBRUYsSUFBSSxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7WUFDakIsTUFBTSxTQUFTLEdBQUcsK0JBQWdCLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztZQUMxRCxRQUFRLENBQUMsT0FBTyxHQUFHLCtCQUFnQixDQUFDLGNBQWMsQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUNoRSxDQUFDO1FBRUQsS0FBSyxNQUFNLENBQUMsR0FBRyxFQUFFLEtBQUssQ0FBQyxJQUFJLE1BQU0sQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQztZQUNwRCxFQUFFLENBQUMsTUFBTSxDQUFDLEdBQUcsK0JBQWdCLENBQUMsTUFBTSxDQUFDLEdBQUcsR0FBRyxHQUFHLENBQUMsSUFBSSxLQUFLLEVBQUUsQ0FBQyxDQUFDO1FBQzlELENBQUM7UUFDRCxFQUFFLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBRWIsSUFBSSxJQUFJLENBQUMsSUFBSSxFQUFFLENBQUM7WUFDZCxFQUFFLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBQ3BDLENBQUM7UUFFRCxFQUFFLENBQUMsS0FBSyxFQUFFLENBQUM7UUFFWCxPQUFPLEVBQUUsQ0FBQztJQUNaLENBQUM7SUFFTSxjQUFjLENBQ25CLFNBQTBCO1FBRTFCLE1BQU0sV0FBVyxHQUFHLFNBQVMsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDO1FBRWpFLE1BQU0sRUFBRSxHQUFHLElBQUksK0JBQWdCLENBQUM7WUFDOUIsRUFBRSxFQUFFLElBQUksQ0FBQyxlQUFlLENBQUM7Z0JBQ3ZCLEVBQUUsRUFBRSxTQUFTLENBQUMsRUFBRTtnQkFDaEIsV0FBVyxFQUFFLFNBQVMsQ0FBQyxXQUFXO2dCQUNsQyxHQUFHLEVBQUUsU0FBUyxDQUFDLEdBQUc7Z0JBQ2xCLEdBQUcsSUFBSSxDQUFDLFFBQVE7YUFDakIsQ0FBQztZQUNGLE1BQU0sRUFBRTtnQkFDTixLQUFLLEVBQUUsU0FBUyxDQUFDLFdBQVc7Z0JBQzVCLEdBQUcsRUFBRSxXQUFXO2dCQUNoQixHQUFHLEVBQUUsSUFBSTtnQkFDVCxNQUFNLEVBQUUsU0FBUyxDQUFDLElBQUksQ0FBQyxVQUFVO2FBQ2xDO1NBQ0YsQ0FBQyxDQUFDO1FBRUgsSUFBSSxTQUFTLENBQUMsSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDO1lBQzlCLEVBQUUsQ0FBQyxNQUFNLENBQ1AsR0FBRywrQkFBZ0IsQ0FBQyxNQUFNLENBQUMsYUFBYSxDQUFDLElBQUksU0FBUyxDQUFDLElBQUksQ0FBQyxpQkFBaUIsRUFBRSxDQUNoRixDQUFDO1lBQ0YsRUFBRSxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUNmLENBQUM7UUFHRCxNQUFNLFFBQVEsR0FBUTtZQUNwQixJQUFJLEVBQUUsSUFBSSxDQUFDLGFBQWEsQ0FBQyxTQUFTLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxRQUFRLEVBQUUsSUFBSSxDQUFDLGFBQWEsQ0FBQztTQUM1RSxDQUFDO1FBRUYsSUFBSSxTQUFTLENBQUMsT0FBTyxFQUFFLENBQUM7WUFDdEIsTUFBTSxTQUFTLEdBQUcsK0JBQWdCLENBQUMsUUFBUSxDQUFDLFNBQVMsQ0FBQyxPQUFPLENBQUMsQ0FBQztZQUMvRCxRQUFRLENBQUMsT0FBTyxHQUFHLCtCQUFnQixDQUFDLGNBQWMsQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUNoRSxDQUFDO1FBRUQsS0FBSyxNQUFNLENBQUMsR0FBRyxFQUFFLEtBQUssQ0FBQyxJQUFJLE1BQU0sQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQztZQUNwRCxFQUFFLENBQUMsTUFBTSxDQUFDLEdBQUcsK0JBQWdCLENBQUMsTUFBTSxDQUFDLEdBQUcsR0FBRyxHQUFHLENBQUMsSUFBSSxLQUFLLEVBQUUsQ0FBQyxDQUFDO1FBQzlELENBQUM7UUFDRCxFQUFFLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBRWIsSUFBSSxTQUFTLENBQUMsSUFBSSxFQUFFLENBQUM7WUFDbkIsRUFBRSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUN6QyxDQUFDO1FBRUQsRUFBRSxDQUFDLEtBQUssRUFBRSxDQUFDO1FBRVgsT0FBTyxFQUFFLENBQUM7SUFDWixDQUFDO0lBRU0sbUJBQW1CLENBQ3hCLE1BQW9CO1FBRXBCLE1BQU0sRUFBRSxHQUFHLElBQUksK0JBQWdCLENBQUM7WUFDOUIsRUFBRSxFQUFFLElBQUksQ0FBQyxlQUFlLENBQUM7Z0JBQ3ZCLEVBQUUsRUFBRSxNQUFNLENBQUMsRUFBRTtnQkFDYixXQUFXLEVBQUUsTUFBTSxDQUFDLFdBQVc7Z0JBQy9CLEdBQUcsRUFBRSxNQUFNLENBQUMsR0FBRztnQkFDZixHQUFHLElBQUksQ0FBQyxRQUFRO2FBQ2pCLENBQUM7WUFDRixNQUFNLEVBQUU7Z0JBQ04sS0FBSyxFQUFFLE1BQU0sQ0FBQyxXQUFXO2dCQUN6QixHQUFHLEVBQUUsSUFBSTtnQkFDVCxNQUFNLEVBQUUsTUFBTSxDQUFDLElBQUksQ0FBQyxVQUFVO2FBQy9CO1NBQ0YsQ0FBQyxDQUFDO1FBRUgsSUFBSSxNQUFNLENBQUMsS0FBSyxFQUFFLENBQUM7WUFDakIsRUFBRSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLFFBQVEsRUFBRSxFQUFFLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUNsRCxDQUFDO1FBRUQsSUFBSSxNQUFNLENBQUMsSUFBSSxFQUFFLENBQUM7WUFDaEIsRUFBRSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUN0QyxDQUFDO1FBRUQsS0FBSyxNQUFNLEtBQUssSUFBSSxNQUFNLENBQUMsVUFBVSxFQUFFLENBQUM7WUFDdEMsRUFBRSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUM7UUFDekMsQ0FBQztRQUVELE9BQU8sRUFBRSxDQUFDO0lBQ1osQ0FBQztJQUVNLG1CQUFtQixDQUN4QixNQUFvQjtRQUVwQixNQUFNLEVBQUUsR0FBRyxJQUFJLCtCQUFnQixDQUFDO1lBQzlCLEVBQUUsRUFBRSxJQUFJLENBQUMsZUFBZSxDQUFDO2dCQUN2QixFQUFFLEVBQUUsTUFBTSxDQUFDLEVBQUU7Z0JBQ2IsV0FBVyxFQUFFLE1BQU0sQ0FBQyxXQUFXO2dCQUMvQixHQUFHLEVBQUUsTUFBTSxDQUFDLEdBQUc7Z0JBQ2YsR0FBRyxJQUFJLENBQUMsUUFBUTthQUNqQixDQUFDO1lBQ0YsTUFBTSxFQUFFO2dCQUNOLEtBQUssRUFBRSxNQUFNLENBQUMsV0FBVztnQkFDekIsR0FBRyxFQUFFLElBQUk7Z0JBQ1QsTUFBTSxFQUFFLE1BQU0sQ0FBQyxJQUFJLENBQUMsVUFBVTthQUMvQjtTQUNGLENBQUMsQ0FBQztRQUVILElBQUksTUFBTSxDQUFDLEtBQUssRUFBRSxDQUFDO1lBQ2pCLEVBQUUsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxRQUFRLEVBQUUsRUFBRSxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDbEQsQ0FBQztRQUVELElBQUksTUFBTSxDQUFDLElBQUksRUFBRSxDQUFDO1lBQ2hCLEVBQUUsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDdEMsQ0FBQztRQUVELEtBQUssTUFBTSxLQUFLLElBQUksTUFBTSxDQUFDLFVBQVUsRUFBRSxDQUFDO1lBQ3RDLEVBQUUsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO1FBQ3pDLENBQUM7UUFFRCxPQUFPLEVBQUUsQ0FBQztJQUNaLENBQUM7SUFFTSxhQUFhLENBQ2xCLFFBQXdCO1FBRXhCLE9BQU8sSUFBSSxDQUFDLGFBQWEsQ0FBQyxRQUFRLENBQUMsQ0FBQztJQUN0QyxDQUFDO0lBRU8sV0FBVyxDQUFDLEtBQXdCOztRQUMxQyxNQUFNLFNBQVMsR0FBZSxFQUFFLENBQUM7UUFDakMsU0FBUyxDQUFDLElBQUksQ0FBQyxDQUFDLE1BQU0sRUFBRSxhQUFhLENBQUMsQ0FBQyxHQUFHLENBQUMsK0JBQWdCLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQztRQUVuRSxLQUFLLE1BQU0sSUFBSSxJQUFJLEtBQUssRUFBRSxDQUFDO1lBQ3pCLE1BQU0sSUFBSSxHQUFHLCtCQUFnQixDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDO2dCQUNuRCxHQUFHLEVBQUUsSUFBSSxDQUFDLEdBQUc7Z0JBQ2IsV0FBVyxFQUFFLElBQUksQ0FBQyxXQUFXO2dCQUM3QixFQUFFLEVBQUUsSUFBSSxDQUFDLEVBQUU7Z0JBQ1gsR0FBRyxJQUFJLENBQUMsUUFBUTthQUNqQixFQUFFLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDO1lBQ25CLE1BQU0sV0FBVyxHQUFHLENBQUEsTUFBQSxJQUFJLENBQUMsSUFBSSwwQ0FBRSxPQUFPLEtBQUksQ0FBQSxNQUFBLElBQUksQ0FBQyxJQUFJLDBDQUFFLE9BQU8sQ0FBQyxNQUFNLElBQUcsQ0FBQztnQkFDckUsQ0FBQyxDQUFDLE1BQUEsSUFBSSxDQUFDLElBQUksMENBQUUsT0FBTztnQkFDcEIsQ0FBQyxDQUFDLCtCQUFnQixDQUFDLE1BQU0sQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO1lBQy9DLFNBQVMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxJQUFJLEVBQUUsV0FBVyxDQUFDLENBQUMsQ0FBQztRQUN0QyxDQUFDO1FBRUQsT0FBTyxTQUFTLENBQUM7SUFDbkIsQ0FBQztJQUVPLG9CQUFvQixDQUFDLEtBQXNCOztRQUNqRCxNQUFNLFNBQVMsR0FBZSxFQUFFLENBQUM7UUFDakMsU0FBUyxDQUFDLElBQUksQ0FBQyxDQUFDLE1BQU0sRUFBRSxNQUFNLEVBQUUsYUFBYSxDQUFDLENBQUMsR0FBRyxDQUFDLCtCQUFnQixDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7UUFFM0UsS0FBSyxNQUFNLElBQUksSUFBSSxLQUFLLEVBQUUsQ0FBQztZQUN6QixNQUFNLElBQUksR0FBRywrQkFBZ0IsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQztnQkFDbkQsR0FBRyxFQUFFLElBQUksQ0FBQyxHQUFHO2dCQUNiLFdBQVcsRUFBRSxJQUFJLENBQUMsV0FBVztnQkFDN0IsRUFBRSxFQUFFLElBQUksQ0FBQyxFQUFFO2dCQUNYLEdBQUcsSUFBSSxDQUFDLFFBQVE7YUFDakIsRUFBRSxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQztZQUNuQixNQUFNLElBQUksR0FBRywrQkFBZ0IsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxRQUFRLEVBQUUsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFDLENBQUM7WUFDcEcsTUFBTSxXQUFXLEdBQUcsQ0FBQSxNQUFBLElBQUksQ0FBQyxJQUFJLDBDQUFFLE9BQU8sS0FBSSxDQUFBLE1BQUEsSUFBSSxDQUFDLElBQUksMENBQUUsT0FBTyxDQUFDLE1BQU0sSUFBRyxDQUFDO2dCQUNyRSxDQUFDLENBQUMsTUFBQSxJQUFJLENBQUMsSUFBSSwwQ0FBRSxPQUFPO2dCQUNwQixDQUFDLENBQUMsK0JBQWdCLENBQUMsTUFBTSxDQUFDLGlCQUFpQixDQUFDLENBQUM7WUFDL0MsU0FBUyxDQUFDLElBQUksQ0FBQyxDQUFDLElBQUksRUFBRSxJQUFJLEVBQUUsV0FBVyxDQUFDLENBQUMsQ0FBQztRQUM1QyxDQUFDO1FBRUQsT0FBTyxTQUFTLENBQUM7SUFDbkIsQ0FBQztDQUNGO0FBaHFCRCw0Q0FncUJDO0FBYUQsU0FBUyxRQUFRLENBQUMsR0FBVztJQUMzQixPQUFPLEdBQUcsQ0FBQyxPQUFPLENBQUMsSUFBSSxFQUFFLEdBQUcsQ0FBQyxDQUFDO0FBQ2hDLENBQUM7QUFFTSxNQUFNLHNCQUFzQixHQUFHLENBQUMsSUFBZ0IsRUFBRSxFQUFFO0lBQ3pELHdEQUF3RDtJQUN4RCxPQUFPLFFBQVEsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUM7QUFDM0IsQ0FBQyxDQUFDO0FBSFcsUUFBQSxzQkFBc0IsMEJBR2pDO0FBRUssTUFBTSxvQkFBb0IsR0FBRyxDQUFDLElBQWdCLEVBQUUsUUFBZ0MsRUFBRSxFQUFFO0lBQ3pGLElBQUksSUFBSSxDQUFDLFdBQVcsS0FBSyxRQUFRLENBQUMsV0FBVyxJQUFJLElBQUksQ0FBQyxTQUFTLEtBQUssUUFBUSxDQUFDLFNBQVMsRUFBRSxDQUFDO1FBQ3ZGLE9BQU8sYUFBYSxRQUFRLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxLQUFLLElBQUksQ0FBQyxXQUFXLE1BQU0sQ0FBQztJQUNuRSxDQUFDO1NBQU0sQ0FBQztRQUNOLDJEQUEyRDtRQUMzRCxPQUFPLElBQUksQ0FBQyxHQUFHLENBQUM7SUFDbEIsQ0FBQztBQUNILENBQUMsQ0FBQztBQVBXLFFBQUEsb0JBQW9CLHdCQU8vQjtBQUVGLFNBQVMsVUFBVSxDQUFDLEtBQVU7SUFDNUIsT0FBTyxDQUNMLEtBQUssS0FBSyxJQUFJO1dBQ1gsT0FBTyxLQUFLLEtBQUssUUFBUTtZQUN6QixLQUFLLGFBQUwsS0FBSyx1QkFBTCxLQUFLLENBQUUsR0FBRyxDQUFBO1lBQ1YsS0FBSyxhQUFMLEtBQUssdUJBQUwsS0FBSyxDQUFFLEVBQUUsQ0FBQTtZQUNULEtBQUssYUFBTCxLQUFLLHVCQUFMLEtBQUssQ0FBRSxXQUFXLENBQUEsQ0FDdEIsQ0FBQztBQUNKLENBQUM7QUFFTSxNQUFNLG9CQUFvQixHQUFHLENBQ2xDLElBQWdCLEVBQ2hCLFFBQWdDLEVBQ2hDLGFBQTZFLEVBQ3JFLEVBQUU7O0lBQ1YsSUFBSSxNQUFNLEdBQUcsSUFBSSxDQUFDLGlCQUFpQixDQUFDO0lBQ3BDLE1BQU0sUUFBUSxHQUFHLEVBQUUsQ0FBQztJQUNwQixLQUFLLE1BQU0sT0FBTyxJQUFJLE1BQUEsSUFBSSxDQUFDLEtBQUssbUNBQUksRUFBRSxFQUFFLENBQUM7UUFDdkMsSUFBSSxVQUFVLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQztZQUN4QixRQUFRLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxPQUFPLEVBQUUsUUFBUSxDQUFDLENBQUMsQ0FBQztRQUNsRCxDQUFDO2FBQU0sQ0FBQztZQUNOLFFBQVEsQ0FBQyxJQUFJLENBQUMsSUFBQSw0QkFBb0IsRUFBQyxPQUFPLEVBQUUsUUFBUSxFQUFFLGFBQWEsQ0FBQyxDQUFDLENBQUM7UUFDeEUsQ0FBQztJQUNILENBQUM7SUFFRCxxREFBcUQ7SUFDckQsTUFBTSxrQkFBa0IsR0FBRyxLQUFLLENBQUM7SUFDakMsS0FBSyxNQUFNLE9BQU8sSUFBSSxRQUFRLEVBQUUsQ0FBQztRQUMvQixNQUFNLE9BQU8sR0FBRyxrQkFBa0IsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDaEQsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO1lBQ2IsNkVBQTZFO1lBQzdFLDJGQUEyRjtZQUMzRixTQUFTO1FBQ1gsQ0FBQztRQUNELE1BQU0sWUFBWSxHQUFXLE9BQU8sQ0FBQyxLQUFLLENBQUM7UUFDM0MsTUFBTSxHQUFHLE1BQU0sQ0FBQyxTQUFTLENBQUMsQ0FBQyxFQUFFLFlBQVksQ0FBQyxHQUFHLE9BQU8sR0FBRyxNQUFNLENBQUMsU0FBUyxDQUFDLFlBQVksR0FBRyxDQUFDLENBQUMsQ0FBQztJQUM1RixDQUFDO0lBRUQsT0FBTyxNQUFNLENBQUM7QUFDaEIsQ0FBQyxDQUFDO0FBN0JXLFFBQUEsb0JBQW9CLHdCQTZCL0IiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyByZWZsZWN0IGZyb20gJ2pzaWktcmVmbGVjdCc7XG5pbXBvcnQgeyBNYXJrZG93bkRvY3VtZW50IH0gZnJvbSAnLi9tYXJrZG93bi1kb2MnO1xuaW1wb3J0IHsgQXBpUmVmZXJlbmNlU2NoZW1hLCBBc3NlbWJseU1ldGFkYXRhU2NoZW1hLCBDbGFzc1NjaGVtYSwgQ29uc3RydWN0U2NoZW1hLCBFbnVtTWVtYmVyU2NoZW1hLCBFbnVtU2NoZW1hLCBJbml0aWFsaXplclNjaGVtYSwgSW50ZXJmYWNlU2NoZW1hLCBKc2lpRW50aXR5LCBNZXRob2RTY2hlbWEsIFBhcmFtZXRlclNjaGVtYSwgUHJvcGVydHlTY2hlbWEsIFNjaGVtYSwgQ1VSUkVOVF9TQ0hFTUFfVkVSU0lPTiwgU3RydWN0U2NoZW1hLCBUeXBlU2NoZW1hIH0gZnJvbSAnLi4vc2NoZW1hJztcbmltcG9ydCB7IExhbmd1YWdlLCBzdWJtb2R1bGVSZWxOYW1lIH0gZnJvbSAnLi4vdHJhbnNwaWxlL3RyYW5zcGlsZSc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgTWFya2Rvd25Gb3JtYXR0aW5nT3B0aW9ucyB7XG4gIC8qKlxuICAgKiBIb3cganNpaSBlbnRpdHkgSURzIHNob3VsZCBiZSBmb3JtYXR0ZWQgaW50byBhbmNob3JzLiBUaGlzIHNob3VsZCBiZVxuICAgKiBjdXN0b21pemVkIGluIGNvbmp1bmN0aW9uIHdpdGggYGxpbmtGb3JtYXR0ZXJgLlxuICAgKlxuICAgKiBAcGFyYW0gdHlwZSAtIHRoZSBlbnRpdHkgd2UgYXJlIGNyZWF0aW5nIGFuIGFuY2hvciBmb3JcbiAgICpcbiAgICogQGV4cGVyaW1lbnRhbFxuICAgKiBAZGVmYXVsdCAtIHVzZSB0aGUgZnVsbCBpZFxuICAgKi9cbiAgcmVhZG9ubHkgYW5jaG9yRm9ybWF0dGVyPzogKHR5cGU6IEpzaWlFbnRpdHkpID0+IHN0cmluZztcblxuICAvKipcbiAgICogSG93IHNob3VsZCBsaW5rcyB0byBlbnRpdGllcyBiZSByZW5kZXJlZC4gRm9yIGV4YW1wbGUsIGlmIGEgY2xhc3Mgb3IgYVxuICAgKiBwcm9wZXJ0eSBpcyByZWZlcmVuY2VkIHdpdGhpbiBhIGRlc2NyaXB0aW9uIG9yIHRhYmxlLlxuICAgKlxuICAgKiBUaGUgYG1ldGFkYXRhYCBwYXJhbWV0ZXIgY2FuIGJlIG9wdGlvbmFsbHkgdXNlZCB0byBjdXN0b21pemUgbGlua3MgYmFzZWRcbiAgICogb24gd2hldGhlciBvciBub3QgdGhlIHR5cGUgYmVsb25ncyB0byB0aGUgcGFja2FnZSAvIHN1Ym1vZHVsZSB0aGF0IGlzXG4gICAqIGJlaW5nIGdlbmVyYXRlZC5cbiAgICpcbiAgICogQHBhcmFtIHR5cGUgLSB0aGUgZW50aXR5IHdlIGFyZSBjcmVhdGluZyBhIGxpbmsgZm9yXG4gICAqIEBwYXJhbSBtZXRhZGF0YSAtIGluZm9ybWF0aW9uIGFib3V0IHRoZSBtb2R1bGUgYmVpbmcgZG9jZ2VuLWVkXG4gICAqXG4gICAqIEBleHBlcmltZW50YWxcbiAgICogQGRlZmF1bHQgLSAnPGEgaHJlZj1cIiN7dHlwZS5pZH1cIj57dHlwZS5kaXNwbGF5TmFtZX08L2E+JyBpZiB0aGUgdHlwZVxuICAgKiAgIGJlbG9uZ3MgdG8gdGhpcyBwYWNrYWdlLCAne3R5cGUuZnFufScgb3RoZXJ3aXNlXG4gICAqL1xuICByZWFkb25seSBsaW5rRm9ybWF0dGVyPzogKHR5cGU6IEpzaWlFbnRpdHksIG1ldGFkYXRhOiBBc3NlbWJseU1ldGFkYXRhU2NoZW1hKSA9PiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIEhvdyB0eXBlIHNpZ25hdHVyZXMgc2hvdWxkIGJlIGZvcm1hdHRlZCwgaW5jbHVkaW5nIHRob3NlIG1hZGUgb2YgbmVzdGVkXG4gICAqIHR5cGVzIChsaWtlIGBNYXA8c3RyaW5nLCBCdWNrZXQ+YCkuXG4gICAqXG4gICAqIFRoZSBgbWV0YWRhdGFgIGFuZCBgbGlua0Zvcm1hdHRlcmAgcGFyYW1ldGVycyBhcmUgcHJvdmlkZWQgc28gdGhhdCBsaW5rc1xuICAgKiBjYW4gYmUgaW5jbHVkZWQgaW4gdGhlIGZvcm1hdHRlZCB0eXBlcyBpZiBkZXNpcmVkLlxuICAgKlxuICAgKiBAcGFyYW0gdHlwZSAtIHRoZSB0eXBlIGJlaW5nIGZvcm1hdHRlZFxuICAgKiBAcGFyYW0gbWV0YWRhdGEgLSBpbmZvcm1hdGlvbiBhYm91dCB0aGUgbW9kdWxlIGJlaW5nIGRvY2dlbi1lZFxuICAgKiBAcGFyYW0gbGlua0Zvcm1hdHRlciAtIHRoZSB0eXBlIGxpbmsgZm9ybWF0dGVyXG4gICAqXG4gICAqIEBleHBlcmltZW50YWxcbiAgICogQGRlZmF1bHQgLSBIVE1MIGNvZGUgYmxvY2sgd2l0aCB0eXBlIHJlZmVyZW5jZXMgbGlua2VkXG4gICAqIGFjY29yZGluZyB0byBgbGlua0Zvcm1hdHRlcmBcbiAgICovXG4gIHJlYWRvbmx5IHR5cGVGb3JtYXR0ZXI/OiAoXG4gICAgdHlwZTogVHlwZVNjaGVtYSxcbiAgICBtZXRhZGF0YTogQXNzZW1ibHlNZXRhZGF0YVNjaGVtYSxcbiAgICBsaW5rRm9ybWF0dGVyOiAodHlwZTogSnNpaUVudGl0eSwgbWV0YWRhdGE6IEFzc2VtYmx5TWV0YWRhdGFTY2hlbWEpID0+IHN0cmluZ1xuICApID0+IHN0cmluZztcblxuXG4gIC8qKlxuICAgKiBIb3cgdG8gcmVuZGVyIHRoZSBoZWFkZXIgb2YgdGhlIGdlbmVyYXRlZCBkb2N1bWVudGF0aW9uLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIGRlZmF1bHQgc2VjdGlvbiBoZWFkZXJzXG4gICAqL1xuICByZWFkb25seSBoZWFkZXI/OiB7IHRpdGxlOiBzdHJpbmc7IGlkOiBzdHJpbmcgfTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBNYXJrZG93blJlbmRlcmVyT3B0aW9ucyBleHRlbmRzIE1hcmtkb3duRm9ybWF0dGluZ09wdGlvbnMsIEFzc2VtYmx5TWV0YWRhdGFTY2hlbWEge1xuICAvKipcbiAgICogTGFuZ3VhZ2UgdGhlIGRvY3VtZW50YXRpb24gaXMgcmVuZGVyZWQgZm9yLlxuICAgKi9cbiAgcmVhZG9ubHkgbGFuZ3VhZ2U6IExhbmd1YWdlO1xufVxuXG4vKipcbiAqIEdlbmVyYXRlcyBgTWFya2Rvd25Eb2N1bWVudGAgaW5zdGFuY2VzIGZyb20gYEFQSS5qc29uYCBvciBpdHMgcGFydHMuXG4gKlxuICogVGhpcyBjbGFzcyBjYW4gYmUgdXNlZCBpbiB0d28gd2F5czpcbiAqXG4gKiAxLiBJbnN0YW50aWF0ZSBpdCB2aWEgdGhlIGNvbnN0cnVjdG9yIHdpdGggYG9wdGlvbnNgLCB3aGljaCByZXF1aXJlc1xuICogcGFzc2luZyBpbiBzb21lIGdsb2JhbCBjb250ZXh0IGFib3V0IHRoZSBtb2R1bGUgYW5kIGxhbmd1YWdlIHlvdSBhcmVcbiAqIGdlbmVyYXRlZCBmb3IuIChUaGlzIGNvbnRleHQgY2FuIGJlIGZvdW5kIGluIHRoZSB0b3AtbGV2ZWwgYG1ldGFkYXRhYFxuICogZmllbGQgb2YgQVBJLmpzb24uKSBUaGVuLCBjYWxsIGEgYHZpc2l0WHh4YCBtZXRob2QgdG8gZ2VuZXJhdGUgYVxuICogYE1hcmtkb3duRG9jdW1lbnRgIGZvciB0aGUgYXBwcm9wcmlhdGUgcGFydCBvZiB0aGUgc2NoZW1hLlxuICpcbiAqIDIuIEdlbmVyYXRlIGEgYE1hcmtkb3duRG9jdW1lbnRgIGZyb20gdGhlIGNvbXBsZXRlIGBBUEkuanNvbmAgdXNpbmcgdGhlXG4gKiBgZnJvbVNjaGVtYWAgc3RhdGljIG1ldGhvZCAobm8gaW5zdGFudGlhdGlvbiBuZWVkZWQpLiBHbG9iYWwgY29udGV4dCBpc1xuICogYXV0b21hdGljYWxseSBpbmZlcnJlZCBmcm9tIHRoZSBBUEkuanNvbi5cbiAqXG4gKiBCb3RoIGNob2ljZXMgYWxsb3cgY3VzdG9taXppbmcgdGhlIG91dHB1dCB2aWEgYE1hcmtkb3duRm9ybWF0dGluZ09wdGlvbnNgLlxuICovXG5leHBvcnQgY2xhc3MgTWFya2Rvd25SZW5kZXJlciB7XG4gIHB1YmxpYyBzdGF0aWMgZnJvbVNjaGVtYShzY2hlbWE6IFNjaGVtYSwgb3B0aW9uczogTWFya2Rvd25Gb3JtYXR0aW5nT3B0aW9ucyk6IE1hcmtkb3duRG9jdW1lbnQge1xuICAgIGNvbnN0IGRvY3VtZW50YXRpb24gPSBuZXcgTWFya2Rvd25Eb2N1bWVudCgpO1xuXG4gICAgaWYgKHNjaGVtYS52ZXJzaW9uICE9PSBDVVJSRU5UX1NDSEVNQV9WRVJTSU9OKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYFVuZXhwZWN0ZWQgc2NoZW1hIHZlcnNpb246ICR7c2NoZW1hLnZlcnNpb259YCk7XG4gICAgfVxuXG4gICAgaWYgKHNjaGVtYS5yZWFkbWUpIHtcbiAgICAgIGNvbnN0IG1kID0gbmV3IE1hcmtkb3duRG9jdW1lbnQoKTtcbiAgICAgIG1kLmxpbmVzKHNjaGVtYS5yZWFkbWUpO1xuICAgICAgZG9jdW1lbnRhdGlvbi5zZWN0aW9uKG1kKTtcbiAgICB9XG5cbiAgICBpZiAoc2NoZW1hLmFwaVJlZmVyZW5jZSkge1xuICAgICAgY29uc3QgcmVuZGVyZXIgPSBuZXcgTWFya2Rvd25SZW5kZXJlcih7XG4gICAgICAgIGFuY2hvckZvcm1hdHRlcjogb3B0aW9ucy5hbmNob3JGb3JtYXR0ZXIsXG4gICAgICAgIGxpbmtGb3JtYXR0ZXI6IG9wdGlvbnMubGlua0Zvcm1hdHRlcixcbiAgICAgICAgdHlwZUZvcm1hdHRlcjogb3B0aW9ucy50eXBlRm9ybWF0dGVyLFxuICAgICAgICBsYW5ndWFnZTogTGFuZ3VhZ2UuZnJvbVN0cmluZyhzY2hlbWEubGFuZ3VhZ2UpLFxuICAgICAgICAuLi5zY2hlbWEubWV0YWRhdGEsXG4gICAgICB9KTtcblxuICAgICAgZG9jdW1lbnRhdGlvbi5zZWN0aW9uKHJlbmRlcmVyLnZpc2l0QXBpUmVmZXJlbmNlKHNjaGVtYS5hcGlSZWZlcmVuY2UsIG9wdGlvbnMuaGVhZGVyKSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGRvY3VtZW50YXRpb247XG4gIH1cblxuICBwdWJsaWMgc3RhdGljIGZyb21TdWJtb2R1bGVzKHN1Ym1vZHVsZXM6IHJlYWRvbmx5IHJlZmxlY3QuU3VibW9kdWxlW10sIGZpbGVTdWZmaXg6IHN0cmluZywgb3B0aW9uczogTWFya2Rvd25SZW5kZXJlck9wdGlvbnMpOiBNYXJrZG93bkRvY3VtZW50IHtcbiAgICBjb25zdCBkb2N1bWVudGF0aW9uID0gbmV3IE1hcmtkb3duRG9jdW1lbnQoKTtcblxuICAgIGNvbnN0IHJlbmRlcmVyID0gbmV3IE1hcmtkb3duUmVuZGVyZXIoe1xuICAgICAgYW5jaG9yRm9ybWF0dGVyOiBvcHRpb25zLmFuY2hvckZvcm1hdHRlcixcbiAgICAgIGxpbmtGb3JtYXR0ZXI6IG9wdGlvbnMubGlua0Zvcm1hdHRlcixcbiAgICAgIHR5cGVGb3JtYXR0ZXI6IG9wdGlvbnMudHlwZUZvcm1hdHRlcixcbiAgICAgIGxhbmd1YWdlOiBvcHRpb25zLmxhbmd1YWdlLFxuICAgICAgcGFja2FnZU5hbWU6IG9wdGlvbnMucGFja2FnZU5hbWUsXG4gICAgICBwYWNrYWdlVmVyc2lvbjogb3B0aW9ucy5wYWNrYWdlVmVyc2lvbixcbiAgICB9KTtcblxuICAgIGNvbnN0IGFwaVJlZiA9IHJlbmRlcmVyLnZpc2l0U3VibW9kdWxlcyhzdWJtb2R1bGVzLCBmaWxlU3VmZml4KTtcbiAgICBkb2N1bWVudGF0aW9uLnNlY3Rpb24oYXBpUmVmKTtcblxuICAgIHJldHVybiBkb2N1bWVudGF0aW9uO1xuICB9XG5cbiAgcHJpdmF0ZSByZWFkb25seSBhbmNob3JGb3JtYXR0ZXI6IE5vbk51bGxhYmxlPE1hcmtkb3duRm9ybWF0dGluZ09wdGlvbnNbJ2FuY2hvckZvcm1hdHRlciddPjtcbiAgcHJpdmF0ZSByZWFkb25seSBsaW5rRm9ybWF0dGVyOiBOb25OdWxsYWJsZTxNYXJrZG93bkZvcm1hdHRpbmdPcHRpb25zWydsaW5rRm9ybWF0dGVyJ10+O1xuICBwcml2YXRlIHJlYWRvbmx5IHR5cGVGb3JtYXR0ZXI6IE5vbk51bGxhYmxlPE1hcmtkb3duRm9ybWF0dGluZ09wdGlvbnNbJ3R5cGVGb3JtYXR0ZXInXT47XG4gIHByaXZhdGUgcmVhZG9ubHkgbWV0YWRhdGE6IEFzc2VtYmx5TWV0YWRhdGFTY2hlbWE7XG4gIHByaXZhdGUgcmVhZG9ubHkgbGFuZ3VhZ2U6IExhbmd1YWdlO1xuXG4gIGNvbnN0cnVjdG9yKG9wdGlvbnM6IE1hcmtkb3duUmVuZGVyZXJPcHRpb25zKSB7XG4gICAgdGhpcy5hbmNob3JGb3JtYXR0ZXIgPSBvcHRpb25zLmFuY2hvckZvcm1hdHRlciA/PyBkZWZhdWx0QW5jaG9yRm9ybWF0dGVyO1xuICAgIHRoaXMubGlua0Zvcm1hdHRlciA9IG9wdGlvbnMubGlua0Zvcm1hdHRlciA/PyBkZWZhdWx0TGlua0Zvcm1hdHRlcjtcbiAgICB0aGlzLnR5cGVGb3JtYXR0ZXIgPSBvcHRpb25zLnR5cGVGb3JtYXR0ZXIgPz8gZGVmYXVsdFR5cGVGb3JtYXR0ZXI7XG4gICAgdGhpcy5sYW5ndWFnZSA9IG9wdGlvbnMubGFuZ3VhZ2U7XG4gICAgdGhpcy5tZXRhZGF0YSA9IHtcbiAgICAgIHBhY2thZ2VOYW1lOiBvcHRpb25zLnBhY2thZ2VOYW1lLFxuICAgICAgcGFja2FnZVZlcnNpb246IG9wdGlvbnMucGFja2FnZVZlcnNpb24sXG4gICAgICBzdWJtb2R1bGU6IG9wdGlvbnMuc3VibW9kdWxlLFxuICAgIH07XG4gIH1cblxuICBwdWJsaWMgdmlzaXRTdWJtb2R1bGVzKHN1Ym1vZHVsZXM6IHJlYWRvbmx5IHJlZmxlY3QuU3VibW9kdWxlW10sIGZpbGVTdWZmaXg6IHN0cmluZyk6IE1hcmtkb3duRG9jdW1lbnQge1xuICAgIGNvbnN0IG1kID0gbmV3IE1hcmtkb3duRG9jdW1lbnQoeyBoZWFkZXI6IHsgdGl0bGU6ICdTdWJtb2R1bGVzJyB9LCBpZDogJ3N1Ym1vZHVsZXMnIH0pO1xuICAgIG1kLmxpbmVzKCdUaGUgZm9sbG93aW5nIHN1Ym1vZHVsZXMgYXJlIGF2YWlsYWJsZTonKTtcbiAgICBtZC5saW5lcygnJyk7XG4gICAgZm9yIChjb25zdCBzdWJtb2R1bGUgb2Ygc3VibW9kdWxlcykge1xuICAgICAgbWQubGluZXMoYC0gWyR7c3VibW9kdWxlUmVsTmFtZShzdWJtb2R1bGUpfV0oLi8ke3N1Ym1vZHVsZVJlbE5hbWUoc3VibW9kdWxlKX0uJHtmaWxlU3VmZml4fSlgKTtcbiAgICB9XG4gICAgbWQubGluZXMoJycpO1xuICAgIHJldHVybiBtZDtcbiAgfVxuXG4gIHB1YmxpYyB2aXNpdEFwaVJlZmVyZW5jZShcbiAgICBhcGlSZWY6IEFwaVJlZmVyZW5jZVNjaGVtYSxcbiAgICBoZWFkZXI6IHsgdGl0bGU6IHN0cmluZzsgaWQ6IHN0cmluZyB9ID0geyB0aXRsZTogJ0FQSSBSZWZlcmVuY2UnLCBpZDogJ2FwaS1yZWZlcmVuY2UnIH0sXG4gICk6IE1hcmtkb3duRG9jdW1lbnQge1xuICAgIGNvbnN0IG1kID0gbmV3IE1hcmtkb3duRG9jdW1lbnQoeyBoZWFkZXI6IHsgdGl0bGU6IGhlYWRlci50aXRsZSB9LCBpZDogaGVhZGVyLmlkIH0pO1xuICAgIG1kLnNlY3Rpb24odGhpcy52aXNpdENvbnN0cnVjdHMoYXBpUmVmLmNvbnN0cnVjdHMpKTtcbiAgICBtZC5zZWN0aW9uKHRoaXMudmlzaXRTdHJ1Y3RzKGFwaVJlZi5zdHJ1Y3RzKSk7XG4gICAgbWQuc2VjdGlvbih0aGlzLnZpc2l0Q2xhc3NlcyhhcGlSZWYuY2xhc3NlcykpO1xuICAgIG1kLnNlY3Rpb24odGhpcy52aXNpdEludGVyZmFjZXMoYXBpUmVmLmludGVyZmFjZXMpKTtcbiAgICBtZC5zZWN0aW9uKHRoaXMudmlzaXRFbnVtcyhhcGlSZWYuZW51bXMpKTtcbiAgICByZXR1cm4gbWQ7XG4gIH1cblxuICBwdWJsaWMgdmlzaXRDb25zdHJ1Y3RzKFxuICAgIGNvbnN0cnVjdHM6IENvbnN0cnVjdFNjaGVtYVtdLFxuICApOiBNYXJrZG93bkRvY3VtZW50IHtcbiAgICBpZiAoY29uc3RydWN0cy5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybiBNYXJrZG93bkRvY3VtZW50LkVNUFRZO1xuICAgIH1cblxuICAgIGNvbnN0IG1kID0gbmV3IE1hcmtkb3duRG9jdW1lbnQoeyBoZWFkZXI6IHsgdGl0bGU6ICdDb25zdHJ1Y3RzJyB9IH0pO1xuICAgIGZvciAoY29uc3QgY29uc3RydWN0IG9mIGNvbnN0cnVjdHMpIHtcbiAgICAgIG1kLnNlY3Rpb24odGhpcy52aXNpdENvbnN0cnVjdChjb25zdHJ1Y3QpKTtcbiAgICB9XG4gICAgcmV0dXJuIG1kO1xuICB9XG5cbiAgcHVibGljIHZpc2l0U3RydWN0cyhcbiAgICBzdHJ1Y3RzOiBTdHJ1Y3RTY2hlbWFbXSxcbiAgKTogTWFya2Rvd25Eb2N1bWVudCB7XG4gICAgaWYgKHN0cnVjdHMubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm4gTWFya2Rvd25Eb2N1bWVudC5FTVBUWTtcbiAgICB9XG5cbiAgICBjb25zdCBtZCA9IG5ldyBNYXJrZG93bkRvY3VtZW50KHsgaGVhZGVyOiB7IHRpdGxlOiAnU3RydWN0cycgfSB9KTtcbiAgICBmb3IgKGNvbnN0IHN0cnVjdCBvZiBzdHJ1Y3RzKSB7XG4gICAgICBtZC5zZWN0aW9uKHRoaXMudmlzaXRTdHJ1Y3Qoc3RydWN0KSk7XG4gICAgfVxuICAgIHJldHVybiBtZDtcbiAgfVxuXG4gIHB1YmxpYyB2aXNpdENsYXNzZXMoXG4gICAgY2xhc3NlczogQ2xhc3NTY2hlbWFbXSxcbiAgKTogTWFya2Rvd25Eb2N1bWVudCB7XG4gICAgaWYgKGNsYXNzZXMubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm4gTWFya2Rvd25Eb2N1bWVudC5FTVBUWTtcbiAgICB9XG5cbiAgICBjb25zdCBtZCA9IG5ldyBNYXJrZG93bkRvY3VtZW50KHsgaGVhZGVyOiB7IHRpdGxlOiAnQ2xhc3NlcycgfSB9KTtcbiAgICBmb3IgKGNvbnN0IGtsYXNzIG9mIGNsYXNzZXMpIHtcbiAgICAgIG1kLnNlY3Rpb24odGhpcy52aXNpdENsYXNzKGtsYXNzKSk7XG4gICAgfVxuICAgIHJldHVybiBtZDtcbiAgfVxuXG4gIHB1YmxpYyB2aXNpdEludGVyZmFjZXMoXG4gICAgaWZhY2VzOiBJbnRlcmZhY2VTY2hlbWFbXSxcbiAgKTogTWFya2Rvd25Eb2N1bWVudCB7XG4gICAgaWYgKGlmYWNlcy5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybiBNYXJrZG93bkRvY3VtZW50LkVNUFRZO1xuICAgIH1cblxuICAgIGNvbnN0IG1kID0gbmV3IE1hcmtkb3duRG9jdW1lbnQoeyBoZWFkZXI6IHsgdGl0bGU6ICdQcm90b2NvbHMnIH0gfSk7XG4gICAgZm9yIChjb25zdCBpZmFjZSBvZiBpZmFjZXMpIHtcbiAgICAgIG1kLnNlY3Rpb24odGhpcy52aXNpdEludGVyZmFjZShpZmFjZSkpO1xuICAgIH1cbiAgICByZXR1cm4gbWQ7XG4gIH1cblxuICBwdWJsaWMgdmlzaXRFbnVtcyhcbiAgICBlbnVtczogRW51bVNjaGVtYVtdLFxuICApOiBNYXJrZG93bkRvY3VtZW50IHtcbiAgICBpZiAoZW51bXMubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm4gTWFya2Rvd25Eb2N1bWVudC5FTVBUWTtcbiAgICB9XG5cbiAgICBjb25zdCBtZCA9IG5ldyBNYXJrZG93bkRvY3VtZW50KHsgaGVhZGVyOiB7IHRpdGxlOiAnRW51bXMnIH0gfSk7XG4gICAgZm9yIChjb25zdCBlbnUgb2YgZW51bXMpIHtcbiAgICAgIG1kLnNlY3Rpb24odGhpcy52aXNpdEVudW0oZW51KSk7XG4gICAgfVxuICAgIHJldHVybiBtZDtcbiAgfVxuXG4gIHB1YmxpYyB2aXNpdENvbnN0cnVjdChcbiAgICBjb25zdHJ1Y3Q6IENvbnN0cnVjdFNjaGVtYSxcbiAgKTogTWFya2Rvd25Eb2N1bWVudCB7XG4gICAgcmV0dXJuIHRoaXMudmlzaXRDbGFzcyhjb25zdHJ1Y3QpO1xuICB9XG5cbiAgcHVibGljIHZpc2l0U3RydWN0KFxuICAgIHN0cnVjdDogU3RydWN0U2NoZW1hLFxuICApOiBNYXJrZG93bkRvY3VtZW50IHtcbiAgICBjb25zdCBtZCA9IG5ldyBNYXJrZG93bkRvY3VtZW50KHtcbiAgICAgIGlkOiB0aGlzLmFuY2hvckZvcm1hdHRlcih7XG4gICAgICAgIGlkOiBzdHJ1Y3QuaWQsXG4gICAgICAgIGRpc3BsYXlOYW1lOiBzdHJ1Y3QuZGlzcGxheU5hbWUsXG4gICAgICAgIGZxbjogc3RydWN0LmZxbixcbiAgICAgICAgLi4udGhpcy5tZXRhZGF0YSxcbiAgICAgIH0pLFxuICAgICAgaGVhZGVyOiB7IHRpdGxlOiBzdHJ1Y3QuZGlzcGxheU5hbWUgfSxcbiAgICB9KTtcblxuICAgIGlmIChzdHJ1Y3QuZG9jcykge1xuICAgICAgbWQuZG9jcyhzdHJ1Y3QuZG9jcywgdGhpcy5sYW5ndWFnZSk7XG4gICAgfVxuXG4gICAgY29uc3QgaW5pdGlhbGl6ZXIgPSBuZXcgTWFya2Rvd25Eb2N1bWVudCh7XG4gICAgICBpZDogdGhpcy5hbmNob3JGb3JtYXR0ZXIoe1xuICAgICAgICBpZDogYCR7c3RydWN0LmlkfS5Jbml0aWFsaXplcmAsXG4gICAgICAgIGRpc3BsYXlOYW1lOiAnSW5pdGlhbGl6ZXInLFxuICAgICAgICBmcW46IGAke3N0cnVjdC5mcW59LkluaXRpYWxpemVyYCxcbiAgICAgICAgLi4udGhpcy5tZXRhZGF0YSxcbiAgICAgIH0pLFxuICAgICAgaGVhZGVyOiB7IHRpdGxlOiAnSW5pdGlhbGl6ZXInIH0sXG4gICAgfSk7XG5cbiAgICBpZiAoc3RydWN0LnVzYWdlKSB7XG4gICAgICBpbml0aWFsaXplci5jb2RlKHRoaXMubGFuZ3VhZ2UudG9TdHJpbmcoKSwgc3RydWN0LnVzYWdlKTtcbiAgICB9XG5cbiAgICBtZC5zZWN0aW9uKGluaXRpYWxpemVyKTtcbiAgICBtZC5zZWN0aW9uKHRoaXMudmlzaXRQcm9wZXJ0aWVzKHN0cnVjdC5wcm9wZXJ0aWVzKSk7XG4gICAgcmV0dXJuIG1kO1xuICB9XG5cbiAgcHVibGljIHZpc2l0Q2xhc3MoXG4gICAga2xhc3M6IENsYXNzU2NoZW1hLFxuICApOiBNYXJrZG93bkRvY3VtZW50IHtcbiAgICBjb25zdCBtZCA9IG5ldyBNYXJrZG93bkRvY3VtZW50KHtcbiAgICAgIGlkOiB0aGlzLmFuY2hvckZvcm1hdHRlcih7XG4gICAgICAgIGlkOiBrbGFzcy5pZCxcbiAgICAgICAgZGlzcGxheU5hbWU6IGtsYXNzLmRpc3BsYXlOYW1lLFxuICAgICAgICBmcW46IGtsYXNzLmZxbixcbiAgICAgICAgLi4udGhpcy5tZXRhZGF0YSxcbiAgICAgIH0pLFxuICAgICAgaGVhZGVyOiB7IHRpdGxlOiBrbGFzcy5kaXNwbGF5TmFtZSB9LFxuICAgIH0pO1xuXG4gICAgaWYgKGtsYXNzLmludGVyZmFjZXMubGVuZ3RoID4gMCkge1xuICAgICAgY29uc3QgaWZhY2VzID0gW107XG4gICAgICBmb3IgKGNvbnN0IGlmYWNlIG9mIGtsYXNzLmludGVyZmFjZXMpIHtcbiAgICAgICAgaWZhY2VzLnB1c2godGhpcy5saW5rRm9ybWF0dGVyKGlmYWNlLCB0aGlzLm1ldGFkYXRhKSk7XG4gICAgICB9XG4gICAgICBtZC5idWxsZXQoYCR7TWFya2Rvd25Eb2N1bWVudC5pdGFsaWMoJ0ltcGxlbWVudHM6Jyl9ICR7aWZhY2VzLmpvaW4oJywgJyl9YCk7XG4gICAgICBtZC5saW5lcygnJyk7XG4gICAgfVxuXG4gICAgaWYgKGtsYXNzLmRvY3MpIHtcbiAgICAgIG1kLmRvY3Moa2xhc3MuZG9jcywgdGhpcy5sYW5ndWFnZSk7XG4gICAgfVxuXG4gICAgaWYgKGtsYXNzLmluaXRpYWxpemVyKSB7XG4gICAgICBtZC5zZWN0aW9uKHRoaXMudmlzaXRJbml0aWFsaXplcihrbGFzcy5pbml0aWFsaXplcikpO1xuICAgIH1cblxuICAgIG1kLnNlY3Rpb24odGhpcy52aXNpdEluc3RhbmNlTWV0aG9kcyhrbGFzcy5pbnN0YW5jZU1ldGhvZHMpKTtcbiAgICBtZC5zZWN0aW9uKHRoaXMudmlzaXRTdGF0aWNGdW5jdGlvbnMoa2xhc3Muc3RhdGljTWV0aG9kcykpO1xuICAgIG1kLnNlY3Rpb24odGhpcy52aXNpdFByb3BlcnRpZXMoa2xhc3MucHJvcGVydGllcykpO1xuICAgIG1kLnNlY3Rpb24odGhpcy52aXNpdENvbnN0YW50cyhrbGFzcy5jb25zdGFudHMpKTtcbiAgICByZXR1cm4gbWQ7XG4gIH1cblxuICBwdWJsaWMgdmlzaXRJbnRlcmZhY2UoXG4gICAgaWZhY2U6IEludGVyZmFjZVNjaGVtYSxcbiAgKTogTWFya2Rvd25Eb2N1bWVudCB7XG4gICAgY29uc3QgbWQgPSBuZXcgTWFya2Rvd25Eb2N1bWVudCh7XG4gICAgICBpZDogdGhpcy5hbmNob3JGb3JtYXR0ZXIoe1xuICAgICAgICBpZDogaWZhY2UuaWQsXG4gICAgICAgIGRpc3BsYXlOYW1lOiBpZmFjZS5kaXNwbGF5TmFtZSxcbiAgICAgICAgZnFuOiBpZmFjZS5mcW4sXG4gICAgICAgIC4uLnRoaXMubWV0YWRhdGEsXG4gICAgICB9KSxcbiAgICAgIGhlYWRlcjogeyB0aXRsZTogaWZhY2UuZGlzcGxheU5hbWUgfSxcbiAgICB9KTtcblxuICAgIGlmIChpZmFjZS5pbnRlcmZhY2VzLmxlbmd0aCA+IDApIHtcbiAgICAgIGNvbnN0IGJhc2VzID0gW107XG4gICAgICBmb3IgKGNvbnN0IGJhc2Ugb2YgaWZhY2UuaW50ZXJmYWNlcykge1xuICAgICAgICBiYXNlcy5wdXNoKHRoaXMubGlua0Zvcm1hdHRlcihiYXNlLCB0aGlzLm1ldGFkYXRhKSk7XG4gICAgICB9XG4gICAgICBtZC5idWxsZXQoYCR7TWFya2Rvd25Eb2N1bWVudC5pdGFsaWMoJ0V4dGVuZHM6Jyl9ICR7YmFzZXMuam9pbignLCAnKX1gKTtcbiAgICAgIG1kLmxpbmVzKCcnKTtcbiAgICB9XG5cbiAgICBpZiAoaWZhY2UuaW1wbGVtZW50YXRpb25zLmxlbmd0aCA+IDApIHtcbiAgICAgIGNvbnN0IGltcGxzID0gW107XG4gICAgICBmb3IgKGNvbnN0IGltcGwgb2YgaWZhY2UuaW1wbGVtZW50YXRpb25zKSB7XG4gICAgICAgIGltcGxzLnB1c2godGhpcy5saW5rRm9ybWF0dGVyKGltcGwsIHRoaXMubWV0YWRhdGEpKTtcbiAgICAgIH1cbiAgICAgIG1kLmJ1bGxldChgJHtNYXJrZG93bkRvY3VtZW50Lml0YWxpYygnSW1wbGVtZW50ZWQgQnk6Jyl9ICR7aW1wbHMuam9pbignLCAnKX1gKTtcbiAgICAgIG1kLmxpbmVzKCcnKTtcbiAgICB9XG5cbiAgICBpZiAoaWZhY2UuZG9jcykge1xuICAgICAgbWQuZG9jcyhpZmFjZS5kb2NzLCB0aGlzLmxhbmd1YWdlKTtcbiAgICB9XG5cbiAgICBtZC5zZWN0aW9uKHRoaXMudmlzaXRJbnN0YW5jZU1ldGhvZHMoaWZhY2UuaW5zdGFuY2VNZXRob2RzKSk7XG4gICAgbWQuc2VjdGlvbih0aGlzLnZpc2l0UHJvcGVydGllcyhpZmFjZS5wcm9wZXJ0aWVzKSk7XG4gICAgcmV0dXJuIG1kO1xuICB9XG5cbiAgcHVibGljIHZpc2l0RW51bShcbiAgICBlbnU6IEVudW1TY2hlbWEsXG4gICk6IE1hcmtkb3duRG9jdW1lbnQge1xuICAgIGNvbnN0IG1kID0gbmV3IE1hcmtkb3duRG9jdW1lbnQoe1xuICAgICAgaWQ6IHRoaXMuYW5jaG9yRm9ybWF0dGVyKHtcbiAgICAgICAgaWQ6IGVudS5pZCxcbiAgICAgICAgZGlzcGxheU5hbWU6IGVudS5kaXNwbGF5TmFtZSxcbiAgICAgICAgZnFuOiBlbnUuZnFuLFxuICAgICAgICAuLi50aGlzLm1ldGFkYXRhLFxuICAgICAgfSksXG4gICAgICBoZWFkZXI6IHsgdGl0bGU6IGVudS5kaXNwbGF5TmFtZSB9LFxuICAgIH0pO1xuXG4gICAgaWYgKGVudS5kb2NzKSB7XG4gICAgICBtZC5kb2NzKGVudS5kb2NzLCB0aGlzLmxhbmd1YWdlKTtcbiAgICB9XG5cbiAgICBtZC5zZWN0aW9uKHRoaXMudmlzaXRFbnVtTWVtYmVycyhlbnUubWVtYmVycykpO1xuXG4gICAgcmV0dXJuIG1kO1xuICB9XG5cbiAgcHVibGljIHZpc2l0RW51bU1lbWJlcnMoXG4gICAgZW51czogRW51bU1lbWJlclNjaGVtYVtdLFxuICApOiBNYXJrZG93bkRvY3VtZW50IHtcbiAgICBpZiAoZW51cy5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybiBNYXJrZG93bkRvY3VtZW50LkVNUFRZO1xuICAgIH1cblxuICAgIGNvbnN0IG1kID0gbmV3IE1hcmtkb3duRG9jdW1lbnQoeyBoZWFkZXI6IHsgdGl0bGU6ICdNZW1iZXJzJyB9IH0pO1xuXG4gICAgbWQudGFibGUodGhpcy5jcmVhdGVUYWJsZShlbnVzKSk7XG4gICAgbWQuc3BsaXQoKTtcblxuICAgIGZvciAoY29uc3QgZW51IG9mIGVudXMpIHtcbiAgICAgIG1kLnNlY3Rpb24odGhpcy52aXNpdEVudW1NZW1iZXIoZW51KSk7XG4gICAgfVxuICAgIHJldHVybiBtZDtcbiAgfVxuXG4gIHB1YmxpYyB2aXNpdFByb3BlcnRpZXMoXG4gICAgcHJvcGVydGllczogUHJvcGVydHlTY2hlbWFbXSxcbiAgKTogTWFya2Rvd25Eb2N1bWVudCB7XG4gICAgaWYgKHByb3BlcnRpZXMubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm4gTWFya2Rvd25Eb2N1bWVudC5FTVBUWTtcbiAgICB9XG5cbiAgICBjb25zdCBtZCA9IG5ldyBNYXJrZG93bkRvY3VtZW50KHsgaGVhZGVyOiB7IHRpdGxlOiAnUHJvcGVydGllcycgfSB9KTtcblxuICAgIG1kLnRhYmxlKHRoaXMuY3JlYXRlVGFibGVXaXRoVHlwZXMocHJvcGVydGllcykpO1xuICAgIG1kLnNwbGl0KCk7XG5cbiAgICBmb3IgKGNvbnN0IHByb3Agb2YgcHJvcGVydGllcykge1xuICAgICAgbWQuc2VjdGlvbih0aGlzLnZpc2l0UHJvcGVydHkocHJvcCkpO1xuICAgIH1cblxuICAgIHJldHVybiBtZDtcbiAgfVxuXG4gIHB1YmxpYyB2aXNpdEluaXRpYWxpemVyKFxuICAgIGluaXQ6IEluaXRpYWxpemVyU2NoZW1hLFxuICApOiBNYXJrZG93bkRvY3VtZW50IHtcbiAgICBjb25zdCBtZCA9IG5ldyBNYXJrZG93bkRvY3VtZW50KHtcbiAgICAgIGlkOiB0aGlzLmFuY2hvckZvcm1hdHRlcih7XG4gICAgICAgIGlkOiBpbml0LmlkLFxuICAgICAgICBkaXNwbGF5TmFtZTogaW5pdC5kaXNwbGF5TmFtZSxcbiAgICAgICAgZnFuOiBpbml0LmZxbixcbiAgICAgICAgLi4udGhpcy5tZXRhZGF0YSxcbiAgICAgIH0pLFxuICAgICAgaGVhZGVyOiB7XG4gICAgICAgIHRpdGxlOiAnSW5pdGlhbGl6ZXJzJyxcbiAgICAgIH0sXG4gICAgfSk7XG5cbiAgICBpZiAoaW5pdC51c2FnZSkge1xuICAgICAgbWQuY29kZSh0aGlzLmxhbmd1YWdlLnRvU3RyaW5nKCksIGluaXQudXNhZ2UpO1xuICAgIH1cblxuICAgIG1kLnRhYmxlKHRoaXMuY3JlYXRlVGFibGVXaXRoVHlwZXMoaW5pdC5wYXJhbWV0ZXJzKSk7XG4gICAgbWQuc3BsaXQoKTtcblxuICAgIGZvciAoY29uc3QgcGFyYW0gb2YgaW5pdC5wYXJhbWV0ZXJzKSB7XG4gICAgICBtZC5zZWN0aW9uKHRoaXMudmlzaXRQYXJhbWV0ZXIocGFyYW0pKTtcbiAgICB9XG5cbiAgICByZXR1cm4gbWQ7XG4gIH1cblxuICBwdWJsaWMgdmlzaXRJbnN0YW5jZU1ldGhvZHMoXG4gICAgbWV0aG9kczogTWV0aG9kU2NoZW1hW10sXG4gICk6IE1hcmtkb3duRG9jdW1lbnQge1xuICAgIGlmIChtZXRob2RzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgcmV0dXJuIE1hcmtkb3duRG9jdW1lbnQuRU1QVFk7XG4gICAgfVxuXG4gICAgY29uc3QgbWQgPSBuZXcgTWFya2Rvd25Eb2N1bWVudCh7IGhlYWRlcjogeyB0aXRsZTogJ01ldGhvZHMnIH0gfSk7XG5cbiAgICBtZC50YWJsZSh0aGlzLmNyZWF0ZVRhYmxlKG1ldGhvZHMpKTtcbiAgICBtZC5zcGxpdCgpO1xuXG4gICAgZm9yIChjb25zdCBtZXRob2Qgb2YgbWV0aG9kcykge1xuICAgICAgbWQuc2VjdGlvbih0aGlzLnZpc2l0SW5zdGFuY2VNZXRob2QobWV0aG9kKSk7XG4gICAgfVxuICAgIHJldHVybiBtZDtcbiAgfVxuXG4gIHB1YmxpYyB2aXNpdFN0YXRpY0Z1bmN0aW9ucyhcbiAgICBtZXRob2RzOiBNZXRob2RTY2hlbWFbXSxcbiAgKSB7XG4gICAgaWYgKG1ldGhvZHMubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm4gTWFya2Rvd25Eb2N1bWVudC5FTVBUWTtcbiAgICB9XG5cbiAgICBjb25zdCBtZCA9IG5ldyBNYXJrZG93bkRvY3VtZW50KHsgaGVhZGVyOiB7IHRpdGxlOiAnU3RhdGljIEZ1bmN0aW9ucycgfSB9KTtcblxuICAgIG1kLnRhYmxlKHRoaXMuY3JlYXRlVGFibGUobWV0aG9kcykpO1xuICAgIG1kLnNwbGl0KCk7XG5cbiAgICBmb3IgKGNvbnN0IG1ldGhvZCBvZiBtZXRob2RzKSB7XG4gICAgICBtZC5zZWN0aW9uKHRoaXMudmlzaXRTdGF0aWNGdW5jdGlvbihtZXRob2QpKTtcbiAgICB9XG4gICAgcmV0dXJuIG1kO1xuICB9XG5cbiAgcHVibGljIHZpc2l0Q29uc3RhbnRzKFxuICAgIGNvbnN0YW50czogUHJvcGVydHlTY2hlbWFbXSxcbiAgKTogTWFya2Rvd25Eb2N1bWVudCB7XG4gICAgaWYgKGNvbnN0YW50cy5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybiBNYXJrZG93bkRvY3VtZW50LkVNUFRZO1xuICAgIH1cblxuICAgIGNvbnN0IG1kID0gbmV3IE1hcmtkb3duRG9jdW1lbnQoeyBoZWFkZXI6IHsgdGl0bGU6ICdDb25zdGFudHMnIH0gfSk7XG5cbiAgICBtZC50YWJsZSh0aGlzLmNyZWF0ZVRhYmxlV2l0aFR5cGVzKGNvbnN0YW50cykpO1xuICAgIG1kLnNwbGl0KCk7XG5cbiAgICBmb3IgKGNvbnN0IGNvbiBvZiBjb25zdGFudHMpIHtcbiAgICAgIG1kLnNlY3Rpb24odGhpcy52aXNpdENvbnN0YW50KGNvbikpO1xuICAgIH1cblxuICAgIHJldHVybiBtZDtcbiAgfVxuXG4gIHB1YmxpYyB2aXNpdEVudW1NZW1iZXIoXG4gICAgZW06IEVudW1NZW1iZXJTY2hlbWEsXG4gICk6IE1hcmtkb3duRG9jdW1lbnQge1xuICAgIGNvbnN0IG1kID0gbmV3IE1hcmtkb3duRG9jdW1lbnQoe1xuICAgICAgaWQ6IHRoaXMuYW5jaG9yRm9ybWF0dGVyKHtcbiAgICAgICAgaWQ6IGVtLmlkLFxuICAgICAgICBkaXNwbGF5TmFtZTogZW0uZGlzcGxheU5hbWUsXG4gICAgICAgIGZxbjogZW0uZnFuLFxuICAgICAgICAuLi50aGlzLm1ldGFkYXRhLFxuICAgICAgfSksXG4gICAgICBoZWFkZXI6IHtcbiAgICAgICAgdGl0bGU6IGVtLmRpc3BsYXlOYW1lLFxuICAgICAgICBwcmU6IHRydWUsXG4gICAgICAgIHN0cmlrZTogZW0uZG9jcy5kZXByZWNhdGVkLFxuICAgICAgfSxcbiAgICB9KTtcblxuICAgIGlmIChlbS5kb2NzLmRlcHJlY2F0ZWQpIHtcbiAgICAgIG1kLmJ1bGxldChcbiAgICAgICAgYCR7TWFya2Rvd25Eb2N1bWVudC5pdGFsaWMoJ0RlcHJlY2F0ZWQ6Jyl9ICR7ZW0uZG9jcy5kZXByZWNhdGlvblJlYXNvbn1gLFxuICAgICAgKTtcbiAgICAgIG1kLmxpbmVzKCcnKTtcbiAgICB9XG5cbiAgICBpZiAoZW0uZG9jcykge1xuICAgICAgbWQuZG9jcyhlbS5kb2NzLCB0aGlzLmxhbmd1YWdlKTtcbiAgICB9XG5cbiAgICBtZC5zcGxpdCgpO1xuICAgIG1kLmxpbmVzKCcnKTtcblxuICAgIHJldHVybiBtZDtcbiAgfVxuXG4gIHB1YmxpYyB2aXNpdFByb3BlcnR5KFxuICAgIHByb3A6IFByb3BlcnR5U2NoZW1hLFxuICApOiBNYXJrZG93bkRvY3VtZW50IHtcbiAgICBjb25zdCBvcHRpb25hbGl0eSA9IHByb3Aub3B0aW9uYWxcbiAgICAgID8gJ09wdGlvbmFsJ1xuICAgICAgOiAnUmVxdWlyZWQnO1xuXG4gICAgY29uc3QgbWQgPSBuZXcgTWFya2Rvd25Eb2N1bWVudCh7XG4gICAgICBpZDogdGhpcy5hbmNob3JGb3JtYXR0ZXIoe1xuICAgICAgICBpZDogcHJvcC5pZCxcbiAgICAgICAgZGlzcGxheU5hbWU6IHByb3AuZGlzcGxheU5hbWUsXG4gICAgICAgIGZxbjogcHJvcC5mcW4sXG4gICAgICAgIC4uLnRoaXMubWV0YWRhdGEsXG4gICAgICB9KSxcbiAgICAgIGhlYWRlcjoge1xuICAgICAgICB0aXRsZTogcHJvcC5kaXNwbGF5TmFtZSxcbiAgICAgICAgc3VwOiBvcHRpb25hbGl0eSxcbiAgICAgICAgcHJlOiB0cnVlLFxuICAgICAgICBzdHJpa2U6IHByb3AuZG9jcy5kZXByZWNhdGVkLFxuICAgICAgfSxcbiAgICB9KTtcblxuICAgIGlmIChwcm9wLmRvY3MuZGVwcmVjYXRlZCkge1xuICAgICAgbWQuYnVsbGV0KFxuICAgICAgICBgJHtNYXJrZG93bkRvY3VtZW50Lml0YWxpYygnRGVwcmVjYXRlZDonKX0gJHtwcm9wLmRvY3MuZGVwcmVjYXRpb25SZWFzb259YCxcbiAgICAgICk7XG4gICAgICBtZC5saW5lcygnJyk7XG4gICAgfVxuXG4gICAgaWYgKHByb3AudXNhZ2UpIHtcbiAgICAgIG1kLmNvZGUodGhpcy5sYW5ndWFnZS50b1N0cmluZygpLCBwcm9wLnVzYWdlKTtcbiAgICB9XG5cbiAgICBjb25zdCBtZXRhZGF0YTogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHtcbiAgICAgIFR5cGU6IHRoaXMudHlwZUZvcm1hdHRlcihwcm9wLnR5cGUsIHRoaXMubWV0YWRhdGEsIHRoaXMubGlua0Zvcm1hdHRlciksXG4gICAgfTtcblxuICAgIGlmIChwcm9wLmRlZmF1bHQpIHtcbiAgICAgIGNvbnN0IHNhbml0aXplZCA9IE1hcmtkb3duRG9jdW1lbnQuc2FuaXRpemUocHJvcC5kZWZhdWx0KTtcbiAgICAgIG1ldGFkYXRhLkRlZmF1bHQgPSBNYXJrZG93bkRvY3VtZW50LnJlbW92ZU5ld2xpbmVzKHNhbml0aXplZCk7XG4gICAgfVxuXG4gICAgZm9yIChjb25zdCBba2V5LCB2YWx1ZV0gb2YgT2JqZWN0LmVudHJpZXMobWV0YWRhdGEpKSB7XG4gICAgICBtZC5idWxsZXQoYCR7TWFya2Rvd25Eb2N1bWVudC5pdGFsaWMoYCR7a2V5fTpgKX0gJHt2YWx1ZX1gKTtcbiAgICB9XG4gICAgbWQubGluZXMoJycpO1xuXG4gICAgaWYgKHByb3AuZG9jcykge1xuICAgICAgbWQuZG9jcyhwcm9wLmRvY3MsIHRoaXMubGFuZ3VhZ2UpO1xuICAgIH1cblxuICAgIG1kLnNwbGl0KCk7XG5cbiAgICByZXR1cm4gbWQ7XG4gIH1cblxuICBwdWJsaWMgdmlzaXRQYXJhbWV0ZXIoXG4gICAgcGFyYW1ldGVyOiBQYXJhbWV0ZXJTY2hlbWEsXG4gICk6IE1hcmtkb3duRG9jdW1lbnQge1xuICAgIGNvbnN0IG9wdGlvbmFsaXR5ID0gcGFyYW1ldGVyLm9wdGlvbmFsID8gJ09wdGlvbmFsJyA6ICdSZXF1aXJlZCc7XG5cbiAgICBjb25zdCBtZCA9IG5ldyBNYXJrZG93bkRvY3VtZW50KHtcbiAgICAgIGlkOiB0aGlzLmFuY2hvckZvcm1hdHRlcih7XG4gICAgICAgIGlkOiBwYXJhbWV0ZXIuaWQsXG4gICAgICAgIGRpc3BsYXlOYW1lOiBwYXJhbWV0ZXIuZGlzcGxheU5hbWUsXG4gICAgICAgIGZxbjogcGFyYW1ldGVyLmZxbixcbiAgICAgICAgLi4udGhpcy5tZXRhZGF0YSxcbiAgICAgIH0pLFxuICAgICAgaGVhZGVyOiB7XG4gICAgICAgIHRpdGxlOiBwYXJhbWV0ZXIuZGlzcGxheU5hbWUsXG4gICAgICAgIHN1cDogb3B0aW9uYWxpdHksXG4gICAgICAgIHByZTogdHJ1ZSxcbiAgICAgICAgc3RyaWtlOiBwYXJhbWV0ZXIuZG9jcy5kZXByZWNhdGVkLFxuICAgICAgfSxcbiAgICB9KTtcblxuICAgIGlmIChwYXJhbWV0ZXIuZG9jcy5kZXByZWNhdGVkKSB7XG4gICAgICBtZC5idWxsZXQoXG4gICAgICAgIGAke01hcmtkb3duRG9jdW1lbnQuaXRhbGljKCdEZXByZWNhdGVkOicpfSAke3BhcmFtZXRlci5kb2NzLmRlcHJlY2F0aW9uUmVhc29ufWAsXG4gICAgICApO1xuICAgICAgbWQubGluZXMoJycpO1xuICAgIH1cblxuXG4gICAgY29uc3QgbWV0YWRhdGE6IGFueSA9IHtcbiAgICAgIFR5cGU6IHRoaXMudHlwZUZvcm1hdHRlcihwYXJhbWV0ZXIudHlwZSwgdGhpcy5tZXRhZGF0YSwgdGhpcy5saW5rRm9ybWF0dGVyKSxcbiAgICB9O1xuXG4gICAgaWYgKHBhcmFtZXRlci5kZWZhdWx0KSB7XG4gICAgICBjb25zdCBzYW5pdGl6ZWQgPSBNYXJrZG93bkRvY3VtZW50LnNhbml0aXplKHBhcmFtZXRlci5kZWZhdWx0KTtcbiAgICAgIG1ldGFkYXRhLkRlZmF1bHQgPSBNYXJrZG93bkRvY3VtZW50LnJlbW92ZU5ld2xpbmVzKHNhbml0aXplZCk7XG4gICAgfVxuXG4gICAgZm9yIChjb25zdCBba2V5LCB2YWx1ZV0gb2YgT2JqZWN0LmVudHJpZXMobWV0YWRhdGEpKSB7XG4gICAgICBtZC5idWxsZXQoYCR7TWFya2Rvd25Eb2N1bWVudC5pdGFsaWMoYCR7a2V5fTpgKX0gJHt2YWx1ZX1gKTtcbiAgICB9XG4gICAgbWQubGluZXMoJycpO1xuXG4gICAgaWYgKHBhcmFtZXRlci5kb2NzKSB7XG4gICAgICBtZC5kb2NzKHBhcmFtZXRlci5kb2NzLCB0aGlzLmxhbmd1YWdlKTtcbiAgICB9XG5cbiAgICBtZC5zcGxpdCgpO1xuXG4gICAgcmV0dXJuIG1kO1xuICB9XG5cbiAgcHVibGljIHZpc2l0SW5zdGFuY2VNZXRob2QoXG4gICAgbWV0aG9kOiBNZXRob2RTY2hlbWEsXG4gICk6IE1hcmtkb3duRG9jdW1lbnQge1xuICAgIGNvbnN0IG1kID0gbmV3IE1hcmtkb3duRG9jdW1lbnQoe1xuICAgICAgaWQ6IHRoaXMuYW5jaG9yRm9ybWF0dGVyKHtcbiAgICAgICAgaWQ6IG1ldGhvZC5pZCxcbiAgICAgICAgZGlzcGxheU5hbWU6IG1ldGhvZC5kaXNwbGF5TmFtZSxcbiAgICAgICAgZnFuOiBtZXRob2QuZnFuLFxuICAgICAgICAuLi50aGlzLm1ldGFkYXRhLFxuICAgICAgfSksXG4gICAgICBoZWFkZXI6IHtcbiAgICAgICAgdGl0bGU6IG1ldGhvZC5kaXNwbGF5TmFtZSxcbiAgICAgICAgcHJlOiB0cnVlLFxuICAgICAgICBzdHJpa2U6IG1ldGhvZC5kb2NzLmRlcHJlY2F0ZWQsXG4gICAgICB9LFxuICAgIH0pO1xuXG4gICAgaWYgKG1ldGhvZC51c2FnZSkge1xuICAgICAgbWQuY29kZSh0aGlzLmxhbmd1YWdlLnRvU3RyaW5nKCksIG1ldGhvZC51c2FnZSk7XG4gICAgfVxuXG4gICAgaWYgKG1ldGhvZC5kb2NzKSB7XG4gICAgICBtZC5kb2NzKG1ldGhvZC5kb2NzLCB0aGlzLmxhbmd1YWdlKTtcbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IHBhcmFtIG9mIG1ldGhvZC5wYXJhbWV0ZXJzKSB7XG4gICAgICBtZC5zZWN0aW9uKHRoaXMudmlzaXRQYXJhbWV0ZXIocGFyYW0pKTtcbiAgICB9XG5cbiAgICByZXR1cm4gbWQ7XG4gIH1cblxuICBwdWJsaWMgdmlzaXRTdGF0aWNGdW5jdGlvbihcbiAgICBtZXRob2Q6IE1ldGhvZFNjaGVtYSxcbiAgKSB7XG4gICAgY29uc3QgbWQgPSBuZXcgTWFya2Rvd25Eb2N1bWVudCh7XG4gICAgICBpZDogdGhpcy5hbmNob3JGb3JtYXR0ZXIoe1xuICAgICAgICBpZDogbWV0aG9kLmlkLFxuICAgICAgICBkaXNwbGF5TmFtZTogbWV0aG9kLmRpc3BsYXlOYW1lLFxuICAgICAgICBmcW46IG1ldGhvZC5mcW4sXG4gICAgICAgIC4uLnRoaXMubWV0YWRhdGEsXG4gICAgICB9KSxcbiAgICAgIGhlYWRlcjoge1xuICAgICAgICB0aXRsZTogbWV0aG9kLmRpc3BsYXlOYW1lLFxuICAgICAgICBwcmU6IHRydWUsXG4gICAgICAgIHN0cmlrZTogbWV0aG9kLmRvY3MuZGVwcmVjYXRlZCxcbiAgICAgIH0sXG4gICAgfSk7XG5cbiAgICBpZiAobWV0aG9kLnVzYWdlKSB7XG4gICAgICBtZC5jb2RlKHRoaXMubGFuZ3VhZ2UudG9TdHJpbmcoKSwgbWV0aG9kLnVzYWdlKTtcbiAgICB9XG5cbiAgICBpZiAobWV0aG9kLmRvY3MpIHtcbiAgICAgIG1kLmRvY3MobWV0aG9kLmRvY3MsIHRoaXMubGFuZ3VhZ2UpO1xuICAgIH1cblxuICAgIGZvciAoY29uc3QgcGFyYW0gb2YgbWV0aG9kLnBhcmFtZXRlcnMpIHtcbiAgICAgIG1kLnNlY3Rpb24odGhpcy52aXNpdFBhcmFtZXRlcihwYXJhbSkpO1xuICAgIH1cblxuICAgIHJldHVybiBtZDtcbiAgfVxuXG4gIHB1YmxpYyB2aXNpdENvbnN0YW50KFxuICAgIGNvbnN0YW50OiBQcm9wZXJ0eVNjaGVtYSxcbiAgKTogTWFya2Rvd25Eb2N1bWVudCB7XG4gICAgcmV0dXJuIHRoaXMudmlzaXRQcm9wZXJ0eShjb25zdGFudCk7XG4gIH1cblxuICBwcml2YXRlIGNyZWF0ZVRhYmxlKGl0ZW1zOiBTaW1wbGVUYWJsZUl0ZW1bXSk6IHN0cmluZ1tdW10ge1xuICAgIGNvbnN0IHRhYmxlUm93czogc3RyaW5nW11bXSA9IFtdO1xuICAgIHRhYmxlUm93cy5wdXNoKFsnTmFtZScsICdEZXNjcmlwdGlvbiddLm1hcChNYXJrZG93bkRvY3VtZW50LmJvbGQpKTtcblxuICAgIGZvciAoY29uc3QgaXRlbSBvZiBpdGVtcykge1xuICAgICAgY29uc3QgbGluayA9IE1hcmtkb3duRG9jdW1lbnQucHJlKHRoaXMubGlua0Zvcm1hdHRlcih7XG4gICAgICAgIGZxbjogaXRlbS5mcW4sXG4gICAgICAgIGRpc3BsYXlOYW1lOiBpdGVtLmRpc3BsYXlOYW1lLFxuICAgICAgICBpZDogaXRlbS5pZCxcbiAgICAgICAgLi4udGhpcy5tZXRhZGF0YSxcbiAgICAgIH0sIHRoaXMubWV0YWRhdGEpKTtcbiAgICAgIGNvbnN0IGRlc2NyaXB0aW9uID0gaXRlbS5kb2NzPy5zdW1tYXJ5ICYmIGl0ZW0uZG9jcz8uc3VtbWFyeS5sZW5ndGggPiAwXG4gICAgICAgID8gaXRlbS5kb2NzPy5zdW1tYXJ5XG4gICAgICAgIDogTWFya2Rvd25Eb2N1bWVudC5pdGFsaWMoJ05vIGRlc2NyaXB0aW9uLicpO1xuICAgICAgdGFibGVSb3dzLnB1c2goW2xpbmssIGRlc2NyaXB0aW9uXSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRhYmxlUm93cztcbiAgfVxuXG4gIHByaXZhdGUgY3JlYXRlVGFibGVXaXRoVHlwZXMoaXRlbXM6IFR5cGVUYWJsZUl0ZW1bXSk6IHN0cmluZ1tdW10ge1xuICAgIGNvbnN0IHRhYmxlUm93czogc3RyaW5nW11bXSA9IFtdO1xuICAgIHRhYmxlUm93cy5wdXNoKFsnTmFtZScsICdUeXBlJywgJ0Rlc2NyaXB0aW9uJ10ubWFwKE1hcmtkb3duRG9jdW1lbnQuYm9sZCkpO1xuXG4gICAgZm9yIChjb25zdCBpdGVtIG9mIGl0ZW1zKSB7XG4gICAgICBjb25zdCBsaW5rID0gTWFya2Rvd25Eb2N1bWVudC5wcmUodGhpcy5saW5rRm9ybWF0dGVyKHtcbiAgICAgICAgZnFuOiBpdGVtLmZxbixcbiAgICAgICAgZGlzcGxheU5hbWU6IGl0ZW0uZGlzcGxheU5hbWUsXG4gICAgICAgIGlkOiBpdGVtLmlkLFxuICAgICAgICAuLi50aGlzLm1ldGFkYXRhLFxuICAgICAgfSwgdGhpcy5tZXRhZGF0YSkpO1xuICAgICAgY29uc3QgdHlwZSA9IE1hcmtkb3duRG9jdW1lbnQucHJlKHRoaXMudHlwZUZvcm1hdHRlcihpdGVtLnR5cGUsIHRoaXMubWV0YWRhdGEsIHRoaXMubGlua0Zvcm1hdHRlcikpO1xuICAgICAgY29uc3QgZGVzY3JpcHRpb24gPSBpdGVtLmRvY3M/LnN1bW1hcnkgJiYgaXRlbS5kb2NzPy5zdW1tYXJ5Lmxlbmd0aCA+IDBcbiAgICAgICAgPyBpdGVtLmRvY3M/LnN1bW1hcnlcbiAgICAgICAgOiBNYXJrZG93bkRvY3VtZW50Lml0YWxpYygnTm8gZGVzY3JpcHRpb24uJyk7XG4gICAgICB0YWJsZVJvd3MucHVzaChbbGluaywgdHlwZSwgZGVzY3JpcHRpb25dKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGFibGVSb3dzO1xuICB9XG59XG5cbmludGVyZmFjZSBTaW1wbGVUYWJsZUl0ZW0ge1xuICByZWFkb25seSBmcW46IHN0cmluZztcbiAgcmVhZG9ubHkgZGlzcGxheU5hbWU6IHN0cmluZztcbiAgcmVhZG9ubHkgaWQ6IHN0cmluZztcbiAgcmVhZG9ubHkgZG9jcz86IHsgc3VtbWFyeT86IHN0cmluZyB9O1xufVxuXG5pbnRlcmZhY2UgVHlwZVRhYmxlSXRlbSBleHRlbmRzIFNpbXBsZVRhYmxlSXRlbSB7XG4gIHJlYWRvbmx5IHR5cGU6IFR5cGVTY2hlbWE7XG59XG5cbmZ1bmN0aW9uIHNhbml0aXplKHN0cjogc3RyaW5nKSB7XG4gIHJldHVybiBzdHIucmVwbGFjZSgvIC9nLCAnLScpO1xufVxuXG5leHBvcnQgY29uc3QgZGVmYXVsdEFuY2hvckZvcm1hdHRlciA9ICh0eXBlOiBKc2lpRW50aXR5KSA9PiB7XG4gIC8vIEhUTUw1IGFsbG93cyBhbnkgY2hhcmFjdGVyIGluIElEcyAvZXhjZXB0LyB3aGl0ZXNwYWNlXG4gIHJldHVybiBzYW5pdGl6ZSh0eXBlLmlkKTtcbn07XG5cbmV4cG9ydCBjb25zdCBkZWZhdWx0TGlua0Zvcm1hdHRlciA9ICh0eXBlOiBKc2lpRW50aXR5LCBtZXRhZGF0YTogQXNzZW1ibHlNZXRhZGF0YVNjaGVtYSkgPT4ge1xuICBpZiAodHlwZS5wYWNrYWdlTmFtZSA9PT0gbWV0YWRhdGEucGFja2FnZU5hbWUgJiYgdHlwZS5zdWJtb2R1bGUgPT09IG1ldGFkYXRhLnN1Ym1vZHVsZSkge1xuICAgIHJldHVybiBgPGEgaHJlZj1cIiMke3Nhbml0aXplKHR5cGUuaWQpfVwiPiR7dHlwZS5kaXNwbGF5TmFtZX08L2E+YDtcbiAgfSBlbHNlIHtcbiAgICAvLyBkbyBub3QgZGlzcGxheSBhIGxpbmsgaWYgdGhlIHR5cGUgaXNuJ3QgaW4gdGhpcyBkb2N1bWVudFxuICAgIHJldHVybiB0eXBlLmZxbjtcbiAgfVxufTtcblxuZnVuY3Rpb24gaXNKc2lpVHlwZSh2YWx1ZTogYW55KTogdmFsdWUgaXMgSnNpaUVudGl0eSB7XG4gIHJldHVybiAoXG4gICAgdmFsdWUgIT09IG51bGxcbiAgICAmJiB0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnXG4gICAgJiYgdmFsdWU/LmZxblxuICAgICYmIHZhbHVlPy5pZFxuICAgICYmIHZhbHVlPy5kaXNwbGF5TmFtZVxuICApO1xufVxuXG5leHBvcnQgY29uc3QgZGVmYXVsdFR5cGVGb3JtYXR0ZXIgPSAoXG4gIHR5cGU6IFR5cGVTY2hlbWEsXG4gIG1ldGFkYXRhOiBBc3NlbWJseU1ldGFkYXRhU2NoZW1hLFxuICBsaW5rRm9ybWF0dGVyOiAodHlwZTogSnNpaUVudGl0eSwgbWV0YWRhdGE6IEFzc2VtYmx5TWV0YWRhdGFTY2hlbWEpID0+IHN0cmluZyxcbik6IHN0cmluZyA9PiB7XG4gIGxldCByZXN1bHQgPSB0eXBlLmZvcm1hdHRpbmdQYXR0ZXJuO1xuICBjb25zdCB0eXBlUmVmcyA9IFtdO1xuICBmb3IgKGNvbnN0IHR5cGVSZWYgb2YgdHlwZS50eXBlcyA/PyBbXSkge1xuICAgIGlmIChpc0pzaWlUeXBlKHR5cGVSZWYpKSB7XG4gICAgICB0eXBlUmVmcy5wdXNoKGxpbmtGb3JtYXR0ZXIodHlwZVJlZiwgbWV0YWRhdGEpKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdHlwZVJlZnMucHVzaChkZWZhdWx0VHlwZUZvcm1hdHRlcih0eXBlUmVmLCBtZXRhZGF0YSwgbGlua0Zvcm1hdHRlcikpO1xuICAgIH1cbiAgfVxuXG4gIC8vIHN1YnN0aXR1dGUgcmVmZXJyZWQgdHlwZXMgaW50byB0aGUgb3JpZ2luYWwgc3RyaW5nXG4gIGNvbnN0IHBsYWNlaG9sZGVyTWF0Y2hlciA9IC9cXCUvZztcbiAgZm9yIChjb25zdCB0eXBlUmVmIG9mIHR5cGVSZWZzKSB7XG4gICAgY29uc3QgbWF0Y2hlcyA9IHBsYWNlaG9sZGVyTWF0Y2hlci5leGVjKHJlc3VsdCk7XG4gICAgaWYgKCFtYXRjaGVzKSB7XG4gICAgICAvLyBpdCdzIHBvc3NpYmxlIHRoZSBudW1iZXIgb2YgJSdzIGRvZXNuJ3QgbWF0Y2ggdGhlIG51bWJlciBvZiB0eXBlcyBwcm92aWRlZFxuICAgICAgLy8gZS5nLiBjc2hhcnAgdW5pb25zIGFyZSBjdXJyZW50bHkgcmVuZGVyZWQgdG8gYHsgbmFtZTogJ29iamVjdCcsIHR5cGVzOiBbdHlwZTEsIHR5cGUyXSB9YFxuICAgICAgY29udGludWU7XG4gICAgfVxuICAgIGNvbnN0IGluc2VydGlvbklkeDogbnVtYmVyID0gbWF0Y2hlcy5pbmRleDtcbiAgICByZXN1bHQgPSByZXN1bHQuc3Vic3RyaW5nKDAsIGluc2VydGlvbklkeCkgKyB0eXBlUmVmICsgcmVzdWx0LnN1YnN0cmluZyhpbnNlcnRpb25JZHggKyAxKTtcbiAgfVxuXG4gIHJldHVybiByZXN1bHQ7XG59O1xuIl19