request-monitor
Version:
437 lines (395 loc) • 40.1 kB
JavaScript
(function webpackUniversalModuleDefinition(root, factory) {
if(typeof exports === 'object' && typeof module === 'object')
module.exports = factory();
else if(typeof define === 'function' && define.amd)
define([], factory);
else if(typeof exports === 'object')
exports["requestMonitor"] = factory();
else
root["requestMonitor"] = factory();
})(window, function() {
return /******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId]) {
/******/ return installedModules[moduleId].exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ i: moduleId,
/******/ l: false,
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ // Flag the module as loaded
/******/ module.l = true;
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/******/
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/
/******/ // define getter function for harmony exports
/******/ __webpack_require__.d = function(exports, name, getter) {
/******/ if(!__webpack_require__.o(exports, name)) {
/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter });
/******/ }
/******/ };
/******/
/******/ // define __esModule on exports
/******/ __webpack_require__.r = function(exports) {
/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
/******/ }
/******/ Object.defineProperty(exports, '__esModule', { value: true });
/******/ };
/******/
/******/ // create a fake namespace object
/******/ // mode & 1: value is a module id, require it
/******/ // mode & 2: merge all properties of value into the ns
/******/ // mode & 4: return value when already ns object
/******/ // mode & 8|1: behave like require
/******/ __webpack_require__.t = function(value, mode) {
/******/ if(mode & 1) value = __webpack_require__(value);
/******/ if(mode & 8) return value;
/******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
/******/ var ns = Object.create(null);
/******/ __webpack_require__.r(ns);
/******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value });
/******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
/******/ return ns;
/******/ };
/******/
/******/ // getDefaultExport function for compatibility with non-harmony modules
/******/ __webpack_require__.n = function(module) {
/******/ var getter = module && module.__esModule ?
/******/ function getDefault() { return module['default']; } :
/******/ function getModuleExports() { return module; };
/******/ __webpack_require__.d(getter, 'a', getter);
/******/ return getter;
/******/ };
/******/
/******/ // Object.prototype.hasOwnProperty.call
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/
/******/
/******/ // Load entry module and return exports
/******/ return __webpack_require__(__webpack_require__.s = "./src/index.js");
/******/ })
/************************************************************************/
/******/ ({
/***/ "./src/index.js":
/*!**********************!*\
!*** ./src/index.js ***!
\**********************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {
;
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
/**
*
* @param {*} listener
*
http Info: {
__type: "fetch", // 使用底层库类型,有 fetch 和 xhr
url: "",
method: "",
timeout: 0, // 超时时间
params: {}, // 请求参数
responseStatus: 200, // 如果是 -1 ,代表网络异常
responseStatusText: "ok",
responseJson: {"code": 0},
responseText: "{"code": 0}",
requestTime: 100, 请求时间,单位为 ms
}
*/
var listeners = {};
var id = 1;
function getId() {
return id++;
}
function handleEndTime(info) {
var endTime = new Date().getTime();
info.requestTime = endTime - info.startTime;
info.endTime = endTime;
}
function handleDefaultApi(emit) {
if (window._requestMonitorIsLoad) return null;
window._requestMonitorIsLoad = true;
handleXhr(emit);
handleFetch(emit);
return true;
}
function handleHeader(xhr) {
try {
var headers = xhr.getAllResponseHeaders();
if (!headers) return;
if ((typeof headers === 'undefined' ? 'undefined' : _typeof(headers)) === 'object') {
return headers;
}
var newHeaders = {},
headers = headers.split(/[\r\n]/).forEach(function (header) {
var index = header.indexOf(":");
var name = header.substr(0, index);
var value = header.substr(index + 2);
if (name) {
newHeaders[name] = value;
}
});
return newHeaders;
} catch (e) {
return {};
}
}
function handleXhr(emit) {
var _open = XMLHttpRequest.prototype.open;
var _send = XMLHttpRequest.prototype.send;
XMLHttpRequest.prototype.open = function () {
for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
var method = args[0];
var url = args[1];
this._monitor = {
__type: 'xhr'
};
_open.apply(this, args);
Object.assign(this._monitor, {
method: method,
url: url
});
};
XMLHttpRequest.prototype.send = function () {
var _this = this;
for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
args[_key2] = arguments[_key2];
}
_send.apply(this, args);
this._monitor.startTime = new Date().getTime();
this._monitor.timeout = this.timeout || 0;
try {
if (args.length > 0 && typeof args[0] === 'string') {
this._monitor.params = args[0];
}
} catch (err) {}
this.addEventListener('load', function () {
var contentType = this.getResponseHeader('Content-Type');
contentType = contentType || '';
contentType = contentType.toLowerCase();
var ignores = ['blob', 'arraybuffer', 'moz-chunked-arraybuffer', "ms-stream"];
if (this.responseType && ignores.indexOf(this.responseType) > -1) {
return; // ignore blob type
}
if (contentType.indexOf('application/json') !== -1) {
this._monitor.responseText = this.responseText;
try {
this._monitor.responseJson = JSON.parse(this.responseText);
} catch (e) {}
} else if (contentType.indexOf('text/plain') !== -1) {
this._monitor.responseText = this.responseText;
}
this._monitor.responseHeaders = handleHeader(this);
this._monitor.responseStatus = this.status;
this._monitor.responseStatusText = this.statusText;
emit(this._monitor);
}, false);
this.addEventListener('error', function () {
_this._monitor.responseStatusText = 'Xhr Network request exception';
_this._monitor.responseStatus = -1;
emit(_this._monitor);
});
this.addEventListener('timeout', function () {
emit(_this._monitor);
});
};
}
function getParams(options) {
var params = void 0;
try {
if (options.body && typeof options.body === 'string') {
params = options.body;
}
} catch (er) {}
return params;
}
function handleFetch(emit) {
if (window.fetch) {
var getHeaders = function getHeaders(response) {
try {
var headers = response.headers.entries();
var result = {};
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
try {
for (var _iterator = headers[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
var pair = _step.value;
result[pair[0]] = pair[1];
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator.return) {
_iterator.return();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
}
}
return result;
} catch (e) {
console.warn(e);
return {};
}
};
var monitorFetch = function monitorFetch(url) {
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
var params = getParams(options);
var _monitor = {
__type: 'fetch',
url: url,
method: options.method || 'GET',
params: params,
startTime: new Date().getTime(),
timeout: options.timeout || 0
};
var fetchRequest =
// _Promise
// .race ([
// new _Promise ((resolve, reject) => {
// setTimeout (() => {
// let err = new Error ('前端fetch Network request timeout: ' + options.timeout);
// err.status = 504;
// reject (err);
// }, timeout);
// }),
// ])
_fetch(url, options).then(function (response) {
var _text = response.text;
_monitor.responseStatus = response.status;
_monitor.responseHeaders = getHeaders(response);
_monitor.responseStatusText = response.statusText;
response.json = function () {
return new _Promise(function (resolve, reject) {
_text.call(response).then(function (text) {
try {
var json = JSON.parse(text);
_monitor.responseText = text;
_monitor.responseJson = json;
emit(_monitor);
resolve(json);
} catch (e) {
e.type = 'invalid-json';
_monitor.responseText = text;
emit(_monitor);
reject(e);
}
}).catch(function (err) {
reject(err);
});
});
};
response.text = function () {
return new _Promise(function (resolve, reject) {
_text.call(response).then(function (text) {
_monitor.responseText = text;
emit(_monitor);
resolve(text);
}).catch(function (err) {
reject(err);
});
});
};
return response;
});
return new _Promise(function (resolve, reject) {
fetchRequest.then(function (data) {
resolve(data);
}).catch(function (err) {
_monitor.responseStatus = err.status || -1;
_monitor.responseText = err.message || 'Fetch Network request exception';
emit(_monitor);
reject(err);
});
return fetchRequest;
});
};
var _Promise = window.fetch.Promise || Promise;
var _fetch = window.fetch;
monitorFetch.Promise = _Promise;
Object.defineProperty(monitorFetch, 'Promise', {
set: function set(value) {
// monitorFetch.Promise = value;
_fetch.Promise = value;
},
get: function get() {
return _fetch.Promise;
}
});
window.fetch = monitorFetch;
}
}
function emit(info) {
handleEndTime(info);
try {
Object.keys(info).forEach(function (key) {
if (typeof info[key] === 'undefined') {
delete info[key];
}
});
Object.keys(listeners).forEach(function (key) {
setTimeout(function () {
try {
listeners[key](info);
} catch (err) {
console.error(err);
}
});
});
} catch (e) {
console.error(e);
}
}
module.exports = requestMonitor;
function requestMonitor(listener) {
listener = listener || function (httpInfo) {
return httpInfo;
};
if (typeof listener !== 'function') {
throw new Error('The listener Type must be function');
}
var _id = getId();
listeners[_id] = listener;
handleDefaultApi(emit);
return {
cancel: function cancel() {
delete listeners[_id];
}
};
}
requestMonitor.handleDefaultApi = handleDefaultApi;
/***/ })
/******/ });
});
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9yZXF1ZXN0TW9uaXRvci93ZWJwYWNrL3VuaXZlcnNhbE1vZHVsZURlZmluaXRpb24iLCJ3ZWJwYWNrOi8vcmVxdWVzdE1vbml0b3Ivd2VicGFjay9ib290c3RyYXAiLCJ3ZWJwYWNrOi8vcmVxdWVzdE1vbml0b3IvLi9zcmMvaW5kZXguanMiXSwibmFtZXMiOlsibGlzdGVuZXJzIiwiaWQiLCJnZXRJZCIsImhhbmRsZUVuZFRpbWUiLCJpbmZvIiwiZW5kVGltZSIsIkRhdGUiLCJnZXRUaW1lIiwicmVxdWVzdFRpbWUiLCJzdGFydFRpbWUiLCJoYW5kbGVEZWZhdWx0QXBpIiwiZW1pdCIsIndpbmRvdyIsIl9yZXF1ZXN0TW9uaXRvcklzTG9hZCIsImhhbmRsZVhociIsImhhbmRsZUZldGNoIiwiaGFuZGxlSGVhZGVyIiwieGhyIiwiaGVhZGVycyIsImdldEFsbFJlc3BvbnNlSGVhZGVycyIsIm5ld0hlYWRlcnMiLCJzcGxpdCIsImZvckVhY2giLCJoZWFkZXIiLCJpbmRleCIsImluZGV4T2YiLCJuYW1lIiwic3Vic3RyIiwidmFsdWUiLCJlIiwiX29wZW4iLCJYTUxIdHRwUmVxdWVzdCIsInByb3RvdHlwZSIsIm9wZW4iLCJfc2VuZCIsInNlbmQiLCJhcmdzIiwibWV0aG9kIiwidXJsIiwiX21vbml0b3IiLCJfX3R5cGUiLCJhcHBseSIsIk9iamVjdCIsImFzc2lnbiIsInRpbWVvdXQiLCJsZW5ndGgiLCJwYXJhbXMiLCJlcnIiLCJhZGRFdmVudExpc3RlbmVyIiwiY29udGVudFR5cGUiLCJnZXRSZXNwb25zZUhlYWRlciIsInRvTG93ZXJDYXNlIiwiaWdub3JlcyIsInJlc3BvbnNlVHlwZSIsInJlc3BvbnNlVGV4dCIsInJlc3BvbnNlSnNvbiIsIkpTT04iLCJwYXJzZSIsInJlc3BvbnNlSGVhZGVycyIsInJlc3BvbnNlU3RhdHVzIiwic3RhdHVzIiwicmVzcG9uc2VTdGF0dXNUZXh0Iiwic3RhdHVzVGV4dCIsImdldFBhcmFtcyIsIm9wdGlvbnMiLCJib2R5IiwiZXIiLCJmZXRjaCIsImdldEhlYWRlcnMiLCJyZXNwb25zZSIsImVudHJpZXMiLCJyZXN1bHQiLCJwYWlyIiwiY29uc29sZSIsIndhcm4iLCJtb25pdG9yRmV0Y2giLCJmZXRjaFJlcXVlc3QiLCJfZmV0Y2giLCJ0aGVuIiwiX3RleHQiLCJ0ZXh0IiwianNvbiIsIl9Qcm9taXNlIiwicmVzb2x2ZSIsInJlamVjdCIsImNhbGwiLCJ0eXBlIiwiY2F0Y2giLCJkYXRhIiwibWVzc2FnZSIsIlByb21pc2UiLCJkZWZpbmVQcm9wZXJ0eSIsInNldCIsImdldCIsImtleXMiLCJrZXkiLCJzZXRUaW1lb3V0IiwiZXJyb3IiLCJtb2R1bGUiLCJleHBvcnRzIiwicmVxdWVzdE1vbml0b3IiLCJsaXN0ZW5lciIsImh0dHBJbmZvIiwiRXJyb3IiLCJfaWQiLCJjYW5jZWwiXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7QUFDRCxPO0FDVkE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxrREFBMEMsZ0NBQWdDO0FBQzFFO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsZ0VBQXdELGtCQUFrQjtBQUMxRTtBQUNBLHlEQUFpRCxjQUFjO0FBQy9EOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpREFBeUMsaUNBQWlDO0FBQzFFLHdIQUFnSCxtQkFBbUIsRUFBRTtBQUNySTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLG1DQUEyQiwwQkFBMEIsRUFBRTtBQUN2RCx5Q0FBaUMsZUFBZTtBQUNoRDtBQUNBO0FBQ0E7O0FBRUE7QUFDQSw4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Q0FlQyxPQUFNbEIsQ0FBTixFQUFRO0FBQ1A0QyxZQUFRd0IsS0FBUixDQUFjcEUsQ0FBZDtBQUNEO0FBQ0Y7O0FBRURxRSxPQUFPQyxPQUFQLEdBQWlCQyxjQUFqQjs7QUFFQSxTQUFTQSxjQUFULENBQXlCQyxRQUF6QixFQUFtQztBQUNqQ0EsYUFBV0EsWUFBYTtBQUFBLFdBQVlDLFFBQVo7QUFBQSxHQUF4Qjs7QUFFQSxNQUFJLE9BQU9ELFFBQVAsS0FBb0IsVUFBeEIsRUFBb0M7QUFDbEMsVUFBTSxJQUFJRSxLQUFKLHNDQUFOO0FBQ0Q7O0FBRUQsTUFBSUMsTUFBTXRHLE9BQVY7QUFDQUYsWUFBVXdHLEdBQVYsSUFBaUJILFFBQWpCO0FBQ0EzRixtQkFBa0JDLElBQWxCOztBQUVBLFNBQU87QUFDTDhGLFlBQVEsa0JBQU07QUFDWixhQUFPekcsVUFBVXdHLEdBQVYsQ0FBUDtBQUNEO0FBSEksR0FBUDtBQUtEOztBQUVESixlQUFlMUYsZ0JBQWYsR0FBa0NBLGdCQUFsQyxDIiwiZmlsZSI6InJlcXVlc3QtbW9uaXRvci5qcyIsInNvdXJjZXNDb250ZW50IjpbIihmdW5jdGlvbiB3ZWJwYWNrVW5pdmVyc2FsTW9kdWxlRGVmaW5pdGlvbihyb290LCBmYWN0b3J5KSB7XG5cdGlmKHR5cGVvZiBleHBvcnRzID09PSAnb2JqZWN0JyAmJiB0eXBlb2YgbW9kdWxlID09PSAnb2JqZWN0Jylcblx0XHRtb2R1bGUuZXhwb3J0cyA9IGZhY3RvcnkoKTtcblx0ZWxzZSBpZih0eXBlb2YgZGVmaW5lID09PSAnZnVuY3Rpb24nICYmIGRlZmluZS5hbWQpXG5cdFx0ZGVmaW5lKFtdLCBmYWN0b3J5KTtcblx0ZWxzZSBpZih0eXBlb2YgZXhwb3J0cyA9PT0gJ29iamVjdCcpXG5cdFx0ZXhwb3J0c1tcInJlcXVlc3RNb25pdG9yXCJdID0gZmFjdG9yeSgpO1xuXHRlbHNlXG5cdFx0cm9vdFtcInJlcXVlc3RNb25pdG9yXCJdID0gZmFjdG9yeSgpO1xufSkod2luZG93LCBmdW5jdGlvbigpIHtcbnJldHVybiAiLCIgXHQvLyBUaGUgbW9kdWxlIGNhY2hlXG4gXHR2YXIgaW5zdGFsbGVkTW9kdWxlcyA9IHt9O1xuXG4gXHQvLyBUaGUgcmVxdWlyZSBmdW5jdGlvblxuIFx0ZnVuY3Rpb24gX193ZWJwYWNrX3JlcXVpcmVfXyhtb2R1bGVJZCkge1xuXG4gXHRcdC8vIENoZWNrIGlmIG1vZHVsZSBpcyBpbiBjYWNoZVxuIFx0XHRpZihpbnN0YWxsZWRNb2R1bGVzW21vZHVsZUlkXSkge1xuIFx0XHRcdHJldHVybiBpbnN0YWxsZWRNb2R1bGVzW21vZHVsZUlkXS5leHBvcnRzO1xuIFx0XHR9XG4gXHRcdC8vIENyZWF0ZSBhIG5ldyBtb2R1bGUgKGFuZCBwdXQgaXQgaW50byB0aGUgY2FjaGUpXG4gXHRcdHZhciBtb2R1bGUgPSBpbnN0YWxsZWRNb2R1bGVzW21vZHVsZUlkXSA9IHtcbiBcdFx0XHRpOiBtb2R1bGVJZCxcbiBcdFx0XHRsOiBmYWxzZSxcbiBcdFx0XHRleHBvcnRzOiB7fVxuIFx0XHR9O1xuXG4gXHRcdC8vIEV4ZWN1dGUgdGhlIG1vZHVsZSBmdW5jdGlvblxuIFx0XHRtb2R1bGVzW21vZHVsZUlkXS5jYWxsKG1vZHVsZS5leHBvcnRzLCBtb2R1bGUsIG1vZHVsZS5leHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKTtcblxuIFx0XHQvLyBGbGFnIHRoZSBtb2R1bGUgYXMgbG9hZGVkXG4gXHRcdG1vZHVsZS5sID0gdHJ1ZTtcblxuIFx0XHQvLyBSZXR1cm4gdGhlIGV4cG9ydHMgb2YgdGhlIG1vZHVsZVxuIFx0XHRyZXR1cm4gbW9kdWxlLmV4cG9ydHM7XG4gXHR9XG5cblxuIFx0Ly8gZXhwb3NlIHRoZSBtb2R1bGVzIG9iamVjdCAoX193ZWJwYWNrX21vZHVsZXNfXylcbiBcdF9fd2VicGFja19yZXF1aXJlX18ubSA9IG1vZHVsZXM7XG5cbiBcdC8vIGV4cG9zZSB0aGUgbW9kdWxlIGNhY2hlXG4gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLmMgPSBpbnN0YWxsZWRNb2R1bGVzO1xuXG4gXHQvLyBkZWZpbmUgZ2V0dGVyIGZ1bmN0aW9uIGZvciBoYXJtb255IGV4cG9ydHNcbiBcdF9fd2VicGFja19yZXF1aXJlX18uZCA9IGZ1bmN0aW9uKGV4cG9ydHMsIG5hbWUsIGdldHRlcikge1xuIFx0XHRpZighX193ZWJwYWNrX3JlcXVpcmVfXy5vKGV4cG9ydHMsIG5hbWUpKSB7XG4gXHRcdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIG5hbWUsIHsgZW51bWVyYWJsZTogdHJ1ZSwgZ2V0OiBnZXR0ZXIgfSk7XG4gXHRcdH1cbiBcdH07XG5cbiBcdC8vIGRlZmluZSBfX2VzTW9kdWxlIG9uIGV4cG9ydHNcbiBcdF9fd2VicGFja19yZXF1aXJlX18uciA9IGZ1bmN0aW9uKGV4cG9ydHMpIHtcbiBcdFx0aWYodHlwZW9mIFN5bWJvbCAhPT0gJ3VuZGVmaW5lZCcgJiYgU3ltYm9sLnRvU3RyaW5nVGFnKSB7XG4gXHRcdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFN5bWJvbC50b1N0cmluZ1RhZywgeyB2YWx1ZTogJ01vZHVsZScgfSk7XG4gXHRcdH1cbiBcdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICdfX2VzTW9kdWxlJywgeyB2YWx1ZTogdHJ1ZSB9KTtcbiBcdH07XG5cbiBcdC8vIGNyZWF0ZSBhIGZha2UgbmFtZXNwYWNlIG9iamVjdFxuIFx0Ly8gbW9kZSAmIDE6IHZhbHVlIGlzIGEgbW9kdWxlIGlkLCByZXF1aXJlIGl0XG4gXHQvLyBtb2RlICYgMjogbWVyZ2UgYWxsIHByb3BlcnRpZXMgb2YgdmFsdWUgaW50byB0aGUgbnNcbiBcdC8vIG1vZGUgJiA0OiByZXR1cm4gdmFsdWUgd2hlbiBhbHJlYWR5IG5zIG9iamVjdFxuIFx0Ly8gbW9kZSAmIDh8MTogYmVoYXZlIGxpa2UgcmVxdWlyZVxuIFx0X193ZWJwYWNrX3JlcXVpcmVfXy50ID0gZnVuY3Rpb24odmFsdWUsIG1vZGUpIHtcbiBcdFx0aWYobW9kZSAmIDEpIHZhbHVlID0gX193ZWJwYWNrX3JlcXVpcmVfXyh2YWx1ZSk7XG4gXHRcdGlmKG1vZGUgJiA4KSByZXR1cm4gdmFsdWU7XG4gXHRcdGlmKChtb2RlICYgNCkgJiYgdHlwZW9mIHZhbHVlID09PSAnb2JqZWN0JyAmJiB2YWx1ZSAmJiB2YWx1ZS5fX2VzTW9kdWxlKSByZXR1cm4gdmFsdWU7XG4gXHRcdHZhciBucyA9IE9iamVjdC5jcmVhdGUobnVsbCk7XG4gXHRcdF9fd2VicGFja19yZXF1aXJlX18ucihucyk7XG4gXHRcdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShucywgJ2RlZmF1bHQnLCB7IGVudW1lcmFibGU6IHRydWUsIHZhbHVlOiB2YWx1ZSB9KTtcbiBcdFx0aWYobW9kZSAmIDIgJiYgdHlwZW9mIHZhbHVlICE9ICdzdHJpbmcnKSBmb3IodmFyIGtleSBpbiB2YWx1ZSkgX193ZWJwYWNrX3JlcXVpcmVfXy5kKG5zLCBrZXksIGZ1bmN0aW9uKGtleSkgeyByZXR1cm4gdmFsdWVba2V5XTsgfS5iaW5kKG51bGwsIGtleSkpO1xuIFx0XHRyZXR1cm4gbnM7XG4gXHR9O1xuXG4gXHQvLyBnZXREZWZhdWx0RXhwb3J0IGZ1bmN0aW9uIGZvciBjb21wYXRpYmlsaXR5IHdpdGggbm9uLWhhcm1vbnkgbW9kdWxlc1xuIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5uID0gZnVuY3Rpb24obW9kdWxlKSB7XG4gXHRcdHZhciBnZXR0ZXIgPSBtb2R1bGUgJiYgbW9kdWxlLl9fZXNNb2R1bGUgP1xuIFx0XHRcdGZ1bmN0aW9uIGdldERlZmF1bHQoKSB7IHJldHVybiBtb2R1bGVbJ2RlZmF1bHQnXTsgfSA6XG4gXHRcdFx0ZnVuY3Rpb24gZ2V0TW9kdWxlRXhwb3J0cygpIHsgcmV0dXJuIG1vZHVsZTsgfTtcbiBcdFx0X193ZWJwYWNrX3JlcXVpcmVfXy5kKGdldHRlciwgJ2EnLCBnZXR0ZXIpO1xuIFx0XHRyZXR1cm4gZ2V0dGVyO1xuIFx0fTtcblxuIFx0Ly8gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsXG4gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLm8gPSBmdW5jdGlvbihvYmplY3QsIHByb3BlcnR5KSB7IHJldHVybiBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwob2JqZWN0LCBwcm9wZXJ0eSk7IH07XG5cbiBcdC8vIF9fd2VicGFja19wdWJsaWNfcGF0aF9fXG4gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLnAgPSBcIlwiO1xuXG5cbiBcdC8vIExvYWQgZW50cnkgbW9kdWxlIGFuZCByZXR1cm4gZXhwb3J0c1xuIFx0cmV0dXJuIF9fd2VicGFja19yZXF1aXJlX18oX193ZWJwYWNrX3JlcXVpcmVfXy5zID0gXCIuL3NyYy9pbmRleC5qc1wiKTtcbiIsIi8qKlxuICogXG4gKiBAcGFyYW0geyp9IGxpc3RlbmVyIFxuICogXG5odHRwIEluZm86IHtcbiAgIF9fdHlwZTogXCJmZXRjaFwiLCAgLy8g5L2/55So5bqV5bGC5bqT57G75Z6L77yM5pyJIGZldGNoIOWSjCB4aHJcbiAgIHVybDogXCJcIixcbiAgIG1ldGhvZDogXCJcIixcbiAgIHRpbWVvdXQ6IDAsIC8vIOi2heaXtuaXtumXtFxuICAgcGFyYW1zOiB7fSwgLy8g6K+35rGC5Y+C5pWwXG4gICByZXNwb25zZVN0YXR1czogMjAwLCAgLy8g5aaC5p6c5pivIC0xIO+8jOS7o+ihqOe9kee7nOW8guW4uFxuICAgcmVzcG9uc2VTdGF0dXNUZXh0OiBcIm9rXCIsXG4gICByZXNwb25zZUpzb246IHtcImNvZGVcIjogMH0sXG4gICByZXNwb25zZVRleHQ6IFwie1wiY29kZVwiOiAwfVwiLFxuICAgcmVxdWVzdFRpbWU6IDEwMCwgIOivt+axguaXtumXtO+8jOWNleS9jeS4uiBtc1xufVxuICovXG5cbmNvbnN0IGxpc3RlbmVycyA9IHt9O1xubGV0IGlkID0gMTtcblxuZnVuY3Rpb24gZ2V0SWQgKCkge1xuICByZXR1cm4gaWQrKztcbn1cblxuZnVuY3Rpb24gaGFuZGxlRW5kVGltZShpbmZvKXtcbiAgbGV0IGVuZFRpbWUgPSBuZXcgRGF0ZSAoKS5nZXRUaW1lICgpO1xuICBpbmZvLnJlcXVlc3RUaW1lID0gZW5kVGltZSAtIGluZm8uc3RhcnRUaW1lO1xuICBpbmZvLmVuZFRpbWUgPSBlbmRUaW1lO1xufVxuXG5cbmZ1bmN0aW9uIGhhbmRsZURlZmF1bHRBcGkgKGVtaXQpIHtcbiAgaWYgKHdpbmRvdy5fcmVxdWVzdE1vbml0b3JJc0xvYWQpIHJldHVybiBudWxsO1xuICB3aW5kb3cuX3JlcXVlc3RNb25pdG9ySXNMb2FkID0gdHJ1ZTtcbiAgaGFuZGxlWGhyIChlbWl0KTtcbiAgaGFuZGxlRmV0Y2ggKGVtaXQpO1xuICByZXR1cm4gdHJ1ZTtcbn1cblxuZnVuY3Rpb24gaGFuZGxlSGVhZGVyKHhocikge1xuICB0cnl7XG4gICAgdmFyIGhlYWRlcnMgPSB4aHIuZ2V0QWxsUmVzcG9uc2VIZWFkZXJzKCk7XG4gICAgaWYgKCFoZWFkZXJzKSByZXR1cm47XG4gICAgaWYgKHR5cGVvZiBoZWFkZXJzID09PSAnb2JqZWN0Jykge1xuICAgICAgICByZXR1cm4gaGVhZGVycztcbiAgICB9XG4gICAgdmFyIG5ld0hlYWRlcnMgPSB7fSwgaGVhZGVycyA9IGhlYWRlcnMuc3BsaXQoL1tcXHJcXG5dLykuZm9yRWFjaChmdW5jdGlvbiAoaGVhZGVyKSB7XG4gICAgICAgIHZhciBpbmRleCA9IGhlYWRlci5pbmRleE9mKFwiOlwiKTtcbiAgICAgICAgdmFyIG5hbWUgPSBoZWFkZXIuc3Vic3RyKDAsIGluZGV4KTtcbiAgICAgICAgdmFyIHZhbHVlID0gaGVhZGVyLnN1YnN0cihpbmRleCArIDIpO1xuICAgICAgICBpZiAobmFtZSkge1xuICAgICAgICAgICAgbmV3SGVhZGVyc1tuYW1lXSA9IHZhbHVlO1xuICAgICAgICB9XG5cbiAgICB9KVxuICAgIHJldHVybiBuZXdIZWFkZXJzO1xuICB9Y2F0Y2goZSl7XG4gICAgcmV0dXJuIHt9XG4gIH1cbn1cblxuZnVuY3Rpb24gaGFuZGxlWGhyIChlbWl0KSB7XG4gIGxldCBfb3BlbiA9IFhNTEh0dHBSZXF1ZXN0LnByb3RvdHlwZS5vcGVuO1xuICBsZXQgX3NlbmQgPSBYTUxIdHRwUmVxdWVzdC5wcm90b3R5cGUuc2VuZDtcbiAgWE1MSHR0cFJlcXVlc3QucHJvdG90eXBlLm9wZW4gPSBmdW5jdGlvbiAoLi4uYXJncykge1xuICAgIGNvbnN0IG1ldGhvZCA9IGFyZ3NbMF07XG4gICAgY29uc3QgdXJsID0gYXJnc1sxXTtcbiAgICB0aGlzLl9tb25pdG9yID0ge1xuICAgICAgX190eXBlOiAneGhyJyxcbiAgICB9O1xuICAgIF9vcGVuLmFwcGx5ICh0aGlzLCBhcmdzKTtcbiAgICBPYmplY3QuYXNzaWduICh0aGlzLl9tb25pdG9yLCB7XG4gICAgICBtZXRob2QsXG4gICAgICB1cmwsXG4gICAgfSk7XG4gIH07XG5cbiAgWE1MSHR0cFJlcXVlc3QucHJvdG90eXBlLnNlbmQgPSBmdW5jdGlvbiAoLi4uYXJncykge1xuICAgIF9zZW5kLmFwcGx5ICh0aGlzLCBhcmdzKTtcbiAgICB0aGlzLl9tb25pdG9yLnN0YXJ0VGltZSA9IG5ldyBEYXRlICgpLmdldFRpbWUgKCk7XG4gICAgdGhpcy5fbW9uaXRvci50aW1lb3V0ID0gdGhpcy50aW1lb3V0IHx8IDA7XG4gICAgdHJ5IHtcbiAgICAgIGlmIChhcmdzLmxlbmd0aCA+IDAgJiYgdHlwZW9mIGFyZ3NbMF0gPT09ICdzdHJpbmcnKSB7XG4gICAgICAgIHRoaXMuX21vbml0b3IucGFyYW1zID0gYXJnc1swXTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnIpIHt9XG4gICAgdGhpcy5hZGRFdmVudExpc3RlbmVyIChcbiAgICAgICdsb2FkJyxcbiAgICAgIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgbGV0IGNvbnRlbnRUeXBlID0gdGhpcy5nZXRSZXNwb25zZUhlYWRlciAoXG4gICAgICAgICAgJ0NvbnRlbnQtVHlwZSdcbiAgICAgICAgKTtcbiAgICAgICAgY29udGVudFR5cGUgPSBjb250ZW50VHlwZSB8fCAnJztcbiAgICAgICAgY29udGVudFR5cGUgPSBjb250ZW50VHlwZS50b0xvd2VyQ2FzZSAoKTtcbiAgICAgICAgY29uc3QgaWdub3JlcyA9IFsnYmxvYicsICdhcnJheWJ1ZmZlcicsICdtb3otY2h1bmtlZC1hcnJheWJ1ZmZlcicsIFwibXMtc3RyZWFtXCJdO1xuICAgICAgICBpZih0aGlzLnJlc3BvbnNlVHlwZSAmJiBpZ25vcmVzLmluZGV4T2YodGhpcy5yZXNwb25zZVR5cGUpID4gLTEpe1xuICAgICAgICAgIHJldHVybjsgLy8gaWdub3JlIGJsb2IgdHlwZVxuICAgICAgICB9XG4gICAgICAgIGlmIChjb250ZW50VHlwZS5pbmRleE9mICgnYXBwbGljYXRpb24vanNvbicpICE9PSAtMSkge1xuICAgICAgICAgIHRoaXMuX21vbml0b3IucmVzcG9uc2VUZXh0ID0gdGhpcy5yZXNwb25zZVRleHQ7XG4gICAgICAgICAgdHJ5e1xuICAgICAgICAgICAgdGhpcy5fbW9uaXRvci5yZXNwb25zZUpzb24gPSBKU09OLnBhcnNlICh0aGlzLnJlc3BvbnNlVGV4dCk7XG4gICAgICAgICAgfWNhdGNoKGUpe31cbiAgICAgICAgICBcbiAgICAgICAgfSBlbHNlIGlmIChjb250ZW50VHlwZS5pbmRleE9mICgndGV4dC9wbGFpbicpICE9PSAtMSkge1xuICAgICAgICAgIHRoaXMuX21vbml0b3IucmVzcG9uc2VUZXh0ID0gdGhpcy5yZXNwb25zZVRleHQ7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fbW9uaXRvci5yZXNwb25zZUhlYWRlcnMgPSBoYW5kbGVIZWFkZXIodGhpcyk7XG4gICAgICAgIHRoaXMuX21vbml0b3IucmVzcG9uc2VTdGF0dXMgPSB0aGlzLnN0YXR1cztcbiAgICAgICAgdGhpcy5fbW9uaXRvci5yZXNwb25zZVN0YXR1c1RleHQgPSB0aGlzLnN0YXR1c1RleHQ7XG4gICAgICAgIGVtaXQgKHRoaXMuX21vbml0b3IpO1xuICAgICAgfSxcbiAgICAgIGZhbHNlXG4gICAgKTtcbiAgICB0aGlzLmFkZEV2ZW50TGlzdGVuZXIgKCdlcnJvcicsICgpID0+IHtcbiAgICAgIHRoaXMuX21vbml0b3IucmVzcG9uc2VTdGF0dXNUZXh0ID0gJ1hociBOZXR3b3JrIHJlcXVlc3QgZXhjZXB0aW9uJztcbiAgICAgIHRoaXMuX21vbml0b3IucmVzcG9uc2VTdGF0dXMgPSAtMTtcbiAgICAgIGVtaXQgKHRoaXMuX21vbml0b3IpO1xuICAgIH0pO1xuXG4gICAgdGhpcy5hZGRFdmVudExpc3RlbmVyICgndGltZW91dCcsICgpID0+IHtcbiAgICAgIGVtaXQgKHRoaXMuX21vbml0b3IpO1xuICAgIH0pO1xuXG4gIH07XG59XG5cbmZ1bmN0aW9uIGdldFBhcmFtcyAob3B0aW9ucykge1xuICBsZXQgcGFyYW1zO1xuICB0cnkge1xuICAgIGlmIChvcHRpb25zLmJvZHkgJiYgdHlwZW9mIG9wdGlvbnMuYm9keSA9PT0gJ3N0cmluZycpIHtcbiAgICAgIHBhcmFtcyA9IG9wdGlvbnMuYm9keTtcbiAgICB9XG4gIH0gY2F0Y2ggKGVyKSB7fVxuICByZXR1cm4gcGFyYW1zO1xufVxuXG5mdW5jdGlvbiBoYW5kbGVGZXRjaCAoZW1pdCkge1xuICBpZiAod2luZG93LmZldGNoKSB7XG4gICAgY29uc3QgX1Byb21pc2UgPSB3aW5kb3cuZmV0Y2guUHJvbWlzZSB8fCBQcm9taXNlO1xuICAgIGNvbnN0IF9mZXRjaCA9IHdpbmRvdy5mZXRjaDtcblxuICAgIGZ1bmN0aW9uIGdldEhlYWRlcnMocmVzcG9uc2Upe1xuICAgICAgdHJ5e1xuICAgICAgICBsZXQgaGVhZGVycyA9IHJlc3BvbnNlLmhlYWRlcnMuZW50cmllcygpO1xuICAgICAgICBsZXQgcmVzdWx0ID0ge307XG4gICAgICAgIGZvciAodmFyIHBhaXIgb2YgaGVhZGVycykge1xuICAgICAgICAgIHJlc3VsdFtwYWlyWzBdXSA9IHBhaXJbMV07XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgIH1jYXRjaChlKXtcbiAgICAgICAgY29uc29sZS53YXJuKGUpO1xuICAgICAgICByZXR1cm4ge307XG4gICAgICB9XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gbW9uaXRvckZldGNoICh1cmwsIG9wdGlvbnMgPSB7fSkge1xuICAgICAgY29uc3QgcGFyYW1zID0gZ2V0UGFyYW1zIChvcHRpb25zKTtcblxuICAgICAgY29uc3QgX21vbml0b3IgPSB7XG4gICAgICAgIF9fdHlwZTogJ2ZldGNoJyxcbiAgICAgICAgdXJsLFxuICAgICAgICBtZXRob2Q6IG9wdGlvbnMubWV0aG9kIHx8ICdHRVQnLFxuICAgICAgICBwYXJhbXMsXG4gICAgICAgIHN0YXJ0VGltZTogbmV3IERhdGUgKCkuZ2V0VGltZSAoKSxcbiAgICAgICAgdGltZW91dDogb3B0aW9ucy50aW1lb3V0IHx8IDBcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IGZldGNoUmVxdWVzdCA9IFxuICAgICAgICAvLyBfUHJvbWlzZVxuICAgICAgICAvLyAucmFjZSAoW1xuICAgICAgICAgIFxuICAgICAgICAvLyAgIG5ldyBfUHJvbWlzZSAoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAvLyAgICAgc2V0VGltZW91dCAoKCkgPT4ge1xuICAgICAgICAvLyAgICAgICBsZXQgZXJyID0gbmV3IEVycm9yICgn5YmN56uvZmV0Y2ggTmV0d29yayByZXF1ZXN0IHRpbWVvdXQ6ICcgKyBvcHRpb25zLnRpbWVvdXQpO1xuICAgICAgICAvLyAgICAgICBlcnIuc3RhdHVzID0gNTA0O1xuICAgICAgICAvLyAgICAgICByZWplY3QgKGVycik7XG4gICAgICAgIC8vICAgICB9LCB0aW1lb3V0KTtcbiAgICAgICAgLy8gICB9KSxcbiAgICAgICAgLy8gXSlcbiAgICAgICAgX2ZldGNoICh1cmwsIG9wdGlvbnMpXG4gICAgICAgIC50aGVuIChyZXNwb25zZSA9PiB7XG4gICAgICAgICAgbGV0IF90ZXh0ID0gcmVzcG9uc2UudGV4dDtcbiAgICAgICAgICBfbW9uaXRvci5yZXNwb25zZVN0YXR1cyA9IHJlc3BvbnNlLnN0YXR1cztcbiAgICAgICAgICBfbW9uaXRvci5yZXNwb25zZUhlYWRlcnMgPSBnZXRIZWFkZXJzKHJlc3BvbnNlKVxuICAgICAgICAgIF9tb25pdG9yLnJlc3BvbnNlU3RhdHVzVGV4dCA9IHJlc3BvbnNlLnN0YXR1c1RleHQ7XG4gICAgICAgICAgcmVzcG9uc2UuanNvbiA9ICgpID0+IHtcbiAgICAgICAgICAgIHJldHVybiBuZXcgX1Byb21pc2UgKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgICAgX3RleHRcbiAgICAgICAgICAgICAgICAuY2FsbCAocmVzcG9uc2UpXG4gICAgICAgICAgICAgICAgLnRoZW4gKHRleHQgPT4ge1xuICAgICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgbGV0IGpzb24gPSBKU09OLnBhcnNlICh0ZXh0KTtcbiAgICAgICAgICAgICAgICAgICAgX21vbml0b3IucmVzcG9uc2VUZXh0ID0gdGV4dDtcbiAgICAgICAgICAgICAgICAgICAgX21vbml0b3IucmVzcG9uc2VKc29uID0ganNvbjtcbiAgICAgICAgICAgICAgICAgICAgZW1pdCAoX21vbml0b3IpO1xuICAgICAgICAgICAgICAgICAgICByZXNvbHZlIChqc29uKTtcbiAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgICAgICAgZS50eXBlID0gJ2ludmFsaWQtanNvbic7XG4gICAgICAgICAgICAgICAgICAgIF9tb25pdG9yLnJlc3BvbnNlVGV4dCA9IHRleHQ7XG4gICAgICAgICAgICAgICAgICAgIGVtaXQoX21vbml0b3IpO1xuICAgICAgICAgICAgICAgICAgICByZWplY3QgKGUpO1xuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgLmNhdGNoIChlcnIgPT4ge1xuICAgICAgICAgICAgICAgICAgcmVqZWN0IChlcnIpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfTtcblxuICAgICAgICAgIHJlc3BvbnNlLnRleHQgPSAoKSA9PiB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IF9Qcm9taXNlICgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICAgIF90ZXh0XG4gICAgICAgICAgICAgICAgLmNhbGwgKHJlc3BvbnNlKVxuICAgICAgICAgICAgICAgIC50aGVuICh0ZXh0ID0+IHtcbiAgICAgICAgICAgICAgICAgIF9tb25pdG9yLnJlc3BvbnNlVGV4dCA9IHRleHQ7XG4gICAgICAgICAgICAgICAgICBlbWl0IChfbW9uaXRvcik7XG4gICAgICAgICAgICAgICAgICByZXNvbHZlICh0ZXh0KTtcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgIC5jYXRjaCAoZXJyID0+IHtcbiAgICAgICAgICAgICAgICAgIHJlamVjdCAoZXJyKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH07XG5cbiAgICAgICAgICByZXR1cm4gcmVzcG9uc2U7XG4gICAgICAgIH0pO1xuXG4gICAgICByZXR1cm4gbmV3IF9Qcm9taXNlICgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgIGZldGNoUmVxdWVzdFxuICAgICAgICAgIC50aGVuIChkYXRhID0+IHtcbiAgICAgICAgICAgIHJlc29sdmUgKGRhdGEpO1xuICAgICAgICAgIH0pXG4gICAgICAgICAgLmNhdGNoIChlcnIgPT4ge1xuICAgICAgICAgICAgX21vbml0b3IucmVzcG9uc2VTdGF0dXMgPSBlcnIuc3RhdHVzIHx8IC0xO1xuICAgICAgICAgICAgX21vbml0b3IucmVzcG9uc2VUZXh0ID0gZXJyLm1lc3NhZ2UgfHwgJ0ZldGNoIE5ldHdvcmsgcmVxdWVzdCBleGNlcHRpb24nO1xuICAgICAgICAgICAgZW1pdCAoX21vbml0b3IpO1xuICAgICAgICAgICAgcmVqZWN0IChlcnIpO1xuICAgICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gZmV0Y2hSZXF1ZXN0O1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgbW9uaXRvckZldGNoLlByb21pc2UgPSBfUHJvbWlzZTtcblxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSAobW9uaXRvckZldGNoLCAnUHJvbWlzZScsIHtcbiAgICAgIHNldCAodmFsdWUpIHtcbiAgICAgICAgLy8gbW9uaXRvckZldGNoLlByb21pc2UgPSB2YWx1ZTtcbiAgICAgICAgX2ZldGNoLlByb21pc2UgPSB2YWx1ZTtcbiAgICAgIH0sXG4gICAgICBnZXQgKCkge1xuICAgICAgICByZXR1cm4gX2ZldGNoLlByb21pc2U7XG4gICAgICB9LFxuICAgIH0pO1xuXG4gICAgd2luZG93LmZldGNoID0gbW9uaXRvckZldGNoO1xuICB9XG59XG5cbmZ1bmN0aW9uIGVtaXQgKGluZm8pIHtcbiAgaGFuZGxlRW5kVGltZShpbmZvKVxuICB0cnl7XG4gICAgT2JqZWN0LmtleXMgKGluZm8pLmZvckVhY2ggKGtleSA9PiB7XG4gICAgICBpZiAodHlwZW9mIGluZm9ba2V5XSA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgZGVsZXRlIGluZm9ba2V5XTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICBPYmplY3Qua2V5cyAobGlzdGVuZXJzKS5mb3JFYWNoIChrZXkgPT4ge1xuICAgICAgc2V0VGltZW91dCgoKT0+IHtcbiAgICAgICAgdHJ5e1xuICAgICAgICAgIGxpc3RlbmVyc1trZXldIChpbmZvKVxuICAgICAgICB9Y2F0Y2goZXJyKXtcbiAgICAgICAgICBjb25zb2xlLmVycm9yKGVycilcbiAgICAgICAgfVxuICAgICAgfSlcbiAgICB9KTtcbiAgfWNhdGNoKGUpe1xuICAgIGNvbnNvbGUuZXJyb3IoZSlcbiAgfVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHJlcXVlc3RNb25pdG9yO1xuXG5mdW5jdGlvbiByZXF1ZXN0TW9uaXRvciAobGlzdGVuZXIpIHtcbiAgbGlzdGVuZXIgPSBsaXN0ZW5lciB8fCAoaHR0cEluZm8gPT4gaHR0cEluZm8pO1xuXG4gIGlmICh0eXBlb2YgbGlzdGVuZXIgIT09ICdmdW5jdGlvbicpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IgKGBUaGUgbGlzdGVuZXIgVHlwZSBtdXN0IGJlIGZ1bmN0aW9uYCk7XG4gIH1cblxuICBsZXQgX2lkID0gZ2V0SWQgKCk7XG4gIGxpc3RlbmVyc1tfaWRdID0gbGlzdGVuZXI7XG4gIGhhbmRsZURlZmF1bHRBcGkgKGVtaXQpO1xuXG4gIHJldHVybiB7XG4gICAgY2FuY2VsOiAoKSA9PiB7XG4gICAgICBkZWxldGUgbGlzdGVuZXJzW19pZF07XG4gICAgfSxcbiAgfTtcbn1cblxucmVxdWVzdE1vbml0b3IuaGFuZGxlRGVmYXVsdEFwaSA9IGhhbmRsZURlZmF1bHRBcGk7XG4iXSwic291cmNlUm9vdCI6IiJ9