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)
149 lines (148 loc) • 17 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "default", {
enumerable: true,
get: function() {
return ExpertAdvisorClient;
}
});
const _metaApiclient = /*#__PURE__*/ _interop_require_default(require("../metaApi.client"));
const _formdata = /*#__PURE__*/ _interop_require_default(require("form-data"));
const _fs = /*#__PURE__*/ _interop_require_default(require("fs"));
function _interop_require_default(obj) {
return obj && obj.__esModule ? obj : {
default: obj
};
}
let ExpertAdvisorClient = class ExpertAdvisorClient extends _metaApiclient.default {
/**
* Expert advisor model
* @typedef {Object} ExpertAdvisorDto
* @property {String} expertId expert advisor id
* @property {String} period expert advisor period
* @property {String} symbol expert advisor symbol
* @property {Boolean} fileUploaded true if expert file was uploaded
*/ /**
* Retrieves expert advisors by account id (see
* https://metaapi.cloud/docs/provisioning/api/expertAdvisor/readExpertAdvisors/)
* Method is accessible only with API access token
* @param {String} accountId Metatrader account id
* @returns {Promise<ExpertAdvisorDto[]>} promise resolving with expert advisors found
*/ getExpertAdvisors(accountId) {
if (this._isNotJwtToken()) {
return this._handleNoAccessError("getExpertAdvisors");
}
const opts = {
url: `${this._host}/users/current/accounts/${accountId}/expert-advisors`,
method: "GET",
headers: {
"auth-token": this._token
},
json: true
};
return this._httpClient.request(opts, "getExpertAdvisors");
}
/**
* Retrieves an expert advisor by id (see
* https://metaapi.cloud/docs/provisioning/api/expertAdvisor/readExpertAdvisor/).
* Thrown an error if expert is not found. Method is accessible only with API access token
* @param {String} accountId Metatrader account id
* @param {String} expertId expert advisor id
* @returns {Promise<ExpertAdvisorDto>} promise resolving with expert advisor found
*/ getExpertAdvisor(accountId, expertId) {
if (this._isNotJwtToken()) {
return this._handleNoAccessError("getExpertAdvisor");
}
const opts = {
url: `${this._host}/users/current/accounts/${accountId}/expert-advisors/${expertId}`,
method: "GET",
headers: {
"auth-token": this._token
},
json: true
};
return this._httpClient.request(opts, "getExpertAdvisor");
}
/**
* Updated expert advisor data
* @typedef {Object} NewExpertAdvisorDto
* @property {String} period expert advisor symbol.
* For MetaTrader 4 allowed periods are 1m, 5m, 15m, 30m, 1h, 4h, 1d, 1w, 1mn
* For MetaTrader 5 allowed periods are 1m, 2m, 3m, 4m, 5m, 6m, 10m, 12m, 15m, 20m, 30m, 1h, 2h, 3h, 4h, 6h, 8h, 12h,
* 1d, 1w, 1mn
* @property {String} symbol expert advisor period
* @property {String} preset base64-encoded preset file
*/ /**
* Updates or creates expert advisor data (see
* https://metaapi.cloud/docs/provisioning/api/expertAdvisor/updateExpertAdvisor/).
* Method is accessible only with API access token
* @param {String} accountId Metatrader account id
* @param {String} expertId expert id
* @param {NewExpertAdvisorDto} expert new expert advisor data
* @returns {Promise} promise resolving when expert advisor is updated
*/ updateExpertAdvisor(accountId, expertId, expert) {
if (this._isNotJwtToken()) {
return this._handleNoAccessError("updateExpertAdvisor");
}
const opts = {
url: `${this._host}/users/current/accounts/${accountId}/expert-advisors/${expertId}`,
method: "PUT",
headers: {
"auth-token": this._token
},
json: true,
data: expert
};
return this._httpClient.request(opts, "updateExpertAdvisor");
}
/**
* Uploads an expert advisor file (see https://metaapi.cloud/docs/provisioning/api/expertAdvisor/uploadEAFile/)
* Method is accessible only with API access token
* @param {String} accountId Metatrader account id
* @param {String} expertId expert id
* @param {String|Buffer} file path to a file to upload or buffer containing file contents
* @returns {Promise} promise resolving when file upload is completed
*/ uploadExpertAdvisorFile(accountId, expertId, file) {
if (this._isNotJwtToken()) {
return this._handleNoAccessError("uploadExpertAdvisorFile");
}
if (typeof file === "string") {
file = _fs.default.createReadStream(file);
}
const formData = new _formdata.default();
formData.append("file", file);
const opts = {
method: "PUT",
url: `${this._host}/users/current/accounts/${accountId}/expert-advisors/${expertId}/file`,
data: formData,
headers: {
...formData.getHeaders(),
"auth-token": this._token
}
};
return this._httpClient.request(opts, "uploadExpertAdvisorFile");
}
/**
* Deletes an expert advisor (see https://metaapi.cloud/docs/provisioning/api/expertAdvisor/deleteExpertAdvisor/)
* Method is accessible only with API access token
* @param {String} accountId Metatrader account id
* @param {String} expertId expert id
* @returns {Promise} promise resolving when expert advisor is deleted
*/ deleteExpertAdvisor(accountId, expertId) {
if (this._isNotJwtToken()) {
return this._handleNoAccessError("deleteExpertAdvisor");
}
const opts = {
url: `${this._host}/users/current/accounts/${accountId}/expert-advisors/${expertId}`,
method: "DELETE",
headers: {
"auth-token": this._token
},
json: true
};
return this._httpClient.request(opts, "deleteExpertAdvisor");
}
};
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIjxhbm9uPiJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbmltcG9ydCBNZXRhQXBpQ2xpZW50IGZyb20gJy4uL21ldGFBcGkuY2xpZW50JztcbmltcG9ydCBGb3JtRGF0YSBmcm9tICdmb3JtLWRhdGEnO1xuaW1wb3J0IGZzIGZyb20gJ2ZzJztcblxuLyoqXG4gKiBtZXRhYXBpLmNsb3VkIGV4cGVydCBhZHZpc29yIEFQSSBjbGllbnQgKHNlZSBodHRwczovL21ldGFhcGkuY2xvdWQvZG9jcy9wcm92aXNpb25pbmcvKVxuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBFeHBlcnRBZHZpc29yQ2xpZW50IGV4dGVuZHMgTWV0YUFwaUNsaWVudCB7XG5cbiAgLyoqXG4gICAqIEV4cGVydCBhZHZpc29yIG1vZGVsXG4gICAqIEB0eXBlZGVmIHtPYmplY3R9IEV4cGVydEFkdmlzb3JEdG9cbiAgICogQHByb3BlcnR5IHtTdHJpbmd9IGV4cGVydElkIGV4cGVydCBhZHZpc29yIGlkXG4gICAqIEBwcm9wZXJ0eSB7U3RyaW5nfSBwZXJpb2QgZXhwZXJ0IGFkdmlzb3IgcGVyaW9kXG4gICAqIEBwcm9wZXJ0eSB7U3RyaW5nfSBzeW1ib2wgZXhwZXJ0IGFkdmlzb3Igc3ltYm9sXG4gICAqIEBwcm9wZXJ0eSB7Qm9vbGVhbn0gZmlsZVVwbG9hZGVkIHRydWUgaWYgZXhwZXJ0IGZpbGUgd2FzIHVwbG9hZGVkXG4gICAqL1xuXG4gIC8qKlxuICAgKiBSZXRyaWV2ZXMgZXhwZXJ0IGFkdmlzb3JzIGJ5IGFjY291bnQgaWQgKHNlZVxuICAgKiBodHRwczovL21ldGFhcGkuY2xvdWQvZG9jcy9wcm92aXNpb25pbmcvYXBpL2V4cGVydEFkdmlzb3IvcmVhZEV4cGVydEFkdmlzb3JzLylcbiAgICogTWV0aG9kIGlzIGFjY2Vzc2libGUgb25seSB3aXRoIEFQSSBhY2Nlc3MgdG9rZW5cbiAgICogQHBhcmFtIHtTdHJpbmd9IGFjY291bnRJZCBNZXRhdHJhZGVyIGFjY291bnQgaWRcbiAgICogQHJldHVybnMge1Byb21pc2U8RXhwZXJ0QWR2aXNvckR0b1tdPn0gcHJvbWlzZSByZXNvbHZpbmcgd2l0aCBleHBlcnQgYWR2aXNvcnMgZm91bmRcbiAgICovXG4gIGdldEV4cGVydEFkdmlzb3JzKGFjY291bnRJZCkge1xuICAgIGlmICh0aGlzLl9pc05vdEp3dFRva2VuKCkpIHtcbiAgICAgIHJldHVybiB0aGlzLl9oYW5kbGVOb0FjY2Vzc0Vycm9yKCdnZXRFeHBlcnRBZHZpc29ycycpO1xuICAgIH1cbiAgICBjb25zdCBvcHRzID0ge1xuICAgICAgdXJsOiBgJHt0aGlzLl9ob3N0fS91c2Vycy9jdXJyZW50L2FjY291bnRzLyR7YWNjb3VudElkfS9leHBlcnQtYWR2aXNvcnNgLFxuICAgICAgbWV0aG9kOiAnR0VUJyxcbiAgICAgIGhlYWRlcnM6IHtcbiAgICAgICAgJ2F1dGgtdG9rZW4nOiB0aGlzLl90b2tlblxuICAgICAgfSxcbiAgICAgIGpzb246IHRydWVcbiAgICB9O1xuICAgIHJldHVybiB0aGlzLl9odHRwQ2xpZW50LnJlcXVlc3Qob3B0cywgJ2dldEV4cGVydEFkdmlzb3JzJyk7XG4gIH1cblxuICAvKipcbiAgICogUmV0cmlldmVzIGFuIGV4cGVydCBhZHZpc29yIGJ5IGlkIChzZWVcbiAgICogaHR0cHM6Ly9tZXRhYXBpLmNsb3VkL2RvY3MvcHJvdmlzaW9uaW5nL2FwaS9leHBlcnRBZHZpc29yL3JlYWRFeHBlcnRBZHZpc29yLykuXG4gICAqIFRocm93biBhbiBlcnJvciBpZiBleHBlcnQgaXMgbm90IGZvdW5kLiBNZXRob2QgaXMgYWNjZXNzaWJsZSBvbmx5IHdpdGggQVBJIGFjY2VzcyB0b2tlblxuICAgKiBAcGFyYW0ge1N0cmluZ30gYWNjb3VudElkIE1ldGF0cmFkZXIgYWNjb3VudCBpZFxuICAgKiBAcGFyYW0ge1N0cmluZ30gZXhwZXJ0SWQgZXhwZXJ0IGFkdmlzb3IgaWRcbiAgICogQHJldHVybnMge1Byb21pc2U8RXhwZXJ0QWR2aXNvckR0bz59IHByb21pc2UgcmVzb2x2aW5nIHdpdGggZXhwZXJ0IGFkdmlzb3IgZm91bmRcbiAgICovXG4gIGdldEV4cGVydEFkdmlzb3IoYWNjb3VudElkLCBleHBlcnRJZCkge1xuICAgIGlmICh0aGlzLl9pc05vdEp3dFRva2VuKCkpIHtcbiAgICAgIHJldHVybiB0aGlzLl9oYW5kbGVOb0FjY2Vzc0Vycm9yKCdnZXRFeHBlcnRBZHZpc29yJyk7XG4gICAgfVxuICAgIGNvbnN0IG9wdHMgPSB7XG4gICAgICB1cmw6IGAke3RoaXMuX2hvc3R9L3VzZXJzL2N1cnJlbnQvYWNjb3VudHMvJHthY2NvdW50SWR9L2V4cGVydC1hZHZpc29ycy8ke2V4cGVydElkfWAsXG4gICAgICBtZXRob2Q6ICdHRVQnLFxuICAgICAgaGVhZGVyczoge1xuICAgICAgICAnYXV0aC10b2tlbic6IHRoaXMuX3Rva2VuXG4gICAgICB9LFxuICAgICAganNvbjogdHJ1ZVxuICAgIH07XG4gICAgcmV0dXJuIHRoaXMuX2h0dHBDbGllbnQucmVxdWVzdChvcHRzLCAnZ2V0RXhwZXJ0QWR2aXNvcicpO1xuICB9XG5cbiAgLyoqXG4gICAqIFVwZGF0ZWQgZXhwZXJ0IGFkdmlzb3IgZGF0YVxuICAgKiBAdHlwZWRlZiB7T2JqZWN0fSBOZXdFeHBlcnRBZHZpc29yRHRvXG4gICAqIEBwcm9wZXJ0eSB7U3RyaW5nfSBwZXJpb2QgZXhwZXJ0IGFkdmlzb3Igc3ltYm9sLlxuICAgKiBGb3IgTWV0YVRyYWRlciA0IGFsbG93ZWQgcGVyaW9kcyBhcmUgMW0sIDVtLCAxNW0sIDMwbSwgMWgsIDRoLCAxZCwgMXcsIDFtblxuICAgKiBGb3IgTWV0YVRyYWRlciA1IGFsbG93ZWQgcGVyaW9kcyBhcmUgMW0sIDJtLCAzbSwgNG0sIDVtLCA2bSwgMTBtLCAxMm0sIDE1bSwgMjBtLCAzMG0sIDFoLCAyaCwgM2gsIDRoLCA2aCwgOGgsIDEyaCxcbiAgICogMWQsIDF3LCAxbW5cbiAgICogQHByb3BlcnR5IHtTdHJpbmd9IHN5bWJvbCBleHBlcnQgYWR2aXNvciBwZXJpb2RcbiAgICogQHByb3BlcnR5IHtTdHJpbmd9IHByZXNldCBiYXNlNjQtZW5jb2RlZCBwcmVzZXQgZmlsZVxuICAgKi9cblxuICAvKipcbiAgICogVXBkYXRlcyBvciBjcmVhdGVzIGV4cGVydCBhZHZpc29yIGRhdGEgKHNlZVxuICAgKiBodHRwczovL21ldGFhcGkuY2xvdWQvZG9jcy9wcm92aXNpb25pbmcvYXBpL2V4cGVydEFkdmlzb3IvdXBkYXRlRXhwZXJ0QWR2aXNvci8pLlxuICAgKiBNZXRob2QgaXMgYWNjZXNzaWJsZSBvbmx5IHdpdGggQVBJIGFjY2VzcyB0b2tlblxuICAgKiBAcGFyYW0ge1N0cmluZ30gYWNjb3VudElkIE1ldGF0cmFkZXIgYWNjb3VudCBpZFxuICAgKiBAcGFyYW0ge1N0cmluZ30gZXhwZXJ0SWQgZXhwZXJ0IGlkXG4gICAqIEBwYXJhbSB7TmV3RXhwZXJ0QWR2aXNvckR0b30gZXhwZXJ0IG5ldyBleHBlcnQgYWR2aXNvciBkYXRhXG4gICAqIEByZXR1cm5zIHtQcm9taXNlfSBwcm9taXNlIHJlc29sdmluZyB3aGVuIGV4cGVydCBhZHZpc29yIGlzIHVwZGF0ZWRcbiAgICovXG4gIHVwZGF0ZUV4cGVydEFkdmlzb3IoYWNjb3VudElkLCBleHBlcnRJZCwgZXhwZXJ0KSB7XG4gICAgaWYgKHRoaXMuX2lzTm90Snd0VG9rZW4oKSkge1xuICAgICAgcmV0dXJuIHRoaXMuX2hhbmRsZU5vQWNjZXNzRXJyb3IoJ3VwZGF0ZUV4cGVydEFkdmlzb3InKTtcbiAgICB9XG4gICAgY29uc3Qgb3B0cyA9IHtcbiAgICAgIHVybDogYCR7dGhpcy5faG9zdH0vdXNlcnMvY3VycmVudC9hY2NvdW50cy8ke2FjY291bnRJZH0vZXhwZXJ0LWFkdmlzb3JzLyR7ZXhwZXJ0SWR9YCxcbiAgICAgIG1ldGhvZDogJ1BVVCcsXG4gICAgICBoZWFkZXJzOiB7XG4gICAgICAgICdhdXRoLXRva2VuJzogdGhpcy5fdG9rZW5cbiAgICAgIH0sXG4gICAgICBqc29uOiB0cnVlLFxuICAgICAgZGF0YTogZXhwZXJ0XG4gICAgfTtcbiAgICByZXR1cm4gdGhpcy5faHR0cENsaWVudC5yZXF1ZXN0KG9wdHMsICd1cGRhdGVFeHBlcnRBZHZpc29yJyk7XG4gIH1cblxuICAvKipcbiAgICogVXBsb2FkcyBhbiBleHBlcnQgYWR2aXNvciBmaWxlIChzZWUgaHR0cHM6Ly9tZXRhYXBpLmNsb3VkL2RvY3MvcHJvdmlzaW9uaW5nL2FwaS9leHBlcnRBZHZpc29yL3VwbG9hZEVBRmlsZS8pXG4gICAqIE1ldGhvZCBpcyBhY2Nlc3NpYmxlIG9ubHkgd2l0aCBBUEkgYWNjZXNzIHRva2VuXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBhY2NvdW50SWQgTWV0YXRyYWRlciBhY2NvdW50IGlkXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBleHBlcnRJZCBleHBlcnQgaWRcbiAgICogQHBhcmFtIHtTdHJpbmd8QnVmZmVyfSBmaWxlIHBhdGggdG8gYSBmaWxlIHRvIHVwbG9hZCBvciBidWZmZXIgY29udGFpbmluZyBmaWxlIGNvbnRlbnRzXG4gICAqIEByZXR1cm5zIHtQcm9taXNlfSBwcm9taXNlIHJlc29sdmluZyB3aGVuIGZpbGUgdXBsb2FkIGlzIGNvbXBsZXRlZFxuICAgKi9cbiAgdXBsb2FkRXhwZXJ0QWR2aXNvckZpbGUoYWNjb3VudElkLCBleHBlcnRJZCwgZmlsZSkge1xuICAgIGlmICh0aGlzLl9pc05vdEp3dFRva2VuKCkpIHtcbiAgICAgIHJldHVybiB0aGlzLl9oYW5kbGVOb0FjY2Vzc0Vycm9yKCd1cGxvYWRFeHBlcnRBZHZpc29yRmlsZScpO1xuICAgIH1cbiAgICBpZiAodHlwZW9mIGZpbGUgPT09ICdzdHJpbmcnKSB7XG4gICAgICBmaWxlID0gZnMuY3JlYXRlUmVhZFN0cmVhbShmaWxlKTtcbiAgICB9XG5cbiAgICBjb25zdCBmb3JtRGF0YSA9IG5ldyBGb3JtRGF0YSgpO1xuICAgIGZvcm1EYXRhLmFwcGVuZCgnZmlsZScsIGZpbGUpO1xuXG4gICAgY29uc3Qgb3B0cyA9IHtcbiAgICAgIG1ldGhvZDogJ1BVVCcsXG4gICAgICB1cmw6IGAke3RoaXMuX2hvc3R9L3VzZXJzL2N1cnJlbnQvYWNjb3VudHMvJHthY2NvdW50SWR9L2V4cGVydC1hZHZpc29ycy8ke2V4cGVydElkfS9maWxlYCxcbiAgICAgIGRhdGE6IGZvcm1EYXRhLFxuICAgICAgaGVhZGVyczoge1xuICAgICAgICAuLi5mb3JtRGF0YS5nZXRIZWFkZXJzKCksXG4gICAgICAgICdhdXRoLXRva2VuJzogdGhpcy5fdG9rZW5cbiAgICAgIH1cbiAgICB9O1xuXG4gICAgcmV0dXJuIHRoaXMuX2h0dHBDbGllbnQucmVxdWVzdChvcHRzLCAndXBsb2FkRXhwZXJ0QWR2aXNvckZpbGUnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBEZWxldGVzIGFuIGV4cGVydCBhZHZpc29yIChzZWUgaHR0cHM6Ly9tZXRhYXBpLmNsb3VkL2RvY3MvcHJvdmlzaW9uaW5nL2FwaS9leHBlcnRBZHZpc29yL2RlbGV0ZUV4cGVydEFkdmlzb3IvKVxuICAgKiBNZXRob2QgaXMgYWNjZXNzaWJsZSBvbmx5IHdpdGggQVBJIGFjY2VzcyB0b2tlblxuICAgKiBAcGFyYW0ge1N0cmluZ30gYWNjb3VudElkIE1ldGF0cmFkZXIgYWNjb3VudCBpZFxuICAgKiBAcGFyYW0ge1N0cmluZ30gZXhwZXJ0SWQgZXhwZXJ0IGlkXG4gICAqIEByZXR1cm5zIHtQcm9taXNlfSBwcm9taXNlIHJlc29sdmluZyB3aGVuIGV4cGVydCBhZHZpc29yIGlzIGRlbGV0ZWRcbiAgICovXG4gIGRlbGV0ZUV4cGVydEFkdmlzb3IoYWNjb3VudElkLCBleHBlcnRJZCkge1xuICAgIGlmICh0aGlzLl9pc05vdEp3dFRva2VuKCkpIHtcbiAgICAgIHJldHVybiB0aGlzLl9oYW5kbGVOb0FjY2Vzc0Vycm9yKCdkZWxldGVFeHBlcnRBZHZpc29yJyk7XG4gICAgfVxuICAgIGNvbnN0IG9wdHMgPSB7XG4gICAgICB1cmw6IGAke3RoaXMuX2hvc3R9L3VzZXJzL2N1cnJlbnQvYWNjb3VudHMvJHthY2NvdW50SWR9L2V4cGVydC1hZHZpc29ycy8ke2V4cGVydElkfWAsXG4gICAgICBtZXRob2Q6ICdERUxFVEUnLFxuICAgICAgaGVhZGVyczoge1xuICAgICAgICAnYXV0aC10b2tlbic6IHRoaXMuX3Rva2VuXG4gICAgICB9LFxuICAgICAganNvbjogdHJ1ZVxuICAgIH07XG4gICAgcmV0dXJuIHRoaXMuX2h0dHBDbGllbnQucmVxdWVzdChvcHRzLCAnZGVsZXRlRXhwZXJ0QWR2aXNvcicpO1xuICB9XG5cbn1cbiJdLCJuYW1lcyI6WyJFeHBlcnRBZHZpc29yQ2xpZW50IiwiTWV0YUFwaUNsaWVudCIsImdldEV4cGVydEFkdmlzb3JzIiwiYWNjb3VudElkIiwiX2lzTm90Snd0VG9rZW4iLCJfaGFuZGxlTm9BY2Nlc3NFcnJvciIsIm9wdHMiLCJ1cmwiLCJfaG9zdCIsIm1ldGhvZCIsImhlYWRlcnMiLCJfdG9rZW4iLCJqc29uIiwiX2h0dHBDbGllbnQiLCJyZXF1ZXN0IiwiZ2V0RXhwZXJ0QWR2aXNvciIsImV4cGVydElkIiwidXBkYXRlRXhwZXJ0QWR2aXNvciIsImV4cGVydCIsImRhdGEiLCJ1cGxvYWRFeHBlcnRBZHZpc29yRmlsZSIsImZpbGUiLCJmcyIsImNyZWF0ZVJlYWRTdHJlYW0iLCJmb3JtRGF0YSIsIkZvcm1EYXRhIiwiYXBwZW5kIiwiZ2V0SGVhZGVycyIsImRlbGV0ZUV4cGVydEFkdmlzb3IiXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7O2VBU3FCQTs7O3NFQVBLO2lFQUNMOzJEQUNOOzs7Ozs7QUFLQSxJQUFBLEFBQU1BLHNCQUFOLE1BQU1BLDRCQUE0QkMsc0JBQWE7SUFFNUQ7Ozs7Ozs7R0FPQyxHQUVEOzs7Ozs7R0FNQyxHQUNEQyxrQkFBa0JDLFNBQVMsRUFBRTtRQUMzQixJQUFJLElBQUksQ0FBQ0MsY0FBYyxJQUFJO1lBQ3pCLE9BQU8sSUFBSSxDQUFDQyxvQkFBb0IsQ0FBQztRQUNuQztRQUNBLE1BQU1DLE9BQU87WUFDWEMsS0FBSyxDQUFDLEVBQUUsSUFBSSxDQUFDQyxLQUFL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