cdk-preflight 1.10.0 → 1.11.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/.jsii CHANGED
@@ -9626,7 +9626,7 @@
9626
9626
  },
9627
9627
  "name": "cdk-preflight",
9628
9628
  "readme": {
9629
- "markdown": "<p align=\"center\">\n <img src=\"https://raw.githubusercontent.com/badmintoncryer/cdk-preflight/main/assets/logo.png\" alt=\"cdk-preflight\" width=\"104\" height=\"104\">\n</p>\n\n<h1 align=\"center\">cdk-preflight</h1>\n\n<p align=\"center\">\n <strong>Catch deploy-time CloudFormation failures at <code>cdk synth</code> time.</strong>\n</p>\n\n<p align=\"center\">\n <a href=\"https://github.com/badmintoncryer/cdk-preflight/actions/workflows/monthly-verify.yml\"><img src=\"https://github.com/badmintoncryer/cdk-preflight/actions/workflows/monthly-verify.yml/badge.svg\" alt=\"monthly real-deploy verification\"></a>\n <a href=\"https://www.npmjs.com/package/cdk-preflight\"><img src=\"https://img.shields.io/npm/v/cdk-preflight.svg\" alt=\"npm version\"></a>\n <a href=\"https://www.npmjs.com/package/cdk-preflight\"><img src=\"https://img.shields.io/npm/dt/cdk-preflight.svg\" alt=\"npm total downloads\"></a>\n <a href=\"docs/rules.md\"><img src=\"https://img.shields.io/badge/rules-3361-blue\" alt=\"3361 bundled rules\"></a>\n</p>\n\nSome CloudFormation constraints are not expressed in resource provider schemas — they live only in documentation, in service API validation, or across multiple properties. Templates that violate them pass `cdk synth`, pass CloudFormation pre-deployment validation, and then fail minutes into a deployment, burning a rollback cycle.\n\ncdk-preflight is a curated [Rego rule pack](docs/rules.md) for exactly those constraints, evaluated with the CloudFormation validation engine that ships inside `aws-cdk-lib` (>= 2.267.0). By default a violation **fails `cdk synth`** — a template that is known to fail at deploy time never leaves your machine.\n\nThe pack aims at **every deploy-time failure, and every post-deploy run that is certain to fail, that no existing CDK mechanism already catches** — nothing narrower. Every bundled rule is backed by a `fail`/`pass` template pair, and the failure has been reproduced against real AWS. The handful of rules that could not be reproduced are marked `doc-only` and report as **warnings**, as does a rule whose remaining false positives cannot be told from the template (a cross-account Lambda layer the owner may have shared): they show up in the validation report but never fail synth. Rules that the built-in validation engine already covers are deliberately **not** duplicated — a test suite enforces this, and a rule the engine catches up with later is skipped on engines that cover it (see [Scope and rule lifecycle](#scope-and-rule-lifecycle)).\n\n> **Requires `aws-cdk-lib` >= 2.267.0** (released 2026-08-27) — the first release that bundles\n> the CloudFormation validation engine. On older versions the rules cannot run at all.\n\n## Quick start\n\n```bash\nnpm i -D cdk-preflight\nnpx cdkpf init # inserts Preflight.apply(app) into your CDK app\n # (`npx cdkpf init` is the same command, shorter)\n```\n\nor add one line yourself:\n\n```ts\nimport { Preflight } from 'cdk-preflight';\n\nconst app = new App();\nPreflight.apply(app);\n```\n\nOn violation, `cdk synth` fails with one error per finding, including the construct trace:\n\n```text\nERROR idle_timeout.timeout_seconds is 5000 but must be between 1 and 4000 seconds (cdk-preflight)\n MyStack/Alb/Resource (Alb16C2F182) aws-cdk-lib.aws_elasticloadbalancingv2.CfnLoadBalancer\n\nSynthesis finished with errors\n```\n\n## What it catches\n\nFour ordinary-looking snippets. All of them pass `cdk synth` and CloudFormation\npre-deployment validation, and all of them fail minutes into a deployment:\n\n```ts\n// 1) pf-iam-inline-policy-size — enumerate buckets, grant each one, blow past 10,240 chars\n// \"Maximum policy size of 10240 bytes exceeded for role IngestRole\"\n// (via role.addToPolicy the CDK auto-splits into managed policies instead,\n// and you hit the 6,144-char limit as pf-iam-managed-policy-size)\nnew iam.Policy(this, 'IngestPolicy', {\n roles: [role],\n statements: [new iam.PolicyStatement({\n actions: ['s3:GetObject', 's3:ListBucket'],\n resources: Array.from({ length: 200 },\n (_, i) => `arn:aws:s3:::data-lake-landing-zone-${i}/year=*/month=*/*`),\n })],\n});\n\n// 2) pf-lambda-env-size — a config blob in the environment, over the 4KB total\n// \"Lambda was unable to configure your environment variables because the\n// environment variables you have provided exceeded the 4KB limit\"\nnew lambda.Function(this, 'Fn', {\n runtime: lambda.Runtime.NODEJS_22_X,\n handler: 'index.handler',\n code: lambda.Code.fromInline('exports.handler = async () => {};'),\n environment: { FEATURE_FLAGS: JSON.stringify(bigFeatureFlagMap) },\n});\n\n// 3) pf-sfn-asl-missing-state (+ pf-sfn-asl-unreachable-state) — a typo in a state name\n// \"Invalid State Machine Definition: 'MISSING_TRANSITION_TARGET: ...'\"\nnew sfn.StateMachine(this, 'Pipeline', {\n definitionBody: sfn.DefinitionBody.fromString(JSON.stringify({\n StartAt: 'Validate',\n States: {\n Validate: { Type: 'Pass', Next: 'Transform' },\n Trasform: { Type: 'Pass', End: true }, // typo: Transform\n },\n })),\n});\n\n// 4) pf-logs-filter-pattern-bracket — a filter pattern opened with '[' and never closed\n// \"If a filter pattern starts with '[' it must end with ']'\"\nnew logs.MetricFilter(this, 'ErrorFilter', {\n logGroup,\n metricNamespace: 'Pipeline',\n metricName: 'Errors',\n filterPattern: logs.FilterPattern.literal('[time, level=ERROR, msg'),\n});\n```\n\nNone of these are type errors, so the L2 constructs accept them; none of them are\nexpressible in a resource schema, so CloudFormation accepts the template. With\n`Preflight.apply(app)` in place they fail `cdk synth` instead.\n\n## Observe-only mode\n\nTo roll the rules out gradually, start with `enforce: false`: findings then surface as synth **warnings** through the CDK built-in validator, with construct traces and per-finding acknowledgement:\n\n```ts\nPreflight.apply(app, { enforce: false });\n```\n\n```text\nWARNING idle_timeout.timeout_seconds is 5000 but must be between 1 and 4000 seconds (CloudFormation Validate)\n MyStack/Alb (Alb) aws-cdk-lib.aws_elasticloadbalancingv2.CfnLoadBalancer\n Acknowledge with 'CloudFormation-Validate::pf-elbv2-lb-idle-timeout-range'\n```\n\n> **Known limitation with stages.** The AWS CDK CLI drops validation findings for stacks nested in a `Stage`\n> before printing them, so in observe-only mode those findings appear **only** in `cdk.out/validation-report.json`\n> and never on the console. Enforce mode is not affected: cdk-preflight reports such findings itself and fails\n> synthesis. This is a CLI-side bug (present since aws-cdk 2.1128.1), not a rule evaluation problem.\n\n> **If the rules cannot run, the build stops.** When the evaluation engine fails on a template (a rule pack that\n> does not compile, an engine bug), enforce mode reports it as a violation named `pf-engine-error` and fails\n> synthesis for that stack instead of passing green with no rule having run. The other stacks keep their rules.\n> `pf-engine-error` is not a bundled rule and cannot be `exclude`d; `enforce: false` unblocks the build if you\n> need one.\n\n| Option | Default | Effect |\n|---|---|---|\n| `enforce` | `true` | Violations of bundled rules fail synthesis; set to `false` to only warn |\n| `strict` | `false` | With `enforce`: also fail on error-class findings (`ERROR`/`FATAL`, e.g. `F3034`) of the built-in validation engine itself, which the CDK currently downgrades to warnings |\n| `exclude` | `[]` | Rule ids to disable |\n| `includeUpstreamPending` | `true` | Include rules already proposed to the upstream engine but not yet merged |\n| `checkQuotas` | `false` | Also check the target account's Service Quotas and current usage (calls AWS at synth time, see below) |\n| `quotaCacheTtl` | 5 minutes | How long `checkQuotas` reuses the usage and deployed-stack state it fetched |\n\nTo opt out of a single rule everywhere, pass its id in `exclude`. To suppress a\nsingle *finding* on one construct, acknowledge it — this works in both modes, the\nid prefix just differs (`cdk-preflight::` when enforcing, `CloudFormation-Validate::`\nin observe-only, as printed in the warning text):\n\n```ts\ncdk.Validations.of(errorFilter).acknowledge({\n id: 'cdk-preflight::pf-logs-filter-pattern-bracket',\n reason: 'log group is written by a legacy producer; pattern is fixed upstream',\n});\n```\n\n## Service quota check (opt-in)\n\nThe rules only read the template, so they never assert a limit an account can raise. `checkQuotas: true` covers that\ngap for the quotas a CDK app runs into most: it adds up what every stack in the app (nested stacks included) is about\nto create in each account and Region, and compares that against the account's applied quota and current usage.\n\n```ts\nPreflight.apply(app, { checkQuotas: true });\n```\n\n| Check | Counts | Against |\n|---|---|---|\n| `pf-quota-vpcs-per-region` | new `AWS::EC2::VPC` | VPCs per Region (`vpc/L-F678F1CE`) |\n| `pf-quota-internet-gateways-per-region` | new `AWS::EC2::InternetGateway` | Internet gateways per Region (`vpc/L-A4707A72`) |\n| `pf-quota-elastic-ips-per-region` | new `AWS::EC2::EIP` (one per NAT gateway in a default `ec2.Vpc`) | EC2-VPC Elastic IPs (`ec2/L-0263D0A3`) |\n| `pf-quota-lambda-unreserved-concurrency` | increase in `ReservedConcurrentExecutions` | Lambda keeps at least 100 concurrent executions unreserved |\n\n- **Only new resources count.** The deployed template of each stack is read with `GetTemplate`; a resource whose\n logical id and type are already deployed is not counted again, so redeploying an unchanged app never trips the\n check. Resources behind a `Condition` and the brief overlap during a replacement are not counted.\n- **A finding fails synth** in enforce mode and is a warning with `enforce: false`. Acknowledge one like any other\n finding (`cdk-preflight::pf-quota-...`; `cdk-preflight-quotas::pf-quota-...` with `enforce: false`). The ids also work in `exclude`, including `pf-quota-check-skipped` to silence the skip warning.\n- **It needs credentials in the app process.** The CDK CLI does not pass `--profile` on to the app, so set\n `AWS_PROFILE` (or `AWS_*` variables) instead. When the credentials are missing, lack permissions, or belong to a\n different account than the stack's, the check is skipped with a `pf-quota-check-skipped` warning and synth goes on.\n- **Permissions:** `servicequotas:GetServiceQuota`, `servicequotas:GetAWSDefaultServiceQuota`, `ec2:DescribeVpcs`,\n `ec2:DescribeInternetGateways`, `ec2:DescribeAddresses`, `lambda:GetAccountSettings`, `cloudformation:GetTemplate`,\n `cloudformation:DescribeStackResource`. All read-only (`ReadOnlyAccess` covers them). The check also calls\n `sts:GetCallerIdentity`, which IAM never denies.\n- **Results are cached** in `cdk.out/.cdk-preflight/quota-cache.json`: usage and deployed templates for\n `quotaCacheTtl` (5 minutes), quota values for 24 hours. Delete the file to force a refetch.\n- Usage can change between synth and deploy (another team deploying to the same account), so a clean check is not a\n guarantee. The reverse also happens: EC2 does not always enforce the Elastic IP quota when CloudFormation\n creates several addresses in parallel (measured 2026-10-16: with 4 of 5 in use, two parallel `AWS::EC2::EIP` both\n succeeded), so a template the check stops may occasionally deploy. The check follows the quota, not the race.\n\n## Bundled rules\n\nSee [docs/rules.md](docs/rules.md) for the generated rule table.\n\n<!-- supported-resources:start -->\n<details>\n<summary><b>431 resource types across 78 services</b> — click to expand</summary>\n\nResource names are relative to `AWS::<Service>::`; the number in parentheses is how many rules target that type.\n\n| Service | Resource types |\n|---|---|\n| **(any resource type)** | `*` (14) |\n| **ApiGateway** | `ApiKey` (1), `Authorizer` (5), `Deployment` (1), `DocumentationPart` (1), `DomainName` (4), `GatewayResponse` (1), `Method` (14), `Model` (3), `Resource` (1), `RestApi` (5), `Stage` (9), `UsagePlan` (5), `VpcLink` (1) |\n| **ApiGatewayV2** | `Api` (5), `Authorizer` (11), `DomainName` (3), `Integration` (15), `IntegrationResponse` (1), `Model` (2), `Route` (6), `RouteResponse` (2), `Stage` (4), `VpcLink` (1) |\n| **ApplicationAutoScaling** | `ScalableTarget` (19), `ScalingPolicy` (30) |\n| **AppSync** | `Api` (7), `ApiCache` (4), `ApiKey` (2), `ChannelNamespace` (5), `DataSource` (15), `DomainName` (1), `FunctionConfiguration` (24), `GraphQLApi` (16), `GraphQLSchema` (12), `Resolver` (32), `SourceApiAssociation` (3) |\n| **APS** | `AnomalyDetector` (9), `ResourcePolicy` (5), `RuleGroupsNamespace` (10), `Workspace` (12) |\n| **Athena** | `DataCatalog` (6), `WorkGroup` (8) |\n| **AutoScaling** | `AutoScalingGroup` (38), `LifecycleHook` (8), `ScalingPolicy` (41), `ScheduledAction` (13), `WarmPool` (4) |\n| **Backup** | `BackupPlan` (12), `BackupSelection` (5), `BackupVault` (3), `Framework` (3), `LogicallyAirGappedBackupVault` (2), `ReportPlan` (2), `RestoreTestingPlan` (5), `RestoreTestingSelection` (3) |\n| **Batch** | `ComputeEnvironment` (40), `ConsumableResource` (2), `JobDefinition` (109), `JobQueue` (18), `SchedulingPolicy` (8), `ServiceEnvironment` (6) |\n| **Bedrock** | `ApplicationInferenceProfile` (2), `AutomatedReasoningPolicy` (3), `Blueprint` (3), `DataAutomationProject` (8), `DataSource` (12), `Flow` (14), `Guardrail` (19), `IntelligentPromptRouter` (5), `KnowledgeBase` (18), `Prompt` (4) |\n| **BedrockAgentCore** | `ApiKeyCredentialProvider` (1), `BrowserCustom` (1), `BrowserProfile` (1), `CapacityProvider` (8), `CodeInterpreterCustom` (1), `ConfigurationBundle` (4), `Dataset` (3), `Evaluator` (4), `Gateway` (16), `GatewayRateLimit` (5), `GatewayRule` (5), `GatewayTarget` (11), `Harness` (2), `HarnessEndpoint` (2), `Memory` (14), `OAuth2CredentialProvider` (5), `OnlineEvaluationConfig` (3), `PaymentCredentialProvider` (1), `PaymentManager` (1), `Policy` (3), `ResourcePolicy` (1), `Runtime` (16), `RuntimeEndpoint` (1) |\n| **Cassandra** | `Keyspace` (2), `Table` (22), `Type` (13) |\n| **CertificateManager** | `Certificate` (4) |\n| **CloudFormation** | `GuardHook` (1), `Stack` (2), `StackSet` (6) |\n| **CloudFront** | `AnycastIpList` (1), `CachePolicy` (7), `ContinuousDeploymentPolicy` (5), `Distribution` (55), `Function` (4), `KeyGroup` (1), `KeyValueStore` (2), `OriginRequestPolicy` (5), `PublicKey` (1), `RealtimeLogConfig` (3), `ResponseHeadersPolicy` (8), `VpcOrigin` (3) |\n| **CloudTrail** | `EventDataStore` (1), `Trail` (19) |\n| **CloudWatch** | `Alarm` (22), `AnomalyDetector` (6), `CompositeAlarm` (7), `Dashboard` (14), `InsightRule` (7), `MetricStream` (6) |\n| **CodeBuild** | `Project` (37), `ReportGroup` (2), `SourceCredential` (4) |\n| **CodeCommit** | `Repository` (11) |\n| **CodeDeploy** | `Application` (7), `DeploymentConfig` (12), `DeploymentGroup` (23) |\n| **CodePipeline** | `CustomActionType` (3), `Pipeline` (25), `Webhook` (2) |\n| **Cognito** | `IdentityPool` (3), `IdentityPoolRoleAttachment` (7), `LogDeliveryConfiguration` (3), `ManagedLoginBranding` (2), `UserPool` (52), `UserPoolClient` (21), `UserPoolDomain` (7), `UserPoolGroup` (1), `UserPoolIdentityProvider` (11), `UserPoolResourceServer` (4), `UserPoolRiskConfigurationAttachment` (6), `UserPoolUICustomizationAttachment` (2) |\n| **Config** | `ConfigRule` (6), `ConfigurationAggregator` (2), `ConfigurationRecorder` (7), `ConformancePack` (1), `RemediationConfiguration` (2) |\n| **DocDB** | `DBCluster` (14), `DBInstance` (1), `DBSubnetGroup` (2), `EventSubscription` (1) |\n| **DocDBElastic** | `Cluster` (7) |\n| **DynamoDB** | `GlobalTable` (25), `Table` (28) |\n| **EC2** | `ClientVpnAuthorizationRule` (1), `ClientVpnEndpoint` (6), `DHCPOptions` (2), `EIPAssociation` (1), `FlowLog` (4), `Instance` (10), `KeyPair` (1), `LaunchTemplate` (12), `NatGateway` (2), `NetworkAclEntry` (1), `NetworkInterface` (2), `PlacementGroup` (3), `PrefixList` (3), `Route` (1), `SecurityGroup` (7), `SecurityGroupEgress` (5), `SecurityGroupIngress` (5), `Subnet` (14), `TrafficMirrorTarget` (1), `TransitGateway` (2), `TransitGatewayRoute` (1), `Volume` (6), `VPC` (2), `VPCCidrBlock` (1), `VPCEndpoint` (4), `VPCGatewayAttachment` (1), `VPNConnection` (5) |\n| **ECR** | `PullThroughCacheRule` (3), `RegistryScanningConfiguration` (1), `ReplicationConfiguration` (1), `Repository` (7), `RepositoryCreationTemplate` (8), `SigningConfiguration` (1) |\n| **ECS** | `CapacityProvider` (3), `Cluster` (5), `Service` (37), `TaskDefinition` (66), `TaskSet` (2) |\n| **EFS** | `AccessPoint` (1), `FileSystem` (7), `MountTarget` (4) |\n| **EKS** | `AccessEntry` (14), `Addon` (5), `Cluster` (21), `FargateProfile` (5), `IdentityProviderConfig` (3), `Nodegroup` (21), `PodIdentityAssociation` (5) |\n| **ElastiCache** | `CacheCluster` (9), `ReplicationGroup` (14), `User` (2), `UserGroup` (1) |\n| **ElasticBeanstalk** | `Application` (2), `ConfigurationTemplate` (37), `Environment` (35) |\n| **ElasticLoadBalancingV2** | `Listener` (57), `ListenerCertificate` (2), `ListenerRule` (38), `LoadBalancer` (37), `TargetGroup` (58), `TrustStore` (1), `TrustStoreRevocation` (1) |\n| **Events** | `ApiDestination` (1), `Archive` (5), `Connection` (1), `Endpoint` (2), `EventBus` (2), `Rule` (27) |\n| **EventSchemas** | `Discoverer` (1), `Registry` (1), `RegistryPolicy` (1), `Schema` (1) |\n| **GlobalAccelerator** | `Accelerator` (1), `EndpointGroup` (5), `Listener` (2) |\n| **Glue** | `Classifier` (6), `Connection` (5), `Crawler` (11), `CustomEntityType` (1), `Database` (1), `DataQualityRuleset` (1), `Job` (15), `MLTransform` (4), `Partition` (1), `Schema` (3), `SecurityConfiguration` (1), `Table` (1), `Trigger` (10), `UserDefinedFunction` (2), `Workflow` (1) |\n| **Grafana** | `Workspace` (7) |\n| **IAM** | `Group` (23), `GroupPolicy` (19), `InstanceProfile` (2), `ManagedPolicy` (31), `OIDCProvider` (2), `Policy` (29), `Role` (44), `RolePolicy` (19), `ServiceLinkedRole` (1), `User` (24), `UserPolicy` (19) |\n| **IoT** | `Authorizer` (3), `Certificate` (1), `CertificateProvider` (1), `Command` (1), `DomainConfiguration` (3), `JobTemplate` (3), `MitigationAction` (1), `Policy` (4), `PolicyPrincipalAttachment` (1), `ProvisioningTemplate` (3), `RoleAlias` (1), `ScheduledAudit` (1), `Thing` (1), `ThingGroup` (2), `TopicRule` (5), `TopicRuleDestination` (2) |\n| **Kinesis** | `ResourcePolicy` (4), `Stream` (5), `StreamConsumer` (2) |\n| **KinesisAnalyticsV2** | `Application` (20), `ApplicationCloudWatchLoggingOption` (1), `ApplicationOutput` (1), `ApplicationReferenceDataSource` (1) |\n| **KinesisFirehose** | `DeliveryStream` (68) |\n| **KMS** | `Alias` (2), `Key` (12), `ReplicaKey` (4) |\n| **Lambda** | `Alias` (7), `CodeSigningConfig` (1), `EventInvokeConfig` (5), `EventSourceMapping` (54), `Function` (48), `LayerVersion` (8), `LayerVersionPermission` (3), `Permission` (8), `Url` (8), `Version` (1) |\n| **Logs** | `AccountPolicy` (6), `DeliveryDestination` (3), `Destination` (1), `LogAnomalyDetector` (2), `LogGroup` (10), `MetricFilter` (7), `QueryDefinition` (1), `ResourcePolicy` (1), `SubscriptionFilter` (6), `Transformer` (3) |\n| **MediaConvert** | `JobTemplate` (9), `Preset` (32), `Queue` (2) |\n| **MemoryDB** | `Cluster` (8), `User` (1) |\n| **MSK** | `BatchScramSecret` (2), `Cluster` (31), `ClusterPolicy` (1), `Configuration` (4), `Replicator` (10), `ServerlessCluster` (4) |\n| **Neptune** | `DBCluster` (11), `DBClusterParameterGroup` (1), `DBInstance` (3), `DBSubnetGroup` (1), `GlobalCluster` (1) |\n| **NeptuneGraph** | `Graph` (2), `PrivateGraphEndpoint` (1) |\n| **NetworkFirewall** | `FirewallPolicy` (18), `RuleGroup` (34), `TLSInspectionConfiguration` (7) |\n| **OpenSearchServerless** | `AccessPolicy` (7), `Collection` (2), `CollectionGroup` (3), `LifecyclePolicy` (4), `SecurityConfig` (5), `SecurityPolicy` (14) |\n| **OpenSearchService** | `Domain` (65) |\n| **Pipes** | `Pipe` (9) |\n| **RDS** | `DBCluster` (19), `DBInstance` (33), `DBParameterGroup` (2), `DBProxy` (4), `DBProxyTargetGroup` (2), `DBShardGroup` (1), `DBSubnetGroup` (3), `EventSubscription` (3), `OptionGroup` (1) |\n| **Redshift** | `Cluster` (20), `EventSubscription` (1), `ScheduledAction` (2) |\n| **RedshiftServerless** | `Namespace` (5), `Workgroup` (6) |\n| **Route53** | `CidrCollection` (11), `DNSSEC` (3), `HealthCheck` (30), `HostedZone` (14), `KeySigningKey` (9), `RecordSet` (74), `RecordSetGroup` (76) |\n| **Route53Profiles** | `ProfileAssociation` (1), `ProfileResourceAssociation` (6) |\n| **Route53Resolver** | `FirewallDomainList` (3), `FirewallRuleGroup` (18), `FirewallRuleGroupAssociation` (4), `ResolverDNSSECConfig` (1), `ResolverEndpoint` (18), `ResolverQueryLoggingConfig` (1), `ResolverQueryLoggingConfigAssociation` (1), `ResolverRule` (15), `ResolverRuleAssociation` (1) |\n| **S3** | `AccessPoint` (1), `Bucket` (54), `BucketPolicy` (4), `StorageLens` (5), `StorageLensGroup` (3) |\n| **S3Express** | `AccessPoint` (3), `DirectoryBucket` (11) |\n| **Scheduler** | `Schedule` (12), `ScheduleGroup` (1) |\n| **SecretsManager** | `RotationSchedule` (4), `Secret` (5), `SecretTargetAttachment` (1) |\n| **ServiceDiscovery** | `HttpNamespace` (3), `Instance` (19), `PrivateDnsNamespace` (4), `PublicDnsNamespace` (4), `Service` (13) |\n| **SES** | `ConfigurationSetEventDestination` (8), `ContactList` (1), `EmailIdentity` (6), `ReceiptRule` (6), `ReceiptRuleSet` (1), `Template` (1) |\n| **SNS** | `Subscription` (10), `Topic` (14), `TopicPolicy` (1) |\n| **SQS** | `Queue` (10), `QueuePolicy` (1) |\n| **SSM** | `Association` (4), `Document` (3), `MaintenanceWindow` (2), `MaintenanceWindowTarget` (1), `MaintenanceWindowTask` (1), `Parameter` (5) |\n| **StepFunctions** | `Activity` (3), `StateMachine` (26) |\n| **Synthetics** | `Canary` (16) |\n| **VerifiedPermissions** | `IdentitySource` (3), `Policy` (26), `PolicyStore` (23), `PolicyStoreAlias` (1), `PolicyTemplate` (29) |\n| **VpcLattice** | `AccessLogSubscription` (3), `AuthPolicy` (3), `DomainVerification` (1), `Listener` (12), `ResourceConfiguration` (30), `ResourceGateway` (6), `ResourcePolicy` (1), `Rule` (7), `Service` (2), `ServiceNetwork` (1), `ServiceNetworkResourceAssociation` (3), `ServiceNetworkServiceAssociation` (3), `ServiceNetworkVpcAssociation` (8), `TargetGroup` (14) |\n| **WAFv2** | `IPSet` (3), `LoggingConfiguration` (3), `RegexPatternSet` (3), `RuleGroup` (18), `WebACL` (23), `WebACLAssociation` (2) |\n| **XRay** | `Group` (1), `ResourcePolicy` (3), `SamplingRule` (6) |\n\n</details>\n<!-- supported-resources:end -->\n\nHighlights:\n\n- **ELBv2**: `idle_timeout` / `deregistration_delay` / `slow_start` attribute ranges (stringly-typed Key/Value attributes are invisible to schema validation)\n- **IAM**: managed (6,144 chars) and inline (role/group/user) policy document size limits\n- **CloudFront**: `MinTTL <= DefaultTTL <= MaxTTL` ordering, ACM certificates must live in `us-east-1`\n- **Step Functions**: `Next`/`Default`/`Choices` must reference defined states (a dangling `StartAt` is already caught by the engine's built-in `E3601`)\n- **EC2**: security group TCP/UDP port ranges and `FromPort <= ToPort`\n\n## Pull request report (GitHub Action)\n\nThe repository is also a GitHub Action that synthesizes the app on both sides of a pull request and posts **one comment** with:\n\n- the cdk-preflight findings of the pull request (from `cdk.out/validation-report.json`, or the synth log),\n- the idle cost change, from [cfn-idle-cost](https://github.com/badmintoncryer/cfn-idle-cost) (what the stacks cost a month with zero traffic),\n- the CloudFormation execution role permission change, from [cfn-exec-policy](https://github.com/badmintoncryer/cfn-exec-policy).\n\n```yaml\nname: cdk-report\non: pull_request\npermissions: { contents: read, pull-requests: write }\njobs:\n report:\n runs-on: ubuntu-latest\n steps:\n - uses: actions/checkout@v7\n - uses: actions/setup-node@v7\n with: { node-version: 22 }\n - uses: badmintoncryer/cdk-preflight@main\n with:\n idle-cost-args: --region us-east-1 --max-increase 50\n exec-policy-args: --fail-on wildcard,unknown\n```\n\nThe base branch is fetched and synthesized in a separate worktree, so neither side needs AWS credentials (unless the app's synth does lookups that are not in `cdk.context.json`). The comment is updated on each push and also written to the job summary. The job fails when the pull request has cdk-preflight errors, does not synthesize, or goes over a budget or `--fail-on` given to the other two tools; the `failed` output says which.\n\n| Input | What it does |\n|---|---|\n| `working-directory` | Directory of the CDK app (where `cdk.json` is). Default `.` |\n| `install` | Install command, run on both sides. Default `npm ci`; empty to skip |\n| `synth` | Synth command, run on both sides. It must write `cdk.out` in the app directory. Default `npx cdk synth -q` |\n| `base-ref` | Branch to compare against. Default: the pull request's base branch |\n| `idle-cost`, `idle-cost-args` | `false` to leave the idle cost out; more `cfn-idle-cost` flags (`--region` is needed for env-agnostic stacks) |\n| `exec-policy`, `exec-policy-args` | `false` to leave the permissions out; more `cfn-exec-policy diff` flags |\n| `comment` | `false` to only write the job summary. Default `true` |\n| `github-token` | Token used to comment. Default `github.token` |\n\nWhen the base branch does not synthesize, the idle cost is shown for the whole app instead of the change, and the permission change is left out.\n\n## For AI agents\n\nTo add cdk-preflight to a CDK app:\n\n1. `npm i -D cdk-preflight`\n2. `npx cdk-preflight init` — or the shorter alias `npx cdkpf init` (finds the entry point via `cdk.json` and inserts `Preflight.apply(app)`; use `--dry-run` to preview)\n3. Run `cdk synth`. Violations fail the synth with a validation report; each finding carries a rule id, the actual value, and a suggested fix\n4. To fix a finding, prefer correcting the resource. To opt out instead: `exclude: ['<rule-id>']` disables one rule, `enforce: false` switches to warn-only reporting\n\nThe machine-readable findings are written to `cdk.out/validation-report.json` when synthesizing with `-c @aws-cdk/core:validationReportJson=true`.\n\n### Report missed deploy errors\n\ncdk-preflight only knows the failure modes it has benched. When a deploy fails on a constraint the pack should have caught, that report is how new rules get added — but at that moment cdk-preflight is out of the loop (it passed the synth), so the instruction has to already sit in your agent's context. Paste this into your repository's `AGENTS.md` (or `CLAUDE.md`):\n\n```markdown\n## cdk-preflight: report missed deploy errors\n\nIf `cdk deploy` fails even though `cdk synth` (with cdk-preflight enabled) passed,\nand the failure is a service-side validation rejection — CREATE_FAILED/UPDATE_FAILED\nwith a 400-class message such as \"Invalid request provided: ...\" — cdk-preflight is\nmissing a rule. Report it:\n\n1. Qualify first. NOT reportable: AccessDenied / permissions, service quotas\n (those belong to the opt-in `checkQuotas`; open a regular issue if it missed one),\n throttling, name conflicts with existing resources, stabilization timeouts.\n2. Redact account-specific data (account IDs -> 123456789012, real ARNs/domains\n -> placeholders).\n3. Search existing issues: https://github.com/badmintoncryer/cdk-preflight/issues\n4. With your user's approval, open a \"Missed deploy error\" issue with the verbatim\n error message, the resource type, a minimal template snippet, and your\n aws-cdk-lib / cdk-preflight versions.\n```\n\n## Scope and rule lifecycle\n\nA constraint belongs in the pack when violating it makes a real deployment fail, or lets the deployment succeed and then makes every run of the deployed resource fail (an SSM Automation association that targets several tags, for example), *and* no layer that sees the same synthesized template already blocks it. There is no further \"is this worth a rule\" question — if the gap is real, it gets a rule.\n\nCDK L2 construct validation is deliberately **not** one of those layers. `CfnXxx` usage, escape hatches, `addPropertyOverride`, `cloudformation-include` and migrated templates all bypass L2, so an L2 guard covering the same mistake neither disqualifies a rule nor retires one.\n\nThat makes growth the normal state, and it has a consequence worth knowing before you upgrade: **new rules land in minor releases, so a minor upgrade can newly fail a `cdk synth` that passed yesterday.** That is intended, not a regression. If you need a frozen rule set, pin the version; to drop a single rule, `exclude: ['<rule-id>']`; to see everything without failing the build, `enforce: false`.\n\nRules move the other way too. Once the validation engine bundled in `aws-cdk-lib` starts blocking a constraint, the rule records the engine version that covers it and stops being evaluated on that engine or later — but only where that changes nothing about whether synth fails: with `enforce: false`, with `strict: true`, or when your app sets the context `@aws-cdk/core:validateAgainstDefaultRules: true`. In the default enforce mode the CDK reports its own engine's errors as warnings, so the rule keeps running and you may see both. Users on an older `aws-cdk-lib` keep the rule either way; it is deleted only once the minimum supported `aws-cdk-lib` bundles an engine that covers it.\n\n## How it works\n\n`Preflight.apply()` evaluates the rules with the [cloudformation-validate](https://github.com/aws-cloudformation/cloudformation-validate) Rust/WASM engine that ships inside `aws-cdk-lib` — no extra binaries, and no network access at synth time unless you opt in to `checkQuotas`, which calls AWS from a child process. In the default enforce mode the engine is invoked through a dedicated CDK validation plugin so that violations fail synthesis; with `enforce: false` the rules are instead injected into the CDK built-in `CloudFormationValidatePlugin` and reported as warnings.\n\nConstraints that *can* be expressed in schemas or generic engine rules also make good upstream PRs to that engine, but nothing here waits on one — the upstream release cycle is deliberately slower than this pack's. Each rule's `meta.yaml` tracks its upstream status so that retirement stays bookkeeping.\n\n## Requirements\n\n- `aws-cdk-lib` >= 2.267.0, released 2026-08-27 (the first release that bundles the built-in CloudFormation validator). This is a recent release — an existing CDK app may need an upgrade before cdk-preflight can run.\n\n## Contributing\n\nRule authoring, the verification gates (including real-deploy reproduction), and the test layout are documented in [AGENTS.md](AGENTS.md) — written for AI coding agents and humans alike.\n\n## License\n\nApache-2.0\n"
9629
+ "markdown": "<p align=\"center\">\n <img src=\"https://raw.githubusercontent.com/badmintoncryer/cdk-preflight/main/assets/logo.png\" alt=\"cdk-preflight\" width=\"104\" height=\"104\">\n</p>\n\n<h1 align=\"center\">cdk-preflight</h1>\n\n<p align=\"center\">\n <strong>Catch deploy-time CloudFormation failures at <code>cdk synth</code> time.</strong>\n</p>\n\n<p align=\"center\">\n <a href=\"https://github.com/badmintoncryer/cdk-preflight/actions/workflows/monthly-verify.yml\"><img src=\"https://github.com/badmintoncryer/cdk-preflight/actions/workflows/monthly-verify.yml/badge.svg\" alt=\"monthly real-deploy verification\"></a>\n <a href=\"https://www.npmjs.com/package/cdk-preflight\"><img src=\"https://img.shields.io/npm/v/cdk-preflight.svg\" alt=\"npm version\"></a>\n <a href=\"https://www.npmjs.com/package/cdk-preflight\"><img src=\"https://img.shields.io/npm/dt/cdk-preflight.svg\" alt=\"npm total downloads\"></a>\n <a href=\"docs/rules.md\"><img src=\"https://img.shields.io/badge/rules-3361-blue\" alt=\"3361 bundled rules\"></a>\n</p>\n\nSome CloudFormation constraints are not expressed in resource provider schemas — they live only in documentation, in service API validation, or across multiple properties. Templates that violate them pass `cdk synth`, pass CloudFormation pre-deployment validation, and then fail minutes into a deployment, burning a rollback cycle.\n\ncdk-preflight is a curated [Rego rule pack](docs/rules.md) for exactly those constraints, evaluated with the CloudFormation validation engine that ships inside `aws-cdk-lib` (>= 2.267.0). By default a violation **fails `cdk synth`** — a template that is known to fail at deploy time never leaves your machine.\n\nThe pack aims at **every deploy-time failure, and every post-deploy run that is certain to fail, that no existing CDK mechanism already catches** — nothing narrower. Every bundled rule is backed by a `fail`/`pass` template pair, and the failure has been reproduced against real AWS. The handful of rules that could not be reproduced are marked `doc-only` and report as **warnings**, as does a rule whose remaining false positives cannot be told from the template (a cross-account Lambda layer the owner may have shared): they show up in the validation report but never fail synth. Rules that the built-in validation engine already covers are deliberately **not** duplicated — a test suite enforces this, and a rule the engine catches up with later is skipped on engines that cover it (see [Scope and rule lifecycle](#scope-and-rule-lifecycle)).\n\n> **Requires `aws-cdk-lib` >= 2.267.0** (released 2026-08-27) — the first release that bundles\n> the CloudFormation validation engine. On older versions the rules cannot run at all.\n\n## Quick start\n\n```bash\nnpm i -D cdk-preflight\nnpx cdkpf init # inserts Preflight.apply(app) into your CDK app\n # (`npx cdkpf init` is the same command, shorter)\n```\n\nor add one line yourself:\n\n```ts\nimport { Preflight } from 'cdk-preflight';\n\nconst app = new App();\nPreflight.apply(app);\n```\n\nOn violation, `cdk synth` fails with one error per finding, including the construct trace:\n\n```text\nERROR idle_timeout.timeout_seconds is 5000 but must be between 1 and 4000 seconds (cdk-preflight)\n MyStack/Alb/Resource (Alb16C2F182) aws-cdk-lib.aws_elasticloadbalancingv2.CfnLoadBalancer\n\nSynthesis finished with errors\n```\n\n## What it catches\n\nFour ordinary-looking snippets. All of them pass `cdk synth` and CloudFormation\npre-deployment validation, and all of them fail minutes into a deployment:\n\n```ts\n// 1) pf-iam-inline-policy-size — enumerate buckets, grant each one, blow past 10,240 chars\n// \"Maximum policy size of 10240 bytes exceeded for role IngestRole\"\n// (via role.addToPolicy the CDK auto-splits into managed policies instead,\n// and you hit the 6,144-char limit as pf-iam-managed-policy-size)\nnew iam.Policy(this, 'IngestPolicy', {\n roles: [role],\n statements: [new iam.PolicyStatement({\n actions: ['s3:GetObject', 's3:ListBucket'],\n resources: Array.from({ length: 200 },\n (_, i) => `arn:aws:s3:::data-lake-landing-zone-${i}/year=*/month=*/*`),\n })],\n});\n\n// 2) pf-lambda-env-size — a config blob in the environment, over the 4KB total\n// \"Lambda was unable to configure your environment variables because the\n// environment variables you have provided exceeded the 4KB limit\"\nnew lambda.Function(this, 'Fn', {\n runtime: lambda.Runtime.NODEJS_22_X,\n handler: 'index.handler',\n code: lambda.Code.fromInline('exports.handler = async () => {};'),\n environment: { FEATURE_FLAGS: JSON.stringify(bigFeatureFlagMap) },\n});\n\n// 3) pf-sfn-asl-missing-state (+ pf-sfn-asl-unreachable-state) — a typo in a state name\n// \"Invalid State Machine Definition: 'MISSING_TRANSITION_TARGET: ...'\"\nnew sfn.StateMachine(this, 'Pipeline', {\n definitionBody: sfn.DefinitionBody.fromString(JSON.stringify({\n StartAt: 'Validate',\n States: {\n Validate: { Type: 'Pass', Next: 'Transform' },\n Trasform: { Type: 'Pass', End: true }, // typo: Transform\n },\n })),\n});\n\n// 4) pf-logs-filter-pattern-bracket — a filter pattern opened with '[' and never closed\n// \"If a filter pattern starts with '[' it must end with ']'\"\nnew logs.MetricFilter(this, 'ErrorFilter', {\n logGroup,\n metricNamespace: 'Pipeline',\n metricName: 'Errors',\n filterPattern: logs.FilterPattern.literal('[time, level=ERROR, msg'),\n});\n```\n\nNone of these are type errors, so the L2 constructs accept them; none of them are\nexpressible in a resource schema, so CloudFormation accepts the template. With\n`Preflight.apply(app)` in place they fail `cdk synth` instead.\n\n## Observe-only mode\n\nTo roll the rules out gradually, start with `enforce: false`: findings then surface as synth **warnings** through the CDK built-in validator, with construct traces and per-finding acknowledgement:\n\n```ts\nPreflight.apply(app, { enforce: false });\n```\n\n```text\nWARNING idle_timeout.timeout_seconds is 5000 but must be between 1 and 4000 seconds (CloudFormation Validate)\n MyStack/Alb (Alb) aws-cdk-lib.aws_elasticloadbalancingv2.CfnLoadBalancer\n Acknowledge with 'CloudFormation-Validate::pf-elbv2-lb-idle-timeout-range'\n```\n\n> **Known limitation with stages.** The AWS CDK CLI drops validation findings for stacks nested in a `Stage`\n> before printing them, so in observe-only mode those findings appear **only** in `cdk.out/validation-report.json`\n> and never on the console. Enforce mode is not affected: cdk-preflight reports such findings itself and fails\n> synthesis. This is a CLI-side bug (present since aws-cdk 2.1128.1), not a rule evaluation problem.\n\n> **If the rules cannot run, the build stops.** When the evaluation engine fails on a template (a rule pack that\n> does not compile, an engine bug), enforce mode reports it as a violation named `pf-engine-error` and fails\n> synthesis for that stack instead of passing green with no rule having run. The other stacks keep their rules.\n> `pf-engine-error` is not a bundled rule and cannot be `exclude`d; `enforce: false` unblocks the build if you\n> need one.\n\n| Option | Default | Effect |\n|---|---|---|\n| `enforce` | `true` | Violations of bundled rules fail synthesis; set to `false` to only warn |\n| `strict` | `false` | With `enforce`: also fail on error-class findings (`ERROR`/`FATAL`, e.g. `F3034`) of the built-in validation engine itself, which the CDK currently downgrades to warnings |\n| `exclude` | `[]` | Rule ids to disable |\n| `includeUpstreamPending` | `true` | Include rules already proposed to the upstream engine but not yet merged |\n| `checkQuotas` | `false` | Also check the target account's Service Quotas and current usage (calls AWS at synth time, see below) |\n| `quotaCacheTtl` | 5 minutes | How long `checkQuotas` reuses the usage and deployed-stack state it fetched |\n\nTo opt out of a single rule everywhere, pass its id in `exclude`. To suppress a\nsingle *finding* on one construct, acknowledge it — this works in both modes, the\nid prefix just differs (`cdk-preflight::` when enforcing, `CloudFormation-Validate::`\nin observe-only, as printed in the warning text):\n\n```ts\ncdk.Validations.of(errorFilter).acknowledge({\n id: 'cdk-preflight::pf-logs-filter-pattern-bracket',\n reason: 'log group is written by a legacy producer; pattern is fixed upstream',\n});\n```\n\n## Service quota check (opt-in)\n\nThe rules only read the template, so they never assert a limit an account can raise. `checkQuotas: true` covers that\ngap for the quotas a CDK app runs into most: it adds up what every stack in the app (nested stacks included) is about\nto create in each account and Region, and compares that against the account's applied quota and current usage.\n\n```ts\nPreflight.apply(app, { checkQuotas: true });\n```\n\n| Check | Counts | Against |\n|---|---|---|\n| `pf-quota-vpcs-per-region` | new `AWS::EC2::VPC` | VPCs per Region (`vpc/L-F678F1CE`) |\n| `pf-quota-internet-gateways-per-region` | new `AWS::EC2::InternetGateway` | Internet gateways per Region (`vpc/L-A4707A72`) |\n| `pf-quota-elastic-ips-per-region` | new `AWS::EC2::EIP` (one per NAT gateway in a default `ec2.Vpc`) | EC2-VPC Elastic IPs (`ec2/L-0263D0A3`) |\n| `pf-quota-lambda-unreserved-concurrency` | increase in `ReservedConcurrentExecutions` | Lambda keeps at least 100 concurrent executions unreserved |\n\n- **Only new resources count.** The deployed template of each stack is read with `GetTemplate`; a resource whose\n logical id and type are already deployed is not counted again, so redeploying an unchanged app never trips the\n check. Resources behind a `Condition` and the brief overlap during a replacement are not counted.\n- **A finding fails synth** in enforce mode and is a warning with `enforce: false`. Acknowledge one like any other\n finding (`cdk-preflight::pf-quota-...`; `cdk-preflight-quotas::pf-quota-...` with `enforce: false`). The ids also work in `exclude`, including `pf-quota-check-skipped` to silence the skip warning.\n- **It needs credentials in the app process.** The CDK CLI does not pass `--profile` on to the app, so set\n `AWS_PROFILE` (or `AWS_*` variables) instead. When the credentials are missing, lack permissions, or belong to a\n different account than the stack's, the check is skipped with a `pf-quota-check-skipped` warning and synth goes on.\n- **Permissions:** `servicequotas:GetServiceQuota`, `servicequotas:GetAWSDefaultServiceQuota`, `ec2:DescribeVpcs`,\n `ec2:DescribeInternetGateways`, `ec2:DescribeAddresses`, `lambda:GetAccountSettings`, `cloudformation:GetTemplate`,\n `cloudformation:DescribeStackResource`. All read-only (`ReadOnlyAccess` covers them). The check also calls\n `sts:GetCallerIdentity`, which IAM never denies.\n- **Results are cached** in `cdk.out/.cdk-preflight/quota-cache.json`: usage and deployed templates for\n `quotaCacheTtl` (5 minutes), quota values for 24 hours. Delete the file to force a refetch.\n- Usage can change between synth and deploy (another team deploying to the same account), so a clean check is not a\n guarantee. The reverse also happens: EC2 does not always enforce the Elastic IP quota when CloudFormation\n creates several addresses in parallel (measured 2026-10-16: with 4 of 5 in use, two parallel `AWS::EC2::EIP` both\n succeeded), so a template the check stops may occasionally deploy. The check follows the quota, not the race.\n- **CloudFormation's own quota warning is a different check.** Since June 2026, creating a change set (and\n `cdk validate` with `--online`, below) warns when a stack would exceed a service quota. That warning runs per stack,\n after the template is uploaded, and never stops the deploy. `checkQuotas` adds up every stack of the app that\n targets the same account and Region, and fails `cdk synth` before anything is uploaded. Both can be on.\n\n## Across stacks\n\nTwo checks read every stack of the app at once, because a single template cannot show the problem. They report\n**warnings** (they have not been reproduced on the bench yet, see [Scope](#scope-and-rule-lifecycle)) and never fail\nsynth, in either mode:\n\n| Check | Finds | Deploy error it predicts |\n|---|---|---|\n| `pf-cfn-export-name-conflict` | two stacks that deploy to the same account and Region export the same name (Stages included) | `Export with name X is already exported by stack Y` |\n| `pf-cfn-import-value-missing-export` | `Fn::ImportValue` of a name that starts with the name of a stack of the app (`Producer:...`, CDK's naming) that this stack, in the same account and Region, does not export | `No export named X found` |\n\nImports of names that do not start with a stack name of the app are left alone, since another app may export them.\nAcknowledge a finding with `cdk-preflight-exports::<rule-id>`, or turn a check off with `exclude`.\n\n## With `cdk validate`\n\nThe CDK CLI's experimental `cdk validate` (`cdk --unstable=validate validate`) synthesizes the app and runs its\nvalidation plugins without deploying, so cdk-preflight runs there exactly as in `cdk synth`: in enforce mode a finding\nfails the command, with `enforce: false` it is a warning (checked with CLI 2.1147.0). `--watch` re-runs it on each\nchange. `--online` (the default) also submits the templates to CloudFormation's pre-deployment validation, which\nneeds credentials and adds the server-side checks (resource name conflicts, the quota warning above); `--no-online`\nkeeps it offline.\n\n```sh\nnpx cdk --unstable=validate validate --no-online --watch\n```\n\n## Bundled rules\n\nSee [docs/rules.md](docs/rules.md) for the generated rule table.\n\n<!-- supported-resources:start -->\n<details>\n<summary><b>431 resource types across 78 services</b> — click to expand</summary>\n\nResource names are relative to `AWS::<Service>::`; the number in parentheses is how many rules target that type.\n\n| Service | Resource types |\n|---|---|\n| **(any resource type)** | `*` (14) |\n| **ApiGateway** | `ApiKey` (1), `Authorizer` (5), `Deployment` (1), `DocumentationPart` (1), `DomainName` (4), `GatewayResponse` (1), `Method` (14), `Model` (3), `Resource` (1), `RestApi` (5), `Stage` (9), `UsagePlan` (5), `VpcLink` (1) |\n| **ApiGatewayV2** | `Api` (5), `Authorizer` (11), `DomainName` (3), `Integration` (15), `IntegrationResponse` (1), `Model` (2), `Route` (6), `RouteResponse` (2), `Stage` (4), `VpcLink` (1) |\n| **ApplicationAutoScaling** | `ScalableTarget` (19), `ScalingPolicy` (30) |\n| **AppSync** | `Api` (7), `ApiCache` (4), `ApiKey` (2), `ChannelNamespace` (5), `DataSource` (15), `DomainName` (1), `FunctionConfiguration` (24), `GraphQLApi` (16), `GraphQLSchema` (12), `Resolver` (32), `SourceApiAssociation` (3) |\n| **APS** | `AnomalyDetector` (9), `ResourcePolicy` (5), `RuleGroupsNamespace` (10), `Workspace` (12) |\n| **Athena** | `DataCatalog` (6), `WorkGroup` (8) |\n| **AutoScaling** | `AutoScalingGroup` (38), `LifecycleHook` (8), `ScalingPolicy` (41), `ScheduledAction` (13), `WarmPool` (4) |\n| **Backup** | `BackupPlan` (12), `BackupSelection` (5), `BackupVault` (3), `Framework` (3), `LogicallyAirGappedBackupVault` (2), `ReportPlan` (2), `RestoreTestingPlan` (5), `RestoreTestingSelection` (3) |\n| **Batch** | `ComputeEnvironment` (40), `ConsumableResource` (2), `JobDefinition` (109), `JobQueue` (18), `SchedulingPolicy` (8), `ServiceEnvironment` (6) |\n| **Bedrock** | `ApplicationInferenceProfile` (2), `AutomatedReasoningPolicy` (3), `Blueprint` (3), `DataAutomationProject` (8), `DataSource` (12), `Flow` (14), `Guardrail` (19), `IntelligentPromptRouter` (5), `KnowledgeBase` (18), `Prompt` (4) |\n| **BedrockAgentCore** | `ApiKeyCredentialProvider` (1), `BrowserCustom` (1), `BrowserProfile` (1), `CapacityProvider` (8), `CodeInterpreterCustom` (1), `ConfigurationBundle` (4), `Dataset` (3), `Evaluator` (4), `Gateway` (16), `GatewayRateLimit` (5), `GatewayRule` (5), `GatewayTarget` (11), `Harness` (2), `HarnessEndpoint` (2), `Memory` (14), `OAuth2CredentialProvider` (5), `OnlineEvaluationConfig` (3), `PaymentCredentialProvider` (1), `PaymentManager` (1), `Policy` (3), `ResourcePolicy` (1), `Runtime` (16), `RuntimeEndpoint` (1) |\n| **Cassandra** | `Keyspace` (2), `Table` (22), `Type` (13) |\n| **CertificateManager** | `Certificate` (4) |\n| **CloudFormation** | `GuardHook` (1), `Stack` (2), `StackSet` (6) |\n| **CloudFront** | `AnycastIpList` (1), `CachePolicy` (7), `ContinuousDeploymentPolicy` (5), `Distribution` (55), `Function` (4), `KeyGroup` (1), `KeyValueStore` (2), `OriginRequestPolicy` (5), `PublicKey` (1), `RealtimeLogConfig` (3), `ResponseHeadersPolicy` (8), `VpcOrigin` (3) |\n| **CloudTrail** | `EventDataStore` (1), `Trail` (19) |\n| **CloudWatch** | `Alarm` (22), `AnomalyDetector` (6), `CompositeAlarm` (7), `Dashboard` (14), `InsightRule` (7), `MetricStream` (6) |\n| **CodeBuild** | `Project` (37), `ReportGroup` (2), `SourceCredential` (4) |\n| **CodeCommit** | `Repository` (11) |\n| **CodeDeploy** | `Application` (7), `DeploymentConfig` (12), `DeploymentGroup` (23) |\n| **CodePipeline** | `CustomActionType` (3), `Pipeline` (25), `Webhook` (2) |\n| **Cognito** | `IdentityPool` (3), `IdentityPoolRoleAttachment` (7), `LogDeliveryConfiguration` (3), `ManagedLoginBranding` (2), `UserPool` (52), `UserPoolClient` (21), `UserPoolDomain` (7), `UserPoolGroup` (1), `UserPoolIdentityProvider` (11), `UserPoolResourceServer` (4), `UserPoolRiskConfigurationAttachment` (6), `UserPoolUICustomizationAttachment` (2) |\n| **Config** | `ConfigRule` (6), `ConfigurationAggregator` (2), `ConfigurationRecorder` (7), `ConformancePack` (1), `RemediationConfiguration` (2) |\n| **DocDB** | `DBCluster` (14), `DBInstance` (1), `DBSubnetGroup` (2), `EventSubscription` (1) |\n| **DocDBElastic** | `Cluster` (7) |\n| **DynamoDB** | `GlobalTable` (25), `Table` (28) |\n| **EC2** | `ClientVpnAuthorizationRule` (1), `ClientVpnEndpoint` (6), `DHCPOptions` (2), `EIPAssociation` (1), `FlowLog` (4), `Instance` (10), `KeyPair` (1), `LaunchTemplate` (12), `NatGateway` (2), `NetworkAclEntry` (1), `NetworkInterface` (2), `PlacementGroup` (3), `PrefixList` (3), `Route` (1), `SecurityGroup` (7), `SecurityGroupEgress` (5), `SecurityGroupIngress` (5), `Subnet` (14), `TrafficMirrorTarget` (1), `TransitGateway` (2), `TransitGatewayRoute` (1), `Volume` (6), `VPC` (2), `VPCCidrBlock` (1), `VPCEndpoint` (4), `VPCGatewayAttachment` (1), `VPNConnection` (5) |\n| **ECR** | `PullThroughCacheRule` (3), `RegistryScanningConfiguration` (1), `ReplicationConfiguration` (1), `Repository` (7), `RepositoryCreationTemplate` (8), `SigningConfiguration` (1) |\n| **ECS** | `CapacityProvider` (3), `Cluster` (5), `Service` (37), `TaskDefinition` (66), `TaskSet` (2) |\n| **EFS** | `AccessPoint` (1), `FileSystem` (7), `MountTarget` (4) |\n| **EKS** | `AccessEntry` (14), `Addon` (5), `Cluster` (21), `FargateProfile` (5), `IdentityProviderConfig` (3), `Nodegroup` (21), `PodIdentityAssociation` (5) |\n| **ElastiCache** | `CacheCluster` (9), `ReplicationGroup` (14), `User` (2), `UserGroup` (1) |\n| **ElasticBeanstalk** | `Application` (2), `ConfigurationTemplate` (37), `Environment` (35) |\n| **ElasticLoadBalancingV2** | `Listener` (57), `ListenerCertificate` (2), `ListenerRule` (38), `LoadBalancer` (37), `TargetGroup` (58), `TrustStore` (1), `TrustStoreRevocation` (1) |\n| **Events** | `ApiDestination` (1), `Archive` (5), `Connection` (1), `Endpoint` (2), `EventBus` (2), `Rule` (27) |\n| **EventSchemas** | `Discoverer` (1), `Registry` (1), `RegistryPolicy` (1), `Schema` (1) |\n| **GlobalAccelerator** | `Accelerator` (1), `EndpointGroup` (5), `Listener` (2) |\n| **Glue** | `Classifier` (6), `Connection` (5), `Crawler` (11), `CustomEntityType` (1), `Database` (1), `DataQualityRuleset` (1), `Job` (15), `MLTransform` (4), `Partition` (1), `Schema` (3), `SecurityConfiguration` (1), `Table` (1), `Trigger` (10), `UserDefinedFunction` (2), `Workflow` (1) |\n| **Grafana** | `Workspace` (7) |\n| **IAM** | `Group` (23), `GroupPolicy` (19), `InstanceProfile` (2), `ManagedPolicy` (31), `OIDCProvider` (2), `Policy` (29), `Role` (44), `RolePolicy` (19), `ServiceLinkedRole` (1), `User` (24), `UserPolicy` (19) |\n| **IoT** | `Authorizer` (3), `Certificate` (1), `CertificateProvider` (1), `Command` (1), `DomainConfiguration` (3), `JobTemplate` (3), `MitigationAction` (1), `Policy` (4), `PolicyPrincipalAttachment` (1), `ProvisioningTemplate` (3), `RoleAlias` (1), `ScheduledAudit` (1), `Thing` (1), `ThingGroup` (2), `TopicRule` (5), `TopicRuleDestination` (2) |\n| **Kinesis** | `ResourcePolicy` (4), `Stream` (5), `StreamConsumer` (2) |\n| **KinesisAnalyticsV2** | `Application` (20), `ApplicationCloudWatchLoggingOption` (1), `ApplicationOutput` (1), `ApplicationReferenceDataSource` (1) |\n| **KinesisFirehose** | `DeliveryStream` (68) |\n| **KMS** | `Alias` (2), `Key` (12), `ReplicaKey` (4) |\n| **Lambda** | `Alias` (7), `CodeSigningConfig` (1), `EventInvokeConfig` (5), `EventSourceMapping` (54), `Function` (48), `LayerVersion` (8), `LayerVersionPermission` (3), `Permission` (8), `Url` (8), `Version` (1) |\n| **Logs** | `AccountPolicy` (6), `DeliveryDestination` (3), `Destination` (1), `LogAnomalyDetector` (2), `LogGroup` (10), `MetricFilter` (7), `QueryDefinition` (1), `ResourcePolicy` (1), `SubscriptionFilter` (6), `Transformer` (3) |\n| **MediaConvert** | `JobTemplate` (9), `Preset` (32), `Queue` (2) |\n| **MemoryDB** | `Cluster` (8), `User` (1) |\n| **MSK** | `BatchScramSecret` (2), `Cluster` (31), `ClusterPolicy` (1), `Configuration` (4), `Replicator` (10), `ServerlessCluster` (4) |\n| **Neptune** | `DBCluster` (11), `DBClusterParameterGroup` (1), `DBInstance` (3), `DBSubnetGroup` (1), `GlobalCluster` (1) |\n| **NeptuneGraph** | `Graph` (2), `PrivateGraphEndpoint` (1) |\n| **NetworkFirewall** | `FirewallPolicy` (18), `RuleGroup` (34), `TLSInspectionConfiguration` (7) |\n| **OpenSearchServerless** | `AccessPolicy` (7), `Collection` (2), `CollectionGroup` (3), `LifecyclePolicy` (4), `SecurityConfig` (5), `SecurityPolicy` (14) |\n| **OpenSearchService** | `Domain` (65) |\n| **Pipes** | `Pipe` (9) |\n| **RDS** | `DBCluster` (19), `DBInstance` (33), `DBParameterGroup` (2), `DBProxy` (4), `DBProxyTargetGroup` (2), `DBShardGroup` (1), `DBSubnetGroup` (3), `EventSubscription` (3), `OptionGroup` (1) |\n| **Redshift** | `Cluster` (20), `EventSubscription` (1), `ScheduledAction` (2) |\n| **RedshiftServerless** | `Namespace` (5), `Workgroup` (6) |\n| **Route53** | `CidrCollection` (11), `DNSSEC` (3), `HealthCheck` (30), `HostedZone` (14), `KeySigningKey` (9), `RecordSet` (74), `RecordSetGroup` (76) |\n| **Route53Profiles** | `ProfileAssociation` (1), `ProfileResourceAssociation` (6) |\n| **Route53Resolver** | `FirewallDomainList` (3), `FirewallRuleGroup` (18), `FirewallRuleGroupAssociation` (4), `ResolverDNSSECConfig` (1), `ResolverEndpoint` (18), `ResolverQueryLoggingConfig` (1), `ResolverQueryLoggingConfigAssociation` (1), `ResolverRule` (15), `ResolverRuleAssociation` (1) |\n| **S3** | `AccessPoint` (1), `Bucket` (54), `BucketPolicy` (4), `StorageLens` (5), `StorageLensGroup` (3) |\n| **S3Express** | `AccessPoint` (3), `DirectoryBucket` (11) |\n| **Scheduler** | `Schedule` (12), `ScheduleGroup` (1) |\n| **SecretsManager** | `RotationSchedule` (4), `Secret` (5), `SecretTargetAttachment` (1) |\n| **ServiceDiscovery** | `HttpNamespace` (3), `Instance` (19), `PrivateDnsNamespace` (4), `PublicDnsNamespace` (4), `Service` (13) |\n| **SES** | `ConfigurationSetEventDestination` (8), `ContactList` (1), `EmailIdentity` (6), `ReceiptRule` (6), `ReceiptRuleSet` (1), `Template` (1) |\n| **SNS** | `Subscription` (10), `Topic` (14), `TopicPolicy` (1) |\n| **SQS** | `Queue` (10), `QueuePolicy` (1) |\n| **SSM** | `Association` (4), `Document` (3), `MaintenanceWindow` (2), `MaintenanceWindowTarget` (1), `MaintenanceWindowTask` (1), `Parameter` (5) |\n| **StepFunctions** | `Activity` (3), `StateMachine` (26) |\n| **Synthetics** | `Canary` (16) |\n| **VerifiedPermissions** | `IdentitySource` (3), `Policy` (26), `PolicyStore` (23), `PolicyStoreAlias` (1), `PolicyTemplate` (29) |\n| **VpcLattice** | `AccessLogSubscription` (3), `AuthPolicy` (3), `DomainVerification` (1), `Listener` (12), `ResourceConfiguration` (30), `ResourceGateway` (6), `ResourcePolicy` (1), `Rule` (7), `Service` (2), `ServiceNetwork` (1), `ServiceNetworkResourceAssociation` (3), `ServiceNetworkServiceAssociation` (3), `ServiceNetworkVpcAssociation` (8), `TargetGroup` (14) |\n| **WAFv2** | `IPSet` (3), `LoggingConfiguration` (3), `RegexPatternSet` (3), `RuleGroup` (18), `WebACL` (23), `WebACLAssociation` (2) |\n| **XRay** | `Group` (1), `ResourcePolicy` (3), `SamplingRule` (6) |\n\n</details>\n<!-- supported-resources:end -->\n\nHighlights:\n\n- **ELBv2**: `idle_timeout` / `deregistration_delay` / `slow_start` attribute ranges (stringly-typed Key/Value attributes are invisible to schema validation)\n- **IAM**: managed (6,144 chars) and inline (role/group/user) policy document size limits\n- **CloudFront**: `MinTTL <= DefaultTTL <= MaxTTL` ordering, ACM certificates must live in `us-east-1`\n- **Step Functions**: `Next`/`Default`/`Choices` must reference defined states (a dangling `StartAt` is already caught by the engine's built-in `E3601`)\n- **EC2**: security group TCP/UDP port ranges and `FromPort <= ToPort`\n\n## Pull request report (GitHub Action)\n\nThe repository is also a GitHub Action that synthesizes the app on both sides of a pull request and posts **one comment** with:\n\n- the cdk-preflight findings of the pull request (from `cdk.out/validation-report.json`, or the synth log),\n- the idle cost change, from [cfn-idle-cost](https://github.com/badmintoncryer/cfn-idle-cost) (what the stacks cost a month with zero traffic),\n- the CloudFormation execution role permission change, from [cfn-exec-policy](https://github.com/badmintoncryer/cfn-exec-policy).\n\n```yaml\nname: cdk-report\non: pull_request\npermissions: { contents: read, pull-requests: write }\njobs:\n report:\n runs-on: ubuntu-latest\n steps:\n - uses: actions/checkout@v7\n - uses: actions/setup-node@v7\n with: { node-version: 22 }\n - uses: badmintoncryer/cdk-preflight@main\n with:\n idle-cost-args: --region us-east-1 --max-increase 50\n exec-policy-args: --fail-on wildcard,unknown\n```\n\nThe base branch is fetched and synthesized in a separate worktree, so neither side needs AWS credentials (unless the app's synth does lookups that are not in `cdk.context.json`). The comment is updated on each push and also written to the job summary. The job fails when the pull request has cdk-preflight errors, does not synthesize, or goes over a budget or `--fail-on` given to the other two tools; the `failed` output says which.\n\n| Input | What it does |\n|---|---|\n| `working-directory` | Directory of the CDK app (where `cdk.json` is). Default `.` |\n| `install` | Install command, run on both sides. Default `npm ci`; empty to skip |\n| `synth` | Synth command, run on both sides. It must write `cdk.out` in the app directory. Default `npx cdk synth -q` |\n| `base-ref` | Branch to compare against. Default: the pull request's base branch |\n| `idle-cost`, `idle-cost-args` | `false` to leave the idle cost out; more `cfn-idle-cost` flags (`--region` is needed for env-agnostic stacks) |\n| `exec-policy`, `exec-policy-args` | `false` to leave the permissions out; more `cfn-exec-policy diff` flags |\n| `comment` | `false` to only write the job summary. Default `true` |\n| `github-token` | Token used to comment. Default `github.token` |\n\nWhen the base branch does not synthesize, the idle cost is shown for the whole app instead of the change, and the permission change is left out.\n\n## For AI agents\n\nTo add cdk-preflight to a CDK app:\n\n1. `npm i -D cdk-preflight`\n2. `npx cdk-preflight init` — or the shorter alias `npx cdkpf init` (finds the entry point via `cdk.json` and inserts `Preflight.apply(app)`; use `--dry-run` to preview)\n3. Run `cdk synth`. Violations fail the synth with a validation report; each finding carries a rule id, the actual value, and a suggested fix\n4. To fix a finding, prefer correcting the resource. To opt out instead: `exclude: ['<rule-id>']` disables one rule, `enforce: false` switches to warn-only reporting\n\nThe machine-readable findings are written to `cdk.out/validation-report.json` when synthesizing with `-c @aws-cdk/core:validationReportJson=true`.\n\nThe two sibling tools also run as MCP servers, so an agent can check the same `cdk.out` for what it costs idle and\nwhat it asks of the CloudFormation execution role:\n\n```sh\nclaude mcp add idle-cost -- npx -y cfn-idle-cost mcp # idle_cost\nclaude mcp add exec-policy -- npx -y cfn-exec-policy mcp # exec_policy_explain / _generate / _diff / _doctor\n```\n\n### Report missed deploy errors\n\ncdk-preflight only knows the failure modes it has benched. When a deploy fails on a constraint the pack should have caught, that report is how new rules get added — but at that moment cdk-preflight is out of the loop (it passed the synth), so the instruction has to already sit in your agent's context. Paste this into your repository's `AGENTS.md` (or `CLAUDE.md`):\n\n```markdown\n## cdk-preflight: report missed deploy errors\n\nIf `cdk deploy` fails even though `cdk synth` (with cdk-preflight enabled) passed,\nand the failure is a service-side validation rejection — CREATE_FAILED/UPDATE_FAILED\nwith a 400-class message such as \"Invalid request provided: ...\" — cdk-preflight is\nmissing a rule. Report it:\n\n1. Qualify first. NOT reportable: AccessDenied / permissions, service quotas\n (those belong to the opt-in `checkQuotas`; open a regular issue if it missed one),\n throttling, name conflicts with existing resources, stabilization timeouts.\n2. Redact account-specific data (account IDs -> 123456789012, real ARNs/domains\n -> placeholders).\n3. Search existing issues: https://github.com/badmintoncryer/cdk-preflight/issues\n4. With your user's approval, open a \"Missed deploy error\" issue with the verbatim\n error message, the resource type, a minimal template snippet, and your\n aws-cdk-lib / cdk-preflight versions.\n```\n\n## Scope and rule lifecycle\n\nA constraint belongs in the pack when violating it makes a real deployment fail, or lets the deployment succeed and then makes every run of the deployed resource fail (an SSM Automation association that targets several tags, for example), *and* no layer that sees the same synthesized template already blocks it. There is no further \"is this worth a rule\" question — if the gap is real, it gets a rule.\n\nCDK L2 construct validation is deliberately **not** one of those layers. `CfnXxx` usage, escape hatches, `addPropertyOverride`, `cloudformation-include` and migrated templates all bypass L2, so an L2 guard covering the same mistake neither disqualifies a rule nor retires one.\n\nThat makes growth the normal state, and it has a consequence worth knowing before you upgrade: **new rules land in minor releases, so a minor upgrade can newly fail a `cdk synth` that passed yesterday.** That is intended, not a regression. If you need a frozen rule set, pin the version; to drop a single rule, `exclude: ['<rule-id>']`; to see everything without failing the build, `enforce: false`.\n\nRules move the other way too. Once the validation engine bundled in `aws-cdk-lib` starts blocking a constraint, the rule records the engine version that covers it and stops being evaluated on that engine or later — but only where that changes nothing about whether synth fails: with `enforce: false`, with `strict: true`, or when your app sets the context `@aws-cdk/core:validateAgainstDefaultRules: true`. In the default enforce mode the CDK reports its own engine's errors as warnings, so the rule keeps running and you may see both. Users on an older `aws-cdk-lib` keep the rule either way; it is deleted only once the minimum supported `aws-cdk-lib` bundles an engine that covers it.\n\n## How it works\n\n`Preflight.apply()` evaluates the rules with the [cloudformation-validate](https://github.com/aws-cloudformation/cloudformation-validate) Rust/WASM engine that ships inside `aws-cdk-lib` — no extra binaries, and no network access at synth time unless you opt in to `checkQuotas`, which calls AWS from a child process. In the default enforce mode the engine is invoked through a dedicated CDK validation plugin so that violations fail synthesis; with `enforce: false` the rules are instead injected into the CDK built-in `CloudFormationValidatePlugin` and reported as warnings.\n\nConstraints that *can* be expressed in schemas or generic engine rules also make good upstream PRs to that engine, but nothing here waits on one — the upstream release cycle is deliberately slower than this pack's. Each rule's `meta.yaml` tracks its upstream status so that retirement stays bookkeeping.\n\n## Requirements\n\n- `aws-cdk-lib` >= 2.267.0, released 2026-08-27 (the first release that bundles the built-in CloudFormation validator). This is a recent release — an existing CDK app may need an upgrade before cdk-preflight can run.\n\n## Contributing\n\nRule authoring, the verification gates (including real-deploy reproduction), and the test layout are documented in [AGENTS.md](AGENTS.md) — written for AI coding agents and humans alike.\n\n## License\n\nApache-2.0\n"
9630
9630
  },
