metaapi.cloud-sdk
Version:
SDK for MetaApi, a professional cloud forex API which includes MetaTrader REST API and MetaTrader websocket API. Supports both MetaTrader 5 (MT5) and MetaTrader 4 (MT4). CopyFactory copy trading API included. (https://metaapi.cloud)
239 lines (238 loc) • 26.7 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "default", {
enumerable: true,
get: function() {
return _default;
}
});
const _randomstring = /*#__PURE__*/ _interop_require_default(require("randomstring"));
const _longrunningasyncprocess = /*#__PURE__*/ _interop_require_wildcard(require("../long-running-async-process"));
const _stickySocketConnection = /*#__PURE__*/ _interop_require_default(require("./stickySocketConnection"));
const _errorHandler = /*#__PURE__*/ _interop_require_wildcard(require("../../clients/errorHandler"));
const _commonutils = require("./common.utils");
const _time = require("../../helpers/convert/time");
const _eventEmitter = /*#__PURE__*/ _interop_require_default(require("../../tools/eventEmitter"));
const _logger = /*#__PURE__*/ _interop_require_default(require("../../logger"));
const _queue = /*#__PURE__*/ _interop_require_default(require("../../tools/queue"));
function _define_property(obj, key, value) {
if (key in obj) {
Object.defineProperty(obj, key, {
value: value,
enumerable: true,
configurable: true,
writable: true
});
} else {
obj[key] = value;
}
return obj;
}
function _interop_require_default(obj) {
return obj && obj.__esModule ? obj : {
default: obj
};
}
function _getRequireWildcardCache(nodeInterop) {
if (typeof WeakMap !== "function") return null;
var cacheBabelInterop = new WeakMap();
var cacheNodeInterop = new WeakMap();
return (_getRequireWildcardCache = function(nodeInterop) {
return nodeInterop ? cacheNodeInterop : cacheBabelInterop;
})(nodeInterop);
}
function _interop_require_wildcard(obj, nodeInterop) {
if (!nodeInterop && obj && obj.__esModule) {
return obj;
}
if (obj === null || typeof obj !== "object" && typeof obj !== "function") {
return {
default: obj
};
}
var cache = _getRequireWildcardCache(nodeInterop);
if (cache && cache.has(obj)) {
return cache.get(obj);
}
var newObj = {
__proto__: null
};
var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor;
for(var key in obj){
if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) {
var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null;
if (desc && (desc.get || desc.set)) {
Object.defineProperty(newObj, key, desc);
} else {
newObj[key] = obj[key];
}
}
}
newObj.default = obj;
if (cache) {
cache.set(obj, newObj);
}
return newObj;
}
/**
* Client sticky socket
*/ let ClientStickySocket = class ClientStickySocket extends _eventEmitter.default {
/**
* Returns socket ID
* @returns socket ID
*/ get id() {
return this._id;
}
/**
* Returns current native socket
* @returns socket.io socket
* @internal intended for tests only
*/ get socket() {
var _this__pool_getProcess;
return (_this__pool_getProcess = this._pool.getProcess("connection")) === null || _this__pool_getProcess === void 0 ? void 0 : _this__pool_getProcess.socket;
}
/**
* Returns current transport name, using socket.io internals
* @returns transport name, e.g. "websocket"
* @internal intended for tests only
*/ get transportName() {
var _this__pool_getProcess;
return (_this__pool_getProcess = this._pool.getProcess("connection")) === null || _this__pool_getProcess === void 0 ? void 0 : _this__pool_getProcess.transportName;
}
/**
* Returns first present packet index in last emit history
* @returns first history index
* @internal intended for tests only
*/ get firstHistoryIndex() {
var _this__pool_getProcess;
return (_this__pool_getProcess = this._pool.getProcess("connection")) === null || _this__pool_getProcess === void 0 ? void 0 : _this__pool_getProcess.firstHistoryIndex;
}
/**
* Returns whether socket connected
* @returns is connected
*/ get connected() {
return this._connected;
}
/**
* @inheritdoc
* @remarks Socket events `ClientStickySockets.INTERNAL_EVENTS` cannot be subscribed to
* @throws `ValidationError` if attempting to subscribe to an internal event
*/ on(event, callback) {
if (ClientStickySocket.INTERNAL_EVENTS.includes(event)) {
throw new _errorHandler.ValidationError("Cannot subscribe to an internal event");
}
super.on(event, callback);
}
/**
* Emits a data event. All events are buffered if no connection
* @param event The event that we're emitting
* @param args Optional arguments to send with the event
*/ send(event, ...args) {
var _this__pool_getProcess;
(_this__pool_getProcess = this._pool.getProcess("connection")) === null || _this__pool_getProcess === void 0 ? void 0 : _this__pool_getProcess.send(event, ...args);
}
/**
* Disconnects socket
* @param err error if disconnecting with error
* @returns promise resolving when disconnected
*/ async disconnect(err) {
clearTimeout(this._stickyConnectionWaitTimeout);
let wasStopped = this._stopped;
this._stopped = true;
await this._pool.stop();
if (!wasStopped) {
this._connected = false;
this.emit("disconnect", err);
}
}
/**
* Destroys underlying socket, using socket.io internals. The socket must have `websocket` transport
* @param err optional error
* @internal intended for tests only, e.g. to test connection loss
*/ destroyInternalSocket(err) {
(0, _commonutils.destroyInternalClientSocket)(this._pool.getProcess("connection").socket, err);
}
/**
* Removes expired emit history
* @internal intended for tests only
*/ removeExpiredEmitHistory() {
var _this__pool_getProcess;
(_this__pool_getProcess = this._pool.getProcess("connection")) === null || _this__pool_getProcess === void 0 ? void 0 : _this__pool_getProcess.removeExpiredEmitHistory();
}
/**
* Constructs instance
* @param url URL
* @param options options
*/ constructor(url, options){
super();
_define_property(this, "_logger", _logger.default.getLogger("ClientStickySocket"));
_define_property(this, "_pool", void 0);
_define_property(this, "_stickyConnectionWaitTimeout", void 0);
_define_property(this, "_id", _randomstring.default.generate(16));
_define_property(this, "_label", void 0);
_define_property(this, "_stopped", false);
_define_property(this, "_connected", false);
this._label = `${(options === null || options === void 0 ? void 0 : options.label) || "connection"}:${this._id}`;
var _options_stickyConnectionTtlInSeconds;
const stickyConnectionTtlInMs = 1000 * ((_options_stickyConnectionTtlInSeconds = options === null || options === void 0 ? void 0 : options.stickyConnectionTtlInSeconds) !== null && _options_stickyConnectionTtlInSeconds !== void 0 ? _options_stickyConnectionTtlInSeconds : 10);
let internalEvents = new _eventEmitter.default();
internalEvents.once("connect", ()=>{
this._connected = true;
this.emit("connect");
});
internalEvents.on("connect", ()=>clearTimeout(this._stickyConnectionWaitTimeout));
internalEvents.on("fail", (err)=>{
if (options === null || options === void 0 ? void 0 : options.useNativeSocketIoServer) {
this.disconnect(err);
return;
}
if (!this._stopped) {
this._stickyConnectionWaitTimeout = setTimeout(()=>{
this._logger.warn(`${this._label}: failed to restore sticky connection`);
this.disconnect(err);
}, stickyConnectionTtlInMs);
}
});
this._pool = new _longrunningasyncprocess.RootPool(_stickySocketConnection.default, {
dependencies: [
this,
internalEvents
],
label: `clientStickySocket:${this._label}`
});
var _options_emitHistoryTtlInSeconds, _options_reconnectionDelayInMs, _options_reconnectionDelayMaxInMs, _options_reconnectionRandomizationFactor;
this._pool.scheduleProcess("connection", {
args: [
url,
this._id,
{
startCount: 0,
emitHistory: new _queue.default(),
lastSentIndex: -1,
lastReceivedIndex: -1
},
{
label: this._label,
connection: options === null || options === void 0 ? void 0 : options.connection,
useNativeSocketIoServer: options === null || options === void 0 ? void 0 : options.useNativeSocketIoServer,
emitHistoryTtlInSeconds: (_options_emitHistoryTtlInSeconds = options === null || options === void 0 ? void 0 : options.emitHistoryTtlInSeconds) !== null && _options_emitHistoryTtlInSeconds !== void 0 ? _options_emitHistoryTtlInSeconds : (0, _time.msToSeconds)(stickyConnectionTtlInMs)
}
],
failoverThrottleDelay: {
mode: "exponential",
resetDelayInMs: 0,
minDelayInMs: (_options_reconnectionDelayInMs = options === null || options === void 0 ? void 0 : options.reconnectionDelayInMs) !== null && _options_reconnectionDelayInMs !== void 0 ? _options_reconnectionDelayInMs : 1000,
maxDelayInMs: (_options_reconnectionDelayMaxInMs = options === null || options === void 0 ? void 0 : options.reconnectionDelayMaxInMs) !== null && _options_reconnectionDelayMaxInMs !== void 0 ? _options_reconnectionDelayMaxInMs : 10000,
randomizationFactor: (_options_reconnectionRandomizationFactor = options === null || options === void 0 ? void 0 : options.reconnectionRandomizationFactor) !== null && _options_reconnectionRandomizationFactor !== void 0 ? _options_reconnectionRandomizationFactor : 0.5
}
});
}
};
(function(ClientStickySocket) {
/** Connection events */ ClientStickySocket.CONNECTION_EVENTS = _stickySocketConnection.default.CONNECTION_EVENTS;
/** Internal events */ ClientStickySocket.INTERNAL_EVENTS = _stickySocketConnection.default.INTERNAL_EVENTS;
})(ClientStickySocket || (ClientStickySocket = {}));
const _default = ClientStickySocket;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIjxhbm9uPiJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgcmFuZG9tc3RyaW5nIGZyb20gJ3JhbmRvbXN0cmluZyc7XG5pbXBvcnQgKiBhcyBscmFwIGZyb20gJy4uL2xvbmctcnVubmluZy1hc3luYy1wcm9jZXNzJztcbmltcG9ydCBTdGlja3lTb2NrZXRDb25uZWN0aW9uIGZyb20gJy4vc3RpY2t5U29ja2V0Q29ubmVjdGlvbic7XG5pbXBvcnQgKiBhcyBlcnJvcnMgZnJvbSAnLi4vLi4vY2xpZW50cy9lcnJvckhhbmRsZXInO1xuaW1wb3J0IHtkZXN0cm95SW50ZXJuYWxDbGllbnRTb2NrZXR9IGZyb20gJy4vY29tbW9uLnV0aWxzJztcbmltcG9ydCB7bXNUb1NlY29uZHN9IGZyb20gJy4uLy4uL2hlbHBlcnMvY29udmVydC90aW1lJztcbmltcG9ydCBFdmVudEVtaXR0ZXIgZnJvbSAnLi4vLi4vdG9vbHMvZXZlbnRFbWl0dGVyJztcbmltcG9ydCBMb2dnZXJNYW5hZ2VyIGZyb20gJy4uLy4uL2xvZ2dlcic7XG5pbXBvcnQgUXVldWUgZnJvbSAnLi4vLi4vdG9vbHMvcXVldWUnO1xuXG4vKipcbiAqIENsaWVudCBzdGlja3kgc29ja2V0XG4gKi9cbmNsYXNzIENsaWVudFN0aWNreVNvY2tldCBleHRlbmRzIEV2ZW50RW1pdHRlcjxDbGllbnRTdGlja3lTb2NrZXQuRXZlbnRzPiB7XG5cbiAgcHJpdmF0ZSBfbG9nZ2VyID0gTG9nZ2VyTWFuYWdlci5nZXRMb2dnZXIoJ0NsaWVudFN0aWNreVNvY2tldCcpO1xuICBwcml2YXRlIF9wb29sOiBscmFwLlJvb3RQb29sPFN0aWNreVNvY2tldENvbm5lY3Rpb24+O1xuICBwcml2YXRlIF9zdGlja3lDb25uZWN0aW9uV2FpdFRpbWVvdXQ/OiBOb2RlSlMuVGltZW91dDtcbiAgcHJpdmF0ZSBfaWQgPSByYW5kb21zdHJpbmcuZ2VuZXJhdGUoMTYpO1xuICBwcml2YXRlIF9sYWJlbDogc3RyaW5nO1xuICBwcml2YXRlIF9zdG9wcGVkID0gZmFsc2U7XG4gIHByaXZhdGUgX2Nvbm5lY3RlZCA9IGZhbHNlO1xuXG4gIC8qKlxuICAgKiBDb25zdHJ1Y3RzIGluc3RhbmNlXG4gICAqIEBwYXJhbSB1cmwgVVJMXG4gICAqIEBwYXJhbSBvcHRpb25zIG9wdGlvbnNcbiAgICovXG4gIGNvbnN0cnVjdG9yKHVybDogc3RyaW5nLCBvcHRpb25zPzogQ2xpZW50U3RpY2t5U29ja2V0Lk9wdGlvbnMpIHtcbiAgICBzdXBlcigpO1xuICAgIHRoaXMuX2xhYmVsID0gYCR7b3B0aW9ucz8ubGFiZWwgfHwgJ2Nvbm5lY3Rpb24nfToke3RoaXMuX2lkfWA7XG4gICAgXG4gICAgY29uc3Qgc3RpY2t5Q29ubmVjdGlvblR0bEluTXMgPSAxMDAwICogKG9wdGlvbnM/LnN0aWNreUNvbm5lY3Rpb25UdGxJblNlY29uZHMgPz8gMTApO1xuICAgIGxldCBpbnRlcm5hbEV2ZW50cyA9IG5ldyBFdmVudEVtaXR0ZXI8U3RpY2t5U29ja2V0Q29ubmVjdGlvbi5TaGFyZWRFdmVudHM+KCk7XG4gICAgaW50ZXJuYWxFdmVudHMub25jZSgnY29ubmVjdCcsICgpID0+IHtcbiAgICAgIHRoaXMuX2Nvbm5lY3RlZCA9IHRydWU7XG4gICAgICB0aGlzLmVtaXQoJ2Nvbm5lY3QnKTtcbiAgICB9KTtcbiAgICBpbnRlcm5hbEV2ZW50cy5vbignY29ubmVjdCcsICgpID0+IGNsZWFyVGltZW91dCh0aGlzLl9zdGlja3lDb25uZWN0aW9uV2FpdFRpbWVvdXQpKTtcbiAgICBpbnRlcm5hbEV2ZW50cy5vbignZmFpbCcsIGVyciA9PiB7XG4gICAgICBpZiAob3B0aW9ucz8udXNlTmF0aXZlU29ja2V0SW9TZXJ2ZXIpIHtcbiAgICAgICAgdGhpcy5kaXNjb25uZWN0KGVycik7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGlmICghdGhpcy5fc3RvcHBlZCkge1xuICAgICAgICB0aGlzLl9zdGlja3lDb25uZWN0aW9uV2FpdFRpbWVvdXQgPSBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICB0aGlzLl9sb2dnZXIud2FybihgJHt0aGlzLl9sYWJlbH06IGZhaWxlZCB0byByZXN0b3JlIHN0aWNreSBjb25uZWN0aW9uYCk7XG4gICAgICAgICAgdGhpcy5kaXNjb25uZWN0KGVycik7XG4gICAgICAgIH0sIHN0aWNreUNvbm5lY3Rpb25UdGxJbk1zKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICBcbiAgICB0aGlzLl9wb29sID0gbmV3IGxyYXAuUm9vdFBvb2woU3RpY2t5U29ja2V0Q29ubmVjdGlvbiwge1xuICAgICAgZGVwZW5kZW5jaWVzOiBbdGhpcywgaW50ZXJuYWxFdmVudHNdLFxuICAgICAgbGFiZWw6IGBjbGllbnRTdGlja3lTb2NrZXQ6JHt0aGlzLl9sYWJlbH1gLFxuICAgIH0pO1xuICAgIHRoaXMuX3Bvb2wuc2NoZWR1bGVQcm9jZXNzKCdjb25uZWN0aW9uJywge1xuICAgICAgYXJnczogW1xuICAgICAgICB1cmwsIHRoaXMuX2lkLFxuICAgICAgICB7XG4gICAgICAgICAgc3RhcnRDb3VudDogMCxcbiAgICAgICAgICBlbWl0SGlzdG9yeTogbmV3IFF1ZXVlKCksXG4gICAgICAgICAgbGFzdFNlbnRJbmRleDogLTEsXG4gICAgICAgICAgbGFzdFJlY2VpdmVkSW5kZXg6IC0xXG4gICAgICAgIH0sXG4gICAgICAgIHtcbiAgICAgICAgICBsYWJlbDogdGhpcy5fbGFiZWwsXG4gICAgICAgICAgY29ubmVjdGlvbjogb3B0aW9ucz8uY29ubmVjdGlvbixcbiAgICAgICAgICB1c2VOYXRpdmVTb2NrZXRJb1NlcnZlcjogb3B0aW9ucz8udXNlTmF0aXZlU29ja2V0SW9TZXJ2ZXIsXG4gICAgICAgICAgZW1pdEhpc3RvcnlUdGxJblNlY29uZHM6IG9wdGlvbnM/LmVtaXRIaXN0b3J5VHRsSW5TZWNvbmRzID8/IG1zVG9TZWNvbmRzKHN0aWNreUNvbm5lY3Rpb25UdGxJbk1zKVxuICAgICAgICB9XG4gICAgICBdLFxuICAgICAgZmFpbG92ZXJUaHJvdHRsZURlbGF5OiB7XG4gICAgICAgIG1vZGU6ICdleHBvbmVudGlhbCcsXG4gICAgICAgIHJlc2V0RGVsYXlJbk1zOiAwLFxuICAgICAgICBtaW5EZWxheUluTXM6IG9wdGlvbnM/LnJlY29ubmVjdGlvbkRlbGF5SW5NcyA/PyAxMDAwLFxuICAgICAgICBtYXhEZWxheUluTXM6IG9wdGlvbnM/LnJlY29ubmVjdGlvbkRlbGF5TWF4SW5NcyA/PyAxMDAwMCxcbiAgICAgICAgcmFuZG9taXphdGlvbkZhY3Rvcjogb3B0aW9ucz8ucmVjb25uZWN0aW9uUmFuZG9taXphdGlvbkZhY3RvciA/PyAwLjVcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHNvY2tldCBJRFxuICAgKiBAcmV0dXJucyBzb2NrZXQgSURcbiAgICovXG4gIGdldCBpZCgpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLl9pZDtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIGN1cnJlbnQgbmF0aXZlIHNvY2tldFxuICAgKiBAcmV0dXJucyBzb2NrZXQuaW8gc29ja2V0XG4gICAqIEBpbnRlcm5hbCBpbnRlbmRlZCBmb3IgdGVzdHMgb25seVxuICAgKi9cbiAgZ2V0IHNvY2tldCgpOiBTb2NrZXRJT0NsaWVudC5Tb2NrZXQge1xuICAgIHJldHVybiB0aGlzLl9wb29sLmdldFByb2Nlc3MoJ2Nvbm5lY3Rpb24nKT8uc29ja2V0O1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgY3VycmVudCB0cmFuc3BvcnQgbmFtZSwgdXNpbmcgc29ja2V0LmlvIGludGVybmFsc1xuICAgKiBAcmV0dXJucyB0cmFuc3BvcnQgbmFtZSwgZS5nLiBcIndlYnNvY2tldFwiXG4gICAqIEBpbnRlcm5hbCBpbnRlbmRlZCBmb3IgdGVzdHMgb25seVxuICAgKi9cbiAgZ2V0IHRyYW5zcG9ydE5hbWUoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gdGhpcy5fcG9vbC5nZXRQcm9jZXNzKCdjb25uZWN0aW9uJyk/LnRyYW5zcG9ydE5hbWU7XG4gIH1cbiAgXG4gIC8qKlxuICAgKiBSZXR1cm5zIGZpcnN0IHByZXNlbnQgcGFja2V0IGluZGV4IGluIGxhc3QgZW1pdCBoaXN0b3J5XG4gICAqIEByZXR1cm5zIGZpcnN0IGhpc3RvcnkgaW5kZXhcbiAgICogQGludGVybmFsIGludGVuZGVkIGZvciB0ZXN0cyBvbmx5XG4gICAqL1xuICBnZXQgZmlyc3RIaXN0b3J5SW5kZXgoKTogbnVtYmVyIHwgdW5kZWZpbmVkIHtcbiAgICByZXR1cm4gdGhpcy5fcG9vbC5nZXRQcm9jZXNzKCdjb25uZWN0aW9uJyk/LmZpcnN0SGlzdG9yeUluZGV4O1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgd2hldGhlciBzb2NrZXQgY29ubmVjdGVkXG4gICAqIEByZXR1cm5zIGlzIGNvbm5lY3RlZFxuICAgKi9cbiAgZ2V0IGNvbm5lY3RlZCgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5fY29ubmVjdGVkO1xuICB9XG5cbiAgLyoqXG4gICAqIEBpbmhlcml0ZG9jXG4gICAqIEByZW1hcmtzIFNvY2tldCBldmVudHMgYENsaWVudFN0aWNreVNvY2tldHMuSU5URVJOQUxfRVZFTlRTYCBjYW5ub3QgYmUgc3Vic2NyaWJlZCB0b1xuICAgKiBAdGhyb3dzIGBWYWxpZGF0aW9uRXJyb3JgIGlmIGF0dGVtcHRpbmcgdG8gc3Vic2NyaWJlIHRvIGFuIGludGVybmFsIGV2ZW50XG4gICAqL1xuICBvbjxVIGV4dGVuZHMgRXZlbnRFbWl0dGVyLkV2ZW50PENsaWVudFN0aWNreVNvY2tldC5FdmVudHM+PihldmVudDogVSwgY2FsbGJhY2s6IENsaWVudFN0aWNreVNvY2tldC5FdmVudHNbVV0pIHtcbiAgICBpZiAoQ2xpZW50U3RpY2t5U29ja2V0LklOVEVSTkFMX0VWRU5UUy5pbmNsdWRlcyhldmVudCkpIHtcbiAgICAgIHRocm93IG5ldyBlcnJvcnMuVmFsaWRhdGlvbkVycm9yKCdDYW5ub3Qgc3Vic2NyaWJlIHRvIGFuIGludGVybmFsIGV2ZW50Jyk7XG4gICAgfVxuICAgIHN1cGVyLm9uKGV2ZW50LCBjYWxsYmFjayk7XG4gIH1cblxuICAvKipcbiAgICogRW1pdHMgYSBkYXRhIGV2ZW50LiBBbGwgZXZlbnRzIGFyZSBidWZmZXJlZCBpZiBubyBjb25uZWN0aW9uXG4gICAqIEBwYXJhbSBldmVudCBUaGUgZXZlbnQgdGhhdCB3ZSdyZSBlbWl0dGluZ1xuICAgKiBAcGFyYW0gYXJncyBPcHRpb25hbCBhcmd1bWVudHMgdG8gc2VuZCB3aXRoIHRoZSBldmVudFxuICAgKi9cbiAgc2VuZChldmVudDogc3RyaW5nLCAuLi5hcmdzOiBhbnlbXSkge1xuICAgIHRoaXMuX3Bvb2wuZ2V0UHJvY2VzcygnY29ubmVjdGlvbicpPy5zZW5kKGV2ZW50LCAuLi5hcmdzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBEaXNjb25uZWN0cyBzb2NrZXRcbiAgICogQHBhcmFtIGVyciBlcnJvciBpZiBkaXNjb25uZWN0aW5nIHdpdGggZXJyb3JcbiAgICogQHJldHVybnMgcHJvbWlzZSByZXNvbHZpbmcgd2hlbiBkaXNjb25uZWN0ZWRcbiAgICovXG4gIGFzeW5jIGRpc2Nvbm5lY3QoZXJyPzogRXJyb3IpIHtcbiAgICBjbGVhclRpbWVvdXQodGhpcy5fc3RpY2t5Q29ubmVjdGlvbldhaXRUaW1lb3V0KTtcbiAgICBsZXQgd2FzU3RvcHBlZCA9IHRoaXMuX3N0b3BwZWQ7XG4gICAgdGhpcy5fc3RvcHBlZCA9IHRydWU7XG4gICAgYXdhaXQgdGhpcy5fcG9vbC5zdG9wKCk7XG4gICAgaWYgKCF3YXNTdG9wcGVkKSB7XG4gICAgICB0aGlzLl9jb25uZWN0ZWQgPSBmYWxzZTtcbiAgICAgIHRoaXMuZW1pdCgnZGlzY29ubmVjdCcsIGVycik7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIERlc3Ryb3lzIHVuZGVybHlpbmcgc29ja2V0LCB1c2luZyBzb2NrZXQuaW8gaW50ZXJuYWxzLiBUaGUgc29ja2V0IG11c3QgaGF2ZSBgd2Vic29ja2V0YCB0cmFuc3BvcnRcbiAgICogQHBhcmFtIGVyciBvcHRpb25hbCBlcnJvclxuICAgKiBAaW50ZXJuYWwgaW50ZW5kZWQgZm9yIHRlc3RzIG9ubHksIGUuZy4gdG8gdGVzdCBjb25uZWN0aW9uIGxvc3NcbiAgICovXG4gIGRlc3Ryb3lJbnRlcm5hbFNvY2tldChlcnI/OiBFcnJvcikge1xuICAgIGRlc3Ryb3lJbnRlcm5hbENsaWVudFNvY2tldCh0aGlzLl9wb29sLmdldFByb2Nlc3MoJ2Nvbm5lY3Rpb24nKS5zb2NrZXQsIGVycik7XG4gIH1cblxuICAvKipcbiAgICogUmVtb3ZlcyBleHBpcmVkIGVtaXQgaGlzdG9yeVxuICAgKiBAaW50ZXJuYWwgaW50ZW5kZWQgZm9yIHRlc3RzIG9ubHlcbiAgICovXG4gIHJlbW92ZUV4cGlyZWRFbWl0SGlzdG9yeSgpIHtcbiAgICB0aGlzLl9wb29sLmdldFByb2Nlc3MoJ2Nvbm5lY3Rpb24nKT8ucmVtb3ZlRXhwaXJlZEVtaXRIaXN0b3J5KCk7XG4gIH1cbn1cblxubmFtZXNwYWNlIENsaWVudFN0aWNreVNvY2tldCB7XG5cbiAgLyoqIENvbnN0cnVjdGluZyBvcHRpb25zICovXG4gIGV4cG9ydCB0eXBlIE9wdGlvbnMgPSBQaWNrPFN0aWNreVNvY2tldENvbm5lY3Rpb24uT3B0aW9ucywgJ2Nvbm5lY3Rpb24nIHwgJ2xhYmVsJyB8ICd1c2VOYXRpdmVTb2NrZXRJb1NlcnZlcic+ICYge1xuICAgIC8qKlxuICAgICAqIEVtaXQgaGlzdG9yeSBidWZmZXIgVFRMLiBEZWZhdWx0cyB0byBgc3RpY2t5Q29ubmVjdGlvblR0bEluU2Vjb25kc2AgKyBgcmVjb25uZWN0VGhyb3R0bGVEZWxheUluTXNgXG4gICAgICogKGNvbnZlcnRlZCB0byBzZWNvbmRzKVxuICAgICAqL1xuICAgIGVtaXRIaXN0b3J5VHRsSW5TZWNvbmRzPzogbnVtYmVyO1xuICAgIC8qKiBUaW1lb3V0IHdpdGhpbiBvZiB3aGljaCBhIGNvbm5lY3Rpb24gY2FuIGJlIHJlc3RvcmVkIGFzIHByZXZpb3VzIG9uZS4gRGVmYXVsdHMgdG8gYDEwYCAqL1xuICAgIHN0aWNreUNvbm5lY3Rpb25UdGxJblNlY29uZHM/OiBudW1iZXI7XG4gICAgLyoqIFJlY29ubmVjdGlvbiBkZWxheS4gVGhlIGRlbGF5IHdpbGwgYmUgaW5jcmVhc2VkIGJ5IDJ4IGVhY2ggZmFpbGVkIGNvbm5lY3Rpb24gYXR0ZW1wdC4gRGVmYXVsdHMgdG8gYDEwMDBgICovXG4gICAgcmVjb25uZWN0aW9uRGVsYXlJbk1zPzogbnVtYmVyO1xuICAgIC8qKiBNYXggcmVjb25uZWN0aW9uIGRlbGF5LiBEZWZhdWx0cyB0byBgMTAwMDBgICovXG4gICAgcmVjb25uZWN0aW9uRGVsYXlNYXhJbk1zPzogbnVtYmVyO1xuICAgIC8qKiBSZWNvbm5lY3Rpb24gZGVsYXkgcmFuZG9taXphdGlvbiBmYWN0b3IgaW4gcmFuZ2UgWzA7IDFdLiBEZWZhdWx0cyB0byBgMC41YCAqL1xuICAgIHJlY29ubmVjdGlvblJhbmRvbWl6YXRpb25GYWN0b3I/OiBudW1iZXI7XG4gIH07XG5cbiAgLyoqIEV2ZW50IGxpc3RlbmVycyAqL1xuICBleHBvcnQgdHlwZSBFdmVudHMgPSB7XG4gICAgLyoqIEZpcmVkIG9ubHkgb25jZSB1cG9uIGZpcnN0IGNvbm5lY3Rpb24gKi9cbiAgICBjb25uZWN0OiAoKSA9PiB2b2lkO1xuICAgIC8qKiBGaXJlZCBvbmx5IG9uY2UgdXBvbiB0aGUgbGFzdCBkaXNjb25uZWN0aW9uLiBXaWxsIGJlIGZpcmVkIGFueXdheSwgZXZlbiBpZiB3YXMgbmV2ZXIgY29ubmVjdGVkICovXG4gICAgZGlzY29ubmVjdDogKGVycj86IEVycm9yKSA9PiB2b2lkO1xuICAgIC8qKiBDdXN0b20gc3Vic2NyaXB0aW9uIGV2ZW50cyAqL1xuICAgIFtldmVudDogc3RyaW5nXTogKC4uLmFyZ3M6IGFueVtdKSA9PiBhbnk7XG4gIH07XG5cbiAgLyoqIENvbm5lY3Rpb24gZXZlbnRzICovXG4gIGV4cG9ydCBjb25zdCBDT05ORUNUSU9OX0VWRU5UUyA9IFN0aWNreVNvY2tldENvbm5lY3Rpb24uQ09OTkVDVElPTl9FVkVOVFM7XG4gIC8qKiBJbnRlcm5hbCBldmVudHMgKi9cbiAgZXhwb3J0IGNvbnN0IElOVEVSTkFMX0VWRU5UUyA9IFN0aWNreVNvY2tldENvbm5lY3Rpb24uSU5URVJOQUxfRVZFTlRTO1xufVxuXG5leHBvcnQgZGVmYXVsdCBDbGllbnRTdGlja3lTb2NrZXQ7XG4iXSwibmFtZXMiOlsiQ2xpZW50U3RpY2t5U29ja2V0IiwiRXZlbnRFbWl0dGVyIiwiaWQiLCJfaWQiLCJzb2NrZXQiLCJfcG9vbCIsImdldFByb2Nlc3MiLCJ0cmFuc3BvcnROYW1lIiwiZmlyc3RIaXN0b3J5SW5kZXgiLCJjb25uZWN0ZWQiLCJfY29ubmVjdGVkIiwib24iLCJldmVudCIsImNhbGxiYWNrIiwiSU5URVJOQUxfRVZFTlRTIiwiaW5jbHVkZXMiLCJlcnJvcnMiLCJWYWxpZGF0aW9uRXJyb3IiLCJzZW5kIiwiYXJncyIsImRpc2Nvbm5lY3QiLCJlcnIiLCJjbGVhclRpbWVvdXQiLCJfc3RpY2t5Q29ubmVjdGlvbldhaXRUaW1lb3V0Iiwid2FzU3RvcHBlZCIsIl9zdG9wcGVkIiwic3RvcCIsImVtaXQiLCJkZXN0cm95SW50ZXJuYWxTb2NrZXQiLCJkZXN0cm95SW50ZXJuYWxDbGllbnRTb2NrZXQiLCJyZW1vdmVFeHBpcmVkRW1pdEhpc3RvcnkiLCJjb25zdHJ1Y3RvciIsInVybCIsIm9wdGlvbnMiLCJfbG9nZ2VyIiwiTG9nZ2VyTWFuYWdlciIsImdldExvZ2dlciIsInJhbmRvbXN0cmluZyIsImdlbmVyYXRlIiwiX2xhYmVsIiwibGFiZWwiLCJzdGlja3lDb25uZWN0aW9uVHRsSW5NcyIsInN0aWNreUNvbm5lY3Rpb25UdGxJblNlY29uZHMiLCJpbnRlcm5hbEV2ZW50cyIsIm9uY2UiLCJ1c2VOYXRpdmVTb2NrZXRJb1NlcnZlciIsInNldFRpbWVvdXQiLCJ3YXJuIiwibHJhcCIsIlJvb3RQb29sIiwiU3RpY2t5U29ja2V0Q29ubmVjdGlvbiIsImRlcGVuZGVuY2llcyIsInNjaGVkdWxlUHJvY2VzcyIsInN0YXJ0Q291bnQiLCJlbWl0SGlzdG9yeSIsIlF1ZXVlIiwibGFzdFNlbnRJbmRleCIsImxhc3RSZWNlaXZlZEluZGV4IiwiY29ubmVjdGlvbiIsImVtaXRIaXN0b3J5VHRsSW5TZWNvbmRzIiwibXNUb1NlY29uZHMiLCJmYWlsb3ZlclRocm90dGxlRGVsYXkiLCJtb2RlIiwicmVzZXREZWxheUluTXMiLCJtaW5EZWxheUluTXMiLCJyZWNvbm5lY3Rpb25EZWxheUluTXMiLCJtYXhEZWxheUluTXMiLCJyZWNvbm5lY3Rpb25EZWxheU1heEluTXMiLCJyYW5kb21pemF0aW9uRmFjdG9yIiwicmVjb25uZWN0aW9uUmFuZG9taXphdGlvbkZhY3RvciIsIkNPTk5FQ1RJT05fRVZFTlRTIl0sIm1hcHBpbmdzIjoiOzs7OytCQXVOQTs7O2VBQUE7OztxRUF2TnlCO2lGQUNIOytFQUNhO3NFQUNYOzZCQUNrQjtzQkFDaEI7cUVBQ0Q7K0RBQ0M7OERBQ1I7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUVsQjs7Q0FFQyxHQUNELElBQUEsQUFBTUEscUJBQU4sTUFBTUEsMkJBQTJCQyxxQkFBWTtJQXFFM0M7OztHQUdDLEdBQ0QsSUFBSUMsS0FBYTtRQUNmLE9BQU8sSUFBSSxDQUFDQyxHQUFHO0lBQ2pCO0lBRUE7Ozs7R0FJQyxHQUNELElBQUlDLFNBQWdDO1lBQzNCO1FBQVAsUUFBTyx5QkFBQSxJQUFJLENBQUNDLEtBQUssQ0FBQ0MsVUFBVSxDQUFDLDJCQUF0Qiw2Q0FBQSx1QkFBcUNGLE1BQU07SUFDcEQ7SUFFQTs7OztHQUlDLEdBQ0QsSUFBSUcsZ0JBQXdCO1lBQ25CO1FBQVAsUUFBTyx5QkFBQSxJQUFJLENBQUNGLEtBQUssQ0FBQ0MsVUFBVSxDQUFDLDJCQUF0Qiw2Q0FBQSx1QkFBcUNDLGFBQWE7SUFDM0Q7SUFFQTs7OztHQUlDLEdBQ0QsSUFBSUMsb0JBQXdDO1lBQ25DO1FBQVAsUUFBTyx5QkFBQSxJQUFJLENBQUNI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