UNPKG

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)

253 lines (252 loc) 32.1 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "default", { enumerable: true, get: function() { return Reservoir; } }); let Reservoir = class Reservoir { checkStatisticsOnRestore(statistics) { if (statistics.count === 0) { statistics = { count: 0, sum: 0, max: undefined, min: undefined, average: undefined, sumOfSquares: 0, msdev: undefined, stddev: undefined }; } else if (statistics.count < 2) { statistics.msdev = undefined; statistics.stddev = undefined; } return statistics; } /** * Add element to Reservoir * @param {Number} data to add */ pushMeasurement(data) { if (isFinite(data)) { this._updateQueue(); this._updateIntermediaryRecord(data); this._updateStatisticsOnAdd(data); } } /** * return Reservoir statistics * @return {Object} Reservoir statistics */ getStatistics() { this._updateQueue(); return this.statistics; } toPlainObject() { this._updateQueue(true); return { array: this.array, size: this.size, _interval: this._interval, _queueEndTime: this._queueEndTime, _fisrtQueueIndex: this._fisrtQueueIndex, _intermediaryRecord: this._intermediaryRecord, statistics: this.statistics }; } _updateQueue() { let intervalsCount = this._takeTimeIntervalsCount(); let emptyElementsCount = this._takeEmptyElementsAddCount(); if (emptyElementsCount > 0) { this._addRecord(emptyElementsCount); this._queueEndTime += intervalsCount * this._interval; } } _takeEmptyElementsAddCount() { let emptyElementsCount = this._takeTimeIntervalsCount(); if (emptyElementsCount > this.size) { emptyElementsCount = this.size; } return emptyElementsCount; } _takeTimeIntervalsCount() { let timeNow = Date.now(); let timeDiff = timeNow - this._queueEndTime; let timeIntervalsCount = Math.floor(timeDiff / this._interval); return timeIntervalsCount; } _updateRunningStatisticsOnRemove(removeCount) { let removeElementIndex = this._fisrtQueueIndex + 1; for(let i = 0; i < removeCount; i++){ if (removeElementIndex >= this.size) { removeElementIndex = 0; } this._updateStatisticsOnRemove(this.array[removeElementIndex], removeElementIndex); this.array[removeElementIndex] = { count: 0, sum: 0, max: undefined, min: undefined, average: 0, sumOfSquares: 0 }; removeElementIndex++; } removeElementIndex--; if (removeElementIndex < 0) { removeElementIndex = this.size - 1; } return removeElementIndex; } _updateStatisticsOnRemove(removeElement, removeElementIndex) { if (removeElement !== undefined && removeElement !== null) { this.statistics.count -= removeElement.count; this.statistics.sumOfSquares -= removeElement.sumOfSquares; this.statistics.sum -= removeElement.sum; this._updateStatisticsMinAndMaxOnRemove(removeElement, removeElementIndex); if (this.statistics.count > 0) { this.statistics.average = this.statistics.sum / this.statistics.count; if (this.statistics.count > 1) { let difOfSums = this._calculateDifferenceOfSums(this.statistics.sumOfSquares, this.statistics.sum, this.statistics.count); this.statistics.msdev = parseFloat(Math.sqrt(difOfSums / this.statistics.count)); this.statistics.stddev = parseFloat(Math.sqrt(difOfSums / (this.statistics.count - 1))); } else { this.statistics.stddev = undefined; this.statistics.msdev = undefined; } } else { this.statistics.average = undefined; this.statistics.stddev = undefined; this.statistics.msdev = undefined; } } } _updateStatisticsMinAndMaxOnRemove(removeElement, removeElementIndex) { if (removeElement.max !== undefined && removeElement.max === this.statistics.max) { this.statistics.max = this._findMax(removeElementIndex); } if (removeElement.min !== undefined && removeElement.min === this.statistics.min) { this.statistics.min = this._findMin(removeElementIndex); } } _updateStatisticsOnAdd(el) { if (el !== undefined && el !== null) { this.statistics.count += 1; this.statistics.sum += el; this._updateStatisticsMinAndMaxOnAdd(el); this.statistics.sumOfSquares += Math.pow(el, 2); if (this.statistics.count > 0) { this.statistics.average = this.statistics.sum / this.statistics.count; let difOfSums = this._calculateDifferenceOfSums(this.statistics.sumOfSquares, this.statistics.sum, this.statistics.count); if (this.statistics.count > 1) { this.statistics.msdev = parseFloat(Math.sqrt(difOfSums / this.statistics.count)); this.statistics.stddev = parseFloat(Math.sqrt(difOfSums / (this.statistics.count - 1))); } else { this.statistics.msdev = undefined; this.statistics.stddev = undefined; } } } } _updateStatisticsMinAndMaxOnAdd(el) { if (this.statistics.max < el || this.statistics.max === undefined || this.statistics.max === null) { this.statistics.max = el; } if (this.statistics.min > el || this.statistics.min === undefined || this.statistics.min === null) { this.statistics.min = el; } } _addRecord(emptyElementsCount) { if (this._intermediaryRecord !== undefined) { this.array[this._fisrtQueueIndex] = this._intermediaryRecord; this._intermediaryRecord = undefined; } let curIndexInArray = this._updateRunningStatisticsOnRemove(emptyElementsCount); this._fisrtQueueIndex = curIndexInArray; } _calculateDifferenceOfSums(sum1, sum2, count) { let dif = sum1 - Math.pow(sum2, 2) / count; return dif; } _updateIntermediaryRecord(el) { if (this._intermediaryRecord === undefined) { this._intermediaryRecord = { count: 1, sum: el, max: el, min: el, average: el, sumOfSquares: Math.pow(el, 2) }; } else { if (this._intermediaryRecord.max < el) { this._intermediaryRecord.max = el; } if (this._intermediaryRecord.min > el) { this._intermediaryRecord.min = el; } this._intermediaryRecord.count += 1; this._intermediaryRecord.sum += el; this._intermediaryRecord.sumOfSquares += Math.pow(el, 2); } } _findMin(index) { let min = Infinity; this.array.forEach((el, i)=>{ if (el !== null && el !== undefined && el.min !== undefined && el.min < min && i !== index) { min = el.min; } }); if (min === Infinity) { return this._intermediaryRecord !== undefined ? this._intermediaryRecord.min : undefined; } return min; } _findMax(index) { let max = -Infinity; this.array.forEach((el, i)=>{ if (el !== null && el !== undefined && el.max !== undefined && el.max > max && i !== index) { max = el.max; } }); if (max === -Infinity) { return this._intermediaryRecord !== undefined ? this._intermediaryRecord.max : undefined; } return max; } /** * Constructs Reservoir * @param {number} size Reservoir size * @param {number} observationIntervalInMS Reservoir observation Interval In ms */ constructor(size, observationIntervalInMS, object){ if (!object) { this.array = new Array(); this.size = size; this._interval = observationIntervalInMS / size; this._queueEndTime = Date.now(); this._fisrtQueueIndex = 0; this._intermediaryRecord = undefined; this.statistics = { count: 0, sum: 0, max: undefined, min: undefined, average: 0, sumOfSquares: 0, msdev: 0, stddev: 0 }; } else { this.array = object.array; this.size = object.size; this._interval = object._interval; this._queueEndTime = object._queueEndTime; this._fisrtQueueIndex = object._fisrtQueueIndex; this._intermediaryRecord = object._intermediaryRecord; this.statistics = this.checkStatisticsOnRestore(object.statistics); } } }; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIjxhbm9uPiJdLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbi8qKlxuICogRklGTy1saWtlIHJlc2Vydm9pciBvZiBhIGZpeGVkIHNpemUgY2FwYWJsZVxuICogY2FsY3VsYXRpbmcgcnVubmluZyBzdW1zLCBtaW4vbWF4LCBhdmVyYWdlLCBtc2RldiBhbmQgc3RkZGV2XG4gKiBtc2RldiBhbmQgc3RkZGV2IGNhbGN1bGF0aW9uIGJ5IE5haXZlIGFsZ29yaXRobVxuICogKE1lYW4gc3F1YXJlIGRldmlhdGlvbikgbXNkZXYgPSBzcXJ0KCjiiJF7aSA9IGZyb20gMSB0byBufShYaSleMiAtKOKIkXtpID0gZnJvbSAxIHRvIG59WGkpXjIgLyBOKSAvIE4pXG4gKiAoU3RhbmRhcmQgZGV2aWF0aW9uKSBzdGRkZXYgPSBzcXJ0KCjiiJF7aSA9IGZyb20gMSB0byBufShYaSleMiAtKOKIkXtpID0gZnJvbSAxIHRvIG59WGkpXjIgLyBOKSAvIE4gLSAxKVxuICogbGluazogaHR0cHM6Ly9nb28uZ2wvTUFFR1AyXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFJlc2Vydm9pciB7XG5cbiAgLyoqXG4gICAqIENvbnN0cnVjdHMgUmVzZXJ2b2lyXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBzaXplIFJlc2Vydm9pciBzaXplXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBvYnNlcnZhdGlvbkludGVydmFsSW5NUyBSZXNlcnZvaXIgb2JzZXJ2YXRpb24gSW50ZXJ2YWwgSW4gbXNcbiAgICovXG4gIGNvbnN0cnVjdG9yKHNpemUsIG9ic2VydmF0aW9uSW50ZXJ2YWxJbk1TLCBvYmplY3QpIHtcbiAgICBpZiAoIW9iamVjdCkge1xuICAgICAgdGhpcy5hcnJheSA9IG5ldyBBcnJheSgpO1xuICAgICAgdGhpcy5zaXplID0gc2l6ZTtcbiAgICAgIHRoaXMuX2ludGVydmFsID0gKG9ic2VydmF0aW9uSW50ZXJ2YWxJbk1TIC8gc2l6ZSk7XG4gICAgICB0aGlzLl9xdWV1ZUVuZFRpbWUgPSBEYXRlLm5vdygpO1xuICAgICAgdGhpcy5fZmlzcnRRdWV1ZUluZGV4ID0gMDtcbiAgICAgIHRoaXMuX2ludGVybWVkaWFyeVJlY29yZCA9IHVuZGVmaW5lZDtcbiAgICAgIHRoaXMuc3RhdGlzdGljcyA9IHtcbiAgICAgICAgY291bnQ6IDAsXG4gICAgICAgIHN1bTogMCxcbiAgICAgICAgbWF4OiB1bmRlZmluZWQsXG4gICAgICAgIG1pbjogdW5kZWZpbmVkLFxuICAgICAgICBhdmVyYWdlOiAwLFxuICAgICAgICBzdW1PZlNxdWFyZXM6IDAsXG4gICAgICAgIG1zZGV2OiAwLFxuICAgICAgICBzdGRkZXY6IDBcbiAgICAgIH07XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuYXJyYXkgPSBvYmplY3QuYXJyYXk7XG4gICAgICB0aGlzLnNpemUgPSBvYmplY3Quc2l6ZTtcbiAgICAgIHRoaXMuX2ludGVydmFsID0gb2JqZWN0Ll9pbnRlcnZhbDtcbiAgICAgIHRoaXMuX3F1ZXVlRW5kVGltZSA9IG9iamVjdC5fcXVldWVFbmRUaW1lO1xuICAgICAgdGhpcy5fZmlzcnRRdWV1ZUluZGV4ID0gb2JqZWN0Ll9maXNydFF1ZXVlSW5kZXg7XG4gICAgICB0aGlzLl9pbnRlcm1lZGlhcnlSZWNvcmQgPSBvYmplY3QuX2ludGVybWVkaWFyeVJlY29yZDtcbiAgICAgIHRoaXMuc3RhdGlzdGljcyA9IHRoaXMuY2hlY2tTdGF0aXN0aWNzT25SZXN0b3JlKG9iamVjdC5zdGF0aXN0aWNzKTtcbiAgICB9XG4gIH1cblxuICBjaGVja1N0YXRpc3RpY3NPblJlc3RvcmUoc3RhdGlzdGljcykge1xuICAgIGlmIChzdGF0aXN0aWNzLmNvdW50ID09PSAwKSB7XG4gICAgICBzdGF0aXN0aWNzID0ge1xuICAgICAgICBjb3VudDogMCxcbiAgICAgICAgc3VtOiAwLFxuICAgICAgICBtYXg6IHVuZGVmaW5lZCxcbiAgICAgICAgbWluOiB1bmRlZmluZWQsXG4gICAgICAgIGF2ZXJhZ2U6IHVuZGVmaW5lZCxcbiAgICAgICAgc3VtT2ZTcXVhcmVzOiAwLFxuICAgICAgICBtc2RldjogdW5kZWZpbmVkLFxuICAgICAgICBzdGRkZXY6IHVuZGVmaW5lZFxuICAgICAgfTtcbiAgICB9IGVsc2UgaWYgKHN0YXRpc3RpY3MuY291bnQgPCAyKSB7XG4gICAgICBzdGF0aXN0aWNzLm1zZGV2ID0gdW5kZWZpbmVkO1xuICAgICAgc3RhdGlzdGljcy5zdGRkZXYgPSB1bmRlZmluZWQ7XG4gICAgfVxuICAgIHJldHVybiBzdGF0aXN0aWNzO1xuICB9XG5cbiAgLyoqXG4gICAqIEFkZCBlbGVtZW50IHRvIFJlc2Vydm9pclxuICAgKiBAcGFyYW0ge051bWJlcn0gZGF0YSB0byBhZGRcbiAgICovXG4gIHB1c2hNZWFzdXJlbWVudChkYXRhKSB7XG4gICAgaWYgKGlzRmluaXRlKGRhdGEpKSB7XG4gICAgICB0aGlzLl91cGRhdGVRdWV1ZSgpO1xuICAgICAgdGhpcy5fdXBkYXRlSW50ZXJtZWRpYXJ5UmVjb3JkKGRhdGEpO1xuICAgICAgdGhpcy5fdXBkYXRlU3RhdGlzdGljc09uQWRkKGRhdGEpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiByZXR1cm4gUmVzZXJ2b2lyIHN0YXRpc3RpY3NcbiAgICogQHJldHVybiB7T2JqZWN0fSBSZXNlcnZvaXIgc3RhdGlzdGljc1xuICAgKi9cbiAgZ2V0U3RhdGlzdGljcygpIHtcbiAgICB0aGlzLl91cGRhdGVRdWV1ZSgpO1xuICAgIHJldHVybiB0aGlzLnN0YXRpc3RpY3M7XG4gIH1cblxuICB0b1BsYWluT2JqZWN0KCkge1xuICAgIHRoaXMuX3VwZGF0ZVF1ZXVlKHRydWUpO1xuICAgIHJldHVybiB7XG4gICAgICBhcnJheTogdGhpcy5hcnJheSxcbiAgICAgIHNpemU6IHRoaXMuc2l6ZSxcbiAgICAgIF9pbnRlcnZhbDogdGhpcy5faW50ZXJ2YWwsXG4gICAgICBfcXVldWVFbmRUaW1lOiB0aGlzLl9xdWV1ZUVuZFRpbWUsXG4gICAgICBfZmlzcnRRdWV1ZUluZGV4OiB0aGlzLl9maXNydFF1ZXVlSW5kZXgsXG4gICAgICBfaW50ZXJtZWRpYXJ5UmVjb3JkOiB0aGlzLl9pbnRlcm1lZGlhcnlSZWNvcmQsXG4gICAgICBzdGF0aXN0aWNzOiB0aGlzLnN0YXRpc3RpY3NcbiAgICB9O1xuICB9XG5cbiAgX3VwZGF0ZVF1ZXVlKCkge1xuICAgIGxldCBpbnRlcnZhbHNDb3VudCA9IHRoaXMuX3Rha2VUaW1lSW50ZXJ2YWxzQ291bnQoKTtcbiAgICBsZXQgZW1wdHlFbGVtZW50c0NvdW50ID0gdGhpcy5fdGFrZUVtcHR5RWxlbWVudHNBZGRDb3VudCgpO1xuICAgIGlmIChlbXB0eUVsZW1lbnRzQ291bnQgPiAwKSB7XG4gICAgICB0aGlzLl9hZGRSZWNvcmQoZW1wdHlFbGVtZW50c0NvdW50KTtcbiAgICAgIHRoaXMuX3F1ZXVlRW5kVGltZSArPSBpbnRlcnZhbHNDb3VudCAqIHRoaXMuX2ludGVydmFsO1xuICAgIH1cbiAgfVxuXG4gIF90YWtlRW1wdHlFbGVtZW50c0FkZENvdW50KCkge1xuICAgIGxldCBlbXB0eUVsZW1lbnRzQ291bnQgPSB0aGlzLl90YWtlVGltZUludGVydmFsc0NvdW50KCk7XG4gICAgaWYgKGVtcHR5RWxlbWVudHNDb3VudCA+IHRoaXMuc2l6ZSkge1xuICAgICAgZW1wdHlFbGVtZW50c0NvdW50ID0gdGhpcy5zaXplO1xuICAgIH1cbiAgICByZXR1cm4gZW1wdHlFbGVtZW50c0NvdW50O1xuICB9XG5cbiAgX3Rha2VUaW1lSW50ZXJ2YWxzQ291bnQoKSB7XG4gICAgbGV0IHRpbWVOb3cgPSBEYXRlLm5vdygpO1xuICAgIGxldCB0aW1lRGlmZiA9IHRpbWVOb3cgLSB0aGlzLl9xdWV1ZUVuZFRpbWU7XG4gICAgbGV0IHRpbWVJbnRlcnZhbHNDb3VudCA9IE1hdGguZmxvb3IodGltZURpZmYgLyB0aGlzLl9pbnRlcnZhbCk7XG4gICAgcmV0dXJuIHRpbWVJbnRlcnZhbHNDb3VudDtcbiAgfVxuXG4gIF91cGRhdGVSdW5uaW5nU3RhdGlzdGljc09uUmVtb3ZlKHJlbW92ZUNvdW50KSB7XG4gICAgbGV0IHJlbW92ZUVsZW1lbnRJbmRleCA9IHRoaXMuX2Zpc3J0UXVldWVJbmRleCArIDE7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCByZW1vdmVDb3VudDsgaSsrKSB7XG4gICAgICBpZiAocmVtb3ZlRWxlbWVudEluZGV4ID49IHRoaXMuc2l6ZSkge1xuICAgICAgICByZW1vdmVFbGVtZW50SW5kZXggPSAwO1xuICAgICAgfVxuXG4gICAgICB0aGlzLl91cGRhdGVTdGF0aXN0aWNzT25SZW1vdmUodGhpcy5hcnJheVtyZW1vdmVFbGVtZW50SW5kZXhdLCByZW1vdmVFbGVtZW50SW5kZXgpO1xuICAgICAgdGhpcy5hcnJheVtyZW1vdmVFbGVtZW50SW5kZXhdID0ge1xuICAgICAgICBjb3VudDogMCxcbiAgICAgICAgc3VtOiAwLFxuICAgICAgICBtYXg6IHVuZGVmaW5lZCxcbiAgICAgICAgbWluOiB1bmRlZmluZWQsXG4gICAgICAgIGF2ZXJhZ2U6IDAsXG4gICAgICAgIHN1bU9mU3F1YXJlczogMFxuICAgICAgfTtcbiAgICAgIHJlbW92ZUVsZW1lbnRJbmRleCsrO1xuICAgIH1cbiAgICByZW1vdmVFbGVtZW50SW5kZXgtLTtcbiAgICBpZiAocmVtb3ZlRWxlbWVudEluZGV4IDwgMCkge1xuICAgICAgcmVtb3ZlRWxlbWVudEluZGV4ID0gdGhpcy5zaXplIC0gMTtcbiAgICB9XG4gICAgcmV0dXJuIHJlbW92ZUVsZW1lbnRJbmRleDtcbiAgfVxuXG4gIF91cGRhdGVTdGF0aXN0aWNzT25SZW1vdmUocmVtb3ZlRWxlbWVudCwgcmVtb3ZlRWxlbWVudEluZGV4KSB7XG4gICAgaWYgKHJlbW92ZUVsZW1lbnQgIT09IHVuZGVmaW5lZCAmJiByZW1vdmVFbGVtZW50ICE9PSBudWxsKSB7XG4gICAgICB0aGlzLnN0YXRpc3RpY3MuY291bnQgLT0gcmVtb3ZlRWxlbWVudC5jb3VudDtcbiAgICAgIHRoaXMuc3RhdGlzdGljcy5zdW1PZlNxdWFyZXMgLT0gcmVtb3ZlRWxlbWVudC5zdW1PZlNxdWFyZXM7XG4gICAgICB0aGlzLnN0YXRpc3RpY3Muc3VtIC09IHJlbW92ZUVsZW1lbnQuc3VtO1xuICAgICAgdGhpcy5fdXBkYXRlU3RhdGlzdGljc01pbkFuZE1heE9uUmVtb3ZlKHJlbW92ZUVsZW1lbnQsIHJlbW92ZUVsZW1lbnRJbmRleCk7XG4gICAgICBpZiAodGhpcy5zdGF0aXN0aWNzLmNvdW50ID4gMCkge1xuICAgICAgICB0aGlzLnN0YXRpc3RpY3MuYXZlcmFnZSA9IHRoaXMuc3RhdGlzdGljcy5zdW0gLyB0aGlzLnN0YXRpc3RpY3MuY291bnQ7XG4gICAgICAgIGlmICh0aGlzLnN0YXRpc3RpY3MuY291bnQgPiAxKSB7XG4gICAgICAgICAgbGV0IGRpZk9mU3VtcyA9IHRoaXMuX2NhbGN1bGF0ZURpZmZlcmVuY2VPZlN1bXModGhpcy5zdGF0aXN0aWNzLnN1bU9mU3F1YXJlcyxcbiAgICAgICAgICAgIHRoaXMuc3RhdGlzdGljcy5zdW0sIHRoaXMuc3RhdGlzdGljcy5jb3VudCk7XG4gICAgICAgICAgdGhpcy5zdGF0aXN0aWNzLm1zZGV2ID0gcGFyc2VGbG9hdChNYXRoLnNxcnQoZGlmT2ZTdW1zIC8gdGhpcy5zdGF0aXN0aWNzLmNvdW50KSk7XG4gICAgICAgICAgdGhpcy5zdGF0aXN0aWNzLnN0ZGRldiA9IHBhcnNlRmxvYXQoTWF0aC5zcXJ0KGRpZk9mU3VtcyAvICh0aGlzLnN0YXRpc3RpY3MuY291bnQgLSAxKSkpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRoaXMuc3RhdGlzdGljcy5zdGRkZXYgPSB1bmRlZmluZWQ7XG4gICAgICAgICAgdGhpcy5zdGF0aXN0aWNzLm1zZGV2ID0gdW5kZWZpbmVkO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLnN0YXRpc3RpY3MuYXZlcmFnZSA9IHVuZGVmaW5lZDtcbiAgICAgICAgdGhpcy5zdGF0aXN0aWNzLnN0ZGRldiA9IHVuZGVmaW5lZDtcbiAgICAgICAgdGhpcy5zdGF0aXN0aWNzLm1zZGV2ID0gdW5kZWZpbmVkO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIF91cGRhdGVTdGF0aXN0aWNzTWluQW5kTWF4T25SZW1vdmUocmVtb3ZlRWxlbWVudCwgcmVtb3ZlRWxlbWVudEluZGV4KSB7XG4gICAgaWYgKHJlbW92ZUVsZW1lbnQubWF4ICE9PSB1bmRlZmluZWQgJiYgcmVtb3ZlRWxlbWVudC5tYXggPT09IHRoaXMuc3RhdGlzdGljcy5tYXgpIHtcbiAgICAgIHRoaXMuc3RhdGlzdGljcy5tYXggPSB0aGlzLl9maW5kTWF4KHJlbW92ZUVsZW1lbnRJbmRleCk7XG4gICAgfVxuXG4gICAgaWYgKHJlbW92ZUVsZW1lbnQubWluICE9PSB1bmRlZmluZWQgJiYgcmVtb3ZlRWxlbWVudC5taW4gPT09IHRoaXMuc3RhdGlzdGljcy5taW4pIHtcbiAgICAgIHRoaXMuc3RhdGlzdGljcy5taW4gPSB0aGlzLl9maW5kTWluKHJlbW92ZUVsZW1lbnRJbmRleCk7XG4gICAgfVxuICB9XG5cbiAgX3VwZGF0ZVN0YXRpc3RpY3NPbkFkZChlbCkge1xuICAgIGlmIChlbCAhPT0gdW5kZWZpbmVkICYmIGVsICE9PSBudWxsKSB7XG4gICAgICB0aGlzLnN0YXRpc3RpY3MuY291bnQgKz0gMTtcbiAgICAgIHRoaXMuc3RhdGlzdGljcy5zdW0gKz0gZWw7XG4gICAgICB0aGlzLl91cGRhdGVTdGF0aXN0aWNzTWluQW5kTWF4T25BZGQoZWwpO1xuICAgICAgdGhpcy5zdGF0aXN0aWNzLnN1bU9mU3F1YXJlcyArPSBNYXRoLnBvdyhlbCwgMik7XG4gICAgICBpZiAodGhpcy5zdGF0aXN0aWNzLmNvdW50ID4gMCkge1xuICAgICAgICB0aGlzLnN0YXRpc3RpY3MuYXZlcmFnZSA9IHRoaXMuc3RhdGlzdGljcy5zdW0gLyB0aGlzLnN0YXRpc3RpY3MuY291bnQ7XG4gICAgICAgIGxldCBkaWZPZlN1bXMgPSB0aGlzLl9jYWxjdWxhdGVEaWZmZXJlbmNlT2ZTdW1zKHRoaXMuc3RhdGlzdGljcy5zdW1PZlNxdWFyZXMsXG4gICAgICAgICAgdGhpcy5zdGF0aXN0aWNzLnN1bSwgdGhpcy5zdGF0aXN0aWNzLmNvdW50KTtcbiAgICAgICAgaWYgKHRoaXMuc3RhdGlzdGljcy5jb3VudCA+IDEpIHtcbiAgICAgICAgICB0aGlzLnN0YXRpc3RpY3MubXNkZXYgPSBwYXJzZUZsb2F0KE1hdGguc3FydChkaWZPZlN1bXMgLyB0aGlzLnN0YXRpc3RpY3MuY291bnQpKTtcbiAgICAgICAgICB0aGlzLnN0YXRpc3RpY3Muc3RkZGV2ID0gcGFyc2VGbG9hdChNYXRoLnNxcnQoZGlmT2ZTdW1zIC8gKHRoaXMuc3RhdGlzdGljcy5jb3VudCAtIDEpKSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhpcy5zdGF0aXN0aWNzLm1zZGV2ID0gdW5kZWZpbmVkO1xuICAgICAgICAgIHRoaXMuc3RhdGlzdGljcy5zdGRkZXYgPSB1bmRlZmluZWQ7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBfdXBkYXRlU3RhdGlzdGljc01pbkFuZE1heE9uQWRkKGVsKSB7XG4gICAgaWYgKHRoaXMuc3RhdGlzdGljcy5tYXggPCBlbCB8fCB0aGlzLnN0YXRpc3RpY3MubWF4ID09PSB1bmRlZmluZWQgfHwgdGhpcy5zdGF0aXN0aWNzLm1heCA9PT0gbnVsbCkge1xuICAgICAgdGhpcy5zdGF0aXN0aWNzLm1heCA9IGVsO1xuICAgIH1cbiAgICBpZiAodGhpcy5zdGF0aXN0aWNzLm1pbiA+IGVsIHx8IHRoaXMuc3RhdGlzdGljcy5taW4gPT09IHVuZGVmaW5lZCB8fCB0aGlzLnN0YXRpc3RpY3MubWluID09PSBudWxsKSB7XG4gICAgICB0aGlzLnN0YXRpc3RpY3MubWluID0gZWw7XG4gICAgfVxuICB9XG5cbiAgX2FkZFJlY29yZChlbXB0eUVsZW1lbnRzQ291bnQpIHtcbiAgICBpZiAodGhpcy5faW50ZXJtZWRpYXJ5UmVjb3JkICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHRoaXMuYXJyYXlbdGhpcy5fZmlzcnRRdWV1ZUluZGV4XSA9IHRoaXMuX2ludGVybWVkaWFyeVJlY29yZDtcbiAgICAgIHRoaXMuX2ludGVybWVkaWFyeVJlY29yZCA9IHVuZGVmaW5lZDtcbiAgICB9XG4gICAgbGV0IGN1ckluZGV4SW5BcnJheSA9IHRoaXMuX3VwZGF0ZVJ1bm5pbmdTdGF0aXN0aWNzT25SZW1vdmUoZW1wdHlFbGVtZW50c0NvdW50KTtcbiAgICB0aGlzLl9maXNydFF1ZXVlSW5kZXggPSBjdXJJbmRleEluQXJyYXk7XG4gIH1cblxuICBfY2FsY3VsYXRlRGlmZmVyZW5jZU9mU3VtcyhzdW0xLCBzdW0yLCBjb3VudCkge1xuICAgIGxldCBkaWYgPSBzdW0xIC0gTWF0aC5wb3coc3VtMiwgMikgLyBjb3VudDtcbiAgICByZXR1cm4gZGlmO1xuICB9XG5cbiAgX3VwZGF0ZUludGVybWVkaWFyeVJlY29yZChlbCkge1xuICAgIGlmICh0aGlzLl9pbnRlcm1lZGlhcnlSZWNvcmQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgdGhpcy5faW50ZXJtZWRpYXJ5UmVjb3JkID0ge1xuICAgICAgICBjb3VudDogMSxcbiAgICAgICAgc3VtOiBlbCxcbiAgICAgICAgbWF4OiBlbCxcbiAgICAgICAgbWluOiBlbCxcbiAgICAgICAgYXZlcmFnZTogZWwsXG4gICAgICAgIHN1bU9mU3F1YXJlczogTWF0aC5wb3coZWwsIDIpXG4gICAgICB9O1xuICAgIH0gZWxzZSB7XG4gICAgICBpZiAodGhpcy5faW50ZXJtZWRpYXJ5UmVjb3JkLm1heCA8IGVsKSB7XG4gICAgICAgIHRoaXMuX2ludGVybWVkaWFyeVJlY29yZC5tYXggPSBlbDtcbiAgICAgIH1cbiAgICAgIGlmICh0aGlzLl9pbnRlcm1lZGlhcnlSZWNvcmQubWluID4gZWwpIHtcbiAgICAgICAgdGhpcy5faW50ZXJtZWRpYXJ5UmVjb3JkLm1pbiA9IGVsO1xuICAgICAgfVxuICAgICAgdGhpcy5faW50ZXJtZWRpYXJ5UmVjb3JkLmNvdW50ICs9IDE7XG4gICAgICB0aGlzLl9pbnRlcm1lZGlhcnlSZWNvcmQuc3VtICs9IGVsO1xuICAgICAgdGhpcy5faW50ZXJtZWRpYXJ5UmVjb3JkLnN1bU9mU3F1YXJlcyArPSBNYXRoLnBvdyhlbCwgMik7XG4gICAgfVxuICB9XG5cbiAgX2ZpbmRNaW4oaW5kZXgpIHtcbiAgICBsZXQgbWluID0gSW5maW5pdHk7XG4gICAgdGhpcy5hcnJheS5mb3JFYWNoKChlbCwgaSkgPT4ge1xuICAgICAgaWYgKGVsICE9PSBudWxsICYmIGVsICE9PSB1bmRlZmluZWQgJiYgZWwubWluICE9PSB1bmRlZmluZWQgJiYgZWwubWluIDwgbWluICYmIGkgIT09IGluZGV4KSB7XG4gICAgICAgIG1pbiA9IGVsLm1pbjtcbiAgICAgIH1cbiAgICB9KTtcbiAgICBpZiAobWluID09PSBJbmZpbml0eSkge1xuICAgICAgcmV0dXJuICh0aGlzLl9pbnRlcm1lZGlhcnlSZWNvcmQgIT09IHVuZGVmaW5lZCkgPyB0aGlzLl9pbnRlcm1lZGlhcnlSZWNvcmQubWluIDogdW5kZWZpbmVkO1xuICAgIH1cbiAgICByZXR1cm4gbWluO1xuICB9XG5cbiAgX2ZpbmRNYXgoaW5kZXgpIHtcbiAgICBsZXQgbWF4ID0gLUluZmluaXR5O1xuXG4gICAgdGhpcy5hcnJheS5mb3JFYWNoKChlbCwgaSkgPT4ge1xuICAgICAgaWYgKGVsICE9PSBudWxsICYmIGVsICE9PSB1bmRlZmluZWQgJiYgZWwubWF4ICE9PSB1bmRlZmluZWQgJiYgZWwubWF4ID4gbWF4ICYmIGkgIT09IGluZGV4KSB7XG4gICAgICAgIG1heCA9IGVsLm1heDtcbiAgICAgIH1cbiAgICB9KTtcbiAgICBpZiAobWF4ID09PSAtSW5maW5pdHkpIHtcbiAgICAgIHJldHVybiAodGhpcy5faW50ZXJtZWRpYXJ5UmVjb3JkICE9PSB1bmRlZmluZWQpID8gdGhpcy5faW50ZXJtZWRpYXJ5UmVjb3JkLm1heCA6IHVuZGVmaW5lZDtcbiAgICB9XG4gICAgcmV0dXJuIG1heDtcbiAgfVxufVxuIl0sIm5hbWVzIjpbIlJlc2Vydm9pciIsImNoZWNrU3RhdGlzdGljc09uUmVzdG9yZSIsInN0YXRpc3RpY3MiLCJjb3VudCIsInN1bSIsIm1heCIsInVuZGVmaW5lZCIsIm1pbiIsImF2ZXJhZ2UiLCJzdW1PZlNxdWFyZXMiLCJtc2RldiIsInN0ZGRldiIsInB1c2hNZWFzdXJlbWVudCIsImRhdGEiLCJpc0Zpbml0ZSIsIl91cGRhdGVRdWV1ZSIsIl91cGRhdGVJbnRlcm1lZGlhcnlSZWNvcmQiLCJfdXBkYXRlU3RhdGlzdGljc09uQWRkIiwiZ2V0U3RhdGlzdGljcyIsInRvUGxhaW5PYmplY3QiLCJhcnJheSIsInNpemUiLCJfaW50ZXJ2YWwiLCJfcXVldWVFbmRUaW1lIiwiX2Zpc3J0UXVldWVJbmRleCIsIl9pbnRlcm1lZGlhcnlSZWNvcmQiLCJpbnRlcnZhbHNDb3VudCIsIl90YWtlVGltZUludGVydmFsc0NvdW50IiwiZW1wdHlFbGVtZW50c0NvdW50IiwiX3Rha2VFbXB0eUVsZW1lbnRzQWRkQ291bnQiLCJfYWRkUmVjb3JkIiwidGltZU5vdyIsIkRhdGUiLCJub3ciLCJ0aW1lRGlmZiIsInRpbWVJbnRlcnZhbHNDb3VudCIsIk1hdGgiLCJmbG9vciIsIl91cGRhdGVSdW5uaW5nU3RhdGlzdGljc09uUmVtb3ZlIiwicmVtb3ZlQ291bnQiLCJyZW1vdmVFbGVtZW50SW5kZXgiLCJpIiwiX3VwZGF0ZVN0YXRpc3RpY3NPblJlbW92ZSIsInJlbW92ZUVsZW1lbnQiLCJfdXBkYXRlU3RhdGlzdGljc01pbkFuZE1heE9uUmVtb3ZlIiwiZGlmT2ZTdW1zIiwiX2NhbGN1bGF0ZURpZmZlcmVuY2VPZlN1bXMiLCJwYXJzZUZsb2F0Iiwic3FydCIsIl9maW5kTWF4IiwiX2ZpbmRNaW4iLCJlbCIsIl91cGRhdGVTdGF0aXN0aWNzTWluQW5kTWF4T25BZGQiLCJwb3ciLCJjdXJJbmRleEluQXJyYXkiLCJzdW0xIiwic3VtMiIsImRpZiIsImluZGV4IiwiSW5maW5pdHkiLCJmb3JFYWNoIiwiY29uc3RydWN0b3IiLCJvYnNlcnZh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