@angular-devkit/build-angular 16.1.4 → 16.2.0-next.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/builders.json +5 -0
- package/package.json +21 -22
- package/src/builders/application/build-action.d.ts +24 -0
- package/src/builders/application/build-action.js +159 -0
- package/src/builders/application/execute-build.d.ts +11 -0
- package/src/builders/application/execute-build.js +126 -0
- package/src/builders/application/index.d.ts +29 -0
- package/src/builders/application/index.js +50 -0
- package/src/builders/{browser-esbuild → application}/options.d.ts +11 -9
- package/src/builders/application/options.js +230 -0
- package/src/builders/application/schema.d.ts +390 -0
- package/src/builders/application/schema.js +59 -0
- package/src/builders/application/schema.json +520 -0
- package/src/builders/browser-esbuild/builder-status-warnings.d.ts +2 -2
- package/src/builders/browser-esbuild/builder-status-warnings.js +2 -1
- package/src/builders/browser-esbuild/index.d.ts +0 -17
- package/src/builders/browser-esbuild/index.js +14 -279
- package/src/builders/dev-server/vite-server.js +2 -2
- package/src/builders/jest/index.js +3 -5
- package/src/tools/esbuild/angular/{angular-compilation.d.ts → compilation/angular-compilation.d.ts} +1 -1
- package/src/tools/esbuild/angular/compilation/angular-compilation.js +52 -0
- package/src/tools/esbuild/angular/{aot-compilation.d.ts → compilation/aot-compilation.d.ts} +1 -1
- package/src/tools/esbuild/angular/compilation/aot-compilation.js +211 -0
- package/src/tools/esbuild/angular/compilation/index.d.ts +11 -0
- package/src/tools/esbuild/angular/compilation/index.js +19 -0
- package/src/tools/esbuild/angular/{jit-compilation.d.ts → compilation/jit-compilation.d.ts} +1 -1
- package/src/tools/esbuild/angular/compilation/jit-compilation.js +106 -0
- package/src/tools/esbuild/angular/compilation/noop-compilation.d.ts +20 -0
- package/src/tools/esbuild/angular/compilation/noop-compilation.js +27 -0
- package/src/tools/esbuild/angular/compiler-plugin.d.ts +2 -0
- package/src/tools/esbuild/angular/compiler-plugin.js +22 -8
- package/src/tools/esbuild/application-code-bundle.d.ts +9 -3
- package/src/tools/esbuild/application-code-bundle.js +131 -69
- package/src/tools/esbuild/compiler-plugin-options.d.ts +15 -0
- package/src/tools/esbuild/compiler-plugin-options.js +45 -0
- package/src/tools/esbuild/global-scripts.d.ts +2 -2
- package/src/tools/esbuild/global-scripts.js +1 -1
- package/src/tools/esbuild/global-styles.d.ts +2 -2
- package/src/tools/esbuild/global-styles.js +2 -3
- package/src/tools/esbuild/index-html-generator.d.ts +2 -2
- package/src/tools/esbuild/index-html-generator.js +4 -2
- package/src/tools/esbuild/javascript-transformer-worker.d.ts +0 -1
- package/src/tools/esbuild/javascript-transformer-worker.js +2 -5
- package/src/tools/esbuild/javascript-transformer.js +5 -13
- package/src/tools/esbuild/rxjs-esm-resolution-plugin.d.ts +18 -0
- package/src/tools/esbuild/rxjs-esm-resolution-plugin.js +45 -0
- package/src/tools/esbuild/stylesheets/bundle-options.d.ts +3 -4
- package/src/tools/esbuild/stylesheets/bundle-options.js +3 -4
- package/src/tools/esbuild/stylesheets/stylesheet-plugin-factory.d.ts +0 -7
- package/src/tools/esbuild/stylesheets/stylesheet-plugin-factory.js +6 -24
- package/src/tools/esbuild/utils.d.ts +5 -0
- package/src/tools/esbuild/utils.js +47 -16
- package/src/tools/webpack/plugins/css-optimizer-plugin.js +3 -3
- package/src/tools/webpack/plugins/javascript-optimizer-plugin.js +3 -3
- package/src/utils/index-file/augment-index-html.d.ts +1 -0
- package/src/utils/index-file/augment-index-html.js +6 -1
- package/src/utils/index-file/index-html-generator.d.ts +1 -0
- package/src/utils/index-file/index-html-generator.js +1 -1
- package/src/utils/index-file/inline-fonts.js +44 -14
- package/src/builders/browser-esbuild/options.js +0 -230
- package/src/tools/esbuild/angular/angular-compilation.js +0 -51
- package/src/tools/esbuild/angular/aot-compilation.js +0 -211
- package/src/tools/esbuild/angular/jit-compilation.js +0 -106
- package/src/utils/esbuild-targets.d.ts +0 -12
- package/src/utils/esbuild-targets.js +0 -55
|
@@ -6,12 +6,12 @@
|
|
|
6
6
|
* found in the LICENSE file at https://angular.io/license
|
|
7
7
|
*/
|
|
8
8
|
import { BuilderContext } from '@angular-devkit/architect';
|
|
9
|
-
import { Schema as
|
|
10
|
-
export type
|
|
9
|
+
import { Schema as ApplicationBuilderOptions } from './schema';
|
|
10
|
+
export type NormalizedApplicationBuildOptions = Awaited<ReturnType<typeof normalizeOptions>>;
|
|
11
11
|
/** Internal options hidden from builder schema but available when invoked programmatically. */
|
|
12
12
|
interface InternalOptions {
|
|
13
13
|
/**
|
|
14
|
-
* Entry points to use for the compilation. Incompatible with `
|
|
14
|
+
* Entry points to use for the compilation. Incompatible with `browser`, which must not be provided. May be relative or absolute paths.
|
|
15
15
|
* If given a relative path, it is resolved relative to the current workspace and will generate an output at the same relative location
|
|
16
16
|
* in the output directory. If given an absolute path, the output will be generated in the root of the output directory with the same base
|
|
17
17
|
* name.
|
|
@@ -25,9 +25,9 @@ interface InternalOptions {
|
|
|
25
25
|
*/
|
|
26
26
|
externalPackages?: boolean;
|
|
27
27
|
}
|
|
28
|
-
/** Full set of options for `
|
|
29
|
-
export type
|
|
30
|
-
|
|
28
|
+
/** Full set of options for `application` builder. */
|
|
29
|
+
export type ApplicationBuilderInternalOptions = Omit<ApplicationBuilderOptions & InternalOptions, 'browser'> & {
|
|
30
|
+
browser?: string;
|
|
31
31
|
};
|
|
32
32
|
/**
|
|
33
33
|
* Normalize the user provided options by creating full paths for all path based options
|
|
@@ -39,12 +39,13 @@ export type BrowserEsbuildOptions = Omit<BrowserBuilderOptions & InternalOptions
|
|
|
39
39
|
* @param options An object containing the options to use for the build.
|
|
40
40
|
* @returns An object containing normalized options required to perform the build.
|
|
41
41
|
*/
|
|
42
|
-
export declare function normalizeOptions(context: BuilderContext, projectName: string, options:
|
|
43
|
-
advancedOptimizations: boolean
|
|
42
|
+
export declare function normalizeOptions(context: BuilderContext, projectName: string, options: ApplicationBuilderInternalOptions): Promise<{
|
|
43
|
+
advancedOptimizations: boolean;
|
|
44
44
|
allowedCommonJsDependencies: string[] | undefined;
|
|
45
45
|
baseHref: string | undefined;
|
|
46
46
|
cacheOptions: import("../../utils/normalize-cache").NormalizedCachedOptions;
|
|
47
47
|
crossOrigin: import("./schema").CrossOrigin | undefined;
|
|
48
|
+
deleteOutputPath: boolean | undefined;
|
|
48
49
|
externalDependencies: string[] | undefined;
|
|
49
50
|
extractLicenses: boolean | undefined;
|
|
50
51
|
inlineStyleLanguage: string;
|
|
@@ -57,6 +58,7 @@ export declare function normalizeOptions(context: BuilderContext, projectName: s
|
|
|
57
58
|
preserveSymlinks: boolean;
|
|
58
59
|
stylePreprocessorOptions: import("./schema").StylePreprocessorOptions | undefined;
|
|
59
60
|
subresourceIntegrity: boolean | undefined;
|
|
61
|
+
serverEntryPoint: string | undefined;
|
|
60
62
|
verbose: boolean | undefined;
|
|
61
63
|
watch: boolean | undefined;
|
|
62
64
|
workspaceRoot: string;
|
|
@@ -83,7 +85,7 @@ export declare function normalizeOptions(context: BuilderContext, projectName: s
|
|
|
83
85
|
files: string[];
|
|
84
86
|
initial: boolean;
|
|
85
87
|
}[];
|
|
86
|
-
|
|
88
|
+
serviceWorker: any;
|
|
87
89
|
indexHtmlOptions: {
|
|
88
90
|
input: string;
|
|
89
91
|
output: string;
|
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @license
|
|
4
|
+
* Copyright Google LLC All Rights Reserved.
|
|
5
|
+
*
|
|
6
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
7
|
+
* found in the LICENSE file at https://angular.io/license
|
|
8
|
+
*/
|
|
9
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
10
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
11
|
+
};
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
exports.normalizeOptions = void 0;
|
|
14
|
+
const node_module_1 = require("node:module");
|
|
15
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
16
|
+
const helpers_1 = require("../../tools/webpack/utils/helpers");
|
|
17
|
+
const utils_1 = require("../../utils");
|
|
18
|
+
const normalize_cache_1 = require("../../utils/normalize-cache");
|
|
19
|
+
const package_chunk_sort_1 = require("../../utils/package-chunk-sort");
|
|
20
|
+
const tailwind_1 = require("../../utils/tailwind");
|
|
21
|
+
const webpack_browser_config_1 = require("../../utils/webpack-browser-config");
|
|
22
|
+
const schema_1 = require("./schema");
|
|
23
|
+
/**
|
|
24
|
+
* Normalize the user provided options by creating full paths for all path based options
|
|
25
|
+
* and converting multi-form options into a single form that can be directly used
|
|
26
|
+
* by the build process.
|
|
27
|
+
*
|
|
28
|
+
* @param context The context for current builder execution.
|
|
29
|
+
* @param projectName The name of the project for the current execution.
|
|
30
|
+
* @param options An object containing the options to use for the build.
|
|
31
|
+
* @returns An object containing normalized options required to perform the build.
|
|
32
|
+
*/
|
|
33
|
+
async function normalizeOptions(context, projectName, options) {
|
|
34
|
+
const workspaceRoot = context.workspaceRoot;
|
|
35
|
+
const projectMetadata = await context.getProjectMetadata(projectName);
|
|
36
|
+
const projectRoot = normalizeDirectoryPath(node_path_1.default.join(workspaceRoot, projectMetadata.root ?? ''));
|
|
37
|
+
const projectSourceRoot = normalizeDirectoryPath(node_path_1.default.join(workspaceRoot, projectMetadata.sourceRoot ?? 'src'));
|
|
38
|
+
// Gather persistent caching option and provide a project specific cache location
|
|
39
|
+
const cacheOptions = (0, normalize_cache_1.normalizeCacheOptions)(projectMetadata, workspaceRoot);
|
|
40
|
+
cacheOptions.path = node_path_1.default.join(cacheOptions.path, projectName);
|
|
41
|
+
const entryPoints = normalizeEntryPoints(workspaceRoot, options.browser, options.entryPoints);
|
|
42
|
+
const tsconfig = node_path_1.default.join(workspaceRoot, options.tsConfig);
|
|
43
|
+
const outputPath = normalizeDirectoryPath(node_path_1.default.join(workspaceRoot, options.outputPath));
|
|
44
|
+
const optimizationOptions = (0, utils_1.normalizeOptimization)(options.optimization);
|
|
45
|
+
const sourcemapOptions = (0, utils_1.normalizeSourceMaps)(options.sourceMap ?? false);
|
|
46
|
+
const assets = options.assets?.length
|
|
47
|
+
? (0, utils_1.normalizeAssetPatterns)(options.assets, workspaceRoot, projectRoot, projectSourceRoot)
|
|
48
|
+
: undefined;
|
|
49
|
+
const outputNames = {
|
|
50
|
+
bundles: options.outputHashing === schema_1.OutputHashing.All || options.outputHashing === schema_1.OutputHashing.Bundles
|
|
51
|
+
? '[name].[hash]'
|
|
52
|
+
: '[name]',
|
|
53
|
+
media: 'media/' +
|
|
54
|
+
(options.outputHashing === schema_1.OutputHashing.All || options.outputHashing === schema_1.OutputHashing.Media
|
|
55
|
+
? '[name].[hash]'
|
|
56
|
+
: '[name]'),
|
|
57
|
+
};
|
|
58
|
+
let fileReplacements;
|
|
59
|
+
if (options.fileReplacements) {
|
|
60
|
+
for (const replacement of options.fileReplacements) {
|
|
61
|
+
fileReplacements ?? (fileReplacements = {});
|
|
62
|
+
fileReplacements[node_path_1.default.join(workspaceRoot, replacement.replace)] = node_path_1.default.join(workspaceRoot, replacement.with);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
const globalStyles = [];
|
|
66
|
+
if (options.styles?.length) {
|
|
67
|
+
const { entryPoints: stylesheetEntrypoints, noInjectNames } = (0, helpers_1.normalizeGlobalStyles)(options.styles || []);
|
|
68
|
+
for (const [name, files] of Object.entries(stylesheetEntrypoints)) {
|
|
69
|
+
globalStyles.push({ name, files, initial: !noInjectNames.includes(name) });
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
const globalScripts = [];
|
|
73
|
+
if (options.scripts?.length) {
|
|
74
|
+
for (const { bundleName, paths, inject } of (0, helpers_1.globalScriptsByBundleName)(options.scripts)) {
|
|
75
|
+
globalScripts.push({ name: bundleName, files: paths, initial: inject });
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
let tailwindConfiguration;
|
|
79
|
+
const tailwindConfigurationPath = await (0, tailwind_1.findTailwindConfigurationFile)(workspaceRoot, projectRoot);
|
|
80
|
+
if (tailwindConfigurationPath) {
|
|
81
|
+
// Create a node resolver at the project root as a directory
|
|
82
|
+
const resolver = (0, node_module_1.createRequire)(projectRoot + '/');
|
|
83
|
+
try {
|
|
84
|
+
tailwindConfiguration = {
|
|
85
|
+
file: tailwindConfigurationPath,
|
|
86
|
+
package: resolver.resolve('tailwindcss'),
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
catch {
|
|
90
|
+
const relativeTailwindConfigPath = node_path_1.default.relative(workspaceRoot, tailwindConfigurationPath);
|
|
91
|
+
context.logger.warn(`Tailwind CSS configuration file found (${relativeTailwindConfigPath})` +
|
|
92
|
+
` but the 'tailwindcss' package is not installed.` +
|
|
93
|
+
` To enable Tailwind CSS, please install the 'tailwindcss' package.`);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
let indexHtmlOptions;
|
|
97
|
+
if (options.index) {
|
|
98
|
+
indexHtmlOptions = {
|
|
99
|
+
input: node_path_1.default.join(workspaceRoot, (0, webpack_browser_config_1.getIndexInputFile)(options.index)),
|
|
100
|
+
// The output file will be created within the configured output path
|
|
101
|
+
output: (0, webpack_browser_config_1.getIndexOutputFile)(options.index),
|
|
102
|
+
// TODO: Use existing information from above to create the insertion order
|
|
103
|
+
insertionOrder: (0, package_chunk_sort_1.generateEntryPoints)({
|
|
104
|
+
scripts: options.scripts ?? [],
|
|
105
|
+
styles: options.styles ?? [],
|
|
106
|
+
}),
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
let serverEntryPoint;
|
|
110
|
+
if (options.server) {
|
|
111
|
+
serverEntryPoint = node_path_1.default.join(workspaceRoot, options.server);
|
|
112
|
+
}
|
|
113
|
+
else if (options.server === '') {
|
|
114
|
+
throw new Error('`server` option cannot be an empty string.');
|
|
115
|
+
}
|
|
116
|
+
// Initial options to keep
|
|
117
|
+
const { allowedCommonJsDependencies, aot, baseHref, crossOrigin, externalDependencies, extractLicenses, inlineStyleLanguage = 'css', outExtension, serviceWorker, poll, polyfills, preserveSymlinks, statsJson, stylePreprocessorOptions, subresourceIntegrity, verbose, watch, progress = true, externalPackages, deleteOutputPath, } = options;
|
|
118
|
+
// Return all the normalized options
|
|
119
|
+
return {
|
|
120
|
+
advancedOptimizations: !!aot,
|
|
121
|
+
allowedCommonJsDependencies,
|
|
122
|
+
baseHref,
|
|
123
|
+
cacheOptions,
|
|
124
|
+
crossOrigin,
|
|
125
|
+
deleteOutputPath,
|
|
126
|
+
externalDependencies,
|
|
127
|
+
extractLicenses,
|
|
128
|
+
inlineStyleLanguage,
|
|
129
|
+
jit: !aot,
|
|
130
|
+
stats: !!statsJson,
|
|
131
|
+
polyfills: polyfills === undefined || Array.isArray(polyfills) ? polyfills : [polyfills],
|
|
132
|
+
poll,
|
|
133
|
+
progress,
|
|
134
|
+
externalPackages,
|
|
135
|
+
// If not explicitly set, default to the Node.js process argument
|
|
136
|
+
preserveSymlinks: preserveSymlinks ?? process.execArgv.includes('--preserve-symlinks'),
|
|
137
|
+
stylePreprocessorOptions,
|
|
138
|
+
subresourceIntegrity,
|
|
139
|
+
serverEntryPoint,
|
|
140
|
+
verbose,
|
|
141
|
+
watch,
|
|
142
|
+
workspaceRoot,
|
|
143
|
+
entryPoints,
|
|
144
|
+
optimizationOptions,
|
|
145
|
+
outputPath,
|
|
146
|
+
outExtension,
|
|
147
|
+
sourcemapOptions,
|
|
148
|
+
tsconfig,
|
|
149
|
+
projectRoot,
|
|
150
|
+
assets,
|
|
151
|
+
outputNames,
|
|
152
|
+
fileReplacements,
|
|
153
|
+
globalStyles,
|
|
154
|
+
globalScripts,
|
|
155
|
+
serviceWorker,
|
|
156
|
+
indexHtmlOptions,
|
|
157
|
+
tailwindConfiguration,
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
exports.normalizeOptions = normalizeOptions;
|
|
161
|
+
/**
|
|
162
|
+
* Normalize entry point options. To maintain compatibility with the legacy browser builder, we need a single `browser`
|
|
163
|
+
* option which defines a single entry point. However, we also want to support multiple entry points as an internal option.
|
|
164
|
+
* The two options are mutually exclusive and if `browser` is provided it will be used as the sole entry point.
|
|
165
|
+
* If `entryPoints` are provided, they will be used as the set of entry points.
|
|
166
|
+
*
|
|
167
|
+
* @param workspaceRoot Path to the root of the Angular workspace.
|
|
168
|
+
* @param browser The `browser` option pointing at the application entry point. While required per the schema file, it may be omitted by
|
|
169
|
+
* programmatic usages of `browser-esbuild`.
|
|
170
|
+
* @param entryPoints Set of entry points to use if provided.
|
|
171
|
+
* @returns An object mapping entry point names to their file paths.
|
|
172
|
+
*/
|
|
173
|
+
function normalizeEntryPoints(workspaceRoot, browser, entryPoints = new Set()) {
|
|
174
|
+
if (browser === '') {
|
|
175
|
+
throw new Error('`browser` option cannot be an empty string.');
|
|
176
|
+
}
|
|
177
|
+
// `browser` and `entryPoints` are mutually exclusive.
|
|
178
|
+
if (browser && entryPoints.size > 0) {
|
|
179
|
+
throw new Error('Only one of `browser` or `entryPoints` may be provided.');
|
|
180
|
+
}
|
|
181
|
+
if (!browser && entryPoints.size === 0) {
|
|
182
|
+
// Schema should normally reject this case, but programmatic usages of the builder might make this mistake.
|
|
183
|
+
throw new Error('Either `browser` or at least one `entryPoints` value must be provided.');
|
|
184
|
+
}
|
|
185
|
+
// Schema types force `browser` to always be provided, but it may be omitted when the builder is invoked programmatically.
|
|
186
|
+
if (browser) {
|
|
187
|
+
// Use `browser` alone.
|
|
188
|
+
return { 'main': node_path_1.default.join(workspaceRoot, browser) };
|
|
189
|
+
}
|
|
190
|
+
else {
|
|
191
|
+
// Use `entryPoints` alone.
|
|
192
|
+
const entryPointPaths = {};
|
|
193
|
+
for (const entryPoint of entryPoints) {
|
|
194
|
+
const parsedEntryPoint = node_path_1.default.parse(entryPoint);
|
|
195
|
+
// Use the input file path without an extension as the "name" of the entry point dictating its output location.
|
|
196
|
+
// Relative entry points are generated at the same relative path in the output directory.
|
|
197
|
+
// Absolute entry points are always generated with the same file name in the root of the output directory. This includes absolute
|
|
198
|
+
// paths pointing at files actually within the workspace root.
|
|
199
|
+
const entryPointName = node_path_1.default.isAbsolute(entryPoint)
|
|
200
|
+
? parsedEntryPoint.name
|
|
201
|
+
: node_path_1.default.join(parsedEntryPoint.dir, parsedEntryPoint.name);
|
|
202
|
+
// Get the full file path to the entry point input.
|
|
203
|
+
const entryPointPath = node_path_1.default.isAbsolute(entryPoint)
|
|
204
|
+
? entryPoint
|
|
205
|
+
: node_path_1.default.join(workspaceRoot, entryPoint);
|
|
206
|
+
// Check for conflicts with previous entry points.
|
|
207
|
+
const existingEntryPointPath = entryPointPaths[entryPointName];
|
|
208
|
+
if (existingEntryPointPath) {
|
|
209
|
+
throw new Error(`\`${existingEntryPointPath}\` and \`${entryPointPath}\` both output to the same location \`${entryPointName}\`.` +
|
|
210
|
+
' Rename or move one of the files to fix the conflict.');
|
|
211
|
+
}
|
|
212
|
+
entryPointPaths[entryPointName] = entryPointPath;
|
|
213
|
+
}
|
|
214
|
+
return entryPointPaths;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* Normalize a directory path string.
|
|
219
|
+
* Currently only removes a trailing slash if present.
|
|
220
|
+
* @param path A path string.
|
|
221
|
+
* @returns A normalized path string.
|
|
222
|
+
*/
|
|
223
|
+
function normalizeDirectoryPath(path) {
|
|
224
|
+
const last = path[path.length - 1];
|
|
225
|
+
if (last === '/' || last === '\\') {
|
|
226
|
+
return path.slice(0, -1);
|
|
227
|
+
}
|
|
228
|
+
return path;
|
|
229
|
+
}
|
|
230
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3B0aW9ucy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uLy4uLy4uL3BhY2thZ2VzL2FuZ3VsYXJfZGV2a2l0L2J1aWxkX2FuZ3VsYXIvc3JjL2J1aWxkZXJzL2FwcGxpY2F0aW9uL29wdGlvbnMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBOzs7Ozs7R0FNRzs7Ozs7O0FBR0gsNkNBQTRDO0FBQzVDLDBEQUE2QjtBQUM3QiwrREFHMkM7QUFDM0MsdUNBQWlHO0FBQ2pHLGlFQUFvRTtBQUNwRSx1RUFBcUU7QUFDckUsbURBQXFFO0FBQ3JFLCtFQUEyRjtBQUMzRixxQ0FBOEU7QUFpQzlFOzs7Ozs7Ozs7R0FTRztBQUNJLEtBQUssVUFBVSxnQkFBZ0IsQ0FDcEMsT0FBdUIsRUFDdkIsV0FBbUIsRUFDbkIsT0FBMEM7SUFFMUMsTUFBTSxhQUFhLEdBQUcsT0FBTyxDQUFDLGFBQWEsQ0FBQztJQUM1QyxNQUFNLGVBQWUsR0FBRyxNQUFNLE9BQU8sQ0FBQyxrQkFBa0IsQ0FBQyxXQUFXLENBQUMsQ0FBQztJQUN0RSxNQUFNLFdBQVcsR0FBRyxzQkFBc0IsQ0FDeEMsbUJBQUksQ0FBQyxJQUFJLENBQUMsYUFBYSxFQUFHLGVBQWUsQ0FBQyxJQUEyQixJQUFJLEVBQUUsQ0FBQyxDQUM3RSxDQUFDO0lBQ0YsTUFBTSxpQkFBaUIsR0FBRyxzQkFBc0IsQ0FDOUMsbUJBQUksQ0FBQyxJQUFJLENBQUMsYUFBYSxFQUFHLGVBQWUsQ0FBQyxVQUFpQyxJQUFJLEtBQUssQ0FBQyxDQUN0RixDQUFDO0lBRUYsaUZBQWlGO0lBQ2pGLE1BQU0sWUFBWSxHQUFHLElBQUEsdUNBQXFCLEVBQUMsZUFBZSxFQUFFLGFBQWEsQ0FBQyxDQUFDO0lBQzNFLFlBQVksQ0FBQyxJQUFJLEdBQUcsbUJBQUksQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksRUFBRSxXQUFXLENBQUMsQ0FBQztJQUU5RCxNQUFNLFdBQVcsR0FBRyxv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RSxDQUFDLENBQUMsQ0FBQyxDQUFDO0tBQzFCO0lBRUQsT0FBTyxJQUFJLENBQUM7QUFDZCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IEdvb2dsZSBMTEMgQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqXG4gKiBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhbiBNSVQtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZVxuICogZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZSBhdCBodHRwczovL2FuZ3VsYXIuaW8vbGljZW5zZVxuICovXG5cbmltcG9ydCB7IEJ1aWxkZXJDb250ZXh0IH0gZnJvbSAnQGFuZ3VsYXItZGV2a2l0L2FyY2hpdGVjdCc7XG5pbXBvcnQgeyBjcmVhdGVSZXF1aXJlIH0gZnJvbSAnbm9kZTptb2R1bGUnO1xuaW1wb3J0IHBhdGggZnJvbSAnbm9kZTpwYXRoJztcbmltcG9ydCB7XG4gIGdsb2JhbFNjcmlwdHNCeUJ1bmRsZU5hbWUsXG4gIG5vcm1hbGl6ZUdsb2JhbFN0eWxlcyxcbn0gZnJvbSAnLi4vLi4vdG9vbHMvd2VicGFjay91dGlscy9oZWxwZXJzJztcbmltcG9ydCB7IG5vcm1hbGl6ZUFzc2V0UGF0dGVybnMsIG5vcm1hbGl6ZU9wdGltaXphdGlvbiwgbm9ybWFsaXplU291cmNlTWFwcyB9IGZyb20gJy4uLy4uL3V0aWxzJztcbmltcG9ydCB7IG5vcm1hbGl6ZUNhY2hlT3B0aW9ucyB9IGZyb20gJy4uLy4uL3V0aWxzL25vcm1hbGl6ZS1jYWNoZSc7XG5pbXBvcnQgeyBnZW5lcmF0ZUVudHJ5UG9pbnRzIH0gZnJvbSAnLi4vLi4vdXRpbHMvcGFja2FnZS1jaHVuay1zb3J0JztcbmltcG9ydCB7IGZpbmRUYWlsd2luZENvbmZpZ3VyYXRpb25GaWxlIH0gZnJvbSAnLi4vLi4vdXRpbHMvdGFpbHdpbmQnO1xuaW1wb3J0IHsgZ2V0SW5kZXhJbnB1dEZpbGUsIGdldEluZGV4T3V0cHV0RmlsZSB9IGZyb20gJy4uLy4uL3V0aWxzL3dlYnBhY2stYnJvd3Nlci1jb25maWcnO1xuaW1wb3J0IHsgU2NoZW1hIGFzIEFwcGxpY2F0aW9uQnVpbGRlck9wdGlvbnMsIE91dHB1dEhhc2hpbmcgfSBmcm9tICcuL3NjaGVtYSc7XG5cbmV4cG9ydCB0eXBlIE5vcm1hbGl6ZWRBcHBsaWNhdGlvbkJ1aWxkT3B0aW9ucyA9IEF3YWl0ZWQ8UmV0dXJuVHlwZTx0eXBlb2Ygbm9ybWFsaXplT3B0aW9ucz4+O1xuXG4vKiogSW50ZXJuYWwgb3B0aW9ucyBoaWRkZW4gZnJvbSBidWlsZGVyIHNjaGVtYSBidXQgYXZhaWxhYmxlIHdoZW4gaW52b2tlZCBwcm9ncmFtbWF0aWNhbGx5LiAqL1xuaW50ZXJmYWNlIEludGVybmFsT3B0aW9ucyB7XG4gIC8qKlxuICAgKiBFbnRyeSBwb2ludHMgdG8gdXNlIGZvciB0aGUgY29tcGlsYXRpb24uIEluY29tcGF0aWJsZSB3aXRoIGBicm93c2VyYCwgd2hpY2ggbXVzdCBub3QgYmUgcHJvdmlkZWQuIE1heSBiZSByZWxhdGl2ZSBvciBhYnNvbHV0ZSBwYXRocy5cbiAgICogSWYgZ2l2ZW4gYSByZWxhdGl2ZSBwYXRoLCBpdCBpcyByZXNvbHZlZCByZWxhdGl2ZSB0byB0aGUgY3VycmVudCB3b3Jrc3BhY2UgYW5kIHdpbGwgZ2VuZXJhdGUgYW4gb3V0cHV0IGF0IHRoZSBzYW1lIHJlbGF0aXZlIGxvY2F0aW9uXG4gICAqIGluIHRoZSBvdXRwdXQgZGlyZWN0b3J5LiBJZiBnaXZlbiBhbiBhYnNvbHV0ZSBwYXRoLCB0aGUgb3V0cHV0IHdpbGwgYmUgZ2VuZXJhdGVkIGluIHRoZSByb290IG9mIHRoZSBvdXRwdXQgZGlyZWN0b3J5IHdpdGggdGhlIHNhbWUgYmFzZVxuICAgKiBuYW1lLlxuICAgKi9cbiAgZW50cnlQb2ludHM/OiBTZXQ8c3RyaW5nPjtcblxuICAvKiogRmlsZSBleHRlbnNpb24gdG8gdXNlIGZvciB0aGUgZ2VuZXJhdGVkIG91dHB1dCBmaWxlcy4gKi9cbiAgb3V0RXh0ZW5zaW9uPzogJ2pzJyB8ICdtanMnO1xuXG4gIC8qKlxuICAgKiBJbmRpY2F0ZXMgd2hldGhlciBhbGwgbm9kZSBwYWNrYWdlcyBzaG91bGQgYmUgbWFya2VkIGFzIGV4dGVybmFsLlxuICAgKiBDdXJyZW50bHkgdXNlZCBieSB0aGUgZGV2LXNlcnZlciB0byBzdXBwb3J0IHByZWJ1bmRsaW5nLlxuICAgKi9cbiAgZXh0ZXJuYWxQYWNrYWdlcz86IGJvb2xlYW47XG59XG5cbi8qKiBGdWxsIHNldCBvZiBvcHRpb25zIGZvciBgYXBwbGljYXRpb25gIGJ1aWxkZXIuICovXG5leHBvcnQgdHlwZSBBcHBsaWNhdGlvbkJ1aWxkZXJJbnRlcm5hbE9wdGlvbnMgPSBPbWl0PFxuICBBcHBsaWNhdGlvbkJ1aWxkZXJPcHRpb25zICYgSW50ZXJuYWxPcHRpb25zLFxuICAnYnJvd3Nlcidcbj4gJiB7XG4gIC8vIGBicm93c2VyYCBjYW4gYmUgYHVuZGVmaW5lZGAgaWYgYGVudHJ5UG9pbnRzYCBpcyB1c2VkLlxuICBicm93c2VyPzogc3RyaW5nO1xufTtcblxuLyoqXG4gKiBOb3JtYWxpemUgdGhlIHVzZXIgcHJvdmlkZWQgb3B0aW9ucyBieSBjcmVhdGluZyBmdWxsIHBhdGhzIGZvciBhbGwgcGF0aCBiYXNlZCBvcHRpb25zXG4gKiBhbmQgY29udmVydGluZyBtdWx0aS1mb3JtIG9wdGlvbnMgaW50byBhIHNpbmdsZSBmb3JtIHRoYXQgY2FuIGJlIGRpcmVjdGx5IHVzZWRcbiAqIGJ5IHRoZSBidWlsZCBwcm9jZXNzLlxuICpcbiAqIEBwYXJhbSBjb250ZXh0IFRoZSBjb250ZXh0IGZvciBjdXJyZW50IGJ1aWxkZXIgZXhlY3V0aW9uLlxuICogQHBhcmFtIHByb2plY3ROYW1lIFRoZSBuYW1lIG9mIHRoZSBwcm9qZWN0IGZvciB0aGUgY3VycmVudCBleGVjdXRpb24uXG4gKiBAcGFyYW0gb3B0aW9ucyBBbiBvYmplY3QgY29udGFpbmluZyB0aGUgb3B0aW9ucyB0byB1c2UgZm9yIHRoZSBidWlsZC5cbiAqIEByZXR1cm5zIEFuIG9iamVjdCBjb250YWluaW5nIG5vcm1hbGl6ZWQgb3B0aW9ucyByZXF1aXJlZCB0byBwZXJmb3JtIHRoZSBidWlsZC5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIG5vcm1hbGl6ZU9wdGlvbnMoXG4gIGNvbnRleHQ6IEJ1aWxkZXJDb250ZXh0LFxuICBwcm9qZWN0TmFtZTogc3RyaW5nLFxuICBvcHRpb25zOiBBcHBsaWNhdGlvbkJ1aWxkZXJJbnRlcm5hbE9wdGlvbnMsXG4pIHtcbiAgY29uc3Qgd29ya3NwYWNlUm9vdCA9IGNvbnRleHQud29ya3NwYWNlUm9vdDtcbiAgY29uc3QgcHJvamVjdE1ldGFkYXRhID0gYXdhaXQgY29udGV4dC5nZXRQcm9qZWN0TWV0YWRhdGEocHJvamVjdE5hbWUpO1xuICBjb25zdCBwcm9qZWN0Um9vdCA9IG5vcm1hbGl6ZURpcmVjdG9yeVBhdGgoXG4gICAgcGF0aC5qb2luKHdvcmtzcGFjZVJvb3QsIChwcm9qZWN0TWV0YWRhdGEucm9vdCBhcyBzdHJpbmcgfCB1bmRlZmluZWQpID8/ICcnKSxcbiAgKTtcbiAgY29uc3QgcHJvamVjdFNvdXJjZVJvb3QgPSBub3JtYWxpemVEaXJlY3RvcnlQYXRoKFxuICAgIHBhdGguam9pbih3b3Jrc3BhY2VSb290LCAocHJvamVjdE1ldGFkYXRhLnNvdXJjZVJvb3QgYXMgc3RyaW5nIHwgdW5kZWZpbmVkKSA/PyAnc3JjJyksXG4gICk7XG5cbiAgLy8gR2F0aGVyIHBlcnNpc3RlbnQgY2FjaGluZyBvcHRpb24gYW5kIHByb3ZpZGUgYSBwcm9qZWN0IHNwZWNpZmljIGNhY2hlIGxvY2F0aW9uXG4gIGNvbnN0IGNhY2hlT3B0aW9ucyA9IG5vcm1hbGl6ZUNhY2hlT3B0aW9ucyhwcm9qZWN0TWV0YWRhdGEsIHdvcmtzcGFjZVJvb3QpO1xuICBjYWNoZU9wdGlvbnMucGF0aCA9IHBhdGguam9pbihjYWNoZU9wdGlvbnMucGF0aCwgcHJvamVjdE5hbWUpO1xuXG4gIGNvbnN0IGVudHJ5UG9pbnRzID0gbm9ybWFsaXplRW50cnlQb2ludHMod29ya3NwYWNlUm9vdCwgb3B0aW9ucy5icm93c2VyLCBvcHRpb25zLmVudHJ5UG9pbnRzKTtcbiAgY29uc3QgdHNjb25maWcgPSBwYXRoLmpvaW4od29ya3NwYWNlUm9vdCwgb3B0aW9ucy50c0NvbmZpZyk7XG4gIGNvbnN0IG91dHB1dFBhdGggPSBub3JtYWxpemVEaXJlY3RvcnlQYXRoKHBhdGguam9pbih3b3Jrc3BhY2VSb290LCBvcHRpb25zLm91dHB1dFBhdGgpKTtcbiAgY29uc3Qgb3B0aW1pemF0aW9uT3B0aW9ucyA9IG5vcm1hbGl6ZU9wdGltaXphdGlvbihvcHRpb25zLm9wdGltaXphdGlvbik7XG4gIGNvbnN0IHNvdXJjZW1hcE9wdGlvbnMgPSBub3JtYWxpemVTb3VyY2VNYXBzKG9wdGlvbnMuc291cmNlTWFwID8/IGZhbHNlKTtcbiAgY29uc3QgYXNzZXRzID0gb3B0aW9ucy5hc3NldHM/Lmxlbmd0aFxuICAgID8gbm9ybWFsaXplQXNzZXRQYXR0ZXJucyhvcHRpb25zLmFzc2V0cywgd29ya3NwYWNlUm9vdCwgcHJvamVjdFJvb3QsIHByb2plY3RTb3VyY2VSb290KVxuICAgIDogdW5kZWZpbmVkO1xuXG4gIGNvbnN0IG91dHB1dE5hbWVzID0ge1xuICAgIGJ1bmRsZXM6XG4gICAgICBvcHRpb25zLm91dHB1dEhhc2hpbmcgPT09IE91dHB1dEhhc2hpbmcuQWxsIHx8IG9wdGlvbnMub3V0cHV0SGFzaGluZyA9PT0gT3V0cHV0SGFzaGluZy5CdW5kbGVzXG4gICAgICAgID8gJ1tuYW1lXS5baGFzaF0nXG4gICAgICAgIDogJ1tuYW1lXScsXG4gICAgbWVkaWE6XG4gICAgICAnbWVkaWEvJyArXG4gICAgICAob3B0aW9ucy5vdXRwdXRIYXNoaW5nID09PSBPdXRwdXRIYXNoaW5nLkFsbCB8fCBvcHRpb25zLm91dHB1dEhhc2hpbmcgPT09IE91dHB1dEhhc2hpbmcuTWVkaWFcbiAgICAgICAgPyAnW25hbWVdLltoYXNoXSdcbiAgICAgICAgOiAnW25hbWVdJyksXG4gIH07XG5cbiAgbGV0IGZpbGVSZXBsYWNlbWVudHM6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gfCB1bmRlZmluZWQ7XG4gIGlmIChvcHRpb25zLmZpbGVSZXBsYWNlbWVudHMpIHtcbiAgICBmb3IgKGNvbnN0IHJlcGxhY2VtZW50IG9mIG9wdGlvbnMuZmlsZVJlcGxhY2VtZW50cykge1xuICAgICAgZmlsZVJlcGxhY2VtZW50cyA/Pz0ge307XG4gICAgICBmaWxlUmVwbGFjZW1lbnRzW3BhdGguam9pbih3b3Jrc3BhY2VSb290LCByZXBsYWNlbWVudC5yZXBsYWNlKV0gPSBwYXRoLmpvaW4oXG4gICAgICAgIHdvcmtzcGFjZVJvb3QsXG4gICAgICAgIHJlcGxhY2VtZW50LndpdGgsXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIGNvbnN0IGdsb2JhbFN0eWxlczogeyBuYW1lOiBzdHJpbmc7IGZpbGVzOiBzdHJpbmdbXTsgaW5pdGlhbDogYm9vbGVhbiB9W10gPSBbXTtcbiAgaWYgKG9wdGlvbnMuc3R5bGVzPy5sZW5ndGgpIHtcbiAgICBjb25zdCB7IGVudHJ5UG9pbnRzOiBzdHlsZXNoZWV0RW50cnlwb2ludHMsIG5vSW5qZWN0TmFtZXMgfSA9IG5vcm1hbGl6ZUdsb2JhbFN0eWxlcyhcbiAgICAgIG9wdGlvbnMuc3R5bGVzIHx8IFtdLFxuICAgICk7XG4gICAgZm9yIChjb25zdCBbbmFtZSwgZmlsZXNdIG9mIE9iamVjdC5lbnRyaWVzKHN0eWxlc2hlZXRFbnRyeXBvaW50cykpIHtcbiAgICAgIGdsb2JhbFN0eWxlcy5wdXNoKHsgbmFtZSwgZmlsZXMsIGluaXRpYWw6ICFub0luamVjdE5hbWVzLmluY2x1ZGVzKG5hbWUpIH0pO1xuICAgIH1cbiAgfVxuXG4gIGNvbnN0IGdsb2JhbFNjcmlwdHM6IHsgbmFtZTogc3RyaW5nOyBmaWxlczogc3RyaW5nW107IGluaXRpYWw6IGJvb2xlYW4gfVtdID0gW107XG4gIGlmIChvcHRpb25zLnNjcmlwdHM/Lmxlbmd0aCkge1xuICAgIGZvciAoY29uc3QgeyBidW5kbGVOYW1lLCBwYXRocywgaW5qZWN0IH0gb2YgZ2xvYmFsU2NyaXB0c0J5QnVuZGxlTmFtZShvcHRpb25zLnNjcmlwdHMpKSB7XG4gICAgICBnbG9iYWxTY3JpcHRzLnB1c2goeyBuYW1lOiBidW5kbGVOYW1lLCBmaWxlczogcGF0aHMsIGluaXRpYWw6IGluamVjdCB9KTtcbiAgICB9XG4gIH1cblxuICBsZXQgdGFpbHdpbmRDb25maWd1cmF0aW9uOiB7IGZpbGU6IHN0cmluZzsgcGFja2FnZTogc3RyaW5nIH0gfCB1bmRlZmluZWQ7XG4gIGNvbnN0IHRhaWx3aW5kQ29uZmlndXJhdGlvblBhdGggPSBhd2FpdCBmaW5kVGFpbHdpbmRDb25maWd1cmF0aW9uRmlsZSh3b3Jrc3BhY2VSb290LCBwcm9qZWN0Um9vdCk7XG4gIGlmICh0YWlsd2luZENvbmZpZ3VyYXRpb25QYXRoKSB7XG4gICAgLy8gQ3JlYXRlIGEgbm9kZSByZXNvbHZlciBhdCB0aGUgcHJvamVjdCByb290IGFzIGEgZGlyZWN0b3J5XG4gICAgY29uc3QgcmVzb2x2ZXIgPSBjcmVhdGVSZXF1aXJlKHByb2plY3RSb290ICsgJy8nKTtcbiAgICB0cnkge1xuICAgICAgdGFpbHdpbmRDb25maWd1cmF0aW9uID0ge1xuICAgICAgICBmaWxlOiB0YWlsd2luZENvbmZpZ3VyYXRpb25QYXRoLFxuICAgICAgICBwYWNrYWdlOiByZXNvbHZlci5yZXNvbHZlKCd0YWlsd2luZGNzcycpLFxuICAgICAgfTtcbiAgICB9IGNhdGNoIHtcbiAgICAgIGNvbnN0IHJlbGF0aXZlVGFpbHdpbmRDb25maWdQYXRoID0gcGF0aC5yZWxhdGl2ZSh3b3Jrc3BhY2VSb290LCB0YWlsd2luZENvbmZpZ3VyYXRpb25QYXRoKTtcbiAgICAgIGNvbnRleHQubG9nZ2VyLndhcm4oXG4gICAgICAgIGBUYWlsd2luZCBDU1MgY29uZmlndXJhdGlvbiBmaWxlIGZvdW5kICgke3JlbGF0aXZlVGFpbHdpbmRDb25maWdQYXRofSlgICtcbiAgICAgICAgICBgIGJ1dCB0aGUgJ3RhaWx3aW5kY3NzJyBwYWNrYWdlIGlzIG5vdCBpbnN0YWxsZWQuYCArXG4gICAgICAgICAgYCBUbyBlbmFibGUgVGFpbHdpbmQgQ1NTLCBwbGVhc2UgaW5zdGFsbCB0aGUgJ3RhaWx3aW5kY3NzJyBwYWNrYWdlLmAsXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIGxldCBpbmRleEh0bWxPcHRpb25zO1xuICBpZiAob3B0aW9ucy5pbmRleCkge1xuICAgIGluZGV4SHRtbE9wdGlvbnMgPSB7XG4gICAgICBpbnB1dDogcGF0aC5qb2luKHdvcmtzcGFjZVJvb3QsIGdldEluZGV4SW5wdXRGaWxlKG9wdGlvbnMuaW5kZXgpKSxcbiAgICAgIC8vIFRoZSBvdXRwdXQgZmlsZSB3aWxsIGJlIGNyZWF0ZWQgd2l0aGluIHRoZSBjb25maWd1cmVkIG91dHB1dCBwYXRoXG4gICAgICBvdXRwdXQ6IGdldEluZGV4T3V0cHV0RmlsZShvcHRpb25zLmluZGV4KSxcbiAgICAgIC8vIFRPRE86IFVzZSBleGlzdGluZyBpbmZvcm1hdGlvbiBmcm9tIGFib3ZlIHRvIGNyZWF0ZSB0aGUgaW5zZXJ0aW9uIG9yZGVyXG4gICAgICBpbnNlcnRpb25PcmRlcjogZ2VuZXJhdGVFbnRyeVBvaW50cyh7XG4gICAgICAgIHNjcmlwdHM6IG9wdGlvbnMuc2NyaXB0cyA/PyBbXSxcbiAgICAgICAgc3R5bGVzOiBvcHRpb25zLnN0eWxlcyA/PyBbXSxcbiAgICAgIH0pLFxuICAgIH07XG4gIH1cblxuICBsZXQgc2VydmVyRW50cnlQb2ludDogc3RyaW5nIHwgdW5kZWZpbmVkO1xuICBpZiAob3B0aW9ucy5zZXJ2ZXIpIHtcbiAgICBzZXJ2ZXJFbnRyeVBvaW50ID0gcGF0aC5qb2luKHdvcmtzcGFjZVJvb3QsIG9wdGlvbnMuc2VydmVyKTtcbiAgfSBlbHNlIGlmIChvcHRpb25zLnNlcnZlciA9PT0gJycpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2BzZXJ2ZXJgIG9wdGlvbiBjYW5ub3QgYmUgYW4gZW1wdHkgc3RyaW5nLicpO1xuICB9XG5cbiAgLy8gSW5pdGlhbCBvcHRpb25zIHRvIGtlZXBcbiAgY29uc3Qge1xuICAgIGFsbG93ZWRDb21tb25Kc0RlcGVuZGVuY2llcyxcbiAgICBhb3QsXG4gICAgYmFzZUhyZWYsXG4gICAgY3Jvc3NPcmlnaW4sXG4gICAgZXh0ZXJuYWxEZXBlbmRlbmNpZXMsXG4gICAgZXh0cmFjdExpY2Vuc2VzLFxuICAgIGlubGluZVN0eWxlTGFuZ3VhZ2UgPSAnY3NzJyxcbiAgICBvdXRFeHRlbnNpb24sXG4gICAgc2VydmljZVdvcmtlcixcbiAgICBwb2xsLFxuICAgIHBvbHlmaWxscyxcbiAgICBwcmVzZXJ2ZVN5bWxpbmtzLFxuICAgIHN0YXRzSnNvbixcbiAgICBzdHlsZVByZXByb2Nlc3Nvck9wdGlvbnMsXG4gICAgc3VicmVzb3VyY2VJbnRlZ3JpdHksXG4gICAgdmVyYm9zZSxcbiAgICB3YXRjaCxcbiAgICBwcm9ncmVzcyA9IHRydWUsXG4gICAgZXh0ZXJuYWxQYWNrYWdlcyxcbiAgICBkZWxldGVPdXRwdXRQYXRoLFxuICB9ID0gb3B0aW9ucztcblxuICAvLyBSZXR1cm4gYWxsIHRoZSBub3JtYWxpemVkIG9wdGlvbnNcbiAgcmV0dXJuIHtcbiAgICBhZHZhbmNlZE9wdGltaXphdGlvbnM6ICEhYW90LFxuICAgIGFsbG93ZWRDb21tb25Kc0RlcGVuZGVuY2llcyxcbiAgICBiYXNlSHJlZixcbiAgICBjYWNoZU9wdGlvbnMsXG4gICAgY3Jvc3NPcmlnaW4sXG4gICAgZGVsZXRlT3V0cHV0UGF0aCxcbiAgICBleHRlcm5hbERlcGVuZGVuY2llcyxcbiAgICBleHRyYWN0TGljZW5zZXMsXG4gICAgaW5saW5lU3R5bGVMYW5ndWFnZSxcbiAgICBqaXQ6ICFhb3QsXG4gICAgc3RhdHM6ICEhc3RhdHNKc29uLFxuICAgIHBvbHlmaWxsczogcG9seWZpbGxzID09PSB1bmRlZmluZWQgfHwgQXJyYXkuaXNBcnJheShwb2x5ZmlsbHMpID8gcG9seWZpbGxzIDogW3BvbHlmaWxsc10sXG4gICAgcG9sbCxcbiAgICBwcm9ncmVzcyxcbiAgICBleHRlcm5hbFBhY2thZ2VzLFxuICAgIC8vIElmIG5vdCBleHBsaWNpdGx5IHNldCwgZGVmYXVsdCB0byB0aGUgTm9kZS5qcyBwcm9jZXNzIGFyZ3VtZW50XG4gICAgcHJlc2VydmVTeW1saW5rczogcHJlc2VydmVTeW1saW5rcyA/PyBwcm9jZXNzLmV4ZWNBcmd2LmluY2x1ZGVzKCctLXByZXNlcnZlLXN5bWxpbmtzJyksXG4gICAgc3R5bGVQcmVwcm9jZXNzb3JPcHRpb25zLFxuICAgIHN1YnJlc291cmNlSW50ZWdyaXR5LFxuICAgIHNlcnZlckVudHJ5UG9pbnQsXG4gICAgdmVyYm9zZSxcbiAgICB3YXRjaCxcbiAgICB3b3Jrc3BhY2VSb290LFxuICAgIGVudHJ5UG9pbnRzLFxuICAgIG9wdGltaXphdGlvbk9wdGlvbnMsXG4gICAgb3V0cHV0UGF0aCxcbiAgICBvdXRFeHRlbnNpb24sXG4gICAgc291cmNlbWFwT3B0aW9ucyxcbiAgICB0c2NvbmZpZyxcbiAgICBwcm9qZWN0Um9vdCxcbiAgICBhc3NldHMsXG4gICAgb3V0cHV0TmFtZXMsXG4gICAgZmlsZVJlcGxhY2VtZW50cyxcbiAgICBnbG9iYWxTdHlsZXMsXG4gICAgZ2xvYmFsU2NyaXB0cyxcbiAgICBzZXJ2aWNlV29ya2VyLFxuICAgIGluZGV4SHRtbE9wdGlvbnMsXG4gICAgdGFpbHdpbmRDb25maWd1cmF0aW9uLFxuICB9O1xufVxuXG4vKipcbiAqIE5vcm1hbGl6ZSBlbnRyeSBwb2ludCBvcHRpb25zLiBUbyBtYWludGFpbiBjb21wYXRpYmlsaXR5IHdpdGggdGhlIGxlZ2FjeSBicm93c2VyIGJ1aWxkZXIsIHdlIG5lZWQgYSBzaW5nbGUgYGJyb3dzZXJgXG4gKiBvcHRpb24gd2hpY2ggZGVmaW5lcyBhIHNpbmdsZSBlbnRyeSBwb2ludC4gSG93ZXZlciwgd2UgYWxzbyB3YW50IHRvIHN1cHBvcnQgbXVsdGlwbGUgZW50cnkgcG9pbnRzIGFzIGFuIGludGVybmFsIG9wdGlvbi5cbiAqIFRoZSB0d28gb3B0aW9ucyBhcmUgbXV0dWFsbHkgZXhjbHVzaXZlIGFuZCBpZiBgYnJvd3NlcmAgaXMgcHJvdmlkZWQgaXQgd2lsbCBiZSB1c2VkIGFzIHRoZSBzb2xlIGVudHJ5IHBvaW50LlxuICogSWYgYGVudHJ5UG9pbnRzYCBhcmUgcHJvdmlkZWQsIHRoZXkgd2lsbCBiZSB1c2VkIGFzIHRoZSBzZXQgb2YgZW50cnkgcG9pbnRzLlxuICpcbiAqIEBwYXJhbSB3b3Jrc3BhY2VSb290IFBhdGggdG8gdGhlIHJvb3Qgb2YgdGhlIEFuZ3VsYXIgd29ya3NwYWNlLlxuICogQHBhcmFtIGJyb3dzZXIgVGhlIGBicm93c2VyYCBvcHRpb24gcG9pbnRpbmcgYXQgdGhlIGFwcGxpY2F0aW9uIGVudHJ5IHBvaW50LiBXaGlsZSByZXF1aXJlZCBwZXIgdGhlIHNjaGVtYSBmaWxlLCBpdCBtYXkgYmUgb21pdHRlZCBieVxuICogICAgIHByb2dyYW1tYXRpYyB1c2FnZXMgb2YgYGJyb3dzZXItZXNidWlsZGAuXG4gKiBAcGFyYW0gZW50cnlQb2ludHMgU2V0IG9mIGVudHJ5IHBvaW50cyB0byB1c2UgaWYgcHJvdmlkZWQuXG4gKiBAcmV0dXJucyBBbiBvYmplY3QgbWFwcGluZyBlbnRyeSBwb2ludCBuYW1lcyB0byB0aGVpciBmaWxlIHBhdGhzLlxuICovXG5mdW5jdGlvbiBub3JtYWxpemVFbnRyeVBvaW50cyhcbiAgd29ya3NwYWNlUm9vdDogc3RyaW5nLFxuICBicm93c2VyOiBzdHJpbmcgfCB1bmRlZmluZWQsXG4gIGVudHJ5UG9pbnRzOiBTZXQ8c3RyaW5nPiA9IG5ldyBTZXQoKSxcbik6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4ge1xuICBpZiAoYnJvd3NlciA9PT0gJycpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2Bicm93c2VyYCBvcHRpb24gY2Fubm90IGJlIGFuIGVtcHR5IHN0cmluZy4nKTtcbiAgfVxuXG4gIC8vIGBicm93c2VyYCBhbmQgYGVudHJ5UG9pbnRzYCBhcmUgbXV0dWFsbHkgZXhjbHVzaXZlLlxuICBpZiAoYnJvd3NlciAmJiBlbnRyeVBvaW50cy5zaXplID4gMCkge1xuICAgIHRocm93IG5ldyBFcnJvcignT25seSBvbmUgb2YgYGJyb3dzZXJgIG9yIGBlbnRyeVBvaW50c2AgbWF5IGJlIHByb3ZpZGVkLicpO1xuICB9XG4gIGlmICghYnJvd3NlciAmJiBlbnRyeVBvaW50cy5zaXplID09PSAwKSB7XG4gICAgLy8gU2NoZW1hIHNob3VsZCBub3JtYWxseSByZWplY3QgdGhpcyBjYXNlLCBidXQgcHJvZ3JhbW1hdGljIHVzYWdlcyBvZiB0aGUgYnVpbGRlciBtaWdodCBtYWtlIHRoaXMgbWlzdGFrZS5cbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0VpdGhlciBgYnJvd3NlcmAgb3IgYXQgbGVhc3Qgb25lIGBlbnRyeVBvaW50c2AgdmFsdWUgbXVzdCBiZSBwcm92aWRlZC4nKTtcbiAgfVxuXG4gIC8vIFNjaGVtYSB0eXBlcyBmb3JjZSBgYnJvd3NlcmAgdG8gYWx3YXlzIGJlIHByb3ZpZGVkLCBidXQgaXQgbWF5IGJlIG9taXR0ZWQgd2hlbiB0aGUgYnVpbGRlciBpcyBpbnZva2VkIHByb2dyYW1tYXRpY2FsbHkuXG4gIGlmIChicm93c2VyKSB7XG4gICAgLy8gVXNlIGBicm93c2VyYCBhbG9uZS5cbiAgICByZXR1cm4geyAnbWFpbic6IHBhdGguam9pbih3b3Jrc3BhY2VSb290LCBicm93c2VyKSB9O1xuICB9IGVsc2Uge1xuICAgIC8vIFVzZSBgZW50cnlQb2ludHNgIGFsb25lLlxuICAgIGNvbnN0IGVudHJ5UG9pbnRQYXRoczogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHt9O1xuICAgIGZvciAoY29uc3QgZW50cnlQb2ludCBvZiBlbnRyeVBvaW50cykge1xuICAgICAgY29uc3QgcGFyc2VkRW50cnlQb2ludCA9IHBhdGgucGFyc2UoZW50cnlQb2ludCk7XG5cbiAgICAgIC8vIFVzZSB0aGUgaW5wdXQgZmlsZSBwYXRoIHdpdGhvdXQgYW4gZXh0ZW5zaW9uIGFzIHRoZSBcIm5hbWVcIiBvZiB0aGUgZW50cnkgcG9pbnQgZGljdGF0aW5nIGl0cyBvdXRwdXQgbG9jYXRpb24uXG4gICAgICAvLyBSZWxhdGl2ZSBlbnRyeSBwb2ludHMgYXJlIGdlbmVyYXRlZCBhdCB0aGUgc2FtZSByZWxhdGl2ZSBwYXRoIGluIHRoZSBvdXRwdXQgZGlyZWN0b3J5LlxuICAgICAgLy8gQWJzb2x1dGUgZW50cnkgcG9pbnRzIGFyZSBhbHdheXMgZ2VuZXJhdGVkIHdpdGggdGhlIHNhbWUgZmlsZSBuYW1lIGluIHRoZSByb290IG9mIHRoZSBvdXRwdXQgZGlyZWN0b3J5LiBUaGlzIGluY2x1ZGVzIGFic29sdXRlXG4gICAgICAvLyBwYXRocyBwb2ludGluZyBhdCBmaWxlcyBhY3R1YWxseSB3aXRoaW4gdGhlIHdvcmtzcGFjZSByb290LlxuICAgICAgY29uc3QgZW50cnlQb2ludE5hbWUgPSBwYXRoLmlzQWJzb2x1dGUoZW50cnlQb2ludClcbiAgICAgICAgPyBwYXJzZWRFbnRyeVBvaW50Lm5hbWVcbiAgICAgICAgOiBwYXRoLmpvaW4ocGFyc2VkRW50cnlQb2ludC5kaXIsIHBhcnNlZEVudHJ5UG9pbnQubmFtZSk7XG5cbiAgICAgIC8vIEdldCB0aGUgZnVsbCBmaWxlIHBhdGggdG8gdGhlIGVudHJ5IHBvaW50IGlucHV0LlxuICAgICAgY29uc3QgZW50cnlQb2ludFBhdGggPSBwYXRoLmlzQWJzb2x1dGUoZW50cnlQb2ludClcbiAgICAgICAgPyBlbnRyeVBvaW50XG4gICAgICAgIDogcGF0aC5qb2luKHdvcmtzcGFjZVJvb3QsIGVudHJ5UG9pbnQpO1xuXG4gICAgICAvLyBDaGVjayBmb3IgY29uZmxpY3RzIHdpdGggcHJldmlvdXMgZW50cnkgcG9pbnRzLlxuICAgICAgY29uc3QgZXhpc3RpbmdFbnRyeVBvaW50UGF0aCA9IGVudHJ5UG9pbnRQYXRoc1tlbnRyeVBvaW50TmFtZV07XG4gICAgICBpZiAoZXhpc3RpbmdFbnRyeVBvaW50UGF0aCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgYFxcYCR7ZXhpc3RpbmdFbnRyeVBvaW50UGF0aH1cXGAgYW5kIFxcYCR7ZW50cnlQb2ludFBhdGh9XFxgIGJvdGggb3V0cHV0IHRvIHRoZSBzYW1lIGxvY2F0aW9uIFxcYCR7ZW50cnlQb2ludE5hbWV9XFxgLmAgK1xuICAgICAgICAgICAgJyBSZW5hbWUgb3IgbW92ZSBvbmUgb2YgdGhlIGZpbGVzIHRvIGZpeCB0aGUgY29uZmxpY3QuJyxcbiAgICAgICAgKTtcbiAgICAgIH1cblxuICAgICAgZW50cnlQb2ludFBhdGhzW2VudHJ5UG9pbnROYW1lXSA9IGVudHJ5UG9pbnRQYXRoO1xuICAgIH1cblxuICAgIHJldHVybiBlbnRyeVBvaW50UGF0aHM7XG4gIH1cbn1cblxuLyoqXG4gKiBOb3JtYWxpemUgYSBkaXJlY3RvcnkgcGF0aCBzdHJpbmcuXG4gKiBDdXJyZW50bHkgb25seSByZW1vdmVzIGEgdHJhaWxpbmcgc2xhc2ggaWYgcHJlc2VudC5cbiAqIEBwYXJhbSBwYXRoIEEgcGF0aCBzdHJpbmcuXG4gKiBAcmV0dXJucyBBIG5vcm1hbGl6ZWQgcGF0aCBzdHJpbmcuXG4gKi9cbmZ1bmN0aW9uIG5vcm1hbGl6ZURpcmVjdG9yeVBhdGgocGF0aDogc3RyaW5nKTogc3RyaW5nIHtcbiAgY29uc3QgbGFzdCA9IHBhdGhbcGF0aC5sZW5ndGggLSAxXTtcbiAgaWYgKGxhc3QgPT09ICcvJyB8fCBsYXN0ID09PSAnXFxcXCcpIHtcbiAgICByZXR1cm4gcGF0aC5zbGljZSgwLCAtMSk7XG4gIH1cblxuICByZXR1cm4gcGF0aDtcbn1cbiJdfQ==
|