cdk-preflight 0.0.0 → 0.0.2

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.
@@ -19,6 +19,7 @@ cdk-preflight のルール追加パイプライン。AGENTS.md の設計原則
19
19
  console.log(JSON.stringify(r.diagnostics, null, 2));"
20
20
  ```
21
21
  ERROR/FATAL(source: SCHEMA / CFN_LINT)が既に出るなら**ルールは書かない**。終了し、その旨を報告する。
22
+ 判定の全体像(WARN クラスのみ出るがデプロイは失敗するグレーゾーン、L2/cfn-lint/サーバー側検証との棲み分け)は AGENTS.md の「Where this pack sits among validation layers」に従う。L2 (aws-cdk-lib) が同じ検証を持っていても不採用理由にならない(原則 5)。
22
23
  3. **ルール作成**: `rules/<service>/<rule-id>/` に 4 ファイル。規約:
23
24
  - `package cdk_preflight` + `import rego.v1`、診断は `make_diag_full("<rule-id>", "ERROR", name, path, msg, fix, url)`
24
25
  - ヘルパーは `_pf_<短縮名>_` プレフィックスで一意に
package/.jsii CHANGED
@@ -9410,11 +9410,11 @@
9410
9410
  "hasDefaultInterfaces": true
9411
9411
  }
9412
9412
  },
9413
- "tscRootDir": "/Users/kazuhoshinozuka/git/cdk-preflight/src"
9413
+ "tscRootDir": "/home/runner/work/cdk-preflight/cdk-preflight/src"
9414
9414
  },
9415
9415
  "name": "cdk-preflight",
9416
9416
  "readme": {
9417
- "markdown": "# cdk-preflight\n\n**Catch deploy-time CloudFormation failures at `cdk synth` time.**\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. It injects the rules into the AWS CDK built-in CloudFormation validator (`aws-cdk-lib` >= 2.267.0), so violations surface at synth with construct-level traces before you deploy.\n\nEvery bundled rule is backed by a `fail`/`pass` template pair, and the failure has been reproduced against real AWS (or is explicitly marked `doc-only`). Rules that the built-in validation engine already covers are deliberately **not** duplicated — a test suite enforces this.\n\n## Quick start\n\n```bash\nnpm i -D cdk-preflight\nnpx cdk-preflight init # inserts Preflight.apply(app) into your CDK app\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\n`cdk synth` then reports violations like:\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## Failing the build\n\nBy default findings are warnings (matching the CDK built-in validator behavior). To make violations fail `cdk synth`:\n\n```ts\nPreflight.apply(app, { enforce: true });\n```\n\n| Option | Default | Effect |\n|---|---|---|\n| `enforce` | `false` | Violations of bundled rules fail synthesis instead of warning |\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\nIndividual findings can also be suppressed with the CDK acknowledge mechanism shown in the warning text.\n\n## Bundled rules\n\nSee [docs/rules.md](docs/rules.md) for the generated rule table. Highlights:\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**: `StartAt`/`Next`/`Default`/`Choices` must reference defined states\n- **EC2**: security group TCP/UDP port ranges and `FromPort <= ToPort`\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` (finds the entry point via `cdk.json` and inserts `Preflight.apply(app)`; use `--dry-run` to preview)\n3. Run `cdk synth` and read the warnings; each carries a rule id, a suggested fix, and a construct trace\n4. If the user wants synthesis to fail on violations, change the call to `Preflight.apply(app, { enforce: true })`\n\nThe machine-readable findings are written to `cdk.out/validation-report.json` when synthesizing with `-c @aws-cdk/core:validationReportJson=true`.\n\n## How it works\n\n`Preflight.apply()` registers the rules with the CDK built-in `CloudFormationValidatePlugin` (the [cloudformation-validate](https://github.com/aws-cloudformation/cloudformation-validate) Rust/WASM engine that ships inside `aws-cdk-lib`). No extra binaries, no network access at synth time. In `enforce` mode the same engine is invoked through a dedicated validation plugin so that violations fail synthesis.\n\nConstraints that *can* be expressed in schemas or generic engine rules are contributed upstream instead of living here; each rule's `meta.yaml` tracks its upstream status, and rules retire once the engine covers them.\n\n## Requirements\n\n- `aws-cdk-lib` >= 2.267.0 (the first release that bundles the built-in CloudFormation validator)\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"
9417
+ "markdown": "# cdk-preflight\n\n**Catch deploy-time CloudFormation failures at `cdk synth` time.**\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\nEvery bundled rule is backed by a `fail`/`pass` template pair, and the failure has been reproduced against real AWS (or is explicitly marked `doc-only`). Rules that the built-in validation engine already covers are deliberately **not** duplicated — a test suite enforces this.\n\n## Quick start\n\n```bash\nnpm i -D cdk-preflight\nnpx cdk-preflight init # inserts Preflight.apply(app) into your CDK app\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## 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| 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\nTo opt out of a single rule, pass its id in `exclude`. In observe-only mode, individual findings can also be suppressed with the CDK acknowledge mechanism shown in the warning text.\n\n## Bundled rules\n\nSee [docs/rules.md](docs/rules.md) for the generated rule table. Highlights:\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## For AI agents\n\nTo add cdk-preflight to a CDK app:\n\n1. `npm i -D cdk-preflight`\n2. `npx cdk-preflight 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## 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, no network access at synth time. 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 are contributed upstream instead of living here; each rule's `meta.yaml` tracks its upstream status, and rules retire once the engine covers them.\n\n## Requirements\n\n- `aws-cdk-lib` >= 2.267.0 (the first release that bundles the built-in CloudFormation validator)\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"
9418
9418
  },
9419
9419
  "repository": {
9420
9420
  "type": "git",
@@ -9443,7 +9443,7 @@
9443
9443
  "kind": "class",
9444
9444
  "locationInModule": {
9445
9445
  "filename": "src/index.ts",
9446
- "line": 62
9446
+ "line": 65
9447
9447
  },
9448
9448
  "methods": [
9449
9449
  {
@@ -9453,7 +9453,7 @@
9453
9453
  },
9454
9454
  "locationInModule": {
9455
9455
  "filename": "src/index.ts",
9456
- "line": 66
9456
+ "line": 69
9457
9457
  },
9458
9458
  "name": "apply",
9459
9459
  "parameters": [
@@ -9480,7 +9480,7 @@
9480
9480
  },
9481
9481
  "locationInModule": {
9482
9482
  "filename": "src/index.ts",
9483
- "line": 91
9483
+ "line": 94
9484
9484
  },
9485
9485
  "name": "ruleIds",
9486
9486
  "returns": {
@@ -9517,15 +9517,15 @@
9517
9517
  {
9518
9518
  "abstract": true,
9519
9519
  "docs": {
9520
- "default": "false",
9521
- "remarks": "In the default (warn) mode, findings are reported through the CDK built-in\nCloudFormation validator and surface as synth warnings with construct traces.\nWith `enforce: true`, cdk-preflight evaluates its rules with its own\nvalidation plugin and a violation makes `cdk synth` fail.",
9520
+ "default": "true",
9521
+ "remarks": "In the default (enforce) mode, cdk-preflight evaluates its rules with its\nown validation plugin and a violation makes `cdk synth` fail — the whole\npoint of preflight checks is that a template known to fail at deploy time\nnever leaves your machine. Set `enforce: false` to observe first: findings\nare then reported through the CDK built-in CloudFormation validator and\nsurface as synth warnings with construct traces, which can be muted per\nfinding via `Acknowledge with 'CloudFormation-Validate::<rule-id>'`.",
9522
9522
  "stability": "stable",
9523
- "summary": "Fail synthesis (instead of reporting warnings) when a bundled rule is violated."
9523
+ "summary": "Fail synthesis when a bundled rule is violated."
9524
9524
  },
9525
9525
  "immutable": true,
9526
9526
  "locationInModule": {
9527
9527
  "filename": "src/index.ts",
9528
- "line": 27
9528
+ "line": 30
9529
9529
  },
9530
9530
  "name": "enforce",
9531
9531
  "optional": true,
@@ -9567,7 +9567,7 @@
9567
9567
  "immutable": true,
9568
9568
  "locationInModule": {
9569
9569
  "filename": "src/index.ts",
9570
- "line": 48
9570
+ "line": 51
9571
9571
  },
9572
9572
  "name": "includeUpstreamPending",
9573
9573
  "optional": true,
@@ -9579,14 +9579,14 @@
9579
9579
  "abstract": true,
9580
9580
  "docs": {
9581
9581
  "default": "false",
9582
- "remarks": "Only effective together with `enforce: true`.",
9582
+ "remarks": "Only effective in enforce mode (the default).",
9583
9583
  "stability": "stable",
9584
9584
  "summary": "In enforce mode, additionally fail synthesis on error-class findings (severity ERROR/FATAL) of the built-in validation engine itself, e.g. schema violations like `F3034`. This is the workaround for the CDK behavior where all built-in findings are downgraded to warnings."
9585
9585
  },
9586
9586
  "immutable": true,
9587
9587
  "locationInModule": {
9588
9588
  "filename": "src/index.ts",
9589
- "line": 39
9589
+ "line": 42
9590
9590
  },
9591
9591
  "name": "strict",
9592
9592
  "optional": true,
@@ -9598,6 +9598,6 @@
9598
9598
  "symbolId": "src/index:PreflightOptions"
9599
9599
  }
9600
9600
  },
9601
- "version": "0.0.0",
9602
- "fingerprint": "g0j6zqzT02rux5ro9xIEmyrLbkpnKKMzP4FjqvS4Odo="
9601
+ "version": "0.0.2",
9602
+ "fingerprint": "fJmKA47PBVYXUgC5Wv99/vO+vso7jYJ844L5jcJ8m+Q="
9603
9603
  }
package/AGENTS.md CHANGED
@@ -14,6 +14,22 @@ Scope: **deploy-failure prevention only.** Security/compliance policies (cdk-nag
14
14
  2. **Every rule ships with proof.** `templates/fail.template.json` must violate exactly this rule; `templates/pass.template.json` must be clean. `meta.yaml#repro` records how the deploy-time failure was verified (`real-deploy` / `research-case` / `doc-only` — the last one requires an explanation in `evidence`).
15
15
  3. **Rules graduate upstream.** Constraints expressible in schemas or generic engine rules should be PRed to [cloudformation-validate](https://github.com/aws-cloudformation/cloudformation-validate) (open an issue first). Track status in `meta.yaml#upstream` (`none` / `pending-engine` / `engine-pr` / `retired`). Shrinking this pack is success, not failure.
16
16
  4. **Tests are the contract.** Never merge with a red test; never weaken an assertion to make it pass. New behavior needs a new test first.
17
+ 5. **The boundary is the engine, not the CDK L2 layer.** Rules validate synthesized templates, so an L2 construct that validates (or structurally prevents) the same mistake does not make a rule redundant — L1 usage, escape hatches, `addPropertyOverride`, and externally generated templates all bypass L2. Overlapping an L2 guard is fine and expected; overlapping the bundled engine is forbidden (principle 1). When a rule does overlap L2, note it in the PR so reviewers can weigh the marginal value. See "Where this pack sits among validation layers" below.
18
+
19
+ ## Where this pack sits among validation layers
20
+
21
+ Four other validation layers exist around a CDK app. Only one of them is a boundary for this pack; the relationships are:
22
+
23
+ | Layer | Runs at | Catches | Relation to this pack |
24
+ |---|---|---|---|
25
+ | CDK L2 construct validation | synth, only on that construct's prop path | per-construct guards (e.g. `Volume` iops checks, SNS auto-`.fifo`, Fargate hardcoding `awsvpc`) | **Not a boundary** (principle 5). Bypassed by L1 / escape hatches / external templates. Overlap allowed; record it in the PR |
26
+ | 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 |
27
+ | 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). If the bare engine reports ERROR/FATAL on the minimal violating template, the rule must not exist — enforced by the jest duplication guard |
28
+ | 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) |
29
+ | 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 | **Effectively 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). Never a reason to reject a rule |
30
+ | 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 |
31
+
32
+ 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. (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). (3) L1/L2 coverage never disqualifies, only gets noted.
17
33
 
18
34
  ## Repository layout
19
35
 
@@ -57,4 +73,7 @@ bench/ # real-deploy verification (needs an AWS account; no
57
73
 
58
74
  - Custom rule diagnostics carry `source: "CUSTOM"`; schema checks are `SCHEMA` (e.g. `F3034`), cfn-lint-derived rules are `CFN_LINT`.
59
75
  - The engine's bundled schemas are *patched* (e.g. SQS numeric ranges exist even though the raw registry schema lacks them). Always check what the engine already catches before writing a rule.
60
- - The CDK plugin path downgrades every finding to a warning; `@aws-cdk/core:validateAgainstDefaultRules` does not promote them (confirmed inert in aws-cdk-lib 2.267.0). This is why `enforce` mode exists.
76
+ - The CDK plugin path downgrades every finding to a warning; `@aws-cdk/core:validateAgainstDefaultRules` does not promote them (confirmed inert in aws-cdk-lib 2.267.0). This is why `enforce` mode exists — and why it is the default (`enforce: false` opts into warn-only reporting).
77
+ - `to_number(null)` evaluates to `0` (not undefined). When reading optional numbers via `object.get(x, key, null)`, guard with `!= null` before `to_number`, or an absent property silently becomes 0 and can fire the rule (this bit the S3 lifecycle rules during development).
78
+ - The Rego parser rejects two-variable `some k, v in obj` **inside comprehensions** ("unexpected keyword `some`"; fine in rule bodies). Use `some k in object.keys(obj)` and index instead.
79
+ - The CDK renders `Acknowledge with 'cdk-preflight::<rule-id>'` under enforce-mode errors, but `Validations.acknowledge()` currently suppresses only annotation warnings (`validations.ts`: "Currently only annotation warnings can be suppressed") — the hint is inert for policy violations. The working opt-outs in enforce mode are `exclude` and `enforce: false`; do not document the acknowledge mechanism for enforce mode.
package/API.md CHANGED
@@ -19,7 +19,7 @@ const preflightOptions: PreflightOptions = { ... }
19
19
 
20
20
  | **Name** | **Type** | **Description** |
21
21
  | --- | --- | --- |
22
- | <code><a href="#cdk-preflight.PreflightOptions.property.enforce">enforce</a></code> | <code>boolean</code> | Fail synthesis (instead of reporting warnings) when a bundled rule is violated. |
22
+ | <code><a href="#cdk-preflight.PreflightOptions.property.enforce">enforce</a></code> | <code>boolean</code> | Fail synthesis when a bundled rule is violated. |
23
23
  | <code><a href="#cdk-preflight.PreflightOptions.property.exclude">exclude</a></code> | <code>string[]</code> | Rule ids to disable (see `Preflight.ruleIds()` or docs/rules.md). |
24
24
  | <code><a href="#cdk-preflight.PreflightOptions.property.includeUpstreamPending">includeUpstreamPending</a></code> | <code>boolean</code> | Include rules that are marked `pending-engine` (candidates that have been proposed to the upstream cloudformation-validate engine but are not merged yet). |
25
25
  | <code><a href="#cdk-preflight.PreflightOptions.property.strict">strict</a></code> | <code>boolean</code> | In enforce mode, additionally fail synthesis on error-class findings (severity ERROR/FATAL) of the built-in validation engine itself, e.g. schema violations like `F3034`. This is the workaround for the CDK behavior where all built-in findings are downgraded to warnings. |
@@ -33,14 +33,17 @@ public readonly enforce: boolean;
33
33
  ```
34
34
 
35
35
  - *Type:* boolean
36
- - *Default:* false
36
+ - *Default:* true
37
37
 
38
- Fail synthesis (instead of reporting warnings) when a bundled rule is violated.
38
+ Fail synthesis when a bundled rule is violated.
39
39
 
40
- In the default (warn) mode, findings are reported through the CDK built-in
41
- CloudFormation validator and surface as synth warnings with construct traces.
42
- With `enforce: true`, cdk-preflight evaluates its rules with its own
43
- validation plugin and a violation makes `cdk synth` fail.
40
+ In the default (enforce) mode, cdk-preflight evaluates its rules with its
41
+ own validation plugin and a violation makes `cdk synth` fail the whole
42
+ point of preflight checks is that a template known to fail at deploy time
43
+ never leaves your machine. Set `enforce: false` to observe first: findings
44
+ are then reported through the CDK built-in CloudFormation validator and
45
+ surface as synth warnings with construct traces, which can be muted per
46
+ finding via `Acknowledge with 'CloudFormation-Validate::<rule-id>'`.
44
47
 
45
48
  ---
46
49
 
@@ -83,7 +86,7 @@ public readonly strict: boolean;
83
86
 
84
87
  In enforce mode, additionally fail synthesis on error-class findings (severity ERROR/FATAL) of the built-in validation engine itself, e.g. schema violations like `F3034`. This is the workaround for the CDK behavior where all built-in findings are downgraded to warnings.
85
88
 
86
- Only effective together with `enforce: true`.
89
+ Only effective in enforce mode (the default).
87
90
 
88
91
  ---
89
92
 
package/README.md CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  Some 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.
6
6
 
7
- cdk-preflight is a curated [Rego rule pack](docs/rules.md) for exactly those constraints. It injects the rules into the AWS CDK built-in CloudFormation validator (`aws-cdk-lib` >= 2.267.0), so violations surface at synth with construct-level traces before you deploy.
7
+ cdk-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.
8
8
 
9
9
  Every bundled rule is backed by a `fail`/`pass` template pair, and the failure has been reproduced against real AWS (or is explicitly marked `doc-only`). Rules that the built-in validation engine already covers are deliberately **not** duplicated — a test suite enforces this.
10
10
 
@@ -24,30 +24,37 @@ const app = new App();
24
24
  Preflight.apply(app);
25
25
  ```
26
26
 
27
- `cdk synth` then reports violations like:
27
+ On violation, `cdk synth` fails with one error per finding, including the construct trace:
28
28
 
29
29
  ```text
30
- WARNING idle_timeout.timeout_seconds is 5000 but must be between 1 and 4000 seconds (CloudFormation Validate)
31
- MyStack/Alb (Alb) aws-cdk-lib.aws_elasticloadbalancingv2.CfnLoadBalancer
32
- Acknowledge with 'CloudFormation-Validate::pf-elbv2-lb-idle-timeout-range'
30
+ ERROR idle_timeout.timeout_seconds is 5000 but must be between 1 and 4000 seconds (cdk-preflight)
31
+ MyStack/Alb/Resource (Alb16C2F182) aws-cdk-lib.aws_elasticloadbalancingv2.CfnLoadBalancer
32
+
33
+ Synthesis finished with errors
33
34
  ```
34
35
 
35
- ## Failing the build
36
+ ## Observe-only mode
36
37
 
37
- By default findings are warnings (matching the CDK built-in validator behavior). To make violations fail `cdk synth`:
38
+ To 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:
38
39
 
39
40
  ```ts
40
- Preflight.apply(app, { enforce: true });
41
+ Preflight.apply(app, { enforce: false });
42
+ ```
43
+
44
+ ```text
45
+ WARNING idle_timeout.timeout_seconds is 5000 but must be between 1 and 4000 seconds (CloudFormation Validate)
46
+ MyStack/Alb (Alb) aws-cdk-lib.aws_elasticloadbalancingv2.CfnLoadBalancer
47
+ Acknowledge with 'CloudFormation-Validate::pf-elbv2-lb-idle-timeout-range'
41
48
  ```
42
49
 
43
50
  | Option | Default | Effect |
44
51
  |---|---|---|
45
- | `enforce` | `false` | Violations of bundled rules fail synthesis instead of warning |
52
+ | `enforce` | `true` | Violations of bundled rules fail synthesis; set to `false` to only warn |
46
53
  | `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 |
47
54
  | `exclude` | `[]` | Rule ids to disable |
48
55
  | `includeUpstreamPending` | `true` | Include rules already proposed to the upstream engine but not yet merged |
49
56
 
50
- Individual findings can also be suppressed with the CDK acknowledge mechanism shown in the warning text.
57
+ To opt out of a single rule, pass its id in `exclude`. In observe-only mode, individual findings can also be suppressed with the CDK acknowledge mechanism shown in the warning text.
51
58
 
52
59
  ## Bundled rules
53
60
 
@@ -56,7 +63,7 @@ See [docs/rules.md](docs/rules.md) for the generated rule table. Highlights:
56
63
  - **ELBv2**: `idle_timeout` / `deregistration_delay` / `slow_start` attribute ranges (stringly-typed Key/Value attributes are invisible to schema validation)
57
64
  - **IAM**: managed (6,144 chars) and inline (role/group/user) policy document size limits
58
65
  - **CloudFront**: `MinTTL <= DefaultTTL <= MaxTTL` ordering, ACM certificates must live in `us-east-1`
59
- - **Step Functions**: `StartAt`/`Next`/`Default`/`Choices` must reference defined states
66
+ - **Step Functions**: `Next`/`Default`/`Choices` must reference defined states (a dangling `StartAt` is already caught by the engine's built-in `E3601`)
60
67
  - **EC2**: security group TCP/UDP port ranges and `FromPort <= ToPort`
61
68
 
62
69
  ## For AI agents
@@ -65,14 +72,14 @@ To add cdk-preflight to a CDK app:
65
72
 
66
73
  1. `npm i -D cdk-preflight`
67
74
  2. `npx cdk-preflight init` (finds the entry point via `cdk.json` and inserts `Preflight.apply(app)`; use `--dry-run` to preview)
68
- 3. Run `cdk synth` and read the warnings; each carries a rule id, a suggested fix, and a construct trace
69
- 4. If the user wants synthesis to fail on violations, change the call to `Preflight.apply(app, { enforce: true })`
75
+ 3. Run `cdk synth`. Violations fail the synth with a validation report; each finding carries a rule id, the actual value, and a suggested fix
76
+ 4. 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
70
77
 
71
78
  The machine-readable findings are written to `cdk.out/validation-report.json` when synthesizing with `-c @aws-cdk/core:validationReportJson=true`.
72
79
 
73
80
  ## How it works
74
81
 
75
- `Preflight.apply()` registers the rules with the CDK built-in `CloudFormationValidatePlugin` (the [cloudformation-validate](https://github.com/aws-cloudformation/cloudformation-validate) Rust/WASM engine that ships inside `aws-cdk-lib`). No extra binaries, no network access at synth time. In `enforce` mode the same engine is invoked through a dedicated validation plugin so that violations fail synthesis.
82
+ `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, no network access at synth time. 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.
76
83
 
77
84
  Constraints that *can* be expressed in schemas or generic engine rules are contributed upstream instead of living here; each rule's `meta.yaml` tracks its upstream status, and rules retire once the engine covers them.
78
85
 
package/docs/rules.md CHANGED
@@ -4,12 +4,23 @@
4
4
 
5
5
  | Rule | Resource types | Constraint | Upstream status |
6
6
  |---|---|---|---|
7
+ | `pf-agentcore-gateway-jwt-authorizer` | AWS::BedrockAgentCore::Gateway | Gateways with AuthorizerType CUSTOM_JWT require AuthorizerConfiguration | none |
8
+ | `pf-agentcore-runtime-name` | AWS::BedrockAgentCore::Runtime | AgentCore Runtime names must match [a-zA-Z][a-zA-Z0-9_]{0,47} (no hyphens) | pending-engine |
7
9
  | `pf-cloudfront-acm-cert-region` | AWS::CloudFront::Distribution | CloudFront viewer certificates must live in us-east-1 | none |
8
10
  | `pf-cloudfront-ttl-order` | AWS::CloudFront::Distribution | Cache behavior TTLs must satisfy MinTTL <= DefaultTTL <= MaxTTL | none |
11
+ | `pf-dynamodb-billing-throughput` | AWS::DynamoDB::Table | ProvisionedThroughput must match BillingMode (required for PROVISIONED, forbidden for PAY_PER_REQUEST) | none |
9
12
  | `pf-ec2-sg-port-range` | AWS::EC2::SecurityGroup<br>AWS::EC2::SecurityGroupIngress<br>AWS::EC2::SecurityGroupEgress | Security group TCP/UDP ports must be within 0-65535 and FromPort <= ToPort | none |
13
+ | `pf-ec2-userdata-size` | AWS::EC2::Instance<br>AWS::EC2::LaunchTemplate | EC2 user data is limited to 16384 bytes | none |
14
+ | `pf-ec2-volume-iops` | AWS::EC2::Volume | EBS Iops/Throughput must match the volume type's supported ranges and ratios | none |
15
+ | `pf-ecs-fargate-network-mode` | AWS::ECS::TaskDefinition | Fargate task definitions require NetworkMode 'awsvpc' | none |
10
16
  | `pf-elbv2-lb-idle-timeout-range` | AWS::ElasticLoadBalancingV2::LoadBalancer | ALB idle_timeout.timeout_seconds must be between 1 and 4000 | none |
11
17
  | `pf-elbv2-tg-deregistration-delay-range` | AWS::ElasticLoadBalancingV2::TargetGroup | Target group deregistration_delay.timeout_seconds must be between 0 and 3600 | none |
12
18
  | `pf-elbv2-tg-slow-start-range` | AWS::ElasticLoadBalancingV2::TargetGroup | Target group slow_start.duration_seconds must be 0 or between 30 and 900 | none |
13
19
  | `pf-iam-inline-policy-size` | AWS::IAM::Policy<br>AWS::IAM::RolePolicy<br>AWS::IAM::UserPolicy<br>AWS::IAM::GroupPolicy | Inline policy documents are limited per identity (role 10240 / group 5120 / user 2048 characters) | none |
20
+ | `pf-iam-managed-policy-count` | AWS::IAM::Role<br>AWS::IAM::User<br>AWS::IAM::Group | Managed policies per identity are capped (hard maximums role 25 / user 20 / group 10) | none |
14
21
  | `pf-iam-managed-policy-size` | AWS::IAM::ManagedPolicy | Managed policy documents are limited to 6144 characters (whitespace excluded) | none |
15
- | `pf-sfn-asl-missing-state` | AWS::StepFunctions::StateMachine | ASL StartAt/Next/Default/Choices must reference a defined state (top-level states) | none |
22
+ | `pf-lambda-env-size` | AWS::Lambda::Function | Lambda environment variables are limited to 4096 bytes in total | none |
23
+ | `pf-s3-lifecycle-days-order` | AWS::S3::Bucket | Lifecycle archive transitions must come 30+ days after IA, and expiration after every transition | none |
24
+ | `pf-s3-replication-requires-versioning` | AWS::S3::Bucket | ReplicationConfiguration requires versioning to be enabled on the source bucket | none |
25
+ | `pf-sns-fifo-topic-name` | AWS::SNS::Topic | FIFO topic names must end with '.fifo' (and '.fifo' names require FifoTopic) | none |
26
+ | `pf-sfn-asl-missing-state` | AWS::StepFunctions::StateMachine | ASL Next/Default/Choices must reference a defined state (top-level states; a dangling StartAt is covered by engine rule E3601) | none |
package/lib/cli.js CHANGED
@@ -109,8 +109,8 @@ function runCli(args) {
109
109
  '',
110
110
  'Next steps:',
111
111
  ' 1. npm i -D cdk-preflight (if not installed yet)',
112
- ' 2. cdk synth (violations appear as warnings with construct traces)',
113
- ' 3. Optional: Preflight.apply(app, { enforce: true }) to fail synth on violations',
112
+ ' 2. cdk synth (violations fail the synth with a validation report)',
113
+ ' 3. Optional: Preflight.apply(app, { enforce: false }) to only warn instead of failing',
114
114
  ].join('\n'));
115
115
  return 0;
116
116
  }
@@ -118,4 +118,4 @@ function runCli(args) {
118
118
  if (require.main === module) {
119
119
  process.exit(runCli(process.argv.slice(2)));
120
120
  }
121
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xpLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL2NsaS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFtQkEsd0JBa0VDO0FBcEZEOzs7R0FHRztBQUNILHVDQUF5QjtBQUN6QiwyQ0FBNkI7QUFFN0IsK0JBQStCO0FBRS9CLE1BQU0sS0FBSyxHQUFHO0lBQ1osc0RBQXNEO0lBQ3RELEVBQUU7SUFDRixpRkFBaUY7Q0FDbEYsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7QUFFYjs7R0FFRztBQUNILFNBQWdCLE1BQU0sQ0FBQyxJQUFjO0lBQ25DLE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUNwQixJQUFJLEdBQUcsS0FBSyxTQUFTLElBQUksR0FBRyxLQUFLLFFBQVEsSUFBSSxHQUFHLEtBQUssSUFBSSxFQUFFLENBQUM7UUFDMUQsT0FBTyxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUNuQixPQUFPLENBQUMsQ0FBQztJQUNYLENBQUM7SUFDRCxJQUFJLEdBQUcsS0FBSyxNQUFNLEVBQUUsQ0FBQztRQUNuQixPQUFPLENBQUMsS0FBSyxDQUFDLG1DQUFtQyxHQUFHLFFBQVEsS0FBSyxFQUFFLENBQUMsQ0FBQztRQUNyRSxPQUFPLENBQUMsQ0FBQztJQUNYLENBQUM7SUFDRCxNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLFdBQVcsQ0FBQyxDQUFDO0lBQ3ZDLE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDckMsTUFBTSxHQUFHLEdBQUcsTUFBTSxJQUFJLENBQUMsSUFBSSxJQUFJLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLENBQUMs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RixvRkFBb0Y7S0FDckYsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQztJQUNkLE9BQU8sQ0FBQyxDQUFDO0FBQ1gsQ0FBQztBQUVELDBCQUEwQjtBQUMxQixJQUFJLE9BQU8sQ0FBQyxJQUFJLEtBQUssTUFBTSxFQUFFLENBQUM7SUFDNUIsT0FBTyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQzlDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIjIS91c3IvYmluL2VudiBub2RlXG4vKipcbiAqIGBucHggY2RrLXByZWZsaWdodCBpbml0YCDigJQg5pei5a2YIENESyDjgqLjg5fjg6rjgasgUHJlZmxpZ2h0LmFwcGx5KGFwcCkg44KS5oy/5YWl44GZ44KLIGNvZGVtb2TjgIJcbiAqIOS6uumWk+OBq+OCgiBBSSDjgqjjg7zjgrjjgqfjg7Pjg4jjgavjgoLlkIzjgZjlhaXlj6PjgpLmj5DkvpvjgZnjgovjgIJcbiAqL1xuaW1wb3J0ICogYXMgZnMgZnJvbSAnZnMnO1xuaW1wb3J0ICogYXMgcGF0aCBmcm9tICdwYXRoJztcblxuLyogZXNsaW50LWRpc2FibGUgbm8tY29uc29sZSAqL1xuXG5jb25zdCBVU0FHRSA9IFtcbiAgJ1VzYWdlOiBjZGstcHJlZmxpZ2h0IGluaXQgWy0tZHJ5LXJ1bl0gWy0tZGlyIDxwYXRoPl0nLFxuICAnJyxcbiAgJ0luc2VydHMgYFByZWZsaWdodC5hcHBseShhcHApYCBpbnRvIHRoZSBDREsgYXBwIGVudHJ5IHBvaW50IGZvdW5kIHZpYSBjZGsuanNvbi4nLFxuXS5qb2luKCdcXG4nKTtcblxuLyoqXG4gKiBDTEkg5pys5L2T44CC44OG44K544OI44GL44KJ55u05o6l5ZG844G544KL44KI44GGIGV4aXQg44Gb44Ga57WC5LqG44Kz44O844OJ44KS6L+U44GZ44CCXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBydW5DbGkoYXJnczogc3RyaW5nW10pOiBudW1iZXIge1xuICBjb25zdCBjbWQgPSBhcmdzWzBdO1xuICBpZiAoY21kID09PSB1bmRlZmluZWQgfHwgY21kID09PSAnLS1oZWxwJyB8fCBjbWQgPT09ICctaCcpIHtcbiAgICBjb25zb2xlLmxvZyhVU0FHRSk7XG4gICAgcmV0dXJuIDA7XG4gIH1cbiAgaWYgKGNtZCAhPT0gJ2luaXQnKSB7XG4gICAgY29uc29sZS5lcnJvcihgY2RrLXByZWZsaWdodDogdW5rbm93biBjb21tYW5kIFwiJHtjbWR9XCJcXG5cXG4ke1VTQUdFfWApO1xuICAgIHJldHVybiAxO1xuICB9XG4gIGNvbnN0IGRyeSA9IGFyZ3MuaW5jbHVkZXMoJy0tZHJ5LXJ1bicpO1xuICBjb25zdCBkaXJJZHggPSBhcmdzLmluZGV4T2YoJy0tZGlyJyk7XG4gIGNvbnN0IGN3ZCA9IGRpcklkeCA+PSAwICYmIGFyZ3NbZGlySWR4ICsgMV0gPyBwYXRoLnJlc29sdmUoYXJnc1tkaXJJZHggKyAxXSkgOiBwcm9jZXNzLmN3ZCgpO1xuXG4gIGNvbnN0IGNka0pzb25QYXRoID0gcGF0aC5qb2luKGN3ZCwgJ2Nkay5qc29uJyk7XG4gIGlmICghZnMuZXhpc3RzU3luYyhjZGtKc29uUGF0aCkpIHtcbiAgICBjb25zb2xlLmVycm9yKGBjZGstcHJlZmxpZ2h0OiBubyBjZGsuanNvbiBmb3VuZCBpbiAke2N3ZH0gKHJ1biBpbnNpZGUgYSBDREsgYXBwLCBvciBwYXNzIC0tZGlyKWApO1xuICAgIHJldHVybiAxO1xuICB9XG4gIGNvbnN0IGFwcENtZDogc3RyaW5nID0gSlNPTi5wYXJzZShmcy5yZWFkRmlsZVN5bmMoY2RrSnNvblBhdGgsICd1dGY4JykpLmFwcCA/PyAnJztcbiAgY29uc3QgZW50cnlNYXRjaCA9IGFwcENtZC5tYXRjaCgvKFxcUytcXC4oPzp0c3xtdHN8Y3RzfGpzfG1qc3xjanMpKVxcYi8pO1xuICBpZiAoIWVudHJ5TWF0Y2gpIHtcbiAgICBjb25zb2xlLmVycm9yKGBjZGstcHJlZmxpZ2h0OiBjb3VsZCBub3QgbG9jYXRlIGFuIGVudHJ5IGZpbGUgaW4gY2RrLmpzb24gXCJhcHBcIjogJHthcHBDbWR9YCk7XG4gICAgcmV0dXJuIDE7XG4gIH1cbiAgY29uc3QgZW50cnkgPSBwYXRoLmpvaW4oY3dkLCBlbnRyeU1hdGNoWzFdKTtcbiAgaWYgKCFmcy5leGlzdHNTeW5jKGVudHJ5KSkge1xuICAgIGNvbnNvbGUuZXJyb3IoYGNkay1wcmVmbGlnaHQ6IGVudHJ5IGZpbGUgbm90IGZvdW5kOiAke2VudHJ5fWApO1xuICAgIHJldHVybiAxO1xuICB9XG5cbiAgY29uc3Qgc3JjID0gZnMucmVhZEZpbGVTeW5jKGVudHJ5LCAndXRmOCcpO1xuICBpZiAoc3JjLmluY2x1ZGVzKCdjZGstcHJlZmxpZ2h0JykpIHtcbiAgICBjb25zb2xlLmxvZyhgY2RrLXByZWZsaWdodDogJHtlbnRyeX0gYWxyZWFkeSByZWZlcmVuY2VzIGNkay1wcmVmbGlnaHQg4oCUIG5vdGhpbmcgdG8gZG9gKTtcbiAgICByZXR1cm4gMDtcbiAgfVxuICBjb25zdCBhcHBMaW5lTWF0Y2ggPSBzcmMubWF0Y2goL14uKlxcYm5ld1xccysoPzpjZGtcXC4pP0FwcFxccypcXChbXjtcXG5dKlxcKVxccyo7P1teXFxTXFxuXSokL20pO1xuICBpZiAoIWFwcExpbmVNYXRjaCkge1xuICAgIGNvbnNvbGUuZXJyb3IoW1xuICAgICAgYGNkay1wcmVmbGlnaHQ6IGNvdWxkIG5vdCBmaW5kIFxcYG5ldyBBcHAoLi4uKVxcYCBpbiAke2VudHJ5fS4gQWRkIG1hbnVhbGx5OmAsXG4gICAgICBcIiAgaW1wb3J0IHsgUHJlZmxpZ2h0IH0gZnJvbSAnY2RrLXByZWZsaWdodCc7XCIsXG4gICAgICAnICBQcmVmbGlnaHQuYXBwbHkoYXBwKTsnLFxuICAgIF0uam9pbignXFxuJykpO1xuICAgIHJldHVybiAxO1xuICB9XG4gIGNvbnN0IGFwcExpbmUgPSBhcHBMaW5lTWF0Y2hbMF07XG4gIGNvbnN0IHZhck1hdGNoID0gYXBwTGluZS5tYXRjaCgvKD86Y29uc3R8bGV0fHZhcilcXHMrKFxcdyspXFxzKj0vKTtcbiAgY29uc3QgYXBwVmFyID0gdmFyTWF0Y2ggPyB2YXJNYXRjaFsxXSA6ICdhcHAnO1xuXG4gIGxldCB1cGRhdGVkID0gc3JjLnJlcGxhY2UoYXBwTGluZSwgYCR7YXBwTGluZX1cXG5QcmVmbGlnaHQuYXBwbHkoJHthcHBWYXJ9KTtgKTtcbiAgdXBkYXRlZCA9IGBpbXBvcnQgeyBQcmVmbGlnaHQgfSBmcm9tICdjZGstcHJlZmxpZ2h0JztcXG4ke3VwZGF0ZWR9YDtcblxuICBpZiAoZHJ5KSB7XG4gICAgY29uc29sZS5sb2coYC0tLSAke2VudHJ5fSAoZHJ5IHJ1bikgLS0tXFxuJHt1cGRhdGVkfWApO1xuICB9IGVsc2Uge1xuICAgIGZzLndyaXRlRmlsZVN5bmMoZW50cnksIHVwZGF0ZWQpO1xuICAgIGNvbnNvbGUubG9nKGBjZGstcHJlZmxpZ2h0OiB1cGRhdGVkICR7ZW50cnl9YCk7XG4gIH1cbiAgY29uc29sZS5sb2coW1xuICAgICcnLFxuICAgICdOZXh0IHN0ZXBzOicsXG4gICAgJyAgMS4gbnBtIGkgLUQgY2RrLXByZWZsaWdodCAgIChpZiBub3QgaW5zdGFsbGVkIHlldCknLFxuICAgICcgIDIuIGNkayBzeW50aCAgICAgICAgICAgICAgICAodmlvbGF0aW9ucyBhcHBlYXIgYXMgd2FybmluZ3Mgd2l0aCBjb25zdHJ1Y3QgdHJhY2VzKScsXG4gICAgJyAgMy4gT3B0aW9uYWw6IFByZWZsaWdodC5hcHBseShhcHAsIHsgZW5mb3JjZTogdHJ1ZSB9KSB0byBmYWlsIHN5bnRoIG9uIHZpb2xhdGlvbnMnLFxuICBdLmpvaW4oJ1xcbicpKTtcbiAgcmV0dXJuIDA7XG59XG5cbi8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG5pZiAocmVxdWlyZS5tYWluID09PSBtb2R1bGUpIHtcbiAgcHJvY2Vzcy5leGl0KHJ1bkNsaShwcm9jZXNzLmFyZ3Yuc2xpY2UoMikpKTtcbn1cbiJdfQ==
121
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xpLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL2NsaS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFtQkEsd0JBa0VDO0FBcEZEOzs7R0FHRztBQUNILHVDQUF5QjtBQUN6QiwyQ0FBNkI7QUFFN0IsK0JBQStCO0FBRS9CLE1BQU0sS0FBSyxHQUFHO0lBQ1osc0RBQXNEO0lBQ3RELEVBQUU7SUFDRixpRkFBaUY7Q0FDbEYsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7QUFFYjs7R0FFRztBQUNILFNBQWdCLE1BQU0sQ0FBQyxJQUFjO0lBQ25DLE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUNwQixJQUFJLEdBQUcsS0FBSyxTQUFTLElBQUksR0FBRyxLQUFLLFFBQVEsSUFBSSxHQUFHLEtBQUssSUFBSSxFQUFFLENBQUM7UUFDMUQsT0FBTyxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUNuQixPQUFPLENBQUMsQ0FBQztJQUNYLENBQUM7SUFDRCxJQUFJLEdBQUcsS0FBSyxNQUFNLEVBQUUsQ0FBQztRQUNuQixPQUFPLENBQUMsS0FBSyxDQUFDLG1DQUFtQyxHQUFHLFFBQVEsS0FBSyxFQUFFLENBQUMsQ0FBQztRQUNyRSxPQUFPLENBQUMsQ0FBQztJQUNYLENBQUM7SUFDRCxNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLFdBQVcsQ0FBQyxDQUFDO0lBQ3ZDLE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDckMsTUFBTSxHQUFHLEdBQUcsTUFBTSxJQUFJLENBQUMsSUFBSSxJQUFJLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLEdBQUcsRUFBRSxDQUFDO0lBRTdGLE1BQU0sV0FBVyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxFQUFFLFVBQVUsQ0FBQyxDQUFDO0lBQy9DLElBQUksQ0FBQyxFQUFFLENBQUMsVUFBVSxDQUFDLFdBQVcsQ0FBQyxFQUFFLENBQUM7UUFDaEMsT0FBTyxDQUFDLEtBQUssQ0FBQyx1Q0FBdUMsR0FBRyx3Q0FBd0MsQ0FBQyxDQUFDO1FBQ2xHLE9BQU8sQ0FBQyxDQUFDO0lBQ1gsQ0FBQztJQUNELE1BQU0sTUFBTSxHQUFXLElBQUksQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLFlBQVksQ0FBQyxXQUFXLEVBQUUsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksRUFBRSxDQUFDO0lBQ2xGLE1BQU0sVUFBVSxHQUFHLE1BQU0sQ0FBQyxLQUFLLENBQUMsb0NBQW9DLENBQUMsQ0FBQztJQUN0RSxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7UUFDaEIsT0FBTyxDQUFDLEtBQUssQ0FBQyxvRUFBb0UsTUFBTSxFQUFFLENBQUMsQ0FBQztRQUM1RixPQUFPLENBQUMsQ0FBQztJQUNYLENBQUM7SUFDRCxNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRSxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUM1QyxJQUFJLENBQUMsRUFBRSxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDO1FBQzFCLE9BQU8sQ0FBQyxLQUFLLENBQUMsd0NBQXdDLEtBQUssRUFBRSxDQUFDLENBQUM7UUFDL0QsT0FBTyxDQUFDLENBQUM7SUFDWCxDQUFDO0lBRUQsTUFBTSxHQUFHLEdBQUcsRUFBRSxDQUFDLFlBQVksQ0FBQyxLQUFLLEVBQUUsTUFBTSxDQUFDLENBQUM7SUFDM0MsSUFBSSxHQUFHLENBQUMsUUFBUSxDQUFDLGVBQWUsQ0FBQyxFQUFFLENBQUM7UUFDbEMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxrQkFBa0IsS0FBSyxtREFBbUQsQ0FBQyxDQUFDO1FBQ3hGLE9BQU8sQ0FBQyxDQUFDO0lBQ1gsQ0FBQztJQUNELE1BQU0sWUFBWSxHQUFHLEdBQUcsQ0FBQyxLQUFLLENBQUMsdURBQXVELENBQUMsQ0FBQztJQUN4RixJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7UUFDbEIsT0FBTyxDQUFDLEtBQUssQ0FBQztZQUNaLHFEQUFxRCxLQUFLLGlCQUFpQjtZQUMzRSw4Q0FBOEM7WUFDOUMseUJBQXlCO1NBQzFCLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7UUFDZCxPQUFPLENBQUMsQ0FBQztJQUNYLENBQUM7SUFDRCxNQUFNLE9BQU8sR0FBRyxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDaEMsTUFBTSxRQUFRLEdBQUcsT0FBTyxDQUFDLEtBQUssQ0FBQywrQkFBK0IsQ0FBQyxDQUFDO0lBQ2hFLE1BQU0sTUFBTSxHQUFHLFFBQVEsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUM7SUFFOUMsSUFBSSxPQUFPLEdBQUcsR0FBRyxDQUFDLE9BQU8sQ0FBQyxPQUFPLEVBQUUsR0FBRyxPQUFPLHFCQUFxQixNQUFNLElBQUksQ0FBQyxDQUFDO0lBQzlFLE9BQU8sR0FBRywrQ0FBK0MsT0FBTyxFQUFFLENBQUM7SUFFbkUsSUFBSSxHQUFHLEVBQUUsQ0FBQztRQUNSLE9BQU8sQ0FBQyxHQUFHLENBQUMsT0FBTyxLQUFLLG1CQUFtQixPQUFPLEVBQUUsQ0FBQyxDQUFDO0lBQ3hELENBQUM7U0FBTSxDQUFDO1FBQ04sRUFBRSxDQUFDLGFBQWEsQ0FBQyxLQUFLLEVBQUUsT0FBTyxDQUFDLENBQUM7UUFDakMsT0FBTyxDQUFDLEdBQUcsQ0FBQywwQkFBMEIsS0FBSyxFQUFFLENBQUMsQ0FBQztJQUNqRCxDQUFDO0lBQ0QsT0FBTyxDQUFDLEdBQUcsQ0FBQztRQUNWLEVBQUU7UUFDRixhQUFhO1FBQ2Isc0RBQXNEO1FBQ3RELG9GQUFvRjtRQUNwRix5RkFBeUY7S0FDMUYsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQztJQUNkLE9BQU8sQ0FBQyxDQUFDO0FBQ1gsQ0FBQztBQUVELDBCQUEwQjtBQUMxQixJQUFJLE9BQU8sQ0FBQyxJQUFJLEtBQUssTUFBTSxFQUFFLENBQUM7SUFDNUIsT0FBTyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQzlDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIjIS91c3IvYmluL2VudiBub2RlXG4vKipcbiAqIGBucHggY2RrLXByZWZsaWdodCBpbml0YCDigJQg5pei5a2YIENESyDjgqLjg5fjg6rjgasgUHJlZmxpZ2h0LmFwcGx5KGFwcCkg44KS5oy/5YWl44GZ44KLIGNvZGVtb2TjgIJcbiAqIOS6uumWk+OBq+OCgiBBSSDjgqjjg7zjgrjjgqfjg7Pjg4jjgavjgoLlkIzjgZjlhaXlj6PjgpLmj5DkvpvjgZnjgovjgIJcbiAqL1xuaW1wb3J0ICogYXMgZnMgZnJvbSAnZnMnO1xuaW1wb3J0ICogYXMgcGF0aCBmcm9tICdwYXRoJztcblxuLyogZXNsaW50LWRpc2FibGUgbm8tY29uc29sZSAqL1xuXG5jb25zdCBVU0FHRSA9IFtcbiAgJ1VzYWdlOiBjZGstcHJlZmxpZ2h0IGluaXQgWy0tZHJ5LXJ1bl0gWy0tZGlyIDxwYXRoPl0nLFxuICAnJyxcbiAgJ0luc2VydHMgYFByZWZsaWdodC5hcHBseShhcHApYCBpbnRvIHRoZSBDREsgYXBwIGVudHJ5IHBvaW50IGZvdW5kIHZpYSBjZGsuanNvbi4nLFxuXS5qb2luKCdcXG4nKTtcblxuLyoqXG4gKiBDTEkg5pys5L2T44CC44OG44K544OI44GL44KJ55u05o6l5ZG844G544KL44KI44GGIGV4aXQg44Gb44Ga57WC5LqG44Kz44O844OJ44KS6L+U44GZ44CCXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBydW5DbGkoYXJnczogc3RyaW5nW10pOiBudW1iZXIge1xuICBjb25zdCBjbWQgPSBhcmdzWzBdO1xuICBpZiAoY21kID09PSB1bmRlZmluZWQgfHwgY21kID09PSAnLS1oZWxwJyB8fCBjbWQgPT09ICctaCcpIHtcbiAgICBjb25zb2xlLmxvZyhVU0FHRSk7XG4gICAgcmV0dXJuIDA7XG4gIH1cbiAgaWYgKGNtZCAhPT0gJ2luaXQnKSB7XG4gICAgY29uc29sZS5lcnJvcihgY2RrLXByZWZsaWdodDogdW5rbm93biBjb21tYW5kIFwiJHtjbWR9XCJcXG5cXG4ke1VTQUdFfWApO1xuICAgIHJldHVybiAxO1xuICB9XG4gIGNvbnN0IGRyeSA9IGFyZ3MuaW5jbHVkZXMoJy0tZHJ5LXJ1bicpO1xuICBjb25zdCBkaXJJZHggPSBhcmdzLmluZGV4T2YoJy0tZGlyJyk7XG4gIGNvbnN0IGN3ZCA9IGRpcklkeCA+PSAwICYmIGFyZ3NbZGlySWR4ICsgMV0gPyBwYXRoLnJlc29sdmUoYXJnc1tkaXJJZHggKyAxXSkgOiBwcm9jZXNzLmN3ZCgpO1xuXG4gIGNvbnN0IGNka0pzb25QYXRoID0gcGF0aC5qb2luKGN3ZCwgJ2Nkay5qc29uJyk7XG4gIGlmICghZnMuZXhpc3RzU3luYyhjZGtKc29uUGF0aCkpIHtcbiAgICBjb25zb2xlLmVycm9yKGBjZGstcHJlZmxpZ2h0OiBubyBjZGsuanNvbiBmb3VuZCBpbiAke2N3ZH0gKHJ1biBpbnNpZGUgYSBDREsgYXBwLCBvciBwYXNzIC0tZGlyKWApO1xuICAgIHJldHVybiAxO1xuICB9XG4gIGNvbnN0IGFwcENtZDogc3RyaW5nID0gSlNPTi5wYXJzZShmcy5yZWFkRmlsZVN5bmMoY2RrSnNvblBhdGgsICd1dGY4JykpLmFwcCA/PyAnJztcbiAgY29uc3QgZW50cnlNYXRjaCA9IGFwcENtZC5tYXRjaCgvKFxcUytcXC4oPzp0c3xtdHN8Y3RzfGpzfG1qc3xjanMpKVxcYi8pO1xuICBpZiAoIWVudHJ5TWF0Y2gpIHtcbiAgICBjb25zb2xlLmVycm9yKGBjZGstcHJlZmxpZ2h0OiBjb3VsZCBub3QgbG9jYXRlIGFuIGVudHJ5IGZpbGUgaW4gY2RrLmpzb24gXCJhcHBcIjogJHthcHBDbWR9YCk7XG4gICAgcmV0dXJuIDE7XG4gIH1cbiAgY29uc3QgZW50cnkgPSBwYXRoLmpvaW4oY3dkLCBlbnRyeU1hdGNoWzFdKTtcbiAgaWYgKCFmcy5leGlzdHNTeW5jKGVudHJ5KSkge1xuICAgIGNvbnNvbGUuZXJyb3IoYGNkay1wcmVmbGlnaHQ6IGVudHJ5IGZpbGUgbm90IGZvdW5kOiAke2VudHJ5fWApO1xuICAgIHJldHVybiAxO1xuICB9XG5cbiAgY29uc3Qgc3JjID0gZnMucmVhZEZpbGVTeW5jKGVudHJ5LCAndXRmOCcpO1xuICBpZiAoc3JjLmluY2x1ZGVzKCdjZGstcHJlZmxpZ2h0JykpIHtcbiAgICBjb25zb2xlLmxvZyhgY2RrLXByZWZsaWdodDogJHtlbnRyeX0gYWxyZWFkeSByZWZlcmVuY2VzIGNkay1wcmVmbGlnaHQg4oCUIG5vdGhpbmcgdG8gZG9gKTtcbiAgICByZXR1cm4gMDtcbiAgfVxuICBjb25zdCBhcHBMaW5lTWF0Y2ggPSBzcmMubWF0Y2goL14uKlxcYm5ld1xccysoPzpjZGtcXC4pP0FwcFxccypcXChbXjtcXG5dKlxcKVxccyo7P1teXFxTXFxuXSokL20pO1xuICBpZiAoIWFwcExpbmVNYXRjaCkge1xuICAgIGNvbnNvbGUuZXJyb3IoW1xuICAgICAgYGNkay1wcmVmbGlnaHQ6IGNvdWxkIG5vdCBmaW5kIFxcYG5ldyBBcHAoLi4uKVxcYCBpbiAke2VudHJ5fS4gQWRkIG1hbnVhbGx5OmAsXG4gICAgICBcIiAgaW1wb3J0IHsgUHJlZmxpZ2h0IH0gZnJvbSAnY2RrLXByZWZsaWdodCc7XCIsXG4gICAgICAnICBQcmVmbGlnaHQuYXBwbHkoYXBwKTsnLFxuICAgIF0uam9pbignXFxuJykpO1xuICAgIHJldHVybiAxO1xuICB9XG4gIGNvbnN0IGFwcExpbmUgPSBhcHBMaW5lTWF0Y2hbMF07XG4gIGNvbnN0IHZhck1hdGNoID0gYXBwTGluZS5tYXRjaCgvKD86Y29uc3R8bGV0fHZhcilcXHMrKFxcdyspXFxzKj0vKTtcbiAgY29uc3QgYXBwVmFyID0gdmFyTWF0Y2ggPyB2YXJNYXRjaFsxXSA6ICdhcHAnO1xuXG4gIGxldCB1cGRhdGVkID0gc3JjLnJlcGxhY2UoYXBwTGluZSwgYCR7YXBwTGluZX1cXG5QcmVmbGlnaHQuYXBwbHkoJHthcHBWYXJ9KTtgKTtcbiAgdXBkYXRlZCA9IGBpbXBvcnQgeyBQcmVmbGlnaHQgfSBmcm9tICdjZGstcHJlZmxpZ2h0JztcXG4ke3VwZGF0ZWR9YDtcblxuICBpZiAoZHJ5KSB7XG4gICAgY29uc29sZS5sb2coYC0tLSAke2VudHJ5fSAoZHJ5IHJ1bikgLS0tXFxuJHt1cGRhdGVkfWApO1xuICB9IGVsc2Uge1xuICAgIGZzLndyaXRlRmlsZVN5bmMoZW50cnksIHVwZGF0ZWQpO1xuICAgIGNvbnNvbGUubG9nKGBjZGstcHJlZmxpZ2h0OiB1cGRhdGVkICR7ZW50cnl9YCk7XG4gIH1cbiAgY29uc29sZS5sb2coW1xuICAgICcnLFxuICAgICdOZXh0IHN0ZXBzOicsXG4gICAgJyAgMS4gbnBtIGkgLUQgY2RrLXByZWZsaWdodCAgIChpZiBub3QgaW5zdGFsbGVkIHlldCknLFxuICAgICcgIDIuIGNkayBzeW50aCAgICAgICAgICAgICAgICAodmlvbGF0aW9ucyBmYWlsIHRoZSBzeW50aCB3aXRoIGEgdmFsaWRhdGlvbiByZXBvcnQpJyxcbiAgICAnICAzLiBPcHRpb25hbDogUHJlZmxpZ2h0LmFwcGx5KGFwcCwgeyBlbmZvcmNlOiBmYWxzZSB9KSB0byBvbmx5IHdhcm4gaW5zdGVhZCBvZiBmYWlsaW5nJyxcbiAgXS5qb2luKCdcXG4nKSk7XG4gIHJldHVybiAwO1xufVxuXG4vKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuaWYgKHJlcXVpcmUubWFpbiA9PT0gbW9kdWxlKSB7XG4gIHByb2Nlc3MuZXhpdChydW5DbGkocHJvY2Vzcy5hcmd2LnNsaWNlKDIpKSk7XG59XG4iXX0=
package/lib/index.d.ts CHANGED
@@ -10,14 +10,17 @@ export interface PreflightOptions {
10
10
  */
11
11
  readonly exclude?: string[];
12
12
  /**
13
- * Fail synthesis (instead of reporting warnings) when a bundled rule is violated.
13
+ * Fail synthesis when a bundled rule is violated.
14
14
  *
15
- * In the default (warn) mode, findings are reported through the CDK built-in
16
- * CloudFormation validator and surface as synth warnings with construct traces.
17
- * With `enforce: true`, cdk-preflight evaluates its rules with its own
18
- * validation plugin and a violation makes `cdk synth` fail.
15
+ * In the default (enforce) mode, cdk-preflight evaluates its rules with its
16
+ * own validation plugin and a violation makes `cdk synth` fail the whole
17
+ * point of preflight checks is that a template known to fail at deploy time
18
+ * never leaves your machine. Set `enforce: false` to observe first: findings
19
+ * are then reported through the CDK built-in CloudFormation validator and
20
+ * surface as synth warnings with construct traces, which can be muted per
21
+ * finding via `Acknowledge with 'CloudFormation-Validate::<rule-id>'`.
19
22
  *
20
- * @default false
23
+ * @default true
21
24
  */
22
25
  readonly enforce?: boolean;
23
26
  /**
@@ -26,7 +29,7 @@ export interface PreflightOptions {
26
29
  * schema violations like `F3034`. This is the workaround for the CDK
27
30
  * behavior where all built-in findings are downgraded to warnings.
28
31
  *
29
- * Only effective together with `enforce: true`.
32
+ * Only effective in enforce mode (the default).
30
33
  *
31
34
  * @default false
32
35
  */
package/lib/index.js CHANGED
@@ -17,7 +17,7 @@ const rules_generated_1 = require("./rules.generated");
17
17
  * Preflight.apply(app);
18
18
  */
19
19
  class Preflight {
20
- static [JSII_RTTI_SYMBOL_1] = { fqn: "cdk-preflight.Preflight", version: "0.0.0" };
20
+ static [JSII_RTTI_SYMBOL_1] = { fqn: "cdk-preflight.Preflight", version: "0.0.2" };
21
21
  /**
22
22
  * Register the cdk-preflight rules on an App or Stage.
23
23
  */
@@ -33,7 +33,7 @@ class Preflight {
33
33
  const selected = rules_generated_1.BUNDLED_RULES
34
34
  .filter((r) => (options.includeUpstreamPending ?? true) || r.upstream !== 'pending-engine')
35
35
  .filter((r) => !exclude.includes(r.id));
36
- if (options.enforce ?? false) {
36
+ if (options.enforce ?? true) {
37
37
  aws_cdk_lib_1.Validations.of(scope).addPlugins(new enforce_1.PreflightEnforcePlugin(selected, options.strict ?? false));
38
38
  }
39
39
  else {
@@ -51,4 +51,4 @@ class Preflight {
51
51
  constructor() { }
52
52
  }
53
53
  exports.Preflight = Preflight;
54
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7OztBQUFBLDZDQUErRTtBQUUvRSwrQ0FBMkQ7QUFDM0QsdURBQWtEO0FBK0NsRDs7Ozs7Ozs7OztHQVVHO0FBQ0gsTUFBYSxTQUFTOztJQUNwQjs7T0FFRztJQUNJLE1BQU0sQ0FBQyxLQUFLLENBQUMsS0FBaUIsRUFBRSxVQUE0QixFQUFFO1FBQ25FLElBQUksQ0FBQyxtQkFBSyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDO1lBQzFCLE1BQU0sSUFBSSxLQUFLLENBQUMsc0VBQXNFLENBQUMsQ0FBQztRQUMxRixDQUFDO1FBQ0QsTUFBTSxPQUFPLEdBQUcsT0FBTyxDQUFDLE9BQU8sSUFBSSxFQUFFLENBQUM7UUFDdEMsTUFBTSxPQUFPLEdBQUcsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQywrQkFBYSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsS0FBSyxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQ2hGLElBQUksT0FBTyxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQztZQUN2QixNQUFNLElBQUksS0FBSyxDQUFDLGlEQUFpRCxPQUFPLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUN6RixDQUFDO1FBQ0QsTUFBTSxRQUFRLEdBQUcsK0JBQWE7YUFDM0IsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxzQkFBc0IsSUFBSSxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsUUFBUSxLQUFLLGdCQUFnQixDQUFDO2FBQzFGLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBRTFDLElBQUksT0FBTyxDQUFDLE9BQU8sSUFBSSxLQUFLLEVBQUUsQ0FBQztZQUM3Qix5QkFBVyxDQUFDLEVBQUUsQ0FBQyxLQUFLLENBQUMsQ0FBQyxVQUFVLENBQUMsSUFBSSxnQ0FBc0IsQ0FBQyxRQUFRLEVBQUUsT0FBTyxDQUFDLE1BQU0sSUFBSSxLQUFLLENBQUMsQ0FBQyxDQUFDO1FBQ2xHLENBQUM7YUFBTSxDQUFDO1lBQ04seUJBQVcsQ0FBQyxFQUFFLENBQUMsS0FBSyxDQUFDLENBQUMsVUFBVSxDQUFDLElBQUksMENBQTRCLENBQUM7Z0JBQ2hFLFNBQVMsRUFBRSxRQUFRLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQyxFQUFFLEVBQUUsT0FBTyxFQUFFLENBQUMsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDO2FBQ2xFLENBQUMsQ0FBQyxDQUFDO1FBQ04sQ0FBQztJQUNILENBQUM7SUFFRDs7T0FFRztJQUNJLE1BQU0sQ0FBQyxPQUFPO1FBQ25CLE9BQU8sK0JBQWEsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQztJQUN4QyxDQUFDO0lBRUQsZ0JBQXVCLENBQUM7O0FBakMxQiw4QkFrQ0MiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDbG91ZEZvcm1hdGlvblZhbGlkYXRlUGx1Z2luLCBTdGFnZSwgVmFsaWRhdGlvbnMgfSBmcm9tICdhd3MtY2RrLWxpYic7XG5pbXBvcnQgeyBJQ29uc3RydWN0IH0gZnJvbSAnY29uc3RydWN0cyc7XG5pbXBvcnQgeyBQcmVmbGlnaHRFbmZvcmNlUGx1Z2luIH0gZnJvbSAnLi9wcml2YXRlL2VuZm9yY2UnO1xuaW1wb3J0IHsgQlVORExFRF9SVUxFUyB9IGZyb20gJy4vcnVsZXMuZ2VuZXJhdGVkJztcblxuLyoqXG4gKiBPcHRpb25zIGZvciB7QGxpbmsgUHJlZmxpZ2h0LmFwcGx5fS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBQcmVmbGlnaHRPcHRpb25zIHtcbiAgLyoqXG4gICAqIFJ1bGUgaWRzIHRvIGRpc2FibGUgKHNlZSBgUHJlZmxpZ2h0LnJ1bGVJZHMoKWAgb3IgZG9jcy9ydWxlcy5tZCkuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gYWxsIGJ1bmRsZWQgcnVsZXMgYXJlIGVuYWJsZWRcbiAgICovXG4gIHJlYWRvbmx5IGV4Y2x1ZGU/OiBzdHJpbmdbXTtcblxuICAvKipcbiAgICogRmFpbCBzeW50aGVzaXMgKGluc3RlYWQgb2YgcmVwb3J0aW5nIHdhcm5pbmdzKSB3aGVuIGEgYnVuZGxlZCBydWxlIGlzIHZpb2xhdGVkLlxuICAgKlxuICAgKiBJbiB0aGUgZGVmYXVsdCAod2FybikgbW9kZSwgZmluZGluZ3MgYXJlIHJlcG9ydGVkIHRocm91Z2ggdGhlIENESyBidWlsdC1pblxuICAgKiBDbG91ZEZvcm1hdGlvbiB2YWxpZGF0b3IgYW5kIHN1cmZhY2UgYXMgc3ludGggd2FybmluZ3Mgd2l0aCBjb25zdHJ1Y3QgdHJhY2VzLlxuICAgKiBXaXRoIGBlbmZvcmNlOiB0cnVlYCwgY2RrLXByZWZsaWdodCBldmFsdWF0ZXMgaXRzIHJ1bGVzIHdpdGggaXRzIG93blxuICAgKiB2YWxpZGF0aW9uIHBsdWdpbiBhbmQgYSB2aW9sYXRpb24gbWFrZXMgYGNkayBzeW50aGAgZmFpbC5cbiAgICpcbiAgICogQGRlZmF1bHQgZmFsc2VcbiAgICovXG4gIHJlYWRvbmx5IGVuZm9yY2U/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBJbiBlbmZvcmNlIG1vZGUsIGFkZGl0aW9uYWxseSBmYWlsIHN5bnRoZXNpcyBvbiBlcnJvci1jbGFzcyBmaW5kaW5nc1xuICAgKiAoc2V2ZXJpdHkgRVJST1IvRkFUQUwpIG9mIHRoZSBidWlsdC1pbiB2YWxpZGF0aW9uIGVuZ2luZSBpdHNlbGYsIGUuZy5cbiAgICogc2NoZW1hIHZpb2xhdGlvbnMgbGlrZSBgRjMwMzRgLiBUaGlzIGlzIHRoZSB3b3JrYXJvdW5kIGZvciB0aGUgQ0RLXG4gICAqIGJlaGF2aW9yIHdoZXJlIGFsbCBidWlsdC1pbiBmaW5kaW5ncyBhcmUgZG93bmdyYWRlZCB0byB3YXJuaW5ncy5cbiAgICpcbiAgICogT25seSBlZmZlY3RpdmUgdG9nZXRoZXIgd2l0aCBgZW5mb3JjZTogdHJ1ZWAuXG4gICAqXG4gICAqIEBkZWZhdWx0IGZhbHNlXG4gICAqL1xuICByZWFkb25seSBzdHJpY3Q/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBJbmNsdWRlIHJ1bGVzIHRoYXQgYXJlIG1hcmtlZCBgcGVuZGluZy1lbmdpbmVgIChjYW5kaWRhdGVzIHRoYXQgaGF2ZSBiZWVuXG4gICAqIHByb3Bvc2VkIHRvIHRoZSB1cHN0cmVhbSBjbG91ZGZvcm1hdGlvbi12YWxpZGF0ZSBlbmdpbmUgYnV0IGFyZSBub3QgbWVyZ2VkXG4gICAqIHlldCkuIERpc2FibGUgdGhpcyBpZiB5b3UgcnVuIGEgbmV3ZXIgZW5naW5lIHRoYXQgYWxyZWFkeSBjb3ZlcnMgdGhlbS5cbiAgICpcbiAgICogQGRlZmF1bHQgdHJ1ZVxuICAgKi9cbiAgcmVhZG9ubHkgaW5jbHVkZVVwc3RyZWFtUGVuZGluZz86IGJvb2xlYW47XG59XG5cbi8qKlxuICogY2RrLXByZWZsaWdodDogY2F0Y2ggZGVwbG95LXRpbWUgQ2xvdWRGb3JtYXRpb24gZmFpbHVyZXMgYXQgc3ludGggdGltZS5cbiAqXG4gKiBJbmplY3RzIGEgY3VyYXRlZCBSZWdvIHJ1bGUgcGFjayAoY29uc3RyYWludHMgdGhhdCByZXNvdXJjZSBwcm92aWRlciBzY2hlbWFzXG4gKiBkbyBub3QgZXhwcmVzczogZG9jLW9ubHkgdmFsdWUgbGltaXRzLCBjcm9zcy1wcm9wZXJ0eSBhbmQgY3Jvc3MtcmVzb3VyY2VcbiAqIHJ1bGVzKSBpbnRvIHRoZSBBV1MgQ0RLIGJ1aWx0LWluIENsb3VkRm9ybWF0aW9uIHZhbGlkYXRvci5cbiAqXG4gKiBAZXhhbXBsZVxuICogZGVjbGFyZSBjb25zdCBhcHA6IEFwcDtcbiAqIFByZWZsaWdodC5hcHBseShhcHApO1xuICovXG5leHBvcnQgY2xhc3MgUHJlZmxpZ2h0IHtcbiAgLyoqXG4gICAqIFJlZ2lzdGVyIHRoZSBjZGstcHJlZmxpZ2h0IHJ1bGVzIG9uIGFuIEFwcCBvciBTdGFnZS5cbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgYXBwbHkoc2NvcGU6IElDb25zdHJ1Y3QsIG9wdGlvbnM6IFByZWZsaWdodE9wdGlvbnMgPSB7fSk6IHZvaWQge1xuICAgIGlmICghU3RhZ2UuaXNTdGFnZShzY29wZSkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignY2RrLXByZWZsaWdodDogUHJlZmxpZ2h0LmFwcGx5KCkgbXVzdCBiZSBjYWxsZWQgb24gYW4gQXBwIG9yIGEgU3RhZ2UnKTtcbiAgICB9XG4gICAgY29uc3QgZXhjbHVkZSA9IG9wdGlvbnMuZXhjbHVkZSA/PyBbXTtcbiAgICBjb25zdCB1bmtub3duID0gZXhjbHVkZS5maWx0ZXIoKGlkKSA9PiAhQlVORExFRF9SVUxFUy5zb21lKChyKSA9PiByLmlkID09PSBpZCkpO1xuICAgIGlmICh1bmtub3duLmxlbmd0aCA+IDApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgY2RrLXByZWZsaWdodDogdW5rbm93biBydWxlIGlkKHMpIGluIGV4Y2x1ZGU6ICR7dW5rbm93bi5qb2luKCcsICcpfWApO1xuICAgIH1cbiAgICBjb25zdCBzZWxlY3RlZCA9IEJVTkRMRURfUlVMRVNcbiAgICAgIC5maWx0ZXIoKHIpID0+IChvcHRpb25zLmluY2x1ZGVVcHN0cmVhbVBlbmRpbmcgPz8gdHJ1ZSkgfHwgci51cHN0cmVhbSAhPT0gJ3BlbmRpbmctZW5naW5lJylcbiAgICAgIC5maWx0ZXIoKHIpID0+ICFleGNsdWRlLmluY2x1ZGVzKHIuaWQpKTtcblxuICAgIGlmIChvcHRpb25zLmVuZm9yY2UgPz8gZmFsc2UpIHtcbiAgICAgIFZhbGlkYXRpb25zLm9mKHNjb3BlKS5hZGRQbHVnaW5zKG5ldyBQcmVmbGlnaHRFbmZvcmNlUGx1Z2luKHNlbGVjdGVkLCBvcHRpb25zLnN0cmljdCA/PyBmYWxzZSkpO1xuICAgIH0gZWxzZSB7XG4gICAgICBWYWxpZGF0aW9ucy5vZihzY29wZSkuYWRkUGx1Z2lucyhuZXcgQ2xvdWRGb3JtYXRpb25WYWxpZGF0ZVBsdWdpbih7XG4gICAgICAgIHJlZ29SdWxlczogc2VsZWN0ZWQubWFwKChyKSA9PiAoeyBuYW1lOiByLmlkLCBjb250ZW50OiByLnJlZ28gfSkpLFxuICAgICAgfSkpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBUaGUgaWRzIG9mIGFsbCBidW5kbGVkIHJ1bGVzLlxuICAgKi9cbiAgcHVibGljIHN0YXRpYyBydWxlSWRzKCk6IHN0cmluZ1tdIHtcbiAgICByZXR1cm4gQlVORExFRF9SVUxFUy5tYXAoKHIpID0+IHIuaWQpO1xuICB9XG5cbiAgcHJpdmF0ZSBjb25zdHJ1Y3RvcigpIHt9XG59XG4iXX0=
54
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7OztBQUFBLDZDQUErRTtBQUUvRSwrQ0FBMkQ7QUFDM0QsdURBQWtEO0FBa0RsRDs7Ozs7Ozs7OztHQVVHO0FBQ0gsTUFBYSxTQUFTOztJQUNwQjs7T0FFRztJQUNJLE1BQU0sQ0FBQyxLQUFLLENBQUMsS0FBaUIsRUFBRSxVQUE0QixFQUFFO1FBQ25FLElBQUksQ0FBQyxtQkFBSyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDO1lBQzFCLE1BQU0sSUFBSSxLQUFLLENBQUMsc0VBQXNFLENBQUMsQ0FBQztRQUMxRixDQUFDO1FBQ0QsTUFBTSxPQUFPLEdBQUcsT0FBTyxDQUFDLE9BQU8sSUFBSSxFQUFFLENBQUM7UUFDdEMsTUFBTSxPQUFPLEdBQUcsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQywrQkFBYSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsS0FBSyxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQ2hGLElBQUksT0FBTyxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQztZQUN2QixNQUFNLElBQUksS0FBSyxDQUFDLGlEQUFpRCxPQUFPLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUN6RixDQUFDO1FBQ0QsTUFBTSxRQUFRLEdBQUcsK0JBQWE7YUFDM0IsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxzQkFBc0IsSUFBSSxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsUUFBUSxLQUFLLGdCQUFnQixDQUFDO2FBQzFGLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBRTFDLElBQUksT0FBTyxDQUFDLE9BQU8sSUFBSSxJQUFJLEVBQUUsQ0FBQztZQUM1Qix5QkFBVyxDQUFDLEVBQUUsQ0FBQyxLQUFLLENBQUMsQ0FBQyxVQUFVLENBQUMsSUFBSSxnQ0FBc0IsQ0FBQyxRQUFRLEVBQUUsT0FBTyxDQUFDLE1BQU0sSUFBSSxLQUFLLENBQUMsQ0FBQyxDQUFDO1FBQ2xHLENBQUM7YUFBTSxDQUFDO1lBQ04seUJBQVcsQ0FBQyxFQUFFLENBQUMsS0FBSyxDQUFDLENBQUMsVUFBVSxDQUFDLElBQUksMENBQTRCLENBQUM7Z0JBQ2hFLFNBQVMsRUFBRSxRQUFRLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQyxFQUFFLEVBQUUsT0FBTyxFQUFFLENBQUMsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDO2FBQ2xFLENBQUMsQ0FBQyxDQUFDO1FBQ04sQ0FBQztJQUNILENBQUM7SUFFRDs7T0FFRztJQUNJLE1BQU0sQ0FBQyxPQUFPO1FBQ25CLE9BQU8sK0JBQWEsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQztJQUN4QyxDQUFDO0lBRUQsZ0JBQXVCLENBQUM7O0FBakMxQiw4QkFrQ0MiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDbG91ZEZvcm1hdGlvblZhbGlkYXRlUGx1Z2luLCBTdGFnZSwgVmFsaWRhdGlvbnMgfSBmcm9tICdhd3MtY2RrLWxpYic7XG5pbXBvcnQgeyBJQ29uc3RydWN0IH0gZnJvbSAnY29uc3RydWN0cyc7XG5pbXBvcnQgeyBQcmVmbGlnaHRFbmZvcmNlUGx1Z2luIH0gZnJvbSAnLi9wcml2YXRlL2VuZm9yY2UnO1xuaW1wb3J0IHsgQlVORExFRF9SVUxFUyB9IGZyb20gJy4vcnVsZXMuZ2VuZXJhdGVkJztcblxuLyoqXG4gKiBPcHRpb25zIGZvciB7QGxpbmsgUHJlZmxpZ2h0LmFwcGx5fS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBQcmVmbGlnaHRPcHRpb25zIHtcbiAgLyoqXG4gICAqIFJ1bGUgaWRzIHRvIGRpc2FibGUgKHNlZSBgUHJlZmxpZ2h0LnJ1bGVJZHMoKWAgb3IgZG9jcy9ydWxlcy5tZCkuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gYWxsIGJ1bmRsZWQgcnVsZXMgYXJlIGVuYWJsZWRcbiAgICovXG4gIHJlYWRvbmx5IGV4Y2x1ZGU/OiBzdHJpbmdbXTtcblxuICAvKipcbiAgICogRmFpbCBzeW50aGVzaXMgd2hlbiBhIGJ1bmRsZWQgcnVsZSBpcyB2aW9sYXRlZC5cbiAgICpcbiAgICogSW4gdGhlIGRlZmF1bHQgKGVuZm9yY2UpIG1vZGUsIGNkay1wcmVmbGlnaHQgZXZhbHVhdGVzIGl0cyBydWxlcyB3aXRoIGl0c1xuICAgKiBvd24gdmFsaWRhdGlvbiBwbHVnaW4gYW5kIGEgdmlvbGF0aW9uIG1ha2VzIGBjZGsgc3ludGhgIGZhaWwg4oCUIHRoZSB3aG9sZVxuICAgKiBwb2ludCBvZiBwcmVmbGlnaHQgY2hlY2tzIGlzIHRoYXQgYSB0ZW1wbGF0ZSBrbm93biB0byBmYWlsIGF0IGRlcGxveSB0aW1lXG4gICAqIG5ldmVyIGxlYXZlcyB5b3VyIG1hY2hpbmUuIFNldCBgZW5mb3JjZTogZmFsc2VgIHRvIG9ic2VydmUgZmlyc3Q6IGZpbmRpbmdzXG4gICAqIGFyZSB0aGVuIHJlcG9ydGVkIHRocm91Z2ggdGhlIENESyBidWlsdC1pbiBDbG91ZEZvcm1hdGlvbiB2YWxpZGF0b3IgYW5kXG4gICAqIHN1cmZhY2UgYXMgc3ludGggd2FybmluZ3Mgd2l0aCBjb25zdHJ1Y3QgdHJhY2VzLCB3aGljaCBjYW4gYmUgbXV0ZWQgcGVyXG4gICAqIGZpbmRpbmcgdmlhIGBBY2tub3dsZWRnZSB3aXRoICdDbG91ZEZvcm1hdGlvbi1WYWxpZGF0ZTo6PHJ1bGUtaWQ+J2AuXG4gICAqXG4gICAqIEBkZWZhdWx0IHRydWVcbiAgICovXG4gIHJlYWRvbmx5IGVuZm9yY2U/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBJbiBlbmZvcmNlIG1vZGUsIGFkZGl0aW9uYWxseSBmYWlsIHN5bnRoZXNpcyBvbiBlcnJvci1jbGFzcyBmaW5kaW5nc1xuICAgKiAoc2V2ZXJpdHkgRVJST1IvRkFUQUwpIG9mIHRoZSBidWlsdC1pbiB2YWxpZGF0aW9uIGVuZ2luZSBpdHNlbGYsIGUuZy5cbiAgICogc2NoZW1hIHZpb2xhdGlvbnMgbGlrZSBgRjMwMzRgLiBUaGlzIGlzIHRoZSB3b3JrYXJvdW5kIGZvciB0aGUgQ0RLXG4gICAqIGJlaGF2aW9yIHdoZXJlIGFsbCBidWlsdC1pbiBmaW5kaW5ncyBhcmUgZG93bmdyYWRlZCB0byB3YXJuaW5ncy5cbiAgICpcbiAgICogT25seSBlZmZlY3RpdmUgaW4gZW5mb3JjZSBtb2RlICh0aGUgZGVmYXVsdCkuXG4gICAqXG4gICAqIEBkZWZhdWx0IGZhbHNlXG4gICAqL1xuICByZWFkb25seSBzdHJpY3Q/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBJbmNsdWRlIHJ1bGVzIHRoYXQgYXJlIG1hcmtlZCBgcGVuZGluZy1lbmdpbmVgIChjYW5kaWRhdGVzIHRoYXQgaGF2ZSBiZWVuXG4gICAqIHByb3Bvc2VkIHRvIHRoZSB1cHN0cmVhbSBjbG91ZGZvcm1hdGlvbi12YWxpZGF0ZSBlbmdpbmUgYnV0IGFyZSBub3QgbWVyZ2VkXG4gICAqIHlldCkuIERpc2FibGUgdGhpcyBpZiB5b3UgcnVuIGEgbmV3ZXIgZW5naW5lIHRoYXQgYWxyZWFkeSBjb3ZlcnMgdGhlbS5cbiAgICpcbiAgICogQGRlZmF1bHQgdHJ1ZVxuICAgKi9cbiAgcmVhZG9ubHkgaW5jbHVkZVVwc3RyZWFtUGVuZGluZz86IGJvb2xlYW47XG59XG5cbi8qKlxuICogY2RrLXByZWZsaWdodDogY2F0Y2ggZGVwbG95LXRpbWUgQ2xvdWRGb3JtYXRpb24gZmFpbHVyZXMgYXQgc3ludGggdGltZS5cbiAqXG4gKiBJbmplY3RzIGEgY3VyYXRlZCBSZWdvIHJ1bGUgcGFjayAoY29uc3RyYWludHMgdGhhdCByZXNvdXJjZSBwcm92aWRlciBzY2hlbWFzXG4gKiBkbyBub3QgZXhwcmVzczogZG9jLW9ubHkgdmFsdWUgbGltaXRzLCBjcm9zcy1wcm9wZXJ0eSBhbmQgY3Jvc3MtcmVzb3VyY2VcbiAqIHJ1bGVzKSBpbnRvIHRoZSBBV1MgQ0RLIGJ1aWx0LWluIENsb3VkRm9ybWF0aW9uIHZhbGlkYXRvci5cbiAqXG4gKiBAZXhhbXBsZVxuICogZGVjbGFyZSBjb25zdCBhcHA6IEFwcDtcbiAqIFByZWZsaWdodC5hcHBseShhcHApO1xuICovXG5leHBvcnQgY2xhc3MgUHJlZmxpZ2h0IHtcbiAgLyoqXG4gICAqIFJlZ2lzdGVyIHRoZSBjZGstcHJlZmxpZ2h0IHJ1bGVzIG9uIGFuIEFwcCBvciBTdGFnZS5cbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgYXBwbHkoc2NvcGU6IElDb25zdHJ1Y3QsIG9wdGlvbnM6IFByZWZsaWdodE9wdGlvbnMgPSB7fSk6IHZvaWQge1xuICAgIGlmICghU3RhZ2UuaXNTdGFnZShzY29wZSkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignY2RrLXByZWZsaWdodDogUHJlZmxpZ2h0LmFwcGx5KCkgbXVzdCBiZSBjYWxsZWQgb24gYW4gQXBwIG9yIGEgU3RhZ2UnKTtcbiAgICB9XG4gICAgY29uc3QgZXhjbHVkZSA9IG9wdGlvbnMuZXhjbHVkZSA/PyBbXTtcbiAgICBjb25zdCB1bmtub3duID0gZXhjbHVkZS5maWx0ZXIoKGlkKSA9PiAhQlVORExFRF9SVUxFUy5zb21lKChyKSA9PiByLmlkID09PSBpZCkpO1xuICAgIGlmICh1bmtub3duLmxlbmd0aCA+IDApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgY2RrLXByZWZsaWdodDogdW5rbm93biBydWxlIGlkKHMpIGluIGV4Y2x1ZGU6ICR7dW5rbm93bi5qb2luKCcsICcpfWApO1xuICAgIH1cbiAgICBjb25zdCBzZWxlY3RlZCA9IEJVTkRMRURfUlVMRVNcbiAgICAgIC5maWx0ZXIoKHIpID0+IChvcHRpb25zLmluY2x1ZGVVcHN0cmVhbVBlbmRpbmcgPz8gdHJ1ZSkgfHwgci51cHN0cmVhbSAhPT0gJ3BlbmRpbmctZW5naW5lJylcbiAgICAgIC5maWx0ZXIoKHIpID0+ICFleGNsdWRlLmluY2x1ZGVzKHIuaWQpKTtcblxuICAgIGlmIChvcHRpb25zLmVuZm9yY2UgPz8gdHJ1ZSkge1xuICAgICAgVmFsaWRhdGlvbnMub2Yoc2NvcGUpLmFkZFBsdWdpbnMobmV3IFByZWZsaWdodEVuZm9yY2VQbHVnaW4oc2VsZWN0ZWQsIG9wdGlvbnMuc3RyaWN0ID8/IGZhbHNlKSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIFZhbGlkYXRpb25zLm9mKHNjb3BlKS5hZGRQbHVnaW5zKG5ldyBDbG91ZEZvcm1hdGlvblZhbGlkYXRlUGx1Z2luKHtcbiAgICAgICAgcmVnb1J1bGVzOiBzZWxlY3RlZC5tYXAoKHIpID0+ICh7IG5hbWU6IHIuaWQsIGNvbnRlbnQ6IHIucmVnbyB9KSksXG4gICAgICB9KSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFRoZSBpZHMgb2YgYWxsIGJ1bmRsZWQgcnVsZXMuXG4gICAqL1xuICBwdWJsaWMgc3RhdGljIHJ1bGVJZHMoKTogc3RyaW5nW10ge1xuICAgIHJldHVybiBCVU5ETEVEX1JVTEVTLm1hcCgocikgPT4gci5pZCk7XG4gIH1cblxuICBwcml2YXRlIGNvbnN0cnVjdG9yKCkge31cbn1cbiJdfQ==
@@ -136,4 +136,4 @@ function loadEngine() {
136
136
  return undefined;
137
137
  }
138
138
  }
139
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZW5mb3JjZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9wcml2YXRlL2VuZm9yY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBNkdBLGdDQWVDO0FBNUhELDJDQUE2QjtBQXFCN0I7Ozs7Ozs7R0FPRztBQUNILE1BQWEsc0JBQXNCO0lBSWQ7SUFDQTtJQUpILElBQUksR0FBRyxlQUFlLENBQUM7SUFFdkMsWUFDbUIsS0FBd0IsRUFDeEIsTUFBZTtRQURmLFVBQUssR0FBTCxLQUFLLENBQW1CO1FBQ3hCLFdBQU0sR0FBTixNQUFNLENBQVM7SUFDL0IsQ0FBQztJQUVHLFFBQVEsQ0FBQyxPQUFpQztRQUMvQyxNQUFNLE1BQU0sR0FBRyxnQkFBZ0IsRUFBRSxDQUFDO1FBQ2xDLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztZQUNaLHNDQUFzQztZQUN0QyxPQUFPLENBQUMsS0FBSyxDQUNYLGlFQUFpRTtnQkFDakUsZ0VBQWdFO2dCQUNoRSwrREFBK0QsQ0FDaEUsQ0FBQztZQUNGLE9BQU8sRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLFVBQVUsRUFBRSxFQUFFLEVBQUUsQ0FBQztRQUMzQyxDQUFDO1FBRUQsTUFBTSxHQUFHLEdBQUcsZ0JBQWdCLENBQUMsTUFBTSxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUNqRCxNQUFNLElBQUksR0FBRyxJQUFJLEdBQUcsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDbEQsTUFBTSxVQUFVLEdBQXNCLEVBQUUsQ0FBQztRQUV6QyxLQUFLLE1BQU0sRUFBRSxJQUFJLE9BQU8sQ0FBQyxjQUFjLEVBQUUsQ0FBQztZQUN4QyxNQUFNLE1BQU0sR0FBRyxHQUFHLENBQUMsZ0JBQWdCLENBQUMsSUFB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QUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2xDLENBQUM7QUFFRDs7OztHQUlHO0FBQ0gsU0FBZ0IsVUFBVTtJQUN4QixJQUFJLENBQUM7UUFDSCxPQUFPLE9BQU8sQ0FBQyw4QkFBOEIsQ0FBQyxDQUFDO0lBQ2pELENBQUM7SUFBQyxNQUFNLENBQUM7UUFDUCxlQUFlO0lBQ2pCLENBQUM7SUFDRCxJQUFJLENBQUM7UUFDSCxNQUFNLE1BQU0sR0FBRyxPQUFPLENBQUMsT0FBTyxDQUFDLDBCQUEwQixDQUFDLENBQUM7UUFDM0QsTUFBTSxNQUFNLEdBQUcsT0FBTyxDQUFDLE9BQU8sQ0FBQywyQ0FBMkMsRUFBRTtZQUMxRSxLQUFLLEVBQUUsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1NBQzlCLENBQUMsQ0FBQztRQUNILE9BQU8sT0FBTyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQztJQUN2QyxDQUFDO0lBQUMsTUFBTSxDQUFDO1FBQ1AsT0FBTyxTQUFTLENBQUM7SUFDbkIsQ0FBQztBQUNILENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBwYXRoIGZyb20gJ3BhdGgnO1xuaW1wb3J0IHR5cGUge1xuICBJUG9saWN5VmFsaWRhdGlvbkNvbnRleHQsXG4gIElQb2xpY3lWYWxpZGF0aW9uUGx1Z2luLFxuICBQb2xpY3lWYWxpZGF0aW9uUGx1Z2luUmVwb3J0LFxuICBQb2xpY3lWaW9sYXRpb24sXG59IGZyb20gJ2F3cy1jZGstbGliJztcbmltcG9ydCB0eXBlIHsgQnVuZGxlZFJ1bGVEYXRhIH0gZnJvbSAnLi4vcnVsZXMuZ2VuZXJhdGVkJztcblxuLyogZXNsaW50LWRpc2FibGUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXJlcXVpcmUtaW1wb3J0cyAqL1xuXG5pbnRlcmZhY2UgRW5naW5lRGlhZ25vc3RpYyB7XG4gIHJlYWRvbmx5IHJ1bGVJZDogc3RyaW5nO1xuICByZWFkb25seSBzZXZlcml0eTogc3RyaW5nO1xuICByZWFkb25seSBtZXNzYWdlOiBzdHJpbmc7XG4gIHJlYWRvbmx5IHNvdXJjZT86IHN0cmluZztcbiAgcmVhZG9ubHkgZW50aXR5PzogeyByZWFkb25seSBsb2dpY2FsSWQ/OiBzdHJpbmcgfTtcbiAgcmVhZG9ubHkgcHJvcGVydHlQYXRoPzogc3RyaW5nO1xuICByZWFkb25seSBkb2N1bWVudGF0aW9uVXJsPzogc3RyaW5nO1xufVxuXG4vKipcbiAqIGVuZm9yY2Ug44Oi44O844OJ55So44Gu5YaF6YOo44OX44Op44Kw44Kk44Oz44CCXG4gKlxuICogQ0RLIOe1hOOBv+i+vOOBv+OBriBDbG91ZEZvcm1hdGlvblZhbGlkYXRlUGx1Z2luIOOBr+WFqCBmaW5kaW5nIOOCkiB3YXJuaW5nIOOBq+S4uOOCgeOCi+OBn+OCgVxuICog77yIYXdzLWNkay1saWIgMi4yNjcuMCDlrp/muKzjgIHmmIfmoLzjg5Xjg6njgrDjgoLnhKHlirnvvInjgIHlkIzjgZjjgqjjg7Pjgrjjg7PjgpLnm7TmjqXlkbzjgbPjgIFcbiAqIGNkay1wcmVmbGlnaHQg44Gu44Or44O844Or6YGV5Y+N77yI44GK44KI44GzIHN0cmljdCDmmYLjga/jgqjjg7Pjgrjjg7Pjga7jgqjjg6njg7zjgq/jg6njgrnvvInjgpJcbiAqIHBvbGljeSB2YWxpZGF0aW9uIOOBruWkseaVl+OBqOOBl+OBpuWgseWRiuOBl+OBpiBzeW50aCDjgpLmraLjgoHjgovjgIJcbiAqL1xuZXhwb3J0IGNsYXNzIFByZWZsaWdodEVuZm9yY2VQbHVnaW4gaW1wbGVtZW50cyBJUG9saWN5VmFsaWRhdGlvblBsdWdpbiB7XG4gIHB1YmxpYyByZWFkb25seSBuYW1lID0gJ2Nkay1wcmVmbGlnaHQnO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgcmVhZG9ubHkgcnVsZXM6IEJ1bmRsZWRSdWxlRGF0YVtdLFxuICAgIHByaXZhdGUgcmVhZG9ubHkgc3RyaWN0OiBib29sZWFuLFxuICApIHt9XG5cbiAgcHVibGljIHZhbGlkYXRlKGNvbnRleHQ6IElQb2xpY3lWYWxpZGF0aW9uQ29udGV4dCk6IFBvbGljeVZhbGlkYXRpb25QbHVnaW5SZXBvcnQge1xuICAgIGNvbnN0IGVuZ2luZSA9IGxvYWRFbmdpbmVDYWNoZWQoKTtcbiAgICBpZiAoIWVuZ2luZSkge1xuICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWNvbnNvbGVcbiAgICAgIGNvbnNvbGUuZXJyb3IoXG4gICAgICAgICdjZGstcHJlZmxpZ2h0OiBjb3VsZCBub3QgcmVzb2x2ZSBAYXdzL2Nsb3VkZm9ybWF0aW9uLXZhbGlkYXRlOyAnICtcbiAgICAgICAgJ2VuZm9yY2UgbW9kZSBpcyB1bmF2YWlsYWJsZSBhbmQgbm8gcHJlZmxpZ2h0IGNoZWNrcyB3ZXJlIHJ1bi4gJyArXG4gICAgICAgICdJbnN0YWxsIGl0IGFzIGEgZGV2RGVwZW5kZW5jeSBvciB1c2UgdGhlIGRlZmF1bHQgKHdhcm4pIG1vZGUuJyxcbiAgICAgICk7XG4gICAgICByZXR1cm4geyBzdWNjZXNzOiB0cnVlLCB2aW9sYXRpb25zOiBbXSB9O1xuICAgIH1cblxuICAgIGNvbnN0IGVuZyA9IHJlZ29FbmdpbmVDYWNoZWQoZW5naW5lLCB0aGlzLnJ1bGVzKTtcbiAgICBjb25zdCBvdXJzID0gbmV3IFNldCh0aGlzLnJ1bGVzLm1hcCgocikgPT4gci5pZCkpO1xuICAgIGNvbnN0IHZpb2xhdGlvbnM6IFBvbGljeVZpb2xhdGlvbltdID0gW107XG5cbiAgICBmb3IgKGNvbnN0IHN0IG9mIGNvbnRleHQuc3RhY2tUZW1wbGF0ZXMpIHtcbiAgICAgIGNvbnN0IHJlcG9ydCA9IGVuZy52YWxpZGF0ZURldGFpbGVkKG5ldyBlbmdpbmUuVGVtcGxhdGVGaWxlKHN0LnRlbXBsYXRlUGF0aCksIHtcbiAgICAgICAgcHNldWRvUGFyYW1ldGVyT3ZlcnJpZGVzOiB7XG4gICAgICAgICAgYWNjb3VudElkOiBjb250ZXh0LmFjY291bnRJZCxcbiAgICAgICAgICByZWdpb246IGNvbnRleHQucmVnaW9uLFxuICAgICAgICB9LFxuICAgICAgfSk7XG4gICAgICBmb3IgKGNvbnN0IGQgb2YgKHJlcG9ydC5kaWFnbm9zdGljcyA/PyBbXSkgYXMgRW5naW5lRGlhZ25vc3RpY1tdKSB7XG4gICAgICAgIGNvbnN0IGlzT3VycyA9IGQuc291cmNlID09PSAnQ1VTVE9NJyAmJiBvdXJzLmhhcyhkLnJ1bGVJZCk7XG4gICAgICAgIGNvbnN0IGlzU3RyaWN0SGl0ID0gdGhpcy5zdHJpY3RcbiAgICAgICAgICAmJiBkLnNvdXJjZSAhPT0gJ0NVU1RPTSdcbiAgICAgICAgICAmJiAoZC5zZXZlcml0eSA9PT0gJ0VSUk9SJyB8fCBkLnNldmVyaXR5ID09PSAnRkFUQUwnKTtcbiAgICAgICAgaWYgKCFpc091cnMgJiYgIWlzU3RyaWN0SGl0KSBjb250aW51ZTtcbiAgICAgICAgdmlvbGF0aW9ucy5wdXNoKHtcbiAgICAgICAgICBydWxlTmFtZTogZC5ydWxlSWQsXG4gICAgICAgICAgZGVzY3JpcHRpb246IGQubWVzc2FnZSxcbiAgICAgICAgICBzZXZlcml0eTogJ2Vycm9yJyxcbiAgICAgICAgICB2aW9sYXRpbmdSZXNvdXJjZXM6IFt7XG4gICAgICAgICAgICByZXNvdXJjZUxvZ2ljYWxJZDogZC5lbnRpdHk/LmxvZ2ljYWxJZCA/PyAnKHVua25vd24pJyxcbiAgICAgICAgICAgIHRlbXBsYXRlUGF0aDogc3QudGVtcGxhdGVQYXRoLFxuICAgICAgICAgICAgbG9jYXRpb25zOiBbZC5wcm9wZXJ0eVBhdGggPz8gJyh0ZW1wbGF0ZSknXSxcbiAgICAgICAgICB9XSxcbiAgICAgICAgICAuLi4oZC5kb2N1bWVudGF0aW9uVXJsID8geyBydWxlTWV0YWRhdGE6IHsgRG9jdW1lbnRhdGlvblVybDogZC5kb2N1bWVudGF0aW9uVXJsIH0gfSA6IHt9KSxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHsgc3VjY2VzczogdmlvbGF0aW9ucy5sZW5ndGggPT09IDAsIHZpb2xhdGlvbnMgfTtcbiAgfVxufVxuXG4vLyDjgqjjg7Pjgrjjg7PvvIhXQVNN77yJ44Gu5Yid5pyf5YyW44Gv6YeN44GE44Gf44KB44CB44Oi44K444Ol44O844Or44Os44OZ44Or44Gn44Kt44Oj44OD44K344Ol44GZ44KLXG5sZXQgY2FjaGVkRW5naW5lTW9kdWxlOiBhbnkgfCBmYWxzZSB8IHVuZGVmaW5lZDtcbmZ1bmN0aW9uIGxvYWRFbmdpbmVDYWNoZWQoKTogYW55IHwgdW5kZWZpbmVkIHtcbiAgaWYgKGNhY2hlZEVuZ2luZU1vZHVsZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgY2FjaGVkRW5naW5lTW9kdWxlID0gbG9hZEVuZ2luZSgpID8/IGZhbHNlO1xuICB9XG4gIHJldHVybiBjYWNoZWRFbmdpbmVNb2R1bGUgPT09IGZhbHNlID8gdW5kZWZpbmVkIDogY2FjaGVkRW5naW5lTW9kdWxlO1xufVxuXG5jb25zdCByZWdvRW5naW5lQ2FjaGUgPSBuZXcgTWFwPHN0cmluZywgYW55PigpO1xuZnVuY3Rpb24gcmVnb0VuZ2luZUNhY2hlZChlbmdpbmVNb2R1bGU6IGFueSwgcnVsZXM6IEJ1bmRsZWRSdWxlRGF0YVtdKTogYW55IHtcbiAgY29uc3Qga2V5ID0gcnVsZXMubWFwKChyKSA9PiByLmlkKS5qb2luKCcsJyk7XG4gIGlmICghcmVnb0VuZ2luZUNhY2hlLmhhcyhrZXkpKSB7XG4gICAgcmVnb0VuZ2luZUNhY2hlLnNldChrZXksIG5ldyBlbmdpbmVNb2R1bGUuUmVnb0VuZ2luZSh7XG4gICAgICBjdXN0b21SdWxlczogcnVsZXMubWFwKChyKSA9PiAoeyBuYW1lOiByLmlkLCBjb250ZW50OiByLnJlZ28gfSkpLFxuICAgIH0pKTtcbiAgfVxuICByZXR1cm4gcmVnb0VuZ2luZUNhY2hlLmdldChrZXkpO1xufVxuXG4vKipcbiAqIEBhd3MvY2xvdWRmb3JtYXRpb24tdmFsaWRhdGUg44KS6Kej5rG644GZ44KL44CCXG4gKiDpgJrluLjjga8gYXdzLWNkay1saWIg44GMIGJ1bmRsZWREZXBlbmRlbmNpZXMg44Go44GX44Gm5ZCM5qKx44GX44Gm44GE44KL44Kz44OU44O844Gr5LmX44KL44CCXG4gKiDvvIjjg4bjgrnjg4jjgYvjgonjgoLliKnnlKjjgZnjgovjgZ/jgoEgZXhwb3J0IOOBl+OBpuOBhOOCi++8iVxuICovXG5leHBvcnQgZnVuY3Rpb24gbG9hZEVuZ2luZSgpOiBhbnkgfCB1bmRlZmluZWQge1xuICB0cnkge1xuICAgIHJldHVybiByZXF1aXJlKCdAYXdzL2Nsb3VkZm9ybWF0aW9uLXZhbGlkYXRlJyk7XG4gIH0gY2F0Y2gge1xuICAgIC8vIGZhbGwgdGhyb3VnaFxuICB9XG4gIHRyeSB7XG4gICAgY29uc3QgbGliUGtnID0gcmVxdWlyZS5yZXNvbHZlKCdhd3MtY2RrLWxpYi9wYWNrYWdlLmpzb24nKTtcbiAgICBjb25zdCBlbmdQa2cgPSByZXF1aXJlLnJlc29sdmUoJ0Bhd3MvY2xvdWRmb3JtYXRpb24tdmFsaWRhdGUvcGFja2FnZS5qc29uJywge1xuICAgICAgcGF0aHM6IFtwYXRoLmRpcm5hbWUobGliUGtnKV0sXG4gICAgfSk7XG4gICAgcmV0dXJuIHJlcXVpcmUocGF0aC5kaXJuYW1lKGVuZ1BrZykpO1xuICB9IGNhdGNoIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG59XG4iXX0=
139
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZW5mb3JjZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9wcml2YXRlL2VuZm9yY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBK0dBLGdDQWVDO0FBOUhELDJDQUE2QjtBQXVCN0I7Ozs7Ozs7R0FPRztBQUNILE1BQWEsc0JBQXNCO0lBSWQ7SUFDQTtJQUpILElBQUksR0FBRyxlQUFlLENBQUM7SUFFdkMsWUFDbUIsS0FBd0IsRUFDeEIsTUFBZTtRQURmLFVBQUssR0FBTCxLQUFLLENBQW1CO1FBQ3hCLFdBQU0sR0FBTixNQUFNLENBQVM7SUFDL0IsQ0FBQztJQUVHLFFBQVEsQ0FBQyxPQUFpQztRQUMvQyxNQUFNLE1BQU0sR0FBRyxnQkFBZ0IsRUFBRSxDQUFDO1FBQ2xDLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztZQUNaLHNDQUFzQztZQUN0QyxPQUFPLENBQUMsS0FBSyxDQUNYLGlFQUFpRTtnQkFDakUsZ0VBQWdFO2dCQUNoRSwrREFBK0QsQ0FDaEUsQ0FBQztZQUNGLE9BQU8sRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLFVBQVUsRUFBRSxFQUFFLEVBQUUsQ0FBQztRQUMzQyxDQUFDO1FBRUQsTUFBTSxHQUFHLEdBQUcsZ0JBQWdCLENBQUMsTUFBTSxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUNqRCxNQUFNLElBQUksR0FBRyxJQUFJLEdBQUcsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDbEQsTUFBTSxVQUFVLEdBQXNCLEVBQUUsQ0FBQztRQUV6QyxLQUFLLE1BQU0sRUFBRSxJQUFJLE9BQU8sQ0FBQyxjQUFjLEVBQUUsQ0FBQztZQUN4QyxNQUFNLE1BQU0sR0FBRyxHQUFHLENBQUMsZ0JBQWdCLENBQUMsSUFB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QUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2xDLENBQUM7QUFFRDs7OztHQUlHO0FBQ0gsU0FBZ0IsVUFBVTtJQUN4QixJQUFJLENBQUM7UUFDSCxPQUFPLE9BQU8sQ0FBQyw4QkFBOEIsQ0FBQyxDQUFDO0lBQ2pELENBQUM7SUFBQyxNQUFNLENBQUM7UUFDUCxlQUFlO0lBQ2pCLENBQUM7SUFDRCxJQUFJLENBQUM7UUFDSCxNQUFNLE1BQU0sR0FBRyxPQUFPLENBQUMsT0FBTyxDQUFDLDBCQUEwQixDQUFDLENBQUM7UUFDM0QsTUFBTSxNQUFNLEdBQUcsT0FBTyxDQUFDLE9BQU8sQ0FBQywyQ0FBMkMsRUFBRTtZQUMxRSxLQUFLLEVBQUUsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1NBQzlCLENBQUMsQ0FBQztRQUNILE9BQU8sT0FBTyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQztJQUN2QyxDQUFDO0lBQUMsTUFBTSxDQUFDO1FBQ1AsT0FBTyxTQUFTLENBQUM7SUFDbkIsQ0FBQztBQUNILENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBwYXRoIGZyb20gJ3BhdGgnO1xuaW1wb3J0IHR5cGUge1xuICBJUG9saWN5VmFsaWRhdGlvbkNvbnRleHQsXG4gIElQb2xpY3lWYWxpZGF0aW9uUGx1Z2luLFxuICBQb2xpY3lWYWxpZGF0aW9uUGx1Z2luUmVwb3J0LFxuICBQb2xpY3lWaW9sYXRpb24sXG59IGZyb20gJ2F3cy1jZGstbGliJztcbmltcG9ydCB0eXBlIHsgQnVuZGxlZFJ1bGVEYXRhIH0gZnJvbSAnLi4vcnVsZXMuZ2VuZXJhdGVkJztcblxuLyogZXNsaW50LWRpc2FibGUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXJlcXVpcmUtaW1wb3J0cyAqL1xuLyogZXNsaW50LWRpc2FibGUgaW1wb3J0L25vLWV4dHJhbmVvdXMtZGVwZW5kZW5jaWVzIC0tIEBhd3MvY2xvdWRmb3JtYXRpb24tdmFsaWRhdGUg44GvXG4gICBhd3MtY2RrLWxpYiDlkIzmorHjgrPjg5Tjg7zjgpLli5XnmoTop6PmsbrjgZnjgovoqK3oqIjvvIjkvp3lrZjjgavjga/ovInjgZvjgarjgYTvvInjgIJSRUFETUUvQUdFTlRTLm1kIOWPgueFpyAqL1xuXG5pbnRlcmZhY2UgRW5naW5lRGlhZ25vc3RpYyB7XG4gIHJlYWRvbmx5IHJ1bGVJZDogc3RyaW5nO1xuICByZWFkb25seSBzZXZlcml0eTogc3RyaW5nO1xuICByZWFkb25seSBtZXNzYWdlOiBzdHJpbmc7XG4gIHJlYWRvbmx5IHNvdXJjZT86IHN0cmluZztcbiAgcmVhZG9ubHkgZW50aXR5PzogeyByZWFkb25seSBsb2dpY2FsSWQ/OiBzdHJpbmcgfTtcbiAgcmVhZG9ubHkgcHJvcGVydHlQYXRoPzogc3RyaW5nO1xuICByZWFkb25seSBkb2N1bWVudGF0aW9uVXJsPzogc3RyaW5nO1xufVxuXG4vKipcbiAqIGVuZm9yY2Ug44Oi44O844OJ55So44Gu5YaF6YOo44OX44Op44Kw44Kk44Oz44CCXG4gKlxuICogQ0RLIOe1hOOBv+i+vOOBv+OBriBDbG91ZEZvcm1hdGlvblZhbGlkYXRlUGx1Z2luIOOBr+WFqCBmaW5kaW5nIOOCkiB3YXJuaW5nIOOBq+S4uOOCgeOCi+OBn+OCgVxuICog77yIYXdzLWNkay1saWIgMi4yNjcuMCDlrp/muKzjgIHmmIfmoLzjg5Xjg6njgrDjgoLnhKHlirnvvInjgIHlkIzjgZjjgqjjg7Pjgrjjg7PjgpLnm7TmjqXlkbzjgbPjgIFcbiAqIGNkay1wcmVmbGlnaHQg44Gu44Or44O844Or6YGV5Y+N77yI44GK44KI44GzIHN0cmljdCDmmYLjga/jgqjjg7Pjgrjjg7Pjga7jgqjjg6njg7zjgq/jg6njgrnvvInjgpJcbiAqIHBvbGljeSB2YWxpZGF0aW9uIOOBruWkseaVl+OBqOOBl+OBpuWgseWRiuOBl+OBpiBzeW50aCDjgpLmraLjgoHjgovjgIJcbiAqL1xuZXhwb3J0IGNsYXNzIFByZWZsaWdodEVuZm9yY2VQbHVnaW4gaW1wbGVtZW50cyBJUG9saWN5VmFsaWRhdGlvblBsdWdpbiB7XG4gIHB1YmxpYyByZWFkb25seSBuYW1lID0gJ2Nkay1wcmVmbGlnaHQnO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgcmVhZG9ubHkgcnVsZXM6IEJ1bmRsZWRSdWxlRGF0YVtdLFxuICAgIHByaXZhdGUgcmVhZG9ubHkgc3RyaWN0OiBib29sZWFuLFxuICApIHt9XG5cbiAgcHVibGljIHZhbGlkYXRlKGNvbnRleHQ6IElQb2xpY3lWYWxpZGF0aW9uQ29udGV4dCk6IFBvbGljeVZhbGlkYXRpb25QbHVnaW5SZXBvcnQge1xuICAgIGNvbnN0IGVuZ2luZSA9IGxvYWRFbmdpbmVDYWNoZWQoKTtcbiAgICBpZiAoIWVuZ2luZSkge1xuICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWNvbnNvbGVcbiAgICAgIGNvbnNvbGUuZXJyb3IoXG4gICAgICAgICdjZGstcHJlZmxpZ2h0OiBjb3VsZCBub3QgcmVzb2x2ZSBAYXdzL2Nsb3VkZm9ybWF0aW9uLXZhbGlkYXRlOyAnICtcbiAgICAgICAgJ2VuZm9yY2UgbW9kZSBpcyB1bmF2YWlsYWJsZSBhbmQgbm8gcHJlZmxpZ2h0IGNoZWNrcyB3ZXJlIHJ1bi4gJyArXG4gICAgICAgICdJbnN0YWxsIGl0IGFzIGEgZGV2RGVwZW5kZW5jeSBvciB1c2UgdGhlIGRlZmF1bHQgKHdhcm4pIG1vZGUuJyxcbiAgICAgICk7XG4gICAgICByZXR1cm4geyBzdWNjZXNzOiB0cnVlLCB2aW9sYXRpb25zOiBbXSB9O1xuICAgIH1cblxuICAgIGNvbnN0IGVuZyA9IHJlZ29FbmdpbmVDYWNoZWQoZW5naW5lLCB0aGlzLnJ1bGVzKTtcbiAgICBjb25zdCBvdXJzID0gbmV3IFNldCh0aGlzLnJ1bGVzLm1hcCgocikgPT4gci5pZCkpO1xuICAgIGNvbnN0IHZpb2xhdGlvbnM6IFBvbGljeVZpb2xhdGlvbltdID0gW107XG5cbiAgICBmb3IgKGNvbnN0IHN0IG9mIGNvbnRleHQuc3RhY2tUZW1wbGF0ZXMpIHtcbiAgICAgIGNvbnN0IHJlcG9ydCA9IGVuZy52YWxpZGF0ZURldGFpbGVkKG5ldyBlbmdpbmUuVGVtcGxhdGVGaWxlKHN0LnRlbXBsYXRlUGF0aCksIHtcbiAgICAgICAgcHNldWRvUGFyYW1ldGVyT3ZlcnJpZGVzOiB7XG4gICAgICAgICAgYWNjb3VudElkOiBjb250ZXh0LmFjY291bnRJZCxcbiAgICAgICAgICByZWdpb246IGNvbnRleHQucmVnaW9uLFxuICAgICAgICB9LFxuICAgICAgfSk7XG4gICAgICBmb3IgKGNvbnN0IGQgb2YgKHJlcG9ydC5kaWFnbm9zdGljcyA/PyBbXSkgYXMgRW5naW5lRGlhZ25vc3RpY1tdKSB7XG4gICAgICAgIGNvbnN0IGlzT3VycyA9IGQuc291cmNlID09PSAnQ1VTVE9NJyAmJiBvdXJzLmhhcyhkLnJ1bGVJZCk7XG4gICAgICAgIGNvbnN0IGlzU3RyaWN0SGl0ID0gdGhpcy5zdHJpY3RcbiAgICAgICAgICAmJiBkLnNvdXJjZSAhPT0gJ0NVU1RPTSdcbiAgICAgICAgICAmJiAoZC5zZXZlcml0eSA9PT0gJ0VSUk9SJyB8fCBkLnNldmVyaXR5ID09PSAnRkFUQUwnKTtcbiAgICAgICAgaWYgKCFpc091cnMgJiYgIWlzU3RyaWN0SGl0KSBjb250aW51ZTtcbiAgICAgICAgdmlvbGF0aW9ucy5wdXNoKHtcbiAgICAgICAgICBydWxlTmFtZTogZC5ydWxlSWQsXG4gICAgICAgICAgZGVzY3JpcHRpb246IGQubWVzc2FnZSxcbiAgICAgICAgICBzZXZlcml0eTogJ2Vycm9yJyxcbiAgICAgICAgICB2aW9sYXRpbmdSZXNvdXJjZXM6IFt7XG4gICAgICAgICAgICByZXNvdXJjZUxvZ2ljYWxJZDogZC5lbnRpdHk/LmxvZ2ljYWxJZCA/PyAnKHVua25vd24pJyxcbiAgICAgICAgICAgIHRlbXBsYXRlUGF0aDogc3QudGVtcGxhdGVQYXRoLFxuICAgICAgICAgICAgbG9jYXRpb25zOiBbZC5wcm9wZXJ0eVBhdGggPz8gJyh0ZW1wbGF0ZSknXSxcbiAgICAgICAgICB9XSxcbiAgICAgICAgICAuLi4oZC5kb2N1bWVudGF0aW9uVXJsID8geyBydWxlTWV0YWRhdGE6IHsgRG9jdW1lbnRhdGlvblVybDogZC5kb2N1bWVudGF0aW9uVXJsIH0gfSA6IHt9KSxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHsgc3VjY2VzczogdmlvbGF0aW9ucy5sZW5ndGggPT09IDAsIHZpb2xhdGlvbnMgfTtcbiAgfVxufVxuXG4vLyDjgqjjg7Pjgrjjg7PvvIhXQVNN77yJ44Gu5Yid5pyf5YyW44Gv6YeN44GE44Gf44KB44CB44Oi44K444Ol44O844Or44Os44OZ44Or44Gn44Kt44Oj44OD44K344Ol44GZ44KLXG5sZXQgY2FjaGVkRW5naW5lTW9kdWxlOiBhbnkgfCBmYWxzZSB8IHVuZGVmaW5lZDtcbmZ1bmN0aW9uIGxvYWRFbmdpbmVDYWNoZWQoKTogYW55IHwgdW5kZWZpbmVkIHtcbiAgaWYgKGNhY2hlZEVuZ2luZU1vZHVsZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgY2FjaGVkRW5naW5lTW9kdWxlID0gbG9hZEVuZ2luZSgpID8/IGZhbHNlO1xuICB9XG4gIHJldHVybiBjYWNoZWRFbmdpbmVNb2R1bGUgPT09IGZhbHNlID8gdW5kZWZpbmVkIDogY2FjaGVkRW5naW5lTW9kdWxlO1xufVxuXG5jb25zdCByZWdvRW5naW5lQ2FjaGUgPSBuZXcgTWFwPHN0cmluZywgYW55PigpO1xuZnVuY3Rpb24gcmVnb0VuZ2luZUNhY2hlZChlbmdpbmVNb2R1bGU6IGFueSwgcnVsZXM6IEJ1bmRsZWRSdWxlRGF0YVtdKTogYW55IHtcbiAgY29uc3Qga2V5ID0gcnVsZXMubWFwKChyKSA9PiByLmlkKS5qb2luKCcsJyk7XG4gIGlmICghcmVnb0VuZ2luZUNhY2hlLmhhcyhrZXkpKSB7XG4gICAgcmVnb0VuZ2luZUNhY2hlLnNldChrZXksIG5ldyBlbmdpbmVNb2R1bGUuUmVnb0VuZ2luZSh7XG4gICAgICBjdXN0b21SdWxlczogcnVsZXMubWFwKChyKSA9PiAoeyBuYW1lOiByLmlkLCBjb250ZW50OiByLnJlZ28gfSkpLFxuICAgIH0pKTtcbiAgfVxuICByZXR1cm4gcmVnb0VuZ2luZUNhY2hlLmdldChrZXkpO1xufVxuXG4vKipcbiAqIEBhd3MvY2xvdWRmb3JtYXRpb24tdmFsaWRhdGUg44KS6Kej5rG644GZ44KL44CCXG4gKiDpgJrluLjjga8gYXdzLWNkay1saWIg44GMIGJ1bmRsZWREZXBlbmRlbmNpZXMg44Go44GX44Gm5ZCM5qKx44GX44Gm44GE44KL44Kz44OU44O844Gr5LmX44KL44CCXG4gKiDvvIjjg4bjgrnjg4jjgYvjgonjgoLliKnnlKjjgZnjgovjgZ/jgoEgZXhwb3J0IOOBl+OBpuOBhOOCi++8iVxuICovXG5leHBvcnQgZnVuY3Rpb24gbG9hZEVuZ2luZSgpOiBhbnkgfCB1bmRlZmluZWQge1xuICB0cnkge1xuICAgIHJldHVybiByZXF1aXJlKCdAYXdzL2Nsb3VkZm9ybWF0aW9uLXZhbGlkYXRlJyk7XG4gIH0gY2F0Y2gge1xuICAgIC8vIGZhbGwgdGhyb3VnaFxuICB9XG4gIHRyeSB7XG4gICAgY29uc3QgbGliUGtnID0gcmVxdWlyZS5yZXNvbHZlKCdhd3MtY2RrLWxpYi9wYWNrYWdlLmpzb24nKTtcbiAgICBjb25zdCBlbmdQa2cgPSByZXF1aXJlLnJlc29sdmUoJ0Bhd3MvY2xvdWRmb3JtYXRpb24tdmFsaWRhdGUvcGFja2FnZS5qc29uJywge1xuICAgICAgcGF0aHM6IFtwYXRoLmRpcm5hbWUobGliUGtnKV0sXG4gICAgfSk7XG4gICAgcmV0dXJuIHJlcXVpcmUocGF0aC5kaXJuYW1lKGVuZ1BrZykpO1xuICB9IGNhdGNoIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG59XG4iXX0=
@@ -2,6 +2,28 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.BUNDLED_RULES = void 0;
4
4
  exports.BUNDLED_RULES = [
5
+ {
6
+ "id": "pf-agentcore-gateway-jwt-authorizer",
7
+ "service": "bedrock-agentcore",
8
+ "severity": "ERROR",
9
+ "title": "Gateways with AuthorizerType CUSTOM_JWT require AuthorizerConfiguration",
10
+ "upstream": "none",
11
+ "resourceTypes": [
12
+ "AWS::BedrockAgentCore::Gateway"
13
+ ],
14
+ "rego": "package cdk_preflight\n\nimport rego.v1\n\n_pf_gwjwt_has_config(name) if is_object(resolve(name, \"Properties.AuthorizerConfiguration\"))\n\nviolation contains make_diag_full(\"pf-agentcore-gateway-jwt-authorizer\", \"ERROR\", name,\n\t\"Properties.AuthorizerConfiguration\",\n\t\"AuthorizerType is CUSTOM_JWT but AuthorizerConfiguration is missing; the CreateGateway API requires it and the deployment fails with a ValidationException\",\n\t\"Add AuthorizerConfiguration.CustomJWTAuthorizer (discoveryUrl and allowedAudience/allowedClients), or switch AuthorizerType to AWS_IAM\",\n\t\"https://docs.aws.amazon.com/bedrock-agentcore-control/latest/APIReference/API_CreateGateway.html\") if {\n\tsome name in resources_of_type(\"AWS::BedrockAgentCore::Gateway\")\n\tresolve(name, \"Properties.AuthorizerType\") == \"CUSTOM_JWT\"\n\tnot _pf_gwjwt_has_config(name)\n}\n"
15
+ },
16
+ {
17
+ "id": "pf-agentcore-runtime-name",
18
+ "service": "bedrock-agentcore",
19
+ "severity": "ERROR",
20
+ "title": "AgentCore Runtime names must match [a-zA-Z][a-zA-Z0-9_]{0,47} (no hyphens)",
21
+ "upstream": "pending-engine",
22
+ "resourceTypes": [
23
+ "AWS::BedrockAgentCore::Runtime"
24
+ ],
25
+ "rego": "package cdk_preflight\n\nimport rego.v1\n\n# CloudFormation スキーマは AgentRuntimeName のパターンを持たない(エンジン素通り、\n# 2026-09-01 に 1.7.0-beta で確認)が、CreateAgentRuntime API は\n# [a-zA-Z][a-zA-Z0-9_]{0,47} を強制する。ハイフン入りの CDK 風命名が定番の死因。\nviolation contains make_diag_full(\"pf-agentcore-runtime-name\", \"ERROR\", name,\n\t\"Properties.AgentRuntimeName\",\n\tsprintf(\"AgentRuntimeName '%s' is invalid: it must start with a letter and contain only letters, digits, and underscores (max 48 characters, hyphens are not allowed); CreateAgentRuntime fails at deploy time\", [n]),\n\t\"Use an underscore-separated name such as 'my_agent_runtime'\",\n\t\"https://docs.aws.amazon.com/bedrock-agentcore-control/latest/APIReference/API_CreateAgentRuntime.html\") if {\n\tsome name in resources_of_type(\"AWS::BedrockAgentCore::Runtime\")\n\tn := resolve(name, \"Properties.AgentRuntimeName\")\n\tis_string(n)\n\tnot regex.match(`^[a-zA-Z][a-zA-Z0-9_]{0,47}$`, n)\n}\n"
26
+ },
5
27
  {
6
28
  "id": "pf-cloudfront-acm-cert-region",
7
29
  "service": "cloudfront",
@@ -24,6 +46,17 @@ exports.BUNDLED_RULES = [
24
46
  ],
25
47
  "rego": "package cdk_preflight\n\nimport rego.v1\n\n_pf_cf_ttl_fix := \"Order the TTLs as MinTTL <= DefaultTTL <= MaxTTL\"\n\n_pf_cf_ttl_url := \"https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/Expiration.html\"\n\n_pf_cf_behaviors(name) := array.concat(\n\t[{\"path\": \"Properties.DistributionConfig.DefaultCacheBehavior\", \"value\": it.value} |\n\t\tsome it in flatten_list(name, \"Properties.DistributionConfig.DefaultCacheBehavior\")],\n\t[{\"path\": sprintf(\"Properties.DistributionConfig.CacheBehaviors.%d\", [it.index]), \"value\": it.value} |\n\t\tsome it in flatten_list(name, \"Properties.DistributionConfig.CacheBehaviors\")],\n)\n\nviolation contains make_diag_full(\"pf-cloudfront-ttl-order\", \"ERROR\", name, b.path,\n\tsprintf(\"MinTTL (%v) must be less than or equal to MaxTTL (%v)\", [mn, mx]),\n\t_pf_cf_ttl_fix, _pf_cf_ttl_url) if {\n\tsome name in resources_of_type(\"AWS::CloudFront::Distribution\")\n\tsome b in _pf_cf_behaviors(name)\n\tis_object(b.value)\n\tmn := to_number(object.get(b.value, \"MinTTL\", null))\n\tmx := to_number(object.get(b.value, \"MaxTTL\", null))\n\tmn > mx\n}\n\nviolation contains make_diag_full(\"pf-cloudfront-ttl-order\", \"ERROR\", name, b.path,\n\tsprintf(\"MinTTL (%v) must be less than or equal to DefaultTTL (%v)\", [mn, df]),\n\t_pf_cf_ttl_fix, _pf_cf_ttl_url) if {\n\tsome name in resources_of_type(\"AWS::CloudFront::Distribution\")\n\tsome b in _pf_cf_behaviors(name)\n\tis_object(b.value)\n\tmn := to_number(object.get(b.value, \"MinTTL\", null))\n\tdf := to_number(object.get(b.value, \"DefaultTTL\", null))\n\tmn > df\n}\n\nviolation contains make_diag_full(\"pf-cloudfront-ttl-order\", \"ERROR\", name, b.path,\n\tsprintf(\"DefaultTTL (%v) must be less than or equal to MaxTTL (%v)\", [df, mx]),\n\t_pf_cf_ttl_fix, _pf_cf_ttl_url) if {\n\tsome name in resources_of_type(\"AWS::CloudFront::Distribution\")\n\tsome b in _pf_cf_behaviors(name)\n\tis_object(b.value)\n\tdf := to_number(object.get(b.value, \"DefaultTTL\", null))\n\tmx := to_number(object.get(b.value, \"MaxTTL\", null))\n\tdf > mx\n}\n"
26
48
  },
49
+ {
50
+ "id": "pf-dynamodb-billing-throughput",
51
+ "service": "dynamodb",
52
+ "severity": "ERROR",
53
+ "title": "ProvisionedThroughput must match BillingMode (required for PROVISIONED, forbidden for PAY_PER_REQUEST)",
54
+ "upstream": "none",
55
+ "resourceTypes": [
56
+ "AWS::DynamoDB::Table"
57
+ ],
58
+ "rego": "package cdk_preflight\n\nimport rego.v1\n\n_pf_ddbbt_url := \"https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.ReadWriteCapacityMode.html\"\n\n_pf_ddbbt_has_pt(name) if is_object(resolve(name, \"Properties.ProvisionedThroughput\"))\n\n_pf_ddbbt_billing_present(name) if resolve(name, \"Properties.BillingMode\")\n\n# BillingMode がリテラル \"PROVISIONED\"、または未指定(デフォルト PROVISIONED)。\n# トークン値(Ref 等)は判定に使わない(誤検知防止)。\n_pf_ddbbt_provisioned(name) if resolve(name, \"Properties.BillingMode\") == \"PROVISIONED\"\n\n_pf_ddbbt_provisioned(name) if not _pf_ddbbt_billing_present(name)\n\nviolation contains make_diag_full(\"pf-dynamodb-billing-throughput\", \"ERROR\", name,\n\t\"Properties.ProvisionedThroughput\",\n\t\"ProvisionedThroughput cannot be specified when BillingMode is PAY_PER_REQUEST; CreateTable fails at deploy time\",\n\t\"Remove ProvisionedThroughput, or switch BillingMode to PROVISIONED\",\n\t_pf_ddbbt_url) if {\n\tsome name in resources_of_type(\"AWS::DynamoDB::Table\")\n\tresolve(name, \"Properties.BillingMode\") == \"PAY_PER_REQUEST\"\n\t_pf_ddbbt_has_pt(name)\n}\n\nviolation contains make_diag_full(\"pf-dynamodb-billing-throughput\", \"ERROR\", name,\n\t\"Properties.ProvisionedThroughput\",\n\t\"BillingMode is PROVISIONED (the default) but ProvisionedThroughput is missing; CreateTable fails at deploy time\",\n\t\"Add ProvisionedThroughput (ReadCapacityUnits / WriteCapacityUnits), or set BillingMode to PAY_PER_REQUEST\",\n\t_pf_ddbbt_url) if {\n\tsome name in resources_of_type(\"AWS::DynamoDB::Table\")\n\t_pf_ddbbt_provisioned(name)\n\tnot _pf_ddbbt_has_pt(name)\n}\n"
59
+ },
27
60
  {
28
61
  "id": "pf-ec2-sg-port-range",
29
62
  "service": "ec2",
@@ -37,6 +70,40 @@ exports.BUNDLED_RULES = [
37
70
  ],
38
71
  "rego": "package cdk_preflight\n\nimport rego.v1\n\n_pf_sg_fix := \"Use a port between 0 and 65535 with FromPort <= ToPort\"\n\n_pf_sg_url := \"https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_AuthorizeSecurityGroupIngress.html\"\n\n_pf_port_out(n) if n < 0\n\n_pf_port_out(n) if n > 65535\n\n_pf_tcp_udp(p) if p in {\"tcp\", \"udp\", \"6\", \"17\", 6, 17}\n\nviolation contains make_diag_full(\"pf-ec2-sg-port-range\", \"ERROR\", name,\n\tsprintf(\"Properties.%s.%d.%s\", [dir, item.index, pname]),\n\tsprintf(\"%s %v is outside the valid TCP/UDP port range 0-65535\", [pname, n]),\n\t_pf_sg_fix, _pf_sg_url) if {\n\tsome name in resources_of_type(\"AWS::EC2::SecurityGroup\")\n\tsome dir in {\"SecurityGroupIngress\", \"SecurityGroupEgress\"}\n\tsome item in flatten_list(name, sprintf(\"Properties.%s\", [dir]))\n\tentry := item.value\n\tis_object(entry)\n\t_pf_tcp_udp(object.get(entry, \"IpProtocol\", null))\n\tsome pname in {\"FromPort\", \"ToPort\"}\n\tn := to_number(object.get(entry, pname, null))\n\t_pf_port_out(n)\n}\n\nviolation contains make_diag_full(\"pf-ec2-sg-port-range\", \"ERROR\", name,\n\tsprintf(\"Properties.%s.%d.FromPort\", [dir, item.index]),\n\tsprintf(\"FromPort (%v) must be less than or equal to ToPort (%v)\", [f, t]),\n\t_pf_sg_fix, _pf_sg_url) if {\n\tsome name in resources_of_type(\"AWS::EC2::SecurityGroup\")\n\tsome dir in {\"SecurityGroupIngress\", \"SecurityGroupEgress\"}\n\tsome item in flatten_list(name, sprintf(\"Properties.%s\", [dir]))\n\tentry := item.value\n\tis_object(entry)\n\t_pf_tcp_udp(object.get(entry, \"IpProtocol\", null))\n\tf := to_number(object.get(entry, \"FromPort\", null))\n\tt := to_number(object.get(entry, \"ToPort\", null))\n\tf >= 0\n\tt <= 65535\n\tf > t\n}\n\nviolation contains make_diag_full(\"pf-ec2-sg-port-range\", \"ERROR\", name,\n\tsprintf(\"Properties.%s\", [pname]),\n\tsprintf(\"%s %v is outside the valid TCP/UDP port range 0-65535\", [pname, n]),\n\t_pf_sg_fix, _pf_sg_url) if {\n\tsome rtype in {\"AWS::EC2::SecurityGroupIngress\", \"AWS::EC2::SecurityGroupEgress\"}\n\tsome name in resources_of_type(rtype)\n\t_pf_tcp_udp(resolve(name, \"Properties.IpProtocol\"))\n\tsome pname in {\"FromPort\", \"ToPort\"}\n\tn := to_number(resolve(name, sprintf(\"Properties.%s\", [pname])))\n\t_pf_port_out(n)\n}\n\nviolation contains make_diag_full(\"pf-ec2-sg-port-range\", \"ERROR\", name,\n\t\"Properties.FromPort\",\n\tsprintf(\"FromPort (%v) must be less than or equal to ToPort (%v)\", [f, t]),\n\t_pf_sg_fix, _pf_sg_url) if {\n\tsome rtype in {\"AWS::EC2::SecurityGroupIngress\", \"AWS::EC2::SecurityGroupEgress\"}\n\tsome name in resources_of_type(rtype)\n\t_pf_tcp_udp(resolve(name, \"Properties.IpProtocol\"))\n\tf := to_number(resolve(name, \"Properties.FromPort\"))\n\tt := to_number(resolve(name, \"Properties.ToPort\"))\n\tf >= 0\n\tt <= 65535\n\tf > t\n}\n"
39
72
  },
73
+ {
74
+ "id": "pf-ec2-userdata-size",
75
+ "service": "ec2",
76
+ "severity": "ERROR",
77
+ "title": "EC2 user data is limited to 16384 bytes",
78
+ "upstream": "none",
79
+ "resourceTypes": [
80
+ "AWS::EC2::Instance",
81
+ "AWS::EC2::LaunchTemplate"
82
+ ],
83
+ "rego": "package cdk_preflight\n\nimport rego.v1\n\n_pf_udsz_fix := \"Keep user data under 16384 bytes; move large payloads to S3 and fetch them from a small bootstrap script\"\n\n_pf_udsz_url := \"https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instancedata-add-user-data.html\"\n\n_pf_udsz_limit := 16384\n\n# base64 文字列のデコード後バイト数(パディング考慮)\n_pf_udsz_decoded(s) := ((count(s) * 3) / 4) - 2 if endswith(s, \"==\")\n\n_pf_udsz_decoded(s) := ((count(s) * 3) / 4) - 1 if {\n\tendswith(s, \"=\")\n\tnot endswith(s, \"==\")\n}\n\n_pf_udsz_decoded(s) := (count(s) * 3) / 4 if not endswith(s, \"=\")\n\n_pf_udsz_paths := {\n\t\"AWS::EC2::Instance\": \"Properties.UserData\",\n\t\"AWS::EC2::LaunchTemplate\": \"Properties.LaunchTemplateData.UserData\",\n}\n\n# UserData がリテラル base64 文字列のケース\nviolation contains make_diag_full(\"pf-ec2-userdata-size\", \"ERROR\", name, p,\n\tsprintf(\"UserData decodes to about %v bytes, but EC2 limits user data to %d bytes; RunInstances fails at deploy time\", [size, _pf_udsz_limit]),\n\t_pf_udsz_fix, _pf_udsz_url) if {\n\tsome rtype, p in _pf_udsz_paths\n\tsome name in resources_of_type(rtype)\n\tud := resolve(name, p)\n\tis_string(ud)\n\tsize := _pf_udsz_decoded(ud)\n\tsize > _pf_udsz_limit\n}\n\n# UserData が {\"Fn::Base64\": \"<literal>\"} のケース(エンコード前の生バイト数で判定)\nviolation contains make_diag_full(\"pf-ec2-userdata-size\", \"ERROR\", name, p,\n\tsprintf(\"UserData is %d bytes before base64 encoding, but EC2 limits user data to %d bytes; RunInstances fails at deploy time\", [count(inner), _pf_udsz_limit]),\n\t_pf_udsz_fix, _pf_udsz_url) if {\n\tsome rtype, p in _pf_udsz_paths\n\tsome name in resources_of_type(rtype)\n\tud := resolve(name, p)\n\tis_object(ud)\n\tinner := object.get(ud, \"Fn::Base64\", null)\n\tis_string(inner)\n\tcount(inner) > _pf_udsz_limit\n}\n"
84
+ },
85
+ {
86
+ "id": "pf-ec2-volume-iops",
87
+ "service": "ec2",
88
+ "severity": "ERROR",
89
+ "title": "EBS Iops/Throughput must match the volume type's supported ranges and ratios",
90
+ "upstream": "none",
91
+ "resourceTypes": [
92
+ "AWS::EC2::Volume"
93
+ ],
94
+ "rego": "package cdk_preflight\n\nimport rego.v1\n\n_pf_voliops_fix := \"Match Iops/Throughput to the volume type: gp3 3000-80000 IOPS (max 500/GiB, throughput 125-2000 MiB/s and at most IOPS/4), io1 100-64000 (max 50/GiB), io2 100-256000 (max 1000/GiB); gp2/st1/sc1/standard accept neither property\"\n\n_pf_voliops_url := \"https://docs.aws.amazon.com/ebs/latest/userguide/ebs-volume-types.html\"\n\n_pf_voliops_range := {\"gp3\": [3000, 80000], \"io1\": [100, 64000], \"io2\": [100, 256000]}\n\n_pf_voliops_per_gib := {\"gp3\": 500, \"io1\": 50, \"io2\": 1000}\n\n_pf_voliops_out(n, lo, hi) if n < lo\n\n_pf_voliops_out(n, lo, hi) if n > hi\n\n_pf_voliops_has_iops(name) if resolve(name, \"Properties.Iops\")\n\n# IOPS が型ごとの絶対レンジ外\nviolation contains make_diag_full(\"pf-ec2-volume-iops\", \"ERROR\", name, \"Properties.Iops\",\n\tsprintf(\"Iops %v is outside the supported range %d-%d for %s volumes\", [n, r[0], r[1], vt]),\n\t_pf_voliops_fix, _pf_voliops_url) if {\n\tsome name in resources_of_type(\"AWS::EC2::Volume\")\n\tvt := resolve(name, \"Properties.VolumeType\")\n\tr := _pf_voliops_range[vt]\n\tn := to_number(resolve(name, \"Properties.Iops\"))\n\t_pf_voliops_out(n, r[0], r[1])\n}\n\n# IOPS : サイズ比の超過\nviolation contains make_diag_full(\"pf-ec2-volume-iops\", \"ERROR\", name, \"Properties.Iops\",\n\tsprintf(\"Iops %v exceeds the maximum ratio of %d IOPS per GiB for %s (Size %v GiB allows at most %v)\", [n, ratio, vt, s, s * ratio]),\n\t_pf_voliops_fix, _pf_voliops_url) if {\n\tsome name in resources_of_type(\"AWS::EC2::Volume\")\n\tvt := resolve(name, \"Properties.VolumeType\")\n\tratio := _pf_voliops_per_gib[vt]\n\tn := to_number(resolve(name, \"Properties.Iops\"))\n\ts := to_number(resolve(name, \"Properties.Size\"))\n\tn > s * ratio\n}\n\n# Iops を受け付けない型に Iops を指定\nviolation contains make_diag_full(\"pf-ec2-volume-iops\", \"ERROR\", name, \"Properties.Iops\",\n\tsprintf(\"Iops is not supported for %s volumes (valid only for gp3, io1, io2); EC2 rejects the CreateVolume call\", [vt]),\n\t_pf_voliops_fix, _pf_voliops_url) if {\n\tsome name in resources_of_type(\"AWS::EC2::Volume\")\n\tvt := resolve(name, \"Properties.VolumeType\")\n\tvt in {\"gp2\", \"st1\", \"sc1\", \"standard\"}\n\tresolve(name, \"Properties.Iops\")\n}\n\n# Throughput は gp3 専用\nviolation contains make_diag_full(\"pf-ec2-volume-iops\", \"ERROR\", name, \"Properties.Throughput\",\n\tsprintf(\"Throughput is not supported for %s volumes (valid only for gp3); EC2 rejects the CreateVolume call\", [vt]),\n\t_pf_voliops_fix, _pf_voliops_url) if {\n\tsome name in resources_of_type(\"AWS::EC2::Volume\")\n\tvt := resolve(name, \"Properties.VolumeType\")\n\tis_string(vt)\n\tvt != \"gp3\"\n\tresolve(name, \"Properties.Throughput\")\n}\n\n# gp3 Throughput の絶対レンジ\nviolation contains make_diag_full(\"pf-ec2-volume-iops\", \"ERROR\", name, \"Properties.Throughput\",\n\tsprintf(\"Throughput %v MiB/s is outside the supported range 125-2000 for gp3 volumes\", [t]),\n\t_pf_voliops_fix, _pf_voliops_url) if {\n\tsome name in resources_of_type(\"AWS::EC2::Volume\")\n\tresolve(name, \"Properties.VolumeType\") == \"gp3\"\n\tt := to_number(resolve(name, \"Properties.Throughput\"))\n\t_pf_voliops_out(t, 125, 2000)\n}\n\n# gp3 Throughput : IOPS 比(最大 0.25 MiB/s per IOPS)\nviolation contains make_diag_full(\"pf-ec2-volume-iops\", \"ERROR\", name, \"Properties.Throughput\",\n\tsprintf(\"Throughput %v MiB/s exceeds the maximum ratio of 0.25 MiB/s per provisioned IOPS (%v IOPS allows at most %v)\", [t, n, n / 4]),\n\t_pf_voliops_fix, _pf_voliops_url) if {\n\tsome name in resources_of_type(\"AWS::EC2::Volume\")\n\tresolve(name, \"Properties.VolumeType\") == \"gp3\"\n\tt := to_number(resolve(name, \"Properties.Throughput\"))\n\tn := to_number(resolve(name, \"Properties.Iops\"))\n\tt * 4 > n\n}\n\n# gp3 で Iops 未指定(デフォルト 3000)のときの Throughput 比\nviolation contains make_diag_full(\"pf-ec2-volume-iops\", \"ERROR\", name, \"Properties.Throughput\",\n\tsprintf(\"Throughput %v MiB/s exceeds 750, the maximum for the default 3000 IOPS (0.25 MiB/s per IOPS); provision Iops explicitly or lower the throughput\", [t]),\n\t_pf_voliops_fix, _pf_voliops_url) if {\n\tsome name in resources_of_type(\"AWS::EC2::Volume\")\n\tresolve(name, \"Properties.VolumeType\") == \"gp3\"\n\tnot _pf_voliops_has_iops(name)\n\tt := to_number(resolve(name, \"Properties.Throughput\"))\n\tt > 750\n}\n"
95
+ },
96
+ {
97
+ "id": "pf-ecs-fargate-network-mode",
98
+ "service": "ecs",
99
+ "severity": "ERROR",
100
+ "title": "Fargate task definitions require NetworkMode 'awsvpc'",
101
+ "upstream": "none",
102
+ "resourceTypes": [
103
+ "AWS::ECS::TaskDefinition"
104
+ ],
105
+ "rego": "package cdk_preflight\n\nimport rego.v1\n\n_pf_ecsnm_url := \"https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definition_parameters.html#network_mode\"\n\n_pf_ecsnm_has_mode(name) if resolve(name, \"Properties.NetworkMode\")\n\nviolation contains make_diag_full(\"pf-ecs-fargate-network-mode\", \"ERROR\", name,\n\t\"Properties.NetworkMode\",\n\tsprintf(\"NetworkMode is '%s' but task definitions requiring FARGATE compatibility must use 'awsvpc'; RegisterTaskDefinition fails at deploy time\", [nm]),\n\t\"Set NetworkMode to 'awsvpc'\",\n\t_pf_ecsnm_url) if {\n\tsome name in resources_of_type(\"AWS::ECS::TaskDefinition\")\n\trc := resolve(name, \"Properties.RequiresCompatibilities\")\n\tis_array(rc)\n\t\"FARGATE\" in rc\n\tnm := resolve(name, \"Properties.NetworkMode\")\n\tis_string(nm)\n\tnm != \"awsvpc\"\n}\n\n# NetworkMode 未指定でも RegisterTaskDefinition は\n# \"Fargate only supports network mode 'awsvpc'.\" で失敗する(2026-09-01 実 API 確認)\nviolation contains make_diag_full(\"pf-ecs-fargate-network-mode\", \"ERROR\", name,\n\t\"Properties.NetworkMode\",\n\t\"NetworkMode is not set, but task definitions requiring FARGATE compatibility must set it to 'awsvpc'; RegisterTaskDefinition fails at deploy time\",\n\t\"Set NetworkMode to 'awsvpc'\",\n\t_pf_ecsnm_url) if {\n\tsome name in resources_of_type(\"AWS::ECS::TaskDefinition\")\n\trc := resolve(name, \"Properties.RequiresCompatibilities\")\n\tis_array(rc)\n\t\"FARGATE\" in rc\n\tnot _pf_ecsnm_has_mode(name)\n}\n"
106
+ },
40
107
  {
41
108
  "id": "pf-elbv2-lb-idle-timeout-range",
42
109
  "service": "elbv2",
@@ -84,6 +151,19 @@ exports.BUNDLED_RULES = [
84
151
  ],
85
152
  "rego": "package cdk_preflight\n\nimport rego.v1\n\n_pf_inline_policy_limits := {\n\t\"AWS::IAM::Policy\": 10240,\n\t\"AWS::IAM::RolePolicy\": 10240,\n\t\"AWS::IAM::UserPolicy\": 2048,\n\t\"AWS::IAM::GroupPolicy\": 5120,\n}\n\nviolation contains make_diag_full(\"pf-iam-inline-policy-size\", \"ERROR\", name,\n\t\"Properties.PolicyDocument\",\n\tsprintf(\"PolicyDocument is %d characters (JSON without whitespace) but the inline policy limit for %s is %d (role: 10240, group: 5120, user: 2048)\", [size, rtype, limit]),\n\t\"Move statements into managed policies or shorten the document\",\n\t\"https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_iam-quotas.html\") if {\n\tsome rtype, limit in _pf_inline_policy_limits\n\tsome name in resources_of_type(rtype)\n\tdoc := resolve(name, \"Properties.PolicyDocument\")\n\tis_object(doc)\n\tsize := count(json.marshal(doc))\n\tsize > limit\n}\n"
86
153
  },
154
+ {
155
+ "id": "pf-iam-managed-policy-count",
156
+ "service": "iam",
157
+ "severity": "ERROR",
158
+ "title": "Managed policies per identity are capped (hard maximums role 25 / user 20 / group 10)",
159
+ "upstream": "none",
160
+ "resourceTypes": [
161
+ "AWS::IAM::Role",
162
+ "AWS::IAM::User",
163
+ "AWS::IAM::Group"
164
+ ],
165
+ "rego": "package cdk_preflight\n\nimport rego.v1\n\n# ハード上限(Service Quotas の「Maximum quota」= それ以上引き上げ不可能な値):\n# role 25 / user 20 / group 10(group は adjustable: false、実測でも確認)。\n# デフォルト(role 20 / user 10 / group 10)超はアカウントのクォータ引き上げ次第で\n# 成功し得るため ERROR にしない(bench アカウントの role=20 で 11 個成功を実測済み)。\n_pf_iampol_limits := {\n\t\"AWS::IAM::Role\": 25,\n\t\"AWS::IAM::User\": 20,\n\t\"AWS::IAM::Group\": 10,\n}\n\nviolation contains make_diag_full(\"pf-iam-managed-policy-count\", \"ERROR\", name,\n\t\"Properties.ManagedPolicyArns\",\n\tsprintf(\"%d managed policies are attached, but the hard maximum for %s is %d (quota defaults: role 20, user 10, group 10; raisable only up to the hard maximum); deployment fails with LimitExceeded\", [n, rtype, limit]),\n\t\"Consolidate statements into fewer managed policies\",\n\t\"https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_iam-quotas.html\") if {\n\tsome rtype, limit in _pf_iampol_limits\n\tsome name in resources_of_type(rtype)\n\tarr := resolve(name, \"Properties.ManagedPolicyArns\")\n\tis_array(arr)\n\tn := count(arr)\n\tn > limit\n}\n"
166
+ },
87
167
  {
88
168
  "id": "pf-iam-managed-policy-size",
89
169
  "service": "iam",
@@ -95,16 +175,60 @@ exports.BUNDLED_RULES = [
95
175
  ],
96
176
  "rego": "package cdk_preflight\n\nimport rego.v1\n\nviolation contains make_diag_full(\"pf-iam-managed-policy-size\", \"ERROR\", name,\n\t\"Properties.PolicyDocument\",\n\tsprintf(\"PolicyDocument is %d characters (JSON without whitespace) but the managed policy limit is 6144\", [size]),\n\t\"Split the document into multiple managed policies or shorten it\",\n\t\"https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_iam-quotas.html\") if {\n\tsome name in resources_of_type(\"AWS::IAM::ManagedPolicy\")\n\tdoc := resolve(name, \"Properties.PolicyDocument\")\n\tis_object(doc)\n\tsize := count(json.marshal(doc))\n\tsize > 6144\n}\n"
97
177
  },
178
+ {
179
+ "id": "pf-lambda-env-size",
180
+ "service": "lambda",
181
+ "severity": "ERROR",
182
+ "title": "Lambda environment variables are limited to 4096 bytes in total",
183
+ "upstream": "none",
184
+ "resourceTypes": [
185
+ "AWS::Lambda::Function"
186
+ ],
187
+ "rego": "package cdk_preflight\n\nimport rego.v1\n\n# リテラル文字列のキー/値だけを数える(トークンはスキップ)。合計が既に 4096 を超えて\n# いれば、実際のデプロイでも必ず失敗する(実サイズは推定以上にしかならない)。\n# NOTE: このエンジンの Rego パーサは内包表記内の 2 変数 some(some k, v in vars)を\n# 受け付けないため、object.keys 経由で書く。\n_pf_lenv_size(vars) := sum([s |\n\tsome k in object.keys(vars)\n\tis_string(vars[k])\n\ts := count(k) + count(vars[k])\n])\n\nviolation contains make_diag_full(\"pf-lambda-env-size\", \"ERROR\", name,\n\t\"Properties.Environment.Variables\",\n\tsprintf(\"Environment variables total at least %d bytes (literal keys and values), but Lambda limits the environment to 4096 bytes; CreateFunction fails at deploy time\", [total]),\n\t\"Move large values to SSM Parameter Store, Secrets Manager, or a bundled config file\",\n\t\"https://docs.aws.amazon.com/lambda/latest/dg/gettingstarted-limits.html\") if {\n\tsome name in resources_of_type(\"AWS::Lambda::Function\")\n\tvars := resolve(name, \"Properties.Environment.Variables\")\n\tis_object(vars)\n\ttotal := _pf_lenv_size(vars)\n\ttotal > 4096\n}\n"
188
+ },
189
+ {
190
+ "id": "pf-s3-lifecycle-days-order",
191
+ "service": "s3",
192
+ "severity": "ERROR",
193
+ "title": "Lifecycle archive transitions must come 30+ days after IA, and expiration after every transition",
194
+ "upstream": "none",
195
+ "resourceTypes": [
196
+ "AWS::S3::Bucket"
197
+ ],
198
+ "rego": "package cdk_preflight\n\nimport rego.v1\n\n_pf_s3ord_fix := \"Order the lifecycle days so archive transitions come at least 30 days after IA transitions and expiration comes after every transition\"\n\n_pf_s3ord_url := \"https://docs.aws.amazon.com/AmazonS3/latest/userguide/lifecycle-transition-general-considerations.html\"\n\nviolation contains make_diag_full(\"pf-s3-lifecycle-days-order\", \"ERROR\", name,\n\tsprintf(\"Properties.LifecycleConfiguration.Rules.%d.Transitions\", [r.index]),\n\tsprintf(\"Transition to %s at %v days is less than 30 days after the %s transition at %v days; S3 requires objects to stay at least 30 days in IA storage\", [sc2, d2, sc1, d1]),\n\t_pf_s3ord_fix, _pf_s3ord_url) if {\n\tsome name in resources_of_type(\"AWS::S3::Bucket\")\n\tsome r in flatten_list(name, \"Properties.LifecycleConfiguration.Rules\")\n\tis_object(r.value)\n\ttrans := object.get(r.value, \"Transitions\", [])\n\tis_array(trans)\n\tsome t1 in trans\n\tis_object(t1)\n\tsc1 := object.get(t1, \"StorageClass\", \"\")\n\tsc1 in {\"STANDARD_IA\", \"ONEZONE_IA\"}\n\traw1 := object.get(t1, \"TransitionInDays\", null)\n\traw1 != null # to_number(null) は 0 になる\n\td1 := to_number(raw1)\n\tsome t2 in trans\n\tis_object(t2)\n\tsc2 := object.get(t2, \"StorageClass\", \"\")\n\tsc2 in {\"GLACIER\", \"DEEP_ARCHIVE\"}\n\traw2 := object.get(t2, \"TransitionInDays\", null)\n\traw2 != null\n\td2 := to_number(raw2)\n\td2 < d1 + 30\n}\n\nviolation contains make_diag_full(\"pf-s3-lifecycle-days-order\", \"ERROR\", name,\n\tsprintf(\"Properties.LifecycleConfiguration.Rules.%d.ExpirationInDays\", [r.index]),\n\tsprintf(\"ExpirationInDays (%v) must be greater than TransitionInDays (%v); S3 rejects lifecycle rules that expire objects before or when they transition\", [e, d]),\n\t_pf_s3ord_fix, _pf_s3ord_url) if {\n\tsome name in resources_of_type(\"AWS::S3::Bucket\")\n\tsome r in flatten_list(name, \"Properties.LifecycleConfiguration.Rules\")\n\tis_object(r.value)\n\trawe := object.get(r.value, \"ExpirationInDays\", null)\n\trawe != null # to_number(null) は 0 になる\n\te := to_number(rawe)\n\ttrans := object.get(r.value, \"Transitions\", [])\n\tis_array(trans)\n\tsome t in trans\n\tis_object(t)\n\trawd := object.get(t, \"TransitionInDays\", null)\n\trawd != null\n\td := to_number(rawd)\n\te <= d\n}\n"
199
+ },
200
+ {
201
+ "id": "pf-s3-replication-requires-versioning",
202
+ "service": "s3",
203
+ "severity": "ERROR",
204
+ "title": "ReplicationConfiguration requires versioning to be enabled on the source bucket",
205
+ "upstream": "none",
206
+ "resourceTypes": [
207
+ "AWS::S3::Bucket"
208
+ ],
209
+ "rego": "package cdk_preflight\n\nimport rego.v1\n\n# Status がリテラルで \"Suspended\" 以外(= \"Enabled\")、または未解決トークンなら OK 扱い。\n# VersioningConfiguration 自体が無い / Suspended のときだけ違反にする。\n_pf_s3repl_versioning_ok(name) if {\n\ts := resolve(name, \"Properties.VersioningConfiguration.Status\")\n\tnot s == \"Suspended\"\n}\n\nviolation contains make_diag_full(\"pf-s3-replication-requires-versioning\", \"ERROR\", name,\n\t\"Properties.ReplicationConfiguration\",\n\t\"ReplicationConfiguration is set but bucket versioning is not enabled; S3 rejects the replication configuration at deploy time (InvalidRequest: Versioning must be 'Enabled' on the bucket)\",\n\t\"Set VersioningConfiguration.Status to 'Enabled' on the source bucket\",\n\t\"https://docs.aws.amazon.com/AmazonS3/latest/userguide/replication-requirements.html\") if {\n\tsome name in resources_of_type(\"AWS::S3::Bucket\")\n\tis_object(resolve(name, \"Properties.ReplicationConfiguration\"))\n\tnot _pf_s3repl_versioning_ok(name)\n}\n"
210
+ },
211
+ {
212
+ "id": "pf-sns-fifo-topic-name",
213
+ "service": "sns",
214
+ "severity": "ERROR",
215
+ "title": "FIFO topic names must end with '.fifo' (and '.fifo' names require FifoTopic)",
216
+ "upstream": "none",
217
+ "resourceTypes": [
218
+ "AWS::SNS::Topic"
219
+ ],
220
+ "rego": "package cdk_preflight\n\nimport rego.v1\n\n_pf_snsfifo_fix := \"Give FIFO topics a TopicName ending in '.fifo' (or drop TopicName to let CloudFormation generate one), and set FifoTopic: true whenever the name ends in '.fifo'\"\n\n_pf_snsfifo_url := \"https://docs.aws.amazon.com/sns/latest/dg/sns-create-fifo-topic.html\"\n\n_pf_snsfifo_true(name) if resolve(name, \"Properties.FifoTopic\") in {true, \"true\"}\n\n# FifoTopic が存在し、リテラル false 以外(true やトークン)なら「FIFO かもしれない」扱い\n_pf_snsfifo_maybe_fifo(name) if {\n\tv := resolve(name, \"Properties.FifoTopic\")\n\tnot v in {false, \"false\"}\n}\n\nviolation contains make_diag_full(\"pf-sns-fifo-topic-name\", \"ERROR\", name,\n\t\"Properties.TopicName\",\n\tsprintf(\"FifoTopic is true but TopicName '%s' does not end with '.fifo'; SNS rejects the topic at deploy time\", [tn]),\n\t_pf_snsfifo_fix, _pf_snsfifo_url) if {\n\tsome name in resources_of_type(\"AWS::SNS::Topic\")\n\t_pf_snsfifo_true(name)\n\ttn := resolve(name, \"Properties.TopicName\")\n\tis_string(tn)\n\tnot endswith(tn, \".fifo\")\n}\n\nviolation contains make_diag_full(\"pf-sns-fifo-topic-name\", \"ERROR\", name,\n\t\"Properties.TopicName\",\n\tsprintf(\"TopicName '%s' ends with '.fifo' but FifoTopic is not true; SNS rejects the topic name at deploy time\", [tn]),\n\t_pf_snsfifo_fix, _pf_snsfifo_url) if {\n\tsome name in resources_of_type(\"AWS::SNS::Topic\")\n\ttn := resolve(name, \"Properties.TopicName\")\n\tis_string(tn)\n\tendswith(tn, \".fifo\")\n\tnot _pf_snsfifo_maybe_fifo(name)\n}\n"
221
+ },
98
222
  {
99
223
  "id": "pf-sfn-asl-missing-state",
100
224
  "service": "stepfunctions",
101
225
  "severity": "ERROR",
102
- "title": "ASL StartAt/Next/Default/Choices must reference a defined state (top-level states)",
226
+ "title": "ASL Next/Default/Choices must reference a defined state (top-level states; a dangling StartAt is covered by engine rule E3601)",
103
227
  "upstream": "none",
104
228
  "resourceTypes": [
105
229
  "AWS::StepFunctions::StateMachine"
106
230
  ],
107
- "rego": "package cdk_preflight\n\nimport rego.v1\n\n_pf_sfn_fix := \"Point StartAt/Next/Default at an existing state name\"\n\n_pf_sfn_url := \"https://docs.aws.amazon.com/step-functions/latest/dg/amazon-states-language-states.html\"\n\n_pf_sfn_asl(name) := asl if {\n\tdef := resolve(name, \"Properties.DefinitionString\")\n\tis_string(def)\n\tasl := json.unmarshal(def)\n\tis_object(asl)\n}\n\n_pf_sfn_defined(asl) := {sn | some sn, _ in object.get(asl, \"States\", {})}\n\nviolation contains make_diag_full(\"pf-sfn-asl-missing-state\", \"ERROR\", name,\n\t\"Properties.DefinitionString\",\n\tsprintf(\"state machine definition references state '%s' via StartAt, but no state with that name is defined\", [target]),\n\t_pf_sfn_fix, _pf_sfn_url) if {\n\tsome name in resources_of_type(\"AWS::StepFunctions::StateMachine\")\n\tasl := _pf_sfn_asl(name)\n\ttarget := object.get(asl, \"StartAt\", null)\n\tis_string(target)\n\tnot target in _pf_sfn_defined(asl)\n}\n\nviolation contains make_diag_full(\"pf-sfn-asl-missing-state\", \"ERROR\", name,\n\t\"Properties.DefinitionString\",\n\tsprintf(\"state '%s' references state '%s' via %s, but no state with that name is defined\", [sname, target, key]),\n\t_pf_sfn_fix, _pf_sfn_url) if {\n\tsome name in resources_of_type(\"AWS::StepFunctions::StateMachine\")\n\tasl := _pf_sfn_asl(name)\n\tsome sname, st in object.get(asl, \"States\", {})\n\tis_object(st)\n\tsome key in {\"Next\", \"Default\"}\n\ttarget := object.get(st, key, null)\n\tis_string(target)\n\tnot target in _pf_sfn_defined(asl)\n}\n\nviolation contains make_diag_full(\"pf-sfn-asl-missing-state\", \"ERROR\", name,\n\t\"Properties.DefinitionString\",\n\tsprintf(\"state '%s' has a Choice rule referencing state '%s', but no state with that name is defined\", [sname, target]),\n\t_pf_sfn_fix, _pf_sfn_url) if {\n\tsome name in resources_of_type(\"AWS::StepFunctions::StateMachine\")\n\tasl := _pf_sfn_asl(name)\n\tsome sname, st in object.get(asl, \"States\", {})\n\tis_object(st)\n\tchoices := object.get(st, \"Choices\", [])\n\tis_array(choices)\n\tsome c in choices\n\tis_object(c)\n\ttarget := object.get(c, \"Next\", null)\n\tis_string(target)\n\tnot target in _pf_sfn_defined(asl)\n}\n"
231
+ "rego": "package cdk_preflight\n\nimport rego.v1\n\n_pf_sfn_fix := \"Point Next/Default/Choices at an existing state name\"\n\n_pf_sfn_url := \"https://docs.aws.amazon.com/step-functions/latest/dg/amazon-states-language-states.html\"\n\n_pf_sfn_asl(name) := asl if {\n\tdef := resolve(name, \"Properties.DefinitionString\")\n\tis_string(def)\n\tasl := json.unmarshal(def)\n\tis_object(asl)\n}\n\n_pf_sfn_defined(asl) := {sn | some sn, _ in object.get(asl, \"States\", {})}\n\n# NOTE: a dangling StartAt is deliberately NOT checked here — the engine's\n# built-in rule E3601 (ERROR/CFN_LINT) already covers it. Verified against\n# @aws/cloudformation-validate 1.7.0-beta on 2026-09-01: E3601 fires for\n# StartAt only and does not check Next/Default/Choices, which is what this\n# rule adds.\n\nviolation contains make_diag_full(\"pf-sfn-asl-missing-state\", \"ERROR\", name,\n\t\"Properties.DefinitionString\",\n\tsprintf(\"state '%s' references state '%s' via %s, but no state with that name is defined\", [sname, target, key]),\n\t_pf_sfn_fix, _pf_sfn_url) if {\n\tsome name in resources_of_type(\"AWS::StepFunctions::StateMachine\")\n\tasl := _pf_sfn_asl(name)\n\tsome sname, st in object.get(asl, \"States\", {})\n\tis_object(st)\n\tsome key in {\"Next\", \"Default\"}\n\ttarget := object.get(st, key, null)\n\tis_string(target)\n\tnot target in _pf_sfn_defined(asl)\n}\n\nviolation contains make_diag_full(\"pf-sfn-asl-missing-state\", \"ERROR\", name,\n\t\"Properties.DefinitionString\",\n\tsprintf(\"state '%s' has a Choice rule referencing state '%s', but no state with that name is defined\", [sname, target]),\n\t_pf_sfn_fix, _pf_sfn_url) if {\n\tsome name in resources_of_type(\"AWS::StepFunctions::StateMachine\")\n\tasl := _pf_sfn_asl(name)\n\tsome sname, st in object.get(asl, \"States\", {})\n\tis_object(st)\n\tchoices := object.get(st, \"Choices\", [])\n\tis_array(choices)\n\tsome c in choices\n\tis_object(c)\n\ttarget := object.get(c, \"Next\", null)\n\tis_string(target)\n\tnot target in _pf_sfn_defined(asl)\n}\n"
108
232
  }
109
233
  ];
110
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicnVsZXMuZ2VuZXJhdGVkLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL3J1bGVzLmdlbmVyYXRlZC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFhYSxRQUFBLGFBQWEsR0FBc0I7SUFDOUM7UUFDRSxJQUFJLEVBQUUsK0JBQStCO1FBQ3JDLFNBQVMsRUFBRSxZQUFZO1FBQ3ZCLFVBQVUsRUFBRSxPQUFPO1FBQ25CLE9BQU8sRUFBRSx1REFBdUQ7UUFDaEUsVUFBVSxFQUFFLE1BQU07UUFDbEIsZUFBZSxFQUFFO1lBQ2YsK0JBQStCO1NBQ2hDO1FBQ0QsTUFBTSxFQUFFLDY2QkFBNjZCO0tBQ3Q3QjtJQUNEO1FBQ0UsSUFBSSxFQUFFLHlCQUF5QjtRQUMvQixTQUFTLEVBQUUsWUFBWTtRQUN2QixVQUFVLEVBQUUsT0FBTztRQUNuQixPQUFPLEVBQUUsaUVBQWlFO1FBQzFFLFVBQVUsRUFBRSxNQUFNO1FBQ2xCLGVBQWUsRUFBRTtZQUNmLCtCQUErQjtTQUNoQztRQUNELE1BQU0sRUFBRSxnaUVBQWdpRTtLQUN6aUU7SUFDRDtRQUNFLElBQUksRUFBRSxzQkFBc0I7UUFDNUIsU0FBUyxFQUFFLEtBQUs7UUFDaEIsVUFBVSxFQUFFLE9BQU87UUFDbkIsT0FBTyxFQUFFLDRFQUE0RTtRQUNyRixVQUFVLEVBQUUsTUFBTTtRQUNsQixlQUFlLEVBQUU7WUFDZix5QkFBeUI7WUFDekIsZ0NBQWdDO1lBQ2hDLCtCQUErQjtTQUNoQztRQUNELE1BQU0sRUFBRSxveUZBQW95RjtLQUM3eUY7SUFDRDtRQUNFLElBQUksRUFBRSxnQ0FBZ0M7UUFDdEMsU0FBUyxFQUFFLE9BQU87UUFDbEIsVUFBVSxFQUFFLE9BQU87UUFDbkIsT0FBTyxFQUFFLDZEQUE2RDtRQUN0RSxVQUFVLEVBQUUsTUFBTTtRQUNsQixlQUFlLEVBQUU7WUFDZiwyQ0FBMkM7U0FDNUM7UUFDRCxNQUFNLEVBQUUsdWlDQUF1aUM7S0FDaGpDO0lBQ0Q7UUFDRSxJQUFJLEVBQUUsd0NBQXdDO1FBQzlDLFNBQVMsRUFBRSxPQUFPO1FBQ2xCLFVBQVUsRUFBRSxPQUFPO1FBQ25CLE9BQU8sRUFBRSw4RUFBOEU7UUFDdkYsVUFBVSxFQUFFLE1BQU07UUFDbEIsZUFBZSxFQUFFO1lBQ2YsMENBQTBDO1NBQzNDO1FBQ0QsTUFBTSxFQUFFLHU4QkFBdThCO0tBQ2g5QjtJQUNEO1FBQ0UsSUFBSSxFQUFFLDhCQUE4QjtRQUNwQyxTQUFTLEVBQUUsT0FBTztRQUNsQixVQUFVLEVBQUUsT0FBTztRQUNuQixPQUFPLEVBQUUsMEVBQTBFO1FBQ25GLFVBQVUsRUFBRSxNQUFNO1FBQ2xCLGVBQWUsRUFBRTtZQUNmLDBDQUEwQztTQUMzQztRQUNELE1BQU0sRUFBRSxrK0JBQWsrQjtLQUMzK0I7SUFDRDtRQUNFLElBQUksRUFBRSwyQkFBMkI7UUFDakMsU0FBUyxFQUFFLEtBQUs7UUFDaEIsVUFBVSxFQUFFLE9BQU87UUFDbkIsT0FBTyxFQUFFLG1HQUFtRztRQUM1RyxVQUFVLEVBQUUsTUFBTTtRQUNsQixlQUFlLEVBQUU7WUFDZixrQkFBa0I7WUFDbEIsc0JBQXNCO1lBQ3RCLHNCQUFzQjtZQUN0Qix1QkFBdUI7U0FDeEI7UUFDRCxNQUFNLEVBQUUsMDNCQUEwM0I7S0FDbjRCO0lBQ0Q7UUFDRSxJQUFJLEVBQUUsNEJBQTRCO1FBQ2xDLFNBQVMsRUFBRSxLQUFLO1FBQ2hCLFVBQVUsRUFBRSxPQUFPO1FBQ25CLE9BQU8sRUFBRSwrRUFBK0U7UUFDeEYsVUFBVSxFQUFFLE1BQU07UUFDbEIsZUFBZSxFQUFFO1lBQ2YseUJBQXlCO1NBQzFCO1FBQ0QsTUFBTSxFQUFFLHluQkFBeW5CO0tBQ2xvQjtJQUNEO1FBQ0UsSUFBSSxFQUFFLDBCQUEwQjtRQUNoQyxTQUFTLEVBQUUsZUFBZTtRQUMxQixVQUFVLEVBQUUsT0FBTztRQUNuQixPQUFPLEVBQUUsb0ZBQW9GO1FBQzdGLFVBQVUsRUFBRSxNQUFNO1FBQ2xCLGVBQWUsRUFBRTtZQUNmLGtDQUFrQztTQUNuQztRQUNELE1BQU0sRUFBRSx1cEVBQXVwRTtLQUNocUU7Q0FDRixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLy8gfn4gR2VuZXJhdGVkIGJ5IHNjcmlwdHMvYnVuZGxlLXJ1bGVzLnRzIGZyb20gcnVsZXMvKiouIERvIG5vdCBlZGl0IGJ5IGhhbmQuXG4vLyB+fiBSZWdlbmVyYXRlIHdpdGg6IG5weCBwcm9qZW4gYnVuZGxlLXJ1bGVzXG4vKiBlc2xpbnQtZGlzYWJsZSAqL1xuZXhwb3J0IGludGVyZmFjZSBCdW5kbGVkUnVsZURhdGEge1xuICByZWFkb25seSBpZDogc3RyaW5nO1xuICByZWFkb25seSBzZXJ2aWNlOiBzdHJpbmc7XG4gIHJlYWRvbmx5IHNldmVyaXR5OiBzdHJpbmc7XG4gIHJlYWRvbmx5IHRpdGxlOiBzdHJpbmc7XG4gIHJlYWRvbmx5IHVwc3RyZWFtOiBzdHJpbmc7XG4gIHJlYWRvbmx5IHJlc291cmNlVHlwZXM6IHN0cmluZ1tdO1xuICByZWFkb25seSByZWdvOiBzdHJpbmc7XG59XG5cbmV4cG9ydCBjb25zdCBCVU5ETEVEX1JVTEVTOiBCdW5kbGVkUnVsZURhdGFbXSA9IFtcbiAge1xuICAgIFwiaWRcIjogXCJwZi1jbG91ZGZyb250LWFjbS1jZXJ0LXJlZ2lvblwiLFxuICAgIFwic2VydmljZVwiOiBcImNsb3VkZnJvbnRcIixcbiAgICBcInNldmVyaXR5XCI6IFwiRVJST1JcIixcbiAgICBcInRpdGxlXCI6IFwiQ2xvdWRGcm9udCB2aWV3ZXIgY2VydGlmaWNhdGVzIG11c3QgbGl2ZSBpbiB1cy1lYXN0LTFcIixcbiAgICBcInVwc3RyZWFtXCI6IFwibm9uZVwiLFxuICAgIFwicmVzb3VyY2VUeXBlc1wiOiBbXG4gICAgICBcIkFXUzo6Q2xvdWRGcm9udDo6RGlzdHJpYnV0aW9uXCJcbiAgICBdLFxuICAgIFwicmVnb1wiOiBcInBhY2thZ2UgY2RrX3ByZWZsaWdodFxcblxcbmltcG9ydCByZWdvLnYxXFxuXFxudmlvbGF0aW9uIGNvbnRhaW5zIG1ha2VfZGlhZ19mdWxsKFxcXCJwZi1jbG91ZGZyb250LWFjbS1jZXJ0LXJlZ2lvblxcXCIsIFxcXCJFUlJPUlxcXCIsIG5hbWUsXFxuXFx0XFxcIlByb3BlcnRpZXMuRGlzdHJpYnV0aW9uQ29uZmlnLlZpZXdlckNlcnRpZmljYXRlLkFjbUNlcnRpZmljYXRlQXJuXFxcIixcXG5cXHRzcHJpbnRmKFxcXCJDbG91ZEZyb250IHJlcXVpcmVzIHRoZSBBQ00gY2VydGlmaWNhdGUgdG8gYmUgaW4gdXMtZWFzdC0xLCBidXQgdGhlIGNlcnRpZmljYXRlIGlzIGluICVzXFxcIiwgW3JlZ2lvbl0pLFxcblxcdFxcXCJJc3N1ZSBvciBpbXBvcnQgdGhlIGNlcnRpZmljYXRlIGluIHVzLWVhc3QtMSAoZS5nLiBhIGRlZGljYXRlZCB1cy1lYXN0LTEgc3RhY2spIGFuZCByZWZlcmVuY2UgdGhhdCBBUk5cXFwiLFxcblxcdFxcXCJodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uQ2xvdWRGcm9udC9sYXRlc3QvRGV2ZWxvcGVyR3VpZGUvY25hbWVzLWFuZC1odHRwcy1yZXF1aXJlbWVudHMuaHRtbCNodHRwcy1yZXF1aXJlbWVudHMtY2VydGlmaWNhdGUtaXNzdWVyXFxcIikgaWYge1xcblxcdHNvbWUgbmFtZSBpbiByZXNvdXJjZXNfb2ZfdHlwZShcXFwiQVdTOjpDbG91ZEZyb250OjpEaXN0cmlidXRpb25cXFwiKVxcblxcdGFybiA6PSByZXNvbHZlKG5hbWUsIFxcXCJQcm9wZXJ0aWVzLkRpc3RyaWJ1dGlvbkNvbmZpZy5WaWV3ZXJDZXJ0aWZpY2F0ZS5BY21DZXJ0aWZpY2F0ZUFyblxcXCIpXFxuXFx0aXNfc3RyaW5nKGFybilcXG5cXHRzdGFydHN3aXRoKGFybiwgXFxcImFybjpcXFwiKVxcblxcdHBhcnRzIDo9IHNwbGl0KGFybiwgXFxcIjpcXFwiKVxcblxcdGNvdW50KHBhcnRzKSA+PSA2XFxuXFx0cGFydHNbMl0gPT0gXFxcImFjbVxcXCJcXG5cXHRyZWdpb24gOj0gcGFydHNbM11cXG5cXHRyZWdpb24gIT0gXFxcIlxcXCJcXG5cXHRyZWdpb24gIT0gXFxcInVzLWVhc3QtMVxcXCJcXG59XFxuXCJcbiAgfSxcbiAge1xuICAgIFwiaWRcIjogXCJwZi1jbG91ZGZyb250LXR0bC1vcmRlclwiLFxuICAgIFwic2VydmljZVwiOiBcImNsb3VkZnJvbnRcIixcbiAgICBcInNldmVyaXR5XCI6IFwiRVJST1JcIixcbiAgICBcInRpdGxlXCI6IFwiQ2FjaGUgYmVoYXZpb3IgVFRMcyBtdXN0IHNhdGlzZnkgTWluVFRMIDw9IERlZmF1bHRUVEwgPD0gTWF4VFRMXCIsXG4gICAgXCJ1cHN0cmVhbVwiOiBcIm5vbmVcIixcbiAgICBcInJlc291cmNlVHlwZXNcIjogW1xuICAgICAgXCJBV1M6OkNsb3VkRnJvbnQ6OkRpc3RyaWJ1dGlvblwiXG4gICAgXSxcbiAgICBcInJlZ29cIjogXCJwYWNrYWdlIGNka19wcmVmbGlnaHRcXG5cXG5pbXBvcnQgcmVnby52MVxcblxcbl9wZl9jZl90dGxfZml4IDo9IFxcXCJPcmRlciB0aGUgVFRMcyBhcyBNaW5UVEwgPD0gRGVmYXVsdFRUTCA8PSBNYXhUVExcXFwiXFxuXFxuX3BmX2NmX3R0bF91cmwgOj0gXFxcImh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BbWF6b25DbG91ZEZyb250L2xhdGVzdC9EZXZlbG9wZXJHdWlkZS9FeHBpcmF0aW9uLmh0bWxcXFwiXFxuXFxuX3BmX2NmX2JlaGF2aW9ycyhuYW1lKSA6PSBhcnJheS5jb25jYXQoXFxuXFx0W3tcXFwicGF0aFxcXCI6IFxcXCJQcm9wZXJ0aWVzLkRpc3RyaWJ1dGlvbkNvbmZpZy5EZWZhdWx0Q2FjaGVCZWhhdmlvclxcXCIsIFxcXCJ2YWx1ZVxcXCI6IGl0LnZhbHVlfSB8XFxuXFx0XFx0c29tZSBpdCBpbiBmbGF0dGVuX2xpc3QobmFtZSwgXFxcIlByb3BlcnRpZXMuRGlzdHJpYnV0aW9uQ29uZmlnLkRlZmF1bHRDYWNoZUJlaGF2aW9yXFxcIildLFxcblxcdFt7XFxcInBhdGhcXFwiOiBzcHJpbnRmKFxcXCJQcm9wZXJ0aWVzLkRpc3RyaWJ1dGlvbkNvbmZpZy5DYWNoZUJlaGF2aW9ycy4lZFxcXCIsIFtpdC5pbmRleF0pLCBcXFwidmFsdWVcXFwiOiBpdC52YWx1ZX0gfFxcblxcdFxcdHNvbWUgaXQgaW4gZmxhdHRlbl9saXN0KG5hbWUsIFxcXCJQcm9wZXJ0aWVzLkRpc3RyaWJ1dGlvbkNvbmZpZy5DYWNoZUJlaGF2aW9yc1xcXCIpXSxcXG4pXFxuXFxudmlvbGF0aW9uIGNvbnRhaW5zIG1ha2VfZGlhZ19mdWxsKFxcXCJwZi1jbG91ZGZyb250LXR0bC1vcmRlclxcXCIsIFxcXCJFUlJPUlxcXCIsIG5hbWUsIGIucGF0aCxcXG5cXHRzcHJpbnRmKFxcXCJNaW5UVEwgKCV2KSBtdXN0IGJlIGxlc3MgdGhhbiBvciBlcXVhbCB0byBNYXhUVEwgKCV2KVxcXCIsIFttbiwgbXhdKSxcXG5cXHRfcGZfY2ZfdHRsX2ZpeCwgX3BmX2NmX3R0bF91cmwpIGlmIHtcXG5cXHRzb21lIG5hbWUgaW4gcmVzb3VyY2VzX29mX3R5cGUoXFxcIkFXUzo6Q2xvdWRGcm9udDo6RGlzdHJpYnV0aW9uXFxcIilcXG5cXHRzb21lIGIgaW4gX3BmX2NmX2JlaGF2aW9ycyhuYW1lKVxcblxcdGlzX29iamVjdChiLnZhbHVlKVxcblxcdG1uIDo9IHRvX251bWJlcihvYmplY3QuZ2V0KGIudmFsdWUsIFxcXCJNaW5UVExcXFwiLCBudWxsKSlcXG5cXHRteCA6PSB0b19udW1iZXIob2JqZWN0LmdldChiLnZhbHVlLCBcXFwiTWF4VFRMXFxcIiwgbnVsbCkpXFxuXFx0bW4gPiBteFxcbn1cXG5cXG52aW9sYXRpb24gY29udGFpbnMgbWFrZV9kaWFnX2Z1bGwoXFxcInBmLWNsb3VkZnJvbnQtdHRsLW9yZGVyXFxcIiwgXFxcIkVSUk9SXFxcIiwgbmFtZSwgYi5wYXRoLFxcblxcdHNwcmludGYoXFxcIk1pblRUTCAoJXYpIG11c3QgYmUgbGVzcyB0aGFuIG9yIGVxdWFsIHRvIERlZmF1bHRUVEwgKCV2KVxcXCIsIFttbiwgZGZdKSxcXG5cXHRfcGZfY2ZfdHRsX2ZpeCwgX3BmX2NmX3R0bF91cmwpIGlmIHtcXG5cXHRzb21lIG5hbWUgaW4gcmVzb3VyY2VzX29mX3R5cGUoXFxcIkFXUzo6Q2xvdWRGcm9udDo6RGlzdHJpYnV0aW9uXFxcIilcXG5cXHRzb21lIGIgaW4gX3BmX2NmX2JlaGF2aW9ycyhuYW1lKVxcblxcdGlzX29iamVjdChiLnZhbHVlKVxcblxcdG1uIDo9IHRvX251bWJlcihvYmplY3QuZ2V0KGIudmFsdWUsIFxcXCJNaW5UVExcXFwiLCBudWxsKSlcXG5cXHRkZiA6PSB0b19udW1iZXIob2JqZWN0LmdldChiLnZhbHVlLCBcXFwiRGVmYXVsdFRUTFxcXCIsIG51bGwpKVxcblxcdG1uID4gZGZcXG59XFxuXFxudmlvbGF0aW9uIGNvbnRhaW5zIG1ha2VfZGlhZ19mdWxsKFxcXCJwZi1jbG91ZGZyb250LXR0bC1vcmRlclxcXCIsIFxcXCJFUlJPUlxcXCIsIG5hbWUsIGIucGF0aCxcXG5cXHRzcHJpbnRmKFxcXCJEZWZhdWx0VFRMICgldikgbXVzdCBiZSBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gTWF4VFRMICgldilcXFwiLCBbZGYsIG14XSksXFxuXFx0X3BmX2NmX3R0bF9maXgsIF9wZl9jZl90dGxfdXJsKSBpZiB7XFxuXFx0c29tZSBuYW1lIGluIHJlc291cmNlc19vZl90eXBlKFxcXCJBV1M6OkNsb3VkRnJvbnQ6OkRpc3RyaWJ1dGlvblxcXCIpXFxuXFx0c29tZSBiIGluIF9wZl9jZl9iZWhhdmlvcnMobmFtZSlcXG5cXHRpc19vYmplY3QoYi52YWx1ZSlcXG5cXHRkZiA6PSB0b19udW1iZXIob2JqZWN0LmdldChiLnZhbHVlLCBcXFwiRGVmYXVsdFRUTFxcXCIsIG51bGwpKVxcblxcdG14IDo9IHRvX251bWJlcihvYmplY3QuZ2V0KGIudmFsdWUsIFxcXCJNYXhUVExcXFwiLCBudWxsKSlcXG5cXHRkZiA+IG14XFxufVxcblwiXG4gIH0sXG4gIHtcbiAgICBcImlkXCI6IFwicGYtZWMyLXNnLXBvcnQtcmFuZ2VcIixcbiAgICBcInNlcnZpY2VcIjogXCJlYzJcIixcbiAgICBcInNldmVyaXR5XCI6IFwiRVJST1JcIixcbiAgICBcInRpdGxlXCI6IFwiU2VjdXJpdHkgZ3JvdXAgVENQL1VEUCBwb3J0cyBtdXN0IGJlIHdpdGhpbiAwLTY1NTM1IGFuZCBGcm9tUG9ydCA8PSBUb1BvcnRcIixcbiAgICBcInVwc3RyZWFtXCI6IFwibm9uZVwiLFxuICAgIFwicmVzb3VyY2VUeXBlc1wiOiBbXG4gICAgICBcIkFXUzo6RUMyOjpTZWN1cml0eUdyb3VwXCIsXG4gICAgICBcIkFXUzo6RUMyOjpTZWN1cml0eUdyb3VwSW5ncmVzc1wiLFxuICAgICAgXCJBV1M6OkVDMjo6U2VjdXJpdHlHcm91cEVncmVzc1wiXG4gICAgXSxcbiAgICBcInJlZ29cIjogXCJwYWNrYWdlIGNka19wcmVmbGlnaHRcXG5cXG5pbXBvcnQgcmVnby52MVxcblxcbl9wZl9zZ19maXggOj0gXFxcIlVzZSBhIHBvcnQgYmV0d2VlbiAwIGFuZCA2NTUzNSB3aXRoIEZyb21Qb3J0IDw9IFRvUG9ydFxcXCJcXG5cXG5fcGZfc2dfdXJsIDo9IFxcXCJodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTRUMyL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0F1dGhvcml6ZVNlY3VyaXR5R3JvdXBJbmdyZXNzLmh0bWxcXFwiXFxuXFxuX3BmX3BvcnRfb3V0KG4pIGlmIG4gPCAwXFxuXFxuX3BmX3BvcnRfb3V0KG4pIGlmIG4gPiA2NTUzNVxcblxcbl9wZl90Y3BfdWRwKHApIGlmIHAgaW4ge1xcXCJ0Y3BcXFwiLCBcXFwidWRwXFxcIiwgXFxcIjZcXFwiLCBcXFwiMTdcXFwiLCA2LCAxN31cXG5cXG52aW9sYXRpb24gY29udGFpbnMgbWFrZV9kaWFnX2Z1bGwoXFxcInBmLWVjMi1zZy1wb3J0LXJhbmdlXFxcIiwgXFxcIkVSUk9SXFxcIiwgbmFtZSxcXG5cXHRzcHJpbnRmKFxcXCJQcm9wZXJ0aWVzLiVzLiVkLiVzXFxcIiwgW2RpciwgaXRlbS5pbmRleCwgcG5hbWVdKSxcXG5cXHRzcHJpbnRmKFxcXCIlcyAldiBpcyBvdXRzaWRlIHRoZSB2YWxpZCBUQ1AvVURQIHBvcnQgcmFuZ2UgMC02NTUzNVxcXCIsIFtwbmFtZSwgbl0pLFxcblxcdF9wZl9zZ19maXgsIF9wZl9zZ191cmwpIGlmIHtcXG5cXHRzb21lIG5hbWUgaW4gcmVzb3VyY2VzX29mX3R5cGUoXFxcIkFXUzo6RUMyOjpTZWN1cml0eUdyb3VwXFxcIilcXG5cXHRzb21lIGRpciBpbiB7XFxcIlNlY3VyaXR5R3JvdXBJbmdyZXNzXFxcIiwgXFxcIlNlY3VyaXR5R3JvdXBFZ3Jlc3NcXFwifVxcblxcdHNvbWUgaXRlbSBpbiBmbGF0dGVuX2xpc3QobmFtZSwgc3ByaW50ZihcXFwiUHJvcGVydGllcy4lc1xcXCIsIFtkaXJdKSlcXG5cXHRlbnRyeSA6PSBpdGVtLnZhbHVlXFxuXFx0aXNfb2JqZWN0KGVudHJ5KVxcblxcdF9wZl90Y3BfdWRwKG9iamVjdC5nZXQoZW50cnksIFxcXCJJcFByb3RvY29sXFxcIiwgbnVsbCkpXFxuXFx0c29tZSBwbmFtZSBpbiB7XFxcIkZyb21Qb3J0XFxcIiwgXFxcIlRvUG9ydFxcXCJ9XFxuXFx0biA6PSB0b19udW1iZXIob2JqZWN0LmdldChlbnRyeSwgcG5hbWUsIG51bGwpKVxcblxcdF9wZl9wb3J0X291dChuKVxcbn1cXG5cXG52aW9sYXRpb24gY29udGFpbnMgbWFrZV9kaWFnX2Z1bGwoXFxcInBmLWVjMi1zZy1wb3J0LXJhbmdlXFxcIiwgXFxcIkVSUk9SXFxcIiwgbmFtZSxcXG5cXHRzcHJpbnRmKFxcXCJQcm9wZXJ0aWVzLiVzLiVkLkZyb21Qb3J0XFxcIiwgW2RpciwgaXRlbS5pbmRleF0pLFxcblxcdHNwcmludGYoXFxcIkZyb21Qb3J0ICgldikgbXVzdCBiZSBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gVG9Qb3J0ICgldilcXFwiLCBbZiwgdF0pLFxcblxcdF9wZl9zZ19maXgsIF9wZl9zZ191cmwpIGlmIHtcXG5cXHRzb21lIG5hbWUgaW4gcmVzb3VyY2VzX29mX3R5cGUoXFxcIkFXUzo6RUMyOjpTZWN1cml0eUdyb3VwXFxcIilcXG5cXHRzb21lIGRpciBpbiB7XFxcIlNlY3VyaXR5R3JvdXBJbmdyZXNzXFxcIiwgXFxcIlNlY3VyaXR5R3JvdXBFZ3Jlc3NcXFwifVxcblxcdHNvbWUgaXRlbSBpbiBmbGF0dGVuX2xpc3QobmFtZSwgc3ByaW50ZihcXFwiUHJvcGVydGllcy4lc1xcXCIsIFtkaXJdKSlcXG5cXHRlbnRyeSA6PSBpdGVtLnZhbHVlXFxuXFx0aXNfb2JqZWN0KGVudHJ5KVxcblxcdF9wZl90Y3BfdWRwKG9iamVjdC5nZXQoZW50cnksIFxcXCJJcFByb3RvY29sXFxcIiwgbnVsbCkpXFxuXFx0ZiA6PSB0b19udW1iZXIob2JqZWN0LmdldChlbnRyeSwgXFxcIkZyb21Qb3J0XFxcIiwgbnVsbCkpXFxuXFx0dCA6PSB0b19udW1iZXIob2JqZWN0LmdldChlbnRyeSwgXFxcIlRvUG9ydFxcXCIsIG51bGwpKVxcblxcdGYgPj0gMFxcblxcdHQgPD0gNjU1MzVcXG5cXHRmID4gdFxcbn1cXG5cXG52aW9sYXRpb24gY29udGFpbnMgbWFrZV9kaWFnX2Z1bGwoXFxcInBmLWVjMi1zZy1wb3J0LXJhbmdlXFxcIiwgXFxcIkVSUk9SXFxcIiwgbmFtZSxcXG5cXHRzcHJpbnRmKFxcXCJQcm9wZXJ0aWVzLiVzXFxcIiwgW3BuYW1lXSksXFxuXFx0c3ByaW50ZihcXFwiJXMgJXYgaXMgb3V0c2lkZSB0aGUgdmFsaWQgVENQL1VEUCBwb3J0IHJhbmdlIDAtNjU1MzVcXFwiLCBbcG5hbWUsIG5dKSxcXG5cXHRfcGZfc2dfZml4LCBfcGZfc2dfdXJsKSBpZiB7XFxuXFx0c29tZSBydHlwZSBpbiB7XFxcIkFXUzo6RUMyOjpTZWN1cml0eUdyb3VwSW5ncmVzc1xcXCIsIFxcXCJBV1M6OkVDMjo6U2VjdXJpdHlHcm91cEVncmVzc1xcXCJ9XFxuXFx0c29tZSBuYW1lIGluIHJlc291cmNlc19vZl90eXBlKHJ0eXBlKVxcblxcdF9wZl90Y3BfdWRwKHJlc29sdmUobmFtZSwgXFxcIlByb3BlcnRpZXMuSXBQcm90b2NvbFxcXCIpKVxcblxcdHNvbWUgcG5hbWUgaW4ge1xcXCJGcm9tUG9ydFxcXCIsIFxcXCJUb1BvcnRcXFwifVxcblxcdG4gOj0gdG9fbnVtYmVyKHJlc29sdmUobmFtZSwgc3ByaW50ZihcXFwiUHJvcGVydGllcy4lc1xcXCIsIFtwbmFtZV0pKSlcXG5cXHRfcGZfcG9ydF9vdXQobilcXG59XFxuXFxudmlvbGF0aW9uIGNvbnRhaW5zIG1ha2VfZGlhZ19mdWxsKFxcXCJwZi1lYzItc2ctcG9ydC1yYW5nZVxcXCIsIFxcXCJFUlJPUlxcXCIsIG5hbWUsXFxuXFx0XFxcIlByb3BlcnRpZXMuRnJvbVBvcnRcXFwiLFxcblxcdHNwcmludGYoXFxcIkZyb21Qb3J0ICgldikgbXVzdCBiZSBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gVG9Qb3J0ICgldilcXFwiLCBbZiwgdF0pLFxcblxcdF9wZl9zZ19maXgsIF9wZl9zZ191cmwpIGlmIHtcXG5cXHRzb21lIHJ0eXBlIGluIHtcXFwiQVdTOjpFQzI6OlNlY3VyaXR5R3JvdXBJbmdyZXNzXFxcIiwgXFxcIkFXUzo6RUMyOjpTZWN1cml0eUdyb3VwRWdyZXNzXFxcIn1cXG5cXHRzb21lIG5hbWUgaW4gcmVzb3VyY2VzX29mX3R5cGUocnR5cGUpXFxuXFx0X3BmX3RjcF91ZHAocmVzb2x2ZShuYW1lLCBcXFwiUHJvcGVydGllcy5JcFByb3RvY29sXFxcIikpXFxuXFx0ZiA6PSB0b19udW1iZXIocmVzb2x2ZShuYW1lLCBcXFwiUHJvcGVydGllcy5Gcm9tUG9ydFxcXCIpKVxcblxcdHQgOj0gdG9fbnVtYmVyKHJlc29sdmUobmFtZSwgXFxcIlByb3BlcnRpZXMuVG9Qb3J0XFxcIikpXFxuXFx0ZiA+PSAwXFxuXFx0dCA8PSA2NTUzNVxcblxcdGYgPiB0XFxufVxcblwiXG4gIH0sXG4gIHtcbiAgICBcImlkXCI6IFwicGYtZWxidjItbGItaWRsZS10aW1lb3V0LXJhbmdlXCIsXG4gICAgXCJzZXJ2aWNlXCI6IFwiZWxidjJcIixcbiAgICBcInNldmVyaXR5XCI6IFwiRVJST1JcIixcbiAgICBcInRpdGxlXCI6IFwiQUxCIGlkbGVfdGltZW91dC50aW1lb3V0X3NlY29uZHMgbXVzdCBiZSBiZXR3ZWVuIDEgYW5kIDQwMDBcIixcbiAgICBcInVwc3RyZWFtXCI6IFwibm9uZVwiLFxuICAgIFwicmVzb3VyY2VUeXBlc1wiOiBbXG4gICAgICBcIkFXUzo6RWxhc3RpY0xvYWRCYWxhbmNpbmdWMjo6TG9hZEJhbGFuY2VyXCJcbiAgICBdLFxuICAgIFwicmVnb1wiOiBcInBhY2thZ2UgY2RrX3ByZWZsaWdodFxcblxcbmltcG9ydCByZWdvLnYxXFxuXFxuX3BmX2lkbGVfdGltZW91dF9vdXQobikgaWYgbiA8IDFcXG5cXG5fcGZfaWRsZV90aW1lb3V0X291dChuKSBpZiBuID4gNDAwMFxcblxcbl9wZl9ub25fYWxiKG5hbWUpIGlmIHtcXG5cXHR0IDo9IHJlc29sdmUobmFtZSwgXFxcIlByb3BlcnRpZXMuVHlwZVxcXCIpXFxuXFx0dCAhPSBcXFwiYXBwbGljYXRpb25cXFwiXFxufVxcblxcbnZpb2xhdGlvbiBjb250YWlucyBtYWtlX2RpYWdfZnVsbChcXFwicGYtZWxidjItbGItaWRsZS10aW1lb3V0LXJhbmdlXFxcIiwgXFxcIkVSUk9SXFxcIiwgbmFtZSxcXG5cXHRzcHJpbnRmKFxcXCJQcm9wZXJ0aWVzLkxvYWRCYWxhbmNlckF0dHJpYnV0ZXMuJWQuVmFsdWVcXFwiLCBbaXRlbS5pbmRleF0pLFxcblxcdHNwcmludGYoXFxcImlkbGVfdGltZW91dC50aW1lb3V0X3NlY29uZHMgaXMgJXYgYnV0IG11c3QgYmUgYmV0d2VlbiAxIGFuZCA0MDAwIHNlY29uZHNcXFwiLCBbbnVtXSksXFxuXFx0XFxcIlNldCBpZGxlX3RpbWVvdXQudGltZW91dF9zZWNvbmRzIHRvIGEgdmFsdWUgYmV0d2VlbiAxIGFuZCA0MDAwXFxcIixcXG5cXHRcXFwiaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2VsYXN0aWNsb2FkYmFsYW5jaW5nL2xhdGVzdC9hcHBsaWNhdGlvbi9hcHBsaWNhdGlvbi1sb2FkLWJhbGFuY2Vycy5odG1sI2Nvbm5lY3Rpb24taWRsZS10aW1lb3V0XFxcIikgaWYge1xcblxcdHNvbWUgbmFtZSBpbiByZXNvdXJjZXNfb2ZfdHlwZShcXFwiQVdTOjpFbGFzdGljTG9hZEJhbGFuY2luZ1YyOjpMb2FkQmFsYW5jZXJcXFwiKVxcblxcdG5vdCBfcGZfbm9uX2FsYihuYW1lKVxcblxcdHNvbWUgaXRlbSBpbiBmbGF0dGVuX2xpc3QobmFtZSwgXFxcIlByb3BlcnRpZXMuTG9hZEJhbGFuY2VyQXR0cmlidXRlc1xcXCIpXFxuXFx0YXR0ciA6PSBpdGVtLnZhbHVlXFxuXFx0aXNfb2JqZWN0KGF0dHIpXFxuXFx0b2JqZWN0LmdldChhdHRyLCBcXFwiS2V5XFxcIiwgXFxcIlxcXCIpID09IFxcXCJpZGxlX3RpbWVvdXQudGltZW91dF9zZWNvbmRzXFxcIlxcblxcdG51bSA6PSB0b19udW1iZXIob2JqZWN0LmdldChhdHRyLCBcXFwiVmFsdWVcXFwiLCBudWxsKSlcXG5cXHRfcGZfaWRsZV90aW1lb3V0X291dChudW0pXFxufVxcblwiXG4gIH0sXG4gIHtcbiAgICBcImlkXCI6IFwicGYtZWxidjItdGctZGVyZWdpc3RyYXRpb24tZGVsYXktcmFuZ2VcIixcbiAgICBcInNlcnZpY2VcIjogXCJlbGJ2MlwiLFxuICAgIFwic2V2ZXJpdHlcIjogXCJFUlJPUlwiLFxuICAgIFwidGl0bGVcIjogXCJUYXJnZXQgZ3JvdXAgZGVyZWdpc3RyYXRpb25fZGVsYXkudGltZW91dF9zZWNvbmRzIG11c3QgYmUgYmV0d2VlbiAwIGFuZCAzNjAwXCIsXG4gICAgXCJ1cHN0cmVhbVwiOiBcIm5vbmVcIixcbiAgICBcInJlc291cmNlVHlwZXNcIjogW1xuICAgICAgXCJBV1M6OkVsYXN0aWNMb2FkQmFsYW5jaW5nVjI6OlRhcmdldEdyb3VwXCJcbiAgICBdLFxuICAgIFwicmVnb1wiOiBcInBhY2thZ2UgY2RrX3ByZWZsaWdodFxcblxcbmltcG9ydCByZWdvLnYxXFxuXFxuX3BmX2RlcmVnX2RlbGF5X291dChuKSBpZiBuIDwgMFxcblxcbl9wZl9kZXJlZ19kZWxheV9vdXQobikgaWYgbiA+IDM2MDBcXG5cXG52aW9sYXRpb24gY29udGFpbnMgbWFrZV9kaWFnX2Z1bGwoXFxcInBmLWVsYnYyLXRnLWRlcmVnaXN0cmF0aW9uLWRlbGF5LXJhbmdlXFxcIiwgXFxcIkVSUk9SXFxcIiwgbmFtZSxcXG5cXHRzcHJpbnRmKFxcXCJQcm9wZXJ0aWVzLlRhcmdldEdyb3VwQXR0cmlidXRlcy4lZC5WYWx1ZVxcXCIsIFtpdGVtLmluZGV4XSksXFxuXFx0c3ByaW50ZihcXFwiZGVyZWdpc3RyYXRpb25fZGVsYXkudGltZW91dF9zZWNvbmRzIGlzICV2IGJ1dCBtdXN0IGJlIGJldHdlZW4gMCBhbmQgMzYwMCBzZWNvbmRzXFxcIiwgW251bV0pLFxcblxcdFxcXCJTZXQgZGVyZWdpc3RyYXRpb25fZGVsYXkudGltZW91dF9zZWNvbmRzIHRvIGEgdmFsdWUgYmV0d2VlbiAwIGFuZCAzNjAwXFxcIixcXG5cXHRcXFwiaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2VsYXN0aWNsb2FkYmFsYW5jaW5nL2xhdGVzdC9hcHBsaWNhdGlvbi9lZGl0LXRhcmdldC1ncm91cC1hdHRyaWJ1dGVzLmh0bWwjZGVyZWdpc3RyYXRpb24tZGVsYXlcXFwiKSBpZiB7XFxuXFx0c29tZSBuYW1lIGluIHJlc291cmNlc19vZl90eXBlKFxcXCJBV1M6OkVsYXN0aWNMb2FkQmFsYW5jaW5nVjI6OlRhcmdldEdyb3VwXFxcIilcXG5cXHRzb21lIGl0ZW0gaW4gZmxhdHRlbl9saXN0KG5hbWUsIFxcXCJQcm9wZXJ0aWVzLlRhcmdldEdyb3VwQXR0cmlidXRlc1xcXCIpXFxuXFx0YXR0ciA6PSBpdGVtLnZhbHVlXFxuXFx0aXNfb2JqZWN0KGF0dHIpXFxuXFx0b2JqZWN0LmdldChhdHRyLCBcXFwiS2V5XFxcIiwgXFxcIlxcXCIpID09IFxcXCJkZXJlZ2lzdHJhdGlvbl9kZWxheS50aW1lb3V0X3NlY29uZHNcXFwiXFxuXFx0bnVtIDo9IHRvX251bWJlcihvYmplY3QuZ2V0KGF0dHIsIFxcXCJWYWx1ZVxcXCIsIG51bGwpKVxcblxcdF9wZl9kZXJlZ19kZWxheV9vdXQobnVtKVxcbn1cXG5cIlxuICB9LFxuICB7XG4gICAgXCJpZFwiOiBcInBmLWVsYnYyLXRnLXNsb3ctc3RhcnQtcmFuZ2VcIixcbiAgICBcInNlcnZpY2VcIjogXCJlbGJ2MlwiLFxuICAgIFwic2V2ZXJpdHlcIjogXCJFUlJPUlwiLFxuICAgIFwidGl0bGVcIjogXCJUYXJnZXQgZ3JvdXAgc2xvd19zdGFydC5kdXJhdGlvbl9zZWNvbmRzIG11c3QgYmUgMCBvciBiZXR3ZWVuIDMwIGFuZCA5MDBcIixcbiAgICBcInVwc3RyZWFtXCI6IFwibm9uZVwiLFxuICAgIFwicmVzb3VyY2VUeXBlc1wiOiBbXG4gICAgICBcIkFXUzo6RWxhc3RpY0xvYWRCYWxhbmNpbmdWMjo6VGFyZ2V0R3JvdXBcIlxuICAgIF0sXG4gICAgXCJyZWdvXCI6IFwicGFja2FnZSBjZGtfcHJlZmxpZ2h0XFxuXFxuaW1wb3J0IHJlZ28udjFcXG5cXG5fcGZfc2xvd19zdGFydF9vdXQobikgaWYgbiA8IDBcXG5cXG5fcGZfc2xvd19zdGFydF9vdXQobikgaWYge1xcblxcdG4gPiAwXFxuXFx0biA8IDMwXFxufVxcblxcbl9wZl9zbG93X3N0YXJ0X291dChuKSBpZiBuID4gOTAwXFxuXFxudmlvbGF0aW9uIGNvbnRhaW5zIG1ha2VfZGlhZ19mdWxsKFxcXCJwZi1lbGJ2Mi10Zy1zbG93LXN0YXJ0LXJhbmdlXFxcIiwgXFxcIkVSUk9SXFxcIiwgbmFtZSxcXG5cXHRzcHJpbnRmKFxcXCJQcm9wZXJ0aWVzLlRhcmdldEdyb3VwQXR0cmlidXRlcy4lZC5WYWx1ZVxcXCIsIFtpdGVtLmluZGV4XSksXFxuXFx0c3ByaW50ZihcXFwic2xvd19zdGFydC5kdXJhdGlvbl9zZWNvbmRzIGlzICV2IGJ1dCBtdXN0IGJlIDAgKGRpc2FibGVkKSBvciBiZXR3ZWVuIDMwIGFuZCA5MDAgc2Vjb25kc1xcXCIsIFtudW1dKSxcXG5cXHRcXFwiU2V0IHNsb3dfc3RhcnQuZHVyYXRpb25fc2Vjb25kcyB0byAwIG9yIGEgdmFsdWUgYmV0d2VlbiAzMCBhbmQgOTAwXFxcIixcXG5cXHRcXFwiaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2VsYXN0aWNsb2FkYmFsYW5jaW5nL2xhdGVzdC9hcHBsaWNhdGlvbi9lZGl0LXRhcmdldC1ncm91cC1hdHRyaWJ1dGVzLmh0bWwjc2xvdy1zdGFydC1tb2RlXFxcIikgaWYge1xcblxcdHNvbWUgbmFtZSBpbiByZXNvdXJjZXNfb2ZfdHlwZShcXFwiQVdTOjpFbGFzdGljTG9hZEJhbGFuY2luZ1YyOjpUYXJnZXRHcm91cFxcXCIpXFxuXFx0c29tZSBpdGVtIGluIGZsYXR0ZW5fbGlzdChuYW1lLCBcXFwiUHJvcGVydGllcy5UYXJnZXRHcm91cEF0dHJpYnV0ZXNcXFwiKVxcblxcdGF0dHIgOj0gaXRlbS52YWx1ZVxcblxcdGlzX29iamVjdChhdHRyKVxcblxcdG9iamVjdC5nZXQoYXR0ciwgXFxcIktleVxcXCIsIFxcXCJcXFwiKSA9PSBcXFwic2xvd19zdGFydC5kdXJhdGlvbl9zZWNvbmRzXFxcIlxcblxcdG51bSA6PSB0b19udW1iZXIob2JqZWN0LmdldChhdHRyLCBcXFwiVmFsdWVcXFwiLCBudWxsKSlcXG5cXHRfcGZfc2xvd19zdGFydF9vdXQobnVtKVxcbn1cXG5cIlxuICB9LFxuICB7XG4gICAgXCJpZFwiOiBcInBmLWlhbS1pbmxpbmUtcG9saWN5LXNpemVcIixcbiAgICBcInNlcnZpY2VcIjogXCJpYW1cIixcbiAgICBcInNldmVyaXR5XCI6IFwiRVJST1JcIixcbiAgICBcInRpdGxlXCI6IFwiSW5saW5lIHBvbGljeSBkb2N1bWVudHMgYXJlIGxpbWl0ZWQgcGVyIGlkZW50aXR5IChyb2xlIDEwMjQwIC8gZ3JvdXAgNTEyMCAvIHVzZXIgMjA0OCBjaGFyYWN0ZXJzKVwiLFxuICAgIFwidXBzdHJlYW1cIjogXCJub25lXCIsXG4gICAgXCJyZXNvdXJjZVR5cGVzXCI6IFtcbiAgICAgIFwiQVdTOjpJQU06OlBvbGljeVwiLFxuICAgICAgXCJBV1M6OklBTTo6Um9sZVBvbGljeVwiLFxuICAgICAgXCJBV1M6OklBTTo6VXNlclBvbGljeVwiLFxuICAgICAgXCJBV1M6OklBTTo6R3JvdXBQb2xpY3lcIlxuICAgIF0sXG4gICAgXCJyZWdvXCI6IFwicGFja2FnZSBjZGtfcHJlZmxpZ2h0XFxuXFxuaW1wb3J0IHJlZ28udjFcXG5cXG5fcGZfaW5saW5lX3BvbGljeV9saW1pdHMgOj0ge1xcblxcdFxcXCJBV1M6OklBTTo6UG9saWN5XFxcIjogMTAyNDAsXFxuXFx0XFxcIkFXUzo6SUFNOjpSb2xlUG9saWN5XFxcIjogMTAyNDAsXFxuXFx0XFxcIkFXUzo6SUFNOjpVc2VyUG9saWN5XFxcIjogMjA0OCxcXG5cXHRcXFwiQVdTOjpJQU06Okdyb3VwUG9saWN5XFxcIjogNTEyMCxcXG59XFxuXFxudmlvbGF0aW9uIGNvbnRhaW5zIG1ha2VfZGlhZ19mdWxsKFxcXCJwZi1pYW0taW5saW5lLXBvbGljeS1zaXplXFxcIiwgXFxcIkVSUk9SXFxcIiwgbmFtZSxcXG5cXHRcXFwiUHJvcGVydGllcy5Qb2xpY3lEb2N1bWVudFxcXCIsXFxuXFx0c3ByaW50ZihcXFwiUG9saWN5RG9jdW1lbnQgaXMgJWQgY2hhcmFjdGVycyAoSlNPTiB3aXRob3V0IHdoaXRlc3BhY2UpIGJ1dCB0aGUgaW5saW5lIHBvbGljeSBsaW1pdCBmb3IgJXMgaXMgJWQgKHJvbGU6IDEwMjQwLCBncm91cDogNTEyMCwgdXNlcjogMjA0OClcXFwiLCBbc2l6ZSwgcnR5cGUsIGxpbWl0XSksXFxuXFx0XFxcIk1vdmUgc3RhdGVtZW50cyBpbnRvIG1hbmFnZWQgcG9saWNpZXMgb3Igc2hvcnRlbiB0aGUgZG9jdW1lbnRcXFwiLFxcblxcdFxcXCJodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vSUFNL2xhdGVzdC9Vc2VyR3VpZGUvcmVmZXJlbmNlX2lhbS1xdW90YXMuaHRtbFxcXCIpIGlmIHtcXG5cXHRzb21lIHJ0eXBlLCBsaW1pdCBpbiBfcGZfaW5saW5lX3BvbGljeV9saW1pdHNcXG5cXHRzb21lIG5hbWUgaW4gcmVzb3VyY2VzX29mX3R5cGUocnR5cGUpXFxuXFx0ZG9jIDo9IHJlc29sdmUobmFtZSwgXFxcIlByb3BlcnRpZXMuUG9saWN5RG9jdW1lbnRcXFwiKVxcblxcdGlzX29iamVjdChkb2MpXFxuXFx0c2l6ZSA6PSBjb3VudChqc29uLm1hcnNoYWwoZG9jKSlcXG5cXHRzaXplID4gbGltaXRcXG59XFxuXCJcbiAgfSxcbiAge1xuICAgIFwiaWRcIjogXCJwZi1pYW0tbWFuYWdlZC1wb2xpY3ktc2l6ZVwiLFxuICAgIFwic2VydmljZVwiOiBcImlhbVwiLFxuICAgIFwic2V2ZXJpdHlcIjogXCJFUlJPUlwiLFxuICAgIFwidGl0bGVcIjogXCJNYW5hZ2VkIHBvbGljeSBkb2N1bWVudHMgYXJlIGxpbWl0ZWQgdG8gNjE0NCBjaGFyYWN0ZXJzICh3aGl0ZXNwYWNlIGV4Y2x1ZGVkKVwiLFxuICAgIFwidXBzdHJlYW1cIjogXCJub25lXCIsXG4gICAgXCJyZXNvdXJjZVR5cGVzXCI6IFtcbiAgICAgIFwiQVdTOjpJQU06Ok1hbmFnZWRQb2xpY3lcIlxuICAgIF0sXG4gICAgXCJyZWdvXCI6IFwicGFja2FnZSBjZGtfcHJlZmxpZ2h0XFxuXFxuaW1wb3J0IHJlZ28udjFcXG5cXG52aW9sYXRpb24gY29udGFpbnMgbWFrZV9kaWFnX2Z1bGwoXFxcInBmLWlhbS1tYW5hZ2VkLXBvbGljeS1zaXplXFxcIiwgXFxcIkVSUk9SXFxcIiwgbmFtZSxcXG5cXHRcXFwiUHJvcGVydGllcy5Qb2xpY3lEb2N1bWVudFxcXCIsXFxuXFx0c3ByaW50ZihcXFwiUG9saWN5RG9jdW1lbnQgaXMgJWQgY2hhcmFjdGVycyAoSlNPTiB3aXRob3V0IHdoaXRlc3BhY2UpIGJ1dCB0aGUgbWFuYWdlZCBwb2xpY3kgbGltaXQgaXMgNjE0NFxcXCIsIFtzaXplXSksXFxuXFx0XFxcIlNwbGl0IHRoZSBkb2N1bWVudCBpbnRvIG11bHRpcGxlIG1hbmFnZWQgcG9saWNpZXMgb3Igc2hvcnRlbiBpdFxcXCIsXFxuXFx0XFxcImh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9yZWZlcmVuY2VfaWFtLXF1b3Rhcy5odG1sXFxcIikgaWYge1xcblxcdHNvbWUgbmFtZSBpbiByZXNvdXJjZXNfb2ZfdHlwZShcXFwiQVdTOjpJQU06Ok1hbmFnZWRQb2xpY3lcXFwiKVxcblxcdGRvYyA6PSByZXNvbHZlKG5hbWUsIFxcXCJQcm9wZXJ0aWVzLlBvbGljeURvY3VtZW50XFxcIilcXG5cXHRpc19vYmplY3QoZG9jKVxcblxcdHNpemUgOj0gY291bnQoanNvbi5tYXJzaGFsKGRvYykpXFxuXFx0c2l6ZSA+IDYxNDRcXG59XFxuXCJcbiAgfSxcbiAge1xuICAgIFwiaWRcIjogXCJwZi1zZm4tYXNsLW1pc3Npbmctc3RhdGVcIixcbiAgICBcInNlcnZpY2VcIjogXCJzdGVwZnVuY3Rpb25zXCIsXG4gICAgXCJzZXZlcml0eVwiOiBcIkVSUk9SXCIsXG4gICAgXCJ0aXRsZVwiOiBcIkFTTCBTdGFydEF0L05leHQvRGVmYXVsdC9DaG9pY2VzIG11c3QgcmVmZXJlbmNlIGEgZGVmaW5lZCBzdGF0ZSAodG9wLWxldmVsIHN0YXRlcylcIixcbiAgICBcInVwc3RyZWFtXCI6IFwibm9uZVwiLFxuICAgIFwicmVzb3VyY2VUeXBlc1wiOiBbXG4gICAgICBcIkFXUzo6U3RlcEZ1bmN0aW9uczo6U3RhdGVNYWNoaW5lXCJcbiAgICBdLFxuICAgIFwicmVnb1wiOiBcInBhY2thZ2UgY2RrX3ByZWZsaWdodFxcblxcbmltcG9ydCByZWdvLnYxXFxuXFxuX3BmX3Nmbl9maXggOj0gXFxcIlBvaW50IFN0YXJ0QXQvTmV4dC9EZWZhdWx0IGF0IGFuIGV4aXN0aW5nIHN0YXRlIG5hbWVcXFwiXFxuXFxuX3BmX3Nmbl91cmwgOj0gXFxcImh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9zdGVwLWZ1bmN0aW9ucy9sYXRlc3QvZGcvYW1hem9uLXN0YXRlcy1sYW5ndWFnZS1zdGF0ZXMuaHRtbFxcXCJcXG5cXG5fcGZfc2ZuX2FzbChuYW1lKSA6PSBhc2wgaWYge1xcblxcdGRlZiA6PSByZXNvbHZlKG5hbWUsIFxcXCJQcm9wZXJ0aWVzLkRlZmluaXRpb25TdHJpbmdcXFwiKVxcblxcdGlzX3N0cmluZyhkZWYpXFxuXFx0YXNsIDo9IGpzb24udW5tYXJzaGFsKGRlZilcXG5cXHRpc19vYmplY3QoYXNsKVxcbn1cXG5cXG5fcGZfc2ZuX2RlZmluZWQoYXNsKSA6PSB7c24gfCBzb21lIHNuLCBfIGluIG9iamVjdC5nZXQoYXNsLCBcXFwiU3RhdGVzXFxcIiwge30pfVxcblxcbnZpb2xhdGlvbiBjb250YWlucyBtYWtlX2RpYWdfZnVsbChcXFwicGYtc2ZuLWFzbC1taXNzaW5nLXN0YXRlXFxcIiwgXFxcIkVSUk9SXFxcIiwgbmFtZSxcXG5cXHRcXFwiUHJvcGVydGllcy5EZWZpbml0aW9uU3RyaW5nXFxcIixcXG5cXHRzcHJpbnRmKFxcXCJzdGF0ZSBtYWNoaW5lIGRlZmluaXRpb24gcmVmZXJlbmNlcyBzdGF0ZSAnJXMnIHZpYSBTdGFydEF0LCBidXQgbm8gc3RhdGUgd2l0aCB0aGF0IG5hbWUgaXMgZGVmaW5lZFxcXCIsIFt0YXJnZXRdKSxcXG5cXHRfcGZfc2ZuX2ZpeCwgX3BmX3Nmbl91cmwpIGlmIHtcXG5cXHRzb21lIG5hbWUgaW4gcmVzb3VyY2VzX29mX3R5cGUoXFxcIkFXUzo6U3RlcEZ1bmN0aW9uczo6U3RhdGVNYWNoaW5lXFxcIilcXG5cXHRhc2wgOj0gX3BmX3Nmbl9hc2wobmFtZSlcXG5cXHR0YXJnZXQgOj0gb2JqZWN0LmdldChhc2wsIFxcXCJTdGFydEF0XFxcIiwgbnVsbClcXG5cXHRpc19zdHJpbmcodGFyZ2V0KVxcblxcdG5vdCB0YXJnZXQgaW4gX3BmX3Nmbl9kZWZpbmVkKGFzbClcXG59XFxuXFxudmlvbGF0aW9uIGNvbnRhaW5zIG1ha2VfZGlhZ19mdWxsKFxcXCJwZi1zZm4tYXNsLW1pc3Npbmctc3RhdGVcXFwiLCBcXFwiRVJST1JcXFwiLCBuYW1lLFxcblxcdFxcXCJQcm9wZXJ0aWVzLkRlZmluaXRpb25TdHJpbmdcXFwiLFxcblxcdHNwcmludGYoXFxcInN0YXRlICclcycgcmVmZXJlbmNlcyBzdGF0ZSAnJXMnIHZpYSAlcywgYnV0IG5vIHN0YXRlIHdpdGggdGhhdCBuYW1lIGlzIGRlZmluZWRcXFwiLCBbc25hbWUsIHRhcmdldCwga2V5XSksXFxuXFx0X3BmX3Nmbl9maXgsIF9wZl9zZm5fdXJsKSBpZiB7XFxuXFx0c29tZSBuYW1lIGluIHJlc291cmNlc19vZl90eXBlKFxcXCJBV1M6OlN0ZXBGdW5jdGlvbnM6OlN0YXRlTWFjaGluZVxcXCIpXFxuXFx0YXNsIDo9IF9wZl9zZm5fYXNsKG5hbWUpXFxuXFx0c29tZSBzbmFtZSwgc3QgaW4gb2JqZWN0LmdldChhc2wsIFxcXCJTdGF0ZXNcXFwiLCB7fSlcXG5cXHRpc19vYmplY3Qoc3QpXFxuXFx0c29tZSBrZXkgaW4ge1xcXCJOZXh0XFxcIiwgXFxcIkRlZmF1bHRcXFwifVxcblxcdHRhcmdldCA6PSBvYmplY3QuZ2V0KHN0LCBrZXksIG51bGwpXFxuXFx0aXNfc3RyaW5nKHRhcmdldClcXG5cXHRub3QgdGFyZ2V0IGluIF9wZl9zZm5fZGVmaW5lZChhc2wpXFxufVxcblxcbnZpb2xhdGlvbiBjb250YWlucyBtYWtlX2RpYWdfZnVsbChcXFwicGYtc2ZuLWFzbC1taXNzaW5nLXN0YXRlXFxcIiwgXFxcIkVSUk9SXFxcIiwgbmFtZSxcXG5cXHRcXFwiUHJvcGVydGllcy5EZWZpbml0aW9uU3RyaW5nXFxcIixcXG5cXHRzcHJpbnRmKFxcXCJzdGF0ZSAnJXMnIGhhcyBhIENob2ljZSBydWxlIHJlZmVyZW5jaW5nIHN0YXRlICclcycsIGJ1dCBubyBzdGF0ZSB3aXRoIHRoYXQgbmFtZSBpcyBkZWZpbmVkXFxcIiwgW3NuYW1lLCB0YXJnZXRdKSxcXG5cXHRfcGZfc2ZuX2ZpeCwgX3BmX3Nmbl91cmwpIGlmIHtcXG5cXHRzb21lIG5hbWUgaW4gcmVzb3VyY2VzX29mX3R5cGUoXFxcIkFXUzo6U3RlcEZ1bmN0aW9uczo6U3RhdGVNYWNoaW5lXFxcIilcXG5cXHRhc2wgOj0gX3BmX3Nmbl9hc2wobmFtZSlcXG5cXHRzb21lIHNuYW1lLCBzdCBpbiBvYmplY3QuZ2V0KGFzbCwgXFxcIlN0YXRlc1xcXCIsIHt9KVxcblxcdGlzX29iamVjdChzdClcXG5cXHRjaG9pY2VzIDo9IG9iamVjdC5nZXQoc3QsIFxcXCJDaG9pY2VzXFxcIiwgW10pXFxuXFx0aXNfYXJyYXkoY2hvaWNlcylcXG5cXHRzb21lIGMgaW4gY2hvaWNlc1xcblxcdGlzX29iamVjdChjKVxcblxcdHRhcmdldCA6PSBvYmplY3QuZ2V0KGMsIFxcXCJOZXh0XFxcIiwgbnVsbClcXG5cXHRpc19zdHJpbmcodGFyZ2V0KVxcblxcdG5vdCB0YXJnZXQgaW4gX3BmX3Nmbl9kZWZpbmVkKGFzbClcXG59XFxuXCJcbiAgfVxuXTtcbiJdfQ==
234
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicnVsZXMuZ2VuZXJhdGVkLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL3J1bGVzLmdlbmVyYXRlZC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFhYSxRQUFBLGFBQWEsR0FBc0I7SUFDOUM7UUFDRSxJQUFJLEVBQUUscUNBQXFDO1FBQzNDLFNBQVMsRUFBRSxtQkFBbUI7UUFDOUIsVUFBVSxFQUFFLE9BQU87UUFDbkIsT0FBTyxFQUFFLHlFQUF5RTtRQUNsRixVQUFVLEVBQUUsTUFBTTtRQUNsQixlQUFlLEVBQUU7WUFDZixnQ0FBZ0M7U0FDakM7UUFDRCxNQUFNLEVBQUUsbzJCQUFvMkI7S0FDNzJCO0lBQ0Q7UUFDRSxJQUFJLEVBQUUsMkJBQTJCO1FBQ2pDLFNBQVMsRUFBRSxtQkFBbUI7UUFDOUIsVUFBVSxFQUFFLE9BQU87UUFDbkIsT0FBTyxFQUFFLDRFQUE0RTtRQUNyRixVQUFVLEVBQUUsZ0JBQWdCO1FBQzVCLGVBQWUsRUFBRTtZQUNmLGdDQUFnQztTQUNqQztRQUNELE1BQU0sRUFBRSwrNkJBQSs2QjtLQUN4N0I7SUFDRDtRQUNFLElBQUksRUFBRSwrQkFBK0I7UUFDckMsU0FBUyxFQUFFLFlBQVk7UUFDdkIsVUFBVSxFQUFFLE9BQU87UUFDbkIsT0FBTyxFQUFFLHVEQUF1RDtRQUNoRSxVQUFVLEVBQUUsTUFBTTtRQUNsQixlQUFlLEVBQUU7WUFDZiwrQkFBK0I7U0FDaEM7UUFDRCxNQUFNLEVBQUUsNjZCQUE2NkI7S0FDdDdCO0lBQ0Q7UUFDRSxJQUFJLEVBQUUseUJBQXlCO1FBQy9CLFNBQVMsRUFBRSxZQUFZO1FBQ3ZCLFVBQVUsRUFBRSxPQUFPO1FBQ25CLE9BQU8sRUFBRSxpRUFBaUU7UUFDMUUsVUFBVSxFQUFFLE1BQU07UUFDbEIsZUFBZSxFQUFFO1lBQ2YsK0JBQStCO1NBQ2hDO1FBQ0QsTUFBTSxFQUFFLGdpRUFBZ2lFO0tBQ3ppRTtJQUNEO1FBQ0UsSUFBSSxFQUFFLGdDQUFnQztRQUN0QyxTQUFT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Q2xCO1FBQ0QsTUFBTSxFQUFFLDYrQ0FBNitDO0tBQ3QvQztJQUNEO1FBQ0UsSUFBSSxFQUFFLDBCQUEwQjtRQUNoQyxTQUFTLEVBQUUsZUFBZTtRQUMxQixVQUFVLEVBQUUsT0FBTztRQUNuQixPQUFPLEVBQUUsZ0lBQWdJO1FBQ3pJLFVBQVUsRUFBRSxNQUFNO1FBQ2xCLGVBQWUsRUFBRTtZQUNmLGtDQUFrQztTQUNuQztRQUNELE1BQU0sRUFBRSwyK0RBQTIrRDtLQUNwL0Q7Q0FDRixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLy8gfn4gR2VuZXJhdGVkIGJ5IHNjcmlwdHMvYnVuZGxlLXJ1bGVzLnRzIGZyb20gcnVsZXMvKiouIERvIG5vdCBlZGl0IGJ5IGhhbmQuXG4vLyB+fiBSZWdlbmVyYXRlIHdpdGg6IG5weCBwcm9qZW4gYnVuZGxlLXJ1bGVzXG4vKiBlc2xpbnQtZGlzYWJsZSAqL1xuZXhwb3J0IGludGVyZmFjZSBCdW5kbGVkUnVsZURhdGEge1xuICByZWFkb25seSBpZDogc3RyaW5nO1xuICByZWFkb25seSBzZXJ2aWNlOiBzdHJpbmc7XG4gIHJlYWRvbmx5IHNldmVyaXR5OiBzdHJpbmc7XG4gIHJlYWRvbmx5IHRpdGxlOiBzdHJpbmc7XG4gIHJlYWRvbmx5IHVwc3RyZWFtOiBzdHJpbmc7XG4gIHJlYWRvbmx5IHJlc291cmNlVHlwZXM6IHN0cmluZ1tdO1xuICByZWFkb25seSByZWdvOiBzdHJpbmc7XG59XG5cbmV4cG9ydCBjb25zdCBCVU5ETEVEX1JVTEVTOiBCdW5kbGVkUnVsZURhdGFbXSA9IFtcbiAge1xuICAgIFwiaWRcIjogXCJwZi1hZ2VudGNvcmUtZ2F0ZXdheS1qd3QtYXV0aG9yaXplclwiLFxuICAgIFwic2VydmljZVwiOiBcImJlZHJvY2stYWdlbnRjb3JlXCIsXG4gICAgXCJzZXZlcml0eVwiOiBcIkVSUk9SXCIsXG4gICAgXCJ0aXRsZVwiOiBcIkdhdGV3YXlzIHdpdGggQXV0aG9yaXplclR5cGUgQ1VTVE9NX0pXVCByZXF1aXJlIEF1dGhvcml6ZXJDb25maWd1cmF0aW9uXCIsXG4gICAgXCJ1cHN0cmVhbVwiOiBcIm5vbmVcIixcbiAgICBcInJlc291cmNlVHlwZXNcIjogW1xuICAgICAgXCJBV1M6OkJlZHJvY2tBZ2VudENvcmU6OkdhdGV3YXlcIlxuICAgIF0sXG4gICAgXCJyZWdvXCI6IFwicGFja2FnZSBjZGtfcHJlZmxpZ2h0XFxuXFxuaW1wb3J0IHJlZ28udjFcXG5cXG5fcGZfZ3dqd3RfaGFzX2NvbmZpZyhuYW1lKSBpZiBpc19vYmplY3QocmVzb2x2ZShuYW1lLCBcXFwiUHJvcGVydGllcy5BdXRob3JpemVyQ29uZmlndXJhdGlvblxcXCIpKVxcblxcbnZpb2xhdGlvbiBjb250YWlucyBtYWtlX2RpYWdfZnVsbChcXFwicGYtYWdlbnRjb3JlLWdhdGV3YXktand0LWF1dGhvcml6ZXJcXFwiLCBcXFwiRVJST1JcXFwiLCBuYW1lLFxcblxcdFxcXCJQcm9wZXJ0aWVzLkF1dGhvcml6ZXJDb25maWd1cmF0aW9uXFxcIixcXG5cXHRcXFwiQXV0aG9yaXplclR5cGUgaXMgQ1VTVE9NX0pXVCBidXQgQXV0aG9yaXplckNvbmZpZ3VyYXRpb24gaXMgbWlzc2luZzsgdGhlIENyZWF0ZUdhdGV3YXkgQVBJIHJlcXVpcmVzIGl0IGFuZCB0aGUgZGVwbG95bWVudCBmYWlscyB3aXRoIGEgVmFsaWRhdGlvbkV4Y2VwdGlvblxcXCIsXFxuXFx0XFxcIkFkZCBBdXRob3JpemVyQ29uZmlndXJhdGlvbi5DdXN0b21KV1RBdXRob3JpemVyIChkaXNjb3ZlcnlVcmwgYW5kIGFsbG93ZWRBdWRpZW5jZS9hbGxvd2VkQ2xpZW50cyksIG9yIHN3aXRjaCBBdXRob3JpemVyVHlwZSB0byBBV1NfSUFNXFxcIixcXG5cXHRcXFwiaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2JlZHJvY2stYWdlbnRjb3JlLWNvbnRyb2wvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfQ3JlYXRlR2F0ZXdheS5odG1sXFxcIikgaWYge1xcblxcdHNvbWUgbmFtZSBpbiByZXNvdXJjZXNfb2ZfdHlwZShcXFwiQVdTOjpCZWRyb2NrQWdlbnRDb3JlOjpHYXRld2F5XFxcIilcXG5cXHRyZXNvbHZlKG5hbWUsIFxcXCJQcm9wZXJ0aWVzLkF1dGhvcml6ZXJUeXBlXFxcIikgPT0gXFxcIkNVU1RPTV9KV1RcXFwiXFxuXFx0bm90IF9wZl9nd2p3dF9oYXNfY29uZmlnKG5hbWUpXFxufVxcblwiXG4gIH0sXG4gIHtcbiAgICBcImlkXCI6IFwicGYtYWdlbnRjb3JlLXJ1bnRpbWUtbmFtZVwiLFxuICAgIFwic2VydmljZVwiOiBcImJlZHJvY2stYWdlbnRjb3JlXCIsXG4gICAgXCJzZXZlcml0eVwiOiBcIkVSUk9SXCIsXG4gICAgXCJ0aXRsZVwiOiBcIkFnZW50Q29yZSBSdW50aW1lIG5hbWVzIG11c3QgbWF0Y2ggW2EtekEtWl1bYS16QS1aMC05X117MCw0N30gKG5vIGh5cGhlbnMpXCIsXG4gICAgXCJ1cHN0cmVhbVwiOiBcInBlbmRpbmctZW5naW5lXCIsXG4gICAgXCJyZXNvdXJjZVR5cGVzXCI6IFtcbiAgICAgIFwiQVdTOjpCZWRyb2NrQWdlbnRDb3JlOjpSdW50aW1lXCJcbiAgICBdLFxuICAgIFwicmVnb1wiOiBcInBhY2thZ2UgY2RrX3ByZWZsaWdodFxcblxcbmltcG9ydCByZWdvLnYxXFxuXFxuIyBDbG91ZEZvcm1hdGlvbiDjgrnjgq3jg7zjg57jga8gQWdlbnRSdW50aW1lTmFtZSDjga7jg5Hjgr/jg7zjg7PjgpLmjIHjgZ/jgarjgYTvvIjjgqjjg7Pjgrjjg7PntKDpgJrjgorjgIFcXG4jIDIwMjYtMDktMDEg44GrIDEuNy4wLWJldGEg44Gn56K66KqN77yJ44GM44CBQ3JlYXRlQWdlbnRSdW50aW1lIEFQSSDjga9cXG4jIFthLXpBLVpdW2EtekEtWjAtOV9dezAsNDd9IOOCkuW8t+WItuOBmeOCi+OAguODj+OCpOODleODs+WFpeOCiuOBriBDREsg6aKo5ZG95ZCN44GM5a6a55Wq44Gu5q275Zug44CCXFxudmlvbGF0aW9uIGNvbnRhaW5zIG1ha2VfZGlhZ19mdWxsKFxcXCJwZi1hZ2VudGNvcmUtcnVudGltZS1uYW1lXFxcIiwgXFxcIkVSUk9SXFxcIiwgbmFtZSxcXG5cXHRcXFwiUHJvcGVydGllcy5BZ2VudFJ1bnRpbWVOYW1lXFxcIixcXG5cXHRzcHJpbnRmKFxcXCJBZ2VudFJ1bnRpbWVOYW1lICclcycgaXMgaW52YWxpZDogaXQgbXVzdCBzdGFydCB3aXRoIGEgbGV0dGVyIGFuZCBjb250YWluIG9ubHkgbGV0dGVycywgZGlnaXRzLCBhbmQgdW5kZXJzY29yZXMgKG1heCA0OCBjaGFyYWN0ZXJzLCBoeXBoZW5zIGFyZSBub3QgYWxsb3dlZCk7IENyZWF0ZUFnZW50UnVudGltZSBmYWlscyBhdCBkZXBsb3kgdGltZVxcXCIsIFtuXSksXFxuXFx0XFxcIlVzZSBhbiB1bmRlcnNjb3JlLXNlcGFyYXRlZCBuYW1lIHN1Y2ggYXMgJ215X2FnZW50X3J1bnRpbWUnXFxcIixcXG5cXHRcXFwiaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2JlZHJvY2stYWdlbnRjb3JlLWNvbnRyb2wvbGF0ZXN0L0FQSVJlZmVyZW5jZS9BUElfQ3JlYXRlQWdlbnRSdW50aW1lLmh0bWxcXFwiKSBpZiB7XFxuXFx0c29tZSBuYW1lIGluIHJlc291cmNlc19vZl90eXBlKFxcXCJBV1M6OkJlZHJvY2tBZ2VudENvcmU6OlJ1bnRpbWVcXFwiKVxcblxcdG4gOj0gcmVzb2x2ZShuYW1lLCBcXFwiUHJvcGVydGllcy5BZ2VudFJ1bnRpbWVOYW1lXFxcIilcXG5cXHRpc19zdHJpbmcobilcXG5cXHRub3QgcmVnZXgubWF0Y2goYF5bYS16QS1aXVthLXpBLVowLTlfXXswLDQ3fSRgLCBuKVxcbn1cXG5cIlxuICB9LFxuICB7XG4gICAgXCJpZFwiOiBcInBmLWNsb3VkZnJvbnQtYWNtLWNlcnQtcmVnaW9uXCIsXG4gICAgXCJzZXJ2aWNlXCI6IFwiY2xvdWRmcm9udFwiLFxuICAgIFwic2V2ZXJpdHlcIjogXCJFUlJPUlwiLFxuICAgIFwidGl0bGVcIjogXCJDbG91ZEZyb250IHZpZXdlciBjZXJ0aWZpY2F0ZXMgbXVzdCBsaXZlIGluIHVzLWVhc3QtMVwiLFxuICAgIFwidXBzdHJlYW1cIjogXCJub25lXCIsXG4gICAgXCJyZXNvdXJjZVR5cGVzXCI6IFtcbiAgICAgIFwiQVdTOjpDbG91ZEZyb250OjpEaXN0cmlidXRpb25cIlxuICAgIF0sXG4gICAgXCJyZWdvXCI6IFwicGFja2FnZSBjZGtfcHJlZmxpZ2h0XFxuXFxuaW1wb3J0IHJlZ28udjFcXG5cXG52aW9sYXRpb24gY29udGFpbnMgbWFrZV9kaWFnX2Z1bGwoXFxcInBmLWNsb3VkZnJvbnQtYWNtLWNlcnQtcmVnaW9uXFxcIiwgXFxcIkVSUk9SXFxcIiwgbmFtZSxcXG5cXHRcXFwiUHJvcGVydGllcy5EaXN0cmlidXRpb25Db25maWcuVmlld2VyQ2VydGlmaWNhdGUuQWNtQ2VydGlmaWNhdGVBcm5cXFwiLFxcblxcdHNwcmludGYoXFxcIkNsb3VkRnJvbnQgcmVxdWlyZXMgdGhlIEFDTSBjZXJ0aWZpY2F0ZSB0byBiZSBpbiB1cy1lYXN0LTEsIGJ1dCB0aGUgY2VydGlmaWNhdGUgaXMgaW4gJXNcXFwiLCBbcmVnaW9uXSksXFxuXFx0XFxcIklzc3VlIG9yIGltcG9ydCB0aGUgY2VydGlmaWNhdGUgaW4gdXMtZWFzdC0xIChlLmcuIGEgZGVkaWNhdGVkIHVzLWVhc3QtMSBzdGFjaykgYW5kIHJlZmVyZW5jZSB0aGF0IEFSTlxcXCIsXFxuXFx0XFxcImh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BbWF6b25DbG91ZEZyb250L2xhdGVzdC9EZXZlbG9wZXJHdWlkZS9jbmFtZXMtYW5kLWh0dHBzLXJlcXVpcmVtZW50cy5odG1sI2h0dHBzLXJlcXVpcmVtZW50cy1jZXJ0aWZpY2F0ZS1pc3N1ZXJcXFwiKSBpZiB7XFxuXFx0c29tZSBuYW1lIGluIHJlc291cmNlc19vZl90eXBlKFxcXCJBV1M6OkNsb3VkRnJvbnQ6OkRpc3RyaWJ1dGlvblxcXCIpXFxuXFx0YXJuIDo9IHJlc29sdmUobmFtZSwgXFxcIlByb3BlcnRpZXMuRGlzdHJpYnV0aW9uQ29uZmlnLlZpZXdlckNlcnRpZmljYXRlLkFjbUNlcnRpZmljYXRlQXJuXFxcIilcXG5cXHRpc19zdHJpbmcoYXJuKVxcblxcdHN0YXJ0c3dpdGgoYXJuLCBcXFwiYXJuOlxcXCIpXFxuXFx0cGFydHMgOj0gc3BsaXQoYXJuLCBcXFwiOlxcXCIpXFxuXFx0Y291bnQocGFydHMpID49IDZcXG5cXHRwYXJ0c1syXSA9PSBcXFwiYWNtXFxcIlxcblxcdHJlZ2lvbiA6PSBwYXJ0c1szXVxcblxcdHJlZ2lvbiAhPSBcXFwiXFxcIlxcblxcdHJlZ2lvbiAhPSBcXFwidXMtZWFzdC0xXFxcIlxcbn1cXG5cIlxuICB9LFxuICB7XG4gICAgXCJpZFwiOiBcInBmLWNsb3VkZnJvbnQtdHRsLW9yZGVyXCIsXG4gICAgXCJzZXJ2aWNlXCI6IFwiY2xvdWRmcm9udFwiLFxuICAgIFwic2V2ZXJpdHlcIjogXCJFUlJPUlwiLFxuICAgIFwidGl0bGVcIjogXCJDYWNoZSBiZWhhdmlvciBUVExzIG11c3Qgc2F0aXNmeSBNaW5UVEwgPD0gRGVmYXVsdFRUTCA8PSBNYXhUVExcIixcbiAgICBcInVwc3RyZWFtXCI6IFwibm9uZVwiLFxuICAgIFwicmVzb3VyY2VUeXBlc1wiOiBbXG4gICAgICBcIkFXUzo6Q2xvdWRGcm9udDo6RGlzdHJpYnV0aW9uXCJcbiAgICBdLFxuICAgIFwicmVnb1wiOiBcInBhY2thZ2UgY2RrX3ByZWZsaWdodFxcblxcbmltcG9ydCByZWdvLnYxXFxuXFxuX3BmX2NmX3R0bF9maXggOj0gXFxcIk9yZGVyIHRoZSBUVExzIGFzIE1pblRUTCA8PSBEZWZhdWx0VFRMIDw9IE1heFRUTFxcXCJcXG5cXG5fcGZfY2ZfdHRsX3VybCA6PSBcXFwiaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0FtYXpvbkNsb3VkRnJvbnQvbGF0ZXN0L0RldmVsb3Blckd1aWRlL0V4cGlyYXRpb24uaHRtbFxcXCJcXG5cXG5fcGZfY2ZfYmVoYXZpb3JzKG5hbWUpIDo9IGFycmF5LmNvbmNhdChcXG5cXHRbe1xcXCJwYXRoXFxcIjogXFxcIlByb3BlcnRpZXMuRGlzdHJpYnV0aW9uQ29uZmlnLkRlZmF1bHRDYWNoZUJlaGF2aW9yXFxcIiwgXFxcInZhbHVlXFxcIjogaXQudmFsdWV9IHxcXG5cXHRcXHRzb21lIGl0IGluIGZsYXR0ZW5fbGlzdChuYW1lLCBcXFwiUHJvcGVydGllcy5EaXN0cmlidXRpb25Db25maWcuRGVmYXVsdENhY2hlQmVoYXZpb3JcXFwiKV0sXFxuXFx0W3tcXFwicGF0aFxcXCI6IHNwcmludGYoXFxcIlByb3BlcnRpZXMuRGlzdHJpYnV0aW9uQ29uZmlnLkNhY2hlQmVoYXZpb3JzLiVkXFxcIiwgW2l0LmluZGV4XSksIFxcXCJ2YWx1ZVxcXCI6IGl0LnZhbHVlfSB8XFxuXFx0XFx0c29tZSBpdCBpbiBmbGF0dGVuX2xpc3QobmFtZSwgXFxcIlByb3BlcnRpZXMuRGlzdHJpYnV0aW9uQ29uZmlnLkNhY2hlQmVoYXZpb3JzXFxcIildLFxcbilcXG5cXG52aW9sYXRpb24gY29udGFpbnMgbWFrZV9kaWFnX2Z1bGwoXFxcInBmLWNsb3VkZnJvbnQtdHRsLW9yZGVyXFxcIiwgXFxcIkVSUk9SXFxcIiwgbmFtZSwgYi5wYXRoLFxcblxcdHNwcmludGYoXFxcIk1pblRUTCAoJXYpIG11c3QgYmUgbGVzcyB0aGFuIG9yIGVxdWFsIHRvIE1heFRUTCAoJXYpXFxcIiwgW21uLCBteF0pLFxcblxcdF9wZl9jZl90dGxfZml4LCBfcGZfY2ZfdHRsX3VybCkgaWYge1xcblxcdHNvbWUgbmFtZSBpbiByZXNvdXJjZXNfb2ZfdHlwZShcXFwiQVdTOjpDbG91ZEZyb250OjpEaXN0cmlidXRpb25cXFwiKVxcblxcdHNvbWUgYiBpbiBfcGZfY2ZfYmVoYXZpb3JzKG5hbWUpXFxuXFx0aXNfb2JqZWN0KGIudmFsdWUpXFxuXFx0bW4gOj0gdG9fbnVtYmVyKG9iamVjdC5nZXQoYi52YWx1ZSwgXFxcIk1pblRUTFxcXCIsIG51bGwpKVxcblxcdG14IDo9IHRvX251bWJlcihvYmplY3QuZ2V0KGIudmFsdWUsIFxcXCJNYXhUVExcXFwiLCBudWxsKSlcXG5cXHRtbiA+IG14XFxufVxcblxcbnZpb2xhdGlvbiBjb250YWlucyBtYWtlX2RpYWdfZnVsbChcXFwicGYtY2xvdWRmcm9udC10dGwtb3JkZXJcXFwiLCBcXFwiRVJST1JcXFwiLCBuYW1lLCBiLnBhdGgsXFxuXFx0c3ByaW50ZihcXFwiTWluVFRMICgldikgbXVzdCBiZSBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gRGVmYXVsdFRUTCAoJXYpXFxcIiwgW21uLCBkZl0pLFxcblxcdF9wZl9jZl90dGxfZml4LCBfcGZfY2ZfdHRsX3VybCkgaWYge1xcblxcdHNvbWUgbmFtZSBpbiByZXNvdXJjZXNfb2ZfdHlwZShcXFwiQVdTOjpDbG91ZEZyb250OjpEaXN0cmlidXRpb25cXFwiKVxcblxcdHNvbWUgYiBpbiBfcGZfY2ZfYmVoYXZpb3JzKG5hbWUpXFxuXFx0aXNfb2JqZWN0KGIudmFsdWUpXFxuXFx0bW4gOj0gdG9fbnVtYmVyKG9iamVjdC5nZXQoYi52YWx1ZSwgXFxcIk1pblRUTFxcXCIsIG51bGwpKVxcblxcdGRmIDo9IHRvX251bWJlcihvYmplY3QuZ2V0KGIudmFsdWUsIFxcXCJEZWZhdWx0VFRMXFxcIiwgbnVsbCkpXFxuXFx0bW4gPiBkZlxcbn1cXG5cXG52aW9sYXRpb24gY29udGFpbnMgbWFrZV9kaWFnX2Z1bGwoXFxcInBmLWNsb3VkZnJvbnQtdHRsLW9yZGVyXFxcIiwgXFxcIkVSUk9SXFxcIiwgbmFtZSwgYi5wYXRoLFxcblxcdHNwcmludGYoXFxcIkRlZmF1bHRUVEwgKCV2KSBtdXN0IGJlIGxlc3MgdGhhbiBvciBlcXVhbCB0byBNYXhUVEwgKCV2KVxcXCIsIFtkZiwgbXhdKSxcXG5cXHRfcGZfY2ZfdHRsX2ZpeCwgX3BmX2NmX3R0bF91cmwpIGlmIHtcXG5cXHRzb21lIG5hbWUgaW4gcmVzb3VyY2VzX29mX3R5cGUoXFxcIkFXUzo6Q2xvdWRGcm9udDo6RGlzdHJpYnV0aW9uXFxcIilcXG5cXHRzb21lIGIgaW4gX3BmX2NmX2JlaGF2aW9ycyhuYW1lKVxcblxcdGlzX29iamVjdChiLnZhbHVlKVxcblxcdGRmIDo9IHRvX251bWJlcihvYmplY3QuZ2V0KGIudmFsdWUsIFxcXCJEZWZhdWx0VFRMXFxcIiwgbnVsbCkpXFxuXFx0bXggOj0gdG9fbnVtYmVyKG9iamVjdC5nZXQoYi52YWx1ZSwgXFxcIk1heFRUTFxcXCIsIG51bGwpKVxcblxcdGRmID4gbXhcXG59XFxuXCJcbiAgfSxcbiAge1xuICAgIFwiaWRcIjogXCJwZi1keW5hbW9kYi1iaWxsaW5nLXRocm91Z2hwdXRcIixcbiAgICBcInNlcnZpY2VcIjogXCJkeW5hbW9kYlwiLFxuICAgIFwic2V2ZXJpdHlcIjogXCJFUlJPUlwiLFxuICAgIFwidGl0bGVcIjogXCJQcm92aXNpb25lZFRocm91Z2hwdXQgbXVzdCBtYXRjaCBCaWxsaW5nTW9kZSAocmVxdWlyZWQgZm9yIFBST1ZJU0lPTkVELCBmb3JiaWRkZW4gZm9yIFBBWV9QRVJfUkVRVUVTVClcIixcbiAgICBcInVwc3RyZWFtXCI6IFwibm9uZVwiLFxuICAgIFwicmVzb3VyY2VUeXBlc1wiOiBbXG4gICAgICBcIkFXUzo6RHluYW1vREI6OlRhYmxlXCJcbiAgICBdLFxuICAgIFwicmVnb1wiOiBcInBhY2thZ2UgY2RrX3ByZWZsaWdodFxcblxcbmltcG9ydCByZWdvLnYxXFxuXFxuX3BmX2RkYmJ0X3VybCA6PSBcXFwiaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2FtYXpvbmR5bmFtb2RiL2xhdGVzdC9kZXZlbG9wZXJndWlkZS9Ib3dJdFdvcmtzLlJlYWRXcml0ZUNhcGFjaXR5TW9kZS5odG1sXFxcIlxcblxcbl9wZl9kZGJidF9oYXNfcHQobmFtZSkgaWYgaXNfb2JqZWN0KHJlc29sdmUobmFtZSwgXFxcIlByb3BlcnRpZXMuUHJvdmlzaW9uZWRUaHJvdWdocHV0XFxcIikpXFxuXFxuX3BmX2RkYmJ0X2JpbGxpbmdfcHJlc2VudChuYW1lKSBpZiByZXNvbHZlKG5hbWUsIFxcXCJQcm9wZXJ0aWVzLkJpbGxpbmdNb2RlXFxcIilcXG5cXG4jIEJpbGxpbmdNb2RlIOOBjOODquODhuODqeODqyBcXFwiUFJPVklTSU9ORURcXFwi44CB44G+44Gf44Gv5pyq5oyH5a6a77yI44OH44OV44Kp44Or44OIIFBST1ZJU0lPTkVE77yJ44CCXFxuIyDjg4jjg7zjgq/jg7PlgKTvvIhSZWYg562J77yJ44Gv5Yik5a6a44Gr5L2/44KP44Gq44GE77yI6Kqk5qSc55+l6Ziy5q2i77yJ44CCXFxuX3BmX2RkYmJ0X3Byb3Zpc2lvbmVkKG5hbWUpIGlmIHJlc29sdmUobmFtZSwgXFxcIlByb3BlcnRpZXMuQmlsbGluZ01vZGVcXFwiKSA9PSBcXFwiUFJPVklTSU9ORURcXFwiXFxuXFxuX3BmX2RkYmJ0X3Byb3Zpc2lvbmVkKG5hbWUpIGlmIG5vdCBfcGZfZGRiYnRfYmlsbGluZ19wcmVzZW50KG5hbWUpXFxuXFxudmlvbGF0aW9uIGNvbnRhaW5zIG1ha2VfZGlhZ19mdWxsKFxcXCJwZi1keW5hbW9kYi1iaWxsaW5nLXRocm91Z2hwdXRcXFwiLCBcXFwiRVJST1JcXFwiLCBuYW1lLFxcblxcdFxcXCJQcm9wZXJ0aWVzLlByb3Zpc2lvbmVkVGhyb3VnaHB1dFxcXCIsXFxuXFx0XFxcIlByb3Zpc2lvbmVkVGhyb3VnaHB1dCBjYW5ub3QgYmUgc3BlY2lmaWVkIHdoZW4gQmlsbGluZ01vZGUgaXMgUEFZX1BFUl9SRVFVRVNUOyBDcmVhdGVUYWJsZSBmYWlscyBhdCBkZXBsb3kgdGltZVxcXCIsXFxuXFx0XFxcIlJlbW92ZSBQcm92aXNpb25lZFRocm91Z2hwdXQsIG9yIHN3aXRjaCBCaWxsaW5nTW9kZSB0byBQUk9WSVNJT05FRFxcXCIsXFxuXFx0X3BmX2RkYmJ0X3VybCkgaWYge1xcblxcdHNvbWUgbmFtZSBpbiByZXNvdXJjZXNfb2ZfdHlwZShcXFwiQVdTOjpEeW5hbW9EQjo6VGFibGVcXFwiKVxcblxcdHJlc29sdmUobmFtZSwgXFxcIlByb3BlcnRpZXMuQmlsbGluZ01vZGVcXFwiKSA9PSBcXFwiUEFZX1BFUl9SRVFVRVNUXFxcIlxcblxcdF9wZl9kZGJidF9oYXNfcHQobmFtZSlcXG59XFxuXFxudmlvbGF0aW9uIGNvbnRhaW5zIG1ha2VfZGlhZ19mdWxsKFxcXCJwZi1keW5hbW9kYi1iaWxsaW5nLXRocm91Z2hwdXRcXFwiLCBcXFwiRVJST1JcXFwiLCBuYW1lLFxcblxcdFxcXCJQcm9wZXJ0aWVzLlByb3Zpc2lvbmVkVGhyb3VnaHB1dFxcXCIsXFxuXFx0XFxcIkJpbGxpbmdNb2RlIGlzIFBST1ZJU0lPTkVEICh0aGUgZGVmYXVsdCkgYnV0IFByb3Zpc2lvbmVkVGhyb3VnaHB1dCBpcyBtaXNzaW5nOyBDcmVhdGVUYWJsZSBmYWlscyBhdCBkZXBsb3kgdGltZVxcXCIsXFxuXFx0XFxcIkFkZCBQcm92aXNpb25lZFRocm91Z2hwdXQgKFJlYWRDYXBhY2l0eVVuaXRzIC8gV3JpdGVDYXBhY2l0eVVuaXRzKSwgb3Igc2V0IEJpbGxpbmdNb2RlIHRvIFBBWV9QRVJfUkVRVUVTVFxcXCIsXFxuXFx0X3BmX2RkYmJ0X3VybCkgaWYge1xcblxcdHNvbWUgbmFtZSBpbiByZXNvdXJjZXNfb2ZfdHlwZShcXFwiQVdTOjpEeW5hbW9EQjo6VGFibGVcXFwiKVxcblxcdF9wZl9kZGJidF9wcm92aXNpb25lZChuYW1lKVxcblxcdG5vdCBfcGZfZGRiYnRfaGFzX3B0KG5hbWUpXFxufVxcblwiXG4gIH0sXG4gIHtcbiAgICBcImlkXCI6IFwicGYtZWMyLXNnLXBvcnQtcmFuZ2VcIixcbiAgICBcInNlcnZpY2VcIjogXCJlYzJcIixcbiAgICBcInNldmVyaXR5XCI6IFwiRVJST1JcIixcbiAgICBcInRpdGxlXCI6IFwiU2VjdXJpdHkgZ3JvdXAgVENQL1VEUCBwb3J0cyBtdXN0IGJlIHdpdGhpbiAwLTY1NTM1IGFuZCBGcm9tUG9ydCA8PSBUb1BvcnRcIixcbiAgICBcInVwc3RyZWFtXCI6IFwibm9uZVwiLFxuICAgIFwicmVzb3VyY2VUeXBlc1wiOiBbXG4gICAgICBcIkFXUzo6RUMyOjpTZWN1cml0eUdyb3VwXCIsXG4gICAgICBcIkFXUzo6RUMyOjpTZWN1cml0eUdyb3VwSW5ncmVzc1wiLFxuICAgICAgXCJBV1M6OkVDMjo6U2VjdXJpdHlHcm91cEVncmVzc1wiXG4gICAgXSxcbiAgICBcInJlZ29cIjogXCJwYWNrYWdlIGNka19wcmVmbGlnaHRcXG5cXG5pbXBvcnQgcmVnby52MVxcblxcbl9wZl9zZ19maXggOj0gXFxcIlVzZSBhIHBvcnQgYmV0d2VlbiAwIGFuZCA2NTUzNSB3aXRoIEZyb21Qb3J0IDw9IFRvUG9ydFxcXCJcXG5cXG5fcGZfc2dfdXJsIDo9IFxcXCJodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQVdTRUMyL2xhdGVzdC9BUElSZWZlcmVuY2UvQVBJX0F1dGhvcml6ZVNlY3VyaXR5R3JvdXBJbmdyZXNzLmh0bWxcXFwiXFxuXFxuX3BmX3BvcnRfb3V0KG4pIGlmIG4gPCAwXFxuXFxuX3BmX3BvcnRfb3V0KG4pIGlmIG4gPiA2NTUzNVxcblxcbl9wZl90Y3BfdWRwKHApIGlmIHAgaW4ge1xcXCJ0Y3BcXFwiLCBcXFwidWRwXFxcIiwgXFxcIjZcXFwiLCBcXFwiMTdcXFwiLCA2LCAxN31cXG5cXG52aW9sYXRpb24gY29udGFpbnMgbWFrZV9kaWFnX2Z1bGwoXFxcInBmLWVjMi1zZy1wb3J0LXJhbmdlXFxcIiwgXFxcIkVSUk9SXFxcIiwgbmFtZSxcXG5cXHRzcHJpbnRmKFxcXCJQcm9wZXJ0aWVzLiVzLiVkLiVzXFxcIiwgW2RpciwgaXRlbS5pbmRleCwgcG5hbWVdKSxcXG5cXHRzcHJpbnRmKFxcXCIlcyAldiBpcyBvdXRzaWRlIHRoZSB2YWxpZCBUQ1AvVURQIHBvcnQgcmFuZ2UgMC02NTUzNVxcXCIsIFtwbmFtZSwgbl0pLFxcblxcdF9wZl9zZ19maXgsIF9wZl9zZ191cmwpIGlmIHtcXG5cXHRzb21lIG5hbWUgaW4gcmVzb3VyY2VzX29mX3R5cGUoXFxcIkFXUzo6RUMyOjpTZWN1cml0eUdyb3VwXFxcIilcXG5cXHRzb21lIGRpciBpbiB7XFxcIlNlY3VyaXR5R3JvdXBJbmdyZXNzXFxcIiwgXFxcIlNlY3VyaXR5R3JvdXBFZ3Jlc3NcXFwifVxcblxcdHNvbWUgaXRlbSBpbiBmbGF0dGVuX2xpc3QobmFtZSwgc3ByaW50ZihcXFwiUHJvcGVydGllcy4lc1xcXCIsIFtkaXJdKSlcXG5cXHRlbnRyeSA6PSBpdGVtLnZhbHVlXFxuXFx0aXNfb2JqZWN0KGVudHJ5KVxcblxcdF9wZl90Y3BfdWRwKG9iamVjdC5nZXQoZW50cnksIFxcXCJJcFByb3RvY29sXFxcIiwgbnVsbCkpXFxuXFx0c29tZSBwbmFtZSBpbiB7XFxcIkZyb21Qb3J0XFxcIiwgXFxcIlRvUG9ydFxcXCJ9XFxuXFx0biA6PSB0b19udW1iZXIob2JqZWN0LmdldChlbnRyeSwgcG5hbWUsIG51bGwpKVxcblxcdF9wZl9wb3J0X291dChuKVxcbn1cXG5cXG52aW9sYXRpb24gY29udGFpbnMgbWFrZV9kaWFnX2Z1bGwoXFxcInBmLWVjMi1zZy1wb3J0LXJhbmdlXFxcIiwgXFxcIkVSUk9SXFxcIiwgbmFtZSxcXG5cXHRzcHJpbnRmKFxcXCJQcm9wZXJ0aWVzLiVzLiVkLkZyb21Qb3J0XFxcIiwgW2RpciwgaXRlbS5pbmRleF0pLFxcblxcdHNwcmludGYoXFxcIkZyb21Qb3J0ICgldikgbXVzdCBiZSBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gVG9Qb3J0ICgldilcXFwiLCBbZiwgdF0pLFxcblxcdF9wZl9zZ19maXgsIF9wZl9zZ191cmwpIGlmIHtcXG5cXHRzb21lIG5hbWUgaW4gcmVzb3VyY2VzX29mX3R5cGUoXFxcIkFXUzo6RUMyOjpTZWN1cml0eUdyb3VwXFxcIilcXG5cXHRzb21lIGRpciBpbiB7XFxcIlNlY3VyaXR5R3JvdXBJbmdyZXNzXFxcIiwgXFxcIlNlY3VyaXR5R3JvdXBFZ3Jlc3NcXFwifVxcblxcdHNvbWUgaXRlbSBpbiBmbGF0dGVuX2xpc3QobmFtZSwgc3ByaW50ZihcXFwiUHJvcGVydGllcy4lc1xcXCIsIFtkaXJdKSlcXG5cXHRlbnRyeSA6PSBpdGVtLnZhbHVlXFxuXFx0aXNfb2JqZWN0KGVudHJ5KVxcblxcdF9wZl90Y3BfdWRwKG9iamVjdC5nZXQoZW50cnksIFxcXCJJcFByb3RvY29sXFxcIiwgbnVsbCkpXFxuXFx0ZiA6PSB0b19udW1iZXIob2JqZWN0LmdldChlbnRyeSwgXFxcIkZyb21Qb3J0XFxcIiwgbnVsbCkpXFxuXFx0dCA6PSB0b19udW1iZXIob2JqZWN0LmdldChlbnRyeSwgXFxcIlRvUG9ydFxcXCIsIG51bGwpKVxcblxcdGYgPj0gMFxcblxcdHQgPD0gNjU1MzVcXG5cXHRmID4gdFxcbn1cXG5cXG52aW9sYXRpb24gY29udGFpbnMgbWFrZV9kaWFnX2Z1bGwoXFxcInBmLWVjMi1zZy1wb3J0LXJhbmdlXFxcIiwgXFxcIkVSUk9SXFxcIiwgbmFtZSxcXG5cXHRzcHJpbnRmKFxcXCJQcm9wZXJ0aWVzLiVzXFxcIiwgW3BuYW1lXSksXFxuXFx0c3ByaW50ZihcXFwiJXMgJXYgaXMgb3V0c2lkZSB0aGUgdmFsaWQgVENQL1VEUCBwb3J0IHJhbmdlIDAtNjU1MzVcXFwiLCBbcG5hbWUsIG5dKSxcXG5cXHRfcGZfc2dfZml4LCBfcGZfc2dfdXJsKSBpZiB7XFxuXFx0c29tZSBydHlwZSBpbiB7XFxcIkFXUzo6RUMyOjpTZWN1cml0eUdyb3VwSW5ncmVzc1xcXCIsIFxcXCJBV1M6OkVDMjo6U2VjdXJpdHlHcm91cEVncmVzc1xcXCJ9XFxuXFx0c29tZSBuYW1lIGluIHJlc291cmNlc19vZl90eXBlKHJ0eXBlKVxcblxcdF9wZl90Y3BfdWRwKHJlc29sdmUobmFtZSwgXFxcIlByb3BlcnRpZXMuSXBQcm90b2NvbFxcXCIpKVxcblxcdHNvbWUgcG5hbWUgaW4ge1xcXCJGcm9tUG9ydFxcXCIsIFxcXCJUb1BvcnRcXFwifVxcblxcdG4gOj0gdG9fbnVtYmVyKHJlc29sdmUobmFtZSwgc3ByaW50ZihcXFwiUHJvcGVydGllcy4lc1xcXCIsIFtwbmFtZV0pKSlcXG5cXHRfcGZfcG9ydF9vdXQobilcXG59XFxuXFxudmlvbGF0aW9uIGNvbnRhaW5zIG1ha2VfZGlhZ19mdWxsKFxcXCJwZi1lYzItc2ctcG9ydC1yYW5nZVxcXCIsIFxcXCJFUlJPUlxcXCIsIG5hbWUsXFxuXFx0XFxcIlByb3BlcnRpZXMuRnJvbVBvcnRcXFwiLFxcblxcdHNwcmludGYoXFxcIkZyb21Qb3J0ICgldikgbXVzdCBiZSBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gVG9Qb3J0ICgldilcXFwiLCBbZiwgdF0pLFxcblxcdF9wZl9zZ19maXgsIF9wZl9zZ191cmwpIGlmIHtcXG5cXHRzb21lIHJ0eXBlIGluIHtcXFwiQVdTOjpFQzI6OlNlY3VyaXR5R3JvdXBJbmdyZXNzXFxcIiwgXFxcIkFXUzo6RUMyOjpTZWN1cml0eUdyb3VwRWdyZXNzXFxcIn1cXG5cXHRzb21lIG5hbWUgaW4gcmVzb3VyY2VzX29mX3R5cGUocnR5cGUpXFxuXFx0X3BmX3RjcF91ZHAocmVzb2x2ZShuYW1lLCBcXFwiUHJvcGVydGllcy5JcFByb3RvY29sXFxcIikpXFxuXFx0ZiA6PSB0b19udW1iZXIocmVzb2x2ZShuYW1lLCBcXFwiUHJvcGVydGllcy5Gcm9tUG9ydFxcXCIpKVxcblxcdHQgOj0gdG9fbnVtYmVyKHJlc29sdmUobmFtZSwgXFxcIlByb3BlcnRpZXMuVG9Qb3J0XFxcIikpXFxuXFx0ZiA+PSAwXFxuXFx0dCA8PSA2NTUzNVxcblxcdGYgPiB0XFxufVxcblwiXG4gIH0sXG4gIHtcbiAgICBcImlkXCI6IFwicGYtZWMyLXVzZXJkYXRhLXNpemVcIixcbiAgICBcInNlcnZpY2VcIjogXCJlYzJcIixcbiAgICBcInNldmVyaXR5XCI6IFwiRVJST1JcIixcbiAgICBcInRpdGxlXCI6IFwiRUMyIHVzZXIgZGF0YSBpcyBsaW1pdGVkIHRvIDE2Mzg0IGJ5dGVzXCIsXG4gICAgXCJ1cHN0cmVhbVwiOiBcIm5vbmVcIixcbiAgICBcInJlc291cmNlVHlwZXNcIjogW1xuICAgICAgXCJBV1M6OkVDMjo6SW5zdGFuY2VcIixcbiAgICAgIFwiQVdTOjpFQzI6OkxhdW5jaFRlbXBsYXRlXCJcbiAgICBdLFxuICAgIFwicmVnb1wiOiBcInBhY2thZ2UgY2RrX3ByZWZsaWdodFxcblxcbmltcG9ydCByZWdvLnYxXFxuXFxuX3BmX3Vkc3pfZml4IDo9IFxcXCJLZWVwIHVzZXIgZGF0YSB1bmRlciAxNjM4NCBieXRlczsgbW92ZSBsYXJnZSBwYXlsb2FkcyB0byBTMyBhbmQgZmV0Y2ggdGhlbSBmcm9tIGEgc21hbGwgYm9vdHN0cmFwIHNjcmlwdFxcXCJcXG5cXG5fcGZfdWRzel91cmwgOj0gXFxcImh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BV1NFQzIvbGF0ZXN0L1VzZXJHdWlkZS9pbnN0YW5jZWRhdGEtYWRkLXVzZXItZGF0YS5odG1sXFxcIlxcblxcbl9wZl91ZHN6X2xpbWl0IDo9IDE2Mzg0XFxuXFxuIyBiYXNlNjQg5paH5a2X5YiX44Gu44OH44Kz44O844OJ5b6M44OQ44Kk44OI5pWw77yI44OR44OH44Kj44Oz44Kw6ICD5oWu77yJXFxuX3BmX3Vkc3pfZGVjb2RlZChzKSA6PSAoKGNvdW50KHMpICogMykgLyA0KSAtIDIgaWYgZW5kc3dpdGgocywgXFxcIj09XFxcIilcXG5cXG5fcGZfdWRzel9kZWNvZGVkKHMpIDo9ICgoY291bnQocykgKiAzKSAvIDQpIC0gMSBpZiB7XFxuXFx0ZW5kc3dpdGgocywgXFxcIj1cXFwiKVxcblxcdG5vdCBlbmRzd2l0aChzLCBcXFwiPT1cXFwiKVxcbn1cXG5cXG5fcGZfdWRzel9kZWNvZGVkKHMpIDo9IChjb3VudChzKSAqIDMpIC8gNCBpZiBub3QgZW5kc3dpdGgocywgXFxcIj1cXFwiKVxcblxcbl9wZl91ZHN6X3BhdGhzIDo9IHtcXG5cXHRcXFwiQVdTOjpFQzI6Okluc3RhbmNlXFxcIjogXFxcIlByb3BlcnRpZXMuVXNlckRhdGFcXFwiLFxcblxcdFxcXCJBV1M6OkVDMjo6TGF1bmNoVGVtcGxhdGVcXFwiOiBcXFwiUHJvcGVydGllcy5MYXVuY2hUZW1wbGF0ZURhdGEuVXNlckRhdGFcXFwiLFxcbn1cXG5cXG4jIFVzZXJEYXRhIOOBjOODquODhuODqeODqyBiYXNlNjQg5paH5a2X5YiX44Gu44Kx44O844K5XFxudmlvbGF0aW9uIGNvbnRhaW5zIG1ha2VfZGlhZ19mdWxsKFxcXCJwZi1lYzItdXNlcmRhdGEtc2l6ZVxcXCIsIFxcXCJFUlJPUlxcXCIsIG5hbWUsIHAsXFxuXFx0c3ByaW50ZihcXFwiVXNlckRhdGEgZGVjb2RlcyB0byBhYm91dCAldiBieXRlcywgYnV0IEVDMiBsaW1pdHMgdXNlciBkYXRhIHRvICVkIGJ5dGVzOyBSdW5JbnN0YW5jZXMgZmFpbHMgYXQgZGVwbG95IHRpbWVcXFwiLCBbc2l6ZSwgX3BmX3Vkc3pfbGltaXRdKSxcXG5cXHRfcGZfdWRzel9maXgsIF9wZl91ZHN6X3VybCkgaWYge1xcblxcdHNvbWUgcnR5cGUsIHAgaW4gX3BmX3Vkc3pfcGF0aHNcXG5cXHRzb21lIG5hbWUgaW4gcmVzb3VyY2VzX29mX3R5cGUocnR5cGUpXFxuXFx0dWQgOj0gcmVzb2x2ZShuYW1lLCBwKVxcblxcdGlzX3N0cmluZyh1ZClcXG5cXHRzaXplIDo9IF9wZl91ZHN6X2RlY29kZWQodWQpXFxuXFx0c2l6ZSA+IF9wZl91ZHN6X2xpbWl0XFxufVxcblxcbiMgVXNlckRhdGEg44GMIHtcXFwiRm46OkJhc2U2NFxcXCI6IFxcXCI8bGl0ZXJhbD5cXFwifSDjga7jgrHjg7zjgrnvvIjjgqjjg7PjgrPjg7zjg4nliY3jga7nlJ/jg5DjgqTjg4jmlbDjgafliKTlrprvvIlcXG52aW9sYXRpb24gY29udGFpbnMgbWFrZV9kaWFnX2Z1bGwoXFxcInBmLWVjMi11c2VyZGF0YS1zaXplXFxcIiwgXFxcIkVSUk9SXFxcIiwgbmFtZSwgcCxcXG5cXHRzcHJpbnRmKFxcXCJVc2VyRGF0YSBpcyAlZCBieXRlcyBiZWZvcmUgYmFzZTY0IGVuY29kaW5nLCBidXQgRUMyIGxpbWl0cyB1c2VyIGRhdGEgdG8gJWQgYnl0ZXM7IFJ1bkluc3RhbmNlcyBmYWlscyBhdCBkZXBsb3kgdGltZVxcXCIsIFtjb3VudChpbm5lciksIF9wZl91ZHN6X2xpbWl0XSksXFxuXFx0X3BmX3Vkc3pfZml4LCBfcGZfdWRzel91cmwpIGlmIHtcXG5cXHRzb21lIHJ0eXBlLCBwIGluIF9wZl91ZHN6X3BhdGhzXFxuXFx0c29tZSBuYW1lIGluIHJlc291cmNlc19vZl90eXBlKHJ0eXBlKVxcblxcdHVkIDo9IHJlc29sdmUobmFtZSwgcClcXG5cXHRpc19vYmplY3QodWQpXFxuXFx0aW5uZXIgOj0gb2JqZWN0LmdldCh1ZCwgXFxcIkZuOjpCYXNlNjRcXFwiLCBudWxsKVxcblxcdGlzX3N0cmluZyhpbm5lcilcXG5cXHRjb3VudChpbm5lcikgPiBfcGZfdWRzel9saW1pdFxcbn1cXG5cIlxuICB9LFxuICB7XG4gICAgXCJpZFwiOiBcInBmLWVjMi12b2x1bWUtaW9wc1wiLFxuICAgIFwic2VydmljZVwiOiBcImVjMlwiLFxuICAgIFwic2V2ZXJpdHlcIjogXCJFUlJPUlwiLFxuICAgIFwidGl0bGVcIjogXCJFQlMgSW9wcy9UaHJvdWdocHV0IG11c3QgbWF0Y2ggdGhlIHZvbHVtZSB0eXBlJ3Mgc3VwcG9ydGVkIHJhbmdlcyBhbmQgcmF0aW9zXCIsXG4gICAgXCJ1cHN0cmVhbVwiOiBcIm5vbmVcIixcbiAgICBcInJlc291cmNlVHlwZXNcIjogW1xuICAgICAgXCJBV1M6OkVDMjo6Vm9sdW1lXCJcbiAgICBdLFxuICAgIFwicmVnb1wiOiBcInBhY2thZ2UgY2RrX3ByZWZsaWdodFxcblxcbmltcG9ydCByZWdvLnYxXFxuXFxuX3BmX3ZvbGlvcHNfZml4IDo9IFxcXCJNYXRjaCBJb3BzL1Rocm91Z2hwdXQgdG8gdGhlIHZvbHVtZSB0eXBlOiBncDMgMzAwMC04MDAwMCBJT1BTIChtYXggNTAwL0dpQiwgdGhyb3VnaHB1dCAxMjUtMjAwMCBNaUIvcyBhbmQgYXQgbW9zdCBJT1BTLzQpLCBpbzEgMTAwLTY0MDAwIChtYXggNTAvR2lCKSwgaW8yIDEwMC0yNTYwMDAgKG1heCAxMDAwL0dpQik7IGdwMi9zdDEvc2MxL3N0YW5kYXJkIGFjY2VwdCBuZWl0aGVyIHByb3BlcnR5XFxcIlxcblxcbl9wZl92b2xpb3BzX3VybCA6PSBcXFwiaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2Vicy9sYXRlc3QvdXNlcmd1aWRlL2Vicy12b2x1bWUtdHlwZXMuaHRtbFxcXCJcXG5cXG5fcGZfdm9saW9wc19yYW5nZSA6PSB7XFxcImdwM1xcXCI6IFszMDAwLCA4MDAwMF0sIFxcXCJpbzFcXFwiOiBbMTAwLCA2NDAwMF0sIFxcXCJpbzJcXFwiOiBbMTAwLCAyNTYwMDBdfVxcblxcbl9wZl92b2xpb3BzX3Blcl9naWIgOj0ge1xcXCJncDNcXFwiOiA1MDAsIFxcXCJpbzFcXFwiOiA1MCwgXFxcImlvMlxcXCI6IDEwMDB9XFxuXFxuX3BmX3ZvbGlvcHNfb3V0KG4sIGxvLCBoaSkgaWYgbiA8IGxvXFxuXFxuX3BmX3ZvbGlvcHNfb3V0KG4sIGxvLCBoaSkgaWYgbiA+IGhpXFxuXFxuX3BmX3ZvbGlvcHNfaGFzX2lvcHMobmFtZSkgaWYgcmVzb2x2ZShuYW1lLCBcXFwiUHJvcGVydGllcy5Jb3BzXFxcIilcXG5cXG4jIElPUFMg44GM5Z6L44GU44Go44Gu57W25a++44Os44Oz44K45aSWXFxudmlvbGF0aW9uIGNvbnRhaW5zIG1ha2VfZGlhZ19mdWxsKFxcXCJwZi1lYzItdm9sdW1lLWlvcHNcXFwiLCBcXFwiRVJST1JcXFwiLCBuYW1lLCBcXFwiUHJvcGVydGllcy5Jb3BzXFxcIixcXG5cXHRzcHJpbnRmKFxcXCJJb3BzICV2IGlzIG91dHNpZGUgdGhlIHN1cHBvcnRlZCByYW5nZSAlZC0lZCBmb3IgJXMgdm9sdW1lc1xcXCIsIFtuLCByWzBdLCByWzFdLCB2dF0pLFxcblxcdF9wZl92b2xpb3BzX2ZpeCwgX3BmX3ZvbGlvcHNfdXJsKSBpZiB7XFxuXFx0c29tZSBuYW1lIGluIHJlc291cmNlc19vZl90eXBlKFxcXCJBV1M6OkVDMjo6Vm9sdW1lXFxcIilcXG5cXHR2dCA6PSByZXNvbHZlKG5hbWUsIFxcXCJQcm9wZXJ0aWVzLlZvbHVtZVR5cGVcXFwiKVxcblxcdHIgOj0gX3BmX3ZvbGlvcHNfcmFuZ2VbdnRdXFxuXFx0biA6PSB0b19udW1iZXIocmVzb2x2ZShuYW1lLCBcXFwiUHJvcGVydGllcy5Jb3BzXFxcIikpXFxuXFx0X3BmX3ZvbGlvcHNfb3V0KG4sIHJbMF0sIHJbMV0pXFxufVxcblxcbiMgSU9QUyA6IOOCteOCpOOCuuavlOOBrui2hemBjlxcbnZpb2xhdGlvbiBjb250YWlucyBtYWtlX2RpYWdfZnVsbChcXFwicGYtZWMyLXZvbHVtZS1pb3BzXFxcIiwgXFxcIkVSUk9SXFxcIiwgbmFtZSwgXFxcIlByb3BlcnRpZXMuSW9wc1xcXCIsXFxuXFx0c3ByaW50ZihcXFwiSW9wcyAldiBleGNlZWRzIHRoZSBtYXhpbXVtIHJhdGlvIG9mICVkIElPUFMgcGVyIEdpQiBmb3IgJXMgKFNpemUgJXYgR2lCIGFsbG93cyBhdCBtb3N0ICV2KVxcXCIsIFtuLCByYXRpbywgdnQsIHMsIHMgKiByYXRpb10pLFxcblxcdF9wZl92b2xpb3BzX2ZpeCwgX3BmX3ZvbGlvcHNfdXJsKSBpZiB7XFxuXFx0c29tZSBuYW1lIGluIHJlc291cmNlc19vZl90eXBlKFxcXCJBV1M6OkVDMjo6Vm9sdW1lXFxcIilcXG5cXHR2dCA6PSByZXNvbHZlKG5hbWUsIFxcXCJQcm9wZXJ0aWVzLlZvbHVtZVR5cGVcXFwiKVxcblxcdHJhdGlvIDo9IF9wZl92b2xpb3BzX3Blcl9naWJbdnRdXFxuXFx0biA6PSB0b19udW1iZXIocmVzb2x2ZShuYW1lLCBcXFwiUHJvcGVydGllcy5Jb3BzXFxcIikpXFxuXFx0cyA6PSB0b19udW1iZXIocmVzb2x2ZShuYW1lLCBcXFwiUHJvcGVydGllcy5TaXplXFxcIikpXFxuXFx0biA+IHMgKiByYXRpb1xcbn1cXG5cXG4jIElvcHMg44KS5Y+X44GR5LuY44GR44Gq44GE5Z6L44GrIElvcHMg44KS5oyH5a6aXFxudmlvbGF0aW9uIGNvbnRhaW5zIG1ha2VfZGlhZ19mdWxsKFxcXCJwZi1lYzItdm9sdW1lLWlvcHNcXFwiLCBcXFwiRVJST1JcXFwiLCBuYW1lLCBcXFwiUHJvcGVydGllcy5Jb3BzXFxcIixcXG5cXHRzcHJpbnRmKFxcXCJJb3BzIGlzIG5vdCBzdXBwb3J0ZWQgZm9yICVzIHZvbHVtZXMgKHZhbGlkIG9ubHkgZm9yIGdwMywgaW8xLCBpbzIpOyBFQzIgcmVqZWN0cyB0aGUgQ3JlYXRlVm9sdW1lIGNhbGxcXFwiLCBbdnRdKSxcXG5cXHRfcGZfdm9saW9wc19maXgsIF9wZl92b2xpb3BzX3VybCkgaWYge1xcblxcdHNvbWUgbmFtZSBpbiByZXNvdXJjZXNfb2ZfdHlwZShcXFwiQVdTOjpFQzI6OlZvbHVtZVxcXCIpXFxuXFx0dnQgOj0gcmVzb2x2ZShuYW1lLCBcXFwiUHJvcGVydGllcy5Wb2x1bWVUeXBlXFxcIilcXG5cXHR2dCBpbiB7XFxcImdwMlxcXCIsIFxcXCJzdDFcXFwiLCBcXFwic2MxXFxcIiwgXFxcInN0YW5kYXJkXFxcIn1cXG5cXHRyZXNvbHZlKG5hbWUsIFxcXCJQcm9wZXJ0aWVzLklvcHNcXFwiKVxcbn1cXG5cXG4jIFRocm91Z2hwdXQg44GvIGdwMyDlsILnlKhcXG52aW9sYXRpb24gY29udGFpbnMgbWFrZV9kaWFnX2Z1bGwoXFxcInBmLWVjMi12b2x1bWUtaW9wc1xcXCIsIFxcXCJFUlJPUlxcXCIsIG5hbWUsIFxcXCJQcm9wZXJ0aWVzLlRocm91Z2hwdXRcXFwiLFxcblxcdHNwcmludGYoXFxcIlRocm91Z2hwdXQgaXMgbm90IHN1cHBvcnRlZCBmb3IgJXMgdm9sdW1lcyAodmFsaWQgb25seSBmb3IgZ3AzKTsgRUMyIHJlamVjdHMgdGhlIENyZWF0ZVZvbHVtZSBjYWxsXFxcIiwgW3Z0XSksXFxuXFx0X3BmX3ZvbGlvcHNfZml4LCBfcGZfdm9saW9wc191cmwpIGlmIHtcXG5cXHRzb21lIG5hbWUgaW4gcmVzb3VyY2VzX29mX3R5cGUoXFxcIkFXUzo6RUMyOjpWb2x1bWVcXFwiKVxcblxcdHZ0IDo9IHJlc29sdmUobmFtZSwgXFxcIlByb3BlcnRpZXMuVm9sdW1lVHlwZVxcXCIpXFxuXFx0aXNfc3RyaW5nKHZ0KVxcblxcdHZ0ICE9IFxcXCJncDNcXFwiXFxuXFx0cmVzb2x2ZShuYW1lLCBcXFwiUHJvcGVydGllcy5UaHJvdWdocHV0XFxcIilcXG59XFxuXFxuIyBncDMgVGhyb3VnaHB1dCDjga7ntbblr77jg6zjg7PjgrhcXG52aW9sYXRpb24gY29udGFpbnMgbWFrZV9kaWFnX2Z1bGwoXFxcInBmLWVjMi12b2x1bWUtaW9wc1xcXCIsIFxcXCJFUlJPUlxcXCIsIG5hbWUsIFxcXCJQcm9wZXJ0aWVzLlRocm91Z2hwdXRcXFwiLFxcblxcdHNwcmludGYoXFxcIlRocm91Z2hwdXQgJXYgTWlCL3MgaXMgb3V0c2lkZSB0aGUgc3VwcG9ydGVkIHJhbmdlIDEyNS0yMDAwIGZvciBncDMgdm9sdW1lc1xcXCIsIFt0XSksXFxuXFx0X3BmX3ZvbGlvcHNfZml4LCBfcGZfdm9saW9wc191cmwpIGlmIHtcXG5cXHRzb21lIG5hbWUgaW4gcmVzb3VyY2VzX29mX3R5cGUoXFxcIkFXUzo6RUMyOjpWb2x1bWVcXFwiKVxcblxcdHJlc29sdmUobmFtZSwgXFxcIlByb3BlcnRpZXMuVm9sdW1lVHlwZVxcXCIpID09IFxcXCJncDNcXFwiXFxuXFx0dCA6PSB0b19udW1iZXIocmVzb2x2ZShuYW1lLCBcXFwiUHJvcGVydGllcy5UaHJvdWdocHV0XFxcIikpXFxuXFx0X3BmX3ZvbGlvcHNfb3V0KHQsIDEyNSwgMjAwMClcXG59XFxuXFxuIyBncDMgVGhyb3VnaHB1dCA6IElPUFMg5q+U77yI5pyA5aSnIDAuMjUgTWlCL3MgcGVyIElPUFPvvIlcXG52aW9sYXRpb24gY29udGFpbnMgbWFrZV9kaWFnX2Z1bGwoXFxcInBmLWVjMi12b2x1bWUtaW9wc1xcXCIsIFxcXCJFUlJPUlxcXCIsIG5hbWUsIFxcXCJQcm9wZXJ0aWVzLlRocm91Z2hwdXRcXFwiLFxcblxcdHNwcmludGYoXFxcIlRocm91Z2hwdXQgJXYgTWlCL3MgZXhjZWVkcyB0aGUgbWF4aW11bSByYXRpbyBvZiAwLjI1IE1pQi9zIHBlciBwcm92aXNpb25lZCBJT1BTICgldiBJT1BTIGFsbG93cyBhdCBtb3N0ICV2KVxcXCIsIFt0LCBuLCBuIC8gNF0pLFxcblxcdF9wZl92b2xpb3BzX2ZpeCwgX3BmX3ZvbGlvcHNfdXJsKSBpZiB7XFxuXFx0c29tZSBuYW1lIGluIHJlc291cmNlc19vZl90eXBlKFxcXCJBV1M6OkVDMjo6Vm9sdW1lXFxcIilcXG5cXHRyZXNvbHZlKG5hbWUsIFxcXCJQcm9wZXJ0aWVzLlZvbHVtZVR5cGVcXFwiKSA9PSBcXFwiZ3AzXFxcIlxcblxcdHQgOj0gdG9fbnVtYmVyKHJlc29sdmUobmFtZSwgXFxcIlByb3BlcnRpZXMuVGhyb3VnaHB1dFxcXCIpKVxcblxcdG4gOj0gdG9fbnVtYmVyKHJlc29sdmUobmFtZSwgXFxcIlByb3BlcnRpZXMuSW9wc1xcXCIpKVxcblxcdHQgKiA0ID4gblxcbn1cXG5cXG4jIGdwMyDjgacgSW9wcyDmnKrmjIflrprvvIjjg4fjg5Xjgqnjg6vjg4ggMzAwMO+8ieOBruOBqOOBjeOBriBUaHJvdWdocHV0IOavlFxcbnZpb2xhdGlvbiBjb250YWlucyBtYWtlX2RpYWdfZnVsbChcXFwicGYtZWMyLXZvbHVtZS1pb3BzXFxcIiwgXFxcIkVSUk9SXFxcIiwgbmFtZSwgXFxcIlByb3BlcnRpZXMuVGhyb3VnaHB1dFxcXCIsXFxuXFx0c3ByaW50ZihcXFwiVGhyb3VnaHB1dCAldiBNaUIvcyBleGNlZWRzIDc1MCwgdGhlIG1heGltdW0gZm9yIHRoZSBkZWZhdWx0IDMwMDAgSU9QUyAoMC4yNSBNaUIvcyBwZXIgSU9QUyk7IHByb3Zpc2lvbiBJb3BzIGV4cGxpY2l0bHkgb3IgbG93ZXIgdGhlIHRocm91Z2hwdXRcXFwiLCBbdF0pLFxcblxcdF9wZl92b2xpb3BzX2ZpeCwgX3BmX3ZvbGlvcHNfdXJsKSBpZiB7XFxuXFx0c29tZSBuYW1lIGluIHJlc291cmNlc19vZl90eXBlKFxcXCJBV1M6OkVDMjo6Vm9sdW1lXFxcIilcXG5cXHRyZXNvbHZlKG5hbWUsIFxcXCJQcm9wZXJ0aWVzLlZvbHVtZVR5cGVcXFwiKSA9PSBcXFwiZ3AzXFxcIlxcblxcdG5vdCBfcGZfdm9saW9wc19oYXNfaW9wcyhuYW1lKVxcblxcdHQgOj0gdG9fbnVtYmVyKHJlc29sdmUobmFtZSwgXFxcIlByb3BlcnRpZXMuVGhyb3VnaHB1dFxcXCIpKVxcblxcdHQgPiA3NTBcXG59XFxuXCJcbiAgfSxcbiAge1xuICAgIFwiaWRcIjogXCJwZi1lY3MtZmFyZ2F0ZS1uZXR3b3JrLW1vZGVcIixcbiAgICBcInNlcnZpY2VcIjogXCJlY3NcIixcbiAgICBcInNldmVyaXR5XCI6IFwiRVJST1JcIixcbiAgICBcInRpdGxlXCI6IFwiRmFyZ2F0ZSB0YXNrIGRlZmluaXRpb25zIHJlcXVpcmUgTmV0d29ya01vZGUgJ2F3c3ZwYydcIixcbiAgICBcInVwc3RyZWFtXCI6IFwibm9uZVwiLFxuICAgIFwicmVzb3VyY2VUeXBlc1wiOiBbXG4gICAgICBcIkFXUzo6RUNTOjpUYXNrRGVmaW5pdGlvblwiXG4gICAgXSxcbiAgICBcInJlZ29cIjogXCJwYWNrYWdlIGNka19wcmVmbGlnaHRcXG5cXG5pbXBvcnQgcmVnby52MVxcblxcbl9wZl9lY3NubV91cmwgOj0gXFxcImh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BbWF6b25FQ1MvbGF0ZXN0L2RldmVsb3Blcmd1aWRlL3Rhc2tfZGVmaW5pdGlvbl9wYXJhbWV0ZXJzLmh0bWwjbmV0d29ya19tb2RlXFxcIlxcblxcbl9wZl9lY3NubV9oYXNfbW9kZShuYW1lKSBpZiByZXNvbHZlKG5hbWUsIFxcXCJQcm9wZXJ0aWVzLk5ldHdvcmtNb2RlXFxcIilcXG5cXG52aW9sYXRpb24gY29udGFpbnMgbWFrZV9kaWFnX2Z1bGwoXFxcInBmLWVjcy1mYXJnYXRlLW5ldHdvcmstbW9kZVxcXCIsIFxcXCJFUlJPUlxcXCIsIG5hbWUsXFxuXFx0XFxcIlByb3BlcnRpZXMuTmV0d29ya01vZGVcXFwiLFxcblxcdHNwcmludGYoXFxcIk5ldHdvcmtNb2RlIGlzICclcycgYnV0IHRhc2sgZGVmaW5pdGlvbnMgcmVxdWlyaW5nIEZBUkdBVEUgY29tcGF0aWJpbGl0eSBtdXN0IHVzZSAnYXdzdnBjJzsgUmVnaXN0ZXJUYXNrRGVmaW5pdGlvbiBmYWlscyBhdCBkZXBsb3kgdGltZVxcXCIsIFtubV0pLFxcblxcdFxcXCJTZXQgTmV0d29ya01vZGUgdG8gJ2F3c3ZwYydcXFwiLFxcblxcdF9wZl9lY3NubV91cmwpIGlmIHtcXG5cXHRzb21lIG5hbWUgaW4gcmVzb3VyY2VzX29mX3R5cGUoXFxcIkFXUzo6RUNTOjpUYXNrRGVmaW5pdGlvblxcXCIpXFxuXFx0cmMgOj0gcmVzb2x2ZShuYW1lLCBcXFwiUHJvcGVydGllcy5SZXF1aXJlc0NvbXBhdGliaWxpdGllc1xcXCIpXFxuXFx0aXNfYXJyYXkocmMpXFxuXFx0XFxcIkZBUkdBVEVcXFwiIGluIHJjXFxuXFx0bm0gOj0gcmVzb2x2ZShuYW1lLCBcXFwiUHJvcGVydGllcy5OZXR3b3JrTW9kZVxcXCIpXFxuXFx0aXNfc3RyaW5nKG5tKVxcblxcdG5tICE9IFxcXCJhd3N2cGNcXFwiXFxufVxcblxcbiMgTmV0d29ya01vZGUg5pyq5oyH5a6a44Gn44KCIFJlZ2lzdGVyVGFza0RlZmluaXRpb24g44GvXFxuIyBcXFwiRmFyZ2F0ZSBvbmx5IHN1cHBvcnRzIG5ldHdvcmsgbW9kZSAnYXdzdnBjJy5cXFwiIOOBp+WkseaVl+OBmeOCi++8iDIwMjYtMDktMDEg5a6fIEFQSSDnorroqo3vvIlcXG52aW9sYXRpb24gY29udGFpbnMgbWFrZV9kaWFnX2Z1bGwoXFxcInBmLWVjcy1mYXJnYXRlLW5ldHdvcmstbW9kZVxcXCIsIFxcXCJFUlJPUlxcXCIsIG5hbWUsXFxuXFx0XFxcIlByb3BlcnRpZXMuTmV0d29ya01vZGVcXFwiLFxcblxcdFxcXCJOZXR3b3JrTW9kZSBpcyBub3Qgc2V0LCBidXQgdGFzayBkZWZpbml0aW9ucyByZXF1aXJpbmcgRkFSR0FURSBjb21wYXRpYmlsaXR5IG11c3Qgc2V0IGl0IHRvICdhd3N2cGMnOyBSZWdpc3RlclRhc2tEZWZpbml0aW9uIGZhaWxzIGF0IGRlcGxveSB0aW1lXFxcIixcXG5cXHRcXFwiU2V0IE5ldHdvcmtNb2RlIHRvICdhd3N2cGMnXFxcIixcXG5cXHRfcGZfZWNzbm1fdXJsKSBpZiB7XFxuXFx0c29tZSBuYW1lIGluIHJlc291cmNlc19vZl90eXBlKFxcXCJBV1M6OkVDUzo6VGFza0RlZmluaXRpb25cXFwiKVxcblxcdHJjIDo9IHJlc29sdmUobmFtZSwgXFxcIlByb3BlcnRpZXMuUmVxdWlyZXNDb21wYXRpYmlsaXRpZXNcXFwiKVxcblxcdGlzX2FycmF5KHJjKVxcblxcdFxcXCJGQVJHQVRFXFxcIiBpbiByY1xcblxcdG5vdCBfcGZfZWNzbm1faGFzX21vZGUobmFtZSlcXG59XFxuXCJcbiAgfSxcbiAge1xuICAgIFwiaWRcIjogXCJwZi1lbGJ2Mi1sYi1pZGxlLXRpbWVvdXQtcmFuZ2VcIixcbiAgICBcInNlcnZpY2VcIjogXCJlbGJ2MlwiLFxuICAgIFwic2V2ZXJpdHlcIjogXCJFUlJPUlwiLFxuICAgIFwidGl0bGVcIjogXCJBTEIgaWRsZV90aW1lb3V0LnRpbWVvdXRfc2Vjb25kcyBtdXN0IGJlIGJldHdlZW4gMSBhbmQgNDAwMFwiLFxuICAgIFwidXBzdHJlYW1cIjogXCJub25lXCIsXG4gICAgXCJyZXNvdXJjZVR5cGVzXCI6IFtcbiAgICAgIFwiQVdTOjpFbGFzdGljTG9hZEJhbGFuY2luZ1YyOjpMb2FkQmFsYW5jZXJcIlxuICAgIF0sXG4gICAgXCJyZWdvXCI6IFwicGFja2FnZSBjZGtfcHJlZmxpZ2h0XFxuXFxuaW1wb3J0IHJlZ28udjFcXG5cXG5fcGZfaWRsZV90aW1lb3V0X291dChuKSBpZiBuIDwgMVxcblxcbl9wZl9pZGxlX3RpbWVvdXRfb3V0KG4pIGlmIG4gPiA0MDAwXFxuXFxuX3BmX25vbl9hbGIobmFtZSkgaWYge1xcblxcdHQgOj0gcmVzb2x2ZShuYW1lLCBcXFwiUHJvcGVydGllcy5UeXBlXFxcIilcXG5cXHR0ICE9IFxcXCJhcHBsaWNhdGlvblxcXCJcXG59XFxuXFxudmlvbGF0aW9uIGNvbnRhaW5zIG1ha2VfZGlhZ19mdWxsKFxcXCJwZi1lbGJ2Mi1sYi1pZGxlLXRpbWVvdXQtcmFuZ2VcXFwiLCBcXFwiRVJST1JcXFwiLCBuYW1lLFxcblxcdHNwcmludGYoXFxcIlByb3BlcnRpZXMuTG9hZEJhbGFuY2VyQXR0cmlidXRlcy4lZC5WYWx1ZVxcXCIsIFtpdGVtLmluZGV4XSksXFxuXFx0c3ByaW50ZihcXFwiaWRsZV90aW1lb3V0LnRpbWVvdXRfc2Vjb25kcyBpcyAldiBidXQgbXVzdCBiZSBiZXR3ZWVuIDEgYW5kIDQwMDAgc2Vjb25kc1xcXCIsIFtudW1dKSxcXG5cXHRcXFwiU2V0IGlkbGVfdGltZW91dC50aW1lb3V0X3NlY29uZHMgdG8gYSB2YWx1ZSBiZXR3ZWVuIDEgYW5kIDQwMDBcXFwiLFxcblxcdFxcXCJodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vZWxhc3RpY2xvYWRiYWxhbmNpbmcvbGF0ZXN0L2FwcGxpY2F0aW9uL2FwcGxpY2F0aW9uLWxvYWQtYmFsYW5jZXJzLmh0bWwjY29ubmVjdGlvbi1pZGxlLXRpbWVvdXRcXFwiKSBpZiB7XFxuXFx0c29tZSBuYW1lIGluIHJlc291cmNlc19vZl90eXBlKFxcXCJBV1M6OkVsYXN0aWNMb2FkQmFsYW5jaW5nVjI6OkxvYWRCYWxhbmNlclxcXCIpXFxuXFx0bm90IF9wZl9ub25fYWxiKG5hbWUpXFxuXFx0c29tZSBpdGVtIGluIGZsYXR0ZW5fbGlzdChuYW1lLCBcXFwiUHJvcGVydGllcy5Mb2FkQmFsYW5jZXJBdHRyaWJ1dGVzXFxcIilcXG5cXHRhdHRyIDo9IGl0ZW0udmFsdWVcXG5cXHRpc19vYmplY3QoYXR0cilcXG5cXHRvYmplY3QuZ2V0KGF0dHIsIFxcXCJLZXlcXFwiLCBcXFwiXFxcIikgPT0gXFxcImlkbGVfdGltZW91dC50aW1lb3V0X3NlY29uZHNcXFwiXFxuXFx0bnVtIDo9IHRvX251bWJlcihvYmplY3QuZ2V0KGF0dHIsIFxcXCJWYWx1ZVxcXCIsIG51bGwpKVxcblxcdF9wZl9pZGxlX3RpbWVvdXRfb3V0KG51bSlcXG59XFxuXCJcbiAgfSxcbiAge1xuICAgIFwiaWRcIjogXCJwZi1lbGJ2Mi10Zy1kZXJlZ2lzdHJhdGlvbi1kZWxheS1yYW5nZVwiLFxuICAgIFwic2VydmljZVwiOiBcImVsYnYyXCIsXG4gICAgXCJzZXZlcml0eVwiOiBcIkVSUk9SXCIsXG4gICAgXCJ0aXRsZVwiOiBcIlRhcmdldCBncm91cCBkZXJlZ2lzdHJhdGlvbl9kZWxheS50aW1lb3V0X3NlY29uZHMgbXVzdCBiZSBiZXR3ZWVuIDAgYW5kIDM2MDBcIixcbiAgICBcInVwc3RyZWFtXCI6IFwibm9uZVwiLFxuICAgIFwicmVzb3VyY2VUeXBlc1wiOiBbXG4gICAgICBcIkFXUzo6RWxhc3RpY0xvYWRCYWxhbmNpbmdWMjo6VGFyZ2V0R3JvdXBcIlxuICAgIF0sXG4gICAgXCJyZWdvXCI6IFwicGFja2FnZSBjZGtfcHJlZmxpZ2h0XFxuXFxuaW1wb3J0IHJlZ28udjFcXG5cXG5fcGZfZGVyZWdfZGVsYXlfb3V0KG4pIGlmIG4gPCAwXFxuXFxuX3BmX2RlcmVnX2RlbGF5X291dChuKSBpZiBuID4gMzYwMFxcblxcbnZpb2xhdGlvbiBjb250YWlucyBtYWtlX2RpYWdfZnVsbChcXFwicGYtZWxidjItdGctZGVyZWdpc3RyYXRpb24tZGVsYXktcmFuZ2VcXFwiLCBcXFwiRVJST1JcXFwiLCBuYW1lLFxcblxcdHNwcmludGYoXFxcIlByb3BlcnRpZXMuVGFyZ2V0R3JvdXBBdHRyaWJ1dGVzLiVkLlZhbHVlXFxcIiwgW2l0ZW0uaW5kZXhdKSxcXG5cXHRzcHJpbnRmKFxcXCJkZXJlZ2lzdHJhdGlvbl9kZWxheS50aW1lb3V0X3NlY29uZHMgaXMgJXYgYnV0IG11c3QgYmUgYmV0d2VlbiAwIGFuZCAzNjAwIHNlY29uZHNcXFwiLCBbbnVtXSksXFxuXFx0XFxcIlNldCBkZXJlZ2lzdHJhdGlvbl9kZWxheS50aW1lb3V0X3NlY29uZHMgdG8gYSB2YWx1ZSBiZXR3ZWVuIDAgYW5kIDM2MDBcXFwiLFxcblxcdFxcXCJodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vZWxhc3RpY2xvYWRiYWxhbmNpbmcvbGF0ZXN0L2FwcGxpY2F0aW9uL2VkaXQtdGFyZ2V0LWdyb3VwLWF0dHJpYnV0ZXMuaHRtbCNkZXJlZ2lzdHJhdGlvbi1kZWxheVxcXCIpIGlmIHtcXG5cXHRzb21lIG5hbWUgaW4gcmVzb3VyY2VzX29mX3R5cGUoXFxcIkFXUzo6RWxhc3RpY0xvYWRCYWxhbmNpbmdWMjo6VGFyZ2V0R3JvdXBcXFwiKVxcblxcdHNvbWUgaXRlbSBpbiBmbGF0dGVuX2xpc3QobmFtZSwgXFxcIlByb3BlcnRpZXMuVGFyZ2V0R3JvdXBBdHRyaWJ1dGVzXFxcIilcXG5cXHRhdHRyIDo9IGl0ZW0udmFsdWVcXG5cXHRpc19vYmplY3QoYXR0cilcXG5cXHRvYmplY3QuZ2V0KGF0dHIsIFxcXCJLZXlcXFwiLCBcXFwiXFxcIikgPT0gXFxcImRlcmVnaXN0cmF0aW9uX2RlbGF5LnRpbWVvdXRfc2Vjb25kc1xcXCJcXG5cXHRudW0gOj0gdG9fbnVtYmVyKG9iamVjdC5nZXQoYXR0ciwgXFxcIlZhbHVlXFxcIiwgbnVsbCkpXFxuXFx0X3BmX2RlcmVnX2RlbGF5X291dChudW0pXFxufVxcblwiXG4gIH0sXG4gIHtcbiAgICBcImlkXCI6IFwicGYtZWxidjItdGctc2xvdy1zdGFydC1yYW5nZVwiLFxuICAgIFwic2VydmljZVwiOiBcImVsYnYyXCIsXG4gICAgXCJzZXZlcml0eVwiOiBcIkVSUk9SXCIsXG4gICAgXCJ0aXRsZVwiOiBcIlRhcmdldCBncm91cCBzbG93X3N0YXJ0LmR1cmF0aW9uX3NlY29uZHMgbXVzdCBiZSAwIG9yIGJldHdlZW4gMzAgYW5kIDkwMFwiLFxuICAgIFwidXBzdHJlYW1cIjogXCJub25lXCIsXG4gICAgXCJyZXNvdXJjZVR5cGVzXCI6IFtcbiAgICAgIFwiQVdTOjpFbGFzdGljTG9hZEJhbGFuY2luZ1YyOjpUYXJnZXRHcm91cFwiXG4gICAgXSxcbiAgICBcInJlZ29cIjogXCJwYWNrYWdlIGNka19wcmVmbGlnaHRcXG5cXG5pbXBvcnQgcmVnby52MVxcblxcbl9wZl9zbG93X3N0YXJ0X291dChuKSBpZiBuIDwgMFxcblxcbl9wZl9zbG93X3N0YXJ0X291dChuKSBpZiB7XFxuXFx0biA+IDBcXG5cXHRuIDwgMzBcXG59XFxuXFxuX3BmX3Nsb3dfc3RhcnRfb3V0KG4pIGlmIG4gPiA5MDBcXG5cXG52aW9sYXRpb24gY29udGFpbnMgbWFrZV9kaWFnX2Z1bGwoXFxcInBmLWVsYnYyLXRnLXNsb3ctc3RhcnQtcmFuZ2VcXFwiLCBcXFwiRVJST1JcXFwiLCBuYW1lLFxcblxcdHNwcmludGYoXFxcIlByb3BlcnRpZXMuVGFyZ2V0R3JvdXBBdHRyaWJ1dGVzLiVkLlZhbHVlXFxcIiwgW2l0ZW0uaW5kZXhdKSxcXG5cXHRzcHJpbnRmKFxcXCJzbG93X3N0YXJ0LmR1cmF0aW9uX3NlY29uZHMgaXMgJXYgYnV0IG11c3QgYmUgMCAoZGlzYWJsZWQpIG9yIGJldHdlZW4gMzAgYW5kIDkwMCBzZWNvbmRzXFxcIiwgW251bV0pLFxcblxcdFxcXCJTZXQgc2xvd19zdGFydC5kdXJhdGlvbl9zZWNvbmRzIHRvIDAgb3IgYSB2YWx1ZSBiZXR3ZWVuIDMwIGFuZCA5MDBcXFwiLFxcblxcdFxcXCJodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vZWxhc3RpY2xvYWRiYWxhbmNpbmcvbGF0ZXN0L2FwcGxpY2F0aW9uL2VkaXQtdGFyZ2V0LWdyb3VwLWF0dHJpYnV0ZXMuaHRtbCNzbG93LXN0YXJ0LW1vZGVcXFwiKSBpZiB7XFxuXFx0c29tZSBuYW1lIGluIHJlc291cmNlc19vZl90eXBlKFxcXCJBV1M6OkVsYXN0aWNMb2FkQmFsYW5jaW5nVjI6OlRhcmdldEdyb3VwXFxcIilcXG5cXHRzb21lIGl0ZW0gaW4gZmxhdHRlbl9saXN0KG5hbWUsIFxcXCJQcm9wZXJ0aWVzLlRhcmdldEdyb3VwQXR0cmlidXRlc1xcXCIpXFxuXFx0YXR0ciA6PSBpdGVtLnZhbHVlXFxuXFx0aXNfb2JqZWN0KGF0dHIpXFxuXFx0b2JqZWN0LmdldChhdHRyLCBcXFwiS2V5XFxcIiwgXFxcIlxcXCIpID09IFxcXCJzbG93X3N0YXJ0LmR1cmF0aW9uX3NlY29uZHNcXFwiXFxuXFx0bnVtIDo9IHRvX251bWJlcihvYmplY3QuZ2V0KGF0dHIsIFxcXCJWYWx1ZVxcXCIsIG51bGwpKVxcblxcdF9wZl9zbG93X3N0YXJ0X291dChudW0pXFxufVxcblwiXG4gIH0sXG4gIHtcbiAgICBcImlkXCI6IFwicGYtaWFtLWlubGluZS1wb2xpY3ktc2l6ZVwiLFxuICAgIFwic2VydmljZVwiOiBcImlhbVwiLFxuICAgIFwic2V2ZXJpdHlcIjogXCJFUlJPUlwiLFxuICAgIFwidGl0bGVcIjogXCJJbmxpbmUgcG9saWN5IGRvY3VtZW50cyBhcmUgbGltaXRlZCBwZXIgaWRlbnRpdHkgKHJvbGUgMTAyNDAgLyBncm91cCA1MTIwIC8gdXNlciAyMDQ4IGNoYXJhY3RlcnMpXCIsXG4gICAgXCJ1cHN0cmVhbVwiOiBcIm5vbmVcIixcbiAgICBcInJlc291cmNlVHlwZXNcIjogW1xuICAgICAgXCJBV1M6OklBTTo6UG9saWN5XCIsXG4gICAgICBcIkFXUzo6SUFNOjpSb2xlUG9saWN5XCIsXG4gICAgICBcIkFXUzo6SUFNOjpVc2VyUG9saWN5XCIsXG4gICAgICBcIkFXUzo6SUFNOjpHcm91cFBvbGljeVwiXG4gICAgXSxcbiAgICBcInJlZ29cIjogXCJwYWNrYWdlIGNka19wcmVmbGlnaHRcXG5cXG5pbXBvcnQgcmVnby52MVxcblxcbl9wZl9pbmxpbmVfcG9saWN5X2xpbWl0cyA6PSB7XFxuXFx0XFxcIkFXUzo6SUFNOjpQb2xpY3lcXFwiOiAxMDI0MCxcXG5cXHRcXFwiQVdTOjpJQU06OlJvbGVQb2xpY3lcXFwiOiAxMDI0MCxcXG5cXHRcXFwiQVdTOjpJQU06OlVzZXJQb2xpY3lcXFwiOiAyMDQ4LFxcblxcdFxcXCJBV1M6OklBTTo6R3JvdXBQb2xpY3lcXFwiOiA1MTIwLFxcbn1cXG5cXG52aW9sYXRpb24gY29udGFpbnMgbWFrZV9kaWFnX2Z1bGwoXFxcInBmLWlhbS1pbmxpbmUtcG9saWN5LXNpemVcXFwiLCBcXFwiRVJST1JcXFwiLCBuYW1lLFxcblxcdFxcXCJQcm9wZXJ0aWVzLlBvbGljeURvY3VtZW50XFxcIixcXG5cXHRzcHJpbnRmKFxcXCJQb2xpY3lEb2N1bWVudCBpcyAlZCBjaGFyYWN0ZXJzIChKU09OIHdpdGhvdXQgd2hpdGVzcGFjZSkgYnV0IHRoZSBpbmxpbmUgcG9saWN5IGxpbWl0IGZvciAlcyBpcyAlZCAocm9sZTogMTAyNDAsIGdyb3VwOiA1MTIwLCB1c2VyOiAyMDQ4KVxcXCIsIFtzaXplLCBydHlwZSwgbGltaXRdKSxcXG5cXHRcXFwiTW92ZSBzdGF0ZW1lbnRzIGludG8gbWFuYWdlZCBwb2xpY2llcyBvciBzaG9ydGVuIHRoZSBkb2N1bWVudFxcXCIsXFxuXFx0XFxcImh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9yZWZlcmVuY2VfaWFtLXF1b3Rhcy5odG1sXFxcIikgaWYge1xcblxcdHNvbWUgcnR5cGUsIGxpbWl0IGluIF9wZl9pbmxpbmVfcG9saWN5X2xpbWl0c1xcblxcdHNvbWUgbmFtZSBpbiByZXNvdXJjZXNfb2ZfdHlwZShydHlwZSlcXG5cXHRkb2MgOj0gcmVzb2x2ZShuYW1lLCBcXFwiUHJvcGVydGllcy5Qb2xpY3lEb2N1bWVudFxcXCIpXFxuXFx0aXNfb2JqZWN0KGRvYylcXG5cXHRzaXplIDo9IGNvdW50KGpzb24ubWFyc2hhbChkb2MpKVxcblxcdHNpemUgPiBsaW1pdFxcbn1cXG5cIlxuICB9LFxuICB7XG4gICAgXCJpZFwiOiBcInBmLWlhbS1tYW5hZ2VkLXBvbGljeS1jb3VudFwiLFxuICAgIFwic2VydmljZVwiOiBcImlhbVwiLFxuICAgIFwic2V2ZXJpdHlcIjogXCJFUlJPUlwiLFxuICAgIFwidGl0bGVcIjogXCJNYW5hZ2VkIHBvbGljaWVzIHBlciBpZGVudGl0eSBhcmUgY2FwcGVkIChoYXJkIG1heGltdW1zIHJvbGUgMjUgLyB1c2VyIDIwIC8gZ3JvdXAgMTApXCIsXG4gICAgXCJ1cHN0cmVhbVwiOiBcIm5vbmVcIixcbiAgICBcInJlc291cmNlVHlwZXNcIjogW1xuICAgICAgXCJBV1M6OklBTTo6Um9sZVwiLFxuICAgICAgXCJBV1M6OklBTTo6VXNlclwiLFxuICAgICAgXCJBV1M6OklBTTo6R3JvdXBcIlxuICAgIF0sXG4gICAgXCJyZWdvXCI6IFwicGFja2FnZSBjZGtfcHJlZmxpZ2h0XFxuXFxuaW1wb3J0IHJlZ28udjFcXG5cXG4jIOODj+ODvOODieS4iumZkO+8iFNlcnZpY2UgUXVvdGFzIOOBruOAjE1heGltdW0gcXVvdGHjgI09IOOBneOCjOS7peS4iuW8leOBjeS4iuOBkuS4jeWPr+iDveOBquWApO+8iTpcXG4jICAgcm9sZSAyNSAvIHVzZXIgMjAgLyBncm91cCAxMO+8iGdyb3VwIOOBryBhZGp1c3RhYmxlOiBmYWxzZeOAgeWun+a4rOOBp+OCgueiuuiqje+8ieOAglxcbiMg44OH44OV44Kp44Or44OI77yIcm9sZSAyMCAvIHVzZXIgMTAgLyBncm91cCAxMO+8iei2heOBr+OCouOCq+OCpuODs+ODiOOBruOCr+OCqeODvOOCv+W8leOBjeS4iuOBkuasoeesrOOBp1xcbiMg5oiQ5Yqf44GX5b6X44KL44Gf44KBIEVSUk9SIOOBq+OBl+OBquOBhO+8iGJlbmNoIOOCouOCq+OCpuODs+ODiOOBriByb2xlPTIwIOOBpyAxMSDlgIvmiJDlip/jgpLlrp/muKzmuIjjgb/vvInjgIJcXG5fcGZfaWFtcG9sX2xpbWl0cyA6PSB7XFxuXFx0XFxcIkFXUzo6SUFNOjpSb2xlXFxcIjogMjUsXFxuXFx0XFxcIkFXUzo6SUFNOjpVc2VyXFxcIjogMjAsXFxuXFx0XFxcIkFXUzo6SUFNOjpHcm91cFxcXCI6IDEwLFxcbn1cXG5cXG52aW9sYXRpb24gY29udGFpbnMgbWFrZV9kaWFnX2Z1bGwoXFxcInBmLWlhbS1tYW5hZ2VkLXBvbGljeS1jb3VudFxcXCIsIFxcXCJFUlJPUlxcXCIsIG5hbWUsXFxuXFx0XFxcIlByb3BlcnRpZXMuTWFuYWdlZFBvbGljeUFybnNcXFwiLFxcblxcdHNwcmludGYoXFxcIiVkIG1hbmFnZWQgcG9saWNpZXMgYXJlIGF0dGFjaGVkLCBidXQgdGhlIGhhcmQgbWF4aW11bSBmb3IgJXMgaXMgJWQgKHF1b3RhIGRlZmF1bHRzOiByb2xlIDIwLCB1c2VyIDEwLCBncm91cCAxMDsgcmFpc2FibGUgb25seSB1cCB0byB0aGUgaGFyZCBtYXhpbXVtKTsgZGVwbG95bWVudCBmYWlscyB3aXRoIExpbWl0RXhjZWVkZWRcXFwiLCBbbiwgcnR5cGUsIGxpbWl0XSksXFxuXFx0XFxcIkNvbnNvbGlkYXRlIHN0YXRlbWVudHMgaW50byBmZXdlciBtYW5hZ2VkIHBvbGljaWVzXFxcIixcXG5cXHRcXFwiaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL0lBTS9sYXRlc3QvVXNlckd1aWRlL3JlZmVyZW5jZV9pYW0tcXVvdGFzLmh0bWxcXFwiKSBpZiB7XFxuXFx0c29tZSBydHlwZSwgbGltaXQgaW4gX3BmX2lhbXBvbF9saW1pdHNcXG5cXHRzb21lIG5hbWUgaW4gcmVzb3VyY2VzX29mX3R5cGUocnR5cGUpXFxuXFx0YXJyIDo9IHJlc29sdmUobmFtZSwgXFxcIlByb3BlcnRpZXMuTWFuYWdlZFBvbGljeUFybnNcXFwiKVxcblxcdGlzX2FycmF5KGFycilcXG5cXHRuIDo9IGNvdW50KGFycilcXG5cXHRuID4gbGltaXRcXG59XFxuXCJcbiAgfSxcbiAge1xuICAgIFwiaWRcIjogXCJwZi1pYW0tbWFuYWdlZC1wb2xpY3ktc2l6ZVwiLFxuICAgIFwic2VydmljZVwiOiBcImlhbVwiLFxuICAgIFwic2V2ZXJpdHlcIjogXCJFUlJPUlwiLFxuICAgIFwidGl0bGVcIjogXCJNYW5hZ2VkIHBvbGljeSBkb2N1bWVudHMgYXJlIGxpbWl0ZWQgdG8gNjE0NCBjaGFyYWN0ZXJzICh3aGl0ZXNwYWNlIGV4Y2x1ZGVkKVwiLFxuICAgIFwidXBzdHJlYW1cIjogXCJub25lXCIsXG4gICAgXCJyZXNvdXJjZVR5cGVzXCI6IFtcbiAgICAgIFwiQVdTOjpJQU06Ok1hbmFnZWRQb2xpY3lcIlxuICAgIF0sXG4gICAgXCJyZWdvXCI6IFwicGFja2FnZSBjZGtfcHJlZmxpZ2h0XFxuXFxuaW1wb3J0IHJlZ28udjFcXG5cXG52aW9sYXRpb24gY29udGFpbnMgbWFrZV9kaWFnX2Z1bGwoXFxcInBmLWlhbS1tYW5hZ2VkLXBvbGljeS1zaXplXFxcIiwgXFxcIkVSUk9SXFxcIiwgbmFtZSxcXG5cXHRcXFwiUHJvcGVydGllcy5Qb2xpY3lEb2N1bWVudFxcXCIsXFxuXFx0c3ByaW50ZihcXFwiUG9saWN5RG9jdW1lbnQgaXMgJWQgY2hhcmFjdGVycyAoSlNPTiB3aXRob3V0IHdoaXRlc3BhY2UpIGJ1dCB0aGUgbWFuYWdlZCBwb2xpY3kgbGltaXQgaXMgNjE0NFxcXCIsIFtzaXplXSksXFxuXFx0XFxcIlNwbGl0IHRoZSBkb2N1bWVudCBpbnRvIG11bHRpcGxlIG1hbmFnZWQgcG9saWNpZXMgb3Igc2hvcnRlbiBpdFxcXCIsXFxuXFx0XFxcImh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9yZWZlcmVuY2VfaWFtLXF1b3Rhcy5odG1sXFxcIikgaWYge1xcblxcdHNvbWUgbmFtZSBpbiByZXNvdXJjZXNfb2ZfdHlwZShcXFwiQVdTOjpJQU06Ok1hbmFnZWRQb2xpY3lcXFwiKVxcblxcdGRvYyA6PSByZXNvbHZlKG5hbWUsIFxcXCJQcm9wZXJ0aWVzLlBvbGljeURvY3VtZW50XFxcIilcXG5cXHRpc19vYmplY3QoZG9jKVxcblxcdHNpemUgOj0gY291bnQoanNvbi5tYXJzaGFsKGRvYykpXFxuXFx0c2l6ZSA+IDYxNDRcXG59XFxuXCJcbiAgfSxcbiAge1xuICAgIFwiaWRcIjogXCJwZi1sYW1iZGEtZW52LXNpemVcIixcbiAgICBcInNlcnZpY2VcIjogXCJsYW1iZGFcIixcbiAgICBcInNldmVyaXR5XCI6IFwiRVJST1JcIixcbiAgICBcInRpdGxlXCI6IFwiTGFtYmRhIGVudmlyb25tZW50IHZhcmlhYmxlcyBhcmUgbGltaXRlZCB0byA0MDk2IGJ5dGVzIGluIHRvdGFsXCIsXG4gICAgXCJ1cHN0cmVhbVwiOiBcIm5vbmVcIixcbiAgICBcInJlc291cmNlVHlwZXNcIjogW1xuICAgICAgXCJBV1M6OkxhbWJkYTo6RnVuY3Rpb25cIlxuICAgIF0sXG4gICAgXCJyZWdvXCI6IFwicGFja2FnZSBjZGtfcHJlZmxpZ2h0XFxuXFxuaW1wb3J0IHJlZ28udjFcXG5cXG4jIOODquODhuODqeODq+aWh+Wtl+WIl+OBruOCreODvC/lgKTjgaDjgZHjgpLmlbDjgYjjgovvvIjjg4jjg7zjgq/jg7Pjga/jgrnjgq3jg4Pjg5fvvInjgILlkIjoqIjjgYzml6LjgasgNDA5NiDjgpLotoXjgYjjgaZcXG4jIOOBhOOCjOOBsOOAgeWun+mam+OBruODh+ODl+ODreOCpOOBp+OCguW/heOBmuWkseaVl+OBmeOCi++8iOWun+OCteOCpOOCuuOBr+aOqOWumuS7peS4iuOBq+OBl+OBi+OBquOCieOBquOBhO+8ieOAglxcbiMgTk9URTog44GT44Gu44Ko44Oz44K444Oz44GuIFJlZ28g44OR44O844K144Gv5YaF5YyF6KGo6KiY5YaF44GuIDIg5aSJ5pWwIHNvbWXvvIhzb21lIGssIHYgaW4gdmFyc++8ieOCklxcbiMg5Y+X44GR5LuY44GR44Gq44GE44Gf44KB44CBb2JqZWN0LmtleXMg57WM55Sx44Gn5pu444GP44CCXFxuX3BmX2xlbnZfc2l6ZSh2YXJzKSA6PSBzdW0oW3MgfFxcblxcdHNvbWUgayBpbiBvYmplY3Qua2V5cyh2YXJzKVxcblxcdGlzX3N0cmluZyh2YXJzW2tdKVxcblxcdHMgOj0gY291bnQoaykgKyBjb3VudCh2YXJzW2tdKVxcbl0pXFxuXFxudmlvbGF0aW9uIGNvbnRhaW5zIG1ha2VfZGlhZ19mdWxsKFxcXCJwZi1sYW1iZGEtZW52LXNpemVcXFwiLCBcXFwiRVJST1JcXFwiLCBuYW1lLFxcblxcdFxcXCJQcm9wZXJ0aWVzLkVudmlyb25tZW50LlZhcmlhYmxlc1xcXCIsXFxuXFx0c3ByaW50ZihcXFwiRW52aXJvbm1lbnQgdmFyaWFibGVzIHRvdGFsIGF0IGxlYXN0ICVkIGJ5dGVzIChsaXRlcmFsIGtleXMgYW5kIHZhbHVlcyksIGJ1dCBMYW1iZGEgbGltaXRzIHRoZSBlbnZpcm9ubWVudCB0byA0MDk2IGJ5dGVzOyBDcmVhdGVGdW5jdGlvbiBmYWlscyBhdCBkZXBsb3kgdGltZVxcXCIsIFt0b3RhbF0pLFxcblxcdFxcXCJNb3ZlIGxhcmdlIHZhbHVlcyB0byBTU00gUGFyYW1ldGVyIFN0b3JlLCBTZWNyZXRzIE1hbmFnZXIsIG9yIGEgYnVuZGxlZCBjb25maWcgZmlsZVxcXCIsXFxuXFx0XFxcImh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9sYW1iZGEvbGF0ZXN0L2RnL2dldHRpbmdzdGFydGVkLWxpbWl0cy5odG1sXFxcIikgaWYge1xcblxcdHNvbWUgbmFtZSBpbiByZXNvdXJjZXNfb2ZfdHlwZShcXFwiQVdTOjpMYW1iZGE6OkZ1bmN0aW9uXFxcIilcXG5cXHR2YXJzIDo9IHJlc29sdmUobmFtZSwgXFxcIlByb3BlcnRpZXMuRW52aXJvbm1lbnQuVmFyaWFibGVzXFxcIilcXG5cXHRpc19vYmplY3QodmFycylcXG5cXHR0b3RhbCA6PSBfcGZfbGVudl9zaXplKHZhcnMpXFxuXFx0dG90YWwgPiA0MDk2XFxufVxcblwiXG4gIH0sXG4gIHtcbiAgICBcImlkXCI6IFwicGYtczMtbGlmZWN5Y2xlLWRheXMtb3JkZXJcIixcbiAgICBcInNlcnZpY2VcIjogXCJzM1wiLFxuICAgIFwic2V2ZXJpdHlcIjogXCJFUlJPUlwiLFxuICAgIFwidGl0bGVcIjogXCJMaWZlY3ljbGUgYXJjaGl2ZSB0cmFuc2l0aW9ucyBtdXN0IGNvbWUgMzArIGRheXMgYWZ0ZXIgSUEsIGFuZCBleHBpcmF0aW9uIGFmdGVyIGV2ZXJ5IHRyYW5zaXRpb25cIixcbiAgICBcInVwc3RyZWFtXCI6IFwibm9uZVwiLFxuICAgIFwicmVzb3VyY2VUeXBlc1wiOiBbXG4gICAgICBcIkFXUzo6UzM6OkJ1Y2tldFwiXG4gICAgXSxcbiAgICBcInJlZ29cIjogXCJwYWNrYWdlIGNka19wcmVmbGlnaHRcXG5cXG5pbXBvcnQgcmVnby52MVxcblxcbl9wZl9zM29yZF9maXggOj0gXFxcIk9yZGVyIHRoZSBsaWZlY3ljbGUgZGF5cyBzbyBhcmNoaXZlIHRyYW5zaXRpb25zIGNvbWUgYXQgbGVhc3QgMzAgZGF5cyBhZnRlciBJQSB0cmFuc2l0aW9ucyBhbmQgZXhwaXJhdGlvbiBjb21lcyBhZnRlciBldmVyeSB0cmFuc2l0aW9uXFxcIlxcblxcbl9wZl9zM29yZF91cmwgOj0gXFxcImh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9BbWF6b25TMy9sYXRlc3QvdXNlcmd1aWRlL2xpZmVjeWNsZS10cmFuc2l0aW9uLWdlbmVyYWwtY29uc2lkZXJhdGlvbnMuaHRtbFxcXCJcXG5cXG52aW9sYXRpb24gY29udGFpbnMgbWFrZV9kaWFnX2Z1bGwoXFxcInBmLXMzLWxpZmVjeWNsZS1kYXlzLW9yZGVyXFxcIiwgXFxcIkVSUk9SXFxcIiwgbmFtZSxcXG5cXHRzcHJpbnRmKFxcXCJQcm9wZXJ0aWVzLkxpZmVjeWNsZUNvbmZpZ3VyYXRpb24uUnVsZXMuJWQuVHJhbnNpdGlvbnNcXFwiLCBbci5pbmRleF0pLFxcblxcdHNwcmludGYoXFxcIlRyYW5zaXRpb24gdG8gJXMgYXQgJXYgZGF5cyBpcyBsZXNzIHRoYW4gMzAgZGF5cyBhZnRlciB0aGUgJXMgdHJhbnNpdGlvbiBhdCAldiBkYXlzOyBTMyByZXF1aXJlcyBvYmplY3RzIHRvIHN0YXkgYXQgbGVhc3QgMzAgZGF5cyBpbiBJQSBzdG9yYWdlXFxcIiwgW3NjMiwgZDIsIHNjMSwgZDFdKSxcXG5cXHRfcGZfczNvcmRfZml4LCBfcGZfczNvcmRfdXJsKSBpZiB7XFxuXFx0c29tZSBuYW1lIGluIHJlc291cmNlc19vZl90eXBlKFxcXCJBV1M6OlMzOjpCdWNrZXRcXFwiKVxcblxcdHNvbWUgciBpbiBmbGF0dGVuX2xpc3QobmFtZSwgXFxcIlByb3BlcnRpZXMuTGlmZWN5Y2xlQ29uZmlndXJhdGlvbi5SdWxlc1xcXCIpXFxuXFx0aXNfb2JqZWN0KHIudmFsdWUpXFxuXFx0dHJhbnMgOj0gb2JqZWN0LmdldChyLnZhbHVlLCBcXFwiVHJhbnNpdGlvbnNcXFwiLCBbXSlcXG5cXHRpc19hcnJheSh0cmFucylcXG5cXHRzb21lIHQxIGluIHRyYW5zXFxuXFx0aXNfb2JqZWN0KHQxKVxcblxcdHNjMSA6PSBvYmplY3QuZ2V0KHQxLCBcXFwiU3RvcmFnZUNsYXNzXFxcIiwgXFxcIlxcXCIpXFxuXFx0c2MxIGluIHtcXFwiU1RBTkRBUkRfSUFcXFwiLCBcXFwiT05FWk9ORV9JQVxcXCJ9XFxuXFx0cmF3MSA6PSBvYmplY3QuZ2V0KHQxLCBcXFwiVHJhbnNpdGlvbkluRGF5c1xcXCIsIG51bGwpXFxuXFx0cmF3MSAhPSBudWxsICMgdG9fbnVtYmVyKG51bGwpIOOBryAwIOOBq+OBquOCi1xcblxcdGQxIDo9IHRvX251bWJlcihyYXcxKVxcblxcdHNvbWUgdDIgaW4gdHJhbnNcXG5cXHRpc19vYmplY3QodDIpXFxuXFx0c2MyIDo9IG9iamVjdC5nZXQodDIsIFxcXCJTdG9yYWdlQ2xhc3NcXFwiLCBcXFwiXFxcIilcXG5cXHRzYzIgaW4ge1xcXCJHTEFDSUVSXFxcIiwgXFxcIkRFRVBfQVJDSElWRVxcXCJ9XFxuXFx0cmF3MiA6PSBvYmplY3QuZ2V0KHQyLCBcXFwiVHJhbnNpdGlvbkluRGF5c1xcXCIsIG51bGwpXFxuXFx0cmF3MiAhPSBudWxsXFxuXFx0ZDIgOj0gdG9fbnVtYmVyKHJhdzIpXFxuXFx0ZDIgPCBkMSArIDMwXFxufVxcblxcbnZpb2xhdGlvbiBjb250YWlucyBtYWtlX2RpYWdfZnVsbChcXFwicGYtczMtbGlmZWN5Y2xlLWRheXMtb3JkZXJcXFwiLCBcXFwiRVJST1JcXFwiLCBuYW1lLFxcblxcdHNwcmludGYoXFxcIlByb3BlcnRpZXMuTGlmZWN5Y2xlQ29uZmlndXJhdGlvbi5SdWxlcy4lZC5FeHBpcmF0aW9uSW5EYXlzXFxcIiwgW3IuaW5kZXhdKSxcXG5cXHRzcHJpbnRmKFxcXCJFeHBpcmF0aW9uSW5EYXlzICgldikgbXVzdCBiZSBncmVhdGVyIHRoYW4gVHJhbnNpdGlvbkluRGF5cyAoJXYpOyBTMyByZWplY3RzIGxpZmVjeWNsZSBydWxlcyB0aGF0IGV4cGlyZSBvYmplY3RzIGJlZm9yZSBvciB3aGVuIHRoZXkgdHJhbnNpdGlvblxcXCIsIFtlLCBkXSksXFxuXFx0X3BmX3Mzb3JkX2ZpeCwgX3BmX3Mzb3JkX3VybCkgaWYge1xcblxcdHNvbWUgbmFtZSBpbiByZXNvdXJjZXNfb2ZfdHlwZShcXFwiQVdTOjpTMzo6QnVja2V0XFxcIilcXG5cXHRzb21lIHIgaW4gZmxhdHRlbl9saXN0KG5hbWUsIFxcXCJQcm9wZXJ0aWVzLkxpZmVjeWNsZUNvbmZpZ3VyYXRpb24uUnVsZXNcXFwiKVxcblxcdGlzX29iamVjdChyLnZhbHVlKVxcblxcdHJhd2UgOj0gb2JqZWN0LmdldChyLnZhbHVlLCBcXFwiRXhwaXJhdGlvbkluRGF5c1xcXCIsIG51bGwpXFxuXFx0cmF3ZSAhPSBudWxsICMgdG9fbnVtYmVyKG51bGwpIOOBryAwIOOBq+OBquOCi1xcblxcdGUgOj0gdG9fbnVtYmVyKHJhd2UpXFxuXFx0dHJhbnMgOj0gb2JqZWN0LmdldChyLnZhbHVlLCBcXFwiVHJhbnNpdGlvbnNcXFwiLCBbXSlcXG5cXHRpc19hcnJheSh0cmFucylcXG5cXHRzb21lIHQgaW4gdHJhbnNcXG5cXHRpc19vYmplY3QodClcXG5cXHRyYXdkIDo9IG9iamVjdC5nZXQodCwgXFxcIlRyYW5zaXRpb25JbkRheXNcXFwiLCBudWxsKVxcblxcdHJhd2QgIT0gbnVsbFxcblxcdGQgOj0gdG9fbnVtYmVyKHJhd2QpXFxuXFx0ZSA8PSBkXFxufVxcblwiXG4gIH0sXG4gIHtcbiAgICBcImlkXCI6IFwicGYtczMtcmVwbGljYXRpb24tcmVxdWlyZXMtdmVyc2lvbmluZ1wiLFxuICAgIFwic2VydmljZVwiOiBcInMzXCIsXG4gICAgXCJzZXZlcml0eVwiOiBcIkVSUk9SXCIsXG4gICAgXCJ0aXRsZVwiOiBcIlJlcGxpY2F0aW9uQ29uZmlndXJhdGlvbiByZXF1aXJlcyB2ZXJzaW9uaW5nIHRvIGJlIGVuYWJsZWQgb24gdGhlIHNvdXJjZSBidWNrZXRcIixcbiAgICBcInVwc3RyZWFtXCI6IFwibm9uZVwiLFxuICAgIFwicmVzb3VyY2VUeXBlc1wiOiBbXG4gICAgICBcIkFXUzo6UzM6OkJ1Y2tldFwiXG4gICAgXSxcbiAgICBcInJlZ29cIjogXCJwYWNrYWdlIGNka19wcmVmbGlnaHRcXG5cXG5pbXBvcnQgcmVnby52MVxcblxcbiMgU3RhdHVzIOOBjOODquODhuODqeODq+OBpyBcXFwiU3VzcGVuZGVkXFxcIiDku6XlpJbvvIg9IFxcXCJFbmFibGVkXFxcIu+8ieOAgeOBvuOBn+OBr+acquino+axuuODiOODvOOCr+ODs+OBquOCiSBPSyDmibHjgYTjgIJcXG4jIFZlcnNpb25pbmdDb25maWd1cmF0aW9uIOiHquS9k+OBjOeEoeOBhCAvIFN1c3BlbmRlZCDjga7jgajjgY3jgaDjgZHpgZXlj43jgavjgZnjgovjgIJcXG5fcGZfczNyZXBsX3ZlcnNpb25pbmdfb2sobmFtZSkgaWYge1xcblxcdHMgOj0gcmVzb2x2ZShuYW1lLCBcXFwiUHJvcGVydGllcy5WZXJzaW9uaW5nQ29uZmlndXJhdGlvbi5TdGF0dXNcXFwiKVxcblxcdG5vdCBzID09IFxcXCJTdXNwZW5kZWRcXFwiXFxufVxcblxcbnZpb2xhdGlvbiBjb250YWlucyBtYWtlX2RpYWdfZnVsbChcXFwicGYtczMtcmVwbGljYXRpb24tcmVxdWlyZXMtdmVyc2lvbmluZ1xcXCIsIFxcXCJFUlJPUlxcXCIsIG5hbWUsXFxuXFx0XFxcIlByb3BlcnRpZXMuUmVwbGljYXRpb25Db25maWd1cmF0aW9uXFxcIixcXG5cXHRcXFwiUmVwbGljYXRpb25Db25maWd1cmF0aW9uIGlzIHNldCBidXQgYnVja2V0IHZlcnNpb25pbmcgaXMgbm90IGVuYWJsZWQ7IFMzIHJlamVjdHMgdGhlIHJlcGxpY2F0aW9uIGNvbmZpZ3VyYXRpb24gYXQgZGVwbG95IHRpbWUgKEludmFsaWRSZXF1ZXN0OiBWZXJzaW9uaW5nIG11c3QgYmUgJ0VuYWJsZWQnIG9uIHRoZSBidWNrZXQpXFxcIixcXG5cXHRcXFwiU2V0IFZlcnNpb25pbmdDb25maWd1cmF0aW9uLlN0YXR1cyB0byAnRW5hYmxlZCcgb24gdGhlIHNvdXJjZSBidWNrZXRcXFwiLFxcblxcdFxcXCJodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vQW1hem9uUzMvbGF0ZXN0L3VzZXJndWlkZS9yZXBsaWNhdGlvbi1yZXF1aXJlbWVudHMuaHRtbFxcXCIpIGlmIHtcXG5cXHRzb21lIG5hbWUgaW4gcmVzb3VyY2VzX29mX3R5cGUoXFxcIkFXUzo6UzM6OkJ1Y2tldFxcXCIpXFxuXFx0aXNfb2JqZWN0KHJlc29sdmUobmFtZSwgXFxcIlByb3BlcnRpZXMuUmVwbGljYXRpb25Db25maWd1cmF0aW9uXFxcIikpXFxuXFx0bm90IF9wZl9zM3JlcGxfdmVyc2lvbmluZ19vayhuYW1lKVxcbn1cXG5cIlxuICB9LFxuICB7XG4gICAgXCJpZFwiOiBcInBmLXNucy1maWZvLXRvcGljLW5hbWVcIixcbiAgICBcInNlcnZpY2VcIjogXCJzbnNcIixcbiAgICBcInNldmVyaXR5XCI6IFwiRVJST1JcIixcbiAgICBcInRpdGxlXCI6IFwiRklGTyB0b3BpYyBuYW1lcyBtdXN0IGVuZCB3aXRoICcuZmlmbycgKGFuZCAnLmZpZm8nIG5hbWVzIHJlcXVpcmUgRmlmb1RvcGljKVwiLFxuICAgIFwidXBzdHJlYW1cIjogXCJub25lXCIsXG4gICAgXCJyZXNvdXJjZVR5cGVzXCI6IFtcbiAgICAgIFwiQVdTOjpTTlM6OlRvcGljXCJcbiAgICBdLFxuICAgIFwicmVnb1wiOiBcInBhY2thZ2UgY2RrX3ByZWZsaWdodFxcblxcbmltcG9ydCByZWdvLnYxXFxuXFxuX3BmX3Nuc2ZpZm9fZml4IDo9IFxcXCJHaXZlIEZJRk8gdG9waWNzIGEgVG9waWNOYW1lIGVuZGluZyBpbiAnLmZpZm8nIChvciBkcm9wIFRvcGljTmFtZSB0byBsZXQgQ2xvdWRGb3JtYXRpb24gZ2VuZXJhdGUgb25lKSwgYW5kIHNldCBGaWZvVG9waWM6IHRydWUgd2hlbmV2ZXIgdGhlIG5hbWUgZW5kcyBpbiAnLmZpZm8nXFxcIlxcblxcbl9wZl9zbnNmaWZvX3VybCA6PSBcXFwiaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL3Nucy9sYXRlc3QvZGcvc25zLWNyZWF0ZS1maWZvLXRvcGljLmh0bWxcXFwiXFxuXFxuX3BmX3Nuc2ZpZm9fdHJ1ZShuYW1lKSBpZiByZXNvbHZlKG5hbWUsIFxcXCJQcm9wZXJ0aWVzLkZpZm9Ub3BpY1xcXCIpIGluIHt0cnVlLCBcXFwidHJ1ZVxcXCJ9XFxuXFxuIyBGaWZvVG9waWMg44GM5a2Y5Zyo44GX44CB44Oq44OG44Op44OrIGZhbHNlIOS7peWklu+8iHRydWUg44KE44OI44O844Kv44Oz77yJ44Gq44KJ44CMRklGTyDjgYvjgoLjgZfjgozjgarjgYTjgI3mibHjgYRcXG5fcGZfc25zZmlmb19tYXliZV9maWZvKG5hbWUpIGlmIHtcXG5cXHR2IDo9IHJlc29sdmUobmFtZSwgXFxcIlByb3BlcnRpZXMuRmlmb1RvcGljXFxcIilcXG5cXHRub3QgdiBpbiB7ZmFsc2UsIFxcXCJmYWxzZVxcXCJ9XFxufVxcblxcbnZpb2xhdGlvbiBjb250YWlucyBtYWtlX2RpYWdfZnVsbChcXFwicGYtc25zLWZpZm8tdG9waWMtbmFtZVxcXCIsIFxcXCJFUlJPUlxcXCIsIG5hbWUsXFxuXFx0XFxcIlByb3BlcnRpZXMuVG9waWNOYW1lXFxcIixcXG5cXHRzcHJpbnRmKFxcXCJGaWZvVG9waWMgaXMgdHJ1ZSBidXQgVG9waWNOYW1lICclcycgZG9lcyBub3QgZW5kIHdpdGggJy5maWZvJzsgU05TIHJlamVjdHMgdGhlIHRvcGljIGF0IGRlcGxveSB0aW1lXFxcIiwgW3RuXSksXFxuXFx0X3BmX3Nuc2ZpZm9fZml4LCBfcGZfc25zZmlmb191cmwpIGlmIHtcXG5cXHRzb21lIG5hbWUgaW4gcmVzb3VyY2VzX29mX3R5cGUoXFxcIkFXUzo6U05TOjpUb3BpY1xcXCIpXFxuXFx0X3BmX3Nuc2ZpZm9fdHJ1ZShuYW1lKVxcblxcdHRuIDo9IHJlc29sdmUobmFtZSwgXFxcIlByb3BlcnRpZXMuVG9waWNOYW1lXFxcIilcXG5cXHRpc19zdHJpbmcodG4pXFxuXFx0bm90IGVuZHN3aXRoKHRuLCBcXFwiLmZpZm9cXFwiKVxcbn1cXG5cXG52aW9sYXRpb24gY29udGFpbnMgbWFrZV9kaWFnX2Z1bGwoXFxcInBmLXNucy1maWZvLXRvcGljLW5hbWVcXFwiLCBcXFwiRVJST1JcXFwiLCBuYW1lLFxcblxcdFxcXCJQcm9wZXJ0aWVzLlRvcGljTmFtZVxcXCIsXFxuXFx0c3ByaW50ZihcXFwiVG9waWNOYW1lICclcycgZW5kcyB3aXRoICcuZmlmbycgYnV0IEZpZm9Ub3BpYyBpcyBub3QgdHJ1ZTsgU05TIHJlamVjdHMgdGhlIHRvcGljIG5hbWUgYXQgZGVwbG95IHRpbWVcXFwiLCBbdG5dKSxcXG5cXHRfcGZfc25zZmlmb19maXgsIF9wZl9zbnNmaWZvX3VybCkgaWYge1xcblxcdHNvbWUgbmFtZSBpbiByZXNvdXJjZXNfb2ZfdHlwZShcXFwiQVdTOjpTTlM6OlRvcGljXFxcIilcXG5cXHR0biA6PSByZXNvbHZlKG5hbWUsIFxcXCJQcm9wZXJ0aWVzLlRvcGljTmFtZVxcXCIpXFxuXFx0aXNfc3RyaW5nKHRuKVxcblxcdGVuZHN3aXRoKHRuLCBcXFwiLmZpZm9cXFwiKVxcblxcdG5vdCBfcGZfc25zZmlmb19tYXliZV9maWZvKG5hbWUpXFxufVxcblwiXG4gIH0sXG4gIHtcbiAgICBcImlkXCI6IFwicGYtc2ZuLWFzbC1taXNzaW5nLXN0YXRlXCIsXG4gICAgXCJzZXJ2aWNlXCI6IFwic3RlcGZ1bmN0aW9uc1wiLFxuICAgIFwic2V2ZXJpdHlcIjogXCJFUlJPUlwiLFxuICAgIFwidGl0bGVcIjogXCJBU0wgTmV4dC9EZWZhdWx0L0Nob2ljZXMgbXVzdCByZWZlcmVuY2UgYSBkZWZpbmVkIHN0YXRlICh0b3AtbGV2ZWwgc3RhdGVzOyBhIGRhbmdsaW5nIFN0YXJ0QXQgaXMgY292ZXJlZCBieSBlbmdpbmUgcnVsZSBFMzYwMSlcIixcbiAgICBcInVwc3RyZWFtXCI6IFwibm9uZVwiLFxuICAgIFwicmVzb3VyY2VUeXBlc1wiOiBbXG4gICAgICBcIkFXUzo6U3RlcEZ1bmN0aW9uczo6U3RhdGVNYWNoaW5lXCJcbiAgICBdLFxuICAgIFwicmVnb1wiOiBcInBhY2thZ2UgY2RrX3ByZWZsaWdodFxcblxcbmltcG9ydCByZWdvLnYxXFxuXFxuX3BmX3Nmbl9maXggOj0gXFxcIlBvaW50IE5leHQvRGVmYXVsdC9DaG9pY2VzIGF0IGFuIGV4aXN0aW5nIHN0YXRlIG5hbWVcXFwiXFxuXFxuX3BmX3Nmbl91cmwgOj0gXFxcImh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9zdGVwLWZ1bmN0aW9ucy9sYXRlc3QvZGcvYW1hem9uLXN0YXRlcy1sYW5ndWFnZS1zdGF0ZXMuaHRtbFxcXCJcXG5cXG5fcGZfc2ZuX2FzbChuYW1lKSA6PSBhc2wgaWYge1xcblxcdGRlZiA6PSByZXNvbHZlKG5hbWUsIFxcXCJQcm9wZXJ0aWVzLkRlZmluaXRpb25TdHJpbmdcXFwiKVxcblxcdGlzX3N0cmluZyhkZWYpXFxuXFx0YXNsIDo9IGpzb24udW5tYXJzaGFsKGRlZilcXG5cXHRpc19vYmplY3QoYXNsKVxcbn1cXG5cXG5fcGZfc2ZuX2RlZmluZWQoYXNsKSA6PSB7c24gfCBzb21lIHNuLCBfIGluIG9iamVjdC5nZXQoYXNsLCBcXFwiU3RhdGVzXFxcIiwge30pfVxcblxcbiMgTk9URTogYSBkYW5nbGluZyBTdGFydEF0IGlzIGRlbGliZXJhdGVseSBOT1QgY2hlY2tlZCBoZXJlIOKAlCB0aGUgZW5naW5lJ3NcXG4jIGJ1aWx0LWluIHJ1bGUgRTM2MDEgKEVSUk9SL0NGTl9MSU5UKSBhbHJlYWR5IGNvdmVycyBpdC4gVmVyaWZpZWQgYWdhaW5zdFxcbiMgQGF3cy9jbG91ZGZvcm1hdGlvbi12YWxpZGF0ZSAxLjcuMC1iZXRhIG9uIDIwMjYtMDktMDE6IEUzNjAxIGZpcmVzIGZvclxcbiMgU3RhcnRBdCBvbmx5IGFuZCBkb2VzIG5vdCBjaGVjayBOZXh0L0RlZmF1bHQvQ2hvaWNlcywgd2hpY2ggaXMgd2hhdCB0aGlzXFxuIyBydWxlIGFkZHMuXFxuXFxudmlvbGF0aW9uIGNvbnRhaW5zIG1ha2VfZGlhZ19mdWxsKFxcXCJwZi1zZm4tYXNsLW1pc3Npbmctc3RhdGVcXFwiLCBcXFwiRVJST1JcXFwiLCBuYW1lLFxcblxcdFxcXCJQcm9wZXJ0aWVzLkRlZmluaXRpb25TdHJpbmdcXFwiLFxcblxcdHNwcmludGYoXFxcInN0YXRlICclcycgcmVmZXJlbmNlcyBzdGF0ZSAnJXMnIHZpYSAlcywgYnV0IG5vIHN0YXRlIHdpdGggdGhhdCBuYW1lIGlzIGRlZmluZWRcXFwiLCBbc25hbWUsIHRhcmdldCwga2V5XSksXFxuXFx0X3BmX3Nmbl9maXgsIF9wZl9zZm5fdXJsKSBpZiB7XFxuXFx0c29tZSBuYW1lIGluIHJlc291cmNlc19vZl90eXBlKFxcXCJBV1M6OlN0ZXBGdW5jdGlvbnM6OlN0YXRlTWFjaGluZVxcXCIpXFxuXFx0YXNsIDo9IF9wZl9zZm5fYXNsKG5hbWUpXFxuXFx0c29tZSBzbmFtZSwgc3QgaW4gb2JqZWN0LmdldChhc2wsIFxcXCJTdGF0ZXNcXFwiLCB7fSlcXG5cXHRpc19vYmplY3Qoc3QpXFxuXFx0c29tZSBrZXkgaW4ge1xcXCJOZXh0XFxcIiwgXFxcIkRlZmF1bHRcXFwifVxcblxcdHRhcmdldCA6PSBvYmplY3QuZ2V0KHN0LCBrZXksIG51bGwpXFxuXFx0aXNfc3RyaW5nKHRhcmdldClcXG5cXHRub3QgdGFyZ2V0IGluIF9wZl9zZm5fZGVmaW5lZChhc2wpXFxufVxcblxcbnZpb2xhdGlvbiBjb250YWlucyBtYWtlX2RpYWdfZnVsbChcXFwicGYtc2ZuLWFzbC1taXNzaW5nLXN0YXRlXFxcIiwgXFxcIkVSUk9SXFxcIiwgbmFtZSxcXG5cXHRcXFwiUHJvcGVydGllcy5EZWZpbml0aW9uU3RyaW5nXFxcIixcXG5cXHRzcHJpbnRmKFxcXCJzdGF0ZSAnJXMnIGhhcyBhIENob2ljZSBydWxlIHJlZmVyZW5jaW5nIHN0YXRlICclcycsIGJ1dCBubyBzdGF0ZSB3aXRoIHRoYXQgbmFtZSBpcyBkZWZpbmVkXFxcIiwgW3NuYW1lLCB0YXJnZXRdKSxcXG5cXHRfcGZfc2ZuX2ZpeCwgX3BmX3Nmbl91cmwpIGlmIHtcXG5cXHRzb21lIG5hbWUgaW4gcmVzb3VyY2VzX29mX3R5cGUoXFxcIkFXUzo6U3RlcEZ1bmN0aW9uczo6U3RhdGVNYWNoaW5lXFxcIilcXG5cXHRhc2wgOj0gX3BmX3Nmbl9hc2wobmFtZSlcXG5cXHRzb21lIHNuYW1lLCBzdCBpbiBvYmplY3QuZ2V0KGFzbCwgXFxcIlN0YXRlc1xcXCIsIHt9KVxcblxcdGlzX29iamVjdChzdClcXG5cXHRjaG9pY2VzIDo9IG9iamVjdC5nZXQoc3QsIFxcXCJDaG9pY2VzXFxcIiwgW10pXFxuXFx0aXNfYXJyYXkoY2hvaWNlcylcXG5cXHRzb21lIGMgaW4gY2hvaWNlc1xcblxcdGlzX29iamVjdChjKVxcblxcdHRhcmdldCA6PSBvYmplY3QuZ2V0KGMsIFxcXCJOZXh0XFxcIiwgbnVsbClcXG5cXHRpc19zdHJpbmcodGFyZ2V0KVxcblxcdG5vdCB0YXJnZXQgaW4gX3BmX3Nmbl9kZWZpbmVkKGFzbClcXG59XFxuXCJcbiAgfVxuXTtcbiJdfQ==
package/llms.txt CHANGED
@@ -6,8 +6,8 @@
6
6
 
7
7
  1. `npm i -D cdk-preflight`
8
8
  2. `npx cdk-preflight init` — locates the app entry via cdk.json and inserts `Preflight.apply(app)`. `--dry-run` previews, `--dir <path>` targets another directory. Idempotent.
9
- 3. `cdk synth` — violations appear as warnings with rule id, actual value, suggested fix, and construct trace.
10
- 4. To fail the build on violations: `Preflight.apply(app, { enforce: true })`. Add `strict: true` to also fail on the engine's own error-class findings (F-/E-prefixed) that CDK otherwise downgrades to warnings.
9
+ 3. `cdk synth` — violations FAIL the synth by default, reported with rule id, actual value, and suggested fix.
10
+ 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.
11
11
  5. Machine-readable findings: synth with `-c @aws-cdk/core:validationReportJson=true`, then read `cdk.out/validation-report.json`.
12
12
 
13
13
  ## Key files
package/package.json CHANGED
@@ -87,7 +87,7 @@
87
87
  "publishConfig": {
88
88
  "access": "public"
89
89
  },
90
- "version": "0.0.0",
90
+ "version": "0.0.2",
91
91
  "jest": {
92
92
  "coverageProvider": "v8",
93
93
  "testMatch": [