aws-cdk
Version:
AWS CDK CLI, the command line tool for CDK apps
681 lines • 96.4 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.exec = exec;
exports.cli = cli;
/* eslint-disable @typescript-eslint/no-shadow */ // yargs
const cxapi = require("@aws-cdk/cx-api");
const toolkit_lib_1 = require("@aws-cdk/toolkit-lib");
const chalk = require("chalk");
const cdk_toolkit_1 = require("./cdk-toolkit");
const ci_systems_1 = require("./ci-systems");
const display_version_1 = require("./display-version");
const io_host_1 = require("./io-host");
const parse_command_line_arguments_1 = require("./parse-command-line-arguments");
const platform_warnings_1 = require("./platform-warnings");
const pretty_print_error_1 = require("./pretty-print-error");
const singleton_plugin_host_1 = require("./singleton-plugin-host");
const user_configuration_1 = require("./user-configuration");
const api_private_1 = require("../../lib/api-private");
const api_1 = require("../api");
const aws_auth_1 = require("../api/aws-auth");
const bootstrap_1 = require("../api/bootstrap");
const deployments_1 = require("../api/deployments");
const hotswap_1 = require("../api/hotswap");
const context_1 = require("../commands/context");
const docs_1 = require("../commands/docs");
const doctor_1 = require("../commands/doctor");
const flags_1 = require("../commands/flags/flags");
const init_1 = require("../commands/init");
const migrate_1 = require("../commands/migrate");
const cxapp_1 = require("../cxapp");
const proxy_agent_1 = require("./proxy-agent");
const error_1 = require("./telemetry/error");
const ci_1 = require("./util/ci");
const version_1 = require("./version");
const language_1 = require("../commands/language");
if (!process.stdout.isTTY) {
// Disable chalk color highlighting
process.env.FORCE_COLOR = '0';
}
async function exec(args, synthesizer) {
const argv = await (0, parse_command_line_arguments_1.parseCommandLineArguments)(args);
argv.language = (0, language_1.getLanguageFromAlias)(argv.language) ?? argv.language;
const cmd = argv._[0];
// if one -v, log at a DEBUG level
// if 2 -v, log at a TRACE level
let ioMessageLevel = 'info';
if (argv.verbose) {
switch (argv.verbose) {
case 1:
ioMessageLevel = 'debug';
break;
case 2:
default:
ioMessageLevel = 'trace';
break;
}
}
const ioHost = io_host_1.CliIoHost.instance({
logLevel: ioMessageLevel,
isTTY: process.stdout.isTTY,
isCI: Boolean(argv.ci),
currentAction: cmd,
stackProgress: argv.progress,
autoRespond: argv.yes,
}, true);
const ioHelper = (0, api_private_1.asIoHelper)(ioHost, ioHost.currentAction);
// Debug should always imply tracing
(0, aws_auth_1.setSdkTracing)(argv.debug || argv.verbose > 2);
try {
await (0, platform_warnings_1.checkForPlatformWarnings)(ioHelper);
}
catch (e) {
await ioHost.defaults.debug(`Error while checking for platform warnings: ${e}`);
}
await ioHost.defaults.debug('CDK Toolkit CLI version:', (0, version_1.versionWithBuild)());
await ioHost.defaults.debug('Command line arguments:', argv);
const configuration = await user_configuration_1.Configuration.fromArgsAndFiles(ioHelper, {
commandLineArguments: {
...argv,
_: argv._, // TypeScript at its best
},
});
// Always create and use ProxyAgent to support configuration via env vars
const proxyAgent = await new proxy_agent_1.ProxyAgentProvider(ioHelper).create({
proxyAddress: configuration.settings.get(['proxy']),
caBundlePath: configuration.settings.get(['caBundlePath']),
});
try {
await ioHost.startTelemetry(argv, configuration.context);
}
catch (e) {
await ioHost.asIoHelper().defaults.trace(`Telemetry instantiation failed: ${e.message}`);
}
/**
* The default value for displaying (and refreshing) notices on all commands.
*
* If the user didn't supply either `--notices` or `--no-notices`, we do
* autodetection. The autodetection currently is: do write notices if we are
* not on CI, or are on a CI system where we know that writing to stderr is
* safe. We fail "closed"; that is, we decide to NOT print for unknown CI
* systems, even though technically we maybe could.
*/
const isSafeToWriteNotices = !(0, ci_1.isCI)() || Boolean((0, ci_systems_1.ciSystemIsStdErrSafe)());
// Determine if notices should be displayed based on CLI args and configuration
let shouldDisplayNotices;
if (argv.notices !== undefined) {
// CLI argument takes precedence
shouldDisplayNotices = argv.notices;
}
else {
// Fall back to configuration file setting, then autodetection
const configNotices = configuration.settings.get(['notices']);
if (configNotices !== undefined) {
// Consider string "false" to be falsy in this context
shouldDisplayNotices = configNotices !== 'false' && Boolean(configNotices);
}
else {
// Default autodetection behavior
shouldDisplayNotices = isSafeToWriteNotices;
}
}
// Notices either go to stderr, or nowhere
ioHost.noticesDestination = shouldDisplayNotices ? 'stderr' : 'drop';
const notices = api_1.Notices.create({
ioHost,
context: configuration.context,
output: configuration.settings.get(['outdir']),
httpOptions: { agent: proxyAgent },
cliVersion: (0, version_1.versionNumber)(),
});
const refreshNotices = (async () => {
// the cdk notices command has it's own refresh
if (shouldDisplayNotices && cmd !== 'notices') {
try {
return await notices.refresh();
}
catch (e) {
await ioHelper.defaults.debug(`Could not refresh notices: ${e}`);
}
}
})();
const sdkProvider = await aws_auth_1.SdkProvider.withAwsCliCompatibleDefaults({
ioHelper,
requestHandler: (0, aws_auth_1.sdkRequestHandler)(proxyAgent),
logger: new aws_auth_1.IoHostSdkLogger((0, api_private_1.asIoHelper)(ioHost, ioHost.currentAction)),
pluginHost: singleton_plugin_host_1.GLOBAL_PLUGIN_HOST,
}, configuration.settings.get(['profile']));
try {
await ioHost.telemetry?.attachRegion(sdkProvider.defaultRegion);
}
catch (e) {
await ioHost.asIoHelper().defaults.trace(`Telemetry attach region failed: ${e.message}`);
}
let outDirLock;
const cloudExecutable = new cxapp_1.CloudExecutable({
configuration,
sdkProvider,
synthesizer: synthesizer ??
(async (aws, config) => {
// Invoke 'execProgram', and copy the lock for the directory in the global
// variable here. It will be released when the CLI exits. Locks are not re-entrant
// so release it if we have to synthesize more than once (because of context lookups).
await outDirLock?.release();
const { assembly, lock } = await (0, cxapp_1.execProgram)(aws, ioHost.asIoHelper(), config);
outDirLock = lock;
return assembly;
}),
ioHelper: ioHost.asIoHelper(),
});
/** Function to load plug-ins, using configurations additively. */
async function loadPlugins(...settings) {
for (const source of settings) {
const plugins = source.get(['plugin']) || [];
for (const plugin of plugins) {
await singleton_plugin_host_1.GLOBAL_PLUGIN_HOST.load(plugin, ioHost);
}
}
}
await loadPlugins(configuration.settings);
if ((typeof cmd) !== 'string') {
throw new toolkit_lib_1.ToolkitError(`First argument should be a string. Got: ${cmd} (${typeof cmd})`);
}
try {
return await main(cmd, argv);
}
finally {
// If we locked the 'cdk.out' directory, release it here.
await outDirLock?.release();
// Do PSAs here
await (0, display_version_1.displayVersionMessage)(ioHelper);
await refreshNotices;
if (cmd === 'notices') {
await notices.refresh({ force: true });
await notices.display({
includeAcknowledged: !argv.unacknowledged,
showTotal: argv.unacknowledged,
});
}
else if (shouldDisplayNotices && cmd !== 'version') {
await notices.display();
}
}
async function main(command, args) {
ioHost.currentAction = command;
const toolkitStackName = api_1.ToolkitInfo.determineName(configuration.settings.get(['toolkitStackName']));
await ioHost.defaults.debug(`Toolkit stack: ${chalk.bold(toolkitStackName)}`);
const cloudFormation = new deployments_1.Deployments({
sdkProvider,
toolkitStackName,
ioHelper: (0, api_private_1.asIoHelper)(ioHost, ioHost.currentAction),
});
if (args.all && args.STACKS) {
throw new toolkit_lib_1.ToolkitError('You must either specify a list of Stacks or the `--all` argument');
}
args.STACKS = args.STACKS ?? (args.STACK ? [args.STACK] : []);
args.ENVIRONMENTS = args.ENVIRONMENTS ?? [];
const selector = {
allTopLevel: args.all,
patterns: args.STACKS,
};
const cli = new cdk_toolkit_1.CdkToolkit({
ioHost,
cloudExecutable,
toolkitStackName,
deployments: cloudFormation,
verbose: argv.trace || argv.verbose > 0,
ignoreErrors: argv['ignore-errors'],
strict: argv.strict,
configuration,
sdkProvider,
});
switch (command) {
case 'context':
ioHost.currentAction = 'context';
return (0, context_1.contextHandler)({
ioHelper,
context: configuration.context,
clear: argv.clear,
json: argv.json,
force: argv.force,
reset: argv.reset,
});
case 'docs':
case 'doc':
ioHost.currentAction = 'docs';
return (0, docs_1.docs)({
ioHelper,
browser: configuration.settings.get(['browser']),
});
case 'doctor':
ioHost.currentAction = 'doctor';
return (0, doctor_1.doctor)({
ioHelper,
});
case 'ls':
case 'list':
ioHost.currentAction = 'list';
return cli.list(args.STACKS, {
long: args.long,
json: argv.json,
showDeps: args.showDependencies,
});
case 'diff':
ioHost.currentAction = 'diff';
const enableDiffNoFail = isFeatureEnabled(configuration, cxapi.ENABLE_DIFF_NO_FAIL_CONTEXT);
return cli.diff({
stackNames: args.STACKS,
exclusively: args.exclusively,
templatePath: args.template,
strict: args.strict,
contextLines: args.contextLines,
securityOnly: args.securityOnly,
fail: args.fail != null ? args.fail : !enableDiffNoFail,
compareAgainstProcessedTemplate: args.processed,
quiet: args.quiet,
changeSet: args['change-set'],
toolkitStackName: toolkitStackName,
importExistingResources: args.importExistingResources,
includeMoves: args['include-moves'],
});
case 'drift':
ioHost.currentAction = 'drift';
return cli.drift({
selector,
fail: args.fail,
});
case 'refactor':
if (!configuration.settings.get(['unstable']).includes('refactor')) {
throw new toolkit_lib_1.ToolkitError('Unstable feature use: \'refactor\' is unstable. It must be opted in via \'--unstable\', e.g. \'cdk refactor --unstable=refactor\'');
}
ioHost.currentAction = 'refactor';
return cli.refactor({
dryRun: args.dryRun,
overrideFile: args.overrideFile,
revert: args.revert,
stacks: selector,
additionalStackNames: arrayFromYargs(args.additionalStackName ?? []),
force: args.force ?? false,
roleArn: args.roleArn,
});
case 'bootstrap':
ioHost.currentAction = 'bootstrap';
const source = await determineBootstrapVersion(ioHost, args);
if (args.showTemplate) {
const bootstrapper = new bootstrap_1.Bootstrapper(source, (0, api_private_1.asIoHelper)(ioHost, ioHost.currentAction));
return bootstrapper.showTemplate(args.json);
}
return cli.bootstrap(args.ENVIRONMENTS, {
source,
roleArn: args.roleArn,
forceDeployment: argv.force,
toolkitStackName: toolkitStackName,
execute: args.execute,
tags: configuration.settings.get(['tags']),
terminationProtection: args.terminationProtection,
usePreviousParameters: args['previous-parameters'],
parameters: {
bucketName: configuration.settings.get(['toolkitBucket', 'bucketName']),
kmsKeyId: configuration.settings.get(['toolkitBucket', 'kmsKeyId']),
createCustomerMasterKey: args.bootstrapCustomerKey,
qualifier: args.qualifier ?? configuration.context.get('@aws-cdk/core:bootstrapQualifier'),
publicAccessBlockConfiguration: args.publicAccessBlockConfiguration,
examplePermissionsBoundary: argv.examplePermissionsBoundary,
customPermissionsBoundary: argv.customPermissionsBoundary,
trustedAccounts: arrayFromYargs(args.trust),
trustedAccountsForLookup: arrayFromYargs(args.trustForLookup),
untrustedAccounts: arrayFromYargs(args.untrust),
cloudFormationExecutionPolicies: arrayFromYargs(args.cloudformationExecutionPolicies),
denyExternalId: args.denyExternalId,
},
});
case 'deploy':
ioHost.currentAction = 'deploy';
const parameterMap = {};
for (const parameter of args.parameters) {
if (typeof parameter === 'string') {
const keyValue = parameter.split('=');
parameterMap[keyValue[0]] = keyValue.slice(1).join('=');
}
}
if (args.execute !== undefined && args.method !== undefined) {
throw new toolkit_lib_1.ToolkitError('Can not supply both --[no-]execute and --method at the same time');
}
return cli.deploy({
selector,
exclusively: args.exclusively,
toolkitStackName,
roleArn: args.roleArn,
notificationArns: args.notificationArns,
requireApproval: configuration.settings.get(['requireApproval']),
reuseAssets: args['build-exclude'],
tags: configuration.settings.get(['tags']),
deploymentMethod: determineDeploymentMethod(args, configuration),
force: args.force,
parameters: parameterMap,
usePreviousParameters: args['previous-parameters'],
outputsFile: configuration.settings.get(['outputsFile']),
progress: configuration.settings.get(['progress']),
ci: args.ci,
rollback: configuration.settings.get(['rollback']),
watch: args.watch,
traceLogs: args.logs,
concurrency: args.concurrency,
assetParallelism: configuration.settings.get(['assetParallelism']),
assetBuildTime: configuration.settings.get(['assetPrebuild'])
? cdk_toolkit_1.AssetBuildTime.ALL_BEFORE_DEPLOY
: cdk_toolkit_1.AssetBuildTime.JUST_IN_TIME,
ignoreNoStacks: args.ignoreNoStacks,
});
case 'rollback':
ioHost.currentAction = 'rollback';
return cli.rollback({
selector,
toolkitStackName,
roleArn: args.roleArn,
force: args.force,
validateBootstrapStackVersion: args['validate-bootstrap-version'],
orphanLogicalIds: args.orphan,
});
case 'import':
ioHost.currentAction = 'import';
return cli.import({
selector,
toolkitStackName,
roleArn: args.roleArn,
deploymentMethod: {
method: 'change-set',
execute: args.execute,
changeSetName: args.changeSetName,
},
progress: configuration.settings.get(['progress']),
rollback: configuration.settings.get(['rollback']),
recordResourceMapping: args['record-resource-mapping'],
resourceMappingFile: args['resource-mapping'],
force: args.force,
});
case 'watch':
ioHost.currentAction = 'watch';
await cli.watch({
selector,
exclusively: args.exclusively,
toolkitStackName,
roleArn: args.roleArn,
reuseAssets: args['build-exclude'],
deploymentMethod: determineDeploymentMethod(args, configuration, true),
force: args.force,
progress: configuration.settings.get(['progress']),
rollback: configuration.settings.get(['rollback']),
traceLogs: args.logs,
concurrency: args.concurrency,
});
return;
case 'destroy':
ioHost.currentAction = 'destroy';
return cli.destroy({
selector,
exclusively: args.exclusively,
force: args.force,
roleArn: args.roleArn,
});
case 'gc':
ioHost.currentAction = 'gc';
if (!configuration.settings.get(['unstable']).includes('gc')) {
throw new toolkit_lib_1.ToolkitError('Unstable feature use: \'gc\' is unstable. It must be opted in via \'--unstable\', e.g. \'cdk gc --unstable=gc\'');
}
if (args.bootstrapStackName) {
await ioHost.defaults.warn('--bootstrap-stack-name is deprecated and will be removed when gc is GA. Use --toolkit-stack-name.');
}
// roleArn is defined for when cloudformation is invoked
// This conflicts with direct sdk calls existing in the gc command to s3 and ecr
if (args.roleArn) {
await ioHost.defaults.warn('The --role-arn option is not supported for the gc command and will be ignored.');
}
return cli.garbageCollect(args.ENVIRONMENTS, {
action: args.action,
type: args.type,
rollbackBufferDays: args['rollback-buffer-days'],
createdBufferDays: args['created-buffer-days'],
bootstrapStackName: args.toolkitStackName ?? args.bootstrapStackName,
confirm: args.confirm,
});
case 'flags':
ioHost.currentAction = 'flags';
if (!configuration.settings.get(['unstable']).includes('flags')) {
throw new toolkit_lib_1.ToolkitError('Unstable feature use: \'flags\' is unstable. It must be opted in via \'--unstable\', e.g. \'cdk flags --unstable=flags\'');
}
const toolkit = new toolkit_lib_1.Toolkit({
ioHost,
toolkitStackName,
unstableFeatures: configuration.settings.get(['unstable']),
});
const flagsData = await toolkit.flags(cloudExecutable);
const handler = new flags_1.FlagCommandHandler(flagsData, ioHelper, args, toolkit);
return handler.processFlagsCommand();
case 'synthesize':
case 'synth':
ioHost.currentAction = 'synth';
const quiet = configuration.settings.get(['quiet']) ?? args.quiet;
if (args.exclusively) {
return cli.synth(args.STACKS, args.exclusively, quiet, args.validation, argv.json);
}
else {
return cli.synth(args.STACKS, true, quiet, args.validation, argv.json);
}
case 'notices':
ioHost.currentAction = 'notices';
// If the user explicitly asks for notices, they are now the primary output
// of the command and they should go to stdout.
ioHost.noticesDestination = 'stdout';
// This is a valid command, but we're postponing its execution because displaying
// notices automatically happens after every command.
return;
case 'metadata':
ioHost.currentAction = 'metadata';
return cli.metadata(args.STACK, argv.json);
case 'acknowledge':
case 'ack':
ioHost.currentAction = 'notices';
return cli.acknowledge(args.ID);
case 'cli-telemetry':
ioHost.currentAction = 'cli-telemetry';
if (args.enable === undefined && args.disable === undefined && args.status === undefined) {
throw new toolkit_lib_1.ToolkitError('Must specify \'--enable\', \'--disable\', or \'--status\'');
}
if (args.status) {
return cli.cliTelemetryStatus(args);
}
else {
const enable = args.enable ?? !args.disable;
return cli.cliTelemetry(enable);
}
case 'init':
ioHost.currentAction = 'init';
const language = configuration.settings.get(['language']);
if (args.list) {
return (0, init_1.printAvailableTemplates)(ioHelper, language);
}
else {
// Gate custom template support with unstable flag
if (args['from-path'] && !configuration.settings.get(['unstable']).includes('init')) {
throw new toolkit_lib_1.ToolkitError('Unstable feature use: \'init\' with custom templates is unstable. It must be opted in via \'--unstable\', e.g. \'cdk init --from-path=./my-template --unstable=init\'');
}
return (0, init_1.cliInit)({
ioHelper,
type: args.TEMPLATE,
language,
canUseNetwork: undefined,
generateOnly: args.generateOnly,
libVersion: args.libVersion,
fromPath: args['from-path'],
templatePath: args['template-path'],
packageManager: args['package-manager'],
});
}
case 'migrate':
ioHost.currentAction = 'migrate';
return cli.migrate({
stackName: args['stack-name'],
fromPath: args['from-path'],
fromStack: args['from-stack'],
language: args.language,
outputPath: args['output-path'],
fromScan: (0, migrate_1.getMigrateScanType)(args['from-scan']),
filter: args.filter,
account: args.account,
region: args.region,
compress: args.compress,
});
case 'version':
ioHost.currentAction = 'version';
return ioHost.defaults.result((0, version_1.versionWithBuild)());
default:
throw new toolkit_lib_1.ToolkitError('Unknown command: ' + command);
}
}
}
/**
* Determine which version of bootstrapping
*/
async function determineBootstrapVersion(ioHost, args) {
let source;
if (args.template) {
await ioHost.defaults.info(`Using bootstrapping template from ${args.template}`);
source = { source: 'custom', templateFile: args.template };
}
else if (process.env.CDK_LEGACY_BOOTSTRAP) {
await ioHost.defaults.info('CDK_LEGACY_BOOTSTRAP set, using legacy-style bootstrapping');
source = { source: 'legacy' };
}
else {
// in V2, the "new" bootstrapping is the default
source = { source: 'default' };
}
return source;
}
function isFeatureEnabled(configuration, featureFlag) {
return configuration.context.get(featureFlag) ?? cxapi.futureFlagDefault(featureFlag);
}
/**
* Translate a Yargs input array to something that makes more sense in a programming language
* model (telling the difference between absence and an empty array)
*
* - An empty array is the default case, meaning the user didn't pass any arguments. We return
* undefined.
* - If the user passed a single empty string, they did something like `--array=`, which we'll
* take to mean they passed an empty array.
*/
function arrayFromYargs(xs) {
if (xs.length === 0) {
return undefined;
}
return xs.filter((x) => x !== '');
}
function determineDeploymentMethod(args, configuration, watch) {
let deploymentMethod;
switch (args.method) {
case 'direct':
if (args.changeSetName) {
throw new toolkit_lib_1.ToolkitError('--change-set-name cannot be used with method=direct');
}
if (args.importExistingResources) {
throw new toolkit_lib_1.ToolkitError('--import-existing-resources cannot be enabled with method=direct');
}
deploymentMethod = { method: 'direct' };
break;
case 'change-set':
deploymentMethod = {
method: 'change-set',
execute: true,
changeSetName: args.changeSetName,
importExistingResources: args.importExistingResources,
};
break;
case 'prepare-change-set':
deploymentMethod = {
method: 'change-set',
execute: false,
changeSetName: args.changeSetName,
importExistingResources: args.importExistingResources,
};
break;
case undefined:
default:
deploymentMethod = {
method: 'change-set',
execute: watch ? true : args.execute ?? true,
changeSetName: args.changeSetName,
importExistingResources: args.importExistingResources,
};
break;
}
const hotswapMode = determineHotswapMode(args.hotswap, args.hotswapFallback, watch);
const hotswapProperties = configuration.settings.get(['hotswap']) || {};
switch (hotswapMode) {
case hotswap_1.HotswapMode.FALL_BACK:
return {
method: 'hotswap',
properties: hotswapProperties,
fallback: deploymentMethod,
};
case hotswap_1.HotswapMode.HOTSWAP_ONLY:
return {
method: 'hotswap',
properties: hotswapProperties,
};
default:
case hotswap_1.HotswapMode.FULL_DEPLOYMENT:
return deploymentMethod;
}
}
function determineHotswapMode(hotswap, hotswapFallback, watch) {
if (hotswap && hotswapFallback) {
throw new toolkit_lib_1.ToolkitError('Can not supply both --hotswap and --hotswap-fallback at the same time');
}
else if (!hotswap && !hotswapFallback) {
if (hotswap === undefined && hotswapFallback === undefined) {
return watch ? hotswap_1.HotswapMode.HOTSWAP_ONLY : hotswap_1.HotswapMode.FULL_DEPLOYMENT;
}
else if (hotswap === false || hotswapFallback === false) {
return hotswap_1.HotswapMode.FULL_DEPLOYMENT;
}
}
let hotswapMode;
if (hotswap) {
hotswapMode = hotswap_1.HotswapMode.HOTSWAP_ONLY;
/* if (hotswapFallback)*/
}
else {
hotswapMode = hotswap_1.HotswapMode.FALL_BACK;
}
return hotswapMode;
}
/* c8 ignore start */ // we never call this in unit tests
function cli(args = process.argv.slice(2)) {
let error;
exec(args)
.then(async (value) => {
if (typeof value === 'number') {
process.exitCode = value;
}
})
.catch(async (err) => {
// Log the stack trace if we're on a developer workstation. Otherwise this will be into a minified
// file and the printed code line and stack trace are huge and useless.
(0, pretty_print_error_1.prettyPrintError)(err, (0, version_1.isDeveloperBuildVersion)());
error = {
name: (0, error_1.cdkCliErrorName)(err.name),
};
process.exitCode = 1;
})
.finally(async () => {
try {
await io_host_1.CliIoHost.get()?.telemetry?.end(error);
}
catch (e) {
await io_host_1.CliIoHost.get()?.asIoHelper().defaults.trace(`Ending Telemetry failed: ${e.message}`);
}
});
}
/* c8 ignore stop */
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xpLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiY2xpLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBNkNBLG9CQStoQkM7QUEwSEQsa0JBd0JDO0FBOXRCRCxpREFBaUQsQ0FBQyxRQUFRO0FBQzFELHlDQUF5QztBQUV6QyxzREFBNkQ7QUFDN0QsK0JBQStCO0FBQy9CLCtDQUEyRDtBQUMzRCw2Q0FBb0Q7QUFDcEQsdURBQTBEO0FBRTFELHVDQUFzQztBQUN0QyxpRkFBMkU7QUFDM0UsMkRBQStEO0FBQy9ELDZEQUF3RDtBQUN4RCxtRUFBNkQ7QUFFN0QsNkRBQXFEO0FBQ3JELHVEQUFtRDtBQUVuRCxnQ0FBOEM7QUFDOUMsOENBQWlHO0FBRWpHLGdEQUFnRDtBQUNoRCxvREFBaUQ7QUFDakQsNENBQTZDO0FBRTdDLGlEQUFnRTtBQUNoRSwyQ0FBd0M7QUFDeEMsK0NBQTRDO0FBQzVDLG1EQUE2RDtBQUM3RCwyQ0FBb0U7QUFDcEUsaURBQXlEO0FBQ3pELG9DQUF3RDtBQUV4RCwrQ0FBbUQ7QUFDbkQsNkNBQW9EO0FBRXBELGtDQUFpQztBQUNqQyx1Q0FBcUY7QUFDckYsbURBQTREO0FBRTVELElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLEtBQUssRUFBRSxDQUFDO0lBQzFCLG1DQUFtQztJQUNuQyxPQUFPLENBQUMsR0FBRyxDQUFDLFdBQVcsR0FBRyxHQUFHLENBQUM7QUFDaEMsQ0FBQztBQUVNLEtBQUssVUFBVSxJQUFJLENBQUMsSUFBYyxFQUFFLFdBQXlCO0lBQ2xFLE1BQU0sSUFBSSxHQUFHLE1BQU0sSUFBQSx3REFBeUIsRUFBQyxJQUFJLENBQUMsQ0FBQztJQUNuRCxJQUFJLENBQUMsUUFBUSxHQUFHLElBQUEsK0JBQW9CLEVBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLElBQUksQ0FBQyxRQUFRLENBQUM7SUFFckUsTUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUV0QixrQ0FBa0M7SUFDbEMsZ0NBQWdDO0lBQ2hDLElBQUksY0FBYyxHQUFtQixNQUFNLENBQUM7SUFDNUMsSUFBSSxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7UUFDakIsUUFBUSxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7WUFDckIsS0FBSyxDQUFDO2dCQUNKLGNBQWMsR0FBRyxPQUFPLENBQUM7Z0JBQ3pCLE1BQU07WUFDUixLQUFLLENBQUMsQ0FBQztZQUNQO2dCQUNFLGNBQWMsR0FBRyxPQUFPLENBQUM7Z0JBQ3pCLE1BQU07UUFDVixDQUFDO0lBQ0gsQ0FBQztJQUVELE1BQU0sTUFBTSxHQUFHLG1CQUFTLENBQUMsUUFBUSxDQUFDO1FBQ2hDLFFBQVEsRUFBRSxjQUFjO1FBQ3hCLEtBQUssRUFBRSxPQUFPLENBQUMsTUFBTSxDQUFDLEtBQUs7UUFDM0IsSUFBSSxFQUFFLE9BQU8sQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDO1FBQ3RCLGFBQWEsRUFBRSxHQUFHO1FBQ2xCLGFBQWEsRUFBRSxJQUFJLENBQUMsUUFBUTtRQUM1QixXQUFXLEVBQUUsSUFBSSxDQUFDLEdBQUc7S0FDdEIsRUFBRSxJQUFJLENBQUMsQ0FBQztJQUNULE1BQU0sUUFBUSxHQUFHLElBQUEsd0JBQVUsRUFBQyxNQUFNLEVBQUUsTUFBTSxDQUFDLGFBQW9CLENBQUMsQ0FBQztJQUVqRSxvQ0FBb0M7SUFDcEMsSUFBQSx3QkFBYSxFQUFDLElBQUksQ0FBQyxLQUFLLElBQUksSUFBSSxDQUFDLE9BQU8sR0FBRyxDQUFDLENBQUMsQ0FBQztJQUU5QyxJQUFJLENBQUM7UUFDSCxNQUFNLElBQUEsNENBQXdCLEVBQUMsUUFBUSxDQUFDLENBQUM7SUFDM0MsQ0FBQztJQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7UUFDWCxNQUFNLE1BQU0sQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLCtDQUErQyxDQUFDLEVBQUUsQ0FBQyxDQUFDO0lBQ2xGLENBQUM7SUFFRCxNQUFNLE1BQU0sQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLDBCQUEwQixFQUFFLElBQUEsMEJBQWdCLEdBQUUsQ0FBQyxDQUFDO0lBQzVFLE1BQU0sTUFBTSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMseUJBQXlCLEVBQUUsSUFBSSxDQUFDLENBQUM7SUFFN0QsTUFBTSxhQUFhLEdBQUcsTUFBTSxrQ0FBYSxDQUFDLGdCQUFnQixDQUFDLFFBQVEsRUFDakU7UUFDRSxvQkFBb0IsRUFBRTtZQUNwQixHQUFHLElBQUk7WUFDUCxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQTJCLEVBQUUseUJBQXlCO1NBQy9EO0tBQ0YsQ0FBQyxDQUFDO0lBRUwseUVBQXlFO0lBQ3pFLE1BQU0sVUFBVSxHQUFHLE1BQU0sSUFBSSxnQ0FBa0IsQ0FBQyxRQUFRLENBQUMsQ0FBQyxNQUFNLENBQUM7UUFDL0QsWUFBWSxFQUFFLGFBQWEsQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDbkQsWUFBWSxFQUFFLGFBQWEsQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLENBQUMsY0FBYyxDQUFDLENBQUM7S0FDM0QsQ0FBQyxDQUFDO0lBRUgsSUFBSSxDQUFDO1FBQ0gsTUFBTSxNQUFNLENBQUMsY0FBYyxDQUFDLElBQUksRUFBRSxhQUFhLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDM0QsQ0FBQztJQUFDLE9BQU8sQ0FBTSxFQUFFLENBQUM7UUFDaEIsTUFBTSxNQUFNLENBQUMsVUFBVSxFQUFFLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxtQ0FBbUMsQ0FBQyxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUM7SUFDM0YsQ0FBQztJQUVEOzs7Ozs7OztPQVFHO0lBQ0gsTUFBTSxvQkFBb0IsR0FBRyxDQUFDLElBQUEsU0FBSSxHQUFFLElBQUksT0FBTyxDQUFDLElBQUEsaUNBQW9CLEdBQUUsQ0FBQyxDQUFDO0lBRXhFLCtFQUErRTtJQUMvRSxJQUFJLG9CQUE2QixDQUFDO0lBQ2xDLElBQUksSUFBSSxDQUFDLE9BQU8sS0FBSyxTQUFTLEVBQUUsQ0FBQztRQUMvQixnQ0FBZ0M7UUFDaEMsb0JBQW9CLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQztJQUN0QyxDQUFDO1NBQU0sQ0FBQztRQUNOLDhEQUE4RDtRQUM5RCxNQUFNLGFBQWEsR0FBRyxhQUFhLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUM7UUFDOUQsSUFBSSxhQUFhLEtBQUssU0FBUyxFQUFFLENBQUM7WUFDaEMsc0RBQXNEO1lBQ3RELG9CQUFvQixHQUFHLGFBQWEsS0FBSyxPQUFPLElBQUksT0FBTyxDQUFDLGFBQWEsQ0FBQyxDQUFDO1FBQzdFLENBQUM7YUFBTSxDQUFDO1lBQ04saUNBQWlDO1lBQ2pDLG9CQUFvQixHQUFHLG9CQUFvQixDQUFDO1FBQzlDLENBQUM7SUFDSCxDQUFDO0lBRUQsMENBQTBDO0lBQzFDLE1BQU0sQ0FBQyxrQkFBa0IsR0FBRyxvQkFBb0IsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUM7SUFDckUsTUFBTSxPQUFPLEdBQUcsYUFBTyxDQUFDLE1BQU0sQ0FBQztRQUM3QixNQUFNO1FBQ04sT0FBTyxFQUFFLGFBQWEsQ0FBQyxPQUFPO1FBQzlCLE1BQU0sRUFBRSxhQUFhLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBQzlDLFdBQVcsRUFBRSxFQUFFLEtBQUssRUFBRSxVQUFVLEVBQUU7UUFDbEMsVUFBVSxFQUFFLElBQUEsdUJBQWEsR0FBRTtLQUM1QixDQUFDLENBQUM7SUFDSCxNQUFNLGNBQWMsR0FBRyxDQUFDLEtBQUssSUFBSSxFQUFFO1FBQ2pDLCtDQUErQztRQUMvQyxJQUFJLG9CQUFvQixJQUFJLEdBQUcsS0FBSyxTQUFTLEVBQUUsQ0FBQztZQUM5QyxJQUFJLENBQUM7Z0JBQ0gsT0FBTyxNQUFNLE9BQU8sQ0FBQyxPQUFPLEVBQUUsQ0FBQztZQUNqQyxDQUFDO1lBQUMsT0FBTyxDQUFNLEVBQUUsQ0FBQztnQkFDaEIsTUFBTSxRQUFRLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyw4QkFBOEIsQ0FBQyxFQUFFLENBQUMsQ0FBQztZQUNuRSxDQUFDO1FBQ0gsQ0FBQztJQUNILENBQUMsQ0FBQyxFQUFFLENBQUM7SUFFTCxNQUFNLFdBQVcsR0FBRyxNQUFNLHNCQUFXLENBQUMsNEJBQTRCLENBQUM7UUFDakUsUUFBUTtRQUNSLGNBQWMsRUFBRSxJQUFBLDRCQUFpQixFQUFDLFVBQVUsQ0FBQztRQUM3QyxNQUFNLEVBQUUsSUFBSSwwQkFBZSxDQUFDLElBQUEsd0JBQVUsRUFBQyxNQUFNLEVBQUUsTUFBTSxDQUFDLGFBQW9CLENBQUMsQ0FBQztRQUM1RSxVQUFVLEVBQUUsMENBQWtCO0tBQy9CLEVBQUUsYUFBYSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFFNUMsSUFBSSxDQUFDO1FBQ0gsTUFBTSxNQUFNLENBQUMsU0FBUyxFQUFFLFlBQVksQ0FBQyxXQUFXLENBQUMsYUFBYSxDQUFDLENBQUM7SUFDbEUsQ0FBQztJQUFDLE9BQU8sQ0FBTSxFQUFFLENBQUM7UUFDaEIsTUFBTSxNQUFNLENBQUMsVUFBVSxFQUFFLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxtQ0FBbUMsQ0FBQyxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUM7SUFDM0YsQ0FBQztJQUVELElBQUksVUFBaUMsQ0FBQztJQUN0QyxNQUFNLGVBQWUsR0FBRyxJQUFJLHVCQUFlLENBQUM7UUFDMUMsYUFBYTtRQUNiLFdBQVc7UUFDWCxXQUFXLEVBQ1QsV0FBVztZQUNYLENBQUMsS0FBSyxFQUFFLEdBQUcsRUFBRSxNQUFNLEVBQUUsRUFBRTtnQkFDckIsMEVBQTBFO2dCQUMxRSxrRkFBa0Y7Z0JBQ2xGLHNGQUFzRjtnQkFDdEYsTUFBTSxVQUFVLEVBQUUsT0FBTyxFQUFFLENBQUM7Z0JBQzVCLE1BQU0sRUFBRSxRQUFRLEVBQUUsSUFBSSxFQUFFLEdBQUcsTUFBTSxJQUFBLG1CQUFXLEVBQUMsR0FBRyxFQUFFLE1BQU0sQ0FBQyxVQUFVLEVBQUUsRUFBRSxNQUFNLENBQUMsQ0FBQztnQkFDL0UsVUFBVSxHQUFHLElBQUksQ0FBQztnQkFDbEIsT0FBTyxRQUFRLENBQUM7WUFDbEIsQ0FBQyxDQUFDO1FBQ0osUUFBUSxFQUFFLE1BQU0sQ0FBQyxVQUFVLEVBQUU7S0FDOUIsQ0FBQyxDQUFDO0lBRUgsa0VBQWtFO0lBQ2xFLEtBQUssVUFBVSxXQUFXLENBQUMsR0FBRyxRQUFvQjtRQUNoRCxLQUFLLE1BQU0sTUFBTSxJQUFJLFFBQVEsRUFBRSxDQUFDO1lBQzlCLE1BQU0sT0FBTyxHQUFhLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxRQUFRLENBQUMsQ0FBQyxJQUFJLEVBQUUsQ0FBQztZQUN2RCxLQUFLLE1BQU0sTUFBTSxJQUFJLE9BQU8sRUFBRSxDQUFDO2dCQUM3QixNQUFNLDBDQUFrQixDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsTUFBTSxDQUFDLENBQUM7WUFDaEQsQ0FBQztRQUNILENBQUM7SUFDSCxDQUFDO0lBRUQsTUFBTSxXQUFXLENBQUMsYUFBYSxDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBRTFDLElBQUksQ0FBQyxPQUFPLEdBQUcsQ0FBQyxLQUFLLFFBQVEsRUFBRSxDQUFDO1FBQzlCLE1BQU0sSUFBSSwwQkFBWSxDQUFDLDJDQUEyQyxHQUFHLEtBQUssT0FBTyxHQUFHLEdBQUcsQ0FBQyxDQUFDO0lBQzNGLENBQUM7SUFFRCxJQUFJLENBQUM7UUFDSCxPQUFPLE1BQU0sSUFBSSxDQUFDLEdBQUcsRUFBRSxJQUFJLENBQUMsQ0FBQztJQUMvQixDQUFDO1lBQVMsQ0FBQztRQUNULHlEQUF5RDtRQUN6RCxNQUFNLFVBQVUsRUFBRSxPQUFPLEVBQUUsQ0FBQztRQUU1QixlQUFlO1FBQ2YsTUFBTSxJQUFBLHVDQUFxQixFQUFDLFFBQVEsQ0FBQyxDQUFDO1FBRXRDLE1BQU0sY0FBYyxDQUFDO1FBQ3JCLElBQUksR0FBRyxLQUFLLFNBQVMsRUFBRSxDQUFDO1lBQ3RCLE1BQU0sT0FBTyxDQUFDLE9BQU8sQ0FBQyxFQUFFLEtBQUssRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO1lBQ3ZDLE1BQU0sT0FBTyxDQUFDLE9BQU8sQ0FBQztnQkFDcEIsbUJBQW1CLEVBQUUsQ0FBQyxJQUFJLENBQUMsY0FBYztnQkFDekMsU0FBUyxFQUFFLElBQUksQ0FBQyxjQUFjO2FBQy9CLENBQUMsQ0FBQztRQUNMLENBQUM7YUFBTSxJQUFJLG9CQUFvQixJQUFJLEdBQUcsS0FBSyxTQUFTLEVBQUUsQ0FBQztZQUNyRCxNQUFNLE9BQU8sQ0FBQyxPQUFPLEVBQUUsQ0FBQztRQUMxQixDQUFDO0lBQ0gsQ0FBQztJQUVELEtBQUssVUFBVSxJQUFJLENBQUMsT0FBZSxFQUFFLElBQVM7UUFDNUMsTUFBTSxDQUFDLGFBQWEsR0FBRyxPQUFjLENBQUM7UUFDdEMsTUFBTSxnQkFBZ0IsR0FBVyxpQkFBVyxDQUFDLGFBQWEsQ0FBQyxhQUFhLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxDQUFDLGtCQUFrQixDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQzdHLE1BQU0sTUFBTSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsa0JBQWtCLEtBQUssQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsRUFBRSxDQUFDLENBQUM7UUFFOUUsTUFBTSxjQUFjLEdBQUcsSUFBSSx5QkFBVyxDQUFDO1lBQ3JDLFdBQVc7WUFDWCxnQkFBZ0I7WUFDaEIsUUFBUSxFQUFFLElBQUEsd0JBQVUsRUFBQyxNQUFNLEVBQUUsTUFBTSxDQUFDLGFBQW9CLENBQUM7U0FDMUQsQ0FBQyxDQUFDO1FBRUgsSUFBSSxJQUFJLENBQUMsR0FBRyxJQUFJLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztZQUM1QixNQUFNLElBQUksMEJBQVksQ0FBQyxrRUFBa0UsQ0FBQyxDQUFDO1FBQzdGLENBQUM7UUFFRCxJQUFJLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQyxNQUFNLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUM7UUFDOUQsSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLENBQUMsWUFBWSxJQUFJLEVBQUUsQ0FBQztRQUU1QyxNQUFNLFFBQVEsR0FBa0I7WUFDOUIsV0FBVyxFQUFFLElBQUksQ0FBQyxHQUFHO1lBQ3JCLFFBQVEsRUFBRSxJQUFJLENBQUMsTUFBTTtTQUN0QixDQUFDO1FBRUYsTUFBTSxHQUFHLEdBQUcsSUFBSSx3QkFBVSxDQUFDO1lBQ3pCLE1BQU07WUFDTixlQUFlO1lBQ2YsZ0JBQWdCO1lBQ2hCLFdBQVcsRUFBRSxjQUFjO1lBQzNCLE9BQU8sRUFBRSxJQUFJLENBQUMsS0FBSyxJQUFJLElBQUksQ0FBQyxPQUFPLEdBQUcsQ0FBQztZQUN2QyxZQUFZLEVBQUUsSUFBSSxDQUFDLGVBQWUsQ0FBQztZQUNuQyxNQUFNLEVBQUUsSUFBSSxDQUFDLE1BQU07WUFDbkIsYUFBYTtZQUNiLFdBQVc7U0FDWixDQUFDLENBQUM7UUFFSCxRQUFRLE9BQU8sRUFBRSxDQUFDO1lBQ2hCLEtBQUssU0FBUztnQkFDWixNQUFNLENBQUMsYUFBYSxHQUFHLFNBQVMsQ0FBQztnQkFDakMsT0FBTyxJQUFBLHdCQUFPLEVBQUM7b0JBQ2IsUUFBUTtvQkFDUixPQUFPLEVBQUUsYUFBYSxDQUFDLE9BQU87b0JBQzlCLEtBQUssRUFBRSxJQUFJLENBQUMsS0FBSztvQkFDakIsSUFBSSxFQUFFLElBQUksQ0FBQyxJQUFJO29CQUNmLEtBQUssRUFBRSxJQUFJLENBQUMsS0FBSztvQkFDakIsS0FBSyxFQUFFLElBQUksQ0FBQyxLQUFLO2lCQUNsQixDQUFDLENBQUM7WUFFTCxLQUFLLE1BQU0sQ0FBQztZQUNaLEtBQUssS0FBSztnQkFDUixNQUFNLENBQUMsYUFBYSxHQUFHLE1BQU0sQ0FBQztnQkFDOUIsT0FBTyxJQUFBLFdBQUksRUFBQztvQkFDVixRQUFRO29CQUNSLE9BQU8sRUFBRSxhQUFhLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDO2lCQUNqRCxDQUFDLENBQUM7WUFFTCxLQUFLLFFBQVE7Z0JBQ1gsTUFBTSxDQUFDLGFBQWEsR0FBRyxRQUFRLENBQUM7Z0JBQ2hDLE9BQU8sSUFBQSxlQUFNLEVBQUM7b0JBQ1osUUFBUTtpQkFDVCxDQUFDLENBQUM7WUFFTCxLQUFLLElBQUksQ0FBQztZQUNWLEtBQUssTUFBTTtnQkFDVCxNQUFNLENBQUMsYUFBYSxHQUFHLE1BQU0sQ0FBQztnQkFDOUIsT0FBTyxHQUFHLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUU7b0JBQzNCLElBQUksRUFBRSxJQUFJLENBQUMsSUFBSTtvQkFDZixJQUFJLEVBQUUsSUFBSSxDQUFDLElBQUk7b0JBQ2YsUUFBUSxFQUFFLElBQUksQ0FBQyxnQkFBZ0I7aUJBQ2hDLENBQUMsQ0FBQztZQUVMLEtBQUssTUFBTTtnQkFDVCxNQUFNLENBQUMsYUFBYSxHQUFHLE1BQU0sQ0FBQztnQkFDOUIsTUFBTSxnQkFBZ0IsR0FBRyxnQkFBZ0IsQ0FBQyxhQUFhLEVBQUUsS0FBSyxDQUFDLDJCQUEyQixDQUFDLENBQUM7Z0JBQzVGLE9BQU8sR0FBRyxDQUFDLElBQUksQ0FBQztvQkFDZCxVQUFVLEVBQUUsSUFBSSxDQUFDLE1BQU07b0JBQ3ZCLFdBQVcsRUFBRSxJQUFJLENBQUMsV0FBVztvQkFDN0IsWUFBWSxFQUFFLElBQUksQ0FBQyxRQUFRO29CQUMzQixNQUFNLEVBQUUsSUFBSSxDQUFDLE1BQU07b0JBQ25CLFlBQVksRUFBRSxJQUFJLENBQUMsWUFBWTtvQkFDL0IsWUFBWSxFQUFFLElBQUksQ0FBQyxZQUFZO29CQUMvQixJQUFJLEVBQUUsSUFBSSxDQUFDLElBQUksSUFBSSxJQUFJLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsZ0JBQWdCO29CQUN2RCwrQkFBK0IsRUFBRSxJQUFJLENBQUMsU0FBUztvQkFDL0MsS0FBSyxFQUFFLElBQUksQ0FBQyxLQUFLO29CQUNqQixTQUFTLEVBQUUsSUFBSSxDQUFDLFlBQVksQ0FBQztvQkFDN0IsZ0JBQWdCLEVBQUUsZ0JBQWdCO29CQUNsQyx1QkFBdUIsRUFBRSxJQUFJLENBQUMsdUJBQXVCO29CQUNyRCxZQUFZLEVBQUUsSUFBSSxDQUFDLGVBQWUsQ0FBQztpQkFDcEMsQ0FBQyxDQUFDO1lBRUwsS0FBSyxPQUFPO2dCQUNWLE1BQU0sQ0FBQyxhQUFhLEdBQUcsT0FBTyxDQUFDO2dCQUMvQixPQUFPLEdBQUcsQ0FBQyxLQUFLLENBQUM7b0JBQ2YsUUFBUTtvQkFDUixJQUFJLEVBQUUsSUFBSSxDQUFDLElBQUk7aUJBQ2hCLENBQUMsQ0FBQztZQUVMLEtBQUssVUFBVTtnQkFDYixJQUFJLENBQUMsYUFBYSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxVQUFVLENBQUMsRUFBRSxDQUFDO29CQUNuRSxNQUFNLElBQUksMEJBQVksQ0FBQyxtSUFBbUksQ0FBQyxDQUFDO2dCQUM5SixDQUFDO2dCQUVELE1BQU0sQ0FBQyxhQUFhLEdBQUcsVUFBVSxDQUFDO2dCQUNsQyxPQUFPLEdBQUcsQ0FBQyxRQUFRLENBQUM7b0JBQ2xCLE1BQU0sRUFBRSxJQUFJLENBQUMsTUFBTTtvQkFDbkIsWUFBWSxFQUFFLElBQUksQ0FBQyxZQUFZO29CQUMvQixNQUFNLEVBQUUsSUFBSSxDQUFDLE1BQU07b0JBQ25CLE1BQU0sRUFBRSxRQUFRO29CQUNoQixvQkFBb0IsRUFBRSxjQUFjLENBQUMsSUFBSSxDQUFDLG1CQUFtQixJQUFJLEVBQUUsQ0FBQztvQkFDcEUsS0FBSyxFQUFFLElBQUksQ0FBQyxLQUFLLElBQUksS0FBSztvQkFDMUIsT0FBTyxFQUFFLElBQUksQ0FBQyxPQUFPO2lCQUN0QixDQUFDLENBQUM7WUFFTCxLQUFLLFdBQVc7Z0JBQ2QsTUFBTSxDQUFDLGFBQWEsR0FBRyxXQUFXLENBQUM7Z0JBQ25DLE1BQU0sTUFBTSxHQUFvQixNQUFNLHlCQUF5QixDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsQ0FBQztnQkFFOUUsSUFBSSxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7b0JBQ3RCLE1BQU0sWUFBWSxHQUFHLElBQUksd0JBQVksQ0FBQyxNQUFNLEVBQUUsSUFBQSx3QkFBVSxFQUFDLE1BQU0sRUFBRSxNQUFNLENBQUMsYUFBYSxDQUFDLENBQUMsQ0FBQztvQkFDeEYsT0FBTyxZQUFZLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztnQkFDOUMsQ0FBQztnQkFFRCxPQUFPLEdBQUcsQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLFlBQVksRUFBRTtvQkFDdEMsTUFBTTtvQkFDTixPQUFPLEVBQUUsSUFBSSxDQUFDLE9BQU87b0JBQ3JCLGVBQWUsRUFBRSxJQUFJLENBQUMsS0FBSztvQkFDM0IsZ0JBQWdCLEVBQUUsZ0JBQWdCO29CQUNsQyxPQUFPLEVBQUUsSUFBSSxDQUFDLE9BQU87b0JBQ3JCLElBQUksRUFBRSxhQUFhLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDO29CQUMxQyxxQkFBcUIsRUFBRSxJQUFJLENBQUMscUJBQXFCO29CQUNqRCxxQkFBcUIsRUFBRSxJQUFJLENBQUMscUJBQXFCLENBQUM7b0JBQ2xELFVBQVUsRUFBRTt3QkFDVixVQUFVLEVBQUUsYUFBYSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQyxlQUFlLEVBQUUsWUFBWSxDQUFDLENBQUM7d0JBQ3ZFLFFBQVEsRUFBRSxhQUFhLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxDQUFDLGVBQWUsRUFBRSxVQUFVLENBQUMsQ0FBQzt3QkFDbkUsdUJBQXVCLEVBQUUsSUFBSSxDQUFDLG9CQUFvQjt3QkFDbEQsU0FBUyxFQUFFLElBQUksQ0FBQyxTQUFTLElBQUksYUFBYSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsa0NBQWtDLENBQUM7d0JBQzFGLDhCQUE4QixFQUFFLElBQUksQ0FBQyw4QkFBOEI7d0JBQ25FLDBCQUEwQixFQUFFLElBQUksQ0FBQywwQkFBMEI7d0JBQzNELHlCQUF5QixFQUFFLElBQUksQ0FBQyx5QkFBeUI7d0JBQ3pELGVBQWUsRUFBRSxjQUFjLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQzt3QkFDM0Msd0JBQXdCLEVBQUUsY0FBYyxDQUFDLElBQUksQ0FBQyxjQUFjLENBQUM7d0JBQzdELGlCQUFpQixFQUFFLGNBQWMsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDO3dCQUMvQywrQkFBK0IsRUFBRSxjQUFjLENBQUMsSUFBSSxDQUFDLCtCQUErQixDQUFDO3dCQUNyRixjQUFjLEVBQUUsSUFBSSxDQUFDLGNBQWM7cUJBQ3BDO2lCQUNGLENBQUMsQ0FBQztZQUVMLEtBQUssUUFBUTtnQkFDWCxNQUFNLENBQUMsYUFBYSxHQUFHLFFBQVEsQ0FBQztnQkFDaEMsTUFBTSxZQUFZLEdBQTJDLEVBQUUsQ0FBQztnQkFDaEUsS0FBSyxNQUFNLFNBQVMsSUFBSSxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7b0JBQ3hDLElBQUksT0FBTyxTQUFTLEtBQUssUUFBUSxFQUFFLENBQUM7d0JBQ2xDLE1BQU0sUUFBUSxHQUFJLFNBQW9CLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDO3dCQUNsRCxZQUFZLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7b0JBQzFELENBQUM7Z0JBQ0gsQ0FBQztnQkFFRCxJQUFJLElBQUksQ0FBQyxPQUFPLEtBQUssU0FBUyxJQUFJLElBQUksQ0FBQyxNQUFNLEtBQUssU0FBUyxFQUFFLENBQUM7b0JBQzVELE1BQU0sSUFBSSwwQkFBWSxDQUFDLGtFQUFrRSxDQUFDLENBQUM7Z0JBQzdGLENBQUM7Z0JBRUQsT0FBTyxHQUFHLENBQUMsTUFBTSxDQUFDO29CQUNoQixRQUFRO29CQUNSLFdBQVcsRUFBRSxJQUFJLENBQUMsV0FBVztvQkFDN0IsZ0JBQWdCO29CQUNoQixPQUFPLEVBQUUsSUFBSSxDQUFDLE9BQU87b0JBQ3JCLGdCQUFnQixFQUFFLElBQUksQ0FBQyxnQkFBZ0I7b0JBQ3ZDLGVBQWUsRUFBRSxhQUFhLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxDQUFDLGlCQUFpQixDQUFDLENBQUM7b0JBQ2hFLFdBQVcsRUFBRSxJQUFJLENBQUMsZUFBZSxDQUFDO29CQUNsQyxJQUFJLEVBQUUsYUFBYSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQztvQkFDMUMsZ0JBQWdCLEVBQUUseUJBQXlCLENBQUMsSUFBSSxFQUFFLGFBQWEsQ0FBQztvQkFDaEUsS0FBSyxFQUFFLElBQUksQ0FBQyxLQUFLO29CQUNqQixVQUFVLEVBQUUsWUFBWTtvQkFDeEIscUJBQXFCLEVBQUUsSUFBSSxDQUFDLHFCQUFxQixDQUFDO29CQUNsRCxXQUFXLEVBQUUsYUFBYSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQyxhQUFhLENBQUMsQ0FBQztvQkFDeEQsUUFBUSxFQUFFLGFBQWEsQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLENBQUMsVUFBVSxDQUFDLENBQUM7b0JBQ2xELEVBQUUsRUFBRSxJQUFJLENBQUMsRUFBRTtvQkFDWCxRQUFRLEVBQUUsYUFBYSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQyxVQUFVLENBQUMsQ0FBQztvQkFDbEQsS0FBSyxFQUFFLElBQUksQ0FBQyxLQUFLO29CQUNqQixTQUFTLEVBQUUsSUFBSSxDQUFDLElBQUk7b0JBQ3BCLFdBQVcsRUFBRSxJQUFJLENBQUMsV0FBVztvQkFDN0IsZ0JBQWdCLEVBQUUsYUFBYSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO29CQUNsRSxjQUFjLEVBQUUsYUFBYSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQyxlQUFlLENBQUMsQ0FBQzt3QkFDM0QsQ0FBQyxDQUFDLDRCQUFjLENBQUMsaUJBQWlCO3dCQUNsQyxDQUFDLENBQUMsNEJBQWMsQ0FBQyxZQUFZO29CQUMvQixjQUFjLEVBQUUsSUFBSSxDQUFDLGNBQWM7aUJBQ3BDLENBQUMsQ0FBQztZQUVMLEtBQUssVUFBVTtnQkFDYixNQUFNLENBQUMsYUFBYSxHQUFHLFVBQVUsQ0FBQztnQkFDbEMsT0FBTyxHQUFHLENBQUMsUUFBUSxDQUFDO29CQUNsQixRQUFRO29CQUNSLGdCQUFnQjtvQkFDaEIsT0FBTyxFQUFFLElBQUksQ0FBQyxPQUFPO29CQUNyQixLQUFLLEVBQUUsSUFBSSxDQUFDLEtBQUs7b0JBQ2pCLDZCQUE2QixFQUFFLElBQUksQ0FBQyw0QkFBNEIsQ0FBQztvQkFDakUsZ0JBQWdCLEVBQUUsSUFBSSxDQUFDLE1BQU07aUJBQzlCLENBQUMsQ0FBQztZQUVMLEtBQUssUUFBUTtnQkFDWCxNQUFNLENBQUMsYUFBYSxHQUFHLFFBQVEsQ0FBQztnQkFDaEMsT0FBTyxHQUFHLENBQUMsTUFBTSxDQUFDO29CQUNoQixRQUFRO29CQUNSLGdCQUFnQjtvQkFDaEIsT0FBTyxFQUFFLElBQUksQ0FBQyxPQUFPO29CQUNyQixnQkFBZ0IsRUFBRTt3QkFDaEIsTUFBTSxFQUFFLFlBQVk7d0JBQ3BCLE9BQU8sRUFBRSxJQUFJLENBQUMsT0FBTzt3QkFDckIsYUFBYSxFQUFFLElBQUksQ0FBQyxhQUFhO3FCQUNsQztvQkFDRCxRQUFRLEVBQUUsYUFBYSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQyxVQUFVLENBQUMsQ0FBQztvQkFDbEQsUUFBUSxFQUFFLGFBQWEsQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLENBQUMsVUFBVSxDQUFDLENBQUM7b0JBQ2xELHFCQUFxQixFQUFFLElBQUksQ0FBQyx5QkFBeUIsQ0FBQztvQkFDdEQsbUJBQW1CLEVBQUUsSUFBSSxDQUFDLGtCQUFrQixDQUFDO29CQUM3QyxLQUFLLEVBQUUsSUFBSSxDQUFDLEtBQUs7aUJBQ2xCLENBQUMsQ0FBQztZQUVMLEtBQUssT0FBTztnQkFDVixNQUFNLENBQUMsYUFBYSxHQUFHLE9BQU8sQ0FBQztnQkFDL0IsTUFBTSxHQUFHLENBQUMsS0FBSyxDQUFDO29CQUNkLFFBQVE7b0JBQ1IsV0FBVyxFQUFFLElBQUksQ0FBQyxXQUFXO29CQUM3QixnQkFBZ0I7b0JBQ2hCLE9BQU8sRUFBRSxJQUFJLENBQUMsT0FBTztvQkFDckIsV0FBVyxFQUFFLElBQUksQ0FBQyxlQUFlLENBQUM7b0JBQ2xDLGdCQUFnQixFQUFFLHlCQUF5QixDQUFDLElBQUksRUFBRSxhQUFhLEVBQUUsSUFBSSxDQUFDO29CQUN0RSxLQUFLLEVBQUUsSUFBSSxDQUFDLEtBQUs7b0JBQ2pCLFFBQVEsRUFBRSxhQUFhLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxDQUFDO29CQUNsRCxRQUFRLEVBQUUsYUFBYSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQyxVQUFVLENBQUMsQ0FBQztvQkFDbEQsU0FBUyxFQUFFLElBQUksQ0FBQyxJQUFJO29CQUNwQixXQUFXLEVBQUUsSUFBSSxDQUFDLFdBQVc7aUJBQzlCLENBQUMsQ0FBQztnQkFDSCxPQUFPO1lBRVQsS0FBSyxTQUFTO2dCQUNaLE1BQU0sQ0FBQyxhQUFhLEdBQUcsU0FBUyxDQUFDO2dCQUNqQyxPQUFPLEdBQUcsQ0FBQyxPQUFPLENBQUM7b0JBQ2pCLFFBQVE7b0JBQ1IsV0FBVyxFQUFFLElBQUksQ0FBQyxXQUFXO29CQUM3QixLQUFLLEVBQUUsSUFBSSxDQUFDLEtBQUs7b0JBQ2pCLE9BQU8sRUFBRSxJQUFJLENBQUMsT0FBTztpQkFDdEIsQ0FBQyxDQUFDO1lBRUwsS0FBSyxJQUFJO2dCQUNQLE1BQU0sQ0FBQyxhQUFhLEdBQUcsSUFBSSxDQUFDO2dCQUM1QixJQUFJLENBQUMsYUFBYSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDO29CQUM3RCxNQUFNLElBQUksMEJBQVksQ0FBQyxpSEFBaUgsQ0FBQyxDQUFDO2dCQUM1SSxDQUFDO2dCQUNELElBQUksSUFBSSxDQUFDLGtCQUFrQixFQUFFLENBQUM7b0JBQzVCLE1BQU0sTUFBTSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsbUdBQW1HLENBQUMsQ0FBQztnQkFDbEksQ0FBQztnQkFDRCx3REFBd0Q7Z0JBQ3hELGdGQUFnRjtnQkFDaEYsSUFBSSxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7b0JBQ2pCLE1BQU0sTUFBTSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsZ0ZBQWdGLENBQUMsQ0FBQztnQkFDL0csQ0FBQztnQkFDRCxPQUFPLEdBQUcsQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLFlBQVksRUFBRTtvQkFDM0MsTUFBTSxFQUFFLElBQUksQ0FBQyxNQUFNO29CQUNuQixJQUFJLEVBQUUsSUFBSSxDQUFDLElBQUk7b0JBQ2Ysa0JBQWtCLEVBQUUsSUFBSSxDQUFDLHNCQUFzQixDQUFDO29CQUNoRCxpQkFBaUIsRUFBRSxJQUFJLENBQUMscUJBQXFCLENBQUM7b0JBQzlDLGtCQUFrQixFQUFFLElBQUksQ0FBQyxnQkFBZ0IsSUFBSSxJQUFJLENBQUMsa0JBQWtCO29CQUNwRSxPQUFPLEVBQUUsSUFBSSxDQUFDLE9BQU87aUJBQ3RCLENBQUMsQ0FBQztZQUVMLEtBQUssT0FBTztnQkFDVixNQUFNLENBQUMsYUFBYSxHQUFHLE9BQU8sQ0FBQztnQkFFL0IsSUFBSSxDQUFDLGFBQWEsQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQztvQkFDaEUsTUFBTSxJQUFJLDBCQUFZLENBQUMsMEhBQTBILENBQUMsQ0FBQztnQkFDckosQ0FBQztnQkFDRCxNQUFNLE9BQU8sR0FBRyxJQUFJLHFCQUFPLENBQUM7b0JBQzFCLE1BQU07b0JBQ04sZ0JBQWdCO29CQUNoQixnQkFBZ0IsRUFBRSxhQUFhLENBQUMs