9631
9631
  "repository": {
9632
9632
  "type": "git",
@@ -9655,7 +9655,7 @@
9655
9655
  "kind": "class",
9656
9656
  "locationInModule": {
9657
9657
  "filename": "src/index.ts",
9658
- "line": 105
9658
+ "line": 106
9659
9659
  },
9660
9660
  "methods": [
9661
9661
  {
@@ -9665,7 +9665,7 @@
9665
9665
  },
9666
9666
  "locationInModule": {
9667
9667
  "filename": "src/index.ts",
9668
- "line": 109
9668
+ "line": 110
9669
9669
  },
9670
9670
  "name": "apply",
9671
9671
  "parameters": [
@@ -9692,7 +9692,7 @@
9692
9692
  },
9693
9693
  "locationInModule": {
9694
9694
  "filename": "src/index.ts",
9695
- "line": 148
9695
+ "line": 154
9696
9696
  },
9697
9697
  "name": "ruleIds",
9698
9698
  "returns": {
@@ -9722,7 +9722,7 @@
9722
9722
  "kind": "interface",
9723
9723
  "locationInModule": {
9724
9724
  "filename": "src/index.ts",
9725
- "line": 10
9725
+ "line": 11
9726
9726
  },
9727
9727
  "name": "PreflightOptions",
9728
9728
  "properties": [
@@ -9737,7 +9737,7 @@
9737
9737
  "immutable": true,
9738
9738
  "locationInModule": {
9739
9739
  "filename": "src/index.ts",
9740
- "line": 82
9740
+ "line": 83
9741
9741
  },
9742
9742
  "name": "checkQuotas",
9743
9743
  "optional": true,
@@ -9756,7 +9756,7 @@
9756
9756
  "immutable": true,
9757
9757
  "locationInModule": {
9758
9758
  "filename": "src/index.ts",
9759
- "line": 31
9759
+ "line": 32
9760
9760
  },
9761
9761
  "name": "enforce",
9762
9762
  "optional": true,
@@ -9774,7 +9774,7 @@
9774
9774
  "immutable": true,
9775
9775
  "locationInModule": {
9776
9776
  "filename": "src/index.ts",
9777
- "line": 16
9777
+ "line": 17
9778
9778
  },
9779
9779
  "name": "exclude",
9780
9780
  "optional": true,
@@ -9798,7 +9798,7 @@
9798
9798
  "immutable": true,
9799
9799
  "locationInModule": {
9800
9800
  "filename": "src/index.ts",
9801
- "line": 63
9801
+ "line": 64
9802
9802
  },
9803
9803
  "name": "includeUpstreamPending",
9804
9804
  "optional": true,
@@ -9816,7 +9816,7 @@
9816
9816
  "immutable": true,
9817
9817
  "locationInModule": {
9818
9818
  "filename": "src/index.ts",
9819
- "line": 91
9819
+ "line": 92
9820
9820
  },
9821
9821
  "name": "quotaCacheTtl",
9822
9822
  "optional": true,
@@ -9835,7 +9835,7 @@
9835
9835
  "immutable": true,
9836
9836
  "locationInModule": {
9837
9837
  "filename": "src/index.ts",
9838
- "line": 48
9838
+ "line": 49
9839
9839
  },
9840
9840
  "name": "strict",
9841
9841
  "optional": true,
@@ -9847,6 +9847,6 @@
9847
9847
  "symbolId": "src/index:PreflightOptions"
9848
9848
  }
9849
9849
  },
9850
- "version": "1.10.0",
9851
- "fingerprint": "Q4/5VckF222hIs9KyU3HjnOtpAl6MQwSIke33HkgY5c="
9850
+ "version": "1.11.1",
9851
+ "fingerprint": "FhDJGk/YFUf3rGxCvea+A/Jfx/70e+6aZ6U5Xg7ujTU="
9852
9852
  }
package/AGENTS.md CHANGED
@@ -38,7 +38,7 @@ Five other validation layers sit around a CDK app. Exactly one of them is a boun
38
38
  | CDK L1 generated validators (`CfnXxx`) | synth, every CDK app | type and required-property checks only — never value ranges, patterns, or cross-field rules | **No practical overlap**: pack rules are value / cross-field constraints by construction |
39
39
  | Bundled engine default rules (`@aws/cloudformation-validate`: SCHEMA / CFN_LINT / ENGINE) | synth, via this plugin | patched registry-schema ranges/patterns/enums + cfn-lint rules | **The hard boundary** (principle 1) **and the only retirement trigger**. If the bare engine reports ERROR/FATAL on the minimal violating template, a *new* rule must not exist — enforced by the jest duplication guard. When a later engine catches up with an *existing* rule, the same guard turns red until the rule records `supersededBy` (it stays for users on older `aws-cdk-lib`) |
40
40
  | cfn-lint (external CLI) | outside the synth path (a separate CI step, if the user runs one) | near-parity with the bundled engine | **Not a boundary** — never disqualifies a rule. A check cfn-lint has but the engine lacks is an upstream-PR candidate *for the engine* (project policy: contribute to cloudformation-validate, not to cfn-lint) |
41
- | CloudFormation server-side pre-deploy validation | CreateStack / UpdateStack / CreateChangeSet, before resources are touched | property syntax against RAW registry schemas for non-excluded types; resource name conflicts | **Almost no overlap** with this pack's domain: ~420 resource types are excluded (IAM, EC2 SG, ECS, RDS, SFN, …) and raw schemas carry none of the doc-only limits — 0/16 real-world cases detected (measured 2026-09, cdk-validation-gap-research). **Not a retirement trigger** — this is the one place where a layer that *blocks the deploy* still does not make a rule redundant, because what it returns is not equivalent. A raw-schema violation comes back as a stack-level `Validation failed with 1 error(s). Call DescribeEvents to retrieve the full list of issues…`, which **names no property**: the developer has to make a second API call to find out what was wrong. A rule here fails `cdk synth` instead, before any AWS call, naming the property path. Audited 2026-09-17: 36 shipped rules sit in this band and 30+ of their `repro.evidence` lines record that sentence verbatim. They carry `upstream: cfn-schema` |
41
+ | CloudFormation server-side pre-deploy validation | CreateStack / UpdateStack / CreateChangeSet, before resources are touched | property syntax against RAW registry schemas for non-excluded types; resource name conflicts | **Almost no overlap** with this pack's domain: ~420 resource types are excluded (IAM, EC2 SG, ECS, RDS, SFN, …) and raw schemas carry none of the doc-only limits — 0/16 real-world cases detected (measured 2026-09, cdk-validation-gap-research). **Not a retirement trigger** — this is the one place where a layer that *blocks the deploy* still does not make a rule redundant, because what it returns is not equivalent. A raw-schema violation comes back as a stack-level `Validation failed with 1 error(s). Call DescribeEvents to retrieve the full list of issues…`, which **names no property**: the developer has to make a second API call to find out what was wrong. A rule here fails `cdk synth` instead, before any AWS call, naming the property path. Audited 2026-09-17: 36 shipped rules sit in this band and 30+ of their `repro.evidence` lines record that sentence verbatim. They carry `upstream: cfn-schema`. Since 2026-06 the same checks also run on CreateStack/UpdateStack, and change sets add three **warnings** (service quota, AWS Config recorder conflict, ECR repository not empty on delete). The quota warning is per stack and never blocks the deploy, so it is not a reason to drop a `checkQuotas` quota, which sums the whole app and fails synth (principle 7) |
42
42
  | CloudFormation + service APIs | deploy (CREATE/UPDATE) | everything else: cross-field rules, service-side business rules, quotas | **The target, not a duplicate to avoid.** A rule exists *iff* it front-runs a real deploy-time failure here; `meta.yaml#repro` (real-deploy gate) proves that equivalence |
43
43
 
44
44
  Selection algorithm for a new rule, in order: (1) duplication guard — run the minimal violating template through the bare engine; any built-in ERROR/FATAL kills the candidate. A **WARN-class-only** engine finding (`W…`) does *not* kill it but marks a gray zone: the engine knows about the constraint and under-classifies it, so nothing blocks the deploy (`strict` promotes only ERROR/FATAL) — prefer filing an upstream severity issue, and if a stopgap rule ships anyway, mark it `upstream: pending-engine` so it retires with the upstream fix. **A second gray zone looks similar and is not the same one**: CloudFormation's raw registry schema carries the constraint, so the deploy stops at `CreateStack` with `Validation failed with 1 error(s)` and no property name, while the bundled engine is silent. Those rules are marked `upstream: cfn-schema` — they do not retire with an engine fix, because the engine never knew. The two were conflated under `pending-engine` until the 2026-09-17 audit split them (20 `W3030` / 16 `cfn-schema`); read the evidence, not the failure string, to tell them apart. `includeUpstreamPending: false` drops only the `pending-engine` half. (2) real-deploy gate — the fail template must actually fail CREATE with the predicted service error; a fail template that deploys kills the candidate (it happened: the "30-day minimum before STANDARD_IA" and the "4096-char ZipFile" constraints are documented but not enforced, so those rules were dropped). There is no third gate: L1/L2 coverage, marginal value, and how exotic the mistake looks never disqualify a candidate.
package/README.md CHANGED
@@ -186,6 +186,37 @@ Preflight.apply(app, { checkQuotas: true });
186
186
  guarantee. The reverse also happens: EC2 does not always enforce the Elastic IP quota when CloudFormation
187
187
  creates several addresses in parallel (measured 2026-10-16: with 4 of 5 in use, two parallel `AWS::EC2::EIP` both
188
188
  succeeded), so a template the check stops may occasionally deploy. The check follows the quota, not the race.
189
+ - **CloudFormation's own quota warning is a different check.** Since June 2026, creating a change set (and
190
+ `cdk validate` with `--online`, below) warns when a stack would exceed a service quota. That warning runs per stack,
191
+ after the template is uploaded, and never stops the deploy. `checkQuotas` adds up every stack of the app that
192
+ targets the same account and Region, and fails `cdk synth` before anything is uploaded. Both can be on.
193
+
194
+ ## Across stacks
195
+
196
+ Two checks read every stack of the app at once, because a single template cannot show the problem. They report
197
+ **warnings** (they have not been reproduced on the bench yet, see [Scope](#scope-and-rule-lifecycle)) and never fail
198
+ synth, in either mode:
199
+
200
+ | Check | Finds | Deploy error it predicts |
201
+ |---|---|---|
202
+ | `pf-cfn-export-name-conflict` | two stacks that deploy to the same account and Region export the same name (Stages included) | `Export with name X is already exported by stack Y` |
203
+ | `pf-cfn-import-value-missing-export` | `Fn::ImportValue` of a name that starts with the name of a stack of the app (`Producer:...`, CDK's naming) that this stack, in the same account and Region, does not export | `No export named X found` |
204
+
205
+ Imports of names that do not start with a stack name of the app are left alone, since another app may export them.
206
+ Acknowledge a finding with `cdk-preflight-exports::<rule-id>`, or turn a check off with `exclude`.
207
+
208
+ ## With `cdk validate`
209
+
210
+ The CDK CLI's experimental `cdk validate` (`cdk --unstable=validate validate`) synthesizes the app and runs its
211
+ validation plugins without deploying, so cdk-preflight runs there exactly as in `cdk synth`: in enforce mode a finding
212
+ fails the command, with `enforce: false` it is a warning (checked with CLI 2.1147.0). `--watch` re-runs it on each
213
+ change. `--online` (the default) also submits the templates to CloudFormation's pre-deployment validation, which
214
+ needs credentials and adds the server-side checks (resource name conflicts, the quota warning above); `--no-online`
215
+ keeps it offline.
216
+
217
+ ```sh
218
+ npx cdk --unstable=validate validate --no-online --watch
219
+ ```
189
220
 
190
221
  ## Bundled rules
191
222
 
@@ -340,6 +371,14 @@ To add cdk-preflight to a CDK app:
340
371
 
341
372
  The machine-readable findings are written to `cdk.out/validation-report.json` when synthesizing with `-c @aws-cdk/core:validationReportJson=true`.
342
373
 
374
+ The two sibling tools also run as MCP servers, so an agent can check the same `cdk.out` for what it costs idle and
375
+ what it asks of the CloudFormation execution role:
376
+
377
+ ```sh
378
+ claude mcp add idle-cost -- npx -y cfn-idle-cost mcp # idle_cost
379
+ claude mcp add exec-policy -- npx -y cfn-exec-policy mcp # exec_policy_explain / _generate / _diff / _doctor
380
+ ```
381
+
343
382
  ### Report missed deploy errors
344
383
 
345
384
  cdk-preflight only knows the failure modes it has benched. When a deploy fails on a constraint the pack should have caught, that report is how new rules get added — but at that moment cdk-preflight is out of the loop (it passed the synth), so the instruction has to already sit in your agent's context. Paste this into your repository's `AGENTS.md` (or `CLAUDE.md`):
package/lib/index.js CHANGED
@@ -4,6 +4,7 @@ exports.Preflight = void 0;
4
4
  const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
5
5
  const aws_cdk_lib_1 = require("aws-cdk-lib");
6
6
  const enforce_1 = require("./private/enforce");
7
+ const exports_1 = require("./private/exports");
7
8
  const quota_1 = require("./private/quota");
8
9
  const rules_generated_1 = require("./rules.generated");
9
10
  /**
@@ -18,7 +19,7 @@ const rules_generated_1 = require("./rules.generated");
18
19
  * Preflight.apply(app);
19
20
  */
20
21
  class Preflight {
21
- static [JSII_RTTI_SYMBOL_1] = { fqn: "cdk-preflight.Preflight", version: "1.10.0" };
22
+ static [JSII_RTTI_SYMBOL_1] = { fqn: "cdk-preflight.Preflight", version: "1.11.1" };
22
23
  /**
23
24
  * Register the cdk-preflight rules on an App or Stage.
24
25
  */
@@ -27,8 +28,10 @@ class Preflight {
27
28
  throw new Error('cdk-preflight: Preflight.apply() must be called on an App or a Stage');
28
29
  }
29
30
  const exclude = options.exclude ?? [];
30
- // pf-quota-* は Rego のルールではないので BUNDLED_RULES には無い(src/private/quota.ts)
31
- const unknown = exclude.filter((id) => !rules_generated_1.BUNDLED_RULES.some((r) => r.id === id) && !quota_1.QUOTA_RULE_IDS.includes(id));
31
+ // pf-quota-* と スタック間の Export のルールは Rego のルールではないので BUNDLED_RULES には無い
32
+ // (src/private/quota.ts、src/private/exports.ts)
33
+ const unknown = exclude.filter((id) => !rules_generated_1.BUNDLED_RULES.some((r) => r.id === id)
34
+ && !quota_1.QUOTA_RULE_IDS.includes(id) && !exports_1.EXPORT_RULE_IDS.includes(id));
32
35
  if (unknown.length > 0) {
33
36
  throw new Error(`cdk-preflight: unknown rule id(s) in exclude: ${unknown.join(', ')}`);
34
37
  }
@@ -49,6 +52,9 @@ class Preflight {
49
52
  : undefined;
50
53
  if (quotas)
51
54
  (0, quota_1.installQuotaCacheFlush)(scope);
55
+ if (!exports_1.EXPORT_RULE_IDS.every((id) => exclude.includes(id))) {
56
+ aws_cdk_lib_1.Validations.of(scope).addPlugins(new exports_1.PreflightExportPlugin(exclude));
57
+ }
52
58
  if (enforce) {
53
59
  aws_cdk_lib_1.Validations.of(scope).addPlugins(new enforce_1.PreflightEnforcePlugin(selected, strict, quotas));
54
60
  (0, enforce_1.installEnforceGate)(scope);
@@ -77,4 +83,4 @@ function cdkKeepsDefaultRuleErrors(scope) {
77
83
  const raw = scope.node.tryGetContext('@aws-cdk/core:validateAgainstDefaultRules');
78
84
  return raw !== undefined && raw !== false && raw !== 'false' && process.env.CDK_VALIDATION !== 'false';
79
85
  }
80
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7OztBQUFBLDZDQUEyRDtBQUUzRCwrQ0FBdUo7QUFDdkosMkNBQXlFO0FBQ3pFLHVEQUFrRDtBQXlGbEQ7Ozs7Ozs7Ozs7R0FVRztBQUNILE1BQWEsU0FBUzs7SUFDcEI7O09BRUc7SUFDSSxNQUFNLENBQUMsS0FBSyxDQUFDLEtBQWlCLEVBQUUsVUFBNEIsRUFBRTtRQUNuRSxJQUFJLENBQUMsbUJBQUssQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQztZQUMxQixNQUFNLElBQUksS0FBSyxDQUFDLHNFQUFzRSxDQUFDLENBQUM7UUFDMUYsQ0FBQztRQUNELE1BQU0sT0FBTyxHQUFHLE9BQU8sQ0FBQyxPQUFPLElBQUksRUFBRSxDQUFDO1FBQ3RDLHdFQUF3RTtRQUN4RSxNQUFNLE9BQU8sR0FBRyxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFDLCtCQUFhLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxLQUFLLEVBQUUsQ0FBQyxJQUFJLENBQUMsc0JBQWMsQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUNoSCxJQUFJLE9BQU8sQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLENBQUM7WUFDdkIsTUFBTSxJQUFJLEtBQUssQ0FBQyxpREFBaUQsT0FBTyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUM7UUFDekYsQ0FBQztRQUNELE1BQU0sT0FBTyxHQUFHLE9BQU8sQ0FBQyxPQUFPLElBQUksSUFBSSxDQUFDO1FBQ3hDLE1BQU0sTUFBTSxHQUFHLE9BQU8sQ0FBQyxNQUFNLElBQUksS0FBSyxDQUFDO1FBQ3ZDLHdEQUF3RDtRQUN4RCxtREFBbUQ7UUFDbkQsMkRBQTJEO1FBQzNELHNEQUFzRDtRQUN0RCxNQUFNLFlBQVksR0FBRyxDQUFDLE9BQU8sSUFBSSxNQUFNLElBQUkseUJBQXlCLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDNUUsTUFBTSxPQUFPLEdBQUcsWUFBWSxDQUFDLENBQUMsQ0FBQyxJQUFBLHVCQUFhLEdBQUUsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDO1FBQzNELE1BQU0sUUFBUSxHQUFHLCtCQUFhO2FBQzNCLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxPQUFPLENBQUMsc0JBQXNCLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLFFBQVEsS0FBSyxnQkFBZ0IsQ0FBQzthQUMxRixNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUM7YUFDdEMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLElBQUEsc0JBQVksRUFBQyxDQUFDLEVBQUUsT0FBTyxDQUFDLENBQUMsQ0FBQztRQUU1QyxNQUFNLE1BQU0sR0FBRyxPQUFPLENBQUMsV0FBVztZQUNoQyxDQUFDLENBQUMsRUFBRSxLQUFLLEVBQUUsQ0FBQyxPQUFPLENBQUMsYUFBYSxJQUFJLHNCQUFRLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsY0FBYyxFQUFFLEVBQUUsT0FBTyxFQUFFO1lBQ3JGLENBQUMsQ0FBQyxTQUFTLENBQUM7UUFDZCxJQUFJLE1BQU07WUFBRSxJQUFBLDhCQUFzQixFQUFDLEtBQUssQ0FBQyxDQUFDO1FBQzFDLElBQUksT0FBTyxFQUFFLENBQUM7WUFDWix5QkFBVyxDQUFDLEVBQUUsQ0FBQyxLQUFLLENBQUMsQ0FBQyxVQUFVLENBQUMsSUFBSSxnQ0FBc0IsQ0FBQyxRQUFRLEVBQUUsTUFBTSxFQUFFLE1BQU0sQ0FBQyxDQUFDLENBQUM7WUFDdkYsSUFBQSw0QkFBa0IsRUFBQyxLQUFLLENBQUMsQ0FBQztRQUM1QixDQUFDO2FBQU0sQ0FBQztZQUNOLHlCQUFXLENBQUMsRUFBRSxDQUFDLEtBQUssQ0FBQyxDQUFDLFVBQVUsQ0FBQyxJQUFBLDZCQUFtQixFQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUM7WUFDaEUsSUFBSSxNQUFNO2dCQUFFLHlCQUFXLENBQUMsRUFBRSxDQUFDLEtBQUssQ0FBQyxDQUFDLFVBQVUsQ0FBQyxJQUFJLDhCQUFvQixDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUM7UUFDakYsQ0FBQztJQUNILENBQUM7SUFFRDs7T0FFRztJQUNJLE1BQU0sQ0FBQyxPQUFPO1FBQ25CLE9BQU8sK0JBQWEsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQztJQUN4QyxDQUFDO0lBRUQsZ0JBQXVCLENBQUM7O0FBL0MxQiw4QkFnREM7QUFFRDs7OztHQUlHO0FBQ0gsU0FBUyx5QkFBeUIsQ0FBQyxLQUFpQjtJQUNsRCxNQUFNLEdBQUcsR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQywyQ0FBMkMsQ0FBQyxDQUFDO0lBQ2xGLE9BQU8sR0FBRyxLQUFLLFNBQVMsSUFBSSxHQUFHLEtBQUssS0FBSyxJQUFJLEdBQUcsS0FBSyxPQUFPLElBQUksT0FBTyxDQUFDLEdBQUcsQ0FBQyxjQUFjLEtBQUssT0FBTyxDQUFDO0FBQ3pHLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBEdXJhdGlvbiwgU3RhZ2UsIFZhbGlkYXRpb25zIH0gZnJvbSAnYXdzLWNkay1saWInO1xuaW1wb3J0IHsgSUNvbnN0cnVjdCB9IGZyb20gJ2NvbnN0cnVjdHMnO1xuaW1wb3J0IHsgZW5naW5lVmVyc2lvbiwgaW5zdGFsbEVuZm9yY2VHYXRlLCBpc1N1cGVyc2VkZWQsIG9ic2VydmVQbHVnaW5DYWNoZWQsIFByZWZsaWdodEVuZm9yY2VQbHVnaW4sIFByZWZsaWdodFF1b3RhUGx1Z2luIH0gZnJvbSAnLi9wcml2YXRlL2VuZm9yY2UnO1xuaW1wb3J0IHsgaW5zdGFsbFF1b3RhQ2FjaGVGbHVzaCwgUVVPVEFfUlVMRV9JRFMgfSBmcm9tICcuL3ByaXZhdGUvcXVvdGEnO1xuaW1wb3J0IHsgQlVORExFRF9SVUxFUyB9IGZyb20gJy4vcnVsZXMuZ2VuZXJhdGVkJztcblxuLyoqXG4gKiBPcHRpb25zIGZvciB7QGxpbmsgUHJlZmxpZ2h0LmFwcGx5fS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBQcmVmbGlnaHRPcHRpb25zIHtcbiAgLyoqXG4gICAqIFJ1bGUgaWRzIHRvIGRpc2FibGUgKHNlZSBgUHJlZmxpZ2h0LnJ1bGVJZHMoKWAgb3IgZG9jcy9ydWxlcy5tZCkuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gYWxsIGJ1bmRsZWQgcnVsZXMgYXJlIGVuYWJsZWRcbiAgICovXG4gIHJlYWRvbmx5IGV4Y2x1ZGU/OiBzdHJpbmdbXTtcblxuICAvKipcbiAgICogRmFpbCBzeW50aGVzaXMgd2hlbiBhIGJ1bmRsZWQgcnVsZSBpcyB2aW9sYXRlZC5cbiAgICpcbiAgICogSW4gdGhlIGRlZmF1bHQgKGVuZm9yY2UpIG1vZGUsIGNkay1wcmVmbGlnaHQgZXZhbHVhdGVzIGl0cyBydWxlcyB3aXRoIGl0c1xuICAgKiBvd24gdmFsaWRhdGlvbiBwbHVnaW4gYW5kIGEgdmlvbGF0aW9uIG1ha2VzIGBjZGsgc3ludGhgIGZhaWwg4oCUIHRoZSB3aG9sZVxuICAgKiBwb2ludCBvZiBwcmVmbGlnaHQgY2hlY2tzIGlzIHRoYXQgYSB0ZW1wbGF0ZSBrbm93biB0byBmYWlsIGF0IGRlcGxveSB0aW1lXG4gICAqIG5ldmVyIGxlYXZlcyB5b3VyIG1hY2hpbmUuIFNldCBgZW5mb3JjZTogZmFsc2VgIHRvIG9ic2VydmUgZmlyc3Q6IGZpbmRpbmdzXG4gICAqIGFyZSB0aGVuIHJlcG9ydGVkIHRocm91Z2ggdGhlIENESyBidWlsdC1pbiBDbG91ZEZvcm1hdGlvbiB2YWxpZGF0b3IgYW5kXG4gICAqIHN1cmZhY2UgYXMgc3ludGggd2FybmluZ3Mgd2l0aCBjb25zdHJ1Y3QgdHJhY2VzLCB3aGljaCBjYW4gYmUgbXV0ZWQgcGVyXG4gICAqIGZpbmRpbmcgdmlhIGBBY2tub3dsZWRnZSB3aXRoICdDbG91ZEZvcm1hdGlvbi1WYWxpZGF0ZTo6PHJ1bGUtaWQ+J2AuXG4gICAqXG4gICAqIEBkZWZhdWx0IHRydWVcbiAgICovXG4gIHJlYWRvbmx5IGVuZm9yY2U/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBJbiBlbmZvcmNlIG1vZGUsIGFkZGl0aW9uYWxseSBmYWlsIHN5bnRoZXNpcyBvbiBlcnJvci1jbGFzcyBmaW5kaW5nc1xuICAgKiAoc2V2ZXJpdHkgRVJST1IvRkFUQUwpIG9mIHRoZSBidWlsdC1pbiB2YWxpZGF0aW9uIGVuZ2luZSBpdHNlbGYsIGUuZy5cbiAgICogc2NoZW1hIHZpb2xhdGlvbnMgbGlrZSBgRjMwMzRgLiBUaGlzIGlzIHRoZSB3b3JrYXJvdW5kIGZvciB0aGUgQ0RLXG4gICAqIGJlaGF2aW9yIHdoZXJlIGFsbCBidWlsdC1pbiBmaW5kaW5ncyBhcmUgZG93bmdyYWRlZCB0byB3YXJuaW5ncy5cbiAgICpcbiAgICogU2luY2UgdGhlIGVuZ2luZSdzIG93biBlcnJvcnMgdGhlbiBmYWlsIHN5bnRoZXNpcywgYnVuZGxlZCBydWxlcyB0aGF0IHRoZVxuICAgKiBydW5uaW5nIGVuZ2luZSBhbHJlYWR5IGNvdmVycyBhcmUgc2tpcHBlZCBpbnN0ZWFkIG9mIGJlaW5nIHJlcG9ydGVkIHR3aWNlLlxuICAgKiBUaGUgc2FtZSBoYXBwZW5zIHdpdGggYGVuZm9yY2U6IGZhbHNlYCwgYW5kIHdoZW4gdGhlIGFwcCBzZXRzIHRoZSBjb250ZXh0XG4gICAqIGBAYXdzLWNkay9jb3JlOnZhbGlkYXRlQWdhaW5zdERlZmF1bHRSdWxlczogdHJ1ZWAuXG4gICAqXG4gICAqIE9ubHkgZWZmZWN0aXZlIGluIGVuZm9yY2UgbW9kZSAodGhlIGRlZmF1bHQpLlxuICAgKlxuICAgKiBAZGVmYXVsdCBmYWxzZVxuICAgKi9cbiAgcmVhZG9ubHkgc3RyaWN0PzogYm9vbGVhbjtcblxuICAvKipcbiAgICogSW5jbHVkZSBydWxlcyB0aGF0IGFyZSBtYXJrZWQgYHBlbmRpbmctZW5naW5lYCAoY2FuZGlkYXRlcyB0aGF0IGhhdmUgYmVlblxuICAgKiBwcm9wb3NlZCB0byB0aGUgdXBzdHJlYW0gY2xvdWRmb3JtYXRpb24tdmFsaWRhdGUgZW5naW5lIGJ1dCBhcmUgbm90IG1lcmdlZFxuICAgKiB5ZXQpLiBEaXNhYmxlIHRoaXMgaWYgeW91IHJ1biBhIG5ld2VyIGVuZ2luZSB0aGF0IGFscmVhZHkgY292ZXJzIHRoZW0uXG4gICAqXG4gICAqIFJ1bGVzIG1hcmtlZCBgY2ZuLXNjaGVtYWAgYXJlIHVuYWZmZWN0ZWQgYnkgdGhpcyBzd2l0Y2guIENsb3VkRm9ybWF0aW9uJ3NcbiAgICogb3duIHJlZ2lzdHJ5IHNjaGVtYSBkb2VzIHJlamVjdCB0aG9zZSB0ZW1wbGF0ZXMsIGJ1dCBvbmx5IHdpdGggYVxuICAgKiBzdGFjay1sZXZlbCBcIlZhbGlkYXRpb24gZmFpbGVkIHdpdGggMSBlcnJvcihzKVwiIHRoYXQgbmFtZXMgbm8gcHJvcGVydHksIHNvXG4gICAqIHRoZXkga2VlcCBlYXJuaW5nIHRoZWlyIHBsYWNlIGF0IHN5bnRoIHRpbWUgYW5kIG5vIGVuZ2luZSByZWxlYXNlIHJldGlyZXNcbiAgICogdGhlbS5cbiAgICpcbiAgICogQGRlZmF1bHQgdHJ1ZVxuICAgKi9cbiAgcmVhZG9ubHkgaW5jbHVkZVVwc3RyZWFtUGVuZGluZz86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIENvbXBhcmUgd2hhdCB0aGUgYXBwIGlzIGFib3V0IHRvIGNyZWF0ZSBhZ2FpbnN0IHRoZSB0YXJnZXQgYWNjb3VudCdzXG4gICAqIFNlcnZpY2UgUXVvdGFzIGFuZCBjdXJyZW50IHVzYWdlOiBWUENzLCBpbnRlcm5ldCBnYXRld2F5cyBhbmQgRWxhc3RpYyBJUHNcbiAgICogcGVyIFJlZ2lvbiwgYW5kIHRoZSB1bnJlc2VydmVkIExhbWJkYSBjb25jdXJyZW5jeSBsZWZ0IGFmdGVyIHJlc2VydmVkXG4gICAqIGNvbmN1cnJlbmN5IGNoYW5nZXMuIENvdW50cyBhcmUgc3VtbWVkIG92ZXIgZXZlcnkgc3RhY2sgKGluY2x1ZGluZyBuZXN0ZWRcbiAgICogc3RhY2tzKSB0aGF0IGRlcGxveXMgdG8gdGhlIHNhbWUgYWNjb3VudCBhbmQgUmVnaW9uLCBhbmQgcmVzb3VyY2VzIHRoYXRcbiAgICogYWxyZWFkeSBleGlzdCBpbiB0aGUgZGVwbG95ZWQgc3RhY2sgYXJlIG5vdCBjb3VudGVkIGFnYWluLlxuICAgKlxuICAgKiBUaGlzIGlzIHRoZSBvbmUgZmVhdHVyZSB0aGF0IG1ha2VzIHN5bnRoIGNhbGwgQVdTLiBJdCBuZWVkcyBjcmVkZW50aWFsc1xuICAgKiBmb3IgdGhlIHRhcmdldCBhY2NvdW50IGluIHRoZSBhcHAgcHJvY2VzczogdGhlIENESyBDTEkgZG9lcyBub3QgcGFzc1xuICAgKiBgLS1wcm9maWxlYCBvbiB0byB0aGUgYXBwLCBzbyBzZXQgYEFXU19QUk9GSUxFYCAob3IgYEFXU18qYCB2YXJpYWJsZXMpXG4gICAqIGluc3RlYWQuIFdpdGhvdXQgdXNhYmxlIGNyZWRlbnRpYWxzIHRoZSBjaGVjayBpcyBza2lwcGVkIHdpdGggYSB3YXJuaW5nXG4gICAqIGFuZCBzeW50aCBnb2VzIG9uLiBBIGZpbmRpbmcgZmFpbHMgc3ludGggaW4gZW5mb3JjZSBtb2RlIGFuZCBpcyBhIHdhcm5pbmdcbiAgICogd2l0aCBgZW5mb3JjZTogZmFsc2VgLlxuICAgKlxuICAgKiBAZGVmYXVsdCBmYWxzZVxuICAgKi9cbiAgcmVhZG9ubHkgY2hlY2tRdW90YXM/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBIb3cgbG9uZyBgY2hlY2tRdW90YXNgIHJldXNlcyB0aGUgdXNhZ2UgYW5kIGRlcGxveWVkLXN0YWNrIHN0YXRlIGl0XG4gICAqIGZldGNoZWQsIGNhY2hlZCB1bmRlciB0aGUgY2xvdWQgYXNzZW1ibHkgZGlyZWN0b3J5IChgY2RrLm91dGApLiBRdW90YVxuICAgKiB2YWx1ZXMgdGhlbXNlbHZlcyBhcmUgY2FjaGVkIGZvciAyNCBob3Vycy5cbiAgICpcbiAgICogQGRlZmF1bHQgRHVyYXRpb24ubWludXRlcyg1KVxuICAgKi9cbiAgcmVhZG9ubHkgcXVvdGFDYWNoZVR0bD86IER1cmF0aW9uO1xufVxuXG4vKipcbiAqIGNkay1wcmVmbGlnaHQ6IGNhdGNoIGRlcGxveS10aW1lIENsb3VkRm9ybWF0aW9uIGZhaWx1cmVzIGF0IHN5bnRoIHRpbWUuXG4gKlxuICogSW5qZWN0cyBhIGN1cmF0ZWQgUmVnbyBydWxlIHBhY2sgKGNvbnN0cmFpbnRzIHRoYXQgcmVzb3VyY2UgcHJvdmlkZXIgc2NoZW1hc1xuICogZG8gbm90IGV4cHJlc3M6IGRvYy1vbmx5IHZhbHVlIGxpbWl0cywgY3Jvc3MtcHJvcGVydHkgYW5kIGNyb3NzLXJlc291cmNlXG4gKiBydWxlcykgaW50byB0aGUgQVdTIENESyBidWlsdC1pbiBDbG91ZEZvcm1hdGlvbiB2YWxpZGF0b3IuXG4gKlxuICogQGV4YW1wbGVcbiAqIGRlY2xhcmUgY29uc3QgYXBwOiBBcHA7XG4gKiBQcmVmbGlnaHQuYXBwbHkoYXBwKTtcbiAqL1xuZXhwb3J0IGNsYXNzIFByZWZsaWdodCB7XG4gIC8qKlxuICAgKiBSZWdpc3RlciB0aGUgY2RrLXByZWZsaWdodCBydWxlcyBvbiBhbiBBcHAgb3IgU3RhZ2UuXG4gICAqL1xuICBwdWJsaWMgc3RhdGljIGFwcGx5KHNjb3BlOiBJQ29uc3RydWN0LCBvcHRpb25zOiBQcmVmbGlnaHRPcHRpb25zID0ge30pOiB2b2lkIHtcbiAgICBpZiAoIVN0YWdlLmlzU3RhZ2Uoc2NvcGUpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2Nkay1wcmVmbGlnaHQ6IFByZWZsaWdodC5hcHBseSgpIG11c3QgYmUgY2FsbGVkIG9uIGFuIEFwcCBvciBhIFN0YWdlJyk7XG4gICAgfVxuICAgIGNvbnN0IGV4Y2x1ZGUgPSBvcHRpb25zLmV4Y2x1ZGUgPz8gW107XG4gICAgLy8gcGYtcXVvdGEtKiDjga8gUmVnbyDjga7jg6vjg7zjg6vjgafjga/jgarjgYTjga7jgacgQlVORExFRF9SVUxFUyDjgavjga/nhKHjgYTvvIhzcmMvcHJpdmF0ZS9xdW90YS50c++8iVxuICAgIGNvbnN0IHVua25vd24gPSBleGNsdWRlLmZpbHRlcigoaWQpID0+ICFCVU5ETEVEX1JVTEVTLnNvbWUoKHIpID0+IHIuaWQgPT09IGlkKSAmJiAhUVVPVEFfUlVMRV9JRFMuaW5jbHVkZXMoaWQpKTtcbiAgICBpZiAodW5rbm93bi5sZW5ndGggPiAwKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYGNkay1wcmVmbGlnaHQ6IHVua25vd24gcnVsZSBpZChzKSBpbiBleGNsdWRlOiAke3Vua25vd24uam9pbignLCAnKX1gKTtcbiAgICB9XG4gICAgY29uc3QgZW5mb3JjZSA9IG9wdGlvbnMuZW5mb3JjZSA/PyB0cnVlO1xuICAgIGNvbnN0IHN0cmljdCA9IG9wdGlvbnMuc3RyaWN0ID8/IGZhbHNlO1xuICAgIC8vIG1ldGEueWFtbCNzdXBlcnNlZGVkQnkg44Gu44Or44O844Or44Gv44CB44GT44Gu44Ko44Oz44K444Oz44GM5ZCM44GY6YGV5Y+N44KS6Ieq5Yqb44Gn6KaL44Gk44GR44KL44CC55yB44GP44Gu44GvXG4gICAgLy8g55yB44GE44Gm44KC5q2i44G+44KK5pa544GM5aSJ44KP44KJ44Gq44GE44Go44GN44Gg44GROiBvYnNlcnZl77yI44Gp44Gh44KJ44KC6K2m5ZGK77yJ44CBc3RyaWN077yI57WE44G/6L6844G/44GuXG4gICAgLy8gRVJST1IvRkFUQUwg44Gn5q2i44G+44KL77yJ44CBQ0RLIOiHqui6q+OBjOe1hOOBv+i+vOOBv+OCkuagvOS4i+OBkuOBl+OBquOBhOioreWumuOBruOBqOOBjeOAguaXouWumuOBriBlbmZvcmNlIOOBp+OBr1xuICAgIC8vIENESyDjgYzntYTjgb/ovrzjgb/jga4gRVJST1IvRkFUQUwg44KS6K2m5ZGK44Gr6JC944Go44GZ44Gu44Gn44CB55yB44GP44GoIHN5bnRoIOOBjOmAmuOBo+OBpuOBl+OBvuOBhuOAglxuICAgIGNvbnN0IGVuZ2luZUJsb2NrcyA9ICFlbmZvcmNlIHx8IHN0cmljdCB8fCBjZGtLZWVwc0RlZmF1bHRSdWxlRXJyb3JzKHNjb3BlKTtcbiAgICBjb25zdCB2ZXJzaW9uID0gZW5naW5lQmxvY2tzID8gZW5naW5lVmVyc2lvbigpIDogdW5kZWZpbmVkO1xuICAgIGNvbnN0IHNlbGVjdGVkID0gQlVORExFRF9SVUxFU1xuICAgICAgLmZpbHRlcigocikgPT4gKG9wdGlvbnMuaW5jbHVkZVVwc3RyZWFtUGVuZGluZyA/PyB0cnVlKSB8fCByLnVwc3RyZWFtICE9PSAncGVuZGluZy1lbmdpbmUnKVxuICAgICAgLmZpbHRlcigocikgPT4gIWV4Y2x1ZGUuaW5jbHVkZXMoci5pZCkpXG4gICAgICAuZmlsdGVyKChyKSA9PiAhaXNTdXBlcnNlZGVkKHIsIHZlcnNpb24pKTtcblxuICAgIGNvbnN0IHF1b3RhcyA9IG9wdGlvbnMuY2hlY2tRdW90YXNcbiAgICAgID8geyB0dGxNczogKG9wdGlvbnMucXVvdGFDYWNoZVR0bCA/PyBEdXJhdGlvbi5taW51dGVzKDUpKS50b01pbGxpc2Vjb25kcygpLCBleGNsdWRlIH1cbiAgICAgIDogdW5kZWZpbmVkO1xuICAgIGlmIChxdW90YXMpIGluc3RhbGxRdW90YUNhY2hlRmx1c2goc2NvcGUpO1xuICAgIGlmIChlbmZvcmNlKSB7XG4gICAgICBWYWxpZGF0aW9ucy5vZihzY29wZSkuYWRkUGx1Z2lucyhuZXcgUHJlZmxpZ2h0RW5mb3JjZVBsdWdpbihzZWxlY3RlZCwgc3RyaWN0LCBxdW90YXMpKTtcbiAgICAgIGluc3RhbGxFbmZvcmNlR2F0ZShzY29wZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIFZhbGlkYXRpb25zLm9mKHNjb3BlKS5hZGRQbHVnaW5zKG9ic2VydmVQbHVnaW5DYWNoZWQoc2VsZWN0ZWQpKTtcbiAgICAgIGlmIChxdW90YXMpIFZhbGlkYXRpb25zLm9mKHNjb3BlKS5hZGRQbHVnaW5zKG5ldyBQcmVmbGlnaHRRdW90YVBsdWdpbihxdW90YXMpKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogVGhlIGlkcyBvZiBhbGwgYnVuZGxlZCBydWxlcy5cbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgcnVsZUlkcygpOiBzdHJpbmdbXSB7XG4gICAgcmV0dXJuIEJVTkRMRURfUlVMRVMubWFwKChyKSA9PiByLmlkKTtcbiAgfVxuXG4gIHByaXZhdGUgY29uc3RydWN0b3IoKSB7fVxufVxuXG4vKipcbiAqIENESyDjgYzntYTjgb/ovrzjgb/jgqjjg7Pjgrjjg7Pjga4gRVJST1IvRkFUQUwg44KS6K2m5ZGK44Gr6JC944Go44GV44Gq44GE6Kit5a6a44GL44CC5Yik5a6a44GvIGF3cy1jZGstbGliIDIuMjcxLjAg44GuXG4gKiBzeW50aGVzaXMtdmFsaWRhdGlvbiDjgajlkIzjgZg6IGNvbnRleHQgYEBhd3MtY2RrL2NvcmU6dmFsaWRhdGVBZ2FpbnN0RGVmYXVsdFJ1bGVzYCDjgYwgZmFsc2Ug5Lul5aSW44GnXG4gKiDoqK3lrprjgZXjgozjgabjgYTjgabjgIHjgYvjgaTntYTjgb/ovrzjgb/jga7oh6rli5XnmbvpjLLjgYwgYENES19WQUxJREFUSU9OPWZhbHNlYCDjgafmraLjgoHjgonjgozjgabjgYTjgarjgYTjgZPjgajjgIJcbiAqL1xuZnVuY3Rpb24gY2RrS2VlcHNEZWZhdWx0UnVsZUVycm9ycyhzY29wZTogSUNvbnN0cnVjdCk6IGJvb2xlYW4ge1xuICBjb25zdCByYXcgPSBzY29wZS5ub2RlLnRyeUdldENvbnRleHQoJ0Bhd3MtY2RrL2NvcmU6dmFsaWRhdGVBZ2FpbnN0RGVmYXVsdFJ1bGVzJyk7XG4gIHJldHVybiByYXcgIT09IHVuZGVmaW5lZCAmJiByYXcgIT09IGZhbHNlICYmIHJhdyAhPT0gJ2ZhbHNlJyAmJiBwcm9jZXNzLmVudi5DREtfVkFMSURBVElPTiAhPT0gJ2ZhbHNlJztcbn1cbiJdfQ==
86
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7OztBQUFBLDZDQUEyRDtBQUUzRCwrQ0FBdUo7QUFDdkosK0NBQTJFO0FBQzNFLDJDQUF5RTtBQUN6RSx1REFBa0Q7QUF5RmxEOzs7Ozs7Ozs7O0dBVUc7QUFDSCxNQUFhLFNBQVM7O0lBQ3BCOztPQUVHO0lBQ0ksTUFBTSxDQUFDLEtBQUssQ0FBQyxLQUFpQixFQUFFLFVBQTRCLEVBQUU7UUFDbkUsSUFBSSxDQUFDLG1CQUFLLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUM7WUFDMUIsTUFBTSxJQUFJLEtBQUssQ0FBQyxzRUFBc0UsQ0FBQyxDQUFDO1FBQzFGLENBQUM7UUFDRCxNQUFNLE9BQU8sR0FBRyxPQUFPLENBQUMsT0FBTyxJQUFJLEVBQUUsQ0FBQztRQUN0QyxzRUFBc0U7UUFDdEUsZ0RBQWdEO1FBQ2hELE1BQU0sT0FBTyxHQUFHLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLENBQUMsK0JBQWEsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLEtBQUssRUFBRSxDQUFDO2VBQ3pFLENBQUMsc0JBQWMsQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyx5QkFBZSxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQ3BFLElBQUksT0FBTyxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQztZQUN2QixNQUFNLElBQUksS0FBSyxDQUFDLGlEQUFpRCxPQUFPLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUN6RixDQUFDO1FBQ0QsTUFBTSxPQUFPLEdBQUcsT0FBTyxDQUFDLE9BQU8sSUFBSSxJQUFJLENBQUM7UUFDeEMsTUFBTSxNQUFNLEdBQUcsT0FB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cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgRHVyYXRpb24sIFN0YWdlLCBWYWxpZGF0aW9ucyB9IGZyb20gJ2F3cy1jZGstbGliJztcbmltcG9ydCB7IElDb25zdHJ1Y3QgfSBmcm9tICdjb25zdHJ1Y3RzJztcbmltcG9ydCB7IGVuZ2luZVZlcnNpb24sIGluc3RhbGxFbmZvcmNlR2F0ZSwgaXNTdXBlcnNlZGVkLCBvYnNlcnZlUGx1Z2luQ2FjaGVkLCBQcmVmbGlnaHRFbmZvcmNlUGx1Z2luLCBQcmVmbGlnaHRRdW90YVBsdWdpbiB9IGZyb20gJy4vcHJpdmF0ZS9lbmZvcmNlJztcbmltcG9ydCB7IEVYUE9SVF9SVUxFX0lEUywgUHJlZmxpZ2h0RXhwb3J0UGx1Z2luIH0gZnJvbSAnLi9wcml2YXRlL2V4cG9ydHMnO1xuaW1wb3J0IHsgaW5zdGFsbFF1b3RhQ2FjaGVGbHVzaCwgUVVPVEFfUlVMRV9JRFMgfSBmcm9tICcuL3ByaXZhdGUvcXVvdGEnO1xuaW1wb3J0IHsgQlVORExFRF9SVUxFUyB9IGZyb20gJy4vcnVsZXMuZ2VuZXJhdGVkJztcblxuLyoqXG4gKiBPcHRpb25zIGZvciB7QGxpbmsgUHJlZmxpZ2h0LmFwcGx5fS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBQcmVmbGlnaHRPcHRpb25zIHtcbiAgLyoqXG4gICAqIFJ1bGUgaWRzIHRvIGRpc2FibGUgKHNlZSBgUHJlZmxpZ2h0LnJ1bGVJZHMoKWAgb3IgZG9jcy9ydWxlcy5tZCkuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gYWxsIGJ1bmRsZWQgcnVsZXMgYXJlIGVuYWJsZWRcbiAgICovXG4gIHJlYWRvbmx5IGV4Y2x1ZGU/OiBzdHJpbmdbXTtcblxuICAvKipcbiAgICogRmFpbCBzeW50aGVzaXMgd2hlbiBhIGJ1bmRsZWQgcnVsZSBpcyB2aW9sYXRlZC5cbiAgICpcbiAgICogSW4gdGhlIGRlZmF1bHQgKGVuZm9yY2UpIG1vZGUsIGNkay1wcmVmbGlnaHQgZXZhbHVhdGVzIGl0cyBydWxlcyB3aXRoIGl0c1xuICAgKiBvd24gdmFsaWRhdGlvbiBwbHVnaW4gYW5kIGEgdmlvbGF0aW9uIG1ha2VzIGBjZGsgc3ludGhgIGZhaWwg4oCUIHRoZSB3aG9sZVxuICAgKiBwb2ludCBvZiBwcmVmbGlnaHQgY2hlY2tzIGlzIHRoYXQgYSB0ZW1wbGF0ZSBrbm93biB0byBmYWlsIGF0IGRlcGxveSB0aW1lXG4gICAqIG5ldmVyIGxlYXZlcyB5b3VyIG1hY2hpbmUuIFNldCBgZW5mb3JjZTogZmFsc2VgIHRvIG9ic2VydmUgZmlyc3Q6IGZpbmRpbmdzXG4gICAqIGFyZSB0aGVuIHJlcG9ydGVkIHRocm91Z2ggdGhlIENESyBidWlsdC1pbiBDbG91ZEZvcm1hdGlvbiB2YWxpZGF0b3IgYW5kXG4gICAqIHN1cmZhY2UgYXMgc3ludGggd2FybmluZ3Mgd2l0aCBjb25zdHJ1Y3QgdHJhY2VzLCB3aGljaCBjYW4gYmUgbXV0ZWQgcGVyXG4gICAqIGZpbmRpbmcgdmlhIGBBY2tub3dsZWRnZSB3aXRoICdDbG91ZEZvcm1hdGlvbi1WYWxpZGF0ZTo6PHJ1bGUtaWQ+J2AuXG4gICAqXG4gICAqIEBkZWZhdWx0IHRydWVcbiAgICovXG4gIHJlYWRvbmx5IGVuZm9yY2U/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBJbiBlbmZvcmNlIG1vZGUsIGFkZGl0aW9uYWxseSBmYWlsIHN5bnRoZXNpcyBvbiBlcnJvci1jbGFzcyBmaW5kaW5nc1xuICAgKiAoc2V2ZXJpdHkgRVJST1IvRkFUQUwpIG9mIHRoZSBidWlsdC1pbiB2YWxpZGF0aW9uIGVuZ2luZSBpdHNlbGYsIGUuZy5cbiAgICogc2NoZW1hIHZpb2xhdGlvbnMgbGlrZSBgRjMwMzRgLiBUaGlzIGlzIHRoZSB3b3JrYXJvdW5kIGZvciB0aGUgQ0RLXG4gICAqIGJlaGF2aW9yIHdoZXJlIGFsbCBidWlsdC1pbiBmaW5kaW5ncyBhcmUgZG93bmdyYWRlZCB0byB3YXJuaW5ncy5cbiAgICpcbiAgICogU2luY2UgdGhlIGVuZ2luZSdzIG93biBlcnJvcnMgdGhlbiBmYWlsIHN5bnRoZXNpcywgYnVuZGxlZCBydWxlcyB0aGF0IHRoZVxuICAgKiBydW5uaW5nIGVuZ2luZSBhbHJlYWR5IGNvdmVycyBhcmUgc2tpcHBlZCBpbnN0ZWFkIG9mIGJlaW5nIHJlcG9ydGVkIHR3aWNlLlxuICAgKiBUaGUgc2FtZSBoYXBwZW5zIHdpdGggYGVuZm9yY2U6IGZhbHNlYCwgYW5kIHdoZW4gdGhlIGFwcCBzZXRzIHRoZSBjb250ZXh0XG4gICAqIGBAYXdzLWNkay9jb3JlOnZhbGlkYXRlQWdhaW5zdERlZmF1bHRSdWxlczogdHJ1ZWAuXG4gICAqXG4gICAqIE9ubHkgZWZmZWN0aXZlIGluIGVuZm9yY2UgbW9kZSAodGhlIGRlZmF1bHQpLlxuICAgKlxuICAgKiBAZGVmYXVsdCBmYWxzZVxuICAgKi9cbiAgcmVhZG9ubHkgc3RyaWN0PzogYm9vbGVhbjtcblxuICAvKipcbiAgICogSW5jbHVkZSBydWxlcyB0aGF0IGFyZSBtYXJrZWQgYHBlbmRpbmctZW5naW5lYCAoY2FuZGlkYXRlcyB0aGF0IGhhdmUgYmVlblxuICAgKiBwcm9wb3NlZCB0byB0aGUgdXBzdHJlYW0gY2xvdWRmb3JtYXRpb24tdmFsaWRhdGUgZW5naW5lIGJ1dCBhcmUgbm90IG1lcmdlZFxuICAgKiB5ZXQpLiBEaXNhYmxlIHRoaXMgaWYgeW91IHJ1biBhIG5ld2VyIGVuZ2luZSB0aGF0IGFscmVhZHkgY292ZXJzIHRoZW0uXG4gICAqXG4gICAqIFJ1bGVzIG1hcmtlZCBgY2ZuLXNjaGVtYWAgYXJlIHVuYWZmZWN0ZWQgYnkgdGhpcyBzd2l0Y2guIENsb3VkRm9ybWF0aW9uJ3NcbiAgICogb3duIHJlZ2lzdHJ5IHNjaGVtYSBkb2VzIHJlamVjdCB0aG9zZSB0ZW1wbGF0ZXMsIGJ1dCBvbmx5IHdpdGggYVxuICAgKiBzdGFjay1sZXZlbCBcIlZhbGlkYXRpb24gZmFpbGVkIHdpdGggMSBlcnJvcihzKVwiIHRoYXQgbmFtZXMgbm8gcHJvcGVydHksIHNvXG4gICAqIHRoZXkga2VlcCBlYXJuaW5nIHRoZWlyIHBsYWNlIGF0IHN5bnRoIHRpbWUgYW5kIG5vIGVuZ2luZSByZWxlYXNlIHJldGlyZXNcbiAgICogdGhlbS5cbiAgICpcbiAgICogQGRlZmF1bHQgdHJ1ZVxuICAgKi9cbiAgcmVhZG9ubHkgaW5jbHVkZVVwc3RyZWFtUGVuZGluZz86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIENvbXBhcmUgd2hhdCB0aGUgYXBwIGlzIGFib3V0IHRvIGNyZWF0ZSBhZ2FpbnN0IHRoZSB0YXJnZXQgYWNjb3VudCdzXG4gICAqIFNlcnZpY2UgUXVvdGFzIGFuZCBjdXJyZW50IHVzYWdlOiBWUENzLCBpbnRlcm5ldCBnYXRld2F5cyBhbmQgRWxhc3RpYyBJUHNcbiAgICogcGVyIFJlZ2lvbiwgYW5kIHRoZSB1bnJlc2VydmVkIExhbWJkYSBjb25jdXJyZW5jeSBsZWZ0IGFmdGVyIHJlc2VydmVkXG4gICAqIGNvbmN1cnJlbmN5IGNoYW5nZXMuIENvdW50cyBhcmUgc3VtbWVkIG92ZXIgZXZlcnkgc3RhY2sgKGluY2x1ZGluZyBuZXN0ZWRcbiAgICogc3RhY2tzKSB0aGF0IGRlcGxveXMgdG8gdGhlIHNhbWUgYWNjb3VudCBhbmQgUmVnaW9uLCBhbmQgcmVzb3VyY2VzIHRoYXRcbiAgICogYWxyZWFkeSBleGlzdCBpbiB0aGUgZGVwbG95ZWQgc3RhY2sgYXJlIG5vdCBjb3VudGVkIGFnYWluLlxuICAgKlxuICAgKiBUaGlzIGlzIHRoZSBvbmUgZmVhdHVyZSB0aGF0IG1ha2VzIHN5bnRoIGNhbGwgQVdTLiBJdCBuZWVkcyBjcmVkZW50aWFsc1xuICAgKiBmb3IgdGhlIHRhcmdldCBhY2NvdW50IGluIHRoZSBhcHAgcHJvY2VzczogdGhlIENESyBDTEkgZG9lcyBub3QgcGFzc1xuICAgKiBgLS1wcm9maWxlYCBvbiB0byB0aGUgYXBwLCBzbyBzZXQgYEFXU19QUk9GSUxFYCAob3IgYEFXU18qYCB2YXJpYWJsZXMpXG4gICAqIGluc3RlYWQuIFdpdGhvdXQgdXNhYmxlIGNyZWRlbnRpYWxzIHRoZSBjaGVjayBpcyBza2lwcGVkIHdpdGggYSB3YXJuaW5nXG4gICAqIGFuZCBzeW50aCBnb2VzIG9uLiBBIGZpbmRpbmcgZmFpbHMgc3ludGggaW4gZW5mb3JjZSBtb2RlIGFuZCBpcyBhIHdhcm5pbmdcbiAgICogd2l0aCBgZW5mb3JjZTogZmFsc2VgLlxuICAgKlxuICAgKiBAZGVmYXVsdCBmYWxzZVxuICAgKi9cbiAgcmVhZG9ubHkgY2hlY2tRdW90YXM/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBIb3cgbG9uZyBgY2hlY2tRdW90YXNgIHJldXNlcyB0aGUgdXNhZ2UgYW5kIGRlcGxveWVkLXN0YWNrIHN0YXRlIGl0XG4gICAqIGZldGNoZWQsIGNhY2hlZCB1bmRlciB0aGUgY2xvdWQgYXNzZW1ibHkgZGlyZWN0b3J5IChgY2RrLm91dGApLiBRdW90YVxuICAgKiB2YWx1ZXMgdGhlbXNlbHZlcyBhcmUgY2FjaGVkIGZvciAyNCBob3Vycy5cbiAgICpcbiAgICogQGRlZmF1bHQgRHVyYXRpb24ubWludXRlcyg1KVxuICAgKi9cbiAgcmVhZG9ubHkgcXVvdGFDYWNoZVR0bD86IER1cmF0aW9uO1xufVxuXG4vKipcbiAqIGNkay1wcmVmbGlnaHQ6IGNhdGNoIGRlcGxveS10aW1lIENsb3VkRm9ybWF0aW9uIGZhaWx1cmVzIGF0IHN5bnRoIHRpbWUuXG4gKlxuICogSW5qZWN0cyBhIGN1cmF0ZWQgUmVnbyBydWxlIHBhY2sgKGNvbnN0cmFpbnRzIHRoYXQgcmVzb3VyY2UgcHJvdmlkZXIgc2NoZW1hc1xuICogZG8gbm90IGV4cHJlc3M6IGRvYy1vbmx5IHZhbHVlIGxpbWl0cywgY3Jvc3MtcHJvcGVydHkgYW5kIGNyb3NzLXJlc291cmNlXG4gKiBydWxlcykgaW50byB0aGUgQVdTIENESyBidWlsdC1pbiBDbG91ZEZvcm1hdGlvbiB2YWxpZGF0b3IuXG4gKlxuICogQGV4YW1wbGVcbiAqIGRlY2xhcmUgY29uc3QgYXBwOiBBcHA7XG4gKiBQcmVmbGlnaHQuYXBwbHkoYXBwKTtcbiAqL1xuZXhwb3J0IGNsYXNzIFByZWZsaWdodCB7XG4gIC8qKlxuICAgKiBSZWdpc3RlciB0aGUgY2RrLXByZWZsaWdodCBydWxlcyBvbiBhbiBBcHAgb3IgU3RhZ2UuXG4gICAqL1xuICBwdWJsaWMgc3RhdGljIGFwcGx5KHNjb3BlOiBJQ29uc3RydWN0LCBvcHRpb25zOiBQcmVmbGlnaHRPcHRpb25zID0ge30pOiB2b2lkIHtcbiAgICBpZiAoIVN0YWdlLmlzU3RhZ2Uoc2NvcGUpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2Nkay1wcmVmbGlnaHQ6IFByZWZsaWdodC5hcHBseSgpIG11c3QgYmUgY2FsbGVkIG9uIGFuIEFwcCBvciBhIFN0YWdlJyk7XG4gICAgfVxuICAgIGNvbnN0IGV4Y2x1ZGUgPSBvcHRpb25zLmV4Y2x1ZGUgPz8gW107XG4gICAgLy8gcGYtcXVvdGEtKiDjgagg44K544K/44OD44Kv6ZaT44GuIEV4cG9ydCDjga7jg6vjg7zjg6vjga8gUmVnbyDjga7jg6vjg7zjg6vjgafjga/jgarjgYTjga7jgacgQlVORExFRF9SVUxFUyDjgavjga/nhKHjgYRcbiAgICAvLyDvvIhzcmMvcHJpdmF0ZS9xdW90YS50c+OAgXNyYy9wcml2YXRlL2V4cG9ydHMudHPvvIlcbiAgICBjb25zdCB1bmtub3duID0gZXhjbHVkZS5maWx0ZXIoKGlkKSA9PiAhQlVORExFRF9SVUxFUy5zb21lKChyKSA9PiByLmlkID09PSBpZClcbiAgICAgICYmICFRVU9UQV9SVUxFX0lEUy5pbmNsdWRlcyhpZCkgJiYgIUVYUE9SVF9SVUxFX0lEUy5pbmNsdWRlcyhpZCkpO1xuICAgIGlmICh1bmtub3duLmxlbmd0aCA+IDApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgY2RrLXByZWZsaWdodDogdW5rbm93biBydWxlIGlkKHMpIGluIGV4Y2x1ZGU6ICR7dW5rbm93bi5qb2luKCcsICcpfWApO1xuICAgIH1cbiAgICBjb25zdCBlbmZvcmNlID0gb3B0aW9ucy5lbmZvcmNlID8/IHRydWU7XG4gICAgY29uc3Qgc3RyaWN0ID0gb3B0aW9ucy5zdHJpY3QgPz8gZmFsc2U7XG4gICAgLy8gbWV0YS55YW1sI3N1cGVyc2VkZWRCeSDjga7jg6vjg7zjg6vjga/jgIHjgZPjga7jgqjjg7Pjgrjjg7PjgYzlkIzjgZjpgZXlj43jgpLoh6rlipvjgafopovjgaTjgZHjgovjgILnnIHjgY/jga7jga9cbiAgICAvLyDnnIHjgYTjgabjgoLmraLjgb7jgormlrnjgYzlpInjgo/jgonjgarjgYTjgajjgY3jgaDjgZE6IG9ic2VydmXvvIjjganjgaHjgonjgoLorablkYrvvInjgIFzdHJpY3TvvIjntYTjgb/ovrzjgb/jga5cbiAgICAvLyBFUlJPUi9GQVRBTCDjgafmraLjgb7jgovvvInjgIFDREsg6Ieq6Lqr44GM57WE44G/6L6844G/44KS5qC85LiL44GS44GX44Gq44GE6Kit5a6a44Gu44Go44GN44CC5pei5a6a44GuIGVuZm9yY2Ug44Gn44GvXG4gICAgLy8gQ0RLIOOBjOe1hOOBv+i+vOOBv+OBriBFUlJPUi9GQVRBTCDjgpLorablkYrjgavokL3jgajjgZnjga7jgafjgIHnnIHjgY/jgaggc3ludGgg44GM6YCa44Gj44Gm44GX44G+44GG44CCXG4gICAgY29uc3QgZW5naW5lQmxvY2tzID0gIWVuZm9yY2UgfHwgc3RyaWN0IHx8IGNka0tlZXBzRGVmYXVsdFJ1bGVFcnJvcnMoc2NvcGUpO1xuICAgIGNvbnN0IHZlcnNpb24gPSBlbmdpbmVCbG9ja3MgPyBlbmdpbmVWZXJzaW9uKCkgOiB1bmRlZmluZWQ7XG4gICAgY29uc3Qgc2VsZWN0ZWQgPSBCVU5ETEVEX1JVTEVTXG4gICAgICAuZmlsdGVyKChyKSA9PiAob3B0aW9ucy5pbmNsdWRlVXBzdHJlYW1QZW5kaW5nID8/IHRydWUpIHx8IHIudXBzdHJlYW0gIT09ICdwZW5kaW5nLWVuZ2luZScpXG4gICAgICAuZmlsdGVyKChyKSA9PiAhZXhjbHVkZS5pbmNsdWRlcyhyLmlkKSlcbiAgICAgIC5maWx0ZXIoKHIpID0+ICFpc1N1cGVyc2VkZWQociwgdmVyc2lvbikpO1xuXG4gICAgY29uc3QgcXVvdGFzID0gb3B0aW9ucy5jaGVja1F1b3Rhc1xuICAgICAgPyB7IHR0bE1zOiAob3B0aW9ucy5xdW90YUNhY2hlVHRsID8/IER1cmF0aW9uLm1pbnV0ZXMoNSkpLnRvTWlsbGlzZWNvbmRzKCksIGV4Y2x1ZGUgfVxuICAgICAgOiB1bmRlZmluZWQ7XG4gICAgaWYgKHF1b3RhcykgaW5zdGFsbFF1b3RhQ2FjaGVGbHVzaChzY29wZSk7XG4gICAgaWYgKCFFWFBPUlRfUlVMRV9JRFMuZXZlcnkoKGlkKSA9PiBleGNsdWRlLmluY2x1ZGVzKGlkKSkpIHtcbiAgICAgIFZhbGlkYXRpb25zLm9mKHNjb3BlKS5hZGRQbHVnaW5zKG5ldyBQcmVmbGlnaHRFeHBvcnRQbHVnaW4oZXhjbHVkZSkpO1xuICAgIH1cbiAgICBpZiAoZW5mb3JjZSkge1xuICAgICAgVmFsaWRhdGlvbnMub2Yoc2NvcGUpLmFkZFBsdWdpbnMobmV3IFByZWZsaWdodEVuZm9yY2VQbHVnaW4oc2VsZWN0ZWQsIHN0cmljdCwgcXVvdGFzKSk7XG4gICAgICBpbnN0YWxsRW5mb3JjZUdhdGUoc2NvcGUpO1xuICAgIH0gZWxzZSB7XG4gICAgICBWYWxpZGF0aW9ucy5vZihzY29wZSkuYWRkUGx1Z2lucyhvYnNlcnZlUGx1Z2luQ2FjaGVkKHNlbGVjdGVkKSk7XG4gICAgICBpZiAocXVvdGFzKSBWYWxpZGF0aW9ucy5vZihzY29wZSkuYWRkUGx1Z2lucyhuZXcgUHJlZmxpZ2h0UXVvdGFQbHVnaW4ocXVvdGFzKSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFRoZSBpZHMgb2YgYWxsIGJ1bmRsZWQgcnVsZXMuXG4gICAqL1xuICBwdWJsaWMgc3RhdGljIHJ1bGVJZHMoKTogc3RyaW5nW10ge1xuICAgIHJldHVybiBCVU5ETEVEX1JVTEVTLm1hcCgocikgPT4gci5pZCk7XG4gIH1cblxuICBwcml2YXRlIGNvbnN0cnVjdG9yKCkge31cbn1cblxuLyoqXG4gKiBDREsg44GM57WE44G/6L6844G/44Ko44Oz44K444Oz44GuIEVSUk9SL0ZBVEFMIOOCkuitpuWRiuOBq+iQveOBqOOBleOBquOBhOioreWumuOBi+OAguWIpOWumuOBryBhd3MtY2RrLWxpYiAyLjI3MS4wIOOBrlxuICogc3ludGhlc2lzLXZhbGlkYXRpb24g44Go5ZCM44GYOiBjb250ZXh0IGBAYXdzLWNkay9jb3JlOnZhbGlkYXRlQWdhaW5zdERlZmF1bHRSdWxlc2Ag44GMIGZhbHNlIOS7peWkluOBp1xuICog6Kit5a6a44GV44KM44Gm44GE44Gm44CB44GL44Gk57WE44G/6L6844G/44Gu6Ieq5YuV55m76Yyy44GMIGBDREtfVkFMSURBVElPTj1mYWxzZWAg44Gn5q2i44KB44KJ44KM44Gm44GE44Gq44GE44GT44Go44CCXG4gKi9cbmZ1bmN0aW9uIGNka0tlZXBzRGVmYXVsdFJ1bGVFcnJvcnMoc2NvcGU6IElDb25zdHJ1Y3QpOiBib29sZWFuIHtcbiAgY29uc3QgcmF3ID0gc2NvcGUubm9kZS50cnlHZXRDb250ZXh0KCdAYXdzLWNkay9jb3JlOnZhbGlkYXRlQWdhaW5zdERlZmF1bHRSdWxlcycpO1xuICByZXR1cm4gcmF3ICE9PSB1bmRlZmluZWQgJiYgcmF3ICE9PSBmYWxzZSAmJiByYXcgIT09ICdmYWxzZScgJiYgcHJvY2Vzcy5lbnYuQ0RLX1ZBTElEQVRJT04gIT09ICdmYWxzZSc7XG59XG4iXX0=
@@ -0,0 +1,33 @@
1
+ import type { IPolicyValidationContext, IPolicyValidationPlugin, PolicyValidationPluginReport, PolicyViolation } from 'aws-cdk-lib';
2
+ /**
3
+ * スタックをまたぐ Export の検査(issue #263 の候補 1 と 2)。Rego はテンプレートを 1 枚ずつしか
4
+ * 見ないので、アプリの全スタックを読むこのプラグイン側で判定する。
5
+ *
6
+ * - pf-cfn-export-name-conflict: 同じ環境(account × region)に向かう 2 つのスタックが同じ
7
+ * Export.Name を宣言している。後からデプロイする方が
8
+ * "Export with name X is already exported by stack Y" で失敗する。
9
+ * - pf-cfn-import-value-missing-export: `Fn::ImportValue` の名前が、このアプリのスタックの命名
10
+ * (CDK が自動で付ける `<stackName>:...`)なのに、同じ環境のそのスタックが export していない。
11
+ * "No export named X found" で失敗する。アプリの外のスタックが同じ名前を export している
12
+ * 可能性はテンプレートからは消せないので、名前がアプリ内のスタック名で始まるものに限る。
13
+ *
14
+ * どちらも実アカウントでの再現(bench)がまだ無いので、AGENTS.md の doc-only と同じく
15
+ * warning として報告し、synth は止めない。
16
+ */
17
+ export declare const EXPORT_CONFLICT_RULE = "pf-cfn-export-name-conflict";
18
+ export declare const IMPORT_MISSING_RULE = "pf-cfn-import-value-missing-export";
19
+ export declare const EXPORT_RULE_IDS: string[];
20
+ export declare function checkExports(context: Pick<IPolicyValidationContext, 'stackTemplates'>, opts: {
21
+ severity: string;
22
+ exclude?: string[];
23
+ }): PolicyViolation[];
24
+ /**
25
+ * スタック間の Export を検査するプラグイン。どちらのルールもまだ warning なので、enforce でも
26
+ * observe でも同じプラグインで報告する(`cdk-preflight-exports::<rule-id>` で acknowledge)。
27
+ */
28
+ export declare class PreflightExportPlugin implements IPolicyValidationPlugin {
29
+ private readonly exclude;
30
+ readonly name = "cdk-preflight-exports";
31
+ constructor(exclude?: string[]);
32
+ validate(context: IPolicyValidationContext): PolicyValidationPluginReport;
33
+ }
@@ -0,0 +1,186 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.PreflightExportPlugin = exports.EXPORT_RULE_IDS = exports.IMPORT_MISSING_RULE = exports.EXPORT_CONFLICT_RULE = void 0;
37
+ exports.checkExports = checkExports;
38
+ const fs = __importStar(require("fs"));
39
+ const enforce_1 = require("./enforce");
40
+ const quota_1 = require("./quota");
41
+ /**
42
+ * スタックをまたぐ Export の検査(issue #263 の候補 1 と 2)。Rego はテンプレートを 1 枚ずつしか
43
+ * 見ないので、アプリの全スタックを読むこのプラグイン側で判定する。
44
+ *
45
+ * - pf-cfn-export-name-conflict: 同じ環境(account × region)に向かう 2 つのスタックが同じ
46
+ * Export.Name を宣言している。後からデプロイする方が
47
+ * "Export with name X is already exported by stack Y" で失敗する。
48
+ * - pf-cfn-import-value-missing-export: `Fn::ImportValue` の名前が、このアプリのスタックの命名
49
+ * (CDK が自動で付ける `<stackName>:...`)なのに、同じ環境のそのスタックが export していない。
50
+ * "No export named X found" で失敗する。アプリの外のスタックが同じ名前を export している
51
+ * 可能性はテンプレートからは消せないので、名前がアプリ内のスタック名で始まるものに限る。
52
+ *
53
+ * どちらも実アカウントでの再現(bench)がまだ無いので、AGENTS.md の doc-only と同じく
54
+ * warning として報告し、synth は止めない。
55
+ */
56
+ exports.EXPORT_CONFLICT_RULE = 'pf-cfn-export-name-conflict';
57
+ exports.IMPORT_MISSING_RULE = 'pf-cfn-import-value-missing-export';
58
+ exports.EXPORT_RULE_IDS = [exports.EXPORT_CONFLICT_RULE, exports.IMPORT_MISSING_RULE];
59
+ /** 具体的でない環境は 1 つにまとめる(環境非依存のスタックは同じ CLI の環境にデプロイされる)。 */
60
+ function envKey(st) {
61
+ const account = (0, enforce_1.isConcreteAccount)(st.accountId) ? st.accountId : process.env.CDK_DEFAULT_ACCOUNT ?? '';
62
+ const region = (0, enforce_1.isConcreteRegion)(st.region) ? st.region : process.env.CDK_DEFAULT_REGION ?? '';
63
+ return `${account}/${region}`;
64
+ }
65
+ /** テンプレートの中の `Fn::ImportValue` のうち、名前が文字列のもの。 */
66
+ function findImports(node, logicalId, out) {
67
+ if (Array.isArray(node)) {
68
+ for (const x of node)
69
+ findImports(x, logicalId, out);
70
+ return;
71
+ }
72
+ if (node === null || typeof node !== 'object')
73
+ return;
74
+ for (const [k, v] of Object.entries(node)) {
75
+ if (k === 'Fn::ImportValue' && typeof v === 'string') {
76
+ out.push({ name: v, logicalId });
77
+ }
78
+ else {
79
+ findImports(v, logicalId, out);
80
+ }
81
+ }
82
+ }
83
+ function readStacks(context) {
84
+ const stacks = [];
85
+ for (const st of context.stackTemplates) {
86
+ let template;
87
+ try {
88
+ template = JSON.parse(fs.readFileSync(st.templatePath, 'utf8'));
89
+ }
90
+ catch {
91
+ continue; // 読めないテンプレートは他のプラグインが報告する
92
+ }
93
+ const exports = new Map();
94
+ for (const [id, o] of Object.entries(template.Outputs ?? {})) {
95
+ const name = o?.Export?.Name;
96
+ if (typeof name === 'string')
97
+ exports.set(name, id);
98
+ }
99
+ const imports = [];
100
+ for (const [id, r] of Object.entries(template.Resources ?? {}))
101
+ findImports(r, id, imports);
102
+ for (const [id, o] of Object.entries(template.Outputs ?? {}))
103
+ findImports(o?.Value, id, imports);
104
+ stacks.push({
105
+ stackName: (0, quota_1.stackNameOf)(st.templatePath),
106
+ stackConstructPath: st.stackConstructPath,
107
+ templatePath: st.templatePath,
108
+ env: envKey(st),
109
+ exports,
110
+ imports,
111
+ });
112
+ }
113
+ return stacks;
114
+ }
115
+ function checkExports(context, opts) {
116
+ const violations = [];
117
+ const stacks = readStacks(context);
118
+ const byEnv = new Map();
119
+ for (const s of stacks)
120
+ byEnv.set(s.env, [...(byEnv.get(s.env) ?? []), s]);
121
+ for (const group of byEnv.values()) {
122
+ // 1. 同じ環境で同じ Export.Name を持つスタックの組
123
+ const owner = new Map();
124
+ for (const s of group) {
125
+ for (const [name, outputId] of s.exports) {
126
+ const first = owner.get(name);
127
+ if (!first) {
128
+ owner.set(name, s);
129
+ continue;
130
+ }
131
+ if (first.stackName === s.stackName)
132
+ continue; // 同じスタック名 = 別環境の同名スタック(envKey が粗いとき)
133
+ violations.push({
134
+ ruleName: exports.EXPORT_CONFLICT_RULE,
135
+ description: `Stacks ${first.stackName} and ${s.stackName} deploy to the same account and Region and both export "${name}"; `
136
+ + `export names must be unique there, so the second deploy fails with "Export with name ${name} is already exported by stack ${first.stackName}".`,
137
+ severity: opts.severity,
138
+ fix: 'Give one of the outputs a different exportName, or drop the explicit name and let CDK generate one.',
139
+ violatingResources: [{
140
+ resourceLogicalId: outputId,
141
+ templatePath: s.templatePath,
142
+ locations: [`Outputs/${outputId}/Export/Name`],
143
+ }],
144
+ });
145
+ }
146
+ }
147
+ // 2. アプリ内のスタック名で始まる import 名を、そのスタックが export していない
148
+ const byName = new Map(group.map((s) => [s.stackName, s]));
149
+ for (const s of group) {
150
+ for (const imp of s.imports) {
151
+ const producer = byName.get(imp.name.split(':')[0]);
152
+ if (!imp.name.includes(':') || !producer || producer.exports.has(imp.name))
153
+ continue;
154
+ violations.push({
155
+ ruleName: exports.IMPORT_MISSING_RULE,
156
+ description: `${s.stackName} imports "${imp.name}", but stack ${producer.stackName} in this app, which deploys to the same account `
157
+ + `and Region, has no output exported under that name; the deploy fails with "No export named ${imp.name} found".`,
158
+ severity: opts.severity,
159
+ fix: `Export the value from ${producer.stackName} under this name (CfnOutput exportName), or reference the construct directly so CDK creates the export.`,
160
+ violatingResources: [{
161
+ resourceLogicalId: imp.logicalId,
162
+ templatePath: s.templatePath,
163
+ locations: [`Resources/${imp.logicalId}`],
164
+ }],
165
+ });
166
+ }
167
+ }
168
+ }
169
+ return violations.filter((v) => !opts.exclude?.includes(v.ruleName));
170
+ }
171
+ /**
172
+ * スタック間の Export を検査するプラグイン。どちらのルールもまだ warning なので、enforce でも
173
+ * observe でも同じプラグインで報告する(`cdk-preflight-exports::<rule-id>` で acknowledge)。
174
+ */
175
+ class PreflightExportPlugin {
176
+ exclude;
177
+ name = 'cdk-preflight-exports';
178
+ constructor(exclude = []) {
179
+ this.exclude = exclude;
180
+ }
181
+ validate(context) {
182
+ return { success: true, violations: checkExports(context, { severity: 'warning', exclude: this.exclude }) };
183
+ }
184
+ }
185
+ exports.PreflightExportPlugin = PreflightExportPlugin;
186
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXhwb3J0cy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9wcml2YXRlL2V4cG9ydHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBcUZBLG9DQXdEQztBQTdJRCx1Q0FBeUI7QUFFekIsdUNBQWdFO0FBQ2hFLG1DQUFzQztBQUV0Qzs7Ozs7Ozs7Ozs7Ozs7R0FjRztBQUNVLFFBQUEsb0JBQW9CLEdBQUcsNkJBQTZCLENBQUM7QUFDckQsUUFBQSxtQkFBbUIsR0FBRyxvQ0FBb0MsQ0FBQztBQUMzRCxRQUFBLGVBQWUsR0FBRyxDQUFDLDRCQUFvQixFQUFFLDJCQUFtQixDQUFDLENBQUM7QUFXM0UseURBQXlEO0FBQ3pELFNBQVMsTUFBTSxDQUFDLEVBQTJDO0lBQ3pELE1BQU0sT0FBTyxHQUFHLElBQUEsMkJBQWlCLEVBQUMsRUFBRSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLG1CQUFtQixJQUFJLEVBQUUsQ0FBQztJQUN2RyxNQUFNLE1BQU0sR0FBRyxJQUFBLDBCQUFnQixFQUFDLEVBQUUsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxrQkFBa0IsSUFBSSxFQUFFLENBQUM7SUFDOUYsT0FBTyxHQUFHLE9BQU8sSUFBSSxNQUFNLEVBQUUsQ0FBQztBQUNoQyxDQUFDO0FBRUQsaURBQWlEO0FBQ2pELFNBQVMsV0FBVyxDQUFDLElBQWEsRUFBRSxTQUFpQixFQUFFLEdBQTBDO0lBQy9GLElBQUksS0FBSyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDO1FBQ3hCLEtBQUssTUFBTSxDQUFDLElBQUksSUFBSTtZQUFFLFdBQVcsQ0FBQyxDQUFDLEVBQUUs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QyxZQUFZOzRCQUM1QixTQUFTLEVBQUUsQ0FBQyxhQUFhLEdBQUcsQ0FBQyxTQUFTLEVBQUUsQ0FBQzt5QkFDMUMsQ0FBQztpQkFDSCxDQUFDLENBQUM7WUFDTCxDQUFDO1FBQ0gsQ0FBQztJQUNILENBQUM7SUFDRCxPQUFPLFVBQVUsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxRQUFRLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUM7QUFDdkUsQ0FBQztBQUVEOzs7R0FHRztBQUNILE1BQWEscUJBQXFCO0lBR0g7SUFGYixJQUFJLEdBQUcsdUJBQXVCLENBQUM7SUFFL0MsWUFBNkIsVUFBb0IsRUFBRTtRQUF0QixZQUFPLEdBQVAsT0FBTyxDQUFlO0lBQUcsQ0FBQztJQUVoRCxRQUFRLENBQUMsT0FBaUM7UUFDL0MsT0FBTyxFQUFFLE9BQU8sRUFBRSxJQUFJLEVBQUUsVUFBVSxFQUFFLFlBQVksQ0FBQyxPQUFPLEVBQUUsRUFBRSxRQUFRLEVBQUUsU0FBUyxFQUFFLE9BQU8sRUFBRSxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUMsRUFBRSxDQUFDO0lBQzlHLENBQUM7Q0FDRjtBQVJELHNEQVFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgZnMgZnJvbSAnZnMnO1xuaW1wb3J0IHR5cGUgeyBJUG9saWN5VmFsaWRhdGlvbkNvbnRleHQsIElQb2xpY3lWYWxpZGF0aW9uUGx1Z2luLCBQb2xpY3lWYWxpZGF0aW9uUGx1Z2luUmVwb3J0LCBQb2xpY3lWaW9sYXRpb24gfSBmcm9tICdhd3MtY2RrLWxpYic7XG5pbXBvcnQgeyBpc0NvbmNyZXRlQWNjb3VudCwgaXNDb25jcmV0ZVJlZ2lvbiB9IGZyb20gJy4vZW5mb3JjZSc7XG5pbXBvcnQgeyBzdGFja05hbWVPZiB9IGZyb20gJy4vcXVvdGEnO1xuXG4vKipcbiAqIOOCueOCv+ODg+OCr+OCkuOBvuOBn+OBkCBFeHBvcnQg44Gu5qSc5p+777yIaXNzdWUgIzI2MyDjga7lgJnoo5wgMSDjgaggMu+8ieOAglJlZ28g44Gv44OG44Oz44OX44Os44O844OI44KSIDEg5p6a44Ga44Gk44GX44GLXG4gKiDopovjgarjgYTjga7jgafjgIHjgqLjg5fjg6rjga7lhajjgrnjgr/jg4Pjgq/jgpLoqq3jgoDjgZPjga7jg5fjg6njgrDjgqTjg7PlgbTjgafliKTlrprjgZnjgovjgIJcbiAqXG4gKiAtIHBmLWNmbi1leHBvcnQtbmFtZS1jb25mbGljdDog5ZCM44GY55Kw5aKD77yIYWNjb3VudCDDlyByZWdpb27vvInjgavlkJHjgYvjgYYgMiDjgaTjga7jgrnjgr/jg4Pjgq/jgYzlkIzjgZhcbiAqICAgRXhwb3J0Lk5hbWUg44KS5a6j6KiA44GX44Gm44GE44KL44CC5b6M44GL44KJ44OH44OX44Ot44Kk44GZ44KL5pa544GMXG4gKiAgIFwiRXhwb3J0IHdpdGggbmFtZSBYIGlzIGFscmVhZHkgZXhwb3J0ZWQgYnkgc3RhY2sgWVwiIOOBp+WkseaVl+OBmeOCi+OAglxuICogLSBwZi1jZm4taW1wb3J0LXZhbHVlLW1pc3NpbmctZXhwb3J0OiBgRm46OkltcG9ydFZhbHVlYCDjga7lkI3liY3jgYzjgIHjgZPjga7jgqLjg5fjg6rjga7jgrnjgr/jg4Pjgq/jga7lkb3lkI1cbiAqICAg77yIQ0RLIOOBjOiHquWLleOBp+S7mOOBkeOCiyBgPHN0YWNrTmFtZT46Li4uYO+8ieOBquOBruOBq+OAgeWQjOOBmOeSsOWig+OBruOBneOBruOCueOCv+ODg+OCr+OBjCBleHBvcnQg44GX44Gm44GE44Gq44GE44CCXG4gKiAgIFwiTm8gZXhwb3J0IG5hbWVkIFggZm91bmRcIiDjgaflpLHmlZfjgZnjgovjgILjgqLjg5fjg6rjga7lpJbjga7jgrnjgr/jg4Pjgq/jgYzlkIzjgZjlkI3liY3jgpIgZXhwb3J0IOOBl+OBpuOBhOOCi1xuICogICDlj6/og73mgKfjga/jg4bjg7Pjg5fjg6zjg7zjg4jjgYvjgonjga/mtojjgZvjgarjgYTjga7jgafjgIHlkI3liY3jgYzjgqLjg5fjg6rlhoXjga7jgrnjgr/jg4Pjgq/lkI3jgaflp4vjgb7jgovjgoLjga7jgavpmZDjgovjgIJcbiAqXG4gKiDjganjgaHjgonjgoLlrp/jgqLjgqvjgqbjg7Pjg4jjgafjga7lho3nj77vvIhiZW5jaO+8ieOBjOOBvuOBoOeEoeOBhOOBruOBp+OAgUFHRU5UUy5tZCDjga4gZG9jLW9ubHkg44Go5ZCM44GY44GPXG4gKiB3YXJuaW5nIOOBqOOBl+OBpuWgseWRiuOBl+OAgXN5bnRoIOOBr+atouOCgeOBquOBhOOAglxuICovXG5leHBvcnQgY29uc3QgRVhQT1JUX0NPTkZMSUNUX1JVTEUgPSAncGYtY2ZuLWV4cG9ydC1uYW1lLWNvbmZsaWN0JztcbmV4cG9ydCBjb25zdCBJTVBPUlRfTUlTU0lOR19SVUxFID0gJ3BmLWNmbi1pbXBvcnQtdmFsdWUtbWlzc2luZy1leHBvcnQnO1xuZXhwb3J0IGNvbnN0IEVYUE9SVF9SVUxFX0lEUyA9IFtFWFBPUlRfQ09ORkxJQ1RfUlVMRSwgSU1QT1JUX01JU1NJTkdfUlVMRV07XG5cbmludGVyZmFjZSBTdGFja0V4cG9ydHMge1xuICBzdGFja05hbWU6IHN0cmluZztcbiAgc3RhY2tDb25zdHJ1Y3RQYXRoOiBzdHJpbmc7XG4gIHRlbXBsYXRlUGF0aDogc3RyaW5nO1xuICBlbnY6IHN0cmluZztcbiAgZXhwb3J0czogTWFwPHN0cmluZywgc3RyaW5nPjsgLy8gRXhwb3J0Lk5hbWUgLT4gT3V0cHV0IOOBruirlueQhiBJRFxuICBpbXBvcnRzOiB7IG5hbWU6IHN0cmluZzsgbG9naWNhbElkOiBzdHJpbmcgfVtdO1xufVxuXG4vKiog5YW35L2T55qE44Gn44Gq44GE55Kw5aKD44GvIDEg44Gk44Gr44G+44Go44KB44KL77yI55Kw5aKD6Z2e5L6d5a2Y44Gu44K544K/44OD44Kv44Gv5ZCM44GYIENMSSDjga7nkrDlooPjgavjg4fjg5fjg63jgqTjgZXjgozjgovvvInjgIIgKi9cbmZ1bmN0aW9uIGVudktleShzdDogeyBhY2NvdW50SWQ/OiBzdHJpbmc7IHJlZ2lvbj86IHN0cmluZyB9KTogc3RyaW5nIHtcbiAgY29uc3QgYWNjb3VudCA9IGlzQ29uY3JldGVBY2NvdW50KHN0LmFjY291bnRJZCkgPyBzdC5hY2NvdW50SWQgOiBwcm9jZXNzLmVudi5DREtfREVGQVVMVF9BQ0NPVU5UID8/ICcnO1xuICBjb25zdCByZWdpb24gPSBpc0NvbmNyZXRlUmVnaW9uKHN0LnJlZ2lvbikgPyBzdC5yZWdpb24gOiBwcm9jZXNzLmVudi5DREtfREVGQVVMVF9SRUdJT04gPz8gJyc7XG4gIHJldHVybiBgJHthY2NvdW50fS8ke3JlZ2lvbn1gO1xufVxuXG4vKiog44OG44Oz44OX44Os44O844OI44Gu5Lit44GuIGBGbjo6SW1wb3J0VmFsdWVgIOOBruOBhuOBoeOAgeWQjeWJjeOBjOaWh+Wtl+WIl+OBruOCguOBruOAgiAqL1xuZnVuY3Rpb24gZmluZEltcG9ydHMobm9kZTogdW5rbm93biwgbG9naWNhbElkOiBzdHJpbmcsIG91dDogeyBuYW1lOiBzdHJpbmc7IGxvZ2ljYWxJZDogc3RyaW5nIH1bXSk6IHZvaWQge1xuICBpZiAoQXJyYXkuaXNBcnJheShub2RlKSkge1xuICAgIGZvciAoY29uc3QgeCBvZiBub2RlKSBmaW5kSW1wb3J0cyh4LCBsb2dpY2FsSWQsIG91dCk7XG4gICAgcmV0dXJuO1xuICB9XG4gIGlmIChub2RlID09PSBudWxsIHx8IHR5cGVvZiBub2RlICE9PSAnb2JqZWN0JykgcmV0dXJuO1xuICBmb3IgKGNvbnN0IFtrLCB2XSBvZiBPYmplY3QuZW50cmllcyhub2RlKSkge1xuICAgIGlmIChrID09PSAnRm46OkltcG9ydFZhbHVlJyAmJiB0eXBlb2YgdiA9PT0gJ3N0cmluZycpIHtcbiAgICAgIG91dC5wdXNoKHsgbmFtZTogdiwgbG9naWNhbElkIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICBmaW5kSW1wb3J0cyh2LCBsb2dpY2FsSWQsIG91dCk7XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIHJlYWRTdGFja3MoY29udGV4dDogUGljazxJUG9saWN5VmFsaWRhdGlvbkNvbnRleHQsICdzdGFja1RlbXBsYXRlcyc+KTogU3RhY2tFeHBvcnRzW10ge1xuICBjb25zdCBzdGFja3M6IFN0YWNrRXhwb3J0c1tdID0gW107XG4gIGZvciAoY29uc3Qgc3Qgb2YgY29udGV4dC5zdGFja1RlbXBsYXRlcykge1xuICAgIGxldCB0ZW1wbGF0ZTogYW55O1xuICAgIHRyeSB7XG4gICAgICB0ZW1wbGF0ZSA9IEpTT04ucGFyc2UoZnMucmVhZEZpbGVTeW5jKHN0LnRlbXBsYXRlUGF0aCwgJ3V0ZjgnKSk7XG4gICAgfSBjYXRjaCB7XG4gICAgICBjb250aW51ZTsgLy8g6Kqt44KB44Gq44GE44OG44Oz44OX44Os44O844OI44Gv5LuW44Gu44OX44Op44Kw44Kk44Oz44GM5aCx5ZGK44GZ44KLXG4gICAgfVxuICAgIGNvbnN0IGV4cG9ydHMgPSBuZXcgTWFwPHN0cmluZywgc3RyaW5nPigpO1xuICAgIGZvciAoY29uc3QgW2lkLCBvXSBvZiBPYmplY3QuZW50cmllczxhbnk+KHRlbXBsYXRlLk91dHB1dHMgPz8ge30pKSB7XG4gICAgICBjb25zdCBuYW1lID0gbz8uRXhwb3J0Py5OYW1lO1xuICAgICAgaWYgKHR5cGVvZiBuYW1lID09PSAnc3RyaW5nJykgZXhwb3J0cy5zZXQobmFtZSwgaWQpO1xuICAgIH1cbiAgICBjb25zdCBpbXBvcnRzOiB7IG5hbWU6IHN0cmluZzsgbG9naWNhbElkOiBzdHJpbmcgfVtdID0gW107XG4gICAgZm9yIChjb25zdCBbaWQsIHJdIG9mIE9iamVjdC5lbnRyaWVzPGFueT4odGVtcGxhdGUuUmVzb3VyY2VzID8/IHt9KSkgZmluZEltcG9ydHMociwgaWQsIGltcG9ydHMpO1xuICAgIGZvciAoY29uc3QgW2lkLCBvXSBvZiBPYmplY3QuZW50cmllczxhbnk+KHRlbXBsYXRlLk91dHB1dHMgPz8ge30pKSBmaW5kSW1wb3J0cyhvPy5WYWx1ZSwgaWQsIGltcG9ydHMpO1xuICAgIHN0YWNrcy5wdXNoKHtcbiAgICAgIHN0YWNrTmFtZTogc3RhY2tOYW1lT2Yoc3QudGVtcGxhdGVQYXRoKSxcbiAgICAgIHN0YWNrQ29uc3RydWN0UGF0aDogc3Quc3RhY2tDb25zdHJ1Y3RQYXRoLFxuICAgICAgdGVtcGxhdGVQYXRoOiBzdC50ZW1wbGF0ZVBhdGgsXG4gICAgICBlbnY6IGVudktleShzdCksXG4gICAgICBleHBvcnRzLFxuICAgICAgaW1wb3J0cyxcbiAgICB9KTtcbiAgfVxuICByZXR1cm4gc3RhY2tzO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gY2hlY2tFeHBvcnRzKFxuICBjb250ZXh0OiBQaWNrPElQb2xpY3lWYWxpZGF0aW9uQ29udGV4dCwgJ3N0YWNrVGVtcGxhdGVzJz4sXG4gIG9wdHM6IHsgc2V2ZXJpdHk6IHN0cmluZzsgZXhjbHVkZT86IHN0cmluZ1tdIH0sXG4pOiBQb2xpY3lWaW9sYXRpb25bXSB7XG4gIGNvbnN0IHZpb2xhdGlvbnM6IFBvbGljeVZpb2xhdGlvbltdID0gW107XG4gIGNvbnN0IHN0YWNrcyA9IHJlYWRTdGFja3MoY29udGV4dCk7XG4gIGNvbnN0IGJ5RW52ID0gbmV3IE1hcDxzdHJpbmcsIFN0YWNrRXhwb3J0c1tdPigpO1xuICBmb3IgKGNvbnN0IHMgb2Ygc3RhY2tzKSBieUVudi5zZXQocy5lbnYsIFsuLi4oYnlFbnYuZ2V0KHMuZW52KSA/PyBbXSksIHNdKTtcblxuICBmb3IgKGNvbnN0IGdyb3VwIG9mIGJ5RW52LnZhbHVlcygpKSB7XG4gICAgLy8gMS4g5ZCM44GY55Kw5aKD44Gn5ZCM44GYIEV4cG9ydC5OYW1lIOOCkuaMgeOBpOOCueOCv+ODg+OCr+OBrue1hFxuICAgIGNvbnN0IG93bmVyID0gbmV3IE1hcDxzdHJpbmcsIFN0YWNrRXhwb3J0cz4oKTtcbiAgICBmb3IgKGNvbnN0IHMgb2YgZ3JvdXApIHtcbiAgICAgIGZvciAoY29uc3QgW25hbWUsIG91dHB1dElkXSBvZiBzLmV4cG9ydHMpIHtcbiAgICAgICAgY29uc3QgZmlyc3QgPSBvd25lci5nZXQobmFtZSk7XG4gICAgICAgIGlmICghZmlyc3QpIHtcbiAgICAgICAgICBvd25lci5zZXQobmFtZSwgcyk7XG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGZpcnN0LnN0YWNrTmFtZSA9PT0gcy5zdGFja05hbWUpIGNvbnRpbnVlOyAvLyDlkIzjgZjjgrnjgr/jg4Pjgq/lkI0gPSDliKXnkrDlooPjga7lkIzlkI3jgrnjgr/jg4Pjgq/vvIhlbnZLZXkg44GM57KX44GE44Go44GN77yJXG4gICAgICAgIHZpb2xhdGlvbnMucHVzaCh7XG4gICAgICAgICAgcnVsZU5hbWU6IEVYUE9SVF9DT05GTElDVF9SVUxFLFxuICAgICAgICAgIGRlc2NyaXB0aW9uOiBgU3RhY2tzICR7Zmlyc3Quc3RhY2tOYW1lfSBhbmQgJHtzLnN0YWNrTmFtZX0gZGVwbG95IHRvIHRoZSBzYW1lIGFjY291bnQgYW5kIFJlZ2lvbiBhbmQgYm90aCBleHBvcnQgXCIke25hbWV9XCI7IGBcbiAgICAgICAgICAgICsgYGV4cG9ydCBuYW1lcyBtdXN0IGJlIHVuaXF1ZSB0aGVyZSwgc28gdGhlIHNlY29uZCBkZXBsb3kgZmFpbHMgd2l0aCBcIkV4cG9ydCB3aXRoIG5hbWUgJHtuYW1lfSBpcyBhbHJlYWR5IGV4cG9ydGVkIGJ5IHN0YWNrICR7Zmlyc3Quc3RhY2tOYW1lfVwiLmAsXG4gICAgICAgICAgc2V2ZXJpdHk6IG9wdHMuc2V2ZXJpdHksXG4gICAgICAgICAgZml4OiAnR2l2ZSBvbmUgb2YgdGhlIG91dHB1dHMgYSBkaWZmZXJlbnQgZXhwb3J0TmFtZSwgb3IgZHJvcCB0aGUgZXhwbGljaXQgbmFtZSBhbmQgbGV0IENESyBnZW5lcmF0ZSBvbmUuJyxcbiAgICAgICAgICB2aW9sYXRpbmdSZXNvdXJjZXM6IFt7XG4gICAgICAgICAgICByZXNvdXJjZUxvZ2ljYWxJZDogb3V0cHV0SWQsXG4gICAgICAgICAgICB0ZW1wbGF0ZVBhdGg6IHMudGVtcGxhdGVQYXRoLFxuICAgICAgICAgICAgbG9jYXRpb25zOiBbYE91dHB1dHMvJHtvdXRwdXRJZH0vRXhwb3J0L05hbWVgXSxcbiAgICAgICAgICB9XSxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuICAgIC8vIDIuIOOCouODl+ODquWGheOBruOCueOCv+ODg+OCr+WQjeOBp+Wni+OBvuOCiyBpbXBvcnQg5ZCN44KS44CB44Gd44Gu44K544K/44OD44Kv44GMIGV4cG9ydCDjgZfjgabjgYTjgarjgYRcbiAgICBjb25zdCBieU5hbWUgPSBuZXcgTWFwKGdyb3VwLm1hcCgocykgPT4gW3Muc3RhY2tOYW1lLCBzXSkpO1xuICAgIGZvciAoY29uc3QgcyBvZiBncm91cCkge1xuICAgICAgZm9yIChjb25zdCBpbXAgb2Ygcy5pbXBvcnRzKSB7XG4gICAgICAgIGNvbnN0IHByb2R1Y2VyID0gYnlOYW1lLmdldChpbXAubmFtZS5zcGxpdCgnOicpWzBdKTtcbiAgICAgICAgaWYgKCFpbXAubmFtZS5pbmNsdWRlcygnOicpIHx8ICFwcm9kdWNlciB8fCBwcm9kdWNlci5leHBvcnRzLmhhcyhpbXAubmFtZSkpIGNvbnRpbnVlO1xuICAgICAgICB2aW9sYXRpb25zLnB1c2goe1xuICAgICAgICAgIHJ1bGVOYW1lOiBJTVBPUlRfTUlTU0lOR19SVUxFLFxuICAgICAgICAgIGRlc2NyaXB0aW9uOiBgJHtzLnN0YWNrTmFtZX0gaW1wb3J0cyBcIiR7aW1wLm5hbWV9XCIsIGJ1dCBzdGFjayAke3Byb2R1Y2VyLnN0YWNrTmFtZX0gaW4gdGhpcyBhcHAsIHdoaWNoIGRlcGxveXMgdG8gdGhlIHNhbWUgYWNjb3VudCBgXG4gICAgICAgICAgICArIGBhbmQgUmVnaW9uLCBoYXMgbm8gb3V0cHV0IGV4cG9ydGVkIHVuZGVyIHRoYXQgbmFtZTsgdGhlIGRlcGxveSBmYWlscyB3aXRoIFwiTm8gZXhwb3J0IG5hbWVkICR7aW1wLm5hbWV9IGZvdW5kXCIuYCxcbiAgICAgICAgICBzZXZlcml0eTogb3B0cy5zZXZlcml0eSxcbiAgICAgICAgICBmaXg6IGBFeHBvcnQgdGhlIHZhbHVlIGZyb20gJHtwcm9kdWNlci5zdGFja05hbWV9IHVuZGVyIHRoaXMgbmFtZSAoQ2ZuT3V0cHV0IGV4cG9ydE5hbWUpLCBvciByZWZlcmVuY2UgdGhlIGNvbnN0cnVjdCBkaXJlY3RseSBzbyBDREsgY3JlYXRlcyB0aGUgZXhwb3J0LmAsXG4gICAgICAgICAgdmlvbGF0aW5nUmVzb3VyY2VzOiBbe1xuICAgICAgICAgICAgcmVzb3VyY2VMb2dpY2FsSWQ6IGltcC5sb2dpY2FsSWQsXG4gICAgICAgICAgICB0ZW1wbGF0ZVBhdGg6IHMudGVtcGxhdGVQYXRoLFxuICAgICAgICAgICAgbG9jYXRpb25zOiBbYFJlc291cmNlcy8ke2ltcC5sb2dpY2FsSWR9YF0sXG4gICAgICAgICAgfV0sXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICByZXR1cm4gdmlvbGF0aW9ucy5maWx0ZXIoKHYpID0+ICFvcHRzLmV4Y2x1ZGU/LmluY2x1ZGVzKHYucnVsZU5hbWUpKTtcbn1cblxuLyoqXG4gKiDjgrnjgr/jg4Pjgq/plpPjga4gRXhwb3J0IOOCkuaknOafu+OBmeOCi+ODl+ODqeOCsOOCpOODs+OAguOBqeOBoeOCieOBruODq+ODvOODq+OCguOBvuOBoCB3YXJuaW5nIOOBquOBruOBp+OAgWVuZm9yY2Ug44Gn44KCXG4gKiBvYnNlcnZlIOOBp+OCguWQjOOBmOODl+ODqeOCsOOCpOODs+OBp+WgseWRiuOBmeOCi++8iGBjZGstcHJlZmxpZ2h0LWV4cG9ydHM6OjxydWxlLWlkPmAg44GnIGFja25vd2xlZGdl77yJ44CCXG4gKi9cbmV4cG9ydCBjbGFzcyBQcmVmbGlnaHRFeHBvcnRQbHVnaW4gaW1wbGVtZW50cyBJUG9saWN5VmFsaWRhdGlvblBsdWdpbiB7XG4gIHB1YmxpYyByZWFkb25seSBuYW1lID0gJ2Nkay1wcmVmbGlnaHQtZXhwb3J0cyc7XG5cbiAgY29uc3RydWN0b3IocHJpdmF0ZSByZWFkb25seSBleGNsdWRlOiBzdHJpbmdbXSA9IFtdKSB7fVxuXG4gIHB1YmxpYyB2YWxpZGF0ZShjb250ZXh0OiBJUG9saWN5VmFsaWRhdGlvbkNvbnRleHQpOiBQb2xpY3lWYWxpZGF0aW9uUGx1Z2luUmVwb3J0IHtcbiAgICByZXR1cm4geyBzdWNjZXNzOiB0cnVlLCB2aW9sYXRpb25zOiBjaGVja0V4cG9ydHMoY29udGV4dCwgeyBzZXZlcml0eTogJ3dhcm5pbmcnLCBleGNsdWRlOiB0aGlzLmV4Y2x1ZGUgfSkgfTtcbiAgfVxufVxuIl19
@@ -84,6 +84,8 @@ interface Unit {
84
84
  }
85
85
  /** context のスタックと、そのネストしたスタック。context にはネストしたスタックが入らない。 */
86
86
  export declare function collectUnits(context: Pick<IPolicyValidationContext, 'stackTemplates'>): Unit[];
87
+ /** manifest.json からデプロイ時のスタック名を引く。見つからなければファイル名から。 */
88
+ export declare function stackNameOf(templatePath: string): string;
87
89
  export declare function checkQuotas(context: Pick<IPolicyValidationContext, 'stackTemplates'>, opts: QuotaCheckOptions): PolicyViolation[];
88
90
  export declare function flushQuotaCache(): void;
89
91
  /** App.synth() の後で flushQuotaCache() を呼ぶようにする。 */
@@ -36,6 +36,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
36
36
  exports.QUOTA_RULE_IDS = exports.LAMBDA_CONCURRENCY_RULE = exports.QUOTA_SKIPPED_RULE = void 0;
37
37
  exports.demand = demand;
38
38
  exports.collectUnits = collectUnits;
39
+ exports.stackNameOf = stackNameOf;
39
40
  exports.checkQuotas = checkQuotas;
40
41
  exports.flushQuotaCache = flushQuotaCache;
41
42
  exports.installQuotaCacheFlush = installQuotaCacheFlush;
@@ -345,4 +346,4 @@ function fetchFromAws(req) {
345
346
  });
346
347
  return JSON.parse(out);
347
348
  }
348
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicXVvdGEuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvcHJpdmF0ZS9xdW90YS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFnRkEsd0JBc0JDO0FBY0Qsb0NBcUJDO0FBbUNELGtDQUVDO0FBc0pELDBDQVVDO0FBS0Qsd0RBY0M7QUFqV0QsaURBQTZDO0FBQzdDLHVDQUF5QjtBQUN6QiwyQ0FBNkI7QUFDN0IsNkNBQXVGO0FBOEN2RiwwQ0FBMEM7QUFDMUMsTUFBTSxZQUFZLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsSUFBSSxDQUFDO0FBRXpDLHdDQUF3QztBQUN4QyxNQUFNLDBCQUEwQixHQUFHLEdBQUcsQ0FBQztBQUV2QyxNQUFNLE9BQU8sR0FBRztJQUNkLEdBQUcsRUFBRSxFQUFFLElBQUksRUFBRSxlQUFlLEVBQUUsSUFBSSxFQUFFLDBCQUEwQixFQUFFLElBQUksRUFBRSxpQkFBaUIsRUFBRSxJQUFJLEVBQUUsZ0JBQWdCLEVBQUU7SUFDakgsR0FBRyxFQUFFLEVBQUUsSUFBSSxFQUFFLDJCQUEyQixFQUFFLElBQUksRUFBRSx1Q0FBdUMsRUFBRSxJQUFJLEVBQUUsOEJBQThCLEVBQUUsSUFBSSxFQUFFLGdCQUFnQixFQUFFO0lBQ3ZKLEdBQUcsRUFBRSxFQUFFLElBQUksRUFBRSxlQUFlLEVBQUUsSUFBSSxFQUFFLGlDQUFpQyxFQUFFLElBQUksRUFBRSxxQkFBcUIsRUFBRSxJQUFJLEVBQUUsZ0JBQWdCLEVBQUU7Q0FDcEgsQ0FBQztBQUdFLFFBQUEsa0JBQWtCLEdBQUcsd0JBQXdCLENBQUM7QUFDOUMsUUFBQSx1QkFBdUIsR0FBRyx3Q0FBd0MsQ0FBQztBQUVoRiw0REFBNEQ7QUFDL0MsUUFBQSxjQUFjLEdBQWEsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FB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UUFBUSxDQUFDLEdBQUcsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxXQUFXLENBQUM7UUFBRSxHQUFHLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUMzRSxPQUFPLEdBQUcsQ0FBQztBQUNiLENBQUM7QUFFRCxTQUFTLFlBQVksQ0FBQyxHQUFpQjtJQUNyQyxNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBRSxpQkFBaUIsQ0FBQyxDQUFDO0lBQ3ZELElBQUksQ0FBQyxFQUFFLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQztRQUFFLE1BQU0sSUFBSSxLQUFLLENBQUMsNkJBQTZCLE1BQU0sRUFBRSxDQUFDLENBQUM7SUFDbkYsTUFBTSxHQUFHLEdBQUcsSUFBQSw0QkFBWSxFQUFDLE9BQU8sQ0FBQyxRQUFRLEVBQUUsQ0FBQyxNQUFNLENBQUMsRUFBRTtRQUNuRCxLQUFLLEVBQUUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUM7UUFDMUIsUUFBUSxFQUFFLE1BQU07UUFDaEIsT0FBTyxFQUFFLE1BQU07UUFDZixxREFBcUQ7UUFDckQsU0FBUyxFQUFFLEdBQUcsR0FBRyxJQUFJLEdBQUcsSUFBSTtRQUM1QixLQUFLLEVBQUUsQ0FBQyxNQUFNLEVBQUUsTUFBTSxFQUFFLE1BQU0sQ0FBQztLQUNoQyxDQUFDLENBQUM7SUFDSCxPQUFPLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDekIsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGV4ZWNGaWxlU3luYyB9IGZyb20gJ2NoaWxkX3Byb2Nlc3MnO1xuaW1wb3J0ICogYXMgZnMgZnJvbSAnZnMnO1xuaW1wb3J0ICogYXMgcGF0aCBmcm9tICdwYXRoJztcbmltcG9ydCB7IEFwcCwgdHlwZSBJUG9saWN5VmFsaWRhdGlvbkNvbnRleHQsIHR5cGUgUG9saWN5VmlvbGF0aW9uIH0gZnJvbSAnYXdzLWNkay1saWInO1xuaW1wb3J0IHR5cGUgeyBJQ29uc3RydWN0IH0gZnJvbSAnY29uc3RydWN0cyc7XG5cbi8qKlxuICogU2VydmljZSBRdW90YXMg5qSc5p+777yIYGNoZWNrUXVvdGFzOiB0cnVlYCDjga7jgajjgY3jgaDjgZHli5XjgY/vvInjgIJcbiAqXG4gKiBSZWdvIOOBruODq+ODvOODq+OBr+ODhuODs+ODl+ODrOODvOODiCAxIOaemuOBl+OBi+imi+OCieOCjOOBmuOAgeOCouOCq+OCpuODs+ODiOOBrueKtuaFi+OCguefpeOCieOBquOBhOOAguOBk+OBk+OBp+OBr1xuICog44Ki44OX44Oq5YaF44Gu5YWo44K544K/44OD44Kv77yI44ON44K544OI44GX44Gf44K544K/44OD44Kv44KS5ZCr44KA77yJ44GM5a6b5YWI44Gu44Ki44Kr44Km44Oz44OIIMOXIOODquODvOOCuOODp+ODs+OBq+aWsOOBl+OBj+S9nOOCi1xuICog44Oq44K944O844K544KS5ZCI6KiI44GX44CB44Gd44Gu44Ki44Kr44Km44Oz44OI44Gu6YGp55So5riI44G/44Kv44Kp44O844K/44Go54++5Zyo44Gu5L2/55So6YeP44Gr56qB44GN5ZCI44KP44Gb44KL44CCXG4gKiBBV1Mg44G444Gu5ZWP44GE5ZCI44KP44Gb44Gv5a2Q44OX44Ot44K744K577yIcXVvdGEtd29ya2VyLnRz77yJ44Gr5Lu744Gb44KL44CCdmFsaWRhdGUoKSDjgYzlkIzmnJ/jgaDjgYvjgonjgIJcbiAqL1xuXG50eXBlIFJlc291cmNlID0geyBUeXBlPzogc3RyaW5nOyBDb25kaXRpb24/OiBzdHJpbmc7IFByb3BlcnRpZXM/OiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjsgTWV0YWRhdGE/OiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiB9O1xudHlwZSBUZW1wbGF0ZSA9IHsgUmVzb3VyY2VzPzogUmVjb3JkPHN0cmluZywgUmVzb3VyY2U+IH07XG5cbmV4cG9ydCBpbnRlcmZhY2UgUXVvdGFSZXF1ZXN0IHtcbiAgLyoqIOacquaMh+WumuOBquOCieWtkOODl+ODreOCu+OCueOBjCBTREsg44Gu5pei5a6a44Oq44O844K444On44Oz44Gn6KOc44GGICovXG4gIHJlYWRvbmx5IHJlZ2lvbj86IHN0cmluZztcbiAgcmVhZG9ubHkgc3RhY2tOYW1lczogc3RyaW5nW107XG4gIC8qKiDjgq3jg6Pjg4Pjgrfjg6Xjga7jgq/jgqnjg7zjgr/lgKTjgYzjgb7jgaDmlrDjgZfjgYTjgajjgY3jga/lj5bjgornm7TjgZXjgarjgYQgKi9cbiAgcmVhZG9ubHkgc2tpcFF1b3Rhcz86IGJvb2xlYW47XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUXVvdGFGYWN0cyB7XG4gIHJlYWRvbmx5IHJlZ2lvbjogc3RyaW5nO1xuICByZWFkb25seSBjYWxsZXJBY2NvdW50OiBzdHJpbmc7XG4gIHJlYWRvbmx5IHF1b3Rhcz86IHsgdnBjOiBudW1iZXI7IGlndzogbnVtYmVyOyBlaXA6IG51bWJlciB9O1xuICByZWFkb25seSB1c2FnZTogeyB2cGM6IG51bWJlcjsgaWd3OiBudW1iZXI7IGVpcDogbnVtYmVyOyB1bnJlc2VydmVkQ29uY3VycmVuY3k6IG51bWJlciB9O1xuICAvKiogYOOCueOCv+ODg+OCr+WQjWAgLyBg44K544K/44OD44Kv5ZCNL+irlueQhklEYO+8iOODjeOCueODiO+8ieKGkiDjg4fjg5fjg63jgqTmuIjjgb/jg4bjg7Pjg5fjg6zjg7zjg4jjgILnhKHjgZHjgozjgbAgbnVsbCAqL1xuICByZWFkb25seSB0ZW1wbGF0ZXM6IFJlY29yZDxzdHJpbmcsIFRlbXBsYXRlIHwgbnVsbCB8ICd1bnBhcnNlYWJsZSc+O1xufVxuXG5leHBvcnQgdHlwZSBRdW90YUZldGNoZXIgPSAocmVxOiBRdW90YVJlcXVlc3QpID0+IFF1b3RhRmFjdHM7XG5cbmV4cG9ydCBpbnRlcmZhY2UgUXVvdGFDaGVja09wdGlvbnMge1xuICAvKiogJ2Vycm9yJyDjgarjgokgc3ludGgg44KS5q2i44KB44KL77yIZW5mb3JjZSDjg6Ljg7zjg4nvvInjgIEnd2FybmluZycg44Gq44KJ5aCx5ZGK44Gg44GRICovXG4gIHJlYWRvbmx5IHNldmVyaXR5OiAnZXJyb3InIHwgJ3dhcm5pbmcnO1xuICAvKiog5L2/55So6YeP44Go44OH44OX44Ot44Kk5riI44G/44OG44Oz44OX44Os44O844OI44Gu44Kt44Oj44OD44K344Ol5a+/5ZG9ICovXG4gIHJlYWRvbmx5IHR0bE1zOiBudW1iZXI7XG4gIC8qKiDloLHlkYrjgZfjgarjgYQgaWTvvIhQcmVmbGlnaHQuYXBwbHkg44GuIGV4Y2x1ZGXvvIkgKi9cbiAgcmVhZG9ubHkgZXhjbHVkZT86IHN0cmluZ1tdO1xuICAvKiog44OG44K544OI55So44CC5pei5a6a44Gv5a2Q44OX44Ot44K744K544GnIEFXUyDjgavllY/jgYTlkIjjgo/jgZvjgosgKi9cbiAgcmVhZG9ubHkgZmV0Y2g/OiBRdW90YUZldGNoZXI7XG4gIHJlYWRvbmx5IG5vdz86ICgpID0+IG51bWJlcjtcbn1cblxuLyoqIOOCr+OCqeODvOOCv+OBruWApOOBneOBruOCguOBruOBr+a7heWkmuOBq+WkieOCj+OCieOBquOBhOOBruOBp+OAgeS9v+eUqOmHj+OBqOOBr+WIpeOBq+mVt+OCgeOBq+aMgeOBpOOAgiAqL1xuY29uc3QgUVVPVEFfVFRMX01TID0gMjQgKiA2MCAqIDYwICogMTAwMDtcblxuLyoqIExhbWJkYSDjga/kuojntITjgZXjgozjgabjgYTjgarjgYTlkIzmmYLlrp/ooYzjgYzjgZPjgozjgpLkuIvlm57jgovlpInmm7TjgpLmi5LjgoDjgIIgKi9cbmNvbnN0IE1JTl9VTlJFU0VSVkVEX0NPTkNVUlJFTkNZID0gMTAwO1xuXG5jb25zdCBDT1VOVEVEID0ge1xuICB2cGM6IHsgdHlwZTogJ0FXUzo6RUMyOjpWUEMnLCBydWxlOiAncGYtcXVvdGEtdnBjcy1wZXItcmVnaW9uJywgbmFtZTogJ1ZQQ3MgcGVyIFJlZ2lvbicsIGNvZGU6ICd2cGMvTC1GNjc4RjFDRScgfSxcbiAgaWd3OiB7IHR5cGU6ICdBV1M6OkVDMjo6SW50ZXJuZXRHYXRld2F5JywgcnVsZTogJ3BmLXF1b3RhLWludGVybmV0LWdhdGV3YXlzLXBlci1yZWdpb24nLCBuYW1lOiAnSW50ZXJuZXQgZ2F0ZXdheXMgcGVyIFJlZ2lvbicsIGNvZGU6ICd2cGMvTC1BNDcwN0E3MicgfSxcbiAgZWlwOiB7IHR5cGU6ICdBV1M6OkVDMjo6RUlQJywgcnVsZTogJ3BmLXF1b3RhLWVsYXN0aWMtaXBzLXBlci1yZWdpb24nLCBuYW1lOiAnRUMyLVZQQyBFbGFzdGljIElQcycsIGNvZGU6ICdlYzIvTC0wMjYzRDBBMycgfSxcbn0gYXMgY29uc3Q7XG50eXBlIENvdW50ZWQgPSBrZXlvZiB0eXBlb2YgQ09VTlRFRDtcblxuZXhwb3J0IGNvbnN0IFFVT1RBX1NLSVBQRURfUlVMRSA9ICdwZi1xdW90YS1jaGVjay1za2lwcGVkJztcbmV4cG9ydCBjb25zdCBMQU1CREFfQ09OQ1VSUkVOQ1lfUlVMRSA9ICdwZi1xdW90YS1sYW1iZGEtdW5yZXNlcnZlZC1jb25jdXJyZW5jeSc7XG5cbi8qKiBgZXhjbHVkZWAg44Gr5pu444GR44KLIGlk44CCUmVnbyDjga7jg6vjg7zjg6vjgafjga/jgarjgYTjga7jgacgQlVORExFRF9SVUxFUyDjgavjga/nhKHjgYTjgIIgKi9cbmV4cG9ydCBjb25zdCBRVU9UQV9SVUxFX0lEUzogc3RyaW5nW10gPSBbLi4uT2JqZWN0LnZhbHVlcyhDT1VOVEVEKS5tYXAoKHEpID0+IHEucnVsZSksIExBTUJEQV9DT05DVVJSRU5DWV9SVUxFLCBRVU9UQV9TS0lQUEVEX1JVTEVdO1xuXG5leHBvcnQgaW50ZXJmYWNlIERlbWFuZCB7XG4gIHZwYzogc3RyaW5nW107XG4gIGlndzogc3RyaW5nW107XG4gIGVpcDogc3RyaW5nW107XG4gIC8qKiDkuojntITlkIzmmYLlrp/ooYzjgpLlopfjgoTjgZnplqLmlbDjgajjgIHjgZ3jga7lopfliIYgKi9cbiAgY29uY3VycmVuY3k6IHsgaWQ6IHN0cmluZzsgZGVsdGE6IG51bWJlciB9W107XG59XG5cbi8qKlxuICogMSDmnprjga7jg4bjg7Pjg5fjg6zjg7zjg4jjgYzmlrDjgZfjgY/kvb/jgYbliIbjgILjg4fjg5fjg63jgqTmuIjjgb/jgavlkIzjgZjoq5bnkIYgSUTjg7vlkIzjgZjlnovjgYzjgYLjgozjgbDml6LlrZjjgajjgZfjgabmlbDjgYjjgarjgYTjgIJcbiAqIOWJiumZpOOBleOCjOOCi+WIhuOBr+W3ruOBl+W8leOBi+OBquOBhDogQ2xvdWRGb3JtYXRpb24g44GM5Y+k44GE44Oq44K944O844K544KS5raI44GZ44Gu44Gv5L2c5oiQ44Gu5b6M77yIY2xlYW51cO+8ieOBoOOBi+OCieOAglxuICovXG5leHBvcnQgZnVuY3Rpb24gZGVtYW5kKGxvY2FsOiBUZW1wbGF0ZSwgZGVwbG95ZWQ6IFRlbXBsYXRlIHwgbnVsbCB8IHVuZGVmaW5lZCk6IERlbWFuZCB7XG4gIGNvbnN0IGQ6IERlbWFuZCA9IHsgdnBjOiBbXSwgaWd3OiBbXSwgZWlwOiBbXSwgY29uY3VycmVuY3k6IFtdIH07XG4gIGNvbnN0IG9sZCA9IGRlcGxveWVkPy5SZXNvdXJjZXMgPz8ge307XG4gIGZvciAoY29uc3QgW2lkLCByXSBvZiBPYmplY3QuZW50cmllcyhsb2NhbC5SZXNvdXJjZXMgPz8ge30pKSB7XG4gICAgLy8gcG9ueXRhaWw6IENvbmRpdGlvbiDku5jjgY3jga/kvZzjgonjgozjgovjgYvliIbjgYvjgonjgarjgYTjga7jgafmlbDjgYjjgarjgYTvvIjlgb3pmbDmgKflgbTvvInjgILmnaHku7bjgpLoqZXkvqHjgZnjgovjgarjgokgRm46OkVxdWFscyDnrYnjga7op6PmsbrjgYzopoHjgotcbiAgICBpZiAoIXIgfHwgci5Db25kaXRpb24pIGNvbnRpbnVlO1xuICAgIGNvbnN0IGJlZm9yZSA9IG9sZFtpZF0/LlR5cGUgPT09IHIuVHlwZSA/IG9sZFtpZF0gOiB1bmRlZmluZWQ7XG4gICAgLy8gcG9ueXRhaWw6IOe9ruOBjeaPm+OBiO+8iHJlcGxhY2VtZW5077yJ44Gv5paw44GX44GE5pa544KS5YWI44Gr5L2c44KL44Gu44Gn5LiA5pmC55qE44GrIDIg44Gk44Gr44Gq44KL44GM44CB5pWw44GI44Gq44GE77yI5YG96Zmw5oCn5YG077yJXG4gICAgZm9yIChjb25zdCBrIG9mIE9iamVjdC5rZXlzKENPVU5URUQpIGFzIENvdW50ZWRbXSkge1xuICAgICAgaWYgKHIuVHlwZSA9PT0gQ09VTlRFRFtrXS50eXBlICYmICFiZWZvcmUpIGRba10ucHVzaChpZCk7XG4gICAgfVxuICAgIGlmIChyLlR5cGUgPT09ICdBV1M6OkxhbWJkYTo6RnVuY3Rpb24nKSB7XG4gICAgICBjb25zdCBub3cgPSByLlByb3BlcnRpZXM/LlJlc2VydmVkQ29uY3VycmVudEV4ZWN1dGlvbnM7XG4gICAgICBjb25zdCB3YXMgPSBiZWZvcmU/LlByb3BlcnRpZXM/LlJlc2VydmVkQ29uY3VycmVudEV4ZWN1dGlvbnM7XG4gICAgICAvLyBwb255dGFpbDog44OH44OX44Ot44Kk5riI44G/44Gu5YCk44GM57WE44G/6L6844G/6Zai5pWw44Gq44KJIDAg44Go44G/44Gq44GZ44Gu44Gn44CB5beu5YiG44KS5aSa44KB44Gr5pWw44GI44KL77yI5YG96Zm95oCn5YG077yJXG4gICAgICBpZiAodHlwZW9mIG5vdyA9PT0gJ251bWJlcicpIHtcbiAgICAgICAgY29uc3QgZGVsdGEgPSBub3cgLSAodHlwZW9mIHdhcyA9PT0gJ251bWJlcicgPyB3YXMgOiAwKTtcbiAgICAgICAgaWYgKGRlbHRhID4gMCkgZC5jb25jdXJyZW5jeS5wdXNoKHsgaWQsIGRlbHRhIH0pO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICByZXR1cm4gZDtcbn1cblxuaW50ZXJmYWNlIFVuaXQge1xuICAvKiogZmFjdHMudGVtcGxhdGVzIOOBruOCreODvCAqL1xuICByZWFkb25seSBrZXk6IHN0cmluZztcbiAgcmVhZG9ubHkgc3RhY2tOYW1lOiBzdHJpbmc7XG4gIHJlYWRvbmx5IHN0YWNrQ29uc3RydWN0UGF0aDogc3RyaW5nO1xuICByZWFkb25seSB0ZW1wbGF0ZVBhdGg6IHN0cmluZztcbiAgcmVhZG9ubHkgbG9jYWw6IFRlbXBsYXRlO1xuICByZWFkb25seSBhY2NvdW50Pzogc3RyaW5nO1xuICByZWFkb25seSByZWdpb24/OiBzdHJpbmc7XG59XG5cbi8qKiBjb250ZXh0IOOBruOCueOCv+ODg+OCr+OBqOOAgeOBneOBruODjeOCueODiOOBl+OBn+OCueOCv+ODg+OCr+OAgmNvbnRleHQg44Gr44Gv44ON44K544OI44GX44Gf44K544K/44OD44Kv44GM5YWl44KJ44Gq44GE44CCICovXG5leHBvcnQgZnVuY3Rpb24gY29sbGVjdFVuaXRzKGNvbnRleHQ6IFBpY2s8SVBvbGljeVZhbGlkYXRpb25Db250ZXh0LCAnc3RhY2tUZW1wbGF0ZXMnPik6IFVuaXRbXSB7XG4gIGNvbnN0IHVuaXRzOiBVbml0W10gPSBbXTtcbiAgZm9yIChjb25zdCBzdCBvZiBjb250ZXh0LnN0YWNrVGVtcGxhdGVzKSB7XG4gICAgY29uc3Qgc3RhY2tOYW1lID0gc3RhY2tOYW1lT2Yoc3QudGVtcGxhdGVQYXRoKTtcbiAgICBjb25zdCBiYXNlID0ge1xuICAgICAgc3RhY2tOYW1lLFxuICAgICAgc3RhY2tDb25zdHJ1Y3RQYXRoOiBzdC5zdGFja0NvbnN0cnVjdFBhdGgsXG4gICAgICBhY2NvdW50OiBzdC5hY2NvdW50SWQgPz8gcHJvY2Vzcy5lbnYuQ0RLX0RFRkFVTFRfQUNDT1VOVCxcbiAgICAgIHJlZ2lvbjogc3QucmVnaW9uID8/IHByb2Nlc3MuZW52LkNES19ERUZBVUxUX1JFR0lPTixcbiAgICB9O1xuICAgIGNvbnN0IHZpc2l0ID0gKGtleTogc3RyaW5nLCB0ZW1wbGF0ZVBhdGg6IHN0cmluZykgPT4ge1xuICAgICAgY29uc3QgbG9jYWw6IFRlbXBsYXRlID0gSlNPTi5wYXJzZShmcy5yZWFkRmlsZVN5bmModGVtcGxhdGVQYXRoLCAndXRmOCcpKTtcbiAgICAgIHVuaXRzLnB1c2goeyAuLi5iYXNlLCBrZXksIHRlbXBsYXRlUGF0aCwgbG9jYWwgfSk7XG4gICAgICBmb3IgKGNvbnN0IFtpZCwgcl0gb2YgT2JqZWN0LmVudHJpZXMobG9jYWwuUmVzb3VyY2VzID8/IHt9KSkge1xuICAgICAgICBjb25zdCBjaGlsZCA9IHI/LlR5cGUgPT09ICdBV1M6OkNsb3VkRm9ybWF0aW9uOjpTdGFjaycgPyBuZXN0ZWRUZW1wbGF0ZUZpbGUocGF0aC5kaXJuYW1lKHRlbXBsYXRlUGF0aCksIHIpIDogdW5kZWZpbmVkO1xuICAgICAgICBpZiAoY2hpbGQpIHZpc2l0KGAke2tleX0vJHtpZH1gLCBwYXRoLmpvaW4ocGF0aC5kaXJuYW1lKHRlbXBsYXRlUGF0aCksIGNoaWxkKSk7XG4gICAgICB9XG4gICAgfTtcbiAgICB2aXNpdChzdGFja05hbWUsIHN0LnRlbXBsYXRlUGF0aCk7XG4gIH1cbiAgcmV0dXJuIHVuaXRzO1xufVxuXG4vKipcbiAqIOODjeOCueODiOOBl+OBn+OCueOCv+ODg+OCr+OBruWtkOODhuODs+ODl+ODrOODvOODiOOBriBjZGsub3V0IOWGheOBruODleOCoeOCpOODq+WQjeOAgmBhd3M6YXNzZXQ6cGF0aGAg44Oh44K/44OH44O844K/44GvXG4gKiBDTEkg57WM55Sx44GuIHN5bnRoIOOBq+OBl+OBi+S7mOOBi+OBquOBhOOBruOBp+OAgeeEoeOBkeOCjOOBsCBUZW1wbGF0ZVVSTCDjga7kuK3jga7jgqLjgrvjg4Pjg4jjg4/jg4Pjgrfjg6XjgpJcbiAqIGAqLmFzc2V0cy5qc29uYCDjgaflvJXjgY/jgIJcbiAqL1xuZnVuY3Rpb24gbmVzdGVkVGVtcGxhdGVGaWxlKGRpcjogc3RyaW5nLCByOiBSZXNvdXJjZSk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gIGNvbnN0IGFzc2V0ID0gci5NZXRhZGF0YT8uWydhd3M6YXNzZXQ6cGF0aCddO1xuICBpZiAodHlwZW9mIGFzc2V0ID09PSAnc3RyaW5nJykgcmV0dXJuIGFzc2V0O1xuICBjb25zdCBoYXNoID0gLyhbMC05YS1mXXs2NH0pXFwuanNvbi8uZXhlYyhKU09OLnN0cmluZ2lmeShyLlByb3BlcnRpZXM/LlRlbXBsYXRlVVJMID8/ICcnKSk/LlsxXTtcbiAgaWYgKCFoYXNoKSByZXR1cm4gdW5kZWZpbmVkO1xuICBmb3IgKGNvbnN0IGYgb2YgZnMucmVhZGRpclN5bmMoZGlyKS5maWx0ZXIoKG4pID0+IG4uZW5kc1dpdGgoJy5hc3NldHMuanNvbicpKSkge1xuICAgIGNvbnN0IHNvdXJjZSA9IEpTT04ucGFyc2UoZnMucmVhZEZpbGVTeW5jKHBhdGguam9pbihkaXIsIGYpLCAndXRmOCcpKS5maWxlcz8uW2hhc2hdPy5zb3VyY2U/LnBhdGg7XG4gICAgaWYgKHR5cGVvZiBzb3VyY2UgPT09ICdzdHJpbmcnKSByZXR1cm4gc291cmNlO1xuICB9XG4gIHJldHVybiB1bmRlZmluZWQ7XG59XG5cbi8qKiBtYW5pZmVzdC5qc29uIOOBi+OCieODh+ODl+ODreOCpOaZguOBruOCueOCv+ODg+OCr+WQjeOCkuW8leOBj+OAguimi+OBpOOBi+OCieOBquOBkeOCjOOBsOODleOCoeOCpOODq+WQjeOBi+OCieOAgiAqL1xuZnVuY3Rpb24gc3RhY2tOYW1lT2YodGVtcGxhdGVQYXRoOiBzdHJpbmcpOiBzdHJpbmcge1xuICBjb25zdCBmaWxlID0gcGF0aC5iYXNlbmFtZSh0ZW1wbGF0ZVBhdGgpO1xuICB0cnkge1xuICAgIGNvbnN0IG1hbmlmZXN0ID0gSlNPTi5wYXJzZShmcy5yZWFkRmlsZVN5bmMocGF0aC5qb2luKHBhdGguZGlybmFtZSh0ZW1wbGF0ZVBhdGgpLCAnbWFuaWZlc3QuanNvbicpLCAndXRmOCcpKTtcbiAgICBmb3IgKGNvbnN0IFtpZCwgYV0gb2YgT2JqZWN0LmVudHJpZXM8YW55PihtYW5pZmVzdC5hcnRpZmFjdHMgPz8ge30pKSB7XG4gICAgICBpZiAoYT8udHlwZSA9PT0gJ2F3czpjbG91ZGZvcm1hdGlvbjpzdGFjaycgJiYgYS5wcm9wZXJ0aWVzPy50ZW1wbGF0ZUZpbGUgPT09IGZpbGUpIHtcbiAgICAgICAgcmV0dXJuIGEucHJvcGVydGllcy5zdGFja05hbWUgPz8gaWQ7XG4gICAgICB9XG4gICAgfVxuICB9IGNhdGNoIHtcbiAgICAvLyBmYWxsIHRocm91Z2hcbiAgfVxuICByZXR1cm4gZmlsZS5yZXBsYWNlKC9cXC50ZW1wbGF0ZVxcLmpzb24kLywgJycpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gY2hlY2tRdW90YXMoY29udGV4dDogUGljazxJUG9saWN5VmFsaWRhdGlvbkNvbnRleHQsICdzdGFja1RlbXBsYXRlcyc+LCBvcHRzOiBRdW90YUNoZWNrT3B0aW9ucyk6IFBvbGljeVZpb2xhdGlvbltdIHtcbiAgcmV0dXJuIGZpbmRWaW9sYXRpb25zKGNvbnRleHQsIG9wdHMpLmZpbHRlcigodikgPT4gIW9wdHMuZXhjbHVkZT8uaW5jbHVkZXModi5ydWxlTmFtZSkpO1xufVxuXG5mdW5jdGlvbiBmaW5kVmlvbGF0aW9ucyhjb250ZXh0OiBQaWNrPElQb2xpY3lWYWxpZGF0aW9uQ29udGV4dCwgJ3N0YWNrVGVtcGxhdGVzJz4sIG9wdHM6IFF1b3RhQ2hlY2tPcHRpb25zKTogUG9saWN5VmlvbGF0aW9uW10ge1xuICBjb25zdCB2aW9sYXRpb25zOiBQb2xpY3lWaW9sYXRpb25bXSA9IFtdO1xuICBsZXQgdW5pdHM6IFVuaXRbXTtcbiAgdHJ5IHtcbiAgICB1bml0cyA9IGNvbGxlY3RVbml0cyhjb250ZXh0KTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIHJldHVybiBjb250ZXh0LnN0YWNrVGVtcGxhdGVzLmxlbmd0aCA+IDBcbiAgICAgID8gW3NraXBwZWQoY29udGV4dC5zdGFja1RlbXBsYXRlc1swXSwgYGNvdWxkIG5vdCByZWFkIHRoZSB0ZW1wbGF0ZXMgKCR7ZXJyb3JUZXh0KGUpfSlgKV1cbiAgICAgIDogW107XG4gIH1cbiAgY29uc3QgYnlSZWdpb24gPSBuZXcgTWFwPHN0cmluZyB8IHVuZGVmaW5lZCwgVW5pdFtdPigpO1xuICBmb3IgKGNvbnN0IHUgb2YgdW5pdHMpIGJ5UmVnaW9uLnNldCh1LnJlZ2lvbiwgWy4uLihieVJlZ2lvbi5nZXQodS5yZWdpb24pID8/IFtdKSwgdV0pO1xuXG4gIGZvciAoY29uc3QgW3JlZ2lvbiwgZ3JvdXBdIG9mIGJ5UmVnaW9uKSB7XG4gICAgbGV0IGZhY3RzOiBRdW90YUZhY3RzO1xuICAgIHRyeSB7XG4gICAgICBmYWN0cyA9IGNhY2hlZEZldGNoKGdyb3VwWzBdLnRlbXBsYXRlUGF0aCwgeyByZWdpb24sIHN0YWNrTmFtZXM6IFsuLi5uZXcgU2V0KGdyb3VwLm1hcCgodSkgPT4gdS5zdGFja05hbWUpKV0gfSwgb3B0cyk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgdmlvbGF0aW9ucy5wdXNoKHNraXBwZWQoZ3JvdXBbMF0sIGVycm9yVGV4dChlKSkpO1xuICAgICAgY29udGludWU7XG4gICAgfVxuICAgIGNvbnN0IHRvdGFsOiBEZW1hbmQgPSB7IHZwYzogW10sIGlndzogW10sIGVpcDogW10sIGNvbmN1cnJlbmN5OiBbXSB9O1xuICAgIGNvbnN0IHdoZXJlID0gbmV3IE1hcDxzdHJpbmcsIFVuaXQ+KCk7XG4gICAgY29uc3Qgc2tpcHBlZFN0YWNrcyA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuICAgIGNvbnN0IHNraXAgPSAodTogVW5pdCwgd2h5OiBzdHJpbmcpID0+IHtcbiAgICAgIC8vIOODjeOCueODiOOBl+OBn+OCueOCv+ODg+OCr+OBr+imquOBqOWQjOOBmCBjb25zdHJ1Y3QgcGF0aCDjgavlh7rjgovjga7jgafjgIHjgrnjgr/jg4Pjgq/jgZTjgajjgasgMSDku7bjgavjgZnjgotcbiAgICAgIGlmICghc2tpcHBlZFN0YWNrcy5oYXModS5zdGFja05hbWUpKSB2aW9sYXRpb25zLnB1c2goc2tpcHBlZCh1LCB3aHkpKTtcbiAgICAgIHNraXBwZWRTdGFja3MuYWRkKHUuc3RhY2tOYW1lKTtcbiAgICB9O1xuICAgIC8vIOWFiOOBq+OCueOCv+ODg+OCr+WNmOS9jeOBp+mZjeOCiuOCi+OBi+OCkuaxuuOCgeOCi+OAguODjeOCueODiOOBrueJh+aWueOBoOOBkeaVsOOBiOOCi+OBqOOAgeWNiuerr+OBquWQiOioiOOBp+WIpOWumuOBl+OBpuOBl+OBvuOBhlxuICAgIGZvciAoY29uc3QgdSBvZiBncm91cCkge1xuICAgICAgaWYgKHUuYWNjb3VudCAmJiAvXlxcZHsxMn0kLy50ZXN0KHUuYWNjb3VudCkgJiYgdS5hY2NvdW50ICE9PSBmYWN0cy5jYWxsZXJBY2NvdW50KSB7XG4gICAgICAgIHNraXAodSwgYHRoZSBjcmVkZW50aWFscyBiZWxvbmcgdG8gYWNjb3VudCAke2ZhY3RzLmNhbGxlckFjY291bnR9LCBidXQgdGhpcyBzdGFjayBkZXBsb3lzIHRvICR7dS5hY2NvdW50fS4gYFxuICAgICAgICAgICsgJ1RoZSBDREsgQ0xJIGRvZXMgbm90IHBhc3MgLS1wcm9maWxlIHRvIHRoZSBhcHA7IHNldCBBV1NfUFJPRklMRSBpbnN0ZWFkJyk7XG4gICAgICB9IGVsc2UgaWYgKGZhY3RzLnRlbXBsYXRlc1t1LmtleV0gPT09ICd1bnBhcnNlYWJsZScpIHtcbiAgICAgICAgc2tpcCh1LCBgdGhlIGRlcGxveWVkIHRlbXBsYXRlIG9mICR7dS5rZXl9IGlzIG5vdCBKU09OYCk7XG4gICAgICB9XG4gICAgfVxuICAgIGZvciAoY29uc3QgdSBvZiBncm91cCkge1xuICAgICAgaWYgKHNraXBwZWRTdGFja3MuaGFzKHUuc3RhY2tOYW1lKSkgY29udGludWU7XG4gICAgICBjb25zdCBkID0gZGVtYW5kKHUubG9jYWwsIGZhY3RzLnRlbXBsYXRlc1t1LmtleV0gYXMgVGVtcGxhdGUgfCBudWxsIHwgdW5kZWZpbmVkKTtcbiAgICAgIGZvciAoY29uc3QgayBvZiBPYmplY3Qua2V5cyhDT1VOVEVEKSBhcyBDb3VudGVkW10pIHRvdGFsW2tdLnB1c2goLi4uZFtrXS5tYXAoKGlkKSA9PiB0YWcod2hlcmUsIHUsIGlkKSkpO1xuICAgICAgdG90YWwuY29uY3VycmVuY3kucHVzaCguLi5kLmNvbmN1cnJlbmN5Lm1hcCgoYykgPT4gKHsgaWQ6IHRhZyh3aGVyZSwgdSwgYy5pZCksIGRlbHRhOiBjLmRlbHRhIH0pKSk7XG4gICAgfVxuICAgIGNvbnN0IGVudiA9IGAke2ZhY3RzLmNhbGxlckFjY291bnR9LyR7ZmFjdHMucmVnaW9ufWA7XG4gICAgZm9yIChjb25zdCBrIG9mIE9iamVjdC5rZXlzKENPVU5URUQpIGFzIENvdW50ZWRbXSkge1xuICAgICAgY29uc3QgcXVvdGEgPSBmYWN0cy5xdW90YXM/LltrXTtcbiAgICAgIGNvbnN0IHVzZWQgPSBmYWN0cy51c2FnZVtrXTtcbiAgICAgIGNvbnN0IGFkZGluZyA9IHRvdGFsW2tdLmxlbmd0aDtcbiAgICAgIGlmIChxdW90YSA9PT0gdW5kZWZpbmVkIHx8IGFkZGluZyA9PT0gMCB8fCB1c2VkICsgYWRkaW5nIDw9IHF1b3RhKSBjb250aW51ZTtcbiAgICAgIGNvbnN0IHEgPSBDT1VOVEVEW2tdO1xuICAgICAgdmlvbGF0aW9ucy5wdXNoKHtcbiAgICAgICAgcnVsZU5hbWU6IHEucnVsZSxcbiAgICAgICAgZGVzY3JpcHRpb246IGBUaGlzIGFwcCBjcmVhdGVzICR7YWRkaW5nfSBuZXcgJHtxLnR5cGV9IGluICR7ZW52fSwgd2hpY2ggYWxyZWFkeSB1c2VzICR7dXNlZH0gb2YgaXRzIGBcbiAgICAgICAgICArIGBcIiR7cS5uYW1lfVwiIHF1b3RhIG9mICR7cXVvdGF9ICgke3EuY29kZX0pOyB0aGUgZGVwbG95IHdvdWxkIGZhaWwgb25jZSB0aGUgcXVvdGEgaXMgcmVhY2hlZC5gLFxuICAgICAgICBzZXZlcml0eTogb3B0cy5zZXZlcml0eSxcbiAgICAgICAgZml4OiBgUmVxdWVzdCBhIHF1b3RhIGluY3JlYXNlIGluIHRoZSBTZXJ2aWNlIFF1b3RhcyBjb25zb2xlICgke3EuY29kZX0pLCBvciBjcmVhdGUgZmV3ZXIgJHtxLnR5cGV9IHJlc291cmNlcyBpbiB0aGlzIGVudmlyb25tZW50LmAsXG4gICAgICAgIHZpb2xhdGluZ1Jlc291cmNlczogdG90YWxba10ubWFwKCh0YWdnZWQpID0+IHJlc291cmNlT2Yod2hlcmUsIHRhZ2dlZCkpLFxuICAgICAgfSk7XG4gICAgfVxuICAgIGNvbnN0IGRlbHRhID0gdG90YWwuY29uY3VycmVuY3kucmVkdWNlKChzLCBjKSA9PiBzICsgYy5kZWx0YSwgMCk7XG4gICAgY29uc3QgbGVmdCA9IGZhY3RzLnVzYWdlLnVucmVzZXJ2ZWRDb25jdXJyZW5jeSAtIGRlbHRhO1xuICAgIGlmIChkZWx0YSA+IDAgJiYgbGVmdCA8IE1JTl9VTlJFU0VSVkVEX0NPTkNVUlJFTkNZKSB7XG4gICAgICB2aW9sYXRpb25zLnB1c2goe1xuICAgICAgICBydWxlTmFtZTogTEFNQkRBX0NPTkNVUlJFTkNZX1JVTEUsXG4gICAgICAgIGRlc2NyaXB0aW9uOiBgVGhpcyBhcHAgcmVzZXJ2ZXMgJHtkZWx0YX0gbW9yZSBMYW1iZGEgY29uY3VycmVudCBleGVjdXRpb25zIGluICR7ZW52fSwgd2hpY2ggaGFzIGBcbiAgICAgICAgICArIGAke2ZhY3RzLnVzYWdlLnVucmVzZXJ2ZWRDb25jdXJyZW5jeX0gdW5yZXNlcnZlZDsgTGFtYmRhIHJlamVjdHMgYSBjaGFuZ2UgdGhhdCBsZWF2ZXMgZmV3ZXIgdGhhbiBgXG4gICAgICAgICAgKyBgJHtNSU5fVU5SRVNFUlZFRF9DT05DVVJSRU5DWX0uYCxcbiAgICAgICAgc2V2ZXJpdHk6IG9wdHMuc2V2ZXJpdHksXG4gICAgICAgIGZpeDogJ0xvd2VyIFJlc2VydmVkQ29uY3VycmVudEV4ZWN1dGlvbnMsIG9yIHJlcXVlc3QgYSBoaWdoZXIgXCJDb25jdXJyZW50IGV4ZWN1dGlvbnNcIiBxdW90YSAobGFtYmRhL0wtQjk5QTkzODQpLicsXG4gICAgICAgIHZpb2xhdGluZ1Jlc291cmNlczogdG90YWwuY29uY3VycmVuY3kubWFwKChjKSA9PiByZXNvdXJjZU9mKHdoZXJlLCBjLmlkKSksXG4gICAgICB9KTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHZpb2xhdGlvbnM7XG59XG5cbi8qKiDjgrnjgr/jg4Pjgq/jgpLjgb7jgZ/jgYTjgaflkIzjgZjoq5bnkIYgSUQg44GM5Ye644Gm44GP44KL44Gu44Gn44CB44Kt44O85LuY44GN44Gu6K2Y5Yil5a2Q44Gr44GX44Gm44GL44KJ5Ye65omA44KS5byV44GP44CCICovXG5mdW5jdGlvbiB0YWcod2hlcmU6IE1hcDxzdHJpbmcsIFVuaXQ+LCB1OiBVbml0LCBpZDogc3RyaW5nKTogc3RyaW5nIHtcbiAgY29uc3QgdCA9IGAke3Uua2V5fVxcdTAwMDAke2lkfWA7XG4gIHdoZXJlLnNldCh0LCB1KTtcbiAgcmV0dXJuIHQ7XG59XG5cbmZ1bmN0aW9uIHJlc291cmNlT2Yod2hlcmU6IE1hcDxzdHJpbmcsIFVuaXQ+LCB0YWdnZWQ6IHN0cmluZykge1xuICBjb25zdCB1ID0gd2hlcmUuZ2V0KHRhZ2dlZCkhO1xuICByZXR1cm4geyByZXNvdXJjZUxvZ2ljYWxJZDogdGFnZ2VkLnNwbGl0KCdcXHUwMDAwJylbMV0sIHRlbXBsYXRlUGF0aDogdS50ZW1wbGF0ZVBhdGgsIGxvY2F0aW9uczogWycodGVtcGxhdGUpJ10gfTtcbn1cblxuZnVuY3Rpb24gc2tpcHBlZChzdDogeyBzdGFja0NvbnN0cnVjdFBhdGg6IHN0cmluZzsgdGVtcGxhdGVQYXRoOiBzdHJpbmcgfSwgd2h5OiBzdHJpbmcpOiBQb2xpY3lWaW9sYXRpb24ge1xuICByZXR1cm4ge1xuICAgIHJ1bGVOYW1lOiBRVU9UQV9TS0lQUEVEX1JVTEUsXG4gICAgZGVzY3JpcHRpb246IGBjZGstcHJlZmxpZ2h0IGRpZCBub3QgY2hlY2sgc2VydmljZSBxdW90YXMgZm9yIHRoaXMgc3RhY2s6ICR7d2h5fS5gLFxuICAgIHNldmVyaXR5OiAnd2FybmluZycsXG4gICAgZml4OiAnTWFrZSBBV1MgY3JlZGVudGlhbHMgZm9yIHRoZSB0YXJnZXQgYWNjb3VudCBhdmFpbGFibGUgdG8gdGhlIGFwcCBwcm9jZXNzIChBV1NfUFJPRklMRSBvciBBV1NfKiBlbnZpcm9ubWVudCB2YXJpYWJsZXMpLCAnXG4gICAgICArICd3aXRoIHNlcnZpY2VxdW90YXM6R2V0U2VydmljZVF1b3RhLCBzZXJ2aWNlcXVvdGFzOkdldEFXU0RlZmF1bHRTZXJ2aWNlUXVvdGEsIGVjMjpEZXNjcmliZXtWcGNzLEludGVybmV0R2F0ZXdheXMsQWRkcmVzc2VzfSwgbGFtYmRhOkdldEFjY291bnRTZXR0aW5ncywgJ1xuICAgICAgKyAnY2xvdWRmb3JtYXRpb246R2V0VGVtcGxhdGUgYW5kIGNsb3VkZm9ybWF0aW9uOkRlc2NyaWJlU3RhY2tSZXNvdXJjZS4nLFxuICAgIHZpb2xhdGluZ1Jlc291cmNlczogW3sgY29uc3RydWN0UGF0aDogc3Quc3RhY2tDb25zdHJ1Y3RQYXRoLCB0ZW1wbGF0ZVBhdGg6IHN0LnRlbXBsYXRlUGF0aCwgbG9jYXRpb25zOiBbJyh0ZW1wbGF0ZSknXSB9XSxcbiAgfTtcbn1cblxuZnVuY3Rpb24gZXJyb3JUZXh0KGU6IHVua25vd24pOiBzdHJpbmcge1xuICBjb25zdCBzdGRlcnIgPSAoZSBhcyB7IHN0ZGVycj86IHVua25vd24gfSk/LnN0ZGVycjtcbiAgaWYgKHR5cGVvZiBzdGRlcnIgPT09ICdzdHJpbmcnICYmIHN0ZGVyci50cmltKCkpIHJldHVybiBzdGRlcnIudHJpbSgpO1xuICBjb25zdCBtZXNzYWdlID0gKGUgYXMgeyBtZXNzYWdlPzogdW5rbm93biB9KT8ubWVzc2FnZTtcbiAgcmV0dXJuIHR5cGVvZiBtZXNzYWdlID09PSAnc3RyaW5nJyA/IG1lc3NhZ2UgOiBTdHJpbmcoZSk7XG59XG5cbmludGVyZmFjZSBDYWNoZUVudHJ5IHtcbiAgcmVhZG9ubHkgYXQ6IG51bWJlcjtcbiAgcmVhZG9ubHkgcXVvdGFzQXQ6IG51bWJlcjtcbiAgcmVhZG9ubHkgZmFjdHM6IFF1b3RhRmFjdHM7XG59XG5cbi8qKlxuICogY2RrLm91dC8uY2RrLXByZWZsaWdodC9xdW90YS1jYWNoZS5qc29uIOOBq+e9ruOBj+OAgnN5bnRoIOOBryBkaWZmL2RlcGxveS93YXRjaCDjga7jgZ/jgbPjgavotbDjgovjga7jgafjgIFcbiAqIOavjuWbniBBV1Mg44Gr5ZWP44GE5ZCI44KP44Gb44Gq44GE44KI44GG44Gr44GZ44KL44CC44Kt44O844GrIEFXU19QUk9GSUxFIOOCkuWFpeOCjOOAgeizh+agvOaDheWgseOCkuWIh+OCiuabv+OBiOOBn+OCieW8leOBjeebtOOBmeOAglxuICovXG5mdW5jdGlvbiBjYWNoZWRGZXRjaCh0ZW1wbGF0ZVBhdGg6IHN0cmluZywgcmVxOiBRdW90YVJlcXVlc3QsIG9wdHM6IFF1b3RhQ2hlY2tPcHRpb25zKTogUXVvdGFGYWN0cyB7XG4gIGNvbnN0IG5vdyA9IChvcHRzLm5vdyA/PyBEYXRlLm5vdykoKTtcbiAgY29uc3QgZmlsZSA9IHBhdGguam9pbihhc3NlbWJseVJvb3QodGVtcGxhdGVQYXRoKSwgJy5jZGstcHJlZmxpZ2h0JywgJ3F1b3RhLWNhY2hlLmpzb24nKTtcbiAgY29uc3Qga2V5ID0gYCR7cHJvY2Vzcy5lbnYuQVdTX1BST0ZJTEUgPz8gJyd9fCR7cmVxLnJlZ2lvbiA/PyAnJ31gO1xuICBsZXQgY2FjaGU6IFJlY29yZDxzdHJpbmcsIENhY2hlRW50cnk+ID0ge307XG4gIHRyeSB7XG4gICAgY2FjaGUgPSBKU09OLnBhcnNlKGZzLnJlYWRGaWxlU3luYyhmaWxlLCAndXRmOCcpKTtcbiAgfSBjYXRjaCB7XG4gICAgLy8g54Sh44GE44O75aOK44KM44Gm44GE44KLXG4gIH1cbiAgY29uc3QgaGl0ID0gY2FjaGVba2V5XTtcbiAgY29uc3QgY292ZXJzID0gaGl0ICYmIHJlcS5zdGFja05hbWVzLmV2ZXJ5KChuKSA9PiBuIGluIGhpdC5mYWN0cy50ZW1wbGF0ZXMpO1xuICBpZiAoaGl0ICYmIGNvdmVycyAmJiBub3cgLSBoaXQuYXQgPCBvcHRzLnR0bE1zICYmIGhpdC5mYWN0cy5xdW90YXMpIHJldHVybiBoaXQuZmFjdHM7XG5cbiAgY29uc3QgcXVvdGFzRnJlc2ggPSBoaXQ/LmZhY3RzLnF1b3RhcyAhPT0gdW5kZWZpbmVkICYmIG5vdyAtIGhpdC5xdW90YXNBdCA8IFFVT1RBX1RUTF9NUztcbiAgY29uc3QgZ290ID0gKG9wdHMuZmV0Y2ggPz8gZmV0Y2hGcm9tQXdzKSh7IC4uLnJlcSwgc2tpcFF1b3RhczogcXVvdGFzRnJlc2ggfSk7XG4gIGNvbnN0IGZhY3RzOiBRdW90YUZhY3RzID0geyAuLi5nb3QsIHF1b3RhczogZ290LnF1b3RhcyA/PyBoaXQ/LmZhY3RzLnF1b3RhcyB9O1xuICBjYWNoZVtrZXldID0geyBhdDogbm93LCBxdW90YXNBdDogZ290LnF1b3RhcyA/IG5vdyA6IGhpdCEucXVvdGFzQXQsIGZhY3RzIH07XG4gIHBlbmRpbmdDYWNoZS5zZXQoZmlsZSwgY2FjaGUpO1xuICByZXR1cm4gZmFjdHM7XG59XG5cbi8qKlxuICogdmFsaWRhdGUoKSDjga7mnIDkuK3jga8gY2RrLm91dCDjgavmm7jjgZHjgarjgYTjgIJDREsg44GvIENsb3VkRm9ybWF0aW9uVmFsaWRhdGVQbHVnaW4g5Lul5aSW44Gu44OX44Op44Kw44Kk44Oz44GuXG4gKiDliY3lvozjgacgY2RrLm91dCDphY3kuIvjga7lhajjg5XjgqHjgqTjg6vjga7jg4/jg4Pjgrfjg6XjgpLlj5bjgorjgIHml6LlrZjjg5XjgqHjgqTjg6vjgYzlpInjgo/jgaPjgabjgYTjgozjgbBcbiAqIElsbGVnYWxQbHVnaW5PcGVyYXRpb24g44GnIHN5bnRoIOOCkuiQveOBqOOBme+8iGF3cy1jZGstbGliIDIuMjcxLjAgc3ludGhlc2lzLXZhbGlkYXRpb27vvInjgIJcbiAqIFRUTCDliIfjgozjga7kuIrmm7jjgY3jgYzjgaHjgofjgYbjganjgZ3jgozjgavlvZPjgZ/jgovjga7jgafjgIHmm7jjgY/jga7jga8gc3ludGgg44GM57WC44KP44Gj44Gm44GL44KJ44Gr44GZ44KL44CCXG4gKi9cbmNvbnN0IHBlbmRpbmdDYWNoZSA9IG5ldyBNYXA8c3RyaW5nLCBSZWNvcmQ8c3RyaW5nLCBDYWNoZUVudHJ5Pj4oKTtcblxuZXhwb3J0IGZ1bmN0aW9uIGZsdXNoUXVvdGFDYWNoZSgpOiB2b2lkIHtcbiAgZm9yIChjb25zdCBbZmlsZSwgY2FjaGVdIG9mIHBlbmRpbmdDYWNoZSkge1xuICAgIHRyeSB7XG4gICAgICBmcy5ta2RpclN5bmMocGF0aC5kaXJuYW1lKGZpbGUpLCB7IHJlY3Vyc2l2ZTogdHJ1ZSB9KTtcbiAgICAgIGZzLndyaXRlRmlsZVN5bmMoZmlsZSwgSlNPTi5zdHJpbmdpZnkoY2FjaGUpKTtcbiAgICB9IGNhdGNoIHtcbiAgICAgIC8vIOOCreODo+ODg+OCt+ODpeOBr+eEoeOBj+OBpuOCguWLleOBj1xuICAgIH1cbiAgfVxuICBwZW5kaW5nQ2FjaGUuY2xlYXIoKTtcbn1cblxuY29uc3QgRkxVU0hfSU5TVEFMTEVEID0gU3ltYm9sLmZvcignY2RrLXByZWZsaWdodC5xdW90YUNhY2hlRmx1c2gnKTtcblxuLyoqIEFwcC5zeW50aCgpIOOBruW+jOOBpyBmbHVzaFF1b3RhQ2FjaGUoKSDjgpLlkbzjgbbjgojjgYbjgavjgZnjgovjgIIgKi9cbmV4cG9ydCBmdW5jdGlvbiBpbnN0YWxsUXVvdGFDYWNoZUZsdXNoKHNjb3BlOiBJQ29uc3RydWN0KTogdm9pZCB7XG4gIGNvbnN0IHJvb3QgPSBzY29wZS5ub2RlLnJvb3Q7XG4gIGlmICghQXBwLmlzQXBwKHJvb3QpKSByZXR1cm47XG4gIGNvbnN0IGFwcCA9IHJvb3QgYXMgQXBwICYgeyBbRkxVU0hfSU5TVEFMTEVEXT86IGJvb2xlYW4gfTtcbiAgaWYgKGFwcFtGTFVTSF9JTlNUQUxMRURdKSByZXR1cm47XG4gIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShhcHAsIEZMVVNIX0lOU1RBTExFRCwgeyB2YWx1ZTogdHJ1ZSwgZW51bWVyYWJsZTogZmFsc2UgfSk7XG4gIGNvbnN0IHN5bnRoID0gYXBwLnN5bnRoLmJpbmQoYXBwKTtcbiAgYXBwLnN5bnRoID0gKG9wdGlvbnM/OiBQYXJhbWV0ZXJzPEFwcFsnc3ludGgnXT5bMF0pID0+IHtcbiAgICB0cnkge1xuICAgICAgcmV0dXJuIHN5bnRoKG9wdGlvbnMpO1xuICAgIH0gZmluYWxseSB7XG4gICAgICBmbHVzaFF1b3RhQ2FjaGUoKTtcbiAgICB9XG4gIH07XG59XG5cbi8qKiBTdGFnZSDjga7jgrnjgr/jg4Pjgq/jga8gY2RrLm91dC9hc3NlbWJseS0q77yP44Gr5YWl44KL44Gu44Gn44CB44Ki44OX44Oq44GuIGNkay5vdXQg44G+44Gn5LiK44GM44KL44CCICovXG5mdW5jdGlvbiBhc3NlbWJseVJvb3QodGVtcGxhdGVQYXRoOiBzdHJpbmcpOiBzdHJpbmcge1xuICBsZXQgZGlyID0gcGF0aC5kaXJuYW1lKHRlbXBsYXRlUGF0aCk7XG4gIHdoaWxlIChwYXRoLmJhc2VuYW1lKGRpcikuc3RhcnRzV2l0aCgnYXNzZW1ibHktJykpIGRpciA9IHBhdGguZGlybmFtZShkaXIpO1xuICByZXR1cm4gZGlyO1xufVxuXG5mdW5jdGlvbiBmZXRjaEZyb21Bd3MocmVxOiBRdW90YVJlcXVlc3QpOiBRdW90YUZhY3RzIHtcbiAgY29uc3Qgd29ya2VyID0gcGF0aC5qb2luKF9fZGlybmFtZSwgJ3F1b3RhLXdvcmtlci5qcycpO1xuICBpZiAoIWZzLmV4aXN0c1N5bmMod29ya2VyKSkgdGhyb3cgbmV3IEVycm9yKGBxdW90YSB3b3JrZXIgbm90IGZvdW5kIGF0ICR7d29ya2VyfWApO1xuICBjb25zdCBvdXQgPSBleGVjRmlsZVN5bmMocHJvY2Vzcy5leGVjUGF0aCwgW3dvcmtlcl0sIHtcbiAgICBpbnB1dDogSlNPTi5zdHJpbmdpZnkocmVxKSxcbiAgICBlbmNvZGluZzogJ3V0ZjgnLFxuICAgIHRpbWVvdXQ6IDYwXzAwMCxcbiAgICAvLyDjg4fjg5fjg63jgqTmuIjjgb/jg4bjg7Pjg5fjg6zjg7zjg4jjga7lhajmlofjgpLov5TjgZnjga7jgafjgIHml6Llrprjga4gMSBNaUIg44Gn44Gv5aSn44GN44GE44Ki44OX44Oq44G744Gp6buZ44Gj44Gm5qSc5p+744GM5aSW44KM44KLXG4gICAgbWF4QnVmZmVyOiAyNTYgKiAxMDI0ICogMTAyNCxcbiAgICBzdGRpbzogWydwaXBlJywgJ3BpcGUnLCAncGlwZSddLFxuICB9KTtcbiAgcmV0dXJuIEpTT04ucGFyc2Uob3V0KTtcbn1cbiJdfQ==
349
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicXVvdGEuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvcHJpdmF0ZS9xdW90YS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFnRkEsd0JBc0JDO0FBY0Qsb0NBcUJDO0FBb0JELGtDQWFDO0FBRUQsa0NBRUM7QUFzSkQsMENBVUM7QUFLRCx3REFjQztBQWpXRCxpREFBNkM7QUFDN0MsdUNBQXlCO0FBQ3pCLDJDQUE2QjtBQUM3Qiw2Q0FBdUY7QUE4Q3ZGLDBDQUEwQztBQUMxQyxNQUFNLFlBQVksR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxJQUFJLENBQUM7QUFFekMsd0NBQXdDO0FBQ3hDLE1BQU0sMEJBQTBCLEdBQUcsR0FBRyxDQUFDO0FBRXZDLE1BQU0sT0FBTyxHQUFHO0lBQ2QsR0FBRyxFQUFFLEVBQUUsSUFBSSxFQUFFLGVBQWUsRUFBRSxJQUFJLEVBQUUsMEJBQTBCLEVBQUUsSUFBSSxFQUFFLGlCQUFpQixFQUFFLElBQUksRUFBRSxnQkFBZ0IsRUFBRTtJQUNqSCxHQUFHLEVBQUUsRUFBRSxJQUFJLEVBQUUsMkJBQTJCLEVBQUUsSUFBSSxFQUFFLHVDQUF1QyxFQUFFLElBQUksRUFBRSw4QkFBOEIsRUFBRSxJQUFJLEVBQUUsZ0JBQWdCLEVBQUU7SUFDdkosR0FBRyxFQUFFLEVBQUUsSUFBSSxFQUFFLGVBQWUsRUFBRSxJQUFJLEVBQUUsaUNBQWlDLEVBQUUsSUFBSSxFQUFFLHFCQUFxQixFQUFFLElBQUksRUFBRSxnQkFBZ0IsRUFBRTtDQUNwSCxDQUFDO0FBR0UsUUFBQSxrQkFBa0IsR0FBRyx3QkFBd0IsQ0FBQztBQUM5QyxRQUFBLHVCQUF1QixHQUFHLHdDQUF3QyxDQUFDO0FBRWhGLDREQUE0RDtBQUMvQyxRQUFBLGNBQWMsR0FBYSxDQUFDLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQyxHQUFHLENB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TyxJQUFJLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxXQUFXLENBQUM7UUFBRSxHQUFHLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUMzRSxPQUFPLEdBQUcsQ0FBQztBQUNiLENBQUM7QUFFRCxTQUFTLFlBQVksQ0FBQyxHQUFpQjtJQUNyQyxNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBRSxpQkFBaUIsQ0FBQyxDQUFDO0lBQ3ZELElBQUksQ0FBQyxFQUFFLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQztRQUFFLE1BQU0sSUFBSSxLQUFLLENBQUMsNkJBQTZCLE1BQU0sRUFBRSxDQUFDLENBQUM7SUFDbkYsTUFBTSxHQUFHLEdBQUcsSUFBQSw0QkFBWSxFQUFDLE9BQU8sQ0FBQyxRQUFRLEVBQUUsQ0FBQyxNQUFNLENBQUMsRUFBRTtRQUNuRCxLQUFLLEVBQUUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUM7UUFDMUIsUUFBUSxFQUFFLE1BQU07UUFDaEIsT0FBTyxFQUFFLE1BQU07UUFDZixxREFBcUQ7UUFDckQsU0FBUyxFQUFFLEdBQUcsR0FBRyxJQUFJLEdBQUcsSUFBSTtRQUM1QixLQUFLLEVBQUUsQ0FBQyxNQUFNLEVBQUUsTUFBTSxFQUFFLE1BQU0sQ0FBQztLQUNoQyxDQUFDLENBQUM7SUFDSCxPQUFPLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDekIsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGV4ZWNGaWxlU3luYyB9IGZyb20gJ2NoaWxkX3Byb2Nlc3MnO1xuaW1wb3J0ICogYXMgZnMgZnJvbSAnZnMnO1xuaW1wb3J0ICogYXMgcGF0aCBmcm9tICdwYXRoJztcbmltcG9ydCB7IEFwcCwgdHlwZSBJUG9saWN5VmFsaWRhdGlvbkNvbnRleHQsIHR5cGUgUG9saWN5VmlvbGF0aW9uIH0gZnJvbSAnYXdzLWNkay1saWInO1xuaW1wb3J0IHR5cGUgeyBJQ29uc3RydWN0IH0gZnJvbSAnY29uc3RydWN0cyc7XG5cbi8qKlxuICogU2VydmljZSBRdW90YXMg5qSc5p+777yIYGNoZWNrUXVvdGFzOiB0cnVlYCDjga7jgajjgY3jgaDjgZHli5XjgY/vvInjgIJcbiAqXG4gKiBSZWdvIOOBruODq+ODvOODq+OBr+ODhuODs+ODl+ODrOODvOODiCAxIOaemuOBl+OBi+imi+OCieOCjOOBmuOAgeOCouOCq+OCpuODs+ODiOOBrueKtuaFi+OCguefpeOCieOBquOBhOOAguOBk+OBk+OBp+OBr1xuICog44Ki44OX44Oq5YaF44Gu5YWo44K544K/44OD44Kv77yI44ON44K544OI44GX44Gf44K544K/44OD44Kv44KS5ZCr44KA77yJ44GM5a6b5YWI44Gu44Ki44Kr44Km44Oz44OIIMOXIOODquODvOOCuOODp+ODs+OBq+aWsOOBl+OBj+S9nOOCi1xuICog44Oq44K944O844K544KS5ZCI6KiI44GX44CB44Gd44Gu44Ki44Kr44Km44Oz44OI44Gu6YGp55So5riI44G/44Kv44Kp44O844K/44Go54++5Zyo44Gu5L2/55So6YeP44Gr56qB44GN5ZCI44KP44Gb44KL44CCXG4gKiBBV1Mg44G444Gu5ZWP44GE5ZCI44KP44Gb44Gv5a2Q44OX44Ot44K744K577yIcXVvdGEtd29ya2VyLnRz77yJ44Gr5Lu744Gb44KL44CCdmFsaWRhdGUoKSDjgYzlkIzmnJ/jgaDjgYvjgonjgIJcbiAqL1xuXG50eXBlIFJlc291cmNlID0geyBUeXBlPzogc3RyaW5nOyBDb25kaXRpb24/OiBzdHJpbmc7IFByb3BlcnRpZXM/OiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjsgTWV0YWRhdGE/OiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiB9O1xudHlwZSBUZW1wbGF0ZSA9IHsgUmVzb3VyY2VzPzogUmVjb3JkPHN0cmluZywgUmVzb3VyY2U+IH07XG5cbmV4cG9ydCBpbnRlcmZhY2UgUXVvdGFSZXF1ZXN0IHtcbiAgLyoqIOacquaMh+WumuOBquOCieWtkOODl+ODreOCu+OCueOBjCBTREsg44Gu5pei5a6a44Oq44O844K444On44Oz44Gn6KOc44GGICovXG4gIHJlYWRvbmx5IHJlZ2lvbj86IHN0cmluZztcbiAgcmVhZG9ubHkgc3RhY2tOYW1lczogc3RyaW5nW107XG4gIC8qKiDjgq3jg6Pjg4Pjgrfjg6Xjga7jgq/jgqnjg7zjgr/lgKTjgYzjgb7jgaDmlrDjgZfjgYTjgajjgY3jga/lj5bjgornm7TjgZXjgarjgYQgKi9cbiAgcmVhZG9ubHkgc2tpcFF1b3Rhcz86IGJvb2xlYW47XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUXVvdGFGYWN0cyB7XG4gIHJlYWRvbmx5IHJlZ2lvbjogc3RyaW5nO1xuICByZWFkb25seSBjYWxsZXJBY2NvdW50OiBzdHJpbmc7XG4gIHJlYWRvbmx5IHF1b3Rhcz86IHsgdnBjOiBudW1iZXI7IGlndzogbnVtYmVyOyBlaXA6IG51bWJlciB9O1xuICByZWFkb25seSB1c2FnZTogeyB2cGM6IG51bWJlcjsgaWd3OiBudW1iZXI7IGVpcDogbnVtYmVyOyB1bnJlc2VydmVkQ29uY3VycmVuY3k6IG51bWJlciB9O1xuICAvKiogYOOCueOCv+ODg+OCr+WQjWAgLyBg44K544K/44OD44Kv5ZCNL+irlueQhklEYO+8iOODjeOCueODiO+8ieKGkiDjg4fjg5fjg63jgqTmuIjjgb/jg4bjg7Pjg5fjg6zjg7zjg4jjgILnhKHjgZHjgozjgbAgbnVsbCAqL1xuICByZWFkb25seSB0ZW1wbGF0ZXM6IFJlY29yZDxzdHJpbmcsIFRlbXBsYXRlIHwgbnVsbCB8ICd1bnBhcnNlYWJsZSc+O1xufVxuXG5leHBvcnQgdHlwZSBRdW90YUZldGNoZXIgPSAocmVxOiBRdW90YVJlcXVlc3QpID0+IFF1b3RhRmFjdHM7XG5cbmV4cG9ydCBpbnRlcmZhY2UgUXVvdGFDaGVja09wdGlvbnMge1xuICAvKiogJ2Vycm9yJyDjgarjgokgc3ludGgg44KS5q2i44KB44KL77yIZW5mb3JjZSDjg6Ljg7zjg4nvvInjgIEnd2FybmluZycg44Gq44KJ5aCx5ZGK44Gg44GRICovXG4gIHJlYWRvbmx5IHNldmVyaXR5OiAnZXJyb3InIHwgJ3dhcm5pbmcnO1xuICAvKiog5L2/55So6YeP44Go44OH44OX44Ot44Kk5riI44G/44OG44Oz44OX44Os44O844OI44Gu44Kt44Oj44OD44K344Ol5a+/5ZG9ICovXG4gIHJlYWRvbmx5IHR0bE1zOiBudW1iZXI7XG4gIC8qKiDloLHlkYrjgZfjgarjgYQgaWTvvIhQcmVmbGlnaHQuYXBwbHkg44GuIGV4Y2x1ZGXvvIkgKi9cbiAgcmVhZG9ubHkgZXhjbHVkZT86IHN0cmluZ1tdO1xuICAvKiog44OG44K544OI55So44CC5pei5a6a44Gv5a2Q44OX44Ot44K744K544GnIEFXUyDjgavllY/jgYTlkIjjgo/jgZvjgosgKi9cbiAgcmVhZG9ubHkgZmV0Y2g/OiBRdW90YUZldGNoZXI7XG4gIHJlYWRvbmx5IG5vdz86ICgpID0+IG51bWJlcjtcbn1cblxuLyoqIOOCr+OCqeODvOOCv+OBruWApOOBneOBruOCguOBruOBr+a7heWkmuOBq+WkieOCj+OCieOBquOBhOOBruOBp+OAgeS9v+eUqOmHj+OBqOOBr+WIpeOBq+mVt+OCgeOBq+aMgeOBpOOAgiAqL1xuY29uc3QgUVVPVEFfVFRMX01TID0gMjQgKiA2MCAqIDYwICogMTAwMDtcblxuLyoqIExhbWJkYSDjga/kuojntITjgZXjgozjgabjgYTjgarjgYTlkIzmmYLlrp/ooYzjgYzjgZPjgozjgpLkuIvlm57jgovlpInmm7TjgpLmi5LjgoDjgIIgKi9cbmNvbnN0IE1JTl9VTlJFU0VSVkVEX0NPTkNVUlJFTkNZID0gMTAwO1xuXG5jb25zdCBDT1VOVEVEID0ge1xuICB2cGM6IHsgdHlwZTogJ0FXUzo6RUMyOjpWUEMnLCBydWxlOiAncGYtcXVvdGEtdnBjcy1wZXItcmVnaW9uJywgbmFtZTogJ1ZQQ3MgcGVyIFJlZ2lvbicsIGNvZGU6ICd2cGMvTC1GNjc4RjFDRScgfSxcbiAgaWd3OiB7IHR5cGU6ICdBV1M6OkVDMjo6SW50ZXJuZXRHYXRld2F5JywgcnVsZTogJ3BmLXF1b3RhLWludGVybmV0LWdhdGV3YXlzLXBlci1yZWdpb24nLCBuYW1lOiAnSW50ZXJuZXQgZ2F0ZXdheXMgcGVyIFJlZ2lvbicsIGNvZGU6ICd2cGMvTC1BNDcwN0E3MicgfSxcbiAgZWlwOiB7IHR5cGU6ICdBV1M6OkVDMjo6RUlQJywgcnVsZTogJ3BmLXF1b3RhLWVsYXN0aWMtaXBzLXBlci1yZWdpb24nLCBuYW1lOiAnRUMyLVZQQyBFbGFzdGljIElQcycsIGNvZGU6ICdlYzIvTC0wMjYzRDBBMycgfSxcbn0gYXMgY29uc3Q7XG50eXBlIENvdW50ZWQgPSBrZXlvZiB0eXBlb2YgQ09VTlRFRDtcblxuZXhwb3J0IGNvbnN0IFFVT1RBX1NLSVBQRURfUlVMRSA9ICdwZi1xdW90YS1jaGVjay1za2lwcGVkJztcbmV4cG9ydCBjb25zdCBMQU1CREFfQ09OQ1VSUkVOQ1lfUlVMRSA9ICdwZi1xdW90YS1sYW1iZGEtdW5yZXNlcnZlZC1jb25jdXJyZW5jeSc7XG5cbi8qKiBgZXhjbHVkZWAg44Gr5pu444GR44KLIGlk44CCUmVnbyDjga7jg6vjg7zjg6vjgafjga/jgarjgYTjga7jgacgQlVORExFRF9SVUxFUyDjgavjga/nhKHjgYTjgIIgKi9cbmV4cG9ydCBjb25zdCBRVU9UQV9SVUxFX0lEUzogc3RyaW5nW10gPSBbLi4uT2JqZWN0LnZhbHVlcyhDT1VOVEVEKS5tYXAoKHEpID0+IHEucnVsZSksIExBTUJEQV9DT05DVVJSRU5DWV9SVUxFLCBRVU9UQV9TS0lQUEVEX1JVTEVdO1xuXG5leHBvcnQgaW50ZXJmYWNlIERlbWFuZCB7XG4gIHZwYzogc3RyaW5nW107XG4gIGlndzogc3RyaW5nW107XG4gIGVpcDogc3RyaW5nW107XG4gIC8qKiDkuojntITlkIzmmYLlrp/ooYzjgpLlopfjgoTjgZnplqLmlbDjgajjgIHjgZ3jga7lopfliIYgKi9cbiAgY29uY3VycmVuY3k6IHsgaWQ6IHN0cmluZzsgZGVsdGE6IG51bWJlciB9W107XG59XG5cbi8qKlxuICogMSDmnprjga7jg4bjg7Pjg5fjg6zjg7zjg4jjgYzmlrDjgZfjgY/kvb/jgYbliIbjgILjg4fjg5fjg63jgqTmuIjjgb/jgavlkIzjgZjoq5bnkIYgSUTjg7vlkIzjgZjlnovjgYzjgYLjgozjgbDml6LlrZjjgajjgZfjgabmlbDjgYjjgarjgYTjgIJcbiAqIOWJiumZpOOBleOCjOOCi+WIhuOBr+W3ruOBl+W8leOBi+OBquOBhDogQ2xvdWRGb3JtYXRpb24g44GM5Y+k44GE44Oq44K944O844K544KS5raI44GZ44Gu44Gv5L2c5oiQ44Gu5b6M77yIY2xlYW51cO+8ieOBoOOBi+OCieOAglxuICovXG5leHBvcnQgZnVuY3Rpb24gZGVtYW5kKGxvY2FsOiBUZW1wbGF0ZSwgZGVwbG95ZWQ6IFRlbXBsYXRlIHwgbnVsbCB8IHVuZGVmaW5lZCk6IERlbWFuZCB7XG4gIGNvbnN0IGQ6IERlbWFuZCA9IHsgdnBjOiBbXSwgaWd3OiBbXSwgZWlwOiBbXSwgY29uY3VycmVuY3k6IFtdIH07XG4gIGNvbnN0IG9sZCA9IGRlcGxveWVkPy5SZXNvdXJjZXMgPz8ge307XG4gIGZvciAoY29uc3QgW2lkLCByXSBvZiBPYmplY3QuZW50cmllcyhsb2NhbC5SZXNvdXJjZXMgPz8ge30pKSB7XG4gICAgLy8gcG9ueXRhaWw6IENvbmRpdGlvbiDku5jjgY3jga/kvZzjgonjgozjgovjgYvliIbjgYvjgonjgarjgYTjga7jgafmlbDjgYjjgarjgYTvvIjlgb3pmbDmgKflgbTvvInjgILmnaHku7bjgpLoqZXkvqHjgZnjgovjgarjgokgRm46OkVxdWFscyDnrYnjga7op6PmsbrjgYzopoHjgotcbiAgICBpZiAoIXIgfHwgci5Db25kaXRpb24pIGNvbnRpbnVlO1xuICAgIGNvbnN0IGJlZm9yZSA9IG9sZFtpZF0/LlR5cGUgPT09IHIuVHlwZSA/IG9sZFtpZF0gOiB1bmRlZmluZWQ7XG4gICAgLy8gcG9ueXRhaWw6IOe9ruOBjeaPm+OBiO+8iHJlcGxhY2VtZW5077yJ44Gv5paw44GX44GE5pa544KS5YWI44Gr5L2c44KL44Gu44Gn5LiA5pmC55qE44GrIDIg44Gk44Gr44Gq44KL44GM44CB5pWw44GI44Gq44GE77yI5YG96Zmw5oCn5YG077yJXG4gICAgZm9yIChjb25zdCBrIG9mIE9iamVjdC5rZXlzKENPVU5URUQpIGFzIENvdW50ZWRbXSkge1xuICAgICAgaWYgKHIuVHlwZSA9PT0gQ09VTlRFRFtrXS50eXBlICYmICFiZWZvcmUpIGRba10ucHVzaChpZCk7XG4gICAgfVxuICAgIGlmIChyLlR5cGUgPT09ICdBV1M6OkxhbWJkYTo6RnVuY3Rpb24nKSB7XG4gICAgICBjb25zdCBub3cgPSByLlByb3BlcnRpZXM/LlJlc2VydmVkQ29uY3VycmVudEV4ZWN1dGlvbnM7XG4gICAgICBjb25zdCB3YXMgPSBiZWZvcmU/LlByb3BlcnRpZXM/LlJlc2VydmVkQ29uY3VycmVudEV4ZWN1dGlvbnM7XG4gICAgICAvLyBwb255dGFpbDog44OH44OX44Ot44Kk5riI44G/44Gu5YCk44GM57WE44G/6L6844G/6Zai5pWw44Gq44KJIDAg44Go44G/44Gq44GZ44Gu44Gn44CB5beu5YiG44KS5aSa44KB44Gr5pWw44GI44KL77yI5YG96Zm95oCn5YG077yJXG4gICAgICBpZiAodHlwZW9mIG5vdyA9PT0gJ251bWJlcicpIHtcbiAgICAgICAgY29uc3QgZGVsdGEgPSBub3cgLSAodHlwZW9mIHdhcyA9PT0gJ251bWJlcicgPyB3YXMgOiAwKTtcbiAgICAgICAgaWYgKGRlbHRhID4gMCkgZC5jb25jdXJyZW5jeS5wdXNoKHsgaWQsIGRlbHRhIH0pO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICByZXR1cm4gZDtcbn1cblxuaW50ZXJmYWNlIFVuaXQge1xuICAvKiogZmFjdHMudGVtcGxhdGVzIOOBruOCreODvCAqL1xuICByZWFkb25seSBrZXk6IHN0cmluZztcbiAgcmVhZG9ubHkgc3RhY2tOYW1lOiBzdHJpbmc7XG4gIHJlYWRvbmx5IHN0YWNrQ29uc3RydWN0UGF0aDogc3RyaW5nO1xuICByZWFkb25seSB0ZW1wbGF0ZVBhdGg6IHN0cmluZztcbiAgcmVhZG9ubHkgbG9jYWw6IFRlbXBsYXRlO1xuICByZWFkb25seSBhY2NvdW50Pzogc3RyaW5nO1xuICByZWFkb25seSByZWdpb24/OiBzdHJpbmc7XG59XG5cbi8qKiBjb250ZXh0IOOBruOCueOCv+ODg+OCr+OBqOOAgeOBneOBruODjeOCueODiOOBl+OBn+OCueOCv+ODg+OCr+OAgmNvbnRleHQg44Gr44Gv44ON44K544OI44GX44Gf44K544K/44OD44Kv44GM5YWl44KJ44Gq44GE44CCICovXG5leHBvcnQgZnVuY3Rpb24gY29sbGVjdFVuaXRzKGNvbnRleHQ6IFBpY2s8SVBvbGljeVZhbGlkYXRpb25Db250ZXh0LCAnc3RhY2tUZW1wbGF0ZXMnPik6IFVuaXRbXSB7XG4gIGNvbnN0IHVuaXRzOiBVbml0W10gPSBbXTtcbiAgZm9yIChjb25zdCBzdCBvZiBjb250ZXh0LnN0YWNrVGVtcGxhdGVzKSB7XG4gICAgY29uc3Qgc3RhY2tOYW1lID0gc3RhY2tOYW1lT2Yoc3QudGVtcGxhdGVQYXRoKTtcbiAgICBjb25zdCBiYXNlID0ge1xuICAgICAgc3RhY2tOYW1lLFxuICAgICAgc3RhY2tDb25zdHJ1Y3RQYXRoOiBzdC5zdGFja0NvbnN0cnVjdFBhdGgsXG4gICAgICBhY2NvdW50OiBzdC5hY2NvdW50SWQgPz8gcHJvY2Vzcy5lbnYuQ0RLX0RFRkFVTFRfQUNDT1VOVCxcbiAgICAgIHJlZ2lvbjogc3QucmVnaW9uID8/IHByb2Nlc3MuZW52LkNES19ERUZBVUxUX1JFR0lPTixcbiAgICB9O1xuICAgIGNvbnN0IHZpc2l0ID0gKGtleTogc3RyaW5nLCB0ZW1wbGF0ZVBhdGg6IHN0cmluZykgPT4ge1xuICAgICAgY29uc3QgbG9jYWw6IFRlbXBsYXRlID0gSlNPTi5wYXJzZShmcy5yZWFkRmlsZVN5bmModGVtcGxhdGVQYXRoLCAndXRmOCcpKTtcbiAgICAgIHVuaXRzLnB1c2goeyAuLi5iYXNlLCBrZXksIHRlbXBsYXRlUGF0aCwgbG9jYWwgfSk7XG4gICAgICBmb3IgKGNvbnN0IFtpZCwgcl0gb2YgT2JqZWN0LmVudHJpZXMobG9jYWwuUmVzb3VyY2VzID8/IHt9KSkge1xuICAgICAgICBjb25zdCBjaGlsZCA9IHI/LlR5cGUgPT09ICdBV1M6OkNsb3VkRm9ybWF0aW9uOjpTdGFjaycgPyBuZXN0ZWRUZW1wbGF0ZUZpbGUocGF0aC5kaXJuYW1lKHRlbXBsYXRlUGF0aCksIHIpIDogdW5kZWZpbmVkO1xuICAgICAgICBpZiAoY2hpbGQpIHZpc2l0KGAke2tleX0vJHtpZH1gLCBwYXRoLmpvaW4ocGF0aC5kaXJuYW1lKHRlbXBsYXRlUGF0aCksIGNoaWxkKSk7XG4gICAgICB9XG4gICAgfTtcbiAgICB2aXNpdChzdGFja05hbWUsIHN0LnRlbXBsYXRlUGF0aCk7XG4gIH1cbiAgcmV0dXJuIHVuaXRzO1xufVxuXG4vKipcbiAqIOODjeOCueODiOOBl+OBn+OCueOCv+ODg+OCr+OBruWtkOODhuODs+ODl+ODrOODvOODiOOBriBjZGsub3V0IOWGheOBruODleOCoeOCpOODq+WQjeOAgmBhd3M6YXNzZXQ6cGF0aGAg44Oh44K/44OH44O844K/44GvXG4gKiBDTEkg57WM55Sx44GuIHN5bnRoIOOBq+OBl+OBi+S7mOOBi+OBquOBhOOBruOBp+OAgeeEoeOBkeOCjOOBsCBUZW1wbGF0ZVVSTCDjga7kuK3jga7jgqLjgrvjg4Pjg4jjg4/jg4Pjgrfjg6XjgpJcbiAqIGAqLmFzc2V0cy5qc29uYCDjgaflvJXjgY/jgIJcbiAqL1xuZnVuY3Rpb24gbmVzdGVkVGVtcGxhdGVGaWxlKGRpcjogc3RyaW5nLCByOiBSZXNvdXJjZSk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gIGNvbnN0IGFzc2V0ID0gci5NZXRhZGF0YT8uWydhd3M6YXNzZXQ6cGF0aCddO1xuICBpZiAodHlwZW9mIGFzc2V0ID09PSAnc3RyaW5nJykgcmV0dXJuIGFzc2V0O1xuICBjb25zdCBoYXNoID0gLyhbMC05YS1mXXs2NH0pXFwuanNvbi8uZXhlYyhKU09OLnN0cmluZ2lmeShyLlByb3BlcnRpZXM/LlRlbXBsYXRlVVJMID8/ICcnKSk/LlsxXTtcbiAgaWYgKCFoYXNoKSByZXR1cm4gdW5kZWZpbmVkO1xuICBmb3IgKGNvbnN0IGYgb2YgZnMucmVhZGRpclN5bmMoZGlyKS5maWx0ZXIoKG4pID0+IG4uZW5kc1dpdGgoJy5hc3NldHMuanNvbicpKSkge1xuICAgIGNvbnN0IHNvdXJjZSA9IEpTT04ucGFyc2UoZnMucmVhZEZpbGVTeW5jKHBhdGguam9pbihkaXIsIGYpLCAndXRmOCcpKS5maWxlcz8uW2hhc2hdPy5zb3VyY2U/LnBhdGg7XG4gICAgaWYgKHR5cGVvZiBzb3VyY2UgPT09ICdzdHJpbmcnKSByZXR1cm4gc291cmNlO1xuICB9XG4gIHJldHVybiB1bmRlZmluZWQ7XG59XG5cbi8qKiBtYW5pZmVzdC5qc29uIOOBi+OCieODh+ODl+ODreOCpOaZguOBruOCueOCv+ODg+OCr+WQjeOCkuW8leOBj+OAguimi+OBpOOBi+OCieOBquOBkeOCjOOBsOODleOCoeOCpOODq+WQjeOBi+OCieOAgiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHN0YWNrTmFtZU9mKHRlbXBsYXRlUGF0aDogc3RyaW5nKTogc3RyaW5nIHtcbiAgY29uc3QgZmlsZSA9IHBhdGguYmFzZW5hbWUodGVtcGxhdGVQYXRoKTtcbiAgdHJ5IHtcbiAgICBjb25zdCBtYW5pZmVzdCA9IEpTT04ucGFyc2UoZnMucmVhZEZpbGVTeW5jKHBhdGguam9pbihwYXRoLmRpcm5hbWUodGVtcGxhdGVQYXRoKSwgJ21hbmlmZXN0Lmpzb24nKSwgJ3V0ZjgnKSk7XG4gICAgZm9yIChjb25zdCBbaWQsIGFdIG9mIE9iamVjdC5lbnRyaWVzPGFueT4obWFuaWZlc3QuYXJ0aWZhY3RzID8/IHt9KSkge1xuICAgICAgaWYgKGE/LnR5cGUgPT09ICdhd3M6Y2xvdWRmb3JtYXRpb246c3RhY2snICYmIGEucHJvcGVydGllcz8udGVtcGxhdGVGaWxlID09PSBmaWxlKSB7XG4gICAgICAgIHJldHVybiBhLnByb3BlcnRpZXMuc3RhY2tOYW1lID8/IGlkO1xuICAgICAgfVxuICAgIH1cbiAgfSBjYXRjaCB7XG4gICAgLy8gZmFsbCB0aHJvdWdoXG4gIH1cbiAgcmV0dXJuIGZpbGUucmVwbGFjZSgvXFwudGVtcGxhdGVcXC5qc29uJC8sICcnKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGNoZWNrUXVvdGFzKGNvbnRleHQ6IFBpY2s8SVBvbGljeVZhbGlkYXRpb25Db250ZXh0LCAnc3RhY2tUZW1wbGF0ZXMnPiwgb3B0czogUXVvdGFDaGVja09wdGlvbnMpOiBQb2xpY3lWaW9sYXRpb25bXSB7XG4gIHJldHVybiBmaW5kVmlvbGF0aW9ucyhjb250ZXh0LCBvcHRzKS5maWx0ZXIoKHYpID0+ICFvcHRzLmV4Y2x1ZGU/LmluY2x1ZGVzKHYucnVsZU5hbWUpKTtcbn1cblxuZnVuY3Rpb24gZmluZFZpb2xhdGlvbnMoY29udGV4dDogUGljazxJUG9saWN5VmFsaWRhdGlvbkNvbnRleHQsICdzdGFja1RlbXBsYXRlcyc+LCBvcHRzOiBRdW90YUNoZWNrT3B0aW9ucyk6IFBvbGljeVZpb2xhdGlvbltdIHtcbiAgY29uc3QgdmlvbGF0aW9uczogUG9saWN5VmlvbGF0aW9uW10gPSBbXTtcbiAgbGV0IHVuaXRzOiBVbml0W107XG4gIHRyeSB7XG4gICAgdW5pdHMgPSBjb2xsZWN0VW5pdHMoY29udGV4dCk7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICByZXR1cm4gY29udGV4dC5zdGFja1RlbXBsYXRlcy5sZW5ndGggPiAwXG4gICAgICA/IFtza2lwcGVkKGNvbnRleHQuc3RhY2tUZW1wbGF0ZXNbMF0sIGBjb3VsZCBub3QgcmVhZCB0aGUgdGVtcGxhdGVzICgke2Vycm9yVGV4dChlKX0pYCldXG4gICAgICA6IFtdO1xuICB9XG4gIGNvbnN0IGJ5UmVnaW9uID0gbmV3IE1hcDxzdHJpbmcgfCB1bmRlZmluZWQsIFVuaXRbXT4oKTtcbiAgZm9yIChjb25zdCB1IG9mIHVuaXRzKSBieVJlZ2lvbi5zZXQodS5yZWdpb24sIFsuLi4oYnlSZWdpb24uZ2V0KHUucmVnaW9uKSA/PyBbXSksIHVdKTtcblxuICBmb3IgKGNvbnN0IFtyZWdpb24sIGdyb3VwXSBvZiBieVJlZ2lvbikge1xuICAgIGxldCBmYWN0czogUXVvdGFGYWN0cztcbiAgICB0cnkge1xuICAgICAgZmFjdHMgPSBjYWNoZWRGZXRjaChncm91cFswXS50ZW1wbGF0ZVBhdGgsIHsgcmVnaW9uLCBzdGFja05hbWVzOiBbLi4ubmV3IFNldChncm91cC5tYXAoKHUpID0+IHUuc3RhY2tOYW1lKSldIH0sIG9wdHMpO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIHZpb2xhdGlvbnMucHVzaChza2lwcGVkKGdyb3VwWzBdLCBlcnJvclRleHQoZSkpKTtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cbiAgICBjb25zdCB0b3RhbDogRGVtYW5kID0geyB2cGM6IFtdLCBpZ3c6IFtdLCBlaXA6IFtdLCBjb25jdXJyZW5jeTogW10gfTtcbiAgICBjb25zdCB3aGVyZSA9IG5ldyBNYXA8c3RyaW5nLCBVbml0PigpO1xuICAgIGNvbnN0IHNraXBwZWRTdGFja3MgPSBuZXcgU2V0PHN0cmluZz4oKTtcbiAgICBjb25zdCBza2lwID0gKHU6IFVuaXQsIHdoeTogc3RyaW5nKSA9PiB7XG4gICAgICAvLyDjg43jgrnjg4jjgZfjgZ/jgrnjgr/jg4Pjgq/jga/opqrjgajlkIzjgZggY29uc3RydWN0IHBhdGgg44Gr5Ye644KL44Gu44Gn44CB44K544K/44OD44Kv44GU44Go44GrIDEg5Lu244Gr44GZ44KLXG4gICAgICBpZiAoIXNraXBwZWRTdGFja3MuaGFzKHUuc3RhY2tOYW1lKSkgdmlvbGF0aW9ucy5wdXNoKHNraXBwZWQodSwgd2h5KSk7XG4gICAgICBza2lwcGVkU3RhY2tzLmFkZCh1LnN0YWNrTmFtZSk7XG4gICAgfTtcbiAgICAvLyDlhYjjgavjgrnjgr/jg4Pjgq/ljZjkvY3jgafpmY3jgorjgovjgYvjgpLmsbrjgoHjgovjgILjg43jgrnjg4jjga7niYfmlrnjgaDjgZHmlbDjgYjjgovjgajjgIHljYrnq6/jgarlkIjoqIjjgafliKTlrprjgZfjgabjgZfjgb7jgYZcbiAgICBmb3IgKGNvbnN0IHUgb2YgZ3JvdXApIHtcbiAgICAgIGlmICh1LmFjY291bnQgJiYgL15cXGR7MTJ9JC8udGVzdCh1LmFjY291bnQpICYmIHUuYWNjb3VudCAhPT0gZmFjdHMuY2FsbGVyQWNjb3VudCkge1xuICAgICAgICBza2lwKHUsIGB0aGUgY3JlZGVudGlhbHMgYmVsb25nIHRvIGFjY291bnQgJHtmYWN0cy5jYWxsZXJBY2NvdW50fSwgYnV0IHRoaXMgc3RhY2sgZGVwbG95cyB0byAke3UuYWNjb3VudH0uIGBcbiAgICAgICAgICArICdUaGUgQ0RLIENMSSBkb2VzIG5vdCBwYXNzIC0tcHJvZmlsZSB0byB0aGUgYXBwOyBzZXQgQVdTX1BST0ZJTEUgaW5zdGVhZCcpO1xuICAgICAgfSBlbHNlIGlmIChmYWN0cy50ZW1wbGF0ZXNbdS5rZXldID09PSAndW5wYXJzZWFibGUnKSB7XG4gICAgICAgIHNraXAodSwgYHRoZSBkZXBsb3llZCB0ZW1wbGF0ZSBvZiAke3Uua2V5fSBpcyBub3QgSlNPTmApO1xuICAgICAgfVxuICAgIH1cbiAgICBmb3IgKGNvbnN0IHUgb2YgZ3JvdXApIHtcbiAgICAgIGlmIChza2lwcGVkU3RhY2tzLmhhcyh1LnN0YWNrTmFtZSkpIGNvbnRpbnVlO1xuICAgICAgY29uc3QgZCA9IGRlbWFuZCh1LmxvY2FsLCBmYWN0cy50ZW1wbGF0ZXNbdS5rZXldIGFzIFRlbXBsYXRlIHwgbnVsbCB8IHVuZGVmaW5lZCk7XG4gICAgICBmb3IgKGNvbnN0IGsgb2YgT2JqZWN0LmtleXMoQ09VTlRFRCkgYXMgQ291bnRlZFtdKSB0b3RhbFtrXS5wdXNoKC4uLmRba10ubWFwKChpZCkgPT4gdGFnKHdoZXJlLCB1LCBpZCkpKTtcbiAgICAgIHRvdGFsLmNvbmN1cnJlbmN5LnB1c2goLi4uZC5jb25jdXJyZW5jeS5tYXAoKGMpID0+ICh7IGlkOiB0YWcod2hlcmUsIHUsIGMuaWQpLCBkZWx0YTogYy5kZWx0YSB9KSkpO1xuICAgIH1cbiAgICBjb25zdCBlbnYgPSBgJHtmYWN0cy5jYWxsZXJBY2NvdW50fS8ke2ZhY3RzLnJlZ2lvbn1gO1xuICAgIGZvciAoY29uc3QgayBvZiBPYmplY3Qua2V5cyhDT1VOVEVEKSBhcyBDb3VudGVkW10pIHtcbiAgICAgIGNvbnN0IHF1b3RhID0gZmFjdHMucXVvdGFzPy5ba107XG4gICAgICBjb25zdCB1c2VkID0gZmFjdHMudXNhZ2Vba107XG4gICAgICBjb25zdCBhZGRpbmcgPSB0b3RhbFtrXS5sZW5ndGg7XG4gICAgICBpZiAocXVvdGEgPT09IHVuZGVmaW5lZCB8fCBhZGRpbmcgPT09IDAgfHwgdXNlZCArIGFkZGluZyA8PSBxdW90YSkgY29udGludWU7XG4gICAgICBjb25zdCBxID0gQ09VTlRFRFtrXTtcbiAgICAgIHZpb2xhdGlvbnMucHVzaCh7XG4gICAgICAgIHJ1bGVOYW1lOiBxLnJ1bGUsXG4gICAgICAgIGRlc2NyaXB0aW9uOiBgVGhpcyBhcHAgY3JlYXRlcyAke2FkZGluZ30gbmV3ICR7cS50eXBlfSBpbiAke2Vudn0sIHdoaWNoIGFscmVhZHkgdXNlcyAke3VzZWR9IG9mIGl0cyBgXG4gICAgICAgICAgKyBgXCIke3EubmFtZX1cIiBxdW90YSBvZiAke3F1b3RhfSAoJHtxLmNvZGV9KTsgdGhlIGRlcGxveSB3b3VsZCBmYWlsIG9uY2UgdGhlIHF1b3RhIGlzIHJlYWNoZWQuYCxcbiAgICAgICAgc2V2ZXJpdHk6IG9wdHMuc2V2ZXJpdHksXG4gICAgICAgIGZpeDogYFJlcXVlc3QgYSBxdW90YSBpbmNyZWFzZSBpbiB0aGUgU2VydmljZSBRdW90YXMgY29uc29sZSAoJHtxLmNvZGV9KSwgb3IgY3JlYXRlIGZld2VyICR7cS50eXBlfSByZXNvdXJjZXMgaW4gdGhpcyBlbnZpcm9ubWVudC5gLFxuICAgICAgICB2aW9sYXRpbmdSZXNvdXJjZXM6IHRvdGFsW2tdLm1hcCgodGFnZ2VkKSA9PiByZXNvdXJjZU9mKHdoZXJlLCB0YWdnZWQpKSxcbiAgICAgIH0pO1xuICAgIH1cbiAgICBjb25zdCBkZWx0YSA9IHRvdGFsLmNvbmN1cnJlbmN5LnJlZHVjZSgocywgYykgPT4gcyArIGMuZGVsdGEsIDApO1xuICAgIGNvbnN0IGxlZnQgPSBmYWN0cy51c2FnZS51bnJlc2VydmVkQ29uY3VycmVuY3kgLSBkZWx0YTtcbiAgICBpZiAoZGVsdGEgPiAwICYmIGxlZnQgPCBNSU5fVU5SRVNFUlZFRF9DT05DVVJSRU5DWSkge1xuICAgICAgdmlvbGF0aW9ucy5wdXNoKHtcbiAgICAgICAgcnVsZU5hbWU6IExBTUJEQV9DT05DVVJSRU5DWV9SVUxFLFxuICAgICAgICBkZXNjcmlwdGlvbjogYFRoaXMgYXBwIHJlc2VydmVzICR7ZGVsdGF9IG1vcmUgTGFtYmRhIGNvbmN1cnJlbnQgZXhlY3V0aW9ucyBpbiAke2Vudn0sIHdoaWNoIGhhcyBgXG4gICAgICAgICAgKyBgJHtmYWN0cy51c2FnZS51bnJlc2VydmVkQ29uY3VycmVuY3l9IHVucmVzZXJ2ZWQ7IExhbWJkYSByZWplY3RzIGEgY2hhbmdlIHRoYXQgbGVhdmVzIGZld2VyIHRoYW4gYFxuICAgICAgICAgICsgYCR7TUlOX1VOUkVTRVJWRURfQ09OQ1VSUkVOQ1l9LmAsXG4gICAgICAgIHNldmVyaXR5OiBvcHRzLnNldmVyaXR5LFxuICAgICAgICBmaXg6ICdMb3dlciBSZXNlcnZlZENvbmN1cnJlbnRFeGVjdXRpb25zLCBvciByZXF1ZXN0IGEgaGlnaGVyIFwiQ29uY3VycmVudCBleGVjdXRpb25zXCIgcXVvdGEgKGxhbWJkYS9MLUI5OUE5Mzg0KS4nLFxuICAgICAgICB2aW9sYXRpbmdSZXNvdXJjZXM6IHRvdGFsLmNvbmN1cnJlbmN5Lm1hcCgoYykgPT4gcmVzb3VyY2VPZih3aGVyZSwgYy5pZCkpLFxuICAgICAgfSk7XG4gICAgfVxuICB9XG4gIHJldHVybiB2aW9sYXRpb25zO1xufVxuXG4vKiog44K544K/44OD44Kv44KS44G+44Gf44GE44Gn5ZCM44GY6KuW55CGIElEIOOBjOWHuuOBpuOBj+OCi+OBruOBp+OAgeOCreODvOS7mOOBjeOBruitmOWIpeWtkOOBq+OBl+OBpuOBi+OCieWHuuaJgOOCkuW8leOBj+OAgiAqL1xuZnVuY3Rpb24gdGFnKHdoZXJlOiBNYXA8c3RyaW5nLCBVbml0PiwgdTogVW5pdCwgaWQ6IHN0cmluZyk6IHN0cmluZyB7XG4gIGNvbnN0IHQgPSBgJHt1LmtleX1cXHUwMDAwJHtpZH1gO1xuICB3aGVyZS5zZXQodCwgdSk7XG4gIHJldHVybiB0O1xufVxuXG5mdW5jdGlvbiByZXNvdXJjZU9mKHdoZXJlOiBNYXA8c3RyaW5nLCBVbml0PiwgdGFnZ2VkOiBzdHJpbmcpIHtcbiAgY29uc3QgdSA9IHdoZXJlLmdldCh0YWdnZWQpITtcbiAgcmV0dXJuIHsgcmVzb3VyY2VMb2dpY2FsSWQ6IHRhZ2dlZC5zcGxpdCgnXFx1MDAwMCcpWzFdLCB0ZW1wbGF0ZVBhdGg6IHUudGVtcGxhdGVQYXRoLCBsb2NhdGlvbnM6IFsnKHRlbXBsYXRlKSddIH07XG59XG5cbmZ1bmN0aW9uIHNraXBwZWQoc3Q6IHsgc3RhY2tDb25zdHJ1Y3RQYXRoOiBzdHJpbmc7IHRlbXBsYXRlUGF0aDogc3RyaW5nIH0sIHdoeTogc3RyaW5nKTogUG9saWN5VmlvbGF0aW9uIHtcbiAgcmV0dXJuIHtcbiAgICBydWxlTmFtZTogUVVPVEFfU0tJUFBFRF9SVUxFLFxuICAgIGRlc2NyaXB0aW9uOiBgY2RrLXByZWZsaWdodCBkaWQgbm90IGNoZWNrIHNlcnZpY2UgcXVvdGFzIGZvciB0aGlzIHN0YWNrOiAke3doeX0uYCxcbiAgICBzZXZlcml0eTogJ3dhcm5pbmcnLFxuICAgIGZpeDogJ01ha2UgQVdTIGNyZWRlbnRpYWxzIGZvciB0aGUgdGFyZ2V0IGFjY291bnQgYXZhaWxhYmxlIHRvIHRoZSBhcHAgcHJvY2VzcyAoQVdTX1BST0ZJTEUgb3IgQVdTXyogZW52aXJvbm1lbnQgdmFyaWFibGVzKSwgJ1xuICAgICAgKyAnd2l0aCBzZXJ2aWNlcXVvdGFzOkdldFNlcnZpY2VRdW90YSwgc2VydmljZXF1b3RhczpHZXRBV1NEZWZhdWx0U2VydmljZVF1b3RhLCBlYzI6RGVzY3JpYmV7VnBjcyxJbnRlcm5ldEdhdGV3YXlzLEFkZHJlc3Nlc30sIGxhbWJkYTpHZXRBY2NvdW50U2V0dGluZ3MsICdcbiAgICAgICsgJ2Nsb3VkZm9ybWF0aW9uOkdldFRlbXBsYXRlIGFuZCBjbG91ZGZvcm1hdGlvbjpEZXNjcmliZVN0YWNrUmVzb3VyY2UuJyxcbiAgICB2aW9sYXRpbmdSZXNvdXJjZXM6IFt7IGNvbnN0cnVjdFBhdGg6IHN0LnN0YWNrQ29uc3RydWN0UGF0aCwgdGVtcGxhdGVQYXRoOiBzdC50ZW1wbGF0ZVBhdGgsIGxvY2F0aW9uczogWycodGVtcGxhdGUpJ10gfV0sXG4gIH07XG59XG5cbmZ1bmN0aW9uIGVycm9yVGV4dChlOiB1bmtub3duKTogc3RyaW5nIHtcbiAgY29uc3Qgc3RkZXJyID0gKGUgYXMgeyBzdGRlcnI/OiB1bmtub3duIH0pPy5zdGRlcnI7XG4gIGlmICh0eXBlb2Ygc3RkZXJyID09PSAnc3RyaW5nJyAmJiBzdGRlcnIudHJpbSgpKSByZXR1cm4gc3RkZXJyLnRyaW0oKTtcbiAgY29uc3QgbWVzc2FnZSA9IChlIGFzIHsgbWVzc2FnZT86IHVua25vd24gfSk/Lm1lc3NhZ2U7XG4gIHJldHVybiB0eXBlb2YgbWVzc2FnZSA9PT0gJ3N0cmluZycgPyBtZXNzYWdlIDogU3RyaW5nKGUpO1xufVxuXG5pbnRlcmZhY2UgQ2FjaGVFbnRyeSB7XG4gIHJlYWRvbmx5IGF0OiBudW1iZXI7XG4gIHJlYWRvbmx5IHF1b3Rhc0F0OiBudW1iZXI7XG4gIHJlYWRvbmx5IGZhY3RzOiBRdW90YUZhY3RzO1xufVxuXG4vKipcbiAqIGNkay5vdXQvLmNkay1wcmVmbGlnaHQvcXVvdGEtY2FjaGUuanNvbiDjgavnva7jgY/jgIJzeW50aCDjga8gZGlmZi9kZXBsb3kvd2F0Y2gg44Gu44Gf44Gz44Gr6LWw44KL44Gu44Gn44CBXG4gKiDmr47lm54gQVdTIOOBq+WVj+OBhOWQiOOCj+OBm+OBquOBhOOCiOOBhuOBq+OBmeOCi+OAguOCreODvOOBqyBBV1NfUFJPRklMRSDjgpLlhaXjgozjgIHos4fmoLzmg4XloLHjgpLliIfjgormm7/jgYjjgZ/jgonlvJXjgY3nm7TjgZnjgIJcbiAqL1xuZnVuY3Rpb24gY2FjaGVkRmV0Y2godGVtcGxhdGVQYXRoOiBzdHJpbmcsIHJlcTogUXVvdGFSZXF1ZXN0LCBvcHRzOiBRdW90YUNoZWNrT3B0aW9ucyk6IFF1b3RhRmFjdHMge1xuICBjb25zdCBub3cgPSAob3B0cy5ub3cgPz8gRGF0ZS5ub3cpKCk7XG4gIGNvbnN0IGZpbGUgPSBwYXRoLmpvaW4oYXNzZW1ibHlSb290KHRlbXBsYXRlUGF0aCksICcuY2RrLXByZWZsaWdodCcsICdxdW90YS1jYWNoZS5qc29uJyk7XG4gIGNvbnN0IGtleSA9IGAke3Byb2Nlc3MuZW52LkFXU19QUk9GSUxFID8/ICcnfXwke3JlcS5yZWdpb24gPz8gJyd9YDtcbiAgbGV0IGNhY2hlOiBSZWNvcmQ8c3RyaW5nLCBDYWNoZUVudHJ5PiA9IHt9O1xuICB0cnkge1xuICAgIGNhY2hlID0gSlNPTi5wYXJzZShmcy5yZWFkRmlsZVN5bmMoZmlsZSwgJ3V0ZjgnKSk7XG4gIH0gY2F0Y2gge1xuICAgIC8vIOeEoeOBhOODu+WjiuOCjOOBpuOBhOOCi1xuICB9XG4gIGNvbnN0IGhpdCA9IGNhY2hlW2tleV07XG4gIGNvbnN0IGNvdmVycyA9IGhpdCAmJiByZXEuc3RhY2tOYW1lcy5ldmVyeSgobikgPT4gbiBpbiBoaXQuZmFjdHMudGVtcGxhdGVzKTtcbiAgaWYgKGhpdCAmJiBjb3ZlcnMgJiYgbm93IC0gaGl0LmF0IDwgb3B0cy50dGxNcyAmJiBoaXQuZmFjdHMucXVvdGFzKSByZXR1cm4gaGl0LmZhY3RzO1xuXG4gIGNvbnN0IHF1b3Rhc0ZyZXNoID0gaGl0Py5mYWN0cy5xdW90YXMgIT09IHVuZGVmaW5lZCAmJiBub3cgLSBoaXQucXVvdGFzQXQgPCBRVU9UQV9UVExfTVM7XG4gIGNvbnN0IGdvdCA9IChvcHRzLmZldGNoID8/IGZldGNoRnJvbUF3cykoeyAuLi5yZXEsIHNraXBRdW90YXM6IHF1b3Rhc0ZyZXNoIH0pO1xuICBjb25zdCBmYWN0czogUXVvdGFGYWN0cyA9IHsgLi4uZ290LCBxdW90YXM6IGdvdC5xdW90YXMgPz8gaGl0Py5mYWN0cy5xdW90YXMgfTtcbiAgY2FjaGVba2V5XSA9IHsgYXQ6IG5vdywgcXVvdGFzQXQ6IGdvdC5xdW90YXMgPyBub3cgOiBoaXQhLnF1b3Rhc0F0LCBmYWN0cyB9O1xuICBwZW5kaW5nQ2FjaGUuc2V0KGZpbGUsIGNhY2hlKTtcbiAgcmV0dXJuIGZhY3RzO1xufVxuXG4vKipcbiAqIHZhbGlkYXRlKCkg44Gu5pyA5Lit44GvIGNkay5vdXQg44Gr5pu444GR44Gq44GE44CCQ0RLIOOBryBDbG91ZEZvcm1hdGlvblZhbGlkYXRlUGx1Z2luIOS7peWkluOBruODl+ODqeOCsOOCpOODs+OBrlxuICog5YmN5b6M44GnIGNkay5vdXQg6YWN5LiL44Gu5YWo44OV44Kh44Kk44Or44Gu44OP44OD44K344Ol44KS5Y+W44KK44CB5pei5a2Y44OV44Kh44Kk44Or44GM5aSJ44KP44Gj44Gm44GE44KM44GwXG4gKiBJbGxlZ2FsUGx1Z2luT3BlcmF0aW9uIOOBpyBzeW50aCDjgpLokL3jgajjgZnvvIhhd3MtY2RrLWxpYiAyLjI3MS4wIHN5bnRoZXNpcy12YWxpZGF0aW9u77yJ44CCXG4gKiBUVEwg5YiH44KM44Gu5LiK5pu444GN44GM44Gh44KH44GG44Gp44Gd44KM44Gr5b2T44Gf44KL44Gu44Gn44CB5pu444GP44Gu44GvIHN5bnRoIOOBjOe1guOCj+OBo+OBpuOBi+OCieOBq+OBmeOCi+OAglxuICovXG5jb25zdCBwZW5kaW5nQ2FjaGUgPSBuZXcgTWFwPHN0cmluZywgUmVjb3JkPHN0cmluZywgQ2FjaGVFbnRyeT4+KCk7XG5cbmV4cG9ydCBmdW5jdGlvbiBmbHVzaFF1b3RhQ2FjaGUoKTogdm9pZCB7XG4gIGZvciAoY29uc3QgW2ZpbGUsIGNhY2hlXSBvZiBwZW5kaW5nQ2FjaGUpIHtcbiAgICB0cnkge1xuICAgICAgZnMubWtkaXJTeW5jKHBhdGguZGlybmFtZShmaWxlKSwgeyByZWN1cnNpdmU6IHRydWUgfSk7XG4gICAgICBmcy53cml0ZUZpbGVTeW5jKGZpbGUsIEpTT04uc3RyaW5naWZ5KGNhY2hlKSk7XG4gICAgfSBjYXRjaCB7XG4gICAgICAvLyDjgq3jg6Pjg4Pjgrfjg6Xjga/nhKHjgY/jgabjgoLli5XjgY9cbiAgICB9XG4gIH1cbiAgcGVuZGluZ0NhY2hlLmNsZWFyKCk7XG59XG5cbmNvbnN0IEZMVVNIX0lOU1RBTExFRCA9IFN5bWJvbC5mb3IoJ2Nkay1wcmVmbGlnaHQucXVvdGFDYWNoZUZsdXNoJyk7XG5cbi8qKiBBcHAuc3ludGgoKSDjga7lvozjgacgZmx1c2hRdW90YUNhY2hlKCkg44KS5ZG844G244KI44GG44Gr44GZ44KL44CCICovXG5leHBvcnQgZnVuY3Rpb24gaW5zdGFsbFF1b3RhQ2FjaGVGbHVzaChzY29wZTogSUNvbnN0cnVjdCk6IHZvaWQge1xuICBjb25zdCByb290ID0gc2NvcGUubm9kZS5yb290O1xuICBpZiAoIUFwcC5pc0FwcChyb290KSkgcmV0dXJuO1xuICBjb25zdCBhcHAgPSByb290IGFzIEFwcCAmIHsgW0ZMVVNIX0lOU1RBTExFRF0/OiBib29sZWFuIH07XG4gIGlmIChhcHBbRkxVU0hfSU5TVEFMTEVEXSkgcmV0dXJuO1xuICBPYmplY3QuZGVmaW5lUHJvcGVydHkoYXBwLCBGTFVTSF9JTlNUQUxMRUQsIHsgdmFsdWU6IHRydWUsIGVudW1lcmFibGU6IGZhbHNlIH0pO1xuICBjb25zdCBzeW50aCA9IGFwcC5zeW50aC5iaW5kKGFwcCk7XG4gIGFwcC5zeW50aCA9IChvcHRpb25zPzogUGFyYW1ldGVyczxBcHBbJ3N5bnRoJ10+WzBdKSA9PiB7XG4gICAgdHJ5IHtcbiAgICAgIHJldHVybiBzeW50aChvcHRpb25zKTtcbiAgICB9IGZpbmFsbHkge1xuICAgICAgZmx1c2hRdW90YUNhY2hlKCk7XG4gICAgfVxuICB9O1xufVxuXG4vKiogU3RhZ2Ug44Gu44K544K/44OD44Kv44GvIGNkay5vdXQvYXNzZW1ibHktKu+8j+OBq+WFpeOCi+OBruOBp+OAgeOCouODl+ODquOBriBjZGsub3V0IOOBvuOBp+S4iuOBjOOCi+OAgiAqL1xuZnVuY3Rpb24gYXNzZW1ibHlSb290KHRlbXBsYXRlUGF0aDogc3RyaW5nKTogc3RyaW5nIHtcbiAgbGV0IGRpciA9IHBhdGguZGlybmFtZSh0ZW1wbGF0ZVBhdGgpO1xuICB3aGlsZSAocGF0aC5iYXNlbmFtZShkaXIpLnN0YXJ0c1dpdGgoJ2Fzc2VtYmx5LScpKSBkaXIgPSBwYXRoLmRpcm5hbWUoZGlyKTtcbiAgcmV0dXJuIGRpcjtcbn1cblxuZnVuY3Rpb24gZmV0Y2hGcm9tQXdzKHJlcTogUXVvdGFSZXF1ZXN0KTogUXVvdGFGYWN0cyB7XG4gIGNvbnN0IHdvcmtlciA9IHBhdGguam9pbihfX2Rpcm5hbWUsICdxdW90YS13b3JrZXIuanMnKTtcbiAgaWYgKCFmcy5leGlzdHNTeW5jKHdvcmtlcikpIHRocm93IG5ldyBFcnJvcihgcXVvdGEgd29ya2VyIG5vdCBmb3VuZCBhdCAke3dvcmtlcn1gKTtcbiAgY29uc3Qgb3V0ID0gZXhlY0ZpbGVTeW5jKHByb2Nlc3MuZXhlY1BhdGgsIFt3b3JrZXJdLCB7XG4gICAgaW5wdXQ6IEpTT04uc3RyaW5naWZ5KHJlcSksXG4gICAgZW5jb2Rpbmc6ICd1dGY4JyxcbiAgICB0aW1lb3V0OiA2MF8wMDAsXG4gICAgLy8g44OH44OX44Ot44Kk5riI44G/44OG44Oz44OX44Os44O844OI44Gu5YWo5paH44KS6L+U44GZ44Gu44Gn44CB5pei5a6a44GuIDEgTWlCIOOBp+OBr+Wkp+OBjeOBhOOCouODl+ODquOBu+OBqem7meOBo+OBpuaknOafu+OBjOWkluOCjOOCi1xuICAgIG1heEJ1ZmZlcjogMjU2ICogMTAyNCAqIDEwMjQsXG4gICAgc3RkaW86IFsncGlwZScsICdwaXBlJywgJ3BpcGUnXSxcbiAgfSk7XG4gIHJldHVybiBKU09OLnBhcnNlKG91dCk7XG59XG4iXX0=
package/llms.txt CHANGED
@@ -12,6 +12,9 @@ Scope: every deploy-time failure, and every post-deploy run that is certain to f
12
12
  4. Opt-outs: `exclude: ['<rule-id>']` disables one rule; `enforce: false` reports as warnings only (with construct traces and per-finding acknowledgement). Add `strict: true` to also fail on the engine's own error-class findings (F-/E-prefixed) that CDK otherwise downgrades to warnings.
13
13
  5. Opt-in: `checkQuotas: true` also compares what the app creates (VPCs, internet gateways, Elastic IPs per Region, reserved Lambda concurrency) against the target account's Service Quotas and usage. It is the only option that calls AWS at synth time; the app process needs credentials (`AWS_PROFILE`, since the CDK CLI does not pass `--profile` on), and without them the check is skipped with a `pf-quota-check-skipped` warning.
14
14
  6. Machine-readable findings: synth with `-c @aws-cdk/core:validationReportJson=true`, then read `cdk.out/validation-report.json`.
15
+ 7. Without deploying or a full synth step: `cdk --unstable=validate validate --no-online` runs the same rules (add `--watch` to re-run on change).
16
+ 8. Across stacks (warnings, never fail synth): `pf-cfn-export-name-conflict` (two stacks in one account and Region export the same name) and `pf-cfn-import-value-missing-export` (an import named `<app stack>:...` that stack does not export). Acknowledge with `cdk-preflight-exports::<rule-id>`.
17
+ 9. Sibling MCP servers for the same cdk.out: `npx -y cfn-idle-cost mcp` (idle cost) and `npx -y cfn-exec-policy mcp` (execution role permissions).
15
18
 
16
19
  ## Key files
17
20
 
package/package.json CHANGED
@@ -103,7 +103,7 @@
103
103
  "publishConfig": {
104
104
  "access": "public"
105
105
  },
106
- "version": "1.10.0",
106
+ "version": "1.11.1",
107
107
  "jest": {
108
108
  "coverageProvider": "v8",
109
109
  "collectCoverage": false,