verdaccio
Version:
A lightweight private npm proxy registry
274 lines (264 loc) • 32 kB
JavaScript
;
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.getVersion = getVersion;
exports.hasDiffOneKey = hasDiffOneKey;
exports.hasLogin = hasLogin;
exports.hasTarball = hasTarball;
exports.initLogger = initLogger;
exports.isObject = void 0;
exports.isObjectOrArray = isObjectOrArray;
exports.isRelatedToDeprecation = isRelatedToDeprecation;
exports.isVersionValid = isVersionValid;
exports.logHTTPSWarning = logHTTPSWarning;
exports.normalizeDistTags = normalizeDistTags;
Object.defineProperty(exports, "parseConfigFile", {
enumerable: true,
get: function () {
return _config.parseConfigFile;
}
});
exports.parseInterval = parseInterval;
exports.parseReadme = parseReadme;
exports.resolveConfigPath = void 0;
exports.sortByName = sortByName;
exports.tagVersion = tagVersion;
var _debug = _interopRequireDefault(require("debug"));
var _lodash = _interopRequireDefault(require("lodash"));
var _nodePath = _interopRequireDefault(require("node:path"));
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 }; }
const debug = (0, _debug.default)('verdaccio:lib:utils');
const {
getBadData,
getBadRequest,
getCode,
getConflict,
getForbidden,
getInternalError,
getNotFound,
getServiceUnavailable,
getUnauthorized
} = _core.errorUtils;
function initLogger(logConfig) {
if (logConfig.logs) {
logConfig.log = logConfig.logs;
_core.warningUtils.emit(_core.warningUtils.Codes.VERWAR002);
}
debug('initializing logger with config: %o', logConfig.log);
(0, _logger.setup)(logConfig.log);
}
function addScope(scope, packageName) {
return `@${scope}/${packageName}`;
}
/**
* 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 {
return undefined;
}
}
/**
* 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 = _core.pkgUtils.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.
sorted = _core.pkgUtils.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
};
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 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!';
}
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;
}
const resolveConfigPath = function (storageLocation, file) {
return _nodePath.default.resolve(_nodePath.default.dirname(storageLocation), file);
};
exports.resolveConfigPath = resolveConfigPath;
function logHTTPSWarning(storageLocation) {
_logger.logger.fatal(['You have enabled HTTPS and need to specify either ', ' "https.key" and "https.cert" or ', ' "https.pfx" and optionally "https.passphrase" ', 'to run https server', '',
// commands are borrowed from node.js docs
'To quickly create self-signed certificate, use:', ' $ openssl genrsa -out ' + resolveConfigPath(storageLocation, _constants.keyPem) + ' 2048', ' $ openssl req -new -sha256 -key ' + resolveConfigPath(storageLocation, _constants.keyPem) + ' -out ' + resolveConfigPath(storageLocation, _constants.csrPem), ' $ openssl x509 -req -in ' + resolveConfigPath(storageLocation, _constants.csrPem) + ' -signkey ' + resolveConfigPath(storageLocation, _constants.keyPem) + ' -out ' + resolveConfigPath(storageLocation, _constants.certPem), '', 'And then add to config file (' + storageLocation + '):', ' https:', ` key: ${resolveConfigPath(storageLocation, _constants.keyPem)}`, ` cert: ${resolveConfigPath(storageLocation, _constants.certPem)}`].join('\n'));
process.exit(2);
}
function hasLogin(config) {
return _lodash.default.isNil(config?.web?.login) || config?.web?.login === true;
}
/**
* Check whether any version in a package manifest has a tarball URL
* that matches the given filename.
*/
function hasTarball(pkg, filename) {
return Object.values(pkg.versions || {}).some(version => version.dist?.tarball?.endsWith('/' + filename));
}
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfZGVidWciLCJfaW50ZXJvcFJlcXVpcmVEZWZhdWx0IiwicmVxdWlyZSIsIl9sb2Rhc2giLCJfbm9kZVBhdGgiLCJfc2VtdmVyIiwiX2NvbmZpZyIsIl9jb3JlIiwiX3V0aWxzIiwiX2NvbnN0YW50cyIsIl9sb2dnZXIiLCJlIiwiX19lc01vZHVsZSIsImRlZmF1bHQiLCJkZWJ1ZyIsImNyZWF0ZURlYnVnIiwiZ2V0QmFkRGF0YSIsImdldEJhZFJlcXVlc3QiLCJnZXRDb2RlIiwiZ2V0Q29uZmxpY3QiLCJnZXRGb3JiaWRkZW4iLCJnZXRJbnRlcm5hbEVycm9yIiwiZ2V0Tm90Rm91bmQiLCJnZXRTZXJ2aWNlVW5hdmFpbGFibGUiLCJnZXRVbmF1dGhvcml6ZWQiLCJlcnJvclV0aWxzIiwiaW5pdExvZ2dlciIsImxvZ0NvbmZpZyIsImxvZ3MiLCJsb2ciLCJ3YXJuaW5nVXRpbHMiLCJlbWl0IiwiQ29kZXMiLCJWRVJXQVIwMDIiLCJzZXR1cCIsImFkZFNjb3BlIiwic2NvcGUiLCJwYWNrYWdlTmFtZSIsImlzT2JqZWN0IiwiZXhwb3J0cyIsInZhbGlkYXRpb25VdGlscyIsImlzT2JqZWN0T3JBcnJheSIsIm9iaiIsIl8iLCJpc051bGwiLCJ0YWdWZXJzaW9uIiwiZGF0YSIsInZlcnNpb24iLCJ0YWciLCJESVNUX1RBR1MiLCJzZW12ZXIiLCJwYXJzZSIsImdldFZlcnNpb24iLCJwa2ciLCJpc05pbCIsInZlcnNpb25zIiwidmVyc2lvbkl0ZW0iLCJjb21wYXJlIiwidW5kZWZpbmVkIiwibm9ybWFsaXplRGlzdFRhZ3MiLCJzb3J0ZWQiLCJsYXRlc3QiLCJwa2dVdGlscyIsInNlbXZlclNvcnQiLCJPYmplY3QiLCJrZXlzIiwibGVuZ3RoIiwicG9wIiwiaXNBcnJheSIsImlzU3RyaW5nIiwicGFyc2VJbnRlcnZhbFRhYmxlIiwibXMiLCJzIiwibSIsImgiLCJkIiwidyIsIk0iLCJ5IiwicGFyc2VJbnRlcnZhbCIsImludGVydmFsIiwicmVzdWx0IiwibGFzdF9zdWZmaXgiLCJJbmZpbml0eSIsInNwbGl0IiwiZm9yRWFjaCIsIngiLCJtYXRjaCIsIkVycm9yIiwiTnVtYmVyIiwiRXJyb3JDb2RlIiwic29ydEJ5TmFtZSIsInBhY2thZ2VzIiwib3JkZXJBc2NlbmRpbmciLCJzbGljZSIsInNvcnQiLCJhIiwiYiIsImNvbXBhcmF0b3JOYW1lcyIsIm5hbWUiLCJ0b0xvd2VyQ2FzZSIsImRlbGV0ZVByb3BlcnRpZXMiLCJwcm9wZXJ0aWVzVG9EZWxldGUiLCJvYmplY3RJdGVtIiwicHJvcGVydHkiLCJwYXJzZVJlYWRtZSIsInJlYWRtZSIsImlzRW1wdHkiLCJsb2dnZXIiLCJpbmZvIiwiZW5jb2RlU2NvcGVkVXJpIiwicmVwbGFjZSIsImhhc0RpZmZPbmVLZXkiLCJpc1ZlcnNpb25WYWxpZCIsInBhY2thZ2VNZXRhIiwicGFja2FnZVZlcnNpb24iLCJoYXNWZXJzaW9uIiwiaGFzTWF0Y2hWZXJzaW9uIiwiaW5jbHVkZXMiLCJpc1JlbGF0ZWRUb0RlcHJlY2F0aW9uIiwicGtnSW5mbyIsInByb3RvdHlwZSIsImhhc093blByb3BlcnR5IiwiY2FsbCIsInJlc29sdmVDb25maWdQYXRoIiwic3RvcmFnZUxvY2F0aW9uIiwiZmlsZSIsInBhdGgiLCJyZXNvbHZlIiwiZGlybmFtZSIsImxvZ0hUVFBTV2FybmluZyIsImZhdGFsIiwia2V5UGVtIiwiY3NyUGVtIiwiY2VydFBlbSIsImpvaW4iLCJwcm9jZXNzIiwiZXhpdCIsImhhc0xvZ2luIiwiY29uZmlnIiwid2ViIiwibG9naW4iLCJoYXNUYXJiYWxsIiwiZmlsZW5hbWUiLCJ2YWx1ZXMiLCJzb21lIiwiZGlzdCIsInRhcmJhbGwiLCJlbmRzV2l0aCJdLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9saWIvdXRpbHMudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IGNyZWF0ZURlYnVnIGZyb20gJ2RlYnVnJztcbmltcG9ydCBfIGZyb20gJ2xvZGFzaCc7XG5pbXBvcnQgcGF0aCBmcm9tICdub2RlOnBhdGgnO1xuaW1wb3J0IHNlbXZlciBmcm9tICdzZW12ZXInO1xuXG5pbXBvcnQgeyBwYXJzZUNvbmZpZ0ZpbGUgfSBmcm9tICdAdmVyZGFjY2lvL2NvbmZpZyc7XG5pbXBvcnQgeyBlcnJvclV0aWxzLCBwa2dVdGlscywgdmFsaWRhdGlvblV0aWxzLCB3YXJuaW5nVXRpbHMgfSBmcm9tICdAdmVyZGFjY2lvL2NvcmUnO1xuaW1wb3J0IHsgQ29uZmlnWWFtbCwgTG9nZ2VyQ29uZmlnSXRlbSwgU3RyaW5nVmFsdWUgfSBmcm9tICdAdmVyZGFjY2lvL3R5cGVzJztcbmltcG9ydCB7IENvbmZpZywgTWFuaWZlc3QsIFZlcnNpb24gfSBmcm9tICdAdmVyZGFjY2lvL3R5cGVzJztcbmltcG9ydCB7IGJ1aWxkVG9rZW4gYXMgYnVpbGRUb2tlblV0aWwgfSBmcm9tICdAdmVyZGFjY2lvL3V0aWxzJztcblxuaW1wb3J0IHsgRElTVF9UQUdTLCBjZXJ0UGVtLCBjc3JQZW0sIGtleVBlbSB9IGZyb20gJy4vY29uc3RhbnRzJztcbmltcG9ydCB7IGxvZ2dlciwgc2V0dXAgfSBmcm9tICcuL2xvZ2dlcic7XG5cbmNvbnN0IGRlYnVnID0gY3JlYXRlRGVidWcoJ3ZlcmRhY2NpbzpsaWI6dXRpbHMnKTtcblxuY29uc3Qge1xuICBnZXRCYWREYXRhLFxuICBnZXRCYWRSZXF1ZXN0LFxuICBnZXRDb2RlLFxuICBnZXRDb25mbGljdCxcbiAgZ2V0Rm9yYmlkZGVuLFxuICBnZXRJbnRlcm5hbEVycm9yLFxuICBnZXROb3RGb3VuZCxcbiAgZ2V0U2VydmljZVVuYXZhaWxhYmxlLFxuICBnZXRVbmF1dGhvcml6ZWQsXG59ID0gZXJyb3JVdGlscztcblxuZXhwb3J0IGZ1bmN0aW9uIGluaXRMb2dnZXIobG9nQ29uZmlnOiBDb25maWdZYW1sKSB7XG4gIGlmIChsb2dDb25maWcubG9ncykge1xuICAgIGxvZ0NvbmZpZy5sb2cgPSBsb2dDb25maWcubG9ncztcbiAgICB3YXJuaW5nVXRpbHMuZW1pdCh3YXJuaW5nVXRpbHMuQ29kZXMuVkVSV0FSMDAyKTtcbiAgfVxuICBkZWJ1ZygnaW5pdGlhbGl6aW5nIGxvZ2dlciB3aXRoIGNvbmZpZzogJW8nLCBsb2dDb25maWcubG9nKTtcbiAgc2V0dXAobG9nQ29uZmlnLmxvZyBhcyBMb2dnZXJDb25maWdJdGVtKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGFkZFNjb3BlKHNjb3BlOiBzdHJpbmcsIHBhY2thZ2VOYW1lOiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gYEAke3Njb3BlfS8ke3BhY2thZ2VOYW1lfWA7XG59XG5cbi8qKlxuICogQ2hlY2sgd2hldGhlciBhbiBlbGVtZW50IGlzIGFuIE9iamVjdFxuICogQHBhcmFtIHsqfSBvYmogdGhlIGVsZW1lbnRcbiAqIEByZXR1cm4ge0Jvb2xlYW59XG4gKi9cbmV4cG9ydCBjb25zdCBpc09iamVjdCA9IHZhbGlkYXRpb25VdGlscy5pc09iamVjdDtcblxuLyoqXG4gKiBAZGVwcmVjYXRlZCBub3QgdXNlZCB1biB2NlxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNPYmplY3RPckFycmF5KG9iajogYW55KTogYm9vbGVhbiB7XG4gIHJldHVybiBfLmlzT2JqZWN0KG9iaikgJiYgXy5pc051bGwob2JqKSA9PT0gZmFsc2U7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiB0YWdWZXJzaW9uKGRhdGE6IE1hbmlmZXN0LCB2ZXJzaW9uOiBzdHJpbmcsIHRhZzogU3RyaW5nVmFsdWUpOiBib29sZWFuIHtcbiAgaWYgKHRhZyAmJiBkYXRhW0RJU1RfVEFHU11bdGFnXSAhPT0gdmVyc2lvbiAmJiBzZW12ZXIucGFyc2UodmVyc2lvbiwgdHJ1ZSkpIHtcbiAgICAvLyB2YWxpZCB2ZXJzaW9uIC0gc3RvcmVcbiAgICBkYXRhW0RJU1RfVEFHU11bdGFnXSA9IHZlcnNpb247XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cbiAgcmV0dXJuIGZhbHNlO1xufVxuXG4vKipcbiAqIEdldHMgdmVyc2lvbiBmcm9tIGEgcGFja2FnZSBvYmplY3QgdGFraW5nIGludG8gYWNjb3VudCBzZW12ZXIgd2VpcmRuZXNzLlxuICogQHJldHVybiB7U3RyaW5nfSByZXR1cm4gdGhlIHNlbWFudGljIHZlcnNpb24gb2YgYSBwYWNrYWdlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRWZXJzaW9uKHBrZzogTWFuaWZlc3QsIHZlcnNpb246IGFueSk6IFZlcnNpb24gfCB2b2lkIHtcbiAgLy8gdGhpcyBjb25kaXRpb24gbXVzdCBhbGxvdyBjYXN0XG4gIGlmIChfLmlzTmlsKHBrZy52ZXJzaW9uc1t2ZXJzaW9uXSkgPT09IGZhbHNlKSB7XG4gICAgcmV0dXJuIHBrZy52ZXJzaW9uc1t2ZXJzaW9uXTtcbiAgfVxuXG4gIHRyeSB7XG4gICAgdmVyc2lvbiA9IHNlbXZlci5wYXJzZSh2ZXJzaW9uLCB0cnVlKTtcbiAgICBmb3IgKGNvbnN0IHZlcnNpb25JdGVtIGluIHBrZy52ZXJzaW9ucykge1xuICAgICAgaWYgKHZlcnNpb24uY29tcGFyZShzZW12ZXIucGFyc2UodmVyc2lvbkl0ZW0sIHRydWUpKSA9PT0gMCkge1xuICAgICAgICByZXR1cm4gcGtnLnZlcnNpb25zW3ZlcnNpb25JdGVtXTtcbiAgICAgIH1cbiAgICB9XG4gIH0gY2F0Y2gge1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cbn1cblxuLyoqXG4gKiBGbGF0dGVuIGFycmF5cyBvZiB0YWdzLlxuICogQHBhcmFtIHsqfSBkYXRhXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBub3JtYWxpemVEaXN0VGFncyhwa2c6IE1hbmlmZXN0KTogdm9pZCB7XG4gIGxldCBzb3J0ZWQ7XG4gIGlmICghcGtnW0RJU1RfVEFHU10ubGF0ZXN0KSB7XG4gICAgLy8gb3ZlcndyaXRlIGxhdGVzdCB3aXRoIGhpZ2hlc3Qga25vd24gdmVyc2lvbiBiYXNlZCBvbiBzZW12ZXIgc29ydFxuICAgIHNvcnRlZCA9IHBrZ1V0aWxzLnNlbXZlclNvcnQoT2JqZWN0LmtleXMocGtnLnZlcnNpb25zKSk7XG4gICAgaWYgKHNvcnRlZCAmJiBzb3J0ZWQubGVuZ3RoKSB7XG4gICAgICBwa2dbRElTVF9UQUdTXS5sYXRlc3QgPSBzb3J0ZWQucG9wKCk7XG4gICAgfVxuICB9XG5cbiAgZm9yIChjb25zdCB0YWcgaW4gcGtnW0RJU1RfVEFHU10pIHtcbiAgICBpZiAoXy5pc0FycmF5KHBrZ1tESVNUX1RBR1NdW3RhZ10pKSB7XG4gICAgICBpZiAocGtnW0RJU1RfVEFHU11bdGFnXS5sZW5ndGgpIHtcbiAgICAgICAgLy8gc29ydCBhcnJheVxuICAgICAgICAvLyBGSVhNRTogdGhpcyBpcyBjbGVhcmx5IHdyb25nLCB3ZSBuZWVkIHRvIHJlc2VhcmNoIHdoeSB0aGlzIGlzIGxpa2UgdGhpcy5cbiAgICAgICAgc29ydGVkID0gcGtnVXRpbHMuc2VtdmVyU29ydChwa2dbRElTVF9UQUdTXVt0YWddKTtcbiAgICAgICAgaWYgKHNvcnRlZC5sZW5ndGgpIHtcbiAgICAgICAgICAvLyB1c2UgaGlnaGVzdCB2ZXJzaW9uIGJhc2VkIG9uIHNlbXZlciBzb3J0XG4gICAgICAgICAgcGtnW0RJU1RfVEFHU11bdGFnXSA9IHNvcnRlZC5wb3AoKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZGVsZXRlIHBrZ1tESVNUX1RBR1NdW3RhZ107XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChfLmlzU3RyaW5nKHBrZ1tESVNUX1RBR1NdW3RhZ10pKSB7XG4gICAgICBpZiAoIXNlbXZlci5wYXJzZShwa2dbRElTVF9UQUdTXVt0YWddLCB0cnVlKSkge1xuICAgICAgICAvLyBpZiB0aGUgdmVyc2lvbiBpcyBpbnZhbGlkLCBkZWxldGUgdGhlIGRpc3QtdGFnIGVudHJ5XG4gICAgICAgIGRlbGV0ZSBwa2dbRElTVF9UQUdTXVt0YWddO1xuICAgICAgfVxuICAgIH1cbiAgfVxufVxuXG5jb25zdCBwYXJzZUludGVydmFsVGFibGUgPSB7XG4gICcnOiAxMDAwLFxuICBtczogMSxcbiAgczogMTAwMCxcbiAgbTogNjAgKiAxMDAwLFxuICBoOiA2MCAqIDYwICogMTAwMCxcbiAgZDogODY0MDAwMDAsXG4gIHc6IDcgKiA4NjQwMDAwMCxcbiAgTTogMzAgKiA4NjQwMDAwMCxcbiAgeTogMzY1ICogODY0MDAwMDAsXG59O1xuXG4vKipcbiAqIFBhcnNlIGFuIGludGVybmFsIHN0cmluZyB0byBudW1iZXJcbiAqIEBwYXJhbSB7Kn0gaW50ZXJ2YWxcbiAqIEByZXR1cm4ge051bWJlcn1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHBhcnNlSW50ZXJ2YWwoaW50ZXJ2YWw6IGFueSk6IG51bWJlciB7XG4gIGlmICh0eXBlb2YgaW50ZXJ2YWwgPT09ICdudW1iZXInKSB7XG4gICAgcmV0dXJuIGludGVydmFsICogMTAwMDtcbiAgfVxuICBsZXQgcmVzdWx0ID0gMDtcbiAgbGV0IGxhc3Rfc3VmZml4ID0gSW5maW5pdHk7XG4gIGludGVydmFsLnNwbGl0KC9cXHMrLykuZm9yRWFjaChmdW5jdGlvbiAoeCk6IHZvaWQge1xuICAgIGlmICgheCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBtID0geC5tYXRjaCgvXigoMHxbMS05XVswLTldKikoXFwuWzAtOV0rKT8pKG1zfHN8bXxofGR8d3xNfHl8KSQvKTtcbiAgICBpZiAoXG4gICAgICAhbSB8fFxuICAgICAgcGFyc2VJbnRlcnZhbFRhYmxlW21bNF1dID49IGxhc3Rfc3VmZml4IHx8XG4gICAgICAobVs0XSA9PT0gJycgJiYgbGFzdF9zdWZmaXggIT09IEluZmluaXR5KVxuICAgICkge1xuICAgICAgdGhyb3cgRXJyb3IoJ2ludmFsaWQgaW50ZXJ2YWw6ICcgKyBpbnRlcnZhbCk7XG4gICAgfVxuICAgIGxhc3Rfc3VmZml4ID0gcGFyc2VJbnRlcnZhbFRhYmxlW21bNF1dO1xuICAgIHJlc3VsdCArPSBOdW1iZXIobVsxXSkgKiBwYXJzZUludGVydmFsVGFibGVbbVs0XV07XG4gIH0pO1xuICByZXR1cm4gcmVzdWx0O1xufVxuXG5leHBvcnQgY29uc3QgRXJyb3JDb2RlID0ge1xuICBnZXRDb25mbGljdCxcbiAgZ2V0QmFkRGF0YSxcbiAgZ2V0QmFkUmVxdWVzdCxcbiAgZ2V0SW50ZXJuYWxFcnJvcixcbiAgZ2V0VW5hdXRob3JpemVkLFxuICBnZXRGb3JiaWRkZW4sXG4gIGdldFNlcnZpY2VVbmF2YWlsYWJsZSxcbiAgZ2V0Tm90Rm91bmQsXG4gIGdldENvZGUsXG59O1xuXG5leHBvcnQgZnVuY3Rpb24gc29ydEJ5TmFtZShwYWNrYWdlczogYW55W10sIG9yZGVyQXNjZW5kaW5nOiBib29sZWFuIHwgdm9pZCA9IHRydWUpOiBzdHJpbmdbXSB7XG4gIHJldHVybiBwYWNrYWdlcy5zbGljZSgpLnNvcnQoZnVuY3Rpb24gKGEsIGIpOiBudW1iZXIge1xuICAgIGNvbnN0IGNvbXBhcmF0b3JOYW1lcyA9IGEubmFtZS50b0xvd2VyQ2FzZSgpIDwgYi5uYW1lLnRvTG93ZXJDYXNlKCk7XG5cbiAgICByZXR1cm4gb3JkZXJBc2NlbmRpbmcgPyAoY29tcGFyYXRvck5hbWVzID8gLTEgOiAxKSA6IGNvbXBhcmF0b3JOYW1lcyA/IDEgOiAtMTtcbiAgfSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBkZWxldGVQcm9wZXJ0aWVzKHByb3BlcnRpZXNUb0RlbGV0ZTogc3RyaW5nW10sIG9iamVjdEl0ZW06IGFueSk6IGFueSB7XG4gIF8uZm9yRWFjaChwcm9wZXJ0aWVzVG9EZWxldGUsIChwcm9wZXJ0eSk6IGFueSA9PiB7XG4gICAgZGVsZXRlIG9iamVjdEl0ZW1bcHJvcGVydHldO1xuICB9KTtcblxuICByZXR1cm4gb2JqZWN0SXRlbTtcbn1cblxuLyoqXG4gKiBwYXJzZSBwYWNrYWdlIHJlYWRtZSAtIG1hcmtkb3duL2FzY2lpXG4gKiBAcGFyYW0ge1N0cmluZ30gcGFja2FnZU5hbWUgbmFtZSBvZiBwYWNrYWdlXG4gKiBAcGFyYW0ge1N0cmluZ30gcmVhZG1lIHBhY2thZ2UgcmVhZG1lXG5cbiAqIEByZXR1cm4ge1N0cmluZ30gY29udmVydGVkIGh0bWwgdGVtcGxhdGVcbiAqL1xuLy8gVE9ETzogcmVuYW1lLCBkb2VzIG5vdCBwYXJzZSBhbnltb3JlXG5leHBvcnQgZnVuY3Rpb24gcGFyc2VSZWFkbWUocGFja2FnZU5hbWU6IHN0cmluZywgcmVhZG1lOiBzdHJpbmcpOiBzdHJpbmcgfCB2b2lkIHtcbiAgaWYgKF8uaXNFbXB0eShyZWFkbWUpID09PSBmYWxzZSkge1xuICAgIHJldHVybiByZWFkbWU7XG4gIH1cblxuICAvLyBsb2dzIHJlYWRtZSBub3QgZm91bmQgZXJyb3JcbiAgbG9nZ2VyLmluZm8oeyBwYWNrYWdlTmFtZSB9LCAnQHtwYWNrYWdlTmFtZX06IE5vIHJlYWRtZSBmb3VuZCcpO1xuXG4gIHJldHVybiAnRVJST1I6IE5vIFJFQURNRSBkYXRhIGZvdW5kISc7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBlbmNvZGVTY29wZWRVcmkocGFja2FnZU5hbWUpOiBzdHJpbmcge1xuICByZXR1cm4gcGFja2FnZU5hbWUucmVwbGFjZSgvXFwvL2csICclMmYnKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGhhc0RpZmZPbmVLZXkodmVyc2lvbnMpOiBib29sZWFuIHtcbiAgcmV0dXJuIE9iamVjdC5rZXlzKHZlcnNpb25zKS5sZW5ndGggIT09IDE7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpc1ZlcnNpb25WYWxpZChwYWNrYWdlTWV0YSwgcGFja2FnZVZlcnNpb24pOiBib29sZWFuIHtcbiAgY29uc3QgaGFzVmVyc2lvbiA9IHR5cGVvZiBwYWNrYWdlVmVyc2lvbiAhPT0gJ3VuZGVmaW5lZCc7XG4gIGlmICghaGFzVmVyc2lvbikge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIGNvbnN0IGhhc01hdGNoVmVyc2lvbiA9IE9iamVjdC5rZXlzKHBhY2thZ2VNZXRhLnZlcnNpb25zKS5pbmNsdWRlcyhwYWNrYWdlVmVyc2lvbik7XG4gIHJldHVybiBoYXNNYXRjaFZlcnNpb247XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpc1JlbGF0ZWRUb0RlcHJlY2F0aW9uKHBrZ0luZm86IE1hbmlmZXN0KTogYm9vbGVhbiB7XG4gIGNvbnN0IHsgdmVyc2lvbnMgfSA9IHBrZ0luZm87XG4gIGZvciAoY29uc3QgdmVyc2lvbiBpbiB2ZXJzaW9ucykge1xuICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwodmVyc2lvbnNbdmVyc2lvbl0sICdkZXByZWNhdGVkJykpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgfVxuICByZXR1cm4gZmFsc2U7XG59XG5cbmV4cG9ydCBjb25zdCByZXNvbHZlQ29uZmlnUGF0aCA9IGZ1bmN0aW9uIChzdG9yYWdlTG9jYXRpb246IHN0cmluZywgZmlsZTogc3RyaW5nKSB7XG4gIHJldHVybiBwYXRoLnJlc29sdmUocGF0aC5kaXJuYW1lKHN0b3JhZ2VMb2NhdGlvbiksIGZpbGUpO1xufTtcblxuZXhwb3J0IGZ1bmN0aW9uIGxvZ0hUVFBTV2FybmluZyhzdG9yYWdlTG9jYXRpb24pIHtcbiAgbG9nZ2VyLmZhdGFsKFxuICAgIFtcbiAgICAgICdZb3UgaGF2ZSBlbmFibGVkIEhUVFBTIGFuZCBuZWVkIHRvIHNwZWNpZnkgZWl0aGVyICcsXG4gICAgICAnICAgIFwiaHR0cHMua2V5XCIgYW5kIFwiaHR0cHMuY2VydFwiIG9yICcsXG4gICAgICAnICAgIFwiaHR0cHMucGZ4XCIgYW5kIG9wdGlvbmFsbHkgXCJodHRwcy5wYXNzcGhyYXNlXCIgJyxcbiAgICAgICd0byBydW4gaHR0cHMgc2VydmVyJyxcbiAgICAgICcnLFxuICAgICAgLy8gY29tbWFuZHMgYXJlIGJvcnJvd2VkIGZyb20gbm9kZS5qcyBkb2NzXG4gICAgICAnVG8gcXVpY2tseSBjcmVhdGUgc2VsZi1zaWduZWQgY2VydGlmaWNhdGUsIHVzZTonLFxuICAgICAgJyAkIG9wZW5zc2wgZ2VucnNhIC1vdXQgJyArIHJlc29sdmVDb25maWdQYXRoKHN0b3JhZ2VMb2NhdGlvbiwga2V5UGVtKSArICcgMjA0OCcsXG4gICAgICAnICQgb3BlbnNzbCByZXEgLW5ldyAtc2hhMjU2IC1rZXkgJyArXG4gICAgICAgIHJlc29sdmVDb25maWdQYXRoKHN0b3JhZ2VMb2NhdGlvbiwga2V5UGVtKSArXG4gICAgICAgICcgLW91dCAnICtcbiAgICAgICAgcmVzb2x2ZUNvbmZpZ1BhdGgoc3RvcmFnZUxvY2F0aW9uLCBjc3JQZW0pLFxuICAgICAgJyAkIG9wZW5zc2wgeDUwOSAtcmVxIC1pbiAnICtcbiAgICAgICAgcmVzb2x2ZUNvbmZpZ1BhdGgoc3RvcmFnZUxvY2F0aW9uLCBjc3JQZW0pICtcbiAgICAgICAgJyAtc2lnbmtleSAnICtcbiAgICAgICAgcmVzb2x2ZUNvbmZpZ1BhdGgoc3RvcmFnZUxvY2F0aW9uLCBrZXlQZW0pICtcbiAgICAgICAgJyAtb3V0ICcgK1xuICAgICAgICByZXNvbHZlQ29uZmlnUGF0aChzdG9yYWdlTG9jYXRpb24sIGNlcnRQZW0pLFxuICAgICAgJycsXG4gICAgICAnQW5kIHRoZW4gYWRkIHRvIGNvbmZpZyBmaWxlICgnICsgc3RvcmFnZUxvY2F0aW9uICsgJyk6JyxcbiAgICAgICcgIGh0dHBzOicsXG4gICAgICBgICAgIGtleTogJHtyZXNvbHZlQ29uZmlnUGF0aChzdG9yYWdlTG9jYXRpb24sIGtleVBlbSl9YCxcbiAgICAgIGAgICAgY2VydDogJHtyZXNvbHZlQ29uZmlnUGF0aChzdG9yYWdlTG9jYXRpb24sIGNlcnRQZW0pfWAsXG4gICAgXS5qb2luKCdcXG4nKVxuICApO1xuICBwcm9jZXNzLmV4aXQoMik7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBoYXNMb2dpbihjb25maWc6IENvbmZpZykge1xuICByZXR1cm4gXy5pc05pbChjb25maWc/LndlYj8ubG9naW4pIHx8IGNvbmZpZz8ud2ViPy5sb2dpbiA9PT0gdHJ1ZTtcbn1cblxuLyoqXG4gKiBDaGVjayB3aGV0aGVyIGFueSB2ZXJzaW9uIGluIGEgcGFja2FnZSBtYW5pZmVzdCBoYXMgYSB0YXJiYWxsIFVSTFxuICogdGhhdCBtYXRjaGVzIHRoZSBnaXZlbiBmaWxlbmFtZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGhhc1RhcmJhbGwocGtnOiBNYW5pZmVzdCwgZmlsZW5hbWU6IHN0cmluZyk6IGJvb2xlYW4ge1xuICByZXR1cm4gT2JqZWN0LnZhbHVlcyhwa2cudmVyc2lvbnMgfHwge30pLnNvbWUoKHZlcnNpb24pID0+XG4gICAgKHZlcnNpb24gYXMgVmVyc2lvbikuZGlzdD8udGFyYmFsbD8uZW5kc1dpdGgoJy8nICsgZmlsZW5hbWUpXG4gICk7XG59XG5cbmV4cG9ydCB7IGJ1aWxkVG9rZW5VdGlsIGFzIGJ1aWxkVG9rZW4sIHBhcnNlQ29uZmlnRmlsZSB9O1xuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUEsSUFBQUEsTUFBQSxHQUFBQyxzQkFBQSxDQUFBQyxPQUFBO0FBQ0EsSUFBQUMsT0FBQSxHQUFBRixzQkFBQSxDQUFBQyxPQUFBO0FBQ0EsSUFBQUUsU0FBQSxHQUFBSCxzQkFBQSxDQUFBQyxPQUFBO0FBQ0EsSUFBQUcsT0FBQSxHQUFBSixzQkFBQSxDQUFBQyxPQUFBO0FBRUEsSUFBQUksT0FBQSxHQUFBSixPQUFBO0FBQ0EsSUFBQUssS0FBQSxHQUFBTCxPQUFBO0FBR0EsSUFBQU0sTUFBQSxHQUFBTixPQUFBO0FBRUEsSUFBQU8sVUFBQSxHQUFBUCxPQUFBO0FBQ0EsSUFBQVEsT0FBQSxHQUFBUixPQUFBO0FBQXlDLFNBQUFELHVCQUFBVSxDQUFBLFdBQUFBLENBQUEsSUFBQUEsQ0FBQSxDQUFBQyxVQUFBLEdBQUFELENBQUEsS0FBQUUsT0FBQSxFQUFBRixDQUFBO0FBRXpDLE1BQU1HLEtBQUssR0FBRyxJQUFBQyxjQUFXLEVBQUMscUJBQXFCLENBQUM7QUFFaEQsTUFBTTtFQUNKQyxVQUFVO0VBQ1ZDLGFBQWE7RUFDYkMsT0FBTztFQUNQQyxXQUFXO0VBQ1hDLFlBQVk7RUFDWkMsZ0JBQWdCO0VBQ2hCQyxXQUFXO0VBQ1hDLHFCQUFxQjtFQUNyQkM7QUFDRixDQUFDLEdBQUdDLGdCQUFVO0FBRVAsU0FBU0MsVUFBVUEsQ0FBQ0MsU0FBcUIsRUFBRTtFQUNoRCxJQUFJQSxTQUFTLENBQUND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