cdk-opennext 0.4.9 → 0.4.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/.jsii CHANGED
@@ -8432,7 +8432,7 @@
8432
8432
  },
8433
8433
  "name": "cdk-opennext",
8434
8434
  "readme": {
8435
- "markdown": "# About\n\nCDK construct to deploy a NextJs 15 or higher application using the\n[OpenNext AWS adapter](https://github.com/opennextjs/opennextjs-aws).\n\nIt works best if [deployed in an Nx\nmonorepo](https://opennext.js.org/aws/config/nx).\n\nThis OpenNext CDK construct is based on [the reference\nconstruct](https://opennext.js.org/aws/reference-implementation)\nprovided by OpenNext. The example has been modernised, and the deploy\nto ECS option has been removed.\n\n# Usage\n\n1. Install:\n\n```sh\nnpm install --save-dev esbuild @opennextjs/aws cdk-opennext\n```\n\n2. Build your app: `npx next build`\n\n3. Build with open-next: `npx open-next build`\n\n4. Add the `NextjsSite` construct:\n\n```typescript\nimport { NextjsSite } from \"cdk-opennext\"\n\nconst site = new NextjsSite(this, \"NextjsSite\", {\n openNextPath: \".open-next\",\n})\n```\n\n`openNextPath` is optional and defaults to \".open-next\".\n\nYou can customize the Lambda function configuration using `defaultFunctionProps`:\n\n```typescript\nimport { NextjsSite } from \"cdk-opennext\"\nimport { Duration } from \"aws-cdk-lib/core\"\n\nconst site = new NextjsSite(this, \"NextjsSite\", {\n defaultFunctionProps: {\n memorySize: 2048,\n timeout: Duration.seconds(30),\n environment: {\n MY_ENV_VAR: \"value\",\n },\n },\n})\n```\n\n## Lambda Warming\n\nBy default, Lambda warming is enabled to prevent cold starts. The construct keeps 1 server instance warm with 5-minute intervals.\n\n### Default Behavior\n\n```typescript\nimport { NextjsSite } from \"cdk-opennext\"\n\nconst site = new NextjsSite(this, \"NextjsSite\", {\n // Warming is enabled by default with warm: 1\n})\n```\n\n### Customize Warming\n\n```typescript\nimport { NextjsSite } from \"cdk-opennext\"\nimport { Duration } from \"aws-cdk-lib/core\"\n\nconst site = new NextjsSite(this, \"NextjsSite\", {\n warm: 5, // Keep 5 concurrent instances warm\n warmerInterval: Duration.minutes(10), // Warm every 10 minutes\n prewarmOnDeploy: false, // Disable pre-warming on deployment\n})\n```\n\n### Disable Warming\n\n```typescript\nconst site = new NextjsSite(this, \"NextjsSite\", {\n warm: false, // Disable warming\n})\n```\n\n### How It Works\n\n- A dedicated warmer Lambda function (provided by OpenNext) periodically invokes your server functions\n- Creates concurrent invocations to keep multiple instances warm\n- EventBridge rule triggers the warmer at the specified interval\n- Optional pre-warming invokes the warmer immediately after deployment\n- Environment variable `WARMER_ENABLED=true` is set when warming is configured\n\n**Note**: Warming requires OpenNext 3.x+ with warmer support. If OpenNext doesn't provide a warmer bundle, warming will be skipped with a warning.\n\n## Custom Domain\n\nYou can configure a custom domain in three ways:\n\n### Option 1: Route 53 Hosted Zone (automatic certificate and DNS)\n\nProvide a hosted zone and the construct will automatically create a DNS-validated\ncertificate and set up A/AAAA records:\n\n```typescript\nimport { NextjsSite } from \"cdk-opennext\"\nimport { HostedZone } from \"aws-cdk-lib/aws-route53\"\n\nconst hostedZone = HostedZone.fromLookup(this, \"HostedZone\", {\n domainName: \"example.com\",\n})\n\nconst site = new NextjsSite(this, \"NextjsSite\", {\n customDomain: {\n domainName: \"app.example.com\",\n hostedZone: hostedZone,\n },\n})\n```\n\n### Option 2: Bring Your Own Certificate (external DNS)\n\nProvide your own ACM certificate when DNS is managed externally. The certificate\nmust be in us-east-1 for CloudFront:\n\n```typescript\nimport { NextjsSite } from \"cdk-opennext\"\nimport { Certificate } from \"aws-cdk-lib/aws-certificatemanager\"\n\nconst certificate = Certificate.fromCertificateArn(\n this,\n \"Certificate\",\n \"arn:aws:acm:us-east-1:123456789012:certificate/...\"\n)\n\nconst site = new NextjsSite(this, \"NextjsSite\", {\n customDomain: {\n domainName: \"app.example.com\",\n certificate: certificate,\n },\n})\n// Configure your DNS provider to point app.example.com to site.distribution.distributionDomainName\n```\n\n### Option 3: Bring Your Own Certificate with Route 53 DNS\n\nProvide both a certificate and hosted zone to use your own certificate while\nstill having the construct manage DNS records:\n\n```typescript\nimport { NextjsSite } from \"cdk-opennext\"\nimport { Certificate } from \"aws-cdk-lib/aws-certificatemanager\"\nimport { HostedZone } from \"aws-cdk-lib/aws-route53\"\n\nconst hostedZone = HostedZone.fromLookup(this, \"HostedZone\", {\n domainName: \"example.com\",\n})\n\nconst certificate = Certificate.fromCertificateArn(\n this,\n \"Certificate\",\n \"arn:aws:acm:us-east-1:123456789012:certificate/...\"\n)\n\nconst site = new NextjsSite(this, \"NextjsSite\", {\n customDomain: {\n domainName: \"app.example.com\",\n hostedZone: hostedZone,\n certificate: certificate,\n },\n})\n```\n\n# How it works\n\nThis package assumes that the Next and OpenNext build are done outside\nof this construct. Therefore this package does not pull in the\n`@opennextjs/aws` package, but it should be a dependency of your package.\n\nObviously you don't wantt to build this manually all the time, that's\nwhere Nx comes in.\n\n## Use with Nx\n\nConfiguring Nx is also covered in [the OpenNext documentation](https://opennext.js.org/aws/config/nx).\n\nIn your Nx `project.json` add a \"build\" target to build next:\n\n```json\n\"build\": {\n \"options\": {\n \"command\": \"next build\"\n },\n \"inputs\": [\n \"default\",\n \"^production\",\n \"!{projectRoot}/.next\",\n \"!{projectRoot}/.open-next\",\n \"!{projectRoot}/open-next.config.ts\",\n \"!{projectRoot}/cdk.json\",\n \"!{projectRoot}/cdk.context.json\"\n ],\n \"outputs\": [\"{projectRoot}/.next\"]\n},\n```\n\nIf you enable caching, it will only build when your NextJs app has actually changed.\n\nThen add a target to build OpenNext:\n\n```json\n\"build-open-next\": {\n \"executor\": \"nx:run-commands\",\n \"dependsOn\": [\"build\"],\n \"cache\": true,\n \"inputs\": [\"{projectRoot}/open-next.config.ts\", \"{projectRoot}/.next\"],\n \"outputs\": [\"{projectRoot}/.open-next\"],\n \"options\": {\n \"cwd\": \"{projectRoot}\",\n \"command\": \"open-next build\"\n }\n},\n```\n\nAnd finally for your cdk deploy target, depend on the open next build:\n\n```json\n\"deploy\": {\n \"dependsOn\": [\"build-open-next\"]\n}\n```\n\nSet the output to standalone in `next.config.ts`, this is key:\n\n```ts\nconst nextConfig: NextConfig = {\n output: \"standalone\",\n ...\n}\n```\n\nYour `open-next.config.ts` can look like this:\n\n```ts\nimport type { OpenNextConfig } from \"@opennextjs/aws/types/open-next\"\n\nconst config = {\n default: {\n install: {\n packages: [\n \"@swc/helpers@0.5.17\",\n \"styled-jsx@5.1.6\",\n \"@next/env@16.0.7\",\n \"semver\",\n \"pg\",\n ],\n arch: \"arm64\",\n },\n },\n buildCommand: \"exit 0\", // Nx builds Next for us\n packageJsonPath: \"../../\", // Root directory of monorepo\n} satisfies OpenNextConfig\n\nexport default config\n```\n\nThe packages to install depend on your particular config. If you don't\nuse postgres for example, remove \"pg\".\n\n# SST v2 compatibility\n\nSwitching to this construct from SST v2 is a fairly major update. All Lambda functions will be replaced.\n\n## Compatible Features\n\n- [x] Custom domains with Route 53 or external DNS\n- [x] Automatic certificate creation and DNS records\n- [x] S3 asset storage with Origin Access Control\n- [x] CloudFront distribution with custom behaviors\n- [x] Lambda server functions with streaming support\n- [x] Image optimization function\n- [x] Incremental Static Regeneration (ISR)\n- [x] Revalidation queue and DynamoDB table\n- [x] Multiple origins support\n- [x] Custom Lambda function configuration via `defaultFunctionProps`\n- [x] ARM64 architecture support\n- [x] Lambda warming to prevent cold starts (enabled by default)\n- [x] Image optimizer function protected by Origin Access Control\n\n## Not Yet Implemented\n\n**Core Functions:**\n\n- [ ] Lambda@Edge deployment - Cannot deploy server to edge for lower latency\n- [ ] Middleware as edge functions - Middleware may not execute optimally\n- [ ] Protect default server function url so it cannot be access directly\n\n**CloudFront:**\n\n- [ ] Advanced cache key generation - Current implementation uses basic x-forwarded-host only\n- [x] Geo-location header injection - CloudFront geo-headers passed to Lambda\n- [ ] Custom server cache policy configuration - Cache policy is hard-coded\n\n**Lambda Configuration:**\n\n- [ ] Image optimization configuration - No memorySize or staticImageOptimization options\n- [ ] VPC support for revalidation function\n- [ ] Custom runtime configuration - Defaults to Node.js 24.x\n- [ ] Dynamic memory allocation for initialization function - Fixed at 128 MB\n\n**Debugging:**\n\n- [ ] Sourcemap handling - Less detailed error reporting compared to SST v2\n\n# Comparison to other implementations\n\n- [SST v2](https://github.com/sst/v2): this is what I used in the\n past, but it's now community supported, PRs are being merged slowly,\n and it's getting very hard to integrate in modern monorepos.\n- [cdk-nextjs-standalone](https://github.com/jetbridge/cdk-nextjs/):\n seems actively maintained, but README.md feels very dated. It's now\n also based on OpenNext but unclear how it tracks against OpenNext.\n- [cdklabs/cdk-nextjs](https://github.com/cdklabs/cdk-nextjs): not\n based on the OpenNext adapter. Needs NAT gateway and EFS, so very\n expensive to run.\n- [open-next-cdk](https://github.com/datasprayio/open-next-cdk): no\n longer maintained it seems\n"
8435
+ "markdown": "# About\n\nCDK construct to deploy a NextJs 15 or higher application using the\n[OpenNext AWS adapter](https://github.com/opennextjs/opennextjs-aws).\n\nIt works best if [deployed in an Nx\nmonorepo](https://opennext.js.org/aws/config/nx).\n\nThis OpenNext CDK construct is based on [the reference\nconstruct](https://opennext.js.org/aws/reference-implementation)\nprovided by OpenNext. The example has been modernised, and the deploy\nto ECS option has been removed.\n\n# Usage\n\n1. Install:\n\n```sh\nnpm install --save-dev esbuild @opennextjs/aws cdk-opennext\n```\n\n2. Build your app: `npx next build`\n\n3. Build with open-next: `npx open-next build`\n\n4. Add the `NextjsSite` construct:\n\n```typescript\nimport { NextjsSite } from \"cdk-opennext\"\n\nconst site = new NextjsSite(this, \"NextjsSite\", {\n openNextPath: \".open-next\",\n})\n```\n\n`openNextPath` is optional and defaults to \".open-next\".\n\nYou can customize the Lambda function configuration using `defaultFunctionProps`:\n\n```typescript\nimport { NextjsSite } from \"cdk-opennext\"\nimport { Duration } from \"aws-cdk-lib/core\"\n\nconst site = new NextjsSite(this, \"NextjsSite\", {\n defaultFunctionProps: {\n memorySize: 2048,\n timeout: Duration.seconds(30),\n environment: {\n MY_ENV_VAR: \"value\",\n },\n },\n})\n```\n\n## Lambda Warming\n\nBy default, Lambda warming is enabled to prevent cold starts. The construct keeps 1 server instance warm with 5-minute intervals.\n\n### Default Behavior\n\n```typescript\nimport { NextjsSite } from \"cdk-opennext\"\n\nconst site = new NextjsSite(this, \"NextjsSite\", {\n // Warming is enabled by default with warm: 1\n})\n```\n\n### Customize Warming\n\n```typescript\nimport { NextjsSite } from \"cdk-opennext\"\nimport { Duration } from \"aws-cdk-lib/core\"\n\nconst site = new NextjsSite(this, \"NextjsSite\", {\n warm: 5, // Keep 5 concurrent instances warm\n warmerInterval: Duration.minutes(10), // Warm every 10 minutes\n prewarmOnDeploy: false, // Disable pre-warming on deployment\n})\n```\n\n### Disable Warming\n\n```typescript\nconst site = new NextjsSite(this, \"NextjsSite\", {\n warm: false, // Disable warming\n})\n```\n\n### How It Works\n\n- A dedicated warmer Lambda function (provided by OpenNext) periodically invokes your server functions\n- Creates concurrent invocations to keep multiple instances warm\n- EventBridge rule triggers the warmer at the specified interval\n- Optional pre-warming invokes the warmer immediately after deployment\n- Environment variable `WARMER_ENABLED=true` is set when warming is configured\n\n**Note**: Warming requires OpenNext 3.x+ with warmer support. If OpenNext doesn't provide a warmer bundle, warming will be skipped with a warning.\n\n## Custom Domain\n\nYou can configure a custom domain in three ways:\n\n### Option 1: Route 53 Hosted Zone (automatic certificate and DNS)\n\nProvide a hosted zone and the construct will automatically create a DNS-validated\ncertificate and set up A/AAAA records:\n\n```typescript\nimport { NextjsSite } from \"cdk-opennext\"\nimport { HostedZone } from \"aws-cdk-lib/aws-route53\"\n\nconst hostedZone = HostedZone.fromLookup(this, \"HostedZone\", {\n domainName: \"example.com\",\n})\n\nconst site = new NextjsSite(this, \"NextjsSite\", {\n customDomain: {\n domainName: \"app.example.com\",\n hostedZone: hostedZone,\n },\n})\n```\n\n### Option 2: Bring Your Own Certificate (external DNS)\n\nProvide your own ACM certificate when DNS is managed externally. The certificate\nmust be in us-east-1 for CloudFront:\n\n```typescript\nimport { NextjsSite } from \"cdk-opennext\"\nimport { Certificate } from \"aws-cdk-lib/aws-certificatemanager\"\n\nconst certificate = Certificate.fromCertificateArn(\n this,\n \"Certificate\",\n \"arn:aws:acm:us-east-1:123456789012:certificate/...\"\n)\n\nconst site = new NextjsSite(this, \"NextjsSite\", {\n customDomain: {\n domainName: \"app.example.com\",\n certificate: certificate,\n },\n})\n// Configure your DNS provider to point app.example.com to site.distribution.distributionDomainName\n```\n\n### Option 3: Bring Your Own Certificate with Route 53 DNS\n\nProvide both a certificate and hosted zone to use your own certificate while\nstill having the construct manage DNS records:\n\n```typescript\nimport { NextjsSite } from \"cdk-opennext\"\nimport { Certificate } from \"aws-cdk-lib/aws-certificatemanager\"\nimport { HostedZone } from \"aws-cdk-lib/aws-route53\"\n\nconst hostedZone = HostedZone.fromLookup(this, \"HostedZone\", {\n domainName: \"example.com\",\n})\n\nconst certificate = Certificate.fromCertificateArn(\n this,\n \"Certificate\",\n \"arn:aws:acm:us-east-1:123456789012:certificate/...\"\n)\n\nconst site = new NextjsSite(this, \"NextjsSite\", {\n customDomain: {\n domainName: \"app.example.com\",\n hostedZone: hostedZone,\n certificate: certificate,\n },\n})\n```\n\n# How it works\n\nThis package assumes that the Next and OpenNext build are done outside\nof this construct. Therefore this package does not pull in the\n`@opennextjs/aws` package, but it should be a dependency of your package.\n\nObviously you don't wantt to build this manually all the time, that's\nwhere Nx comes in.\n\n## Use with Nx\n\nConfiguring Nx is also covered in [the OpenNext documentation](https://opennext.js.org/aws/config/nx).\n\nIn your Nx `project.json` add a \"build\" target to build next:\n\n```json\n\"build\": {\n \"options\": {\n \"command\": \"next build\"\n },\n \"inputs\": [\n \"default\",\n \"^production\",\n \"!{projectRoot}/.next\",\n \"!{projectRoot}/.open-next\",\n \"!{projectRoot}/open-next.config.ts\",\n \"!{projectRoot}/cdk.json\",\n \"!{projectRoot}/cdk.context.json\"\n ],\n \"outputs\": [\"{projectRoot}/.next\"]\n},\n```\n\nIf you enable caching, it will only build when your NextJs app has actually changed.\n\nThen add a target to build OpenNext:\n\n```json\n\"build-open-next\": {\n \"executor\": \"nx:run-commands\",\n \"dependsOn\": [\"build\"],\n \"cache\": true,\n \"inputs\": [\"{projectRoot}/open-next.config.ts\", \"{projectRoot}/.next\"],\n \"outputs\": [\"{projectRoot}/.open-next\"],\n \"options\": {\n \"cwd\": \"{projectRoot}\",\n \"command\": \"open-next build\"\n }\n},\n```\n\nAnd finally for your cdk deploy target, depend on the open next build:\n\n```json\n\"deploy\": {\n \"dependsOn\": [\"build-open-next\"]\n}\n```\n\nSet the output to standalone in `next.config.ts`, this is key:\n\n```ts\nconst nextConfig: NextConfig = {\n output: \"standalone\",\n ...\n}\n```\n\nYour `open-next.config.ts` can look like this:\n\n```ts\nimport type { OpenNextConfig } from \"@opennextjs/aws/types/open-next\"\n\nconst config = {\n default: {\n install: {\n packages: [\n \"@swc/helpers@0.5.17\",\n \"styled-jsx@5.1.6\",\n \"@next/env@16.0.7\",\n \"semver\",\n \"pg\",\n ],\n arch: \"arm64\",\n },\n },\n buildCommand: \"exit 0\", // Nx builds Next for us\n packageJsonPath: \"../../\", // Root directory of monorepo\n} satisfies OpenNextConfig\n\nexport default config\n```\n\nThe packages to install depend on your particular config. If you don't\nuse postgres for example, remove \"pg\".\n\n# SST v2 compatibility\n\nSwitching to this construct from SST v2 is a fairly major update. All Lambda functions will be replaced.\n\n## Compatible Features\n\n- [x] Custom domains with Route 53 or external DNS\n- [x] Automatic certificate creation and DNS records\n- [x] S3 asset storage with Origin Access Control\n- [x] CloudFront distribution with custom behaviors\n- [x] Lambda server functions with streaming support\n- [x] Image optimization function\n- [x] Incremental Static Regeneration (ISR)\n- [x] Revalidation queue and DynamoDB table\n- [x] Multiple origins support\n- [x] Custom Lambda function configuration via `defaultFunctionProps`\n- [x] ARM64 architecture support\n- [x] Lambda warming to prevent cold starts (enabled by default)\n- [x] Image optimizer function protected by Origin Access Control (see [Known Issues](#known-issues))\n\n## Not Yet Implemented\n\n**Core Functions:**\n\n- [ ] Lambda@Edge deployment - Cannot deploy server to edge for lower latency\n- [ ] Middleware as edge functions - Middleware may not execute optimally\n- [ ] Protect default server function URL so it cannot be accessed directly\n\n**CloudFront:**\n\n- [ ] Advanced cache key generation - Current implementation uses basic x-forwarded-host only\n- [x] Geo-location header injection - CloudFront geo-headers passed to Lambda\n- [ ] Custom server cache policy configuration - Cache policy is hard-coded\n\n**Lambda Configuration:**\n\n- [ ] Image optimization configuration - No memorySize or staticImageOptimization options\n- [ ] VPC support for revalidation function\n- [ ] Custom runtime configuration - Defaults to Node.js 24.x\n- [ ] Dynamic memory allocation for initialization function - Fixed at 128 MB\n\n**Debugging:**\n\n- [ ] Sourcemap handling - Less detailed error reporting compared to SST v2\n\n## Known Issues\n\n### Image Optimizer OAC Missing Permission\n\nThe image optimizer function is protected by CloudFront Origin Access Control (OAC), which prevents direct access to the Lambda function URL. However, due to a [bug in AWS CDK](https://github.com/aws/aws-cdk/issues/35872), the generated Lambda resource-based policy is missing the required `lambda:InvokeFunction` permission.\n\nAWS Lambda introduced **Dual Authentication** for Function URLs, which requires **both** permissions:\n\n- `lambda:InvokeFunctionUrl`\n- `lambda:InvokeFunction` (with `invokedViaFunctionUrl: true` condition)\n\nThe CDK currently only grants the first permission. A [fix has been submitted](https://github.com/aws/aws-cdk/pull/35919) and is awaiting maintainer review.\n\n**Workaround:** Until the CDK fix is released, you can manually add the missing permission after deployment:\n\n```bash\naws lambda add-permission \\\n --statement-id \"AllowCloudFrontServicePrincipalInvokeFunction\" \\\n --action \"lambda:InvokeFunction\" \\\n --principal \"cloudfront.amazonaws.com\" \\\n --source-arn \"arn:aws:cloudfront::<ACCOUNT_ID>:distribution/<DISTRIBUTION_ID>\" \\\n --function-name <IMAGE_OPTIMIZER_FUNCTION_NAME>\n```\n\n**Note:** AWS has a temporary exception period until November 1, 2026, during which the old single-permission model still works. After this date, the dual permission will be strictly enforced.\n\n# Comparison to other implementations\n\n- [SST v2](https://github.com/sst/v2): this is what I used in the\n past, but it's now community supported, PRs are being merged slowly,\n and it's getting very hard to integrate in modern monorepos.\n- [cdk-nextjs-standalone](https://github.com/jetbridge/cdk-nextjs/):\n seems actively maintained, but README.md feels very dated. It's now\n also based on OpenNext but unclear how it tracks against OpenNext.\n- [cdklabs/cdk-nextjs](https://github.com/cdklabs/cdk-nextjs): not\n based on the OpenNext adapter. Needs NAT gateway and EFS, so very\n expensive to run.\n- [open-next-cdk](https://github.com/datasprayio/open-next-cdk): no\n longer maintained it seems\n"
8436
8436
  },
