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)
148 lines (147 loc) • 25.6 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "default", {
enumerable: true,
get: function() {
return MetaApi;
}
});
const _httpClient = /*#__PURE__*/ _interop_require_default(require("../clients/httpClient"));
const _provisioningProfileclient = /*#__PURE__*/ _interop_require_default(require("../clients/metaApi/provisioningProfile.client"));
const _provisioningProfileApi = /*#__PURE__*/ _interop_require_default(require("./provisioningProfileApi"));
const _metaApiWebsocketclient = /*#__PURE__*/ _interop_require_default(require("../clients/metaApi/metaApiWebsocket.client"));
const _metatraderAccountApi = /*#__PURE__*/ _interop_require_default(require("./metatraderAccountApi"));
const _metatraderAccountclient = /*#__PURE__*/ _interop_require_default(require("../clients/metaApi/metatraderAccount.client"));
const _metatraderAccountGeneratorApi = /*#__PURE__*/ _interop_require_default(require("./metatraderAccountGeneratorApi"));
const _metatraderAccountGeneratorclient = /*#__PURE__*/ _interop_require_default(require("../clients/metaApi/metatraderAccountGenerator.client"));
const _historicalMarketDataclient = /*#__PURE__*/ _interop_require_default(require("../clients/metaApi/historicalMarketData.client"));
const _clientApiclient = /*#__PURE__*/ _interop_require_default(require("../clients/metaApi/clientApi.client"));
const _connectionRegistry = /*#__PURE__*/ _interop_require_default(require("./connectionRegistry"));
const _errorHandler = require("../clients/errorHandler");
const _optionsValidator = /*#__PURE__*/ _interop_require_default(require("../clients/optionsValidator"));
const _latencyMonitor = /*#__PURE__*/ _interop_require_default(require("./latencyMonitor"));
const _expertAdvisorclient = /*#__PURE__*/ _interop_require_default(require("../clients/metaApi/expertAdvisor.client"));
const _logger = /*#__PURE__*/ _interop_require_default(require("../logger"));
const _domainclient = /*#__PURE__*/ _interop_require_default(require("../clients/domain.client"));
const _terminalHashManager = /*#__PURE__*/ _interop_require_default(require("./terminalHashManager"));
const _tokenManagementclient = /*#__PURE__*/ _interop_require_default(require("../clients/metaApi/tokenManagement.client"));
const _tokenManagementApi = /*#__PURE__*/ _interop_require_default(require("./tokenManagementApi"));
const _lodash = /*#__PURE__*/ _interop_require_default(require("lodash"));
function _interop_require_default(obj) {
return obj && obj.__esModule ? obj : {
default: obj
};
}
let MetaApi = class MetaApi {
/**
* Enables using Log4js logger with extended log levels for debugging instead of
* console.* functions. Note that log4js configuration performed by the user.
*/ static enableLog4jsLogging() {
_logger.default.useLog4js();
}
/**
* Returns provisioning profile API
* @returns {ProvisioningProfileApi} provisioning profile API
*/ get provisioningProfileApi() {
return this._provisioningProfileApi;
}
/**
* Returns MetaTrader account API
* @return {MetatraderAccountApi} MetaTrader account API
*/ get metatraderAccountApi() {
return this._metatraderAccountApi;
}
/**
* Returns MetaTrader account generator API
* @return {MetatraderDemoAccountApi} MetaTrader account generator API
*/ get metatraderAccountGeneratorApi() {
return this._metatraderAccountGeneratorApi;
}
/**
* Returns MetaApi application latency monitor
* @return {LatencyMonitor} latency monitor
*/ get latencyMonitor() {
return this._latencyMonitor;
}
/**
* Returns token management API
* @returns {TokenManagementApi} token management API
*/ get tokenManagementApi() {
return this._tokenManagementApi;
}
/**
* Closes all clients and connections and stops all internal jobs
*/ close() {
this._metaApiWebsocketClient.removeLatencyListener(this._latencyMonitor);
this._metaApiWebsocketClient.close();
this._metaApiWebsocketClient.stop();
this._terminalHashManager._stop();
}
/**
* Constructs MetaApi class instance
* @param {String} token authorization token
* @param {MetaApiOpts} opts application options
*/ // eslint-disable-next-line complexity
constructor(token, opts){
const validator = new _optionsValidator.default();
opts = _lodash.default.omit(opts || {}, [
"connections"
]);
const application = opts.application || "MetaApi";
const domain = opts.domain || "agiliumtrade.agiliumtrade.ai";
const requestTimeout = validator.validateNonZero(opts.requestTimeout, 60, "requestTimeout");
const historicalMarketDataRequestTimeout = validator.validateNonZero(opts.historicalMarketDataRequestTimeout, 240, "historicalMarketDataRequestTimeout");
const connectTimeout = validator.validateNonZero(opts.connectTimeout, 60, "connectTimeout");
const packetOrderingTimeout = validator.validateNonZero(opts.packetOrderingTimeout, 60, "packetOrderingTimeout");
const retryOpts = opts.retryOpts || {};
const packetLogger = opts.packetLogger || {};
const synchronizationThrottler = opts.synchronizationThrottler || {};
const accountGeneratorRequestTimeout = validator.validateNonZero(opts.accountGeneratorRequestTimeout, 240, "accountGeneratorRequestTimeout");
if (!application.match(/[a-zA-Z0-9_]+/)) {
throw new _errorHandler.ValidationError("Application name must be non-empty string consisting from letters, digits and _ only");
}
const useSharedClientApi = opts.useSharedClientApi || false;
const refreshSubscriptionsOpts = opts.refreshSubscriptionsOpts || {};
const httpClient = new _httpClient.default(requestTimeout, retryOpts);
const domainClient = new _domainclient.default(httpClient, token, domain);
const historicalMarketDataHttpClient = new _httpClient.default(historicalMarketDataRequestTimeout, retryOpts);
const accountGeneratorHttpClient = new _httpClient.default(accountGeneratorRequestTimeout, retryOpts);
const clientApiClient = new _clientApiclient.default(httpClient, domainClient);
const tokenManagmentClient = new _tokenManagementclient.default(httpClient, domainClient);
this._terminalHashManager = new _terminalHashManager.default(clientApiClient, opts.keepHashTrees);
this._metaApiWebsocketClient = new _metaApiWebsocketclient.default(this, domainClient, token, {
application,
domain,
requestTimeout,
connectTimeout,
packetLogger,
packetOrderingTimeout,
synchronizationThrottler,
retryOpts,
useSharedClientApi,
region: opts.region,
unsubscribeThrottlingIntervalInSeconds: opts.unsubscribeThrottlingIntervalInSeconds,
useNativeSocketIoServer: opts.useNativeSocketIoServer
});
this._provisioningProfileApi = new _provisioningProfileApi.default(new _provisioningProfileclient.default(httpClient, domainClient));
this._connectionRegistry = new _connectionRegistry.default(opts, this._metaApiWebsocketClient, this._terminalHashManager, application, refreshSubscriptionsOpts);
let historicalMarketDataClient = new _historicalMarketDataclient.default(historicalMarketDataHttpClient, domainClient);
this._metatraderAccountApi = new _metatraderAccountApi.default(new _metatraderAccountclient.default(httpClient, domainClient), this._metaApiWebsocketClient, this._connectionRegistry, new _expertAdvisorclient.default(httpClient, domainClient), historicalMarketDataClient, application);
this._metatraderAccountGeneratorApi = new _metatraderAccountGeneratorApi.default(new _metatraderAccountGeneratorclient.default(accountGeneratorHttpClient, domainClient));
this._tokenManagementApi = new _tokenManagementApi.default(tokenManagmentClient);
if (opts.enableLatencyTracking || opts.enableLatencyMonitor) {
this._latencyMonitor = new _latencyMonitor.default();
this._metaApiWebsocketClient.addLatencyListener(this._latencyMonitor);
}
this._logger = _logger.default.getLogger("MetaAPI");
if (process.env.IS_BROWSER) {
if (!this._tokenManagementApi.areTokenResourcesNarrowedDown(token)) {
this._logger.warn("USING THE ADMIN TOKEN");
this._logger.info("It seems like you are using a admin API token. Since the token can be retrieven from the browser or " + "mobile apps by end user this can lead to your application being compromised, unless you understand what " + "are you doing. Please use Token Management API " + "(https://github.com/metaapi/metaapi-javascript-sdk/blob/master/docs/tokenManagementApi.md) in your " + "backend application to produce secure tokens which you can then use in web UI or mobile apps.");
}
}
}
};
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIjxhbm9uPiJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbmltcG9ydCBIdHRwQ2xpZW50IGZyb20gJy4uL2NsaWVudHMvaHR0cENsaWVudCc7XG5pbXBvcnQgUHJvdmlzaW9uaW5nUHJvZmlsZUNsaWVudCBmcm9tICcuLi9jbGllbnRzL21ldGFBcGkvcHJvdmlzaW9uaW5nUHJvZmlsZS5jbGllbnQnO1xuaW1wb3J0IFByb3Zpc2lvbmluZ1Byb2ZpbGVBcGkgZnJvbSAnLi9wcm92aXNpb25pbmdQcm9maWxlQXBpJztcbmltcG9ydCBNZXRhQXBpV2Vic29ja2V0Q2xpZW50IGZyb20gJy4uL2NsaWVudHMvbWV0YUFwaS9tZXRhQXBpV2Vic29ja2V0LmNsaWVudCc7XG5pbXBvcnQgTWV0YXRyYWRlckFjY291bnRBcGkgZnJvbSAnLi9tZXRhdHJhZGVyQWNjb3VudEFwaSc7XG5pbXBvcnQgTWV0YXRyYWRlckFjY291bnRDbGllbnQgZnJvbSAnLi4vY2xpZW50cy9tZXRhQXBpL21ldGF0cmFkZXJBY2NvdW50LmNsaWVudCc7XG5pbXBvcnQgTWV0YXRyYWRlckFjY291bnRHZW5lcmF0b3JBcGkgZnJvbSAnLi9tZXRhdHJhZGVyQWNjb3VudEdlbmVyYXRvckFwaSc7XG5pbXBvcnQgTWV0YXRyYWRlckFjY291bnRHZW5lcmF0b3JDbGllbnQgZnJvbSAnLi4vY2xpZW50cy9tZXRhQXBpL21ldGF0cmFkZXJBY2NvdW50R2VuZXJhdG9yLmNsaWVudCc7XG5pbXBvcnQgSGlzdG9yaWNhbE1hcmtldERhdGFDbGllbnQgZnJvbSAnLi4vY2xpZW50cy9tZXRhQXBpL2hpc3RvcmljYWxNYXJrZXREYXRhLmNsaWVudCc7XG5pbXBvcnQgQ2xpZW50QXBpQ2xpZW50IGZyb20gJy4uL2NsaWVudHMvbWV0YUFwaS9jbGllbnRBcGkuY2xpZW50JztcbmltcG9ydCBDb25uZWN0aW9uUmVnaXN0cnkgZnJvbSAnLi9jb25uZWN0aW9uUmVnaXN0cnknO1xuaW1wb3J0IHtWYWxpZGF0aW9uRXJyb3J9IGZyb20gJy4uL2NsaWVudHMvZXJyb3JIYW5kbGVyJztcbmltcG9ydCBPcHRpb25zVmFsaWRhdG9yIGZyb20gJy4uL2NsaWVudHMvb3B0aW9uc1ZhbGlkYXRvcic7XG5pbXBvcnQgTGF0ZW5jeU1vbml0b3IgZnJvbSAnLi9sYXRlbmN5TW9uaXRvcic7XG5pbXBvcnQgRXhwZXJ0QWR2aXNvckNsaWVudCBmcm9tICcuLi9jbGllbnRzL21ldGFBcGkvZXhwZXJ0QWR2aXNvci5jbGllbnQnO1xuaW1wb3J0IExvZ2dlck1hbmFnZXIgZnJvbSAnLi4vbG9nZ2VyJztcbmltcG9ydCBEb21haW5DbGllbnQgZnJvbSAnLi4vY2xpZW50cy9kb21haW4uY2xpZW50JztcbmltcG9ydCBUZXJtaW5hbEhhc2hNYW5hZ2VyIGZyb20gJy4vdGVybWluYWxIYXNoTWFuYWdlcic7XG5pbXBvcnQgVG9rZW5NYW5hZ2VtZW50Q2xpZW50IGZyb20gJy4uL2NsaWVudHMvbWV0YUFwaS90b2tlbk1hbmFnZW1lbnQuY2xpZW50JztcbmltcG9ydCBUb2tlbk1hbmFnZW1lbnRBcGkgZnJvbSAnLi90b2tlbk1hbmFnZW1lbnRBcGknO1xuaW1wb3J0IHtNZXRhQXBpT3B0c30gZnJvbSAnLi9tZXRhQXBpJztcbmltcG9ydCBfIGZyb20gJ2xvZGFzaCc7XG5cbi8qKlxuICogTWV0YUFwaSBNZXRhVHJhZGVyIEFQSSBTREtcbiAqL1xuZXhwb3J0IGRlZmF1bHQgY2xhc3MgTWV0YUFwaSB7XG5cbiAgLyoqXG4gICAqIEVuYWJsZXMgdXNpbmcgTG9nNGpzIGxvZ2dlciB3aXRoIGV4dGVuZGVkIGxvZyBsZXZlbHMgZm9yIGRlYnVnZ2luZyBpbnN0ZWFkIG9mXG4gICAqIGNvbnNvbGUuKiBmdW5jdGlvbnMuIE5vdGUgdGhhdCBsb2c0anMgY29uZmlndXJhdGlvbiBwZXJmb3JtZWQgYnkgdGhlIHVzZXIuXG4gICAqL1xuICBzdGF0aWMgZW5hYmxlTG9nNGpzTG9nZ2luZygpIHtcbiAgICBMb2dnZXJNYW5hZ2VyLnVzZUxvZzRqcygpO1xuICB9XG5cbiAgLyoqXG4gICAqIENvbnN0cnVjdHMgTWV0YUFwaSBjbGFzcyBpbnN0YW5jZVxuICAgKiBAcGFyYW0ge1N0cmluZ30gdG9rZW4gYXV0aG9yaXphdGlvbiB0b2tlblxuICAgKiBAcGFyYW0ge01ldGFBcGlPcHRzfSBvcHRzIGFwcGxpY2F0aW9uIG9wdGlvbnNcbiAgICovXG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBjb21wbGV4aXR5XG4gIGNvbnN0cnVjdG9yKHRva2VuLCBvcHRzKSB7XG4gICAgY29uc3QgdmFsaWRhdG9yID0gbmV3IE9wdGlvbnNWYWxpZGF0b3IoKTtcbiAgICBvcHRzID0gXy5vbWl0KG9wdHMgfHwge30sIFsnY29ubmVjdGlvbnMnXSk7XG4gICAgY29uc3QgYXBwbGljYXRpb24gPSBvcHRzLmFwcGxpY2F0aW9uIHx8ICdNZXRhQXBpJztcbiAgICBjb25zdCBkb21haW4gPSBvcHRzLmRvbWFpbiB8fCAnYWdpbGl1bXRyYWRlLmFnaWxpdW10cmFkZS5haSc7XG4gICAgY29uc3QgcmVxdWVzdFRpbWVvdXQgPSB2YWxpZGF0b3IudmFsaWRhdGVOb25aZXJvKG9wdHMucmVxdWVzdFRpbWVvdXQsIDYwLCAncmVxdWVzdFRpbWVvdXQnKTtcbiAgICBjb25zdCBoaXN0b3JpY2FsTWFya2V0RGF0YVJlcXVlc3RUaW1lb3V0ID0gdmFsaWRhdG9yLnZhbGlkYXRlTm9uWmVybyhcbiAgICAgIG9wdHMuaGlzdG9yaWNhbE1hcmtldERhdGFSZXF1ZXN0VGltZW91dCwgMjQwLCAnaGlzdG9yaWNhbE1hcmtldERhdGFSZXF1ZXN0VGltZW91dCcpO1xuICAgIGNvbnN0IGNvbm5lY3RUaW1lb3V0ID0gdmFsaWRhdG9yLnZhbGlkYXRlTm9uWmVybyhvcHRzLmNvbm5lY3RUaW1lb3V0LCA2MCwgJ2Nvbm5lY3RUaW1lb3V0Jyk7XG4gICAgY29uc3QgcGFja2V0T3JkZXJpbmdUaW1lb3V0ID0gdmFsaWRhdG9yLnZhbGlkYXRlTm9uWmVybyhvcHRzLnBhY2tldE9yZGVyaW5nVGltZW91dCwgNjAsICdwYWNrZXRPcmRlcmluZ1RpbWVvdXQnKTtcbiAgICBjb25zdCByZXRyeU9wdHMgPSBvcHRzLnJldHJ5T3B0cyB8fCB7fTtcbiAgICBjb25zdCBwYWNrZXRMb2dnZXIgPSBvcHRzLnBhY2tldExvZ2dlciB8fCB7fTtcbiAgICBjb25zdCBzeW5jaHJvbml6YXRpb25UaHJvdHRsZXIgPSBvcHRzLnN5bmNocm9uaXphdGlvblRocm90dGxlciB8fCB7fTtcbiAgICBjb25zdCBhY2NvdW50R2VuZXJhdG9yUmVxdWVzdFRpbWVvdXQgPSB2YWxpZGF0b3IudmFsaWRhdGVOb25aZXJvKG9wdHMuYWNjb3VudEdlbmVyYXRvclJlcXVlc3RUaW1lb3V0LCAyNDAsXG4gICAgICAnYWNjb3VudEdlbmVyYXRvclJlcXVlc3RUaW1lb3V0Jyk7XG4gICAgaWYgKCFhcHBsaWNhdGlvbi5tYXRjaCgvW2EtekEtWjAtOV9dKy8pKSB7XG4gICAgICB0aHJvdyBuZXcgVmFsaWRhdGlvbkVycm9yKCdBcHBsaWNhdGlvbiBuYW1lIG11c3QgYmUgbm9uLWVtcHR5IHN0cmluZyBjb25zaXN0aW5nIGZyb20gbGV0dGVycywgZGlnaXRzIGFuZCBfIG9ubHknKTtcbiAgICB9XG4gICAgY29uc3QgdXNlU2hhcmVkQ2xpZW50QXBpID0gb3B0cy51c2VTaGFyZWRDbGllbnRBcGkgfHwgZmFsc2U7XG4gICAgY29uc3QgcmVmcmVzaFN1YnNjcmlwdGlvbnNPcHRzID0gb3B0cy5yZWZyZXNoU3Vic2NyaXB0aW9uc09wdHMgfHwge307XG4gICAgY29uc3QgaHR0cENsaWVudCA9IG5ldyBIdHRwQ2xpZW50KHJlcXVlc3RUaW1lb3V0LCByZXRyeU9wdHMpO1xuICAgIGNvbnN0IGRvbWFpbkNsaWVudCA9IG5ldyBEb21haW5DbGllbnQoaHR0cENsaWVudCwgdG9rZW4sIGRvbWFpbik7XG4gICAgY29uc3QgaGlzdG9yaWNhbE1hcmtldERhdGFIdHRwQ2xpZW50ID0gbmV3IEh0dHBDbGllbnQoaGlzdG9yaWNhbE1hcmtldERhdGFSZXF1ZXN0VGltZW91dCwgcmV0cnlPcHRzKTtcbiAgICBjb25zdCBhY2NvdW50R2VuZXJhdG9ySHR0cENsaWVudCA9IG5ldyBIdHRwQ2xpZW50KGFjY291bnRHZW5lcmF0b3JSZXF1ZXN0VGltZW91dCwgcmV0cnlPcHRzKTtcbiAgICBjb25zdCBjbGllbnRBcGlDbGllbnQgPSBuZXcgQ2xpZW50QXBpQ2xpZW50KGh0dHBDbGllbnQsIGRvbWFpbkNsaWVudCk7IFxuICAgIGNvbnN0IHRva2VuTWFuYWdtZW50Q2xpZW50ID0gbmV3IFRva2VuTWFuYWdlbWVudENsaWVudChodHRwQ2xpZW50LCBkb21haW5DbGllbnQpOyBcbiAgICB0aGlzLl90ZXJtaW5hbEhhc2hNYW5hZ2VyID0gbmV3IFRlcm1pbmFsSGFzaE1hbmFnZXIoY2xpZW50QXBpQ2xpZW50LCBvcHRzLmtlZXBIYXNoVHJlZXMpO1xuICAgIHRoaXMuX21ldGFBcGlXZWJzb2NrZXRDbGllbnQgPSBuZXcgTWV0YUFwaVdlYnNvY2tldENsaWVudCh0aGlzLCBkb21haW5DbGllbnQsIHRva2VuLCB7XG4gICAgICBhcHBsaWNhdGlvbiwgZG9tYWluLFxuICAgICAgcmVxdWVzdFRpbWVvdXQsIGNvbm5lY3RUaW1lb3V0LCBwYWNrZXRMb2dnZXIsIHBhY2tldE9yZGVyaW5nVGltZW91dCwgc3luY2hyb25pemF0aW9uVGhyb3R0bGVyLCByZXRyeU9wdHMsXG4gICAgICB1c2VTaGFyZWRDbGllbnRBcGksIHJlZ2lvbjogb3B0cy5yZWdpb24sXG4gICAgICB1bnN1YnNjcmliZVRocm90dGxpbmdJbnRlcnZhbEluU2Vjb25kczogb3B0cy51bnN1YnNjcmliZVRocm90dGxpbmdJbnRlcnZhbEluU2Vjb25kcyxcbiAgICAgIHVzZU5hdGl2ZVNvY2tldElvU2VydmVyOiBvcHRzLnVzZU5hdGl2ZVNvY2tldElvU2VydmVyXG4gICAgfSk7XG4gICAgdGhpcy5fcHJvdmlzaW9uaW5nUHJvZmlsZUFwaSA9IG5ldyBQcm92aXNpb25pbmdQcm9maWxlQXBpKG5ldyBQcm92aXNpb25pbmdQcm9maWxlQ2xpZW50KGh0dHBDbGllbnQsIGRvbWFpbkNsaWVudCkpO1xuICAgIHRoaXMuX2Nvbm5lY3Rpb25SZWdpc3RyeSA9IG5ldyBDb25uZWN0aW9uUmVnaXN0cnkob3B0cywgdGhpcy5fbWV0YUFwaVdlYnNvY2tldENsaWVudCwgdGhpcy5fdGVybWluYWxIYXNoTWFuYWdlcixcbiAgICAgIGFwcGxpY2F0aW9uLCByZWZyZXNoU3Vic2NyaXB0aW9uc09wdHMpO1xuICAgIGxldCBoaXN0b3JpY2FsTWFya2V0RGF0YUNsaWVudCA9IG5ldyBIaXN0b3JpY2FsTWFya2V0RGF0YUNsaWVudChoaXN0b3JpY2FsTWFya2V0RGF0YUh0dHBDbGllbnQsIGRvbWFpbkNsaWVudCk7XG4gICAgdGhpcy5fbWV0YXRyYWRlckFjY291bnRBcGkgPSBuZXcgTWV0YXRyYWRlckFjY291bnRBcGkobmV3IE1ldGF0cmFkZXJBY2NvdW50Q2xpZW50KGh0dHBDbGllbnQsIGRvbWFpbkNsaWVudCksXG4gICAgICB0aGlzLl9tZXRhQXBpV2Vic29ja2V0Q2xpZW50LCB0aGlzLl9jb25uZWN0aW9uUmVnaXN0cnksIFxuICAgICAgbmV3IEV4cGVydEFkdmlzb3JDbGllbnQoaHR0cENsaWVudCwgZG9tYWluQ2xpZW50KSwgaGlzdG9yaWNhbE1hcmtldERhdGFDbGllbnQsIGFwcGxpY2F0aW9uKTtcbiAgICB0aGlzLl9tZXRhdHJhZGVyQWNjb3VudEdlbmVyYXRvckFwaSA9IG5ldyBNZXRhdHJhZGVyQWNjb3VudEdlbmVyYXRvckFwaShcbiAgICAgIG5ldyBNZXRhdHJhZGVyQWNjb3VudEdlbmVyYXRvckNsaWVudChhY2NvdW50R2VuZXJhdG9ySHR0cENsaWVudCwgZG9tYWluQ2xpZW50KSk7XG4gICAgdGhpcy5fdG9rZW5NYW5hZ2VtZW50QXBpID0gbmV3IFRva2VuTWFuYWdlbWVudEFwaSh0b2tlbk1hbmFnbWVudENsaWVudCk7XG4gICAgaWYgKG9wdHMuZW5hYmxlTGF0ZW5jeVRyYWNraW5nIHx8IG9wdHMuZW5hYmxlTGF0ZW5jeU1vbml0b3IpIHtcbiAgICAgIHRoaXMuX2xhdGVuY3lNb25pdG9yID0gbmV3IExhdGVuY3lNb25pdG9yKCk7XG4gICAgICB0aGlzLl9tZXRhQXBpV2Vic29ja2V0Q2xpZW50LmFkZExhdGVuY3lMaXN0ZW5lcih0aGlzLl9sYXRlbmN5TW9uaXRvcik7XG4gICAgfVxuICAgIFxuICAgIHRoaXMuX2xvZ2dlciA9IExvZ2dlck1hbmFnZXIuZ2V0TG9nZ2VyKCdNZXRhQVBJJyk7XG4gICAgaWYgKHByb2Nlc3MuZW52LklTX0JST1dTRVIpIHtcbiAgICAgIGlmICghdGhpcy5fdG9rZW5NYW5hZ2VtZW50QXBpLmFyZVRva2VuUmVzb3VyY2VzTmFycm93ZWREb3duKHRva2VuKSkge1xuICAgICAgICB0aGlzLl9sb2dnZXIud2FybignVVNJTkcgVEhFIEFETUlOIFRPS0VOJyk7XG4gICAgICAgIHRoaXMuX2xvZ2dlci5pbmZvKFxuICAgICAgICAgICdJdCBzZWVtcyBsaWtlIHlvdSBhcmUgdXNpbmcgYSBhZG1pbiBBUEkgdG9rZW4uIFNpbmNlIHRoZSB0b2tlbiBjYW4gYmUgcmV0cmlldmVuIGZyb20gdGhlIGJyb3dzZXIgb3IgJyArXG4gICAgICAgICAgJ21vYmlsZSBhcHBzIGJ5IGVuZCB1c2VyIHRoaXMgY2FuIGxlYWQgdG8geW91ciBhcHBsaWNhdGlvbiBiZWluZyBjb21wcm9taXNlZCwgdW5sZXNzIHlvdSB1bmRlcnN0YW5kIHdoYXQgJyArXG4gICAgICAgICAgJ2FyZSB5b3UgZG9pbmcuIFBsZWFzZSB1c2UgVG9rZW4gTWFuYWdlbWVudCBBUEkgJyArXG4gICAgICAgICAgJyhodHRwczovL2dpdGh1Yi5jb20vbWV0YWFwaS9tZXRhYXBpLWphdmFzY3JpcHQtc2RrL2Jsb2IvbWFzdGVyL2RvY3MvdG9rZW5NYW5hZ2VtZW50QXBpLm1kKSBpbiB5b3VyICcgK1xuICAgICAgICAgICdiYWNrZW5kIGFwcGxpY2F0aW9uIHRvIHByb2R1Y2Ugc2VjdXJlIHRva2VucyB3aGljaCB5b3UgY2FuIHRoZW4gdXNlIGluIHdlYiBVSSBvciBtb2JpbGUgYXBwcy4nXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgcHJvdmlzaW9uaW5nIHByb2ZpbGUgQVBJXG4gICAqIEByZXR1cm5zIHtQcm92aXNpb25pbmdQcm9maWxlQXBpfSBwcm92aXNpb25pbmcgcHJvZmlsZSBBUElcbiAgICovXG4gIGdldCBwcm92aXNpb25pbmdQcm9maWxlQXBpKCkge1xuICAgIHJldHVybiB0aGlzLl9wcm92aXNpb25pbmdQcm9maWxlQXBpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgTWV0YVRyYWRlciBhY2NvdW50IEFQSVxuICAgKiBAcmV0dXJuIHtNZXRhdHJhZGVyQWNjb3VudEFwaX0gTWV0YVRyYWRlciBhY2NvdW50IEFQSVxuICAgKi9cbiAgZ2V0IG1ldGF0cmFkZXJBY2NvdW50QXBpKCkge1xuICAgIHJldHVybiB0aGlzLl9tZXRhdHJhZGVyQWNjb3VudEFwaTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIE1ldGFUcmFkZXIgYWNjb3VudCBnZW5lcmF0b3IgQVBJXG4gICAqIEByZXR1cm4ge01ldGF0cmFkZXJEZW1vQWNjb3VudEFwaX0gTWV0YVRyYWRlciBhY2NvdW50IGdlbmVyYXRvciBBUElcbiAgICovXG4gIGdldCBtZXRhdHJhZGVyQWNjb3VudEdlbmVyYXRvckFwaSgpIHtcbiAgICByZXR1cm4gdGhpcy5fbWV0YXRyYWRlckFjY291bnRHZW5lcmF0b3JBcGk7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyBNZXRhQXBpIGFwcGxpY2F0aW9uIGxhdGVuY3kgbW9uaXRvclxuICAgKiBAcmV0dXJuIHtMYXRlbmN5TW9uaXRvcn0gbGF0ZW5jeSBtb25pdG9yXG4gICAqL1xuICBnZXQgbGF0ZW5jeU1vbml0b3IoKSB7XG4gICAgcmV0dXJuIHRoaXMuX2xhdGVuY3lNb25pdG9yO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgdG9rZW4gbWFuYWdlbWVudCBBUElcbiAgICogQHJldHVybnMge1Rva2VuTWFuYWdlbWVudEFwaX0gdG9rZW4gbWFuYWdlbWVudCBBUElcbiAgICovXG4gIGdldCB0b2tlbk1hbmFnZW1lbnRBcGkoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3Rva2VuTWFuYWdlbWVudEFwaTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDbG9zZXMgYWxsIGNsaWVudHMgYW5kIGNvbm5lY3Rpb25zIGFuZCBzdG9wcyBhbGwgaW50ZXJuYWwgam9ic1xuICAgKi9cbiAgY2xvc2UoKSB7XG4gICAgdGhpcy5fbWV0YUFwaVdlYnNvY2tldENsaWVudC5yZW1vdmVMYXRlbmN5TGlzdGVuZXIodGhpcy5fbGF0ZW5jeU1vbml0b3IpO1xuICAgIHRoaXMuX21ldGFBcGlXZWJzb2NrZXRDbGllbnQuY2xvc2UoKTtcbiAgICB0aGlzLl9tZXRhQXBpV2Vic29ja2V0Q2xpZW50LnN0b3AoKTtcbiAgICB0aGlzLl90ZXJtaW5hbEhhc2hNYW5hZ2VyLl9zdG9wKCk7XG4gIH1cbn1cbiJdLCJuYW1lcyI6WyJNZXRhQXBpIiwiZW5hYmxlTG9nNGpzTG9nZ2luZyIsIkxvZ2dlck1hbmFnZXIiLCJ1c2VMb2c0anMiLCJwcm92aXNpb25pbmdQcm9maWxlQXBpIiwiX3Byb3Zpc2lvbmluZ1Byb2ZpbGVBcGkiLCJtZXRhdHJhZGVyQWNjb3VudEFwaSIsIl9tZXRhdHJhZGVyQWNjb3VudEFwaSIsIm1ldGF0cmFkZXJBY2NvdW50R2VuZXJhdG9yQXBpIiwiX21ldGF0cmFkZXJBY2NvdW50R2VuZXJhdG9yQXBpIiwibGF0ZW5jeU1vbml0b3IiLCJfbGF0ZW5jeU1vbml0b3IiLCJ0b2tlbk1hbmFnZW1lbnRBcGkiLCJfdG9rZW5NYW5hZ2VtZW50QXBpIiwiY2xvc2UiLCJfbWV0YUFwaVdlYnNvY2tldENsaWVudCIsInJlbW92ZUxhdGVuY3lMaXN0ZW5lciIsInN0b3AiLCJfdGVybWluYWxIYXNoTWFuYWdlciIsIl9zdG9wIiwiY29uc3RydWN0b3IiLCJ0b2tlbiIsIm9wdHMiLCJ2YWxpZGF0b3IiLCJPcHRpb25zVmFsaWRhdG9yIiwiXyIsIm9taXQiLCJhcHBsaWNhdGlvbiIsImRvbWFpbiIsInJlcXVlc3RUaW1lb3V0IiwidmFsaWRhdGVOb25aZXJvIiwiaGlzdG9yaWNhbE1hcmtldERhdGFSZXF1ZXN0VGltZW91dCIsImNvbm5lY3RUaW1lb3V0IiwicGFja2V0T3JkZXJpbmdUaW1lb3V0IiwicmV0cnlPcHRzIiwicGFja2V0TG9nZ2VyIiwic3luY2hyb25pemF0aW9uVGhyb3R0bGVyIiwiYWNjb3VudEdlbmVyYXRvclJlcXVlc3RUaW1lb3V0IiwibWF0Y2giLCJWYWxpZGF0aW9uRXJyb3IiLCJ1c2VTaGFyZWRDbGllbnRBcGkiLCJyZWZyZXNoU3Vic2NyaXB0aW9uc09wdHMiLCJodHRwQ2xpZW50IiwiSHR0cENsaWVudCIsImRvbWFpbkNsaWVudCIsIkRvbWFpbkNsaWVudCIsImhpc3RvcmljYWxNYXJrZXREYXRhSHR0cENsaWVudCIsImFjY291bnRHZW5lcmF0b3JIdHRwQ2xpZW50IiwiY2xpZW50QXBpQ2xpZW50IiwiQ2xpZW50QXBpQ2xpZW50IiwidG9rZW5NYW5hZ21lbnRDbGllbnQiLCJUb2tlbk1hbmFnZW1lbnRDbGllbnQiLCJUZXJtaW5hbEhhc2hNYW5hZ2VyIiwia2VlcEhhc2hUcmVlcyIsIk1ldGFBcGlXZWJzb2NrZXRDbGllbnQiLCJyZWdpb24iLCJ1bnN1YnNjcmliZVRocm90dGxpbmdJbnRlcnZhbEluU2Vjb25kcyIsInVzZU5hdGl2ZVNvY2tldElvU2VydmVyIiwiUHJvdmlzaW9uaW5nUHJvZmlsZUFwaSIsIlByb3Zpc2lvbmluZ1Byb2ZpbGVDbGllbnQiLCJfY29ubmVjdGlvblJlZ2lzdHJ5IiwiQ29ubmVjdGlvblJlZ2lzdHJ5IiwiaGlzdG9yaWNhbE1hcmtldERhdGFDbGllbnQiLCJIaXN0b3JpY2FsTWFya2V0RGF0YUNsaWVudCIsIk1ldGF0cmFkZXJBY2NvdW50QXBpIiwiTWV0YXRyYWRlckFjY291bnRDbGllbnQiLCJFeHBlcnRBZHZpc29yQ2xpZW50IiwiTWV0YXRyYWRlckFjY291bnRHZW5lcmF0b3JBcGkiLCJNZXRhdHJhZGVyQWNjb3VudEdlbmVyYXRvckNsaWVudCIsIlRva2VuTWFuYWdlbWVudEFwaSIsImVuYWJsZUxhdGVuY3lUcmFja2luZyIsImVuYWJsZUxhdGVuY3lNb25pdG9yIiwiTGF0ZW5jeU1vbml0b3IiLCJhZGRMYXRlbmN5TGlzdGVuZXIiLCJfbG9nZ2VyIiwiZ2V0TG9nZ2VyIiwicHJvY2VzcyIsImVudiIsIklTX0JST1dTRVIiLCJhcmVUb2tlblJlc291cmNlc05hcnJvd2VkRG93biIsIndhcm4iLCJpbmZvIl0sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7OztlQTRCcUJBOzs7bUVBMUJFO2tGQUNlOytFQUNIOytFQUNBOzZFQUNGO2dGQUNHO3NGQUNNO3lGQUNHO21GQUNOO3dFQUNYOzJFQUNHOzhCQUNEO3lFQUNEO3VFQUNGOzRFQUNLOytEQUNOO3FFQUNEOzRFQUNPOzhFQUNFOzJFQUNIOytEQUVqQjs7Ozs7O0FBS0MsSUFBQSxBQUFNQSxVQUFOLE1BQU1BO0lBRW5COzs7R0FHQyxHQUNELE9BQU9DLHNCQUFzQjtRQUMzQkMsZUFBYSxDQUFDQyxTQUFTO0lBQ3pCO0lBd0VBOzs7R0FHQyxHQUNELElBQUlDLHlCQUF5QjtRQUMzQixPQUFPLElBQUksQ0FBQ0MsdUJBQXVCO0lBQ3JDO0lBRUE7OztHQUdDLEdBQ0QsSUFBSUMsdUJBQXVCO1FBQ3pCLE9BQU8sSUFBSSxDQUFDQyxxQkFBcUI7SUFDbkM7SUFFQTs7O0dBR0MsR0FDRCxJQUFJQyxnQ0FBZ0M7UUFDbEMsT0FBTyxJQUFJLENBQUNDLDhCQUE4QjtJQUM1QztJQUVBOzs7R0FHQyxHQUNELElBQUlDLGlCQUFpQjtRQUNuQixPQUFPLElBQUksQ0FBQ0MsZUFBZTtJQUM3QjtJQUVBOzs7R0FHQyxHQUNELElBQUlDLHFCQUFxQjtRQUN2QixPQUFPLElBQUksQ0FBQ0MsbUJBQW1CO0lBQ2pDO0lBRUE7O0dBRUMsR0FDREMsUUFBUTtRQUNOLElBQUksQ0FBQ0MsdUJBQXVCLENB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