live-set
Version:
Class representing a changing and transformable collection of items.
438 lines (366 loc) • 41.7 kB
JavaScript
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
var _Scheduler = _interopRequireDefault(require("./Scheduler"));
var _symbolObservable = _interopRequireDefault(require("symbol-observable"));
var LiveSet =
/*#__PURE__*/
function () {
// Whether we can mutate the _values Set.
function LiveSet(init) {
(0, _classCallCheck2.default)(this, LiveSet);
(0, _defineProperty2.default)(this, "_init", void 0);
(0, _defineProperty2.default)(this, "_scheduler", void 0);
(0, _defineProperty2.default)(this, "_values", null);
(0, _defineProperty2.default)(this, "_mutableValues", false);
(0, _defineProperty2.default)(this, "_active", null);
(0, _defineProperty2.default)(this, "_inSubscriptionStart", false);
(0, _defineProperty2.default)(this, "_ended", false);
(0, _defineProperty2.default)(this, "_endedWithError", false);
(0, _defineProperty2.default)(this, "_error", null);
(0, _defineProperty2.default)(this, "_queuedCall", false);
(0, _defineProperty2.default)(this, "_changeQueue", []);
(0, _defineProperty2.default)(this, "_observers", []);
this._init = init;
this._scheduler = init.scheduler || LiveSet.defaultScheduler;
}
(0, _createClass2.default)(LiveSet, [{
key: "_queueChange",
value: function _queueChange(record) {
var _this = this;
if (record) {
this._changeQueue.push(record);
}
if (!this._queuedCall) {
this._queuedCall = true;
this._scheduler.schedule(function () {
_this._queuedCall = false;
var changes = _this._changeQueue;
_this._changeQueue = [];
var observersToCall;
var ended = _this._ended;
if (ended) {
observersToCall = _this._observers;
_this._observers = [];
} else {
observersToCall = _this._observers.slice();
}
observersToCall.forEach(function (record) {
var observer = record.observer,
ignore = record.ignore;
var observerNext = observer.next;
if (observerNext) {
if (ignore === 0) {
observerNext.call(observer, changes);
} else {
record.ignore = 0;
var changesToDeliver = changes.slice(ignore);
if (changesToDeliver.length) {
observerNext.call(observer, changesToDeliver);
}
}
}
if (ended) {
if (_this._endedWithError) {
if (observer.error) observer.error(_this._error);
} else {
if (observer.complete) observer.complete();
}
}
});
});
}
}
}, {
key: "_deactivate",
value: function _deactivate() {
if (!this._active) throw new Error('already inactive');
var listenHandler = this._active.listenHandler;
this._active = null;
if (listenHandler) {
listenHandler.unsubscribe();
}
}
}, {
key: "values",
value: function values() {
if (this._values) {
if (this._active && !this._inSubscriptionStart) {
var listenHandler = this._active.listenHandler;
if (listenHandler.pullChanges) {
listenHandler.pullChanges();
}
}
if (this._mutableValues) {
this._mutableValues = false;
makeSetImmutable(this._values);
}
/*:: if (!this._values) throw new Error(); */
return this._values;
} else {
if (this._active) {
throw new Error('tried to call values() on liveset during subscription before setValues was called');
}
var s = this._init.read();
makeSetImmutable(s);
return s;
}
}
}, {
key: "isEnded",
value: function isEnded() {
return this._ended;
}
}, {
key: "getScheduler",
value: function getScheduler() {
return this._scheduler;
}
}, {
key: "subscribe",
value: function subscribe(observerOrOnNext, onError, onComplete) {
var _this2 = this;
var liveSet = this;
var observer;
if (typeof observerOrOnNext === 'function') {
observer = {
next: observerOrOnNext,
error: onError,
complete: onComplete
};
} else {
observer = observerOrOnNext;
}
observer;
if (this._ended) {
var _subscription = {
closed: false,
unsubscribe: function unsubscribe() {
_subscription.closed = true;
},
pullChanges: function pullChanges() {}
};
if (observer.start) {
observer.start(_subscription);
}
if (!_subscription.closed) {
if (this._endedWithError) {
if (observer.error) {
observer.error(this._error);
}
} else {
if (observer.complete) {
observer.complete();
}
}
}
_subscription.closed = true;
return _subscription;
}
var observerRecord = {
observer: observer,
ignore: this._changeQueue.length
};
var isStarting = true;
var unsubscribedInStart = false;
var subscription = {
/*:: closed: false&&` */
get closed() {
return !isStarting && liveSet._observers.indexOf(observerRecord) < 0;
}
/*:: ` */
,
unsubscribe: function unsubscribe() {
if (isStarting) {
unsubscribedInStart = true;
return;
}
var ix = _this2._observers.indexOf(observerRecord);
if (ix >= 0) {
_this2._observers.splice(ix, 1);
if (!_this2._ended && _this2._observers.length === 0) {
_this2._values = null;
_this2._deactivate();
}
}
},
pullChanges: function pullChanges() {
if (_this2._active && _this2._active.listenHandler && _this2._active.listenHandler.pullChanges) {
_this2._active.listenHandler.pullChanges();
}
var changeQueueLength = _this2._changeQueue.length;
var originalNext = observer.next;
if (changeQueueLength !== 0 && originalNext) {
var changesToDeliver = _this2._changeQueue.slice(observerRecord.ignore);
if (changesToDeliver.length !== 0) {
observerRecord.ignore = changeQueueLength;
originalNext.call(observer, changesToDeliver);
}
}
}
};
if (!this._active) {
var _controller2 = {
// Flow doesn't support getters and setters yet
/*:: closed: false&&` */
get closed() {
return !liveSet._active || liveSet._active.controller !== this;
}
/*:: ` */
,
add: function add(value) {
var values = _this2._values;
if (!values) throw new Error('setValue must be called before controller is used');
if (!_this2._ended && !values.has(value)) {
if (!_this2._mutableValues) {
_this2._values = values = new Set(values);
_this2._mutableValues = true;
}
values.add(value);
_this2._queueChange({
type: 'add',
value: value
});
}
},
remove: function remove(value) {
var values = _this2._values;
if (!values) throw new Error('setValue must be called before controller is used');
if (!_this2._ended && values.has(value)) {
if (!_this2._mutableValues) {
_this2._values = values = new Set(values);
_this2._mutableValues = true;
}
values.delete(value);
_this2._queueChange({
type: 'remove',
value: value
});
}
},
error: function error(err) {
if (_this2._ended) return;
_this2._ended = true;
_this2._endedWithError = true;
_this2._error = err;
_this2._queueChange();
_this2._deactivate();
},
end: function end() {
if (_this2._ended) return;
_this2._ended = true;
_this2._queueChange();
_this2._deactivate();
}
};
var active = this._active = {
controller: _controller2,
listenHandler: {
unsubscribe: function unsubscribe() {}
}
};
var setValuesError = function setValuesError() {
throw new Error('setValues must be called once during listen');
};
var _setValues2 = function _setValues(values) {
_setValues2 = setValuesError;
makeSetImmutable(values);
_this2._values = values;
_this2._mutableValues = false;
};
var listenHandlerOrFunction = this._init.listen(function (values) {
return _setValues2(values);
}, _controller2);
if (!this._values) {
setValuesError();
}
if (typeof listenHandlerOrFunction === 'function') {
active.listenHandler = {
unsubscribe: listenHandlerOrFunction
};
} else if (listenHandlerOrFunction != null && typeof listenHandlerOrFunction.unsubscribe === 'function') {
active.listenHandler = listenHandlerOrFunction;
} else if (listenHandlerOrFunction != null) {
throw new TypeError('listen must return object with unsubscribe method, a function, or null');
}
if (_controller2.closed) {
this._active = active;
this._deactivate();
}
}
if (observer.start) {
this._inSubscriptionStart = true;
observer.start(subscription);
this._inSubscriptionStart = false;
}
isStarting = false;
observerRecord.ignore = this._changeQueue.length;
if (!unsubscribedInStart) {
this._observers.push(observerRecord);
}
return subscription;
}
}], [{
key: "active",
value: function active(initialValues, options) {
var set = initialValues || new Set();
var controller;
var liveSet = new LiveSet({
scheduler: options ? options.scheduler : undefined,
read: function read() {
return set;
},
listen: function listen(setValues, _controller) {
setValues(set);
controller = _controller;
}
});
liveSet.subscribe({});
return {
liveSet: liveSet,
controller: controller
};
}
}, {
key: "constant",
value: function constant(values, options) {
makeSetImmutable(values);
var shouldNotHappen = function shouldNotHappen() {
throw new Error('Should not happen');
};
var ls = new LiveSet({
scheduler: options ? options.scheduler : undefined,
read: shouldNotHappen,
listen: shouldNotHappen
});
ls._ended = true;
ls._values = values;
ls._mutableValues = false;
return ls;
}
}]);
return LiveSet;
}(); // Assign here because Flow doesn't support computed property keys on classes:
// https://github.com/facebook/flow/issues/2286
exports.default = LiveSet;
(0, _defineProperty2.default)(LiveSet, "defaultScheduler", new _Scheduler.default());
LiveSet.prototype[_symbolObservable.default] = function () {
return this;
};
function makeSetImmutable(set) {
if (process.env.NODE_ENV !== 'production') {
set.add = set.delete = set.clear = readOnly;
}
}
function readOnly() {
throw new Error('Do not modify Set passed to or from LiveSet: Set is read-only in development');
}
module.exports = exports.default;
module.exports.default = exports.default;
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInNyYy9pbmRleC5qcyJdLCJuYW1lcyI6WyJMaXZlU2V0IiwiaW5pdCIsIl9pbml0IiwiX3NjaGVkdWxlciIsInNjaGVkdWxlciIsImRlZmF1bHRTY2hlZHVsZXIiLCJyZWNvcmQiLCJfY2hhbmdlUXVldWUiLCJwdXNoIiwiX3F1ZXVlZENhbGwiLCJzY2hlZHVsZSIsImNoYW5nZXMiLCJvYnNlcnZlcnNUb0NhbGwiLCJlbmRlZCIsIl9lbmRlZCIsIl9vYnNlcnZlcnMiLCJzbGljZSIsImZvckVhY2giLCJvYnNlcnZlciIsImlnbm9yZSIsIm9ic2VydmVyTmV4dCIsIm5leHQiLCJjYWxsIiwiY2hhbmdlc1RvRGVsaXZlciIsImxlbmd0aCIsIl9lbmRlZFdpdGhFcnJvciIsImVycm9yIiwiX2Vycm9yIiwiY29tcGxldGUiLCJfYWN0aXZlIiwiRXJyb3IiLCJsaXN0ZW5IYW5kbGVyIiwidW5zdWJzY3JpYmUiLCJfdmFsdWVzIiwiX2luU3Vic2NyaXB0aW9uU3RhcnQiLCJwdWxsQ2hhbmdlcyIsIl9tdXRhYmxlVmFsdWVzIiwibWFrZVNldEltbXV0YWJsZSIsInMiLCJyZWFkIiwib2JzZXJ2ZXJPck9uTmV4dCIsIm9uRXJyb3IiLCJvbkNvbXBsZXRlIiwibGl2ZVNldCIsInN1YnNjcmlwdGlvbiIsImNsb3NlZCIsInN0YXJ0Iiwib2JzZXJ2ZXJSZWNvcmQiLCJpc1N0YXJ0aW5nIiwidW5zdWJzY3JpYmVkSW5TdGFydCIsImluZGV4T2YiLCJpeCIsInNwbGljZSIsIl9kZWFjdGl2YXRlIiwiY2hhbmdlUXVldWVMZW5ndGgiLCJvcmlnaW5hbE5leHQiLCJjb250cm9sbGVyIiwiYWRkIiwidmFsdWUiLCJ2YWx1ZXMiLCJoYXMiLCJTZXQiLCJfcXVldWVDaGFuZ2UiLCJ0eXBlIiwicmVtb3ZlIiwiZGVsZXRlIiwiZXJyIiwiZW5kIiwiYWN0aXZlIiwic2V0VmFsdWVzRXJyb3IiLCJzZXRWYWx1ZXMiLCJsaXN0ZW5IYW5kbGVyT3JGdW5jdGlvbiIsImxpc3RlbiIsIlR5cGVFcnJvciIsImluaXRpYWxWYWx1ZXMiLCJvcHRpb25zIiwic2V0IiwidW5kZWZpbmVkIiwiX2NvbnRyb2xsZXIiLCJzdWJzY3JpYmUiLCJzaG91bGROb3RIYXBwZW4iLCJscyIsIlNjaGVkdWxlciIsInByb3RvdHlwZSIsIiQkb2JzZXJ2YWJsZSIsInByb2Nlc3MiLCJlbnYiLCJOT0RFX0VOViIsImNsZWFyIiwicmVhZE9ubHkiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7OztBQUVBOztBQUNBOztJQWlEcUJBLE87OztBQU9jO0FBY2pDLG1CQUFZQyxJQUFaLEVBQWtDO0FBQUE7QUFBQTtBQUFBO0FBQUEsbURBZmYsSUFlZTtBQUFBLDBEQWRSLEtBY1E7QUFBQSxtREFUOUIsSUFTOEI7QUFBQSxnRUFSWCxLQVFXO0FBQUEsa0RBUGhCLEtBT2dCO0FBQUEsMkRBTlAsS0FNTztBQUFBLGtEQUxwQixJQUtvQjtBQUFBLHVEQUpYLEtBSVc7QUFBQSx3REFIWSxFQUdaO0FBQUEsc0RBRlksRUFFWjtBQUNoQyxTQUFLQyxLQUFMLEdBQWFELElBQWI7QUFDQSxTQUFLRSxVQUFMLEdBQWtCRixJQUFJLENBQUNHLFNBQUwsSUFBa0JKLE9BQU8sQ0FBQ0ssZ0JBQTVDO0FBQ0Q7Ozs7aUNBaUNZQyxNLEVBQWlDO0FBQUE7O0FBQzVDLFVBQUlBLE1BQUosRUFBWTtBQUNWLGFBQUtDLFlBQUwsQ0FBa0JDLElBQWxCLENBQXVCRixNQUF2QjtBQUNEOztBQUNELFVBQUksQ0FBQyxLQUFLRyxXQUFWLEVBQXVCO0FBQ3JCLGFBQUtBLFdBQUwsR0FBbUIsSUFBbkI7O0FBQ0EsYUFBS04sVUFBTCxDQUFnQk8sUUFBaEIsQ0FBeUIsWUFBTTtBQUM3QixVQUFBLEtBQUksQ0FBQ0QsV0FBTCxHQUFtQixLQUFuQjtBQUNBLGNBQU1FLE9BQU8sR0FBRyxLQUFJLENBQUNKLFlBQXJCO0FBQ0EsVUFBQSxLQUFJLENBQUNBLFlBQUwsR0FBb0IsRUFBcEI7QUFDQSxjQUFJSyxlQUFKO0FBQ0EsY0FBTUMsS0FBSyxHQUFHLEtBQUks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OztLQXNRSDtBQUNBOzs7OzhCQTlUcUJqRixPLHNCQUNPLElBQUlrRixrQkFBSixFOztBQThUM0JsRixPQUFELENBQWNtRixTQUFkLENBQXdCQyx5QkFBeEIsSUFBd0MsWUFBVztBQUNqRCxTQUFPLElBQVA7QUFDRCxDQUZEOztBQUlBLFNBQVMvQyxnQkFBVCxDQUEwQnVDLEdBQTFCLEVBQXlDO0FBQ3ZDLE1BQUlTLE9BQU8sQ0FBQ0MsR0FBUixDQUFZQyxRQUFaLEtBQXlCLFlBQTdCLEVBQTJDO0FBQ3hDWCxJQUFBQSxHQUFELENBQVVuQixHQUFWLEdBQWlCbUIsR0FBRCxDQUFVWCxNQUFWLEdBQW9CVyxHQUFELENBQVVZLEtBQVYsR0FBa0JDLFFBQXJEO0FBQ0Q7QUFDRjs7QUFFRCxTQUFTQSxRQUFULEdBQW9CO0FBQ2xCLFFBQU0sSUFBSTNELEtBQUosQ0FBVSw4RUFBVixDQUFOO0FBQ0QiLCJzb3VyY2VzQ29udGVudCI6WyIvKiBAZmxvdyAqL1xuXG5pbXBvcnQgU2NoZWR1bGVyIGZyb20gJy4vU2NoZWR1bGVyJztcbmltcG9ydCAkJG9ic2VydmFibGUgZnJvbSAnc3ltYm9sLW9ic2VydmFibGUnO1xuXG5leHBvcnQgdHlwZSBMaXZlU2V0Q2hhbmdlUmVjb3JkPCtUPiA9XG4gIHt0eXBlOiAnYWRkJywgK3ZhbHVlOiBUfSB8XG4gIHt0eXBlOiAncmVtb3ZlJywgK3ZhbHVlOiBUfSB8XG4gIHt0eXBlOiAnZW5kJ307XG5cbmV4cG9ydCB0eXBlIExpdmVTZXRDb250cm9sbGVyPC1UPiA9IHtcbiAgY2xvc2VkOiBib29sZWFuO1xuICBhZGQoaXRlbTogVCk6IHZvaWQ7XG4gIHJlbW92ZShpdGVtOiBUKTogdm9pZDtcbiAgZXJyb3IoZXJyOiBhbnkpOiB2b2lkO1xuICBlbmQoKTogdm9pZDtcbn07XG5cbmV4cG9ydCB0eXBlIExpc3RlbkhhbmRsZXIgPSB7XG4gIHVuc3Vic2NyaWJlKCk6IHZvaWQ7XG4gICtwdWxsQ2hhbmdlcz86ICgpID0+IHZvaWQ7XG59O1xuXG5leHBvcnQgdHlwZSBMaXZlU2V0SW5pdDxUPiA9IHtcbiAgc2NoZWR1bGVyPzogU2NoZWR1bGVyO1xuICByZWFkKCk6IFNldDxUPjtcbiAgbGlzdGVuKFxuICAgIHNldFZhbHVlczogeyAodmFsdWVzOiBTZXQ8VD4pOiB2b2lkIH0sXG4gICAgY29udHJvbGxlcjogTGl2ZVNldENvbnRyb2xsZXI8VD5cbiAgKTogdm9pZHxMaXN0ZW5IYW5kbGVyfCgpPT52b2lkO1xufTtcblxuZXhwb3J0IHR5cGUgTGl2ZVNldFN1YnNjcmliZXI8LVQ+ID0gKGNoYW5nZXM6ICRSZWFkT25seUFycmF5PExpdmVTZXRDaGFuZ2VSZWNvcmQ8VD4+KSA9PiB2b2lkO1xuXG5leHBvcnQgdHlwZSBMaXZlU2V0U3Vic2NyaXB0aW9uID0ge1xuICBjbG9zZWQ6IGJvb2xlYW47XG4gIHVuc3Vic2NyaWJlKCk6IHZvaWQ7XG4gIHB1bGxDaGFuZ2VzKCk6IHZvaWQ7XG59O1xuXG5leHBvcnQgdHlwZSBMaXZlU2V0T2JzZXJ2ZXI8LVQ+ID0ge1xuICArc3RhcnQ/OiA/KHN1YnNjcmlwdGlvbjogTGl2ZVNldFN1YnNjcmlwdGlvbikgPT4gdm9pZDtcbiAgK25leHQ/OiA/TGl2ZVNldFN1YnNjcmliZXI8VD47XG4gICtlcnJvcj86ID8oZXJyOiBhbnkpID0+IHZvaWQ7XG4gICtjb21wbGV0ZT86ID8oKSA9PiB2b2lkO1xufTtcblxudHlwZSBMaXZlU2V0T2JzZXJ2ZXJSZWNvcmQ8VD4gPSB7XG4gIGlnbm9yZTogbnVtYmVyO1xuICBvYnNlcnZlcjogTGl2ZVNldE9ic2VydmVyPFQ+O1xufTtcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgTGl2ZVNldDxUPiB7XG4gIHN0YXRpYyBkZWZhdWx0U2NoZWR1bGVyID0gbmV3IFNjaGVkdWxlcigpO1xuXG4gIF9pbml0OiBMaXZlU2V0SW5pdDxUPjtcbiAgX3NjaGVkdWxlcjogU2NoZWR1bGVyO1xuXG4gIF92YWx1ZXM6ID9TZXQ8VD4gPSBudWxsO1xuICBfbXV0YWJsZVZhbHVlczogYm9vbGVhbiA9IGZhbHNlOyAvLyBXaGV0aGVyIHdlIGNhbiBtdXRhdGUgdGhlIF92YWx1ZXMgU2V0LlxuXG4gIF9hY3RpdmU6ID97XG4gICAgY29udHJvbGxlcjogTGl2ZVNldENvbnRyb2xsZXI8VD47XG4gICAgbGlzdGVuSGFuZGxlcjogTGlzdGVuSGFuZGxlcjtcbiAgfSA9IG51bGw7XG4gIF9pblN1YnNjcmlwdGlvblN0YXJ0ID0gZmFsc2U7XG4gIF9lbmRlZDogYm9vbGVhbiA9IGZhbHNlO1xuICBfZW5kZWRXaXRoRXJyb3I6IGJvb2xlYW4gPSBmYWxzZTtcbiAgX2Vycm9yOiBhbnkgPSBudWxsO1xuICBfcXVldWVkQ2FsbDogYm9vbGVhbiA9IGZhbHNlO1xuICBfY2hhbmdlUXVldWU6IEFycmF5PExpdmVTZXRDaGFuZ2VSZWNvcmQ8VD4+ID0gW107XG4gIF9vYnNlcnZlcnM6IEFycmF5PExpdmVTZXRPYnNlcnZlclJlY29yZDxUPj4gPSBbXTtcblxuICBjb25zdHJ1Y3Rvcihpbml0OiBMaXZlU2V0SW5pdDxUPikge1xuICAgIHRoaXMuX2luaXQgPSBpbml0O1xuICAgIHRoaXMuX3NjaGVkdWxlciA9IGluaXQuc2NoZWR1bGVyIHx8IExpdmVTZXQuZGVmYXVsdFNjaGVkdWxlcjtcbiAgfVxuXG4gIHN0YXRpYyBhY3RpdmU8VD4oaW5pdGlhbFZhbHVlczogP1NldDxUPiwgb3B0aW9uczogP3tzY2hlZHVsZXI/OiBTY2hlZHVsZXJ9KToge2xpdmVTZXQ6IExpdmVTZXQ8VD4sIGNvbnRyb2xsZXI6IExpdmVTZXRDb250cm9sbGVyPFQ+fSB7XG4gICAgY29uc3Qgc2V0ID0gaW5pdGlhbFZhbHVlcyB8fCBuZXcgU2V0KCk7XG4gICAgbGV0IGNvbnRyb2xsZXI7XG4gICAgY29uc3QgbGl2ZVNldCA9IG5ldyBMaXZlU2V0KHtcbiAgICAgIHNjaGVkdWxlcjogb3B0aW9ucyA/IG9wdGlvbnMuc2NoZWR1bGVyIDogdW5kZWZpbmVkLFxuICAgICAgcmVhZDogKCkgPT4gc2V0LFxuICAgICAgbGlzdGVuOiAoc2V0VmFsdWVzLCBfY29udHJvbGxlcikgPT4ge1xuICAgICAgICBzZXRWYWx1ZXMoc2V0KTtcbiAgICAgICAgY29udHJvbGxlciA9IF9jb250cm9sbGVyO1xuICAgICAgfVxuICAgIH0pO1xuICAgIGxpdmVTZXQuc3Vic2NyaWJlKHt9KTtcbiAgICByZXR1cm4ge2xpdmVTZXQsIGNvbnRyb2xsZXI6IChjb250cm9sbGVyOiBhbnkpfTtcbiAgfVxuXG4gIHN0YXRpYyBjb25zdGFudDxUPih2YWx1ZXM6IFNldDxUPiwgb3B0aW9uczogP3tzY2hlZHVsZXI/OiBTY2hlZHVsZXJ9KTogTGl2ZVNldDxUPiB7XG4gICAgbWFrZVNldEltbXV0YWJsZSh2YWx1ZXMpO1xuICAgIGNvbnN0IHNob3VsZE5vdEhhcHBlbiA9ICgpID0+IHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignU2hvdWxkIG5vdCBoYXBwZW4nKTtcbiAgICB9O1xuICAgIGNvbnN0IGxzID0gbmV3IExpdmVTZXQoe1xuICAgICAgc2NoZWR1bGVyOiBvcHRpb25zID8gb3B0aW9ucy5zY2hlZHVsZXIgOiB1bmRlZmluZWQsXG4gICAgICByZWFkOiBzaG91bGROb3RIYXBwZW4sXG4gICAgICBsaXN0ZW46IHNob3VsZE5vdEhhcHBlblxuICAgIH0pO1xuICAgIGxzLl9lbmRlZCA9IHRydWU7XG4gICAgbHMuX3ZhbHVlcyA9IHZhbHVlcztcbiAgICBscy5fbXV0YWJsZVZhbHVlcyA9IGZhbHNlO1xuICAgIHJldHVybiBscztcbiAgfVxuXG4gIF9xdWV1ZUNoYW5nZShyZWNvcmQ6ID9MaXZlU2V0Q2hhbmdlUmVjb3JkPFQ+KSB7XG4gICAgaWYgKHJlY29yZCkge1xuICAgICAgdGhpcy5fY2hhbmdlUXVldWUucHVzaChyZWNvcmQpO1xuICAgIH1cbiAgICBpZiAoIXRoaXMuX3F1ZXVlZENhbGwpIHtcbiAgICAgIHRoaXMuX3F1ZXVlZENhbGwgPSB0cnVlO1xuICAgICAgdGhpcy5fc2NoZWR1bGVyLnNjaGVkdWxlKCgpID0+IHtcbiAgICAgICAgdGhpcy5fcXVldWVkQ2FsbCA9IGZhbHNlO1xuICAgICAgICBjb25zdCBjaGFuZ2VzID0gdGhpcy5fY2hhbmdlUXVldWU7XG4gICAgICAgIHRoaXMuX2NoYW5nZVF1ZXVlID0gW107XG4gICAgICAgIGxldCBvYnNlcnZlcnNUb0NhbGw7XG4gICAgICAgIGNvbnN0IGVuZGVkID0gdGhpcy5fZW5kZWQ7XG4gICAgICAgIGlmIChlbmRlZCkge1xuICAgICAgICAgIG9ic2VydmVyc1RvQ2FsbCA9IHRoaXMuX29ic2VydmVycztcbiAgICAgICAgICB0aGlzLl9vYnNlcnZlcnMgPSBbXTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBvYnNlcnZlcnNUb0NhbGwgPSB0aGlzLl9vYnNlcnZlcnMuc2xpY2UoKTtcbiAgICAgICAgfVxuICAgICAgICBvYnNlcnZlcnNUb0NhbGwuZm9yRWFjaChyZWNvcmQgPT4ge1xuICAgICAgICAgIGNvbnN0IHtvYnNlcnZlciwgaWdub3JlfSA9IHJlY29yZDtcbiAgICAgICAgICBjb25zdCBvYnNlcnZlck5leHQgPSBvYnNlcnZlci5uZXh0O1xuICAgICAgICAgIGlmIChvYnNlcnZlck5leHQpIHtcbiAgICAgICAgICAgIGlmIChpZ25vcmUgPT09IDApIHtcbiAgICAgICAgICAgICAgb2JzZXJ2ZXJOZXh0LmNhbGwob2JzZXJ2ZXIsIGNoYW5nZXMpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgcmVjb3JkLmlnbm9yZSA9IDA7XG4gICAgICAgICAgICAgIGNvbnN0IGNoYW5nZXNUb0RlbGl2ZXIgPSBjaGFuZ2VzLnNsaWNlKGlnbm9yZSk7XG4gICAgICAgICAgICAgIGlmIChjaGFuZ2VzVG9EZWxpdmVyLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIG9ic2VydmVyTmV4dC5jYWxsKG9ic2VydmVyLCBjaGFuZ2VzVG9EZWxpdmVyKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoZW5kZWQpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLl9lbmRlZFdpdGhFcnJvcikge1xuICAgICAgICAgICAgICBpZiAob2JzZXJ2ZXIuZXJyb3IpIG9ic2VydmVyLmVycm9yKHRoaXMuX2Vycm9yKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIGlmIChvYnNlcnZlci5jb21wbGV0ZSkgb2JzZXJ2ZXIuY29tcGxldGUoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgX2RlYWN0aXZhdGUoKSB7XG4gICAgaWYgKCF0aGlzLl9hY3RpdmUpIHRocm93IG5ldyBFcnJvcignYWxyZWFkeSBpbmFjdGl2ZScpO1xuICAgIGNvbnN0IHtsaXN0ZW5IYW5kbGVyfSA9IHRoaXMuX2FjdGl2ZTtcbiAgICB0aGlzLl9hY3RpdmUgPSBudWxsO1xuICAgIGlmIChsaXN0ZW5IYW5kbGVyKSB7XG4gICAgICBsaXN0ZW5IYW5kbGVyLnVuc3Vic2NyaWJlKCk7XG4gICAgfVxuICB9XG5cbiAgdmFsdWVzKCk6IFNldDxUPiB7XG4gICAgaWYgKHRoaXMuX3ZhbHVlcykge1xuICAgICAgaWYgKHRoaXMuX2FjdGl2ZSAmJiAhdGhpcy5faW5TdWJzY3JpcHRpb25TdGFydCkge1xuICAgICAgICBjb25zdCB7bGlzdGVuSGFuZGxlcn0gPSB0aGlzLl9hY3RpdmU7XG4gICAgICAgIGlmIChsaXN0ZW5IYW5kbGVyLnB1bGxDaGFuZ2VzKSB7XG4gICAgICAgICAgbGlzdGVuSGFuZGxlci5wdWxsQ2hhbmdlcygpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAodGhpcy5fbXV0YWJsZVZhbHVlcykge1xuICAgICAgICB0aGlzLl9tdXRhYmxlVmFsdWVzID0gZmFsc2U7XG4gICAgICAgIG1ha2VTZXRJbW11dGFibGUodGhpcy5fdmFsdWVzKTtcbiAgICAgIH1cbiAgICAgIC8qOjogaWYgKCF0aGlzLl92YWx1ZXMpIHRocm93IG5ldyBFcnJvcigpOyAqL1xuICAgICAgcmV0dXJuIHRoaXMuX3ZhbHVlcztcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKHRoaXMuX2FjdGl2ZSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ3RyaWVkIHRvIGNhbGwgdmFsdWVzKCkgb24gbGl2ZXNldCBkdXJpbmcgc3Vic2NyaXB0aW9uIGJlZm9yZSBzZXRWYWx1ZXMgd2FzIGNhbGxlZCcpO1xuICAgICAgfVxuICAgICAgY29uc3QgcyA9IHRoaXMuX2luaXQucmVhZCgpO1xuICAgICAgbWFrZVNldEltbXV0YWJsZShzKTtcbiAgICAgIHJldHVybiBzO1xuICAgIH1cbiAgfVxuXG4gIGlzRW5kZWQoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuX2VuZGVkO1xuICB9XG5cbiAgZ2V0U2NoZWR1bGVyKCk6IFNjaGVkdWxlciB7XG4gICAgcmV0dXJuIHRoaXMuX3NjaGVkdWxlcjtcbiAgfVxuXG4gIHN1YnNjcmliZShvYnNlcnZlck9yT25OZXh0OiBMaXZlU2V0T2JzZXJ2ZXI8VD4gfCBMaXZlU2V0U3Vic2NyaWJlcjxUPiwgb25FcnJvcjogPyhlcnI6IGFueSkgPT4gdm9pZCwgb25Db21wbGV0ZTogPygpID0+IHZvaWQpOiBMaXZlU2V0U3Vic2NyaXB0aW9uIHtcbiAgICBjb25zdCBsaXZlU2V0ID0gdGhpcztcblxuICAgIGxldCBvYnNlcnZlcjtcbiAgICBpZiAodHlwZW9mIG9ic2VydmVyT3JPbk5leHQgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIG9ic2VydmVyID0ge1xuICAgICAgICBuZXh0OiBvYnNlcnZlck9yT25OZXh0LFxuICAgICAgICBlcnJvcjogb25FcnJvcixcbiAgICAgICAgY29tcGxldGU6IG9uQ29tcGxldGVcbiAgICAgIH07XG4gICAgfSBlbHNlIHtcbiAgICAgIG9ic2VydmVyID0gb2JzZXJ2ZXJPck9uTmV4dDtcbiAgICB9XG5cbiAgICAob2JzZXJ2ZXI6IExpdmVTZXRPYnNlcnZlcjxUPik7XG5cbiAgICBpZiAodGhpcy5fZW5kZWQpIHtcbiAgICAgIGNvbnN0IHN1YnNjcmlwdGlvbiA9IHtcbiAgICAgICAgY2xvc2VkOiBmYWxzZSxcbiAgICAgICAgdW5zdWJzY3JpYmU6ICgpID0+IHtcbiAgICAgICAgICBzdWJzY3JpcHRpb24uY2xvc2VkID0gdHJ1ZTtcbiAgICAgICAgfSxcbiAgICAgICAgcHVsbENoYW5nZXM6ICgpID0+IHt9XG4gICAgICB9O1xuICAgICAgaWYgKG9ic2VydmVyLnN0YXJ0KSB7XG4gICAgICAgIG9ic2VydmVyLnN0YXJ0KHN1YnNjcmlwdGlvbik7XG4gICAgICB9XG4gICAgICBpZiAoIXN1YnNjcmlwdGlvbi5jbG9zZWQpIHtcbiAgICAgICAgaWYgKHRoaXMuX2VuZGVkV2l0aEVycm9yKSB7XG4gICAgICAgICAgaWYgKG9ic2VydmVyLmVycm9yKSB7XG4gICAgICAgICAgICBvYnNlcnZlci5lcnJvcih0aGlzLl9lcnJvcik7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGlmIChvYnNlcnZlci5jb21wbGV0ZSkge1xuICAgICAgICAgICAgb2JzZXJ2ZXIuY29tcGxldGUoKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHN1YnNjcmlwdGlvbi5jbG9zZWQgPSB0cnVlO1xuICAgICAgcmV0dXJuIHN1YnNjcmlwdGlvbjtcbiAgICB9XG5cbiAgICBjb25zdCBvYnNlcnZlclJlY29yZCA9IHtvYnNlcnZlciwgaWdub3JlOiB0aGlzLl9jaGFuZ2VRdWV1ZS5sZW5ndGh9O1xuXG4gICAgbGV0IGlzU3RhcnRpbmcgPSB0cnVlO1xuICAgIGxldCB1bnN1YnNjcmliZWRJblN0YXJ0ID0gZmFsc2U7XG4gICAgY29uc3Qgc3Vic2NyaXB0aW9uID0ge1xuICAgICAgLyo6OiBjbG9zZWQ6IGZhbHNlJiZgICovIGdldCBjbG9zZWQoKSB7XG4gICAgICAgIHJldHVybiAhaXNTdGFydGluZyAmJiBsaXZlU2V0Ll9vYnNlcnZlcnMuaW5kZXhPZihvYnNlcnZlclJlY29yZCkgPCAwO1xuICAgICAgfS8qOjogYCAqLyxcbiAgICAgIHVuc3Vic2NyaWJlOiAoKSA9PiB7XG4gICAgICAgIGlmIChpc1N0YXJ0aW5nKSB7XG4gICAgICAgICAgdW5zdWJzY3JpYmVkSW5TdGFydCA9IHRydWU7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGl4ID0gdGhpcy5fb2JzZXJ2ZXJzLmluZGV4T2Yob2JzZXJ2ZXJSZWNvcmQpO1xuICAgICAgICBpZiAoaXggPj0gMCkge1xuICAgICAgICAgIHRoaXMuX29ic2VydmVycy5zcGxpY2UoaXgsIDEpO1xuICAgICAgICAgIGlmICghdGhpcy5fZW5kZWQgJiYgdGhpcy5fb2JzZXJ2ZXJzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgdGhpcy5fdmFsdWVzID0gbnVsbDtcbiAgICAgICAgICAgIHRoaXMuX2RlYWN0aXZhdGUoKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgICBwdWxsQ2hhbmdlczogKCkgPT4ge1xuICAgICAgICBpZiAodGhpcy5fYWN0aXZlICYmIHRoaXMuX2FjdGl2ZS5saXN0ZW5IYW5kbGVyICYmIHRoaXMuX2FjdGl2ZS5saXN0ZW5IYW5kbGVyLnB1bGxDaGFuZ2VzKSB7XG4gICAgICAgICAgdGhpcy5fYWN0aXZlLmxpc3RlbkhhbmRsZXIucHVsbENoYW5nZXMoKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBjaGFuZ2VRdWV1ZUxlbmd0aCA9IHRoaXMuX2NoYW5nZVF1ZXVlLmxlbmd0aDtcbiAgICAgICAgY29uc3Qgb3JpZ2luYWxOZXh0ID0gb2JzZXJ2ZXIubmV4dDtcbiAgICAgICAgaWYgKGNoYW5nZVF1ZXVlTGVuZ3RoICE9PSAwICYmIG9yaWdpbmFsTmV4dCkge1xuICAgICAgICAgIGNvbnN0IGNoYW5nZXNUb0RlbGl2ZXIgPSB0aGlzLl9jaGFuZ2VRdWV1ZS5zbGljZShvYnNlcnZlclJlY29yZC5pZ25vcmUpO1xuICAgICAgICAgIGlmIChjaGFuZ2VzVG9EZWxpdmVyLmxlbmd0aCAhPT0gMCkge1xuICAgICAgICAgICAgb2JzZXJ2ZXJSZWNvcmQuaWdub3JlID0gY2hhbmdlUXVldWVMZW5ndGg7XG4gICAgICAgICAgICBvcmlnaW5hbE5leHQuY2FsbChvYnNlcnZlciwgY2hhbmdlc1RvRGVsaXZlcik7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfTtcblxuICAgIGlmICghdGhpcy5fYWN0aXZlKSB7XG4gICAgICBjb25zdCBjb250cm9sbGVyOiBMaXZlU2V0Q29udHJvbGxlcjxUPiA9IHtcbiAgICAgICAgLy8gRmxvdyBkb2Vzbid0IHN1cHBvcnQgZ2V0dGVycyBhbmQgc2V0dGVycyB5ZXRcbiAgICAgICAgLyo6OiBjbG9zZWQ6IGZhbHNlJiZgICovIGdldCBjbG9zZWQoKSB7XG4gICAgICAgICAgcmV0dXJuICFsaXZlU2V0Ll9hY3RpdmUgfHwgbGl2ZVNldC5fYWN0aXZlLmNvbnRyb2xsZXIgIT09IHRoaXM7XG4gICAgICAgIH0vKjo6IGAgKi8sXG4gICAgICAgIGFkZDogdmFsdWUgPT4ge1xuICAgICAgICAgIGxldCB2YWx1ZXMgPSB0aGlzLl92YWx1ZXM7XG4gICAgICAgICAgaWYgKCF2YWx1ZXMpIHRocm93IG5ldyBFcnJvcignc2V0VmFsdWUgbXVzdCBiZSBjYWxsZWQgYmVmb3JlIGNvbnRyb2xsZXIgaXMgdXNlZCcpO1xuICAgICAgICAgIGlmICghdGhpcy5fZW5kZWQgJiYgIXZhbHVlcy5oYXModmFsdWUpKSB7XG4gICAgICAgICAgICBpZiAoIXRoaXMuX211dGFibGVWYWx1ZXMpIHtcbiAgICAgICAgICAgICAgdGhpcy5fdmFsdWVzID0gdmFsdWVzID0gbmV3IFNldCh2YWx1ZXMpO1xuICAgICAgICAgICAgICB0aGlzLl9tdXRhYmxlVmFsdWVzID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHZhbHVlcy5hZGQodmFsdWUpO1xuICAgICAgICAgICAgdGhpcy5fcXVldWVDaGFuZ2Uoe3R5cGU6ICdhZGQnLCB2YWx1ZX0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfSxcbiAgICAgICAgcmVtb3ZlOiB2YWx1ZSA9PiB7XG4gICAgICAgICAgbGV0IHZhbHVlcyA9IHRoaXMuX3ZhbHVlcztcbiAgICAgICAgICBpZiAoIXZhbHVlcykgdGhyb3cgbmV3IEVycm9yKCdzZXRWYWx1ZSBtdXN0IGJlIGNhbGxlZCBiZWZvcmUgY29udHJvbGxlciBpcyB1c2VkJyk7XG4gICAgICAgICAgaWYgKCF0aGlzLl9lbmRlZCAmJiB2YWx1ZXMuaGFzKHZhbHVlKSkge1xuICAgICAgICAgICAgaWYgKCF0aGlzLl9tdXRhYmxlVmFsdWVzKSB7XG4gICAgICAgICAgICAgIHRoaXMuX3ZhbHVlcyA9IHZhbHVlcyA9IG5ldyBTZXQodmFsdWVzKTtcbiAgICAgICAgICAgICAgdGhpcy5fbXV0YWJsZVZhbHVlcyA9IHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB2YWx1ZXMuZGVsZXRlKHZhbHVlKTtcbiAgICAgICAgICAgIHRoaXMuX3F1ZXVlQ2hhbmdlKHt0eXBlOiAncmVtb3ZlJywgdmFsdWV9KTtcbiAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICAgIGVycm9yOiBlcnIgPT4ge1xuICAgICAgICAgIGlmICh0aGlzLl9lbmRlZCkgcmV0dXJuO1xuICAgICAgICAgIHRoaXMuX2VuZGVkID0gdHJ1ZTtcbiAgICAgICAgICB0aGlzLl9lbmRlZFdpdGhFcnJvciA9IHRydWU7XG4gICAgICAgICAgdGhpcy5fZXJyb3IgPSBlcnI7XG4gICAgICAgICAgdGhpcy5fcXVldWVDaGFuZ2UoKTtcbiAgICAgICAgICB0aGlzLl9kZWFjdGl2YXRlKCk7XG4gICAgICAgIH0sXG4gICAgICAgIGVuZDogKCkgPT4ge1xuICAgICAgICAgIGlmICh0aGlzLl9lbmRlZCkgcmV0dXJuO1xuICAgICAgICAgIHRoaXMuX2VuZGVkID0gdHJ1ZTtcbiAgICAgICAgICB0aGlzLl9xdWV1ZUNoYW5nZSgpO1xuICAgICAgICAgIHRoaXMuX2RlYWN0aXZhdGUoKTtcbiAgICAgICAgfVxuICAgICAgfTtcbiAgICAgIGNvbnN0IGFjdGl2ZSA9IHRoaXMuX2FjdGl2ZSA9IHtcbiAgICAgICAgY29udHJvbGxlcixcbiAgICAgICAgbGlzdGVuSGFuZGxlcjoge1xuICAgICAgICAgIHVuc3Vic2NyaWJlOiAoKSA9PiB7fVxuICAgICAgICB9XG4gICAgICB9O1xuICAgICAgY29uc3Qgc2V0VmFsdWVzRXJyb3I6IEZ1bmN0aW9uID0gKCkgPT4ge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ3NldFZhbHVlcyBtdXN0IGJlIGNhbGxlZCBvbmNlIGR1cmluZyBsaXN0ZW4nKTtcbiAgICAgIH07XG4gICAgICBsZXQgc2V0VmFsdWVzID0gdmFsdWVzID0+IHtcbiAgICAgICAgc2V0VmFsdWVzID0gc2V0VmFsdWVzRXJyb3I7XG4gICAgICAgIG1ha2VTZXRJbW11dGFibGUodmFsdWVzKTtcbiAgICAgICAgdGhpcy5fdmFsdWVzID0gdmFsdWVzO1xuICAgICAgICB0aGlzLl9tdXRhYmxlVmFsdWVzID0gZmFsc2U7XG4gICAgICB9O1xuICAgICAgY29uc3QgbGlzdGVuSGFuZGxlck9yRnVuY3Rpb24gPSB0aGlzLl9pbml0Lmxpc3Rlbih2YWx1ZXMgPT4gc2V0VmFsdWVzKHZhbHVlcyksIGNvbnRyb2xsZXIpO1xuICAgICAgaWYgKCF0aGlzLl92YWx1ZXMpIHtcbiAgICAgICAgc2V0VmFsdWVzRXJyb3IoKTtcbiAgICAgIH1cbiAgICAgIGlmICh0eXBlb2YgbGlzdGVuSGFuZGxlck9yRnVuY3Rpb24gPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgYWN0aXZlLmxpc3RlbkhhbmRsZXIgPSB7XG4gICAgICAgICAgdW5zdWJzY3JpYmU6IGxpc3RlbkhhbmRsZXJPckZ1bmN0aW9uXG4gICAgICAgIH07XG4gICAgICB9IGVsc2UgaWYgKGxpc3RlbkhhbmRsZXJPckZ1bmN0aW9uICE9IG51bGwgJiYgdHlwZW9mIGxpc3RlbkhhbmRsZXJPckZ1bmN0aW9uLnVuc3Vic2NyaWJlID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIGFjdGl2ZS5saXN0ZW5IYW5kbGVyID0gbGlzdGVuSGFuZGxlck9yRnVuY3Rpb247XG4gICAgICB9IGVsc2UgaWYgKGxpc3RlbkhhbmRsZXJPckZ1bmN0aW9uICE9IG51bGwpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignbGlzdGVuIG11c3QgcmV0dXJuIG9iamVjdCB3aXRoIHVuc3Vic2NyaWJlIG1ldGhvZCwgYSBmdW5jdGlvbiwgb3IgbnVsbCcpO1xuICAgICAgfVxuICAgICAgaWYgKGNvbnRyb2xsZXIuY2xvc2VkKSB7XG4gICAgICAgIHRoaXMuX2FjdGl2ZSA9IGFjdGl2ZTtcbiAgICAgICAgdGhpcy5fZGVhY3RpdmF0ZSgpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChvYnNlcnZlci5zdGFydCkge1xuICAgICAgdGhpcy5faW5TdWJzY3JpcHRpb25TdGFydCA9IHRydWU7XG4gICAgICBvYnNlcnZlci5zdGFydChzdWJzY3JpcHRpb24pO1xuICAgICAgdGhpcy5faW5TdWJzY3JpcHRpb25TdGFydCA9IGZhbHNlO1xuICAgIH1cbiAgICBpc1N0YXJ0aW5nID0gZmFsc2U7XG5cbiAgICBvYnNlcnZlclJlY29yZC5pZ25vcmUgPSB0aGlzLl9jaGFuZ2VRdWV1ZS5sZW5ndGg7XG4gICAgaWYgKCF1bnN1YnNjcmliZWRJblN0YXJ0KSB7XG4gICAgICB0aGlzLl9vYnNlcnZlcnMucHVzaChvYnNlcnZlclJlY29yZCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHN1YnNjcmlwdGlvbjtcbiAgfVxufVxuXG4vLyBBc3NpZ24gaGVyZSBiZWNhdXNlIEZsb3cgZG9lc24ndCBzdXBwb3J0IGNvbXB1dGVkIHByb3BlcnR5IGtleXMgb24gY2xhc3Nlczpcbi8vIGh0dHBzOi8vZ2l0aHViLmNvbS9mYWNlYm9vay9mbG93L2lzc3Vlcy8yMjg2XG4oTGl2ZVNldDphbnkpLnByb3RvdHlwZVskJG9ic2VydmFibGVdID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiB0aGlzO1xufTtcblxuZnVuY3Rpb24gbWFrZVNldEltbXV0YWJsZShzZXQ6IFNldDxhbnk+KSB7XG4gIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSB7XG4gICAgKHNldDphbnkpLmFkZCA9IChzZXQ6YW55KS5kZWxldGUgPSAoc2V0OmFueSkuY2xlYXIgPSByZWFkT25seTtcbiAgfVxufVxuXG5mdW5jdGlvbiByZWFkT25seSgpIHtcbiAgdGhyb3cgbmV3IEVycm9yKCdEbyBub3QgbW9kaWZ5IFNldCBwYXNzZWQgdG8gb3IgZnJvbSBMaXZlU2V0OiBTZXQgaXMgcmVhZC1vbmx5IGluIGRldmVsb3BtZW50Jyk7XG59XG4iXX0=