verdaccio
Version:
A lightweight private npm proxy registry
269 lines (218 loc) • 27.7 kB
JavaScript
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.generatePackageTemplate = generatePackageTemplate;
exports.normalizePackage = normalizePackage;
exports.generateRevision = generateRevision;
exports.getLatestReadme = getLatestReadme;
exports.cleanUpReadme = cleanUpReadme;
exports.normalizeContributors = normalizeContributors;
exports.cleanUpLinksRef = cleanUpLinksRef;
exports.checkPackageLocal = checkPackageLocal;
exports.publishPackage = publishPackage;
exports.checkPackageRemote = checkPackageRemote;
exports.mergeUplinkTimeIntoLocal = mergeUplinkTimeIntoLocal;
exports.prepareSearchPackage = prepareSearchPackage;
exports.isPublishablePackage = isPublishablePackage;
exports.WHITELIST = void 0;
var _lodash = _interopRequireDefault(require("lodash"));
var _cryptoUtils = require("../lib/crypto-utils");
var _utils = require("./utils");
var _search = _interopRequireDefault(require("./search"));
var _constants = require("./constants");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
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, _utils.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, _utils.normalizeDistTags)(pkg);
return pkg;
}
function generateRevision(rev) {
const _rev = rev.split('-');
return (+_rev[0] || 0) + 1 + '-' + (0, _cryptoUtils.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) {
delete version.readme;
}
return version;
}
function normalizeContributors(contributors) {
if (_lodash.default.isNil(contributors)) {
return [];
} else if (contributors && _lodash.default.isArray(contributors) === false) {
// FIXME: this branch is clearly no an array, still tsc complains
// @ts-ignore
return [contributors];
} else if (_lodash.default.isString(contributors)) {
return [{
name: contributors
}];
}
return contributors;
}
const WHITELIST = ['_rev', 'name', 'versions', 'dist-tags', 'readme', 'time', '_id', 'users'];
exports.WHITELIST = WHITELIST;
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(_utils.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)) {
_search.default.add(latest);
}
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(_utils.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(_utils.ErrorCode.getServiceUnavailable(_constants.API_ERROR.UPLINK_OFFLINE_PUBLISH));
}
}
}
return resolve();
});
});
}
function mergeUplinkTimeIntoLocal(localMetadata, remoteMetadata) {
if ('time' in remoteMetadata) {
return Object.assign({}, localMetadata.time, remoteMetadata.time);
}
return localMetadata.time;
}
function prepareSearchPackage(data, time) {
const listVersions = Object.keys(data.versions);
const versions = (0, _utils.semverSort)(listVersions);
const latest = data[_constants.DIST_TAGS] && data[_constants.DIST_TAGS].latest ? data[_constants.DIST_TAGS].latest : versions.pop();
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,
bugs: version.bugs,
license: version.license,
time: {
modified: time
},
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 _lodash.default.includes(keys, 'versions');
}
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9saWIvc3RvcmFnZS11dGlscy50cyJdLCJuYW1lcyI6WyJnZW5lcmF0ZVBhY2thZ2VUZW1wbGF0ZSIsIm5hbWUiLCJ2ZXJzaW9ucyIsInRpbWUiLCJVU0VSUyIsIkRJU1RfVEFHUyIsIl91cGxpbmtzIiwiX2Rpc3RmaWxlcyIsIl9hdHRhY2htZW50cyIsIl9yZXYiLCJub3JtYWxpemVQYWNrYWdlIiwicGtnIiwicGtnUHJvcGVydGllcyIsImZvckVhY2giLCJrZXkiLCJwa2dQcm9wIiwiXyIsImlzTmlsIiwiaXNTdHJpbmciLCJTVE9SQUdFIiwiREVGQVVMVF9SRVZJU0lPTiIsIl9pZCIsImdlbmVyYXRlUmV2aXNpb24iLCJyZXYiLCJzcGxpdCIsImdldExhdGVzdFJlYWRtZSIsImRpc3RUYWdzIiwibGF0ZXN0VmVyc2lvbiIsInJlYWRtZSIsInRyaW0iLCJyZWFkbWVEaXN0VGFnc1ByaW9yaXR5IiwibWFwIiwidGFnIiwidmVyc2lvbiIsImNsZWFuVXBSZWFkbWUiLCJub3JtYWxpemVDb250cmlidXRvcnMiLCJjb250cmlidXRvcnMiLCJpc0FycmF5IiwiV0hJVEVMSVNUIiwiY2xlYW5VcExpbmtzUmVmIiwia2VlcFVwTGlua0RhdGEiLCJyZXN1bHQiLCJwcm9wZXJ0eVRvS2VlcCIsInB1c2giLCJpIiwiaW5kZXhPZiIsImNoZWNrUGFja2FnZUxvY2FsIiwibG9jYWxTdG9yYWdlIiwiUHJvbWlzZSIsInJlc29sdmUiLCJyZWplY3QiLCJnZXRQYWNrYWdlTWV0YWRhdGEiLCJlcnIiLCJyZXN1bHRzIiwic3RhdHVzIiwiSFRUUF9TVEFUVVMiLCJOT1RfRk9VTkQiLCJFcnJvckNvZGUiLCJnZXRDb25mbGljdCIsIkFQSV9FUlJPUiIsIlBBQ0tBR0VfRVhJU1QiLCJwdWJsaXNoUGFja2FnZSIsIm1ldGFkYXRhIiwiYWRkUGFja2FnZSIsImxhdGVzdCIsImlzTnVsbCIsImlzVW5kZWZpbmVkIiwiU2VhcmNoIiwiYWRkIiwiY2hlY2tQYWNrYWdlUmVtb3RlIiwiaXNBbGxvd1B1Ymxpc2hPZmZsaW5lIiwic3luY01ldGFkYXRhIiwicGFja2FnZUpzb25Mb2NhbCIsInVwTGlua3NFcnJvcnMiLCJlcnJvckl0ZW0iLCJsZW5ndGgiLCJnZXRTZXJ2aWNlVW5hdmFpbGFibGUiLCJVUExJTktfT0ZGTElORV9QVUJMSVNIIiwibWVyZ2VVcGxpbmtUaW1lSW50b0xvY2FsIiwibG9jYWxNZXRhZGF0YSIsInJlbW90ZU1ldGFkYXRhIiwiT2JqZWN0IiwiYXNzaWduIiwicHJlcGFyZVNlYXJjaFBhY2thZ2UiLCJkYXRhIiwibGlzdFZlcnNpb25zIiwia2V5cyIsInBvcCIsImRlc2NyaXB0aW9uIiwibWFpbnRhaW5lcnMiLCJhdXRob3IiLCJmaWx0ZXIiLCJCb29sZWFuIiwicmVwb3NpdG9yeSIsInJlYWRtZUZpbGVuYW1lIiwiaG9tZXBhZ2UiLCJrZXl3b3JkcyIsImJ1Z3MiLCJsaWNlbnNlIiwibW9kaWZpZWQiLCJpc1B1Ymxpc2hhYmxlUGFja2FnZSIsImluY2x1ZGVzIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBOztBQUVBOztBQUVBOztBQUNBOztBQUVBOzs7O0FBRU8sU0FBU0EsdUJBQVQsQ0FBaUNDLElBQWpDLEVBQXdEO0FBQzdELFNBQU87QUFDTDtBQUNBQSxJQUFBQSxJQUZLO0FBR0xDLElBQUFBLFFBQVEsRUFBRSxFQUhMO0FBSUxDLElBQUFBLElBQUksRUFBRSxFQUpEO0FBS0wsS0FBQ0MsZ0JBQUQsR0FBUyxFQUxKO0FBTUwsS0FBQ0Msb0JBQUQsR0FBYSxFQU5SO0FBT0xDLElBQUFBLFFBQVEsRUFBRSxFQVBMO0FBUUxDLElBQUFBLFVBQVUsRUFBRSxFQVJQO0FBU0xDLElBQUFBLFlBQVksRUFBRSxFQVRUO0FBVUxDLElBQUFBLElBQUksRUFBRTtBQVZELEdBQVA7QUFZRDtBQUVEO0FBQ0E7QUFDQTtBQUNBOzs7QUFDTyxTQUFTQyxnQkFBVCxDQUEwQkMsR0FBMUIsRUFBaUQ7QUFDdEQsUUFBTUMsYUFBYSxHQUFHLENBQUMsVUFBRCxFQUFhLFdBQWIsRUFBMEIsWUFBMUIsRUFBd0MsY0FBeEMsRUFBd0QsVUFBeEQsRUFBb0UsTUFBcEUsQ0FBdEI7QUFFQUEsRUFBQUEsYUFBYSxDQUFDQyxPQUFkLENBQXVCQyxHQUFELElBQWU7QUFDbkMsVUFBTUMsT0FBTyxHQUFHSixHQUFHLENBQUNHLEdBQUQsQ0FBbkI7O0FBRUEsUUFBSUUsZ0JBQUVDLEtBQUYsQ0FBUUYsT0FBUixLQUFvQixxQkFBU0EsT0FBVCxNQUFzQixLQUE5QyxFQUFxRDtBQUNuREosTUFBQUEsR0FBRyxDQUFDRyxHQUFELENBQUgsR0FBVyxFQUFYO0FBQ0Q7QUFDRixHQU5EOztBQVFBLE1BQUlFLGdCQUFFRSxRQUFGLENBQVdQLEdBQUcsQ0FBQ0YsSUFBZixNQUF5QixLQUE3QixFQUFvQztBQUNsQ0UsSUFBQUEsR0FBRyxDQUFDRixJQUFKLEdBQVdVLG1CQUFRQyxnQkFBbkI7QUFDRDs7QUFFRCxNQUFJSixnQkFBRUUsUUFBRixDQUFXUCxHQUFHLENBQUNVLEdBQWYsTUFBd0IsS0FBNUIsRUFBbUM7QUFDakNWLElBQUFBLEdBQUcsQ0FBQ1UsR0FBSixHQUFVVixHQUFHLENBQUNWLElBQWQ7QUFDRCxHQWpCcUQsQ0FtQnREOzs7QUFDQSxnQ0FBa0JVLEdBQWxCO0FBRUEsU0FBT0EsR0FBUDtBQUNEOztBQUVNLFNBQVNXLGdCQUFULENBQTBCQyxHQUExQixFQUErQztBQUNwRCxRQUFNZCxJQUFJLEdBQUdjLEdBQUcsQ0FBQ0MsS0FBSixDQUFVLEdBQVYsQ0FBYjs7QUFFQSxTQUFPLENBQUMsQ0FBQ2YsSUFBSSxDQUFDLENBQUQsQ0FBTCxJQUFZLENBQWIsSUFBa0IsQ0FBbEIsR0FBc0IsR0FBdEIsR0FBNEIsMkNBQW5DO0FBQ0Q7O0FBRU0sU0FBU2dCLGVBQVQsQ0FBeUJkLEdBQXpCLEVBQStDO0FBQ3BELFFBQU1ULFFBQVEsR0FBR1MsR0FBRyxDQUFDLFVBQUQsQ0FBSCxJQUFtQixFQUFwQztBQUNBLFFBQU1lLFFBQVEsR0FBR2YsR0FBRyxDQUFDTixvQkFBRCxDQUFILElBQWtCLEVBQW5DLENBRm9ELENBR3BEOztBQUNBLFFBQU1zQixhQUE0QixHQUFHRCxRQUFRLENBQUMsUUFBRCxDQUFSLEdBQXFCeEIsUUFBUSxDQUFDd0IsUUFBUSxDQUFDLFFBQUQsQ0FBVCxDQUFSLElBQWdDLEVBQXJELEdBQTBELEVBQS9GOztBQUNBLE1BQUlFLE1BQU0sR0FBR1osZ0JBQUVhLElBQUYsQ0FBT2xCLEdBQUcsQ0FBQ2lCLE1BQUosSUFBY0QsYUFBYSxDQUFDQyxNQUE1QixJQUFzQyxFQUE3QyxDQUFiOztBQUNBLE1BQUlBLE1BQUosRUFBWTtBQUNWLFdBQU9BLE1BQVA7QUFDRCxHQVJtRCxDQVVwRDs7O0FBQ0EsUUFBTUUsc0JBQXNCLEdBQUcsQ0FBQyxNQUFELEVBQVMsTUFBVCxFQUFpQixPQUFqQixFQUEwQixNQUExQixFQUFrQyxLQUFsQyxFQUF5QyxRQUF6QyxDQUEvQjtBQUNBQSxFQUFBQSxzQkFBc0IsQ0FBQ0MsR0FBdkIsQ0FBMkIsVUFBVUMsR0FBVixFQUE4QjtBQUN2RCxRQUFJSixNQUFKLEVBQVk7QUFDVixhQUFPQSxNQUFQO0FBQ0Q7O0FBQ0QsVUFBTUssT0FBc0IsR0FBR1AsUUFBUSxDQUFDTSxHQUFELENBQVIsR0FBZ0I5QixRQUFRLENBQUN3QixRQUFRLENBQUNNLEdBQUQsQ0FBVCxDQUFSLElBQTJCLEVBQTNDLEdBQWdELEVBQS9FO0FBQ0FKLElBQUFBLE1BQU0sR0FBR1osZ0JBQUVhLElBQUYsQ0FBT0ksT0FBTyxDQUFDTCxNQUFSLElBQWtCQSxNQUF6QixDQUFUO0FBQ0QsR0FORDtBQU9BLFNBQU9BLE1BQVA7QUFDRDs7QUFFTSxTQUFTTSxhQUFULENBQXVCRCxPQUF2QixFQUFrRDtBQUN2RCxNQUFJakIsZ0JBQUVDLEtBQUYsQ0FBUWdCLE9BQVIsTUFBcUIsS0FBekIsRUFBZ0M7QUFDOUIsV0FBT0EsT0FBTyxDQUFDTCxNQUFmO0FBQ0Q7O0FBRUQsU0FBT0ssT0FBUDtBQUNEOztBQUVNLFNBQVNFLHFCQUFULENBQStCQyxZQUEvQixFQUFpRTtBQUN0RSxNQUFJcEIsZ0JBQUVDLEtBQUYsQ0FBUW1CLFlBQVIsQ0FBSixFQUEyQjtBQUN6QixXQUFPLEVBQVA7QUFDRCxHQUZELE1BRU8sSUFBSUEsWUFBWSxJQUFJcEIsZ0JBQUVxQixPQUFGLENBQVVELFlBQVYsTUFBNEIsS0FBaEQsRUFBdUQ7QUFDNUQ7QUFDQTtBQUNBLFdBQU8sQ0FBQ0EsWUFBRCxDQUFQO0FBQ0QsR0FKTSxNQUlBLElBQUlwQixnQkFBRUUsUUFBRixDQUFXa0IsWUFBWCxDQUFKLEVBQThCO0FBQ25DLFdBQU8sQ0FDTDtBQUNFbkMsTUFBQUEsSUFBSSxFQUFFbUM7QUFEUixLQURLLENBQVA7QUFLRDs7QUFFRCxTQUFPQSxZQUFQO0FBQ0Q7O0FBRU0sTUFBTUUsU0FBUyxHQUFHLENBQ3ZCLE1BRHVCLEVBRXZCLE1BRnVCLEVBR3ZCLFVBSHVCLEVBSXZCLFdBSnVCLEVBS3ZCLFFBTHVCLEVBTXZCLE1BTnVCLEVBT3ZCLEtBUHVCLEVBUXZCLE9BUnVCLENBQWxCOzs7QUFXQSxTQUFTQyxlQUFULENBQXlCQyxjQUF6QixFQUFrREMsTUFBbEQsRUFBNEU7QUFDakYsUUFBTUMsY0FBYyxHQUFHLENBQUMsR0FBR0osU0FBSixDQUF2Qjs7QUFDQSxNQUFJRSxjQUFjLEtBQUssSUFBdkIsRUFBNkI7QUFDM0JFLElBQUFBLGNBQWMsQ0FBQ0MsSUFBZixDQUFvQixVQUFwQjtBQUNEOztBQUVELE9BQUssTUFBTUMsQ0FBWCxJQUFnQkgsTUFBaEIsRUFBd0I7QUFDdEIsUUFBSUMsY0FBYyxDQUFDRyxPQUFmLENBQXVCRCxDQUF2QixNQUE4QixDQUFDLENBQW5DLEVBQXNDO0FBQ3BDO0FBQ0EsYUFBT0gsTUFBTSxDQUFDRyxDQUFELENBQWI7QUFDRDtBQUNGOztBQUVELFNBQU9ILE1BQVA7QUFDRDtBQUVEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUNPLFNBQVNLLGlCQUFULENBQTJCN0MsSUFBM0IsRUFBeUM4QyxZQUF6QyxFQUErRTtBQUNwRixTQUFPLElBQUlDLE9BQUosQ0FBWSxDQUFDQyxPQUFELEVBQVVDLE1BQVYsS0FBMkI7QUFDNUNILElBQUFBLFlBQVksQ0FBQ0ksa0JBQWIsQ0FBZ0NsRCxJQUFoQyxFQUFzQyxDQUFDbUQsR0FBRCxFQUFNQyxPQUFOLEtBQXdCO0FBQzVELFVBQUksQ0FBQ3JDLGdCQUFFQyxLQUFGLENBQVFtQyxHQUFSLENBQUQsSUFBaUJBLEdBQUcsQ0FBQ0UsTUFBSixLQUFlQyx1QkFBWUMsU0FBaEQsRUFBMkQ7QUFDekQsZUFBT04sTUFBTSxDQUFDRSxHQUFELENBQWI7QUFDRDs7QUFDRCxVQUFJQyxPQUFKLEVBQWE7QUFDWCxlQUFPSCxNQUFNLENBQUNPLGlCQUFVQyxXQUFWLENBQXNCQyxxQkFBVUMsYUFBaEMsQ0FBRCxDQUFiO0FBQ0Q7O0FBQ0QsYUFBT1gsT0FBTyxFQUFkO0FBQ0QsS0FSRDtBQVNELEdBVk0sQ0FBUDtBQVdEOztBQUVNLFNBQVNZLGNBQVQsQ0FBd0I1RCxJQUF4QixFQUFzQzZELFFBQXRDLEVBQXFEZixZQUFyRCxFQUEyRjtBQUNoRyxTQUFPLElBQUlDLE9BQUosQ0FBWSxDQUFDQyxPQUFELEVBQVVDLE1BQVYsS0FBMkI7QUFDNUNILElBQUFBLFlBQVksQ0FBQ2dCLFVBQWIsQ0FBd0I5RCxJQUF4QixFQUE4QjZELFFBQTlCLEVBQXdDLENBQUNWLEdBQUQsRUFBTVksTUFBTixLQUF1QjtBQUM3RCxVQUFJLENBQUNoRCxnQkFBRWlELE1BQUYsQ0FBU2IsR0FBVCxDQUFMLEVBQW9CO0FBQ2xCLGVBQU9GLE1BQU0sQ0FBQ0UsR0FBRCxDQUFiO0FBQ0QsT0FGRCxNQUVPLElBQUksQ0FBQ3BDLGdCQUFFa0QsV0FBRixDQUFjRixNQUFkLENBQUwsRUFBNEI7QUFDakNHLHdCQUFPQyxHQUFQLENBQVdKLE1BQVg7QUFDRDs7QUFDRCxhQUFPZixPQUFPLEVBQWQ7QUFDRCxLQVBEO0FBUUQsR0FUTSxDQUFQO0FBVUQ7O0FBRU0sU0FBU29CLGtCQUFULENBQ0xwRSxJQURLLEVBRUxxRSxxQkFGSyxFQUdMQyxZQUhLLEVBSVM7QUFDZCxTQUFPLElBQUl2QixPQUFKLENBQVksQ0FBQ0MsT0FBRCxFQUFVQyxNQUFWLEtBQTJCO0FBQzVDcUIsSUFBQUEsWUFBWSxDQUFDdEUsSUFBRCxFQUFPLElBQVAsRUFBYSxFQUFiLEVBQWlCLENBQUNtRCxHQUFELEVBQU1vQixnQkFBTixFQUF3QkMsYUFBeEIsS0FBZ0Q7QUFDM0U7QUFDQSxVQUFJckIsR0FBRyxJQUFJQSxHQUFHLENBQUNFLE1BQUosS0FBZUMsdUJBQVlDLFNBQXRDLEVBQWlEO0FBQy9DLGVBQU9OLE1BQU0sQ0FBQ0UsR0FBRCxDQUFiO0FBQ0QsT0FKMEUsQ0FNM0U7OztBQUNBLFVBQUlwQyxnQkFBRUMsS0FBRixDQUFRdUQsZ0JBQVIsTUFBOEIsS0FBbEMsRUFBeUM7QUFDdkMsZUFBT3RCLE1BQU0sQ0FBQ08saUJBQVVDLFdBQVYsQ0FBc0JDLHFCQUFVQyxhQUFoQyxDQUFELENBQWI7QUFDRDs7QUFFRCxXQUFLLElBQUljLFNBQVMsR0FBRyxDQUFyQixFQUF3QkEsU0FBUyxHQUFHRCxhQUFhLENBQUNFLE1BQWxELEVBQTBERCxTQUFTLEVBQW5FLEVBQXVFO0FBQ3JFO0FBQ0E7QUFDQSxZQUFJMUQsZ0JBQUVDLEtBQUYsQ0FBUXdELGFBQWEsQ0FBQ0MsU0FBRCxDQUFiLENBQXlCLENBQXpCLENBQVIsTUFBeUMsS0FBN0MsRUFBb0Q7QUFDbEQsY0FBSUQsYUFBYSxDQUFDQyxTQUFELENBQWIsQ0FBeUIsQ0FBekIsRUFBNEJwQixNQUE1QixLQUF1Q0MsdUJBQVlDLFNBQXZELEVBQWtFO0FBQ2hFLGdCQUFJYyxxQkFBSixFQUEyQjtBQUN6QixxQkFBT3JCLE9BQU8sRUFBZDtBQUNEOztBQUVELG1CQUFPQyxNQUFNLENBQUNPLGlCQUFVbUIscUJBQVYsQ0FBZ0NqQixxQkFBVWtCLHNCQUExQyxDQUFELENBQWI7QUFDRDtBQUNGO0FBQ0Y7O0FBRUQsYUFBTzVCLE9BQU8sRUFBZDtBQUNELEtBMUJXLENBQVo7QUEyQkQsR0E1Qk0sQ0FBUDtBQTZCRDs7QUFFTSxTQUFTNkIsd0JBQVQsQ0FBa0NDLGFBQWxDLEVBQTBEQyxjQUExRCxFQUF3RjtBQUM3RixNQUFJLFVBQVVBLGNBQWQsRUFBOEI7QUFDNUIsV0FBT0MsTUFBTSxDQUFDQyxNQUFQLENBQWMsRUFBZCxFQUFrQkgsYUFBYSxDQUFDNUUsSUFBaEMsRUFBc0M2RSxjQUFjLENBQUM3RSxJQUFyRCxDQUFQO0FBQ0Q7O0FBRUQsU0FBTzRFLGFBQWEsQ0FBQzVFLElBQXJCO0FBQ0Q7O0FBRU0sU0FBU2dGLG9CQUFULENBQThCQyxJQUE5QixFQUE2Q2pGLElBQTdDLEVBQWlFO0FBQ3RFLFFBQU1rRixZQUFzQixHQUFHSixNQUFNLENBQUNLLElBQVAsQ0FBWUYsSUFBSSxDQUFDbEYsUUFBakIsQ0FBL0I7QUFDQSxRQUFNQSxRQUFrQixHQUFHLHVCQUFXbUYsWUFBWCxDQUEzQjtBQUNBLFFBQU1yQixNQUEwQixHQUM5Qm9CLElBQUksQ0FBQy9FLG9CQUFELENBQUosSUFBbUIrRSxJQUFJLENBQUMvRSxvQkFBRCxDQUFKLENBQWdCMkQsTUFBbkMsR0FBNENvQixJQUFJLENBQUMvRSxvQkFBRCxDQUFKLENBQWdCMkQsTUFBNUQsR0FBcUU5RCxRQUFRLENBQUNxRixHQUFULEVBRHZFOztBQUdBLE1BQUl2QixNQUFNLElBQUlvQixJQUFJLENBQUNsRixRQUFMLENBQWM4RCxNQUFkLENBQWQsRUFBcUM7QUFDbkMsVUFBTS9CLE9BQWdCLEdBQUdtRCxJQUFJLENBQUNsRixRQUFMLENBQWM4RCxNQUFkLENBQXpCO0FBQ0EsVUFBTTlELFFBQWEsR0FBRztBQUFFLE9BQUM4RCxNQUFELEdBQVU7QUFBWixLQUF0QjtBQUNBLFVBQU1yRCxHQUFRLEdBQUc7QUFDZlYsTUFBQUEsSUFBSSxFQUFFZ0MsT0FBTyxDQUFDaEMsSUFEQztBQUVmdUYsTUFBQUEsV0FBVyxFQUFFdkQsT0FBTyxDQUFDdUQsV0FGTjtBQUdmLE9BQUNuRixvQkFBRCxHQUFhO0FBQUUyRCxRQUFBQTtBQUFGLE9BSEU7QUFJZnlCLE1BQUFBLFdBQVcsRUFBRXhELE9BQU8sQ0FBQ3dELFdBQVIsSUFBdUIsQ0FBQ3hELE9BQU8sQ0FBQ3lELE1BQVQsRUFBaUJDLE1BQWpCLENBQXdCQyxPQUF4QixDQUpyQjtBQUtmRixNQUFBQSxNQUFNLEVBQUV6RCxPQUFPLENBQUN5RCxNQUxEO0FBTWZHLE1BQUFBLFVBQVUsRUFBRTVELE9BQU8sQ0FBQzRELFVBTkw7QUFPZkMsTUFBQUEsY0FBYyxFQUFFN0QsT0FBTyxDQUFDNkQsY0FBUixJQUEwQixFQVAzQjtBQVFmQyxNQUFBQSxRQUFRLEVBQUU5RCxPQUFPLENBQUM4RCxRQVJIO0FBU2ZDLE1BQUFBLFFBQVEsRUFBRS9ELE9BQU8sQ0FBQytELFFBVEg7QUFVZkMsTUFBQUEsSUFBSSxFQUFFaEUsT0FBTyxDQUFDZ0UsSUFWQztBQVdmQyxNQUFBQSxPQUFPLEVBQUVqRSxPQUFPLENBQUNpRSxPQVhGO0FBWWYvRixNQUFBQSxJQUFJLEVBQUU7QUFDSmdHLFFBQUFBLFFBQVEsRUFBRWhHO0FBRE4sT0FaUztBQWVmRCxNQUFBQTtBQWZlLEtBQWpCO0FBa0JBLFdBQU9TLEdBQVA7QUFDRDtBQUNGO0FBRUQ7QUFDQTtBQUNBO0FBQ0E7OztBQUNPLFNBQVN5RixvQkFBVCxDQUE4QnpGLEdBQTlCLEVBQXFEO0FBQzFELFFBQU0yRSxJQUFjLEdBQUdMLE1BQU0sQ0FBQ0ssSUFBUCxDQUFZM0UsR0FBWixDQUF2QjtBQUVBLFNBQU9LLGdCQUFFcUYsUUFBRixDQUFXZixJQUFYLEVBQWlCLFVBQWpCLENBQVA7QUFDRCIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBfIGZyb20gJ2xvZGFzaCc7XG5pbXBvcnQgeyBQYWNrYWdlLCBWZXJzaW9uLCBBdXRob3IgfSBmcm9tICdAdmVyZGFjY2lvL3R5cGVzJztcbmltcG9ydCB7IGdlbmVyYXRlUmFuZG9tSGV4U3RyaW5nIH0gZnJvbSAnLi4vbGliL2NyeXB0by11dGlscyc7XG5pbXBvcnQgeyBJU3RvcmFnZSB9IGZyb20gJy4uLy4uL3R5cGVzJztcbmltcG9ydCB7IEVycm9yQ29kZSwgaXNPYmplY3QsIG5vcm1hbGl6ZURpc3RUYWdzLCBzZW12ZXJTb3J0IH0gZnJvbSAnLi91dGlscyc7XG5pbXBvcnQgU2VhcmNoIGZyb20gJy4vc2VhcmNoJztcblxuaW1wb3J0IHsgQVBJX0VSUk9SLCBIVFRQX1NUQVRVUywgRElTVF9UQUdTLCBVU0VSUywgU1RPUkFHRSB9IGZyb20gJy4vY29uc3RhbnRzJztcblxuZXhwb3J0IGZ1bmN0aW9uIGdlbmVyYXRlUGFja2FnZVRlbXBsYXRlKG5hbWU6IHN0cmluZyk6IFBhY2thZ2Uge1xuICByZXR1cm4ge1xuICAgIC8vIHN0YW5kYXJkIHRoaW5nc1xuICAgIG5hbWUsXG4gICAgdmVyc2lvbnM6IHt9LFxuICAgIHRpbWU6IHt9LFxuICAgIFtVU0VSU106IHt9LFxuICAgIFtESVNUX1RBR1NdOiB7fSxcbiAgICBfdXBsaW5rczoge30sXG4gICAgX2Rpc3RmaWxlczoge30sXG4gICAgX2F0dGFjaG1lbnRzOiB7fSxcbiAgICBfcmV2OiAnJ1xuICB9O1xufVxuXG4vKipcbiAqIE5vcm1hbGl6ZSBwYWNrYWdlIHByb3BlcnRpZXMsIHRhZ3MsIHJldmlzaW9uIGlkLlxuICogQHBhcmFtIHtPYmplY3R9IHBrZyBwYWNrYWdlIHJlZmVyZW5jZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG5vcm1hbGl6ZVBhY2thZ2UocGtnOiBQYWNrYWdlKTogUGFja2FnZSB7XG4gIGNvbnN0IHBrZ1Byb3BlcnRpZXMgPSBbJ3ZlcnNpb25zJywgJ2Rpc3QtdGFncycsICdfZGlzdGZpbGVzJywgJ19hdHRhY2htZW50cycsICdfdXBsaW5rcycsICd0aW1lJ107XG5cbiAgcGtnUHJvcGVydGllcy5mb3JFYWNoKChrZXkpOiB2b2lkID0+IHtcbiAgICBjb25zdCBwa2dQcm9wID0gcGtnW2tleV07XG5cbiAgICBpZiAoXy5pc05pbChwa2dQcm9wKSB8fCBpc09iamVjdChwa2dQcm9wKSA9PT0gZmFsc2UpIHtcbiAgICAgIHBrZ1trZXldID0ge307XG4gICAgfVxuICB9KTtcblxuICBpZiAoXy5pc1N0cmluZyhwa2cuX3JldikgPT09IGZhbHNlKSB7XG4gICAgcGtnLl9yZXYgPSBTVE9SQUdFLkRFRkFVTFRfUkVWSVNJT047XG4gIH1cblxuICBpZiAoXy5pc1N0cmluZyhwa2cuX2lkKSA9PT0gZmFsc2UpIHtcbiAgICBwa2cuX2lkID0gcGtnLm5hbWU7XG4gIH1cblxuICAvLyBub3JtYWxpemUgZGlzdC10YWdzXG4gIG5vcm1hbGl6ZURpc3RUYWdzKHBrZyk7XG5cbiAgcmV0dXJuIHBrZztcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdlbmVyYXRlUmV2aXNpb24ocmV2OiBzdHJpbmcpOiBzdHJpbmcge1xuICBjb25zdCBfcmV2ID0gcmV2LnNwbGl0KCctJyk7XG5cbiAgcmV0dXJuICgrX3JldlswXSB8fCAwKSArIDEgKyAnLScgKyBnZW5lcmF0ZVJhbmRvbUhleFN0cmluZygpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0TGF0ZXN0UmVhZG1lKHBrZzogUGFja2FnZSk6IHN0cmluZyB7XG4gIGNvbnN0IHZlcnNpb25zID0gcGtnWyd2ZXJzaW9ucyddIHx8IHt9O1xuICBjb25zdCBkaXN0VGFncyA9IHBrZ1tESVNUX1RBR1NdIHx8IHt9O1xuICAvLyBGSVhNRTogaGVyZSBpcyBhIGJpdCB0cmlja3kgYWRkIHRoZSB0eXBlc1xuICBjb25zdCBsYXRlc3RWZXJzaW9uOiBWZXJzaW9uIHwgYW55ID0gZGlzdFRhZ3NbJ2xhdGVzdCddID8gdmVyc2lvbnNbZGlzdFRhZ3NbJ2xhdGVzdCddXSB8fCB7fSA6IHt9O1xuICBsZXQgcmVhZG1lID0gXy50cmltKHBrZy5yZWFkbWUgfHwgbGF0ZXN0VmVyc2lvbi5yZWFkbWUgfHwgJycpO1xuICBpZiAocmVhZG1lKSB7XG4gICAgcmV0dXJuIHJlYWRtZTtcbiAgfVxuXG4gIC8vIEluIGNhc2Ugb2YgZW1wdHkgcmVhZG1lIC0gdHJ5aW5nIHRvIGdldCBBTlkgcmVhZG1lIGluIHRoZSBmb2xsb3dpbmcgb3JkZXI6ICduZXh0JywnYmV0YScsJ2FscGhhJywndGVzdCcsJ2RldicsJ2NhbmFyeSdcbiAgY29uc3QgcmVhZG1lRGlzdFRhZ3NQcmlvcml0eSA9IFsnbmV4dCcsICdiZXRhJywgJ2FscGhhJywgJ3Rlc3QnLCAnZGV2JywgJ2NhbmFyeSddO1xuICByZWFkbWVEaXN0VGFnc1ByaW9yaXR5Lm1hcChmdW5jdGlvbiAodGFnKTogc3RyaW5nIHwgdm9pZCB7XG4gICAgaWYgKHJlYWRtZSkge1xuICAgICAgcmV0dXJuIHJlYWRtZTtcbiAgICB9XG4gICAgY29uc3QgdmVyc2lvbjogVmVyc2lvbiB8IGFueSA9IGRpc3RUYWdzW3RhZ10gPyB2ZXJzaW9uc1tkaXN0VGFnc1t0YWddXSB8fCB7fSA6IHt9O1xuICAgIHJlYWRtZSA9IF8udHJpbSh2ZXJzaW9uLnJlYWRtZSB8fCByZWFkbWUpO1xuICB9KTtcbiAgcmV0dXJuIHJlYWRtZTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGNsZWFuVXBSZWFkbWUodmVyc2lvbjogVmVyc2lvbik6IFZlcnNpb24ge1xuICBpZiAoXy5pc05pbCh2ZXJzaW9uKSA9PT0gZmFsc2UpIHtcbiAgICBkZWxldGUgdmVyc2lvbi5yZWFkbWU7XG4gIH1cblxuICByZXR1cm4gdmVyc2lvbjtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIG5vcm1hbGl6ZUNvbnRyaWJ1dG9ycyhjb250cmlidXRvcnM6IEF1dGhvcltdKTogQXV0aG9yW10ge1xuICBpZiAoXy5pc05pbChjb250cmlidXRvcnMpKSB7XG4gICAgcmV0dXJuIFtdO1xuICB9IGVsc2UgaWYgKGNvbnRyaWJ1dG9ycyAmJiBfLmlzQXJyYXkoY29udHJpYnV0b3JzKSA9PT0gZmFsc2UpIHtcbiAgICAvLyBGSVhNRTogdGhpcyBicmFuY2ggaXMgY2xlYXJseSBubyBhbiBhcnJheSwgc3RpbGwgdHNjIGNvbXBsYWluc1xuICAgIC8vIEB0cy1pZ25vcmVcbiAgICByZXR1cm4gW2NvbnRyaWJ1dG9yc107XG4gIH0gZWxzZSBpZiAoXy5pc1N0cmluZyhjb250cmlidXRvcnMpKSB7XG4gICAgcmV0dXJuIFtcbiAgICAgIHtcbiAgICAgICAgbmFtZTogY29udHJpYnV0b3JzXG4gICAgICB9XG4gICAgXTtcbiAgfVxuXG4gIHJldHVybiBjb250cmlidXRvcnM7XG59XG5cbmV4cG9ydCBjb25zdCBXSElURUxJU1QgPSBbXG4gICdfcmV2JyxcbiAgJ25hbWUnLFxuICAndmVyc2lvbnMnLFxuICAnZGlzdC10YWdzJyxcbiAgJ3JlYWRtZScsXG4gICd0aW1lJyxcbiAgJ19pZCcsXG4gICd1c2Vycydcbl07XG5cbmV4cG9ydCBmdW5jdGlvbiBjbGVhblVwTGlua3NSZWYoa2VlcFVwTGlua0RhdGE6IGJvb2xlYW4sIHJlc3VsdDogUGFja2FnZSk6IFBhY2thZ2Uge1xuICBjb25zdCBwcm9wZXJ0eVRvS2VlcCA9IFsuLi5XSElURUxJU1RdO1xuICBpZiAoa2VlcFVwTGlua0RhdGEgPT09IHRydWUpIHtcbiAgICBwcm9wZXJ0eVRvS2VlcC5wdXNoKCdfdXBsaW5rcycpO1xuICB9XG5cbiAgZm9yIChjb25zdCBpIGluIHJlc3VsdCkge1xuICAgIGlmIChwcm9wZXJ0eVRvS2VlcC5pbmRleE9mKGkpID09PSAtMSkge1xuICAgICAgLy8gUmVtb3ZlIHNlY3Rpb25zIGxpa2UgJ191cGxpbmtzJyBmcm9tIHJlc3BvbnNlXG4gICAgICBkZWxldGUgcmVzdWx0W2ldO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiByZXN1bHQ7XG59XG5cbi8qKlxuICogQ2hlY2sgd2hldGhlciBhIHBhY2thZ2UgaXQgaXMgYWxyZWFkeSBhIGxvY2FsIHBhY2thZ2VcbiAqIEBwYXJhbSB7Kn0gbmFtZVxuICogQHBhcmFtIHsqfSBsb2NhbFN0b3JhZ2VcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNoZWNrUGFja2FnZUxvY2FsKG5hbWU6IHN0cmluZywgbG9jYWxTdG9yYWdlOiBJU3RvcmFnZSk6IFByb21pc2U8YW55PiB7XG4gIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KTogdm9pZCA9PiB7XG4gICAgbG9jYWxTdG9yYWdlLmdldFBhY2thZ2VNZXRhZGF0YShuYW1lLCAoZXJyLCByZXN1bHRzKTogdm9pZCA9PiB7XG4gICAgICBpZiAoIV8uaXNOaWwoZXJyKSAmJiBlcnIuc3RhdHVzICE9PSBIVFRQX1NUQVRVUy5OT1RfRk9VTkQpIHtcbiAgICAgICAgcmV0dXJuIHJlamVjdChlcnIpO1xuICAgICAgfVxuICAgICAgaWYgKHJlc3VsdHMpIHtcbiAgICAgICAgcmV0dXJuIHJlamVjdChFcnJvckNvZGUuZ2V0Q29uZmxpY3QoQVBJX0VSUk9SLlBBQ0tBR0VfRVhJU1QpKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiByZXNvbHZlKCk7XG4gICAgfSk7XG4gIH0pO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcHVibGlzaFBhY2thZ2UobmFtZTogc3RyaW5nLCBtZXRhZGF0YTogYW55LCBsb2NhbFN0b3JhZ2U6IElTdG9yYWdlKTogUHJvbWlzZTxhbnk+IHtcbiAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpOiB2b2lkID0+IHtcbiAgICBsb2NhbFN0b3JhZ2UuYWRkUGFja2FnZShuYW1lLCBtZXRhZGF0YSwgKGVyciwgbGF0ZXN0KTogdm9pZCA9PiB7XG4gICAgICBpZiAoIV8uaXNOdWxsKGVycikpIHtcbiAgICAgICAgcmV0dXJuIHJlamVjdChlcnIpO1xuICAgICAgfSBlbHNlIGlmICghXy5pc1VuZGVmaW5lZChsYXRlc3QpKSB7XG4gICAgICAgIFNlYXJjaC5hZGQobGF0ZXN0KTtcbiAgICAgIH1cbiAgICAgIHJldHVybiByZXNvbHZlKCk7XG4gICAgfSk7XG4gIH0pO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gY2hlY2tQYWNrYWdlUmVtb3RlKFxuICBuYW1lOiBzdHJpbmcsXG4gIGlzQWxsb3dQdWJsaXNoT2ZmbGluZTogYm9vbGVhbixcbiAgc3luY01ldGFkYXRhOiBGdW5jdGlvblxuKTogUHJvbWlzZTxhbnk+IHtcbiAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpOiB2b2lkID0+IHtcbiAgICBzeW5jTWV0YWRhdGEobmFtZSwgbnVsbCwge30sIChlcnIsIHBhY2thZ2VKc29uTG9jYWwsIHVwTGlua3NFcnJvcnMpOiB2b2lkID0+IHtcbiAgICAgIC8vIHNvbWV0aGluZyB3ZWlyZFxuICAgICAgaWYgKGVyciAmJiBlcnIuc3RhdHVzICE9PSBIVFRQX1NUQVRVUy5OT1RfRk9VTkQpIHtcbiAgICAgICAgcmV0dXJuIHJlamVjdChlcnIpO1xuICAgICAgfVxuXG4gICAgICAvLyBjaGVja2luZyBwYWNrYWdlIGV4aXN0IGFscmVhZHlcbiAgICAgIGlmIChfLmlzTmlsKHBhY2thZ2VKc29uTG9jYWwpID09PSBmYWxzZSkge1xuICAgICAgICByZXR1cm4gcmVqZWN0KEVycm9yQ29kZS5nZXRDb25mbGljdChBUElfRVJST1IuUEFDS0FHRV9FWElTVCkpO1xuICAgICAgfVxuXG4gICAgICBmb3IgKGxldCBlcnJvckl0ZW0gPSAwOyBlcnJvckl0ZW0gPCB1cExpbmtzRXJyb3JzLmxlbmd0aDsgZXJyb3JJdGVtKyspIHtcbiAgICAgICAgLy8gY2hlY2tpbmcgZXJyb3JcbiAgICAgICAgLy8gaWYgdXBsaW5rIGZhaWxzIHdpdGggYSBzdGF0dXMgb3RoZXIgdGhhbiA0MDQsIHdlIHJlcG9ydCBmYWlsdXJlXG4gICAgICAgIGlmIChfLmlzTmlsKHVwTGlua3NFcnJvcnNbZXJyb3JJdGVtXVswXSkgPT09IGZhbHNlKSB7XG4gICAgICAgICAgaWYgKHVwTGlua3NFcnJvcnNbZXJyb3JJdGVtXVswXS5zdGF0dXMgIT09IEhUVFBfU1RBVFVTLk5PVF9GT1VORCkge1xuICAgICAgICAgICAgaWYgKGlzQWxsb3dQdWJsaXNoT2ZmbGluZSkge1xuICAgICAgICAgICAgICByZXR1cm4gcmVzb2x2ZSgpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gcmVqZWN0KEVycm9yQ29kZS5nZXRTZXJ2aWNlVW5hdmFpbGFibGUoQVBJX0VSUk9SLlVQTElOS19PRkZMSU5FX1BVQkxJU0gpKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHJlc29sdmUoKTtcbiAgICB9KTtcbiAgfSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBtZXJnZVVwbGlua1RpbWVJbnRvTG9jYWwobG9jYWxNZXRhZGF0YTogUGFja2FnZSwgcmVtb3RlTWV0YWRhdGE6IFBhY2thZ2UpOiBhbnkge1xuICBpZiAoJ3RpbWUnIGluIHJlbW90ZU1ldGFkYXRhKSB7XG4gICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oe30sIGxvY2FsTWV0YWRhdGEudGltZSwgcmVtb3RlTWV0YWRhdGEudGltZSk7XG4gIH1cblxuICByZXR1cm4gbG9jYWxNZXRhZGF0YS50aW1lO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcHJlcGFyZVNlYXJjaFBhY2thZ2UoZGF0YTogUGFja2FnZSwgdGltZTogdW5rbm93bik6IGFueSB7XG4gIGNvbnN0IGxpc3RWZXJzaW9uczogc3RyaW5nW10gPSBPYmplY3Qua2V5cyhkYXRhLnZlcnNpb25zKTtcbiAgY29uc3QgdmVyc2lvbnM6IHN0cmluZ1tdID0gc2VtdmVyU29ydChsaXN0VmVyc2lvbnMpO1xuICBjb25zdCBsYXRlc3Q6IHN0cmluZyB8IHVuZGVmaW5lZCA9XG4gICAgZGF0YVtESVNUX1RBR1NdICYmIGRhdGFbRElTVF9UQUdTXS5sYXRlc3QgPyBkYXRhW0RJU1RfVEFHU10ubGF0ZXN0IDogdmVyc2lvbnMucG9wKCk7XG5cbiAgaWYgKGxhdGVzdCAmJiBkYXRhLnZlcnNpb25zW2xhdGVzdF0pIHtcbiAgICBjb25zdCB2ZXJzaW9uOiBWZXJzaW9uID0gZGF0YS52ZXJzaW9uc1tsYXRlc3RdO1xuICAgIGNvbnN0IHZlcnNpb25zOiBhbnkgPSB7IFtsYXRlc3RdOiAnbGF0ZXN0JyB9O1xuICAgIGNvbnN0IHBrZzogYW55ID0ge1xuICAgICAgbmFtZTogdmVyc2lvbi5uYW1lLFxuICAgICAgZGVzY3JpcHRpb246IHZlcnNpb24uZGVzY3JpcHRpb24sXG4gICAgICBbRElTVF9UQUdTXTogeyBsYXRlc3QgfSxcbiAgICAgIG1haW50YWluZXJzOiB2ZXJzaW9uLm1haW50YWluZXJzIHx8IFt2ZXJzaW9uLmF1dGhvcl0uZmlsdGVyKEJvb2xlYW4pLFxuICAgICAgYXV0aG9yOiB2ZXJzaW9uLmF1dGhvcixcbiAgICAgIHJlcG9zaXRvcnk6IHZlcnNpb24ucmVwb3NpdG9yeSxcbiAgICAgIHJlYWRtZUZpbGVuYW1lOiB2ZXJzaW9uLnJlYWRtZUZpbGVuYW1lIHx8ICcnLFxuICAgICAgaG9tZXBhZ2U6IHZlcnNpb24uaG9tZXBhZ2UsXG4gICAgICBrZXl3b3JkczogdmVyc2lvbi5rZXl3b3JkcyxcbiAgICAgIGJ1Z3M6IHZlcnNpb24uYnVncyxcbiAgICAgIGxpY2Vuc2U6IHZlcnNpb24ubGljZW5zZSxcbiAgICAgIHRpbWU6IHtcbiAgICAgICAgbW9kaWZpZWQ6IHRpbWVcbiAgICAgIH0sXG4gICAgICB2ZXJzaW9uc1xuICAgIH07XG5cbiAgICByZXR1cm4gcGtnO1xuICB9XG59XG5cbi8qKlxuICogQ2hlY2sgd2hldGhlciB0aGUgcGFja2FnZSBtZXRhZHRhIGhhcyBlbm91Z2ggZGF0YSB0byBiZSBwdWJsaXNoZWRcbiAqIEBwYXJhbSBwa2cgbWV0YWRhdGFcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzUHVibGlzaGFibGVQYWNrYWdlKHBrZzogUGFja2FnZSk6IGJvb2xlYW4ge1xuICBjb25zdCBrZXlzOiBzdHJpbmdbXSA9IE9iamVjdC5rZXlzKHBrZyk7XG5cbiAgcmV0dXJuIF8uaW5jbHVkZXMoa2V5cywgJ3ZlcnNpb25zJyk7XG59XG4iXX0=
;