UNPKG

verdaccio

Version:

A lightweight private npm proxy registry

157 lines (121 loc) 19.1 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.normalizeUserList = normalizeUserList; exports.uplinkSanityCheck = uplinkSanityCheck; exports.sanityCheckNames = sanityCheckNames; exports.sanityCheckUplinksProps = sanityCheckUplinksProps; exports.hasProxyTo = hasProxyTo; exports.getMatchedPackagesSpec = getMatchedPackagesSpec; exports.normalisePackageAccess = normalisePackageAccess; var _assert = _interopRequireDefault(require("assert")); var _lodash = _interopRequireDefault(require("lodash")); var _minimatch = _interopRequireDefault(require("minimatch")); var _utils = require("./utils"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } const BLACKLIST = { all: true, anonymous: true, undefined: true, owner: true, none: true }; /** * Normalize user list. * @return {Array} */ function normalizeUserList(oldFormat, newFormat) { const result = []; /* eslint prefer-rest-params: "off" */ for (let i = 0; i < arguments.length; i++) { if (arguments[i] == null) { continue; } // if it's a string, split it to array if (_lodash.default.isString(arguments[i])) { result.push(arguments[i].split(/\s+/)); } else if (Array.isArray(arguments[i])) { result.push(arguments[i]); } else { throw _utils.ErrorCode.getInternalError('CONFIG: bad package acl (array or string expected): ' + JSON.stringify(arguments[i])); } } return _lodash.default.flatten(result); } function uplinkSanityCheck(uplinks, users = BLACKLIST) { const newUplinks = _lodash.default.clone(uplinks); let newUsers = _lodash.default.clone(users); for (const uplink in newUplinks) { if (Object.prototype.hasOwnProperty.call(newUplinks, uplink)) { if (_lodash.default.isNil(newUplinks[uplink].cache)) { newUplinks[uplink].cache = true; } newUsers = sanityCheckNames(uplink, newUsers); } } return newUplinks; } function sanityCheckNames(item, users) { (0, _assert.default)(item !== 'all' && item !== 'owner' && item !== 'anonymous' && item !== 'undefined' && item !== 'none', 'CONFIG: reserved uplink name: ' + item); (0, _assert.default)(!item.match(/\s/), 'CONFIG: invalid uplink name: ' + item); (0, _assert.default)(_lodash.default.isNil(users[item]), 'CONFIG: duplicate uplink name: ' + item); users[item] = true; return users; } function sanityCheckUplinksProps(configUpLinks) { const uplinks = _lodash.default.clone(configUpLinks); for (const uplink in uplinks) { if (Object.prototype.hasOwnProperty.call(uplinks, uplink)) { (0, _assert.default)(uplinks[uplink].url, 'CONFIG: no url for uplink: ' + uplink); (0, _assert.default)(_lodash.default.isString(uplinks[uplink].url), 'CONFIG: wrong url format for uplink: ' + uplink); uplinks[uplink].url = uplinks[uplink].url.replace(/\/$/, ''); } } return uplinks; } /** * Check whether an uplink can proxy */ function hasProxyTo(pkg, upLink, packages) { const matchedPkg = getMatchedPackagesSpec(pkg, packages); const proxyList = typeof matchedPkg !== 'undefined' ? matchedPkg.proxy : []; if (proxyList) { return proxyList.some(curr => upLink === curr); } return false; } function getMatchedPackagesSpec(pkgName, packages) { for (const i in packages) { if (_minimatch.default.makeRe(i).exec(pkgName)) { return packages[i]; } } return; } function normalisePackageAccess(packages) { const normalizedPkgs = _objectSpread({}, packages); // add a default rule for all packages to make writing plugins easier if (_lodash.default.isNil(normalizedPkgs['**'])) { normalizedPkgs['**'] = { access: [], publish: [], proxy: [] }; } for (const pkg in packages) { if (Object.prototype.hasOwnProperty.call(packages, pkg)) { (0, _assert.default)(_lodash.default.isObject(packages[pkg]) && _lodash.default.isArray(packages[pkg]) === false, `CONFIG: bad "'${pkg}'" package description (object expected)`); normalizedPkgs[pkg].access = normalizeUserList(packages[pkg].allow_access, packages[pkg].access); delete normalizedPkgs[pkg].allow_access; normalizedPkgs[pkg].publish = normalizeUserList(packages[pkg].allow_publish, packages[pkg].publish); delete normalizedPkgs[pkg].allow_publish; normalizedPkgs[pkg].proxy = normalizeUserList(packages[pkg].proxy_access, packages[pkg].proxy); delete normalizedPkgs[pkg].proxy_access; // if unpublish is not defined, we set to false to fallback in publish access normalizedPkgs[pkg].unpublish = _lodash.default.isUndefined(packages[pkg].unpublish) ? false : normalizeUserList([], packages[pkg].unpublish); } } return normalizedPkgs; } //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9saWIvY29uZmlnLXV0aWxzLnRzIl0sIm5hbWVzIjpbIkJMQUNLTElTVCIsImFsbCIsImFub255bW91cyIsInVuZGVmaW5lZCIsIm93bmVyIiwibm9uZSIsIm5vcm1hbGl6ZVVzZXJMaXN0Iiwib2xkRm9ybWF0IiwibmV3Rm9ybWF0IiwicmVzdWx0IiwiaSIsImFyZ3VtZW50cyIsImxlbmd0aCIsIl8iLCJpc1N0cmluZyIsInB1c2giLCJzcGxpdCIsIkFycmF5IiwiaXNBcnJheSIsIkVycm9yQ29kZSIsImdldEludGVybmFsRXJyb3IiLCJKU09OIiwic3RyaW5naWZ5IiwiZmxhdHRlbiIsInVwbGlua1Nhbml0eUNoZWNrIiwidXBsaW5rcyIsInVzZXJzIiwibmV3VXBsaW5rcyIsImNsb25lIiwibmV3VXNlcnMiLCJ1cGxpbmsiLCJPYmplY3QiLCJwcm90b3R5cGUiLCJoYXNPd25Qcm9wZXJ0eSIsImNhbGwiLCJpc05pbCIsImNhY2hlIiwic2FuaXR5Q2hlY2tOYW1lcyIsIml0ZW0iLCJtYXRjaCIsInNhbml0eUNoZWNrVXBsaW5rc1Byb3BzIiwiY29uZmlnVXBMaW5rcyIsInVybCIsInJlcGxhY2UiLCJoYXNQcm94eVRvIiwicGtnIiwidXBMaW5rIiwicGFja2FnZXMiLCJtYXRjaGVkUGtnIiwiZ2V0TWF0Y2hlZFBhY2thZ2VzU3BlYyIsInByb3h5TGlzdCIsInByb3h5Iiwic29tZSIsImN1cnIiLCJwa2dOYW1lIiwibWluaW1hdGNoIiwibWFrZVJlIiwiZXhlYyIsIm5vcm1hbGlzZVBhY2thZ2VBY2Nlc3MiLCJub3JtYWxpemVkUGtncyIsImFjY2VzcyIsInB1Ymxpc2giLCJpc09iamVjdCIsImFsbG93X2FjY2VzcyIsImFsbG93X3B1Ymxpc2giLCJwcm94eV9hY2Nlc3MiLCJ1bnB1Ymxpc2giLCJpc1VuZGVmaW5lZCJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7OztBQUtBOztBQUNBOztBQUNBOztBQUlBOzs7Ozs7Ozs7O0FBRUEsTUFB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QSxhQUFPRCxjQUFjLENBQUNkLEdBQUQsQ0FBZCxDQUFvQmtCLFlBQTNCO0FBQ0FKLE1BQUFBLGNBQWMsQ0FBQ2QsR0FBRCxDQUFkLENBQW9CZ0IsT0FBcEIsR0FBOEJ2RCxpQkFBaUIsQ0FDN0N5QyxRQUFRLENBQUNGLEdBQUQsQ0FBUixDQUFjbUIsYUFEK0IsRUFFN0NqQixRQUFRLENBQUNGLEdBQUQsQ0FBUixDQUFjZ0IsT0FGK0IsQ0FBL0M7QUFJQSxhQUFPRixjQUFjLENBQUNkLEdBQUQsQ0FBZCxDQUFvQm1CLGFBQTNCO0FBQ0FMLE1BQUFBLGNBQWMsQ0FBQ2QsR0FBRCxDQUFkLENBQW9CTSxLQUFwQixHQUE0QjdDLGlCQUFpQixDQUMzQ3lDLFFBQVEsQ0FBQ0YsR0FBRCxDQUFSLENBQWNvQixZQUQ2QixFQUUzQ2xCLFFBQVEsQ0FBQ0YsR0FBRCxDQUFSLENBQWNNLEtBRjZCLENBQTdDO0FBSUEsYUFBT1EsY0FBYyxDQUFDZCxHQUFELENBQWQsQ0FBb0JvQixZQUEzQixDQW5CdUQsQ0FvQnZEOztBQUNBTixNQUFBQSxjQUFjLENBQUNkLEdBQUQsQ0FBZCxDQUFvQnFCLFNBQXBCLEdBQWdDckQsZ0JBQUVzRCxXQUFGLENBQWNwQixRQUFRLENBQUNGLEdBQUQsQ0FBUixDQUFjcUIsU0FBNUIsSUFDNUIsS0FENEIsR0FFNUI1RCxpQkFBaUIsQ0FBQyxFQUFELEVBQUt5QyxRQUFRLENBQUNGLEdBQUQsQ0FBUixDQUFjcUIsU0FBbkIsQ0FGckI7QUFHRDtBQUNGOztBQUVELFNBQU9QLGNBQVA7QUFDRCIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQHByZXR0aWVyXG4gKiBAZmxvd1xuICovXG5cbmltcG9ydCBhc3NlcnQgZnJvbSAnYXNzZXJ0JztcbmltcG9ydCBfIGZyb20gJ2xvZGFzaCc7XG5pbXBvcnQgbWluaW1hdGNoIGZyb20gJ21pbmltYXRjaCc7XG5cbmltcG9ydCB7IFBhY2thZ2VMaXN0LCBVcExpbmtzQ29uZkxpc3QgfSBmcm9tICdAdmVyZGFjY2lvL3R5cGVzJztcbmltcG9ydCB7IE1hdGNoZWRQYWNrYWdlLCBMZWdhY3lQYWNrYWdlTGlzdCB9IGZyb20gJy4uLy4uL3R5cGVzJztcbmltcG9ydCB7IEVycm9yQ29kZSB9IGZyb20gJy4vdXRpbHMnO1xuXG5jb25zdCBCTEFDS0xJU1QgPSB7XG4gIGFsbDogdHJ1ZSxcbiAgYW5vbnltb3VzOiB0cnVlLFxuICB1bmRlZmluZWQ6IHRydWUsXG4gIG93bmVyOiB0cnVlLFxuICBub25lOiB0cnVlXG59O1xuXG4vKipcbiAqIE5vcm1hbGl6ZSB1c2VyIGxpc3QuXG4gKiBAcmV0dXJuIHtBcnJheX1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG5vcm1hbGl6ZVVzZXJMaXN0KG9sZEZvcm1hdDogYW55LCBuZXdGb3JtYXQ6IGFueSk6IGFueSB7XG4gIGNvbnN0IHJlc3VsdDogYW55W11bXSA9IFtdO1xuICAvKiBlc2xpbnQgcHJlZmVyLXJlc3QtcGFyYW1zOiBcIm9mZlwiICovXG5cbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHtcbiAgICBpZiAoYXJndW1lbnRzW2ldID09IG51bGwpIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIC8vIGlmIGl0J3MgYSBzdHJpbmcsIHNwbGl0IGl0IHRvIGFycmF5XG4gICAgaWYgKF8uaXNTdHJpbmcoYXJndW1lbnRzW2ldKSkge1xuICAgICAgcmVzdWx0LnB1c2goYXJndW1lbnRzW2ldLnNwbGl0KC9cXHMrLykpO1xuICAgIH0gZWxzZSBpZiAoQXJyYXkuaXNBcnJheShhcmd1bWVudHNbaV0pKSB7XG4gICAgICByZXN1bHQucHVzaChhcmd1bWVudHNbaV0pO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aHJvdyBFcnJvckNvZGUuZ2V0SW50ZXJuYWxFcnJvcihcbiAgICAgICAgJ0NPTkZJRzogYmFkIHBhY2thZ2UgYWNsIChhcnJheSBvciBzdHJpbmcgZXhwZWN0ZWQpOiAnICsgSlNPTi5zdHJpbmdpZnkoYXJndW1lbnRzW2ldKVxuICAgICAgKTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIF8uZmxhdHRlbihyZXN1bHQpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gdXBsaW5rU2FuaXR5Q2hlY2soXG4gIHVwbGlua3M6IFVwTGlua3NDb25mTGlzdCxcbiAgdXNlcnM6IGFueSA9IEJMQUNLTElTVFxuKTogVXBMaW5rc0NvbmZMaXN0IHtcbiAgY29uc3QgbmV3VXBsaW5rcyA9IF8uY2xvbmUodXBsaW5rcyk7XG4gIGxldCBuZXdVc2VycyA9IF8uY2xvbmUodXNlcnMpO1xuXG4gIGZvciAoY29uc3QgdXBsaW5rIGluIG5ld1VwbGlua3MpIHtcbiAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG5ld1VwbGlua3MsIHVwbGluaykpIHtcbiAgICAgIGlmIChfLmlzTmlsKG5ld1VwbGlua3NbdXBsaW5rXS5jYWNoZSkpIHtcbiAgICAgICAgbmV3VXBsaW5rc1t1cGxpbmtdLmNhY2hlID0gdHJ1ZTtcbiAgICAgIH1cbiAgICAgIG5ld1VzZXJzID0gc2FuaXR5Q2hlY2tOYW1lcyh1cGxpbmssIG5ld1VzZXJzKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gbmV3VXBsaW5rcztcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHNhbml0eUNoZWNrTmFtZXMoaXRlbTogc3RyaW5nLCB1c2VyczogYW55KTogYW55IHtcbiAgYXNzZXJ0KFxuICAgIGl0ZW0gIT09ICdhbGwnICYmXG4gICAgICBpdGVtICE9PSAnb3duZXInICYmXG4gICAgICBpdGVtICE9PSAnYW5vbnltb3VzJyAmJlxuICAgICAgaXRlbSAhPT0gJ3VuZGVmaW5lZCcgJiZcbiAgICAgIGl0ZW0gIT09ICdub25lJyxcbiAgICAnQ09ORklHOiByZXNlcnZlZCB1cGxpbmsgbmFtZTogJyArIGl0ZW1cbiAgKTtcbiAgYXNzZXJ0KCFpdGVtLm1hdGNoKC9cXHMvKSwgJ0NPTkZJRzogaW52YWxpZCB1cGxpbmsgbmFtZTogJyArIGl0ZW0pO1xuICBhc3NlcnQoXy5pc05pbCh1c2Vyc1tpdGVtXSksICdDT05GSUc6IGR1cGxpY2F0ZSB1cGxpbmsgbmFtZTogJyArIGl0ZW0pO1xuICB1c2Vyc1tpdGVtXSA9IHRydWU7XG5cbiAgcmV0dXJuIHVzZXJzO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gc2FuaXR5Q2hlY2tVcGxpbmtzUHJvcHMoY29uZmlnVXBMaW5rczogVXBMaW5rc0NvbmZMaXN0KTogVXBMaW5rc0NvbmZMaXN0IHtcbiAgY29uc3QgdXBsaW5rcyA9IF8uY2xvbmUoY29uZmlnVXBMaW5rcyk7XG5cbiAgZm9yIChjb25zdCB1cGxpbmsgaW4gdXBsaW5rcykge1xuICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwodXBsaW5rcywgdXBsaW5rKSkge1xuICAgICAgYXNzZXJ0KHVwbGlua3NbdXBsaW5rXS51cmwsICdDT05GSUc6IG5vIHVybCBmb3IgdXBsaW5rOiAnICsgdXBsaW5rKTtcbiAgICAgIGFzc2VydChfLmlzU3RyaW5nKHVwbGlua3NbdXBsaW5rXS51cmwpLCAnQ09ORklHOiB3cm9uZyB1cmwgZm9ybWF0IGZvciB1cGxpbms6ICcgKyB1cGxpbmspO1xuICAgICAgdXBsaW5rc1t1cGxpbmtdLnVybCA9IHVwbGlua3NbdXBsaW5rXS51cmwucmVwbGFjZSgvXFwvJC8sICcnKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gdXBsaW5rcztcbn1cblxuLyoqXG4gKiBDaGVjayB3aGV0aGVyIGFuIHVwbGluayBjYW4gcHJveHlcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGhhc1Byb3h5VG8ocGtnOiBzdHJpbmcsIHVwTGluazogc3RyaW5nLCBwYWNrYWdlczogUGFja2FnZUxpc3QpOiBib29sZWFuIHtcbiAgY29uc3QgbWF0Y2hlZFBrZzogTWF0Y2hlZFBhY2thZ2UgPSBnZXRNYXRjaGVkUGFja2FnZXNTcGVjKHBrZywgcGFja2FnZXMpO1xuICBjb25zdCBwcm94eUxpc3QgPSB0eXBlb2YgbWF0Y2hlZFBrZyAhPT0gJ3VuZGVmaW5lZCcgPyBtYXRjaGVkUGtnLnByb3h5IDogW107XG4gIGlmIChwcm94eUxpc3QpIHtcbiAgICByZXR1cm4gcHJveHlMaXN0LnNvbWUoKGN1cnIpID0+IHVwTGluayA9PT0gY3Vycik7XG4gIH1cblxuICByZXR1cm4gZmFsc2U7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRNYXRjaGVkUGFja2FnZXNTcGVjKHBrZ05hbWU6IHN0cmluZywgcGFja2FnZXM6IFBhY2thZ2VMaXN0KTogTWF0Y2hlZFBhY2thZ2Uge1xuICBmb3IgKGNvbnN0IGkgaW4gcGFja2FnZXMpIHtcbiAgICBpZiAobWluaW1hdGNoLm1ha2VSZShpKS5leGVjKHBrZ05hbWUpKSB7XG4gICAgICByZXR1cm4gcGFja2FnZXNbaV07XG4gICAgfVxuICB9XG4gIHJldHVybjtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIG5vcm1hbGlzZVBhY2thZ2VBY2Nlc3MocGFja2FnZXM6IExlZ2FjeVBhY2thZ2VMaXN0KTogTGVnYWN5UGFja2FnZUxpc3Qge1xuICBjb25zdCBub3JtYWxpemVkUGtnczogTGVnYWN5UGFja2FnZUxpc3QgPSB7IC4uLnBhY2thZ2VzIH07XG4gIC8vIGFkZCBhIGRlZmF1bHQgcnVsZSBmb3IgYWxsIHBhY2thZ2VzIHRvIG1ha2Ugd3JpdGluZyBwbHVnaW5zIGVhc2llclxuICBpZiAoXy5pc05pbChub3JtYWxpemVkUGtnc1snKionXSkpIHtcbiAgICBub3JtYWxpemVkUGtnc1snKionXSA9IHsgYWNjZXNzOiBbXSwgcHVibGlzaDogW10sIHByb3h5OiBbXSB9O1xuICB9XG5cbiAgZm9yIChjb25zdCBwa2cgaW4gcGFja2FnZXMpIHtcbiAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHBhY2thZ2VzLCBwa2cpKSB7XG4gICAgICBhc3NlcnQoXG4gICAgICAgIF8uaXNPYmplY3QocGFja2FnZXNbcGtnXSkgJiYgXy5pc0FycmF5KHBhY2thZ2VzW3BrZ10pID09PSBmYWxzZSxcbiAgICAgICAgYENPTkZJRzogYmFkIFwiJyR7cGtnfSdcIiBwYWNrYWdlIGRlc2NyaXB0aW9uIChvYmplY3QgZXhwZWN0ZWQpYFxuICAgICAgKTtcbiAgICAgIG5vcm1hbGl6ZWRQa2dzW3BrZ10uYWNjZXNzID0gbm9ybWFsaXplVXNlckxpc3QoXG4gICAgICAgIHBhY2thZ2VzW3BrZ10uYWxsb3dfYWNjZXNzLFxuICAgICAgICBwYWNrYWdlc1twa2ddLmFjY2Vzc1xuICAgICAgKTtcbiAgICAgIGRlbGV0ZSBub3JtYWxpemVkUGtnc1twa2ddLmFsbG93X2FjY2VzcztcbiAgICAgIG5vcm1hbGl6ZWRQa2dzW3BrZ10ucHVibGlzaCA9IG5vcm1hbGl6ZVVzZXJMaXN0KFxuICAgICAgICBwYWNrYWdlc1twa2ddLmFsbG93X3B1Ymxpc2gsXG4gICAgICAgIHBhY2thZ2VzW3BrZ10ucHVibGlzaFxuICAgICAgKTtcbiAgICAgIGRlbGV0ZSBub3JtYWxpemVkUGtnc1twa2ddLmFsbG93X3B1Ymxpc2g7XG4gICAgICBub3JtYWxpemVkUGtnc1twa2ddLnByb3h5ID0gbm9ybWFsaXplVXNlckxpc3QoXG4gICAgICAgIHBhY2thZ2VzW3BrZ10ucHJveHlfYWNjZXNzLFxuICAgICAgICBwYWNrYWdlc1twa2ddLnByb3h5XG4gICAgICApO1xuICAgICAgZGVsZXRlIG5vcm1hbGl6ZWRQa2dzW3BrZ10ucHJveHlfYWNjZXNzO1xuICAgICAgLy8gaWYgdW5wdWJsaXNoIGlzIG5vdCBkZWZpbmVkLCB3ZSBzZXQgdG8gZmFsc2UgdG8gZmFsbGJhY2sgaW4gcHVibGlzaCBhY2Nlc3NcbiAgICAgIG5vcm1hbGl6ZWRQa2dzW3BrZ10udW5wdWJsaXNoID0gXy5pc1VuZGVmaW5lZChwYWNrYWdlc1twa2ddLnVucHVibGlzaClcbiAgICAgICAgPyBmYWxzZVxuICAgICAgICA6IG5vcm1hbGl6ZVVzZXJMaXN0KFtdLCBwYWNrYWdlc1twa2ddLnVucHVibGlzaCk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG5vcm1hbGl6ZWRQa2dzO1xufVxuIl19