UNPKG

44.7 kBJavaScriptView Raw
1"use strict";
2var _a, _b;
3Object.defineProperty(exports, "__esModule", { value: true });
4exports.DockerVolumeConsistency = exports.DockerImage = exports.BundlingDockerImage = exports.BundlingOutput = void 0;
5const jsiiDeprecationWarnings = require("../.warnings.jsii.js");
6const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
7const child_process_1 = require("child_process");
8const crypto = require("crypto");
9const path_1 = require("path");
10const fs_1 = require("./fs");
11const jsii_deprecated_1 = require("./private/jsii-deprecated");
12/**
13 * The type of output that a bundling operation is producing.
14 *
15 */
16var 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 */
40class 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}
195exports.BundlingDockerImage = BundlingDockerImage;
196_a = JSII_RTTI_SYMBOL_1;
197BundlingDockerImage[_a] = { fqn: "@aws-cdk/core.BundlingDockerImage", version: "1.204.0" };
198/**
199 * A Docker image
200 */
201class 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}
313exports.DockerImage = DockerImage;
314_b = JSII_RTTI_SYMBOL_1;
315DockerImage[_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 */
319var 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 = {}));
334function flatten(x) {
335 return Array.prototype.concat([], ...x);
336}
337function 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}
357function 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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYnVuZGxpbmcuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJidW5kbGluZy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7QUFBQSxpREFBNEQ7QUFDNUQsaUNBQWlDO0FBQ2pDLCtCQUF3QztBQUN4Qyw2QkFBa0M7QUFDbEMsK0RBQXlEO0FBK0Z6RDs7O0dBR0c7QUFDSCxJQUFZLGNBbUJYO0FBbkJELFdBQVksY0FBYztJQUN4Qjs7OztPQUlHO0lBQ0gsdUNBQXFCLENBQUE7SUFFckI7OztPQUdHO0lBQ0gsK0NBQTZCLENBQUE7SUFFN0I7OztPQUdHO0lBQ0gsaURBQStCLENBQUE7QUFDakMsQ0FBQyxFQW5CVyxjQUFjLEdBQWQsc0JBQWMsS0FBZCxzQkFBYyxRQW1CekI7QUFrQkQ7Ozs7R0FJRztBQUNILE1BQWEsbUJBQW1CO0lBc0I5QixvQ0FBb0M7SUFDcEMsWUFBc0MsS0FBYSxFQUFtQixVQUFtQjtRQUFuRCxVQUFLLEdBQUwsS0FBSyxDQUFRO1FBQW1CLGVBQVUsR0FBVixVQUFVLENBQVM7Ozs7OzsrQ0F2QjlFLG1CQUFtQjs7OztLQXVCK0Q7SUF0QjdGOzs7O09BSUc7SUFDSSxNQUFNLENBQUMsWUFBWSxDQUFDLEtBQWE7Ozs7Ozs7Ozs7UUFDdEMsT0FBTyxJQUFJLFdBQVcsQ0FBQyxLQUFLLENBQUMsQ0FBQztLQUMvQjtJQUVEOzs7Ozs7O09BT0c7SUFDSSxNQUFNLENBQUMsU0FBUyxDQUFDLElBQVksRUFBRSxVQUE4QixFQUFFOzs7Ozs7Ozs7OztRQUNwRSxPQUFPLFdBQVcsQ0FBQyxTQUFTLENBQUMsSUFBSSxFQUFFLE9BQU8sQ0FBQyxDQUFDO0tBQzdDO0lBS0Q7Ozs7T0FJRztJQUNJLE1BQU07Ozs7Ozs7Ozs7UUFDWCxPQUFPLElBQUksQ0FBQyxVQUFVLElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQztLQUN0QztJQUVEOztPQUVHO0lBQ0ksR0FBRyxDQUFDLFVBQTRCLEVBQUU7Ozs7Ozs7Ozs7O1FBQ3ZDLE1BQU0sT0FBTyxHQUFHLE9BQU8sQ0FBQyxPQUFPLElBQUksRUFBRSxDQUFDO1FBQ3RDLE1BQU0sV0FBVyxHQUFHLE9BQU8sQ0FBQyxXQUFXLElBQUksRUFBRSxDQUFDO1FBQzlDLE1BQU0sVUFBVSxHQUFHLE9BQU8sQ0FBQyxVQUFVLEVBQUUsQ0FBQyxDQUFDLENBQUMsSUFBSSxJQUFJLENBQUM7UUFDbkQsTUFBTSxPQUFPLEdBQUc7WUFDZCxHQUFHLE9BQU8sQ0FBQyxVQUFVLEVBQUUsQ0FBQyxDQUFDLENBQUM7Z0JBQ3hCLENBQUMsQ0FBQyxDQUFDLEdBQUcsT0FBTyxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBQ2xDLENBQUMsQ0FBQyxFQUFFO1lBQ04sR0FBRyxPQUFPLENBQUMsT0FBTztnQkFDaEIsQ0FBQyxDQUFDLENBQUMsR0FBRyxPQUFPLENBQUMsT0FBTyxDQUFDO2dCQUN0QixDQUFDLENBQUMsRUFBRTtTQUNQLENBQUM7UUFFRixNQUFNLFVBQVUsR0FBYTtZQUMzQixLQUFLLEVBQUUsTUFBTTtZQUNiLEdBQUcsT0FBTyxDQUFDLFdBQVc7Z0JBQ3BCLENBQUMsQ0FBQyxDQUFDLGdCQUFnQixFQUFFLE9BQU8sQ0FBQyxXQUFXLENBQUM7Z0JBQ3pDLENBQUMsQ0FBQyxFQUFFO1lBQ04sR0FBRyxPQUFPLENBQUMsSUFBSTtnQkFDYixDQUFDLENBQUMsQ0FBQyxJQUFJLEVBQUUsT0FBTyxDQUFDLElBQUksQ0FBQztnQkFDdEIsQ0FBQyxDQUFDLEVBQUU7WUFDTixHQUFHLE9BQU8sQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxJQUFJLEVBQUUsR0FBRyxDQUFDLENBQUMsUUFBUSxJQUFJLENBQUMsQ0FBQyxhQUFhLElBQUksU0FBUyxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQyxXQUFXLElBQUksdUJBQXVCLENBQUMsU0FBUyxFQUFFLENBQUMsQ0FBQyxDQUFDO1lBQ3hKLEdBQUcsT0FBTyxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsV0FBVyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsT0FBTyxFQUFFLEdBQUcsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztZQUMvRSxHQUFHLE9BQU8sQ0FBQyxnQkFBZ0I7Z0JBQ3pCLENBQUMsQ0FBQyxDQUFDLElBQUksRUFBRSxPQUFPLENBQUMsZ0JBQWdCLENBQUM7Z0JBQ2xDLENBQUMsQ0FBQyxFQUFFO1lBQ04sR0FBRyxVQUFVO2dCQUNYLENBQUMsQ0FBQyxDQUFDLGNBQWMsRUFBRSxVQUFVLENBQUM7Z0JBQzlCLENBQUMsQ0FBQyxFQUFFO1lBQ04sSUFBSSxDQUFDLEtBQUs7WUFDVixHQUFHLE9BQU87U0FDWCxDQUFDO1FBRUYsVUFBVSxDQUFDLFVBQVUsQ0FBQyxDQUFDO0tBQ3hCO0lBRUQ7Ozs7Ozs7O09BUUc7SUFDSSxFQUFFLENBQUMsU0FBaUIsRUFBRSxVQUFtQjs7Ozs7Ozs7OztRQUM5QyxNQUFNLEVBQUUsTUFBTSxFQUFFLEdBQUcsVUFBVSxDQUFDLENBQUMsUUFBUSxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLDhDQUE4QztRQUN6RyxNQUFNLEtBQUssR0FBRyxNQUFNLENBQUMsUUFBUSxFQUFFLENBQUMsS0FBSyxDQUFDLGlCQUFpQixDQUFDLENBQUM7UUFDekQsSUFBSSxDQUFDLEtBQUssRUFBRTtZQUNWLE1BQU0sSUFBSSxLQUFLLENBQUMsMERBQTBELENBQUMsQ0FBQztTQUM3RTtRQUVELE1BQU0sV0FBVyxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUM3QixNQUFNLGFBQWEsR0FBRyxHQUFHLFdBQVcsSUFBSSxTQUFTLEVBQUUsQ0FBQztRQUNwRCxNQUFNLFFBQVEsR0FBRyxVQUFVLElBQUksZUFBVSxDQUFDLE9BQU8sQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO1FBQ3BFLElBQUk7WUFDRixVQUFVLENBQUMsQ0FBQyxJQUFJLEVBQUUsYUFBYSxFQUFFLFFBQVEsQ0FBQyxDQUFDLENBQUM7WUFDNUMsT0FBTyxRQUFRLENBQUM7U0FDakI7UUFBQyxPQUFPLEdBQUcsRUFBRTtZQUNaLE1BQU0sSUFBSSxLQUFLLENBQUMsNkJBQTZCLGFBQWEsT0FBTyxRQUFRLEtBQUssR0FBRyxFQUFFLENBQUMsQ0FBQztTQUN0RjtnQkFBUztZQUNSLFVBQVUsQ0FBQyxDQUFDLElBQUksRUFBRSxJQUFJLEVBQUUsV0FBVyxDQUFDLENBQUMsQ0FBQztTQUN2QztLQUNGOztBQXBHSCxrREFxR0M7OztBQUVEOztHQUVHO0FBQ0gsTUFBYSxXQUFZLFNBQVEsbUJBQW1CO0lBa0RsRCxZQUFZLEtBQWEsRUFBRSxVQUFtQjtRQUM1QyxnRkFBZ0Y7UUFDaEYsOEVBQThFO1FBQzlFLHNFQUFzRTtRQUN0RSxNQUFNLFVBQVUsR0FBRyx1QkFBSyxFQUFFLENBQUM7UUFFM0IsS0FBSyxDQUFDLEtBQUssRUFBRSxVQUFVLENBQUMsQ0FBQztRQUV6Qix1QkFBSyxDQUFDLFVBQVUsQ0FBQyxDQUFDO1FBQ2xCLElBQUksQ0FBQyxLQUFLLEdBQUcsS0FBSyxDQUFDO0tBQ3BCO0lBM0REOzs7OztPQUtHO0lBQ0ksTUFBTSxDQUFDLFNBQVMsQ0FBQyxJQUFZLEVBQUUsVUFBOEIsRUFBRTs7Ozs7Ozs7OztRQUNwRSxNQUFNLFNBQVMsR0FBRyxPQUFPLENBQUMsU0FBUyxJQUFJLEVBQUUsQ0FBQztRQUUxQyxJQUFJLE9BQU8sQ0FBQyxJQUFJLElBQUksaUJBQVUsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLEVBQUU7WUFDNUMsTUFBTSxJQUFJLEtBQUssQ0FBQyw4REFBOEQsT0FBTyxDQUFDLElBQUksRUFBRSxDQUFDLENBQUM7U0FDL0Y7UUFFRCxnREFBZ0Q7UUFDaEQsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxFQUFFLElBQUksRUFBRSxHQUFHLE9BQU8sRUFBRSxDQUFDLENBQUM7UUFDbkQsTUFBTSxPQUFPLEdBQUcsTUFBTSxDQUFDLFVBQVUsQ0FBQyxRQUFRLENBQUMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ3hFLE1BQU0sR0FBRyxHQUFHLE9BQU8sT0FBTyxFQUFFLENBQUM7UUFFN0IsTUFBTSxVQUFVLEdBQWE7WUFDM0IsT0FBTyxFQUFFLElBQUksRUFBRSxHQUFHO1lBQ2xCLEdBQUcsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksRUFBRSxXQUFJLENBQUMsSUFBSSxFQUFFLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7WUFDekQsR0FBRyxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUMsWUFBWSxFQUFFLE9BQU8sQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO1lBQzdELEdBQUcsT0FBTyxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsYUFBYSxFQUFFLEdBQUcsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztZQUNuRixJQUFJO1NBQ0wsQ0FBQztRQUVGLFVBQVUsQ0FBQyxVQUFVLENBQUMsQ0FBQztRQUV2QiwwRUFBMEU7UUFDMUUseUVBQXlFO1FBQ3pFLHNFQUFzRTtRQUN0RSwyRUFBMkU7UUFDM0UsY0FBYztRQUNkLE1BQU0sSUFBSSxHQUFHLGVBQVUsQ0FBQyxXQUFXLENBQUMsSUFBSSxFQUFFLEVBQUUsU0FBUyxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBQ2xGLE9BQU8sSUFBSSxXQUFXLENBQUMsR0FBRyxFQUFFLElBQUksQ0FBQyxDQUFDO0tBQ25DO0lBRUQ7Ozs7T0FJRztJQUNJLE1BQU0sQ0FBQyxZQUFZLENBQUMsS0FBYTtRQUN0QyxPQUFPLElBQUksV0FBVyxDQUFDLEtBQUssQ0FBQyxDQUFDO0tBQy9CO0lBaUJEOzs7O09BSUc7SUFDSSxNQUFNO1FBQ1gsZ0ZBQWdGO1FBQ2hGLDhFQUE4RTtRQUM5RSxzRUFBc0U7UUFDdEUsTUFBTSxVQUFVLEdBQUcsdUJBQUssRUFBRSxDQUFDO1FBRTNCLE1BQU0sSUFBSSxHQUFHLEtBQUssQ0FBQyxNQUFNLEVBQUUsQ0FBQztRQUU1Qix1QkFBSyxDQUFDLFVBQVUsQ0FBQyxDQUFDO1FBQ2xCLE9BQU8sSUFBSSxDQUFDO0tBQ2I7SUFFRDs7T0FFRztJQUNJLEdBQUcsQ0FBQyxVQUE0QixFQUFFOzs7Ozs7Ozs7O1FBQ3ZDLGdGQUFnRjtRQUNoRiw4RUFBOEU7UUFDOUUsc0VBQXNFO1FBQ3RFLE1BQU0sVUFBVSxHQUFHLHVCQUFLLEVBQUUsQ0FBQztRQUUzQixNQUFNLE1BQU0sR0FBRyxLQUFLLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBRWxDLHVCQUFLLENBQUMsVUFBVSxDQUFDLENBQUM7UUFDbEIsT0FBTyxNQUFNLENBQUM7S0FDZjtJQUVEOzs7Ozs7OztPQVFHO0lBQ0ksRUFBRSxDQUFDLFNBQWlCLEVBQUUsVUFBbUI7UUFDOUMsZ0ZBQWdGO1FBQ2hGLDhFQUE4RTtRQUM5RSxzRUFBc0U7UUFDdEUsTUFBTSxVQUFVLEdBQUcsdUJBQUssRUFBRSxDQUFDO1FBRTNCLE1BQU0sTUFBTSxHQUFHLEtBQUssQ0FBQyxFQUFFLENBQUMsU0FBUyxFQUFFLFVBQVUsQ0FBQyxDQUFDO1FBRS9DLHVCQUFLLENBQUMsVUFBVSxDQUFDLENBQUM7UUFDbEIsT0FBTyxNQUFNLENBQUM7S0FDZjs7QUFqSEgsa0NBa0hDOzs7QUF5QkQ7O0dBRUc7QUFDSCxJQUFZLHVCQWFYO0FBYkQsV0FBWSx1QkFBdUI7SUFDakM7O09BRUc7SUFDSCxvREFBeUIsQ0FBQTtJQUN6Qjs7T0FFRztJQUNILGtEQUF1QixDQUFBO0lBQ3ZCOztPQUVHO0lBQ0gsNENBQWlCLENBQUE7QUFDbkIsQ0FBQyxFQWJXLHVCQUF1QixHQUF2QiwrQkFBdUIsS0FBdkIsK0JBQXVCLFFBYWxDO0FBcUZELFNBQVMsT0FBTyxDQUFDLENBQWE7SUFDNUIsT0FBTyxLQUFLLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxFQUFFLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQztBQUMxQyxDQUFDO0FBRUQsU0FBUyxVQUFVLENBQUMsSUFBYyxFQUFFLE9BQTBCO0lBQzVELE1BQU0sSUFBSSxHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUMsVUFBVSxJQUFJLFFBQVEsQ0FBQztJQUNoRCxNQUFNLElBQUksR0FBRyx5QkFBUyxDQUFDLElBQUksRUFBRSxJQUFJLEVBQUUsT0FBTyxJQUFJO1FBQzVDLEtBQUssRUFBRTtZQUNMLFFBQVE7WUFDUixPQUFPLENBQUMsTUFBTTtZQUNkLFNBQVM7U0FDVjtLQUNGLENBQUMsQ0FBQztJQUVILElBQUksSUFBSSxDQUFDLEtBQUssRUFBRTtRQUNkLE1BQU0sSUFBSSxDQUFDLEtBQUssQ0FBQztLQUNsQjtJQUVELElBQUksSUFBSSxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUU7UUFDckIsSUFBSSxJQUFJLENBQUMsTUFBTSxJQUFJLElBQUksQ0FBQyxNQUFNLEVBQUU7WUFDOUIsTUFBTSxJQUFJLEtBQUssQ0FBQyxXQUFXLElBQUksQ0FBQyxNQUFNLGFBQWEsSUFBSSxDQUFDLE1BQU0sRUFBRSxRQUFRLEVBQUUsQ0FBQyxJQUFJLEVBQUUsaUJBQWlCLElBQUksQ0FBQyxNQUFNLEVBQUUsUUFBUSxFQUFFLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxDQUFDO1NBQ3JJO1FBQ0QsTUFBTSxJQUFJLEtBQUssQ0FBQyxHQUFHLElBQUksdUJBQXVCLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDO0tBQzlEO0lBRUQsT0FBTyxJQUFJLENBQUM7QUFDZCxDQUFDO0FBRUQsU0FBUyxTQUFTO0lBQ2hCLElBQUksT0FBTyxDQUFDLFFBQVEsSUFBSSxPQUFPLEVBQUU7UUFDL0IsT0FBTyxLQUFLLENBQUM7S0FDZDtJQUNELE1BQU0sSUFBSSxHQUFHLGdCQUFnQixDQUFDO0lBQzlCLE1BQU0sSUFBSSxHQUFHLHlCQUFTLENBQUMsSUFBSSxFQUFFLEVBQUUsRUFBRTtRQUMvQixLQUFLLEVBQUU7WUFDTCxNQUFNO1lBQ04sT0FBTyxDQUFDLE1BQU07WUFDZCxTQUFTO1NBQ1Y7S0FDRixDQUFDLENBQUM7SUFDSCxJQUFJLElBQUksQ0FBQyxLQUFLLEVBQUU7UUFDZCw0REFBNEQ7UUFDNUQsT0FBTyxLQUFLLENBQUM7S0FDZDtJQUNELElBQUksSUFBSSxDQUFDLE1BQU0sSUFBSSxDQUFDLEVBQUU7UUFDcEIsa0JBQWtCO1FBQ2xCLE9BQU8sSUFBSSxDQUFDO0tBQ2I7U0FBTTtRQUNMLHNCQUFzQjtRQUN0QixPQUFPLEtBQUssQ0FBQztLQUNkO0FBQ0gsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IHNwYXduU3luYywgU3Bhd25TeW5jT3B0aW9ucyB9IGZyb20gJ2NoaWxkX3Byb2Nlc3MnO1xuaW1wb3J0ICogYXMgY3J5cHRvIGZyb20gJ2NyeXB0byc7XG5pbXBvcnQgeyBpc0Fic29sdXRlLCBqb2luIH0gZnJvbSAncGF0aCc7XG5pbXBvcnQgeyBGaWxlU3lzdGVtIH0gZnJvbSAnLi9mcyc7XG5pbXBvcnQgeyBxdWlldCwgcmVzZXQgfSBmcm9tICcuL3ByaXZhdGUvanNpaS1kZXByZWNhdGVkJztcblxuLyoqXG4gKiBCdW5kbGluZyBvcHRpb25zXG4gKlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEJ1bmRsaW5nT3B0aW9ucyB7XG4gIC8qKlxuICAgKiBUaGUgRG9ja2VyIGltYWdlIHdoZXJlIHRoZSBjb21tYW5kIHdpbGwgcnVuLlxuICAgKi9cbiAgcmVhZG9ubHkgaW1hZ2U6IERvY2tlckltYWdlO1xuXG4gIC8qKlxuICAgKiBUaGUgZW50cnlwb2ludCB0byBydW4gaW4gdGhlIERvY2tlciBjb250YWluZXIuXG4gICAqXG4gICAqIEV4YW1wbGUgdmFsdWU6IGBbJy9iaW4vc2gnLCAnLWMnXWBcbiAgICpcbiAgICogQHNlZSBodHRwczovL2RvY3MuZG9ja2VyLmNvbS9lbmdpbmUvcmVmZXJlbmNlL2J1aWxkZXIvI2VudHJ5cG9pbnRcbiAgICpcbiAgICogQGRlZmF1bHQgLSBydW4gdGhlIGVudHJ5cG9pbnQgZGVmaW5lZCBpbiB0aGUgaW1hZ2VcbiAgICovXG4gIHJlYWRvbmx5IGVudHJ5cG9pbnQ/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