cdk-nextjs 0.6.2 → 0.7.0
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 +1548 -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 +852 -0
- package/lib/adapter/build-outputs.test.d.ts +1 -0
- package/lib/adapter/build-outputs.test.js +861 -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 +1213 -0
- package/lib/runtime/core.test.d.ts +1 -0
- package/lib/runtime/core.test.js +1678 -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 +41595 -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 +55 -0
- package/lib/runtime/next-modules.js +124 -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 +41588 -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/utils/base-path.d.ts
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure `basePath` and URL path helpers. Nothing here imports `aws-cdk-lib` or
|
|
3
|
+
* touches the filesystem, so the adapter and runtime bundles can import it as
|
|
4
|
+
* well as the constructs.
|
|
5
|
+
*/
|
|
1
6
|
import { NextjsType } from "../constants";
|
|
2
7
|
/**
|
|
3
8
|
* Reduces a `basePath` to a bare path segment so values that address the same
|
|
@@ -5,6 +10,31 @@ import { NextjsType } from "../constants";
|
|
|
5
10
|
* without doubling separators.
|
|
6
11
|
*/
|
|
7
12
|
export declare function normalizeBasePath(basePath?: string): string;
|
|
13
|
+
/**
|
|
14
|
+
* Whether `path` is `prefix` or under it on a segment boundary, so `/docsearch`
|
|
15
|
+
* is not under `/docs`. An empty `prefix` matches nothing. Both sides must be in
|
|
16
|
+
* the same form (both with or both without the leading `/`).
|
|
17
|
+
*/
|
|
18
|
+
export declare function hasPathPrefix(path: string, prefix: string): boolean;
|
|
19
|
+
/**
|
|
20
|
+
* A `basePath` as Next.js spells it and URLs start with it: one leading slash,
|
|
21
|
+
* no trailing one ("/base"), `""` for none. Accepts any spelling
|
|
22
|
+
* {@link normalizeBasePath} does.
|
|
23
|
+
*/
|
|
24
|
+
export declare function basePathPrefix(basePath?: string): string;
|
|
25
|
+
/**
|
|
26
|
+
* Invalidation paths covering every URI of the app: what a deploy invalidates,
|
|
27
|
+
* and what the cache handler's oversized batches, retries after a quota error,
|
|
28
|
+
* and tags whose routes could not all be named fall back to.
|
|
29
|
+
*
|
|
30
|
+
* `/*` is the whole app only without a `basePath`. `/base/*` matches neither the
|
|
31
|
+
* app's root, `/base`, nor its RSC payload, `/base?_rsc=…` - the same root the
|
|
32
|
+
* `revalidatePath("/")` that overflowed may have named - so those are spelled
|
|
33
|
+
* out. `/base*` would cover them for one wildcard, but also every sibling
|
|
34
|
+
* prefix (`/base2`, `/basement`), which may be another app on the same
|
|
35
|
+
* distribution.
|
|
36
|
+
*/
|
|
37
|
+
export declare function wholeAppInvalidationPaths(basePath?: string): string[];
|
|
8
38
|
/**
|
|
9
39
|
* Joins path parts with a single "/", normalizing each (so no leading or
|
|
10
40
|
* trailing slash survives, including on the result) and dropping the empty
|
|
@@ -19,8 +49,8 @@ export declare function joinPath(...parts: (string | undefined)[]): string;
|
|
|
19
49
|
* answers "/api/health" and "/api/health/" differently.
|
|
20
50
|
*
|
|
21
51
|
* Use this for paths handed to something that talks to the app directly — an ALB
|
|
22
|
-
* target group health check, the
|
|
23
|
-
*
|
|
52
|
+
* target group health check, the container's own health probe — since the app
|
|
53
|
+
* only answers under its own `basePath`.
|
|
24
54
|
*
|
|
25
55
|
* Prefixes unconditionally, so `path` has to arrive as the app routes it,
|
|
26
56
|
* without `basePath`: for an app based at "/base", "/base/api/health" becomes
|
|
@@ -31,18 +61,78 @@ export declare function joinPath(...parts: (string | undefined)[]): string;
|
|
|
31
61
|
*/
|
|
32
62
|
export declare function prefixWithBasePath(basePath: string | undefined, path: string): string;
|
|
33
63
|
/**
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
* this picks up a `basePath` computed in `next.config.js`, not only a literal
|
|
37
|
-
* one). Normalized, empty when the app sets none.
|
|
64
|
+
* The app's own `assetPrefix` as a path with a leading and no trailing slash
|
|
65
|
+
* ("/cdn"), or `""` when the app sets none.
|
|
38
66
|
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
*
|
|
67
|
+
* Returns `""` for an absolute `assetPrefix` ("https://cdn.example.com", or the
|
|
68
|
+
* protocol-relative "//cdn.example.com") too: that names an origin cdk-nextjs
|
|
69
|
+
* does not control, and it is the supported way to serve assets from elsewhere,
|
|
70
|
+
* so nothing about it is worth warning about. Use {@link assetPrefixPath} for
|
|
71
|
+
* what the *distribution* has to answer on, which includes the path an absolute
|
|
72
|
+
* prefix carries.
|
|
73
|
+
*
|
|
74
|
+
* Next.js applies `assetPrefix` on top of, not under, `basePath`, so the result
|
|
75
|
+
* is the whole prefix of a `_next/static` URL and must not be joined with
|
|
76
|
+
* `basePath`.
|
|
44
77
|
*/
|
|
45
|
-
export declare function
|
|
78
|
+
export declare function relativeAssetPrefix(assetPrefix: string): string;
|
|
79
|
+
/**
|
|
80
|
+
* Whether a path-style `assetPrefix` would go unanswered on this `NextjsType`,
|
|
81
|
+
* i.e. whether every bundle would 404.
|
|
82
|
+
*
|
|
83
|
+
* `assetPrefix` moves every bundle URL to `<assetPrefix>/_next/static/...` while
|
|
84
|
+
* the objects keep their `<basePath>/_next/static/...` S3 keys. The Global
|
|
85
|
+
* `NextjsType`s answer that with a cache behavior of their own
|
|
86
|
+
* (`NextjsDistribution`); the regional ones have nothing that maps the prefix
|
|
87
|
+
* back — API Gateway's `_next/static` resource and the container's own files are
|
|
88
|
+
* both under the unprefixed path.
|
|
89
|
+
*
|
|
90
|
+
* A prefix equal to the app's own `basePath` is **not** unserved, because that is
|
|
91
|
+
* the value Next.js resolves `assetPrefix` to when `basePath` is set and
|
|
92
|
+
* `assetPrefix` is not: `.next/required-server-files.json` comes back as
|
|
93
|
+
* `{"assetPrefix":"/prod","basePath":"/prod"}` for an app that only ever set
|
|
94
|
+
* `basePath`. Without that exemption the warning fired on every regional
|
|
95
|
+
* deployment that sets a `basePath` at all — including `examples/regional-functions`
|
|
96
|
+
* — telling users their bundles would 404 at the one path that does serve them.
|
|
97
|
+
* `NextjsDistribution.resolveAssetPrefix` drops the prefix for the same reason.
|
|
98
|
+
*
|
|
99
|
+
* Both sides go through `normalizeBasePath` because they arrive in different
|
|
100
|
+
* shapes: `nextConfigAssetPrefix` carries a leading slash (`"/prod"`),
|
|
101
|
+
* `nextConfigBasePath` does not (`"prod"`).
|
|
102
|
+
*/
|
|
103
|
+
export declare function isAssetPrefixUnserved(nextjsType: NextjsType, nextConfigAssetPrefix: string, nextConfigBasePath?: string): boolean;
|
|
104
|
+
/**
|
|
105
|
+
* The *path* every bundle URL carries, whichever form `assetPrefix` takes: "/cdn"
|
|
106
|
+
* for `assetPrefix: "/cdn"` and for `assetPrefix:
|
|
107
|
+
* "https://cdn.example.com/cdn"` alike, `""` when there is none (an absolute
|
|
108
|
+
* prefix with no path, or no prefix at all).
|
|
109
|
+
*
|
|
110
|
+
* An absolute prefix's path counts because `next build` compiles a `beforeFiles`
|
|
111
|
+
* rewrite of its own for it — `/cdn/_next/:path+ → /_next/:path+` — so `next
|
|
112
|
+
* start` serves every bundle under that path as well as under `/_next`. A CDN
|
|
113
|
+
* fronting this deployment at that path therefore has to be answered, and the
|
|
114
|
+
* distribution's `assetPrefix` behavior is what answers it. Measured against
|
|
115
|
+
* `test/e2e/app-dir/asset-prefix-absolute`; see `docs/harness-coverage.md`.
|
|
116
|
+
* Shared with `NextjsDistribution`, whose `assetPrefix` prop a user can also
|
|
117
|
+
* set by hand.
|
|
118
|
+
*/
|
|
119
|
+
export declare function assetPrefixPath(assetPrefix: string): string;
|
|
120
|
+
/**
|
|
121
|
+
* The path prefix API Gateway strips before matching resources, as far as synth
|
|
122
|
+
* can tell. Only read by `resolveBasePath` for `REGIONAL_FUNCTIONS`.
|
|
123
|
+
*/
|
|
124
|
+
export interface ApiGatewayPrefix {
|
|
125
|
+
/**
|
|
126
|
+
* The stage name on the execute-api endpoint, or the base path mapping on a
|
|
127
|
+
* custom domain (`""` when mapped at the root). `undefined` when it is not
|
|
128
|
+
* known at synth — a token — in which case nothing is derived.
|
|
129
|
+
*/
|
|
130
|
+
readonly strippedPrefix?: string;
|
|
131
|
+
/** Whether a custom domain is configured through `restApiProps.domainName`. */
|
|
132
|
+
readonly customDomain: boolean;
|
|
133
|
+
}
|
|
134
|
+
/** `RestApi`'s own defaults: the `prod` stage, no custom domain. */
|
|
135
|
+
export declare const DEFAULT_API_GATEWAY_PREFIX: ApiGatewayPrefix;
|
|
46
136
|
/**
|
|
47
137
|
* Settles on the single `basePath` the infrastructure should be built around,
|
|
48
138
|
* given the CDK `basePath` prop and the Next.js app's own `basePath`
|
|
@@ -55,5 +145,8 @@ export declare function readNextConfigBasePath(dotNextPath: string): string;
|
|
|
55
145
|
* land under), the config is the prefix the app emits its own links and asset
|
|
56
146
|
* hrefs under — so how strictly they have to line up, and whether one can stand
|
|
57
147
|
* in for the other, depends on how the `NextjsType` routes static requests.
|
|
148
|
+
*
|
|
149
|
+
* `apiGateway` is only read for `REGIONAL_FUNCTIONS`, and only when the prop is
|
|
150
|
+
* unset: see `deriveApiGatewayBasePath`.
|
|
58
151
|
*/
|
|
59
|
-
export declare function resolveBasePath(nextjsType: NextjsType, propBasePath?: string, nextConfigBasePath?: string): string | undefined;
|
|
152
|
+
export declare function resolveBasePath(nextjsType: NextjsType, propBasePath?: string, nextConfigBasePath?: string, apiGateway?: ApiGatewayPrefix): string | undefined;
|
package/lib/utils/base-path.js
CHANGED
|
@@ -1,12 +1,21 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DEFAULT_API_GATEWAY_PREFIX = void 0;
|
|
3
4
|
exports.normalizeBasePath = normalizeBasePath;
|
|
5
|
+
exports.hasPathPrefix = hasPathPrefix;
|
|
6
|
+
exports.basePathPrefix = basePathPrefix;
|
|
7
|
+
exports.wholeAppInvalidationPaths = wholeAppInvalidationPaths;
|
|
4
8
|
exports.joinPath = joinPath;
|
|
5
9
|
exports.prefixWithBasePath = prefixWithBasePath;
|
|
6
|
-
exports.
|
|
10
|
+
exports.relativeAssetPrefix = relativeAssetPrefix;
|
|
11
|
+
exports.isAssetPrefixUnserved = isAssetPrefixUnserved;
|
|
12
|
+
exports.assetPrefixPath = assetPrefixPath;
|
|
7
13
|
exports.resolveBasePath = resolveBasePath;
|
|
8
|
-
|
|
9
|
-
|
|
14
|
+
/**
|
|
15
|
+
* Pure `basePath` and URL path helpers. Nothing here imports `aws-cdk-lib` or
|
|
16
|
+
* touches the filesystem, so the adapter and runtime bundles can import it as
|
|
17
|
+
* well as the constructs.
|
|
18
|
+
*/
|
|
10
19
|
const constants_1 = require("../constants");
|
|
11
20
|
/**
|
|
12
21
|
* Reduces a `basePath` to a bare path segment so values that address the same
|
|
@@ -16,6 +25,39 @@ const constants_1 = require("../constants");
|
|
|
16
25
|
function normalizeBasePath(basePath) {
|
|
17
26
|
return (basePath || "").replace(/^\/+/, "").replace(/\/+$/, "");
|
|
18
27
|
}
|
|
28
|
+
/**
|
|
29
|
+
* Whether `path` is `prefix` or under it on a segment boundary, so `/docsearch`
|
|
30
|
+
* is not under `/docs`. An empty `prefix` matches nothing. Both sides must be in
|
|
31
|
+
* the same form (both with or both without the leading `/`).
|
|
32
|
+
*/
|
|
33
|
+
function hasPathPrefix(path, prefix) {
|
|
34
|
+
return !!prefix && (path === prefix || path.startsWith(`${prefix}/`));
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* A `basePath` as Next.js spells it and URLs start with it: one leading slash,
|
|
38
|
+
* no trailing one ("/base"), `""` for none. Accepts any spelling
|
|
39
|
+
* {@link normalizeBasePath} does.
|
|
40
|
+
*/
|
|
41
|
+
function basePathPrefix(basePath) {
|
|
42
|
+
const bare = normalizeBasePath(basePath);
|
|
43
|
+
return bare ? `/${bare}` : "";
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Invalidation paths covering every URI of the app: what a deploy invalidates,
|
|
47
|
+
* and what the cache handler's oversized batches, retries after a quota error,
|
|
48
|
+
* and tags whose routes could not all be named fall back to.
|
|
49
|
+
*
|
|
50
|
+
* `/*` is the whole app only without a `basePath`. `/base/*` matches neither the
|
|
51
|
+
* app's root, `/base`, nor its RSC payload, `/base?_rsc=…` - the same root the
|
|
52
|
+
* `revalidatePath("/")` that overflowed may have named - so those are spelled
|
|
53
|
+
* out. `/base*` would cover them for one wildcard, but also every sibling
|
|
54
|
+
* prefix (`/base2`, `/basement`), which may be another app on the same
|
|
55
|
+
* distribution.
|
|
56
|
+
*/
|
|
57
|
+
function wholeAppInvalidationPaths(basePath) {
|
|
58
|
+
const prefix = basePathPrefix(basePath);
|
|
59
|
+
return prefix ? [prefix, `${prefix}?*`, `${prefix}/*`] : ["/*"];
|
|
60
|
+
}
|
|
19
61
|
/**
|
|
20
62
|
* Joins path parts with a single "/", normalizing each (so no leading or
|
|
21
63
|
* trailing slash survives, including on the result) and dropping the empty
|
|
@@ -32,8 +74,8 @@ function joinPath(...parts) {
|
|
|
32
74
|
* answers "/api/health" and "/api/health/" differently.
|
|
33
75
|
*
|
|
34
76
|
* Use this for paths handed to something that talks to the app directly — an ALB
|
|
35
|
-
* target group health check, the
|
|
36
|
-
*
|
|
77
|
+
* target group health check, the container's own health probe — since the app
|
|
78
|
+
* only answers under its own `basePath`.
|
|
37
79
|
*
|
|
38
80
|
* Prefixes unconditionally, so `path` has to arrive as the app routes it,
|
|
39
81
|
* without `basePath`: for an app based at "/base", "/base/api/health" becomes
|
|
@@ -47,37 +89,159 @@ function prefixWithBasePath(basePath, path) {
|
|
|
47
89
|
const absolute = path.startsWith("/") ? path : `/${path}`;
|
|
48
90
|
return normalized ? `/${normalized}${absolute}` : absolute;
|
|
49
91
|
}
|
|
92
|
+
/** Whether an `assetPrefix` names an origin rather than a path on this one. */
|
|
93
|
+
function isAbsoluteAssetPrefix(assetPrefix) {
|
|
94
|
+
return /^([a-z][a-z0-9+.-]*:)?\/\//i.test(assetPrefix);
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* The app's own `assetPrefix` as a path with a leading and no trailing slash
|
|
98
|
+
* ("/cdn"), or `""` when the app sets none.
|
|
99
|
+
*
|
|
100
|
+
* Returns `""` for an absolute `assetPrefix` ("https://cdn.example.com", or the
|
|
101
|
+
* protocol-relative "//cdn.example.com") too: that names an origin cdk-nextjs
|
|
102
|
+
* does not control, and it is the supported way to serve assets from elsewhere,
|
|
103
|
+
* so nothing about it is worth warning about. Use {@link assetPrefixPath} for
|
|
104
|
+
* what the *distribution* has to answer on, which includes the path an absolute
|
|
105
|
+
* prefix carries.
|
|
106
|
+
*
|
|
107
|
+
* Next.js applies `assetPrefix` on top of, not under, `basePath`, so the result
|
|
108
|
+
* is the whole prefix of a `_next/static` URL and must not be joined with
|
|
109
|
+
* `basePath`.
|
|
110
|
+
*/
|
|
111
|
+
function relativeAssetPrefix(assetPrefix) {
|
|
112
|
+
return isAbsoluteAssetPrefix(assetPrefix) ? "" : basePathPrefix(assetPrefix);
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Whether a path-style `assetPrefix` would go unanswered on this `NextjsType`,
|
|
116
|
+
* i.e. whether every bundle would 404.
|
|
117
|
+
*
|
|
118
|
+
* `assetPrefix` moves every bundle URL to `<assetPrefix>/_next/static/...` while
|
|
119
|
+
* the objects keep their `<basePath>/_next/static/...` S3 keys. The Global
|
|
120
|
+
* `NextjsType`s answer that with a cache behavior of their own
|
|
121
|
+
* (`NextjsDistribution`); the regional ones have nothing that maps the prefix
|
|
122
|
+
* back — API Gateway's `_next/static` resource and the container's own files are
|
|
123
|
+
* both under the unprefixed path.
|
|
124
|
+
*
|
|
125
|
+
* A prefix equal to the app's own `basePath` is **not** unserved, because that is
|
|
126
|
+
* the value Next.js resolves `assetPrefix` to when `basePath` is set and
|
|
127
|
+
* `assetPrefix` is not: `.next/required-server-files.json` comes back as
|
|
128
|
+
* `{"assetPrefix":"/prod","basePath":"/prod"}` for an app that only ever set
|
|
129
|
+
* `basePath`. Without that exemption the warning fired on every regional
|
|
130
|
+
* deployment that sets a `basePath` at all — including `examples/regional-functions`
|
|
131
|
+
* — telling users their bundles would 404 at the one path that does serve them.
|
|
132
|
+
* `NextjsDistribution.resolveAssetPrefix` drops the prefix for the same reason.
|
|
133
|
+
*
|
|
134
|
+
* Both sides go through `normalizeBasePath` because they arrive in different
|
|
135
|
+
* shapes: `nextConfigAssetPrefix` carries a leading slash (`"/prod"`),
|
|
136
|
+
* `nextConfigBasePath` does not (`"prod"`).
|
|
137
|
+
*/
|
|
138
|
+
function isAssetPrefixUnserved(nextjsType, nextConfigAssetPrefix, nextConfigBasePath) {
|
|
139
|
+
if (!nextConfigAssetPrefix)
|
|
140
|
+
return false;
|
|
141
|
+
if (nextjsType === constants_1.NextjsType.GLOBAL_FUNCTIONS ||
|
|
142
|
+
nextjsType === constants_1.NextjsType.GLOBAL_CONTAINERS) {
|
|
143
|
+
return false;
|
|
144
|
+
}
|
|
145
|
+
return (normalizeBasePath(nextConfigAssetPrefix) !==
|
|
146
|
+
normalizeBasePath(nextConfigBasePath));
|
|
147
|
+
}
|
|
50
148
|
/**
|
|
51
|
-
*
|
|
52
|
-
*
|
|
53
|
-
*
|
|
54
|
-
*
|
|
149
|
+
* The *path* every bundle URL carries, whichever form `assetPrefix` takes: "/cdn"
|
|
150
|
+
* for `assetPrefix: "/cdn"` and for `assetPrefix:
|
|
151
|
+
* "https://cdn.example.com/cdn"` alike, `""` when there is none (an absolute
|
|
152
|
+
* prefix with no path, or no prefix at all).
|
|
55
153
|
*
|
|
56
|
-
*
|
|
57
|
-
*
|
|
58
|
-
*
|
|
59
|
-
*
|
|
60
|
-
*
|
|
154
|
+
* An absolute prefix's path counts because `next build` compiles a `beforeFiles`
|
|
155
|
+
* rewrite of its own for it — `/cdn/_next/:path+ → /_next/:path+` — so `next
|
|
156
|
+
* start` serves every bundle under that path as well as under `/_next`. A CDN
|
|
157
|
+
* fronting this deployment at that path therefore has to be answered, and the
|
|
158
|
+
* distribution's `assetPrefix` behavior is what answers it. Measured against
|
|
159
|
+
* `test/e2e/app-dir/asset-prefix-absolute`; see `docs/harness-coverage.md`.
|
|
160
|
+
* Shared with `NextjsDistribution`, whose `assetPrefix` prop a user can also
|
|
161
|
+
* set by hand.
|
|
61
162
|
*/
|
|
62
|
-
function
|
|
63
|
-
|
|
64
|
-
const fallback = (reason) => {
|
|
65
|
-
console.warn(`${constants_1.LOG_PREFIX} ${reason}. Assuming your Next.js app sets no \`basePath\`: ` +
|
|
66
|
-
"if it does set one, static assets will 404 and any `basePath` prop " +
|
|
67
|
-
"mismatch reported at synth will name the wrong value.");
|
|
163
|
+
function assetPrefixPath(assetPrefix) {
|
|
164
|
+
if (!assetPrefix)
|
|
68
165
|
return "";
|
|
69
|
-
|
|
70
|
-
if (
|
|
71
|
-
|
|
166
|
+
let path = assetPrefix;
|
|
167
|
+
if (isAbsoluteAssetPrefix(assetPrefix)) {
|
|
168
|
+
try {
|
|
169
|
+
// `//cdn.example.com/cdn` is protocol-relative, which `URL` only parses
|
|
170
|
+
// with a base — any base, since only the path is read off it.
|
|
171
|
+
path = new URL(assetPrefix, "https://asset-prefix.invalid").pathname;
|
|
172
|
+
}
|
|
173
|
+
catch {
|
|
174
|
+
return "";
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
return basePathPrefix(path);
|
|
178
|
+
}
|
|
179
|
+
/** `RestApi`'s own defaults: the `prod` stage, no custom domain. */
|
|
180
|
+
exports.DEFAULT_API_GATEWAY_PREFIX = {
|
|
181
|
+
strippedPrefix: "prod",
|
|
182
|
+
customDomain: false,
|
|
183
|
+
};
|
|
184
|
+
/**
|
|
185
|
+
* The resource path an app's `basePath` needs on `REGIONAL_FUNCTIONS` when the
|
|
186
|
+
* `basePath` prop is unset: the app's `basePath` with the prefix API Gateway
|
|
187
|
+
* strips taken off the front, or the whole of it when it does not start with
|
|
188
|
+
* that prefix.
|
|
189
|
+
*
|
|
190
|
+
* An app at the `prod` stage emits `/prod/...` and API Gateway strips `/prod`
|
|
191
|
+
* before matching, so `basePath: "/prod"` needs resources at the root and
|
|
192
|
+
* `basePath: "/prod/base"` needs them under `base`. An app whose `basePath` API
|
|
193
|
+
* Gateway does not strip — a custom domain mapped at the root, serving
|
|
194
|
+
* `basePath: "/docs"` — needs them under `docs`. Leaving that one at the root is
|
|
195
|
+
* what used to happen: `_next/static` and `public/` fell through to the
|
|
196
|
+
* `{proxy+}` catch-all, and every bundle 404'd with nothing said at synth.
|
|
197
|
+
*/
|
|
198
|
+
function deriveApiGatewayBasePath(config, { strippedPrefix, customDomain }) {
|
|
199
|
+
if (!config || strippedPrefix === undefined) {
|
|
200
|
+
return undefined;
|
|
201
|
+
}
|
|
202
|
+
const stripped = normalizeBasePath(strippedPrefix);
|
|
203
|
+
if (hasPathPrefix(config, stripped)) {
|
|
204
|
+
return config.slice(stripped.length + 1) || undefined;
|
|
205
|
+
}
|
|
206
|
+
warnUnstrippedBasePath(config, { strippedPrefix, customDomain });
|
|
207
|
+
return config;
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Warn that an app mounted under its whole `basePath` is served somewhere its
|
|
211
|
+
* own links don't reach, when API Gateway strips a prefix that `basePath` lacks.
|
|
212
|
+
* Both ways of arriving there warn: the prop left unset (derived to the whole
|
|
213
|
+
* `basePath`) and the prop set to the same value.
|
|
214
|
+
*/
|
|
215
|
+
function warnUnstrippedBasePath(config, { strippedPrefix, customDomain }) {
|
|
216
|
+
const stripped = normalizeBasePath(strippedPrefix);
|
|
217
|
+
if (strippedPrefix === undefined || !stripped) {
|
|
218
|
+
// A token, or a custom domain mapped at the root: nothing is stripped that
|
|
219
|
+
// the app's links could miss.
|
|
220
|
+
return;
|
|
72
221
|
}
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
222
|
+
if (customDomain) {
|
|
223
|
+
// The same miss through a custom domain's base path mapping: served at
|
|
224
|
+
// `/<mapping>/<basePath>`, linking to `/<basePath>/...`, which no mapping
|
|
225
|
+
// covers.
|
|
226
|
+
console.warn(`${constants_1.LOG_PREFIX} your Next.js app's \`basePath\` is ${quote(config)}, which does not start with the custom domain's base path mapping "/${stripped}". ` +
|
|
227
|
+
"Its links and bundle URLs will be requested without the mapping, which the custom domain answers with 403. " +
|
|
228
|
+
`Set \`basePath: "/${joinPath(stripped, config)}"\` in your next.config, or map the domain at the root.`);
|
|
76
229
|
}
|
|
77
|
-
|
|
78
|
-
|
|
230
|
+
else {
|
|
231
|
+
// Resources under the app's basePath serve it at `/<stage>/<basePath>`, but
|
|
232
|
+
// the app's own links are `/<basePath>/...`, which misses the stage. A
|
|
233
|
+
// warning, not an error: a domain attached after synth (`addDomainName`)
|
|
234
|
+
// makes it right, and synth cannot see that.
|
|
235
|
+
console.warn(`${constants_1.LOG_PREFIX} your Next.js app's \`basePath\` is ${quote(config)}, which does not start with the API Gateway stage "/${stripped}". ` +
|
|
236
|
+
"Its links and bundle URLs will be requested without the stage, which the execute-api endpoint answers with 403. " +
|
|
237
|
+
`Set \`basePath: "/${joinPath(stripped, config)}"\` in your next.config, or serve the app from a custom domain mapped at the root.`);
|
|
79
238
|
}
|
|
80
239
|
}
|
|
240
|
+
/** Whether API Gateway strips the front of `basePath` before matching resources. */
|
|
241
|
+
function startsWithStrippedPrefix(basePath, { strippedPrefix }) {
|
|
242
|
+
const stripped = normalizeBasePath(strippedPrefix);
|
|
243
|
+
return !!basePath && hasPathPrefix(basePath, stripped);
|
|
244
|
+
}
|
|
81
245
|
function quote(basePath) {
|
|
82
246
|
return basePath ? `"/${basePath}"` : "unset";
|
|
83
247
|
}
|
|
@@ -93,15 +257,43 @@ function quote(basePath) {
|
|
|
93
257
|
* land under), the config is the prefix the app emits its own links and asset
|
|
94
258
|
* hrefs under — so how strictly they have to line up, and whether one can stand
|
|
95
259
|
* in for the other, depends on how the `NextjsType` routes static requests.
|
|
260
|
+
*
|
|
261
|
+
* `apiGateway` is only read for `REGIONAL_FUNCTIONS`, and only when the prop is
|
|
262
|
+
* unset: see `deriveApiGatewayBasePath`.
|
|
96
263
|
*/
|
|
97
|
-
function resolveBasePath(nextjsType, propBasePath, nextConfigBasePath) {
|
|
264
|
+
function resolveBasePath(nextjsType, propBasePath, nextConfigBasePath, apiGateway = exports.DEFAULT_API_GATEWAY_PREFIX) {
|
|
98
265
|
const prop = normalizeBasePath(propBasePath);
|
|
99
266
|
const config = normalizeBasePath(nextConfigBasePath);
|
|
267
|
+
const mismatch = `${constants_1.LOG_PREFIX} basePath mismatch for NextjsType.${nextjsType}: the \`basePath\` prop is ${quote(prop)} ` +
|
|
268
|
+
`but your Next.js app's config sets \`basePath\` to ${quote(config)}. `;
|
|
100
269
|
if (prop === config) {
|
|
270
|
+
if (nextjsType === constants_1.NextjsType.REGIONAL_FUNCTIONS &&
|
|
271
|
+
startsWithStrippedPrefix(prop, apiGateway)) {
|
|
272
|
+
// Agreeing is not enough here: API Gateway strips the stage (or base path
|
|
273
|
+
// mapping) before matching, so resources under the prop's "prod" are only
|
|
274
|
+
// reached at `/prod/prod/...`, and every link the app emits 403s.
|
|
275
|
+
const problem = `API Gateway strips "/${normalizeBasePath(apiGateway.strippedPrefix)}" before matching resources, so a prop that repeats it nests every resource under a path no request reaches. ` +
|
|
276
|
+
"Leave the prop unset: it is derived from your app's `basePath` with that prefix taken off.";
|
|
277
|
+
if (apiGateway.customDomain) {
|
|
278
|
+
throw new Error(mismatch + problem);
|
|
279
|
+
}
|
|
280
|
+
// On the execute-api endpoint that is certain, but an explicit prop wins:
|
|
281
|
+
// a domain attached with `addDomainName()`, invisible here, can map the
|
|
282
|
+
// stage at its root, and then `/prod/...` does reach resources under
|
|
283
|
+
// "prod".
|
|
284
|
+
console.warn(mismatch +
|
|
285
|
+
problem +
|
|
286
|
+
" (Ignore this if a domain attached with `addDomainName()` serves the app without stripping that prefix.)");
|
|
287
|
+
return prop;
|
|
288
|
+
}
|
|
289
|
+
if (nextjsType === constants_1.NextjsType.REGIONAL_FUNCTIONS && prop) {
|
|
290
|
+
// Agreeing the other way round has the unset case's problem: resources
|
|
291
|
+
// under "docs" are reached at `/prod/docs/...`, the app links to
|
|
292
|
+
// `/docs/...`.
|
|
293
|
+
warnUnstrippedBasePath(config, apiGateway);
|
|
294
|
+
}
|
|
101
295
|
return prop || undefined;
|
|
102
296
|
}
|
|
103
|
-
const mismatch = `${constants_1.LOG_PREFIX} basePath mismatch for NextjsType.${nextjsType}: the \`basePath\` prop is ${quote(prop)} ` +
|
|
104
|
-
`but your Next.js app's config sets \`basePath\` to ${quote(config)}. `;
|
|
105
297
|
switch (nextjsType) {
|
|
106
298
|
case constants_1.NextjsType.GLOBAL_FUNCTIONS:
|
|
107
299
|
case constants_1.NextjsType.GLOBAL_CONTAINERS:
|
|
@@ -117,26 +309,47 @@ function resolveBasePath(nextjsType, propBasePath, nextConfigBasePath) {
|
|
|
117
309
|
"CloudFront serves static assets straight from S3 using the request path as the object key, so a mismatch means every `_next/static` and `public/` request 404s. " +
|
|
118
310
|
"Either set both to the same value, or drop the prop — left unset, it follows your app's `basePath`.");
|
|
119
311
|
case constants_1.NextjsType.REGIONAL_FUNCTIONS:
|
|
120
|
-
// Deliberately not derived: API Gateway mounts resources below the stage
|
|
121
|
-
// and strips it before invoking the app, so an app whose basePath is the
|
|
122
|
-
// stage name (or a custom domain base path mapping that gets stripped the
|
|
123
|
-
// same way) is correct precisely because the prop stays unset.
|
|
124
312
|
if (!prop) {
|
|
125
|
-
|
|
313
|
+
// A prop that is set but names no path ("/") is an explicit root
|
|
314
|
+
// mount, not "unset": it is how an app says the prefix is stripped by
|
|
315
|
+
// something synth can't see — a domain attached later with
|
|
316
|
+
// `addDomainName({ basePath })`, say — so deriving here would nest the
|
|
317
|
+
// resources under a path the stripped requests never reach.
|
|
318
|
+
if (propBasePath !== undefined) {
|
|
319
|
+
return undefined;
|
|
320
|
+
}
|
|
321
|
+
return deriveApiGatewayBasePath(config, apiGateway);
|
|
126
322
|
}
|
|
127
323
|
// The prop only has to be the tail of what the app emits, not all of it,
|
|
128
324
|
// because the stripped prefix is part of the app's `basePath` but never
|
|
129
325
|
// part of the resource path: an app at the `prod` stage nested under
|
|
130
|
-
// "/base" sets `basePath: "/prod/base"` and the prop to "/base".
|
|
131
|
-
//
|
|
132
|
-
|
|
326
|
+
// "/base" sets `basePath: "/prod/base"` and the prop to "/base". Exactly
|
|
327
|
+
// the stripped prefix and then the prop, not any tail: with a prop of
|
|
328
|
+
// "/base" an app at "/foo/base" is served at `/prod/base/...` and links
|
|
329
|
+
// to `/foo/base/...`, which 403s. Only a token stage, which synth can't
|
|
330
|
+
// read, falls back to a tail on a path boundary.
|
|
331
|
+
if (apiGateway.strippedPrefix === undefined
|
|
332
|
+
? config.endsWith(`/${prop}`)
|
|
333
|
+
: config === joinPath(apiGateway.strippedPrefix, prop)) {
|
|
334
|
+
return prop;
|
|
335
|
+
}
|
|
336
|
+
// Any tail on a path boundary is also what a domain attached with
|
|
337
|
+
// `addDomainName({ basePath: "v1" })` needs for an app at "/v1/base":
|
|
338
|
+
// synth only sees the stage, so it can't tell that setup from a mistake.
|
|
339
|
+
// An explicit prop wins, so that warns; a custom domain configured in
|
|
340
|
+
// `restApiProps.domainName` is visible, so there it still throws below.
|
|
341
|
+
if (!apiGateway.customDomain && config.endsWith(`/${prop}`)) {
|
|
342
|
+
const leading = config.slice(0, -prop.length - 1);
|
|
343
|
+
console.warn(`${constants_1.LOG_PREFIX} the \`basePath\` prop is ${quote(prop)} and your Next.js app's \`basePath\` is ${quote(config)}, ` +
|
|
344
|
+
`so the app is served at "/${joinPath(normalizeBasePath(apiGateway.strippedPrefix), prop)}" on the execute-api endpoint and links to "/${config}". ` +
|
|
345
|
+
`That only works through a custom domain whose base path mapping strips "/${leading}" (\`addDomainName({ basePath: "${leading}" })\`); otherwise every request 403s.`);
|
|
133
346
|
return prop;
|
|
134
347
|
}
|
|
135
348
|
// Anything else never works: the prop moves every resource, including the
|
|
136
349
|
// `ANY` catch-all, under a path the app never links to.
|
|
137
350
|
throw new Error(mismatch +
|
|
138
351
|
"The `basePath` prop nests every API Gateway resource under that path, including the catch-all, so the app has to emit its links under the same prefix or every request 404s. " +
|
|
139
|
-
'Either set your app\'s `basePath` to
|
|
352
|
+
'Either set your app\'s `basePath` to the prop, or to the prop prefixed by the stage or base path mapping API Gateway strips (e.g. `basePath: "/prod/base"` with a prop of "/base"), or leave the prop unset — unset is what you want when the app\'s `basePath` is the API Gateway stage name, since the stage isn\'t part of the resource path.');
|
|
140
353
|
case constants_1.NextjsType.REGIONAL_CONTAINERS:
|
|
141
354
|
// The ALB forwards every path to the container, which serves its own
|
|
142
355
|
// static assets, so here `basePath` only namespaces the S3 bucket and has
|
|
@@ -144,4 +357,4 @@ function resolveBasePath(nextjsType, propBasePath, nextConfigBasePath) {
|
|
|
144
357
|
return prop || undefined;
|
|
145
358
|
}
|
|
146
359
|
}
|
|
147
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmFzZS1wYXRoLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3V0aWxzL2Jhc2UtcGF0aC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQVNBLDhDQUVDO0FBT0QsNEJBRUM7QUFvQkQsZ0RBT0M7QUFjRCx3REF1QkM7QUFtQkQsMENBNERDO0FBbktELHFDQUFtRDtBQUNuRCx5Q0FBaUM7QUFDakMsNENBQXNEO0FBRXREOzs7O0dBSUc7QUFDSCxTQUFnQixpQkFBaUIsQ0FBQyxRQUFpQjtJQUNqRCxPQUFPLENBQUMsUUFBUSxJQUFJLEVBQUUsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxNQUFNLEVBQUUsRUFBRSxDQUFDLENBQUMsT0FBTyxDQUFDLE1BQU0sRUFBRSxFQUFFLENBQUMsQ0FBQztBQUNsRSxDQUFDO0FBRUQ7Ozs7R0FJRztBQUNILFNBQWdCLFFBQVEsQ0FBQyxHQUFHLEtBQTZCO0lBQ3ZELE9BQU8sS0FBSyxDQUFDLEdBQUcsQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDaEUsQ0FBQztBQUVEOzs7Ozs7Ozs7Ozs7Ozs7OztHQWlCRztBQUNILFNBQWdCLGtCQUFrQixDQUNoQyxRQUE0QixFQUM1QixJQUFZO0lBRVosTUFBTSxVQUFVLEdBQUcsaUJBQWlCLENBQUMsUUFBUSxDQUFDLENBQUM7SUFDL0MsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxJQUFJLElBQUksRUFBRSxDQUFDO0lBQzFELE9BQU8sVUFBVSxDQUFDLENBQUMsQ0FBQyxJQUFJLFVBQVUsR0FBRyxRQUFRLEVBQUUsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDO0FBQzdELENBQUM7QUFFRDs7Ozs7Ozs7Ozs7R0FXRztBQUNILFNBQWdCLHNCQUFzQixDQUFDLFdBQW1CO0lB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QUFtQjtZQUNqQyxxRUFBcUU7WUFDckUsMEVBQTBFO1lBQzFFLHVEQUF1RDtZQUN2RCxPQUFPLElBQUksSUFBSSxTQUFTLENBQUM7SUFDN0IsQ0FBQztBQUNILENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBleGlzdHNTeW5jLCByZWFkRmlsZVN5bmMgfSBmcm9tIFwibm9kZTpmc1wiO1xuaW1wb3J0IHsgam9pbiB9IGZyb20gXCJub2RlOnBhdGhcIjtcbmltcG9ydCB7IExPR19QUkVGSVgsIE5leHRqc1R5cGUgfSBmcm9tIFwiLi4vY29uc3RhbnRzXCI7XG5cbi8qKlxuICogUmVkdWNlcyBhIGBiYXNlUGF0aGAgdG8gYSBiYXJlIHBhdGggc2VnbWVudCBzbyB2YWx1ZXMgdGhhdCBhZGRyZXNzIHRoZSBzYW1lXG4gKiBwYXRoIChcIi9iYXNlXCIsIFwiYmFzZVwiLCBcIi9iYXNlL1wiKSBjb21wYXJlIGVxdWFsIGFuZCBjYW4gYmUgY29uY2F0ZW5hdGVkXG4gKiB3aXRob3V0IGRvdWJsaW5nIHNlcGFyYXRvcnMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBub3JtYWxpemVCYXNlUGF0aChiYXNlUGF0aD86IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiAoYmFzZVBhdGggfHwgXCJcIikucmVwbGFjZSgvXlxcLysvLCBcIlwiKS5yZXBsYWNlKC9cXC8rJC8sIFwiXCIpO1xufVxuXG4vKipcbiAqIEpvaW5zIHBhdGggcGFydHMgd2l0aCBhIHNpbmdsZSBcIi9cIiwgbm9ybWFsaXppbmcgZWFjaCAoc28gbm8gbGVhZGluZyBvclxuICogdHJhaWxpbmcgc2xhc2ggc3Vydml2ZXMsIGluY2x1ZGluZyBvbiB0aGUgcmVzdWx0KSBhbmQgZHJvcHBpbmcgdGhlIGVtcHR5XG4gKiBvbmVzLCBzbyBhbiB1bnNldCBgYmFzZVBhdGhgIG9yIGtleSBwcmVmaXggbGVhdmVzIHRoZSByZXN0IHVudG91Y2hlZC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGpvaW5QYXRoKC4uLnBhcnRzOiAoc3RyaW5nIHwgdW5kZWZpbmVkKVtdKTogc3RyaW5nIHtcbiAgcmV0dXJuIHBhcnRzLm1hcChub3JtYWxpemVCYXNlUGF0aCkuZmlsdGVyKEJvb2xlYW4pLmpvaW4oXCIvXCIpO1xufVxuXG4vKipcbiAqIFByZWZpeGVzIGFuIGFic29sdXRlIGFwcCBwYXRoIChhIGhlYWx0aCBjaGVjayBwYXRoLCBzYXkpIHdpdGggYGJhc2VQYXRoYCxcbiAqIGFsd2F5cyByZXR1cm5pbmcgYSBsZWFkaW5nIHNsYXNoLiBBbiBlbXB0eSBvciB1bnNldCBgYmFzZVBhdGhgIG9ubHlcbiAqIG5vcm1hbGl6ZXMgdGhhdCBsZWFkaW5nIHNsYXNoLiBBbnl0aGluZyBhZnRlciB0aGUgZmlyc3Qgc2VnbWVudCBpcyBwYXNzZWRcbiAqIHRocm91Z2ggYXMgZ2l2ZW4sIHRyYWlsaW5nIHNsYXNoIGluY2x1ZGVkLCBzaW5jZSBhIGB0cmFpbGluZ1NsYXNoYCBhcHBcbiAqIGFuc3dlcnMgXCIvYXBpL2hlYWx0aFwiIGFuZCBcIi9hcGkvaGVhbHRoL1wiIGRpZmZlcmVudGx5LlxuICpcbiAqIFVzZSB0aGlzIGZvciBwYXRocyBoYW5kZWQgdG8gc29tZXRoaW5nIHRoYXQgdGFsa3MgdG8gdGhlIGFwcCBkaXJlY3RseSDigJQgYW4gQUxCXG4gKiB0YXJnZXQgZ3JvdXAgaGVhbHRoIGNoZWNrLCB0aGUgTGFtYmRhIFdlYiBBZGFwdGVyIHJlYWRpbmVzcyBjaGVjayDigJQgc2luY2UgdGhlXG4gKiBhcHAgb25seSBhbnN3ZXJzIHVuZGVyIGl0cyBvd24gYGJhc2VQYXRoYC5cbiAqXG4gKiBQcmVmaXhlcyB1bmNvbmRpdGlvbmFsbHksIHNvIGBwYXRoYCBoYXMgdG8gYXJyaXZlIGFzIHRoZSBhcHAgcm91dGVzIGl0LFxuICogd2l0aG91dCBgYmFzZVBhdGhgOiBmb3IgYW4gYXBwIGJhc2VkIGF0IFwiL2Jhc2VcIiwgXCIvYmFzZS9hcGkvaGVhbHRoXCIgYmVjb21lc1xuICogXCIvYmFzZS9iYXNlL2FwaS9oZWFsdGhcIi4gRGVsaWJlcmF0ZWx5IG5vdCBzcGVjaWFsLWNhc2VkIOKAlCBhbiBhcHAgY2FuIHJvdXRlXG4gKiBcIi9iYXNlL2Jhc2UvLi4uXCIgbGVnaXRpbWF0ZWx5LCBhbmQgYWNjZXB0aW5nIGJvdGggc3BlbGxpbmdzIHdvdWxkIGdpdmUgdGhlXG4gKiBwYXRoIHR3byBtZWFuaW5ncy4gU2VlIGBkb2NzL2JyZWFraW5nLWNoYW5nZXMubWRgICgwLjYuMCksIHdoaWNoIHRlbGxzIHVzZXJzXG4gKiB3aG8gcHJlZml4ZWQgYGhlYWx0aENoZWNrUGF0aGAgYnkgaGFuZCB0byBkcm9wIHRoZSBwcmVmaXguXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwcmVmaXhXaXRoQmFzZVBhdGgoXG4gIGJhc2VQYXRoOiBzdHJpbmcgfCB1bmRlZmluZWQsXG4gIHBhdGg6IHN0cmluZyxcbik6IHN0cmluZyB7XG4gIGNvbnN0IG5vcm1hbGl6ZWQgPSBub3JtYWxpemVCYXNlUGF0aChiYXNlUGF0aCk7XG4gIGNvbnN0IGFic29sdXRlID0gcGF0aC5zdGFydHNXaXRoKFwiL1wiKSA/IHBhdGggOiBgLyR7cGF0aH1gO1xuICByZXR1cm4gbm9ybWFsaXplZCA/IGAvJHtub3JtYWxpemVkfSR7YWJzb2x1dGV9YCA6IGFic29sdXRlO1xufVxuXG4vKipcbiAqIFJlYWQgdGhlIE5leHQuanMgYXBwJ3Mgb3duIGBiYXNlUGF0aGAgb3V0IG9mIGByZXF1aXJlZC1zZXJ2ZXItZmlsZXMuanNvbmAsXG4gKiB3aGljaCBgbmV4dCBidWlsZGAgd3JpdGVzIGludG8gYC5uZXh0YCB3aXRoIHRoZSBmdWxseSByZXNvbHZlZCBjb25maWcgKHNvXG4gKiB0aGlzIHBpY2tzIHVwIGEgYGJhc2VQYXRoYCBjb21wdXRlZCBpbiBgbmV4dC5jb25maWcuanNgLCBub3Qgb25seSBhIGxpdGVyYWxcbiAqIG9uZSkuIE5vcm1hbGl6ZWQsIGVtcHR5IHdoZW4gdGhlIGFwcCBzZXRzIG5vbmUuXG4gKlxuICogRGVncmFkZXMgdG8gYFwiXCJgIHJhdGhlciB0aGFuIHRocm93aW5nLCBzaW5jZSBhbiB1bnJlYWRhYmxlIGZpbGUgc2hvdWxkbid0XG4gKiBmYWlsIGEgZGVwbG95bWVudCB0aGF0IHdvdWxkIG90aGVyd2lzZSB3b3JrLiBJdCB3YXJucyBiZWNhdXNlIGBcIlwiYCBpc1xuICogaW5kaXN0aW5ndWlzaGFibGUgZnJvbSBhbiBhcHAgdGhhdCBnZW51aW5lbHkgc2V0cyBubyBgYmFzZVBhdGhgOiB0aGVcbiAqIGBOZXh0anNUeXBlYHMgdGhhdCBkZXJpdmUgYGJhc2VQYXRoYCBmcm9tIHRoZSBhcHAgd291bGQgcXVpZXRseSBub3QgZGVyaXZlXG4gKiBpdCBhbmQgNDA0IGV2ZXJ5IHN0YXRpYyBhc3NldC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlYWROZXh0Q29uZmlnQmFzZVBhdGgoZG90TmV4dFBhdGg6IHN0cmluZyk6IHN0cmluZyB7XG4gIGNvbnN0IHJlcXVpcmVkU2VydmVyRmlsZXMgPSBqb2luKGRvdE5leHRQYXRoLCBcInJlcXVpcmVkLXNlcnZlci1maWxlcy5qc29uXCIpO1xuICBjb25zdCBmYWxsYmFjayA9IChyZWFzb246IHN0cmluZykgPT4ge1xuICAgIGNvbnNvbGUud2FybihcbiAgICAgIGAke0xPR19QUkVGSVh9ICR7cmVhc29ufS4gQXNzdW1pbmcgeW91ciBOZXh0LmpzIGFwcCBzZXRzIG5vIFxcYGJhc2VQYXRoXFxgOiBgICtcbiAgICAgICAgXCJpZiBpdCBkb2VzIHNldCBvbmUsIHN0YXRpYyBhc3NldHMgd2lsbCA0MDQgYW5kIGFueSBgYmFzZVBhdGhgIHByb3AgXCIgK1xuICAgICAgICBcIm1pc21hdGNoIHJlcG9ydGVkIGF0IHN5bnRoIHdpbGwgbmFtZSB0aGUgd3JvbmcgdmFsdWUuXCIsXG4gICAgKTtcbiAgICByZXR1cm4gXCJcIjtcbiAgfTtcbiAgaWYgKCFleGlzdHNTeW5jKHJlcXVpcmVkU2VydmVyRmlsZXMpKSB7XG4gICAgcmV0dXJuIGZhbGxiYWNrKFxuICAgICAgYFwicmVxdWlyZWQtc2VydmVyLWZpbGVzLmpzb25cIiBub3QgZm91bmQgYXQgJHtyZXF1aXJlZFNlcnZlckZpbGVzfWAsXG4gICAgKTtcbiAgfVxuICB0cnkge1xuICAgIGNvbnN0IHsgY29uZmlnIH0gPSBKU09OLnBhcnNlKHJlYWRGaWxlU3luYyhyZXF1aXJlZFNlcnZlckZpbGVzLCBcInV0Zi04XCIpKTtcbiAgICByZXR1cm4gbm9ybWFsaXplQmFzZVBhdGgoY29uZmlnPy5iYXNlUGF0aCk7XG4gIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgcmV0dXJuIGZhbGxiYWNrKFxuICAgICAgYENvdWxkIG5vdCByZWFkIGJhc2VQYXRoIGZyb20gJHtyZXF1aXJlZFNlcnZlckZpbGVzfTogJHtlcnJvcn1gLFxuICAgICk7XG4gIH1cbn1cblxuZnVuY3Rpb24gcXVvdGUoYmFzZVBhdGg6IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiBiYXNlUGF0aCA/IGBcIi8ke2Jhc2VQYXRofVwiYCA6IFwidW5zZXRcIjtcbn1cblxuLyoqXG4gKiBTZXR0bGVzIG9uIHRoZSBzaW5nbGUgYGJhc2VQYXRoYCB0aGUgaW5mcmFzdHJ1Y3R1cmUgc2hvdWxkIGJlIGJ1aWx0IGFyb3VuZCxcbiAqIGdpdmVuIHRoZSBDREsgYGJhc2VQYXRoYCBwcm9wIGFuZCB0aGUgTmV4dC5qcyBhcHAncyBvd24gYGJhc2VQYXRoYFxuICogKGBOZXh0anNCdWlsZC5uZXh0Q29uZmlnQmFzZVBhdGhgKSwgdGhyb3dpbmcgYXQgc3ludGggaWYgdGhlIHR3byBjYW4ndCBzZXJ2ZVxuICogdGhlIGFwcCB0b2dldGhlci4gUmV0dXJucyBhIG5vcm1hbGl6ZWQgdmFsdWUsIG9yIGB1bmRlZmluZWRgIGZvciBub1xuICogYGJhc2VQYXRoYCBhdCBhbGw7IGNvbnN1bWVycyB0aGF0IG5lZWQgYSBsZWFkaW5nIHNsYXNoIGFkZCB0aGVpciBvd24uXG4gKlxuICogVGhlIHR3byBpbnB1dHMgYXJlIGdlbnVpbmVseSBkaWZmZXJlbnQgdGhpbmdzIOKAlCB0aGUgcHJvcCBpcyB3aGVyZSB0aGVcbiAqIGluZnJhc3RydWN0dXJlIHNlcnZlcyB0aGUgYXBwIGZyb20gKGFuZCB3aGljaCBTMyBrZXkgcHJlZml4IHRoZSBzdGF0aWMgYXNzZXRzXG4gKiBsYW5kIHVuZGVyKSwgdGhlIGNvbmZpZyBpcyB0aGUgcHJlZml4IHRoZSBhcHAgZW1pdHMgaXRzIG93biBsaW5rcyBhbmQgYXNzZXRcbiAqIGhyZWZzIHVuZGVyIOKAlCBzbyBob3cgc3RyaWN0bHkgdGhleSBoYXZlIHRvIGxpbmUgdXAsIGFuZCB3aGV0aGVyIG9uZSBjYW4gc3RhbmRcbiAqIGluIGZvciB0aGUgb3RoZXIsIGRlcGVuZHMgb24gaG93IHRoZSBgTmV4dGpzVHlwZWAgcm91dGVzIHN0YXRpYyByZXF1ZXN0cy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlc29sdmVCYXNlUGF0aChcbiAgbmV4dGpzVHlwZTogTmV4dGpzVHlwZSxcbiAgcHJvcEJhc2VQYXRoPzogc3RyaW5nLFxuICBuZXh0Q29uZmlnQmFzZVBhdGg/OiBzdHJpbmcsXG4pOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICBjb25zdCBwcm9wID0gbm9ybWFsaXplQmFzZVBhdGgocHJvcEJhc2VQYXRoKTtcbiAgY29uc3QgY29uZmlnID0gbm9ybWFsaXplQmFzZVBhdGgobmV4dENvbmZpZ0Jhc2VQYXRoKTtcbiAgaWYgKHByb3AgPT09IGNvbmZpZykge1xuICAgIHJldHVybiBwcm9wIHx8IHVuZGVmaW5lZDtcbiAgfVxuXG4gIGNvbnN0IG1pc21hdGNoID1cbiAgICBgJHtMT0dfUFJFRklYfSBiYXNlUGF0aCBtaXNtYXRjaCBmb3IgTmV4dGpzVHlwZS4ke25leHRqc1R5cGV9OiB0aGUgXFxgYmFzZVBhdGhcXGAgcHJvcCBpcyAke3F1b3RlKHByb3ApfSBgICtcbiAgICBgYnV0IHlvdXIgTmV4dC5qcyBhcHAncyBjb25maWcgc2V0cyBcXGBiYXNlUGF0aFxcYCB0byAke3F1b3RlKGNvbmZpZyl9LiBgO1xuXG4gIHN3aXRjaCAobmV4dGpzVHlwZSkge1xuICAgIGNhc2UgTmV4dGpzVHlwZS5HTE9CQUxfRlVOQ1RJT05TOlxuICAgIGNhc2UgTmV4dGpzVHlwZS5HTE9CQUxfQ09OVEFJTkVSUzpcbiAgICAgIC8vIGBOZXh0anNEaXN0cmlidXRpb25gIGJ1aWxkcyBpdHMgYmVoYXZpb3JzIGFzIGAvJHtiYXNlUGF0aH0vX25leHQvc3RhdGljKmBcbiAgICAgIC8vIGFuZCBDbG91ZEZyb250IGhhbmRzIGFuIFMzIG9yaWdpbiB0aGUgcmVxdWVzdCBwYXRoIHZlcmJhdGltIGFzIHRoZVxuICAgICAgLy8gb2JqZWN0IGtleSwgc28gdGhlIG9ubHkgdmFsdWUgdGhhdCBjYW4gc2VydmUgdGhlIGFwcCBpcyB0aGUgcHJlZml4IHRoZVxuICAgICAgLy8gYXBwIGl0c2VsZiBlbWl0cy4gVGhhdCBsZWF2ZXMgdGhlIHByb3Agbm8gcm9vbSB0byBkaWZmZXIsIHdoaWNoIG1ha2VzXG4gICAgICAvLyB0aGUgYXBwJ3MgY29uZmlnIHRoZSBzaW5nbGUgc291cmNlIG9mIHRydXRoIHdvcnRoIGRlcml2aW5nIGZyb20uXG4gICAgICBpZiAoIXByb3ApIHtcbiAgICAgICAgcmV0dXJuIGNvbmZpZztcbiAgICAgIH1cbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgbWlzbWF0Y2ggK1xuICAgICAgICAgIFwiQ2xvdWRGcm9udCBzZXJ2ZXMgc3RhdGljIGFzc2V0cyBzdHJhaWdodCBmcm9tIFMzIHVzaW5nIHRoZSByZXF1ZXN0IHBhdGggYXMgdGhlIG9iamVjdCBrZXksIHNvIGEgbWlzbWF0Y2ggbWVhbnMgZXZlcnkgYF9uZXh0L3N0YXRpY2AgYW5kIGBwdWJsaWMvYCByZXF1ZXN0IDQwNHMuIFwiICtcbiAgICAgICAgICBcIkVpdGhlciBzZXQgYm90aCB0byB0aGUgc2FtZSB2YWx1ZSwgb3IgZHJvcCB0aGUgcHJvcCDigJQgbGVmdCB1bnNldCwgaXQgZm9sbG93cyB5b3VyIGFwcCdzIGBiYXNlUGF0aGAuXCIsXG4gICAgICApO1xuICAgIGNhc2UgTmV4dGpzVHlwZS5SRUdJT05BTF9GVU5DVElPTlM6XG4gICAgICAvLyBEZWxpYmVyYXRlbHkgbm90IGRlcml2ZWQ6IEFQSSBHYXRld2F5IG1vdW50cyByZXNvdXJjZXMgYmVsb3cgdGhlIHN0YWdlXG4gICAgICAvLyBhbmQgc3RyaXBzIGl0IGJlZm9yZSBpbnZva2luZyB0aGUgYXBwLCBzbyBhbiBhcHAgd2hvc2UgYmFzZVBhdGggaXMgdGhlXG4gICAgICAvLyBzdGFnZSBuYW1lIChvciBhIGN1c3RvbSBkb21haW4gYmFzZSBwYXRoIG1hcHBpbmcgdGhhdCBnZXRzIHN0cmlwcGVkIHRoZVxuICAgICAgLy8gc2FtZSB3YXkpIGlzIGNvcnJlY3QgcHJlY2lzZWx5IGJlY2F1c2UgdGhlIHByb3Agc3RheXMgdW5zZXQuXG4gICAgICBpZiAoIXByb3ApIHtcbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgIH1cbiAgICAgIC8vIFRoZSBwcm9wIG9ubHkgaGFzIHRvIGJlIHRoZSB0YWlsIG9mIHdoYXQgdGhlIGFwcCBlbWl0cywgbm90IGFsbCBvZiBpdCxcbiAgICAgIC8vIGJlY2F1c2UgdGhlIHN0cmlwcGVkIHByZWZpeCBpcyBwYXJ0IG9mIHRoZSBhcHAncyBgYmFzZVBhdGhgIGJ1dCBuZXZlclxuICAgICAgLy8gcGFydCBvZiB0aGUgcmVzb3VyY2UgcGF0aDogYW4gYXBwIGF0IHRoZSBgcHJvZGAgc3RhZ2UgbmVzdGVkIHVuZGVyXG4gICAgICAvLyBcIi9iYXNlXCIgc2V0cyBgYmFzZVBhdGg6IFwiL3Byb2QvYmFzZVwiYCBhbmQgdGhlIHByb3AgdG8gXCIvYmFzZVwiLiBDaGVja2VkXG4gICAgICAvLyBvbiBhIHBhdGggYm91bmRhcnkgc28gXCIvcHJvZC9iYXNlXCIgZG9lc24ndCBhY2NlcHQgYSBwcm9wIG9mIFwic2VcIi5cbiAgICAgIGlmIChjb25maWcuZW5kc1dpdGgoYC8ke3Byb3B9YCkpIHtcbiAgICAgICAgcmV0dXJuIHByb3A7XG4gICAgICB9XG4gICAgICAvLyBBbnl0aGluZyBlbHNlIG5ldmVyIHdvcmtzOiB0aGUgcHJvcCBtb3ZlcyBldmVyeSByZXNvdXJjZSwgaW5jbHVkaW5nIHRoZVxuICAgICAgLy8gYEFOWWAgY2F0Y2gtYWxsLCB1bmRlciBhIHBhdGggdGhlIGFwcCBuZXZlciBsaW5rcyB0by5cbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgbWlzbWF0Y2ggK1xuICAgICAgICAgIFwiVGhlIGBiYXNlUGF0aGAgcHJvcCBuZXN0cyBldmVyeSBBUEkgR2F0ZXdheSByZXNvdXJjZSB1bmRlciB0aGF0IHBhdGgsIGluY2x1ZGluZyB0aGUgY2F0Y2gtYWxsLCBzbyB0aGUgYXBwIGhhcyB0byBlbWl0IGl0cyBsaW5rcyB1bmRlciB0aGUgc2FtZSBwcmVmaXggb3IgZXZlcnkgcmVxdWVzdCA0MDRzLiBcIiArXG4gICAgICAgICAgJ0VpdGhlciBzZXQgeW91ciBhcHBcXCdzIGBiYXNlUGF0aGAgdG8gZW5kIHdpdGggdGhlIHByb3AgKG9wdGlvbmFsbHkgcHJlZml4ZWQgYnkgdGhlIHN0YWdlIG9yIGJhc2UgcGF0aCBtYXBwaW5nIEFQSSBHYXRld2F5IHN0cmlwcywgZS5nLiBgYmFzZVBhdGg6IFwiL3Byb2QvYmFzZVwiYCB3aXRoIGEgcHJvcCBvZiBcIi9iYXNlXCIpLCBvciBsZWF2ZSB0aGUgcHJvcCB1bnNldCDigJQgdW5zZXQgaXMgd2hhdCB5b3Ugd2FudCB3aGVuIHRoZSBhcHBcXCdzIGBiYXNlUGF0aGAgaXMgdGhlIEFQSSBHYXRld2F5IHN0YWdlIG5hbWUsIHNpbmNlIHRoZSBzdGFnZSBpc25cXCd0IHBhcnQgb2YgdGhlIHJlc291cmNlIHBhdGguJyxcbiAgICAgICk7XG4gICAgY2FzZSBOZXh0anNUeXBlLlJFR0lPTkFMX0NPTlRBSU5FUlM6XG4gICAgICAvLyBUaGUgQUxCIGZvcndhcmRzIGV2ZXJ5IHBhdGggdG8gdGhlIGNvbnRhaW5lciwgd2hpY2ggc2VydmVzIGl0cyBvd25cbiAgICAgIC8vIHN0YXRpYyBhc3NldHMsIHNvIGhlcmUgYGJhc2VQYXRoYCBvbmx5IG5hbWVzcGFjZXMgdGhlIFMzIGJ1Y2tldCBhbmQgaGFzXG4gICAgICAvLyBubyByb3V0aW5nIG1lYW5pbmcgdGhhdCBjb3VsZCBkaXNhZ3JlZSB3aXRoIHRoZSBhcHAuXG4gICAgICByZXR1cm4gcHJvcCB8fCB1bmRlZmluZWQ7XG4gIH1cbn1cbiJdfQ==
|
|
360
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmFzZS1wYXRoLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3V0aWxzL2Jhc2UtcGF0aC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFZQSw4Q0FFQztBQU9ELHNDQUVDO0FBT0Qsd0NBR0M7QUFjRCw4REFHQztBQU9ELDRCQUVDO0FBb0JELGdEQU9DO0FBc0JELGtEQUVDO0FBMEJELHNEQWdCQztBQWlCRCwwQ0FhQztBQXVIRCwwQ0FtSEM7QUFoYUQ7Ozs7R0FJRztBQUNILDRDQUFzRDtBQUV0RDs7OztHQUlHO0FBQ0gsU0FBZ0IsaUJBQWlCLENBQUMsUUFBaUI7SUFDakQsT0FBTyxDQUFDLFFBQVEsSUFBSSxFQUFFLENBQUMsQ0FBQyxPQUFPLENBQUMsTUFBTSxFQUFFLEVBQUUsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxNQUFNLEVBQUUsRUFBRSxDQUFDLENBQUM7QUFDbEUsQ0FBQztBQUVEOzs7O0dBSUc7QUFDSCxTQUFnQixhQUFhLENBQUMsSUFBWSxFQUFFLE1BQWM7SUFDeEQsT0FBTyxDQUFDLENBQUMsTUFBTSxJQUFJLENBQUMsSUFBSSxLQUFLLE1BQU0sSUFBSSxJQUFJLENBQUMsVUFBVSxDQUFDLEdBQUcsTUFBTSxHQUFHLENBQUMsQ0FBQyxDQUFDO0FBQ3hFLENBQUM7QUFFRDs7OztHQUlHO0FBQ0gsU0FBZ0IsY0FBYyxDQUFDLFFBQWlCO0lBQzlDLE1BQU0sSUFBSSxHQUFHLGlCQUFpQixDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBQ3pDLE9BQU8sSUFBSSxDQUFDLENBQUMsQ0FBQyxJQUFJLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7QUFDaEMsQ0FBQztBQUVEOzs7Ozs7Ozs7OztHQVdHO0FBQ0gsU0FBZ0IseUJBQXlCLENBQUMsUUFBaUI7SUFDekQsTUFBTSxNQUFNLEdBQUcsY0FBYyxDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBQ3hDLE9BQU8sTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0s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RUFBMEU7WUFDMUUsd0RBQXdEO1lBQ3hELE1BQU0sSUFBSSxLQUFLLENBQ2IsUUFBUTtnQkFDTiwrS0FBK0s7Z0JBQy9LLGtWQUFrVixDQUNyVixDQUFDO1FBQ0osS0FBSyxzQkFBVSxDQUFDLG1CQUFtQjtZQUNqQyxxRUFBcUU7WUFDckUsMEVBQTBFO1lBQzFFLHVEQUF1RDtZQUN2RCxPQUFPLElBQUksSUFBSSxTQUFTLENBQUM7SUFDN0IsQ0FBQztBQUNILENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIFB1cmUgYGJhc2VQYXRoYCBhbmQgVVJMIHBhdGggaGVscGVycy4gTm90aGluZyBoZXJlIGltcG9ydHMgYGF3cy1jZGstbGliYCBvclxuICogdG91Y2hlcyB0aGUgZmlsZXN5c3RlbSwgc28gdGhlIGFkYXB0ZXIgYW5kIHJ1bnRpbWUgYnVuZGxlcyBjYW4gaW1wb3J0IGl0IGFzXG4gKiB3ZWxsIGFzIHRoZSBjb25zdHJ1Y3RzLlxuICovXG5pbXBvcnQgeyBMT0dfUFJFRklYLCBOZXh0anNUeXBlIH0gZnJvbSBcIi4uL2NvbnN0YW50c1wiO1xuXG4vKipcbiAqIFJlZHVjZXMgYSBgYmFzZVBhdGhgIHRvIGEgYmFyZSBwYXRoIHNlZ21lbnQgc28gdmFsdWVzIHRoYXQgYWRkcmVzcyB0aGUgc2FtZVxuICogcGF0aCAoXCIvYmFzZVwiLCBcImJhc2VcIiwgXCIvYmFzZS9cIikgY29tcGFyZSBlcXVhbCBhbmQgY2FuIGJlIGNvbmNhdGVuYXRlZFxuICogd2l0aG91dCBkb3VibGluZyBzZXBhcmF0b3JzLlxuICovXG5leHBvcnQgZnVuY3Rpb24gbm9ybWFsaXplQmFzZVBhdGgoYmFzZVBhdGg/OiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gKGJhc2VQYXRoIHx8IFwiXCIpLnJlcGxhY2UoL15cXC8rLywgXCJcIikucmVwbGFjZSgvXFwvKyQvLCBcIlwiKTtcbn1cblxuLyoqXG4gKiBXaGV0aGVyIGBwYXRoYCBpcyBgcHJlZml4YCBvciB1bmRlciBpdCBvbiBhIHNlZ21lbnQgYm91bmRhcnksIHNvIGAvZG9jc2VhcmNoYFxuICogaXMgbm90IHVuZGVyIGAvZG9jc2AuIEFuIGVtcHR5IGBwcmVmaXhgIG1hdGNoZXMgbm90aGluZy4gQm90aCBzaWRlcyBtdXN0IGJlIGluXG4gKiB0aGUgc2FtZSBmb3JtIChib3RoIHdpdGggb3IgYm90aCB3aXRob3V0IHRoZSBsZWFkaW5nIGAvYCkuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBoYXNQYXRoUHJlZml4KHBhdGg6IHN0cmluZywgcHJlZml4OiBzdHJpbmcpOiBib29sZWFuIHtcbiAgcmV0dXJuICEhcHJlZml4ICYmIChwYXRoID09PSBwcmVmaXggfHwgcGF0aC5zdGFydHNXaXRoKGAke3ByZWZpeH0vYCkpO1xufVxuXG4vKipcbiAqIEEgYGJhc2VQYXRoYCBhcyBOZXh0LmpzIHNwZWxscyBpdCBhbmQgVVJMcyBzdGFydCB3aXRoIGl0OiBvbmUgbGVhZGluZyBzbGFzaCxcbiAqIG5vIHRyYWlsaW5nIG9uZSAoXCIvYmFzZVwiKSwgYFwiXCJgIGZvciBub25lLiBBY2NlcHRzIGFueSBzcGVsbGluZ1xuICoge0BsaW5rIG5vcm1hbGl6ZUJhc2VQYXRofSBkb2VzLlxuICovXG5leHBvcnQgZnVuY3Rpb24gYmFzZVBhdGhQcmVmaXgoYmFzZVBhdGg/OiBzdHJpbmcpOiBzdHJpbmcge1xuICBjb25zdCBiYXJlID0gbm9ybWFsaXplQmFzZVBhdGgoYmFzZVBhdGgpO1xuICByZXR1cm4gYmFyZSA/IGAvJHtiYXJlfWAgOiBcIlwiO1xufVxuXG4vKipcbiAqIEludmFsaWRhdGlvbiBwYXRocyBjb3ZlcmluZyBldmVyeSBVUkkgb2YgdGhlIGFwcDogd2hhdCBhIGRlcGxveSBpbnZhbGlkYXRlcyxcbiAqIGFuZCB3aGF0IHRoZSBjYWNoZSBoYW5kbGVyJ3Mgb3ZlcnNpemVkIGJhdGNoZXMsIHJldHJpZXMgYWZ0ZXIgYSBxdW90YSBlcnJvcixcbiAqIGFuZCB0YWdzIHdob3NlIHJvdXRlcyBjb3VsZCBub3QgYWxsIGJlIG5hbWVkIGZhbGwgYmFjayB0by5cbiAqXG4gKiBgLypgIGlzIHRoZSB3aG9sZSBhcHAgb25seSB3aXRob3V0IGEgYGJhc2VQYXRoYC4gYC9iYXNlLypgIG1hdGNoZXMgbmVpdGhlciB0aGVcbiAqIGFwcCdzIHJvb3QsIGAvYmFzZWAsIG5vciBpdHMgUlNDIHBheWxvYWQsIGAvYmFzZT9fcnNjPeKApmAgLSB0aGUgc2FtZSByb290IHRoZVxuICogYHJldmFsaWRhdGVQYXRoKFwiL1wiKWAgdGhhdCBvdmVyZmxvd2VkIG1heSBoYXZlIG5hbWVkIC0gc28gdGhvc2UgYXJlIHNwZWxsZWRcbiAqIG91dC4gYC9iYXNlKmAgd291bGQgY292ZXIgdGhlbSBmb3Igb25lIHdpbGRjYXJkLCBidXQgYWxzbyBldmVyeSBzaWJsaW5nXG4gKiBwcmVmaXggKGAvYmFzZTJgLCBgL2Jhc2VtZW50YCksIHdoaWNoIG1heSBiZSBhbm90aGVyIGFwcCBvbiB0aGUgc2FtZVxuICogZGlzdHJpYnV0aW9uLlxuICovXG5leHBvcnQgZnVuY3Rpb24gd2hvbGVBcHBJbnZhbGlkYXRpb25QYXRocyhiYXNlUGF0aD86IHN0cmluZyk6IHN0cmluZ1tdIHtcbiAgY29uc3QgcHJlZml4ID0gYmFzZVBhdGhQcmVmaXgoYmFzZVBhdGgpO1xuICByZXR1cm4gcHJlZml4ID8gW3ByZWZpeCwgYCR7cHJlZml4fT8qYCwgYCR7cHJlZml4fS8qYF0gOiBbXCIvKlwiXTtcbn1cblxuLyoqXG4gKiBKb2lucyBwYXRoIHBhcnRzIHdpdGggYSBzaW5nbGUgXCIvXCIsIG5vcm1hbGl6aW5nIGVhY2ggKHNvIG5vIGxlYWRpbmcgb3JcbiAqIHRyYWlsaW5nIHNsYXNoIHN1cnZpdmVzLCBpbmNsdWRpbmcgb24gdGhlIHJlc3VsdCkgYW5kIGRyb3BwaW5nIHRoZSBlbXB0eVxuICogb25lcywgc28gYW4gdW5zZXQgYGJhc2VQYXRoYCBvciBrZXkgcHJlZml4IGxlYXZlcyB0aGUgcmVzdCB1bnRvdWNoZWQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBqb2luUGF0aCguLi5wYXJ0czogKHN0cmluZyB8IHVuZGVmaW5lZClbXSk6IHN0cmluZyB7XG4gIHJldHVybiBwYXJ0cy5tYXAobm9ybWFsaXplQmFzZVBhdGgpLmZpbHRlcihCb29sZWFuKS5qb2luKFwiL1wiKTtcbn1cblxuLyoqXG4gKiBQcmVmaXhlcyBhbiBhYnNvbHV0ZSBhcHAgcGF0aCAoYSBoZWFsdGggY2hlY2sgcGF0aCwgc2F5KSB3aXRoIGBiYXNlUGF0aGAsXG4gKiBhbHdheXMgcmV0dXJuaW5nIGEgbGVhZGluZyBzbGFzaC4gQW4gZW1wdHkgb3IgdW5zZXQgYGJhc2VQYXRoYCBvbmx5XG4gKiBub3JtYWxpemVzIHRoYXQgbGVhZGluZyBzbGFzaC4gQW55dGhpbmcgYWZ0ZXIgdGhlIGZpcnN0IHNlZ21lbnQgaXMgcGFzc2VkXG4gKiB0aHJvdWdoIGFzIGdpdmVuLCB0cmFpbGluZyBzbGFzaCBpbmNsdWRlZCwgc2luY2UgYSBgdHJhaWxpbmdTbGFzaGAgYXBwXG4gKiBhbnN3ZXJzIFwiL2FwaS9oZWFsdGhcIiBhbmQgXCIvYXBpL2hlYWx0aC9cIiBkaWZmZXJlbnRseS5cbiAqXG4gKiBVc2UgdGhpcyBmb3IgcGF0aHMgaGFuZGVkIHRvIHNvbWV0aGluZyB0aGF0IHRhbGtzIHRvIHRoZSBhcHAgZGlyZWN0bHkg4oCUIGFuIEFMQlxuICogdGFyZ2V0IGdyb3VwIGhlYWx0aCBjaGVjaywgdGhlIGNvbnRhaW5lcidzIG93biBoZWFsdGggcHJvYmUg4oCUIHNpbmNlIHRoZSBhcHBcbiAqIG9ubHkgYW5zd2VycyB1bmRlciBpdHMgb3duIGBiYXNlUGF0aGAuXG4gKlxuICogUHJlZml4ZXMgdW5jb25kaXRpb25hbGx5LCBzbyBgcGF0aGAgaGFzIHRvIGFycml2ZSBhcyB0aGUgYXBwIHJvdXRlcyBpdCxcbiAqIHdpdGhvdXQgYGJhc2VQYXRoYDogZm9yIGFuIGFwcCBiYXNlZCBhdCBcIi9iYXNlXCIsIFwiL2Jhc2UvYXBpL2hlYWx0aFwiIGJlY29tZXNcbiAqIFwiL2Jhc2UvYmFzZS9hcGkvaGVhbHRoXCIuIERlbGliZXJhdGVseSBub3Qgc3BlY2lhbC1jYXNlZCDigJQgYW4gYXBwIGNhbiByb3V0ZVxuICogXCIvYmFzZS9iYXNlLy4uLlwiIGxlZ2l0aW1hdGVseSwgYW5kIGFjY2VwdGluZyBib3RoIHNwZWxsaW5ncyB3b3VsZCBnaXZlIHRoZVxuICogcGF0aCB0d28gbWVhbmluZ3MuIFNlZSBgZG9jcy9icmVha2luZy1jaGFuZ2VzLm1kYCAoMC42LjApLCB3aGljaCB0ZWxscyB1c2Vyc1xuICogd2hvIHByZWZpeGVkIGBoZWFsdGhDaGVja1BhdGhgIGJ5IGhhbmQgdG8gZHJvcCB0aGUgcHJlZml4LlxuICovXG5leHBvcnQgZnVuY3Rpb24gcHJlZml4V2l0aEJhc2VQYXRoKFxuICBiYXNlUGF0aDogc3RyaW5nIHwgdW5kZWZpbmVkLFxuICBwYXRoOiBzdHJpbmcsXG4pOiBzdHJpbmcge1xuICBjb25zdCBub3JtYWxpemVkID0gbm9ybWFsaXplQmFzZVBhdGgoYmFzZVBhdGgpO1xuICBjb25zdCBhYnNvbHV0ZSA9IHBhdGguc3RhcnRzV2l0aChcIi9cIikgPyBwYXRoIDogYC8ke3BhdGh9YDtcbiAgcmV0dXJuIG5vcm1hbGl6ZWQgPyBgLyR7bm9ybWFsaXplZH0ke2Fic29sdXRlfWAgOiBhYnNvbHV0ZTtcbn1cblxuLyoqIFdoZXRoZXIgYW4gYGFzc2V0UHJlZml4YCBuYW1lcyBhbiBvcmlnaW4gcmF0aGVyIHRoYW4gYSBwYXRoIG9uIHRoaXMgb25lLiAqL1xuZnVuY3Rpb24gaXNBYnNvbHV0ZUFzc2V0UHJlZml4KGFzc2V0UHJlZml4OiBzdHJpbmcpOiBib29sZWFuIHtcbiAgcmV0dXJuIC9eKFthLXpdW2EtejAtOSsuLV0qOik/XFwvXFwvL2kudGVzdChhc3NldFByZWZpeCk7XG59XG5cbi8qKlxuICogVGhlIGFwcCdzIG93biBgYXNzZXRQcmVmaXhgIGFzIGEgcGF0aCB3aXRoIGEgbGVhZGluZyBhbmQgbm8gdHJhaWxpbmcgc2xhc2hcbiAqIChcIi9jZG5cIiksIG9yIGBcIlwiYCB3aGVuIHRoZSBhcHAgc2V0cyBub25lLlxuICpcbiAqIFJldHVybnMgYFwiXCJgIGZvciBhbiBhYnNvbHV0ZSBgYXNzZXRQcmVmaXhgIChcImh0dHBzOi8vY2RuLmV4YW1wbGUuY29tXCIsIG9yIHRoZVxuICogcHJvdG9jb2wtcmVsYXRpdmUgXCIvL2Nkbi5leGFtcGxlLmNvbVwiKSB0b286IHRoYXQgbmFtZXMgYW4gb3JpZ2luIGNkay1uZXh0anNcbiAqIGRvZXMgbm90IGNvbnRyb2wsIGFuZCBpdCBpcyB0aGUgc3VwcG9ydGVkIHdheSB0byBzZXJ2ZSBhc3NldHMgZnJvbSBlbHNld2hlcmUsXG4gKiBzbyBub3RoaW5nIGFib3V0IGl0IGlzIHdvcnRoIHdhcm5pbmcgYWJvdXQuIFVzZSB7QGxpbmsgYXNzZXRQcmVmaXhQYXRofSBmb3JcbiAqIHdoYXQgdGhlICpkaXN0cmlidXRpb24qIGhhcyB0byBhbnN3ZXIgb24sIHdoaWNoIGluY2x1ZGVzIHRoZSBwYXRoIGFuIGFic29sdXRlXG4gKiBwcmVmaXggY2Fycmllcy5cbiAqXG4gKiBOZXh0LmpzIGFwcGxpZXMgYGFzc2V0UHJlZml4YCBvbiB0b3Agb2YsIG5vdCB1bmRlciwgYGJhc2VQYXRoYCwgc28gdGhlIHJlc3VsdFxuICogaXMgdGhlIHdob2xlIHByZWZpeCBvZiBhIGBfbmV4dC9zdGF0aWNgIFVSTCBhbmQgbXVzdCBub3QgYmUgam9pbmVkIHdpdGhcbiAqIGBiYXNlUGF0aGAuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZWxhdGl2ZUFzc2V0UHJlZml4KGFzc2V0UHJlZml4OiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gaXNBYnNvbHV0ZUFzc2V0UHJlZml4KGFzc2V0UHJlZml4KSA/IFwiXCIgOiBiYXNlUGF0aFByZWZpeChhc3NldFByZWZpeCk7XG59XG5cbi8qKlxuICogV2hldGhlciBhIHBhdGgtc3R5bGUgYGFzc2V0UHJlZml4YCB3b3VsZCBnbyB1bmFuc3dlcmVkIG9uIHRoaXMgYE5leHRqc1R5cGVgLFxuICogaS5lLiB3aGV0aGVyIGV2ZXJ5IGJ1bmRsZSB3b3VsZCA0MDQuXG4gKlxuICogYGFzc2V0UHJlZml4YCBtb3ZlcyBldmVyeSBidW5kbGUgVVJMIHRvIGA8YXNzZXRQcmVmaXg+L19uZXh0L3N0YXRpYy8uLi5gIHdoaWxlXG4gKiB0aGUgb2JqZWN0cyBrZWVwIHRoZWlyIGA8YmFzZVBhdGg+L19uZXh0L3N0YXRpYy8uLi5gIFMzIGtleXMuIFRoZSBHbG9iYWxcbiAqIGBOZXh0anNUeXBlYHMgYW5zd2VyIHRoYXQgd2l0aCBhIGNhY2hlIGJlaGF2aW9yIG9mIHRoZWlyIG93blxuICogKGBOZXh0anNEaXN0cmlidXRpb25gKTsgdGhlIHJlZ2lvbmFsIG9uZXMgaGF2ZSBub3RoaW5nIHRoYXQgbWFwcyB0aGUgcHJlZml4XG4gKiBiYWNrIOKAlCBBUEkgR2F0ZXdheSdzIGBfbmV4dC9zdGF0aWNgIHJlc291cmNlIGFuZCB0aGUgY29udGFpbmVyJ3Mgb3duIGZpbGVzIGFyZVxuICogYm90aCB1bmRlciB0aGUgdW5wcmVmaXhlZCBwYXRoLlxuICpcbiAqIEEgcHJlZml4IGVxdWFsIHRvIHRoZSBhcHAncyBvd24gYGJhc2VQYXRoYCBpcyAqKm5vdCoqIHVuc2VydmVkLCBiZWNhdXNlIHRoYXQgaXNcbiAqIHRoZSB2YWx1ZSBOZXh0LmpzIHJlc29sdmVzIGBhc3NldFByZWZpeGAgdG8gd2hlbiBgYmFzZVBhdGhgIGlzIHNldCBhbmRcbiAqIGBhc3NldFByZWZpeGAgaXMgbm90OiBgLm5leHQvcmVxdWlyZWQtc2VydmVyLWZpbGVzLmpzb25gIGNvbWVzIGJhY2sgYXNcbiAqIGB7XCJhc3NldFByZWZpeFwiOlwiL3Byb2RcIixcImJhc2VQYXRoXCI6XCIvcHJvZFwifWAgZm9yIGFuIGFwcCB0aGF0IG9ubHkgZXZlciBzZXRcbiAqIGBiYXNlUGF0aGAuIFdpdGhvdXQgdGhhdCBleGVtcHRpb24gdGhlIHdhcm5pbmcgZmlyZWQgb24gZXZlcnkgcmVnaW9uYWxcbiAqIGRlcGxveW1lbnQgdGhhdCBzZXRzIGEgYGJhc2VQYXRoYCBhdCBhbGwg4oCUIGluY2x1ZGluZyBgZXhhbXBsZXMvcmVnaW9uYWwtZnVuY3Rpb25zYFxuICog4oCUIHRlbGxpbmcgdXNlcnMgdGhlaXIgYnVuZGxlcyB3b3VsZCA0MDQgYXQgdGhlIG9uZSBwYXRoIHRoYXQgZG9lcyBzZXJ2ZSB0aGVtLlxuICogYE5leHRqc0Rpc3RyaWJ1dGlvbi5yZXNvbHZlQXNzZXRQcmVmaXhgIGRyb3BzIHRoZSBwcmVmaXggZm9yIHRoZSBzYW1lIHJlYXNvbi5cbiAqXG4gKiBCb3RoIHNpZGVzIGdvIHRocm91Z2ggYG5vcm1hbGl6ZUJhc2VQYXRoYCBiZWNhdXNlIHRoZXkgYXJyaXZlIGluIGRpZmZlcmVudFxuICogc2hhcGVzOiBgbmV4dENvbmZpZ0Fzc2V0UHJlZml4YCBjYXJyaWVzIGEgbGVhZGluZyBzbGFzaCAoYFwiL3Byb2RcImApLFxuICogYG5leHRDb25maWdCYXNlUGF0aGAgZG9lcyBub3QgKGBcInByb2RcImApLlxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNBc3NldFByZWZpeFVuc2VydmVkKFxuICBuZXh0anNUeXBlOiBOZXh0anNUeXBlLFxuICBuZXh0Q29uZmlnQXNzZXRQcmVmaXg6IHN0cmluZyxcbiAgbmV4dENvbmZpZ0Jhc2VQYXRoPzogc3RyaW5nLFxuKTogYm9vbGVhbiB7XG4gIGlmICghbmV4dENvbmZpZ0Fzc2V0UHJlZml4KSByZXR1cm4gZmFsc2U7XG4gIGlmIChcbiAgICBuZXh0anNUeXBlID09PSBOZXh0anNUeXBlLkdMT0JBTF9GVU5DVElPTlMgfHxcbiAgICBuZXh0anNUeXBlID09PSBOZXh0anNUeXBlLkdMT0JBTF9DT05UQUlORVJTXG4gICkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICByZXR1cm4gKFxuICAgIG5vcm1hbGl6ZUJhc2VQYXRoKG5leHRDb25maWdBc3NldFByZWZpeCkgIT09XG4gICAgbm9ybWFsaXplQmFzZVBhdGgobmV4dENvbmZpZ0Jhc2VQYXRoKVxuICApO1xufVxuXG4vKipcbiAqIFRoZSAqcGF0aCogZXZlcnkgYnVuZGxlIFVSTCBjYXJyaWVzLCB3aGljaGV2ZXIgZm9ybSBgYXNzZXRQcmVmaXhgIHRha2VzOiBcIi9jZG5cIlxuICogZm9yIGBhc3NldFByZWZpeDogXCIvY2RuXCJgIGFuZCBmb3IgYGFzc2V0UHJlZml4OlxuICogXCJodHRwczovL2Nkbi5leGFtcGxlLmNvbS9jZG5cImAgYWxpa2UsIGBcIlwiYCB3aGVuIHRoZXJlIGlzIG5vbmUgKGFuIGFic29sdXRlXG4gKiBwcmVmaXggd2l0aCBubyBwYXRoLCBvciBubyBwcmVmaXggYXQgYWxsKS5cbiAqXG4gKiBBbiBhYnNvbHV0ZSBwcmVmaXgncyBwYXRoIGNvdW50cyBiZWNhdXNlIGBuZXh0IGJ1aWxkYCBjb21waWxlcyBhIGBiZWZvcmVGaWxlc2BcbiAqIHJld3JpdGUgb2YgaXRzIG93biBmb3IgaXQg4oCUIGAvY2RuL19uZXh0LzpwYXRoKyDihpIgL19uZXh0LzpwYXRoK2Ag4oCUIHNvIGBuZXh0XG4gKiBzdGFydGAgc2VydmVzIGV2ZXJ5IGJ1bmRsZSB1bmRlciB0aGF0IHBhdGggYXMgd2VsbCBhcyB1bmRlciBgL19uZXh0YC4gQSBDRE5cbiAqIGZyb250aW5nIHRoaXMgZGVwbG95bWVudCBhdCB0aGF0IHBhdGggdGhlcmVmb3JlIGhhcyB0byBiZSBhbnN3ZXJlZCwgYW5kIHRoZVxuICogZGlzdHJpYnV0aW9uJ3MgYGFzc2V0UHJlZml4YCBiZWhhdmlvciBpcyB3aGF0IGFuc3dlcnMgaXQuIE1lYXN1cmVkIGFnYWluc3RcbiAqIGB0ZXN0L2UyZS9hcHAtZGlyL2Fzc2V0LXByZWZpeC1hYnNvbHV0ZWA7IHNlZSBgZG9jcy9oYXJuZXNzLWNvdmVyYWdlLm1kYC5cbiAqIFNoYXJlZCB3aXRoIGBOZXh0anNEaXN0cmlidXRpb25gLCB3aG9zZSBgYXNzZXRQcmVmaXhgIHByb3AgYSB1c2VyIGNhbiBhbHNvXG4gKiBzZXQgYnkgaGFuZC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFzc2V0UHJlZml4UGF0aChhc3NldFByZWZpeDogc3RyaW5nKTogc3RyaW5nIHtcbiAgaWYgKCFhc3NldFByZWZpeCkgcmV0dXJuIFwiXCI7XG4gIGxldCBwYXRoID0gYXNzZXRQcmVmaXg7XG4gIGlmIChpc0Fic29sdXRlQXNzZXRQcmVmaXgoYXNzZXRQcmVmaXgpKSB7XG4gICAgdHJ5IHtcbiAgICAgIC8vIGAvL2Nkbi5leGFtcGxlLmNvbS9jZG5gIGlzIHByb3RvY29sLXJlbGF0aXZlLCB3aGljaCBgVVJMYCBvbmx5IHBhcnNlc1xuICAgICAgLy8gd2l0aCBhIGJhc2Ug4oCUIGFueSBiYXNlLCBzaW5jZSBvbmx5IHRoZSBwYXRoIGlzIHJlYWQgb2ZmIGl0LlxuICAgICAgcGF0aCA9IG5ldyBVUkwoYXNzZXRQcmVmaXgsIFwiaHR0cHM6Ly9hc3NldC1wcmVmaXguaW52YWxpZFwiKS5wYXRobmFtZTtcbiAgICB9IGNhdGNoIHtcbiAgICAgIHJldHVybiBcIlwiO1xuICAgIH1cbiAgfVxuICByZXR1cm4gYmFzZVBhdGhQcmVmaXgocGF0aCk7XG59XG5cbi8qKlxuICogVGhlIHBhdGggcHJlZml4IEFQSSBHYXRld2F5IHN0cmlwcyBiZWZvcmUgbWF0Y2hpbmcgcmVzb3VyY2VzLCBhcyBmYXIgYXMgc3ludGhcbiAqIGNhbiB0ZWxsLiBPbmx5IHJlYWQgYnkgYHJlc29sdmVCYXNlUGF0aGAgZm9yIGBSRUdJT05BTF9GVU5DVElPTlNgLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEFwaUdhdGV3YXlQcmVmaXgge1xuICAvKipcbiAgICogVGhlIHN0YWdlIG5hbWUgb24gdGhlIGV4ZWN1dGUtYXBpIGVuZHBvaW50LCBvciB0aGUgYmFzZSBwYXRoIG1hcHBpbmcgb24gYVxuICAgKiBjdXN0b20gZG9tYWluIChgXCJcImAgd2hlbiBtYXBwZWQgYXQgdGhlIHJvb3QpLiBgdW5kZWZpbmVkYCB3aGVuIGl0IGlzIG5vdFxuICAgKiBrbm93biBhdCBzeW50aCDigJQgYSB0b2tlbiDigJQgaW4gd2hpY2ggY2FzZSBub3RoaW5nIGlzIGRlcml2ZWQuXG4gICAqL1xuICByZWFkb25seSBzdHJpcHBlZFByZWZpeD86IHN0cmluZztcbiAgLyoqIFdoZXRoZXIgYSBjdXN0b20gZG9tYWluIGlzIGNvbmZpZ3VyZWQgdGhyb3VnaCBgcmVzdEFwaVByb3BzLmRvbWFpbk5hbWVgLiAqL1xuICByZWFkb25seSBjdXN0b21Eb21haW46IGJvb2xlYW47XG59XG5cbi8qKiBgUmVzdEFwaWAncyBvd24gZGVmYXVsdHM6IHRoZSBgcHJvZGAgc3RhZ2UsIG5vIGN1c3RvbSBkb21haW4uICovXG5leHBvcnQgY29uc3QgREVGQVVMVF9BUElfR0FURVdBWV9QUkVGSVg6IEFwaUdhdGV3YXlQcmVmaXggPSB7XG4gIHN0cmlwcGVkUHJlZml4OiBcInByb2RcIixcbiAgY3VzdG9tRG9tYWluOiBmYWxzZSxcbn07XG5cbi8qKlxuICogVGhlIHJlc291cmNlIHBhdGggYW4gYXBwJ3MgYGJhc2VQYXRoYCBuZWVkcyBvbiBgUkVHSU9OQUxfRlVOQ1RJT05TYCB3aGVuIHRoZVxuICogYGJhc2VQYXRoYCBwcm9wIGlzIHVuc2V0OiB0aGUgYXBwJ3MgYGJhc2VQYXRoYCB3aXRoIHRoZSBwcmVmaXggQVBJIEdhdGV3YXlcbiAqIHN0cmlwcyB0YWtlbiBvZmYgdGhlIGZyb250LCBvciB0aGUgd2hvbGUgb2YgaXQgd2hlbiBpdCBkb2VzIG5vdCBzdGFydCB3aXRoXG4gKiB0aGF0IHByZWZpeC5cbiAqXG4gKiBBbiBhcHAgYXQgdGhlIGBwcm9kYCBzdGFnZSBlbWl0cyBgL3Byb2QvLi4uYCBhbmQgQVBJIEdhdGV3YXkgc3RyaXBzIGAvcHJvZGBcbiAqIGJlZm9yZSBtYXRjaGluZywgc28gYGJhc2VQYXRoOiBcIi9wcm9kXCJgIG5lZWRzIHJlc291cmNlcyBhdCB0aGUgcm9vdCBhbmRcbiAqIGBiYXNlUGF0aDogXCIvcHJvZC9iYXNlXCJgIG5lZWRzIHRoZW0gdW5kZXIgYGJhc2VgLiBBbiBhcHAgd2hvc2UgYGJhc2VQYXRoYCBBUElcbiAqIEdhdGV3YXkgZG9lcyBub3Qgc3RyaXAg4oCUIGEgY3VzdG9tIGRvbWFpbiBtYXBwZWQgYXQgdGhlIHJvb3QsIHNlcnZpbmdcbiAqIGBiYXNlUGF0aDogXCIvZG9jc1wiYCDigJQgbmVlZHMgdGhlbSB1bmRlciBgZG9jc2AuIExlYXZpbmcgdGhhdCBvbmUgYXQgdGhlIHJvb3QgaXNcbiAqIHdoYXQgdXNlZCB0byBoYXBwZW46IGBfbmV4dC9zdGF0aWNgIGFuZCBgcHVibGljL2AgZmVsbCB0aHJvdWdoIHRvIHRoZVxuICogYHtwcm94eSt9YCBjYXRjaC1hbGwsIGFuZCBldmVyeSBidW5kbGUgNDA0J2Qgd2l0aCBub3RoaW5nIHNhaWQgYXQgc3ludGguXG4gKi9cbmZ1bmN0aW9uIGRlcml2ZUFwaUdhdGV3YXlCYXNlUGF0aChcbiAgY29uZmlnOiBzdHJpbmcsXG4gIHsgc3RyaXBwZWRQcmVmaXgsIGN1c3RvbURvbWFpbiB9OiBBcGlHYXRld2F5UHJlZml4LFxuKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgaWYgKCFjb25maWcgfHwgc3RyaXBwZWRQcmVmaXggPT09IHVuZGVmaW5lZCkge1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cbiAgY29uc3Qgc3RyaXBwZWQgPSBub3JtYWxpemVCYXNlUGF0aChzdHJpcHBlZFByZWZpeCk7XG4gIGlmIChoYXNQYXRoUHJlZml4KGNvbmZpZywgc3RyaXBwZWQpKSB7XG4gICAgcmV0dXJuIGNvbmZpZy5zbGljZShzdHJpcHBlZC5sZW5ndGggKyAxKSB8fCB1bmRlZmluZWQ7XG4gIH1cbiAgd2FyblVuc3RyaXBwZWRCYXNlUGF0aChjb25maWcsIHsgc3RyaXBwZWRQcmVmaXgsIGN1c3RvbURvbWFpbiB9KTtcbiAgcmV0dXJuIGNvbmZpZztcbn1cblxuLyoqXG4gKiBXYXJuIHRoYXQgYW4gYXBwIG1vdW50ZWQgdW5kZXIgaXRzIHdob2xlIGBiYXNlUGF0aGAgaXMgc2VydmVkIHNvbWV3aGVyZSBpdHNcbiAqIG93biBsaW5rcyBkb24ndCByZWFjaCwgd2hlbiBBUEkgR2F0ZXdheSBzdHJpcHMgYSBwcmVmaXggdGhhdCBgYmFzZVBhdGhgIGxhY2tzLlxuICogQm90aCB3YXlzIG9mIGFycml2aW5nIHRoZXJlIHdhcm46IHRoZSBwcm9wIGxlZnQgdW5zZXQgKGRlcml2ZWQgdG8gdGhlIHdob2xlXG4gKiBgYmFzZVBhdGhgKSBhbmQgdGhlIHByb3Agc2V0IHRvIHRoZSBzYW1lIHZhbHVlLlxuICovXG5mdW5jdGlvbiB3YXJuVW5zdHJpcHBlZEJhc2VQYXRoKFxuICBjb25maWc6IHN0cmluZyxcbiAgeyBzdHJpcHBlZFByZWZpeCwgY3VzdG9tRG9tYWluIH06IEFwaUdhdGV3YXlQcmVmaXgsXG4pOiB2b2lkIHtcbiAgY29uc3Qgc3RyaXBwZWQgPSBub3JtYWxpemVCYXNlUGF0aChzdHJpcHBlZFByZWZpeCk7XG4gIGlmIChzdHJpcHBlZFByZWZpeCA9PT0gdW5kZWZpbmVkIHx8ICFzdHJpcHBlZCkge1xuICAgIC8vIEEgdG9rZW4sIG9yIGEgY3VzdG9tIGRvbWFpbiBtYXBwZWQgYXQgdGhlIHJvb3Q6IG5vdGhpbmcgaXMgc3RyaXBwZWQgdGhhdFxuICAgIC8vIHRoZSBhcHAncyBsaW5rcyBjb3VsZCBtaXNzLlxuICAgIHJldHVybjtcbiAgfVxuICBpZiAoY3VzdG9tRG9tYWluKSB7XG4gICAgLy8gVGhlIHNhbWUgbWlzcyB0aHJvdWdoIGEgY3VzdG9tIGRvbWFpbidzIGJhc2UgcGF0aCBtYXBwaW5nOiBzZXJ2ZWQgYXRcbiAgICAvLyBgLzxtYXBwaW5nPi88YmFzZVBhdGg+YCwgbGlua2luZyB0byBgLzxiYXNlUGF0aD4vLi4uYCwgd2hpY2ggbm8gbWFwcGluZ1xuICAgIC8vIGNvdmVycy5cbiAgICBjb25zb2xlLndhcm4oXG4gICAgICBgJHtMT0dfUFJFRklYfSB5b3VyIE5leHQuanMgYXBwJ3MgXFxgYmFzZVBhdGhcXGAgaXMgJHtxdW90ZShjb25maWcpfSwgd2hpY2ggZG9lcyBub3Qgc3RhcnQgd2l0aCB0aGUgY3VzdG9tIGRvbWFpbidzIGJhc2UgcGF0aCBtYXBwaW5nIFwiLyR7c3RyaXBwZWR9XCIuIGAgK1xuICAgICAgICBcIkl0cyBsaW5rcyBhbmQgYnVuZGxlIFVSTHMgd2lsbCBiZSByZXF1ZXN0ZWQgd2l0aG91dCB0aGUgbWFwcGluZywgd2hpY2ggdGhlIGN1c3RvbSBkb21haW4gYW5zd2VycyB3aXRoIDQwMy4gXCIgK1xuICAgICAgICBgU2V0IFxcYGJhc2VQYXRoOiBcIi8ke2pvaW5QYXRoKHN0cmlwcGVkLCBjb25maWcpfVwiXFxgIGluIHlvdXIgbmV4dC5jb25maWcsIG9yIG1hcCB0aGUgZG9tYWluIGF0IHRoZSByb290LmAsXG4gICAgKTtcbiAgfSBlbHNlIHtcbiAgICAvLyBSZXNvdXJjZXMgdW5kZXIgdGhlIGFwcCdzIGJhc2VQYXRoIHNlcnZlIGl0IGF0IGAvPHN0YWdlPi88YmFzZVBhdGg+YCwgYnV0XG4gICAgLy8gdGhlIGFwcCdzIG93biBsaW5rcyBhcmUgYC88YmFzZVBhdGg+Ly4uLmAsIHdoaWNoIG1pc3NlcyB0aGUgc3RhZ2UuIEFcbiAgICAvLyB3YXJuaW5nLCBub3QgYW4gZXJyb3I6IGEgZG9tYWluIGF0dGFjaGVkIGFmdGVyIHN5bnRoIChgYWRkRG9tYWluTmFtZWApXG4gICAgLy8gbWFrZXMgaXQgcmlnaHQsIGFuZCBzeW50aCBjYW5ub3Qgc2VlIHRoYXQuXG4gICAgY29uc29sZS53YXJuKFxuICAgICAgYCR7TE9HX1BSRUZJWH0geW91ciBOZXh0LmpzIGFwcCdzIFxcYGJhc2VQYXRoXFxgIGlzICR7cXVvdGUoY29uZmlnKX0sIHdoaWNoIGRvZXMgbm90IHN0YXJ0IHdpdGggdGhlIEFQSSBHYXRld2F5IHN0YWdlIFwiLyR7c3RyaXBwZWR9XCIuIGAgK1xuICAgICAgICBcIkl0cyBsaW5rcyBhbmQgYnVuZGxlIFVSTHMgd2lsbCBiZSByZXF1ZXN0ZWQgd2l0aG91dCB0aGUgc3RhZ2UsIHdoaWNoIHRoZSBleGVjdXRlLWFwaSBlbmRwb2ludCBhbnN3ZXJzIHdpdGggNDAzLiBcIiArXG4gICAgICAgIGBTZXQgXFxgYmFzZVBhdGg6IFwiLyR7am9pblBhdGgoc3RyaXBwZWQsIGNvbmZpZyl9XCJcXGAgaW4geW91ciBuZXh0LmNvbmZpZywgb3Igc2VydmUgdGhlIGFwcCBmcm9tIGEgY3VzdG9tIGRvbWFpbiBtYXBwZWQgYXQgdGhlIHJvb3QuYCxcbiAgICApO1xuICB9XG59XG5cbi8qKiBXaGV0aGVyIEFQSSBHYXRld2F5IHN0cmlwcyB0aGUgZnJvbnQgb2YgYGJhc2VQYXRoYCBiZWZvcmUgbWF0Y2hpbmcgcmVzb3VyY2VzLiAqL1xuZnVuY3Rpb24gc3RhcnRzV2l0aFN0cmlwcGVkUHJlZml4KFxuICBiYXNlUGF0aDogc3RyaW5nLFxuICB7IHN0cmlwcGVkUHJlZml4IH06IEFwaUdhdGV3YXlQcmVmaXgsXG4pOiBib29sZWFuIHtcbiAgY29uc3Qgc3RyaXBwZWQgPSBub3JtYWxpemVCYXNlUGF0aChzdHJpcHBlZFByZWZpeCk7XG4gIHJldHVybiAhIWJhc2VQYXRoICYmIGhhc1BhdGhQcmVmaXgoYmFzZVBhdGgsIHN0cmlwcGVkKTtcbn1cblxuZnVuY3Rpb24gcXVvdGUoYmFzZVBhdGg6IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiBiYXNlUGF0aCA/IGBcIi8ke2Jhc2VQYXRofVwiYCA6IFwidW5zZXRcIjtcbn1cblxuLyoqXG4gKiBTZXR0bGVzIG9uIHRoZSBzaW5nbGUgYGJhc2VQYXRoYCB0aGUgaW5mcmFzdHJ1Y3R1cmUgc2hvdWxkIGJlIGJ1aWx0IGFyb3VuZCxcbiAqIGdpdmVuIHRoZSBDREsgYGJhc2VQYXRoYCBwcm9wIGFuZCB0aGUgTmV4dC5qcyBhcHAncyBvd24gYGJhc2VQYXRoYFxuICogKGBOZXh0anNCdWlsZC5uZXh0Q29uZmlnQmFzZVBhdGhgKSwgdGhyb3dpbmcgYXQgc3ludGggaWYgdGhlIHR3byBjYW4ndCBzZXJ2ZVxuICogdGhlIGFwcCB0b2dldGhlci4gUmV0dXJucyBhIG5vcm1hbGl6ZWQgdmFsdWUsIG9yIGB1bmRlZmluZWRgIGZvciBub1xuICogYGJhc2VQYXRoYCBhdCBhbGw7IGNvbnN1bWVycyB0aGF0IG5lZWQgYSBsZWFkaW5nIHNsYXNoIGFkZCB0aGVpciBvd24uXG4gKlxuICogVGhlIHR3byBpbnB1dHMgYXJlIGdlbnVpbmVseSBkaWZmZXJlbnQgdGhpbmdzIOKAlCB0aGUgcHJvcCBpcyB3aGVyZSB0aGVcbiAqIGluZnJhc3RydWN0dXJlIHNlcnZlcyB0aGUgYXBwIGZyb20gKGFuZCB3aGljaCBTMyBrZXkgcHJlZml4IHRoZSBzdGF0aWMgYXNzZXRzXG4gKiBsYW5kIHVuZGVyKSwgdGhlIGNvbmZpZyBpcyB0aGUgcHJlZml4IHRoZSBhcHAgZW1pdHMgaXRzIG93biBsaW5rcyBhbmQgYXNzZXRcbiAqIGhyZWZzIHVuZGVyIOKAlCBzbyBob3cgc3RyaWN0bHkgdGhleSBoYXZlIHRvIGxpbmUgdXAsIGFuZCB3aGV0aGVyIG9uZSBjYW4gc3RhbmRcbiAqIGluIGZvciB0aGUgb3RoZXIsIGRlcGVuZHMgb24gaG93IHRoZSBgTmV4dGpzVHlwZWAgcm91dGVzIHN0YXRpYyByZXF1ZXN0cy5cbiAqXG4gKiBgYXBpR2F0ZXdheWAgaXMgb25seSByZWFkIGZvciBgUkVHSU9OQUxfRlVOQ1RJT05TYCwgYW5kIG9ubHkgd2hlbiB0aGUgcHJvcCBpc1xuICogdW5zZXQ6IHNlZSBgZGVyaXZlQXBpR2F0ZXdheUJhc2VQYXRoYC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlc29sdmVCYXNlUGF0aChcbiAgbmV4dGpzVHlwZTogTmV4dGpzVHlwZSxcbiAgcHJvcEJhc2VQYXRoPzogc3RyaW5nLFxuICBuZXh0Q29uZmlnQmFzZVBhdGg/OiBzdHJpbmcsXG4gIGFwaUdhdGV3YXk6IEFwaUdhdGV3YXlQcmVmaXggPSBERUZBVUxUX0FQSV9HQVRFV0FZX1BSRUZJWCxcbik6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gIGNvbnN0IHByb3AgPSBub3JtYWxpemVCYXNlUGF0aChwcm9wQmFzZVBhdGgpO1xuICBjb25zdCBjb25maWcgPSBub3JtYWxpemVCYXNlUGF0aChuZXh0Q29uZmlnQmFzZVBhdGgpO1xuICBjb25zdCBtaXNtYXRjaCA9XG4gICAgYCR7TE9HX1BSRUZJWH0gYmFzZVBhdGggbWlzbWF0Y2ggZm9yIE5leHRqc1R5cGUuJHtuZXh0anNUeXBlfTogdGhlIFxcYGJhc2VQYXRoXFxgIHByb3AgaXMgJHtxdW90ZShwcm9wKX0gYCArXG4gICAgYGJ1dCB5b3VyIE5leHQuanMgYXBwJ3MgY29uZmlnIHNldHMgXFxgYmFzZVBhdGhcXGAgdG8gJHtxdW90ZShjb25maWcpfS4gYDtcbiAgaWYgKHByb3AgPT09IGNvbmZpZykge1xuICAgIGlmIChcbiAgICAgIG5leHRqc1R5cGUgPT09IE5leHRqc1R5cGUuUkVHSU9OQUxfRlVOQ1RJT05TICYmXG4gICAgICBzdGFydHNXaXRoU3RyaXBwZWRQcmVmaXgocHJvcCwgYXBpR2F0ZXdheSlcbiAgICApIHtcbiAgICAgIC8vIEFncmVlaW5nIGlzIG5vdCBlbm91Z2ggaGVyZTogQVBJIEdhdGV3YXkgc3RyaXBzIHRoZSBzdGFnZSAob3IgYmFzZSBwYXRoXG4gICAgICAvLyBtYXBwaW5nKSBiZWZvcmUgbWF0Y2hpbmcsIHNvIHJlc291cmNlcyB1bmRlciB0aGUgcHJvcCdzIFwicHJvZFwiIGFyZSBvbmx5XG4gICAgICAvLyByZWFjaGVkIGF0IGAvcHJvZC9wcm9kLy4uLmAsIGFuZCBldmVyeSBsaW5rIHRoZSBhcHAgZW1pdHMgNDAzcy5cbiAgICAgIGNvbnN0IHByb2JsZW0gPVxuICAgICAgICBgQVBJIEdhdGV3YXkgc3RyaXBzIFwiLyR7bm9ybWFsaXplQmFzZVBhdGgoYXBpR2F0ZXdheS5zdHJpcHBlZFByZWZpeCl9XCIgYmVmb3JlIG1hdGNoaW5nIHJlc291cmNlcywgc28gYSBwcm9wIHRoYXQgcmVwZWF0cyBpdCBuZXN0cyBldmVyeSByZXNvdXJjZSB1bmRlciBhIHBhdGggbm8gcmVxdWVzdCByZWFjaGVzLiBgICtcbiAgICAgICAgXCJMZWF2ZSB0aGUgcHJvcCB1bnNldDogaXQgaXMgZGVyaXZlZCBmcm9tIHlvdXIgYXBwJ3MgYGJhc2VQYXRoYCB3aXRoIHRoYXQgcHJlZml4IHRha2VuIG9mZi5cIjtcbiAgICAgIGlmIChhcGlHYXRld2F5LmN1c3RvbURvbWFpbikge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IobWlzbWF0Y2ggKyBwcm9ibGVtKTtcbiAgICAgIH1cbiAgICAgIC8vIE9uIHRoZSBleGVjdXRlLWFwaSBlbmRwb2ludCB0aGF0IGlzIGNlcnRhaW4sIGJ1dCBhbiBleHBsaWNpdCBwcm9wIHdpbnM6XG4gICAgICAvLyBhIGRvbWFpbiBhdHRhY2hlZCB3aXRoIGBhZGREb21haW5OYW1lKClgLCBpbnZpc2libGUgaGVyZSwgY2FuIG1hcCB0aGVcbiAgICAgIC8vIHN0YWdlIGF0IGl0cyByb290LCBhbmQgdGhlbiBgL3Byb2QvLi4uYCBkb2VzIHJlYWNoIHJlc291cmNlcyB1bmRlclxuICAgICAgLy8gXCJwcm9kXCIuXG4gICAgICBjb25zb2xlLndhcm4oXG4gICAgICAgIG1pc21hdGNoICtcbiAgICAgICAgICBwcm9ibGVtICtcbiAgICAgICAgICBcIiAoSWdub3JlIHRoaXMgaWYgYSBkb21haW4gYXR0YWNoZWQgd2l0aCBgYWRkRG9tYWluTmFtZSgpYCBzZXJ2ZXMgdGhlIGFwcCB3aXRob3V0IHN0cmlwcGluZyB0aGF0IHByZWZpeC4pXCIsXG4gICAgICApO1xuICAgICAgcmV0dXJuIHByb3A7XG4gICAgfVxuICAgIGlmIChuZXh0anNUeXBlID09PSBOZXh0anNUeXBlLlJFR0lPTkFMX0ZVTkNUSU9OUyAmJiBwcm9wKSB7XG4gICAgICAvLyBBZ3JlZWluZyB0aGUgb3RoZXIgd2F5IHJvdW5kIGhhcyB0aGUgdW5zZXQgY2FzZSdzIHByb2JsZW06IHJlc291cmNlc1xuICAgICAgLy8gdW5kZXIgXCJkb2NzXCIgYXJlIHJlYWNoZWQgYXQgYC9wcm9kL2RvY3MvLi4uYCwgdGhlIGFwcCBsaW5rcyB0b1xuICAgICAgLy8gYC9kb2NzLy4uLmAuXG4gICAgICB3YXJuVW5zdHJpcHBlZEJhc2VQYXRoKGNvbmZpZywgYXBpR2F0ZXdheSk7XG4gICAgfVxuICAgIHJldHVybiBwcm9wIHx8IHVuZGVmaW5lZDtcbiAgfVxuXG4gIHN3aXRjaCAobmV4dGpzVHlwZSkge1xuICAgIGNhc2UgTmV4dGpzVHlwZS5HTE9CQUxfRlVOQ1RJT05TOlxuICAgIGNhc2UgTmV4dGpzVHlwZS5HTE9CQUxfQ09OVEFJTkVSUzpcbiAgICAgIC8vIGBOZXh0anNEaXN0cmlidXRpb25gIGJ1aWxkcyBpdHMgYmVoYXZpb3JzIGFzIGAvJHtiYXNlUGF0aH0vX25leHQvc3RhdGljKmBcbiAgICAgIC8vIGFuZCBDbG91ZEZyb250IGhhbmRzIGFuIFMzIG9yaWdpbiB0aGUgcmVxdWVzdCBwYXRoIHZlcmJhdGltIGFzIHRoZVxuICAgICAgLy8gb2JqZWN0IGtleSwgc28gdGhlIG9ubHkgdmFsdWUgdGhhdCBjYW4gc2VydmUgdGhlIGFwcCBpcyB0aGUgcHJlZml4IHRoZVxuICAgICAgLy8gYXBwIGl0c2VsZiBlbWl0cy4gVGhhdCBsZWF2ZXMgdGhlIHByb3Agbm8gcm9vbSB0byBkaWZmZXIsIHdoaWNoIG1ha2VzXG4gICAgICAvLyB0aGUgYXBwJ3MgY29uZmlnIHRoZSBzaW5nbGUgc291cmNlIG9mIHRydXRoIHdvcnRoIGRlcml2aW5nIGZyb20uXG4gICAgICBpZiAoIXByb3ApIHtcbiAgICAgICAgcmV0dXJuIGNvbmZpZztcbiAgICAgIH1cbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgbWlzbWF0Y2ggK1xuICAgICAgICAgIFwiQ2xvdWRGcm9udCBzZXJ2ZXMgc3RhdGljIGFzc2V0cyBzdHJhaWdodCBmcm9tIFMzIHVzaW5nIHRoZSByZXF1ZXN0IHBhdGggYXMgdGhlIG9iamVjdCBrZXksIHNvIGEgbWlzbWF0Y2ggbWVhbnMgZXZlcnkgYF9uZXh0L3N0YXRpY2AgYW5kIGBwdWJsaWMvYCByZXF1ZXN0IDQwNHMuIFwiICtcbiAgICAgICAgICBcIkVpdGhlciBzZXQgYm90aCB0byB0aGUgc2FtZSB2YWx1ZSwgb3IgZHJvcCB0aGUgcHJvcCDigJQgbGVmdCB1bnNldCwgaXQgZm9sbG93cyB5b3VyIGFwcCdzIGBiYXNlUGF0aGAuXCIsXG4gICAgICApO1xuICAgIGNhc2UgTmV4dGpzVHlwZS5SRUdJT05BTF9GVU5DVElPTlM6XG4gICAgICBpZiAoIXByb3ApIHtcbiAgICAgICAgLy8gQSBwcm9wIHRoYXQgaXMgc2V0IGJ1dCBuYW1lcyBubyBwYXRoIChcIi9cIikgaXMgYW4gZXhwbGljaXQgcm9vdFxuICAgICAgICAvLyBtb3VudCwgbm90IFwidW5zZXRcIjogaXQgaXMgaG93IGFuIGFwcCBzYXlzIHRoZSBwcmVmaXggaXMgc3RyaXBwZWQgYnlcbiAgICAgICAgLy8gc29tZXRoaW5nIHN5bnRoIGNhbid0IHNlZSDigJQgYSBkb21haW4gYXR0YWNoZWQgbGF0ZXIgd2l0aFxuICAgICAgICAvLyBgYWRkRG9tYWluTmFtZSh7IGJhc2VQYXRoIH0pYCwgc2F5IOKAlCBzbyBkZXJpdmluZyBoZXJlIHdvdWxkIG5lc3QgdGhlXG4gICAgICAgIC8vIHJlc291cmNlcyB1bmRlciBhIHBhdGggdGhlIHN0cmlwcGVkIHJlcXVlc3RzIG5ldmVyIHJlYWNoLlxuICAgICAgICBpZiAocHJvcEJhc2VQYXRoICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBkZXJpdmVBcGlHYXRld2F5QmFzZVBhdGgoY29uZmlnLCBhcGlHYXRld2F5KTtcbiAgICAgIH1cbiAgICAgIC8vIFRoZSBwcm9wIG9ubHkgaGFzIHRvIGJlIHRoZSB0YWlsIG9mIHdoYXQgdGhlIGFwcCBlbWl0cywgbm90IGFsbCBvZiBpdCxcbiAgICAgIC8vIGJlY2F1c2UgdGhlIHN0cmlwcGVkIHByZWZpeCBpcyBwYXJ0IG9mIHRoZSBhcHAncyBgYmFzZVBhdGhgIGJ1dCBuZXZlclxuICAgICAgLy8gcGFydCBvZiB0aGUgcmVzb3VyY2UgcGF0aDogYW4gYXBwIGF0IHRoZSBgcHJvZGAgc3RhZ2UgbmVzdGVkIHVuZGVyXG4gICAgICAvLyBcIi9iYXNlXCIgc2V0cyBgYmFzZVBhdGg6IFwiL3Byb2QvYmFzZVwiYCBhbmQgdGhlIHByb3AgdG8gXCIvYmFzZVwiLiBFeGFjdGx5XG4gICAgICAvLyB0aGUgc3RyaXBwZWQgcHJlZml4IGFuZCB0aGVuIHRoZSBwcm9wLCBub3QgYW55IHRhaWw6IHdpdGggYSBwcm9wIG9mXG4gICAgICAvLyBcIi9iYXNlXCIgYW4gYXBwIGF0IFwiL2Zvby9iYXNlXCIgaXMgc2VydmVkIGF0IGAvcHJvZC9iYXNlLy4uLmAgYW5kIGxpbmtzXG4gICAgICAvLyB0byBgL2Zvby9iYXNlLy4uLmAsIHdoaWNoIDQwM3MuIE9ubHkgYSB0b2tlbiBzdGFnZSwgd2hpY2ggc3ludGggY2FuJ3RcbiAgICAgIC8vIHJlYWQsIGZhbGxzIGJhY2sgdG8gYSB0YWlsIG9uIGEgcGF0aCBib3VuZGFyeS5cbiAgICAgIGlmIChcbiAgICAgICAgYXBpR2F0ZXdheS5zdHJpcHBlZFByZWZpeCA9PT0gdW5kZWZpbmVkXG4gICAgICAgICAgPyBjb25maWcuZW5kc1dpdGgoYC8ke3Byb3B9YClcbiAgICAgICAgICA6IGNvbmZpZyA9PT0gam9pblBhdGgoYXBpR2F0ZXdheS5zdHJpcHBlZFByZWZpeCwgcHJvcClcbiAgICAgICkge1xuICAgICAgICByZXR1cm4gcHJvcDtcbiAgICAgIH1cbiAgICAgIC8vIEFueSB0YWlsIG9uIGEgcGF0aCBib3VuZGFyeSBpcyBhbHNvIHdoYXQgYSBkb21haW4gYXR0YWNoZWQgd2l0aFxuICAgICAgLy8gYGFkZERvbWFpbk5hbWUoeyBiYXNlUGF0aDogXCJ2MVwiIH0pYCBuZWVkcyBmb3IgYW4gYXBwIGF0IFwiL3YxL2Jhc2VcIjpcbiAgICAgIC8vIHN5bnRoIG9ubHkgc2VlcyB0aGUgc3RhZ2UsIHNvIGl0IGNhbid0IHRlbGwgdGhhdCBzZXR1cCBmcm9tIGEgbWlzdGFrZS5cbiAgICAgIC8vIEFuIGV4cGxpY2l0IHByb3Agd2lucywgc28gdGhhdCB3YXJuczsgYSBjdXN0b20gZG9tYWluIGNvbmZpZ3VyZWQgaW5cbiAgICAgIC8vIGByZXN0QXBpUHJvcHMuZG9tYWluTmFtZWAgaXMgdmlzaWJsZSwgc28gdGhlcmUgaXQgc3RpbGwgdGhyb3dzIGJlbG93LlxuICAgICAgaWYgKCFhcGlHYXRld2F5LmN1c3RvbURvbWFpbiAmJiBjb25maWcuZW5kc1dpdGgoYC8ke3Byb3B9YCkpIHtcbiAgICAgICAgY29uc3QgbGVhZGluZyA9IGNvbmZpZy5zbGljZSgwLCAtcHJvcC5sZW5ndGggLSAxKTtcbiAgICAgICAgY29uc29sZS53YXJuKFxuICAgICAgICAgIGAke0xPR19QUkVGSVh9IHRoZSBcXGBiYXNlUGF0aFxcYCBwcm9wIGlzICR7cXVvdGUocHJvcCl9IGFuZCB5b3VyIE5leHQuanMgYXBwJ3MgXFxgYmFzZVBhdGhcXGAgaXMgJHtxdW90ZShjb25maWcpfSwgYCArXG4gICAgICAgICAgICBgc28gdGhlIGFwcCBpcyBzZXJ2ZWQgYXQgXCIvJHtqb2luUGF0aChub3JtYWxpemVCYXNlUGF0aChhcGlHYXRld2F5LnN0cmlwcGVkUHJlZml4KSwgcHJvcCl9XCIgb24gdGhlIGV4ZWN1dGUtYXBpIGVuZHBvaW50IGFuZCBsaW5rcyB0byBcIi8ke2NvbmZpZ31cIi4gYCArXG4gICAgICAgICAgICBgVGhhdCBvbmx5IHdvcmtzIHRocm91Z2ggYSBjdXN0b20gZG9tYWluIHdob3NlIGJhc2UgcGF0aCBtYXBwaW5nIHN0cmlwcyBcIi8ke2xlYWRpbmd9XCIgKFxcYGFkZERvbWFpbk5hbWUoeyBiYXNlUGF0aDogXCIke2xlYWRpbmd9XCIgfSlcXGApOyBvdGhlcndpc2UgZXZlcnkgcmVxdWVzdCA0MDNzLmAsXG4gICAgICAgICk7XG4gICAgICAgIHJldHVybiBwcm9wO1xuICAgICAgfVxuICAgICAgLy8gQW55dGhpbmcgZWxzZSBuZXZlciB3b3JrczogdGhlIHByb3AgbW92ZXMgZXZlcnkgcmVzb3VyY2UsIGluY2x1ZGluZyB0aGVcbiAgICAgIC8vIGBBTllgIGNhdGNoLWFsbCwgdW5kZXIgYSBwYXRoIHRoZSBhcHAgbmV2ZXIgbGlua3MgdG8uXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgIG1pc21hdGNoICtcbiAgICAgICAgICBcIlRoZSBgYmFzZVBhdGhgIHByb3AgbmVzdHMgZXZlcnkgQVBJIEdhdGV3YXkgcmVzb3VyY2UgdW5kZXIgdGhhdCBwYXRoLCBpbmNsdWRpbmcgdGhlIGNhdGNoLWFsbCwgc28gdGhlIGFwcCBoYXMgdG8gZW1pdCBpdHMgbGlua3MgdW5kZXIgdGhlIHNhbWUgcHJlZml4IG9yIGV2ZXJ5IHJlcXVlc3QgNDA0cy4gXCIgK1xuICAgICAgICAgICdFaXRoZXIgc2V0IHlvdXIgYXBwXFwncyBgYmFzZVBhdGhgIHRvIHRoZSBwcm9wLCBvciB0byB0aGUgcHJvcCBwcmVmaXhlZCBieSB0aGUgc3RhZ2Ugb3IgYmFzZSBwYXRoIG1hcHBpbmcgQVBJIEdhdGV3YXkgc3RyaXBzIChlLmcuIGBiYXNlUGF0aDogXCIvcHJvZC9iYXNlXCJgIHdpdGggYSBwcm9wIG9mIFwiL2Jhc2VcIiksIG9yIGxlYXZlIHRoZSBwcm9wIHVuc2V0IOKAlCB1bnNldCBpcyB3aGF0IHlvdSB3YW50IHdoZW4gdGhlIGFwcFxcJ3MgYGJhc2VQYXRoYCBpcyB0aGUgQVBJIEdhdGV3YXkgc3RhZ2UgbmFtZSwgc2luY2UgdGhlIHN0YWdlIGlzblxcJ3QgcGFydCBvZiB0aGUgcmVzb3VyY2UgcGF0aC4nLFxuICAgICAgKTtcbiAgICBjYXNlIE5leHRqc1R5cGUuUkVHSU9OQUxfQ09OVEFJTkVSUzpcbiAgICAgIC8vIFRoZSBBTEIgZm9yd2FyZHMgZXZlcnkgcGF0aCB0byB0aGUgY29udGFpbmVyLCB3aGljaCBzZXJ2ZXMgaXRzIG93blxuICAgICAgLy8gc3RhdGljIGFzc2V0cywgc28gaGVyZSBgYmFzZVBhdGhgIG9ubHkgbmFtZXNwYWNlcyB0aGUgUzMgYnVja2V0IGFuZCBoYXNcbiAgICAgIC8vIG5vIHJvdXRpbmcgbWVhbmluZyB0aGF0IGNvdWxkIGRpc2FncmVlIHdpdGggdGhlIGFwcC5cbiAgICAgIHJldHVybiBwcm9wIHx8IHVuZGVmaW5lZDtcbiAgfVxufVxuIl19
|