@desertnet/html-parser
Version:
HTML parser and non-strict validator
266 lines (210 loc) • 15.7 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.NodeError = exports.NodeType = undefined;
var _createClass = function () { 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var _HTMLParseError = require("../HTMLParseError");
var _HTMLParseError2 = _interopRequireDefault(_HTMLParseError);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: 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) : subClass.__proto__ = superClass; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
/**
* HTML node types.
* @enum {string}
*/
var NodeType = exports.NodeType = {
ROOT: "ROOT",
TAG: "TAG",
ATTRIBUTE: "ATTRIBUTE",
TEXT: "TEXT",
ENTITY: "ENTITY",
COMMENT: "COMMENT",
CLOSETAG: "CLOSETAG"
};
/**
* HTML tree nodes base class. Should never be called outside of
* subclass constructors!
*/
var HTMLNode = function () {
function HTMLNode() {
_classCallCheck(this, HTMLNode);
/**
* @private
* @type {Array.<Foundation.HTML.Parser.HTMLNode>?}
*/
this._children = null;
/**
* @private
* @type {Array.<Foundation.Scanner.Token>}
*/
this._sourceTokens = [];
/**
* @private
* @type {Array.<HTMLParseError>?}
*/
this._errors = null;
}
/**
* Subclasses must override this.
* @return {boolean}
*/
_createClass(HTMLNode, [{
key: "toString",
/**
* Subclasses must override this.
* @return {string}
*/
value: function toString() {
throw new NodeError("toString not overriden in subclass", this);
}
/**
* @return {NodeType}
*/
}, {
key: "addToken",
/**
* @param {Foundation.Scanner.Token} token
*/
value: function addToken(token) {
this._sourceTokens.push(token);
// Create error objects when adding a token of type error.
if (token.type === "error") {
var error = new _HTMLParseError2.default();
error.message = "Invalid token: \"" + token.value + "\"";
error.addToken(token);
this.addError(error);
}
}
/**
* @return {Array.<Foundation.Scanner.Token>}
*/
}, {
key: "appendChild",
/**
* @param {Foundation.HTML.Parser.HTMLNode} childNode
* @return {Foundation.HTML.Parser.HTMLNode}
*/
value: function appendChild(childNode) {
if (!this.canHaveChildren) {
throw new NodeError("attempted to call appendChild on node that can't have children", this);
}
if (!this._children) {
this._children = [];
}
this._children.push(childNode);
return this;
}
/**
* @public
* @return {Array.<HTMLParseError>}
*/
}, {
key: "addError",
/**
* @param {HTMLParseError} error
*/
value: function addError(error) {
if (this._errors === null) {
this._errors = [];
}
this._errors.push(error);
}
/**
* @private
* @return {Array.<HTMLParseError>}
*/
}, {
key: "canHaveChildren",
get: function get() {
throw new NodeError("canHaveChildren not overriden in subclass", this);
}
}, {
key: "type",
get: function get() {
throw new NodeError("type getter not overriden in subclass", this);
}
/**
* @return {Array.<Foundation.HTML.Parser.HTMLNode>?}
*/
}, {
key: "children",
get: function get() {
if (this._children === null || this._children.length === 0) {
return null;
}
return this._children.slice(0);
}
/**
* @return {Foundation.HTML.Parser.HTMLNode}
*/
}, {
key: "lastChild",
get: function get() {
var children = this.children;
if (children === null || children.length === 0) {
return null;
}
return children[children.length - 1];
}
}, {
key: "tokens",
get: function get() {
return this._sourceTokens.slice(0);
}
/**
* @return {Array.<number>?}
*/
}, {
key: "indexRange",
get: function get() {
var tokens = this.tokens;
if (tokens.length === 0) {
return null;
}
var firstToken = tokens[0];
var lastToken = tokens[tokens.length - 1];
return [firstToken.index, lastToken.index + lastToken.value.length - 1];
}
}, {
key: "errors",
get: function get() {
if (this.canHaveChildren && this.children) {
return this.children.reduce(function (accumulator, child) {
return accumulator.concat(child.errors);
}, this.ownErrors);
}
return this.ownErrors;
}
}, {
key: "ownErrors",
get: function get() {
return this._errors === null ? [] : this._errors.slice(0);
}
}]);
return HTMLNode;
}();
/**
* HTML node error class. This is a throwable Error object, not to be
* confused with the HTMLParseError class which deals
* with reporting errors found in the HTML source.
*/
exports.default = HTMLNode;
var NodeError = exports.NodeError = function (_Error) {
_inherits(NodeError, _Error);
/**
* @param {string} message
* @param {Foundation.HTML.Parser.HTMLNode} node
*/
function NodeError(message, node) {
_classCallCheck(this, NodeError);
var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(NodeError).call(this, message));
_this.name = "HTMLParserNodeError";
_this.node = node;
return _this;
}
return NodeError;
}(Error);
;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL2xpYi9IVE1MTm9kZS9IVE1MTm9kZS5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7QUFBQTs7Ozs7Ozs7Ozs7O0FBRUE7Ozs7QUFJTyxJQUFNLDhCQUFXO0FBQ3RCLFFBQU0sTUFEZ0I7QUFFdEIsT0FBTSxLQUZnQjtBQUd0QixhQUFXLFdBSFc7QUFJdEIsUUFBTSxNQUpnQjtBQUt0QixVQUFTLFFBTGE7QUFNdEIsV0FBUyxTQU5hO0FBT3RCLFlBQVU7QUFQWSxDQUFqQjs7QUFVUDs7Ozs7SUFJcUIsUTtBQUNuQixzQkFBZTtBQUFBOztBQUNiOzs7O0FBSUEsU0FBSyxTQUFMLEdBQWlCLElBQWpCOztBQUVBOzs7O0FBSUEsU0FBSyxhQUFMLEdBQXFCLEVBQXJCOztBQUVBOzs7O0FBSUEsU0FBSyxPQUFMLEdBQWUsSUFBZjtBQUNEOztBQUVEOzs7Ozs7Ozs7O0FBUUE7Ozs7K0JBSVk7QUFDVixZQUFNLElBQUksU0FBSixDQUFjLG9DQUFkLEVBQW9ELElBQXBELENBQU47QUFDRDs7QUFFRDs7Ozs7Ozs7QUE2QkE7Ozs2QkFHVSxLLEVBQU87QUFDZixXQUFLLGFBQUwsQ0FBbUIsSUFBbkIsQ0FBd0IsS0FBeEI7O0FBRUE7QUFDQSxVQUFJLE1BQU0sSUFBTixLQUFlLE9BQW5CLEVBQTRCO0FBQzFCLFlBQUksUUFBUSw4QkFBWjtBQUNBLGNBQU0sT0FBTixHQUFnQixzQkFBc0IsTUFBTSxLQUE1QixHQUFvQyxJQUFwRDtBQUNBLGNBQU0sUUFBTixDQUFlLEtBQWY7QUFDQSxhQUFLLFFBQUwsQ0FBYyxLQUFkO0FBQ0Q7QUFDRjs7QUFFRDs7Ozs7Ozs7QUF3QkE7Ozs7Z0NBSWEsUyxFQUFXO0FBQ3RCLFVBQUksQ0FBRSxLQUFLLGVBQVgsRUFBNEI7QUFDMUIsY0FBTSxJQUFJLFNBQUosQ0FDSixnRUFESSxFQUM4RCxJQUQ5RCxDQUFOO0FBR0Q7O0FBRUQsVUFBSSxDQUFFLEtBQUssU0FBWCxFQUFzQjtBQUNwQixhQUFLLFNBQUwsR0FBaUIsRUFBakI7QUFDRDs7QUFFRCxXQUFLLFNBQUwsQ0FBZSxJQUFmLENBQW9CLFNBQXBCOztBQUVBLGFBQU8sSUFBUDtBQUNEOztBQUVEOzs7Ozs7Ozs7QUFjQTs7OzZCQUdVLEssRUFBTztBQUNmLFVBQUksS0FBSyxPQUFMLEtBQWlCLElBQXJCLEVBQTJCO0FBQ3pCLGFBQUssT0FBTCxHQUFlLEVBQWY7QUFDRDtBQUNELFdBQUssT0FBTCxDQUFhLElBQWIsQ0FBa0IsS0FBbEI7QUFDRDs7QUFFRDs7Ozs7Ozt3QkE1SHVCO0FBQ3JCLFlBQU0sSUFBSSxTQUFKLENBQWMsMkNBQWQsRUFBMkQsSUFBM0QsQ0FBTjtBQUNEOzs7d0JBYVc7QUFDVixZQUFNLElBQUksU0FBSixDQUFjLHVDQUFkLEVBQXVELElBQXZELENBQU47QUFDRDs7QUFFRDs7Ozs7O3dCQUdnQjtBQUNkLFVBQUksS0FBSyxTQUFMLEtBQW1CLElBQW5CLElBQTJCLEtBQUssU0FBTCxDQUFlLE1BQWYsS0FBMEIsQ0FBekQsRUFBNEQ7QUFDMUQsZUFBTyxJQUFQO0FBQ0Q7O0FBRUQsYUFBTyxLQUFLLFNBQUwsQ0FBZSxLQUFmLENBQXFCLENBQXJCLENBQVA7QUFDRDs7QUFFRDs7Ozs7O3dCQUdpQjtBQUNmLFVBQUksV0FBVyxLQUFLLFFBQXBCO0FBQ0EsVUFBSSxhQUFhLElBQWIsSUFBcUIsU0FBUyxNQUFULEtBQW9CLENBQTdDLEVBQWdEO0FBQzlDLGVBQU8sSUFBUDtBQUNEO0FBQ0QsYUFBTyxTQUFTLFNBQVMsTUFBVCxHQUFrQixDQUEzQixDQUFQO0FBQ0Q7Ozt3QkFvQmE7QUFDWixhQUFPLEtBQUssYUFBTCxDQUFtQixLQUFuQixDQUF5QixDQUF6QixDQUFQO0FBQ0Q7O0FBRUQ7Ozs7Ozt3QkFHa0I7QUFDaEIsVUFBSSxTQUFTLEtBQUssTUFBbEI7QUFDQSxVQUFJLE9BQU8sTUFBUCxLQUFrQixDQUF0QixFQUF5QjtBQUN2QixlQUFPLElBQVA7QUFDRDs7QUFFRCxVQUFJLGFBQWEsT0FBTyxDQUFQLENBQWpCO0FBQ0EsVUFBSSxZQUFZLE9BQU8sT0FBTyxNQUFQLEdBQWdCLENBQXZCLENBQWhCO0FBQ0EsYUFBTyxDQUNMLFdBQVcsS0FETixFQUVMLFVBQVUsS0FBVixHQUFrQixVQUFVLEtBQVYsQ0FBZ0IsTUFBbEMsR0FBMkMsQ0FGdEMsQ0FBUDtBQUlEOzs7d0JBMEJhO0FBQ1osVUFBSSxLQUFLLGVBQUwsSUFBd0IsS0FBSyxRQUFqQyxFQUEyQztBQUN6QyxlQUFPLEtBQUssUUFBTCxDQUFjLE1BQWQsQ0FBcUIsVUFBQyxXQUFELEVBQWMsS0FBZCxFQUF3QjtBQUNsRCxpQkFBTyxZQUFZLE1BQVosQ0FBbUIsTUFBTSxNQUF6QixDQUFQO0FBQ0QsU0FGTSxFQUVKLEtBQUssU0FGRCxDQUFQO0FBR0Q7O0FBRUQsYUFBTyxLQUFLLFNBQVo7QUFDRDs7O3dCQWdCZ0I7QUFDZixhQUFPLEtBQUssT0FBTCxLQUFpQixJQUFqQixHQUF3QixFQUF4QixHQUE2QixLQUFLLE9BQUwsQ0FBYSxLQUFiLENBQW1CLENBQW5CLENBQXBDO0FBQ0Q7Ozs7OztBQUdIOzs7Ozs7O2tCQTlKcUIsUTs7SUFtS1IsUyxXQUFBLFM7OztBQUNYOzs7O0FBSUEscUJBQWEsT0FBYixFQUFzQixJQUF0QixFQUE0QjtBQUFBOztBQUFBLDZGQUNwQixPQURvQjs7QUFFMUIsVUFBSyxJQUFMLEdBQVkscUJBQVo7QUFDQSxVQUFLLElBQUwsR0FBWSxJQUFaO0FBSDBCO0FBSTNCOzs7RUFUNEIsSzs7QUFVOUIiLCJmaWxlIjoiSFRNTE5vZGUuanMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgSFRNTFBhcnNlRXJyb3IgZnJvbSAnLi4vSFRNTFBhcnNlRXJyb3InXG5cbi8qKlxuICogSFRNTCBub2RlIHR5cGVzLlxuICogQGVudW0ge3N0cmluZ31cbiAqL1xuZXhwb3J0IGNvbnN0IE5vZGVUeXBlID0ge1xuICBST09UOiBcIlJPT1RcIixcbiAgVEFHOiAgXCJUQUdcIixcbiAgQVRUUklCVVRFOiBcIkFUVFJJQlVURVwiLFxuICBURVhUOiBcIlRFWFRcIixcbiAgRU5USVRZOiAgXCJFTlRJVFlcIixcbiAgQ09NTUVOVDogXCJDT01NRU5UXCIsXG4gIENMT1NFVEFHOiBcIkNMT1NFVEFHXCJcbn07XG5cbi8qKlxuICogSFRNTCB0cmVlIG5vZGVzIGJhc2UgY2xhc3MuIFNob3VsZCBuZXZlciBiZSBjYWxsZWQgb3V0c2lkZSBvZlxuICogc3ViY2xhc3MgY29uc3RydWN0b3JzIVxuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBIVE1MTm9kZSB7XG4gIGNvbnN0cnVjdG9yICgpIHtcbiAgICAvKipcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqIEB0eXBlIHtBcnJheS48Rm91bmRhdGlvbi5IVE1MLlBhcnNlci5IVE1MTm9kZT4/fVxuICAgICAqL1xuICAgIHRoaXMuX2NoaWxkcmVuID0gbnVsbDtcblxuICAgIC8qKlxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHR5cGUge0FycmF5LjxGb3VuZGF0aW9uLlNjYW5uZXIuVG9rZW4+fVxuICAgICAqL1xuICAgIHRoaXMuX3NvdXJjZVRva2VucyA9IFtdO1xuXG4gICAgLyoqXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAdHlwZSB7QXJyYXkuPEhUTUxQYXJzZUVycm9yPj99XG4gICAgICovXG4gICAgdGhpcy5fZXJyb3JzID0gbnVsbDtcbiAgfVxuXG4gIC8qKlxuICAgKiBTdWJjbGFzc2VzIG11c3Qgb3ZlcnJpZGUgdGhpcy5cbiAgICogQHJldHVybiB7Ym9vbGVhbn1cbiAgICovXG4gIGdldCBjYW5IYXZlQ2hpbGRyZW4gKCkge1xuICAgIHRocm93IG5ldyBOb2RlRXJyb3IoXCJjYW5IYXZlQ2hpbGRyZW4gbm90IG92ZXJyaWRlbiBpbiBzdWJjbGFzc1wiLCB0aGlzKVxuICB9XG5cbiAgLyoqXG4gICAqIFN1YmNsYXNzZXMgbXVzdCBvdmVycmlkZSB0aGlzLlxuICAgKiBAcmV0dXJuIHtzdHJpbmd9XG4gICAqL1xuICB0b1N0cmluZyAoKSB7XG4gICAgdGhyb3cgbmV3IE5vZGVFcnJvcihcInRvU3RyaW5nIG5vdCBvdmVycmlkZW4gaW4gc3ViY2xhc3NcIiwgdGhpcylcbiAgfVxuXG4gIC8qKlxuICAgKiBAcmV0dXJuIHtOb2RlVHlwZX1cbiAgICovXG4gIGdldCB0eXBlICgpIHtcbiAgICB0aHJvdyBuZXcgTm9kZUVycm9yKFwidHlwZSBnZXR0ZXIgbm90IG92ZXJyaWRlbiBpbiBzdWJjbGFzc1wiLCB0aGlzKVxuICB9XG5cbiAgLyoqXG4gICAqIEByZXR1cm4ge0FycmF5LjxGb3VuZGF0aW9uLkhUTUwuUGFyc2VyLkhUTUxOb2RlPj99XG4gICAqL1xuICBnZXQgY2hpbGRyZW4gKCkge1xuICAgIGlmICh0aGlzLl9jaGlsZHJlbiA9PT0gbnVsbCB8fCB0aGlzLl9jaGlsZHJlbi5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLl9jaGlsZHJlbi5zbGljZSgwKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAcmV0dXJuIHtGb3VuZGF0aW9uLkhUTUwuUGFyc2VyLkhUTUxOb2RlfVxuICAgKi9cbiAgZ2V0IGxhc3RDaGlsZCAoKSB7XG4gICAgdmFyIGNoaWxkcmVuID0gdGhpcy5jaGlsZHJlbjtcbiAgICBpZiAoY2hpbGRyZW4gPT09IG51bGwgfHwgY2hpbGRyZW4ubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgcmV0dXJuIGNoaWxkcmVuW2NoaWxkcmVuLmxlbmd0aCAtIDFdO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7Rm91bmRhdGlvbi5TY2FubmVyLlRva2VufSB0b2tlblxuICAgKi9cbiAgYWRkVG9rZW4gKHRva2VuKSB7XG4gICAgdGhpcy5fc291cmNlVG9rZW5zLnB1c2godG9rZW4pO1xuXG4gICAgLy8gQ3JlYXRlIGVycm9yIG9iamVjdHMgd2hlbiBhZGRpbmcgYSB0b2tlbiBvZiB0eXBlIGVycm9yLlxuICAgIGlmICh0b2tlbi50eXBlID09PSBcImVycm9yXCIpIHtcbiAgICAgIHZhciBlcnJvciA9IG5ldyBIVE1MUGFyc2VFcnJvcigpO1xuICAgICAgZXJyb3IubWVzc2FnZSA9IFwiSW52YWxpZCB0b2tlbjogXFxcIlwiICsgdG9rZW4udmFsdWUgKyBcIlxcXCJcIjtcbiAgICAgIGVycm9yLmFkZFRva2VuKHRva2VuKTtcbiAgICAgIHRoaXMuYWRkRXJyb3IoZXJyb3IpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBAcmV0dXJuIHtBcnJheS48Rm91bmRhdGlvbi5TY2FubmVyLlRva2VuPn1cbiAgICovXG4gIGdldCB0b2tlbnMgKCkge1xuICAgIHJldHVybiB0aGlzLl9zb3VyY2VUb2tlbnMuc2xpY2UoMCk7XG4gIH1cblxuICAvKipcbiAgICogQHJldHVybiB7QXJyYXkuPG51bWJlcj4/fVxuICAgKi9cbiAgZ2V0IGluZGV4UmFuZ2UgKCkge1xuICAgIHZhciB0b2tlbnMgPSB0aGlzLnRva2VucztcbiAgICBpZiAodG9rZW5zLmxlbmd0aCA9PT0gMCkge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgdmFyIGZpcnN0VG9rZW4gPSB0b2tlbnNbMF07XG4gICAgdmFyIGxhc3RUb2tlbiA9IHRva2Vuc1t0b2tlbnMubGVuZ3RoIC0gMV07XG4gICAgcmV0dXJuIFtcbiAgICAgIGZpcnN0VG9rZW4uaW5kZXgsXG4gICAgICBsYXN0VG9rZW4uaW5kZXggKyBsYXN0VG9rZW4udmFsdWUubGVuZ3RoIC0gMVxuICAgIF07XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtGb3VuZGF0aW9uLkhUTUwuUGFyc2VyLkhUTUxOb2RlfSBjaGlsZE5vZGVcbiAgICogQHJldHVybiB7Rm91bmRhdGlvbi5IVE1MLlBhcnNlci5IVE1MTm9kZX1cbiAgICovXG4gIGFwcGVuZENoaWxkIChjaGlsZE5vZGUpIHtcbiAgICBpZiAoISB0aGlzLmNhbkhhdmVDaGlsZHJlbikge1xuICAgICAgdGhyb3cgbmV3IE5vZGVFcnJvcihcbiAgICAgICAgXCJhdHRlbXB0ZWQgdG8gY2FsbCBhcHBlbmRDaGlsZCBvbiBub2RlIHRoYXQgY2FuJ3QgaGF2ZSBjaGlsZHJlblwiLCB0aGlzXG4gICAgICApO1xuICAgIH1cblxuICAgIGlmICghIHRoaXMuX2NoaWxkcmVuKSB7XG4gICAgICB0aGlzLl9jaGlsZHJlbiA9IFtdO1xuICAgIH1cblxuICAgIHRoaXMuX2NoaWxkcmVuLnB1c2goY2hpbGROb2RlKTtcblxuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwdWJsaWNcbiAgICogQHJldHVybiB7QXJyYXkuPEhUTUxQYXJzZUVycm9yPn1cbiAgICovXG4gIGdldCBlcnJvcnMgKCkge1xuICAgIGlmICh0aGlzLmNhbkhhdmVDaGlsZHJlbiAmJiB0aGlzLmNoaWxkcmVuKSB7XG4gICAgICByZXR1cm4gdGhpcy5jaGlsZHJlbi5yZWR1Y2UoKGFjY3VtdWxhdG9yLCBjaGlsZCkgPT4ge1xuICAgICAgICByZXR1cm4gYWNjdW11bGF0b3IuY29uY2F0KGNoaWxkLmVycm9ycylcbiAgICAgIH0sIHRoaXMub3duRXJyb3JzKVxuICAgIH1cblxuICAgIHJldHVybiB0aGlzLm93bkVycm9yc1xuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7SFRNTFBhcnNlRXJyb3J9IGVycm9yXG4gICAqL1xuICBhZGRFcnJvciAoZXJyb3IpIHtcbiAgICBpZiAodGhpcy5fZXJyb3JzID09PSBudWxsKSB7XG4gICAgICB0aGlzLl9lcnJvcnMgPSBbXTtcbiAgICB9XG4gICAgdGhpcy5fZXJyb3JzLnB1c2goZXJyb3IpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBwcml2YXRlXG4gICAqIEByZXR1cm4ge0FycmF5LjxIVE1MUGFyc2VFcnJvcj59XG4gICAqL1xuICBnZXQgb3duRXJyb3JzICgpIHtcbiAgICByZXR1cm4gdGhpcy5fZXJyb3JzID09PSBudWxsID8gW10gOiB0aGlzLl9lcnJvcnMuc2xpY2UoMCk7XG4gIH1cbn1cblxuLyoqXG4gKiBIVE1MIG5vZGUgZXJyb3IgY2xhc3MuIFRoaXMgaXMgYSB0aHJvd2FibGUgRXJyb3Igb2JqZWN0LCBub3QgdG8gYmVcbiAqIGNvbmZ1c2VkIHdpdGggdGhlIEhUTUxQYXJzZUVycm9yIGNsYXNzIHdoaWNoIGRlYWxzXG4gKiB3aXRoIHJlcG9ydGluZyBlcnJvcnMgZm91bmQgaW4gdGhlIEhUTUwgc291cmNlLlxuICovXG5leHBvcnQgY2xhc3MgTm9kZUVycm9yIGV4dGVuZHMgRXJyb3Ige1xuICAvKipcbiAgICogQHBhcmFtIHtzdHJpbmd9IG1lc3NhZ2VcbiAgICogQHBhcmFtIHtGb3VuZGF0aW9uLkhUTUwuUGFyc2VyLkhUTUxOb2RlfSBub2RlXG4gICAqL1xuICBjb25zdHJ1Y3RvciAobWVzc2FnZSwgbm9kZSkge1xuICAgIHN1cGVyKG1lc3NhZ2UpO1xuICAgIHRoaXMubmFtZSA9IFwiSFRNTFBhcnNlck5vZGVFcnJvclwiO1xuICAgIHRoaXMubm9kZSA9IG5vZGU7XG4gIH1cbn07XG4iXX0=