aws-cdk
Version:
CDK Toolkit, the command line tool for CDK apps
794 lines • 94.7 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const setup = require("./hotswap-test-setup");
const common_1 = require("../../../lib/api/hotswap/common");
const s3_bucket_deployments_1 = require("../../../lib/api/hotswap/s3-bucket-deployments");
let mockLambdaInvoke;
let hotswapMockSdkProvider;
const payloadWithoutCustomResProps = {
RequestType: 'Update',
ResponseURL: s3_bucket_deployments_1.REQUIRED_BY_CFN,
PhysicalResourceId: s3_bucket_deployments_1.REQUIRED_BY_CFN,
StackId: s3_bucket_deployments_1.REQUIRED_BY_CFN,
RequestId: s3_bucket_deployments_1.REQUIRED_BY_CFN,
LogicalResourceId: s3_bucket_deployments_1.REQUIRED_BY_CFN,
};
beforeEach(() => {
hotswapMockSdkProvider = setup.setupHotswapTests();
mockLambdaInvoke = jest.fn();
hotswapMockSdkProvider.setInvokeLambdaMock(mockLambdaInvoke);
});
describe.each([common_1.HotswapMode.FALL_BACK, common_1.HotswapMode.HOTSWAP_ONLY])('%p mode', (hotswapMode) => {
test('calls the lambdaInvoke() API when it receives only an asset difference in an S3 bucket deployment and evaluates CFN expressions in S3 Deployment Properties', async () => {
// GIVEN
setup.setCurrentCfnStackTemplate({
Resources: {
S3Deployment: {
Type: 'Custom::CDKBucketDeployment',
Properties: {
ServiceToken: 'a-lambda-arn',
SourceBucketNames: ['src-bucket'],
SourceObjectKeys: ['src-key-old'],
DestinationBucketName: 'dest-bucket',
DestinationBucketKeyPrefix: 'my-key/some-old-prefix',
},
},
},
});
const cdkStackArtifact = setup.cdkStackArtifactOf({
template: {
Resources: {
S3Deployment: {
Type: 'Custom::CDKBucketDeployment',
Properties: {
ServiceToken: 'a-lambda-arn',
SourceBucketNames: ['src-bucket'],
SourceObjectKeys: {
'Fn::Split': [
'-',
'key1-key2-key3',
],
},
DestinationBucketName: 'dest-bucket',
DestinationBucketKeyPrefix: 'my-key/some-new-prefix',
},
},
},
},
});
// WHEN
const deployStackResult = await hotswapMockSdkProvider.tryHotswapDeployment(hotswapMode, cdkStackArtifact);
// THEN
expect(deployStackResult).not.toBeUndefined();
expect(mockLambdaInvoke).toHaveBeenCalledWith({
FunctionName: 'a-lambda-arn',
Payload: JSON.stringify({
...payloadWithoutCustomResProps,
ResourceProperties: {
SourceBucketNames: ['src-bucket'],
SourceObjectKeys: ['key1', 'key2', 'key3'],
DestinationBucketName: 'dest-bucket',
DestinationBucketKeyPrefix: 'my-key/some-new-prefix',
},
}),
});
});
test('does not call the invoke() API when a resource with type that is not Custom::CDKBucketDeployment but has the same properties is changed', async () => {
// GIVEN
setup.setCurrentCfnStackTemplate({
Resources: {
S3Deployment: {
Type: 'Custom::NotCDKBucketDeployment',
Properties: {
SourceObjectKeys: ['src-key-old'],
},
},
},
});
const cdkStackArtifact = setup.cdkStackArtifactOf({
template: {
Resources: {
S3Deployment: {
Type: 'Custom::NotCDKBucketDeployment',
Properties: {
SourceObjectKeys: ['src-key-new'],
},
},
},
},
});
if (hotswapMode === common_1.HotswapMode.FALL_BACK) {
// WHEN
const deployStackResult = await hotswapMockSdkProvider.tryHotswapDeployment(hotswapMode, cdkStackArtifact);
// THEN
expect(deployStackResult).toBeUndefined();
expect(mockLambdaInvoke).not.toHaveBeenCalled();
}
else if (hotswapMode === common_1.HotswapMode.HOTSWAP_ONLY) {
// WHEN
const deployStackResult = await hotswapMockSdkProvider.tryHotswapDeployment(hotswapMode, cdkStackArtifact);
// THEN
expect(deployStackResult).not.toBeUndefined();
expect(deployStackResult?.noOp).toEqual(true);
expect(mockLambdaInvoke).not.toHaveBeenCalled();
}
});
test('does not call the invokeLambda() api if the updated Policy has no Roles in CLASSIC mode but does in HOTSWAP_ONLY mode', async () => {
// GIVEN
setup.setCurrentCfnStackTemplate({
Parameters: {
WebsiteBucketParamOld: { Type: 'String' },
WebsiteBucketParamNew: { Type: 'String' },
},
Resources: {
S3Deployment: {
Type: 'Custom::CDKBucketDeployment',
Properties: {
ServiceToken: 'a-lambda-arn',
SourceObjectKeys: ['src-key-old'],
SourceBucketNames: ['src-bucket'],
DestinationBucketName: 'dest-bucket',
},
},
Policy: {
Type: 'AWS::IAM::Policy',
Properties: {
PolicyName: 'my-policy',
PolicyDocument: {
Statement: [
{
Action: ['s3:GetObject*'],
Effect: 'Allow',
Resource: {
Ref: 'WebsiteBucketParamOld',
},
},
],
},
},
},
},
});
const cdkStackArtifact = setup.cdkStackArtifactOf({
template: {
Parameters: {
WebsiteBucketParamOld: { Type: 'String' },
WebsiteBucketParamNew: { Type: 'String' },
},
Resources: {
S3Deployment: {
Type: 'Custom::CDKBucketDeployment',
Properties: {
ServiceToken: 'a-lambda-arn',
SourceObjectKeys: ['src-key-new'],
SourceBucketNames: ['src-bucket'],
DestinationBucketName: 'dest-bucket',
},
},
Policy: {
Type: 'AWS::IAM::Policy',
Properties: {
PolicyName: 'my-policy',
PolicyDocument: {
Statement: [
{
Action: ['s3:GetObject*'],
Effect: 'Allow',
Resource: {
Ref: 'WebsiteBucketParamNew',
},
},
],
},
},
},
},
},
});
if (hotswapMode === common_1.HotswapMode.FALL_BACK) {
// WHEN
const deployStackResult = await hotswapMockSdkProvider.tryHotswapDeployment(hotswapMode, cdkStackArtifact);
// THEN
expect(deployStackResult).toBeUndefined();
expect(mockLambdaInvoke).not.toHaveBeenCalled();
}
else if (hotswapMode === common_1.HotswapMode.HOTSWAP_ONLY) {
// WHEN
const deployStackResult = await hotswapMockSdkProvider.tryHotswapDeployment(hotswapMode, cdkStackArtifact);
// THEN
expect(deployStackResult).not.toBeUndefined();
expect(mockLambdaInvoke).toHaveBeenCalledWith({
FunctionName: 'a-lambda-arn',
Payload: JSON.stringify({
...payloadWithoutCustomResProps,
ResourceProperties: {
SourceObjectKeys: ['src-key-new'],
SourceBucketNames: ['src-bucket'],
DestinationBucketName: 'dest-bucket',
},
}),
});
}
});
test('throws an error when the serviceToken fails evaluation in the template', async () => {
// GIVEN
setup.setCurrentCfnStackTemplate({
Resources: {
S3Deployment: {
Type: 'Custom::CDKBucketDeployment',
Properties: {
ServiceToken: {
Ref: 'BadLamba',
},
SourceBucketNames: ['src-bucket'],
SourceObjectKeys: ['src-key-old'],
DestinationBucketName: 'dest-bucket',
},
},
},
});
const cdkStackArtifact = setup.cdkStackArtifactOf({
template: {
Resources: {
S3Deployment: {
Type: 'Custom::CDKBucketDeployment',
Properties: {
ServiceToken: {
Ref: 'BadLamba',
},
SourceBucketNames: ['src-bucket'],
SourceObjectKeys: ['src-key-new'],
DestinationBucketName: 'dest-bucket',
},
},
},
},
});
// WHEN
await expect(() => hotswapMockSdkProvider.tryHotswapDeployment(hotswapMode, cdkStackArtifact)).rejects.toThrow(/Parameter or resource 'BadLamba' could not be found for evaluation/);
expect(mockLambdaInvoke).not.toHaveBeenCalled();
});
describe('old-style synthesis', () => {
const parameters = {
WebsiteBucketParamOld: { Type: 'String' },
WebsiteBucketParamNew: { Type: 'String' },
DifferentBucketParamNew: { Type: 'String' },
};
const serviceRole = {
Type: 'AWS::IAM::Role',
Properties: {
AssumeRolePolicyDocument: {
Statement: [
{
Action: 'sts:AssumeRole',
Effect: 'Allow',
Principal: {
Service: 'lambda.amazonaws.com',
},
},
],
Version: '2012-10-17',
},
},
};
const policyOld = {
Type: 'AWS::IAM::Policy',
Properties: {
PolicyName: 'my-policy-old',
Roles: [
{ Ref: 'ServiceRole' },
],
PolicyDocument: {
Statement: [
{
Action: ['s3:GetObject*'],
Effect: 'Allow',
Resource: {
Ref: 'WebsiteBucketParamOld',
},
},
],
},
},
};
const policyNew = {
Type: 'AWS::IAM::Policy',
Properties: {
PolicyName: 'my-policy-new',
Roles: [
{ Ref: 'ServiceRole' },
],
PolicyDocument: {
Statement: [
{
Action: ['s3:GetObject*'],
Effect: 'Allow',
Resource: {
Ref: 'WebsiteBucketParamNew',
},
},
],
},
},
};
const policy2Old = {
Type: 'AWS::IAM::Policy',
Properties: {
PolicyName: 'my-policy-old-2',
Roles: [
{ Ref: 'ServiceRole' },
],
PolicyDocument: {
Statement: [
{
Action: ['s3:GetObject*'],
Effect: 'Allow',
Resource: {
Ref: 'WebsiteBucketParamOld',
},
},
],
},
},
};
const policy2New = {
Type: 'AWS::IAM::Policy',
Properties: {
PolicyName: 'my-policy-new-2',
Roles: [
{ Ref: 'ServiceRole2' },
],
PolicyDocument: {
Statement: [
{
Action: ['s3:GetObject*'],
Effect: 'Allow',
Resource: {
Ref: 'DifferentBucketParamOld',
},
},
],
},
},
};
const deploymentLambda = {
Type: 'AWS::Lambda::Function',
Role: {
'Fn::GetAtt': [
'ServiceRole',
'Arn',
],
},
};
const s3DeploymentOld = {
Type: 'Custom::CDKBucketDeployment',
Properties: {
ServiceToken: {
'Fn::GetAtt': [
'S3DeploymentLambda',
'Arn',
],
},
SourceBucketNames: ['src-bucket-old'],
SourceObjectKeys: ['src-key-old'],
DestinationBucketName: 'WebsiteBucketOld',
},
};
const s3DeploymentNew = {
Type: 'Custom::CDKBucketDeployment',
Properties: {
ServiceToken: {
'Fn::GetAtt': [
'S3DeploymentLambda',
'Arn',
],
},
SourceBucketNames: ['src-bucket-new'],
SourceObjectKeys: ['src-key-new'],
DestinationBucketName: 'WebsiteBucketNew',
},
};
beforeEach(() => {
setup.pushStackResourceSummaries(setup.stackSummaryOf('S3DeploymentLambda', 'AWS::Lambda::Function', 'my-deployment-lambda'), setup.stackSummaryOf('ServiceRole', 'AWS::IAM::Role', 'my-service-role'));
});
test('calls the lambdaInvoke() API when it receives an asset difference in an S3 bucket deployment and an IAM Policy difference using old-style synthesis', async () => {
// GIVEN
setup.setCurrentCfnStackTemplate({
Resources: {
Parameters: parameters,
ServiceRole: serviceRole,
Policy: policyOld,
S3DeploymentLambda: deploymentLambda,
S3Deployment: s3DeploymentOld,
},
});
const cdkStackArtifact = setup.cdkStackArtifactOf({
template: {
Resources: {
Parameters: parameters,
ServiceRole: serviceRole,
Policy: policyNew,
S3DeploymentLambda: deploymentLambda,
S3Deployment: s3DeploymentNew,
},
},
});
// WHEN
const deployStackResult = await hotswapMockSdkProvider.tryHotswapDeployment(hotswapMode, cdkStackArtifact, { WebsiteBucketParamOld: 'WebsiteBucketOld', WebsiteBucketParamNew: 'WebsiteBucketNew' });
// THEN
expect(deployStackResult).not.toBeUndefined();
expect(mockLambdaInvoke).toHaveBeenCalledWith({
FunctionName: 'arn:aws:lambda:here:123456789012:function:my-deployment-lambda',
Payload: JSON.stringify({
...payloadWithoutCustomResProps,
ResourceProperties: {
SourceBucketNames: ['src-bucket-new'],
SourceObjectKeys: ['src-key-new'],
DestinationBucketName: 'WebsiteBucketNew',
},
}),
});
});
test(`does not call the lambdaInvoke() API when the difference in the S3 deployment is referred to in one IAM policy change but not another
in CLASSIC mode but does in HOTSWAP_ONLY`, async () => {
// GIVEN
setup.setCurrentCfnStackTemplate({
Resources: {
ServiceRole: serviceRole,
Policy1: policyOld,
Policy2: policy2Old,
S3DeploymentLambda: deploymentLambda,
S3Deployment: s3DeploymentOld,
},
});
const cdkStackArtifact = setup.cdkStackArtifactOf({
template: {
Resources: {
ServiceRole: serviceRole,
Policy1: policyNew,
Policy2: {
Properties: {
Roles: [
{ Ref: 'ServiceRole' },
'different-role',
],
PolicyDocument: {
Statement: [
{
Action: ['s3:GetObject*'],
Effect: 'Allow',
Resource: {
'Fn::GetAtt': [
'DifferentBucketNew',
'Arn',
],
},
},
],
},
},
},
S3DeploymentLambda: deploymentLambda,
S3Deployment: s3DeploymentNew,
},
},
});
if (hotswapMode === common_1.HotswapMode.FALL_BACK) {
// WHEN
const deployStackResult = await hotswapMockSdkProvider.tryHotswapDeployment(hotswapMode, cdkStackArtifact);
// THEN
expect(deployStackResult).toBeUndefined();
expect(mockLambdaInvoke).not.toHaveBeenCalled();
}
else if (hotswapMode === common_1.HotswapMode.HOTSWAP_ONLY) {
// WHEN
const deployStackResult = await hotswapMockSdkProvider.tryHotswapDeployment(hotswapMode, cdkStackArtifact);
// THEN
expect(deployStackResult).not.toBeUndefined();
expect(mockLambdaInvoke).toHaveBeenCalledWith({
FunctionName: 'arn:aws:lambda:here:123456789012:function:my-deployment-lambda',
Payload: JSON.stringify({
...payloadWithoutCustomResProps,
ResourceProperties: {
SourceBucketNames: ['src-bucket-new'],
SourceObjectKeys: ['src-key-new'],
DestinationBucketName: 'WebsiteBucketNew',
},
}),
});
}
});
test(`does not call the lambdaInvoke() API when the lambda that references the role is referred to by something other than an S3 deployment
in CLASSIC mode but does in HOTSWAP_ONLY mode`, async () => {
// GIVEN
setup.setCurrentCfnStackTemplate({
Resources: {
ServiceRole: serviceRole,
Policy: policyOld,
S3DeploymentLambda: deploymentLambda,
S3Deployment: s3DeploymentOld,
Endpoint: {
Type: 'AWS::Lambda::Permission',
Properties: {
Action: 'lambda:InvokeFunction',
FunctionName: {
'Fn::GetAtt': [
'S3DeploymentLambda',
'Arn',
],
},
Principal: 'apigateway.amazonaws.com',
},
},
},
});
const cdkStackArtifact = setup.cdkStackArtifactOf({
template: {
Resources: {
ServiceRole: serviceRole,
Policy: policyNew,
S3DeploymentLambda: deploymentLambda,
S3Deployment: s3DeploymentNew,
Endpoint: {
Type: 'AWS::Lambda::Permission',
Properties: {
Action: 'lambda:InvokeFunction',
FunctionName: {
'Fn::GetAtt': [
'S3DeploymentLambda',
'Arn',
],
},
Principal: 'apigateway.amazonaws.com',
},
},
},
},
});
if (hotswapMode === common_1.HotswapMode.FALL_BACK) {
// WHEN
const deployStackResult = await hotswapMockSdkProvider.tryHotswapDeployment(hotswapMode, cdkStackArtifact);
// THEN
expect(deployStackResult).toBeUndefined();
expect(mockLambdaInvoke).not.toHaveBeenCalled();
}
else if (hotswapMode === common_1.HotswapMode.HOTSWAP_ONLY) {
// WHEN
const deployStackResult = await hotswapMockSdkProvider.tryHotswapDeployment(hotswapMode, cdkStackArtifact);
// THEN
expect(deployStackResult).not.toBeUndefined();
expect(mockLambdaInvoke).toHaveBeenCalledWith({
FunctionName: 'arn:aws:lambda:here:123456789012:function:my-deployment-lambda',
Payload: JSON.stringify({
...payloadWithoutCustomResProps,
ResourceProperties: {
SourceBucketNames: ['src-bucket-new'],
SourceObjectKeys: ['src-key-new'],
DestinationBucketName: 'WebsiteBucketNew',
},
}),
});
}
});
test('calls the lambdaInvoke() API when it receives an asset difference in two S3 bucket deployments and IAM Policy differences using old-style synthesis', async () => {
// GIVEN
const s3Deployment2Old = {
Type: 'Custom::CDKBucketDeployment',
Properties: {
ServiceToken: {
'Fn::GetAtt': [
'S3DeploymentLambda2',
'Arn',
],
},
SourceBucketNames: ['src-bucket-old'],
SourceObjectKeys: ['src-key-old'],
DestinationBucketName: 'DifferentBucketOld',
},
};
const s3Deployment2New = {
Type: 'Custom::CDKBucketDeployment',
Properties: {
ServiceToken: {
'Fn::GetAtt': [
'S3DeploymentLambda2',
'Arn',
],
},
SourceBucketNames: ['src-bucket-new'],
SourceObjectKeys: ['src-key-new'],
DestinationBucketName: 'DifferentBucketNew',
},
};
setup.setCurrentCfnStackTemplate({
Resources: {
ServiceRole: serviceRole,
ServiceRole2: serviceRole,
Policy1: policyOld,
Policy2: policy2Old,
S3DeploymentLambda: deploymentLambda,
S3DeploymentLambda2: deploymentLambda,
S3Deployment: s3DeploymentOld,
S3Deployment2: s3Deployment2Old,
},
});
const cdkStackArtifact = setup.cdkStackArtifactOf({
template: {
Resources: {
Parameters: parameters,
ServiceRole: serviceRole,
ServiceRole2: serviceRole,
Policy1: policyNew,
Policy2: policy2New,
S3DeploymentLambda: deploymentLambda,
S3DeploymentLambda2: deploymentLambda,
S3Deployment: s3DeploymentNew,
S3Deployment2: s3Deployment2New,
},
},
});
// WHEN
setup.pushStackResourceSummaries(setup.stackSummaryOf('S3DeploymentLambda2', 'AWS::Lambda::Function', 'my-deployment-lambda-2'), setup.stackSummaryOf('ServiceRole2', 'AWS::IAM::Role', 'my-service-role-2'));
const deployStackResult = await hotswapMockSdkProvider.tryHotswapDeployment(hotswapMode, cdkStackArtifact, {
WebsiteBucketParamOld: 'WebsiteBucketOld',
WebsiteBucketParamNew: 'WebsiteBucketNew',
DifferentBucketParamNew: 'WebsiteBucketNew',
});
// THEN
expect(deployStackResult).not.toBeUndefined();
expect(mockLambdaInvoke).toHaveBeenCalledWith({
FunctionName: 'arn:aws:lambda:here:123456789012:function:my-deployment-lambda',
Payload: JSON.stringify({
...payloadWithoutCustomResProps,
ResourceProperties: {
SourceBucketNames: ['src-bucket-new'],
SourceObjectKeys: ['src-key-new'],
DestinationBucketName: 'WebsiteBucketNew',
},
}),
});
expect(mockLambdaInvoke).toHaveBeenCalledWith({
FunctionName: 'arn:aws:lambda:here:123456789012:function:my-deployment-lambda-2',
Payload: JSON.stringify({
...payloadWithoutCustomResProps,
ResourceProperties: {
SourceBucketNames: ['src-bucket-new'],
SourceObjectKeys: ['src-key-new'],
DestinationBucketName: 'DifferentBucketNew',
},
}),
});
});
test(`does not call the lambdaInvoke() API when it receives an asset difference in an S3 bucket deployment that references two different policies
in CLASSIC mode but does in HOTSWAP_ONLY mode`, async () => {
// GIVEN
setup.setCurrentCfnStackTemplate({
Resources: {
ServiceRole: serviceRole,
Policy1: policyOld,
Policy2: policy2Old,
S3DeploymentLambda: deploymentLambda,
S3Deployment: s3DeploymentOld,
},
});
const cdkStackArtifact = setup.cdkStackArtifactOf({
template: {
Resources: {
ServiceRole: serviceRole,
Policy1: policyNew,
Policy2: {
Properties: {
Roles: [
{ Ref: 'ServiceRole' },
],
PolicyDocument: {
Statement: [
{
Action: ['s3:GetObject*'],
Effect: 'Allow',
Resource: {
'Fn::GetAtt': [
'DifferentBucketNew',
'Arn',
],
},
},
],
},
},
},
S3DeploymentLambda: deploymentLambda,
S3Deployment: s3DeploymentNew,
},
},
});
if (hotswapMode === common_1.HotswapMode.FALL_BACK) {
// WHEN
const deployStackResult = await hotswapMockSdkProvider.tryHotswapDeployment(hotswapMode, cdkStackArtifact);
// THEN
expect(deployStackResult).toBeUndefined();
expect(mockLambdaInvoke).not.toHaveBeenCalled();
}
else if (hotswapMode === common_1.HotswapMode.HOTSWAP_ONLY) {
// WHEN
const deployStackResult = await hotswapMockSdkProvider.tryHotswapDeployment(hotswapMode, cdkStackArtifact);
// THEN
expect(deployStackResult).not.toBeUndefined();
expect(mockLambdaInvoke).toHaveBeenCalledWith({
FunctionName: 'arn:aws:lambda:here:123456789012:function:my-deployment-lambda',
Payload: JSON.stringify({
...payloadWithoutCustomResProps,
ResourceProperties: {
SourceBucketNames: ['src-bucket-new'],
SourceObjectKeys: ['src-key-new'],
DestinationBucketName: 'WebsiteBucketNew',
},
}),
});
}
});
test(`does not call the lambdaInvoke() API when a policy is referenced by a resource that is not an S3 deployment
in CLASSIC mode but does in HOTSWAP_ONLY mode`, async () => {
// GIVEN
setup.setCurrentCfnStackTemplate({
Resources: {
ServiceRole: serviceRole,
Policy1: policyOld,
S3DeploymentLambda: deploymentLambda,
S3Deployment: s3DeploymentOld,
NotADeployment: {
Type: 'AWS::Not::S3Deployment',
Properties: {
Prop: {
Ref: 'ServiceRole',
},
},
},
},
});
const cdkStackArtifact = setup.cdkStackArtifactOf({
template: {
Resources: {
ServiceRole: serviceRole,
Policy1: policyNew,
S3DeploymentLambda: deploymentLambda,
S3Deployment: s3DeploymentNew,
NotADeployment: {
Type: 'AWS::Not::S3Deployment',
Properties: {
Prop: {
Ref: 'ServiceRole',
},
},
},
},
},
});
if (hotswapMode === common_1.HotswapMode.FALL_BACK) {
// WHEN
const deployStackResult = await hotswapMockSdkProvider.tryHotswapDeployment(hotswapMode, cdkStackArtifact);
// THEN
expect(deployStackResult).toBeUndefined();
expect(mockLambdaInvoke).not.toHaveBeenCalled();
}
else if (hotswapMode === common_1.HotswapMode.HOTSWAP_ONLY) {
// WHEN
const deployStackResult = await hotswapMockSdkProvider.tryHotswapDeployment(hotswapMode, cdkStackArtifact);
// THEN
expect(deployStackResult).not.toBeUndefined();
expect(mockLambdaInvoke).toHaveBeenCalledWith({
FunctionName: 'arn:aws:lambda:here:123456789012:function:my-deployment-lambda',
Payload: JSON.stringify({
...payloadWithoutCustomResProps,
ResourceProperties: {
SourceBucketNames: ['src-bucket-new'],
SourceObjectKeys: ['src-key-new'],
DestinationBucketName: 'WebsiteBucketNew',
},
}),
});
}
});
});
});
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiczMtYnVja2V0LWhvdHN3YXAtZGVwbG95bWVudHMudGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbInMzLWJ1Y2tldC1ob3Rzd2FwLWRlcGxveW1lbnRzLnRlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFFQSw4Q0FBOEM7QUFDOUMsNERBQThEO0FBQzlELDBGQUFpRjtBQUVqRixJQUFJLGdCQUE2RixDQUFDO0FBQ2xHLElBQUksc0JBQW9ELENBQUM7QUFFekQsTUFBTSw0QkFBNEIsR0FBRztJQUNuQyxXQUFXLEVBQUUsUUFBUTtJQUNyQixXQUFXLEVBQUUsdUNBQWU7SUFDNUIsa0JBQWtCLEVBQUUsdUNBQWU7SUFDbkMsT0FBTyxFQUFFLHVDQUFlO0lBQ3hCLFNBQVMsRUFBRSx1Q0FBZTtJQUMxQixpQkFBaUIsRUFBRSx1Q0FBZTtDQUNuQyxDQUFDO0FBRUYsVUFBVSxDQUFDLEdBQUcsRUFBRTtJQUNkLHNCQUFzQixHQUFHLEtBQUssQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO0lBQ25ELGdCQUFnQixHQUFHLElBQUksQ0FBQyxFQUFFLEVBQUUsQ0FBQztJQUM3QixzQkFBc0IsQ0FBQyxtQkFBbUIsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO0FBQy9ELENBQUMsQ0FBQyxDQUFDO0FBRUgsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDLG9CQUFXLENBQUMsU0FBUyxFQUFFLG9CQUFXLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxTQUFTLEVBQUUsQ0FBQyxXQUFXLEVBQUUsRUFBRTtJQUMxRixJQUFJLENBQUMsNkpBQTZKLEVBQUUsS0FBSyxJQUFJLEVBQUU7UUFDN0ssUUFBUTtRQUNSLEtBQUssQ0FBQywwQkFBMEIsQ0FBQztZQUMvQixTQUFTLEVBQUU7Z0JBQ1QsWUFBWSxFQUFFO29CQUNaLElBQUksRUFBRSw2QkFBNkI7b0JBQ25DLFVBQVUsRUFBRTt3QkFDVixZQUFZLEVBQUUsY0FBYzt3QkFDNUIsaUJBQWlCLEVBQUUsQ0FBQyxZQUFZLENBQUM7d0JBQ2pDLGdCQUFnQixFQUFFLENBQUMsYUFBYSxDQUFDO3dCQUNqQyxxQkFBcUIsRUFBRSxhQUFhO3dCQUNwQywwQkFBMEIsRUFBRSx3QkFBd0I7cUJBQ3JEO2lCQUNGO2FBQ0Y7U0FDRixDQUFDLENBQUM7UUFDSCxNQUFNLGdCQUFnQixHQUFHLEtBQUssQ0FBQyxrQkFBa0IsQ0FBQztZQUNoRCxRQUFRLEVBQUU7Z0JBQ1IsU0FBUyxFQUFFO29CQUNULFlBQVksRUFBRTt3QkFDWixJQUFJLEVBQUUsNkJBQTZCO3dCQUNuQyxVQUFVLEVBQUU7NEJBQ1YsWUFBWSxFQUFFLGNBQWM7NEJBQzVCLGlCQUFpQixFQUFFLENBQUMsWUFBWSxDQUFDOzRCQUNqQyxnQkFBZ0IsRUFBRTtnQ0FDaEIsV0FBVyxFQUFFO29DQUNYLEdBQUc7b0NBQ0gsZ0JBQWdCO2lDQUNqQjs2QkFDRjs0QkFDRCxxQkFBcUIsRUFBRSxhQUFhOzRCQUNwQywwQkFBMEIsRUFBRSx3QkFBd0I7eUJBQ3JEO3FCQUNGO2lCQUNGO2FBQ0Y7U0FDRixDQUFDLENBQUM7UUFFSCxPQUFPO1FBQ1AsTUFBTSxpQkFBaUIsR0FBRyxNQUFNLHNCQUFzQixDQUFDLG9CQUFvQixDQUFDLFdBQVcsRUFBRSxnQkFBZ0IsQ0FBQyxDQUFDO1FBRTNHLE9BQU87UUFDUCxNQUFNLENBQUMsaUJBQWlCLENBQUMsQ0FBQyxHQUFHLENBQUMsYUFBYSxFQUFFLENBQUM7UUFFOUMsTUFBTSxDQUFDLGdCQUFnQixDQUFDLENBQUMsb0JBQW9CLENBQUM7WUFDNUMsWUFBWSxFQUFFLGNBQWM7WUFDNUIsT0FBTyxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUM7Z0JBQ3RCLEdBQUcsNEJBQTRCO2dCQUMvQixrQkFBa0IsRUFBRTtvQkFDbEIsaUJBQWlCLEVBQUUsQ0FBQyxZQUFZLENBQUM7b0JBQ2pDLGdCQUFnQixFQUFFLENBQUMsTUFBTSxFQUFFLE1BQU0sRUFBRSxNQUFNLENBQUM7b0JBQzFDLHFCQUFxQixFQUFFLGFBQWE7b0JBQ3BDLDBCQUEwQixFQUFFLHdCQUF3QjtpQkFDckQ7YUFDRixDQUFDO1NBQ0gsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7SUFFSCxJQUFJLENBQUMseUlBQXlJLEVBQUUsS0FBSyxJQUFJLEVBQUU7UUFDekosUUFBUTtRQUNSLEtBQUssQ0FBQywwQkFBMEIsQ0FBQztZQUMvQixTQUFTLEVBQUU7Z0JBQ1QsWUFBWSxFQUFFO29CQUNaLElBQUksRUFBRSxnQ0FBZ0M7b0JBQ3RDLFVBQVUsRUFBRTt3QkFDVixnQkFBZ0IsRUFBRSxDQUFDLGFBQWEsQ0FBQztxQkFDbEM7aUJBQ0Y7YUFDRjtTQUNGLENBQUMsQ0FBQztRQUNILE1BQU0sZ0JBQWdCLEdBQUcsS0FBSyxDQUFDLGtCQUFrQixDQUFDO1lBQ2hELFFBQVEsRUFBRTtnQkFDUixTQUFTLEVBQUU7b0JBQ1QsWUFBWSxFQUFFO3dCQUNaLElBQUksRUFBRSxnQ0FBZ0M7d0JBQ3RDLFVBQVUsRUFBRTs0QkFDVixnQkFBZ0IsRUFBRSxDQUFDLGFBQWEsQ0FBQzt5QkFDbEM7cUJBQ0Y7aUJBQ0Y7YUFDRjtTQUNGLENBQUMsQ0FBQztRQUVILElBQUksV0FBVyxLQUFLLG9CQUFXLENBQUMsU0FBUyxFQUFFO1lBQ3pDLE9BQU87WUFDUCxNQUFNLGlCQUFpQixHQUFHLE1BQU0sc0JBQXNCLENBQUMsb0JBQW9CLENBQUMsV0FBVyxFQUFFLGdCQUFnQixDQUFDLENBQUM7WUFFM0csT0FBTztZQUNQLE1BQU0sQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDLGFBQWEsRUFBRSxDQUFDO1lBQzFDLE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDO1NBQ2pEO2FBQU0sSUFBSSxXQUFXLEtBQUssb0JBQVcsQ0FBQyxZQUFZLEVBQUU7WUFDbkQsT0FBTztZQUNQLE1BQU0saUJBQWlCLEdBQUcsTUFBTSxzQkFBc0IsQ0FBQyxvQkFBb0IsQ0FBQyxXQUFXLEVBQUUsZ0JBQWdCLENBQUMsQ0FBQztZQUUzRyxPQUFPO1lBQ1AsTUFBTSxDQUFDLGlCQUFpQixDQUFDLENBQUMsR0FBRyxDQUFDLGFBQWEsRUFBRSxDQUFDO1lBQzlDLE1BQU0sQ0FBQyxpQkFBaUIsRUFBRSxJQUFJLENBQUMsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDOUMsTUFBTSxDQUFDLGdCQUFnQixDQUFDLENBQUMsR0FBRyxDQUFDLGdCQUFnQixFQUFFLENBQUM7U0FDakQ7SUFDSCxDQUFDLENBQUMsQ0FBQztJQUVILElBQUksQ0FBQyx1SEFBdUgsRUFBRSxLQUFLLElBQUksRUFBRTtRQUN2SSxRQUFRO1FBQ1IsS0FBSyxDQUFDLDBCQUEwQixDQUFDO1lBQy9CLFVBQVUsRUFBRTtnQkFDVixxQkFBcUIsRUFBRSxFQUFFLElBQUksRUFBRSxRQUFRLEVBQUU7Z0JBQ3pDLHFCQUFxQixFQUFFLEVBQUUsSUFBSSxFQUFFLFFBQVEsRUFBRTthQUMxQztZQUNELFNBQVMsRUFBRTtnQkFDVCxZQUFZLEVBQUU7b0JBQ1osSUFBSSxFQUFFLDZCQUE2QjtvQkFDbkMsVUFBVSxFQUFFO3dCQUNWLFlBQVksRUFBRSxjQUFjO3dCQUM1QixnQkFBZ0IsRUFBRSxDQUFDLGFBQWEsQ0FBQzt3QkFDakMsaUJBQWlCLEVBQUUsQ0FBQyxZQUFZLENBQUM7d0JBQ2pDLHFCQUFxQixFQUFFLGFBQWE7cUJBQ3JDO2lCQUNGO2dCQUNELE1BQU0sRUFBRTtvQkFDTixJQUFJLEVBQUUsa0JBQWtCO29CQUN4QixVQUFVLEVBQUU7d0JBQ1YsVUFBVSxFQUFFLFdBQVc7d0JBQ3ZCLGNBQWMsRUFBRTs0QkFDZCxTQUFTLEVBQUU7Z0NBQ1Q7b0NBQ0UsTUFBTSxFQUFFLENBQUMsZUFBZSxDQUFDO29DQUN6QixNQUFNLEVBQUUsT0FBTztvQ0FDZixRQUFRLEVBQUU7d0NBQ1IsR0FBRyxFQUFFLHVCQUF1QjtxQ0FDN0I7aUNBQ0Y7NkJBQ0Y7eUJBQ0Y7cUJBQ0Y7aUJBQ0Y7YUFDRjtTQUNGLENBQUMsQ0FBQztRQUNILE1BQU0sZ0JBQWdCLEdBQUcsS0FBSyxDQUFDLGtCQUFrQixDQUFDO1lBQ2hELFFBQVEsRUFBRTtnQkFDUixVQUFVLEVBQUU7b0JBQ1YscUJBQXFCLEVBQUUsRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFO29CQUN6QyxxQkFBcUIsRUFBRSxFQUFFLElBQUksRUFBRSxRQUFRLEVBQUU7aUJBQzFDO2dCQUNELFNBQVMsRUFBRTtvQkFDVCxZQUFZLEVBQUU7d0JBQ1osSUFBSSxFQUFFLDZCQUE2Qjt3QkFDbkMsVUFBVSxFQUFFOzRCQUNWLFlBQVksRUFBRSxjQUFjOzRCQUM1QixnQkFBZ0IsRUFBRSxDQUFDLGFBQWEsQ0FBQzs0QkFDakMsaUJBQWlCLEVBQUUsQ0FBQyxZQUFZLENBQUM7NEJBQ2pDLHFCQUFxQixFQUFFLGFBQWE7eUJBQ3JDO3FCQUNGO29CQUNELE1BQU0sRUFBRTt3QkFDTixJQUFJLEVBQUUsa0JBQWtCO3dCQUN4QixVQUFVLEVBQUU7NEJBQ1YsVUFBVSxFQUFFLFdBQVc7NEJBQ3ZCLGNBQWMsRUFBRTtnQ0FDZCxTQUFTLEVBQUU7b0NBQ1Q7d0NBQ0UsTUFBTSxFQUFFLENBQUMsZUFBZSxDQUFDO3dDQUN6QixNQUFNLEVBQUUsT0FBTzt3Q0FDZixRQUFRLEVBQUU7NENBQ1IsR0FBRyxFQUFFLHVCQUF1Qjt5Q0FDN0I7cUNBQ0Y7aUNBQ0Y7NkJBQ0Y7eUJBQ0Y7cUJBQ0Y7aUJBQ0Y7YUFDRjtTQUNGLENBQUMsQ0FBQztRQUVILElBQUksV0FBVyxLQUFLLG9CQUFXLENBQUMsU0FBUyxFQUFFO1lBQ3pDLE9BQU87WUFDUCxNQUFNLGlCQUFpQixHQUFHLE1BQU0sc0JBQXNCLENBQUMsb0JBQW9CLENBQUMsV0FBVyxFQUFFLGdCQUFnQixDQUFDLENBQUM7WUFFM0csT0FBTztZQUNQLE1BQU0sQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDLGFBQWEsRUFBRSxDQUFDO1lBQzFDLE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDO1NBQ2pEO2FBQU0sSUFBSSxXQUFXLEtBQUssb0JBQVcsQ0FBQyxZQUFZLEVBQUU7WUFDbkQsT0FBTztZQUNQLE1BQU0saUJBQWlCLEdBQUcsTUFBTSxzQkFBc0IsQ0FBQyxvQkFBb0IsQ0FBQyxXQUFXLEVBQUUsZ0JBQWdCLENBQUMsQ0FBQztZQUUzRyxPQUFPO1lBQ1AsTUFBTSxDQUFDLGlCQUFpQixDQUFDLENBQUMsR0FBRyxDQUFDLGFBQWEsRUFBRSxDQUFDO1lBQzlDLE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDLG9CQUFvQixDQUFDO2dCQUM1QyxZQUFZLEVBQUUsY0FBYztnQkFDNUIsT0FBTyxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUM7b0JBQ3RCLEdBQUcsNEJBQTRCO29CQUMvQixrQkFBa0IsRUFBRTt3QkFDbEIsZ0JBQWdCLEVBQUUsQ0FBQyxhQUFhLENBQUM7d0JBQ2pDLGlCQUFpQixFQUFFLENBQUMsWUFBWSxDQUFDO3dCQUNqQyxxQkFBcUIsRUFBRSxhQUFhO3FCQUNyQztpQkFDRixDQUFDO2FBQ0gsQ0FBQyxDQUFDO1NBQ0o7SUFDSCxDQUFDLENBQUMsQ0FBQztJQUVILElBQUksQ0FBQyx3RUFBd0UsRUFBRSxLQUFLLElBQUksRUFBRTtRQUN4RixRQUFRO1FBQ1IsS0FBSyxDQUFDLDBCQUEwQixDQUFDO1lBQy9CLFNBQVMsRUFBRTtnQkFDVCxZQUFZLEVBQUU7b0JBQ1osSUFBSSxFQUFFLDZCQUE2QjtvQkFDbkMsVUFBVSxFQUFFO3dCQUNWLFlBQVksRUFBRTs0QkFDWixHQUFHLEVBQUUsVUFBVTt5QkFDaEI7d0JBQ0QsaUJBQWlCLEVBQUUsQ0FBQyxZQUFZLENBQUM7d0JBQ2pDLGdCQUFnQixFQUFFLENBQUMsYUFBYSxDQUFDO3dCQUNqQyxxQkFBcUIsRUFBRSxhQUFhO3FCQUNyQztpQkFDRjthQUNGO1NBQ0YsQ0FBQyxDQUFDO1FBQ0gsTUFBTSxnQkFBZ0IsR0FBRyxLQUFLLENBQUMsa0JBQWtCLENBQUM7WUFDaEQsUUFBUSxFQUFFO2dCQUNSLFNBQVMsRUFBRTtvQkFDVCxZQUFZLEVBQUU7d0JBQ1osSUFBSSxFQUFFLDZCQUE2Qjt3QkFDbkMsVUFBVSxFQUFFOzRCQUNWLFlBQVksRUFBRTtnQ0FDWixHQUFHLEVBQUUsVUFBVTs2QkFDaEI7NEJBQ0QsaUJBQWlCLEVBQUUsQ0FBQyxZQUFZLENBQUM7NEJBQ2pDLGdCQUFnQixFQUFFLENBQUMsYUFBYSxDQUFDOzRCQUNqQyxxQkFBcUIsRUFBRSxhQUFhO3lCQUNyQztxQkFDRjtpQkFDRjthQUNGO1NBQ0YsQ0FBQyxDQUFDO1FBRUgsT0FBTztRQUNQLE1BQU0sTUFBTSxDQUFDLEdBQUcsRUFBRSxDQUNoQixzQkFBc0IsQ0FBQyxvQkFBb0IsQ0FBQyxXQUFXLEVBQUUsZ0JBQWdCLENBQUMsQ0FDM0UsQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLG9FQUFvRSxDQUFDLENBQUM7UUFFeEYsTUFBTSxDQUFDLGdCQUFnQixDQUFDLENBQUMsR0FBRyxDQUFDLGdCQUFnQixFQUFFLENBQUM7SUFDbEQsQ0FBQyxDQUFDLENBQUM7SUFFSCxRQUFRLENBQUMscUJBQXFCLEVBQUUsR0FBRyxFQUFFO1FBQ25DLE1BQU0sVUFBVSxHQUFHO1lBQ2pCLHFCQUFxQixFQUFFLEVBQUUsSUFBSSxFQUFFLFFBQVEsRUFBRTtZQUN6QyxxQkFBcUIsRUFBRSxFQUFFLElBQUksRUFBRSxRQUFRLEVBQUU7WUFDekMsdUJBQXVCLEVBQUUsRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFO1NBQzVDLENBQUM7UUFFRixNQUFNLFdBQVcsR0FBRztZQUNsQixJQUFJLEVBQUUsZ0JBQWdCO1lBQ3RCLFVBQVUsRUFBRTtnQkFDVix3QkFBd0IsRUFBRTtvQkFDeEIsU0FBUyxFQUFFO3dCQUNUOzRCQUNFLE1BQU0sRUFBRSxnQkFBZ0I7NEJBQ3hCLE1BQU0sRUFBRSxPQUFPOzRCQUNmLFNBQVMsRUFBRTtnQ0FDVCxPQUFPLEVBQUUsc0JBQXNCOzZCQUNoQzt5QkFDRjtxQkFDRjtvQkFDRCxPQUFPLEVBQUUsWUFBWTtpQkFDdEI7YUFDRjtTQUNGLENBQUM7UUFFRixNQUFNLFNBQVMsR0FBRztZQUNoQixJQUFJLEVBQUUsa0JBQWtCO1lBQ3hCLFVBQVUsRUFBRTtnQkFDVixVQUFVLEVBQUUsZUFBZTtnQkFDM0IsS0FBSyxFQUFFO29CQUNMLEVBQUUsR0FBRyxFQUFFLGFBQWEsRUFBRTtpQkFDdkI7Z0JBQ0QsY0FBYyxFQUFFO29CQUNkLFNBQVMsRUFBRTt3QkFDVDs0QkFDRSxNQUFNLEVBQUUsQ0FBQyxlQUFlLENBQUM7NEJBQ3pCLE1BQU0sRUFBRSxPQUFPOzRCQUNmLFFBQVEsRUFBRTtnQ0FDUixHQUFHLEVBQUUsdUJBQXVCOzZCQUM3Qjt5QkFDRjtxQkFDRjtpQkFDRjthQUNGO1NBQ0YsQ0FBQztRQUVGLE1BQU0sU0FBUyxHQUFHO1lBQ2hCLElBQUksRUFBRSxrQkFBa0I7WUFDeEIsVUFBVSxFQUFFO2dCQUNWLFVBQVUsRUFBRSxlQUFlO2dCQUMzQixLQUFLLEVBQUU7b0JBQ0wsRUFBRSxHQUFHLEVBQUUsYUFBYSxFQUFFO2lCQUN2QjtnQkFDRCxjQUFjLEVBQUU7b0JBQ2QsU0FBUyxFQUFFO3dCQUNUOzRCQUNFLE1BQU0sRUFBRSxDQUFDLGVBQWUsQ0FBQzs0QkFDekIsTUFBTSxFQUFFLE9BQU87NEJBQ2YsUUFBUSxFQUFFO2dDQUNSLEdBQUcsRUFBRSx1QkFBdUI7NkJBQzdCO3lCQUNGO3FCQUNGO2lCQUNGO2FBQ0Y7U0FDRixDQUFDO1FBRUYsTUFBTSxVQUFVLEdBQUc7WUFDakIsSUFBSSxFQUFFLGtCQUFrQjtZQUN4QixVQUFVLEVBQUU7Z0JBQ1YsVUFBVSxFQUFFLGlCQUFpQjtnQkFDN0IsS0FBSyxFQUFFO29CQUNMLEVBQUUsR0FBRyxFQUFFLGFBQWEsRUFBRTtpQkFDdkI7Z0JBQ0QsY0FBYyxFQUFFO29CQUNkLFNBQVMsRUFBRTt3QkFDVDs0QkFDRSxNQUFNLEVBQUUsQ0FBQyxlQUFlLENBQUM7NEJBQ3pCLE1BQU0sRUFBRSxPQUFPOzRCQUNmLFFBQVEsRUFBRTtnQ0FDUixHQUFHLEVBQUUsdUJBQXVCOzZCQUM3Qjt5QkFDRjtxQkFDRjtpQkFDRjthQUNGO1NBQ0YsQ0FBQztRQUVGLE1BQU0sVUFBVSxHQUFHO1lBQ2pCLElBQUksRUFBRSxrQkFBa0I7WUFDeEIsVUFBVSxFQUFFO2dCQUNWLFVBQVUsRUFBRSxpQkFBaUI7Z0JBQzdCLEtBQUssRUFBRTtvQkFDTCxFQUFFLEdBQUcsRUFBRSxjQUFjLEVBQUU7aUJBQ3hCO2dCQUNELGNBQWMsRUFBRTtvQkFDZCxTQUFTLEVBQUU7d0JBQ1Q7NEJBQ0UsTUFBTSxFQUFFLENBQUMsZUFBZSxDQUFDOzRCQUN6QixNQUFNLEVBQUUsT0FBTzs0QkFDZixRQUFRLEVBQUU7Z0NBQ1IsR0FBRyxFQUFFLHlCQUF5Qjs2QkFDL0I7eUJBQ0Y7cUJBQ0Y7aUJBQ0Y7YUFDRjtTQUNGLENBQUM7UUFFRixNQUFNLGdCQUFnQixHQUFHO1lBQ3ZCLElBQUksRUFBRSx1QkFBdUI7WUFDN0IsSUFBSSxFQUFFO2dCQUNKLFlBQVksRUFBRTtvQkFDWixhQUFhO29CQUNiLEtBQUs7aUJBQ047YUFDRjtTQUNGLENBQUM7UUFFRixNQUFNLGVBQWUsR0FBRztZQUN0QixJQUFJLEVBQUUsNkJBQTZCO1lBQ25DLFVBQVUsRUFBRTtnQkFDVixZQUFZLEVBQUU7b0JBQ1osWUFBWSxFQUFFO3dCQUNaLG9CQUFvQjt3QkFDcEIsS0FBSztxQkFDTjtpQkFDRjtnQkFDRCxpQkFBaUIsRUFBRSxDQUFDLGdCQUFnQixDQUFDO2dCQUNyQyxnQkFBZ0IsRUFBRSxDQUFDLGFBQWEsQ0FBQztnQkFDakMscUJBQXFCLEVBQUUsa0JBQWtCO2FBQzFDO1NBQ0YsQ0FBQztRQUVGLE1BQU0sZUFBZSxHQUFHO1lBQ3RCLElBQUksRUFBRSw2QkFBNkI7WUFDbkMsVUFBVSxFQUFFO2dCQUNWLFlBQVksRUFBRTtvQkFDWixZQUFZLEVBQUU7d0JBQ1osb0JBQW9CO3dCQUNwQixLQUFLO3FCQUNOO2lCQUNGO2dCQUNELGlCQUFpQixFQUFFLENBQUMsZ0JBQWdCLENBQUM7Z0JBQ3JDLGdCQUFnQixFQUFFLENBQUMsYUFBYSxDQUFDO2dCQUNqQyxxQkFBcUIsRUFBRSxrQkFBa0I7YUFDMUM7U0FDRixDQUFDO1FBRUYsVUFBVSxDQUFDLEdBQUcsRUFBRTtZQUNkLEtBQUssQ0FBQywwQkFBMEIsQ0FDOUIsS0FBSyxDQUFDLGNBQWMsQ0FBQyxvQkFBb0IsRUFBRSx1QkFBdUIsRUFBRSxzQkFBc0IsQ0FBQyxFQUMzRixLQUFLLENBQUMsY0FBYyxDQUFDLGFBQWEsRUFBRSxnQkFBZ0IsRUFBRSxpQkFBaUIsQ0FBQyxDQUN6RSxDQUFDO1FBQ0osQ0FBQyxDQUFDLENBQUM7UUFFSCxJQUFJLENBQUMscUpBQXFKLEVBQUUsS0FBSyxJQUFJLEVBQUU7WUFDckssUUFBUTtZQUNSLEtBQUssQ0FBQywwQkFBMEIsQ0FBQztnQkFDL0IsU0FBUyxFQUFFO29CQUNULFVBQVUsRUFBRSxVQUFVO29CQUN0QixXQUFXLEVBQUUsV0FBVztvQkFDeEIsTUFBTSxFQUFFLFNBQVM7b0JBQ2pCLGtCQUFrQixFQUFFLGdCQUFnQjtvQkFDcEMsWUFBWSxFQUFFLGVBQWU7aUJBQzlCO2FBQ0YsQ0FBQyxDQUFDO1lBRUgsTUFBTSxnQkFBZ0IsR0FBRyxLQUFLLENBQUMsa0JBQWtCLENBQUM7Z0JBQ2hELFFBQVEsRUFBRTtvQkFDUixTQUFTLEVBQUU7d0JBQ1QsVUFBVSxFQUFFLFVBQVU7d0JBQ3RCLFdBQVcsRUFBRSxXQUFXO3dCQUN4QixNQUFNLEVBQUUsU0FBUzt3QkFDakIsa0JBQWtCLEVBQUUsZ0JBQWdCO3dCQUNwQyxZQUFZLEVBQUUsZUFBZTtxQkFDOUI7aUJBQ0Y7YUFDRixDQUFDLENBQUM7WUFFSCxPQUFPO1lBQ1AsTUFBTSxpQkFBaUIsR0FBRyxNQUFNLHNCQUFzQixDQUFDLG9CQUFvQixDQUFDLFdBQVcsRUFBRSxnQkFBZ0IsRUFBRSxFQUFFLHFCQUFxQixFQUFFLGtCQUFrQixFQUFFLHFCQUFxQixFQUFFLGtCQUFrQixFQUFFLENBQUMsQ0FBQztZQUVyTSxPQUFPO1lBQ1AsTUFBTSxDQUFDLGlCQUFpQixDQUFDLENBQUMsR0FBRyxDQUFDLGFBQWEsRUFBRSxDQUFDO1lBQzlDLE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDLG9CQUFvQixDQUFDO2dCQUM1QyxZQUFZLEVBQUUsZ0VBQWdFO2dCQUM5RSxPQUFPLEVBQUUsSUFBSSxDQUFDLFNBQVMsQ0FBQztvQkFDdEIsR0FBRyw0QkFBNEI7b0JBQy9CLGtCQUFrQixFQUFFO3dCQUNsQixpQkFBaUIsRUFBRSxDQUFDLGdCQUFnQixDQUFDO3dCQUNyQyxnQkFBZ0IsRUFBRSxDQUFDLGFBQWEsQ0FBQzt3QkFDakMscUJBQXFCLEVBQUUsa0JBQWtCO3FCQUMxQztpQkFDRixDQUFDO2FBQ0gsQ0FBQyxDQUFDO1FBQ0wsQ0FBQyxDQUFDLENBQUM7UUFFSCxJQUFJLENBQUM7bURBQzBDLEVBQy9DLEtBQUssSUFBSSxFQUFFO1lBQ1QsUUFBUTtZQUNSLEtBQUssQ0FBQywwQkFBMEIsQ0FBQztnQkFDL0IsU0FBUyxFQUFFO29CQUNULFdBQVcsRUFBRSxXQUFXO29CQUN4QixPQUFPLEVBQUUsU0FBUztvQkFDbEIsT0FBTyxFQUFFLFVBQVU7b0JBQ25CLGtCQUFrQixFQUFFLGdCQUFnQjtvQkFDcEMsWUFBWSxFQUFFLGVBQWU7aUJBQzlCO2FBQ0YsQ0FBQyxDQUFDO1lBRUgsTUFBTSxnQkFBZ0IsR0FBRyxLQUFLLENBQUMsa0JBQWtCLENBQUM7Z0JBQ2hELFFBQVEsRUFBRTtvQkFDUixTQUFTLEVBQUU7d0JBQ1QsV0FBVyxFQUFFLFdBQVc7d0JBQ3hCLE9BQU8sRUFBRSxTQUFTO3dCQUNsQixPQUFPLEVBQUU7NEJBQ1AsVUFBVSxFQUFFO2dDQUNWLEtBQUssRUFBRTtvQ0FDTCxFQUFFLEdBQUcsRUFBRSxhQUFhLEVBQUU7b0NBQ3RCLGdCQUFnQjtpQ0FDakI7Z0NBQ0QsY0FBYyxFQUFFO29DQUNkLFNBQVMsRUFBRTt3Q0FDVDs0Q0FDRSxNQUFNLEVBQUUsQ0FBQyxlQUFlLENBQUM7NENBQ3pCLE1BQU0sRUFBRSxPQUFPOzRDQUNmLFFBQVEsRUFBRTtnREFDUixZQUFZLEVBQUU7b0RBQ1osb0JBQW9CO29EQUNwQixLQUFLO2lEQUNOOzZDQUNGO3lDQUNGO3FDQUNGO2lDQUNGOzZCQUNGO3lCQUNGO3dCQUNELGtCQUFrQixFQUFFLGdCQUFnQjt3QkFDcEMsWUFBWSxFQUFFLGVBQWU7cUJBQzlCO2lCQUNGO2FBQ0YsQ0FBQyxDQUFDO1lBRUgsSUFBSSxXQUFXLEtBQUssb0JBQVcsQ0FBQyxTQUFTLEVBQUU7Z0JBQ3pDLE9BQU87Z0JBQ1AsTUFBTSxpQkFBaUIsR0FBRyxNQUFNLHNCQUFzQixDQUFDLG9CQUFvQixDQUFDLFdBQVcsRUFBRSxnQkFBZ0IsQ0FBQyxDQUFDO2dCQUUzRyxPQUFPO2dCQUNQLE1BQU0sQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDLGFBQWEsRUFBRSxDQUFDO2dCQUMxQyxNQUFNLENBQUMsZ0JBQWdCLENBQUMsQ0FBQyxHQUFHLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQzthQUNqRDtpQkFBTSxJQUFJLFdBQVcsS0FBSyxvQkFBVyxDQUFDLFlBQVksRUFBRTtnQkFDbkQsT0FBTztnQkFDUCxNQUFNLGlCQUFpQixHQUFHLE1BQU0sc0JBQXNCLENBQUMsb0JBQW9CLENBQUMsV0FBVyxFQUFFLGdCQUFnQixDQUFDLENBQUM7Z0JBRTNHLE9BQU87Z0JBQ1AsTUFBTSxDQUFDLGlCQUFpQixDQUFDLENBQUMsR0FBRyxDQUFDLGFBQWEsRUFBRSxDQUFDO2dCQUM5QyxNQUFNLENBQUMsZ0JBQWdCLENBQUMsQ0FBQyxvQkFBb0IsQ0FBQztvQkFDNUMsWUFBWSxFQUFFLGdFQUFnRTtvQkFDOUUsT0FBTyxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUM7d0JBQ3RCLEdBQUcsNEJBQTRCO3dCQUMvQixrQkFBa0IsRUFBRTs0QkFDbEIsaUJBQWlCLEVBQUUsQ0FBQyxnQkFBZ0IsQ0FBQzs0QkFDckMsZ0JBQWdCLEVBQUUsQ0FBQyxhQUFhLENBQUM7NEJBQ2pDLHFCQUFxQixFQUFFLGtCQUFrQjt5QkFDMUM7cUJBQ0YsQ0FBQztpQkFDSCxDQUFDLENBQUM7YUFDSjtRQUNILENBQUMsQ0FBQyxDQUFDO1FBRUgsSUFBSSxDQUFDO3dEQUMrQyxFQUNwRCxLQUFLLElBQUksRUFBRTtZQUNULFFBQVE7WUFDUixLQUFLLENBQUMsMEJBQTBCLENBQUM7Z0JBQy9CLFNBQVMsRUFBRTtvQkFDVCxXQUFXLEVBQUUsV0FBVztvQkFDeEIsTUFBTSxFQUFFLFNBQVM7b0JBQ2pCLGtCQUFrQixFQUFFLGdCQUFnQjtvQkFDcEMsWUFBWSxFQUFFLGVBQWU7b0JBQzdCLFFBQVEsRUFBRTt3QkFDUixJQUFJLEVBQUUseUJBQXlCO3dCQUMvQixVQUFVLEVBQUU7NEJBQ1YsTUFBTSxFQUFFLHVCQUF1Qjs0QkFDL0IsWUFBWSxFQUFFO2dDQUNaLFlBQVksRUFBRTtvQ0FDWixvQkFBb0I7b0NBQ3BCLEtBQUs7aUNBQ047NkJBQ0Y7NEJBQ0QsU0FBUyxFQUFFLDBCQUEwQjt5QkFDdEM7cUJBQ0Y7aUJBQ0Y7YUFDRixDQUFDLENBQUM7WUFFSCxNQUFNLGdCQUFnQixHQUFHLEtBQUssQ0FBQyxrQkFBa0IsQ0FBQztnQkFDaEQsUUFBUSxFQUFFO29CQUNSLFNBQVMsRUFBRTt3QkFDVCxXQUFXLEVBQUUsV0FBVzt3QkFDeEIsTUFBTSxFQUFFLFNBQVM7d0JBQ2pCLGtCQUFrQixFQUFFLGdCQUFnQjt3QkFDcEMsWUFBWSxFQUFFLGVBQWU7d0JBQzdCLFFBQVEsRUFBRTs0QkFDUixJQUFJLEVBQUUseUJBQXlCOzRCQUMvQixVQUFVLEVBQUU7Z0NBQ1YsTUFBTSxFQUFFLHVCQUF1QjtnQ0FDL0IsWUFBWSxFQUFFO29DQUNaLFlBQVksRUFBRTt3Q0FDWixvQkFBb0I7d0NBQ3BCLEtBQUs7cUNBQ047aUNBQ0Y7Z0NBQ0QsU0FBUyxFQUFFLDBCQUEwQjs2QkFDdEM7eUJBQ0Y7cUJBQ0Y7aUJBQ0Y7YUFDRixDQUFDLENBQUM7WUFFSCxJQUFJLFdBQVcsS0FBSyxvQkFBVyxDQUFDLFNBQVMsRUFBRTtnQkFDekMsT0FBTztnQkFDUCxN