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