UNPKG

verdaccio

Version:

A lightweight private npm proxy registry

282 lines (273 loc) 34.9 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.WHITELIST = void 0; exports.checkPackageLocal = checkPackageLocal; exports.checkPackageRemote = checkPackageRemote; exports.cleanUpLinksRef = cleanUpLinksRef; exports.cleanUpReadme = cleanUpReadme; exports.convertAbbreviatedManifest = convertAbbreviatedManifest; exports.generatePackageTemplate = generatePackageTemplate; exports.generateRevision = generateRevision; exports.getLatestReadme = getLatestReadme; exports.hasInstallScript = hasInstallScript; exports.isPublishablePackage = isPublishablePackage; exports.mergeUplinkTimeIntoLocal = mergeUplinkTimeIntoLocal; exports.normalizePackage = normalizePackage; exports.prepareSearchPackage = prepareSearchPackage; exports.publishPackage = publishPackage; var _debug = _interopRequireDefault(require("debug")); var _lodash = _interopRequireDefault(require("lodash")); var _core = require("@verdaccio/core"); var _searchIndexer = require("@verdaccio/search-indexer"); var _utils = require("@verdaccio/utils"); var _constants = require("./constants"); var _logger = require("./logger"); var _utils2 = require("./utils"); function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; } const debug = (0, _debug.default)('verdaccio:storage-utils'); function generatePackageTemplate(name) { return { // standard things name, versions: {}, time: {}, [_constants.USERS]: {}, [_constants.DIST_TAGS]: {}, _uplinks: {}, _distfiles: {}, _attachments: {}, _rev: '' }; } /** * Normalize package properties, tags, revision id. * @param {Object} pkg package reference. */ function normalizePackage(pkg) { const pkgProperties = ['versions', 'dist-tags', '_distfiles', '_attachments', '_uplinks', 'time']; pkgProperties.forEach(key => { const pkgProp = pkg[key]; if (_lodash.default.isNil(pkgProp) || (0, _utils2.isObject)(pkgProp) === false) { pkg[key] = {}; } }); if (_lodash.default.isString(pkg._rev) === false) { pkg._rev = _constants.STORAGE.DEFAULT_REVISION; } if (_lodash.default.isString(pkg._id) === false) { pkg._id = pkg.name; } // normalize dist-tags (0, _utils2.normalizeDistTags)(pkg); return pkg; } function generateRevision(rev) { const _rev = rev.split('-'); return (+_rev[0] || 0) + 1 + '-' + (0, _utils.generateRandomHexString)(); } function getLatestReadme(pkg) { const versions = pkg['versions'] || {}; const distTags = pkg[_constants.DIST_TAGS] || {}; // FIXME: here is a bit tricky add the types const latestVersion = distTags['latest'] ? versions[distTags['latest']] || {} : {}; let readme = _lodash.default.trim(pkg.readme || latestVersion.readme || ''); if (readme) { return readme; } // In case of empty readme - trying to get ANY readme in the following order: 'next','beta','alpha','test','dev','canary' const readmeDistTagsPriority = ['next', 'beta', 'alpha', 'test', 'dev', 'canary']; readmeDistTagsPriority.map(function (tag) { if (readme) { return readme; } const version = distTags[tag] ? versions[distTags[tag]] || {} : {}; readme = _lodash.default.trim(version.readme || readme); }); return readme; } function cleanUpReadme(version) { if (_lodash.default.isNil(version) === false) { // @ts-ignore delete version.readme; } return version; } const WHITELIST = exports.WHITELIST = ['_rev', 'name', 'versions', 'dist-tags', 'readme', 'time', '_id', 'users']; function cleanUpLinksRef(keepUpLinkData, result) { const propertyToKeep = [...WHITELIST]; if (keepUpLinkData === true) { propertyToKeep.push('_uplinks'); } for (const i in result) { if (propertyToKeep.indexOf(i) === -1) { // Remove sections like '_uplinks' from response delete result[i]; } } return result; } /** * Check whether a package it is already a local package * @param {*} name * @param {*} localStorage */ function checkPackageLocal(name, localStorage) { return new Promise((resolve, reject) => { localStorage.getPackageMetadata(name, (err, results) => { if (!_lodash.default.isNil(err) && err.status !== _constants.HTTP_STATUS.NOT_FOUND) { return reject(err); } if (results) { return reject(_utils2.ErrorCode.getConflict(_constants.API_ERROR.PACKAGE_EXIST)); } return resolve(); }); }); } function publishPackage(name, metadata, localStorage) { return new Promise((resolve, reject) => { localStorage.addPackage(name, metadata, (err, latest) => { if (!_lodash.default.isNull(err)) { return reject(err); } else if (!_lodash.default.isUndefined(latest)) { _searchIndexer.SearchMemoryIndexer.add(latest).catch(reason => { debug('indexer has failed on add item %o', reason); _logger.logger.error('indexer has failed on add item'); }); } return resolve(); }); }); } function checkPackageRemote(name, isAllowPublishOffline, syncMetadata) { return new Promise((resolve, reject) => { syncMetadata(name, null, {}, (err, packageJsonLocal, upLinksErrors) => { // something weird if (err && err.status !== _constants.HTTP_STATUS.NOT_FOUND) { return reject(err); } // checking package exist already if (_lodash.default.isNil(packageJsonLocal) === false) { return reject(_utils2.ErrorCode.getConflict(_constants.API_ERROR.PACKAGE_EXIST)); } for (let errorItem = 0; errorItem < upLinksErrors.length; errorItem++) { // checking error // if uplink fails with a status other than 404, we report failure if (_lodash.default.isNil(upLinksErrors[errorItem][0]) === false) { if (upLinksErrors[errorItem][0].status !== _constants.HTTP_STATUS.NOT_FOUND) { if (isAllowPublishOffline) { return resolve(); } return reject(_utils2.ErrorCode.getServiceUnavailable(_constants.API_ERROR.UPLINK_OFFLINE_PUBLISH)); } } } return resolve(); }); }); } // tested on v6 function mergeUplinkTimeIntoLocal(cacheManifest, remoteManifest) { if ('time' in remoteManifest) { // remote override cache time conflicts return { ...cacheManifest, time: { ...cacheManifest.time, ...remoteManifest.time } }; } return cacheManifest; } function prepareSearchPackage(data, time) { const latest = _core.pkgUtils.getLatest(data); if (latest && data.versions[latest]) { const version = data.versions[latest]; const versions = { [latest]: 'latest' }; const pkg = { name: version.name, description: version.description, [_constants.DIST_TAGS]: { latest }, maintainers: version.maintainers || [version.author].filter(Boolean), author: version.author, repository: version.repository, readmeFilename: version.readmeFilename || '', homepage: version.homepage, keywords: version.keywords, time: { modified: time }, bugs: version.bugs, license: version.license, versions }; return pkg; } } /** * Check whether the package metadta has enough data to be published * @param pkg metadata */ function isPublishablePackage(pkg) { const keys = Object.keys(pkg); return keys.includes('versions'); } function hasInstallScript(version) { if (version?.scripts) { const scripts = Object.keys(version.scripts); return scripts.find(item => { return ['install', 'preinstall', 'postinstall'].includes(item); }) !== undefined; } return false; } function convertAbbreviatedManifest(manifest) { const abbreviatedVersions = Object.keys(manifest.versions).reduce((acc, version) => { const _version = manifest.versions[version]; // This should be align with this document // https://github.com/npm/registry/blob/master/docs/responses/package-metadata.md#abbreviated-version-object const _version_abbreviated = { name: _version.name, version: _version.version, description: _version.description, deprecated: _version.deprecated, bin: _version.bin, dist: _version.dist, engines: _version.engines, cpu: _version.cpu, os: _version.os, funding: _version.funding, directories: _version.directories, dependencies: _version.dependencies, devDependencies: _version.devDependencies, peerDependencies: _version.peerDependencies, peerDependenciesMeta: _version.peerDependenciesMeta, optionalDependencies: _version.optionalDependencies, bundleDependencies: _version.bundleDependencies, // npm cli specifics _hasShrinkwrap: _version._hasShrinkwrap, hasInstallScript: hasInstallScript(_version) }; acc[version] = _version_abbreviated; return acc; }, {}); const convertedManifest = { name: manifest['name'], [_constants.DIST_TAGS]: manifest[_constants.DIST_TAGS], versions: abbreviatedVersions, // @ts-ignore modified: manifest?.time?.modified, // NOTE: special case for pnpm https://github.com/pnpm/rfcs/pull/2 time: manifest?.time }; // @ts-ignore return convertedManifest; } //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfZGVidWciLCJfaW50ZXJvcFJlcXVpcmVEZWZhdWx0IiwicmVxdWlyZSIsIl9sb2Rhc2giLCJfY29yZSIsIl9zZWFyY2hJbmRleGVyIiwiX3V0aWxzIiwiX2NvbnN0YW50cyIsIl9sb2dnZXIiLCJfdXRpbHMyIiwiZSIsIl9fZXNNb2R1bGUiLCJkZWZhdWx0IiwiZGVidWciLCJjcmVhdGVEZWJ1ZyIsImdlbmVyYXRlUGFja2FnZVRlbXBsYXRlIiwibmFtZSIsInZlcnNpb25zIiwidGltZSIsIlVTRVJTIiwiRElTVF9UQUdTIiwiX3VwbGlua3MiLCJfZGlzdGZpbGVzIiwiX2F0dGFjaG1lbnRzIiwiX3JldiIsIm5vcm1hbGl6ZVBhY2thZ2UiLCJwa2ciLCJwa2dQcm9wZXJ0aWVzIiwiZm9yRWFjaCIsImtleSIsInBrZ1Byb3AiLCJfIiwiaXNOaWwiLCJpc09iamVjdCIsImlzU3RyaW5nIiwiU1RPUkFHRSIsIkRFRkFVTFRfUkVWSVNJT04iLCJfaWQiLCJub3JtYWxpemVEaXN0VGFncyIsImdlbmVyYXRlUmV2aXNpb24iLCJyZXYiLCJzcGxpdCIsImdlbmVyYXRlUmFuZG9tSGV4U3RyaW5nIiwiZ2V0TGF0ZXN0UmVhZG1lIiwiZGlzdFRhZ3MiLCJsYXRlc3RWZXJzaW9uIiwicmVhZG1lIiwidHJpbSIsInJlYWRtZURpc3RUYWdzUHJpb3JpdHkiLCJtYXAiLCJ0YWciLCJ2ZXJzaW9uIiwiY2xlYW5VcFJlYWRtZSIsIldISVRFTElTVCIsImV4cG9ydHMiLCJjbGVhblVwTGlua3NSZWYiLCJrZWVwVXBMaW5rRGF0YSIsInJlc3VsdCIsInByb3BlcnR5VG9LZWVwIiwicHVzaCIsImkiLCJpbmRleE9mIiwiY2hlY2tQYWNrYWdlTG9jYWwiLCJsb2NhbFN0b3JhZ2UiLCJQcm9taXNlIiwicmVzb2x2ZSIsInJlamVjdCIsImdldFBhY2thZ2VNZXRhZGF0YSIsImVyciIsInJlc3VsdHMiLCJzdGF0dXMiLCJIVFRQX1NUQVRVUyIsIk5PVF9GT1VORCIsIkVycm9yQ29kZSIsImdldENvbmZsaWN0IiwiQVBJX0VSUk9SIiwiUEFDS0FHRV9FWElTVCIsInB1Ymxpc2hQYWNrYWdlIiwibWV0YWRhdGEiLCJhZGRQYWNrYWdlIiwibGF0ZXN0IiwiaXNOdWxsIiwiaXNVbmRlZmluZWQiLCJTZWFyY2hNZW1vcnlJbmRleGVyIiwiYWRkIiwiY2F0Y2giLCJyZWFzb24iLCJsb2dnZXIiLCJlcnJvciIsImNoZWNrUGFja2FnZVJlbW90ZSIsImlzQWxsb3dQdWJsaXNoT2ZmbGluZSIsInN5bmNNZXRhZGF0YSIsInBhY2thZ2VKc29uTG9jYWwiLCJ1cExpbmtzRXJyb3JzIiwiZXJyb3JJdGVtIiwibGVuZ3RoIiwiZ2V0U2VydmljZVVuYXZhaWxhYmxlIiwiVVBMSU5LX09GRkxJTkVfUFVCTElTSCIsIm1lcmdlVXBsaW5rVGltZUludG9Mb2NhbCIsImNhY2hlTWFuaWZlc3QiLCJyZW1vdGVNYW5pZmVzdCIsInByZXBhcmVTZWFyY2hQYWNrYWdlIiwiZGF0YSIsInBrZ1V0aWxzIiwiZ2V0TGF0ZXN0IiwiZGVzY3JpcHRpb24iLCJtYWludGFpbmVycyIsImF1dGhvciIsImZpbHRlciIsIkJvb2xlYW4iLCJyZXBvc2l0b3J5IiwicmVhZG1lRmlsZW5hbWUiLCJob21lcGFnZSIsImtleXdvcmRzIiwibW9kaWZpZWQiLCJidWdzIiwibGljZW5zZSIsImlzUHVibGlzaGFibGVQYWNrYWdlIiwia2V5cyIsIk9iamVjdCIsImluY2x1ZGVzIiwiaGFzSW5zdGFsbFNjcmlwdCIsInNjcmlwdHMiLCJmaW5kIiwiaXRlbSIsInVuZGVmaW5lZCIsImNvbnZlcnRBYmJyZXZpYXRlZE1hbmlmZXN0IiwibWFuaWZlc3QiLCJhYmJyZXZpYXRlZFZlcnNpb25zIiwicmVkdWNlIiwiYWNjIiwiX3ZlcnNpb24iLCJfdmVyc2lvbl9hYmJyZXZpYXRlZCIsImRlcHJlY2F0ZWQiLCJiaW4iLCJkaXN0IiwiZW5naW5lcyIsImNwdSIsIm9zIiwiZnVuZGluZyIsImRpcmVjdG9yaWVzIiwiZGVwZW5kZW5jaWVzIiwiZGV2RGVwZW5kZW5jaWVzIiwicGVlckRlcGVuZGVuY2llcyIsInBlZXJEZXBlbmRlbmNpZXNNZXRhIiwib3B0aW9uYWxEZXBlbmRlbmNpZXMiLCJidW5kbGVEZXBlbmRlbmNpZXMiLCJfaGFzU2hyaW5rd3JhcCIsImNvbnZlcnRlZE1hbmlmZXN0Il0sInNvdXJjZXMiOlsiLi4vLi4vc3JjL2xpYi9zdG9yYWdlLXV0aWxzLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBjcmVhdGVEZWJ1ZyBmcm9tICdkZWJ1Zyc7XG5pbXBvcnQgXyBmcm9tICdsb2Rhc2gnO1xuXG5pbXBvcnQgeyBwa2dVdGlscyB9IGZyb20gJ0B2ZXJkYWNjaW8vY29yZSc7XG5pbXBvcnQgeyBTZWFyY2hNZW1vcnlJbmRleGVyIH0gZnJvbSAnQHZlcmRhY2Npby9zZWFyY2gtaW5kZXhlcic7XG5pbXBvcnQgeyBBYmJyZXZpYXRlZE1hbmlmZXN0LCBBYmJyZXZpYXRlZFZlcnNpb25zLCBNYW5pZmVzdCwgVmVyc2lvbiB9IGZyb20gJ0B2ZXJkYWNjaW8vdHlwZXMnO1xuaW1wb3J0IHsgZ2VuZXJhdGVSYW5kb21IZXhTdHJpbmcgfSBmcm9tICdAdmVyZGFjY2lvL3V0aWxzJztcblxuaW1wb3J0IHsgQVBJX0VSUk9SLCBESVNUX1RBR1MsIEhUVFBfU1RBVFVTLCBTVE9SQUdFLCBVU0VSUyB9IGZyb20gJy4vY29uc3RhbnRzJztcbmltcG9ydCBMb2NhbFN0b3JhZ2UgZnJvbSAnLi9sb2NhbC1zdG9yYWdlJztcbmltcG9ydCB7IGxvZ2dlciB9IGZyb20gJy4vbG9nZ2VyJztcbmltcG9ydCB7IEVycm9yQ29kZSwgaXNPYmplY3QsIG5vcm1hbGl6ZURpc3RUYWdzIH0gZnJvbSAnLi91dGlscyc7XG5cbmNvbnN0IGRlYnVnID0gY3JlYXRlRGVidWcoJ3ZlcmRhY2NpbzpzdG9yYWdlLXV0aWxzJyk7XG5cbmV4cG9ydCBmdW5jdGlvbiBnZW5lcmF0ZVBhY2thZ2VUZW1wbGF0ZShuYW1lOiBzdHJpbmcpOiBNYW5pZmVzdCB7XG4gIHJldHVybiB7XG4gICAgLy8gc3RhbmRhcmQgdGhpbmdzXG4gICAgbmFtZSxcbiAgICB2ZXJzaW9uczoge30sXG4gICAgdGltZToge30sXG4gICAgW1VTRVJTXToge30sXG4gICAgW0RJU1RfVEFHU106IHt9LFxuICAgIF91cGxpbmtzOiB7fSxcbiAgICBfZGlzdGZpbGVzOiB7fSxcbiAgICBfYXR0YWNobWVudHM6IHt9LFxuICAgIF9yZXY6ICcnLFxuICB9O1xufVxuXG4vKipcbiAqIE5vcm1hbGl6ZSBwYWNrYWdlIHByb3BlcnRpZXMsIHRhZ3MsIHJldmlzaW9uIGlkLlxuICogQHBhcmFtIHtPYmplY3R9IHBrZyBwYWNrYWdlIHJlZmVyZW5jZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG5vcm1hbGl6ZVBhY2thZ2UocGtnOiBNYW5pZmVzdCk6IE1hbmlmZXN0IHtcbiAgY29uc3QgcGtnUHJvcGVydGllcyA9IFsndmVyc2lvbnMnLCAnZGlzdC10YWdzJywgJ19kaXN0ZmlsZXMnLCAnX2F0dGFjaG1lbnRzJywgJ191cGxpbmtzJywgJ3RpbWUnXTtcblxuICBwa2dQcm9wZXJ0aWVzLmZvckVhY2goKGtleSk6IHZvaWQgPT4ge1xuICAgIGNvbnN0IHBrZ1Byb3AgPSBwa2dba2V5XTtcblxuICAgIGlmIChfLmlzTmlsKHBrZ1Byb3ApIHx8IGlzT2JqZWN0KHBrZ1Byb3ApID09PSBmYWxzZSkge1xuICAgICAgcGtnW2tleV0gPSB7fTtcbiAgICB9XG4gIH0pO1xuXG4gIGlmIChfLmlzU3RyaW5nKHBrZy5fcmV2KSA9PT0gZmFsc2UpIHtcbiAgICBwa2cuX3JldiA9IFNUT1JBR0UuREVGQVVMVF9SRVZJU0lPTjtcbiAgfVxuXG4gIGlmIChfLmlzU3RyaW5nKHBrZy5faWQpID09PSBmYWxzZSkge1xuICAgIHBrZy5faWQgPSBwa2cubmFtZTtcbiAgfVxuXG4gIC8vIG5vcm1hbGl6ZSBkaXN0LXRhZ3NcbiAgbm9ybWFsaXplRGlzdFRhZ3MocGtnKTtcblxuICByZXR1cm4gcGtnO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2VuZXJhdGVSZXZpc2lvbihyZXY6IHN0cmluZyk6IHN0cmluZyB7XG4gIGNvbnN0IF9yZXYgPSByZXYuc3BsaXQoJy0nKTtcblxuICByZXR1cm4gKCtfcmV2WzBdIHx8IDApICsgMSArICctJyArIGdlbmVyYXRlUmFuZG9tSGV4U3RyaW5nKCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRMYXRlc3RSZWFkbWUocGtnOiBNYW5pZmVzdCk6IHN0cmluZyB7XG4gIGNvbnN0IHZlcnNpb25zID0gcGtnWyd2ZXJzaW9ucyddIHx8IHt9O1xuICBjb25zdCBkaXN0VGFncyA9IHBrZ1tESVNUX1RBR1NdIHx8IHt9O1xuICAvLyBGSVhNRTogaGVyZSBpcyBhIGJpdCB0cmlja3kgYWRkIHRoZSB0eXBlc1xuICBjb25zdCBsYXRlc3RWZXJzaW9uOiBWZXJzaW9uIHwgYW55ID0gZGlzdFRhZ3NbJ2xhdGVzdCddID8gdmVyc2lvbnNbZGlzdFRhZ3NbJ2xhdGVzdCddXSB8fCB7fSA6IHt9O1xuICBsZXQgcmVhZG1lID0gXy50cmltKHBrZy5yZWFkbWUgfHwgbGF0ZXN0VmVyc2lvbi5yZWFkbWUgfHwgJycpO1xuICBpZiAocmVhZG1lKSB7XG4gICAgcmV0dXJuIHJlYWRtZTtcbiAgfVxuXG4gIC8vIEluIGNhc2Ugb2YgZW1wdHkgcmVhZG1lIC0gdHJ5aW5nIHRvIGdldCBBTlkgcmVhZG1lIGluIHRoZSBmb2xsb3dpbmcgb3JkZXI6ICduZXh0JywnYmV0YScsJ2FscGhhJywndGVzdCcsJ2RldicsJ2NhbmFyeSdcbiAgY29uc3QgcmVhZG1lRGlzdFRhZ3NQcmlvcml0eSA9IFsnbmV4dCcsICdiZXRhJywgJ2FscGhhJywgJ3Rlc3QnLCAnZGV2JywgJ2NhbmFyeSddO1xuICByZWFkbWVEaXN0VGFnc1ByaW9yaXR5Lm1hcChmdW5jdGlvbiAodGFnKTogc3RyaW5nIHwgdm9pZCB7XG4gICAgaWYgKHJlYWRtZSkge1xuICAgICAgcmV0dXJuIHJlYWRtZTtcbiAgICB9XG4gICAgY29uc3QgdmVyc2lvbjogVmVyc2lvbiB8IGFueSA9IGRpc3RUYWdzW3RhZ10gPyB2ZXJzaW9uc1tkaXN0VGFnc1t0YWddXSB8fCB7fSA6IHt9O1xuICAgIHJlYWRtZSA9IF8udHJpbSh2ZXJzaW9uLnJlYWRtZSB8fCByZWFkbWUpO1xuICB9KTtcbiAgcmV0dXJuIHJlYWRtZTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGNsZWFuVXBSZWFkbWUodmVyc2lvbjogVmVyc2lvbik6IFZlcnNpb24ge1xuICBpZiAoXy5pc05pbCh2ZXJzaW9uKSA9PT0gZmFsc2UpIHtcbiAgICAvLyBAdHMtaWdub3JlXG4gICAgZGVsZXRlIHZlcnNpb24ucmVhZG1lO1xuICB9XG5cbiAgcmV0dXJuIHZlcnNpb247XG59XG5cbmV4cG9ydCBjb25zdCBXSElURUxJU1QgPSBbXG4gICdfcmV2JyxcbiAgJ25hbWUnLFxuICAndmVyc2lvbnMnLFxuICAnZGlzdC10YWdzJyxcbiAgJ3JlYWRtZScsXG4gICd0aW1lJyxcbiAgJ19pZCcsXG4gICd1c2VycycsXG5dO1xuXG5leHBvcnQgZnVuY3Rpb24gY2xlYW5VcExpbmtzUmVmKGtlZXBVcExpbmtEYXRhOiBib29sZWFuLCByZXN1bHQ6IE1hbmlmZXN0KTogTWFuaWZlc3Qge1xuICBjb25zdCBwcm9wZXJ0eVRvS2VlcCA9IFsuLi5XSElURUxJU1RdO1xuICBpZiAoa2VlcFVwTGlua0RhdGEgPT09IHRydWUpIHtcbiAgICBwcm9wZXJ0eVRvS2VlcC5wdXNoKCdfdXBsaW5rcycpO1xuICB9XG5cbiAgZm9yIChjb25zdCBpIGluIHJlc3VsdCkge1xuICAgIGlmIChwcm9wZXJ0eVRvS2VlcC5pbmRleE9mKGkpID09PSAtMSkge1xuICAgICAgLy8gUmVtb3ZlIHNlY3Rpb25zIGxpa2UgJ191cGxpbmtzJyBmcm9tIHJlc3BvbnNlXG4gICAgICBkZWxldGUgcmVzdWx0W2ldO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiByZXN1bHQ7XG59XG5cbi8qKlxuICogQ2hlY2sgd2hldGhlciBhIHBhY2thZ2UgaXQgaXMgYWxyZWFkeSBhIGxvY2FsIHBhY2thZ2VcbiAqIEBwYXJhbSB7Kn0gbmFtZVxuICogQHBhcmFtIHsqfSBsb2NhbFN0b3JhZ2VcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNoZWNrUGFja2FnZUxvY2FsKG5hbWU6IHN0cmluZywgbG9jYWxTdG9yYWdlOiBMb2NhbFN0b3JhZ2UpOiBQcm9taXNlPHZvaWQ+IHtcbiAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpOiB2b2lkID0+IHtcbiAgICBsb2NhbFN0b3JhZ2UuZ2V0UGFja2FnZU1ldGFkYXRhKG5hbWUsIChlcnIsIHJlc3VsdHMpOiB2b2lkID0+IHtcbiAgICAgIGlmICghXy5pc05pbChlcnIpICYmIGVyci5zdGF0dXMgIT09IEhUVFBfU1RBVFVTLk5PVF9GT1VORCkge1xuICAgICAgICByZXR1cm4gcmVqZWN0KGVycik7XG4gICAgICB9XG4gICAgICBpZiAocmVzdWx0cykge1xuICAgICAgICByZXR1cm4gcmVqZWN0KEVycm9yQ29kZS5nZXRDb25mbGljdChBUElfRVJST1IuUEFDS0FHRV9FWElTVCkpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHJlc29sdmUoKTtcbiAgICB9KTtcbiAgfSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBwdWJsaXNoUGFja2FnZShcbiAgbmFtZTogc3RyaW5nLFxuICBtZXRhZGF0YTogYW55LFxuICBsb2NhbFN0b3JhZ2U6IExvY2FsU3RvcmFnZVxuKTogUHJvbWlzZTx2b2lkPiB7XG4gIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KTogdm9pZCA9PiB7XG4gICAgbG9jYWxTdG9yYWdlLmFkZFBhY2thZ2UobmFtZSwgbWV0YWRhdGEsIChlcnIsIGxhdGVzdCk6IHZvaWQgPT4ge1xuICAgICAgaWYgKCFfLmlzTnVsbChlcnIpKSB7XG4gICAgICAgIHJldHVybiByZWplY3QoZXJyKTtcbiAgICAgIH0gZWxzZSBpZiAoIV8uaXNVbmRlZmluZWQobGF0ZXN0KSkge1xuICAgICAgICBTZWFyY2hNZW1vcnlJbmRleGVyLmFkZChsYXRlc3QpLmNhdGNoKChyZWFzb24pID0+IHtcbiAgICAgICAgICBkZWJ1ZygnaW5kZXhlciBoYXMgZmFpbGVkIG9uIGFkZCBpdGVtICVvJywgcmVhc29uKTtcbiAgICAgICAgICBsb2dnZXIuZXJyb3IoJ2luZGV4ZXIgaGFzIGZhaWxlZCBvbiBhZGQgaXRlbScpO1xuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIHJldHVybiByZXNvbHZlKCk7XG4gICAgfSk7XG4gIH0pO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gY2hlY2tQYWNrYWdlUmVtb3RlKFxuICBuYW1lOiBzdHJpbmcsXG4gIGlzQWxsb3dQdWJsaXNoT2ZmbGluZTogYm9vbGVhbixcbiAgc3luY01ldGFkYXRhOiBhbnlcbik6IFByb21pc2U8dm9pZD4ge1xuICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCk6IHZvaWQgPT4ge1xuICAgIHN5bmNNZXRhZGF0YShuYW1lLCBudWxsLCB7fSwgKGVyciwgcGFja2FnZUpzb25Mb2NhbCwgdXBMaW5rc0Vycm9ycyk6IHZvaWQgPT4ge1xuICAgICAgLy8gc29tZXRoaW5nIHdlaXJkXG4gICAgICBpZiAoZXJyICYmIGVyci5zdGF0dXMgIT09IEhUVFBfU1RBVFVTLk5PVF9GT1VORCkge1xuICAgICAgICByZXR1cm4gcmVqZWN0KGVycik7XG4gICAgICB9XG5cbiAgICAgIC8vIGNoZWNraW5nIHBhY2thZ2UgZXhpc3QgYWxyZWFkeVxuICAgICAgaWYgKF8uaXNOaWwocGFja2FnZUpzb25Mb2NhbCkgPT09IGZhbHNlKSB7XG4gICAgICAgIHJldHVybiByZWplY3QoRXJyb3JDb2RlLmdldENvbmZsaWN0KEFQSV9FUlJPUi5QQUNLQUdFX0VYSVNUKSk7XG4gICAgICB9XG5cbiAgICAgIGZvciAobGV0IGVycm9ySXRlbSA9IDA7IGVycm9ySXRlbSA8IHVwTGlua3NFcnJvcnMubGVuZ3RoOyBlcnJvckl0ZW0rKykge1xuICAgICAgICAvLyBjaGVja2luZyBlcnJvclxuICAgICAgICAvLyBpZiB1cGxpbmsgZmFpbHMgd2l0aCBhIHN0YXR1cyBvdGhlciB0aGFuIDQwNCwgd2UgcmVwb3J0IGZhaWx1cmVcbiAgICAgICAgaWYgKF8uaXNOaWwodXBMaW5rc0Vycm9yc1tlcnJvckl0ZW1dWzBdKSA9PT0gZmFsc2UpIHtcbiAgICAgICAgICBpZiAodXBMaW5rc0Vycm9yc1tlcnJvckl0ZW1dWzBdLnN0YXR1cyAhPT0gSFRUUF9TVEFUVVMuTk9UX0ZPVU5EKSB7XG4gICAgICAgICAgICBpZiAoaXNBbGxvd1B1Ymxpc2hPZmZsaW5lKSB7XG4gICAgICAgICAgICAgIHJldHVybiByZXNvbHZlKCk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiByZWplY3QoRXJyb3JDb2RlLmdldFNlcnZpY2VVbmF2YWlsYWJsZShBUElfRVJST1IuVVBMSU5LX09GRkxJTkVfUFVCTElTSCkpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICByZXR1cm4gcmVzb2x2ZSgpO1xuICAgIH0pO1xuICB9KTtcbn1cblxuLy8gdGVzdGVkIG9uIHY2XG5leHBvcnQgZnVuY3Rpb24gbWVyZ2VVcGxpbmtUaW1lSW50b0xvY2FsKGNhY2hlTWFuaWZlc3Q6IE1hbmlmZXN0LCByZW1vdGVNYW5pZmVzdDogTWFuaWZlc3QpOiBhbnkge1xuICBpZiAoJ3RpbWUnIGluIHJlbW90ZU1hbmlmZXN0KSB7XG4gICAgLy8gcmVtb3RlIG92ZXJyaWRlIGNhY2hlIHRpbWUgY29uZmxpY3RzXG4gICAgcmV0dXJuIHsgLi4uY2FjaGVNYW5pZmVzdCwgdGltZTogeyAuLi5jYWNoZU1hbmlmZXN0LnRpbWUsIC4uLnJlbW90ZU1hbmlmZXN0LnRpbWUgfSB9O1xuICB9XG5cbiAgcmV0dXJuIGNhY2hlTWFuaWZlc3Q7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBwcmVwYXJlU2VhcmNoUGFja2FnZShkYXRhOiBNYW5pZmVzdCwgdGltZTogdW5rbm93bik6IGFueSB7XG4gIGNvbnN0IGxhdGVzdCA9IHBrZ1V0aWxzLmdldExhdGVzdChkYXRhKTtcblxuICBpZiAobGF0ZXN0ICYmIGRhdGEudmVyc2lvbnNbbGF0ZXN0XSkge1xuICAgIGNvbnN0IHZlcnNpb246IFZlcnNpb24gPSBkYXRhLnZlcnNpb25zW2xhdGVzdF07XG4gICAgY29uc3QgdmVyc2lvbnM6IGFueSA9IHsgW2xhdGVzdF06ICdsYXRlc3QnIH07XG4gICAgY29uc3QgcGtnOiBhbnkgPSB7XG4gICAgICBuYW1lOiB2ZXJzaW9uLm5hbWUsXG4gICAgICBkZXNjcmlwdGlvbjogdmVyc2lvbi5kZXNjcmlwdGlvbixcbiAgICAgIFtESVNUX1RBR1NdOiB7IGxhdGVzdCB9LFxuICAgICAgbWFpbnRhaW5lcnM6IHZlcnNpb24ubWFpbnRhaW5lcnMgfHwgW3ZlcnNpb24uYXV0aG9yXS5maWx0ZXIoQm9vbGVhbiksXG4gICAgICBhdXRob3I6IHZlcnNpb24uYXV0aG9yLFxuICAgICAgcmVwb3NpdG9yeTogdmVyc2lvbi5yZXBvc2l0b3J5LFxuICAgICAgcmVhZG1lRmlsZW5hbWU6IHZlcnNpb24ucmVhZG1lRmlsZW5hbWUgfHwgJycsXG4gICAgICBob21lcGFnZTogdmVyc2lvbi5ob21lcGFnZSxcbiAgICAgIGtleXdvcmRzOiB2ZXJzaW9uLmtleXdvcmRzLFxuICAgICAgdGltZToge1xuICAgICAgICBtb2RpZmllZDogdGltZSxcbiAgICAgIH0sXG4gICAgICBidWdzOiB2ZXJzaW9uLmJ1Z3MsXG4gICAgICBsaWNlbnNlOiB2ZXJzaW9uLmxpY2Vuc2UsXG4gICAgICB2ZXJzaW9ucyxcbiAgICB9O1xuXG4gICAgcmV0dXJuIHBrZztcbiAgfVxufVxuXG4vKipcbiAqIENoZWNrIHdoZXRoZXIgdGhlIHBhY2thZ2UgbWV0YWR0YSBoYXMgZW5vdWdoIGRhdGEgdG8gYmUgcHVibGlzaGVkXG4gKiBAcGFyYW0gcGtnIG1ldGFkYXRhXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc1B1Ymxpc2hhYmxlUGFja2FnZShwa2c6IE1hbmlmZXN0KTogYm9vbGVhbiB7XG4gIGNvbnN0IGtleXM6IHN0cmluZ1tdID0gT2JqZWN0LmtleXMocGtnKTtcblxuICByZXR1cm4ga2V5cy5pbmNsdWRlcygndmVyc2lvbnMnKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGhhc0luc3RhbGxTY3JpcHQodmVyc2lvbjogVmVyc2lvbikge1xuICBpZiAodmVyc2lvbj8uc2NyaXB0cykge1xuICAgIGNvbnN0IHNjcmlwdHMgPSBPYmplY3Qua2V5cyh2ZXJzaW9uLnNjcmlwdHMpO1xuICAgIHJldHVybiAoXG4gICAgICBzY3JpcHRzLmZpbmQoKGl0ZW0pID0+IHtcbiAgICAgICAgcmV0dXJuIFsnaW5zdGFsbCcsICdwcmVpbnN0YWxsJywgJ3Bvc3RpbnN0YWxsJ10uaW5jbHVkZXMoaXRlbSk7XG4gICAgICB9KSAhPT0gdW5kZWZpbmVkXG4gICAgKTtcbiAgfVxuICByZXR1cm4gZmFsc2U7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjb252ZXJ0QWJicmV2aWF0ZWRNYW5pZmVzdChtYW5pZmVzdDogTWFuaWZlc3QpOiBBYmJyZXZpYXRlZE1hbmlmZXN0IHtcbiAgY29uc3QgYWJicmV2aWF0ZWRWZXJzaW9ucyA9IE9iamVjdC5rZXlzKG1hbmlmZXN0LnZlcnNpb25zKS5yZWR1Y2UoXG4gICAgKGFjYzogQWJicmV2aWF0ZWRWZXJzaW9ucywgdmVyc2lvbjogc3RyaW5nKSA9PiB7XG4gICAgICBjb25zdCBfdmVyc2lvbiA9IG1hbmlmZXN0LnZlcnNpb25zW3ZlcnNpb25dO1xuICAgICAgLy8gVGhpcyBzaG91bGQgYmUgYWxpZ24gd2l0aCB0aGlzIGRvY3VtZW50XG4gICAgICAvLyBodHRwczovL2dpdGh1Yi5jb20vbnBtL3JlZ2lzdHJ5L2Jsb2IvbWFzdGVyL2RvY3MvcmVzcG9uc2VzL3BhY2thZ2UtbWV0YWRhdGEubWQjYWJicmV2aWF0ZWQtdmVyc2lvbi1vYmplY3RcbiAgICAgIGNvbnN0IF92ZXJzaW9uX2FiYnJldmlhdGVkID0ge1xuICAgICAgICBuYW1lOiBfdmVyc2lvbi5uYW1lLFxuICAgICAgICB2ZXJzaW9uOiBfdmVyc2lvbi52ZXJzaW9uLFxuICAgICAgICBkZXNjcmlwdGlvbjogX3ZlcnNpb24uZGVzY3JpcHRpb24sXG4gICAgICAgIGRlcHJlY2F0ZWQ6IF92ZXJzaW9uLmRlcHJlY2F0ZWQsXG4gICAgICAgIGJpbjogX3ZlcnNpb24uYmluLFxuICAgICAgICBkaXN0OiBfdmVyc2lvbi5kaXN0LFxuICAgICAgICBlbmdpbmVzOiBfdmVyc2lvbi5lbmdpbmVzLFxuICAgICAgICBjcHU6IF92ZXJzaW9uLmNwdSxcbiAgICAgICAgb3M6IF92ZXJzaW9uLm9zLFxuICAgICAgICBmdW5kaW5nOiBfdmVyc2lvbi5mdW5kaW5nLFxuICAgICAgICBkaXJlY3RvcmllczogX3ZlcnNpb24uZGlyZWN0b3JpZXMsXG4gICAgICAgIGRlcGVuZGVuY2llczogX3ZlcnNpb24uZGVwZW5kZW5jaWVzLFxuICAgICAgICBkZXZEZXBlbmRlbmNpZXM6IF92ZXJzaW9uLmRldkRlcGVuZGVuY2llcyxcbiAgICAgICAgcGVlckRlcGVuZGVuY2llczogX3ZlcnNpb24ucGVlckRlcGVuZGVuY2llcyxcbiAgICAgICAgcGVlckRlcGVuZGVuY2llc01ldGE6IF92ZXJzaW9uLnBlZXJEZXBlbmRlbmNpZXNNZXRhLFxuICAgICAgICBvcHRpb25hbERlcGVuZGVuY2llczogX3ZlcnNpb24ub3B0aW9uYWxEZXBlbmRlbmNpZXMsXG4gICAgICAgIGJ1bmRsZURlcGVuZGVuY2llczogX3ZlcnNpb24uYnVuZGxlRGVwZW5kZW5jaWVzLFxuICAgICAgICAvLyBucG0gY2xpIHNwZWNpZmljc1xuICAgICAgICBfaGFzU2hyaW5rd3JhcDogX3ZlcnNpb24uX2hhc1Nocmlua3dyYXAsXG4gICAgICAgIGhhc0luc3RhbGxTY3JpcHQ6IGhhc0luc3RhbGxTY3JpcHQoX3ZlcnNpb24pLFxuICAgICAgfTtcbiAgICAgIGFjY1t2ZXJzaW9uXSA9IF92ZXJzaW9uX2FiYnJldmlhdGVkO1xuICAgICAgcmV0dXJuIGFjYztcbiAgICB9LFxuICAgIHt9XG4gICk7XG5cbiAgY29uc3QgY29udmVydGVkTWFuaWZlc3QgPSB7XG4gICAgbmFtZTogbWFuaWZlc3RbJ25hbWUnXSxcbiAgICBbRElTVF9UQUdTXTogbWFuaWZlc3RbRElTVF9UQUdTXSxcbiAgICB2ZXJzaW9uczogYWJicmV2aWF0ZWRWZXJzaW9ucyxcbiAgICAvLyBAdHMtaWdub3JlXG4gICAgbW9kaWZpZWQ6IG1hbmlmZXN0Py50aW1lPy5tb2RpZmllZCxcbiAgICAvLyBOT1RFOiBzcGVjaWFsIGNhc2UgZm9yIHBucG0gaHR0cHM6Ly9naXRodWIuY29tL3BucG0vcmZjcy9wdWxsLzJcbiAgICB0aW1lOiBtYW5pZmVzdD8udGltZSxcbiAgfTtcblxuICAvLyBAdHMtaWdub3JlXG4gIHJldHVybiBjb252ZXJ0ZWRNYW5pZmVzdDtcbn1cbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSxJQUFBQSxNQUFBLEdBQUFDLHNCQUFBLENBQUFDLE9BQUE7QUFDQSxJQUFBQyxPQUFBLEdBQUFGLHNCQUFBLENBQUFDLE9BQUE7QUFFQSxJQUFBRSxLQUFBLEdBQUFGLE9BQUE7QUFDQSxJQUFBRyxjQUFBLEdBQUFILE9BQUE7QUFFQSxJQUFBSSxNQUFBLEdBQUFKLE9BQUE7QUFFQSxJQUFBSyxVQUFBLEdBQUFMLE9BQUE7QUFFQSxJQUFBTSxPQUFBLEdBQUFOLE9BQUE7QUFDQSxJQUFBTyxPQUFBLEdBQUFQLE9BQUE7QUFBaUUsU0FBQUQsdUJBQUFTLENBQUEsV0FBQUEsQ0FBQSxJQUFBQSxDQUFBLENBQUFDLFVBQUEsR0FBQUQsQ0FBQSxLQUFBRSxPQUFBLEVBQUFGLENBQUE7QUFFakUsTUFBTUcsS0FBSyxHQUFHLElBQUFDLGNBQVcsRUFBQyx5QkFBeUIsQ0FBQztBQUU3QyxTQUFTQyx1QkFBdUJBLENBQUNDLElBQVksRUFBWTtFQUM5RCxPQUFPO0lBQ0w7SUFDQUEsSUFBSTtJQUNKQyxRQUFRLEVBQUUsQ0FBQyxDQUFDO0lBQ1pDLElBQUksRUFBRSxDQUFDLENBQUM7SUFDUixDQUFDQyxnQkFBSyxH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R0osUUFBUSxDQUFDOUcsUUFBUSxDQUFDa0MsT0FBTyxDQUFDO0lBQzNDO0lBQ0E7SUFDQSxNQUFNaUYsb0JBQW9CLEdBQUc7TUFDM0JwSCxJQUFJLEVBQUVtSCxRQUFRLENBQUNuSCxJQUFJO01BQ25CbUMsT0FBTyxFQUFFZ0YsUUFBUSxDQUFDaEYsT0FBTztNQUN6QnNELFdBQVcsRUFBRTBCLFFBQVEsQ0FBQzFCLFdBQVc7TUFDakM0QixVQUFVLEVBQUVGLFFBQVEsQ0FBQ0UsVUFBVTtNQUMvQkMsR0FBRyxFQUFFSCxRQUFRLENBQUNHLEdBQUc7TUFDakJDLElBQUksRUFBRUosUUFBUSxDQUFDSSxJQUFJO01BQ25CQyxPQUFPLEVBQUVMLFFBQVEsQ0FBQ0ssT0FBTztNQUN6QkMsR0FBRyxFQUFFTixRQUFRLENBQUNNLEdBQUc7TUFDakJDLEVBQUUsRUFBRVAsUUFBUSxDQUFDTyxFQUFFO01BQ2ZDLE9BQU8sRUFBRVIsUUFBUSxDQUFDUSxPQUFPO01BQ3pCQyxXQUFXLEVBQUVULFFBQVEsQ0FBQ1MsV0FBVztNQUNqQ0MsWUFBWSxFQUFFVixRQUFRLENBQUNVLFlBQVk7TUFDbkNDLGVBQWUsRUFBRVgsUUFBUSxDQUFDVyxlQUFlO01BQ3pDQyxnQkFBZ0IsRUFBRVosUUFBUSxDQUFDWSxnQkFBZ0I7TUFDM0NDLG9CQUFvQixFQUFFYixRQUFRLENBQUNhLG9CQUFvQjtNQUNuREMsb0JBQW9CLEVBQUVkLFFBQVEsQ0FBQ2Msb0JBQW9CO01BQ25EQyxrQkFBa0IsRUFBRWYsUUFBUSxDQUFDZSxrQkFBa0I7TUFDL0M7TUFDQUMsY0FBYyxFQUFFaEIsUUFBUSxDQUFDZ0IsY0FBYztNQUN2QzFCLGdCQUFnQixFQUFFQSxnQkFBZ0IsQ0FBQ1UsUUFBUTtJQUM3QyxDQUFDO0lBQ0RELEdBQUcsQ0FBQy9FLE9BQU8sQ0FBQyxHQUFHaUYsb0JBQW9CO0lBQ25DLE9BQU9GLEdBQUc7RUFDWixDQUFDLEVBQ0QsQ0FBQyxDQUNILENBQUM7RUFFRCxNQUFNa0IsaUJBQWlCLEdBQUc7SUFDeEJwSSxJQUFJLEVBQUUrRyxRQUFRLENBQUMsTUFBTSxDQUFDO0lBQ3RCLENBQUMzRyxvQkFBUyxHQUFHMkcsUUFBUSxDQUFDM0csb0JBQVMsQ0FBQztJQUNoQ0gsUUFBUSxFQUFFK0csbUJBQW1CO0lBQzdCO0lBQ0FkLFFBQVEsRUFBRWEsUUFBUSxFQUFFN0csSUFBSSxFQUFFZ0csUUFBUTtJQUNsQztJQUNBaEcsSUFBSSxFQUFFNkcsUUFBUSxFQUFFN0c7RUFDbEIsQ0FBQzs7RUFFRDtFQUNBLE9BQU9rSSxpQkFBaUI7QUFDMUIiLCJpZ25vcmVMaXN0IjpbXX0=