ember-legacy-class-transform
Version:
The default blueprint for ember-cli addons.
264 lines (224 loc) • 31.3 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.DOMTreeConstruction = exports.DOMChanges = exports.DOM = exports.DOMOperations = exports.BLACKLIST_TABLE = exports.SVG_NAMESPACE = exports.insertHTMLBefore = undefined;
exports.isWhitespace = isWhitespace;
exports.moveNodesBefore = moveNodesBefore;
var _bounds = require("../bounds");
var _innerHtmlFix = require("../compat/inner-html-fix");
var _svgInnerHtmlFix = require("../compat/svg-inner-html-fix");
var _textNodeMergingFix = require("../compat/text-node-merging-fix");
exports.insertHTMLBefore = _insertHTMLBefore;
function _defaults(obj, defaults) {
var keys = Object.getOwnPropertyNames(defaults);for (var i = 0; i < keys.length; i++) {
var key = keys[i];var value = Object.getOwnPropertyDescriptor(defaults, key);if (value && value.configurable && obj[key] === undefined) {
Object.defineProperty(obj, key, value);
}
}return obj;
}
function _possibleConstructorReturn(self, call) {
if (!self) {
throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
}return call && (typeof call === "object" || typeof call === "function") ? call : self;
}
function _inherits(subClass, superClass) {
if (typeof superClass !== "function" && superClass !== null) {
throw new TypeError("Super expression must either be null or a function, not " + typeof superClass);
}subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } });if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : _defaults(subClass, superClass);
}
function _classCallCheck(instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
}
var SVG_NAMESPACE = exports.SVG_NAMESPACE = 'http://www.w3.org/2000/svg';
// http://www.w3.org/TR/html/syntax.html#html-integration-point
var SVG_INTEGRATION_POINTS = { foreignObject: 1, desc: 1, title: 1 };
// http://www.w3.org/TR/html/syntax.html#adjust-svg-attributes
// TODO: Adjust SVG attributes
// http://www.w3.org/TR/html/syntax.html#parsing-main-inforeign
// TODO: Adjust SVG elements
// http://www.w3.org/TR/html/syntax.html#parsing-main-inforeign
var BLACKLIST_TABLE = exports.BLACKLIST_TABLE = Object.create(null);
["b", "big", "blockquote", "body", "br", "center", "code", "dd", "div", "dl", "dt", "em", "embed", "h1", "h2", "h3", "h4", "h5", "h6", "head", "hr", "i", "img", "li", "listing", "main", "meta", "nobr", "ol", "p", "pre", "ruby", "s", "small", "span", "strong", "strike", "sub", "sup", "table", "tt", "u", "ul", "var"].forEach(function (tag) {
return BLACKLIST_TABLE[tag] = 1;
});
var WHITESPACE = /[\t-\r \xA0\u1680\u180E\u2000-\u200A\u2028\u2029\u202F\u205F\u3000\uFEFF]/;
var doc = typeof document === 'undefined' ? null : document;
function isWhitespace(string) {
return WHITESPACE.test(string);
}
function moveNodesBefore(source, target, nextSibling) {
var first = source.firstChild;
var last = null;
var current = first;
while (current) {
last = current;
current = current.nextSibling;
target.insertBefore(last, nextSibling);
}
return [first, last];
}
var DOMOperations = exports.DOMOperations = function () {
function DOMOperations(document) {
_classCallCheck(this, DOMOperations);
this.document = document;
this.setupUselessElement();
}
// split into seperate method so that NodeDOMTreeConstruction
// can override it.
DOMOperations.prototype.setupUselessElement = function setupUselessElement() {
this.uselessElement = this.document.createElement('div');
};
DOMOperations.prototype.createElement = function createElement(tag, context) {
var isElementInSVGNamespace = void 0,
isHTMLIntegrationPoint = void 0;
if (context) {
isElementInSVGNamespace = context.namespaceURI === SVG_NAMESPACE || tag === 'svg';
isHTMLIntegrationPoint = SVG_INTEGRATION_POINTS[context.tagName];
} else {
isElementInSVGNamespace = tag === 'svg';
isHTMLIntegrationPoint = false;
}
if (isElementInSVGNamespace && !isHTMLIntegrationPoint) {
// FIXME: This does not properly handle <font> with color, face, or
// size attributes, which is also disallowed by the spec. We should fix
// this.
if (BLACKLIST_TABLE[tag]) {
throw new Error('Cannot create a ' + tag + ' inside an SVG context');
}
return this.document.createElementNS(SVG_NAMESPACE, tag);
} else {
return this.document.createElement(tag);
}
};
DOMOperations.prototype.insertBefore = function insertBefore(parent, node, reference) {
parent.insertBefore(node, reference);
};
DOMOperations.prototype.insertHTMLBefore = function insertHTMLBefore(_parent, nextSibling, html) {
return _insertHTMLBefore(this.uselessElement, _parent, nextSibling, html);
};
DOMOperations.prototype.createTextNode = function createTextNode(text) {
return this.document.createTextNode(text);
};
DOMOperations.prototype.createComment = function createComment(data) {
return this.document.createComment(data);
};
return DOMOperations;
}();
var DOM = exports.DOM = undefined;
(function (DOM) {
var TreeConstruction = function (_DOMOperations) {
_inherits(TreeConstruction, _DOMOperations);
function TreeConstruction() {
_classCallCheck(this, TreeConstruction);
return _possibleConstructorReturn(this, _DOMOperations.apply(this, arguments));
}
TreeConstruction.prototype.createElementNS = function createElementNS(namespace, tag) {
return this.document.createElementNS(namespace, tag);
};
TreeConstruction.prototype.setAttribute = function setAttribute(element, name, value, namespace) {
if (namespace) {
element.setAttributeNS(namespace, name, value);
} else {
element.setAttribute(name, value);
}
};
return TreeConstruction;
}(DOMOperations);
DOM.TreeConstruction = TreeConstruction;
var appliedTreeContruction = TreeConstruction;
appliedTreeContruction = (0, _textNodeMergingFix.treeConstruction)(doc, appliedTreeContruction);
appliedTreeContruction = (0, _innerHtmlFix.treeConstruction)(doc, appliedTreeContruction);
appliedTreeContruction = (0, _svgInnerHtmlFix.treeConstruction)(doc, appliedTreeContruction, SVG_NAMESPACE);
DOM.DOMTreeConstruction = appliedTreeContruction;
})(DOM || (exports.DOM = DOM = {}));
var DOMChanges = exports.DOMChanges = function (_DOMOperations2) {
_inherits(DOMChanges, _DOMOperations2);
function DOMChanges(document) {
_classCallCheck(this, DOMChanges);
var _this2 = _possibleConstructorReturn(this, _DOMOperations2.call(this, document));
_this2.document = document;
_this2.namespace = null;
return _this2;
}
DOMChanges.prototype.setAttribute = function setAttribute(element, name, value) {
element.setAttribute(name, value);
};
DOMChanges.prototype.setAttributeNS = function setAttributeNS(element, namespace, name, value) {
element.setAttributeNS(namespace, name, value);
};
DOMChanges.prototype.removeAttribute = function removeAttribute(element, name) {
element.removeAttribute(name);
};
DOMChanges.prototype.removeAttributeNS = function removeAttributeNS(element, namespace, name) {
element.removeAttributeNS(namespace, name);
};
DOMChanges.prototype.insertNodeBefore = function insertNodeBefore(parent, node, reference) {
if (isDocumentFragment(node)) {
var firstChild = node.firstChild,
lastChild = node.lastChild;
this.insertBefore(parent, node, reference);
return new _bounds.ConcreteBounds(parent, firstChild, lastChild);
} else {
this.insertBefore(parent, node, reference);
return new _bounds.SingleNodeBounds(parent, node);
}
};
DOMChanges.prototype.insertTextBefore = function insertTextBefore(parent, nextSibling, text) {
var textNode = this.createTextNode(text);
this.insertBefore(parent, textNode, nextSibling);
return textNode;
};
DOMChanges.prototype.insertBefore = function insertBefore(element, node, reference) {
element.insertBefore(node, reference);
};
DOMChanges.prototype.insertAfter = function insertAfter(element, node, reference) {
this.insertBefore(element, node, reference.nextSibling);
};
return DOMChanges;
}(DOMOperations);
function _insertHTMLBefore(_useless, _parent, _nextSibling, html) {
// TypeScript vendored an old version of the DOM spec where `insertAdjacentHTML`
// only exists on `HTMLElement` but not on `Element`. We actually work with the
// newer version of the DOM API here (and monkey-patch this method in `./compat`
// when we detect older browsers). This is a hack to work around this limitation.
var parent = _parent;
var useless = _useless;
var nextSibling = _nextSibling;
var prev = nextSibling ? nextSibling.previousSibling : parent.lastChild;
var last = void 0;
if (html === null || html === '') {
return new _bounds.ConcreteBounds(parent, null, null);
}
if (nextSibling === null) {
parent.insertAdjacentHTML('beforeend', html);
last = parent.lastChild;
} else if (nextSibling instanceof HTMLElement) {
nextSibling.insertAdjacentHTML('beforebegin', html);
last = nextSibling.previousSibling;
} else {
// Non-element nodes do not support insertAdjacentHTML, so add an
// element and call it on that element. Then remove the element.
//
// This also protects Edge, IE and Firefox w/o the inspector open
// from merging adjacent text nodes. See ./compat/text-node-merging-fix.ts
parent.insertBefore(useless, nextSibling);
useless.insertAdjacentHTML('beforebegin', html);
last = useless.previousSibling;
parent.removeChild(useless);
}
var first = prev ? prev.nextSibling : parent.firstChild;
return new _bounds.ConcreteBounds(parent, first, last);
}
function isDocumentFragment(node) {
return node.nodeType === Node.DOCUMENT_FRAGMENT_NODE;
}
var helper = DOMChanges;
helper = (0, _textNodeMergingFix.domChanges)(doc, helper);
helper = (0, _innerHtmlFix.domChanges)(doc, helper);
helper = (0, _svgInnerHtmlFix.domChanges)(doc, helper, SVG_NAMESPACE);
exports.default = helper;
var DOMTreeConstruction = exports.DOMTreeConstruction = DOM.DOMTreeConstruction;
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImxpYi9kb20vaGVscGVyLmpzIl0sIm5hbWVzIjpbIkNvbmNyZXRlQm91bmRzIiwiU2luZ2xlTm9kZUJvdW5kcyIsImRvbUNoYW5nZXMiLCJkb21DaGFuZ2VzVGFibGVFbGVtZW50Rml4IiwidHJlZUNvbnN0cnVjdGlvbiIsInRyZWVDb25zdHJ1Y3Rpb25UYWJsZUVsZW1lbnRGaXgiLCJkb21DaGFuZ2VzU3ZnRWxlbWVudEZpeCIsInRyZWVDb25zdHJ1Y3Rpb25TdmdFbGVtZW50Rml4IiwiZG9tQ2hhbmdlc05vZGVNZXJnaW5nRml4IiwidHJlZUNvbnN0cnVjdGlvbk5vZGVNZXJnaW5nRml4IiwiU1ZHX05BTUVTUEFDRSIsIlNWR19JTlRFR1JBVElPTl9QT0lOVFMiLCJmb3JlaWduT2JqZWN0IiwiZGVzYyIsInRpdGxlIiwiQkxBQ0tMSVNUX1RBQkxFIiwiT2JqZWN0IiwiY3JlYXRlIiwiZm9yRWFjaCIsInRhZyIsIldISVRFU1BBQ0UiLCJkb2MiLCJkb2N1bWVudCIsImlzV2hpdGVzcGFjZSIsInN0cmluZyIsInRlc3QiLCJtb3ZlTm9kZXNCZWZvcmUiLCJzb3VyY2UiLCJ0YXJnZXQiLCJuZXh0U2libGluZyIsImZpcnN0IiwiZmlyc3RDaGlsZCIsImxhc3QiLCJjdXJyZW50IiwiaW5zZXJ0QmVmb3JlIiwiRE9NT3BlcmF0aW9ucyIsInNldHVwVXNlbGVzc0VsZW1lbnQiLCJ1c2VsZXNzRWxlbWVudCIsImNyZWF0ZUVsZW1lbnQiLCJjb250ZXh0IiwiaXNFbGVtZW50SW5TVkdOYW1lc3BhY2UiLCJpc0hUTUxJbnRlZ3JhdGlvblBvaW50IiwibmFtZXNwYWNlVVJJIiwidGFnTmFtZSIsIkVycm9yIiwiY3JlYXRlRWxlbWVudE5TIiwicGFyZW50Iiwibm9kZSIsInJlZmVyZW5jZSIsImluc2VydEhUTUxCZWZvcmUiLCJfcGFyZW50IiwiaHRtbCIsImNyZWF0ZVRleHROb2RlIiwidGV4dCIsImNyZWF0ZUNvbW1lbnQiLCJkYXRhIiwiRE9NIiwiVHJlZUNvbnN0cnVjdGlvbiIsIm5hbWVzcGFjZSIsInNldEF0dHJpYnV0ZSIsImVsZW1lbnQiLCJuYW1lIiwidmFsdWUiLCJzZXRBdHRyaWJ1dGVOUyIsImFwcGxpZWRUcmVlQ29udHJ1Y3Rpb24iLCJET01UcmVlQ29uc3RydWN0aW9uIiwiRE9NQ2hhbmdlcyIsInJlbW92ZUF0dHJpYnV0ZSIsInJlbW92ZUF0dHJpYnV0ZU5TIiwiaW5zZXJ0Tm9kZUJlZm9yZSIsImlzRG9jdW1lbnRGcmFnbWVudCIsImxhc3RDaGlsZCIsImluc2VydFRleHRCZWZvcmUiLCJ0ZXh0Tm9kZSIsImluc2VydEFmdGVyIiwiX3VzZWxlc3MiLCJfbmV4dFNpYmxpbmciLCJ1c2VsZXNzIiwicHJldiIsInByZXZpb3VzU2libGluZyIsImluc2VydEFkamFjZW50SFRNTCIsIkhUTUxFbGVtZW50IiwicmVtb3ZlQ2hpbGQiLCJub2RlVHlwZSIsIk5vZGUiLCJET0NVTUVOVF9GUkFHTUVOVF9OT0RFIiwiaGVscGVyIl0sIm1hcHBpbmdzIjoiOzs7Ozs7UUFnQk8sQUFBUztRQUdULEFBQVM7O0FBbkJoQixBQUFTLEFBQWdCLEFBQXdCOztBQUNqRCxBQUFTLEFBQWMsQUFBMkIsQUFBb0IsQUFBdUM7O0FBQzdHLEFBQVMsQUFBYyxBQUF5QixBQUFvQixBQUFxQzs7QUFDekcsQUFBUyxBQUFjLEFBQTBCLEFBQW9CLEFBQXNDLEFBQzNHOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQU8sSUFBTSx3Q0FBTixBQUFzQjtBQUM3QjtBQUNBLElBQU0seUJBQXlCLEVBQUUsZUFBRixBQUFpQixHQUFHLE1BQXBCLEFBQTBCLEdBQUcsT0FBNUQsQUFBK0IsQUFBb0M7QUFDbkU7QUFDQTtBQUNBO0FBQ0E7QUFDQSxBQUNBO0FBQU8sSUFBTSw0Q0FBa0IsT0FBQSxBQUFPLE9BQS9CLEFBQXdCLEFBQWM7QUFDN0MsQ0FBQSxBQUFDLEtBQUQsQUFBTSxPQUFOLEFBQWEsY0FBYixBQUEyQixRQUEzQixBQUFtQyxNQUFuQyxBQUF5QyxVQUF6QyxBQUFtRCxR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LGdCQUFKLEFBQW9CLE1BQU0sQUFDdEI7ZUFBQSxBQUFPLG1CQUFQLEFBQTBCLGFBQTFCLEFBQXVDLEFBQ3ZDO2VBQU8sT0FBUCxBQUFjLEFBQ2pCO0FBSEQsZUFHVyx1QkFBSixBQUEyQixhQUFhLEFBQzNDO29CQUFBLEFBQVksbUJBQVosQUFBK0IsZUFBL0IsQUFBOEMsQUFDOUM7ZUFBTyxZQUFQLEFBQW1CLEFBQ3RCO0FBSE0sS0FBQSxNQUdBLEFBQ0g7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO2VBQUEsQUFBTyxhQUFQLEFBQW9CLFNBQXBCLEFBQTZCLEFBQzdCO2dCQUFBLEFBQVEsbUJBQVIsQUFBMkIsZUFBM0IsQUFBMEMsQUFDMUM7ZUFBTyxRQUFQLEFBQWUsQUFDZjtlQUFBLEFBQU8sWUFBUCxBQUFtQixBQUN0QjtBQUNEO1FBQUksUUFBUSxPQUFPLEtBQVAsQUFBWSxjQUFjLE9BQXRDLEFBQTZDLEFBQzdDO1dBQU8sQUFBSSwyQkFBSixBQUFtQixRQUFuQixBQUEyQixPQUFsQyxBQUFPLEFBQWtDLEFBQzVDOztBQUNELFNBQUEsQUFBUyxtQkFBVCxBQUE0QixNQUFNLEFBQzlCO1dBQU8sS0FBQSxBQUFLLGFBQWEsS0FBekIsQUFBOEIsQUFDakM7O0FBQ0QsSUFBSSxTQUFKLEFBQWE7QUFDYixTQUFTLG9DQUFBLEFBQXlCLEtBQWxDLEFBQVMsQUFBOEI7QUFDdkMsU0FBUyw4QkFBQSxBQUEwQixLQUFuQyxBQUFTLEFBQStCO0FBQ3hDLFNBQVMsaUNBQUEsQUFBd0IsS0FBeEIsQUFBNkIsUUFBdEMsQUFBUyxBQUFxQyxBQUM5QztrQkFBQSxBQUFlLEFBQ2Y7QUFBTyxJQUFNLG9EQUFzQixJQUE1QixBQUFnQyIsImZpbGUiOiJsaWIvZG9tL2hlbHBlci5qcyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbmNyZXRlQm91bmRzLCBTaW5nbGVOb2RlQm91bmRzIH0gZnJvbSAnLi4vYm91bmRzJztcbmltcG9ydCB7IGRvbUNoYW5nZXMgYXMgZG9tQ2hhbmdlc1RhYmxlRWxlbWVudEZpeCwgdHJlZUNvbnN0cnVjdGlvbiBhcyB0cmVlQ29uc3RydWN0aW9uVGFibGVFbGVtZW50Rml4IH0gZnJvbSAnLi4vY29tcGF0L2lubmVyLWh0bWwtZml4JztcbmltcG9ydCB7IGRvbUNoYW5nZXMgYXMgZG9tQ2hhbmdlc1N2Z0VsZW1lbnRGaXgsIHRyZWVDb25zdHJ1Y3Rpb24gYXMgdHJlZUNvbnN0cnVjdGlvblN2Z0VsZW1lbnRGaXggfSBmcm9tICcuLi9jb21wYXQvc3ZnLWlubmVyLWh0bWwtZml4JztcbmltcG9ydCB7IGRvbUNoYW5nZXMgYXMgZG9tQ2hhbmdlc05vZGVNZXJnaW5nRml4LCB0cmVlQ29uc3RydWN0aW9uIGFzIHRyZWVDb25zdHJ1Y3Rpb25Ob2RlTWVyZ2luZ0ZpeCB9IGZyb20gJy4uL2NvbXBhdC90ZXh0LW5vZGUtbWVyZ2luZy1maXgnO1xuZXhwb3J0IGNvbnN0IFNWR19OQU1FU1BBQ0UgPSAnaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnO1xuLy8gaHR0cDovL3d3dy53My5vcmcvVFIvaHRtbC9zeW50YXguaHRtbCNodG1sLWludGVncmF0aW9uLXBvaW50XG5jb25zdCBTVkdfSU5URUdSQVRJT05fUE9JTlRTID0geyBmb3JlaWduT2JqZWN0OiAxLCBkZXNjOiAxLCB0aXRsZTogMSB9O1xuLy8gaHR0cDovL3d3dy53My5vcmcvVFIvaHRtbC9zeW50YXguaHRtbCNhZGp1c3Qtc3ZnLWF0dHJpYnV0ZXNcbi8vIFRPRE86IEFkanVzdCBTVkcgYXR0cmlidXRlc1xuLy8gaHR0cDovL3d3dy53My5vcmcvVFIvaHRtbC9zeW50YXguaHRtbCNwYXJzaW5nLW1haW4taW5mb3JlaWduXG4vLyBUT0RPOiBBZGp1c3QgU1ZHIGVsZW1lbnRzXG4vLyBodHRwOi8vd3d3LnczLm9yZy9UUi9odG1sL3N5bnRheC5odG1sI3BhcnNpbmctbWFpbi1pbmZvcmVpZ25cbmV4cG9ydCBjb25zdCBCTEFDS0xJU1RfVEFCTEUgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuW1wiYlwiLCBcImJpZ1wiLCBcImJsb2NrcXVvdGVcIiwgXCJib2R5XCIsIFwiYnJcIiwgXCJjZW50ZXJcIiwgXCJjb2RlXCIsIFwiZGRcIiwgXCJkaXZcIiwgXCJkbFwiLCBcImR0XCIsIFwiZW1cIiwgXCJlbWJlZFwiLCBcImgxXCIsIFwiaDJcIiwgXCJoM1wiLCBcImg0XCIsIFwiaDVcIiwgXCJoNlwiLCBcImhlYWRcIiwgXCJoclwiLCBcImlcIiwgXCJpbWdcIiwgXCJsaVwiLCBcImxpc3RpbmdcIiwgXCJtYWluXCIsIFwibWV0YVwiLCBcIm5vYnJcIiwgXCJvbFwiLCBcInBcIiwgXCJwcmVcIiwgXCJydWJ5XCIsIFwic1wiLCBcInNtYWxsXCIsIFwic3BhblwiLCBcInN0cm9uZ1wiLCBcInN0cmlrZVwiLCBcInN1YlwiLCBcInN1cFwiLCBcInRhYmxlXCIsIFwidHRcIiwgXCJ1XCIsIFwidWxcIiwgXCJ2YXJcIl0uZm9yRWFjaCh0YWcgPT4gQkxBQ0tMSVNUX1RBQkxFW3RhZ10gPSAxKTtcbmNvbnN0IFdISVRFU1BBQ0UgPSAvW1xcdC1cXHIgXFx4QTBcXHUxNjgwXFx1MTgwRVxcdTIwMDAtXFx1MjAwQVxcdTIwMjhcXHUyMDI5XFx1MjAyRlxcdTIwNUZcXHUzMDAwXFx1RkVGRl0vO1xubGV0IGRvYyA9IHR5cGVvZiBkb2N1bWVudCA9PT0gJ3VuZGVmaW5lZCcgPyBudWxsIDogZG9jdW1lbnQ7XG5leHBvcnQgZnVuY3Rpb24gaXNXaGl0ZXNwYWNlKHN0cmluZykge1xuICAgIHJldHVybiBXSElURVNQQUNFLnRlc3Qoc3RyaW5nKTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBtb3ZlTm9kZXNCZWZvcmUoc291cmNlLCB0YXJnZXQsIG5leHRTaWJsaW5nKSB7XG4gICAgbGV0IGZpcnN0ID0gc291cmNlLmZpcnN0Q2hpbGQ7XG4gICAgbGV0IGxhc3QgPSBudWxsO1xuICAgIGxldCBjdXJyZW50ID0gZmlyc3Q7XG4gICAgd2hpbGUgKGN1cnJlbnQpIHtcbiAgICAgICAgbGFzdCA9IGN1cnJlbnQ7XG4gICAgICAgIGN1cnJlbnQgPSBjdXJyZW50Lm5leHRTaWJsaW5nO1xuICAgICAgICB0YXJnZXQuaW5zZXJ0QmVmb3JlKGxhc3QsIG5leHRTaWJsaW5nKTtcbiAgICB9XG4gICAgcmV0dXJuIFtmaXJzdCwgbGFzdF07XG59XG5leHBvcnQgY2xhc3MgRE9NT3BlcmF0aW9ucyB7XG4gICAgY29uc3RydWN0b3IoZG9jdW1lbnQpIHtcbiAgICAgICAgdGhpcy5kb2N1bWVudCA9IGRvY3VtZW50O1xuICAgICAgICB0aGlzLnNldHVwVXNlbGVzc0VsZW1lbnQoKTtcbiAgICB9XG4gICAgLy8gc3BsaXQgaW50byBzZXBlcmF0ZSBtZXRob2Qgc28gdGhhdCBOb2RlRE9NVHJlZUNvbnN0cnVjdGlvblxuICAgIC8vIGNhbiBvdmVycmlkZSBpdC5cbiAgICBzZXR1cFVzZWxlc3NFbGVtZW50KCkge1xuICAgICAgICB0aGlzLnVzZWxlc3NFbGVtZW50ID0gdGhpcy5kb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICB9XG4gICAgY3JlYXRlRWxlbWVudCh0YWcsIGNvbnRleHQpIHtcbiAgICAgICAgbGV0IGlzRWxlbWVudEluU1ZHTmFtZXNwYWNlLCBpc0hUTUxJbnRlZ3JhdGlvblBvaW50O1xuICAgICAgICBpZiAoY29udGV4dCkge1xuICAgICAgICAgICAgaXNFbGVtZW50SW5TVkdOYW1lc3BhY2UgPSBjb250ZXh0Lm5hbWVzcGFjZVVSSSA9PT0gU1ZHX05BTUVTUEFDRSB8fCB0YWcgPT09ICdzdmcnO1xuICAgICAgICAgICAgaXNIVE1MSW50ZWdyYXRpb25Qb2ludCA9IFNWR19JTlRFR1JBVElPTl9QT0lOVFNbY29udGV4dC50YWdOYW1lXTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGlzRWxlbWVudEluU1ZHTmFtZXNwYWNlID0gdGFnID09PSAnc3ZnJztcbiAgICAgICAgICAgIGlzSFRNTEludGVncmF0aW9uUG9pbnQgPSBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoaXNFbGVtZW50SW5TVkdOYW1lc3BhY2UgJiYgIWlzSFRNTEludGVncmF0aW9uUG9pbnQpIHtcbiAgICAgICAgICAgIC8vIEZJWE1FOiBUaGlzIGRvZXMgbm90IHByb3Blcmx5IGhhbmRsZSA8Zm9udD4gd2l0aCBjb2xvciwgZmFjZSwgb3JcbiAgICAgICAgICAgIC8vIHNpemUgYXR0cmlidXRlcywgd2hpY2ggaXMgYWxzbyBkaXNhbGxvd2VkIGJ5IHRoZSBzcGVjLiBXZSBzaG91bGQgZml4XG4gICAgICAgICAgICAvLyB0aGlzLlxuICAgICAgICAgICAgaWYgKEJMQUNLTElTVF9UQUJMRVt0YWddKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBDYW5ub3QgY3JlYXRlIGEgJHt0YWd9IGluc2lkZSBhbiBTVkcgY29udGV4dGApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuZG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TKFNWR19OQU1FU1BBQ0UsIHRhZyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5kb2N1bWVudC5jcmVhdGVFbGVtZW50KHRhZyk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgaW5zZXJ0QmVmb3JlKHBhcmVudCwgbm9kZSwgcmVmZXJlbmNlKSB7XG4gICAgICAgIHBhcmVudC5pbnNlcnRCZWZvcmUobm9kZSwgcmVmZXJlbmNlKTtcbiAgICB9XG4gICAgaW5zZXJ0SFRNTEJlZm9yZShfcGFyZW50LCBuZXh0U2libGluZywgaHRtbCkge1xuICAgICAgICByZXR1cm4gaW5zZXJ0SFRNTEJlZm9yZSh0aGlzLnVzZWxlc3NFbGVtZW50LCBfcGFyZW50LCBuZXh0U2libGluZywgaHRtbCk7XG4gICAgfVxuICAgIGNyZWF0ZVRleHROb2RlKHRleHQpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUodGV4dCk7XG4gICAgfVxuICAgIGNyZWF0ZUNvbW1lbnQoZGF0YSkge1xuICAgICAgICByZXR1cm4gdGhpcy5kb2N1bWVudC5jcmVhdGVDb21tZW50KGRhdGEpO1xuICAgIH1cbn1cbmV4cG9ydCB2YXIgRE9NO1xuKGZ1bmN0aW9uIChET00pIHtcbiAgICBjbGFzcyBUcmVlQ29uc3RydWN0aW9uIGV4dGVuZHMgRE9NT3BlcmF0aW9ucyB7XG4gICAgICAgIGNyZWF0ZUVsZW1lbnROUyhuYW1lc3BhY2UsIHRhZykge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuZG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TKG5hbWVzcGFjZSwgdGFnKTtcbiAgICAgICAgfVxuICAgICAgICBzZXRBdHRyaWJ1dGUoZWxlbWVudCwgbmFtZSwgdmFsdWUsIG5hbWVzcGFjZSkge1xuICAgICAgICAgICAgaWYgKG5hbWVzcGFjZSkge1xuICAgICAgICAgICAgICAgIGVsZW1lbnQuc2V0QXR0cmlidXRlTlMobmFtZXNwYWNlLCBuYW1lLCB2YWx1ZSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGVsZW1lbnQuc2V0QXR0cmlidXRlKG5hbWUsIHZhbHVlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICBET00uVHJlZUNvbnN0cnVjdGlvbiA9IFRyZWVDb25zdHJ1Y3Rpb247XG4gICAgbGV0IGFwcGxpZWRUcmVlQ29udHJ1Y3Rpb24gPSBUcmVlQ29uc3RydWN0aW9uO1xuICAgIGFwcGxpZWRUcmVlQ29udHJ1Y3Rpb24gPSB0cmVlQ29uc3RydWN0aW9uTm9kZU1lcmdpbmdGaXgoZG9jLCBhcHBsaWVkVHJlZUNvbnRydWN0aW9uKTtcbiAgICBhcHBsaWVkVHJlZUNvbnRydWN0aW9uID0gdHJlZUNvbnN0cnVjdGlvblRhYmxlRWxlbWVudEZpeChkb2MsIGFwcGxpZWRUcmVlQ29udHJ1Y3Rpb24pO1xuICAgIGFwcGxpZWRUcmVlQ29udHJ1Y3Rpb24gPSB0cmVlQ29uc3RydWN0aW9uU3ZnRWxlbWVudEZpeChkb2MsIGFwcGxpZWRUcmVlQ29udHJ1Y3Rpb24sIFNWR19OQU1FU1BBQ0UpO1xuICAgIERPTS5ET01UcmVlQ29uc3RydWN0aW9uID0gYXBwbGllZFRyZWVDb250cnVjdGlvbjtcbn0pKERPTSB8fCAoRE9NID0ge30pKTtcbmV4cG9ydCBjbGFzcyBET01DaGFuZ2VzIGV4dGVuZHMgRE9NT3BlcmF0aW9ucyB7XG4gICAgY29uc3RydWN0b3IoZG9jdW1lbnQpIHtcbiAgICAgICAgc3VwZXIoZG9jdW1lbnQpO1xuICAgICAgICB0aGlzLmRvY3VtZW50ID0gZG9jdW1lbnQ7XG4gICAgICAgIHRoaXMubmFtZXNwYWNlID0gbnVsbDtcbiAgICB9XG4gICAgc2V0QXR0cmlidXRlKGVsZW1lbnQsIG5hbWUsIHZhbHVlKSB7XG4gICAgICAgIGVsZW1lbnQuc2V0QXR0cmlidXRlKG5hbWUsIHZhbHVlKTtcbiAgICB9XG4gICAgc2V0QXR0cmlidXRlTlMoZWxlbWVudCwgbmFtZXNwYWNlLCBuYW1lLCB2YWx1ZSkge1xuICAgICAgICBlbGVtZW50LnNldEF0dHJpYnV0ZU5TKG5hbWVzcGFjZSwgbmFtZSwgdmFsdWUpO1xuICAgIH1cbiAgICByZW1vdmVBdHRyaWJ1dGUoZWxlbWVudCwgbmFtZSkge1xuICAgICAgICBlbGVtZW50LnJlbW92ZUF0dHJpYnV0ZShuYW1lKTtcbiAgICB9XG4gICAgcmVtb3ZlQXR0cmlidXRlTlMoZWxlbWVudCwgbmFtZXNwYWNlLCBuYW1lKSB7XG4gICAgICAgIGVsZW1lbnQucmVtb3ZlQXR0cmlidXRlTlMobmFtZXNwYWNlLCBuYW1lKTtcbiAgICB9XG4gICAgaW5zZXJ0Tm9kZUJlZm9yZShwYXJlbnQsIG5vZGUsIHJlZmVyZW5jZSkge1xuICAgICAgICBpZiAoaXNEb2N1bWVudEZyYWdtZW50KG5vZGUpKSB7XG4gICAgICAgICAgICBsZXQgeyBmaXJzdENoaWxkLCBsYXN0Q2hpbGQgfSA9IG5vZGU7XG4gICAgICAgICAgICB0aGlzLmluc2VydEJlZm9yZShwYXJlbnQsIG5vZGUsIHJlZmVyZW5jZSk7XG4gICAgICAgICAgICByZXR1cm4gbmV3IENvbmNyZXRlQm91bmRzKHBhcmVudCwgZmlyc3RDaGlsZCwgbGFzdENoaWxkKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuaW5zZXJ0QmVmb3JlKHBhcmVudCwgbm9kZSwgcmVmZXJlbmNlKTtcbiAgICAgICAgICAgIHJldHVybiBuZXcgU2luZ2xlTm9kZUJvdW5kcyhwYXJlbnQsIG5vZGUpO1xuICAgICAgICB9XG4gICAgfVxuICAgIGluc2VydFRleHRCZWZvcmUocGFyZW50LCBuZXh0U2libGluZywgdGV4dCkge1xuICAgICAgICBsZXQgdGV4dE5vZGUgPSB0aGlzLmNyZWF0ZVRleHROb2RlKHRleHQpO1xuICAgICAgICB0aGlzLmluc2VydEJlZm9yZShwYXJlbnQsIHRleHROb2RlLCBuZXh0U2libGluZyk7XG4gICAgICAgIHJldHVybiB0ZXh0Tm9kZTtcbiAgICB9XG4gICAgaW5zZXJ0QmVmb3JlKGVsZW1lbnQsIG5vZGUsIHJlZmVyZW5jZSkge1xuICAgICAgICBlbGVtZW50Lmluc2VydEJlZm9yZShub2RlLCByZWZlcmVuY2UpO1xuICAgIH1cbiAgICBpbnNlcnRBZnRlcihlbGVtZW50LCBub2RlLCByZWZlcmVuY2UpIHtcbiAgICAgICAgdGhpcy5pbnNlcnRCZWZvcmUoZWxlbWVudCwgbm9kZSwgcmVmZXJlbmNlLm5leHRTaWJsaW5nKTtcbiAgICB9XG59XG5leHBvcnQgZnVuY3Rpb24gaW5zZXJ0SFRNTEJlZm9yZShfdXNlbGVzcywgX3BhcmVudCwgX25leHRTaWJsaW5nLCBodG1sKSB7XG4gICAgLy8gVHlwZVNjcmlwdCB2ZW5kb3JlZCBhbiBvbGQgdmVyc2lvbiBvZiB0aGUgRE9NIHNwZWMgd2hlcmUgYGluc2VydEFkamFjZW50SFRNTGBcbiAgICAvLyBvbmx5IGV4aXN0cyBvbiBgSFRNTEVsZW1lbnRgIGJ1dCBub3Qgb24gYEVsZW1lbnRgLiBXZSBhY3R1YWxseSB3b3JrIHdpdGggdGhlXG4gICAgLy8gbmV3ZXIgdmVyc2lvbiBvZiB0aGUgRE9NIEFQSSBoZXJlIChhbmQgbW9ua2V5LXBhdGNoIHRoaXMgbWV0aG9kIGluIGAuL2NvbXBhdGBcbiAgICAvLyB3aGVuIHdlIGRldGVjdCBvbGRlciBicm93c2VycykuIFRoaXMgaXMgYSBoYWNrIHRvIHdvcmsgYXJvdW5kIHRoaXMgbGltaXRhdGlvbi5cbiAgICBsZXQgcGFyZW50ID0gX3BhcmVudDtcbiAgICBsZXQgdXNlbGVzcyA9IF91c2VsZXNzO1xuICAgIGxldCBuZXh0U2libGluZyA9IF9uZXh0U2libGluZztcbiAgICBsZXQgcHJldiA9IG5leHRTaWJsaW5nID8gbmV4dFNpYmxpbmcucHJldmlvdXNTaWJsaW5nIDogcGFyZW50Lmxhc3RDaGlsZDtcbiAgICBsZXQgbGFzdDtcbiAgICBpZiAoaHRtbCA9PT0gbnVsbCB8fCBodG1sID09PSAnJykge1xuICAgICAgICByZXR1cm4gbmV3IENvbmNyZXRlQm91bmRzKHBhcmVudCwgbnVsbCwgbnVsbCk7XG4gICAgfVxuICAgIGlmIChuZXh0U2libGluZyA9PT0gbnVsbCkge1xuICAgICAgICBwYXJlbnQuaW5zZXJ0QWRqYWNlbnRIVE1MKCdiZWZvcmVlbmQnLCBodG1sKTtcbiAgICAgICAgbGFzdCA9IHBhcmVudC5sYXN0Q2hpbGQ7XG4gICAgfSBlbHNlIGlmIChuZXh0U2libGluZyBpbnN0YW5jZW9mIEhUTUxFbGVtZW50KSB7XG4gICAgICAgIG5leHRTaWJsaW5nLmluc2VydEFkamFjZW50SFRNTCgnYmVmb3JlYmVnaW4nLCBodG1sKTtcbiAgICAgICAgbGFzdCA9IG5leHRTaWJsaW5nLnByZXZpb3VzU2libGluZztcbiAgICB9IGVsc2Uge1xuICAgICAgICAvLyBOb24tZWxlbWVudCBub2RlcyBkbyBub3Qgc3VwcG9ydCBpbnNlcnRBZGphY2VudEhUTUwsIHNvIGFkZCBhblxuICAgICAgICAvLyBlbGVtZW50IGFuZCBjYWxsIGl0IG9uIHRoYXQgZWxlbWVudC4gVGhlbiByZW1vdmUgdGhlIGVsZW1lbnQuXG4gICAgICAgIC8vXG4gICAgICAgIC8vIFRoaXMgYWxzbyBwcm90ZWN0cyBFZGdlLCBJRSBhbmQgRmlyZWZveCB3L28gdGhlIGluc3BlY3RvciBvcGVuXG4gICAgICAgIC8vIGZyb20gbWVyZ2luZyBhZGphY2VudCB0ZXh0IG5vZGVzLiBTZWUgLi9jb21wYXQvdGV4dC1ub2RlLW1lcmdpbmctZml4LnRzXG4gICAgICAgIHBhcmVudC5pbnNlcnRCZWZvcmUodXNlbGVzcywgbmV4dFNpYmxpbmcpO1xuICAgICAgICB1c2VsZXNzLmluc2VydEFkamFjZW50SFRNTCgnYmVmb3JlYmVnaW4nLCBodG1sKTtcbiAgICAgICAgbGFzdCA9IHVzZWxlc3MucHJldmlvdXNTaWJsaW5nO1xuICAgICAgICBwYXJlbnQucmVtb3ZlQ2hpbGQodXNlbGVzcyk7XG4gICAgfVxuICAgIGxldCBmaXJzdCA9IHByZXYgPyBwcmV2Lm5leHRTaWJsaW5nIDogcGFyZW50LmZpcnN0Q2hpbGQ7XG4gICAgcmV0dXJuIG5ldyBDb25jcmV0ZUJvdW5kcyhwYXJlbnQsIGZpcnN0LCBsYXN0KTtcbn1cbmZ1bmN0aW9uIGlzRG9jdW1lbnRGcmFnbWVudChub2RlKSB7XG4gICAgcmV0dXJuIG5vZGUubm9kZVR5cGUgPT09IE5vZGUuRE9DVU1FTlRfRlJBR01FTlRfTk9ERTtcbn1cbmxldCBoZWxwZXIgPSBET01DaGFuZ2VzO1xuaGVscGVyID0gZG9tQ2hhbmdlc05vZGVNZXJnaW5nRml4KGRvYywgaGVscGVyKTtcbmhlbHBlciA9IGRvbUNoYW5nZXNUYWJsZUVsZW1lbnRGaXgoZG9jLCBoZWxwZXIpO1xuaGVscGVyID0gZG9tQ2hhbmdlc1N2Z0VsZW1lbnRGaXgoZG9jLCBoZWxwZXIsIFNWR19OQU1FU1BBQ0UpO1xuZXhwb3J0IGRlZmF1bHQgaGVscGVyO1xuZXhwb3J0IGNvbnN0IERPTVRyZWVDb25zdHJ1Y3Rpb24gPSBET00uRE9NVHJlZUNvbnN0cnVjdGlvbjsiXX0=