UNPKG

matrix-react-sdk

Version:
224 lines (188 loc) 19.1 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "PerformanceEntryNames", { enumerable: true, get: function () { return _entryNames.PerformanceEntryNames; } }); exports.default = void 0; var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _entryNames = require("./entry-names"); /* Copyright 2021 The Matrix.org Foundation C.I.C. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ class PerformanceMonitor { constructor() { (0, _defineProperty2.default)(this, "START_PREFIX", "start:"); (0, _defineProperty2.default)(this, "STOP_PREFIX", "stop:"); (0, _defineProperty2.default)(this, "listeners", []); (0, _defineProperty2.default)(this, "entries", []); } static get instance() /*: PerformanceMonitor*/ { if (!PerformanceMonitor._instance) { PerformanceMonitor._instance = new PerformanceMonitor(); } return PerformanceMonitor._instance; } /** * Starts a performance recording * @param name Name of the recording * @param id Specify an identifier appended to the measurement name * @returns {void} */ start(name /*: string*/ , id /*: string*/ ) /*: void*/ { if (!this.supportsPerformanceApi()) { return; } const key = this.buildKey(name, id); if (performance.getEntriesByName(this.START_PREFIX + key).length > 0) { console.warn(`Recording already started for: ${name}`); return; } performance.mark(this.START_PREFIX + key); } /** * Stops a performance recording and stores delta duration * with the start marker * @param name Name of the recording * @param id Specify an identifier appended to the measurement name * @returns {void} */ stop(name /*: string*/ , id /*: string*/ ) /*: PerformanceEntry*/ { if (!this.supportsPerformanceApi()) { return; } const key = this.buildKey(name, id); if (performance.getEntriesByName(this.START_PREFIX + key).length === 0) { console.warn(`No recording started for: ${name}`); return; } performance.mark(this.STOP_PREFIX + key); performance.measure(key, this.START_PREFIX + key, this.STOP_PREFIX + key); this.clear(name, id); const measurement = performance.getEntriesByName(key).pop(); // Keeping a reference to all PerformanceEntry created // by this abstraction for historical events collection // when adding a data callback this.entries.push(measurement); this.listeners.forEach(listener => { if (this.shouldEmit(listener, measurement)) { listener.callback([measurement]); } }); return measurement; } clear(name /*: string*/ , id /*: string*/ ) /*: void*/ { if (!this.supportsPerformanceApi()) { return; } const key = this.buildKey(name, id); performance.clearMarks(this.START_PREFIX + key); performance.clearMarks(this.STOP_PREFIX + key); } getEntries({ name, type } /*: GetEntriesOptions*/ = {}) /*: PerformanceEntry[]*/ { return this.entries.filter(entry => { const satisfiesName = !name || entry.name === name; const satisfiedType = !type || entry.entryType === type; return satisfiesName && satisfiedType; }); } addPerformanceDataCallback(listener /*: PerformanceDataListener*/ , buffer = false) { this.listeners.push(listener); if (buffer) { const toEmit = this.entries.filter(entry => this.shouldEmit(listener, entry)); if (toEmit.length > 0) { listener.callback(toEmit); } } } removePerformanceDataCallback(callback /*: PerformanceCallbackFunction*/ ) { if (!callback) { this.listeners = []; } else { this.listeners.splice(this.listeners.findIndex(listener => listener.callback === callback), 1); } } /** * Tor browser does not support the Performance API * @returns {boolean} true if the Performance API is supported */ supportsPerformanceApi() /*: boolean*/ { return performance !== undefined && performance.mark !== undefined; } shouldEmit(listener /*: PerformanceDataListener*/ , entry /*: PerformanceEntry*/ ) /*: boolean*/ { return !listener.entryNames || listener.entryNames.includes(entry.name); } /** * Internal utility to ensure consistent name for the recording * @param name Name of the recording * @param id Specify an identifier appended to the measurement name * @returns {string} a compound of the name and identifier if present */ buildKey(name /*: string*/ , id /*: string*/ ) /*: string*/ { return `${name}${id ? `:${id}` : ''}`; } } // Convenience exports exports.default = PerformanceMonitor; (0, _defineProperty2.default)(PerformanceMonitor, "_instance", void 0); // Exposing those to the window object to bridge them from tests window.mxPerformanceMonitor = PerformanceMonitor.instance; window.mxPerformanceEntryNames = _entryNames.PerformanceEntryNames; //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9wZXJmb3JtYW5jZS9pbmRleC50cyJdLCJuYW1lcyI6WyJQZXJmb3JtYW5jZU1vbml0b3IiLCJpbnN0YW5jZSIsIl9pbnN0YW5jZSIsInN0YXJ0IiwibmFtZSIsImlkIiwic3VwcG9ydHNQZXJmb3JtYW5jZUFwaSIsImtleSIsImJ1aWxkS2V5IiwicGVyZm9ybWFuY2UiLCJnZXRFbnRyaWVzQnlOYW1lIiwiU1RBUlRfUFJFRklYIiwibGVuZ3RoIiwiY29uc29sZSIsIndhcm4iLCJtYXJrIiwic3RvcCIsIlNUT1BfUFJFRklYIiwibWVhc3VyZSIsImNsZWFyIiwibWVhc3VyZW1lbnQiLCJwb3AiLCJlbnRyaWVzIiwicHVzaCIsImxpc3RlbmVycyIsImZvckVhY2giLCJsaXN0ZW5lciIsInNob3VsZEVtaXQiLCJjYWxsYmFjayIsImNsZWFyTWFya3MiLCJnZXRFbnRyaWVzIiwidHlwZSIsImZpbHRlciIsImVudHJ5Iiwic2F0aXNmaWVzTmFtZSIsInNhdGlzZmllZFR5cGUiLCJlbnRyeVR5cGUiLCJhZGRQZXJmb3JtYW5jZURhdGFDYWxsYmFjayIsImJ1ZmZlciIsInRvRW1pdCIsInJlbW92ZVBlcmZvcm1hbmNlRGF0YUNhbGxiYWNrIiwic3BsaWNlIiwiZmluZEluZGV4IiwidW5kZWZpbmVkIiwiZW50cnlOYW1lcyIsImluY2x1ZGVzIiwid2luZG93IiwibXhQZXJmb3JtYW5jZU1vbml0b3IiLCJteFBlcmZvcm1hbmNlRW50cnlOYW1lcyIsIlBlcmZvcm1hbmNlRW50cnlOYW1lcyJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFnQkE7O0FBaEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQWdCZSxNQUFNQSxrQkFBTixDQUF5QjtBQUFBO0FBQUEsd0RBR2IsUUFIYTtBQUFBLHVEQUlkLE9BSmM7QUFBQSxxREFNVyxFQU5YO0FBQUEsbURBT0Us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QUFDSjtBQUNBO0FBQ0E7OztBQUNZdEIsRUFBQUEsc0JBQVI7QUFBQTtBQUEwQztBQUN0QyxXQUFPRyxXQUFXLEtBQUtrQyxTQUFoQixJQUE2QmxDLFdBQVcsQ0FBQ00sSUFBWixLQUFxQjRCLFNBQXpEO0FBQ0g7O0FBRU9oQixFQUFBQSxVQUFSLENBQW1CRDtBQUFuQjtBQUFBLElBQXNETztBQUF0RDtBQUFBO0FBQUE7QUFBd0Y7QUFDcEYsV0FBTyxDQUFDUCxRQUFRLENBQUNrQixVQUFWLElBQXdCbEIsUUFBUSxDQUFDa0IsVUFBVCxDQUFvQkMsUUFBcEIsQ0FBNkJaLEtBQUssQ0FBQzdCLElBQW5DLENBQS9CO0FBQ0g7QUFFRDtBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUNZSSxFQUFBQSxRQUFSLENBQWlCSjtBQUFqQjtBQUFBLElBQStCQztBQUEvQjtBQUFBO0FBQUE7QUFBb0Q7QUFDaEQsV0FBUSxHQUFFRCxJQUFLLEdBQUVDLEVBQUUsR0FBSSxJQUFHQSxFQUFHLEVBQVYsR0FBYyxFQUFHLEVBQXBDO0FBQ0g7O0FBeEltQyxDLENBNEl4Qzs7Ozs4QkE1SXFCTCxrQjtBQWlKckI7QUFDQThDLE1BQU0sQ0FBQ0Msb0JBQVAsR0FBOEIvQyxrQkFBa0IsQ0FBQ0MsUUFBakQ7QUFDQTZDLE1BQU0sQ0FBQ0UsdUJBQVAsR0FBaUNDLGlDQUFqQyIsInNvdXJjZXNDb250ZW50IjpbIi8qXG5Db3B5cmlnaHQgMjAyMSBUaGUgTWF0cml4Lm9yZyBGb3VuZGF0aW9uIEMuSS5DLlxuXG5MaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xueW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG5cbiAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcblxuVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG5TZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG5saW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiovXG5cbmltcG9ydCB7IFBlcmZvcm1hbmNlRW50cnlOYW1lcyB9IGZyb20gXCIuL2VudHJ5LW5hbWVzXCI7XG5cbmludGVyZmFjZSBHZXRFbnRyaWVzT3B0aW9ucyB7XG4gICAgbmFtZT86IHN0cmluZyxcbiAgICB0eXBlPzogc3RyaW5nLFxufVxuXG50eXBlIFBlcmZvcm1hbmNlQ2FsbGJhY2tGdW5jdGlvbiA9IChlbnRyeTogUGVyZm9ybWFuY2VFbnRyeVtdKSA9PiB2b2lkO1xuXG5pbnRlcmZhY2UgUGVyZm9ybWFuY2VEYXRhTGlzdGVuZXIge1xuICAgIGVudHJ5TmFtZXM/OiBzdHJpbmdbXSxcbiAgICBjYWxsYmFjazogUGVyZm9ybWFuY2VDYWxsYmFja0Z1bmN0aW9uXG59XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFBlcmZvcm1hbmNlTW9uaXRvciB7XG4gICAgc3RhdGljIF9pbnN0YW5jZTogUGVyZm9ybWFuY2VNb25pdG9yO1xuXG4gICAgcHJpdmF0ZSBTVEFSVF9QUkVGSVggPSBcInN0YXJ0OlwiXG4gICAgcHJpdmF0ZSBTVE9QX1BSRUZJWCA9IFwic3RvcDpcIlxuXG4gICAgcHJpdmF0ZSBsaXN0ZW5lcnM6IFBlcmZvcm1hbmNlRGF0YUxpc3RlbmVyW10gPSBbXVxuICAgIHByaXZhdGUgZW50cmllczogUGVyZm9ybWFuY2VFbnRyeVtdID0gW11cblxuICAgIHB1YmxpYyBzdGF0aWMgZ2V0IGluc3RhbmNlKCk6IFBlcmZvcm1hbmNlTW9uaXRvciB7XG4gICAgICAgIGlmICghUGVyZm9ybWFuY2VNb25pdG9yLl9pbnN0YW5jZSkge1xuICAgICAgICAgICAgUGVyZm9ybWFuY2VNb25pdG9yLl9pbnN0YW5jZSA9IG5ldyBQZXJmb3JtYW5jZU1vbml0b3IoKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gUGVyZm9ybWFuY2VNb25pdG9yLl9pbnN0YW5jZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTdGFydHMgYSBwZXJmb3JtYW5jZSByZWNvcmRpbmdcbiAgICAgKiBAcGFyYW0gbmFtZSBOYW1lIG9mIHRoZSByZWNvcmRpbmdcbiAgICAgKiBAcGFyYW0gaWQgU3BlY2lmeSBhbiBpZGVudGlmaWVyIGFwcGVuZGVkIHRvIHRoZSBtZWFzdXJlbWVudCBuYW1lXG4gICAgICogQHJldHVybnMge3ZvaWR9XG4gICAgICovXG4gICAgc3RhcnQobmFtZTogc3RyaW5nLCBpZD86IHN0cmluZyk6IHZvaWQge1xuICAgICAgICBpZiAoIXRoaXMuc3VwcG9ydHNQZXJmb3JtYW5jZUFwaSgpKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgY29uc3Qga2V5ID0gdGhpcy5idWlsZEtleShuYW1lLCBpZCk7XG5cbiAgICAgICAgaWYgKHBlcmZvcm1hbmNlLmdldEVudHJpZXNCeU5hbWUodGhpcy5TVEFSVF9QUkVGSVggKyBrZXkpLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIGNvbnNvbGUud2FybihgUmVjb3JkaW5nIGFscmVhZHkgc3RhcnRlZCBmb3I6ICR7bmFtZX1gKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHBlcmZvcm1hbmNlLm1hcmsodGhpcy5TVEFSVF9QUkVGSVggKyBrZXkpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFN0b3BzIGEgcGVyZm9ybWFuY2UgcmVjb3JkaW5nIGFuZCBzdG9yZXMgZGVsdGEgZHVyYXRpb25cbiAgICAgKiB3aXRoIHRoZSBzdGFydCBtYXJrZXJcbiAgICAgKiBAcGFyYW0gbmFtZSBOYW1lIG9mIHRoZSByZWNvcmRpbmdcbiAgICAgKiBAcGFyYW0gaWQgU3BlY2lmeSBhbiBpZGVudGlmaWVyIGFwcGVuZGVkIHRvIHRoZSBtZWFzdXJlbWVudCBuYW1lXG4gICAgICogQHJldHVybnMge3ZvaWR9XG4gICAgICovXG4gICAgc3RvcChuYW1lOiBzdHJpbmcsIGlkPzogc3RyaW5nKTogUGVyZm9ybWFuY2VFbnRyeSB7XG4gICAgICAgIGlmICghdGhpcy5zdXBwb3J0c1BlcmZvcm1hbmNlQXBpKCkpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBrZXkgPSB0aGlzLmJ1aWxkS2V5KG5hbWUsIGlkKTtcbiAgICAgICAgaWYgKHBlcmZvcm1hbmNlLmdldEVudHJpZXNCeU5hbWUodGhpcy5TVEFSVF9QUkVGSVggKyBrZXkpLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgY29uc29sZS53YXJuKGBObyByZWNvcmRpbmcgc3RhcnRlZCBmb3I6ICR7bmFtZX1gKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHBlcmZvcm1hbmNlLm1hcmsodGhpcy5TVE9QX1BSRUZJWCArIGtleSk7XG4gICAgICAgIHBlcmZvcm1hbmNlLm1lYXN1cmUoXG4gICAgICAgICAgICBrZXksXG4gICAgICAgICAgICB0aGlzLlNUQVJUX1BSRUZJWCArIGtleSxcbiAgICAgICAgICAgIHRoaXMuU1RPUF9QUkVGSVggKyBrZXksXG4gICAgICAgICk7XG5cbiAgICAgICAgdGhpcy5jbGVhcihuYW1lLCBpZCk7XG5cbiAgICAgICAgY29uc3QgbWVhc3VyZW1lbnQgPSBwZXJmb3JtYW5jZS5nZXRFbnRyaWVzQnlOYW1lKGtleSkucG9wKCk7XG5cbiAgICAgICAgLy8gS2VlcGluZyBhIHJlZmVyZW5jZSB0byBhbGwgUGVyZm9ybWFuY2VFbnRyeSBjcmVhdGVkXG4gICAgICAgIC8vIGJ5IHRoaXMgYWJzdHJhY3Rpb24gZm9yIGhpc3RvcmljYWwgZXZlbnRzIGNvbGxlY3Rpb25cbiAgICAgICAgLy8gd2hlbiBhZGRpbmcgYSBkYXRhIGNhbGxiYWNrXG4gICAgICAgIHRoaXMuZW50cmllcy5wdXNoKG1lYXN1cmVtZW50KTtcblxuICAgICAgICB0aGlzLmxpc3RlbmVycy5mb3JFYWNoKGxpc3RlbmVyID0+IHtcbiAgICAgICAgICAgIGlmICh0aGlzLnNob3VsZEVtaXQobGlzdGVuZXIsIG1lYXN1cmVtZW50KSkge1xuICAgICAgICAgICAgICAgIGxpc3RlbmVyLmNhbGxiYWNrKFttZWFzdXJlbWVudF0pXG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHJldHVybiBtZWFzdXJlbWVudDtcbiAgICB9XG5cbiAgICBjbGVhcihuYW1lOiBzdHJpbmcsIGlkPzogc3RyaW5nKTogdm9pZCB7XG4gICAgICAgIGlmICghdGhpcy5zdXBwb3J0c1BlcmZvcm1hbmNlQXBpKCkpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBrZXkgPSB0aGlzLmJ1aWxkS2V5KG5hbWUsIGlkKTtcbiAgICAgICAgcGVyZm9ybWFuY2UuY2xlYXJNYXJrcyh0aGlzLlNUQVJUX1BSRUZJWCArIGtleSk7XG4gICAgICAgIHBlcmZvcm1hbmNlLmNsZWFyTWFya3ModGhpcy5TVE9QX1BSRUZJWCArIGtleSk7XG4gICAgfVxuXG4gICAgZ2V0RW50cmllcyh7IG5hbWUsIHR5cGUgfTogR2V0RW50cmllc09wdGlvbnMgPSB7fSk6IFBlcmZvcm1hbmNlRW50cnlbXSB7XG4gICAgICAgIHJldHVybiB0aGlzLmVudHJpZXMuZmlsdGVyKGVudHJ5ID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHNhdGlzZmllc05hbWUgPSAhbmFtZSB8fCBlbnRyeS5uYW1lID09PSBuYW1lO1xuICAgICAgICAgICAgY29uc3Qgc2F0aXNmaWVkVHlwZSA9ICF0eXBlIHx8IGVudHJ5LmVudHJ5VHlwZSA9PT0gdHlwZTtcbiAgICAgICAgICAgIHJldHVybiBzYXRpc2ZpZXNOYW1lICYmIHNhdGlzZmllZFR5cGU7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIGFkZFBlcmZvcm1hbmNlRGF0YUNhbGxiYWNrKGxpc3RlbmVyOiBQZXJmb3JtYW5jZURhdGFMaXN0ZW5lciwgYnVmZmVyID0gZmFsc2UpIHtcbiAgICAgICAgdGhpcy5saXN0ZW5lcnMucHVzaChsaXN0ZW5lcik7XG4gICAgICAgIGlmIChidWZmZXIpIHtcbiAgICAgICAgICAgIGNvbnN0IHRvRW1pdCA9IHRoaXMuZW50cmllcy5maWx0ZXIoZW50cnkgPT4gdGhpcy5zaG91bGRFbWl0KGxpc3RlbmVyLCBlbnRyeSkpO1xuICAgICAgICAgICAgaWYgKHRvRW1pdC5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgICAgbGlzdGVuZXIuY2FsbGJhY2sodG9FbWl0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIHJlbW92ZVBlcmZvcm1hbmNlRGF0YUNhbGxiYWNrKGNhbGxiYWNrPzogUGVyZm9ybWFuY2VDYWxsYmFja0Z1bmN0aW9uKSB7XG4gICAgICAgIGlmICghY2FsbGJhY2spIHtcbiAgICAgICAgICAgIHRoaXMubGlzdGVuZXJzID0gW107XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmxpc3RlbmVycy5zcGxpY2UoXG4gICAgICAgICAgICAgICAgdGhpcy5saXN0ZW5lcnMuZmluZEluZGV4KGxpc3RlbmVyID0+IGxpc3RlbmVyLmNhbGxiYWNrID09PSBjYWxsYmFjayksXG4gICAgICAgICAgICAgICAgMSxcbiAgICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUb3IgYnJvd3NlciBkb2VzIG5vdCBzdXBwb3J0IHRoZSBQZXJmb3JtYW5jZSBBUElcbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gdHJ1ZSBpZiB0aGUgUGVyZm9ybWFuY2UgQVBJIGlzIHN1cHBvcnRlZFxuICAgICAqL1xuICAgIHByaXZhdGUgc3VwcG9ydHNQZXJmb3JtYW5jZUFwaSgpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHBlcmZvcm1hbmNlICE9PSB1bmRlZmluZWQgJiYgcGVyZm9ybWFuY2UubWFyayAhPT0gdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIHByaXZhdGUgc2hvdWxkRW1pdChsaXN0ZW5lcjogUGVyZm9ybWFuY2VEYXRhTGlzdGVuZXIsIGVudHJ5OiBQZXJmb3JtYW5jZUVudHJ5KTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiAhbGlzdGVuZXIuZW50cnlOYW1lcyB8fCBsaXN0ZW5lci5lbnRyeU5hbWVzLmluY2x1ZGVzKGVudHJ5Lm5hbWUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEludGVybmFsIHV0aWxpdHkgdG8gZW5zdXJlIGNvbnNpc3RlbnQgbmFtZSBmb3IgdGhlIHJlY29yZGluZ1xuICAgICAqIEBwYXJhbSBuYW1lIE5hbWUgb2YgdGhlIHJlY29yZGluZ1xuICAgICAqIEBwYXJhbSBpZCBTcGVjaWZ5IGFuIGlkZW50aWZpZXIgYXBwZW5kZWQgdG8gdGhlIG1lYXN1cmVtZW50IG5hbWVcbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBhIGNvbXBvdW5kIG9mIHRoZSBuYW1lIGFuZCBpZGVudGlmaWVyIGlmIHByZXNlbnRcbiAgICAgKi9cbiAgICBwcml2YXRlIGJ1aWxkS2V5KG5hbWU6IHN0cmluZywgaWQ/OiBzdHJpbmcpOiBzdHJpbmcge1xuICAgICAgICByZXR1cm4gYCR7bmFtZX0ke2lkID8gYDoke2lkfWAgOiAnJ31gO1xuICAgIH1cbn1cblxuXG4vLyBDb252ZW5pZW5jZSBleHBvcnRzXG5leHBvcnQge1xuICAgIFBlcmZvcm1hbmNlRW50cnlOYW1lcyxcbn1cblxuLy8gRXhwb3NpbmcgdGhvc2UgdG8gdGhlIHdpbmRvdyBvYmplY3QgdG8gYnJpZGdlIHRoZW0gZnJvbSB0ZXN0c1xud2luZG93Lm14UGVyZm9ybWFuY2VNb25pdG9yID0gUGVyZm9ybWFuY2VNb25pdG9yLmluc3RhbmNlO1xud2luZG93Lm14UGVyZm9ybWFuY2VFbnRyeU5hbWVzID0gUGVyZm9ybWFuY2VFbnRyeU5hbWVzO1xuIl19