UNPKG

verdaccio

Version:

A lightweight private npm proxy registry

354 lines (338 loc) 34.7 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ErrorCode = void 0; exports.addScope = addScope; Object.defineProperty(exports, "buildToken", { enumerable: true, get: function () { return _utils.buildToken; } }); exports.deleteProperties = deleteProperties; exports.encodeScopedUri = encodeScopedUri; exports.fileExists = fileExists; exports.folderExists = folderExists; exports.getVersion = getVersion; exports.hasDiffOneKey = hasDiffOneKey; exports.hasLogin = hasLogin; exports.isObject = void 0; exports.isObjectOrArray = isObjectOrArray; exports.isRelatedToDeprecation = isRelatedToDeprecation; exports.isVersionValid = isVersionValid; exports.mask = mask; exports.normalizeDistTags = normalizeDistTags; exports.parseAddress = parseAddress; Object.defineProperty(exports, "parseConfigFile", { enumerable: true, get: function () { return _config.parseConfigFile; } }); exports.parseInterval = parseInterval; exports.parseReadme = parseReadme; exports.semverSort = semverSort; exports.sortByName = sortByName; exports.tagVersion = tagVersion; var _fs = _interopRequireDefault(require("fs")); var _lodash = _interopRequireDefault(require("lodash")); var _semver = _interopRequireDefault(require("semver")); var _config = require("@verdaccio/config"); var _core = require("@verdaccio/core"); var _utils = require("@verdaccio/utils"); var _constants = require("./constants"); var _logger = require("./logger"); function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; } // eslint-disable-next-line max-len const { getBadData, getBadRequest, getCode, getConflict, getForbidden, getInternalError, getNotFound, getServiceUnavailable, getUnauthorized } = _core.errorUtils; /** * Check whether an element is an Object * @param {*} obj the element * @return {Boolean} */ const isObject = exports.isObject = _core.validationUtils.isObject; /** * @deprecated not used un v6 */ function isObjectOrArray(obj) { return _lodash.default.isObject(obj) && _lodash.default.isNull(obj) === false; } function tagVersion(data, version, tag) { if (tag && data[_constants.DIST_TAGS][tag] !== version && _semver.default.parse(version, true)) { // valid version - store data[_constants.DIST_TAGS][tag] = version; return true; } return false; } /** * Gets version from a package object taking into account semver weirdness. * @return {String} return the semantic version of a package */ function getVersion(pkg, version) { // this condition must allow cast if (_lodash.default.isNil(pkg.versions[version]) === false) { return pkg.versions[version]; } try { version = _semver.default.parse(version, true); for (const versionItem in pkg.versions) { if (version.compare(_semver.default.parse(versionItem, true)) === 0) { return pkg.versions[versionItem]; } } } catch (err) { return undefined; } } /** * Parse an internet address * Allow: - https:localhost:1234 - protocol + host + port - localhost:1234 - host + port - 1234 - port - http::1234 - protocol + port - https://localhost:443/ - full url + https - http://[::1]:443/ - ipv6 - unix:/tmp/http.sock - unix sockets - https://unix:/tmp/http.sock - unix sockets (https) * @param {*} urlAddress the internet address definition * @return {Object|Null} literal object that represent the address parsed */ function parseAddress(urlAddress) { // // TODO: refactor it to something more reasonable? // // protocol : // ( host )|( ipv6 ): port / let urlPattern = /^((https?):(\/\/)?)?((([^\/:]*)|\[([^\[\]]+)\]):)?(\d+)\/?$/.exec(urlAddress); if (urlPattern) { return { proto: urlPattern[2] || _constants.DEFAULT_PROTOCOL, host: urlPattern[6] || urlPattern[7] || _constants.DEFAULT_DOMAIN, port: urlPattern[8] || _constants.DEFAULT_PORT }; } urlPattern = /^((https?):(\/\/)?)?unix:(.*)$/.exec(urlAddress); if (urlPattern) { return { proto: urlPattern[2] || _constants.DEFAULT_PROTOCOL, path: urlPattern[4] }; } return null; } /** * Function filters out bad semver versions and sorts the array. * @return {Array} sorted Array */ function semverSort(listVersions) { return listVersions.filter(function (x) { if (!_semver.default.parse(x, true)) { _logger.logger.warn({ ver: x }, 'ignoring bad version @{ver}'); return false; } return true; }) // FIXME: it seems the @types/semver do not handle a legitimate method named 'compareLoose' // @ts-ignore .sort(_semver.default.compareLoose).map(String); } /** * Flatten arrays of tags. * @param {*} data */ function normalizeDistTags(pkg) { let sorted; if (!pkg[_constants.DIST_TAGS].latest) { // overwrite latest with highest known version based on semver sort sorted = semverSort(Object.keys(pkg.versions)); if (sorted && sorted.length) { pkg[_constants.DIST_TAGS].latest = sorted.pop(); } } for (const tag in pkg[_constants.DIST_TAGS]) { if (_lodash.default.isArray(pkg[_constants.DIST_TAGS][tag])) { if (pkg[_constants.DIST_TAGS][tag].length) { // sort array // FIXME: this is clearly wrong, we need to research why this is like this. // @ts-ignore sorted = semverSort(pkg[_constants.DIST_TAGS][tag]); if (sorted.length) { // use highest version based on semver sort pkg[_constants.DIST_TAGS][tag] = sorted.pop(); } } else { delete pkg[_constants.DIST_TAGS][tag]; } } else if (_lodash.default.isString(pkg[_constants.DIST_TAGS][tag])) { if (!_semver.default.parse(pkg[_constants.DIST_TAGS][tag], true)) { // if the version is invalid, delete the dist-tag entry delete pkg[_constants.DIST_TAGS][tag]; } } } } const parseIntervalTable = { '': 1000, ms: 1, s: 1000, m: 60 * 1000, h: 60 * 60 * 1000, d: 86400000, w: 7 * 86400000, M: 30 * 86400000, y: 365 * 86400000 }; /** * Parse an internal string to number * @param {*} interval * @return {Number} */ function parseInterval(interval) { if (typeof interval === 'number') { return interval * 1000; } let result = 0; let last_suffix = Infinity; interval.split(/\s+/).forEach(function (x) { if (!x) { return; } const m = x.match(/^((0|[1-9][0-9]*)(\.[0-9]+)?)(ms|s|m|h|d|w|M|y|)$/); if (!m || parseIntervalTable[m[4]] >= last_suffix || m[4] === '' && last_suffix !== Infinity) { throw Error('invalid interval: ' + interval); } last_suffix = parseIntervalTable[m[4]]; result += Number(m[1]) * parseIntervalTable[m[4]]; }); return result; } const ErrorCode = exports.ErrorCode = { getConflict, getBadData, getBadRequest, getInternalError, getUnauthorized, getForbidden, getServiceUnavailable, getNotFound, getCode }; /** * Check whether the path already exist. * @param {String} path * @return {Boolean} */ function folderExists(path) { try { const stat = _fs.default.statSync(path); return stat.isDirectory(); } catch (_) { return false; } } /** * Check whether the file already exist. * @param {String} path * @return {Boolean} */ function fileExists(path) { try { const stat = _fs.default.statSync(path); return stat.isFile(); } catch (_) { return false; } } function sortByName(packages, orderAscending = true) { return packages.slice().sort(function (a, b) { const comparatorNames = a.name.toLowerCase() < b.name.toLowerCase(); return orderAscending ? comparatorNames ? -1 : 1 : comparatorNames ? 1 : -1; }); } function addScope(scope, packageName) { return `@${scope}/${packageName}`; } function deleteProperties(propertiesToDelete, objectItem) { _lodash.default.forEach(propertiesToDelete, property => { delete objectItem[property]; }); return objectItem; } /** * parse package readme - markdown/ascii * @param {String} packageName name of package * @param {String} readme package readme * @return {String} converted html template */ // TODO: rename, does not parse anymore function parseReadme(packageName, readme) { if (_lodash.default.isEmpty(readme) === false) { return readme; } // logs readme not found error _logger.logger.info({ packageName }, '@{packageName}: No readme found'); return 'ERROR: No README data found!'; } /** * return a masquerade string with its first and last {charNum} and three dots in between. * @param {String} str * @param {Number} charNum * @returns {String} */ function mask(str, charNum = 3) { return `${str.substr(0, charNum)}...${str.substr(-charNum)}`; } function encodeScopedUri(packageName) { return packageName.replace(/\//g, '%2f'); } function hasDiffOneKey(versions) { return Object.keys(versions).length !== 1; } function isVersionValid(packageMeta, packageVersion) { const hasVersion = typeof packageVersion !== 'undefined'; if (!hasVersion) { return false; } const hasMatchVersion = Object.keys(packageMeta.versions).includes(packageVersion); return hasMatchVersion; } function isRelatedToDeprecation(pkgInfo) { const { versions } = pkgInfo; for (const version in versions) { if (Object.prototype.hasOwnProperty.call(versions[version], 'deprecated')) { return true; } } return false; } /** * * @param config * @deprecated use @verdaccio/middleware * @returns */ function hasLogin(config) { var _config$web, _config$web2; // FIXME: types are not yet on the library verdaccio/monorepo // @ts-ignore return _lodash.default.isNil(config === null || config === void 0 ? void 0 : (_config$web = config.web) === null || _config$web === void 0 ? void 0 : _config$web.login) || (config === null || config === void 0 ? void 0 : (_config$web2 = config.web) === null || _config$web2 === void 0 ? void 0 : _config$web2.login) === true; } //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfZnMiLCJfaW50ZXJvcFJlcXVpcmVEZWZhdWx0IiwicmVxdWlyZSIsIl9sb2Rhc2giLCJfc2VtdmVyIiwiX2NvbmZpZyIsIl9jb3JlIiwiX3V0aWxzIiwiX2NvbnN0YW50cyIsIl9sb2dnZXIiLCJlIiwiX19lc01vZHVsZSIsImRlZmF1bHQiLCJnZXRCYWREYXRhIiwiZ2V0QmFkUmVxdWVzdCIsImdldENvZGUiLCJnZXRDb25mbGljdCIsImdldEZvcmJpZGRlbiIsImdldEludGVybmFsRXJyb3IiLCJnZXROb3RGb3VuZCIsImdldFNlcnZpY2VVbmF2YWlsYWJsZSIsImdldFVuYXV0aG9yaXplZCIsImVycm9yVXRpbHMiLCJpc09iamVjdCIsImV4cG9ydHMiLCJ2YWxpZGF0aW9uVXRpbHMiLCJpc09iamVjdE9yQXJyYXkiLCJvYmoiLCJfIiwiaXNOdWxsIiwidGFnVmVyc2lvbiIsImRhdGEiLCJ2ZXJzaW9uIiwidGFnIiwiRElTVF9UQUdTIiwic2VtdmVyIiwicGFyc2UiLCJnZXRWZXJzaW9uIiwicGtnIiwiaXNOaWwiLCJ2ZXJzaW9ucyIsInZlcnNpb25JdGVtIiwiY29tcGFyZSIsImVyciIsInVuZGVmaW5lZCIsInBhcnNlQWRkcmVzcyIsInVybEFkZHJlc3MiLCJ1cmxQYXR0ZXJuIiwiZXhlYyIsInByb3RvIiwiREVGQVVMVF9QUk9UT0NPTCIsImhvc3QiLCJERUZBVUxUX0RPTUFJTiIsInBvcnQiLCJERUZBVUxUX1BPUlQiLCJwYXRoIiwic2VtdmVyU29ydCIsImxpc3RWZXJzaW9ucyIsImZpbHRlciIsIngiLCJsb2dnZXIiLCJ3YXJuIiwidmVyIiwic29ydCIsImNvbXBhcmVMb29zZSIsIm1hcCIsIlN0cmluZyIsIm5vcm1hbGl6ZURpc3RUYWdzIiwic29ydGVkIiwibGF0ZXN0IiwiT2JqZWN0Iiwia2V5cyIsImxlbmd0aCIsInBvcCIsImlzQXJyYXkiLCJpc1N0cmluZyIsInBhcnNlSW50ZXJ2YWxUYWJsZSIsIm1zIiwicyIsIm0iLCJoIiwiZCIsInciLCJNIiwieSIsInBhcnNlSW50ZXJ2YWwiLCJpbnRlcnZhbCIsInJlc3VsdCIsImxhc3Rfc3VmZml4IiwiSW5maW5pdHkiLCJzcGxpdCIsImZvckVhY2giLCJtYXRjaCIsIkVycm9yIiwiTnVtYmVyIiwiRXJyb3JDb2RlIiwiZm9sZGVyRXhpc3RzIiwic3RhdCIsImZzIiwic3RhdFN5bmMiLCJpc0RpcmVjdG9yeSIsImZpbGVFeGlzdHMiLCJpc0ZpbGUiLCJzb3J0QnlOYW1lIiwicGFja2FnZXMiLCJvcmRlckFzY2VuZGluZyIsInNsaWNlIiwiYSIsImIiLCJjb21wYXJhdG9yTmFtZXMiLCJuYW1lIiwidG9Mb3dlckNhc2UiLCJhZGRTY29wZSIsInNjb3BlIiwicGFja2FnZU5hbWUiLCJkZWxldGVQcm9wZXJ0aWVzIiwicHJvcGVydGllc1RvRGVsZXRlIiwib2JqZWN0SXRlbSIsInByb3BlcnR5IiwicGFyc2VSZWFkbWUiLCJyZWFkbWUiLCJpc0VtcHR5IiwiaW5mbyIsIm1hc2siLCJzdHIiLCJjaGFyTnVtIiwic3Vic3RyIiwiZW5jb2RlU2NvcGVkVXJpIiwicmVwbGFjZSIsImhhc0RpZmZPbmVLZXkiLCJpc1ZlcnNpb25WYWxpZCIsInBhY2thZ2VNZXRhIiwicGFja2FnZVZlcnNpb24iLCJoYXNWZXJzaW9uIiwiaGFzTWF0Y2hWZXJzaW9uIiwiaW5jbHVkZXMiLCJpc1JlbGF0ZWRUb0RlcHJlY2F0aW9uIiwicGtnSW5mbyIsInByb3RvdHlwZSIsImhhc093blByb3BlcnR5IiwiY2FsbCIsImhhc0xvZ2luIiwiY29uZmlnIiwiX2NvbmZpZyR3ZWIiLCJfY29uZmlnJHdlYjIiLCJ3ZWIiLCJsb2dpbiJdLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9saWIvdXRpbHMudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IGZzIGZyb20gJ2ZzJztcbmltcG9ydCBfIGZyb20gJ2xvZGFzaCc7XG5pbXBvcnQgc2VtdmVyIGZyb20gJ3NlbXZlcic7XG5cbmltcG9ydCB7IHBhcnNlQ29uZmlnRmlsZSB9IGZyb20gJ0B2ZXJkYWNjaW8vY29uZmlnJztcbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBtYXgtbGVuXG5pbXBvcnQgeyBlcnJvclV0aWxzLCB2YWxpZGF0aW9uVXRpbHMgfSBmcm9tICdAdmVyZGFjY2lvL2NvcmUnO1xuaW1wb3J0IHsgU3RyaW5nVmFsdWUgfSBmcm9tICdAdmVyZGFjY2lvL3R5cGVzJztcbmltcG9ydCB7IENvbmZpZywgTWFuaWZlc3QsIFZlcnNpb24gfSBmcm9tICdAdmVyZGFjY2lvL3R5cGVzJztcbmltcG9ydCB7IGJ1aWxkVG9rZW4gYXMgYnVpbGRUb2tlblV0aWwgfSBmcm9tICdAdmVyZGFjY2lvL3V0aWxzJztcblxuaW1wb3J0IHsgREVGQVVMVF9ET01BSU4sIERFRkFVTFRfUE9SVCwgREVGQVVMVF9QUk9UT0NPTCwgRElTVF9UQUdTIH0gZnJvbSAnLi9jb25zdGFudHMnO1xuaW1wb3J0IHsgbG9nZ2VyIH0gZnJvbSAnLi9sb2dnZXInO1xuXG5jb25zdCB7XG4gIGdldEJhZERhdGEsXG4gIGdldEJhZFJlcXVlc3QsXG4gIGdldENvZGUsXG4gIGdldENvbmZsaWN0LFxuICBnZXRGb3JiaWRkZW4sXG4gIGdldEludGVybmFsRXJyb3IsXG4gIGdldE5vdEZvdW5kLFxuICBnZXRTZXJ2aWNlVW5hdmFpbGFibGUsXG4gIGdldFVuYXV0aG9yaXplZCxcbn0gPSBlcnJvclV0aWxzO1xuXG4vKipcbiAqIENoZWNrIHdoZXRoZXIgYW4gZWxlbWVudCBpcyBhbiBPYmplY3RcbiAqIEBwYXJhbSB7Kn0gb2JqIHRoZSBlbGVtZW50XG4gKiBAcmV0dXJuIHtCb29sZWFufVxuICovXG5leHBvcnQgY29uc3QgaXNPYmplY3QgPSB2YWxpZGF0aW9uVXRpbHMuaXNPYmplY3Q7XG5cbi8qKlxuICogQGRlcHJlY2F0ZWQgbm90IHVzZWQgdW4gdjZcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzT2JqZWN0T3JBcnJheShvYmo6IGFueSk6IGJvb2xlYW4ge1xuICByZXR1cm4gXy5pc09iamVjdChvYmopICYmIF8uaXNOdWxsKG9iaikgPT09IGZhbHNlO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gdGFnVmVyc2lvbihkYXRhOiBNYW5pZmVzdCwgdmVyc2lvbjogc3RyaW5nLCB0YWc6IFN0cmluZ1ZhbHVlKTogYm9vbGVhbiB7XG4gIGlmICh0YWcgJiYgZGF0YVtESVNUX1RBR1NdW3RhZ10gIT09IHZlcnNpb24gJiYgc2VtdmVyLnBhcnNlKHZlcnNpb24sIHRydWUpKSB7XG4gICAgLy8gdmFsaWQgdmVyc2lvbiAtIHN0b3JlXG4gICAgZGF0YVtESVNUX1RBR1NdW3RhZ10gPSB2ZXJzaW9uO1xuICAgIHJldHVybiB0cnVlO1xuICB9XG4gIHJldHVybiBmYWxzZTtcbn1cblxuLyoqXG4gKiBHZXRzIHZlcnNpb24gZnJvbSBhIHBhY2thZ2Ugb2JqZWN0IHRha2luZyBpbnRvIGFjY291bnQgc2VtdmVyIHdlaXJkbmVzcy5cbiAqIEByZXR1cm4ge1N0cmluZ30gcmV0dXJuIHRoZSBzZW1hbnRpYyB2ZXJzaW9uIG9mIGEgcGFja2FnZVxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0VmVyc2lvbihwa2c6IE1hbmlmZXN0LCB2ZXJzaW9uOiBhbnkpOiBWZXJzaW9uIHwgdm9pZCB7XG4gIC8vIHRoaXMgY29uZGl0aW9uIG11c3QgYWxsb3cgY2FzdFxuICBpZiAoXy5pc05pbChwa2cudmVyc2lvbnNbdmVyc2lvbl0pID09PSBmYWxzZSkge1xuICAgIHJldHVybiBwa2cudmVyc2lvbnNbdmVyc2lvbl07XG4gIH1cblxuICB0cnkge1xuICAgIHZlcnNpb24gPSBzZW12ZXIucGFyc2UodmVyc2lvbiwgdHJ1ZSk7XG4gICAgZm9yIChjb25zdCB2ZXJzaW9uSXRlbSBpbiBwa2cudmVyc2lvbnMpIHtcbiAgICAgIGlmICh2ZXJzaW9uLmNvbXBhcmUoc2VtdmVyLnBhcnNlKHZlcnNpb25JdGVtLCB0cnVlKSkgPT09IDApIHtcbiAgICAgICAgcmV0dXJuIHBrZy52ZXJzaW9uc1t2ZXJzaW9uSXRlbV07XG4gICAgICB9XG4gICAgfVxuICB9IGNhdGNoIChlcnI6IGFueSkge1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cbn1cblxuLyoqXG4gKiBQYXJzZSBhbiBpbnRlcm5ldCBhZGRyZXNzXG4gKiBBbGxvdzpcbiAtIGh0dHBzOmxvY2FsaG9zdDoxMjM0ICAgICAgICAtIHByb3RvY29sICsgaG9zdCArIHBvcnRcbiAtIGxvY2FsaG9zdDoxMjM0ICAgICAgICAgICAgICAtIGhvc3QgKyBwb3J0XG4gLSAxMjM0ICAgICAgICAgICAgICAgICAgICAgICAgLSBwb3J0XG4gLSBodHRwOjoxMjM0ICAgICAgICAgICAgICAgICAgLSBwcm90b2NvbCArIHBvcnRcbiAtIGh0dHBzOi8vbG9jYWxob3N0OjQ0My8gICAgICAtIGZ1bGwgdXJsICsgaHR0cHNcbiAtIGh0dHA6Ly9bOjoxXTo0NDMvICAgICAgICAgICAtIGlwdjZcbiAtIHVuaXg6L3RtcC9odHRwLnNvY2sgICAgICAgICAtIHVuaXggc29ja2V0c1xuIC0gaHR0cHM6Ly91bml4Oi90bXAvaHR0cC5zb2NrIC0gdW5peCBzb2NrZXRzIChodHRwcylcbiAqIEBwYXJhbSB7Kn0gdXJsQWRkcmVzcyB0aGUgaW50ZXJuZXQgYWRkcmVzcyBkZWZpbml0aW9uXG4gKiBAcmV0dXJuIHtPYmplY3R8TnVsbH0gbGl0ZXJhbCBvYmplY3QgdGhhdCByZXByZXNlbnQgdGhlIGFkZHJlc3MgcGFyc2VkXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZUFkZHJlc3ModXJsQWRkcmVzczogYW55KTogYW55IHtcbiAgLy9cbiAgLy8gVE9ETzogcmVmYWN0b3IgaXQgdG8gc29tZXRoaW5nIG1vcmUgcmVhc29uYWJsZT9cbiAgLy9cbiAgLy8gICAgICAgIHByb3RvY29sIDogIC8vICAgICAgKCAgaG9zdCAgKXwoICAgIGlwdjYgICAgICk6ICBwb3J0ICAvXG4gIGxldCB1cmxQYXR0ZXJuID0gL14oKGh0dHBzPyk6KFxcL1xcLyk/KT8oKChbXlxcLzpdKil8XFxbKFteXFxbXFxdXSspXFxdKTopPyhcXGQrKVxcLz8kLy5leGVjKHVybEFkZHJlc3MpO1xuXG4gIGlmICh1cmxQYXR0ZXJuKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHByb3RvOiB1cmxQYXR0ZXJuWzJdIHx8IERFRkFVTFRfUFJPVE9DT0wsXG4gICAgICBob3N0OiB1cmxQYXR0ZXJuWzZdIHx8IHVybFBhdHRlcm5bN10gfHwgREVGQVVMVF9ET01BSU4sXG4gICAgICBwb3J0OiB1cmxQYXR0ZXJuWzhdIHx8IERFRkFVTFRfUE9SVCxcbiAgICB9O1xuICB9XG5cbiAgdXJsUGF0dGVybiA9IC9eKChodHRwcz8pOihcXC9cXC8pPyk/dW5peDooLiopJC8uZXhlYyh1cmxBZGRyZXNzKTtcblxuICBpZiAodXJsUGF0dGVybikge1xuICAgIHJldHVybiB7XG4gICAgICBwcm90bzogdXJsUGF0dGVyblsyXSB8fCBERUZBVUxUX1BST1RPQ09MLFxuICAgICAgcGF0aDogdXJsUGF0dGVybls0XSxcbiAgICB9O1xuICB9XG5cbiAgcmV0dXJuIG51bGw7XG59XG5cbi8qKlxuICogRnVuY3Rpb24gZmlsdGVycyBvdXQgYmFkIHNlbXZlciB2ZXJzaW9ucyBhbmQgc29ydHMgdGhlIGFycmF5LlxuICogQHJldHVybiB7QXJyYXl9IHNvcnRlZCBBcnJheVxuICovXG5leHBvcnQgZnVuY3Rpb24gc2VtdmVyU29ydChsaXN0VmVyc2lvbnM6IHN0cmluZ1tdKTogc3RyaW5nW10ge1xuICByZXR1cm4gKFxuICAgIGxpc3RWZXJzaW9uc1xuICAgICAgLmZpbHRlcihmdW5jdGlvbiAoeCk6IGJvb2xlYW4ge1xuICAgICAgICBpZiAoIXNlbXZlci5wYXJzZSh4LCB0cnVlKSkge1xuICAgICAgICAgIGxvZ2dlci53YXJuKHsgdmVyOiB4IH0sICdpZ25vcmluZyBiYWQgdmVyc2lvbiBAe3Zlcn0nKTtcbiAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9KVxuICAgICAgLy8gRklYTUU6IGl0IHNlZW1zIHRoZSBAdHlwZXMvc2VtdmVyIGRvIG5vdCBoYW5kbGUgYSBsZWdpdGltYXRlIG1ldGhvZCBuYW1lZCAnY29tcGFyZUxvb3NlJ1xuICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgLnNvcnQoc2VtdmVyLmNvbXBhcmVMb29zZSlcbiAgICAgIC5tYXAoU3RyaW5nKVxuICApO1xufVxuXG4vKipcbiAqIEZsYXR0ZW4gYXJyYXlzIG9mIHRhZ3MuXG4gKiBAcGFyYW0geyp9IGRhdGFcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG5vcm1hbGl6ZURpc3RUYWdzKHBrZzogTWFuaWZlc3QpOiB2b2lkIHtcbiAgbGV0IHNvcnRlZDtcbiAgaWYgKCFwa2dbRElTVF9UQUdTXS5sYXRlc3QpIHtcbiAgICAvLyBvdmVyd3JpdGUgbGF0ZXN0IHdpdGggaGlnaGVzdCBrbm93biB2ZXJzaW9uIGJhc2VkIG9uIHNlbXZlciBzb3J0XG4gICAgc29ydGVkID0gc2VtdmVyU29ydChPYmplY3Qua2V5cyhwa2cudmVyc2lvbnMpKTtcbiAgICBpZiAoc29ydGVkICYmIHNvcnRlZC5sZW5ndGgpIHtcbiAgICAgIHBrZ1tESVNUX1RBR1NdLmxhdGVzdCA9IHNvcnRlZC5wb3AoKTtcbiAgICB9XG4gIH1cblxuICBmb3IgKGNvbnN0IHRhZyBpbiBwa2dbRElTVF9UQUdTXSkge1xuICAgIGlmIChfLmlzQXJyYXkocGtnW0RJU1RfVEFHU11bdGFnXSkpIHtcbiAgICAgIGlmIChwa2dbRElTVF9UQUdTXVt0YWddLmxlbmd0aCkge1xuICAgICAgICAvLyBzb3J0IGFycmF5XG4gICAgICAgIC8vIEZJWE1FOiB0aGlzIGlzIGNsZWFybHkgd3JvbmcsIHdlIG5lZWQgdG8gcmVzZWFyY2ggd2h5IHRoaXMgaXMgbGlrZSB0aGlzLlxuICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgIHNvcnRlZCA9IHNlbXZlclNvcnQocGtnW0RJU1RfVEFHU11bdGFnXSk7XG4gICAgICAgIGlmIChzb3J0ZWQubGVuZ3RoKSB7XG4gICAgICAgICAgLy8gdXNlIGhpZ2hlc3QgdmVyc2lvbiBiYXNlZCBvbiBzZW12ZXIgc29ydFxuICAgICAgICAgIHBrZ1tESVNUX1RBR1NdW3RhZ10gPSBzb3J0ZWQucG9wKCk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGRlbGV0ZSBwa2dbRElTVF9UQUdTXVt0YWddO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoXy5pc1N0cmluZyhwa2dbRElTVF9UQUdTXVt0YWddKSkge1xuICAgICAgaWYgKCFzZW12ZXIucGFyc2UocGtnW0RJU1RfVEFHU11bdGFnXSwgdHJ1ZSkpIHtcbiAgICAgICAgLy8gaWYgdGhlIHZlcnNpb24gaXMgaW52YWxpZCwgZGVsZXRlIHRoZSBkaXN0LXRhZyBlbnRyeVxuICAgICAgICBkZWxldGUgcGtnW0RJU1RfVEFHU11bdGFnXTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuY29uc3QgcGFyc2VJbnRlcnZhbFRhYmxlID0ge1xuICAnJzogMTAwMCxcbiAgbXM6IDEsXG4gIHM6IDEwMDAsXG4gIG06IDYwICogMTAwMCxcbiAgaDogNjAgKiA2MCAqIDEwMDAsXG4gIGQ6IDg2NDAwMDAwLFxuICB3OiA3ICogODY0MDAwMDAsXG4gIE06IDMwICogODY0MDAwMDAsXG4gIHk6IDM2NSAqIDg2NDAwMDAwLFxufTtcblxuLyoqXG4gKiBQYXJzZSBhbiBpbnRlcm5hbCBzdHJpbmcgdG8gbnVtYmVyXG4gKiBAcGFyYW0geyp9IGludGVydmFsXG4gKiBAcmV0dXJuIHtOdW1iZXJ9XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZUludGVydmFsKGludGVydmFsOiBhbnkpOiBudW1iZXIge1xuICBpZiAodHlwZW9mIGludGVydmFsID09PSAnbnVtYmVyJykge1xuICAgIHJldHVybiBpbnRlcnZhbCAqIDEwMDA7XG4gIH1cbiAgbGV0IHJlc3VsdCA9IDA7XG4gIGxldCBsYXN0X3N1ZmZpeCA9IEluZmluaXR5O1xuICBpbnRlcnZhbC5zcGxpdCgvXFxzKy8pLmZvckVhY2goZnVuY3Rpb24gKHgpOiB2b2lkIHtcbiAgICBpZiAoIXgpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgbSA9IHgubWF0Y2goL14oKDB8WzEtOV1bMC05XSopKFxcLlswLTldKyk/KShtc3xzfG18aHxkfHd8TXx5fCkkLyk7XG4gICAgaWYgKFxuICAgICAgIW0gfHxcbiAgICAgIHBhcnNlSW50ZXJ2YWxUYWJsZVttWzRdXSA+PSBsYXN0X3N1ZmZpeCB8fFxuICAgICAgKG1bNF0gPT09ICcnICYmIGxhc3Rfc3VmZml4ICE9PSBJbmZpbml0eSlcbiAgICApIHtcbiAgICAgIHRocm93IEVycm9yKCdpbnZhbGlkIGludGVydmFsOiAnICsgaW50ZXJ2YWwpO1xuICAgIH1cbiAgICBsYXN0X3N1ZmZpeCA9IHBhcnNlSW50ZXJ2YWxUYWJsZVttWzRdXTtcbiAgICByZXN1bHQgKz0gTnVtYmVyKG1bMV0pICogcGFyc2VJbnRlcnZhbFRhYmxlW21bNF1dO1xuICB9KTtcbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxuZXhwb3J0IGNvbnN0IEVycm9yQ29kZSA9IHtcbiAgZ2V0Q29uZmxpY3QsXG4gIGdldEJhZERhdGEsXG4gIGdldEJhZFJlcXVlc3QsXG4gIGdldEludGVybmFsRXJyb3IsXG4gIGdldFVuYXV0aG9yaXplZCxcbiAgZ2V0Rm9yYmlkZGVuLFxuICBnZXRTZXJ2aWNlVW5hdmFpbGFibGUsXG4gIGdldE5vdEZvdW5kLFxuICBnZXRDb2RlLFxufTtcblxuLyoqXG4gKiBDaGVjayB3aGV0aGVyIHRoZSBwYXRoIGFscmVhZHkgZXhpc3QuXG4gKiBAcGFyYW0ge1N0cmluZ30gcGF0aFxuICogQHJldHVybiB7Qm9vbGVhbn1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGZvbGRlckV4aXN0cyhwYXRoOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgdHJ5IHtcbiAgICBjb25zdCBzdGF0ID0gZnMuc3RhdFN5bmMocGF0aCk7XG4gICAgcmV0dXJuIHN0YXQuaXNEaXJlY3RvcnkoKTtcbiAgfSBjYXRjaCAoXzogYW55KSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG59XG5cbi8qKlxuICogQ2hlY2sgd2hldGhlciB0aGUgZmlsZSBhbHJlYWR5IGV4aXN0LlxuICogQHBhcmFtIHtTdHJpbmd9IHBhdGhcbiAqIEByZXR1cm4ge0Jvb2xlYW59XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBmaWxlRXhpc3RzKHBhdGg6IHN0cmluZyk6IGJvb2xlYW4ge1xuICB0cnkge1xuICAgIGNvbnN0IHN0YXQgPSBmcy5zdGF0U3luYyhwYXRoKTtcbiAgICByZXR1cm4gc3RhdC5pc0ZpbGUoKTtcbiAgfSBjYXRjaCAoXzogYW55KSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBzb3J0QnlOYW1lKHBhY2thZ2VzOiBhbnlbXSwgb3JkZXJBc2NlbmRpbmc6IGJvb2xlYW4gfCB2b2lkID0gdHJ1ZSk6IHN0cmluZ1tdIHtcbiAgcmV0dXJuIHBhY2thZ2VzLnNsaWNlKCkuc29ydChmdW5jdGlvbiAoYSwgYik6IG51bWJlciB7XG4gICAgY29uc3QgY29tcGFyYXRvck5hbWVzID0gYS5uYW1lLnRvTG93ZXJDYXNlKCkgPCBiLm5hbWUudG9Mb3dlckNhc2UoKTtcblxuICAgIHJldHVybiBvcmRlckFzY2VuZGluZyA/IChjb21wYXJhdG9yTmFtZXMgPyAtMSA6IDEpIDogY29tcGFyYXRvck5hbWVzID8gMSA6IC0xO1xuICB9KTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGFkZFNjb3BlKHNjb3BlOiBzdHJpbmcsIHBhY2thZ2VOYW1lOiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gYEAke3Njb3BlfS8ke3BhY2thZ2VOYW1lfWA7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBkZWxldGVQcm9wZXJ0aWVzKHByb3BlcnRpZXNUb0RlbGV0ZTogc3RyaW5nW10sIG9iamVjdEl0ZW06IGFueSk6IGFueSB7XG4gIF8uZm9yRWFjaChwcm9wZXJ0aWVzVG9EZWxldGUsIChwcm9wZXJ0eSk6IGFueSA9PiB7XG4gICAgZGVsZXRlIG9iamVjdEl0ZW1bcHJvcGVydHldO1xuICB9KTtcblxuICByZXR1cm4gb2JqZWN0SXRlbTtcbn1cblxuLyoqXG4gKiBwYXJzZSBwYWNrYWdlIHJlYWRtZSAtIG1hcmtkb3duL2FzY2lpXG4gKiBAcGFyYW0ge1N0cmluZ30gcGFja2FnZU5hbWUgbmFtZSBvZiBwYWNrYWdlXG4gKiBAcGFyYW0ge1N0cmluZ30gcmVhZG1lIHBhY2thZ2UgcmVhZG1lXG5cbiAqIEByZXR1cm4ge1N0cmluZ30gY29udmVydGVkIGh0bWwgdGVtcGxhdGVcbiAqL1xuLy8gVE9ETzogcmVuYW1lLCBkb2VzIG5vdCBwYXJzZSBhbnltb3JlXG5leHBvcnQgZnVuY3Rpb24gcGFyc2VSZWFkbWUocGFja2FnZU5hbWU6IHN0cmluZywgcmVhZG1lOiBzdHJpbmcpOiBzdHJpbmcgfCB2b2lkIHtcbiAgaWYgKF8uaXNFbXB0eShyZWFkbWUpID09PSBmYWxzZSkge1xuICAgIHJldHVybiByZWFkbWU7XG4gIH1cblxuICAvLyBsb2dzIHJlYWRtZSBub3QgZm91bmQgZXJyb3JcbiAgbG9nZ2VyLmluZm8oeyBwYWNrYWdlTmFtZSB9LCAnQHtwYWNrYWdlTmFtZX06IE5vIHJlYWRtZSBmb3VuZCcpO1xuXG4gIHJldHVybiAnRVJST1I6IE5vIFJFQURNRSBkYXRhIGZvdW5kISc7XG59XG5cbi8qKlxuICogcmV0dXJuIGEgbWFzcXVlcmFkZSBzdHJpbmcgd2l0aCBpdHMgZmlyc3QgYW5kIGxhc3Qge2NoYXJOdW19IGFuZCB0aHJlZSBkb3RzIGluIGJldHdlZW4uXG4gKiBAcGFyYW0ge1N0cmluZ30gc3RyXG4gKiBAcGFyYW0ge051bWJlcn0gY2hhck51bVxuICogQHJldHVybnMge1N0cmluZ31cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG1hc2soc3RyOiBzdHJpbmcsIGNoYXJOdW0gPSAzKTogc3RyaW5nIHtcbiAgcmV0dXJuIGAke3N0ci5zdWJzdHIoMCwgY2hhck51bSl9Li4uJHtzdHIuc3Vic3RyKC1jaGFyTnVtKX1gO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZW5jb2RlU2NvcGVkVXJpKHBhY2thZ2VOYW1lKTogc3RyaW5nIHtcbiAgcmV0dXJuIHBhY2thZ2VOYW1lLnJlcGxhY2UoL1xcLy9nLCAnJTJmJyk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBoYXNEaWZmT25lS2V5KHZlcnNpb25zKTogYm9vbGVhbiB7XG4gIHJldHVybiBPYmplY3Qua2V5cyh2ZXJzaW9ucykubGVuZ3RoICE9PSAxO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaXNWZXJzaW9uVmFsaWQocGFja2FnZU1ldGEsIHBhY2thZ2VWZXJzaW9uKTogYm9vbGVhbiB7XG4gIGNvbnN0IGhhc1ZlcnNpb24gPSB0eXBlb2YgcGFja2FnZVZlcnNpb24gIT09ICd1bmRlZmluZWQnO1xuICBpZiAoIWhhc1ZlcnNpb24pIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBjb25zdCBoYXNNYXRjaFZlcnNpb24gPSBPYmplY3Qua2V5cyhwYWNrYWdlTWV0YS52ZXJzaW9ucykuaW5jbHVkZXMocGFja2FnZVZlcnNpb24pO1xuICByZXR1cm4gaGFzTWF0Y2hWZXJzaW9uO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaXNSZWxhdGVkVG9EZXByZWNhdGlvbihwa2dJbmZvOiBNYW5pZmVzdCk6IGJvb2xlYW4ge1xuICBjb25zdCB7IHZlcnNpb25zIH0gPSBwa2dJbmZvO1xuICBmb3IgKGNvbnN0IHZlcnNpb24gaW4gdmVyc2lvbnMpIHtcbiAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHZlcnNpb25zW3ZlcnNpb25dLCAnZGVwcmVjYXRlZCcpKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGZhbHNlO1xufVxuXG4vKipcbiAqXG4gKiBAcGFyYW0gY29uZmlnXG4gKiBAZGVwcmVjYXRlZCB1c2UgQHZlcmRhY2Npby9taWRkbGV3YXJlXG4gKiBAcmV0dXJuc1xuICovXG5leHBvcnQgZnVuY3Rpb24gaGFzTG9naW4oY29uZmlnOiBDb25maWcpIHtcbiAgLy8gRklYTUU6IHR5cGVzIGFyZSBub3QgeWV0IG9uIHRoZSBsaWJyYXJ5IHZlcmRhY2Npby9tb25vcmVwb1xuICAvLyBAdHMtaWdub3JlXG4gIHJldHVybiBfLmlzTmlsKGNvbmZpZz8ud2ViPy5sb2dpbikgfHwgY29uZmlnPy53ZWI/LmxvZ2luID09PSB0cnVlO1xufVxuXG5leHBvcnQgeyBidWlsZFRva2VuVXRpbCBhcyBidWlsZFRva2VuLCBwYXJzZUNvbmZpZ0ZpbGUgfTtcbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSxJQUFBQSxHQUFBLEdBQUFDLHNCQUFBLENBQUFDLE9BQUE7QUFDQSxJQUFBQyxPQUFBLEdBQUFGLHNCQUFBLENBQUFDLE9BQUE7QUFDQSxJQUFBRSxPQUFBLEdBQUFILHNCQUFBLENBQUFDLE9BQUE7QUFFQSxJQUFBRyxPQUFBLEdBQUFILE9BQUE7QUFFQSxJQUFBSSxLQUFBLEdBQUFKLE9BQUE7QUFHQSxJQUFBSyxNQUFBLEdBQUFMLE9BQUE7QUFFQSxJQUFBTSxVQUFBLEdBQUFOLE9BQUE7QUFDQSxJQUFBTyxPQUFBLEdBQUFQLE9BQUE7QUFBa0MsU0FBQUQsdUJBQUFTLENBQUEsV0FBQUEsQ0FBQSxJQUFBQSxDQUFBLENBQUFDLFVBQUEsR0FBQUQsQ0FBQSxLQUFBRSxPQUFBLEVBQUFGLENBQUE7QUFQbEM7O0FBU0EsTUFBTTtFQUNKRyxVQUFVO0VBQ1ZDLGFBQWE7RUFDYkMsT0FBTztFQUNQQyxXQUFXO0VBQ1hDLFlBQVk7RUFDWkMsZ0JBQWdCO0VBQ2hCQyxXQUFXO0VBQ1hDLHFCQUFxQjtFQUNyQkM7QUFDRixDQUFDLEdBQUdDLGdCQUFVOztBQUVkO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxNQUFNQyxRQUFRLEdBQUFDLE9BQUEsQ0FBQUQsUUFBQSxHQUFHRSxxQkFBZSxDQUFDRixRQUFROztBQUVoRDtBQUNBO0FBQ0E7QUFDTyxTQUFTRyxlQUFlQSxDQUFDQyxHQUFRLEVBQVc7RUFDakQsT0FBT0MsZUFBQyxDQUFDTCxR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