@xpertss/projen-types 0.0.2 → 0.0.4

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.
Files changed (37) hide show
  1. package/.jsii +118 -103
  2. package/API.md +101 -61
  3. package/README.md +35 -13
  4. package/lib/actions/action-build-workflow.js +1 -1
  5. package/lib/actions/action-dogfood-workflow.d.ts +5 -1
  6. package/lib/actions/action-dogfood-workflow.js +49 -19
  7. package/lib/actions/action-sonar-workflow.js +1 -1
  8. package/lib/actions/github-action-project.d.ts +15 -6
  9. package/lib/actions/github-action-project.js +16 -24
  10. package/lib/cdk/app-runtime-scaffold.js +1 -1
  11. package/lib/cdk/cdk-app-project.js +1 -1
  12. package/lib/cdk/cdk-infra-project.js +1 -1
  13. package/lib/cdk/cdk-typescript-base.js +38 -2
  14. package/lib/cdk/components/ecr-ecs-constructs.js +1 -1
  15. package/lib/cdk/components/edge-networking-constructs.js +1 -1
  16. package/lib/cdk/database-component.js +1 -1
  17. package/lib/cdk/options.d.ts +14 -2
  18. package/lib/cdk/options.js +1 -1
  19. package/lib/common/actions-allowlist-guard.js +1 -1
  20. package/lib/common/projen-drift-check-workflow.js +7 -3
  21. package/lib/common/projenrc-ts.d.ts +22 -0
  22. package/lib/common/projenrc-ts.js +43 -0
  23. package/lib/common/workflow-change-notice-workflow.js +1 -1
  24. package/lib/java/components/cdk-deploy-hook.d.ts +7 -0
  25. package/lib/java/components/cdk-deploy-hook.js +26 -5
  26. package/lib/java/components/code-index-workflow.js +1 -1
  27. package/lib/java/components/docker-publish.js +1 -1
  28. package/lib/java/components/flyway-migration.js +1 -1
  29. package/lib/java/components/github-packages-publish.js +1 -1
  30. package/lib/java/components/maven-central-publish.js +1 -1
  31. package/lib/java/java-app-project.js +1 -1
  32. package/lib/java/java-library-project.js +1 -1
  33. package/lib/java/java-maven-base.js +21 -2
  34. package/lib/java/java-service-project.js +6 -5
  35. package/lib/java/options.d.ts +27 -5
  36. package/lib/java/options.js +1 -1
  37. package/package.json +2 -2
package/API.md CHANGED
@@ -258,12 +258,16 @@ public readonly workflow: TaskWorkflow;
258
258
 
259
259
  Per AD-001's dogfood test: the composite action is run **against this repo**, end-to-end, via a local `uses: .` reference - no external harness. Builds `test-dogfood.yml` from an ordered `scenario` of invocation steps (see `ActionDogfoodStep`) followed by a shared cleanup step.
260
260
 
261
+ Omitting `options` generates the workflow with a single failing step (see
262
+ `UNCONFIGURED_STEPS`). A *partially* declared dogfood is still a synth
263
+ error: if you wrote a scenario by hand, you can write its cleanup too.
264
+
261
265
  #### Initializers <a name="Initializers" id="@xpertss/projen-types.ActionDogfoodWorkflow.Initializer"></a>
262
266
 
263
267
  ```typescript
264
268
  import { ActionDogfoodWorkflow } from '@xpertss/projen-types'
265
269
 
266
- new ActionDogfoodWorkflow(scope: GitHubProject, options: ActionDogfoodOptions)
270
+ new ActionDogfoodWorkflow(scope: GitHubProject, options?: ActionDogfoodOptions)
267
271
  ```
268
272
 
269
273
  | **Name** | **Type** | **Description** |
@@ -279,7 +283,7 @@ new ActionDogfoodWorkflow(scope: GitHubProject, options: ActionDogfoodOptions)
279
283
 
280
284
  ---
281
285
 
282
- ##### `options`<sup>Required</sup> <a name="options" id="@xpertss/projen-types.ActionDogfoodWorkflow.Initializer.parameter.options"></a>
286
+ ##### `options`<sup>Optional</sup> <a name="options" id="@xpertss/projen-types.ActionDogfoodWorkflow.Initializer.parameter.options"></a>
283
287
 
284
288
  - *Type:* <a href="#@xpertss/projen-types.ActionDogfoodOptions">ActionDogfoodOptions</a>
285
289
 
@@ -2664,6 +2668,13 @@ public readonly DEFAULT_TS_JEST_TRANFORM_PATTERN: string;
2664
2668
 
2665
2669
  Manual-dispatch workflow that invokes a downstream CDK deploy in a companion `CdkInfraProject`/`CdkAppProject` repo, using the same `ManualDeployWorkflow` contract those project types use for their own deploys - see the CDK spec's open question about sharing this contract.
2666
2670
 
2671
+ With no `targetRepo` the workflow is still generated, but every job's
2672
+ only step fails with instructions. Synthesizing is not the place to
2673
+ enforce this: it would make the project type unscaffoldable by
2674
+ `projen new` (which cannot supply the value), and it is a dispatch-only
2675
+ workflow - nobody hits the failure until they actually try to deploy,
2676
+ which is exactly when "this repo has no deploy target" needs saying.
2677
+
2667
2678
  #### Initializers <a name="Initializers" id="@xpertss/projen-types.CdkDeployHook.Initializer"></a>
2668
2679
 
2669
2680
  ```typescript
@@ -7181,7 +7192,7 @@ public readonly project: Project;
7181
7192
 
7182
7193
  ### GitHubActionProject <a name="GitHubActionProject" id="@xpertss/projen-types.GitHubActionProject"></a>
7183
7194
 
7184
- Scaffolds the repo lifecycle (AD-001) around a hand-committed, composite (shell) GitHub Action: the `build`/`test-dogfood`/`sonar`/`release` workflows, versioning and release discipline, the F003 verify components, the F009 allowlist guard, and repo boilerplate (`tsconfig.json` for `.projenrc.ts`, a private version-source `package.json`, `.yamllint`, `LICENSE`, and a `README.md` template). The action's own content (`action.yml`, its shell scripts, `test/` fixtures) is authored by hand per the action's own F### spec - this type only lints it.
7195
+ Scaffolds the repo lifecycle (AD-001) around a hand-committed, composite (shell) GitHub Action: the `build`/`test-dogfood`/`sonar`/`release` workflows, versioning and release discipline, the F003 verify components, the F009 allowlist guard, and repo boilerplate (a private version-source `package.json`, `.yamllint`, `LICENSE`, and a `README.md` template). The action's own content (`action.yml`, its shell scripts, `test/` fixtures) is authored by hand per the action's own F### spec - this type only lints it.
7185
7196
 
7186
7197
  #### Initializers <a name="Initializers" id="@xpertss/projen-types.GitHubActionProject.Initializer"></a>
7187
7198
 
@@ -13099,9 +13110,9 @@ const cdkAppProjectOptions: CdkAppProjectOptions = { ... }
13099
13110
  | <code><a href="#@xpertss/projen-types.CdkAppProjectOptions.property.name">name</a></code> | <code>string</code> | *No description.* |
13100
13111
  | <code><a href="#@xpertss/projen-types.CdkAppProjectOptions.property.cdkVersion">cdkVersion</a></code> | <code>string</code> | *No description.* |
13101
13112
  | <code><a href="#@xpertss/projen-types.CdkAppProjectOptions.property.gheTokenSecret">gheTokenSecret</a></code> | <code>string</code> | *No description.* |
13102
- | <code><a href="#@xpertss/projen-types.CdkAppProjectOptions.property.environments">environments</a></code> | <code>string \| <a href="#@xpertss/projen-types.EnvironmentOptions">EnvironmentOptions</a>[]</code> | Deploy targets for the manual-dispatch deploy workflow, e.g. ["dev", "stage", "prod"]. |
13103
13113
  | <code><a href="#@xpertss/projen-types.CdkAppProjectOptions.property.ecrEcs">ecrEcs</a></code> | <code><a href="#@xpertss/projen-types.EcrEcsOptions">EcrEcsOptions</a></code> | *No description.* |
13104
13114
  | <code><a href="#@xpertss/projen-types.CdkAppProjectOptions.property.edgeResources">edgeResources</a></code> | <code>string[]</code> | *No description.* |
13115
+ | <code><a href="#@xpertss/projen-types.CdkAppProjectOptions.property.environments">environments</a></code> | <code>string \| <a href="#@xpertss/projen-types.EnvironmentOptions">EnvironmentOptions</a>[]</code> | Deploy targets for the manual-dispatch deploy workflow, e.g. ["dev", "stage", "prod"]. No `deploy` workflow is generated when this is empty or omitted. |
13105
13116
  | <code><a href="#@xpertss/projen-types.CdkAppProjectOptions.property.appEntryPoint">appEntryPoint</a></code> | <code>string</code> | *No description.* |
13106
13117
  | <code><a href="#@xpertss/projen-types.CdkAppProjectOptions.property.database">database</a></code> | <code><a href="#@xpertss/projen-types.DatabaseOptions">DatabaseOptions</a></code> | *No description.* |
13107
13118
 
@@ -13139,35 +13150,42 @@ public readonly gheTokenSecret: string;
13139
13150
 
13140
13151
  ---
13141
13152
 
13142
- ##### `environments`<sup>Required</sup> <a name="environments" id="@xpertss/projen-types.CdkAppProjectOptions.property.environments"></a>
13153
+ ##### `ecrEcs`<sup>Optional</sup> <a name="ecrEcs" id="@xpertss/projen-types.CdkAppProjectOptions.property.ecrEcs"></a>
13143
13154
 
13144
13155
  ```typescript
13145
- public readonly environments: (string | EnvironmentOptions)[];
13156
+ public readonly ecrEcs: EcrEcsOptions;
13146
13157
  ```
13147
13158
 
13148
- - *Type:* string | <a href="#@xpertss/projen-types.EnvironmentOptions">EnvironmentOptions</a>[]
13149
-
13150
- Deploy targets for the manual-dispatch deploy workflow, e.g. ["dev", "stage", "prod"].
13159
+ - *Type:* <a href="#@xpertss/projen-types.EcrEcsOptions">EcrEcsOptions</a>
13151
13160
 
13152
13161
  ---
13153
13162
 
13154
- ##### `ecrEcs`<sup>Optional</sup> <a name="ecrEcs" id="@xpertss/projen-types.CdkAppProjectOptions.property.ecrEcs"></a>
13163
+ ##### `edgeResources`<sup>Optional</sup> <a name="edgeResources" id="@xpertss/projen-types.CdkAppProjectOptions.property.edgeResources"></a>
13155
13164
 
13156
13165
  ```typescript
13157
- public readonly ecrEcs: EcrEcsOptions;
13166
+ public readonly edgeResources: string[];
13158
13167
  ```
13159
13168
 
13160
- - *Type:* <a href="#@xpertss/projen-types.EcrEcsOptions">EcrEcsOptions</a>
13169
+ - *Type:* string[]
13161
13170
 
13162
13171
  ---
13163
13172
 
13164
- ##### `edgeResources`<sup>Optional</sup> <a name="edgeResources" id="@xpertss/projen-types.CdkAppProjectOptions.property.edgeResources"></a>
13173
+ ##### `environments`<sup>Optional</sup> <a name="environments" id="@xpertss/projen-types.CdkAppProjectOptions.property.environments"></a>
13165
13174
 
13166
13175
  ```typescript
