cdk-nextjs 0.7.11 → 0.7.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/.jsii +310 -100
  2. package/.jsii.tabl.json +1 -1
  3. package/API.md +211 -3
  4. package/README.md +116 -101
  5. package/docs/breaking-changes.md +36 -2
  6. package/docs/development-guide.md +10 -0
  7. package/docs/next-build-output-guide.md +1 -1
  8. package/lib/adapter/adapter.mjs +4 -1
  9. package/lib/generated-structs/OptionalNextjsDistributionProps.d.ts +21 -0
  10. package/lib/generated-structs/OptionalNextjsDistributionProps.js +1 -1
  11. package/lib/nextjs-api.js +1 -1
  12. package/lib/nextjs-build/nextjs-build.js +1 -1
  13. package/lib/nextjs-cache.js +1 -1
  14. package/lib/nextjs-compute/nextjs-containers.js +1 -1
  15. package/lib/nextjs-compute/nextjs-functions.js +1 -1
  16. package/lib/nextjs-distribution.d.ts +71 -2
  17. package/lib/nextjs-distribution.js +156 -107
  18. package/lib/nextjs-distribution.test.js +361 -12
  19. package/lib/nextjs-post-deploy.js +1 -1
  20. package/lib/nextjs-static-assets.d.ts +74 -5
  21. package/lib/nextjs-static-assets.js +276 -41
  22. package/lib/nextjs-static-assets.test.js +298 -1
  23. package/lib/root-constructs/nextjs-base-construct.d.ts +5 -4
  24. package/lib/root-constructs/nextjs-base-construct.js +17 -8
  25. package/lib/root-constructs/nextjs-global-containers.d.ts +16 -1
  26. package/lib/root-constructs/nextjs-global-containers.js +4 -2
  27. package/lib/root-constructs/nextjs-global-functions.d.ts +16 -1
  28. package/lib/root-constructs/nextjs-global-functions.js +4 -2
  29. package/lib/root-constructs/nextjs-regional-containers.js +1 -1
  30. package/lib/root-constructs/nextjs-regional-functions.js +1 -1
  31. package/lib/runtime/image-utils.d.ts +1 -0
  32. package/lib/runtime/image-utils.js +2 -1
  33. package/lib/runtime/image-utils.test.js +17 -1
  34. package/lib/runtime/image.js +5 -2
  35. package/lib/runtime/image.test.js +21 -1
  36. package/lib/runtime/lambda.mjs +9 -2
  37. package/lib/runtime/server.mjs +9 -2
  38. package/lib/utils/viewer-request-functions.d.ts +53 -0
  39. package/lib/utils/viewer-request-functions.js +172 -0
  40. package/lib/utils/viewer-request-functions.test.d.ts +1 -0
  41. package/lib/utils/viewer-request-functions.test.js +43 -0
  42. package/package.json +4 -1
  43. package/scripts/e2e-harness/app.js +7 -2
  44. package/scripts/render-diagrams.mjs +121 -0
@@ -18,7 +18,7 @@ const base_path_1 = require("./utils/base-path");
18
18
  * current build id AND are older than `msTtl`
19
19
  */