8437
8437
  "repository": {
8438
8438
  "type": "git",
@@ -8796,6 +8796,6 @@
8796
8796
  "symbolId": "src/open-next:NextjsSiteProps"
8797
8797
  }
8798
8798
  },
8799
- "version": "0.4.9",
8800
- "fingerprint": "BtaYnAOQs8y1iasge9HywZ1DmSs4xPnNcgx5PNipvoM="
8799
+ "version": "0.4.10",
8800
+ "fingerprint": "ErlvqLWTR3lfBZ/aKX1wc8eu+0mruabOAfgDIs7HiDE="
8801
8801
  }
package/README.md CHANGED
@@ -289,7 +289,7 @@ Switching to this construct from SST v2 is a fairly major update. All Lambda fun
289
289
  - [x] Custom Lambda function configuration via `defaultFunctionProps`
290
290
  - [x] ARM64 architecture support
291
291
  - [x] Lambda warming to prevent cold starts (enabled by default)
292
- - [x] Image optimizer function protected by Origin Access Control
292
+ - [x] Image optimizer function protected by Origin Access Control (see [Known Issues](#known-issues))
293
293
 
294
294
  ## Not Yet Implemented
295
295
 
@@ -297,7 +297,7 @@ Switching to this construct from SST v2 is a fairly major update. All Lambda fun
297
297
 
298
298
  - [ ] Lambda@Edge deployment - Cannot deploy server to edge for lower latency
299
299
  - [ ] Middleware as edge functions - Middleware may not execute optimally
300
- - [ ] Protect default server function url so it cannot be access directly
300
+ - [ ] Protect default server function URL so it cannot be accessed directly
301
301
 
302
302
  **CloudFront:**
303
303
 
@@ -316,6 +316,32 @@ Switching to this construct from SST v2 is a fairly major update. All Lambda fun
316
316
 
317
317
  - [ ] Sourcemap handling - Less detailed error reporting compared to SST v2
318
318
 
319
+ ## Known Issues
320
+
321
+ ### Image Optimizer OAC Missing Permission
322
+
323
+ The image optimizer function is protected by CloudFront Origin Access Control (OAC), which prevents direct access to the Lambda function URL. However, due to a [bug in AWS CDK](https://github.com/aws/aws-cdk/issues/35872), the generated Lambda resource-based policy is missing the required `lambda:InvokeFunction` permission.
324
+
325
+ AWS Lambda introduced **Dual Authentication** for Function URLs, which requires **both** permissions:
326
+
327
+ - `lambda:InvokeFunctionUrl`
328
+ - `lambda:InvokeFunction` (with `invokedViaFunctionUrl: true` condition)
329
+
330
+ The CDK currently only grants the first permission. A [fix has been submitted](https://github.com/aws/aws-cdk/pull/35919) and is awaiting maintainer review.
331
+
332
+ **Workaround:** Until the CDK fix is released, you can manually add the missing permission after deployment:
333
+
334
+ ```bash
335
+ aws lambda add-permission \
336
+ --statement-id "AllowCloudFrontServicePrincipalInvokeFunction" \
337
+ --action "lambda:InvokeFunction" \
338
+ --principal "cloudfront.amazonaws.com" \
339
+ --source-arn "arn:aws:cloudfront::<ACCOUNT_ID>:distribution/<DISTRIBUTION_ID>" \
340
+ --function-name <IMAGE_OPTIMIZER_FUNCTION_NAME>
341
+ ```
342
+
343
+ **Note:** AWS has a temporary exception period until November 1, 2026, during which the old single-permission model still works. After this date, the dual permission will be strictly enforced.
344
+
319
345
  # Comparison to other implementations
320
346
 
321
347
  - [SST v2](https://github.com/sst/v2): this is what I used in the
package/lib/open-next.js CHANGED
@@ -455,5 +455,5 @@ if(request.headers["cloudfront-viewer-longitude"]) {
455
455
  }
456
456
  exports.NextjsSite = NextjsSite;
457
457
  _a = JSII_RTTI_SYMBOL_1;
458
- NextjsSite[_a] = { fqn: "cdk-opennext.NextjsSite", version: "0.4.9" };
458
+ NextjsSite[_a] = { fqn: "cdk-opennext.NextjsSite", version: "0.4.10" };
459
459
  //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3Blbi1uZXh0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL29wZW4tbmV4dC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUFBLG1DQUFtQztBQUNuQywyQkFBaUM7QUFDakMsNkJBQTRCO0FBQzVCLCtFQUEwRjtBQUMxRiwrREFnQm1DO0FBQ25DLCtFQUkyQztBQUMzQywyREFBbUY7QUFDbkYsdURBQXVEO0FBQ3ZELHVFQUErRDtBQUUvRCx1REFTK0I7QUFDL0IsbUZBQXFFO0FBQ3JFLG1EQUE4RDtBQUM5RCx5REFBd0Y7QUFDeEYseUVBQWtFO0FBQ2xFLCtDQUE4RDtBQUM5RCxxRUFBd0U7QUFDeEUsaURBQTJDO0FBQzNDLDJDQU95QjtBQUN6QixtRUFBdUQ7QUFDdkQsMkNBQXNDO0FBZ0p0QyxNQUFhLFVBQVcsU0FBUSxzQkFBUztJQWlCdkMsSUFBVyxxQkFBcUI7UUFDOUIsT0FBTyxJQUFJLENBQUMsc0JBQXNCLENBQUE7SUFDcEMsQ0FBQztJQUVELElBQVcsR0FBRztRQUNaLE9BQU8sV0FBVyxJQUFJLENBQUMsWUFBWSxDQUFDLHNCQUFzQixFQUFFLENBQUE7SUFDOUQsQ0FBQztJQUVELElBQVcsZUFBZTtRQUN4QixPQUFPLElBQUksQ0FBQyxpQkFBaUI7WUFDM0IsQ0FBQyxDQUFDLFdBQVcsSUFBSSxDQUFDLGlCQUFpQixFQUFFO1lBQ3JDLENBQUMsQ0FBQyxXQUFXLElBQUksQ0FBQyxZQUFZLENBQUMsc0JBQXNCLEVBQUUsQ0FBQTtJQUMzRCxDQUFDO0lBRUQsWUFBWSxLQUFnQixFQUFFLEVBQVUsRUFBRSxLQUFzQjtRQUM5RCxLQUFLLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxDQUFBO1FBQ2hCLElBQUksQ0FBQyxLQUFLLEdBQUcsS0FBSyxDQUFBO1FBQ2xCLElBQUksQ0FBQyxZQUFZLEdBQUcsS0FBSyxDQUFDLFlBQVksSUFBSSxZQUFZLENBQUE7UUFDdEQsSUFBSSxDQUFDLGNBQWMsR0FBRyxJQUFJLENB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QUMsSUFBSSxDQUFDLENBQUMsQ0FBQztZQUM1QixNQUFNLEVBQUUsZUFBUSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUM7WUFDMUIsTUFBTSxFQUFFLGVBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO1NBQ3pCLENBQUMsQ0FBQTtJQUNKLENBQUM7SUFFTyx1QkFBdUI7UUFDN0IsT0FBTyw0QkFBVyxDQUFDLGlCQUFpQixDQUFBO0lBQ3RDLENBQUM7O0FBamlCSCxnQ0FraUJDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgY3JlYXRlSGFzaCB9IGZyb20gXCJjcnlwdG9cIlxuaW1wb3J0IHsgcmVhZEZpbGVTeW5jIH0gZnJvbSBcImZzXCJcbmltcG9ydCAqIGFzIHBhdGggZnJvbSBcInBhdGhcIlxuaW1wb3J0IHsgRG5zVmFsaWRhdGVkQ2VydGlmaWNhdGUsIElDZXJ0aWZpY2F0ZSB9IGZyb20gXCJhd3MtY2RrLWxpYi9hd3MtY2VydGlmaWNhdGVtYW5hZ2VyXCJcbmltcG9ydCB7XG4gIEFsbG93ZWRNZXRob2RzLFxuICB0eXBlIEJlaGF2aW9yT3B0aW9ucyxcbiAgQ2FjaGVDb29raWVCZWhhdmlvcixcbiAgQ2FjaGVIZWFkZXJCZWhhdmlvcixcbiAgQ2FjaGVQb2xpY3ksXG4gIENhY2hlUXVlcnlTdHJpbmdCZWhhdmlvcixcbiAgQ2FjaGVkTWV0aG9kcyxcbiAgRGlzdHJpYnV0aW9uLFxuICB0eXBlIElDYWNoZVBvbGljeSxcbiAgdHlwZSBJT3JpZ2luLFxuICBWaWV3ZXJQcm90b2NvbFBvbGljeSxcbiAgRnVuY3Rpb25FdmVudFR5cGUsXG4gIE9yaWdpblJlcXVlc3RQb2xpY3ksXG4gIEZ1bmN0aW9uIGFzIENsb3VkZnJvbnRGdW5jdGlvbixcbiAgRnVuY3Rpb25Db2RlLFxufSBmcm9tIFwiYXdzLWNkay1saWIvYXdzLWNsb3VkZnJvbnRcIlxuaW1wb3J0IHtcbiAgRnVuY3Rpb25VcmxPcmlnaW4sXG4gIEh0dHBPcmlnaW4sXG4gIFMzQnVja2V0T3JpZ2luLFxufSBmcm9tIFwiYXdzLWNkay1saWIvYXdzLWNsb3VkZnJvbnQtb3JpZ2luc1wiXG5pbXBvcnQgeyBUYWJsZVYyIGFzIFRhYmxlLCBBdHRyaWJ1dGVUeXBlLCBCaWxsaW5nIH0gZnJvbSBcImF3cy1jZGstbGliL2F3cy1keW5hbW9kYlwiXG5pbXBvcnQgeyBSdWxlLCBTY2hlZHVsZSB9IGZyb20gXCJhd3MtY2RrLWxpYi9hd3MtZXZlbnRzXCJcbmltcG9ydCB7IExhbWJkYUZ1bmN0aW9uIH0gZnJvbSBcImF3cy1jZGstbGliL2F3cy1ldmVudHMtdGFyZ2V0c1wiXG5pbXBvcnQgeyB0eXBlIElHcmFudGFibGUgfSBmcm9tIFwiYXdzLWNkay1saWIvYXdzLWlhbVwiXG5pbXBvcnQge1xuICBDb2RlLFxuICBGdW5jdGlvbiBhcyBDZGtGdW5jdGlvbixcbiAgdHlwZSBGdW5jdGlvbk9wdGlvbnMsXG4gIEZ1bmN0aW9uVXJsQXV0aFR5cGUsXG4gIEludm9rZU1vZGUsXG4gIExvZ2dpbmdGb3JtYXQsXG4gIFJ1bnRpbWUsXG4gIEFyY2hpdGVjdHVyZSxcbn0gZnJvbSBcImF3cy1jZGstbGliL2F3cy1sYW1iZGFcIlxuaW1wb3J0IHsgU3FzRXZlbnRTb3VyY2UgfSBmcm9tIFwiYXdzLWNkay1saWIvYXdzLWxhbWJkYS1ldmVudC1zb3VyY2VzXCJcbmltcG9ydCB7IExvZ0dyb3VwLCBSZXRlbnRpb25EYXlzIH0gZnJvbSBcImF3cy1jZGstbGliL2F3cy1sb2dzXCJcbmltcG9ydCB7IEFhYWFSZWNvcmQsIEFSZWNvcmQsIElIb3N0ZWRab25lLCBSZWNvcmRUYXJnZXQgfSBmcm9tIFwiYXdzLWNkay1saWIvYXdzLXJvdXRlNTNcIlxuaW1wb3J0IHsgQ2xvdWRGcm9udFRhcmdldCB9IGZyb20gXCJhd3MtY2RrLWxpYi9hd3Mtcm91dGU1My10YXJnZXRzXCJcbmltcG9ydCB7IEJsb2NrUHVibGljQWNjZXNzLCBCdWNrZXQgfSBmcm9tIFwiYXdzLWNkay1saWIvYXdzLXMzXCJcbmltcG9ydCB7IEJ1Y2tldERlcGxveW1lbnQsIFNvdXJjZSB9IGZyb20gXCJhd3MtY2RrLWxpYi9hd3MtczMtZGVwbG95bWVudFwiXG5pbXBvcnQgeyBRdWV1ZSB9IGZyb20gXCJhd3MtY2RrLWxpYi9hd3Mtc3FzXCJcbmltcG9ydCB7XG4gIEFubm90YXRpb25zLFxuICBDdXN0b21SZXNvdXJjZSxcbiAgRHVyYXRpb24sXG4gIEZuLFxuICBSZW1vdmFsUG9saWN5LFxuICBTdGFjayxcbn0gZnJvbSBcImF3cy1jZGstbGliL2NvcmVcIlxuaW1wb3J0IHsgUHJvdmlkZXIgfSBmcm9tIFwiYXdzLWNkay1saWIvY3VzdG9tLXJlc291cmNlc1wiXG5pbXBvcnQgeyBDb25zdHJ1Y3QgfSBmcm9tIFwiY29uc3RydWN0c1wiXG5cbnR5cGUgQmFzZUZ1bmN0aW9uID0ge1xuICBoYW5kbGVyOiBzdHJpbmdcbiAgYnVuZGxlOiBzdHJpbmdcbn1cblxudHlwZSBPcGVuTmV4dEZ1bmN0aW9uT3JpZ2luID0ge1xuICB0eXBlOiBcImZ1bmN0aW9uXCJcbiAgc3RyZWFtaW5nPzogYm9vbGVhblxufSAmIEJhc2VGdW5jdGlvblxuXG50eXBlIE9wZW5OZXh0UzNPcmlnaW4gPSB7XG4gIHR5cGU6IFwiczNcIlxuICBvcmlnaW5QYXRoOiBzdHJpbmdcbiAgY29weToge1xuICAgIGZyb206IHN0cmluZ1xuICAgIHRvOiBzdHJpbmdcbiAgICBjYWNoZWQ6IGJvb2xlYW5cbiAgICB2ZXJzaW9uZWRTdWJEaXI/OiBzdHJpbmdcbiAgfVtdXG59XG5cbnR5cGUgT3Blbk5leHRPcmlnaW5zID0gT3Blbk5leHRGdW5jdGlvbk9yaWdpbiB8IE9wZW5OZXh0UzNPcmlnaW5cblxuaW50ZXJmYWNlIE9wZW5OZXh0T3V0cHV0IHtcbiAgZWRnZUZ1bmN0aW9uczoge1xuICAgIFtrZXk6IHN0cmluZ106IEJhc2VGdW5jdGlvblxuICB9XG4gIG9yaWdpbnM6IHtcbiAgICBzMzogT3Blbk5leHRTM09yaWdpblxuICAgIGRlZmF1bHQ6IE9wZW5OZXh0RnVuY3Rpb25PcmlnaW5cbiAgICBpbWFnZU9wdGltaXplcjogT3Blbk5leHRGdW5jdGlvbk9yaWdpblxuICAgIFtrZXk6IHN0cmluZ106IE9wZW5OZXh0T3JpZ2luc1xuICB9XG4gIGJlaGF2aW9yczoge1xuICAgIHBhdHRlcm46IHN0cmluZ1xuICAgIG9yaWdpbj86IHN0cmluZ1xuICAgIGVkZ2VGdW5jdGlvbj86IHN0cmluZ1xuICB9W11cbiAgYWRkaXRpb25hbFByb3BzPzoge1xuICAgIGRpc2FibGVJbmNyZW1lbnRhbENhY2hlPzogYm9vbGVhblxuICAgIGRpc2FibGVUYWdDYWNoZT86IGJvb2xlYW5cbiAgICBpbml0aWFsaXphdGlvbkZ1bmN0aW9uPzogQmFzZUZ1bmN0aW9uXG4gICAgd2FybWVyPzogQmFzZUZ1bmN0aW9uXG4gICAgcmV2YWxpZGF0aW9uRnVuY3Rpb24/OiBCYXNlRnVuY3Rpb25cbiAgfVxufVxuXG4vKipcbiAqIFByb3BzIGZvciBMYW1iZGEgZnVuY3Rpb25zLCBleGNsdWRpbmcgaGFuZGxlciBhbmQgY29kZSB3aGljaCBhcmUgc2V0IGJ5IHRoZSBjb25zdHJ1Y3QuXG4gKiBFeHRlbmRzIEZ1bmN0aW9uT3B0aW9ucyBhbmQgYWRkcyBydW50aW1lLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIERlZmF1bHRGdW5jdGlvblByb3BzIGV4dGVuZHMgRnVuY3Rpb25PcHRpb25zIHtcbiAgLyoqXG4gICAqIFRoZSBydW50aW1lIGVudmlyb25tZW50IGZvciB0aGUgTGFtYmRhIGZ1bmN0aW9uLlxuICAgKlxuICAgKiBAZGVmYXVsdCBSdW50aW1lLk5PREVKU18yNF9YXG4gICAqL1xuICByZWFkb25seSBydW50aW1lPzogUnVudGltZVxufVxuXG5leHBvcnQgaW50ZXJmYWNlIERpc3RyaWJ1dGlvbkRvbWFpblByb3BzIHtcbiAgLyoqXG4gICAqIFRoZSBkb21haW4gdG8gYmUgYXNzaWduZWQgdG8gdGhlIHdlYnNpdGUgVVJMIChpZS4gZG9tYWluLmNvbSkuXG4gICAqXG4gICAqIFN1cHBvcnRzIGRvbWFpbnMgdGhhdCBhcmUgaG9zdGVkIGVpdGhlciBvbiBbUm91dGUgNTNdKGh0dHBzOi8vYXdzLmFtYXpvbi5jb20vcm91dGU1My8pIG9yIGV4dGVybmFsbHkuXG4gICAqL1xuICByZWFkb25seSBkb21haW5OYW1lOiBzdHJpbmdcblxuICAvKipcbiAgICogSW1wb3J0IHRoZSB1bmRlcmx5aW5nIFJvdXRlIDUzIGhvc3RlZCB6b25lLlxuICAgKlxuICAgKiBSZXF1aXJlZCBpZiBgY2VydGlmaWNhdGVgIGlzIG5vdCBwcm92aWRlZC4gV2hlbiBwcm92aWRlZCwgYSBETlMtdmFsaWRhdGVkXG4gICAqIGNlcnRpZmljYXRlIHdpbGwgYmUgY3JlYXRlZCBhdXRvbWF0aWNhbGx5IGFuZCBETlMgYWxpYXNlcyB3aWxsIGJlIHNldCB1cC5cbiAgICovXG4gIHJlYWRvbmx5IGhvc3RlZFpvbmU/OiBJSG9zdGVkWm9uZVxuXG4gIC8qKlxuICAgKiBUaGUgQUNNIGNlcnRpZmljYXRlIHRvIHVzZSBmb3IgdGhlIGN1c3RvbSBkb21haW4uXG4gICAqXG4gICAqIFJlcXVpcmVkIGlmIGBob3N0ZWRab25lYCBpcyBub3QgcHJvdmlkZWQuIFRoZSBjZXJ0aWZpY2F0ZSBtdXN0IGJlIGluXG4gICAqIHVzLWVhc3QtMSBmb3IgQ2xvdWRGcm9udCBkaXN0cmlidXRpb25zLlxuICAgKlxuICAgKiBXaGVuIHByb3ZpZGVkIHdpdGhvdXQgYGhvc3RlZFpvbmVgLCBubyBETlMgYWxpYXNlcyB3aWxsIGJlIGNyZWF0ZWRcbiAgICogYW5kIHlvdSBtdXN0IGNvbmZpZ3VyZSBETlMgcmVjb3JkcyBleHRlcm5hbGx5LlxuICAgKi9cbiAgcmVhZG9ubHkgY2VydGlmaWNhdGU/OiBJQ2VydGlmaWNhdGVcbn1cblxuZXhwb3J0IGludGVyZmFjZSBOZXh0anNTaXRlUHJvcHMge1xuICAvKipcbiAgICogVGhlIGN1c3RvbURvbWFpbiBmb3IgdGhpcyB3ZWJzaXRlLiBUaGlzIGRvbWFpbiBtdXN0IGJlIGhvc3RlZCBpblxuICAgKiByb3V0ZTUzLCBhbmQgd2UgbXVzdCBiZSBhYmxlIHRvIGNyZWF0ZSBhbiBBQ00gY2VydGlmaWNhdGUgZm9yIHRoaXNcbiAgICogZG9tYWluLlxuICAgKlxuICAgKiBOb3RlIHRoYXQgeW91IGNhbiBhbHNvIG1pZ3JhdGUgZXh0ZXJuYWxseSBob3N0ZWQgZG9tYWlucyB0byBSb3V0ZSA1MyBieVxuICAgKiBbZm9sbG93aW5nIHRoaXMgZ3VpZGVdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9Sb3V0ZTUzL2xhdGVzdC9EZXZlbG9wZXJHdWlkZS9NaWdyYXRpbmdETlMuaHRtbCkuXG4gICAqL1xuICByZWFkb25seSBjdXN0b21Eb21haW4/OiBEaXN0cmlidXRpb25Eb21haW5Qcm9wc1xuXG4gIC8qKlxuICAgKiBTaG91bGQgcG9pbnQgdG8gdGhlIC5vcGVuLW5leHQgZGlyZWN0b3J5LlxuICAgKlxuICAgKiBAZGVmYXVsdCBcIi5vcGVuLW5leHRcIlxuICAgKi9cbiAgcmVhZG9ubHkgb3Blbk5leHRQYXRoPzogc3RyaW5nIHwgdW5kZWZpbmVkXG5cbiAgLyoqXG4gICAqIERlZmF1bHQgcHJvcHMgdG8gYXBwbHkgdG8gYWxsIExhbWJkYSBmdW5jdGlvbnMgY3JlYXRlZCBieSB0aGlzIGNvbnN0cnVjdC5cbiAgICogVGhlc2UgY2FuIGJlIG92ZXJyaWRkZW4gYnkgc3BlY2lmaWMgZnVuY3Rpb24gY29uZmlndXJhdGlvbnMuXG4gICAqL1xuICByZWFkb25seSBkZWZhdWx0RnVuY3Rpb25Qcm9wcz86IERlZmF1bHRGdW5jdGlvblByb3BzXG5cbiAgLyoqXG4gICAqIFRoZSBudW1iZXIgb2Ygc2VydmVyIGluc3RhbmNlcyB0byBrZWVwIHdhcm0uIFNldCB0byBmYWxzZSB0byBkaXNhYmxlIHdhcm1pbmcuXG4gICAqIE11c3QgYmUgYSBwb3NpdGl2ZSBpbnRlZ2VyICg+PSAxKSBpZiBzcGVjaWZpZWQuIFZhbHVlcyA8PSAwIHdpbGwgZGlzYWJsZSB3YXJtaW5nLlxuICAgKlxuICAgKiBAZGVmYXVsdCAxXG4gICAqIEBleGFtcGxlXG4gICAqIHdhcm06IDUgLy8gS2VlcCA1IGNvbmN1cnJlbnQgaW5zdGFuY2VzIHdhcm1cbiAgICogd2FybTogZmFsc2UgLy8gRGlzYWJsZSB3YXJtaW5nXG4gICAqL1xuICByZWFkb25seSB3YXJtPzogbnVtYmVyIHwgZmFsc2VcblxuICAvKipcbiAgICogSG93IG9mdGVuIHRvIGludm9rZSB0aGUgd2FybWVyIGZ1bmN0aW9uLlxuICAgKlxuICAgKiBAZGVmYXVsdCBEdXJhdGlvbi5taW51dGVzKDUpXG4gICAqIEBleGFtcGxlXG4gICAqIHdhcm1lckludGVydmFsOiBEdXJhdGlvbi5taW51dGVzKDEwKVxuICAgKi9cbiAgcmVhZG9ubHkgd2FybWVySW50ZXJ2YWw/OiBEdXJhdGlvblxuXG4gIC8qKlxuICAgKiBXaGV0aGVyIHRvIGludm9rZSB0aGUgd2FybWVyIGZ1bmN0aW9uIGltbWVkaWF0ZWx5IGFmdGVyIGRlcGxveW1lbnQuXG4gICAqXG4gICAqIEBkZWZhdWx0IHRydWVcbiAgICogQGV4YW1wbGVcbiAgICogcHJld2FybU9uRGVwbG95OiBmYWxzZVxuICAgKi9cbiAgcmVhZG9ubHkgcHJld2FybU9uRGVwbG95PzogYm9vbGVhblxufVxuXG5leHBvcnQgY2xhc3MgTmV4dGpzU2l0ZSBleHRlbmRzIENvbnN0cnVjdCB7XG4gIHByaXZhdGUgb3Blbk5leHRPdXRwdXQ6IE9wZW5OZXh0T3V0cHV0XG4gIHByaXZhdGUgYnVja2V0OiBCdWNrZXRcbiAgcHJpdmF0ZSB0YWJsZTogVGFibGVcbiAgcHJpdmF0ZSBxdWV1ZTogUXVldWVcblxuICBwcml2YXRlIHN0YXRpY0NhY2hlUG9saWN5OiBJQ2FjaGVQb2xpY3lcbiAgcHJpdmF0ZSBzZXJ2ZXJDYWNoZVBvbGljeTogQ2FjaGVQb2xpY3lcblxuICBwcml2YXRlIG9wZW5OZXh0UGF0aDogc3RyaW5nXG5cbiAgcHVibGljIHJlYWRvbmx5IGRpc3RyaWJ1dGlvbjogRGlzdHJpYnV0aW9uXG4gIHByaXZhdGUgX2RlZmF1bHRTZXJ2ZXJGdW5jdGlvbiE6IENka0Z1bmN0aW9uXG4gIHByaXZhdGUgX2N1c3RvbURvbWFpbk5hbWU/OiBzdHJpbmdcbiAgcHJpdmF0ZSB3YXJtZXJGdW5jdGlvbj86IENka0Z1bmN0aW9uXG4gIHByaXZhdGUgcHJvcHM6IE5leHRqc1NpdGVQcm9wc1xuXG4gIHB1YmxpYyBnZXQgZGVmYXVsdFNlcnZlckZ1bmN0aW9uKCk6IENka0Z1bmN0aW9uIHtcbiAgICByZXR1cm4gdGhpcy5fZGVmYXVsdFNlcnZlckZ1bmN0aW9uXG4gIH1cblxuICBwdWJsaWMgZ2V0IHVybCgpOiBzdHJpbmcge1xuICAgIHJldHVybiBgaHR0cHM6Ly8ke3RoaXMuZGlzdHJpYnV0aW9uLmRpc3RyaWJ1dGlvbkRvbWFpbk5hbWV9YFxuICB9XG5cbiAgcHVibGljIGdldCBjdXN0b21Eb21haW5VcmwoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gdGhpcy5fY3VzdG9tRG9tYWluTmFtZVxuICAgICAgPyBgaHR0cHM6Ly8ke3RoaXMuX2N1c3RvbURvbWFpbk5hbWV9YFxuICAgICAgOiBgaHR0cHM6Ly8ke3RoaXMuZGlzdHJpYnV0aW9uLmRpc3RyaWJ1dGlvbkRvbWFpbk5hbWV9YFxuICB9XG5cbiAgY29uc3RydWN0b3Ioc2NvcGU6IENvbnN0cnVjdCwgaWQ6IHN0cmluZywgcHJvcHM6IE5leHRqc1NpdGVQcm9wcykge1xuICAgIHN1cGVyKHNjb3BlLCBpZClcbiAgICB0aGlzLnByb3BzID0gcHJvcHNcbiAgICB0aGlzLm9wZW5OZXh0UGF0aCA9IHByb3BzLm9wZW5OZXh0UGF0aCA/PyBcIi5vcGVuLW5leHRcIlxuICAgIHRoaXMub3Blbk5leHRPdXRwdXQgPSBKU09OLnBhcnNlKFxuICAgICAgcmVhZEZpbGVTeW5jKHBhdGguam9pbih0aGlzLm9wZW5OZXh0UGF0aCwgXCJvcGVuLW5leHQub3V0cHV0Lmpzb25cIiksIFwidXRmLThcIilcbiAgICApIGFzIE9wZW5OZXh0T3V0cHV0XG5cbiAgICB0aGlzLl9jdXN0b21Eb21haW5OYW1lID0gcHJvcHMuY3VzdG9tRG9tYWluPy5kb21haW5OYW1lXG5cbiAgICAvLyBWYWxpZGF0ZSBjdXN0b21Eb21haW4gcHJvcHM6IGVpdGhlciBjZXJ0aWZpY2F0ZSBvciBob3N0ZWRab25lIG11c3QgYmUgcHJvdmlkZWRcbiAgICBpZiAoXG4gICAgICBwcm9wcy5jdXN0b21Eb21haW4gJiZcbiAgICAgICFwcm9wcy5jdXN0b21Eb21haW4uY2VydGlmaWNhdGUgJiZcbiAgICAgICFwcm9wcy5jdXN0b21Eb21haW4uaG9zdGVkWm9uZVxuICAgICkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICBcImN1c3RvbURvbWFpbiByZXF1aXJlcyBlaXRoZXIgYSBjZXJ0aWZpY2F0ZSBvciBhIGhvc3RlZFpvbmUuIFwiICtcbiAgICAgICAgICBcIlByb3ZpZGUgYSBob3N0ZWRab25lIHRvIGF1dG9tYXRpY2FsbHkgY3JlYXRlIGEgRE5TLXZhbGlkYXRlZCBjZXJ0aWZpY2F0ZSwgXCIgK1xuICAgICAgICAgIFwib3IgcHJvdmlkZSB5b3VyIG93biBjZXJ0aWZpY2F0ZS5cIlxuICAgICAgKVxuICAgIH1cblxuICAgIHRoaXMuYnVja2V0ID0gbmV3IEJ1Y2tldCh0aGlzLCBcIlMzQnVja2V0XCIsIHtcbiAgICAgIHB1YmxpY1JlYWRBY2Nlc3M6IGZhbHNlLFxuICAgICAgYmxvY2tQdWJsaWNBY2Nlc3M6IEJsb2NrUHVibGljQWNjZXNzLkJMT0NLX0FMTCxcbiAgICAgIGF1dG9EZWxldGVPYmplY3RzOiB0cnVlLFxuICAgICAgcmVtb3ZhbFBvbGljeTogUmVtb3ZhbFBvbGljeS5ERVNUUk9ZLFxuICAgICAgZW5mb3JjZVNTTDogdHJ1ZSxcbiAgICB9KVxuICAgIHRoaXMudGFibGUgPSB0aGlzLmNyZWF0ZVJldmFsaWRhdGlvblRhYmxlKClcbiAgICB0aGlzLnF1ZXVlID0gdGhpcy5jcmVhdGVSZXZhbGlkYXRpb25RdWV1ZSgpXG5cbiAgICAvLyBVc2UgcHJvdmlkZWQgY2VydGlmaWNhdGUgb3IgY3JlYXRlIG9uZSBpZiBob3N0ZWRab25lIGlzIGF2YWlsYWJsZVxuICAgIGNvbnN0IGNlcnRpZmljYXRlID1cbiAgICAgIHByb3BzLmN1c3RvbURvbWFpbj8uY2VydGlmaWNhdGUgPz9cbiAgICAgIChwcm9wcy5jdXN0b21Eb21haW4/Lmhvc3RlZFpvbmVcbiAgICAgICAgPyB0aGlzLmNyZWF0ZUNlcnRpZmljYXRlKFxuICAgICAgICAgICAgcHJvcHMuY3VzdG9tRG9tYWluLmRvbWFpbk5hbWUsXG4gICAgICAgICAgICBwcm9wcy5jdXN0b21Eb21haW4uaG9zdGVkWm9uZVxuICAgICAgICAgIClcbiAgICAgICAgOiB1bmRlZmluZWQpXG5cbiAgICBjb25zdCBvcmlnaW5zID0gdGhpcy5jcmVhdGVPcmlnaW5zKHByb3BzLmRlZmF1bHRGdW5jdGlvblByb3BzKVxuICAgIHRoaXMuc2VydmVyQ2FjaGVQb2xpY3kgPSB0aGlzLmNyZWF0ZVNlcnZlckNhY2hlUG9saWN5KClcbiAgICB0aGlzLnN0YXRpY0NhY2hlUG9saWN5ID0gdGhpcy5jcmVhdGVTdGF0aWNDYWNoZVBvbGljeSgpXG4gICAgdGhpcy5kaXN0cmlidXRpb24gPSB0aGlzLmNyZWF0ZURpc3RyaWJ1dGlvbihvcmlnaW5zLCBwcm9wcywgY2VydGlmaWNhdGUpXG4gICAgdGhpcy5jcmVhdGVXYXJtZXIoKVxuICAgIGlmIChwcm9wcy5jdXN0b21Eb21haW4gJiYgcHJvcHMuY3VzdG9tRG9tYWluLmhvc3RlZFpvbmUpIHtcbiAgICAgIG5ldyBBUmVjb3JkKHRoaXMsIFwiQWxpYXNSZWNvcmRcIiwge1xuICAgICAgICB6b25lOiBwcm9wcy5jdXN0b21Eb21haW4uaG9zdGVkWm9uZSxcbiAgICAgICAgcmVjb3JkTmFtZTogcHJvcHMuY3VzdG9tRG9tYWluLmRvbWFpbk5hbWUsXG4gICAgICAgIHRhcmdldDogUmVjb3JkVGFyZ2V0LmZyb21BbGlhcyhuZXcgQ2xvdWRGcm9udFRhcmdldCh0aGlzLmRpc3RyaWJ1dGlvbikpLFxuICAgICAgfSlcblxuICAgICAgbmV3IEFhYWFSZWNvcmQodGhpcywgXCJBbGlhc1JlY29yZEFBQUFcIiwge1xuICAgICAgICB6b25lOiBwcm9wcy5jdXN0b21Eb21haW4uaG9zdGVkWm9uZSxcbiAgICAgICAgcmVjb3JkTmFtZTogcHJvcHMuY3VzdG9tRG9tYWluLmRvbWFpbk5hbWUsXG4gICAgICAgIHRhcmdldDogUmVjb3JkVGFyZ2V0LmZyb21BbGlhcyhuZXcgQ2xvdWRGcm9udFRhcmdldCh0aGlzLmRpc3RyaWJ1dGlvbikpLFxuICAgICAgfSlcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGNyZWF0ZUNlcnRpZmljYXRlKGRvbWFpbk5hbWU6IHN0cmluZywgaG9zdGVkWm9uZTogSUhvc3RlZFpvbmUpIHtcbiAgICAvLyBDbG91ZEZyb250IHJlcXVpcmVzIGNlcnRpZmljYXRlcyB0byBiZSBpbiB1cy1lYXN0LTFcbiAgICAvLyBEbnNWYWxpZGF0ZWRDZXJ0aWZpY2F0ZSBoYW5kbGVzIGNyb3NzLXJlZ2lvbiBjZXJ0aWZpY2F0ZSBjcmVhdGlvbiBhdXRvbWF0aWNhbGx5XG4gICAgcmV0dXJuIG5ldyBEbnNWYWxpZGF0ZWRDZXJ0aWZpY2F0ZSh0aGlzLCBcIkNlcnRpZmljYXRlXCIsIHtcbiAgICAgIGRvbWFpbk5hbWUsXG4gICAgICBob3N0ZWRab25lLFxuICAgICAgcmVnaW9uOiBcInVzLWVhc3QtMVwiLFxuICAgIH0pXG4gIH1cblxuICBwcml2YXRlIGNyZWF0ZVJldmFsaWRhdGlvblRhYmxlKCkge1xuICAgIGNvbnN0IHRhYmxlID0gbmV3IFRhYmxlKHRoaXMsIFwiUmV2YWxpZGF0aW9uVGFibGVcIiwge1xuICAgICAgcGFydGl0aW9uS2V5OiB7IG5hbWU6IFwidGFnXCIsIHR5cGU6IEF0dHJpYnV0ZVR5cGUuU1RSSU5HIH0sXG4gICAgICBzb3J0S2V5OiB7IG5hbWU6IFwicGF0aFwiLCB0eXBlOiBBdHRyaWJ1dGVUeXBlLlNUUklORyB9LFxuICAgICAgcG9pbnRJblRpbWVSZWNvdmVyeVNwZWNpZmljYXRpb246IHtcbiAgICAgICAgcG9pbnRJblRpbWVSZWNvdmVyeUVuYWJsZWQ6IHRydWUsXG4gICAgICB9LFxuICAgICAgYmlsbGluZzogQmlsbGluZy5vbkRlbWFuZCgpLFxuICAgICAgZ2xvYmFsU2Vjb25kYXJ5SW5kZXhlczogW1xuICAgICAgICB7XG4gICAgICAgICAgaW5kZXhOYW1lOiBcInJldmFsaWRhdGVcIixcbiAgICAgICAgICBwYXJ0aXRpb25LZXk6IHsgbmFtZTogXCJwYXRoXCIsIHR5cGU6IEF0dHJpYnV0ZVR5cGUuU1RSSU5HIH0sXG4gICAgICAgICAgc29ydEtleTogeyBuYW1lOiBcInJldmFsaWRhdGVkQXRcIiwgdHlwZTogQXR0cmlidXRlVHlwZS5OVU1CRVIgfSxcbiAgICAgICAgfSxcbiAgICAgIF0sXG4gICAgICByZW1vdmFsUG9saWN5OiBSZW1vdmFsUG9saWN5LkRFU1RST1ksXG4gICAgfSlcblxuICAgIGNvbnN0IGluaXRGbiA9IHRoaXMub3Blbk5leHRPdXRwdXQuYWRkaXRpb25hbFByb3BzPy5pbml0aWFsaXphdGlvbkZ1bmN0aW9uXG5cbiAgICBjb25zdCBpbnNlcnRGbiA9IG5ldyBDZGtGdW5jdGlvbih0aGlzLCBcIlJldmFsaWRhdGlvbkluc2VydEZ1bmN0aW9uXCIsIHtcbiAgICAgIGRlc2NyaXB0aW9uOiBcIk5leHQuanMgcmV2YWxpZGF0aW9uIGRhdGEgaW5zZXJ0XCIsXG4gICAgICBoYW5kbGVyOiBpbml0Rm4/LmhhbmRsZXIgPz8gXCJpbmRleC5oYW5kbGVyXCIsXG4gICAgICAvLyBjb2RlOiBDb2RlLmZyb21Bc3NldChpbml0Rm4/LmJ1bmRsZSA/PyBcIlwiKSxcbiAgICAgIGNvZGU6IENvZGUuZnJvbUFzc2V0KHBhdGguam9pbih0aGlzLm9wZW5OZXh0UGF0aCwgXCJkeW5hbW9kYi1wcm92aWRlclwiKSksXG4gICAgICBydW50aW1lOiBSdW50aW1lLk5PREVKU18yNF9YLFxuICAgICAgYXJjaGl0ZWN0dXJlOiBBcmNoaXRlY3R1cmUuQVJNXzY0LFxuICAgICAgdGltZW91dDogRHVyYXRpb24ubWludXRlcygxNSksXG4gICAgICBtZW1vcnlTaXplOiAxMjgsXG4gICAgICBsb2dnaW5nRm9ybWF0OiBMb2dnaW5nRm9ybWF0LkpTT04sXG4gICAgICBlbnZpcm9ubWVudDoge1xuICAgICAgICBDQUNIRV9EWU5BTU9fVEFCTEU6IHRhYmxlLnRhYmxlTmFtZSxcbiAgICAgIH0sXG4gICAgfSlcblxuICAgIGNvbnN0IHByb3ZpZGVyTG9nR3JvdXAgPSBuZXcgTG9nR3JvdXAodGhpcywgXCJSZXZhbGlkYXRpb25Qcm92aWRlckxvZ0dyb3VwXCIsIHtcbiAgICAgIHJldGVudGlvbjogUmV0ZW50aW9uRGF5cy5PTkVfREFZLFxuICAgICAgcmVtb3ZhbFBvbGljeTogUmVtb3ZhbFBvbGljeS5ERVNUUk9ZLFxuICAgIH0pXG5cbiAgICBjb25zdCBwcm92aWRlciA9IG5ldyBQcm92aWRlcih0aGlzLCBcIlJldmFsaWRhdGlvblByb3ZpZGVyXCIsIHtcbiAgICAgIG9uRXZlbnRIYW5kbGVyOiBpbnNlcnRGbixcbiAgICAgIGxvZ0dyb3VwOiBwcm92aWRlckxvZ0dyb3VwLFxuICAgIH0pXG5cbiAgICBuZXcgQ3VzdG9tUmVzb3VyY2UodGhpcywgXCJSZXZhbGlkYXRpb25SZXNvdXJjZVwiLCB7XG4gICAgICBzZXJ2aWNlVG9rZW46IHByb3ZpZGVyLnNlcnZpY2VUb2tlbixcbiAgICAgIHByb3BlcnRpZXM6IHtcbiAgICAgICAgdmVyc2lvbjogRGF0ZS5ub3coKS50b1N0cmluZygpLFxuICAgICAgfSxcbiAgICB9KVxuXG4gICAgcmV0dXJuIHRhYmxlXG4gIH1cblxuICBwcml2YXRlIGNyZWF0ZU9yaWdpbnMoZGVmYXVsdEZ1bmN0aW9uUHJvcHM/OiBEZWZhdWx0RnVuY3Rpb25Qcm9wcykge1xuICAgIGNvbnN0IHtcbiAgICAgIHMzOiBzM09yaWdpbixcbiAgICAgIGRlZmF1bHQ6IGRlZmF1bHRPcmlnaW4sXG4gICAgICBpbWFnZU9wdGltaXplcjogaW1hZ2VPcmlnaW4sXG4gICAgICAuLi5yZXN0T3JpZ2luc1xuICAgIH0gPSB0aGlzLm9wZW5OZXh0T3V0cHV0Lm9yaWdpbnNcbiAgICBmb3IgKGNvbnN0IGNvcHkgb2YgczNPcmlnaW4uY29weSkge1xuICAgICAgbmV3IEJ1Y2tldERlcGxveW1lbnQodGhpcywgYE9wZW5OZXh0QnVja2V0RGVwbG95bWVudCR7Y29weS5mcm9tfWAsIHtcbiAgICAgICAgc291cmNlczogW1NvdXJjZS5hc3NldChwYXRoLmpvaW4odGhpcy5vcGVuTmV4dFBhdGgsIFwiLi5cIiwgY29weS5mcm9tKSldLFxuICAgICAgICBkZXN0aW5hdGlvbkJ1Y2tldDogdGhpcy5idWNrZXQsXG4gICAgICAgIGRlc3RpbmF0aW9uS2V5UHJlZml4OiBjb3B5LnRvLFxuICAgICAgICBwcnVuZTogZmFsc2UsXG4gICAgICB9KVxuICAgIH1cbiAgICBjb25zdCBvcmlnaW5zID0ge1xuICAgICAgczM6IFMzQnVja2V0T3JpZ2luLndpdGhPcmlnaW5BY2Nlc3NDb250cm9sKHRoaXMuYnVja2V0LCB7XG4gICAgICAgIG9yaWdpbklkOiBcIlMzQnVja2V0XCIsXG4gICAgICAgIG9yaWdpblBhdGg6IHMzT3JpZ2luLm9yaWdpblBhdGgsXG4gICAgICB9KSxcbiAgICAgIGRlZmF1bHQ6IHRoaXMuY3JlYXRlRnVuY3Rpb25PcmlnaW4oXG4gICAgICAgIFwiZGVmYXVsdFwiLFxuICAgICAgICBkZWZhdWx0T3JpZ2luLFxuICAgICAgICBcIk5leHRKc1NlcnZlclwiLFxuICAgICAgICBkZWZhdWx0RnVuY3Rpb25Qcm9wc1xuICAgICAgKSxcbiAgICAgIGltYWdlT3B0aW1pemVyOiB0aGlzLmNyZWF0ZUltYWdlT3B0aW1pemVyT3JpZ2luKGltYWdlT3JpZ2luKSxcbiAgICAgIC4uLk9iamVjdC5lbnRyaWVzKHJlc3RPcmlnaW5zKS5yZWR1Y2UoXG4gICAgICAgIChhY2MsIFtrZXksIHZhbHVlXSkgPT4ge1xuICAgICAgICAgIGNvbnN0IG9yaWdpbklkID0ga2V5LmNoYXJBdCgwKS50b1VwcGVyQ2FzZSgpICsga2V5LnNsaWNlKDEpXG4gICAgICAgICAgaWYgKHZhbHVlLnR5cGUgPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAgICAgYWNjW2tleV0gPSB0aGlzLmNyZWF0ZUZ1bmN0aW9uT3JpZ2luKGtleSwgdmFsdWUsIG9yaWdpbklkKVxuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gYWNjXG4gICAgICAgIH0sXG4gICAgICAgIHt9IGFzIFJlY29yZDxzdHJpbmcsIEh0dHBPcmlnaW4+XG4gICAgICApLFxuICAgIH1cbiAgICByZXR1cm4gb3JpZ2luc1xuICB9XG5cbiAgcHJpdmF0ZSBjcmVhdGVSZXZhbGlkYXRpb25RdWV1ZSgpIHtcbiAgICBjb25zdCBxdWV1ZSA9IG5ldyBRdWV1ZSh0aGlzLCBcIlJldmFsaWRhdGlvblF1ZXVlXCIsIHtcbiAgICAgIGZpZm86IHRydWUsXG4gICAgICByZWNlaXZlTWVzc2FnZVdhaXRUaW1lOiBEdXJhdGlvbi5zZWNvbmRzKDIwKSxcbiAgICB9KVxuICAgIGNvbnN0IGNvbnN1bWVyID0gbmV3IENka0Z1bmN0aW9uKHRoaXMsIFwiUmV2YWxpZGF0aW9uRnVuY3Rpb25cIiwge1xuICAgICAgZGVzY3JpcHRpb246IFwiTmV4dC5qcyByZXZhbGlkYXRvclwiLFxuICAgICAgaGFuZGxlcjogXCJpbmRleC5oYW5kbGVyXCIsXG4gICAgICBjb2RlOiBDb2RlLmZyb21Bc3NldChcbiAgICAgICAgdGhpcy5vcGVuTmV4dE91dHB1dC5hZGRpdGlvbmFsUHJvcHM/LnJldmFsaWRhdGlvbkZ1bmN0aW9uPy5idW5kbGVcbiAgICAgICAgICA/IHBhdGguam9pbihcbiAgICAgICAgICAgICAgdGhpcy5vcGVuTmV4dFBhdGgsXG4gICAgICAgICAgICAgIFwiLi5cIixcbiAgICAgICAgICAgICAgdGhpcy5vcGVuTmV4dE91dHB1dC5hZGRpdGlvbmFsUHJvcHM/LnJldmFsaWRhdGlvbkZ1bmN0aW9uPy5idW5kbGVcbiAgICAgICAgICAgIClcbiAgICAgICAgICA6IFwiXCJcbiAgICAgICksXG4gICAgICBydW50aW1lOiBSdW50aW1lLk5PREVKU18yNF9YLFxuICAgICAgYXJjaGl0ZWN0dXJlOiBBcmNoaXRlY3R1cmUuQVJNXzY0LFxuICAgICAgdGltZW91dDogRHVyYXRpb24uc2Vjb25kcygzMCksXG4gICAgICBsb2dnaW5nRm9ybWF0OiBMb2dnaW5nRm9ybWF0LkpTT04sXG4gICAgfSlcbiAgICBjb25zdW1lci5hZGRFdmVudFNvdXJjZShuZXcgU3FzRXZlbnRTb3VyY2UocXVldWUsIHsgYmF0Y2hTaXplOiA1IH0pKVxuICAgIHJldHVybiBxdWV1ZVxuICB9XG5cbiAgcHJpdmF0ZSBjcmVhdGVXYXJtZXIoKSB7XG4gICAgLy8gRGVmYXVsdDogd2FybTogMSwgdXNlcnMgY2FuIGRpc2FibGUgd2l0aCB3YXJtOiBmYWxzZVxuICAgIGNvbnN0IHdhcm1Db25jdXJyZW5jeSA9IHRoaXMucHJvcHMud2FybSA9PT0gZmFsc2UgPyB1bmRlZmluZWQgOiAodGhpcy5wcm9wcy53YXJtID8/IDEpXG5cbiAgICAvLyBTa2lwIGlmIHdhcm1pbmcgaXMgZGlzYWJsZWQgb3IgaW52YWxpZFxuICAgIGlmICghd2FybUNvbmN1cnJlbmN5IHx8IHdhcm1Db25jdXJyZW5jeSA8PSAwKSByZXR1cm5cblxuICAgIC8vIEdldCB3YXJtZXIgYnVuZGxlIGZyb20gT3Blbk5leHRcbiAgICBjb25zdCB3YXJtZXIgPSB0aGlzLm9wZW5OZXh0T3V0cHV0LmFkZGl0aW9uYWxQcm9wcz8ud2FybWVyXG4gICAgaWYgKCF3YXJtZXIpIHtcbiAgICAgIEFubm90YXRpb25zLm9mKHRoaXMpLmFkZFdhcm5pbmcoXG4gICAgICAgIFwiV2FybWluZyBpcyBlbmFibGVkIGJ1dCBPcGVuTmV4dCBkaWQgbm90IHByb3ZpZGUgYSB3YXJtZXIgYnVuZGxlLiBcIiArXG4gICAgICAgICAgXCJTa2lwcGluZyB3YXJtZXIgY3JlYXRpb24uIEVuc3VyZSB5b3UncmUgdXNpbmcgT3Blbk5leHQgMy54KyB3aXRoIHdhcm1pbmcgc3VwcG9ydC5cIlxuICAgICAgKVxuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgY29uc3Qgd2FybWVyQnVuZGxlID0gcGF0aC5qb2luKHRoaXMub3Blbk5leHRQYXRoLCBcIi4uXCIsIHdhcm1lci5idW5kbGUpXG4gICAgY29uc3Qgd2FybWVySGFuZGxlciA9IHdhcm1lci5oYW5kbGVyXG5cbiAgICAvLyBDb25maWd1cmUgV0FSTV9QQVJBTVNcbiAgICBjb25zdCB3YXJtUGFyYW1zID0gW1xuICAgICAge1xuICAgICAgICBjb25jdXJyZW5jeTogd2FybUNvbmN1cnJlbmN5LFxuICAgICAgICBmdW5jdGlvbjogdGhpcy5fZGVmYXVsdFNlcnZlckZ1bmN0aW9uLmZ1bmN0aW9uTmFtZSxcbiAgICAgIH0sXG4gICAgXVxuXG4gICAgLy8gQ3JlYXRlIHdhcm1lciBMYW1iZGFcbiAgICB0aGlzLndhcm1lckZ1bmN0aW9uID0gbmV3IENka0Z1bmN0aW9uKHRoaXMsIFwiV2FybWVyRnVuY3Rpb25cIiwge1xuICAgICAgZGVzY3JpcHRpb246IFwiTmV4dC5qcyB3YXJtZXJcIixcbiAgICAgIGhhbmRsZXI6IHdhcm1lckhhbmRsZXIsXG4gICAgICBjb2RlOiBDb2RlLmZyb21Bc3NldCh3YXJtZXJCdW5kbGUpLFxuICAgICAgcnVudGltZTogUnVudGltZS5OT0RFSlNfMjRfWCxcbiAgICAgIGFyY2hpdGVjdHVyZTogQXJjaGl0ZWN0dXJlLkFSTV82NCxcbiAgICAgIHRpbWVvdXQ6IER1cmF0aW9uLm1pbnV0ZXMoMSksXG4gICAgICBtZW1vcnlTaXplOiAxMjgsXG4gICAgICBsb2dnaW5nRm9ybWF0OiBMb2dnaW5nRm9ybWF0LkpTT04sXG4gICAgICBlbnZpcm9ubWVudDoge1xuICAgICAgICBXQVJNX1BBUkFNUzogSlNPTi5zdHJpbmdpZnkod2FybVBhcmFtcyksXG4gICAgICB9LFxuICAgIH0pXG5cbiAgICAvLyBHcmFudCBpbnZva2UgcGVybWlzc2lvbnNcbiAgICB0aGlzLl9kZWZhdWx0U2VydmVyRnVuY3Rpb24uZ3JhbnRJbnZva2UodGhpcy53YXJtZXJGdW5jdGlvbilcbiAgICB0aGlzLl9kZWZhdWx0U2VydmVyRnVuY3Rpb24uYWRkRW52aXJvbm1lbnQoXCJXQVJNRVJfRU5BQkxFRFwiLCBcInRydWVcIilcblxuICAgIC8vIENyZWF0ZSBFdmVudEJyaWRnZSBydWxlXG4gICAgY29uc3QgaW50ZXJ2YWwgPSB0aGlzLnByb3BzLndhcm1lckludGVydmFsID8/IER1cmF0aW9uLm1pbnV0ZXMoNSlcbiAgICBuZXcgUnVsZSh0aGlzLCBcIldhcm1lclJ1bGVcIiwge1xuICAgICAgZGVzY3JpcHRpb246IGBJbnZva2Ugd2FybWVyIGV2ZXJ5ICR7aW50ZXJ2YWwudG9NaW51dGVzKCl9IG1pbnV0ZXNgLFxuICAgICAgc2NoZWR1bGU6IFNjaGVkdWxlLnJhdGUoaW50ZXJ2YWwpLFxuICAgICAgdGFyZ2V0czogW25ldyBMYW1iZGFGdW5jdGlvbih0aGlzLndhcm1lckZ1bmN0aW9uLCB7IHJldHJ5QXR0ZW1wdHM6IDAgfSldLFxuICAgIH0pXG5cbiAgICAvLyBDcmVhdGUgcHJlLXdhcm1lciBpZiBlbmFibGVkIChkZWZhdWx0OiB0cnVlKVxuICAgIGlmICh0aGlzLnByb3BzLnByZXdhcm1PbkRlcGxveSAhPT0gZmFsc2UpIHtcbiAgICAgIGNvbnN0IHByZXdhcm1lckxvZ0dyb3VwID0gbmV3IExvZ0dyb3VwKHRoaXMsIFwiUHJld2FybWVyTG9nR3JvdXBcIiwge1xuICAgICAgICByZXRlbnRpb246IFJldGVudGlvbkRheXMuT05FX0RBWSxcbiAgICAgICAgcmVtb3ZhbFBvbGljeTogUmVtb3ZhbFBvbGljeS5ERVNUUk9ZLFxuICAgICAgfSlcblxuICAgICAgY29uc3QgcHJld2FybWVyRm4gPSBuZXcgQ2RrRnVuY3Rpb24odGhpcywgXCJQcmV3YXJtZXJGdW5jdGlvblwiLCB7XG4gICAgICAgIGRlc2NyaXB0aW9uOiBcIk5leHQuanMgcHJlLXdhcm1lclwiLFxuICAgICAgICBoYW5kbGVyOiBcImluZGV4LmhhbmRsZXJcIixcbiAgICAgICAgY29kZTogQ29kZS5mcm9tSW5saW5lKGBcbiAgICAgICAgICBjb25zdCB7IExhbWJkYUNsaWVudCwgSW52b2tlQ29tbWFuZCB9ID0gcmVxdWlyZShcIkBhd3Mtc2RrL2NsaWVudC1sYW1iZGFcIilcbiAgICAgICAgICBjb25zdCBsYW1iZGEgPSBuZXcgTGFtYmRhQ2xpZW50KHt9KVxuXG4gICAgICAgICAgZXhwb3J0cy5oYW5kbGVyID0gYXN5bmMgKGV2ZW50KSA9PiB7XG4gICAgICAgICAgICBpZiAoZXZlbnQuUmVxdWVzdFR5cGUgPT09IFwiRGVsZXRlXCIpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIHsgUGh5c2ljYWxSZXNvdXJjZUlkOiBcInByZXdhcm1lclwiIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgYXdhaXQgbGFtYmRhLnNlbmQoXG4gICAgICAgICAgICAgICAgbmV3IEludm9rZUNvbW1hbmQoe1xuICAgICAgICAgICAgICAgICAgRnVuY3Rpb25OYW1lOiBldmVudC5SZXNvdXJjZVByb3BlcnRpZXMuRnVuY3Rpb25OYW1lLFxuICAgICAgICAgICAgICAgICAgSW52b2NhdGlvblR5cGU6IFwiUmVxdWVzdFJlc3BvbnNlXCIsXG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihcIlByZS13YXJtaW5nIGZhaWxlZDpcIiwgZXJyb3IpXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiB7IFBoeXNpY2FsUmVzb3VyY2VJZDogXCJwcmV3YXJtZXJcIiB9XG4gICAgICAgICAgfVxuICAgICAgICBgKSxcbiAgICAgICAgcnVudGltZTogUnVudGltZS5OT0RFSlNfMjRfWCxcbiAgICAgICAgYXJjaGl0ZWN0dXJlOiBBcmNoaXRlY3R1cmUuQVJNXzY0LFxuICAgICAgICB0aW1lb3V0OiBEdXJhdGlvbi5taW51dGVzKDIpLFxuICAgICAgICBtZW1vcnlTaXplOiAxMjgsXG4gICAgICAgIGxvZ2dpbmdGb3JtYXQ6IExvZ2dpbmdGb3JtYXQuSlNPTixcbiAgICAgICAgbG9nR3JvdXA6IHByZXdhcm1lckxvZ0dyb3VwLFxuICAgICAgfSlcblxuICAgICAgdGhpcy53YXJtZXJGdW5jdGlvbi5ncmFudEludm9rZShwcmV3YXJtZXJGbilcblxuICAgICAgY29uc3QgcHJvdmlkZXIgPSBuZXcgUHJvdmlkZXIodGhpcywgXCJQcmV3YXJtZXJQcm92aWRlclwiLCB7XG4gICAgICAgIG9uRXZlbnRIYW5kbGVyOiBwcmV3YXJtZXJGbixcbiAgICAgICAgbG9nR3JvdXA6IHByZXdhcm1lckxvZ0dyb3VwLFxuICAgICAgfSlcblxuICAgICAgLy8gQ3JlYXRlIGEgZGV0ZXJtaW5pc3RpYyB2ZXJzaW9uIGhhc2ggYmFzZWQgb24gd2FybWVyIGNvbmZpZ3VyYXRpb25cbiAgICAgIC8vIFRoaXMgZW5zdXJlcyBwcmUtd2FybWluZyBvbmx5IHRyaWdnZXJzIHdoZW4gY29uZmlnIGFjdHVhbGx5IGNoYW5nZXNcbiAgICAgIGNvbnN0IGNvbmZpZ0hhc2ggPSBjcmVhdGVIYXNoKFwic2hhMjU2XCIpXG4gICAgICAgIC51cGRhdGUoXG4gICAgICAgICAgSlNPTi5zdHJpbmdpZnkoe1xuICAgICAgICAgICAgY29uY3VycmVuY3k6IHdhcm1Db25jdXJyZW5jeSxcbiAgICAgICAgICAgIGludGVydmFsOiBpbnRlcnZhbC50b01pbnV0ZXMoKSxcbiAgICAgICAgICAgIHByZXdhcm1FbmFibGVkOiB0aGlzLnByb3BzLnByZXdhcm1PbkRlcGxveSxcbiAgICAgICAgICB9KVxuICAgICAgICApXG4gICAgICAgIC5kaWdlc3QoXCJoZXhcIilcbiAgICAgICAgLnN1YnN0cmluZygwLCAxNikgLy8gVHJ1bmNhdGUgZm9yIHJlYWRhYmlsaXR5XG5cbiAgICAgIG5ldyBDdXN0b21SZXNvdXJjZSh0aGlzLCBcIlByZXdhcm1lclJlc291cmNlXCIsIHtcbiAgICAgICAgc2VydmljZVRva2VuOiBwcm92aWRlci5zZXJ2aWNlVG9rZW4sXG4gICAgICAgIHByb3BlcnRpZXM6IHtcbiAgICAgICAgICBGdW5jdGlvbk5hbWU6IHRoaXMud2FybWVyRnVuY3Rpb24uZnVuY3Rpb25OYW1lLFxuICAgICAgICAgIFZlcnNpb246IGNvbmZpZ0hhc2gsXG4gICAgICAgIH0sXG4gICAgICB9KVxuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgZ2V0RW52aXJvbm1lbnQoKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIENBQ0hFX0JVQ0tFVF9OQU1FOiB0aGlzLmJ1Y2tldC5idWNrZXROYW1lLFxuICAgICAgQ0FDSEVfQlVDS0VUX0tFWV9QUkVGSVg6IFwiX2NhY2hlXCIsXG4gICAgICBDQUNIRV9CVUNLRVRfUkVHSU9OOiBTdGFjay5vZih0aGlzKS5yZWdpb24sXG4gICAgICBSRVZBTElEQVRJT05fUVVFVUVfVVJMOiB0aGlzLnF1ZXVlLnF1ZXVlVXJsLFxuICAgICAgUkVWQUxJREFUSU9OX1FVRVVFX1JFR0lPTjogU3RhY2sub2YodGhpcykucmVnaW9uLFxuICAgICAgQ0FDSEVfRFlOQU1PX1RBQkxFOiB0aGlzLnRhYmxlLnRhYmxlTmFtZSxcbiAgICAgIC8vIFRob3NlIDIgYXJlIHVzZWQgb25seSBmb3IgaW1hZ2Ugb3B0aW1pemVyXG4gICAgICBCVUNLRVRfTkFNRTogdGhpcy5idWNrZXQuYnVja2V0TmFtZSxcbiAgICAgIEJVQ0tFVF9LRVlfUFJFRklYOiBcIl9hc3NldHNcIixcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGdyYW50UGVybWlzc2lvbnMoZ3JhbnRhYmxlOiBJR3JhbnRhYmxlKSB7XG4gICAgdGhpcy5idWNrZXQuZ3JhbnRSZWFkV3JpdGUoZ3JhbnRhYmxlKVxuICAgIHRoaXMudGFibGUuZ3JhbnRSZWFkV3JpdGVEYXRhKGdyYW50YWJsZSlcbiAgICB0aGlzLnF1ZXVlLmdyYW50U2VuZE1lc3NhZ2VzKGdyYW50YWJsZSlcbiAgfVxuXG4gIHByaXZhdGUgY3JlYXRlRnVuY3Rpb25PcmlnaW4oXG4gICAga2V5OiBzdHJpbmcsXG4gICAgb3JpZ2luOiBPcGVuTmV4dEZ1bmN0aW9uT3JpZ2luLFxuICAgIG9yaWdpbklkPzogc3RyaW5nLFxuICAgIGZuUHJvcHM/OiBEZWZhdWx0RnVuY3Rpb25Qcm9wc1xuICApIHtcbiAgICBjb25zdCBlbnZpcm9ubWVudCA9IHRoaXMuZ2V0RW52aXJvbm1lbnQoKVxuICAgIGNvbnN0IGZuID0gbmV3IENka0Z1bmN0aW9uKHRoaXMsIGAke2tleX1GdW5jdGlvbmAsIHtcbiAgICAgIC4uLmZuUHJvcHMsXG4gICAgICBydW50aW1lOiBmblByb3BzPy5ydW50aW1lID8/IFJ1bnRpbWUuTk9ERUpTXzI0X1gsXG4gICAgICBhcmNoaXRlY3R1cmU6IGZuUHJvcHM/LmFyY2hpdGVjdHVyZSA/PyBBcmNoaXRlY3R1cmUuQVJNXzY0LFxuICAgICAgbWVtb3J5U2l6ZTogZm5Qcm9wcz8ubWVtb3J5U2l6ZSA/PyAxMDI0LFxuICAgICAgbG9nZ2luZ0Zvcm1hdDogZm5Qcm9wcz8ubG9nZ2luZ0Zvcm1hdCA/PyBMb2dnaW5nRm9ybWF0LkpTT04sXG4gICAgICBoYW5kbGVyOiBvcmlnaW4uaGFuZGxlcixcbiAgICAgIGNvZGU6IENvZGUuZnJvbUFzc2V0KHBhdGguam9pbih0aGlzLm9wZW5OZXh0UGF0aCwgXCIuLlwiLCBvcmlnaW4uYnVuZGxlKSksXG4gICAgICBlbnZpcm9ubWVudDoge1xuICAgICAgICAuLi5mblByb3BzPy5lbnZpcm9ubWVudCxcbiAgICAgICAgLi4uZW52aXJvbm1lbnQsXG4gICAgICB9LFxuICAgIH0pXG4gICAgY29uc3QgZm5VcmwgPSBmbi5hZGRGdW5jdGlvblVybCh7XG4gICAgICBhdXRoVHlwZTogRnVuY3Rpb25VcmxBdXRoVHlwZS5OT05FLFxuICAgICAgaW52b2tlTW9kZTogb3JpZ2luLnN0cmVhbWluZyA/IEludm9rZU1vZGUuUkVTUE9OU0VfU1RSRUFNIDogSW52b2tlTW9kZS5CVUZGRVJFRCxcbiAgICB9KVxuICAgIHRoaXMuZ3JhbnRQZXJtaXNzaW9ucyhmbilcblxuICAgIC8vIFN0b3JlIHJlZmVyZW5jZSB0byBkZWZhdWx0IHNlcnZlciBmdW5jdGlvblxuICAgIGlmIChrZXkgPT09IFwiZGVmYXVsdFwiKSB7XG4gICAgICB0aGlzLl9kZWZhdWx0U2VydmVyRnVuY3Rpb24gPSBmblxuICAgIH1cblxuICAgIHJldHVybiBuZXcgSHR0cE9yaWdpbihGbi5wYXJzZURvbWFpbk5hbWUoZm5VcmwudXJsKSwge1xuICAgICAgLi4uKG9yaWdpbklkID8geyBvcmlnaW5JZCB9IDoge30pLFxuICAgIH0pXG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlcyB0aGUgaW1hZ2Ugb3B0aW1pemVyIExhbWJkYSBmdW5jdGlvbiB3aXRoIE9yaWdpbiBBY2Nlc3MgQ29udHJvbCAoT0FDKS5cbiAgICogT0FDIGVuc3VyZXMgdGhhdCB0aGUgaW1hZ2Ugb3B0aW1pemVyIGNhbiBvbmx5IGJlIGFjY2Vzc2VkIHRocm91Z2ggQ2xvdWRGcm9udCxcbiAgICogcHJldmVudGluZyBkaXJlY3QgYWNjZXNzIHRvIHRoZSBMYW1iZGEgZnVuY3Rpb24gVVJMLlxuICAgKi9cbiAgcHJpdmF0ZSBjcmVhdGVJbWFnZU9wdGltaXplck9yaWdpbihvcmlnaW46IE9wZW5OZXh0RnVuY3Rpb25PcmlnaW4pIHtcbiAgICBjb25zdCBlbnZpcm9ubWVudCA9IHRoaXMuZ2V0RW52aXJvbm1lbnQoKVxuICAgIGNvbnN0IGZuID0gbmV3IENka0Z1bmN0aW9uKHRoaXMsIFwiaW1hZ2VPcHRpbWl6ZXJGdW5jdGlvblwiLCB7XG4gICAgICBydW50aW1lOiBSdW50aW1lLk5PREVKU18yNF9YLFxuICAgICAgYXJjaGl0ZWN0dXJlOiBBcmNoaXRlY3R1cmUuQVJNXzY0LFxuICAgICAgbWVtb3J5U2l6ZTogMTAyNCxcbiAgICAgIGxvZ2dpbmdGb3JtYXQ6IExvZ2dpbmdGb3JtYXQuSlNPTixcbiAgICAgIGhhbmRsZXI6IG9yaWdpbi5oYW5kbGVyLFxuICAgICAgY29kZTogQ29kZS5mcm9tQXNzZXQocGF0aC5qb2luKHRoaXMub3Blbk5leHRQYXRoLCBcIi4uXCIsIG9yaWdpbi5idW5kbGUpKSxcbiAgICAgIGVudmlyb25tZW50LFxuICAgIH0pXG5cbiAgICAvLyBDcmVhdGUgZnVuY3Rpb24gVVJMIHdpdGggSUFNIGF1dGggLSByZXF1aXJlZCBmb3IgT0FDXG4gICAgY29uc3QgZm5VcmwgPSBmbi5hZGRGdW5jdGlvblVybCh7XG4gICAgICBhdXRoVHlwZTogRnVuY3Rpb25VcmxBdXRoVHlwZS5BV1NfSUFNLFxuICAgIH0pXG5cbiAgICB0aGlzLmdyYW50UGVybWlzc2lvbnMoZm4pXG5cbiAgICAvLyBVc2UgRnVuY3Rpb25VcmxPcmlnaW4ud2l0aE9yaWdpbkFjY2Vzc0NvbnRyb2wgd2hpY2g6XG4gICAgLy8gMS4gQ3JlYXRlcyBhbiBPQUMgZm9yIExhbWJkYSBmdW5jdGlvbiBVUkxzXG4gICAgLy8gMi4gR3JhbnRzIENsb3VkRnJvbnQgcGVybWlzc2lvbiB0byBpbnZva2UgdGhlIGZ1bmN0aW9uIFVSTFxuICAgIHJldHVybiBGdW5jdGlvblVybE9yaWdpbi53aXRoT3JpZ2luQWNjZXNzQ29udHJvbChmblVybCwge1xuICAgICAgb3JpZ2luSWQ6IFwiSW1hZ2VPcHRpbWl6ZXJcIixcbiAgICB9KVxuICB9XG5cbiAgcHJpdmF0ZSBnZXRHZW9IZWFkZXJzSW5qZWN0aW9uKCkge1xuICAgIHJldHVybiBgXG5pZihyZXF1ZXN0LmhlYWRlcnNbXCJjbG91ZGZyb250LXZpZXdlci1jaXR5XCJdKSB7XG4gIHJlcXVlc3QuaGVhZGVyc1tcIngtb3Blbi1uZXh0LWNpdHlcIl0gPSByZXF1ZXN0LmhlYWRlcnNbXCJjbG91ZGZyb250LXZpZXdlci1jaXR5XCJdO1xufVxuaWYocmVxdWVzdC5oZWFkZXJzW1wiY2xvdWRmcm9udC12aWV3ZXItY291bnRyeVwiXSkge1xuICByZXF1ZXN0LmhlYWRlcnNbXCJ4LW9wZW4tbmV4dC1jb3VudHJ5XCJdID0gcmVxdWVzdC5oZWFkZXJzW1wiY2xvdWRmcm9udC12aWV3ZXItY291bnRyeVwiXTtcbn1cbmlmKHJlcXVlc3QuaGVhZGVyc1tcImNsb3VkZnJvbnQtdmlld2VyLXJlZ2lvblwiXSkge1xuICByZXF1ZXN0LmhlYWRlcnNbXCJ4LW9wZW4tbmV4dC1yZWdpb25cIl0gPSByZXF1ZXN0LmhlYWRlcnNbXCJjbG91ZGZyb250LXZpZXdlci1yZWdpb25cIl07XG59XG5pZihyZXF1ZXN0LmhlYWRlcnNbXCJjbG91ZGZyb250LXZpZXdlci1sYXRpdHVkZVwiXSkge1xuICByZXF1ZXN0LmhlYWRlcnNbXCJ4LW9wZW4tbmV4dC1sYXRpdHVkZVwiXSA9IHJlcXVlc3QuaGVhZGVyc1tcImNsb3VkZnJvbnQtdmlld2VyLWxhdGl0dWRlXCJdO1xufVxuaWYocmVxdWVzdC5oZWFkZXJzW1wiY2xvdWRmcm9udC12aWV3ZXItbG9uZ2l0dWRlXCJdKSB7XG4gIHJlcXVlc3QuaGVhZGVyc1tcIngtb3Blbi1uZXh0LWxvbmdpdHVkZVwiXSA9IHJlcXVlc3QuaGVhZGVyc1tcImNsb3VkZnJvbnQtdmlld2VyLWxvbmdpdHVkZVwiXTtcbn1cbiAgICBgLnRyaW0oKVxuICB9XG5cbiAgcHJpdmF0ZSBjcmVhdGVEaXN0cmlidXRpb24oXG4gICAgb3JpZ2luczogUmVjb3JkPHN0cmluZywgSU9yaWdpbj4sXG4gICAgcHJvcHM6IE5leHRqc1NpdGVQcm9wcyxcbiAgICBjZXJ0aWZpY2F0ZT86IElDZXJ0aWZpY2F0ZVxuICApIHtcbiAgICBjb25zdCBjbG91ZGZyb250RnVuY3Rpb24gPSBuZXcgQ2xvdWRmcm9udEZ1bmN0aW9uKHRoaXMsIFwiQ2xvdWRGcm9udEZ1bmN0aW9uXCIsIHtcbiAgICAgIGNvZGU6IEZ1bmN0aW9uQ29kZS5mcm9tSW5saW5lKGBcblx0XHRcdGZ1bmN0aW9uIGhhbmRsZXIoZXZlbnQpIHtcblx0XHRcdFx0dmFyIHJlcXVlc3QgPSBldmVudC5yZXF1ZXN0O1xuXHRcdFx0XHRyZXF1ZXN0LmhlYWRlcnNbXCJ4LWZvcndhcmRlZC1ob3N0XCJdID0gcmVxdWVzdC5oZWFkZXJzLmhvc3Q7XG5cdFx0XHRcdCR7dGhpcy5nZXRHZW9IZWFkZXJzSW5qZWN0aW9uKCl9XG5cdFx0XHRcdHJldHVybiByZXF1ZXN0O1xuXHRcdFx0fVxuXHRcdFx0YCksXG4gICAgfSlcbiAgICBjb25zdCBmbkFzc29jaWF0aW9ucyA9IFtcbiAgICAgIHtcbiAgICAgICAgZnVuY3Rpb246IGNsb3VkZnJvbnRGdW5jdGlvbixcbiAgICAgICAgZXZlbnRUeXBlOiBGdW5jdGlvbkV2ZW50VHlwZS5WSUVXRVJfUkVRVUVTVCxcbiAgICAgIH0sXG4gICAgXVxuXG4gICAgY29uc3QgZGlzdHJpYnV0aW9uID0gbmV3IERpc3RyaWJ1dGlvbih0aGlzLCBcIkRpc3RyaWJ1dGlvblwiLCB7XG4gICAgICBkb21haW5OYW1lczogcHJvcHMuY3VzdG9tRG9tYWluID8gW3Byb3BzLmN1c3RvbURvbWFpbi5kb21haW5OYW1lXSA6IHVuZGVmaW5lZCxcbiAgICAgIGNlcnRpZmljYXRlLFxuICAgICAgZGVmYXVsdEJlaGF2aW9yOiB7XG4gICAgICAgIG9yaWdpbjogb3JpZ2lucy5kZWZhdWx0ISwgLy8gZXNsaW50LWRpc2FibGUtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tbm9uLW51bGwtYXNzZXJ0aW9uXG4gICAgICAgIHZpZXdlclByb3RvY29sUG9saWN5OiBWaWV3ZXJQcm90b2NvbFBvbGljeS5SRURJUkVDVF9UT19IVFRQUyxcbiAgICAgICAgYWxsb3dlZE1ldGhvZHM6IEFsbG93ZWRNZXRob2RzLkFMTE9XX0FMTCxcbiAgICAgICAgY2FjaGVkTWV0aG9kczogQ2FjaGVkTWV0aG9kcy5DQUNIRV9HRVRfSEVBRF9PUFRJT05TLFxuICAgICAgICBjYWNoZVBvbGljeTogdGhpcy5zZXJ2ZXJDYWNoZVBvbGljeSxcbiAgICAgICAgb3JpZ2luUmVxdWVzdFBvbGljeTogT3JpZ2luUmVxdWVzdFBvbGljeS5BTExfVklFV0VSX0VYQ0VQVF9IT1NUX0hFQURFUixcbiAgICAgICAgZnVuY3Rpb25Bc3NvY2lhdGlvbnM6IGZuQXNzb2NpYXRpb25zLFxuICAgICAgfSxcbiAgICAgIGFkZGl0aW9uYWxCZWhhdmlvcnM6IHRoaXMub3Blbk5leHRPdXRwdXQuYmVoYXZpb3JzXG4gICAgICAgIC5maWx0ZXIoKGIpID0+IGIucGF0dGVybiAhPT0gXCIqXCIpXG4gICAgICAgIC5yZWR1Y2UoXG4gICAgICAgICAgKGFjYywgYmVoYXZpb3IpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGJlaGF2aW9yT3B0aW9uczogQmVoYXZpb3JPcHRpb25zID0ge1xuICAgICAgICAgICAgICBvcmlnaW46IChiZWhhdmlvci5vcmlnaW4gPyBvcmlnaW5zW2JlaGF2aW9yLm9yaWdpbl0gOiBvcmlnaW5zLmRlZmF1bHQpISwgLy8gZXNsaW50LWRpc2FibGUtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tbm9uLW51bGwtYXNzZXJ0aW9uXG4gICAgICAgICAgICAgIHZpZXdlclByb3RvY29sUG9saWN5OiBWaWV3ZXJQcm90b2NvbFBvbGljeS5SRURJUkVDVF9UT19IVFRQUyxcbiAgICAgICAgICAgICAgYWxsb3dlZE1ldGhvZHM6IEFsbG93ZWRNZXRob2RzLkFMTE9XX0dFVF9IRUFEX09QVElPTlMsXG4gICAgICAgICAgICAgIGNhY2hlZE1ldGhvZHM6IENhY2hlZE1ldGhvZHMuQ0FDSEVfR0VUX0hFQURfT1BUSU9OUyxcbiAgICAgICAgICAgICAgY2FjaGVQb2xpY3k6XG4gICAgICAgICAgICAgICAgYmVoYXZpb3Iub3JpZ2luID09PSBcInMzXCJcbiAgICAgICAgICAgICAgICAgID8gdGhpcy5zdGF0aWNDYWNoZVBvbGljeVxuICAgICAgICAgICAgICAgICAgOiB0aGlzLnNlcnZlckNhY2hlUG9saWN5LFxuICAgICAgICAgICAgICAuLi4oYmVoYXZpb3Iub3JpZ2luID09PSBcInMzXCJcbiAgICAgICAgICAgICAgICA/IHt9XG4gICAgICAgICAgICAgICAgOiB7XG4gICAgICAgICAgICAgICAgICAgIG9yaWdpblJlcXVlc3RQb2xpY3k6XG4gICAgICAgICAgICAgICAgICAgICAgT3JpZ2luUmVxdWVzdFBvbGljeS5BTExfVklFV0VSX0VYQ0VQVF9IT1NUX0hFQURFUixcbiAgICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICBmdW5jdGlvbkFzc29jaWF0aW9uczogZm5Bc3NvY2lhdGlvbnMsXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBhY2NbYmVoYXZpb3IucGF0dGVybl0gPSBiZWhhdmlvck9wdGlvbnNcbiAgICAgICAgICAgIHJldHVybiBhY2NcbiAgICAgICAgICB9LFxuICAgICAgICAgIHt9IGFzIFJlY29yZDxzdHJpbmcsIEJlaGF2aW9yT3B0aW9ucz5cbiAgICAgICAgKSxcbiAgICB9KVxuICAgIHJldHVybiBkaXN0cmlidXRpb25cbiAgfVxuXG4gIHByaXZhdGUgY3JlYXRlU2VydmVyQ2FjaGVQb2xpY3koKSB7XG4gICAgcmV0dXJuIG5ldyBDYWNoZVBvbGljeSh0aGlzLCBcIk9wZW5OZXh0U2VydmVyQ2FjaGVQb2xpY3lcIiwge1xuICAgICAgcXVlcnlTdHJpbmdCZWhhdmlvcjogQ2FjaGVRdWVyeVN0cmluZ0JlaGF2aW9yLmFsbCgpLFxuICAgICAgaGVhZGVyQmVoYXZpb3I6IENhY2hlSGVhZGVyQmVoYXZpb3IuYWxsb3dMaXN0KFxuICAgICAgICBcImFjY2VwdFwiLFxuICAgICAgICBcImFjY2VwdC1lbmNvZGluZ1wiLFxuICAgICAgICBcInJzY1wiLFxuICAgICAgICBcIm5leHQtcm91dGVyLXByZWZldGNoXCIsXG4gICAgICAgIFwibmV4dC1yb3V0ZXItc3RhdGUtdHJlZVwiLFxuICAgICAgICBcIm5leHQtdXJsXCIsXG4gICAgICAgIFwieC1wcmVyZW5kZXItcmV2YWxpZGF0ZVwiXG4gICAgICApLFxuICAgICAgY29va2llQmVoYXZpb3I6IENhY2hlQ29va2llQmVoYXZpb3Iubm9uZSgpLFxuICAgICAgZGVmYXVsdFR0bDogRHVyYXRpb24uZGF5cygwKSxcbiAgICAgIG1heFR0bDogRHVyYXRpb24uZGF5cygzNjUpLFxuICAgICAgbWluVHRsOiBEdXJhdGlvbi5kYXlzKDApLFxuICAgIH0pXG4gIH1cblxuICBwcml2YXRlIGNyZWF0ZVN0YXRpY0NhY2hlUG9saWN5KCkge1xuICAgIHJldHVybiBDYWNoZVBvbGljeS5DQUNISU5HX09QVElNSVpFRFxuICB9XG59XG4iXX0=
package/package.json CHANGED
@@ -82,7 +82,7 @@
82
82
  "publishConfig": {
83
83
  "access": "public"
84
84
  },
85
- "version": "0.4.9",
85
+ "version": "0.4.10",
86
86
  "jest": {
87
87
  "coverageProvider": "v8",
88
88
  "testMatch": [