terraconstructs 0.0.8
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/.envrc +5 -0
- package/.jsii +79780 -0
- package/.mise.toml +8 -0
- package/.nvmrc +1 -0
- package/.terraform-version +1 -0
- package/.terraform.d/plugin-cache/.gitignore +5 -0
- package/LICENSE +674 -0
- package/NOTICE.txt +12 -0
- package/README.md +42 -0
- package/bun.lockb +0 -0
- package/go.mod +158 -0
- package/go.sum +1206 -0
- package/lib/aws/arn.d.ts +187 -0
- package/lib/aws/arn.js +383 -0
- package/lib/aws/aws-construct.d.ts +76 -0
- package/lib/aws/aws-construct.js +38 -0
- package/lib/aws/aws-stack.d.ts +201 -0
- package/lib/aws/aws-stack.js +303 -0
- package/lib/aws/cloudwatch/actions/ec2.d.ts +35 -0
- package/lib/aws/cloudwatch/actions/ec2.js +48 -0
- package/lib/aws/cloudwatch/actions/index.d.ts +2 -0
- package/lib/aws/cloudwatch/actions/index.js +24 -0
- package/lib/aws/cloudwatch/actions/lambda.d.ts +16 -0
- package/lib/aws/cloudwatch/actions/lambda.js +48 -0
- package/lib/aws/cloudwatch/alarm-action.d.ts +23 -0
- package/lib/aws/cloudwatch/alarm-action.js +4 -0
- package/lib/aws/cloudwatch/alarm-base.d.ts +84 -0
- package/lib/aws/cloudwatch/alarm-base.js +64 -0
- package/lib/aws/cloudwatch/alarm-rule.d.ts +61 -0
- package/lib/aws/cloudwatch/alarm-rule.js +116 -0
- package/lib/aws/cloudwatch/alarm-status-widget.d.ts +77 -0
- package/lib/aws/cloudwatch/alarm-status-widget.js +62 -0
- package/lib/aws/cloudwatch/alarm.d.ts +158 -0
- package/lib/aws/cloudwatch/alarm.js +410 -0
- package/lib/aws/cloudwatch/composite-alarm.d.ts +88 -0
- package/lib/aws/cloudwatch/composite-alarm.js +98 -0
- package/lib/aws/cloudwatch/dashboard.d.ts +137 -0
- package/lib/aws/cloudwatch/dashboard.js +141 -0
- package/lib/aws/cloudwatch/data-protection-policy.d.ts +184 -0
- package/lib/aws/cloudwatch/data-protection-policy.js +246 -0
- package/lib/aws/cloudwatch/graph.d.ts +792 -0
- package/lib/aws/cloudwatch/graph.js +537 -0
- package/lib/aws/cloudwatch/index.d.ts +26 -0
- package/lib/aws/cloudwatch/index.js +49 -0
- package/lib/aws/cloudwatch/layout.d.ts +89 -0
- package/lib/aws/cloudwatch/layout.js +147 -0
- package/lib/aws/cloudwatch/log-destinations/index.d.ts +2 -0
- package/lib/aws/cloudwatch/log-destinations/index.js +20 -0
- package/lib/aws/cloudwatch/log-destinations/kinesis.d.ts +29 -0
- package/lib/aws/cloudwatch/log-destinations/kinesis.js +52 -0
- package/lib/aws/cloudwatch/log-destinations/lambda.d.ts +22 -0
- package/lib/aws/cloudwatch/log-destinations/lambda.js +46 -0
- package/lib/aws/cloudwatch/log-group.d.ts +453 -0
- package/lib/aws/cloudwatch/log-group.js +350 -0
- package/lib/aws/cloudwatch/log-query.d.ts +91 -0
- package/lib/aws/cloudwatch/log-query.js +85 -0
- package/lib/aws/cloudwatch/log-stream.d.ts +57 -0
- package/lib/aws/cloudwatch/log-stream.js +57 -0
- package/lib/aws/cloudwatch/metric-filter.d.ts +30 -0
- package/lib/aws/cloudwatch/metric-filter.js +69 -0
- package/lib/aws/cloudwatch/metric-types.d.ts +407 -0
- package/lib/aws/cloudwatch/metric-types.js +151 -0
- package/lib/aws/cloudwatch/metric.d.ts +492 -0
- package/lib/aws/cloudwatch/metric.js +493 -0
- package/lib/aws/cloudwatch/pattern.d.ts +195 -0
- package/lib/aws/cloudwatch/pattern.js +412 -0
- package/lib/aws/cloudwatch/policy.d.ts +43 -0
- package/lib/aws/cloudwatch/policy.js +50 -0
- package/lib/aws/cloudwatch/private/drop-empty-object-at-the-end-of-an-array-token.d.ts +14 -0
- package/lib/aws/cloudwatch/private/drop-empty-object-at-the-end-of-an-array-token.js +37 -0
- package/lib/aws/cloudwatch/private/env-tokens.d.ts +8 -0
- package/lib/aws/cloudwatch/private/env-tokens.js +48 -0
- package/lib/aws/cloudwatch/private/metric-util.d.ts +60 -0
- package/lib/aws/cloudwatch/private/metric-util.js +132 -0
- package/lib/aws/cloudwatch/private/object.d.ts +1 -0
- package/lib/aws/cloudwatch/private/object.js +18 -0
- package/lib/aws/cloudwatch/private/rendering.d.ts +60 -0
- package/lib/aws/cloudwatch/private/rendering.js +181 -0
- package/lib/aws/cloudwatch/private/statistic.d.ts +51 -0
- package/lib/aws/cloudwatch/private/statistic.js +176 -0
- package/lib/aws/cloudwatch/query-definition.d.ts +150 -0
- package/lib/aws/cloudwatch/query-definition.js +114 -0
- package/lib/aws/cloudwatch/stats.d.ts +150 -0
- package/lib/aws/cloudwatch/stats.js +207 -0
- package/lib/aws/cloudwatch/subscription-filter.d.ts +75 -0
- package/lib/aws/cloudwatch/subscription-filter.js +51 -0
- package/lib/aws/cloudwatch/text.d.ts +52 -0
- package/lib/aws/cloudwatch/text.js +53 -0
- package/lib/aws/cloudwatch/variable.d.ts +156 -0
- package/lib/aws/cloudwatch/variable.js +156 -0
- package/lib/aws/cloudwatch/widget.d.ts +62 -0
- package/lib/aws/cloudwatch/widget.js +45 -0
- package/lib/aws/compute/activity.d.ts +81 -0
- package/lib/aws/compute/activity.js +132 -0
- package/lib/aws/compute/architecture.d.ts +33 -0
- package/lib/aws/compute/architecture.js +42 -0
- package/lib/aws/compute/chain.d.ts +52 -0
- package/lib/aws/compute/chain.js +68 -0
- package/lib/aws/compute/condition.d.ts +202 -0
- package/lib/aws/compute/condition.js +409 -0
- package/lib/aws/compute/event-invoke-config.d.ts +74 -0
- package/lib/aws/compute/event-invoke-config.js +63 -0
- package/lib/aws/compute/event-source-filter.d.ts +64 -0
- package/lib/aws/compute/event-source-filter.js +86 -0
- package/lib/aws/compute/event-source-mapping.d.ts +310 -0
- package/lib/aws/compute/event-source-mapping.js +267 -0
- package/lib/aws/compute/event-sources/index.d.ts +4 -0
- package/lib/aws/compute/event-sources/index.js +28 -0
- package/lib/aws/compute/event-sources/s3-onfailure-destination.d.ts +13 -0
- package/lib/aws/compute/event-sources/s3-onfailure-destination.js +26 -0
- package/lib/aws/compute/event-sources/s3.d.ts +24 -0
- package/lib/aws/compute/event-sources/s3.js +25 -0
- package/lib/aws/compute/event-sources/sqs-dlq.d.ts +13 -0
- package/lib/aws/compute/event-sources/sqs-dlq.js +26 -0
- package/lib/aws/compute/event-sources/sqs.d.ts +75 -0
- package/lib/aws/compute/event-sources/sqs.js +84 -0
- package/lib/aws/compute/fields.d.ts +367 -0
- package/lib/aws/compute/fields.js +546 -0
- package/lib/aws/compute/function-alias.d.ts +148 -0
- package/lib/aws/compute/function-alias.js +176 -0
- package/lib/aws/compute/function-base.d.ts +314 -0
- package/lib/aws/compute/function-base.js +421 -0
- package/lib/aws/compute/function-destination.d.ts +42 -0
- package/lib/aws/compute/function-destination.js +18 -0
- package/lib/aws/compute/function-destinations/event-bridge.d.ts +19 -0
- package/lib/aws/compute/function-destinations/event-bridge.js +46 -0
- package/lib/aws/compute/function-destinations/function.d.ts +34 -0
- package/lib/aws/compute/function-destinations/function.js +55 -0
- package/lib/aws/compute/function-destinations/index.d.ts +3 -0
- package/lib/aws/compute/function-destinations/index.js +22 -0
- package/lib/aws/compute/function-destinations/sqs.d.ts +14 -0
- package/lib/aws/compute/function-destinations/sqs.js +27 -0
- package/lib/aws/compute/function-nodejs.d.ts +55 -0
- package/lib/aws/compute/function-nodejs.js +70 -0
- package/lib/aws/compute/function-permission.d.ts +83 -0
- package/lib/aws/compute/function-permission.js +3 -0
- package/lib/aws/compute/function-url.d.ts +210 -0
- package/lib/aws/compute/function-url.js +148 -0
- package/lib/aws/compute/function-vpc-config.generated.d.ts +36 -0
- package/lib/aws/compute/function-vpc-config.generated.js +3 -0
- package/lib/aws/compute/function.d.ts +492 -0
- package/lib/aws/compute/function.js +692 -0
- package/lib/aws/compute/index.d.ts +42 -0
- package/lib/aws/compute/index.js +64 -0
- package/lib/aws/compute/private/intrinstics.d.ts +86 -0
- package/lib/aws/compute/private/intrinstics.js +220 -0
- package/lib/aws/compute/private/json-path.d.ts +57 -0
- package/lib/aws/compute/private/json-path.js +351 -0
- package/lib/aws/compute/private/util.d.ts +1 -0
- package/lib/aws/compute/private/util.js +38 -0
- package/lib/aws/compute/state-graph.d.ts +100 -0
- package/lib/aws/compute/state-graph.js +177 -0
- package/lib/aws/compute/state-machine-fragment.d.ts +61 -0
- package/lib/aws/compute/state-machine-fragment.js +56 -0
- package/lib/aws/compute/state-machine.d.ts +323 -0
- package/lib/aws/compute/state-machine.js +392 -0
- package/lib/aws/compute/states/choice.d.ts +94 -0
- package/lib/aws/compute/states/choice.js +81 -0
- package/lib/aws/compute/states/custom-state.d.ts +55 -0
- package/lib/aws/compute/states/custom-state.js +114 -0
- package/lib/aws/compute/states/distributed-map/item-batcher.d.ts +64 -0
- package/lib/aws/compute/states/distributed-map/item-batcher.js +58 -0
- package/lib/aws/compute/states/distributed-map/item-reader.d.ts +256 -0
- package/lib/aws/compute/states/distributed-map/item-reader.js +253 -0
- package/lib/aws/compute/states/distributed-map/result-writer.d.ts +41 -0
- package/lib/aws/compute/states/distributed-map/result-writer.js +66 -0
- package/lib/aws/compute/states/distributed-map.d.ts +153 -0
- package/lib/aws/compute/states/distributed-map.js +207 -0
- package/lib/aws/compute/states/fail.d.ts +74 -0
- package/lib/aws/compute/states/fail.js +83 -0
- package/lib/aws/compute/states/map-base.d.ts +145 -0
- package/lib/aws/compute/states/map-base.js +109 -0
- package/lib/aws/compute/states/map.d.ts +76 -0
- package/lib/aws/compute/states/map.js +110 -0
- package/lib/aws/compute/states/parallel.d.ts +113 -0
- package/lib/aws/compute/states/parallel.js +100 -0
- package/lib/aws/compute/states/pass.d.ts +122 -0
- package/lib/aws/compute/states/pass.js +99 -0
- package/lib/aws/compute/states/private/state-type.d.ts +13 -0
- package/lib/aws/compute/states/private/state-type.js +19 -0
- package/lib/aws/compute/states/state.d.ts +276 -0
- package/lib/aws/compute/states/state.js +482 -0
- package/lib/aws/compute/states/succeed.d.ts +51 -0
- package/lib/aws/compute/states/succeed.js +32 -0
- package/lib/aws/compute/states/task-base.d.ts +225 -0
- package/lib/aws/compute/states/task-base.js +160 -0
- package/lib/aws/compute/states/task.d.ts +127 -0
- package/lib/aws/compute/states/task.js +92 -0
- package/lib/aws/compute/states/wait.d.ts +78 -0
- package/lib/aws/compute/states/wait.js +90 -0
- package/lib/aws/compute/step-functions-task.d.ts +78 -0
- package/lib/aws/compute/step-functions-task.js +27 -0
- package/lib/aws/compute/task-credentials.d.ts +45 -0
- package/lib/aws/compute/task-credentials.js +52 -0
- package/lib/aws/compute/task-input.d.ts +86 -0
- package/lib/aws/compute/task-input.js +107 -0
- package/lib/aws/compute/tasks/aws-sdk/call-aws-service.d.ts +73 -0
- package/lib/aws/compute/tasks/aws-sdk/call-aws-service.js +69 -0
- package/lib/aws/compute/tasks/eventbridge/put-events.d.ts +74 -0
- package/lib/aws/compute/tasks/eventbridge/put-events.js +94 -0
- package/lib/aws/compute/tasks/http/invoke.d.ts +104 -0
- package/lib/aws/compute/tasks/http/invoke.js +117 -0
- package/lib/aws/compute/tasks/index.d.ts +7 -0
- package/lib/aws/compute/tasks/index.js +42 -0
- package/lib/aws/compute/tasks/lambda/invoke.d.ts +106 -0
- package/lib/aws/compute/tasks/lambda/invoke.js +125 -0
- package/lib/aws/compute/tasks/private/task-utils.d.ts +8 -0
- package/lib/aws/compute/tasks/private/task-utils.js +36 -0
- package/lib/aws/compute/tasks/resource-arn-suffix.d.ts +3 -0
- package/lib/aws/compute/tasks/resource-arn-suffix.js +25 -0
- package/lib/aws/compute/tasks/sqs/send-message.d.ts +62 -0
- package/lib/aws/compute/tasks/sqs/send-message.js +70 -0
- package/lib/aws/compute/tasks/stepfunctions/invoke-activity.d.ts +36 -0
- package/lib/aws/compute/tasks/stepfunctions/invoke-activity.js +45 -0
- package/lib/aws/compute/tasks/stepfunctions/start-execution.d.ts +63 -0
- package/lib/aws/compute/tasks/stepfunctions/start-execution.js +123 -0
- package/lib/aws/compute/types.d.ts +214 -0
- package/lib/aws/compute/types.js +103 -0
- package/lib/aws/compute/util.d.ts +12 -0
- package/lib/aws/compute/util.js +29 -0
- package/lib/aws/edge/certificate.d.ts +144 -0
- package/lib/aws/edge/certificate.js +191 -0
- package/lib/aws/edge/distribution.d.ts +505 -0
- package/lib/aws/edge/distribution.js +444 -0
- package/lib/aws/edge/dns-alias-record-targets.d.ts +29 -0
- package/lib/aws/edge/dns-alias-record-targets.js +46 -0
- package/lib/aws/edge/dns-record.d.ts +536 -0
- package/lib/aws/edge/dns-record.js +532 -0
- package/lib/aws/edge/dns-zone.d.ts +169 -0
- package/lib/aws/edge/dns-zone.js +149 -0
- package/lib/aws/edge/function.d.ts +185 -0
- package/lib/aws/edge/function.js +141 -0
- package/lib/aws/edge/index.d.ts +8 -0
- package/lib/aws/edge/index.js +25 -0
- package/lib/aws/edge/key-value-store.d.ts +162 -0
- package/lib/aws/edge/key-value-store.js +163 -0
- package/lib/aws/edge/origin.d.ts +160 -0
- package/lib/aws/edge/origin.js +245 -0
- package/lib/aws/encryption/alias.d.ts +137 -0
- package/lib/aws/encryption/alias.js +216 -0
- package/lib/aws/encryption/index.d.ts +4 -0
- package/lib/aws/encryption/index.js +21 -0
- package/lib/aws/encryption/key-lookup.d.ts +11 -0
- package/lib/aws/encryption/key-lookup.js +4 -0
- package/lib/aws/encryption/key.d.ts +461 -0
- package/lib/aws/encryption/key.js +586 -0
- package/lib/aws/encryption/private/perms.d.ts +5 -0
- package/lib/aws/encryption/private/perms.js +30 -0
- package/lib/aws/encryption/via-service-principal.d.ts +11 -0
- package/lib/aws/encryption/via-service-principal.js +39 -0
- package/lib/aws/iam/grant.d.ts +221 -0
- package/lib/aws/iam/grant.js +239 -0
- package/lib/aws/iam/identity-base.d.ts +20 -0
- package/lib/aws/iam/identity-base.js +3 -0
- package/lib/aws/iam/index.d.ts +16 -0
- package/lib/aws/iam/index.js +34 -0
- package/lib/aws/iam/managed-policy.d.ts +227 -0
- package/lib/aws/iam/managed-policy.js +237 -0
- package/lib/aws/iam/oidc-provider.d.ts +120 -0
- package/lib/aws/iam/oidc-provider.js +82 -0
- package/lib/aws/iam/policy-document-config.generated.d.ts +78 -0
- package/lib/aws/iam/policy-document-config.generated.js +3 -0
- package/lib/aws/iam/policy-document.d.ts +150 -0
- package/lib/aws/iam/policy-document.js +172 -0
- package/lib/aws/iam/policy-statement-props.generated.d.ts +55 -0
- package/lib/aws/iam/policy-statement-props.generated.js +3 -0
- package/lib/aws/iam/policy-statement.d.ts +451 -0
- package/lib/aws/iam/policy-statement.js +947 -0
- package/lib/aws/iam/policy.d.ts +122 -0
- package/lib/aws/iam/policy.js +192 -0
- package/lib/aws/iam/principals.d.ts +668 -0
- package/lib/aws/iam/principals.js +1032 -0
- package/lib/aws/iam/private/adapter.d.ts +21 -0
- package/lib/aws/iam/private/adapter.js +51 -0
- package/lib/aws/iam/private/assume-role-policy.d.ts +8 -0
- package/lib/aws/iam/private/assume-role-policy.js +27 -0
- package/lib/aws/iam/private/comparable-principal.d.ts +6 -0
- package/lib/aws/iam/private/comparable-principal.js +20 -0
- package/lib/aws/iam/private/immutable-role.d.ts +43 -0
- package/lib/aws/iam/private/immutable-role.js +76 -0
- package/lib/aws/iam/private/imported-role.d.ts +49 -0
- package/lib/aws/iam/private/imported-role.js +103 -0
- package/lib/aws/iam/private/merge-statements.d.ts +44 -0
- package/lib/aws/iam/private/merge-statements.js +214 -0
- package/lib/aws/iam/private/postprocess-policy-document.d.ts +15 -0
- package/lib/aws/iam/private/postprocess-policy-document.js +102 -0
- package/lib/aws/iam/private/util.d.ts +37 -0
- package/lib/aws/iam/private/util.js +87 -0
- package/lib/aws/iam/role.d.ts +425 -0
- package/lib/aws/iam/role.js +407 -0
- package/lib/aws/iam/saml-provider.d.ts +79 -0
- package/lib/aws/iam/saml-provider.js +79 -0
- package/lib/aws/iam/unknown-principal.d.ts +32 -0
- package/lib/aws/iam/unknown-principal.js +45 -0
- package/lib/aws/iam/utils.d.ts +12 -0
- package/lib/aws/iam/utils.js +41 -0
- package/lib/aws/index.d.ts +13 -0
- package/lib/aws/index.js +34 -0
- package/lib/aws/log-retention.d.ts +97 -0
- package/lib/aws/log-retention.js +103 -0
- package/lib/aws/network/index.d.ts +4 -0
- package/lib/aws/network/index.js +21 -0
- package/lib/aws/network/network.d.ts +77 -0
- package/lib/aws/network/network.js +3 -0
- package/lib/aws/network/simple-ipv4-vpc.d.ts +84 -0
- package/lib/aws/network/simple-ipv4-vpc.js +236 -0
- package/lib/aws/network/subnet-group.d.ts +42 -0
- package/lib/aws/network/subnet-group.js +72 -0
- package/lib/aws/network/subnet.d.ts +95 -0
- package/lib/aws/network/subnet.js +123 -0
- package/lib/aws/notify/archive.d.ts +77 -0
- package/lib/aws/notify/archive.js +62 -0
- package/lib/aws/notify/connection.d.ts +276 -0
- package/lib/aws/notify/connection.js +261 -0
- package/lib/aws/notify/event-bus.d.ts +298 -0
- package/lib/aws/notify/event-bus.js +326 -0
- package/lib/aws/notify/event-pattern.d.ts +220 -0
- package/lib/aws/notify/event-pattern.js +197 -0
- package/lib/aws/notify/index.d.ts +15 -0
- package/lib/aws/notify/index.js +35 -0
- package/lib/aws/notify/input.d.ts +126 -0
- package/lib/aws/notify/input.js +282 -0
- package/lib/aws/notify/kinesis-canned-metrics.generated.d.ts +68 -0
- package/lib/aws/notify/kinesis-canned-metrics.generated.js +103 -0
- package/lib/aws/notify/kinesis-fixed-canned-metrics.d.ts +195 -0
- package/lib/aws/notify/kinesis-fixed-canned-metrics.js +155 -0
- package/lib/aws/notify/kinesis-stream.d.ts +705 -0
- package/lib/aws/notify/kinesis-stream.js +541 -0
- package/lib/aws/notify/on-event-options.d.ts +54 -0
- package/lib/aws/notify/on-event-options.js +3 -0
- package/lib/aws/notify/queue-config.generated.d.ts +85 -0
- package/lib/aws/notify/queue-config.generated.js +3 -0
- package/lib/aws/notify/queue-policy.d.ts +35 -0
- package/lib/aws/notify/queue-policy.js +39 -0
- package/lib/aws/notify/queue.d.ts +355 -0
- package/lib/aws/notify/queue.js +305 -0
- package/lib/aws/notify/resource-policy.d.ts +41 -0
- package/lib/aws/notify/resource-policy.js +43 -0
- package/lib/aws/notify/rule.d.ts +153 -0
- package/lib/aws/notify/rule.js +227 -0
- package/lib/aws/notify/schedule.d.ts +83 -0
- package/lib/aws/notify/schedule.js +116 -0
- package/lib/aws/notify/target.d.ts +102 -0
- package/lib/aws/notify/target.js +3 -0
- package/lib/aws/notify/targets/event-bus.d.ts +39 -0
- package/lib/aws/notify/targets/event-bus.js +40 -0
- package/lib/aws/notify/targets/function.d.ts +31 -0
- package/lib/aws/notify/targets/function.js +36 -0
- package/lib/aws/notify/targets/index.d.ts +6 -0
- package/lib/aws/notify/targets/index.js +37 -0
- package/lib/aws/notify/targets/log-group.d.ts +89 -0
- package/lib/aws/notify/targets/log-group.js +110 -0
- package/lib/aws/notify/targets/sqs.d.ts +45 -0
- package/lib/aws/notify/targets/sqs.js +73 -0
- package/lib/aws/notify/targets/state-machine.d.ts +36 -0
- package/lib/aws/notify/targets/state-machine.js +39 -0
- package/lib/aws/notify/targets/util.d.ts +71 -0
- package/lib/aws/notify/targets/util.js +130 -0
- package/lib/aws/notify/util.d.ts +13 -0
- package/lib/aws/notify/util.js +69 -0
- package/lib/aws/provider-config.generated.d.ts +220 -0
- package/lib/aws/provider-config.generated.js +3 -0
- package/lib/aws/storage/bucket-destination.d.ts +41 -0
- package/lib/aws/storage/bucket-destination.js +13 -0
- package/lib/aws/storage/bucket-notifications.d.ts +58 -0
- package/lib/aws/storage/bucket-notifications.js +169 -0
- package/lib/aws/storage/bucket-perms.d.ts +9 -0
- package/lib/aws/storage/bucket-perms.js +33 -0
- package/lib/aws/storage/bucket-policy.d.ts +51 -0
- package/lib/aws/storage/bucket-policy.js +53 -0
- package/lib/aws/storage/bucket-source.d.ts +41 -0
- package/lib/aws/storage/bucket-source.js +79 -0
- package/lib/aws/storage/bucket.d.ts +941 -0
- package/lib/aws/storage/bucket.js +869 -0
- package/lib/aws/storage/cors-config.generated.d.ts +57 -0
- package/lib/aws/storage/cors-config.generated.js +3 -0
- package/lib/aws/storage/cors-rule-config.generated.d.ts +38 -0
- package/lib/aws/storage/cors-rule-config.generated.js +3 -0
- package/lib/aws/storage/index.d.ts +12 -0
- package/lib/aws/storage/index.js +31 -0
- package/lib/aws/storage/lifecycle-config.generated.d.ts +55 -0
- package/lib/aws/storage/lifecycle-config.generated.js +3 -0
- package/lib/aws/storage/notification-targets/function.d.ts +11 -0
- package/lib/aws/storage/notification-targets/function.js +48 -0
- package/lib/aws/storage/notification-targets/index.d.ts +2 -0
- package/lib/aws/storage/notification-targets/index.js +21 -0
- package/lib/aws/storage/notification-targets/queue.d.ts +15 -0
- package/lib/aws/storage/notification-targets/queue.js +58 -0
- package/lib/aws/storage/origin-access-identity.d.ts +91 -0
- package/lib/aws/storage/origin-access-identity.js +76 -0
- package/lib/aws/storage/util.d.ts +40 -0
- package/lib/aws/storage/util.js +85 -0
- package/lib/aws/storage/website-config.generated.d.ts +73 -0
- package/lib/aws/storage/website-config.generated.js +3 -0
- package/lib/aws/util.d.ts +4 -0
- package/lib/aws/util.js +25 -0
- package/lib/construct-base.d.ts +69 -0
- package/lib/construct-base.js +89 -0
- package/lib/duration.d.ts +160 -0
- package/lib/duration.js +327 -0
- package/lib/index.d.ts +5 -0
- package/lib/index.js +24 -0
- package/lib/private/index.d.ts +2 -0
- package/lib/private/index.js +19 -0
- package/lib/private/terraform-dependables-aspect.d.ts +20 -0
- package/lib/private/terraform-dependables-aspect.js +95 -0
- package/lib/private/unique-resource-name.d.ts +9 -0
- package/lib/private/unique-resource-name.js +145 -0
- package/lib/size.d.ts +146 -0
- package/lib/size.js +220 -0
- package/lib/stack-base.d.ts +188 -0
- package/lib/stack-base.js +183 -0
- package/lib/token.d.ts +32 -0
- package/lib/token.js +54 -0
- package/node_modules/camel-case/LICENSE +21 -0
- package/node_modules/camel-case/README.md +47 -0
- package/node_modules/camel-case/dist/index.d.ts +5 -0
- package/node_modules/camel-case/dist/index.js +23 -0
- package/node_modules/camel-case/dist/index.js.map +1 -0
- package/node_modules/camel-case/dist/index.spec.d.ts +1 -0
- package/node_modules/camel-case/dist/index.spec.js +26 -0
- package/node_modules/camel-case/dist/index.spec.js.map +1 -0
- package/node_modules/camel-case/dist.es2015/index.d.ts +5 -0
- package/node_modules/camel-case/dist.es2015/index.js +17 -0
- package/node_modules/camel-case/dist.es2015/index.js.map +1 -0
- package/node_modules/camel-case/dist.es2015/index.spec.d.ts +1 -0
- package/node_modules/camel-case/dist.es2015/index.spec.js +24 -0
- package/node_modules/camel-case/dist.es2015/index.spec.js.map +1 -0
- package/node_modules/camel-case/package.json +89 -0
- package/node_modules/capital-case/LICENSE +21 -0
- package/node_modules/capital-case/README.md +37 -0
- package/node_modules/capital-case/dist/index.d.ts +4 -0
- package/node_modules/capital-case/dist/index.js +16 -0
- package/node_modules/capital-case/dist/index.js.map +1 -0
- package/node_modules/capital-case/dist/index.spec.d.ts +1 -0
- package/node_modules/capital-case/dist/index.spec.js +24 -0
- package/node_modules/capital-case/dist/index.spec.js.map +1 -0
- package/node_modules/capital-case/dist.es2015/index.d.ts +4 -0
- package/node_modules/capital-case/dist.es2015/index.js +11 -0
- package/node_modules/capital-case/dist.es2015/index.js.map +1 -0
- package/node_modules/capital-case/dist.es2015/index.spec.d.ts +1 -0
- package/node_modules/capital-case/dist.es2015/index.spec.js +22 -0
- package/node_modules/capital-case/dist.es2015/index.spec.js.map +1 -0
- package/node_modules/capital-case/package.json +90 -0
- package/node_modules/change-case/LICENSE +21 -0
- package/node_modules/change-case/README.md +44 -0
- package/node_modules/change-case/dist/index.d.ts +11 -0
- package/node_modules/change-case/dist/index.js +15 -0
- package/node_modules/change-case/dist/index.js.map +1 -0
- package/node_modules/change-case/dist/index.spec.d.ts +1 -0
- package/node_modules/change-case/dist/index.spec.js +9 -0
- package/node_modules/change-case/dist/index.spec.js.map +1 -0
- package/node_modules/change-case/dist.es2015/index.d.ts +11 -0
- package/node_modules/change-case/dist.es2015/index.js +12 -0
- package/node_modules/change-case/dist.es2015/index.js.map +1 -0
- package/node_modules/change-case/dist.es2015/index.spec.d.ts +1 -0
- package/node_modules/change-case/dist.es2015/index.spec.js +7 -0
- package/node_modules/change-case/dist.es2015/index.spec.js.map +1 -0
- package/node_modules/change-case/package.json +101 -0
- package/node_modules/constant-case/LICENSE +21 -0
- package/node_modules/constant-case/README.md +37 -0
- package/node_modules/constant-case/dist/index.d.ts +3 -0
- package/node_modules/constant-case/dist/index.js +12 -0
- package/node_modules/constant-case/dist/index.js.map +1 -0
- package/node_modules/constant-case/dist/index.spec.d.ts +1 -0
- package/node_modules/constant-case/dist/index.spec.js +26 -0
- package/node_modules/constant-case/dist/index.spec.js.map +1 -0
- package/node_modules/constant-case/dist.es2015/index.d.ts +3 -0
- package/node_modules/constant-case/dist.es2015/index.js +8 -0
- package/node_modules/constant-case/dist.es2015/index.js.map +1 -0
- package/node_modules/constant-case/dist.es2015/index.spec.d.ts +1 -0
- package/node_modules/constant-case/dist.es2015/index.spec.js +24 -0
- package/node_modules/constant-case/dist.es2015/index.spec.js.map +1 -0
- package/node_modules/constant-case/package.json +90 -0
- package/node_modules/dot-case/LICENSE +21 -0
- package/node_modules/dot-case/README.md +37 -0
- package/node_modules/dot-case/dist/index.d.ts +3 -0
- package/node_modules/dot-case/dist/index.js +11 -0
- package/node_modules/dot-case/dist/index.js.map +1 -0
- package/node_modules/dot-case/dist/index.spec.d.ts +1 -0
- package/node_modules/dot-case/dist/index.spec.js +26 -0
- package/node_modules/dot-case/dist/index.spec.js.map +1 -0
- package/node_modules/dot-case/dist.es2015/index.d.ts +3 -0
- package/node_modules/dot-case/dist.es2015/index.js +7 -0
- package/node_modules/dot-case/dist.es2015/index.js.map +1 -0
- package/node_modules/dot-case/dist.es2015/index.spec.d.ts +1 -0
- package/node_modules/dot-case/dist.es2015/index.spec.js +24 -0
- package/node_modules/dot-case/dist.es2015/index.spec.js.map +1 -0
- package/node_modules/dot-case/package.json +89 -0
- package/node_modules/esbuild-wasm/LICENSE.md +21 -0
- package/node_modules/esbuild-wasm/README.md +3 -0
- package/node_modules/esbuild-wasm/bin/esbuild +91 -0
- package/node_modules/esbuild-wasm/esbuild.wasm +0 -0
- package/node_modules/esbuild-wasm/esm/browser.d.ts +705 -0
- package/node_modules/esbuild-wasm/esm/browser.js +2370 -0
- package/node_modules/esbuild-wasm/esm/browser.min.js +20 -0
- package/node_modules/esbuild-wasm/lib/browser.d.ts +705 -0
- package/node_modules/esbuild-wasm/lib/browser.js +2415 -0
- package/node_modules/esbuild-wasm/lib/browser.min.js +22 -0
- package/node_modules/esbuild-wasm/lib/main.d.ts +705 -0
- package/node_modules/esbuild-wasm/lib/main.js +2051 -0
- package/node_modules/esbuild-wasm/package.json +19 -0
- package/node_modules/esbuild-wasm/wasm_exec.js +561 -0
- package/node_modules/esbuild-wasm/wasm_exec_node.js +39 -0
- package/node_modules/header-case/LICENSE +21 -0
- package/node_modules/header-case/README.md +37 -0
- package/node_modules/header-case/dist/index.d.ts +3 -0
- package/node_modules/header-case/dist/index.js +11 -0
- package/node_modules/header-case/dist/index.js.map +1 -0
- package/node_modules/header-case/dist/index.spec.d.ts +1 -0
- package/node_modules/header-case/dist/index.spec.js +24 -0
- package/node_modules/header-case/dist/index.spec.js.map +1 -0
- package/node_modules/header-case/dist.es2015/index.d.ts +3 -0
- package/node_modules/header-case/dist.es2015/index.js +7 -0
- package/node_modules/header-case/dist.es2015/index.js.map +1 -0
- package/node_modules/header-case/dist.es2015/index.spec.d.ts +1 -0
- package/node_modules/header-case/dist.es2015/index.spec.js +22 -0
- package/node_modules/header-case/dist.es2015/index.spec.js.map +1 -0
- package/node_modules/header-case/package.json +89 -0
- package/node_modules/lower-case/LICENSE +21 -0
- package/node_modules/lower-case/README.md +35 -0
- package/node_modules/lower-case/dist/index.d.ts +8 -0
- package/node_modules/lower-case/dist/index.js +53 -0
- package/node_modules/lower-case/dist/index.js.map +1 -0
- package/node_modules/lower-case/dist/index.spec.d.ts +1 -0
- package/node_modules/lower-case/dist/index.spec.js +36 -0
- package/node_modules/lower-case/dist/index.spec.js.map +1 -0
- package/node_modules/lower-case/dist.es2015/index.d.ts +8 -0
- package/node_modules/lower-case/dist.es2015/index.js +48 -0
- package/node_modules/lower-case/dist.es2015/index.js.map +1 -0
- package/node_modules/lower-case/dist.es2015/index.spec.d.ts +1 -0
- package/node_modules/lower-case/dist.es2015/index.spec.js +34 -0
- package/node_modules/lower-case/dist.es2015/index.spec.js.map +1 -0
- package/node_modules/lower-case/package.json +87 -0
- package/node_modules/mime-db/HISTORY.md +507 -0
- package/node_modules/mime-db/LICENSE +23 -0
- package/node_modules/mime-db/README.md +100 -0
- package/node_modules/mime-db/db.json +8519 -0
- package/node_modules/mime-db/index.js +12 -0
- package/node_modules/mime-db/package.json +60 -0
- package/node_modules/mime-types/HISTORY.md +397 -0
- package/node_modules/mime-types/LICENSE +23 -0
- package/node_modules/mime-types/README.md +113 -0
- package/node_modules/mime-types/index.js +188 -0
- package/node_modules/mime-types/package.json +44 -0
- package/node_modules/no-case/LICENSE +21 -0
- package/node_modules/no-case/README.md +37 -0
- package/node_modules/no-case/dist/index.d.ts +10 -0
- package/node_modules/no-case/dist/index.js +35 -0
- package/node_modules/no-case/dist/index.js.map +1 -0
- package/node_modules/no-case/dist/index.spec.d.ts +1 -0
- package/node_modules/no-case/dist/index.spec.js +59 -0
- package/node_modules/no-case/dist/index.spec.js.map +1 -0
- package/node_modules/no-case/dist.es2015/index.d.ts +10 -0
- package/node_modules/no-case/dist.es2015/index.js +31 -0
- package/node_modules/no-case/dist.es2015/index.js.map +1 -0
- package/node_modules/no-case/dist.es2015/index.spec.d.ts +1 -0
- package/node_modules/no-case/dist.es2015/index.spec.js +57 -0
- package/node_modules/no-case/dist.es2015/index.spec.js.map +1 -0
- package/node_modules/no-case/package.json +85 -0
- package/node_modules/param-case/LICENSE +21 -0
- package/node_modules/param-case/README.md +37 -0
- package/node_modules/param-case/dist/index.d.ts +3 -0
- package/node_modules/param-case/dist/index.js +11 -0
- package/node_modules/param-case/dist/index.js.map +1 -0
- package/node_modules/param-case/dist/index.spec.d.ts +1 -0
- package/node_modules/param-case/dist/index.spec.js +24 -0
- package/node_modules/param-case/dist/index.spec.js.map +1 -0
- package/node_modules/param-case/dist.es2015/index.d.ts +3 -0
- package/node_modules/param-case/dist.es2015/index.js +7 -0
- package/node_modules/param-case/dist.es2015/index.js.map +1 -0
- package/node_modules/param-case/dist.es2015/index.spec.d.ts +1 -0
- package/node_modules/param-case/dist.es2015/index.spec.js +22 -0
- package/node_modules/param-case/dist.es2015/index.spec.js.map +1 -0
- package/node_modules/param-case/package.json +91 -0
- package/node_modules/pascal-case/LICENSE +21 -0
- package/node_modules/pascal-case/README.md +47 -0
- package/node_modules/pascal-case/dist/index.d.ts +5 -0
- package/node_modules/pascal-case/dist/index.js +24 -0
- package/node_modules/pascal-case/dist/index.js.map +1 -0
- package/node_modules/pascal-case/dist/index.spec.d.ts +1 -0
- package/node_modules/pascal-case/dist/index.spec.js +25 -0
- package/node_modules/pascal-case/dist/index.spec.js.map +1 -0
- package/node_modules/pascal-case/dist.es2015/index.d.ts +5 -0
- package/node_modules/pascal-case/dist.es2015/index.js +18 -0
- package/node_modules/pascal-case/dist.es2015/index.js.map +1 -0
- package/node_modules/pascal-case/dist.es2015/index.spec.d.ts +1 -0
- package/node_modules/pascal-case/dist.es2015/index.spec.js +23 -0
- package/node_modules/pascal-case/dist.es2015/index.spec.js.map +1 -0
- package/node_modules/pascal-case/package.json +90 -0
- package/node_modules/path-case/LICENSE +21 -0
- package/node_modules/path-case/README.md +37 -0
- package/node_modules/path-case/dist/index.d.ts +3 -0
- package/node_modules/path-case/dist/index.js +11 -0
- package/node_modules/path-case/dist/index.js.map +1 -0
- package/node_modules/path-case/dist/index.spec.d.ts +1 -0
- package/node_modules/path-case/dist/index.spec.js +24 -0
- package/node_modules/path-case/dist/index.spec.js.map +1 -0
- package/node_modules/path-case/dist.es2015/index.d.ts +3 -0
- package/node_modules/path-case/dist.es2015/index.js +7 -0
- package/node_modules/path-case/dist.es2015/index.js.map +1 -0
- package/node_modules/path-case/dist.es2015/index.spec.d.ts +1 -0
- package/node_modules/path-case/dist.es2015/index.spec.js +22 -0
- package/node_modules/path-case/dist.es2015/index.spec.js.map +1 -0
- package/node_modules/path-case/package.json +88 -0
- package/node_modules/sentence-case/LICENSE +21 -0
- package/node_modules/sentence-case/README.md +37 -0
- package/node_modules/sentence-case/dist/index.d.ts +4 -0
- package/node_modules/sentence-case/dist/index.js +19 -0
- package/node_modules/sentence-case/dist/index.js.map +1 -0
- package/node_modules/sentence-case/dist/index.spec.d.ts +1 -0
- package/node_modules/sentence-case/dist/index.spec.js +24 -0
- package/node_modules/sentence-case/dist/index.spec.js.map +1 -0
- package/node_modules/sentence-case/dist.es2015/index.d.ts +4 -0
- package/node_modules/sentence-case/dist.es2015/index.js +14 -0
- package/node_modules/sentence-case/dist.es2015/index.js.map +1 -0
- package/node_modules/sentence-case/dist.es2015/index.spec.d.ts +1 -0
- package/node_modules/sentence-case/dist.es2015/index.spec.js +22 -0
- package/node_modules/sentence-case/dist.es2015/index.spec.js.map +1 -0
- package/node_modules/sentence-case/package.json +89 -0
- package/node_modules/snake-case/LICENSE +21 -0
- package/node_modules/snake-case/README.md +37 -0
- package/node_modules/snake-case/dist/index.d.ts +3 -0
- package/node_modules/snake-case/dist/index.js +11 -0
- package/node_modules/snake-case/dist/index.js.map +1 -0
- package/node_modules/snake-case/dist/index.spec.d.ts +1 -0
- package/node_modules/snake-case/dist/index.spec.js +25 -0
- package/node_modules/snake-case/dist/index.spec.js.map +1 -0
- package/node_modules/snake-case/dist.es2015/index.d.ts +3 -0
- package/node_modules/snake-case/dist.es2015/index.js +7 -0
- package/node_modules/snake-case/dist.es2015/index.js.map +1 -0
- package/node_modules/snake-case/dist.es2015/index.spec.d.ts +1 -0
- package/node_modules/snake-case/dist.es2015/index.spec.js +23 -0
- package/node_modules/snake-case/dist.es2015/index.spec.js.map +1 -0
- package/node_modules/snake-case/package.json +90 -0
- package/node_modules/tslib/CopyrightNotice.txt +15 -0
- package/node_modules/tslib/LICENSE.txt +12 -0
- package/node_modules/tslib/README.md +164 -0
- package/node_modules/tslib/SECURITY.md +41 -0
- package/node_modules/tslib/modules/index.d.ts +37 -0
- package/node_modules/tslib/modules/index.js +68 -0
- package/node_modules/tslib/modules/package.json +3 -0
- package/node_modules/tslib/package.json +47 -0
- package/node_modules/tslib/tslib.d.ts +453 -0
- package/node_modules/tslib/tslib.es6.html +1 -0
- package/node_modules/tslib/tslib.es6.js +374 -0
- package/node_modules/tslib/tslib.es6.mjs +373 -0
- package/node_modules/tslib/tslib.html +1 -0
- package/node_modules/tslib/tslib.js +424 -0
- package/node_modules/upper-case/README.md +34 -0
- package/node_modules/upper-case/dist/index.d.ts +8 -0
- package/node_modules/upper-case/dist/index.js +49 -0
- package/node_modules/upper-case/dist/index.js.map +1 -0
- package/node_modules/upper-case/dist/index.spec.d.ts +1 -0
- package/node_modules/upper-case/dist/index.spec.js +34 -0
- package/node_modules/upper-case/dist/index.spec.js.map +1 -0
- package/node_modules/upper-case/dist.es2015/index.d.ts +8 -0
- package/node_modules/upper-case/dist.es2015/index.js +44 -0
- package/node_modules/upper-case/dist.es2015/index.js.map +1 -0
- package/node_modules/upper-case/dist.es2015/index.spec.d.ts +1 -0
- package/node_modules/upper-case/dist.es2015/index.spec.js +32 -0
- package/node_modules/upper-case/dist.es2015/index.spec.js.map +1 -0
- package/node_modules/upper-case/package.json +86 -0
- package/node_modules/upper-case-first/LICENSE +21 -0
- package/node_modules/upper-case-first/README.md +32 -0
- package/node_modules/upper-case-first/dist/index.d.ts +4 -0
- package/node_modules/upper-case-first/dist/index.js +11 -0
- package/node_modules/upper-case-first/dist/index.js.map +1 -0
- package/node_modules/upper-case-first/dist/index.spec.d.ts +1 -0
- package/node_modules/upper-case-first/dist/index.spec.js +20 -0
- package/node_modules/upper-case-first/dist/index.spec.js.map +1 -0
- package/node_modules/upper-case-first/dist.es2015/index.d.ts +4 -0
- package/node_modules/upper-case-first/dist.es2015/index.js +7 -0
- package/node_modules/upper-case-first/dist.es2015/index.js.map +1 -0
- package/node_modules/upper-case-first/dist.es2015/index.spec.d.ts +1 -0
- package/node_modules/upper-case-first/dist.es2015/index.spec.js +18 -0
- package/node_modules/upper-case-first/dist.es2015/index.spec.js.map +1 -0
- package/node_modules/upper-case-first/package.json +87 -0
- package/package.json +152 -0
- package/setup.js +2 -0
|
@@ -0,0 +1,869 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var _a;
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.EventType = exports.StorageClass = exports.Bucket = void 0;
|
|
5
|
+
const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
|
|
6
|
+
const provider_aws_1 = require("@cdktf/provider-aws");
|
|
7
|
+
const provider_time_1 = require("@cdktf/provider-time");
|
|
8
|
+
const _1 = require(".");
|
|
9
|
+
const __1 = require("..");
|
|
10
|
+
const iam = require("../iam");
|
|
11
|
+
const perms = require("./bucket-perms");
|
|
12
|
+
/**
|
|
13
|
+
* The `Bucket` beacon provides an [AWS S3 Bucket](https://aws.amazon.com/s3/).
|
|
14
|
+
*
|
|
15
|
+
* ```ts
|
|
16
|
+
* new storage.Bucket(stack, "MyWebsite", {
|
|
17
|
+
* path: path.join(__dirname, "dist"),
|
|
18
|
+
* });
|
|
19
|
+
* ```
|
|
20
|
+
*
|
|
21
|
+
* #### Public read access
|
|
22
|
+
*
|
|
23
|
+
* Enables `public` read access for all the files in the bucket. Dangerous and
|
|
24
|
+
* recommended to use edge.Distribution instead.
|
|
25
|
+
*
|
|
26
|
+
* Useful for hosting public files directly from S3.
|
|
27
|
+
*
|
|
28
|
+
* ```ts
|
|
29
|
+
* new storage.Bucket("MyBucket", {
|
|
30
|
+
* public: true
|
|
31
|
+
* });
|
|
32
|
+
* ```
|
|
33
|
+
*
|
|
34
|
+
* @resource aws_s3_bucket
|
|
35
|
+
* @terraconstruct storage.IBucket
|
|
36
|
+
*/
|
|
37
|
+
class Bucket extends __1.AwsConstructBase {
|
|
38
|
+
get versioned() {
|
|
39
|
+
return this._versioned;
|
|
40
|
+
}
|
|
41
|
+
get bucketOutputs() {
|
|
42
|
+
return this._outputs;
|
|
43
|
+
}
|
|
44
|
+
get outputs() {
|
|
45
|
+
return this.bucketOutputs;
|
|
46
|
+
}
|
|
47
|
+
get bucketName() {
|
|
48
|
+
return this.resource.bucket;
|
|
49
|
+
}
|
|
50
|
+
get bucketArn() {
|
|
51
|
+
return this.resource.arn;
|
|
52
|
+
}
|
|
53
|
+
get hostedZoneId() {
|
|
54
|
+
return this.resource.hostedZoneId;
|
|
55
|
+
}
|
|
56
|
+
get websiteDomainName() {
|
|
57
|
+
return this.websiteConfig?.websiteDomain;
|
|
58
|
+
}
|
|
59
|
+
constructor(scope, name, props = {}) {
|
|
60
|
+
super(scope, name, props);
|
|
61
|
+
/** @internal */
|
|
62
|
+
this.sources = [];
|
|
63
|
+
this.node.addValidation({
|
|
64
|
+
validate: () => this.policy?.document.validateForResourcePolicy() ?? [],
|
|
65
|
+
});
|
|
66
|
+
const { websiteConfig, corsConfig, cloudfrontAccess } = props;
|
|
67
|
+
this._isWebsite = false;
|
|
68
|
+
if (props.bucketName && props.namePrefix) {
|
|
69
|
+
throw new Error("Cannot specify both 'bucketName' and 'namePrefix'. Use only one.");
|
|
70
|
+
}
|
|
71
|
+
let bucketPrefix;
|
|
72
|
+
if (!props.bucketName) {
|
|
73
|
+
// Bucket names must be lowercase and between 3 (min) and 63 (max) characters long.
|
|
74
|
+
bucketPrefix = this.stack.uniqueResourceNamePrefix(this, {
|
|
75
|
+
prefix: (props.namePrefix ?? this.gridUUID) + "-",
|
|
76
|
+
lowerCase: true,
|
|
77
|
+
allowedSpecialCharacters: ".-",
|
|
78
|
+
maxLength: 63,
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
this.resource = new provider_aws_1.s3Bucket.S3Bucket(this, "Resource", {
|
|
82
|
+
bucket: props.bucketName,
|
|
83
|
+
forceDestroy: props.forceDestroy,
|
|
84
|
+
bucketPrefix,
|
|
85
|
+
});
|
|
86
|
+
this._versioned = props.versioned ?? false;
|
|
87
|
+
if (this._versioned) {
|
|
88
|
+
new provider_aws_1.s3BucketVersioning.S3BucketVersioningA(this, "Versioning", {
|
|
89
|
+
bucket: this.resource.bucket,
|
|
90
|
+
versioningConfiguration: {
|
|
91
|
+
status: this._versioned ? "Enabled" : "Suspended",
|
|
92
|
+
},
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
this.eventBridgeEnabled = props.eventBridgeEnabled;
|
|
96
|
+
if (props.sources) {
|
|
97
|
+
if (typeof props.sources === "string") {
|
|
98
|
+
this.addSource({ path: props.sources });
|
|
99
|
+
}
|
|
100
|
+
else if (Array.isArray(props.sources)) {
|
|
101
|
+
for (const sourceProps of props.sources) {
|
|
102
|
+
if (typeof sourceProps === "string") {
|
|
103
|
+
this.addSource({ path: sourceProps });
|
|
104
|
+
}
|
|
105
|
+
else {
|
|
106
|
+
this.addSource(sourceProps);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
if (props.lifecycleRules) {
|
|
112
|
+
new provider_aws_1.s3BucketLifecycleConfiguration.S3BucketLifecycleConfiguration(this, "LifeCycleConfig", {
|
|
113
|
+
bucket: this.resource.bucket,
|
|
114
|
+
rule: props.lifecycleRules.map((rule) => ({
|
|
115
|
+
...rule,
|
|
116
|
+
status: rule.enabled ? "Enabled" : "Disabled",
|
|
117
|
+
})),
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
// Enforce AWS Foundational Security Best Practice
|
|
121
|
+
if (props.enforceSSL) {
|
|
122
|
+
this.enforceSSLStatement();
|
|
123
|
+
this.minimumTLSVersionStatement(props.minimumTLSVersion);
|
|
124
|
+
}
|
|
125
|
+
else if (props.minimumTLSVersion) {
|
|
126
|
+
throw new Error("'enforceSSL' must be enabled for 'minimumTLSVersion' to be applied");
|
|
127
|
+
}
|
|
128
|
+
if (websiteConfig && websiteConfig.enabled) {
|
|
129
|
+
this._isWebsite = true;
|
|
130
|
+
this.websiteConfig =
|
|
131
|
+
new provider_aws_1.s3BucketWebsiteConfiguration.S3BucketWebsiteConfiguration(this, "WebsiteConfig", {
|
|
132
|
+
bucket: this.resource.bucket,
|
|
133
|
+
...websiteConfig,
|
|
134
|
+
indexDocument: websiteConfig?.indexDocument
|
|
135
|
+
? {
|
|
136
|
+
suffix: websiteConfig.indexDocument,
|
|
137
|
+
}
|
|
138
|
+
: {
|
|
139
|
+
suffix: "index.html",
|
|
140
|
+
},
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
this.public = props.public ?? false;
|
|
144
|
+
if (this.public) {
|
|
145
|
+
// TODO: switch to Lazy config using "grantPublicAccess" mechanism instead?
|
|
146
|
+
// ref: https://github.com/aws/aws-cdk/blob/v2.160.0/packages/aws-cdk-lib/aws-s3/lib/bucket.ts#L850
|
|
147
|
+
const ownershipControls = new provider_aws_1.s3BucketOwnershipControls.S3BucketOwnershipControls(this, "OwnershipControls", {
|
|
148
|
+
bucket: this.resource.bucket,
|
|
149
|
+
rule: {
|
|
150
|
+
objectOwnership: "BucketOwnerPreferred",
|
|
151
|
+
},
|
|
152
|
+
});
|
|
153
|
+
const publicAccessBlock = new provider_aws_1.s3BucketPublicAccessBlock.S3BucketPublicAccessBlock(this, "PublicAccessBlock", {
|
|
154
|
+
bucket: this.resource.bucket,
|
|
155
|
+
blockPublicAcls: false,
|
|
156
|
+
blockPublicPolicy: false,
|
|
157
|
+
ignorePublicAcls: false,
|
|
158
|
+
restrictPublicBuckets: false,
|
|
159
|
+
});
|
|
160
|
+
new provider_aws_1.s3BucketAcl.S3BucketAcl(this, "PublicAcl", {
|
|
161
|
+
bucket: this.resource.bucket,
|
|
162
|
+
acl: "public-read",
|
|
163
|
+
dependsOn: [ownershipControls, publicAccessBlock],
|
|
164
|
+
});
|
|
165
|
+
this.addToResourcePolicy(new iam.PolicyStatement({
|
|
166
|
+
resources: [this.arnForObjects("*")],
|
|
167
|
+
actions: ["s3:GetObject"],
|
|
168
|
+
principals: [new iam.AnyPrincipal()],
|
|
169
|
+
}));
|
|
170
|
+
// // policy depends on public access block?
|
|
171
|
+
// // is this needed?
|
|
172
|
+
// if (policyDependable && policyDependable instanceof Construct) {
|
|
173
|
+
// policyDependable.node.addDependency(publicAccessBlock);
|
|
174
|
+
// }
|
|
175
|
+
}
|
|
176
|
+
if (corsConfig) {
|
|
177
|
+
this.corsConfig = new provider_aws_1.s3BucketCorsConfiguration.S3BucketCorsConfiguration(this, "CorsConfig", {
|
|
178
|
+
bucket: this.resource.bucket,
|
|
179
|
+
...corsConfig,
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
let originAccessIdentity;
|
|
183
|
+
if (cloudfrontAccess?.enabled) {
|
|
184
|
+
const oai = new _1.OriginAccessIdentity(this, "OriginAccessIdentity", {
|
|
185
|
+
comment: `OAI for ${this.resource.bucket}`,
|
|
186
|
+
});
|
|
187
|
+
originAccessIdentity = oai.cloudFrontOriginAccessIdentityPath;
|
|
188
|
+
const resources = (cloudfrontAccess.keyPatterns ?? ["*"]).map((keyPattern) => this.arnForObjects(keyPattern));
|
|
189
|
+
this.addToResourcePolicy(new iam.PolicyStatement({
|
|
190
|
+
resources,
|
|
191
|
+
actions: ["s3:GetObject"],
|
|
192
|
+
principals: [oai.grantPrincipal],
|
|
193
|
+
}));
|
|
194
|
+
}
|
|
195
|
+
if (this.eventBridgeEnabled) {
|
|
196
|
+
this.enableEventBridgeNotification();
|
|
197
|
+
}
|
|
198
|
+
//register outputs
|
|
199
|
+
this._outputs = {
|
|
200
|
+
name: this.resource.bucket,
|
|
201
|
+
arn: this.resource.arn,
|
|
202
|
+
domainName: this.resource.bucketDomainName,
|
|
203
|
+
regionalDomainName: this.resource.bucketRegionalDomainName,
|
|
204
|
+
websiteDomainName: this.websiteConfig?.websiteDomain,
|
|
205
|
+
websiteUrl: this.websiteConfig?.websiteEndpoint,
|
|
206
|
+
originAccessIdentity,
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Adds a statement to the resource policy for a principal (i.e.
|
|
211
|
+
* account/role/service) to perform actions on this bucket and/or its
|
|
212
|
+
* contents. Use `bucketArn` and `arnForObjects(keys)` to obtain ARNs for
|
|
213
|
+
* this bucket or objects.
|
|
214
|
+
*
|
|
215
|
+
* Note that the policy statement may or may not be added to the policy.
|
|
216
|
+
* For example, when an `IBucket` is created from an existing bucket,
|
|
217
|
+
* it's not possible to tell whether the bucket already has a policy
|
|
218
|
+
* attached, let alone to re-use that policy to add more statements to it.
|
|
219
|
+
* So it's safest to do nothing in these cases.
|
|
220
|
+
*
|
|
221
|
+
* @param permission the policy statement to be added to the bucket's
|
|
222
|
+
* policy.
|
|
223
|
+
* @returns metadata about the execution of this method. If the policy
|
|
224
|
+
* was not added, the value of `statementAdded` will be `false`. You
|
|
225
|
+
* should always check this value to make sure that the operation was
|
|
226
|
+
* actually carried out. Otherwise, synthesis and deploy will terminate
|
|
227
|
+
* silently, which may be confusing.
|
|
228
|
+
*/
|
|
229
|
+
addToResourcePolicy(permission) {
|
|
230
|
+
// TODO: re-add autoCreatePolicy option?
|
|
231
|
+
// ref: https://github.com/aws/aws-cdk/blob/v2.160.0/packages/aws-cdk-lib/aws-s3/lib/bucket.ts#L652
|
|
232
|
+
if (!this.policy) {
|
|
233
|
+
this.policy = new _1.BucketPolicy(this, "Policy", { bucket: this });
|
|
234
|
+
}
|
|
235
|
+
if (this.policy) {
|
|
236
|
+
this.policy.document.addStatements(permission);
|
|
237
|
+
return { statementAdded: true, policyDependable: this.policy };
|
|
238
|
+
}
|
|
239
|
+
return { statementAdded: false };
|
|
240
|
+
}
|
|
241
|
+
/**
|
|
242
|
+
* Grant read permissions for this bucket and it's contents to an IAM
|
|
243
|
+
* principal (Role/Group/User).
|
|
244
|
+
*
|
|
245
|
+
* If encryption is used, permission to use the key to decrypt the contents
|
|
246
|
+
* of the bucket will also be granted to the same principal.
|
|
247
|
+
*
|
|
248
|
+
* @param identity The principal
|
|
249
|
+
* @param objectsKeyPattern Restrict the permission to a certain key pattern (default '*'). Parameter type is `any` but `string` should be passed in.
|
|
250
|
+
*/
|
|
251
|
+
grantRead(identity, objectsKeyPattern = "*") {
|
|
252
|
+
return this.grant(identity, perms.BUCKET_READ_ACTIONS, perms.KEY_READ_ACTIONS, this.resource.arn, this.arnForObjects(objectsKeyPattern));
|
|
253
|
+
}
|
|
254
|
+
grantWrite(identity, objectsKeyPattern = "*", allowedActionPatterns = []) {
|
|
255
|
+
const grantedWriteActions = allowedActionPatterns.length > 0
|
|
256
|
+
? allowedActionPatterns
|
|
257
|
+
: this.writeActions;
|
|
258
|
+
return this.grant(identity, grantedWriteActions, perms.KEY_WRITE_ACTIONS, this.resource.arn, this.arnForObjects(objectsKeyPattern));
|
|
259
|
+
}
|
|
260
|
+
/**
|
|
261
|
+
* Grants s3:PutObject* and s3:Abort* permissions for this bucket to an IAM principal.
|
|
262
|
+
*
|
|
263
|
+
* If encryption is used, permission to use the key to encrypt the contents
|
|
264
|
+
* of written files will also be granted to the same principal.
|
|
265
|
+
* @param identity The principal
|
|
266
|
+
* @param objectsKeyPattern Restrict the permission to a certain key pattern (default '*'). Parameter type is `any` but `string` should be passed in.
|
|
267
|
+
*/
|
|
268
|
+
grantPut(identity, objectsKeyPattern = "*") {
|
|
269
|
+
return this.grant(identity, perms.BUCKET_PUT_ACTIONS, perms.KEY_WRITE_ACTIONS, this.arnForObjects(objectsKeyPattern));
|
|
270
|
+
}
|
|
271
|
+
grantPutAcl(identity, objectsKeyPattern = "*") {
|
|
272
|
+
return this.grant(identity, perms.BUCKET_PUT_ACL_ACTIONS, [], this.arnForObjects(objectsKeyPattern));
|
|
273
|
+
}
|
|
274
|
+
/**
|
|
275
|
+
* Grants s3:DeleteObject* permission to an IAM principal for objects
|
|
276
|
+
* in this bucket.
|
|
277
|
+
*
|
|
278
|
+
* @param identity The principal
|
|
279
|
+
* @param objectsKeyPattern Restrict the permission to a certain key pattern (default '*'). Parameter type is `any` but `string` should be passed in.
|
|
280
|
+
*/
|
|
281
|
+
grantDelete(identity, objectsKeyPattern = "*") {
|
|
282
|
+
return this.grant(identity, perms.BUCKET_DELETE_ACTIONS, [], this.arnForObjects(objectsKeyPattern));
|
|
283
|
+
}
|
|
284
|
+
grantReadWrite(identity, objectsKeyPattern = "*") {
|
|
285
|
+
const bucketActions = perms.BUCKET_READ_ACTIONS.concat(this.writeActions);
|
|
286
|
+
// we need unique permissions because some permissions are common between read and write key actions
|
|
287
|
+
const keyActions = [
|
|
288
|
+
...new Set([...perms.KEY_READ_ACTIONS, ...perms.KEY_WRITE_ACTIONS]),
|
|
289
|
+
];
|
|
290
|
+
return this.grant(identity, bucketActions, keyActions, this.resource.arn, this.arnForObjects(objectsKeyPattern));
|
|
291
|
+
}
|
|
292
|
+
// TODO: currently only supported through `props.public` in constructor
|
|
293
|
+
// /**
|
|
294
|
+
// * Allows unrestricted access to objects from this bucket.
|
|
295
|
+
// *
|
|
296
|
+
// * IMPORTANT: This permission allows anyone to perform actions on S3 objects
|
|
297
|
+
// * in this bucket, which is useful for when you configure your bucket as a
|
|
298
|
+
// * website and want everyone to be able to read objects in the bucket without
|
|
299
|
+
// * needing to authenticate.
|
|
300
|
+
// *
|
|
301
|
+
// * Without arguments, this method will grant read ("s3:GetObject") access to
|
|
302
|
+
// * all objects ("*") in the bucket.
|
|
303
|
+
// *
|
|
304
|
+
// * The method returns the `iam.Grant` object, which can then be modified
|
|
305
|
+
// * as needed. For example, you can add a condition that will restrict access only
|
|
306
|
+
// * to an IPv4 range like this:
|
|
307
|
+
// *
|
|
308
|
+
// * const grant = bucket.grantPublicAccess();
|
|
309
|
+
// * grant.resourceStatement!.addCondition(‘IpAddress’, { “aws:SourceIp”: “54.240.143.0/24” });
|
|
310
|
+
// *
|
|
311
|
+
// * Note that if this `IBucket` refers to an existing bucket, possibly not
|
|
312
|
+
// * managed by CloudFormation, this method will have no effect, since it's
|
|
313
|
+
// * impossible to modify the policy of an existing bucket.
|
|
314
|
+
// *
|
|
315
|
+
// * @param keyPrefix the prefix of S3 object keys (e.g. `home/*`). Default is "*".
|
|
316
|
+
// * @param allowedActions the set of S3 actions to allow. Default is "s3:GetObject".
|
|
317
|
+
// */
|
|
318
|
+
// public grantPublicAccess(keyPrefix = "*", ...allowedActions: string[]) {
|
|
319
|
+
// if (!this.public) {
|
|
320
|
+
// throw new Error("Cannot grant public access when 'public' is enabled");
|
|
321
|
+
// }
|
|
322
|
+
// // TDOO: This should create publicAccess resource
|
|
323
|
+
// allowedActions =
|
|
324
|
+
// allowedActions.length > 0 ? allowedActions : ["s3:GetObject"];
|
|
325
|
+
// return iam.Grant.addToPrincipalOrResource({
|
|
326
|
+
// actions: allowedActions,
|
|
327
|
+
// resourceArns: [this.arnForObjects(keyPrefix)],
|
|
328
|
+
// grantee: new iam.AnyPrincipal(),
|
|
329
|
+
// resource: this,
|
|
330
|
+
// });
|
|
331
|
+
// }
|
|
332
|
+
/**
|
|
333
|
+
* Adds a bucket notification event destination.
|
|
334
|
+
*
|
|
335
|
+
* S3 Buckets only support a single notification configuration resource.
|
|
336
|
+
* Declaring multiple `aws_s3_bucket_notification` resources to the same
|
|
337
|
+
* S3 Bucket will cause a perpetual difference in configuration.
|
|
338
|
+
*
|
|
339
|
+
* Calling this function will overwrite any existing event notifications configured
|
|
340
|
+
* for the S3 bucket outside of this beacon.
|
|
341
|
+
*
|
|
342
|
+
* @param event The event to trigger the notification
|
|
343
|
+
* @param dest The notification destination (Lambda, SNS Topic or SQS Queue)
|
|
344
|
+
*
|
|
345
|
+
* @param filters S3 object key filter rules to determine which objects
|
|
346
|
+
* trigger this event. Each filter must include a `prefix` and/or `suffix`
|
|
347
|
+
* that will be matched against the s3 object key. Refer to the S3 Developer Guide
|
|
348
|
+
* for details about allowed filter rules.
|
|
349
|
+
*
|
|
350
|
+
* @see https://docs.aws.amazon.com/AmazonS3/latest/dev/NotificationHowTo.html#notification-how-to-filtering
|
|
351
|
+
*
|
|
352
|
+
* @example
|
|
353
|
+
*
|
|
354
|
+
* declare const myFunction: compute.Function;
|
|
355
|
+
* const bucket = new storage.Bucket(this, 'MyBucket');
|
|
356
|
+
* bucket.addEventNotification(s3.EventType.OBJECT_CREATED, new s3n.LambdaDestination(myFunction), {prefix: 'home/myusername/*'});
|
|
357
|
+
*
|
|
358
|
+
* @see
|
|
359
|
+
* https://docs.aws.amazon.com/AmazonS3/latest/dev/NotificationHowTo.html
|
|
360
|
+
*/
|
|
361
|
+
addEventNotification(event, dest, ...filters) {
|
|
362
|
+
// TODO: This blocks adding notifications outside of the Stack owning the bucket...
|
|
363
|
+
// AWS-CDK works around this by using a CustomResource handler (Lambda function) which modifies
|
|
364
|
+
// the bucket policy in place (and CFN does not manage the actual bucket policy, so no tf state!)
|
|
365
|
+
this.withNotifications((notifications) => notifications.addNotification(event, dest, ...filters));
|
|
366
|
+
}
|
|
367
|
+
withNotifications(cb) {
|
|
368
|
+
if (!this.notifications) {
|
|
369
|
+
this.notifications = new _1.BucketNotifications(this, "Notifications", {
|
|
370
|
+
bucket: this,
|
|
371
|
+
});
|
|
372
|
+
}
|
|
373
|
+
cb(this.notifications);
|
|
374
|
+
}
|
|
375
|
+
/**
|
|
376
|
+
* Subscribes a destination to receive notifications when an object is
|
|
377
|
+
* created in the bucket. This is identical to calling
|
|
378
|
+
* `onEvent(EventType.OBJECT_CREATED)`.
|
|
379
|
+
*
|
|
380
|
+
* @param dest The notification destination (see onEvent)
|
|
381
|
+
* @param filters Filters (see onEvent)
|
|
382
|
+
*/
|
|
383
|
+
addObjectCreatedNotification(dest, ...filters) {
|
|
384
|
+
return this.addEventNotification(EventType.OBJECT_CREATED, dest, ...filters);
|
|
385
|
+
}
|
|
386
|
+
/**
|
|
387
|
+
* Subscribes a destination to receive notifications when an object is
|
|
388
|
+
* removed from the bucket. This is identical to calling
|
|
389
|
+
* `onEvent(EventType.OBJECT_REMOVED)`.
|
|
390
|
+
*
|
|
391
|
+
* @param dest The notification destination (see onEvent)
|
|
392
|
+
* @param filters Filters (see onEvent)
|
|
393
|
+
*/
|
|
394
|
+
addObjectRemovedNotification(dest, ...filters) {
|
|
395
|
+
return this.addEventNotification(EventType.OBJECT_REMOVED, dest, ...filters);
|
|
396
|
+
}
|
|
397
|
+
/**
|
|
398
|
+
* Enables event bridge notification, causing all events below to be sent to EventBridge:
|
|
399
|
+
*
|
|
400
|
+
* - Object Deleted (DeleteObject)
|
|
401
|
+
* - Object Deleted (Lifecycle expiration)
|
|
402
|
+
* - Object Restore Initiated
|
|
403
|
+
* - Object Restore Completed
|
|
404
|
+
* - Object Restore Expired
|
|
405
|
+
* - Object Storage Class Changed
|
|
406
|
+
* - Object Access Tier Changed
|
|
407
|
+
* - Object ACL Updated
|
|
408
|
+
* - Object Tags Added
|
|
409
|
+
* - Object Tags Deleted
|
|
410
|
+
*/
|
|
411
|
+
enableEventBridgeNotification() {
|
|
412
|
+
this.withNotifications((notifications) => notifications.enableEventBridgeNotification());
|
|
413
|
+
}
|
|
414
|
+
grant(grantee, bucketActions, _keyActions, resourceArn, ...otherResourceArns) {
|
|
415
|
+
const resources = [resourceArn, ...otherResourceArns];
|
|
416
|
+
const ret = iam.Grant.addToPrincipalOrResource({
|
|
417
|
+
grantee,
|
|
418
|
+
actions: bucketActions,
|
|
419
|
+
resourceArns: resources,
|
|
420
|
+
resource: this,
|
|
421
|
+
});
|
|
422
|
+
// TODO: re-add KMS support
|
|
423
|
+
// if (this.encryptionKey && keyActions && keyActions.length !== 0) {
|
|
424
|
+
// this.encryptionKey.grant(grantee, ...keyActions);
|
|
425
|
+
// }
|
|
426
|
+
return ret;
|
|
427
|
+
}
|
|
428
|
+
get writeActions() {
|
|
429
|
+
return [...perms.BUCKET_DELETE_ACTIONS, ...perms.BUCKET_PUT_ACTIONS];
|
|
430
|
+
}
|
|
431
|
+
/**
|
|
432
|
+
* Add a source to the bucket.
|
|
433
|
+
*
|
|
434
|
+
* @param props The properties of the source to add
|
|
435
|
+
*/
|
|
436
|
+
addSource(props, sourceId) {
|
|
437
|
+
if (this.versioned) {
|
|
438
|
+
/**
|
|
439
|
+
* If you enable versioning on a bucket for the first time, it might take up to 15 minutes
|
|
440
|
+
* for the change to be fully propagated. We recommend that you wait for 15 minutes after
|
|
441
|
+
* enabling versioning before issuing write operations (PUT or DELETE) on objects in the bucket.
|
|
442
|
+
*
|
|
443
|
+
* Write operations issued before this conversion is complete may apply to unversioned objects.
|
|
444
|
+
*/
|
|
445
|
+
if (!this.sourceSleep) {
|
|
446
|
+
this.sourceSleep = new provider_time_1.sleep.Sleep(this, "VersioningSleep", {
|
|
447
|
+
createDuration: "15m",
|
|
448
|
+
});
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
const indexedSource = this.sources.find((sourceIndex) => sourceIndex.props === props);
|
|
452
|
+
if (indexedSource) {
|
|
453
|
+
if (sourceId && sourceId !== indexedSource.id) {
|
|
454
|
+
throw new Error(`Duplicate bucket source for ${indexedSource.id} and ${sourceId}.`);
|
|
455
|
+
}
|
|
456
|
+
return indexedSource.id;
|
|
457
|
+
}
|
|
458
|
+
const nextIndex = this.sources.length;
|
|
459
|
+
const id = sourceId ?? `source-${nextIndex}`;
|
|
460
|
+
// ensure id (if provided) is unique within Bucket
|
|
461
|
+
if (this.sources.some((sourceIndex) => sourceIndex.id === id)) {
|
|
462
|
+
throw new Error(`Duplicate source id ${id}. SourceIds must be unique within a Bucket.`);
|
|
463
|
+
}
|
|
464
|
+
this.sources.push({
|
|
465
|
+
props: {
|
|
466
|
+
...props,
|
|
467
|
+
bucket: this,
|
|
468
|
+
dependsOn: this.sourceSleep ? [this.sourceSleep] : undefined,
|
|
469
|
+
},
|
|
470
|
+
id,
|
|
471
|
+
});
|
|
472
|
+
return id;
|
|
473
|
+
}
|
|
474
|
+
isWebsite() {
|
|
475
|
+
return this._isWebsite;
|
|
476
|
+
}
|
|
477
|
+
/**
|
|
478
|
+
* The https URL of an S3 object. Specify `regional: false` at the options
|
|
479
|
+
* for non-regional URLs. For example:
|
|
480
|
+
*
|
|
481
|
+
* - `https://s3.us-west-1.amazonaws.com/onlybucket`
|
|
482
|
+
* - `https://s3.us-west-1.amazonaws.com/bucket/key`
|
|
483
|
+
* - `https://s3.cn-north-1.amazonaws.com.cn/china-bucket/mykey`
|
|
484
|
+
*
|
|
485
|
+
* @param key The S3 key of the object. If not specified, the URL of the
|
|
486
|
+
* bucket is returned.
|
|
487
|
+
* @returns an ObjectS3Url token
|
|
488
|
+
*/
|
|
489
|
+
urlForObject(key) {
|
|
490
|
+
const stack = __1.AwsStack.ofAwsConstruct(this);
|
|
491
|
+
const prefix = `https://s3.${this.env.region}.${stack.urlSuffix}/`;
|
|
492
|
+
if (typeof key !== "string") {
|
|
493
|
+
return this.urlJoin(prefix, this.bucketName);
|
|
494
|
+
}
|
|
495
|
+
return this.urlJoin(prefix, this.bucketName, key);
|
|
496
|
+
}
|
|
497
|
+
/**
|
|
498
|
+
* The S3 URL of an S3 object. For example:
|
|
499
|
+
*
|
|
500
|
+
* - `s3://onlybucket`
|
|
501
|
+
* - `s3://bucket/key`
|
|
502
|
+
*
|
|
503
|
+
* @param key The S3 key of the object. If not specified, the S3 URL of the
|
|
504
|
+
* bucket is returned.
|
|
505
|
+
* @returns an ObjectS3Url token
|
|
506
|
+
*/
|
|
507
|
+
s3UrlForObject(key) {
|
|
508
|
+
const prefix = "s3://";
|
|
509
|
+
if (typeof key !== "string") {
|
|
510
|
+
return this.urlJoin(prefix, this.bucketName);
|
|
511
|
+
}
|
|
512
|
+
return this.urlJoin(prefix, this.bucketName, key);
|
|
513
|
+
}
|
|
514
|
+
/**
|
|
515
|
+
* Returns an ARN that represents all objects within the bucket that match
|
|
516
|
+
* the key pattern specified. To represent all keys, specify ``"*"``.
|
|
517
|
+
*
|
|
518
|
+
* If you need to specify a keyPattern with multiple components, concatenate them into a single string, e.g.:
|
|
519
|
+
*
|
|
520
|
+
* arnForObjects(`home/${team}/${user}/*`)
|
|
521
|
+
*
|
|
522
|
+
*/
|
|
523
|
+
arnForObjects(keyPattern) {
|
|
524
|
+
return `${this.resource.arn}/${keyPattern}`;
|
|
525
|
+
}
|
|
526
|
+
// https://github.com/aws/aws-cdk/blob/v2.140.0/packages/aws-cdk-lib/aws-s3/lib/bucket.ts#L953
|
|
527
|
+
urlJoin(...components) {
|
|
528
|
+
return components.reduce((result, component) => {
|
|
529
|
+
if (result.endsWith("/")) {
|
|
530
|
+
result = result.slice(0, -1);
|
|
531
|
+
}
|
|
532
|
+
if (component.startsWith("/")) {
|
|
533
|
+
component = component.slice(1);
|
|
534
|
+
}
|
|
535
|
+
return `${result}/${component}`;
|
|
536
|
+
});
|
|
537
|
+
}
|
|
538
|
+
/**
|
|
539
|
+
* Adds an iam statement to enforce SSL requests only.
|
|
540
|
+
*/
|
|
541
|
+
enforceSSLStatement() {
|
|
542
|
+
const statement = new iam.PolicyStatement({
|
|
543
|
+
actions: ["s3:*"],
|
|
544
|
+
condition: [
|
|
545
|
+
{
|
|
546
|
+
test: "Bool",
|
|
547
|
+
variable: "aws:SecureTransport",
|
|
548
|
+
values: ["false"],
|
|
549
|
+
},
|
|
550
|
+
],
|
|
551
|
+
effect: iam.Effect.DENY,
|
|
552
|
+
resources: [this.resource.arn, this.arnForObjects("*")],
|
|
553
|
+
principals: [new iam.AnyPrincipal()],
|
|
554
|
+
});
|
|
555
|
+
this.addToResourcePolicy(statement);
|
|
556
|
+
}
|
|
557
|
+
/**
|
|
558
|
+
* Adds an iam statement to allow requests with a minimum TLS
|
|
559
|
+
* version only.
|
|
560
|
+
*/
|
|
561
|
+
minimumTLSVersionStatement(minimumTLSVersion) {
|
|
562
|
+
if (!minimumTLSVersion)
|
|
563
|
+
return;
|
|
564
|
+
const statement = new iam.PolicyStatement({
|
|
565
|
+
actions: ["s3:*"],
|
|
566
|
+
condition: [
|
|
567
|
+
{
|
|
568
|
+
test: "NumericLessThan",
|
|
569
|
+
variable: "s3:TlsVersion",
|
|
570
|
+
values: [minimumTLSVersion.toString()],
|
|
571
|
+
},
|
|
572
|
+
],
|
|
573
|
+
effect: iam.Effect.DENY,
|
|
574
|
+
resources: [this.resource.arn, this.arnForObjects("*")],
|
|
575
|
+
principals: [new iam.AnyPrincipal()],
|
|
576
|
+
});
|
|
577
|
+
this.addToResourcePolicy(statement);
|
|
578
|
+
}
|
|
579
|
+
/**
|
|
580
|
+
* Adds resource to the Terraform JSON output at Synth time.
|
|
581
|
+
*
|
|
582
|
+
* called by TerraformStack.prepareStack()
|
|
583
|
+
*/
|
|
584
|
+
toTerraform() {
|
|
585
|
+
/**
|
|
586
|
+
* A preparing resolve might add new resources to the stack
|
|
587
|
+
*
|
|
588
|
+
* should not add resources if no bucket sources are defined
|
|
589
|
+
*/
|
|
590
|
+
if (Object.keys(this.sources).length === 0) {
|
|
591
|
+
return {};
|
|
592
|
+
}
|
|
593
|
+
for (const source of this.sources) {
|
|
594
|
+
// TODO: Ideally we should have used IResolvable.resolve and use the IResolveContext.preparing flag
|
|
595
|
+
// ref: https://github.com/aws/aws-cdk/blob/v2.170.0/packages/aws-cdk-lib/aws-iam/lib/policy-document.ts#L48
|
|
596
|
+
if (this.node.tryFindChild(source.id))
|
|
597
|
+
continue; // ignore if already generated
|
|
598
|
+
new _1.BucketSource(this, source.id, source.props);
|
|
599
|
+
}
|
|
600
|
+
return {};
|
|
601
|
+
}
|
|
602
|
+
}
|
|
603
|
+
exports.Bucket = Bucket;
|
|
604
|
+
_a = JSII_RTTI_SYMBOL_1;
|
|
605
|
+
Bucket[_a] = { fqn: "terraconstructs.aws.storage.Bucket", version: "0.0.8" };
|
|
606
|
+
/**
|
|
607
|
+
* Storage class to move an object to
|
|
608
|
+
*/
|
|
609
|
+
var StorageClass;
|
|
610
|
+
(function (StorageClass) {
|
|
611
|
+
/**
|
|
612
|
+
* Storage class for data that is accessed less frequently, but requires rapid
|
|
613
|
+
* access when needed.
|
|
614
|
+
*
|
|
615
|
+
* Has lower availability than Standard storage.
|
|
616
|
+
*/
|
|
617
|
+
StorageClass["INFREQUENT_ACCESS"] = "STANDARD_IA";
|
|
618
|
+
/**
|
|
619
|
+
* Infrequent Access that's only stored in one availability zone.
|
|
620
|
+
*
|
|
621
|
+
* Has lower availability than standard InfrequentAccess.
|
|
622
|
+
*/
|
|
623
|
+
StorageClass["ONE_ZONE_INFREQUENT_ACCESS"] = "ONEZONE_IA";
|
|
624
|
+
/**
|
|
625
|
+
* Storage class for long-term archival that can take between minutes and
|
|
626
|
+
* hours to access.
|
|
627
|
+
*
|
|
628
|
+
* Use for archives where portions of the data might need to be retrieved in
|
|
629
|
+
* minutes. Data stored in the GLACIER storage class has a minimum storage
|
|
630
|
+
* duration period of 90 days and can be accessed in as little as 1-5 minutes
|
|
631
|
+
* using expedited retrieval. If you delete an object before the 90-day
|
|
632
|
+
* minimum, you are charged for 90 days.
|
|
633
|
+
*/
|
|
634
|
+
StorageClass["GLACIER"] = "GLACIER";
|
|
635
|
+
/**
|
|
636
|
+
* Storage class for long-term archival that can be accessed in a few milliseconds.
|
|
637
|
+
*
|
|
638
|
+
* It is ideal for data that is accessed once or twice per quarter, and
|
|
639
|
+
* that requires immediate access. Data stored in the GLACIER_IR storage class
|
|
640
|
+
* has a minimum storage duration period of 90 days and can be accessed in
|
|
641
|
+
* as milliseconds. If you delete an object before the 90-day minimum,
|
|
642
|
+
* you are charged for 90 days.
|
|
643
|
+
*/
|
|
644
|
+
StorageClass["GLACIER_INSTANT_RETRIEVAL"] = "GLACIER_IR";
|
|
645
|
+
/**
|
|
646
|
+
* Use for archiving data that rarely needs to be accessed. Data stored in the
|
|
647
|
+
* DEEP_ARCHIVE storage class has a minimum storage duration period of 180
|
|
648
|
+
* days and a default retrieval time of 12 hours. If you delete an object
|
|
649
|
+
* before the 180-day minimum, you are charged for 180 days. For pricing
|
|
650
|
+
* information, see Amazon S3 Pricing.
|
|
651
|
+
*/
|
|
652
|
+
StorageClass["DEEP_ARCHIVE"] = "DEEP_ARCHIVE";
|
|
653
|
+
/**
|
|
654
|
+
* The INTELLIGENT_TIERING storage class is designed to optimize storage costs
|
|
655
|
+
* by automatically moving data to the most cost-effective storage access
|
|
656
|
+
* tier, without performance impact or operational overhead.
|
|
657
|
+
* INTELLIGENT_TIERING delivers automatic cost savings by moving data on a
|
|
658
|
+
* granular object level between two access tiers, a frequent access tier and
|
|
659
|
+
* a lower-cost infrequent access tier, when access patterns change. The
|
|
660
|
+
* INTELLIGENT_TIERING storage class is ideal if you want to optimize storage
|
|
661
|
+
* costs automatically for long-lived data when access patterns are unknown or
|
|
662
|
+
* unpredictable.
|
|
663
|
+
*/
|
|
664
|
+
StorageClass["INTELLIGENT_TIERING"] = "INTELLIGENT_TIERING";
|
|
665
|
+
})(StorageClass || (exports.StorageClass = StorageClass = {}));
|
|
666
|
+
/**
|
|
667
|
+
* Notification event types.
|
|
668
|
+
* @link https://docs.aws.amazon.com/AmazonS3/latest/userguide/notification-how-to-event-types-and-destinations.html#supported-notification-event-types
|
|
669
|
+
*/
|
|
670
|
+
var EventType;
|
|
671
|
+
(function (EventType) {
|
|
672
|
+
/**
|
|
673
|
+
* Amazon S3 APIs such as PUT, POST, and COPY can create an object. Using
|
|
674
|
+
* these event types, you can enable notification when an object is created
|
|
675
|
+
* using a specific API, or you can use the s3:ObjectCreated:* event type to
|
|
676
|
+
* request notification regardless of the API that was used to create an
|
|
677
|
+
* object.
|
|
678
|
+
*/
|
|
679
|
+
EventType["OBJECT_CREATED"] = "s3:ObjectCreated:*";
|
|
680
|
+
/**
|
|
681
|
+
* Amazon S3 APIs such as PUT, POST, and COPY can create an object. Using
|
|
682
|
+
* these event types, you can enable notification when an object is created
|
|
683
|
+
* using a specific API, or you can use the s3:ObjectCreated:* event type to
|
|
684
|
+
* request notification regardless of the API that was used to create an
|
|
685
|
+
* object.
|
|
686
|
+
*/
|
|
687
|
+
EventType["OBJECT_CREATED_PUT"] = "s3:ObjectCreated:Put";
|
|
688
|
+
/**
|
|
689
|
+
* Amazon S3 APIs such as PUT, POST, and COPY can create an object. Using
|
|
690
|
+
* these event types, you can enable notification when an object is created
|
|
691
|
+
* using a specific API, or you can use the s3:ObjectCreated:* event type to
|
|
692
|
+
* request notification regardless of the API that was used to create an
|
|
693
|
+
* object.
|
|
694
|
+
*/
|
|
695
|
+
EventType["OBJECT_CREATED_POST"] = "s3:ObjectCreated:Post";
|
|
696
|
+
/**
|
|
697
|
+
* Amazon S3 APIs such as PUT, POST, and COPY can create an object. Using
|
|
698
|
+
* these event types, you can enable notification when an object is created
|
|
699
|
+
* using a specific API, or you can use the s3:ObjectCreated:* event type to
|
|
700
|
+
* request notification regardless of the API that was used to create an
|
|
701
|
+
* object.
|
|
702
|
+
*/
|
|
703
|
+
EventType["OBJECT_CREATED_COPY"] = "s3:ObjectCreated:Copy";
|
|
704
|
+
/**
|
|
705
|
+
* Amazon S3 APIs such as PUT, POST, and COPY can create an object. Using
|
|
706
|
+
* these event types, you can enable notification when an object is created
|
|
707
|
+
* using a specific API, or you can use the s3:ObjectCreated:* event type to
|
|
708
|
+
* request notification regardless of the API that was used to create an
|
|
709
|
+
* object.
|
|
710
|
+
*/
|
|
711
|
+
EventType["OBJECT_CREATED_COMPLETE_MULTIPART_UPLOAD"] = "s3:ObjectCreated:CompleteMultipartUpload";
|
|
712
|
+
/**
|
|
713
|
+
* By using the ObjectRemoved event types, you can enable notification when
|
|
714
|
+
* an object or a batch of objects is removed from a bucket.
|
|
715
|
+
*
|
|
716
|
+
* You can request notification when an object is deleted or a versioned
|
|
717
|
+
* object is permanently deleted by using the s3:ObjectRemoved:Delete event
|
|
718
|
+
* type. Or you can request notification when a delete marker is created for
|
|
719
|
+
* a versioned object by using s3:ObjectRemoved:DeleteMarkerCreated. For
|
|
720
|
+
* information about deleting versioned objects, see Deleting Object
|
|
721
|
+
* Versions. You can also use a wildcard s3:ObjectRemoved:* to request
|
|
722
|
+
* notification anytime an object is deleted.
|
|
723
|
+
*
|
|
724
|
+
* You will not receive event notifications from automatic deletes from
|
|
725
|
+
* lifecycle policies or from failed operations.
|
|
726
|
+
*/
|
|
727
|
+
EventType["OBJECT_REMOVED"] = "s3:ObjectRemoved:*";
|
|
728
|
+
/**
|
|
729
|
+
* By using the ObjectRemoved event types, you can enable notification when
|
|
730
|
+
* an object or a batch of objects is removed from a bucket.
|
|
731
|
+
*
|
|
732
|
+
* You can request notification when an object is deleted or a versioned
|
|
733
|
+
* object is permanently deleted by using the s3:ObjectRemoved:Delete event
|
|
734
|
+
* type. Or you can request notification when a delete marker is created for
|
|
735
|
+
* a versioned object by using s3:ObjectRemoved:DeleteMarkerCreated. For
|
|
736
|
+
* information about deleting versioned objects, see Deleting Object
|
|
737
|
+
* Versions. You can also use a wildcard s3:ObjectRemoved:* to request
|
|
738
|
+
* notification anytime an object is deleted.
|
|
739
|
+
*
|
|
740
|
+
* You will not receive event notifications from automatic deletes from
|
|
741
|
+
* lifecycle policies or from failed operations.
|
|
742
|
+
*/
|
|
743
|
+
EventType["OBJECT_REMOVED_DELETE"] = "s3:ObjectRemoved:Delete";
|
|
744
|
+
/**
|
|
745
|
+
* By using the ObjectRemoved event types, you can enable notification when
|
|
746
|
+
* an object or a batch of objects is removed from a bucket.
|
|
747
|
+
*
|
|
748
|
+
* You can request notification when an object is deleted or a versioned
|
|
749
|
+
* object is permanently deleted by using the s3:ObjectRemoved:Delete event
|
|
750
|
+
* type. Or you can request notification when a delete marker is created for
|
|
751
|
+
* a versioned object by using s3:ObjectRemoved:DeleteMarkerCreated. For
|
|
752
|
+
* information about deleting versioned objects, see Deleting Object
|
|
753
|
+
* Versions. You can also use a wildcard s3:ObjectRemoved:* to request
|
|
754
|
+
* notification anytime an object is deleted.
|
|
755
|
+
*
|
|
756
|
+
* You will not receive event notifications from automatic deletes from
|
|
757
|
+
* lifecycle policies or from failed operations.
|
|
758
|
+
*/
|
|
759
|
+
EventType["OBJECT_REMOVED_DELETE_MARKER_CREATED"] = "s3:ObjectRemoved:DeleteMarkerCreated";
|
|
760
|
+
/**
|
|
761
|
+
* Using restore object event types you can receive notifications for
|
|
762
|
+
* initiation and completion when restoring objects from the S3 Glacier
|
|
763
|
+
* storage class.
|
|
764
|
+
*
|
|
765
|
+
* You use s3:ObjectRestore:Post to request notification of object restoration
|
|
766
|
+
* initiation.
|
|
767
|
+
*/
|
|
768
|
+
EventType["OBJECT_RESTORE_POST"] = "s3:ObjectRestore:Post";
|
|
769
|
+
/**
|
|
770
|
+
* Using restore object event types you can receive notifications for
|
|
771
|
+
* initiation and completion when restoring objects from the S3 Glacier
|
|
772
|
+
* storage class.
|
|
773
|
+
*
|
|
774
|
+
* You use s3:ObjectRestore:Completed to request notification of
|
|
775
|
+
* restoration completion.
|
|
776
|
+
*/
|
|
777
|
+
EventType["OBJECT_RESTORE_COMPLETED"] = "s3:ObjectRestore:Completed";
|
|
778
|
+
/**
|
|
779
|
+
* Using restore object event types you can receive notifications for
|
|
780
|
+
* initiation and completion when restoring objects from the S3 Glacier
|
|
781
|
+
* storage class.
|
|
782
|
+
*
|
|
783
|
+
* You use s3:ObjectRestore:Delete to request notification of
|
|
784
|
+
* restoration completion.
|
|
785
|
+
*/
|
|
786
|
+
EventType["OBJECT_RESTORE_DELETE"] = "s3:ObjectRestore:Delete";
|
|
787
|
+
/**
|
|
788
|
+
* You can use this event type to request Amazon S3 to send a notification
|
|
789
|
+
* message when Amazon S3 detects that an object of the RRS storage class is
|
|
790
|
+
* lost.
|
|
791
|
+
*/
|
|
792
|
+
EventType["REDUCED_REDUNDANCY_LOST_OBJECT"] = "s3:ReducedRedundancyLostObject";
|
|
793
|
+
/**
|
|
794
|
+
* You receive this notification event when an object that was eligible for
|
|
795
|
+
* replication using Amazon S3 Replication Time Control failed to replicate.
|
|
796
|
+
*/
|
|
797
|
+
EventType["REPLICATION_OPERATION_FAILED_REPLICATION"] = "s3:Replication:OperationFailedReplication";
|
|
798
|
+
/**
|
|
799
|
+
* You receive this notification event when an object that was eligible for
|
|
800
|
+
* replication using Amazon S3 Replication Time Control exceeded the 15-minute
|
|
801
|
+
* threshold for replication.
|
|
802
|
+
*/
|
|
803
|
+
EventType["REPLICATION_OPERATION_MISSED_THRESHOLD"] = "s3:Replication:OperationMissedThreshold";
|
|
804
|
+
/**
|
|
805
|
+
* You receive this notification event for an object that was eligible for
|
|
806
|
+
* replication using the Amazon S3 Replication Time Control feature replicated
|
|
807
|
+
* after the 15-minute threshold.
|
|
808
|
+
*/
|
|
809
|
+
EventType["REPLICATION_OPERATION_REPLICATED_AFTER_THRESHOLD"] = "s3:Replication:OperationReplicatedAfterThreshold";
|
|
810
|
+
/**
|
|
811
|
+
* You receive this notification event for an object that was eligible for
|
|
812
|
+
* replication using Amazon S3 Replication Time Control but is no longer tracked
|
|
813
|
+
* by replication metrics.
|
|
814
|
+
*/
|
|
815
|
+
EventType["REPLICATION_OPERATION_NOT_TRACKED"] = "s3:Replication:OperationNotTracked";
|
|
816
|
+
/**
|
|
817
|
+
* By using the LifecycleExpiration event types, you can receive a notification
|
|
818
|
+
* when Amazon S3 deletes an object based on your S3 Lifecycle configuration.
|
|
819
|
+
*/
|
|
820
|
+
EventType["LIFECYCLE_EXPIRATION"] = "s3:LifecycleExpiration:*";
|
|
821
|
+
/**
|
|
822
|
+
* The s3:LifecycleExpiration:Delete event type notifies you when an object
|
|
823
|
+
* in an unversioned bucket is deleted.
|
|
824
|
+
* It also notifies you when an object version is permanently deleted by an
|
|
825
|
+
* S3 Lifecycle configuration.
|
|
826
|
+
*/
|
|
827
|
+
EventType["LIFECYCLE_EXPIRATION_DELETE"] = "s3:LifecycleExpiration:Delete";
|
|
828
|
+
/**
|
|
829
|
+
* The s3:LifecycleExpiration:DeleteMarkerCreated event type notifies you
|
|
830
|
+
* when S3 Lifecycle creates a delete marker when a current version of an
|
|
831
|
+
* object in versioned bucket is deleted.
|
|
832
|
+
*/
|
|
833
|
+
EventType["LIFECYCLE_EXPIRATION_DELETE_MARKER_CREATED"] = "s3:LifecycleExpiration:DeleteMarkerCreated";
|
|
834
|
+
/**
|
|
835
|
+
* You receive this notification event when an object is transitioned to
|
|
836
|
+
* another Amazon S3 storage class by an S3 Lifecycle configuration.
|
|
837
|
+
*/
|
|
838
|
+
EventType["LIFECYCLE_TRANSITION"] = "s3:LifecycleTransition";
|
|
839
|
+
/**
|
|
840
|
+
* You receive this notification event when an object within the
|
|
841
|
+
* S3 Intelligent-Tiering storage class moved to the Archive Access tier or
|
|
842
|
+
* Deep Archive Access tier.
|
|
843
|
+
*/
|
|
844
|
+
EventType["INTELLIGENT_TIERING"] = "s3:IntelligentTiering";
|
|
845
|
+
/**
|
|
846
|
+
* By using the ObjectTagging event types, you can enable notification when
|
|
847
|
+
* an object tag is added or deleted from an object.
|
|
848
|
+
*/
|
|
849
|
+
EventType["OBJECT_TAGGING"] = "s3:ObjectTagging:*";
|
|
850
|
+
/**
|
|
851
|
+
* The s3:ObjectTagging:Put event type notifies you when a tag is PUT on an
|
|
852
|
+
* object or an existing tag is updated.
|
|
853
|
+
|
|
854
|
+
*/
|
|
855
|
+
EventType["OBJECT_TAGGING_PUT"] = "s3:ObjectTagging:Put";
|
|
856
|
+
/**
|
|
857
|
+
* The s3:ObjectTagging:Delete event type notifies you when a tag is removed
|
|
858
|
+
* from an object.
|
|
859
|
+
*/
|
|
860
|
+
EventType["OBJECT_TAGGING_DELETE"] = "s3:ObjectTagging:Delete";
|
|
861
|
+
/**
|
|
862
|
+
* You receive this notification event when an ACL is PUT on an object or when
|
|
863
|
+
* an existing ACL is changed.
|
|
864
|
+
* An event is not generated when a request results in no change to an
|
|
865
|
+
* object’s ACL.
|
|
866
|
+
*/
|
|
867
|
+
EventType["OBJECT_ACL_PUT"] = "s3:ObjectAcl:Put";
|
|
868
|
+
})(EventType || (exports.EventType = EventType = {}));
|
|
869
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYnVja2V0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2F3cy9zdG9yYWdlL2J1Y2tldC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUFBLHNEQVM2QjtBQUM3Qix3REFBNkM7QUFFN0Msd0JBVVc7QUFDWCwwQkFLWTtBQUNaLDhCQUE4QjtBQUM5Qix3Q0FBd0M7QUF1ZnhDOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0F3Qkc7QUFFSCxNQUFhLE1BQU8sU0FBUSxvQkFBZ0I7SUFVMUMsSUFBVyxTQUFTO1FBQ2xCLE9BQU8sSUFBSSxDQUFDLFVBQVUsQ0FBQztJQUN6QixDQUFDO0lBU0QsSUFBVyxhQUFhO1FBQ3RCLE9BQU8sSUFBSSxDQUFDLFFBQVEsQ0FBQztJQUN2QixDQUFDO0lBQ0QsSUFBVyxPQUFPO1FBQ2hCLE9BQU8sSUFBSSxDQUFDLGFBQWEsQ0FBQztJQUM1QixDQUFDO0lBRUQsSUFBVyxVQUFVO1FBQ25CLE9BQU8sSUFBSSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUM7SUFDOUIsQ0FBQztJQUNELElBQVcsU0FBUztRQUNsQixPQUFPLElBQUksQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDO0lBQzNCLENBQUM7SUFDRCxJQUFXLFlBQVk7UUFDckIsT0FBTyxJQUFJLENBQUMsUUFBUSxDQUFDLFlBQVksQ0FBQztJQUNwQyxDQUFDO0lBQ0QsSUFBVyxpQkFBaUI7UUFDMUIsT0FBTyxJQUFJLENBQUMsYUFBYSxFQUFFLGFBQWEsQ0FBQztJQUMzQyxDQUFDO0lBV0QsWUFBWSxLQUFnQixFQUFFLElBQVksRUFBRSxRQUFxQixFQUFFO1FBQ2pFLEtBQUssQ0FBQyxLQUFLLEVBQUUsSUFBSSxFQUFFLEtBQUssQ0FBQyxDQUFDO1FBN0M1QixnQkFBZ0I7UUFDQyxZQUFPLEdBQWtCLEVBQUUsQ0FBQztRQThDM0MsSUFBSSxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUM7WUFDdEIsUUFBUSxFQUFFLEdBQUcsRUFBRSxD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QyxDQUFBO0lBRXJDOzs7Ozs7T0FNRztJQUNILHdEQUEyQyxDQUFBO0lBRTNDOzs7Ozs7T0FNRztJQUNILDBEQUE2QyxDQUFBO0lBRTdDOzs7Ozs7T0FNRztJQUNILDBEQUE2QyxDQUFBO0lBRTdDOzs7Ozs7T0FNRztJQUNILGtHQUFxRixDQUFBO0lBRXJGOzs7Ozs7Ozs7Ozs7OztPQWNHO0lBQ0gsa0RBQXFDLENBQUE7SUFFckM7Ozs7Ozs7Ozs7Ozs7O09BY0c7SUFDSCw4REFBaUQsQ0FBQTtJQUVqRDs7Ozs7Ozs7Ozs7Ozs7T0FjRztJQUNILDBGQUE2RSxDQUFBO0lBRTdFOzs7Ozs7O09BT0c7SUFDSCwwREFBNkMsQ0FBQTtJQUU3Qzs7Ozs7OztPQU9HO0lBQ0gsb0VBQXVELENBQUE7SUFFdkQ7Ozs7Ozs7T0FPRztJQUNILDhEQUFpRCxDQUFBO0lBRWpEOzs7O09BSUc7SUFDSCw4RUFBaUUsQ0FBQTtJQUVqRTs7O09BR0c7SUFDSCxtR0FBc0YsQ0FBQTtJQUV0Rjs7OztPQUlHO0lBQ0gsK0ZBQWtGLENBQUE7SUFFbEY7Ozs7T0FJRztJQUNILGtIQUFxRyxDQUFBO0lBRXJHOzs7O09BSUc7SUFDSCxxRkFBd0UsQ0FBQTtJQUV4RTs7O09BR0c7SUFDSCw4REFBaUQsQ0FBQTtJQUVqRDs7Ozs7T0FLRztJQUNILDBFQUE2RCxDQUFBO0lBRTdEOzs7O09BSUc7SUFDSCxzR0FBeUYsQ0FBQTtJQUV6Rjs7O09BR0c7SUFDSCw0REFBK0MsQ0FBQTtJQUUvQzs7OztPQUlHO0lBQ0gsMERBQTZDLENBQUE7SUFFN0M7OztPQUdHO0lBQ0gsa0RBQXFDLENBQUE7SUFFckM7Ozs7T0FJRztJQUNILHdEQUEyQyxDQUFBO0lBRTNDOzs7T0FHRztJQUNILDhEQUFpRCxDQUFBO0lBRWpEOzs7OztPQUtHO0lBQ0gsZ0RBQW1DLENBQUE7QUFDckMsQ0FBQyxFQTdOVyxTQUFTLHlCQUFULFNBQVMsUUE2TnBCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgczNCdWNrZXQsXG4gIHMzQnVja2V0QWNsLFxuICBzM0J1Y2tldENvcnNDb25maWd1cmF0aW9uLFxuICBzM0J1Y2tldE93bmVyc2hpcENvbnRyb2xzLFxuICBzM0J1Y2tldFB1YmxpY0FjY2Vzc0Jsb2NrLFxuICBzM0J1Y2tldFdlYnNpdGVDb25maWd1cmF0aW9uLFxuICBzM0J1Y2tldExpZmVjeWNsZUNvbmZpZ3VyYXRpb24sXG4gIHMzQnVja2V0VmVyc2lvbmluZyxcbn0gZnJvbSBcIkBjZGt0Zi9wcm92aWRlci1hd3NcIjtcbmltcG9ydCB7IHNsZWVwIH0gZnJvbSBcIkBjZGt0Zi9wcm92aWRlci10aW1lXCI7XG5pbXBvcnQgeyBDb25zdHJ1Y3QgfSBmcm9tIFwiY29uc3RydWN0c1wiO1xuaW1wb3J0IHtcbiAgQnVja2V0U291cmNlLFxuICBCdWNrZXRTb3VyY2VQcm9wcyxcbiAgV2Vic2l0ZUNvbmZpZyxcbiAgQ29yc0NvbmZpZyxcbiAgTGlmZWN5Y2xlQ29uZmlndXJhdGlvblJ1bGUsXG4gIE9yaWdpbkFjY2Vzc0lkZW50aXR5LFxuICBCdWNrZXRQb2xpY3ksXG4gIEJ1Y2tldE5vdGlmaWNhdGlvbnMsXG4gIElCdWNrZXROb3RpZmljYXRpb25EZXN0aW5hdGlvbixcbn0gZnJvbSBcIi5cIjtcbmltcG9ydCB7XG4gIEF3c0NvbnN0cnVjdEJhc2UsXG4gIElBd3NDb25zdHJ1Y3QsXG4gIEF3c0NvbnN0cnVjdFByb3BzLFxuICBBd3NTdGFjayxcbn0gZnJvbSBcIi4uXCI7XG5pbXBvcnQgKiBhcyBpYW0gZnJvbSBcIi4uL2lhbVwiO1xuaW1wb3J0ICogYXMgcGVybXMgZnJvbSBcIi4vYnVja2V0LXBlcm1zXCI7XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ2xvdWRmcm9udEFjY2Vzc0NvbmZpZyB7XG4gIC8qKlxuICAgKiBFbmFibGUgQ2xvdWRmcm9udCBhY2Nlc3MgdmlhIE9yaWdpbiBBY2Nlc3MgSWRlbnRpdHkuXG4gICAqL1xuICByZWFkb25seSBlbmFibGVkOiBib29sZWFuO1xuICAvKipcbiAgICogT2JqZWN0IGtleSBwYXR0ZXJucyBmb3IgY2xvdWRmcm9udCBhY2Nlc3MuXG4gICAqXG4gICAqIEBkZWZhdWx0IFwiKlwiXG4gICAqL1xuICByZWFkb25seSBrZXlQYXR0ZXJucz86IHN0cmluZ1tdO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEJ1Y2tldFByb3BzIGV4dGVuZHMgQXdzQ29uc3RydWN0UHJvcHMge1xuICAvKipcbiAgICogVGhlIHBhdGgocykgdG8gc3RhdGljIGRpcmVjdG9yaWVzIG9yIGZpbGVzIHRvIHVwbG9hZCwgcmVsYXRpdmUgdG8gdGhlIFN0YWNrIGZpbGUuXG4gICAqXG4gICAqIEBleGFtcGxlIFwiLi9kaXN0XCJcbiAgICogQGRlZmF1bHQgLSBObyBmaWxlcyBhcmUgdXBsb2FkZWQuXG4gICAqL1xuICByZWFkb25seSBzb3VyY2VzPzogc3RyaW5nIHwgc3RyaW5nW10gfCBBZGRTb3VyY2VPcHRpb25zW107XG5cbiAgLy8gVE9ETzogQWRkIHN1cHBvcnQgdG8gcGFzcyBkb21haW4gcHJvcHMgKGZvciByb3V0ZTUzIGFsaWFzPylcblxuICAvKipcbiAgICogRW5hYmxlIHB1YmxpYyByZWFkIGFjY2VzcyBmb3IgYWxsIHRoZSBmaWxlcyBpbiB0aGUgYnVja2V0LlxuICAgKlxuICAgKiBFbmFibGUgdGhpcyBvbmx5IGlmIHlvdSdyZSBub3QgdXNpbmcgQ0ROIChDbG91ZEZyb250KSB0byBzZXJ2ZSBmaWxlcyBmcm9tIHRoZSBidWNrZXQuXG4gICAqIFNob3VsZCBvbmx5IGJlIHR1cm5lZCBvbiBpZiB5b3Ugd2FudCB0byBob3N0IHB1YmxpYyBmaWxlcyBkaXJlY3RseSBmcm9tIHRoZSBidWNrZXQuXG4gICAqXG4gICAqIEBkZWZhdWx0IGBmYWxzZWBcbiAgICovXG4gIHJlYWRvbmx5IHB1YmxpYz86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIEEgbmFtZSBmb3IgdGhlIGJ1Y2tldC5cbiAgICpcbiAgICogTXVzdCBiZSBsb3dlcmNhc2UgYW5kIGJldHdlZW4gMyAobWluKSBhbmQgNjMgKG1heCkgY2hhcmFjdGVycyBsb25nLlxuICAgKlxuICAgKiBUaGUgbmFtZSBtdXN0IG5vdCBiZSBpbiB0aGUgZm9ybWF0IFtidWNrZXRfbmFtZV0tLVthemlkXS0teC1zMy4gVXNlIHRoZVxuICAgKiBgYXdzX3MzX2RpcmVjdG9yeV9idWNrZXRgIHJlc291cmNlIHRvIG1hbmFnZSBTMyBFeHByZXNzIGJ1Y2tldHMuXG4gICAqXG4gICAqIEEgZnVsbCBsaXN0IG9mIGJ1Y2tldCBuYW1pbmcgcnVsZXMgW21heSBiZSBmb3VuZCBoZXJlXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uUzMvbGF0ZXN0L3VzZXJndWlkZS9idWNrZXRuYW1pbmdydWxlcy5odG1sKS5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBJZiBvbWl0dGVkLCBSZWZlciB0byBgbmFtZVByZWZpeGAuXG4gICAqL1xuICByZWFkb25seSBidWNrZXROYW1lPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBDcmVhdGVzIGEgdW5pcXVlIG5hbWUgYmVnaW5uaW5nIHdpdGggdGhlIHNwZWNpZmllZCBwcmVmaXguXG4gICAqIENvbmZsaWN0cyB3aXRoIGBidWNrZXROYW1lYC5cbiAgICpcbiAgICogVGVycmFmb3JtIFByZWZpeGVzIG11c3QgcmVzZXJ2ZSAyNiBjaGFyYWN0ZXJzIGZvciB0aGUgdGVycmFmb3JtIGdlbmVyYXRlZCBzdWZmaXguXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gSWYgb21pdHRlZCwgRVQgd2lsbCBhc3NpZ24gYSByYW5kb20sIHVuaXF1ZSBuYW1lIHByZWZpeGVkIGJ5IEdyaWRVVUlELlxuICAgKi9cbiAgcmVhZG9ubHkgbmFtZVByZWZpeD86IHN0cmluZztcblxuICAvKipcbiAgICogQm9vbGVhbiB0aGF0IGluZGljYXRlcyBhbGwgb2JqZWN0cyAoaW5jbHVkaW5nIGFueSBsb2NrZWQgb2JqZWN0cylcbiAgICogc2hvdWxkIGJlIGRlbGV0ZWQgZnJvbSB0aGUgYnVja2V0IHdoZW4gdGhlIGJ1Y2tldCBpcyBkZXN0cm95ZWRcbiAgICogc28gdGhhdCB0aGUgYnVja2V0IGNhbiBiZSBkZXN0cm95ZWQgd2l0aG91dCBlcnJvci5cbiAgICpcbiAgICogVGhlc2Ugb2JqZWN0cyBhcmUgbm90IHJlY292ZXJhYmxlLiBUaGlzIG9ubHkgZGVsZXRlcyBvYmplY3RzIHdoZW5cbiAgICogdGhlIGJ1Y2tldCBpcyBkZXN0cm95ZWQsIG5vdCB3aGVuIHNldHRpbmcgdGhpcyBwYXJhbWV0ZXIgdG8gdHJ1ZS5cbiAgICpcbiAgICogT25jZSB0aGlzIHBhcmFtZXRlciBpcyBzZXQgdG8gdHJ1ZSwgdGhlcmUgbXVzdCBiZSBhIHN1Y2Nlc3NmdWxcbiAgICogdGVycmFmb3JtIGFwcGx5IHJ1biBiZWZvcmUgYSBkZXN0cm95IGlzIHJlcXVpcmVkIHRvIHVwZGF0ZSB0aGlzXG4gICAqIHZhbHVlIGluIHRoZSByZXNvdXJjZSBzdGF0ZS5cbiAgICpcbiAgICogV2l0aG91dCBhIHN1Y2Nlc3NmdWwgdGVycmFmb3JtIGFwcGx5IGFmdGVyIHRoaXMgcGFyYW1ldGVyIGlzIHNldCxcbiAgICogdGhpcyBmbGFnIHdpbGwgaGF2ZSBubyBlZmZlY3QuIElmIHNldHRpbmcgdGhpcyBmaWVsZCBpbiB0aGUgc2FtZVxuICAgKiBvcGVyYXRpb24gdGhhdCB3b3VsZCByZXF1aXJlIHJlcGxhY2luZyB0aGUgYnVja2V0IG9yIGRlc3Ryb3lpbmdcbiAgICogdGhlIGJ1Y2tldCwgdGhpcyBmbGFnIHdpbGwgbm90IHdvcmsuXG4gICAqXG4gICAqIEFkZGl0aW9uYWxseSB3aGVuIGltcG9ydGluZyBhIGJ1Y2tldCwgYSBzdWNjZXNzZnVsIHRlcnJhZm9ybSBhcHBseVxuICAgKiBpcyByZXF1aXJlZCB0byBzZXQgdGhpcyB2YWx1ZSBpbiBzdGF0ZSBiZWZvcmUgaXQgd2lsbCB0YWtlIGVmZmVjdFxuICAgKiBvbiBhIGRlc3Ryb3kgb3BlcmF0aW9uLlxuICAgKlxuICAgKiBAZGVmYXVsdCBmYWxzZVxuICAgKi9cbiAgcmVhZG9ubHkgZm9yY2VEZXN0cm95PzogYm9vbGVhbjtcblxuICAvKipcbiAgICogUHJvdmlkZXMgYW4gUzMgYnVja2V0IHdlYnNpdGUgY29uZmlndXJhdGlvbiByZXNvdXJjZS5cbiAgICpcbiAgICogSW1wb3J0YW50OiBBbWF6b24gUzMgd2Vic2l0ZSBlbmRwb2ludHMgZG8gbm90IHN1cHBvcnQgSFRUUFMgb3IgYWNjZXNzIHBvaW50cy5cbiAgICogSWYgeW91IHdhbnQgdG8gdXNlIEhUVFBTLCB5b3UgY2FuIHVzZSBlZGdlIERpc3RyaWJ1dGlvbiB0byBzZXJ2ZSBhIHN0YXRpY1xuICAgKiB3ZWJzaXRlIGhvc3RlZCBpbiBhIGJ1Y2tldC5cbiAgICpcbiAgICogVXNlIE9yaWdpbkFjY2Vzc0lkZW50aXR5IHByb3BlcnR5IHRvIGNvbnRyb2wgaW5ncmVzcyB0aHJvdWdoIGVkZ2UgRGlzdHJpYnV0aW9uLlxuICAgKlxuICAgKiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgc2VlIFtIb3N0aW5nIFdlYnNpdGVzIG9uIFMzXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uUzMvbGF0ZXN0L2Rldi9XZWJzaXRlSG9zdGluZy5odG1sKS5cbiAgICovXG4gIHJlYWRvbmx5IHdlYnNpdGVDb25maWc/OiBXZWJzaXRlQ29uZmlnO1xuXG4gIC8qKlxuICAgKiBQcm92aWRlcyBhbiBTMyBidWNrZXQgQ09SUyBjb25maWd1cmF0aW9uIHJlc291cmNlLlxuICAgKlxuICAgKiBGb3IgbW9yZSBpbmZvcm1hdGlvbiBhYm91dCBDT1JTLCBnbyB0b1xuICAgKiBbRW5hYmxpbmcgQ3Jvc3MtT3JpZ2luIFJlc291cmNlIFNoYXJpbmddKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BbWF6b25TMy9sYXRlc3QvdXNlcmd1aWRlL2NvcnMuaHRtbClcbiAgICogaW4gdGhlIEFtYXpvbiBTMyBVc2VyIEd1aWRlLlxuICAgKi9cbiAgcmVhZG9ubHkgY29yc0NvbmZpZz86IENvcnNDb25maWc7XG5cbiAgLyoqXG4gICAqIE9uZSBvciBtb3JlIExpZmVjeWNsZSBydWxlcy4gRWFjaCBydWxlIGNvbnNpc3RzIG9mIHRoZSBmb2xsb3dpbmc6XG4gICAqXG4gICAqICAtIFJ1bGUgaWRcbiAgICogIC0gRmlsdGVyIGlkZW50aWZ5aW5nIG9iamVjdHMgdG8gd2hpY2ggdGhlIHJ1bGUgYXBwbGllc1xuICAgKiAgLSBPbmUgb3IgbW9yZSB0cmFuc2l0aW9uIG9yIGV4cGlyYXRpb24gYWN0aW9uc1xuICAgKlxuICAgKiBGb3IgbW9yZSBpbmZvcm1hdGlvbiBzZWUgdGhlIEFtYXpvbiBTMyBVc2VyIEd1aWRlIG9uIFtMaWZlY3ljbGUgQ29uZmlndXJhdGlvbiBFbGVtZW50c10oaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FtYXpvblMzL2xhdGVzdC91c2VyZ3VpZGUvaW50cm8tbGlmZWN5Y2xlLXJ1bGVzLmh0bWwpLlxuICAgKi9cbiAgcmVhZG9ubHkgbGlmZWN5Y2xlUnVsZXM/OiBMaWZlY3ljbGVDb25maWd1cmF0aW9uUnVsZVtdO1xuXG4gIC8qKlxuICAgKiBDb250cm9scyB2ZXJzaW9uaW5nIG9uIHRoZSBTMyBidWNrZXQuXG4gICAqXG4gICAqIFNldHRpbmcgdGhpcyB0byBmYWxzZSB3aWxsIHN1c3BlbmQgdmVyc2lvbmluZyBpZiB0aGUgYXNzb2NpYXRlZCBTMyBidWNrZXQgaXMgdmVyc2lvbmVkLlxuICAgKlxuICAgKiBJZiB5b3UgYXJlIGVuYWJsaW5nIHZlcnNpb25pbmcgb24gdGhlIGJ1Y2tldCBmb3IgdGhlIGZpcnN0IHRpbWUsIEFXUyByZWNvbW1lbmRzIHRoYXQgeW91IHdhaXQgZm9yIDE1IG1pbnV0ZXMgYWZ0ZXIgZW5hYmxpbmcgdmVyc2lvbmluZyBiZWZvcmUgaXNzdWluZyB3cml0ZSBvcGVyYXRpb25zIChQVVQgb3IgREVMRVRFKSBvbiBvYmplY3RzIGluIHRoZSBidWNrZXQuXG4gICAqIFRoaXMgd2lsbCBjYXVzZSAxNW0gZGVsYXkgaWYgYHBhdGhgIGlzIGNvbmZpZ3VyZWQuXG4gICAqXG4gICAqIEBkZWZhdWx0IGZhbHNlXG4gICAqL1xuICByZWFkb25seSB2ZXJzaW9uZWQ/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBXaGV0aGVyIHRoaXMgYnVja2V0IHNob3VsZCBzZW5kIG5vdGlmaWNhdGlvbnMgdG8gQW1hem9uIEV2ZW50QnJpZGdlIG9yIG5vdC5cbiAgICpcbiAgICogQGRlZmF1bHQgZmFsc2VcbiAgICovXG4gIHJlYWRvbmx5IGV2ZW50QnJpZGdlRW5hYmxlZD86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIEVuZm9yY2VzIFNTTCBmb3IgcmVxdWVzdHMuIFMzLjUgb2YgdGhlIEFXUyBGb3VuZGF0aW9uYWwgU2VjdXJpdHkgQmVzdCBQcmFjdGljZXMgUmVnYXJkaW5nIFMzLlxuICAgKiBAc2VlIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9jb25maWcvbGF0ZXN0L2RldmVsb3Blcmd1aWRlL3MzLWJ1Y2tldC1zc2wtcmVxdWVzdHMtb25seS5odG1sXG4gICAqXG4gICAqIEBkZWZhdWx0IGZhbHNlXG4gICAqL1xuICByZWFkb25seSBlbmZvcmNlU1NMPzogYm9vbGVhbjtcblxuICAvKipcbiAgICogRW5mb3JjZXMgbWluaW11bSBUTFMgdmVyc2lvbiBmb3IgcmVxdWVzdHMuXG4gICAqXG4gICAqIFJlcXVpcmVzIGBlbmZvcmNlU1NMYCB0byBiZSBlbmFibGVkLlxuICAgKlxuICAgKiBAc2VlIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BbWF6b25TMy9sYXRlc3QvdXNlcmd1aWRlL2FtYXpvbi1zMy1wb2xpY3kta2V5cy5odG1sI2V4YW1wbGUtb2JqZWN0LXRscy12ZXJzaW9uXG4gICAqXG4gICAqIEBkZWZhdWx0IE5vIG1pbmltdW0gVExTIHZlcnNpb24gaXMgZW5mb3JjZWQuXG4gICAqL1xuICByZWFkb25seSBtaW5pbXVtVExTVmVyc2lvbj86IG51bWJlcjtcblxuICAvKipcbiAgICogRW5hYmxlIENsb3VkZnJvbnQgYWNjZXNzIHZpYSBPcmlnaW4gQWNjZXNzIElkZW50aXR5LlxuICAgKlxuICAgKiBOb3RlOiByZWNvbW1lbmRlZCB0byBtaWdyYXRlIHRvIE9BQyBpbiBmdXR1cmUuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gbm8gY2xvdWRmcm9udCBhY2Nlc3NcbiAgICovXG4gIHJlYWRvbmx5IGNsb3VkZnJvbnRBY2Nlc3M/OiBDbG91ZGZyb250QWNjZXNzQ29uZmlnO1xuXG4gIC8vIFRPRE86IEFkZCBmbGFnIHRvIHJlZ2lzdGVyIEJ1Y2tldCBTb3VyY2Ugb3V0cHV0cz9cbn1cblxuLyoqXG4gKiBPdXRwdXRzIHdoaWNoIG1heSBiZSByZWdpc3RlcmVkIGZvciBvdXRwdXQgdmlhIHRoZSBHcmlkLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEJ1Y2tldE91dHB1dHMge1xuICAvKipcbiAgICogQVdTIEJ1Y2tldCBuYW1lXG4gICAqIEBhdHRyaWJ1dGVcbiAgICovXG4gIHJlYWRvbmx5IG5hbWU6IHN0cmluZztcblxuICAvKipcbiAgICogQVdTIEJ1Y2tldCBhcm5cbiAgICogQGF0dHJpYnV0ZVxuICAgKi9cbiAgcmVhZG9ubHkgYXJuOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSBVUkwgb2YgdGhlIHN0YXRpYyB3ZWJzaXRlLlxuICAgKiBAYXR0cmlidXRlXG4gICAqL1xuICByZWFkb25seSB3ZWJzaXRlVXJsPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaGUgRG9tYWluIG5hbWUgb2YgdGhlIHN0YXRpYyB3ZWJzaXRlLlxuICAgKiBAYXR0cmlidXRlXG4gICAqL1xuICByZWFkb25seSB3ZWJzaXRlRG9tYWluTmFtZT86IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIElQdjQgRE5TIG5hbWUgb2YgdGhlIHNwZWNpZmllZCBidWNrZXQuXG4gICAqIEBhdHRyaWJ1dGVcbiAgICovXG4gIHJlYWRvbmx5IGRvbWFpbk5hbWU6IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIHJlZ2lvbmFsIGRvbWFpbiBuYW1lIG9mIHRoZSBzcGVjaWZpZWQgYnVja2V0LlxuICAgKiBAYXR0cmlidXRlXG4gICAqL1xuICByZWFkb25seSByZWdpb25hbERvbWFpbk5hbWU6IHN0cmluZztcblxuICAvKipcbiAgICogT3JpZ2luIEFjY2VzcyBJZGVudGl0eSwgaWYgY2xvdWRmcm9udEFjY2VzcyBpcyBlbmFibGVkLlxuICAgKiBAYXR0cmlidXRlXG4gICAqL1xuICByZWFkb25seSBvcmlnaW5BY2Nlc3NJZGVudGl0eT86IHN0cmluZztcbn1cblxuLyoqXG4gKiBJbXBvcnRlZCBvciBjcmVhdGVkIEJ1Y2tldCBhdHRyaWJ1dGVzXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgSUJ1Y2tldCBleHRlbmRzIElBd3NDb25zdHJ1Y3Qge1xuICAvKiogU3Ryb25nbHkgdHlwZWQgb3V0cHV0cyAqL1xuICByZWFkb25seSBidWNrZXRPdXRwdXRzOiBCdWNrZXRPdXRwdXRzO1xuXG4gIC8qKlxuICAgKiBBV1MgQnVja2V0IG5hbWVcbiAgICovXG4gIHJlYWRvbmx5IGJ1Y2tldE5hbWU6IHN0cmluZztcbiAgLyoqXG4gICAqIEFXUyBCdWNrZXQgYXJuXG4gICAqL1xuICByZWFkb25seSBidWNrZXRBcm46IHN0cmluZztcblxuICAvKiogV2hldGhlciB0aGUgYnVja2V0IGhhcyB2ZXJzaW9uaW5nIGVuYWJsZWQgKi9cbiAgcmVhZG9ubHkgdmVyc2lvbmVkOiBib29sZWFuO1xuXG4gIC8qKiBUaGUgaG9zdGVkIFpvbmUgSWQgZm9yIHRoZSBidWNrZXQgKi9cbiAgcmVhZG9ubHkgaG9zdGVkWm9uZUlkOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSBEb21haW4gbmFtZSBvZiB0aGUgc3RhdGljIHdlYnNpdGUuXG4gICAqIEBhdHRyaWJ1dGVcbiAgICovXG4gIHJlYWRvbmx5IHdlYnNpdGVEb21haW5OYW1lPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBFbmFibGUgcHVibGljIHJlYWQgYWNjZXNzIGZvciBhbGwgdGhlIGZpbGVzIGluIHRoZSBidWNrZXQuXG4gICAqXG4gICAqIFRoaXMgZXhwbGljaXRseSBkaXNhYmxlcyB0aGUgZGVmYXVsdCBTMyBidWNrZXQgc2VjdXJpdHkgc2V0dGluZ3MuIFRoaXNcbiAgICogc2hvdWxkIGJlIGRvbmUgd2l0aCBjYXV0aW9uLCBhcyBhbGwgYnVja2V0IG9iamVjdHMgYmVjb21lIHB1YmxpY2x5IGV4cG9zZWQuXG4gICAqXG4gICAqIFlvdSBkb24ndCBuZWVkIHRvIGVuYWJsZSB0aGlzIGlmIHlvdSdyZSB1c2luZyBDbG91ZEZyb250IHRvIHNlcnZlIGZpbGVzIGZyb20gdGhlIGJ1Y2tldC5cbiAgICpcbiAgICogQGRlZmF1bHQgYGZhbHNlYFxuICAgKi9cbiAgcHVibGljPzogYm9vbGVhbjtcblxuICAvKipcbiAgICogVGhlIHJlc291cmNlIHBvbGljeSBhc3NvY2lhdGVkIHdpdGggdGhpcyBidWNrZXQuXG4gICAqXG4gICAqIElmIGBhdXRvQ3JlYXRlUG9saWN5YCBpcyB0cnVlLCBhIGBCdWNrZXRQb2xpY3lgIHdpbGwgYmUgY3JlYXRlZCB1cG9uIHRoZVxuICAgKiBmaXJzdCBjYWxsIHRvIGFkZFRvUmVzb3VyY2VQb2xpY3kocykuXG4gICAqL1xuICBwb2xpY3k/OiBCdWNrZXRQb2xpY3k7XG5cbiAgLyoqXG4gICAqIEFkZCBhIHNvdXJjZSBvZiBmaWxlcyBmb3IgdXBsb2FkIHRvIHRoZSBidWNrZXQuXG4gICAqL1xuICBhZGRTb3VyY2UocHJvcHM6IEFkZFNvdXJjZU9wdGlvbnMsIHNvdXJjZUlkPzogc3RyaW5nKTogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBJZiB0aGlzIGJ1Y2tldCBoYXMgYmVlbiBjb25maWd1cmVkIGZvciBzdGF0aWMgd2Vic2l0ZSBob3N0aW5nLlxuICAgKi9cbiAgaXNXZWJzaXRlKCk6IHRoaXMgaXMge1xuICAgIHdlYnNpdGVEb21haW5OYW1lOiBzdHJpbmc7XG4gICAgYnVja2V0T3V0cHV0czogeyB3ZWJzaXRlVXJsOiBzdHJpbmc7IHdlYnNpdGVEb21haW5OYW1lOiBzdHJpbmcgfTtcbiAgfTtcblxuICAvKipcbiAgICogVGhlIGh0dHBzIFVSTCBvZiBhbiBTMyBvYmplY3QuIEZvciBleGFtcGxlOlxuICAgKlxuICAgKiAtIGBodHRwczovL3MzLnVzLXdlc3QtMS5hbWF6b25hd3MuY29tL29ubHlidWNrZXRgXG4gICAqIC0gYGh0dHBzOi8vczMudXMtd2VzdC0xLmFtYXpvbmF3cy5jb20vYnVja2V0L2tleWBcbiAgICogLSBgaHR0cHM6Ly9zMy5jbi1ub3J0aC0xLmFtYXpvbmF3cy5jb20uY24vY2hpbmEtYnVja2V0L215a2V5YFxuICAgKiBAcGFyYW0ga2V5IFRoZSBTMyBrZXkgb2YgdGhlIG9iamVjdC4gSWYgbm90IHNwZWNpZmllZCwgdGhlIFVSTCBvZiB0aGVcbiAgICogICAgICBidWNrZXQgaXMgcmV0dXJuZWQuXG4gICAqIEByZXR1cm5zIGFuIE9iamVjdFMzVXJsIHRva2VuXG4gICAqL1xuICB1cmxGb3JPYmplY3Qoa2V5Pzogc3RyaW5nKTogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaGUgUzMgVVJMIG9mIGFuIFMzIG9iamVjdC4gRm9yIGV4YW1wbGU6XG4gICAqIC0gYHMzOi8vb25seWJ1Y2tldGBcbiAgICogLSBgczM6Ly9idWNrZXQva2V5YFxuICAgKiBAcGFyYW0ga2V5IFRoZSBTMyBrZXkgb2YgdGhlIG9iamVjdC4gSWYgbm90IHNwZWNpZmllZCwgdGhlIFMzIFVSTCBvZiB0aGVcbiAgICogICAgICBidWNrZXQgaXMgcmV0dXJuZWQuXG4gICAqIEByZXR1cm5zIGFuIE9iamVjdFMzVXJsIHRva2VuXG4gICAqL1xuICBzM1VybEZvck9iamVjdChrZXk/OiBzdHJpbmcpOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFJldHVybnMgYW4gQVJOIHRoYXQgcmVwcmVzZW50cyBhbGwgb2JqZWN0cyB3aXRoaW4gdGhlIGJ1Y2tldCB0aGF0IG1hdGNoXG4gICAqIHRoZSBrZXkgcGF0dGVybiBzcGVjaWZpZWQuIFRvIHJlcHJlc2VudCBhbGwga2V5cywgc3BlY2lmeSBgYFwiKlwiYGAuXG4gICAqL1xuICBhcm5Gb3JPYmplY3RzKGtleVBhdHRlcm46IHN0cmluZyk6IHN0cmluZztcblxuICAvKipcbiAgICogQWRkcyBhIHN0YXRlbWVudCB0byB0aGUgcmVzb3VyY2UgcG9saWN5IGZvciBhIHByaW5jaXBhbCAoaS5lLlxuICAgKiBhY2NvdW50L3JvbGUvc2VydmljZSkgdG8gcGVyZm9ybSBhY3Rpb25zIG9uIHRoaXMgYnVja2V0IGFuZC9vciBpdHNcbiAgICogY29udGVudHMuIFVzZSBgYnVja2V0QXJuYCBhbmQgYGFybkZvck9iamVjdHMoa2V5cylgIHRvIG9idGFpbiBBUk5zIGZvclxuICAgKiB0aGlzIGJ1Y2tldCBvciBvYmplY3RzLlxuICAgKlxuICAgKiBOb3RlIHRoYXQgdGhlIHBvbGljeSBzdGF0ZW1lbnQgbWF5IG9yIG1heSBub3QgYmUgYWRkZWQgdG8gdGhlIHBvbGljeS5cbiAgICogRm9yIGV4YW1wbGUsIHdoZW4gYW4gYElCdWNrZXRgIGlzIGNyZWF0ZWQgZnJvbSBhbiBleGlzdGluZyBidWNrZXQsXG4gICAqIGl0J3Mgbm90IHBvc3NpYmxlIHRvIHRlbGwgd2hldGhlciB0aGUgYnVja2V0IGFscmVhZHkgaGFzIGEgcG9saWN5XG4gICAqIGF0dGFjaGVkLCBsZXQgYWxvbmUgdG8gcmUtdXNlIHRoYXQgcG9saWN5IHRvIGFkZCBtb3JlIHN0YXRlbWVudHMgdG8gaXQuXG4gICAqIFNvIGl0J3Mgc2FmZXN0IHRvIGRvIG5vdGhpbmcgaW4gdGhlc2UgY2FzZXMuXG4gICAqXG4gICAqIEBwYXJhbSBwZXJtaXNzaW9uIHRoZSBwb2xpY3kgc3RhdGVtZW50IHRvIGJlIGFkZGVkIHRvIHRoZSBidWNrZXQnc1xuICAgKiBwb2xpY3kuXG4gICAqIEByZXR1cm5zIG1ldGFkYXRhIGFib3V0IHRoZSBleGVjdXRpb24gb2YgdGhpcyBtZXRob2QuIElmIHRoZSBwb2xpY3lcbiAgICogd2FzIG5vdCBhZGRlZCwgdGhlIHZhbHVlIG9mIGBzdGF0ZW1lbnRBZGRlZGAgd2lsbCBiZSBgZmFsc2VgLiBZb3VcbiAgICogc2hvdWxkIGFsd2F5cyBjaGVjayB0aGlzIHZhbHVlIHRvIG1ha2Ugc3VyZSB0aGF0IHRoZSBvcGVyYXRpb24gd2FzXG4gICAqIGFjdHVhbGx5IGNhcnJpZWQgb3V0LiBPdGhlcndpc2UsIHN5bnRoZXNpcyBhbmQgZGVwbG95IHdpbGwgdGVybWluYXRlXG4gICAqIHNpbGVudGx5LCB3aGljaCBtYXkgYmUgY29uZnVzaW5nLlxuICAgKi9cbiAgYWRkVG9SZXNvdXJjZVBvbGljeShcbiAgICBwZXJtaXNzaW9uOiBpYW0uUG9saWN5U3RhdGVtZW50LFxuICApOiBpYW0uQWRkVG9SZXNvdXJjZVBvbGljeVJlc3VsdDtcblxuICAvKipcbiAgICogR3JhbnQgcmVhZCBwZXJtaXNzaW9ucyBmb3IgdGhpcyBidWNrZXQgYW5kIGl0J3MgY29udGVudHMgdG8gYW4gSUFNXG4gICAqIHByaW5jaXBhbCAoUm9sZS9Hcm91cC9Vc2VyKS5cbiAgICpcbiAgICogSWYgZW5jcnlwdGlvbiBpcyB1c2VkLCBwZXJtaXNzaW9uIHRvIHVzZSB0aGUga2V5IHRvIGRlY3J5cHQgdGhlIGNvbnRlbnRzXG4gICAqIG9mIHRoZSBidWNrZXQgd2lsbCBhbHNvIGJlIGdyYW50ZWQgdG8gdGhlIHNhbWUgcHJpbmNpcGFsLlxuICAgKlxuICAgKiBAcGFyYW0gaWRlbnRpdHkgVGhlIHByaW5jaXBhbFxuICAgKiBAcGFyYW0gb2JqZWN0c0tleVBhdHRlcm4gUmVzdHJpY3QgdGhlIHBlcm1pc3Npb24gdG8gYSBjZXJ0YWluIGtleSBwYXR0ZXJuIChkZWZhdWx0ICcqJykuIFBhcmFtZXRlciB0eXBlIGlzIGBhbnlgIGJ1dCBgc3RyaW5nYCBzaG91bGQgYmUgcGFzc2VkIGluLlxuICAgKi9cbiAgZ3JhbnRSZWFkKGlkZW50aXR5OiBpYW0uSUdyYW50YWJsZSwgb2JqZWN0c0tleVBhdHRlcm4/OiBhbnkpOiBpYW0uR3JhbnQ7XG5cbiAgLyoqXG4gICAqIEdyYW50IHdyaXRlIHBlcm1pc3Npb25zIHRvIHRoaXMgYnVja2V0IHRvIGFuIElBTSBwcmluY2lwYWwuXG4gICAqXG4gICAqIElmIGVuY3J5cHRpb24gaXMgdXNlZCwgcGVybWlzc2lvbiB0byB1c2UgdGhlIGtleSB0byBlbmNyeXB0IHRoZSBjb250ZW50c1xuICAgKiBvZiB3cml0dGVuIGZpbGVzIHdpbGwgYWxzbyBiZSBncmFudGVkIHRvIHRoZSBzYW1lIHByaW5jaXBhbC5cbiAgICpcbiAgICogVGhpcyBkb2VzIG5vdCBpbmNsdWRlIGBzMzpQdXRPYmplY3RBY2xgLCB3aGljaCBjb3VsZCBiZSB1c2VkIHRvIGdyYW50IHJlYWQvd3JpdGUgb2JqZWN0IGFjY2VzcyB0byBJQU0gcHJpbmNpcGFscyBpbiBvdGhlciBhY2NvdW50cy5cbiAgICpcbiAgICogSWYgeW91IG5lZWQgdGhlIHByaW5jaXBhbCB0byBoYXZlIHBlcm1pc3Npb25zIHRvIG1vZGlmeSB0aGUgQUNMcyxcbiAgICogdXNlIHRoZSBgZ3JhbnRQdXRBY2xgIG1ldGhvZC5cbiAgICpcbiAgICogQHBhcmFtIGlkZW50aXR5IFRoZSBwcmluY2lwYWxcbiAgICogQHBhcmFtIG9iamVjdHNLZXlQYXR0ZXJuIFJlc3RyaWN0IHRoZSBwZXJtaXNzaW9uIHRvIGEgY2VydGFpbiBrZXkgcGF0dGVybiAoZGVmYXVsdCAnKicpLiBQYXJhbWV0ZXIgdHlwZSBpcyBgYW55YCBidXQgYHN0cmluZ2Agc2hvdWxkIGJlIHBhc3NlZCBpbi5cbiAgICogQHBhcmFtIGFsbG93ZWRBY3Rpb25QYXR0ZXJucyBSZXN0cmljdCB0aGUgcGVybWlzc2lvbnMgdG8gY2VydGFpbiBsaXN0IG9mIGFjdGlvbiBwYXR0ZXJuc1xuICAgKi9cbiAgZ3JhbnRXcml0ZShcbiAgICBpZGVudGl0eTogaWFtLklHcmFudGFibGUsXG4gICAgb2JqZWN0c0tleVBhdHRlcm4/OiBhbnksXG4gICAgYWxsb3dlZEFjdGlvblBhdHRlcm5zPzogc3RyaW5nW10sXG4gICk6IGlhbS5HcmFudDtcblxuICAvKipcbiAgICogR3JhbnRzIHMzOlB1dE9iamVjdCogYW5kIHMzOkFib3J0KiBwZXJtaXNzaW9ucyBmb3IgdGhpcyBidWNrZXQgdG8gYW4gSUFNIHByaW5jaXBhbC5cbiAgICpcbiAgICogSWYgZW5jcnlwdGlvbiBpcyB1c2VkLCBwZXJtaXNzaW9uIHRvIHVzZSB0aGUga2V5IHRvIGVuY3J5cHQgdGhlIGNvbnRlbnRzXG4gICAqIG9mIHdyaXR0ZW4gZmlsZXMgd2lsbCBhbHNvIGJlIGdyYW50ZWQgdG8gdGhlIHNhbWUgcHJpbmNpcGFsLlxuICAgKiBAcGFyYW0gaWRlbnRpdHkgVGhlIHByaW5jaXBhbFxuICAgKiBAcGFyYW0gb2JqZWN0c0tleVBhdHRlcm4gUmVzdHJpY3QgdGhlIHBlcm1pc3Npb24gdG8gYSBjZXJ0YWluIGtleSBwYXR0ZXJuIChkZWZhdWx0ICcqJykuIFBhcmFtZXRlciB0eXBlIGlzIGBhbnlgIGJ1dCBgc3RyaW5nYCBzaG91bGQgYmUgcGFzc2VkIGluLlxuICAgKi9cbiAgZ3JhbnRQdXQoaWRlbnRpdHk6IGlhbS5JR3JhbnRhYmxlLCBvYmplY3RzS2V5UGF0dGVybj86IGFueSk6IGlhbS5HcmFudDtcblxuICAvKipcbiAgICogR3JhbnQgdGhlIGdpdmVuIElBTSBpZGVudGl0eSBwZXJtaXNzaW9ucyB0byBtb2RpZnkgdGhlIEFDTHMgb2Ygb2JqZWN0cyBpbiB0aGUgZ2l2ZW4gQnVja2V0LlxuICAgKlxuICAgKiBjYWxsaW5nIGBncmFudFdyaXRlYCBvciBgZ3JhbnRSZWFkV3JpdGVgIGRvZXMgbm90IGdyYW50IHBlcm1pc3Npb25zIHRvIG1vZGlmeSB0aGUgQUNMcyBvZiB0aGUgb2JqZWN0cztcbiAgICogaW4gdGhpcyBjYXNlLCBpZiB5b3UgbmVlZCB0byBtb2RpZnkgb2JqZWN0IEFDTHMsIGNhbGwgdGhpcyBtZXRob2QgZXhwbGljaXRseS5cbiAgICpcbiAgICogQHBhcmFtIGlkZW50aXR5IFRoZSBwcmluY2lwYWxcbiAgICogQHBhcmFtIG9iamVjdHNLZXlQYXR0ZXJuIFJlc3RyaWN0IHRoZSBwZXJtaXNzaW9uIHRvIGEgY2VydGFpbiBrZXkgcGF0dGVybiAoZGVmYXVsdCAnKicpXG4gICAqL1xuICBncmFudFB1dEFjbChpZGVudGl0eTogaWFtLklHcmFudGFibGUsIG9iamVjdHNLZXlQYXR0ZXJuPzogc3RyaW5nKTogaWFtLkdyYW50O1xuXG4gIC8qKlxuICAgKiBHcmFudHMgczM6RGVsZXRlT2JqZWN0KiBwZXJtaXNzaW9uIHRvIGFuIElBTSBwcmluY2lwYWwgZm9yIG9iamVjdHNcbiAgICogaW4gdGhpcyBidWNrZXQuXG4gICAqXG4gICAqIEBwYXJhbSBpZGVudGl0eSBUaGUgcHJpbmNpcGFsXG4gICAqIEBwYXJhbSBvYmplY3RzS2V5UGF0dGVybiBSZXN0cmljdCB0aGUgcGVybWlzc2lvbiB0byBhIGNlcnRhaW4ga2V5IHBhdHRlcm4gKGRlZmF1bHQgJyonKS4gUGFyYW1ldGVyIHR5cGUgaXMgYGFueWAgYnV0IGBzdHJpbmdgIHNob3VsZCBiZSBwYXNzZWQgaW4uXG4gICAqL1xuICBncmFudERlbGV0ZShpZGVudGl0eTogaWFtLklHcmFudGFibGUsIG9iamVjdHNLZXlQYXR0ZXJuPzogYW55KTogaWFtLkdyYW50O1xuXG4gIC8qKlxuICAgKiBHcmFudHMgcmVhZC93cml0ZSBwZXJtaXNzaW9ucyBmb3IgdGhpcyBidWNrZXQgYW5kIGl0J3MgY29udGVudHMgdG8gYW4gSUFNXG4gICAqIHByaW5jaXBhbCAoUm9sZS9Hcm91cC9Vc2VyKS5cbiAgICpcbiAgICogSWYgYW4gZW5jcnlwdGlvbiBrZXkgaXMgdXNlZCwgcGVybWlzc2lvbiB0byB1c2UgdGhlIGtleSBmb3JcbiAgICogZW5jcnlwdC9kZWNyeXB0IHdpbGwgYWxzbyBiZSBncmFudGVkLlxuICAgKlxuICAgKiBUaGlzIGRvZXMgbm90IGluY2x1ZGUgYHMzOlB1dE9iamVjdEFjbGAsIHdoaWNoIGNvdWxkIGJlIHVzZWQgdG8gZ3JhbnQgcmVhZC93cml0ZSBvYmplY3QgYWNjZXNzIHRvIElBTSBwcmluY2lwYWxzIGluIG90aGVyIGFjY291bnRzLlxuICAgKlxuICAgKiBJZiB5b3UgbmVlZCB0aGUgcHJpbmNpcGFsIHRvIGhhdmUgcGVybWlzc2lvbnMgdG8gbW9kaWZ5IHRoZSBBQ0xzLFxuICAgKiB1c2UgdGhlIGBncmFudFB1dEFjbGAgbWV0aG9kLlxuICAgKlxuICAgKiBAcGFyYW0gaWRlbnRpdHkgVGhlIHByaW5jaXBhbFxuICAgKiBAcGFyYW0gb2JqZWN0c0tleVBhdHRlcm4gUmVzdHJpY3QgdGhlIHBlcm1pc3Npb24gdG8gYSBjZXJ0YWluIGtleSBwYXR0ZXJuIChkZWZhdWx0ICcqJykuIFBhcmFtZXRlciB0eXBlIGlzIGBhbnlgIGJ1dCBgc3RyaW5nYCBzaG91bGQgYmUgcGFzc2VkIGluLlxuICAgKi9cbiAgZ3JhbnRSZWFkV3JpdGUoaWRlbnRpdHk6IGlhbS5JR3JhbnRhYmxlLCBvYmplY3RzS2V5UGF0dGVybj86IGFueSk6IGlhbS5HcmFudDtcblxuICAvLyAvKipcbiAgLy8gICogQWxsb3dzIHVucmVzdHJpY3RlZCBhY2Nlc3MgdG8gb2JqZWN0cyBmcm9tIHRoaXMgYnVja2V0LlxuICAvLyAgKlxuICAvLyAgKiBJTVBPUlRBTlQ6IFRoaXMgcGVybWlzc2lvbiBhbGxvd3MgYW55b25lIHRvIHBlcmZvcm0gYWN0aW9ucyBvbiBTMyBvYmplY3RzXG4gIC8vICAqIGluIHRoaXMgYnVja2V0LCB3aGljaCBpcyB1c2VmdWwgZm9yIHdoZW4geW91IGNvbmZpZ3VyZSB5b3VyIGJ1Y2tldCBhcyBhXG4gIC8vICAqIHdlYnNpdGUgYW5kIHdhbnQgZXZlcnlvbmUgdG8gYmUgYWJsZSB0byByZWFkIG9iamVjdHMgaW4gdGhlIGJ1Y2tldCB3aXRob3V0XG4gIC8vICAqIG5lZWRpbmcgdG8gYXV0aGVudGljYXRlLlxuICAvLyAgKlxuICAvLyAgKiBXaXRob3V0IGFyZ3VtZW50cywgdGhpcyBtZXRob2Qgd2lsbCBncmFudCByZWFkIChcInMzOkdldE9iamVjdFwiKSBhY2Nlc3MgdG9cbiAgLy8gICogYWxsIG9iamVjdHMgKFwiKlwiKSBpbiB0aGUgYnVja2V0LlxuICAvLyAgKlxuICAvLyAgKiBUaGUgbWV0aG9kIHJldHVybnMgdGhlIGBpYW0uR3JhbnRgIG9iamVjdCwgd2hpY2ggY2FuIHRoZW4gYmUgbW9kaWZpZWRcbiAgLy8gICogYXMgbmVlZGVkLiBGb3IgZXhhbXBsZSwgeW91IGNhbiBhZGQgYSBjb25kaXRpb24gdGhhdCB3aWxsIHJlc3RyaWN0IGFjY2VzcyBvbmx5XG4gIC8vICAqIHRvIGFuIElQdjQgcmFuZ2UgbGlrZSB0aGlzOlxuICAvLyAgKlxuICAvLyAgKiAgICAgY29uc3QgZ3JhbnQgPSBidWNrZXQuZ3JhbnRQdWJsaWNBY2Nlc3MoKTtcbiAgLy8gICogICAgIGdyYW50LnJlc291cmNlU3RhdGVtZW50IS5hZGRDb25kaXRpb24o4oCYSXBBZGRyZXNz4oCZLCB7IOKAnGF3czpTb3VyY2VJcOKAnTog4oCcNTQuMjQwLjE0My4wLzI04oCdIH0pO1xuICAvLyAgKlxuICAvLyAgKlxuICAvLyAgKiBAcGFyYW0ga2V5UHJlZml4IHRoZSBwcmVmaXggb2YgUzMgb2JqZWN0IGtleXMgKGUuZy4gYGhvbWUvKmApLiBEZWZhdWx0IGlzIFwiKlwiLlxuICAvLyAgKiBAcGFyYW0gYWxsb3dlZEFjdGlvbnMgdGhlIHNldCBvZiBTMyBhY3Rpb25zIHRvIGFsbG93LiBEZWZhdWx0IGlzIFwiczM6R2V0T2JqZWN0XCIuXG4gIC8vICAqIEByZXR1cm5zIFRoZSBgaWFtLlBvbGljeVN0YXRlbWVudGAgb2JqZWN0LCB3aGljaCBjYW4gYmUgdXNlZCB0byBhcHBseSBlLmcuIGNvbmRpdGlvbnMuXG4gIC8vICAqL1xuICAvLyBncmFudFB1YmxpY0FjY2VzcyhrZXlQcmVmaXg/OiBzdHJpbmcsIC4uLmFsbG93ZWRBY3Rpb25zOiBzdHJpbmdbXSk6IGlhbS5HcmFudDtcblxuICAvKipcbiAgICogQWRkcyBhIGJ1Y2tldCBub3RpZmljYXRpb24gZXZlbnQgZGVzdGluYXRpb24uXG4gICAqIEBwYXJhbSBldmVudCBUaGUgZXZlbnQgdG8gdHJpZ2dlciB0aGUgbm90aWZpY2F0aW9uXG4gICAqIEBwYXJhbSBkZXN0IFRoZSBub3RpZmljYXRpb24gZGVzdGluYXRpb24gKExhbWJkYSwgU05TIFRvcGljIG9yIFNRUyBRdWV1ZSlcbiAgICpcbiAgICogQHBhcmFtIGZpbHRlcnMgUzMgb2JqZWN0IGtleSBmaWx0ZXIgcnVsZXMgdG8gZGV0ZXJtaW5lIHdoaWNoIG9iamVjdHNcbiAgICogdHJpZ2dlciB0aGlzIGV2ZW50LiBFYWNoIGZpbHRlciBtdXN0IGluY2x1ZGUgYSBgcHJlZml4YCBhbmQvb3IgYHN1ZmZpeGBcbiAgICogdGhhdCB3aWxsIGJlIG1hdGNoZWQgYWdhaW5zdCB0aGUgczMgb2JqZWN0IGtleS4gUmVmZXIgdG8gdGhlIFMzIERldmVsb3BlciBHdWlkZVxuICAgKiBmb3IgZGV0YWlscyBhYm91dCBhbGxvd2VkIGZpbHRlciBydWxlcy5cbiAgICpcbiAgICogQHNlZSBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uUzMvbGF0ZXN0L2Rldi9Ob3RpZmljYXRpb25Ib3dUby5odG1sI25vdGlmaWNhdGlvbi1ob3ctdG8tZmlsdGVyaW5nXG4gICAqXG4gICAqIEBleGFtcGxlXG4gICAqXG4gICAqICAgIGRlY2xhcmUgY29uc3QgbXlMYW1iZGE6IGxhbWJkYS5GdW5jdGlvbjtcbiAgICogICAgY29uc3QgYnVja2V0ID0gbmV3IHMzLkJ1Y2tldCh0aGlzLCAnTXlCdWNrZXQnKTtcbiAgICogICAgYnVja2V0LmFkZEV2ZW50Tm90aWZpY2F0aW9uKHMzLkV2ZW50VHlwZS5PQkpFQ1RfQ1JFQVRFRCwgbmV3IHMzbi5MYW1iZGFEZXN0aW5hdGlvbihteUxhbWJkYSksIHtwcmVmaXg6ICdob21lL215dXNlcm5hbWUvKid9KVxuICAgKlxuICAgKiBAc2VlXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BbWF6b25TMy9sYXRlc3QvZGV2L05vdGlmaWNhdGlvbkhvd1RvLmh0bWxcbiAgICovXG4gIGFkZEV2ZW50Tm90aWZpY2F0aW9uKFxuICAgIGV2ZW50OiBFdmVudFR5cGUsXG4gICAgZGVzdDogSUJ1Y2tldE5vdGlmaWNhdGlvbkRlc3RpbmF0aW9uLFxuICAgIC4uLmZpbHRlcnM6IE5vdGlmaWNhdGlvbktleUZpbHRlcltdXG4gICk6IHZvaWQ7XG5cbiAgLyoqXG4gICAqIFN1YnNjcmliZXMgYSBkZXN0aW5hdGlvbiB0byByZWNlaXZlIG5vdGlmaWNhdGlvbnMgd2hlbiBhbiBvYmplY3QgaXNcbiAgICogY3JlYXRlZCBpbiB0aGUgYnVja2V0LiBUaGlzIGlzIGlkZW50aWNhbCB0byBjYWxsaW5nXG4gICAqIGBvbkV2ZW50KHMzLkV2ZW50VHlwZS5PQkpFQ1RfQ1JFQVRFRClgLlxuICAgKlxuICAgKiBAcGFyYW0gZGVzdCBUaGUgbm90aWZpY2F0aW9uIGRlc3RpbmF0aW9uIChzZWUgb25FdmVudClcbiAgICogQHBhcmFtIGZpbHRlcnMgRmlsdGVycyAoc2VlIG9uRXZlbnQpXG4gICAqL1xuICBhZGRPYmplY3RDcmVhdGVkTm90aWZpY2F0aW9uKFxuICAgIGRlc3Q6IElCdWNrZXROb3RpZmljYXRpb25EZXN0aW5hdGlvbixcbiAgICAuLi5maWx0ZXJzOiBOb3RpZmljYXRpb25LZXlGaWx0ZXJbXVxuICApOiB2b2lkO1xuXG4gIC8qKlxuICAgKiBTdWJzY3JpYmVzIGEgZGVzdGluYXRpb24gdG8gcmVjZWl2ZSBub3RpZmljYXRpb25zIHdoZW4gYW4gb2JqZWN0IGlzXG4gICAqIHJlbW92ZWQgZnJvbSB0aGUgYnVja2V0LiBUaGlzIGlzIGlkZW50aWNhbCB0byBjYWxsaW5nXG4gICAqIGBvbkV2ZW50KEV2ZW50VHlwZS5PQkpFQ1RfUkVNT1ZFRClgLlxuICAgKlxuICAgKiBAcGFyYW0gZGVzdCBUaGUgbm90aWZpY2F0aW9uIGRlc3RpbmF0aW9uIChzZWUgb25FdmVudClcbiAgICogQHBhcmFtIGZpbHRlcnMgRmlsdGVycyAoc2VlIG9uRXZlbnQpXG4gICAqL1xuICBhZGRPYmplY3RSZW1vdmVkTm90aWZpY2F0aW9uKFxuICAgIGRlc3Q6IElCdWNrZXROb3RpZmljYXRpb25EZXN0aW5hdGlvbixcbiAgICAuLi5maWx0ZXJzOiBOb3RpZmljYXRpb25LZXlGaWx0ZXJbXVxuICApOiB2b2lkO1xuXG4gIC8qKlxuICAgKiBFbmFibGVzIGV2ZW50IGJyaWRnZSBub3RpZmljYXRpb24sIGNhdXNpbmcgYWxsIGV2ZW50cyBiZWxvdyB0byBiZSBzZW50IHRvIEV2ZW50QnJpZGdlOlxuICAgKlxuICAgKiAtIE9iamVjdCBEZWxldGVkIChEZWxldGVPYmplY3QpXG4gICAqIC0gT2JqZWN0IERlbGV0ZWQgKExpZmVjeWNsZSBleHBpcmF0aW9uKVxuICAgKiAtIE9iamVjdCBSZXN0b3JlIEluaXRpYXRlZFxuICAgKiAtIE9iamVjdCBSZXN0b3JlIENvbXBsZXRlZFxuICAgKiAtIE9iamVjdCBSZXN0b3JlIEV4cGlyZWRcbiAgICogLSBPYmplY3QgU3RvcmFnZSBDbGFzcyBDaGFuZ2VkXG4gICAqIC0gT2JqZWN0IEFjY2VzcyBUaWVyIENoYW5nZWRcbiAgICogLSBPYmplY3QgQUNMIFVwZGF0ZWRcbiAgICogLSBPYmplY3QgVGFncyBBZGRlZFxuICAgKiAtIE9iamVjdCBUYWdzIERlbGV0ZWRcbiAgICovXG4gIGVuYWJsZUV2ZW50QnJpZGdlTm90aWZpY2F0aW9uKCk6IHZvaWQ7XG59XG5cbi8qKlxuICogVGhlIGBCdWNrZXRgIGJlYWNvbiBwcm92aWRlcyBhbiBbQVdTIFMzIEJ1Y2tldF0oaHR0cHM6Ly9hd3MuYW1hem9uLmNvbS9zMy8pLlxuICpcbiAqIGBgYHRzXG4gKiBuZXcgc3RvcmFnZS5CdWNrZXQoc3RhY2ssIFwiTXlXZWJzaXRlXCIsIHtcbiAqICAgcGF0aDogcGF0aC5qb2luKF9fZGlybmFtZSwgXCJkaXN0XCIpLFxuICogfSk7XG4gKiBgYGBcbiAqXG4gKiAjIyMjIFB1YmxpYyByZWFkIGFjY2Vzc1xuICpcbiAqIEVuYWJsZXMgYHB1YmxpY2AgcmVhZCBhY2Nlc3MgZm9yIGFsbCB0aGUgZmlsZXMgaW4gdGhlIGJ1Y2tldC4gRGFuZ2Vyb3VzIGFuZFxuICogcmVjb21tZW5kZWQgdG8gdXNlIGVkZ2UuRGlzdHJpYnV0aW9uIGluc3RlYWQuXG4gKlxuICogVXNlZnVsIGZvciBob3N0aW5nIHB1YmxpYyBmaWxlcyBkaXJlY3RseSBmcm9tIFMzLlxuICpcbiAqIGBgYHRzXG4gKiBuZXcgc3RvcmFnZS5CdWNrZXQoXCJNeUJ1Y2tldFwiLCB7XG4gKiAgIHB1YmxpYzogdHJ1ZVxuICogfSk7XG4gKiBgYGBcbiAqXG4gKiBAcmVzb3VyY2UgYXdzX3MzX2J1Y2tldFxuICogQHRlcnJhY29uc3RydWN0IHN0b3JhZ2UuSUJ1Y2tldFxuICovXG5cbmV4cG9ydCBjbGFzcyBCdWNrZXQgZXh0ZW5kcyBBd3NDb25zdHJ1Y3RCYXNlIGltcGxlbWVudHMgSUJ1Y2tldCB7XG4gIC8vIFRPRE86IEFkZCBzdGF0aWMgZnJvbUxvb2t1cD9cbiAgcHJvdGVjdGVkIHJlYWRvbmx5IHJlc291cmNlOiBzM0J1Y2tldC5TM0J1Y2tldDtcbiAgcHJvdGVjdGVkIHJlYWRvbmx5IHdlYnNpdGVDb25maWc/OiBzM0J1Y2tldFdlYnNpdGVDb25maWd1cmF0aW9uLlMzQnVja2V0V2Vic2l0ZUNvbmZpZ3VyYXRpb247XG4gIHByb3RlY3RlZCByZWFkb25seSBjb3JzQ29uZmlnPzogczNCdWNrZXRDb3JzQ29uZmlndXJhdGlvbi5TM0J1Y2tldENvcnNDb25maWd1cmF0aW9uO1xuXG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgcHJpdmF0ZSByZWFkb25seSBzb3VyY2VzOiBTb3VyY2VJbmRleFtdID0gW107XG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgcHJpdmF0ZSByZWFkb25seSBfdmVyc2lvbmVkOiBib29sZWFuO1xuICBwdWJsaWMgZ2V0IHZlcnNpb25lZCgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5fdmVyc2lvbmVkO1xuICB9XG5cbiAgLyoqIEBpbnRlcm5hbCAqL1xuICBwcml2YXRlIHJlYWRvbmx5IF9pc1dlYnNpdGU6IGJvb2xlYW47XG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgcHJpdmF0ZSBzb3VyY2VTbGVlcD86IHNsZWVwLlNsZWVwO1xuXG4gIC8qKiBAaW50ZXJuYWwgKi9cbiAgcHJpdmF0ZSByZWFkb25seSBfb3V0cHV0czogQnVja2V0T3V0cHV0cztcbiAgcHVibGljIGdldCBidWNrZXRPdXRwdXRzKCk6IEJ1Y2tldE91dHB1dHMge1xuICAgIHJldHVybiB0aGlzLl9vdXRwdXRzO1xuICB9XG4gIHB1YmxpYyBnZXQgb3V0cHV0cygpOiBSZWNvcmQ8c3RyaW5nLCBhbnk+IHtcbiAgICByZXR1cm4gdGhpcy5idWNrZXRPdXRwdXRzO1xuICB9XG5cbiAgcHVibGljIGdldCBidWNrZXROYW1lKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMucmVzb3VyY2UuYnVja2V0O1xuICB9XG4gIHB1YmxpYyBnZXQgYnVja2V0QXJuKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMucmVzb3VyY2UuYXJuO1xuICB9XG4gIHB1YmxpYyBnZXQgaG9zdGVkWm9uZUlkKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMucmVzb3VyY2UuaG9zdGVkWm9uZUlkO1xuICB9XG4gIHB1YmxpYyBnZXQgd2Vic2l0ZURvbWFpbk5hbWUoKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgICByZXR1cm4gdGhpcy53ZWJzaXRlQ29uZmlnPy53ZWJzaXRlRG9tYWluO1xuICB9XG5cbiAgcHVibGljIHBvbGljeT86IEJ1Y2tldFBvbGljeTtcblxuICAvKipcbiAgICogV2hldGhlciB0aGUgYnVja2V0IGlzIHB1YmxpYyBvciBub3QuXG4gICAqL1xuICBwdWJsaWMgcHVibGljPzogYm9vbGVhbjtcbiAgcHJpdmF0ZSBub3RpZmljYXRpb25zPzogQnVja2V0Tm90aWZpY2F0aW9ucztcbiAgcHJpdmF0ZSByZWFkb25seSBldmVudEJyaWRnZUVuYWJsZWQ/OiBib29sZWFuO1xuXG4gIGNvbnN0cnVjdG9yKHNjb3BlOiBDb25zdHJ1Y3QsIG5hbWU6IHN0cmluZywgcHJvcHM6IEJ1Y2tldFByb3BzID0ge30pIHtcbiAgICBzdXBlcihzY29wZSwgbmFtZSwgcHJvcHMpO1xuXG4gICAgdGhpcy5ub2RlLmFkZFZhbGlkYXRpb24oe1xuICAgICAgdmFsaWRhdGU6ICgpID0+IHRoaXMucG9saWN5Py5kb2N1bWVudC52YWxpZGF0ZUZvclJlc291cmNlUG9saWN5KCkgPz8gW10sXG4gICAgfSk7XG5cbiAgICBjb25zdCB7IHdlYnNpdGVDb25maWcsIGNvcnNDb25maWcsIGNsb3VkZnJvbnRBY2Nlc3MgfSA9IHByb3BzO1xuICAgIHRoaXMuX2lzV2Vic2l0ZSA9IGZhbHNlO1xuXG4gICAgaWYgKHByb3BzLmJ1Y2tldE5hbWUgJiYgcHJvcHMubmFtZVByZWZpeCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICBcIkNhbm5vdCBzcGVjaWZ5IGJvdGggJ2J1Y2tldE5hbWUnIGFuZCAnbmFtZVByZWZpeCcuIFVzZSBvbmx5IG9uZS5cIixcbiAgICAgICk7XG4gICAgfVxuXG4gICAgbGV0IGJ1Y2tldFByZWZpeDogc3RyaW5nIHwgdW5kZWZpbmVkO1xuICAgIGlmICghcHJvcHMuYnVja2V0TmFtZSkge1xuICAgICAgLy8gQnVja2V0IG5hbWVzIG11c3QgYmUgbG93ZXJjYXNlIGFuZCBiZXR3ZWVuIDMgKG1pbikgYW5kIDYzIChtYXgpIGNoYXJhY3RlcnMgbG9uZy5cbiAgICAgIGJ1Y2tldFByZWZpeCA9IHRoaXMuc3RhY2sudW5pcXVlUmVzb3VyY2VOYW1lUHJlZml4KHRoaXMsIHtcbiAgICAgICAgcHJlZml4OiAocHJvcHMubmFtZVByZWZpeCA/PyB0aGlzLmdyaWRVVUlEKSArIFwiLVwiLFxuICAgICAgICBsb3dlckNhc2U6IHRydWUsXG4gICAgICAgIGFsbG93ZWRTcGVjaWFsQ2hhcmFjdGVyczogXCIuLVwiLFxuICAgICAgICBtYXhMZW5ndGg6IDYzLFxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgdGhpcy5yZXNvdXJjZSA9IG5ldyBzM0J1Y2tldC5TM0J1Y2tldCh0aGlzLCBcIlJlc291cmNlXCIsIHtcbiAgICAgIGJ1Y2tldDogcHJvcHMuYnVja2V0TmFtZSxcbiAgICAgIGZvcmNlRGVzdHJveTogcHJvcHMuZm9yY2VEZXN0cm95LFxuICAgICAgYnVja2V0UHJlZml4LFxuICAgIH0pO1xuXG4gICAgdGhpcy5fdmVyc2lvbmVkID0gcHJvcHMudmVyc2lvbmVkID8/IGZhbHNlO1xuICAgIGlmICh0aGlzLl92ZXJzaW9uZWQpIHtcbiAgICAgIG5ldyBzM0J1Y2tldFZlcnNpb25pbmcuUzNCdWNrZXRWZXJzaW9uaW5nQSh0aGlzLCBcIlZlcnNpb25pbmdcIiwge1xuICAgICAgICBidWNrZXQ6IHRoaXMucmVzb3VyY2UuYnVja2V0LFxuICAgICAgICB2ZXJzaW9uaW5nQ29uZmlndXJhdGlvbjoge1xuICAgICAgICAgIHN0YXR1czogdGhpcy5fdmVyc2lvbmVkID8gXCJFbmFibGVkXCIgOiBcIlN1c3BlbmRlZFwiLFxuICAgICAgICB9LFxuICAgICAgfSk7XG4gICAgfVxuICAgIHRoaXMuZXZlbnRCcmlkZ2VFbmFibGVkID0gcHJvcHMuZXZlbnRCcmlkZ2VFbmFibGVkO1xuXG4gICAgaWYgKHByb3BzLnNvdXJjZXMpIHtcbiAgICAgIGlmICh0eXBlb2YgcHJvcHMuc291cmNlcyA9PT0gXCJzdHJpbmdcIikge1xuICAgICAgICB0aGlzLmFkZFNvdXJjZSh7IHBhdGg6IHByb3BzLnNvdXJjZXMgfSk7XG4gICAgICB9IGVsc2UgaWYgKEFycmF5LmlzQXJyYXkocHJvcHMuc291cmNlcykpIHtcbiAgICAgICAgZm9yIChjb25zdCBzb3VyY2VQcm9wcyBvZiBwcm9wcy5zb3VyY2VzKSB7XG4gICAgICAgICAgaWYgKHR5cGVvZiBzb3VyY2VQcm9wcyA9PT0gXCJzdHJpbmdcIikge1xuICAgICAgICAgICAgdGhpcy5hZGRTb3VyY2UoeyBwYXRoOiBzb3VyY2VQcm9wcyB9KTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5hZGRTb3VyY2Uoc291cmNlUHJvcHMpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChwcm9wcy5saWZlY3ljbGVSdWxlcykge1xuICAgICAgbmV3IHMzQnVja2V0TGlmZWN5Y2xlQ29uZmlndXJhdGlvbi5TM0J1Y2tldExpZmVjeWNsZUNvbmZpZ3VyYXRpb24oXG4gICAgICAgIHRoaXMsXG4gICAgICAgIFwiTGlmZUN5Y2xlQ29uZmlnXCIsXG4gICAgICAgIHtcbiAgICAgICAgICBidWNrZXQ6IHRoaXMucmVzb3VyY2UuYnVja2V0LFxuICAgICAgICAgIHJ1bGU6IHByb3BzLmxpZmVjeWNsZVJ1bGVzLm1hcCgocnVsZSkgPT4gKHtcbiAgICAgICAgICAgIC4uLnJ1bGUsXG4gICAgICAgICAgICBzdGF0dXM6IHJ1bGUuZW5hYmxlZCA/IFwiRW5hYmxlZFwiIDogXCJEaXNhYmxlZFwiLFxuICAgICAgICAgIH0pKSxcbiAgICAgICAgfSxcbiAgICAgICk7XG4gICAgfVxuXG4gICAgLy8gRW5mb3JjZSBBV1MgRm91bmRhdGlvbmFsIFNlY3VyaXR5IEJlc3QgUHJhY3RpY2VcbiAgICBpZiAocHJvcHMuZW5mb3JjZVNTTCkge1xuICAgICAgdGhpcy5lbmZvcmNlU1NMU3RhdGVtZW50KCk7XG4gICAgICB0aGlzLm1pbmltdW1UTFNWZXJzaW9uU3RhdGVtZW50KHByb3BzLm1pbmltdW1UTFNWZXJzaW9uKTtcbiAgICB9IGVsc2UgaWYgKHByb3BzLm1pbmltdW1UTFNWZXJzaW9uKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgIFwiJ2VuZm9yY2VTU0wnIG11c3QgYmUgZW5hYmxlZCBmb3IgJ21pbmltdW1UTFNWZXJzaW9uJyB0byBiZSBhcHBsaWVkXCIsXG4gICAgICApO1xuICAgIH1cblxuICAgIGlmICh3ZWJzaXRlQ29uZmlnICYmIHdlYnNpdGVDb25maWcuZW5hYmxlZCkge1xuICAgICAgdGhpcy5faXNXZWJzaXRlID0gdHJ1ZTtcbiAgICAgIHRoaXMud2Vic2l0ZUNvbmZpZyA9XG4gICAgICAgIG5ldyBzM0J1Y2tldFdlYnNpdGVDb25maWd1cmF0aW9uLlMzQnVja2V0V2Vic2l0ZUNvbmZpZ3VyYXRpb24oXG4gICAgICAgICAgdGhpcyxcbiAgICAgICAgICBcIldlYnNpdGVDb25maWdcIixcbiAgICAgICAgICB7XG4gICAgICAgICAgICBidWNrZXQ6IHRoaXMucmVzb3VyY2UuYnVja2V0LFxuICAgICAgICAgICAgLi4ud2Vic2l0ZUNvbmZpZyxcbiAgICAgICAgICAgIGluZGV4RG9jdW1lbnQ6IHdlYnNpdGVDb25maWc/LmluZGV4RG9jdW1lbnRcbiAgICAgICAgICAgICAgPyB7XG4gICAgICAgICAgICAgICAgICBzdWZmaXg6IHdlYnNpdGVDb25maWcuaW5kZXhEb2N1bWVudCxcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIDoge1xuICAgICAgICAgICAgICAgICAgc3VmZml4OiBcImluZGV4Lmh0bWxcIixcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgIH0sXG4gICAgICAgICk7XG4gICAgfVxuXG4gICAgdGhpcy5wdWJsaWMgPSBwcm9wcy5wdWJsaWMgPz8gZmFsc2U7XG4gICAgaWYgKHRoaXMucHVibGljKSB7XG4gICAgICAvLyBUT0RPOiBzd2l0Y2ggdG8gTGF6eSBjb25maWcgdXNpbmcgXCJncmFudFB1YmxpY0FjY2Vzc1wiIG1lY2hhbmlzbSBpbnN0ZWFkP1xuICAgICAgLy8gcmVmOiBodHRwczovL2dpdGh1Yi5jb20vYXdzL2F3cy1jZGsvYmxvYi92Mi4xNjAuMC9wYWNrYWdlcy9hd3MtY2RrLWxpYi9hd3MtczMvbGliL2J1Y2tldC50cyNMODUwXG4gICAgICBjb25zdCBvd25lcnNoaXBDb250cm9scyA9XG4gICAgICAgIG5ldyBzM0J1Y2tldE93bmVyc2hpcENvbnRyb2xzLlMzQnVja2V0T3duZXJzaGlwQ29udHJvbHMoXG4gICAgICAgICAgdGhpcyxcbiAgICAgICAgICBcIk93bmVyc2hpcENvbnRyb2xzXCIsXG4gICAgICAgICAge1xuICAgICAgICAgICAgYnVja2V0OiB0aGlzLnJlc291cmNlLmJ1Y2tldCxcbiAgICAgICAgICAgIHJ1bGU6IHtcbiAgICAgICAgICAgICAgb2JqZWN0T3duZXJzaGlwOiBcIkJ1Y2tldE93bmVyUHJlZmVycmVkXCIsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0sXG4gICAgICAgICk7XG4gICAgICBjb25zdCBwdWJsaWNBY2Nlc3NCbG9jayA9XG4gICAgICAgIG5ldyBzM0J1Y2tldFB1YmxpY0FjY2Vzc0Jsb2NrLlMzQnVja2V0UHVibGljQWNjZXNzQmxvY2soXG4gICAgICAgICAgdGhpcyxcbiAgICAgICAgICBcIlB1YmxpY0FjY2Vzc0Jsb2NrXCIsXG4gICAgICAgICAge1xuICAgICAgICAgICAgYnVja2V0OiB0aGlzLnJlc291cmNlLmJ1Y2tldCxcbiAgICAgICAgICAgIGJsb2NrUHVibGljQWNsczogZmFsc2UsXG4gICAgICAgICAgICBibG9ja1B1YmxpY1BvbGljeTogZmFsc2UsXG4gICAgICAgICAgICBpZ25vcmVQdWJsaWNBY2xzOiBmYWxzZSxcbiAgICAgICAgICAgIHJlc3RyaWN0UHVibGljQnVja2V0czogZmFsc2UsXG4gICAgICAgICAgfSxcbiAgICAgICAgKTtcbiAgICAgIG5ldyBzM0J1Y2tldEFjbC5TM0J1Y2tldEFjbCh0aGlzLCBcIlB1YmxpY0FjbFwiLCB7XG4gICAgICAgIGJ1Y2tldDogdGhpcy5yZXNvdXJjZS5idWNrZXQsXG4gICAgICAgIGFjbDogXCJwdWJsaWMtcmVhZFwiLFxuICAgICAgICBkZXBlbmRzT246IFtvd25lcnNoaXBDb250cm9scywgcHVibGljQWNjZXNzQmxvY2tdLFxuICAgICAgfSk7XG4gICAgICB0aGlzLmFkZFRvUmVzb3VyY2VQb2xpY3koXG4gICAgICAgIG5ldyBpYW0uUG9saWN5U3RhdGVtZW50KHtcbiAgICAgICAgICByZXNvdXJjZXM6IFt0aGlzLmFybkZvck9iamVjdHMoXCIqXCIpXSxcbiAgICAgICAgICBhY3Rpb25zOiBbXCJzMzpHZXRPYmplY3RcIl0sXG4gICAgICAgICAgcHJpbmNpcGFsczogW25ldyBpYW0uQW55UHJpbmNpcGFsKCldLFxuICAgICAgICB9KSxcbiAgICAgICk7XG4gICAgICAvLyAvLyBwb2xpY3kgZGVwZW5kcyBvbiBwdWJsaWMgYWNjZXNzIGJsb2NrP1xuICAgICAgLy8gLy8gaXMgdGhpcyBuZWVkZWQ/XG4gICAgICAvLyBpZiAocG9saWN5RGVwZW5kYWJsZSAmJiBwb2xpY3lEZXBlbmRhYmxlIGluc3RhbmNlb2YgQ29uc3RydWN0KSB7XG4gICAgICAvLyAgIHBvbGljeURlcGVuZGFibGUubm9kZS5hZGREZXBlbmRlbmN5KHB1YmxpY0FjY2Vzc0Jsb2NrKTtcbiAgICAgIC8vIH1cbiAgICB9XG5cbiAgICBpZiAoY29yc0NvbmZpZykge1xuICAgICAgdGhpcy5jb3JzQ29uZmlnID0gbmV3IHMzQnVja2V0Q29yc0NvbmZpZ3VyYXRpb24uUzNCdWNrZXRDb3JzQ29uZmlndXJhdGlvbihcbiAgICAgICAgdGhpcyxcbiAgICAgICAgXCJDb3JzQ29uZmlnXCIsXG4gICAgICAgIHtcbiAgICAgICAgICBidWNrZXQ6IHRoaXMucmVzb3VyY2UuYnVja2V0LFxuICAgICAgICAgIC4uLmNvcnNDb25maWcsXG4gICAgICAgIH0sXG4gICAgICApO1xuICAgIH1cblxuICAgIGxldCBvcmlnaW5BY2Nlc3NJZGVudGl0eTogc3RyaW5nIHwgdW5kZWZpbmVkO1xuICAgIGlmIChjbG91ZGZyb250QWNjZXNzPy5lbmFibGVkKSB7XG4gICAgICBjb25zdCBvYWkgPSBuZXcgT3JpZ2luQWNjZXNzSWRlbnRpdHkodGhpcywgXCJPcmlnaW5BY2Nlc3NJZGVudGl0eVwiLCB7XG4gICAgICAgIGNvbW1lbnQ6IGBPQUkgZm9yICR7dGhpcy5yZXNvdXJjZS5idWNrZXR9YCxcbiAgICAgIH0pO1xuICAgICAgb3JpZ2luQWNjZXNzSWRlbnRpdHkgPSBvYWkuY2xvdWRGcm9udE9yaWdpbkFjY2Vzc0lkZW50aXR5UGF0aDtcbiAgICAgIGNvbnN0IHJlc291cmNlcyA9IChjbG91ZGZyb250QWNjZXNzLmtleVBhdHRlcm5zID8/IFtcIipcIl0pLm1hcChcbiAgICAgICAgKGtleVBhdHRlcm4pID0+IHRoaXMuYXJuRm9yT2JqZWN0cyhrZXlQYXR0ZXJuKSxcbiAgICAgICk7XG4gICAgICB0aGlzLmFkZFRvUmVzb3VyY2VQb2xpY3koXG4gICAgICAgIG5ldyBpYW0uUG9saWN5U3RhdGVtZW50KHtcbiAgICAgICAgICByZXNvdXJjZXMsXG4gICAgICAgICAgYWN0aW9uczogW1wiczM6R2V0T2JqZWN0XCJdLFxuICAgICAgICAgIHByaW5jaXBhbHM6IFtvYWkuZ3JhbnRQcmluY2lwYWxdLFxuICAgICAgICB9KSxcbiAgICAgICk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuZXZlbnRCcmlkZ2VFbmFibGVkKSB7XG4gICAgICB0aGlzLmVuYWJsZUV2ZW50QnJpZGdlTm90aWZpY2F0aW9uKCk7XG4gICAgfVxuXG4gICAgLy9yZWdpc3RlciBvdXRwdXRzXG4gICAgdGhpcy5fb3V0cHV0cyA9IHtcbiAgICAgIG5hbWU6IHRoaXMucmVzb3VyY2UuYnVja2V0LFxuICAgICAgYXJuOiB0aGlzLnJlc291cmNlLmFybixcbiAgICAgIGRvbWFpbk5hbWU6IHRoaXMucmVzb3VyY2UuYnVja2V0RG9tYWluTmFtZSxcbiAgICAgIHJlZ2lvbmFsRG9tYWluTmFtZTogdGhpcy5yZXNvdXJjZS5idWNrZXRSZWdpb25hbERvbWFpbk5hbWUsXG4gICAgICB3ZWJzaXRlRG9tYWluTmFtZTogdGhpcy53ZWJzaXRlQ29uZmlnPy53ZWJzaXRlRG9tYWluLFxuICAgICAgd2Vic2l0ZVVybDogdGhpcy53ZWJzaXRlQ29uZmlnPy53ZWJzaXRlRW5kcG9pbnQsXG4gICAgICBvcmlnaW5BY2Nlc3NJZGVudGl0eSxcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIEFkZHMgYSBzdGF0ZW1lbnQgdG8gdGhlIHJlc291cmNlIHBvbGljeSBmb3IgYSBwcmluY2lwYWwgKGkuZS5cbiAgICogYWNjb3VudC9yb2xlL3NlcnZpY2UpIHRvIHBlcmZvcm0gYWN0aW9ucyBvbiB0aGlzIGJ1Y2tldCBhbmQvb3IgaXRzXG4gICAqIGNvbnRlbnRzLiBVc2UgYGJ1Y2tldEFybmAgYW5kIGBhcm5Gb3JPYmplY3RzKGtleXMpYCB0byBvYnRhaW4gQVJOcyBmb3JcbiAgICogdGhpcyBidWNrZXQgb3Igb2JqZWN0cy5cbiAgICpcbiAgICogTm90ZSB0aGF0IHRoZSBwb2xpY3kgc3RhdGVtZW50IG1heSBvciBtYXkgbm90IGJlIGFkZGVkIHRvIHRoZSBwb2xpY3kuXG4gICAqIEZvciBleGFtcGxlLCB3aGVuIGFuIGBJQnVja2V0YCBpcyBjcmVhdGVkIGZyb20gYW4gZXhpc3RpbmcgYnVja2V0LFxuICAgKiBpdCdzIG5vdCBwb3NzaWJsZSB0byB0ZWxsIHdoZXRoZXIgdGhlIGJ1Y2tldCBhbHJlYWR5IGhhcyBhIHBvbGljeVxuICAgKiBhdHRhY2hlZCwgbGV0IGFsb25lIHRvIHJlLXVzZSB0aGF0IHBvbGljeSB0byBhZGQgbW9yZSBzdGF0ZW1lbnRzIHRvIGl0LlxuICAgKiBTbyBpdCdzIHNhZmVzdCB0byBkbyBub3RoaW5nIGluIHRoZXNlIGNhc2VzLlxuICAgKlxuICAgKiBAcGFyYW0gcGVybWlzc2lvbiB0aGUgcG9saWN5IHN0YXRlbWVudCB0byBiZSBhZGRlZCB0byB0aGUgYnVja2V0J3NcbiAgICogcG9saWN5LlxuICAgKiBAcmV0dXJucyBtZXRhZGF0YSBhYm91dCB0aGUgZXhlY3V0aW9uIG9mIHRoaXMgbWV0aG9kLiBJZiB0aGUgcG9saWN5XG4gICAqIHdhcyBub3QgYWRkZWQsIHRoZSB2YWx1ZSBvZiBgc3RhdGVtZW50QWRkZWRgIHdpbGwgYmUgYGZhbHNlYC4gWW91XG4gICAqIHNob3VsZCBhbHdheXMgY2hlY2sgdGhpcyB2YWx1ZSB0byBtYWtlIHN1cmUgdGhhdCB0aGUgb3BlcmF0aW9uIHdhc1xuICAgKiBhY3R1YWxseSBjYXJyaWVkIG91dC4gT3RoZXJ3aXNlLCBzeW50aGVzaXMgYW5kIGRlcGxveSB3aWxsIHRlcm1pbmF0ZVxuICAgKiBzaWxlbnRseSwgd2hpY2ggbWF5IGJlIGNvbmZ1c2luZy5cbiAgICovXG4gIHB1YmxpYyBhZGRUb1Jlc291cmNlUG9saWN5KFxuICAgIHBlcm1pc3Npb246IGlhbS5Qb2xpY3lTdGF0ZW1lbnQsXG4gICk6IGlhbS5BZGRUb1Jlc291cmNlUG9saWN5UmVzdWx0IHtcbiAgICAvLyBUT0RPOiByZS1hZGQgYXV0b0NyZWF0ZVBvbGljeSBvcHRpb24/XG4gICAgLy8gcmVmOiBodHRwczovL2dpdGh1Yi5jb20vYXdzL2F3cy1jZGsvYmxvYi92Mi4xNjAuMC9wYWNrYWdlcy9hd3MtY2RrLWxpYi9hd3MtczMvbGliL2J1Y2tldC50cyNMNjUyXG4gICAgaWYgKCF0aGlzLnBvbGljeSkge1xuICAgICAgdGhpcy5wb2xpY3kgPSBuZXcgQnVja2V0UG9saWN5KHRoaXMsIFwiUG9saWN5XCIsIHsgYnVja2V0OiB0aGlzIH0pO1xuICAgIH1cblxuICAgIGlmICh0aGlzLnBvbGljeSkge1xuICAgICAgdGhpcy5wb2xpY3kuZG9jdW1lbnQuYWRkU3RhdGVtZW50cyhwZXJtaXNzaW9uKTtcbiAgICAgIHJldHVybiB7IHN0YXRlbWVudEFkZGVkOiB0cnVlLCBwb2xpY3lEZXBlbmRhYmxlOiB0aGlzLnBvbGljeSB9O1xuICAgIH1cblxuICAgIHJldHVybiB7IHN0YXRlbWVudEFkZGVkOiBmYWxzZSB9O1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50IHJlYWQgcGVybWlzc2lvbnMgZm9yIHRoaXMgYnVja2V0IGFuZCBpdCdzIGNvbnRlbnRzIHRvIGFuIElBTVxuICAgKiBwcmluY2lwYWwgKFJvbGUvR3JvdXAvVXNlcikuXG4gICAqXG4gICAqIElmIGVuY3J5cHRpb24gaXMgdXNlZCwgcGVybWlzc2lvbiB0byB1c2UgdGhlIGtleSB0byBkZWNyeXB0IHRoZSBjb250ZW50c1xuICAgKiBvZiB0aGUgYnVja2V0IHdpbGwgYWxzbyBiZSBncmFudGVkIHRvIHRoZSBzYW1lIHByaW5jaXBhbC5cbiAgICpcbiAgICogQHBhcmFtIGlkZW50aXR5IFRoZSBwcmluY2lwYWxcbiAgICogQHBhcmFtIG9iamVjdHNLZXlQYXR0ZXJuIFJlc3RyaWN0IHRoZSBwZXJtaXNzaW9uIHRvIGEgY2VydGFpbiBrZXkgcGF0dGVybiAoZGVmYXVsdCAnKicpLiBQYXJhbWV0ZXIgdHlwZSBpcyBgYW55YCBidXQgYHN0cmluZ2Agc2hvdWxkIGJlIHBhc3NlZCBpbi5cbiAgICovXG4gIHB1YmxpYyBncmFudFJlYWQoaWRlbnRpdHk6IGlhbS5JR3JhbnRhYmxlLCBvYmplY3RzS2V5UGF0dGVybjogYW55ID0gXCIqXCIpIHtcbiAgICByZXR1cm4gdGhpcy5ncmFudChcbiAgICAgIGlkZW50aXR5LFxuICAgICAgcGVybXMuQlVDS0VUX1JFQURfQUNUSU9OUyxcbiAgICAgIHBlcm1zLktFWV9SRUFEX0FDVElPTlMsXG4gICAgICB0aGlzLnJlc291cmNlLmFybixcbiAgICAgIHRoaXMuYXJuRm9yT2JqZWN0cyhvYmplY3RzS2V5UGF0dGVybiksXG4gICAgKTtcbiAgfVxuXG4gIHB1YmxpYyBncmFudFdyaXRlKFxuICAgIGlkZW50aXR5OiBpYW0uSUdyYW50YWJsZSxcbiAgICBvYmplY3RzS2V5UGF0dGVybjogYW55ID0gXCIqXCIsXG4gICAgYWxsb3dlZEFjdGlvblBhdHRlcm5zOiBzdHJpbmdbXSA9IFtdLFxuICApIHtcbiAgICBjb25zdCBncmFudGVkV3JpdGVBY3Rpb25zID1cbiAgICAgIGFsbG93ZWRBY3Rpb25QYXR0ZXJucy5sZW5ndGggPiAwXG4gICAgICAgID8gYWxsb3dlZEFjdGlvblBhdHRlcm5zXG4gICAgICAgIDogdGhpcy53cml0ZUFjdGlvbnM7XG4gICAgcmV0dXJuIHRoaXMuZ3JhbnQoXG4gICAgICBpZGVudGl0eSxcbiAgICAgIGdyYW50ZWRXcml0ZUFjdGlvbnMsXG4gICAgICBwZXJtcy5LRVlfV1JJVEVfQUNUSU9OUyxcbiAgICAgIHRoaXMucmVzb3VyY2UuYXJuLFxuICAgICAgdGhpcy5hcm5Gb3JPYmplY3RzKG9iamVjdHNLZXlQYXR0ZXJuKSxcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBzMzpQdXRPYmplY3QqIGFuZCBzMzpBYm9ydCogcGVybWlzc2lvbnMgZm9yIHRoaXMgYnVja2V0IHRvIGFuIElBTSBwcmluY2lwYWwuXG4gICAqXG4gICAqIElmIGVuY3J5cHRpb24gaXMgdXNlZCwgcGVybWlzc2lvbiB0byB1c2UgdGhlIGtleSB0byBlbmNyeXB0IHRoZSBjb250ZW50c1xuICAgKiBvZiB3cml0dGVuIGZpbGVzIHdpbGwgYWxzbyBiZSBncmFudGVkIHRvIHRoZSBzYW1lIHByaW5jaXBhbC5cbiAgICogQHBhcmFtIGlkZW50aXR5IFRoZSBwcmluY2lwYWxcbiAgICogQHBhcmFtIG9iamVjdHNLZXlQYXR0ZXJuIFJlc3RyaWN0IHRoZSBwZXJtaXNzaW9uIHRvIGEgY2VydGFpbiBrZXkgcGF0dGVybiAoZGVmYXVsdCAnKicpLiBQYXJhbWV0ZXIgdHlwZSBpcyBgYW55YCBidXQgYHN0cmluZ2Agc2hvdWxkIGJlIHBhc3NlZCBpbi5cbiAgICovXG4gIHB1YmxpYyBncmFudFB1dChpZGVudGl0eTogaWFtLklHcmFudGFibGUsIG9iamVjdHNLZXlQYXR0ZXJuOiBhbnkgPSBcIipcIikge1xuICAgIHJldHVybiB0aGlzLmdyYW50KFxuICAgICAgaWRlbnRpdHksXG4gICAgICBwZXJtcy5CVUNLRVRfUFVUX0FDVElPTlMsXG4gICAgICBwZXJtcy5LRVlfV1JJVEVfQUNUSU9OUyxcbiAgICAgIHRoaXMuYXJuRm9yT2JqZWN0cyhvYmplY3RzS2V5UGF0dGVybiksXG4gICAgKTtcbiAgfVxuXG4gIHB1YmxpYyBncmFudFB1dEFjbChcbiAgICBpZGVudGl0eTogaWFtLklHcmFudGFibGUsXG4gICAgb2JqZWN0c0tleVBhdHRlcm46IHN0cmluZyA9IFwiKlwiLFxuICApIHtcbiAgICByZXR1cm4gdGhpcy5ncmFudChcbiAgICAgIGlkZW50aXR5LFxuICAgICAgcGVybXMuQlVDS0VUX1BVVF9BQ0xfQUNUSU9OUyxcbiAgICAgIFtdLFxuICAgICAgdGhpcy5hcm5Gb3JPYmplY3RzKG9iamVjdHNLZXlQYXR0ZXJuKSxcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50cyBzMzpEZWxldGVPYmplY3QqIHBlcm1pc3Npb24gdG8gYW4gSUFNIHByaW5jaXBhbCBmb3Igb2JqZWN0c1xuICAgKiBpbiB0aGlzIGJ1Y2tldC5cbiAgICpcbiAgICogQHBhcmFtIGlkZW50aXR5IFRoZSBwcmluY2lwYWxcbiAgICogQHBhcmFtIG9iamVjdHNLZXlQYXR0ZXJuIFJlc3RyaWN0IHRoZSBwZXJtaXNzaW9uIHRvIGEgY2VydGFpbiBrZXkgcGF0dGVybiAoZGVmYXVsdCAnKicpLiBQYXJhbWV0ZXIgdHlwZSBpcyBgYW55YCBidXQgYHN0cmluZ2Agc2hvdWxkIGJlIHBhc3NlZCBpbi5cbiAgICovXG4gIHB1YmxpYyBncmFudERlbGV0ZShpZGVudGl0eTogaWFtLklHcmFudGFibGUsIG9iamVjdHNLZXlQYXR0ZXJuOiBhbnkgPSBcIipcIikge1xuICAgIHJldHVybiB0aGlzLmdyYW50KFxuICAgICAgaWRlbnRpdHksXG4gICAgICBwZXJtcy5CVUNLRVRfREVMRVRFX0FDVElPTlMsXG4gICAgICBbXSxcbiAgICAgIHRoaXMuYXJuRm9yT2JqZWN0cyhvYmplY3RzS2V5UGF0dGVybiksXG4gICAgKTtcbiAgfVxuXG4gIHB1YmxpYyBncmFudFJlYWRXcml0ZShcbiAgICBpZGVudGl0eTogaWFtLklHcmFudGFibGUsXG4gICAgb2JqZWN0c0tleVBhdHRlcm46IGFueSA9IFwiKlwiLFxuICApIHtcbiAgICBjb25zdCBidWNrZXRBY3Rpb25zID0gcGVybXMuQlVDS0VUX1JFQURfQUNUSU9OUy5jb25jYXQodGhpcy53cml0ZUFjdGlvbnMpO1xuICAgIC8vIHdlIG5lZWQgdW5pcXVlIHBlcm1pc3Npb25zIGJlY2F1c2Ugc29tZSBwZXJtaXNzaW9ucyBhcmUgY29tbW9uIGJldHdlZW4gcmVhZCBhbmQgd3JpdGUga2V5IGFjdGlvbnNcbiAgICBjb25zdCBrZXlBY3Rpb25zID0gW1xuICAgICAgLi4ubmV3IFNldChbLi4ucGVybXMuS0VZX1JFQURfQUNUSU9OUywgLi4ucGVybXMuS0VZX1dSSVRFX0FDVElPTlNdKSxcbiAgICBdO1xuXG4gICAgcmV0dXJuIHRoaXMuZ3JhbnQoXG4gICAgICBpZGVudGl0eSxcbiAgICAgIGJ1Y2tldEFjdGlvbnMsXG4gICAgICBrZXlBY3Rpb25zLFxuICAgICAgdGhpcy5yZXNvdXJjZS5hcm4sXG4gICAgICB0aGlzLmFybkZvck9iamVjdHMob2JqZWN0c0tleVBhdHRlcm4pLFxuICAgICk7XG4gIH1cblxuICAvLyBUT0RPOiBjdXJyZW50bHkgb25seSBzdXBwb3J0ZWQgdGhyb3VnaCBgcHJvcHMucHVibGljYCBpbiBjb25zdHJ1Y3RvclxuICAvLyAvKipcbiAgLy8gICogQWxsb3dzIHVucmVzdHJpY3RlZCBhY2Nlc3MgdG8gb2JqZWN0cyBmcm9tIHRoaXMgYnVja2V0LlxuICAvLyAgKlxuICAvLyAgKiBJTVBPUlRBTlQ6IFRoaXMgcGVybWlzc2lvbiBhbGxvd3MgYW55b25lIHRvIHBlcmZvcm0gYWN0aW9ucyBvbiBTMyBvYmplY3RzXG4gIC8vICAqIGluIHRoaXMgYnVja2V0LCB3aGljaCBpcyB1c2VmdWwgZm9yIHdoZW4geW91IGNvbmZpZ3VyZSB5b3VyIGJ1Y2tldCBhcyBhXG4gIC8vICAqIHdlYnNpdGUgYW5kIHdhbnQgZXZlcnlvbmUgdG8gYmUgYWJsZSB0byByZWFkIG9iamVjdHMgaW4gdGhlIGJ1Y2tldCB3aXRob3V0XG4gIC8vICAqIG5lZWRpbmcgdG8gYXV0aGVudGljYXRlLlxuICAvLyAgKlxuICAvLyAgKiBXaXRob3V0IGFyZ3VtZW50cywgdGhpcyBtZXRob2Qgd2lsbCBncmFudCByZWFkIChcInMzOkdldE9iamVjdFwiKSBhY2Nlc3MgdG9cbiAgLy8gICogYWxsIG9iamVjdHMgKFwiKlwiKSBpbiB0aGUgYnVja2V0LlxuICAvLyAgKlxuICAvLyAgKiBUaGUgbWV0aG9kIHJldHVybnMgdGhlIGBpYW0uR3JhbnRgIG9iamVjdCwgd2hpY2ggY2FuIHRoZW4gYmUgbW9kaWZpZWRcbiAgLy8gICogYXMgbmVlZGVkLiBGb3IgZXhhbXBsZSwgeW91IGNhbiBhZGQgYSBjb25kaXRpb24gdGhhdCB3aWxsIHJlc3RyaWN0IGFjY2VzcyBvbmx5XG4gIC8vICAqIHRvIGFuIElQdjQgcmFuZ2UgbGlrZSB0aGlzOlxuICAvLyAgKlxuICAvLyAgKiAgICAgY29uc3QgZ3JhbnQgPSBidWNrZXQuZ3JhbnRQdWJsaWNBY2Nlc3MoKTtcbiAgLy8gICogICAgIGdyYW50LnJlc291cmNlU3RhdGVtZW50IS5hZGRDb25kaXRpb24o4oCYSXBBZGRyZXNz4oCZLCB7IOKAnGF3czpTb3VyY2VJcOKAnTog4oCcNTQuMjQwLjE0My4wLzI04oCdIH0pO1xuICAvLyAgKlxuICAvLyAgKiBOb3RlIHRoYXQgaWYgdGhpcyBgSUJ1Y2tldGAgcmVmZXJzIHRvIGFuIGV4aXN0aW5nIGJ1Y2tldCwgcG9zc2libHkgbm90XG4gIC8vICAqIG1hbmFnZWQgYnkgQ2xvdWRGb3JtYXRpb24sIHRoaXMgbWV0aG9kIHdpbGwgaGF2ZSBubyBlZmZlY3QsIHNpbmNlIGl0J3NcbiAgLy8gICogaW1wb3NzaWJsZSB0byBtb2RpZnkgdGhlIHBvbGljeSBvZiBhbiBleGlzdGluZyBidWNrZXQuXG4gIC8vICAqXG4gIC8vICAqIEBwYXJhbSBrZXlQcmVmaXggdGhlIHByZWZpeCBvZiBTMyBvYmplY3Qga2V5cyAoZS5nLiBgaG9tZS8qYCkuIERlZmF1bHQgaXMgXCIqXCIuXG4gIC8vICAqIEBwYXJhbSBhbGxvd2VkQWN0aW9ucyB0aGUgc2V0IG9mIFMzIGFjdGlvbnMgdG8gYWxsb3cuIERlZmF1bHQgaXMgXCJzMzpHZXRPYmplY3RcIi5cbiAgLy8gICovXG4gIC8vIHB1YmxpYyBncmFudFB1YmxpY0FjY2VzcyhrZXlQcmVmaXggPSBcIipcIiwgLi4uYWxsb3dlZEFjdGlvbnM6IHN0cmluZ1tdKSB7XG4gIC8vICAgaWYgKCF0aGlzLnB1YmxpYykge1xuICAvLyAgICAgdGhyb3cgbmV3IEVycm9yKFwiQ2Fubm90IGdyYW50IHB1YmxpYyBhY2Nlc3Mgd2hlbiAncHVibGljJyBpcyBlbmFibGVkXCIpO1xuICAvLyAgIH1cbiAgLy8gICAvLyBURE9POiBUaGlzIHNob3VsZCBjcmVhdGUgcHVibGljQWNjZXNzIHJlc291cmNlXG4gIC8vICAgYWxsb3dlZEFjdGlvbnMgPVxuICAvLyAgICAgYWxsb3dlZEFjdGlvbnMubGVuZ3RoID4gMCA/IGFsbG93ZWRBY3Rpb25zIDogW1wiczM6R2V0T2JqZWN0XCJdO1xuXG4gIC8vICAgcmV0dXJuIGlhbS5HcmFudC5hZGRUb1ByaW5jaXBhbE9yUmVzb3VyY2Uoe1xuICAvLyAgICAgYWN0aW9uczogYWxsb3dlZEFjdGlvbnMsXG4gIC8vICAgICByZXNvdXJjZUFybnM6IFt0aGlzLmFybkZvck9iamVjdHMoa2V5UHJlZml4KV0sXG4gIC8vICAgICBncmFudGVlOiBuZXcgaWFtLkFueVByaW5jaXBhbCgpLFxuICAvLyAgICAgcmVzb3VyY2U6IHRoaXMsXG4gIC8vICAgfSk7XG4gIC8vIH1cblxuICAvKipcbiAgICogQWRkcyBhIGJ1Y2tldCBub3RpZmljYXRpb24gZXZlbnQgZGVzdGluYXRpb24uXG4gICAqXG4gICAqIFMzIEJ1Y2tldHMgb25seSBzdXBwb3J0IGEgc2luZ2xlIG5vdGlmaWNhdGlvbiBjb25maWd1cmF0aW9uIHJlc291cmNlLlxuICAgKiBEZWNsYXJpbmcgbXVsdGlwbGUgYGF3c19zM19idWNrZXRfbm90aWZpY2F0aW9uYCByZXNvdXJjZXMgdG8gdGhlIHNhbWVcbiAgICogUzMgQnVja2V0IHdpbGwgY2F1c2UgYSBwZXJwZXR1YWwgZGlmZmVyZW5jZSBpbiBjb25maWd1cmF0aW9uLlxuICAgKlxuICAgKiBDYWxsaW5nIHRoaXMgZnVuY3Rpb24gd2lsbCBvdmVyd3JpdGUgYW55IGV4aXN0aW5nIGV2ZW50IG5vdGlmaWNhdGlvbnMgY29uZmlndXJlZFxuICAgKiBmb3IgdGhlIFMzIGJ1Y2tldCBvdXRzaWRlIG9mIHRoaXMgYmVhY29uLlxuICAgKlxuICAgKiBAcGFyYW0gZXZlbnQgVGhlIGV2ZW50IHRvIHRyaWdnZXIgdGhlIG5vdGlmaWNhdGlvblxuICAgKiBAcGFyYW0gZGVzdCBUaGUgbm90aWZpY2F0aW9uIGRlc3RpbmF0aW9uIChMYW1iZGEsIFNOUyBUb3BpYyBvciBTUVMgUXVldWUpXG4gICAqXG4gICAqIEBwYXJhbSBmaWx0ZXJzIFMzIG9iamVjdCBrZXkgZmlsdGVyIHJ1bGVzIHRvIGRldGVybWluZSB3aGljaCBvYmplY3RzXG4gICAqIHRyaWdnZXIgdGhpcyBldmVudC4gRWFjaCBmaWx0ZXIgbXVzdCBpbmNsdWRlIGEgYHByZWZpeGAgYW5kL29yIGBzdWZmaXhgXG4gICAqIHRoYXQgd2lsbCBiZSBtYXRjaGVkIGFnYWluc3QgdGhlIHMzIG9iamVjdCBrZXkuIFJlZmVyIHRvIHRoZSBTMyBEZXZlbG9wZXIgR3VpZGVcbiAgICogZm9yIGRldGFpbHMgYWJvdXQgYWxsb3dlZCBmaWx0ZXIgcnVsZXMuXG4gICAqXG4gICAqIEBzZWUgaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FtYXpvblMzL2xhdGVzdC9kZXYvTm90aWZpY2F0aW9uSG93VG8uaHRtbCNub3RpZmljYXRpb24taG93LXRvLWZpbHRlcmluZ1xuICAgKlxuICAgKiBAZXhhbXBsZVxuICAgKlxuICAgKiAgICBkZWNsYXJlIGNvbnN0IG15RnVuY3Rpb246IGNvbXB1dGUuRnVuY3Rpb247XG4gICAqICAgIGNvbnN0IGJ1Y2tldCA9IG5ldyBzdG9yYWdlLkJ1Y2tldCh0aGlzLCAnTXlCdWNrZXQnKTtcbiAgICogICAgYnVja2V0LmFkZEV2ZW50Tm90aWZpY2F0aW9uKHMzLkV2ZW50VHlwZS5PQkpFQ1RfQ1JFQVRFRCwgbmV3IHMzbi5MYW1iZGFEZXN0aW5hdGlvbihteUZ1bmN0aW9uKSwge3ByZWZpeDogJ2hvbWUvbXl1c2VybmFtZS8qJ30pO1xuICAgKlxuICAgKiBAc2VlXG4gICAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BbWF6b25TMy9sYXRlc3QvZGV2L05vdGlmaWNhdGlvbkhvd1RvLmh0bWxcbiAgICovXG4gIHB1YmxpYyBhZGRFdmVudE5vdGlmaWNhdGlvbihcbiAgICBldmVudDogRXZlbnRUeXBlLFxuICAgIGRlc3Q6IElCdWNrZXROb3RpZmljYXRpb25EZXN0aW5hdGlvbixcbiAgICAuLi5maWx0ZXJzOiBOb3RpZmljYXRpb25LZXlGaWx0ZXJbXVxuICApIHtcbiAgICAvLyBUT0RPOiBUaGlzIGJsb2NrcyBhZGRpbmcgbm90aWZpY2F0aW9ucyBvdXRzaWRlIG9mIHRoZSBTdGFjayBvd25pbmcgdGhlIGJ1Y2tldC4uLlxuICAgIC8vIEFXUy1DREsgd29ya3MgYXJvdW5kIHRoaXMgYnkgdXNpbmcgYSBDdXN0b21SZXNvdXJjZSBoYW5kbGVyIChMYW1iZGEgZnVuY3Rpb24pIHdoaWNoIG1vZGlmaWVzXG4gICAgLy8gdGhlIGJ1Y2tldCBwb2xpY3kgaW4gcGxhY2UgKGFuZCBDRk4gZG9lcyBub3QgbWFuYWdlIHRoZSBhY3R1YWwgYnVja2V0IHBvbGljeSwgc28gbm8gdGYgc3RhdGUhKVxuICAgIHRoaXMud2l0aE5vdGlmaWNhdGlvbnMoKG5vdGlmaWNhdGlvbnMpID0+XG4gICAgICBub3RpZmljYXRpb25zLmFkZE5vdGlmaWNhdGlvbihldmVudCwgZGVzdCwgLi4uZmlsdGVycyksXG4gICAgKTtcbiAgfVxuXG4gIHByaXZhdGUgd2l0aE5vdGlmaWNhdGlvbnMoY2I6IChub3RpZmljYXRpb25zOiBCdWNrZXROb3RpZmljYXRpb25zKSA9PiB2b2lkKSB7XG4gICAgaWYgKCF0aGlzLm5vdGlmaWNhdGlvbnMpIHtcbiAgICAgIHRoaXMubm90aWZpY2F0aW9ucyA9IG5ldyBCdWNrZXROb3RpZmljYXRpb25zKHRoaXMsIFwiTm90aWZpY2F0aW9uc1wiLCB7XG4gICAgICAgIGJ1Y2tldDogdGhpcyxcbiAgICAgIH0pO1xuICAgIH1cbiAgICBjYih0aGlzLm5vdGlmaWNhdGlvbnMpO1xuICB9XG5cbiAgLyoqXG4gICAqIFN1YnNjcmliZXMgYSBkZXN0aW5hdGlvbiB0byByZWNlaXZlIG5vdGlmaWNhdGlvbnMgd2hlbiBhbiBvYmplY3QgaXNcbiAgICogY3JlYXRlZCBpbiB0aGUgYnVja2V0LiBUaGlzIGlzIGlkZW50aWNhbCB0byBjYWxsaW5nXG4gICAqIGBvbkV2ZW50KEV2ZW50VHlwZS5PQkpFQ1RfQ1JFQVRFRClgLlxuICAgKlxuICAgKiBAcGFyYW0gZGVzdCBUaGUgbm90aWZpY2F0aW9uIGRlc3RpbmF0aW9uIChzZWUgb25FdmVudClcbiAgICogQHBhcmFtIGZpbHRlcnMgRmlsdGVycyAoc2VlIG9uRXZlbnQpXG4gICAqL1xuICBwdWJsaWMgYWRkT2JqZWN0Q3JlYXRlZE5vdGlmaWNhdGlvbihcbiAgICBkZXN0OiBJQnVja2V0Tm90aWZpY2F0aW9uRGVzdGluYXRpb24sXG4gICAgLi4uZmlsdGVyczogTm90aWZpY2F0aW9uS2V5RmlsdGVyW11cbiAgKSB7XG4gICAgcmV0dXJuIHRoaXMuYWRkRXZlbnROb3RpZmljYXRpb24oXG4gICAgICBFdmVudFR5cGUuT0JKRUNUX0NSRUFURUQsXG4gICAgICBkZXN0LFxuICAgICAgLi4uZmlsdGVycyxcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIFN1YnNjcmliZXMgYSBkZXN0aW5hdGlvbiB0byByZWNlaXZlIG5vdGlmaWNhdGlvbnMgd2hlbiBhbiBvYmplY3QgaXNcbiAgICogcmVtb3ZlZCBmcm9tIHRoZSBidWNrZXQuIFRoaXMgaXMgaWRlbnRpY2FsIHRvIGNhbGxpbmdcbiAgICogYG9uRXZlbnQoRXZlbnRUeXBlLk9CSkVDVF9SRU1PVkVEKWAuXG4gICAqXG4gICAqIEBwYXJhbSBkZXN0IFRoZSBub3RpZmljYXRpb24gZGVzdGluYXRpb24gKHNlZSBvbkV2ZW50KVxuICAgKiBAcGFyYW0gZmlsdGVycyBGaWx0ZXJzIChzZWUgb25FdmVudClcbiAgICovXG4gIHB1YmxpYyBhZGRPYmplY3RSZW1vdmVkTm90aWZpY2F0aW9uKFxuICAgIGRlc3Q6IElCdWNrZXROb3RpZmljYXRpb25EZXN0aW5hdGlvbixcbiAgICAuLi5maWx0ZXJzOiBOb3RpZmljYXRpb25LZXlGaWx0ZXJbXVxuICApIHtcbiAgICByZXR1cm4gdGhpcy5hZGRFdmVudE5vdGlmaWNhdGlvbihcbiAgICAgIEV2ZW50VHlwZS5PQkpFQ1RfUkVNT1ZFRCxcbiAgICAgIGRlc3QsXG4gICAgICAuLi5maWx0ZXJzLFxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogRW5hYmxlcyBldmVudCBicmlkZ2Ugbm90aWZpY2F0aW9uLCBjYXVzaW5nIGFsbCBldmVudHMgYmVsb3cgdG8gYmUgc2VudCB0byBFdmVudEJyaWRnZTpcbiAgICpcbiAgICogLSBPYmplY3QgRGVsZXRlZCAoRGVsZXRlT2JqZWN0KVxuICAgKiAtIE9iamVjdCBEZWxldGVkIChMaWZlY3ljbGUgZXhwaXJhdGlvbilcbiAgICogLSBPYmplY3QgUmVzdG9yZSBJbml0aWF0ZWRcbiAgICogLSBPYmplY3QgUmVzdG9yZSBDb21wbGV0ZWRcbiAgICogLSBPYmplY3QgUmVzdG9yZSBFeHBpcmVkXG4gICAqIC0gT2JqZWN0IFN0b3JhZ2UgQ2xhc3MgQ2hhbmdlZFxuICAgKiAtIE9iamVjdCBBY2Nlc3MgVGllciBDaGFuZ2VkXG4gICAqIC0gT2JqZWN0IEFDTCBVcGRhdGVkXG4gICAqIC0gT2JqZWN0IFRhZ3MgQWRkZWRcbiAgICogLSBPYmplY3QgVGFncyBEZWxldGVkXG4gICAqL1xuICBwdWJsaWMgZW5hYmxlRXZlbnRCcmlkZ2VOb3RpZmljYXRpb24oKSB7XG4gICAgdGhpcy53aXRoTm90aWZpY2F0aW9ucygobm90aWZpY2F0aW9ucykgPT5cbiAgICAgIG5vdGlmaWNhdGlvbnMuZW5hYmxlRXZlbnRCcmlkZ2VOb3RpZmljYXRpb24oKSxcbiAgICApO1xuICB9XG5cbiAgcHJpdmF0ZSBncmFudChcbiAgICBncmFudGVlOiBpYW0uSUdyYW50YWJsZSxcbiAgICBidWNrZXRBY3Rpb25zOiBzdHJpbmdbXSxcbiAgICBfa2V5QWN0aW9uczogc3RyaW5nW10sXG4gICAgcmVzb3VyY2VBcm46IHN0cmluZyxcbiAgICAuLi5vdGhlclJlc291cmNlQXJuczogc3RyaW5nW11cbiAgKSB7XG4gICAgY29uc3QgcmVzb3VyY2VzID0gW3Jlc291cmNlQXJuLCAuLi5vdGhlclJlc291cmNlQXJuc107XG5cbiAgICBjb25zdCByZXQgPSBpYW0uR3JhbnQuYWRkVG9QcmluY2lwYWxPclJlc291cmNlKHtcbiAgICAgIGdyYW50ZWUsXG4gICAgICBhY3Rpb25zOiBidWNrZXRBY3Rpb25zLFxuICAgICAgcmVzb3VyY2VBcm5zOiByZXNvdXJjZXMsXG4gICAgICByZXNvdXJjZTogdGhpcyxcbiAgICB9KTtcblxuICAgIC8vIFRPRE86IHJlLWFkZCBLTVMgc3VwcG9ydFxuICAgIC8vIGlmICh0aGlzLmVuY3J5cHRpb25LZXkgJiYga2V5QWN0aW9ucyAmJiBrZXlBY3Rpb25zLmxlbmd0aCAhPT0gMCkge1xuICAgIC8vICAgdGhpcy5lbmNyeXB0aW9uS2V5LmdyYW50KGdyYW50ZWUsIC4uLmtleUFjdGlvbnMpO1xuICAgIC8vIH1cblxuICAgIHJldHVybiByZXQ7XG4gIH1cblxuICBwcml2YXRlIGdldCB3cml0ZUFjdGlvbnMoKTogc3RyaW5nW10ge1xuICAgIHJldHVybiBbLi4ucGVybXMuQlVDS0VUX0RFTEVURV9BQ1RJT05TLCAuLi5wZXJtcy5CVUNLRVRfUFVUX0FDVElPTlNdO1xuICB9XG5cbiAgLyoqXG4gICAqIEFkZCBhIHNvdXJjZSB0byB0aGUgYnVja2V0LlxuICAgKlxuICAgKiBAcGFyYW0gcHJvcHMgVGhlIHByb3BlcnRpZXMgb2YgdGhlIHNvdXJjZSB0byBhZGRcbiAgICovXG4gIHB1YmxpYyBhZGRTb3VyY2UocHJvcHM6IEFkZFNvdXJjZU9wdGlvbnMsIHNvdXJjZUlkPzogc3RyaW5nKTogc3RyaW5nIHtcbiAgICBpZiAodGhpcy52ZXJzaW9uZWQpIHtcbiAgICAgIC8qKlxuICAgICAgICogSWYgeW91IGVuYWJsZSB2ZXJzaW9uaW5nIG9uIGEgYnVja2V0IGZvciB0aGUgZmlyc3QgdGltZSwgaXQgbWlnaHQgdGFrZSB1cCB0byAxNSBtaW51dGVzXG4gICAgICAgKiBmb3IgdGhlIGNoYW5nZSB0byBiZSBmdWxseSBwcm9wYWdhdGVkLiBXZSByZWNvbW1lbmQgdGhhdCB5b3Ugd2FpdCBmb3IgMTUgbWludXRlcyBhZnRlclxuICAgICAgICogZW5hYmxpbmcgdmVyc2lvbmluZyBiZWZvcmUgaXNzdWluZyB3cml0ZSBvcGVyYXRpb25zIChQVVQgb3IgREVMRVRFKSBvbiBvYmplY3RzIGluIHRoZSBidWNrZXQuXG4gICAgICAgKlxuICAgICAgICogV3JpdGUgb3BlcmF0aW9ucyBpc3N1ZWQgYmVmb3JlIHRoaXMgY29udmVyc2lvbiBpcyBjb21wbGV0ZSBtYXkgYXBwbHkgdG8gdW52ZXJzaW9uZWQgb2JqZWN0cy5cbiAgICAgICAqL1xuICAgICAgaWYgKCF0aGlzLnNvdXJjZVNsZWVwKSB7XG4gICAgICAgIHRoaXMuc291cmNlU2xlZXAgPSBuZXcgc2xlZXAuU2xlZXAodGhpcywgXCJWZXJzaW9uaW5nU2xlZXBcIiwge1xuICAgICAgICAgIGNyZWF0ZUR1cmF0aW9uOiBcIjE1bVwiLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9XG4gICAgY29uc3QgaW5kZXhlZFNvdXJjZSA9IHRoaXMuc291cmNlcy5maW5kKFxuICAgICAgKHNvdXJjZUluZGV4KSA9PiBzb3VyY2VJbmRleC5wcm9wcyA9PT0gcHJvcHMsXG4gICAgKTtcbiAgICBpZiAoaW5kZXhlZFNvdXJjZSkge1xuICAgICAgaWYgKHNvdXJjZUlkICYmIHNvdXJjZUlkICE9PSBpbmRleGVkU291cmNlLmlkKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICBgRHVwbGljYXRlIGJ1Y2tldCBzb3VyY2UgZm9yICR7aW5kZXhlZFNvdXJjZS5pZH0gYW5kICR7c291cmNlSWR9LmAsXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgICByZXR1cm4gaW5kZXhlZFNvdXJjZS5pZDtcbiAgICB9XG4gICAgY29uc3QgbmV4dEluZGV4ID0gdGhpcy5zb3VyY2VzLmxlbmd0aDtcbiAgICBjb25zdCBpZCA9IHNvdXJjZUlkID8/IGBzb3VyY2UtJHtuZXh0SW5kZXh9YDtcbiAgICAvLyBlbnN1cmUgaWQgKGlmIHByb3ZpZGVkKSBpcyB1bmlxdWUgd2l0aGluIEJ1Y2tldFxuICAgIGlmICh0aGlzLnNvdXJjZXMuc29tZSgoc291cmNlSW5kZXgpID0+IHNvdXJjZUluZGV4LmlkID09PSBpZCkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgYER1cGxpY2F0ZSBzb3VyY2UgaWQgJHtpZH0uIFNvdXJjZUlkcyBtdXN0IGJlIHVuaXF1ZSB3aXRoaW4gYSBCdWNrZXQuYCxcbiAgICAgICk7XG4gICAgfVxuICAgIHRoaXMuc291cmNlcy5wdXNoKHtcbiAgICAgIHByb3BzOiB7XG4gICAgICAgIC4uLnByb3BzLFxuICAgICAgICBidWNrZXQ6IHRoaXMsXG4gICAgICAgIGRlcGVuZHNPbjogdGhpcy5zb3VyY2VTbGVlcCA/IFt0aGlzLnNvdXJjZVNsZWVwXSA6IHVuZGVmaW5lZCxcbiAgICAgIH0sXG4gICAgICBpZCxcbiAgICB9KTtcbiAgICByZXR1cm4gaWQ7XG4gIH1cblxuICBwdWJsaWMgaXNXZWJzaXRlKCk6IHRoaXMgaXMge1xuICAgIHdlYnNpdGVEb21haW5OYW1lOiBzdHJpbmc7XG4gICAgYnVja2V0T3V0cHV0czogeyB3ZWJzaXRlVXJsOiBzdHJpbmc7IHdlYnNpdGVEb21haW5OYW1lOiBzdHJpbmcgfTtcbiAgfSB7XG4gICAgcmV0dXJuIHRoaXMuX2lzV2Vic2l0ZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGUgaHR0cHMgVVJMIG9mIGFuIFMzIG9iamVjdC4gU3BlY2lmeSBgcmVnaW9uYWw6IGZhbHNlYCBhdCB0aGUgb3B0aW9uc1xuICAgKiBmb3Igbm9uLXJlZ2lvbmFsIFVSTHMuIEZvciBleGFtcGxlOlxuICAgKlxuICAgKiAtIGBodHRwczovL3MzLnVzLXdlc3QtMS5hbWF6b25hd3MuY29tL29ubHlidWNrZXRgXG4gICAqIC0gYGh0dHBzOi8vczMudXMtd2VzdC0xLmFtYXpvbmF3cy5jb20vYnVja2V0L2tleWBcbiAgICogLSBgaHR0cHM6Ly9zMy5jbi1ub3J0aC0xLmFtYXpvbmF3cy5jb20uY24vY2hpbmEtYnVja2V0L215a2V5YFxuICAgKlxuICAgKiBAcGFyYW0ga2V5IFRoZSBTMyBrZXkgb2YgdGhlIG9iamVjdC4gSWYgbm90IHNwZWNpZmllZCwgdGhlIFVSTCBvZiB0aGVcbiAgICogICAgICBidWNrZXQgaXMgcmV0dXJuZWQuXG4gICAqIEByZXR1cm5zIGFuIE9iamVjdFMzVXJsIHRva2VuXG4gICAqL1xuICBwdWJsaWMgdXJsRm9yT2JqZWN0KGtleT86IHN0cmluZyk6IHN0cmluZyB7XG4gICAgY29uc3Qgc3RhY2sgPSBBd3NTdGFjay5vZkF3c0NvbnN0cnVjdCh0aGlzKTtcbiAgICBjb25zdCBwcmVmaXggPSBgaHR0cHM6Ly9zMy4ke3RoaXMuZW52LnJlZ2lvbn0uJHtzdGFjay51cmxTdWZmaXh9L2A7XG4gICAgaWYgKHR5cGVvZiBrZXkgIT09IFwic3RyaW5nXCIpIHtcbiAgICAgIHJldHVybiB0aGlzLnVybEpvaW4ocHJlZml4LCB0aGlzLmJ1Y2tldE5hbWUpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy51cmxKb2luKHByZWZpeCwgdGhpcy5idWNrZXROYW1lLCBrZXkpO1xuICB9XG5cbiAgLyoqXG4gICAqIFRoZSBTMyBVUkwgb2YgYW4gUzMgb2JqZWN0LiBGb3IgZXhhbXBsZTpcbiAgICpcbiAgICogLSBgczM6Ly9vbmx5YnVja2V0YFxuICAgKiAtIGBzMzovL2J1Y2tldC9rZXlgXG4gICAqXG4gICAqIEBwYXJhbSBrZXkgVGhlIFMzIGtleSBvZiB0aGUgb2JqZWN0LiBJZiBub3Qgc3BlY2lmaWVkLCB0aGUgUzMgVVJMIG9mIHRoZVxuICAgKiAgICAgIGJ1Y2tldCBpcyByZXR1cm5lZC5cbiAgICogQHJldHVybnMgYW4gT2JqZWN0UzNVcmwgdG9rZW5cbiAgICovXG4gIHB1YmxpYyBzM1VybEZvck9iamVjdChrZXk/OiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIGNvbnN0IHByZWZpeCA9IFwiczM6Ly9cIjtcbiAgICBpZiAodHlwZW9mIGtleSAhPT0gXCJzdHJpbmdcIikge1xuICAgICAgcmV0dXJuIHRoaXMudXJsSm9pbihwcmVmaXgsIHRoaXMuYnVja2V0TmFtZSk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLnVybEpvaW4ocHJlZml4LCB0aGlzLmJ1Y2tldE5hbWUsIGtleSk7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyBhbiBBUk4gdGhhdCByZXByZXNlbnRzIGFsbCBvYmplY3RzIHdpdGhpbiB0aGUgYnVja2V0IHRoYXQgbWF0Y2hcbiAgICogdGhlIGtleSBwYXR0ZXJuIHNwZWNpZmllZC4gVG8gcmVwcmVzZW50IGFsbCBrZXlzLCBzcGVjaWZ5IGBgXCIqXCJgYC5cbiAgICpcbiAgICogSWYgeW91IG5lZWQgdG8gc3BlY2lmeSBhIGtleVBhdHRlcm4gd2l0aCBtdWx0aXBsZSBjb21wb25lbnRzLCBjb25jYXRlbmF0ZSB0aGVtIGludG8gYSBzaW5nbGUgc3RyaW5nLCBlLmcuOlxuICAgKlxuICAgKiAgIGFybkZvck9iamVjdHMoYGhvbWUvJHt0ZWFtfS8ke3VzZXJ9LypgKVxuICAgKlxuICAgKi9cbiAgcHVibGljIGFybkZvck9iamVjdHMoa2V5UGF0dGVybjogc3RyaW5nKTogc3RyaW5nIHtcbiAgICByZXR1cm4gYCR7dGhpcy5yZXNvdXJjZS5hcm59LyR7a2V5UGF0dGVybn1gO1xuICB9XG5cbiAgLy8gaHR0cHM6Ly9naXRodWIuY29tL2F3cy9hd3MtY2RrL2Jsb2IvdjIuMTQwLjAvcGFja2FnZXMvYXdzLWNkay1saWIvYXdzLXMzL2xpYi9idWNrZXQudHMjTDk1M1xuICBwcml2YXRlIHVybEpvaW4oLi4uY29tcG9uZW50czogc3RyaW5nW10pOiBzdHJpbmcge1xuICAgIHJldHVybiBjb21wb25lbnRzLnJlZHVjZSgocmVzdWx0LCBjb21wb25lbnQpID0+IHtcbiAgICAgIGlmIChyZXN1bHQuZW5kc1dpdGgoXCIvXCIpKSB7XG4gICAgICAgIHJlc3VsdCA9IHJlc3VsdC5zbGljZSgwLCAtMSk7XG4gICAgICB9XG4gICAgICBpZiAoY29tcG9uZW50LnN0YXJ0c1dpdGgoXCIvXCIpKSB7XG4gICAgICAgIGNvbXBvbmVudCA9IGNvbXBvbmVudC5zbGljZSgxKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBgJHtyZXN1bHR9LyR7Y29tcG9uZW50fWA7XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogQWRkcyBhbiBpYW0gc3RhdGVtZW50IHRvIGVuZm9yY2UgU1NMIHJlcXVlc3RzIG9ubHkuXG4gICAqL1xuICBwcml2YXRlIGVuZm9yY2VTU0xTdGF0ZW1lbnQoKSB7XG4gICAgY29uc3Qgc3RhdGVtZW50ID0gbmV3IGlhbS5Qb2xpY3lTdGF0ZW1lbnQoe1xuICAgICAgYWN0aW9uczogW1wiczM6KlwiXSxcbiAgICAgIGNvbmRpdGlvbjogW1xuICAgICAgICB7XG4gICAgICAgICAgdGVzdDogXCJCb29sXCIsXG4gICAgICAgICAgdmFyaWFibGU6IFwiYXdzOlNlY3VyZVRyYW5zcG9ydFwiLFxuICAgICAgICAgIHZhbHVlczogW1wiZmFsc2VcIl0sXG4gICAgICAgIH0sXG4gICAgICBdLFxuICAgICAgZWZmZWN0OiBpYW0uRWZmZWN0LkRFTlksXG4gICAgICByZXNvdXJjZXM6IFt0aGlzLnJlc291cmNlLmFybiwgdGhpcy5hcm5Gb3JPYmplY3RzKFwiKlwiKV0sXG4gICAgICBwcmluY2lwYWxzOiBbbmV3IGlhbS5BbnlQcmluY2lwYWwoKV0sXG4gICAgfSk7XG4gICAgdGhpcy5hZGRUb1Jlc291cmNlUG9saWN5KHN0YXRlbWVudCk7XG4gIH1cblxuICAvKipcbiAgICogQWRkcyBhbiBpYW0gc3RhdGVtZW50IHRvIGFsbG93IHJlcXVlc3RzIHdpdGggYSBtaW5pbXVtIFRMU1xuICAgKiB2ZXJzaW9uIG9ubHkuXG4gICAqL1xuICBwcml2YXRlIG1pbmltdW1UTFNWZXJzaW9uU3RhdGVtZW50KG1pbmltdW1UTFNWZXJzaW9uPzogbnVtYmVyKSB7XG4gICAgaWYgKCFtaW5pbXVtVExTVmVyc2lvbikgcmV0dXJuO1xuICAgIGNvbnN0IHN0YXRlbWVudCA9IG5ldyBpYW0uUG9saWN5U3RhdGVtZW50KHtcbiAgICAgIGFjdGlvbnM6IFtcInMzOipcIl0sXG4gICAgICBjb25kaXRpb246IFtcbiAgICAgICAge1xuICAgICAgICAgIHRlc3Q6IFwiTnVtZXJpY0xlc3NUaGFuXCIsXG4gICAgICAgICAgdmFyaWFibGU6IFwiczM6VGxzVmVyc2lvblwiLFxuICAgICAgICAgIHZhbHVlczogW21pbmltdW1UTFNWZXJzaW9uLnRvU3RyaW5nKCldLFxuICAgICAgICB9LFxuICAgICAgXSxcbiAgICAgIGVmZmVjdDogaWFtLkVmZmVjdC5ERU5ZLFxuICAgICAgcmVzb3VyY2VzOiBbdGhpcy5yZXNvdXJjZS5hcm4sIHRoaXMuYXJuRm9yT2JqZWN0cyhcIipcIildLFxuICAgICAgcHJpbmNpcGFsczogW25ldyBpYW0uQW55UHJpbmNpcGFsKCldLFxuICAgIH0pO1xuICAgIHRoaXMuYWRkVG9SZXNvdXJjZVBvbGljeShzdGF0ZW1lbnQpO1xuICB9XG5cbiAgLyoqXG4gICAqIEFkZHMgcmVzb3VyY2UgdG8gdGhlIFRlcnJhZm9ybSBKU09OIG91dHB1dCBhdCBTeW50aCB0aW1lLlxuICAgKlxuICAgKiBjYWxsZWQgYnkgVGVycmFmb3JtU3RhY2sucHJlcGFyZVN0YWNrKClcbiAgICovXG4gIHB1YmxpYyB0b1RlcnJhZm9ybSgpOiBhbnkge1xuICAgIC8qKlxuICAgICAqIEEgcHJlcGFyaW5nIHJlc29sdmUgbWlnaHQgYWRkIG5ldyByZXNvdXJjZXMgdG8gdGhlIHN0YWNrXG4gICAgICpcbiAgICAgKiBzaG91bGQgbm90IGFkZCByZXNvdXJjZXMgaWYgbm8gYnVja2V0IHNvdXJjZXMgYXJlIGRlZmluZWRcbiAgICAgKi9cbiAgICBpZiAoT2JqZWN0LmtleXModGhpcy5zb3VyY2VzKS5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybiB7fTtcbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IHNvdXJjZSBvZiB0aGlzLnNvdXJjZXMpIHtcbiAgICAgIC8vIFRPRE86IElkZWFsbHkgd2Ugc2hvdWxkIGhhdmUgdXNlZCBJUmVzb2x2YWJsZS5yZXNvbHZlIGFuZCB1c2UgdGhlIElSZXNvbHZlQ29udGV4dC5wcmVwYXJpbmcgZmxhZ1xuICAgICAgLy8gcmVmOiBodHRwczovL2dpdGh1Yi5jb20vYXdzL2F3cy1jZGsvYmxvYi92Mi4xNzAuMC9wYWNrYWdlcy9hd3MtY2RrLWxpYi9hd3MtaWFtL2xpYi9wb2xpY3ktZG9jdW1lbnQudHMjTDQ4XG4gICAgICBpZiAodGhpcy5ub2RlLnRyeUZpbmRDaGlsZChzb3VyY2UuaWQpKSBjb250aW51ZTsgLy8gaWdub3JlIGlmIGFscmVhZHkgZ2VuZXJhdGVkXG4gICAgICBuZXcgQnVja2V0U291cmNlKHRoaXMsIHNvdXJjZS5pZCwgc291cmNlLnByb3BzKTtcbiAgICB9XG4gICAgcmV0dXJuIHt9O1xuICB9XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQWRkU291cmNlT3B0aW9ucyB7XG4gIC8qKlxuICAgKiBMb2NhbCBwYXRoIHRvIHRoZSBzb3VyY2UgZmlsZXNcbiAgICovXG4gIHJlYWRvbmx5IHBhdGg6IHN0cmluZztcbiAgLyoqXG4gICAqIFByZWZpeCB0byBhZGQgdG8gdGhlIHVwbG9hZGVkIG9iamVjdHNcbiAgICovXG4gIHJlYWRvbmx5IHByZWZpeD86IHN0cmluZztcbn1cblxuLy8gcHJpdmF0ZSBpbnRlcmZhY2UgdG8gaW5kZXggQnVja2V0IHNvdXJjZXMgYnkgaWRcbmludGVyZmFjZSBTb3VyY2VJbmRleCB7XG4gIHByb3BzOiBCdWNrZXRTb3VyY2VQcm9wcztcbiAgaWQ6IHN0cmluZztcbn1cblxuLyoqXG4gKiBTdG9yYWdlIGNsYXNzIHRvIG1vdmUgYW4gb2JqZWN0IHRvXG4gKi9cbmV4cG9ydCBlbnVtIFN0b3JhZ2VDbGFzcyB7XG4gIC8qKlxuICAgKiBTdG9yYWdlIGNsYXNzIGZvciBkYXRhIHRoYXQgaXMgYWNjZXNzZWQgbGVzcyBmcmVxdWVudGx5LCBidXQgcmVxdWlyZXMgcmFwaWRcbiAgICogYWNjZXNzIHdoZW4gbmVlZGVkLlxuICAgKlxuICAgKiBIYXMgbG93ZXIgYXZhaWxhYmlsaXR5IHRoYW4gU3RhbmRhcmQgc3RvcmFnZS5cbiAgICovXG4gIElORlJFUVVFTlRfQUNDRVNTID0gXCJTVEFOREFSRF9JQVwiLFxuXG4gIC8qKlxuICAgKiBJbmZyZXF1ZW50IEFjY2VzcyB0aGF0J3Mgb25seSBzdG9yZWQgaW4gb25lIGF2YWlsYWJpbGl0eSB6b25lLlxuICAgKlxuICAgKiBIYXMgbG93ZXIgYXZhaWxhYmlsaXR5IHRoYW4gc3RhbmRhcmQgSW5mcmVxdWVudEFjY2Vzcy5cbiAgICovXG4gIE9ORV9aT05FX0lORlJFUVVFTlRfQUNDRVNTID0gXCJPTkVaT05FX0lBXCIsXG5cbiAgLyoqXG4gICAqIFN0b3JhZ2UgY2xhc3MgZm9yIGxvbmctdGVybSBhcmNoaXZhbCB0aGF0IGNhbiB0YWtlIGJldHdlZW4gbWludXRlcyBhbmRcbiAgICogaG91cnMgdG8gYWNjZXNzLlxuICAgKlxuICAgKiBVc2UgZm9yIGFyY2hpdmVzIHdoZXJlIHBvcnRpb25zIG9mIHRoZSBkYXRhIG1pZ2h0IG5lZWQgdG8gYmUgcmV0cmlldmVkIGluXG4gICAqIG1pbnV0ZXMuIERhdGEgc3RvcmVkIGluIHRoZSBHTEFDSUVSIHN0b3JhZ2UgY2xhc3MgaGFzIGEgbWluaW11bSBzdG9yYWdlXG4gICAqIGR1cmF0aW9uIHBlcmlvZCBvZiA5MCBkYXlzIGFuZCBjYW4gYmUgYWNjZXNzZWQgaW4gYXMgbGl0dGxlIGFzIDEtNSBtaW51dGVzXG4gICAqIHVzaW5nIGV4cGVkaXRlZCByZXRyaWV2YWwuIElmIHlvdSBkZWxldGUgYW4gb2JqZWN0IGJlZm9yZSB0aGUgOTAtZGF5XG4gICAqIG1pbmltdW0sIHlvdSBhcmUgY2hhcmdlZCBmb3IgOTAgZGF5cy5cbiAgICovXG4gIEdMQUNJRVIgPSBcIkdMQUNJRVJcIixcblxuICAvKipcbiAgICogU3RvcmFnZSBjbGFzcyBmb3IgbG9uZy10ZXJtIGFyY2hpdmFsIHRoYXQgY2FuIGJlIGFjY2Vzc2VkIGluIGEgZmV3IG1pbGxpc2Vjb25kcy5cbiAgICpcbiAgICogSXQgaXMgaWRlYWwgZm9yIGRhdGEgdGhhdCBpcyBhY2Nlc3NlZCBvbmNlIG9yIHR3aWNlIHBlciBxdWFydGVyLCBhbmRcbiAgICogdGhhdCByZXF1aXJlcyBpbW1lZGlhdGUgYWNjZXNzLiBEYXRhIHN0b3JlZCBpbiB0aGUgR0xBQ0lFUl9JUiBzdG9yYWdlIGNsYXNzXG4gICAqIGhhcyBhIG1pbmltdW0gc3RvcmFnZSBkdXJhdGlvbiBwZXJpb2Qgb2YgOTAgZGF5cyBhbmQgY2FuIGJlIGFjY2Vzc2VkIGluXG4gICAqIGFzIG1pbGxpc2Vjb25kcy4gSWYgeW91IGRlbGV0ZSBhbiBvYmplY3QgYmVmb3JlIHRoZSA5MC1kYXkgbWluaW11bSxcbiAgICogeW91IGFyZSBjaGFyZ2VkIGZvciA5MCBkYXlzLlxuICAgKi9cbiAgR0xBQ0lFUl9JTlNUQU5UX1JFVFJJRVZBTCA9IFwiR0xBQ0lFUl9JUlwiLFxuXG4gIC8qKlxuICAgKiBVc2UgZm9yIGFyY2hpdmluZyBkYXRhIHRoYXQgcmFyZWx5IG5lZWRzIHRvIGJlIGFjY2Vzc2VkLiBEYXRhIHN0b3JlZCBpbiB0aGVcbiAgICogREVFUF9BUkNISVZFIHN0b3JhZ2UgY2xhc3MgaGFzIGEgbWluaW11bSBzdG9yYWdlIGR1cmF0aW9uIHBlcmlvZCBvZiAxODBcbiAgICogZGF5cyBhbmQgYSBkZWZhdWx0IHJldHJpZXZhbCB0aW1lIG9mIDEyIGhvdXJzLiBJZiB5b3UgZGVsZXRlIGFuIG9iamVjdFxuICAgKiBiZWZvcmUgdGhlIDE4MC1kYXkgbWluaW11bSwgeW91IGFyZSBjaGFyZ2VkIGZvciAxODAgZGF5cy4gRm9yIHByaWNpbmdcbiAgICogaW5mb3JtYXRpb24sIHNlZSBBbWF6b24gUzMgUHJpY2luZy5cbiAgICovXG4gIERFRVBfQVJDSElWRSA9IFwiREVFUF9BUkNISVZFXCIsXG5cbiAgLyoqXG4gICAqIFRoZSBJTlRFTExJR0VOVF9USUVSSU5HIHN0b3JhZ2UgY2xhc3MgaXMgZGVzaWduZWQgdG8gb3B0aW1pemUgc3RvcmFnZSBjb3N0c1xuICAgKiBieSBhdXRvbWF0aWNhbGx5IG1vdmluZyBkYXRhIHRvIHRoZSBtb3N0IGNvc3QtZWZmZWN0aXZlIHN0b3JhZ2UgYWNjZXNzXG4gICAqIHRpZXIsIHdpdGhvdXQgcGVyZm9ybWFuY2UgaW1wYWN0IG9yIG9wZXJhdGlvbmFsIG92ZXJoZWFkLlxuICAgKiBJTlRFTExJR0VOVF9USUVSSU5HIGRlbGl2ZXJzIGF1dG9tYXRpYyBjb3N0IHNhdmluZ3MgYnkgbW92aW5nIGRhdGEgb24gYVxuICAgKiBncmFudWxhciBvYmplY3QgbGV2ZWwgYmV0d2VlbiB0d28gYWNjZXNzIHRpZXJzLCBhIGZyZXF1ZW50IGFjY2VzcyB0aWVyIGFuZFxuICAgKiBhIGxvd2VyLWNvc3QgaW5mcmVxdWVudCBhY2Nlc3MgdGllciwgd2hlbiBhY2Nlc3MgcGF0dGVybnMgY2hhbmdlLiBUaGVcbiAgICogSU5URUxMSUdFTlRfVElFUklORyBzdG9yYWdlIGNsYXNzIGlzIGlkZWFsIGlmIHlvdSB3YW50IHRvIG9wdGltaXplIHN0b3JhZ2VcbiAgICogY29zdHMgYXV0b21hdGljYWxseSBmb3IgbG9uZy1saXZlZCBkYXRhIHdoZW4gYWNjZXNzIHBhdHRlcm5zIGFyZSB1bmtub3duIG9yXG4gICAqIHVucHJlZGljdGFibGUuXG4gICAqL1xuICBJTlRFTExJR0VOVF9USUVSSU5HID0gXCJJTlRFTExJR0VOVF9USUVSSU5HXCIsXG59XG5cbi8qKlxuICogTm90aWZpY2F0aW9uIGV2ZW50IHR5cGVzLlxuICogQGxpbmsgaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FtYXpvblMzL2xhdGVzdC91c2VyZ3VpZGUvbm90aWZpY2F0aW9uLWhvdy10by1ldmVudC10eXBlcy1hbmQtZGVzdGluYXRpb25zLmh0bWwjc3VwcG9ydGVkLW5vdGlmaWNhdGlvbi1ldmVudC10eXBlc1xuICovXG5leHBvcnQgZW51bSBFdmVudFR5cGUge1xuICAvKipcbiAgICogQW1hem9uIFMzIEFQSXMgc3VjaCBhcyBQVVQsIFBPU1QsIGFuZCBDT1BZIGNhbiBjcmVhdGUgYW4gb2JqZWN0LiBVc2luZ1xuICAgKiB0aGVzZSBldmVudCB0eXBlcywgeW91IGNhbiBlbmFibGUgbm90aWZpY2F0aW9uIHdoZW4gYW4gb2JqZWN0IGlzIGNyZWF0ZWRcbiAgICogdXNpbmcgYSBzcGVjaWZpYyBBUEksIG9yIHlvdSBjYW4gdXNlIHRoZSBzMzpPYmplY3RDcmVhdGVkOiogZXZlbnQgdHlwZSB0b1xuICAgKiByZXF1ZXN0IG5vdGlmaWNhdGlvbiByZWdhcmRsZXNzIG9mIHRoZSBBUEkgdGhhdCB3YXMgdXNlZCB0byBjcmVhdGUgYW5cbiAgICogb2JqZWN0LlxuICAgKi9cbiAgT0JKRUNUX0NSRUFURUQgPSBcInMzOk9iamVjdENyZWF0ZWQ6KlwiLFxuXG4gIC8qKlxuICAgKiBBbWF6b24gUzMgQVBJcyBzdWNoIGFzIFBVVCwgUE9TVCwgYW5kIENPUFkgY2FuIGNyZWF0ZSBhbiBvYmplY3QuIFVzaW5nXG4gICAqIHRoZXNlIGV2ZW50IHR5cGVzLCB5b3UgY2FuIGVuYWJsZSBub3RpZmljYXRpb24gd2hlbiBhbiBvYmplY3QgaXMgY3JlYXRlZFxuICAgKiB1c2luZyBhIHNwZWNpZmljIEFQSSwgb3IgeW91IGNhbiB1c2UgdGhlIHMzOk9iamVjdENyZWF0ZWQ6KiBldmVudCB0eXBlIHRvXG4gICAqIHJlcXVlc3Qgbm90aWZpY2F0aW9uIHJlZ2FyZGxlc3Mgb2YgdGhlIEFQSSB0aGF0IHdhcyB1c2VkIHRvIGNyZWF0ZSBhblxuICAgKiBvYmplY3QuXG4gICAqL1xuICBPQkpFQ1RfQ1JFQVRFRF9QVVQgPSBcInMzOk9iamVjdENyZWF0ZWQ6UHV0XCIsXG5cbiAgLyoqXG4gICAqIEFtYXpvbiBTMyBBUElzIHN1Y2ggYXMgUFVULCBQT1NULCBhbmQgQ09QWSBjYW4gY3JlYXRlIGFuIG9iamVjdC4gVXNpbmdcbiAgICogdGhlc2UgZXZlbnQgdHlwZXMsIHlvdSBjYW4gZW5hYmxlIG5vdGlmaWNhdGlvbiB3aGVuIGFuIG9iamVjdCBpcyBjcmVhdGVkXG4gICAqIHVzaW5nIGEgc3BlY2lmaWMgQVBJLCBvciB5b3UgY2FuIHVzZSB0aGUgczM6T2JqZWN0Q3JlYXRlZDoqIGV2ZW50IHR5cGUgdG9cbiAgICogcmVxdWVzdCBub3RpZmljYXRpb24gcmVnYXJkbGVzcyBvZiB0aGUgQVBJIHRoYXQgd2FzIHVzZWQgdG8gY3JlYXRlIGFuXG4gICAqIG9iamVjdC5cbiAgICovXG4gIE9CSkVDVF9DUkVBVEVEX1BPU1QgPSBcInMzOk9iamVjdENyZWF0ZWQ6UG9zdFwiLFxuXG4gIC8qKlxuICAgKiBBbWF6b24gUzMgQVBJcyBzdWNoIGFzIFBVVCwgUE9TVCwgYW5kIENPUFkgY2FuIGNyZWF0ZSBhbiBvYmplY3QuIFVzaW5nXG4gICAqIHRoZXNlIGV2ZW50IHR5cGVzLCB5b3UgY2FuIGVuYWJsZSBub3RpZmljYXRpb24gd2hlbiBhbiBvYmplY3QgaXMgY3JlYXRlZFxuICAgKiB1c2luZyBhIHNwZWNpZmljIEFQSSwgb3IgeW91IGNhbiB1c2UgdGhlIHMzOk9iamVjdENyZWF0ZWQ6KiBldmVudCB0eXBlIHRvXG4gICAqIHJlcXVlc3Qgbm90aWZpY2F0aW9uIHJlZ2FyZGxlc3Mgb2YgdGhlIEFQSSB0aGF0IHdhcyB1c2VkIHRvIGNyZWF0ZSBhblxuICAgKiBvYmplY3QuXG4gICAqL1xuICBPQkpFQ1RfQ1JFQVRFRF9DT1BZID0gXCJzMzpPYmplY3RDcmVhdGVkOkNvcHlcIixcblxuICAvKipcbiAgICogQW1hem9uIFMzIEFQSXMgc3VjaCBhcyBQVVQsIFBPU1QsIGFuZCBDT1BZIGNhbiBjcmVhdGUgYW4gb2JqZWN0LiBVc2luZ1xuICAgKiB0aGVzZSBldmVudCB0eXBlcywgeW91IGNhbiBlbmFibGUgbm90aWZpY2F0aW9uIHdoZW4gYW4gb2JqZWN0IGlzIGNyZWF0ZWRcbiAgICogdXNpbmcgYSBzcGVjaWZpYyBBUEksIG9yIHlvdSBjYW4gdXNlIHRoZSBzMzpPYmplY3RDcmVhdGVkOiogZXZlbnQgdHlwZSB0b1xuICAgKiByZXF1ZXN0IG5vdGlmaWNhdGlvbiByZWdhcmRsZXNzIG9mIHRoZSBBUEkgdGhhdCB3YXMgdXNlZCB0byBjcmVhdGUgYW5cbiAgICogb2JqZWN0LlxuICAgKi9cbiAgT0JKRUNUX0NSRUFURURfQ09NUExFVEVfTVVMVElQQVJUX1VQTE9BRCA9IFwiczM6T2JqZWN0Q3JlYXRlZDpDb21wbGV0ZU11bHRpcGFydFVwbG9hZFwiLFxuXG4gIC8qKlxuICAgKiBCeSB1c2luZyB0aGUgT2JqZWN0UmVtb3ZlZCBldmVudCB0eXBlcywgeW91IGNhbiBlbmFibGUgbm90aWZpY2F0aW9uIHdoZW5cbiAgICogYW4gb2JqZWN0IG9yIGEgYmF0Y2ggb2Ygb2JqZWN0cyBpcyByZW1vdmVkIGZyb20gYSBidWNrZXQuXG4gICAqXG4gICAqIFlvdSBjYW4gcmVxdWVzdCBub3RpZmljYXRpb24gd2hlbiBhbiBvYmplY3QgaXMgZGVsZXRlZCBvciBhIHZlcnNpb25lZFxuICAgKiBvYmplY3QgaXMgcGVybWFuZW50bHkgZGVsZXRlZCBieSB1c2luZyB0aGUgczM6T2JqZWN0UmVtb3ZlZDpEZWxldGUgZXZlbnRcbiAgICogdHlwZS4gT3IgeW91IGNhbiByZXF1ZXN0IG5vdGlmaWNhdGlvbiB3aGVuIGEgZGVsZXRlIG1hcmtlciBpcyBjcmVhdGVkIGZvclxuICAgKiBhIHZlcnNpb25lZCBvYmplY3QgYnkgdXNpbmcgczM6T2JqZWN0UmVtb3ZlZDpEZWxldGVNYXJrZXJDcmVhdGVkLiBGb3JcbiAgICogaW5mb3JtYXRpb24gYWJvdXQgZGVsZXRpbmcgdmVyc2lvbmVkIG9iamVjdHMsIHNlZSBEZWxldGluZyBPYmplY3RcbiAgICogVmVyc2lvbnMuIFlvdSBjYW4gYWxzbyB1c2UgYSB3aWxkY2FyZCBzMzpPYmplY3RSZW1vdmVkOiogdG8gcmVxdWVzdFxuICAgKiBub3RpZmljYXRpb24gYW55dGltZSBhbiBvYmplY3QgaXMgZGVsZXRlZC5cbiAgICpcbiAgICogWW91IHdpbGwgbm90IHJlY2VpdmUgZXZlbnQgbm90aWZpY2F0aW9ucyBmcm9tIGF1dG9tYXRpYyBkZWxldGVzIGZyb21cbiAgICogbGlmZWN5Y2xlIHBvbGljaWVzIG9yIGZyb20gZmFpbGVkIG9wZXJhdGlvbnMuXG4gICAqL1xuICBPQkpFQ1RfUkVNT1ZFRCA9IFwiczM6T2JqZWN0UmVtb3ZlZDoqXCIsXG5cbiAgLyoqXG4gICAqIEJ5IHVzaW5nIHRoZSBPYmplY3RSZW1vdmVkIGV2ZW50IHR5cGVzLCB5b3UgY2FuIGVuYWJsZSBub3RpZmljYXRpb24gd2hlblxuICAgKiBhbiBvYmplY3Qgb3IgYSBiYXRjaCBvZiBvYmplY3RzIGlzIHJlbW92ZWQgZnJvbSBhIGJ1Y2tldC5cbiAgICpcbiAgICogWW91IGNhbiByZXF1ZXN0IG5vdGlmaWNhdGlvbiB3aGVuIGFuIG9iamVjdCBpcyBkZWxldGVkIG9yIGEgdmVyc2lvbmVkXG4gICAqIG9iamVjdCBpcyBwZXJtYW5lbnRseSBkZWxldGVkIGJ5IHVzaW5nIHRoZSBzMzpPYmplY3RSZW1vdmVkOkRlbGV0ZSBldmVudFxuICAgKiB0eXBlLiBPciB5b3UgY2FuIHJlcXVlc3Qgbm90aWZpY2F0aW9uIHdoZW4gYSBkZWxldGUgbWFya2VyIGlzIGNyZWF0ZWQgZm9yXG4gICAqIGEgdmVyc2lvbmVkIG9iamVjdCBieSB1c2luZyBzMzpPYmplY3RSZW1vdmVkOkRlbGV0ZU1hcmtlckNyZWF0ZWQuIEZvclxuICAgKiBpbmZvcm1hdGlvbiBhYm91dCBkZWxldGluZyB2ZXJzaW9uZWQgb2JqZWN0cywgc2VlIERlbGV0aW5nIE9iamVjdFxuICAgKiBWZXJzaW9ucy4gWW91IGNhbiBhbHNvIHVzZSBhIHdpbGRjYXJkIHMzOk9iamVjdFJlbW92ZWQ6KiB0byByZXF1ZXN0XG4gICAqIG5vdGlmaWNhdGlvbiBhbnl0aW1lIGFuIG9iamVjdCBpcyBkZWxldGVkLlxuICAgKlxuICAgKiBZb3Ugd2lsbCBub3QgcmVjZWl2ZSBldmVudCBub3RpZmljYXRpb25zIGZyb20gYXV0b21hdGljIGRlbGV0ZXMgZnJvbVxuICAgKiBsaWZlY3ljbGUgcG9saWNpZXMgb3IgZnJvbSBmYWlsZWQgb3BlcmF0aW9ucy5cbiAgICovXG4gIE9CSkVDVF9SRU1PVkVEX0RFTEVURSA9IFwiczM6T2JqZWN0UmVtb3ZlZDpEZWxldGVcIixcblxuICAvKipcbiAgICogQnkgdXNpbmcgdGhlIE9iamVjdFJlbW92ZWQgZXZlbnQgdHlwZXMsIHlvdSBjYW4gZW5hYmxlIG5vdGlmaWNhdGlvbiB3aGVuXG4gICAqIGFuIG9iamVjdCBvciBhIGJhdGNoIG9mIG9iamVjdHMgaXMgcmVtb3ZlZCBmcm9tIGEgYnVja2V0LlxuICAgKlxuICAgKiBZb3UgY2FuIHJlcXVlc3Qgbm90aWZpY2F0aW9uIHdoZW4gYW4gb2JqZWN0IGlzIGRlbGV0ZWQgb3IgYSB2ZXJzaW9uZWRcbiAgICogb2JqZWN0IGlzIHBlcm1hbmVudGx5IGRlbGV0ZWQgYnkgdXNpbmcgdGhlIHMzOk9iamVjdFJlbW92ZWQ6RGVsZXRlIGV2ZW50XG4gICAqIHR5cGUuIE9yIHlvdSBjYW4gcmVxdWVzdCBub3RpZmljYXRpb24gd2hlbiBhIGRlbGV0ZSBtYXJrZXIgaXMgY3JlYXRlZCBmb3JcbiAgICogYSB2ZXJzaW9uZWQgb2JqZWN0IGJ5IHVzaW5nIHMzOk9iamVjdFJlbW92ZWQ6RGVsZXRlTWFya2VyQ3JlYXRlZC4gRm9yXG4gICAqIGluZm9ybWF0aW9uIGFib3V0IGRlbGV0aW5nIHZlcnNpb25lZCBvYmplY3RzLCBzZWUgRGVsZXRpbmcgT2JqZWN0XG4gICAqIFZlcnNpb25zLiBZb3UgY2FuIGFsc28gdXNlIGEgd2lsZGNhcmQgczM6T2JqZWN0UmVtb3ZlZDoqIHRvIHJlcXVlc3RcbiAgICogbm90aWZpY2F0aW9uIGFueXRpbWUgYW4gb2JqZWN0IGlzIGRlbGV0ZWQuXG4gICAqXG4gICAqIFlvdSB3aWxsIG5vdCByZWNlaXZlIGV2ZW50IG5vdGlmaWNhdGlvbnMgZnJvbSBhdXRvbWF0aWMgZGVsZXRlcyBmcm9tXG4gICAqIGxpZmVjeWNsZSBwb2xpY2llcyBvciBmcm9tIGZhaWxlZCBvcGVyYXRpb25zLlxuICAgKi9cbiAgT0JKRUNUX1JFTU9WRURfREVMRVRFX01BUktFUl9DUkVBVEVEID0gXCJzMzpPYmplY3RSZW1vdmVkOkRlbGV0ZU1hcmtlckNyZWF0ZWRcIixcblxuICAvKipcbiAgICogVXNpbmcgcmVzdG9yZSBvYmplY3QgZXZlbnQgdHlwZXMgeW91IGNhbiByZWNlaXZlIG5vdGlmaWNhdGlvbnMgZm9yXG4gICAqIGluaXRpYXRpb24gYW5kIGNvbXBsZXRpb24gd2hlbiByZXN0b3Jpbmcgb2JqZWN0cyBmcm9tIHRoZSBTMyBHbGFjaWVyXG4gICAqIHN0b3JhZ2UgY2xhc3MuXG4gICAqXG4gICAqIFlvdSB1c2UgczM6T2JqZWN0UmVzdG9yZTpQb3N0IHRvIHJlcXVlc3Qgbm90aWZpY2F0aW9uIG9mIG9iamVjdCByZXN0b3JhdGlvblxuICAgKiBpbml0aWF0aW9uLlxuICAgKi9cbiAgT0JKRUNUX1JFU1RPUkVfUE9TVCA9IFwiczM6T2JqZWN0UmVzdG9yZTpQb3N0XCIsXG5cbiAgLyoqXG4gICAqIFVzaW5nIHJlc3RvcmUgb2JqZWN0IGV2ZW50IHR5cGVzIHlvdSBjYW4gcmVjZWl2ZSBub3RpZmljYXRpb25zIGZvclxuICAgKiBpbml0aWF0aW9uIGFuZCBjb21wbGV0aW9uIHdoZW4gcmVzdG9yaW5nIG9iamVjdHMgZnJvbSB0aGUgUzMgR2xhY2llclxuICAgKiBzdG9yYWdlIGNsYXNzLlxuICAgKlxuICAgKiBZb3UgdXNlIHMzOk9iamVjdFJlc3RvcmU6Q29tcGxldGVkIHRvIHJlcXVlc3Qgbm90aWZpY2F0aW9uIG9mXG4gICAqIHJlc3RvcmF0aW9uIGNvbXBsZXRpb24uXG4gICAqL1xuICBPQkpFQ1RfUkVTVE9SRV9DT01QTEVURUQgPSBcInMzOk9iamVjdFJlc3RvcmU6Q29tcGxldGVkXCIsXG5cbiAgLyoqXG4gICAqIFVzaW5nIHJlc3RvcmUgb2JqZWN0IGV2ZW50IHR5cGVzIHlvdSBjYW4gcmVjZWl2ZSBub3RpZmljYXRpb25zIGZvclxuICAgKiBpbml0aWF0aW9uIGFuZCBjb21wbGV0aW9uIHdoZW4gcmVzdG9yaW5nIG9iamVjdHMgZnJvbSB0aGUgUzMgR2xhY2llclxuICAgKiBzdG9yYWdlIGNsYXNzLlxuICAgKlxuICAgKiBZb3UgdXNlIHMzOk9iamVjdFJlc3RvcmU6RGVsZXRlIHRvIHJlcXVlc3Qgbm90aWZpY2F0aW9uIG9mXG4gICAqIHJlc3RvcmF0aW9uIGNvbXBsZXRpb24uXG4gICAqL1xuICBPQkpFQ1RfUkVTVE9SRV9ERUxFVEUgPSBcInMzOk9iamVjdFJlc3RvcmU6RGVsZXRlXCIsXG5cbiAgLyoqXG4gICAqIFlvdSBjYW4gdXNlIHRoaXMgZXZlbnQgdHlwZSB0byByZXF1ZXN0IEFtYXpvbiBTMyB0byBzZW5kIGEgbm90aWZpY2F0aW9uXG4gICAqIG1lc3NhZ2Ugd2hlbiBBbWF6b24gUzMgZGV0ZWN0cyB0aGF0IGFuIG9iamVjdCBvZiB0aGUgUlJTIHN0b3JhZ2UgY2xhc3MgaXNcbiAgICogbG9zdC5cbiAgICovXG4gIFJFRFVDRURfUkVEVU5EQU5DWV9MT1NUX09CSkVDVCA9IFwiczM6UmVkdWNlZFJlZHVuZGFuY3lMb3N0T2JqZWN0XCIsXG5cbiAgLyoqXG4gICAqIFlvdSByZWNlaXZlIHRoaXMgbm90aWZpY2F0aW9uIGV2ZW50IHdoZW4gYW4gb2JqZWN0IHRoYXQgd2FzIGVsaWdpYmxlIGZvclxuICAgKiByZXBsaWNhdGlvbiB1c2luZyBBbWF6b24gUzMgUmVwbGljYXRpb24gVGltZSBDb250cm9sIGZhaWxlZCB0byByZXBsaWNhdGUuXG4gICAqL1xuICBSRVBMSUNBVElPTl9PUEVSQVRJT05fRkFJTEVEX1JFUExJQ0FUSU9OID0gXCJzMzpSZXBsaWNhdGlvbjpPcGVyYXRpb25GYWlsZWRSZXBsaWNhdGlvblwiLFxuXG4gIC8qKlxuICAgKiBZb3UgcmVjZWl2ZSB0aGlzIG5vdGlmaWNhdGlvbiBldmVudCB3aGVuIGFuIG9iamVjdCB0aGF0IHdhcyBlbGlnaWJsZSBmb3JcbiAgICogcmVwbGljYXRpb24gdXNpbmcgQW1hem9uIFMzIFJlcGxpY2F0aW9uIFRpbWUgQ29udHJvbCBleGNlZWRlZCB0aGUgMTUtbWludXRlXG4gICAqIHRocmVzaG9sZCBmb3IgcmVwbGljYXRpb24uXG4gICAqL1xuICBSRVBMSUNBVElPTl9PUEVSQVRJT05fTUlTU0VEX1RIUkVTSE9MRCA9IFwiczM6UmVwbGljYXRpb246T3BlcmF0aW9uTWlzc2VkVGhyZXNob2xkXCIsXG5cbiAgLyoqXG4gICAqIFlvdSByZWNlaXZlIHRoaXMgbm90aWZpY2F0aW9uIGV2ZW50IGZvciBhbiBvYmplY3QgdGhhdCB3YXMgZWxpZ2libGUgZm9yXG4gICAqIHJlcGxpY2F0aW9uIHVzaW5nIHRoZSBBbWF6b24gUzMgUmVwbGljYXRpb24gVGltZSBDb250cm9sIGZlYXR1cmUgcmVwbGljYXRlZFxuICAgKiBhZnRlciB0aGUgMTUtbWludXRlIHRocmVzaG9sZC5cbiAgICovXG4gIFJFUExJQ0FUSU9OX09QRVJBVElPTl9SRVBMSUNBVEVEX0FGVEVSX1RIUkVTSE9MRCA9IFwiczM6UmVwbGljYXRpb246T3BlcmF0aW9uUmVwbGljYXRlZEFmdGVyVGhyZXNob2xkXCIsXG5cbiAgLyoqXG4gICAqIFlvdSByZWNlaXZlIHRoaXMgbm90aWZpY2F0aW9uIGV2ZW50IGZvciBhbiBvYmplY3QgdGhhdCB3YXMgZWxpZ2libGUgZm9yXG4gICAqIHJlcGxpY2F0aW9uIHVzaW5nIEFtYXpvbiBTMyBSZXBsaWNhdGlvbiBUaW1lIENvbnRyb2wgYnV0IGlzIG5vIGxvbmdlciB0cmFja2VkXG4gICAqIGJ5IHJlcGxpY2F0aW9uIG1ldHJpY3MuXG4gICAqL1xuICBSRVBMSUNBVElPTl9PUEVSQVRJT05fTk9UX1RSQUNLRUQgPSBcInMzOlJlcGxpY2F0aW9uOk9wZXJhdGlvbk5vdFRyYWNrZWRcIixcblxuICAvKipcbiAgICogQnkgdXNpbmcgdGhlIExpZmVjeWNsZUV4cGlyYXRpb24gZXZlbnQgdHlwZXMsIHlvdSBjYW4gcmVjZWl2ZSBhIG5vdGlmaWNhdGlvblxuICAgKiB3aGVuIEFtYXpvbiBTMyBkZWxldGVzIGFuIG9iamVjdCBiYXNlZCBvbiB5b3VyIFMzIExpZmVjeWNsZSBjb25maWd1cmF0aW9uLlxuICAgKi9cbiAgTElGRUNZQ0xFX0VYUElSQVRJT04gPSBcInMzOkxpZmVjeWNsZUV4cGlyYXRpb246KlwiLFxuXG4gIC8qKlxuICAgKiBUaGUgczM6TGlmZWN5Y2xlRXhwaXJhdGlvbjpEZWxldGUgZXZlbnQgdHlwZSBub3RpZmllcyB5b3Ugd2hlbiBhbiBvYmplY3RcbiAgICogaW4gYW4gdW52ZXJzaW9uZWQgYnVja2V0IGlzIGRlbGV0ZWQuXG4gICAqIEl0IGFsc28gbm90aWZpZXMgeW91IHdoZW4gYW4gb2JqZWN0IHZlcnNpb24gaXMgcGVybWFuZW50bHkgZGVsZXRlZCBieSBhblxuICAgKiBTMyBMaWZlY3ljbGUgY29uZmlndXJhdGlvbi5cbiAgICovXG4gIExJRkVDWUNMRV9FWFBJUkFUSU9OX0RFTEVURSA9IFwiczM6TGlmZWN5Y2xlRXhwaXJhdGlvbjpEZWxldGVcIixcblxuICAvKipcbiAgICogVGhlIHMzOkxpZmVjeWNsZUV4cGlyYXRpb246RGVsZXRlTWFya2VyQ3JlYXRlZCBldmVudCB0eXBlIG5vdGlmaWVzIHlvdVxuICAgKiB3aGVuIFMzIExpZmVjeWNsZSBjcmVhdGVzIGEgZGVsZXRlIG1hcmtlciB3aGVuIGEgY3VycmVudCB2ZXJzaW9uIG9mIGFuXG4gICAqIG9iamVjdCBpbiB2ZXJzaW9uZWQgYnVja2V0IGlzIGRlbGV0ZWQuXG4gICAqL1xuICBMSUZFQ1lDTEVfRVhQSVJBVElPTl9ERUxFVEVfTUFSS0VSX0NSRUFURUQgPSBcInMzOkxpZmVjeWNsZUV4cGlyYXRpb246RGVsZXRlTWFya2VyQ3JlYXRlZFwiLFxuXG4gIC8qKlxuICAgKiBZb3UgcmVjZWl2ZSB0aGlzIG5vdGlmaWNhdGlvbiBldmVudCB3aGVuIGFuIG9iamVjdCBpcyB0cmFuc2l0aW9uZWQgdG9cbiAgICogYW5vdGhlciBBbWF6b24gUzMgc3RvcmFnZSBjbGFzcyBieSBhbiBTMyBMaWZlY3ljbGUgY29uZmlndXJhdGlvbi5cbiAgICovXG4gIExJRkVDWUNMRV9UUkFOU0lUSU9OID0gXCJzMzpMaWZlY3ljbGVUcmFuc2l0aW9uXCIsXG5cbiAgLyoqXG4gICAqIFlvdSByZWNlaXZlIHRoaXMgbm90aWZpY2F0aW9uIGV2ZW50IHdoZW4gYW4gb2JqZWN0IHdpdGhpbiB0aGVcbiAgICogUzMgSW50ZWxsaWdlbnQtVGllcmluZyBzdG9yYWdlIGNsYXNzIG1vdmVkIHRvIHRoZSBBcmNoaXZlIEFjY2VzcyB0aWVyIG9yXG4gICAqIERlZXAgQXJjaGl2ZSBBY2Nlc3MgdGllci5cbiAgICovXG4gIElOVEVMTElHRU5UX1RJRVJJTkcgPSBcInMzOkludGVsbGlnZW50VGllcmluZ1wiLFxuXG4gIC8qKlxuICAgKiBCeSB1c2luZyB0aGUgT2JqZWN0VGFnZ2luZyBldmVudCB0eXBlcywgeW91IGNhbiBlbmFibGUgbm90aWZpY2F0aW9uIHdoZW5cbiAgICogYW4gb2JqZWN0IHRhZyBpcyBhZGRlZCBvciBkZWxldGVkIGZyb20gYW4gb2JqZWN0LlxuICAgKi9cbiAgT0JKRUNUX1RBR0dJTkcgPSBcInMzOk9iamVjdFRhZ2dpbmc6KlwiLFxuXG4gIC8qKlxuICAgKiBUaGUgczM6T2JqZWN0VGFnZ2luZzpQdXQgZXZlbnQgdHlwZSBub3RpZmllcyB5b3Ugd2hlbiBhIHRhZyBpcyBQVVQgb24gYW5cbiAgICogb2JqZWN0IG9yIGFuIGV4aXN0aW5nIHRhZyBpcyB1cGRhdGVkLlxuXG4gICAqL1xuICBPQkpFQ1RfVEFHR0lOR19QVVQgPSBcInMzOk9iamVjdFRhZ2dpbmc6UHV0XCIsXG5cbiAgLyoqXG4gICAqIFRoZSBzMzpPYmplY3RUYWdnaW5nOkRlbGV0ZSBldmVudCB0eXBlIG5vdGlmaWVzIHlvdSB3aGVuIGEgdGFnIGlzIHJlbW92ZWRcbiAgICogZnJvbSBhbiBvYmplY3QuXG4gICAqL1xuICBPQkpFQ1RfVEFHR0lOR19ERUxFVEUgPSBcInMzOk9iamVjdFRhZ2dpbmc6RGVsZXRlXCIsXG5cbiAgLyoqXG4gICAqIFlvdSByZWNlaXZlIHRoaXMgbm90aWZpY2F0aW9uIGV2ZW50IHdoZW4gYW4gQUNMIGlzIFBVVCBvbiBhbiBvYmplY3Qgb3Igd2hlblxuICAgKiBhbiBleGlzdGluZyBBQ0wgaXMgY2hhbmdlZC5cbiAgICogQW4gZXZlbnQgaXMgbm90IGdlbmVyYXRlZCB3aGVuIGEgcmVxdWVzdCByZXN1bHRzIGluIG5vIGNoYW5nZSB0byBhblxuICAgKiBvYmplY3TigJlzIEFDTC5cbiAgICovXG4gIE9CSkVDVF9BQ0xfUFVUID0gXCJzMzpPYmplY3RBY2w6UHV0XCIsXG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgTm90aWZpY2F0aW9uS2V5RmlsdGVyIHtcbiAgLyoqXG4gICAqIFVuaXF1ZSBpZGVudGlmaWVyIGZvciBlYWNoIG9mIHRoZSBub3RpZmljYXRpb24gY29uZmlndXJhdGlvbnMuXG4gICAqL1xuICByZWFkb25seSBpZD86IHN0cmluZztcbiAgLyoqXG4gICAqIFMzIGtleXMgbXVzdCBoYXZlIHRoZSBzcGVjaWZpZWQgcHJlZml4LlxuICAgKi9cbiAgcmVhZG9ubHkgcHJlZml4Pzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBTMyBrZXlzIG11c3QgaGF2ZSB0aGUgc3BlY2lmaWVkIHN1ZmZpeC5cbiAgICovXG4gIHJlYWRvbmx5IHN1ZmZpeD86IHN0cmluZztcbn1cbiJdfQ==
|