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)
240 lines (239 loc) • 28.1 kB
JavaScript
;
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
try {
var info = gen[key](arg);
var value = info.value;
} catch (error) {
reject(error);
return;
}
if (info.done) {
resolve(value);
} else {
Promise.resolve(value).then(_next, _throw);
}
}
function _async_to_generator(fn) {
return function() {
var self = this, args = arguments;
return new Promise(function(resolve, reject) {
var gen = fn.apply(self, args);
function _next(value) {
asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value);
}
function _throw(err) {
asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err);
}
_next(undefined);
});
};
}
let TerminalListener = class TerminalListener {
/**
* Returns MetaApiConnection instance
* @return {MetaApiConnection} MetaApiConnection instance
*/ get connection() {
return this._connection;
}
/**
* Sets MetaApiConnection instance
* @param {MetaApiConnection} connection MetaApiConnection instance
*/ set connection(connection) {
this._connection = connection;
}
/**
* Invoked when connection to MetaTrader terminal established
* @return {Promise} promise which resolves when the asynchronous event is processed
*/ onConnected() {
return _async_to_generator(function*() {})();
}
/**
* Invoked when connection to MetaTrader terminal terminated
* @return {Promise} promise which resolves when the asynchronous event is processed
*/ onDisconnected() {
return _async_to_generator(function*() {})();
}
/**
* Invoked when broker connection satus have changed
* @param {Boolean} connected is MetaTrader terminal is connected to broker
* @return {Promise} promise which resolves when the asynchronous event is processed
*/ onBrokerConnectionStatus(connected) {
return _async_to_generator(function*() {})();
}
/**
* Invoked when MetaTrader terminal state synchronization is started
* @param {string} instanceIndex index of an account instance connected
* @param {string} specificationsHash specifications hash
* @param {string} positionsHash positions hash
* @param {string} ordersHash orders hash
* @param {string} synchronizationId synchronization id
* @return {Promise} promise which resolves when the asynchronous event is processed
*/ onSynchronizationStarted(instanceIndex, specificationsHash, positionsHash, ordersHash, synchronizationId) {}
/**
* Invoked when MetaTrader account information is updated
* @param {MetatraderAccountInformation} accountInformation updated MetaTrader account information
* @return {Promise} promise which resolves when the asynchronous event is processed
*/ onAccountInformationUpdated(accountInformation) {
return _async_to_generator(function*() {})();
}
/**
* Invoked when the positions are replaced as a result of initial terminal state synchronization. This method
* will be invoked only if server thinks the data was updated, otherwise invocation can be skipped
* @param {Array<MetatraderPosition>} positions updated array of positions
* @return {Promise} promise which resolves when the asynchronous event is processed
*/ onPositionsReplaced(positions) {
return _async_to_generator(function*() {})();
}
/**
* Invoked when position synchronization fnished to indicate progress of an initial terminal state synchronization
* @return {Promise} promise which resolves when the asynchronous event is processed
*/ onPositionsSynchronized() {
return _async_to_generator(function*() {})();
}
/**
* Invoked when MetaTrader position is updated
* @param {MetatraderPosition} position updated MetaTrader position
* @return {Promise} promise which resolves when the asynchronous event is processed
*/ onPositionUpdated(position) {
return _async_to_generator(function*() {})();
}
/**
* Invoked when MetaTrader position is removed
* @param {String} positionId removed MetaTrader position id
* @return {Promise} promise which resolves when the asynchronous event is processed
*/ onPositionRemoved(positionId) {
return _async_to_generator(function*() {})();
}
/**
* Invoked when the pending orders are replaced as a result of initial terminal state synchronization. This method
* will be invoked only if server thinks the data was updated, otherwise invocation can be skipped
* @param {Array<MetatraderOrder>} orders updated array of pending orders
* @return {Promise} promise which resolves when the asynchronous event is processed
*/ onPendingOrdersReplaced(orders) {
return _async_to_generator(function*() {})();
}
/**
* Invoked when MetaTrader pending order is updated
* @param {MetatraderOrder} order updated MetaTrader pending order
* @return {Promise} promise which resolves when the asynchronous event is processed
*/ onPendingOrderUpdated(order) {
return _async_to_generator(function*() {})();
}
/**
* Invoked when MetaTrader pending order is completed (executed or canceled)
* @param {String} orderId completed MetaTrader pending order id
* @return {Promise} promise which resolves when the asynchronous event is processed
*/ onPendingOrderCompleted(orderId) {
return _async_to_generator(function*() {})();
}
/**
* Invoked when pending order synchronization fnished to indicate progress of an initial terminal state
* synchronization
* @return {Promise} promise which resolves when the asynchronous event is processed
*/ onPendingOrdersSynchronized() {
return _async_to_generator(function*() {})();
}
/**
* Invoked when a new MetaTrader history order is added
* @param {MetatraderOrder} historyOrder new MetaTrader history order
* @return {Promise} promise which resolves when the asynchronous event is processed
*/ onHistoryOrderAdded(historyOrder) {
return _async_to_generator(function*() {})();
}
/**
* Invoked when a synchronization of history orders on a MetaTrader account have finished to indicate progress of an
* initial terminal state synchronization
* @return {Promise} promise which resolves when the asynchronous event is processed
*/ onHistoryOrdersSynchronized() {
return _async_to_generator(function*() {})();
}
/**
* Invoked when a new MetaTrader history deal is added
* @param {MetatraderDeal} deal new MetaTrader history deal
* @return {Promise} promise which resolves when the asynchronous event is processed
*/ onDealAdded(deal) {
return _async_to_generator(function*() {})();
}
/**
* Invoked when a synchronization of history deals on a MetaTrader account have finished to indicate progress of an
* initial terminal state synchronization
* @return {Promise} promise which resolves when the asynchronous event is processed
*/ onDealsSynchronized() {
return _async_to_generator(function*() {})();
}
/**
* Invoked when a symbol specification was updated
* @param {MetatraderSymbolSpecification} specification updated MetaTrader symbol specification
* @return {Promise} promise which resolves when the asynchronous event is processed
*/ onSymbolSpecificationUpdated(specification) {
return _async_to_generator(function*() {})();
}
/**
* Invoked when a symbol specification was removed
* @param {String} symbol removed symbol
* @returns {Promise} promise which resolves when the asynchronous event is processed
*/ onSymbolSpecificationRemoved(symbol) {
return _async_to_generator(function*() {})();
}
/**
* Invoked when a symbol price was updated
* @param {MetatraderSymbolPrice} quote updated MetaTrader symbol quote
* @return {Promise} promise which resolves when the asynchronous event is processed
*/ onQuote(quote) {
return _async_to_generator(function*() {})();
}
/**
* Invoked when symbol candles were updated
* @param {MetatraderCandle} candle updated MetaTrader symbol candle
* @return {Promise} promise which resolves when the asynchronous event is processed
*/ onCandle(candles) {
return _async_to_generator(function*() {})();
}
/**
* Invoked when symbol ticks were updated
* @param {MetatraderTick} tick updated MetaTrader symbol tick
* @return {Promise} promise which resolves when the asynchronous event is processed
*/ onTick(tick) {
return _async_to_generator(function*() {})();
}
/**
* Invoked when order books were updated
* @param {MetatraderBook} book updated MetaTrader order book
* @return {Promise} promise which resolves when the asynchronous event is processed
*/ onBook(book) {
return _async_to_generator(function*() {})();
}
/**
* Invoked when subscription downgrade has occurred
* @param {string} symbol symbol to update subscriptions for
* @param {Array<MarketDataSubscription>} updates array of market data subscription to update
* @param {Array<MarketDataUnsubscription>} unsubscriptions array of subscriptions to cancel
* @return {Promise} promise which resolves when the asynchronous event is processed
*/ onSubscriptionDowngraded(symbol, updates, unsubscriptions) {
return _async_to_generator(function*() {})();
}
};
/**
* Defines interface for a terminal listener class. You can extend your trading application implementation from
* this class.
* Unlike low-level SynchronizationListener, when you use TerminalListener, the SDK will remove race conditions and most
* events duplicates present on the transport layer. There is also a warranty that TeminalListener listener methods
* will be invoked in sequence. No new event will be delivered until previous event have finished processing.
* So that it is much easier to create trading applicaitions using TerminalListener, especially if the application is a
* complex one.
* Please note that some event listener methods can still receive event duplicates, so that they must be idempotent.
* The terminal lifecycle starts with onConnected event, followed by initial synchronization, followed by data updates.
* During initial synchronization the SDK will invoke the following methods in sequence: onSynchronizationStarted,
* onSymbolSpecificationUpdated (invoked both for new and updated symbol specifications, can be skipped if
* specifications data has not changed), onSymbolSpecificationRemoved, onQuote, onAccountInformationUpdated,
* onPositionsReplaced (can be skipped if position data has not changed), onPositionsSynchronized,
* onPendingOrdersReplaced (can be skipped if pending order data has not changed), onPendingOrdersSynchronized,
* onHistoryOrderAdded, onHistoryOrdersSynchronized, onDealAdded, onDealsSynchronized.
* Data update events are onPositionUpdated (invoked both for new and updated positions), onPositionRemoved,
* onPendingOrderUpdated (invoked both for new and updated pending orders), onPendingOrderCompleted,
* onHistoryOrderAdded, onDealAdded, onSymbolSpecificationUpdated (invoked both for new and updated symbol
* specifications), onSymbolSpecificationRemoved, onQuote, onCandle, onTick, onBook.
* There are also status events available such as onBrokerConnectionStatus, onDisconnected,
* onSubscriptionDowngraded.
*/ export { TerminalListener as default };
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIjxhbm9uPiJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbi8qKlxuICogRGVmaW5lcyBpbnRlcmZhY2UgZm9yIGEgdGVybWluYWwgbGlzdGVuZXIgY2xhc3MuIFlvdSBjYW4gZXh0ZW5kIHlvdXIgdHJhZGluZyBhcHBsaWNhdGlvbiBpbXBsZW1lbnRhdGlvbiBmcm9tXG4gKiB0aGlzIGNsYXNzLlxuICogVW5saWtlIGxvdy1sZXZlbCBTeW5jaHJvbml6YXRpb25MaXN0ZW5lciwgd2hlbiB5b3UgdXNlIFRlcm1pbmFsTGlzdGVuZXIsIHRoZSBTREsgd2lsbCByZW1vdmUgcmFjZSBjb25kaXRpb25zIGFuZCBtb3N0XG4gKiBldmVudHMgZHVwbGljYXRlcyBwcmVzZW50IG9uIHRoZSB0cmFuc3BvcnQgbGF5ZXIuIFRoZXJlIGlzIGFsc28gYSB3YXJyYW50eSB0aGF0IFRlbWluYWxMaXN0ZW5lciBsaXN0ZW5lciBtZXRob2RzXG4gKiB3aWxsIGJlIGludm9rZWQgaW4gc2VxdWVuY2UuIE5vIG5ldyBldmVudCB3aWxsIGJlIGRlbGl2ZXJlZCB1bnRpbCBwcmV2aW91cyBldmVudCBoYXZlIGZpbmlzaGVkIHByb2Nlc3NpbmcuXG4gKiBTbyB0aGF0IGl0IGlzIG11Y2ggZWFzaWVyIHRvIGNyZWF0ZSB0cmFkaW5nIGFwcGxpY2FpdGlvbnMgdXNpbmcgVGVybWluYWxMaXN0ZW5lciwgZXNwZWNpYWxseSBpZiB0aGUgYXBwbGljYXRpb24gaXMgYVxuICogY29tcGxleCBvbmUuXG4gKiBQbGVhc2Ugbm90ZSB0aGF0IHNvbWUgZXZlbnQgbGlzdGVuZXIgbWV0aG9kcyBjYW4gc3RpbGwgcmVjZWl2ZSBldmVudCBkdXBsaWNhdGVzLCBzbyB0aGF0IHRoZXkgbXVzdCBiZSBpZGVtcG90ZW50LlxuICogVGhlIHRlcm1pbmFsIGxpZmVjeWNsZSBzdGFydHMgd2l0aCBvbkNvbm5lY3RlZCBldmVudCwgZm9sbG93ZWQgYnkgaW5pdGlhbCBzeW5jaHJvbml6YXRpb24sIGZvbGxvd2VkIGJ5IGRhdGEgdXBkYXRlcy5cbiAqIER1cmluZyBpbml0aWFsIHN5bmNocm9uaXphdGlvbiB0aGUgU0RLIHdpbGwgaW52b2tlIHRoZSBmb2xsb3dpbmcgbWV0aG9kcyBpbiBzZXF1ZW5jZTogb25TeW5jaHJvbml6YXRpb25TdGFydGVkLFxuICogb25TeW1ib2xTcGVjaWZpY2F0aW9uVXBkYXRlZCAoaW52b2tlZCBib3RoIGZvciBuZXcgYW5kIHVwZGF0ZWQgc3ltYm9sIHNwZWNpZmljYXRpb25zLCBjYW4gYmUgc2tpcHBlZCBpZlxuICogc3BlY2lmaWNhdGlvbnMgZGF0YSBoYXMgbm90IGNoYW5nZWQpLCBvblN5bWJvbFNwZWNpZmljYXRpb25SZW1vdmVkLCBvblF1b3RlLCBvbkFjY291bnRJbmZvcm1hdGlvblVwZGF0ZWQsXG4gKiBvblBvc2l0aW9uc1JlcGxhY2VkIChjYW4gYmUgc2tpcHBlZCBpZiBwb3NpdGlvbiBkYXRhIGhhcyBub3QgY2hhbmdlZCksIG9uUG9zaXRpb25zU3luY2hyb25pemVkLFxuICogb25QZW5kaW5nT3JkZXJzUmVwbGFjZWQgKGNhbiBiZSBza2lwcGVkIGlmIHBlbmRpbmcgb3JkZXIgZGF0YSBoYXMgbm90IGNoYW5nZWQpLCBvblBlbmRpbmdPcmRlcnNTeW5jaHJvbml6ZWQsXG4gKiBvbkhpc3RvcnlPcmRlckFkZGVkLCBvbkhpc3RvcnlPcmRlcnNTeW5jaHJvbml6ZWQsIG9uRGVhbEFkZGVkLCBvbkRlYWxzU3luY2hyb25pemVkLlxuICogRGF0YSB1cGRhdGUgZXZlbnRzIGFyZSBvblBvc2l0aW9uVXBkYXRlZCAoaW52b2tlZCBib3RoIGZvciBuZXcgYW5kIHVwZGF0ZWQgcG9zaXRpb25zKSwgb25Qb3NpdGlvblJlbW92ZWQsXG4gKiBvblBlbmRpbmdPcmRlclVwZGF0ZWQgKGludm9rZWQgYm90aCBmb3IgbmV3IGFuZCB1cGRhdGVkIHBlbmRpbmcgb3JkZXJzKSwgb25QZW5kaW5nT3JkZXJDb21wbGV0ZWQsXG4gKiBvbkhpc3RvcnlPcmRlckFkZGVkLCBvbkRlYWxBZGRlZCwgb25TeW1ib2xTcGVjaWZpY2F0aW9uVXBkYXRlZCAoaW52b2tlZCBib3RoIGZvciBuZXcgYW5kIHVwZGF0ZWQgc3ltYm9sXG4gKiBzcGVjaWZpY2F0aW9ucyksIG9uU3ltYm9sU3BlY2lmaWNhdGlvblJlbW92ZWQsIG9uUXVvdGUsIG9uQ2FuZGxlLCBvblRpY2ssIG9uQm9vay5cbiAqIFRoZXJlIGFyZSBhbHNvIHN0YXR1cyBldmVudHMgYXZhaWxhYmxlIHN1Y2ggYXMgb25Ccm9rZXJDb25uZWN0aW9uU3RhdHVzLCBvbkRpc2Nvbm5lY3RlZCxcbiAqIG9uU3Vic2NyaXB0aW9uRG93bmdyYWRlZC5cbiAqL1xuZXhwb3J0IGRlZmF1bHQgY2xhc3MgVGVybWluYWxMaXN0ZW5lciB7XG5cbiAgLyoqXG4gICAqIFJldHVybnMgTWV0YUFwaUNvbm5lY3Rpb24gaW5zdGFuY2VcbiAgICogQHJldHVybiB7TWV0YUFwaUNvbm5lY3Rpb259IE1ldGFBcGlDb25uZWN0aW9uIGluc3RhbmNlXG4gICAqL1xuICBnZXQgY29ubmVjdGlvbigpIHtcbiAgICByZXR1cm4gdGhpcy5fY29ubmVjdGlvbjtcbiAgfVxuXG4gIC8qKlxuICAgKiBTZXRzIE1ldGFBcGlDb25uZWN0aW9uIGluc3RhbmNlXG4gICAqIEBwYXJhbSB7TWV0YUFwaUNvbm5lY3Rpb259IGNvbm5lY3Rpb24gTWV0YUFwaUNvbm5lY3Rpb24gaW5zdGFuY2VcbiAgICovXG4gIHNldCBjb25uZWN0aW9uKGNvbm5lY3Rpb24pIHtcbiAgICB0aGlzLl9jb25uZWN0aW9uID0gY29ubmVjdGlvbjtcbiAgfVxuXG4gIC8qKlxuICAgKiBJbnZva2VkIHdoZW4gY29ubmVjdGlvbiB0byBNZXRhVHJhZGVyIHRlcm1pbmFsIGVzdGFibGlzaGVkXG4gICAqIEByZXR1cm4ge1Byb21pc2V9IHByb21pc2Ugd2hpY2ggcmVzb2x2ZXMgd2hlbiB0aGUgYXN5bmNocm9ub3VzIGV2ZW50IGlzIHByb2Nlc3NlZFxuICAgKi9cbiAgYXN5bmMgb25Db25uZWN0ZWQoKSB7fVxuXG4gIC8qKlxuICAgKiBJbnZva2VkIHdoZW4gY29ubmVjdGlvbiB0byBNZXRhVHJhZGVyIHRlcm1pbmFsIHRlcm1pbmF0ZWRcbiAgICogQHJldHVybiB7UHJvbWlzZX0gcHJvbWlzZSB3aGljaCByZXNvbHZlcyB3aGVuIHRoZSBhc3luY2hyb25vdXMgZXZlbnQgaXMgcHJvY2Vzc2VkXG4gICAqL1xuICBhc3luYyBvbkRpc2Nvbm5lY3RlZCgpIHt9XG5cbiAgLyoqXG4gICAqIEludm9rZWQgd2hlbiBicm9rZXIgY29ubmVjdGlvbiBzYXR1cyBoYXZlIGNoYW5nZWRcbiAgICogQHBhcmFtIHtCb29sZWFufSBjb25uZWN0ZWQgaXMgTWV0YVRyYWRlciB0ZXJtaW5hbCBpcyBjb25uZWN0ZWQgdG8gYnJva2VyXG4gICAqIEByZXR1cm4ge1Byb21pc2V9IHByb21pc2Ugd2hpY2ggcmVzb2x2ZXMgd2hlbiB0aGUgYXN5bmNocm9ub3VzIGV2ZW50IGlzIHByb2Nlc3NlZFxuICAgKi9cbiAgYXN5bmMgb25Ccm9rZXJDb25uZWN0aW9uU3RhdHVzKGNvbm5lY3RlZCkge31cblxuICAvKipcbiAgICogSW52b2tlZCB3aGVuIE1ldGFUcmFkZXIgdGVybWluYWwgc3RhdGUgc3luY2hyb25pemF0aW9uIGlzIHN0YXJ0ZWRcbiAgICogQHBhcmFtIHtzdHJpbmd9IGluc3RhbmNlSW5kZXggaW5kZXggb2YgYW4gYWNjb3VudCBpbnN0YW5jZSBjb25uZWN0ZWRcbiAgICogQHBhcmFtIHtzdHJpbmd9IHNwZWNpZmljYXRpb25zSGFzaCBzcGVjaWZpY2F0aW9ucyBoYXNoXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBwb3NpdGlvbnNIYXNoIHBvc2l0aW9ucyBoYXNoXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBvcmRlcnNIYXNoIG9yZGVycyBoYXNoXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBzeW5jaHJvbml6YXRpb25JZCBzeW5jaHJvbml6YXRpb24gaWRcbiAgICogQHJldHVybiB7UHJvbWlzZX0gcHJvbWlzZSB3aGljaCByZXNvbHZlcyB3aGVuIHRoZSBhc3luY2hyb25vdXMgZXZlbnQgaXMgcHJvY2Vzc2VkXG4gICAqL1xuICBvblN5bmNocm9uaXphdGlvblN0YXJ0ZWQoaW5zdGFuY2VJbmRleCwgc3BlY2lmaWNhdGlvbnNIYXNoLCBwb3NpdGlvbnNIYXNoLCBvcmRlcnNIYXNoLCBzeW5jaHJvbml6YXRpb25JZCkge31cblxuICAvKipcbiAgICogSW52b2tlZCB3aGVuIE1ldGFUcmFkZXIgYWNjb3VudCBpbmZvcm1hdGlvbiBpcyB1cGRhdGVkXG4gICAqIEBwYXJhbSB7TWV0YXRyYWRlckFjY291bnRJbmZvcm1hdGlvbn0gYWNjb3VudEluZm9ybWF0aW9uIHVwZGF0ZWQgTWV0YVRyYWRlciBhY2NvdW50IGluZm9ybWF0aW9uXG4gICAqIEByZXR1cm4ge1Byb21pc2V9IHByb21pc2Ugd2hpY2ggcmVzb2x2ZXMgd2hlbiB0aGUgYXN5bmNocm9ub3VzIGV2ZW50IGlzIHByb2Nlc3NlZFxuICAgKi9cbiAgYXN5bmMgb25BY2NvdW50SW5mb3JtYXRpb25VcGRhdGVkKGFjY291bnRJbmZvcm1hdGlvbikge31cblxuICAvKipcbiAgICogSW52b2tlZCB3aGVuIHRoZSBwb3NpdGlvbnMgYXJlIHJlcGxhY2VkIGFzIGEgcmVzdWx0IG9mIGluaXRpYWwgdGVybWluYWwgc3RhdGUgc3luY2hyb25pemF0aW9uLiBUaGlzIG1ldGhvZFxuICAgKiB3aWxsIGJlIGludm9rZWQgb25seSBpZiBzZXJ2ZXIgdGhpbmtzIHRoZSBkYXRhIHdhcyB1cGRhdGVkLCBvdGhlcndpc2UgaW52b2NhdGlvbiBjYW4gYmUgc2tpcHBlZFxuICAgKiBAcGFyYW0ge0FycmF5PE1ldGF0cmFkZXJQb3NpdGlvbj59IHBvc2l0aW9ucyB1cGRhdGVkIGFycmF5IG9mIHBvc2l0aW9uc1xuICAgKiBAcmV0dXJuIHtQcm9taXNlfSBwcm9taXNlIHdoaWNoIHJlc29sdmVzIHdoZW4gdGhlIGFzeW5jaHJvbm91cyBldmVudCBpcyBwcm9jZXNzZWRcbiAgICovXG4gIGFzeW5jIG9uUG9zaXRpb25zUmVwbGFjZWQocG9zaXRpb25zKSB7fVxuXG4gIC8qKlxuICAgKiBJbnZva2VkIHdoZW4gcG9zaXRpb24gc3luY2hyb25pemF0aW9uIGZuaXNoZWQgdG8gaW5kaWNhdGUgcHJvZ3Jlc3Mgb2YgYW4gaW5pdGlhbCB0ZXJtaW5hbCBzdGF0ZSBzeW5jaHJvbml6YXRpb25cbiAgICogQHJldHVybiB7UHJvbWlzZX0gcHJvbWlzZSB3aGljaCByZXNvbHZlcyB3aGVuIHRoZSBhc3luY2hyb25vdXMgZXZlbnQgaXMgcHJvY2Vzc2VkXG4gICAqL1xuICBhc3luYyBvblBvc2l0aW9uc1N5bmNocm9uaXplZCgpIHt9XG5cbiAgLyoqXG4gICAqIEludm9rZWQgd2hlbiBNZXRhVHJhZGVyIHBvc2l0aW9uIGlzIHVwZGF0ZWRcbiAgICogQHBhcmFtIHtNZXRhdHJhZGVyUG9zaXRpb259IHBvc2l0aW9uIHVwZGF0ZWQgTWV0YVRyYWRlciBwb3NpdGlvblxuICAgKiBAcmV0dXJuIHtQcm9taXNlfSBwcm9taXNlIHdoaWNoIHJlc29sdmVzIHdoZW4gdGhlIGFzeW5jaHJvbm91cyBldmVudCBpcyBwcm9jZXNzZWRcbiAgICovXG4gIGFzeW5jIG9uUG9zaXRpb25VcGRhdGVkKHBvc2l0aW9uKSB7fVxuXG4gIC8qKlxuICAgKiBJbnZva2VkIHdoZW4gTWV0YVRyYWRlciBwb3NpdGlvbiBpcyByZW1vdmVkXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBwb3NpdGlvbklkIHJlbW92ZWQgTWV0YVRyYWRlciBwb3NpdGlvbiBpZFxuICAgKiBAcmV0dXJuIHtQcm9taXNlfSBwcm9taXNlIHdoaWNoIHJlc29sdmVzIHdoZW4gdGhlIGFzeW5jaHJvbm91cyBldmVudCBpcyBwcm9jZXNzZWRcbiAgICovXG4gIGFzeW5jIG9uUG9zaXRpb25SZW1vdmVkKHBvc2l0aW9uSWQpIHt9XG5cbiAgLyoqXG4gICAqIEludm9rZWQgd2hlbiB0aGUgcGVuZGluZyBvcmRlcnMgYXJlIHJlcGxhY2VkIGFzIGEgcmVzdWx0IG9mIGluaXRpYWwgdGVybWluYWwgc3RhdGUgc3luY2hyb25pemF0aW9uLiBUaGlzIG1ldGhvZFxuICAgKiB3aWxsIGJlIGludm9rZWQgb25seSBpZiBzZXJ2ZXIgdGhpbmtzIHRoZSBkYXRhIHdhcyB1cGRhdGVkLCBvdGhlcndpc2UgaW52b2NhdGlvbiBjYW4gYmUgc2tpcHBlZFxuICAgKiBAcGFyYW0ge0FycmF5PE1ldGF0cmFkZXJPcmRlcj59IG9yZGVycyB1cGRhdGVkIGFycmF5IG9mIHBlbmRpbmcgb3JkZXJzXG4gICAqIEByZXR1cm4ge1Byb21pc2V9IHByb21pc2Ugd2hpY2ggcmVzb2x2ZXMgd2hlbiB0aGUgYXN5bmNocm9ub3VzIGV2ZW50IGlzIHByb2Nlc3NlZFxuICAgKi9cbiAgYXN5bmMgb25QZW5kaW5nT3JkZXJzUmVwbGFjZWQob3JkZXJzKSB7fVxuXG4gIC8qKlxuICAgKiBJbnZva2VkIHdoZW4gTWV0YVRyYWRlciBwZW5kaW5nIG9yZGVyIGlzIHVwZGF0ZWRcbiAgICogQHBhcmFtIHtNZXRhdHJhZGVyT3JkZXJ9IG9yZGVyIHVwZGF0ZWQgTWV0YVRyYWRlciBwZW5kaW5nIG9yZGVyXG4gICAqIEByZXR1cm4ge1Byb21pc2V9IHByb21pc2Ugd2hpY2ggcmVzb2x2ZXMgd2hlbiB0aGUgYXN5bmNocm9ub3VzIGV2ZW50IGlzIHByb2Nlc3NlZFxuICAgKi9cbiAgYXN5bmMgb25QZW5kaW5nT3JkZXJVcGRhdGVkKG9yZGVyKSB7fVxuXG4gIC8qKlxuICAgKiBJbnZva2VkIHdoZW4gTWV0YVRyYWRlciBwZW5kaW5nIG9yZGVyIGlzIGNvbXBsZXRlZCAoZXhlY3V0ZWQgb3IgY2FuY2VsZWQpXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBvcmRlcklkIGNvbXBsZXRlZCBNZXRhVHJhZGVyIHBlbmRpbmcgb3JkZXIgaWRcbiAgICogQHJldHVybiB7UHJvbWlzZX0gcHJvbWlzZSB3aGljaCByZXNvbHZlcyB3aGVuIHRoZSBhc3luY2hyb25vdXMgZXZlbnQgaXMgcHJvY2Vzc2VkXG4gICAqL1xuICBhc3luYyBvblBlbmRpbmdPcmRlckNvbXBsZXRlZChvcmRlcklkKSB7fVxuXG4gIC8qKlxuICAgKiBJbnZva2VkIHdoZW4gcGVuZGluZyBvcmRlciBzeW5jaHJvbml6YXRpb24gZm5pc2hlZCB0byBpbmRpY2F0ZSBwcm9ncmVzcyBvZiBhbiBpbml0aWFsIHRlcm1pbmFsIHN0YXRlXG4gICAqIHN5bmNocm9uaXphdGlvblxuICAgKiBAcmV0dXJuIHtQcm9taXNlfSBwcm9taXNlIHdoaWNoIHJlc29sdmVzIHdoZW4gdGhlIGFzeW5jaHJvbm91cyBldmVudCBpcyBwcm9jZXNzZWRcbiAgICovXG4gIGFzeW5jIG9uUGVuZGluZ09yZGVyc1N5bmNocm9uaXplZCgpIHt9XG5cbiAgLyoqXG4gICAqIEludm9rZWQgd2hlbiBhIG5ldyBNZXRhVHJhZGVyIGhpc3Rvcnkgb3JkZXIgaXMgYWRkZWRcbiAgICogQHBhcmFtIHtNZXRhdHJhZGVyT3JkZXJ9IGhpc3RvcnlPcmRlciBuZXcgTWV0YVRyYWRlciBoaXN0b3J5IG9yZGVyXG4gICAqIEByZXR1cm4ge1Byb21pc2V9IHByb21pc2Ugd2hpY2ggcmVzb2x2ZXMgd2hlbiB0aGUgYXN5bmNocm9ub3VzIGV2ZW50IGlzIHByb2Nlc3NlZFxuICAgKi9cbiAgYXN5bmMgb25IaXN0b3J5T3JkZXJBZGRlZChoaXN0b3J5T3JkZXIpIHt9XG5cbiAgLyoqXG4gICAqIEludm9rZWQgd2hlbiBhIHN5bmNocm9uaXphdGlvbiBvZiBoaXN0b3J5IG9yZGVycyBvbiBhIE1ldGFUcmFkZXIgYWNjb3VudCBoYXZlIGZpbmlzaGVkIHRvIGluZGljYXRlIHByb2dyZXNzIG9mIGFuXG4gICAqIGluaXRpYWwgdGVybWluYWwgc3RhdGUgc3luY2hyb25pemF0aW9uXG4gICAqIEByZXR1cm4ge1Byb21pc2V9IHByb21pc2Ugd2hpY2ggcmVzb2x2ZXMgd2hlbiB0aGUgYXN5bmNocm9ub3VzIGV2ZW50IGlzIHByb2Nlc3NlZFxuICAgKi9cbiAgYXN5bmMgb25IaXN0b3J5T3JkZXJzU3luY2hyb25pemVkKCkge31cblxuICAvKipcbiAgICogSW52b2tlZCB3aGVuIGEgbmV3IE1ldGFUcmFkZXIgaGlzdG9yeSBkZWFsIGlzIGFkZGVkXG4gICAqIEBwYXJhbSB7TWV0YXRyYWRlckRlYWx9IGRlYWwgbmV3IE1ldGFUcmFkZXIgaGlzdG9yeSBkZWFsXG4gICAqIEByZXR1cm4ge1Byb21pc2V9IHByb21pc2Ugd2hpY2ggcmVzb2x2ZXMgd2hlbiB0aGUgYXN5bmNocm9ub3VzIGV2ZW50IGlzIHByb2Nlc3NlZFxuICAgKi9cbiAgYXN5bmMgb25EZWFsQWRkZWQoZGVhbCkge31cblxuICAvKipcbiAgICogSW52b2tlZCB3aGVuIGEgc3luY2hyb25pemF0aW9uIG9mIGhpc3RvcnkgZGVhbHMgb24gYSBNZXRhVHJhZGVyIGFjY291bnQgaGF2ZSBmaW5pc2hlZCB0byBpbmRpY2F0ZSBwcm9ncmVzcyBvZiBhblxuICAgKiBpbml0aWFsIHRlcm1pbmFsIHN0YXRlIHN5bmNocm9uaXphdGlvblxuICAgKiBAcmV0dXJuIHtQcm9taXNlfSBwcm9taXNlIHdoaWNoIHJlc29sdmVzIHdoZW4gdGhlIGFzeW5jaHJvbm91cyBldmVudCBpcyBwcm9jZXNzZWRcbiAgICovXG4gIGFzeW5jIG9uRGVhbHNTeW5jaHJvbml6ZWQoKSB7fVxuXG4gIC8qKlxuICAgKiBJbnZva2VkIHdoZW4gYSBzeW1ib2wgc3BlY2lmaWNhdGlvbiB3YXMgdXBkYXRlZFxuICAgKiBAcGFyYW0ge01ldGF0cmFkZXJTeW1ib2xTcGVjaWZpY2F0aW9ufSBzcGVjaWZpY2F0aW9uIHVwZGF0ZWQgTWV0YVRyYWRlciBzeW1ib2wgc3BlY2lmaWNhdGlvblxuICAgKiBAcmV0dXJuIHtQcm9taXNlfSBwcm9taXNlIHdoaWNoIHJlc29sdmVzIHdoZW4gdGhlIGFzeW5jaHJvbm91cyBldmVudCBpcyBwcm9jZXNzZWRcbiAgICovXG4gIGFzeW5jIG9uU3ltYm9sU3BlY2lmaWNhdGlvblVwZGF0ZWQoc3BlY2lmaWNhdGlvbikge31cblxuICAvKipcbiAgICogSW52b2tlZCB3aGVuIGEgc3ltYm9sIHNwZWNpZmljYXRpb24gd2FzIHJlbW92ZWRcbiAgICogQHBhcmFtIHtTdHJpbmd9IHN5bWJvbCByZW1vdmVkIHN5bWJvbFxuICAgKiBAcmV0dXJucyB7UHJvbWlzZX0gcHJvbWlzZSB3aGljaCByZXNvbHZlcyB3aGVuIHRoZSBhc3luY2hyb25vdXMgZXZlbnQgaXMgcHJvY2Vzc2VkXG4gICAqL1xuICBhc3luYyBvblN5bWJvbFNwZWNpZmljYXRpb25SZW1vdmVkKHN5bWJvbCkge31cblxuICAvKipcbiAgICogSW52b2tlZCB3aGVuIGEgc3ltYm9sIHByaWNlIHdhcyB1cGRhdGVkXG4gICAqIEBwYXJhbSB7TWV0YXRyYWRlclN5bWJvbFByaWNlfSBxdW90ZSB1cGRhdGVkIE1ldGFUcmFkZXIgc3ltYm9sIHF1b3RlXG4gICAqIEByZXR1cm4ge1Byb21pc2V9IHByb21pc2Ugd2hpY2ggcmVzb2x2ZXMgd2hlbiB0aGUgYXN5bmNocm9ub3VzIGV2ZW50IGlzIHByb2Nlc3NlZFxuICAgKi9cbiAgYXN5bmMgb25RdW90ZShxdW90ZSkge31cblxuICAvKipcbiAgICogSW52b2tlZCB3aGVuIHN5bWJvbCBjYW5kbGVzIHdlcmUgdXBkYXRlZFxuICAgKiBAcGFyYW0ge01ldGF0cmFkZXJDYW5kbGV9IGNhbmRsZSB1cGRhdGVkIE1ldGFUcmFkZXIgc3ltYm9sIGNhbmRsZVxuICAgKiBAcmV0dXJuIHtQcm9taXNlfSBwcm9taXNlIHdoaWNoIHJlc29sdmVzIHdoZW4gdGhlIGFzeW5jaHJvbm91cyBldmVudCBpcyBwcm9jZXNzZWRcbiAgICovXG4gIGFzeW5jIG9uQ2FuZGxlKGNhbmRsZXMpIHt9XG5cbiAgLyoqXG4gICAqIEludm9rZWQgd2hlbiBzeW1ib2wgdGlja3Mgd2VyZSB1cGRhdGVkXG4gICAqIEBwYXJhbSB7TWV0YXRyYWRlclRpY2t9IHRpY2sgdXBkYXRlZCBNZXRhVHJhZGVyIHN5bWJvbCB0aWNrXG4gICAqIEByZXR1cm4ge1Byb21pc2V9IHByb21pc2Ugd2hpY2ggcmVzb2x2ZXMgd2hlbiB0aGUgYXN5bmNocm9ub3VzIGV2ZW50IGlzIHByb2Nlc3NlZFxuICAgKi9cbiAgYXN5bmMgb25UaWNrKHRpY2spIHt9XG5cbiAgLyoqXG4gICAqIEludm9rZWQgd2hlbiBvcmRlciBib29rcyB3ZXJlIHVwZGF0ZWRcbiAgICogQHBhcmFtIHtNZXRhdHJhZGVyQm9va30gYm9vayB1cGRhdGVkIE1ldGFUcmFkZXIgb3JkZXIgYm9va1xuICAgKiBAcmV0dXJuIHtQcm9taXNlfSBwcm9taXNlIHdoaWNoIHJlc29sdmVzIHdoZW4gdGhlIGFzeW5jaHJvbm91cyBldmVudCBpcyBwcm9jZXNzZWRcbiAgICovXG4gIGFzeW5jIG9uQm9vayhib29rKSB7fVxuXG4gIC8qKlxuICAgKiBJbnZva2VkIHdoZW4gc3Vic2NyaXB0aW9uIGRvd25ncmFkZSBoYXMgb2NjdXJyZWRcbiAgICogQHBhcmFtIHtzdHJpbmd9IHN5bWJvbCBzeW1ib2wgdG8gdXBkYXRlIHN1YnNjcmlwdGlvbnMgZm9yXG4gICAqIEBwYXJhbSB7QXJyYXk8TWFya2V0RGF0YVN1YnNjcmlwdGlvbj59IHVwZGF0ZXMgYXJyYXkgb2YgbWFya2V0IGRhdGEgc3Vic2NyaXB0aW9uIHRvIHVwZGF0ZVxuICAgKiBAcGFyYW0ge0FycmF5PE1hcmtldERhdGFVbnN1YnNjcmlwdGlvbj59IHVuc3Vic2NyaXB0aW9ucyBhcnJheSBvZiBzdWJzY3JpcHRpb25zIHRvIGNhbmNlbFxuICAgKiBAcmV0dXJuIHtQcm9taXNlfSBwcm9taXNlIHdoaWNoIHJlc29sdmVzIHdoZW4gdGhlIGFzeW5jaHJvbm91cyBldmVudCBpcyBwcm9jZXNzZWRcbiAgICovXG4gIGFzeW5jIG9uU3Vic2NyaXB0aW9uRG93bmdyYWRlZChzeW1ib2wsIHVwZGF0ZXMsIHVuc3Vic2NyaXB0aW9ucykge31cblxufVxuIl0sIm5hbWVzIjpbIlRlcm1pbmFsTGlzdGVuZXIiLCJjb25uZWN0aW9uIiwiX2Nvbm5lY3Rpb24iLCJvbkNvbm5lY3RlZCIsIm9uRGlzY29ubmVjdGVkIiwib25Ccm9rZXJDb25uZWN0aW9uU3RhdHVzIiwiY29ubmVjdGVkIiwib25TeW5jaHJvbml6YXRpb25TdGFydGVkIiwiaW5zdGFuY2VJbmRleCIsInNwZWNpZmljYXRpb25zSGFzaCIsInBvc2l0aW9uc0hhc2giLCJvcmRlcnNIYXNoIiwic3luY2hyb25pemF0aW9uSWQiLCJvbkFjY291bnRJbmZvcm1hdGlvblVwZGF0ZWQiLCJhY2NvdW50SW5mb3JtYXRpb24iLCJvblBvc2l0aW9uc1JlcGxhY2VkIiwicG9zaXRpb25zIiwib25Qb3NpdGlvbnNTeW5jaHJvbml6ZWQiLCJvblBvc2l0aW9uVXBkYXRlZCIsInBvc2l0aW9uIiwib25Qb3NpdGlvblJlbW92ZWQiLCJwb3NpdGlvbklkIiwib25QZW5kaW5nT3JkZXJzUmVwbGFjZWQiLCJvcmRlcnMiLCJvblBlbmRpbmdPcmRlclVwZGF0ZWQiLCJvcmRlciIsIm9uUGVuZGluZ09yZGVyQ29tcGxldGVkIiwib3JkZXJJZCIsIm9uUGVuZGluZ09yZGVyc1N5bmNocm9uaXplZCIsIm9uSGlzdG9yeU9yZGVyQWRkZWQiLCJoaXN0b3J5T3JkZXIiLCJvbkhpc3RvcnlPcmRlcnNTeW5jaHJvbml6ZWQiLCJvbkRlYWxBZGRlZCIsImRlYWwiLCJvbkRlYWxzU3luY2hyb25pemVkIiwib25TeW1ib2xTcGVjaWZpY2F0aW9uVXBkYXRlZCIsInNwZWNpZmljYXRpb24iLCJvblN5bWJvbFNwZWNpZmljYXRpb25SZW1vdmVkIiwic3ltYm9sIiwib25RdW90ZSIsInF1b3RlIiwib25DYW5kbGUiLCJjYW5kbGVzIiwib25UaWNrIiwidGljayIsIm9uQm9vayIsImJvb2siLCJvblN1YnNjcmlwdGlvbkRvd25ncmFkZWQiLCJ1cGRhdGVzIiwidW5zdWJzY3JpcHRpb25zIl0sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBeUJlLElBQUEsQUFBTUEsbUJBQU4sTUFBTUE7SUFFbkI7OztHQUdDLEdBQ0QsSUFBSUMsYUFBYTtRQUNmLE9BQU8sSUFBSSxDQUFDQyxXQUFXO0lBQ3pCO0lBRUE7OztHQUdDLEdBQ0QsSUFBSUQsV0FBV0EsVUFBVSxFQUFFO1FBQ3pCLElBQUksQ0FBQ0MsV0FBVyxHQUFHRDtJQUNyQjtJQUVBOzs7R0FHQyxHQUNELEFBQU1FO2VBQU4sb0JBQUEsYUFBcUI7O0lBRXJCOzs7R0FHQyxHQUNELEFBQU1DO2VBQU4sb0JBQUEsYUFBd0I7O0lBRXhCOzs7O0dBSUMsR0FDRCxBQUFNQyx5QkFBeUJDLFNBQVM7ZUFBeEMsb0JBQUEsYUFBMkM7O0lBRTNDOzs7Ozs7OztHQVFDLEdBQ0RDLHlCQUF5QkMsYUFBYSxFQUFFQyxrQkFBa0IsRUFBRUMsYUFBYSxFQUFFQyxVQUFVLEVBQUVDLGlCQUFpQixFQUFFLENBQUM7SUFFM0c7Ozs7R0FJQyxHQUNELEFBQU1DLDRCQUE0QkMsa0JBQWtCO2VBQXBELG9CQUFBLGFBQXVEOztJQUV2RDs7Ozs7R0FLQyxHQUNELEFBQU1DLG9CQUFvQkMsU0FBUztlQUFuQyxvQkFBQSxhQUFzQzs7SUFFdEM7OztHQUdDLEdBQ0QsQUFBTUM7ZUFBTixvQkFBQSxhQUFpQzs7SUFFakM7Ozs7R0FJQyxHQUNELEFBQU1DLGtCQUFrQkMsUUFBUTtlQUFoQyxvQkFBQSxhQUFtQzs7SUFFbkM7Ozs7R0FJQyxHQUNELEFBQU1DLGtCQUFrQkMsVUFBVTtlQUFsQyxvQkFBQSxhQUFxQzs7SUFFckM7Ozs7O0dBS0MsR0FDRCxBQUFNQyx3QkFBd0JDLE1BQU07ZUFBcEMsb0JBQUEsYUFBdUM7O0lBRXZDOzs7O0dBSUMsR0FDRCxBQUFNQyxzQkFBc0JDLEtBQUs7ZUFBakMsb0JBQUEsYUFBb0M7O0lBRXBDOzs7O0dBSUMsR0FDRCxBQUFNQyx3QkFBd0JDLE9BQU87ZUFBckMsb0JBQUEsYUFBd0M7O0lBRXhDOzs7O0dBSUMsR0FDRCxBQUFNQztlQUFOLG9CQUFBLGFBQXFDOztJQUVyQzs7OztHQUlDLEdBQ0QsQUFBTUMsb0JBQW9CQyxZQUFZO2VBQXRDLG9CQUFBLGFBQXlDOztJQUV6Qzs7OztHQUlDLEdBQ0QsQUFBTUM7ZUFBTixvQkFBQSxhQUFxQzs7SUFFckM7Ozs7R0FJQyxHQUNELEFBQU1DLFlBQVlDLElBQUk7ZUFBdEIsb0JBQUEsYUFBeUI7O0lBRXpCOzs7O0dBSUMsR0FDRCxBQUFNQztlQUFOLG9CQUFBLGFBQTZCOztJQUU3Qjs7OztHQUlDLEdBQ0QsQUFBTUMsNkJBQTZCQyxhQUFhO2VBQWhELG9CQUFBLGFBQW1EOztJQUVuRDs7OztHQUlDLEdBQ0QsQUFBTUMsNkJBQTZCQyxNQUFNO2VBQXpDLG9CQUFBLGFBQTRDOztJQUU1Qzs7OztHQUlDLEdBQ0QsQUFBTUMsUUFBUUMsS0FBSztlQUFuQixvQkFBQSxhQUFzQjs7SUFFdEI7Ozs7R0FJQyxHQUNELEFBQU1DLFNBQVNDLE9BQU87ZUFBdEIsb0JBQUEsYUFBeUI7O0lBRXpCOzs7O0dBSUMsR0FDRCxBQUFNQyxPQUFPQyxJQUFJO2VBQWpCLG9CQUFBLGFBQW9COztJQUVwQjs7OztHQUlDLEdBQ0QsQUFBTUMsT0FBT0MsSUFBSTtlQUFqQixvQkFBQSxhQUFvQjs7SUFFcEI7Ozs7OztHQU1DLEdBQ0QsQUFBTUMseUJBQXlCVCxNQUFNLEVBQUVVLE9BQU8sRUFBRUMsZUFBZTtlQUEvRCxvQkFBQSxhQUFrRTs7QUFFcEU7QUF0TkE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Q0FzQkMsR0FDRCxTQUFxQmpELDhCQStMcEIifQ==