20
20
  class NextjsPostDeploy extends constructs_1.Construct {
21
- static [JSII_RTTI_SYMBOL_1] = { fqn: "cdk-nextjs.NextjsPostDeploy", version: "0.7.11" };
21
+ static [JSII_RTTI_SYMBOL_1] = { fqn: "cdk-nextjs.NextjsPostDeploy", version: "0.7.13" };
22
22
  customResource;
23
23
  lambdaFunction;
24
24
  props;
@@ -10,6 +10,19 @@ import { Construct } from "constructs";
10
10
  export declare function staticAssetsObjectsPattern(keyPrefix?: string): string;
11
11
  export interface NextjsStaticAssetsOverrides {
12
12
  readonly bucketProps?: BucketProps;
13
+ /**
14
+ * Applied to every upload (`public/`, `_next/static/` and
15
+ * `_next/static/service-worker/`), except that the two `_next/static` uploads
16
+ * always keep the `Cache-Control` Next.js sends for them. So a `cacheControl`
17
+ * here sets the header for `public/` files only, while anything else, such as
18
+ * a `distribution` to invalidate, applies to each upload in turn.
19
+ *
20
+ * `sources` and `destinationBucket`, which the type requires, are ignored:
21
+ * the uploads are always the build's assets, to the bucket CloudFront and
22
+ * API Gateway read from (pass `bucket` to bring your own). `prune: true` and
23
+ * `retainOnDelete: false` are rejected, since each would break the other
24
+ * uploads.
25
+ */
13
26
  readonly bucketDeploymentProps?: BucketDeploymentProps;
14
27
  }
15
28
  export interface NextjsStaticAssetsProps {
@@ -43,7 +56,35 @@ export interface NextjsStaticAssetsProps {
43
56
  */
44
57
  export declare class NextjsStaticAssets extends Construct {
45
58
  bucket: IBucket;
59
+ /**
60
+ * The first of `staticDeployment`, `serviceWorkerDeployment` and
61
+ * `publicDeployment` the build has files for.
62
+ *
63
+ * @deprecated The assets are uploaded by up to three deployments, and this
64
+ * is only one of them: a dependency on it doesn't wait for the others. Use
65
+ * `staticDeployment`, `serviceWorkerDeployment` and `publicDeployment`.
66
+ */
46
67
  deployment: BucketDeployment;
68
+ /**
69
+ * Uploads `.next/static` to `_next/static/` with
70
+ * `Cache-Control: public, max-age=31536000, immutable`, except for
71
+ * `service-worker/` (see `serviceWorkerDeployment`). Absent if the build has
72
+ * no `.next/static`.
73
+ */
74
+ readonly staticDeployment?: BucketDeployment;
75
+ /**
76
+ * Uploads `.next/static/service-worker` with
77
+ * `Cache-Control: public, max-age=0, must-revalidate`, as Next.js serves it:
78
+ * a service worker keeps its URL across builds, so it can't be `immutable`.
79
+ * Absent if the build has no service worker.
80
+ */
81
+ readonly serviceWorkerDeployment?: BucketDeployment;
82
+ /**
83
+ * Uploads `public/`, separately from `staticDeployment` because its files
84
+ * keep their names when they change and so can't be `immutable`. Absent if
85
+ * the build has no `public` directory.
86
+ */
87
+ readonly publicDeployment?: BucketDeployment;
47
88
  /**
48
89
  * S3 key prefix the assets are actually uploaded under, normalized to a bare
49
90
  * path segment (empty when they live at the bucket root).
@@ -57,9 +98,34 @@ export declare class NextjsStaticAssets extends Construct {
57
98
  * bytes were uploaded.
58
99
  */
59
100
  readonly keyPrefix: string;
60
- private stagingDir?;
61
101
  private props;
62
102
  constructor(scope: Construct, id: string, props: NextjsStaticAssetsProps);
103
+ /**
104
+ * Stages each tree and creates its deployment, adding every staging
105
+ * directory to `staged` as it's made, so the caller can remove them even if
106
+ * a later step throws.
107
+ */
108
+ private createDeployments;
109
+ /**
110
+ * Rejects the `bucketDeploymentProps` that can't work across several
111
+ * deployments sharing one prefix. Each is spread into every one of them:
112
+ *
113
+ * - `prune: true` makes each deployment's `s3 sync --delete` remove the files
114
+ * the others uploaded.
115
+ * - `retainOnDelete: false` makes a deployment `s3 rm --recursive` its old
116
+ * prefix when the prefix changes, without checking whether the bucket is
117
+ * CDK's (only Delete checks), so it can delete files another deployment has
118
+ * just uploaded there. On Delete, CDK skips that `rm` only for a bucket it
119
+ * tagged, and it can't tag an imported one, so a build that stops having
120
+ * files for one deployment would lose the others' files too.
121
+ *
122
+ * `sources` and `destinationBucket` aren't rejected, because the type
123
+ * requires them; `newDeployment` sets them after the spread instead.
124
+ *
125
+ * Compared against the exact value, as with `destinationKeyPrefix`, so an
126
+ * explicit `undefined` from a JSII binding is not mistaken for an override.
127
+ */
128
+ private validateDeploymentOverrides;
63
129
  /**
64
130
  * Resolves the single prefix both the upload and the URLs use. A
65
131
  * `bucketDeploymentProps.destinationKeyPrefix` override wins over `basePath`,
@@ -77,11 +143,14 @@ export declare class NextjsStaticAssets extends Construct {
77
143
  private createBucket;
78
144
  private createDeployment;
79
145
  /**
80
- * Create a staging directory with the correct structure:
81
- * - public/ files go to root
82
- * - .next/static/ files go to _next/static/
146
+ * Copies `sourceDir` to `<staging>/<subPath>` in a new staging directory, or
147
+ * returns `undefined` if there is no `sourceDir` or no file in it passes
148
+ * `include`. Staged under `subPath` rather than uploaded with a longer
149
+ * `destinationKeyPrefix`, so every deployment shares the one prefix
150
+ * `keyPrefix` resolves. `include` gets each entry's path relative to
151
+ * `sourceDir`.
83
152
  */
84
- private createStagingDirectory;
153
+ private stageDirectory;
85
154
  /**
86
155
  * Check if a directory exists
87
156
  */
@@ -1,4 +1,37 @@
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.NextjsStaticAssets = void 0;
4
37
  exports.staticAssetsObjectsPattern = staticAssetsObjectsPattern;
@@ -9,6 +42,7 @@ const node_path_1 = require("node:path");
9
42
  const aws_cdk_lib_1 = require("aws-cdk-lib");
10
43
  const aws_s3_1 = require("aws-cdk-lib/aws-s3");
11
44
  const aws_s3_deployment_1 = require("aws-cdk-lib/aws-s3-deployment");
45
+ const cxapi = __importStar(require("aws-cdk-lib/cx-api"));
12
46
  const constructs_1 = require("constructs");
13
47
  const constants_1 = require("./constants");
14
48
  const base_path_1 = require("./utils/base-path");
@@ -25,13 +59,90 @@ function staticAssetsObjectsPattern(keyPrefix) {
25
59
  const prefix = (0, base_path_1.normalizeBasePath)(keyPrefix);
26
60
  return prefix ? `${prefix}/*` : "*";
27
61
  }
62
+ /** Where `.next/static` is served from, relative to `keyPrefix`. */
63
+ const STATIC_PATH = (0, node_path_1.join)("_next", "static");
64
+ /** Where Next.js compiles service workers to, relative to `.next/static`. */
65
+ const SERVICE_WORKER_DIR = "service-worker";
66
+ /**
67
+ * Every file under `dir`, relative to it, through symlinks too: CDK uploads a
68
+ * linked file or directory as what it points to, under every name it's reached
69
+ * by.
70
+ *
71
+ * An explicit walk rather than `readdirSync({ recursive: true })`, which never
72
+ * returns on a symlink cycle (Node 24 follows directory links), and whose
73
+ * `Dirent.parentPath` doesn't exist before Node 20.12. A link back to a
74
+ * directory already on the current path is a cycle and isn't followed; one that
75
+ * can't be stat'd (dangling, or a loop of links) counts as a file.
76
+ */
77
+ function listFiles(dir) {
78
+ const files = [];
79
+ const walk = (sub, ancestors) => {
80
+ const real = (0, node_fs_1.realpathSync)((0, node_path_1.join)(dir, sub));
81
+ if (ancestors.has(real)) {
82
+ return;
83
+ }
84
+ const path = new Set(ancestors).add(real);
85
+ for (const entry of (0, node_fs_1.readdirSync)(real, { withFileTypes: true })) {
86
+ const child = (0, node_path_1.join)(sub, entry.name);
87
+ if (entry.isDirectory() ||
88
+ (entry.isSymbolicLink() && isDirectoryLink((0, node_path_1.join)(real, entry.name)))) {
89
+ walk(child, path);
90
+ }
91
+ else {
92
+ files.push(child);
93
+ }
94
+ }
95
+ };
96
+ walk("", new Set());
97
+ return files;
98
+ }
99
+ function isDirectoryLink(path) {
100
+ try {
101
+ return (0, node_fs_1.statSync)(path).isDirectory();
102
+ }
103
+ catch {
104
+ return false;
105
+ }
106
+ }
107
+ /** Whether the relative `path` is `dir` or inside it. */
108
+ function isWithin(path, dir) {
109
+ return path === dir || path.startsWith(dir + node_path_1.sep);
110
+ }
28
111
  /**
29
112
  * Creates S3 Bucket for public and _next/static assets and deploys them using S3Deployment.
30
113
  */
31
114
  class NextjsStaticAssets extends constructs_1.Construct {
32
- static [JSII_RTTI_SYMBOL_1] = { fqn: "cdk-nextjs.NextjsStaticAssets", version: "0.7.11" };
115
+ static [JSII_RTTI_SYMBOL_1] = { fqn: "cdk-nextjs.NextjsStaticAssets", version: "0.7.13" };
33
116
  bucket;
117
+ /**
118
+ * The first of `staticDeployment`, `serviceWorkerDeployment` and
119
+ * `publicDeployment` the build has files for.
120
+ *
121
+ * @deprecated The assets are uploaded by up to three deployments, and this
122
+ * is only one of them: a dependency on it doesn't wait for the others. Use
123
+ * `staticDeployment`, `serviceWorkerDeployment` and `publicDeployment`.
124
+ */
34
125
  deployment;
126
+ /**
127
+ * Uploads `.next/static` to `_next/static/` with
128
+ * `Cache-Control: public, max-age=31536000, immutable`, except for
129
+ * `service-worker/` (see `serviceWorkerDeployment`). Absent if the build has
130
+ * no `.next/static`.
131
+ */
132
+ staticDeployment;
133
+ /**
134
+ * Uploads `.next/static/service-worker` with
135
+ * `Cache-Control: public, max-age=0, must-revalidate`, as Next.js serves it:
136
+ * a service worker keeps its URL across builds, so it can't be `immutable`.
137
+ * Absent if the build has no service worker.
138
+ */
139
+ serviceWorkerDeployment;
140
+ /**
141
+ * Uploads `public/`, separately from `staticDeployment` because its files
142
+ * keep their names when they change and so can't be `immutable`. Absent if
143
+ * the build has no `public` directory.
144
+ */
145
+ publicDeployment;
35
146
  /**
36
147
  * S3 key prefix the assets are actually uploaded under, normalized to a bare
37
148
  * path segment (empty when they live at the bucket root).
@@ -45,14 +156,132 @@ class NextjsStaticAssets extends constructs_1.Construct {
45
156
  * bytes were uploaded.
46
157
  */
47
158
  keyPrefix;
48
- stagingDir;
49
159
  props;
50
160
  constructor(scope, id, props) {
51
161
  super(scope, id);
52
162
  this.props = props;
163
+ this.validateDeploymentOverrides();
53
164
  this.keyPrefix = this.resolveKeyPrefix();
54
165
  this.bucket = props.bucket ?? this.createBucket();
55
- this.deployment = this.createDeployment();
166
+ const staged = [];
167
+ try {
168
+ const uploads = this.createDeployments(staged);
169
+ this.staticDeployment = uploads.staticDeployment;
170
+ this.serviceWorkerDeployment = uploads.serviceWorkerDeployment;
171
+ this.publicDeployment = uploads.publicDeployment;
172
+ }
173
+ finally {
174
+ // `Source.asset` stages during `BucketDeployment`'s construction (CDK's
175
+ // `AssetStaging` copies into `cdk.out` from its own constructor), so the
176
+ // temporary copies are dead once the deployments exist, or once one of
177
+ // them failed. Left behind, every synth would add another full copy of
178
+ // the app's static assets to the temp directory.
179
+ //
180
+ // Unless staging is disabled (`cdk synth --no-staging`, and SAM, which
181
+ // sets the same context): then the asset manifest points at these
182
+ // directories themselves, and removing them would fail the publish that
183
+ // follows.
184
+ if (!this.node.tryGetContext(cxapi.DISABLE_ASSET_STAGING_CONTEXT)) {
185
+ for (const dir of staged) {
186
+ (0, node_fs_1.rmSync)(dir, { recursive: true, force: true });
187
+ }
188
+ }
189
+ }
190
+ this.deployment = (this.staticDeployment ??
191
+ this.serviceWorkerDeployment ??
192
+ this.publicDeployment);
193
+ }
194
+ /**
195
+ * Stages each tree and creates its deployment, adding every staging
196
+ * directory to `staged` as it's made, so the caller can remove them even if
197
+ * a later step throws.
198
+ */
199
+ createDeployments(staged) {
200
+ const stage = (...args) => {
201
+ const dir = this.stageDirectory(...args);
202
+ if (dir) {
203
+ staged.push(dir);
204
+ }
205
+ return dir;
206
+ };
207
+ const builtDir = (0, node_path_1.join)(this.props.buildDirectory, ".next", "static");
208
+ const publicSourceDir = (0, node_path_1.join)(this.props.buildDirectory, "public");
209
+ // Only a directory is uploaded as service workers, so only a directory is
210
+ // left out here.
211
+ const hasServiceWorkers = this.directoryExists((0, node_path_1.join)(builtDir, SERVICE_WORKER_DIR));
212
+ const staticDir = stage(builtDir, STATIC_PATH, (path) => !hasServiceWorkers || !isWithin(path, SERVICE_WORKER_DIR));
213
+ const serviceWorkerDir = stage((0, node_path_1.join)(builtDir, SERVICE_WORKER_DIR), (0, node_path_1.join)(STATIC_PATH, SERVICE_WORKER_DIR));
214
+ // A `public/_next/static` file with a built file's name would land on the
215
+ // same key. `next start` serves the built one, so the public copy is left
216
+ // out; uploading both would leave whichever deployment finished last.
217
+ // Other `public/_next/static` files are served as `next start` does.
218
+ // Matched against a listing rather than with `existsSync`, which on macOS
219
+ // and Windows would let `Legacy.js` shadow `legacy.js`: Next.js and S3 keys
220
+ // are case-sensitive.
221
+ const builtFiles = new Set(this.directoryExists(builtDir) ? listFiles(builtDir) : []);
222
+ const publicDir = stage(publicSourceDir, "", (path) => !isWithin(path, STATIC_PATH) ||
223
+ !builtFiles.has((0, node_path_1.relative)(STATIC_PATH, path)));
224
+ if (!staticDir && !serviceWorkerDir && !publicDir) {
225
+ throw new Error(`No static assets found to deploy. Ensure your Next.js build output contains files in either:
226
+ - A 'public' directory at: ${publicSourceDir}
227
+ - A '.next/static' directory at: ${builtDir}`);
228
+ }
229
+ // `_next/static/` files are content-hashed, so they get the same header
230
+ // Next.js sends for them. Nothing else would: CloudFront and API Gateway
231
+ // serve them straight from S3, where the object's metadata is the only
232
+ // `Cache-Control` there is. A `BucketDeployment`'s `cacheControl` applies to
233
+ // every object it uploads, hence one deployment per header.
234
+ return {
235
+ staticDeployment: staticDir
236
+ ? this.createDeployment("Deployment", staticDir, [
237
+ aws_s3_deployment_1.CacheControl.setPublic(),
238
+ aws_s3_deployment_1.CacheControl.maxAge(aws_cdk_lib_1.Duration.days(365)),
239
+ aws_s3_deployment_1.CacheControl.immutable(),
240
+ ])
241
+ : undefined,
242
+ serviceWorkerDeployment: serviceWorkerDir
243
+ ? this.createDeployment("ServiceWorkerDeployment", serviceWorkerDir, [
244
+ aws_s3_deployment_1.CacheControl.setPublic(),
245
+ aws_s3_deployment_1.CacheControl.maxAge(aws_cdk_lib_1.Duration.seconds(0)),
246
+ aws_s3_deployment_1.CacheControl.mustRevalidate(),
247
+ ])
248
+ : undefined,
249
+ publicDeployment: publicDir
250
+ ? this.createDeployment("PublicDeployment", publicDir)
251
+ : undefined,
252
+ };
253
+ }
254
+ /**
255
+ * Rejects the `bucketDeploymentProps` that can't work across several
256
+ * deployments sharing one prefix. Each is spread into every one of them:
257
+ *
258
+ * - `prune: true` makes each deployment's `s3 sync --delete` remove the files
259
+ * the others uploaded.
260
+ * - `retainOnDelete: false` makes a deployment `s3 rm --recursive` its old
261
+ * prefix when the prefix changes, without checking whether the bucket is
262
+ * CDK's (only Delete checks), so it can delete files another deployment has
263
+ * just uploaded there. On Delete, CDK skips that `rm` only for a bucket it
264
+ * tagged, and it can't tag an imported one, so a build that stops having
265
+ * files for one deployment would lose the others' files too.
266
+ *
267
+ * `sources` and `destinationBucket` aren't rejected, because the type
268
+ * requires them; `newDeployment` sets them after the spread instead.
269
+ *
270
+ * Compared against the exact value, as with `destinationKeyPrefix`, so an
271
+ * explicit `undefined` from a JSII binding is not mistaken for an override.
272
+ */
273
+ validateDeploymentOverrides() {
274
+ const overrides = this.props.overrides?.bucketDeploymentProps;
275
+ const rejected = [
276
+ overrides?.prune === true &&
277
+ "`prune: true` (old assets are pruned after deploy by NextjsPostDeploy, once they are past its TTL)",
278
+ overrides?.retainOnDelete === false && "`retainOnDelete: false`",
279
+ ].filter((reason) => !!reason);
280
+ if (rejected.length > 0) {
281
+ throw new Error(`${constants_1.LOG_PREFIX} overrides.bucketDeploymentProps can't set ${rejected.join(", or ")}: ` +
282
+ "the static assets are uploaded by one deployment per Cache-Control, " +
283
+ "and each of these would break the others.");
284
+ }
56
285
  }
57
286
  /**
58
287
  * Resolves the single prefix both the upload and the URLs use. A
@@ -85,24 +314,24 @@ class NextjsStaticAssets extends constructs_1.Construct {
85
314
  ...this.props.overrides?.bucketProps,
86
315
  });
87
316
  }
88
- createDeployment() {
89
- // Create a staging directory with the correct structure
90
- this.stagingDir = this.createStagingDirectory();
91
- if (!this.stagingDir) {
92
- throw new Error(`No static assets found to deploy. Ensure your Next.js build output contains either:
93
- - A 'public' directory at: ${(0, node_path_1.join)(this.props.buildDirectory, "public")}
94
- - A '.next/static' directory at: ${(0, node_path_1.join)(this.props.buildDirectory, ".next", "static")}`);
95
- }
96
- return new aws_s3_deployment_1.BucketDeployment(this, "Deployment", {
97
- sources: [aws_s3_deployment_1.Source.asset(this.stagingDir)],
98
- destinationBucket: this.bucket,
317
+ createDeployment(id, stagingDir, cacheControl) {
318
+ return new aws_s3_deployment_1.BucketDeployment(this, id, {
99
319
  // Add BUILD_ID as metadata to all objects for version tracking
100
320
  metadata: {
101
321
  BUILD_ID: this.props.buildId,
102
322
  },
103
- prune: false, // Don't delete existing assets to prevent 404s during deployment, pruning will be handled by post-deploy
104
323
  // S3Deployment automatically detects content types based on file extensions
105
324
  ...this.props.overrides?.bucketDeploymentProps,
325
+ // Set after the spread. The type makes callers pass `sources` and
326
+ // `destinationBucket`, and either would upload something other than the
327
+ // build's assets, or somewhere CloudFront and API Gateway don't read from.
328
+ // `validateDeploymentOverrides` lets `prune` through only as `false` or an
329
+ // explicit `undefined` from a JSII binding, which would turn on CDK's
330
+ // default `prune: true`.
331
+ sources: [aws_s3_deployment_1.Source.asset(stagingDir)],
332
+ destinationBucket: this.bucket,
333
+ prune: false, // Don't delete existing assets to prevent 404s during deployment, pruning will be handled by post-deploy
334
+ ...(cacheControl && { cacheControl }),
106
335
  // Set after the spread: `resolveKeyPrefix` already folded in any
107
336
  // `destinationKeyPrefix` override, so this is the normalized form of it.
108
337
  // Letting the raw override through here would upload the assets somewhere
@@ -111,43 +340,49 @@ class NextjsStaticAssets extends constructs_1.Construct {
111
340
  });
112
341
  }
113
342
  /**
114
- * Create a staging directory with the correct structure:
115
- * - public/ files go to root
116
- * - .next/static/ files go to _next/static/
343
+ * Copies `sourceDir` to `<staging>/<subPath>` in a new staging directory, or
344
+ * returns `undefined` if there is no `sourceDir` or no file in it passes
345
+ * `include`. Staged under `subPath` rather than uploaded with a longer
346
+ * `destinationKeyPrefix`, so every deployment shares the one prefix
347
+ * `keyPrefix` resolves. `include` gets each entry's path relative to
348
+ * `sourceDir`.
117
349
  */
118
- createStagingDirectory() {
350
+ stageDirectory(sourceDir, subPath, include = () => true) {
351
+ if (!this.directoryExists(sourceDir)) {
352
+ return undefined;
353
+ }
354
+ // From the real path, and dereferencing links inside it: `cpSync` would
355
+ // copy a link as a link, which fails for a symlinked `sourceDir` (onto the
356
+ // directory made for it here) and hides a linked directory's files from
357
+ // `include`, though CDK uploads them.
358
+ const realSourceDir = (0, node_fs_1.realpathSync)(sourceDir);
119
359
  const stagingDir = (0, node_fs_1.mkdtempSync)((0, node_path_1.join)((0, node_os_1.tmpdir)(), "nextjs-assets-"));
120
- let hasAssets = false;
121
360
  try {
122
- // Copy public directory contents to staging root
123
- const publicPath = (0, node_path_1.join)(this.props.buildDirectory, "public");
124
- if (this.directoryExists(publicPath)) {
125
- (0, node_fs_1.cpSync)(publicPath, stagingDir, { recursive: true });
126
- hasAssets = true;
127
- }
128
- // Copy .next/static to staging/_next/static
129
- const staticPath = (0, node_path_1.join)(this.props.buildDirectory, ".next", "static");
130
- if (this.directoryExists(staticPath)) {
131
- const nextDir = (0, node_path_1.join)(stagingDir, "_next");
132
- const staticDestDir = (0, node_path_1.join)(nextDir, "static");
133
- // Create _next directory
134
- (0, node_fs_1.mkdirSync)(nextDir, { recursive: true });
135
- // Copy static assets
136
- (0, node_fs_1.cpSync)(staticPath, staticDestDir, { recursive: true });
137
- hasAssets = true;
361
+ const destDir = (0, node_path_1.join)(stagingDir, subPath);
362
+ (0, node_fs_1.mkdirSync)(destDir, { recursive: true });
363
+ (0, node_fs_1.cpSync)(realSourceDir, destDir, {
364
+ recursive: true,
365
+ dereference: true,
366
+ filter: (path) => include((0, node_path_1.relative)(realSourceDir, path)),
367
+ });
368
+ if (listFiles(destDir).length === 0) {
369
+ (0, node_fs_1.rmSync)(stagingDir, { recursive: true, force: true });
370
+ return undefined;
138
371
  }
139
- return hasAssets ? stagingDir : undefined;
372
+ return stagingDir;
140
373
  }
141
374
  catch (error) {
142
- console.error(`${constants_1.LOG_PREFIX} Error creating staging directory:`, error);
143
- // Clean up on error
375
+ // Thrown rather than skipped, which would deploy without these assets.
376
+ // The cleanup's own failure must not replace that error.
144
377
  try {
145
378
  (0, node_fs_1.rmSync)(stagingDir, { recursive: true, force: true });
146
379
  }
147
380
  catch {
148
381
  // Ignore cleanup errors
149
382
  }
150
- return undefined;
383
+ throw new Error(`${constants_1.LOG_PREFIX} Could not stage ${sourceDir} for upload`, {
384
+ cause: error,
385
+ });
151
386
  }
152
387
  }
153
388
  /**
@@ -163,4 +398,4 @@ class NextjsStaticAssets extends constructs_1.Construct {
163
398
  }
164
399
  }
165
400
  exports.NextjsStaticAssets = NextjsStaticAssets;
166
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmV4dGpzLXN0YXRpYy1hc3NldHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvbmV4dGpzLXN0YXRpYy1hc3NldHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBaUNBLGdFQU1DOztBQXZDRCxxQ0FPaUI7QUFDakIscUNBQWlDO0FBQ2pDLHlDQUFpQztBQUNqQyw2Q0FBbUQ7QUFDbkQsK0NBTTRCO0FBQzVCLHFFQUl1QztBQUN2QywyQ0FBdUM7QUFDdkMsMkNBQXlDO0FBQ3pDLGlEQUFzRDtBQUV0RDs7Ozs7R0FLRztBQUNILFNBQWdCLDBCQUEwQixDQUFDLFNBQWtCO0lBQzNELElBQUksU0FBUyxJQUFJLG1CQUFLLENBQUMsWUFBWSxDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQUM7UUFDL0MsT0FBTyxHQUFHLENBQUM7SUFDYixDQUFDO0lBQ0QsTUFBTSxNQUFNLEdBQUcsSUFBQSw2QkFBaUIsRUFBQyxTQUFTLENBQUMsQ0FBQztJQUM1QyxPQUFPLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxNQUFNLElBQUksQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDO0FBQ3RDLENBQUM7QUFrQ0Q7O0dBRUc7QUFDSCxNQUFhLGtCQUFtQixTQUFRLHNCQUFTOztJQUMvQyxNQUFNLENBQVU7SUFDaEIsVUFBVSxDQUFtQjtJQUM3Qjs7Ozs7Ozs7Ozs7T0FXRztJQUNNLFNBQVMsQ0FBUztJQUNuQixVQUFVLENBQVU7SUFFcEIsS0FBSyxDQUEwQjtJQUV2QyxZQUFZLEtBQWdCLEVBQUUsRUFBVSxFQUFFLEtBQThCO1FBQ3RFLEtBQUssQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFDakIsSUFBSSxDQUFDLEtBQUssR0FBRyxLQUFLLENBQUM7UUFDbkIsSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQztRQUN6QyxJQUFJLENBQUMsTUFBTSxHQUFHLEtBQUssQ0FBQyxNQUFNLElBQUksSUFBSSxDQUFD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O0lBQ0ssZUFBZSxDQUFDLE9BQWU7UUFDckMsSUFBSSxDQUFDO1lBQ0gsT0FBTyxJQUFBLG9CQUFVLEVBQUMsT0FBTyxDQUFDLElBQUksSUFBQSxrQkFBUSxFQUFDLE9BQU8sQ0FBQyxDQUFDLFdBQVcsRUFBRSxDQUFDO1FBQ2hFLENBQUM7UUFBQyxNQUFNLENBQUM7WUFDUCxPQUFPLEtBQUssQ0FBQztRQUNmLENBQUM7SUFDSCxDQUFDOztBQWpKSCxnREFrSkMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBjcFN5bmMsXG4gIGV4aXN0c1N5bmMsXG4gIG1rZGlyU3luYyxcbiAgbWtkdGVtcFN5bmMsXG4gIHJtU3luYyxcbiAgc3RhdFN5bmMsXG59IGZyb20gXCJub2RlOmZzXCI7XG5pbXBvcnQgeyB0bXBkaXIgfSBmcm9tIFwibm9kZTpvc1wiO1xuaW1wb3J0IHsgam9pbiB9IGZyb20gXCJub2RlOnBhdGhcIjtcbmltcG9ydCB7IFJlbW92YWxQb2xpY3ksIFRva2VuIH0gZnJvbSBcImF3cy1jZGstbGliXCI7XG5pbXBvcnQge1xuICBCbG9ja1B1YmxpY0FjY2VzcyxcbiAgQnVja2V0LFxuICBCdWNrZXRFbmNyeXB0aW9uLFxuICBCdWNrZXRQcm9wcyxcbiAgSUJ1Y2tldCxcbn0gZnJvbSBcImF3cy1jZGstbGliL2F3cy1zM1wiO1xuaW1wb3J0IHtcbiAgQnVja2V0RGVwbG95bWVudCxcbiAgQnVja2V0RGVwbG95bWVudFByb3BzLFxuICBTb3VyY2UsXG59IGZyb20gXCJhd3MtY2RrLWxpYi9hd3MtczMtZGVwbG95bWVudFwiO1xuaW1wb3J0IHsgQ29uc3RydWN0IH0gZnJvbSBcImNvbnN0cnVjdHNcIjtcbmltcG9ydCB7IExPR19QUkVGSVggfSBmcm9tIFwiLi9jb25zdGFudHNcIjtcbmltcG9ydCB7IG5vcm1hbGl6ZUJhc2VQYXRoIH0gZnJvbSBcIi4vdXRpbHMvYmFzZS1wYXRoXCI7XG5cbi8qKlxuICogVGhlIFMzIG9iamVjdCBrZXkgcGF0dGVybiBjb3ZlcmluZyBldmVyeSBzdGF0aWMgYXNzZXQgdXBsb2FkZWQgdW5kZXJcbiAqIGBrZXlQcmVmaXhgIChgTmV4dGpzU3RhdGljQXNzZXRzLmtleVByZWZpeGApOiBgXCJiYXNlLypcImAsIG9yIGBcIipcImAgYXQgdGhlXG4gKiBidWNrZXQgcm9vdC4gRm9yIHNjb3BpbmcgdGhlIGNvbXB1dGUncyByZWFkIGdyYW50IHRvIHRoZSBhcHAncyBvd24gb2JqZWN0c1xuICogd2hlbiBzZXZlcmFsIGFwcHMgc2hhcmUgb25lIGJ1Y2tldC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHN0YXRpY0Fzc2V0c09iamVjdHNQYXR0ZXJuKGtleVByZWZpeD86IHN0cmluZyk6IHN0cmluZyB7XG4gIGlmIChrZXlQcmVmaXggJiYgVG9rZW4uaXNVbnJlc29sdmVkKGtleVByZWZpeCkpIHtcbiAgICByZXR1cm4gXCIqXCI7XG4gIH1cbiAgY29uc3QgcHJlZml4ID0gbm9ybWFsaXplQmFzZVBhdGgoa2V5UHJlZml4KTtcbiAgcmV0dXJuIHByZWZpeCA/IGAke3ByZWZpeH0vKmAgOiBcIipcIjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBOZXh0anNTdGF0aWNBc3NldHNPdmVycmlkZXMge1xuICByZWFkb25seSBidWNrZXRQcm9wcz86IEJ1Y2tldFByb3BzO1xuICByZWFkb25seSBidWNrZXREZXBsb3ltZW50UHJvcHM/OiBCdWNrZXREZXBsb3ltZW50UHJvcHM7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgTmV4dGpzU3RhdGljQXNzZXRzUHJvcHMge1xuICAvKipcbiAgICogQnJpbmcgeW91ciBvd24gUzMgYnVja2V0IGZvciBzdGF0aWMgYXNzZXRzLiBXaGVuIHByb3ZpZGVkLCBjZGstbmV4dGpzXG4gICAqIHdpbGwgc2tpcCBjcmVhdGluZyBhIG5ldyBidWNrZXQgYW5kIGRlcGxveSBhc3NldHMgdG8gdGhpcyBidWNrZXQgaW5zdGVhZC5cbiAgICogQ2FuIGJlIHNoYXJlZCBvbmx5IGJldHdlZW4gZGVwbG95bWVudHMgd2l0aCBkaWZmZXJlbnQgYGJhc2VQYXRoYHMgKFMzIGtleVxuICAgKiBwcmVmaXhlcyk6IHBydW5pbmcgaXMgc2NvcGVkIHRvIGA8YmFzZVBhdGg+L19uZXh0L2AsIGJ1dCB0d28gZGVwbG95bWVudHNcbiAgICogdW5kZXIgdGhlIHNhbWUgcHJlZml4IG92ZXJ3cml0ZSBlYWNoIG90aGVyJ3MgYHB1YmxpYy9gIGZpbGVzIGFuZCBwcnVuZSBlYWNoXG4gICAqIG90aGVyJ3Mgb2xkZXIgYF9uZXh0L2AgYXNzZXRzLlxuICAgKi9cbiAgcmVhZG9ubHkgYnVja2V0PzogSUJ1Y2tldDtcbiAgLyoqXG4gICAqIERpcmVjdG9yeSB3aGVyZSB0aGUgTmV4dC5qcyBhcHBsaWNhdGlvbiBpcyBsb2NhdGVkLlxuICAgKiBUaGlzIHNob3VsZCBjb250YWluIHRoZSAubmV4dCBkaXJlY3RvcnkgYW5kIG90aGVyIGJ1aWxkIGFydGlmYWN0cy5cbiAgICovXG4gIHJlYWRvbmx5IGJ1aWxkRGlyZWN0b3J5OiBzdHJpbmc7XG4gIC8qKlxuICAgKiBCdWlsZCBJRCBmcm9tIE5leHRqc0J1aWxkIHRvIHRyYWNrIGFzc2V0IHZlcnNpb25zXG4gICAqL1xuICByZWFkb25seSBidWlsZElkOiBzdHJpbmc7XG4gIC8qKlxuICAgKiBQcmVmaXggdG8gdGhlIFVSSSBwYXRoIHRoZSBhcHAgd2lsbCBiZSBzZXJ2ZWQgYXQuXG4gICAqIEBleGFtcGxlIFwiL215LWJhc2UtcGF0aFwiXG4gICAqL1xuICByZWFkb25seSBiYXNlUGF0aD86IHN0cmluZztcbiAgcmVhZG9ubHkgb3ZlcnJpZGVzPzogTmV4dGpzU3RhdGljQXNzZXRzT3ZlcnJpZGVzO1xufVxuXG4vKipcbiAqIENyZWF0ZXMgUzMgQnVja2V0IGZvciBwdWJsaWMgYW5kIF9uZXh0L3N0YXRpYyBhc3NldHMgYW5kIGRlcGxveXMgdGhlbSB1c2luZyBTM0RlcGxveW1lbnQuXG4gKi9cbmV4cG9ydCBjbGFzcyBOZXh0anNTdGF0aWNBc3NldHMgZXh0ZW5kcyBDb25zdHJ1Y3Qge1xuICBidWNrZXQ6IElCdWNrZXQ7XG4gIGRlcGxveW1lbnQ6IEJ1Y2tldERlcGxveW1lbnQ7XG4gIC8qKlxuICAgKiBTMyBrZXkgcHJlZml4IHRoZSBhc3NldHMgYXJlIGFjdHVhbGx5IHVwbG9hZGVkIHVuZGVyLCBub3JtYWxpemVkIHRvIGEgYmFyZVxuICAgKiBwYXRoIHNlZ21lbnQgKGVtcHR5IHdoZW4gdGhleSBsaXZlIGF0IHRoZSBidWNrZXQgcm9vdCkuXG4gICAqXG4gICAqIENvbnN1bWVycyB0aGF0IHJlYWQgYXNzZXRzIGJhY2sgb3V0IG9mIHRoZSBidWNrZXQgKHRoZSBydW50aW1lJ3MgaW1hZ2VcbiAgICogb3B0aW1pemVyLCBgTmV4dGpzQXBpYCdzIFMzIGludGVncmF0aW9ucykgbXVzdCB1c2UgdGhpcyByYXRoZXIgdGhhbiB0aGVcbiAgICogYGJhc2VQYXRoYCBwcm9wLCBzaW5jZSBgb3ZlcnJpZGVzLmJ1Y2tldERlcGxveW1lbnRQcm9wc2AgY2FuIHJlcGxhY2UgdGhlXG4gICAqIHByZWZpeCBvdXRyaWdodC4gTm9yIGNhbiB0aGV5IGRlcml2ZSBpdCBmcm9tIHRoZSBhcHAncyBvd24gYGJhc2VQYXRoYDogdGhhdFxuICAgKiBpcyB0aGUgcHJlZml4IG9mIHRoZSAqVVJMKiB0aGUgYXBwIGlzIHNlcnZlZCBhdCwgd2hpY2ggZm9yIHRoZSBBUEkgR2F0ZXdheVxuICAgKiBkZXBsb3ltZW50IHR5cGVzIGlzIHRoZSBzdGFnZSBuYW1lIGFuZCBoYXMgbm90aGluZyB0byBkbyB3aXRoIHdoZXJlIHRoZVxuICAgKiBieXRlcyB3ZXJlIHVwbG9hZGVkLlxuICAgKi9cbiAgcmVhZG9ubHkga2V5UHJlZml4OiBzdHJpbmc7XG4gIHByaXZhdGUgc3RhZ2luZ0Rpcj86IHN0cmluZztcblxuICBwcml2YXRlIHByb3BzOiBOZXh0anNTdGF0aWNBc3NldHNQcm9wcztcblxuICBjb25zdHJ1Y3RvcihzY29wZTogQ29uc3RydWN0LCBpZDogc3RyaW5nLCBwcm9wczogTmV4dGpzU3RhdGljQXNzZXRzUHJvcHMpIHtcbiAgICBzdXBlcihzY29wZSwgaWQpO1xuICAgIHRoaXMucHJvcHMgPSBwcm9wcztcbiAgICB0aGlzLmtleVByZWZpeCA9IHRoaXMucmVzb2x2ZUtleVByZWZpeCgpO1xuICAgIHRoaXMuYnVja2V0ID0gcHJvcHMuYnVja2V0ID8/IHRoaXMuY3JlYXRlQnVja2V0KCk7XG4gICAgdGhpcy5kZXBsb3ltZW50ID0gdGhpcy5jcmVhdGVEZXBsb3ltZW50KCk7XG4gIH1cblxuICAvKipcbiAgICogUmVzb2x2ZXMgdGhlIHNpbmdsZSBwcmVmaXggYm90aCB0aGUgdXBsb2FkIGFuZCB0aGUgVVJMcyB1c2UuIEFcbiAgICogYGJ1Y2tldERlcGxveW1lbnRQcm9wcy5kZXN0aW5hdGlvbktleVByZWZpeGAgb3ZlcnJpZGUgd2lucyBvdmVyIGBiYXNlUGF0aGAsXG4gICAqIGJ1dCBpdCdzIG5vcm1hbGl6ZWQgaGVyZSBhbmQgYGNyZWF0ZURlcGxveW1lbnRgIHNldHMgdGhlIG5vcm1hbGl6ZWQgdmFsdWVcbiAgICogYWZ0ZXIgdGhlIG92ZXJyaWRlIHNwcmVhZCwgc28gYGtleVByZWZpeGAgY2FuJ3QgZHJpZnQgZnJvbSB3aGVyZSB0aGUgYXNzZXRzXG4gICAqIGxhbmQuXG4gICAqXG4gICAqIENvbXBhcmVkIGFnYWluc3QgYHVuZGVmaW5lZGAgcmF0aGVyIHRoYW4gdGVzdGVkIHdpdGggYGluYCwgYmVjYXVzZSBhIEpTSUlcbiAgICogbGFuZ3VhZ2UgYmluZGluZyAob3IgYSBwcm9ncmFtbWF0aWNhbGx5IGJ1aWx0IHByb3BzIG9iamVjdCkgY2FuIG1hdGVyaWFsaXplXG4gICAqIGFuIHVuc2V0IG9wdGlvbmFsIGZpZWxkIGFzIGFuIGV4cGxpY2l0IGB1bmRlZmluZWRgLiBUcmVhdGluZyB0aGF0IGFzIGFuXG4gICAqIGludGVudGlvbmFsIFwibW92ZSB0aGUgYXNzZXRzIHRvIHRoZSBidWNrZXQgcm9vdFwiIG92ZXJyaWRlIHdvdWxkIHNpbGVudGx5XG4gICAqIGRyb3AgYGJhc2VQYXRoYCBmcm9tIHRoZSBwcmVmaXguXG4gICAqL1xuICBwcml2YXRlIHJlc29sdmVLZXlQcmVmaXgoKTogc3RyaW5nIHtcbiAgICBjb25zdCBkZXBsb3ltZW50T3ZlcnJpZGVzID0gdGhpcy5wcm9wcy5vdmVycmlkZXM/LmJ1Y2tldERlcGxveW1lbnRQcm9wcztcbiAgICBjb25zdCBwcmVmaXggPVxuICAgICAgZGVwbG95bWVudE92ZXJyaWRlcz8uZGVzdGluYXRpb25LZXlQcmVmaXggIT09IHVuZGVmaW5lZFxuICAgICAgICA/IGRlcGxveW1lbnRPdmVycmlkZXMuZGVzdGluYXRpb25LZXlQcmVmaXhcbiAgICAgICAgOiB0aGlzLnByb3BzLmJhc2VQYXRoO1xuICAgIHJldHVybiBub3JtYWxpemVCYXNlUGF0aChwcmVmaXgpO1xuICB9XG5cbiAgcHJpdmF0ZSBjcmVhdGVCdWNrZXQoKSB7XG4gICAgcmV0dXJuIG5ldyBCdWNrZXQodGhpcywgXCJCdWNrZXRcIiwge1xuICAgICAgcmVtb3ZhbFBvbGljeTogUmVtb3ZhbFBvbGljeS5ERVNUUk9ZLFxuICAgICAgYXV0b0RlbGV0ZU9iamVjdHM6IHRydWUsXG4gICAgICBlbmZvcmNlU1NMOiB0cnVlLFxuICAgICAgYmxvY2tQdWJsaWNBY2Nlc3M6IEJsb2NrUHVibGljQWNjZXNzLkJMT0NLX0FMTCxcbiAgICAgIGVuY3J5cHRpb246IEJ1Y2tldEVuY3J5cHRpb24uUzNfTUFOQUdFRCxcbiAgICAgIG1pbmltdW1UTFNWZXJzaW9uOiAxLjIsXG4gICAgICAuLi50aGlzLnByb3BzLm92ZXJyaWRlcz8uYnVja2V0UHJvcHMsXG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGNyZWF0ZURlcGxveW1lbnQoKSB7XG4gICAgLy8gQ3JlYXRlIGEgc3RhZ2luZyBkaXJlY3Rvcnkgd2l0aCB0aGUgY29ycmVjdCBzdHJ1Y3R1cmVcbiAgICB0aGlzLnN0YWdpbmdEaXIgPSB0aGlzLmNyZWF0ZVN0YWdpbmdEaXJlY3RvcnkoKTtcblxuICAgIGlmICghdGhpcy5zdGFnaW5nRGlyKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgIGBObyBzdGF0aWMgYXNzZXRzIGZvdW5kIHRvIGRlcGxveS4gRW5zdXJlIHlvdXIgTmV4dC5qcyBidWlsZCBvdXRwdXQgY29udGFpbnMgZWl0aGVyOlxuICAgICAgICAtIEEgJ3B1YmxpYycgZGlyZWN0b3J5IGF0OiAke2pvaW4odGhpcy5wcm9wcy5idWlsZERpcmVjdG9yeSwgXCJwdWJsaWNcIil9XG4gICAgICAgIC0gQSAnLm5leHQvc3RhdGljJyBkaXJlY3RvcnkgYXQ6ICR7am9pbih0aGlzLnByb3BzLmJ1aWxkRGlyZWN0b3J5LCBcIi5uZXh0XCIsIFwic3RhdGljXCIpfWAsXG4gICAgICApO1xuICAgIH1cblxuICAgIHJldHVybiBuZXcgQnVja2V0RGVwbG95bWVudCh0aGlzLCBcIkRlcGxveW1lbnRcIiwge1xuICAgICAgc291cmNlczogW1NvdXJjZS5hc3NldCh0aGlzLnN0YWdpbmdEaXIpXSxcbiAgICAgIGRlc3RpbmF0aW9uQnVja2V0OiB0aGlzLmJ1Y2tldCxcbiAgICAgIC8vIEFkZCBCVUlMRF9JRCBhcyBtZXRhZGF0YSB0byBhbGwgb2JqZWN0cyBmb3IgdmVyc2lvbiB0cmFja2luZ1xuICAgICAgbWV0YWRhdGE6IHtcbiAgICAgICAgQlVJTERfSUQ6IHRoaXMucHJvcHMuYnVpbGRJZCxcbiAgICAgIH0sXG4gICAgICBwcnVuZTogZmFsc2UsIC8vIERvbid0IGRlbGV0ZSBleGlzdGluZyBhc3NldHMgdG8gcHJldmVudCA0MDRzIGR1cmluZyBkZXBsb3ltZW50LCBwcnVuaW5nIHdpbGwgYmUgaGFuZGxlZCBieSBwb3N0LWRlcGxveVxuICAgICAgLy8gUzNEZXBsb3ltZW50IGF1dG9tYXRpY2FsbHkgZGV0ZWN0cyBjb250ZW50IHR5cGVzIGJhc2VkIG9uIGZpbGUgZXh0ZW5zaW9uc1xuICAgICAgLi4udGhpcy5wcm9wcy5vdmVycmlkZXM/LmJ1Y2tldERlcGxveW1lbnRQcm9wcyxcbiAgICAgIC8vIFNldCBhZnRlciB0aGUgc3ByZWFkOiBgcmVzb2x2ZUtleVByZWZpeGAgYWxyZWFkeSBmb2xkZWQgaW4gYW55XG4gICAgICAvLyBgZGVzdGluYXRpb25LZXlQcmVmaXhgIG92ZXJyaWRlLCBzbyB0aGlzIGlzIHRoZSBub3JtYWxpemVkIGZvcm0gb2YgaXQuXG4gICAgICAvLyBMZXR0aW5nIHRoZSByYXcgb3ZlcnJpZGUgdGhyb3VnaCBoZXJlIHdvdWxkIHVwbG9hZCB0aGUgYXNzZXRzIHNvbWV3aGVyZVxuICAgICAgLy8gb3RoZXIgdGhhbiB0aGUgYGtleVByZWZpeGAgdXNlZCB0byBidWlsZCB0aGVpciBVUkxzLlxuICAgICAgZGVzdGluYXRpb25LZXlQcmVmaXg6IHRoaXMua2V5UHJlZml4IHx8IHVuZGVmaW5lZCxcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGUgYSBzdGFnaW5nIGRpcmVjdG9yeSB3aXRoIHRoZSBjb3JyZWN0IHN0cnVjdHVyZTpcbiAgICogLSBwdWJsaWMvIGZpbGVzIGdvIHRvIHJvb3RcbiAgICogLSAubmV4dC9zdGF0aWMvIGZpbGVzIGdvIHRvIF9uZXh0L3N0YXRpYy9cbiAgICovXG4gIHByaXZhdGUgY3JlYXRlU3RhZ2luZ0RpcmVjdG9yeSgpOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICAgIGNvbnN0IHN0YWdpbmdEaXIgPSBta2R0ZW1wU3luYyhqb2luKHRtcGRpcigpLCBcIm5leHRqcy1hc3NldHMtXCIpKTtcbiAgICBsZXQgaGFzQXNzZXRzID0gZmFsc2U7XG5cbiAgICB0cnkge1xuICAgICAgLy8gQ29weSBwdWJsaWMgZGlyZWN0b3J5IGNvbnRlbnRzIHRvIHN0YWdpbmcgcm9vdFxuICAgICAgY29uc3QgcHVibGljUGF0aCA9IGpvaW4odGhpcy5wcm9wcy5idWlsZERpcmVjdG9yeSwgXCJwdWJsaWNcIik7XG4gICAgICBpZiAodGhpcy5kaXJlY3RvcnlFeGlzdHMocHVibGljUGF0aCkpIHtcbiAgICAgICAgY3BTeW5jKHB1YmxpY1BhdGgsIHN0YWdpbmdEaXIsIHsgcmVjdXJzaXZlOiB0cnVlIH0pO1xuICAgICAgICBoYXNBc3NldHMgPSB0cnVlO1xuICAgICAgfVxuXG4gICAgICAvLyBDb3B5IC5uZXh0L3N0YXRpYyB0byBzdGFnaW5nL19uZXh0L3N0YXRpY1xuICAgICAgY29uc3Qgc3RhdGljUGF0aCA9IGpvaW4odGhpcy5wcm9wcy5idWlsZERpcmVjdG9yeSwgXCIubmV4dFwiLCBcInN0YXRpY1wiKTtcbiAgICAgIGlmICh0aGlzLmRpcmVjdG9yeUV4aXN0cyhzdGF0aWNQYXRoKSkge1xuICAgICAgICBjb25zdCBuZXh0RGlyID0gam9pbihzdGFnaW5nRGlyLCBcIl9uZXh0XCIpO1xuICAgICAgICBjb25zdCBzdGF0aWNEZXN0RGlyID0gam9pbihuZXh0RGlyLCBcInN0YXRpY1wiKTtcblxuICAgICAgICAvLyBDcmVhdGUgX25leHQgZGlyZWN0b3J5XG4gICAgICAgIG1rZGlyU3luYyhuZXh0RGlyLCB7IHJlY3Vyc2l2ZTogdHJ1ZSB9KTtcblxuICAgICAgICAvLyBDb3B5IHN0YXRpYyBhc3NldHNcbiAgICAgICAgY3BTeW5jKHN0YXRpY1BhdGgsIHN0YXRpY0Rlc3REaXIsIHsgcmVjdXJzaXZlOiB0cnVlIH0pO1xuICAgICAgICBoYXNBc3NldHMgPSB0cnVlO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gaGFzQXNzZXRzID8gc3RhZ2luZ0RpciA6IHVuZGVmaW5lZDtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgY29uc29sZS5lcnJvcihgJHtMT0dfUFJFRklYfSBFcnJvciBjcmVhdGluZyBzdGFnaW5nIGRpcmVjdG9yeTpgLCBlcnJvcik7XG4gICAgICAvLyBDbGVhbiB1cCBvbiBlcnJvclxuICAgICAgdHJ5IHtcbiAgICAgICAgcm1TeW5jKHN0YWdpbmdEaXIsIHsgcmVjdXJzaXZlOiB0cnVlLCBmb3JjZTogdHJ1ZSB9KTtcbiAgICAgIH0gY2F0Y2gge1xuICAgICAgICAvLyBJZ25vcmUgY2xlYW51cCBlcnJvcnNcbiAgICAgIH1cbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIENoZWNrIGlmIGEgZGlyZWN0b3J5IGV4aXN0c1xuICAgKi9cbiAgcHJpdmF0ZSBkaXJlY3RvcnlFeGlzdHMoZGlyUGF0aDogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgdHJ5IHtcbiAgICAgIHJldHVybiBleGlzdHNTeW5jKGRpclBhdGgpICYmIHN0YXRTeW5jKGRpclBhdGgpLmlzRGlyZWN0b3J5KCk7XG4gICAgfSBjYXRjaCB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG59XG4iXX0=
401
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmV4dGpzLXN0YXRpYy1hc3NldHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvbmV4dGpzLXN0YXRpYy1hc3NldHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBcUNBLGdFQU1DOztBQTNDRCxxQ0FTaUI7QUFDakIscUNBQWlDO0FBQ2pDLHlDQUFnRDtBQUNoRCw2Q0FBNkQ7QUFDN0QsK0NBTTRCO0FBQzVCLHFFQUt1QztBQUN2QywwREFBNEM7QUFDNUMsMkNBQXVDO0FBQ3ZDLDJDQUF5QztBQUN6QyxpREFBc0Q7QUFFdEQ7Ozs7O0dBS0c7QUFDSCxTQUFnQiwwQkFBMEIsQ0FBQyxTQUFrQjtJQUMzRCxJQUFJLFNBQVMsSUFBSSxtQkFBSyxDQUFDLFlBQVksQ0FBQyxTQUFTLENBQUMsRUFBRSxDQUFDO1FBQy9DLE9BQU8sR0FBRyxDQUFDO0lBQ2IsQ0FBQztJQUNELE1BQU0sTUFBTSxHQUFHLElBQUEsNkJBQWlCLEVBQUMsU0FBUyxDQUFDLENBQUM7SUFDNUMsT0FBTyxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsTUFBTSxJQUFJLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQztBQUN0QyxDQUFDO0FBRUQsb0VBQW9FO0FBQ3BFLE1BQU0sV0FBVyxHQUFHLElBQUEsZ0JBQUksRUFBQyxPQUFPLEVBQUUsUUFBUSxDQUFDLENBQUM7QUFDNUMsNkVBQTZFO0FBQzdFLE1BQU0sa0JBQWtCLEdBQUcsZ0JBQWdCLENBQUM7QUFFNUM7Ozs7Ozs7Ozs7R0FVRztBQUNILFNBQVMsU0FBUyxDQUFDLEdBQVc7SUFDNUIsTUFBTSxLQUFLLEdBQWEsRUFBRSxDQUFDO0lBQzNCLE1BQU0sSUFBSSxHQUFHLENBQUMsR0FBVyxFQUFFLFNBQThCLEVBQUUsRUFBRTtRQUMzRCxNQUFNLElBQUksR0FBRyxJQUFBLHNCQUFZLEVBQUMsSUFBQSxnQkFBSSxFQUFDLEdBQUcsRUFBRSxHQUFHLENB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QyxPQUFlO1FBQ3JDLElBQUksQ0FBQztZQUNILE9BQU8sSUFBQSxvQkFBVSxFQUFDLE9BQU8sQ0FBQyxJQUFJLElBQUEsa0JBQVEsRUFBQyxPQUFPLENBQUMsQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUNoRSxDQUFDO1FBQUMsTUFBTSxDQUFDO1lBQ1AsT0FBTyxLQUFLLENBQUM7UUFDZixDQUFDO0lBQ0gsQ0FBQzs7QUFqVUgsZ0RBa1VDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgY3BTeW5jLFxuICBleGlzdHNTeW5jLFxuICBta2RpclN5bmMsXG4gIG1rZHRlbXBTeW5jLFxuICByZWFkZGlyU3luYyxcbiAgcmVhbHBhdGhTeW5jLFxuICBybVN5bmMsXG4gIHN0YXRTeW5jLFxufSBmcm9tIFwibm9kZTpmc1wiO1xuaW1wb3J0IHsgdG1wZGlyIH0gZnJvbSBcIm5vZGU6b3NcIjtcbmltcG9ydCB7IGpvaW4sIHJlbGF0aXZlLCBzZXAgfSBmcm9tIFwibm9kZTpwYXRoXCI7XG5pbXBvcnQgeyBEdXJhdGlvbiwgUmVtb3ZhbFBvbGljeSwgVG9rZW4gfSBmcm9tIFwiYXdzLWNkay1saWJcIjtcbmltcG9ydCB7XG4gIEJsb2NrUHVibGljQWNjZXNzLFxuICBCdWNrZXQsXG4gIEJ1Y2tldEVuY3J5cHRpb24sXG4gIEJ1Y2tldFByb3BzLFxuICBJQnVja2V0LFxufSBmcm9tIFwiYXdzLWNkay1saWIvYXdzLXMzXCI7XG5pbXBvcnQge1xuICBCdWNrZXREZXBsb3ltZW50LFxuICBCdWNrZXREZXBsb3ltZW50UHJvcHMsXG4gIENhY2hlQ29udHJvbCxcbiAgU291cmNlLFxufSBmcm9tIFwiYXdzLWNkay1saWIvYXdzLXMzLWRlcGxveW1lbnRcIjtcbmltcG9ydCAqIGFzIGN4YXBpIGZyb20gXCJhd3MtY2RrLWxpYi9jeC1hcGlcIjtcbmltcG9ydCB7IENvbnN0cnVjdCB9IGZyb20gXCJjb25zdHJ1Y3RzXCI7XG5pbXBvcnQgeyBMT0dfUFJFRklYIH0gZnJvbSBcIi4vY29uc3RhbnRzXCI7XG5pbXBvcnQgeyBub3JtYWxpemVCYXNlUGF0aCB9IGZyb20gXCIuL3V0aWxzL2Jhc2UtcGF0aFwiO1xuXG4vKipcbiAqIFRoZSBTMyBvYmplY3Qga2V5IHBhdHRlcm4gY292ZXJpbmcgZXZlcnkgc3RhdGljIGFzc2V0IHVwbG9hZGVkIHVuZGVyXG4gKiBga2V5UHJlZml4YCAoYE5leHRqc1N0YXRpY0Fzc2V0cy5rZXlQcmVmaXhgKTogYFwiYmFzZS8qXCJgLCBvciBgXCIqXCJgIGF0IHRoZVxuICogYnVja2V0IHJvb3QuIEZvciBzY29waW5nIHRoZSBjb21wdXRlJ3MgcmVhZCBncmFudCB0byB0aGUgYXBwJ3Mgb3duIG9iamVjdHNcbiAqIHdoZW4gc2V2ZXJhbCBhcHBzIHNoYXJlIG9uZSBidWNrZXQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzdGF0aWNBc3NldHNPYmplY3RzUGF0dGVybihrZXlQcmVmaXg/OiBzdHJpbmcpOiBzdHJpbmcge1xuICBpZiAoa2V5UHJlZml4ICYmIFRva2VuLmlzVW5yZXNvbHZlZChrZXlQcmVmaXgpKSB7XG4gICAgcmV0dXJuIFwiKlwiO1xuICB9XG4gIGNvbnN0IHByZWZpeCA9IG5vcm1hbGl6ZUJhc2VQYXRoKGtleVByZWZpeCk7XG4gIHJldHVybiBwcmVmaXggPyBgJHtwcmVmaXh9LypgIDogXCIqXCI7XG59XG5cbi8qKiBXaGVyZSBgLm5leHQvc3RhdGljYCBpcyBzZXJ2ZWQgZnJvbSwgcmVsYXRpdmUgdG8gYGtleVByZWZpeGAuICovXG5jb25zdCBTVEFUSUNfUEFUSCA9IGpvaW4oXCJfbmV4dFwiLCBcInN0YXRpY1wiKTtcbi8qKiBXaGVyZSBOZXh0LmpzIGNvbXBpbGVzIHNlcnZpY2Ugd29ya2VycyB0bywgcmVsYXRpdmUgdG8gYC5uZXh0L3N0YXRpY2AuICovXG5jb25zdCBTRVJWSUNFX1dPUktFUl9ESVIgPSBcInNlcnZpY2Utd29ya2VyXCI7XG5cbi8qKlxuICogRXZlcnkgZmlsZSB1bmRlciBgZGlyYCwgcmVsYXRpdmUgdG8gaXQsIHRocm91Z2ggc3ltbGlua3MgdG9vOiBDREsgdXBsb2FkcyBhXG4gKiBsaW5rZWQgZmlsZSBvciBkaXJlY3RvcnkgYXMgd2hhdCBpdCBwb2ludHMgdG8sIHVuZGVyIGV2ZXJ5IG5hbWUgaXQncyByZWFjaGVkXG4gKiBieS5cbiAqXG4gKiBBbiBleHBsaWNpdCB3YWxrIHJhdGhlciB0aGFuIGByZWFkZGlyU3luYyh7IHJlY3Vyc2l2ZTogdHJ1ZSB9KWAsIHdoaWNoIG5ldmVyXG4gKiByZXR1cm5zIG9uIGEgc3ltbGluayBjeWNsZSAoTm9kZSAyNCBmb2xsb3dzIGRpcmVjdG9yeSBsaW5rcyksIGFuZCB3aG9zZVxuICogYERpcmVudC5wYXJlbnRQYXRoYCBkb2Vzbid0IGV4aXN0IGJlZm9yZSBOb2RlIDIwLjEyLiBBIGxpbmsgYmFjayB0byBhXG4gKiBkaXJlY3RvcnkgYWxyZWFkeSBvbiB0aGUgY3VycmVudCBwYXRoIGlzIGEgY3ljbGUgYW5kIGlzbid0IGZvbGxvd2VkOyBvbmUgdGhhdFxuICogY2FuJ3QgYmUgc3RhdCdkIChkYW5nbGluZywgb3IgYSBsb29wIG9mIGxpbmtzKSBjb3VudHMgYXMgYSBmaWxlLlxuICovXG5mdW5jdGlvbiBsaXN0RmlsZXMoZGlyOiBzdHJpbmcpOiBzdHJpbmdbXSB7XG4gIGNvbnN0IGZpbGVzOiBzdHJpbmdbXSA9IFtdO1xuICBjb25zdCB3YWxrID0gKHN1Yjogc3RyaW5nLCBhbmNlc3RvcnM6IFJlYWRvbmx5U2V0PHN0cmluZz4pID0+IHtcbiAgICBjb25zdCByZWFsID0gcmVhbHBhdGhTeW5jKGpvaW4oZGlyLCBzdWIpKTtcbiAgICBpZiAoYW5jZXN0b3JzLmhhcyhyZWFsKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBwYXRoID0gbmV3IFNldChhbmNlc3RvcnMpLmFkZChyZWFsKTtcbiAgICBmb3IgKGNvbnN0IGVudHJ5IG9mIHJlYWRkaXJTeW5jKHJlYWwsIHsgd2l0aEZpbGVUeXBlczogdHJ1ZSB9KSkge1xuICAgICAgY29uc3QgY2hpbGQgPSBqb2luKHN1YiwgZW50cnkubmFtZSk7XG4gICAgICBpZiAoXG4gICAgICAgIGVudHJ5LmlzRGlyZWN0b3J5KCkgfHxcbiAgICAgICAgKGVudHJ5LmlzU3ltYm9saWNMaW5rKCkgJiYgaXNEaXJlY3RvcnlMaW5rKGpvaW4ocmVhbCwgZW50cnkubmFtZSkpKVxuICAgICAgKSB7XG4gICAgICAgIHdhbGsoY2hpbGQsIHBhdGgpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZmlsZXMucHVzaChjaGlsZCk7XG4gICAgICB9XG4gICAgfVxuICB9O1xuICB3YWxrKFwiXCIsIG5ldyBTZXQoKSk7XG4gIHJldHVybiBmaWxlcztcbn1cblxuZnVuY3Rpb24gaXNEaXJlY3RvcnlMaW5rKHBhdGg6IHN0cmluZyk6IGJvb2xlYW4ge1xuICB0cnkge1xuICAgIHJldHVybiBzdGF0U3luYyhwYXRoKS5pc0RpcmVjdG9yeSgpO1xuICB9IGNhdGNoIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbn1cblxuLyoqIFdoZXRoZXIgdGhlIHJlbGF0aXZlIGBwYXRoYCBpcyBgZGlyYCBvciBpbnNpZGUgaXQuICovXG5mdW5jdGlvbiBpc1dpdGhpbihwYXRoOiBzdHJpbmcsIGRpcjogc3RyaW5nKTogYm9vbGVhbiB7XG4gIHJldHVybiBwYXRoID09PSBkaXIgfHwgcGF0aC5zdGFydHNXaXRoKGRpciArIHNlcCk7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgTmV4dGpzU3RhdGljQXNzZXRzT3ZlcnJpZGVzIHtcbiAgcmVhZG9ubHkgYnVja2V0UHJvcHM/OiBCdWNrZXRQcm9wcztcbiAgLyoqXG4gICAqIEFwcGxpZWQgdG8gZXZlcnkgdXBsb2FkIChgcHVibGljL2AsIGBfbmV4dC9zdGF0aWMvYCBhbmRcbiAgICogYF9uZXh0L3N0YXRpYy9zZXJ2aWNlLXdvcmtlci9gKSwgZXhjZXB0IHRoYXQgdGhlIHR3byBgX25leHQvc3RhdGljYCB1cGxvYWRzXG4gICAqIGFsd2F5cyBrZWVwIHRoZSBgQ2FjaGUtQ29udHJvbGAgTmV4dC5qcyBzZW5kcyBmb3IgdGhlbS4gU28gYSBgY2FjaGVDb250cm9sYFxuICAgKiBoZXJlIHNldHMgdGhlIGhlYWRlciBmb3IgYHB1YmxpYy9gIGZpbGVzIG9ubHksIHdoaWxlIGFueXRoaW5nIGVsc2UsIHN1Y2ggYXNcbiAgICogYSBgZGlzdHJpYnV0aW9uYCB0byBpbnZhbGlkYXRlLCBhcHBsaWVzIHRvIGVhY2ggdXBsb2FkIGluIHR1cm4uXG4gICAqXG4gICAqIGBzb3VyY2VzYCBhbmQgYGRlc3RpbmF0aW9uQnVja2V0YCwgd2hpY2ggdGhlIHR5cGUgcmVxdWlyZXMsIGFyZSBpZ25vcmVkOlxuICAgKiB0aGUgdXBsb2FkcyBhcmUgYWx3YXlzIHRoZSBidWlsZCdzIGFzc2V0cywgdG8gdGhlIGJ1Y2tldCBDbG91ZEZyb250IGFuZFxuICAgKiBBUEkgR2F0ZXdheSByZWFkIGZyb20gKHBhc3MgYGJ1Y2tldGAgdG8gYnJpbmcgeW91ciBvd24pLiBgcHJ1bmU6IHRydWVgIGFuZFxuICAgKiBgcmV0YWluT25EZWxldGU6IGZhbHNlYCBhcmUgcmVqZWN0ZWQsIHNpbmNlIGVhY2ggd291bGQgYnJlYWsgdGhlIG90aGVyXG4gICAqIHVwbG9hZHMuXG4gICAqL1xuICByZWFkb25seSBidWNrZXREZXBsb3ltZW50UHJvcHM/OiBCdWNrZXREZXBsb3ltZW50UHJvcHM7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgTmV4dGpzU3RhdGljQXNzZXRzUHJvcHMge1xuICAvKipcbiAgICogQnJpbmcgeW91ciBvd24gUzMgYnVja2V0IGZvciBzdGF0aWMgYXNzZXRzLiBXaGVuIHByb3ZpZGVkLCBjZGstbmV4dGpzXG4gICAqIHdpbGwgc2tpcCBjcmVhdGluZyBhIG5ldyBidWNrZXQgYW5kIGRlcGxveSBhc3NldHMgdG8gdGhpcyBidWNrZXQgaW5zdGVhZC5cbiAgICogQ2FuIGJlIHNoYXJlZCBvbmx5IGJldHdlZW4gZGVwbG95bWVudHMgd2l0aCBkaWZmZXJlbnQgYGJhc2VQYXRoYHMgKFMzIGtleVxuICAgKiBwcmVmaXhlcyk6IHBydW5pbmcgaXMgc2NvcGVkIHRvIGA8YmFzZVBhdGg+L19uZXh0L2AsIGJ1dCB0d28gZGVwbG95bWVudHNcbiAgICogdW5kZXIgdGhlIHNhbWUgcHJlZml4IG92ZXJ3cml0ZSBlYWNoIG90aGVyJ3MgYHB1YmxpYy9gIGZpbGVzIGFuZCBwcnVuZSBlYWNoXG4gICAqIG90aGVyJ3Mgb2xkZXIgYF9uZXh0L2AgYXNzZXRzLlxuICAgKi9cbiAgcmVhZG9ubHkgYnVja2V0PzogSUJ1Y2tldDtcbiAgLyoqXG4gICAqIERpcmVjdG9yeSB3aGVyZSB0aGUgTmV4dC5qcyBhcHBsaWNhdGlvbiBpcyBsb2NhdGVkLlxuICAgKiBUaGlzIHNob3VsZCBjb250YWluIHRoZSAubmV4dCBkaXJlY3RvcnkgYW5kIG90aGVyIGJ1aWxkIGFydGlmYWN0cy5cbiAgICovXG4gIHJlYWRvbmx5IGJ1aWxkRGlyZWN0b3J5OiBzdHJpbmc7XG4gIC8qKlxuICAgKiBCdWlsZCBJRCBmcm9tIE5leHRqc0J1aWxkIHRvIHRyYWNrIGFzc2V0IHZlcnNpb25zXG4gICAqL1xuICByZWFkb25seSBidWlsZElkOiBzdHJpbmc7XG4gIC8qKlxuICAgKiBQcmVmaXggdG8gdGhlIFVSSSBwYXRoIHRoZSBhcHAgd2lsbCBiZSBzZXJ2ZWQgYXQuXG4gICAqIEBleGFtcGxlIFwiL215LWJhc2UtcGF0aFwiXG4gICAqL1xuICByZWFkb25seSBiYXNlUGF0aD86IHN0cmluZztcbiAgcmVhZG9ubHkgb3ZlcnJpZGVzPzogTmV4dGpzU3RhdGljQXNzZXRzT3ZlcnJpZGVzO1xufVxuXG4vKipcbiAqIENyZWF0ZXMgUzMgQnVja2V0IGZvciBwdWJsaWMgYW5kIF9uZXh0L3N0YXRpYyBhc3NldHMgYW5kIGRlcGxveXMgdGhlbSB1c2luZyBTM0RlcGxveW1lbnQuXG4gKi9cbmV4cG9ydCBjbGFzcyBOZXh0anNTdGF0aWNBc3NldHMgZXh0ZW5kcyBDb25zdHJ1Y3Qge1xuICBidWNrZXQ6IElCdWNrZXQ7XG4gIC8qKlxuICAgKiBUaGUgZmlyc3Qgb2YgYHN0YXRpY0RlcGxveW1lbnRgLCBgc2VydmljZVdvcmtlckRlcGxveW1lbnRgIGFuZFxuICAgKiBgcHVibGljRGVwbG95bWVudGAgdGhlIGJ1aWxkIGhhcyBmaWxlcyBmb3IuXG4gICAqXG4gICAqIEBkZXByZWNhdGVkIFRoZSBhc3NldHMgYXJlIHVwbG9hZGVkIGJ5IHVwIHRvIHRocmVlIGRlcGxveW1lbnRzLCBhbmQgdGhpc1xuICAgKiBpcyBvbmx5IG9uZSBvZiB0aGVtOiBhIGRlcGVuZGVuY3kgb24gaXQgZG9lc24ndCB3YWl0IGZvciB0aGUgb3RoZXJzLiBVc2VcbiAgICogYHN0YXRpY0RlcGxveW1lbnRgLCBgc2VydmljZVdvcmtlckRlcGxveW1lbnRgIGFuZCBgcHVibGljRGVwbG95bWVudGAuXG4gICAqL1xuICBkZXBsb3ltZW50OiBCdWNrZXREZXBsb3ltZW50O1xuICAvKipcbiAgICogVXBsb2FkcyBgLm5leHQvc3RhdGljYCB0byBgX25leHQvc3RhdGljL2Agd2l0aFxuICAgKiBgQ2FjaGUtQ29udHJvbDogcHVibGljLCBtYXgtYWdlPTMxNTM2MDAwLCBpbW11dGFibGVgLCBleGNlcHQgZm9yXG4gICAqIGBzZXJ2aWNlLXdvcmtlci9gIChzZWUgYHNlcnZpY2VXb3JrZXJEZXBsb3ltZW50YCkuIEFic2VudCBpZiB0aGUgYnVpbGQgaGFzXG4gICAqIG5vIGAubmV4dC9zdGF0aWNgLlxuICAgKi9cbiAgcmVhZG9ubHkgc3RhdGljRGVwbG95bWVudD86IEJ1Y2tldERlcGxveW1lbnQ7XG4gIC8qKlxuICAgKiBVcGxvYWRzIGAubmV4dC9zdGF0aWMvc2VydmljZS13b3JrZXJgIHdpdGhcbiAgICogYENhY2hlLUNvbnRyb2w6IHB1YmxpYywgbWF4LWFnZT0wLCBtdXN0LXJldmFsaWRhdGVgLCBhcyBOZXh0LmpzIHNlcnZlcyBpdDpcbiAgICogYSBzZXJ2aWNlIHdvcmtlciBrZWVwcyBpdHMgVVJMIGFjcm9zcyBidWlsZHMsIHNvIGl0IGNhbid0IGJlIGBpbW11dGFibGVgLlxuICAgKiBBYnNlbnQgaWYgdGhlIGJ1aWxkIGhhcyBubyBzZXJ2aWNlIHdvcmtlci5cbiAgICovXG4gIHJlYWRvbmx5IHNlcnZpY2VXb3JrZXJEZXBsb3ltZW50PzogQnVja2V0RGVwbG95bWVudDtcbiAgLyoqXG4gICAqIFVwbG9hZHMgYHB1YmxpYy9gLCBzZXBhcmF0ZWx5IGZyb20gYHN0YXRpY0RlcGxveW1lbnRgIGJlY2F1c2UgaXRzIGZpbGVzXG4gICAqIGtlZXAgdGhlaXIgbmFtZXMgd2hlbiB0aGV5IGNoYW5nZSBhbmQgc28gY2FuJ3QgYmUgYGltbXV0YWJsZWAuIEFic2VudCBpZlxuICAgKiB0aGUgYnVpbGQgaGFzIG5vIGBwdWJsaWNgIGRpcmVjdG9yeS5cbiAgICovXG4gIHJlYWRvbmx5IHB1YmxpY0RlcGxveW1lbnQ/OiBCdWNrZXREZXBsb3ltZW50O1xuICAvKipcbiAgICogUzMga2V5IHByZWZpeCB0aGUgYXNzZXRzIGFyZSBhY3R1YWxseSB1cGxvYWRlZCB1bmRlciwgbm9ybWFsaXplZCB0byBhIGJhcmVcbiAgICogcGF0aCBzZWdtZW50IChlbXB0eSB3aGVuIHRoZXkgbGl2ZSBhdCB0aGUgYnVja2V0IHJvb3QpLlxuICAgKlxuICAgKiBDb25zdW1lcnMgdGhhdCByZWFkIGFzc2V0cyBiYWNrIG91dCBvZiB0aGUgYnVja2V0ICh0aGUgcnVudGltZSdzIGltYWdlXG4gICAqIG9wdGltaXplciwgYE5leHRqc0FwaWAncyBTMyBpbnRlZ3JhdGlvbnMpIG11c3QgdXNlIHRoaXMgcmF0aGVyIHRoYW4gdGhlXG4gICAqIGBiYXNlUGF0aGAgcHJvcCwgc2luY2UgYG92ZXJyaWRlcy5idWNrZXREZXBsb3ltZW50UHJvcHNgIGNhbiByZXBsYWNlIHRoZVxuICAgKiBwcmVmaXggb3V0cmlnaHQuIE5vciBjYW4gdGhleSBkZXJpdmUgaXQgZnJvbSB0aGUgYXBwJ3Mgb3duIGBiYXNlUGF0aGA6IHRoYXRcbiAgICogaXMgdGhlIHByZWZpeCBvZiB0aGUgKlVSTCogdGhlIGFwcCBpcyBzZXJ2ZWQgYXQsIHdoaWNoIGZvciB0aGUgQVBJIEdhdGV3YXlcbiAgICogZGVwbG95bWVudCB0eXBlcyBpcyB0aGUgc3RhZ2UgbmFtZSBhbmQgaGFzIG5vdGhpbmcgdG8gZG8gd2l0aCB3aGVyZSB0aGVcbiAgICogYnl0ZXMgd2VyZSB1cGxvYWRlZC5cbiAgICovXG4gIHJlYWRvbmx5IGtleVByZWZpeDogc3RyaW5nO1xuXG4gIHByaXZhdGUgcHJvcHM6IE5leHRqc1N0YXRpY0Fzc2V0c1Byb3BzO1xuXG4gIGNvbnN0cnVjdG9yKHNjb3BlOiBDb25zdHJ1Y3QsIGlkOiBzdHJpbmcsIHByb3BzOiBOZXh0anNTdGF0aWNBc3NldHNQcm9wcykge1xuICAgIHN1cGVyKHNjb3BlLCBpZCk7XG4gICAgdGhpcy5wcm9wcyA9IHByb3BzO1xuICAgIHRoaXMudmFsaWRhdGVEZXBsb3ltZW50T3ZlcnJpZGVzKCk7XG4gICAgdGhpcy5rZXlQcmVmaXggPSB0aGlzLnJlc29sdmVLZXlQcmVmaXgoKTtcbiAgICB0aGlzLmJ1Y2tldCA9IHByb3BzLmJ1Y2tldCA/PyB0aGlzLmNyZWF0ZUJ1Y2tldCgpO1xuICAgIGNvbnN0IHN0YWdlZDogc3RyaW5nW10gPSBbXTtcbiAgICB0cnkge1xuICAgICAgY29uc3QgdXBsb2FkcyA9IHRoaXMuY3JlYXRlRGVwbG95bWVudHMoc3RhZ2VkKTtcbiAgICAgIHRoaXMuc3RhdGljRGVwbG95bWVudCA9IHVwbG9hZHMuc3RhdGljRGVwbG95bWVudDtcbiAgICAgIHRoaXMuc2VydmljZVdvcmtlckRlcGxveW1lbnQgPSB1cGxvYWRzLnNlcnZpY2VXb3JrZXJEZXBsb3ltZW50O1xuICAgICAgdGhpcy5wdWJsaWNEZXBsb3ltZW50ID0gdXBsb2Fkcy5wdWJsaWNEZXBsb3ltZW50O1xuICAgIH0gZmluYWxseSB7XG4gICAgICAvLyBgU291cmNlLmFzc2V0YCBzdGFnZXMgZHVyaW5nIGBCdWNrZXREZXBsb3ltZW50YCdzIGNvbnN0cnVjdGlvbiAoQ0RLJ3NcbiAgICAgIC8vIGBBc3NldFN0YWdpbmdgIGNvcGllcyBpbnRvIGBjZGsub3V0YCBmcm9tIGl0cyBvd24gY29uc3RydWN0b3IpLCBzbyB0aGVcbiAgICAgIC8vIHRlbXBvcmFyeSBjb3BpZXMgYXJlIGRlYWQgb25jZSB0aGUgZGVwbG95bWVudHMgZXhpc3QsIG9yIG9uY2Ugb25lIG9mXG4gICAgICAvLyB0aGVtIGZhaWxlZC4gTGVmdCBiZWhpbmQsIGV2ZXJ5IHN5bnRoIHdvdWxkIGFkZCBhbm90aGVyIGZ1bGwgY29weSBvZlxuICAgICAgLy8gdGhlIGFwcCdzIHN0YXRpYyBhc3NldHMgdG8gdGhlIHRlbXAgZGlyZWN0b3J5LlxuICAgICAgLy9cbiAgICAgIC8vIFVubGVzcyBzdGFnaW5nIGlzIGRpc2FibGVkIChgY2RrIHN5bnRoIC0tbm8tc3RhZ2luZ2AsIGFuZCBTQU0sIHdoaWNoXG4gICAgICAvLyBzZXRzIHRoZSBzYW1lIGNvbnRleHQpOiB0aGVuIHRoZSBhc3NldCBtYW5pZmVzdCBwb2ludHMgYXQgdGhlc2VcbiAgICAgIC8vIGRpcmVjdG9yaWVzIHRoZW1zZWx2ZXMsIGFuZCByZW1vdmluZyB0aGVtIHdvdWxkIGZhaWwgdGhlIHB1Ymxpc2ggdGhhdFxuICAgICAgLy8gZm9sbG93cy5cbiAgICAgIGlmICghdGhpcy5ub2RlLnRyeUdldENvbnRleHQoY3hhcGkuRElTQUJMRV9BU1NFVF9TVEFHSU5HX0NPTlRFWFQpKSB7XG4gICAgICAgIGZvciAoY29uc3QgZGlyIG9mIHN0YWdlZCkge1xuICAgICAgICAgIHJtU3luYyhkaXIsIHsgcmVjdXJzaXZlOiB0cnVlLCBmb3JjZTogdHJ1ZSB9KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICB0aGlzLmRlcGxveW1lbnQgPSAodGhpcy5zdGF0aWNEZXBsb3ltZW50ID8/XG4gICAgICB0aGlzLnNlcnZpY2VXb3JrZXJEZXBsb3ltZW50ID8/XG4gICAgICB0aGlzLnB1YmxpY0RlcGxveW1lbnQpITtcbiAgfVxuXG4gIC8qKlxuICAgKiBTdGFnZXMgZWFjaCB0cmVlIGFuZCBjcmVhdGVzIGl0cyBkZXBsb3ltZW50LCBhZGRpbmcgZXZlcnkgc3RhZ2luZ1xuICAgKiBkaXJlY3RvcnkgdG8gYHN0YWdlZGAgYXMgaXQncyBtYWRlLCBzbyB0aGUgY2FsbGVyIGNhbiByZW1vdmUgdGhlbSBldmVuIGlmXG4gICAqIGEgbGF0ZXIgc3RlcCB0aHJvd3MuXG4gICAqL1xuICBwcml2YXRlIGNyZWF0ZURlcGxveW1lbnRzKHN0YWdlZDogc3RyaW5nW10pOiB7XG4gICAgc3RhdGljRGVwbG95bWVudD86IEJ1Y2tldERlcGxveW1lbnQ7XG4gICAgc2VydmljZVdvcmtlckRlcGxveW1lbnQ/OiBCdWNrZXREZXBsb3ltZW50O1xuICAgIHB1YmxpY0RlcGxveW1lbnQ/OiBCdWNrZXREZXBsb3ltZW50O1xuICB9IHtcbiAgICBjb25zdCBzdGFnZTogdHlwZW9mIHRoaXMuc3RhZ2VEaXJlY3RvcnkgPSAoLi4uYXJncykgPT4ge1xuICAgICAgY29uc3QgZGlyID0gdGhpcy5zdGFnZURpcmVjdG9yeSguLi5hcmdzKTtcbiAgICAgIGlmIChkaXIpIHtcbiAgICAgICAgc3RhZ2VkLnB1c2goZGlyKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBkaXI7XG4gICAgfTtcbiAgICBjb25zdCBidWlsdERpciA9IGpvaW4odGhpcy5wcm9wcy5idWlsZERpcmVjdG9yeSwgXCIubmV4dFwiLCBcInN0YXRpY1wiKTtcbiAgICBjb25zdCBwdWJsaWNTb3VyY2VEaXIgPSBqb2luKHRoaXMucHJvcHMuYnVpbGREaXJlY3RvcnksIFwicHVibGljXCIpO1xuICAgIC8vIE9ubHkgYSBkaXJlY3RvcnkgaXMgdXBsb2FkZWQgYXMgc2VydmljZSB3b3JrZXJzLCBzbyBvbmx5IGEgZGlyZWN0b3J5IGlzXG4gICAgLy8gbGVmdCBvdXQgaGVyZS5cbiAgICBjb25zdCBoYXNTZXJ2aWNlV29ya2VycyA9IHRoaXMuZGlyZWN0b3J5RXhpc3RzKFxuICAgICAgam9pbihidWlsdERpciwgU0VSVklDRV9XT1JLRVJfRElSKSxcbiAgICApO1xuICAgIGNvbnN0IHN0YXRpY0RpciA9IHN0YWdlKFxuICAgICAgYnVpbHREaXIsXG4gICAgICBTVEFUSUNfUEFUSCxcbiAgICAgIChwYXRoKSA9PiAhaGFzU2VydmljZVdvcmtlcnMgfHwgIWlzV2l0aGluKHBhdGgsIFNFUlZJQ0VfV09SS0VSX0RJUiksXG4gICAgKTtcbiAgICBjb25zdCBzZXJ2aWNlV29ya2VyRGlyID0gc3RhZ2UoXG4gICAgICBqb2luKGJ1aWx0RGlyLCBTRVJWSUNFX1dPUktFUl9ESVIpLFxuICAgICAgam9pbihTVEFUSUNfUEFUSCwgU0VSVklDRV9XT1JLRVJfRElSKSxcbiAgICApO1xuICAgIC8vIEEgYHB1YmxpYy9fbmV4dC9zdGF0aWNgIGZpbGUgd2l0aCBhIGJ1aWx0IGZpbGUncyBuYW1lIHdvdWxkIGxhbmQgb24gdGhlXG4gICAgLy8gc2FtZSBrZXkuIGBuZXh0IHN0YXJ0YCBzZXJ2ZXMgdGhlIGJ1aWx0IG9uZSwgc28gdGhlIHB1YmxpYyBjb3B5IGlzIGxlZnRcbiAgICAvLyBvdXQ7IHVwbG9hZGluZyBib3RoIHdvdWxkIGxlYXZlIHdoaWNoZXZlciBkZXBsb3ltZW50IGZpbmlzaGVkIGxhc3QuXG4gICAgLy8gT3RoZXIgYHB1YmxpYy9fbmV4dC9zdGF0aWNgIGZpbGVzIGFyZSBzZXJ2ZWQgYXMgYG5leHQgc3RhcnRgIGRvZXMuXG4gICAgLy8gTWF0Y2hlZCBhZ2FpbnN0IGEgbGlzdGluZyByYXRoZXIgdGhhbiB3aXRoIGBleGlzdHNTeW5jYCwgd2hpY2ggb24gbWFjT1NcbiAgICAvLyBhbmQgV2luZG93cyB3b3VsZCBsZXQgYExlZ2FjeS5qc2Agc2hhZG93IGBsZWdhY3kuanNgOiBOZXh0LmpzIGFuZCBTMyBrZXlzXG4gICAgLy8gYXJlIGNhc2Utc2Vuc2l0aXZlLlxuICAgIGNvbnN0IGJ1aWx0RmlsZXMgPSBuZXcgU2V0KFxuICAgICAgdGhpcy5kaXJlY3RvcnlFeGlzdHMoYnVpbHREaXIpID8gbGlzdEZpbGVzKGJ1aWx0RGlyKSA6IFtdLFxuICAgICk7XG4gICAgY29uc3QgcHVibGljRGlyID0gc3RhZ2UoXG4gICAgICBwdWJsaWNTb3VyY2VEaXIsXG4gICAgICBcIlwiLFxuICAgICAgKHBhdGgpID0+XG4gICAgICAgICFpc1dpdGhpbihwYXRoLCBTVEFUSUNfUEFUSCkgfHxcbiAgICAgICAgIWJ1aWx0RmlsZXMuaGFzKHJlbGF0aXZlKFNUQVRJQ19QQVRILCBwYXRoKSksXG4gICAgKTtcbiAgICBpZiAoIXN0YXRpY0RpciAmJiAhc2VydmljZVdvcmtlckRpciAmJiAhcHVibGljRGlyKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgIGBObyBzdGF0aWMgYXNzZXRzIGZvdW5kIHRvIGRlcGxveS4gRW5zdXJlIHlvdXIgTmV4dC5qcyBidWlsZCBvdXRwdXQgY29udGFpbnMgZmlsZXMgaW4gZWl0aGVyOlxuICAgICAgICAtIEEgJ3B1YmxpYycgZGlyZWN0b3J5IGF0OiAke3B1YmxpY1NvdXJjZURpcn1cbiAgICAgICAgLSBBICcubmV4dC9zdGF0aWMnIGRpcmVjdG9yeSBhdDogJHtidWlsdERpcn1gLFxuICAgICAgKTtcbiAgICB9XG4gICAgLy8gYF9uZXh0L3N0YXRpYy9gIGZpbGVzIGFyZSBjb250ZW50LWhhc2hlZCwgc28gdGhleSBnZXQgdGhlIHNhbWUgaGVhZGVyXG4gICAgLy8gTmV4dC5qcyBzZW5kcyBmb3IgdGhlbS4gTm90aGluZyBlbHNlIHdvdWxkOiBDbG91ZEZyb250IGFuZCBBUEkgR2F0ZXdheVxuICAgIC8vIHNlcnZlIHRoZW0gc3RyYWlnaHQgZnJvbSBTMywgd2hlcmUgdGhlIG9iamVjdCdzIG1ldGFkYXRhIGlzIHRoZSBvbmx5XG4gICAgLy8gYENhY2hlLUNvbnRyb2xgIHRoZXJlIGlzLiBBIGBCdWNrZXREZXBsb3ltZW50YCdzIGBjYWNoZUNvbnRyb2xgIGFwcGxpZXMgdG9cbiAgICAvLyBldmVyeSBvYmplY3QgaXQgdXBsb2FkcywgaGVuY2Ugb25lIGRlcGxveW1lbnQgcGVyIGhlYWRlci5cbiAgICByZXR1cm4ge1xuICAgICAgc3RhdGljRGVwbG95bWVudDogc3RhdGljRGlyXG4gICAgICAgID8gdGhpcy5jcmVhdGVEZXBsb3ltZW50KFwiRGVwbG95bWVudFwiLCBzdGF0aWNEaXIsIFtcbiAgICAgICAgICAgIENhY2hlQ29udHJvbC5zZXRQdWJsaWMoKSxcbiAgICAgICAgICAgIENhY2hlQ29udHJvbC5tYXhBZ2UoRHVyYXRpb24uZGF5cygzNjUpKSxcbiAgICAgICAgICAgIENhY2hlQ29udHJvbC5pbW11dGFibGUoKSxcbiAgICAgICAgICBdKVxuICAgICAgICA6IHVuZGVmaW5lZCxcbiAgICAgIHNlcnZpY2VXb3JrZXJEZXBsb3ltZW50OiBzZXJ2aWNlV29ya2VyRGlyXG4gICAgICAgID8gdGhpcy5jcmVhdGVEZXBsb3ltZW50KFwiU2VydmljZVdvcmtlckRlcGxveW1lbnRcIiwgc2VydmljZVdvcmtlckRpciwgW1xuICAgICAgICAgICAgQ2FjaGVDb250cm9sLnNldFB1YmxpYygpLFxuICAgICAgICAgICAgQ2FjaGVDb250cm9sLm1heEFnZShEdXJhdGlvbi5zZWNvbmRzKDApKSxcbiAgICAgICAgICAgIENhY2hlQ29udHJvbC5tdXN0UmV2YWxpZGF0ZSgpLFxuICAgICAgICAgIF0pXG4gICAgICAgIDogdW5kZWZpbmVkLFxuICAgICAgcHVibGljRGVwbG95bWVudDogcHVibGljRGlyXG4gICAgICAgID8gdGhpcy5jcmVhdGVEZXBsb3ltZW50KFwiUHVibGljRGVwbG95bWVudFwiLCBwdWJsaWNEaXIpXG4gICAgICAgIDogdW5kZWZpbmVkLFxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogUmVqZWN0cyB0aGUgYGJ1Y2tldERlcGxveW1lbnRQcm9wc2AgdGhhdCBjYW4ndCB3b3JrIGFjcm9zcyBzZXZlcmFsXG4gICAqIGRlcGxveW1lbnRzIHNoYXJpbmcgb25lIHByZWZpeC4gRWFjaCBpcyBzcHJlYWQgaW50byBldmVyeSBvbmUgb2YgdGhlbTpcbiAgICpcbiAgICogLSBgcHJ1bmU6IHRydWVgIG1ha2VzIGVhY2ggZGVwbG95bWVudCdzIGBzMyBzeW5jIC0tZGVsZXRlYCByZW1vdmUgdGhlIGZpbGVzXG4gICAqICAgdGhlIG90aGVycyB1cGxvYWRlZC5cbiAgICogLSBgcmV0YWluT25EZWxldGU6IGZhbHNlYCBtYWtlcyBhIGRlcGxveW1lbnQgYHMzIHJtIC0tcmVjdXJzaXZlYCBpdHMgb2xkXG4gICAqICAgcHJlZml4IHdoZW4gdGhlIHByZWZpeCBjaGFuZ2VzLCB3aXRob3V0IGNoZWNraW5nIHdoZXRoZXIgdGhlIGJ1Y2tldCBpc1xuICAgKiAgIENESydzIChvbmx5IERlbGV0ZSBjaGVja3MpLCBzbyBpdCBjYW4gZGVsZXRlIGZpbGVzIGFub3RoZXIgZGVwbG95bWVudCBoYXNcbiAgICogICBqdXN0IHVwbG9hZGVkIHRoZXJlLiBPbiBEZWxldGUsIENESyBza2lwcyB0aGF0IGBybWAgb25seSBmb3IgYSBidWNrZXQgaXRcbiAgICogICB0YWdnZWQsIGFuZCBpdCBjYW4ndCB0YWcgYW4gaW1wb3J0ZWQgb25lLCBzbyBhIGJ1aWxkIHRoYXQgc3RvcHMgaGF2aW5nXG4gICAqICAgZmlsZXMgZm9yIG9uZSBkZXBsb3ltZW50IHdvdWxkIGxvc2UgdGhlIG90aGVycycgZmlsZXMgdG9vLlxuICAgKlxuICAgKiBgc291cmNlc2AgYW5kIGBkZXN0aW5hdGlvbkJ1Y2tldGAgYXJlbid0IHJlamVjdGVkLCBiZWNhdXNlIHRoZSB0eXBlXG4gICAqIHJlcXVpcmVzIHRoZW07IGBuZXdEZXBsb3ltZW50YCBzZXRzIHRoZW0gYWZ0ZXIgdGhlIHNwcmVhZCBpbnN0ZWFkLlxuICAgKlxuICAgKiBDb21wYXJlZCBhZ2FpbnN0IHRoZSBleGFjdCB2YWx1ZSwgYXMgd2l0aCBgZGVzdGluYXRpb25LZXlQcmVmaXhgLCBzbyBhblxuICAgKiBleHBsaWNpdCBgdW5kZWZpbmVkYCBmcm9tIGEgSlNJSSBiaW5kaW5nIGlzIG5vdCBtaXN0YWtlbiBmb3IgYW4gb3ZlcnJpZGUuXG4gICAqL1xuICBwcml2YXRlIHZhbGlkYXRlRGVwbG95bWVudE92ZXJyaWRlcygpIHtcbiAgICBjb25zdCBvdmVycmlkZXMgPSB0aGlzLnByb3BzLm92ZXJyaWRlcz8uYnVja2V0RGVwbG95bWVudFByb3BzO1xuICAgIGNvbnN0IHJlamVjdGVkID0gW1xuICAgICAgb3ZlcnJpZGVzPy5wcnVuZSA9PT0gdHJ1ZSAmJlxuICAgICAgICBcImBwcnVuZTogdHJ1ZWAgKG9sZCBhc3NldHMgYXJlIHBydW5lZCBhZnRlciBkZXBsb3kgYnkgTmV4dGpzUG9zdERlcGxveSwgb25jZSB0aGV5IGFyZSBwYXN0IGl0cyBUVEwpXCIsXG4gICAgICBvdmVycmlkZXM/LnJldGFpbk9uRGVsZXRlID09PSBmYWxzZSAmJiBcImByZXRhaW5PbkRlbGV0ZTogZmFsc2VgXCIsXG4gICAgXS5maWx0ZXIoKHJlYXNvbik6IHJlYXNvbiBpcyBzdHJpbmcgPT4gISFyZWFzb24pO1xuICAgIGlmIChyZWplY3RlZC5sZW5ndGggPiAwKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgIGAke0xPR19QUkVGSVh9IG92ZXJyaWRlcy5idWNrZXREZXBsb3ltZW50UHJvcHMgY2FuJ3Qgc2V0ICR7cmVqZWN0ZWQuam9pbihcIiwgb3IgXCIpfTogYCArXG4gICAgICAgICAgXCJ0aGUgc3RhdGljIGFzc2V0cyBhcmUgdXBsb2FkZWQgYnkgb25lIGRlcGxveW1lbnQgcGVyIENhY2hlLUNvbnRyb2wsIFwiICtcbiAgICAgICAgICBcImFuZCBlYWNoIG9mIHRoZXNlIHdvdWxkIGJyZWFrIHRoZSBvdGhlcnMuXCIsXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSZXNvbHZlcyB0aGUgc2luZ2xlIHByZWZpeCBib3RoIHRoZSB1cGxvYWQgYW5kIHRoZSBVUkxzIHVzZS4gQVxuICAgKiBgYnVja2V0RGVwbG95bWVudFByb3BzLmRlc3RpbmF0aW9uS2V5UHJlZml4YCBvdmVycmlkZSB3aW5zIG92ZXIgYGJhc2VQYXRoYCxcbiAgICogYnV0IGl0J3Mgbm9ybWFsaXplZCBoZXJlIGFuZCBgY3JlYXRlRGVwbG95bWVudGAgc2V0cyB0aGUgbm9ybWFsaXplZCB2YWx1ZVxuICAgKiBhZnRlciB0aGUgb3ZlcnJpZGUgc3ByZWFkLCBzbyBga2V5UHJlZml4YCBjYW4ndCBkcmlmdCBmcm9tIHdoZXJlIHRoZSBhc3NldHNcbiAgICogbGFuZC5cbiAgICpcbiAgICogQ29tcGFyZWQgYWdhaW5zdCBgdW5kZWZpbmVkYCByYXRoZXIgdGhhbiB0ZXN0ZWQgd2l0aCBgaW5gLCBiZWNhdXNlIGEgSlNJSVxuICAgKiBsYW5ndWFnZSBiaW5kaW5nIChvciBhIHByb2dyYW1tYXRpY2FsbHkgYnVpbHQgcHJvcHMgb2JqZWN0KSBjYW4gbWF0ZXJpYWxpemVcbiAgICogYW4gdW5zZXQgb3B0aW9uYWwgZmllbGQgYXMgYW4gZXhwbGljaXQgYHVuZGVmaW5lZGAuIFRyZWF0aW5nIHRoYXQgYXMgYW5cbiAgICogaW50ZW50aW9uYWwgXCJtb3ZlIHRoZSBhc3NldHMgdG8gdGhlIGJ1Y2tldCByb290XCIgb3ZlcnJpZGUgd291bGQgc2lsZW50bHlcbiAgICogZHJvcCBgYmFzZVBhdGhgIGZyb20gdGhlIHByZWZpeC5cbiAgICovXG4gIHByaXZhdGUgcmVzb2x2ZUtleVByZWZpeCgpOiBzdHJpbmcge1xuICAgIGNvbnN0IGRlcGxveW1lbnRPdmVycmlkZXMgPSB0aGlzLnByb3BzLm92ZXJyaWRlcz8uYnVja2V0RGVwbG95bWVudFByb3BzO1xuICAgIGNvbnN0IHByZWZpeCA9XG4gICAgICBkZXBsb3ltZW50T3ZlcnJpZGVzPy5kZXN0aW5hdGlvbktleVByZWZpeCAhPT0gdW5kZWZpbmVkXG4gICAgICAgID8gZGVwbG95bWVudE92ZXJyaWRlcy5kZXN0aW5hdGlvbktleVByZWZpeFxuICAgICAgICA6IHRoaXMucHJvcHMuYmFzZVBhdGg7XG4gICAgcmV0dXJuIG5vcm1hbGl6ZUJhc2VQYXRoKHByZWZpeCk7XG4gIH1cblxuICBwcml2YXRlIGNyZWF0ZUJ1Y2tldCgpIHtcbiAgICByZXR1cm4gbmV3IEJ1Y2tldCh0aGlzLCBcIkJ1Y2tldFwiLCB7XG4gICAgICByZW1vdmFsUG9saWN5OiBSZW1vdmFsUG9saWN5LkRFU1RST1ksXG4gICAgICBhdXRvRGVsZXRlT2JqZWN0czogdHJ1ZSxcbiAgICAgIGVuZm9yY2VTU0w6IHRydWUsXG4gICAgICBibG9ja1B1YmxpY0FjY2VzczogQmxvY2tQdWJsaWNBY2Nlc3MuQkxPQ0tfQUxMLFxuICAgICAgZW5jcnlwdGlvbjogQnVja2V0RW5jcnlwdGlvbi5TM19NQU5BR0VELFxuICAgICAgbWluaW11bVRMU1ZlcnNpb246IDEuMixcbiAgICAgIC4uLnRoaXMucHJvcHMub3ZlcnJpZGVzPy5idWNrZXRQcm9wcyxcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgY3JlYXRlRGVwbG95bWVudChcbiAgICBpZDogc3RyaW5nLFxuICAgIHN0YWdpbmdEaXI6IHN0cmluZyxcbiAgICBjYWNoZUNvbnRyb2w/OiBDYWNoZUNvbnRyb2xbXSxcbiAgKSB7XG4gICAgcmV0dXJuIG5ldyBCdWNrZXREZXBsb3ltZW50KHRoaXMsIGlkLCB7XG4gICAgICAvLyBBZGQgQlVJTERfSUQgYXMgbWV0YWRhdGEgdG8gYWxsIG9iamVjdHMgZm9yIHZlcnNpb24gdHJhY2tpbmdcbiAgICAgIG1ldGFkYXRhOiB7XG4gICAgICAgIEJVSUxEX0lEOiB0aGlzLnByb3BzLmJ1aWxkSWQsXG4gICAgICB9LFxuICAgICAgLy8gUzNEZXBsb3ltZW50IGF1dG9tYXRpY2FsbHkgZGV0ZWN0cyBjb250ZW50IHR5cGVzIGJhc2VkIG9uIGZpbGUgZXh0ZW5zaW9uc1xuICAgICAgLi4udGhpcy5wcm9wcy5vdmVycmlkZXM/LmJ1Y2tldERlcGxveW1lbnRQcm9wcyxcbiAgICAgIC8vIFNldCBhZnRlciB0aGUgc3ByZWFkLiBUaGUgdHlwZSBtYWtlcyBjYWxsZXJzIHBhc3MgYHNvdXJjZXNgIGFuZFxuICAgICAgLy8gYGRlc3RpbmF0aW9uQnVja2V0YCwgYW5kIGVpdGhlciB3b3VsZCB1cGxvYWQgc29tZXRoaW5nIG90aGVyIHRoYW4gdGhlXG4gICAgICAvLyBidWlsZCdzIGFzc2V0cywgb3Igc29tZXdoZXJlIENsb3VkRnJvbnQgYW5kIEFQSSBHYXRld2F5IGRvbid0IHJlYWQgZnJvbS5cbiAgICAgIC8vIGB2YWxpZGF0ZURlcGxveW1lbnRPdmVycmlkZXNgIGxldHMgYHBydW5lYCB0aHJvdWdoIG9ubHkgYXMgYGZhbHNlYCBvciBhblxuICAgICAgLy8gZXhwbGljaXQgYHVuZGVmaW5lZGAgZnJvbSBhIEpTSUkgYmluZGluZywgd2hpY2ggd291bGQgdHVybiBvbiBDREsnc1xuICAgICAgLy8gZGVmYXVsdCBgcHJ1bmU6IHRydWVgLlxuICAgICAgc291cmNlczogW1NvdXJjZS5hc3NldChzdGFnaW5nRGlyKV0sXG4gICAgICBkZXN0aW5hdGlvbkJ1Y2tldDogdGhpcy5idWNrZXQsXG4gICAgICBwcnVuZTogZmFsc2UsIC8vIERvbid0IGRlbGV0ZSBleGlzdGluZyBhc3NldHMgdG8gcHJldmVudCA0MDRzIGR1cmluZyBkZXBsb3ltZW50LCBwcnVuaW5nIHdpbGwgYmUgaGFuZGxlZCBieSBwb3N0LWRlcGxveVxuICAgICAgLi4uKGNhY2hlQ29udHJvbCAmJiB7IGNhY2hlQ29udHJvbCB9KSxcbiAgICAgIC8vIFNldCBhZnRlciB0aGUgc3ByZWFkOiBgcmVzb2x2ZUtleVByZWZpeGAgYWxyZWFkeSBmb2xkZWQgaW4gYW55XG4gICAgICAvLyBgZGVzdGluYXRpb25LZXlQcmVmaXhgIG92ZXJyaWRlLCBzbyB0aGlzIGlzIHRoZSBub3JtYWxpemVkIGZvcm0gb2YgaXQuXG4gICAgICAvLyBMZXR0aW5nIHRoZSByYXcgb3ZlcnJpZGUgdGhyb3VnaCBoZXJlIHdvdWxkIHVwbG9hZCB0aGUgYXNzZXRzIHNvbWV3aGVyZVxuICAgICAgLy8gb3RoZXIgdGhhbiB0aGUgYGtleVByZWZpeGAgdXNlZCB0byBidWlsZCB0aGVpciBVUkxzLlxuICAgICAgZGVzdGluYXRpb25LZXlQcmVmaXg6IHRoaXMua2V5UHJlZml4IHx8IHVuZGVmaW5lZCxcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDb3BpZXMgYHNvdXJjZURpcmAgdG8gYDxzdGFnaW5nPi88c3ViUGF0aD5gIGluIGEgbmV3IHN0YWdpbmcgZGlyZWN0b3J5LCBvclxuICAgKiByZXR1cm5zIGB1bmRlZmluZWRgIGlmIHRoZXJlIGlzIG5vIGBzb3VyY2VEaXJgIG9yIG5vIGZpbGUgaW4gaXQgcGFzc2VzXG4gICAqIGBpbmNsdWRlYC4gU3RhZ2VkIHVuZGVyIGBzdWJQYXRoYCByYXRoZXIgdGhhbiB1cGxvYWRlZCB3aXRoIGEgbG9uZ2VyXG4gICAqIGBkZXN0aW5hdGlvbktleVByZWZpeGAsIHNvIGV2ZXJ5IGRlcGxveW1lbnQgc2hhcmVzIHRoZSBvbmUgcHJlZml4XG4gICAqIGBrZXlQcmVmaXhgIHJlc29sdmVzLiBgaW5jbHVkZWAgZ2V0cyBlYWNoIGVudHJ5J3MgcGF0aCByZWxhdGl2ZSB0b1xuICAgKiBgc291cmNlRGlyYC5cbiAgICovXG4gIHByaXZhdGUgc3RhZ2VEaXJlY3RvcnkoXG4gICAgc291cmNlRGlyOiBzdHJpbmcsXG4gICAgc3ViUGF0aDogc3RyaW5nLFxuICAgIGluY2x1ZGU6IChwYXRoOiBzdHJpbmcpID0+IGJvb2xlYW4gPSAoKSA9PiB0cnVlLFxuICApOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICAgIGlmICghdGhpcy5kaXJlY3RvcnlFeGlzdHMoc291cmNlRGlyKSkge1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG4gICAgLy8gRnJvbSB0aGUgcmVhbCBwYXRoLCBhbmQgZGVyZWZlcmVuY2luZyBsaW5rcyBpbnNpZGUgaXQ6IGBjcFN5bmNgIHdvdWxkXG4gICAgLy8gY29weSBhIGxpbmsgYXMgYSBsaW5rLCB3aGljaCBmYWlscyBmb3IgYSBzeW1saW5rZWQgYHNvdXJjZURpcmAgKG9udG8gdGhlXG4gICAgLy8gZGlyZWN0b3J5IG1hZGUgZm9yIGl0IGhlcmUpIGFuZCBoaWRlcyBhIGxpbmtlZCBkaXJlY3RvcnkncyBmaWxlcyBmcm9tXG4gICAgLy8gYGluY2x1ZGVgLCB0aG91Z2ggQ0RLIHVwbG9hZHMgdGhlbS5cbiAgICBjb25zdCByZWFsU291cmNlRGlyID0gcmVhbHBhdGhTeW5jKHNvdXJjZURpcik7XG4gICAgY29uc3Qgc3RhZ2luZ0RpciA9IG1rZHRlbXBTeW5jKGpvaW4odG1wZGlyKCksIFwibmV4dGpzLWFzc2V0cy1cIikpO1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBkZXN0RGlyID0gam9pbihzdGFnaW5nRGlyLCBzdWJQYXRoKTtcbiAgICAgIG1rZGlyU3luYyhkZXN0RGlyLCB7IHJlY3Vyc2l2ZTogdHJ1ZSB9KTtcbiAgICAgIGNwU3luYyhyZWFsU291cmNlRGlyLCBkZXN0RGlyLCB7XG4gICAgICAgIHJlY3Vyc2l2ZTogdHJ1ZSxcbiAgICAgICAgZGVyZWZlcmVuY2U6IHRydWUsXG4gICAgICAgIGZpbHRlcjogKHBhdGgpID0+IGluY2x1ZGUocmVsYXRpdmUocmVhbFNvdXJjZURpciwgcGF0aCkpLFxuICAgICAgfSk7XG4gICAgICBpZiAobGlzdEZpbGVzKGRlc3REaXIpLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICBybVN5bmMoc3RhZ2luZ0RpciwgeyByZWN1cnNpdmU6IHRydWUsIGZvcmNlOiB0cnVlIH0pO1xuICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHN0YWdpbmdEaXI7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIC8vIFRocm93biByYXRoZXIgdGhhbiBza2lwcGVkLCB3aGljaCB3b3VsZCBkZXBsb3kgd2l0aG91dCB0aGVzZSBhc3NldHMuXG4gICAgICAvLyBUaGUgY2xlYW51cCdzIG93biBmYWlsdXJlIG11c3Qgbm90IHJlcGxhY2UgdGhhdCBlcnJvci5cbiAgICAgIHRyeSB7XG4gICAgICAgIHJtU3luYyhzdGFnaW5nRGlyLCB7IHJlY3Vyc2l2ZTogdHJ1ZSwgZm9yY2U6IHRydWUgfSk7XG4gICAgICB9IGNhdGNoIHtcbiAgICAgICAgLy8gSWdub3JlIGNsZWFudXAgZXJyb3JzXG4gICAgICB9XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYCR7TE9HX1BSRUZJWH0gQ291bGQgbm90IHN0YWdlICR7c291cmNlRGlyfSBmb3IgdXBsb2FkYCwge1xuICAgICAgICBjYXVzZTogZXJyb3IsXG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQ2hlY2sgaWYgYSBkaXJlY3RvcnkgZXhpc3RzXG4gICAqL1xuICBwcml2YXRlIGRpcmVjdG9yeUV4aXN0cyhkaXJQYXRoOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICB0cnkge1xuICAgICAgcmV0dXJuIGV4aXN0c1N5bmMoZGlyUGF0aCkgJiYgc3RhdFN5bmMoZGlyUGF0aCkuaXNEaXJlY3RvcnkoKTtcbiAgICB9IGNhdGNoIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cbn1cbiJdfQ==