UNPKG

@angular/cli

Version:
181 lines • 25.4 kB
"use strict"; /** * @license * Copyright Google LLC All Rights Reserved. * * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://angular.io/license */ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.AnalyticsCollector = void 0; const crypto_1 = require("crypto"); const https = __importStar(require("https")); const os = __importStar(require("os")); const querystring = __importStar(require("querystring")); const semver = __importStar(require("semver")); const environment_options_1 = require("../utilities/environment-options"); const error_1 = require("../utilities/error"); const version_1 = require("../utilities/version"); const analytics_parameters_1 = require("./analytics-parameters"); const TRACKING_ID_PROD = 'G-VETNJBW8L4'; const TRACKING_ID_STAGING = 'G-TBMPRL1BTM'; class AnalyticsCollector { constructor(context, userId) { this.context = context; const requestParameters = { [analytics_parameters_1.RequestParameter.ProtocolVersion]: 2, [analytics_parameters_1.RequestParameter.ClientId]: userId, [analytics_parameters_1.RequestParameter.UserId]: userId, [analytics_parameters_1.RequestParameter.TrackingId]: /^\d+\.\d+\.\d+$/.test(version_1.VERSION.full) && version_1.VERSION.full !== '0.0.0' ? TRACKING_ID_PROD : TRACKING_ID_STAGING, // Built-in user properties [analytics_parameters_1.RequestParameter.SessionId]: (0, crypto_1.randomUUID)(), [analytics_parameters_1.RequestParameter.UserAgentArchitecture]: os.arch(), [analytics_parameters_1.RequestParameter.UserAgentPlatform]: os.platform(), [analytics_parameters_1.RequestParameter.UserAgentPlatformVersion]: os.release(), [analytics_parameters_1.RequestParameter.UserAgentMobile]: 0, [analytics_parameters_1.RequestParameter.SessionEngaged]: 1, // The below is needed for tech details to be collected. [analytics_parameters_1.RequestParameter.UserAgentFullVersionList]: 'Google%20Chrome;111.0.5563.64|Not(A%3ABrand;8.0.0.0|Chromium;111.0.5563.64', }; if (environment_options_1.ngDebug) { requestParameters[analytics_parameters_1.RequestParameter.DebugView] = 1; } this.requestParameterStringified = querystring.stringify(requestParameters); const parsedVersion = semver.parse(process.version); const packageManagerVersion = context.packageManager.version; this.userParameters = { // While architecture is being collect by GA as UserAgentArchitecture. // It doesn't look like there is a way to query this. Therefore we collect this as a custom user dimension too. [analytics_parameters_1.UserCustomDimension.OsArchitecture]: os.arch(), // While User ID is being collected by GA, this is not visible in reports/for filtering. [analytics_parameters_1.UserCustomDimension.UserId]: userId, [analytics_parameters_1.UserCustomDimension.NodeVersion]: parsedVersion ? `${parsedVersion.major}.${parsedVersion.minor}.${parsedVersion.patch}` : 'other', [analytics_parameters_1.UserCustomDimension.NodeMajorVersion]: parsedVersion?.major, [analytics_parameters_1.UserCustomDimension.PackageManager]: context.packageManager.name, [analytics_parameters_1.UserCustomDimension.PackageManagerVersion]: packageManagerVersion, [analytics_parameters_1.UserCustomDimension.PackageManagerMajorVersion]: packageManagerVersion ? +packageManagerVersion.split('.', 1)[0] : undefined, [analytics_parameters_1.UserCustomDimension.AngularCLIVersion]: version_1.VERSION.full, [analytics_parameters_1.UserCustomDimension.AngularCLIMajorVersion]: version_1.VERSION.major, }; } reportWorkspaceInfoEvent(parameters) { this.event('workspace_info', parameters); } reportRebuildRunEvent(parameters) { this.event('run_rebuild', parameters); } reportBuildRunEvent(parameters) { this.event('run_build', parameters); } reportArchitectRunEvent(parameters) { this.event('run_architect', parameters); } reportSchematicRunEvent(parameters) { this.event('run_schematic', parameters); } reportCommandRunEvent(command) { this.event('run_command', { [analytics_parameters_1.EventCustomDimension.Command]: command }); } event(eventName, parameters) { this.trackingEventsQueue ?? (this.trackingEventsQueue = []); this.trackingEventsQueue.push({ ...this.userParameters, ...parameters, 'en': eventName, }); } /** * Flush on an interval (if the event loop is waiting). * * @returns a method that when called will terminate the periodic * flush and call flush one last time. */ periodFlush() { let analyticsFlushPromise = Promise.resolve(); const analyticsFlushInterval = setInterval(() => { if (this.trackingEventsQueue?.length) { analyticsFlushPromise = analyticsFlushPromise.then(() => this.flush()); } }, 4000); return () => { clearInterval(analyticsFlushInterval); // Flush one last time. return analyticsFlushPromise.then(() => this.flush()); }; } async flush() { const pendingTrackingEvents = this.trackingEventsQueue; this.context.logger.debug(`Analytics flush size. ${pendingTrackingEvents?.length}.`); if (!pendingTrackingEvents?.length) { return; } // The below is needed so that if flush is called multiple times, // we don't report the same event multiple times. this.trackingEventsQueue = undefined; try { await this.send(pendingTrackingEvents); } catch (error) { // Failure to report analytics shouldn't crash the CLI. (0, error_1.assertIsError)(error); this.context.logger.debug(`Send analytics error. ${error.message}.`); } } async send(data) { return new Promise((resolve, reject) => { const request = https.request({ host: 'www.google-analytics.com', method: 'POST', path: '/g/collect?' + this.requestParameterStringified, headers: { // The below is needed for tech details to be collected even though we provide our own information from the OS Node.js module 'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36', }, }, (response) => { // The below is needed as otherwise the response will never close which will cause the CLI not to terminate. response.on('data', () => { }); if (response.statusCode !== 200 && response.statusCode !== 204) { reject(new Error(`Analytics reporting failed with status code: ${response.statusCode}.`)); } else { resolve(); } }); request.on('error', reject); const queryParameters = data.map((p) => querystring.stringify(p)).join('\n'); request.write(queryParameters); request.end(); }); } } exports.AnalyticsCollector = AnalyticsCollector; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYW5hbHl0aWNzLWNvbGxlY3Rvci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uLy4uL3BhY2thZ2VzL2FuZ3VsYXIvY2xpL3NyYy9hbmFseXRpY3MvYW5hbHl0aWNzLWNvbGxlY3Rvci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUE7Ozs7OztHQU1HOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUVILG1DQUFvQztBQUNwQyw2Q0FBK0I7QUFDL0IsdUNBQXlCO0FBQ3pCLHlEQUEyQztBQUMzQywrQ0FBaUM7QUFFakMsMEVBQTJEO0FBQzNELDhDQUFtRDtBQUNuRCxrREFBK0M7QUFDL0MsaUVBTWdDO0FBRWhDLE1BQU0sZ0JBQWdCLEdBQUcsY0FBYyxDQUFDO0FBQ3hDLE1BQU0sbUJBQW1CLEdBQUcsY0FBYyxDQUFDO0FBRTNDLE1BQWEsa0JBQWtCO0lBSzdCLFlBQW9CLE9BQXVCLEVBQUUsTUFBYztRQUF2QyxZQUFPLEdBQVAsT0FBTyxDQUFnQjtRQUN6QyxNQUFNLGlCQUFpQixHQUFzRDtZQUMzRSxDQUFDLHVDQUFnQixDQUFDLGVBQWUsQ0FBQyxFQUFFLENBQUM7WUFDckMsQ0FBQyx1Q0FBZ0IsQ0FBQyxRQUFRLENBQUMsRUFBRSxNQUFNO1lBQ25DLENBQUMsdUNBQWdCLENBQUMsTUFBTSxDQUFDLEVBQUUsTUFBTTtZQUNqQyxDQUFDLHVDQUFnQixDQUFDLFVBQVUsQ0FBQyxFQUMzQixpQkFBaUIsQ0FBQyxJQUFJLENBQUMsaUJBQU8sQ0FBQyxJQUFJLENBQUMsSUFBSSxpQkFBTyxDQUFDLElBQUksS0FBSyxPQUFPO2dCQUM5RCxDQUFDLENBQUMsZ0JBQWdCO2dCQUNsQixDQUFDLENBQUMsbUJBQW1CO1lBRXpCLDJCQUEyQjtZQUMzQixDQUFDLHVDQUFnQixDQUFDLFNBQVMsQ0FBQyxFQUFFLElBQUEsbUJBQVUsR0FBRTtZQUMxQyxDQUFDLHVDQUFnQixDQUFDLHFCQUFxQixDQUFDLEVBQUUsRUFB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O2lCQUNYO1lBQ0gsQ0FBQyxDQUNGLENBQUM7WUFFRixPQUFPLENBQUMsRUFBRSxDQUFDLE9BQU8sRUFBRSxNQUFNLENBQUMsQ0FBQztZQUM1QixNQUFNLGVBQWUsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxXQUFXLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQzdFLE9BQU8sQ0FBQyxLQUFLLENBQUMsZUFBZSxDQUFDLENBQUM7WUFDL0IsT0FBTyxDQUFDLEdBQUcsRUFBRSxDQUFDO1FBQ2hCLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztDQUNGO0FBL0tELGdEQStLQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQGxpY2Vuc2VcbiAqIENvcHlyaWdodCBHb29nbGUgTExDIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKlxuICogVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYW4gTUlULXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmVcbiAqIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUgYXQgaHR0cHM6Ly9hbmd1bGFyLmlvL2xpY2Vuc2VcbiAqL1xuXG5pbXBvcnQgeyByYW5kb21VVUlEIH0gZnJvbSAnY3J5cHRvJztcbmltcG9ydCAqIGFzIGh0dHBzIGZyb20gJ2h0dHBzJztcbmltcG9ydCAqIGFzIG9zIGZyb20gJ29zJztcbmltcG9ydCAqIGFzIHF1ZXJ5c3RyaW5nIGZyb20gJ3F1ZXJ5c3RyaW5nJztcbmltcG9ydCAqIGFzIHNlbXZlciBmcm9tICdzZW12ZXInO1xuaW1wb3J0IHR5cGUgeyBDb21tYW5kQ29udGV4dCB9IGZyb20gJy4uL2NvbW1hbmQtYnVpbGRlci9jb21tYW5kLW1vZHVsZSc7XG5pbXBvcnQgeyBuZ0RlYnVnIH0gZnJvbSAnLi4vdXRpbGl0aWVzL2Vudmlyb25tZW50LW9wdGlvbnMnO1xuaW1wb3J0IHsgYXNzZXJ0SXNFcnJvciB9IGZyb20gJy4uL3V0aWxpdGllcy9lcnJvcic7XG5pbXBvcnQgeyBWRVJTSU9OIH0gZnJvbSAnLi4vdXRpbGl0aWVzL3ZlcnNpb24nO1xuaW1wb3J0IHtcbiAgRXZlbnRDdXN0b21EaW1lbnNpb24sXG4gIEV2ZW50Q3VzdG9tTWV0cmljLFxuICBQcmltaXRpdmVUeXBlcyxcbiAgUmVxdWVzdFBhcmFtZXRlcixcbiAgVXNlckN1c3RvbURpbWVuc2lvbixcbn0gZnJvbSAnLi9hbmFseXRpY3MtcGFyYW1ldGVycyc7XG5cbmNvbnN0IFRSQUNLSU5HX0lEX1BST0QgPSAnRy1WRVROSkJXOEw0JztcbmNvbnN0IFRSQUNLSU5HX0lEX1NUQUdJTkcgPSAnRy1UQk1QUkwxQlRNJztcblxuZXhwb3J0IGNsYXNzIEFuYWx5dGljc0NvbGxlY3RvciB7XG4gIHByaXZhdGUgdHJhY2tpbmdFdmVudHNRdWV1ZTogUmVjb3JkPHN0cmluZywgUHJpbWl0aXZlVHlwZXMgfCB1bmRlZmluZWQ+W10gfCB1bmRlZmluZWQ7XG4gIHByaXZhdGUgcmVhZG9ubHkgcmVxdWVzdFBhcmFtZXRlclN0cmluZ2lmaWVkOiBzdHJpbmc7XG4gIHByaXZhdGUgcmVhZG9ubHkgdXNlclBhcmFtZXRlcnM6IFJlY29yZDxVc2VyQ3VzdG9tRGltZW5zaW9uLCBQcmltaXRpdmVUeXBlcyB8IHVuZGVmaW5lZD47XG5cbiAgY29uc3RydWN0b3IocHJpdmF0ZSBjb250ZXh0OiBDb21tYW5kQ29udGV4dCwgdXNlcklkOiBzdHJpbmcpIHtcbiAgICBjb25zdCByZXF1ZXN0UGFyYW1ldGVyczogUGFydGlhbDxSZWNvcmQ8UmVxdWVzdFBhcmFtZXRlciwgUHJpbWl0aXZlVHlwZXM+PiA9IHtcbiAgICAgIFtSZXF1ZXN0UGFyYW1ldGVyLlByb3RvY29sVmVyc2lvbl06IDIsXG4gICAgICBbUmVxdWVzdFBhcmFtZXRlci5DbGllbnRJZF06IHVzZXJJZCxcbiAgICAgIFtSZXF1ZXN0UGFyYW1ldGVyLlVzZXJJZF06IHVzZXJJZCxcbiAgICAgIFtSZXF1ZXN0UGFyYW1ldGVyLlRyYWNraW5nSWRdOlxuICAgICAgICAvXlxcZCtcXC5cXGQrXFwuXFxkKyQvLnRlc3QoVkVSU0lPTi5mdWxsKSAmJiBWRVJTSU9OLmZ1bGwgIT09ICcwLjAuMCdcbiAgICAgICAgICA/IFRSQUNLSU5HX0lEX1BST0RcbiAgICAgICAgICA6IFRSQUNLSU5HX0lEX1NUQUdJTkcsXG5cbiAgICAgIC8vIEJ1aWx0LWluIHVzZXIgcHJvcGVydGllc1xuICAgICAgW1JlcXVlc3RQYXJhbWV0ZXIuU2Vzc2lvbklkXTogcmFuZG9tVVVJRCgpLFxuICAgICAgW1JlcXVlc3RQYXJhbWV0ZXIuVXNlckFnZW50QXJjaGl0ZWN0dXJlXTogb3MuYXJjaCgpLFxuICAgICAgW1JlcXVlc3RQYXJhbWV0ZXIuVXNlckFnZW50UGxhdGZvcm1dOiBvcy5wbGF0Zm9ybSgpLFxuICAgICAgW1JlcXVlc3RQYXJhbWV0ZXIuVXNlckFnZW50UGxhdGZvcm1WZXJzaW9uXTogb3MucmVsZWFzZSgpLFxuICAgICAgW1JlcXVlc3RQYXJhbWV0ZXIuVXNlckFnZW50TW9iaWxlXTogMCxcbiAgICAgIFtSZXF1ZXN0UGFyYW1ldGVyLlNlc3Npb25FbmdhZ2VkXTogMSxcbiAgICAgIC8vIFRoZSBiZWxvdyBpcyBuZWVkZWQgZm9yIHRlY2ggZGV0YWlscyB0byBiZSBjb2xsZWN0ZWQuXG4gICAgICBbUmVxdWVzdFBhcmFtZXRlci5Vc2VyQWdlbnRGdWxsVmVyc2lvbkxpc3RdOlxuICAgICAgICAnR29vZ2xlJTIwQ2hyb21lOzExMS4wLjU1NjMuNjR8Tm90KEElM0FCcmFuZDs4LjAuMC4wfENocm9taXVtOzExMS4wLjU1NjMuNjQnLFxuICAgIH07XG5cbiAgICBpZiAobmdEZWJ1Zykge1xuICAgICAgcmVxdWVzdFBhcmFtZXRlcnNbUmVxdWVzdFBhcmFtZXRlci5EZWJ1Z1ZpZXddID0gMTtcbiAgICB9XG5cbiAgICB0aGlzLnJlcXVlc3RQYXJhbWV0ZXJTdHJpbmdpZmllZCA9IHF1ZXJ5c3RyaW5nLnN0cmluZ2lmeShyZXF1ZXN0UGFyYW1ldGVycyk7XG5cbiAgICBjb25zdCBwYXJzZWRWZXJzaW9uID0gc2VtdmVyLnBhcnNlKHByb2Nlc3MudmVyc2lvbik7XG4gICAgY29uc3QgcGFja2FnZU1hbmFnZXJWZXJzaW9uID0gY29udGV4dC5wYWNrYWdlTWFuYWdlci52ZXJzaW9uO1xuXG4gICAgdGhpcy51c2VyUGFyYW1ldGVycyA9IHtcbiAgICAgIC8vIFdoaWxlIGFyY2hpdGVjdHVyZSBpcyBiZWluZyBjb2xsZWN0IGJ5IEdBIGFzIFVzZXJBZ2VudEFyY2hpdGVjdHVyZS5cbiAgICAgIC8vIEl0IGRvZXNuJ3QgbG9vayBsaWtlIHRoZXJlIGlzIGEgd2F5IHRvIHF1ZXJ5IHRoaXMuIFRoZXJlZm9yZSB3ZSBjb2xsZWN0IHRoaXMgYXMgYSBjdXN0b20gdXNlciBkaW1lbnNpb24gdG9vLlxuICAgICAgW1VzZXJDdXN0b21EaW1lbnNpb24uT3NBcmNoaXRlY3R1cmVdOiBvcy5hcmNoKCksXG4gICAgICAvLyBXaGlsZSBVc2VyIElEIGlzIGJlaW5nIGNvbGxlY3RlZCBieSBHQSwgdGhpcyBpcyBub3QgdmlzaWJsZSBpbiByZXBvcnRzL2ZvciBmaWx0ZXJpbmcuXG4gICAgICBbVXNlckN1c3RvbURpbWVuc2lvbi5Vc2VySWRdOiB1c2VySWQsXG4gICAgICBbVXNlckN1c3RvbURpbWVuc2lvbi5Ob2RlVmVyc2lvbl06IHBhcnNlZFZlcnNpb25cbiAgICAgICAgPyBgJHtwYXJzZWRWZXJzaW9uLm1ham9yfS4ke3BhcnNlZFZlcnNpb24ubWlub3J9LiR7cGFyc2VkVmVyc2lvbi5wYXRjaH1gXG4gICAgICAgIDogJ290aGVyJyxcbiAgICAgIFtVc2VyQ3VzdG9tRGltZW5zaW9uLk5vZGVNYWpvclZlcnNpb25dOiBwYXJzZWRWZXJzaW9uPy5tYWpvcixcbiAgICAgIFtVc2VyQ3VzdG9tRGltZW5zaW9uLlBhY2thZ2VNYW5hZ2VyXTogY29udGV4dC5wYWNrYWdlTWFuYWdlci5uYW1lLFxuICAgICAgW1VzZXJDdXN0b21EaW1lbnNpb24uUGFja2FnZU1hbmFnZXJWZXJzaW9uXTogcGFja2FnZU1hbmFnZXJWZXJzaW9uLFxuICAgICAgW1VzZXJDdXN0b21EaW1lbnNpb24uUGFja2FnZU1hbmFnZXJNYWpvclZlcnNpb25dOiBwYWNrYWdlTWFuYWdlclZlcnNpb25cbiAgICAgICAgPyArcGFja2FnZU1hbmFnZXJWZXJzaW9uLnNwbGl0KCcuJywgMSlbMF1cbiAgICAgICAgOiB1bmRlZmluZWQsXG4gICAgICBbVXNlckN1c3RvbURpbWVuc2lvbi5Bbmd1bGFyQ0xJVmVyc2lvbl06IFZFUlNJT04uZnVsbCxcbiAgICAgIFtVc2VyQ3VzdG9tRGltZW5zaW9uLkFuZ3VsYXJDTElNYWpvclZlcnNpb25dOiBWRVJTSU9OLm1ham9yLFxuICAgIH07XG4gIH1cblxuICByZXBvcnRXb3Jrc3BhY2VJbmZvRXZlbnQoXG4gICAgcGFyYW1ldGVyczogUGFydGlhbDxSZWNvcmQ8RXZlbnRDdXN0b21NZXRyaWMsIHN0cmluZyB8IGJvb2xlYW4gfCBudW1iZXIgfCB1bmRlZmluZWQ+PixcbiAgKTogdm9pZCB7XG4gICAgdGhpcy5ldmVudCgnd29ya3NwYWNlX2luZm8nLCBwYXJhbWV0ZXJzKTtcbiAgfVxuXG4gIHJlcG9ydFJlYnVpbGRSdW5FdmVudChcbiAgICBwYXJhbWV0ZXJzOiBQYXJ0aWFsPFxuICAgICAgUmVjb3JkPEV2ZW50Q3VzdG9tTWV0cmljICYgRXZlbnRDdXN0b21EaW1lbnNpb24sIHN0cmluZyB8IGJvb2xlYW4gfCBudW1iZXIgfCB1bmRlZmluZWQ+XG4gICAgPixcbiAgKTogdm9pZCB7XG4gICAgdGhpcy5ldmVudCgncnVuX3JlYnVpbGQnLCBwYXJhbWV0ZXJzKTtcbiAgfVxuXG4gIHJlcG9ydEJ1aWxkUnVuRXZlbnQoXG4gICAgcGFyYW1ldGVyczogUGFydGlhbDxcbiAgICAgIFJlY29yZDxFdmVudEN1c3RvbU1ldHJpYyAmIEV2ZW50Q3VzdG9tRGltZW5zaW9uLCBzdHJpbmcgfCBib29sZWFuIHwgbnVtYmVyIHwgdW5kZWZpbmVkPlxuICAgID4sXG4gICk6IHZvaWQge1xuICAgIHRoaXMuZXZlbnQoJ3J1bl9idWlsZCcsIHBhcmFtZXRlcnMpO1xuICB9XG5cbiAgcmVwb3J0QXJjaGl0ZWN0UnVuRXZlbnQocGFyYW1ldGVyczogUGFydGlhbDxSZWNvcmQ8RXZlbnRDdXN0b21EaW1lbnNpb24sIFByaW1pdGl2ZVR5cGVzPj4pOiB2b2lkIHtcbiAgICB0aGlzLmV2ZW50KCdydW5fYXJjaGl0ZWN0JywgcGFyYW1ldGVycyk7XG4gIH1cblxuICByZXBvcnRTY2hlbWF0aWNSdW5FdmVudChwYXJhbWV0ZXJzOiBQYXJ0aWFsPFJlY29yZDxFdmVudEN1c3RvbURpbWVuc2lvbiwgUHJpbWl0aXZlVHlwZXM+Pik6IHZvaWQge1xuICAgIHRoaXMuZXZlbnQoJ3J1bl9zY2hlbWF0aWMnLCBwYXJhbWV0ZXJzKTtcbiAgfVxuXG4gIHJlcG9ydENvbW1hbmRSdW5FdmVudChjb21tYW5kOiBzdHJpbmcpOiB2b2lkIHtcbiAgICB0aGlzLmV2ZW50KCdydW5fY29tbWFuZCcsIHsgW0V2ZW50Q3VzdG9tRGltZW5zaW9uLkNvbW1hbmRdOiBjb21tYW5kIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBldmVudChldmVudE5hbWU6IHN0cmluZywgcGFyYW1ldGVycz86IFJlY29yZDxzdHJpbmcsIFByaW1pdGl2ZVR5cGVzPik6IHZvaWQge1xuICAgIHRoaXMudHJhY2tpbmdFdmVudHNRdWV1ZSA/Pz0gW107XG4gICAgdGhpcy50cmFja2luZ0V2ZW50c1F1ZXVlLnB1c2goe1xuICAgICAgLi4udGhpcy51c2VyUGFyYW1ldGVycyxcbiAgICAgIC4uLnBhcmFtZXRlcnMsXG4gICAgICAnZW4nOiBldmVudE5hbWUsXG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogRmx1c2ggb24gYW4gaW50ZXJ2YWwgKGlmIHRoZSBldmVudCBsb29wIGlzIHdhaXRpbmcpLlxuICAgKlxuICAgKiBAcmV0dXJucyBhIG1ldGhvZCB0aGF0IHdoZW4gY2FsbGVkIHdpbGwgdGVybWluYXRlIHRoZSBwZXJpb2RpY1xuICAgKiBmbHVzaCBhbmQgY2FsbCBmbHVzaCBvbmUgbGFzdCB0aW1lLlxuICAgKi9cbiAgcGVyaW9kRmx1c2goKTogKCkgPT4gUHJvbWlzZTx2b2lkPiB7XG4gICAgbGV0IGFuYWx5dGljc0ZsdXNoUHJvbWlzZSA9IFByb21pc2UucmVzb2x2ZSgpO1xuICAgIGNvbnN0IGFuYWx5dGljc0ZsdXNoSW50ZXJ2YWwgPSBzZXRJbnRlcnZhbCgoKSA9PiB7XG4gICAgICBpZiAodGhpcy50cmFja2luZ0V2ZW50c1F1ZXVlPy5sZW5ndGgpIHtcbiAgICAgICAgYW5hbHl0aWNzRmx1c2hQcm9taXNlID0gYW5hbHl0aWNzRmx1c2hQcm9taXNlLnRoZW4oKCkgPT4gdGhpcy5mbHVzaCgpKTtcbiAgICAgIH1cbiAgICB9LCA0MDAwKTtcblxuICAgIHJldHVybiAoKSA9PiB7XG4gICAgICBjbGVhckludGVydmFsKGFuYWx5dGljc0ZsdXNoSW50ZXJ2YWwpO1xuXG4gICAgICAvLyBGbHVzaCBvbmUgbGFzdCB0aW1lLlxuICAgICAgcmV0dXJuIGFuYWx5dGljc0ZsdXNoUHJvbWlzZS50aGVuKCgpID0+IHRoaXMuZmx1c2goKSk7XG4gICAgfTtcbiAgfVxuXG4gIGFzeW5jIGZsdXNoKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IHBlbmRpbmdUcmFja2luZ0V2ZW50cyA9IHRoaXMudHJhY2tpbmdFdmVudHNRdWV1ZTtcbiAgICB0aGlzLmNvbnRleHQubG9nZ2VyLmRlYnVnKGBBbmFseXRpY3MgZmx1c2ggc2l6ZS4gJHtwZW5kaW5nVHJhY2tpbmdFdmVudHM/Lmxlbmd0aH0uYCk7XG5cbiAgICBpZiAoIXBlbmRpbmdUcmFja2luZ0V2ZW50cz8ubGVuZ3RoKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gVGhlIGJlbG93IGlzIG5lZWRlZCBzbyB0aGF0IGlmIGZsdXNoIGlzIGNhbGxlZCBtdWx0aXBsZSB0aW1lcyxcbiAgICAvLyB3ZSBkb24ndCByZXBvcnQgdGhlIHNhbWUgZXZlbnQgbXVsdGlwbGUgdGltZXMuXG4gICAgdGhpcy50cmFja2luZ0V2ZW50c1F1ZXVlID0gdW5kZWZpbmVkO1xuXG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IHRoaXMuc2VuZChwZW5kaW5nVHJhY2tpbmdFdmVudHMpO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAvLyBGYWlsdXJlIHRvIHJlcG9ydCBhbmFseXRpY3Mgc2hvdWxkbid0IGNyYXNoIHRoZSBDTEkuXG4gICAgICBhc3NlcnRJc0Vycm9yKGVycm9yKTtcbiAgICAgIHRoaXMuY29udGV4dC5sb2dnZXIuZGVidWcoYFNlbmQgYW5hbHl0aWNzIGVycm9yLiAke2Vycm9yLm1lc3NhZ2V9LmApO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgc2VuZChkYXRhOiBSZWNvcmQ8c3RyaW5nLCBQcmltaXRpdmVUeXBlcyB8IHVuZGVmaW5lZD5bXSk6IFByb21pc2U8dm9pZD4ge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZTx2b2lkPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICBjb25zdCByZXF1ZXN0ID0gaHR0cHMucmVxdWVzdChcbiAgICAgICAge1xuICAgICAgICAgIGhvc3Q6ICd3d3cuZ29vZ2xlLWFuYWx5dGljcy5jb20nLFxuICAgICAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgICAgIHBhdGg6ICcvZy9jb2xsZWN0PycgKyB0aGlzLnJlcXVlc3RQYXJhbWV0ZXJTdHJpbmdpZmllZCxcbiAgICAgICAgICBoZWFkZXJzOiB7XG4gICAgICAgICAgICAvLyBUaGUgYmVsb3cgaXMgbmVlZGVkIGZvciB0ZWNoIGRldGFpbHMgdG8gYmUgY29sbGVjdGVkIGV2ZW4gdGhvdWdoIHdlIHByb3ZpZGUgb3VyIG93biBpbmZvcm1hdGlvbiBmcm9tIHRoZSBPUyBOb2RlLmpzIG1vZHVsZVxuICAgICAgICAgICAgJ3VzZXItYWdlbnQnOlxuICAgICAgICAgICAgICAnTW96aWxsYS81LjAgKE1hY2ludG9zaDsgSW50ZWwgTWFjIE9TIFggMTBfMTVfNykgQXBwbGVXZWJLaXQvNTM3LjM2IChLSFRNTCwgbGlrZSBHZWNrbykgQ2hyb21lLzExMS4wLjAuMCBTYWZhcmkvNTM3LjM2JyxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgICAocmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAvLyBUaGUgYmVsb3cgaXMgbmVlZGVkIGFzIG90aGVyd2lzZSB0aGUgcmVzcG9uc2Ugd2lsbCBuZXZlciBjbG9zZSB3aGljaCB3aWxsIGNhdXNlIHRoZSBDTEkgbm90IHRvIHRlcm1pbmF0ZS5cbiAgICAgICAgICByZXNwb25zZS5vbignZGF0YScsICgpID0+IHt9KTtcblxuICAgICAgICAgIGlmIChyZXNwb25zZS5zdGF0dXNDb2RlICE9PSAyMDAgJiYgcmVzcG9uc2Uuc3RhdHVzQ29kZSAhPT0gMjA0KSB7XG4gICAgICAgICAgICByZWplY3QoXG4gICAgICAgICAgICAgIG5ldyBFcnJvcihgQW5hbHl0aWNzIHJlcG9ydGluZyBmYWlsZWQgd2l0aCBzdGF0dXMgY29kZTogJHtyZXNwb25zZS5zdGF0dXNDb2RlfS5gKSxcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICApO1xuXG4gICAgICByZXF1ZXN0Lm9uKCdlcnJvcicsIHJlamVjdCk7XG4gICAgICBjb25zdCBxdWVyeVBhcmFtZXRlcnMgPSBkYXRhLm1hcCgocCkgPT4gcXVlcnlzdHJpbmcuc3RyaW5naWZ5KHApKS5qb2luKCdcXG4nKTtcbiAgICAgIHJlcXVlc3Qud3JpdGUocXVlcnlQYXJhbWV0ZXJzKTtcbiAgICAgIHJlcXVlc3QuZW5kKCk7XG4gICAgfSk7XG4gIH1cbn1cbiJdfQ==