@glimmer/runtime
Version:
Minimal runtime needed to render Glimmer templates
431 lines (349 loc) • 38.4 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.ListBlockOpcode = exports.ListItemOpcode = exports.TryOpcode = exports.BlockOpcode = exports.ResumableVMStateImpl = exports.default = void 0;
var _env = require("@glimmer/env");
var _reference = require("@glimmer/reference");
var _destroyable = require("@glimmer/destroyable");
var _util = require("@glimmer/util");
var _validator = require("@glimmer/validator");
var _bounds = require("../bounds");
var _elementBuilder = require("./element-builder");
class UpdatingVMImpl {
constructor(env, {
alwaysRevalidate = false
}) {
this.frameStack = new _util.Stack();
this.env = env;
this.dom = env.getDOM();
this.alwaysRevalidate = alwaysRevalidate;
}
execute(opcodes, handler) {
if (_env.DEBUG) {
let hasErrored = true;
try {
(0, _validator.runInTrackingTransaction)(() => 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${(0, _validator.resetTracking)()}\n\n`);
}
}
} else {
this._execute(opcodes, handler);
}
}
_execute(opcodes, handler) {
let {
frameStack
} = this;
this.try(opcodes, handler);
while (true) {
if (frameStack.isEmpty()) break;
let opcode = this.frame.nextStatement();
if (opcode === undefined) {
frameStack.pop();
continue;
}
opcode.evaluate(this);
}
}
get frame() {
return this.frameStack.current;
}
goto(index) {
this.frame.goto(index);
}
try(ops, handler) {
this.frameStack.push(new UpdatingVMFrame(ops, handler));
}
throw() {
this.frame.handleException();
this.frameStack.pop();
}
}
exports.default = UpdatingVMImpl;
class ResumableVMStateImpl {
constructor(state, resumeCallback) {
this.state = state;
this.resumeCallback = resumeCallback;
}
resume(runtime, builder) {
return this.resumeCallback(runtime, this.state, builder);
}
}
exports.ResumableVMStateImpl = ResumableVMStateImpl;
class BlockOpcode {
constructor(state, runtime, bounds, children) {
this.state = state;
this.runtime = runtime;
this.children = children;
this.bounds = bounds;
}
parentElement() {
return this.bounds.parentElement();
}
firstNode() {
return this.bounds.firstNode();
}
lastNode() {
return this.bounds.lastNode();
}
evaluate(vm) {
vm.try(this.children, null);
}
}
exports.BlockOpcode = BlockOpcode;
class TryOpcode extends BlockOpcode {
constructor() {
super(...arguments);
this.type = 'try';
}
evaluate(vm) {
vm.try(this.children, this);
}
handleException() {
let {
state,
bounds,
runtime
} = this;
(0, _destroyable.destroyChildren)(this);
let elementStack = _elementBuilder.NewElementBuilder.resume(runtime.env, bounds);
let vm = state.resume(runtime, elementStack);
let updating = [];
let children = this.children = [];
let result = vm.execute(vm => {
vm.pushUpdating(updating);
vm.updateWith(this);
vm.pushUpdating(children);
});
(0, _destroyable.associateDestroyableChild)(this, result.drop);
}
}
exports.TryOpcode = TryOpcode;
class ListItemOpcode extends TryOpcode {
constructor(state, runtime, bounds, key, memo, value) {
super(state, runtime, bounds, []);
this.key = key;
this.memo = memo;
this.value = value;
this.retained = false;
this.index = -1;
}
updateReferences(item) {
this.retained = true;
(0, _reference.updateRef)(this.value, item.value);
(0, _reference.updateRef)(this.memo, item.memo);
}
shouldRemove() {
return !this.retained;
}
reset() {
this.retained = false;
}
}
exports.ListItemOpcode = ListItemOpcode;
class ListBlockOpcode extends BlockOpcode {
constructor(state, runtime, bounds, children, iterableRef) {
super(state, runtime, bounds, children);
this.iterableRef = iterableRef;
this.type = 'list-block';
this.opcodeMap = new Map();
this.marker = null;
this.lastIterator = (0, _reference.valueForRef)(iterableRef);
}
initializeChild(opcode) {
opcode.index = this.children.length - 1;
this.opcodeMap.set(opcode.key, opcode);
}
evaluate(vm) {
let iterator = (0, _reference.valueForRef)(this.iterableRef);
if (this.lastIterator !== iterator) {
let {
bounds
} = this;
let {
dom
} = vm;
let 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
super.evaluate(vm);
}
sync(iterator) {
let {
opcodeMap: itemMap,
children
} = this;
let currentOpcodeIndex = 0;
let seenIndex = 0;
this.children = this.bounds.boundList = [];
while (true) {
let item = iterator.next();
if (item === null) break;
let opcode = children[currentOpcodeIndex];
let {
key
} = item; // 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)) {
let 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;
let 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 (let 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 (let i = 0; i < children.length; i++) {
let opcode = children[i];
if (opcode.retained === false) {
this.deleteItem(opcode);
} else {
opcode.reset();
}
}
}
retainItem(opcode, item) {
if (false
/* LOCAL_DEBUG */
) {
(0, _util.logStep)('list-updates', ['retain', item.key]);
}
let {
children
} = this;
(0, _reference.updateRef)(opcode.memo, item.memo);
(0, _reference.updateRef)(opcode.value, item.value);
opcode.retained = true;
opcode.index = children.length;
children.push(opcode);
}
insertItem(item, before) {
if (false
/* LOCAL_DEBUG */
) {
(0, _util.logStep)('list-updates', ['insert', item.key]);
}
let {
opcodeMap,
bounds,
state,
runtime,
children
} = this;
let {
key
} = item;
let nextSibling = before === undefined ? this.marker : before.firstNode();
let elementStack = _elementBuilder.NewElementBuilder.forInitialRender(runtime.env, {
element: bounds.parentElement(),
nextSibling
});
let vm = state.resume(runtime, elementStack);
vm.execute(vm => {
vm.pushUpdating();
let opcode = vm.enterItem(item);
opcode.index = children.length;
children.push(opcode);
opcodeMap.set(key, opcode);
(0, _destroyable.associateDestroyableChild)(this, opcode);
});
}
moveItem(opcode, item, before) {
let {
children
} = this;
(0, _reference.updateRef)(opcode.memo, item.memo);
(0, _reference.updateRef)(opcode.value, item.value);
opcode.retained = true;
let currentSibling, nextSibling;
if (before === undefined) {
(0, _bounds.move)(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) {
(0, _bounds.move)(opcode, nextSibling);
}
}
opcode.index = children.length;
children.push(opcode);
if (false
/* LOCAL_DEBUG */
) {
let type = currentSibling && currentSibling === nextSibling ? 'move-retain' : 'move';
(0, _util.logStep)('list-updates', [type, item.key]);
}
}
deleteItem(opcode) {
if (false
/* LOCAL_DEBUG */
) {
(0, _util.logStep)('list-updates', ['delete', opcode.key]);
}
(0, _destroyable.destroy)(opcode);
(0, _bounds.clear)(opcode);
this.opcodeMap.delete(opcode.key);
}
}
exports.ListBlockOpcode = ListBlockOpcode;
class UpdatingVMFrame {
constructor(ops, exceptionHandler) {
this.ops = ops;
this.exceptionHandler = exceptionHandler;
this.current = 0;
}
goto(index) {
this.current = index;
}
nextStatement() {
return this.ops[this.current++];
}
handleException() {
if (this.exceptionHandler) {
this.exceptionHandler.handleException();
}
}
}
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3BhY2thZ2VzL0BnbGltbWVyL3J1bnRpbWUvbGliL3ZtL3VwZGF0ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBQUE7O0FBaUJBOztBQU9BOztBQUNBOztBQUNBOztBQUVBOztBQUVBOztBQUVjLE1BQUEsY0FBQSxDQUFxQjtBQU9qQyxFQUFBLFdBQUEsQ0FBQSxHQUFBLEVBQThCO0FBQUUsSUFBQSxnQkFBZ0IsR0FBRztBQUFyQixHQUE5QixFQUEwRDtBQUZsRCxTQUFBLFVBQUEsR0FBcUMsSUFBckMsV0FBcUMsRUFBckM7QUFHTixTQUFBLEdBQUEsR0FBQSxHQUFBO0FBQ0EsU0FBQSxHQUFBLEdBQVcsR0FBRyxDQUFkLE1BQVcsRUFBWDtBQUNBLFNBQUEsZ0JBQUEsR0FBQSxnQkFBQTtBQUNEOztBQUVELEVBQUEsT0FBTyxDQUFBLE9BQUEsRUFBQSxPQUFBLEVBQXFEO0FBQzFELFFBQUEsVUFBQSxFQUFXO0FBQ1QsVUFBSSxVQUFVLEdBQWQsSUFBQTs7QUFDQSxVQUFJO0FBQ0YsaURBQTBCLE1BQU0sS0FBQSxRQUFBLENBQUEsT0FBQSxFQUFQLE9BQU8sQ0FBaEMsRUFERSxvQkFDRixFQURFLENBR0Y7QUFDQTs7QUFDQSxRQUFBLFVBQVUsR0FBVixLQUFBO0FBTEYsT0FBQSxTQU1VO0FBQ1IsWUFBQSxVQUFBLEVBQWdCO0FBQ2Q7QUFDQSxVQUFBLE9BQU8sQ0FBUCxLQUFBLENBQWMsMEJBQTBCLCtCQUF4QyxNQUFBO0FBQ0Q7QUFDRjtBQWJILEtBQUEsTUFjTztBQUNMLFdBQUEsUUFBQSxDQUFBLE9BQUEsRUFBQSxPQUFBO0FBQ0Q7QUFDRjs7QUFFTyxFQUFBLFFBQVEsQ0FBQSxPQUFBLEVBQUEsT0FBQSxFQUFxRDtBQUNuRSxRQUFJO0FBQUUsTUFBQTtBQUFGLFFBQUosSUFBQTtBQUVBLFNBQUEsR0FBQSxDQUFBLE9BQUEsRUFBQSxPQUFBOztBQUVBLFdBQUEsSUFBQSxFQUFhO0FBQ1gsVUFBSSxVQUFV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Q0FBekI7QUFDRDs7QUFFRCw4QkFBQSxNQUFBO0FBQ0EsdUJBQUEsTUFBQTtBQUNBLFNBQUEsU0FBQSxDQUFBLE1BQUEsQ0FBc0IsTUFBTSxDQUE1QixHQUFBO0FBQ0Q7O0FBbE42Qzs7OztBQXFOaEQsTUFBQSxlQUFBLENBQXFCO0FBR25CLEVBQUEsV0FBQSxDQUFBLEdBQUEsRUFBQSxnQkFBQSxFQUE2RjtBQUF6RSxTQUFBLEdBQUEsR0FBQSxHQUFBO0FBQStCLFNBQUEsZ0JBQUEsR0FBQSxnQkFBQTtBQUYzQyxTQUFBLE9BQUEsR0FBQSxDQUFBO0FBRXlGOztBQUVqRyxFQUFBLElBQUksQ0FBQSxLQUFBLEVBQWM7QUFDaEIsU0FBQSxPQUFBLEdBQUEsS0FBQTtBQUNEOztBQUVELEVBQUEsYUFBYSxHQUFBO0FBQ1gsV0FBTyxLQUFBLEdBQUEsQ0FBUyxLQUFoQixPQUFnQixFQUFULENBQVA7QUFDRDs7QUFFRCxFQUFBLGVBQWUsR0FBQTtBQUNiLFFBQUksS0FBSixnQkFBQSxFQUEyQjtBQUN6QixXQUFBLGdCQUFBLENBQUEsZUFBQTtBQUNEO0FBQ0Y7O0FBakJrQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IERFQlVHIH0gZnJvbSAnQGdsaW1tZXIvZW52JztcbmltcG9ydCB7XG4gIEJvdW5kcyxcbiAgRHluYW1pY1Njb3BlLFxuICBFbGVtZW50QnVpbGRlcixcbiAgRW52aXJvbm1lbnQsXG4gIEV4Y2VwdGlvbkhhbmRsZXIsXG4gIEdsaW1tZXJUcmVlQ2hhbmdlcyxcbiAgTGl2ZUJsb2NrLFxuICBPcHRpb24sXG4gIFJ1bnRpbWVDb250ZXh0LFxuICBTY29wZSxcbiAgVXBkYXRhYmxlQmxvY2ssXG4gIFVwZGF0aW5nVk0sXG4gIFVwZGF0aW5nT3Bjb2RlLFxufSBmcm9tICdAZ2xpbW1lci9pbnRlcmZhY2VzJztcbmltcG9ydCB7IExPQ0FMX0RFQlVHIH0gZnJvbSAnQGdsaW1tZXIvbG9jYWwtZGVidWctZmxhZ3MnO1xuaW1wb3J0IHtcbiAgT3BhcXVlSXRlcmF0aW9uSXRlbSxcbiAgT3BhcXVlSXRlcmF0b3IsXG4gIFJlZmVyZW5jZSxcbiAgdXBkYXRlUmVmLFxuICB2YWx1ZUZvclJlZixcbn0gZnJvbSAnQGdsaW1tZXIvcmVmZXJlbmNlJztcbmltcG9ydCB7IGFzc29jaWF0ZURlc3Ryb3lhYmxlQ2hpbGQsIGRlc3Ryb3ksIGRlc3Ryb3lDaGlsZHJlbiB9IGZyb20gJ0BnbGltbWVyL2Rlc3Ryb3lhYmxlJztcbmltcG9ydCB7IGV4cGVjdCwgU3RhY2ssIGxvZ1N0ZXAgfSBmcm9tICdAZ2xpbW1lci91dGlsJztcbmltcG9ydCB7IHJlc2V0VHJhY2tpbmcsIHJ1bkluVHJhY2tpbmdUcmFuc2FjdGlvbiB9IGZyb20gJ0BnbGltbWVyL3ZhbGlkYXRvcic7XG5pbXBvcnQgeyBTaW1wbGVDb21tZW50IH0gZnJvbSAnQHNpbXBsZS1kb20vaW50ZXJmYWNlJztcbmltcG9ydCB7IGNsZWFyLCBtb3ZlIGFzIG1vdmVCb3VuZHMgfSBmcm9tICcuLi9ib3VuZHMnO1xuaW1wb3J0IHsgSW50ZXJuYWxWTSwgVm1Jbml0Q2FsbGJhY2sgfSBmcm9tICcuL2FwcGVuZCc7XG5pbXBvcnQgeyBMaXZlQmxvY2tMaXN0LCBOZXdFbGVtZW50QnVpbGRlciB9IGZyb20gJy4vZWxlbWVudC1idWlsZGVyJztcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgVXBkYXRpbmdWTUltcGwgaW1wbGVtZW50cyBVcGRhdGluZ1ZNIHtcbiAgcHVibGljIGVudjogRW52aXJvbm1lbnQ7XG4gIHB1YmxpYyBkb206IEdsaW1tZXJUcmVlQ2hhbmdlcztcbiAgcHVibGljIGFsd2F5c1JldmFsaWRhdGU6IGJvb2xlYW47XG5cbiAgcHJpdmF0ZSBmcmFtZVN0YWNrOiBTdGFjazxVcGRhdGluZ1ZNRnJhbWU+ID0gbmV3IFN0YWNrPFVwZGF0aW5nVk1GcmFtZT4oKTtcblxuICBjb25zdHJ1Y3RvcihlbnY6IEVudmlyb25tZW50LCB7IGFsd2F5c1JldmFsaWRhdGUgPSBmYWxzZSB9KSB7XG4gICAgdGhpcy5lbnYgPSBlbnY7XG4gICAgdGhpcy5kb20gPSBlbnYuZ2V0RE9NKCk7XG4gICAgdGhpcy5hbHdheXNSZXZhbGlkYXRlID0gYWx3YXlzUmV2YWxpZGF0ZTtcbiAgfVxuXG4gIGV4ZWN1dGUob3Bjb2RlczogVXBkYXRpbmdPcGNvZGVbXSwgaGFuZGxlcjogRXhjZXB0aW9uSGFuZGxlcikge1xuICAgIGlmIChERUJVRykge1xuICAgICAgbGV0IGhhc0Vycm9yZWQgPSB0cnVlO1xuICAgICAgdHJ5IHtcbiAgICAgICAgcnVuSW5UcmFja2luZ1RyYW5zYWN0aW9uISgoKSA9PiB0aGlzLl9leGVjdXRlKG9wY29kZXMsIGhhbmRsZXIpLCAnLSBXaGlsZSByZW5kZXJpbmc6Jyk7XG5cbiAgICAgICAgLy8gdXNpbmcgYSBib29sZWFuIGhlcmUgdG8gYXZvaWQgYnJlYWtpbmcgZXJnb25vbWljcyBvZiBcInBhdXNlIG9uIHVuY2F1Z2h0IGV4Y2VwdGlvbnNcIlxuICAgICAgICAvLyB3aGljaCB3b3VsZCBoYXBwZW4gd2l0aCBhIGBjYXRjaGAgKyBgdGhyb3dgXG4gICAgICAgIGhhc0Vycm9yZWQgPSBmYWxzZTtcbiAgICAgIH0gZmluYWxseSB7XG4gICAgICAgIGlmIChoYXNFcnJvcmVkKSB7XG4gICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWNvbnNvbGVcbiAgICAgICAgICBjb25zb2xlLmVycm9yKGBcXG5cXG5FcnJvciBvY2N1cnJlZDpcXG5cXG4ke3Jlc2V0VHJhY2tpbmcoKX1cXG5cXG5gKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLl9leGVjdXRlKG9wY29kZXMsIGhhbmRsZXIpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgX2V4ZWN1dGUob3Bjb2RlczogVXBkYXRpbmdPcGNvZGVbXSwgaGFuZGxlcjogRXhjZXB0aW9uSGFuZGxlcikge1xuICAgIGxldCB7IGZyYW1lU3RhY2sgfSA9IHRoaXM7XG5cbiAgICB0aGlzLnRyeShvcGNvZGVzLCBoYW5kbGVyKTtcblxuICAgIHdoaWxlICh0cnVlKSB7XG4gICAgICBpZiAoZnJhbWVTdGFjay5pc0VtcHR5KCkpIGJyZWFrO1xuXG4gICAgICBsZXQgb3Bjb2RlID0gdGhpcy5mcmFtZS5uZXh0U3RhdGVtZW50KCk7XG5cbiAgICAgIGlmIChvcGNvZGUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICBmcmFtZVN0YWNrLnBvcCgpO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgb3Bjb2RlLmV2YWx1YXRlKHRoaXMpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgZ2V0IGZyYW1lKCkge1xuICAgIHJldHVybiBleHBlY3QodGhpcy5mcmFtZVN0YWNrLmN1cnJlbnQsICdidWc6IGV4cGVjdGVkIGEgZnJhbWUnKTtcbiAgfVxuXG4gIGdvdG8oaW5kZXg6IG51bWJlcikge1xuICAgIHRoaXMuZnJhbWUuZ290byhpbmRleCk7XG4gIH1cblxuICB0cnkob3BzOiBVcGRhdGluZ09wY29kZVtdLCBoYW5kbGVyOiBPcHRpb248RXhjZXB0aW9uSGFuZGxlcj4pIHtcbiAgICB0aGlzLmZyYW1lU3RhY2sucHVzaChuZXcgVXBkYXRpbmdWTUZyYW1lKG9wcywgaGFuZGxlcikpO1xuICB9XG5cbiAgdGhyb3coKSB7XG4gICAgdGhpcy5mcmFtZS5oYW5kbGVFeGNlcHRpb24oKTtcbiAgICB0aGlzLmZyYW1lU3RhY2sucG9wKCk7XG4gIH1cbn1cblxuZXhwb3J0IGludGVyZmFjZSBWTVN0YXRlIHtcbiAgcmVhZG9ubHkgcGM6IG51bWJlcjtcbiAgcmVhZG9ubHkgc2NvcGU6IFNjb3BlO1xuICByZWFkb25seSBkeW5hbWljU2NvcGU6IER5bmFtaWNTY29wZTtcbiAgcmVhZG9ubHkgc3RhY2s6IHVua25vd25bXTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBSZXN1bWFibGVWTVN0YXRlIHtcbiAgcmVzdW1lKHJ1bnRpbWU6IFJ1bnRpbWVDb250ZXh0LCBidWlsZGVyOiBFbGVtZW50QnVpbGRlcik6IEludGVybmFsVk07XG59XG5cbmV4cG9ydCBjbGFzcyBSZXN1bWFibGVWTVN0YXRlSW1wbCBpbXBsZW1lbnRzIFJlc3VtYWJsZVZNU3RhdGUge1xuICBjb25zdHJ1Y3RvcihyZWFkb25seSBzdGF0ZTogVk1TdGF0ZSwgcHJpdmF0ZSByZXN1bWVDYWxsYmFjazogVm1Jbml0Q2FsbGJhY2spIHt9XG5cbiAgcmVzdW1lKHJ1bnRpbWU6IFJ1bnRpbWVDb250ZXh0LCBidWlsZGVyOiBFbGVtZW50QnVpbGRlcik6IEludGVybmFsVk0ge1xuICAgIHJldHVybiB0aGlzLnJlc3VtZUNhbGxiYWNrKHJ1bnRpbWUsIHRoaXMuc3RhdGUsIGJ1aWxkZXIpO1xuICB9XG59XG5cbmV4cG9ydCBhYnN0cmFjdCBjbGFzcyBCbG9ja09wY29kZSBpbXBsZW1lbnRzIFVwZGF0aW5nT3Bjb2RlLCBCb3VuZHMge1xuICBwdWJsaWMgY2hpbGRyZW46IFVwZGF0aW5nT3Bjb2RlW107XG5cbiAgcHJvdGVjdGVkIHJlYWRvbmx5IGJvdW5kczogTGl2ZUJsb2NrO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByb3RlY3RlZCBzdGF0ZTogUmVzdW1hYmxlVk1TdGF0ZSxcbiAgICBwcm90ZWN0ZWQgcnVudGltZTogUnVudGltZUNvbnRleHQsXG4gICAgYm91bmRzOiBMaXZlQmxvY2ssXG4gICAgY2hpbGRyZW46IFVwZGF0aW5nT3Bjb2RlW11cbiAgKSB7XG4gICAgdGhpcy5jaGlsZHJlbiA9IGNoaWxkcmVuO1xuICAgIHRoaXMuYm91bmRzID0gYm91bmRzO1xuICB9XG5cbiAgcGFyZW50RWxlbWVudCgpIHtcbiAgICByZXR1cm4gdGhpcy5ib3VuZHMucGFyZW50RWxlbWVudCgpO1xuICB9XG5cbiAgZmlyc3ROb2RlKCkge1xuICAgIHJldHVybiB0aGlzLmJvdW5kcy5maXJzdE5vZGUoKTtcbiAgfVxuXG4gIGxhc3ROb2RlKCkge1xuICAgIHJldHVybiB0aGlzLmJvdW5kcy5sYXN0Tm9kZSgpO1xuICB9XG5cbiAgZXZhbHVhdGUodm06IFVwZGF0aW5nVk1JbXBsKSB7XG4gICAgdm0udHJ5KHRoaXMuY2hpbGRyZW4sIG51bGwpO1xuICB9XG59XG5cbmV4cG9ydCBjbGFzcyBUcnlPcGNvZGUgZXh0ZW5kcyBCbG9ja09wY29kZSBpbXBsZW1lbnRzIEV4Y2VwdGlvbkhhbmRsZXIge1xuICBwdWJsaWMgdHlwZSA9ICd0cnknO1xuXG4gIHByb3RlY3RlZCBib3VuZHMhOiBVcGRhdGFibGVCbG9jazsgLy8gSGlkZXMgcHJvcGVydHkgb24gYmFzZSBjbGFzc1xuXG4gIGV2YWx1YXRlKHZtOiBVcGRhdGluZ1ZNSW1wbCkge1xuICAgIHZtLnRyeSh0aGlzLmNoaWxkcmVuLCB0aGlzKTtcbiAgfVxuXG4gIGhhbmRsZUV4Y2VwdGlvbigpIHtcbiAgICBsZXQgeyBzdGF0ZSwgYm91bmRzLCBydW50aW1lIH0gPSB0aGlzO1xuXG4gICAgZGVzdHJveUNoaWxkcmVuKHRoaXMpO1xuXG4gICAgbGV0IGVsZW1lbnRTdGFjayA9IE5ld0VsZW1lbnRCdWlsZGVyLnJlc3VtZShydW50aW1lLmVudiwgYm91bmRzKTtcbiAgICBsZXQgdm0gPSBzdGF0ZS5yZXN1bWUocnVudGltZSwgZWxlbWVudFN0YWNrKTtcblxuICAgIGxldCB1cGRhdGluZzogVXBkYXRpbmdPcGNvZGVbXSA9IFtdO1xuICAgIGxldCBjaGlsZHJlbiA9ICh0aGlzLmNoaWxkcmVuID0gW10pO1xuXG4gICAgbGV0IHJlc3VsdCA9IHZtLmV4ZWN1dGUoKHZtKSA9PiB7XG4gICAgICB2bS5wdXNoVXBkYXRpbmcodXBkYXRpbmcpO1xuICAgICAgdm0udXBkYXRlV2l0aCh0aGlzKTtcbiAgICAgIHZtLnB1c2hVcGRhdGluZyhjaGlsZHJlbik7XG4gICAgfSk7XG5cbiAgICBhc3NvY2lhdGVEZXN0cm95YWJsZUNoaWxkKHRoaXMsIHJlc3VsdC5kcm9wKTtcbiAgfVxufVxuXG5leHBvcnQgY2xhc3MgTGlzdEl0ZW1PcGNvZGUgZXh0ZW5kcyBUcnlPcGNvZGUge1xuICBwdWJsaWMgcmV0YWluZWQgPSBmYWxzZTtcbiAgcHVibGljIGluZGV4ID0gLTE7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgc3RhdGU6IFJlc3VtYWJsZVZNU3RhdGUsXG4gICAgcnVudGltZTogUnVudGltZUNvbnRleHQsXG4gICAgYm91bmRzOiBVcGRhdGFibGVCbG9jayxcbiAgICBwdWJsaWMga2V5OiB1bmtub3duLFxuICAgIHB1YmxpYyBtZW1vOiBSZWZlcmVuY2UsXG4gICAgcHVibGljIHZhbHVlOiBSZWZlcmVuY2VcbiAgKSB7XG4gICAgc3VwZXIoc3RhdGUsIHJ1bnRpbWUsIGJvdW5kcywgW10pO1xuICB9XG5cbiAgdXBkYXRlUmVmZXJlbmNlcyhpdGVtOiBPcGFxdWVJdGVyYXRpb25JdGVtKSB7XG4gICAgdGhpcy5yZXRhaW5lZCA9IHRydWU7XG4gICAgdXBkYXRlUmVmKHRoaXMudmFsdWUsIGl0ZW0udmFsdWUpO1xuICAgIHVwZGF0ZVJlZih0aGlzLm1lbW8sIGl0ZW0ubWVtbyk7XG4gIH1cblxuICBzaG91bGRSZW1vdmUoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuICF0aGlzLnJldGFpbmVkO1xuICB9XG5cbiAgcmVzZXQoKSB7XG4gICAgdGhpcy5yZXRhaW5lZCA9IGZhbHNlO1xuICB9XG59XG5cbmV4cG9ydCBjbGFzcyBMaXN0QmxvY2tPcGNvZGUgZXh0ZW5kcyBCbG9ja09wY29kZSB7XG4gIHB1YmxpYyB0eXBlID0gJ2xpc3QtYmxvY2snO1xuICBwdWJsaWMgY2hpbGRyZW4hOiBMaXN0SXRlbU9wY29kZVtdO1xuXG4gIHByaXZhdGUgb3Bjb2RlTWFwID0gbmV3IE1hcDx1bmtub3duLCBMaXN0SXRlbU9wY29kZT4oKTtcbiAgcHJpdmF0ZSBtYXJrZXI6IFNpbXBsZUNvbW1lbnQgfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSBsYXN0SXRlcmF0b3I6IE9wYXF1ZUl0ZXJhdG9yO1xuXG4gIHByb3RlY3RlZCByZWFkb25seSBib3VuZHMhOiBMaXZlQmxvY2tMaXN0O1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHN0YXRlOiBSZXN1bWFibGVWTVN0YXRlLFxuICAgIHJ1bnRpbWU6IFJ1bnRpbWVDb250ZXh0LFxuICAgIGJvdW5kczogTGl2ZUJsb2NrTGlzdCxcbiAgICBjaGlsZHJlbjogTGlzdEl0ZW1PcGNvZGVbXSxcbiAgICBwcml2YXRlIGl0ZXJhYmxlUmVmOiBSZWZlcmVuY2U8T3BhcXVlSXRlcmF0b3I+XG4gICkge1xuICAgIHN1cGVyKHN0YXRlLCBydW50aW1lLCBib3VuZHMsIGNoaWxkcmVuKTtcbiAgICB0aGlzLmxhc3RJdGVyYXRvciA9IHZhbHVlRm9yUmVmKGl0ZXJhYmxlUmVmKTtcbiAgfVxuXG4gIGluaXRpYWxpemVDaGlsZChvcGNvZGU6IExpc3RJdGVtT3Bjb2RlKSB7XG4gICAgb3Bjb2RlLmluZGV4ID0gdGhpcy5jaGlsZHJlbi5sZW5ndGggLSAxO1xuICAgIHRoaXMub3Bjb2RlTWFwLnNldChvcGNvZGUua2V5LCBvcGNvZGUpO1xuICB9XG5cbiAgZXZhbHVhdGUodm06IFVwZGF0aW5nVk1JbXBsKSB7XG4gICAgbGV0IGl0ZXJhdG9yID0gdmFsdWVGb3JSZWYodGhpcy5pdGVyYWJsZVJlZik7XG5cbiAgICBpZiAodGhpcy5sYXN0SXRlcmF0b3IgIT09IGl0ZXJhdG9yKSB7XG4gICAgICBsZXQgeyBib3VuZHMgfSA9IHRoaXM7XG4gICAgICBsZXQgeyBkb20gfSA9IHZtO1xuXG4gICAgICBsZXQgbWFya2VyID0gKHRoaXMubWFya2VyID0gZG9tLmNyZWF0ZUNvbW1lbnQoJycpKTtcbiAgICAgIGRvbS5pbnNlcnRBZnRlcihcbiAgICAgICAgYm91bmRzLnBhcmVudEVsZW1lbnQoKSxcbiAgICAgICAgbWFya2VyLFxuICAgICAgICBleHBlY3QoYm91bmRzLmxhc3ROb2RlKCksIFwiY2FuJ3QgaW5zZXJ0IGFmdGVyIGFuIGVtcHR5IGJvdW5kc1wiKVxuICAgICAgKTtcblxuICAgICAgdGhpcy5zeW5jKGl0ZXJhdG9yKTtcblxuICAgICAgdGhpcy5wYXJlbnRFbGVtZW50KCkucmVtb3ZlQ2hpbGQobWFya2VyKTtcbiAgICAgIHRoaXMubWFya2VyID0gbnVsbDtcbiAgICAgIHRoaXMubGFzdEl0ZXJhdG9yID0gaXRlcmF0b3I7XG4gICAgfVxuXG4gICAgLy8gUnVuIG5vdy11cGRhdGVkIHVwZGF0aW5nIG9wY29kZXNcbiAgICBzdXBlci5ldmFsdWF0ZSh2bSk7XG4gIH1cblxuICBwcml2YXRlIHN5bmMoaXRlcmF0b3I6IE9wYXF1ZUl0ZXJhdG9yKSB7XG4gICAgbGV0IHsgb3Bjb2RlTWFwOiBpdGVtTWFwLCBjaGlsZHJlbiB9ID0gdGhpcztcblxuICAgIGxldCBjdXJyZW50T3Bjb2RlSW5kZXggPSAwO1xuICAgIGxldCBzZWVuSW5kZXggPSAwO1xuXG4gICAgdGhpcy5jaGlsZHJlbiA9IHRoaXMuYm91bmRzLmJvdW5kTGlzdCA9IFtdO1xuXG4gICAgd2hpbGUgKHRydWUpIHtcbiAgICAgIGxldCBpdGVtID0gaXRlcmF0b3IubmV4dCgpO1xuXG4gICAgICBpZiAoaXRlbSA9PT0gbnVsbCkgYnJlYWs7XG5cbiAgICAgIGxldCBvcGNvZGUgPSBjaGlsZHJlbltjdXJyZW50T3Bjb2RlSW5kZXhdO1xuICAgICAgbGV0IHsga2V5IH0gPSBpdGVtO1xuXG4gICAgICAvLyBJdGVtcyB0aGF0IGhhdmUgYWxyZWFkeSBiZWVuIGZvdW5kIGFuZCBtb3ZlZCB3aWxsIGFscmVhZHkgYmUgcmV0YWluZWQsXG4gICAgICAvLyB3ZSBjYW4gY29udGludWUgdW50aWwgd2UgZmluZCB0aGUgbmV4dCB1bnJldGFpbmVkIGl0ZW1cbiAgICAgIHdoaWxlIChvcGNvZGUgIT09IHVuZGVmaW5lZCAmJiBvcGNvZGUucmV0YWluZWQgPT09IHRydWUpIHtcbiAgICAgICAgb3Bjb2RlID0gY2hpbGRyZW5bKytjdXJyZW50T3Bjb2RlSW5kZXhdO1xuICAgICAgfVxuXG4gICAgICBpZiAob3Bjb2RlICE9PSB1bmRlZmluZWQgJiYgb3Bjb2RlLmtleSA9PT0ga2V5KSB7XG4gICAgICAgIHRoaXMucmV0YWluSXRlbShvcGNvZGUsIGl0ZW0pO1xuICAgICAgICBjdXJyZW50T3Bjb2RlSW5kZXgrKztcbiAgICAgIH0gZWxzZSBpZiAoaXRlbU1hcC5oYXMoa2V5KSkge1xuICAgICAgICBsZXQgaXRlbU9wY29kZSA9IGl0ZW1NYXAuZ2V0KGtleSkhO1xuXG4gICAgICAgIC8vIFRoZSBpdGVtIG9wY29kZSB3YXMgc2VlbiBhbHJlYWR5LCBzbyB3ZSBzaG91bGQgbW92ZSBpdC5cbiAgICAgICAgaWYgKGl0ZW1PcGNvZGUuaW5kZXggPCBzZWVuSW5kZXgpIHtcbiAgICAgICAgICB0aGlzLm1vdmVJdGVtKGl0ZW1PcGNvZGUsIGl0ZW0sIG9wY29kZSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gVXBkYXRlIHRoZSBzZWVuIGluZGV4LCB3ZSBhcmUgZ29pbmcgdG8gYmUgbW92aW5nIHRoaXMgaXRlbSBhcm91bmRcbiAgICAgICAgICAvLyBzbyBhbnkgb3RoZXIgaXRlbXMgdGhhdCBjb21lIGJlZm9yZSBpdCB3aWxsIGxpa2VseSBuZWVkIHRvIG1vdmUgYXNcbiAgICAgICAgICAvLyB3ZWxsLlxuICAgICAgICAgIHNlZW5JbmRleCA9IGl0ZW1PcGNvZGUuaW5kZXg7XG5cbiAgICAgICAgICBsZXQgc2VlblVucmV0YWluZWQgPSBmYWxzZTtcblxuICAgICAgICAgIC8vIGl0ZXJhdGUgdGhyb3VnaCBhbGwgb2YgdGhlIG9wY29kZXMgYmV0d2VlbiB0aGUgY3VycmVudCBwb3NpdGlvbiBhbmRcbiAgICAgICAgICAvLyB0aGUgcG9zaXRpb24gb2YgdGhlIGl0ZW0ncyBvcGNvZGUsIGFuZCBkZXRlcm1pbmUgaWYgdGhleSBhcmUgYWxsXG4gICAgICAgICAgLy8gcmV0YWluZWQuXG4gICAgICAgICAgZm9yIChsZXQgaSA9IGN1cnJlbnRPcGNvZGVJbmRleCArIDE7IGkgPCBzZWVuSW5kZXg7IGkrKykge1xuICAgICAgICAgICAgaWYgKGNoaWxkcmVuW2ldLnJldGFpbmVkID09PSBmYWxzZSkge1xuICAgICAgICAgICAgICBzZWVuVW5yZXRhaW5lZCA9IHRydWU7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cblxuICAgICAgICAgIC8vIElmIHdlIGhhdmUgc2VlbiBvbmx5IHJldGFpbmVkIG9wY29kZXMgYmV0d2VlbiB0aGlzIGFuZCB0aGUgbWF0Y2hpbmdcbiAgICAgICAgICAvLyBvcGNvZGUsIGl0IG1lYW5zIHRoYXQgYWxsIHRoZSBvcGNvZGVzIGluIGJldHdlZW4gaGF2ZSBiZWVuIG1vdmVkXG4gICAgICAgICAgLy8gYWxyZWFkeSwgYW5kIHdlIGNhbiBzYWZlbHkgcmV0YWluIHRoaXMgaXRlbSdzIG9wY29kZS5cbiAgICAgICAgICBpZiAoc2VlblVucmV0YWluZWQgPT09IGZhbHNlKSB7XG4gICAgICAgICAgICB0aGlzLnJldGFpbkl0ZW0oaXRlbU9wY29kZSwgaXRlbSk7XG4gICAgICAgICAgICBjdXJyZW50T3Bjb2RlSW5kZXggPSBzZWVuSW5kZXggKyAxO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLm1vdmVJdGVtKGl0ZW1PcGNvZGUsIGl0ZW0sIG9wY29kZSk7XG4gICAgICAgICAgICBjdXJyZW50T3Bjb2RlSW5kZXgrKztcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuaW5zZXJ0SXRlbShpdGVtLCBvcGNvZGUpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgY2hpbGRyZW4ubGVuZ3RoOyBpKyspIHtcbiAgICAgIGxldCBvcGNvZGUgPSBjaGlsZHJlbltpXTtcblxuICAgICAgaWYgKG9wY29kZS5yZXRhaW5lZCA9PT0gZmFsc2UpIHtcbiAgICAgICAgdGhpcy5kZWxldGVJdGVtKG9wY29kZSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBvcGNvZGUucmVzZXQoKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHJldGFpbkl0ZW0ob3Bjb2RlOiBMaXN0SXRlbU9wY29kZSwgaXRlbTogT3BhcXVlSXRlcmF0aW9uSXRlbSkge1xuICAgIGlmIChMT0NBTF9ERUJVRykge1xuICAgICAgbG9nU3RlcCEoJ2xpc3QtdXBkYXRlcycsIFsncmV0YWluJywgaXRlbS5rZXldKTtcbiAgICB9XG5cbiAgICBsZXQgeyBjaGlsZHJlbiB9ID0gdGhpcztcblxuICAgIHVwZGF0ZVJlZihvcGNvZGUubWVtbywgaXRlbS5tZW1vKTtcbiAgICB1cGRhdGVSZWYob3Bjb2RlLnZhbHVlLCBpdGVtLnZhbHVlKTtcbiAgICBvcGNvZGUucmV0YWluZWQgPSB0cnVlO1xuXG4gICAgb3Bjb2RlLmluZGV4ID0gY2hpbGRyZW4ubGVuZ3RoO1xuICAgIGNoaWxkcmVuLnB1c2gob3Bjb2RlKTtcbiAgfVxuXG4gIHByaXZhdGUgaW5zZXJ0SXRlbShpdGVtOiBPcGFxdWVJdGVyYXRpb25JdGVtLCBiZWZvcmU6IExpc3RJdGVtT3Bjb2RlKSB7XG4gICAgaWYgKExPQ0FMX0RFQlVHKSB7XG4gICAgICBsb2dTdGVwISgnbGlzdC11cGRhdGVzJywgWydpbnNlcnQnLCBpdGVtLmtleV0pO1xuICAgIH1cblxuICAgIGxldCB7IG9wY29kZU1hcCwgYm91bmRzLCBzdGF0ZSwgcnVudGltZSwgY2hpbGRyZW4gfSA9IHRoaXM7XG4gICAgbGV0IHsga2V5IH0gPSBpdGVtO1xuICAgIGxldCBuZXh0U2libGluZyA9IGJlZm9yZSA9PT0gdW5kZWZpbmVkID8gdGhpcy5tYXJrZXIgOiBiZWZvcmUuZmlyc3ROb2RlKCk7XG5cbiAgICBsZXQgZWxlbWVudFN0YWNrID0gTmV3RWxlbWVudEJ1aWxkZXIuZm9ySW5pdGlhbFJlbmRlcihydW50aW1lLmVudiwge1xuICAgICAgZWxlbWVudDogYm91bmRzLnBhcmVudEVsZW1lbnQoKSxcbiAgICAgIG5leHRTaWJsaW5nLFxuICAgIH0pO1xuXG4gICAgbGV0IHZtID0gc3RhdGUucmVzdW1lKHJ1bnRpbWUsIGVsZW1lbnRTdGFjayk7XG5cbiAgICB2bS5leGVjdXRlKCh2bSkgPT4ge1xuICAgICAgdm0ucHVzaFVwZGF0aW5nKCk7XG4gICAgICBsZXQgb3Bjb2RlID0gdm0uZW50ZXJJdGVtKGl0ZW0pO1xuXG4gICAgICBvcGNvZGUuaW5kZXggPSBjaGlsZHJlbi5sZW5ndGg7XG4gICAgICBjaGlsZHJlbi5wdXNoKG9wY29kZSk7XG4gICAgICBvcGNvZGVNYXAuc2V0KGtleSwgb3Bjb2RlKTtcbiAgICAgIGFzc29jaWF0ZURlc3Ryb3lhYmxlQ2hpbGQodGhpcywgb3Bjb2RlKTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgbW92ZUl0ZW0ob3Bjb2RlOiBMaXN0SXRlbU9wY29kZSwgaXRlbTogT3BhcXVlSXRlcmF0aW9uSXRlbSwgYmVmb3JlOiBMaXN0SXRlbU9wY29kZSkge1xuICAgIGxldCB7IGNoaWxkcmVuIH0gPSB0aGlzO1xuXG4gICAgdXBkYXRlUmVmKG9wY29kZS5tZW1vLCBpdGVtLm1lbW8pO1xuICAgIHVwZGF0ZVJlZihvcGNvZGUudmFsdWUsIGl0ZW0udmFsdWUpO1xuICAgIG9wY29kZS5yZXRhaW5lZCA9IHRydWU7XG5cbiAgICBsZXQgY3VycmVudFNpYmxpbmcsIG5leHRTaWJsaW5nO1xuXG4gICAgaWYgKGJlZm9yZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBtb3ZlQm91bmRzKG9wY29kZSwgdGhpcy5tYXJrZXIpO1xuICAgIH0gZWxzZSB7XG4gICAgICBjdXJyZW50U2libGluZyA9IG9wY29kZS5sYXN0Tm9kZSgpLm5leHRTaWJsaW5nO1xuICAgICAgbmV4dFNpYmxpbmcgPSBiZWZvcmUuZmlyc3ROb2RlKCk7XG5cbiAgICAgIC8vIEl0ZW1zIGFyZSBtb3ZlZCB0aHJvdWdob3V0IHRoZSBhbGdvcml0aG0sIHNvIHRoZXJlIGFyZSBjYXNlcyB3aGVyZSB0aGVcbiAgICAgIC8vIHRoZSBpdGVtcyBhbHJlYWR5IGhhcHBlbiB0byBiZSBzaWJsaW5ncyAoZS5nLiBhbiBpdGVtIGluIGJldHdlZW4gd2FzXG4gICAgICAvLyBtb3ZlZCBiZWZvcmUgdGhpcyBtb3ZlIGhhcHBlbmVkKS4gQ2hlY2sgdG8gc2VlIGlmIHRoZXkgYXJlIHNpYmxpbmdzXG4gICAgICAvLyBmaXJzdCBiZWZvcmUgZG9pbmcgdGhlIG1vdmUuXG4gICAgICBpZiAoY3VycmVudFNpYmxpbmcgIT09IG5leHRTaWJsaW5nKSB7XG4gICAgICAgIG1vdmVCb3VuZHMob3Bjb2RlLCBuZXh0U2libGluZyk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgb3Bjb2RlLmluZGV4ID0gY2hpbGRyZW4ubGVuZ3RoO1xuICAgIGNoaWxkcmVuLnB1c2gob3Bjb2RlKTtcblxuICAgIGlmIChMT0NBTF9ERUJVRykge1xuICAgICAgbGV0IHR5cGUgPSBjdXJyZW50U2libGluZyAmJiBjdXJyZW50U2libGluZyA9PT0gbmV4dFNpYmxpbmcgPyAnbW92ZS1yZXRhaW4nIDogJ21vdmUnO1xuICAgICAgbG9nU3RlcCEoJ2xpc3QtdXBkYXRlcycsIFt0eXBlLCBpdGVtLmtleV0pO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgZGVsZXRlSXRlbShvcGNvZGU6IExpc3RJdGVtT3Bjb2RlKSB7XG4gICAgaWYgKExPQ0FMX0RFQlVHKSB7XG4gICAgICBsb2dTdGVwISgnbGlzdC11cGRhdGVzJywgWydkZWxldGUnLCBvcGNvZGUua2V5XSk7XG4gICAgfVxuXG4gICAgZGVzdHJveShvcGNvZGUpO1xuICAgIGNsZWFyKG9wY29kZSk7XG4gICAgdGhpcy5vcGNvZGVNYXAuZGVsZXRlKG9wY29kZS5rZXkpO1xuICB9XG59XG5cbmNsYXNzIFVwZGF0aW5nVk1GcmFtZSB7XG4gIHByaXZhdGUgY3VycmVudCA9IDA7XG5cbiAgY29uc3RydWN0b3IocHJpdmF0ZSBvcHM6IFVwZGF0aW5nT3Bjb2RlW10sIHByaXZhdGUgZXhjZXB0aW9uSGFuZGxlcjogT3B0aW9uPEV4Y2VwdGlvbkhhbmRsZXI+KSB7fVxuXG4gIGdvdG8oaW5kZXg6IG51bWJlcikge1xuICAgIHRoaXMuY3VycmVudCA9IGluZGV4O1xuICB9XG5cbiAgbmV4dFN0YXRlbWVudCgpOiBVcGRhdGluZ09wY29kZSB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIHRoaXMub3BzW3RoaXMuY3VycmVudCsrXTtcbiAgfVxuXG4gIGhhbmRsZUV4Y2VwdGlvbigpIHtcbiAgICBpZiAodGhpcy5leGNlcHRpb25IYW5kbGVyKSB7XG4gICAgICB0aGlzLmV4Y2VwdGlvbkhhbmRsZXIuaGFuZGxlRXhjZXB0aW9uKCk7XG4gICAgfVxuICB9XG59XG4iXSwic291cmNlUm9vdCI6IiJ9