@decaf-ts/fabric-weaver
Version:
template for ts projects
442 lines • 67.1 kB
JavaScript
import { Logging } from "@decaf-ts/logging";
import { FabricBinaries } from "../constants/fabric-binaries";
import { FabricCAServerCommand } from "../constants/fabric-ca-server";
import { COMMA_SEPARATOR } from "../../core/constants/constants";
import { mapParser } from "../../utils";
import { runCommand } from "../../utils/child-process";
export class FabricCAServerCommandBuilder {
constructor(logger) {
this.binName = FabricBinaries.SERVER;
this.command = FabricCAServerCommand.HELP;
this.args = new Map();
if (!logger)
this.log = Logging.for(FabricCAServerCommandBuilder);
else
this.log = logger.for(FabricCAServerCommandBuilder.name);
}
/**
* @description Sets the command for the Fabric CA Server.
* @summary Configures the primary action for the Fabric CA Server, such as starting the server or generating certificates.
* @param {FabricCAServerCommand} [command] - The command to be executed by the Fabric CA Server.
* @return {this} The current instance of the builder for method chaining.
*/
setCommand(command) {
if (command !== undefined) {
this.log.debug(`Setting command: ${command}`);
this.command = command;
}
return this;
}
/**
* @description Sets the port for the Fabric CA Server.
* @summary Configures the network port on which the Fabric CA Server will listen for incoming connections.
* @param {number} [port] - The port number for the Fabric CA Server to listen on.
* @return {this} The current instance of the builder for method chaining.
*/
setPort(port) {
if (port !== undefined) {
this.log.debug(`Setting port: ${port}`);
this.args.set("port", port);
}
return this;
}
/**
* @description Enables or disables debug mode for the Fabric CA Server.
* @summary Configures whether the Fabric CA Server should run in debug mode, providing more detailed logging and output.
* @param {boolean} [enable] - Whether to enable debug mode.
* @return {this} The current instance of the builder for method chaining.
*/
enableDebug(enable) {
if (enable !== undefined) {
this.log.debug(`Setting debug: ${enable}`);
this.args.set("debug", enable);
}
return this;
}
setServerTLS(tlsConfig) {
if (!tlsConfig)
return this;
if (tlsConfig.enabled !== undefined) {
this.log.debug("Setting TLS enabled");
this.args.set("tls.enabled", tlsConfig.enabled);
}
if (tlsConfig.certfile !== undefined) {
this.log.debug(`Setting TLS cert file: ${tlsConfig.certfile}`);
this.args.set("tls.certfile", tlsConfig.certfile);
}
if (tlsConfig.keyfile !== undefined) {
this.log.debug(`Setting TLS key file: ${tlsConfig.keyfile}`);
this.args.set("tls.keyfile", tlsConfig.keyfile);
}
if (tlsConfig.clientauth === undefined)
return this;
if (tlsConfig.clientauth.certfiles !== undefined) {
this.log.debug(`Setting TLS client certfiles: ${tlsConfig.clientauth.certfiles}`);
this.args.set("tls.clientauth.certfiles", tlsConfig.clientauth.certfiles.join(COMMA_SEPARATOR));
}
if (tlsConfig.clientauth.type !== undefined) {
this.log.debug(`Setting TLS client auth type: ${tlsConfig.clientauth.type}`);
this.args.set("tls.clientauth.type", tlsConfig.clientauth.type);
}
return this;
}
setCA(config) {
if (!config)
return this;
if (config.name !== undefined) {
this.log.debug(`Setting CA name: ${config.name}`);
this.args.set("ca.name", config.name);
}
if (config.keyfile !== undefined) {
this.log.debug(`Setting CA key file: ${config.keyfile}`);
this.args.set("ca.keyfile", config.keyfile);
}
if (config.certfile !== undefined) {
this.log.debug(`Setting CA cert file: ${config.certfile}`);
this.args.set("ca.certfile", config.certfile);
}
if (config.chainfile !== undefined) {
this.log.debug(`Setting CA chain file: ${config.chainfile}`);
this.args.set("ca.chainfile", config.chainfile);
}
if (config.reenrollIgnoreCertExpiry !== undefined) {
this.log.debug(`Setting reenrollIgnoreCertExpiry: ${config.reenrollIgnoreCertExpiry}`);
this.args.set("ca.reenrollignorecertexpiry", config.reenrollIgnoreCertExpiry);
}
return this;
}
/**
* @description Sets the address for the Fabric CA Server.
* @summary Configures the network address on which the Fabric CA Server will listen for incoming connections.
* @param {string} [address] - The network address for the Fabric CA Server to listen on.
* @return {this} The current instance of the builder for method chaining.
*/
setAddress(address) {
if (address !== undefined) {
this.log.debug(`Setting address: ${address}`);
this.args.set("address", address);
}
return this;
}
/**
* @description Sets the bootstrap admin user for the Fabric CA Server.
* @summary Configures the initial admin user with full privileges for the Fabric CA Server.
* @param {string} [bootUser] - The bootstrap admin user in the format "username:password".
* @return {this} The current instance of the builder for method chaining.
*/
setBootstrapAdmin(bootUser) {
if (bootUser !== undefined) {
const [user, password] = bootUser.split(":");
this.log.debug(`Setting bootstrap admin: ${user}:${password}`);
this.args.set("boot", bootUser);
}
return this;
}
/**
* @description Sets the number of CAs to run on the Fabric CA Server.
* @summary Configures the Fabric CA Server to run multiple CA instances.
* @param {number} [count] - The number of CA instances to run.
* @return {this} The current instance of the builder for method chaining.
*/
setCACount(count) {
if (count !== undefined) {
this.log.debug(`Setting CA count: ${count}`);
this.args.set("cacount", count);
}
return this;
}
/**
* @description Sets the configuration files for multiple CAs.
* @summary Configures the Fabric CA Server with multiple CA configurations using separate files.
* @param {string[]} [files] - An array of paths to CA configuration files.
* @return {this} The current instance of the builder for method chaining.
*/
setCAFiles(files) {
if (files !== undefined && files.length > 0) {
this.log.debug(`Setting CA configuration files: ${files.join(", ")}`);
this.args.set("cafiles", files.join(COMMA_SEPARATOR));
}
return this;
}
setCors(config) {
if (!config)
return this;
if (config.enabled !== undefined) {
this.log.debug(`Setting CORS enabled: ${config.enabled}`);
this.args.set("cors.enabled", config.enabled);
}
if (config.origins !== undefined) {
this.log.debug(`Setting CORS origins: ${config.origins.join(", ")}`);
this.args.set("cors.origins", config.origins.join(COMMA_SEPARATOR));
}
return this;
}
setCrlExpiry(crlExpiry) {
if (crlExpiry !== undefined) {
this.log.debug(`Setting CRL expiry: ${crlExpiry}`);
this.args.set("crl.expiry", crlExpiry);
}
return this;
}
/**
* @description Sets the size limit for the Certificate Revocation List (CRL).
* @summary Configures the maximum number of revoked certificates that can be included in a single CRL.
* @param {number} [limit] - The maximum number of revoked certificates in the CRL.
* @return {this} The current instance of the builder for method chaining.
*/
setCRLSizeLimit(limit) {
if (limit !== undefined) {
this.log.debug(`Setting CRL size limit: ${limit}`);
this.args.set("crlsizelimit", limit);
}
return this;
}
setCSR(csr) {
if (csr === undefined)
return this;
if (csr.cn !== undefined) {
this.log.debug(`Setting CSR CN: ${csr.cn}`);
this.args.set("csr.cn", csr.cn);
}
if (csr.hosts !== undefined) {
this.log.debug(`Setting CSR hosts: ${csr.hosts}`);
this.args.set("csr.hosts", [...new Set(csr.hosts)].join(COMMA_SEPARATOR));
}
if (csr.keyrequest !== undefined) {
if (csr.keyrequest.algo !== undefined) {
this.log.debug(`Setting CSR key request algorithm: ${csr.keyrequest.algo}`);
this.args.set("csr.keyrequest.algo", csr.keyrequest.algo);
}
if (csr.keyrequest.size !== undefined) {
this.log.debug(`Setting CSR key request size: ${csr.keyrequest.size}`);
this.args.set("csr.keyrequest.size", csr.keyrequest.size);
}
if (csr.keyrequest.reusekey !== undefined) {
this.log.debug(`Setting CSR key request reuse key: ${csr.keyrequest.reusekey}`);
this.args.set("csr.keyrequest.reusekey", csr.keyrequest.reusekey);
}
}
if (csr.serialnumber !== undefined) {
this.log.debug(`Setting CSR serial number: ${csr.serialnumber}`);
this.args.set("csr.serialnumber", csr.serialnumber);
}
return this;
}
setHelp(show) {
if (show !== undefined) {
this.log.debug(`Setting help flag: ${show}`);
this.args.set("help", show);
}
return this;
}
setHome(home) {
if (home !== undefined) {
this.log.debug(`Setting home directory: ${home}`);
this.args.set("home", home);
}
return this;
}
setDatabase(cfg) {
if (cfg === undefined)
return this;
if (cfg.type !== undefined) {
this.log.debug(`Setting database type: ${cfg.type}`);
this.args.set("db.type", cfg.type);
}
if (cfg.datasource !== undefined) {
this.log.debug(`Setting database datasource: ${cfg.datasource}`);
this.args.set("db.datasource", cfg.datasource);
}
if (cfg.tls !== undefined) {
if (cfg.tls.certfiles !== undefined) {
this.log.debug(`Setting TLS certfiles: ${cfg.tls.certfiles}`);
this.args.set("db.tls.certfiles", cfg.tls.certfiles.join(COMMA_SEPARATOR));
}
if (cfg.tls.client !== undefined) {
if (cfg.tls.client.certfile !== undefined) {
this.log.debug(`Setting TLS client certfile: ${cfg.tls.client.certfile}`);
this.args.set("db.tls.client.certfile", cfg.tls.client.certfile);
}
if (cfg.tls.client.keyfile !== undefined) {
this.log.debug(`Setting TLS client keyfile: ${cfg.tls.client.keyfile}`);
this.args.set("db.tls.client.keyfile", cfg.tls.client.keyfile);
}
}
}
return this;
}
setIdemix(idemix) {
if (idemix === undefined)
return this;
if (idemix.nonceexpiration !== undefined) {
this.log.debug(`Setting Idemix nonce expiration: ${idemix.nonceexpiration}`);
this.args.set("idemix.nonceexpiration", idemix.nonceexpiration);
}
if (idemix.curve !== undefined) {
this.log.debug(`Setting Idemix curve: ${idemix.curve}`);
this.args.set("idemix.curve", idemix.curve);
}
if (idemix.noncesweepinterval !== undefined) {
this.log.debug(`Setting Idemix noncesweep interval: ${idemix.noncesweepinterval}`);
this.args.set("idemix.noncesweepinterval", idemix.noncesweepinterval);
}
if (idemix.rhpoolsize !== undefined) {
this.log.debug(`Setting Idemix rhpoolsize: ${idemix.rhpoolsize}`);
this.args.set("idemix.rhpoolsize", idemix.rhpoolsize);
}
return this;
}
setIntermediate(int) {
if (int === undefined)
return this;
if (int.parentserver !== undefined) {
if (int.parentserver.url !== undefined) {
this.log.debug(`Setting intermediate CA parent server URL: ${int.parentserver.url}`);
this.args.set("intermediate.parentserver.url", int.parentserver.url);
}
if (int.parentserver.caname !== undefined) {
this.log.debug(`Setting intermediate CA parent server caname: ${int.parentserver.caname}`);
this.args.set("intermediate.parentserver.caname", int.parentserver.caname);
}
}
if (int.enrollment !== undefined) {
if (int.enrollment.type !== undefined) {
this.log.debug(`Setting intermediate CA enrollment type: ${int.enrollment.type}`);
this.args.set("intermediate.enrollment.type", int.enrollment.type);
}
if (int.enrollment.profile !== undefined) {
this.log.debug(`Setting intermediate CA enrollment profile: ${int.enrollment.profile}`);
this.args.set("intermediate.enrollment.profile", int.enrollment.profile);
}
if (int.enrollment.label !== undefined) {
this.log.debug(`Setting intermediate CA enrollment label: ${int.enrollment.label}`);
this.args.set("intermediate.enrollment.label", int.enrollment.label);
}
}
if (int.tls !== undefined) {
if (int.tls.certfiles !== undefined) {
this.log.debug(`Setting intermediate CA TLS certfiles: ${int.tls.certfiles.join(", ")}`);
this.args.set("intermediate.tls.certfiles", int.tls.certfiles.join(COMMA_SEPARATOR));
}
if (int.tls.client !== undefined) {
if (int.tls.client.certfile !== undefined) {
this.log.debug(`Setting intermediate CA TLS client certfile: ${int.tls.client.certfile}`);
this.args.set("intermediate.tls.client.certfile", int.tls.client.certfile);
}
if (int.tls.client.keyfile !== undefined) {
this.log.debug(`Setting intermediate CA TLS client keyfile: ${int.tls.client.keyfile}`);
this.args.set("intermediate.tls.client.keyfile", int.tls.client.keyfile);
}
}
}
return this;
}
setLDAP(ldap) {
if (ldap === undefined)
return this;
if (ldap.enabled !== undefined) {
this.log.debug(`Setting LDAP enabled: ${ldap.enabled}`);
this.args.set("ldap.enabled", ldap.enabled);
}
if (ldap.url !== undefined) {
this.log.debug(`Setting LDAP URL: ${ldap.url}`);
this.args.set("ldap.url", ldap.url);
}
if (ldap.tls !== undefined) {
if (ldap.tls.certfiles !== undefined) {
this.log.debug(`Setting TLS certfiles: ${ldap.tls.certfiles.join(", ")}`);
this.args.set("ldap.tls.certfiles", ldap.tls.certfiles.join(COMMA_SEPARATOR));
}
if (ldap.tls.client !== undefined) {
if (ldap.tls.client.certfile !== undefined) {
this.log.debug(`Setting TLS client certfile: ${ldap.tls.client.certfile}`);
this.args.set("ldap.tls.client.certfile", ldap.tls.client.certfile);
}
if (ldap.tls.client.keyfile !== undefined) {
this.log.debug(`Setting TLS client keyfile: ${ldap.tls.client.keyfile}`);
this.args.set("ldap.tls.client.keyfile", ldap.tls.client.keyfile);
}
}
}
if (ldap.attribute !== undefined) {
if (ldap.attribute.names !== undefined) {
this.log.debug(`Setting LDAP attribute names: ${ldap.attribute.names.join(", ")}`);
this.args.set("ldap.attribute.names", ldap.attribute.names.join(COMMA_SEPARATOR));
}
}
if (ldap.groupfilter !== undefined) {
this.log.debug(`Setting LDAP groupfiler: ${ldap.groupfilter}`);
this.args.set("ldap.groupfilter", ldap.groupfilter);
}
if (ldap.userfilter !== undefined) {
this.log.debug(`Setting LDAP userfilter: ${ldap.userfilter}`);
this.args.set("ldap.userfilter", ldap.userfilter);
}
return this;
}
setLogLevel(level) {
this.log.debug(`Setting log level: ${level}`);
this.args.set("loglevel", level);
return this;
}
setMaxEnrollments(maxEnrollments) {
if (maxEnrollments !== undefined) {
this.log.debug(`Setting max enrollments: ${maxEnrollments}`);
this.args.set("registry.maxenrollments", maxEnrollments);
}
return this;
}
setAllowAffiliationsRemove(allow) {
if (allow !== undefined) {
this.log.debug(`Setting affiliations allow remove: ${allow}`);
this.args.set("cfg.affiliations.allowremove", allow);
}
return this;
}
setAllowIdentitiesRemove(allow) {
if (allow !== undefined) {
this.log.debug(`Setting identities allow remove: ${allow}`);
this.args.set("cfg.identities.allowremove", allow);
}
return this;
}
setPasswordAttempts(attempts) {
if (attempts !== undefined) {
this.log.debug(`Setting password attempts: ${attempts}`);
this.args.set("cfg.identities.passwordattempts", attempts);
}
return this;
}
build() {
const command = [
this.getBinary(),
this.getCommand(),
...mapParser(this.args),
].join(" ");
this.log.debug(`Built command: ${command}`);
return command;
}
getCommand() {
return this.command;
}
getBinary() {
return this.binName;
}
getArgs() {
return mapParser(this.args);
}
async execute() {
const bin = this.getBinary();
const argz = [this.getCommand(), ...this.getArgs()];
try {
// const regex = /\[\s*INFO\s*\] Listening on http/;
// can be used as a promise but to lock the logs running as execsync
await runCommand(bin, argz);
}
catch (error) {
this.log.error(`Error: Failed to execute the command: ${error}`);
process.exit(1);
}
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmFicmljLWNhLXNlcnZlci1jb21tYW5kLWJ1aWxkZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvZmFicmljL2ZhYnJpYy1jYS1zZXJ2ZXIvZmFicmljLWNhLXNlcnZlci1jb21tYW5kLWJ1aWxkZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFVLE9BQU8sRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBQ3BELE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSw4QkFBOEIsQ0FBQztBQUM5RCxPQUFPLEVBQUUscUJBQXFCLEVBQUUsTUFBTSwrQkFBK0IsQ0FBQztBQVd0RSxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sZ0NBQWdDLENBQUM7QUFDakUsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUN4QyxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFHdkQsTUFBTSxPQUFPLDRCQUE0QjtJQVF2QyxZQUFZLE1BQWU7UUFMbkIsWUFBTyxHQUFtQixjQUFjLENBQUMsTUFBTSxDQUFDO1FBQ2hELFlBQU8sR0FBMEIscUJBQXFCLENBQUMsSUFBSSxDQUFDO1FBRTVELFNBQUksR0FBc0QsSUFBSSxHQUFHLEVBQUUsQ0FBQztRQUcxRSxJQUFJLENBQUMsTUFBTTtZQUFFLElBQUksQ0FBQyxHQUFHLEdBQUcsT0FBTyxDQUFDLEdBQUcsQ0FBQyw0QkFBNEIsQ0FBQyxDQUFDOztZQUM3RCxJQUFJLENBQUMsR0FBRyxHQUFHLE1BQU0sQ0FBQyxHQUFHLENBQUMsNEJBQTRCLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDaEUsQ0FBQztJQUVEOzs7OztPQUtHO0lBQ0gsVUFBVSxDQUFDLE9BQStCO1FBQ3hDLElBQUksT0FBTyxLQUFLLFNBQVMsRUFBRSxDQUFDO1lBQzFCLElBQUksQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLG9CQUFvQixPQUFPLEVBQUUsQ0FBQyxDQUFDO1lB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V0FBVyxFQUFFLENBQUMsR0FBRyxJQUFJLEdBQUcsQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDLENBQUMsQ0FBQztRQUM1RSxDQUFDO1FBRUQsSUFBSSxHQUFHLENBQUMsVUFBVSxLQUFLLFNBQVMsRUFBRSxDQUFDO1lBQ2pDLElBQUksR0FBRyxDQUFDLFVBQVUsQ0FBQyxJQUFJLEtBQUssU0FBUyxFQUFFLENBQUM7Z0JBQ3RDLElBQUksQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUNaLHNDQUFzQyxHQUFHLENBQUMsVUFBVSxDQUFDLElBQUksRUFBRSxDQUM1RCxDQUFDO2dCQUNGLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLHFCQUFxQixFQUFFLEdBQUcsQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDNUQsQ0FBQztZQUNELElBQUksR0FBRyxDQUFDLFVBQVUsQ0FBQyxJQUFJLEtBQUssU0FBUyxFQUFFLENBQUM7Z0JBQ3RDLElBQUksQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLGlDQUFpQyxHQUFHLENBQUMsVUFBVSxDQUFDLElBQUksRUFBRSxDQUFDLENBQUM7Z0JBQ3ZFLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLHFCQUFxQixFQUFFLEdBQUcsQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDNUQsQ0FBQztZQUNELElBQUksR0FBRyxDQUFDLFVBQVUsQ0FBQyxRQUFRLEtBQUssU0FBUyxFQUFFLENBQUM7Z0JBQzFDLElBQUksQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUNaLHNDQUFzQyxHQUFHLENBQUMsVUFBVSxDQUFDLFFBQVEsRUFBRSxDQUNoRSxDQUFDO2dCQUNGLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLHlCQUF5QixFQUFFLEdBQUcsQ0FBQyxVQUFVLENBQUMsUUFBUSxDQUFDLENBQUM7WUFDcEUsQ0FBQztRQUNILENBQUM7UUFFRCxJQUFJLEdBQUcsQ0FBQyxZQUFZLEtBQUssU0FBUyxFQUFFLENBQUM7WUFDbkMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsOEJBQThCLEdBQUcsQ0FBQyxZQUFZLEVBQUUsQ0FBQyxDQUFDO1lBQ2pFLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLGtCQUFrQixFQUFFLEdBQUcsQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUN0RCxDQUFDO1FBRUQsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBRUQsT0FBTyxDQUFDLElBQWM7UUFDcEIsSUFBSSxJQUFJLEtBQUssU0FBUyxFQUFFLENBQUM7WUFDdkIsSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsc0JBQXNCLElBQUksRUFBRSxDQUFDLENBQUM7WUFDN0MsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsTUFBTSxFQUFFLElBQUksQ0FBQyxDQUFDO1FBQzlCLENBQUM7UUFDRCxPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFRCxPQUFPLENBQUMsSUFBYTtRQUNuQixJQUFJLElBQUksS0FBSyxTQUFTLEVBQUUsQ0FBQztZQUN2QixJQUFJLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQywyQkFBMkIsSUFBSSxFQUFFLENBQUMsQ0FBQztZQUNsRCxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFDOUIsQ0FBQztRQUNELE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUVELFdBQVcsQ0FBQyxHQUFjO1FBQ3hCLElBQUksR0FBRyxLQUFLLFNBQVM7WUFBRSxPQUFPLElBQUksQ0FBQztRQUVuQyxJQUFJLEdBQUcsQ0FBQyxJQUFJLEtBQUssU0FBUyxFQUFFLENBQUM7WUFDM0IsSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsMEJBQTBCLEdBQUcsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDO1lBQ3JELElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLFNBQVMsRUFBRSxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDckMsQ0FBQztRQUNELElBQUksR0FBRyxDQUFDLFVBQVUsS0FBSyxTQUFTLEVBQUUsQ0FBQztZQUNqQyxJQUFJLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxnQ0FBZ0MsR0FBRyxDQUFDLFVBQVUsRUFBRSxDQUFDLENBQUM7WUFDakUsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsZUFBZSxFQUFFLEdBQUcsQ0FBQyxVQUFVLENBQUMsQ0FBQztRQUNqRCxDQUFDO1FBRUQsSUFBSSxHQUFHLENBQUMsR0FBRyxLQUFLLFNBQVMsRUFBRSxDQUFDO1lBQzFCLElBQUksR0FBRyxDQUFDLEdBQUcsQ0FBQyxTQUFTLEtBQUssU0FBUyxFQUFFLENBQUM7Z0JBQ3BDLElBQUksQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLDBCQUEwQixHQUFHLENBQUMsR0FBRyxDQUFDLFNBQVMsRUFBRSxDQUFDLENBQUM7Z0JBQzlELElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUNYLGtCQUFrQixFQUNsQixHQUFHLENBQUMsR0FBRyxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDLENBQ3hDLENBQUM7WUFDSixDQUFDO1lBRUQsSUFBSSxHQUFHLENBQUMsR0FBRyxDQUFDLE1BQU0sS0FBSyxTQUFTLEVBQUUsQ0FBQztnQkFDakMsSUFBSSxHQUFHLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxRQUFRLEtBQUssU0FBUyxFQUFFLENBQUM7b0JBQzFDLElBQUksQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUNaLGdDQUFnQyxHQUFHLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxRQUFRLEVBQUUsQ0FDMUQsQ0FBQztvQkFDRixJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyx3QkFBd0IsRUFBRSxHQUFHLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQztnQkFDbkUsQ0FBQztnQkFFRCxJQUFJLEdBQUcsQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLE9BQU8sS0FBSyxTQUFTLEVBQUUsQ0FBQztvQkFDekMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQ1osK0JBQStCLEdBQUcsQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLE9BQU8sRUFBRSxDQUN4RCxDQUFDO29CQUNGLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLHVCQUF1QixFQUFFLEdBQUcsQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDO2dCQUNqRSxDQUFDO1lBQ0gsQ0FBQztRQUNILENBQUM7UUFFRCxPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFRCxTQUFTLENBQUMsTUFBcUI7UUFDN0IsSUFBSSxNQUFNLEtBQUssU0FBUztZQUFFLE9BQU8sSUFBSSxDQUFDO1FBRXRDLElBQUksTUFBTSxDQUFDLGVBQWUsS0FBSyxTQUFTLEVBQUUsQ0FBQztZQUN6QyxJQUFJLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FDWixvQ0FBb0MsTUFBTSxDQUFDLGVBQWUsRUFBRSxDQUM3RCxDQUFDO1lBQ0YsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsd0JBQXdCLEVBQUUsTUFBTSxDQUFDLGVBQWUsQ0FBQyxDQUFDO1FBQ2xFLENBQUM7UUFFRCxJQUFJLE1BQU0sQ0FBQyxLQUFLLEtBQUssU0FBUyxFQUFFLENBQUM7WUFDL0IsSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMseUJBQXlCLE1BQU0sQ0FBQyxLQUFLLEVBQUUsQ0FBQyxDQUFDO1lBQ3hELElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLGNBQWMsRUFBRSxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDOUMsQ0FBQztRQUVELElBQUksTUFBTSxDQUFDLGtCQUFrQixLQUFLLFNBQVMsRUFBRSxDQUFDO1lBQzVDLElBQUksQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUNaLHVDQUF1QyxNQUFNLENBQUMsa0JBQWtCLEVBQUUsQ0FDbkUsQ0FBQztZQUNGLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLDJCQUEyQixFQUFFLE1BQU0sQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO1FBQ3hFLENBQUM7UUFFRCxJQUFJLE1BQU0sQ0FBQyxVQUFVLEtBQUssU0FBUyxFQUFFLENBQUM7WUFDcEMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsOEJBQThCLE1BQU0sQ0FBQyxVQUFVLEVBQUUsQ0FBQyxDQUFDO1lBQ2xFLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLG1CQUFtQixFQUFFLE1BQU0sQ0FBQyxVQUFVLENBQUMsQ0FBQztRQUN4RCxDQUFDO1FBRUQsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBRUQsZUFBZSxDQUFDLEdBQWdDO1FBQzlDLElBQUksR0FBRyxLQUFLLFNBQVM7WUFBRSxPQUFPLElBQUksQ0FBQztRQUVuQyxJQUFJLEdBQUcsQ0FBQyxZQUFZLEtBQUssU0FBUyxFQUFFLENBQUM7WUFDbkMsSUFBSSxHQUFHLENBQUMsWUFBWSxDQUFDLEdBQUcsS0FBSyxTQUFTLEVBQUUsQ0FBQztnQkFDdkMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQ1osOENBQThDLEdBQUcsQ0FBQyxZQUFZLENBQUMsR0FBRyxFQUFFLENBQ3JFLENBQUM7Z0JBQ0YsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsK0JBQStCLEVBQUUsR0FBRyxDQUFDLFlBQVksQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUN2RSxDQUFDO1lBQ0QsSUFBSSxHQUFHLENBQUMsWUFBWSxDQUFDLE1BQU0sS0FBSyxTQUFTLEVBQUUsQ0FBQztnQkFDMUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQ1osaURBQWlELEdBQUcsQ0FBQyxZQUFZLENBQUMsTUFBTSxFQUFFLENBQzNFLENBQUM7Z0JBQ0YsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQ1gsa0NBQWtDLEVBQ2xDLEdBQUcsQ0FBQyxZQUFZLENBQUMsTUFBTSxDQUN4QixDQUFDO1lBQ0osQ0FBQztRQUNILENBQUM7UUFFRCxJQUFJLEdBQUcsQ0FBQyxVQUFVLEtBQUssU0FBUyxFQUFFLENBQUM7WUFDakMsSUFBSSxHQUFHLENBQUMsVUFBVSxDQUFDLElBQUksS0FBSyxTQUFTLEVBQUUsQ0FBQztnQkFDdEMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQ1osNENBQTRDLEdBQUcsQ0FBQyxVQUFVLENBQUMsSUFBSSxFQUFFLENBQ2xFLENBQUM7Z0JBQ0YsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsOEJBQThCLEVBQUUsR0FBRyxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUNyRSxDQUFDO1lBRUQsSUFBSSxHQUFHLENBQUMsVUFBVSxDQUFDLE9BQU8sS0FBSyxTQUFTLEVBQUUsQ0FBQztnQkFDekMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQ1osK0NBQStDLEdBQUcsQ0FBQyxVQUFVLENBQUMsT0FBTyxFQUFFLENBQ3hFLENBQUM7Z0JBQ0YsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQ1gsaUNBQWlDLEVBQ2pDLEdBQUcsQ0FBQyxVQUFVLENBQUMsT0FBTyxDQUN2QixDQUFDO1lBQ0osQ0FBQztZQUNELElBQUksR0FBRyxDQUFDLFVBQVUsQ0FBQyxLQUFLLEtBQUssU0FBUyxFQUFFLENBQUM7Z0JBQ3ZDLElBQUksQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUNaLDZDQUE2QyxHQUFHLENBQUMsVUFBVSxDQUFDLEtBQUssRUFBRSxDQUNwRSxDQUFDO2dCQUNGLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLCtCQUErQixFQUFFLEdBQUcsQ0FBQyxVQUFVLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDdkUsQ0FBQztRQUNILENBQUM7UUFFRCxJQUFJLEdBQUcsQ0FBQyxHQUFHLEtBQUssU0FBUyxFQUFFLENBQUM7WUFDMUIsSUFBSSxHQUFHLENBQUMsR0FBRyxDQUFDLFNBQVMsS0FBSyxTQUFTLEVBQUUsQ0FBQztnQkFDcEMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQ1osMENBQTBDLEdBQUcsQ0FBQyxHQUFHLENBQUMsU0FBUyxDQUFDLElBQUksQ0FDOUQsSUFBSSxDQUNMLEVBQUUsQ0FDSixDQUFDO2dCQUNGLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUNYLDRCQUE0QixFQUM1QixHQUFHLENBQUMsR0FBRyxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDLENBQ3hDLENBQUM7WUFDSixDQUFDO1lBQ0QsSUFBSSxHQUFHLENBQUMsR0FBRyxDQUFDLE1BQU0sS0FBSyxTQUFTLEVBQUUsQ0FBQztnQkFDakMsSUFBSSxHQUFHLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxRQUFRLEtBQUssU0FBUyxFQUFFLENBQUM7b0JBQzFDLElBQUksQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUNaLGdEQUFnRCxHQUFHLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxRQUFRLEVBQUUsQ0FDMUUsQ0FBQztvQkFDRixJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FDWCxrQ0FBa0MsRUFDbEMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUN4QixDQUFDO2dCQUNKLENBQUM7Z0JBQ0QsSUFBSSxHQUFHLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxPQUFPLEtBQUssU0FBUyxFQUFFLENBQUM7b0JBQ3pDLElBQUksQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUNaLCtDQUErQyxHQUFHLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxPQUFPLEVBQUUsQ0FDeEUsQ0FBQztvQkFDRixJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FDWCxpQ0FBaUMsRUFDakMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUN2QixDQUFDO2dCQUNKLENBQUM7WUFDSCxDQUFDO1FBQ0gsQ0FBQztRQUVELE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUVELE9BQU8sQ0FBQyxJQUF3QjtRQUM5QixJQUFJLElBQUksS0FBSyxTQUFTO1lBQUUsT0FBTyxJQUFJLENBQUM7UUFFcEMsSUFBSSxJQUFJLENBQUMsT0FBTyxLQUFLLFNBQVMsRUFBRSxDQUFDO1lBQy9CLElBQUksQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLHlCQUF5QixJQUFJLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQztZQUN4RCxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxjQUFjLEVBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQzlDLENBQUM7UUFFRCxJQUFJLElBQUksQ0FBQyxHQUFHLEtBQUssU0FBUyxFQUFFLENBQUM7WUFDM0IsSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMscUJBQXFCLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQyxDQUFDO1lBQ2hELElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLFVBQVUsRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDdEMsQ0FBQztRQUVELElBQUksSUFBSSxDQUFDLEdBQUcsS0FBSyxTQUFTLEVBQUUsQ0FBQztZQUMzQixJQUFJLElBQUksQ0FBQyxHQUFHLENBQUMsU0FBUyxLQUFLLFNBQVMsRUFBRSxDQUFDO2dCQUNyQyxJQUFJLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FDWiwwQkFBMEIsSUFBSSxDQUFDLEdBQUcsQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQzFELENBQUM7Z0JBQ0YsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQ1gsb0JBQW9CLEVBQ3BCLElBQUksQ0FBQyxHQUFHLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxlQUFlLENBQUMsQ0FDekMsQ0FBQztZQUNKLENBQUM7WUFFRCxJQUFJLElBQUksQ0FBQyxHQUFHLENBQUMsTUFBTSxLQUFLLFNBQVMsRUFBRSxDQUFDO2dCQUNsQyxJQUFJLElBQUksQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLFFBQVEsS0FBSyxTQUFTLEVBQUUsQ0FBQztvQkFDM0MsSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQ1osZ0NBQWdDLElBQUksQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLFFBQVEsRUFBRSxDQUMzRCxDQUFDO29CQUNGLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLDBCQUEwQixFQUFFLElBQUksQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDO2dCQUN0RSxDQUFDO2dCQUVELElBQUksSUFBSSxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsT0FBTyxLQUFLLFNBQVMsRUFBRSxDQUFDO29CQUMxQyxJQUFJLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FDWiwrQkFBK0IsSUFBSSxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsT0FBTyxFQUFFLENBQ3pELENBQUM7b0JBQ0YsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMseUJBQXlCLEVBQUUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLENBQUM7Z0JBQ3BFLENBQUM7WUFDSCxDQUFDO1FBQ0gsQ0FBQztRQUVELElBQUksSUFBSSxDQUFDLFNBQVMsS0FBSyxTQUFTLEVBQUUsQ0FBQztZQUNqQyxJQUFJLElBQUksQ0FBQyxTQUFTLENBQUMsS0FBSyxLQUFLLFNBQVMsRUFBRSxDQUFDO2dCQUN2QyxJQUFJLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FDWixpQ0FBaUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQ25FLENBQUM7Z0JBQ0YsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQ1gsc0JBQXNCLEVBQ3RCLElBQUksQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxlQUFlLENBQUMsQ0FDM0MsQ0FBQztZQUNKLENBQUM7UUFDSCxDQUFDO1FBRUQsSUFBSSxJQUFJLENBQUMsV0FBVyxLQUFLLFNBQVMsRUFBRSxDQUFDO1lBQ25DLElBQUksQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLDRCQUE0QixJQUFJLENBQUMsV0FBVyxFQUFFLENBQUMsQ0FBQztZQUMvRCxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxrQkFBa0IsRUFBRSxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUM7UUFDdEQsQ0FBQztRQUVELElBQUksSUFBSSxDQUFDLFVBQVUsS0FBSyxTQUFTLEVBQUUsQ0FBQztZQUNsQyxJQUFJLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyw0QkFBNEIsSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDLENBQUM7WUFDOUQsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsaUJBQWlCLEVBQUUsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDO1FBQ3BELENBQUM7UUFFRCxPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFRCxXQUFXLENBQUMsS0FBcUI7UUFDL0IsSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsc0JBQXNCLEtBQUssRUFBRSxDQUFDLENBQUM7UUFDOUMsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsVUFBVSxFQUFFLEtBQUssQ0FBQyxDQUFDO1FBQ2pDLE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUVELGlCQUFpQixDQUFDLGNBQXVCO1FBQ3ZDLElBQUksY0FBYyxLQUFLLFNBQVMsRUFBRSxDQUFDO1lBQ2pDLElBQUksQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLDRCQUE0QixjQUFjLEVBQUUsQ0FBQyxDQUFDO1lBQzdELElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLHlCQUF5QixFQUFFLGNBQWMsQ0FBQyxDQUFDO1FBQzNELENBQUM7UUFDRCxPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFRCwwQkFBMEIsQ0FBQyxLQUFlO1FBQ3hDLElBQUksS0FBSyxLQUFLLFNBQVMsRUFBRSxDQUFDO1lBQ3hCLElBQUksQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLHNDQUFzQyxLQUFLLEVBQUUsQ0FBQyxDQUFDO1lBQzlELElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLDhCQUE4QixFQUFFLEtBQUssQ0FBQyxDQUFDO1FBQ3ZELENBQUM7UUFDRCxPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFRCx3QkFBd0IsQ0FBQyxLQUFlO1FBQ3RDLElBQUksS0FBSyxLQUFLLFNBQVMsRUFBRSxDQUFDO1lBQ3hCLElBQUksQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLG9DQUFvQyxLQUFLLEVBQUUsQ0FBQyxDQUFDO1lBQzVELElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLDRCQUE0QixFQUFFLEtBQUssQ0FBQyxDQUFDO1FBQ3JELENBQUM7UUFDRCxPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFRCxtQkFBbUIsQ0FBQyxRQUFpQjtRQUNuQyxJQUFJLFFBQVEsS0FBSyxTQUFTLEVBQUUsQ0FBQztZQUMzQixJQUFJLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyw4QkFBOEIsUUFBUSxFQUFFLENBQUMsQ0FBQztZQUN6RCxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxpQ0FBaUMsRUFBRSxRQUFRLENBQUMsQ0FBQztRQUM3RCxDQUFDO1FBQ0QsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBRUQsS0FBSztRQUNILE1BQU0sT0FBTyxHQUFXO1lBQ3RCLElBQUksQ0FBQyxTQUFTLEVBQUU7WUFDaEIsSUFBSSxDQUFDLFVBQVUsRUFBRTtZQUNqQixHQUFHLFNBQVMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDO1NBQ3hCLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBRVosSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsa0JBQWtCLE9BQU8sRUFBRSxDQUFDLENBQUM7UUFDNUMsT0FBTyxPQUFPLENBQUM7SUFDakIsQ0FBQztJQUVELFVBQVU7UUFDUixPQUFPLElBQUksQ0FBQyxPQUFPLENBQUM7SUFDdEIsQ0FBQztJQUVELFNBQVM7UUFDUCxPQUFPLElBQUksQ0FBQyxPQUFPLENBQUM7SUFDdEIsQ0FBQztJQUVELE9BQU87UUFDTCxPQUFPLFNBQVMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDOUIsQ0FBQztJQUVELEtBQUssQ0FBQyxPQUFPO1FBQ1gsTUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFDO1FBQzdCLE1BQU0sSUFBSSxHQUFHLENBQUMsSUFBSSxDQUFDLFVBQVUsRUFBRSxFQUFFLEdBQUcsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUM7UUFFcEQsSUFBSSxDQUFDO1lBQ0gsb0RBQW9EO1lBQ3BELG9FQUFvRTtZQUNwRSxNQUFNLFVBQVUsQ0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFDOUIsQ0FBQztRQUFDLE9BQU8sS0FBYyxFQUFFLENBQUM7WUFDeEIsSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMseUNBQXlDLEtBQUssRUFBRSxDQUFDLENBQUM7WUFDakUsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNsQixDQUFDO0lBQ0gsQ0FBQztDQUNGIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgTG9nZ2VyLCBMb2dnaW5nIH0gZnJvbSBcIkBkZWNhZi10cy9sb2dnaW5nXCI7XG5pbXBvcnQgeyBGYWJyaWNCaW5hcmllcyB9IGZyb20gXCIuLi9jb25zdGFudHMvZmFicmljLWJpbmFyaWVzXCI7XG5pbXBvcnQgeyBGYWJyaWNDQVNlcnZlckNvbW1hbmQgfSBmcm9tIFwiLi4vY29uc3RhbnRzL2ZhYnJpYy1jYS1zZXJ2ZXJcIjtcbmltcG9ydCB7XG4gIENBQ29uZmlnLFxuICBDb21tYWRDU1JDb25maWcsXG4gIENvbW1hbmRJbnRlcm1lZGlhdGVDQUNvbmZpZyxcbiAgQ29tbWFuZExEQVBDb25maWcsXG4gIENvcnNDb25maWcsXG4gIERCQ29uZmlnLFxuICBJZGVtaXhDb25maWcsXG4gIFNlcnZlclRMU0NvbmZpZyxcbn0gZnJvbSBcIi4uL2ludGVyZmFjZXMvZmFicmljL2ZhYnJpYy1jYS1zZXJ2ZXItY29uZmlnXCI7XG5pbXBvcnQgeyBDT01NQV9TRVBBUkFUT1IgfSBmcm9tIFwiLi4vLi4vY29yZS9jb25zdGFudHMvY29uc3RhbnRzXCI7XG5pbXBvcnQgeyBtYXBQYXJzZXIgfSBmcm9tIFwiLi4vLi4vdXRpbHNcIjtcbmltcG9ydCB7IHJ1bkNvbW1hbmQgfSBmcm9tIFwiLi4vLi4vdXRpbHMvY2hpbGQtcHJvY2Vzc1wiO1xuaW1wb3J0IHsgRmFicmljTG9nTGV2ZWwgfSBmcm9tIFwiLi4vY29uc3RhbnRzL2ZhYnJpYy1nZW5lcmFsXCI7XG5cbmV4cG9ydCBjbGFzcyBGYWJyaWNDQVNlcnZlckNvbW1hbmRCdWlsZGVyIHtcbiAgcHJpdmF0ZSBsb2c6IExvZ2dlcjtcblxuICBwcml2YXRlIGJpbk5hbWU6IEZhYnJpY0JpbmFyaWVzID0gRmFicmljQmluYXJpZXMuU0VSVkVSO1xuICBwcml2YXRlIGNvbW1hbmQ6IEZhYnJpY0NBU2VydmVyQ29tbWFuZCA9IEZhYnJpY0NBU2VydmVyQ29tbWFuZC5IRUxQO1xuXG4gIHByaXZhdGUgYXJnczogTWFwPHN0cmluZywgc3RyaW5nIHwgYm9vbGVhbiB8IG51bWJlciB8IHN0cmluZ1tdPiA9IG5ldyBNYXAoKTtcblxuICBjb25zdHJ1Y3Rvcihsb2dnZXI/OiBMb2dnZXIpIHtcbiAgICBpZiAoIWxvZ2dlcikgdGhpcy5sb2cgPSBMb2dnaW5nLmZvcihGYWJyaWNDQVNlcnZlckNvbW1hbmRCdWlsZGVyKTtcbiAgICBlbHNlIHRoaXMubG9nID0gbG9nZ2VyLmZvcihGYWJyaWNDQVNlcnZlckNvbW1hbmRCdWlsZGVyLm5hbWUpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBTZXRzIHRoZSBjb21tYW5kIGZvciB0aGUgRmFicmljIENBIFNlcnZlci5cbiAgICogQHN1bW1hcnkgQ29uZmlndXJlcyB0aGUgcHJpbWFyeSBhY3Rpb24gZm9yIHRoZSBGYWJyaWMgQ0EgU2VydmVyLCBzdWNoIGFzIHN0YXJ0aW5nIHRoZSBzZXJ2ZXIgb3IgZ2VuZXJhdGluZyBjZXJ0aWZpY2F0ZXMuXG4gICAqIEBwYXJhbSB7RmFicmljQ0FTZXJ2ZXJDb21tYW5kfSBbY29tbWFuZF0gLSBUaGUgY29tbWFuZCB0byBiZSBleGVjdXRlZCBieSB0aGUgRmFicmljIENBIFNlcnZlci5cbiAgICogQHJldHVybiB7dGhpc30gVGhlIGN1cnJlbnQgaW5zdGFuY2Ugb2YgdGhlIGJ1aWxkZXIgZm9yIG1ldGhvZCBjaGFpbmluZy5cbiAgICovXG4gIHNldENvbW1hbmQoY29tbWFuZD86IEZhYnJpY0NBU2VydmVyQ29tbWFuZCk6IHRoaXMge1xuICAgIGlmIChjb21tYW5kICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHRoaXMubG9nLmRlYnVnKGBTZXR0aW5nIGNvbW1hbmQ6ICR7Y29tbWFuZH1gKTtcbiAgICAgIHRoaXMuY29tbWFuZCA9IGNvbW1hbmQ7XG4gICAgfVxuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBTZXRzIHRoZSBwb3J0IGZvciB0aGUgRmFicmljIENBIFNlcnZlci5cbiAgICogQHN1bW1hcnkgQ29uZmlndXJlcyB0aGUgbmV0d29yayBwb3J0IG9uIHdoaWNoIHRoZSBGYWJyaWMgQ0EgU2VydmVyIHdpbGwgbGlzdGVuIGZvciBpbmNvbWluZyBjb25uZWN0aW9ucy5cbiAgICogQHBhcmFtIHtudW1iZXJ9IFtwb3J0XSAtIFRoZSBwb3J0IG51bWJlciBmb3IgdGhlIEZhYnJpYyBDQSBTZXJ2ZXIgdG8gbGlzdGVuIG9uLlxuICAgKiBAcmV0dXJuIHt0aGlzfSBUaGUgY3VycmVudCBpbnN0YW5jZSBvZiB0aGUgYnVpbGRlciBmb3IgbWV0aG9kIGNoYWluaW5nLlxuICAgKi9cbiAgc2V0UG9ydChwb3J0PzogbnVtYmVyKTogdGhpcyB7XG4gICAgaWYgKHBvcnQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgdGhpcy5sb2cuZGVidWcoYFNldHRpbmcgcG9ydDogJHtwb3J0fWApO1xuICAgICAgdGhpcy5hcmdzLnNldChcInBvcnRcIiwgcG9ydCk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBFbmFibGVzIG9yIGRpc2FibGVzIGRlYnVnIG1vZGUgZm9yIHRoZSBGYWJyaWMgQ0EgU2VydmVyLlxuICAgKiBAc3VtbWFyeSBDb25maWd1cmVzIHdoZXRoZXIgdGhlIEZhYnJpYyBDQSBTZXJ2ZXIgc2hvdWxkIHJ1biBpbiBkZWJ1ZyBtb2RlLCBwcm92aWRpbmcgbW9yZSBkZXRhaWxlZCBsb2dnaW5nIGFuZCBvdXRwdXQuXG4gICAqIEBwYXJhbSB7Ym9vbGVhbn0gW2VuYWJsZV0gLSBXaGV0aGVyIHRvIGVuYWJsZSBkZWJ1ZyBtb2RlLlxuICAgKiBAcmV0dXJuIHt0aGlzfSBUaGUgY3VycmVudCBpbnN0YW5jZSBvZiB0aGUgYnVpbGRlciBmb3IgbWV0aG9kIGNoYWluaW5nLlxuICAgKi9cbiAgZW5hYmxlRGVidWcoZW5hYmxlPzogYm9vbGVhbik6IHRoaXMge1xuICAgIGlmIChlbmFibGUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgdGhpcy5sb2cuZGVidWcoYFNldHRpbmcgZGVidWc6ICR7ZW5hYmxlfWApO1xuICAgICAgdGhpcy5hcmdzLnNldChcImRlYnVnXCIsIGVuYWJsZSk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgc2V0U2VydmVyVExTKHRsc0NvbmZpZz86IFNlcnZlclRMU0NvbmZpZyk6IHRoaXMge1xuICAgIGlmICghdGxzQ29uZmlnKSByZXR1cm4gdGhpcztcblxuICAgIGlmICh0bHNDb25maWcuZW5hYmxlZCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICB0aGlzLmxvZy5kZWJ1ZyhcIlNldHRpbmcgVExTIGVuYWJsZWRcIik7XG4gICAgICB0aGlzLmFyZ3Muc2V0KFwidGxzLmVuYWJsZWRcIiwgdGxzQ29uZmlnLmVuYWJsZWQpO1xuICAgIH1cblxuICAgIGlmICh0bHNDb25maWcuY2VydGZpbGUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgdGhpcy5sb2cuZGVidWcoYFNldHRpbmcgVExTIGNlcnQgZmlsZTogJHt0bHNDb25maWcuY2VydGZpbGV9YCk7XG4gICAgICB0aGlzLmFyZ3Muc2V0KFwidGxzLmNlcnRmaWxlXCIsIHRsc0NvbmZpZy5jZXJ0ZmlsZSk7XG4gICAgfVxuXG4gICAgaWYgKHRsc0NvbmZpZy5rZXlmaWxlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHRoaXMubG9nLmRlYnVnKGBTZXR0aW5nIFRMUyBrZXkgZmlsZTogJHt0bHNDb25maWcua2V5ZmlsZX1gKTtcbiAgICAgIHRoaXMuYXJncy5zZXQoXCJ0bHMua2V5ZmlsZVwiLCB0bHNDb25maWcua2V5ZmlsZSk7XG4gICAgfVxuXG4gICAgaWYgKHRsc0NvbmZpZy5jbGllbnRhdXRoID09PSB1bmRlZmluZWQpIHJldHVybiB0aGlzO1xuXG4gICAgaWYgKHRsc0NvbmZpZy5jbGllbnRhdXRoLmNlcnRmaWxlcyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICB0aGlzLmxvZy5kZWJ1ZyhcbiAgICAgICAgYFNldHRpbmcgVExTIGNsaWVudCBjZXJ0ZmlsZXM6ICR7dGxzQ29uZmlnLmNsaWVudGF1dGguY2VydGZpbGVzfWBcbiAgICAgICk7XG4gICAgICB0aGlzLmFyZ3Muc2V0KFxuICAgICAgICBcInRscy5jbGllbnRhdXRoLmNlcnRmaWxlc1wiLFxuICAgICAgICB0bHNDb25maWcuY2xpZW50YXV0aC5jZXJ0ZmlsZXMuam9pbihDT01NQV9TRVBBUkFUT1IpXG4gICAgICApO1xuICAgIH1cblxuICAgIGlmICh0bHNDb25maWcuY2xpZW50YXV0aC50eXBlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHRoaXMubG9nLmRlYnVnKFxuICAgICAgICBgU2V0dGluZyBUTFMgY2xpZW50IGF1dGggdHlwZTogJHt0bHNDb25maWcuY2xpZW50YXV0aC50eXBlfWBcbiAgICAgICk7XG4gICAgICB0aGlzLmFyZ3Muc2V0KFwidGxzLmNsaWVudGF1dGgudHlwZVwiLCB0bHNDb25maWcuY2xpZW50YXV0aC50eXBlKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIHNldENBKGNvbmZpZzogQ0FDb25maWcpOiB0aGlzIHtcbiAgICBpZiAoIWNvbmZpZykgcmV0dXJuIHRoaXM7XG5cbiAgICBpZiAoY29uZmlnLm5hbWUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgdGhpcy5sb2cuZGVidWcoYFNldHRpbmcgQ0EgbmFtZTogJHtjb25maWcubmFtZX1gKTtcbiAgICAgIHRoaXMuYXJncy5zZXQoXCJjYS5uYW1lXCIsIGNvbmZpZy5uYW1lKTtcbiAgICB9XG5cbiAgICBpZiAoY29uZmlnLmtleWZpbGUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgdGhpcy5sb2cuZGVidWcoYFNldHRpbmcgQ0Ega2V5IGZpbGU6ICR7Y29uZmlnLmtleWZpbGV9YCk7XG4gICAgICB0aGlzLmFyZ3Muc2V0KFwiY2Eua2V5ZmlsZVwiLCBjb25maWcua2V5ZmlsZSk7XG4gICAgfVxuXG4gICAgaWYgKGNvbmZpZy5jZXJ0ZmlsZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICB0aGlzLmxvZy5kZWJ1ZyhgU2V0dGluZyBDQSBjZXJ0IGZpbGU6ICR7Y29uZmlnLmNlcnRmaWxlfWApO1xuICAgICAgdGhpcy5hcmdzLnNldChcImNhLmNlcnRmaWxlXCIsIGNvbmZpZy5jZXJ0ZmlsZSk7XG4gICAgfVxuXG4gICAgaWYgKGNvbmZpZy5jaGFpbmZpbGUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgdGhpcy5sb2cuZGVidWcoYFNldHRpbmcgQ0EgY2hhaW4gZmlsZTogJHtjb25maWcuY2hhaW5maWxlfWApO1xuICAgICAgdGhpcy5hcmdzLnNldChcImNhLmNoYWluZmlsZVwiLCBjb25maWcuY2hhaW5maWxlKTtcbiAgICB9XG5cbiAgICBpZiAoY29uZmlnLnJlZW5yb2xsSWdub3JlQ2VydEV4cGlyeSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICB0aGlzLmxvZy5kZWJ1ZyhcbiAgICAgICAgYFNldHRpbmcgcmVlbnJvbGxJZ25vcmVDZXJ0RXhwaXJ5OiAke2NvbmZpZy5yZWVucm9sbElnbm9yZUNlcnRFeHBpcnl9YFxuICAgICAgKTtcbiAgICAgIHRoaXMuYXJncy5zZXQoXG4gICAgICAgIFwiY2EucmVlbnJvbGxpZ25vcmVjZXJ0ZXhwaXJ5XCIsXG4gICAgICAgIGNvbmZpZy5yZWVucm9sbElnbm9yZUNlcnRFeHBpcnlcbiAgICAgICk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFNldHMgdGhlIGFkZHJlc3MgZm9yIHRoZSBGYWJyaWMgQ0EgU2VydmVyLlxuICAgKiBAc3VtbWFyeSBDb25maWd1cmVzIHRoZSBuZXR3b3JrIGFkZHJlc3Mgb24gd2hpY2ggdGhlIEZhYnJpYyBDQSBTZXJ2ZXIgd2lsbCBsaXN0ZW4gZm9yIGluY29taW5nIGNvbm5lY3Rpb25zLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gW2FkZHJlc3NdIC0gVGhlIG5ldHdvcmsgYWRkcmVzcyBmb3IgdGhlIEZhYnJpYyBDQSBTZXJ2ZXIgdG8gbGlzdGVuIG9uLlxuICAgKiBAcmV0dXJuIHt0aGlzfSBUaGUgY3VycmVudCBpbnN0YW5jZSBvZiB0aGUgYnVpbGRlciBmb3IgbWV0aG9kIGNoYWluaW5nLlxuICAgKi9cbiAgc2V0QWRkcmVzcyhhZGRyZXNzPzogc3RyaW5nKTogdGhpcyB7XG4gICAgaWYgKGFkZHJlc3MgIT09IHVuZGVmaW5lZCkge1xuICAgICAgdGhpcy5sb2cuZGVidWcoYFNldHRpbmcgYWRkcmVzczogJHthZGRyZXNzfWApO1xuICAgICAgdGhpcy5hcmdzLnNldChcImFkZHJlc3NcIiwgYWRkcmVzcyk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBTZXRzIHRoZSBib290c3RyYXAgYWRtaW4gdXNlciBmb3IgdGhlIEZhYnJpYyBDQSBTZXJ2ZXIuXG4gICAqIEBzdW1tYXJ5IENvbmZpZ3VyZXMgdGhlIGluaXRpYWwgYWRtaW4gdXNlciB3aXRoIGZ1bGwgcHJpdmlsZWdlcyBmb3IgdGhlIEZhYnJpYyBDQSBTZXJ2ZXIuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBbYm9vdFVzZXJdIC0gVGhlIGJvb3RzdHJhcCBhZG1pbiB1c2VyIGluIHRoZSBmb3JtYXQgXCJ1c2VybmFtZTpwYXNzd29yZFwiLlxuICAgKiBAcmV0dXJuIHt0aGlzfSBUaGUgY3VycmVudCBpbnN0YW5jZSBvZiB0aGUgYnVpbGRlciBmb3IgbWV0aG9kIGNoYWluaW5nLlxuICAgKi9cbiAgc2V0Qm9vdHN0cmFwQWRtaW4oYm9vdFVzZXI/OiBzdHJpbmcpOiB0aGlzIHtcbiAgICBpZiAoYm9vdFVzZXIgIT09IHVuZGVmaW5lZCkge1xuICAgICAgY29uc3QgW3VzZXIsIHBhc3N3b3JkXSA9IGJvb3RVc2VyLnNwbGl0KFwiOlwiKTtcbiAgICAgIHRoaXMubG9nLmRlYnVnKGBTZXR0aW5nIGJvb3RzdHJhcCBhZG1pbjogJHt1c2VyfToke3Bhc3N3b3JkfWApO1xuICAgICAgdGhpcy5hcmdzLnNldChcImJvb3RcIiwgYm9vdFVzZXIpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gU2V0cyB0aGUgbnVtYmVyIG9mIENBcyB0byBydW4gb24gdGhlIEZhYnJpYyBDQSBTZXJ2ZXIuXG4gICAqIEBzdW1tYXJ5IENvbmZpZ3VyZXMgdGhlIEZhYnJpYyBDQSBTZXJ2ZXIgdG8gcnVuIG11bHRpcGxlIENBIGluc3RhbmNlcy5cbiAgICogQHBhcmFtIHtudW1iZXJ9IFtjb3VudF0gLSBUaGUgbnVtYmVyIG9mIENBIGluc3RhbmNlcyB0byBydW4uXG4gICAqIEByZXR1cm4ge3RoaXN9IFRoZSBjdXJyZW50IGluc3RhbmNlIG9mIHRoZSBidWlsZGVyIGZvciBtZXRob2QgY2hha