13167
- public readonly edgeResources: string[];
13176
+ public readonly environments: (string | EnvironmentOptions)[];
13168
13177
  ```
13169
13178
 
13170
- - *Type:* string[]
13179
+ - *Type:* string | <a href="#@xpertss/projen-types.EnvironmentOptions">EnvironmentOptions</a>[]
13180
+ - *Default:* no deploy workflow
13181
+
13182
+ Deploy targets for the manual-dispatch deploy workflow, e.g. ["dev", "stage", "prod"]. No `deploy` workflow is generated when this is empty or omitted.
13183
+
13184
+ Optional rather than required so that `projen new --from` can scaffold
13185
+ the repo: its union type (`string | EnvironmentOptions`) is not
13186
+ "JSON-like", so projen's CLI cannot render a value for it into the
13187
+ initial `.projenrc.ts` - and a *required* option it cannot render leaves
13188
+ behind a projenrc that does not type-check.
13171
13189
 
13172
13190
  ---
13173
13191
 
@@ -13206,22 +13224,10 @@ const cdkDeployHookOptions: CdkDeployHookOptions = { ... }
13206
13224
 
13207
13225
  | **Name** | **Type** | **Description** |
13208
13226
  | --- | --- | --- |
13209
- | <code><a href="#@xpertss/projen-types.CdkDeployHookOptions.property.enabled">enabled</a></code> | <code>boolean</code> | *No description.* |
13210
13227
  | <code><a href="#@xpertss/projen-types.CdkDeployHookOptions.property.targetRepo">targetRepo</a></code> | <code>string</code> | The companion CDK infra/app repo (owner/repo) that owns the actual infrastructure. |
13211
13228
 
13212
13229
  ---
13213
13230
 
13214
- ##### `enabled`<sup>Optional</sup> <a name="enabled" id="@xpertss/projen-types.CdkDeployHookOptions.property.enabled"></a>
13215
-
13216
- ```typescript
13217
- public readonly enabled: boolean;
13218
- ```
13219
-
13220
- - *Type:* boolean
13221
- - *Default:* true
13222
-
13223
- ---
13224
-
13225
13231
  ##### `targetRepo`<sup>Optional</sup> <a name="targetRepo" id="@xpertss/projen-types.CdkDeployHookOptions.property.targetRepo"></a>
13226
13232
 
13227
13233
  ```typescript
@@ -13229,6 +13235,7 @@ public readonly targetRepo: string;
13229
13235
  ```
13230
13236
 
13231
13237
  - *Type:* string
13238
+ - *Default:* the workflow is still generated, but its only step fails with instructions (see `CdkDeployHook`)
13232
13239
 
13233
13240
  The companion CDK infra/app repo (owner/repo) that owns the actual infrastructure.
13234
13241
 
@@ -13251,9 +13258,9 @@ const cdkInfraProjectOptions: CdkInfraProjectOptions = { ... }
13251
13258
  | <code><a href="#@xpertss/projen-types.CdkInfraProjectOptions.property.name">name</a></code> | <code>string</code> | *No description.* |
13252
13259
  | <code><a href="#@xpertss/projen-types.CdkInfraProjectOptions.property.cdkVersion">cdkVersion</a></code> | <code>string</code> | *No description.* |
13253
13260
  | <code><a href="#@xpertss/projen-types.CdkInfraProjectOptions.property.gheTokenSecret">gheTokenSecret</a></code> | <code>string</code> | *No description.* |
13254
- | <code><a href="#@xpertss/projen-types.CdkInfraProjectOptions.property.environments">environments</a></code> | <code>string \| <a href="#@xpertss/projen-types.EnvironmentOptions">EnvironmentOptions</a>[]</code> | Deploy targets for the manual-dispatch deploy workflow, e.g. ["dev", "stage", "prod"]. |
13255
13261
  | <code><a href="#@xpertss/projen-types.CdkInfraProjectOptions.property.ecrEcs">ecrEcs</a></code> | <code><a href="#@xpertss/projen-types.EcrEcsOptions">EcrEcsOptions</a></code> | *No description.* |
13256
13262
  | <code><a href="#@xpertss/projen-types.CdkInfraProjectOptions.property.edgeResources">edgeResources</a></code> | <code>string[]</code> | *No description.* |
13263
+ | <code><a href="#@xpertss/projen-types.CdkInfraProjectOptions.property.environments">environments</a></code> | <code>string \| <a href="#@xpertss/projen-types.EnvironmentOptions">EnvironmentOptions</a>[]</code> | Deploy targets for the manual-dispatch deploy workflow, e.g. ["dev", "stage", "prod"]. No `deploy` workflow is generated when this is empty or omitted. |
13257
13264
 
13258
13265
  ---
13259
13266
 
@@ -13289,35 +13296,42 @@ public readonly gheTokenSecret: string;
13289
13296
 
13290
13297
  ---
13291
13298
 
13292
- ##### `environments`<sup>Required</sup> <a name="environments" id="@xpertss/projen-types.CdkInfraProjectOptions.property.environments"></a>
13299
+ ##### `ecrEcs`<sup>Optional</sup> <a name="ecrEcs" id="@xpertss/projen-types.CdkInfraProjectOptions.property.ecrEcs"></a>
13293
13300
 
13294
13301
  ```typescript
13295
- public readonly environments: (string | EnvironmentOptions)[];
13302
+ public readonly ecrEcs: EcrEcsOptions;
13296
13303
  ```
13297
13304
 
13298
- - *Type:* string | <a href="#@xpertss/projen-types.EnvironmentOptions">EnvironmentOptions</a>[]
13299
-
13300
- Deploy targets for the manual-dispatch deploy workflow, e.g. ["dev", "stage", "prod"].
13305
+ - *Type:* <a href="#@xpertss/projen-types.EcrEcsOptions">EcrEcsOptions</a>
13301
13306
 
13302
13307
  ---
13303
13308
 
13304
- ##### `ecrEcs`<sup>Optional</sup> <a name="ecrEcs" id="@xpertss/projen-types.CdkInfraProjectOptions.property.ecrEcs"></a>
13309
+ ##### `edgeResources`<sup>Optional</sup> <a name="edgeResources" id="@xpertss/projen-types.CdkInfraProjectOptions.property.edgeResources"></a>
13305
13310
 
13306
13311
  ```typescript
13307
- public readonly ecrEcs: EcrEcsOptions;
13312
+ public readonly edgeResources: string[];
13308
13313
  ```
13309
13314
 
13310
- - *Type:* <a href="#@xpertss/projen-types.EcrEcsOptions">EcrEcsOptions</a>
13315
+ - *Type:* string[]
13311
13316
 
13312
13317
  ---
13313
13318
 
13314
- ##### `edgeResources`<sup>Optional</sup> <a name="edgeResources" id="@xpertss/projen-types.CdkInfraProjectOptions.property.edgeResources"></a>
13319
+ ##### `environments`<sup>Optional</sup> <a name="environments" id="@xpertss/projen-types.CdkInfraProjectOptions.property.environments"></a>
13315
13320
 
13316
13321
  ```typescript
13317
- public readonly edgeResources: string[];
13322
+ public readonly environments: (string | EnvironmentOptions)[];
13318
13323
  ```
13319
13324
 
13320
- - *Type:* string[]
13325
+ - *Type:* string | <a href="#@xpertss/projen-types.EnvironmentOptions">EnvironmentOptions</a>[]
13326
+ - *Default:* no deploy workflow
13327
+
13328
+ Deploy targets for the manual-dispatch deploy workflow, e.g. ["dev", "stage", "prod"]. No `deploy` workflow is generated when this is empty or omitted.
13329
+
13330
+ Optional rather than required so that `projen new --from` can scaffold
13331
+ the repo: its union type (`string | EnvironmentOptions`) is not
13332
+ "JSON-like", so projen's CLI cannot render a value for it into the
13333
+ initial `.projenrc.ts` - and a *required* option it cannot render leaves
13334
+ behind a projenrc that does not type-check.
13321
13335
 
13322
13336
  ---
13323
13337
 
@@ -13751,9 +13765,9 @@ const gitHubActionProjectOptions: GitHubActionProjectOptions = { ... }
13751
13765
  | <code><a href="#@xpertss/projen-types.GitHubActionProjectOptions.property.stale">stale</a></code> | <code>boolean</code> | Auto-close of stale issues and pull request. |
13752
13766
  | <code><a href="#@xpertss/projen-types.GitHubActionProjectOptions.property.staleOptions">staleOptions</a></code> | <code>projen.github.StaleOptions</code> | Auto-close stale issues and pull requests. |
13753
13767
  | <code><a href="#@xpertss/projen-types.GitHubActionProjectOptions.property.vscode">vscode</a></code> | <code>boolean</code> | Enable VSCode integration. |
13754
- | <code><a href="#@xpertss/projen-types.GitHubActionProjectOptions.property.dogfood">dogfood</a></code> | <code><a href="#@xpertss/projen-types.ActionDogfoodOptions">ActionDogfoodOptions</a></code> | The dogfood scenario (AD-001). |
13755
13768
  | <code><a href="#@xpertss/projen-types.GitHubActionProjectOptions.property.sonarHostUrl">sonarHostUrl</a></code> | <code>string</code> | URL of the org's self-hosted SonarQube instance. |
13756
13769
  | <code><a href="#@xpertss/projen-types.GitHubActionProjectOptions.property.description">description</a></code> | <code>string</code> | One-line description of the action. |
13770
+ | <code><a href="#@xpertss/projen-types.GitHubActionProjectOptions.property.dogfood">dogfood</a></code> | <code><a href="#@xpertss/projen-types.ActionDogfoodOptions">ActionDogfoodOptions</a></code> | The dogfood scenario (AD-001). |
13757
13771
  | <code><a href="#@xpertss/projen-types.GitHubActionProjectOptions.property.gheTokenSecret">gheTokenSecret</a></code> | <code>string</code> | Name of the GitHub Actions secret holding the PAT used for projen-automation PR comments (F003/F009) and, when the action has a `token` input, the dogfood's invocation of it. |
13758
13772
  | <code><a href="#@xpertss/projen-types.GitHubActionProjectOptions.property.license">license</a></code> | <code>string</code> | SPDX identifier for the generated `LICENSE`. |
13759
13773
  | <code><a href="#@xpertss/projen-types.GitHubActionProjectOptions.property.sonarPullRequestGate">sonarPullRequestGate</a></code> | <code>boolean</code> | Whether `sonar.yml` also runs on `pull_request` as a pass/fail gate. |
@@ -14129,23 +14143,6 @@ Enabled by default for root projects. Disabled for non-root projects.
14129
14143
 
14130
14144
  ---
14131
14145
 
14132
- ##### `dogfood`<sup>Required</sup> <a name="dogfood" id="@xpertss/projen-types.GitHubActionProjectOptions.property.dogfood"></a>
14133
-
14134
- ```typescript
14135
- public readonly dogfood: ActionDogfoodOptions;
14136
- ```
14137
-
14138
- - *Type:* <a href="#@xpertss/projen-types.ActionDogfoodOptions">ActionDogfoodOptions</a>
14139
-
14140
- The dogfood scenario (AD-001).
14141
-
14142
- What fixture state, what to assert, and
14143
- how to clean up are specified by the action's own F### spec - the
14144
- highest-risk behavior of that action. Required: a default no-op
14145
- dogfood would silently hollow out a load-bearing AD-001 workflow.
14146
-
14147
- ---
14148
-
14149
14146
  ##### `sonarHostUrl`<sup>Required</sup> <a name="sonarHostUrl" id="@xpertss/projen-types.GitHubActionProjectOptions.property.sonarHostUrl"></a>
14150
14147
 
14151
14148
  ```typescript
@@ -14177,6 +14174,30 @@ template and recorded in the private `package.json`.
14177
14174
 
14178
14175
  ---
14179
14176
 
