1 | /**
|
---|
2 | * @license
|
---|
3 | * Copyright Google LLC All Rights Reserved.
|
---|
4 | *
|
---|
5 | * Use of this source code is governed by an MIT-style license that can be
|
---|
6 | * found in the LICENSE file at https://angular.io/license
|
---|
7 | */
|
---|
8 | (function (factory) {
|
---|
9 | if (typeof module === "object" && typeof module.exports === "object") {
|
---|
10 | var v = factory(require, exports);
|
---|
11 | if (v !== undefined) module.exports = v;
|
---|
12 | }
|
---|
13 | else if (typeof define === "function" && define.amd) {
|
---|
14 | define("@angular/compiler-cli/src/perform_watch", ["require", "exports", "chokidar", "path", "typescript", "@angular/compiler-cli/src/perform_compile", "@angular/compiler-cli/src/transformers/api", "@angular/compiler-cli/src/transformers/entry_points", "@angular/compiler-cli/src/transformers/util"], factory);
|
---|
15 | }
|
---|
16 | })(function (require, exports) {
|
---|
17 | "use strict";
|
---|
18 | Object.defineProperty(exports, "__esModule", { value: true });
|
---|
19 | exports.performWatchCompilation = exports.createPerformWatchHost = exports.FileChangeEvent = void 0;
|
---|
20 | var chokidar = require("chokidar");
|
---|
21 | var path = require("path");
|
---|
22 | var ts = require("typescript");
|
---|
23 | var perform_compile_1 = require("@angular/compiler-cli/src/perform_compile");
|
---|
24 | var api = require("@angular/compiler-cli/src/transformers/api");
|
---|
25 | var entry_points_1 = require("@angular/compiler-cli/src/transformers/entry_points");
|
---|
26 | var util_1 = require("@angular/compiler-cli/src/transformers/util");
|
---|
27 | function totalCompilationTimeDiagnostic(timeInMillis) {
|
---|
28 | var duration;
|
---|
29 | if (timeInMillis > 1000) {
|
---|
30 | duration = (timeInMillis / 1000).toPrecision(2) + "s";
|
---|
31 | }
|
---|
32 | else {
|
---|
33 | duration = timeInMillis + "ms";
|
---|
34 | }
|
---|
35 | return {
|
---|
36 | category: ts.DiagnosticCategory.Message,
|
---|
37 | messageText: "Total time: " + duration,
|
---|
38 | code: api.DEFAULT_ERROR_CODE,
|
---|
39 | source: api.SOURCE,
|
---|
40 | };
|
---|
41 | }
|
---|
42 | var FileChangeEvent;
|
---|
43 | (function (FileChangeEvent) {
|
---|
44 | FileChangeEvent[FileChangeEvent["Change"] = 0] = "Change";
|
---|
45 | FileChangeEvent[FileChangeEvent["CreateDelete"] = 1] = "CreateDelete";
|
---|
46 | FileChangeEvent[FileChangeEvent["CreateDeleteDir"] = 2] = "CreateDeleteDir";
|
---|
47 | })(FileChangeEvent = exports.FileChangeEvent || (exports.FileChangeEvent = {}));
|
---|
48 | function createPerformWatchHost(configFileName, reportDiagnostics, existingOptions, createEmitCallback) {
|
---|
49 | return {
|
---|
50 | reportDiagnostics: reportDiagnostics,
|
---|
51 | createCompilerHost: function (options) { return entry_points_1.createCompilerHost({ options: options }); },
|
---|
52 | readConfiguration: function () { return perform_compile_1.readConfiguration(configFileName, existingOptions); },
|
---|
53 | createEmitCallback: function (options) { return createEmitCallback ? createEmitCallback(options) : undefined; },
|
---|
54 | onFileChange: function (options, listener, ready) {
|
---|
55 | if (!options.basePath) {
|
---|
56 | reportDiagnostics([{
|
---|
57 | category: ts.DiagnosticCategory.Error,
|
---|
58 | messageText: 'Invalid configuration option. baseDir not specified',
|
---|
59 | source: api.SOURCE,
|
---|
60 | code: api.DEFAULT_ERROR_CODE
|
---|
61 | }]);
|
---|
62 | return { close: function () { } };
|
---|
63 | }
|
---|
64 | var watcher = chokidar.watch(options.basePath, {
|
---|
65 | // ignore .dotfiles, .js and .map files.
|
---|
66 | // can't ignore other files as we e.g. want to recompile if an `.html` file changes as well.
|
---|
67 | ignored: /((^[\/\\])\..)|(\.js$)|(\.map$)|(\.metadata\.json|node_modules)/,
|
---|
68 | ignoreInitial: true,
|
---|
69 | persistent: true,
|
---|
70 | });
|
---|
71 | watcher.on('all', function (event, path) {
|
---|
72 | switch (event) {
|
---|
73 | case 'change':
|
---|
74 | listener(FileChangeEvent.Change, path);
|
---|
75 | break;
|
---|
76 | case 'unlink':
|
---|
77 | case 'add':
|
---|
78 | listener(FileChangeEvent.CreateDelete, path);
|
---|
79 | break;
|
---|
80 | case 'unlinkDir':
|
---|
81 | case 'addDir':
|
---|
82 | listener(FileChangeEvent.CreateDeleteDir, path);
|
---|
83 | break;
|
---|
84 | }
|
---|
85 | });
|
---|
86 | watcher.on('ready', ready);
|
---|
87 | return { close: function () { return watcher.close(); }, ready: ready };
|
---|
88 | },
|
---|
89 | setTimeout: (ts.sys.clearTimeout && ts.sys.setTimeout) || setTimeout,
|
---|
90 | clearTimeout: (ts.sys.setTimeout && ts.sys.clearTimeout) || clearTimeout,
|
---|
91 | };
|
---|
92 | }
|
---|
93 | exports.createPerformWatchHost = createPerformWatchHost;
|
---|
94 | /**
|
---|
95 | * The logic in this function is adapted from `tsc.ts` from TypeScript.
|
---|
96 | */
|
---|
97 | function performWatchCompilation(host) {
|
---|
98 | var cachedProgram; // Program cached from last compilation
|
---|
99 | var cachedCompilerHost; // CompilerHost cached from last compilation
|
---|
100 | var cachedOptions; // CompilerOptions cached from last compilation
|
---|
101 | var timerHandleForRecompilation; // Handle for 0.25s wait timer to trigger recompilation
|
---|
102 | var ignoreFilesForWatch = new Set();
|
---|
103 | var fileCache = new Map();
|
---|
104 | var firstCompileResult = doCompilation();
|
---|
105 | // Watch basePath, ignoring .dotfiles
|
---|
106 | var resolveReadyPromise;
|
---|
107 | var readyPromise = new Promise(function (resolve) { return resolveReadyPromise = resolve; });
|
---|
108 | // Note: ! is ok as options are filled after the first compilation
|
---|
109 | // Note: ! is ok as resolvedReadyPromise is filled by the previous call
|
---|
110 | var fileWatcher = host.onFileChange(cachedOptions.options, watchedFileChanged, resolveReadyPromise);
|
---|
111 | return { close: close, ready: function (cb) { return readyPromise.then(cb); }, firstCompileResult: firstCompileResult };
|
---|
112 | function cacheEntry(fileName) {
|
---|
113 | fileName = path.normalize(fileName);
|
---|
114 | var entry = fileCache.get(fileName);
|
---|
115 | if (!entry) {
|
---|
116 | entry = {};
|
---|
117 | fileCache.set(fileName, entry);
|
---|
118 | }
|
---|
119 | return entry;
|
---|
120 | }
|
---|
121 | function close() {
|
---|
122 | fileWatcher.close();
|
---|
123 | if (timerHandleForRecompilation) {
|
---|
124 | host.clearTimeout(timerHandleForRecompilation.timerHandle);
|
---|
125 | timerHandleForRecompilation = undefined;
|
---|
126 | }
|
---|
127 | }
|
---|
128 | // Invoked to perform initial compilation or re-compilation in watch mode
|
---|
129 | function doCompilation() {
|
---|
130 | if (!cachedOptions) {
|
---|
131 | cachedOptions = host.readConfiguration();
|
---|
132 | }
|
---|
133 | if (cachedOptions.errors && cachedOptions.errors.length) {
|
---|
134 | host.reportDiagnostics(cachedOptions.errors);
|
---|
135 | return cachedOptions.errors;
|
---|
136 | }
|
---|
137 | var startTime = Date.now();
|
---|
138 | if (!cachedCompilerHost) {
|
---|
139 | cachedCompilerHost = host.createCompilerHost(cachedOptions.options);
|
---|
140 | var originalWriteFileCallback_1 = cachedCompilerHost.writeFile;
|
---|
141 | cachedCompilerHost.writeFile = function (fileName, data, writeByteOrderMark, onError, sourceFiles) {
|
---|
142 | if (sourceFiles === void 0) { sourceFiles = []; }
|
---|
143 | ignoreFilesForWatch.add(path.normalize(fileName));
|
---|
144 | return originalWriteFileCallback_1(fileName, data, writeByteOrderMark, onError, sourceFiles);
|
---|
145 | };
|
---|
146 | var originalFileExists_1 = cachedCompilerHost.fileExists;
|
---|
147 | cachedCompilerHost.fileExists = function (fileName) {
|
---|
148 | var ce = cacheEntry(fileName);
|
---|
149 | if (ce.exists == null) {
|
---|
150 | ce.exists = originalFileExists_1.call(this, fileName);
|
---|
151 | }
|
---|
152 | return ce.exists;
|
---|
153 | };
|
---|
154 | var originalGetSourceFile_1 = cachedCompilerHost.getSourceFile;
|
---|
155 | cachedCompilerHost.getSourceFile = function (fileName, languageVersion) {
|
---|
156 | var ce = cacheEntry(fileName);
|
---|
157 | if (!ce.sf) {
|
---|
158 | ce.sf = originalGetSourceFile_1.call(this, fileName, languageVersion);
|
---|
159 | }
|
---|
160 | return ce.sf;
|
---|
161 | };
|
---|
162 | var originalReadFile_1 = cachedCompilerHost.readFile;
|
---|
163 | cachedCompilerHost.readFile = function (fileName) {
|
---|
164 | var ce = cacheEntry(fileName);
|
---|
165 | if (ce.content == null) {
|
---|
166 | ce.content = originalReadFile_1.call(this, fileName);
|
---|
167 | }
|
---|
168 | return ce.content;
|
---|
169 | };
|
---|
170 | // Provide access to the file paths that triggered this rebuild
|
---|
171 | cachedCompilerHost.getModifiedResourceFiles = function () {
|
---|
172 | if (timerHandleForRecompilation === undefined) {
|
---|
173 | return undefined;
|
---|
174 | }
|
---|
175 | return timerHandleForRecompilation.modifiedResourceFiles;
|
---|
176 | };
|
---|
177 | }
|
---|
178 | ignoreFilesForWatch.clear();
|
---|
179 | var oldProgram = cachedProgram;
|
---|
180 | // We clear out the `cachedProgram` here as a
|
---|
181 | // program can only be used as `oldProgram` 1x
|
---|
182 | cachedProgram = undefined;
|
---|
183 | var compileResult = perform_compile_1.performCompilation({
|
---|
184 | rootNames: cachedOptions.rootNames,
|
---|
185 | options: cachedOptions.options,
|
---|
186 | host: cachedCompilerHost,
|
---|
187 | oldProgram: oldProgram,
|
---|
188 | emitCallback: host.createEmitCallback(cachedOptions.options)
|
---|
189 | });
|
---|
190 | if (compileResult.diagnostics.length) {
|
---|
191 | host.reportDiagnostics(compileResult.diagnostics);
|
---|
192 | }
|
---|
193 | var endTime = Date.now();
|
---|
194 | if (cachedOptions.options.diagnostics) {
|
---|
195 | var totalTime = (endTime - startTime) / 1000;
|
---|
196 | host.reportDiagnostics([totalCompilationTimeDiagnostic(endTime - startTime)]);
|
---|
197 | }
|
---|
198 | var exitCode = perform_compile_1.exitCodeFromResult(compileResult.diagnostics);
|
---|
199 | if (exitCode == 0) {
|
---|
200 | cachedProgram = compileResult.program;
|
---|
201 | host.reportDiagnostics([util_1.createMessageDiagnostic('Compilation complete. Watching for file changes.')]);
|
---|
202 | }
|
---|
203 | else {
|
---|
204 | host.reportDiagnostics([util_1.createMessageDiagnostic('Compilation failed. Watching for file changes.')]);
|
---|
205 | }
|
---|
206 | return compileResult.diagnostics;
|
---|
207 | }
|
---|
208 | function resetOptions() {
|
---|
209 | cachedProgram = undefined;
|
---|
210 | cachedCompilerHost = undefined;
|
---|
211 | cachedOptions = undefined;
|
---|
212 | }
|
---|
213 | function watchedFileChanged(event, fileName) {
|
---|
214 | var normalizedPath = path.normalize(fileName);
|
---|
215 | if (cachedOptions && event === FileChangeEvent.Change &&
|
---|
216 | // TODO(chuckj): validate that this is sufficient to skip files that were written.
|
---|
217 | // This assumes that the file path we write is the same file path we will receive in the
|
---|
218 | // change notification.
|
---|
219 | normalizedPath === path.normalize(cachedOptions.project)) {
|
---|
220 | // If the configuration file changes, forget everything and start the recompilation timer
|
---|
221 | resetOptions();
|
---|
222 | }
|
---|
223 | else if (event === FileChangeEvent.CreateDelete || event === FileChangeEvent.CreateDeleteDir) {
|
---|
224 | // If a file was added or removed, reread the configuration
|
---|
225 | // to determine the new list of root files.
|
---|
226 | cachedOptions = undefined;
|
---|
227 | }
|
---|
228 | if (event === FileChangeEvent.CreateDeleteDir) {
|
---|
229 | fileCache.clear();
|
---|
230 | }
|
---|
231 | else {
|
---|
232 | fileCache.delete(normalizedPath);
|
---|
233 | }
|
---|
234 | if (!ignoreFilesForWatch.has(normalizedPath)) {
|
---|
235 | // Ignore the file if the file is one that was written by the compiler.
|
---|
236 | startTimerForRecompilation(normalizedPath);
|
---|
237 | }
|
---|
238 | }
|
---|
239 | // Upon detecting a file change, wait for 250ms and then perform a recompilation. This gives batch
|
---|
240 | // operations (such as saving all modified files in an editor) a chance to complete before we kick
|
---|
241 | // off a new compilation.
|
---|
242 | function startTimerForRecompilation(changedPath) {
|
---|
243 | if (timerHandleForRecompilation) {
|
---|
244 | host.clearTimeout(timerHandleForRecompilation.timerHandle);
|
---|
245 | }
|
---|
246 | else {
|
---|
247 | timerHandleForRecompilation = {
|
---|
248 | modifiedResourceFiles: new Set(),
|
---|
249 | timerHandle: undefined
|
---|
250 | };
|
---|
251 | }
|
---|
252 | timerHandleForRecompilation.timerHandle = host.setTimeout(recompile, 250);
|
---|
253 | timerHandleForRecompilation.modifiedResourceFiles.add(changedPath);
|
---|
254 | }
|
---|
255 | function recompile() {
|
---|
256 | host.reportDiagnostics([util_1.createMessageDiagnostic('File change detected. Starting incremental compilation.')]);
|
---|
257 | doCompilation();
|
---|
258 | timerHandleForRecompilation = undefined;
|
---|
259 | }
|
---|
260 | }
|
---|
261 | exports.performWatchCompilation = performWatchCompilation;
|
---|
262 | });
|
---|
263 | //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGVyZm9ybV93YXRjaC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3BhY2thZ2VzL2NvbXBpbGVyLWNsaS9zcmMvcGVyZm9ybV93YXRjaC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7O0dBTUc7Ozs7Ozs7Ozs7Ozs7SUFFSCxtQ0FBcUM7SUFDckMsMkJBQTZCO0lBQzdCLCtCQUFpQztJQUVqQyw2RUFBd0o7SUFDeEosZ0VBQTBDO0lBQzFDLG9GQUErRDtJQUMvRCxvRUFBNEQ7SUFFNUQsU0FBUyw4QkFBOEIsQ0FBQyxZQUFvQjtRQUMxRCxJQUFJLFFBQWdCLENBQUM7UUFDckIsSUFBSSxZQUFZLEdBQUcsSUFBSSxFQUFFO1lBQ3ZCLFFBQVEsR0FBTSxDQUFDLFlBQVksR0FBRyxJQUFJLENBQUMsQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLE1BQUcsQ0FBQztTQUN2RDthQUFNO1lBQ0wsUUFBUSxHQUFNLFlBQVksT0FBSSxDQUFDO1NBQ2hDO1FBQ0QsT0FBTztZQUNMLFFBQVEsRUFBRSxFQUFFLENBQUMsa0JBQWtCLENBQUMsT0FBTztZQUN2QyxXQUFXLEVBQUUsaUJBQWUsUUFBVTtZQUN0QyxJQUFJLEVBQUUsR0FBRyxDQUFDLGtCQUFrQjtZQUM1QixNQUFNLEVBQUUsR0FBRyxDQUFDLE1BQU07U0FDbkIsQ0FBQztJQUNKLENBQUM7SUFFRCxJQUFZLGVBSVg7SUFKRCxXQUFZLGVBQWU7UUFDekIseURBQU0sQ0FBQTtRQUNOLHFFQUFZLENBQUE7UUFDWiwyRUFBZSxDQUFBO0lBQ2pCLENBQUMsRUFKVyxlQUFlLEdBQWYsdUJBQWUsS0FBZix1QkFBZSxRQUkxQjtJQWNELFNBQWdCLHNCQUFzQixDQUNsQyxjQUFzQixFQUFFLGlCQUFxRCxFQUM3RSxlQUFvQyxFQUNwQyxrQkFDa0M7UUFDcEMsT0FBTztZQUNMLGlCQUFpQixFQUFFLGlCQUFpQjtZQUNwQyxrQkFBa0IsRUFBRSxVQUFBLE9BQU8sSUFB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LDJCQUEyQixDQUFDLFdBQVcsQ0FBQyxDQUFDO2FBQzVEO2lCQUFNO2dCQUNMLDJCQUEyQixHQUFHO29CQUM1QixxQkFBcUIsRUFBRSxJQUFJLEdBQUcsRUFBVTtvQkFDeEMsV0FBVyxFQUFFLFNBQVM7aUJBQ3ZCLENBQUM7YUFDSDtZQUNELDJCQUEyQixDQUFDLFdBQVcsR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDLFNBQVMsRUFBRSxHQUFHLENBQUMsQ0FBQztZQUMxRSwyQkFBMkIsQ0FBQyxxQkFBcUIsQ0FBQyxHQUFHLENBQUMsV0FBVyxDQUFDLENBQUM7UUFDckUsQ0FBQztRQUVELFNBQVMsU0FBUztZQUNoQixJQUFJLENBQUMsaUJBQWlCLENBQ2xCLENBQUMsOEJBQXVCLENBQUMseURBQXlELENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDMUYsYUFBYSxFQUFFLENBQUM7WUFDaEIsMkJBQTJCLEdBQUcsU0FBUyxDQUFDO1FBQzFDLENBQUM7SUFDSCxDQUFDO0lBekxELDBEQXlMQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQGxpY2Vuc2VcbiAqIENvcHlyaWdodCBHb29nbGUgTExDIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKlxuICogVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYW4gTUlULXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmVcbiAqIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUgYXQgaHR0cHM6Ly9hbmd1bGFyLmlvL2xpY2Vuc2VcbiAqL1xuXG5pbXBvcnQgKiBhcyBjaG9raWRhciBmcm9tICdjaG9raWRhcic7XG5pbXBvcnQgKiBhcyBwYXRoIGZyb20gJ3BhdGgnO1xuaW1wb3J0ICogYXMgdHMgZnJvbSAndHlwZXNjcmlwdCc7XG5cbmltcG9ydCB7RGlhZ25vc3RpY3MsIGV4aXRDb2RlRnJvbVJlc3VsdCwgUGFyc2VkQ29uZmlndXJhdGlvbiwgcGVyZm9ybUNvbXBpbGF0aW9uLCBQZXJmb3JtQ29tcGlsYXRpb25SZXN1bHQsIHJlYWRDb25maWd1cmF0aW9ufSBmcm9tICcuL3BlcmZvcm1fY29tcGlsZSc7XG5pbXBvcnQgKiBhcyBhcGkgZnJvbSAnLi90cmFuc2Zvcm1lcnMvYXBpJztcbmltcG9ydCB7Y3JlYXRlQ29tcGlsZXJIb3N0fSBmcm9tICcuL3RyYW5zZm9ybWVycy9lbnRyeV9wb2ludHMnO1xuaW1wb3J0IHtjcmVhdGVNZXNzYWdlRGlhZ25vc3RpY30gZnJvbSAnLi90cmFuc2Zvcm1lcnMvdXRpbCc7XG5cbmZ1bmN0aW9uIHRvdGFsQ29tcGlsYXRpb25UaW1lRGlhZ25vc3RpYyh0aW1lSW5NaWxsaXM6IG51bWJlcik6IGFwaS5EaWFnbm9zdGljIHtcbiAgbGV0IGR1cmF0aW9uOiBzdHJpbmc7XG4gIGlmICh0aW1lSW5NaWxsaXMgPiAxMDAwKSB7XG4gICAgZHVyYXRpb24gPSBgJHsodGltZUluTWlsbGlzIC8gMTAwMCkudG9QcmVjaXNpb24oMil9c2A7XG4gIH0gZWxzZSB7XG4gICAgZHVyYXRpb24gPSBgJHt0aW1lSW5NaWxsaXN9bXNgO1xuICB9XG4gIHJldHVybiB7XG4gICAgY2F0ZWdvcnk6IHRzLkRpYWdub3N0aWNDYXRlZ29yeS5NZXNzYWdlLFxuICAgIG1lc3NhZ2VUZXh0OiBgVG90YWwgdGltZTogJHtkdXJhdGlvbn1gLFxuICAgIGNvZGU6IGFwaS5ERUZBVUxUX0VSUk9SX0NPREUsXG4gICAgc291cmNlOiBhcGkuU09VUkNFLFxuICB9O1xufVxuXG5leHBvcnQgZW51bSBGaWxlQ2hhbmdlRXZlbnQge1xuICBDaGFuZ2UsXG4gIENyZWF0ZURlbGV0ZSxcbiAgQ3JlYXRlRGVsZXRlRGlyLFxufVxuXG5leHBvcnQgaW50ZXJmYWNlIFBlcmZvcm1XYXRjaEhvc3Qge1xuICByZXBvcnREaWFnbm9zdGljcyhkaWFnbm9zdGljczogRGlhZ25vc3RpY3MpOiB2b2lkO1xuICByZWFkQ29uZmlndXJhdGlvbigpOiBQYXJzZWRDb25maWd1cmF0aW9uO1xuICBjcmVhdGVDb21waWxlckhvc3Qob3B0aW9uczogYXBpLkNvbXBpbGVyT3B0aW9ucyk6IGFwaS5Db21waWxlckhvc3Q7XG4gIGNyZWF0ZUVtaXRDYWxsYmFjayhvcHRpb25zOiBhcGkuQ29tcGlsZXJPcHRpb25zKTogYXBpLlRzRW1pdENhbGxiYWNrfHVuZGVmaW5lZDtcbiAgb25GaWxlQ2hhbmdlKFxuICAgICAgb3B0aW9uczogYXBpLkNvbXBpbGVyT3B0aW9ucywgbGlzdGVuZXI6IChldmVudDogRmlsZUNoYW5nZUV2ZW50LCBmaWxlTmFtZTogc3RyaW5nKSA9PiB2b2lkLFxuICAgICAgcmVhZHk6ICgpID0+IHZvaWQpOiB7Y2xvc2U6ICgpID0+IHZvaWR9O1xuICBzZXRUaW1lb3V0KGNhbGxiYWNrOiAoKSA9PiB2b2lkLCBtczogbnVtYmVyKTogYW55O1xuICBjbGVhclRpbWVvdXQodGltZW91dElkOiBhbnkpOiB2b2lkO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlUGVyZm9ybVdhdGNoSG9zdChcbiAgICBjb25maWdGaWxlTmFtZTogc3RyaW5nLCByZXBvcnREaWFnbm9zdGljczogKGRpYWdub3N0aWNzOiBEaWFnbm9zdGljcykgPT4gdm9pZCxcbiAgICBleGlzdGluZ09wdGlvbnM/OiB0cy5Db21waWxlck9wdGlvbnMsXG4gICAgY3JlYXRlRW1pdENhbGxiYWNrPzogKG9wdGlvbnM6IGFwaS5Db21waWxlck9wdGlvbnMpID0+XG4gICAgICAgIGFwaS5Uc0VtaXRDYWxsYmFjayB8IHVuZGVmaW5lZCk6IFBlcmZvcm1XYXRjaEhvc3Qge1xuICByZXR1cm4ge1xuICAgIHJlcG9ydERpYWdub3N0aWNzOiByZXBvcnREaWFnbm9zdGljcyxcbiAgICBjcmVhdGVDb21waWxlckhvc3Q6IG9wdGlvbnMgPT4gY3JlYXRlQ29tcGlsZXJIb3N0KHtvcHRpb25zfSksXG4gICAgcmVhZENvbmZpZ3VyYXRpb246ICgpID0+IHJlYWRDb25maWd1cmF0aW9uKGNvbmZpZ0ZpbGVOYW1lLCBleGlzdGluZ09wdGlvbnMpLFxuICAgIGNyZWF0ZUVtaXRDYWxsYmFjazogb3B0aW9ucyA9PiBjcmVhdGVFbWl0Q2FsbGJhY2sgPyBjcmVhdGVFbWl0Q2FsbGJhY2sob3B0aW9ucykgOiB1bmRlZmluZWQsXG4gICAgb25GaWxlQ2hhbmdlOiAob3B0aW9ucywgbGlzdGVuZXIsIHJlYWR5OiAoKSA9PiB2b2lkKSA9PiB7XG4gICAgICBpZiAoIW9wdGlvbnMuYmFzZVBhdGgpIHtcbiAgICAgICAgcmVwb3J0RGlhZ25vc3RpY3MoW3tcbiAgICAgICAgICBjYXRlZ29yeTogdHMuRGlhZ25vc3RpY0NhdGVnb3J5LkVycm9yLFxuICAgICAgICAgIG1lc3NhZ2VUZXh0OiAnSW52YWxpZCBjb25maWd1cmF0aW9uIG9wdGlvbi4gYmFzZURpciBub3Qgc3BlY2lmaWVkJyxcbiAgICAgICAgICBzb3VyY2U6IGFwaS5TT1VSQ0UsXG4gICAgICAgICAgY29kZTogYXBpLkRFRkFVTFRfRVJST1JfQ09ERVxuICAgICAgICB9XSk7XG4gICAgICAgIHJldHVybiB7Y2xvc2U6ICgpID0+IHt9fTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHdhdGNoZXIgPSBjaG9raWRhci53YXRjaChvcHRpb25zLmJhc2VQYXRoLCB7XG4gICAgICAgIC8vIGlnbm9yZSAuZG90ZmlsZXMsIC5qcyBhbmQgLm1hcCBmaWxlcy5cbiAgICAgICAgLy8gY2FuJ3QgaWdub3JlIG90aGVyIGZpbGVzIGFzIHdlIGUuZy4gd2FudCB0byByZWNvbXBpbGUgaWYgYW4gYC5odG1sYCBmaWxlIGNoYW5nZXMgYXMgd2VsbC5cbiAgICAgICAgaWdub3JlZDogLygoXltcXC9cXFxcXSlcXC4uKXwoXFwuanMkKXwoXFwubWFwJCl8KFxcLm1ldGFkYXRhXFwuanNvbnxub2RlX21vZHVsZXMpLyxcbiAgICAgICAgaWdub3JlSW5pdGlhbDogdHJ1ZSxcbiAgICAgICAgcGVyc2lzdGVudDogdHJ1ZSxcbiAgICAgIH0pO1xuICAgICAgd2F0Y2hlci5vbignYWxsJywgKGV2ZW50OiBzdHJpbmcsIHBhdGg6IHN0cmluZykgPT4ge1xuICAgICAgICBzd2l0Y2ggKGV2ZW50KSB7XG4gICAgICAgICAgY2FzZSAnY2hhbmdlJzpcbiAgICAgICAgICAgIGxpc3RlbmVyKEZpbGVDaGFuZ2VFdmVudC5DaGFuZ2UsIHBhdGgpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgY2FzZSAndW5saW5rJzpcbiAgICAgICAgICBjYXNlICdhZGQnOlxuICAgICAgICAgICAgbGlzdGVuZXIoRmlsZUNoYW5nZUV2ZW50LkNyZWF0ZURlbGV0ZSwgcGF0aCk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICBjYXNlICd1bmxpbmtEaXInOlxuICAgICAgICAgIGNhc2UgJ2FkZERpcic6XG4gICAgICAgICAgICBsaXN0ZW5lcihGaWxlQ2hhbmdlRXZlbnQuQ3JlYXRlRGVsZXRlRGlyLCBwYXRoKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIHdhdGNoZXIub24oJ3JlYWR5JywgcmVhZHkpO1xuICAgICAgcmV0dXJuIHtjbG9zZTogKCkgPT4gd2F0Y2hlci5jbG9zZSgpLCByZWFkeX07XG4gICAgfSxcbiAgICBzZXRUaW1lb3V0OiAodHMuc3lzLmNsZWFyVGltZW91dCAmJiB0cy5zeXMuc2V0VGltZW91dCkgfHwgc2V0VGltZW91dCxcbiAgICBjbGVhclRpbWVvdXQ6ICh0cy5zeXMuc2V0VGltZW91dCAmJiB0cy5zeXMuY2xlYXJUaW1lb3V0KSB8fCBjbGVhclRpbWVvdXQsXG4gIH07XG59XG5cbmludGVyZmFjZSBDYWNoZUVudHJ5IHtcbiAgZXhpc3RzPzogYm9vbGVhbjtcbiAgc2Y/OiB0cy5Tb3VyY2VGaWxlO1xuICBjb250ZW50Pzogc3RyaW5nO1xufVxuXG5pbnRlcmZhY2UgUXVldWVkQ29tcGlsYXRpb25JbmZvIHtcbiAgdGltZXJIYW5kbGU6IGFueTtcbiAgbW9kaWZpZWRSZXNvdXJjZUZpbGVzOiBTZXQ8c3RyaW5nPjtcbn1cblxuLyoqXG4gKiBUaGUgbG9naWMgaW4gdGhpcyBmdW5jdGlvbiBpcyBhZGFwdGVkIGZyb20gYHRzYy50c2AgZnJvbSBUeXBlU2NyaXB0LlxuICovXG5leHBvcnQgZnVuY3Rpb24gcGVyZm9ybVdhdGNoQ29tcGlsYXRpb24oaG9zdDogUGVyZm9ybVdhdGNoSG9zdCk6XG4gICAge2Nsb3NlOiAoKSA9PiB2b2lkLCByZWFkeTogKGNiOiAoKSA9PiB2b2lkKSA9PiB2b2lkLCBmaXJzdENvbXBpbGVSZXN1bHQ6IERpYWdub3N0aWNzfSB7XG4gIGxldCBjYWNoZWRQcm9ncmFtOiBhcGkuUHJvZ3JhbXx1bmRlZmluZWQ7ICAgICAgICAgICAgLy8gUHJvZ3JhbSBjYWNoZWQgZnJvbSBsYXN0IGNvbXBpbGF0aW9uXG4gIGxldCBjYWNoZWRDb21waWxlckhvc3Q6IGFwaS5Db21waWxlckhvc3R8dW5kZWZpbmVkOyAgLy8gQ29tcGlsZXJIb3N0IGNhY2hlZCBmcm9tIGxhc3QgY29tcGlsYXRpb25cbiAgbGV0IGNhY2hlZE9wdGlvbnM6IFBhcnNlZENvbmZpZ3VyYXRpb258dW5kZWZpbmVkOyAgLy8gQ29tcGlsZXJPcHRpb25zIGNhY2hlZCBmcm9tIGxhc3QgY29tcGlsYXRpb25cbiAgbGV0IHRpbWVySGFuZGxlRm9yUmVjb21waWxhdGlvbjogUXVldWVkQ29tcGlsYXRpb25JbmZvfFxuICAgICAgdW5kZWZpbmVkOyAgLy8gSGFuZGxlIGZvciAwLjI1cyB3YWl0IHRpbWVyIHRvIHRyaWdnZXIgcmVjb21waWxhdGlvblxuXG4gIGNvbnN0IGlnbm9yZUZpbGVzRm9yV2F0Y2ggPSBuZXcgU2V0PHN0cmluZz4oKTtcbiAgY29uc3QgZmlsZUNhY2hlID0gbmV3IE1hcDxzdHJpbmcsIENhY2hlRW50cnk+KCk7XG5cbiAgY29uc3QgZmlyc3RDb21waWxlUmVzdWx0ID0gZG9Db21waWxhdGlvbigpO1xuXG4gIC8vIFdhdGNoIGJhc2VQYXRoLCBpZ25vcmluZyAuZG90ZmlsZXNcbiAgbGV0IHJlc29sdmVSZWFkeVByb21pc2U6ICgpID0+IHZvaWQ7XG4gIGNvbnN0IHJlYWR5UHJvbWlzZSA9IG5ldyBQcm9taXNlPHZvaWQ+KHJlc29sdmUgPT4gcmVzb2x2ZVJlYWR5UHJvbWlzZSA9IHJlc29sdmUpO1xuICAvLyBOb3RlOiAhIGlzIG9rIGFzIG9wdGlvbnMgYXJlIGZpbGxlZCBhZnRlciB0aGUgZmlyc3QgY29tcGlsYXRpb25cbiAgLy8gTm90ZTogISBpcyBvayBhcyByZXNvbHZlZFJlYWR5UHJvbWlzZSBpcyBmaWxsZWQgYnkgdGhlIHByZXZpb3VzIGNhbGxcbiAgY29uc3QgZmlsZVdhdGNoZXIgPVxuICAgICAgaG9zdC5vbkZpbGVDaGFuZ2UoY2FjaGVkT3B0aW9ucyEub3B0aW9ucywgd2F0Y2hlZEZpbGVDaGFuZ2VkLCByZXNvbHZlUmVhZHlQcm9taXNlISk7XG5cbiAgcmV0dXJuIHtjbG9zZSwgcmVhZHk6IGNiID0+IHJlYWR5UHJvbWlzZS50aGVuKGNiKSwgZmlyc3RDb21waWxlUmVzdWx0fTtcblxuICBmdW5jdGlvbiBjYWNoZUVudHJ5KGZpbGVOYW1lOiBzdHJpbmcpOiBDYWNoZUVudHJ5IHtcbiAgICBmaWxlTmFtZSA9IHBhdGgubm9ybWFsaXplKGZpbGVOYW1lKTtcbiAgICBsZXQgZW50cnkgPSBmaWxlQ2FjaGUuZ2V0KGZpbGVOYW1lKTtcbiAgICBpZiAoIWVudHJ5KSB7XG4gICAgICBlbnRyeSA9IHt9O1xuICAgICAgZmlsZUNhY2hlLnNldChmaWxlTmFtZSwgZW50cnkpO1xuICAgIH1cbiAgICByZXR1cm4gZW50cnk7XG4gIH1cblxuICBmdW5jdGlvbiBjbG9zZSgpIHtcbiAgICBmaWxlV2F0Y2hlci5jbG9zZSgpO1xuICAgIGlmICh0aW1lckhhbmRsZUZvclJlY29tcGlsYXRpb24pIHtcbiAgICAgIGhvc3QuY2xlYXJUaW1lb3V0KHRpbWVySGFuZGxlRm9yUmVjb21waWxhdGlvbi50aW1lckhhbmRsZSk7XG4gICAgICB0aW1lckhhbmRsZUZvclJlY29tcGlsYXRpb24gPSB1bmRlZmluZWQ7XG4gICAgfVxuICB9XG5cbiAgLy8gSW52b2tlZCB0byBwZXJmb3JtIGluaXRpYWwgY29tcGlsYXRpb24gb3IgcmUtY29tcGlsYXRpb24gaW4gd2F0Y2ggbW9kZVxuICBmdW5jdGlvbiBkb0NvbXBpbGF0aW9uKCk6IERpYWdub3N0aWNzIHtcbiAgICBpZiAoIWNhY2hlZE9wdGlvbnMpIHtcbiAgICAgIGNhY2hlZE9wdGlvbnMgPSBob3N0LnJlYWRDb25maWd1cmF0aW9uKCk7XG4gICAgfVxuICAgIGlmIChjYWNoZWRPcHRpb25zLmVycm9ycyAmJiBjYWNoZWRPcHRpb25zLmVycm9ycy5sZW5ndGgpIHtcbiAgICAgIGhvc3QucmVwb3J0RGlhZ25vc3RpY3MoY2FjaGVkT3B0aW9ucy5lcnJvcnMpO1xuICAgICAgcmV0dXJuIGNhY2hlZE9wdGlvbnMuZXJyb3JzO1xuICAgIH1cbiAgICBjb25zdCBzdGFydFRpbWUgPSBEYXRlLm5vdygpO1xuICAgIGlmICghY2FjaGVkQ29tcGlsZXJIb3N0KSB7XG4gICAgICBjYWNoZWRDb21waWxlckhvc3QgPSBob3N0LmNyZWF0ZUNvbXBpbGVySG9zdChjYWNoZWRPcHRpb25zLm9wdGlvbnMpO1xuICAgICAgY29uc3Qgb3JpZ2luYWxXcml0ZUZpbGVDYWxsYmFjayA9IGNhY2hlZENvbXBpbGVySG9zdC53cml0ZUZpbGU7XG4gICAgICBjYWNoZWRDb21waWxlckhvc3Qud3JpdGVGaWxlID0gZnVuY3Rpb24oXG4gICAgICAgICAgZmlsZU5hbWU6IHN0cmluZywgZGF0YTogc3RyaW5nLCB3cml0ZUJ5dGVPcmRlck1hcms6IGJvb2xlYW4sXG4gICAgICAgICAgb25FcnJvcj86IChtZXNzYWdlOiBzdHJpbmcpID0+IHZvaWQsIHNvdXJjZUZpbGVzOiBSZWFkb25seUFycmF5PHRzLlNvdXJjZUZpbGU+ID0gW10pIHtcbiAgICAgICAgaWdub3JlRmlsZXNGb3JXYXRjaC5hZGQocGF0aC5ub3JtYWxpemUoZmlsZU5hbWUpKTtcbiAgICAgICAgcmV0dXJuIG9yaWdpbmFsV3JpdGVGaWxlQ2FsbGJhY2soZmlsZU5hbWUsIGRhdGEsIHdyaXRlQnl0ZU9yZGVyTWFyaywgb25FcnJvciwgc291cmNlRmlsZXMpO1xuICAgICAgfTtcbiAgICAgIGNvbnN0IG9yaWdpbmFsRmlsZUV4aXN0cyA9IGNhY2hlZENvbXBpbGVySG9zdC5maWxlRXhpc3RzO1xuICAgICAgY2FjaGVkQ29tcGlsZXJIb3N0LmZpbGVFeGlzdHMgPSBmdW5jdGlvbihmaWxlTmFtZTogc3RyaW5nKSB7XG4gICAgICAgIGNvbnN0IGNlID0gY2FjaGVFbnRyeShmaWxlTmFtZSk7XG4gICAgICAgIGlmIChjZS5leGlzdHMgPT0gbnVsbCkge1xuICAgICAgICAgIGNlLmV4aXN0cyA9IG9yaWdpbmFsRmlsZUV4aXN0cy5jYWxsKHRoaXMsIGZpbGVOYW1lKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gY2UuZXhpc3RzITtcbiAgICAgIH07XG4gICAgICBjb25zdCBvcmlnaW5hbEdldFNvdXJjZUZpbGUgPSBjYWNoZWRDb21waWxlckhvc3QuZ2V0U291cmNlRmlsZTtcbiAgICAgIGNhY2hlZENvbXBpbGVySG9zdC5nZXRTb3VyY2VGaWxlID0gZnVuY3Rpb24oXG4gICAgICAgICAgZmlsZU5hbWU6IHN0cmluZywgbGFuZ3VhZ2VWZXJzaW9uOiB0cy5TY3JpcHRUYXJnZXQpIHtcbiAgICAgICAgY29uc3QgY2UgPSBjYWNoZUVudHJ5KGZpbGVOYW1lKTtcbiAgICAgICAgaWYgKCFjZS5zZikge1xuICAgICAgICAgIGNlLnNmID0gb3JpZ2luYWxHZXRTb3VyY2VGaWxlLmNhbGwodGhpcywgZmlsZU5hbWUsIGxhbmd1YWdlVmVyc2lvbik7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGNlLnNmITtcbiAgICAgIH07XG4gICAgICBjb25zdCBvcmlnaW5hbFJlYWRGaWxlID0gY2FjaGVkQ29tcGlsZXJIb3N0LnJlYWRGaWxlO1xuICAgICAgY2FjaGVkQ29tcGlsZXJIb3N0LnJlYWRGaWxlID0gZnVuY3Rpb24oZmlsZU5hbWU6IHN0cmluZykge1xuICAgICAgICBjb25zdCBjZSA9IGNhY2hlRW50cnkoZmlsZU5hbWUpO1xuICAgICAgICBpZiAoY2UuY29udGVudCA9PSBudWxsKSB7XG4gICAgICAgICAgY2UuY29udGVudCA9IG9yaWdpbmFsUmVhZEZpbGUuY2FsbCh0aGlzLCBmaWxlTmFtZSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGNlLmNvbnRlbnQhO1xuICAgICAgfTtcbiAgICAgIC8vIFByb3ZpZGUgYWNjZXNzIHRvIHRoZSBmaWxlIHBhdGhzIHRoYXQgdHJpZ2dlcmVkIHRoaXMgcmVidWlsZFxuICAgICAgY2FjaGVkQ29tcGlsZXJIb3N0LmdldE1vZGlmaWVkUmVzb3VyY2VGaWxlcyA9IGZ1bmN0aW9uKCkge1xuICAgICAgICBpZiAodGltZXJIYW5kbGVGb3JSZWNvbXBpbGF0aW9uID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aW1lckhhbmRsZUZvclJlY29tcGlsYXRpb24ubW9kaWZpZWRSZXNvdXJjZUZpbGVzO1xuICAgICAgfTtcbiAgICB9XG4gICAgaWdub3JlRmlsZXNGb3JXYXRjaC5jbGVhcigpO1xuICAgIGNvbnN0IG9sZFByb2dyYW0gPSBjYWNoZWRQcm9ncmFtO1xuICAgIC8vIFdlIGNsZWFyIG91dCB0aGUgYGNhY2hlZFByb2dyYW1gIGhlcmUgYXMgYVxuICAgIC8vIHByb2dyYW0gY2FuIG9ubHkgYmUgdXNlZCBhcyBgb2xkUHJvZ3JhbWAgMXhcbiAgICBjYWNoZWRQcm9ncmFtID0gdW5kZWZpbmVkO1xuICAgIGNvbnN0IGNvbXBpbGVSZXN1bHQgPSBwZXJmb3JtQ29tcGlsYXRpb24oe1xuICAgICAgcm9vdE5hbWVzOiBjYWNoZWRPcHRpb25zLnJvb3ROYW1lcyxcbiAgICAgIG9wdGlvbnM6IGNhY2hlZE9wdGlvbnMub3B0aW9ucyxcbiAgICAgIGhvc3Q6IGNhY2hlZENvbXBpbGVySG9zdCxcbiAgICAgIG9sZFByb2dyYW06IG9sZFByb2dyYW0sXG4gICAgICBlbWl0Q2FsbGJhY2s6IGhvc3QuY3JlYXRlRW1pdENhbGxiYWNrKGNhY2hlZE9wdGlvbnMub3B0aW9ucylcbiAgICB9KTtcblxuICAgIGlmIChjb21waWxlUmVzdWx0LmRpYWdub3N0aWNzLmxlbmd0aCkge1xuICAgICAgaG9zdC5yZXBvcnREaWFnbm9zdGljcyhjb21waWxlUmVzdWx0LmRpYWdub3N0aWNzKTtcbiAgICB9XG5cbiAgICBjb25zdCBlbmRUaW1lID0gRGF0ZS5ub3coKTtcbiAgICBpZiAoY2FjaGVkT3B0aW9ucy5vcHRpb25zLmRpYWdub3N0aWNzKSB7XG4gICAgICBjb25zdCB0b3RhbFRpbWUgPSAoZW5kVGltZSAtIHN0YXJ0VGltZSkgLyAxMDAwO1xuICAgICAgaG9zdC5yZXBvcnREaWFnbm9zdGljcyhbdG90YWxDb21waWxhdGlvblRpbWVEaWFnbm9zdGljKGVuZFRpbWUgLSBzdGFydFRpbWUpXSk7XG4gICAgfVxuICAgIGNvbnN0IGV4aXRDb2RlID0gZXhpdENvZGVGcm9tUmVzdWx0KGNvbXBpbGVSZXN1bHQuZGlhZ25vc3RpY3MpO1xuICAgIGlmIChleGl0Q29kZSA9PSAwKSB7XG4gICAgICBjYWNoZWRQcm9ncmFtID0gY29tcGlsZVJlc3VsdC5wcm9ncmFtO1xuICAgICAgaG9zdC5yZXBvcnREaWFnbm9zdGljcyhcbiAgICAgICAgICBbY3JlYXRlTWVzc2FnZURpYWdub3N0aWMoJ0NvbXBpbGF0aW9uIGNvbXBsZXRlLiBXYXRjaGluZyBmb3IgZmlsZSBjaGFuZ2VzLicpXSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGhvc3QucmVwb3J0RGlhZ25vc3RpY3MoXG4gICAgICAgICAgW2NyZWF0ZU1lc3NhZ2VEaWFnbm9zdGljKCdDb21waWxhdGlvbiBmYWlsZWQuIFdhdGNoaW5nIGZvciBmaWxlIGNoYW5nZXMuJyldKTtcbiAgICB9XG5cbiAgICByZXR1cm4gY29tcGlsZVJlc3VsdC5kaWFnbm9zdGljcztcbiAgfVxuXG4gIGZ1bmN0aW9uIHJlc2V0T3B0aW9ucygpIHtcbiAgICBjYWNoZWRQcm9ncmFtID0gdW5kZWZpbmVkO1xuICAgIGNhY2hlZENvbXBpbGVySG9zdCA9IHVuZGVmaW5lZDtcbiAgICBjYWNoZWRPcHRpb25zID0gdW5kZWZpbmVkO1xuICB9XG5cbiAgZnVuY3Rpb24gd2F0Y2hlZEZpbGVDaGFuZ2VkKGV2ZW50OiBGaWxlQ2hhbmdlRXZlbnQsIGZpbGVOYW1lOiBzdHJpbmcpIHtcbiAgICBjb25zdCBub3JtYWxpemVkUGF0aCA9IHBhdGgubm9ybWFsaXplKGZpbGVOYW1lKTtcblxuICAgIGlmIChjYWNoZWRPcHRpb25zICYmIGV2ZW50ID09PSBGaWxlQ2hhbmdlRXZlbnQuQ2hhbmdlICYmXG4gICAgICAgIC8vIFRPRE8oY2h1Y2tqKTogdmFsaWRhdGUgdGhhdCB0aGlzIGlzIHN1ZmZpY2llbnQgdG8gc2tpcCBmaWxlcyB0aGF0IHdlcmUgd3JpdHRlbi5cbiAgICAgICAgLy8gVGhpcyBhc3N1bWVzIHRoYXQgdGhlIGZpbGUgcGF0aCB3ZSB3cml0ZSBpcyB0aGUgc2FtZSBmaWxlIHBhdGggd2Ugd2lsbCByZWNlaXZlIGluIHRoZVxuICAgICAgICAvLyBjaGFuZ2Ugbm90aWZpY2F0aW9uLlxuICAgICAgICBub3JtYWxpemVkUGF0aCA9PT0gcGF0aC5ub3JtYWxpemUoY2FjaGVkT3B0aW9ucy5wcm9qZWN0KSkge1xuICAgICAgLy8gSWYgdGhlIGNvbmZpZ3VyYXRpb24gZmlsZSBjaGFuZ2VzLCBmb3JnZXQgZXZlcnl0aGluZyBhbmQgc3RhcnQgdGhlIHJlY29tcGlsYXRpb24gdGltZXJcbiAgICAgIHJlc2V0T3B0aW9ucygpO1xuICAgIH0gZWxzZSBpZiAoXG4gICAgICAgIGV2ZW50ID09PSBGaWxlQ2hhbmdlRXZlbnQuQ3JlYXRlRGVsZXRlIHx8IGV2ZW50ID09PSBGaWxlQ2hhbmdlRXZlbnQuQ3JlYXRlRGVsZXRlRGlyKSB7XG4gICAgICAvLyBJZiBhIGZpbGUgd2FzIGFkZGVkIG9yIHJlbW92ZWQsIHJlcmVhZCB0aGUgY29uZmlndXJhdGlvblxuICAgICAgLy8gdG8gZGV0ZXJtaW5lIHRoZSBuZXcgbGlzdCBvZiByb290IGZpbGVzLlxuICAgICAgY2FjaGVkT3B0aW9ucyA9IHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICBpZiAoZXZlbnQgPT09IEZpbGVDaGFuZ2VFdmVudC5DcmVhdGVEZWxldGVEaXIpIHtcbiAgICAgIGZpbGVDYWNoZS5jbGVhcigpO1xuICAgIH0gZWxzZSB7XG4gICAgICBmaWxlQ2FjaGUuZGVsZXRlKG5vcm1hbGl6ZWRQYXRoKTtcbiAgICB9XG5cbiAgICBpZiAoIWlnbm9yZUZpbGVzRm9yV2F0Y2guaGFzKG5vcm1hbGl6ZWRQYXRoKSkge1xuICAgICAgLy8gSWdub3JlIHRoZSBmaWxlIGlmIHRoZSBmaWxlIGlzIG9uZSB0aGF0IHdhcyB3cml0dGVuIGJ5IHRoZSBjb21waWxlci5cbiAgICAgIHN0YXJ0VGltZXJGb3JSZWNvbXBpbGF0aW9uKG5vcm1hbGl6ZWRQYXRoKTtcbiAgICB9XG4gIH1cblxuICAvLyBVcG9uIGRldGVjdGluZyBhIGZpbGUgY2hhbmdlLCB3YWl0IGZvciAyNTBtcyBhbmQgdGhlbiBwZXJmb3JtIGEgcmVjb21waWxhdGlvbi4gVGhpcyBnaXZlcyBiYXRjaFxuICAvLyBvcGVyYXRpb25zIChzdWNoIGFzIHNhdmluZyBhbGwgbW9kaWZpZWQgZmlsZXMgaW4gYW4gZWRpdG9yKSBhIGNoYW5jZSB0byBjb21wbGV0ZSBiZWZvcmUgd2Uga2lja1xuICAvLyBvZmYgYSBuZXcgY29tcGlsYXRpb24uXG4gIGZ1bmN0aW9uIHN0YXJ0VGltZXJGb3JSZWNvbXBpbGF0aW9uKGNoYW5nZWRQYXRoOiBzdHJpbmcpIHtcbiAgICBpZiAodGltZXJIYW5kbGVGb3JSZWNvbXBpbGF0aW9uKSB7XG4gICAgICBob3N0LmNsZWFyVGltZW91dCh0aW1lckhhbmRsZUZvclJlY29tcGlsYXRpb24udGltZXJIYW5kbGUpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aW1lckhhbmRsZUZvclJlY29tcGlsYXRpb24gPSB7XG4gICAgICAgIG1vZGlmaWVkUmVzb3VyY2VGaWxlczogbmV3IFNldDxzdHJpbmc+KCksXG4gICAgICAgIHRpbWVySGFuZGxlOiB1bmRlZmluZWRcbiAgICAgIH07XG4gICAgfVxuICAgIHRpbWVySGFuZGxlRm9yUmVjb21waWxhdGlvbi50aW1lckhhbmRsZSA9IGhvc3Quc2V0VGltZW91dChyZWNvbXBpbGUsIDI1MCk7XG4gICAgdGltZXJIYW5kbGVGb3JSZWNvbXBpbGF0aW9uLm1vZGlmaWVkUmVzb3VyY2VGaWxlcy5hZGQoY2hhbmdlZFBhdGgpO1xuICB9XG5cbiAgZnVuY3Rpb24gcmVjb21waWxlKCkge1xuICAgIGhvc3QucmVwb3J0RGlhZ25vc3RpY3MoXG4gICAgICAgIFtjcmVhdGVNZXNzYWdlRGlhZ25vc3RpYygnRmlsZSBjaGFuZ2UgZGV0ZWN0ZWQuIFN0YXJ0aW5nIGluY3JlbWVudGFsIGNvbXBpbGF0aW9uLicpXSk7XG4gICAgZG9Db21waWxhdGlvbigpO1xuICAgIHRpbWVySGFuZGxlRm9yUmVjb21waWxhdGlvbiA9IHVuZGVmaW5lZDtcbiAgfVxufVxuIl19 |
---|