1 | ;
|
2 | var _a, _b;
|
3 | Object.defineProperty(exports, "__esModule", { value: true });
|
4 | exports.DockerVolumeConsistency = exports.DockerImage = exports.BundlingDockerImage = exports.BundlingOutput = void 0;
|
5 | const jsiiDeprecationWarnings = require("../.warnings.jsii.js");
|
6 | const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
|
7 | const child_process_1 = require("child_process");
|
8 | const crypto = require("crypto");
|
9 | const path_1 = require("path");
|
10 | const fs_1 = require("./fs");
|
11 | const jsii_deprecated_1 = require("./private/jsii-deprecated");
|
12 | /**
|
13 | * The type of output that a bundling operation is producing.
|
14 | *
|
15 | */
|
16 | var BundlingOutput;
|
17 | (function (BundlingOutput) {
|
18 | /**
|
19 | * The bundling output directory includes a single .zip or .jar file which
|
20 | * will be used as the final bundle. If the output directory does not
|
21 | * include exactly a single archive, bundling will fail.
|
22 | */
|
23 | BundlingOutput["ARCHIVED"] = "archived";
|
24 | /**
|
25 | * The bundling output directory contains one or more files which will be
|
26 | * archived and uploaded as a .zip file to S3.
|
27 | */
|
28 | BundlingOutput["NOT_ARCHIVED"] = "not-archived";
|
29 | /**
|
30 | * If the bundling output directory contains a single archive file (zip or jar)
|
31 | * it will be used as the bundle output as-is. Otherwise all the files in the bundling output directory will be zipped.
|
32 | */
|
33 | BundlingOutput["AUTO_DISCOVER"] = "auto-discover";
|
34 | })(BundlingOutput = exports.BundlingOutput || (exports.BundlingOutput = {}));
|
35 | /**
|
36 | * A Docker image used for asset bundling
|
37 | *
|
38 | * @deprecated use DockerImage
|
39 | */
|
40 | class BundlingDockerImage {
|
41 | /** @param image The Docker image */
|
42 | constructor(image, _imageHash) {
|
43 | this.image = image;
|
44 | this._imageHash = _imageHash;
|
45 | try {
|
46 | jsiiDeprecationWarnings.print("@aws-cdk/core.BundlingDockerImage", "use DockerImage");
|
47 | }
|
48 | catch (error) {
|
49 | if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
|
50 | Error.captureStackTrace(error, BundlingDockerImage);
|
51 | }
|
52 | throw error;
|
53 | }
|
54 | }
|
55 | /**
|
56 | * Reference an image on DockerHub or another online registry.
|
57 | *
|
58 | * @param image the image name
|
59 | */
|
60 | static fromRegistry(image) {
|
61 | try {
|
62 | jsiiDeprecationWarnings.print("@aws-cdk/core.BundlingDockerImage#fromRegistry", "use DockerImage");
|
63 | }
|
64 | catch (error) {
|
65 | if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
|
66 | Error.captureStackTrace(error, this.fromRegistry);
|
67 | }
|
68 | throw error;
|
69 | }
|
70 | return new DockerImage(image);
|
71 | }
|
72 | /**
|
73 | * Reference an image that's built directly from sources on disk.
|
74 | *
|
75 | * @param path The path to the directory containing the Docker file
|
76 | * @param options Docker build options
|
77 | *
|
78 | * @deprecated use DockerImage.fromBuild()
|
79 | */
|
80 | static fromAsset(path, options = {}) {
|
81 | try {
|
82 | jsiiDeprecationWarnings.print("@aws-cdk/core.BundlingDockerImage#fromAsset", "use DockerImage.fromBuild()");
|
83 | jsiiDeprecationWarnings._aws_cdk_core_DockerBuildOptions(options);
|
84 | }
|
85 | catch (error) {
|
86 | if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
|
87 | Error.captureStackTrace(error, this.fromAsset);
|
88 | }
|
89 | throw error;
|
90 | }
|
91 | return DockerImage.fromBuild(path, options);
|
92 | }
|
93 | /**
|
94 | * Provides a stable representation of this image for JSON serialization.
|
95 | *
|
96 | * @return The overridden image name if set or image hash name in that order
|
97 | */
|
98 | toJSON() {
|
99 | try {
|
100 | jsiiDeprecationWarnings.print("@aws-cdk/core.BundlingDockerImage#toJSON", "use DockerImage");
|
101 | }
|
102 | catch (error) {
|
103 | if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
|
104 | Error.captureStackTrace(error, this.toJSON);
|
105 | }
|
106 | throw error;
|
107 | }
|
108 | return this._imageHash ?? this.image;
|
109 | }
|
110 | /**
|
111 | * Runs a Docker image
|
112 | */
|
113 | run(options = {}) {
|
114 | try {
|
115 | jsiiDeprecationWarnings.print("@aws-cdk/core.BundlingDockerImage#run", "use DockerImage");
|
116 | jsiiDeprecationWarnings._aws_cdk_core_DockerRunOptions(options);
|
117 | }
|
118 | catch (error) {
|
119 | if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
|
120 | Error.captureStackTrace(error, this.run);
|
121 | }
|
122 | throw error;
|
123 | }
|
124 | const volumes = options.volumes || [];
|
125 | const environment = options.environment || {};
|
126 | const entrypoint = options.entrypoint?.[0] || null;
|
127 | const command = [
|
128 | ...options.entrypoint?.[1]
|
129 | ? [...options.entrypoint.slice(1)]
|
130 | : [],
|
131 | ...options.command
|
132 | ? [...options.command]
|
133 | : [],
|
134 | ];
|
135 | const dockerArgs = [
|
136 | 'run', '--rm',
|
137 | ...options.securityOpt
|
138 | ? ['--security-opt', options.securityOpt]
|
139 | : [],
|
140 | ...options.user
|
141 | ? ['-u', options.user]
|
142 | : [],
|
143 | ...flatten(volumes.map(v => ['-v', `${v.hostPath}:${v.containerPath}:${isSeLinux() ? 'z,' : ''}${v.consistency ?? DockerVolumeConsistency.DELEGATED}`])),
|
144 | ...flatten(Object.entries(environment).map(([k, v]) => ['--env', `${k}=${v}`])),
|
145 | ...options.workingDirectory
|
146 | ? ['-w', options.workingDirectory]
|
147 | : [],
|
148 | ...entrypoint
|
149 | ? ['--entrypoint', entrypoint]
|
150 | : [],
|
151 | this.image,
|
152 | ...command,
|
153 | ];
|
154 | dockerExec(dockerArgs);
|
155 | }
|
156 | /**
|
157 | * Copies a file or directory out of the Docker image to the local filesystem.
|
158 | *
|
159 | * If `outputPath` is omitted the destination path is a temporary directory.
|
160 | *
|
161 | * @param imagePath the path in the Docker image
|
162 | * @param outputPath the destination path for the copy operation
|
163 | * @returns the destination path
|
164 | */
|
165 | cp(imagePath, outputPath) {
|
166 | try {
|
167 | jsiiDeprecationWarnings.print("@aws-cdk/core.BundlingDockerImage#cp", "use DockerImage");
|
168 | }
|
169 | catch (error) {
|
170 | if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
|
171 | Error.captureStackTrace(error, this.cp);
|
172 | }
|
173 | throw error;
|
174 | }
|
175 | const { stdout } = dockerExec(['create', this.image], {}); // Empty options to avoid stdout redirect here
|
176 | const match = stdout.toString().match(/([0-9a-f]{16,})/);
|
177 | if (!match) {
|
178 | throw new Error('Failed to extract container ID from Docker create output');
|
179 | }
|
180 | const containerId = match[1];
|
181 | const containerPath = `${containerId}:${imagePath}`;
|
182 | const destPath = outputPath ?? fs_1.FileSystem.mkdtemp('cdk-docker-cp-');
|
183 | try {
|
184 | dockerExec(['cp', containerPath, destPath]);
|
185 | return destPath;
|
186 | }
|
187 | catch (err) {
|
188 | throw new Error(`Failed to copy files from ${containerPath} to ${destPath}: ${err}`);
|
189 | }
|
190 | finally {
|
191 | dockerExec(['rm', '-v', containerId]);
|
192 | }
|
193 | }
|
194 | }
|
195 | exports.BundlingDockerImage = BundlingDockerImage;
|
196 | _a = JSII_RTTI_SYMBOL_1;
|
197 | BundlingDockerImage[_a] = { fqn: "@aws-cdk/core.BundlingDockerImage", version: "1.204.0" };
|
198 | /**
|
199 | * A Docker image
|
200 | */
|
201 | class DockerImage extends BundlingDockerImage {
|
202 | constructor(image, _imageHash) {
|
203 | // It is preferrable for the deprecated class to inherit a non-deprecated class.
|
204 | // However, in this case, the opposite has occurred which is incompatible with
|
205 | // a deprecation feature. See https://github.com/aws/jsii/issues/3102.
|
206 | const deprecated = jsii_deprecated_1.quiet();
|
207 | super(image, _imageHash);
|
208 | jsii_deprecated_1.reset(deprecated);
|
209 | this.image = image;
|
210 | }
|
211 | /**
|
212 | * Builds a Docker image
|
213 | *
|
214 | * @param path The path to the directory containing the Docker file
|
215 | * @param options Docker build options
|
216 | */
|
217 | static fromBuild(path, options = {}) {
|
218 | try {
|
219 | jsiiDeprecationWarnings._aws_cdk_core_DockerBuildOptions(options);
|
220 | }
|
221 | catch (error) {
|
222 | if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
|
223 | Error.captureStackTrace(error, this.fromBuild);
|
224 | }
|
225 | throw error;
|
226 | }
|
227 | const buildArgs = options.buildArgs || {};
|
228 | if (options.file && path_1.isAbsolute(options.file)) {
|
229 | throw new Error(`"file" must be relative to the docker build directory. Got ${options.file}`);
|
230 | }
|
231 | // Image tag derived from path and build options
|
232 | const input = JSON.stringify({ path, ...options });
|
233 | const tagHash = crypto.createHash('sha256').update(input).digest('hex');
|
234 | const tag = `cdk-${tagHash}`;
|
235 | const dockerArgs = [
|
236 | 'build', '-t', tag,
|
237 | ...(options.file ? ['-f', path_1.join(path, options.file)] : []),
|
238 | ...(options.platform ? ['--platform', options.platform] : []),
|
239 | ...flatten(Object.entries(buildArgs).map(([k, v]) => ['--build-arg', `${k}=${v}`])),
|
240 | path,
|
241 | ];
|
242 | dockerExec(dockerArgs);
|
243 | // Fingerprints the directory containing the Dockerfile we're building and
|
244 | // differentiates the fingerprint based on build arguments. We do this so
|
245 | // we can provide a stable image hash. Otherwise, the image ID will be
|
246 | // different every time the Docker layer cache is cleared, due primarily to
|
247 | // timestamps.
|
248 | const hash = fs_1.FileSystem.fingerprint(path, { extraHash: JSON.stringify(options) });
|
249 | return new DockerImage(tag, hash);
|
250 | }
|
251 | /**
|
252 | * Reference an image on DockerHub or another online registry.
|
253 | *
|
254 | * @param image the image name
|
255 | */
|
256 | static fromRegistry(image) {
|
257 | return new DockerImage(image);
|
258 | }
|
259 | /**
|
260 | * Provides a stable representation of this image for JSON serialization.
|
261 | *
|
262 | * @return The overridden image name if set or image hash name in that order
|
263 | */
|
264 | toJSON() {
|
265 | // It is preferrable for the deprecated class to inherit a non-deprecated class.
|
266 | // However, in this case, the opposite has occurred which is incompatible with
|
267 | // a deprecation feature. See https://github.com/aws/jsii/issues/3102.
|
268 | const deprecated = jsii_deprecated_1.quiet();
|
269 | const json = super.toJSON();
|
270 | jsii_deprecated_1.reset(deprecated);
|
271 | return json;
|
272 | }
|
273 | /**
|
274 | * Runs a Docker image
|
275 | */
|
276 | run(options = {}) {
|
277 | try {
|
278 | jsiiDeprecationWarnings._aws_cdk_core_DockerRunOptions(options);
|
279 | }
|
280 | catch (error) {
|
281 | if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
|
282 | Error.captureStackTrace(error, this.run);
|
283 | }
|
284 | throw error;
|
285 | }
|
286 | // It is preferrable for the deprecated class to inherit a non-deprecated class.
|
287 | // However, in this case, the opposite has occurred which is incompatible with
|
288 | // a deprecation feature. See https://github.com/aws/jsii/issues/3102.
|
289 | const deprecated = jsii_deprecated_1.quiet();
|
290 | const result = super.run(options);
|
291 | jsii_deprecated_1.reset(deprecated);
|
292 | return result;
|
293 | }
|
294 | /**
|
295 | * Copies a file or directory out of the Docker image to the local filesystem.
|
296 | *
|
297 | * If `outputPath` is omitted the destination path is a temporary directory.
|
298 | *
|
299 | * @param imagePath the path in the Docker image
|
300 | * @param outputPath the destination path for the copy operation
|
301 | * @returns the destination path
|
302 | */
|
303 | cp(imagePath, outputPath) {
|
304 | // It is preferrable for the deprecated class to inherit a non-deprecated class.
|
305 | // However, in this case, the opposite has occurred which is incompatible with
|
306 | // a deprecation feature. See https://github.com/aws/jsii/issues/3102.
|
307 | const deprecated = jsii_deprecated_1.quiet();
|
308 | const result = super.cp(imagePath, outputPath);
|
309 | jsii_deprecated_1.reset(deprecated);
|
310 | return result;
|
311 | }
|
312 | }
|
313 | exports.DockerImage = DockerImage;
|
314 | _b = JSII_RTTI_SYMBOL_1;
|
315 | DockerImage[_b] = { fqn: "@aws-cdk/core.DockerImage", version: "1.204.0" };
|
316 | /**
|
317 | * Supported Docker volume consistency types. Only valid on macOS due to the way file storage works on Mac
|
318 | */
|
319 | var DockerVolumeConsistency;
|
320 | (function (DockerVolumeConsistency) {
|
321 | /**
|
322 | * Read/write operations inside the Docker container are applied immediately on the mounted host machine volumes
|
323 | */
|
324 | DockerVolumeConsistency["CONSISTENT"] = "consistent";
|
325 | /**
|
326 | * Read/write operations on mounted Docker volumes are first written inside the container and then synchronized to the host machine
|
327 | */
|
328 | DockerVolumeConsistency["DELEGATED"] = "delegated";
|
329 | /**
|
330 | * Read/write operations on mounted Docker volumes are first applied on the host machine and then synchronized to the container
|
331 | */
|
332 | DockerVolumeConsistency["CACHED"] = "cached";
|
333 | })(DockerVolumeConsistency = exports.DockerVolumeConsistency || (exports.DockerVolumeConsistency = {}));
|
334 | function flatten(x) {
|
335 | return Array.prototype.concat([], ...x);
|
336 | }
|
337 | function dockerExec(args, options) {
|
338 | const prog = process.env.CDK_DOCKER ?? 'docker';
|
339 | const proc = child_process_1.spawnSync(prog, args, options ?? {
|
340 | stdio: [
|
341 | 'ignore',
|
342 | process.stderr,
|
343 | 'inherit',
|
344 | ],
|
345 | });
|
346 | if (proc.error) {
|
347 | throw proc.error;
|
348 | }
|
349 | if (proc.status !== 0) {
|
350 | if (proc.stdout || proc.stderr) {
|
351 | throw new Error(`[Status ${proc.status}] stdout: ${proc.stdout?.toString().trim()}\n\n\nstderr: ${proc.stderr?.toString().trim()}`);
|
352 | }
|
353 | throw new Error(`${prog} exited with status ${proc.status}`);
|
354 | }
|
355 | return proc;
|
356 | }
|
357 | function isSeLinux() {
|
358 | if (process.platform != 'linux') {
|
359 | return false;
|
360 | }
|
361 | const prog = 'selinuxenabled';
|
362 | const proc = child_process_1.spawnSync(prog, [], {
|
363 | stdio: [
|
364 | 'pipe',
|
365 | process.stderr,
|
366 | 'inherit',
|
367 | ],
|
368 | });
|
369 | if (proc.error) {
|
370 | // selinuxenabled not a valid command, therefore not enabled
|
371 | return false;
|
372 | }
|
373 | if (proc.status == 0) {
|
374 | // selinux enabled
|
375 | return true;
|
376 | }
|
377 | else {
|
378 | // selinux not enabled
|
379 | return false;
|
380 | }
|
381 | }
|
382 | //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYnVuZGxpbmcuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJidW5kbGluZy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7QUFBQSxpREFBNEQ7QUFDNUQsaUNBQWlDO0FBQ2pDLCtCQUF3QztBQUN4Qyw2QkFBa0M7QUFDbEMsK0RBQXlEO0FBK0Z6RDs7O0dBR0c7QUFDSCxJQUFZLGNBbUJYO0FBbkJELFdBQVksY0FBYztJQUN4Qjs7OztPQUlHO0lBQ0gsdUNBQXFCLENBQUE7SUFFckI7OztPQUdHO0lBQ0gsK0NBQTZCLENBQUE7SUFFN0I7OztPQUdHO0lBQ0gsaURBQStCLENBQUE7QUFDakMsQ0FBQyxFQW5CVyxjQUFjLEdBQWQsc0JBQWMsS0FBZCxzQkFBYyxRQW1CekI7QUFrQkQ7Ozs7R0FJRztBQUNILE1BQWEsbUJBQW1CO0lBc0I5QixvQ0FBb0M7SUFDcEMsWUFBc0MsS0FBYSxFQUFtQixVQUFtQjtRQUFuRCxVQUFLLEdBQUwsS0FBSyxDQUFRO1FBQW1CLGVBQVUsR0FBVixVQUFVLENBQVM7Ozs7OzsrQ0F2QjlFLG1CQUFtQjs7OztLQXVCK0Q7SUF0QjdGOzs7O09BSUc7SUFDSSxNQUFNLENBQUMsWUFBWSxDQUFDLEtBQWE7Ozs7Ozs7Ozs7UUFDdEMsT0FBTyxJQUFJLFdBQVcsQ0FBQyxLQUFLLENBQUMsQ0FBQztLQUMvQjtJQUVEOzs7Ozs7O09BT0c7SUFDSSxNQUFNLENBQUMsU0FBUyxDQUFDLElBQVksRUFBRSxVQUE4QixFQUFFOzs7Ozs7Ozs7OztRQUNwRSxPQUFPLFdBQVcsQ0FBQyxTQUFTLENBQUMsSUFBSSxFQUFFLE9BQU8sQ0FBQyxDQUFDO0tBQzdDO0lBS0Q7Ozs7T0FJRztJQUNJLE1BQU07Ozs7Ozs7Ozs7UUFDWCxPQUFPLElBQUksQ0FBQyxVQUFVLElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQztLQUN0QztJQUVEOztPQUVHO0lBQ0ksR0FBRyxDQUFDLFVBQTRCLEVBQUU7Ozs7Ozs7Ozs7O1FBQ3ZDLE1BQU0sT0FBTyxH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TyxLQUFLLENBQUM7S0FDZDtJQUNELE1BQU0sSUFBSSxHQUFHLGdCQUFnQixDQUFDO0lBQzlCLE1BQU0sSUFBSSxHQUFHLHlCQUFTLENBQUMsSUFBSSxFQUFFLEVBQUUsRUFBRTtRQUMvQixLQUFLLEVBQUU7WUFDTCxNQUFNO1lBQ04sT0FBTyxDQUFDLE1BQU07WUFDZCxTQUFTO1NBQ1Y7S0FDRixDQUFDLENBQUM7SUFDSCxJQUFJLElBQUksQ0FBQyxLQUFLLEVBQUU7UUFDZCw0REFBNEQ7UUFDNUQsT0FBTyxLQUFLLENBQUM7S0FDZDtJQUNELElBQUksSUFBSSxDQUFDLE1BQU0sSUFBSSxDQUFDLEVBQUU7UUFDcEIsa0JBQWtCO1FBQ2xCLE9BQU8sSUFBSSxDQUFDO0tBQ2I7U0FBTTtRQUNMLHNCQUFzQjtRQUN0QixPQUFPLEtBQUssQ0FBQztLQUNkO0FBQ0gsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IHNwYXduU3luYywgU3Bhd25TeW5jT3B0aW9ucyB9IGZyb20gJ2NoaWxkX3Byb2Nlc3MnO1xuaW1wb3J0ICogYXMgY3J5cHRvIGZyb20gJ2NyeXB0byc7XG5pbXBvcnQgeyBpc0Fic29sdXRlLCBqb2luIH0gZnJvbSAncGF0aCc7XG5pbXBvcnQgeyBGaWxlU3lzdGVtIH0gZnJvbSAnLi9mcyc7XG5pbXBvcnQgeyBxdWlldCwgcmVzZXQgfSBmcm9tICcuL3ByaXZhdGUvanNpaS1kZXByZWNhdGVkJztcblxuLyoqXG4gKiBCdW5kbGluZyBvcHRpb25zXG4gKlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEJ1bmRsaW5nT3B0aW9ucyB7XG4gIC8qKlxuICAgKiBUaGUgRG9ja2VyIGltYWdlIHdoZXJlIHRoZSBjb21tYW5kIHdpbGwgcnVuLlxuICAgKi9cbiAgcmVhZG9ubHkgaW1hZ2U6IERvY2tlckltYWdlO1xuXG4gIC8qKlxuICAgKiBUaGUgZW50cnlwb2ludCB0byBydW4gaW4gdGhlIERvY2tlciBjb250YWluZXIuXG4gICAqXG4gICAqIEV4YW1wbGUgdmFsdWU6IGBbJy9iaW4vc2gnLCAnLWMnXWBcbiAgICpcbiAgICogQHNlZSBodHRwczovL2RvY3MuZG9ja2VyLmNvbS9lbmdpbmUvcmVmZXJlbmNlL2J1aWxkZXIvI2VudHJ5cG9pbnRcbiAgICpcbiAgICogQGRlZmF1bHQgLSBydW4gdGhlIGVudHJ5cG9pbnQgZGVmaW5lZCBpbiB0aGUgaW1hZ2VcbiAgICovXG4gIHJlYWRvbmx5IGVudHJ5cG9pbnQ/OiBzdHJpbmdbXTtcblxuICAvKipcbiAgICogVGhlIGNvbW1hbmQgdG8gcnVuIGluIHRoZSBEb2NrZXIgY29udGFpbmVyLlxuICAgKlxuICAgKiBFeGFtcGxlIHZhbHVlOiBgWyducG0nLCAnaW5zdGFsbCddYFxuICAgKlxuICAgKiBAc2VlIGh0dHBzOi8vZG9jcy5kb2NrZXIuY29tL2VuZ2luZS9yZWZlcmVuY2UvcnVuL1xuICAgKlxuICAgKiBAZGVmYXVsdCAtIHJ1biB0aGUgY29tbWFuZCBkZWZpbmVkIGluIHRoZSBpbWFnZVxuICAgKi9cbiAgcmVhZG9ubHkgY29tbWFuZD86IHN0cmluZ1tdO1xuXG4gIC8qKlxuICAgKiBBZGRpdGlvbmFsIERvY2tlciB2b2x1bWVzIHRvIG1vdW50LlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIG5vIGFkZGl0aW9uYWwgdm9sdW1lcyBhcmUgbW91bnRlZFxuICAgKi9cbiAgcmVhZG9ubHkgdm9sdW1lcz86IERvY2tlclZvbHVtZVtdO1xuXG4gIC8qKlxuICAgKiBUaGUgZW52aXJvbm1lbnQgdmFyaWFibGVzIHRvIHBhc3MgdG8gdGhlIERvY2tlciBjb250YWluZXIuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gbm8gZW52aXJvbm1lbnQgdmFyaWFibGVzLlxuICAgKi9cbiAgcmVhZG9ubHkgZW52aXJvbm1lbnQ/OiB7IFtrZXk6IHN0cmluZ106IHN0cmluZzsgfTtcblxuICAvKipcbiAgICogV29ya2luZyBkaXJlY3RvcnkgaW5zaWRlIHRoZSBEb2NrZXIgY29udGFpbmVyLlxuICAgKlxuICAgKiBAZGVmYXVsdCAvYXNzZXQtaW5wdXRcbiAgICovXG4gIHJlYWRvbmx5IHdvcmtpbmdEaXJlY3Rvcnk/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSB1c2VyIHRvIHVzZSB3aGVuIHJ1bm5pbmcgdGhlIERvY2tlciBjb250YWluZXIuXG4gICAqXG4gICAqICAgdXNlciB8IHVzZXI6Z3JvdXAgfCB1aWQgfCB1aWQ6Z2lkIHwgdXNlcjpnaWQgfCB1aWQ6Z3JvdXBcbiAgICpcbiAgICogQHNlZSBodHRwczovL2RvY3MuZG9ja2VyLmNvbS9lbmdpbmUvcmVmZXJlbmNlL3J1bi8jdXNlclxuICAgKlxuICAgKiBAZGVmYXVsdCAtIHVpZDpnaWQgb2YgdGhlIGN1cnJlbnQgdXNlciBvciAxMDAwOjEwMDAgb24gV2luZG93c1xuICAgKi9cbiAgcmVhZG9ubHkgdXNlcj86IHN0cmluZztcblxuICAvKipcbiAgICogTG9jYWwgYnVuZGxpbmcgcHJvdmlkZXIuXG4gICAqXG4gICAqIFRoZSBwcm92aWRlciBpbXBsZW1lbnRzIGEgbWV0aG9kIGB0cnlCdW5kbGUoKWAgd2hpY2ggc2hvdWxkIHJldHVybiBgdHJ1ZWBcbiAgICogaWYgbG9jYWwgYnVuZGxpbmcgd2FzIHBlcmZvcm1lZC4gSWYgYGZhbHNlYCBpcyByZXR1cm5lZCwgZG9ja2VyIGJ1bmRsaW5nXG4gICAqIHdpbGwgYmUgZG9uZS5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBidW5kbGluZyB3aWxsIG9ubHkgYmUgcGVyZm9ybWVkIGluIGEgRG9ja2VyIGNvbnRhaW5lclxuICAgKlxuICAgKi9cbiAgcmVhZG9ubHkgbG9jYWw/OiBJTG9jYWxCdW5kbGluZztcblxuICAvKipcbiAgICogVGhlIHR5cGUgb2Ygb3V0cHV0IHRoYXQgdGhpcyBidW5kbGluZyBvcGVyYXRpb24gaXMgcHJvZHVjaW5nLlxuICAgKlxuICAgKiBAZGVmYXVsdCBCdW5kbGluZ091dHB1dC5BVVRPX0RJU0NPVkVSXG4gICAqXG4gICAqL1xuICByZWFkb25seSBvdXRwdXRUeXBlPzogQnVuZGxpbmdPdXRwdXQ7XG5cbiAgLyoqXG4gICAqIFtTZWN1cml0eSBjb25maWd1cmF0aW9uXShodHRwczovL2RvY3MuZG9ja2VyLmNvbS9lbmdpbmUvcmVmZXJlbmNlL3J1bi8jc2VjdXJpdHktY29uZmlndXJhdGlvbilcbiAgICogd2hlbiBydW5uaW5nIHRoZSBkb2NrZXIgY29udGFpbmVyLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIG5vIHNlY3VyaXR5IG9wdGlvbnNcbiAgICovXG4gIHJlYWRvbmx5IHNlY3VyaXR5T3B0Pzogc3RyaW5nO1xufVxuXG4vKipcbiAqIFRoZSB0eXBlIG9mIG91dHB1dCB0aGF0IGEgYnVuZGxpbmcgb3BlcmF0aW9uIGlzIHByb2R1Y2luZy5cbiAqXG4gKi9cbmV4cG9ydCBlbnVtIEJ1bmRsaW5nT3V0cHV0IHtcbiAgLyoqXG4gICAqIFRoZSBidW5kbGluZyBvdXRwdXQgZGlyZWN0b3J5IGluY2x1ZGVzIGEgc2luZ2xlIC56aXAgb3IgLmphciBmaWxlIHdoaWNoXG4gICAqIHdpbGwgYmUgdXNlZCBhcyB0aGUgZmluYWwgYnVuZGxlLiBJZiB0aGUgb3V0cHV0IGRpcmVjdG9yeSBkb2VzIG5vdFxuICAgKiBpbmNsdWRlIGV4YWN0bHkgYSBzaW5nbGUgYXJjaGl2ZSwgYnVuZGxpbmcgd2lsbCBmYWlsLlxuICAgKi9cbiAgQVJDSElWRUQgPSAnYXJjaGl2ZWQnLFxuXG4gIC8qKlxuICAgKiBUaGUgYnVuZGxpbmcgb3V0cHV0IGRpcmVjdG9yeSBjb250YWlucyBvbmUgb3IgbW9yZSBmaWxlcyB3aGljaCB3aWxsIGJlXG4gICAqIGFyY2hpdmVkIGFuZCB1cGxvYWRlZCBhcyBhIC56aXAgZmlsZSB0byBTMy5cbiAgICovXG4gIE5PVF9BUkNISVZFRCA9ICdub3QtYXJjaGl2ZWQnLFxuXG4gIC8qKlxuICAgKiBJZiB0aGUgYnVuZGxpbmcgb3V0cHV0IGRpcmVjdG9yeSBjb250YWlucyBhIHNpbmdsZSBhcmNoaXZlIGZpbGUgKHppcCBvciBqYXIpXG4gICAqIGl0IHdpbGwgYmUgdXNlZCBhcyB0aGUgYnVuZGxlIG91dHB1dCBhcy1pcy4gT3RoZXJ3aXNlIGFsbCB0aGUgZmlsZXMgaW4gdGhlIGJ1bmRsaW5nIG91dHB1dCBkaXJlY3Rvcnkgd2lsbCBiZSB6aXBwZWQuXG4gICAqL1xuICBBVVRPX0RJU0NPVkVSID0gJ2F1dG8tZGlzY292ZXInLFxufVxuXG4vKipcbiAqIExvY2FsIGJ1bmRsaW5nXG4gKlxuICovXG5leHBvcnQgaW50ZXJmYWNlIElMb2NhbEJ1bmRsaW5nIHtcbiAgLyoqXG4gICAqIFRoaXMgbWV0aG9kIGlzIGNhbGxlZCBiZWZvcmUgYXR0ZW1wdGluZyBkb2NrZXIgYnVuZGxpbmcgdG8gYWxsb3cgdGhlXG4gICAqIGJ1bmRsZXIgdG8gYmUgZXhlY3V0ZWQgbG9jYWxseS4gSWYgdGhlIGxvY2FsIGJ1bmRsZXIgZXhpc3RzLCBhbmQgYnVuZGxpbmdcbiAgICogd2FzIHBlcmZvcm1lZCBsb2NhbGx5LCByZXR1cm4gYHRydWVgLiBPdGhlcndpc2UsIHJldHVybiBgZmFsc2VgLlxuICAgKlxuICAgKiBAcGFyYW0gb3V0cHV0RGlyIHRoZSBkaXJlY3Rvcnkgd2hlcmUgdGhlIGJ1bmRsZWQgYXNzZXQgc2hvdWxkIGJlIG91dHB1dFxuICAgKiBAcGFyYW0gb3B0aW9ucyBidW5kbGluZyBvcHRpb25zIGZvciB0aGlzIGFzc2V0XG4gICAqL1xuICB0cnlCdW5kbGUob3V0cHV0RGlyOiBzdHJpbmcsIG9wdGlvbnM6IEJ1bmRsaW5nT3B0aW9ucyk6IGJvb2xlYW47XG59XG5cbi8qKlxuICogQSBEb2NrZXIgaW1hZ2UgdXNlZCBmb3IgYXNzZXQgYnVuZGxpbmdcbiAqXG4gKiBAZGVwcmVjYXRlZCB1c2UgRG9ja2VySW1hZ2VcbiAqL1xuZXhwb3J0IGNsYXNzIEJ1bmRsaW5nRG9ja2VySW1hZ2Uge1xuICAvKipcbiAgICogUmVmZXJlbmNlIGFuIGltYWdlIG9uIERvY2tlckh1YiBvciBhbm90aGVyIG9ubGluZSByZWdpc3RyeS5cbiAgICpcbiAgICogQHBhcmFtIGltYWdlIHRoZSBpbWFnZSBuYW1lXG4gICAqL1xuICBwdWJsaWMgc3RhdGljIGZyb21SZWdpc3RyeShpbWFnZTogc3RyaW5nKSB7XG4gICAgcmV0dXJuIG5ldyBEb2NrZXJJbWFnZShpbWFnZSk7XG4gIH1cblxuICAvKipcbiAgICogUmVmZXJlbmNlIGFuIGltYWdlIHRoYXQncyBidWlsdCBkaXJlY3RseSBmcm9tIHNvdXJjZXMgb24gZGlzay5cbiAgICpcbiAgICogQHBhcmFtIHBhdGggVGhlIHBhdGggdG8gdGhlIGRpcmVjdG9yeSBjb250YWluaW5nIHRoZSBEb2NrZXIgZmlsZVxuICAgKiBAcGFyYW0gb3B0aW9ucyBEb2NrZXIgYnVpbGQgb3B0aW9uc1xuICAgKlxuICAgKiBAZGVwcmVjYXRlZCB1c2UgRG9ja2VySW1hZ2UuZnJvbUJ1aWxkKClcbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgZnJvbUFzc2V0KHBhdGg6IHN0cmluZywgb3B0aW9uczogRG9ja2VyQnVpbGRPcHRpb25zID0ge30pOiBCdW5kbGluZ0RvY2tlckltYWdlIHtcbiAgICByZXR1cm4gRG9ja2VySW1hZ2UuZnJvbUJ1aWxkKHBhdGgsIG9wdGlvbnMpO1xuICB9XG5cbiAgLyoqIEBwYXJhbSBpbWFnZSBUaGUgRG9ja2VyIGltYWdlICovXG4gIHByb3RlY3RlZCBjb25zdHJ1Y3RvcihwdWJsaWMgcmVhZG9ubHkgaW1hZ2U6IHN0cmluZywgcHJpdmF0ZSByZWFkb25seSBfaW1hZ2VIYXNoPzogc3RyaW5nKSB7fVxuXG4gIC8qKlxuICAgKiBQcm92aWRlcyBhIHN0YWJsZSByZXByZXNlbnRhdGlvbiBvZiB0aGlzIGltYWdlIGZvciBKU09OIHNlcmlhbGl6YXRpb24uXG4gICAqXG4gICAqIEByZXR1cm4gVGhlIG92ZXJyaWRkZW4gaW1hZ2UgbmFtZSBpZiBzZXQgb3IgaW1hZ2UgaGFzaCBuYW1lIGluIHRoYXQgb3JkZXJcbiAgICovXG4gIHB1YmxpYyB0b0pTT04oKSB7XG4gICAgcmV0dXJuIHRoaXMuX2ltYWdlSGFzaCA/PyB0aGlzLmltYWdlO1xuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgYSBEb2NrZXIgaW1hZ2VcbiAgICovXG4gIHB1YmxpYyBydW4ob3B0aW9uczogRG9ja2VyUnVuT3B0aW9ucyA9IHt9KSB7XG4gICAgY29uc3Qgdm9sdW1lcyA9IG9wdGlvbnMudm9sdW1lcyB8fCBbXTtcbiAgICBjb25zdCBlbnZpcm9ubWVudCA9IG9wdGlvbnMuZW52aXJvbm1lbnQgfHwge307XG4gICAgY29uc3QgZW50cnlwb2ludCA9IG9wdGlvbnMuZW50cnlwb2ludD8uWzBdIHx8IG51bGw7XG4gICAgY29uc3QgY29tbWFuZCA9IFtcbiAgICAgIC4uLm9wdGlvbnMuZW50cnlwb2ludD8uWzFdXG4gICAgICAgID8gWy4uLm9wdGlvbnMuZW50cnlwb2ludC5zbGljZSgxKV1cbiAgICAgICAgOiBbXSxcbiAgICAgIC4uLm9wdGlvbnMuY29tbWFuZFxuICAgICAgICA/IFsuLi5vcHRpb25zLmNvbW1hbmRdXG4gICAgICAgIDogW10sXG4gICAgXTtcblxuICAgIGNvbnN0IGRvY2tlckFyZ3M6IHN0cmluZ1tdID0gW1xuICAgICAgJ3J1bicsICctLXJtJyxcbiAgICAgIC4uLm9wdGlvbnMuc2VjdXJpdHlPcHRcbiAgICAgICAgPyBbJy0tc2VjdXJpdHktb3B0Jywgb3B0aW9ucy5zZWN1cml0eU9wdF1cbiAgICAgICAgOiBbXSxcbiAgICAgIC4uLm9wdGlvbnMudXNlclxuICAgICAgICA/IFsnLXUnLCBvcHRpb25zLnVzZXJdXG4gICAgICAgIDogW10sXG4gICAgICAuLi5mbGF0dGVuKHZvbHVtZXMubWFwKHYgPT4gWyctdicsIGAke3YuaG9zdFBhdGh9OiR7di5jb250YWluZXJQYXRofToke2lzU2VMaW51eCgpID8gJ3osJyA6ICcnfSR7di5jb25zaXN0ZW5jeSA/PyBEb2NrZXJWb2x1bWVDb25zaXN0ZW5jeS5ERUxFR0FURUR9YF0pKSxcbiAgICAgIC4uLmZsYXR0ZW4oT2JqZWN0LmVudHJpZXMoZW52aXJvbm1lbnQpLm1hcCgoW2ssIHZdKSA9PiBbJy0tZW52JywgYCR7a309JHt2fWBdKSksXG4gICAgICAuLi5vcHRpb25zLndvcmtpbmdEaXJlY3RvcnlcbiAgICAgICAgPyBbJy13Jywgb3B0aW9ucy53b3JraW5nRGlyZWN0b3J5XVxuICAgICAgICA6IFtdLFxuICAgICAgLi4uZW50cnlwb2ludFxuICAgICAgICA/IFsnLS1lbnRyeXBvaW50JywgZW50cnlwb2ludF1cbiAgICAgICAgOiBbXSxcbiAgICAgIHRoaXMuaW1hZ2UsXG4gICAgICAuLi5jb21tYW5kLFxuICAgIF07XG5cbiAgICBkb2NrZXJFeGVjKGRvY2tlckFyZ3MpO1xuICB9XG5cbiAgLyoqXG4gICAqIENvcGllcyBhIGZpbGUgb3IgZGlyZWN0b3J5IG91dCBvZiB0aGUgRG9ja2VyIGltYWdlIHRvIHRoZSBsb2NhbCBmaWxlc3lzdGVtLlxuICAgKlxuICAgKiBJZiBgb3V0cHV0UGF0aGAgaXMgb21pdHRlZCB0aGUgZGVzdGluYXRpb24gcGF0aCBpcyBhIHRlbXBvcmFyeSBkaXJlY3RvcnkuXG4gICAqXG4gICAqIEBwYXJhbSBpbWFnZVBhdGggdGhlIHBhdGggaW4gdGhlIERvY2tlciBpbWFnZVxuICAgKiBAcGFyYW0gb3V0cHV0UGF0aCB0aGUgZGVzdGluYXRpb24gcGF0aCBmb3IgdGhlIGNvcHkgb3BlcmF0aW9uXG4gICAqIEByZXR1cm5zIHRoZSBkZXN0aW5hdGlvbiBwYXRoXG4gICAqL1xuICBwdWJsaWMgY3AoaW1hZ2VQYXRoOiBzdHJpbmcsIG91dHB1dFBhdGg/OiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIGNvbnN0IHsgc3Rkb3V0IH0gPSBkb2NrZXJFeGVjKFsnY3JlYXRlJywgdGhpcy5pbWFnZV0sIHt9KTsgLy8gRW1wdHkgb3B0aW9ucyB0byBhdm9pZCBzdGRvdXQgcmVkaXJlY3QgaGVyZVxuICAgIGNvbnN0IG1hdGNoID0gc3Rkb3V0LnRvU3RyaW5nKCkubWF0Y2goLyhbMC05YS1mXXsxNix9KS8pO1xuICAgIGlmICghbWF0Y2gpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignRmFpbGVkIHRvIGV4dHJhY3QgY29udGFpbmVyIElEIGZyb20gRG9ja2VyIGNyZWF0ZSBvdXRwdXQnKTtcbiAgICB9XG5cbiAgICBjb25zdCBjb250YWluZXJJZCA9IG1hdGNoWzFdO1xuICAgIGNvbnN0IGNvbnRhaW5lclBhdGggPSBgJHtjb250YWluZXJJZH06JHtpbWFnZVBhdGh9YDtcbiAgICBjb25zdCBkZXN0UGF0aCA9IG91dHB1dFBhdGggPz8gRmlsZVN5c3RlbS5ta2R0ZW1wKCdjZGstZG9ja2VyLWNwLScpO1xuICAgIHRyeSB7XG4gICAgICBkb2NrZXJFeGVjKFsnY3AnLCBjb250YWluZXJQYXRoLCBkZXN0UGF0aF0pO1xuICAgICAgcmV0dXJuIGRlc3RQYXRoO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBGYWlsZWQgdG8gY29weSBmaWxlcyBmcm9tICR7Y29udGFpbmVyUGF0aH0gdG8gJHtkZXN0UGF0aH06ICR7ZXJyfWApO1xuICAgIH0gZmluYWxseSB7XG4gICAgICBkb2NrZXJFeGVjKFsncm0nLCAnLXYnLCBjb250YWluZXJJZF0pO1xuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIEEgRG9ja2VyIGltYWdlXG4gKi9cbmV4cG9ydCBjbGFzcyBEb2NrZXJJbWFnZSBleHRlbmRzIEJ1bmRsaW5nRG9ja2VySW1hZ2Uge1xuICAvKipcbiAgICogQnVpbGRzIGEgRG9ja2VyIGltYWdlXG4gICAqXG4gICAqIEBwYXJhbSBwYXRoIFRoZSBwYXRoIHRvIHRoZSBkaXJlY3RvcnkgY29udGFpbmluZyB0aGUgRG9ja2VyIGZpbGVcbiAgICogQHBhcmFtIG9wdGlvbnMgRG9ja2VyIGJ1aWxkIG9wdGlvbnNcbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgZnJvbUJ1aWxkKHBhdGg6IHN0cmluZywgb3B0aW9uczogRG9ja2VyQnVpbGRPcHRpb25zID0ge30pIHtcbiAgICBjb25zdCBidWlsZEFyZ3MgPSBvcHRpb25zLmJ1aWxkQXJncyB8fCB7fTtcblxuICAgIGlmIChvcHRpb25zLmZpbGUgJiYgaXNBYnNvbHV0ZShvcHRpb25zLmZpbGUpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYFwiZmlsZVwiIG11c3QgYmUgcmVsYXRpdmUgdG8gdGhlIGRvY2tlciBidWlsZCBkaXJlY3RvcnkuIEdvdCAke29wdGlvbnMuZmlsZX1gKTtcbiAgICB9XG5cbiAgICAvLyBJbWFnZSB0YWcgZGVyaXZlZCBmcm9tIHBhdGggYW5kIGJ1aWxkIG9wdGlvbnNcbiAgICBjb25zdCBpbnB1dCA9IEpTT04uc3RyaW5naWZ5KHsgcGF0aCwgLi4ub3B0aW9ucyB9KTtcbiAgICBjb25zdCB0YWdIYXNoID0gY3J5cHRvLmNyZWF0ZUhhc2goJ3NoYTI1NicpLnVwZGF0ZShpbnB1dCkuZGlnZXN0KCdoZXgnKTtcbiAgICBjb25zdCB0YWcgPSBgY2RrLSR7dGFnSGFzaH1gO1xuXG4gICAgY29uc3QgZG9ja2VyQXJnczogc3RyaW5nW10gPSBbXG4gICAgICAnYnVpbGQnLCAnLXQnLCB0YWcsXG4gICAgICAuLi4ob3B0aW9ucy5maWxlID8gWyctZicsIGpvaW4ocGF0aCwgb3B0aW9ucy5maWxlKV0gOiBbXSksXG4gICAgICAuLi4ob3B0aW9ucy5wbGF0Zm9ybSA/IFsnLS1wbGF0Zm9ybScsIG9wdGlvbnMucGxhdGZvcm1dIDogW10pLFxuICAgICAgLi4uZmxhdHRlbihPYmplY3QuZW50cmllcyhidWlsZEFyZ3MpLm1hcCgoW2ssIHZdKSA9PiBbJy0tYnVpbGQtYXJnJywgYCR7a309JHt2fWBdKSksXG4gICAgICBwYXRoLFxuICAgIF07XG5cbiAgICBkb2NrZXJFeGVjKGRvY2tlckFyZ3MpO1xuXG4gICAgLy8gRmluZ2VycHJpbnRzIHRoZSBkaXJlY3RvcnkgY29udGFpbmluZyB0aGUgRG9ja2VyZmlsZSB3ZSdyZSBidWlsZGluZyBhbmRcbiAgICAvLyBkaWZmZXJlbnRpYXRlcyB0aGUgZmluZ2VycHJpbnQgYmFzZWQgb24gYnVpbGQgYXJndW1lbnRzLiBXZSBkbyB0aGlzIHNvXG4gICAgLy8gd2UgY2FuIHByb3ZpZGUgYSBzdGFibGUgaW1hZ2UgaGFzaC4gT3RoZXJ3aXNlLCB0aGUgaW1hZ2UgSUQgd2lsbCBiZVxuICAgIC8vIGRpZmZlcmVudCBldmVyeSB0aW1lIHRoZSBEb2NrZXIgbGF5ZXIgY2FjaGUgaXMgY2xlYXJlZCwgZHVlIHByaW1hcmlseSB0b1xuICAgIC8vIHRpbWVzdGFtcHMuXG4gICAgY29uc3QgaGFzaCA9IEZpbGVTeXN0ZW0uZmluZ2VycHJpbnQocGF0aCwgeyBleHRyYUhhc2g6IEpTT04uc3RyaW5naWZ5KG9wdGlvbnMpIH0pO1xuICAgIHJldHVybiBuZXcgRG9ja2VySW1hZ2UodGFnLCBoYXNoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZWZlcmVuY2UgYW4gaW1hZ2Ugb24gRG9ja2VySHViIG9yIGFub3RoZXIgb25saW5lIHJlZ2lzdHJ5LlxuICAgKlxuICAgKiBAcGFyYW0gaW1hZ2UgdGhlIGltYWdlIG5hbWVcbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgZnJvbVJlZ2lzdHJ5KGltYWdlOiBzdHJpbmcpIHtcbiAgICByZXR1cm4gbmV3IERvY2tlckltYWdlKGltYWdlKTtcbiAgfVxuXG4gIC8qKiBUaGUgRG9ja2VyIGltYWdlICovXG4gIHB1YmxpYyByZWFkb25seSBpbWFnZTogc3RyaW5nO1xuXG4gIGNvbnN0cnVjdG9yKGltYWdlOiBzdHJpbmcsIF9pbWFnZUhhc2g/OiBzdHJpbmcpIHtcbiAgICAvLyBJdCBpcyBwcmVmZXJyYWJsZSBmb3IgdGhlIGRlcHJlY2F0ZWQgY2xhc3MgdG8gaW5oZXJpdCBhIG5vbi1kZXByZWNhdGVkIGNsYXNzLlxuICAgIC8vIEhvd2V2ZXIsIGluIHRoaXMgY2FzZSwgdGhlIG9wcG9zaXRlIGhhcyBvY2N1cnJlZCB3aGljaCBpcyBpbmNvbXBhdGlibGUgd2l0aFxuICAgIC8vIGEgZGVwcmVjYXRpb24gZmVhdHVyZS4gU2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9hd3MvanNpaS9pc3N1ZXMvMzEwMi5cbiAgICBjb25zdCBkZXByZWNhdGVkID0gcXVpZXQoKTtcblxuICAgIHN1cGVyKGltYWdlLCBfaW1hZ2VIYXNoKTtcblxuICAgIHJlc2V0KGRlcHJlY2F0ZWQpO1xuICAgIHRoaXMuaW1hZ2UgPSBpbWFnZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBQcm92aWRlcyBhIHN0YWJsZSByZXByZXNlbnRhdGlvbiBvZiB0aGlzIGltYWdlIGZvciBKU09OIHNlcmlhbGl6YXRpb24uXG4gICAqXG4gICAqIEByZXR1cm4gVGhlIG92ZXJyaWRkZW4gaW1hZ2UgbmFtZSBpZiBzZXQgb3IgaW1hZ2UgaGFzaCBuYW1lIGluIHRoYXQgb3JkZXJcbiAgICovXG4gIHB1YmxpYyB0b0pTT04oKSB7XG4gICAgLy8gSXQgaXMgcHJlZmVycmFibGUgZm9yIHRoZSBkZXByZWNhdGVkIGNsYXNzIHRvIGluaGVyaXQgYSBub24tZGVwcmVjYXRlZCBjbGFzcy5cbiAgICAvLyBIb3dldmVyLCBpbiB0aGlzIGNhc2UsIHRoZSBvcHBvc2l0ZSBoYXMgb2NjdXJyZWQgd2hpY2ggaXMgaW5jb21wYXRpYmxlIHdpdGhcbiAgICAvLyBhIGRlcHJlY2F0aW9uIGZlYXR1cmUuIFNlZSBodHRwczovL2dpdGh1Yi5jb20vYXdzL2pzaWkvaXNzdWVzLzMxMDIuXG4gICAgY29uc3QgZGVwcmVjYXRlZCA9IHF1aWV0KCk7XG5cbiAgICBjb25zdCBqc29uID0gc3VwZXIudG9KU09OKCk7XG5cbiAgICByZXNldChkZXByZWNhdGVkKTtcbiAgICByZXR1cm4ganNvbjtcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGEgRG9ja2VyIGltYWdlXG4gICAqL1xuICBwdWJsaWMgcnVuKG9wdGlvbnM6IERvY2tlclJ1bk9wdGlvbnMgPSB7fSkge1xuICAgIC8vIEl0IGlzIHByZWZlcnJhYmxlIGZvciB0aGUgZGVwcmVjYXRlZCBjbGFzcyB0byBpbmhlcml0IGEgbm9uLWRlcHJlY2F0ZWQgY2xhc3MuXG4gICAgLy8gSG93ZXZlciwgaW4gdGhpcyBjYXNlLCB0aGUgb3Bwb3NpdGUgaGFzIG9jY3VycmVkIHdoaWNoIGlzIGluY29tcGF0aWJsZSB3aXRoXG4gICAgLy8gYSBkZXByZWNhdGlvbiBmZWF0dXJlLiBTZWUgaHR0cHM6Ly9naXRodWIuY29tL2F3cy9qc2lpL2lzc3Vlcy8zMTAyLlxuICAgIGNvbnN0IGRlcHJlY2F0ZWQgPSBxdWlldCgpO1xuXG4gICAgY29uc3QgcmVzdWx0ID0gc3VwZXIucnVuKG9wdGlvbnMpO1xuXG4gICAgcmVzZXQoZGVwcmVjYXRlZCk7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIC8qKlxuICAgKiBDb3BpZXMgYSBmaWxlIG9yIGRpcmVjdG9yeSBvdXQgb2YgdGhlIERvY2tlciBpbWFnZSB0byB0aGUgbG9jYWwgZmlsZXN5c3RlbS5cbiAgICpcbiAgICogSWYgYG91dHB1dFBhdGhgIGlzIG9taXR0ZWQgdGhlIGRlc3RpbmF0aW9uIHBhdGggaXMgYSB0ZW1wb3JhcnkgZGlyZWN0b3J5LlxuICAgKlxuICAgKiBAcGFyYW0gaW1hZ2VQYXRoIHRoZSBwYXRoIGluIHRoZSBEb2NrZXIgaW1hZ2VcbiAgICogQHBhcmFtIG91dHB1dFBhdGggdGhlIGRlc3RpbmF0aW9uIHBhdGggZm9yIHRoZSBjb3B5IG9wZXJhdGlvblxuICAgKiBAcmV0dXJucyB0aGUgZGVzdGluYXRpb24gcGF0aFxuICAgKi9cbiAgcHVibGljIGNwKGltYWdlUGF0aDogc3RyaW5nLCBvdXRwdXRQYXRoPzogc3RyaW5nKTogc3RyaW5nIHtcbiAgICAvLyBJdCBpcyBwcmVmZXJyYWJsZSBmb3IgdGhlIGRlcHJlY2F0ZWQgY2xhc3MgdG8gaW5oZXJpdCBhIG5vbi1kZXByZWNhdGVkIGNsYXNzLlxuICAgIC8vIEhvd2V2ZXIsIGluIHRoaXMgY2FzZSwgdGhlIG9wcG9zaXRlIGhhcyBvY2N1cnJlZCB3aGljaCBpcyBpbmNvbXBhdGlibGUgd2l0aFxuICAgIC8vIGEgZGVwcmVjYXRpb24gZmVhdHVyZS4gU2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9hd3MvanNpaS9pc3N1ZXMvMzEwMi5cbiAgICBjb25zdCBkZXByZWNhdGVkID0gcXVpZXQoKTtcblxuICAgIGNvbnN0IHJlc3VsdCA9IHN1cGVyLmNwKGltYWdlUGF0aCwgb3V0cHV0UGF0aCk7XG5cbiAgICByZXNldChkZXByZWNhdGVkKTtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG59XG5cbi8qKlxuICogQSBEb2NrZXIgdm9sdW1lXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgRG9ja2VyVm9sdW1lIHtcbiAgLyoqXG4gICAqIFRoZSBwYXRoIHRvIHRoZSBmaWxlIG9yIGRpcmVjdG9yeSBvbiB0aGUgaG9zdCBtYWNoaW5lXG4gICAqL1xuICByZWFkb25seSBob3N0UGF0aDogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaGUgcGF0aCB3aGVyZSB0aGUgZmlsZSBvciBkaXJlY3RvcnkgaXMgbW91bnRlZCBpbiB0aGUgY29udGFpbmVyXG4gICAqL1xuICByZWFkb25seSBjb250YWluZXJQYXRoOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIE1vdW50IGNvbnNpc3RlbmN5LiBPbmx5IGFwcGxpY2FibGUgZm9yIG1hY09TXG4gICAqXG4gICAqIEBkZWZhdWx0IERvY2tlckNvbnNpc3RlbmN5LkRFTEVHQVRFRFxuICAgKiBAc2VlIGh0dHBzOi8vZG9jcy5kb2NrZXIuY29tL3N0b3JhZ2UvYmluZC1tb3VudHMvI2NvbmZpZ3VyZS1tb3VudC1jb25zaXN0ZW5jeS1mb3ItbWFjb3NcbiAgICovXG4gIHJlYWRvbmx5IGNvbnNpc3RlbmN5PzogRG9ja2VyVm9sdW1lQ29uc2lzdGVuY3k7XG59XG5cbi8qKlxuICogU3VwcG9ydGVkIERvY2tlciB2b2x1bWUgY29uc2lzdGVuY3kgdHlwZXMuIE9ubHkgdmFsaWQgb24gbWFjT1MgZHVlIHRvIHRoZSB3YXkgZmlsZSBzdG9yYWdlIHdvcmtzIG9uIE1hY1xuICovXG5leHBvcnQgZW51bSBEb2NrZXJWb2x1bWVDb25zaXN0ZW5jeSB7XG4gIC8qKlxuICAgKiBSZWFkL3dyaXRlIG9wZXJhdGlvbnMgaW5zaWRlIHRoZSBEb2NrZXIgY29udGFpbmVyIGFyZSBhcHBsaWVkIGltbWVkaWF0ZWx5IG9uIHRoZSBtb3VudGVkIGhvc3QgbWFjaGluZSB2b2x1bWVzXG4gICAqL1xuICBDT05TSVNURU5UID0gJ2NvbnNpc3RlbnQnLFxuICAvKipcbiAgICogUmVhZC93cml0ZSBvcGVyYXRpb25zIG9uIG1vdW50ZWQgRG9ja2VyIHZvbHVtZXMgYXJlIGZpcnN0IHdyaXR0ZW4gaW5zaWRlIHRoZSBjb250YWluZXIgYW5kIHRoZW4gc3luY2hyb25pemVkIHRvIHRoZSBob3N0IG1hY2hpbmVcbiAgICovXG4gIERFTEVHQVRFRCA9ICdkZWxlZ2F0ZWQnLFxuICAvKipcbiAgICogUmVhZC93cml0ZSBvcGVyYXRpb25zIG9uIG1vdW50ZWQgRG9ja2VyIHZvbHVtZXMgYXJlIGZpcnN0IGFwcGxpZWQgb24gdGhlIGhvc3QgbWFjaGluZSBhbmQgdGhlbiBzeW5jaHJvbml6ZWQgdG8gdGhlIGNvbnRhaW5lclxuICAgKi9cbiAgQ0FDSEVEID0gJ2NhY2hlZCcsXG59XG5cbi8qKlxuICogRG9ja2VyIHJ1biBvcHRpb25zXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgRG9ja2VyUnVuT3B0aW9ucyB7XG4gIC8qKlxuICAgKiBUaGUgZW50cnlwb2ludCB0byBydW4gaW4gdGhlIGNvbnRhaW5lci5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBydW4gdGhlIGVudHJ5cG9pbnQgZGVmaW5lZCBpbiB0aGUgaW1hZ2VcbiAgICovXG4gIHJlYWRvbmx5IGVudHJ5cG9pbnQ/OiBzdHJpbmdbXTtcblxuICAvKipcbiAgICogVGhlIGNvbW1hbmQgdG8gcnVuIGluIHRoZSBjb250YWluZXIuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gcnVuIHRoZSBjb21tYW5kIGRlZmluZWQgaW4gdGhlIGltYWdlXG4gICAqL1xuICByZWFkb25seSBjb21tYW5kPzogc3RyaW5nW107XG5cbiAgLyoqXG4gICAqIERvY2tlciB2b2x1bWVzIHRvIG1vdW50LlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIG5vIHZvbHVtZXMgYXJlIG1vdW50ZWRcbiAgICovXG4gIHJlYWRvbmx5IHZvbHVtZXM/OiBEb2NrZXJWb2x1bWVbXTtcblxuICAvKipcbiAgICogVGhlIGVudmlyb25tZW50IHZhcmlhYmxlcyB0byBwYXNzIHRvIHRoZSBjb250YWluZXIuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gbm8gZW52aXJvbm1lbnQgdmFyaWFibGVzLlxuICAgKi9cbiAgcmVhZG9ubHkgZW52aXJvbm1lbnQ/OiB7IFtrZXk6IHN0cmluZ106IHN0cmluZzsgfTtcblxuICAvKipcbiAgICogV29ya2luZyBkaXJlY3RvcnkgaW5zaWRlIHRoZSBjb250YWluZXIuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gaW1hZ2UgZGVmYXVsdFxuICAgKi9cbiAgcmVhZG9ubHkgd29ya2luZ0RpcmVjdG9yeT86IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIHVzZXIgdG8gdXNlIHdoZW4gcnVubmluZyB0aGUgY29udGFpbmVyLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIHJvb3Qgb3IgaW1hZ2UgZGVmYXVsdFxuICAgKi9cbiAgcmVhZG9ubHkgdXNlcj86IHN0cmluZztcblxuICAvKipcbiAgICogW1NlY3VyaXR5IGNvbmZpZ3VyYXRpb25dKGh0dHBzOi8vZG9jcy5kb2NrZXIuY29tL2VuZ2luZS9yZWZlcmVuY2UvcnVuLyNzZWN1cml0eS1jb25maWd1cmF0aW9uKVxuICAgKiB3aGVuIHJ1bm5pbmcgdGhlIGRvY2tlciBjb250YWluZXIuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gbm8gc2VjdXJpdHkgb3B0aW9uc1xuICAgKi9cbiAgcmVhZG9ubHkgc2VjdXJpdHlPcHQ/OiBzdHJpbmc7XG59XG5cbi8qKlxuICogRG9ja2VyIGJ1aWxkIG9wdGlvbnNcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBEb2NrZXJCdWlsZE9wdGlvbnMge1xuICAvKipcbiAgICogQnVpbGQgYXJnc1xuICAgKlxuICAgKiBAZGVmYXVsdCAtIG5vIGJ1aWxkIGFyZ3NcbiAgICovXG4gIHJlYWRvbmx5IGJ1aWxkQXJncz86IHsgW2tleTogc3RyaW5nXTogc3RyaW5nIH07XG5cbiAgLyoqXG4gICAqIE5hbWUgb2YgdGhlIERvY2tlcmZpbGUsIG11c3QgcmVsYXRpdmUgdG8gdGhlIGRvY2tlciBidWlsZCBwYXRoLlxuICAgKlxuICAgKiBAZGVmYXVsdCBgRG9ja2VyZmlsZWBcbiAgICovXG4gIHJlYWRvbmx5IGZpbGU/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFNldCBwbGF0Zm9ybSBpZiBzZXJ2ZXIgaXMgbXVsdGktcGxhdGZvcm0gY2FwYWJsZS4gX1JlcXVpcmVzIERvY2tlciBFbmdpbmUgQVBJIHYxLjM4K18uXG4gICAqXG4gICAqIEV4YW1wbGUgdmFsdWU6IGBsaW51eC9hbWQ2NGBcbiAgICpcbiAgICogQGRlZmF1bHQgLSBubyBwbGF0Zm9ybSBzcGVjaWZpZWRcbiAgICovXG4gIHJlYWRvbmx5IHBsYXRmb3JtPzogc3RyaW5nO1xufVxuXG5mdW5jdGlvbiBmbGF0dGVuKHg6IHN0cmluZ1tdW10pIHtcbiAgcmV0dXJuIEFycmF5LnByb3RvdHlwZS5jb25jYXQoW10sIC4uLngpO1xufVxuXG5mdW5jdGlvbiBkb2NrZXJFeGVjKGFyZ3M6IHN0cmluZ1tdLCBvcHRpb25zPzogU3Bhd25TeW5jT3B0aW9ucykge1xuICBjb25zdCBwcm9nID0gcHJvY2Vzcy5lbnYuQ0RLX0RPQ0tFUiA/PyAnZG9ja2VyJztcbiAgY29uc3QgcHJvYyA9IHNwYXduU3luYyhwcm9nLCBhcmdzLCBvcHRpb25zID8/IHtcbiAgICBzdGRpbzogWyAvLyBzaG93IERvY2tlciBvdXRwdXRcbiAgICAgICdpZ25vcmUnLCAvLyBpZ25vcmUgc3RkaW9cbiAgICAgIHByb2Nlc3Muc3RkZXJyLCAvLyByZWRpcmVjdCBzdGRvdXQgdG8gc3RkZXJyXG4gICAgICAnaW5oZXJpdCcsIC8vIGluaGVyaXQgc3RkZXJyXG4gICAgXSxcbiAgfSk7XG5cbiAgaWYgKHByb2MuZXJyb3IpIHtcbiAgICB0aHJvdyBwcm9jLmVycm9yO1xuICB9XG5cbiAgaWYgKHByb2Muc3RhdHVzICE9PSAwKSB7XG4gICAgaWYgKHByb2Muc3Rkb3V0IHx8IHByb2Muc3RkZXJyKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYFtTdGF0dXMgJHtwcm9jLnN0YXR1c31dIHN0ZG91dDogJHtwcm9jLnN0ZG91dD8udG9TdHJpbmcoKS50cmltKCl9XFxuXFxuXFxuc3RkZXJyOiAke3Byb2Muc3RkZXJyPy50b1N0cmluZygpLnRyaW0oKX1gKTtcbiAgICB9XG4gICAgdGhyb3cgbmV3IEVycm9yKGAke3Byb2d9IGV4aXRlZCB3aXRoIHN0YXR1cyAke3Byb2Muc3RhdHVzfWApO1xuICB9XG5cbiAgcmV0dXJuIHByb2M7XG59XG5cbmZ1bmN0aW9uIGlzU2VMaW51eCgpIDogYm9vbGVhbiB7XG4gIGlmIChwcm9jZXNzLnBsYXRmb3JtICE9ICdsaW51eCcpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgY29uc3QgcHJvZyA9ICdzZWxpbnV4ZW5hYmxlZCc7XG4gIGNvbnN0IHByb2MgPSBzcGF3blN5bmMocHJvZywgW10sIHtcbiAgICBzdGRpbzogWyAvLyBzaG93IHNlbGludXggc3RhdHVzIG91dHB1dFxuICAgICAgJ3BpcGUnLCAvLyBnZXQgdmFsdWUgb2Ygc3RkaW9cbiAgICAgIHByb2Nlc3Muc3RkZXJyLCAvLyByZWRpcmVjdCBzdGRvdXQgdG8gc3RkZXJyXG4gICAgICAnaW5oZXJpdCcsIC8vIGluaGVyaXQgc3RkZXJyXG4gICAgXSxcbiAgfSk7XG4gIGlmIChwcm9jLmVycm9yKSB7XG4gICAgLy8gc2VsaW51eGVuYWJsZWQgbm90IGEgdmFsaWQgY29tbWFuZCwgdGhlcmVmb3JlIG5vdCBlbmFibGVkXG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIGlmIChwcm9jLnN0YXR1cyA9PSAwKSB7XG4gICAgLy8gc2VsaW51eCBlbmFibGVkXG4gICAgcmV0dXJuIHRydWU7XG4gIH0gZWxzZSB7XG4gICAgLy8gc2VsaW51eCBub3QgZW5hYmxlZFxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxufVxuIl19 |
\ | No newline at end of file |