cdk-nextjs 0.6.2 → 0.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.jsii +2404 -2723
- package/.jsii.tabl.json +1 -1
- package/API.md +1681 -1930
- package/CLAUDE.md +2 -1
- package/README.md +429 -130
- package/assets/lambdas/post-deploy/post-deploy.lambda/index.js +148 -169
- package/assets/lambdas/redeploy-stage/redeploy-stage.lambda/index.js +875 -0
- package/docs/adapter-runtime.md +185 -0
- package/docs/breaking-changes.md +667 -4
- package/docs/caching-guide.md +156 -112
- package/docs/cdk-nextjs-cfn-exec-policy.json +2 -1
- package/docs/development-guide.md +1 -1
- package/docs/harness-coverage.md +598 -0
- package/docs/init-cache-deployment.md +32 -1
- package/docs/next-build-output-guide.md +30 -20
- package/examples/README.md +5 -1
- package/lib/adapter/__fixtures__/app-playground-base-path.json +4926 -0
- package/lib/adapter/__fixtures__/app-playground.json +4917 -0
- package/lib/adapter/__fixtures__/pages-i18n.json +1728 -0
- package/lib/adapter/adapter.mjs +1551 -185
- package/lib/adapter/adapter.test.js +106 -0
- package/lib/adapter/aws-cache-store.d.ts +489 -0
- package/lib/adapter/aws-cache-store.js +1004 -0
- package/lib/adapter/aws-cache-store.test.d.ts +1 -0
- package/lib/adapter/aws-cache-store.test.js +361 -0
- package/lib/adapter/build-outputs.d.ts +80 -0
- package/lib/adapter/build-outputs.js +857 -0
- package/lib/adapter/build-outputs.test.d.ts +1 -0
- package/lib/adapter/build-outputs.test.js +863 -0
- package/lib/adapter/cache-handler.d.ts +9 -2
- package/lib/adapter/cache-handler.js +72 -96
- package/lib/adapter/cache-handler.mjs +18956 -17774
- package/lib/adapter/cache-handler.test.js +263 -31
- package/lib/adapter/cache-kinds.d.ts +32 -0
- package/lib/adapter/cache-kinds.js +35 -0
- package/lib/adapter/cache-kinds.test.d.ts +1 -0
- package/lib/adapter/cache-kinds.test.js +69 -0
- package/lib/adapter/cache-utils.d.ts +90 -0
- package/lib/adapter/cache-utils.js +199 -4
- package/lib/adapter/cache-utils.test.d.ts +1 -0
- package/lib/adapter/cache-utils.test.js +179 -0
- package/lib/adapter/function-groups.d.ts +215 -0
- package/lib/adapter/function-groups.js +1099 -0
- package/lib/adapter/function-groups.test.d.ts +1 -0
- package/lib/adapter/function-groups.test.js +743 -0
- package/lib/adapter/init-cache.d.ts +6 -0
- package/lib/adapter/init-cache.js +245 -0
- package/lib/adapter/init-cache.test.d.ts +1 -0
- package/lib/adapter/init-cache.test.js +137 -0
- package/lib/adapter/local-file-cache-handler.d.ts +23 -0
- package/lib/adapter/local-file-cache-handler.js +52 -1
- package/lib/adapter/memory-cache-handler.d.ts +26 -17
- package/lib/adapter/memory-cache-handler.js +32 -50
- package/lib/adapter/memory-cache-handler.test.js +105 -85
- package/lib/adapter/s3-cache-handler.d.ts +179 -40
- package/lib/adapter/s3-cache-handler.js +807 -277
- package/lib/adapter/s3-cache-handler.test.js +1186 -31
- package/lib/adapter/use-cache-common.d.ts +90 -0
- package/lib/adapter/use-cache-common.js +250 -0
- package/lib/adapter/use-cache-common.test.d.ts +1 -0
- package/lib/adapter/use-cache-common.test.js +646 -0
- package/lib/adapter/use-cache-default-handler.d.ts +24 -0
- package/lib/adapter/use-cache-default-handler.js +90 -0
- package/lib/adapter/use-cache-default-handler.mjs +38645 -0
- package/lib/adapter/use-cache-handlers.test.d.ts +1 -0
- package/lib/adapter/use-cache-handlers.test.js +349 -0
- package/lib/adapter/use-cache-remote-handler.d.ts +26 -0
- package/lib/adapter/use-cache-remote-handler.js +186 -0
- package/lib/{image-optimization/handler.mjs → adapter/use-cache-remote-handler.mjs} +33572 -38798
- package/lib/generated-structs/OptionalNextjsApiProps.d.ts +59 -0
- package/lib/generated-structs/OptionalNextjsApiProps.js +3 -0
- package/lib/generated-structs/OptionalNextjsCacheProps.d.ts +15 -6
- package/lib/generated-structs/OptionalNextjsCacheProps.js +1 -1
- package/lib/generated-structs/OptionalNextjsContainersProps.d.ts +25 -11
- package/lib/generated-structs/OptionalNextjsContainersProps.js +1 -1
- package/lib/generated-structs/OptionalNextjsDistributionProps.d.ts +31 -9
- package/lib/generated-structs/OptionalNextjsDistributionProps.js +1 -1
- package/lib/generated-structs/OptionalNextjsPostDeployProps.d.ts +8 -0
- package/lib/generated-structs/OptionalNextjsPostDeployProps.js +1 -1
- package/lib/generated-structs/OptionalPostDeployCustomResourceProperties.d.ts +6 -4
- package/lib/generated-structs/OptionalPostDeployCustomResourceProperties.js +1 -1
- package/lib/index.d.ts +6 -7
- package/lib/index.js +2 -4
- package/lib/lambdas/post-deploy/prune-cache-bucket.d.ts +7 -3
- package/lib/lambdas/post-deploy/prune-cache-bucket.js +57 -71
- package/lib/lambdas/post-deploy/prune-cache-bucket.test.d.ts +1 -0
- package/lib/lambdas/post-deploy/prune-cache-bucket.test.js +114 -0
- package/lib/lambdas/post-deploy/prune-revalidation-table.d.ts +1 -0
- package/lib/lambdas/post-deploy/prune-revalidation-table.js +23 -31
- package/lib/lambdas/post-deploy/prune-revalidation-table.test.d.ts +1 -0
- package/lib/lambdas/post-deploy/prune-revalidation-table.test.js +71 -0
- package/lib/lambdas/post-deploy/prune-s3.d.ts +14 -5
- package/lib/lambdas/post-deploy/prune-s3.js +41 -12
- package/lib/lambdas/post-deploy/prune-s3.test.js +97 -18
- package/lib/lambdas/redeploy-stage/redeploy-stage-function.d.ts +13 -0
- package/lib/lambdas/redeploy-stage/redeploy-stage-function.js +55 -0
- package/lib/lambdas/redeploy-stage/redeploy-stage.d.ts +24 -0
- package/lib/lambdas/redeploy-stage/redeploy-stage.js +68 -0
- package/lib/lambdas/redeploy-stage/redeploy-stage.lambda.d.ts +20 -0
- package/lib/lambdas/redeploy-stage/redeploy-stage.lambda.js +24 -0
- package/lib/lambdas/redeploy-stage/redeploy-stage.test.d.ts +1 -0
- package/lib/lambdas/redeploy-stage/redeploy-stage.test.js +93 -0
- package/lib/nextjs-api.d.ts +102 -18
- package/lib/nextjs-api.js +338 -38
- package/lib/nextjs-api.test.js +537 -1
- package/lib/nextjs-build/global-containers.Dockerfile +15 -10
- package/lib/nextjs-build/nextjs-build.d.ts +339 -63
- package/lib/nextjs-build/nextjs-build.js +684 -327
- package/lib/nextjs-build/nextjs-build.test.d.ts +1 -0
- package/lib/nextjs-build/nextjs-build.test.js +412 -0
- package/lib/nextjs-build/patch-fetch.js +1 -1
- package/lib/nextjs-build/patch-fetch.test.js +166 -11
- package/lib/nextjs-build/regional-containers.Dockerfile +17 -10
- package/lib/nextjs-cache.d.ts +82 -4
- package/lib/nextjs-cache.js +186 -10
- package/lib/nextjs-cache.test.js +176 -1
- package/lib/nextjs-compute/nextjs-compute-base-props.d.ts +21 -8
- package/lib/nextjs-compute/nextjs-compute-base-props.js +41 -1
- package/lib/nextjs-compute/nextjs-compute-base-props.test.d.ts +1 -0
- package/lib/nextjs-compute/nextjs-compute-base-props.test.js +44 -0
- package/lib/nextjs-compute/nextjs-containers.d.ts +19 -0
- package/lib/nextjs-compute/nextjs-containers.js +57 -20
- package/lib/nextjs-compute/nextjs-functions.d.ts +122 -7
- package/lib/nextjs-compute/nextjs-functions.js +113 -67
- package/lib/nextjs-compute/nextjs-functions.test.d.ts +1 -0
- package/lib/nextjs-compute/nextjs-functions.test.js +99 -0
- package/lib/nextjs-distribution.d.ts +194 -23
- package/lib/nextjs-distribution.js +535 -62
- package/lib/nextjs-distribution.test.d.ts +1 -0
- package/lib/nextjs-distribution.test.js +697 -0
- package/lib/nextjs-post-deploy.d.ts +13 -5
- package/lib/nextjs-post-deploy.js +13 -10
- package/lib/nextjs-post-deploy.test.d.ts +1 -0
- package/lib/nextjs-post-deploy.test.js +34 -0
- package/lib/nextjs-static-assets.d.ts +17 -4
- package/lib/nextjs-static-assets.js +22 -5
- package/lib/root-constructs/nextjs-base-construct.d.ts +102 -58
- package/lib/root-constructs/nextjs-base-construct.js +139 -47
- package/lib/root-constructs/nextjs-global-containers.d.ts +18 -20
- package/lib/root-constructs/nextjs-global-containers.js +20 -71
- package/lib/root-constructs/nextjs-global-functions.d.ts +26 -28
- package/lib/root-constructs/nextjs-global-functions.js +52 -70
- package/lib/root-constructs/nextjs-regional-containers.d.ts +18 -5
- package/lib/root-constructs/nextjs-regional-containers.js +8 -15
- package/lib/root-constructs/nextjs-regional-functions.d.ts +22 -18
- package/lib/root-constructs/nextjs-regional-functions.js +8 -26
- package/lib/runtime/api-gateway-path.d.ts +34 -0
- package/lib/runtime/api-gateway-path.js +71 -0
- package/lib/runtime/api-gateway-path.test.d.ts +1 -0
- package/lib/runtime/api-gateway-path.test.js +65 -0
- package/lib/runtime/case-redirect.d.ts +22 -0
- package/lib/runtime/case-redirect.js +63 -0
- package/lib/runtime/case-redirect.test.d.ts +1 -0
- package/lib/runtime/case-redirect.test.js +32 -0
- package/lib/runtime/core.d.ts +234 -0
- package/lib/runtime/core.js +1216 -0
- package/lib/runtime/core.test.d.ts +1 -0
- package/lib/runtime/core.test.js +1686 -0
- package/lib/runtime/deployment-root.d.ts +13 -0
- package/lib/runtime/deployment-root.js +29 -0
- package/lib/runtime/dispatch.d.ts +331 -0
- package/lib/runtime/dispatch.js +751 -0
- package/lib/runtime/dispatch.test.d.ts +1 -0
- package/lib/runtime/dispatch.test.js +853 -0
- package/lib/runtime/entrypoints.d.ts +57 -0
- package/lib/runtime/entrypoints.js +115 -0
- package/lib/runtime/http/abort-signal.d.ts +6 -0
- package/lib/runtime/http/abort-signal.js +19 -0
- package/lib/runtime/http/abort-signal.test.d.ts +1 -0
- package/lib/runtime/http/abort-signal.test.js +49 -0
- package/lib/runtime/http/node-server.d.ts +38 -0
- package/lib/runtime/http/node-server.js +99 -0
- package/lib/runtime/http/node-server.test.d.ts +1 -0
- package/lib/runtime/http/node-server.test.js +96 -0
- package/lib/runtime/http/node-sink.d.ts +16 -0
- package/lib/runtime/http/node-sink.js +48 -0
- package/lib/runtime/http/node-sink.test.d.ts +1 -0
- package/lib/runtime/http/node-sink.test.js +66 -0
- package/lib/runtime/http/request.d.ts +62 -0
- package/lib/runtime/http/request.js +134 -0
- package/lib/runtime/http/request.test.d.ts +1 -0
- package/lib/runtime/http/request.test.js +103 -0
- package/lib/runtime/http/response.d.ts +77 -0
- package/lib/runtime/http/response.js +229 -0
- package/lib/runtime/http/response.test.d.ts +1 -0
- package/lib/runtime/http/response.test.js +178 -0
- package/lib/runtime/http/sink.d.ts +73 -0
- package/lib/runtime/http/sink.js +188 -0
- package/lib/runtime/http/sink.test.d.ts +1 -0
- package/lib/runtime/http/sink.test.js +257 -0
- package/lib/runtime/image-utils.d.ts +78 -0
- package/lib/runtime/image-utils.js +129 -0
- package/lib/runtime/image-utils.test.d.ts +1 -0
- package/lib/runtime/image-utils.test.js +237 -0
- package/lib/runtime/image.d.ts +76 -0
- package/lib/runtime/image.js +296 -0
- package/lib/runtime/image.test.d.ts +1 -0
- package/lib/runtime/image.test.js +405 -0
- package/lib/runtime/lambda-event.d.ts +4 -0
- package/lib/runtime/lambda-event.js +113 -0
- package/lib/runtime/lambda-event.test.d.ts +1 -0
- package/lib/runtime/lambda-event.test.js +119 -0
- package/lib/runtime/lambda.mjs +41600 -0
- package/lib/runtime/load-module.d.ts +8 -0
- package/lib/runtime/load-module.js +35 -0
- package/lib/runtime/manifest.d.ts +215 -0
- package/lib/runtime/manifest.js +118 -0
- package/lib/runtime/middleware.d.ts +43 -0
- package/lib/runtime/middleware.js +113 -0
- package/lib/runtime/middleware.test.d.ts +1 -0
- package/lib/runtime/middleware.test.js +259 -0
- package/lib/runtime/next-modules.d.ts +71 -0
- package/lib/runtime/next-modules.js +144 -0
- package/lib/runtime/next-modules.test.d.ts +1 -0
- package/lib/runtime/next-modules.test.js +34 -0
- package/lib/runtime/public-files.d.ts +32 -0
- package/lib/runtime/public-files.js +117 -0
- package/lib/runtime/public-files.test.d.ts +1 -0
- package/lib/runtime/public-files.test.js +97 -0
- package/lib/runtime/server.mjs +41593 -0
- package/lib/runtime/static-files.d.ts +50 -0
- package/lib/runtime/static-files.js +266 -0
- package/lib/runtime/static-files.test.d.ts +1 -0
- package/lib/runtime/static-files.test.js +118 -0
- package/lib/runtime/util.d.ts +28 -0
- package/lib/runtime/util.js +79 -0
- package/lib/utils/base-path.d.ts +106 -13
- package/lib/utils/base-path.js +254 -41
- package/lib/utils/base-path.test.js +219 -51
- package/lib/utils/get-architecture.d.ts +7 -8
- package/lib/utils/get-architecture.js +12 -13
- package/lib/utils/zip-directory.d.ts +14 -0
- package/lib/utils/zip-directory.js +121 -0
- package/lib/utils/zip-directory.test.d.ts +1 -0
- package/lib/utils/zip-directory.test.js +99 -0
- package/package.json +22 -3
- package/scripts/capture-adapter-fixture.mjs +325 -0
- package/scripts/e2e-deploy.sh +398 -0
- package/scripts/e2e-harness/README.md +707 -0
- package/scripts/e2e-harness/app.js +370 -0
- package/scripts/e2e-harness/common.sh +249 -0
- package/scripts/e2e-harness/screen.mjs +302 -0
- package/scripts/e2e-harness/stage-proxy.mjs +145 -0
- package/scripts/e2e-harness/type-filters.mjs +47 -0
- package/scripts/e2e-logs.sh +75 -0
- package/scripts/e2e-offline.sh +91 -0
- package/scripts/e2e-sweep.sh +370 -0
- package/scripts/e2e-warm.sh +114 -0
- package/scripts/zero-config-build.mjs +418 -0
- package/docs/1k-concurrent-users-executions.png +0 -0
- package/docs/plans/adapter-runtime-release.md +0 -362
- package/docs/plans/phase-0-image-function-opt-in.md +0 -295
- package/lib/generated-structs/OptionalDockerImageFunctionProps.d.ts +0 -425
- package/lib/generated-structs/OptionalDockerImageFunctionProps.js +0 -3
- package/lib/image-optimization/handler-utils.d.ts +0 -34
- package/lib/image-optimization/handler-utils.js +0 -83
- package/lib/image-optimization/handler-utils.test.js +0 -178
- package/lib/nextjs-build/functions.Dockerfile +0 -31
- package/lib/nextjs-compute/nextjs-image-function.d.ts +0 -53
- package/lib/nextjs-compute/nextjs-image-function.js +0 -59
- package/lib/utils/experimental-flags.d.ts +0 -24
- package/lib/utils/experimental-flags.js +0 -30
- /package/lib/{image-optimization/handler-utils.test.d.ts → adapter/adapter.test.d.ts} +0 -0
package/lib/nextjs-cache.js
CHANGED
|
@@ -1,19 +1,92 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
2
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
36
|
exports.NextjsCache = void 0;
|
|
4
37
|
const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
|
|
5
38
|
const fs_1 = require("fs");
|
|
39
|
+
const os_1 = require("os");
|
|
40
|
+
const path_1 = require("path");
|
|
6
41
|
const aws_cdk_lib_1 = require("aws-cdk-lib");
|
|
7
42
|
const aws_dynamodb_1 = require("aws-cdk-lib/aws-dynamodb");
|
|
8
43
|
const aws_s3_1 = require("aws-cdk-lib/aws-s3");
|
|
9
44
|
const aws_s3_deployment_1 = require("aws-cdk-lib/aws-s3-deployment");
|
|
45
|
+
const cxapi = __importStar(require("aws-cdk-lib/cx-api"));
|
|
10
46
|
const constructs_1 = require("constructs");
|
|
11
47
|
const constants_1 = require("./constants");
|
|
48
|
+
/** What a `BucketDeployment` Lambda gets without asking. */
|
|
49
|
+
const DEFAULT_EPHEMERAL_STORAGE_MIB = 512;
|
|
50
|
+
/** The most Lambda will give any function. */
|
|
51
|
+
const MAX_EPHEMERAL_STORAGE_MIB = 10240;
|
|
52
|
+
/**
|
|
53
|
+
* The smallest power-of-two MiB step at or above `mib`, capped at `max`.
|
|
54
|
+
*
|
|
55
|
+
* `BucketDeployment` folds `ephemeralStorageSize` into both its singleton
|
|
56
|
+
* handler's UUID and its custom resource's logical ID, so every distinct size is
|
|
57
|
+
* a new handler Lambda, a new `ServiceToken`, and a replaced custom resource.
|
|
58
|
+
* Sized to the MiB, that was every deploy whose init cache grew by one: a full
|
|
59
|
+
* CloudFormation deployment where a hotswap would have done. Doubling steps
|
|
60
|
+
* change only when the cache does by a large fraction.
|
|
61
|
+
*/
|
|
62
|
+
function storageStep(mib, max) {
|
|
63
|
+
let step = DEFAULT_EPHEMERAL_STORAGE_MIB;
|
|
64
|
+
while (step < mib) {
|
|
65
|
+
step *= 2;
|
|
66
|
+
}
|
|
67
|
+
return Math.min(step, max);
|
|
68
|
+
}
|
|
69
|
+
/** Bytes on disk under `dir`, following the tree but not symlinks. */
|
|
70
|
+
function sizeOfDirectory(dir) {
|
|
71
|
+
let total = 0;
|
|
72
|
+
for (const entry of (0, fs_1.readdirSync)(dir, {
|
|
73
|
+
withFileTypes: true,
|
|
74
|
+
recursive: true,
|
|
75
|
+
})) {
|
|
76
|
+
if (entry.isFile()) {
|
|
77
|
+
// `parentPath` only exists from Node 20.12; `path` is its deprecated
|
|
78
|
+
// predecessor, and the only one on 20.9-20.11.
|
|
79
|
+
const parent = entry.parentPath ?? entry.path;
|
|
80
|
+
total += (0, fs_1.statSync)((0, path_1.join)(parent, entry.name)).size;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
return total;
|
|
84
|
+
}
|
|
12
85
|
/**
|
|
13
86
|
* Next.js Cache construct providing unified S3 and DynamoDB cache management.
|
|
14
87
|
*/
|
|
15
88
|
class NextjsCache extends constructs_1.Construct {
|
|
16
|
-
static [JSII_RTTI_SYMBOL_1] = { fqn: "cdk-nextjs.NextjsCache", version: "0.
|
|
89
|
+
static [JSII_RTTI_SYMBOL_1] = { fqn: "cdk-nextjs.NextjsCache", version: "0.7.1" };
|
|
17
90
|
cacheBucket;
|
|
18
91
|
revalidationTable;
|
|
19
92
|
buildId;
|
|
@@ -45,6 +118,9 @@ class NextjsCache extends constructs_1.Construct {
|
|
|
45
118
|
/**
|
|
46
119
|
* Creates DynamoDB table for revalidation metadata
|
|
47
120
|
* Schema: pk (buildId or "METADATA"), sk (tag#cacheKey or "CURRENT_BUILD"), createdAt, revalidatedAt
|
|
121
|
+
*
|
|
122
|
+
* Also the `'use cache'` revalidation log (pk "<buildId>#log",
|
|
123
|
+
* sk "<epoch-ms>#<tag>"), whose rows expire through the `ttl` attribute.
|
|
48
124
|
*/
|
|
49
125
|
createRevalidationTable() {
|
|
50
126
|
const table = new aws_dynamodb_1.TableV2(this, "RevalidationTable", {
|
|
@@ -58,6 +134,7 @@ class NextjsCache extends constructs_1.Construct {
|
|
|
58
134
|
},
|
|
59
135
|
billing: aws_dynamodb_1.Billing.onDemand(),
|
|
60
136
|
removalPolicy: aws_cdk_lib_1.RemovalPolicy.DESTROY,
|
|
137
|
+
timeToLiveAttribute: "ttl",
|
|
61
138
|
...this.props.overrides?.revalidationTableProps,
|
|
62
139
|
});
|
|
63
140
|
return table;
|
|
@@ -72,16 +149,115 @@ class NextjsCache extends constructs_1.Construct {
|
|
|
72
149
|
return undefined;
|
|
73
150
|
}
|
|
74
151
|
console.log(`${constants_1.LOG_PREFIX} Deploying init cache from ${this.props.initCacheDir}`);
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
152
|
+
const stagingDir = this.createStagingDirectory();
|
|
153
|
+
try {
|
|
154
|
+
// Use standard BucketDeployment for regular S3 buckets
|
|
155
|
+
const bucketDeployment = new aws_s3_deployment_1.BucketDeployment(this, "InitCacheDeployment", {
|
|
156
|
+
sources: [aws_s3_deployment_1.Source.asset(stagingDir)],
|
|
157
|
+
destinationBucket: this.cacheBucket,
|
|
158
|
+
prune: false, // Don't delete existing objects to prevent 404s during deployment, pruning will be handled by post-deploy
|
|
159
|
+
...this.sizeDeploymentLambda(),
|
|
160
|
+
...this.props.overrides?.bucketDeploymentProps,
|
|
161
|
+
});
|
|
162
|
+
return bucketDeployment;
|
|
163
|
+
}
|
|
164
|
+
finally {
|
|
165
|
+
// `Source.asset` stages during `BucketDeployment`'s construction - CDK's
|
|
166
|
+
// `AssetStaging` zips into `cdk.out` from its own constructor - so the
|
|
167
|
+
// temporary copy is dead the moment that returns. Leaving it was a slow
|
|
168
|
+
// leak with a large unit: the init cache has been measured at 664 MiB, and
|
|
169
|
+
// every `cdk synth` left another full copy in the system temp directory,
|
|
170
|
+
// so a CI loop of ~22 deploys could put ~15 GB on the runner's disk.
|
|
171
|
+
//
|
|
172
|
+
// Unless staging is disabled (`cdk synth --no-staging`, and SAM, which
|
|
173
|
+
// sets the same context): then nothing is copied into `cdk.out`, the
|
|
174
|
+
// asset manifest points at this directory itself, and removing it fails
|
|
175
|
+
// the publish that follows the synth with ENOENT.
|
|
176
|
+
if (!this.node.tryGetContext(cxapi.DISABLE_ASSET_STAGING_CONTEXT)) {
|
|
177
|
+
(0, fs_1.rmSync)(stagingDir, { recursive: true, force: true });
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* `/tmp` and memory for `BucketDeployment`'s unzip Lambda, scaled to the init
|
|
183
|
+
* cache it has to unpack.
|
|
184
|
+
*
|
|
185
|
+
* That Lambda downloads the asset zip into `/tmp` and then extracts it
|
|
186
|
+
* alongside, so it needs room for both at once. CDK defaults it to 512 MiB of
|
|
187
|
+
* ephemeral storage and 128 MB of memory — fine for a small app, and a hard
|
|
188
|
+
* failure for one whose prerendered payloads are large. A fixture with 60
|
|
189
|
+
* statically generated pages carrying ~1 MB of RSC each produced a 664 MiB
|
|
190
|
+
* seed directory and the handler died on
|
|
191
|
+
* `OSError: [Errno 28] No space left on device` inside `zip.extractall`.
|
|
192
|
+
* Worse, `cdk deploy --hotswap` invokes the custom resource directly with a
|
|
193
|
+
* placeholder response URL, so the `Status: FAILED` it sends goes nowhere: the
|
|
194
|
+
* CLI prints "Contents of AWS::S3::Bucket … hotswapped!", exits 0, and the app
|
|
195
|
+
* comes up serving a *partially* seeded cache. Every route whose entry did not
|
|
196
|
+
* make it is then a miss that re-renders — which, for a
|
|
197
|
+
* `cacheComponents: true` app, means a postponed shell where the prerender
|
|
198
|
+
* should have been.
|
|
199
|
+
*
|
|
200
|
+
* The zip's compressed size is not known at synth time (CDK archives the asset
|
|
201
|
+
* later), so the worst case — an incompressible payload — is what gets
|
|
202
|
+
* budgeted: twice the directory, plus headroom, rounded up to a
|
|
203
|
+
* {@link storageStep}. Memory is only raised past
|
|
204
|
+
* CDK's default for caches big enough that 128 MB's slice of a vCPU would make
|
|
205
|
+
* the unzip and upload race the custom resource's 15-minute timeout; small
|
|
206
|
+
* apps keep the cheaper default and their existing template.
|
|
207
|
+
*
|
|
208
|
+
* Above the 10 GiB ephemeral-storage ceiling there is nothing left to ask for,
|
|
209
|
+
* so this warns and lets the deployment fail loudly rather than pretend.
|
|
210
|
+
* `overrides.bucketDeploymentProps` wins over everything here, including
|
|
211
|
+
* `useEfs: true`, which is the supported way out.
|
|
212
|
+
*/
|
|
213
|
+
sizeDeploymentLambda() {
|
|
214
|
+
const mib = Math.ceil(sizeOfDirectory(this.props.initCacheDir) / 1024 ** 2);
|
|
215
|
+
const wanted = mib * 2 + 128;
|
|
216
|
+
if (wanted > MAX_EPHEMERAL_STORAGE_MIB) {
|
|
217
|
+
console.warn(`${constants_1.LOG_PREFIX} The init cache at ${this.props.initCacheDir} is ${mib} MiB, which does not fit in the ${MAX_EPHEMERAL_STORAGE_MIB} MiB of ephemeral storage a BucketDeployment Lambda can be given. Pass overrides.bucketDeploymentProps with useEfs: true to seed a cache this large.`);
|
|
218
|
+
}
|
|
219
|
+
const ephemeral = storageStep(wanted, MAX_EPHEMERAL_STORAGE_MIB);
|
|
220
|
+
return {
|
|
221
|
+
ephemeralStorageSize: aws_cdk_lib_1.Size.mebibytes(ephemeral),
|
|
222
|
+
...(mib > 256 ? { memoryLimit: 1024 } : {}),
|
|
223
|
+
};
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* Stage the init cache under a `buildId` directory, so that the objects land
|
|
227
|
+
* at `<buildId>/<key>` without a `destinationKeyPrefix`.
|
|
228
|
+
*
|
|
229
|
+
* The keys have to carry the build ID — that is how the runtime cache handler
|
|
230
|
+
* and the post-deploy pruner namespace one deployment's entries from the next
|
|
231
|
+
* (`src/adapter/s3-cache-handler.ts`). Asking `BucketDeployment` for it, as
|
|
232
|
+
* this used to, is what costs: it unconditionally tags the *destination
|
|
233
|
+
* bucket* with `aws-cdk:cr-owned:<destinationKeyPrefix>:<hash>`, so a prefix
|
|
234
|
+
* that changes per build makes the bucket's `Tags` change per build.
|
|
235
|
+
* `AWS::S3::Bucket` `Tags` are not hotswappable, so `cdk deploy
|
|
236
|
+
* --hotswap-fallback` rejected the diff and fell back to a full CloudFormation
|
|
237
|
+
* deployment every single time — measured at 19 of 22 deploys in one harness
|
|
238
|
+
* run, ~110s each against a ~52s hotswap.
|
|
239
|
+
*
|
|
240
|
+
* Putting the build ID in the asset's own paths instead leaves the S3 keys
|
|
241
|
+
* byte-identical and the tag key constant (`aws-cdk:cr-owned:<hash>`, derived
|
|
242
|
+
* from the construct path). Nothing else read the prefix: `prune` is already
|
|
243
|
+
* `false`, and the two handler branches that do scope work to it — emptying
|
|
244
|
+
* the prefix on delete, and deleting the old prefix when the destination
|
|
245
|
+
* changes — are both gated on `retainOnDelete`, which `BucketDeployment`
|
|
246
|
+
* defaults to `true`.
|
|
247
|
+
*
|
|
248
|
+
* A copy rather than the directory itself because the build ID is only known
|
|
249
|
+
* *after* `next build`, so the adapter cannot write into a nested directory in
|
|
250
|
+
* the first place, and because `.next/cdk-nextjs-init-cache` has to stay where
|
|
251
|
+
* it is for the local cache handler to read it (`CDK_NEXTJS_INIT_CACHE_DIR`).
|
|
252
|
+
* CDK is about to read every byte of this to zip it regardless.
|
|
253
|
+
*/
|
|
254
|
+
createStagingDirectory() {
|
|
255
|
+
const stagingDir = (0, fs_1.mkdtempSync)((0, path_1.join)((0, os_1.tmpdir)(), "nextjs-init-cache-"));
|
|
256
|
+
(0, fs_1.cpSync)(this.props.initCacheDir, (0, path_1.join)(stagingDir, this.props.buildId), {
|
|
257
|
+
recursive: true,
|
|
82
258
|
});
|
|
83
|
-
return
|
|
259
|
+
return stagingDir;
|
|
84
260
|
}
|
|
85
261
|
}
|
|
86
262
|
exports.NextjsCache = NextjsCache;
|
|
87
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmV4dGpzLWNhY2hlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL25leHRqcy1jYWNoZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7O0FBQUEsMkJBQWdDO0FBQ2hDLDZDQUE0QztBQUM1QywyREFNa0M7QUFDbEMsK0NBTTRCO0FBQzVCLHFFQUl1QztBQUN2QywyQ0FBdUM7QUFDdkMsMkNBQXlDO0FBK0J6Qzs7R0FFRztBQUNILE1BQWEsV0FBWSxTQUFRLHNCQUFTOztJQUMvQixXQUFXLENBQVU7SUFDckIsaUJBQWlCLENBQVc7SUFDNUIsT0FBTyxDQUFTO0lBQ2hCLGdCQUFnQixDQUFvQjtJQUNyQyxLQUFLLENBQW1CO0lBRWhDLFlBQVksS0FBZ0IsRUFBRSxFQUFVLEVBQUUsS0FBdUI7UUFDL0QsS0FBSyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsQ0FBQztRQUNqQixJQUFJLENBQUMsS0FBSyxHQUFHLEtBQUssQ0FBQztRQUNuQixJQUFJLENBQUMsT0FBTyxHQUFHLEtBQUssQ0FBQyxPQUFPLENBQUM7UUFDN0IsSUFBSSxDQUFDLFdBQVcsR0FBRyxLQUFLLENBQUMsV0FBVyxJQUFJLElBQUksQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO1FBQ2pFLElBQUksQ0FBQyxpQkFBaUI7WUFDcEIsS0FBSyxDQUFDLGlCQUFpQixJQUFJLElBQUksQ0FBQyx1QkFBdUIsRUFBRSxDQUFDO1FBQzVELElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxJQUFJLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQztJQUNsRCxDQUFDO0lBRUQ7O09BRUc7SUFDSyxpQkFBaUI7UUFDdkIsTUFBTSxNQUFNLEdBQUcsSUFBSSxlQUFNLENBQUMsSUFBSSxFQUFFLFFBQVEsRUFBRTtZQUN4QyxVQUFVLEVBQUUseUJBQWdCLENBQUMsVUFBVTtZQUN2QyxpQkFBaUIsRUFBRSwwQkFBaUIsQ0FBQyxTQUFTO1lBQzlDLGFBQWEsRUFBRSwyQkFBYSxDQUFDLE9BQU87WUFDcEMsaUJBQWlCLEVBQUUsSUFBSTtZQUN2QixVQUFVLEVBQUUsSUFBSTtZQUNoQixHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsU0FBUyxFQUFFLGdCQUFnQjtTQUMxQyxDQUFDLENBQUM7UUFFSCxPQUFPLE1BQU0sQ0FBQztJQUNoQixDQUFDO0lBRUQ7OztPQUdHO0lBQ0ssdUJBQXVCO1FBQzdCLE1BQU0sS0FBSyxHQUFHLElBQUksc0JBQU8sQ0FBQyxJQUFJLEVBQUUsbUJBQW1CLEVBQUU7WUFDbkQsWUFBWSxFQUFFO2dCQUNaLElBQUksRUFBRSxJQUFJO2dCQUNWLElBQUksRUFBRSw0QkFBYSxDQUFDLE1BQU07YUFDM0I7WUFDRCxPQUFPLEVBQUU7Z0JBQ1AsSUFBSSxFQUFFLElBQUk7Z0JBQ1YsSUFBSSxFQUFFLDRCQUFhLENBQUMsTUFBTTthQUMzQjtZQUNELE9BQU8sRUFBRSxzQkFBTyxDQUFDLFFBQVEsRUFBRTtZQUMzQixhQUFhLEVBQUUsMkJBQWEsQ0FBQyxPQUFPO1lBQ3BDLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxTQUFTLEVBQUUsc0JBQXNCO1NBQ2hELENBQUMsQ0FBQztRQUVILE9BQU8sS0FBSyxDQUFDO0lBQ2YsQ0FBQztJQUVEOztPQUVHO0lBQ0ssZ0JBQWdCO1FBQ3RCLGtDQUFrQztRQUNsQyxJQUFJLENBQUMsSUFBQSxlQUFVLEVBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxZQUFZLENBQUMsRUFBRSxDQUFDO1lBQ3pDLE9BQU8sQ0FBQyxHQUFHLENBQ1QsR0FBRyxzQkFBVSxnQ0FBZ0MsSUFBSSxDQUFDLEtBQUssQ0FBQyxZQUFZLGtDQUFrQyxDQUN2RyxDQUFDO1lBQ0YsT0FBTyxTQUFTLENBQUM7UUFDbkIsQ0FBQztRQUVELE9BQU8sQ0FBQyxHQUFHLENBQ1QsR0FBRyxzQkFBVSw4QkFBOEIsSUFBSSxDQUFDLEtBQUssQ0FBQyxZQUFZLEVBQUUsQ0FDckUsQ0FBQztRQUVGLHVEQUF1RDtRQUN2RCxNQUFNLGdCQUFnQixHQUFHLElBQUksb0NBQWdCLENBQUMsSUFBSSxFQUFFLHFCQUFxQixFQUFFO1lBQ3pFLE9BQU8sRUFBRSxDQUFDLDBCQUFNLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsWUFBWSxDQUFDLENBQUM7WUFDaEQsaUJBQWlCLEVBQUUsSUFBSSxDQUFDLFdBQVc7WUFDbkMsb0JBQW9CLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLEVBQUUsMkNBQTJDO1lBQ3JGLEtBQUssRUFBRSxLQUFLLEVBQUUsMEdBQTBHO1lBQ3hILEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxTQUFTLEVBQUUscUJBQXFCO1NBQy9DLENBQUMsQ0FBQztRQUNILE9BQU8sZ0JBQWdCLENBQUM7SUFDMUIsQ0FBQzs7QUFoRkgsa0NBaUZDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgZXhpc3RzU3luYyB9IGZyb20gXCJmc1wiO1xuaW1wb3J0IHsgUmVtb3ZhbFBvbGljeSB9IGZyb20gXCJhd3MtY2RrLWxpYlwiO1xuaW1wb3J0IHtcbiAgQXR0cmlidXRlVHlwZSxcbiAgQmlsbGluZyxcbiAgVGFibGVWMixcbiAgVGFibGVQcm9wc1YyLFxuICBJVGFibGVWMixcbn0gZnJvbSBcImF3cy1jZGstbGliL2F3cy1keW5hbW9kYlwiO1xuaW1wb3J0IHtcbiAgQnVja2V0LFxuICBCdWNrZXRFbmNyeXB0aW9uLFxuICBCdWNrZXRQcm9wcyxcbiAgQmxvY2tQdWJsaWNBY2Nlc3MsXG4gIElCdWNrZXQsXG59IGZyb20gXCJhd3MtY2RrLWxpYi9hd3MtczNcIjtcbmltcG9ydCB7XG4gIEJ1Y2tldERlcGxveW1lbnQsXG4gIEJ1Y2tldERlcGxveW1lbnRQcm9wcyxcbiAgU291cmNlLFxufSBmcm9tIFwiYXdzLWNkay1saWIvYXdzLXMzLWRlcGxveW1lbnRcIjtcbmltcG9ydCB7IENvbnN0cnVjdCB9IGZyb20gXCJjb25zdHJ1Y3RzXCI7XG5pbXBvcnQgeyBMT0dfUFJFRklYIH0gZnJvbSBcIi4vY29uc3RhbnRzXCI7XG5cbmV4cG9ydCBpbnRlcmZhY2UgTmV4dGpzQ2FjaGVPdmVycmlkZXMge1xuICByZWFkb25seSBjYWNoZUJ1Y2tldFByb3BzPzogQnVja2V0UHJvcHM7XG4gIHJlYWRvbmx5IHJldmFsaWRhdGlvblRhYmxlUHJvcHM/OiBUYWJsZVByb3BzVjI7XG4gIHJlYWRvbmx5IGJ1Y2tldERlcGxveW1lbnRQcm9wcz86IEJ1Y2tldERlcGxveW1lbnRQcm9wcztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBOZXh0anNDYWNoZVByb3BzIHtcbiAgcmVhZG9ubHkgYnVpbGRJZDogc3RyaW5nO1xuICAvKipcbiAgICogQnJpbmcgeW91ciBvd24gUzMgYnVja2V0IGZvciBjYWNoZSBzdG9yYWdlLiBXaGVuIHByb3ZpZGVkLCBjZGstbmV4dGpzXG4gICAqIHdpbGwgc2tpcCBjcmVhdGluZyBhIG5ldyBidWNrZXQuIENhY2hlIG9iamVjdHMgYXJlIHByZWZpeGVkIHdpdGggYGJ1aWxkSWRgXG4gICAqIHNvIG11bHRpcGxlIGRlcGxveW1lbnRzIGNhbiBzYWZlbHkgc2hhcmUgb25lIGJ1Y2tldC5cbiAgICovXG4gIHJlYWRvbmx5IGNhY2hlQnVja2V0PzogSUJ1Y2tldDtcbiAgLyoqXG4gICAqIEFic29sdXRlIHBhdGggdG8gdGhlIGluaXQgY2FjaGUgZGlyZWN0b3J5XG4gICAqIEBleGFtcGxlIFwiL1VzZXJzL2pvaG4vbXlhcHAvLm5leHQvY2RrLW5leHRqcy1pbml0LWNhY2hlXCJcbiAgICovXG4gIHJlYWRvbmx5IGluaXRDYWNoZURpcjogc3RyaW5nO1xuICByZWFkb25seSBvdmVycmlkZXM/OiBOZXh0anNDYWNoZU92ZXJyaWRlcztcbiAgLyoqXG4gICAqIEJyaW5nIHlvdXIgb3duIER5bmFtb0RCIHRhYmxlIGZvciByZXZhbGlkYXRpb24gbWV0YWRhdGEuIFdoZW4gcHJvdmlkZWQsXG4gICAqIGNkay1uZXh0anMgd2lsbCBza2lwIGNyZWF0aW5nIGEgbmV3IHRhYmxlLiBUaGUgdGFibGUgbXVzdCBoYXZlIGBwa2AgKFN0cmluZylcbiAgICogYXMgcGFydGl0aW9uIGtleSBhbmQgYHNrYCAoU3RyaW5nKSBhcyBzb3J0IGtleS4gRW50cmllcyBhcmUgcGFydGl0aW9uZWQgYnlcbiAgICogYGJ1aWxkSWRgIHNvIG11bHRpcGxlIGRlcGxveW1lbnRzIGNhbiBzYWZlbHkgc2hhcmUgb25lIHRhYmxlLlxuICAgKi9cbiAgcmVhZG9ubHkgcmV2YWxpZGF0aW9uVGFibGU/OiBJVGFibGVWMjtcbn1cblxuLyoqXG4gKiBOZXh0LmpzIENhY2hlIGNvbnN0cnVjdCBwcm92aWRpbmcgdW5pZmllZCBTMyBhbmQgRHluYW1vREIgY2FjaGUgbWFuYWdlbWVudC5cbiAqL1xuZXhwb3J0IGNsYXNzIE5leHRqc0NhY2hlIGV4dGVuZHMgQ29uc3RydWN0IHtcbiAgcmVhZG9ubHkgY2FjaGVCdWNrZXQ6IElCdWNrZXQ7XG4gIHJlYWRvbmx5IHJldmFsaWRhdGlvblRhYmxlOiBJVGFibGVWMjtcbiAgcmVhZG9ubHkgYnVpbGRJZDogc3RyaW5nO1xuICByZWFkb25seSBidWNrZXREZXBsb3ltZW50PzogQnVja2V0RGVwbG95bWVudDtcbiAgcHJpdmF0ZSBwcm9wczogTmV4dGpzQ2FjaGVQcm9wcztcblxuICBjb25zdHJ1Y3RvcihzY29wZTogQ29uc3RydWN0LCBpZDogc3RyaW5nLCBwcm9wczogTmV4dGpzQ2FjaGVQcm9wcykge1xuICAgIHN1cGVyKHNjb3BlLCBpZCk7XG4gICAgdGhpcy5wcm9wcyA9IHByb3BzO1xuICAgIHRoaXMuYnVpbGRJZCA9IHByb3BzLmJ1aWxkSWQ7XG4gICAgdGhpcy5jYWNoZUJ1Y2tldCA9IHByb3BzLmNhY2hlQnVja2V0ID8/IHRoaXMuY3JlYXRlQ2FjaGVCdWNrZXQoKTtcbiAgICB0aGlzLnJldmFsaWRhdGlvblRhYmxlID1cbiAgICAgIHByb3BzLnJldmFsaWRhdGlvblRhYmxlID8/IHRoaXMuY3JlYXRlUmV2YWxpZGF0aW9uVGFibGUoKTtcbiAgICB0aGlzLmJ1Y2tldERlcGxveW1lbnQgPSB0aGlzLmNyZWF0ZURlcGxveW1lbnQoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGVzIFMzIGJ1Y2tldCBmb3IgY2FjaGUgc3RvcmFnZSB3aXRoIEJVSUxEX0lEIHByZWZpeGluZy5cbiAgICovXG4gIHByaXZhdGUgY3JlYXRlQ2FjaGVCdWNrZXQoKTogSUJ1Y2tldCB7XG4gICAgY29uc3QgYnVja2V0ID0gbmV3IEJ1Y2tldCh0aGlzLCBcIkJ1Y2tldFwiLCB7XG4gICAgICBlbmNyeXB0aW9uOiBCdWNrZXRFbmNyeXB0aW9uLlMzX01BTkFHRUQsXG4gICAgICBibG9ja1B1YmxpY0FjY2VzczogQmxvY2tQdWJsaWNBY2Nlc3MuQkxPQ0tfQUxMLFxuICAgICAgcmVtb3ZhbFBvbGljeTogUmVtb3ZhbFBvbGljeS5ERVNUUk9ZLFxuICAgICAgYXV0b0RlbGV0ZU9iamVjdHM6IHRydWUsXG4gICAgICBlbmZvcmNlU1NMOiB0cnVlLFxuICAgICAgLi4udGhpcy5wcm9wcy5vdmVycmlkZXM/LmNhY2hlQnVja2V0UHJvcHMsXG4gICAgfSk7XG5cbiAgICByZXR1cm4gYnVja2V0O1xuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZXMgRHluYW1vREIgdGFibGUgZm9yIHJldmFsaWRhdGlvbiBtZXRhZGF0YVxuICAgKiBTY2hlbWE6IHBrIChidWlsZElkIG9yIFwiTUVUQURBVEFcIiksIHNrICh0YWcjY2FjaGVLZXkgb3IgXCJDVVJSRU5UX0JVSUxEXCIpLCBjcmVhdGVkQXQsIHJldmFsaWRhdGVkQXRcbiAgICovXG4gIHByaXZhdGUgY3JlYXRlUmV2YWxpZGF0aW9uVGFibGUoKTogVGFibGVWMiB7XG4gICAgY29uc3QgdGFibGUgPSBuZXcgVGFibGVWMih0aGlzLCBcIlJldmFsaWRhdGlvblRhYmxlXCIsIHtcbiAgICAgIHBhcnRpdGlvbktleToge1xuICAgICAgICBuYW1lOiBcInBrXCIsXG4gICAgICAgIHR5cGU6IEF0dHJpYnV0ZVR5cGUuU1RSSU5HLFxuICAgICAgfSxcbiAgICAgIHNvcnRLZXk6IHtcbiAgICAgICAgbmFtZTogXCJza1wiLFxuICAgICAgICB0eXBlOiBBdHRyaWJ1dGVUeXBlLlNUUklORyxcbiAgICAgIH0sXG4gICAgICBiaWxsaW5nOiBCaWxsaW5nLm9uRGVtYW5kKCksXG4gICAgICByZW1vdmFsUG9saWN5OiBSZW1vdmFsUG9saWN5LkRFU1RST1ksXG4gICAgICAuLi50aGlzLnByb3BzLm92ZXJyaWRlcz8ucmV2YWxpZGF0aW9uVGFibGVQcm9wcyxcbiAgICB9KTtcblxuICAgIHJldHVybiB0YWJsZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBEZXBsb3kgcHJlLWJ1aWx0IGNhY2hlIGZpbGVzIGZyb20gLm5leHQvY2RrLW5leHRqcy1pbml0LWNhY2hlIHRvIFMzXG4gICAqL1xuICBwcml2YXRlIGNyZWF0ZURlcGxveW1lbnQoKTogQnVja2V0RGVwbG95bWVudCB8IHVuZGVmaW5lZCB7XG4gICAgLy8gQ2hlY2sgaWYgY2FjaGUgZGlyZWN0b3J5IGV4aXN0c1xuICAgIGlmICghZXhpc3RzU3luYyh0aGlzLnByb3BzLmluaXRDYWNoZURpcikpIHtcbiAgICAgIGNvbnNvbGUubG9nKFxuICAgICAgICBgJHtMT0dfUFJFRklYfSBObyBwcmUtYnVpbHQgY2FjaGUgZm91bmQgYXQgJHt0aGlzLnByb3BzLmluaXRDYWNoZURpcn0sIHNraXBwaW5nIGluaXQgY2FjaGUgZGVwbG95bWVudGAsXG4gICAgICApO1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICBjb25zb2xlLmxvZyhcbiAgICAgIGAke0xPR19QUkVGSVh9IERlcGxveWluZyBpbml0IGNhY2hlIGZyb20gJHt0aGlzLnByb3BzLmluaXRDYWNoZURpcn1gLFxuICAgICk7XG5cbiAgICAvLyBVc2Ugc3RhbmRhcmQgQnVja2V0RGVwbG95bWVudCBmb3IgcmVndWxhciBTMyBidWNrZXRzXG4gICAgY29uc3QgYnVja2V0RGVwbG95bWVudCA9IG5ldyBCdWNrZXREZXBsb3ltZW50KHRoaXMsIFwiSW5pdENhY2hlRGVwbG95bWVudFwiLCB7XG4gICAgICBzb3VyY2VzOiBbU291cmNlLmFzc2V0KHRoaXMucHJvcHMuaW5pdENhY2hlRGlyKV0sXG4gICAgICBkZXN0aW5hdGlvbkJ1Y2tldDogdGhpcy5jYWNoZUJ1Y2tldCxcbiAgICAgIGRlc3RpbmF0aW9uS2V5UHJlZml4OiB0aGlzLnByb3BzLmJ1aWxkSWQsIC8vIEFkZCBidWlsZElkIHByZWZpeCB0byBhbGwgdXBsb2FkZWQgZmlsZXNcbiAgICAgIHBydW5lOiBmYWxzZSwgLy8gRG9uJ3QgZGVsZXRlIGV4aXN0aW5nIG9iamVjdHMgdG8gcHJldmVudCA0MDRzIGR1cmluZyBkZXBsb3ltZW50LCBwcnVuaW5nIHdpbGwgYmUgaGFuZGxlZCBieSBwb3N0LWRlcGxveVxuICAgICAgLi4udGhpcy5wcm9wcy5vdmVycmlkZXM/LmJ1Y2tldERlcGxveW1lbnRQcm9wcyxcbiAgICB9KTtcbiAgICByZXR1cm4gYnVja2V0RGVwbG95bWVudDtcbiAgfVxufVxuIl19
|
|
263
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmV4dGpzLWNhY2hlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL25leHRqcy1jYWNoZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUEsMkJBT1k7QUFDWiwyQkFBNEI7QUFDNUIsK0JBQTRCO0FBQzVCLDZDQUFrRDtBQUNsRCwyREFNa0M7QUFDbEMsK0NBTTRCO0FBQzVCLHFFQUl1QztBQUN2QywwREFBNEM7QUFDNUMsMkNBQXVDO0FBQ3ZDLDJDQUF5QztBQUV6Qyw0REFBNEQ7QUFDNUQsTUFBTSw2QkFBNkIsR0FBRyxHQUFHLENBQUM7QUFDMUMsOENBQThDO0FBQzlDLE1BQU0seUJBQXlCLEdBQUcsS0FBSyxDQUFDO0FBRXhDOzs7Ozs7Ozs7R0FTRztBQUNILFNBQVMsV0FBVyxDQUFDLEdBQVcsRUFBRSxHQUFXO0lBQzNDLElBQUksSUFBSSxHQUFHLDZCQUE2QixDQUFDO0lBQ3pDLE9BQU8sSUFBSSxHQUFHLEdBQUcsRUFBRSxDQUFDO1FBQ2xCLElBQUksSUFBSSxDQUFDLENBQUM7SUFDWixDQUFDO0lBQ0QsT0FBTyxJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksRUFBRSxHQUFHLENBQUMsQ0FBQztBQUM3QixDQUFDO0FBRUQsc0VBQXNFO0FBQ3RFLFNBQVMsZUFBZSxDQUFDLEdBQVc7SUFDbEMsSUFBSSxLQUFLLEdBQUcsQ0FBQyxDQUFDO0lBQ2QsS0FBSyxNQUFNLEtBQUssSUFBSSxJQUFBLGdCQUFXLEVBQUMsR0FBRyxFQUFFO1FBQ25DLGFBQWEsRUFBRSxJQUFJO1FBQ25CLFNBQVMsRUFBRSxJQUFJO0tBQ2hCLENBQUMsRUFBRSxDQUFDO1FBQ0gsSUFBSSxLQUFLLENBQUMsTUFBTSxFQUFFLEVBQUUsQ0FBQztZQUNuQixxRUFBcUU7WUFDckUsK0NBQStDO1lBQy9DLE1BQU0sTUFBTSxHQUNWLEtBQUssQ0FBQyxVQUFVLElBQUssS0FBcUMsQ0FBQyxJQUFJLENBQUM7WUFDbEUsS0FBSyxJQUFJLElBQUEsYUFBUSxFQUFDLElBQUEsV0FBSSxFQUFDLE1BQU0sRUFBRSxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUM7UUFDbkQsQ0FBQztJQUNILENBQUM7SUFDRCxPQUFPLEtBQUssQ0FBQztBQUNmLENBQUM7QUEyQ0Q7O0dBRUc7QUFDSCxNQUFhLFdBQVksU0FBUSxzQkFBUzs7SUFDL0IsV0FBVyxDQUFVO0lBQ3JCLGlCQUFpQixDQUFXO0lBQzVCLE9BQU8sQ0FBUztJQUNoQixnQkFBZ0IsQ0FBb0I7SUFDckMsS0FBSyxDQUFtQjtJQUVoQyxZQUFZLEtBQWdCLEVBQUUsRUFBVSxFQUFFLEtBQXVCO1FBQy9ELEtBQUssQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFDakIsSUFBSSxDQUFDLEtBQUssR0FBRyxLQUFLLENBQUM7UUFDbkIsSUFBSSxDQUFDLE9BQU8sR0FBRyxLQUFLLENBQUMsT0FBTyxDQUFDO1FBQzdCLElBQUksQ0FBQyxXQUFXLEdBQUcsS0FBSyxDQUFDLFdBQVcsSUFBSSxJQUFJLENBQUMsaUJBQWlCLEVBQUUsQ0FBQztRQUNqRSxJQUFJLENBQUMsaUJBQWlCO1lBQ3BCLEtBQUssQ0FBQyxpQkFBaUIsSUFBSSxJQUFJLENBQUMsdUJBQXVCLEVBQUUsQ0FBQztRQUM1RCxJQUFJLENBQUMsZ0JBQWdCLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixFQUFFLENBQUM7SUFDbEQsQ0FBQztJQUVEOztPQUVHO0lBQ0ssaUJBQWlCO1FBQ3ZCLE1BQU0sTUFBTSxHQUFHLElBQUksZUFBTSxDQUFDLElBQUksRUFBRSxRQUFRLEVBQUU7WUFDeEMsVUFBVSxFQUFFLHlCQUFnQixDQUFDLFVBQVU7WUFDdkMsaUJBQWlCLEVBQUUsMEJBQWlCLENBQUMsU0FBUztZQUM5QyxhQUFhLEVBQUUsMkJBQWEsQ0FBQyxPQUFPO1lBQ3BDLGlCQUFpQixFQUFFLElBQUk7WUFDdkIsVUFBVSxFQUFFLElBQUk7WUFDaEIsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLFNBQVMsRUFBRSxnQkFBZ0I7U0FDMUMsQ0FBQyxDQUFDO1FBRUgsT0FBTyxNQUFNLENBQUM7SUFDaEIsQ0FBQztJQUVEOzs7Ozs7T0FNRztJQUNLLHVCQUF1QjtRQUM3QixNQUFNLEtBQUssR0FBRyxJQUFJLHNCQUFPLENBQUMsSUFBSSxFQUFFLG1CQUFtQixFQUFFO1lBQ25ELFlBQVksRUFBRTtnQkFDWixJQUFJLEVBQUUsSUFBSTtnQkFDVixJQUFJLEVBQUUsNEJBQWEsQ0FBQyxNQUFNO2FBQzNCO1lBQ0QsT0FBTyxFQUFFO2dCQUNQLElBQUksRUFBRSxJQUFJO2dCQUNWLElBQUksRUFBRSw0QkFBYSxDQUFDLE1BQU07YUFDM0I7WUFDRCxPQUFPLEVBQUUsc0JBQU8sQ0FBQyxRQUFRLEVBQUU7WUFDM0IsYUFBYSxFQUFFLDJCQUFhLENBQUMsT0FBTztZQUNwQyxtQkFBbUIsRUFBRSxLQUFLO1lBQzFCLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxTQUFTLEVBQUUsc0JBQXNCO1NBQ2hELENBQUMsQ0FBQztRQUVILE9BQU8sS0FBSyxDQUFDO0lBQ2YsQ0FBQztJQUVEOztPQUVHO0lBQ0ssZ0JBQWdCO1FBQ3RCLGtDQUFrQztRQUNsQyxJQUFJLENBQUMsSUFBQSxlQUFVLEVBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxZQUFZLENBQUMsRUFBRSxDQUFDO1lBQ3pDLE9BQU8sQ0FBQyxHQUFHLENBQ1QsR0FBRyxzQkFBVSxnQ0FBZ0MsSUFBSSxDQUFDLEtBQUssQ0FBQyxZQUFZLGtDQUFrQyxDQUN2RyxDQUFDO1lBQ0YsT0FBTyxTQUFTLENBQUM7UUFDbkIsQ0FBQztRQUVELE9BQU8sQ0FBQyxHQUFHLENBQ1QsR0FBRyxzQkFBVSw4QkFBOEIsSUFBSSxDQUFDLEtBQUssQ0FBQyxZQUFZLEVBQUUsQ0FDckUsQ0FBQztRQUVGLE1BQU0sVUFBVSxHQUFHLElBQUksQ0FBQyxzQkFBc0IsRUFBRSxDQUFDO1FBRWpELElBQUksQ0FBQztZQUNILHVEQUF1RDtZQUN2RCxNQUFNLGdCQUFnQixHQUFHLElBQUksb0NBQWdCLENBQzNDLElBQUksRUFDSixxQkFBcUIsRUFDckI7Z0JBQ0UsT0FBTyxFQUFFLENBQUMsMEJBQU0sQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDLENBQUM7Z0JBQ25DLGlCQUFpQixFQUFFLElBQUksQ0FBQyxXQUFXO2dCQUNuQyxLQUFLLEVBQUUsS0FBSyxFQUFFLDBHQUEwRztnQkFDeEgsR0FBRyxJQUFJLENBQUMsb0JBQW9CLEVBQUU7Z0JBQzlCLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxTQUFTLEVBQUUscUJBQXFCO2FBQy9DLENBQ0YsQ0FBQztZQUNGLE9BQU8sZ0JBQWdCLENBQUM7UUFDMUIsQ0FBQztnQkFBUyxDQUFDO1lBQ1QseUVBQXlFO1lBQ3pFLHVFQUF1RTtZQUN2RSx3RUFBd0U7WUFDeEUsMkVBQTJFO1lBQzNFLHlFQUF5RTtZQUN6RSxxRUFBcUU7WUFDckUsRUFBRTtZQUNGLHVFQUF1RTtZQUN2RSxxRUFBcUU7WUFDckUsd0VBQXdFO1lBQ3hFLGtEQUFrRDtZQUNsRCxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsS0FBSyxDQUFDLDZCQUE2QixDQUFDLEVBQUUsQ0FBQztnQkFDbEUsSUFBQSxXQUFNLEVBQUMsVUFBVSxFQUFFLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztZQUN2RCxDQUFDO1FBQ0gsQ0FBQztJQUNILENBQUM7SUFFRDs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztPQStCRztJQUNLLG9CQUFvQjtRQUMxQixNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLFlBQVksQ0FBQyxHQUFHLElBQUksSUFBSSxDQUFDLENBQUMsQ0FBQztRQUM1RSxNQUFNLE1BQU0sR0FBRyxHQUFHLEdBQUcsQ0FBQyxHQUFHLEdBQUcsQ0FBQztRQUM3QixJQUFJLE1BQU0sR0FBRyx5QkFBeUIsRUFBRSxDQUFDO1lBQ3ZDLE9BQU8sQ0FBQyxJQUFJLENBQ1YsR0FBRyxzQkFBVSxzQkFBc0IsSUFBSSxDQUFDLEtBQUssQ0FBQyxZQUFZLE9BQU8sR0FBRyxtQ0FBbUMseUJBQXlCLHNKQUFzSixDQUN2UixDQUFDO1FBQ0osQ0FBQztRQUNELE1BQU0sU0FBUyxHQUFHLFdBQVcsQ0FBQyxNQUFNLEVBQUUseUJBQXlCLENBQUMsQ0FBQztRQUVqRSxPQUFPO1lBQ0wsb0JBQW9CLEVBQUUsa0JBQUksQ0FBQyxTQUFTLENBQUMsU0FBUyxDQUFDO1lBQy9DLEdBQUcsQ0FBQyxHQUFHLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLFdBQVcsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO1NBQzVDLENBQUM7SUFDSixDQUFDO0lBRUQ7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7T0E0Qkc7SUFDSyxzQkFBc0I7UUFDNUIsTUFBTSxVQUFVLEdBQUcsSUFBQSxnQkFBVyxFQUFDLElBQUEsV0FBSSxFQUFDLElBQUEsV0FBTSxHQUFFLEVBQUUsb0JBQW9CLENBQUMsQ0FBQyxDQUFDO1FBQ3JFLElBQUEsV0FBTSxFQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsWUFBWSxFQUFFLElBQUEsV0FBSSxFQUFDLFVBQVUsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxFQUFFO1lBQ3BFLFNBQVMsRUFBRSxJQUFJO1NBQ2hCLENBQUMsQ0FBQztRQUNILE9BQU8sVUFBVSxDQUFDO0lBQ3BCLENBQUM7O0FBaE1ILGtDQWlNQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIGNwU3luYyxcbiAgZXhpc3RzU3luYyxcbiAgbWtkdGVtcFN5bmMsXG4gIHJlYWRkaXJTeW5jLFxuICBybVN5bmMsXG4gIHN0YXRTeW5jLFxufSBmcm9tIFwiZnNcIjtcbmltcG9ydCB7IHRtcGRpciB9IGZyb20gXCJvc1wiO1xuaW1wb3J0IHsgam9pbiB9IGZyb20gXCJwYXRoXCI7XG5pbXBvcnQgeyBSZW1vdmFsUG9saWN5LCBTaXplIH0gZnJvbSBcImF3cy1jZGstbGliXCI7XG5pbXBvcnQge1xuICBBdHRyaWJ1dGVUeXBlLFxuICBCaWxsaW5nLFxuICBUYWJsZVYyLFxuICBUYWJsZVByb3BzVjIsXG4gIElUYWJsZVYyLFxufSBmcm9tIFwiYXdzLWNkay1saWIvYXdzLWR5bmFtb2RiXCI7XG5pbXBvcnQge1xuICBCdWNrZXQsXG4gIEJ1Y2tldEVuY3J5cHRpb24sXG4gIEJ1Y2tldFByb3BzLFxuICBCbG9ja1B1YmxpY0FjY2VzcyxcbiAgSUJ1Y2tldCxcbn0gZnJvbSBcImF3cy1jZGstbGliL2F3cy1zM1wiO1xuaW1wb3J0IHtcbiAgQnVja2V0RGVwbG95bWVudCxcbiAgQnVja2V0RGVwbG95bWVudFByb3BzLFxuICBTb3VyY2UsXG59IGZyb20gXCJhd3MtY2RrLWxpYi9hd3MtczMtZGVwbG95bWVudFwiO1xuaW1wb3J0ICogYXMgY3hhcGkgZnJvbSBcImF3cy1jZGstbGliL2N4LWFwaVwiO1xuaW1wb3J0IHsgQ29uc3RydWN0IH0gZnJvbSBcImNvbnN0cnVjdHNcIjtcbmltcG9ydCB7IExPR19QUkVGSVggfSBmcm9tIFwiLi9jb25zdGFudHNcIjtcblxuLyoqIFdoYXQgYSBgQnVja2V0RGVwbG95bWVudGAgTGFtYmRhIGdldHMgd2l0aG91dCBhc2tpbmcuICovXG5jb25zdCBERUZBVUxUX0VQSEVNRVJBTF9TVE9SQUdFX01JQiA9IDUxMjtcbi8qKiBUaGUgbW9zdCBMYW1iZGEgd2lsbCBnaXZlIGFueSBmdW5jdGlvbi4gKi9cbmNvbnN0IE1BWF9FUEhFTUVSQUxfU1RPUkFHRV9NSUIgPSAxMDI0MDtcblxuLyoqXG4gKiBUaGUgc21hbGxlc3QgcG93ZXItb2YtdHdvIE1pQiBzdGVwIGF0IG9yIGFib3ZlIGBtaWJgLCBjYXBwZWQgYXQgYG1heGAuXG4gKlxuICogYEJ1Y2tldERlcGxveW1lbnRgIGZvbGRzIGBlcGhlbWVyYWxTdG9yYWdlU2l6ZWAgaW50byBib3RoIGl0cyBzaW5nbGV0b25cbiAqIGhhbmRsZXIncyBVVUlEIGFuZCBpdHMgY3VzdG9tIHJlc291cmNlJ3MgbG9naWNhbCBJRCwgc28gZXZlcnkgZGlzdGluY3Qgc2l6ZSBpc1xuICogYSBuZXcgaGFuZGxlciBMYW1iZGEsIGEgbmV3IGBTZXJ2aWNlVG9rZW5gLCBhbmQgYSByZXBsYWNlZCBjdXN0b20gcmVzb3VyY2UuXG4gKiBTaXplZCB0byB0aGUgTWlCLCB0aGF0IHdhcyBldmVyeSBkZXBsb3kgd2hvc2UgaW5pdCBjYWNoZSBncmV3IGJ5IG9uZTogYSBmdWxsXG4gKiBDbG91ZEZvcm1hdGlvbiBkZXBsb3ltZW50IHdoZXJlIGEgaG90c3dhcCB3b3VsZCBoYXZlIGRvbmUuIERvdWJsaW5nIHN0ZXBzXG4gKiBjaGFuZ2Ugb25seSB3aGVuIHRoZSBjYWNoZSBkb2VzIGJ5IGEgbGFyZ2UgZnJhY3Rpb24uXG4gKi9cbmZ1bmN0aW9uIHN0b3JhZ2VTdGVwKG1pYjogbnVtYmVyLCBtYXg6IG51bWJlcik6IG51bWJlciB7XG4gIGxldCBzdGVwID0gREVGQVVMVF9FUEhFTUVSQUxfU1RPUkFHRV9NSUI7XG4gIHdoaWxlIChzdGVwIDwgbWliKSB7XG4gICAgc3RlcCAqPSAyO1xuICB9XG4gIHJldHVybiBNYXRoLm1pbihzdGVwLCBtYXgpO1xufVxuXG4vKiogQnl0ZXMgb24gZGlzayB1bmRlciBgZGlyYCwgZm9sbG93aW5nIHRoZSB0cmVlIGJ1dCBub3Qgc3ltbGlua3MuICovXG5mdW5jdGlvbiBzaXplT2ZEaXJlY3RvcnkoZGlyOiBzdHJpbmcpOiBudW1iZXIge1xuICBsZXQgdG90YWwgPSAwO1xuICBmb3IgKGNvbnN0IGVudHJ5IG9mIHJlYWRkaXJTeW5jKGRpciwge1xuICAgIHdpdGhGaWxlVHlwZXM6IHRydWUsXG4gICAgcmVjdXJzaXZlOiB0cnVlLFxuICB9KSkge1xuICAgIGlmIChlbnRyeS5pc0ZpbGUoKSkge1xuICAgICAgLy8gYHBhcmVudFBhdGhgIG9ubHkgZXhpc3RzIGZyb20gTm9kZSAyMC4xMjsgYHBhdGhgIGlzIGl0cyBkZXByZWNhdGVkXG4gICAgICAvLyBwcmVkZWNlc3NvciwgYW5kIHRoZSBvbmx5IG9uZSBvbiAyMC45LTIwLjExLlxuICAgICAgY29uc3QgcGFyZW50ID1cbiAgICAgICAgZW50cnkucGFyZW50UGF0aCA/PyAoZW50cnkgYXMgdW5rbm93biBhcyB7IHBhdGg6IHN0cmluZyB9KS5wYXRoO1xuICAgICAgdG90YWwgKz0gc3RhdFN5bmMoam9pbihwYXJlbnQsIGVudHJ5Lm5hbWUpKS5zaXplO1xuICAgIH1cbiAgfVxuICByZXR1cm4gdG90YWw7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgTmV4dGpzQ2FjaGVPdmVycmlkZXMge1xuICByZWFkb25seSBjYWNoZUJ1Y2tldFByb3BzPzogQnVja2V0UHJvcHM7XG4gIHJlYWRvbmx5IHJldmFsaWRhdGlvblRhYmxlUHJvcHM/OiBUYWJsZVByb3BzVjI7XG4gIHJlYWRvbmx5IGJ1Y2tldERlcGxveW1lbnRQcm9wcz86IEJ1Y2tldERlcGxveW1lbnRQcm9wcztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBOZXh0anNDYWNoZVByb3BzIHtcbiAgcmVhZG9ubHkgYnVpbGRJZDogc3RyaW5nO1xuICAvKipcbiAgICogQnJpbmcgeW91ciBvd24gUzMgYnVja2V0IGZvciBjYWNoZSBzdG9yYWdlLiBXaGVuIHByb3ZpZGVkLCBjZGstbmV4dGpzXG4gICAqIHdpbGwgc2tpcCBjcmVhdGluZyBhIG5ldyBidWNrZXQuXG4gICAqXG4gICAqIFRoZSBidWNrZXQgbXVzdCBiZSBkZWRpY2F0ZWQgdG8gdGhpcyBvbmUgZGVwbG95bWVudC4gRG9uJ3Qgc2hhcmUgaXQgd2l0aFxuICAgKiBhbm90aGVyIGRlcGxveW1lbnQgKGFub3RoZXIgYnJhbmNoLCBzdGFnZSwgb3IgYXBwKTogZXZlcnkgZGVwbG95J3NcbiAgICogcG9zdC1kZXBsb3kgc3RlcCBkZWxldGVzIGV2ZXJ5IG9iamVjdCB1bmRlciBhIHRvcC1sZXZlbCBwcmVmaXggb3RoZXIgdGhhblxuICAgKiB0aGUgY3VycmVudCBgYnVpbGRJZC9gLCB3aGljaCBpbmNsdWRlcyBldmVyeSBvdGhlciBkZXBsb3ltZW50J3MgY2FjaGUuXG4gICAqL1xuICByZWFkb25seSBjYWNoZUJ1Y2tldD86IElCdWNrZXQ7XG4gIC8qKlxuICAgKiBBYnNvbHV0ZSBwYXRoIHRvIHRoZSBpbml0IGNhY2hlIGRpcmVjdG9yeVxuICAgKiBAZXhhbXBsZSBcIi9Vc2Vycy9qb2huL215YXBwLy5uZXh0L2Nkay1uZXh0anMtaW5pdC1jYWNoZVwiXG4gICAqL1xuICByZWFkb25seSBpbml0Q2FjaGVEaXI6IHN0cmluZztcbiAgcmVhZG9ubHkgb3ZlcnJpZGVzPzogTmV4dGpzQ2FjaGVPdmVycmlkZXM7XG4gIC8qKlxuICAgKiBCcmluZyB5b3VyIG93biBEeW5hbW9EQiB0YWJsZSBmb3IgcmV2YWxpZGF0aW9uIG1ldGFkYXRhLiBXaGVuIHByb3ZpZGVkLFxuICAgKiBjZGstbmV4dGpzIHdpbGwgc2tpcCBjcmVhdGluZyBhIG5ldyB0YWJsZS4gVGhlIHRhYmxlIG11c3QgaGF2ZSBgcGtgIChTdHJpbmcpXG4gICAqIGFzIHBhcnRpdGlvbiBrZXkgYW5kIGBza2AgKFN0cmluZykgYXMgc29ydCBrZXkuXG4gICAqIEVuYWJsaW5nIFRUTCBvbiBpdHMgYHR0bGAgYXR0cmlidXRlIGlzIHJlY29tbWVuZGVkOiBlYWNoIHRhZyByZXZhbGlkYXRpb25cbiAgICogd3JpdGVzIGEgcmV2YWxpZGF0aW9uIGxvZyByb3cgdGhhdCBleHBpcmVzIHRocm91Z2ggaXQgYWZ0ZXIgMTUgbWludXRlcy5cbiAgICogV2l0aG91dCBUVEwgdGhvc2Ugcm93cyBhcmUga2VwdCB1bnRpbCBhIGRlcGxveSByZXBsYWNlcyB0aGVpciBidWlsZCwgd2hvc2VcbiAgICogcG9zdC1kZXBsb3kgc3RlcCBkZWxldGVzIHRoZW0uXG4gICAqXG4gICAqIFRoZSB0YWJsZSBtdXN0IGJlIGRlZGljYXRlZCB0byB0aGlzIG9uZSBkZXBsb3ltZW50LiBEb24ndCBzaGFyZSBpdCB3aXRoXG4gICAqIGFub3RoZXIgZGVwbG95bWVudCAoYW5vdGhlciBicmFuY2gsIHN0YWdlLCBvciBhcHApOiBldmVyeSBkZXBsb3knc1xuICAgKiBwb3N0LWRlcGxveSBzdGVwIGRlbGV0ZXMgdGhlIGVudHJpZXMgb2YgdGhlIGJ1aWxkIGl0IGxhc3QgcmVjb3JkZWQgaW4gdGhlXG4gICAqIHRhYmxlLCB3aGljaCB3aXRoIGEgc2hhcmVkIHRhYmxlIGlzIGFub3RoZXIgZGVwbG95bWVudCdzIGxpdmUgYnVpbGQuXG4gICAqL1xuICByZWFkb25seSByZXZhbGlkYXRpb25UYWJsZT86IElUYWJsZVYyO1xufVxuXG4vKipcbiAqIE5leHQuanMgQ2FjaGUgY29uc3RydWN0IHByb3ZpZGluZyB1bmlmaWVkIFMzIGFuZCBEeW5hbW9EQiBjYWNoZSBtYW5hZ2VtZW50LlxuICovXG5leHBvcnQgY2xhc3MgTmV4dGpzQ2FjaGUgZXh0ZW5kcyBDb25zdHJ1Y3Qge1xuICByZWFkb25seSBjYWNoZUJ1Y2tldDogSUJ1Y2tldDtcbiAgcmVhZG9ubHkgcmV2YWxpZGF0aW9uVGFibGU6IElUYWJsZVYyO1xuICByZWFkb25seSBidWlsZElkOiBzdHJpbmc7XG4gIHJlYWRvbmx5IGJ1Y2tldERlcGxveW1lbnQ/OiBCdWNrZXREZXBsb3ltZW50O1xuICBwcml2YXRlIHByb3BzOiBOZXh0anNDYWNoZVByb3BzO1xuXG4gIGNvbnN0cnVjdG9yKHNjb3BlOiBDb25zdHJ1Y3QsIGlkOiBzdHJpbmcsIHByb3BzOiBOZXh0anNDYWNoZVByb3BzKSB7XG4gICAgc3VwZXIoc2NvcGUsIGlkKTtcbiAgICB0aGlzLnByb3BzID0gcHJvcHM7XG4gICAgdGhpcy5idWlsZElkID0gcHJvcHMuYnVpbGRJZDtcbiAgICB0aGlzLmNhY2hlQnVja2V0ID0gcHJvcHMuY2FjaGVCdWNrZXQgPz8gdGhpcy5jcmVhdGVDYWNoZUJ1Y2tldCgpO1xuICAgIHRoaXMucmV2YWxpZGF0aW9uVGFibGUgPVxuICAgICAgcHJvcHMucmV2YWxpZGF0aW9uVGFibGUgPz8gdGhpcy5jcmVhdGVSZXZhbGlkYXRpb25UYWJsZSgpO1xuICAgIHRoaXMuYnVja2V0RGVwbG95bWVudCA9IHRoaXMuY3JlYXRlRGVwbG95bWVudCgpO1xuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZXMgUzMgYnVja2V0IGZvciBjYWNoZSBzdG9yYWdlIHdpdGggQlVJTERfSUQgcHJlZml4aW5nLlxuICAgKi9cbiAgcHJpdmF0ZSBjcmVhdGVDYWNoZUJ1Y2tldCgpOiBJQnVja2V0IHtcbiAgICBjb25zdCBidWNrZXQgPSBuZXcgQnVja2V0KHRoaXMsIFwiQnVja2V0XCIsIHtcbiAgICAgIGVuY3J5cHRpb246IEJ1Y2tldEVuY3J5cHRpb24uUzNfTUFOQUdFRCxcbiAgICAgIGJsb2NrUHVibGljQWNjZXNzOiBCbG9ja1B1YmxpY0FjY2Vzcy5CTE9DS19BTEwsXG4gICAgICByZW1vdmFsUG9saWN5OiBSZW1vdmFsUG9saWN5LkRFU1RST1ksXG4gICAgICBhdXRvRGVsZXRlT2JqZWN0czogdHJ1ZSxcbiAgICAgIGVuZm9yY2VTU0w6IHRydWUsXG4gICAgICAuLi50aGlzLnByb3BzLm92ZXJyaWRlcz8uY2FjaGVCdWNrZXRQcm9wcyxcbiAgICB9KTtcblxuICAgIHJldHVybiBidWNrZXQ7XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlcyBEeW5hbW9EQiB0YWJsZSBmb3IgcmV2YWxpZGF0aW9uIG1ldGFkYXRhXG4gICAqIFNjaGVtYTogcGsgKGJ1aWxkSWQgb3IgXCJNRVRBREFUQVwiKSwgc2sgKHRhZyNjYWNoZUtleSBvciBcIkNVUlJFTlRfQlVJTERcIiksIGNyZWF0ZWRBdCwgcmV2YWxpZGF0ZWRBdFxuICAgKlxuICAgKiBBbHNvIHRoZSBgJ3VzZSBjYWNoZSdgIHJldmFsaWRhdGlvbiBsb2cgKHBrIFwiPGJ1aWxkSWQ+I2xvZ1wiLFxuICAgKiBzayBcIjxlcG9jaC1tcz4jPHRhZz5cIiksIHdob3NlIHJvd3MgZXhwaXJlIHRocm91Z2ggdGhlIGB0dGxgIGF0dHJpYnV0ZS5cbiAgICovXG4gIHByaXZhdGUgY3JlYXRlUmV2YWxpZGF0aW9uVGFibGUoKTogVGFibGVWMiB7XG4gICAgY29uc3QgdGFibGUgPSBuZXcgVGFibGVWMih0aGlzLCBcIlJldmFsaWRhdGlvblRhYmxlXCIsIHtcbiAgICAgIHBhcnRpdGlvbktleToge1xuICAgICAgICBuYW1lOiBcInBrXCIsXG4gICAgICAgIHR5cGU6IEF0dHJpYnV0ZVR5cGUuU1RSSU5HLFxuICAgICAgfSxcbiAgICAgIHNvcnRLZXk6IHtcbiAgICAgICAgbmFtZTogXCJza1wiLFxuICAgICAgICB0eXBlOiBBdHRyaWJ1dGVUeXBlLlNUUklORyxcbiAgICAgIH0sXG4gICAgICBiaWxsaW5nOiBCaWxsaW5nLm9uRGVtYW5kKCksXG4gICAgICByZW1vdmFsUG9saWN5OiBSZW1vdmFsUG9saWN5LkRFU1RST1ksXG4gICAgICB0aW1lVG9MaXZlQXR0cmlidXRlOiBcInR0bFwiLFxuICAgICAgLi4udGhpcy5wcm9wcy5vdmVycmlkZXM/LnJldmFsaWRhdGlvblRhYmxlUHJvcHMsXG4gICAgfSk7XG5cbiAgICByZXR1cm4gdGFibGU7XG4gIH1cblxuICAvKipcbiAgICogRGVwbG95IHByZS1idWlsdCBjYWNoZSBmaWxlcyBmcm9tIC5uZXh0L2Nkay1uZXh0anMtaW5pdC1jYWNoZSB0byBTM1xuICAgKi9cbiAgcHJpdmF0ZSBjcmVhdGVEZXBsb3ltZW50KCk6IEJ1Y2tldERlcGxveW1lbnQgfCB1bmRlZmluZWQge1xuICAgIC8vIENoZWNrIGlmIGNhY2hlIGRpcmVjdG9yeSBleGlzdHNcbiAgICBpZiAoIWV4aXN0c1N5bmModGhpcy5wcm9wcy5pbml0Q2FjaGVEaXIpKSB7XG4gICAgICBjb25zb2xlLmxvZyhcbiAgICAgICAgYCR7TE9HX1BSRUZJWH0gTm8gcHJlLWJ1aWx0IGNhY2hlIGZvdW5kIGF0ICR7dGhpcy5wcm9wcy5pbml0Q2FjaGVEaXJ9LCBza2lwcGluZyBpbml0IGNhY2hlIGRlcGxveW1lbnRgLFxuICAgICAgKTtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgY29uc29sZS5sb2coXG4gICAgICBgJHtMT0dfUFJFRklYfSBEZXBsb3lpbmcgaW5pdCBjYWNoZSBmcm9tICR7dGhpcy5wcm9wcy5pbml0Q2FjaGVEaXJ9YCxcbiAgICApO1xuXG4gICAgY29uc3Qgc3RhZ2luZ0RpciA9IHRoaXMuY3JlYXRlU3RhZ2luZ0RpcmVjdG9yeSgpO1xuXG4gICAgdHJ5IHtcbiAgICAgIC8vIFVzZSBzdGFuZGFyZCBCdWNrZXREZXBsb3ltZW50IGZvciByZWd1bGFyIFMzIGJ1Y2tldHNcbiAgICAgIGNvbnN0IGJ1Y2tldERlcGxveW1lbnQgPSBuZXcgQnVja2V0RGVwbG95bWVudChcbiAgICAgICAgdGhpcyxcbiAgICAgICAgXCJJbml0Q2FjaGVEZXBsb3ltZW50XCIsXG4gICAgICAgIHtcbiAgICAgICAgICBzb3VyY2VzOiBbU291cmNlLmFzc2V0KHN0YWdpbmdEaXIpXSxcbiAgICAgICAgICBkZXN0aW5hdGlvbkJ1Y2tldDogdGhpcy5jYWNoZUJ1Y2tldCxcbiAgICAgICAgICBwcnVuZTogZmFsc2UsIC8vIERvbid0IGRlbGV0ZSBleGlzdGluZyBvYmplY3RzIHRvIHByZXZlbnQgNDA0cyBkdXJpbmcgZGVwbG95bWVudCwgcHJ1bmluZyB3aWxsIGJlIGhhbmRsZWQgYnkgcG9zdC1kZXBsb3lcbiAgICAgICAgICAuLi50aGlzLnNpemVEZXBsb3ltZW50TGFtYmRhKCksXG4gICAgICAgICAgLi4udGhpcy5wcm9wcy5vdmVycmlkZXM/LmJ1Y2tldERlcGxveW1lbnRQcm9wcyxcbiAgICAgICAgfSxcbiAgICAgICk7XG4gICAgICByZXR1cm4gYnVja2V0RGVwbG95bWVudDtcbiAgICB9IGZpbmFsbHkge1xuICAgICAgLy8gYFNvdXJjZS5hc3NldGAgc3RhZ2VzIGR1cmluZyBgQnVja2V0RGVwbG95bWVudGAncyBjb25zdHJ1Y3Rpb24gLSBDREsnc1xuICAgICAgLy8gYEFzc2V0U3RhZ2luZ2AgemlwcyBpbnRvIGBjZGsub3V0YCBmcm9tIGl0cyBvd24gY29uc3RydWN0b3IgLSBzbyB0aGVcbiAgICAgIC8vIHRlbXBvcmFyeSBjb3B5IGlzIGRlYWQgdGhlIG1vbWVudCB0aGF0IHJldHVybnMuIExlYXZpbmcgaXQgd2FzIGEgc2xvd1xuICAgICAgLy8gbGVhayB3aXRoIGEgbGFyZ2UgdW5pdDogdGhlIGluaXQgY2FjaGUgaGFzIGJlZW4gbWVhc3VyZWQgYXQgNjY0IE1pQiwgYW5kXG4gICAgICAvLyBldmVyeSBgY2RrIHN5bnRoYCBsZWZ0IGFub3RoZXIgZnVsbCBjb3B5IGluIHRoZSBzeXN0ZW0gdGVtcCBkaXJlY3RvcnksXG4gICAgICAvLyBzbyBhIENJIGxvb3Agb2YgfjIyIGRlcGxveXMgY291bGQgcHV0IH4xNSBHQiBvbiB0aGUgcnVubmVyJ3MgZGlzay5cbiAgICAgIC8vXG4gICAgICAvLyBVbmxlc3Mgc3RhZ2luZyBpcyBkaXNhYmxlZCAoYGNkayBzeW50aCAtLW5vLXN0YWdpbmdgLCBhbmQgU0FNLCB3aGljaFxuICAgICAgLy8gc2V0cyB0aGUgc2FtZSBjb250ZXh0KTogdGhlbiBub3RoaW5nIGlzIGNvcGllZCBpbnRvIGBjZGsub3V0YCwgdGhlXG4gICAgICAvLyBhc3NldCBtYW5pZmVzdCBwb2ludHMgYXQgdGhpcyBkaXJlY3RvcnkgaXRzZWxmLCBhbmQgcmVtb3ZpbmcgaXQgZmFpbHNcbiAgICAgIC8vIHRoZSBwdWJsaXNoIHRoYXQgZm9sbG93cyB0aGUgc3ludGggd2l0aCBFTk9FTlQuXG4gICAgICBpZiAoIXRoaXMubm9kZS50cnlHZXRDb250ZXh0KGN4YXBpLkRJU0FCTEVfQVNTRVRfU1RBR0lOR19DT05URVhUKSkge1xuICAgICAgICBybVN5bmMoc3RhZ2luZ0RpciwgeyByZWN1cnNpdmU6IHRydWUsIGZvcmNlOiB0cnVlIH0pO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBgL3RtcGAgYW5kIG1lbW9yeSBmb3IgYEJ1Y2tldERlcGxveW1lbnRgJ3MgdW56aXAgTGFtYmRhLCBzY2FsZWQgdG8gdGhlIGluaXRcbiAgICogY2FjaGUgaXQgaGFzIHRvIHVucGFjay5cbiAgICpcbiAgICogVGhhdCBMYW1iZGEgZG93bmxvYWRzIHRoZSBhc3NldCB6aXAgaW50byBgL3RtcGAgYW5kIHRoZW4gZXh0cmFjdHMgaXRcbiAgICogYWxvbmdzaWRlLCBzbyBpdCBuZWVkcyByb29tIGZvciBib3RoIGF0IG9uY2UuIENESyBkZWZhdWx0cyBpdCB0byA1MTIgTWlCIG9mXG4gICAqIGVwaGVtZXJhbCBzdG9yYWdlIGFuZCAxMjggTUIgb2YgbWVtb3J5IOKAlCBmaW5lIGZvciBhIHNtYWxsIGFwcCwgYW5kIGEgaGFyZFxuICAgKiBmYWlsdXJlIGZvciBvbmUgd2hvc2UgcHJlcmVuZGVyZWQgcGF5bG9hZHMgYXJlIGxhcmdlLiBBIGZpeHR1cmUgd2l0aCA2MFxuICAgKiBzdGF0aWNhbGx5IGdlbmVyYXRlZCBwYWdlcyBjYXJyeWluZyB+MSBNQiBvZiBSU0MgZWFjaCBwcm9kdWNlZCBhIDY2NCBNaUJcbiAgICogc2VlZCBkaXJlY3RvcnkgYW5kIHRoZSBoYW5kbGVyIGRpZWQgb25cbiAgICogYE9TRXJyb3I6IFtFcnJubyAyOF0gTm8gc3BhY2UgbGVmdCBvbiBkZXZpY2VgIGluc2lkZSBgemlwLmV4dHJhY3RhbGxgLlxuICAgKiBXb3JzZSwgYGNkayBkZXBsb3kgLS1ob3Rzd2FwYCBpbnZva2VzIHRoZSBjdXN0b20gcmVzb3VyY2UgZGlyZWN0bHkgd2l0aCBhXG4gICAqIHBsYWNlaG9sZGVyIHJlc3BvbnNlIFVSTCwgc28gdGhlIGBTdGF0dXM6IEZBSUxFRGAgaXQgc2VuZHMgZ29lcyBub3doZXJlOiB0aGVcbiAgICogQ0xJIHByaW50cyBcIkNvbnRlbnRzIG9mIEFXUzo6UzM6OkJ1Y2tldCDigKYgaG90c3dhcHBlZCFcIiwgZXhpdHMgMCwgYW5kIHRoZSBhcHBcbiAgICogY29tZXMgdXAgc2VydmluZyBhICpwYXJ0aWFsbHkqIHNlZWRlZCBjYWNoZS4gRXZlcnkgcm91dGUgd2hvc2UgZW50cnkgZGlkIG5vdFxuICAgKiBtYWtlIGl0IGlzIHRoZW4gYSBtaXNzIHRoYXQgcmUtcmVuZGVycyDigJQgd2hpY2gsIGZvciBhXG4gICAqIGBjYWNoZUNvbXBvbmVudHM6IHRydWVgIGFwcCwgbWVhbnMgYSBwb3N0cG9uZWQgc2hlbGwgd2hlcmUgdGhlIHByZXJlbmRlclxuICAgKiBzaG91bGQgaGF2ZSBiZWVuLlxuICAgKlxuICAgKiBUaGUgemlwJ3MgY29tcHJlc3NlZCBzaXplIGlzIG5vdCBrbm93biBhdCBzeW50aCB0aW1lIChDREsgYXJjaGl2ZXMgdGhlIGFzc2V0XG4gICAqIGxhdGVyKSwgc28gdGhlIHdvcnN0IGNhc2Ug4oCUIGFuIGluY29tcHJlc3NpYmxlIHBheWxvYWQg4oCUIGlzIHdoYXQgZ2V0c1xuICAgKiBidWRnZXRlZDogdHdpY2UgdGhlIGRpcmVjdG9yeSwgcGx1cyBoZWFkcm9vbSwgcm91bmRlZCB1cCB0byBhXG4gICAqIHtAbGluayBzdG9yYWdlU3RlcH0uIE1lbW9yeSBpcyBvbmx5IHJhaXNlZCBwYXN0XG4gICAqIENESydzIGRlZmF1bHQgZm9yIGNhY2hlcyBiaWcgZW5vdWdoIHRoYXQgMTI4IE1CJ3Mgc2xpY2Ugb2YgYSB2Q1BVIHdvdWxkIG1ha2VcbiAgICogdGhlIHVuemlwIGFuZCB1cGxvYWQgcmFjZSB0aGUgY3VzdG9tIHJlc291cmNlJ3MgMTUtbWludXRlIHRpbWVvdXQ7IHNtYWxsXG4gICAqIGFwcHMga2VlcCB0aGUgY2hlYXBlciBkZWZhdWx0IGFuZCB0aGVpciBleGlzdGluZyB0ZW1wbGF0ZS5cbiAgICpcbiAgICogQWJvdmUgdGhlIDEwIEdpQiBlcGhlbWVyYWwtc3RvcmFnZSBjZWlsaW5nIHRoZXJlIGlzIG5vdGhpbmcgbGVmdCB0byBhc2sgZm9yLFxuICAgKiBzbyB0aGlzIHdhcm5zIGFuZCBsZXRzIHRoZSBkZXBsb3ltZW50IGZhaWwgbG91ZGx5IHJhdGhlciB0aGFuIHByZXRlbmQuXG4gICAqIGBvdmVycmlkZXMuYnVja2V0RGVwbG95bWVudFByb3BzYCB3aW5zIG92ZXIgZXZlcnl0aGluZyBoZXJlLCBpbmNsdWRpbmdcbiAgICogYHVzZUVmczogdHJ1ZWAsIHdoaWNoIGlzIHRoZSBzdXBwb3J0ZWQgd2F5IG91dC5cbiAgICovXG4gIHByaXZhdGUgc2l6ZURlcGxveW1lbnRMYW1iZGEoKSB7XG4gICAgY29uc3QgbWliID0gTWF0aC5jZWlsKHNpemVPZkRpcmVjdG9yeSh0aGlzLnByb3BzLmluaXRDYWNoZURpcikgLyAxMDI0ICoqIDIpO1xuICAgIGNvbnN0IHdhbnRlZCA9IG1pYiAqIDIgKyAxMjg7XG4gICAgaWYgKHdhbnRlZCA+IE1BWF9FUEhFTUVSQUxfU1RPUkFHRV9NSUIpIHtcbiAgICAgIGNvbnNvbGUud2FybihcbiAgICAgICAgYCR7TE9HX1BSRUZJWH0gVGhlIGluaXQgY2FjaGUgYXQgJHt0aGlzLnByb3BzLmluaXRDYWNoZURpcn0gaXMgJHttaWJ9IE1pQiwgd2hpY2ggZG9lcyBub3QgZml0IGluIHRoZSAke01BWF9FUEhFTUVSQUxfU1RPUkFHRV9NSUJ9IE1pQiBvZiBlcGhlbWVyYWwgc3RvcmFnZSBhIEJ1Y2tldERlcGxveW1lbnQgTGFtYmRhIGNhbiBiZSBnaXZlbi4gUGFzcyBvdmVycmlkZXMuYnVja2V0RGVwbG95bWVudFByb3BzIHdpdGggdXNlRWZzOiB0cnVlIHRvIHNlZWQgYSBjYWNoZSB0aGlzIGxhcmdlLmAsXG4gICAgICApO1xuICAgIH1cbiAgICBjb25zdCBlcGhlbWVyYWwgPSBzdG9yYWdlU3RlcCh3YW50ZWQsIE1BWF9FUEhFTUVSQUxfU1RPUkFHRV9NSUIpO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIGVwaGVtZXJhbFN0b3JhZ2VTaXplOiBTaXplLm1lYmlieXRlcyhlcGhlbWVyYWwpLFxuICAgICAgLi4uKG1pYiA+IDI1NiA/IHsgbWVtb3J5TGltaXQ6IDEwMjQgfSA6IHt9KSxcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIFN0YWdlIHRoZSBpbml0IGNhY2hlIHVuZGVyIGEgYGJ1aWxkSWRgIGRpcmVjdG9yeSwgc28gdGhhdCB0aGUgb2JqZWN0cyBsYW5kXG4gICAqIGF0IGA8YnVpbGRJZD4vPGtleT5gIHdpdGhvdXQgYSBgZGVzdGluYXRpb25LZXlQcmVmaXhgLlxuICAgKlxuICAgKiBUaGUga2V5cyBoYXZlIHRvIGNhcnJ5IHRoZSBidWlsZCBJRCDigJQgdGhhdCBpcyBob3cgdGhlIHJ1bnRpbWUgY2FjaGUgaGFuZGxlclxuICAgKiBhbmQgdGhlIHBvc3QtZGVwbG95IHBydW5lciBuYW1lc3BhY2Ugb25lIGRlcGxveW1lbnQncyBlbnRyaWVzIGZyb20gdGhlIG5leHRcbiAgICogKGBzcmMvYWRhcHRlci9zMy1jYWNoZS1oYW5kbGVyLnRzYCkuIEFza2luZyBgQnVja2V0RGVwbG95bWVudGAgZm9yIGl0LCBhc1xuICAgKiB0aGlzIHVzZWQgdG8sIGlzIHdoYXQgY29zdHM6IGl0IHVuY29uZGl0aW9uYWxseSB0YWdzIHRoZSAqZGVzdGluYXRpb25cbiAgICogYnVja2V0KiB3aXRoIGBhd3MtY2RrOmNyLW93bmVkOjxkZXN0aW5hdGlvbktleVByZWZpeD46PGhhc2g+YCwgc28gYSBwcmVmaXhcbiAgICogdGhhdCBjaGFuZ2VzIHBlciBidWlsZCBtYWtlcyB0aGUgYnVja2V0J3MgYFRhZ3NgIGNoYW5nZSBwZXIgYnVpbGQuXG4gICAqIGBBV1M6OlMzOjpCdWNrZXRgIGBUYWdzYCBhcmUgbm90IGhvdHN3YXBwYWJsZSwgc28gYGNkayBkZXBsb3lcbiAgICogLS1ob3Rzd2FwLWZhbGxiYWNrYCByZWplY3RlZCB0aGUgZGlmZiBhbmQgZmVsbCBiYWNrIHRvIGEgZnVsbCBDbG91ZEZvcm1hdGlvblxuICAgKiBkZXBsb3ltZW50IGV2ZXJ5IHNpbmdsZSB0aW1lIOKAlCBtZWFzdXJlZCBhdCAxOSBvZiAyMiBkZXBsb3lzIGluIG9uZSBoYXJuZXNzXG4gICAqIHJ1biwgfjExMHMgZWFjaCBhZ2FpbnN0IGEgfjUycyBob3Rzd2FwLlxuICAgKlxuICAgKiBQdXR0aW5nIHRoZSBidWlsZCBJRCBpbiB0aGUgYXNzZXQncyBvd24gcGF0aHMgaW5zdGVhZCBsZWF2ZXMgdGhlIFMzIGtleXNcbiAgICogYnl0ZS1pZGVudGljYWwgYW5kIHRoZSB0YWcga2V5IGNvbnN0YW50IChgYXdzLWNkazpjci1vd25lZDo8aGFzaD5gLCBkZXJpdmVkXG4gICAqIGZyb20gdGhlIGNvbnN0cnVjdCBwYXRoKS4gTm90aGluZyBlbHNlIHJlYWQgdGhlIHByZWZpeDogYHBydW5lYCBpcyBhbHJlYWR5XG4gICAqIGBmYWxzZWAsIGFuZCB0aGUgdHdvIGhhbmRsZXIgYnJhbmNoZXMgdGhhdCBkbyBzY29wZSB3b3JrIHRvIGl0IOKAlCBlbXB0eWluZ1xuICAgKiB0aGUgcHJlZml4IG9uIGRlbGV0ZSwgYW5kIGRlbGV0aW5nIHRoZSBvbGQgcHJlZml4IHdoZW4gdGhlIGRlc3RpbmF0aW9uXG4gICAqIGNoYW5nZXMg4oCUIGFyZSBib3RoIGdhdGVkIG9uIGByZXRhaW5PbkRlbGV0ZWAsIHdoaWNoIGBCdWNrZXREZXBsb3ltZW50YFxuICAgKiBkZWZhdWx0cyB0byBgdHJ1ZWAuXG4gICAqXG4gICAqIEEgY29weSByYXRoZXIgdGhhbiB0aGUgZGlyZWN0b3J5IGl0c2VsZiBiZWNhdXNlIHRoZSBidWlsZCBJRCBpcyBvbmx5IGtub3duXG4gICAqICphZnRlciogYG5leHQgYnVpbGRgLCBzbyB0aGUgYWRhcHRlciBjYW5ub3Qgd3JpdGUgaW50byBhIG5lc3RlZCBkaXJlY3RvcnkgaW5cbiAgICogdGhlIGZpcnN0IHBsYWNlLCBhbmQgYmVjYXVzZSBgLm5leHQvY2RrLW5leHRqcy1pbml0LWNhY2hlYCBoYXMgdG8gc3RheSB3aGVyZVxuICAgKiBpdCBpcyBmb3IgdGhlIGxvY2FsIGNhY2hlIGhhbmRsZXIgdG8gcmVhZCBpdCAoYENES19ORVhUSlNfSU5JVF9DQUNIRV9ESVJgKS5cbiAgICogQ0RLIGlzIGFib3V0IHRvIHJlYWQgZXZlcnkgYnl0ZSBvZiB0aGlzIHRvIHppcCBpdCByZWdhcmRsZXNzLlxuICAgKi9cbiAgcHJpdmF0ZSBjcmVhdGVTdGFnaW5nRGlyZWN0b3J5KCk6IHN0cmluZyB7XG4gICAgY29uc3Qgc3RhZ2luZ0RpciA9IG1rZHRlbXBTeW5jKGpvaW4odG1wZGlyKCksIFwibmV4dGpzLWluaXQtY2FjaGUtXCIpKTtcbiAgICBjcFN5bmModGhpcy5wcm9wcy5pbml0Q2FjaGVEaXIsIGpvaW4oc3RhZ2luZ0RpciwgdGhpcy5wcm9wcy5idWlsZElkKSwge1xuICAgICAgcmVjdXJzaXZlOiB0cnVlLFxuICAgIH0pO1xuICAgIHJldHVybiBzdGFnaW5nRGlyO1xuICB9XG59XG4iXX0=
|
package/lib/nextjs-cache.test.js
CHANGED
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
/* eslint-disable import/no-extraneous-dependencies */
|
|
4
|
+
const fs_1 = require("fs");
|
|
5
|
+
const os_1 = require("os");
|
|
6
|
+
const path_1 = require("path");
|
|
4
7
|
const aws_cdk_lib_1 = require("aws-cdk-lib");
|
|
5
8
|
const assertions_1 = require("aws-cdk-lib/assertions");
|
|
6
9
|
const aws_dynamodb_1 = require("aws-cdk-lib/aws-dynamodb");
|
|
10
|
+
const aws_s3_1 = require("aws-cdk-lib/aws-s3");
|
|
11
|
+
const aws_s3_deployment_1 = require("aws-cdk-lib/aws-s3-deployment");
|
|
7
12
|
const nextjs_cache_1 = require("./nextjs-cache");
|
|
8
13
|
describe("NextjsCache", () => {
|
|
9
14
|
let app;
|
|
@@ -65,6 +70,16 @@ describe("NextjsCache", () => {
|
|
|
65
70
|
BillingMode: "PAY_PER_REQUEST",
|
|
66
71
|
});
|
|
67
72
|
});
|
|
73
|
+
// The 'use cache' revalidation log's rows expire through `ttl`.
|
|
74
|
+
it("expires revalidation log rows through a TTL attribute", () => {
|
|
75
|
+
new nextjs_cache_1.NextjsCache(stack, "TestCache", {
|
|
76
|
+
buildId: "test-build-123",
|
|
77
|
+
initCacheDir: "/tmp/test-cache",
|
|
78
|
+
});
|
|
79
|
+
assertions_1.Template.fromStack(stack).hasResourceProperties("AWS::DynamoDB::GlobalTable", {
|
|
80
|
+
TimeToLiveSpecification: { AttributeName: "ttl", Enabled: true },
|
|
81
|
+
});
|
|
82
|
+
});
|
|
68
83
|
it("should apply custom overrides", () => {
|
|
69
84
|
new nextjs_cache_1.NextjsCache(stack, "TestCache", {
|
|
70
85
|
buildId: "test-build-123",
|
|
@@ -83,6 +98,7 @@ describe("NextjsCache", () => {
|
|
|
83
98
|
name: "cacheKey",
|
|
84
99
|
type: aws_dynamodb_1.AttributeType.STRING,
|
|
85
100
|
},
|
|
101
|
+
timeToLiveAttribute: "expiresAt",
|
|
86
102
|
},
|
|
87
103
|
},
|
|
88
104
|
});
|
|
@@ -92,8 +108,167 @@ describe("NextjsCache", () => {
|
|
|
92
108
|
});
|
|
93
109
|
template.hasResourceProperties("AWS::DynamoDB::GlobalTable", {
|
|
94
110
|
TableName: "custom-revalidation-table",
|
|
111
|
+
TimeToLiveSpecification: { AttributeName: "expiresAt", Enabled: true },
|
|
112
|
+
});
|
|
113
|
+
});
|
|
114
|
+
});
|
|
115
|
+
describe("Init cache deployment", () => {
|
|
116
|
+
let initCacheDir;
|
|
117
|
+
let outdir;
|
|
118
|
+
beforeEach(() => {
|
|
119
|
+
initCacheDir = (0, fs_1.mkdtempSync)((0, path_1.join)((0, os_1.tmpdir)(), "init-cache-src-"));
|
|
120
|
+
(0, fs_1.mkdirSync)((0, path_1.join)(initCacheDir, "server", "app"), { recursive: true });
|
|
121
|
+
(0, fs_1.writeFileSync)((0, path_1.join)(initCacheDir, "server", "app", "index.html"), "<p/>");
|
|
122
|
+
outdir = (0, fs_1.mkdtempSync)((0, path_1.join)((0, os_1.tmpdir)(), "init-cache-out-"));
|
|
123
|
+
});
|
|
124
|
+
afterEach(() => {
|
|
125
|
+
(0, fs_1.rmSync)(initCacheDir, { recursive: true, force: true });
|
|
126
|
+
(0, fs_1.rmSync)(outdir, { recursive: true, force: true });
|
|
127
|
+
});
|
|
128
|
+
/**
|
|
129
|
+
* The tag `BucketDeployment` stamps on its destination bucket, and the only
|
|
130
|
+
* one that can vary between two builds. `Tags` on an `AWS::S3::Bucket` are
|
|
131
|
+
* not hotswappable, so a tag key that carries the build ID costs a full
|
|
132
|
+
* CloudFormation deployment on every deploy.
|
|
133
|
+
*/
|
|
134
|
+
function ownerTags(template) {
|
|
135
|
+
const buckets = template.findResources("AWS::S3::Bucket");
|
|
136
|
+
return Object.values(buckets)
|
|
137
|
+
.flatMap((bucket) => bucket.Properties?.Tags ?? [])
|
|
138
|
+
.map((tag) => tag.Key)
|
|
139
|
+
.filter((key) => key.startsWith("aws-cdk:cr-owned"));
|
|
140
|
+
}
|
|
141
|
+
function synth(buildId) {
|
|
142
|
+
const ownApp = new aws_cdk_lib_1.App({ outdir: (0, fs_1.mkdtempSync)((0, path_1.join)(outdir, "app-")) });
|
|
143
|
+
const ownStack = new aws_cdk_lib_1.Stack(ownApp, "TestStack");
|
|
144
|
+
new nextjs_cache_1.NextjsCache(ownStack, "TestCache", { buildId, initCacheDir });
|
|
145
|
+
return { app: ownApp, template: assertions_1.Template.fromStack(ownStack) };
|
|
146
|
+
}
|
|
147
|
+
it("keys the objects under the build ID without a destinationKeyPrefix", () => {
|
|
148
|
+
const { app: ownApp, template } = synth("build-abc123");
|
|
149
|
+
// Not `DestinationBucketKeyPrefix: Match.absent()` on its own: that would
|
|
150
|
+
// also pass if the staged tree had lost the build ID, which is what keeps
|
|
151
|
+
// the S3 keys the same as before this moved.
|
|
152
|
+
const deployments = template.findResources("Custom::CDKBucketDeployment");
|
|
153
|
+
expect(Object.keys(deployments)).toHaveLength(1);
|
|
154
|
+
expect(Object.values(deployments)[0].Properties).not.toHaveProperty("DestinationBucketKeyPrefix");
|
|
155
|
+
const assembly = ownApp.synth();
|
|
156
|
+
const stagedUnderBuildId = (0, fs_1.readdirSync)(assembly.directory, {
|
|
157
|
+
withFileTypes: true,
|
|
158
|
+
}).some((entry) => entry.isDirectory() &&
|
|
159
|
+
entry.name.startsWith("asset.") &&
|
|
160
|
+
(0, fs_1.readdirSync)((0, path_1.join)(assembly.directory, entry.name)).includes("build-abc123"));
|
|
161
|
+
expect(stagedUnderBuildId).toBe(true);
|
|
162
|
+
});
|
|
163
|
+
it("removes its temporary staging copy once the asset is staged", () => {
|
|
164
|
+
// `Source.asset` stages during `BucketDeployment`'s construction, so the
|
|
165
|
+
// copy is dead as soon as that returns - and it is a whole init cache,
|
|
166
|
+
// measured at 664 MiB. Leaving one per synth put ~15 GB in the system temp
|
|
167
|
+
// directory over a CI loop of ~22 deploys.
|
|
168
|
+
const existing = new Set((0, fs_1.readdirSync)((0, os_1.tmpdir)()).filter((name) => name.startsWith("nextjs-init-cache-")));
|
|
169
|
+
synth("build-abc123").app.synth();
|
|
170
|
+
const leaked = (0, fs_1.readdirSync)((0, os_1.tmpdir)()).filter((name) => name.startsWith("nextjs-init-cache-") && !existing.has(name));
|
|
171
|
+
expect(leaked).toEqual([]);
|
|
172
|
+
});
|
|
173
|
+
it("tags the cache bucket the same way whatever the build ID", () => {
|
|
174
|
+
const first = ownerTags(synth("build-abc123").template);
|
|
175
|
+
const second = ownerTags(synth("build-def456").template);
|
|
176
|
+
expect(first).toHaveLength(1);
|
|
177
|
+
expect(first[0]).toMatch(/^aws-cdk:cr-owned:[0-9a-f]{8}$/);
|
|
178
|
+
expect(second).toEqual(first);
|
|
179
|
+
});
|
|
180
|
+
/**
|
|
181
|
+
* The unzip Lambda holds the asset zip and its extracted contents in `/tmp`
|
|
182
|
+
* at once, so a seed directory bigger than the 512 MiB CDK asks for by
|
|
183
|
+
* default kills it with `[Errno 28] No space left on device` — and under
|
|
184
|
+
* `cdk deploy --hotswap` that failure is invisible, because the CLI hands the
|
|
185
|
+
* custom resource a placeholder response URL and never reads its status.
|
|
186
|
+
*/
|
|
187
|
+
function deploymentLambda(template) {
|
|
188
|
+
const functions = template.findResources("AWS::Lambda::Function", {
|
|
189
|
+
Properties: {
|
|
190
|
+
Handler: "index.handler",
|
|
191
|
+
Runtime: assertions_1.Match.stringLikeRegexp("^python"),
|
|
192
|
+
},
|
|
193
|
+
});
|
|
194
|
+
expect(Object.keys(functions)).toHaveLength(1);
|
|
195
|
+
return Object.values(functions)[0].Properties;
|
|
196
|
+
}
|
|
197
|
+
it("leaves a small init cache on the default Lambda sizing", () => {
|
|
198
|
+
const properties = deploymentLambda(synth("build-abc123").template);
|
|
199
|
+
// The floor, not a computed value: a handful of bytes still wants 512 MiB
|
|
200
|
+
// because that is the least Lambda will give.
|
|
201
|
+
expect(properties.EphemeralStorage).toEqual({ Size: 512 });
|
|
202
|
+
// Absent, not 128: leaving `memoryLimit` alone keeps the property out of
|
|
203
|
+
// the template, which is Lambda's own 128 MB default.
|
|
204
|
+
expect(properties.MemorySize).toBeUndefined();
|
|
205
|
+
});
|
|
206
|
+
it("scales /tmp and memory to a large init cache", () => {
|
|
207
|
+
// A sparse file: `statSync` reports 300 MiB, the filesystem stores almost
|
|
208
|
+
// nothing, and the zip of a 300 MiB hole costs no real work.
|
|
209
|
+
const big = (0, path_1.join)(initCacheDir, "server", "app", "big.rsc");
|
|
210
|
+
(0, fs_1.writeFileSync)(big, "");
|
|
211
|
+
(0, fs_1.truncateSync)(big, 300 * 1024 * 1024);
|
|
212
|
+
const properties = deploymentLambda(synth("build-abc123").template);
|
|
213
|
+
// 301 MiB of cache — the 300 MiB hole plus the fixture's own file, rounded
|
|
214
|
+
// up — doubled for the zip that sits beside it, plus headroom: 730 MiB,
|
|
215
|
+
// rounded up to the next step.
|
|
216
|
+
expect(properties.EphemeralStorage).toEqual({ Size: 1024 });
|
|
217
|
+
expect(properties.MemorySize).toBe(1024);
|
|
218
|
+
});
|
|
219
|
+
it("keeps the deployment's identity while the cache grows by a little", () => {
|
|
220
|
+
// `ephemeralStorageSize` is part of the singleton handler's UUID and the
|
|
221
|
+
// custom resource's logical ID. Sized to the MiB, a cache 5 MiB bigger
|
|
222
|
+
// than the last deploy's was a new handler Lambda, a new ServiceToken
|
|
223
|
+
// and a replaced custom resource - a full deployment, not a hotswap.
|
|
224
|
+
const big = (0, path_1.join)(initCacheDir, "server", "app", "big.rsc");
|
|
225
|
+
const logicalIds = (mib) => {
|
|
226
|
+
(0, fs_1.writeFileSync)(big, "");
|
|
227
|
+
(0, fs_1.truncateSync)(big, mib * 1024 * 1024);
|
|
228
|
+
const template = synth("build-abc123").template;
|
|
229
|
+
return [
|
|
230
|
+
...Object.keys(template.findResources("Custom::CDKBucketDeployment")),
|
|
231
|
+
...Object.keys(template.findResources("AWS::Lambda::Function")),
|
|
232
|
+
].sort();
|
|
233
|
+
};
|
|
234
|
+
expect(logicalIds(305)).toEqual(logicalIds(300));
|
|
235
|
+
});
|
|
236
|
+
it("keeps the staging copy when asset staging is disabled", () => {
|
|
237
|
+
// `--no-staging` (and SAM) leaves the asset where it is rather than
|
|
238
|
+
// copying it into `cdk.out`, so the staging copy *is* the asset, and the
|
|
239
|
+
// publish after synth needs it.
|
|
240
|
+
const ownApp = new aws_cdk_lib_1.App({
|
|
241
|
+
outdir: (0, fs_1.mkdtempSync)((0, path_1.join)(outdir, "app-")),
|
|
242
|
+
context: { "aws:cdk:disable-asset-staging": true },
|
|
243
|
+
});
|
|
244
|
+
const existing = new Set((0, fs_1.readdirSync)((0, os_1.tmpdir)()).filter((name) => name.startsWith("nextjs-init-cache-")));
|
|
245
|
+
new nextjs_cache_1.NextjsCache(new aws_cdk_lib_1.Stack(ownApp, "TestStack"), "TestCache", {
|
|
246
|
+
buildId: "build-abc123",
|
|
247
|
+
initCacheDir,
|
|
248
|
+
});
|
|
249
|
+
const kept = (0, fs_1.readdirSync)((0, os_1.tmpdir)()).filter((name) => name.startsWith("nextjs-init-cache-") && !existing.has(name));
|
|
250
|
+
expect(kept).toHaveLength(1);
|
|
251
|
+
(0, fs_1.rmSync)((0, path_1.join)((0, os_1.tmpdir)(), kept[0]), { recursive: true, force: true });
|
|
252
|
+
});
|
|
253
|
+
it("lets overrides win over the computed sizing", () => {
|
|
254
|
+
const ownApp = new aws_cdk_lib_1.App({ outdir: (0, fs_1.mkdtempSync)((0, path_1.join)(outdir, "app-")) });
|
|
255
|
+
const ownStack = new aws_cdk_lib_1.Stack(ownApp, "TestStack");
|
|
256
|
+
new nextjs_cache_1.NextjsCache(ownStack, "TestCache", {
|
|
257
|
+
buildId: "build-abc123",
|
|
258
|
+
initCacheDir,
|
|
259
|
+
overrides: {
|
|
260
|
+
bucketDeploymentProps: {
|
|
261
|
+
destinationBucket: aws_s3_1.Bucket.fromBucketName(ownStack, "Existing", "someone-elses-bucket"),
|
|
262
|
+
sources: [aws_s3_deployment_1.Source.data("marker", "x")],
|
|
263
|
+
ephemeralStorageSize: aws_cdk_lib_1.Size.gibibytes(2),
|
|
264
|
+
memoryLimit: 2048,
|
|
265
|
+
},
|
|
266
|
+
},
|
|
95
267
|
});
|
|
268
|
+
const properties = deploymentLambda(assertions_1.Template.fromStack(ownStack));
|
|
269
|
+
expect(properties.EphemeralStorage).toEqual({ Size: 2048 });
|
|
270
|
+
expect(properties.MemorySize).toBe(2048);
|
|
96
271
|
});
|
|
97
272
|
});
|
|
98
273
|
});
|
|
99
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmV4dGpzLWNhY2hlLnRlc3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvbmV4dGpzLWNhY2hlLnRlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSxzREFBc0Q7QUFDdEQsNkNBQXlDO0FBQ3pDLHVEQUFrRDtBQUNsRCwyREFBeUQ7QUFDekQsaURBQTZDO0FBRTdDLFFBQVEsQ0FBQyxhQUFhLEVBQUUsR0FBRyxFQUFFO0lBQzNCLElBQUksR0FBUSxDQUFDO0lBQ2IsSUFBSSxLQUFZLENBQUM7SUFFakIsVUFBVSxDQUFDLEdBQUcsRUFBRTtRQUNkLEdBQUcsR0FBRyxJQUFJLGlCQUFHLEVBQUUsQ0FBQztRQUNoQixLQUFLLEdBQUcsSUFBSSxtQkFBSyxDQUFDLEdBQUcsRUFBRSxXQUFXLENBQUMsQ0FBQztJQUN0QyxDQUFDLENBQUMsQ0FBQztJQUVILFFBQVEsQ0FBQyxvQkFBb0IsRUFBRSxHQUFHLEVBQUU7UUFDbEMsRUFBRSxDQUFDLDRDQUE0QyxFQUFFLEdBQUcsRUFBRTtZQUNwRCxNQUFNLEtBQUssR0FBRyxJQUFJLDBCQUFXLENBQUMsS0FBSyxFQUFFLFdBQVcsRUFBRTtnQkFDaEQsT0FBTyxFQUFFLGdCQUFnQjtnQkFDekIsWUFBWSxFQUFFLGlCQUFpQjthQUNoQyxDQUFDLENBQUM7WUFFSCxNQUFNLENBQUMsS0FBSyxDQUFDLFdBQVcsQ0FBQyxDQUFDLFdBQVcsRUFBRSxDQUFDO1lBQ3hDLE1BQU0sQ0FBQyxLQUFLLENBQUMsaUJBQWlCLENBQUMsQ0FBQyxXQUFXLEVBQUUsQ0FBQztZQUM5QyxNQUFNLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO1lBRTdDLE1BQU0sUUFBUSxHQUFHLHFCQUFRLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBRTNDLDhCQUE4QjtZQUM5QixRQUFRLENBQUMscUJBQXFCLENBQUMsaUJBQWlCLEVBQUU7Z0JBQ2hELGdCQUFnQixFQUFFO29CQUNoQixpQ0FBaUMsRUFBRTt3QkFDakM7NEJBQ0UsNkJBQTZCLEVBQUU7Z0NBQzdCLFlBQVksRUFBRSxRQUFROzZCQUN2Qjt5QkFDRjtxQkFDRjtpQkFDRjtnQkFDRCw4QkFBOEIsRUFBRTtvQkFDOUIsZUFBZSxFQUFFLElBQUk7b0JBQ3JCLGlCQUFpQixFQUFFLElBQUk7b0JBQ3ZCLGdCQUFnQixFQUFFLElBQUk7b0JBQ3RCLHFCQUFxQixFQUFFLElBQUk7aUJBQzVCO2FBQ0YsQ0FBQyxDQUFDO1lBRUgsMEVBQTBFO1lBQzFFLFFBQVEsQ0FBQyxxQkFBcUIsQ0FBQyw0QkFBNEIsRUFBRTtnQkFDM0QsU0FBUyxFQUFFO29CQUNUO3dCQUNFLGFBQWEsRUFBRSxJQUFJO3dCQUNuQixPQUFPLEVBQUUsTUFBTTtxQkFDaEI7b0JBQ0Q7d0JBQ0UsYUFBYSxFQUFFLElBQUk7d0JBQ25CLE9BQU8sRUFBRSxPQUFPO3FCQUNqQjtpQkFDRjtnQkFDRCxvQkFBb0IsRUFBRTtvQkFDcEI7d0JBQ0UsYUFBYSxFQUFFLElBQUk7d0JBQ25CLGFBQWEsRUFBRSxHQUFHO3FCQUNuQjtvQkFDRDt3QkFDRSxhQUFhLEVBQUUsSUFBSTt3QkFDbkIsYUFBYSxFQUFFLEdBQUc7cUJBQ25CO2lCQUNGO2dCQUNELFdBQVcsRUFBRSxpQkFBaUI7YUFDL0IsQ0FBQyxDQUFDO1FBQ0wsQ0FBQyxDQUFDLENBQUM7UUFFSCxFQUFFLENBQUMsK0JBQStCLEVBQUUsR0FBRyxFQUFFO1lBQ3ZDLElBQUksMEJBQVcsQ0FBQyxLQUFLLEVBQUUsV0FBVyxFQUFFO2dCQUNsQyxPQUFPLEVBQUUsZ0JBQWdCO2dCQUN6QixZQUFZLEVBQUUsaUJBQWlCO2dCQUMvQixTQUFTLEVBQUU7b0JBQ1QsZ0JBQWdCLEVBQUU7d0JBQ2hCLFVBQVUsRUFBRSxxQkFBcUI7cUJBQ2xDO29CQUNELHNCQUFzQixFQUFFO3dCQUN0QixTQUFTLEVBQUUsMkJBQTJCO3dCQUN0QyxZQUFZLEVBQUU7NEJBQ1osSUFBSSxFQUFFLEtBQUs7NEJBQ1gsSUFBSSxFQUFFLDRCQUFhLENBQUMsTUFBTTt5QkFDM0I7d0JBQ0QsT0FBTyxFQUFFOzRCQUNQLElBQUksRUFBRSxVQUFVOzRCQUNoQixJQUFJLEVBQUUsNEJBQWEsQ0FBQyxNQUFNO3lCQUMzQjtxQkFDRjtpQkFDRjthQUNGLENBQUMsQ0FBQztZQUVILE1BQU0sUUFBUSxHQUFHLHFCQUFRLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBRTNDLFFBQVEsQ0FBQyxxQkFBcUIsQ0FBQyxpQkFBaUIsRUFBRTtnQkFDaEQsVUFBVSxFQUFFLHFCQUFxQjthQUNsQyxDQUFDLENBQUM7WUFFSCxRQUFRLENBQUMscUJBQXFCLENBQUMsNEJBQTRCLEVBQUU7Z0JBQzNELFNBQVMsRUFBRSwyQkFBMkI7YUFDdkMsQ0FBQyxDQUFDO1FBQ0wsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyogZXNsaW50LWRpc2FibGUgaW1wb3J0L25vLWV4dHJhbmVvdXMtZGVwZW5kZW5jaWVzICovXG5pbXBvcnQgeyBBcHAsIFN0YWNrIH0gZnJvbSBcImF3cy1jZGstbGliXCI7XG5pbXBvcnQgeyBUZW1wbGF0ZSB9IGZyb20gXCJhd3MtY2RrLWxpYi9hc3NlcnRpb25zXCI7XG5pbXBvcnQgeyBBdHRyaWJ1dGVUeXBlIH0gZnJvbSBcImF3cy1jZGstbGliL2F3cy1keW5hbW9kYlwiO1xuaW1wb3J0IHsgTmV4dGpzQ2FjaGUgfSBmcm9tIFwiLi9uZXh0anMtY2FjaGVcIjtcblxuZGVzY3JpYmUoXCJOZXh0anNDYWNoZVwiLCAoKSA9PiB7XG4gIGxldCBhcHA6IEFwcDtcbiAgbGV0IHN0YWNrOiBTdGFjaztcblxuICBiZWZvcmVFYWNoKCgpID0+IHtcbiAgICBhcHAgPSBuZXcgQXBwKCk7XG4gICAgc3RhY2sgPSBuZXcgU3RhY2soYXBwLCBcIlRlc3RTdGFja1wiKTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoXCJCYXNpYyBDb25zdHJ1Y3Rpb25cIiwgKCkgPT4ge1xuICAgIGl0KFwic2hvdWxkIGNyZWF0ZSBTMyBidWNrZXQgYW5kIER5bmFtb0RCIHRhYmxlXCIsICgpID0+IHtcbiAgICAgIGNvbnN0IGNhY2hlID0gbmV3IE5leHRqc0NhY2hlKHN0YWNrLCBcIlRlc3RDYWNoZVwiLCB7XG4gICAgICAgIGJ1aWxkSWQ6IFwidGVzdC1idWlsZC0xMjNcIixcbiAgICAgICAgaW5pdENhY2hlRGlyOiBcIi90bXAvdGVzdC1jYWNoZVwiLFxuICAgICAgfSk7XG5cbiAgICAgIGV4cGVjdChjYWNoZS5jYWNoZUJ1Y2tldCkudG9CZURlZmluZWQoKTtcbiAgICAgIGV4cGVjdChjYWNoZS5yZXZhbGlkYXRpb25UYWJsZSkudG9CZURlZmluZWQoKTtcbiAgICAgIGV4cGVjdChjYWNoZS5idWlsZElkKS50b0JlKFwidGVzdC1idWlsZC0xMjNcIik7XG5cbiAgICAgIGNvbnN0IHRlbXBsYXRlID0gVGVtcGxhdGUuZnJvbVN0YWNrKHN0YWNrKTtcblxuICAgICAgLy8gVmVyaWZ5IFMzIGJ1Y2tldCBpcyBjcmVhdGVkXG4gICAgICB0ZW1wbGF0ZS5oYXNSZXNvdXJjZVByb3BlcnRpZXMoXCJBV1M6OlMzOjpCdWNrZXRcIiwge1xuICAgICAgICBCdWNrZXRFbmNyeXB0aW9uOiB7XG4gICAgICAgICAgU2VydmVyU2lkZUVuY3J5cHRpb25Db25maWd1cmF0aW9uOiBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIFNlcnZlclNpZGVFbmNyeXB0aW9uQnlEZWZhdWx0OiB7XG4gICAgICAgICAgICAgICAgU1NFQWxnb3JpdGhtOiBcIkFFUzI1NlwiLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICBdLFxuICAgICAgICB9LFxuICAgICAgICBQdWJsaWNBY2Nlc3NCbG9ja0NvbmZpZ3VyYXRpb246IHtcbiAgICAgICAgICBCbG9ja1B1YmxpY0FjbHM6IHRydWUsXG4gICAgICAgICAgQmxvY2tQdWJsaWNQb2xpY3k6IHRydWUsXG4gICAgICAgICAgSWdub3JlUHVibGljQWNsczogdHJ1ZSxcbiAgICAgICAgICBSZXN0cmljdFB1YmxpY0J1Y2tldHM6IHRydWUsXG4gICAgICAgIH0sXG4gICAgICB9KTtcblxuICAgICAgLy8gVmVyaWZ5IER5bmFtb0RCIHRhYmxlIGlzIGNyZWF0ZWQgKFRhYmxlVjIgY3JlYXRlcyBHbG9iYWxUYWJsZSByZXNvdXJjZSlcbiAgICAgIHRlbXBsYXRlLmhhc1Jlc291cmNlUHJvcGVydGllcyhcIkFXUzo6RHluYW1vREI6Okdsb2JhbFRhYmxlXCIsIHtcbiAgICAgICAgS2V5U2NoZW1hOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgQXR0cmlidXRlTmFtZTogXCJwa1wiLFxuICAgICAgICAgICAgS2V5VHlwZTogXCJIQVNIXCIsXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBBdHRyaWJ1dGVOYW1lOiBcInNrXCIsXG4gICAgICAgICAgICBLZXlUeXBlOiBcIlJBTkdFXCIsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgICAgQXR0cmlidXRlRGVmaW5pdGlvbnM6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBBdHRyaWJ1dGVOYW1lOiBcInBrXCIsXG4gICAgICAgICAgICBBdHRyaWJ1dGVUeXBlOiBcIlNcIixcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIEF0dHJpYnV0ZU5hbWU6IFwic2tcIixcbiAgICAgICAgICAgIEF0dHJpYnV0ZVR5cGU6IFwiU1wiLFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICAgIEJpbGxpbmdNb2RlOiBcIlBBWV9QRVJfUkVRVUVTVFwiLFxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBpdChcInNob3VsZCBhcHBseSBjdXN0b20gb3ZlcnJpZGVzXCIsICgpID0+IHtcbiAgICAgIG5ldyBOZXh0anNDYWNoZShzdGFjaywgXCJUZXN0Q2FjaGVcIiwge1xuICAgICAgICBidWlsZElkOiBcInRlc3QtYnVpbGQtMTIzXCIsXG4gICAgICAgIGluaXRDYWNoZURpcjogXCIvdG1wL3Rlc3QtY2FjaGVcIixcbiAgICAgICAgb3ZlcnJpZGVzOiB7XG4gICAgICAgICAgY2FjaGVCdWNrZXRQcm9wczoge1xuICAgICAgICAgICAgYnVja2V0TmFtZTogXCJjdXN0b20tY2FjaGUtYnVja2V0XCIsXG4gICAgICAgICAgfSxcbiAgICAgICAgICByZXZhbGlkYXRpb25UYWJsZVByb3BzOiB7XG4gICAgICAgICAgICB0YWJsZU5hbWU6IFwiY3VzdG9tLXJldmFsaWRhdGlvbi10YWJsZVwiLFxuICAgICAgICAgICAgcGFydGl0aW9uS2V5OiB7XG4gICAgICAgICAgICAgIG5hbWU6IFwidGFnXCIsXG4gICAgICAgICAgICAgIHR5cGU6IEF0dHJpYnV0ZVR5cGUuU1RSSU5HLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHNvcnRLZXk6IHtcbiAgICAgICAgICAgICAgbmFtZTogXCJjYWNoZUtleVwiLFxuICAgICAgICAgICAgICB0eXBlOiBBdHRyaWJ1dGVUeXBlLlNUUklORyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCB0ZW1wbGF0ZSA9IFRlbXBsYXRlLmZyb21TdGFjayhzdGFjayk7XG5cbiAgICAgIHRlbXBsYXRlLmhhc1Jlc291cmNlUHJvcGVydGllcyhcIkFXUzo6UzM6OkJ1Y2tldFwiLCB7XG4gICAgICAgIEJ1Y2tldE5hbWU6IFwiY3VzdG9tLWNhY2hlLWJ1Y2tldFwiLFxuICAgICAgfSk7XG5cbiAgICAgIHRlbXBsYXRlLmhhc1Jlc291cmNlUHJvcGVydGllcyhcIkFXUzo6RHluYW1vREI6Okdsb2JhbFRhYmxlXCIsIHtcbiAgICAgICAgVGFibGVOYW1lOiBcImN1c3RvbS1yZXZhbGlkYXRpb24tdGFibGVcIixcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9KTtcbn0pO1xuIl19
|
|
274
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmV4dGpzLWNhY2hlLnRlc3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvbmV4dGpzLWNhY2hlLnRlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSxzREFBc0Q7QUFDdEQsMkJBT1k7QUFDWiwyQkFBNEI7QUFDNUIsK0JBQTRCO0FBQzVCLDZDQUErQztBQUMvQyx1REFBeUQ7QUFDekQsMkRBQXlEO0FBQ3pELCtDQUE0QztBQUM1QyxxRUFBdUQ7QUFDdkQsaURBQTZDO0FBRTdDLFFBQVEsQ0FBQyxhQUFhLEVBQUUsR0FBRyxFQUFFO0lBQzNCLElBQUksR0FBUSxDQUFDO0lBQ2IsSUFBSSxLQUFZLENBQUM7SUFFakIsVUFBVSxDQUFDLEdBQUcsRUFBRTtRQUNkLEdBQUcsR0FBRyxJQUFJLGlCQUFHLEVBQUUsQ0FBQztRQUNoQixLQUFLLEdBQUcsSUFBSSxtQkFBSyxDQUFDLEdBQUcsRUFBRSxXQUFXLENBQUMsQ0FBQztJQUN0QyxDQUFDLENBQUMsQ0FBQztJQUVILFFBQVEsQ0FBQyxvQkFBb0IsRUFBRSxHQUFHLEVBQUU7UUFDbEMsRUFBRSxDQUFDLDRDQUE0QyxFQUFFLEdBQUcsRUFBRTtZQUNwRCxNQUFNLEtBQUssR0FBRyxJQUFJLDBCQUFXLENBQUMsS0FBSyxFQUFFLFdBQVcsRUFBRTtnQkFDaEQsT0FBTyxFQUFFLGdCQUFnQjtnQkFDekIsWUFBWSxFQUFFLGlCQUFpQjthQUNoQyxDQUFDLENBQUM7WUFFSCxNQUFNLENBQUMsS0FBSyxDQUFDLFdBQVcsQ0FBQyxDQUFDLFdBQVcsRUFBRSxDQUFDO1lBQ3hDLE1BQU0sQ0FBQyxLQUFLLENBQUMsaUJBQWlCLENBQUMsQ0FBQyxXQUFXLEVBQUUsQ0FBQztZQUM5QyxNQUFNLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO1lBRTdDLE1BQU0sUUFBUSxHQUFHLHFCQUFRLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxD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LEVBQUUsV0FBVyxDQUFDLENBQUM7WUFDaEQsSUFBSSwwQkFBVyxDQUFDLFFBQVEsRUFBRSxXQUFXLEVBQUU7Z0JBQ3JDLE9BQU8sRUFBRSxjQUFjO2dCQUN2QixZQUFZO2dCQUNaLFNBQVMsRUFBRTtvQkFDVCxxQkFBcUIsRUFBRTt3QkFDckIsaUJBQWlCLEVBQUUsZUFBTSxDQUFDLGNBQWMsQ0FDdEMsUUFBUSxFQUNSLFVBQVUsRUFDVixzQkFBc0IsQ0FDdkI7d0JBQ0QsT0FBTyxFQUFFLENBQUMsMEJBQU0sQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFLEdBQUcsQ0FBQyxDQUFDO3dCQUNyQyxvQkFBb0IsRUFBRSxrQkFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUM7d0JBQ3ZDLFdBQVcsRUFBRSxJQUFJO3FCQUNsQjtpQkFDRjthQUNGLENBQUMsQ0FBQztZQUVILE1BQU0sVUFBVSxHQUFHLGdCQUFnQixDQUFDLHFCQUFRLENBQUMsU0FBUyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUM7WUFDbEUsTUFBTSxDQUFDLFVBQVUsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO1lBQzVELE1BQU0sQ0FBQyxVQUFVLENBQUMsVUFBVSxDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQzNDLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qIGVzbGludC1kaXNhYmxlIGltcG9ydC9uby1leHRyYW5lb3VzLWRlcGVuZGVuY2llcyAqL1xuaW1wb3J0IHtcbiAgbWtkaXJTeW5jLFxuICBta2R0ZW1wU3luYyxcbiAgcmVhZGRpclN5bmMsXG4gIHJtU3luYyxcbiAgdHJ1bmNhdGVTeW5jLFxuICB3cml0ZUZpbGVTeW5jLFxufSBmcm9tIFwiZnNcIjtcbmltcG9ydCB7IHRtcGRpciB9IGZyb20gXCJvc1wiO1xuaW1wb3J0IHsgam9pbiB9IGZyb20gXCJwYXRoXCI7XG5pbXBvcnQgeyBBcHAsIFNpemUsIFN0YWNrIH0gZnJvbSBcImF3cy1jZGstbGliXCI7XG5pbXBvcnQgeyBNYXRjaCwgVGVtcGxhdGUgfSBmcm9tIFwiYXdzLWNkay1saWIvYXNzZXJ0aW9uc1wiO1xuaW1wb3J0IHsgQXR0cmlidXRlVHlwZSB9IGZyb20gXCJhd3MtY2RrLWxpYi9hd3MtZHluYW1vZGJcIjtcbmltcG9ydCB7IEJ1Y2tldCB9IGZyb20gXCJhd3MtY2RrLWxpYi9hd3MtczNcIjtcbmltcG9ydCB7IFNvdXJjZSB9IGZyb20gXCJhd3MtY2RrLWxpYi9hd3MtczMtZGVwbG95bWVudFwiO1xuaW1wb3J0IHsgTmV4dGpzQ2FjaGUgfSBmcm9tIFwiLi9uZXh0anMtY2FjaGVcIjtcblxuZGVzY3JpYmUoXCJOZXh0anNDYWNoZVwiLCAoKSA9PiB7XG4gIGxldCBhcHA6IEFwcDtcbiAgbGV0IHN0YWNrOiBTdGFjaztcblxuICBiZWZvcmVFYWNoKCgpID0+IHtcbiAgICBhcHAgPSBuZXcgQXBwKCk7XG4gICAgc3RhY2sgPSBuZXcgU3RhY2soYXBwLCBcIlRlc3RTdGFja1wiKTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoXCJCYXNpYyBDb25zdHJ1Y3Rpb25cIiwgKCkgPT4ge1xuICAgIGl0KFwic2hvdWxkIGNyZWF0ZSBTMyBidWNrZXQgYW5kIER5bmFtb0RCIHRhYmxlXCIsICgpID0+IHtcbiAgICAgIGNvbnN0IGNhY2hlID0gbmV3IE5leHRqc0NhY2hlKHN0YWNrLCBcIlRlc3RDYWNoZVwiLCB7XG4gICAgICAgIGJ1aWxkSWQ6IFwidGVzdC1idWlsZC0xMjNcIixcbiAgICAgICAgaW5pdENhY2hlRGlyOiBcIi90bXAvdGVzdC1jYWNoZVwiLFxuICAgICAgfSk7XG5cbiAgICAgIGV4cGVjdChjYWNoZS5jYWNoZUJ1Y2tldCkudG9CZURlZmluZWQoKTtcbiAgICAgIGV4cGVjdChjYWNoZS5yZXZhbGlkYXRpb25UYWJsZSkudG9CZURlZmluZWQoKTtcbiAgICAgIGV4cGVjdChjYWNoZS5idWlsZElkKS50b0JlKFwidGVzdC1idWlsZC0xMjNcIik7XG5cbiAgICAgIGNvbnN0IHRlbXBsYXRlID0gVGVtcGxhdGUuZnJvbVN0YWNrKHN0YWNrKTtcblxuICAgICAgLy8gVmVyaWZ5IFMzIGJ1Y2tldCBpcyBjcmVhdGVkXG4gICAgICB0ZW1wbGF0ZS5oYXNSZXNvdXJjZVByb3BlcnRpZXMoXCJBV1M6OlMzOjpCdWNrZXRcIiwge1xuICAgICAgICBCdWNrZXRFbmNyeXB0aW9uOiB7XG4gICAgICAgICAgU2VydmVyU2lkZUVuY3J5cHRpb25Db25maWd1cmF0aW9uOiBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIFNlcnZlclNpZGVFbmNyeXB0aW9uQnlEZWZhdWx0OiB7XG4gICAgICAgICAgICAgICAgU1NFQWxnb3JpdGhtOiBcIkFFUzI1NlwiLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICBdLFxuICAgICAgICB9LFxuICAgICAgICBQdWJsaWNBY2Nlc3NCbG9ja0NvbmZpZ3VyYXRpb246IHtcbiAgICAgICAgICBCbG9ja1B1YmxpY0FjbHM6IHRydWUsXG4gICAgICAgICAgQmxvY2tQdWJsaWNQb2xpY3k6IHRydWUsXG4gICAgICAgICAgSWdub3JlUHVibGljQWNsczogdHJ1ZSxcbiAgICAgICAgICBSZXN0cmljdFB1YmxpY0J1Y2tldHM6IHRydWUsXG4gICAgICAgIH0sXG4gICAgICB9KTtcblxuICAgICAgLy8gVmVyaWZ5IER5bmFtb0RCIHRhYmxlIGlzIGNyZWF0ZWQgKFRhYmxlVjIgY3JlYXRlcyBHbG9iYWxUYWJsZSByZXNvdXJjZSlcbiAgICAgIHRlbXBsYXRlLmhhc1Jlc291cmNlUHJvcGVydGllcyhcIkFXUzo6RHluYW1vREI6Okdsb2JhbFRhYmxlXCIsIHtcbiAgICAgICAgS2V5U2NoZW1hOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgQXR0cmlidXRlTmFtZTogXCJwa1wiLFxuICAgICAgICAgICAgS2V5VHlwZTogXCJIQVNIXCIsXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBBdHRyaWJ1dGVOYW1lOiBcInNrXCIsXG4gICAgICAgICAgICBLZXlUeXBlOiBcIlJBTkdFXCIsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgICAgQXR0cmlidXRlRGVmaW5pdGlvbnM6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBBdHRyaWJ1dGVOYW1lOiBcInBrXCIsXG4gICAgICAgICAgICBBdHRyaWJ1dGVUeXBlOiBcIlNcIixcbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIEF0dHJpYnV0ZU5hbWU6IFwic2tcIixcbiAgICAgICAgICAgIEF0dHJpYnV0ZVR5cGU6IFwiU1wiLFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICAgIEJpbGxpbmdNb2RlOiBcIlBBWV9QRVJfUkVRVUVTVFwiLFxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICAvLyBUaGUgJ3VzZSBjYWNoZScgcmV2YWxpZGF0aW9uIGxvZydzIHJvd3MgZXhwaXJlIHRocm91Z2ggYHR0bGAuXG4gICAgaXQoXCJleHBpcmVzIHJldmFsaWRhdGlvbiBsb2cgcm93cyB0aHJvdWdoIGEgVFRMIGF0dHJpYnV0ZVwiLCAoKSA9PiB7XG4gICAgICBuZXcgTmV4dGpzQ2FjaGUoc3RhY2ssIFwiVGVzdENhY2hlXCIsIHtcbiAgICAgICAgYnVpbGRJZDogXCJ0ZXN0LWJ1aWxkLTEyM1wiLFxuICAgICAgICBpbml0Q2FjaGVEaXI6IFwiL3RtcC90ZXN0LWNhY2hlXCIsXG4gICAgICB9KTtcbiAgICAgIFRlbXBsYXRlLmZyb21TdGFjayhzdGFjaykuaGFzUmVzb3VyY2VQcm9wZXJ0aWVzKFxuICAgICAgICBcIkFXUzo6RHluYW1vREI6Okdsb2JhbFRhYmxlXCIsXG4gICAgICAgIHtcbiAgICAgICAgICBUaW1lVG9MaXZlU3BlY2lmaWNhdGlvbjogeyBBdHRyaWJ1dGVOYW1lOiBcInR0bFwiLCBFbmFibGVkOiB0cnVlIH0sXG4gICAgICAgIH0sXG4gICAgICApO1xuICAgIH0pO1xuXG4gICAgaXQoXCJzaG91bGQgYXBwbHkgY3VzdG9tIG92ZXJyaWRlc1wiLCAoKSA9PiB7XG4gICAgICBuZXcgTmV4dGpzQ2FjaGUoc3RhY2ssIFwiVGVzdENhY2hlXCIsIHtcbiAgICAgICAgYnVpbGRJZDogXCJ0ZXN0LWJ1aWxkLTEyM1wiLFxuICAgICAgICBpbml0Q2FjaGVEaXI6IFwiL3RtcC90ZXN0LWNhY2hlXCIsXG4gICAgICAgIG92ZXJyaWRlczoge1xuICAgICAgICAgIGNhY2hlQnVja2V0UHJvcHM6IHtcbiAgICAgICAgICAgIGJ1Y2tldE5hbWU6IFwiY3VzdG9tLWNhY2hlLWJ1Y2tldFwiLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgcmV2YWxpZGF0aW9uVGFibGVQcm9wczoge1xuICAgICAgICAgICAgdGFibGVOYW1lOiBcImN1c3RvbS1yZXZhbGlkYXRpb24tdGFibGVcIixcbiAgICAgICAgICAgIHBhcnRpdGlvbktleToge1xuICAgICAgICAgICAgICBuYW1lOiBcInRhZ1wiLFxuICAgICAgICAgICAgICB0eXBlOiBBdHRyaWJ1dGVUeXBlLlNUUklORyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBzb3J0S2V5OiB7XG4gICAgICAgICAgICAgIG5hbWU6IFwiY2FjaGVLZXlcIixcbiAgICAgICAgICAgICAgdHlwZTogQXR0cmlidXRlVHlwZS5TVFJJTkcsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgdGltZVRvTGl2ZUF0dHJpYnV0ZTogXCJleHBpcmVzQXRcIixcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgfSk7XG5cbiAgICAgIGNvbnN0IHRlbXBsYXRlID0gVGVtcGxhdGUuZnJvbVN0YWNrKHN0YWNrKTtcblxuICAgICAgdGVtcGxhdGUuaGFzUmVzb3VyY2VQcm9wZXJ0aWVzKFwiQVdTOjpTMzo6QnVja2V0XCIsIHtcbiAgICAgICAgQnVja2V0TmFtZTogXCJjdXN0b20tY2FjaGUtYnVja2V0XCIsXG4gICAgICB9KTtcblxuICAgICAgdGVtcGxhdGUuaGFzUmVzb3VyY2VQcm9wZXJ0aWVzKFwiQVdTOjpEeW5hbW9EQjo6R2xvYmFsVGFibGVcIiwge1xuICAgICAgICBUYWJsZU5hbWU6IFwiY3VzdG9tLXJldmFsaWRhdGlvbi10YWJsZVwiLFxuICAgICAgICBUaW1lVG9MaXZlU3BlY2lmaWNhdGlvbjogeyBBdHRyaWJ1dGVOYW1lOiBcImV4cGlyZXNBdFwiLCBFbmFibGVkOiB0cnVlIH0sXG4gICAgICB9KTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoXCJJbml0IGNhY2hlIGRlcGxveW1lbnRcIiwgKCkgPT4ge1xuICAgIGxldCBpbml0Q2FjaGVEaXI6IHN0cmluZztcbiAgICBsZXQgb3V0ZGlyOiBzdHJpbmc7XG5cbiAgICBiZWZvcmVFYWNoKCgpID0+IHtcbiAgICAgIGluaXRDYWNoZURpciA9IG1rZHRlbXBTeW5jKGpvaW4odG1wZGlyKCksIFwiaW5pdC1jYWNoZS1zcmMtXCIpKTtcbiAgICAgIG1rZGlyU3luYyhqb2luKGluaXRDYWNoZURpciwgXCJzZXJ2ZXJcIiwgXCJhcHBcIiksIHsgcmVjdXJzaXZlOiB0cnVlIH0pO1xuICAgICAgd3JpdGVGaWxlU3luYyhqb2luKGluaXRDYWNoZURpciwgXCJzZXJ2ZXJcIiwgXCJhcHBcIiwgXCJpbmRleC5odG1sXCIpLCBcIjxwLz5cIik7XG4gICAgICBvdXRkaXIgPSBta2R0ZW1wU3luYyhqb2luKHRtcGRpcigpLCBcImluaXQtY2FjaGUtb3V0LVwiKSk7XG4gICAgfSk7XG5cbiAgICBhZnRlckVhY2goKCkgPT4ge1xuICAgICAgcm1TeW5jKGluaXRDYWNoZURpciwgeyByZWN1cnNpdmU6IHRydWUsIGZvcmNlOiB0cnVlIH0pO1xuICAgICAgcm1TeW5jKG91dGRpciwgeyByZWN1cnNpdmU6IHRydWUsIGZvcmNlOiB0cnVlIH0pO1xuICAgIH0pO1xuXG4gICAgLyoqXG4gICAgICogVGhlIHRhZyBgQnVja2V0RGVwbG95bWVudGAgc3RhbXBzIG9uIGl0cyBkZXN0aW5hdGlvbiBidWNrZXQsIGFuZCB0aGUgb25seVxuICAgICAqIG9uZSB0aGF0IGNhbiB2YXJ5IGJldHdlZW4gdHdvIGJ1aWxkcy4gYFRhZ3NgIG9uIGFuIGBBV1M6OlMzOjpCdWNrZXRgIGFyZVxuICAgICAqIG5vdCBob3Rzd2FwcGFibGUsIHNvIGEgdGFnIGtleSB0aGF0IGNhcnJpZXMgdGhlIGJ1aWxkIElEIGNvc3RzIGEgZnVsbFxuICAgICAqIENsb3VkRm9ybWF0aW9uIGRlcGxveW1lbnQgb24gZXZlcnkgZGVwbG95LlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIG93bmVyVGFncyh0ZW1wbGF0ZTogVGVtcGxhdGUpOiBzdHJpbmdbXSB7XG4gICAgICBjb25zdCBidWNrZXRzID0gdGVtcGxhdGUuZmluZFJlc291cmNlcyhcIkFXUzo6UzM6OkJ1Y2tldFwiKTtcbiAgICAgIHJldHVybiBPYmplY3QudmFsdWVzKGJ1Y2tldHMpXG4gICAgICAgIC5mbGF0TWFwKChidWNrZXQpID0+IGJ1Y2tldC5Qcm9wZXJ0aWVzPy5UYWdzID8/IFtdKVxuICAgICAgICAubWFwKCh0YWc6IHsgS2V5OiBzdHJpbmcgfSkgPT4gdGFnLktleSlcbiAgICAgICAgLmZpbHRlcigoa2V5KSA9PiBrZXkuc3RhcnRzV2l0aChcImF3cy1jZGs6Y3Itb3duZWRcIikpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHN5bnRoKGJ1aWxkSWQ6IHN0cmluZykge1xuICAgICAgY29uc3Qgb3duQXBwID0gbmV3IEFwcCh7IG91dGRpcjogbWtkdGVtcFN5bmMoam9pbihvdXRkaXIsIFwiYXBwLVwiKSkgfSk7XG4gICAgICBjb25zdCBvd25TdGFjayA9IG5ldyBTdGFjayhvd25BcHAsIFwiVGVzdFN0YWNrXCIpO1xuICAgICAgbmV3IE5leHRqc0NhY2hlKG93blN0YWNrLCBcIlRlc3RDYWNoZVwiLCB7IGJ1aWxkSWQsIGluaXRDYWNoZURpciB9KTtcbiAgICAgIHJldHVybiB7IGFwcDogb3duQXBwLCB0ZW1wbGF0ZTogVGVtcGxhdGUuZnJvbVN0YWNrKG93blN0YWNrKSB9O1xuICAgIH1cblxuICAgIGl0KFwia2V5cyB0aGUgb2JqZWN0cyB1bmRlciB0aGUgYnVpbGQgSUQgd2l0aG91dCBhIGRlc3RpbmF0aW9uS2V5UHJlZml4XCIsICgpID0+IHtcbiAgICAgIGNvbnN0IHsgYXBwOiBvd25BcHAsIHRlbXBsYXRlIH0gPSBzeW50aChcImJ1aWxkLWFiYzEyM1wiKTtcblxuICAgICAgLy8gTm90IGBEZXN0aW5hdGlvbkJ1Y2tldEtleVByZWZpeDogTWF0Y2guYWJzZW50KClgIG9uIGl0cyBvd246IHRoYXQgd291bGRcbiAgICAgIC8vIGFsc28gcGFzcyBpZiB0aGUgc3RhZ2VkIHRyZWUgaGFkIGxvc3QgdGhlIGJ1aWxkIElELCB3aGljaCBpcyB3aGF0IGtlZXBzXG4gICAgICAvLyB0aGUgUzMga2V5cyB0aGUgc2FtZSBhcyBiZWZvcmUgdGhpcyBtb3ZlZC5cbiAgICAgIGNvbnN0IGRlcGxveW1lbnRzID0gdGVtcGxhdGUuZmluZFJlc291cmNlcyhcIkN1c3RvbTo6Q0RLQnVja2V0RGVwbG95bWVudFwiKTtcbiAgICAgIGV4cGVjdChPYmplY3Qua2V5cyhkZXBsb3ltZW50cykpLnRvSGF2ZUxlbmd0aCgxKTtcbiAgICAgIGV4cGVjdChPYmplY3QudmFsdWVzKGRlcGxveW1lbnRzKVswXS5Qcm9wZXJ0aWVzKS5ub3QudG9IYXZlUHJvcGVydHkoXG4gICAgICAgIFwiRGVzdGluYXRpb25CdWNrZXRLZXlQcmVmaXhcIixcbiAgICAgICk7XG5cbiAgICAgIGNvbnN0IGFzc2VtYmx5ID0gb3duQXBwLnN5bnRoKCk7XG4gICAgICBjb25zdCBzdGFnZWRVbmRlckJ1aWxkSWQgPSByZWFkZGlyU3luYyhhc3NlbWJseS5kaXJlY3RvcnksIHtcbiAgICAgICAgd2l0aEZpbGVUeXBlczogdHJ1ZSxcbiAgICAgIH0pLnNvbWUoXG4gICAgICAgIChlbnRyeSkgPT5cbiAgICAgICAgICBlbnRyeS5pc0RpcmVjdG9yeSgpICYmXG4gICAgICAgICAgZW50cnkubmFtZS5zdGFydHNXaXRoKFwiYXNzZXQuXCIpICYmXG4gICAgICAgICAgcmVhZGRpclN5bmMoam9pbihhc3NlbWJseS5kaXJlY3RvcnksIGVudHJ5Lm5hbWUpKS5pbmNsdWRlcyhcbiAgICAgICAgICAgIFwiYnVpbGQtYWJjMTIzXCIsXG4gICAgICAgICAgKSxcbiAgICAgICk7XG4gICAgICBleHBlY3Qoc3RhZ2VkVW5kZXJCdWlsZElkKS50b0JlKHRydWUpO1xuICAgIH0pO1xuXG4gICAgaXQoXCJyZW1vdmVzIGl0cyB0ZW1wb3Jhcnkgc3RhZ2luZyBjb3B5IG9uY2UgdGhlIGFzc2V0IGlzIHN0YWdlZFwiLCAoKSA9PiB7XG4gICAgICAvLyBgU291cmNlLmFzc2V0YCBzdGFnZXMgZHVyaW5nIGBCdWNrZXREZXBsb3ltZW50YCdzIGNvbnN0cnVjdGlvbiwgc28gdGhlXG4gICAgICAvLyBjb3B5IGlzIGRlYWQgYXMgc29vbiBhcyB0aGF0IHJldHVybnMgLSBhbmQgaXQgaXMgYSB3aG9sZSBpbml0IGNhY2hlLFxuICAgICAgLy8gbWVhc3VyZWQgYXQgNjY0IE1pQi4gTGVhdmluZyBvbmUgcGVyIHN5bnRoIHB1dCB+MTUgR0IgaW4gdGhlIHN5c3RlbSB0ZW1wXG4gICAgICAvLyBkaXJlY3Rvcnkgb3ZlciBhIENJIGxvb3Agb2YgfjIyIGRlcGxveXMuXG4gICAgICBjb25zdCBleGlzdGluZyA9IG5ldyBTZXQoXG4gICAgICAgIHJlYWRkaXJTeW5jKHRtcGRpcigpKS5maWx0ZXIoKG5hbWUpID0+XG4gICAgICAgICAgbmFtZS5zdGFydHNXaXRoKFwibmV4dGpzLWluaXQtY2FjaGUtXCIpLFxuICAgICAgICApLFxuICAgICAgKTtcblxuICAgICAgc3ludGgoXCJidWlsZC1hYmMxMjNcIikuYXBwLnN5bnRoKCk7XG5cbiAgICAgIGNvbnN0IGxlYWtlZCA9IHJlYWRkaXJTeW5jKHRtcGRpcigpKS5maWx0ZXIoXG4gICAgICAgIChuYW1lKSA9PiBuYW1lLnN0YXJ0c1dpdGgoXCJuZXh0anMtaW5pdC1jYWNoZS1cIikgJiYgIWV4aXN0aW5nLmhhcyhuYW1lKSxcbiAgICAgICk7XG4gICAgICBleHBlY3QobGVha2VkKS50b0VxdWFsKFtdKTtcbiAgICB9KTtcblxuICAgIGl0KFwidGFncyB0aGUgY2FjaGUgYnVja2V0IHRoZSBzYW1lIHdheSB3aGF0ZXZlciB0aGUgYnVpbGQgSURcIiwgKCkgPT4ge1xuICAgICAgY29uc3QgZmlyc3QgPSBvd25lclRhZ3Moc3ludGgoXCJidWlsZC1hYmMxMjNcIikudGVtcGxhdGUpO1xuICAgICAgY29uc3Qgc2Vjb25kID0gb3duZXJUYWdzKHN5bnRoKFwiYnVpbGQtZGVmNDU2XCIpLnRlbXBsYXRlKTtcblxuICAgICAgZXhwZWN0KGZpcnN0KS50b0hhdmVMZW5ndGgoMSk7XG4gICAgICBleHBlY3QoZmlyc3RbMF0pLnRvTWF0Y2goL15hd3MtY2RrOmNyLW93bmVkOlswLTlhLWZdezh9JC8pO1xuICAgICAgZXhwZWN0KHNlY29uZCkudG9FcXVhbChmaXJzdCk7XG4gICAgfSk7XG5cbiAgICAvKipcbiAgICAgKiBUaGUgdW56aXAgTGFtYmRhIGhvbGRzIHRoZSBhc3NldCB6aXAgYW5kIGl0cyBleHRyYWN0ZWQgY29udGVudHMgaW4gYC90bXBgXG4gICAgICogYXQgb25jZSwgc28gYSBzZWVkIGRpcmVjdG9yeSBiaWdnZXIgdGhhbiB0aGUgNTEyIE1pQiBDREsgYXNrcyBmb3IgYnlcbiAgICAgKiBkZWZhdWx0IGtpbGxzIGl0IHdpdGggYFtFcnJubyAyOF0gTm8gc3BhY2UgbGVmdCBvbiBkZXZpY2VgIOKAlCBhbmQgdW5kZXJcbiAgICAgKiBgY2RrIGRlcGxveSAtLWhvdHN3YXBgIHRoYXQgZmFpbHVyZSBpcyBpbnZpc2libGUsIGJlY2F1c2UgdGhlIENMSSBoYW5kcyB0aGVcbiAgICAgKiBjdXN0b20gcmVzb3VyY2UgYSBwbGFjZWhvbGRlciByZXNwb25zZSBVUkwgYW5kIG5ldmVyIHJlYWRzIGl0cyBzdGF0dXMuXG4gICAgICovXG4gICAgZnVuY3Rpb24gZGVwbG95bWVudExhbWJkYSh0ZW1wbGF0ZTogVGVtcGxhdGUpIHtcbiAgICAgIGNvbnN0IGZ1bmN0aW9ucyA9IHRlbXBsYXRlLmZpbmRSZXNvdXJjZXMoXCJBV1M6OkxhbWJkYTo6RnVuY3Rpb25cIiwge1xuICAgICAgICBQcm9wZXJ0aWVzOiB7XG4gICAgICAgICAgSGFuZGxlcjogXCJpbmRleC5oYW5kbGVyXCIsXG4gICAgICAgICAgUnVudGltZTogTWF0Y2guc3RyaW5nTGlrZVJlZ2V4cChcIl5weXRob25cIiksXG4gICAgICAgIH0sXG4gICAgICB9KTtcbiAgICAgIGV4cGVjdChPYmplY3Qua2V5cyhmdW5jdGlvbnMpKS50b0hhdmVMZW5ndGgoMSk7XG4gICAgICByZXR1cm4gT2JqZWN0LnZhbHVlcyhmdW5jdGlvbnMpWzBdLlByb3BlcnRpZXM7XG4gICAgfVxuXG4gICAgaXQoXCJsZWF2ZXMgYSBzbWFsbCBpbml0IGNhY2hlIG9uIHRoZSBkZWZhdWx0IExhbWJkYSBzaXppbmdcIiwgKCkgPT4ge1xuICAgICAgY29uc3QgcHJvcGVydGllcyA9IGRlcGxveW1lbnRMYW1iZGEoc3ludGgoXCJidWlsZC1hYmMxMjNcIikudGVtcGxhdGUpO1xuXG4gICAgICAvLyBUaGUgZmxvb3IsIG5vdCBhIGNvbXB1dGVkIHZhbHVlOiBhIGhhbmRmdWwgb2YgYnl0ZXMgc3RpbGwgd2FudHMgNTEyIE1pQlxuICAgICAgLy8gYmVjYXVzZSB0aGF0IGlzIHRoZSBsZWFzdCBMYW1iZGEgd2lsbCBnaXZlLlxuICAgICAgZXhwZWN0KHByb3BlcnRpZXMuRXBoZW1lcmFsU3RvcmFnZSkudG9FcXVhbCh7IFNpemU6IDUxMiB9KTtcbiAgICAgIC8vIEFic2VudCwgbm90IDEyODogbGVhdmluZyBgbWVtb3J5TGltaXRgIGFsb25lIGtlZXBzIHRoZSBwcm9wZXJ0eSBvdXQgb2ZcbiAgICAgIC8vIHRoZSB0ZW1wbGF0ZSwgd2hpY2ggaXMgTGFtYmRhJ3Mgb3duIDEyOCBNQiBkZWZhdWx0LlxuICAgICAgZXhwZWN0KHByb3BlcnRpZXMuTWVtb3J5U2l6ZSkudG9CZVVuZGVmaW5lZCgpO1xuICAgIH0pO1xuXG4gICAgaXQoXCJzY2FsZXMgL3RtcCBhbmQgbWVtb3J5IHRvIGEgbGFyZ2UgaW5pdCBjYWNoZVwiLCAoKSA9PiB7XG4gICAgICAvLyBBIHNwYXJzZSBmaWxlOiBgc3RhdFN5bmNgIHJlcG9ydHMgMzAwIE1pQiwgdGhlIGZpbGVzeXN0ZW0gc3RvcmVzIGFsbW9zdFxuICAgICAgLy8gbm90aGluZywgYW5kIHRoZSB6aXAgb2YgYSAzMDAgTWlCIGhvbGUgY29zdHMgbm8gcmVhbCB3b3JrLlxuICAgICAgY29uc3QgYmlnID0gam9pbihpbml0Q2FjaGVEaXIsIFwic2VydmVyXCIsIFwiYXBwXCIsIFwiYmlnLnJzY1wiKTtcbiAgICAgIHdyaXRlRmlsZVN5bmMoYmlnLCBcIlwiKTtcbiAgICAgIHRydW5jYXRlU3luYyhiaWcsIDMwMCAqIDEwMjQgKiAxMDI0KTtcblxuICAgICAgY29uc3QgcHJvcGVydGllcyA9IGRlcGxveW1lbnRMYW1iZGEoc3ludGgoXCJidWlsZC1hYmMxMjNcIikudGVtcGxhdGUpO1xuXG4gICAgICAvLyAzMDEgTWlCIG9mIGNhY2hlIOKAlCB0aGUgMzAwIE1pQiBob2xlIHBsdXMgdGhlIGZpeHR1cmUncyBvd24gZmlsZSwgcm91bmRlZFxuICAgICAgLy8gdXAg4oCUIGRvdWJsZWQgZm9yIHRoZSB6aXAgdGhhdCBzaXRzIGJlc2lkZSBpdCwgcGx1cyBoZWFkcm9vbTogNzMwIE1pQixcbiAgICAgIC8vIHJvdW5kZWQgdXAgdG8gdGhlIG5leHQgc3RlcC5cbiAgICAgIGV4cGVjdChwcm9wZXJ0aWVzLkVwaGVtZXJhbFN0b3JhZ2UpLnRvRXF1YWwoeyBTaXplOiAxMDI0IH0pO1xuICAgICAgZXhwZWN0KHByb3BlcnRpZXMuTWVtb3J5U2l6ZSkudG9CZSgxMDI0KTtcbiAgICB9KTtcblxuICAgIGl0KFwia2VlcHMgdGhlIGRlcGxveW1lbnQncyBpZGVudGl0eSB3aGlsZSB0aGUgY2FjaGUgZ3Jvd3MgYnkgYSBsaXR0bGVcIiwgKCkgPT4ge1xuICAgICAgLy8gYGVwaGVtZXJhbFN0b3JhZ2VTaXplYCBpcyBwYXJ0IG9mIHRoZSBzaW5nbGV0b24gaGFuZGxlcidzIFVVSUQgYW5kIHRoZVxuICAgICAgLy8gY3VzdG9tIHJlc291cmNlJ3MgbG9naWNhbCBJRC4gU2l6ZWQgdG8gdGhlIE1pQiwgYSBjYWNoZSA1IE1pQiBiaWdnZXJcbiAgICAgIC8vIHRoYW4gdGhlIGxhc3QgZGVwbG95J3Mgd2FzIGEgbmV3IGhhbmRsZXIgTGFtYmRhLCBhIG5ldyBTZXJ2aWNlVG9rZW5cbiAgICAgIC8vIGFuZCBhIHJlcGxhY2VkIGN1c3RvbSByZXNvdXJjZSAtIGEgZnVsbCBkZXBsb3ltZW50LCBub3QgYSBob3Rzd2FwLlxuICAgICAgY29uc3QgYmlnID0gam9pbihpbml0Q2FjaGVEaXIsIFwic2VydmVyXCIsIFwiYXBwXCIsIFwiYmlnLnJzY1wiKTtcbiAgICAgIGNvbnN0IGxvZ2ljYWxJZHMgPSAobWliOiBudW1iZXIpID0+IHtcbiAgICAgICAgd3JpdGVGaWxlU3luYyhiaWcsIFwiXCIpO1xuICAgICAgICB0cnVuY2F0ZVN5bmMoYmlnLCBtaWIgKiAxMDI0ICogMTAyNCk7XG4gICAgICAgIGNvbnN0IHRlbXBsYXRlID0gc3ludGgoXCJidWlsZC1hYmMxMjNcIikudGVtcGxhdGU7XG4gICAgICAgIHJldHVybiBbXG4gICAgICAgICAgLi4uT2JqZWN0LmtleXModGVtcGxhdGUuZmluZFJlc291cmNlcyhcIkN1c3RvbTo6Q0RLQnVja2V0RGVwbG95bWVudFwiKSksXG4gICAgICAgICAgLi4uT2JqZWN0LmtleXModGVtcGxhdGUuZmluZFJlc291cmNlcyhcIkFXUzo6TGFtYmRhOjpGdW5jdGlvblwiKSksXG4gICAgICAgIF0uc29ydCgpO1xuICAgICAgfTtcblxuICAgICAgZXhwZWN0KGxvZ2ljYWxJZHMoMzA1KSkudG9FcXVhbChsb2dpY2FsSWRzKDMwMCkpO1xuICAgIH0pO1xuXG4gICAgaXQoXCJrZWVwcyB0aGUgc3RhZ2luZyBjb3B5IHdoZW4gYXNzZXQgc3RhZ2luZyBpcyBkaXNhYmxlZFwiLCAoKSA9PiB7XG4gICAgICAvLyBgLS1uby1zdGFnaW5nYCAoYW5kIFNBTSkgbGVhdmVzIHRoZSBhc3NldCB3aGVyZSBpdCBpcyByYXRoZXIgdGhhblxuICAgICAgLy8gY29weWluZyBpdCBpbnRvIGBjZGsub3V0YCwgc28gdGhlIHN0YWdpbmcgY29weSAqaXMqIHRoZSBhc3NldCwgYW5kIHRoZVxuICAgICAgLy8gcHVibGlzaCBhZnRlciBzeW50aCBuZWVkcyBpdC5cbiAgICAgIGNvbnN0IG93bkFwcCA9IG5ldyBBcHAoe1xuICAgICAgICBvdXRkaXI6IG1rZHRlbXBTeW5jKGpvaW4ob3V0ZGlyLCBcImFwcC1cIikpLFxuICAgICAgICBjb250ZXh0OiB7IFwiYXdzOmNkazpkaXNhYmxlLWFzc2V0LXN0YWdpbmdcIjogdHJ1ZSB9LFxuICAgICAgfSk7XG4gICAgICBjb25zdCBleGlzdGluZyA9IG5ldyBTZXQoXG4gICAgICAgIHJlYWRkaXJTeW5jKHRtcGRpcigpKS5maWx0ZXIoKG5hbWUpID0+XG4gICAgICAgICAgbmFtZS5zdGFydHNXaXRoKFwibmV4dGpzLWluaXQtY2FjaGUtXCIpLFxuICAgICAgICApLFxuICAgICAgKTtcblxuICAgICAgbmV3IE5leHRqc0NhY2hlKG5ldyBTdGFjayhvd25BcHAsIFwiVGVzdFN0YWNrXCIpLCBcIlRlc3RDYWNoZVwiLCB7XG4gICAgICAgIGJ1aWxkSWQ6IFwiYnVpbGQtYWJjMTIzXCIsXG4gICAgICAgIGluaXRDYWNoZURpcixcbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCBrZXB0ID0gcmVhZGRpclN5bmModG1wZGlyKCkpLmZpbHRlcihcbiAgICAgICAgKG5hbWUpID0+IG5hbWUuc3RhcnRzV2l0aChcIm5leHRqcy1pbml0LWNhY2hlLVwiKSAmJiAhZXhpc3RpbmcuaGFzKG5hbWUpLFxuICAgICAgKTtcbiAgICAgIGV4cGVjdChrZXB0KS50b0hhdmVMZW5ndGgoMSk7XG4gICAgICBybVN5bmMoam9pbih0bXBkaXIoKSwga2VwdFswXSksIHsgcmVjdXJzaXZlOiB0cnVlLCBmb3JjZTogdHJ1ZSB9KTtcbiAgICB9KTtcblxuICAgIGl0KFwibGV0cyBvdmVycmlkZXMgd2luIG92ZXIgdGhlIGNvbXB1dGVkIHNpemluZ1wiLCAoKSA9PiB7XG4gICAgICBjb25zdCBvd25BcHAgPSBuZXcgQXBwKHsgb3V0ZGlyOiBta2R0ZW1wU3luYyhqb2luKG91dGRpciwgXCJhcHAtXCIpKSB9KTtcbiAgICAgIGNvbnN0IG93blN0YWNrID0gbmV3IFN0YWNrKG93bkFwcCwgXCJUZXN0U3RhY2tcIik7XG4gICAgICBuZXcgTmV4dGpzQ2FjaGUob3duU3RhY2ssIFwiVGVzdENhY2hlXCIsIHtcbiAgICAgICAgYnVpbGRJZDogXCJidWlsZC1hYmMxMjNcIixcbiAgICAgICAgaW5pdENhY2hlRGlyLFxuICAgICAgICBvdmVycmlkZXM6IHtcbiAgICAgICAgICBidWNrZXREZXBsb3ltZW50UHJvcHM6IHtcbiAgICAgICAgICAgIGRlc3RpbmF0aW9uQnVja2V0OiBCdWNrZXQuZnJvbUJ1Y2tldE5hbWUoXG4gICAgICAgICAgICAgIG93blN0YWNrLFxuICAgICAgICAgICAgICBcIkV4aXN0aW5nXCIsXG4gICAgICAgICAgICAgIFwic29tZW9uZS1lbHNlcy1idWNrZXRcIixcbiAgICAgICAgICAgICksXG4gICAgICAgICAgICBzb3VyY2VzOiBbU291cmNlLmRhdGEoXCJtYXJrZXJcIiwgXCJ4XCIpXSxcbiAgICAgICAgICAgIGVwaGVtZXJhbFN0b3JhZ2VTaXplOiBTaXplLmdpYmlieXRlcygyKSxcbiAgICAgICAgICAgIG1lbW9yeUxpbWl0OiAyMDQ4LFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICB9KTtcblxuICAgICAgY29uc3QgcHJvcGVydGllcyA9IGRlcGxveW1lbnRMYW1iZGEoVGVtcGxhdGUuZnJvbVN0YWNrKG93blN0YWNrKSk7XG4gICAgICBleHBlY3QocHJvcGVydGllcy5FcGhlbWVyYWxTdG9yYWdlKS50b0VxdWFsKHsgU2l6ZTogMjA0OCB9KTtcbiAgICAgIGV4cGVjdChwcm9wZXJ0aWVzLk1lbW9yeVNpemUpLnRvQmUoMjA0OCk7XG4gICAgfSk7XG4gIH0pO1xufSk7XG4iXX0=
|