hurt
Version:
HTTP and SPA routing using RFC 6570 URI templates
167 lines (138 loc) • 14.1 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.mixin = undefined;
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
var _trie = require('./trie');
var _handler2 = require('./handler');
var _handler3 = _interopRequireDefault(_handler2);
var _uriTemplates = require('uri-templates');
var _uriTemplates2 = _interopRequireDefault(_uriTemplates);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function templatePrefix(template) {
var index = template.indexOf('{');
var prefix = index < 0 ? template : template.substr(0, index);
return prefix;
}
function templateParams(template) {
var t = (0, _uriTemplates2.default)(template);
return function (url) {
var match = t.fromUri(url);
return match;
};
}
function regExpPrefix(regexp) {
var source = regexp.source.replace(/(^\^|\$$)/g, '');
var match = /(^|[^\\])([[({.]|\\[dDsSwWxu])/.exec(source);
var prefix = match ? source.substr(0, match.index + match[1].length) : source;
return prefix.replace(/\\([/\\().*\[\]])/g, '$1');
}
function regExpParams(regexp) {
return function (url) {
var match = regexp.exec(url);
return match && match[0] === url && match;
};
}
function routeHandler(params, fn) {
return function (req) {
for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
args[_key - 1] = arguments[_key];
}
var next = args.pop();
var match = params(req.url);
if (match) {
req.params = _extends({}, req.params, match);
fn.call.apply(fn, [this, req].concat(args, [function (err) {
if (!err) {
req.handled = true;
}
next(err);
}]));
} else {
next();
}
};
}
function mixin() {
var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
_ref$base = _ref.base,
_base = _ref$base === undefined ? '' : _ref$base;
var EMPTY = {};
var tries = [EMPTY];
var _notfound = [];
var handle = (0, _handler3.default)(_notfound);
return {
post: [function (req) {
for (var _len2 = arguments.length, args = Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
args[_key2 - 1] = arguments[_key2];
}
if (!req.handled) {
handle.call.apply(handle, [this, req].concat(args));
} else {
var next = args[args.length - 1];
next();
}
}],
base: function base(url) {
if (typeof url === 'string') {
_base = url;
return this;
}
return _base;
},
use: function use(options) {
for (var _len3 = arguments.length, stack = Array(_len3 > 1 ? _len3 - 1 : 0), _key3 = 1; _key3 < _len3; _key3++) {
stack[_key3 - 1] = arguments[_key3];
}
var url = void 0;
var prefix = void 0;
var params = void 0;
if (typeof options === 'string' || options instanceof RegExp) {
url = options;
options = { url: url };
} else {
url = options.url;
}
if (typeof url === 'string') {
prefix = templatePrefix(url);
params = templateParams(url);
} else if (url instanceof RegExp) {
prefix = regExpPrefix(url);
params = regExpParams(url);
} else {
if (tries[tries.length - 1] !== EMPTY) {
tries.push(EMPTY);
}
return this.use.apply(this, [options].concat(stack));
}
var route = this.route.apply(this, [options].concat(stack));
var trie = tries.pop();
var index = tries.length;
tries.push((0, _trie.add)(trie, prefix, [routeHandler(params, route)]));
if (trie === EMPTY) {
return this.use(function (req) {
var stack = (0, _trie.match)(tries[index], req.url, []);
for (var _len4 = arguments.length, args = Array(_len4 > 1 ? _len4 - 1 : 0), _key4 = 1; _key4 < _len4; _key4++) {
args[_key4 - 1] = arguments[_key4];
}
if (stack.length) {
var _handler;
(_handler = (0, _handler3.default)(stack)).call.apply(_handler, [this, req].concat(args));
} else {
var next = args[args.length - 1];
next();
}
});
} else {
return this;
}
},
notfound: function notfound() {
_notfound.push.apply(_notfound, arguments);
return this;
}
};
}
exports.mixin = mixin;
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy91cmwuanMiXSwibmFtZXMiOlsidGVtcGxhdGVQcmVmaXgiLCJ0ZW1wbGF0ZSIsImluZGV4IiwiaW5kZXhPZiIsInByZWZpeCIsInN1YnN0ciIsInRlbXBsYXRlUGFyYW1zIiwidCIsIm1hdGNoIiwiZnJvbVVyaSIsInVybCIsInJlZ0V4cFByZWZpeCIsInJlZ2V4cCIsInNvdXJjZSIsInJlcGxhY2UiLCJleGVjIiwibGVuZ3RoIiwicmVnRXhwUGFyYW1zIiwicm91dGVIYW5kbGVyIiwicGFyYW1zIiwiZm4iLCJyZXEiLCJhcmdzIiwibmV4dCIsInBvcCIsImNhbGwiLCJlcnIiLCJoYW5kbGVkIiwibWl4aW4iLCJiYXNlIiwiRU1QVFkiLCJ0cmllcyIsIm5vdGZvdW5kIiwiaGFuZGxlIiwicG9zdCIsInVzZSIsIm9wdGlvbnMiLCJzdGFjayIsIlJlZ0V4cCIsInB1c2giLCJyb3V0ZSIsInRyaWUiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7OztBQUFBOztBQUNBOzs7O0FBRUE7Ozs7OztBQUVBLFNBQVNBLGNBQVQsQ0FBd0JDLFFBQXhCLEVBQWtDO0FBQ2hDLE1BQU1DLFFBQVFELFNBQVNFLE9BQVQsQ0FBaUIsR0FBakIsQ0FBZDtBQUNBLE1BQU1DLFNBQVNGLFFBQVEsQ0FBUixHQUFZRCxRQUFaLEdBQXVCQSxTQUFTSSxNQUFULENBQWdCLENBQWhCLEVBQW1CSCxLQUFuQixDQUF0QztBQUNBLFNBQU9FLE1BQVA7QUFDRDs7QUFFRCxTQUFTRSxjQUFULENBQXdCTCxRQUF4QixFQUFrQztBQUNoQyxNQUFNTSxJQUFJLDRCQUFZTixRQUFaLENBQVY7QUFDQSxTQUFPLGVBQU87QUFDWixRQUFNTyxRQUFRRCxFQUFFRSxPQUFGLENBQVVDLEdBQVYsQ0FBZDtBQUNBLFdBQU9GLEtBQVA7QUFDRCxHQUhEO0FBSUQ7O0FBRUQsU0FBU0csWUFBVCxDQUFzQkMsTUFBdEIsRUFBOEI7QUFDNUIsTUFBTUMsU0FBU0QsT0FBT0MsTUFBUCxDQUFjQyxPQUFkLENBQXNCLFlBQXRCLEVBQW9DLEVBQXBDLENBQWY7QUFDQSxNQUFNTixRQUFRLGlDQUFpQ08sSUFBakMsQ0FBc0NGLE1BQXRDLENBQWQ7QUFDQSxNQUFNVCxTQUFTSSxRQUFRSyxPQUFPUixNQUFQLENBQWMsQ0FBZCxFQUFpQkcsTUFBTU4sS0FBTixHQUFjTSxNQUFNLENBQU4sRUFBU1EsTUFBeEMsQ0FBUixHQUEwREgsTUFBekU7QUFDQSxTQUFPVCxPQUFPVSxPQUFQLENBQWUsb0JBQWYsRUFBcUMsSUFBckMsQ0FBUDtBQUNEOztBQUVELFNBQVNHLFlBQVQsQ0FBc0JMLE1BQXRCLEVBQThCO0FBQzVCLFNBQU8sZUFBTztBQUNaLFFBQU1KLFFBQVFJLE9BQU9HLElBQVAsQ0FBWUwsR0FBWixDQUFkO0FBQ0EsV0FBT0YsU0FBVUEsTUFBTSxDQUFOLE1BQWFFLEdBQXZCLElBQStCRixLQUF0QztBQUNELEdBSEQ7QUFJRDs7QUFFRCxTQUFTVSxZQUFULENBQXNCQyxNQUF0QixFQUE4QkMsRUFBOUIsRUFBa0M7QUFDaEMsU0FBTyxVQUFVQyxHQUFWLEVBQXdCO0FBQUEsc0NBQU5DLElBQU07QUFBTkEsVUFBTTtBQUFBOztBQUM3QixRQUFNQyxPQUFPRCxLQUFLRSxHQUFMLEVBQWI7QUFDQSxRQUFNaEIsUUFBUVcsT0FBT0UsSUFBSVgsR0FBWCxDQUFkOztBQUVBLFFBQUlGLEtBQUosRUFBVztBQUNUYSxVQUFJRixNQUFKLGdCQUNLRSxJQUFJRixNQURULEVBRUtYLEtBRkw7O0FBS0FZLFNBQUdLLElBQUgsWUFBUSxJQUFSLEVBQWNKLEdBQWQsU0FBc0JDLElBQXRCLEdBQTRCLFVBQVVJLEdBQVYsRUFBZTtBQUN6QyxZQUFJLENBQUNBLEdBQUwsRUFBVTtBQUNSTCxjQUFJTSxPQUFKLEdBQWMsSUFBZDtBQUNEO0FBQ0RKLGFBQUtHLEdBQUw7QUFDRCxPQUxEO0FBTUQsS0FaRCxNQWFLO0FBQ0hIO0FBQ0Q7QUFDRixHQXBCRDtBQXFCRDs7QUFFTSxTQUFTSyxLQUFULEdBQW1DO0FBQUEsaUZBQUosRUFBSTtBQUFBLHVCQUFsQkMsSUFBa0I7QUFBQSxNQUFsQkEsS0FBa0IsNkJBQVgsRUFBVzs7QUFDeEMsTUFBTUMsUUFBUSxFQUFkO0FBQ0EsTUFBTUMsUUFBUSxDQUFDRCxLQUFELENBQWQ7QUFDQSxNQUFNRSxZQUFXLEVBQWpCO0FBQ0EsTUFBTUMsU0FBUyx1QkFBUUQsU0FBUixDQUFmOztBQUVBLFNBQU87QUFDTEUsVUFBTSxDQUNKLFVBQVViLEdBQVYsRUFBd0I7QUFBQSx5Q0FBTkMsSUFBTTtBQUFOQSxZQUFNO0FBQUE7O0FBQ3RCLFVBQUksQ0FBQ0QsSUFBSU0sT0FBVCxFQUFrQjtBQUNoQk0sZUFBT1IsSUFBUCxnQkFBWSxJQUFaLEVBQWtCSixHQUFsQixTQUEwQkMsSUFBMUI7QUFDRCxPQUZELE1BR0s7QUFDSCxZQUFNQyxPQUFPRCxLQUFNQSxLQUFLTixNQUFMLEdBQWMsQ0FBcEIsQ0FBYjtBQUNBTztBQUNEO0FBQ0YsS0FURyxDQUREO0FBWUxNLFFBWkssZ0JBWUFuQixHQVpBLEVBWUs7QUFDUixVQUFJLE9BQU9BLEdBQVAsS0FBZSxRQUFuQixFQUE2QjtBQUMzQm1CLGdCQUFPbkIsR0FBUDtBQUNBLGVBQU8sSUFBUDtBQUNEO0FBQ0QsYUFBT21CLEtBQVA7QUFDRCxLQWxCSTtBQW1CTE0sT0FuQkssZUFtQkRDLE9BbkJDLEVBbUJrQjtBQUFBLHlDQUFQQyxLQUFPO0FBQVBBLGFBQU87QUFBQTs7QUFDckIsVUFBSTNCLFlBQUo7QUFDQSxVQUFJTixlQUFKO0FBQ0EsVUFBSWUsZUFBSjs7QUFFQSxVQUFJLE9BQU9pQixPQUFQLEtBQW1CLFFBQW5CLElBQStCQSxtQkFBbUJFLE1BQXRELEVBQThEO0FBQzVENUIsY0FBTTBCLE9BQU47QUFDQUEsa0JBQVUsRUFBRTFCLFFBQUYsRUFBVjtBQUNELE9BSEQsTUFJSztBQUNIQSxjQUFNMEIsUUFBUTFCLEdBQWQ7QUFDRDs7QUFFRCxVQUFJLE9BQU9BLEdBQVAsS0FBZSxRQUFuQixFQUE2QjtBQUMzQk4saUJBQVNKLGVBQWVVLEdBQWYsQ0FBVDtBQUNBUyxpQkFBU2IsZUFBZUksR0FBZixDQUFUO0FBQ0QsT0FIRCxNQUlLLElBQUlBLGVBQWU0QixNQUFuQixFQUEyQjtBQUM5QmxDLGlCQUFTTyxhQUFhRCxHQUFiLENBQVQ7QUFDQVMsaUJBQVNGLGFBQWFQLEdBQWIsQ0FBVDtBQUNELE9BSEksTUFJQTtBQUNILFlBQUlxQixNQUFNQSxNQUFNZixNQUFOLEdBQWUsQ0FBckIsTUFBNEJjLEtBQWhDLEVBQXVDO0FBQ3JDQyxnQkFBTVEsSUFBTixDQUFXVCxLQUFYO0FBQ0Q7QUFDRCxlQUFPLEtBQUtLLEdBQUwsY0FBU0MsT0FBVCxTQUFxQkMsS0FBckIsRUFBUDtBQUNEOztBQUVELFVBQU1HLFFBQVEsS0FBS0EsS0FBTCxjQUFXSixPQUFYLFNBQXVCQyxLQUF2QixFQUFkO0FBQ0EsVUFBTUksT0FBT1YsTUFBTVAsR0FBTixFQUFiO0FBQ0EsVUFBTXRCLFFBQVE2QixNQUFNZixNQUFwQjs7QUFFQWUsWUFBTVEsSUFBTixDQUFXLGVBQUlFLElBQUosRUFBVXJDLE1BQVYsRUFBa0IsQ0FBRWMsYUFBYUMsTUFBYixFQUFxQnFCLEtBQXJCLENBQUYsQ0FBbEIsQ0FBWDs7QUFFQSxVQUFJQyxTQUFTWCxLQUFiLEVBQW9CO0FBQ2xCLGVBQU8sS0FBS0ssR0FBTCxDQUFTLFVBQVVkLEdBQVYsRUFBd0I7QUFDdEMsY0FBTWdCLFFBQVEsaUJBQU1OLE1BQU83QixLQUFQLENBQU4sRUFBc0JtQixJQUFJWCxHQUExQixFQUErQixFQUEvQixDQUFkOztBQURzQyw2Q0FBTlksSUFBTTtBQUFOQSxnQkFBTTtBQUFBOztBQUd0QyxjQUFJZSxNQUFNckIsTUFBVixFQUFrQjtBQUFBOztBQUNoQiwrQ0FBUXFCLEtBQVIsR0FBZVosSUFBZixrQkFBb0IsSUFBcEIsRUFBMEJKLEdBQTFCLFNBQWtDQyxJQUFsQztBQUNELFdBRkQsTUFHSztBQUNILGdCQUFNQyxPQUFPRCxLQUFNQSxLQUFLTixNQUFMLEdBQWMsQ0FBcEIsQ0FBYjtBQUNBTztBQUNEO0FBQ0YsU0FWTSxDQUFQO0FBV0QsT0FaRCxNQWFLO0FBQ0gsZUFBTyxJQUFQO0FBQ0Q7QUFDRixLQXJFSTtBQXNFTFMsWUF0RUssc0JBc0VjO0FBQ2pCQSxnQkFBU08sSUFBVDtBQUNBLGFBQU8sSUFBUDtBQUNEO0FBekVJLEdBQVA7QUEyRUQiLCJmaWxlIjoidXJsLmpzIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgYWRkLCBtYXRjaCB9IGZyb20gJy4vdHJpZSc7XG5pbXBvcnQgaGFuZGxlciBmcm9tICcuL2hhbmRsZXInO1xuXG5pbXBvcnQgdXJpVGVtcGxhdGUgZnJvbSAndXJpLXRlbXBsYXRlcyc7XG5cbmZ1bmN0aW9uIHRlbXBsYXRlUHJlZml4KHRlbXBsYXRlKSB7XG4gIGNvbnN0IGluZGV4ID0gdGVtcGxhdGUuaW5kZXhPZigneycpO1xuICBjb25zdCBwcmVmaXggPSBpbmRleCA8IDAgPyB0ZW1wbGF0ZSA6IHRlbXBsYXRlLnN1YnN0cigwLCBpbmRleCk7XG4gIHJldHVybiBwcmVmaXg7XG59XG5cbmZ1bmN0aW9uIHRlbXBsYXRlUGFyYW1zKHRlbXBsYXRlKSB7XG4gIGNvbnN0IHQgPSB1cmlUZW1wbGF0ZSh0ZW1wbGF0ZSk7XG4gIHJldHVybiB1cmwgPT4ge1xuICAgIGNvbnN0IG1hdGNoID0gdC5mcm9tVXJpKHVybCk7XG4gICAgcmV0dXJuIG1hdGNoO1xuICB9O1xufVxuXG5mdW5jdGlvbiByZWdFeHBQcmVmaXgocmVnZXhwKSB7XG4gIGNvbnN0IHNvdXJjZSA9IHJlZ2V4cC5zb3VyY2UucmVwbGFjZSgvKF5cXF58XFwkJCkvZywgJycpO1xuICBjb25zdCBtYXRjaCA9IC8oXnxbXlxcXFxdKShbWyh7Ll18XFxcXFtkRHNTd1d4dV0pLy5leGVjKHNvdXJjZSk7XG4gIGNvbnN0IHByZWZpeCA9IG1hdGNoID8gc291cmNlLnN1YnN0cigwLCBtYXRjaC5pbmRleCArIG1hdGNoWzFdLmxlbmd0aCkgOiBzb3VyY2U7XG4gIHJldHVybiBwcmVmaXgucmVwbGFjZSgvXFxcXChbL1xcXFwoKS4qXFxbXFxdXSkvZywgJyQxJyk7XG59XG5cbmZ1bmN0aW9uIHJlZ0V4cFBhcmFtcyhyZWdleHApIHtcbiAgcmV0dXJuIHVybCA9PiB7XG4gICAgY29uc3QgbWF0Y2ggPSByZWdleHAuZXhlYyh1cmwpO1xuICAgIHJldHVybiBtYXRjaCAmJiAobWF0Y2hbMF0gPT09IHVybCkgJiYgbWF0Y2g7XG4gIH07XG59XG5cbmZ1bmN0aW9uIHJvdXRlSGFuZGxlcihwYXJhbXMsIGZuKSB7XG4gIHJldHVybiBmdW5jdGlvbiAocmVxLCAuLi5hcmdzKSB7XG4gICAgY29uc3QgbmV4dCA9IGFyZ3MucG9wKCk7XG4gICAgY29uc3QgbWF0Y2ggPSBwYXJhbXMocmVxLnVybCk7XG5cbiAgICBpZiAobWF0Y2gpIHtcbiAgICAgIHJlcS5wYXJhbXMgPSB7XG4gICAgICAgIC4uLnJlcS5wYXJhbXMsXG4gICAgICAgIC4uLm1hdGNoXG4gICAgICB9O1xuXG4gICAgICBmbi5jYWxsKHRoaXMsIHJlcSwgLi4uYXJncywgZnVuY3Rpb24gKGVycikge1xuICAgICAgICBpZiAoIWVycikge1xuICAgICAgICAgIHJlcS5oYW5kbGVkID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICBuZXh0KGVycik7XG4gICAgICB9KTtcbiAgICB9XG4gICAgZWxzZSB7XG4gICAgICBuZXh0KCk7XG4gICAgfVxuICB9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gbWl4aW4oeyBiYXNlID0gJycgfSA9IHt9KSB7XG4gIGNvbnN0IEVNUFRZID0ge307XG4gIGNvbnN0IHRyaWVzID0gW0VNUFRZXTtcbiAgY29uc3Qgbm90Zm91bmQgPSBbXTtcbiAgY29uc3QgaGFuZGxlID0gaGFuZGxlcihub3Rmb3VuZCk7XG5cbiAgcmV0dXJuIHtcbiAgICBwb3N0OiBbXG4gICAgICBmdW5jdGlvbiAocmVxLCAuLi5hcmdzKSB7XG4gICAgICAgIGlmICghcmVxLmhhbmRsZWQpIHtcbiAgICAgICAgICBoYW5kbGUuY2FsbCh0aGlzLCByZXEsIC4uLmFyZ3MpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgIGNvbnN0IG5leHQgPSBhcmdzWyBhcmdzLmxlbmd0aCAtIDEgXTtcbiAgICAgICAgICBuZXh0KCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICBdLFxuICAgIGJhc2UodXJsKSB7XG4gICAgICBpZiAodHlwZW9mIHVybCA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgYmFzZSA9IHVybDtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICB9XG4gICAgICByZXR1cm4gYmFzZTtcbiAgICB9LFxuICAgIHVzZShvcHRpb25zLCAuLi5zdGFjaykge1xuICAgICAgbGV0IHVybDtcbiAgICAgIGxldCBwcmVmaXg7XG4gICAgICBsZXQgcGFyYW1zO1xuXG4gICAgICBpZiAodHlwZW9mIG9wdGlvbnMgPT09ICdzdHJpbmcnIHx8IG9wdGlvbnMgaW5zdGFuY2VvZiBSZWdFeHApIHtcbiAgICAgICAgdXJsID0gb3B0aW9ucztcbiAgICAgICAgb3B0aW9ucyA9IHsgdXJsIH07XG4gICAgICB9XG4gICAgICBlbHNlIHtcbiAgICAgICAgdXJsID0gb3B0aW9ucy51cmw7XG4gICAgICB9XG5cbiAgICAgIGlmICh0eXBlb2YgdXJsID09PSAnc3RyaW5nJykge1xuICAgICAgICBwcmVmaXggPSB0ZW1wbGF0ZVByZWZpeCh1cmwpO1xuICAgICAgICBwYXJhbXMgPSB0ZW1wbGF0ZVBhcmFtcyh1cmwpO1xuICAgICAgfVxuICAgICAgZWxzZSBpZiAodXJsIGluc3RhbmNlb2YgUmVnRXhwKSB7XG4gICAgICAgIHByZWZpeCA9IHJlZ0V4cFByZWZpeCh1cmwpO1xuICAgICAgICBwYXJhbXMgPSByZWdFeHBQYXJhbXModXJsKTtcbiAgICAgIH1cbiAgICAgIGVsc2Uge1xuICAgICAgICBpZiAodHJpZXNbdHJpZXMubGVuZ3RoIC0gMV0gIT09IEVNUFRZKSB7XG4gICAgICAgICAgdHJpZXMucHVzaChFTVBUWSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMudXNlKG9wdGlvbnMsIC4uLnN0YWNrKTtcbiAgICAgIH1cblxuICAgICAgY29uc3Qgcm91dGUgPSB0aGlzLnJvdXRlKG9wdGlvbnMsIC4uLnN0YWNrKVxuICAgICAgY29uc3QgdHJpZSA9IHRyaWVzLnBvcCgpO1xuICAgICAgY29uc3QgaW5kZXggPSB0cmllcy5sZW5ndGg7XG5cbiAgICAgIHRyaWVzLnB1c2goYWRkKHRyaWUsIHByZWZpeCwgWyByb3V0ZUhhbmRsZXIocGFyYW1zLCByb3V0ZSkgXSkpO1xuXG4gICAgICBpZiAodHJpZSA9PT0gRU1QVFkpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMudXNlKGZ1bmN0aW9uIChyZXEsIC4uLmFyZ3MpIHtcbiAgICAgICAgICBjb25zdCBzdGFjayA9IG1hdGNoKHRyaWVzWyBpbmRleCBdLCByZXEudXJsLCBbXSk7XG5cbiAgICAgICAgICBpZiAoc3RhY2subGVuZ3RoKSB7XG4gICAgICAgICAgICBoYW5kbGVyKHN0YWNrKS5jYWxsKHRoaXMsIHJlcSwgLi4uYXJncyk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgY29uc3QgbmV4dCA9IGFyZ3NbIGFyZ3MubGVuZ3RoIC0gMSBdO1xuICAgICAgICAgICAgbmV4dCgpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICBlbHNlIHtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICB9XG4gICAgfSxcbiAgICBub3Rmb3VuZCguLi5zdGFjaykge1xuICAgICAgbm90Zm91bmQucHVzaCguLi5zdGFjayk7XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gIH07XG59XG4iXX0=