UNPKG

35.9 kBJavaScriptView Raw
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 */
9var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
10 if (k2 === undefined) k2 = k;
11 var desc = Object.getOwnPropertyDescriptor(m, k);
12 if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
13 desc = { enumerable: true, get: function() { return m[k]; } };
14 }
15 Object.defineProperty(o, k2, desc);
16}) : (function(o, m, k, k2) {
17 if (k2 === undefined) k2 = k;
18 o[k2] = m[k];
19}));
20var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
21 Object.defineProperty(o, "default", { enumerable: true, value: v });
22}) : function(o, v) {
23 o["default"] = v;
24});
25var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
26 var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
27 if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
28 else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
29 return c > 3 && r && Object.defineProperty(target, key, r), r;
30};
31var __importStar = (this && this.__importStar) || function (mod) {
32 if (mod && mod.__esModule) return mod;
33 var result = {};
34 if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
35 __setModuleDefault(result, mod);
36 return result;
37};
38var __metadata = (this && this.__metadata) || function (k, v) {
39 if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
40};
41var __importDefault = (this && this.__importDefault) || function (mod) {
42 return (mod && mod.__esModule) ? mod : { "default": mod };
43};
44Object.defineProperty(exports, "__esModule", { value: true });
45exports.CommandModuleError = exports.CommandModule = exports.CommandScope = void 0;
46const core_1 = require("@angular-devkit/core");
47const fs_1 = require("fs");
48const path = __importStar(require("path"));
49const yargs_1 = __importDefault(require("yargs"));
50const helpers_1 = require("yargs/helpers");
51const analytics_1 = require("../analytics/analytics");
52const analytics_collector_1 = require("../analytics/analytics-collector");
53const analytics_parameters_1 = require("../analytics/analytics-parameters");
54const completion_1 = require("../utilities/completion");
55const memoize_1 = require("../utilities/memoize");
56var CommandScope;
57(function (CommandScope) {
58 /** Command can only run inside an Angular workspace. */
59 CommandScope[CommandScope["In"] = 0] = "In";
60 /** Command can only run outside an Angular workspace. */
61 CommandScope[CommandScope["Out"] = 1] = "Out";
62 /** Command can run inside and outside an Angular workspace. */
63 CommandScope[CommandScope["Both"] = 2] = "Both";
64})(CommandScope = exports.CommandScope || (exports.CommandScope = {}));
65class CommandModule {
66 constructor(context) {
67 this.context = context;
68 this.shouldReportAnalytics = true;
69 this.scope = CommandScope.Both;
70 this.optionsWithAnalytics = new Map();
71 }
72 /**
73 * Description object which contains the long command descroption.
74 * This is used to generate JSON help wich is used in AIO.
75 *
76 * `false` will result in a hidden command.
77 */
78 get fullDescribe() {
79 return this.describe === false
80 ? false
81 : {
82 describe: this.describe,
83 ...(this.longDescriptionPath
84 ? {
85 longDescriptionRelativePath: path
86 .relative(path.join(__dirname, '../../../../'), this.longDescriptionPath)
87 .replace(/\\/g, path.posix.sep),
88 longDescription: (0, fs_1.readFileSync)(this.longDescriptionPath, 'utf8').replace(/\r\n/g, '\n'),
89 }
90 : {}),
91 };
92 }
93 get commandName() {
94 return this.command.split(' ', 1)[0];
95 }
96 async handler(args) {
97 const { _, $0, ...options } = args;
98 // Camelize options as yargs will return the object in kebab-case when camel casing is disabled.
99 const camelCasedOptions = {};
100 for (const [key, value] of Object.entries(options)) {
101 camelCasedOptions[helpers_1.Parser.camelCase(key)] = value;
102 }
103 // Set up autocompletion if appropriate.
104 const autocompletionExitCode = await (0, completion_1.considerSettingUpAutocompletion)(this.commandName, this.context.logger);
105 if (autocompletionExitCode !== undefined) {
106 process.exitCode = autocompletionExitCode;
107 return;
108 }
109 // Gather and report analytics.
110 const analytics = await this.getAnalytics();
111 const stopPeriodicFlushes = analytics && analytics.periodFlush();
112 let exitCode;
113 try {
114 if (analytics) {
115 this.reportCommandRunAnalytics(analytics);
116 this.reportWorkspaceInfoAnalytics(analytics);
117 }
118 exitCode = await this.run(camelCasedOptions);
119 }
120 catch (e) {
121 if (e instanceof core_1.schema.SchemaValidationException) {
122 this.context.logger.fatal(`Error: ${e.message}`);
123 exitCode = 1;
124 }
125 else {
126 throw e;
127 }
128 }
129 finally {
130 await (stopPeriodicFlushes === null || stopPeriodicFlushes === void 0 ? void 0 : stopPeriodicFlushes());
131 if (typeof exitCode === 'number' && exitCode > 0) {
132 process.exitCode = exitCode;
133 }
134 }
135 }
136 async getAnalytics() {
137 if (!this.shouldReportAnalytics) {
138 return undefined;
139 }
140 const userId = await (0, analytics_1.getAnalyticsUserId)(this.context,
141 // Don't prompt for `ng update` and `ng analytics` commands.
142 ['update', 'analytics'].includes(this.commandName));
143 return userId ? new analytics_collector_1.AnalyticsCollector(this.context, userId) : undefined;
144 }
145 /**
146 * Adds schema options to a command also this keeps track of options that are required for analytics.
147 * **Note:** This method should be called from the command bundler method.
148 */
149 addSchemaOptionsToCommand(localYargs, options) {
150 const booleanOptionsWithNoPrefix = new Set();
151 for (const option of options) {
152 const { default: defaultVal, positional, deprecated, description, alias, userAnalytics, type, hidden, name, choices, } = option;
153 const sharedOptions = {
154 alias,
155 hidden,
156 description,
157 deprecated,
158 choices,
159 // This should only be done when `--help` is used otherwise default will override options set in angular.json.
160 ...(this.context.args.options.help ? { default: defaultVal } : {}),
161 };
162 let dashedName = core_1.strings.dasherize(name);
163 // Handle options which have been defined in the schema with `no` prefix.
164 if (type === 'boolean' && dashedName.startsWith('no-')) {
165 dashedName = dashedName.slice(3);
166 booleanOptionsWithNoPrefix.add(dashedName);
167 }
168 if (positional === undefined) {
169 localYargs = localYargs.option(dashedName, {
170 type,
171 ...sharedOptions,
172 });
173 }
174 else {
175 localYargs = localYargs.positional(dashedName, {
176 type: type === 'array' || type === 'count' ? 'string' : type,
177 ...sharedOptions,
178 });
179 }
180 // Record option of analytics.
181 if (userAnalytics !== undefined) {
182 this.optionsWithAnalytics.set(name, userAnalytics);
183 }
184 }
185 // Handle options which have been defined in the schema with `no` prefix.
186 if (booleanOptionsWithNoPrefix.size) {
187 localYargs.middleware((options) => {
188 for (const key of booleanOptionsWithNoPrefix) {
189 if (key in options) {
190 options[`no-${key}`] = !options[key];
191 delete options[key];
192 }
193 }
194 }, false);
195 }
196 return localYargs;
197 }
198 getWorkspaceOrThrow() {
199 const { workspace } = this.context;
200 if (!workspace) {
201 throw new CommandModuleError('A workspace is required for this command.');
202 }
203 return workspace;
204 }
205 /**
206 * Flush on an interval (if the event loop is waiting).
207 *
208 * @returns a method that when called will terminate the periodic
209 * flush and call flush one last time.
210 */
211 getAnalyticsParameters(options) {
212 const parameters = {};
213 const validEventCustomDimensionAndMetrics = new Set([
214 ...Object.values(analytics_parameters_1.EventCustomDimension),
215 ...Object.values(analytics_parameters_1.EventCustomMetric),
216 ]);
217 for (const [name, ua] of this.optionsWithAnalytics) {
218 const value = options[name];
219 if ((typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') &&
220 validEventCustomDimensionAndMetrics.has(ua)) {
221 parameters[ua] = value;
222 }
223 }
224 return parameters;
225 }
226 reportCommandRunAnalytics(analytics) {
227 // eslint-disable-next-line @typescript-eslint/no-explicit-any
228 const internalMethods = yargs_1.default.getInternalMethods();
229 // $0 generate component [name] -> generate_component
230 // $0 add <collection> -> add
231 const fullCommand = internalMethods.getUsageInstance().getUsage()[0][0]
232 .split(' ')
233 .filter((x) => {
234 const code = x.charCodeAt(0);
235 return code >= 97 && code <= 122;
236 })
237 .join('_');
238 analytics.reportCommandRunEvent(fullCommand);
239 }
240 reportWorkspaceInfoAnalytics(analytics) {
241 const { workspace } = this.context;
242 if (!workspace) {
243 return;
244 }
245 let applicationProjectsCount = 0;
246 let librariesProjectsCount = 0;
247 for (const project of workspace.projects.values()) {
248 switch (project.extensions['projectType']) {
249 case 'application':
250 applicationProjectsCount++;
251 break;
252 case 'library':
253 librariesProjectsCount++;
254 break;
255 }
256 }
257 analytics.reportWorkspaceInfoEvent({
258 [analytics_parameters_1.EventCustomMetric.AllProjectsCount]: librariesProjectsCount + applicationProjectsCount,
259 [analytics_parameters_1.EventCustomMetric.ApplicationProjectsCount]: applicationProjectsCount,
260 [analytics_parameters_1.EventCustomMetric.LibraryProjectsCount]: librariesProjectsCount,
261 });
262 }
263}
264__decorate([
265 memoize_1.memoize,
266 __metadata("design:type", Function),
267 __metadata("design:paramtypes", []),
268 __metadata("design:returntype", Promise)
269], CommandModule.prototype, "getAnalytics", null);
270exports.CommandModule = CommandModule;
271/**
272 * Creates an known command module error.
273 * This is used so during executation we can filter between known validation error and real non handled errors.
274 */
275class CommandModuleError extends Error {
276}
277exports.CommandModuleError = CommandModuleError;
278//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29tbWFuZC1tb2R1bGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9wYWNrYWdlcy9hbmd1bGFyL2NsaS9zcmMvY29tbWFuZC1idWlsZGVyL2NvbW1hbmQtbW9kdWxlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQTs7Ozs7O0dBTUc7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBRUgsK0NBQWdFO0FBQ2hFLDJCQUFrQztBQUNsQywyQ0FBNkI7QUFDN0Isa0RBUWU7QUFDZiwyQ0FBc0Q7QUFDdEQsc0RBQTREO0FBQzVELDBFQUFzRTtBQUN0RSw0RUFBNEY7QUFDNUYsd0RBQTBFO0FBRTFFLGtEQUErQztBQU0vQyxJQUFZLFlBT1g7QUFQRCxXQUFZLFlBQVk7SUFDdEIsd0RBQXdEO0lBQ3hELDJDQUFFLENBQUE7SUFDRix5REFBeUQ7SUFDekQsNkNBQUcsQ0FBQTtJQUNILCtEQUErRDtJQUMvRCwrQ0FBSSxDQUFBO0FBQ04sQ0FBQyxFQVBXLFlBQVksR0FBWixvQkFBWSxLQUFaLG9CQUFZLFFBT3ZCO0FBd0NELE1BQXNCLGFBQWE7SUFTakMsWUFBK0IsT0FBdUI7UUFBdkIsWUFBTyxHQUFQLE9BQU8sQ0FBZ0I7UUFMbkMsMEJBQXFCLEdBQVksSUFBSSxDQUFDO1FBQ2hELFVBQUssR0FBaUIsWUFBWSxDQUFDLElBQUksQ0FBQztRQUVoQyx5QkFBb0IsR0FBRyxJQUFJLEdBQUcsRUFBa0IsQ0FBQztJQUVULENBQUM7SUFFMUQ7Ozs7O09BS0c7SUFDSCxJQUFXLFlBQVk7UUFDckIsT0FBTyxJQUFJLENBQUMsUUFBUSxLQUFLLEtBQUs7WUFDNUIsQ0FBQyxDQUFDLEtBQUs7WUFDUCxDQUFDLENBQUM7Z0JBQ0UsUUFBUSxFQUFFLElBQUksQ0FBQyxRQUFRO2dCQUN2QixHQUFHLENBQUMsSUFBSSxDQUFDLG1CQUFtQjtvQkFDMUIsQ0FBQyxDQUFDO3dCQUNFLDJCQUEyQixFQUFF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LyoqXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IEdvb2dsZSBMTEMgQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqXG4gKiBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhbiBNSVQtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZVxuICogZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZSBhdCBodHRwczovL2FuZ3VsYXIuaW8vbGljZW5zZVxuICovXG5cbmltcG9ydCB7IGxvZ2dpbmcsIHNjaGVtYSwgc3RyaW5ncyB9IGZyb20gJ0Bhbmd1bGFyLWRldmtpdC9jb3JlJztcbmltcG9ydCB7IHJlYWRGaWxlU3luYyB9IGZyb20gJ2ZzJztcbmltcG9ydCAqIGFzIHBhdGggZnJvbSAncGF0aCc7XG5pbXBvcnQgeWFyZ3MsIHtcbiAgQXJndW1lbnRzLFxuICBBcmd1bWVudHNDYW1lbENhc2UsXG4gIEFyZ3YsXG4gIENhbWVsQ2FzZUtleSxcbiAgUG9zaXRpb25hbE9wdGlvbnMsXG4gIENvbW1hbmRNb2R1bGUgYXMgWWFyZ3NDb21tYW5kTW9kdWxlLFxuICBPcHRpb25zIGFzIFlhcmdzT3B0aW9ucyxcbn0gZnJvbSAneWFyZ3MnO1xuaW1wb3J0IHsgUGFyc2VyIGFzIHlhcmdzUGFyc2VyIH0gZnJvbSAneWFyZ3MvaGVscGVycyc7XG5pbXBvcnQgeyBnZXRBbmFseXRpY3NVc2VySWQgfSBmcm9tICcuLi9hbmFseXRpY3MvYW5hbHl0aWNzJztcbmltcG9ydCB7IEFuYWx5dGljc0NvbGxlY3RvciB9IGZyb20gJy4uL2FuYWx5dGljcy9hbmFseXRpY3MtY29sbGVjdG9yJztcbmltcG9ydCB7IEV2ZW50Q3VzdG9tRGltZW5zaW9uLCBFdmVudEN1c3RvbU1ldHJpYyB9IGZyb20gJy4uL2FuYWx5dGljcy9hbmFseXRpY3MtcGFyYW1ldGVycyc7XG5pbXBvcnQgeyBjb25zaWRlclNldHRpbmdVcEF1dG9jb21wbGV0aW9uIH0gZnJvbSAnLi4vdXRpbGl0aWVzL2NvbXBsZXRpb24nO1xuaW1wb3J0IHsgQW5ndWxhcldvcmtzcGFjZSB9IGZyb20gJy4uL3V0aWxpdGllcy9jb25maWcnO1xuaW1wb3J0IHsgbWVtb2l6ZSB9IGZyb20gJy4uL3V0aWxpdGllcy9tZW1vaXplJztcbmltcG9ydCB7IFBhY2thZ2VNYW5hZ2VyVXRpbHMgfSBmcm9tICcuLi91dGlsaXRpZXMvcGFja2FnZS1tYW5hZ2VyJztcbmltcG9ydCB7IE9wdGlvbiB9IGZyb20gJy4vdXRpbGl0aWVzL2pzb24tc2NoZW1hJztcblxuZXhwb3J0IHR5cGUgT3B0aW9uczxUPiA9IHsgW2tleSBpbiBrZXlvZiBUIGFzIENhbWVsQ2FzZUtleTxrZXk+XTogVFtrZXldIH07XG5cbmV4cG9ydCBlbnVtIENvbW1hbmRTY29wZSB7XG4gIC8qKiBDb21tYW5kIGNhbiBvbmx5IHJ1biBpbnNpZGUgYW4gQW5ndWxhciB3b3Jrc3BhY2UuICovXG4gIEluLFxuICAvKiogQ29tbWFuZCBjYW4gb25seSBydW4gb3V0c2lkZSBhbiBBbmd1bGFyIHdvcmtzcGFjZS4gKi9cbiAgT3V0LFxuICAvKiogQ29tbWFuZCBjYW4gcnVuIGluc2lkZSBhbmQgb3V0c2lkZSBhbiBBbmd1bGFyIHdvcmtzcGFjZS4gKi9cbiAgQm90aCxcbn1cblxuZXhwb3J0IGludGVyZmFjZSBDb21tYW5kQ29udGV4dCB7XG4gIGN1cnJlbnREaXJlY3Rvcnk6IHN0cmluZztcbiAgcm9vdDogc3RyaW5nO1xuICB3b3Jrc3BhY2U/OiBBbmd1bGFyV29ya3NwYWNlO1xuICBnbG9iYWxDb25maWd1cmF0aW9uOiBBbmd1bGFyV29ya3NwYWNlO1xuICBsb2dnZXI6IGxvZ2dpbmcuTG9nZ2VyO1xuICBwYWNrYWdlTWFuYWdlcjogUGFja2FnZU1hbmFnZXJVdGlscztcbiAgLyoqIEFyZ3VtZW50cyBwYXJzZWQgaW4gZnJlZS1mcm9tIHdpdGhvdXQgcGFyc2VyIGNvbmZpZ3VyYXRpb24uICovXG4gIGFyZ3M6IHtcbiAgICBwb3NpdGlvbmFsOiBzdHJpbmdbXTtcbiAgICBvcHRpb25zOiB7XG4gICAgICBoZWxwOiBib29sZWFuO1xuICAgICAganNvbkhlbHA6IGJvb2xlYW47XG4gICAgICBnZXRZYXJnc0NvbXBsZXRpb25zOiBib29sZWFuO1xuICAgIH0gJiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjtcbiAgfTtcbn1cblxuZXhwb3J0IHR5cGUgT3RoZXJPcHRpb25zID0gUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ29tbWFuZE1vZHVsZUltcGxlbWVudGF0aW9uPFQgZXh0ZW5kcyB7fSA9IHt9PlxuICBleHRlbmRzIE9taXQ8WWFyZ3NDb21tYW5kTW9kdWxlPHt9LCBUPiwgJ2J1aWxkZXInIHwgJ2hhbmRsZXInPiB7XG4gIC8qKiBTY29wZSBpbiB3aGljaCB0aGUgY29tbWFuZCBjYW4gYmUgZXhlY3V0ZWQgaW4uICovXG4gIHNjb3BlOiBDb21tYW5kU2NvcGU7XG4gIC8qKiBQYXRoIHVzZWQgdG8gbG9hZCB0aGUgbG9uZyBkZXNjcmlwdGlvbiBmb3IgdGhlIGNvbW1hbmQgaW4gSlNPTiBoZWxwIHRleHQuICovXG4gIGxvbmdEZXNjcmlwdGlvblBhdGg/OiBzdHJpbmc7XG4gIC8qKiBPYmplY3QgZGVjbGFyaW5nIHRoZSBvcHRpb25zIHRoZSBjb21tYW5kIGFjY2VwdHMsIG9yIGEgZnVuY3Rpb24gYWNjZXB0aW5nIGFuZCByZXR1cm5pbmcgYSB5YXJncyBpbnN0YW5jZS4gKi9cbiAgYnVpbGRlcihhcmd2OiBBcmd2KTogUHJvbWlzZTxBcmd2PFQ+PiB8IEFyZ3Y8VD47XG4gIC8qKiBBIGZ1bmN0aW9uIHdoaWNoIHdpbGwgYmUgcGFzc2VkIHRoZSBwYXJzZWQgYXJndi4gKi9cbiAgcnVuKG9wdGlvbnM6IE9wdGlvbnM8VD4gJiBPdGhlck9wdGlvbnMpOiBQcm9taXNlPG51bWJlciB8IHZvaWQ+IHwgbnVtYmVyIHwgdm9pZDtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBGdWxsRGVzY3JpYmUge1xuICBkZXNjcmliZT86IHN0cmluZztcbiAgbG9uZ0Rlc2NyaXB0aW9uPzogc3RyaW5nO1xuICBsb25nRGVzY3JpcHRpb25SZWxhdGl2ZVBhdGg/OiBzdHJpbmc7XG59XG5cbmV4cG9ydCBhYnN0cmFjdCBjbGFzcyBDb21tYW5kTW9kdWxlPFQgZXh0ZW5kcyB7fSA9IHt9PiBpbXBsZW1lbnRzIENvbW1hbmRNb2R1bGVJbXBsZW1lbnRhdGlvbjxUPiB7XG4gIGFic3RyYWN0IHJlYWRvbmx5IGNvbW1hbmQ6IHN0cmluZztcbiAgYWJzdHJhY3QgcmVhZG9ubHkgZGVzY3JpYmU6IHN0cmluZyB8IGZhbHNlO1xuICBhYnN0cmFjdCByZWFkb25seSBsb25nRGVzY3JpcHRpb25QYXRoPzogc3RyaW5nO1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgc2hvdWxkUmVwb3J0QW5hbHl0aWNzOiBib29sZWFuID0gdHJ1ZTtcbiAgcmVhZG9ubHkgc2NvcGU6IENvbW1hbmRTY29wZSA9IENvbW1hbmRTY29wZS5Cb3RoO1xuXG4gIHByaXZhdGUgcmVhZG9ubHkgb3B0aW9uc1dpdGhBbmFseXRpY3MgPSBuZXcgTWFwPHN0cmluZywgc3RyaW5nPigpO1xuXG4gIGNvbnN0cnVjdG9yKHByb3RlY3RlZCByZWFkb25seSBjb250ZXh0OiBDb21tYW5kQ29udGV4dCkge31cblxuICAvKipcbiAgICogRGVzY3JpcHRpb24gb2JqZWN0IHdoaWNoIGNvbnRhaW5zIHRoZSBsb25nIGNvbW1hbmQgZGVzY3JvcHRpb24uXG4gICAqIFRoaXMgaXMgdXNlZCB0byBnZW5lcmF0ZSBKU09OIGhlbHAgd2ljaCBpcyB1c2VkIGluIEFJTy5cbiAgICpcbiAgICogYGZhbHNlYCB3aWxsIHJlc3VsdCBpbiBhIGhpZGRlbiBjb21tYW5kLlxuICAgKi9cbiAgcHVibGljIGdldCBmdWxsRGVzY3JpYmUoKTogRnVsbERlc2NyaWJlIHwgZmFsc2Uge1xuICAgIHJldHVybiB0aGlzLmRlc2NyaWJlID09PSBmYWxzZVxuICAgICAgPyBmYWxzZVxuICAgICAgOiB7XG4gICAgICAgICAgZGVzY3JpYmU6IHRoaXMuZGVzY3JpYmUsXG4gICAgICAgICAgLi4uKHRoaXMubG9uZ0Rlc2NyaXB0aW9uUGF0aFxuICAgICAgICAgICAgPyB7XG4gICAgICAgICAgICAgICAgbG9uZ0Rlc2NyaXB0aW9uUmVsYXRpdmVQYXRoOiBwYXRoXG4gICAgICAgICAgICAgICAgICAucmVsYXRpdmUocGF0aC5qb2luKF9fZGlybmFtZSwgJy4uLy4uLy4uLy4uLycpLCB0aGlzLmxvbmdEZXNjcmlwdGlvblBhdGgpXG4gICAgICAgICAgICAgICAgICAucmVwbGFjZSgvXFxcXC9nLCBwYXRoLnBvc2l4LnNlcCksXG4gICAgICAgICAgICAgICAgbG9uZ0Rlc2NyaXB0aW9uOiByZWFkRmlsZVN5bmModGhpcy5sb25nRGVzY3JpcHRpb25QYXRoLCAndXRmOCcpLnJlcGxhY2UoXG4gICAgICAgICAgICAgICAgICAvXFxyXFxuL2csXG4gICAgICAgICAgICAgICAgICAnXFxuJyxcbiAgICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICA6IHt9KSxcbiAgICAgICAgfTtcbiAgfVxuXG4gIHByb3RlY3RlZCBnZXQgY29tbWFuZE5hbWUoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gdGhpcy5jb21tYW5kLnNwbGl0KCcgJywgMSlbMF07XG4gIH1cblxuICBhYnN0cmFjdCBidWlsZGVyKGFyZ3Y6IEFyZ3YpOiBQcm9taXNlPEFyZ3Y8VD4+IHwgQXJndjxUPjtcbiAgYWJzdHJhY3QgcnVuKG9wdGlvbnM6IE9wdGlvbnM8VD4gJiBPdGhlck9wdGlvbnMpOiBQcm9taXNlPG51bWJlciB8IHZvaWQ+IHwgbnVtYmVyIHwgdm9pZDtcblxuICBhc3luYyBoYW5kbGVyKGFyZ3M6IEFyZ3VtZW50c0NhbWVsQ2FzZTxUPiAmIE90aGVyT3B0aW9ucyk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IHsgXywgJDAsIC4uLm9wdGlvbnMgfSA9IGFyZ3M7XG5cbiAgICAvLyBDYW1lbGl6ZSBvcHRpb25zIGFzIHlhcmdzIHdpbGwgcmV0dXJuIHRoZSBvYmplY3QgaW4ga2ViYWItY2FzZSB3aGVuIGNhbWVsIGNhc2luZyBpcyBkaXNhYmxlZC5cbiAgICBjb25zdCBjYW1lbENhc2VkT3B0aW9uczogUmVjb3JkPHN0cmluZywgdW5rbm93bj4gPSB7fTtcbiAgICBmb3IgKGNvbnN0IFtrZXksIHZhbHVlXSBvZiBPYmplY3QuZW50cmllcyhvcHRpb25zKSkge1xuICAgICAgY2FtZWxDYXNlZE9wdGlvbnNbeWFyZ3NQYXJzZXIuY2FtZWxDYXNlKGtleSldID0gdmFsdWU7XG4gICAgfVxuXG4gICAgLy8gU2V0IHVwIGF1dG9jb21wbGV0aW9uIGlmIGFwcHJvcHJpYXRlLlxuICAgIGNvbnN0IGF1dG9jb21wbGV0aW9uRXhpdENvZGUgPSBhd2FpdCBjb25zaWRlclNldHRpbmdVcEF1dG9jb21wbGV0aW9uKFxuICAgICAgdGhpcy5jb21tYW5kTmFtZSxcbiAgICAgIHRoaXMuY29udGV4dC5sb2dnZXIsXG4gICAgKTtcbiAgICBpZiAoYXV0b2NvbXBsZXRpb25FeGl0Q29kZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBwcm9jZXNzLmV4aXRDb2RlID0gYXV0b2NvbXBsZXRpb25FeGl0Q29kZTtcblxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIEdhdGhlciBhbmQgcmVwb3J0IGFuYWx5dGljcy5cbiAgICBjb25zdCBhbmFseXRpY3MgPSBhd2FpdCB0aGlzLmdldEFuYWx5dGljcygpO1xuICAgIGNvbnN0IHN0b3BQZXJpb2RpY0ZsdXNoZXMgPSBhbmFseXRpY3MgJiYgYW5hbHl0aWNzLnBlcmlvZEZsdXNoKCk7XG5cbiAgICBsZXQgZXhpdENvZGU6IG51bWJlciB8IHZvaWQgfCB1bmRlZmluZWQ7XG4gICAgdHJ5IHtcbiAgICAgIGlmIChhbmFseXRpY3MpIHtcbiAgICAgICAgdGhpcy5yZXBvcnRDb21tYW5kUnVuQW5hbHl0aWNzKGFuYWx5dGljcyk7XG4gICAgICAgIHRoaXMucmVwb3J0V29ya3NwYWNlSW5mb0FuYWx5dGljcyhhbmFseXRpY3MpO1xuICAgICAgfVxuXG4gICAgICBleGl0Q29kZSA9IGF3YWl0IHRoaXMucnVuKGNhbWVsQ2FzZWRPcHRpb25zIGFzIE9wdGlvbnM8VD4gJiBPdGhlck9wdGlvbnMpO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIGlmIChlIGluc3RhbmNlb2Ygc2NoZW1hLlNjaGVtYVZhbGlkYXRpb25FeGNlcHRpb24pIHtcbiAgICAgICAgdGhpcy5jb250ZXh0LmxvZ2dlci5mYXRhbChgRXJyb3I6ICR7ZS5tZXNzYWdlfWApO1xuICAgICAgICBleGl0Q29kZSA9IDE7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aHJvdyBlO1xuICAgICAgfVxuICAgIH0gZmluYWxseSB7XG4gICAgICBhd2FpdCBzdG9wUGVyaW9kaWNGbHVzaGVzPy4oKTtcblxuICAgICAgaWYgKHR5cGVvZiBleGl0Q29kZSA9PT0gJ251bWJlcicgJiYgZXhpdENvZGUgPiAwKSB7XG4gICAgICAgIHByb2Nlc3MuZXhpdENvZGUgPSBleGl0Q29kZTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBAbWVtb2l6ZVxuICBwcm90ZWN0ZWQgYXN5bmMgZ2V0QW5hbHl0aWNzKCk6IFByb21pc2U8QW5hbHl0aWNzQ29sbGVjdG9yIHwgdW5kZWZpbmVkPiB7XG4gICAgaWYgKCF0aGlzLnNob3VsZFJlcG9ydEFuYWx5dGljcykge1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICBjb25zdCB1c2VySWQgPSBhd2FpdCBnZXRBbmFseXRpY3NVc2VySWQoXG4gICAgICB0aGlzLmNvbnRleHQsXG4gICAgICAvLyBEb24ndCBwcm9tcHQgZm9yIGBuZyB1cGRhdGVgIGFuZCBgbmcgYW5hbHl0aWNzYCBjb21tYW5kcy5cbiAgICAgIFsndXBkYXRlJywgJ2FuYWx5dGljcyddLmluY2x1ZGVzKHRoaXMuY29tbWFuZE5hbWUpLFxuICAgICk7XG5cbiAgICByZXR1cm4gdXNlcklkID8gbmV3IEFuYWx5dGljc0NvbGxlY3Rvcih0aGlzLmNvbnRleHQsIHVzZXJJZCkgOiB1bmRlZmluZWQ7XG4gIH1cblxuICAvKipcbiAgICogQWRkcyBzY2hlbWEgb3B0aW9ucyB0byBhIGNvbW1hbmQgYWxzbyB0aGlzIGtlZXBzIHRyYWNrIG9mIG9wdGlvbnMgdGhhdCBhcmUgcmVxdWlyZWQgZm9yIGFuYWx5dGljcy5cbiAgICogKipOb3RlOioqIFRoaXMgbWV0aG9kIHNob3VsZCBiZSBjYWxsZWQgZnJvbSB0aGUgY29tbWFuZCBidW5kbGVyIG1ldGhvZC5cbiAgICovXG4gIHByb3RlY3RlZCBhZGRTY2hlbWFPcHRpb25zVG9Db21tYW5kPFQ+KGxvY2FsWWFyZ3M6IEFyZ3Y8VD4sIG9wdGlvbnM6IE9wdGlvbltdKTogQXJndjxUPiB7XG4gICAgY29uc3QgYm9vbGVhbk9wdGlvbnNXaXRoTm9QcmVmaXggPSBuZXcgU2V0PHN0cmluZz4oKTtcblxuICAgIGZvciAoY29uc3Qgb3B0aW9uIG9mIG9wdGlvbnMpIHtcbiAgICAgIGNvbnN0IHtcbiAgICAgICAgZGVmYXVsdDogZGVmYXVsdFZhbCxcbiAgICAgICAgcG9zaXRpb25hbCxcbiAgICAgICAgZGVwcmVjYXRlZCxcbiAgICAgICAgZGVzY3JpcHRpb24sXG4gICAgICAgIGFsaWFzLFxuICAgICAgICB1c2VyQW5hbHl0aWNzLFxuICAgICAgICB0eXBlLFxuICAgICAgICBoaWRkZW4sXG4gICAgICAgIG5hbWUsXG4gICAgICAgIGNob2ljZXMsXG4gICAgICB9ID0gb3B0aW9uO1xuXG4gICAgICBjb25zdCBzaGFyZWRPcHRpb25zOiBZYXJnc09wdGlvbnMgJiBQb3NpdGlvbmFsT3B0aW9ucyA9IHtcbiAgICAgICAgYWxpYXMsXG4gICAgICAgIGhpZGRlbixcbiAgICAgICAgZGVzY3JpcHRpb24sXG4gICAgICAgIGRlcHJlY2F0ZWQsXG4gICAgICAgIGNob2ljZXMsXG4gICAgICAgIC8vIFRoaXMgc2hvdWxkIG9ubHkgYmUgZG9uZSB3aGVuIGAtLWhlbHBgIGlzIHVzZWQgb3RoZXJ3aXNlIGRlZmF1bHQgd2lsbCBvdmVycmlkZSBvcHRpb25zIHNldCBpbiBhbmd1bGFyLmpzb24uXG4gICAgICAgIC4uLih0aGlzLmNvbnRleHQuYXJncy5vcHRpb25zLmhlbHAgPyB7IGRlZmF1bHQ6IGRlZmF1bHRWYWwgfSA6IHt9KSxcbiAgICAgIH07XG5cbiAgICAgIGxldCBkYXNoZWROYW1lID0gc3RyaW5ncy5kYXNoZXJpemUobmFtZSk7XG5cbiAgICAgIC8vIEhhbmRsZSBvcHRpb25zIHdoaWNoIGhhdmUgYmVlbiBkZWZpbmVkIGluIHRoZSBzY2hlbWEgd2l0aCBgbm9gIHByZWZpeC5cbiAgICAgIGlmICh0eXBlID09PSAnYm9vbGVhbicgJiYgZGFzaGVkTmFtZS5zdGFydHNXaXRoKCduby0nKSkge1xuICAgICAgICBkYXNoZWROYW1lID0gZGFzaGVkTmFtZS5zbGljZSgzKTtcbiAgICAgICAgYm9vbGVhbk9wdGlvbnNXaXRoTm9QcmVmaXguYWRkKGRhc2hlZE5hbWUpO1xuICAgICAgfVxuXG4gICAgICBpZiAocG9zaXRpb25hbCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGxvY2FsWWFyZ3MgPSBsb2NhbFlhcmdzLm9wdGlvbihkYXNoZWROYW1lLCB7XG4gICAgICAgICAgdHlwZSxcbiAgICAgICAgICAuLi5zaGFyZWRPcHRpb25zLFxuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGxvY2FsWWFyZ3MgPSBsb2NhbFlhcmdzLnBvc2l0aW9uYWwoZGFzaGVkTmFtZSwge1xuICAgICAgICAgIHR5cGU6IHR5cGUgPT09ICdhcnJheScgfHwgdHlwZSA9PT0gJ2NvdW50JyA/ICdzdHJpbmcnIDogdHlwZSxcbiAgICAgICAgICAuLi5zaGFyZWRPcHRpb25zLFxuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgLy8gUmVjb3JkIG9wdGlvbiBvZiBhbmFseXRpY3MuXG4gICAgICBpZiAodXNlckFuYWx5dGljcyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHRoaXMub3B0aW9uc1dpdGhBbmFseXRpY3Muc2V0KG5hbWUsIHVzZXJBbmFseXRpY3MpO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIEhhbmRsZSBvcHRpb25zIHdoaWNoIGhhdmUgYmVlbiBkZWZpbmVkIGluIHRoZSBzY2hlbWEgd2l0aCBgbm9gIHByZWZpeC5cbiAgICBpZiAoYm9vbGVhbk9wdGlvbnNXaXRoTm9QcmVmaXguc2l6ZSkge1xuICAgICAgbG9jYWxZYXJncy5taWRkbGV3YXJlKChvcHRpb25zOiBBcmd1bWVudHMpID0+IHtcbiAgICAgICAgZm9yIChjb25zdCBrZXkgb2YgYm9vbGVhbk9wdGlvbnNXaXRoTm9QcmVmaXgpIHtcbiAgICAgICAgICBpZiAoa2V5IGluIG9wdGlvbnMpIHtcbiAgICAgICAgICAgIG9wdGlvbnNbYG5vLSR7a2V5fWBdID0gIW9wdGlvbnNba2V5XTtcbiAgICAgICAgICAgIGRlbGV0ZSBvcHRpb25zW2tleV07XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9LCBmYWxzZSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGxvY2FsWWFyZ3M7XG4gIH1cblxuICBwcm90ZWN0ZWQgZ2V0V29ya3NwYWNlT3JUaHJvdygpOiBBbmd1bGFyV29ya3NwYWNlIHtcbiAgICBjb25zdCB7IHdvcmtzcGFjZSB9ID0gdGhpcy5jb250ZXh0O1xuICAgIGlmICghd29ya3NwYWNlKSB7XG4gICAgICB0aHJvdyBuZXcgQ29tbWFuZE1vZHVsZUVycm9yKCdBIHdvcmtzcGFjZSBpcyByZXF1aXJlZCBmb3IgdGhpcyBjb21tYW5kLicpO1xuICAgIH1cblxuICAgIHJldHVybiB3b3Jrc3BhY2U7XG4gIH1cblxuICAvKipcbiAgICogRmx1c2ggb24gYW4gaW50ZXJ2YWwgKGlmIHRoZSBldmVudCBsb29wIGlzIHdhaXRpbmcpLlxuICAgKlxuICAgKiBAcmV0dXJucyBhIG1ldGhvZCB0aGF0IHdoZW4gY2FsbGVkIHdpbGwgdGVybWluYXRlIHRoZSBwZXJpb2RpY1xuICAgKiBmbHVzaCBhbmQgY2FsbCBmbHVzaCBvbmUgbGFzdCB0aW1lLlxuICAgKi9cbiAgcHJvdGVjdGVkIGdldEFuYWx5dGljc1BhcmFtZXRlcnMoXG4gICAgb3B0aW9uczogKE9wdGlvbnM8VD4gJiBPdGhlck9wdGlvbnMpIHwgT3RoZXJPcHRpb25zLFxuICApOiBQYXJ0aWFsPFJlY29yZDxFdmVudEN1c3RvbURpbWVuc2lvbiB8IEV2ZW50Q3VzdG9tTWV0cmljLCBzdHJpbmcgfCBib29sZWFuIHwgbnVtYmVyPj4ge1xuICAgIGNvbnN0IHBhcmFtZXRlcnM6IFBhcnRpYWw8XG4gICAgICBSZWNvcmQ8RXZlbnRDdXN0b21EaW1lbnNpb24gfCBFdmVudEN1c3RvbU1ldHJpYywgc3RyaW5nIHwgYm9vbGVhbiB8IG51bWJlcj5cbiAgICA+ID0ge307XG5cbiAgICBjb25zdCB2YWxpZEV2ZW50Q3VzdG9tRGltZW5zaW9uQW5kTWV0cmljcyA9IG5ldyBTZXQoW1xuICAgICAgLi4uT2JqZWN0LnZhbHVlcyhFdmVudEN1c3RvbURpbWVuc2lvbiksXG4gICAgICAuLi5PYmplY3QudmFsdWVzKEV2ZW50Q3VzdG9tTWV0cmljKSxcbiAgICBdKTtcblxuICAgIGZvciAoY29uc3QgW25hbWUsIHVhXSBvZiB0aGlzLm9wdGlvbnNXaXRoQW5hbHl0aWNzKSB7XG4gICAgICBjb25zdCB2YWx1ZSA9IG9wdGlvbnNbbmFtZV07XG4gICAgICBpZiAoXG4gICAgICAgICh0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnIHx8IHR5cGVvZiB2YWx1ZSA9PT0gJ251bWJlcicgfHwgdHlwZW9mIHZhbHVlID09PSAnYm9vbGVhbicpICYmXG4gICAgICAgIHZhbGlkRXZlbnRDdXN0b21EaW1lbnNpb25BbmRNZXRyaWNzLmhhcyh1YSBhcyBFdmVudEN1c3RvbURpbWVuc2lvbiB8IEV2ZW50Q3VzdG9tTWV0cmljKVxuICAgICAgKSB7XG4gICAgICAgIHBhcmFtZXRlcnNbdWEgYXMgRXZlbnRDdXN0b21EaW1lbnNpb24gfCBFdmVudEN1c3RvbU1ldHJpY10gPSB2YWx1ZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gcGFyYW1ldGVycztcbiAgfVxuXG4gIHByaXZhdGUgcmVwb3J0Q29tbWFuZFJ1bkFuYWx5dGljcyhhbmFseXRpY3M6IEFuYWx5dGljc0NvbGxlY3Rvcik6IHZvaWQge1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55XG4gICAgY29uc3QgaW50ZXJuYWxNZXRob2RzID0gKHlhcmdzIGFzIGFueSkuZ2V0SW50ZXJuYWxNZXRob2RzKCk7XG4gICAgLy8gJDAgZ2VuZXJhdGUgY29tcG9uZW50IFtuYW1lXSAtPiBnZW5lcmF0ZV9jb21wb25lbnRcbiAgICAvLyAkMCBhZGQgPGNvbGxlY3Rpb24+IC0+IGFkZFxuICAgIGNvbnN0IGZ1bGxDb21tYW5kID0gKGludGVybmFsTWV0aG9kcy5nZXRVc2FnZUluc3RhbmNlKCkuZ2V0VXNhZ2UoKVswXVswXSBhcyBzdHJpbmcpXG4gICAgICAuc3BsaXQoJyAnKVxuICAgICAgLmZpbHRlcigoeCkgPT4ge1xuICAgICAgICBjb25zdCBjb2RlID0geC5jaGFyQ29kZUF0KDApO1xuXG4gICAgICAgIHJldHVybiBjb2RlID49IDk3ICYmIGNvZGUgPD0gMTIyO1xuICAgICAgfSlcbiAgICAgIC5qb2luKCdfJyk7XG5cbiAgICBhbmFseXRpY3MucmVwb3J0Q29tbWFuZFJ1bkV2ZW50KGZ1bGxDb21tYW5kKTtcbiAgfVxuXG4gIHByaXZhdGUgcmVwb3J0V29ya3NwYWNlSW5mb0FuYWx5dGljcyhhbmFseXRpY3M6IEFuYWx5dGljc0NvbGxlY3Rvcik6IHZvaWQge1xuICAgIGNvbnN0IHsgd29ya3NwYWNlIH0gPSB0aGlzLmNvbnRleHQ7XG4gICAgaWYgKCF3b3Jrc3BhY2UpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBsZXQgYXBwbGljYXRpb25Qcm9qZWN0c0NvdW50ID0gMDtcbiAgICBsZXQgbGlicmFyaWVzUHJvamVjdHNDb3VudCA9IDA7XG4gICAgZm9yIChjb25zdCBwcm9qZWN0IG9mIHdvcmtzcGFjZS5wcm9qZWN0cy52YWx1ZXMoKSkge1xuICAgICAgc3dpdGNoIChwcm9qZWN0LmV4dGVuc2lvbnNbJ3Byb2plY3RUeXBlJ10pIHtcbiAgICAgICAgY2FzZSAnYXBwbGljYXRpb24nOlxuICAgICAgICAgIGFwcGxpY2F0aW9uUHJvamVjdHNDb3VudCsrO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdsaWJyYXJ5JzpcbiAgICAgICAgICBsaWJyYXJpZXNQcm9qZWN0c0NvdW50Kys7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuXG4gICAgYW5hbHl0aWNzLnJlcG9ydFdvcmtzcGFjZUluZm9FdmVudCh7XG4gICAgICBbRXZlbnRDdXN0b21NZXRyaWMuQWxsUHJvamVjdHNDb3VudF06IGxpYnJhcmllc1Byb2plY3RzQ291bnQgKyBhcHBsaWNhdGlvblByb2plY3RzQ291bnQsXG4gICAgICBbRXZlbnRDdXN0b21NZXRyaWMuQXBwbGljYXRpb25Qcm9qZWN0c0NvdW50XTogYXBwbGljYXRpb25Qcm9qZWN0c0NvdW50LFxuICAgICAgW0V2ZW50Q3VzdG9tTWV0cmljLkxpYnJhcnlQcm9qZWN0c0NvdW50XTogbGlicmFyaWVzUHJvamVjdHNDb3VudCxcbiAgICB9KTtcbiAgfVxufVxuXG4vKipcbiAqIENyZWF0ZXMgYW4ga25vd24gY29tbWFuZCBtb2R1bGUgZXJyb3IuXG4gKiBUaGlzIGlzIHVzZWQgc28gZHVyaW5nIGV4ZWN1dGF0aW9uIHdlIGNhbiBmaWx0ZXIgYmV0d2VlbiBrbm93biB2YWxpZGF0aW9uIGVycm9yIGFuZCByZWFsIG5vbiBoYW5kbGVkIGVycm9ycy5cbiAqL1xuZXhwb3J0IGNsYXNzIENvbW1hbmRNb2R1bGVFcnJvciBleHRlbmRzIEVycm9yIHt9XG4iXX0=
\No newline at end of file