14177
+ ##### `dogfood`<sup>Optional</sup> <a name="dogfood" id="@xpertss/projen-types.GitHubActionProjectOptions.property.dogfood"></a>
14178
+
14179
+ ```typescript
14180
+ public readonly dogfood: ActionDogfoodOptions;
14181
+ ```
14182
+
14183
+ - *Type:* <a href="#@xpertss/projen-types.ActionDogfoodOptions">ActionDogfoodOptions</a>
14184
+ - *Default:* `test-dogfood.yml` runs one failing step that tells you to declare a scenario
14185
+
14186
+ The dogfood scenario (AD-001).
14187
+
14188
+ What fixture state, what to assert, and
14189
+ how to clean up are specified by the action's own F### spec - the
14190
+ highest-risk behavior of that action.
14191
+
14192
+ Its type is a struct, which projen's CLI cannot render into a projenrc,
14193
+ so it can only be written by hand - it is therefore optional, because a
14194
+ *required* option `projen new` cannot supply would make this project
14195
+ type impossible to scaffold. AD-001's "never a silent no-op dogfood"
14196
+ rule is enforced instead by the workflow it generates in that case: a
14197
+ single step that fails on every PR until a scenario is declared.
14198
+
14199
+ ---
14200
+
14180
14201
  ##### `gheTokenSecret`<sup>Optional</sup> <a name="gheTokenSecret" id="@xpertss/projen-types.GitHubActionProjectOptions.property.gheTokenSecret"></a>
14181
14202
 
14182
14203
  ```typescript
@@ -14580,7 +14601,8 @@ const javaServiceProjectOptions: JavaServiceProjectOptions = { ... }
14580
14601
  | <code><a href="#@xpertss/projen-types.JavaServiceProjectOptions.property.gheTokenSecret">gheTokenSecret</a></code> | <code>string</code> | *No description.* |
14581
14602
  | <code><a href="#@xpertss/projen-types.JavaServiceProjectOptions.property.sonarProjectKey">sonarProjectKey</a></code> | <code>string</code> | SonarQube project key. |
14582
14603
  | <code><a href="#@xpertss/projen-types.JavaServiceProjectOptions.property.version">version</a></code> | <code>string</code> | *No description.* |
14583
- | <code><a href="#@xpertss/projen-types.JavaServiceProjectOptions.property.cdkDeployHook">cdkDeployHook</a></code> | <code><a href="#@xpertss/projen-types.CdkDeployHookOptions">CdkDeployHookOptions</a></code> | *No description.* |
14604
+ | <code><a href="#@xpertss/projen-types.JavaServiceProjectOptions.property.cdkDeployHook">cdkDeployHook</a></code> | <code>boolean</code> | Whether to generate the `deploy-cdk` workflow at all. |
14605
+ | <code><a href="#@xpertss/projen-types.JavaServiceProjectOptions.property.cdkDeployTargetRepo">cdkDeployTargetRepo</a></code> | <code>string</code> | The companion CDK infra/app repo (`owner/repo`) whose `deploy.yml` the `deploy-cdk` workflow dispatches. |
14584
14606
  | <code><a href="#@xpertss/projen-types.JavaServiceProjectOptions.property.dockerRegistry">dockerRegistry</a></code> | <code>string</code> | *No description.* |
14585
14607
  | <code><a href="#@xpertss/projen-types.JavaServiceProjectOptions.property.environments">environments</a></code> | <code>string \| <a href="#@xpertss/projen-types.EnvironmentOptions">EnvironmentOptions</a>[]</code> | Deploy targets to offer on the `CdkDeployHook`'s manual-dispatch workflow, when the hook is enabled. |
14586
14608
  | <code><a href="#@xpertss/projen-types.JavaServiceProjectOptions.property.useFlyway">useFlyway</a></code> | <code>boolean</code> | *No description.* |
@@ -14656,11 +14678,29 @@ public readonly version: string;
14656
14678
  ##### `cdkDeployHook`<sup>Optional</sup> <a name="cdkDeployHook" id="@xpertss/projen-types.JavaServiceProjectOptions.property.cdkDeployHook"></a>
14657
14679
 
14658
14680
  ```typescript
14659
- public readonly cdkDeployHook: CdkDeployHookOptions;
14681
+ public readonly cdkDeployHook: boolean;
14660
14682
  ```
14661
14683
 
14662
- - *Type:* <a href="#@xpertss/projen-types.CdkDeployHookOptions">CdkDeployHookOptions</a>
14663
- - *Default:* { enabled: true }
14684
+ - *Type:* boolean
14685
+ - *Default:* true
14686
+
14687
+ Whether to generate the `deploy-cdk` workflow at all.
14688
+
14689
+ ---
14690
+
14691
+ ##### `cdkDeployTargetRepo`<sup>Optional</sup> <a name="cdkDeployTargetRepo" id="@xpertss/projen-types.JavaServiceProjectOptions.property.cdkDeployTargetRepo"></a>
14692
+
14693
+ ```typescript
14694
+ public readonly cdkDeployTargetRepo: string;
14695
+ ```
14696
+
14697
+ - *Type:* string
14698
+ - *Default:* `deploy-cdk.yml` is generated with a single failing step that tells you to set this
14699
+
14700
+ The companion CDK infra/app repo (`owner/repo`) whose `deploy.yml` the `deploy-cdk` workflow dispatches.
14701
+
14702
+ A plain string rather than a nested struct so that
14703
+ `projen new --from
14664
14704
 
14665
14705
  ---
14666
14706
 
package/README.md CHANGED
@@ -25,21 +25,39 @@ All project types:
25
25
 
26
26
  ## Getting started
27
27
 
28
- Create a new git repository and install the dependencies:
28
+ Scaffold the repo with projen's own bootstrap, pointed at this package:
29
29
 
30
30
  ```bash
31
31
  mkdir my-project && cd my-project
32
32
  git init
33
- npm install -D projen constructs @xpertss/projen-types
33
+ npx projen new --from @xpertss/projen-types cdk_infra --name my-project
34
34
  ```
35
35
 
36
- Write a `.projenrc.ts` (see examples below), then generate the project:
36
+ That writes a starter `.projenrc.ts`, synthesizes the whole scaffold and
37
+ installs dependencies. The type names `projen new` accepts are `cdk_infra`,
38
+ `cdk_app`, `java_library`, `java_service`, `java_app` and
39
+ `git_hub_action`; pass a bogus one to have it list them. Required options
40
+ become flags: `--name` for every type, plus `--group-id`/`--artifact-id`
41
+ (Java) and `--sonar-host-url` (`git_hub_action`). Any other plainly-typed
42
+ option can be passed the same way - `--cdk-deploy-target-repo owner/repo`,
43
+ `--docker-registry ghcr.io`, `--no-use-flyway`, and so on.
44
+
45
+ Commit the result. From then on, every change to the scaffold goes through
46
+ `.projenrc.ts` followed by `npx projen`:
37
47
 
38
48
  ```bash
39
49
  npx projen
40
50
  ```
41
51
 
42
- Commit the result. From then on, every change to the scaffold goes through `.projenrc.ts` followed by `npx projen`.
52
+ Every type scaffolds from that one command; no option is *required* that
53
+ `projen new` cannot pass. The structured options - `environments` and
54
+ `GitHubActionProject`'s `dogfood` - are ones projen's CLI cannot render
55
+ into a projenrc, so they are added afterwards by editing `.projenrc.ts` and
56
+ re-running `npx projen`. Leaving `environments` out simply generates no
57
+ deploy workflow; leaving `dogfood` out (or a service's
58
+ `cdkDeployTargetRepo`) still generates the workflow, with one step that
59
+ fails and tells you what to add - a gate this package considers load-bearing
60
+ is allowed to be missing loudly, never silently.
43
61
 
44
62
  The `name` option must match the `name` field in the project's `package.json` (for the CDK types) or the project name used by projen's `java.JavaProject` (for the Java types).
45
63
 
@@ -143,7 +161,7 @@ const project = new JavaServiceProject({
143
161
  groupId: 'org.xpertss',
144
162
  artifactId: 'stream-processor',
145
163
  dockerRegistry: 'docker.io/xpertss',
146
- cdkDeployHook: { targetRepo: 'xpertss/stream-infra' },
164
+ cdkDeployTargetRepo: 'xpertss/stream-infra',
147
165
  environments: ['dev', { name: 'prod', requiresApproval: true }],
148
166
  });
149
167
 
