+597
| /******/ (function(modules) { // webpackBootstrap | ||
| /******/ // The module cache | ||
| /******/ var installedModules = {}; | ||
| /******/ | ||
| /******/ // The require function | ||
| /******/ function __webpack_require__(moduleId) { | ||
| /******/ | ||
| /******/ // Check if module is in cache | ||
| /******/ if(installedModules[moduleId]) | ||
| /******/ return installedModules[moduleId].exports; | ||
| /******/ | ||
| /******/ // Create a new module (and put it into the cache) | ||
| /******/ var module = installedModules[moduleId] = { | ||
| /******/ i: moduleId, | ||
| /******/ l: false, | ||
| /******/ exports: {} | ||
| /******/ }; | ||
| /******/ | ||
| /******/ // Execute the module function | ||
| /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); | ||
| /******/ | ||
| /******/ // Flag the module as loaded | ||
| /******/ module.l = true; | ||
| /******/ | ||
| /******/ // Return the exports of the module | ||
| /******/ return module.exports; | ||
| /******/ } | ||
| /******/ | ||
| /******/ | ||
| /******/ // expose the modules object (__webpack_modules__) | ||
| /******/ __webpack_require__.m = modules; | ||
| /******/ | ||
| /******/ // expose the module cache | ||
| /******/ __webpack_require__.c = installedModules; | ||
| /******/ | ||
| /******/ // identity function for calling harmony imports with the correct context | ||
| /******/ __webpack_require__.i = function(value) { return value; }; | ||
| /******/ | ||
| /******/ // define getter function for harmony exports | ||
| /******/ __webpack_require__.d = function(exports, name, getter) { | ||
| /******/ if(!__webpack_require__.o(exports, name)) { | ||
| /******/ Object.defineProperty(exports, name, { | ||
| /******/ configurable: false, | ||
| /******/ enumerable: true, | ||
| /******/ get: getter | ||
| /******/ }); | ||
| /******/ } | ||
| /******/ }; | ||
| /******/ | ||
| /******/ // getDefaultExport function for compatibility with non-harmony modules | ||
| /******/ __webpack_require__.n = function(module) { | ||
| /******/ var getter = module && module.__esModule ? | ||
| /******/ function getDefault() { return module['default']; } : | ||
| /******/ function getModuleExports() { return module; }; | ||
| /******/ __webpack_require__.d(getter, 'a', getter); | ||
| /******/ return getter; | ||
| /******/ }; | ||
| /******/ | ||
| /******/ // Object.prototype.hasOwnProperty.call | ||
| /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; | ||
| /******/ | ||
| /******/ // __webpack_public_path__ | ||
| /******/ __webpack_require__.p = ""; | ||
| /******/ | ||
| /******/ // Load entry module and return exports | ||
| /******/ return __webpack_require__(__webpack_require__.s = 3); | ||
| /******/ }) | ||
| /************************************************************************/ | ||
| /******/ ([ | ||
| /* 0 */ | ||
| /***/ (function(module, exports, __webpack_require__) { | ||
| "use strict"; | ||
| var pathToRegexp = __webpack_require__(2); | ||
| function hashpath() { | ||
| // cut prefix '#' | ||
| return window.location.hash.slice(1); | ||
| } | ||
| var Router = (function () { | ||
| // private hashCurrent() : string { | ||
| // return hashpath() | ||
| // } | ||
| // private hashPrevious() : string { | ||
| // return this.previous | ||
| // } | ||
| // private hashRoutes() : Route[] { | ||
| // return this.routes | ||
| // } | ||
| function Router(window) { | ||
| this.routes = []; | ||
| this.window = window; | ||
| } | ||
| Router.prototype.hash = function (path, arg) { | ||
| //if (path === undefined) throw new TypeError('invalid argument arg[1:path]') | ||
| //if (arg === undefined) throw new TypeError('invalid argument arg[2:arg]') | ||
| var keys = []; | ||
| var re = pathToRegexp(path, keys); | ||
| var route = { re: re, keys: keys }; | ||
| if (typeof arg === 'function') { | ||
| route.callback = arg; | ||
| } | ||
| else { | ||
| route.callback = function () { | ||
| // TODO | ||
| //riot.route(arg) | ||
| }; | ||
| } | ||
| this.routes.push(route); | ||
| }; | ||
| Router.prototype.start = function () { | ||
| this.window.addEventListener('hashchange', this.onHashChanged, false); | ||
| var hash = hashpath(); | ||
| if (hash.length > 0) { | ||
| this.dispatch(hash); | ||
| } | ||
| }; | ||
| Router.prototype.stop = function () { | ||
| this.window.removeEventListener('hashchange', this.onHashChanged, false); | ||
| }; | ||
| Router.prototype.onHashChanged = function () { | ||
| this.dispatch(hashpath()); | ||
| }; | ||
| Router.prototype.dispatch = function (path) { | ||
| if (!path) { | ||
| path = hashpath(); | ||
| } | ||
| else { | ||
| } | ||
| for (var _i = 0, _a = this.routes; _i < _a.length; _i++) { | ||
| var route = _a[_i]; | ||
| var result = route.re.exec(path); | ||
| if (result) { | ||
| route.callback.apply(this, result.slice(1)); | ||
| break; | ||
| } | ||
| } | ||
| }; | ||
| return Router; | ||
| }()); | ||
| exports.Router = Router; | ||
| /***/ }), | ||
| /* 1 */ | ||
| /***/ (function(module, exports) { | ||
| module.exports = Array.isArray || function (arr) { | ||
| return Object.prototype.toString.call(arr) == '[object Array]'; | ||
| }; | ||
| /***/ }), | ||
| /* 2 */ | ||
| /***/ (function(module, exports, __webpack_require__) { | ||
| var isarray = __webpack_require__(1) | ||
| /** | ||
| * Expose `pathToRegexp`. | ||
| */ | ||
| module.exports = pathToRegexp | ||
| module.exports.parse = parse | ||
| module.exports.compile = compile | ||
| module.exports.tokensToFunction = tokensToFunction | ||
| module.exports.tokensToRegExp = tokensToRegExp | ||
| /** | ||
| * The main path matching regexp utility. | ||
| * | ||
| * @type {RegExp} | ||
| */ | ||
| var PATH_REGEXP = new RegExp([ | ||
| // Match escaped characters that would otherwise appear in future matches. | ||
| // This allows the user to escape special characters that won't transform. | ||
| '(\\\\.)', | ||
| // Match Express-style parameters and un-named parameters with a prefix | ||
| // and optional suffixes. Matches appear as: | ||
| // | ||
| // "/:test(\\d+)?" => ["/", "test", "\d+", undefined, "?", undefined] | ||
| // "/route(\\d+)" => [undefined, undefined, undefined, "\d+", undefined, undefined] | ||
| // "/*" => ["/", undefined, undefined, undefined, undefined, "*"] | ||
| '([\\/.])?(?:(?:\\:(\\w+)(?:\\(((?:\\\\.|[^\\\\()])+)\\))?|\\(((?:\\\\.|[^\\\\()])+)\\))([+*?])?|(\\*))' | ||
| ].join('|'), 'g') | ||
| /** | ||
| * Parse a string for the raw tokens. | ||
| * | ||
| * @param {string} str | ||
| * @param {Object=} options | ||
| * @return {!Array} | ||
| */ | ||
| function parse (str, options) { | ||
| var tokens = [] | ||
| var key = 0 | ||
| var index = 0 | ||
| var path = '' | ||
| var defaultDelimiter = options && options.delimiter || '/' | ||
| var res | ||
| while ((res = PATH_REGEXP.exec(str)) != null) { | ||
| var m = res[0] | ||
| var escaped = res[1] | ||
| var offset = res.index | ||
| path += str.slice(index, offset) | ||
| index = offset + m.length | ||
| // Ignore already escaped sequences. | ||
| if (escaped) { | ||
| path += escaped[1] | ||
| continue | ||
| } | ||
| var next = str[index] | ||
| var prefix = res[2] | ||
| var name = res[3] | ||
| var capture = res[4] | ||
| var group = res[5] | ||
| var modifier = res[6] | ||
| var asterisk = res[7] | ||
| // Push the current path onto the tokens. | ||
| if (path) { | ||
| tokens.push(path) | ||
| path = '' | ||
| } | ||
| var partial = prefix != null && next != null && next !== prefix | ||
| var repeat = modifier === '+' || modifier === '*' | ||
| var optional = modifier === '?' || modifier === '*' | ||
| var delimiter = res[2] || defaultDelimiter | ||
| var pattern = capture || group | ||
| tokens.push({ | ||
| name: name || key++, | ||
| prefix: prefix || '', | ||
| delimiter: delimiter, | ||
| optional: optional, | ||
| repeat: repeat, | ||
| partial: partial, | ||
| asterisk: !!asterisk, | ||
| pattern: pattern ? escapeGroup(pattern) : (asterisk ? '.*' : '[^' + escapeString(delimiter) + ']+?') | ||
| }) | ||
| } | ||
| // Match any characters still remaining. | ||
| if (index < str.length) { | ||
| path += str.substr(index) | ||
| } | ||
| // If the path exists, push it onto the end. | ||
| if (path) { | ||
| tokens.push(path) | ||
| } | ||
| return tokens | ||
| } | ||
| /** | ||
| * Compile a string to a template function for the path. | ||
| * | ||
| * @param {string} str | ||
| * @param {Object=} options | ||
| * @return {!function(Object=, Object=)} | ||
| */ | ||
| function compile (str, options) { | ||
| return tokensToFunction(parse(str, options)) | ||
| } | ||
| /** | ||
| * Prettier encoding of URI path segments. | ||
| * | ||
| * @param {string} | ||
| * @return {string} | ||
| */ | ||
| function encodeURIComponentPretty (str) { | ||
| return encodeURI(str).replace(/[\/?#]/g, function (c) { | ||
| return '%' + c.charCodeAt(0).toString(16).toUpperCase() | ||
| }) | ||
| } | ||
| /** | ||
| * Encode the asterisk parameter. Similar to `pretty`, but allows slashes. | ||
| * | ||
| * @param {string} | ||
| * @return {string} | ||
| */ | ||
| function encodeAsterisk (str) { | ||
| return encodeURI(str).replace(/[?#]/g, function (c) { | ||
| return '%' + c.charCodeAt(0).toString(16).toUpperCase() | ||
| }) | ||
| } | ||
| /** | ||
| * Expose a method for transforming tokens into the path function. | ||
| */ | ||
| function tokensToFunction (tokens) { | ||
| // Compile all the tokens into regexps. | ||
| var matches = new Array(tokens.length) | ||
| // Compile all the patterns before compilation. | ||
| for (var i = 0; i < tokens.length; i++) { | ||
| if (typeof tokens[i] === 'object') { | ||
| matches[i] = new RegExp('^(?:' + tokens[i].pattern + ')$') | ||
| } | ||
| } | ||
| return function (obj, opts) { | ||
| var path = '' | ||
| var data = obj || {} | ||
| var options = opts || {} | ||
| var encode = options.pretty ? encodeURIComponentPretty : encodeURIComponent | ||
| for (var i = 0; i < tokens.length; i++) { | ||
| var token = tokens[i] | ||
| if (typeof token === 'string') { | ||
| path += token | ||
| continue | ||
| } | ||
| var value = data[token.name] | ||
| var segment | ||
| if (value == null) { | ||
| if (token.optional) { | ||
| // Prepend partial segment prefixes. | ||
| if (token.partial) { | ||
| path += token.prefix | ||
| } | ||
| continue | ||
| } else { | ||
| throw new TypeError('Expected "' + token.name + '" to be defined') | ||
| } | ||
| } | ||
| if (isarray(value)) { | ||
| if (!token.repeat) { | ||
| throw new TypeError('Expected "' + token.name + '" to not repeat, but received `' + JSON.stringify(value) + '`') | ||
| } | ||
| if (value.length === 0) { | ||
| if (token.optional) { | ||
| continue | ||
| } else { | ||
| throw new TypeError('Expected "' + token.name + '" to not be empty') | ||
| } | ||
| } | ||
| for (var j = 0; j < value.length; j++) { | ||
| segment = encode(value[j]) | ||
| if (!matches[i].test(segment)) { | ||
| throw new TypeError('Expected all "' + token.name + '" to match "' + token.pattern + '", but received `' + JSON.stringify(segment) + '`') | ||
| } | ||
| path += (j === 0 ? token.prefix : token.delimiter) + segment | ||
| } | ||
| continue | ||
| } | ||
| segment = token.asterisk ? encodeAsterisk(value) : encode(value) | ||
| if (!matches[i].test(segment)) { | ||
| throw new TypeError('Expected "' + token.name + '" to match "' + token.pattern + '", but received "' + segment + '"') | ||
| } | ||
| path += token.prefix + segment | ||
| } | ||
| return path | ||
| } | ||
| } | ||
| /** | ||
| * Escape a regular expression string. | ||
| * | ||
| * @param {string} str | ||
| * @return {string} | ||
| */ | ||
| function escapeString (str) { | ||
| return str.replace(/([.+*?=^!:${}()[\]|\/\\])/g, '\\$1') | ||
| } | ||
| /** | ||
| * Escape the capturing group by escaping special characters and meaning. | ||
| * | ||
| * @param {string} group | ||
| * @return {string} | ||
| */ | ||
| function escapeGroup (group) { | ||
| return group.replace(/([=!:$\/()])/g, '\\$1') | ||
| } | ||
| /** | ||
| * Attach the keys as a property of the regexp. | ||
| * | ||
| * @param {!RegExp} re | ||
| * @param {Array} keys | ||
| * @return {!RegExp} | ||
| */ | ||
| function attachKeys (re, keys) { | ||
| re.keys = keys | ||
| return re | ||
| } | ||
| /** | ||
| * Get the flags for a regexp from the options. | ||
| * | ||
| * @param {Object} options | ||
| * @return {string} | ||
| */ | ||
| function flags (options) { | ||
| return options.sensitive ? '' : 'i' | ||
| } | ||
| /** | ||
| * Pull out keys from a regexp. | ||
| * | ||
| * @param {!RegExp} path | ||
| * @param {!Array} keys | ||
| * @return {!RegExp} | ||
| */ | ||
| function regexpToRegexp (path, keys) { | ||
| // Use a negative lookahead to match only capturing groups. | ||
| var groups = path.source.match(/\((?!\?)/g) | ||
| if (groups) { | ||
| for (var i = 0; i < groups.length; i++) { | ||
| keys.push({ | ||
| name: i, | ||
| prefix: null, | ||
| delimiter: null, | ||
| optional: false, | ||
| repeat: false, | ||
| partial: false, | ||
| asterisk: false, | ||
| pattern: null | ||
| }) | ||
| } | ||
| } | ||
| return attachKeys(path, keys) | ||
| } | ||
| /** | ||
| * Transform an array into a regexp. | ||
| * | ||
| * @param {!Array} path | ||
| * @param {Array} keys | ||
| * @param {!Object} options | ||
| * @return {!RegExp} | ||
| */ | ||
| function arrayToRegexp (path, keys, options) { | ||
| var parts = [] | ||
| for (var i = 0; i < path.length; i++) { | ||
| parts.push(pathToRegexp(path[i], keys, options).source) | ||
| } | ||
| var regexp = new RegExp('(?:' + parts.join('|') + ')', flags(options)) | ||
| return attachKeys(regexp, keys) | ||
| } | ||
| /** | ||
| * Create a path regexp from string input. | ||
| * | ||
| * @param {string} path | ||
| * @param {!Array} keys | ||
| * @param {!Object} options | ||
| * @return {!RegExp} | ||
| */ | ||
| function stringToRegexp (path, keys, options) { | ||
| return tokensToRegExp(parse(path, options), keys, options) | ||
| } | ||
| /** | ||
| * Expose a function for taking tokens and returning a RegExp. | ||
| * | ||
| * @param {!Array} tokens | ||
| * @param {(Array|Object)=} keys | ||
| * @param {Object=} options | ||
| * @return {!RegExp} | ||
| */ | ||
| function tokensToRegExp (tokens, keys, options) { | ||
| if (!isarray(keys)) { | ||
| options = /** @type {!Object} */ (keys || options) | ||
| keys = [] | ||
| } | ||
| options = options || {} | ||
| var strict = options.strict | ||
| var end = options.end !== false | ||
| var route = '' | ||
| // Iterate over the tokens and create our regexp string. | ||
| for (var i = 0; i < tokens.length; i++) { | ||
| var token = tokens[i] | ||
| if (typeof token === 'string') { | ||
| route += escapeString(token) | ||
| } else { | ||
| var prefix = escapeString(token.prefix) | ||
| var capture = '(?:' + token.pattern + ')' | ||
| keys.push(token) | ||
| if (token.repeat) { | ||
| capture += '(?:' + prefix + capture + ')*' | ||
| } | ||
| if (token.optional) { | ||
| if (!token.partial) { | ||
| capture = '(?:' + prefix + '(' + capture + '))?' | ||
| } else { | ||
| capture = prefix + '(' + capture + ')?' | ||
| } | ||
| } else { | ||
| capture = prefix + '(' + capture + ')' | ||
| } | ||
| route += capture | ||
| } | ||
| } | ||
| var delimiter = escapeString(options.delimiter || '/') | ||
| var endsWithDelimiter = route.slice(-delimiter.length) === delimiter | ||
| // In non-strict mode we allow a slash at the end of match. If the path to | ||
| // match already ends with a slash, we remove it for consistency. The slash | ||
| // is valid at the end of a path match, not in the middle. This is important | ||
| // in non-ending mode, where "/test/" shouldn't match "/test//route". | ||
| if (!strict) { | ||
| route = (endsWithDelimiter ? route.slice(0, -delimiter.length) : route) + '(?:' + delimiter + '(?=$))?' | ||
| } | ||
| if (end) { | ||
| route += '$' | ||
| } else { | ||
| // In non-ending mode, we need the capturing groups to match as much as | ||
| // possible by using a positive lookahead to the end or next path segment. | ||
| route += strict && endsWithDelimiter ? '' : '(?=' + delimiter + '|$)' | ||
| } | ||
| return attachKeys(new RegExp('^' + route, flags(options)), keys) | ||
| } | ||
| /** | ||
| * Normalize the given path string, returning a regular expression. | ||
| * | ||
| * An empty array can be passed in for the keys, which will hold the | ||
| * placeholder key descriptions. For example, using `/user/:id`, `keys` will | ||
| * contain `[{ name: 'id', delimiter: '/', optional: false, repeat: false }]`. | ||
| * | ||
| * @param {(string|RegExp|Array)} path | ||
| * @param {(Array|Object)=} keys | ||
| * @param {Object=} options | ||
| * @return {!RegExp} | ||
| */ | ||
| function pathToRegexp (path, keys, options) { | ||
| if (!isarray(keys)) { | ||
| options = /** @type {!Object} */ (keys || options) | ||
| keys = [] | ||
| } | ||
| options = options || {} | ||
| if (path instanceof RegExp) { | ||
| return regexpToRegexp(path, /** @type {!Array} */ (keys)) | ||
| } | ||
| if (isarray(path)) { | ||
| return arrayToRegexp(/** @type {!Array} */ (path), /** @type {!Array} */ (keys), options) | ||
| } | ||
| return stringToRegexp(/** @type {string} */ (path), /** @type {!Array} */ (keys), options) | ||
| } | ||
| /***/ }), | ||
| /* 3 */ | ||
| /***/ (function(module, exports, __webpack_require__) { | ||
| "use strict"; | ||
| var router_1 = __webpack_require__(0); | ||
| window['router'] = new router_1.Router(window); | ||
| /***/ }) | ||
| /******/ ]); | ||
| //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vd2VicGFjay9ib290c3RyYXAgZWUzZWUwMjRiZWVhNjZlZjBkYmMiLCJ3ZWJwYWNrOi8vLy4vc3JjL3JvdXRlci50cyIsIndlYnBhY2s6Ly8vLi9+L2lzYXJyYXkvaW5kZXguanMiLCJ3ZWJwYWNrOi8vLy4vfi9wYXRoLXRvLXJlZ2V4cC9pbmRleC5qcyIsIndlYnBhY2s6Ly8vLi9zcmMvYnJvd3Nlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0EsbURBQTJDLGNBQWM7O0FBRXpEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBSztBQUNMO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsbUNBQTJCLDBCQUEwQixFQUFFO0FBQ3ZELHlDQUFpQyxlQUFlO0FBQ2hEO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLDhEQUFzRCwrREFBK0Q7O0FBRXJIO0FBQ0E7O0FBRUE7QUFDQTs7Ozs7Ozs7QUNoRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxxQkFBcUI7QUFDckI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMENBQTBDLGdCQUFnQjtBQUMxRDtBQUNBO0FBQ0E7QUFD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QVksT0FBTztBQUNuQixZQUFZLE9BQU87QUFDbkIsWUFBWSxRQUFRO0FBQ3BCLFlBQVk7QUFDWjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxZQUFZLE9BQU87QUFDbkIsWUFBWSxnQkFBZ0I7QUFDNUIsWUFBWSxRQUFRO0FBQ3BCLFlBQVk7QUFDWjtBQUNBO0FBQ0E7QUFDQSx5QkFBeUIsUUFBUTtBQUNqQztBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLGlCQUFpQixtQkFBbUI7QUFDcEM7O0FBRUE7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBLE9BQU87QUFDUDtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxHQUFHO0FBQ0g7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYyw2REFBNkQ7QUFDM0U7QUFDQSxZQUFZLHNCQUFzQjtBQUNsQyxZQUFZLGdCQUFnQjtBQUM1QixZQUFZLFFBQVE7QUFDcEIsWUFBWTtBQUNaO0FBQ0E7QUFDQTtBQUNBLHlCQUF5QixRQUFRO0FBQ2pDO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQSwyQ0FBMkMsT0FBTztBQUNsRDs7QUFFQTtBQUNBLG9DQUFvQyxPQUFPLHVCQUF1QixPQUFPO0FBQ3pFOztBQUVBLG1DQUFtQyxPQUFPLHVCQUF1QixPQUFPO0FBQ3hFOzs7Ozs7OztBQ3phQTtBQUNBO0FBQ0EiLCJmaWxlIjoicm91Z2h0ZXIuanMiLCJzb3VyY2VzQ29udGVudCI6WyIgXHQvLyBUaGUgbW9kdWxlIGNhY2hlXG4gXHR2YXIgaW5zdGFsbGVkTW9kdWxlcyA9IHt9O1xuXG4gXHQvLyBUaGUgcmVxdWlyZSBmdW5jdGlvblxuIFx0ZnVuY3Rpb24gX193ZWJwYWNrX3JlcXVpcmVfXyhtb2R1bGVJZCkge1xuXG4gXHRcdC8vIENoZWNrIGlmIG1vZHVsZSBpcyBpbiBjYWNoZVxuIFx0XHRpZihpbnN0YWxsZWRNb2R1bGVzW21vZHVsZUlkXSlcbiBcdFx0XHRyZXR1cm4gaW5zdGFsbGVkTW9kdWxlc1ttb2R1bGVJZF0uZXhwb3J0cztcblxuIFx0XHQvLyBDcmVhdGUgYSBuZXcgbW9kdWxlIChhbmQgcHV0IGl0IGludG8gdGhlIGNhY2hlKVxuIFx0XHR2YXIgbW9kdWxlID0gaW5zdGFsbGVkTW9kdWxlc1ttb2R1bGVJZF0gPSB7XG4gXHRcdFx0aTogbW9kdWxlSWQsXG4gXHRcdFx0bDogZmFsc2UsXG4gXHRcdFx0ZXhwb3J0czoge31cbiBcdFx0fTtcblxuIFx0XHQvLyBFeGVjdXRlIHRoZSBtb2R1bGUgZnVuY3Rpb25cbiBcdFx0bW9kdWxlc1ttb2R1bGVJZF0uY2FsbChtb2R1bGUuZXhwb3J0cywgbW9kdWxlLCBtb2R1bGUuZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXyk7XG5cbiBcdFx0Ly8gRmxhZyB0aGUgbW9kdWxlIGFzIGxvYWRlZFxuIFx0XHRtb2R1bGUubCA9IHRydWU7XG5cbiBcdFx0Ly8gUmV0dXJuIHRoZSBleHBvcnRzIG9mIHRoZSBtb2R1bGVcbiBcdFx0cmV0dXJuIG1vZHVsZS5leHBvcnRzO1xuIFx0fVxuXG5cbiBcdC8vIGV4cG9zZSB0aGUgbW9kdWxlcyBvYmplY3QgKF9fd2VicGFja19tb2R1bGVzX18pXG4gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLm0gPSBtb2R1bGVzO1xuXG4gXHQvLyBleHBvc2UgdGhlIG1vZHVsZSBjYWNoZVxuIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5jID0gaW5zdGFsbGVkTW9kdWxlcztcblxuIFx0Ly8gaWRlbnRpdHkgZnVuY3Rpb24gZm9yIGNhbGxpbmcgaGFybW9ueSBpbXBvcnRzIHdpdGggdGhlIGNvcnJlY3QgY29udGV4dFxuIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5pID0gZnVuY3Rpb24odmFsdWUpIHsgcmV0dXJuIHZhbHVlOyB9O1xuXG4gXHQvLyBkZWZpbmUgZ2V0dGVyIGZ1bmN0aW9uIGZvciBoYXJtb255IGV4cG9ydHNcbiBcdF9fd2VicGFja19yZXF1aXJlX18uZCA9IGZ1bmN0aW9uKGV4cG9ydHMsIG5hbWUsIGdldHRlcikge1xuIFx0XHRpZighX193ZWJwYWNrX3JlcXVpcmVfXy5vKGV4cG9ydHMsIG5hbWUpKSB7XG4gXHRcdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIG5hbWUsIHtcbiBcdFx0XHRcdGNvbmZpZ3VyYWJsZTogZmFsc2UsXG4gXHRcdFx0XHRlbnVtZXJhYmxlOiB0cnVlLFxuIFx0XHRcdFx0Z2V0OiBnZXR0ZXJcbiBcdFx0XHR9KTtcbiBcdFx0fVxuIFx0fTtcblxuIFx0Ly8gZ2V0RGVmYXVsdEV4cG9ydCBmdW5jdGlvbiBmb3IgY29tcGF0aWJpbGl0eSB3aXRoIG5vbi1oYXJtb255IG1vZHVsZXNcbiBcdF9fd2VicGFja19yZXF1aXJlX18ubiA9IGZ1bmN0aW9uKG1vZHVsZSkge1xuIFx0XHR2YXIgZ2V0dGVyID0gbW9kdWxlICYmIG1vZHVsZS5fX2VzTW9kdWxlID9cbiBcdFx0XHRmdW5jdGlvbiBnZXREZWZhdWx0KCkgeyByZXR1cm4gbW9kdWxlWydkZWZhdWx0J107IH0gOlxuIFx0XHRcdGZ1bmN0aW9uIGdldE1vZHVsZUV4cG9ydHMoKSB7IHJldHVybiBtb2R1bGU7IH07XG4gXHRcdF9fd2VicGFja19yZXF1aXJlX18uZChnZXR0ZXIsICdhJywgZ2V0dGVyKTtcbiBcdFx0cmV0dXJuIGdldHRlcjtcbiBcdH07XG5cbiBcdC8vIE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbFxuIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5vID0gZnVuY3Rpb24ob2JqZWN0LCBwcm9wZXJ0eSkgeyByZXR1cm4gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG9iamVjdCwgcHJvcGVydHkpOyB9O1xuXG4gXHQvLyBfX3dlYnBhY2tfcHVibGljX3BhdGhfX1xuIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5wID0gXCJcIjtcblxuIFx0Ly8gTG9hZCBlbnRyeSBtb2R1bGUgYW5kIHJldHVybiBleHBvcnRzXG4gXHRyZXR1cm4gX193ZWJwYWNrX3JlcXVpcmVfXyhfX3dlYnBhY2tfcmVxdWlyZV9fLnMgPSAzKTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyB3ZWJwYWNrL2Jvb3RzdHJhcCBlZTNlZTAyNGJlZWE2NmVmMGRiYyIsIlwidXNlIHN0cmljdFwiO1xudmFyIHBhdGhUb1JlZ2V4cCA9IHJlcXVpcmUoXCJwYXRoLXRvLXJlZ2V4cFwiKTtcbmZ1bmN0aW9uIGhhc2hwYXRoKCkge1xuICAgIC8vIGN1dCBwcmVmaXggJyMnXG4gICAgcmV0dXJuIHdpbmRvdy5sb2NhdGlvbi5oYXNoLnNsaWNlKDEpO1xufVxudmFyIFJvdXRlciA9IChmdW5jdGlvbiAoKSB7XG4gICAgLy8gcHJpdmF0ZSBoYXNoQ3VycmVudCgpIDogc3RyaW5nIHtcbiAgICAvLyBcdHJldHVybiBoYXNocGF0aCgpXG4gICAgLy8gfVxuICAgIC8vIHByaXZhdGUgaGFzaFByZXZpb3VzKCkgOiBzdHJpbmcge1xuICAgIC8vIFx0cmV0dXJuIHRoaXMucHJldmlvdXNcbiAgICAvLyB9XG4gICAgLy8gcHJpdmF0ZSBoYXNoUm91dGVzKCkgOiBSb3V0ZVtdIHtcbiAgICAvLyBcdHJldHVybiB0aGlzLnJvdXRlc1xuICAgIC8vIH1cbiAgICBmdW5jdGlvbiBSb3V0ZXIod2luZG93KSB7XG4gICAgICAgIHRoaXMucm91dGVzID0gW107XG4gICAgICAgIHRoaXMud2luZG93ID0gd2luZG93O1xuICAgIH1cbiAgICBSb3V0ZXIucHJvdG90eXBlLmhhc2ggPSBmdW5jdGlvbiAocGF0aCwgYXJnKSB7XG4gICAgICAgIC8vaWYgKHBhdGggPT09IHVuZGVmaW5lZCkgdGhyb3cgbmV3IFR5cGVFcnJvcignaW52YWxpZCBhcmd1bWVudCBhcmdbMTpwYXRoXScpXG4gICAgICAgIC8vaWYgKGFyZyA9PT0gdW5kZWZpbmVkKSB0aHJvdyBuZXcgVHlwZUVycm9yKCdpbnZhbGlkIGFyZ3VtZW50IGFyZ1syOmFyZ10nKVxuICAgICAgICB2YXIga2V5cyA9IFtdO1xuICAgICAgICB2YXIgcmUgPSBwYXRoVG9SZWdleHAocGF0aCwga2V5cyk7XG4gICAgICAgIHZhciByb3V0ZSA9IHsgcmU6IHJlLCBrZXlzOiBrZXlzIH07XG4gICAgICAgIGlmICh0eXBlb2YgYXJnID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICByb3V0ZS5jYWxsYmFjayA9IGFyZztcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJvdXRlLmNhbGxiYWNrID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIC8vIFRPRE9cbiAgICAgICAgICAgICAgICAvL3Jpb3Qucm91dGUoYXJnKVxuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnJvdXRlcy5wdXNoKHJvdXRlKTtcbiAgICB9O1xuICAgIFJvdXRlci5wcm90b3R5cGUuc3RhcnQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMud2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ2hhc2hjaGFuZ2UnLCB0aGlzLm9uSGFzaENoYW5nZWQsIGZhbHNlKTtcbiAgICAgICAgdmFyIGhhc2ggPSBoYXNocGF0aCgpO1xuICAgICAgICBpZiAoaGFzaC5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICB0aGlzLmRpc3BhdGNoKGhhc2gpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICBSb3V0ZXIucHJvdG90eXBlLnN0b3AgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMud2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2hhc2hjaGFuZ2UnLCB0aGlzLm9uSGFzaENoYW5nZWQsIGZhbHNlKTtcbiAgICB9O1xuICAgIFJvdXRlci5wcm90b3R5cGUub25IYXNoQ2hhbmdlZCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5kaXNwYXRjaChoYXNocGF0aCgpKTtcbiAgICB9O1xuICAgIFJvdXRlci5wcm90b3R5cGUuZGlzcGF0Y2ggPSBmdW5jdGlvbiAocGF0aCkge1xuICAgICAgICBpZiAoIXBhdGgpIHtcbiAgICAgICAgICAgIHBhdGggPSBoYXNocGF0aCgpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICB9XG4gICAgICAgIGZvciAodmFyIF9pID0gMCwgX2EgPSB0aGlzLnJvdXRlczsgX2kgPCBfYS5sZW5ndGg7IF9pKyspIHtcbiAgICAgICAgICAgIHZhciByb3V0ZSA9IF9hW19pXTtcbiAgICAgICAgICAgIHZhciByZXN1bHQgPSByb3V0ZS5yZS5leGVjKHBhdGgpO1xuICAgICAgICAgICAgaWYgKHJlc3VsdCkge1xuICAgICAgICAgICAgICAgIHJvdXRlLmNhbGxiYWNrLmFwcGx5KHRoaXMsIHJlc3VsdC5zbGljZSgxKSk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9O1xuICAgIHJldHVybiBSb3V0ZXI7XG59KCkpO1xuZXhwb3J0cy5Sb3V0ZXIgPSBSb3V0ZXI7XG5cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL3NyYy9yb3V0ZXIudHNcbi8vIG1vZHVsZSBpZCA9IDBcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwibW9kdWxlLmV4cG9ydHMgPSBBcnJheS5pc0FycmF5IHx8IGZ1bmN0aW9uIChhcnIpIHtcbiAgcmV0dXJuIE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChhcnIpID09ICdbb2JqZWN0IEFycmF5XSc7XG59O1xuXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9+L2lzYXJyYXkvaW5kZXguanNcbi8vIG1vZHVsZSBpZCA9IDFcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwidmFyIGlzYXJyYXkgPSByZXF1aXJlKCdpc2FycmF5JylcblxuLyoqXG4gKiBFeHBvc2UgYHBhdGhUb1JlZ2V4cGAuXG4gKi9cbm1vZHVsZS5leHBvcnRzID0gcGF0aFRvUmVnZXhwXG5tb2R1bGUuZXhwb3J0cy5wYXJzZSA9IHBhcnNlXG5tb2R1bGUuZXhwb3J0cy5jb21waWxlID0gY29tcGlsZVxubW9kdWxlLmV4cG9ydHMudG9rZW5zVG9GdW5jdGlvbiA9IHRva2Vuc1RvRnVuY3Rpb25cbm1vZHVsZS5leHBvcnRzLnRva2Vuc1RvUmVnRXhwID0gdG9rZW5zVG9SZWdFeHBcblxuLyoqXG4gKiBUaGUgbWFpbiBwYXRoIG1hdGNoaW5nIHJlZ2V4cCB1dGlsaXR5LlxuICpcbiAqIEB0eXBlIHtSZWdFeHB9XG4gKi9cbnZhciBQQVRIX1JFR0VYUCA9IG5ldyBSZWdFeHAoW1xuICAvLyBNYXRjaCBlc2NhcGVkIGNoYXJhY3RlcnMgdGhhdCB3b3VsZCBvdGhlcndpc2UgYXBwZWFyIGluIGZ1dHVyZSBtYXRjaGVzLlxuICAvLyBUaGlzIGFsbG93cyB0aGUgdXNlciB0byBlc2NhcGUgc3BlY2lhbCBjaGFyYWN0ZXJzIHRoYXQgd29uJ3QgdHJhbnNmb3JtLlxuICAnKFxcXFxcXFxcLiknLFxuICAvLyBNYXRjaCBFeHByZXNzLXN0eWxlIHBhcmFtZXRlcnMgYW5kIHVuLW5hbWVkIHBhcmFtZXRlcnMgd2l0aCBhIHByZWZpeFxuICAvLyBhbmQgb3B0aW9uYWwgc3VmZml4ZXMuIE1hdGNoZXMgYXBwZWFyIGFzOlxuICAvL1xuICAvLyBcIi86dGVzdChcXFxcZCspP1wiID0+IFtcIi9cIiwgXCJ0ZXN0XCIsIFwiXFxkK1wiLCB1bmRlZmluZWQsIFwiP1wiLCB1bmRlZmluZWRdXG4gIC8vIFwiL3JvdXRlKFxcXFxkKylcIiAgPT4gW3VuZGVmaW5lZCwgdW5kZWZpbmVkLCB1bmRlZmluZWQsIFwiXFxkK1wiLCB1bmRlZmluZWQsIHVuZGVmaW5lZF1cbiAgLy8gXCIvKlwiICAgICAgICAgICAgPT4gW1wiL1wiLCB1bmRlZmluZWQsIHVuZGVmaW5lZCwgdW5kZWZpbmVkLCB1bmRlZmluZWQsIFwiKlwiXVxuICAnKFtcXFxcLy5dKT8oPzooPzpcXFxcOihcXFxcdyspKD86XFxcXCgoKD86XFxcXFxcXFwufFteXFxcXFxcXFwoKV0pKylcXFxcKSk/fFxcXFwoKCg/OlxcXFxcXFxcLnxbXlxcXFxcXFxcKCldKSspXFxcXCkpKFsrKj9dKT98KFxcXFwqKSknXG5dLmpvaW4oJ3wnKSwgJ2cnKVxuXG4vKipcbiAqIFBhcnNlIGEgc3RyaW5nIGZvciB0aGUgcmF3IHRva2Vucy5cbiAqXG4gKiBAcGFyYW0gIHtzdHJpbmd9ICBzdHJcbiAqIEBwYXJhbSAge09iamVjdD19IG9wdGlvbnNcbiAqIEByZXR1cm4geyFBcnJheX1cbiAqL1xuZnVuY3Rpb24gcGFyc2UgKHN0ciwgb3B0aW9ucykge1xuICB2YXIgdG9rZW5zID0gW11cbiAgdmFyIGtleSA9IDBcbiAgdmFyIGluZGV4ID0gMFxuICB2YXIgcGF0aCA9ICcnXG4gIHZhciBkZWZhdWx0RGVsaW1pdGVyID0gb3B0aW9ucyAmJiBvcHRpb25zLmRlbGltaXRlciB8fCAnLydcbiAgdmFyIHJlc1xuXG4gIHdoaWxlICgocmVzID0gUEFUSF9SRUdFWFAuZXhlYyhzdHIpKSAhPSBudWxsKSB7XG4gICAgdmFyIG0gPSByZXNbMF1cbiAgICB2YXIgZXNjYXBlZCA9IHJlc1sxXVxuICAgIHZhciBvZmZzZXQgPSByZXMuaW5kZXhcbiAgICBwYXRoICs9IHN0ci5zbGljZShpbmRleCwgb2Zmc2V0KVxuICAgIGluZGV4ID0gb2Zmc2V0ICsgbS5sZW5ndGhcblxuICAgIC8vIElnbm9yZSBhbHJlYWR5IGVzY2FwZWQgc2VxdWVuY2VzLlxuICAgIGlmIChlc2NhcGVkKSB7XG4gICAgICBwYXRoICs9IGVzY2FwZWRbMV1cbiAgICAgIGNvbnRpbnVlXG4gICAgfVxuXG4gICAgdmFyIG5leHQgPSBzdHJbaW5kZXhdXG4gICAgdmFyIHByZWZpeCA9IHJlc1syXVxuICAgIHZhciBuYW1lID0gcmVzWzNdXG4gICAgdmFyIGNhcHR1cmUgPSByZXNbNF1cbiAgICB2YXIgZ3JvdXAgPSByZXNbNV1cbiAgICB2YXIgbW9kaWZpZXIgPSByZXNbNl1cbiAgICB2YXIgYXN0ZXJpc2sgPSByZXNbN11cblxuICAgIC8vIFB1c2ggdGhlIGN1cnJlbnQgcGF0aCBvbnRvIHRoZSB0b2tlbnMuXG4gICAgaWYgKHBhdGgpIHtcbiAgICAgIHRva2Vucy5wdXNoKHBhdGgpXG4gICAgICBwYXRoID0gJydcbiAgICB9XG5cbiAgICB2YXIgcGFydGlhbCA9IHByZWZpeCAhPSBudWxsICYmIG5leHQgIT0gbnVsbCAmJiBuZXh0ICE9PSBwcmVmaXhcbiAgICB2YXIgcmVwZWF0ID0gbW9kaWZpZXIgPT09ICcrJyB8fCBtb2RpZmllciA9PT0gJyonXG4gICAgdmFyIG9wdGlvbmFsID0gbW9kaWZpZXIgPT09ICc/JyB8fCBtb2RpZmllciA9PT0gJyonXG4gICAgdmFyIGRlbGltaXRlciA9IHJlc1syXSB8fCBkZWZhdWx0RGVsaW1pdGVyXG4gICAgdmFyIHBhdHRlcm4gPSBjYXB0dXJlIHx8IGdyb3VwXG5cbiAgICB0b2tlbnMucHVzaCh7XG4gICAgICBuYW1lOiBuYW1lIHx8IGtleSsrLFxuICAgICAgcHJlZml4OiBwcmVmaXggfHwgJycsXG4gICAgICBkZWxpbWl0ZXI6IGRlbGltaXRlcixcbiAgICAgIG9wdGlvbmFsOiBvcHRpb25hbCxcbiAgICAgIHJlcGVhdDogcmVwZWF0LFxuICAgICAgcGFydGlhbDogcGFydGlhbCxcbiAgICAgIGFzdGVyaXNrOiAhIWFzdGVyaXNrLFxuICAgICAgcGF0dGVybjogcGF0dGVybiA/IGVzY2FwZUdyb3VwKHBhdHRlcm4pIDogKGFzdGVyaXNrID8gJy4qJyA6ICdbXicgKyBlc2NhcGVTdHJpbmcoZGVsaW1pdGVyKSArICddKz8nKVxuICAgIH0pXG4gIH1cblxuICAvLyBNYXRjaCBhbnkgY2hhcmFjdGVycyBzdGlsbCByZW1haW5pbmcuXG4gIGlmIChpbmRleCA8IHN0ci5sZW5ndGgpIHtcbiAgICBwYXRoICs9IHN0ci5zdWJzdHIoaW5kZXgpXG4gIH1cblxuICAvLyBJZiB0aGUgcGF0aCBleGlzdHMsIHB1c2ggaXQgb250byB0aGUgZW5kLlxuICBpZiAocGF0aCkge1xuICAgIHRva2Vucy5wdXNoKHBhdGgpXG4gIH1cblxuICByZXR1cm4gdG9rZW5zXG59XG5cbi8qKlxuICogQ29tcGlsZSBhIHN0cmluZyB0byBhIHRlbXBsYXRlIGZ1bmN0aW9uIGZvciB0aGUgcGF0aC5cbiAqXG4gKiBAcGFyYW0gIHtzdHJpbmd9ICAgICAgICAgICAgIHN0clxuICogQHBhcmFtICB7T2JqZWN0PX0gICAgICAgICAgICBvcHRpb25zXG4gKiBAcmV0dXJuIHshZnVuY3Rpb24oT2JqZWN0PSwgT2JqZWN0PSl9XG4gKi9cbmZ1bmN0aW9uIGNvbXBpbGUgKHN0ciwgb3B0aW9ucykge1xuICByZXR1cm4gdG9rZW5zVG9GdW5jdGlvbihwYXJzZShzdHIsIG9wdGlvbnMpKVxufVxuXG4vKipcbiAqIFByZXR0aWVyIGVuY29kaW5nIG9mIFVSSSBwYXRoIHNlZ21lbnRzLlxuICpcbiAqIEBwYXJhbSAge3N0cmluZ31cbiAqIEByZXR1cm4ge3N0cmluZ31cbiAqL1xuZnVuY3Rpb24gZW5jb2RlVVJJQ29tcG9uZW50UHJldHR5IChzdHIpIHtcbiAgcmV0dXJuIGVuY29kZVVSSShzdHIpLnJlcGxhY2UoL1tcXC8/I10vZywgZnVuY3Rpb24gKGMpIHtcbiAgICByZXR1cm4gJyUnICsgYy5jaGFyQ29kZUF0KDApLnRvU3RyaW5nKDE2KS50b1VwcGVyQ2FzZSgpXG4gIH0pXG59XG5cbi8qKlxuICogRW5jb2RlIHRoZSBhc3RlcmlzayBwYXJhbWV0ZXIuIFNpbWlsYXIgdG8gYHByZXR0eWAsIGJ1dCBhbGxvd3Mgc2xhc2hlcy5cbiAqXG4gKiBAcGFyYW0gIHtzdHJpbmd9XG4gKiBAcmV0dXJuIHtzdHJpbmd9XG4gKi9cbmZ1bmN0aW9uIGVuY29kZUFzdGVyaXNrIChzdHIpIHtcbiAgcmV0dXJuIGVuY29kZVVSSShzdHIpLnJlcGxhY2UoL1s/I10vZywgZnVuY3Rpb24gKGMpIHtcbiAgICByZXR1cm4gJyUnICsgYy5jaGFyQ29kZUF0KDApLnRvU3RyaW5nKDE2KS50b1VwcGVyQ2FzZSgpXG4gIH0pXG59XG5cbi8qKlxuICogRXhwb3NlIGEgbWV0aG9kIGZvciB0cmFuc2Zvcm1pbmcgdG9rZW5zIGludG8gdGhlIHBhdGggZnVuY3Rpb24uXG4gKi9cbmZ1bmN0aW9uIHRva2Vuc1RvRnVuY3Rpb24gKHRva2Vucykge1xuICAvLyBDb21waWxlIGFsbCB0aGUgdG9rZW5zIGludG8gcmVnZXhwcy5cbiAgdmFyIG1hdGNoZXMgPSBuZXcgQXJyYXkodG9rZW5zLmxlbmd0aClcblxuICAvLyBDb21waWxlIGFsbCB0aGUgcGF0dGVybnMgYmVmb3JlIGNvbXBpbGF0aW9uLlxuICBmb3IgKHZhciBpID0gMDsgaSA8IHRva2Vucy5sZW5ndGg7IGkrKykge1xuICAgIGlmICh0eXBlb2YgdG9rZW5zW2ldID09PSAnb2JqZWN0Jykge1xuICAgICAgbWF0Y2hlc1tpXSA9IG5ldyBSZWdFeHAoJ14oPzonICsgdG9rZW5zW2ldLnBhdHRlcm4gKyAnKSQnKVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBmdW5jdGlvbiAob2JqLCBvcHRzKSB7XG4gICAgdmFyIHBhdGggPSAnJ1xuICAgIHZhciBkYXRhID0gb2JqIHx8IHt9XG4gICAgdmFyIG9wdGlvbnMgPSBvcHRzIHx8IHt9XG4gICAgdmFyIGVuY29kZSA9IG9wdGlvbnMucHJldHR5ID8gZW5jb2RlVVJJQ29tcG9uZW50UHJldHR5IDogZW5jb2RlVVJJQ29tcG9uZW50XG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRva2Vucy5sZW5ndGg7IGkrKykge1xuICAgICAgdmFyIHRva2VuID0gdG9rZW5zW2ldXG5cbiAgICAgIGlmICh0eXBlb2YgdG9rZW4gPT09ICdzdHJpbmcnKSB7XG4gICAgICAgIHBhdGggKz0gdG9rZW5cblxuICAgICAgICBjb250aW51ZVxuICAgICAgfVxuXG4gICAgICB2YXIgdmFsdWUgPSBkYXRhW3Rva2VuLm5hbWVdXG4gICAgICB2YXIgc2VnbWVudFxuXG4gICAgICBpZiAodmFsdWUgPT0gbnVsbCkge1xuICAgICAgICBpZiAodG9rZW4ub3B0aW9uYWwpIHtcbiAgICAgICAgICAvLyBQcmVwZW5kIHBhcnRpYWwgc2VnbWVudCBwcmVmaXhlcy5cbiAgICAgICAgICBpZiAodG9rZW4ucGFydGlhbCkge1xuICAgICAgICAgICAgcGF0aCArPSB0b2tlbi5wcmVmaXhcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBjb250aW51ZVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0V4cGVjdGVkIFwiJyArIHRva2VuLm5hbWUgKyAnXCIgdG8gYmUgZGVmaW5lZCcpXG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKGlzYXJyYXkodmFsdWUpKSB7XG4gICAgICAgIGlmICghdG9rZW4ucmVwZWF0KSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignRXhwZWN0ZWQgXCInICsgdG9rZW4ubmFtZSArICdcIiB0byBub3QgcmVwZWF0LCBidXQgcmVjZWl2ZWQgYCcgKyBKU09OLnN0cmluZ2lmeSh2YWx1ZSkgKyAnYCcpXG4gICAgICAgIH1cblxuICAgICAgICBpZiAodmFsdWUubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgaWYgKHRva2VuLm9wdGlvbmFsKSB7XG4gICAgICAgICAgICBjb250aW51ZVxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdFeHBlY3RlZCBcIicgKyB0b2tlbi5uYW1lICsgJ1wiIHRvIG5vdCBiZSBlbXB0eScpXG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCB2YWx1ZS5sZW5ndGg7IGorKykge1xuICAgICAgICAgIHNlZ21lbnQgPSBlbmNvZGUodmFsdWVbal0pXG5cbiAgICAgICAgICBpZiAoIW1hdGNoZXNbaV0udGVzdChzZWdtZW50KSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignRXhwZWN0ZWQgYWxsIFwiJyArIHRva2VuLm5hbWUgKyAnXCIgdG8gbWF0Y2ggXCInICsgdG9rZW4ucGF0dGVybiArICdcIiwgYnV0IHJlY2VpdmVkIGAnICsgSlNPTi5zdHJpbmdpZnkoc2VnbWVudCkgKyAnYCcpXG4gICAgICAgICAgfVxuXG4gICAgICAgICAgcGF0aCArPSAoaiA9PT0gMCA/IHRva2VuLnByZWZpeCA6IHRva2VuLmRlbGltaXRlcikgKyBzZWdtZW50XG4gICAgICAgIH1cblxuICAgICAgICBjb250aW51ZVxuICAgICAgfVxuXG4gICAgICBzZWdtZW50ID0gdG9rZW4uYXN0ZXJpc2sgPyBlbmNvZGVBc3Rlcmlzayh2YWx1ZSkgOiBlbmNvZGUodmFsdWUpXG5cbiAgICAgIGlmICghbWF0Y2hlc1tpXS50ZXN0KHNlZ21lbnQpKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0V4cGVjdGVkIFwiJyArIHRva2VuLm5hbWUgKyAnXCIgdG8gbWF0Y2ggXCInICsgdG9rZW4ucGF0dGVybiArICdcIiwgYnV0IHJlY2VpdmVkIFwiJyArIHNlZ21lbnQgKyAnXCInKVxuICAgICAgfVxuXG4gICAgICBwYXRoICs9IHRva2VuLnByZWZpeCArIHNlZ21lbnRcbiAgICB9XG5cbiAgICByZXR1cm4gcGF0aFxuICB9XG59XG5cbi8qKlxuICogRXNjYXBlIGEgcmVndWxhciBleHByZXNzaW9uIHN0cmluZy5cbiAqXG4gKiBAcGFyYW0gIHtzdHJpbmd9IHN0clxuICogQHJldHVybiB7c3RyaW5nfVxuICovXG5mdW5jdGlvbiBlc2NhcGVTdHJpbmcgKHN0cikge1xuICByZXR1cm4gc3RyLnJlcGxhY2UoLyhbLisqPz1eIToke30oKVtcXF18XFwvXFxcXF0pL2csICdcXFxcJDEnKVxufVxuXG4vKipcbiAqIEVzY2FwZSB0aGUgY2FwdHVyaW5nIGdyb3VwIGJ5IGVzY2FwaW5nIHNwZWNpYWwgY2hhcmFjdGVycyBhbmQgbWVhbmluZy5cbiAqXG4gKiBAcGFyYW0gIHtzdHJpbmd9IGdyb3VwXG4gKiBAcmV0dXJuIHtzdHJpbmd9XG4gKi9cbmZ1bmN0aW9uIGVzY2FwZUdyb3VwIChncm91cCkge1xuICByZXR1cm4gZ3JvdXAucmVwbGFjZSgvKFs9ITokXFwvKCldKS9nLCAnXFxcXCQxJylcbn1cblxuLyoqXG4gKiBBdHRhY2ggdGhlIGtleXMgYXMgYSBwcm9wZXJ0eSBvZiB0aGUgcmVnZXhwLlxuICpcbiAqIEBwYXJhbSAgeyFSZWdFeHB9IHJlXG4gKiBAcGFyYW0gIHtBcnJheX0gICBrZXlzXG4gKiBAcmV0dXJuIHshUmVnRXhwfVxuICovXG5mdW5jdGlvbiBhdHRhY2hLZXlzIChyZSwga2V5cykge1xuICByZS5rZXlzID0ga2V5c1xuICByZXR1cm4gcmVcbn1cblxuLyoqXG4gKiBHZXQgdGhlIGZsYWdzIGZvciBhIHJlZ2V4cCBmcm9tIHRoZSBvcHRpb25zLlxuICpcbiAqIEBwYXJhbSAge09iamVjdH0gb3B0aW9uc1xuICogQHJldHVybiB7c3RyaW5nfVxuICovXG5mdW5jdGlvbiBmbGFncyAob3B0aW9ucykge1xuICByZXR1cm4gb3B0aW9ucy5zZW5zaXRpdmUgPyAnJyA6ICdpJ1xufVxuXG4vKipcbiAqIFB1bGwgb3V0IGtleXMgZnJvbSBhIHJlZ2V4cC5cbiAqXG4gKiBAcGFyYW0gIHshUmVnRXhwfSBwYXRoXG4gKiBAcGFyYW0gIHshQXJyYXl9ICBrZXlzXG4gKiBAcmV0dXJuIHshUmVnRXhwfVxuICovXG5mdW5jdGlvbiByZWdleHBUb1JlZ2V4cCAocGF0aCwga2V5cykge1xuICAvLyBVc2UgYSBuZWdhdGl2ZSBsb29rYWhlYWQgdG8gbWF0Y2ggb25seSBjYXB0dXJpbmcgZ3JvdXBzLlxuICB2YXIgZ3JvdXBzID0gcGF0aC5zb3VyY2UubWF0Y2goL1xcKCg/IVxcPykvZylcblxuICBpZiAoZ3JvdXBzKSB7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBncm91cHMubGVuZ3RoOyBpKyspIHtcbiAgICAgIGtleXMucHVzaCh7XG4gICAgICAgIG5hbWU6IGksXG4gICAgICAgIHByZWZpeDogbnVsbCxcbiAgICAgICAgZGVsaW1pdGVyOiBudWxsLFxuICAgICAgICBvcHRpb25hbDogZmFsc2UsXG4gICAgICAgIHJlcGVhdDogZmFsc2UsXG4gICAgICAgIHBhcnRpYWw6IGZhbHNlLFxuICAgICAgICBhc3RlcmlzazogZmFsc2UsXG4gICAgICAgIHBhdHRlcm46IG51bGxcbiAgICAgIH0pXG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGF0dGFjaEtleXMocGF0aCwga2V5cylcbn1cblxuLyoqXG4gKiBUcmFuc2Zvcm0gYW4gYXJyYXkgaW50byBhIHJlZ2V4cC5cbiAqXG4gKiBAcGFyYW0gIHshQXJyYXl9ICBwYXRoXG4gKiBAcGFyYW0gIHtBcnJheX0gICBrZXlzXG4gKiBAcGFyYW0gIHshT2JqZWN0fSBvcHRpb25zXG4gKiBAcmV0dXJuIHshUmVnRXhwfVxuICovXG5mdW5jdGlvbiBhcnJheVRvUmVnZXhwIChwYXRoLCBrZXlzLCBvcHRpb25zKSB7XG4gIHZhciBwYXJ0cyA9IFtdXG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBwYXRoLmxlbmd0aDsgaSsrKSB7XG4gICAgcGFydHMucHVzaChwYXRoVG9SZWdleHAocGF0aFtpXSwga2V5cywgb3B0aW9ucykuc291cmNlKVxuICB9XG5cbiAgdmFyIHJlZ2V4cCA9IG5ldyBSZWdFeHAoJyg/OicgKyBwYXJ0cy5qb2luKCd8JykgKyAnKScsIGZsYWdzKG9wdGlvbnMpKVxuXG4gIHJldHVybiBhdHRhY2hLZXlzKHJlZ2V4cCwga2V5cylcbn1cblxuLyoqXG4gKiBDcmVhdGUgYSBwYXRoIHJlZ2V4cCBmcm9tIHN0cmluZyBpbnB1dC5cbiAqXG4gKiBAcGFyYW0gIHtzdHJpbmd9ICBwYXRoXG4gKiBAcGFyYW0gIHshQXJyYXl9ICBrZXlzXG4gKiBAcGFyYW0gIHshT2JqZWN0fSBvcHRpb25zXG4gKiBAcmV0dXJuIHshUmVnRXhwfVxuICovXG5mdW5jdGlvbiBzdHJpbmdUb1JlZ2V4cCAocGF0aCwga2V5cywgb3B0aW9ucykge1xuICByZXR1cm4gdG9rZW5zVG9SZWdFeHAocGFyc2UocGF0aCwgb3B0aW9ucyksIGtleXMsIG9wdGlvbnMpXG59XG5cbi8qKlxuICogRXhwb3NlIGEgZnVuY3Rpb24gZm9yIHRha2luZyB0b2tlbnMgYW5kIHJldHVybmluZyBhIFJlZ0V4cC5cbiAqXG4gKiBAcGFyYW0gIHshQXJyYXl9ICAgICAgICAgIHRva2Vuc1xuICogQHBhcmFtICB7KEFycmF5fE9iamVjdCk9fSBrZXlzXG4gKiBAcGFyYW0gIHtPYmplY3Q9fSAgICAgICAgIG9wdGlvbnNcbiAqIEByZXR1cm4geyFSZWdFeHB9XG4gKi9cbmZ1bmN0aW9uIHRva2Vuc1RvUmVnRXhwICh0b2tlbnMsIGtleXMsIG9wdGlvbnMpIHtcbiAgaWYgKCFpc2FycmF5KGtleXMpKSB7XG4gICAgb3B0aW9ucyA9IC8qKiBAdHlwZSB7IU9iamVjdH0gKi8gKGtleXMgfHwgb3B0aW9ucylcbiAgICBrZXlzID0gW11cbiAgfVxuXG4gIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9XG5cbiAgdmFyIHN0cmljdCA9IG9wdGlvbnMuc3RyaWN0XG4gIHZhciBlbmQgPSBvcHRpb25zLmVuZCAhPT0gZmFsc2VcbiAgdmFyIHJvdXRlID0gJydcblxuICAvLyBJdGVyYXRlIG92ZXIgdGhlIHRva2VucyBhbmQgY3JlYXRlIG91ciByZWdleHAgc3RyaW5nLlxuICBmb3IgKHZhciBpID0gMDsgaSA8IHRva2Vucy5sZW5ndGg7IGkrKykge1xuICAgIHZhciB0b2tlbiA9IHRva2Vuc1tpXVxuXG4gICAgaWYgKHR5cGVvZiB0b2tlbiA9PT0gJ3N0cmluZycpIHtcbiAgICAgIHJvdXRlICs9IGVzY2FwZVN0cmluZyh0b2tlbilcbiAgICB9IGVsc2Uge1xuICAgICAgdmFyIHByZWZpeCA9IGVzY2FwZVN0cmluZyh0b2tlbi5wcmVmaXgpXG4gICAgICB2YXIgY2FwdHVyZSA9ICcoPzonICsgdG9rZW4ucGF0dGVybiArICcpJ1xuXG4gICAgICBrZXlzLnB1c2godG9rZW4pXG5cbiAgICAgIGlmICh0b2tlbi5yZXBlYXQpIHtcbiAgICAgICAgY2FwdHVyZSArPSAnKD86JyArIHByZWZpeCArIGNhcHR1cmUgKyAnKSonXG4gICAgICB9XG5cbiAgICAgIGlmICh0b2tlbi5vcHRpb25hbCkge1xuICAgICAgICBpZiAoIXRva2VuLnBhcnRpYWwpIHtcbiAgICAgICAgICBjYXB0dXJlID0gJyg/OicgKyBwcmVmaXggKyAnKCcgKyBjYXB0dXJlICsgJykpPydcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjYXB0dXJlID0gcHJlZml4ICsgJygnICsgY2FwdHVyZSArICcpPydcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY2FwdHVyZSA9IHByZWZpeCArICcoJyArIGNhcHR1cmUgKyAnKSdcbiAgICAgIH1cblxuICAgICAgcm91dGUgKz0gY2FwdHVyZVxuICAgIH1cbiAgfVxuXG4gIHZhciBkZWxpbWl0ZXIgPSBlc2NhcGVTdHJpbmcob3B0aW9ucy5kZWxpbWl0ZXIgfHwgJy8nKVxuICB2YXIgZW5kc1dpdGhEZWxpbWl0ZXIgPSByb3V0ZS5zbGljZSgtZGVsaW1pdGVyLmxlbmd0aCkgPT09IGRlbGltaXRlclxuXG4gIC8vIEluIG5vbi1zdHJpY3QgbW9kZSB3ZSBhbGxvdyBhIHNsYXNoIGF0IHRoZSBlbmQgb2YgbWF0Y2guIElmIHRoZSBwYXRoIHRvXG4gIC8vIG1hdGNoIGFscmVhZHkgZW5kcyB3aXRoIGEgc2xhc2gsIHdlIHJlbW92ZSBpdCBmb3IgY29uc2lzdGVuY3kuIFRoZSBzbGFzaFxuICAvLyBpcyB2YWxpZCBhdCB0aGUgZW5kIG9mIGEgcGF0aCBtYXRjaCwgbm90IGluIHRoZSBtaWRkbGUuIFRoaXMgaXMgaW1wb3J0YW50XG4gIC8vIGluIG5vbi1lbmRpbmcgbW9kZSwgd2hlcmUgXCIvdGVzdC9cIiBzaG91bGRuJ3QgbWF0Y2ggXCIvdGVzdC8vcm91dGVcIi5cbiAgaWYgKCFzdHJpY3QpIHtcbiAgICByb3V0ZSA9IChlbmRzV2l0aERlbGltaXRlciA/IHJvdXRlLnNsaWNlKDAsIC1kZWxpbWl0ZXIubGVuZ3RoKSA6IHJvdXRlKSArICcoPzonICsgZGVsaW1pdGVyICsgJyg/PSQpKT8nXG4gIH1cblxuICBpZiAoZW5kKSB7XG4gICAgcm91dGUgKz0gJyQnXG4gIH0gZWxzZSB7XG4gICAgLy8gSW4gbm9uLWVuZGluZyBtb2RlLCB3ZSBuZWVkIHRoZSBjYXB0dXJpbmcgZ3JvdXBzIHRvIG1hdGNoIGFzIG11Y2ggYXNcbiAgICAvLyBwb3NzaWJsZSBieSB1c2luZyBhIHBvc2l0aXZlIGxvb2thaGVhZCB0byB0aGUgZW5kIG9yIG5leHQgcGF0aCBzZWdtZW50LlxuICAgIHJvdXRlICs9IHN0cmljdCAmJiBlbmRzV2l0aERlbGltaXRlciA/ICcnIDogJyg/PScgKyBkZWxpbWl0ZXIgKyAnfCQpJ1xuICB9XG5cbiAgcmV0dXJuIGF0dGFjaEtleXMobmV3IFJlZ0V4cCgnXicgKyByb3V0ZSwgZmxhZ3Mob3B0aW9ucykpLCBrZXlzKVxufVxuXG4vKipcbiAqIE5vcm1hbGl6ZSB0aGUgZ2l2ZW4gcGF0aCBzdHJpbmcsIHJldHVybmluZyBhIHJlZ3VsYXIgZXhwcmVzc2lvbi5cbiAqXG4gKiBBbiBlbXB0eSBhcnJheSBjYW4gYmUgcGFzc2VkIGluIGZvciB0aGUga2V5cywgd2hpY2ggd2lsbCBob2xkIHRoZVxuICogcGxhY2Vob2xkZXIga2V5IGRlc2NyaXB0aW9ucy4gRm9yIGV4YW1wbGUsIHVzaW5nIGAvdXNlci86aWRgLCBga2V5c2Agd2lsbFxuICogY29udGFpbiBgW3sgbmFtZTogJ2lkJywgZGVsaW1pdGVyOiAnLycsIG9wdGlvbmFsOiBmYWxzZSwgcmVwZWF0OiBmYWxzZSB9XWAuXG4gKlxuICogQHBhcmFtICB7KHN0cmluZ3xSZWdFeHB8QXJyYXkpfSBwYXRoXG4gKiBAcGFyYW0gIHsoQXJyYXl8T2JqZWN0KT19ICAgICAgIGtleXNcbiAqIEBwYXJhbSAge09iamVjdD19ICAgICAgICAgICAgICAgb3B0aW9uc1xuICogQHJldHVybiB7IVJlZ0V4cH1cbiAqL1xuZnVuY3Rpb24gcGF0aFRvUmVnZXhwIChwYXRoLCBrZXlzLCBvcHRpb25zKSB7XG4gIGlmICghaXNhcnJheShrZXlzKSkge1xuICAgIG9wdGlvbnMgPSAvKiogQHR5cGUgeyFPYmplY3R9ICovIChrZXlzIHx8IG9wdGlvbnMpXG4gICAga2V5cyA9IFtdXG4gIH1cblxuICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fVxuXG4gIGlmIChwYXRoIGluc3RhbmNlb2YgUmVnRXhwKSB7XG4gICAgcmV0dXJuIHJlZ2V4cFRvUmVnZXhwKHBhdGgsIC8qKiBAdHlwZSB7IUFycmF5fSAqLyAoa2V5cykpXG4gIH1cblxuICBpZiAoaXNhcnJheShwYXRoKSkge1xuICAgIHJldHVybiBhcnJheVRvUmVnZXhwKC8qKiBAdHlwZSB7IUFycmF5fSAqLyAocGF0aCksIC8qKiBAdHlwZSB7IUFycmF5fSAqLyAoa2V5cyksIG9wdGlvbnMpXG4gIH1cblxuICByZXR1cm4gc3RyaW5nVG9SZWdleHAoLyoqIEB0eXBlIHtzdHJpbmd9ICovIChwYXRoKSwgLyoqIEB0eXBlIHshQXJyYXl9ICovIChrZXlzKSwgb3B0aW9ucylcbn1cblxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vfi9wYXRoLXRvLXJlZ2V4cC9pbmRleC5qc1xuLy8gbW9kdWxlIGlkID0gMlxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJcInVzZSBzdHJpY3RcIjtcbnZhciByb3V0ZXJfMSA9IHJlcXVpcmUoXCIuL3JvdXRlclwiKTtcbndpbmRvd1sncm91dGVyJ10gPSBuZXcgcm91dGVyXzEuUm91dGVyKHdpbmRvdyk7XG5cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL3NyYy9icm93c2VyLnRzXG4vLyBtb2R1bGUgaWQgPSAzXG4vLyBtb2R1bGUgY2h1bmtzID0gMCJdLCJzb3VyY2VSb290IjoiIn0= |
| !function(e){function t(r){if(n[r])return n[r].exports;var o=n[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,t),o.l=!0,o.exports}var n={};return t.m=e,t.c=n,t.i=function(e){return e},t.d=function(e,n,r){t.o(e,n)||Object.defineProperty(e,n,{configurable:!1,enumerable:!0,get:r})},t.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(n,"a",n),n},t.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},t.p="",t(t.s=3)}([function(e,t,n){"use strict";function r(){return window.location.hash.slice(1)}var o=n(2),i=function(){function e(e){this.routes=[],this.window=e}return e.prototype.hash=function(e,t){var n=[],r=o(e,n),i={re:r,keys:n};"function"==typeof t?i.callback=t:i.callback=function(){},this.routes.push(i)},e.prototype.start=function(){this.window.addEventListener("hashchange",this.onHashChanged,!1);var e=r();e.length>0&&this.dispatch(e)},e.prototype.stop=function(){this.window.removeEventListener("hashchange",this.onHashChanged,!1)},e.prototype.onHashChanged=function(){this.dispatch(r())},e.prototype.dispatch=function(e){e||(e=r());for(var t=0,n=this.routes;t<n.length;t++){var o=n[t],i=o.re.exec(e);if(i){o.callback.apply(this,i.slice(1));break}}},e}();t.Router=i},function(e,t){e.exports=Array.isArray||function(e){return"[object Array]"==Object.prototype.toString.call(e)}},function(e,t,n){function r(e,t){for(var n,r=[],o=0,i=0,a="",u=t&&t.delimiter||"/";null!=(n=w.exec(e));){var s=n[0],f=n[1],l=n.index;if(a+=e.slice(i,l),i=l+s.length,f)a+=f[1];else{var h=e[i],d=n[2],g=n[3],v=n[4],x=n[5],y=n[6],m=n[7];a&&(r.push(a),a="");var E=null!=d&&null!=h&&h!==d,b="+"===y||"*"===y,k="?"===y||"*"===y,R=n[2]||u,C=v||x;r.push({name:g||o++,prefix:d||"",delimiter:R,optional:k,repeat:b,partial:E,asterisk:!!m,pattern:C?c(C):m?".*":"[^"+p(R)+"]+?"})}}return i<e.length&&(a+=e.substr(i)),a&&r.push(a),r}function o(e,t){return u(r(e,t))}function i(e){return encodeURI(e).replace(/[\/?#]/g,function(e){return"%"+e.charCodeAt(0).toString(16).toUpperCase()})}function a(e){return encodeURI(e).replace(/[?#]/g,function(e){return"%"+e.charCodeAt(0).toString(16).toUpperCase()})}function u(e){for(var t=new Array(e.length),n=0;n<e.length;n++)"object"==typeof e[n]&&(t[n]=new RegExp("^(?:"+e[n].pattern+")$"));return function(n,r){for(var o="",u=n||{},p=r||{},c=p.pretty?i:encodeURIComponent,s=0;s<e.length;s++){var f=e[s];if("string"!=typeof f){var l,h=u[f.name];if(null==h){if(f.optional){f.partial&&(o+=f.prefix);continue}throw new TypeError('Expected "'+f.name+'" to be defined')}if(x(h)){if(!f.repeat)throw new TypeError('Expected "'+f.name+'" to not repeat, but received `'+JSON.stringify(h)+"`");if(0===h.length){if(f.optional)continue;throw new TypeError('Expected "'+f.name+'" to not be empty')}for(var d=0;d<h.length;d++){if(l=c(h[d]),!t[s].test(l))throw new TypeError('Expected all "'+f.name+'" to match "'+f.pattern+'", but received `'+JSON.stringify(l)+"`");o+=(0===d?f.prefix:f.delimiter)+l}}else{if(l=f.asterisk?a(h):c(h),!t[s].test(l))throw new TypeError('Expected "'+f.name+'" to match "'+f.pattern+'", but received "'+l+'"');o+=f.prefix+l}}else o+=f}return o}}function p(e){return e.replace(/([.+*?=^!:${}()[\]|\/\\])/g,"\\$1")}function c(e){return e.replace(/([=!:$\/()])/g,"\\$1")}function s(e,t){return e.keys=t,e}function f(e){return e.sensitive?"":"i"}function l(e,t){var n=e.source.match(/\((?!\?)/g);if(n)for(var r=0;r<n.length;r++)t.push({name:r,prefix:null,delimiter:null,optional:!1,repeat:!1,partial:!1,asterisk:!1,pattern:null});return s(e,t)}function h(e,t,n){for(var r=[],o=0;o<e.length;o++)r.push(v(e[o],t,n).source);var i=new RegExp("(?:"+r.join("|")+")",f(n));return s(i,t)}function d(e,t,n){return g(r(e,n),t,n)}function g(e,t,n){x(t)||(n=t||n,t=[]),n=n||{};for(var r=n.strict,o=n.end!==!1,i="",a=0;a<e.length;a++){var u=e[a];if("string"==typeof u)i+=p(u);else{var c=p(u.prefix),l="(?:"+u.pattern+")";t.push(u),u.repeat&&(l+="(?:"+c+l+")*"),l=u.optional?u.partial?c+"("+l+")?":"(?:"+c+"("+l+"))?":c+"("+l+")",i+=l}}var h=p(n.delimiter||"/"),d=i.slice(-h.length)===h;return r||(i=(d?i.slice(0,-h.length):i)+"(?:"+h+"(?=$))?"),i+=o?"$":r&&d?"":"(?="+h+"|$)",s(new RegExp("^"+i,f(n)),t)}function v(e,t,n){return x(t)||(n=t||n,t=[]),n=n||{},e instanceof RegExp?l(e,t):x(e)?h(e,t,n):d(e,t,n)}var x=n(1);e.exports=v,e.exports.parse=r,e.exports.compile=o,e.exports.tokensToFunction=u,e.exports.tokensToRegExp=g;var w=new RegExp(["(\\\\.)","([\\/.])?(?:(?:\\:(\\w+)(?:\\(((?:\\\\.|[^\\\\()])+)\\))?|\\(((?:\\\\.|[^\\\\()])+)\\))([+*?])?|(\\*))"].join("|"),"g")},function(e,t,n){"use strict";var r=n(0);window.router=new r.Router(window)}]); |
| export declare class Router { | ||
| private window; | ||
| private previous; | ||
| private routes; | ||
| constructor(window: Window); | ||
| hash(path: string, arg: any): void; | ||
| start(): void; | ||
| stop(): void; | ||
| private onHashChanged(); | ||
| dispatch(path?: string): void; | ||
| } |
+13
-7
| { | ||
| "name": "roughter", | ||
| "version": "0.1.0", | ||
| "description": "Tiny Express-inspired hash router.", | ||
| "version": "0.2.0", | ||
| "description": "Tiny hash router.", | ||
| "keywords": [ | ||
@@ -17,11 +17,8 @@ "hash", | ||
| "files": [ | ||
| "dispatcher", | ||
| "hash", | ||
| "lib", | ||
| "dist", | ||
| "gulpfile.js", | ||
| "LICENSE.txt" | ||
| ], | ||
| "scripts": { | ||
| "test": "echo \"Error: no test specified\" && exit 1" | ||
| "watch": "nara", | ||
| "test": "mocha" | ||
| }, | ||
@@ -39,3 +36,12 @@ "repository": { | ||
| "devDependencies": { | ||
| "chai": "^3.5.0", | ||
| "mocha": "^3.2.0", | ||
| "mocha-typescript": "^1.0.18", | ||
| "nara": "^0.2.2", | ||
| "ts-loader": "^2.0.0", | ||
| "typescript": "^2.1.5", | ||
| "typings": "^2.1.0", | ||
| "uglify-js": "^2.7.5", | ||
| "webpack": "^2.2.1" | ||
| } | ||
| } |
+14
-19
| # Riot Dispatcher | ||
| # Hash router | ||
| Tiny Express-inspired router for [Riot 2](http://riotjs.com) | ||
| Tiny hash router. | ||
| ``` | ||
| riot.dispatcher.hash('/', index) | ||
| riot.dispatcher.hash('/user/:user', show) | ||
| riot.dispatcher.hash('/user/:user/edit', edit) | ||
| riot.dispatcher.hash('/user/:user/album', album) | ||
| riot.dispatcher.hash('/user/:user/album/sort', sort) | ||
| riot.dispatcher.hash('*', notfound) | ||
| router.hash('/', index) | ||
| router.hash('/user/:user', show) | ||
| router.hash('/user/:user/edit', edit) | ||
| router.hash('/user/:user/album', album) | ||
| router.hash('/user/:user/album/sort', sort) | ||
| router.hash('*', notfound) | ||
| // start router | ||
| router.start() | ||
| ``` | ||
@@ -17,8 +20,2 @@ | ||
| ## Use Versions | ||
| - **Riot** v2.2 | ||
| ## Installation | ||
@@ -28,10 +25,8 @@ | ||
| Download [riot-dispatcher.min.js](https://raw.githubusercontent.com/jumilla/riot-dispatcher/master/dist/riot-dispatcher.min.js) (master) | ||
| Download [roughter.min.js](https://raw.githubusercontent.com/jumilla/node-roughter/master/dist/roughter.min.js) (master) | ||
| or | ||
| ### for Node.js | ||
| Bower | ||
| ```sh | ||
| bower install riot-dispatcher --save | ||
| npm install roughter --save | ||
| ``` | ||
@@ -38,0 +33,0 @@ |
| { | ||
| "private": true, | ||
| "main": "../lib/hash.js" | ||
| } |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Minified code
QualityThis package contains minified code. This may be harmless in some cases where minified code is included in packaged libraries, however packages on npm should not minify code.
Found 1 instance in 1 package
Empty package
Supply chain riskPackage does not contain any code. It may be removed, is name squatting, or the result of a faulty package publish.
Found 1 instance in 1 package
No tests
QualityPackage does not have any tests. This is a strong signal of a poorly maintained or low quality package.
Found 1 instance in 1 package
49707
1862.38%6
50%529
Infinity%9
Infinity%37
-11.9%