@glimmer/runtime
Version:
Minimal runtime needed to render Glimmer templates
586 lines (460 loc) • 58.5 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.isSerializationFirstNode = isSerializationFirstNode;
exports.rehydrationBuilder = rehydrationBuilder;
exports.RehydrateBuilder = exports.RehydratingCursor = exports.SERIALIZATION_FIRST_NODE_STRING = void 0;
var _util = require("@glimmer/util");
var _bounds = require("../bounds");
var _elementBuilder = require("./element-builder");
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;
}
function _inheritsLoose(subClass, superClass) {
subClass.prototype = Object.create(superClass.prototype);
subClass.prototype.constructor = subClass;
subClass.__proto__ = superClass;
}
var SERIALIZATION_FIRST_NODE_STRING = '%+b:0%';
exports.SERIALIZATION_FIRST_NODE_STRING = SERIALIZATION_FIRST_NODE_STRING;
function isSerializationFirstNode(node) {
return node.nodeValue === SERIALIZATION_FIRST_NODE_STRING;
}
var RehydratingCursor = /*#__PURE__*/function (_CursorImpl) {
_inheritsLoose(RehydratingCursor, _CursorImpl);
function RehydratingCursor(element, nextSibling, startingBlockDepth) {
var _this;
_this = _CursorImpl.call(this, element, nextSibling) || this;
_this.startingBlockDepth = startingBlockDepth;
_this.candidate = null;
_this.injectedOmittedNode = false;
_this.openBlockDepth = startingBlockDepth - 1;
return _this;
}
return RehydratingCursor;
}(_bounds.CursorImpl);
exports.RehydratingCursor = RehydratingCursor;
var RehydrateBuilder = /*#__PURE__*/function (_NewElementBuilder) {
_inheritsLoose(RehydrateBuilder, _NewElementBuilder);
function RehydrateBuilder(env, parentNode, nextSibling) {
var _this2;
_this2 = _NewElementBuilder.call(this, env, parentNode, nextSibling) || this;
_this2.unmatchedAttributes = null;
_this2.blockDepth = 0;
if (nextSibling) throw new Error('Rehydration with nextSibling not supported');
var node = _this2.currentCursor.element.firstChild;
while (node !== null) {
if (isOpenBlock(node)) {
break;
}
node = node.nextSibling;
}
false && (0, _util.assert)(node, 'Must have opening comment for rehydration.');
_this2.candidate = node;
var startingBlockOffset = getBlockDepth(node);
if (startingBlockOffset !== 0) {
// We are rehydrating from a partial tree and not the root component
// We need to add an extra block before the first block to rehydrate correctly
// The extra block is needed since the renderComponent API creates a synthetic component invocation which generates the extra block
var newBlockDepth = startingBlockOffset - 1;
var newCandidate = _this2.dom.createComment("%+b:" + newBlockDepth + "%");
node.parentNode.insertBefore(newCandidate, _this2.candidate);
var closingNode = node.nextSibling;
while (closingNode !== null) {
if (isCloseBlock(closingNode) && getBlockDepth(closingNode) === startingBlockOffset) {
break;
}
closingNode = closingNode.nextSibling;
}
false && (0, _util.assert)(closingNode, 'Must have closing comment for starting block comment');
var newClosingBlock = _this2.dom.createComment("%-b:" + newBlockDepth + "%");
node.parentNode.insertBefore(newClosingBlock, closingNode.nextSibling);
_this2.candidate = newCandidate;
_this2.startingBlockOffset = newBlockDepth;
} else {
_this2.startingBlockOffset = 0;
}
return _this2;
}
var _proto = RehydrateBuilder.prototype;
_proto.disableRehydration = function disableRehydration(nextSibling) {
var currentCursor = this.currentCursor; // rehydration will be disabled until we either:
// * hit popElement (and return to using the parent elements cursor)
// * hit closeBlock and the next sibling is a close block comment
// matching the expected openBlockDepth
currentCursor.candidate = null;
currentCursor.nextSibling = nextSibling;
};
_proto.enableRehydration = function enableRehydration(candidate) {
var currentCursor = this.currentCursor;
currentCursor.candidate = candidate;
currentCursor.nextSibling = null;
};
_proto.pushElement = function pushElement(element, nextSibling) {
if (nextSibling === void 0) {
nextSibling = null;
}
var cursor = new RehydratingCursor(element, nextSibling, this.blockDepth || 0);
/**
* <div> <--------------- currentCursor.element
* <!--%+b:1%--> <------- would have been removed during openBlock
* <div> <--------------- currentCursor.candidate -> cursor.element
* <!--%+b:2%--> <----- currentCursor.candidate.firstChild -> cursor.candidate
* Foo
* <!--%-b:2%-->
* </div>
* <!--%-b:1%--> <------ becomes currentCursor.candidate
*/
if (this.candidate !== null) {
cursor.candidate = element.firstChild;
this.candidate = element.nextSibling;
}
this[_elementBuilder.CURSOR_STACK].push(cursor);
} // clears until the end of the current container
// either the current open block or higher
;
_proto.clearMismatch = function clearMismatch(candidate) {
var current = candidate;
var currentCursor = this.currentCursor;
if (currentCursor !== null) {
var openBlockDepth = currentCursor.openBlockDepth;
if (openBlockDepth >= currentCursor.startingBlockDepth) {
while (current) {
if (isCloseBlock(current)) {
var closeBlockDepth = getBlockDepthWithOffset(current, this.startingBlockOffset);
if (openBlockDepth >= closeBlockDepth) {
break;
}
}
current = this.remove(current);
}
} else {
while (current !== null) {
current = this.remove(current);
}
} // current cursor parentNode should be openCandidate if element
// or openCandidate.parentNode if comment
this.disableRehydration(current);
}
};
_proto.__openBlock = function __openBlock() {
var currentCursor = this.currentCursor;
if (currentCursor === null) return;
var blockDepth = this.blockDepth;
this.blockDepth++;
var candidate = currentCursor.candidate;
if (candidate === null) return;
var tagName = currentCursor.element.tagName;
if (isOpenBlock(candidate) && getBlockDepthWithOffset(candidate, this.startingBlockOffset) === blockDepth) {
this.candidate = this.remove(candidate);
currentCursor.openBlockDepth = blockDepth;
} else if (tagName !== 'TITLE' && tagName !== 'SCRIPT' && tagName !== 'STYLE') {
this.clearMismatch(candidate);
}
};
_proto.__closeBlock = function __closeBlock() {
var currentCursor = this.currentCursor;
if (currentCursor === null) return; // openBlock is the last rehydrated open block
var openBlockDepth = currentCursor.openBlockDepth; // this currently is the expected next open block depth
this.blockDepth--;
var candidate = currentCursor.candidate;
var isRehydrating = false;
if (candidate !== null) {
isRehydrating = true; //assert(
// openBlockDepth === this.blockDepth,
// 'when rehydrating, openBlockDepth should match this.blockDepth here'
//);
if (isCloseBlock(candidate) && getBlockDepthWithOffset(candidate, this.startingBlockOffset) === openBlockDepth) {
var nextSibling = this.remove(candidate);
this.candidate = nextSibling;
currentCursor.openBlockDepth--;
} else {
// close the block and clear mismatch in parent container
// we will be either at the end of the element
// or at the end of our containing block
this.clearMismatch(candidate);
isRehydrating = false;
}
}
if (isRehydrating === false) {
// check if nextSibling matches our expected close block
// if so, we remove the close block comment and
// restore rehydration after clearMismatch disabled
var _nextSibling = currentCursor.nextSibling;
if (_nextSibling !== null && isCloseBlock(_nextSibling) && getBlockDepthWithOffset(_nextSibling, this.startingBlockOffset) === this.blockDepth) {
// restore rehydration state
var _candidate2 = this.remove(_nextSibling);
this.enableRehydration(_candidate2);
currentCursor.openBlockDepth--;
}
}
};
_proto.__appendNode = function __appendNode(node) {
var candidate = this.candidate; // This code path is only used when inserting precisely one node. It needs more
// comparison logic, but we can probably lean on the cases where this code path
// is actually used.
if (candidate) {
return candidate;
} else {
return _NewElementBuilder.prototype.__appendNode.call(this, node);
}
};
_proto.__appendHTML = function __appendHTML(html) {
var candidateBounds = this.markerBounds();
if (candidateBounds) {
var first = candidateBounds.firstNode();
var last = candidateBounds.lastNode();
var newBounds = new _bounds.ConcreteBounds(this.element, first.nextSibling, last.previousSibling);
var possibleEmptyMarker = this.remove(first);
this.remove(last);
if (possibleEmptyMarker !== null && isEmpty(possibleEmptyMarker)) {
this.candidate = this.remove(possibleEmptyMarker);
if (this.candidate !== null) {
this.clearMismatch(this.candidate);
}
}
return newBounds;
} else {
return _NewElementBuilder.prototype.__appendHTML.call(this, html);
}
};
_proto.remove = function remove(node) {
var element = node.parentNode;
var next = node.nextSibling;
element.removeChild(node);
return next;
};
_proto.markerBounds = function markerBounds() {
var _candidate = this.candidate;
if (_candidate && isMarker(_candidate)) {
var first = _candidate;
var last = first.nextSibling;
while (last && !isMarker(last)) {
last = last.nextSibling;
}
return new _bounds.ConcreteBounds(this.element, first, last);
} else {
return null;
}
};
_proto.__appendText = function __appendText(string) {
var candidate = this.candidate;
if (candidate) {
if (isTextNode(candidate)) {
if (candidate.nodeValue !== string) {
candidate.nodeValue = string;
}
this.candidate = candidate.nextSibling;
return candidate;
} else if (isSeparator(candidate)) {
this.candidate = this.remove(candidate);
return this.__appendText(string);
} else if (isEmpty(candidate) && string === '') {
this.candidate = this.remove(candidate);
return this.__appendText(string);
} else {
this.clearMismatch(candidate);
return _NewElementBuilder.prototype.__appendText.call(this, string);
}
} else {
return _NewElementBuilder.prototype.__appendText.call(this, string);
}
};
_proto.__appendComment = function __appendComment(string) {
var _candidate = this.candidate;
if (_candidate && isComment(_candidate)) {
if (_candidate.nodeValue !== string) {
_candidate.nodeValue = string;
}
this.candidate = _candidate.nextSibling;
return _candidate;
} else if (_candidate) {
this.clearMismatch(_candidate);
}
return _NewElementBuilder.prototype.__appendComment.call(this, string);
};
_proto.__openElement = function __openElement(tag) {
var _candidate = this.candidate;
if (_candidate && isElement(_candidate) && isSameNodeType(_candidate, tag)) {
this.unmatchedAttributes = [].slice.call(_candidate.attributes);
return _candidate;
} else if (_candidate) {
if (isElement(_candidate) && _candidate.tagName === 'TBODY') {
this.pushElement(_candidate, null);
this.currentCursor.injectedOmittedNode = true;
return this.__openElement(tag);
}
this.clearMismatch(_candidate);
}
return _NewElementBuilder.prototype.__openElement.call(this, tag);
};
_proto.__setAttribute = function __setAttribute(name, value, namespace) {
var unmatched = this.unmatchedAttributes;
if (unmatched) {
var attr = findByName(unmatched, name);
if (attr) {
if (attr.value !== value) {
attr.value = value;
}
unmatched.splice(unmatched.indexOf(attr), 1);
return;
}
}
return _NewElementBuilder.prototype.__setAttribute.call(this, name, value, namespace);
};
_proto.__setProperty = function __setProperty(name, value) {
var unmatched = this.unmatchedAttributes;
if (unmatched) {
var attr = findByName(unmatched, name);
if (attr) {
if (attr.value !== value) {
attr.value = value;
}
unmatched.splice(unmatched.indexOf(attr), 1);
return;
}
}
return _NewElementBuilder.prototype.__setProperty.call(this, name, value);
};
_proto.__flushElement = function __flushElement(parent, constructing) {
var unmatched = this.unmatchedAttributes;
if (unmatched) {
for (var i = 0; i < unmatched.length; i++) {
this.constructing.removeAttribute(unmatched[i].name);
}
this.unmatchedAttributes = null;
} else {
_NewElementBuilder.prototype.__flushElement.call(this, parent, constructing);
}
};
_proto.willCloseElement = function willCloseElement() {
var candidate = this.candidate,
currentCursor = this.currentCursor;
if (candidate !== null) {
this.clearMismatch(candidate);
}
if (currentCursor && currentCursor.injectedOmittedNode) {
this.popElement();
}
_NewElementBuilder.prototype.willCloseElement.call(this);
};
_proto.getMarker = function getMarker(element, guid) {
var marker = element.querySelector("script[glmr=\"" + guid + "\"]");
if (marker) {
return marker;
}
return null;
};
_proto.__pushRemoteElement = function __pushRemoteElement(element, cursorId, insertBefore) {
var marker = this.getMarker(element, cursorId);
false && (0, _util.assert)(!marker || marker.parentNode === element, "expected remote element marker's parent node to match remote element"); // when insertBefore is not present, we clear the element
if (insertBefore === undefined) {
while (element.firstChild !== null && element.firstChild !== marker) {
this.remove(element.firstChild);
}
insertBefore = null;
}
var cursor = new RehydratingCursor(element, null, this.blockDepth);
this[_elementBuilder.CURSOR_STACK].push(cursor);
if (marker === null) {
this.disableRehydration(insertBefore);
} else {
this.candidate = this.remove(marker);
}
var block = new _elementBuilder.RemoteLiveBlock(element);
return this.pushLiveBlock(block, true);
};
_proto.didAppendBounds = function didAppendBounds(bounds) {
_NewElementBuilder.prototype.didAppendBounds.call(this, bounds);
if (this.candidate) {
var last = bounds.lastNode();
this.candidate = last && last.nextSibling;
}
return bounds;
};
_createClass(RehydrateBuilder, [{
key: "currentCursor",
get: function get() {
return this[_elementBuilder.CURSOR_STACK].current;
}
}, {
key: "candidate",
get: function get() {
if (this.currentCursor) {
return this.currentCursor.candidate;
}
return null;
},
set: function set(node) {
var currentCursor = this.currentCursor;
currentCursor.candidate = node;
}
}]);
return RehydrateBuilder;
}(_elementBuilder.NewElementBuilder);
exports.RehydrateBuilder = RehydrateBuilder;
function isTextNode(node) {
return node.nodeType === 3;
}
function isComment(node) {
return node.nodeType === 8;
}
function isOpenBlock(node) {
return node.nodeType === 8
/* COMMENT_NODE */
&& node.nodeValue.lastIndexOf('%+b:', 0) === 0;
}
function isCloseBlock(node) {
return node.nodeType === 8
/* COMMENT_NODE */
&& node.nodeValue.lastIndexOf('%-b:', 0) === 0;
}
function getBlockDepth(node) {
return parseInt(node.nodeValue.slice(4), 10);
}
function getBlockDepthWithOffset(node, offset) {
return getBlockDepth(node) - offset;
}
function isElement(node) {
return node.nodeType === 1;
}
function isMarker(node) {
return node.nodeType === 8 && node.nodeValue === '%glmr%';
}
function isSeparator(node) {
return node.nodeType === 8 && node.nodeValue === '%|%';
}
function isEmpty(node) {
return node.nodeType === 8 && node.nodeValue === '% %';
}
function isSameNodeType(candidate, tag) {
if (candidate.namespaceURI === "http://www.w3.org/2000/svg"
/* SVG */
) {
return candidate.tagName === tag;
}
return candidate.tagName === tag.toUpperCase();
}
function findByName(array, name) {
for (var i = 0; i < array.length; i++) {
var attr = array[i];
if (attr.name === name) return attr;
}
return undefined;
}
function rehydrationBuilder(env, cursor) {
return RehydrateBuilder.forInitialRender(env, cursor);
}
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3BhY2thZ2VzL0BnbGltbWVyL3J1bnRpbWUvbGliL3ZtL3JlaHlkcmF0ZS1idWlsZGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7OztBQUNBOztBQVdBOztBQUNBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFFTyxJQUFNLCtCQUErQixHQUFyQyxRQUFBOzs7QUFFRCxTQUFBLHdCQUFBLENBQUEsSUFBQSxFQUFtRDtBQUN2RCxTQUFPLElBQUksQ0FBSixTQUFBLEtBQVAsK0JBQUE7QUFDRDs7QUFFRCxJQUFNLGlCQUFOLEdBQUEsYUFBQSxVQUFBLFdBQUEsRUFBQTtBQUFBLEVBQUEsY0FBQSxDQUFBLGlCQUFBLEVBQUEsV0FBQSxDQUFBOztBQUlFLFdBQUEsaUJBQUEsQ0FBQSxPQUFBLEVBQUEsV0FBQSxFQUFBLGtCQUFBLEVBRzRDO0FBQUEsUUFBQSxLQUFBOztBQUUxQyxJQUFBLEtBQUEsR0FBQSxXQUFBLENBQUEsSUFBQSxDQUFBLElBQUEsRUFBQSxPQUFBLEVBQUEsV0FBQSxLQUFBLElBQUE7QUFGZ0IsSUFBQSxLQUFBLENBQUEsa0JBQUEsR0FBQSxrQkFBQTtBQU5sQixJQUFBLEtBQUEsQ0FBQSxTQUFBLEdBQUEsSUFBQTtBQUVBLElBQUEsS0FBQSxDQUFBLG1CQUFBLEdBQUEsS0FBQTtBQU9FLElBQUEsS0FBQSxDQUFBLGNBQUEsR0FBc0Isa0JBQWtCLEdBQXhDLENBQUE7QUFIMEMsV0FBQSxLQUFBO0FBSTNDOztBQVhILFNBQUEsaUJBQUE7QUFBQSxDQUFBLENBQUEsa0JBQUEsQ0FBQTs7OztBQWNBLElBQU0sZ0JBQU4sR0FBQSxhQUFBLFVBQUEsa0JBQUEsRUFBQTtBQUFBLEVBQUEsY0FBQSxDQUFBLGdCQUFBLEVBQUEsa0JBQUEsQ0FBQTs7QUFNRSxXQUFBLGdCQUFBLENBQUEsR0FBQSxFQUFBLFVBQUEsRUFBQSxXQUFBLEVBQXdGO0FBQUEsUUFBQSxNQUFBOztBQUN0RixJQUFBLE1BQUEsR0FB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QUosUUFBQSxLQUFBLENBQUEsSUFBdUIsSUFBSSxDQUFKLFNBQUEsS0FBOUIsUUFBQTtBQUNEOztBQUVELFNBQUEsV0FBQSxDQUFBLElBQUEsRUFBcUM7QUFDbkMsU0FBTyxJQUFJLENBQUosUUFBQSxLQUFBLENBQUEsSUFBdUIsSUFBSSxDQUFKLFNBQUEsS0FBOUIsS0FBQTtBQUNEOztBQUVELFNBQUEsT0FBQSxDQUFBLElBQUEsRUFBaUM7QUFDL0IsU0FBTyxJQUFJLENBQUosUUFBQSxLQUFBLENBQUEsSUFBdUIsSUFBSSxDQUFKLFNBQUEsS0FBOUIsS0FBQTtBQUNEOztBQUVELFNBQUEsY0FBQSxDQUFBLFNBQUEsRUFBQSxHQUFBLEVBQTZEO0FBQzNELE1BQUksU0FBUyxDQUFULFlBQUEsS0FBc0I7QUFBQTtBQUExQixJQUE4QztBQUM1QyxhQUFPLFNBQVMsQ0FBVCxPQUFBLEtBQVAsR0FBQTtBQUNEOztBQUNELFNBQU8sU0FBUyxDQUFULE9BQUEsS0FBc0IsR0FBRyxDQUFoQyxXQUE2QixFQUE3QjtBQUNEOztBQUVELFNBQUEsVUFBQSxDQUFBLEtBQUEsRUFBQSxJQUFBLEVBQXFEO0FBQ25ELE9BQUssSUFBSSxDQUFDLEdBQVYsQ0FBQSxFQUFnQixDQUFDLEdBQUcsS0FBSyxDQUF6QixNQUFBLEVBQWtDLENBQWxDLEVBQUEsRUFBdUM7QUFDckMsUUFBSSxJQUFJLEdBQUcsS0FBSyxDQUFoQixDQUFnQixDQUFoQjtBQUNBLFFBQUksSUFBSSxDQUFKLElBQUEsS0FBSixJQUFBLEVBQXdCLE9BQUEsSUFBQTtBQUN6Qjs7QUFFRCxTQUFBLFNBQUE7QUFDRDs7QUFFSyxTQUFBLGtCQUFBLENBQUEsR0FBQSxFQUFBLE1BQUEsRUFBaUU7QUFDckUsU0FBTyxnQkFBZ0IsQ0FBaEIsZ0JBQUEsQ0FBQSxHQUFBLEVBQVAsTUFBTyxDQUFQO0FBQ0QiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBCb3VuZHMsIEVsZW1lbnRCdWlsZGVyLCBFbnZpcm9ubWVudCwgT3B0aW9uLCBNYXliZSB9IGZyb20gJ0BnbGltbWVyL2ludGVyZmFjZXMnO1xuaW1wb3J0IHsgYXNzZXJ0LCBjYXN0VG9Ccm93c2VyLCBjYXN0VG9TaW1wbGUsIGV4cGVjdCwgU3RhY2sgfSBmcm9tICdAZ2xpbW1lci91dGlsJztcbmltcG9ydCB7XG4gIEF0dHJOYW1lc3BhY2UsXG4gIE5hbWVzcGFjZSxcbiAgTm9kZVR5cGUsXG4gIFNpbXBsZUF0dHIsXG4gIFNpbXBsZUNvbW1lbnQsXG4gIFNpbXBsZUVsZW1lbnQsXG4gIFNpbXBsZU5vZGUsXG4gIFNpbXBsZVRleHQsXG59IGZyb20gJ0BzaW1wbGUtZG9tL2ludGVyZmFjZSc7XG5pbXBvcnQgeyBDb25jcmV0ZUJvdW5kcywgQ3Vyc29ySW1wbCB9IGZyb20gJy4uL2JvdW5kcyc7XG5pbXBvcnQgeyBDVVJTT1JfU1RBQ0ssIE5ld0VsZW1lbnRCdWlsZGVyLCBSZW1vdGVMaXZlQmxvY2sgfSBmcm9tICcuL2VsZW1lbnQtYnVpbGRlcic7XG5cbmV4cG9ydCBjb25zdCBTRVJJQUxJWkFUSU9OX0ZJUlNUX05PREVfU1RSSU5HID0gJyUrYjowJSc7XG5cbmV4cG9ydCBmdW5jdGlvbiBpc1NlcmlhbGl6YXRpb25GaXJzdE5vZGUobm9kZTogU2ltcGxlTm9kZSk6IGJvb2xlYW4ge1xuICByZXR1cm4gbm9kZS5ub2RlVmFsdWUgPT09IFNFUklBTElaQVRJT05fRklSU1RfTk9ERV9TVFJJTkc7XG59XG5cbmV4cG9ydCBjbGFzcyBSZWh5ZHJhdGluZ0N1cnNvciBleHRlbmRzIEN1cnNvckltcGwge1xuICBjYW5kaWRhdGU6IE9wdGlvbjxTaW1wbGVOb2RlPiA9IG51bGw7XG4gIG9wZW5CbG9ja0RlcHRoOiBudW1iZXI7XG4gIGluamVjdGVkT21pdHRlZE5vZGUgPSBmYWxzZTtcbiAgY29uc3RydWN0b3IoXG4gICAgZWxlbWVudDogU2ltcGxlRWxlbWVudCxcbiAgICBuZXh0U2libGluZzogT3B0aW9uPFNpbXBsZU5vZGU+LFxuICAgIHB1YmxpYyByZWFkb25seSBzdGFydGluZ0Jsb2NrRGVwdGg6IG51bWJlclxuICApIHtcbiAgICBzdXBlcihlbGVtZW50LCBuZXh0U2libGluZyk7XG4gICAgdGhpcy5vcGVuQmxvY2tEZXB0aCA9IHN0YXJ0aW5nQmxvY2tEZXB0aCAtIDE7XG4gIH1cbn1cblxuZXhwb3J0IGNsYXNzIFJlaHlkcmF0ZUJ1aWxkZXIgZXh0ZW5kcyBOZXdFbGVtZW50QnVpbGRlciBpbXBsZW1lbnRzIEVsZW1lbnRCdWlsZGVyIHtcbiAgcHJpdmF0ZSB1bm1hdGNoZWRBdHRyaWJ1dGVzOiBPcHRpb248U2ltcGxlQXR0cltdPiA9IG51bGw7XG4gIFtDVVJTT1JfU1RBQ0tdITogU3RhY2s8UmVoeWRyYXRpbmdDdXJzb3I+OyAvLyBIaWRlcyBwcm9wZXJ0eSBvbiBiYXNlIGNsYXNzXG4gIGJsb2NrRGVwdGggPSAwO1xuICBzdGFydGluZ0Jsb2NrT2Zmc2V0OiBudW1iZXI7XG5cbiAgY29uc3RydWN0b3IoZW52OiBFbnZpcm9ubWVudCwgcGFyZW50Tm9kZTogU2ltcGxlRWxlbWVudCwgbmV4dFNpYmxpbmc6IE9wdGlvbjxTaW1wbGVOb2RlPikge1xuICAgIHN1cGVyKGVudiwgcGFyZW50Tm9kZSwgbmV4dFNpYmxpbmcpO1xuICAgIGlmIChuZXh0U2libGluZykgdGhyb3cgbmV3IEVycm9yKCdSZWh5ZHJhdGlvbiB3aXRoIG5leHRTaWJsaW5nIG5vdCBzdXBwb3J0ZWQnKTtcblxuICAgIGxldCBub2RlID0gdGhpcy5jdXJyZW50Q3Vyc29yIS5lbGVtZW50LmZpcnN0Q2hpbGQ7XG5cbiAgICB3aGlsZSAobm9kZSAhPT0gbnVsbCkge1xuICAgICAgaWYgKGlzT3BlbkJsb2NrKG5vZGUpKSB7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgbm9kZSA9IG5vZGUubmV4dFNpYmxpbmc7XG4gICAgfVxuXG4gICAgYXNzZXJ0KG5vZGUsICdNdXN0IGhhdmUgb3BlbmluZyBjb21tZW50IGZvciByZWh5ZHJhdGlvbi4nKTtcbiAgICB0aGlzLmNhbmRpZGF0ZSA9IG5vZGU7XG4gICAgY29uc3Qgc3RhcnRpbmdCbG9ja09mZnNldCA9IGdldEJsb2NrRGVwdGgobm9kZSBhcyBTaW1wbGVDb21tZW50KTtcbiAgICBpZiAoc3RhcnRpbmdCbG9ja09mZnNldCAhPT0gMCkge1xuICAgICAgLy8gV2UgYXJlIHJlaHlkcmF0aW5nIGZyb20gYSBwYXJ0aWFsIHRyZWUgYW5kIG5vdCB0aGUgcm9vdCBjb21wb25lbnRcbiAgICAgIC8vIFdlIG5lZWQgdG8gYWRkIGFuIGV4dHJhIGJsb2NrIGJlZm9yZSB0aGUgZmlyc3QgYmxvY2sgdG8gcmVoeWRyYXRlIGNvcnJlY3RseVxuICAgICAgLy8gVGhlIGV4dHJhIGJsb2NrIGlzIG5lZWRlZCBzaW5jZSB0aGUgcmVuZGVyQ29tcG9uZW50IEFQSSBjcmVhdGVzIGEgc3ludGhldGljIGNvbXBvbmVudCBpbnZvY2F0aW9uIHdoaWNoIGdlbmVyYXRlcyB0aGUgZXh0cmEgYmxvY2tcbiAgICAgIGNvbnN0IG5ld0Jsb2NrRGVwdGggPSBzdGFydGluZ0Jsb2NrT2Zmc2V0IC0gMTtcbiAgICAgIGNvbnN0IG5ld0NhbmRpZGF0ZSA9IHRoaXMuZG9tLmNyZWF0ZUNvbW1lbnQoYCUrYjoke25ld0Jsb2NrRGVwdGh9JWApO1xuXG4gICAgICBub2RlIS5wYXJlbnROb2RlIS5pbnNlcnRCZWZvcmUobmV3Q2FuZGlkYXRlLCB0aGlzLmNhbmRpZGF0ZSk7XG4gICAgICBsZXQgY2xvc2luZ05vZGUgPSBub2RlIS5uZXh0U2libGluZztcbiAgICAgIHdoaWxlIChjbG9zaW5nTm9kZSAhPT0gbnVsbCkge1xuICAgICAgICBpZiAoaXNDbG9zZUJsb2NrKGNsb3NpbmdOb2RlKSAmJiBnZXRCbG9ja0RlcHRoKGNsb3NpbmdOb2RlKSA9PT0gc3RhcnRpbmdCbG9ja09mZnNldCkge1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIGNsb3NpbmdOb2RlID0gY2xvc2luZ05vZGUubmV4dFNpYmxpbmc7XG4gICAgICB9XG5cbiAgICAgIGFzc2VydChjbG9zaW5nTm9kZSwgJ011c3QgaGF2ZSBjbG9zaW5nIGNvbW1lbnQgZm9yIHN0YXJ0aW5nIGJsb2NrIGNvbW1lbnQnKTtcbiAgICAgIGNvbnN0IG5ld0Nsb3NpbmdCbG9jayA9IHRoaXMuZG9tLmNyZWF0ZUNvbW1lbnQoYCUtYjoke25ld0Jsb2NrRGVwdGh9JWApO1xuICAgICAgbm9kZSEucGFyZW50Tm9kZSEuaW5zZXJ0QmVmb3JlKG5ld0Nsb3NpbmdCbG9jaywgY2xvc2luZ05vZGUhLm5leHRTaWJsaW5nKTtcbiAgICAgIHRoaXMuY2FuZGlkYXRlID0gbmV3Q2FuZGlkYXRlO1xuICAgICAgdGhpcy5zdGFydGluZ0Jsb2NrT2Zmc2V0ID0gbmV3QmxvY2tEZXB0aDtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5zdGFydGluZ0Jsb2NrT2Zmc2V0ID0gMDtcbiAgICB9XG4gIH1cblxuICBnZXQgY3VycmVudEN1cnNvcigpOiBPcHRpb248UmVoeWRyYXRpbmdDdXJzb3I+IHtcbiAgICByZXR1cm4gdGhpc1tDVVJTT1JfU1RBQ0tdLmN1cnJlbnQ7XG4gIH1cblxuICBnZXQgY2FuZGlkYXRlKCk6IE9wdGlvbjxTaW1wbGVOb2RlPiB7XG4gICAgaWYgKHRoaXMuY3VycmVudEN1cnNvcikge1xuICAgICAgcmV0dXJuIHRoaXMuY3VycmVudEN1cnNvci5jYW5kaWRhdGUhO1xuICAgIH1cblxuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgc2V0IGNhbmRpZGF0ZShub2RlOiBPcHRpb248U2ltcGxlTm9kZT4pIHtcbiAgICBsZXQgY3VycmVudEN1cnNvciA9IHRoaXMuY3VycmVudEN1cnNvciE7XG5cbiAgICBjdXJyZW50Q3Vyc29yLmNhbmRpZGF0ZSA9IG5vZGU7XG4gIH1cblxuICBkaXNhYmxlUmVoeWRyYXRpb24obmV4dFNpYmxpbmc6IE9wdGlvbjxTaW1wbGVOb2RlPikge1xuICAgIGxldCBjdXJyZW50Q3Vyc29yID0gdGhpcy5jdXJyZW50Q3Vyc29yITtcblxuICAgIC8vIHJlaHlkcmF0aW9uIHdpbGwgYmUgZGlzYWJsZWQgdW50aWwgd2UgZWl0aGVyOlxuICAgIC8vICogaGl0IHBvcEVsZW1lbnQgKGFuZCByZXR1cm4gdG8gdXNpbmcgdGhlIHBhcmVudCBlbGVtZW50cyBjdXJzb3IpXG4gICAgLy8gKiBoaXQgY2xvc2VCbG9jayBhbmQgdGhlIG5leHQgc2libGluZyBpcyBhIGNsb3NlIGJsb2NrIGNvbW1lbnRcbiAgICAvLyAgIG1hdGNoaW5nIHRoZSBleHBlY3RlZCBvcGVuQmxvY2tEZXB0aFxuICAgIGN1cnJlbnRDdXJzb3IuY2FuZGlkYXRlID0gbnVsbDtcbiAgICBjdXJyZW50Q3Vyc29yLm5leHRTaWJsaW5nID0gbmV4dFNpYmxpbmc7XG4gIH1cblxuICBlbmFibGVSZWh5ZHJhdGlvbihjYW5kaWRhdGU6IE9wdGlvbjxTaW1wbGVOb2RlPikge1xuICAgIGxldCBjdXJyZW50Q3Vyc29yID0gdGhpcy5jdXJyZW50Q3Vyc29yITtcblxuICAgIGN1cnJlbnRDdXJzb3IuY2FuZGlkYXRlID0gY2FuZGlkYXRlO1xuICAgIGN1cnJlbnRDdXJzb3IubmV4dFNpYmxpbmcgPSBudWxsO1xuICB9XG5cbiAgcHVzaEVsZW1lbnQoXG4gICAgLyoqIGNhbGxlZCBmcm9tIHBhcmVudCBjb25zdHJ1Y3RvciBiZWZvcmUgd2UgaW5pdGlhbGl6ZSB0aGlzICovXG4gICAgdGhpczpcbiAgICAgIHwgUmVoeWRyYXRlQnVpbGRlclxuICAgICAgfCAoTmV3RWxlbWVudEJ1aWxkZXIgJiBQYXJ0aWFsPFBpY2s8UmVoeWRyYXRlQnVpbGRlciwgJ2Jsb2NrRGVwdGgnIHwgJ2NhbmRpZGF0ZSc+PiksXG4gICAgZWxlbWVudDogU2ltcGxlRWxlbWVudCxcbiAgICBuZXh0U2libGluZzogTWF5YmU8U2ltcGxlTm9kZT4gPSBudWxsXG4gICkge1xuICAgIGxldCBjdXJzb3IgPSBuZXcgUmVoeWRyYXRpbmdDdXJzb3IoZWxlbWVudCwgbmV4dFNpYmxpbmcsIHRoaXMuYmxvY2tEZXB0aCB8fCAwKTtcblxuICAgIC8qKlxuICAgICAqIDxkaXY+ICAgPC0tLS0tLS0tLS0tLS0tLSAgY3VycmVudEN1cnNvci5lbGVtZW50XG4gICAgICogICA8IS0tJStiOjElLS0+IDwtLS0tLS0tICB3b3VsZCBoYXZlIGJlZW4gcmVtb3ZlZCBkdXJpbmcgb3BlbkJsb2NrXG4gICAgICogICA8ZGl2PiA8LS0tLS0tLS0tLS0tLS0tICBjdXJyZW50Q3Vyc29yLmNhbmRpZGF0ZSAtPiBjdXJzb3IuZWxlbWVudFxuICAgICAqICAgICA8IS0tJStiOjIlLS0+IDwtLS0tLSAgY3VycmVudEN1cnNvci5jYW5kaWRhdGUuZmlyc3RDaGlsZCAtPiBjdXJzb3IuY2FuZGlkYXRlXG4gICAgICogICAgIEZvb1xuICAgICAqICAgICA8IS0tJS1iOjIlLS0+XG4gICAgICogICA8L2Rpdj5cbiAgICAgKiAgIDwhLS0lLWI6MSUtLT4gIDwtLS0tLS0gIGJlY29tZXMgY3VycmVudEN1cnNvci5jYW5kaWRhdGVcbiAgICAgKi9cbiAgICBpZiAodGhpcy5jYW5kaWRhdGUgIT09IG51bGwpIHtcbiAgICAgIGN1cnNvci5jYW5kaWRhdGUgPSBlbGVtZW50LmZpcnN0Q2hpbGQ7XG4gICAgICB0aGlzLmNhbmRpZGF0ZSA9IGVsZW1lbnQubmV4dFNpYmxpbmc7XG4gICAgfVxuXG4gICAgdGhpc1tDVVJTT1JfU1RBQ0tdLnB1c2goY3Vyc29yKTtcbiAgfVxuXG4gIC8vIGNsZWFycyB1bnRpbCB0aGUgZW5kIG9mIHRoZSBjdXJyZW50IGNvbnRhaW5lclxuICAvLyBlaXRoZXIgdGhlIGN1cnJlbnQgb3BlbiBibG9jayBvciBoaWdoZXJcbiAgcHJpdmF0ZSBjbGVhck1pc21hdGNoKGNhbmRpZGF0ZTogU2ltcGxlTm9kZSkge1xuICAgIGxldCBjdXJyZW50OiBPcHRpb248U2ltcGxlTm9kZT4gPSBjYW5kaWRhdGU7XG4gICAgbGV0IGN1cnJlbnRDdXJzb3IgPSB0aGlzLmN1cnJlbnRDdXJzb3I7XG4gICAgaWYgKGN1cnJlbnRDdXJzb3IgIT09IG51bGwpIHtcbiAgICAgIGxldCBvcGVuQmxvY2tEZXB0aCA9IGN1cnJlbnRDdXJzb3Iub3BlbkJsb2NrRGVwdGg7XG4gICAgICBpZiAob3BlbkJsb2NrRGVwdGggPj0gY3VycmVudEN1cnNvci5zdGFydGluZ0Jsb2NrRGVwdGgpIHtcbiAgICAgICAgd2hpbGUgKGN1cnJlbnQpIHtcbiAgICAgICAgICBpZiAoaXNDbG9zZUJsb2NrKGN1cnJlbnQpKSB7XG4gICAgICAgICAgICBsZXQgY2xvc2VCbG9ja0RlcHRoID0gZ2V0QmxvY2tEZXB0aFdpdGhPZmZzZXQoY3VycmVudCwgdGhpcy5zdGFydGluZ0Jsb2NrT2Zmc2V0KTtcbiAgICAgICAgICAgIGlmIChvcGVuQmxvY2tEZXB0aCA+PSBjbG9zZUJsb2NrRGVwdGgpIHtcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIGN1cnJlbnQgPSB0aGlzLnJlbW92ZShjdXJyZW50KTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgd2hpbGUgKGN1cnJlbnQgIT09IG51bGwpIHtcbiAgICAgICAgICBjdXJyZW50ID0gdGhpcy5yZW1vdmUoY3VycmVudCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIC8vIGN1cnJlbnQgY3Vyc29yIHBhcmVudE5vZGUgc2hvdWxkIGJlIG9wZW5DYW5kaWRhdGUgaWYgZWxlbWVudFxuICAgICAgLy8gb3Igb3BlbkNhbmRpZGF0ZS5wYXJlbnROb2RlIGlmIGNvbW1lbnRcbiAgICAgIHRoaXMuZGlzYWJsZVJlaHlkcmF0aW9uKGN1cnJlbnQpO1xuICAgIH1cbiAgfVxuXG4gIF9fb3BlbkJsb2NrKCk6IHZvaWQge1xuICAgIGxldCB7IGN1cnJlbnRDdXJzb3IgfSA9IHRoaXM7XG4gICAgaWYgKGN1cnJlbnRDdXJzb3IgPT09IG51bGwpIHJldHVybjtcblxuICAgIGxldCBibG9ja0RlcHRoID0gdGhpcy5ibG9ja0RlcHRoO1xuXG4gICAgdGhpcy5ibG9ja0RlcHRoKys7XG5cbiAgICBsZXQgeyBjYW5kaWRhdGUgfSA9IGN1cnJlbnRDdXJzb3I7XG4gICAgaWYgKGNhbmRpZGF0ZSA9PT0gbnVsbCkgcmV0dXJuO1xuXG4gICAgbGV0IHsgdGFnTmFtZSB9ID0gY3VycmVudEN1cnNvci5lbGVtZW50O1xuXG4gICAgaWYgKFxuICAgICAgaXNPcGVuQmxvY2soY2FuZGlkYXRlKSAmJlxuICAgICAgZ2V0QmxvY2tEZXB0aFdpdGhPZmZzZXQoY2FuZGlkYXRlLCB0aGlzLnN0YXJ0aW5nQmxvY2tPZmZzZXQpID09PSBibG9ja0RlcHRoXG4gICAgKSB7XG4gICAgICB0aGlzLmNhbmRpZGF0ZSA9IHRoaXMucmVtb3ZlKGNhbmRpZGF0ZSk7XG4gICAgICBjdXJyZW50Q3Vyc29yLm9wZW5CbG9ja0RlcHRoID0gYmxvY2tEZXB0aDtcbiAgICB9IGVsc2UgaWYgKHRhZ05hbWUgIT09ICdUSVRMRScgJiYgdGFnTmFtZSAhPT0gJ1NDUklQVCcgJiYgdGFnTmFtZSAhPT0gJ1NUWUxFJykge1xuICAgICAgdGhpcy5jbGVhck1pc21hdGNoKGNhbmRpZGF0ZSk7XG4gICAgfVxuICB9XG5cbiAgX19jbG9zZUJsb2NrKCk6IHZvaWQge1xuICAgIGxldCB7IGN1cnJlbnRDdXJzb3IgfSA9IHRoaXM7XG4gICAgaWYgKGN1cnJlbnRDdXJzb3IgPT09IG51bGwpIHJldHVybjtcblxuICAgIC8vIG9wZW5CbG9jayBpcyB0aGUgbGFzdCByZWh5ZHJhdGVkIG9wZW4gYmxvY2tcbiAgICBsZXQgb3BlbkJsb2NrRGVwdGggPSBjdXJyZW50Q3Vyc29yLm9wZW5CbG9ja0RlcHRoO1xuXG4gICAgLy8gdGhpcyBjdXJyZW50bHkgaXMgdGhlIGV4cGVjdGVkIG5leHQgb3BlbiBibG9jayBkZXB0aFxuICAgIHRoaXMuYmxvY2tEZXB0aC0tO1xuXG4gICAgbGV0IHsgY2FuZGlkYXRlIH0gPSBjdXJyZW50Q3Vyc29yO1xuXG4gICAgbGV0IGlzUmVoeWRyYXRpbmcgPSBmYWxzZTtcblxuICAgIGlmIChjYW5kaWRhdGUgIT09IG51bGwpIHtcbiAgICAgIGlzUmVoeWRyYXRpbmcgPSB0cnVlO1xuICAgICAgLy9hc3NlcnQoXG4gICAgICAvLyAgb3BlbkJsb2NrRGVwdGggPT09IHRoaXMuYmxvY2tEZXB0aCxcbiAgICAgIC8vICAnd2hlbiByZWh5ZHJhdGluZywgb3BlbkJsb2NrRGVwdGggc2hvdWxkIG1hdGNoIHRoaXMuYmxvY2tEZXB0aCBoZXJlJ1xuICAgICAgLy8pO1xuXG4gICAgICBpZiAoXG4gICAgICAgIGlzQ2xvc2VCbG9jayhjYW5kaWRhdGUpICYmXG4gICAgICAgIGdldEJsb2NrRGVwdGhXaXRoT2Zmc2V0KGNhbmRpZGF0ZSwgdGhpcy5zdGFydGluZ0Jsb2NrT2Zmc2V0KSA9PT0gb3BlbkJsb2NrRGVwdGhcbiAgICAgICkge1xuICAgICAgICBsZXQgbmV4dFNpYmxpbmcgPSB0aGlzLnJlbW92ZShjYW5kaWRhdGUpO1xuICAgICAgICB0aGlzLmNhbmRpZGF0ZSA9IG5leHRTaWJsaW5nO1xuICAgICAgICBjdXJyZW50Q3Vyc29yLm9wZW5CbG9ja0RlcHRoLS07XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBjbG9zZSB0aGUgYmxvY2sgYW5kIGNsZWFyIG1pc21hdGNoIGluIHBhcmVudCBjb250YWluZXJcbiAgICAgICAgLy8gd2Ugd2lsbCBiZSBlaXRoZXIgYXQgdGhlIGVuZCBvZiB0aGUgZWxlbWVudFxuICAgICAgICAvLyBvciBhdCB0aGUgZW5kIG9mIG91ciBjb250YWluaW5nIGJsb2NrXG4gICAgICAgIHRoaXMuY2xlYXJNaXNtYXRjaChjYW5kaWRhdGUpO1xuICAgICAgICBpc1JlaHlkcmF0aW5nID0gZmFsc2U7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGlzUmVoeWRyYXRpbmcgPT09IGZhbHNlKSB7XG4gICAgICAvLyBjaGVjayBpZiBuZXh0U2libGluZyBtYXRjaGVzIG91ciBleHBlY3RlZCBjbG9zZSBibG9ja1xuICAgICAgLy8gaWYgc28sIHdlIHJlbW92ZSB0aGUgY2xvc2UgYmxvY2sgY29tbWVudCBhbmRcbiAgICAgIC8vIHJlc3RvcmUgcmVoeWRyYXRpb24gYWZ0ZXIgY2xlYXJNaXNtYXRjaCBkaXNhYmxlZFxuICAgICAgbGV0IG5leHRTaWJsaW5nID0gY3VycmVudEN1cnNvci5uZXh0U2libGluZztcbiAgICAgIGlmIChcbiAgICAgICAgbmV4dFNpYmxpbmcgIT09IG51bGwgJiZcbiAgICAgICAgaXNDbG9zZUJsb2NrKG5leHRTaWJsaW5nKSAmJlxuICAgICAgICBnZXRCbG9ja0RlcHRoV2l0aE9mZnNldChuZXh0U2libGluZywgdGhpcy5zdGFydGluZ0Jsb2NrT2Zmc2V0KSA9PT0gdGhpcy5ibG9ja0RlcHRoXG4gICAgICApIHtcbiAgICAgICAgLy8gcmVzdG9yZSByZWh5ZHJhdGlvbiBzdGF0ZVxuICAgICAgICBsZXQgY2FuZGlkYXRlID0gdGhpcy5yZW1vdmUobmV4dFNpYmxpbmcpO1xuICAgICAgICB0aGlzLmVuYWJsZVJlaHlkcmF0aW9uKGNhbmRpZGF0ZSk7XG5cbiAgICAgICAgY3VycmVudEN1cnNvci5vcGVuQmxvY2tEZXB0aC0tO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIF9fYXBwZW5kTm9kZShub2RlOiBTaW1wbGVOb2RlKTogU2ltcGxlTm9kZSB7XG4gICAgbGV0IHsgY2FuZGlkYXRlIH0gPSB0aGlzO1xuXG4gICAgLy8gVGhpcyBjb2RlIHBhdGggaXMgb25seSB1c2VkIHdoZW4gaW5zZXJ0aW5nIHByZWNpc2VseSBvbmUgbm9kZS4gSXQgbmVlZHMgbW9yZVxuICAgIC8vIGNvbXBhcmlzb24gbG9naWMsIGJ1dCB3ZSBjYW4gcHJvYmFibHkgbGVhbiBvbiB0aGUgY2FzZXMgd2hlcmUgdGhpcyBjb2RlIHBhdGhcbiAgICAvLyBpcyBhY3R1YWxseSB1c2VkLlxuICAgIGlmIChjYW5kaWRhdGUpIHtcbiAgICAgIHJldHVybiBjYW5kaWRhdGU7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBzdXBlci5fX2FwcGVuZE5vZGUobm9kZSk7XG4gICAgfVxuICB9XG5cbiAgX19hcHBlbmRIVE1MKGh0bWw6IHN0cmluZyk6IEJvdW5kcyB7XG4gICAgbGV0IGNhbmRpZGF0ZUJvdW5kcyA9IHRoaXMubWFya2VyQm91bmRzKCk7XG5cbiAgICBpZiAoY2FuZGlkYXRlQm91bmRzKSB7XG4gICAgICBsZXQgZmlyc3QgPSBjYW5kaWRhdGVCb3VuZHMuZmlyc3ROb2RlKCkhO1xuICAgICAgbGV0IGxhc3QgPSBjYW5kaWRhdGVCb3VuZHMubGFzdE5vZGUoKSE7XG5cbiAgICAgIGxldCBuZXdCb3VuZHMgPSBuZXcgQ29uY3JldGVCb3VuZHModGhpcy5lbGVtZW50LCBmaXJzdC5uZXh0U2libGluZyEsIGxhc3QucHJldmlvdXNTaWJsaW5nISk7XG5cbiAgICAgIGxldCBwb3NzaWJsZUVtcHR5TWFya2VyID0gdGhpcy5yZW1vdmUoZmlyc3QpO1xuICAgICAgdGhpcy5yZW1vdmUobGFzdCk7XG5cbiAgICAgIGlmIChwb3NzaWJsZUVtcHR5TWFya2VyICE9PSBudWxsICYmIGlzRW1wdHkocG9zc2libGVFbXB0eU1hcmtlcikpIHtcbiAgICAgICAgdGhpcy5jYW5kaWRhdGUgPSB0aGlzLnJlbW92ZShwb3NzaWJsZUVtcHR5TWFya2VyKTtcblxuICAgICAgICBpZiAodGhpcy5jYW5kaWRhdGUgIT09IG51bGwpIHtcbiAgICAgICAgICB0aGlzLmNsZWFyTWlzbWF0Y2godGhpcy5jYW5kaWRhdGUpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBuZXdCb3VuZHM7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBzdXBlci5fX2FwcGVuZEhUTUwoaHRtbCk7XG4gICAgfVxuICB9XG5cbiAgcHJvdGVjdGVkIHJlbW92ZShub2RlOiBTaW1wbGVOb2RlKTogT3B0aW9uPFNpbXBsZU5vZGU+IHtcbiAgICBsZXQgZWxlbWVudCA9IGV4cGVjdChub2RlLnBhcmVudE5vZGUsIGBjYW5ub3QgcmVtb3ZlIGEgZGV0YWNoZWQgbm9kZWApIGFzIFNpbXBsZUVsZW1lbnQ7XG4gICAgbGV0IG5leHQgPSBub2RlLm5leHRTaWJsaW5nO1xuICAgIGVsZW1lbnQucmVtb3ZlQ2hpbGQobm9kZSk7XG4gICAgcmV0dXJuIG5leHQ7XG4gIH1cblxuICBwcml2YXRlIG1hcmtlckJvdW5kcygpOiBPcHRpb248Qm91bmRzPiB7XG4gICAgbGV0IF9jYW5kaWRhdGUgPSB0aGlzLmNhbmRpZGF0ZTtcblxuICAgIGlmIChfY2FuZGlkYXRlICYmIGlzTWFya2VyKF9jYW5kaWRhdGUpKSB7XG4gICAgICBsZXQgZmlyc3QgPSBfY2FuZGlkYXRlO1xuICAgICAgbGV0IGxhc3QgPSBleHBlY3QoZmlyc3QubmV4dFNpYmxpbmcsIGBCVUc6IHNlcmlhbGl6YXRpb24gbWFya2VycyBtdXN0IGJlIHBhaXJlZGApO1xuXG4gICAgICB3aGlsZSAobGFzdCAmJiAhaXNNYXJrZXIobGFzdCkpIHtcbiAgICAgICAgbGFzdCA9IGV4cGVjdChsYXN0Lm5leHRTaWJsaW5nLCBgQlVHOiBzZXJpYWxpemF0aW9uIG1hcmtlcnMgbXVzdCBiZSBwYWlyZWRgKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIG5ldyBDb25jcmV0ZUJvdW5kcyh0aGlzLmVsZW1lbnQsIGZpcnN0LCBsYXN0KTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICB9XG5cbiAgX19hcHBlbmRUZXh0KHN0cmluZzogc3RyaW5nKTogU2ltcGxlVGV4dCB7XG4gICAgbGV0IHsgY2FuZGlkYXRlIH0gPSB0aGlzO1xuXG4gICAgaWYgKGNhbmRpZGF0ZSkge1xuICAgICAgaWYgKGlzVGV4dE5vZGUoY2FuZGlkYXRlKSkge1xuICAgICAgICBpZiAoY2FuZGlkYXRlLm5vZGVWYWx1ZSAhPT0gc3RyaW5nKSB7XG4gICAgICAgICAgY2FuZGlkYXRlLm5vZGVWYWx1ZSA9IHN0cmluZztcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmNhbmRpZGF0ZSA9IGNhbmRpZGF0ZS5uZXh0U2libGluZztcblxuICAgICAgICByZXR1cm4gY2FuZG