@@ -155,7 +173,7 @@ You get (everything from `JavaMavenProject` - `pom.xml`, `build` + drift check,
155
173
  - `spring-boot-starter-web` added to the pom.
156
174
  - `.github/workflows/publish-docker.yml` - manual dispatch: `mvn -B package && docker build -t <registry>/<name>:<sha>`, logged in with the `DOCKER_USERNAME` / `DOCKER_PASSWORD` secrets. `dockerRegistry` defaults to `docker.io`.
157
175
  - Flyway wiring when `useFlyway` (default `true`): `flyway-maven-plugin` ^10 + `flyway-core` ^10 in the pom, and `src/main/resources/db/migration/V1__init.sql`.
158
- - `.github/workflows/deploy-cdk.yml` (the `CdkDeployHook`, enabled by default) - manual dispatch with an environment selector; each job sends a `workflow_dispatch` to `deploy.yml` in the companion `targetRepo` (a `CdkInfraProject`/`CdkAppProject` repo). `targetRepo` is required when the hook is enabled; disable it with `cdkDeployHook: { enabled: false }`. `environments` defaults to `['prod']`.
176
+ - `.github/workflows/deploy-cdk.yml` (the `CdkDeployHook`, generated by default) - manual dispatch with an environment selector; each job sends a `workflow_dispatch` to `deploy.yml` in the companion `cdkDeployTargetRepo` (a `CdkInfraProject`/`CdkAppProject` repo). With no `cdkDeployTargetRepo` set, the workflow is still generated but each job's only step fails with instructions - it is dispatch-only, so that lands on whoever tries to deploy rather than on every PR. Turn the workflow off entirely with `cdkDeployHook: false`. `environments` defaults to `['prod']`.
159
177
 
160
178
  ### JavaAppProject
161
179
 
@@ -235,13 +253,13 @@ You get:
235
253
 
236
254
  - `action.yml` and `auto-commit.sh` are hand-written - this type only lints their content via `build.yml`'s shellcheck/yamllint/actionlint checks.
237
255
  - `.github/workflows/build.yml` - lint gate: `apt`-installed shellcheck/yamllint plus a pinned, SHA-256-verified `actionlint` release binary. Gates `main` alongside `sonar.yml`.
238
- - `.github/workflows/test-dogfood.yml` - runs the `dogfood.scenario` steps above against this repo's own `action.yml` (via `uses: .`), then the shared `cleanup`, on `workflow_dispatch`, every `pull_request`, and nightly.
256
+ - `.github/workflows/test-dogfood.yml` - runs the `dogfood.scenario` steps above against this repo's own `action.yml` (via `uses: .`), then the shared `cleanup`, on `workflow_dispatch`, every `pull_request`, and nightly. Omit `dogfood` and the workflow still exists, with one step that fails on every PR until you declare a scenario - AD-001 allows a dogfood to be missing loudly, never silently. A *partial* `dogfood` (a scenario with no cleanup) is a synth error.
239
257
  - `.github/workflows/sonar.yml` - self-hosted SonarQube via the Scanner CLI, scanning `action.yml`/`.github/workflows/**`/`**/*.sh` explicitly.
240
258
  - `.github/workflows/release.yml` - `feat:`/`fix:` commits on `main` bump the version, tag `vX.Y.Z`, and create a GitHub Release.
241
259
  - `.github/workflows/projen-drift-check.yml`, `workflow-change-notice.yml`, `actions-allowlist-guard.yml` - drift detection, a change notice, and an action allow-list guard, always included.
242
- - `package.json` (**private**, version source only), `tsconfig.json`, `.yamllint`, `LICENSE` (MIT by default), and a `README.md` template - all regenerated by `npx projen`.
260
+ - `package.json` (**private**, version source only), `.yamllint`, `LICENSE` (MIT by default), and a `README.md` template - all regenerated by `npx projen`.
243
261
 
244
- Needs the same two secrets as everything else in this package: `PROJEN_GITHUB_TOKEN` (used for automated PR comments) and `SONAR_TOKEN` (the Sonar scan). Onboarding a brand-new action repo from scratch: `npm init -y && npm install -D projen constructs @xpertss/projen-types`, write the `.projenrc.ts` above, `npx projen && npm install`, then hand-write `action.yml`/`auto-commit.sh`/`test/fixtures/`.
262
+ Needs the same two secrets as everything else in this package: `PROJEN_GITHUB_TOKEN` (used for automated PR comments) and `SONAR_TOKEN` (the Sonar scan). Onboard a brand-new action repo following [Getting started](#getting-started), write the `.projenrc.ts` above, then hand-write `action.yml`/`auto-commit.sh`/`test/fixtures/`.
245
263
 
246
264
  ## Common options
247
265
 
@@ -253,7 +271,7 @@ CDK project types (`CdkInfraProjectOptions` / `CdkAppProjectOptions`):
253
271
  | `cdkVersion` | `2.189.1` | AWS CDK version |
254
272
  | `gheTokenSecret` | `PROJEN_GITHUB_TOKEN` | GitHub secret holding projen's PAT |
255
273
  | `slackWebhookSecret` | - | GitHub secret with a Slack webhook URL for deploy notifications |
256
- | `environments` | - (required) | Deploy targets for the `deploy` workflow; strings or `EnvironmentOptions` |
274
+ | `environments` | - (no `deploy` workflow) | Deploy targets for the `deploy` workflow; strings or `EnvironmentOptions` |
257
275
  | `ecrEcs` | - | `EcrEcsOptions` - `enabled`, `externalImageSource` (default `true`) |
258
276
  | `edgeResources` | - | Subset of `cloudfront`, `route53`, `apigateway`, `cognito`, `sqs` |
259
277
  | `database` | - (app only) | `DatabaseOptions` - `engine` (`postgres`/`mysql`/`dynamodb`, default `postgres`), `migrationTool` |
@@ -269,10 +287,14 @@ Java project types (`JavaLibraryProjectOptions` / `JavaServiceProjectOptions` /
269
287
  | `version` | `0.1.0` | Maven version |
270
288
  | `sonarProjectKey` | - | SonarQube project key; the sonar step is skipped when unset |
271
289
  | `gheTokenSecret` | `PROJEN_GITHUB_TOKEN` | GitHub secret holding projen's PAT |
290
+ | `cdkDeployTargetRepo` | - (service only; `deploy-cdk.yml` fails until set) | Companion CDK repo (`owner/repo`) whose `deploy.yml` the deploy hook dispatches |
291
+ | `cdkDeployHook` | `true` (service only) | Whether to generate `deploy-cdk.yml` at all |
292
+ | `dockerRegistry` | `docker.io` (service only) | Registry the Docker image is pushed to |
293
+ | `useFlyway` | `true` (service only) | Flyway plugin/dependency + `V1__init.sql` |
272
294
 
273
295
  `EnvironmentOptions` for deploy targets:
274
296
 
275
- ```typescript
297
+ ```text
276
298
  interface EnvironmentOptions {
277
299
  readonly name: string; // e.g. "dev", "stage", "prod"
278
300
  readonly accountId?: string; // AWS account id (CDK deploys)
@@ -292,13 +314,13 @@ Plain strings (`'dev'`) are shorthand for `{ name: 'dev' }`.
292
314
  | `sonarHostUrl` | - (required) | URL of your self-hosted SonarQube instance; must be reachable from github.com-hosted runners |
293
315
  | `sonarTokenSecret` | `SONAR_TOKEN` | GitHub secret holding the Sonar token |
294
316
  | `sonarPullRequestGate` | `true` | Whether `sonar.yml` also runs on `pull_request` as a pass/fail gate |
295
- | `dogfood` | - (required) | `ActionDogfoodOptions` - the scenario that exercises the action end-to-end via `uses: .` |
317
+ | `dogfood` | - (a `test-dogfood.yml` that fails until you declare one) | `ActionDogfoodOptions` - the scenario that exercises the action end-to-end via `uses: .` |
296
318
  | `license` | `MIT` | SPDX identifier for the generated `LICENSE` |
297
319
  | `gheTokenSecret` | `PROJEN_GITHUB_TOKEN` | GitHub secret holding projen's PAT |
298
320
 
299
321
  `ActionDogfoodOptions`/`ActionDogfoodStep` - the dogfood scenario (`test-dogfood.yml`):
300
322
 
301
- ```typescript
323
+ ```text
302
324
  interface ActionDogfoodOptions {
303
325
  readonly scenario: ActionDogfoodStep[]; // one or more, run in order - required
304
326
  readonly cleanup: string[]; // shared, run once at the end with `if: always()` - required
@@ -19,7 +19,7 @@ const ACTIONLINT_SHA256 = '8aca8db96f1b94770f1b0d72b6dddcb1ebb8123cb3712530b08cc
19
19
  * the release build job, so the lint commands exist in exactly one place.
20
20
  */
21
21
  class ActionBuildWorkflow extends projen_1.Component {
22
- static [JSII_RTTI_SYMBOL_1] = { fqn: "@xpertss/projen-types.ActionBuildWorkflow", version: "0.0.2" };
22
+ static [JSII_RTTI_SYMBOL_1] = { fqn: "@xpertss/projen-types.ActionBuildWorkflow", version: "0.0.4" };
23
23
  task;
24
24
  workflow;
25
25
  constructor(scope) {
@@ -40,8 +40,12 @@ export interface ActionDogfoodOptions {
40
40
  * repo**, end-to-end, via a local `uses: .` reference - no external harness.
41
41
  * Builds `test-dogfood.yml` from an ordered `scenario` of invocation steps
42
42
  * (see `ActionDogfoodStep`) followed by a shared cleanup step.
43
+ *
44
+ * Omitting `options` generates the workflow with a single failing step (see
45
+ * `UNCONFIGURED_STEPS`). A *partially* declared dogfood is still a synth
46
+ * error: if you wrote a scenario by hand, you can write its cleanup too.
43
47
  */
44
48
  export declare class ActionDogfoodWorkflow extends Component {
45
49
  readonly workflow: github.GithubWorkflow;
46
- constructor(scope: github.GitHubProject, options: ActionDogfoodOptions);
50
+ constructor(scope: github.GitHubProject, options?: ActionDogfoodOptions);
47
51
  }
@@ -18,29 +18,53 @@ function slug(name, index) {
18
18
  .replace(/^-+|-+$/g, '');
19
19
  return `${base || 'step'}-${index}`;
20
20
  }
21
+ // The stand-in scenario used when a project declares no `dogfood` at all
22
+ // (e.g. a repo `projen new` just scaffolded). The workflow is still
23
+ // generated and still runs on every PR - it just fails, telling you what to
24
+ // write. AD-001's rule is that a dogfood must never be *silently* absent;
25
+ // throwing during synth instead would make the project type unscaffoldable,
26
+ // since `projen new` has no way to supply a scenario.
27
+ const UNCONFIGURED_STEPS = [
28
+ 'echo "::error::this action has no dogfood scenario, so nothing exercises it end-to-end."',
29
+ 'echo "Add dogfood: { scenario: [...], cleanup: [...] } to .projenrc.ts and run npx projen - see the @xpertss/projen-types README."',
30
+ 'exit 1',
31
+ ];
21
32
  /**
22
33
  * Per AD-001's dogfood test: the composite action is run **against this
23
34
  * repo**, end-to-end, via a local `uses: .` reference - no external harness.
24
35
  * Builds `test-dogfood.yml` from an ordered `scenario` of invocation steps
25
36
  * (see `ActionDogfoodStep`) followed by a shared cleanup step.
37
+ *
38
+ * Omitting `options` generates the workflow with a single failing step (see
39
+ * `UNCONFIGURED_STEPS`). A *partially* declared dogfood is still a synth
40
+ * error: if you wrote a scenario by hand, you can write its cleanup too.
26
41
  */
27
42
  class ActionDogfoodWorkflow extends projen_1.Component {
28
- static [JSII_RTTI_SYMBOL_1] = { fqn: "@xpertss/projen-types.ActionDogfoodWorkflow", version: "0.0.2" };
43
+ static [JSII_RTTI_SYMBOL_1] = { fqn: "@xpertss/projen-types.ActionDogfoodWorkflow", version: "0.0.4" };
29
44
  workflow;
30
45
  constructor(scope, options) {
31
46
  super(scope, 'ActionDogfoodWorkflow');
32
- if (!options.scenario || options.scenario.length === 0) {
33
- throw new Error('ActionDogfoodWorkflow requires at least one dogfood.scenario step');
34
- }
35
- if (!options.cleanup || options.cleanup.length === 0) {
36
- throw new Error('ActionDogfoodWorkflow requires dogfood.cleanup');
47
+ if (options) {
48
+ if (!options.scenario || options.scenario.length === 0) {
49
+ throw new Error('ActionDogfoodWorkflow requires at least one dogfood.scenario step');
50
+ }
51
+ if (!options.cleanup || options.cleanup.length === 0) {
52
+ throw new Error('ActionDogfoodWorkflow requires dogfood.cleanup');
53
+ }
37
54
  }
38
55
  const gh = scope.github;
39
56
  if (!gh) {
40
57
  throw new Error('ActionDogfoodWorkflow requires GitHub integration to be enabled');
41
58
  }
42
- const steps = [projen_1.github.WorkflowSteps.checkout()];
43
- options.scenario.forEach((step, index) => {
59
+ const steps = options
60
+ ? [projen_1.github.WorkflowSteps.checkout()]
61
+ : [
62
+ {
63
+ name: 'Dogfood scenario not configured',
64
+ run: UNCONFIGURED_STEPS.join('\n'),
65
+ },
66
+ ];
67
+ (options?.scenario ?? []).forEach((step, index) => {
44
68
  if (step.fixtureSteps && step.fixtureSteps.length > 0) {
45
69
  steps.push({
46
70
  name: `${step.name}: fixture`,
@@ -59,26 +83,32 @@ class ActionDogfoodWorkflow extends projen_1.Component {
59
83
  run: step.assertions.join('\n'),
60
84
  });
61
85
  });
62
- steps.push({
63
- name: 'Cleanup',
64
- if: 'always()',
65
- run: options.cleanup.join('\n'),
66
- });
86
+ if (options) {
87
+ steps.push({
88
+ name: 'Cleanup',
89
+ if: 'always()',
90
+ run: options.cleanup.join('\n'),
91
+ });
92
+ }
67
93
  this.workflow = new projen_1.github.GithubWorkflow(gh, 'test-dogfood');
68
94
  this.workflow.on({
69
95
  workflowDispatch: {},
70
96
  pullRequest: { branches: ['main'] },
71
- schedule: [{ cron: NIGHTLY_DOGFOOD_SCHEDULE }],
97
+ // No nightly canary while unconfigured: the PR run is the signal, and
98
+ // a cron that always fails is just a daily notification nobody reads.
99
+ ...(options ? { schedule: [{ cron: NIGHTLY_DOGFOOD_SCHEDULE }] } : {}),
72
100
  });
73
101
  this.workflow.addJob('dogfood', {
74
102
  runsOn: ['ubuntu-latest'],
75
- permissions: {
76
- contents: projen_1.github.workflows.JobPermission.WRITE,
77
- pullRequests: projen_1.github.workflows.JobPermission.WRITE,
78
- },
103
+ permissions: options
104
+ ? {
105
+ contents: projen_1.github.workflows.JobPermission.WRITE,
106
+ pullRequests: projen_1.github.workflows.JobPermission.WRITE,
107
+ }
108
+ : { contents: projen_1.github.workflows.JobPermission.READ },
79
109
  steps,
80
110
  });
81
111
  }
82
112
  }
83
113
  exports.ActionDogfoodWorkflow = ActionDogfoodWorkflow;
84
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWN0aW9uLWRvZ2Zvb2Qtd29ya2Zsb3cuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvYWN0aW9ucy9hY3Rpb24tZG9nZm9vZC13b3JrZmxvdy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7O0FBQUEsbUNBQTJDO0FBRTNDLHdFQUF3RTtBQUN4RSwwRUFBMEU7QUFDMUUscUVBQXFFO0FBQ3JFLG9EQUFvRDtBQUNwRCxNQUFNLHdCQUF3QixHQUFHLFlBQVksQ0FBQztBQXFDOUMseUVBQXlFO0FBQ3pFLHVFQUF1RTtBQUN2RSw4Q0FBOEM7QUFDOUMsU0FBUyxJQUFJLENBQUMsSUFBWSxFQUFFLEtBQWE7SUFDdkMsTUFBTSxJQUFJLEdBQUcsSUFBSTtTQUNkLFdBQVcsRUFBRTtTQUNiLE9BQU8sQ0FBQyxhQUFhLEVBQUUsR0FBRyxDQUFDO1NBQzNCLE9BQU8sQ0FBQyxVQUFVLEVBQUUsRUFBRSxDQUFDLENBQUM7SUFDM0IsT0FBTyxHQUFHLElBQUksSUFBSSxNQUFNLElBQUksS0FBSyxFQUFFLENBQUM7QUFDdEMsQ0FBQztBQVVEOzs7OztHQUtHO0FBQ0gsTUFBYSxxQkFBc0IsU0FBUSxrQkFBUzs7SUFDbEMsUUFBUSxDQUF3QjtJQUVoRCxZQUFZLEtBQTJCLEVBQUUsT0FBNkI7UUFDcEUsS0FBSyxDQUFDLEtBQUssRUFBRSx1QkFBdUIsQ0FBQyxDQUFDO1FBRXRDLElBQUksQ0FBQyxPQUFPLENBQUMsUUFBUSxJQUFJLE9BQU8sQ0FBQyxRQUFRLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRSxDQUFDO1lBQ3ZELE1BQU0sSUFBSSxLQUFLLENBQ2IsbUVBQW1FLENBQ3BFLENBQUM7UUFDSixDQUFDO1FBQ0QsSUFBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPLElBQUksT0FBTyxDQUFDLE9BQU8sQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFLENBQUM7WUFDckQsTUFBTSxJQUFJLEtBQUssQ0FBQyxnREFBZ0QsQ0FBQyxDQUFDO1FBQ3BFLENBQUM7UUFFRCxNQUFNLEVBQUUsR0FBRyxLQUFLLENBQUMsTUFBTSxDQUFDO1FBQ3hCLElBQUksQ0FBQyxFQUFFLEVBQUUsQ0FBQztZQUNSLE1BQU0sSUFBSSxLQUFLLENBQ2IsaUVBQWlFLENBQ2xFLENBQUM7UUFDSixDQUFDO1FBRUQsTUFBTSxLQUFLLEdBQStCLENBQUMsZUFBTSxDQUFDLGFBQWEsQ0FBQyxRQUFRLEVBQUUsQ0FBQyxDQUFDO1FBRTVFLE9BQU8sQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLENBQUMsSUFBSSxFQUFFLEtBQUssRUFBRSxFQUFFO1lBQ3ZDLElBQUksSUFBSSxDQUFDLFlBQVksSUFBSSxJQUFJLENBQUMsWUFBWSxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQztnQkFDdEQsS0FBSyxDQUFDLElBQUksQ0FBQztvQkFDVCxJQUFJLEVBQUUsR0FBRyxJQUFJLENBQUMsSUFBSSxXQUFXO29CQUM3QixHQUFHLEVBQUUsSUFBSSxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDO2lCQUNsQyxDQUFDLENBQUM7WUFDTCxDQUFDO1lBRUQsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLE1BQU0sSUFBSSxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDO1lBQ3JFLEtBQUssQ0FBQyxJQUFJLENBQUM7Z0JBQ1QsRUFBRSxFQUFFLElBQUksQ0FBQyxFQUFFLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsS0FBSyxDQUFDO2dCQUNyQyxJQUFJLEVBQUUsR0FBRyxJQUFJLENBQUMsSUFBSSxrQkFBa0I7Z0JBQ3BDLElBQUksRUFBRSxHQUFHO2dCQUNULEdBQUcsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLEVBQUUsSUFBSSxFQUFFLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO2FBQzVDLENBQUMsQ0FBQztZQUVILEtBQUssQ0FBQyxJQUFJLENBQUM7Z0JBQ1QsSUFBSSxFQUFFLEdBQUcsSUFBSSxDQUFDLElBQUksVUFBVTtnQkFDNUIsR0FBRyxFQUFFLElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQzthQUNoQyxDQUFDLENBQUM7UUFDTCxDQUFDLENBQUMsQ0FBQztRQUVILEtBQUssQ0FBQyxJQUFJLENBQUM7WUFDVCxJQUFJLEVBQUUsU0FBUztZQUNmLEVBQUUsRUFBRSxVQUFVO1lBQ2QsR0FBRyxFQUFFLE9BQU8sQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQztTQUNoQyxDQUFDLENBQUM7UUFFSCxJQUFJLENBQUMsUUFBUSxHQUFHLElBQUksZUFBTSxDQUFDLGNBQWMsQ0FBQyxFQUFFLEVBQUUsY0FBYyxDQUFDLENBQUM7UUFDOUQsSUFBSSxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUM7WUFDZixnQkFBZ0IsRUFBRSxFQUFFO1lBQ3BCLFdBQVcsRUFBRSxFQUFFLFFBQVEsRUFBRSxDQUFDLE1BQU0sQ0FBQyxFQUFFO1lBQ25DLFFBQVEsRUFBRSxDQUFDLEVBQUUsSUFBSSxFQUFFLHdCQUF3QixFQUFFLENBQUM7U0FDL0MsQ0FBQyxDQUFDO1FBQ0gsSUFBSSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsU0FBUyxFQUFFO1lBQzlCLE1BQU0sRUFBRSxDQUFDLGVBQWUsQ0FBQztZQUN6QixXQUFXLEVBQUU7Z0JBQ1gsUUFBUSxFQUFFLGVBQU0sQ0FBQyxTQUFTLENBQUMsYUFBYSxDQUFDLEtBQUs7Z0JBQzlDLFlBQVksRUFBRSxlQUFNLENBQUMsU0FBUyxDQUFDLGFBQWEsQ0FBQyxLQUFLO2FBQ25EO1lBQ0QsS0FBSztTQUNOLENBQUMsQ0FBQztJQUNMLENBQUM7O0FBbEVILHNEQW1FQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgZ2l0aHViIH0gZnJvbSAncHJvamVuJztcblxuLy8gTmlnaHRseSBlbnZpcm9ubWVudC1yZWdyZXNzaW9uIGNhbmFyeSAoQUQtMDAxL0YwMDYpOiByZS1ydW5zIHRoZSBzYW1lXG4vLyBzY2VuYXJpbyBhZ2FpbnN0IHNldHRsZWQgYG1haW5gIGluIHRvZGF5J3MgcnVubmVyIGltYWdlLCBpbmRlcGVuZGVudCBvZlxuLy8gdGhlIHB1bGxfcmVxdWVzdCBnYXRlLiBRdWlldCBVVEMgaG91cjsgYSBjb21wb25lbnQgY29uc3RhbnQsIG5vdCBhXG4vLyBwcm9qZWN0IG9wdGlvbiAtIHVwZ3JhZGluZyBpdCBpcyBhIHJldmlld2VkIGRpZmYuXG5jb25zdCBOSUdIVExZX0RPR0ZPT0RfU0NIRURVTEUgPSAnMTcgMyAqICogKic7XG5cbi8qKlxuICogT25lIGludm9jYXRpb24gb2YgdGhlIGFjdGlvbiB3aXRoaW4gdGhlIGRvZ2Zvb2Qgc2NlbmFyaW86IG9wdGlvbmFsIGZpeHR1cmVcbiAqIHNldHVwLCB0aGUgYHVzZXM6IC5gIGNhbGwgd2l0aCB0aGlzIHN0ZXAncyBpbnB1dHMsIHRoZW4gdGhpcyBzdGVwJ3NcbiAqIGFzc2VydGlvbnMuIE1vc3QgYWN0aW9ucyBuZWVkIGV4YWN0bHkgb25lOyBhY3Rpb25zIHdpdGggYSByZS1ydW4vbm8tb3BcbiAqIGJlaGF2aW9yIHRvIHZlcmlmeSAoZS5nLiBGMDA2J3MgcmV1c2UtdGhlLVBSIHBhdGgsIEYwMDcncyBuby1vcC1jb21taXRcbiAqIHBhdGgpIGRlY2xhcmUgdHdvLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEFjdGlvbkRvZ2Zvb2RTdGVwIHtcbiAgLyoqIExhYmVsIHVzZWQgdG8gbmFtZSB0aGlzIHN0ZXAtZ3JvdXAncyBnZW5lcmF0ZWQgd29ya2Zsb3cgc3RlcHMuICovXG4gIHJlYWRvbmx5IG5hbWU6IHN0cmluZztcblxuICAvKipcbiAgICogU3RlcCBpZCBmb3IgdGhlIGB1c2VzOiAuYCBpbnZvY2F0aW9uLCBzbyBhIGxhdGVyIGFzc2VydGlvbiBjYW5cbiAgICogcmVmZXJlbmNlIHRoaXMgc3RlcCdzIG91dHB1dHMgdmlhIGAke3sgc3RlcHMuPGlkPi5vdXRwdXRzLjxuYW1lPiB9fWAuXG4gICAqIEBkZWZhdWx0IC0gYSBzbHVnIGRlcml2ZWQgZnJvbSBgbmFtZWAsIGRpc2FtYmlndWF0ZWQgYnkgcG9zaXRpb25cbiAgICovXG4gIHJlYWRvbmx5IGlkPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBTaGVsbCBzdGVwcyBleGVjdXRlZCBiZWZvcmUgdGhpcyBpbnZvY2F0aW9uLCB0byBwcm9kdWNlIG9yIGFsdGVyXG4gICAqIGZpeHR1cmUgc3RhdGUuXG4gICAqIEBkZWZhdWx0IFtdXG4gICAqL1xuICByZWFkb25seSBmaXh0dXJlU3RlcHM/OiBzdHJpbmdbXTtcblxuICAvKipcbiAgICogYHdpdGg6YCBpbnB1dHMgZm9yIHRoaXMgaW52b2NhdGlvbidzIGxvY2FsIGB1c2VzOiAuYCBjYWxsLlxuICAgKiBAZGVmYXVsdCB7fVxuICAgKi9cbiAgcmVhZG9ubHkgaW5wdXRzPzogUmVjb3JkPHN0cmluZywgc3RyaW5nPjtcblxuICAvKiogU2hlbGwgYXNzZXJ0aW9ucyBhZnRlciB0aGlzIGludm9jYXRpb24gLSB0aGUgam9iIGZhaWxzIHVubGVzcyBldmVyeSBvbmUgZXhpdHMgMC4gKi9cbiAgcmVhZG9ubHkgYXNzZXJ0aW9uczogc3RyaW5nW107XG59XG5cbi8vIExvd2VyY2FzZSwgbm9uLWFscGhhbnVtZXJpY3MgY29sbGFwc2VkIHRvIGEgc2luZ2xlIGAtYCwgdHJpbW1lZCAtIHRoZW5cbi8vIGRpc2FtYmlndWF0ZWQgYnkgcG9zaXRpb24gc28gdHdvIHN0ZXBzIHNoYXJpbmcgYSBuYW1lIChvciBhbiB1bm5hbWVkXG4vLyBzbHVnLCBlLmcuIHB1bmN0dWF0aW9uLW9ubHkpIG5ldmVyIGNvbGxpZGUuXG5mdW5jdGlvbiBzbHVnKG5hbWU6IHN0cmluZywgaW5kZXg6IG51bWJlcik6IHN0cmluZyB7XG4gIGNvbnN0IGJhc2UgPSBuYW1lXG4gICAgLnRvTG93ZXJDYXNlKClcbiAgICAucmVwbGFjZSgvW15hLXowLTldKy9nLCAnLScpXG4gICAgLnJlcGxhY2UoL14tK3wtKyQvZywgJycpO1xuICByZXR1cm4gYCR7YmFzZSB8fCAnc3RlcCd9LSR7aW5kZXh9YDtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBBY3Rpb25Eb2dmb29kT3B0aW9ucyB7XG4gIC8qKiBPbmUgb3IgbW9yZSBzY2VuYXJpbyBzdGVwcywgcnVuIGluIG9yZGVyLCBpbiB0aGUgZG9nZm9vZCBqb2IuICovXG4gIHJlYWRvbmx5IHNjZW5hcmlvOiBBY3Rpb25Eb2dmb29kU3RlcFtdO1xuXG4gIC8qKiBTaGVsbCBjbGVhbnVwLCBydW4gb25jZSBhdCB0aGUgZW5kIHdpdGggYGlmOiBhbHdheXMoKWAsIHNvIHJlcGVhdGVkIHJ1bnMgc3RhcnQgY2xlYW4uICovXG4gIHJlYWRvbmx5IGNsZWFudXA6IHN0cmluZ1tdO1xufVxuXG4vKipcbiAqIFBlciBBRC0wMDEncyBkb2dmb29kIHRlc3Q6IHRoZSBjb21wb3NpdGUgYWN0aW9uIGlzIHJ1biAqKmFnYWluc3QgdGhpc1xuICogcmVwbyoqLCBlbmQtdG8tZW5kLCB2aWEgYSBsb2NhbCBgdXNlczogLmAgcmVmZXJlbmNlIC0gbm8gZXh0ZXJuYWwgaGFybmVzcy5cbiAqIEJ1aWxkcyBgdGVzdC1kb2dmb29kLnltbGAgZnJvbSBhbiBvcmRlcmVkIGBzY2VuYXJpb2Agb2YgaW52b2NhdGlvbiBzdGVwc1xuICogKHNlZSBgQWN0aW9uRG9nZm9vZFN0ZXBgKSBmb2xsb3dlZCBieSBhIHNoYXJlZCBjbGVhbnVwIHN0ZXAuXG4gKi9cbmV4cG9ydCBjbGFzcyBBY3Rpb25Eb2dmb29kV29ya2Zsb3cgZXh0ZW5kcyBDb21wb25lbnQge1xuICBwdWJsaWMgcmVhZG9ubHkgd29ya2Zsb3c6IGdpdGh1Yi5HaXRodWJXb3JrZmxvdztcblxuICBjb25zdHJ1Y3RvcihzY29wZTogZ2l0aHViLkdpdEh1YlByb2plY3QsIG9wdGlvbnM6IEFjdGlvbkRvZ2Zvb2RPcHRpb25zKSB7XG4gICAgc3VwZXIoc2NvcGUsICdBY3Rpb25Eb2dmb29kV29ya2Zsb3cnKTtcblxuICAgIGlmICghb3B0aW9ucy5zY2VuYXJpbyB8fCBvcHRpb25zLnNjZW5hcmlvLmxlbmd0aCA9PT0gMCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAnQWN0aW9uRG9nZm9vZFdvcmtmbG93IHJlcXVpcmVzIGF0IGxlYXN0IG9uZSBkb2dmb29kLnNjZW5hcmlvIHN0ZXAnLFxuICAgICAgKTtcbiAgICB9XG4gICAgaWYgKCFvcHRpb25zLmNsZWFudXAgfHwgb3B0aW9ucy5jbGVhbnVwLmxlbmd0aCA9PT0gMCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdBY3Rpb25Eb2dmb29kV29ya2Zsb3cgcmVxdWlyZXMgZG9nZm9vZC5jbGVhbnVwJyk7XG4gICAgfVxuXG4gICAgY29uc3QgZ2ggPSBzY29wZS5naXRodWI7XG4gICAgaWYgKCFnaCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAnQWN0aW9uRG9nZm9vZFdvcmtmbG93IHJlcXVpcmVzIEdpdEh1YiBpbnRlZ3JhdGlvbiB0byBiZSBlbmFibGVkJyxcbiAgICAgICk7XG4gICAgfVxuXG4gICAgY29uc3Qgc3RlcHM6IGdpdGh1Yi53b3JrZmxvd3MuSm9iU3RlcFtdID0gW2dpdGh1Yi5Xb3JrZmxvd1N0ZXBzLmNoZWNrb3V0KCldO1xuXG4gICAgb3B0aW9ucy5zY2VuYXJpby5mb3JFYWNoKChzdGVwLCBpbmRleCkgPT4ge1xuICAgICAgaWYgKHN0ZXAuZml4dHVyZVN0ZXBzICYmIHN0ZXAuZml4dHVyZVN0ZXBzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgc3RlcHMucHVzaCh7XG4gICAgICAgICAgbmFtZTogYCR7c3RlcC5uYW1lfTogZml4dHVyZWAsXG4gICAgICAgICAgcnVuOiBzdGVwLmZpeHR1cmVTdGVwcy5qb2luKCdcXG4nKSxcbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGhhc0lucHV0cyA9IHN0ZXAuaW5wdXRzICYmIE9iamVjdC5rZXlzKHN0ZXAuaW5wdXRzKS5sZW5ndGggPiAwO1xuICAgICAgc3RlcHMucHVzaCh7XG4gICAgICAgIGlkOiBzdGVwLmlkID8/IHNsdWcoc3RlcC5uYW1lLCBpbmRleCksXG4gICAgICAgIG5hbWU6IGAke3N0ZXAubmFtZX06IHJ1biB0aGUgYWN0aW9uYCxcbiAgICAgICAgdXNlczogJy4nLFxuICAgICAgICAuLi4oaGFzSW5wdXRzID8geyB3aXRoOiBzdGVwLmlucHV0cyB9IDoge30pLFxuICAgICAgfSk7XG5cbiAgICAgIHN0ZXBzLnB1c2goe1xuICAgICAgICBuYW1lOiBgJHtzdGVwLm5hbWV9OiBhc3NlcnRgLFxuICAgICAgICBydW46IHN0ZXAuYXNzZXJ0aW9ucy5qb2luKCdcXG4nKSxcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgc3RlcHMucHVzaCh7XG4gICAgICBuYW1lOiAnQ2xlYW51cCcsXG4gICAgICBpZjogJ2Fsd2F5cygpJyxcbiAgICAgIHJ1bjogb3B0aW9ucy5jbGVhbnVwLmpvaW4oJ1xcbicpLFxuICAgIH0pO1xuXG4gICAgdGhpcy53b3JrZmxvdyA9IG5ldyBnaXRodWIuR2l0aHViV29ya2Zsb3coZ2gsICd0ZXN0LWRvZ2Zvb2QnKTtcbiAgICB0aGlzLndvcmtmbG93Lm9uKHtcbiAgICAgIHdvcmtmbG93RGlzcGF0Y2g6IHt9LFxuICAgICAgcHVsbFJlcXVlc3Q6IHsgYnJhbmNoZXM6IFsnbWFpbiddIH0sXG4gICAgICBzY2hlZHVsZTogW3sgY3JvbjogTklHSFRMWV9ET0dGT09EX1NDSEVEVUxFIH1dLFxuICAgIH0pO1xuICAgIHRoaXMud29ya2Zsb3cuYWRkSm9iKCdkb2dmb29kJywge1xuICAgICAgcnVuc09uOiBbJ3VidW50dS1sYXRlc3QnXSxcbiAgICAgIHBlcm1pc3Npb25zOiB7XG4gICAgICAgIGNvbnRlbnRzOiBnaXRodWIud29ya2Zsb3dzLkpvYlBlcm1pc3Npb24uV1JJVEUsXG4gICAgICAgIHB1bGxSZXF1ZXN0czogZ2l0aHViLndvcmtmbG93cy5Kb2JQZXJtaXNzaW9uLldSSVRFLFxuICAgICAgfSxcbiAgICAgIHN0ZXBzLFxuICAgIH0pO1xuICB9XG59XG4iXX0=
114
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWN0aW9uLWRvZ2Zvb2Qtd29ya2Zsb3cuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvYWN0aW9ucy9hY3Rpb24tZG9nZm9vZC13b3JrZmxvdy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7O0FBQUEsbUNBQTJDO0FBRTNDLHdFQUF3RTtBQUN4RSwwRUFBMEU7QUFDMUUscUVBQXFFO0FBQ3JFLG9EQUFvRDtBQUNwRCxNQUFNLHdCQUF3QixHQUFHLFlBQVksQ0FBQztBQXFDOUMseUVBQXlFO0FBQ3pFLHVFQUF1RTtBQUN2RSw4Q0FBOEM7QUFDOUMsU0FBUyxJQUFJLENBQUMsSUFBWSxFQUFFLEtBQWE7SUFDdkMsTUFBTSxJQUFJLEdBQUcsSUFBSTtTQUNkLFdBQVcsRUFBRTtTQUNiLE9BQU8sQ0FBQyxhQUFhLEVBQUUsR0FBRyxDQUFDO1NBQzNCLE9BQU8sQ0FBQyxVQUFVLEVBQUUsRUFBRSxDQUFDLENBQUM7SUFDM0IsT0FBTyxHQUFHLElBQUksSUFBSSxNQUFNLElBQUksS0FBSyxFQUFFLENBQUM7QUFDdEMsQ0FBQztBQVVELHlFQUF5RTtBQUN6RSxvRUFBb0U7QUFDcEUsNEVBQTRFO0FBQzVFLDBFQUEwRTtBQUMxRSw0RUFBNEU7QUFDNUUsc0RBQXNEO0FBQ3RELE1BQU0sa0JBQWtCLEdBQWE7SUFDbkMsMEZBQTBGO0lBQzFGLG9JQUFvSTtJQUNwSSxRQUFRO0NBQ1QsQ0FBQztBQUVGOzs7Ozs7Ozs7R0FTRztBQUNILE1BQWEscUJBQXNCLFNBQVEsa0JBQVM7O0lBQ2xDLFFBQVEsQ0FBd0I7SUFFaEQsWUFBWSxLQUEyQixFQUFFLE9BQThCO1FBQ3JFLEtBQUssQ0FBQyxLQUFLLEVBQUUsdUJBQXVCLENBQUMsQ0FBQztRQUV0QyxJQUFJLE9BQU8sRUFBRSxDQUFDO1lBQ1osSUFBSSxDQUFDLE9BQU8sQ0FBQyxRQUFRLElBQUksT0FBTyxDQUFDLFFBQVEsQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFLENBQUM7Z0JBQ3ZELE1BQU0sSUFBSSxLQUFLLENBQ2IsbUVBQW1FLENBQ3BFLENBQUM7WUFDSixDQUFDO1lBQ0QsSUFBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPLElBQUksT0FBTyxDQUFDLE9BQU8sQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFLENBQUM7Z0JBQ3JELE1BQU0sSUFBSSxLQUFLLENBQUMsZ0RBQWdELENBQUMsQ0FBQztZQUNwRSxDQUFDO1FBQ0gsQ0FBQztRQUVELE1BQU0sRUFBRSxHQUFHLEtBQUssQ0FBQyxNQUFNLENBQUM7UUFDeEIsSUFBSSxDQUFDLEVBQUUsRUFBRSxDQUFDO1lBQ1IsTUFBTSxJQUFJLEtBQUssQ0FDYixpRUFBaUUsQ0FDbEUsQ0FBQztRQUNKLENBQUM7UUFFRCxNQUFNLEtBQUssR0FBK0IsT0FBTztZQUMvQyxDQUFDLENBQUMsQ0FBQyxlQUFNLENBQUMsYUFBYSxDQUFDLFFBQVEsRUFBRSxDQUFDO1lBQ25DLENBQUMsQ0FBQztnQkFDQTtvQkFDRSxJQUFJLEVBQUUsaUNBQWlDO29CQUN2QyxHQUFHLEVBQUUsa0JBQWtCLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQztpQkFDbkM7YUFDRixDQUFDO1FBRUosQ0FBQyxPQUFPLEVBQUUsUUFBUSxJQUFJLEVBQUUsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLElBQUksRUFBRSxLQUFLLEVBQUUsRUFBRTtZQUNoRCxJQUFJLElBQUksQ0FBQyxZQUFZLElBQUksSUFBSSxDQUFDLFlBQVksQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLENBQUM7Z0JBQ3RELEtBQUssQ0FBQyxJQUFJLENBQUM7b0JBQ1QsSUFBSSxFQUFFLEdBQUcsSUFBSSxDQUFDLElBQUksV0FBVztvQkFDN0IsR0FBRyxFQUFFLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQztpQkFDbEMsQ0FBQyxDQUFDO1lBQ0wsQ0FBQztZQUVELE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxNQUFNLElBQUksTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQztZQUNyRSxLQUFLLENBQUMsSUFBSSxDQUFDO2dCQUNULEVBQUUsRUFBRSxJQUFJLENBQUMsRUFBRSxJQUFJLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLEtBQUssQ0FBQztnQkFDckMsSUFBSSxFQUFFLEdBQUcsSUFBSSxDQUFDLElBQUksa0JBQWtCO2dCQUNwQyxJQUFJLEVBQUUsR0FBRztnQkFDVCxHQUFHLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxFQUFFLElBQUksRUFBRSxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQzthQUM1QyxDQUFDLENBQUM7WUFFSCxLQUFLLENBQUMsSUFBSSxDQUFDO2dCQUNULElBQUksRUFBRSxHQUFHLElBQUksQ0FBQyxJQUFJLFVBQVU7Z0JBQzVCLEdBQUcsRUFBRSxJQUFJLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUM7YUFDaEMsQ0FBQyxDQUFDO1FBQ0wsQ0FBQyxDQUFDLENBQUM7UUFFSCxJQUFJLE9BQU8sRUFBRSxDQUFDO1lBQ1osS0FBSyxDQUFDLElBQUksQ0FBQztnQkFDVCxJQUFJLEVBQUUsU0FBUztnQkFDZixFQUFFLEVBQUUsVUFBVTtnQkFDZCxHQUFHLEVBQUUsT0FBTyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDO2FBQ2hDLENBQUMsQ0FBQztRQUNMLENBQUM7UUFFRCxJQUFJLENBQUMsUUFBUSxHQUFHLElBQUksZUFBTSxDQUFDLGNBQWMsQ0FBQyxFQUFFLEVBQUUsY0FBYyxDQUFDLENBQUM7UUFDOUQsSUFBSSxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUM7WUFDZixnQkFBZ0IsRUFBRSxFQUFFO1lBQ3BCLFdBQVcsRUFBRSxFQUFFLFFBQVEsRUFBRSxDQUFDLE1BQU0sQ0FBQyxFQUFFO1lBQ25DLHNFQUFzRTtZQUN0RSxzRUFBc0U7WUFDdEUsR0FBRyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsRUFBRSxRQUFRLEVBQUUsQ0FBQyxFQUFFLElBQUksRUFBRSx3QkFBd0IsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO1NBQ3ZFLENBQUMsQ0FBQztRQUNILElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLFNBQVMsRUFBRTtZQUM5QixNQUFNLEVBQUUsQ0FBQyxlQUFlLENBQUM7WUFDekIsV0FBVyxFQUFFLE9BQU87Z0JBQ2xCLENBQUMsQ0FBQztvQkFDQSxRQUFRLEVBQUUsZUFBTSxDQUFDLFNBQVMsQ0FBQyxhQUFhLENBQUMsS0FBSztvQkFDOUMsWUFBWSxFQUFFLGVBQU0sQ0FBQyxTQUFTLENBQUMsYUFBYSxDQUFDLEtBQUs7aUJBQ25EO2dCQUNELENBQUMsQ0FBQyxFQUFFLFFBQVEsRUFBRSxlQUFNLENBQUMsU0FBUyxDQUFDLGFBQWEsQ0FBQyxJQUFJLEVBQUU7WUFDckQsS0FBSztTQUNOLENBQUMsQ0FBQztJQUNMLENBQUM7O0FBakZILHNEQWtGQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgZ2l0aHViIH0gZnJvbSAncHJvamVuJztcblxuLy8gTmlnaHRseSBlbnZpcm9ubWVudC1yZWdyZXNzaW9uIGNhbmFyeSAoQUQtMDAxL0YwMDYpOiByZS1ydW5zIHRoZSBzYW1lXG4vLyBzY2VuYXJpbyBhZ2FpbnN0IHNldHRsZWQgYG1haW5gIGluIHRvZGF5J3MgcnVubmVyIGltYWdlLCBpbmRlcGVuZGVudCBvZlxuLy8gdGhlIHB1bGxfcmVxdWVzdCBnYXRlLiBRdWlldCBVVEMgaG91cjsgYSBjb21wb25lbnQgY29uc3RhbnQsIG5vdCBhXG4vLyBwcm9qZWN0IG9wdGlvbiAtIHVwZ3JhZGluZyBpdCBpcyBhIHJldmlld2VkIGRpZmYuXG5jb25zdCBOSUdIVExZX0RPR0ZPT0RfU0NIRURVTEUgPSAnMTcgMyAqICogKic7XG5cbi8qKlxuICogT25lIGludm9jYXRpb24gb2YgdGhlIGFjdGlvbiB3aXRoaW4gdGhlIGRvZ2Zvb2Qgc2NlbmFyaW86IG9wdGlvbmFsIGZpeHR1cmVcbiAqIHNldHVwLCB0aGUgYHVzZXM6IC5gIGNhbGwgd2l0aCB0aGlzIHN0ZXAncyBpbnB1dHMsIHRoZW4gdGhpcyBzdGVwJ3NcbiAqIGFzc2VydGlvbnMuIE1vc3QgYWN0aW9ucyBuZWVkIGV4YWN0bHkgb25lOyBhY3Rpb25zIHdpdGggYSByZS1ydW4vbm8tb3BcbiAqIGJlaGF2aW9yIHRvIHZlcmlmeSAoZS5nLiBGMDA2J3MgcmV1c2UtdGhlLVBSIHBhdGgsIEYwMDcncyBuby1vcC1jb21taXRcbiAqIHBhdGgpIGRlY2xhcmUgdHdvLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEFjdGlvbkRvZ2Zvb2RTdGVwIHtcbiAgLyoqIExhYmVsIHVzZWQgdG8gbmFtZSB0aGlzIHN0ZXAtZ3JvdXAncyBnZW5lcmF0ZWQgd29ya2Zsb3cgc3RlcHMuICovXG4gIHJlYWRvbmx5IG5hbWU6IHN0cmluZztcblxuICAvKipcbiAgICogU3RlcCBpZCBmb3IgdGhlIGB1c2VzOiAuYCBpbnZvY2F0aW9uLCBzbyBhIGxhdGVyIGFzc2VydGlvbiBjYW5cbiAgICogcmVmZXJlbmNlIHRoaXMgc3RlcCdzIG91dHB1dHMgdmlhIGAke3sgc3RlcHMuPGlkPi5vdXRwdXRzLjxuYW1lPiB9fWAuXG4gICAqIEBkZWZhdWx0IC0gYSBzbHVnIGRlcml2ZWQgZnJvbSBgbmFtZWAsIGRpc2FtYmlndWF0ZWQgYnkgcG9zaXRpb25cbiAgICovXG4gIHJlYWRvbmx5IGlkPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBTaGVsbCBzdGVwcyBleGVjdXRlZCBiZWZvcmUgdGhpcyBpbnZvY2F0aW9uLCB0byBwcm9kdWNlIG9yIGFsdGVyXG4gICAqIGZpeHR1cmUgc3RhdGUuXG4gICAqIEBkZWZhdWx0IFtdXG4gICAqL1xuICByZWFkb25seSBmaXh0dXJlU3RlcHM/OiBzdHJpbmdbXTtcblxuICAvKipcbiAgICogYHdpdGg6YCBpbnB1dHMgZm9yIHRoaXMgaW52b2NhdGlvbidzIGxvY2FsIGB1c2VzOiAuYCBjYWxsLlxuICAgKiBAZGVmYXVsdCB7fVxuICAgKi9cbiAgcmVhZG9ubHkgaW5wdXRzPzogUmVjb3JkPHN0cmluZywgc3RyaW5nPjtcblxuICAvKiogU2hlbGwgYXNzZXJ0aW9ucyBhZnRlciB0aGlzIGludm9jYXRpb24gLSB0aGUgam9iIGZhaWxzIHVubGVzcyBldmVyeSBvbmUgZXhpdHMgMC4gKi9cbiAgcmVhZG9ubHkgYXNzZXJ0aW9uczogc3RyaW5nW107XG59XG5cbi8vIExvd2VyY2FzZSwgbm9uLWFscGhhbnVtZXJpY3MgY29sbGFwc2VkIHRvIGEgc2luZ2xlIGAtYCwgdHJpbW1lZCAtIHRoZW5cbi8vIGRpc2FtYmlndWF0ZWQgYnkgcG9zaXRpb24gc28gdHdvIHN0ZXBzIHNoYXJpbmcgYSBuYW1lIChvciBhbiB1bm5hbWVkXG4vLyBzbHVnLCBlLmcuIHB1bmN0dWF0aW9uLW9ubHkpIG5ldmVyIGNvbGxpZGUuXG5mdW5jdGlvbiBzbHVnKG5hbWU6IHN0cmluZywgaW5kZXg6IG51bWJlcik6IHN0cmluZyB7XG4gIGNvbnN0IGJhc2UgPSBuYW1lXG4gICAgLnRvTG93ZXJDYXNlKClcbiAgICAucmVwbGFjZSgvW15hLXowLTldKy9nLCAnLScpXG4gICAgLnJlcGxhY2UoL14tK3wtKyQvZywgJycpO1xuICByZXR1cm4gYCR7YmFzZSB8fCAnc3RlcCd9LSR7aW5kZXh9YDtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBBY3Rpb25Eb2dmb29kT3B0aW9ucyB7XG4gIC8qKiBPbmUgb3IgbW9yZSBzY2VuYXJpbyBzdGVwcywgcnVuIGluIG9yZGVyLCBpbiB0aGUgZG9nZm9vZCBqb2IuICovXG4gIHJlYWRvbmx5IHNjZW5hcmlvOiBBY3Rpb25Eb2dmb29kU3RlcFtdO1xuXG4gIC8qKiBTaGVsbCBjbGVhbnVwLCBydW4gb25jZSBhdCB0aGUgZW5kIHdpdGggYGlmOiBhbHdheXMoKWAsIHNvIHJlcGVhdGVkIHJ1bnMgc3RhcnQgY2xlYW4uICovXG4gIHJlYWRvbmx5IGNsZWFudXA6IHN0cmluZ1tdO1xufVxuXG4vLyBUaGUgc3RhbmQtaW4gc2NlbmFyaW8gdXNlZCB3aGVuIGEgcHJvamVjdCBkZWNsYXJlcyBubyBgZG9nZm9vZGAgYXQgYWxsXG4vLyAoZS5nLiBhIHJlcG8gYHByb2plbiBuZXdgIGp1c3Qgc2NhZmZvbGRlZCkuIFRoZSB3b3JrZmxvdyBpcyBzdGlsbFxuLy8gZ2VuZXJhdGVkIGFuZCBzdGlsbCBydW5zIG9uIGV2ZXJ5IFBSIC0gaXQganVzdCBmYWlscywgdGVsbGluZyB5b3Ugd2hhdCB0b1xuLy8gd3JpdGUuIEFELTAwMSdzIHJ1bGUgaXMgdGhhdCBhIGRvZ2Zvb2QgbXVzdCBuZXZlciBiZSAqc2lsZW50bHkqIGFic2VudDtcbi8vIHRocm93aW5nIGR1cmluZyBzeW50aCBpbnN0ZWFkIHdvdWxkIG1ha2UgdGhlIHByb2plY3QgdHlwZSB1bnNjYWZmb2xkYWJsZSxcbi8vIHNpbmNlIGBwcm9qZW4gbmV3YCBoYXMgbm8gd2F5IHRvIHN1cHBseSBhIHNjZW5hcmlvLlxuY29uc3QgVU5DT05GSUdVUkVEX1NURVBTOiBzdHJpbmdbXSA9IFtcbiAgJ2VjaG8gXCI6OmVycm9yOjp0aGlzIGFjdGlvbiBoYXMgbm8gZG9nZm9vZCBzY2VuYXJpbywgc28gbm90aGluZyBleGVyY2lzZXMgaXQgZW5kLXRvLWVuZC5cIicsXG4gICdlY2hvIFwiQWRkIGRvZ2Zvb2Q6IHsgc2NlbmFyaW86IFsuLi5dLCBjbGVhbnVwOiBbLi4uXSB9IHRvIC5wcm9qZW5yYy50cyBhbmQgcnVuIG5weCBwcm9qZW4gLSBzZWUgdGhlIEB4cGVydHNzL3Byb2plbi10eXBlcyBSRUFETUUuXCInLFxuICAnZXhpdCAxJyxcbl07XG5cbi8qKlxuICogUGVyIEFELTAwMSdzIGRvZ2Zvb2QgdGVzdDogdGhlIGNvbXBvc2l0ZSBhY3Rpb24gaXMgcnVuICoqYWdhaW5zdCB0aGlzXG4gKiByZXBvKiosIGVuZC10by1lbmQsIHZpYSBhIGxvY2FsIGB1c2VzOiAuYCByZWZlcmVuY2UgLSBubyBleHRlcm5hbCBoYXJuZXNzLlxuICogQnVpbGRzIGB0ZXN0LWRvZ2Zvb2QueW1sYCBmcm9tIGFuIG9yZGVyZWQgYHNjZW5hcmlvYCBvZiBpbnZvY2F0aW9uIHN0ZXBzXG4gKiAoc2VlIGBBY3Rpb25Eb2dmb29kU3RlcGApIGZvbGxvd2VkIGJ5IGEgc2hhcmVkIGNsZWFudXAgc3RlcC5cbiAqXG4gKiBPbWl0dGluZyBgb3B0aW9uc2AgZ2VuZXJhdGVzIHRoZSB3b3JrZmxvdyB3aXRoIGEgc2luZ2xlIGZhaWxpbmcgc3RlcCAoc2VlXG4gKiBgVU5DT05GSUdVUkVEX1NURVBTYCkuIEEgKnBhcnRpYWxseSogZGVjbGFyZWQgZG9nZm9vZCBpcyBzdGlsbCBhIHN5bnRoXG4gKiBlcnJvcjogaWYgeW91IHdyb3RlIGEgc2NlbmFyaW8gYnkgaGFuZCwgeW91IGNhbiB3cml0ZSBpdHMgY2xlYW51cCB0b28uXG4gKi9cbmV4cG9ydCBjbGFzcyBBY3Rpb25Eb2dmb29kV29ya2Zsb3cgZXh0ZW5kcyBDb21wb25lbnQge1xuICBwdWJsaWMgcmVhZG9ubHkgd29ya2Zsb3c6IGdpdGh1Yi5HaXRodWJXb3JrZmxvdztcblxuICBjb25zdHJ1Y3RvcihzY29wZTogZ2l0aHViLkdpdEh1YlByb2plY3QsIG9wdGlvbnM/OiBBY3Rpb25Eb2dmb29kT3B0aW9ucykge1xuICAgIHN1cGVyKHNjb3BlLCAnQWN0aW9uRG9nZm9vZFdvcmtmbG93Jyk7XG5cbiAgICBpZiAob3B0aW9ucykge1xuICAgICAgaWYgKCFvcHRpb25zLnNjZW5hcmlvIHx8IG9wdGlvbnMuc2NlbmFyaW8ubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICAnQWN0aW9uRG9nZm9vZFdvcmtmbG93IHJlcXVpcmVzIGF0IGxlYXN0IG9uZSBkb2dmb29kLnNjZW5hcmlvIHN0ZXAnLFxuICAgICAgICApO1xuICAgICAgfVxuICAgICAgaWYgKCFvcHRpb25zLmNsZWFudXAgfHwgb3B0aW9ucy5jbGVhbnVwLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0FjdGlvbkRvZ2Zvb2RXb3JrZmxvdyByZXF1aXJlcyBkb2dmb29kLmNsZWFudXAnKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCBnaCA9IHNjb3BlLmdpdGh1YjtcbiAgICBpZiAoIWdoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICdBY3Rpb25Eb2dmb29kV29ya2Zsb3cgcmVxdWlyZXMgR2l0SHViIGludGVncmF0aW9uIHRvIGJlIGVuYWJsZWQnLFxuICAgICAgKTtcbiAgICB9XG5cbiAgICBjb25zdCBzdGVwczogZ2l0aHViLndvcmtmbG93cy5Kb2JTdGVwW10gPSBvcHRpb25zXG4gICAgICA/IFtnaXRodWIuV29ya2Zsb3dTdGVwcy5jaGVja291dCgpXVxuICAgICAgOiBbXG4gICAgICAgIHtcbiAgICAgICAgICBuYW1lOiAnRG9nZm9vZCBzY2VuYXJpbyBub3QgY29uZmlndXJlZCcsXG4gICAgICAgICAgcnVuOiBVTkNPTkZJR1VSRURfU1RFUFMuam9pbignXFxuJyksXG4gICAgICAgIH0sXG4gICAgICBdO1xuXG4gICAgKG9wdGlvbnM/LnNjZW5hcmlvID8/IFtdKS5mb3JFYWNoKChzdGVwLCBpbmRleCkgPT4ge1xuICAgICAgaWYgKHN0ZXAuZml4dHVyZVN0ZXBzICYmIHN0ZXAuZml4dHVyZVN0ZXBzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgc3RlcHMucHVzaCh7XG4gICAgICAgICAgbmFtZTogYCR7c3RlcC5uYW1lfTogZml4dHVyZWAsXG4gICAgICAgICAgcnVuOiBzdGVwLmZpeHR1cmVTdGVwcy5qb2luKCdcXG4nKSxcbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGhhc0lucHV0cyA9IHN0ZXAuaW5wdXRzICYmIE9iamVjdC5rZXlzKHN0ZXAuaW5wdXRzKS5sZW5ndGggPiAwO1xuICAgICAgc3RlcHMucHVzaCh7XG4gICAgICAgIGlkOiBzdGVwLmlkID8/IHNsdWcoc3RlcC5uYW1lLCBpbmRleCksXG4gICAgICAgIG5hbWU6IGAke3N0ZXAubmFtZX06IHJ1biB0aGUgYWN0aW9uYCxcbiAgICAgICAgdXNlczogJy4nLFxuICAgICAgICAuLi4oaGFzSW5wdXRzID8geyB3aXRoOiBzdGVwLmlucHV0cyB9IDoge30pLFxuICAgICAgfSk7XG5cbiAgICAgIHN0ZXBzLnB1c2goe1xuICAgICAgICBuYW1lOiBgJHtzdGVwLm5hbWV9OiBhc3NlcnRgLFxuICAgICAgICBydW46IHN0ZXAuYXNzZXJ0aW9ucy5qb2luKCdcXG4nKSxcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgaWYgKG9wdGlvbnMpIHtcbiAgICAgIHN0ZXBzLnB1c2goe1xuICAgICAgICBuYW1lOiAnQ2xlYW51cCcsXG4gICAgICAgIGlmOiAnYWx3YXlzKCknLFxuICAgICAgICBydW46IG9wdGlvbnMuY2xlYW51cC5qb2luKCdcXG4nKSxcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHRoaXMud29ya2Zsb3cgPSBuZXcgZ2l0aHViLkdpdGh1YldvcmtmbG93KGdoLCAndGVzdC1kb2dmb29kJyk7XG4gICAgdGhpcy53b3JrZmxvdy5vbih7XG4gICAgICB3b3JrZmxvd0Rpc3BhdGNoOiB7fSxcbiAgICAgIHB1bGxSZXF1ZXN0OiB7IGJyYW5jaGVzOiBbJ21haW4nXSB9LFxuICAgICAgLy8gTm8gbmlnaHRseSBjYW5hcnkgd2hpbGUgdW5jb25maWd1cmVkOiB0aGUgUFIgcnVuIGlzIHRoZSBzaWduYWwsIGFuZFxuICAgICAgLy8gYSBjcm9uIHRoYXQgYWx3YXlzIGZhaWxzIGlzIGp1c3QgYSBkYWlseSBub3RpZmljYXRpb24gbm9ib2R5IHJlYWRzLlxuICAgICAgLi4uKG9wdGlvbnMgPyB7IHNjaGVkdWxlOiBbeyBjcm9uOiBOSUdIVExZX0RPR0ZPT0RfU0NIRURVTEUgfV0gfSA6IHt9KSxcbiAgICB9KTtcbiAgICB0aGlzLndvcmtmbG93LmFkZEpvYignZG9nZm9vZCcsIHtcbiAgICAgIHJ1bnNPbjogWyd1YnVudHUtbGF0ZXN0J10sXG4gICAgICBwZXJtaXNzaW9uczogb3B0aW9uc1xuICAgICAgICA/IHtcbiAgICAgICAgICBjb250ZW50czogZ2l0aHViLndvcmtmbG93cy5Kb2JQZXJtaXNzaW9uLldSSVRFLFxuICAgICAgICAgIHB1bGxSZXF1ZXN0czogZ2l0aHViLndvcmtmbG93cy5Kb2JQZXJtaXNzaW9uLldSSVRFLFxuICAgICAgICB9XG4gICAgICAgIDogeyBjb250ZW50czogZ2l0aHViLndvcmtmbG93cy5Kb2JQZXJtaXNzaW9uLlJFQUQgfSxcbiAgICAgIHN0ZXBzLFxuICAgIH0pO1xuICB9XG59XG4iXX0=