@glimmer/runtime
Version:
Minimal runtime needed to render Glimmer templates
549 lines (434 loc) • 56 kB
JavaScript
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; }
import { assert } from '@glimmer/util';
import { ConcreteBounds, CursorImpl } from '../bounds';
import { CURSOR_STACK, NewElementBuilder, RemoteLiveBlock } from './element-builder';
export var SERIALIZATION_FIRST_NODE_STRING = '%+b:0%';
export function isSerializationFirstNode(node) {
return node.nodeValue === SERIALIZATION_FIRST_NODE_STRING;
}
export 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;
}(CursorImpl);
export 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 && 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 && 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[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 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 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 && 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[CURSOR_STACK].push(cursor);
if (marker === null) {
this.disableRehydration(insertBefore);
} else {
this.candidate = this.remove(marker);
}
var block = new 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[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;
}(NewElementBuilder);
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;
}
export function rehydrationBuilder(env, cursor) {
return RehydrateBuilder.forInitialRender(env, cursor);
}
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3BhY2thZ2VzL0BnbGltbWVyL3J1bnRpbWUvbGliL3ZtL3JlaHlkcmF0ZS1idWlsZGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7OztBQUNBLFNBQUEsTUFBQSxRQUFBLGVBQUE7QUFXQSxTQUFBLGNBQUEsRUFBQSxVQUFBLFFBQUEsV0FBQTtBQUNBLFNBQUEsWUFBQSxFQUFBLGlCQUFBLEVBQUEsZUFBQSxRQUFBLG1CQUFBO0FBRUEsT0FBTyxJQUFNLCtCQUErQixHQUFyQyxRQUFBO0FBRVAsT0FBTSxTQUFBLHdCQUFBLENBQUEsSUFBQSxFQUFtRDtBQUN2RCxTQUFPLElBQUksQ0FBSixTQUFBLEtBQVAsK0JBQUE7QUFDRDtBQUVELFdBQU0saUJBQU47QUFBQTs7QUFJRSw2QkFBQSxPQUFBLEVBQUEsV0FBQSxFQUFBLGtCQUFBLEVBRzRDO0FBQUE7O0FBRTFDLG1DQUFBLE9BQUEsRUFBQSxXQUFBO0FBRmdCLFVBQUEsa0JBQUEsR0FBQSxrQkFBQTtBQU5sQixVQUFBLFNBQUEsR0FBQSxJQUFBO0FBRUEsVUFBQSxtQkFBQSxHQUFBLEtBQUE7QUFPRSxVQUFBLGNBQUEsR0FBc0Isa0JBQWtCLEdBQXhDLENBQUE7QUFIMEM7QUFJM0M7O0FBWEg7QUFBQSxFQUFNLFVBQU47QUFjQSxXQUFNLGdCQUFOO0FBQUE7O0FBTUUsNEJBQUEsR0FBQSxFQUFBLFVBQUEsRUFBQSxXQUFBLEVBQXdGO0FBQUE7O0FBQ3RGLDJDQUFBLEdBQUEsRUFBQSxVQUFBLEVBQUEsV0FBQTtBQU5NLFdBQUEsbUJBQUEsR0FBQSxJQUFBO0FBRVIsV0FBQSxVQUFBLEdBQUEsQ0FBQTtBQUtFLFFBQUEsV0FBQSxFQUFpQixNQUFNLElBQUEsS0FBQSxDQUFOLDRDQUFNLENBQU47QUFFakIsUUFBSSxJQUFJLEdBQUcsT0FBQSxhQUFBLENBQUEsT0FBQSxDQUFYLFVBQUE7O0FBRUEsV0FBTyxJQUFJLEtBQVgsSUFBQSxFQUFzQjtBQUNwQixVQUFJLFdB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Q0FBQSxFQUFnQixDQUFDLEdBQUcsS0FBSyxDQUF6QixNQUFBLEVBQWtDLENBQWxDLEVBQUEsRUFBdUM7QUFDckMsUUFBSSxJQUFJLEdBQUcsS0FBSyxDQUFoQixDQUFnQixDQUFoQjtBQUNBLFFBQUksSUFBSSxDQUFKLElBQUEsS0FBSixJQUFBLEVBQXdCLE9BQUEsSUFBQTtBQUN6Qjs7QUFFRCxTQUFBLFNBQUE7QUFDRDs7QUFFRCxPQUFNLFNBQUEsa0JBQUEsQ0FBQSxHQUFBLEVBQUEsTUFBQSxFQUFpRTtBQUNyRSxTQUFPLGdCQUFnQixDQUFoQixnQkFBQSxDQUFBLEdBQUEsRUFBUCxNQUFPLENBQVA7QUFDRCIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEJvdW5kcywgRWxlbWVudEJ1aWxkZXIsIEVudmlyb25tZW50LCBPcHRpb24sIE1heWJlIH0gZnJvbSAnQGdsaW1tZXIvaW50ZXJmYWNlcyc7XG5pbXBvcnQgeyBhc3NlcnQsIGNhc3RUb0Jyb3dzZXIsIGNhc3RUb1NpbXBsZSwgZXhwZWN0LCBTdGFjayB9IGZyb20gJ0BnbGltbWVyL3V0aWwnO1xuaW1wb3J0IHtcbiAgQXR0ck5hbWVzcGFjZSxcbiAgTmFtZXNwYWNlLFxuICBOb2RlVHlwZSxcbiAgU2ltcGxlQXR0cixcbiAgU2ltcGxlQ29tbWVudCxcbiAgU2ltcGxlRWxlbWVudCxcbiAgU2ltcGxlTm9kZSxcbiAgU2ltcGxlVGV4dCxcbn0gZnJvbSAnQHNpbXBsZS1kb20vaW50ZXJmYWNlJztcbmltcG9ydCB7IENvbmNyZXRlQm91bmRzLCBDdXJzb3JJbXBsIH0gZnJvbSAnLi4vYm91bmRzJztcbmltcG9ydCB7IENVUlNPUl9TVEFDSywgTmV3RWxlbWVudEJ1aWxkZXIsIFJlbW90ZUxpdmVCbG9jayB9IGZyb20gJy4vZWxlbWVudC1idWlsZGVyJztcblxuZXhwb3J0IGNvbnN0IFNFUklBTElaQVRJT05fRklSU1RfTk9ERV9TVFJJTkcgPSAnJStiOjAlJztcblxuZXhwb3J0IGZ1bmN0aW9uIGlzU2VyaWFsaXphdGlvbkZpcnN0Tm9kZShub2RlOiBTaW1wbGVOb2RlKTogYm9vbGVhbiB7XG4gIHJldHVybiBub2RlLm5vZGVWYWx1ZSA9PT0gU0VSSUFMSVpBVElPTl9GSVJTVF9OT0RFX1NUUklORztcbn1cblxuZXhwb3J0IGNsYXNzIFJlaHlkcmF0aW5nQ3Vyc29yIGV4dGVuZHMgQ3Vyc29ySW1wbCB7XG4gIGNhbmRpZGF0ZTogT3B0aW9uPFNpbXBsZU5vZGU+ID0gbnVsbDtcbiAgb3BlbkJsb2NrRGVwdGg6IG51bWJlcjtcbiAgaW5qZWN0ZWRPbWl0dGVkTm9kZSA9IGZhbHNlO1xuICBjb25zdHJ1Y3RvcihcbiAgICBlbGVtZW50OiBTaW1wbGVFbGVtZW50LFxuICAgIG5leHRTaWJsaW5nOiBPcHRpb248U2ltcGxlTm9kZT4sXG4gICAgcHVibGljIHJlYWRvbmx5IHN0YXJ0aW5nQmxvY2tEZXB0aDogbnVtYmVyXG4gICkge1xuICAgIHN1cGVyKGVsZW1lbnQsIG5leHRTaWJsaW5nKTtcbiAgICB0aGlzLm9wZW5CbG9ja0RlcHRoID0gc3RhcnRpbmdCbG9ja0RlcHRoIC0gMTtcbiAgfVxufVxuXG5leHBvcnQgY2xhc3MgUmVoeWRyYXRlQnVpbGRlciBleHRlbmRzIE5ld0VsZW1lbnRCdWlsZGVyIGltcGxlbWVudHMgRWxlbWVudEJ1aWxkZXIge1xuICBwcml2YXRlIHVubWF0Y2hlZEF0dHJpYnV0ZXM6IE9wdGlvbjxTaW1wbGVBdHRyW10+ID0gbnVsbDtcbiAgW0NVUlNPUl9TVEFDS10hOiBTdGFjazxSZWh5ZHJhdGluZ0N1cnNvcj47IC8vIEhpZGVzIHByb3BlcnR5IG9uIGJhc2UgY2xhc3NcbiAgYmxvY2tEZXB0aCA9IDA7XG4gIHN0YXJ0aW5nQmxvY2tPZmZzZXQ6IG51bWJlcjtcblxuICBjb25zdHJ1Y3RvcihlbnY6IEVudmlyb25tZW50LCBwYXJlbnROb2RlOiBTaW1wbGVFbGVtZW50LCBuZXh0U2libGluZzogT3B0aW9uPFNpbXBsZU5vZGU+KSB7XG4gICAgc3VwZXIoZW52LCBwYXJlbnROb2RlLCBuZXh0U2libGluZyk7XG4gICAgaWYgKG5leHRTaWJsaW5nKSB0aHJvdyBuZXcgRXJyb3IoJ1JlaHlkcmF0aW9uIHdpdGggbmV4dFNpYmxpbmcgbm90IHN1cHBvcnRlZCcpO1xuXG4gICAgbGV0IG5vZGUgPSB0aGlzLmN1cnJlbnRDdXJzb3IhLmVsZW1lbnQuZmlyc3RDaGlsZDtcblxuICAgIHdoaWxlIChub2RlICE9PSBudWxsKSB7XG4gICAgICBpZiAoaXNPcGVuQmxvY2sobm9kZSkpIHtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBub2RlID0gbm9kZS5uZXh0U2libGluZztcbiAgICB9XG5cbiAgICBhc3NlcnQobm9kZSwgJ011c3QgaGF2ZSBvcGVuaW5nIGNvbW1lbnQgZm9yIHJlaHlkcmF0aW9uLicpO1xuICAgIHRoaXMuY2FuZGlkYXRlID0gbm9kZTtcbiAgICBjb25zdCBzdGFydGluZ0Jsb2NrT2Zmc2V0ID0gZ2V0QmxvY2tEZXB0aChub2RlIGFzIFNpbXBsZUNvbW1lbnQpO1xuICAgIGlmIChzdGFydGluZ0Jsb2NrT2Zmc2V0ICE9PSAwKSB7XG4gICAgICAvLyBXZSBhcmUgcmVoeWRyYXRpbmcgZnJvbSBhIHBhcnRpYWwgdHJlZSBhbmQgbm90IHRoZSByb290IGNvbXBvbmVudFxuICAgICAgLy8gV2UgbmVlZCB0byBhZGQgYW4gZXh0cmEgYmxvY2sgYmVmb3JlIHRoZSBmaXJzdCBibG9jayB0byByZWh5ZHJhdGUgY29ycmVjdGx5XG4gICAgICAvLyBUaGUgZXh0cmEgYmxvY2sgaXMgbmVlZGVkIHNpbmNlIHRoZSByZW5kZXJDb21wb25lbnQgQVBJIGNyZWF0ZXMgYSBzeW50aGV0aWMgY29tcG9uZW50IGludm9jYXRpb24gd2hpY2ggZ2VuZXJhdGVzIHRoZSBleHRyYSBibG9ja1xuICAgICAgY29uc3QgbmV3QmxvY2tEZXB0aCA9IHN0YXJ0aW5nQmxvY2tPZmZzZXQgLSAxO1xuICAgICAgY29uc3QgbmV3Q2FuZGlkYXRlID0gdGhpcy5kb20uY3JlYXRlQ29tbWVudChgJStiOiR7bmV3QmxvY2tEZXB0aH0lYCk7XG5cbiAgICAgIG5vZGUhLnBhcmVudE5vZGUhLmluc2VydEJlZm9yZShuZXdDYW5kaWRhdGUsIHRoaXMuY2FuZGlkYXRlKTtcbiAgICAgIGxldCBjbG9zaW5nTm9kZSA9IG5vZGUhLm5leHRTaWJsaW5nO1xuICAgICAgd2hpbGUgKGNsb3NpbmdOb2RlICE9PSBudWxsKSB7XG4gICAgICAgIGlmIChpc0Nsb3NlQmxvY2soY2xvc2luZ05vZGUpICYmIGdldEJsb2NrRGVwdGgoY2xvc2luZ05vZGUpID09PSBzdGFydGluZ0Jsb2NrT2Zmc2V0KSB7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgY2xvc2luZ05vZGUgPSBjbG9zaW5nTm9kZS5uZXh0U2libGluZztcbiAgICAgIH1cblxuICAgICAgYXNzZXJ0KGNsb3NpbmdOb2RlLCAnTXVzdCBoYXZlIGNsb3NpbmcgY29tbWVudCBmb3Igc3RhcnRpbmcgYmxvY2sgY29tbWVudCcpO1xuICAgICAgY29uc3QgbmV3Q2xvc2luZ0Jsb2NrID0gdGhpcy5kb20uY3JlYXRlQ29tbWVudChgJS1iOiR7bmV3QmxvY2tEZXB0aH0lYCk7XG4gICAgICBub2RlIS5wYXJlbnROb2RlIS5pbnNlcnRCZWZvcmUobmV3Q2xvc2luZ0Jsb2NrLCBjbG9zaW5nTm9kZSEubmV4dFNpYmxpbmcpO1xuICAgICAgdGhpcy5jYW5kaWRhdGUgPSBuZXdDYW5kaWRhdGU7XG4gICAgICB0aGlzLnN0YXJ0aW5nQmxvY2tPZmZzZXQgPSBuZXdCbG9ja0RlcHRoO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnN0YXJ0aW5nQmxvY2tPZmZzZXQgPSAwO1xuICAgIH1cbiAgfVxuXG4gIGdldCBjdXJyZW50Q3Vyc29yKCk6IE9wdGlvbjxSZWh5ZHJhdGluZ0N1cnNvcj4ge1xuICAgIHJldHVybiB0aGlzW0NVUlNPUl9TVEFDS10uY3VycmVudDtcbiAgfVxuXG4gIGdldCBjYW5kaWRhdGUoKTogT3B0aW9uPFNpbXBsZU5vZGU+IHtcbiAgICBpZiAodGhpcy5jdXJyZW50Q3Vyc29yKSB7XG4gICAgICByZXR1cm4gdGhpcy5jdXJyZW50Q3Vyc29yLmNhbmRpZGF0ZSE7XG4gICAgfVxuXG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBzZXQgY2FuZGlkYXRlKG5vZGU6IE9wdGlvbjxTaW1wbGVOb2RlPikge1xuICAgIGxldCBjdXJyZW50Q3Vyc29yID0gdGhpcy5jdXJyZW50Q3Vyc29yITtcblxuICAgIGN1cnJlbnRDdXJzb3IuY2FuZGlkYXRlID0gbm9kZTtcbiAgfVxuXG4gIGRpc2FibGVSZWh5ZHJhdGlvbihuZXh0U2libGluZzogT3B0aW9uPFNpbXBsZU5vZGU+KSB7XG4gICAgbGV0IGN1cnJlbnRDdXJzb3IgPSB0aGlzLmN1cnJlbnRDdXJzb3IhO1xuXG4gICAgLy8gcmVoeWRyYXRpb24gd2lsbCBiZSBkaXNhYmxlZCB1bnRpbCB3ZSBlaXRoZXI6XG4gICAgLy8gKiBoaXQgcG9wRWxlbWVudCAoYW5kIHJldHVybiB0byB1c2luZyB0aGUgcGFyZW50IGVsZW1lbnRzIGN1cnNvcilcbiAgICAvLyAqIGhpdCBjbG9zZUJsb2NrIGFuZCB0aGUgbmV4dCBzaWJsaW5nIGlzIGEgY2xvc2UgYmxvY2sgY29tbWVudFxuICAgIC8vICAgbWF0Y2hpbmcgdGhlIGV4cGVjdGVkIG9wZW5CbG9ja0RlcHRoXG4gICAgY3VycmVudEN1cnNvci5jYW5kaWRhdGUgPSBudWxsO1xuICAgIGN1cnJlbnRDdXJzb3IubmV4dFNpYmxpbmcgPSBuZXh0U2libGluZztcbiAgfVxuXG4gIGVuYWJsZVJlaHlkcmF0aW9uKGNhbmRpZGF0ZTogT3B0aW9uPFNpbXBsZU5vZGU+KSB7XG4gICAgbGV0IGN1cnJlbnRDdXJzb3IgPSB0aGlzLmN1cnJlbnRDdXJzb3IhO1xuXG4gICAgY3VycmVudEN1cnNvci5jYW5kaWRhdGUgPSBjYW5kaWRhdGU7XG4gICAgY3VycmVudEN1cnNvci5uZXh0U2libGluZyA9IG51bGw7XG4gIH1cblxuICBwdXNoRWxlbWVudChcbiAgICAvKiogY2FsbGVkIGZyb20gcGFyZW50IGNvbnN0cnVjdG9yIGJlZm9yZSB3ZSBpbml0aWFsaXplIHRoaXMgKi9cbiAgICB0aGlzOlxuICAgICAgfCBSZWh5ZHJhdGVCdWlsZGVyXG4gICAgICB8IChOZXdFbGVtZW50QnVpbGRlciAmIFBhcnRpYWw8UGljazxSZWh5ZHJhdGVCdWlsZGVyLCAnYmxvY2tEZXB0aCcgfCAnY2FuZGlkYXRlJz4+KSxcbiAgICBlbGVtZW50OiBTaW1wbGVFbGVtZW50LFxuICAgIG5leHRTaWJsaW5nOiBNYXliZTxTaW1wbGVOb2RlPiA9IG51bGxcbiAgKSB7XG4gICAgbGV0IGN1cnNvciA9IG5ldyBSZWh5ZHJhdGluZ0N1cnNvcihlbGVtZW50LCBuZXh0U2libGluZywgdGhpcy5ibG9ja0RlcHRoIHx8IDApO1xuXG4gICAgLyoqXG4gICAgICogPGRpdj4gICA8LS0tLS0tLS0tLS0tLS0tICBjdXJyZW50Q3Vyc29yLmVsZW1lbnRcbiAgICAgKiAgIDwhLS0lK2I6MSUtLT4gPC0tLS0tLS0gIHdvdWxkIGhhdmUgYmVlbiByZW1vdmVkIGR1cmluZyBvcGVuQmxvY2tcbiAgICAgKiAgIDxkaXY+IDwtLS0tLS0tLS0tLS0tLS0gIGN1cnJlbnRDdXJzb3IuY2FuZGlkYXRlIC0+IGN1cnNvci5lbGVtZW50XG4gICAgICogICAgIDwhLS0lK2I6MiUtLT4gPC0tLS0tICBjdXJyZW50Q3Vyc29yLmNhbmRpZGF0ZS5maXJzdENoaWxkIC0+IGN1cnNvci5jYW5kaWRhdGVcbiAgICAgKiAgICAgRm9vXG4gICAgICogICAgIDwhLS0lLWI6MiUtLT5cbiAgICAgKiAgIDwvZGl2PlxuICAgICAqICAgPCEtLSUtYjoxJS0tPiAgPC0tLS0tLSAgYmVjb21lcyBjdXJyZW50Q3Vyc29yLmNhbmRpZGF0ZVxuICAgICAqL1xuICAgIGlmICh0aGlzLmNhbmRpZGF0ZSAhPT0gbnVsbCkge1xuICAgICAgY3Vyc29yLmNhbmRpZGF0ZSA9IGVsZW1lbnQuZmlyc3RDaGlsZDtcbiAgICAgIHRoaXMuY2FuZGlkYXRlID0gZWxlbWVudC5uZXh0U2libGluZztcbiAgICB9XG5cbiAgICB0aGlzW0NVUlNPUl9TVEFDS10ucHVzaChjdXJzb3IpO1xuICB9XG5cbiAgLy8gY2xlYXJzIHVudGlsIHRoZSBlbmQgb2YgdGhlIGN1cnJlbnQgY29udGFpbmVyXG4gIC8vIGVpdGhlciB0aGUgY3VycmVudCBvcGVuIGJsb2NrIG9yIGhpZ2hlclxuICBwcml2YXRlIGNsZWFyTWlzbWF0Y2goY2FuZGlkYXRlOiBTaW1wbGVOb2RlKSB7XG4gICAgbGV0IGN1cnJlbnQ6IE9wdGlvbjxTaW1wbGVOb2RlPiA9IGNhbmRpZGF0ZTtcbiAgICBsZXQgY3VycmVudEN1cnNvciA9IHRoaXMuY3VycmVudEN1cnNvcjtcbiAgICBpZiAoY3VycmVudEN1cnNvciAhPT0gbnVsbCkge1xuICAgICAgbGV0IG9wZW5CbG9ja0RlcHRoID0gY3VycmVudEN1cnNvci5vcGVuQmxvY2tEZXB0aDtcbiAgICAgIGlmIChvcGVuQmxvY2tEZXB0aCA+PSBjdXJyZW50Q3Vyc29yLnN0YXJ0aW5nQmxvY2tEZXB0aCkge1xuICAgICAgICB3aGlsZSAoY3VycmVudCkge1xuICAgICAgICAgIGlmIChpc0Nsb3NlQmxvY2soY3VycmVudCkpIHtcbiAgICAgICAgICAgIGxldCBjbG9zZUJsb2NrRGVwdGggPSBnZXRCbG9ja0RlcHRoV2l0aE9mZnNldChjdXJyZW50LCB0aGlzLnN0YXJ0aW5nQmxvY2tPZmZzZXQpO1xuICAgICAgICAgICAgaWYgKG9wZW5CbG9ja0RlcHRoID49IGNsb3NlQmxvY2tEZXB0aCkge1xuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgY3VycmVudCA9IHRoaXMucmVtb3ZlKGN1cnJlbnQpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB3aGlsZSAoY3VycmVudCAhPT0gbnVsbCkge1xuICAgICAgICAgIGN1cnJlbnQgPSB0aGlzLnJlbW92ZShjdXJyZW50KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgLy8gY3VycmVudCBjdXJzb3IgcGFyZW50Tm9kZSBzaG91bGQgYmUgb3BlbkNhbmRpZGF0ZSBpZiBlbGVtZW50XG4gICAgICAvLyBvciBvcGVuQ2FuZGlkYXRlLnBhcmVudE5vZGUgaWYgY29tbWVudFxuICAgICAgdGhpcy5kaXNhYmxlUmVoeWRyYXRpb24oY3VycmVudCk7XG4gICAgfVxuICB9XG5cbiAgX19vcGVuQmxvY2soKTogdm9pZCB7XG4gICAgbGV0IHsgY3VycmVudEN1cnNvciB9ID0gdGhpcztcbiAgICBpZiAoY3VycmVudEN1cnNvciA9PT0gbnVsbCkgcmV0dXJuO1xuXG4gICAgbGV0IGJsb2NrRGVwdGggPSB0aGlzLmJsb2NrRGVwdGg7XG5cbiAgICB0aGlzLmJsb2NrRGVwdGgrKztcblxuICAgIGxldCB7IGNhbmRpZGF0ZSB9ID0gY3VycmVudEN1cnNvcjtcbiAgICBpZiAoY2FuZGlkYXRlID09PSBudWxsKSByZXR1cm47XG5cbiAgICBsZXQgeyB0YWdOYW1lIH0gPSBjdXJyZW50Q3Vyc29yLmVsZW1lbnQ7XG5cbiAgICBpZiAoXG4gICAgICBpc09wZW5CbG9jayhjYW5kaWRhdGUpICYmXG4gICAgICBnZXRCbG9ja0RlcHRoV2l0aE9mZnNldChjYW5kaWRhdGUsIHRoaXMuc3RhcnRpbmdCbG9ja09mZnNldCkgPT09IGJsb2NrRGVwdGhcbiAgICApIHtcbiAgICAgIHRoaXMuY2FuZGlkYXRlID0gdGhpcy5yZW1vdmUoY2FuZGlkYXRlKTtcbiAgICAgIGN1cnJlbnRDdXJzb3Iub3BlbkJsb2NrRGVwdGggPSBibG9ja0RlcHRoO1xuICAgIH0gZWxzZSBpZiAodGFnTmFtZSAhPT0gJ1RJVExFJyAmJiB0YWdOYW1lICE9PSAnU0NSSVBUJyAmJiB0YWdOYW1lICE9PSAnU1RZTEUnKSB7XG4gICAgICB0aGlzLmNsZWFyTWlzbWF0Y2goY2FuZGlkYXRlKTtcbiAgICB9XG4gIH1cblxuICBfX2Nsb3NlQmxvY2soKTogdm9pZCB7XG4gICAgbGV0IHsgY3VycmVudEN1cnNvciB9ID0gdGhpcztcbiAgICBpZiAoY3VycmVudEN1cnNvciA9PT0gbnVsbCkgcmV0dXJuO1xuXG4gICAgLy8gb3BlbkJsb2NrIGlzIHRoZSBsYXN0IHJlaHlkcmF0ZWQgb3BlbiBibG9ja1xuICAgIGxldCBvcGVuQmxvY2tEZXB0aCA9IGN1cnJlbnRDdXJzb3Iub3BlbkJsb2NrRGVwdGg7XG5cbiAgICAvLyB0aGlzIGN1cnJlbnRseSBpcyB0aGUgZXhwZWN0ZWQgbmV4dCBvcGVuIGJsb2NrIGRlcHRoXG4gICAgdGhpcy5ibG9ja0RlcHRoLS07XG5cbiAgICBsZXQgeyBjYW5kaWRhdGUgfSA9IGN1cnJlbnRDdXJzb3I7XG5cbiAgICBsZXQgaXNSZWh5ZHJhdGluZyA9IGZhbHNlO1xuXG4gICAgaWYgKGNhbmRpZGF0ZSAhPT0gbnVsbCkge1xuICAgICAgaXNSZWh5ZHJhdGluZyA9IHRydWU7XG4gICAgICAvL2Fzc2VydChcbiAgICAgIC8vICBvcGVuQmxvY2tEZXB0aCA9PT0gdGhpcy5ibG9ja0RlcHRoLFxuICAgICAgLy8gICd3aGVuIHJlaHlkcmF0aW5nLCBvcGVuQmxvY2tEZXB0aCBzaG91bGQgbWF0Y2ggdGhpcy5ibG9ja0RlcHRoIGhlcmUnXG4gICAgICAvLyk7XG5cbiAgICAgIGlmIChcbiAgICAgICAgaXNDbG9zZUJsb2NrKGNhbmRpZGF0ZSkgJiZcbiAgICAgICAgZ2V0QmxvY2tEZXB0aFdpdGhPZmZzZXQoY2FuZGlkYXRlLCB0aGlzLnN0YXJ0aW5nQmxvY2tPZmZzZXQpID09PSBvcGVuQmxvY2tEZXB0aFxuICAgICAgKSB7XG4gICAgICAgIGxldCBuZXh0U2libGluZyA9IHRoaXMucmVtb3ZlKGNhbmRpZGF0ZSk7XG4gICAgICAgIHRoaXMuY2FuZGlkYXRlID0gbmV4dFNpYmxpbmc7XG4gICAgICAgIGN1cnJlbnRDdXJzb3Iub3BlbkJsb2NrRGVwdGgtLTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIGNsb3NlIHRoZSBibG9jayBhbmQgY2xlYXIgbWlzbWF0Y2ggaW4gcGFyZW50IGNvbnRhaW5lclxuICAgICAgICAvLyB3ZSB3aWxsIGJlIGVpdGhlciBhdCB0aGUgZW5kIG9mIHRoZSBlbGVtZW50XG4gICAgICAgIC8vIG9yIGF0IHRoZSBlbmQgb2Ygb3VyIGNvbnRhaW5pbmcgYmxvY2tcbiAgICAgICAgdGhpcy5jbGVhck1pc21hdGNoKGNhbmRpZGF0ZSk7XG4gICAgICAgIGlzUmVoeWRyYXRpbmcgPSBmYWxzZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoaXNSZWh5ZHJhdGluZyA9PT0gZmFsc2UpIHtcbiAgICAgIC8vIGNoZWNrIGlmIG5leHRTaWJsaW5nIG1hdGNoZXMgb3VyIGV4cGVjdGVkIGNsb3NlIGJsb2NrXG4gICAgICAvLyBpZiBzbywgd2UgcmVtb3ZlIHRoZSBjbG9zZSBibG9jayBjb21tZW50IGFuZFxuICAgICAgLy8gcmVzdG9yZSByZWh5ZHJhdGlvbiBhZnRlciBjbGVhck1pc21hdGNoIGRpc2FibGVkXG4gICAgICBsZXQgbmV4dFNpYmxpbmcgPSBjdXJyZW50Q3Vyc29yLm5leHRTaWJsaW5nO1xuICAgICAgaWYgKFxuICAgICAgICBuZXh0U2libGluZyAhPT0gbnVsbCAmJlxuICAgICAgICBpc0Nsb3NlQmxvY2sobmV4dFNpYmxpbmcpICYmXG4gICAgICAgIGdldEJsb2NrRGVwdGhXaXRoT2Zmc2V0KG5leHRTaWJsaW5nLCB0aGlzLnN0YXJ0aW5nQmxvY2tPZmZzZXQpID09PSB0aGlzLmJsb2NrRGVwdGhcbiAgICAgICkge1xuICAgICAgICAvLyByZXN0b3JlIHJlaHlkcmF0aW9uIHN0YXRlXG4gICAgICAgIGxldCBjYW5kaWRhdGUgPSB0aGlzLnJlbW92ZShuZXh0U2libGluZyk7XG4gICAgICAgIHRoaXMuZW5hYmxlUmVoeWRyYXRpb24oY2FuZGlkYXRlKTtcblxuICAgICAgICBjdXJyZW50Q3Vyc29yLm9wZW5CbG9ja0RlcHRoLS07XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgX19hcHBlbmROb2RlKG5vZGU6IFNpbXBsZU5vZGUpOiBTaW1wbGVOb2RlIHtcbiAgICBsZXQgeyBjYW5kaWRhdGUgfSA9IHRoaXM7XG5cbiAgICAvLyBUaGlzIGNvZGUgcGF0aCBpcyBvbmx5IHVzZWQgd2hlbiBpbnNlcnRpbmcgcHJlY2lzZWx5IG9uZSBub2RlLiBJdCBuZWVkcyBtb3JlXG4gICAgLy8gY29tcGFyaXNvbiBsb2dpYywgYnV0IHdlIGNhbiBwcm9iYWJseSBsZWFuIG9uIHRoZSBjYXNlcyB3aGVyZSB0aGlzIGNvZGUgcGF0aFxuICAgIC8vIGlzIGFjdHVhbGx5IHVzZWQuXG4gICAgaWYgKGNhbmRpZGF0ZSkge1xuICAgICAgcmV0dXJuIGNhbmRpZGF0ZTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHN1cGVyLl9fYXBwZW5kTm9kZShub2RlKTtcbiAgICB9XG4gIH1cblxuICBfX2FwcGVuZEhUTUwoaHRtbDogc3RyaW5nKTogQm91bmRzIHtcbiAgICBsZXQgY2FuZGlkYXRlQm91bmRzID0gdGhpcy5tYXJrZXJCb3VuZHMoKTtcblxuICAgIGlmIChjYW5kaWRhdGVCb3VuZHMpIHtcbiAgICAgIGxldCBmaXJzdCA9IGNhbmRpZGF0ZUJvdW5kcy5maXJzdE5vZGUoKSE7XG4gICAgICBsZXQgbGFzdCA9IGNhbmRpZGF0ZUJvdW5kcy5sYXN0Tm9kZSgpITtcblxuICAgICAgbGV0IG5ld0JvdW5kcyA9IG5ldyBDb25jcmV0ZUJvdW5kcyh0aGlzLmVsZW1lbnQsIGZpcnN0Lm5leHRTaWJsaW5nISwgbGFzdC5wcmV2aW91c1NpYmxpbmchKTtcblxuICAgICAgbGV0IHBvc3NpYmxlRW1wdHlNYXJrZXIgPSB0aGlzLnJlbW92ZShmaXJzdCk7XG4gICAgICB0aGlzLnJlbW92ZShsYXN0KTtcblxuICAgICAgaWYgKHBvc3NpYmxlRW1wdHlNYXJrZXIgIT09IG51bGwgJiYgaXNFbXB0eShwb3NzaWJsZUVtcHR5TWFya2VyKSkge1xuICAgICAgICB0aGlzLmNhbmRpZGF0ZSA9IHRoaXMucmVtb3ZlKHBvc3NpYmxlRW1wdHlNYXJrZXIpO1xuXG4gICAgICAgIGlmICh0aGlzLmNhbmRpZGF0ZSAhPT0gbnVsbCkge1xuICAgICAgICAgIHRoaXMuY2xlYXJNaXNtYXRjaCh0aGlzLmNhbmRpZGF0ZSk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgcmV0dXJuIG5ld0JvdW5kcztcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHN1cGVyLl9fYXBwZW5kSFRNTChodG1sKTtcbiAgICB9XG4gIH1cblxuICBwcm90ZWN0ZWQgcmVtb3ZlKG5vZGU6IFNpbXBsZU5vZGUpOiBPcHRpb248U2ltcGxlTm9kZT4ge1xuICAgIGxldCBlbGVtZW50ID0gZXhwZWN0KG5vZGUucGFyZW50Tm9kZSwgYGNhbm5vdCByZW1vdmUgYSBkZXRhY2hlZCBub2RlYCkgYXMgU2ltcGxlRWxlbWVudDtcbiAgICBsZXQgbmV4dCA9IG5vZGUubmV4dFNpYmxpbmc7XG4gICAgZWxlbWVudC5yZW1vdmVDaGlsZChub2RlKTtcbiAgICByZXR1cm4gbmV4dDtcbiAgfVxuXG4gIHByaXZhdGUgbWFya2VyQm91bmRzKCk6IE9wdGlvbjxCb3VuZHM+IHtcbiAgICBsZXQgX2NhbmRpZGF0ZSA9IHRoaXMuY2FuZGlkYXRlO1xuXG4gICAgaWYgKF9jYW5kaWRhdGUgJiYgaXNNYXJrZXIoX2NhbmRpZGF0ZSkpIHtcbiAgICAgIGxldCBmaXJzdCA9IF9jYW5kaWRhdGU7XG4gICAgICBsZXQgbGFzdCA9IGV4cGVjdChmaXJzdC5uZXh0U2libGluZywgYEJVRzogc2VyaWFsaXphdGlvbiBtYXJrZXJzIG11c3QgYmUgcGFpcmVkYCk7XG5cbiAgICAgIHdoaWxlIChsYXN0ICYmICFpc01hcmtlcihsYXN0KSkge1xuICAgICAgICBsYXN0ID0gZXhwZWN0KGxhc3QubmV4dFNpYmxpbmcsIGBCVUc6IHNlcmlhbGl6YXRpb24gbWFya2VycyBtdXN0IGJlIHBhaXJlZGApO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gbmV3IENvbmNyZXRlQm91bmRzKHRoaXMuZWxlbWVudCwgZmlyc3QsIGxhc3QpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gIH1cblxuICBfX2FwcGVuZFRleHQoc3RyaW5nOiBzdHJpbmcpOiBTaW1wbGVUZXh0IHtcbiAgICBsZXQgeyBjYW5kaWRhdGUgfSA9IHRoaXM7XG5cbiAgICBpZiAoY2FuZGlkYXRlKSB7XG4gICAgICBpZiAoaXNUZXh0Tm9kZShjYW5kaWRhdGUpKSB7XG4gICAgICAgIGlmIChjYW5kaWRhdGUubm9kZVZhbHVlICE9PSBzdHJpbmcpIHtcbiAgICAgICAgICBjYW5kaWRhdGUubm9kZVZhbHVlID0gc3RyaW5nO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuY2FuZGlkYXRlID0gY2FuZGlkYXRlLm5leHRTaWJsaW5nO1xuXG4gICAgICAgIHJldHVybiBjYW5kaWRhdGU7XG4gICAgICB9IGVsc2UgaWYgKGlzU2VwYXJhdG9yKGNhbmRpZGF0ZSkpIHtcbiAgICAgICAgdGhpcy5jYW5kaWRhdGUgPSB0aGlzLnJlbW92ZShjYW5kaWRhdGUpO1xuXG4gICAgICAgIHJldHVybiB0aGlzLl9fYXBwZW5kVGV4dChzdHJpbmcpO1xuICAgICAgfSBlbHNlIGlmIChpc0VtcHR5KGNhbmRpZGF0ZSkgJiYgc3RyaW5nID09PSAnJykge1xuICAgICAgICB0aGlzLmNhbmRpZGF0ZSA9IHRoaXMucmVtb3ZlKGNhbmRpZGF0ZSk7XG5cbiAgICAgICAgcmV0dXJuIHRoaXMuX19hcHBlbmRUZXh0KHN0cmluZyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLmNsZWFyTWlzbWF0Y2goY2FuZGlkYXRlKTtcblxuICAgICAgICByZXR1cm4gc3VwZXIuX19hcHBlbmRUZXh0KHN0cmluZyk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBzdXBlci5fX2FwcGVuZFRleHQoc3RyaW5nKTtcbiAgICB9XG4gIH1cblxuICBfX2FwcGVuZENvbW1lbnQoc3RyaW5nOiBzdHJpbmcpOiBTaW1wbGVDb21tZW50IHtcbiAgICBsZXQgX2NhbmRpZGF0ZSA9IHRoaXMuY2FuZGlkYXRlO1xuICAgIGlmIChfY2FuZGlkYXRlICYmIGlzQ29tbWVudChfY2FuZGlkYXRlKSkge1xuICAgICAgaWYgKF9jYW5kaWRhdGUubm9kZVZhbHVlICE9PSBzdHJpbmcpIHtcbiAgICAgICAgX2NhbmRpZGF0ZS5ub2RlVmFsdWUgPSBzdHJpbmc7XG4gICAgICB9XG5cbiAgICAgIHRoaXMuY2FuZGlkYXRlID0gX2NhbmRpZGF0ZS5uZXh0U2libGluZztcbiAgICAgIHJldHVybiBfY2FuZGlkYXRlO1xuICAgIH0gZWxzZSBpZiAoX2NhbmRpZGF0ZSkge1xuICAgICAgdGhpcy5jbGVhck1pc21hdGNoKF9jYW5kaWRhdGUpO1xuICAgIH1cblxuICAgIHJldHVybiBzdXBlci5fX2FwcGVuZENvbW1lbnQoc3RyaW5nKTtcbiAgfVxuXG4gIF9fb3BlbkVsZW1lbnQodGFnOiBzdHJpbmcpOiBTaW1wbGVFbGVtZW50IHtcbiAgICBsZXQgX2NhbmRpZGF0ZSA9IHRoaXMuY2FuZGlkYXRlO1xuXG4gICAgaWYgKF9jYW5kaWRhdGUgJiYgaXNFbGVtZW50KF9jYW5kaWRhdGUpICYmIGlzU2FtZU5vZGVUeXBlKF9jYW5kaWRhdGUsIHRhZykpIHtcbiAgICAgIHRoaXMudW5tYXRjaGVkQXR0cmlidXRlcyA9IFtdLnNsaWNlLmNhbGwoX2NhbmRpZGF0ZS5hdHRyaWJ1dGVzKTtcbiAgICAgIHJldHVybiBfY2FuZGlkYXRlO1xuICAgIH0gZWxzZSBpZiAoX2NhbmRpZGF0ZSkge1xuICAgICAgaWYgKGlzRWxlbWVudChfY2FuZGlkYXRlKSAmJiBfY2FuZGlkYXRlLnRhZ05hbWUgPT09ICdUQk9EWScpIHtcbiAgICAgICAgdGhpcy5wdXNoRWxlbWVudChfY2FuZGlkYXRlLCBudWxsKTtcbiAgICAgICAgdGhpcy5jdXJyZW50Q3Vyc29yIS5pbmplY3RlZE9taXR0ZWROb2RlID0gdHJ1ZTtcbiAgICAgICAgcmV0dXJuIHRoaXMuX19vcGVuRWxlbWVudCh0YWcpO1xuICAgICAgfVxuICAgICAgdGhpcy5jbGVhck1pc21hdGNoKF9jYW5kaWRhdGUpO1xuICAgIH1cblxuICAgIHJldHVybiBzdXBlci5fX29wZW5FbGVtZW50KHRhZyk7XG4gIH1cblxuICBfX3NldEF0dHJpYnV0ZShuYW1lOiBzdHJpbmcsIHZhbHVlOiBzdHJpbmcsIG5hbWVzcGFjZTogT3B0aW9uPEF0dHJOYW1lc3BhY2U+KTogdm9pZCB7XG4gICAgbGV0IHVubWF0Y2hlZCA9IHRoaXMudW5tYXRjaGVkQXR0cmlidXRlcztcblxuICAgIGlmICh1bm1hdGNoZWQpIHtcbiAgICAgIGxldCBhdHRyID0gZmluZEJ5TmFtZSh1bm1hdGNoZWQsIG5hbWUpO1xuICAgICAgaWYgKGF0dHIpIHtcbiAgICAgICAgaWYgKGF0dHIudmFsdWUgIT09IHZhbHVlKSB7XG4gICAgICAgICAgYXR0ci52YWx1ZSA9IHZhbHVlO1xuICAgICAgICB9XG4g