terraconstructs 0.0.24 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.jsii +83665 -54911
- package/.mise.toml +1 -1
- package/.nvmrc +1 -1
- package/LICENSE +202 -674
- package/go.mod +9 -7
- package/go.sum +18 -14
- package/lib/asset-manager.d.ts +23 -0
- package/lib/asset-manager.js +3 -0
- package/lib/asset-staging.d.ts +178 -0
- package/lib/asset-staging.js +589 -0
- package/lib/assets.d.ts +359 -0
- package/lib/assets.js +55 -0
- package/lib/aws/arn.js +16 -15
- package/lib/aws/aws-asset-manager.d.ts +91 -0
- package/lib/aws/aws-asset-manager.js +244 -0
- package/lib/aws/aws-construct.js +1 -1
- package/lib/aws/aws-stack.d.ts +37 -0
- package/lib/aws/aws-stack.js +30 -9
- package/lib/aws/aws-tags.js +2 -2
- package/lib/aws/cloudwatch/actions/appscaling.d.ts +15 -0
- package/lib/aws/cloudwatch/actions/appscaling.js +24 -0
- package/lib/aws/cloudwatch/actions/ec2.js +1 -1
- package/lib/aws/cloudwatch/actions/index.d.ts +3 -0
- package/lib/aws/cloudwatch/actions/index.js +4 -4
- package/lib/aws/cloudwatch/actions/lambda.js +1 -1
- package/lib/aws/cloudwatch/actions/sns.d.ts +14 -0
- package/lib/aws/cloudwatch/actions/sns.js +23 -0
- package/lib/aws/cloudwatch/actions/ssm.d.ts +72 -0
- package/lib/aws/cloudwatch/actions/ssm.js +104 -0
- package/lib/aws/cloudwatch/alarm-base.js +1 -1
- package/lib/aws/cloudwatch/alarm-rule.js +1 -1
- package/lib/aws/cloudwatch/alarm-status-widget.js +1 -1
- package/lib/aws/cloudwatch/alarm.js +1 -1
- package/lib/aws/cloudwatch/composite-alarm.js +1 -1
- package/lib/aws/cloudwatch/dashboard.js +1 -1
- package/lib/aws/cloudwatch/data-protection-policy.js +3 -3
- package/lib/aws/cloudwatch/graph.js +8 -8
- package/lib/aws/cloudwatch/layout.js +3 -3
- package/lib/aws/cloudwatch/log-destinations/kinesis.js +1 -1
- package/lib/aws/cloudwatch/log-destinations/lambda.js +1 -1
- package/lib/aws/cloudwatch/log-group.js +1 -1
- package/lib/aws/cloudwatch/log-query.js +1 -1
- package/lib/aws/cloudwatch/log-stream.js +1 -1
- package/lib/aws/cloudwatch/metric-filter.js +1 -1
- package/lib/aws/cloudwatch/metric.js +2 -2
- package/lib/aws/cloudwatch/pattern.js +3 -3
- package/lib/aws/cloudwatch/policy.js +1 -1
- package/lib/aws/cloudwatch/query-definition.js +2 -2
- package/lib/aws/cloudwatch/stats.js +1 -1
- package/lib/aws/cloudwatch/subscription-filter.js +1 -1
- package/lib/aws/cloudwatch/text.js +1 -1
- package/lib/aws/cloudwatch/variable.js +3 -3
- package/lib/aws/cloudwatch/widget.js +1 -1
- package/lib/aws/compute/access-log.d.ts +478 -0
- package/lib/aws/compute/access-log.js +649 -0
- package/lib/aws/compute/activity.js +1 -1
- package/lib/aws/compute/alb/application-listener-action.js +1 -1
- package/lib/aws/compute/alb/application-listener-certificate.js +1 -1
- package/lib/aws/compute/alb/application-listener-rule.js +1 -1
- package/lib/aws/compute/alb/application-listener.js +1 -1
- package/lib/aws/compute/alb/application-load-balancer.js +1 -1
- package/lib/aws/compute/alb/application-target-group.js +1 -1
- package/lib/aws/compute/alb/conditions.js +1 -1
- package/lib/aws/compute/alb/trust-store-revocation.js +1 -1
- package/lib/aws/compute/alb/trust-store.js +1 -1
- package/lib/aws/compute/api-definition.d.ts +106 -0
- package/lib/aws/compute/api-definition.js +200 -0
- package/lib/aws/compute/api-key.d.ts +184 -0
- package/lib/aws/compute/api-key.js +197 -0
- package/lib/aws/compute/apigateway-canned-metrics.generated.d.ts +169 -0
- package/lib/aws/compute/apigateway-canned-metrics.generated.js +63 -0
- package/lib/aws/compute/apigateway-util.d.ts +31 -0
- package/lib/aws/compute/apigateway-util.js +152 -0
- package/lib/aws/compute/architecture.js +1 -1
- package/lib/aws/compute/aspects/require-imdsv2-aspect.js +2 -2
- package/lib/aws/compute/authorizer.d.ts +35 -0
- package/lib/aws/compute/authorizer.js +28 -0
- package/lib/aws/compute/authorizers/identity-source.d.ts +37 -0
- package/lib/aws/compute/authorizers/identity-source.js +61 -0
- package/lib/aws/compute/authorizers/index.d.ts +2 -0
- package/lib/aws/compute/authorizers/index.js +20 -0
- package/lib/aws/compute/authorizers/lambda.d.ts +140 -0
- package/lib/aws/compute/authorizers/lambda.js +208 -0
- package/lib/aws/compute/base-path-mapping.d.ts +49 -0
- package/lib/aws/compute/base-path-mapping.js +52 -0
- package/lib/aws/compute/base-scalable-attribute.js +3 -3
- package/lib/aws/compute/bastion-host.js +1 -1
- package/lib/aws/compute/chain.js +1 -1
- package/lib/aws/compute/client-vpn-authorization-rule.js +1 -1
- package/lib/aws/compute/client-vpn-endpoint.js +2 -2
- package/lib/aws/compute/client-vpn-route.js +2 -2
- package/lib/aws/compute/code.d.ts +415 -0
- package/lib/aws/compute/code.js +424 -0
- package/lib/aws/compute/condition.js +1 -1
- package/lib/aws/compute/connections.js +1 -1
- package/lib/aws/compute/cors.d.ts +102 -0
- package/lib/aws/compute/cors.js +33 -0
- package/lib/aws/compute/deployment.d.ts +83 -0
- package/lib/aws/compute/deployment.js +158 -0
- package/lib/aws/compute/domain-name.d.ts +153 -0
- package/lib/aws/compute/domain-name.js +158 -0
- package/lib/aws/compute/event-invoke-config.d.ts +2 -2
- package/lib/aws/compute/event-invoke-config.js +4 -4
- package/lib/aws/compute/event-source-filter.js +2 -2
- package/lib/aws/compute/event-source-mapping.d.ts +2 -2
- package/lib/aws/compute/event-source-mapping.js +9 -7
- package/lib/aws/compute/event-sources/s3-onfailure-destination.js +1 -1
- package/lib/aws/compute/event-sources/s3.js +1 -1
- package/lib/aws/compute/event-sources/sqs-dlq.js +1 -1
- package/lib/aws/compute/event-sources/sqs.js +3 -2
- package/lib/aws/compute/fields.js +4 -4
- package/lib/aws/compute/function-alias.d.ts +1 -0
- package/lib/aws/compute/function-alias.js +8 -2
- package/lib/aws/compute/function-base.d.ts +15 -0
- package/lib/aws/compute/function-base.js +4 -4
- package/lib/aws/compute/function-destinations/event-bridge.js +1 -1
- package/lib/aws/compute/function-destinations/function.js +1 -1
- package/lib/aws/compute/function-destinations/sqs.js +1 -1
- package/lib/aws/compute/function-nodejs/bundling.d.ts +75 -0
- package/lib/aws/compute/function-nodejs/bundling.js +405 -0
- package/lib/aws/compute/function-nodejs/function.d.ts +99 -0
- package/lib/aws/compute/function-nodejs/function.js +175 -0
- package/lib/aws/compute/function-nodejs/index.d.ts +2 -0
- package/lib/aws/compute/function-nodejs/index.js +19 -0
- package/lib/aws/compute/function-nodejs/package-installation.d.ts +8 -0
- package/lib/aws/compute/function-nodejs/package-installation.js +36 -0
- package/lib/aws/compute/function-nodejs/package-manager.d.ts +33 -0
- package/lib/aws/compute/function-nodejs/package-manager.js +99 -0
- package/lib/aws/compute/function-nodejs/types.d.ts +410 -0
- package/lib/aws/compute/function-nodejs/types.js +81 -0
- package/lib/aws/compute/function-nodejs/util.d.ts +60 -0
- package/lib/aws/compute/function-nodejs/util.js +202 -0
- package/lib/aws/compute/function-url.d.ts +2 -2
- package/lib/aws/compute/function-url.js +4 -4
- package/lib/aws/compute/function.d.ts +34 -4
- package/lib/aws/compute/function.js +91 -17
- package/lib/aws/compute/gateway-response.d.ts +157 -0
- package/lib/aws/compute/gateway-response.js +156 -0
- package/lib/aws/compute/handler.d.ts +10 -0
- package/lib/aws/compute/handler.js +20 -0
- package/lib/aws/compute/index.d.ts +27 -0
- package/lib/aws/compute/index.js +29 -1
- package/lib/aws/compute/instance-types.js +1 -1
- package/lib/aws/compute/instance.js +1 -1
- package/lib/aws/compute/integration.d.ts +311 -0
- package/lib/aws/compute/integration.js +165 -0
- package/lib/aws/compute/integrations/aws.d.ts +72 -0
- package/lib/aws/compute/integrations/aws.js +55 -0
- package/lib/aws/compute/integrations/http.d.ts +37 -0
- package/lib/aws/compute/integrations/http.js +35 -0
- package/lib/aws/compute/integrations/index.d.ts +6 -0
- package/lib/aws/compute/integrations/index.js +24 -0
- package/lib/aws/compute/integrations/lambda.d.ts +40 -0
- package/lib/aws/compute/integrations/lambda.js +73 -0
- package/lib/aws/compute/integrations/mock.d.ts +16 -0
- package/lib/aws/compute/integrations/mock.js +30 -0
- package/lib/aws/compute/integrations/request-context.d.ts +144 -0
- package/lib/aws/compute/integrations/request-context.js +3 -0
- package/lib/aws/compute/integrations/stepfunctions.d.ts +102 -0
- package/lib/aws/compute/integrations/stepfunctions.js +268 -0
- package/lib/aws/compute/ip-addresses.js +2 -2
- package/lib/aws/compute/ipam.js +1 -1
- package/lib/aws/compute/json-schema.d.ts +75 -0
- package/lib/aws/compute/json-schema.js +23 -0
- package/lib/aws/compute/key-pair.js +1 -1
- package/lib/aws/compute/lambda-api.d.ts +46 -0
- package/lib/aws/compute/lambda-api.js +64 -0
- package/lib/aws/compute/launch-template.js +2 -2
- package/lib/aws/compute/lb-shared/base-listener.js +1 -1
- package/lib/aws/compute/lb-shared/base-load-balancer.js +2 -2
- package/lib/aws/compute/lb-shared/base-target-group.js +1 -1
- package/lib/aws/compute/lb-shared/listener-certificate.js +1 -1
- package/lib/aws/compute/lb-shared/load-balancer-targets.js +2 -2
- package/lib/aws/compute/lb-targets/alb-target.js +3 -3
- package/lib/aws/compute/lb-targets/instance-target.js +2 -2
- package/lib/aws/compute/lb-targets/ip-target.js +1 -1
- package/lib/aws/compute/lb-targets/lambda-target.js +1 -1
- package/lib/aws/compute/load-balancer.js +3 -3
- package/lib/aws/compute/machine-image/amazon-linux-2022.js +2 -2
- package/lib/aws/compute/machine-image/amazon-linux-2023.js +2 -2
- package/lib/aws/compute/machine-image/amazon-linux2.js +2 -2
- package/lib/aws/compute/machine-image/common.js +1 -1
- package/lib/aws/compute/machine-image/machine-image.js +8 -8
- package/lib/aws/compute/method.d.ts +219 -0
- package/lib/aws/compute/method.js +396 -0
- package/lib/aws/compute/methodresponse.d.ts +28 -0
- package/lib/aws/compute/methodresponse.js +3 -0
- package/lib/aws/compute/model.d.ts +143 -0
- package/lib/aws/compute/model.js +141 -0
- package/lib/aws/compute/nat.js +5 -5
- package/lib/aws/compute/network-acl-types.js +2 -2
- package/lib/aws/compute/network-acl.js +3 -3
- package/lib/aws/compute/nlb/network-listener-action.js +1 -1
- package/lib/aws/compute/nlb/network-listener.js +1 -1
- package/lib/aws/compute/nlb/network-load-balancer.js +1 -1
- package/lib/aws/compute/nlb/network-target-group.js +1 -1
- package/lib/aws/compute/peer.js +1 -1
- package/lib/aws/compute/placement-group.js +1 -1
- package/lib/aws/compute/port.js +1 -1
- package/lib/aws/compute/prefix-list.js +1 -1
- package/lib/aws/compute/requestvalidator.d.ts +50 -0
- package/lib/aws/compute/requestvalidator.js +59 -0
- package/lib/aws/compute/resource.d.ts +223 -0
- package/lib/aws/compute/resource.js +316 -0
- package/lib/aws/compute/restapi.d.ts +510 -0
- package/lib/aws/compute/restapi.js +626 -0
- package/lib/aws/compute/route.js +8 -8
- package/lib/aws/compute/runtime.d.ts +282 -0
- package/lib/aws/compute/runtime.js +337 -0
- package/lib/aws/compute/scalable-target.js +3 -3
- package/lib/aws/compute/schedule.js +3 -3
- package/lib/aws/compute/security-group.js +1 -1
- package/lib/aws/compute/stage.d.ts +350 -0
- package/lib/aws/compute/stage.js +304 -0
- package/lib/aws/compute/state-graph.js +1 -1
- package/lib/aws/compute/state-machine-fragment.js +1 -1
- package/lib/aws/compute/state-machine.js +4 -4
- package/lib/aws/compute/states/choice.js +1 -1
- package/lib/aws/compute/states/custom-state.js +1 -1
- package/lib/aws/compute/states/distributed-map/item-batcher.js +1 -1
- package/lib/aws/compute/states/distributed-map/item-reader.js +5 -5
- package/lib/aws/compute/states/distributed-map/result-writer.js +1 -1
- package/lib/aws/compute/states/distributed-map.js +1 -1
- package/lib/aws/compute/states/fail.js +1 -1
- package/lib/aws/compute/states/map-base.js +1 -1
- package/lib/aws/compute/states/map.js +1 -1
- package/lib/aws/compute/states/parallel.js +1 -1
- package/lib/aws/compute/states/pass.js +2 -2
- package/lib/aws/compute/states/state.js +1 -1
- package/lib/aws/compute/states/succeed.js +1 -1
- package/lib/aws/compute/states/task-base.js +2 -2
- package/lib/aws/compute/states/task.js +1 -1
- package/lib/aws/compute/states/wait.js +2 -2
- package/lib/aws/compute/step-scaling-action.js +3 -3
- package/lib/aws/compute/step-scaling-policy.js +1 -1
- package/lib/aws/compute/stepfunctions-api.d.ts +103 -0
- package/lib/aws/compute/stepfunctions-api.js +39 -0
- package/lib/aws/compute/subnet-v2.js +2 -2
- package/lib/aws/compute/subnet.js +1 -1
- package/lib/aws/compute/target-tracking-scaling-policy.js +3 -3
- package/lib/aws/compute/task-credentials.js +1 -1
- package/lib/aws/compute/task-input.js +1 -1
- package/lib/aws/compute/tasks/aws-sdk/call-aws-service.js +1 -1
- package/lib/aws/compute/tasks/eventbridge/put-events.js +1 -1
- package/lib/aws/compute/tasks/http/invoke.js +1 -1
- package/lib/aws/compute/tasks/lambda/invoke.js +1 -1
- package/lib/aws/compute/tasks/sqs/send-message.js +1 -1
- package/lib/aws/compute/tasks/stepfunctions/invoke-activity.js +1 -1
- package/lib/aws/compute/tasks/stepfunctions/start-execution.js +1 -1
- package/lib/aws/compute/types.js +1 -1
- package/lib/aws/compute/usage-plan.d.ts +194 -0
- package/lib/aws/compute/usage-plan.js +174 -0
- package/lib/aws/compute/user-data.js +3 -3
- package/lib/aws/compute/volume.js +2 -2
- package/lib/aws/compute/vpc-endpoint-service.js +1 -1
- package/lib/aws/compute/vpc-endpoint.js +6 -6
- package/lib/aws/compute/vpc-flow-logs.js +4 -4
- package/lib/aws/compute/vpc-link.d.ts +104 -0
- package/lib/aws/compute/vpc-link.js +137 -0
- package/lib/aws/compute/vpc-v2-base.js +1 -1
- package/lib/aws/compute/vpc-v2.js +2 -2
- package/lib/aws/compute/vpc.js +4 -4
- package/lib/aws/compute/vpn.js +3 -3
- package/lib/aws/edge/certificate.js +1 -1
- package/lib/aws/edge/distribution.js +3 -3
- package/lib/aws/edge/dns-alias-record-targets.js +3 -3
- package/lib/aws/edge/dns-record.js +13 -13
- package/lib/aws/edge/dns-zone.js +1 -1
- package/lib/aws/edge/function.js +2 -2
- package/lib/aws/edge/key-value-store.js +4 -4
- package/lib/aws/edge/origin.js +3 -3
- package/lib/aws/edge/response-headers-policy.js +1 -1
- package/lib/aws/encryption/alias.js +1 -1
- package/lib/aws/encryption/key.js +1 -1
- package/lib/aws/encryption/via-service-principal.js +1 -1
- package/lib/aws/iam/grant.js +2 -2
- package/lib/aws/iam/group.js +1 -1
- package/lib/aws/iam/instance-profile.js +1 -1
- package/lib/aws/iam/managed-policy.js +1 -1
- package/lib/aws/iam/oidc-provider.js +1 -1
- package/lib/aws/iam/policy-document.js +1 -1
- package/lib/aws/iam/policy-statement.js +1 -1
- package/lib/aws/iam/policy.js +1 -1
- package/lib/aws/iam/principals.js +20 -20
- package/lib/aws/iam/role.js +1 -1
- package/lib/aws/iam/saml-provider.js +2 -2
- package/lib/aws/iam/unknown-principal.js +1 -1
- package/lib/aws/iam/user.js +5 -5
- package/lib/aws/index.d.ts +1 -0
- package/lib/aws/index.js +4 -1
- package/lib/aws/network/simple-ipv4-vpc.js +1 -1
- package/lib/aws/network/subnet-group.js +3 -3
- package/lib/aws/network/subnet.js +4 -4
- package/lib/aws/notify/archive.js +1 -1
- package/lib/aws/notify/connection.js +3 -3
- package/lib/aws/notify/event-bus.js +3 -3
- package/lib/aws/notify/event-pattern.js +1 -1
- package/lib/aws/notify/input.js +2 -2
- package/lib/aws/notify/kinesis-stream.js +1 -1
- package/lib/aws/notify/notification-rule.d.ts +1 -1
- package/lib/aws/notify/notification-rule.js +5 -5
- package/lib/aws/notify/policy.js +1 -1
- package/lib/aws/notify/queue-policy.js +1 -1
- package/lib/aws/notify/queue.js +1 -1
- package/lib/aws/notify/resource-policy.js +1 -1
- package/lib/aws/notify/rule.js +1 -1
- package/lib/aws/notify/schedule.js +1 -1
- package/lib/aws/notify/subscription-filter.js +1 -1
- package/lib/aws/notify/subscription.js +4 -4
- package/lib/aws/notify/subscriptions/email.js +1 -1
- package/lib/aws/notify/subscriptions/lambda.js +1 -1
- package/lib/aws/notify/subscriptions/sms.js +1 -1
- package/lib/aws/notify/subscriptions/sqs.js +1 -1
- package/lib/aws/notify/subscriptions/url.js +1 -1
- package/lib/aws/notify/targets/event-bus.js +1 -1
- package/lib/aws/notify/targets/function.js +1 -1
- package/lib/aws/notify/targets/log-group.js +2 -2
- package/lib/aws/notify/targets/sqs.js +1 -1
- package/lib/aws/notify/targets/state-machine.js +1 -1
- package/lib/aws/notify/topic-base.js +1 -1
- package/lib/aws/notify/topic.js +6 -5
- package/lib/aws/partition.d.ts +21 -0
- package/lib/aws/partition.js +42 -0
- package/lib/aws/storage/assets/image-asset.d.ts +379 -0
- package/lib/aws/storage/assets/image-asset.js +247 -0
- package/lib/aws/storage/assets/index.d.ts +2 -0
- package/lib/aws/storage/assets/index.js +21 -0
- package/lib/aws/storage/assets/s3.d.ts +125 -0
- package/lib/aws/storage/assets/s3.js +80 -0
- package/lib/aws/storage/auth-token.d.ts +25 -0
- package/lib/aws/storage/auth-token.js +54 -0
- package/lib/aws/storage/billing.js +1 -1
- package/lib/aws/storage/bucket-notifications.js +1 -1
- package/lib/aws/storage/bucket-policy.js +1 -1
- package/lib/aws/storage/bucket-source.d.ts +1 -1
- package/lib/aws/storage/bucket-source.js +4 -4
- package/lib/aws/storage/bucket.d.ts +14 -6
- package/lib/aws/storage/bucket.js +48 -40
- package/lib/aws/storage/capacity.js +1 -1
- package/lib/aws/storage/ecr-lifecycle.d.ts +88 -0
- package/lib/aws/storage/ecr-lifecycle.js +23 -0
- package/lib/aws/storage/ecr-repository.d.ts +446 -0
- package/lib/aws/storage/ecr-repository.js +685 -0
- package/lib/aws/storage/encryption.js +1 -1
- package/lib/aws/storage/index.d.ts +5 -0
- package/lib/aws/storage/index.js +10 -3
- package/lib/aws/storage/location.d.ts +17 -0
- package/lib/aws/storage/location.js +4 -0
- package/lib/aws/storage/notification-targets/function.js +1 -1
- package/lib/aws/storage/notification-targets/queue.js +1 -1
- package/lib/aws/storage/origin-access-identity.js +1 -1
- package/lib/aws/storage/parameter.js +2 -2
- package/lib/aws/storage/table.js +3 -3
- package/lib/aws/storage/util.d.ts +8 -20
- package/lib/aws/storage/util.js +56 -34
- package/lib/aws/util.d.ts +1 -0
- package/lib/aws/util.js +6 -1
- package/lib/bundling.d.ts +434 -0
- package/lib/bundling.js +368 -0
- package/lib/construct-base.js +2 -2
- package/lib/duration.js +1 -1
- package/lib/expiration.js +1 -1
- package/lib/fs/copy.d.ts +2 -0
- package/lib/fs/copy.js +57 -0
- package/lib/fs/fingerprint.d.ts +21 -0
- package/lib/fs/fingerprint.js +165 -0
- package/lib/fs/ignore.d.ts +107 -0
- package/lib/fs/ignore.js +190 -0
- package/lib/fs/index.d.ts +47 -0
- package/lib/fs/index.js +88 -0
- package/lib/fs/options.d.ts +110 -0
- package/lib/fs/options.js +60 -0
- package/lib/fs/utils.d.ts +11 -0
- package/lib/fs/utils.js +34 -0
- package/lib/index.d.ts +5 -0
- package/lib/index.js +7 -1
- package/lib/private/asset-staging.d.ts +83 -0
- package/lib/private/asset-staging.js +205 -0
- package/lib/private/cache.d.ts +17 -0
- package/lib/private/cache.js +35 -0
- package/lib/private/jsii-deprecated.d.ts +2 -0
- package/lib/private/jsii-deprecated.js +19 -0
- package/lib/private/unique-resource-name.js +3 -2
- package/lib/size.js +1 -1
- package/lib/stack-base.js +1 -1
- package/lib/terra-func.js +2 -2
- package/lib/time-zone.js +1 -1
- package/node_modules/@balena/dockerignore/CHANGELOG.md +31 -0
- package/node_modules/@balena/dockerignore/LICENSE.md +206 -0
- package/node_modules/@balena/dockerignore/README.md +261 -0
- package/node_modules/@balena/dockerignore/ignore.js +363 -0
- package/node_modules/@balena/dockerignore/index.d.ts +45 -0
- package/node_modules/@balena/dockerignore/package.json +49 -0
- package/node_modules/balanced-match/.github/FUNDING.yml +2 -0
- package/node_modules/balanced-match/LICENSE.md +21 -0
- package/node_modules/balanced-match/README.md +97 -0
- package/node_modules/balanced-match/index.js +62 -0
- package/node_modules/balanced-match/package.json +48 -0
- package/node_modules/concat-map/.travis.yml +4 -0
- package/node_modules/concat-map/LICENSE +18 -0
- package/node_modules/concat-map/README.markdown +62 -0
- package/node_modules/concat-map/example/map.js +6 -0
- package/node_modules/concat-map/index.js +13 -0
- package/node_modules/concat-map/package.json +43 -0
- package/node_modules/concat-map/test/map.js +39 -0
- package/node_modules/ignore/LICENSE-MIT +21 -0
- package/node_modules/ignore/README.md +412 -0
- package/node_modules/ignore/index.d.ts +61 -0
- package/node_modules/ignore/index.js +636 -0
- package/node_modules/ignore/legacy.js +559 -0
- package/node_modules/ignore/package.json +74 -0
- package/node_modules/minimatch/LICENSE +15 -0
- package/node_modules/minimatch/README.md +230 -0
- package/node_modules/minimatch/minimatch.js +947 -0
- package/node_modules/minimatch/node_modules/brace-expansion/LICENSE +21 -0
- package/node_modules/minimatch/node_modules/brace-expansion/README.md +129 -0
- package/node_modules/minimatch/node_modules/brace-expansion/index.js +201 -0
- package/node_modules/minimatch/node_modules/brace-expansion/package.json +47 -0
- package/node_modules/minimatch/package.json +33 -0
- package/package.json +14 -5
- package/lib/aws/compute/function-nodejs.d.ts +0 -55
- package/lib/aws/compute/function-nodejs.js +0 -70
|
@@ -0,0 +1,685 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var _a, _b, _c;
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.RepositoryEncryption = exports.TagMutability = exports.Repository = exports.RepositoryBase = void 0;
|
|
5
|
+
const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
|
|
6
|
+
// https://github.com/aws/aws-cdk/blob/v2.186.0/packages/aws-cdk-lib/aws-ecr/lib/repository.ts
|
|
7
|
+
const node_os_1 = require("node:os");
|
|
8
|
+
const provider_aws_1 = require("@cdktf/provider-aws");
|
|
9
|
+
const cdktf_1 = require("cdktf");
|
|
10
|
+
const ecr_lifecycle_1 = require("./ecr-lifecycle");
|
|
11
|
+
const arn_1 = require("../arn");
|
|
12
|
+
const aws_construct_1 = require("../aws-construct");
|
|
13
|
+
const aws_stack_1 = require("../aws-stack");
|
|
14
|
+
const iam = require("../iam");
|
|
15
|
+
const events = require("../notify");
|
|
16
|
+
/**
|
|
17
|
+
* Base class for ECR repository. Reused between imported repositories and owned repositories.
|
|
18
|
+
*/
|
|
19
|
+
class RepositoryBase extends aws_construct_1.AwsConstructBase {
|
|
20
|
+
constructor() {
|
|
21
|
+
super(...arguments);
|
|
22
|
+
this.REPO_PULL_ACTIONS = [
|
|
23
|
+
"ecr:BatchCheckLayerAvailability",
|
|
24
|
+
"ecr:GetDownloadUrlForLayer",
|
|
25
|
+
"ecr:BatchGetImage",
|
|
26
|
+
];
|
|
27
|
+
// https://docs.aws.amazon.com/AmazonECR/latest/userguide/image-push.html#image-push-iam
|
|
28
|
+
this.REPO_PUSH_ACTIONS = [
|
|
29
|
+
"ecr:CompleteLayerUpload",
|
|
30
|
+
"ecr:UploadLayerPart",
|
|
31
|
+
"ecr:InitiateLayerUpload",
|
|
32
|
+
"ecr:BatchCheckLayerAvailability",
|
|
33
|
+
"ecr:PutImage",
|
|
34
|
+
];
|
|
35
|
+
}
|
|
36
|
+
get outputs() {
|
|
37
|
+
return {
|
|
38
|
+
repositoryName: this.repositoryName,
|
|
39
|
+
repositoryArn: this.repositoryArn,
|
|
40
|
+
repositoryUri: this.repositoryUri,
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* The URI of this repository (represents the latest image):
|
|
45
|
+
*
|
|
46
|
+
* ACCOUNT.dkr.ecr.REGION.amazonaws.com/REPOSITORY
|
|
47
|
+
*
|
|
48
|
+
*/
|
|
49
|
+
get repositoryUri() {
|
|
50
|
+
return this.repositoryUriForTag();
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* The URI of this repository's registry:
|
|
54
|
+
*
|
|
55
|
+
* ACCOUNT.dkr.ecr.REGION.amazonaws.com
|
|
56
|
+
*
|
|
57
|
+
*/
|
|
58
|
+
get registryUri() {
|
|
59
|
+
const parts = this.stack.splitArn(this.repositoryArn, arn_1.ArnFormat.SLASH_RESOURCE_NAME);
|
|
60
|
+
return `${parts.account}.dkr.ecr.${parts.region}.${this.stack.urlSuffix}`;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Returns the URL of the repository. Can be used in `docker push/pull`.
|
|
64
|
+
*
|
|
65
|
+
* ACCOUNT.dkr.ecr.REGION.amazonaws.com/REPOSITORY[:TAG]
|
|
66
|
+
*
|
|
67
|
+
* @param tag Optional image tag
|
|
68
|
+
*/
|
|
69
|
+
repositoryUriForTag(tag) {
|
|
70
|
+
const tagSuffix = tag ? `:${tag}` : "";
|
|
71
|
+
return this.repositoryUriWithSuffix(tagSuffix);
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Returns the URL of the repository. Can be used in `docker push/pull`.
|
|
75
|
+
*
|
|
76
|
+
* ACCOUNT.dkr.ecr.REGION.amazonaws.com/REPOSITORY[@DIGEST]
|
|
77
|
+
*
|
|
78
|
+
* @param digest Optional image digest
|
|
79
|
+
*/
|
|
80
|
+
repositoryUriForDigest(digest) {
|
|
81
|
+
const digestSuffix = digest ? `@${digest}` : "";
|
|
82
|
+
return this.repositoryUriWithSuffix(digestSuffix);
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Returns the URL of the repository. Can be used in `docker push/pull`.
|
|
86
|
+
*
|
|
87
|
+
* ACCOUNT.dkr.ecr.REGION.amazonaws.com/REPOSITORY[:TAG]
|
|
88
|
+
* ACCOUNT.dkr.ecr.REGION.amazonaws.com/REPOSITORY[@DIGEST]
|
|
89
|
+
*
|
|
90
|
+
* @param tagOrDigest Optional image tag or digest (digests must start with `sha256:`)
|
|
91
|
+
*/
|
|
92
|
+
repositoryUriForTagOrDigest(tagOrDigest) {
|
|
93
|
+
if (tagOrDigest?.startsWith("sha256:")) {
|
|
94
|
+
return this.repositoryUriForDigest(tagOrDigest);
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
return this.repositoryUriForTag(tagOrDigest);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Returns the repository URI, with an appended suffix, if provided.
|
|
102
|
+
* @param suffix An image tag or an image digest.
|
|
103
|
+
* @private
|
|
104
|
+
*/
|
|
105
|
+
repositoryUriWithSuffix(suffix) {
|
|
106
|
+
const parts = this.stack.splitArn(this.repositoryArn, arn_1.ArnFormat.SLASH_RESOURCE_NAME);
|
|
107
|
+
return `${parts.account}.dkr.ecr.${parts.region}.${this.stack.urlSuffix}/${this.repositoryName}${suffix}`;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Define a CloudWatch event that triggers when something happens to this repository
|
|
111
|
+
*
|
|
112
|
+
* Requires that there exists at least one CloudTrail Trail in your account
|
|
113
|
+
* that captures the event. This method will not create the Trail.
|
|
114
|
+
*
|
|
115
|
+
* @param id The id of the rule
|
|
116
|
+
* @param options Options for adding the rule
|
|
117
|
+
*/
|
|
118
|
+
onCloudTrailEvent(id, options = {}) {
|
|
119
|
+
const rule = new events.Rule(this, id, options);
|
|
120
|
+
rule.addTarget(options.target);
|
|
121
|
+
rule.addEventPattern({
|
|
122
|
+
source: ["aws.ecr"],
|
|
123
|
+
detailType: ["AWS API Call via CloudTrail"],
|
|
124
|
+
detail: {
|
|
125
|
+
requestParameters: {
|
|
126
|
+
repositoryName: [this.repositoryName],
|
|
127
|
+
},
|
|
128
|
+
},
|
|
129
|
+
});
|
|
130
|
+
return rule;
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Defines an AWS CloudWatch event rule that can trigger a target when an image is pushed to this
|
|
134
|
+
* repository.
|
|
135
|
+
*
|
|
136
|
+
* Requires that there exists at least one CloudTrail Trail in your account
|
|
137
|
+
* that captures the event. This method will not create the Trail.
|
|
138
|
+
*
|
|
139
|
+
* @param id The id of the rule
|
|
140
|
+
* @param options Options for adding the rule
|
|
141
|
+
*/
|
|
142
|
+
onCloudTrailImagePushed(id, options = {}) {
|
|
143
|
+
const rule = this.onCloudTrailEvent(id, options);
|
|
144
|
+
rule.addEventPattern({
|
|
145
|
+
detail: {
|
|
146
|
+
eventName: ["PutImage"],
|
|
147
|
+
requestParameters: {
|
|
148
|
+
imageTag: options.imageTag ? [options.imageTag] : undefined,
|
|
149
|
+
},
|
|
150
|
+
},
|
|
151
|
+
});
|
|
152
|
+
return rule;
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Defines an AWS CloudWatch event rule that can trigger a target when an image scan is completed
|
|
156
|
+
*
|
|
157
|
+
*
|
|
158
|
+
* @param id The id of the rule
|
|
159
|
+
* @param options Options for adding the rule
|
|
160
|
+
*/
|
|
161
|
+
onImageScanCompleted(id, options = {}) {
|
|
162
|
+
const rule = new events.Rule(this, id, options);
|
|
163
|
+
rule.addTarget(options.target);
|
|
164
|
+
rule.addEventPattern({
|
|
165
|
+
source: ["aws.ecr"],
|
|
166
|
+
detailType: ["ECR Image Scan"],
|
|
167
|
+
detail: {
|
|
168
|
+
"repository-name": [this.repositoryName],
|
|
169
|
+
"scan-status": ["COMPLETE"],
|
|
170
|
+
"image-tags": options.imageTags ?? undefined,
|
|
171
|
+
},
|
|
172
|
+
});
|
|
173
|
+
return rule;
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Defines a CloudWatch event rule which triggers for repository events. Use
|
|
177
|
+
* `rule.addEventPattern(pattern)` to specify a filter.
|
|
178
|
+
*/
|
|
179
|
+
onEvent(id, options = {}) {
|
|
180
|
+
const rule = new events.Rule(this, id, options);
|
|
181
|
+
rule.addEventPattern({
|
|
182
|
+
source: ["aws.ecr"],
|
|
183
|
+
detail: {
|
|
184
|
+
"repository-name": [this.repositoryName],
|
|
185
|
+
},
|
|
186
|
+
});
|
|
187
|
+
rule.addTarget(options.target);
|
|
188
|
+
return rule;
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* Grant the given principal identity permissions to perform the actions on this repository
|
|
192
|
+
*/
|
|
193
|
+
grant(grantee, ...actions) {
|
|
194
|
+
// TODO: Implement cross-account principal logic from CDK
|
|
195
|
+
return iam.Grant.addToPrincipalOrResource({
|
|
196
|
+
grantee,
|
|
197
|
+
actions,
|
|
198
|
+
resourceArns: [this.repositoryArn],
|
|
199
|
+
resource: this,
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* Grant the given identity permissions to read the images in this repository
|
|
204
|
+
*/
|
|
205
|
+
grantRead(grantee) {
|
|
206
|
+
return this.grant(grantee, "ecr:DescribeRepositories", "ecr:DescribeImages");
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* Grant the given identity permissions to use the images in this repository
|
|
210
|
+
*/
|
|
211
|
+
grantPull(grantee) {
|
|
212
|
+
const ret = this.grant(grantee, ...this.REPO_PULL_ACTIONS);
|
|
213
|
+
iam.Grant.addToPrincipal({
|
|
214
|
+
grantee,
|
|
215
|
+
actions: ["ecr:GetAuthorizationToken"],
|
|
216
|
+
resourceArns: ["*"],
|
|
217
|
+
scope: this,
|
|
218
|
+
});
|
|
219
|
+
return ret;
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* Grant the given identity permissions to use the images in this repository
|
|
223
|
+
*/
|
|
224
|
+
grantPush(grantee) {
|
|
225
|
+
const ret = this.grant(grantee, ...this.REPO_PUSH_ACTIONS);
|
|
226
|
+
iam.Grant.addToPrincipal({
|
|
227
|
+
grantee,
|
|
228
|
+
actions: ["ecr:GetAuthorizationToken"],
|
|
229
|
+
resourceArns: ["*"],
|
|
230
|
+
scope: this,
|
|
231
|
+
});
|
|
232
|
+
return ret;
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* Grant the given identity permissions to pull and push images to this repository.
|
|
236
|
+
*/
|
|
237
|
+
grantPullPush(grantee) {
|
|
238
|
+
const ret = this.grant(grantee, ...this.REPO_PULL_ACTIONS, ...this.REPO_PUSH_ACTIONS);
|
|
239
|
+
iam.Grant.addToPrincipal({
|
|
240
|
+
grantee,
|
|
241
|
+
actions: ["ecr:GetAuthorizationToken"],
|
|
242
|
+
resourceArns: ["*"],
|
|
243
|
+
scope: this,
|
|
244
|
+
});
|
|
245
|
+
return ret;
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
exports.RepositoryBase = RepositoryBase;
|
|
249
|
+
_a = JSII_RTTI_SYMBOL_1;
|
|
250
|
+
RepositoryBase[_a] = { fqn: "terraconstructs.aws.storage.RepositoryBase", version: "0.1.0" };
|
|
251
|
+
/**
|
|
252
|
+
* Define an ECR repository
|
|
253
|
+
*/
|
|
254
|
+
class Repository extends RepositoryBase {
|
|
255
|
+
/**
|
|
256
|
+
* Import a repository
|
|
257
|
+
*/
|
|
258
|
+
static fromRepositoryAttributes(scope, id, attrs) {
|
|
259
|
+
class Import extends RepositoryBase {
|
|
260
|
+
constructor() {
|
|
261
|
+
super(...arguments);
|
|
262
|
+
this.repositoryName = attrs.repositoryName;
|
|
263
|
+
this.repositoryArn = attrs.repositoryArn;
|
|
264
|
+
}
|
|
265
|
+
addToResourcePolicy(_statement) {
|
|
266
|
+
// dropped
|
|
267
|
+
return { statementAdded: false };
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
return new Import(scope, id);
|
|
271
|
+
}
|
|
272
|
+
static fromRepositoryArn(scope, id, repositoryArn) {
|
|
273
|
+
if (cdktf_1.Token.isUnresolved(repositoryArn)) {
|
|
274
|
+
// TODO: UnscopedValidationError
|
|
275
|
+
throw new Error('"repositoryArn" is a late-bound value, and therefore "repositoryName" is required. Use `fromRepositoryAttributes` instead');
|
|
276
|
+
}
|
|
277
|
+
validateRepositoryArn();
|
|
278
|
+
const repositoryName = repositoryArn.split("/").slice(1).join("/");
|
|
279
|
+
class Import extends RepositoryBase {
|
|
280
|
+
constructor() {
|
|
281
|
+
super(...arguments);
|
|
282
|
+
this.repositoryName = repositoryName;
|
|
283
|
+
this.repositoryArn = repositoryArn;
|
|
284
|
+
}
|
|
285
|
+
addToResourcePolicy(_statement) {
|
|
286
|
+
// dropped
|
|
287
|
+
return { statementAdded: false };
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
return new Import(scope, id, {
|
|
291
|
+
environmentFromArn: repositoryArn,
|
|
292
|
+
});
|
|
293
|
+
function validateRepositoryArn() {
|
|
294
|
+
const splitArn = repositoryArn.split(":");
|
|
295
|
+
if (!splitArn[splitArn.length - 1].startsWith("repository/")) {
|
|
296
|
+
// TODO: UnscopedValidationError
|
|
297
|
+
throw new Error(`Repository arn should be in the format 'arn:<PARTITION>:ecr:<REGION>:<ACCOUNT>:repository/<NAME>', got ${repositoryArn}.`);
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
static fromRepositoryName(scope, id, repositoryName) {
|
|
302
|
+
class Import extends RepositoryBase {
|
|
303
|
+
constructor() {
|
|
304
|
+
super(...arguments);
|
|
305
|
+
this.repositoryName = repositoryName;
|
|
306
|
+
this.repositoryArn = Repository.arnForLocalRepository(repositoryName, scope);
|
|
307
|
+
}
|
|
308
|
+
addToResourcePolicy(_statement) {
|
|
309
|
+
// dropped
|
|
310
|
+
return { statementAdded: false };
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
return new Import(scope, id);
|
|
314
|
+
}
|
|
315
|
+
/**
|
|
316
|
+
* Returns an ECR ARN for a repository that resides in the same account/region
|
|
317
|
+
* as the current stack.
|
|
318
|
+
*/
|
|
319
|
+
static arnForLocalRepository(repositoryName, scope, account) {
|
|
320
|
+
return aws_stack_1.AwsStack.ofAwsConstruct(scope).formatArn({
|
|
321
|
+
account,
|
|
322
|
+
service: "ecr",
|
|
323
|
+
resource: "repository",
|
|
324
|
+
resourceName: repositoryName,
|
|
325
|
+
});
|
|
326
|
+
}
|
|
327
|
+
static validateRepositoryName(physicalName) {
|
|
328
|
+
const repositoryName = physicalName;
|
|
329
|
+
if (!repositoryName || cdktf_1.Token.isUnresolved(repositoryName)) {
|
|
330
|
+
// the name is a late-bound value, not a defined string,
|
|
331
|
+
// so skip validation
|
|
332
|
+
return;
|
|
333
|
+
}
|
|
334
|
+
const errors = [];
|
|
335
|
+
// Rules codified from https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ecr-repository.html
|
|
336
|
+
if (repositoryName.length < 2 || repositoryName.length > 256) {
|
|
337
|
+
errors.push("Repository name must be at least 2 and no more than 256 characters");
|
|
338
|
+
}
|
|
339
|
+
const isPatternMatch = /^(?:[a-z0-9]+(?:[._-][a-z0-9]+)*\/)*[a-z0-9]+(?:[._-][a-z0-9]+)*$/.test(repositoryName);
|
|
340
|
+
if (!isPatternMatch) {
|
|
341
|
+
errors.push("Repository name must start with a letter and can only contain lowercase letters, numbers, hyphens, underscores, periods and forward slashes");
|
|
342
|
+
}
|
|
343
|
+
if (errors.length > 0) {
|
|
344
|
+
// TODO: UnscopedValidationError
|
|
345
|
+
throw new Error(`Invalid ECR repository name (value: ${repositoryName})${node_os_1.EOL}${errors.join(node_os_1.EOL)}`);
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
constructor(scope, id, props = {}) {
|
|
349
|
+
super(scope, id, props);
|
|
350
|
+
this.lifecycleRules = new Array();
|
|
351
|
+
const name = props.repositoryName ||
|
|
352
|
+
this.stack.uniqueResourceName(this, {
|
|
353
|
+
// TODO: Repo name can't start with a number...
|
|
354
|
+
// prefix: this.gridUUID,
|
|
355
|
+
//Repository name must start with a letter and can only contain lowercase letters, numbers, hyphens, underscores, periods and forward slashes
|
|
356
|
+
maxLength: 256,
|
|
357
|
+
lowerCase: true,
|
|
358
|
+
allowedSpecialCharacters: "-_./",
|
|
359
|
+
separator: "-",
|
|
360
|
+
});
|
|
361
|
+
Repository.validateRepositoryName(name);
|
|
362
|
+
this.resource = new provider_aws_1.ecrRepository.EcrRepository(this, "Resource", {
|
|
363
|
+
name: name,
|
|
364
|
+
imageScanningConfiguration: props.imageScanOnPush !== undefined
|
|
365
|
+
? { scanOnPush: props.imageScanOnPush }
|
|
366
|
+
: undefined,
|
|
367
|
+
imageTagMutability: props.imageTagMutability || undefined,
|
|
368
|
+
encryptionConfiguration: this.parseEncryption(props),
|
|
369
|
+
forceDelete: props.emptyOnDelete,
|
|
370
|
+
// TODO: implement retain policy by default?
|
|
371
|
+
// lifecycle: {
|
|
372
|
+
// preventDestroy: props.emptyOnDelete === false,
|
|
373
|
+
// },
|
|
374
|
+
});
|
|
375
|
+
if (props.lifecycleRegistryId) {
|
|
376
|
+
// TODO: Annotations.of(this).addWarningV2(...)
|
|
377
|
+
cdktf_1.Annotations.of(this).addWarning("lifecycleRegistryId is not supported by the Terraform AWS provider and will be ignored.");
|
|
378
|
+
}
|
|
379
|
+
if (props.lifecycleRules) {
|
|
380
|
+
props.lifecycleRules.forEach(this.addLifecycleRule.bind(this));
|
|
381
|
+
}
|
|
382
|
+
this.repositoryName = this.resource.name;
|
|
383
|
+
this.repositoryArn = this.resource.arn;
|
|
384
|
+
if (props.emptyOnDelete === false && props.autoDeleteImages) {
|
|
385
|
+
// TODO: ValidationError
|
|
386
|
+
throw new Error("Cannot use 'autoDeleteImages' property on a repository without setting forceDelete to 'true'.");
|
|
387
|
+
}
|
|
388
|
+
else if (props.autoDeleteImages) {
|
|
389
|
+
// TODO: Implement Custom Resource for auto-deleting images.
|
|
390
|
+
// this.enableAutoDeleteImages();
|
|
391
|
+
cdktf_1.Annotations.of(this).addWarning("autoDeleteImages is deprecated and not implemented. Use forceDelete instead.");
|
|
392
|
+
}
|
|
393
|
+
this.node.addValidation({
|
|
394
|
+
validate: () => this.policyDocument?.validateForResourcePolicy() ?? [],
|
|
395
|
+
});
|
|
396
|
+
}
|
|
397
|
+
/**
|
|
398
|
+
* Add a policy statement to the repository's resource policy.
|
|
399
|
+
*/
|
|
400
|
+
addToResourcePolicy(statement) {
|
|
401
|
+
if (statement.resources.length) {
|
|
402
|
+
// TODO: Annotations.of(this).addWarningV2('@aws-cdk/aws-ecr:noResourceStatements, ...)
|
|
403
|
+
cdktf_1.Annotations.of(this).addWarning("ECR resource policy does not allow resource statements.");
|
|
404
|
+
}
|
|
405
|
+
if (this.policyDocument === undefined) {
|
|
406
|
+
this.policyDocument = new iam.PolicyDocument(this, "PolicyDocument");
|
|
407
|
+
new provider_aws_1.ecrRepositoryPolicy.EcrRepositoryPolicy(this, "Policy", {
|
|
408
|
+
repository: this.repositoryName,
|
|
409
|
+
policy: this.policyDocument.json,
|
|
410
|
+
});
|
|
411
|
+
}
|
|
412
|
+
this.policyDocument.addStatements(statement);
|
|
413
|
+
return { statementAdded: true, policyDependable: this.policyDocument };
|
|
414
|
+
}
|
|
415
|
+
/**
|
|
416
|
+
* The URI of this repository's registry:
|
|
417
|
+
*
|
|
418
|
+
* ACCOUNT.dkr.ecr.REGION.amazonaws.com
|
|
419
|
+
*
|
|
420
|
+
*/
|
|
421
|
+
get registryUri() {
|
|
422
|
+
return this.resource.registryId;
|
|
423
|
+
}
|
|
424
|
+
/**
|
|
425
|
+
* Returns the URL of the repository. Can be used in `docker push/pull`.
|
|
426
|
+
*
|
|
427
|
+
* ACCOUNT.dkr.ecr.REGION.amazonaws.com/REPOSITORY[:TAG]
|
|
428
|
+
*
|
|
429
|
+
* @param tag Optional image tag
|
|
430
|
+
*/
|
|
431
|
+
repositoryUriForTag(tag) {
|
|
432
|
+
const tagSuffix = tag ? `:${tag}` : "";
|
|
433
|
+
return this.resource.repositoryUrl + tagSuffix;
|
|
434
|
+
}
|
|
435
|
+
/**
|
|
436
|
+
* Returns the URL of the repository. Can be used in `docker push/pull`.
|
|
437
|
+
*
|
|
438
|
+
* ACCOUNT.dkr.ecr.REGION.amazonaws.com/REPOSITORY[@DIGEST]
|
|
439
|
+
*
|
|
440
|
+
* @param digest Optional image digest
|
|
441
|
+
*/
|
|
442
|
+
repositoryUriForDigest(digest) {
|
|
443
|
+
const digestSuffix = digest ? `@${digest}` : "";
|
|
444
|
+
return this.resource.repositoryUrl + digestSuffix;
|
|
445
|
+
}
|
|
446
|
+
/**
|
|
447
|
+
* Add a life cycle rule to the repository
|
|
448
|
+
*
|
|
449
|
+
* Life cycle rules automatically expire images from the repository that match
|
|
450
|
+
* certain conditions.
|
|
451
|
+
*/
|
|
452
|
+
addLifecycleRule(rule) {
|
|
453
|
+
// Validate rule here so users get errors at the expected location
|
|
454
|
+
if (rule.tagStatus === undefined) {
|
|
455
|
+
rule = {
|
|
456
|
+
...rule,
|
|
457
|
+
tagStatus: rule.tagPrefixList === undefined && rule.tagPatternList === undefined
|
|
458
|
+
? ecr_lifecycle_1.TagStatus.ANY
|
|
459
|
+
: ecr_lifecycle_1.TagStatus.TAGGED,
|
|
460
|
+
};
|
|
461
|
+
}
|
|
462
|
+
if (rule.tagStatus === ecr_lifecycle_1.TagStatus.TAGGED &&
|
|
463
|
+
(rule.tagPrefixList === undefined || rule.tagPrefixList.length === 0) &&
|
|
464
|
+
(rule.tagPatternList === undefined || rule.tagPatternList.length === 0)) {
|
|
465
|
+
// TODO: ValidationError
|
|
466
|
+
throw new Error("TagStatus.Tagged requires the specification of a tagPrefixList or a tagPatternList");
|
|
467
|
+
}
|
|
468
|
+
if (rule.tagStatus !== ecr_lifecycle_1.TagStatus.TAGGED &&
|
|
469
|
+
(rule.tagPrefixList !== undefined || rule.tagPatternList !== undefined)) {
|
|
470
|
+
// TODO: ValidationError
|
|
471
|
+
throw new Error("tagPrefixList and tagPatternList can only be specified when tagStatus is set to Tagged");
|
|
472
|
+
}
|
|
473
|
+
if (rule.tagPrefixList !== undefined && rule.tagPatternList !== undefined) {
|
|
474
|
+
// TODO: ValidationError
|
|
475
|
+
throw new Error("Both tagPrefixList and tagPatternList cannot be specified together in a rule");
|
|
476
|
+
}
|
|
477
|
+
if (rule.tagPatternList !== undefined) {
|
|
478
|
+
rule.tagPatternList.forEach((pattern) => {
|
|
479
|
+
const splitPatternLength = pattern.split("*").length;
|
|
480
|
+
if (splitPatternLength > 5) {
|
|
481
|
+
// TODO: ValidationError
|
|
482
|
+
throw new Error(`A tag pattern cannot contain more than four wildcard characters (*), pattern: ${pattern}, counts: ${splitPatternLength - 1}`);
|
|
483
|
+
}
|
|
484
|
+
});
|
|
485
|
+
}
|
|
486
|
+
if ((rule.maxImageAge !== undefined) ===
|
|
487
|
+
(rule.maxImageCount !== undefined)) {
|
|
488
|
+
// TODO: ValidationError
|
|
489
|
+
throw new Error(`Life cycle rule must contain exactly one of 'maxImageAge' and 'maxImageCount', got: ${JSON.stringify(rule)}`);
|
|
490
|
+
}
|
|
491
|
+
if (rule.tagStatus === ecr_lifecycle_1.TagStatus.ANY &&
|
|
492
|
+
this.lifecycleRules.filter((r) => r.tagStatus === ecr_lifecycle_1.TagStatus.ANY).length >
|
|
493
|
+
0) {
|
|
494
|
+
// TODO: ValidationError
|
|
495
|
+
throw new Error("Life cycle can only have one TagStatus.Any rule");
|
|
496
|
+
}
|
|
497
|
+
this.lifecycleRules.push({ ...rule });
|
|
498
|
+
}
|
|
499
|
+
/**
|
|
500
|
+
* Render the life cycle policy object
|
|
501
|
+
*/
|
|
502
|
+
renderLifecyclePolicy() {
|
|
503
|
+
if (this.lifecycleRules.length === 0) {
|
|
504
|
+
return undefined;
|
|
505
|
+
}
|
|
506
|
+
const policy = {
|
|
507
|
+
rules: this.orderedLifecycleRules().map(renderLifecycleRule),
|
|
508
|
+
};
|
|
509
|
+
return this.stack.toJsonString(policy);
|
|
510
|
+
}
|
|
511
|
+
/**
|
|
512
|
+
* Return life cycle rules with automatic ordering applied.
|
|
513
|
+
*
|
|
514
|
+
* Also applies validation of the 'any' rule.
|
|
515
|
+
*/
|
|
516
|
+
orderedLifecycleRules() {
|
|
517
|
+
if (this.lifecycleRules.length === 0) {
|
|
518
|
+
return [];
|
|
519
|
+
}
|
|
520
|
+
const prioritizedRules = this.lifecycleRules.filter((r) => r.rulePriority !== undefined && r.tagStatus !== ecr_lifecycle_1.TagStatus.ANY);
|
|
521
|
+
const autoPrioritizedRules = this.lifecycleRules.filter((r) => r.rulePriority === undefined && r.tagStatus !== ecr_lifecycle_1.TagStatus.ANY);
|
|
522
|
+
const anyRules = this.lifecycleRules.filter((r) => r.tagStatus === ecr_lifecycle_1.TagStatus.ANY);
|
|
523
|
+
if (anyRules.length > 0 &&
|
|
524
|
+
anyRules[0].rulePriority !== undefined &&
|
|
525
|
+
autoPrioritizedRules.length > 0) {
|
|
526
|
+
// Supporting this is too complex for very little value. We just prohibit it.
|
|
527
|
+
// TODO: ValidationError
|
|
528
|
+
throw new Error("Cannot combine prioritized TagStatus.Any rule with unprioritized rules. Remove rulePriority from the 'Any' rule.");
|
|
529
|
+
}
|
|
530
|
+
const prios = prioritizedRules.map((r) => r.rulePriority);
|
|
531
|
+
let autoPrio = (prios.length > 0 ? Math.max(...prios) : 0) + 1;
|
|
532
|
+
const ret = new Array();
|
|
533
|
+
for (const rule of prioritizedRules
|
|
534
|
+
.concat(autoPrioritizedRules)
|
|
535
|
+
.concat(anyRules)) {
|
|
536
|
+
ret.push({
|
|
537
|
+
...rule,
|
|
538
|
+
rulePriority: rule.rulePriority ?? autoPrio++,
|
|
539
|
+
});
|
|
540
|
+
}
|
|
541
|
+
// Do validation on the final array--might still be wrong because the user supplied all prios, but incorrectly.
|
|
542
|
+
validateAnyRuleLast(ret);
|
|
543
|
+
return ret;
|
|
544
|
+
}
|
|
545
|
+
/**
|
|
546
|
+
* Set up key properties and return the Repository encryption property from the
|
|
547
|
+
* user's configuration.
|
|
548
|
+
*/
|
|
549
|
+
parseEncryption(props) {
|
|
550
|
+
// default based on whether encryptionKey is specified
|
|
551
|
+
const encryptionType = props.encryption ??
|
|
552
|
+
(props.encryptionKey
|
|
553
|
+
? RepositoryEncryption.KMS
|
|
554
|
+
: RepositoryEncryption.AES_256);
|
|
555
|
+
// if encryption key is set, encryption must be set to KMS.
|
|
556
|
+
if (encryptionType !== RepositoryEncryption.KMS && props.encryptionKey) {
|
|
557
|
+
// TODO: ValidationError
|
|
558
|
+
throw new Error(`encryptionKey is specified, so 'encryption' must be set to KMS (value: ${encryptionType.value})`);
|
|
559
|
+
}
|
|
560
|
+
if (encryptionType === RepositoryEncryption.AES_256) {
|
|
561
|
+
return undefined;
|
|
562
|
+
}
|
|
563
|
+
if (encryptionType === RepositoryEncryption.KMS) {
|
|
564
|
+
return [
|
|
565
|
+
{
|
|
566
|
+
encryptionType: "KMS",
|
|
567
|
+
kmsKey: props.encryptionKey?.keyArn,
|
|
568
|
+
},
|
|
569
|
+
];
|
|
570
|
+
}
|
|
571
|
+
// TODO: ValidationError
|
|
572
|
+
throw new Error(`Unexpected 'encryptionType': ${encryptionType}`);
|
|
573
|
+
}
|
|
574
|
+
/**
|
|
575
|
+
* Adds resource to the Terraform JSON output at Synth time.
|
|
576
|
+
*
|
|
577
|
+
* called by TerraformStack.prepareStack()
|
|
578
|
+
*/
|
|
579
|
+
toTerraform() {
|
|
580
|
+
/**
|
|
581
|
+
* A preparing resolve might add new resources to the stack
|
|
582
|
+
*/
|
|
583
|
+
const lifeCyclePolicy = this.renderLifecyclePolicy();
|
|
584
|
+
// ignore if undefined or already generated
|
|
585
|
+
if (lifeCyclePolicy && !this.node.tryFindChild("LifecyclePolicy")) {
|
|
586
|
+
new provider_aws_1.ecrLifecyclePolicy.EcrLifecyclePolicy(this, "LifecyclePolicy", {
|
|
587
|
+
repository: this.repositoryName,
|
|
588
|
+
policy: lifeCyclePolicy,
|
|
589
|
+
});
|
|
590
|
+
}
|
|
591
|
+
return {};
|
|
592
|
+
}
|
|
593
|
+
}
|
|
594
|
+
exports.Repository = Repository;
|
|
595
|
+
_b = JSII_RTTI_SYMBOL_1;
|
|
596
|
+
Repository[_b] = { fqn: "terraconstructs.aws.storage.Repository", version: "0.1.0" };
|
|
597
|
+
function validateAnyRuleLast(rules) {
|
|
598
|
+
const anyRules = rules.filter((r) => r.tagStatus === ecr_lifecycle_1.TagStatus.ANY);
|
|
599
|
+
if (anyRules.length === 1) {
|
|
600
|
+
const maxPrio = Math.max(...rules.map((r) => r.rulePriority));
|
|
601
|
+
if (anyRules[0].rulePriority !== maxPrio) {
|
|
602
|
+
// TODO: UnscopedValidationError
|
|
603
|
+
throw new Error(`TagStatus.Any rule must have highest priority, has ${anyRules[0].rulePriority} which is smaller than ${maxPrio}`);
|
|
604
|
+
}
|
|
605
|
+
}
|
|
606
|
+
}
|
|
607
|
+
/**
|
|
608
|
+
* Render the lifecycle rule to JSON
|
|
609
|
+
*/
|
|
610
|
+
function renderLifecycleRule(rule) {
|
|
611
|
+
return {
|
|
612
|
+
rulePriority: rule.rulePriority,
|
|
613
|
+
description: rule.description,
|
|
614
|
+
selection: {
|
|
615
|
+
tagStatus: rule.tagStatus || ecr_lifecycle_1.TagStatus.ANY,
|
|
616
|
+
tagPrefixList: rule.tagPrefixList,
|
|
617
|
+
tagPatternList: rule.tagPatternList,
|
|
618
|
+
countType: rule.maxImageAge !== undefined
|
|
619
|
+
? CountType.SINCE_IMAGE_PUSHED
|
|
620
|
+
: CountType.IMAGE_COUNT_MORE_THAN,
|
|
621
|
+
countNumber: rule.maxImageAge?.toDays() ?? rule.maxImageCount,
|
|
622
|
+
countUnit: rule.maxImageAge !== undefined ? "days" : undefined,
|
|
623
|
+
},
|
|
624
|
+
action: {
|
|
625
|
+
type: "expire",
|
|
626
|
+
},
|
|
627
|
+
};
|
|
628
|
+
}
|
|
629
|
+
/**
|
|
630
|
+
* Select images based on counts
|
|
631
|
+
*/
|
|
632
|
+
var CountType;
|
|
633
|
+
(function (CountType) {
|
|
634
|
+
/**
|
|
635
|
+
* Set a limit on the number of images in your repository
|
|
636
|
+
*/
|
|
637
|
+
CountType["IMAGE_COUNT_MORE_THAN"] = "imageCountMoreThan";
|
|
638
|
+
/**
|
|
639
|
+
* Set an age limit on the images in your repository
|
|
640
|
+
*/
|
|
641
|
+
CountType["SINCE_IMAGE_PUSHED"] = "sinceImagePushed";
|
|
642
|
+
})(CountType || (CountType = {}));
|
|
643
|
+
/**
|
|
644
|
+
* The tag mutability setting for your repository.
|
|
645
|
+
*/
|
|
646
|
+
var TagMutability;
|
|
647
|
+
(function (TagMutability) {
|
|
648
|
+
/**
|
|
649
|
+
* allow image tags to be overwritten.
|
|
650
|
+
*/
|
|
651
|
+
TagMutability["MUTABLE"] = "MUTABLE";
|
|
652
|
+
/**
|
|
653
|
+
* all image tags within the repository will be immutable which will prevent them from being overwritten.
|
|
654
|
+
*/
|
|
655
|
+
TagMutability["IMMUTABLE"] = "IMMUTABLE";
|
|
656
|
+
})(TagMutability || (exports.TagMutability = TagMutability = {}));
|
|
657
|
+
/**
|
|
658
|
+
* Indicates whether server-side encryption is enabled for the object, and whether that encryption is
|
|
659
|
+
* from the AWS Key Management Service (AWS KMS) or from Amazon S3 managed encryption (SSE-S3).
|
|
660
|
+
* @see https://docs.aws.amazon.com/AmazonS3/latest/dev/UsingMetadata.html#SysMetadata
|
|
661
|
+
*/
|
|
662
|
+
class RepositoryEncryption {
|
|
663
|
+
/**
|
|
664
|
+
* @param value the string value of the encryption
|
|
665
|
+
*/
|
|
666
|
+
constructor(value) {
|
|
667
|
+
this.value = value;
|
|
668
|
+
}
|
|
669
|
+
}
|
|
670
|
+
exports.RepositoryEncryption = RepositoryEncryption;
|
|
671
|
+
_c = JSII_RTTI_SYMBOL_1;
|
|
672
|
+
RepositoryEncryption[_c] = { fqn: "terraconstructs.aws.storage.RepositoryEncryption", version: "0.1.0" };
|
|
673
|
+
/**
|
|
674
|
+
* 'AES256'
|
|
675
|
+
*/
|
|
676
|
+
RepositoryEncryption.AES_256 = new RepositoryEncryption("AES256");
|
|
677
|
+
/**
|
|
678
|
+
* 'KMS'
|
|
679
|
+
*/
|
|
680
|
+
RepositoryEncryption.KMS = new RepositoryEncryption("KMS");
|
|
681
|
+
/**
|
|
682
|
+
* 'KMS_DSSE'
|
|
683
|
+
*/
|
|
684
|
+
RepositoryEncryption.KMS_DSSE = new RepositoryEncryption("KMS_DSSE");
|
|
685
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZWNyLXJlcG9zaXRvcnkuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvYXdzL3N0b3JhZ2UvZWNyLXJlcG9zaXRvcnkudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSw4RkFBOEY7QUFFOUYscUNBQThCO0FBQzlCLHNEQUk2QjtBQUM3QixpQ0FBMkM7QUFFM0MsbURBQTJEO0FBQzNELGdDQUFtQztBQUNuQyxvREFBdUU7QUFDdkUsNENBQXdDO0FBRXhDLDhCQUE4QjtBQUM5QixvQ0FBb0M7QUFpSXBDOztHQUVHO0FBQ0gsTUFBc0IsY0FDcEIsU0FBUSxnQ0FBZ0I7SUFEMUI7O1FBSW1CLHNCQUFpQixHQUFhO1lBQzdDLGlDQUFpQztZQUNqQyw0QkFBNEI7WUFDNUIsbUJBQW1CO1NBQ3BCLENBQUM7UUFFRix3RkFBd0Y7UUFDdkUsc0JBQWlCLEdBQWE7WUFDN0MseUJBQXlCO1lBQ3pCLHFCQUFxQjtZQUNyQix5QkFBeUI7WUFDekIsaUNBQWlDO1lBQ2pDLGNBQWM7U0FDZixDQUFDO0tBOFFIO0lBbFFDLElBQVcsT0FBTztRQUNoQixPQUFPO1lBQ0wsY0FBYyxFQUFFLElBQUksQ0FBQyxjQUFjO1lBQ25DLGFBQWEsRUFBRSxJQUFJLENBQUMsYUFBYTtZQUNqQyxhQUFhLEVBQUUsSUFBSSxDQUFDLGFBQWE7U0FDbEMsQ0FBQztJQUNKLENBQUM7SUFTRDs7Ozs7T0FLRztJQUNILElBQVcsYUFBYTtRQUN0QixPQUFPLElBQUksQ0FBQyxtQkFBbUIsRUFBRSxDQUFDO0lBQ3BDLENBQUM7SUFFRDs7Ozs7T0FLRztJQUNILElBQVcsV0FBVztRQUNwQixNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FDL0IsSUFBSSxDQUFDLGFBQWEsRUFDbEIsZUFBUyxDQUFDLG1CQUFtQixDQUM5QixDQUFDO1FBQ0YsT0FBTyxHQUFHLEtBQUssQ0FBQyxPQUFPLFlBQVksS0FBSyxDQUFDLE1BQU0sSUFBSSxJ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YUFBYTtJQUN2Qjs7T0FFRztJQUNILG9DQUFtQixDQUFBO0lBRW5COztPQUVHO0lBQ0gsd0NBQXVCLENBQUE7QUFDekIsQ0FBQyxFQVZXLGFBQWEsNkJBQWIsYUFBYSxRQVV4QjtBQUVEOzs7O0dBSUc7QUFDSCxNQUFhLG9CQUFvQjtJQWMvQjs7T0FFRztJQUNILFlBQXNDLEtBQWE7UUFBYixVQUFLLEdBQUwsS0FBSyxDQUFRO0lBQUcsQ0FBQzs7QUFqQnpELG9EQWtCQzs7O0FBakJDOztHQUVHO0FBQ29CLDRCQUFPLEdBQUcsSUFBSSxvQkFBb0IsQ0FBQyxRQUFRLENBQUMsQ0FBQztBQUNwRTs7R0FFRztBQUNvQix3QkFBRyxHQUFHLElBQUksb0JBQW9CLENBQUMsS0FBSyxDQUFDLENBQUM7QUFDN0Q7O0dBRUc7QUFDb0IsNkJBQVEsR0FBRyxJQUFJLG9CQUFvQixDQUFDLFVBQVUsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLy8gaHR0cHM6Ly9naXRodWIuY29tL2F3cy9hd3MtY2RrL2Jsb2IvdjIuMTg2LjAvcGFja2FnZXMvYXdzLWNkay1saWIvYXdzLWVjci9saWIvcmVwb3NpdG9yeS50c1xuXG5pbXBvcnQgeyBFT0wgfSBmcm9tIFwibm9kZTpvc1wiO1xuaW1wb3J0IHtcbiAgZWNyTGlmZWN5Y2xlUG9saWN5LFxuICBlY3JSZXBvc2l0b3J5LFxuICBlY3JSZXBvc2l0b3J5UG9saWN5LFxufSBmcm9tIFwiQGNka3RmL3Byb3ZpZGVyLWF3c1wiO1xuaW1wb3J0IHsgQW5ub3RhdGlvbnMsIFRva2VuIH0gZnJvbSBcImNka3RmXCI7XG5pbXBvcnQgeyBJQ29uc3RydWN0LCBDb25zdHJ1Y3QgfSBmcm9tIFwiY29uc3RydWN0c1wiO1xuaW1wb3J0IHsgTGlmZWN5Y2xlUnVsZSwgVGFnU3RhdHVzIH0gZnJvbSBcIi4vZWNyLWxpZmVjeWNsZVwiO1xuaW1wb3J0IHsgQXJuRm9ybWF0IH0gZnJvbSBcIi4uL2FyblwiO1xuaW1wb3J0IHsgQXdzQ29uc3RydWN0QmFzZSwgQXdzQ29uc3RydWN0UHJvcHMgfSBmcm9tIFwiLi4vYXdzLWNvbnN0cnVjdFwiO1xuaW1wb3J0IHsgQXdzU3RhY2sgfSBmcm9tIFwiLi4vYXdzLXN0YWNrXCI7XG5pbXBvcnQgKiBhcyBlbmNyeXB0aW9uIGZyb20gXCIuLi9lbmNyeXB0aW9uXCI7XG5pbXBvcnQgKiBhcyBpYW0gZnJvbSBcIi4uL2lhbVwiO1xuaW1wb3J0ICogYXMgZXZlbnRzIGZyb20gXCIuLi9ub3RpZnlcIjtcblxuLyoqXG4gKiBSZXByZXNlbnRzIGFuIEVDUiByZXBvc2l0b3J5LlxuICovXG5leHBvcnQgaW50ZXJmYWNlIElSZXBvc2l0b3J5IGV4dGVuZHMgaWFtLklBd3NDb25zdHJ1Y3RXaXRoUG9saWN5IHtcbiAgLyoqXG4gICAqIFRoZSBuYW1lIG9mIHRoZSByZXBvc2l0b3J5XG4gICAqIEBhdHRyaWJ1dGVcbiAgICovXG4gIHJlYWRvbmx5IHJlcG9zaXRvcnlOYW1lOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSBBUk4gb2YgdGhlIHJlcG9zaXRvcnlcbiAgICogQGF0dHJpYnV0ZVxuICAgKi9cbiAgcmVhZG9ubHkgcmVwb3NpdG9yeUFybjogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaGUgVVJJIG9mIHRoaXMgcmVwb3NpdG9yeSAocmVwcmVzZW50cyB0aGUgbGF0ZXN0IGltYWdlKTpcbiAgICpcbiAgICogICAgQUNDT1VOVC5ka3IuZWNyLlJFR0lPTi5hbWF6b25hd3MuY29tL1JFUE9TSVRPUllcbiAgICpcbiAgICogQGF0dHJpYnV0ZVxuICAgKi9cbiAgcmVhZG9ubHkgcmVwb3NpdG9yeVVyaTogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaGUgVVJJIG9mIHRoaXMgcmVwb3NpdG9yeSdzIHJlZ2lzdHJ5OlxuICAgKlxuICAgKiAgICBBQ0NPVU5ULmRrci5lY3IuUkVHSU9OLmFtYXpvbmF3cy5jb21cbiAgICpcbiAgICogQGF0dHJpYnV0ZVxuICAgKi9cbiAgcmVhZG9ubHkgcmVnaXN0cnlVcmk6IHN0cmluZztcblxuICAvKipcbiAgICogUmV0dXJucyB0aGUgVVJJIG9mIHRoZSByZXBvc2l0b3J5IGZvciBhIGNlcnRhaW4gdGFnLiBDYW4gYmUgdXNlZCBpbiBgZG9ja2VyIHB1c2gvcHVsbGAuXG4gICAqXG4gICAqICAgIEFDQ09VTlQuZGtyLmVjci5SRUdJT04uYW1hem9uYXdzLmNvbS9SRVBPU0lUT1JZWzpUQUddXG4gICAqXG4gICAqIEBwYXJhbSB0YWcgSW1hZ2UgdGFnIHRvIHVzZSAodG9vbHMgdXN1YWxseSBkZWZhdWx0IHRvIFwibGF0ZXN0XCIgaWYgb21pdHRlZClcbiAgICovXG4gIHJlcG9zaXRvcnlVcmlGb3JUYWcodGFnPzogc3RyaW5nKTogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHRoZSBVUkkgb2YgdGhlIHJlcG9zaXRvcnkgZm9yIGEgY2VydGFpbiBkaWdlc3QuIENhbiBiZSB1c2VkIGluIGBkb2NrZXIgcHVzaC9wdWxsYC5cbiAgICpcbiAgICogICAgQUNDT1VOVC5ka3IuZWNyLlJFR0lPTi5hbWF6b25hd3MuY29tL1JFUE9TSVRPUllbQERJR0VTVF1cbiAgICpcbiAgICogQHBhcmFtIGRpZ2VzdCBJbWFnZSBkaWdlc3QgdG8gdXNlICh0b29scyB1c3VhbGx5IGRlZmF1bHQgdG8gdGhlIGltYWdlIHdpdGggdGhlIFwibGF0ZXN0XCIgdGFnIGlmIG9taXR0ZWQpXG4gICAqL1xuICByZXBvc2l0b3J5VXJpRm9yRGlnZXN0KGRpZ2VzdD86IHN0cmluZyk6IHN0cmluZztcblxuICAvKipcbiAgICogUmV0dXJucyB0aGUgVVJJIG9mIHRoZSByZXBvc2l0b3J5IGZvciBhIGNlcnRhaW4gdGFnIG9yIGRpZ2VzdCwgaW5mZXJyaW5nIGJhc2VkIG9uIHRoZSBzeW50YXggb2YgdGhlIHRhZy4gQ2FuIGJlIHVzZWQgaW4gYGRvY2tlciBwdXNoL3B1bGxgLlxuICAgKlxuICAgKiAgICBBQ0NPVU5ULmRrci5lY3IuUkVHSU9OLmFtYXpvbmF3cy5jb20vUkVQT1NJVE9SWVs6VEFHXVxuICAgKiAgICBBQ0NPVU5ULmRrci5lY3IuUkVHSU9OLmFtYXpvbmF3cy5jb20vUkVQT1NJVE9SWVtARElHRVNUXVxuICAgKlxuICAgKiBAcGFyYW0gdGFnT3JEaWdlc3QgSW1hZ2UgdGFnIG9yIGRpZ2VzdCB0byB1c2UgKHRvb2xzIHVzdWFsbHkgZGVmYXVsdCB0byB0aGUgaW1hZ2Ugd2l0aCB0aGUgXCJsYXRlc3RcIiB0YWcgaWYgb21pdHRlZClcbiAgICovXG4gIHJlcG9zaXRvcnlVcmlGb3JUYWdPckRpZ2VzdCh0YWdPckRpZ2VzdD86IHN0cmluZyk6IHN0cmluZztcblxuICAvKipcbiAgICogR3JhbnQgdGhlIGdpdmVuIGlkZW50aXR5IHBlcm1pc3Npb25zIHRvIHJlYWQgaW1hZ2VzIGluIHRoaXMgcmVwb3NpdG9yeS5cbiAgICovXG4gIGdyYW50UmVhZChncmFudGVlOiBpYW0uSUdyYW50YWJsZSk6IGlhbS5HcmFudDtcblxuICAvKipcbiAgICogR3JhbnQgdGhlIGdpdmVuIGlkZW50aXR5IHBlcm1pc3Npb25zIHRvIHB1bGwgaW1hZ2VzIGluIHRoaXMgcmVwb3NpdG9yeS5cbiAgICovXG4gIGdyYW50UHVsbChncmFudGVlOiBpYW0uSUdyYW50YWJsZSk6IGlhbS5HcmFudDtcblxuICAvKipcbiAgICogR3JhbnQgdGhlIGdpdmVuIGlkZW50aXR5IHBlcm1pc3Npb25zIHRvIHB1c2ggaW1hZ2VzIGluIHRoaXMgcmVwb3NpdG9yeS5cbiAgICovXG4gIGdyYW50UHVzaChncmFudGVlOiBpYW0uSUdyYW50YWJsZSk6IGlhbS5HcmFudDtcblxuICAvKipcbiAgICogR3JhbnQgdGhlIGdpdmVuIGlkZW50aXR5IHBlcm1pc3Npb25zIHRvIHB1bGwgYW5kIHB1c2ggaW1hZ2VzIHRvIHRoaXMgcmVwb3NpdG9yeS5cbiAgICovXG4gIGdyYW50UHVsbFB1c2goZ3JhbnRlZTogaWFtLklHcmFudGFibGUpOiBpYW0uR3JhbnQ7XG5cbiAgLyoqXG4gICAqIERlZmluZSBhIENsb3VkV2F0Y2ggZXZlbnQgdGhhdCB0cmlnZ2VycyB3aGVuIHNvbWV0aGluZyBoYXBwZW5zIHRvIHRoaXMgcmVwb3NpdG9yeVxuICAgKlxuICAgKiBSZXF1aXJlcyB0aGF0IHRoZXJlIGV4aXN0cyBhdCBsZWFzdCBvbmUgQ2xvdWRUcmFpbCBUcmFpbCBpbiB5b3VyIGFjY291bnRcbiAgICogdGhhdCBjYXB0dXJlcyB0aGUgZXZlbnQuIFRoaXMgbWV0aG9kIHdpbGwgbm90IGNyZWF0ZSB0aGUgVHJhaWwuXG4gICAqXG4gICAqIEBwYXJhbSBpZCBUaGUgaWQgb2YgdGhlIHJ1bGVcbiAgICogQHBhcmFtIG9wdGlvbnMgT3B0aW9ucyBmb3IgYWRkaW5nIHRoZSBydWxlXG4gICAqL1xuICBvbkNsb3VkVHJhaWxFdmVudChpZDogc3RyaW5nLCBvcHRpb25zPzogZXZlbnRzLk9uRXZlbnRPcHRpb25zKTogZXZlbnRzLlJ1bGU7XG5cbiAgLyoqXG4gICAqIERlZmluZXMgYW4gQVdTIENsb3VkV2F0Y2ggZXZlbnQgcnVsZSB0aGF0IGNhbiB0cmlnZ2VyIGEgdGFyZ2V0IHdoZW4gYW4gaW1hZ2UgaXMgcHVzaGVkIHRvIHRoaXNcbiAgICogcmVwb3NpdG9yeS5cbiAgICpcbiAgICogUmVxdWlyZXMgdGhhdCB0aGVyZSBleGlzdHMgYXQgbGVhc3Qgb25lIENsb3VkVHJhaWwgVHJhaWwgaW4geW91ciBhY2NvdW50XG4gICAqIHRoYXQgY2FwdHVyZXMgdGhlIGV2ZW50LiBUaGlzIG1ldGhvZCB3aWxsIG5vdCBjcmVhdGUgdGhlIFRyYWlsLlxuICAgKlxuICAgKiBAcGFyYW0gaWQgVGhlIGlkIG9mIHRoZSBydWxlXG4gICAqIEBwYXJhbSBvcHRpb25zIE9wdGlvbnMgZm9yIGFkZGluZyB0aGUgcnVsZVxuICAgKi9cbiAgb25DbG91ZFRyYWlsSW1hZ2VQdXNoZWQoXG4gICAgaWQ6IHN0cmluZyxcbiAgICBvcHRpb25zPzogT25DbG91ZFRyYWlsSW1hZ2VQdXNoZWRPcHRpb25zLFxuICApOiBldmVudHMuUnVsZTtcblxuICAvKipcbiAgICogRGVmaW5lcyBhbiBBV1MgQ2xvdWRXYXRjaCBldmVudCBydWxlIHRoYXQgY2FuIHRyaWdnZXIgYSB0YXJnZXQgd2hlbiB0aGUgaW1hZ2Ugc2NhbiBpcyBjb21wbGV0ZWRcbiAgICpcbiAgICpcbiAgICogQHBhcmFtIGlkIFRoZSBpZCBvZiB0aGUgcnVsZVxuICAgKiBAcGFyYW0gb3B0aW9ucyBPcHRpb25zIGZvciBhZGRpbmcgdGhlIHJ1bGVcbiAgICovXG4gIG9uSW1hZ2VTY2FuQ29tcGxldGVkKFxuICAgIGlkOiBzdHJpbmcsXG4gICAgb3B0aW9ucz86IE9uSW1hZ2VTY2FuQ29tcGxldGVkT3B0aW9ucyxcbiAgKTogZXZlbnRzLlJ1bGU7XG5cbiAgLyoqXG4gICAqIERlZmluZXMgYSBDbG91ZFdhdGNoIGV2ZW50IHJ1bGUgd2hpY2ggdHJpZ2dlcnMgZm9yIHJlcG9zaXRvcnkgZXZlbnRzLiBVc2VcbiAgICogYHJ1bGUuYWRkRXZlbnRQYXR0ZXJuKHBhdHRlcm4pYCB0byBzcGVjaWZ5IGEgZmlsdGVyLlxuICAgKi9cbiAgb25FdmVudChpZDogc3RyaW5nLCBvcHRpb25zPzogZXZlbnRzLk9uRXZlbnRPcHRpb25zKTogZXZlbnRzLlJ1bGU7XG59XG5cbi8qKlxuICogQmFzZSBjbGFzcyBmb3IgRUNSIHJlcG9zaXRvcnkuIFJldXNlZCBiZXR3ZWVuIGltcG9ydGVkIHJlcG9zaXRvcmllcyBhbmQgb3duZWQgcmVwb3NpdG9yaWVzLlxuICovXG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgUmVwb3NpdG9yeUJhc2VcbiAgZXh0ZW5kcyBBd3NDb25zdHJ1Y3RCYXNlXG4gIGltcGxlbWVudHMgSVJlcG9zaXRvcnlcbntcbiAgcHJpdmF0ZSByZWFkb25seSBSRVBPX1BVTExfQUNUSU9OUzogc3RyaW5nW10gPSBbXG4gICAgXCJlY3I6QmF0Y2hDaGVja0xheWVyQXZhaWxhYmlsaXR5XCIsXG4gICAgXCJlY3I6R2V0RG93bmxvYWRVcmxGb3JMYXllclwiLFxuICAgIFwiZWNyOkJhdGNoR2V0SW1hZ2VcIixcbiAgXTtcblxuICAvLyBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uRUNSL2xhdGVzdC91c2VyZ3VpZGUvaW1hZ2UtcHVzaC5odG1sI2ltYWdlLXB1c2gtaWFtXG4gIHByaXZhdGUgcmVhZG9ubHkgUkVQT19QVVNIX0FDVElPTlM6IHN0cmluZ1tdID0gW1xuICAgIFwiZWNyOkNvbXBsZXRlTGF5ZXJVcGxvYWRcIixcbiAgICBcImVjcjpVcGxvYWRMYXllclBhcnRcIixcbiAgICBcImVjcjpJbml0aWF0ZUxheWVyVXBsb2FkXCIsXG4gICAgXCJlY3I6QmF0Y2hDaGVja0xheWVyQXZhaWxhYmlsaXR5XCIsXG4gICAgXCJlY3I6UHV0SW1hZ2VcIixcbiAgXTtcblxuICAvKipcbiAgICogVGhlIG5hbWUgb2YgdGhlIHJlcG9zaXRvcnlcbiAgICovXG4gIHB1YmxpYyBhYnN0cmFjdCByZWFkb25seSByZXBvc2l0b3J5TmFtZTogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaGUgQVJOIG9mIHRoZSByZXBvc2l0b3J5XG4gICAqL1xuICBwdWJsaWMgYWJzdHJhY3QgcmVhZG9ubHkgcmVwb3NpdG9yeUFybjogc3RyaW5nO1xuXG4gIHB1YmxpYyBnZXQgb3V0cHV0cygpOiBSZWNvcmQ8c3RyaW5nLCBhbnk+IHtcbiAgICByZXR1cm4ge1xuICAgICAgcmVwb3NpdG9yeU5hbWU6IHRoaXMucmVwb3NpdG9yeU5hbWUsXG4gICAgICByZXBvc2l0b3J5QXJuOiB0aGlzLnJlcG9zaXRvcnlBcm4sXG4gICAgICByZXBvc2l0b3J5VXJpOiB0aGlzLnJlcG9zaXRvcnlVcmksXG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBZGQgYSBwb2xpY3kgc3RhdGVtZW50IHRvIHRoZSByZXBvc2l0b3J5J3MgcmVzb3VyY2UgcG9saWN5XG4gICAqL1xuICBwdWJsaWMgYWJzdHJhY3QgYWRkVG9SZXNvdXJjZVBvbGljeShcbiAgICBzdGF0ZW1lbnQ6IGlhbS5Qb2xpY3lTdGF0ZW1lbnQsXG4gICk6IGlhbS5BZGRUb1Jlc291cmNlUG9saWN5UmVzdWx0O1xuXG4gIC8qKlxuICAgKiBUaGUgVVJJIG9mIHRoaXMgcmVwb3NpdG9yeSAocmVwcmVzZW50cyB0aGUgbGF0ZXN0IGltYWdlKTpcbiAgICpcbiAgICogICAgQUNDT1VOVC5ka3IuZWNyLlJFR0lPTi5hbWF6b25hd3MuY29tL1JFUE9TSVRPUllcbiAgICpcbiAgICovXG4gIHB1YmxpYyBnZXQgcmVwb3NpdG9yeVVyaSgpIHtcbiAgICByZXR1cm4gdGhpcy5yZXBvc2l0b3J5VXJpRm9yVGFnKCk7XG4gIH1cblxuICAvKipcbiAgICogVGhlIFVSSSBvZiB0aGlzIHJlcG9zaXRvcnkncyByZWdpc3RyeTpcbiAgICpcbiAgICogICAgQUNDT1VOVC5ka3IuZWNyLlJFR0lPTi5hbWF6b25hd3MuY29tXG4gICAqXG4gICAqL1xuICBwdWJsaWMgZ2V0IHJlZ2lzdHJ5VXJpKCk6IHN0cmluZyB7XG4gICAgY29uc3QgcGFydHMgPSB0aGlzLnN0YWNrLnNwbGl0QXJuKFxuICAgICAgdGhpcy5yZXBvc2l0b3J5QXJuLFxuICAgICAgQXJuRm9ybWF0LlNMQVNIX1JFU09VUkNFX05BTUUsXG4gICAgKTtcbiAgICByZXR1cm4gYCR7cGFydHMuYWNjb3VudH0uZGtyLmVjci4ke3BhcnRzLnJlZ2lvbn0uJHt0aGlzLnN0YWNrLnVybFN1ZmZpeH1gO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgdGhlIFVSTCBvZiB0aGUgcmVwb3NpdG9yeS4gQ2FuIGJlIHVzZWQgaW4gYGRvY2tlciBwdXNoL3B1bGxgLlxuICAgKlxuICAgKiAgICBBQ0NPVU5ULmRrci5lY3IuUkVHSU9OLmFtYXpvbmF3cy5jb20vUkVQT1NJVE9SWVs6VEFHXVxuICAgKlxuICAgKiBAcGFyYW0gdGFnIE9wdGlvbmFsIGltYWdlIHRhZ1xuICAgKi9cbiAgcHVibGljIHJlcG9zaXRvcnlVcmlGb3JUYWcodGFnPzogc3RyaW5nKTogc3RyaW5nIHtcbiAgICBjb25zdCB0YWdTdWZmaXggPSB0YWcgPyBgOiR7dGFnfWAgOiBcIlwiO1xuICAgIHJldHVybiB0aGlzLnJlcG9zaXRvcnlVcmlXaXRoU3VmZml4KHRhZ1N1ZmZpeCk7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyB0aGUgVVJMIG9mIHRoZSByZXBvc2l0b3J5LiBDYW4gYmUgdXNlZCBpbiBgZG9ja2VyIHB1c2gvcHVsbGAuXG4gICAqXG4gICAqICAgIEFDQ09VTlQuZGtyLmVjci5SRUdJT04uYW1hem9uYXdzLmNvbS9SRVBPU0lUT1JZW0BESUdFU1RdXG4gICAqXG4gICAqIEBwYXJhbSBkaWdlc3QgT3B0aW9uYWwgaW1hZ2UgZGlnZXN0XG4gICAqL1xuICBwdWJsaWMgcmVwb3NpdG9yeVVyaUZvckRpZ2VzdChkaWdlc3Q/OiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIGNvbnN0IGRpZ2VzdFN1ZmZpeCA9IGRpZ2VzdCA/IGBAJHtkaWdlc3R9YCA6IFwiXCI7XG4gICAgcmV0dXJuIHRoaXMucmVwb3NpdG9yeVVyaVdpdGhTdWZmaXgoZGlnZXN0U3VmZml4KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHRoZSBVUkwgb2YgdGhlIHJlcG9zaXRvcnkuIENhbiBiZSB1c2VkIGluIGBkb2NrZXIgcHVzaC9wdWxsYC5cbiAgICpcbiAgICogICAgQUNDT1VOVC5ka3IuZWNyLlJFR0lPTi5hbWF6b25hd3MuY29tL1JFUE9TSVRPUllbOlRBR11cbiAgICogICAgQUNDT1VOVC5ka3IuZWNyLlJFR0lPTi5hbWF6b25hd3MuY29tL1JFUE9TSVRPUllbQERJR0VTVF1cbiAgICpcbiAgICogQHBhcmFtIHRhZ09yRGlnZXN0IE9wdGlvbmFsIGltYWdlIHRhZyBvciBkaWdlc3QgKGRpZ2VzdHMgbXVzdCBzdGFydCB3aXRoIGBzaGEyNTY6YClcbiAgICovXG4gIHB1YmxpYyByZXBvc2l0b3J5VXJpRm9yVGFnT3JEaWdlc3QodGFnT3JEaWdlc3Q/OiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIGlmICh0YWdPckRpZ2VzdD8uc3RhcnRzV2l0aChcInNoYTI1NjpcIikpIHtcbiAgICAgIHJldHVybiB0aGlzLnJlcG9zaXRvcnlVcmlGb3JEaWdlc3QodGFnT3JEaWdlc3QpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gdGhpcy5yZXBvc2l0b3J5VXJpRm9yVGFnKHRhZ09yRGlnZXN0KTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyB0aGUgcmVwb3NpdG9yeSBVUkksIHdpdGggYW4gYXBwZW5kZWQgc3VmZml4LCBpZiBwcm92aWRlZC5cbiAgICogQHBhcmFtIHN1ZmZpeCBBbiBpbWFnZSB0YWcgb3IgYW4gaW1hZ2UgZGlnZXN0LlxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgcHJpdmF0ZSByZXBvc2l0b3J5VXJpV2l0aFN1ZmZpeChzdWZmaXg/OiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIGNvbnN0IHBhcnRzID0gdGhpcy5zdGFjay5zcGxpdEFybihcbiAgICAgIHRoaXMucmVwb3NpdG9yeUFybixcbiAgICAgIEFybkZvcm1hdC5TTEFTSF9SRVNPVVJDRV9OQU1FLFxuICAgICk7XG4gICAgcmV0dXJuIGAke3BhcnRzLmFjY291bnR9LmRrci5lY3IuJHtwYXJ0cy5yZWdpb259LiR7dGhpcy5zdGFjay51cmxTdWZmaXh9LyR7dGhpcy5yZXBvc2l0b3J5TmFtZX0ke3N1ZmZpeH1gO1xuICB9XG5cbiAgLyoqXG4gICAqIERlZmluZSBhIENsb3VkV2F0Y2ggZXZlbnQgdGhhdCB0cmlnZ2VycyB3aGVuIHNvbWV0aGluZyBoYXBwZW5zIHRvIHRoaXMgcmVwb3NpdG9yeVxuICAgKlxuICAgKiBSZXF1aXJlcyB0aGF0IHRoZXJlIGV4aXN0cyBhdCBsZWFzdCBvbmUgQ2xvdWRUcmFpbCBUcmFpbCBpbiB5b3VyIGFjY291bnRcbiAgICogdGhhdCBjYXB0dXJlcyB0aGUgZXZlbnQuIFRoaXMgbWV0aG9kIHdpbGwgbm90IGNyZWF0ZSB0aGUgVHJhaWwuXG4gICAqXG4gICAqIEBwYXJhbSBpZCBUaGUgaWQgb2YgdGhlIHJ1bGVcbiAgICogQHBhcmFtIG9wdGlvbnMgT3B0aW9ucyBmb3IgYWRkaW5nIHRoZSBydWxlXG4gICAqL1xuICBwdWJsaWMgb25DbG91ZFRyYWlsRXZlbnQoXG4gICAgaWQ6IHN0cmluZyxcbiAgICBvcHRpb25zOiBldmVudHMuT25FdmVudE9wdGlvbnMgPSB7fSxcbiAgKTogZXZlbnRzLlJ1bGUge1xuICAgIGNvbnN0IHJ1bGUgPSBuZXcgZXZlbnRzLlJ1bGUodGhpcywgaWQsIG9wdGlvbnMpO1xuICAgIHJ1bGUuYWRkVGFyZ2V0KG9wdGlvbnMudGFyZ2V0KTtcbiAgICBydWxlLmFkZEV2ZW50UGF0dGVybih7XG4gICAgICBzb3VyY2U6IFtcImF3cy5lY3JcIl0sXG4gICAgICBkZXRhaWxUeXBlOiBbXCJBV1MgQVBJIENhbGwgdmlhIENsb3VkVHJhaWxcIl0sXG4gICAgICBkZXRhaWw6IHtcbiAgICAgICAgcmVxdWVzdFBhcmFtZXRlcnM6IHtcbiAgICAgICAgICByZXBvc2l0b3J5TmFtZTogW3RoaXMucmVwb3NpdG9yeU5hbWVdLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICB9KTtcbiAgICByZXR1cm4gcnVsZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBEZWZpbmVzIGFuIEFXUyBDbG91ZFdhdGNoIGV2ZW50IHJ1bGUgdGhhdCBjYW4gdHJpZ2dlciBhIHRhcmdldCB3aGVuIGFuIGltYWdlIGlzIHB1c2hlZCB0byB0aGlzXG4gICAqIHJlcG9zaXRvcnkuXG4gICAqXG4gICAqIFJlcXVpcmVzIHRoYXQgdGhlcmUgZXhpc3RzIGF0IGxlYXN0IG9uZSBDbG91ZFRyYWlsIFRyYWlsIGluIHlvdXIgYWNjb3VudFxuICAgKiB0aGF0IGNhcHR1cmVzIHRoZSBldmVudC4gVGhpcyBtZXRob2Qgd2lsbCBub3QgY3JlYXRlIHRoZSBUcmFpbC5cbiAgICpcbiAgICogQHBhcmFtIGlkIFRoZSBpZCBvZiB0aGUgcnVsZVxuICAgKiBAcGFyYW0gb3B0aW9ucyBPcHRpb25zIGZvciBhZGRpbmcgdGhlIHJ1bGVcbiAgICovXG4gIHB1YmxpYyBvbkNsb3VkVHJhaWxJbWFnZVB1c2hlZChcbiAgICBpZDogc3RyaW5nLFxuICAgIG9wdGlvbnM6IE9uQ2xvdWRUcmFpbEltYWdlUHVzaGVkT3B0aW9ucyA9IHt9LFxuICApOiBldmVudHMuUnVsZSB7XG4gICAgY29uc3QgcnVsZSA9IHRoaXMub25DbG91ZFRyYWlsRXZlbnQoaWQsIG9wdGlvbnMpO1xuICAgIHJ1bGUuYWRkRXZlbnRQYXR0ZXJuKHtcbiAgICAgIGRldGFpbDoge1xuICAgICAgICBldmVudE5hbWU6IFtcIlB1dEltYWdlXCJdLFxuICAgICAgICByZXF1ZXN0UGFyYW1ldGVyczoge1xuICAgICAgICAgIGltYWdlVGFnOiBvcHRpb25zLmltYWdlVGFnID8gW29wdGlvbnMuaW1hZ2VUYWddIDogdW5kZWZpbmVkLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICB9KTtcbiAgICByZXR1cm4gcnVsZTtcbiAgfVxuICAvKipcbiAgICogRGVmaW5lcyBhbiBBV1MgQ2xvdWRXYXRjaCBldmVudCBydWxlIHRoYXQgY2FuIHRyaWdnZXIgYSB0YXJnZXQgd2hlbiBhbiBpbWFnZSBzY2FuIGlzIGNvbXBsZXRlZFxuICAgKlxuICAgKlxuICAgKiBAcGFyYW0gaWQgVGhlIGlkIG9mIHRoZSBydWxlXG4gICAqIEBwYXJhbSBvcHRpb25zIE9wdGlvbnMgZm9yIGFkZGluZyB0aGUgcnVsZVxuICAgKi9cbiAgcHVibGljIG9uSW1hZ2VTY2FuQ29tcGxldGVkKFxuICAgIGlkOiBzdHJpbmcsXG4gICAgb3B0aW9uczogT25JbWFnZVNjYW5Db21wbGV0ZWRPcHRpb25zID0ge30sXG4gICk6IGV2ZW50cy5SdWxlIHtcbiAgICBjb25zdCBydWxlID0gbmV3IGV2ZW50cy5SdWxlKHRoaXMsIGlkLCBvcHRpb25zKTtcbiAgICBydWxlLmFkZFRhcmdldChvcHRpb25zLnRhcmdldCk7XG4gICAgcnVsZS5hZGRFdmVudFBhdHRlcm4oe1xuICAgICAgc291cmNlOiBbXCJhd3MuZWNyXCJdLFxuICAgICAgZGV0YWlsVHlwZTogW1wiRUNSIEltYWdlIFNjYW5cIl0sXG4gICAgICBkZXRhaWw6IHtcbiAgICAgICAgXCJyZXBvc2l0b3J5LW5hbWVcIjogW3RoaXMucmVwb3NpdG9yeU5hbWVdLFxuICAgICAgICBcInNjYW4tc3RhdHVzXCI6IFtcIkNPTVBMRVRFXCJdLFxuICAgICAgICBcImltYWdlLXRhZ3NcIjogb3B0aW9ucy5pbWFnZVRhZ3MgPz8gdW5kZWZpbmVkLFxuICAgICAgfSxcbiAgICB9KTtcbiAgICByZXR1cm4gcnVsZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBEZWZpbmVzIGEgQ2xvdWRXYXRjaCBldmVudCBydWxlIHdoaWNoIHRyaWdnZXJzIGZvciByZXBvc2l0b3J5IGV2ZW50cy4gVXNlXG4gICAqIGBydWxlLmFkZEV2ZW50UGF0dGVybihwYXR0ZXJuKWAgdG8gc3BlY2lmeSBhIGZpbHRlci5cbiAgICovXG4gIHB1YmxpYyBvbkV2ZW50KGlkOiBzdHJpbmcsIG9wdGlvbnM6IGV2ZW50cy5PbkV2ZW50T3B0aW9ucyA9IHt9KSB7XG4gICAgY29uc3QgcnVsZSA9IG5ldyBldmVudHMuUnVsZSh0aGlzLCBpZCwgb3B0aW9ucyk7XG4gICAgcnVsZS5hZGRFdmVudFBhdHRlcm4oe1xuICAgICAgc291cmNlOiBbXCJhd3MuZWNyXCJdLFxuICAgICAgZGV0YWlsOiB7XG4gICAgICAgIFwicmVwb3NpdG9yeS1uYW1lXCI6IFt0aGlzLnJlcG9zaXRvcnlOYW1lXSxcbiAgICAgIH0sXG4gICAgfSk7XG4gICAgcnVsZS5hZGRUYXJnZXQob3B0aW9ucy50YXJnZXQpO1xuICAgIHJldHVybiBydWxlO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50IHRoZSBnaXZlbiBwcmluY2lwYWwgaWRlbnRpdHkgcGVybWlzc2lvbnMgdG8gcGVyZm9ybSB0aGUgYWN0aW9ucyBvbiB0aGlzIHJlcG9zaXRvcnlcbiAgICovXG4gIHB1YmxpYyBncmFudChncmFudGVlOiBpYW0uSUdyYW50YWJsZSwgLi4uYWN0aW9uczogc3RyaW5nW10pIHtcbiAgICAvLyBUT0RPOiBJbXBsZW1lbnQgY3Jvc3MtYWNjb3VudCBwcmluY2lwYWwgbG9naWMgZnJvbSBDREtcbiAgICByZXR1cm4gaWFtLkdyYW50LmFkZFRvUHJpbmNpcGFsT3JSZXNvdXJjZSh7XG4gICAgICBncmFudGVlLFxuICAgICAgYWN0aW9ucyxcbiAgICAgIHJlc291cmNlQXJuczogW3RoaXMucmVwb3NpdG9yeUFybl0sXG4gICAgICByZXNvdXJjZTogdGhpcyxcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudCB0aGUgZ2l2ZW4gaWRlbnRpdHkgcGVybWlzc2lvbnMgdG8gcmVhZCB0aGUgaW1hZ2VzIGluIHRoaXMgcmVwb3NpdG9yeVxuICAgKi9cbiAgcHVibGljIGdyYW50UmVhZChncmFudGVlOiBpYW0uSUdyYW50YWJsZSk6IGlhbS5HcmFudCB7XG4gICAgcmV0dXJuIHRoaXMuZ3JhbnQoXG4gICAgICBncmFudGVlLFxuICAgICAgXCJlY3I6RGVzY3JpYmVSZXBvc2l0b3JpZXNcIixcbiAgICAgIFwiZWNyOkRlc2NyaWJlSW1hZ2VzXCIsXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudCB0aGUgZ2l2ZW4gaWRlbnRpdHkgcGVybWlzc2lvbnMgdG8gdXNlIHRoZSBpbWFnZXMgaW4gdGhpcyByZXBvc2l0b3J5XG4gICAqL1xuICBwdWJsaWMgZ3JhbnRQdWxsKGdyYW50ZWU6IGlhbS5JR3JhbnRhYmxlKSB7XG4gICAgY29uc3QgcmV0ID0gdGhpcy5ncmFudChncmFudGVlLCAuLi50aGlzLlJFUE9fUFVMTF9BQ1RJT05TKTtcblxuICAgIGlhbS5HcmFudC5hZGRUb1ByaW5jaXBhbCh7XG4gICAgICBncmFudGVlLFxuICAgICAgYWN0aW9uczogW1wiZWNyOkdldEF1dGhvcml6YXRpb25Ub2tlblwiXSxcbiAgICAgIHJlc291cmNlQXJuczogW1wiKlwiXSxcbiAgICAgIHNjb3BlOiB0aGlzLFxuICAgIH0pO1xuXG4gICAgcmV0dXJuIHJldDtcbiAgfVxuXG4gIC8qKlxuICAgKiBHcmFudCB0aGUgZ2l2ZW4gaWRlbnRpdHkgcGVybWlzc2lvbnMgdG8gdXNlIHRoZSBpbWFnZXMgaW4gdGhpcyByZXBvc2l0b3J5XG4gICAqL1xuICBwdWJsaWMgZ3JhbnRQdXNoKGdyYW50ZWU6IGlhbS5JR3JhbnRhYmxlKSB7XG4gICAgY29uc3QgcmV0ID0gdGhpcy5ncmFudChncmFudGVlLCAuLi50aGlzLlJFUE9fUFVTSF9BQ1RJT05TKTtcbiAgICBpYW0uR3JhbnQuYWRkVG9QcmluY2lwYWwoe1xuICAgICAgZ3JhbnRlZSxcbiAgICAgIGFjdGlvbnM6IFtcImVjcjpHZXRBdXRob3JpemF0aW9uVG9rZW5cIl0sXG4gICAgICByZXNvdXJjZUFybnM6IFtcIipcIl0sXG4gICAgICBzY29wZTogdGhpcyxcbiAgICB9KTtcblxuICAgIHJldHVybiByZXQ7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnQgdGhlIGdpdmVuIGlkZW50aXR5IHBlcm1pc3Npb25zIHRvIHB1bGwgYW5kIHB1c2ggaW1hZ2VzIHRvIHRoaXMgcmVwb3NpdG9yeS5cbiAgICovXG4gIHB1YmxpYyBncmFudFB1bGxQdXNoKGdyYW50ZWU6IGlhbS5JR3JhbnRhYmxlKSB7XG4gICAgY29uc3QgcmV0ID0gdGhpcy5ncmFudChcbiAgICAgIGdyYW50ZWUsXG4gICAgICAuLi50aGlzLlJFUE9fUFVMTF9BQ1RJT05TLFxuICAgICAgLi4udGhpcy5SRVBPX1BVU0hfQUNUSU9OUyxcbiAgICApO1xuICAgIGlhbS5HcmFudC5hZGRUb1ByaW5jaXBhbCh7XG4gICAgICBncmFudGVlLFxuICAgICAgYWN0aW9uczogW1wiZWNyOkdldEF1dGhvcml6YXRpb25Ub2tlblwiXSxcbiAgICAgIHJlc291cmNlQXJuczogW1wiKlwiXSxcbiAgICAgIHNjb3BlOiB0aGlzLFxuICAgIH0pO1xuXG4gICAgcmV0dXJuIHJldDtcbiAgfVxufVxuXG4vKipcbiAqIE9wdGlvbnMgZm9yIHRoZSBvbkNsb3VkVHJhaWxJbWFnZVB1c2hlZCBtZXRob2RcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBPbkNsb3VkVHJhaWxJbWFnZVB1c2hlZE9wdGlvbnMgZXh0ZW5kcyBldmVudHMuT25FdmVudE9wdGlvbnMge1xuICAvKipcbiAgICogT25seSB3YXRjaCBjaGFuZ2VzIHRvIHRoaXMgaW1hZ2UgdGFnXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gV2F0Y2ggY2hhbmdlcyB0byBhbGwgdGFnc1xuICAgKi9cbiAgcmVhZG9ubHkgaW1hZ2VUYWc/OiBzdHJpbmc7XG59XG5cbi8qKlxuICogT3B0aW9ucyBmb3IgdGhlIE9uSW1hZ2VTY2FuQ29tcGxldGVkIG1ldGhvZFxuICovXG5leHBvcnQgaW50ZXJmYWNlIE9uSW1hZ2VTY2FuQ29tcGxldGVkT3B0aW9ucyBleHRlbmRzIGV2ZW50cy5PbkV2ZW50T3B0aW9ucyB7XG4gIC8qKlxuICAgKiBPbmx5IHdhdGNoIGNoYW5nZXMgdG8gdGhlIGltYWdlIHRhZ3Mgc3BlY2lmaWVkLlxuICAgKiBMZWF2ZSBpdCB1bmRlZmluZWQgdG8gd2F0Y2ggdGhlIGZ1bGwgcmVwb3NpdG9yeS5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBXYXRjaCB0aGUgY2hhbmdlcyB0byB0aGUgcmVwb3NpdG9yeSB3aXRoIGFsbCBpbWFnZSB0YWdzXG4gICAqL1xuICByZWFkb25seSBpbWFnZVRhZ3M/OiBzdHJpbmdbXTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBSZXBvc2l0b3J5UHJvcHMgZXh0ZW5kcyBBd3NDb25zdHJ1Y3RQcm9wcyB7XG4gIC8qKlxuICAgKiBOYW1lIGZvciB0aGlzIHJlcG9zaXRvcnkuXG4gICAqXG4gICAqIFRoZSByZXBvc2l0b3J5IG5hbWUgbXVzdCBzdGFydCB3aXRoIGEgbGV0dGVyIGFuZCBjYW4gb25seSBjb250YWluIGxvd2VyY2FzZSBsZXR0ZXJzLCBudW1iZXJzLCBoeXBoZW5zLCB1bmRlcnNjb3JlcywgYW5kIGZvcndhcmQgc2xhc2hlcy5cbiAgICpcbiAgICogPiBJZiB5b3Ugc3BlY2lmeSBhIG5hbWUsIHlvdSBjYW5ub3QgcGVyZm9ybSB1cGRhdGVzIHRoYXQgcmVxdWlyZSByZXBsYWNlbWVudCBvZiB0aGlzIHJlc291cmNlLiBZb3UgY2FuIHBlcmZvcm0gdXBkYXRlcyB0aGF0IHJlcXVpcmUgbm8gb3Igc29tZSBpbnRlcnJ1cHRpb24uIElmIHlvdSBtdXN0IHJlcGxhY2UgdGhlIHJlc291cmNlLCBzcGVjaWZ5IGEgbmV3IG5hbWUuXG4gICAqXG4gICAqIEBkZWZhdWx0IEF1dG9tYXRpY2FsbHkgZ2VuZXJhdGVkIG5hbWUuXG4gICAqL1xuICByZWFkb25seSByZXBvc2l0b3J5TmFtZT86IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIGtpbmQgb2Ygc2VydmVyLXNpZGUgZW5jcnlwdGlvbiB0byBhcHBseSB0byB0aGlzIHJlcG9zaXRvcnkuXG4gICAqXG4gICAqIElmIHlvdSBjaG9vc2UgS01TLCB5b3UgY2FuIHNwZWNpZnkgYSBLTVMga2V5IHZpYSBgZW5jcnlwdGlvbktleWAuIElmXG4gICAqIGVuY3J5cHRpb25LZXkgaXMgbm90IHNwZWNpZmllZCwgYW4gQVdTIG1hbmFnZWQgS01TIGtleSBpcyB1c2VkLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIGBLTVNgIGlmIGBlbmNyeXB0aW9uS2V5YCBpcyBzcGVjaWZpZWQsIG9yIGBBRVMyNTZgIG90aGVyd2lzZS5cbiAgICovXG4gIHJlYWRvbmx5IGVuY3J5cHRpb24/OiBSZXBvc2l0b3J5RW5jcnlwdGlvbjtcblxuICAvKipcbiAgICogRXh0ZXJuYWwgS01TIGtleSB0byB1c2UgZm9yIHJlcG9zaXRvcnkgZW5jcnlwdGlvbi5cbiAgICpcbiAgICogVGhlICdlbmNyeXB0aW9uJyBwcm9wZXJ0eSBtdXN0IGJlIGVpdGhlciBub3Qgc3BlY2lmaWVkIG9yIHNldCB0byBcIktNU1wiLlxuICAgKiBBbiBlcnJvciB3aWxsIGJlIGVtaXR0ZWQgaWYgZW5jcnlwdGlvbiBpcyBzZXQgdG8gXCJBRVMyNTZcIi5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBJZiBlbmNyeXB0aW9uIGlzIHNldCB0byBgS01TYCBhbmQgdGhpcyBwcm9wZXJ0eSBpcyB1bmRlZmluZWQsXG4gICAqIGFuIEFXUyBtYW5hZ2VkIEtNUyBrZXkgaXMgdXNlZC5cbiAgICovXG4gIHJlYWRvbmx5IGVuY3J5cHRpb25LZXk/OiBlbmNyeXB0aW9uLklLZXk7XG5cbiAgLyoqXG4gICAqIExpZmUgY3ljbGUgcnVsZXMgdG8gYXBwbHkgdG8gdGhpcyByZWdpc3RyeVxuICAgKlxuICAgKiBAZGVmYXVsdCBObyBsaWZlIGN5Y2xlIHJ1bGVzXG4gICAqL1xuICByZWFkb25seSBsaWZlY3ljbGVSdWxlcz86IExpZmVjeWNsZVJ1bGVbXTtcblxuICAvKipcbiAgICogVGhlIEFXUyBhY2NvdW50IElEIGFzc29jaWF0ZWQgd2l0aCB0aGUgcmVnaXN0cnkgdGhhdCBjb250YWlucyB0aGUgcmVwb3NpdG9yeS5cbiAgICpcbiAgICogQHNlZSBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uRUNSL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX1B1dExpZmVjeWNsZVBvbGljeS5odG1sXG4gICAqIEBkZWZhdWx0IFRoZSBkZWZhdWx0IHJlZ2lzdHJ5IGlzIGFzc3VtZWQuXG4gICAqIEBkZXByZWNhdGVkIFRoaXMgcHJvcGVydHkgaXMgbm90IHN1cHBvcnRlZCBieSB0aGUgVGVycmFmb3JtIEFXUyBwcm92aWRlciBmb3IgRUNSIGxpZmVjeWNsZSBwb2xpY2llcy5cbiAgICovXG4gIHJlYWRvbmx5IGxpZmVjeWNsZVJlZ2lzdHJ5SWQ/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIEVuYWJsZSB0aGUgc2NhbiBvbiBwdXNoIHdoZW4gY3JlYXRpbmcgdGhlIHJlcG9zaXRvcnlcbiAgICpcbiAgICogIEBkZWZhdWx0IGZhbHNlXG4gICAqL1xuICByZWFkb25seSBpbWFnZVNjYW5PblB1c2g/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBUaGUgdGFnIG11dGFiaWxpdHkgc2V0dGluZyBmb3IgdGhlIHJlcG9zaXRvcnkuIElmIHRoaXMgcGFyYW1ldGVyIGlzIG9taXR0ZWQsIHRoZSBkZWZhdWx0IHNldHRpbmcgb2YgTVVUQUJMRSB3aWxsIGJlIHVzZWQgd2hpY2ggd2lsbCBhbGxvdyBpbWFnZSB0YWdzIHRvIGJlIG92ZXJ3cml0dGVuLlxuICAgKlxuICAgKiAgQGRlZmF1bHQgVGFnTXV0YWJpbGl0eS5NVVRBQkxFXG4gICAqL1xuICByZWFkb25seSBpbWFnZVRhZ011dGFiaWxpdHk/OiBUYWdNdXRhYmlsaXR5O1xuXG4gIC8qKlxuICAgKiBXaGV0aGVyIGFsbCBpbWFnZXMgc2hvdWxkIGJlIGF1dG9tYXRpY2FsbHkgZGVsZXRlZCB3aGVuIHRoZSByZXBvc2l0b3J5IGlzXG4gICAqIHJlbW92ZWQgZnJvbSB0aGUgc3RhY2sgb3Igd2hlbiB0aGUgc3RhY2sgaXMgZGVsZXRlZC5cbiAgICpcbiAgICogUmVxdWlyZXMgdGhlIGBmb3JjZURlbGV0ZWAgcHJvcGVydHkgdG8gYmUgc2V0IHRvIGB0cnVlYC5cbiAgICpcbiAgICogQGRlZmF1bHQgZmFsc2VcbiAgICogQGRlcHJlY2F0ZWQgVXNlIGBmb3JjZURlbGV0ZWAgaW5zdGVhZC4gVGhpcyBmdW5jdGlvbmFsaXR5IGlzIG5vdCBpbXBsZW1lbnRlZCBpbiBUZXJyYUNvbnN0cnVjdHMgYXMgaXQgcmVxdWlyZXMgYSBjdXN0b20gcmVzb3VyY2UuXG4gICAqL1xuICByZWFkb25seSBhdXRvRGVsZXRlSW1hZ2VzPzogYm9vbGVhbjtcblxuICAvKipcbiAgICogSWYgdHJ1ZSwgZGVsZXRpbmcgdGhlIHJlcG9zaXRvcnkgZm9yY2UgZGVsZXRlcyB0aGUgY29udGVudHMgb2YgdGhlIHJlcG9zaXRvcnkuIElmIGZhbHNlLCB0aGUgcmVwb3NpdG9yeSBtdXN0IGJlIGVtcHR5IGJlZm9yZSBhdHRlbXB0aW5nIHRvIGRlbGV0ZSBpdC5cbiAgICpcbiAgICogQGRlZmF1bHQgZmFsc2VcbiAgICovXG4gIHJlYWRvbmx5IGVtcHR5T25EZWxldGU/OiBib29sZWFuO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFJlcG9zaXRvcnlBdHRyaWJ1dGVzIHtcbiAgcmVhZG9ubHkgcmVwb3NpdG9yeU5hbWU6IHN0cmluZztcbiAgcmVhZG9ubHkgcmVwb3NpdG9yeUFybjogc3RyaW5nO1xufVxuXG4vKipcbiAqIERlZmluZSBhbiBFQ1IgcmVwb3NpdG9yeVxuICovXG5leHBvcnQgY2xhc3MgUmVwb3NpdG9yeSBleHRlbmRzIFJlcG9zaXRvcnlCYXNlIHtcbiAgLyoqXG4gICAqIEltcG9ydCBhIHJlcG9zaXRvcnlcbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgZnJvbVJlcG9zaXRvcnlBdHRyaWJ1dGVzKFxuICAgIHNjb3BlOiBDb25zdHJ1Y3QsXG4gICAgaWQ6IHN0cmluZyxcbiAgICBhdHRyczogUmVwb3NpdG9yeUF0dHJpYnV0ZXMsXG4gICk6IElSZXBvc2l0b3J5IHtcbiAgICBjbGFzcyBJbXBvcnQgZXh0ZW5kcyBSZXBvc2l0b3J5QmFzZSB7XG4gICAgICBwdWJsaWMgcmVhZG9ubHkgcmVwb3NpdG9yeU5hbWUgPSBhdHRycy5yZXBvc2l0b3J5TmFtZTtcbiAgICAgIHB1YmxpYyByZWFkb25seSByZXBvc2l0b3J5QXJuID0gYXR0cnMucmVwb3NpdG9yeUFybjtcblxuICAgICAgcHVibGljIGFkZFRvUmVzb3VyY2VQb2xpY3koXG4gICAgICAgIF9zdGF0ZW1lbnQ6IGlhbS5Qb2xpY3lTdGF0ZW1lbnQsXG4gICAgICApOiBpYW0uQWRkVG9SZXNvdXJjZVBvbGljeVJlc3VsdCB7XG4gICAgICAgIC8vIGRyb3BwZWRcbiAgICAgICAgcmV0dXJuIHsgc3RhdGVtZW50QWRkZWQ6IGZhbHNlIH07XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIG5ldyBJbXBvcnQoc2NvcGUsIGlkKTtcbiAgfVxuXG4gIHB1YmxpYyBzdGF0aWMgZnJvbVJlcG9zaXRvcnlBcm4oXG4gICAgc2NvcGU6IENvbnN0cnVjdCxcbiAgICBpZDogc3RyaW5nLFxuICAgIHJlcG9zaXRvcnlBcm46IHN0cmluZyxcbiAgKTogSVJlcG9zaXRvcnkge1xuICAgIGlmIChUb2tlbi5pc1VucmVzb2x2ZWQocmVwb3NpdG9yeUFybikpIHtcbiAgICAgIC8vIFRPRE86IFVuc2NvcGVkVmFsaWRhdGlvbkVycm9yXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICdcInJlcG9zaXRvcnlBcm5cIiBpcyBhIGxhdGUtYm91bmQgdmFsdWUsIGFuZCB0aGVyZWZvcmUgXCJyZXBvc2l0b3J5TmFtZVwiIGlzIHJlcXVpcmVkLiBVc2UgYGZyb21SZXBvc2l0b3J5QXR0cmlidXRlc2AgaW5zdGVhZCcsXG4gICAgICApO1xuICAgIH1cblxuICAgIHZhbGlkYXRlUmVwb3NpdG9yeUFybigpO1xuXG4gICAgY29uc3QgcmVwb3NpdG9yeU5hbWUgPSByZXBvc2l0b3J5QXJuLnNwbGl0KFwiL1wiKS5zbGljZSgxKS5qb2luKFwiL1wiKTtcblxuICAgIGNsYXNzIEltcG9ydCBleHRlbmRzIFJlcG9zaXRvcnlCYXNlIHtcbiAgICAgIHB1YmxpYyByZXBvc2l0b3J5TmFtZSA9IHJlcG9zaXRvcnlOYW1lO1xuICAgICAgcHVibGljIHJlcG9zaXRvcnlBcm4gPSByZXBvc2l0b3J5QXJuO1xuXG4gICAgICBwdWJsaWMgYWRkVG9SZXNvdXJjZVBvbGljeShcbiAgICAgICAgX3N0YXRlbWVudDogaWFtLlBvbGljeVN0YXRlbWVudCxcbiAgICAgICk6IGlhbS5BZGRUb1Jlc291cmNlUG9saWN5UmVzdWx0IHtcbiAgICAgICAgLy8gZHJvcHBlZFxuICAgICAgICByZXR1cm4geyBzdGF0ZW1lbnRBZGRlZDogZmFsc2UgfTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gbmV3IEltcG9ydChzY29wZSwgaWQsIHtcbiAgICAgIGVudmlyb25tZW50RnJvbUFybjogcmVwb3NpdG9yeUFybixcbiAgICB9KTtcblxuICAgIGZ1bmN0aW9uIHZhbGlkYXRlUmVwb3NpdG9yeUFybigpIHtcbiAgICAgIGNvbnN0IHNwbGl0QXJuID0gcmVwb3NpdG9yeUFybi5zcGxpdChcIjpcIik7XG5cbiAgICAgIGlmICghc3BsaXRBcm5bc3BsaXRBcm4ubGVuZ3RoIC0gMV0uc3RhcnRzV2l0aChcInJlcG9zaXRvcnkvXCIpKSB7XG4gICAgICAgIC8vIFRPRE86IFVuc2NvcGVkVmFsaWRhdGlvbkVycm9yXG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICBgUmVwb3NpdG9yeSBhcm4gc2hvdWxkIGJlIGluIHRoZSBmb3JtYXQgJ2Fybjo8UEFSVElUSU9OPjplY3I6PFJFR0lPTj46PEFDQ09VTlQ+OnJlcG9zaXRvcnkvPE5BTUU+JywgZ290ICR7cmVwb3NpdG9yeUFybn0uYCxcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwdWJsaWMgc3RhdGljIGZyb21SZXBvc2l0b3J5TmFtZShcbiAgICBzY29wZTogQ29uc3RydWN0LFxuICAgIGlkOiBzdHJpbmcsXG4gICAgcmVwb3NpdG9yeU5hbWU6IHN0cmluZyxcbiAgKTogSVJlcG9zaXRvcnkge1xuICAgIGNsYXNzIEltcG9ydCBleHRlbmRzIFJlcG9zaXRvcnlCYXNlIHtcbiAgICAgIHB1YmxpYyByZXBvc2l0b3J5TmFtZSA9IHJlcG9zaXRvcnlOYW1lO1xuICAgICAgcHVibGljIHJlcG9zaXRvcnlBcm4gPSBSZXBvc2l0b3J5LmFybkZvckxvY2FsUmVwb3NpdG9yeShcbiAgICAgICAgcmVwb3NpdG9yeU5hbWUsXG4gICAgICAgIHNjb3BlLFxuICAgICAgKTtcblxuICAgICAgcHVibGljIGFkZFRvUmVzb3VyY2VQb2xpY3koXG4gICAgICAgIF9zdGF0ZW1lbnQ6IGlhbS5Qb2xpY3lTdGF0ZW1lbnQsXG4gICAgICApOiBpYW0uQWRkVG9SZXNvdXJjZVBvbGljeVJlc3VsdCB7XG4gICAgICAgIC8vIGRyb3BwZWRcbiAgICAgICAgcmV0dXJuIHsgc3RhdGVtZW50QWRkZWQ6IGZhbHNlIH07XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIG5ldyBJbXBvcnQoc2NvcGUsIGlkKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIGFuIEVDUiBBUk4gZm9yIGEgcmVwb3NpdG9yeSB0aGF0IHJlc2lkZXMgaW4gdGhlIHNhbWUgYWNjb3VudC9yZWdpb25cbiAgICogYXMgdGhlIGN1cnJlbnQgc3RhY2suXG4gICAqL1xuICBwdWJsaWMgc3RhdGljIGFybkZvckxvY2FsUmVwb3NpdG9yeShcbiAgICByZXBvc2l0b3J5TmFtZTogc3RyaW5nLFxuICAgIHNjb3BlOiBJQ29uc3RydWN0LFxuICAgIGFjY291bnQ/OiBzdHJpbmcsXG4gICk6IHN0cmluZyB7XG4gICAgcmV0dXJuIEF3c1N0YWNrLm9mQXdzQ29uc3RydWN0KHNjb3BlKS5mb3JtYXRBcm4oe1xuICAgICAgYWNjb3VudCxcbiAgICAgIHNlcnZpY2U6IFwiZWNyXCIsXG4gICAgICByZXNvdXJjZTogXCJyZXBvc2l0b3J5XCIsXG4gICAgICByZXNvdXJjZU5hbWU6IHJlcG9zaXRvcnlOYW1lLFxuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBzdGF0aWMgdmFsaWRhdGVSZXBvc2l0b3J5TmFtZShwaHlzaWNhbE5hbWU6IHN0cmluZykge1xuICAgIGNvbnN0IHJlcG9zaXRvcnlOYW1lID0gcGh5c2ljYWxOYW1lO1xuICAgIGlmICghcmVwb3NpdG9yeU5hbWUgfHwgVG9rZW4uaXNVbnJlc29sdmVkKHJlcG9zaXRvcnlOYW1lKSkge1xuICAgICAgLy8gdGhlIG5hbWUgaXMgYSBsYXRlLWJvdW5kIHZhbHVlLCBub3QgYSBkZWZpbmVkIHN0cmluZyxcbiAgICAgIC8vIHNvIHNraXAgdmFsaWRhdGlvblxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IGVycm9yczogc3RyaW5nW10gPSBbXTtcblxuICAgIC8vIFJ1bGVzIGNvZGlmaWVkIGZyb20gaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FXU0Nsb3VkRm9ybWF0aW9uL2xhdGVzdC9Vc2VyR3VpZGUvYXdzLXJlc291cmNlLWVjci1yZXBvc2l0b3J5Lmh0bWxcbiAgICBpZiAocmVwb3NpdG9yeU5hbWUubGVuZ3RoIDwgMiB8fCByZXBvc2l0b3J5TmFtZS5sZW5ndGggPiAyNTYpIHtcbiAgICAgIGVycm9ycy5wdXNoKFxuICAgICAgICBcIlJlcG9zaXRvcnkgbmFtZSBtdXN0IGJlIGF0IGxlYXN0IDIgYW5kIG5vIG1vcmUgdGhhbiAyNTYgY2hhcmFjdGVyc1wiLFxuICAgICAgKTtcbiAgICB9XG4gICAgY29uc3QgaXNQYXR0ZXJuTWF0Y2ggPVxuICAgICAgL14oPzpbYS16MC05XSsoPzpbLl8tXVthLXowLTldKykqXFwvKSpbYS16MC05XSsoPzpbLl8tXVthLXowLTldKykqJC8udGVzdChcbiAgICAgICAgcmVwb3NpdG9yeU5hbWUsXG4gICAgICApO1xuICAgIGlmICghaXNQYXR0ZXJuTWF0Y2gpIHtcbiAgICAgIGVycm9ycy5wdXNoKFxuICAgICAgICBcIlJlcG9zaXRvcnkgbmFtZSBtdXN0IHN0YXJ0IHdpdGggYSBsZXR0ZXIgYW5kIGNhbiBvbmx5IGNvbnRhaW4gbG93ZXJjYXNlIGxldHRlcnMsIG51bWJlcnMsIGh5cGhlbnMsIHVuZGVyc2NvcmVzLCBwZXJpb2RzIGFuZCBmb3J3YXJkIHNsYXNoZXNcIixcbiAgICAgICk7XG4gICAgfVxuXG4gICAgaWYgKGVycm9ycy5sZW5ndGggPiAwKSB7XG4gICAgICAvLyBUT0RPOiBVbnNjb3BlZFZhbGlkYXRpb25FcnJvclxuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICBgSW52YWxpZCBFQ1IgcmVwb3NpdG9yeSBuYW1lICh2YWx1ZTogJHtyZXBvc2l0b3J5TmFtZX0pJHtFT0x9JHtlcnJvcnMuam9pbihcbiAgICAgICAgICBFT0wsXG4gICAgICAgICl9YCxcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgcHVibGljIHJlYWRvbmx5IHJlcG9zaXRvcnlOYW1lOiBzdHJpbmc7XG4gIHB1YmxpYyByZWFkb25seSByZXBvc2l0b3J5QXJuOiBzdHJpbmc7XG4gIHByaXZhdGUgcmVhZG9ubHkgbGlmZWN5Y2xlUnVsZXMgPSBuZXcgQXJyYXk8TGlmZWN5Y2xlUnVsZT4oKTtcbiAgcHJpdmF0ZSBwb2xpY3lEb2N1bWVudD86IGlhbS5Qb2xpY3lEb2N1bWVudDtcbiAgcHJpdmF0ZSByZWFkb25seSByZXNvdXJjZTogZWNyUmVwb3NpdG9yeS5FY3JSZXBvc2l0b3J5O1xuXG4gIGNvbnN0cnVjdG9yKHNjb3BlOiBDb25zdHJ1Y3QsIGlkOiBzdHJpbmcsIHByb3BzOiBSZXBvc2l0b3J5UHJvcHMgPSB7fSkge1xuICAgIHN1cGVyKHNjb3BlLCBpZCwgcHJvcHMpO1xuXG4gICAgY29uc3QgbmFtZSA9XG4gICAgICBwcm9wcy5yZXBvc2l0b3J5TmFtZSB8fFxuICAgICAgdGhpcy5zdGFjay51bmlxdWVSZXNvdXJjZU5hbWUodGhpcywge1xuICAgICAgICAvLyBUT0RPOiBSZXBvIG5hbWUgY2FuJ3Qgc3RhcnQgd2l0aCBhIG51bWJlci4uLlxuICAgICAgICAvLyBwcmVmaXg6IHRoaXMuZ3JpZFVVSUQsXG4gICAgICAgIC8vUmVwb3NpdG9yeSBuYW1lIG11c3Qgc3RhcnQgd2l0aCBhIGxldHRlciBhbmQgY2FuIG9ubHkgY29udGFpbiBsb3dlcmNhc2UgbGV0dGVycywgbnVtYmVycywgaHlwaGVucywgdW5kZXJzY29yZXMsIHBlcmlvZHMgYW5kIGZvcndhcmQgc2xhc2hlc1xuICAgICAgICBtYXhMZW5ndGg6IDI1NixcbiAgICAgICAgbG93ZXJDYXNlOiB0cnVlLFxuICAgICAgICBhbGxvd2VkU3BlY2lhbENoYXJhY3RlcnM6IFwiLV8uL1wiLFxuICAgICAgICBzZXBhcmF0b3I6IFwiLVwiLFxuICAgICAgfSk7XG4gICAgUmVwb3NpdG9yeS52YWxpZGF0ZVJlcG9zaXRvcnlOYW1lKG5hbWUpO1xuXG4gICAgdGhpcy5yZXNvdXJjZSA9IG5ldyBlY3JSZXBvc2l0b3J5LkVjclJlcG9zaXRvcnkodGhpcywgXCJSZXNvdXJjZVwiLCB7XG4gICAgICBuYW1lOiBuYW1lLFxuICAgICAgaW1hZ2VTY2FubmluZ0NvbmZpZ3VyYXRpb246XG4gICAgICAgIHByb3BzLmltYWdlU2Nhbk9uUHVzaCAhPT0gdW5kZWZpbmVkXG4gICAgICAgICAgPyB7IHNjYW5PblB1c2g6IHByb3BzLmltYWdlU2Nhbk9uUHVzaCB9XG4gICAgICAgICAgOiB1bmRlZmluZWQsXG4gICAgICBpbWFnZVRhZ011dGFiaWxpdHk6IHByb3BzLmltYWdlVGFnTXV0YWJpbGl0eSB8fCB1bmRlZmluZWQsXG4gICAgICBlbmNyeXB0aW9uQ29uZmlndXJhdGlvbjogdGhpcy5wYXJzZUVuY3J5cHRpb24ocHJvcHMpLFxuICAgICAgZm9yY2VEZWxldGU6IHByb3BzLmVtcHR5T25EZWxldGUsXG4gICAgICAvLyBUT0RPOiBpbXBsZW1lbnQgcmV0YWluIHBvbGljeSBieSBkZWZhdWx0P1xuICAgICAgLy8gbGlmZWN5Y2xlOiB7XG4gICAgICAvLyAgIHByZXZlbnREZXN0cm95OiBwcm9wcy5lbXB0eU9uRGVsZXRlID09PSBmYWxzZSxcbiAgICAgIC8vIH0sXG4gICAgfSk7XG5cbiAgICBpZiAocHJvcHMubGlmZWN5Y2xlUmVnaXN0cnlJZCkge1xuICAgICAgLy8gVE9ETzogQW5ub3RhdGlvbnMub2YodGhpcykuYWRkV2FybmluZ1YyKC4uLilcbiAgICAgIEFubm90YXRpb25zLm9mKHRoaXMpLmFkZFdhcm5pbmcoXG4gICAgICAgIFwibGlmZWN5Y2xlUmVnaXN0cnlJZCBpcyBub3Qgc3VwcG9ydGVkIGJ5IHRoZSBUZXJyYWZvcm0gQVdTIHByb3ZpZGVyIGFuZCB3aWxsIGJlIGlnbm9yZWQuXCIsXG4gICAgICApO1xuICAgIH1cblxuICAgIGlmIChwcm9wcy5saWZlY3ljbGVSdWxlcykge1xuICAgICAgcHJvcHMubGlmZWN5Y2xlUnVsZXMuZm9yRWFjaCh0aGlzLmFkZExpZmVjeWNsZVJ1bGUuYmluZCh0aGlzKSk7XG4gICAgfVxuXG4gICAgdGhpcy5yZXBvc2l0b3J5TmFtZSA9IHRoaXMucmVzb3VyY2UubmFtZTtcbiAgICB0aGlzLnJlcG9zaXRvcnlBcm4gPSB0aGlzLnJlc291cmNlLmFybjtcblxuICAgIGlmIChwcm9wcy5lbXB0eU9uRGVsZXRlID09PSBmYWxzZSAmJiBwcm9wcy5hdXRvRGVsZXRlSW1hZ2VzKSB7XG4gICAgICAvLyBUT0RPOiBWYWxpZGF0aW9uRXJyb3JcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgXCJDYW5ub3QgdXNlICdhdXRvRGVsZXRlSW1hZ2VzJyBwcm9wZXJ0eSBvbiBhIHJlcG9zaXRvcnkgd2l0aG91dCBzZXR0aW5nIGZvcmNlRGVsZXRlIHRvICd0cnVlJy5cIixcbiAgICAgICk7XG4gICAgfSBlbHNlIGlmIChwcm9wcy5hdXRvRGVsZXRlSW1hZ2VzKSB7XG4gICAgICAvLyBUT0RPOiBJbXBsZW1lbnQgQ3VzdG9tIFJlc291cmNlIGZvciBhdXRvLWRlbGV0aW5nIGltYWdlcy5cbiAgICAgIC8vIHRoaXMuZW5hYmxlQXV0b0RlbGV0ZUltYWdlcygpO1xuICAgICAgQW5ub3RhdGlvbnMub2YodGhpcykuYWRkV2FybmluZyhcbiAgICAgICAgXCJhdXRvRGVsZXRlSW1hZ2VzIGlzIGRlcHJlY2F0ZWQgYW5kIG5vdCBpbXBsZW1lbnRlZC4gVXNlIGZvcmNlRGVsZXRlIGluc3RlYWQuXCIsXG4gICAgICApO1xuICAgIH1cblxuICAgIHRoaXMubm9kZS5hZGRWYWxpZGF0aW9uKHtcbiAgICAgIHZhbGlkYXRlOiAoKSA9PiB0aGlzLnBvbGljeURvY3VtZW50Py52YWxpZGF0ZUZvclJlc291cmNlUG9saWN5KCkgPz8gW10sXG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogQWRkIGEgcG9saWN5IHN0YXRlbWVudCB0byB0aGUgcmVwb3NpdG9yeSdzIHJlc291cmNlIHBvbGljeS5cbiAgICovXG4gIHB1YmxpYyBhZGRUb1Jlc291cmNlUG9saWN5KFxuICAgIHN0YXRlbWVudDogaWFtLlBvbGljeVN0YXRlbWVudCxcbiAgKTogaWFtLkFkZFRvUmVzb3VyY2VQb2xpY3lSZXN1bHQge1xuICAgIGlmIChzdGF0ZW1lbnQucmVzb3VyY2VzLmxlbmd0aCkge1xuICAgICAgLy8gVE9ETzogQW5ub3RhdGlvbnMub2YodGhpcykuYWRkV2FybmluZ1YyKCdAYXdzLWNkay9hd3MtZWNyOm5vUmVzb3VyY2VTdGF0ZW1lbnRzLCAuLi4pXG4gICAgICBBbm5vdGF0aW9ucy5vZih0aGlzKS5hZGRXYXJuaW5nKFxuICAgICAgICBcIkVDUiByZXNvdXJjZSBwb2xpY3kgZG9lcyBub3QgYWxsb3cgcmVzb3VyY2Ugc3RhdGVtZW50cy5cIixcbiAgICAgICk7XG4gICAgfVxuICAgIGlmICh0aGlzLnBvbGljeURvY3VtZW50ID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHRoaXMucG9saWN5RG9jdW1lbnQgPSBuZXcgaWFtLlBvbGljeURvY3VtZW50KHRoaXMsIFwiUG9saWN5RG9jdW1lbnRcIik7XG4gICAgICBuZXcgZWNyUmVwb3NpdG9yeVBvbGljeS5FY3JSZXBvc2l0b3J5UG9saWN5KHRoaXMsIFwiUG9saWN5XCIsIHtcbiAgICAgICAgcmVwb3NpdG9yeTogdGhpcy5yZXBvc2l0b3J5TmFtZSxcbiAgICAgICAgcG9saWN5OiB0aGlzLnBvbGljeURvY3VtZW50Lmpzb24sXG4gICAgICB9KTtcbiAgICB9XG4gICAgdGhpcy5wb2xpY3lEb2N1bWVudC5hZGRTdGF0ZW1lbnRzKHN0YXRlbWVudCk7XG4gICAgcmV0dXJuIHsgc3RhdGVtZW50QWRkZWQ6IHRydWUsIHBvbGljeURlcGVuZGFibGU6IHRoaXMucG9saWN5RG9jdW1lbnQgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGUgVVJJIG9mIHRoaXMgcmVwb3NpdG9yeSdzIHJlZ2lzdHJ5OlxuICAgKlxuICAgKiAgICBBQ0NPVU5ULmRrci5lY3IuUkVHSU9OLmFtYXpvbmF3cy5jb21cbiAgICpcbiAgICovXG4gIHB1YmxpYyBnZXQgcmVnaXN0cnlVcmkoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gdGhpcy5yZXNvdXJjZS5yZWdpc3RyeUlkO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgdGhlIFVSTCBvZiB0aGUgcmVwb3NpdG9yeS4gQ2FuIGJlIHVzZWQgaW4gYGRvY2tlciBwdXNoL3B1bGxgLlxuICAgKlxuICAgKiAgICBBQ0NPVU5ULmRrci5lY3IuUkVHSU9OLmFtYXpvbmF3cy5jb20vUkVQT1NJVE9SWVs6VEFHXVxuICAgKlxuICAgKiBAcGFyYW0gdGFnIE9wdGlvbmFsIGltYWdlIHRhZ1xuICAgKi9cbiAgcHVibGljIHJlcG9zaXRvcnlVcmlGb3JUYWcodGFnPzogc3RyaW5nKTogc3RyaW5nIHtcbiAgICBjb25zdCB0YWdTdWZmaXggPSB0YWcgPyBgOiR7dGFnfWAgOiBcIlwiO1xuICAgIHJldHVybiB0aGlzLnJlc291cmNlLnJlcG9zaXRvcnlVcmwgKyB0YWdTdWZmaXg7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyB0aGUgVVJMIG9mIHRoZSByZXBvc2l0b3J5LiBDYW4gYmUgdXNlZCBpbiBgZG9ja2VyIHB1c2gvcHVsbGAuXG4gICAqXG4gICAqICAgIEFDQ09VTlQuZGtyLmVjci5SRUdJT04uYW1hem9uYXdzLmNvbS9SRVBPU0lUT1JZW0BESUdFU1RdXG4gICAqXG4gICAqIEBwYXJhbSBkaWdlc3QgT3B0aW9uYWwgaW1hZ2UgZGlnZXN0XG4gICAqL1xuICBwdWJsaWMgcmVwb3NpdG9yeVVyaUZvckRpZ2VzdChkaWdlc3Q/OiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIGNvbnN0IGRpZ2VzdFN1ZmZpeCA9IGRpZ2VzdCA/IGBAJHtkaWdlc3R9YCA6IFwiXCI7XG4gICAgcmV0dXJuIHRoaXMucmVzb3VyY2UucmVwb3NpdG9yeVVybCArIGRpZ2VzdFN1ZmZpeDtcbiAgfVxuXG4gIC8qKlxuICAgKiBBZGQgYSBsaWZlIGN5Y2xlIHJ1bGUgdG8gdGhlIHJlcG9zaXRvcnlcbiAgICpcbiAgICogTGlmZSBjeWNsZSBydWxlcyBhdXRvbWF0aWNhbGx5IGV4cGlyZSBpbWFnZXMgZnJvbSB0aGUgcmVwb3NpdG9yeSB0aGF0IG1hdGNoXG4gICAqIGNlcnRhaW4gY29uZGl0aW9ucy5cbiAgICovXG4gIHB1YmxpYyBhZGRMaWZlY3ljbGVSdWxlKHJ1bGU6IExpZmVjeWNsZVJ1bGUpIHtcbiAgICAvLyBWYWxpZGF0ZSBydWxlIGhlcmUgc28gdXNlcnMgZ2V0IGVycm9ycyBhdCB0aGUgZXhwZWN0ZWQgbG9jYXRpb25cbiAgICBpZiAocnVsZS50YWdTdGF0dXMgPT09IHVuZGVmaW5lZCkge1xuICAgICAgcnVsZSA9IHtcbiAgICAgICAgLi4ucnVsZSxcbiAgICAgICAgdGFnU3RhdHVzOlxuICAgICAgICAgIHJ1bGUudGFnUHJlZml4TGlzdCA9PT0gdW5kZWZpbmVkICYmIHJ1bGUudGFnUGF0dGVybkxpc3QgPT09IHVuZGVmaW5lZFxuICAgICAgICAgICAgPyBUYWdTdGF0dXMuQU5ZXG4gICAgICAgICAgICA6IFRhZ1N0YXR1cy5UQUdHRUQsXG4gICAgICB9O1xuICAgIH1cblxuICAgIGlmIChcbiAgICAgIHJ1bGUudGFnU3RhdHVzID09PSBUYWdTdGF0dXMuVEFHR0VEICYmXG4gICAgICAocnVsZS50YWdQcmVmaXhMaXN0ID09PSB1bmRlZmluZWQgfHwgcnVsZS50YWdQcmVmaXhMaXN0Lmxlbmd0aCA9PT0gMCkgJiZcbiAgICAgIChydWxlLnRhZ1BhdHRlcm5MaXN0ID09PSB1bmRlZmluZWQgfHwgcnVsZS50YWdQYXR0ZXJuTGlzdC5sZW5ndGggPT09IDApXG4gICAgKSB7XG4gICAgICAvLyBUT0RPOiBWYWxpZGF0aW9uRXJyb3JcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgXCJUYWdTdGF0dXMuVGFnZ2VkIHJlcXVpcmVzIHRoZSBzcGVjaWZpY2F0aW9uIG9mIGEgdGFnUHJlZml4TGlzdCBvciBhIHRhZ1BhdHRlcm5MaXN0XCIsXG4gICAgICApO1xuICAgIH1cbiAgICBpZiAoXG4gICAgICBydWxlLnRhZ1N0YXR1cyAhPT0gVGFnU3RhdHVzLlRBR0dFRCAmJlxuICAgICAgKHJ1bGUudGFnUHJlZml4TGlzdCAhPT0gdW5kZWZpbmVkIHx8IHJ1bGUudGFnUGF0dGVybkxpc3QgIT09IHVuZGVmaW5lZClcbiAgICApIHtcbiAgICAgIC8vIFRPRE86IFZhbGlkYXRpb25FcnJvclxuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICBcInRhZ1ByZWZpeExpc3QgYW5kIHRhZ1BhdHRlcm5MaXN0IGNhbiBvbmx5IGJlIHNwZWNpZmllZCB3aGVuIHRhZ1N0YXR1cyBpcyBzZXQgdG8gVGFnZ2VkXCIsXG4gICAgICApO1xuICAgIH1cbiAgICBpZiAocnVsZS50YWdQcmVmaXhMaXN0ICE9PSB1bmRlZmluZWQgJiYgcnVsZS50YWdQYXR0ZXJuTGlzdCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAvLyBUT0RPOiBWYWxpZGF0aW9uRXJyb3JcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgXCJCb3RoIHRhZ1ByZWZpeExpc3QgYW5kIHRhZ1BhdHRlcm5MaXN0IGNhbm5vdCBiZSBzcGVjaWZpZWQgdG9nZXRoZXIgaW4gYSBydWxlXCIsXG4gICAgICApO1xuICAgIH1cbiAgICBpZiAocnVsZS50YWdQYXR0ZXJuTGlzdCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBydWxlLnRhZ1BhdHRlcm5MaXN0LmZvckVhY2goKHBhdHRlcm4pID0+IHtcbiAgICAgICAgY29uc3Qgc3BsaXRQYXR0ZXJuTGVuZ3RoID0gcGF0dGVybi5zcGxpdChcIipcIikubGVuZ3RoO1xuICAgICAgICBpZiAoc3BsaXRQYXR0ZXJuTGVuZ3RoID4gNSkge1xuICAgICAgICAgIC8vIFRPRE86IFZhbGlkYXRpb25FcnJvclxuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICAgIGBBIHRhZyBwYXR0ZXJuIGNhbm5vdCBjb250YWluIG1vcmUgdGhhbiBmb3VyIHdpbGRjYXJkIGNoYXJhY3RlcnMgKCopLCBwYXR0ZXJuOiAke3BhdHRlcm59LCBjb3VudHM6ICR7XG4gICAgICAgICAgICAgIHNwbGl0UGF0dGVybkxlbmd0aCAtIDFcbiAgICAgICAgICAgIH1gLFxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH1cbiAgICBpZiAoXG4gICAgICAocnVsZS5tYXhJbWFnZUFnZSAhPT0gdW5kZWZpbmVkKSA9PT1cbiAgICAgIChydWxlLm1heEltYWdlQ291bnQgIT09IHVuZGVmaW5lZClcbiAgICApIHtcbiAgICAgIC8vIFRPRE86IFZhbGlkYXRpb25FcnJvclxuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICBgTGlmZSBjeWNsZSBydWxlIG11c3QgY29udGFpbiBleGFjdGx5IG9uZSBvZiAnbWF4SW1hZ2VBZ2UnIGFuZCAnbWF4SW1hZ2VDb3VudCcsIGdvdDogJHtKU09OLnN0cmluZ2lmeShcbiAgICAgICAgICBydWxlLFxuICAgICAgICApfWAsXG4gICAgICApO1xuICAgIH1cblxuICAgIGlmIChcbiAgICAgIHJ1bGUudGFnU3RhdHVzID09PSBUYWdTdGF0dXMuQU5ZICYmXG4gICAgICB0aGlzLmxpZmVjeWNsZVJ1bGVzLmZpbHRlcigocikgPT4gci50YWdTdGF0dXMgPT09IFRhZ1N0YXR1cy5BTlkpLmxlbmd0aCA+XG4gICAgICAgIDBcbiAgICApIHtcbiAgICAgIC8vIFRPRE86IFZhbGlkYXRpb25FcnJvclxuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTGlmZSBjeWNsZSBjYW4gb25seSBoYXZlIG9uZSBUYWdTdGF0dXMuQW55IHJ1bGVcIik7XG4gICAgfVxuXG4gICAgdGhpcy5saWZlY3ljbGVSdWxlcy5wdXNoKHsgLi4ucnVsZSB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZW5kZXIgdGhlIGxpZmUgY3ljbGUgcG9saWN5IG9iamVjdFxuICAgKi9cbiAgcHJpdmF0ZSByZW5kZXJMaWZlY3ljbGVQb2xpY3koKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgICBpZiAodGhpcy5saWZlY3ljbGVSdWxlcy5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgY29uc3QgcG9saWN5ID0ge1xuICAgICAgcnVsZXM6IHRoaXMub3JkZXJlZExpZmVjeWNsZVJ1bGVzKCkubWFwKHJlbmRlckxpZmVjeWNsZVJ1bGUpLFxuICAgIH07XG5cbiAgICByZXR1cm4gdGhpcy5zdGFjay50b0pzb25TdHJpbmcocG9saWN5KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm4gbGlmZSBjeWNsZSBydWxlcyB3aXRoIGF1dG9tYXRpYyBvcmRlcmluZyBhcHBsaWVkLlxuICAgKlxuICAgKiBBbHNvIGFwcGxpZXMgdmFsaWRhdGlvbiBvZiB0aGUgJ2FueScgcnVsZS5cbiAgICovXG4gIHByaXZhdGUgb3JkZXJlZExpZmVjeWNsZVJ1bGVzKCk6IExpZmVjeWNsZVJ1bGVbXSB7XG4gICAgaWYgKHRoaXMubGlmZWN5Y2xlUnVsZXMubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm4gW107XG4gICAgfVxuXG4gICAgY29uc3QgcHJpb3JpdGl6ZWRSdWxlcyA9IHRoaXMubGlmZWN5Y2xlUnVsZXMuZmlsdGVyKFxuICAgICAgKHIpID0+IHIucnVsZVByaW9yaXR5ICE9PSB1bmRlZmluZWQgJiYgci50YWdTdGF0dXMgIT09IFRhZ1N0YXR1cy5BTlksXG4gICAgKTtcbiAgICBjb25zdCBhdXRvUHJpb3JpdGl6ZWRSdWxlcyA9IHRoaXMubGlmZWN5Y2xlUnVsZXMuZmlsdGVyKFxuICAgICAgKHIpID0+IHIucnVsZVByaW9yaXR5ID09PSB1bmRlZmluZWQgJiYgci50YWdTdGF0dXMgIT09IFRhZ1N0YXR1cy5BTlksXG4gICAgKTtcbiAgICBjb25zdCBhbnlSdWxlcyA9IHRoaXMubGlmZWN5Y2xlUnVsZXMuZmlsdGVyKFxuICAgICAgKHIpID0+IHIudGFnU3RhdHVzID09PSBUYWdTdGF0dXMuQU5ZLFxuICAgICk7XG4gICAgaWYgKFxuICAgICAgYW55UnVsZXMubGVuZ3RoID4gMCAmJlxuICAgICAgYW55UnVsZXNbMF0ucnVsZVByaW9yaXR5ICE9PSB1bmRlZmluZWQgJiZcbiAgICAgIGF1dG9Qcmlvcml0aXplZFJ1bGVzLmxlbmd0aCA+IDBcbiAgICApIHtcbiAgICAgIC8vIFN1cHBvcnRpbmcgdGhpcyBpcyB0b28gY29tcGxleCBmb3IgdmVyeSBsaXR0bGUgdmFsdWUuIFdlIGp1c3QgcHJvaGliaXQgaXQuXG4gICAgICAvLyBUT0RPOiBWYWxpZGF0aW9uRXJyb3JcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgXCJDYW5ub3QgY29tYmluZSBwcmlvcml0aXplZCBUYWdTdGF0dXMuQW55IHJ1bGUgd2l0aCB1bnByaW9yaXRpemVkIHJ1bGVzLiBSZW1vdmUgcnVsZVByaW9yaXR5IGZyb20gdGhlICdBbnknIHJ1bGUuXCIsXG4gICAgICApO1xuICAgIH1cblxuICAgIGNvbnN0IHByaW9zID0gcHJpb3JpdGl6ZWRSdWxlcy5tYXAoKHIpID0+IHIucnVsZVByaW9yaXR5ISk7XG4gICAgbGV0IGF1dG9QcmlvID0gKHByaW9zLmxlbmd0aCA+IDAgPyBNYXRoLm1heCguLi5wcmlvcykgOiAwKSArIDE7XG5cbiAgICBjb25zdCByZXQgPSBuZXcgQXJyYXk8TGlmZWN5Y2xlUnVsZT4oKTtcbiAgICBmb3IgKGNvbnN0IHJ1bGUgb2YgcHJpb3JpdGl6ZWRSdWxlc1xuICAgICAgLmNvbmNhdChhdXRvUHJpb3JpdGl6ZWRSdWxlcylcbiAgICAgIC5jb25jYXQoYW55UnVsZXMpKSB7XG4gICAgICByZXQucHVzaCh7XG4gICAgICAgIC4uLnJ1bGUsXG4gICAgICAgIHJ1bGVQcmlvcml0eTogcnVsZS5ydWxlUHJpb3JpdHkgPz8gYXV0b1ByaW8rKyxcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIC8vIERvIHZhbGlkYXRpb24gb24gdGhlIGZpbmFsIGFycmF5LS1taWdodCBzdGlsbCBiZSB3cm9uZyBiZWNhdXNlIHRoZSB1c2VyIHN1cHBsaWVkIGFsbCBwcmlvcywgYnV0IGluY29ycmVjdGx5LlxuICAgIHZhbGlkYXRlQW55UnVsZUxhc3QocmV0KTtcbiAgICByZXR1cm4gcmV0O1xuICB9XG5cbiAgLyoqXG4gICAqIFNldCB1cCBrZXkgcHJvcGVydGllcyBhbmQgcmV0dXJuIHRoZSBSZXBvc2l0b3J5IGVuY3J5cHRpb24gcHJvcGVydHkgZnJvbSB0aGVcbiAgICogdXNlcidzIGNvbmZpZ3VyYXRpb24uXG4gICAqL1xuICBwcml2YXRlIHBhcnNlRW5jcnlwdGlvbihcbiAgICBwcm9wczogUmVwb3NpdG9yeVByb3BzLFxuICApOiBlY3JSZXBvc2l0b3J5LkVjclJlcG9zaXRvcnlFbmNyeXB0aW9uQ29uZmlndXJhdGlvbltdIHwgdW5kZWZpbmVkIHtcbiAgICAvLyBkZWZhdWx0IGJhc2VkIG9uIHdoZXRoZXIgZW5jcnlwdGlvbktleSBpcyBzcGVjaWZpZWRcbiAgICBjb25zdCBlbmNyeXB0aW9uVHlwZSA9XG4gICAgICBwcm9wcy5lbmNyeXB0aW9uID8/XG4gICAgICAocHJvcHMuZW5jcnlwdGlvbktleVxuICAgICAgICA/IFJlcG9zaXRvcnlFbmNyeXB0aW9uLktNU1xuICAgICAgICA6IFJlcG9zaXRvcnlFbmNyeXB0aW9uLkFFU18yNTYpO1xuXG4gICAgLy8gaWYgZW5jcnlwdGlvbiBrZXkgaXMgc2V0LCBlbmNyeXB0aW9uIG11c3QgYmUgc2V0IHRvIEtNUy5cbiAgICBpZiAoZW5jcnlwdGlvblR5cGUgIT09IFJlcG9zaXRvcnlFbmNyeXB0aW9uLktNUyAmJiBwcm9wcy5lbmNyeXB0aW9uS2V5KSB7XG4gICAgICAvLyBUT0RPOiBWYWxpZGF0aW9uRXJyb3JcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgYGVuY3J5cHRpb25LZXkgaXMgc3BlY2lmaWVkLCBzbyAnZW5jcnlwdGlvbicgbXVzdCBiZSBzZXQgdG8gS01TICh2YWx1ZTogJHtlbmNyeXB0aW9uVHlwZS52YWx1ZX0pYCxcbiAgICAgICk7XG4gICAgfVxuXG4gICAgaWYgKGVuY3J5cHRpb25UeXBlID09PSBSZXBvc2l0b3J5RW5jcnlwdGlvbi5BRVNfMjU2KSB7XG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIGlmIChlbmNyeXB0aW9uVHlwZSA9PT0gUmVwb3NpdG9yeUVuY3J5cHRpb24uS01TKSB7XG4gICAgICByZXR1cm4gW1xuICAgICAgICB7XG4gICAgICAgICAgZW5jcnlwdGlvblR5cGU6IFwiS01TXCIsXG4gICAgICAgICAga21zS2V5OiBwcm9wcy5lbmNyeXB0aW9uS2V5Py5rZXlBcm4sXG4gICAgICAgIH0sXG4gICAgICBdO1xuICAgIH1cblxuICAgIC8vIFRPRE86IFZhbGlkYXRpb25FcnJvclxuICAgIHRocm93IG5ldyBFcnJvcihgVW5leHBlY3RlZCAnZW5jcnlwdGlvblR5cGUnOiAke2VuY3J5cHRpb25UeXBlfWApO1xuICB9XG5cbiAgLyoqXG4gICAqIEFkZHMgcmVzb3VyY2UgdG8gdGhlIFRlcnJhZm9ybSBKU09OIG91dHB1dCBhdCBTeW50aCB0aW1lLlxuICAgKlxuICAgKiBjYWxsZWQgYnkgVGVycmFmb3JtU3RhY2sucHJlcGFyZVN0YWNrKClcbiAgICovXG4gIHB1YmxpYyB0b1RlcnJhZm9ybSgpOiBhbnkge1xuICAgIC8qKlxuICAgICAqIEEgcHJlcGFyaW5nIHJlc29sdmUgbWlnaHQgYWRkIG5ldyByZXNvdXJjZXMgdG8gdGhlIHN0YWNrXG4gICAgICovXG4gICAgY29uc3QgbGlmZUN5Y2xlUG9saWN5ID0gdGhpcy5yZW5kZXJMaWZlY3ljbGVQb2xpY3koKTtcbiAgICAvLyBpZ25vcmUgaWYgdW5kZWZpbmVkIG9yIGFscmVhZHkgZ2VuZXJhdGVkXG4gICAgaWYgKGxpZmVDeWNsZVBvbGljeSAmJiAhdGhpcy5ub2RlLnRyeUZpbmRDaGlsZChcIkxpZmVjeWNsZVBvbGljeVwiKSkge1xuICAgICAgbmV3IGVjckxpZmVjeWNsZVBvbGljeS5FY3JMaWZlY3ljbGVQb2xpY3kodGhpcywgXCJMaWZlY3ljbGVQb2xpY3lcIiwge1xuICAgICAgICByZXBvc2l0b3J5OiB0aGlzLnJlcG9zaXRvcnlOYW1lLFxuICAgICAgICBwb2xpY3k6IGxpZmVDeWNsZVBvbGljeSxcbiAgICAgIH0pO1xuICAgIH1cbiAgICByZXR1cm4ge307XG4gIH1cbn1cblxuZnVuY3Rpb24gdmFsaWRhdGVBbnlSdWxlTGFzdChydWxlczogTGlmZWN5Y2xlUnVsZVtdKSB7XG4gIGNvbnN0IGFueVJ1bGVzID0gcnVsZXMuZmlsdGVyKChyKSA9PiByLnRhZ1N0YXR1cyA9PT0gVGFnU3RhdHVzLkFOWSk7XG4gIGlmIChhbnlSdWxlcy5sZW5ndGggPT09IDEpIHtcbiAgICBjb25zdCBtYXhQcmlvID0gTWF0aC5tYXgoLi4ucnVsZXMubWFwKChyKSA9PiByLnJ1bGVQcmlvcml0eSEpKTtcbiAgICBpZiAoYW55UnVsZXNbMF0ucnVsZVByaW9yaXR5ICE9PSBtYXhQcmlvKSB7XG4gICAgICAvLyBUT0RPOiBVbnNjb3BlZFZhbGlkYXRpb25FcnJvclxuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICBgVGFnU3RhdHVzLkFueSBydWxlIG11c3QgaGF2ZSBoaWdoZXN0IHByaW9yaXR5LCBoYXMgJHthbnlSdWxlc1swXS5ydWxlUHJpb3JpdHl9IHdoaWNoIGlzIHNtYWxsZXIgdGhhbiAke21heFByaW99YCxcbiAgICAgICk7XG4gICAgfVxuICB9XG59XG5cbi8qKlxuICogUmVuZGVyIHRoZSBsaWZlY3ljbGUgcnVsZSB0byBKU09OXG4gKi9cbmZ1bmN0aW9uIHJlbmRlckxpZmVjeWNsZVJ1bGUocnVsZTogTGlmZWN5Y2xlUnVsZSkge1xuICByZXR1cm4ge1xuICAgIHJ1bGVQcmlvcml0eTogcnVsZS5ydWxlUHJpb3JpdHksXG4gICAgZGVzY3JpcHRpb246IHJ1bGUuZGVzY3JpcHRpb24sXG4gICAgc2VsZWN0aW9uOiB7XG4gICAgICB0YWdTdGF0dXM6IHJ1bGUudGFnU3RhdHVzIHx8IFRhZ1N0YXR1cy5BTlksXG4gICAgICB0YWdQcmVmaXhMaXN0OiBydWxlLnRhZ1ByZWZpeExpc3QsXG4gICAgICB0YWdQYXR0ZXJuTGlzdDogcnVsZS50YWdQYXR0ZXJuTGlzdCxcbiAgICAgIGNvdW50VHlwZTpcbiAgICAgICAgcnVsZS5tYXhJbWFnZUFnZSAhPT0gdW5kZWZpbmVkXG4gICAgICAgICAgPyBDb3VudFR5cGUuU0lOQ0VfSU1BR0VfUFVTSEVEXG4gICAgICAgICAgOiBDb3VudFR5cGUuSU1BR0VfQ09VTlRfTU9SRV9USEFOLFxuICAgICAgY291bnROdW1iZXI6IHJ1bGUubWF4SW1hZ2VBZ2U/LnRvRGF5cygpID8/IHJ1bGUubWF4SW1hZ2VDb3VudCxcbiAgICAgIGNvdW50VW5pdDogcnVsZS5tYXhJbWFnZUFnZSAhPT0gdW5kZWZpbmVkID8gXCJkYXlzXCIgOiB1bmRlZmluZWQsXG4gICAgfSxcbiAgICBhY3Rpb246IHtcbiAgICAgIHR5cGU6IFwiZXhwaXJlXCIsXG4gICAgfSxcbiAgfTtcbn1cblxuLyoqXG4gKiBTZWxlY3QgaW1hZ2VzIGJhc2VkIG9uIGNvdW50c1xuICovXG5lbnVtIENvdW50VHlwZSB7XG4gIC8qKlxuICAgKiBTZXQgYSBsaW1pdCBvbiB0aGUgbnVtYmVyIG9mIGltYWdlcyBpbiB5b3VyIHJlcG9zaXRvcnlcbiAgICovXG4gIElNQUdFX0NPVU5UX01PUkVfVEhBTiA9IFwiaW1hZ2VDb3VudE1vcmVUaGFuXCIsXG5cbiAgLyoqXG4gICAqIFNldCBhbiBhZ2UgbGltaXQgb24gdGhlIGltYWdlcyBpbiB5b3VyIHJlcG9zaXRvcnlcbiAgICovXG4gIFNJTkNFX0lNQUdFX1BVU0hFRCA9IFwic2luY2VJbWFnZVB1c2hlZFwiLFxufVxuXG4vKipcbiAqIFRoZSB0YWcgbXV0YWJpbGl0eSBzZXR0aW5nIGZvciB5b3VyIHJlcG9zaXRvcnkuXG4gKi9cbmV4cG9ydCBlbnVtIFRhZ011dGFiaWxpdHkge1xuICAvKipcbiAgICogYWxsb3cgaW1hZ2UgdGFncyB0byBiZSBvdmVyd3JpdHRlbi5cbiAgICovXG4gIE1VVEFCTEUgPSBcIk1VVEFCTEVcIixcblxuICAvKipcbiAgICogYWxsIGltYWdlIHRhZ3Mgd2l0aGluIHRoZSByZXBvc2l0b3J5IHdpbGwgYmUgaW1tdXRhYmxlIHdoaWNoIHdpbGwgcHJldmVudCB0aGVtIGZyb20gYmVpbmcgb3ZlcndyaXR0ZW4uXG4gICAqL1xuICBJTU1VVEFCTEUgPSBcIklNTVVUQUJMRVwiLFxufVxuXG4vKipcbiAqIEluZGljYXRlcyB3aGV0aGVyIHNlcnZlci1zaWRlIGVuY3J5cHRpb24gaXMgZW5hYmxlZCBmb3IgdGhlIG9iamVjdCwgYW5kIHdoZXRoZXIgdGhhdCBlbmNyeXB0aW9uIGlzXG4gKiBmcm9tIHRoZSBBV1MgS2V5IE1hbmFnZW1lbnQgU2VydmljZSAoQVdTIEtNUykgb3IgZnJvbSBBbWF6b24gUzMgbWFuYWdlZCBlbmNyeXB0aW9uIChTU0UtUzMpLlxuICogQHNlZSBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uUzMvbGF0ZXN0L2Rldi9Vc2luZ01ldGFkYXRhLmh0bWwjU3lzTWV0YWRhdGFcbiAqL1xuZXhwb3J0IGNsYXNzIFJlcG9zaXRvcnlFbmNyeXB0aW9uIHtcbiAgLyoqXG4gICAqICdBRVMyNTYnXG4gICAqL1xuICBwdWJsaWMgc3RhdGljIHJlYWRvbmx5IEFFU18yNTYgPSBuZXcgUmVwb3NpdG9yeUVuY3J5cHRpb24oXCJBRVMyNTZcIik7XG4gIC8qKlxuICAgKiAnS01TJ1xuICAgKi9cbiAgcHVibGljIHN0YXRpYyByZWFkb25seSBLTVMgPSBuZXcgUmVwb3NpdG9yeUVuY3J5cHRpb24oXCJLTVNcIik7XG4gIC8qKlxuICAgKiAnS01TX0RTU0UnXG4gICAqL1xuICBwdWJsaWMgc3RhdGljIHJlYWRvbmx5IEtNU19EU1NFID0gbmV3IFJlcG9zaXRvcnlFbmNyeXB0aW9uKFwiS01TX0RTU0VcIik7XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB2YWx1ZSB0aGUgc3RyaW5nIHZhbHVlIG9mIHRoZSBlbmNyeXB0aW9uXG4gICAqL1xuICBwcm90ZWN0ZWQgY29uc3RydWN0b3IocHVibGljIHJlYWRvbmx5IHZhbHVlOiBzdHJpbmcpIHt9XG59XG4iXX0=
|