@glimmer/runtime
Version:
Minimal runtime needed to render Glimmer templates
432 lines (353 loc) • 41.9 kB
JavaScript
function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; subClass.__proto__ = superClass; }
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
import { DEBUG } from '@glimmer/env';
import { updateRef, valueForRef } from '@glimmer/reference';
import { associateDestroyableChild, destroy, destroyChildren } from '@glimmer/destroyable';
import { Stack, logStep } from '@glimmer/util';
import { resetTracking, runInTrackingTransaction } from '@glimmer/validator';
import { clear, move as moveBounds } from '../bounds';
import { NewElementBuilder } from './element-builder';
var UpdatingVMImpl = /*#__PURE__*/function () {
function UpdatingVMImpl(env, _ref) {
var _ref$alwaysRevalidate = _ref.alwaysRevalidate,
alwaysRevalidate = _ref$alwaysRevalidate === void 0 ? false : _ref$alwaysRevalidate;
this.frameStack = new Stack();
this.env = env;
this.dom = env.getDOM();
this.alwaysRevalidate = alwaysRevalidate;
}
var _proto = UpdatingVMImpl.prototype;
_proto.execute = function execute(opcodes, handler) {
var _this = this;
if (DEBUG) {
var hasErrored = true;
try {
runInTrackingTransaction(function () {
return _this._execute(opcodes, handler);
}, '- While rendering:'); // using a boolean here to avoid breaking ergonomics of "pause on uncaught exceptions"
// which would happen with a `catch` + `throw`
hasErrored = false;
} finally {
if (hasErrored) {
// eslint-disable-next-line no-console
console.error("\n\nError occurred:\n\n" + resetTracking() + "\n\n");
}
}
} else {
this._execute(opcodes, handler);
}
};
_proto._execute = function _execute(opcodes, handler) {
var frameStack = this.frameStack;
this["try"](opcodes, handler);
while (true) {
if (frameStack.isEmpty()) break;
var opcode = this.frame.nextStatement();
if (opcode === undefined) {
frameStack.pop();
continue;
}
opcode.evaluate(this);
}
};
_proto["goto"] = function goto(index) {
this.frame["goto"](index);
};
_proto["try"] = function _try(ops, handler) {
this.frameStack.push(new UpdatingVMFrame(ops, handler));
};
_proto["throw"] = function _throw() {
this.frame.handleException();
this.frameStack.pop();
};
_createClass(UpdatingVMImpl, [{
key: "frame",
get: function get() {
return this.frameStack.current;
}
}]);
return UpdatingVMImpl;
}();
export { UpdatingVMImpl as default };
export var ResumableVMStateImpl = /*#__PURE__*/function () {
function ResumableVMStateImpl(state, resumeCallback) {
this.state = state;
this.resumeCallback = resumeCallback;
}
var _proto2 = ResumableVMStateImpl.prototype;
_proto2.resume = function resume(runtime, builder) {
return this.resumeCallback(runtime, this.state, builder);
};
return ResumableVMStateImpl;
}();
export var BlockOpcode = /*#__PURE__*/function () {
function BlockOpcode(state, runtime, bounds, children) {
this.state = state;
this.runtime = runtime;
this.children = children;
this.bounds = bounds;
}
var _proto3 = BlockOpcode.prototype;
_proto3.parentElement = function parentElement() {
return this.bounds.parentElement();
};
_proto3.firstNode = function firstNode() {
return this.bounds.firstNode();
};
_proto3.lastNode = function lastNode() {
return this.bounds.lastNode();
};
_proto3.evaluate = function evaluate(vm) {
vm["try"](this.children, null);
};
return BlockOpcode;
}();
export var TryOpcode = /*#__PURE__*/function (_BlockOpcode) {
_inheritsLoose(TryOpcode, _BlockOpcode);
function TryOpcode() {
var _this2;
_this2 = _BlockOpcode.apply(this, arguments) || this;
_this2.type = 'try';
return _this2;
}
var _proto4 = TryOpcode.prototype;
_proto4.evaluate = function evaluate(vm) {
vm["try"](this.children, this);
};
_proto4.handleException = function handleException() {
var _this3 = this;
var state = this.state,
bounds = this.bounds,
runtime = this.runtime;
destroyChildren(this);
var elementStack = NewElementBuilder.resume(runtime.env, bounds);
var vm = state.resume(runtime, elementStack);
var updating = [];
var children = this.children = [];
var result = vm.execute(function (vm) {
vm.pushUpdating(updating);
vm.updateWith(_this3);
vm.pushUpdating(children);
});
associateDestroyableChild(this, result.drop);
};
return TryOpcode;
}(BlockOpcode);
export var ListItemOpcode = /*#__PURE__*/function (_TryOpcode) {
_inheritsLoose(ListItemOpcode, _TryOpcode);
function ListItemOpcode(state, runtime, bounds, key, memo, value) {
var _this4;
_this4 = _TryOpcode.call(this, state, runtime, bounds, []) || this;
_this4.key = key;
_this4.memo = memo;
_this4.value = value;
_this4.retained = false;
_this4.index = -1;
return _this4;
}
var _proto5 = ListItemOpcode.prototype;
_proto5.updateReferences = function updateReferences(item) {
this.retained = true;
updateRef(this.value, item.value);
updateRef(this.memo, item.memo);
};
_proto5.shouldRemove = function shouldRemove() {
return !this.retained;
};
_proto5.reset = function reset() {
this.retained = false;
};
return ListItemOpcode;
}(TryOpcode);
export var ListBlockOpcode = /*#__PURE__*/function (_BlockOpcode2) {
_inheritsLoose(ListBlockOpcode, _BlockOpcode2);
function ListBlockOpcode(state, runtime, bounds, children, iterableRef) {
var _this5;
_this5 = _BlockOpcode2.call(this, state, runtime, bounds, children) || this;
_this5.iterableRef = iterableRef;
_this5.type = 'list-block';
_this5.opcodeMap = new Map();
_this5.marker = null;
_this5.lastIterator = valueForRef(iterableRef);
return _this5;
}
var _proto6 = ListBlockOpcode.prototype;
_proto6.initializeChild = function initializeChild(opcode) {
opcode.index = this.children.length - 1;
this.opcodeMap.set(opcode.key, opcode);
};
_proto6.evaluate = function evaluate(vm) {
var iterator = valueForRef(this.iterableRef);
if (this.lastIterator !== iterator) {
var bounds = this.bounds;
var dom = vm.dom;
var marker = this.marker = dom.createComment('');
dom.insertAfter(bounds.parentElement(), marker, bounds.lastNode());
this.sync(iterator);
this.parentElement().removeChild(marker);
this.marker = null;
this.lastIterator = iterator;
} // Run now-updated updating opcodes
_BlockOpcode2.prototype.evaluate.call(this, vm);
};
_proto6.sync = function sync(iterator) {
var itemMap = this.opcodeMap,
children = this.children;
var currentOpcodeIndex = 0;
var seenIndex = 0;
this.children = this.bounds.boundList = [];
while (true) {
var item = iterator.next();
if (item === null) break;
var opcode = children[currentOpcodeIndex];
var key = item.key; // Items that have already been found and moved will already be retained,
// we can continue until we find the next unretained item
while (opcode !== undefined && opcode.retained === true) {
opcode = children[++currentOpcodeIndex];
}
if (opcode !== undefined && opcode.key === key) {
this.retainItem(opcode, item);
currentOpcodeIndex++;
} else if (itemMap.has(key)) {
var itemOpcode = itemMap.get(key); // The item opcode was seen already, so we should move it.
if (itemOpcode.index < seenIndex) {
this.moveItem(itemOpcode, item, opcode);
} else {
// Update the seen index, we are going to be moving this item around
// so any other items that come before it will likely need to move as
// well.
seenIndex = itemOpcode.index;
var seenUnretained = false; // iterate through all of the opcodes between the current position and
// the position of the item's opcode, and determine if they are all
// retained.
for (var i = currentOpcodeIndex + 1; i < seenIndex; i++) {
if (children[i].retained === false) {
seenUnretained = true;
break;
}
} // If we have seen only retained opcodes between this and the matching
// opcode, it means that all the opcodes in between have been moved
// already, and we can safely retain this item's opcode.
if (seenUnretained === false) {
this.retainItem(itemOpcode, item);
currentOpcodeIndex = seenIndex + 1;
} else {
this.moveItem(itemOpcode, item, opcode);
currentOpcodeIndex++;
}
}
} else {
this.insertItem(item, opcode);
}
}
for (var _i = 0; _i < children.length; _i++) {
var _opcode = children[_i];
if (_opcode.retained === false) {
this.deleteItem(_opcode);
} else {
_opcode.reset();
}
}
};
_proto6.retainItem = function retainItem(opcode, item) {
if (false
/* LOCAL_DEBUG */
) {
logStep('list-updates', ['retain', item.key]);
}
var children = this.children;
updateRef(opcode.memo, item.memo);
updateRef(opcode.value, item.value);
opcode.retained = true;
opcode.index = children.length;
children.push(opcode);
};
_proto6.insertItem = function insertItem(item, before) {
var _this6 = this;
if (false
/* LOCAL_DEBUG */
) {
logStep('list-updates', ['insert', item.key]);
}
var opcodeMap = this.opcodeMap,
bounds = this.bounds,
state = this.state,
runtime = this.runtime,
children = this.children;
var key = item.key;
var nextSibling = before === undefined ? this.marker : before.firstNode();
var elementStack = NewElementBuilder.forInitialRender(runtime.env, {
element: bounds.parentElement(),
nextSibling: nextSibling
});
var vm = state.resume(runtime, elementStack);
vm.execute(function (vm) {
vm.pushUpdating();
var opcode = vm.enterItem(item);
opcode.index = children.length;
children.push(opcode);
opcodeMap.set(key, opcode);
associateDestroyableChild(_this6, opcode);
});
};
_proto6.moveItem = function moveItem(opcode, item, before) {
var children = this.children;
updateRef(opcode.memo, item.memo);
updateRef(opcode.value, item.value);
opcode.retained = true;
var currentSibling, nextSibling;
if (before === undefined) {
moveBounds(opcode, this.marker);
} else {
currentSibling = opcode.lastNode().nextSibling;
nextSibling = before.firstNode(); // Items are moved throughout the algorithm, so there are cases where the
// the items already happen to be siblings (e.g. an item in between was
// moved before this move happened). Check to see if they are siblings
// first before doing the move.
if (currentSibling !== nextSibling) {
moveBounds(opcode, nextSibling);
}
}
opcode.index = children.length;
children.push(opcode);
if (false
/* LOCAL_DEBUG */
) {
var type = currentSibling && currentSibling === nextSibling ? 'move-retain' : 'move';
logStep('list-updates', [type, item.key]);
}
};
_proto6.deleteItem = function deleteItem(opcode) {
if (false
/* LOCAL_DEBUG */
) {
logStep('list-updates', ['delete', opcode.key]);
}
destroy(opcode);
clear(opcode);
this.opcodeMap["delete"](opcode.key);
};
return ListBlockOpcode;
}(BlockOpcode);
var UpdatingVMFrame = /*#__PURE__*/function () {
function UpdatingVMFrame(ops, exceptionHandler) {
this.ops = ops;
this.exceptionHandler = exceptionHandler;
this.current = 0;
}
var _proto7 = UpdatingVMFrame.prototype;
_proto7["goto"] = function goto(index) {
this.current = index;
};
_proto7.nextStatement = function nextStatement() {
return this.ops[this.current++];
};
_proto7.handleException = function handleException() {
if (this.exceptionHandler) {
this.exceptionHandler.handleException();
}
};
return UpdatingVMFrame;
}();
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3BhY2thZ2VzL0BnbGltbWVyL3J1bnRpbWUvbGliL3ZtL3VwZGF0ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7QUFBQSxTQUFBLEtBQUEsUUFBQSxjQUFBO0FBaUJBLFNBQUEsU0FBQSxFQUFBLFdBQUEsUUFBQSxvQkFBQTtBQU9BLFNBQUEseUJBQUEsRUFBQSxPQUFBLEVBQUEsZUFBQSxRQUFBLHNCQUFBO0FBQ0EsU0FBQSxLQUFBLEVBQUEsT0FBQSxRQUFBLGVBQUE7QUFDQSxTQUFBLGFBQUEsRUFBQSx3QkFBQSxRQUFBLG9CQUFBO0FBRUEsU0FBQSxLQUFBLEVBQWdCLElBQUksSUFBcEIsVUFBQSxRQUFBLFdBQUE7QUFFQSxTQUFBLGlCQUFBLFFBQUEsbUJBQUE7O0lBRWMsYztBQU9aLDBCQUFBLEdBQUEsUUFBMEQ7QUFBQSxxQ0FBMUIsZ0JBQTBCO0FBQUEsUUFBMUIsZ0JBQTBCLHNDQUFQLEtBQU87QUFGbEQsU0FBQSxVQUFBLEdBQXFDLElBQXJDLEtBQXFDLEVBQXJDO0FBR04sU0FBQSxHQUFBLEdBQUEsR0FBQTtBQUNBLFNBQUEsR0FBQSxHQUFXLEdBQUcsQ0FBZCxNQUFXLEVBQVg7QUFDQSxTQUFBLGdCQUFBLEdBQUEsZ0JBQUE7QUFDRDs7OztTQUVELE8sR0FBQSxpQkFBTyxPQUFQLEVBQU8sT0FBUCxFQUE0RDtBQUFBOztBQUMxRCxRQUFBLEtBQUEsRUFBVztBQUNULFVBQUksVUFBVSxHQUFkLElBQUE7O0FBQ0EsVUFBSTtBQUNGLFFBQUEsd0JBQXlCLENBQUM7QUFBQSxpQkFBTSxLQUFBLENBQUEsUUFBQSxDQUFBLE9BQUEsRUFBUCxPQUFPLENBQU47QUFBQSxTQUFELEVBRHZCLG9CQUN1QixDQUF6QixDQURFLENBR0Y7QUFDQTs7QUFDQSxRQUFBLFVBQVUsR0FBVixLQUFBO0FBTEYsT0FBQSxTQU1VO0FBQ1IsWUFBQSxVQUFBLEVBQWdCO0FBQ2Q7QUFDQSxVQUFBLE9BQU8sQ0FBUCxLQUFBLDZC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QVA7QUFDQSxJQUFBLEtBQUssQ0FBTCxNQUFLLENBQUw7QUFDQSxTQUFBLFNBQUEsV0FBc0IsTUFBTSxDQUE1QixHQUFBO0FBQ0QsR0FsTkg7O0FBQUE7QUFBQSxFQUFNLFdBQU47O0lBcU5BLGU7QUFHRSwyQkFBQSxHQUFBLEVBQUEsZ0JBQUEsRUFBNkY7QUFBekUsU0FBQSxHQUFBLEdBQUEsR0FBQTtBQUErQixTQUFBLGdCQUFBLEdBQUEsZ0JBQUE7QUFGM0MsU0FBQSxPQUFBLEdBQUEsQ0FBQTtBQUV5Rjs7OztvQkFFakcsY0FBSSxLQUFKLEVBQWtCO0FBQ2hCLFNBQUEsT0FBQSxHQUFBLEtBQUE7QUFDRCxHOztVQUVELGEsR0FBQSx5QkFBYTtBQUNYLFdBQU8sS0FBQSxHQUFBLENBQVMsS0FBaEIsT0FBZ0IsRUFBVCxDQUFQO0FBQ0QsRzs7VUFFRCxlLEdBQUEsMkJBQWU7QUFDYixRQUFJLEtBQUosZ0JBQUEsRUFBMkI7QUFDekIsV0FBQSxnQkFBQSxDQUFBLGVBQUE7QUFDRDtBQUNGLEciLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBERUJVRyB9IGZyb20gJ0BnbGltbWVyL2Vudic7XG5pbXBvcnQge1xuICBCb3VuZHMsXG4gIER5bmFtaWNTY29wZSxcbiAgRWxlbWVudEJ1aWxkZXIsXG4gIEVudmlyb25tZW50LFxuICBFeGNlcHRpb25IYW5kbGVyLFxuICBHbGltbWVyVHJlZUNoYW5nZXMsXG4gIExpdmVCbG9jayxcbiAgT3B0aW9uLFxuICBSdW50aW1lQ29udGV4dCxcbiAgU2NvcGUsXG4gIFVwZGF0YWJsZUJsb2NrLFxuICBVcGRhdGluZ1ZNLFxuICBVcGRhdGluZ09wY29kZSxcbn0gZnJvbSAnQGdsaW1tZXIvaW50ZXJmYWNlcyc7XG5pbXBvcnQgeyBMT0NBTF9ERUJVRyB9IGZyb20gJ0BnbGltbWVyL2xvY2FsLWRlYnVnLWZsYWdzJztcbmltcG9ydCB7XG4gIE9wYXF1ZUl0ZXJhdGlvbkl0ZW0sXG4gIE9wYXF1ZUl0ZXJhdG9yLFxuICBSZWZlcmVuY2UsXG4gIHVwZGF0ZVJlZixcbiAgdmFsdWVGb3JSZWYsXG59IGZyb20gJ0BnbGltbWVyL3JlZmVyZW5jZSc7XG5pbXBvcnQgeyBhc3NvY2lhdGVEZXN0cm95YWJsZUNoaWxkLCBkZXN0cm95LCBkZXN0cm95Q2hpbGRyZW4gfSBmcm9tICdAZ2xpbW1lci9kZXN0cm95YWJsZSc7XG5pbXBvcnQgeyBleHBlY3QsIFN0YWNrLCBsb2dTdGVwIH0gZnJvbSAnQGdsaW1tZXIvdXRpbCc7XG5pbXBvcnQgeyByZXNldFRyYWNraW5nLCBydW5JblRyYWNraW5nVHJhbnNhY3Rpb24gfSBmcm9tICdAZ2xpbW1lci92YWxpZGF0b3InO1xuaW1wb3J0IHsgU2ltcGxlQ29tbWVudCB9IGZyb20gJ0BzaW1wbGUtZG9tL2ludGVyZmFjZSc7XG5pbXBvcnQgeyBjbGVhciwgbW92ZSBhcyBtb3ZlQm91bmRzIH0gZnJvbSAnLi4vYm91bmRzJztcbmltcG9ydCB7IEludGVybmFsVk0sIFZtSW5pdENhbGxiYWNrIH0gZnJvbSAnLi9hcHBlbmQnO1xuaW1wb3J0IHsgTGl2ZUJsb2NrTGlzdCwgTmV3RWxlbWVudEJ1aWxkZXIgfSBmcm9tICcuL2VsZW1lbnQtYnVpbGRlcic7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFVwZGF0aW5nVk1JbXBsIGltcGxlbWVudHMgVXBkYXRpbmdWTSB7XG4gIHB1YmxpYyBlbnY6IEVudmlyb25tZW50O1xuICBwdWJsaWMgZG9tOiBHbGltbWVyVHJlZUNoYW5nZXM7XG4gIHB1YmxpYyBhbHdheXNSZXZhbGlkYXRlOiBib29sZWFuO1xuXG4gIHByaXZhdGUgZnJhbWVTdGFjazogU3RhY2s8VXBkYXRpbmdWTUZyYW1lPiA9IG5ldyBTdGFjazxVcGRhdGluZ1ZNRnJhbWU+KCk7XG5cbiAgY29uc3RydWN0b3IoZW52OiBFbnZpcm9ubWVudCwgeyBhbHdheXNSZXZhbGlkYXRlID0gZmFsc2UgfSkge1xuICAgIHRoaXMuZW52ID0gZW52O1xuICAgIHRoaXMuZG9tID0gZW52LmdldERPTSgpO1xuICAgIHRoaXMuYWx3YXlzUmV2YWxpZGF0ZSA9IGFsd2F5c1JldmFsaWRhdGU7XG4gIH1cblxuICBleGVjdXRlKG9wY29kZXM6IFVwZGF0aW5nT3Bjb2RlW10sIGhhbmRsZXI6IEV4Y2VwdGlvbkhhbmRsZXIpIHtcbiAgICBpZiAoREVCVUcpIHtcbiAgICAgIGxldCBoYXNFcnJvcmVkID0gdHJ1ZTtcbiAgICAgIHRyeSB7XG4gICAgICAgIHJ1bkluVHJhY2tpbmdUcmFuc2FjdGlvbiEoKCkgPT4gdGhpcy5fZXhlY3V0ZShvcGNvZGVzLCBoYW5kbGVyKSwgJy0gV2hpbGUgcmVuZGVyaW5nOicpO1xuXG4gICAgICAgIC8vIHVzaW5nIGEgYm9vbGVhbiBoZXJlIHRvIGF2b2lkIGJyZWFraW5nIGVyZ29ub21pY3Mgb2YgXCJwYXVzZSBvbiB1bmNhdWdodCBleGNlcHRpb25zXCJcbiAgICAgICAgLy8gd2hpY2ggd291bGQgaGFwcGVuIHdpdGggYSBgY2F0Y2hgICsgYHRocm93YFxuICAgICAgICBoYXNFcnJvcmVkID0gZmFsc2U7XG4gICAgICB9IGZpbmFsbHkge1xuICAgICAgICBpZiAoaGFzRXJyb3JlZCkge1xuICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1jb25zb2xlXG4gICAgICAgICAgY29uc29sZS5lcnJvcihgXFxuXFxuRXJyb3Igb2NjdXJyZWQ6XFxuXFxuJHtyZXNldFRyYWNraW5nKCl9XFxuXFxuYCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5fZXhlY3V0ZShvcGNvZGVzLCBoYW5kbGVyKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIF9leGVjdXRlKG9wY29kZXM6IFVwZGF0aW5nT3Bjb2RlW10sIGhhbmRsZXI6IEV4Y2VwdGlvbkhhbmRsZXIpIHtcbiAgICBsZXQgeyBmcmFtZVN0YWNrIH0gPSB0aGlzO1xuXG4gICAgdGhpcy50cnkob3Bjb2RlcywgaGFuZGxlcik7XG5cbiAgICB3aGlsZSAodHJ1ZSkge1xuICAgICAgaWYgKGZyYW1lU3RhY2suaXNFbXB0eSgpKSBicmVhaztcblxuICAgICAgbGV0IG9wY29kZSA9IHRoaXMuZnJhbWUubmV4dFN0YXRlbWVudCgpO1xuXG4gICAgICBpZiAob3Bjb2RlID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgZnJhbWVTdGFjay5wb3AoKTtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIG9wY29kZS5ldmFsdWF0ZSh0aGlzKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGdldCBmcmFtZSgpIHtcbiAgICByZXR1cm4gZXhwZWN0KHRoaXMuZnJhbWVTdGFjay5jdXJyZW50LCAnYnVnOiBleHBlY3RlZCBhIGZyYW1lJyk7XG4gIH1cblxuICBnb3RvKGluZGV4OiBudW1iZXIpIHtcbiAgICB0aGlzLmZyYW1lLmdvdG8oaW5kZXgpO1xuICB9XG5cbiAgdHJ5KG9wczogVXBkYXRpbmdPcGNvZGVbXSwgaGFuZGxlcjogT3B0aW9uPEV4Y2VwdGlvbkhhbmRsZXI+KSB7XG4gICAgdGhpcy5mcmFtZVN0YWNrLnB1c2gobmV3IFVwZGF0aW5nVk1GcmFtZShvcHMsIGhhbmRsZXIpKTtcbiAgfVxuXG4gIHRocm93KCkge1xuICAgIHRoaXMuZnJhbWUuaGFuZGxlRXhjZXB0aW9uKCk7XG4gICAgdGhpcy5mcmFtZVN0YWNrLnBvcCgpO1xuICB9XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgVk1TdGF0ZSB7XG4gIHJlYWRvbmx5IHBjOiBudW1iZXI7XG4gIHJlYWRvbmx5IHNjb3BlOiBTY29wZTtcbiAgcmVhZG9ubHkgZHluYW1pY1Njb3BlOiBEeW5hbWljU2NvcGU7XG4gIHJlYWRvbmx5IHN0YWNrOiB1bmtub3duW107XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUmVzdW1hYmxlVk1TdGF0ZSB7XG4gIHJlc3VtZShydW50aW1lOiBSdW50aW1lQ29udGV4dCwgYnVpbGRlcjogRWxlbWVudEJ1aWxkZXIpOiBJbnRlcm5hbFZNO1xufVxuXG5leHBvcnQgY2xhc3MgUmVzdW1hYmxlVk1TdGF0ZUltcGwgaW1wbGVtZW50cyBSZXN1bWFibGVWTVN0YXRlIHtcbiAgY29uc3RydWN0b3IocmVhZG9ubHkgc3RhdGU6IFZNU3RhdGUsIHByaXZhdGUgcmVzdW1lQ2FsbGJhY2s6IFZtSW5pdENhbGxiYWNrKSB7fVxuXG4gIHJlc3VtZShydW50aW1lOiBSdW50aW1lQ29udGV4dCwgYnVpbGRlcjogRWxlbWVudEJ1aWxkZXIpOiBJbnRlcm5hbFZNIHtcbiAgICByZXR1cm4gdGhpcy5yZXN1bWVDYWxsYmFjayhydW50aW1lLCB0aGlzLnN0YXRlLCBidWlsZGVyKTtcbiAgfVxufVxuXG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgQmxvY2tPcGNvZGUgaW1wbGVtZW50cyBVcGRhdGluZ09wY29kZSwgQm91bmRzIHtcbiAgcHVibGljIGNoaWxkcmVuOiBVcGRhdGluZ09wY29kZVtdO1xuXG4gIHByb3RlY3RlZCByZWFkb25seSBib3VuZHM6IExpdmVCbG9jaztcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcm90ZWN0ZWQgc3RhdGU6IFJlc3VtYWJsZVZNU3RhdGUsXG4gICAgcHJvdGVjdGVkIHJ1bnRpbWU6IFJ1bnRpbWVDb250ZXh0LFxuICAgIGJvdW5kczogTGl2ZUJsb2NrLFxuICAgIGNoaWxkcmVuOiBVcGRhdGluZ09wY29kZVtdXG4gICkge1xuICAgIHRoaXMuY2hpbGRyZW4gPSBjaGlsZHJlbjtcbiAgICB0aGlzLmJvdW5kcyA9IGJvdW5kcztcbiAgfVxuXG4gIHBhcmVudEVsZW1lbnQoKSB7XG4gICAgcmV0dXJuIHRoaXMuYm91bmRzLnBhcmVudEVsZW1lbnQoKTtcbiAgfVxuXG4gIGZpcnN0Tm9kZSgpIHtcbiAgICByZXR1cm4gdGhpcy5ib3VuZHMuZmlyc3ROb2RlKCk7XG4gIH1cblxuICBsYXN0Tm9kZSgpIHtcbiAgICByZXR1cm4gdGhpcy5ib3VuZHMubGFzdE5vZGUoKTtcbiAgfVxuXG4gIGV2YWx1YXRlKHZtOiBVcGRhdGluZ1ZNSW1wbCkge1xuICAgIHZtLnRyeSh0aGlzLmNoaWxkcmVuLCBudWxsKTtcbiAgfVxufVxuXG5leHBvcnQgY2xhc3MgVHJ5T3Bjb2RlIGV4dGVuZHMgQmxvY2tPcGNvZGUgaW1wbGVtZW50cyBFeGNlcHRpb25IYW5kbGVyIHtcbiAgcHVibGljIHR5cGUgPSAndHJ5JztcblxuICBwcm90ZWN0ZWQgYm91bmRzITogVXBkYXRhYmxlQmxvY2s7IC8vIEhpZGVzIHByb3BlcnR5IG9uIGJhc2UgY2xhc3NcblxuICBldmFsdWF0ZSh2bTogVXBkYXRpbmdWTUltcGwpIHtcbiAgICB2bS50cnkodGhpcy5jaGlsZHJlbiwgdGhpcyk7XG4gIH1cblxuICBoYW5kbGVFeGNlcHRpb24oKSB7XG4gICAgbGV0IHsgc3RhdGUsIGJvdW5kcywgcnVudGltZSB9ID0gdGhpcztcblxuICAgIGRlc3Ryb3lDaGlsZHJlbih0aGlzKTtcblxuICAgIGxldCBlbGVtZW50U3RhY2sgPSBOZXdFbGVtZW50QnVpbGRlci5yZXN1bWUocnVudGltZS5lbnYsIGJvdW5kcyk7XG4gICAgbGV0IHZtID0gc3RhdGUucmVzdW1lKHJ1bnRpbWUsIGVsZW1lbnRTdGFjayk7XG5cbiAgICBsZXQgdXBkYXRpbmc6IFVwZGF0aW5nT3Bjb2RlW10gPSBbXTtcbiAgICBsZXQgY2hpbGRyZW4gPSAodGhpcy5jaGlsZHJlbiA9IFtdKTtcblxuICAgIGxldCByZXN1bHQgPSB2bS5leGVjdXRlKCh2bSkgPT4ge1xuICAgICAgdm0ucHVzaFVwZGF0aW5nKHVwZGF0aW5nKTtcbiAgICAgIHZtLnVwZGF0ZVdpdGgodGhpcyk7XG4gICAgICB2bS5wdXNoVXBkYXRpbmcoY2hpbGRyZW4pO1xuICAgIH0pO1xuXG4gICAgYXNzb2NpYXRlRGVzdHJveWFibGVDaGlsZCh0aGlzLCByZXN1bHQuZHJvcCk7XG4gIH1cbn1cblxuZXhwb3J0IGNsYXNzIExpc3RJdGVtT3Bjb2RlIGV4dGVuZHMgVHJ5T3Bjb2RlIHtcbiAgcHVibGljIHJldGFpbmVkID0gZmFsc2U7XG4gIHB1YmxpYyBpbmRleCA9IC0xO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHN0YXRlOiBSZXN1bWFibGVWTVN0YXRlLFxuICAgIHJ1bnRpbWU6IFJ1bnRpbWVDb250ZXh0LFxuICAgIGJvdW5kczogVXBkYXRhYmxlQmxvY2ssXG4gICAgcHVibGljIGtleTogdW5rbm93bixcbiAgICBwdWJsaWMgbWVtbzogUmVmZXJlbmNlLFxuICAgIHB1YmxpYyB2YWx1ZTogUmVmZXJlbmNlXG4gICkge1xuICAgIHN1cGVyKHN0YXRlLCBydW50aW1lLCBib3VuZHMsIFtdKTtcbiAgfVxuXG4gIHVwZGF0ZVJlZmVyZW5jZXMoaXRlbTogT3BhcXVlSXRlcmF0aW9uSXRlbSkge1xuICAgIHRoaXMucmV0YWluZWQgPSB0cnVlO1xuICAgIHVwZGF0ZVJlZih0aGlzLnZhbHVlLCBpdGVtLnZhbHVlKTtcbiAgICB1cGRhdGVSZWYodGhpcy5tZW1vLCBpdGVtLm1lbW8pO1xuICB9XG5cbiAgc2hvdWxkUmVtb3ZlKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiAhdGhpcy5yZXRhaW5lZDtcbiAgfVxuXG4gIHJlc2V0KCkge1xuICAgIHRoaXMucmV0YWluZWQgPSBmYWxzZTtcbiAgfVxufVxuXG5leHBvcnQgY2xhc3MgTGlzdEJsb2NrT3Bjb2RlIGV4dGVuZHMgQmxvY2tPcGNvZGUge1xuICBwdWJsaWMgdHlwZSA9ICdsaXN0LWJsb2NrJztcbiAgcHVibGljIGNoaWxkcmVuITogTGlzdEl0ZW1PcGNvZGVbXTtcblxuICBwcml2YXRlIG9wY29kZU1hcCA9IG5ldyBNYXA8dW5rbm93biwgTGlzdEl0ZW1PcGNvZGU+KCk7XG4gIHByaXZhdGUgbWFya2VyOiBTaW1wbGVDb21tZW50IHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUgbGFzdEl0ZXJhdG9yOiBPcGFxdWVJdGVyYXRvcjtcblxuICBwcm90ZWN0ZWQgcmVhZG9ubHkgYm91bmRzITogTGl2ZUJsb2NrTGlzdDtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBzdGF0ZTogUmVzdW1hYmxlVk1TdGF0ZSxcbiAgICBydW50aW1lOiBSdW50aW1lQ29udGV4dCxcbiAgICBib3VuZHM6IExpdmVCbG9ja0xpc3QsXG4gICAgY2hpbGRyZW46IExpc3RJdGVtT3Bjb2RlW10sXG4gICAgcHJpdmF0ZSBpdGVyYWJsZVJlZjogUmVmZXJlbmNlPE9wYXF1ZUl0ZXJhdG9yPlxuICApIHtcbiAgICBzdXBlcihzdGF0ZSwgcnVudGltZSwgYm91bmRzLCBjaGlsZHJlbik7XG4gICAgdGhpcy5sYXN0SXRlcmF0b3IgPSB2YWx1ZUZvclJlZihpdGVyYWJsZVJlZik7XG4gIH1cblxuICBpbml0aWFsaXplQ2hpbGQob3Bjb2RlOiBMaXN0SXRlbU9wY29kZSkge1xuICAgIG9wY29kZS5pbmRleCA9IHRoaXMuY2hpbGRyZW4ubGVuZ3RoIC0gMTtcbiAgICB0aGlzLm9wY29kZU1hcC5zZXQob3Bjb2RlLmtleSwgb3Bjb2RlKTtcbiAgfVxuXG4gIGV2YWx1YXRlKHZtOiBVcGRhdGluZ1ZNSW1wbCkge1xuICAgIGxldCBpdGVyYXRvciA9IHZhbHVlRm9yUmVmKHRoaXMuaXRlcmFibGVSZWYpO1xuXG4gICAgaWYgKHRoaXMubGFzdEl0ZXJhdG9yICE9PSBpdGVyYXRvcikge1xuICAgICAgbGV0IHsgYm91bmRzIH0gPSB0aGlzO1xuICAgICAgbGV0IHsgZG9tIH0gPSB2bTtcblxuICAgICAgbGV0IG1hcmtlciA9ICh0aGlzLm1hcmtlciA9IGRvbS5jcmVhdGVDb21tZW50KCcnKSk7XG4gICAgICBkb20uaW5zZXJ0QWZ0ZXIoXG4gICAgICAgIGJvdW5kcy5wYXJlbnRFbGVtZW50KCksXG4gICAgICAgIG1hcmtlcixcbiAgICAgICAgZXhwZWN0KGJvdW5kcy5sYXN0Tm9kZSgpLCBcImNhbid0IGluc2VydCBhZnRlciBhbiBlbXB0eSBib3VuZHNcIilcbiAgICAgICk7XG5cbiAgICAgIHRoaXMuc3luYyhpdGVyYXRvcik7XG5cbiAgICAgIHRoaXMucGFyZW50RWxlbWVudCgpLnJlbW92ZUNoaWxkKG1hcmtlcik7XG4gICAgICB0aGlzLm1hcmtlciA9IG51bGw7XG4gICAgICB0aGlzLmxhc3RJdGVyYXRvciA9IGl0ZXJhdG9yO1xuICAgIH1cblxuICAgIC8vIFJ1biBub3ctdXBkYXRlZCB1cGRhdGluZyBvcGNvZGVzXG4gICAgc3VwZXIuZXZhbHVhdGUodm0pO1xuICB9XG5cbiAgcHJpdmF0ZSBzeW5jKGl0ZXJhdG9yOiBPcGFxdWVJdGVyYXRvcikge1xuICAgIGxldCB7IG9wY29kZU1hcDogaXRlbU1hcCwgY2hpbGRyZW4gfSA9IHRoaXM7XG5cbiAgICBsZXQgY3VycmVudE9wY29kZUluZGV4ID0gMDtcbiAgICBsZXQgc2VlbkluZGV4ID0gMDtcblxuICAgIHRoaXMuY2hpbGRyZW4gPSB0aGlzLmJvdW5kcy5ib3VuZExpc3QgPSBbXTtcblxuICAgIHdoaWxlICh0cnVlKSB7XG4gICAgICBsZXQgaXRlbSA9IGl0ZXJhdG9yLm5leHQoKTtcblxuICAgICAgaWYgKGl0ZW0gPT09IG51bGwpIGJyZWFrO1xuXG4gICAgICBsZXQgb3Bjb2RlID0gY2hpbGRyZW5bY3VycmVudE9wY29kZUluZGV4XTtcbiAgICAgIGxldCB7IGtleSB9ID0gaXRlbTtcblxuICAgICAgLy8gSXRlbXMgdGhhdCBoYXZlIGFscmVhZHkgYmVlbiBmb3VuZCBhbmQgbW92ZWQgd2lsbCBhbHJlYWR5IGJlIHJldGFpbmVkLFxuICAgICAgLy8gd2UgY2FuIGNvbnRpbnVlIHVudGlsIHdlIGZpbmQgdGhlIG5leHQgdW5yZXRhaW5lZCBpdGVtXG4gICAgICB3aGlsZSAob3Bjb2RlICE9PSB1bmRlZmluZWQgJiYgb3Bjb2RlLnJldGFpbmVkID09PSB0cnVlKSB7XG4gICAgICAgIG9wY29kZSA9IGNoaWxkcmVuWysrY3VycmVudE9wY29kZUluZGV4XTtcbiAgICAgIH1cblxuICAgICAgaWYgKG9wY29kZSAhPT0gdW5kZWZpbmVkICYmIG9wY29kZS5rZXkgPT09IGtleSkge1xuICAgICAgICB0aGlzLnJldGFpbkl0ZW0ob3Bjb2RlLCBpdGVtKTtcbiAgICAgICAgY3VycmVudE9wY29kZUluZGV4Kys7XG4gICAgICB9IGVsc2UgaWYgKGl0ZW1NYXAuaGFzKGtleSkpIHtcbiAgICAgICAgbGV0IGl0ZW1PcGNvZGUgPSBpdGVtTWFwLmdldChrZXkpITtcblxuICAgICAgICAvLyBUaGUgaXRlbSBvcGNvZGUgd2FzIHNlZW4gYWxyZWFkeSwgc28gd2Ugc2hvdWxkIG1vdmUgaXQuXG4gICAgICAgIGlmIChpdGVtT3Bjb2RlLmluZGV4IDwgc2VlbkluZGV4KSB7XG4gICAgICAgICAgdGhpcy5tb3ZlSXRlbShpdGVtT3Bjb2RlLCBpdGVtLCBvcGNvZGUpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIFVwZGF0ZSB0aGUgc2VlbiBpbmRleCwgd2UgYXJlIGdvaW5nIHRvIGJlIG1vdmluZyB0aGlzIGl0ZW0gYXJvdW5kXG4gICAgICAgICAgLy8gc28gYW55IG90aGVyIGl0ZW1zIHRoYXQgY29tZSBiZWZvcmUgaXQgd2lsbCBsaWtlbHkgbmVlZCB0byBtb3ZlIGFzXG4gICAgICAgICAgLy8gd2VsbC5cbiAgICAgICAgICBzZWVuSW5kZXggPSBpdGVtT3Bjb2RlLmluZGV4O1xuXG4gICAgICAgICAgbGV0IHNlZW5VbnJldGFpbmVkID0gZmFsc2U7XG5cbiAgICAgICAgICAvLyBpdGVyYXRlIHRocm91Z2ggYWxsIG9mIHRoZSBvcGNvZGVzIGJldHdlZW4gdGhlIGN1cnJlbnQgcG9zaXRpb24gYW5kXG4gICAgICAgICAgLy8gdGhlIHBvc2l0aW9uIG9mIHRoZSBpdGVtJ3Mgb3Bjb2RlLCBhbmQgZGV0ZXJtaW5lIGlmIHRoZXkgYXJlIGFsbFxuICAgICAgICAgIC8vIHJldGFpbmVkLlxuICAgICAgICAgIGZvciAobGV0IGkgPSBjdXJyZW50T3Bjb2RlSW5kZXggKyAxOyBpIDwgc2VlbkluZGV4OyBpKyspIHtcbiAgICAgICAgICAgIGlmIChjaGlsZHJlbltpXS5yZXRhaW5lZCA9PT0gZmFsc2UpIHtcbiAgICAgICAgICAgICAgc2VlblVucmV0YWluZWQgPSB0cnVlO1xuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG5cbiAgICAgICAgICAvLyBJZiB3ZSBoYXZlIHNlZW4gb25seSByZXRhaW5lZCBvcGNvZGVzIGJldHdlZW4gdGhpcyBhbmQgdGhlIG1hdGNoaW5nXG4gICAgICAgICAgLy8gb3Bjb2RlLCBpdCBtZWFucyB0aGF0IGFsbCB0aGUgb3Bjb2RlcyBpbiBiZXR3ZWVuIGhhdmUgYmVlbiBtb3ZlZFxuICAgICAgICAgIC8vIGFscmVhZHksIGFuZCB3ZSBjYW4gc2FmZWx5IHJldGFpbiB0aGlzIGl0ZW0ncyBvcGNvZGUuXG4gICAgICAgICAgaWYgKHNlZW5VbnJldGFpbmVkID09PSBmYWxzZSkge1xuICAgICAgICAgICAgdGhpcy5yZXRhaW5JdGVtKGl0ZW1PcGNvZGUsIGl0ZW0pO1xuICAgICAgICAgICAgY3VycmVudE9wY29kZUluZGV4ID0gc2VlbkluZGV4ICsgMTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5tb3ZlSXRlbShpdGVtT3Bjb2RlLCBpdGVtLCBvcGNvZGUpO1xuICAgICAgICAgICAgY3VycmVudE9wY29kZUluZGV4Kys7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLmluc2VydEl0ZW0oaXRlbSwgb3Bjb2RlKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGNoaWxkcmVuLmxlbmd0aDsgaSsrKSB7XG4gICAgICBsZXQgb3Bjb2RlID0gY2hpbGRyZW5baV07XG5cbiAgICAgIGlmIChvcGNvZGUucmV0YWluZWQgPT09IGZhbHNlKSB7XG4gICAgICAgIHRoaXMuZGVsZXRlSXRlbShvcGNvZGUpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgb3Bjb2RlLnJlc2V0KCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSByZXRhaW5JdGVtKG9wY29kZTogTGlzdEl0ZW1PcGNvZGUsIGl0ZW06IE9wYXF1ZUl0ZXJhdGlvbkl0ZW0pIHtcbiAgICBpZiAoTE9DQUxfREVCVUcpIHtcbiAgICAgIGxvZ1N0ZXAhKCdsaXN0LXVwZGF0ZXMnLCBbJ3JldGFpbicsIGl0ZW0ua2V5XSk7XG4gICAgfVxuXG4gICAgbGV0IHsgY2hpbGRyZW4gfSA9IHRoaXM7XG5cbiAgICB1cGRhdGVSZWYob3Bjb2RlLm1lbW8sIGl0ZW0ubWVtbyk7XG4gICAgdXBkYXRlUmVmKG9wY29kZS52YWx1ZSwgaXRlbS52YWx1ZSk7XG4gICAgb3Bjb2RlLnJldGFpbmVkID0gdHJ1ZTtcblxuICAgIG9wY29kZS5pbmRleCA9IGNoaWxkcmVuLmxlbmd0aDtcbiAgICBjaGlsZHJlbi5wdXNoKG9wY29kZSk7XG4gIH1cblxuICBwcml2YXRlIGluc2VydEl0ZW0oaXRlbTogT3BhcXVlSXRlcmF0aW9uSXRlbSwgYmVmb3JlOiBMaXN0SXRlbU9wY29kZSkge1xuICAgIGlmIChMT0NBTF9ERUJVRykge1xuICAgICAgbG9nU3RlcCEoJ2xpc3QtdXBkYXRlcycsIFsnaW5zZXJ0JywgaXRlbS5rZXldKTtcbiAgICB9XG5cbiAgICBsZXQgeyBvcGNvZGVNYXAsIGJvdW5kcywgc3RhdGUsIHJ1bnRpbWUsIGNoaWxkcmVuIH0gPSB0aGlzO1xuICAgIGxldCB7IGtleSB9ID0gaXRlbTtcbiAgICBsZXQgbmV4dFNpYmxpbmcgPSBiZWZvcmUgPT09IHVuZGVmaW5lZCA/IHRoaXMubWFya2VyIDogYmVmb3JlLmZpcnN0Tm9kZSgpO1xuXG4gICAgbGV0IGVsZW1lbnRTdGFjayA9IE5ld0VsZW1lbnRCdWlsZGVyLmZvckluaXRpYWxSZW5kZXIocnVudGltZS5lbnYsIHtcbiAgICAgIGVsZW1lbnQ6IGJvdW5kcy5wYXJlbnRFbGVtZW50KCksXG4gICAgICBuZXh0U2libGluZyxcbiAgICB9KTtcblxuICAgIGxldCB2bSA9IHN0YXRlLnJlc3VtZShydW50aW1lLCBlbGVtZW50U3RhY2spO1xuXG4gICAgdm0uZXhlY3V0ZSgodm0pID0+IHtcbiAgICAgIHZtLnB1c2hVcGRhdGluZygpO1xuICAgICAgbGV0IG9wY29kZSA9IHZtLmVudGVySXRlbShpdGVtKTtcblxuICAgICAgb3Bjb2RlLmluZGV4ID0gY2hpbGRyZW4ubGVuZ3RoO1xuICAgICAgY2hpbGRyZW4ucHVzaChvcGNvZGUpO1xuICAgICAgb3Bjb2RlTWFwLnNldChrZXksIG9wY29kZSk7XG4gICAgICBhc3NvY2lhdGVEZXN0cm95YWJsZUNoaWxkKHRoaXMsIG9wY29kZSk7XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIG1vdmVJdGVtKG9wY29kZTogTGlzdEl0ZW1PcGNvZGUsIGl0ZW06IE9wYXF1ZUl0ZXJhdGlvbkl0ZW0sIGJlZm9yZTogTGlzdEl0ZW1PcGNvZGUpIHtcbiAgICBsZXQgeyBjaGlsZHJlbiB9ID0gdGhpcztcblxuICAgIHVwZGF0ZVJlZihvcGNvZGUubWVtbywgaXRlbS5tZW1vKTtcbiAgICB1cGRhdGVSZWYob3Bjb2RlLnZhbHVlLCBpdGVtLnZhbHVlKTtcbiAgICBvcGNvZGUucmV0YWluZWQgPSB0cnVlO1xuXG4gICAgbGV0IGN1cnJlbnRTaWJsaW5nLCBuZXh0U2libGluZztcblxuICAgIGlmIChiZWZvcmUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgbW92ZUJvdW5kcyhvcGNvZGUsIHRoaXMubWFya2VyKTtcbiAgICB9IGVsc2Uge1xuICAgICAgY3VycmVudFNpYmxpbmcgPSBvcGNvZGUubGFzdE5vZGUoKS5uZXh0U2libGluZztcbiAgICAgIG5leHRTaWJsaW5nID0gYmVmb3JlLmZpcnN0Tm9kZSgpO1xuXG4gICAgICAvLyBJdGVtcyBhcmUgbW92ZWQgdGhyb3VnaG91dCB0aGUgYWxnb3JpdGhtLCBzbyB0aGVyZSBhcmUgY2FzZXMgd2hlcmUgdGhlXG4gICAgICAvLyB0aGUgaXRlbXMgYWxyZWFkeSBoYXBwZW4gdG8gYmUgc2libGluZ3MgKGUuZy4gYW4gaXRlbSBpbiBiZXR3ZWVuIHdhc1xuICAgICAgLy8gbW92ZWQgYmVmb3JlIHRoaXMgbW92ZSBoYXBwZW5lZCkuIENoZWNrIHRvIHNlZSBpZiB0aGV5IGFyZSBzaWJsaW5nc1xuICAgICAgLy8gZmlyc3QgYmVmb3JlIGRvaW5nIHRoZSBtb3ZlLlxuICAgICAgaWYgKGN1cnJlbnRTaWJsaW5nICE9PSBuZXh0U2libGluZykge1xuICAgICAgICBtb3ZlQm91bmRzKG9wY29kZSwgbmV4dFNpYmxpbmcpO1xuICAgICAgfVxuICAgIH1cblxuICAgIG9wY29kZS5pbmRleCA9IGNoaWxkcmVuLmxlbmd0aDtcbiAgICBjaGlsZHJlbi5wdXNoKG9wY29kZSk7XG5cbiAgICBpZiAoTE9DQUxfREVCVUcpIHtcbiAgICAgIGxldCB0eXBlID0gY3VycmVudFNpYmxpbmcgJiYgY3VycmVudFNpYmxpbmcgPT09IG5leHRTaWJsaW5nID8gJ21vdmUtcmV0YWluJyA6ICdtb3ZlJztcbiAgICAgIGxvZ1N0ZXAhKCdsaXN0LXVwZGF0ZXMnLCBbdHlwZSwgaXRlbS5rZXldKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGRlbGV0ZUl0ZW0ob3Bjb2RlOiBMaXN0SXRlbU9wY29kZSkge1xuICAgIGlmIChMT0NBTF9ERUJVRykge1xuICAgICAgbG9nU3RlcCEoJ2xpc3QtdXBkYXRlcycsIFsnZGVsZXRlJywgb3Bjb2RlLmtleV0pO1xuICAgIH1cblxuICAgIGRlc3Ryb3kob3Bjb2RlKTtcbiAgICBjbGVhcihvcGNvZGUpO1xuICAgIHRoaXMub3Bjb2RlTWFwLmRlbGV0ZShvcGNvZGUua2V5KTtcbiAgfVxufVxuXG5jbGFzcyBVcGRhdGluZ1ZNRnJhbWUge1xuICBwcml2YXRlIGN1cnJlbnQgPSAwO1xuXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgb3BzOiBVcGRhdGluZ09wY29kZVtdLCBwcml2YXRlIGV4Y2VwdGlvbkhhbmRsZXI6IE9wdGlvbjxFeGNlcHRpb25IYW5kbGVyPikge31cblxuICBnb3RvKGluZGV4OiBudW1iZXIpIHtcbiAgICB0aGlzLmN1cnJlbnQgPSBpbmRleDtcbiAgfVxuXG4gIG5leHRTdGF0ZW1lbnQoKTogVXBkYXRpbmdPcGNvZGUgfCB1bmRlZmluZWQge1xuICAgIHJldHVybiB0aGlzLm9wc1t0aGlzLmN1cnJlbnQrK107XG4gIH1cblxuICBoYW5kbGVFeGNlcHRpb24oKSB7XG4gICAgaWYgKHRoaXMuZXhjZXB0aW9uSGFuZGxlcikge1xuICAgICAgdGhpcy5leGNlcHRpb25IYW5kbGVyLmhhbmRsZUV4Y2VwdGlvbigpO1xuICAgIH1cbiAgfVxufVxuIl0sInNvdXJjZVJvb3QiOiIifQ==