spee.ch/index.js

4219 lines
391 KiB
JavaScript

module.exports =
/******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId]) {
/******/ return installedModules[moduleId].exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ i: moduleId,
/******/ l: false,
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ // Flag the module as loaded
/******/ module.l = true;
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/******/
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/
/******/ // define getter function for harmony exports
/******/ __webpack_require__.d = function(exports, name, getter) {
/******/ if(!__webpack_require__.o(exports, name)) {
/******/ Object.defineProperty(exports, name, {
/******/ configurable: false,
/******/ enumerable: true,
/******/ get: getter
/******/ });
/******/ }
/******/ };
/******/
/******/ // getDefaultExport function for compatibility with non-harmony modules
/******/ __webpack_require__.n = function(module) {
/******/ var getter = module && module.__esModule ?
/******/ function getDefault() { return module['default']; } :
/******/ function getModuleExports() { return module; };
/******/ __webpack_require__.d(getter, 'a', getter);
/******/ return getter;
/******/ };
/******/
/******/ // Object.prototype.hasOwnProperty.call
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "/";
/******/
/******/ // Load entry module and return exports
/******/ return __webpack_require__(__webpack_require__.s = 26);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ (function(module, exports) {
module.exports = require("winston");
/***/ }),
/* 1 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
var logger = __webpack_require__(0);
module.exports = {
handleErrorResponse: function handleErrorResponse(originalUrl, ip, error, res) {
logger.error('Error on ' + originalUrl, module.exports.useObjectPropertiesIfNoKeys(error));
var _module$exports$retur = module.exports.returnErrorMessageAndStatus(error),
_module$exports$retur2 = _slicedToArray(_module$exports$retur, 2),
status = _module$exports$retur2[0],
message = _module$exports$retur2[1];
res.status(status).json(module.exports.createErrorResponsePayload(status, message));
},
returnErrorMessageAndStatus: function returnErrorMessageAndStatus(error) {
var status = void 0,
message = void 0;
// check for daemon being turned off
if (error.code === 'ECONNREFUSED') {
status = 503;
message = 'Connection refused. The daemon may not be running.';
// fallback for everything else
} else {
status = 400;
if (error.message) {
message = error.message;
} else {
message = error;
};
};
return [status, message];
},
useObjectPropertiesIfNoKeys: function useObjectPropertiesIfNoKeys(err) {
if (Object.keys(err).length === 0) {
var newErrorObject = {};
Object.getOwnPropertyNames(err).forEach(function (key) {
newErrorObject[key] = err[key];
});
return newErrorObject;
}
return err;
},
createErrorResponsePayload: function createErrorResponsePayload(status, message) {
return {
status: status,
success: false,
message: message
};
}
};
/***/ }),
/* 2 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var Certificate = __webpack_require__(45);
var Channel = __webpack_require__(46);
var Claim = __webpack_require__(47);
var File = __webpack_require__(48);
var Request = __webpack_require__(49);
var User = __webpack_require__(50);
var Sequelize = __webpack_require__(13);
var logger = __webpack_require__(0);
var _require = __webpack_require__(10),
database = _require.database,
username = _require.username,
password = _require.password;
// set sequelize options
var sequelize = new Sequelize(database, username, password, {
host: 'localhost',
dialect: 'mysql',
dialectOptions: { decimalNumbers: true },
logging: false,
pool: {
max: 5,
min: 0,
idle: 10000,
acquire: 10000
}
});
// establish mysql connection
sequelize.authenticate().then(function () {
logger.info('Sequelize has established mysql connection successfully.');
}).catch(function (err) {
logger.error('Sequelize was unable to connect to the database:', err);
});
// manually add each model to the db object (note: make this dynamic)
var db = {};
db['Certificate'] = sequelize.import('Certificate', Certificate);
db['Channel'] = sequelize.import('Channel', Channel);
db['Claim'] = sequelize.import('Claim', Claim);
db['File'] = sequelize.import('File', File);
db['Request'] = sequelize.import('Request', Request);
db['User'] = sequelize.import('User', User);
// run model.association for each model in the db object that has an association
logger.info('associating db models...');
Object.keys(db).forEach(function (modelName) {
if (db[modelName].associate) {
logger.info('Associating model:', modelName);
db[modelName].associate(db);
}
});
// add sequelize/Sequelize to db
db.sequelize = sequelize;
db.Sequelize = Sequelize;
// add an 'upsert' method to the db object
db.upsert = function (Model, values, condition, tableName) {
return Model.findOne({
where: condition
}).then(function (obj) {
if (obj) {
// update
logger.debug('updating record in db.' + tableName);
return obj.update(values);
} else {
// insert
logger.debug('creating record in db.' + tableName);
return Model.create(values);
}
}).catch(function (error) {
logger.error(tableName + '.upsert error', error);
throw error;
});
};
module.exports = db;
/***/ }),
/* 3 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
function SiteConfig() {
var _this = this;
this.analytics = {
googleId: 'default'
};
this.assetDefaults = {
description: 'An asset published on Spee.ch',
thumbnail: 'https://spee.ch/assets/img/video_thumb_default.png',
title: 'Spee.ch'
};
this.auth = {
sessionKey: 'default'
};
this.customComponents = {};
this.customContainers = {};
this.customPages = {};
this.details = {
description: 'Open-source, decentralized image and video sharing.',
host: 'default',
port: 3000,
title: 'Spee.ch',
twitter: '@spee_ch'
};
this.publishing = {
additionalClaimAddresses: [],
disabled: false,
disabledMessage: 'Please check back soon.',
primaryClaimAddress: 'default',
thumbnailChannel: 'default',
thumbnailChannelId: 'default',
uploadDirectory: '/home/lbry/Uploads'
};
this.routes = {};
this.update = function (config) {
if (!config) {
return console.log('No site config received.');
}
var analytics = config.analytics,
assetDefaults = config.assetDefaults,
auth = config.auth,
customComponents = config.customComponents,
customContainers = config.customContainers,
customPages = config.customPages,
details = config.details,
publishing = config.publishing,
routes = config.routes;
console.log('Configuring site details...');
_this.analytics = analytics;
_this.assetDefaults = assetDefaults;
_this.auth = auth;
_this.details = details;
_this.publishing = publishing;
_this.customComponents = customComponents;
_this.customContainers = customContainers;
_this.customPages = customPages;
_this.routes = routes;
};
};
module.exports = new SiteConfig();
/***/ }),
/* 4 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var logger = __webpack_require__(0);
var ua = __webpack_require__(55);
var _require = __webpack_require__(3),
googleId = _require.analytics.googleId,
title = _require.details.title;
function createServeEventParams(headers, ip, originalUrl) {
return {
eventCategory: 'client requests',
eventAction: 'serve request',
eventLabel: originalUrl,
ipOverride: ip,
userAgentOverride: headers['user-agent']
};
};
function createPublishTimingEventParams(category, variable, label, startTime, endTime) {
var duration = endTime - startTime;
return {
userTimingCategory: category,
userTimingVariableName: variable,
userTimingTime: duration,
userTimingLabel: label
};
};
function sendGoogleAnalyticsEvent(ip, params) {
var visitorId = ip.replace(/\./g, '-');
var visitor = ua(googleId, visitorId, { strictCidFormat: false, https: true });
visitor.event(params, function (err) {
if (err) {
logger.error('Google Analytics Event Error >>', err);
}
});
};
function sendGoogleAnalyticsTiming(visitorId, params) {
var visitor = ua(googleId, visitorId, { strictCidFormat: false, https: true });
visitor.timing(params, function (err) {
if (err) {
logger.error('Google Analytics Event Error >>', err);
}
logger.debug('Timing event successfully sent to google analytics');
});
};
module.exports = {
sendGAServeEvent: function sendGAServeEvent(headers, ip, originalUrl) {
var params = createServeEventParams(headers, ip, originalUrl);
sendGoogleAnalyticsEvent(ip, params);
},
sendGATimingEvent: function sendGATimingEvent(category, variable, label, startTime, endTime) {
var params = createPublishTimingEventParams(category, variable, label, startTime, endTime);
sendGoogleAnalyticsTiming(title, params);
},
chooseGaLbrynetPublishLabel: function chooseGaLbrynetPublishLabel(_ref) {
var channelName = _ref.channel_name,
channelId = _ref.channel_id;
return channelName || channelId ? 'PUBLISH_IN_CHANNEL_CLAIM' : 'PUBLISH_ANONYMOUS_CLAIM';
}
};
/***/ }),
/* 5 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var axios = __webpack_require__(53);
var logger = __webpack_require__(0);
var _require = __webpack_require__(54),
_require$api = _require.api,
apiHost = _require$api.apiHost,
apiPort = _require$api.apiPort;
var lbryApiUri = 'http://' + apiHost + ':' + apiPort;
var _require2 = __webpack_require__(4),
chooseGaLbrynetPublishLabel = _require2.chooseGaLbrynetPublishLabel,
sendGATimingEvent = _require2.sendGATimingEvent;
var handleLbrynetResponse = function handleLbrynetResponse(_ref, resolve, reject) {
var data = _ref.data;
logger.debug('lbry api data:', data);
if (data.result) {
// check for an error
if (data.result.error) {
logger.debug('Lbrynet api error:', data.result.error);
reject(new Error(data.result.error));
return;
};
resolve(data.result);
return;
}
// fallback in case it just timed out
reject(JSON.stringify(data));
};
module.exports = {
publishClaim: function publishClaim(publishParams) {
logger.debug('lbryApi >> Publishing claim to "' + publishParams.name + '"');
var gaStartTime = Date.now();
return new Promise(function (resolve, reject) {
axios.post(lbryApiUri, {
method: 'publish',
params: publishParams
}).then(function (response) {
sendGATimingEvent('lbrynet', 'publish', chooseGaLbrynetPublishLabel(publishParams), gaStartTime, Date.now());
handleLbrynetResponse(response, resolve, reject);
}).catch(function (error) {
reject(error);
});
});
},
getClaim: function getClaim(uri) {
logger.debug('lbryApi >> Getting Claim for "' + uri + '"');
var gaStartTime = Date.now();
return new Promise(function (resolve, reject) {
axios.post(lbryApiUri, {
method: 'get',
params: { uri: uri, timeout: 20 }
}).then(function (response) {
sendGATimingEvent('lbrynet', 'getClaim', 'GET', gaStartTime, Date.now());
handleLbrynetResponse(response, resolve, reject);
}).catch(function (error) {
reject(error);
});
});
},
getClaimList: function getClaimList(claimName) {
logger.debug('lbryApi >> Getting claim_list for "' + claimName + '"');
var gaStartTime = Date.now();
return new Promise(function (resolve, reject) {
axios.post(lbryApiUri, {
method: 'claim_list',
params: { name: claimName }
}).then(function (response) {
sendGATimingEvent('lbrynet', 'getClaimList', 'CLAIM_LIST', gaStartTime, Date.now());
handleLbrynetResponse(response, resolve, reject);
}).catch(function (error) {
reject(error);
});
});
},
resolveUri: function resolveUri(uri) {
logger.debug('lbryApi >> Resolving URI for "' + uri + '"');
var gaStartTime = Date.now();
return new Promise(function (resolve, reject) {
axios.post(lbryApiUri, {
method: 'resolve',
params: { uri: uri }
}).then(function (_ref2) {
var data = _ref2.data;
sendGATimingEvent('lbrynet', 'resolveUri', 'RESOLVE', gaStartTime, Date.now());
if (data.result[uri].error) {
// check for errors
reject(data.result[uri].error);
} else {
// if no errors, resolve
resolve(data.result[uri]);
}
}).catch(function (error) {
reject(error);
});
});
},
getDownloadDirectory: function getDownloadDirectory() {
logger.debug('lbryApi >> Retrieving the download directory path from lbry daemon...');
var gaStartTime = Date.now();
return new Promise(function (resolve, reject) {
axios.post(lbryApiUri, {
method: 'settings_get'
}).then(function (_ref3) {
var data = _ref3.data;
sendGATimingEvent('lbrynet', 'getDownloadDirectory', 'SETTINGS_GET', gaStartTime, Date.now());
if (data.result) {
resolve(data.result.download_directory);
} else {
return new Error('Successfully connected to lbry daemon, but unable to retrieve the download directory.');
}
}).catch(function (error) {
logger.error('Lbrynet Error:', error);
resolve('/home/lbry/Downloads/');
});
});
},
createChannel: function createChannel(name) {
logger.debug('lbryApi >> Creating channel for ' + name + '...');
var gaStartTime = Date.now();
return new Promise(function (resolve, reject) {
axios.post(lbryApiUri, {
method: 'channel_new',
params: {
channel_name: name,
amount: 0.1
}
}).then(function (response) {
sendGATimingEvent('lbrynet', 'createChannel', 'CHANNEL_NEW', gaStartTime, Date.now());
handleLbrynetResponse(response, resolve, reject);
}).catch(function (error) {
reject(error);
});
});
}
};
/***/ }),
/* 6 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
var db = __webpack_require__(2);
var logger = __webpack_require__(0);
var _require = __webpack_require__(66),
returnPaginatedChannelClaims = _require.returnPaginatedChannelClaims;
var NO_CHANNEL = 'NO_CHANNEL';
var NO_CLAIM = 'NO_CLAIM';
var NO_FILE = 'NO_FILE';
module.exports = {
getClaimId: function getClaimId(channelName, channelClaimId, name, claimId) {
if (channelName) {
return module.exports.getClaimIdByChannel(channelName, channelClaimId, name);
} else {
return module.exports.getClaimIdByClaim(name, claimId);
}
},
getClaimIdByClaim: function getClaimIdByClaim(claimName, claimId) {
logger.debug('getClaimIdByClaim(' + claimName + ', ' + claimId + ')');
return new Promise(function (resolve, reject) {
db.Claim.getLongClaimId(claimName, claimId).then(function (longClaimId) {
if (!longClaimId) {
resolve(NO_CLAIM);
}
resolve(longClaimId);
}).catch(function (error) {
reject(error);
});
});
},
getClaimIdByChannel: function getClaimIdByChannel(channelName, channelClaimId, claimName) {
logger.debug('getClaimIdByChannel(' + channelName + ', ' + channelClaimId + ', ' + claimName + ')');
return new Promise(function (resolve, reject) {
db.Certificate.getLongChannelId(channelName, channelClaimId) // 1. get the long channel id
.then(function (longChannelId) {
if (!longChannelId) {
return [null, null];
}
return Promise.all([longChannelId, db.Claim.getClaimIdByLongChannelId(longChannelId, claimName)]); // 2. get the long claim id
}).then(function (_ref) {
var _ref2 = _slicedToArray(_ref, 2),
longChannelId = _ref2[0],
longClaimId = _ref2[1];
if (!longChannelId) {
return resolve(NO_CHANNEL);
}
if (!longClaimId) {
return resolve(NO_CLAIM);
}
resolve(longClaimId);
}).catch(function (error) {
reject(error);
});
});
},
getChannelData: function getChannelData(channelName, channelClaimId, page) {
return new Promise(function (resolve, reject) {
// 1. get the long channel Id (make sure channel exists)
db.Certificate.getLongChannelId(channelName, channelClaimId).then(function (longChannelClaimId) {
if (!longChannelClaimId) {
return [null, null, null];
}
// 2. get the short ID and all claims for that channel
return Promise.all([longChannelClaimId, db.Certificate.getShortChannelIdFromLongChannelId(longChannelClaimId, channelName)]);
}).then(function (_ref3) {
var _ref4 = _slicedToArray(_ref3, 2),
longChannelClaimId = _ref4[0],
shortChannelClaimId = _ref4[1];
if (!longChannelClaimId) {
return resolve(NO_CHANNEL);
}
// 3. return all the channel information
resolve({
channelName: channelName,
longChannelClaimId: longChannelClaimId,
shortChannelClaimId: shortChannelClaimId
});
}).catch(function (error) {
reject(error);
});
});
},
getChannelClaims: function getChannelClaims(channelName, channelClaimId, page) {
return new Promise(function (resolve, reject) {
// 1. get the long channel Id (make sure channel exists)
db.Certificate.getLongChannelId(channelName, channelClaimId).then(function (longChannelClaimId) {
if (!longChannelClaimId) {
return [null, null, null];
}
// 2. get the short ID and all claims for that channel
return Promise.all([longChannelClaimId, db.Claim.getAllChannelClaims(longChannelClaimId)]);
}).then(function (_ref5) {
var _ref6 = _slicedToArray(_ref5, 2),
longChannelClaimId = _ref6[0],
channelClaimsArray = _ref6[1];
if (!longChannelClaimId) {
return resolve(NO_CHANNEL);
}
// 3. format the data for the view, including pagination
var paginatedChannelViewData = returnPaginatedChannelClaims(channelName, longChannelClaimId, channelClaimsArray, page);
// 4. return all the channel information and contents
resolve(paginatedChannelViewData);
}).catch(function (error) {
reject(error);
});
});
},
getLocalFileRecord: function getLocalFileRecord(claimId, name) {
return db.File.findOne({ where: { claimId: claimId, name: name } }).then(function (file) {
if (!file) {
return NO_FILE;
}
return file.dataValues;
});
}
};
/***/ }),
/* 7 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var passport = __webpack_require__(43);
var localLoginStrategy = __webpack_require__(44);
var localSignupStrategy = __webpack_require__(52);
var _require = __webpack_require__(56),
serializeSpeechUser = _require.serializeSpeechUser,
deserializeSpeechUser = _require.deserializeSpeechUser;
passport.deserializeUser(deserializeSpeechUser);
passport.serializeUser(serializeSpeechUser);
passport.use('local-login', localLoginStrategy);
passport.use('local-signup', localSignupStrategy);
module.exports = passport;
/***/ }),
/* 8 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
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; }
var logger = __webpack_require__(0);
var db = __webpack_require__(2);
var lbryApi = __webpack_require__(5);
var publishHelpers = __webpack_require__(9);
var _require = __webpack_require__(3),
_require$publishing = _require.publishing,
primaryClaimAddress = _require$publishing.primaryClaimAddress,
additionalClaimAddresses = _require$publishing.additionalClaimAddresses;
var Sequelize = __webpack_require__(13);
var Op = Sequelize.Op;
module.exports = {
publish: function publish(publishParams, fileName, fileType) {
return new Promise(function (resolve, reject) {
var publishResults = void 0,
certificateId = void 0,
channelName = void 0;
// publish the file
return lbryApi.publishClaim(publishParams).then(function (tx) {
logger.info('Successfully published ' + publishParams.name + ' ' + fileName, tx);
publishResults = tx;
// get the channel information
if (publishParams.channel_name) {
logger.debug('this claim was published in channel: ' + publishParams.channel_name);
return db.Channel.findOne({
where: {
channelName: publishParams.channel_name
}
});
} else {
logger.debug('this claim was not published in a channel');
return null;
}
}).then(function (channel) {
// set channel information
certificateId = null;
channelName = null;
if (channel) {
certificateId = channel.channelClaimId;
channelName = channel.channelName;
}
logger.debug('certificateId: ' + certificateId);
}).then(function () {
// create the File record
var fileRecord = {
name: publishParams.name,
claimId: publishResults.claim_id,
title: publishParams.metadata.title,
description: publishParams.metadata.description,
address: publishParams.claim_address,
outpoint: publishResults.txid + ':' + publishResults.nout,
height: 0,
fileName: fileName,
filePath: publishParams.file_path,
fileType: fileType,
nsfw: publishParams.metadata.nsfw
};
// create the Claim record
var claimRecord = {
name: publishParams.name,
claimId: publishResults.claim_id,
title: publishParams.metadata.title,
description: publishParams.metadata.description,
address: publishParams.claim_address,
thumbnail: publishParams.metadata.thumbnail,
outpoint: publishResults.txid + ':' + publishResults.nout,
height: 0,
contentType: fileType,
nsfw: publishParams.metadata.nsfw,
amount: publishParams.bid,
certificateId: certificateId,
channelName: channelName
};
// upsert criteria
var upsertCriteria = {
name: publishParams.name,
claimId: publishResults.claim_id
};
// upsert the records
return Promise.all([db.upsert(db.File, fileRecord, upsertCriteria, 'File'), db.upsert(db.Claim, claimRecord, upsertCriteria, 'Claim')]);
}).then(function (_ref) {
var _ref2 = _slicedToArray(_ref, 2),
file = _ref2[0],
claim = _ref2[1];
logger.debug('File and Claim records successfully created');
return Promise.all([file.setClaim(claim), claim.setFile(file)]);
}).then(function () {
logger.debug('File and Claim records successfully associated');
resolve(publishResults); // resolve the promise with the result from lbryApi.publishClaim;
}).catch(function (error) {
logger.error('PUBLISH ERROR', error);
publishHelpers.deleteTemporaryFile(publishParams.file_path); // delete the local file
reject(error);
});
});
},
claimNameIsAvailable: function claimNameIsAvailable(name) {
var claimAddresses = additionalClaimAddresses || [];
claimAddresses.push(primaryClaimAddress);
// find any records where the name is used
return db.Claim.findAll({
attributes: ['address'],
where: {
name: name,
address: _defineProperty({}, Op.or, claimAddresses)
}
}).then(function (result) {
if (result.length >= 1) {
throw new Error('That claim is already in use');
};
return name;
}).catch(function (error) {
throw error;
});
},
checkChannelAvailability: function checkChannelAvailability(name) {
return db.Channel.findAll({
where: { channelName: name }
}).then(function (result) {
if (result.length >= 1) {
throw new Error('That channel has already been claimed');
}
return name;
}).catch(function (error) {
throw error;
});
}
};
/***/ }),
/* 9 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var logger = __webpack_require__(0);
var fs = __webpack_require__(64);
var _require = __webpack_require__(3),
details = _require.details,
publishing = _require.publishing;
module.exports = {
parsePublishApiRequestBody: function parsePublishApiRequestBody(_ref) {
var name = _ref.name,
nsfw = _ref.nsfw,
license = _ref.license,
title = _ref.title,
description = _ref.description,
thumbnail = _ref.thumbnail;
// validate name
if (!name) {
throw new Error('no name field found in request');
}
var invalidNameCharacters = /[^A-Za-z0-9,-]/.exec(name);
if (invalidNameCharacters) {
throw new Error('The claim name you provided is not allowed. Only the following characters are allowed: A-Z, a-z, 0-9, and "-"');
}
// optional parameters
nsfw = nsfw === 'true';
license = license || null;
title = title || null;
description = description || null;
thumbnail = thumbnail || null;
// return results
return {
name: name,
nsfw: nsfw,
license: license,
title: title,
description: description,
thumbnail: thumbnail
};
},
parsePublishApiRequestFiles: function parsePublishApiRequestFiles(_ref2) {
var file = _ref2.file,
thumbnail = _ref2.thumbnail;
// make sure a file was provided
if (!file) {
throw new Error('no file with key of [file] found in request');
}
if (!file.path) {
throw new Error('no file path found');
}
if (!file.type) {
throw new Error('no file type found');
}
if (!file.size) {
throw new Error('no file type found');
}
// validate the file name
if (/'/.test(file.name)) {
throw new Error('apostrophes are not allowed in the file name');
}
// validate the file
module.exports.validateFileTypeAndSize(file);
// return results
return {
fileName: file.name,
filePath: file.path,
fileType: file.type,
thumbnailFileName: thumbnail ? thumbnail.name : null,
thumbnailFilePath: thumbnail ? thumbnail.path : null,
thumbnailFileType: thumbnail ? thumbnail.type : null
};
},
validateFileTypeAndSize: function validateFileTypeAndSize(file) {
// check file type and size
switch (file.type) {
case 'image/jpeg':
case 'image/jpg':
case 'image/png':
if (file.size > 10000000) {
logger.debug('publish > file validation > .jpeg/.jpg/.png was too big');
throw new Error('Sorry, images are limited to 10 megabytes.');
}
break;
case 'image/gif':
if (file.size > 50000000) {
logger.debug('publish > file validation > .gif was too big');
throw new Error('Sorry, .gifs are limited to 50 megabytes.');
}
break;
case 'video/mp4':
if (file.size > 50000000) {
logger.debug('publish > file validation > .mp4 was too big');
throw new Error('Sorry, videos are limited to 50 megabytes.');
}
break;
default:
logger.debug('publish > file validation > unrecognized file type');
throw new Error('The ' + file.type + ' content type is not supported. Only, .jpeg, .png, .gif, and .mp4 files are currently supported.');
}
return file;
},
createBasicPublishParams: function createBasicPublishParams(filePath, name, title, description, license, nsfw, thumbnail) {
logger.debug('Creating Publish Parameters');
// provide defaults for title
if (title === null || title.trim() === '') {
title = name;
}
// provide default for description
if (description === null || description.trim() === '') {
description = '';
}
// provide default for license
if (license === null || license.trim() === '') {
license = ' '; // default to empty string
}
// create the publish params
var publishParams = {
name: name,
file_path: filePath,
bid: 0.01,
metadata: {
description: description,
title: title,
author: details.title,
language: 'en',
license: license,
nsfw: nsfw
},
claim_address: publishing.primaryClaimAddress
};
// add thumbnail to channel if video
if (thumbnail) {
publishParams['metadata']['thumbnail'] = thumbnail;
}
return publishParams;
},
createThumbnailPublishParams: function createThumbnailPublishParams(thumbnailFilePath, claimName, license, nsfw) {
if (!thumbnailFilePath) {
return;
}
logger.debug('Creating Thumbnail Publish Parameters');
// create the publish params
return {
name: claimName + '-thumb',
file_path: thumbnailFilePath,
bid: 0.01,
metadata: {
title: claimName + ' thumbnail',
description: 'a thumbnail for ' + claimName,
author: details.title,
language: 'en',
license: license,
nsfw: nsfw
},
claim_address: publishing.primaryClaimAddress,
channel_name: publishing.thumbnailChannel,
channel_id: publishing.thumbnailChannelId
};
},
deleteTemporaryFile: function deleteTemporaryFile(filePath) {
fs.unlink(filePath, function (err) {
if (err) {
logger.error('error deleting temporary file ' + filePath);
throw err;
}
logger.debug('successfully deleted ' + filePath);
});
},
addGetResultsToFileData: function addGetResultsToFileData(fileInfo, getResult) {
fileInfo.fileName = getResult.file_name;
fileInfo.filePath = getResult.download_path;
return fileInfo;
},
createFileData: function createFileData(_ref3) {
var name = _ref3.name,
claimId = _ref3.claimId,
outpoint = _ref3.outpoint,
height = _ref3.height,
address = _ref3.address,
nsfw = _ref3.nsfw,
contentType = _ref3.contentType;
return {
name: name,
claimId: claimId,
outpoint: outpoint,
height: height,
address: address,
fileName: '',
filePath: '',
fileType: contentType,
nsfw: nsfw
};
}
};
/***/ }),
/* 10 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var logger = __webpack_require__(0);
function mysql() {
var _this = this;
this.database = 'default';
this.username = 'default';
this.password = 'default';
this.update = function (config) {
if (!config) {
return logger.warn('No MySQL config received.');
}
// configure credentials
logger.info('configuring mysql...');
var database = config.database,
username = config.username,
password = config.password;
_this.database = database;
_this.username = username;
_this.password = password;
};
};
module.exports = new mysql();
/***/ }),
/* 11 */
/***/ (function(module, exports) {
module.exports = require("passport-local");
/***/ }),
/* 12 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
module.exports = {
returnShortId: function returnShortId(claimsArray, longId) {
var claimIndex = void 0;
var shortId = longId.substring(0, 1); // default short id is the first letter
var shortIdLength = 0;
// find the index of this claim id
claimIndex = claimsArray.findIndex(function (element) {
return element.claimId === longId;
});
if (claimIndex < 0) {
throw new Error('claim id not found in claims list');
}
// get an array of all claims with lower height
var possibleMatches = claimsArray.slice(0, claimIndex);
// remove certificates with the same prefixes until none are left.
while (possibleMatches.length > 0) {
shortIdLength += 1;
shortId = longId.substring(0, shortIdLength);
possibleMatches = possibleMatches.filter(function (element) {
return element.claimId && element.claimId.substring(0, shortIdLength) === shortId;
});
}
return shortId;
}
};
/***/ }),
/* 13 */
/***/ (function(module, exports) {
module.exports = require("sequelize");
/***/ }),
/* 14 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _react = __webpack_require__(15);
var _react2 = _interopRequireDefault(_react);
var _server = __webpack_require__(16);
var _redux = __webpack_require__(17);
var _reactRedux = __webpack_require__(18);
var _reactRouterDom = __webpack_require__(19);
var _spee = __webpack_require__(20);
var _renderFullPage = __webpack_require__(21);
var _renderFullPage2 = _interopRequireDefault(_renderFullPage);
var _reactHelmet = __webpack_require__(22);
var _reactHelmet2 = _interopRequireDefault(_reactHelmet);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/*
^ note: to do this right, maybe
these should be passed in from the implementation (www.spee.ch) itself,
so that there are no conflicts between the SSR here and
the bundle sent to the server?
there might also be issues if this package uses a different version of spee.ch-components than www.spee.ch does?
*/
var siteConfig = __webpack_require__(3);
module.exports = function (req, res) {
var context = {};
// customize the reducer by passing in intial state configs
var MyReducers = (0, _spee.Reducers)(siteConfig);
var MyApp = (0, _spee.App)(siteConfig);
var MyGAListener = (0, _spee.GAListener)(siteConfig);
// create a new Redux store instance
var store = (0, _redux.createStore)(MyReducers);
// render component to a string
var html = (0, _server.renderToString)(_react2.default.createElement(
_reactRedux.Provider,
{ store: store },
_react2.default.createElement(
_reactRouterDom.StaticRouter,
{ location: req.url, context: context },
_react2.default.createElement(
MyGAListener,
null,
_react2.default.createElement(MyApp, null)
)
)
));
// get head tags from helmet
var helmet = _reactHelmet2.default.renderStatic();
// check for a redirect
if (context.url) {
// Somewhere a `<Redirect>` was rendered
return res.redirect(301, context.url);
} else {}
// we're good, send the response
// get the initial state from our Redux store
var preloadedState = store.getState();
// send the rendered page back to the client
res.send((0, _renderFullPage2.default)(helmet, html, preloadedState));
console.log('hello from spee.ch handlePageRender.jsx');
};
/***/ }),
/* 15 */
/***/ (function(module, exports) {
module.exports = require("react");
/***/ }),
/* 16 */
/***/ (function(module, exports) {
module.exports = require("react-dom/server");
/***/ }),
/* 17 */
/***/ (function(module, exports) {
module.exports = require("redux");
/***/ }),
/* 18 */
/***/ (function(module, exports) {
module.exports = require("react-redux");
/***/ }),
/* 19 */
/***/ (function(module, exports) {
module.exports = require("react-router-dom");
/***/ }),
/* 20 */
/***/ (function(module, exports) {
module.exports = require("spee.ch-components");
/***/ }),
/* 21 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
module.exports = function (helmet, html, preloadedState) {
// take the html and preloadedState and return the full page
return '\n <!DOCTYPE html>\n <html lang="en" prefix="og: http://ogp.me/ns# fb: http://ogp.me/ns/fb#">\n <head>\n <meta charset="UTF-8">\n <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1, user-scalable=no">\n <meta http-equiv="X-UA-Compatible" content="ie=edge">\n <!--helmet-->\n ' + helmet.title.toString() + '\n ' + helmet.meta.toString() + '\n ' + helmet.link.toString() + '\n <!--style sheets-->\n <link rel="stylesheet" href="/assets/css/reset.css" type="text/css">\n <link rel="stylesheet" href="/assets/css/general.css" type="text/css">\n <link rel="stylesheet" href="/assets/css/mediaQueries.css" type="text/css">\n <!--google font-->\n <link href="https://fonts.googleapis.com/css?family=Roboto:300" rel="stylesheet">\n </head>\n <body id="main-body">\n <div class="row row--tall flex-container--column">\n <div id="react-app" class="row row--tall flex-container--column">' + html + '</div>\n </div>\n <script>\n window.__PRELOADED_STATE__ = ' + JSON.stringify(preloadedState).replace(/</g, '\\<') + '\n </script>\n <script src="/bundle/bundle.js"></script>\n </body>\n </html>\n ';
};
/***/ }),
/* 22 */
/***/ (function(module, exports) {
module.exports = require("react-helmet");
/***/ }),
/* 23 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var logger = __webpack_require__(0);
var _require = __webpack_require__(6),
getClaimId = _require.getClaimId,
getLocalFileRecord = _require.getLocalFileRecord;
var _require2 = __webpack_require__(1),
handleErrorResponse = _require2.handleErrorResponse;
var SERVE = 'SERVE';
var SHOW = 'SHOW';
var NO_FILE = 'NO_FILE';
var NO_CHANNEL = 'NO_CHANNEL';
var NO_CLAIM = 'NO_CLAIM';
function clientAcceptsHtml(_ref) {
var accept = _ref.accept;
return accept && accept.match(/text\/html/);
};
function requestIsFromBrowser(headers) {
return headers['user-agent'] && headers['user-agent'].match(/Mozilla/);
};
function clientWantsAsset(_ref2) {
var accept = _ref2.accept,
range = _ref2.range;
var imageIsWanted = accept && accept.match(/image\/.*/) && !accept.match(/text\/html/) && !accept.match(/text\/\*/);
var videoIsWanted = accept && range;
return imageIsWanted || videoIsWanted;
};
function isValidClaimId(claimId) {
return claimId.length === 40 && !/[^A-Za-z0-9]/g.test(claimId);
};
function isValidShortId(claimId) {
return claimId.length === 1; // it should really evaluate the short url itself
};
function isValidShortIdOrClaimId(input) {
return isValidClaimId(input) || isValidShortId(input);
};
function serveAssetToClient(claimId, name, res) {
return getLocalFileRecord(claimId, name).then(function (fileRecord) {
// check that a local record was found
if (fileRecord === NO_FILE) {
return res.status(307).redirect('/api/claim/get/' + name + '/' + claimId);
}
// serve the file
var filePath = fileRecord.filePath,
fileType = fileRecord.fileType;
logger.verbose('serving file: ' + filePath);
var sendFileOptions = {
headers: {
'X-Content-Type-Options': 'nosniff',
'Content-Type': fileType || 'image/jpeg'
}
};
res.status(200).sendFile(filePath, sendFileOptions);
}).catch(function (error) {
throw error;
});
};
module.exports = {
getClaimIdAndServeAsset: function getClaimIdAndServeAsset(channelName, channelClaimId, claimName, claimId, originalUrl, ip, res) {
// get the claim Id and then serve the asset
getClaimId(channelName, channelClaimId, claimName, claimId).then(function (fullClaimId) {
if (fullClaimId === NO_CLAIM) {
return res.status(404).json({ success: false, message: 'no claim id could be found' });
} else if (fullClaimId === NO_CHANNEL) {
return res.status(404).json({ success: false, message: 'no channel id could be found' });
}
serveAssetToClient(fullClaimId, claimName, res);
// postToStats(responseType, originalUrl, ip, claimName, fullClaimId, 'success');
}).catch(function (error) {
handleErrorResponse(originalUrl, ip, error, res);
// postToStats(responseType, originalUrl, ip, claimName, fullClaimId, 'fail');
});
},
determineResponseType: function determineResponseType(hasFileExtension, headers) {
var responseType = void 0;
if (hasFileExtension) {
responseType = SERVE; // assume a serve request if file extension is present
if (clientAcceptsHtml(headers)) {
// if the request comes from a browser, change it to a show request
responseType = SHOW;
}
} else {
responseType = SHOW;
if (clientWantsAsset(headers) && requestIsFromBrowser(headers)) {
// this is in case someone embeds a show url
logger.debug('Show request came from browser but wants an image/video. Changing response to serve...');
responseType = SERVE;
}
}
return responseType;
},
flipClaimNameAndIdForBackwardsCompatibility: function flipClaimNameAndIdForBackwardsCompatibility(identifier, name) {
// this is a patch for backwards compatability with '/name/claim_id' url format
if (isValidShortIdOrClaimId(name) && !isValidShortIdOrClaimId(identifier)) {
var tempName = name;
name = identifier;
identifier = tempName;
}
return [identifier, name];
},
logRequestData: function logRequestData(responseType, claimName, channelName, claimId) {
logger.debug('responseType ===', responseType);
logger.debug('claim name === ', claimName);
logger.debug('channel name ===', channelName);
logger.debug('claim id ===', claimId);
}
};
/***/ }),
/* 24 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
var logger = __webpack_require__(0);
module.exports = {
REGEXP_INVALID_CLAIM: /[^A-Za-z0-9-]/g,
REGEXP_INVALID_CHANNEL: /[^A-Za-z0-9-@]/g,
REGEXP_ADDRESS: /^b(?=[^0OIl]{32,33})[0-9A-Za-z]{32,33}$/,
CHANNEL_CHAR: '@',
parseIdentifier: function parseIdentifier(identifier) {
logger.debug('parsing identifier:', identifier);
var componentsRegex = new RegExp('([^:$#/]*)' + // value (stops at the first separator or end)
'([:$#]?)([^/]*)' // modifier separator, modifier (stops at the first path separator or end)
);
var _componentsRegex$exec = componentsRegex.exec(identifier).map(function (match) {
return match || null;
}),
_componentsRegex$exec2 = _slicedToArray(_componentsRegex$exec, 4),
proto = _componentsRegex$exec2[0],
value = _componentsRegex$exec2[1],
modifierSeperator = _componentsRegex$exec2[2],
modifier = _componentsRegex$exec2[3];
logger.debug(proto + ', ' + value + ', ' + modifierSeperator + ', ' + modifier);
// Validate and process name
if (!value) {
throw new Error('Check your url. No channel name provided before "' + modifierSeperator + '"');
}
var isChannel = value.startsWith(module.exports.CHANNEL_CHAR);
var channelName = isChannel ? value : null;
var claimId = void 0;
if (isChannel) {
if (!channelName) {
throw new Error('No channel name after @.');
}
var nameBadChars = channelName.match(module.exports.REGEXP_INVALID_CHANNEL);
if (nameBadChars) {
throw new Error('Invalid characters in channel name: ' + nameBadChars.join(', ') + '.');
}
} else {
claimId = value;
}
// Validate and process modifier
var channelClaimId = void 0;
if (modifierSeperator) {
if (!modifier) {
throw new Error('No modifier provided after separator "' + modifierSeperator + '"');
}
if (modifierSeperator === ':') {
channelClaimId = modifier;
} else {
throw new Error('The "' + modifierSeperator + '" modifier is not currently supported');
}
}
return {
isChannel: isChannel,
channelName: channelName,
channelClaimId: channelClaimId,
claimId: claimId
};
},
parseClaim: function parseClaim(claim) {
logger.debug('parsing name:', claim);
var componentsRegex = new RegExp('([^:$#/.]*)' + // name (stops at the first modifier)
'([:$#.]?)([^/]*)' // modifier separator, modifier (stops at the first path separator or end)
);
var _componentsRegex$exec3 = componentsRegex.exec(claim).map(function (match) {
return match || null;
}),
_componentsRegex$exec4 = _slicedToArray(_componentsRegex$exec3, 4),
proto = _componentsRegex$exec4[0],
claimName = _componentsRegex$exec4[1],
modifierSeperator = _componentsRegex$exec4[2],
modifier = _componentsRegex$exec4[3];
logger.debug(proto + ', ' + claimName + ', ' + modifierSeperator + ', ' + modifier);
// Validate and process name
if (!claimName) {
throw new Error('No claim name provided before .');
}
var nameBadChars = claimName.match(module.exports.REGEXP_INVALID_CLAIM);
if (nameBadChars) {
throw new Error('Invalid characters in claim name: ' + nameBadChars.join(', ') + '.');
}
// Validate and process modifier
if (modifierSeperator) {
if (!modifier) {
throw new Error('No file extension provided after separator ' + modifierSeperator + '.');
}
if (modifierSeperator !== '.') {
throw new Error('The ' + modifierSeperator + ' modifier is not supported in the claim name');
}
}
// return results
return {
claimName: claimName
};
},
parseModifier: function parseModifier(claim) {
logger.debug('parsing modifier:', claim);
var componentsRegex = new RegExp('([^:$#/.]*)' + // name (stops at the first modifier)
'([:$#.]?)([^/]*)' // modifier separator, modifier (stops at the first path separator or end)
);
var _componentsRegex$exec5 = componentsRegex.exec(claim).map(function (match) {
return match || null;
}),
_componentsRegex$exec6 = _slicedToArray(_componentsRegex$exec5, 4),
proto = _componentsRegex$exec6[0],
claimName = _componentsRegex$exec6[1],
modifierSeperator = _componentsRegex$exec6[2],
modifier = _componentsRegex$exec6[3];
logger.debug(proto + ', ' + claimName + ', ' + modifierSeperator + ', ' + modifier);
// Validate and process modifier
var hasFileExtension = false;
if (modifierSeperator) {
hasFileExtension = true;
}
return {
hasFileExtension: hasFileExtension
};
}
};
/***/ }),
/* 25 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _react = __webpack_require__(15);
var _react2 = _interopRequireDefault(_react);
var _server = __webpack_require__(16);
var _redux = __webpack_require__(17);
var _reactRedux = __webpack_require__(18);
var _reactRouterDom = __webpack_require__(19);
var _renderFullPage = __webpack_require__(21);
var _renderFullPage2 = _interopRequireDefault(_renderFullPage);
var _reduxSaga = __webpack_require__(87);
var _reduxSaga2 = _interopRequireDefault(_reduxSaga);
var _effects = __webpack_require__(88);
var _spee = __webpack_require__(20);
var _reactHelmet = __webpack_require__(22);
var _reactHelmet2 = _interopRequireDefault(_reactHelmet);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
// configure the reducers by passing initial state configs
var siteConfig = __webpack_require__(3);
/*
^ note: to do this right, maybe
these should be passed in from the implementation (www.spee.ch) itself,
so that there are no conflicts between the SSR here and
the bundle sent to the server?
there might also be issues if this package uses a different version of spee.ch-components than www.spee.ch does?
*/
var MyReducers = (0, _spee.Reducers)(siteConfig);
var MyApp = (0, _spee.App)(siteConfig);
var MyGAListener = (0, _spee.GAListener)(siteConfig);
var returnSagaWithParams = function returnSagaWithParams(saga, params) {
return (/*#__PURE__*/regeneratorRuntime.mark(function _callee() {
return regeneratorRuntime.wrap(function _callee$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
_context.next = 2;
return (0, _effects.call)(saga, params);
case 2:
case 'end':
return _context.stop();
}
}
}, _callee, this);
})
);
};
module.exports = function (req, res) {
var context = {};
// create and apply middleware
var sagaMiddleware = (0, _reduxSaga2.default)();
var middleware = (0, _redux.applyMiddleware)(sagaMiddleware);
// create a new Redux store instance
var store = (0, _redux.createStore)(MyReducers, middleware);
// create saga
var action = _spee.Actions.onHandleShowPageUri(req.params);
var saga = returnSagaWithParams(_spee.Sagas.handleShowPageUri, action);
// run the saga middleware
sagaMiddleware.run(saga).done.then(function () {
// render component to a string
var html = (0, _server.renderToString)(_react2.default.createElement(
_reactRedux.Provider,
{ store: store },
_react2.default.createElement(
_reactRouterDom.StaticRouter,
{ location: req.url, context: context },
_react2.default.createElement(
MyGAListener,
null,
_react2.default.createElement(MyApp, null)
)
)
));
// get head tags from helmet
var helmet = _reactHelmet2.default.renderStatic();
// check for a redirect
if (context.url) {
return res.redirect(301, context.url);
}
// get the initial state from our Redux store
var preloadedState = store.getState();
// send the rendered page back to the client
res.send((0, _renderFullPage2.default)(helmet, html, preloadedState));
});
console.log('hello from spee.ch handleShowRender.jsx');
};
/***/ }),
/* 26 */
/***/ (function(module, exports, __webpack_require__) {
__webpack_require__(27);
__webpack_require__(28);
module.exports = __webpack_require__(29);
/***/ }),
/* 27 */
/***/ (function(module, exports) {
module.exports = require("babel-polyfill");
/***/ }),
/* 28 */
/***/ (function(module, exports) {
module.exports = require("whatwg-fetch");
/***/ }),
/* 29 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var Server = __webpack_require__(30);
var _exports = {
Server: Server
};
module.exports = _exports;
/***/ }),
/* 30 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
// app dependencies
var express = __webpack_require__(31);
var bodyParser = __webpack_require__(32);
var expressHandlebars = __webpack_require__(33);
var Handlebars = __webpack_require__(34);
var helmet = __webpack_require__(35);
var cookieSession = __webpack_require__(36);
var http = __webpack_require__(37);
var logger = __webpack_require__(0);
var requestLogger = __webpack_require__(38);
var Path = __webpack_require__(39);
var loggerConfig = __webpack_require__(40);
var mysqlConfig = __webpack_require__(10);
var siteConfig = __webpack_require__(3);
var slackConfig = __webpack_require__(41);
function Server() {
var _this = this;
this.configureLogger = function (userConfig) {
loggerConfig.update(userConfig);
};
this.configureMysql = function (userConfig) {
mysqlConfig.update(userConfig);
};
this.configureSiteDetails = function (userConfig) {
siteConfig.update(userConfig);
};
this.configureSlack = function (userConfig) {
slackConfig.update(userConfig);
};
this.configureClientBundle = function () {
logger.debug('configure the client here by passing in the bundle and configuring it, or better yet: taking in the components to use dynamically from here.');
};
this.configureModels = function () {
logger.debug('here is where you could add/overwrite the default models');
};
this.configureRoutes = function () {
logger.debug('here is where you could add/overwrite the default routes');
};
this.createApp = function () {
// create an Express application
var app = express();
// trust the proxy to get ip address for us
app.enable('trust proxy');
/* add middleware */
// set HTTP headers to protect against well-known web vulnerabilties
app.use(helmet());
// 'express.static' to serve static files from public directory
if (siteConfig.routes.publicFolder) {
// take in a different public folder, so it can serve it's own bundle if needed
var publicFolder = Path.resolve(process.cwd(), siteConfig.routes.publicFolder);
app.use(express.static(publicFolder));
logger.info('serving static files from custom path:', publicFolder);
} else {
var publicPath = Path.resolve(__dirname, 'public');
app.use(express.static(publicPath));
logger.info('serving static files from default path:', publicPath);
};
// 'body parser' for parsing application/json
app.use(bodyParser.json());
// 'body parser' for parsing application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: true }));
// add custom middleware (note: build out to accept dynamically use what is in server/middleware/
app.use(requestLogger);
// configure passport
var speechPassport = __webpack_require__(7);
// initialize passport
var sessionKey = siteConfig.auth.sessionKey;
app.use(cookieSession({
name: 'session',
keys: [sessionKey],
maxAge: 24 * 60 * 60 * 1000 // i.e. 24 hours
}));
app.use(speechPassport.initialize());
app.use(speechPassport.session());
// configure handlebars & register it with express app
var hbs = expressHandlebars.create({
defaultLayout: 'embed',
handlebars: Handlebars
});
app.engine('handlebars', hbs.engine);
app.set('view engine', 'handlebars');
// set the routes on the app
__webpack_require__(57)(app);
__webpack_require__(62)(app);
__webpack_require__(81)(app);
__webpack_require__(85)(app);
__webpack_require__(90)(app);
_this.app = app;
};
this.initialize = function () {
_this.createApp();
_this.server = http.Server(_this.app);
};
this.start = function () {
var db = __webpack_require__(2);
var PORT = siteConfig.details.port;
// sync sequelize
db.sequelize.sync()
// start the server
.then(function () {
_this.server.listen(PORT, function () {
logger.info('Server is listening on PORT ' + PORT);
});
}).catch(function (error) {
logger.error('Startup Error:', error);
});
};
};
module.exports = Server;
/***/ }),
/* 31 */
/***/ (function(module, exports) {
module.exports = require("express");
/***/ }),
/* 32 */
/***/ (function(module, exports) {
module.exports = require("body-parser");
/***/ }),
/* 33 */
/***/ (function(module, exports) {
module.exports = require("express-handlebars");
/***/ }),
/* 34 */
/***/ (function(module, exports) {
module.exports = require("handlebars");
/***/ }),
/* 35 */
/***/ (function(module, exports) {
module.exports = require("helmet");
/***/ }),
/* 36 */
/***/ (function(module, exports) {
module.exports = require("cookie-session");
/***/ }),
/* 37 */
/***/ (function(module, exports) {
module.exports = require("http");
/***/ }),
/* 38 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var logger = __webpack_require__(0);
var requestLogger = function requestLogger(req, res, next) {
// custom logging middleware to log all incoming http requests
logger.verbose('Request on ' + req.originalUrl + ' from ' + req.ip);
next();
};
module.exports = requestLogger;
/***/ }),
/* 39 */
/***/ (function(module, exports) {
module.exports = require("path");
/***/ }),
/* 40 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var logger = __webpack_require__(0);
function LoggerConfig() {
var _this = this;
this.logLevel = 'debug';
this.update = function (config) {
if (!config) {
return logger.warn('No logger config received.');
}
logger.info('configuring winston logger...');
// update values with local config params
var logLevel = config.logLevel;
_this.logLevel = logLevel;
// configure the winston logger
logger.configure({
transports: [new logger.transports.Console({
level: _this.logLevel,
timestamp: false,
colorize: true,
prettyPrint: true,
handleExceptions: true,
humanReadableUnhandledException: true
})]
});
// test all the log levels
logger.info('testing winston log levels...');
logger.error('Level 0');
logger.warn('Level 1');
logger.info('Level 2');
logger.verbose('Level 3');
logger.debug('Level 4');
logger.silly('Level 5');
};
};
module.exports = new LoggerConfig();
/***/ }),
/* 41 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var winstonSlackWebHook = __webpack_require__(42).SlackWebHook;
var winston = __webpack_require__(0);
function SlackConfig() {
var _this = this;
this.slackWebHook = 'default';
this.slackErrorChannel = 'default';
this.slackInfoChannel = 'default';
this.update = function (config) {
if (!config) {
return winston.warn('No slack config received');
}
// update variables
winston.info('configuring slack logger...');
var slackWebHook = config.slackWebHook,
slackErrorChannel = config.slackErrorChannel,
slackInfoChannel = config.slackInfoChannel;
_this.slackWebHook = slackWebHook;
_this.slackErrorChannel = slackErrorChannel;
_this.slackInfoChannel = slackInfoChannel;
// update slack webhook settings
if (_this.slackWebHook) {
// add a transport for errors to slack
if (_this.slackErrorChannel) {
winston.add(winstonSlackWebHook, {
name: 'slack-errors-transport',
level: 'warn',
webhookUrl: _this.slackWebHook,
channel: _this.slackErrorChannel,
username: 'spee.ch',
iconEmoji: ':face_with_head_bandage:'
});
};
if (slackInfoChannel) {
winston.add(winstonSlackWebHook, {
name: 'slack-info-transport',
level: 'info',
webhookUrl: _this.slackWebHook,
channel: _this.slackInfoChannel,
username: 'spee.ch',
iconEmoji: ':nerd_face:'
});
};
// send test messages
winston.info('testing slack logger...');
winston.error('Slack "error" logging is online.');
winston.info('Slack "info" logging is online.');
} else {
winston.warn('Slack logging is not enabled because no slackWebHook config var provided.');
}
};
};
module.exports = new SlackConfig();
/***/ }),
/* 42 */
/***/ (function(module, exports) {
module.exports = require("winston-slack-webhook");
/***/ }),
/* 43 */
/***/ (function(module, exports) {
module.exports = require("passport");
/***/ }),
/* 44 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var PassportLocalStrategy = __webpack_require__(11).Strategy;
var logger = __webpack_require__(0);
var db = __webpack_require__(2);
var returnUserAndChannelInfo = function returnUserAndChannelInfo(userInstance) {
return new Promise(function (resolve, reject) {
var userInfo = {};
userInfo['id'] = userInstance.id;
userInfo['userName'] = userInstance.userName;
userInstance.getChannel().then(function (_ref) {
var channelName = _ref.channelName,
channelClaimId = _ref.channelClaimId;
userInfo['channelName'] = channelName;
userInfo['channelClaimId'] = channelClaimId;
return db.Certificate.getShortChannelIdFromLongChannelId(channelClaimId, channelName);
}).then(function (shortChannelId) {
userInfo['shortChannelId'] = shortChannelId;
resolve(userInfo);
}).catch(function (error) {
reject(error);
});
});
};
module.exports = new PassportLocalStrategy({
usernameField: 'username',
passwordField: 'password'
}, function (username, password, done) {
return db.User.findOne({
where: { userName: username }
}).then(function (user) {
if (!user) {
logger.debug('no user found');
return done(null, false, { message: 'Incorrect username or password' });
}
return user.comparePassword(password).then(function (isMatch) {
if (!isMatch) {
logger.debug('incorrect password');
return done(null, false, { message: 'Incorrect username or password' });
}
logger.debug('Password was a match, returning User');
return returnUserAndChannelInfo(user).then(function (userInfo) {
return done(null, userInfo);
}).catch(function (error) {
return error;
});
}).catch(function (error) {
return error;
});
}).catch(function (error) {
return done(error);
});
});
/***/ }),
/* 45 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var logger = __webpack_require__(0);
var _require = __webpack_require__(12),
returnShortId = _require.returnShortId;
module.exports = function (sequelize, _ref) {
var STRING = _ref.STRING,
BOOLEAN = _ref.BOOLEAN,
INTEGER = _ref.INTEGER,
TEXT = _ref.TEXT,
DECIMAL = _ref.DECIMAL;
var Certificate = sequelize.define('Certificate', {
address: {
type: STRING,
default: null
},
amount: {
type: DECIMAL(19, 8),
default: null
},
claimId: {
type: STRING,
default: null
},
claimSequence: {
type: INTEGER,
default: null
},
decodedClaim: {
type: BOOLEAN,
default: null
},
depth: {
type: INTEGER,
default: null
},
effectiveAmount: {
type: DECIMAL(19, 8),
default: null
},
hasSignature: {
type: BOOLEAN,
default: null
},
height: {
type: INTEGER,
default: null
},
hex: {
type: TEXT('long'),
default: null
},
name: {
type: STRING,
default: null
},
nout: {
type: INTEGER,
default: null
},
txid: {
type: STRING,
default: null
},
validAtHeight: {
type: INTEGER,
default: null
},
outpoint: {
type: STRING,
default: null
},
valueVersion: {
type: STRING,
default: null
},
claimType: {
type: STRING,
default: null
},
certificateVersion: {
type: STRING,
default: null
},
keyType: {
type: STRING,
default: null
},
publicKey: {
type: TEXT('long'),
default: null
}
}, {
freezeTableName: true
});
Certificate.associate = function (db) {
Certificate.belongsTo(db.Channel, {
foreignKey: {
allowNull: true
}
});
};
Certificate.getShortChannelIdFromLongChannelId = function (longChannelId, channelName) {
var _this = this;
logger.debug('getShortChannelIdFromLongChannelId ' + channelName + ':' + longChannelId);
return new Promise(function (resolve, reject) {
_this.findAll({
where: { name: channelName },
order: [['height', 'ASC']]
}).then(function (result) {
switch (result.length) {
case 0:
throw new Error('No channel(s) found with that channel name');
default:
return resolve(returnShortId(result, longChannelId));
}
}).catch(function (error) {
reject(error);
});
});
};
Certificate.getLongChannelIdFromShortChannelId = function (channelName, channelClaimId) {
var _this2 = this;
logger.debug('getLongChannelIdFromShortChannelId(' + channelName + ', ' + channelClaimId + ')');
return new Promise(function (resolve, reject) {
_this2.findAll({
where: {
name: channelName,
claimId: {
$like: channelClaimId + '%'
}
},
order: [['height', 'ASC']]
}).then(function (result) {
switch (result.length) {
case 0:
return resolve(null);
default:
// note results must be sorted
return resolve(result[0].claimId);
}
}).catch(function (error) {
reject(error);
});
});
};
Certificate.getLongChannelIdFromChannelName = function (channelName) {
var _this3 = this;
logger.debug('getLongChannelIdFromChannelName(' + channelName + ')');
return new Promise(function (resolve, reject) {
_this3.findAll({
where: { name: channelName },
order: [['effectiveAmount', 'DESC'], ['height', 'ASC']]
}).then(function (result) {
switch (result.length) {
case 0:
return resolve(null);
default:
return resolve(result[0].claimId);
}
}).catch(function (error) {
reject(error);
});
});
};
Certificate.validateLongChannelId = function (name, claimId) {
var _this4 = this;
logger.debug('validateLongChannelId(' + name + ', ' + claimId + ')');
return new Promise(function (resolve, reject) {
_this4.findOne({
where: { name: name, claimId: claimId }
}).then(function (result) {
if (!result) {
return resolve(null);
};
resolve(claimId);
}).catch(function (error) {
reject(error);
});
});
};
Certificate.getLongChannelId = function (channelName, channelClaimId) {
logger.debug('getLongChannelId(' + channelName + ', ' + channelClaimId + ')');
if (channelClaimId && channelClaimId.length === 40) {
// if a full channel id is provided
return this.validateLongChannelId(channelName, channelClaimId);
} else if (channelClaimId && channelClaimId.length < 40) {
// if a short channel id is provided
return this.getLongChannelIdFromShortChannelId(channelName, channelClaimId);
} else {
return this.getLongChannelIdFromChannelName(channelName); // if no channel id provided
}
};
return Certificate;
};
/***/ }),
/* 46 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
module.exports = function (sequelize, _ref) {
var STRING = _ref.STRING;
var Channel = sequelize.define('Channel', {
channelName: {
type: STRING,
allowNull: false
},
channelClaimId: {
type: STRING,
allowNull: false
}
}, {
freezeTableName: true
});
Channel.associate = function (db) {
Channel.belongsTo(db.User);
Channel.hasOne(db.Certificate);
};
return Channel;
};
/***/ }),
/* 47 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var logger = __webpack_require__(0);
var _require = __webpack_require__(12),
returnShortId = _require.returnShortId;
var _require2 = __webpack_require__(3),
defaultThumbnail = _require2.assetDefaults.thumbnail,
host = _require2.details.host;
function determineFileExtensionFromContentType(contentType) {
switch (contentType) {
case 'image/jpeg':
case 'image/jpg':
return 'jpeg';
case 'image/png':
return 'png';
case 'image/gif':
return 'gif';
case 'video/mp4':
return 'mp4';
default:
logger.debug('setting unknown file type as file extension jpeg');
return 'jpeg';
}
};
function determineThumbnail(storedThumbnail, defaultThumbnail) {
if (storedThumbnail === '') {
return defaultThumbnail;
}
return storedThumbnail;
};
function prepareClaimData(claim) {
// logger.debug('preparing claim data based on resolved data:', claim);
claim['thumbnail'] = determineThumbnail(claim.thumbnail, defaultThumbnail);
claim['fileExt'] = determineFileExtensionFromContentType(claim.contentType);
claim['host'] = host;
return claim;
};
module.exports = function (sequelize, _ref) {
var STRING = _ref.STRING,
BOOLEAN = _ref.BOOLEAN,
INTEGER = _ref.INTEGER,
TEXT = _ref.TEXT,
DECIMAL = _ref.DECIMAL;
var Claim = sequelize.define('Claim', {
address: {
type: STRING,
default: null
},
amount: {
type: DECIMAL(19, 8),
default: null
},
claimId: {
type: STRING,
default: null
},
claimSequence: {
type: INTEGER,
default: null
},
decodedClaim: {
type: BOOLEAN,
default: null
},
depth: {
type: INTEGER,
default: null
},
effectiveAmount: {
type: DECIMAL(19, 8),
default: null
},
hasSignature: {
type: BOOLEAN,
default: null
},
height: {
type: INTEGER,
default: null
},
hex: {
type: TEXT('long'),
default: null
},
name: {
type: STRING,
default: null
},
nout: {
type: INTEGER,
default: null
},
txid: {
type: STRING,
default: null
},
validAtHeight: {
type: INTEGER,
default: null
},
outpoint: {
type: STRING,
default: null
},
claimType: {
type: STRING,
default: null
},
certificateId: {
type: STRING,
default: null
},
author: {
type: STRING,
default: null
},
description: {
type: TEXT('long'),
default: null
},
language: {
type: STRING,
default: null
},
license: {
type: STRING,
default: null
},
licenseUrl: {
type: STRING,
default: null
},
nsfw: {
type: BOOLEAN,
default: null
},
preview: {
type: STRING,
default: null
},
thumbnail: {
type: STRING,
default: null
},
title: {
type: STRING,
default: null
},
metadataVersion: {
type: STRING,
default: null
},
contentType: {
type: STRING,
default: null
},
source: {
type: STRING,
default: null
},
sourceType: {
type: STRING,
default: null
},
sourceVersion: {
type: STRING,
default: null
},
streamVersion: {
type: STRING,
default: null
},
valueVersion: {
type: STRING,
default: null
},
channelName: {
type: STRING,
allowNull: true,
default: null
}
}, {
freezeTableName: true
});
Claim.associate = function (db) {
Claim.belongsTo(db.File, {
foreignKey: {
allowNull: true
}
});
};
Claim.getShortClaimIdFromLongClaimId = function (claimId, claimName) {
var _this = this;
logger.debug('Claim.getShortClaimIdFromLongClaimId for ' + claimName + '#' + claimId);
return new Promise(function (resolve, reject) {
_this.findAll({
where: { name: claimName },
order: [['height', 'ASC']]
}).then(function (result) {
switch (result.length) {
case 0:
throw new Error('No claim(s) found with that claim name');
default:
resolve(returnShortId(result, claimId));
}
}).catch(function (error) {
reject(error);
});
});
};
Claim.getAllChannelClaims = function (channelClaimId) {
var _this2 = this;
logger.debug('Claim.getAllChannelClaims for ' + channelClaimId);
return new Promise(function (resolve, reject) {
_this2.findAll({
where: { certificateId: channelClaimId },
order: [['height', 'ASC']],
raw: true // returns an array of only data, not an array of instances
}).then(function (channelClaimsArray) {
// logger.debug('channelclaimsarray length:', channelClaimsArray.length);
switch (channelClaimsArray.length) {
case 0:
return resolve(null);
default:
channelClaimsArray.forEach(function (claim) {
claim['fileExt'] = determineFileExtensionFromContentType(claim.contentType);
claim['thumbnail'] = determineThumbnail(claim.thumbnail, defaultThumbnail);
return claim;
});
return resolve(channelClaimsArray);
}
}).catch(function (error) {
reject(error);
});
});
};
Claim.getClaimIdByLongChannelId = function (channelClaimId, claimName) {
var _this3 = this;
logger.debug('finding claim id for claim ' + claimName + ' from channel ' + channelClaimId);
return new Promise(function (resolve, reject) {
_this3.findAll({
where: { name: claimName, certificateId: channelClaimId },
order: [['id', 'ASC']]
}).then(function (result) {
switch (result.length) {
case 0:
return resolve(null);
case 1:
return resolve(result[0].claimId);
default:
logger.error(result.length + ' records found for "' + claimName + '" in channel "' + channelClaimId + '"');
return resolve(result[0].claimId);
}
}).catch(function (error) {
reject(error);
});
});
};
Claim.getLongClaimIdFromShortClaimId = function (name, shortId) {
var _this4 = this;
return new Promise(function (resolve, reject) {
_this4.findAll({
where: {
name: name,
claimId: {
$like: shortId + '%'
} },
order: [['height', 'ASC']]
}).then(function (result) {
switch (result.length) {
case 0:
return resolve(null);
default:
// note results must be sorted
return resolve(result[0].claimId);
}
}).catch(function (error) {
reject(error);
});
});
};
Claim.getTopFreeClaimIdByClaimName = function (name) {
var _this5 = this;
return new Promise(function (resolve, reject) {
_this5.findAll({
where: { name: name },
order: [['effectiveAmount', 'DESC'], ['height', 'ASC']] // note: maybe height and effective amount need to switch?
}).then(function (result) {
logger.debug('length of result', result.length);
switch (result.length) {
case 0:
return resolve(null);
default:
return resolve(result[0].dataValues.claimId);
}
}).catch(function (error) {
reject(error);
});
});
};
Claim.validateLongClaimId = function (name, claimId) {
var _this6 = this;
return new Promise(function (resolve, reject) {
_this6.findOne({
where: { name: name, claimId: claimId }
}).then(function (result) {
if (!result) {
return resolve(null);
};
resolve(claimId);
}).catch(function (error) {
reject(error);
});
});
};
Claim.getLongClaimId = function (claimName, claimId) {
logger.debug('getLongClaimId(' + claimName + ', ' + claimId + ')');
if (claimId && claimId.length === 40) {
// if a full claim id is provided
return this.validateLongClaimId(claimName, claimId);
} else if (claimId && claimId.length < 40) {
return this.getLongClaimIdFromShortClaimId(claimName, claimId); // if a short claim id is provided
} else {
return this.getTopFreeClaimIdByClaimName(claimName); // if no claim id is provided
}
};
Claim.resolveClaim = function (name, claimId) {
var _this7 = this;
logger.debug('Claim.resolveClaim: ' + name + ' ' + claimId);
return new Promise(function (resolve, reject) {
_this7.findAll({
where: { name: name, claimId: claimId }
}).then(function (claimArray) {
switch (claimArray.length) {
case 0:
return resolve(null);
case 1:
return resolve(prepareClaimData(claimArray[0].dataValues));
default:
logger.error('more than one record matches ' + name + '#' + claimId + ' in db.Claim');
return resolve(prepareClaimData(claimArray[0].dataValues));
}
}).catch(function (error) {
reject(error);
});
});
};
return Claim;
};
/***/ }),
/* 48 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
module.exports = function (sequelize, _ref) {
var STRING = _ref.STRING,
BOOLEAN = _ref.BOOLEAN,
INTEGER = _ref.INTEGER;
var File = sequelize.define('File', {
name: {
type: STRING,
allowNull: false
},
claimId: {
type: STRING,
allowNull: false
},
address: {
type: STRING,
allowNull: false
},
outpoint: {
type: STRING,
allowNull: false
},
height: {
type: INTEGER,
allowNull: false,
default: 0
},
fileName: {
type: STRING,
allowNull: false
},
filePath: {
type: STRING,
allowNull: false
},
fileType: {
type: STRING
},
nsfw: {
type: BOOLEAN,
allowNull: false,
defaultValue: false
},
trendingEligible: {
type: BOOLEAN,
allowNull: false,
defaultValue: true
}
}, {
freezeTableName: true
});
File.associate = function (db) {
File.hasMany(db.Request);
File.hasOne(db.Claim);
};
File.getRecentClaims = function () {
return this.findAll({
where: { nsfw: false, trendingEligible: true },
order: [['createdAt', 'DESC']],
limit: 25
});
};
return File;
};
/***/ }),
/* 49 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
module.exports = function (sequelize, _ref) {
var STRING = _ref.STRING,
BOOLEAN = _ref.BOOLEAN,
TEXT = _ref.TEXT;
var Request = sequelize.define('Request', {
action: {
type: STRING,
allowNull: false
},
url: {
type: STRING,
allowNull: false
},
ipAddress: {
type: STRING,
allowNull: true
},
result: {
type: TEXT('long'),
allowNull: true,
default: null
}
}, {
freezeTableName: true
});
Request.associate = function (db) {
Request.belongsTo(db.File, {
foreignKey: {
allowNull: true
}
});
};
return Request;
};
/***/ }),
/* 50 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var bcrypt = __webpack_require__(51);
var logger = __webpack_require__(0);
module.exports = function (sequelize, _ref) {
var STRING = _ref.STRING;
var User = sequelize.define('User', {
userName: {
type: STRING,
allowNull: false
},
password: {
type: STRING,
allowNull: false
}
}, {
freezeTableName: true
});
User.associate = function (db) {
User.hasOne(db.Channel);
};
User.prototype.comparePassword = function (password) {
return bcrypt.compare(password, this.password);
};
User.prototype.changePassword = function (newPassword) {
var _this = this;
return new Promise(function (resolve, reject) {
// generate a salt string to use for hashing
bcrypt.genSalt(function (saltError, salt) {
if (saltError) {
logger.error('salt error', saltError);
reject(saltError);
return;
}
// generate a hashed version of the user's password
bcrypt.hash(newPassword, salt, function (hashError, hash) {
// if there is an error with the hash generation return the error
if (hashError) {
logger.error('hash error', hashError);
reject(hashError);
return;
}
// replace the current password with the new hash
_this.update({ password: hash }).then(function () {
resolve();
}).catch(function (error) {
reject(error);
});
});
});
});
};
// pre-save hook method to hash the user's password before the user's info is saved to the db.
User.hook('beforeCreate', function (user, options) {
logger.debug('User.beforeCreate hook...');
return new Promise(function (resolve, reject) {
// generate a salt string to use for hashing
bcrypt.genSalt(function (saltError, salt) {
if (saltError) {
logger.error('salt error', saltError);
reject(saltError);
return;
}
// generate a hashed version of the user's password
bcrypt.hash(user.password, salt, function (hashError, hash) {
// if there is an error with the hash generation return the error
if (hashError) {
logger.error('hash error', hashError);
reject(hashError);
return;
}
// replace the password string with the hash password value
user.password = hash;
resolve();
});
});
});
});
return User;
};
/***/ }),
/* 51 */
/***/ (function(module, exports) {
module.exports = require("bcrypt");
/***/ }),
/* 52 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
var PassportLocalStrategy = __webpack_require__(11).Strategy;
var lbryApi = __webpack_require__(5);
var logger = __webpack_require__(0);
var db = __webpack_require__(2);
module.exports = new PassportLocalStrategy({
usernameField: 'username',
passwordField: 'password'
}, function (username, password, done) {
logger.verbose('new channel signup request. user: ' + username + ' pass: ' + password + ' .');
var userInfo = {};
// server-side validaton of inputs (username, password)
// create the channel and retrieve the metadata
return lbryApi.createChannel('@' + username).then(function (tx) {
// create user record
var userData = {
userName: username,
password: password
};
logger.verbose('userData >', userData);
// create user record
var channelData = {
channelName: '@' + username,
channelClaimId: tx.claim_id
};
logger.verbose('channelData >', channelData);
// create certificate record
var certificateData = {
claimId: tx.claim_id,
name: '@' + username
// address,
};
logger.verbose('certificateData >', certificateData);
// save user and certificate to db
return Promise.all([db.User.create(userData), db.Channel.create(channelData), db.Certificate.create(certificateData)]);
}).then(function (_ref) {
var _ref2 = _slicedToArray(_ref, 3),
newUser = _ref2[0],
newChannel = _ref2[1],
newCertificate = _ref2[2];
logger.verbose('user and certificate successfully created');
// store the relevant newUser info to be passed back for req.User
userInfo['id'] = newUser.id;
userInfo['userName'] = newUser.userName;
userInfo['channelName'] = newChannel.channelName;
userInfo['channelClaimId'] = newChannel.channelClaimId;
// associate the instances
return Promise.all([newCertificate.setChannel(newChannel), newChannel.setUser(newUser)]);
}).then(function () {
logger.verbose('user and certificate successfully associated');
return db.Certificate.getShortChannelIdFromLongChannelId(userInfo.channelClaimId, userInfo.channelName);
}).then(function (shortChannelId) {
userInfo['shortChannelId'] = shortChannelId;
return done(null, userInfo);
}).catch(function (error) {
logger.error('signup error', error);
return done(error);
});
});
/***/ }),
/* 53 */
/***/ (function(module, exports) {
module.exports = require("axios");
/***/ }),
/* 54 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var lbryConfig = {
api: {
apiHost: 'localhost',
apiPort: '5279'
}
};
module.exports = lbryConfig;
/***/ }),
/* 55 */
/***/ (function(module, exports) {
module.exports = require("universal-analytics");
/***/ }),
/* 56 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
module.exports = {
serializeSpeechUser: function serializeSpeechUser(user, done) {
// returns user data to be serialized into session
console.log('serializing user');
done(null, user);
},
deserializeSpeechUser: function deserializeSpeechUser(user, done) {
// deserializes session and populates additional info to req.user
console.log('deserializing user');
done(null, user);
}
};
/***/ }),
/* 57 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var speechPassport = __webpack_require__(7);
var handleSignupRequest = __webpack_require__(58);
var handleLoginRequest = __webpack_require__(59);
var handleLogoutRequest = __webpack_require__(60);
var handleUserRequest = __webpack_require__(61);
module.exports = function (app) {
app.post('/signup', speechPassport.authenticate('local-signup'), handleSignupRequest);
app.post('/login', handleLoginRequest);
app.get('/logout', handleLogoutRequest);
app.get('/user', handleUserRequest);
};
/***/ }),
/* 58 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var signup = function signup(req, res) {
res.status(200).json({
success: true,
channelName: req.user.channelName,
channelClaimId: req.user.channelClaimId,
shortChannelId: req.user.shortChannelId
});
};
module.exports = signup;
/***/ }),
/* 59 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var speechPassport = __webpack_require__(7);
var login = function login(req, res, next) {
speechPassport.authenticate('local-login', function (err, user, info) {
if (err) {
return next(err);
}
if (!user) {
return res.status(400).json({
success: false,
message: info.message
});
}
req.logIn(user, function (err) {
if (err) {
return next(err);
}
return res.status(200).json({
success: true,
channelName: req.user.channelName,
channelClaimId: req.user.channelClaimId,
shortChannelId: req.user.shortChannelId
});
});
})(req, res, next);
};
module.exports = login;
/***/ }),
/* 60 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var logout = function logout(req, res) {
req.logout();
res.status(200).json({ success: true, message: 'you successfully logged out' });
};
module.exports = logout;
/***/ }),
/* 61 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var user = function user(req, res) {
if (req.user) {
res.status(200).json({ success: true, data: req.user });
} else {
res.status(401).json({ success: false, message: 'user is not logged in' });
}
};
module.exports = user;
/***/ }),
/* 62 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var channelAvailability = __webpack_require__(63);
var channelClaims = __webpack_require__(65);
var channelData = __webpack_require__(67);
var channelShortId = __webpack_require__(68);
var claimAvailability = __webpack_require__(69);
var claimData = __webpack_require__(70);
var claimGet = __webpack_require__(71);
var claimLongId = __webpack_require__(72);
var claimPublish = __webpack_require__(73);
var claimResolve = __webpack_require__(75);
var claimShortId = __webpack_require__(76);
var claimList = __webpack_require__(77);
var fileAvailability = __webpack_require__(78);
var multipartMiddleware = __webpack_require__(79);
module.exports = function (app) {
// channel routes
app.get('/api/channel/availability/:name', channelAvailability);
app.get('/api/channel/short-id/:longId/:name', channelShortId);
app.get('/api/channel/data/:channelName/:channelClaimId', channelData);
app.get('/api/channel/claims/:channelName/:channelClaimId/:page', channelClaims);
// claim routes
app.get('/api/claim/list/:name', claimList);
app.get('/api/claim/get/:name/:claimId', claimGet);
app.get('/api/claim/availability/:name', claimAvailability);
app.get('/api/claim/resolve/:name/:claimId', claimResolve);
app.post('/api/claim/publish', multipartMiddleware, claimPublish);
app.get('/api/claim/short-id/:longId/:name', claimShortId);
app.post('/api/claim/long-id', claimLongId);
app.get('/api/claim/data/:claimName/:claimId', claimData);
// file routes
app.get('/api/file/availability/:name/:claimId', fileAvailability);
};
/***/ }),
/* 63 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _require = __webpack_require__(8),
checkChannelAvailability = _require.checkChannelAvailability;
var _require2 = __webpack_require__(4),
sendGATimingEvent = _require2.sendGATimingEvent;
var _require3 = __webpack_require__(1),
handleErrorResponse = _require3.handleErrorResponse;
/*
route to check whether site has published to a channel
*/
var channelAvailability = function channelAvailability(_ref, res) {
var ip = _ref.ip,
originalUrl = _ref.originalUrl,
name = _ref.params.name;
var gaStartTime = Date.now();
checkChannelAvailability(name).then(function (availableName) {
res.status(200).json(availableName);
sendGATimingEvent('end-to-end', 'claim name availability', name, gaStartTime, Date.now());
}).catch(function (error) {
handleErrorResponse(originalUrl, ip, error, res);
});
};
module.exports = channelAvailability;
/***/ }),
/* 64 */
/***/ (function(module, exports) {
module.exports = require("fs");
/***/ }),
/* 65 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _require = __webpack_require__(6),
getChannelClaims = _require.getChannelClaims;
var _require2 = __webpack_require__(1),
handleErrorResponse = _require2.handleErrorResponse;
var NO_CHANNEL = 'NO_CHANNEL';
/*
route to get all claims for channel
*/
var channelClaims = function channelClaims(_ref, res) {
var ip = _ref.ip,
originalUrl = _ref.originalUrl,
body = _ref.body,
params = _ref.params;
var channelName = params.channelName;
var channelClaimId = params.channelClaimId;
if (channelClaimId === 'none') channelClaimId = null;
var page = params.page;
getChannelClaims(channelName, channelClaimId, page).then(function (data) {
if (data === NO_CHANNEL) {
return res.status(404).json({ success: false, message: 'No matching channel was found' });
}
res.status(200).json({ success: true, data: data });
}).catch(function (error) {
handleErrorResponse(originalUrl, ip, error, res);
});
};
module.exports = channelClaims;
/***/ }),
/* 66 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var CLAIMS_PER_PAGE = 12;
module.exports = {
returnPaginatedChannelClaims: function returnPaginatedChannelClaims(channelName, longChannelClaimId, claims, page) {
var totalPages = module.exports.determineTotalPages(claims);
var paginationPage = module.exports.getPageFromQuery(page);
var viewData = {
channelName: channelName,
longChannelClaimId: longChannelClaimId,
claims: module.exports.extractPageFromClaims(claims, paginationPage),
previousPage: module.exports.determinePreviousPage(paginationPage),
currentPage: paginationPage,
nextPage: module.exports.determineNextPage(totalPages, paginationPage),
totalPages: totalPages,
totalResults: module.exports.determineTotalClaims(claims)
};
return viewData;
},
getPageFromQuery: function getPageFromQuery(page) {
if (page) {
return parseInt(page);
}
return 1;
},
extractPageFromClaims: function extractPageFromClaims(claims, pageNumber) {
if (!claims) {
return []; // if no claims, return this default
}
// logger.debug('claims is array?', Array.isArray(claims));
// logger.debug(`pageNumber ${pageNumber} is number?`, Number.isInteger(pageNumber));
var claimStartIndex = (pageNumber - 1) * CLAIMS_PER_PAGE;
var claimEndIndex = claimStartIndex + CLAIMS_PER_PAGE;
var pageOfClaims = claims.slice(claimStartIndex, claimEndIndex);
return pageOfClaims;
},
determineTotalPages: function determineTotalPages(claims) {
if (!claims) {
return 0;
} else {
var totalClaims = claims.length;
if (totalClaims < CLAIMS_PER_PAGE) {
return 1;
}
var fullPages = Math.floor(totalClaims / CLAIMS_PER_PAGE);
var remainder = totalClaims % CLAIMS_PER_PAGE;
if (remainder === 0) {
return fullPages;
}
return fullPages + 1;
}
},
determinePreviousPage: function determinePreviousPage(currentPage) {
if (currentPage === 1) {
return null;
}
return currentPage - 1;
},
determineNextPage: function determineNextPage(totalPages, currentPage) {
if (currentPage === totalPages) {
return null;
}
return currentPage + 1;
},
determineTotalClaims: function determineTotalClaims(claims) {
if (!claims) {
return 0;
}
return claims.length;
}
};
/***/ }),
/* 67 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _require = __webpack_require__(6),
getChannelData = _require.getChannelData;
var _require2 = __webpack_require__(1),
handleErrorResponse = _require2.handleErrorResponse;
var NO_CHANNEL = 'NO_CHANNEL';
/*
route to get data for a channel
*/
var channelData = function channelData(_ref, res) {
var ip = _ref.ip,
originalUrl = _ref.originalUrl,
body = _ref.body,
params = _ref.params;
var channelName = params.channelName;
var channelClaimId = params.channelClaimId;
if (channelClaimId === 'none') channelClaimId = null;
getChannelData(channelName, channelClaimId, 0).then(function (data) {
if (data === NO_CHANNEL) {
return res.status(404).json({ success: false, message: 'No matching channel was found' });
}
res.status(200).json({ success: true, data: data });
}).catch(function (error) {
handleErrorResponse(originalUrl, ip, error, res);
});
};
module.exports = channelData;
/***/ }),
/* 68 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _require = __webpack_require__(1),
handleErrorResponse = _require.handleErrorResponse;
var db = __webpack_require__(2);
/*
route to get a short channel id from long channel Id
*/
var channelShortIdRoute = function channelShortIdRoute(_ref, res) {
var ip = _ref.ip,
originalUrl = _ref.originalUrl,
params = _ref.params;
db.Certificate.getShortChannelIdFromLongChannelId(params.longId, params.name).then(function (shortId) {
res.status(200).json(shortId);
}).catch(function (error) {
handleErrorResponse(originalUrl, ip, error, res);
});
};
module.exports = channelShortIdRoute;
/***/ }),
/* 69 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _require = __webpack_require__(8),
claimNameIsAvailable = _require.claimNameIsAvailable;
var _require2 = __webpack_require__(4),
sendGATimingEvent = _require2.sendGATimingEvent;
var _require3 = __webpack_require__(1),
handleErrorResponse = _require3.handleErrorResponse;
/*
route to check whether this site published to a claim
*/
var claimAvailability = function claimAvailability(_ref, res) {
var ip = _ref.ip,
originalUrl = _ref.originalUrl,
name = _ref.params.name;
var gaStartTime = Date.now();
claimNameIsAvailable(name).then(function (result) {
res.status(200).json(result);
sendGATimingEvent('end-to-end', 'claim name availability', name, gaStartTime, Date.now());
}).catch(function (error) {
handleErrorResponse(originalUrl, ip, error, res);
});
};
module.exports = claimAvailability;
/***/ }),
/* 70 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _require = __webpack_require__(1),
handleErrorResponse = _require.handleErrorResponse;
var db = __webpack_require__(2);
/*
route to return data for a claim
*/
var claimData = function claimData(_ref, res) {
var ip = _ref.ip,
originalUrl = _ref.originalUrl,
body = _ref.body,
params = _ref.params;
var claimName = params.claimName;
var claimId = params.claimId;
if (claimId === 'none') claimId = null;
db.Claim.resolveClaim(claimName, claimId).then(function (claimInfo) {
if (!claimInfo) {
return res.status(404).json({ success: false, message: 'No claim could be found' });
}
res.status(200).json({ success: true, data: claimInfo });
}).catch(function (error) {
handleErrorResponse(originalUrl, ip, error, res);
});
};
module.exports = claimData;
/***/ }),
/* 71 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
var _require = __webpack_require__(5),
getClaim = _require.getClaim;
var _require2 = __webpack_require__(9),
addGetResultsToFileData = _require2.addGetResultsToFileData,
createFileData = _require2.createFileData;
var _require3 = __webpack_require__(1),
handleErrorResponse = _require3.handleErrorResponse;
var db = __webpack_require__(2);
/*
route to get a claim
*/
var claimGet = function claimGet(_ref, res) {
var ip = _ref.ip,
originalUrl = _ref.originalUrl,
params = _ref.params;
var name = params.name;
var claimId = params.claimId;
// resolve the claim
db.Claim.resolveClaim(name, claimId).then(function (resolveResult) {
// make sure a claim actually exists at that uri
if (!resolveResult) {
throw new Error('No matching uri found in Claim table');
}
var fileData = createFileData(resolveResult);
// get the claim
return Promise.all([fileData, getClaim(name + '#' + claimId)]);
}).then(function (_ref2) {
var _ref3 = _slicedToArray(_ref2, 2),
fileData = _ref3[0],
getResult = _ref3[1];
fileData = addGetResultsToFileData(fileData, getResult);
return Promise.all([db.upsert(db.File, fileData, { name: name, claimId: claimId }, 'File'), getResult]);
}).then(function (_ref4) {
var _ref5 = _slicedToArray(_ref4, 2),
fileRecord = _ref5[0],
_ref5$ = _ref5[1],
message = _ref5$.message,
completed = _ref5$.completed;
res.status(200).json({ success: true, message: message, completed: completed });
}).catch(function (error) {
handleErrorResponse(originalUrl, ip, error, res);
});
};
module.exports = claimGet;
/***/ }),
/* 72 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _require = __webpack_require__(6),
getClaimId = _require.getClaimId;
var _require2 = __webpack_require__(1),
handleErrorResponse = _require2.handleErrorResponse;
var NO_CHANNEL = 'NO_CHANNEL';
var NO_CLAIM = 'NO_CLAIM';
/*
route to get a long claim id
*/
var claimLongId = function claimLongId(_ref, res) {
var ip = _ref.ip,
originalUrl = _ref.originalUrl,
body = _ref.body,
params = _ref.params;
var channelName = body.channelName;
var channelClaimId = body.channelClaimId;
var claimName = body.claimName;
var claimId = body.claimId;
getClaimId(channelName, channelClaimId, claimName, claimId).then(function (result) {
if (result === NO_CHANNEL) {
return res.status(404).json({ success: false, message: 'No matching channel could be found' });
}
if (result === NO_CLAIM) {
return res.status(404).json({ success: false, message: 'No matching claim id could be found' });
}
res.status(200).json({ success: true, data: result });
}).catch(function (error) {
handleErrorResponse(originalUrl, ip, error, res);
});
};
module.exports = claimLongId;
/***/ }),
/* 73 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
var _require = __webpack_require__(9),
createBasicPublishParams = _require.createBasicPublishParams,
createThumbnailPublishParams = _require.createThumbnailPublishParams,
parsePublishApiRequestBody = _require.parsePublishApiRequestBody,
parsePublishApiRequestFiles = _require.parsePublishApiRequestFiles;
var _require2 = __webpack_require__(8),
claimNameIsAvailable = _require2.claimNameIsAvailable,
publish = _require2.publish;
var _require3 = __webpack_require__(74),
authenticateUser = _require3.authenticateUser;
var _require4 = __webpack_require__(4),
sendGATimingEvent = _require4.sendGATimingEvent;
var _require5 = __webpack_require__(1),
handleErrorResponse = _require5.handleErrorResponse;
var _require6 = __webpack_require__(3),
host = _require6.details.host;
/*
route to publish a claim through the daemon
*/
var claimPublish = function claimPublish(_ref, res) {
var body = _ref.body,
files = _ref.files,
headers = _ref.headers,
ip = _ref.ip,
originalUrl = _ref.originalUrl,
user = _ref.user;
// define variables
var channelName = void 0,
channelId = void 0,
channelPassword = void 0,
description = void 0,
fileName = void 0,
filePath = void 0,
fileType = void 0,
gaStartTime = void 0,
license = void 0,
name = void 0,
nsfw = void 0,
thumbnail = void 0,
thumbnailFileName = void 0,
thumbnailFilePath = void 0,
thumbnailFileType = void 0,
title = void 0;
// record the start time of the request
gaStartTime = Date.now();
// validate the body and files of the request
try {
var _parsePublishApiReque = parsePublishApiRequestBody(body);
// validateApiPublishRequest(body, files);
name = _parsePublishApiReque.name;
nsfw = _parsePublishApiReque.nsfw;
license = _parsePublishApiReque.license;
title = _parsePublishApiReque.title;
description = _parsePublishApiReque.description;
thumbnail = _parsePublishApiReque.thumbnail;
var _parsePublishApiReque2 = parsePublishApiRequestFiles(files);
fileName = _parsePublishApiReque2.fileName;
filePath = _parsePublishApiReque2.filePath;
fileType = _parsePublishApiReque2.fileType;
thumbnailFileName = _parsePublishApiReque2.thumbnailFileName;
thumbnailFilePath = _parsePublishApiReque2.thumbnailFilePath;
thumbnailFileType = _parsePublishApiReque2.thumbnailFileType;
channelName = body.channelName;
channelId = body.channelId;
channelPassword = body.channelPassword;
} catch (error) {
return res.status(400).json({ success: false, message: error.message });
}
// check channel authorization
Promise.all([authenticateUser(channelName, channelId, channelPassword, user), claimNameIsAvailable(name), createBasicPublishParams(filePath, name, title, description, license, nsfw, thumbnail), createThumbnailPublishParams(thumbnailFilePath, name, license, nsfw)]).then(function (_ref2) {
var _ref3 = _slicedToArray(_ref2, 4),
_ref3$ = _ref3[0],
channelName = _ref3$.channelName,
channelClaimId = _ref3$.channelClaimId,
validatedClaimName = _ref3[1],
publishParams = _ref3[2],
thumbnailPublishParams = _ref3[3];
// add channel details to the publish params
if (channelName && channelClaimId) {
publishParams['channel_name'] = channelName;
publishParams['channel_id'] = channelClaimId;
}
// publish the thumbnail
if (thumbnailPublishParams) {
publish(thumbnailPublishParams, thumbnailFileName, thumbnailFileType);
}
// publish the asset
return publish(publishParams, fileName, fileType);
}).then(function (result) {
res.status(200).json({
success: true,
message: 'publish completed successfully',
data: {
name: name,
claimId: result.claim_id,
url: host + '/' + result.claim_id + '/' + name,
lbryTx: result
}
});
// record the publish end time and send to google analytics
sendGATimingEvent('end-to-end', 'publish', fileType, gaStartTime, Date.now());
}).catch(function (error) {
handleErrorResponse(originalUrl, ip, error, res);
});
};
module.exports = claimPublish;
/***/ }),
/* 74 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var db = __webpack_require__(2);
var logger = __webpack_require__(0);
module.exports = {
authenticateUser: function authenticateUser(channelName, channelId, channelPassword, user) {
// case: no channelName or channel Id are provided (anonymous), regardless of whether user token is provided
if (!channelName && !channelId) {
return {
channelName: null,
channelClaimId: null
};
}
// case: channelName or channel Id are provided with user token
if (user) {
if (channelName && channelName !== user.channelName) {
throw new Error('the provided channel name does not match user credentials');
}
if (channelId && channelId !== user.channelClaimId) {
throw new Error('the provided channel id does not match user credentials');
}
return {
channelName: user.channelName,
channelClaimId: user.channelClaimId
};
}
// case: channelName or channel Id are provided with password instead of user token
if (!channelPassword) throw new Error('no channel password provided');
return module.exports.authenticateChannelCredentials(channelName, channelId, channelPassword);
},
authenticateChannelCredentials: function authenticateChannelCredentials(channelName, channelId, userPassword) {
return new Promise(function (resolve, reject) {
// hoisted variables
var channelData = void 0;
// build the params for finding the channel
var channelFindParams = {};
if (channelName) channelFindParams['channelName'] = channelName;
if (channelId) channelFindParams['channelClaimId'] = channelId;
// find the channel
db.Channel.findOne({
where: channelFindParams
}).then(function (channel) {
if (!channel) {
logger.debug('no channel found');
throw new Error('Authentication failed, you do not have access to that channel');
}
channelData = channel.get();
logger.debug('channel data:', channelData);
return db.User.findOne({
where: { userName: channelData.channelName.substring(1) }
});
}).then(function (user) {
if (!user) {
logger.debug('no user found');
throw new Error('Authentication failed, you do not have access to that channel');
}
return user.comparePassword(userPassword);
}).then(function (isMatch) {
if (!isMatch) {
logger.debug('incorrect password');
throw new Error('Authentication failed, you do not have access to that channel');
}
logger.debug('...password was a match...');
resolve(channelData);
}).catch(function (error) {
reject(error);
});
});
}
};
/***/ }),
/* 75 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _require = __webpack_require__(5),
resolveUri = _require.resolveUri;
var _require2 = __webpack_require__(1),
handleErrorResponse = _require2.handleErrorResponse;
/*
route to run a resolve request on the daemon
*/
var claimResolve = function claimResolve(_ref, res) {
var headers = _ref.headers,
ip = _ref.ip,
originalUrl = _ref.originalUrl,
params = _ref.params;
resolveUri(params.name + '#' + params.claimId).then(function (resolvedUri) {
res.status(200).json(resolvedUri);
}).catch(function (error) {
handleErrorResponse(originalUrl, ip, error, res);
});
};
module.exports = claimResolve;
/***/ }),
/* 76 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _require = __webpack_require__(1),
handleErrorResponse = _require.handleErrorResponse;
var db = __webpack_require__(2);
/*
route to get a short claim id from long claim Id
*/
var claimShortId = function claimShortId(_ref, res) {
var ip = _ref.ip,
originalUrl = _ref.originalUrl,
body = _ref.body,
params = _ref.params;
db.Claim.getShortClaimIdFromLongClaimId(params.longId, params.name).then(function (shortId) {
res.status(200).json({ success: true, data: shortId });
}).catch(function (error) {
handleErrorResponse(originalUrl, ip, error, res);
});
};
module.exports = claimShortId;
/***/ }),
/* 77 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _require = __webpack_require__(5),
getClaimList = _require.getClaimList;
var _require2 = __webpack_require__(1),
handleErrorResponse = _require2.handleErrorResponse;
/*
route to get list of claims
*/
var claimList = function claimList(_ref, res) {
var ip = _ref.ip,
originalUrl = _ref.originalUrl,
params = _ref.params;
getClaimList(params.name).then(function (claimsList) {
res.status(200).json(claimsList);
}).catch(function (error) {
handleErrorResponse(originalUrl, ip, error, res);
});
};
module.exports = claimList;
/***/ }),
/* 78 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _require = __webpack_require__(1),
handleErrorResponse = _require.handleErrorResponse;
var db = __webpack_require__(2);
/*
route to see if asset is available locally
*/
var fileAvailability = function fileAvailability(_ref, res) {
var ip = _ref.ip,
originalUrl = _ref.originalUrl,
params = _ref.params;
var name = params.name;
var claimId = params.claimId;
db.File.findOne({
where: {
name: name,
claimId: claimId
}
}).then(function (result) {
if (result) {
return res.status(200).json({ success: true, data: true });
}
res.status(200).json({ success: true, data: false });
}).catch(function (error) {
handleErrorResponse(originalUrl, ip, error, res);
});
};
module.exports = fileAvailability;
/***/ }),
/* 79 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var multipart = __webpack_require__(80);
var _require = __webpack_require__(3),
uploadDirectory = _require.publishing.uploadDirectory;
var multipartMiddleware = multipart({ uploadDir: uploadDirectory });
module.exports = multipartMiddleware;
/***/ }),
/* 80 */
/***/ (function(module, exports) {
module.exports = require("connect-multiparty");
/***/ }),
/* 81 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var handlePageRequest = __webpack_require__(82);
var handleEmbedRequest = __webpack_require__(83);
var redirect = __webpack_require__(84);
module.exports = function (app) {
app.get('/', handlePageRequest);
app.get('/login', handlePageRequest);
app.get('/about', handlePageRequest);
app.get('/trending', redirect('/popular'));
app.get('/popular', handlePageRequest);
app.get('/new', handlePageRequest);
app.get('/embed/:claimId/:name', handleEmbedRequest); // route to send embedable video player (for twitter)
};
/***/ }),
/* 82 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var handlePageRender = __webpack_require__(14);
var sendReactApp = function sendReactApp(req, res) {
handlePageRender(req, res);
};
module.exports = sendReactApp;
/***/ }),
/* 83 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _require = __webpack_require__(3),
host = _require.details.host;
var sendEmbedPage = function sendEmbedPage(_ref, res) {
var params = _ref.params;
var claimId = params.claimId;
var name = params.name;
// get and render the content
res.status(200).render('embed', { layout: 'embed', host: host, claimId: claimId, name: name });
};
module.exports = sendEmbedPage;
/***/ }),
/* 84 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var redirect = function redirect(route) {
return function (req, res) {
res.status(301).redirect(route);
};
};
module.exports = redirect;
/***/ }),
/* 85 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var serveAssetByClaim = __webpack_require__(86);
var serveAssetByIdentifierAndClaim = __webpack_require__(89);
module.exports = function (app, db) {
app.get('/:identifier/:claim', serveAssetByIdentifierAndClaim);
app.get('/:claim', serveAssetByClaim);
};
/***/ }),
/* 86 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _require = __webpack_require__(4),
sendGAServeEvent = _require.sendGAServeEvent;
var _require2 = __webpack_require__(23),
determineResponseType = _require2.determineResponseType,
logRequestData = _require2.logRequestData,
getClaimIdAndServeAsset = _require2.getClaimIdAndServeAsset;
var lbryUri = __webpack_require__(24);
var handleShowRender = __webpack_require__(25);
var SERVE = 'SERVE';
/*
route to serve an asset or the react app via the claim name only
*/
var serverAssetByClaim = function serverAssetByClaim(req, res) {
var headers = req.headers,
ip = req.ip,
originalUrl = req.originalUrl,
params = req.params;
// decide if this is a show request
var hasFileExtension = void 0;
try {
var _lbryUri$parseModifie = lbryUri.parseModifier(params.claim);
hasFileExtension = _lbryUri$parseModifie.hasFileExtension;
} catch (error) {
return res.status(400).json({ success: false, message: error.message });
}
var responseType = determineResponseType(hasFileExtension, headers);
if (responseType !== SERVE) {
return handleShowRender(req, res);
}
// handle serve request
// send google analytics
sendGAServeEvent(headers, ip, originalUrl);
// parse the claim
var claimName = void 0;
try {
var _lbryUri$parseClaim = lbryUri.parseClaim(params.claim);
claimName = _lbryUri$parseClaim.claimName;
} catch (error) {
return res.status(400).json({ success: false, message: error.message });
}
// log the request data for debugging
logRequestData(responseType, claimName, null, null);
// get the claim Id and then serve the asset
getClaimIdAndServeAsset(null, null, claimName, null, originalUrl, ip, res);
};
module.exports = serverAssetByClaim;
/***/ }),
/* 87 */
/***/ (function(module, exports) {
module.exports = require("redux-saga");
/***/ }),
/* 88 */
/***/ (function(module, exports) {
module.exports = require("redux-saga/effects");
/***/ }),
/* 89 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
var _require = __webpack_require__(4),
sendGAServeEvent = _require.sendGAServeEvent;
var _require2 = __webpack_require__(23),
determineResponseType = _require2.determineResponseType,
flipClaimNameAndIdForBackwardsCompatibility = _require2.flipClaimNameAndIdForBackwardsCompatibility,
logRequestData = _require2.logRequestData,
getClaimIdAndServeAsset = _require2.getClaimIdAndServeAsset;
var lbryUri = __webpack_require__(24);
var handleShowRender = __webpack_require__(25);
var SERVE = 'SERVE';
/*
route to serve an asset or the react app via the claim name and an identifier
*/
var serverAssetByIdentifierAndClaim = function serverAssetByIdentifierAndClaim(req, res) {
var headers = req.headers,
ip = req.ip,
originalUrl = req.originalUrl,
params = req.params;
// decide if this is a show request
var hasFileExtension = void 0;
try {
var _lbryUri$parseModifie = lbryUri.parseModifier(params.claim);
hasFileExtension = _lbryUri$parseModifie.hasFileExtension;
} catch (error) {
return res.status(400).json({ success: false, message: error.message });
}
var responseType = determineResponseType(hasFileExtension, headers);
if (responseType !== SERVE) {
return handleShowRender(req, res);
}
// handle serve request
// send google analytics
sendGAServeEvent(headers, ip, originalUrl);
// parse the claim
var claimName = void 0;
try {
var _lbryUri$parseClaim = lbryUri.parseClaim(params.claim);
claimName = _lbryUri$parseClaim.claimName;
} catch (error) {
return res.status(400).json({ success: false, message: error.message });
}
// parse the identifier
var isChannel = void 0,
channelName = void 0,
channelClaimId = void 0,
claimId = void 0;
try {
var _lbryUri$parseIdentif = lbryUri.parseIdentifier(params.identifier);
isChannel = _lbryUri$parseIdentif.isChannel;
channelName = _lbryUri$parseIdentif.channelName;
channelClaimId = _lbryUri$parseIdentif.channelClaimId;
claimId = _lbryUri$parseIdentif.claimId;
} catch (error) {
return res.status(400).json({ success: false, message: error.message });
}
if (!isChannel) {
var _flipClaimNameAndIdFo = flipClaimNameAndIdForBackwardsCompatibility(claimId, claimName);
var _flipClaimNameAndIdFo2 = _slicedToArray(_flipClaimNameAndIdFo, 2);
claimId = _flipClaimNameAndIdFo2[0];
claimName = _flipClaimNameAndIdFo2[1];
}
// log the request data for debugging
logRequestData(responseType, claimName, channelName, claimId);
// get the claim Id and then serve the asset
getClaimIdAndServeAsset(channelName, channelClaimId, claimName, claimId, originalUrl, ip, res);
};
module.exports = serverAssetByIdentifierAndClaim;
/***/ }),
/* 90 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var handlePageRequest = __webpack_require__(91);
module.exports = function (app) {
app.get('*', handlePageRequest);
};
/***/ }),
/* 91 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var handlePageRender = __webpack_require__(14);
var sendReactApp = function sendReactApp(req, res) {
handlePageRender(req, res);
};
module.exports = sendReactApp;
/***/ })
/******/ ]);
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vd2VicGFjay9ib290c3RyYXAgMWJlZDZhZWJlYmIzMTkyYmU1YjYiLCJ3ZWJwYWNrOi8vL2V4dGVybmFsIFwid2luc3RvblwiIiwid2VicGFjazovLy8uL3NlcnZlci9oZWxwZXJzL2Vycm9ySGFuZGxlcnMuanMiLCJ3ZWJwYWNrOi8vLy4vc2VydmVyL21vZGVscy9pbmRleC5qcyIsIndlYnBhY2s6Ly8vLi9jb25maWcvc2l0ZUNvbmZpZy5qcyIsIndlYnBhY2s6Ly8vLi9zZXJ2ZXIvaGVscGVycy9nb29nbGVBbmFseXRpY3MuanMiLCJ3ZWJwYWNrOi8vLy4vc2VydmVyL2hlbHBlcnMvbGJyeUFwaS5qcyIsIndlYnBhY2s6Ly8vLi9zZXJ2ZXIvY29udHJvbGxlcnMvc2VydmVDb250cm9sbGVyLmpzIiwid2VicGFjazovLy8uL3NlcnZlci9zcGVlY2hQYXNzcG9ydC9pbmRleC5qcyIsIndlYnBhY2s6Ly8vLi9zZXJ2ZXIvY29udHJvbGxlcnMvcHVibGlzaENvbnRyb2xsZXIuanMiLCJ3ZWJwYWNrOi8vLy4vc2VydmVyL2hlbHBlcnMvcHVibGlzaEhlbHBlcnMuanMiLCJ3ZWJwYWNrOi8vLy4vY29uZmlnL215c3FsQ29uZmlnLmpzIiwid2VicGFjazovLy9leHRlcm5hbCBcInBhc3Nwb3J0LWxvY2FsXCIiLCJ3ZWJwYWNrOi8vLy4vc2VydmVyL2hlbHBlcnMvc2VxdWVsaXplSGVscGVycy5qcyIsIndlYnBhY2s6Ly8vZXh0ZXJuYWwgXCJzZXF1ZWxpemVcIiIsIndlYnBhY2s6Ly8vLi9zZXJ2ZXIvaGVscGVycy9oYW5kbGVQYWdlUmVuZGVyLmpzeCIsIndlYnBhY2s6Ly8vZXh0ZXJuYWwgXCJyZWFjdFwiIiwid2VicGFjazovLy9leHRlcm5hbCBcInJlYWN0LWRvbS9zZXJ2ZXJcIiIsIndlYnBhY2s6Ly8vZXh0ZXJuYWwgXCJyZWR1eFwiIiwid2VicGFjazovLy9leHRlcm5hbCBcInJlYWN0LXJlZHV4XCIiLCJ3ZWJwYWNrOi8vL2V4dGVybmFsIFwicmVhY3Qtcm91dGVyLWRvbVwiIiwid2VicGFjazovLy9leHRlcm5hbCBcInNwZWUuY2gtY29tcG9uZW50c1wiIiwid2VicGFjazovLy8uL3NlcnZlci9oZWxwZXJzL3JlbmRlckZ1bGxQYWdlLmpzIiwid2VicGFjazovLy9leHRlcm5hbCBcInJlYWN0LWhlbG1ldFwiIiwid2VicGFjazovLy8uL3NlcnZlci9oZWxwZXJzL3NlcnZlSGVscGVycy5qcyIsIndlYnBhY2s6Ly8vLi9zZXJ2ZXIvaGVscGVycy9sYnJ5VXJpLmpzIiwid2VicGFjazovLy8uL3NlcnZlci9oZWxwZXJzL2hhbmRsZVNob3dSZW5kZXIuanN4Iiwid2VicGFjazovLy9leHRlcm5hbCBcImJhYmVsLXBvbHlmaWxsXCIiLCJ3ZWJwYWNrOi8vL2V4dGVybmFsIFwid2hhdHdnLWZldGNoXCIiLCJ3ZWJwYWNrOi8vLy4vc3BlZWNoLmpzIiwid2VicGFjazovLy8uL3NlcnZlci9pbmRleC5qcyIsIndlYnBhY2s6Ly8vZXh0ZXJuYWwgXCJleHByZXNzXCIiLCJ3ZWJwYWNrOi8vL2V4dGVybmFsIFwiYm9keS1wYXJzZXJcIiIsIndlYnBhY2s6Ly8vZXh0ZXJuYWwgXCJleHByZXNzLWhhbmRsZWJhcnNcIiIsIndlYnBhY2s6Ly8vZXh0ZXJuYWwgXCJoYW5kbGViYXJzXCIiLCJ3ZWJwYWNrOi8vL2V4dGVybmFsIFwiaGVsbWV0XCIiLCJ3ZWJwYWNrOi8vL2V4dGVybmFsIFwiY29va2llLXNlc3Npb25cIiIsIndlYnBhY2s6Ly8vZXh0ZXJuYWwgXCJodHRwXCIiLCJ3ZWJwYWNrOi8vLy4vc2VydmVyL21pZGRsZXdhcmUvcmVxdWVzdExvZ2dlci5qcyIsIndlYnBhY2s6Ly8vZXh0ZXJuYWwgXCJwYXRoXCIiLCJ3ZWJwYWNrOi8vLy4vY29uZmlnL2xvZ2dlckNvbmZpZy5qcyIsIndlYnBhY2s6Ly8vLi9jb25maWcvc2xhY2tDb25maWcuanMiLCJ3ZWJwYWNrOi8vL2V4dGVybmFsIFwid2luc3Rvbi1zbGFjay13ZWJob29rXCIiLCJ3ZWJwYWNrOi8vL2V4dGVybmFsIFwicGFzc3BvcnRcIiIsIndlYnBhY2s6Ly8vLi9zZXJ2ZXIvc3BlZWNoUGFzc3BvcnQvbG9jYWwtbG9naW4uanMiLCJ3ZWJwYWNrOi8vLy4vc2VydmVyL21vZGVscy9jZXJ0aWZpY2F0ZS5qcyIsIndlYnBhY2s6Ly8vLi9zZXJ2ZXIvbW9kZWxzL2NoYW5uZWwuanMiLCJ3ZWJwYWNrOi8vLy4vc2VydmVyL21vZGVscy9jbGFpbS5qcyIsIndlYnBhY2s6Ly8vLi9zZXJ2ZXIvbW9kZWxzL2ZpbGUuanMiLCJ3ZWJwYWNrOi8vLy4vc2VydmVyL21vZGVscy9yZXF1ZXN0LmpzIiwid2VicGFjazovLy8uL3NlcnZlci9tb2RlbHMvdXNlci5qcyIsIndlYnBhY2s6Ly8vZXh0ZXJuYWwgXCJiY3J5cHRcIiIsIndlYnBhY2s6Ly8vLi9zZXJ2ZXIvc3BlZWNoUGFzc3BvcnQvbG9jYWwtc2lnbnVwLmpzIiwid2VicGFjazovLy9leHRlcm5hbCBcImF4aW9zXCIiLCJ3ZWJwYWNrOi8vLy4vY29uZmlnL2xicnlDb25maWcuanMiLCJ3ZWJwYWNrOi8vL2V4dGVybmFsIFwidW5pdmVyc2FsLWFuYWx5dGljc1wiIiwid2VicGFjazovLy8uL3NlcnZlci9oZWxwZXJzL2F1dGhIZWxwZXJzLmpzIiwid2VicGFjazovLy8uL3NlcnZlci9yb3V0ZXMvYXV0aC9pbmRleC5qcyIsIndlYnBhY2s6Ly8vLi9zZXJ2ZXIvcm91dGVzL2F1dGgvc2lnbnVwLmpzIiwid2VicGFjazovLy8uL3NlcnZlci9yb3V0ZXMvYXV0aC9sb2dpbi5qcyIsIndlYnBhY2s6Ly8vLi9zZXJ2ZXIvcm91dGVzL2F1dGgvbG9nb3V0LmpzIiwid2VicGFjazovLy8uL3NlcnZlci9yb3V0ZXMvYXV0aC91c2VyLmpzIiwid2VicGFjazovLy8uL3NlcnZlci9yb3V0ZXMvYXBpL2luZGV4LmpzIiwid2VicGFjazovLy8uL3NlcnZlci9yb3V0ZXMvYXBpL2NoYW5uZWxBdmFpbGFiaWxpdHkuanMiLCJ3ZWJwYWNrOi8vL2V4dGVybmFsIFwiZnNcIiIsIndlYnBhY2s6Ly8vLi9zZXJ2ZXIvcm91dGVzL2FwaS9jaGFubmVsQ2xhaW1zLmpzIiwid2VicGFjazovLy8uL3NlcnZlci9oZWxwZXJzL2NoYW5uZWxQYWdpbmF0aW9uLmpzIiwid2VicGFjazovLy8uL3NlcnZlci9yb3V0ZXMvYXBpL2NoYW5uZWxEYXRhLmpzIiwid2VicGFjazovLy8uL3NlcnZlci9yb3V0ZXMvYXBpL2NoYW5uZWxTaG9ydElkLmpzIiwid2VicGFjazovLy8uL3NlcnZlci9yb3V0ZXMvYXBpL2NsYWltQXZhaWxhYmlsaXR5LmpzIiwid2VicGFjazovLy8uL3NlcnZlci9yb3V0ZXMvYXBpL2NsYWltRGF0YS5qcyIsIndlYnBhY2s6Ly8vLi9zZXJ2ZXIvcm91dGVzL2FwaS9jbGFpbUdldC5qcyIsIndlYnBhY2s6Ly8vLi9zZXJ2ZXIvcm91dGVzL2FwaS9jbGFpbUxvbmdJZC5qcyIsIndlYnBhY2s6Ly8vLi9zZXJ2ZXIvcm91dGVzL2FwaS9jbGFpbVB1Ymxpc2guanMiLCJ3ZWJwYWNrOi8vLy4vc2VydmVyL2F1dGgvYXV0aGVudGljYXRpb24uanMiLCJ3ZWJwYWNrOi8vLy4vc2VydmVyL3JvdXRlcy9hcGkvY2xhaW1SZXNvbHZlLmpzIiwid2VicGFjazovLy8uL3NlcnZlci9yb3V0ZXMvYXBpL2NsYWltU2hvcnRJZC5qcyIsIndlYnBhY2s6Ly8vLi9zZXJ2ZXIvcm91dGVzL2FwaS9jbGFpbUxpc3QuanMiLCJ3ZWJwYWNrOi8vLy4vc2VydmVyL3JvdXRlcy9hcGkvZmlsZUF2YWlsYWJpbGl0eS5qcyIsIndlYnBhY2s6Ly8vLi9zZXJ2ZXIvaGVscGVycy9tdWx0aXBhcnRNaWRkbGV3YXJlLmpzIiwid2VicGFjazovLy9leHRlcm5hbCBcImNvbm5lY3QtbXVsdGlwYXJ0eVwiIiwid2VicGFjazovLy8uL3NlcnZlci9yb3V0ZXMvcGFnZXMvaW5kZXguanMiLCJ3ZWJwYWNrOi8vLy4vc2VydmVyL3JvdXRlcy9wYWdlcy9zZW5kUmVhY3RBcHAuanMiLCJ3ZWJwYWNrOi8vLy4vc2VydmVyL3JvdXRlcy9wYWdlcy9zZW5kRW1iZWRQYWdlLmpzIiwid2VicGFjazovLy8uL3NlcnZlci9yb3V0ZXMvcGFnZXMvcmVkaXJlY3QuanMiLCJ3ZWJwYWNrOi8vLy4vc2VydmVyL3JvdXRlcy9hc3NldHMvaW5kZXguanMiLCJ3ZWJwYWNrOi8vLy4vc2VydmVyL3JvdXRlcy9hc3NldHMvc2VydmVBc3NldEJ5Q2xhaW0uanMiLCJ3ZWJwYWNrOi8vL2V4dGVybmFsIFwicmVkdXgtc2FnYVwiIiwid2VicGFjazovLy9leHRlcm5hbCBcInJlZHV4LXNhZ2EvZWZmZWN0c1wiIiwid2VicGFjazovLy8uL3NlcnZlci9yb3V0ZXMvYXNzZXRzL3NlcnZlQXNzZXRCeUlkZW50aWZpZXJBbmRDbGFpbS5qcyIsIndlYnBhY2s6Ly8vLi9zZXJ2ZXIvcm91dGVzL2ZhbGxiYWNrL2luZGV4LmpzIiwid2VicGFjazovLy8uL3NlcnZlci9yb3V0ZXMvZmFsbGJhY2svc2VuZFJlYWN0QXBwLmpzIl0sIm5hbWVzIjpbImxvZ2dlciIsInJlcXVpcmUiLCJtb2R1bGUiLCJleHBvcnRzIiwiaGFuZGxlRXJyb3JSZXNwb25zZSIsIm9yaWdpbmFsVXJsIiwiaXAiLCJlcnJvciIsInJlcyIsInVzZU9iamVjdFByb3BlcnRpZXNJZk5vS2V5cyIsInJldHVybkVycm9yTWVzc2FnZUFuZFN0YXR1cyIsInN0YXR1cyIsIm1lc3NhZ2UiLCJqc29uIiwiY3JlYXRlRXJyb3JSZXNwb25zZVBheWxvYWQiLCJjb2RlIiwiZXJyIiwiT2JqZWN0Iiwia2V5cyIsImxlbmd0aCIsIm5ld0Vycm9yT2JqZWN0IiwiZ2V0T3duUHJvcGVydHlOYW1lcyIsImZvckVhY2giLCJrZXkiLCJzdWNjZXNzIiwiQ2VydGlmaWNhdGUiLCJDaGFubmVsIiwiQ2xhaW0iLCJGaWxlIiwiUmVxdWVzdCIsIlVzZXIiLCJTZXF1ZWxpemUiLCJkYXRhYmFzZSIsInVzZXJuYW1lIiwicGFzc3dvcmQiLCJzZXF1ZWxpemUiLCJob3N0IiwiZGlhbGVjdCIsImRpYWxlY3RPcHRpb25zIiwiZGVjaW1hbE51bWJlcnMiLCJsb2dnaW5nIiwicG9vbCIsIm1heCIsIm1pbiIsImlkbGUiLCJhY3F1aXJlIiwiYXV0aGVudGljYXRlIiwidGhlbiIsImluZm8iLCJjYXRjaCIsImRiIiwiaW1wb3J0IiwibW9kZWxOYW1lIiwiYXNzb2NpYXRlIiwidXBzZXJ0IiwiTW9kZWwiLCJ2YWx1ZXMiLCJjb25kaXRpb24iLCJ0YWJsZU5hbWUiLCJmaW5kT25lIiwid2hlcmUiLCJvYmoiLCJkZWJ1ZyIsInVwZGF0ZSIsImNyZWF0ZSIsIlNpdGVDb25maWciLCJhbmFseXRpY3MiLCJnb29nbGVJZCIsImFzc2V0RGVmYXVsdHMiLCJkZXNjcmlwdGlvbiIsInRodW1ibmFpbCIsInRpdGxlIiwiYXV0aCIsInNlc3Npb25LZXkiLCJjdXN0b21Db21wb25lbnRzIiwiY3VzdG9tQ29udGFpbmVycyIsImN1c3RvbVBhZ2VzIiwiZGV0YWlscyIsInBvcnQiLCJ0d2l0dGVyIiwicHVibGlzaGluZyIsImFkZGl0aW9uYWxDbGFpbUFkZHJlc3NlcyIsImRpc2FibGVkIiwiZGlzYWJsZWRNZXNzYWdlIiwicHJpbWFyeUNsYWltQWRkcmVzcyIsInRodW1ibmFpbENoYW5uZWwiLCJ0aHVtYm5haWxDaGFubmVsSWQiLCJ1cGxvYWREaXJlY3RvcnkiLCJyb3V0ZXMiLCJjb25maWciLCJjb25zb2xlIiwibG9nIiwidWEiLCJjcmVhdGVTZXJ2ZUV2ZW50UGFyYW1zIiwiaGVhZGVycyIsImV2ZW50Q2F0ZWdvcnkiLCJldmVudEFjdGlvbiIsImV2ZW50TGFiZWwiLCJpcE92ZXJyaWRlIiwidXNlckFnZW50T3ZlcnJpZGUiLCJjcmVhdGVQdWJsaXNoVGltaW5nRXZlbnRQYXJhbXMiLCJjYXRlZ29yeSIsInZhcmlhYmxlIiwibGFiZWwiLCJzdGFydFRpbWUiLCJlbmRUaW1lIiwiZHVyYXRpb24iLCJ1c2VyVGltaW5nQ2F0ZWdvcnkiLCJ1c2VyVGltaW5nVmFyaWFibGVOYW1lIiwidXNlclRpbWluZ1RpbWUiLCJ1c2VyVGltaW5nTGFiZWwiLCJzZW5kR29vZ2xlQW5hbHl0aWNzRXZlbnQiLCJwYXJhbXMiLCJ2aXNpdG9ySWQiLCJyZXBsYWNlIiwidmlzaXRvciIsInN0cmljdENpZEZvcm1hdCIsImh0dHBzIiwiZXZlbnQiLCJzZW5kR29vZ2xlQW5hbHl0aWNzVGltaW5nIiwidGltaW5nIiwic2VuZEdBU2VydmVFdmVudCIsInNlbmRHQVRpbWluZ0V2ZW50IiwiY2hvb3NlR2FMYnJ5bmV0UHVibGlzaExhYmVsIiwiY2hhbm5lbE5hbWUiLCJjaGFubmVsX25hbWUiLCJjaGFubmVsSWQiLCJjaGFubmVsX2lkIiwiYXhpb3MiLCJhcGkiLCJhcGlIb3N0IiwiYXBpUG9ydCIsImxicnlBcGlVcmkiLCJoYW5kbGVMYnJ5bmV0UmVzcG9uc2UiLCJyZXNvbHZlIiwicmVqZWN0IiwiZGF0YSIsInJlc3VsdCIsIkVycm9yIiwiSlNPTiIsInN0cmluZ2lmeSIsInB1Ymxpc2hDbGFpbSIsInB1Ymxpc2hQYXJhbXMiLCJuYW1lIiwiZ2FTdGFydFRpbWUiLCJEYXRlIiwibm93IiwiUHJvbWlzZSIsInBvc3QiLCJtZXRob2QiLCJyZXNwb25zZSIsImdldENsYWltIiwidXJpIiwidGltZW91dCIsImdldENsYWltTGlzdCIsImNsYWltTmFtZSIsInJlc29sdmVVcmkiLCJnZXREb3dubG9hZERpcmVjdG9yeSIsImRvd25sb2FkX2RpcmVjdG9yeSIsImNyZWF0ZUNoYW5uZWwiLCJhbW91bnQiLCJyZXR1cm5QYWdpbmF0ZWRDaGFubmVsQ2xhaW1zIiwiTk9fQ0hBTk5FTCIsIk5PX0NMQUlNIiwiTk9fRklMRSIsImdldENsYWltSWQiLCJjaGFubmVsQ2xhaW1JZCIsImNsYWltSWQiLCJnZXRDbGFpbUlkQnlDaGFubmVsIiwiZ2V0Q2xhaW1JZEJ5Q2xhaW0iLCJnZXRMb25nQ2xhaW1JZCIsImxvbmdDbGFpbUlkIiwiZ2V0TG9uZ0NoYW5uZWxJZCIsImxvbmdDaGFubmVsSWQiLCJhbGwiLCJnZXRDbGFpbUlkQnlMb25nQ2hhbm5lbElkIiwiZ2V0Q2hhbm5lbERhdGEiLCJwYWdlIiwibG9uZ0NoYW5uZWxDbGFpbUlkIiwiZ2V0U2hvcnRDaGFubmVsSWRGcm9tTG9uZ0NoYW5uZWxJZCIsInNob3J0Q2hhbm5lbENsYWltSWQiLCJnZXRDaGFubmVsQ2xhaW1zIiwiZ2V0QWxsQ2hhbm5lbENsYWltcyIsImNoYW5uZWxDbGFpbXNBcnJheSIsInBhZ2luYXRlZENoYW5uZWxWaWV3RGF0YSIsImdldExvY2FsRmlsZVJlY29yZCIsImZpbGUiLCJkYXRhVmFsdWVzIiwicGFzc3BvcnQiLCJsb2NhbExvZ2luU3RyYXRlZ3kiLCJsb2NhbFNpZ251cFN0cmF0ZWd5Iiwic2VyaWFsaXplU3BlZWNoVXNlciIsImRlc2VyaWFsaXplU3BlZWNoVXNlciIsImRlc2VyaWFsaXplVXNlciIsInNlcmlhbGl6ZVVzZXIiLCJ1c2UiLCJsYnJ5QXBpIiwicHVibGlzaEhlbHBlcnMiLCJPcCIsInB1Ymxpc2giLCJmaWxlTmFtZSIsImZpbGVUeXBlIiwicHVibGlzaFJlc3VsdHMiLCJjZXJ0aWZpY2F0ZUlkIiwidHgiLCJjaGFubmVsIiwiZmlsZVJlY29yZCIsImNsYWltX2lkIiwibWV0YWRhdGEiLCJhZGRyZXNzIiwiY2xhaW1fYWRkcmVzcyIsIm91dHBvaW50IiwidHhpZCIsIm5vdXQiLCJoZWlnaHQiLCJmaWxlUGF0aCIsImZpbGVfcGF0aCIsIm5zZnciLCJjbGFpbVJlY29yZCIsImNvbnRlbnRUeXBlIiwiYmlkIiwidXBzZXJ0Q3JpdGVyaWEiLCJjbGFpbSIsInNldENsYWltIiwic2V0RmlsZSIsImRlbGV0ZVRlbXBvcmFyeUZpbGUiLCJjbGFpbU5hbWVJc0F2YWlsYWJsZSIsImNsYWltQWRkcmVzc2VzIiwicHVzaCIsImZpbmRBbGwiLCJhdHRyaWJ1dGVzIiwib3IiLCJjaGVja0NoYW5uZWxBdmFpbGFiaWxpdHkiLCJmcyIsInBhcnNlUHVibGlzaEFwaVJlcXVlc3RCb2R5IiwibGljZW5zZSIsImludmFsaWROYW1lQ2hhcmFjdGVycyIsImV4ZWMiLCJwYXJzZVB1Ymxpc2hBcGlSZXF1ZXN0RmlsZXMiLCJwYXRoIiwidHlwZSIsInNpemUiLCJ0ZXN0IiwidmFsaWRhdGVGaWxlVHlwZUFuZFNpemUiLCJ0aHVtYm5haWxGaWxlTmFtZSIsInRodW1ibmFpbEZpbGVQYXRoIiwidGh1bWJuYWlsRmlsZVR5cGUiLCJjcmVhdGVCYXNpY1B1Ymxpc2hQYXJhbXMiLCJ0cmltIiwiYXV0aG9yIiwibGFuZ3VhZ2UiLCJjcmVhdGVUaHVtYm5haWxQdWJsaXNoUGFyYW1zIiwidW5saW5rIiwiYWRkR2V0UmVzdWx0c1RvRmlsZURhdGEiLCJmaWxlSW5mbyIsImdldFJlc3VsdCIsImZpbGVfbmFtZSIsImRvd25sb2FkX3BhdGgiLCJjcmVhdGVGaWxlRGF0YSIsIm15c3FsIiwid2FybiIsInJldHVyblNob3J0SWQiLCJjbGFpbXNBcnJheSIsImxvbmdJZCIsImNsYWltSW5kZXgiLCJzaG9ydElkIiwic3Vic3RyaW5nIiwic2hvcnRJZExlbmd0aCIsImZpbmRJbmRleCIsImVsZW1lbnQiLCJwb3NzaWJsZU1hdGNoZXMiLCJzbGljZSIsImZpbHRlciIsInNpdGVDb25maWciLCJyZXEiLCJjb250ZXh0IiwiTXlSZWR1Y2VycyIsIk15QXBwIiwiTXlHQUxpc3RlbmVyIiwic3RvcmUiLCJodG1sIiwidXJsIiwiaGVsbWV0IiwicmVuZGVyU3RhdGljIiwicmVkaXJlY3QiLCJwcmVsb2FkZWRTdGF0ZSIsImdldFN0YXRlIiwic2VuZCIsInRvU3RyaW5nIiwibWV0YSIsImxpbmsiLCJTRVJWRSIsIlNIT1ciLCJjbGllbnRBY2NlcHRzSHRtbCIsImFjY2VwdCIsIm1hdGNoIiwicmVxdWVzdElzRnJvbUJyb3dzZXIiLCJjbGllbnRXYW50c0Fzc2V0IiwicmFuZ2UiLCJpbWFnZUlzV2FudGVkIiwidmlkZW9Jc1dhbnRlZCIsImlzVmFsaWRDbGFpbUlkIiwiaXNWYWxpZFNob3J0SWQiLCJpc1ZhbGlkU2hvcnRJZE9yQ2xhaW1JZCIsImlucHV0Iiwic2VydmVBc3NldFRvQ2xpZW50IiwidmVyYm9zZSIsInNlbmRGaWxlT3B0aW9ucyIsInNlbmRGaWxlIiwiZ2V0Q2xhaW1JZEFuZFNlcnZlQXNzZXQiLCJmdWxsQ2xhaW1JZCIsImRldGVybWluZVJlc3BvbnNlVHlwZSIsImhhc0ZpbGVFeHRlbnNpb24iLCJyZXNwb25zZVR5cGUiLCJmbGlwQ2xhaW1OYW1lQW5kSWRGb3JCYWNrd2FyZHNDb21wYXRpYmlsaXR5IiwiaWRlbnRpZmllciIsInRlbXBOYW1lIiwibG9nUmVxdWVzdERhdGEiLCJSRUdFWFBfSU5WQUxJRF9DTEFJTSIsIlJFR0VYUF9JTlZBTElEX0NIQU5ORUwiLCJSRUdFWFBfQUREUkVTUyIsIkNIQU5ORUxfQ0hBUiIsInBhcnNlSWRlbnRpZmllciIsImNvbXBvbmVudHNSZWdleCIsIlJlZ0V4cCIsIm1hcCIsInByb3RvIiwidmFsdWUiLCJtb2RpZmllclNlcGVyYXRvciIsIm1vZGlmaWVyIiwiaXNDaGFubmVsIiwic3RhcnRzV2l0aCIsIm5hbWVCYWRDaGFycyIsImpvaW4iLCJwYXJzZUNsYWltIiwicGFyc2VNb2RpZmllciIsInJldHVyblNhZ2FXaXRoUGFyYW1zIiwic2FnYSIsInNhZ2FNaWRkbGV3YXJlIiwibWlkZGxld2FyZSIsImFjdGlvbiIsIm9uSGFuZGxlU2hvd1BhZ2VVcmkiLCJoYW5kbGVTaG93UGFnZVVyaSIsInJ1biIsImRvbmUiLCJTZXJ2ZXIiLCJleHByZXNzIiwiYm9keVBhcnNlciIsImV4cHJlc3NIYW5kbGViYXJzIiwiSGFuZGxlYmFycyIsImNvb2tpZVNlc3Npb24iLCJodHRwIiwicmVxdWVzdExvZ2dlciIsIlBhdGgiLCJsb2dnZXJDb25maWciLCJteXNxbENvbmZpZyIsInNsYWNrQ29uZmlnIiwiY29uZmlndXJlTG9nZ2VyIiwidXNlckNvbmZpZyIsImNvbmZpZ3VyZU15c3FsIiwiY29uZmlndXJlU2l0ZURldGFpbHMiLCJjb25maWd1cmVTbGFjayIsImNvbmZpZ3VyZUNsaWVudEJ1bmRsZSIsImNvbmZpZ3VyZU1vZGVscyIsImNvbmZpZ3VyZVJvdXRlcyIsImNyZWF0ZUFwcCIsImFwcCIsImVuYWJsZSIsInB1YmxpY0ZvbGRlciIsInByb2Nlc3MiLCJjd2QiLCJzdGF0aWMiLCJwdWJsaWNQYXRoIiwiX19kaXJuYW1lIiwidXJsZW5jb2RlZCIsImV4dGVuZGVkIiwic3BlZWNoUGFzc3BvcnQiLCJtYXhBZ2UiLCJpbml0aWFsaXplIiwic2Vzc2lvbiIsImhicyIsImRlZmF1bHRMYXlvdXQiLCJoYW5kbGViYXJzIiwiZW5naW5lIiwic2V0Iiwic2VydmVyIiwic3RhcnQiLCJQT1JUIiwic3luYyIsImxpc3RlbiIsIm5leHQiLCJMb2dnZXJDb25maWciLCJsb2dMZXZlbCIsImNvbmZpZ3VyZSIsInRyYW5zcG9ydHMiLCJDb25zb2xlIiwibGV2ZWwiLCJ0aW1lc3RhbXAiLCJjb2xvcml6ZSIsInByZXR0eVByaW50IiwiaGFuZGxlRXhjZXB0aW9ucyIsImh1bWFuUmVhZGFibGVVbmhhbmRsZWRFeGNlcHRpb24iLCJzaWxseSIsIndpbnN0b25TbGFja1dlYkhvb2siLCJTbGFja1dlYkhvb2siLCJ3aW5zdG9uIiwiU2xhY2tDb25maWciLCJzbGFja1dlYkhvb2siLCJzbGFja0Vycm9yQ2hhbm5lbCIsInNsYWNrSW5mb0NoYW5uZWwiLCJhZGQiLCJ3ZWJob29rVXJsIiwiaWNvbkVtb2ppIiwiUGFzc3BvcnRMb2NhbFN0cmF0ZWd5IiwiU3RyYXRlZ3kiLCJyZXR1cm5Vc2VyQW5kQ2hhbm5lbEluZm8iLCJ1c2VySW5zdGFuY2UiLCJ1c2VySW5mbyIsImlkIiwidXNlck5hbWUiLCJnZXRDaGFubmVsIiwic2hvcnRDaGFubmVsSWQiLCJ1c2VybmFtZUZpZWxkIiwicGFzc3dvcmRGaWVsZCIsInVzZXIiLCJjb21wYXJlUGFzc3dvcmQiLCJpc01hdGNoIiwiU1RSSU5HIiwiQk9PTEVBTiIsIklOVEVHRVIiLCJURVhUIiwiREVDSU1BTCIsImRlZmluZSIsImRlZmF1bHQiLCJjbGFpbVNlcXVlbmNlIiwiZGVjb2RlZENsYWltIiwiZGVwdGgiLCJlZmZlY3RpdmVBbW91bnQiLCJoYXNTaWduYXR1cmUiLCJoZXgiLCJ2YWxpZEF0SGVpZ2h0IiwidmFsdWVWZXJzaW9uIiwiY2xhaW1UeXBlIiwiY2VydGlmaWNhdGVWZXJzaW9uIiwia2V5VHlwZSIsInB1YmxpY0tleSIsImZyZWV6ZVRhYmxlTmFtZSIsImJlbG9uZ3NUbyIsImZvcmVpZ25LZXkiLCJhbGxvd051bGwiLCJvcmRlciIsImdldExvbmdDaGFubmVsSWRGcm9tU2hvcnRDaGFubmVsSWQiLCIkbGlrZSIsImdldExvbmdDaGFubmVsSWRGcm9tQ2hhbm5lbE5hbWUiLCJ2YWxpZGF0ZUxvbmdDaGFubmVsSWQiLCJoYXNPbmUiLCJkZWZhdWx0VGh1bWJuYWlsIiwiZGV0ZXJtaW5lRmlsZUV4dGVuc2lvbkZyb21Db250ZW50VHlwZSIsImRldGVybWluZVRodW1ibmFpbCIsInN0b3JlZFRodW1ibmFpbCIsInByZXBhcmVDbGFpbURhdGEiLCJsaWNlbnNlVXJsIiwicHJldmlldyIsIm1ldGFkYXRhVmVyc2lvbiIsInNvdXJjZSIsInNvdXJjZVR5cGUiLCJzb3VyY2VWZXJzaW9uIiwic3RyZWFtVmVyc2lvbiIsImdldFNob3J0Q2xhaW1JZEZyb21Mb25nQ2xhaW1JZCIsInJhdyIsImdldExvbmdDbGFpbUlkRnJvbVNob3J0Q2xhaW1JZCIsImdldFRvcEZyZWVDbGFpbUlkQnlDbGFpbU5hbWUiLCJ2YWxpZGF0ZUxvbmdDbGFpbUlkIiwicmVzb2x2ZUNsYWltIiwiY2xhaW1BcnJheSIsImRlZmF1bHRWYWx1ZSIsInRyZW5kaW5nRWxpZ2libGUiLCJoYXNNYW55IiwiZ2V0UmVjZW50Q2xhaW1zIiwibGltaXQiLCJpcEFkZHJlc3MiLCJiY3J5cHQiLCJwcm90b3R5cGUiLCJjb21wYXJlIiwiY2hhbmdlUGFzc3dvcmQiLCJuZXdQYXNzd29yZCIsImdlblNhbHQiLCJzYWx0RXJyb3IiLCJzYWx0IiwiaGFzaCIsImhhc2hFcnJvciIsImhvb2siLCJvcHRpb25zIiwidXNlckRhdGEiLCJjaGFubmVsRGF0YSIsImNlcnRpZmljYXRlRGF0YSIsIm5ld1VzZXIiLCJuZXdDaGFubmVsIiwibmV3Q2VydGlmaWNhdGUiLCJzZXRDaGFubmVsIiwic2V0VXNlciIsImxicnlDb25maWciLCJoYW5kbGVTaWdudXBSZXF1ZXN0IiwiaGFuZGxlTG9naW5SZXF1ZXN0IiwiaGFuZGxlTG9nb3V0UmVxdWVzdCIsImhhbmRsZVVzZXJSZXF1ZXN0IiwiZ2V0Iiwic2lnbnVwIiwibG9naW4iLCJsb2dJbiIsImxvZ291dCIsImNoYW5uZWxBdmFpbGFiaWxpdHkiLCJjaGFubmVsQ2xhaW1zIiwiY2hhbm5lbFNob3J0SWQiLCJjbGFpbUF2YWlsYWJpbGl0eSIsImNsYWltRGF0YSIsImNsYWltR2V0IiwiY2xhaW1Mb25nSWQiLCJjbGFpbVB1Ymxpc2giLCJjbGFpbVJlc29sdmUiLCJjbGFpbVNob3J0SWQiLCJjbGFpbUxpc3QiLCJmaWxlQXZhaWxhYmlsaXR5IiwibXVsdGlwYXJ0TWlkZGxld2FyZSIsImF2YWlsYWJsZU5hbWUiLCJib2R5IiwiQ0xBSU1TX1BFUl9QQUdFIiwiY2xhaW1zIiwidG90YWxQYWdlcyIsImRldGVybWluZVRvdGFsUGFnZXMiLCJwYWdpbmF0aW9uUGFnZSIsImdldFBhZ2VGcm9tUXVlcnkiLCJ2aWV3RGF0YSIsImV4dHJhY3RQYWdlRnJvbUNsYWltcyIsInByZXZpb3VzUGFnZSIsImRldGVybWluZVByZXZpb3VzUGFnZSIsImN1cnJlbnRQYWdlIiwibmV4dFBhZ2UiLCJkZXRlcm1pbmVOZXh0UGFnZSIsInRvdGFsUmVzdWx0cyIsImRldGVybWluZVRvdGFsQ2xhaW1zIiwicGFyc2VJbnQiLCJwYWdlTnVtYmVyIiwiY2xhaW1TdGFydEluZGV4IiwiY2xhaW1FbmRJbmRleCIsInBhZ2VPZkNsYWltcyIsInRvdGFsQ2xhaW1zIiwiZnVsbFBhZ2VzIiwiTWF0aCIsImZsb29yIiwicmVtYWluZGVyIiwiY2hhbm5lbFNob3J0SWRSb3V0ZSIsImNsYWltSW5mbyIsInJlc29sdmVSZXN1bHQiLCJmaWxlRGF0YSIsImNvbXBsZXRlZCIsImF1dGhlbnRpY2F0ZVVzZXIiLCJmaWxlcyIsImNoYW5uZWxQYXNzd29yZCIsInZhbGlkYXRlZENsYWltTmFtZSIsInRodW1ibmFpbFB1Ymxpc2hQYXJhbXMiLCJsYnJ5VHgiLCJhdXRoZW50aWNhdGVDaGFubmVsQ3JlZGVudGlhbHMiLCJ1c2VyUGFzc3dvcmQiLCJjaGFubmVsRmluZFBhcmFtcyIsInJlc29sdmVkVXJpIiwiY2xhaW1zTGlzdCIsIm11bHRpcGFydCIsInVwbG9hZERpciIsImhhbmRsZVBhZ2VSZXF1ZXN0IiwiaGFuZGxlRW1iZWRSZXF1ZXN0IiwiaGFuZGxlUGFnZVJlbmRlciIsInNlbmRSZWFjdEFwcCIsInNlbmRFbWJlZFBhZ2UiLCJyZW5kZXIiLCJsYXlvdXQiLCJyb3V0ZSIsInNlcnZlQXNzZXRCeUNsYWltIiwic2VydmVBc3NldEJ5SWRlbnRpZmllckFuZENsYWltIiwibGJyeVVyaSIsImhhbmRsZVNob3dSZW5kZXIiLCJzZXJ2ZXJBc3NldEJ5Q2xhaW0iLCJzZXJ2ZXJBc3NldEJ5SWRlbnRpZmllckFuZENsYWltIl0sIm1hcHBpbmdzIjoiOztBQUFBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOzs7QUFHQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFLO0FBQ0w7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxtQ0FBMkIsMEJBQTBCLEVBQUU7QUFDdkQseUNBQWlDLGVBQWU7QUFDaEQ7QUFDQTtBQUNBOztBQUVBO0FBQ0EsOERBQXNELCtEQUErRDs7QUFFckg7QUFDQTs7QUFFQTtBQUNBOzs7Ozs7O0FDN0RBLG9DOzs7Ozs7Ozs7OztBQ0FBLElBQU1BLFNBQVMsbUJBQUFDLENBQVEsQ0FBUixDQUFmOztBQUVBQyxPQUFPQyxPQUFQLEdBQWlCO0FBQ2ZDLHVCQUFxQiw2QkFBVUMsV0FBVixFQUF1QkMsRUFBdkIsRUFBMkJDLEtBQTNCLEVB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QyxPQUFPQyxPQUFQLEdBQWlCLFVBQUMyVyxHQUFELEVBQVM7QUFDeEJBLE1BQUk0SSxHQUFKLENBQVEsR0FBUixFQUFhK0QsaUJBQWI7QUFDRCxDQUZELEM7Ozs7Ozs7OztBQ0ZBLElBQU1FLG1CQUFtQixtQkFBQTFqQixDQUFRLEVBQVIsQ0FBekI7O0FBRUEsSUFBTTJqQixlQUFlLFNBQWZBLFlBQWUsQ0FBQzFTLEdBQUQsRUFBTTFRLEdBQU4sRUFBYztBQUNqQ21qQixtQkFBaUJ6UyxHQUFqQixFQUFzQjFRLEdBQXRCO0FBQ0QsQ0FGRDs7QUFJQU4sT0FBT0MsT0FBUCxHQUFpQnlqQixZQUFqQixDIiwiZmlsZSI6ImluZGV4LmpzIiwic291cmNlc0NvbnRlbnQiOlsiIFx0Ly8gVGhlIG1vZHVsZSBjYWNoZVxuIFx0dmFyIGluc3RhbGxlZE1vZHVsZXMgPSB7fTtcblxuIFx0Ly8gVGhlIHJlcXVpcmUgZnVuY3Rpb25cbiBcdGZ1bmN0aW9uIF9fd2VicGFja19yZXF1aXJlX18obW9kdWxlSWQpIHtcblxuIFx0XHQvLyBDaGVjayBpZiBtb2R1bGUgaXMgaW4gY2FjaGVcbiBcdFx0aWYoaW5zdGFsbGVkTW9kdWxlc1ttb2R1bGVJZF0pIHtcbiBcdFx0XHRyZXR1cm4gaW5zdGFsbGVkTW9kdWxlc1ttb2R1bGVJZF0uZXhwb3J0cztcbiBcdFx0fVxuIFx0XHQvLyBDcmVhdGUgYSBuZXcgbW9kdWxlIChhbmQgcHV0IGl0IGludG8gdGhlIGNhY2hlKVxuIFx0XHR2YXIgbW9kdWxlID0gaW5zdGFsbGVkTW9kdWxlc1ttb2R1bGVJZF0gPSB7XG4gXHRcdFx0aTogbW9kdWxlSWQsXG4gXHRcdFx0bDogZmFsc2UsXG4gXHRcdFx0ZXhwb3J0czoge31cbiBcdFx0fTtcblxuIFx0XHQvLyBFeGVjdXRlIHRoZSBtb2R1bGUgZnVuY3Rpb25cbiBcdFx0bW9kdWxlc1ttb2R1bGVJZF0uY2FsbChtb2R1bGUuZXhwb3J0cywgbW9kdWxlLCBtb2R1bGUuZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXyk7XG5cbiBcdFx0Ly8gRmxhZyB0aGUgbW9kdWxlIGFzIGxvYWRlZFxuIFx0XHRtb2R1bGUubCA9IHRydWU7XG5cbiBcdFx0Ly8gUmV0dXJuIHRoZSBleHBvcnRzIG9mIHRoZSBtb2R1bGVcbiBcdFx0cmV0dXJuIG1vZHVsZS5leHBvcnRzO1xuIFx0fVxuXG5cbiBcdC8vIGV4cG9zZSB0aGUgbW9kdWxlcyBvYmplY3QgKF9fd2VicGFja19tb2R1bGVzX18pXG4gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLm0gPSBtb2R1bGVzO1xuXG4gXHQvLyBleHBvc2UgdGhlIG1vZHVsZSBjYWNoZVxuIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5jID0gaW5zdGFsbGVkTW9kdWxlcztcblxuIFx0Ly8gZGVmaW5lIGdldHRlciBmdW5jdGlvbiBmb3IgaGFybW9ueSBleHBvcnRzXG4gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLmQgPSBmdW5jdGlvbihleHBvcnRzLCBuYW1lLCBnZXR0ZXIpIHtcbiBcdFx0aWYoIV9fd2VicGFja19yZXF1aXJlX18ubyhleHBvcnRzLCBuYW1lKSkge1xuIFx0XHRcdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBuYW1lLCB7XG4gXHRcdFx0XHRjb25maWd1cmFibGU6IGZhbHNlLFxuIFx0XHRcdFx0ZW51bWVyYWJsZTogdHJ1ZSxcbiBcdFx0XHRcdGdldDogZ2V0dGVyXG4gXHRcdFx0fSk7XG4gXHRcdH1cbiBcdH07XG5cbiBcdC8vIGdldERlZmF1bHRFeHBvcnQgZnVuY3Rpb24gZm9yIGNvbXBhdGliaWxpdHkgd2l0aCBub24taGFybW9ueSBtb2R1bGVzXG4gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLm4gPSBmdW5jdGlvbihtb2R1bGUpIHtcbiBcdFx0dmFyIGdldHRlciA9IG1vZHVsZSAmJiBtb2R1bGUuX19lc01vZHVsZSA/XG4gXHRcdFx0ZnVuY3Rpb24gZ2V0RGVmYXVsdCgpIHsgcmV0dXJuIG1vZHVsZVsnZGVmYXVsdCddOyB9IDpcbiBcdFx0XHRmdW5jdGlvbiBnZXRNb2R1bGVFeHBvcnRzKCkgeyByZXR1cm4gbW9kdWxlOyB9O1xuIFx0XHRfX3dlYnBhY2tfcmVxdWlyZV9fLmQoZ2V0dGVyLCAnYScsIGdldHRlcik7XG4gXHRcdHJldHVybiBnZXR0ZXI7XG4gXHR9O1xuXG4gXHQvLyBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGxcbiBcdF9fd2VicGFja19yZXF1aXJlX18ubyA9IGZ1bmN0aW9uKG9iamVjdCwgcHJvcGVydHkpIHsgcmV0dXJuIE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChvYmplY3QsIHByb3BlcnR5KTsgfTtcblxuIFx0Ly8gX193ZWJwYWNrX3B1YmxpY19wYXRoX19cbiBcdF9fd2VicGFja19yZXF1aXJlX18ucCA9IFwiL1wiO1xuXG4gXHQvLyBMb2FkIGVudHJ5IG1vZHVsZSBhbmQgcmV0dXJuIGV4cG9ydHNcbiBcdHJldHVybiBfX3dlYnBhY2tfcmVxdWlyZV9fKF9fd2VicGFja19yZXF1aXJlX18ucyA9IDI2KTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyB3ZWJwYWNrL2Jvb3RzdHJhcCAxYmVkNmFlYmViYjMxOTJiZTViNiIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcIndpbnN0b25cIik7XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gZXh0ZXJuYWwgXCJ3aW5zdG9uXCJcbi8vIG1vZHVsZSBpZCA9IDBcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiY29uc3QgbG9nZ2VyID0gcmVxdWlyZSgnd2luc3RvbicpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgaGFuZGxlRXJyb3JSZXNwb25zZTogZnVuY3Rpb24gKG9yaWdpbmFsVXJsLCBpcCwgZXJyb3IsIHJlcykge1xuICAgIGxvZ2dlci5lcnJvcihgRXJyb3Igb24gJHtvcmlnaW5hbFVybH1gLCBtb2R1bGUuZXhwb3J0cy51c2VPYmplY3RQcm9wZXJ0aWVzSWZOb0tleXMoZXJyb3IpKTtcbiAgICBjb25zdCBbc3RhdHVzLCBtZXNzYWdlXSA9IG1vZHVsZS5leHBvcnRzLnJldHVybkVycm9yTWVzc2FnZUFuZFN0YXR1cyhlcnJvcik7XG4gICAgcmVzXG4gICAgICAuc3RhdHVzKHN0YXR1cylcbiAgICAgIC5qc29uKG1vZHVsZS5leHBvcnRzLmNyZWF0ZUVycm9yUmVzcG9uc2VQYXlsb2FkKHN0YXR1cywgbWVzc2FnZSkpO1xuICB9LFxuICByZXR1cm5FcnJvck1lc3NhZ2VBbmRTdGF0dXM6IGZ1bmN0aW9uIChlcnJvcikge1xuICAgIGxldCBzdGF0dXMsIG1lc3NhZ2U7XG4gICAgLy8gY2hlY2sgZm9yIGRhZW1vbiBiZWluZyB0dXJuZWQgb2ZmXG4gICAgaWYgKGVycm9yLmNvZGUgPT09ICdFQ09OTlJFRlVTRUQnKSB7XG4gICAgICBzdGF0dXMgPSA1MDM7XG4gICAgICBtZXNzYWdlID0gJ0Nvbm5lY3Rpb24gcmVmdXNlZC4gIFRoZSBkYWVtb24gbWF5IG5vdCBiZSBydW5uaW5nLic7XG4gICAgICAvLyBmYWxsYmFjayBmb3IgZXZlcnl0aGluZyBlbHNlXG4gICAgfSBlbHNlIHtcbiAgICAgIHN0YXR1cyA9IDQwMDtcbiAgICAgIGlmIChlcnJvci5tZXNzYWdlKSB7XG4gICAgICAgIG1lc3NhZ2UgPSBlcnJvci5tZXNzYWdlO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbWVzc2FnZSA9IGVycm9yO1xuICAgICAgfTtcbiAgICB9O1xuICAgIHJldHVybiBbc3RhdHVzLCBtZXNzYWdlXTtcbiAgfSxcbiAgdXNlT2JqZWN0UHJvcGVydGllc0lmTm9LZXlzOiBmdW5jdGlvbiAoZXJyKSB7XG4gICAgaWYgKE9iamVjdC5rZXlzKGVycikubGVuZ3RoID09PSAwKSB7XG4gICAgICBsZXQgbmV3RXJyb3JPYmplY3QgPSB7fTtcbiAgICAgIE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzKGVycikuZm9yRWFjaCgoa2V5KSA9PiB7XG4gICAgICAgIG5ld0Vycm9yT2JqZWN0W2tleV0gPSBlcnJba2V5XTtcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIG5ld0Vycm9yT2JqZWN0O1xuICAgIH1cbiAgICByZXR1cm4gZXJyO1xuICB9LFxuICBjcmVhdGVFcnJvclJlc3BvbnNlUGF5bG9hZCAoc3RhdHVzLCBtZXNzYWdlKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHN0YXR1cyxcbiAgICAgIHN1Y2Nlc3M6IGZhbHNlLFxuICAgICAgbWVzc2FnZSxcbiAgICB9O1xuICB9LFxufTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL3NlcnZlci9oZWxwZXJzL2Vycm9ySGFuZGxlcnMuanMiLCJjb25zdCBDZXJ0aWZpY2F0ZSA9IHJlcXVpcmUoJ21vZGVscy9jZXJ0aWZpY2F0ZS5qcycpO1xuY29uc3QgQ2hhbm5lbCA9IHJlcXVpcmUoJ21vZGVscy9jaGFubmVsLmpzJyk7XG5jb25zdCBDbGFpbSA9IHJlcXVpcmUoJ21vZGVscy9jbGFpbS5qcycpO1xuY29uc3QgRmlsZSA9IHJlcXVpcmUoJ21vZGVscy9maWxlLmpzJyk7XG5jb25zdCBSZXF1ZXN0ID0gcmVxdWlyZSgnbW9kZWxzL3JlcXVlc3QuanMnKTtcbmNvbnN0IFVzZXIgPSByZXF1aXJlKCdtb2RlbHMvdXNlci5qcycpO1xuXG5jb25zdCBTZXF1ZWxpemUgPSByZXF1aXJlKCdzZXF1ZWxpemUnKTtcbmNvbnN0IGxvZ2dlciA9IHJlcXVpcmUoJ3dpbnN0b24nKTtcblxuY29uc3Qge2RhdGFiYXNlLCB1c2VybmFtZSwgcGFzc3dvcmR9ID0gcmVxdWlyZSgnbXlzcWxDb25maWcuanMnKTtcblxuLy8gc2V0IHNlcXVlbGl6ZSBvcHRpb25zXG5jb25zdCBzZXF1ZWxpemUgPSBuZXcgU2VxdWVsaXplKGRhdGFiYXNlLCB1c2VybmFtZSwgcGFzc3dvcmQsIHtcbiAgaG9zdCAgICAgICAgICA6ICdsb2NhbGhvc3QnLFxuICBkaWFsZWN0ICAgICAgIDogJ215c3FsJyxcbiAgZGlhbGVjdE9wdGlvbnM6IHtkZWNpbWFsTnVtYmVyczogdHJ1ZX0sXG4gIGxvZ2dpbmcgICAgICAgOiBmYWxzZSxcbiAgcG9vbCAgICAgICAgICA6IHtcbiAgICBtYXggICAgOiA1LFxuICAgIG1pbiAgICA6IDAsXG4gICAgaWRsZSAgIDogMTAwMDAsXG4gICAgYWNxdWlyZTogMTAwMDAsXG4gIH0sXG59KTtcblxuLy8gZXN0YWJsaXNoIG15c3FsIGNvbm5lY3Rpb25cbnNlcXVlbGl6ZVxuICAuYXV0aGVudGljYXRlKClcbiAgLnRoZW4oKCkgPT4ge1xuICAgIGxvZ2dlci5pbmZvKCdTZXF1ZWxpemUgaGFzIGVzdGFibGlzaGVkIG15c3FsIGNvbm5lY3Rpb24gc3VjY2Vzc2Z1bGx5LicpO1xuICB9KVxuICAuY2F0Y2goZXJyID0+IHtcbiAgICBsb2dnZXIuZXJyb3IoJ1NlcXVlbGl6ZSB3YXMgdW5hYmxlIHRvIGNvbm5lY3QgdG8gdGhlIGRhdGFiYXNlOicsIGVycik7XG4gIH0pO1xuXG4vLyBtYW51YWxseSBhZGQgZWFjaCBtb2RlbCB0byB0aGUgZGIgb2JqZWN0IChub3RlOiBtYWtlIHRoaXMgZHluYW1pYylcbmNvbnN0IGRiID0ge307XG5kYlsnQ2VydGlmaWNhdGUnXSA9IHNlcXVlbGl6ZS5pbXBvcnQoJ0NlcnRpZmljYXRlJywgQ2VydGlmaWNhdGUpO1xuZGJbJ0NoYW5uZWwnXSA9IHNlcXVlbGl6ZS5pbXBvcnQoJ0NoYW5uZWwnLCBDaGFubmVsKTtcbmRiWydDbGFpbSddID0gc2VxdWVsaXplLmltcG9ydCgnQ2xhaW0nLCBDbGFpbSk7XG5kYlsnRmlsZSddID0gc2VxdWVsaXplLmltcG9ydCgnRmlsZScsIEZpbGUpO1xuZGJbJ1JlcXVlc3QnXSA9IHNlcXVlbGl6ZS5pbXBvcnQoJ1JlcXVlc3QnLCBSZXF1ZXN0KTtcbmRiWydVc2VyJ10gPSBzZXF1ZWxpemUuaW1wb3J0KCdVc2VyJywgVXNlcik7XG5cbi8vIHJ1biBtb2RlbC5hc3NvY2lhdGlvbiBmb3IgZWFjaCBtb2RlbCBpbiB0aGUgZGIgb2JqZWN0IHRoYXQgaGFzIGFuIGFzc29jaWF0aW9uXG5sb2dnZXIuaW5mbygnYXNzb2NpYXRpbmcgZGIgbW9kZWxzLi4uJyk7XG5PYmplY3Qua2V5cyhkYikuZm9yRWFjaChtb2RlbE5hbWUgPT4ge1xuICBpZiAoZGJbbW9kZWxOYW1lXS5hc3NvY2lhdGUpIHtcbiAgICBsb2dnZXIuaW5mbygnQXNzb2NpYXRpbmcgbW9kZWw6JywgbW9kZWxOYW1lKTtcbiAgICBkYlttb2RlbE5hbWVdLmFzc29jaWF0ZShkYik7XG4gIH1cbn0pO1xuXG4vLyBhZGQgc2VxdWVsaXplL1NlcXVlbGl6ZSB0byBkYlxuZGIuc2VxdWVsaXplID0gc2VxdWVsaXplO1xuZGIuU2VxdWVsaXplID0gU2VxdWVsaXplO1xuLy8gYWRkIGFuICd1cHNlcnQnIG1ldGhvZCB0byB0aGUgZGIgb2JqZWN0XG5kYi51cHNlcnQgPSAoTW9kZWwsIHZhbHVlcywgY29uZGl0aW9uLCB0YWJsZU5hbWUpID0+IHtcbiAgcmV0dXJuIE1vZGVsXG4gICAgLmZpbmRPbmUoe1xuICAgICAgd2hlcmU6IGNvbmRpdGlvbixcbiAgICB9KVxuICAgIC50aGVuKG9iaiA9PiB7XG4gICAgICBpZiAob2JqKSB7ICAvLyB1cGRhdGVcbiAgICAgICAgbG9nZ2VyLmRlYnVnKGB1cGRhdGluZyByZWNvcmQgaW4gZGIuJHt0YWJsZU5hbWV9YCk7XG4gICAgICAgIHJldHVybiBvYmoudXBkYXRlKHZhbHVlcyk7XG4gICAgICB9IGVsc2UgeyAgLy8gaW5zZXJ0XG4gICAgICAgIGxvZ2dlci5kZWJ1ZyhgY3JlYXRpbmcgcmVjb3JkIGluIGRiLiR7dGFibGVOYW1lfWApO1xuICAgICAgICByZXR1cm4gTW9kZWwuY3JlYXRlKHZhbHVlcyk7XG4gICAgICB9XG4gICAgfSlcbiAgICAuY2F0Y2goZnVuY3Rpb24gKGVycm9yKSB7XG4gICAgICBsb2dnZXIuZXJyb3IoYCR7dGFibGVOYW1lfS51cHNlcnQgZXJyb3JgLCBlcnJvcik7XG4gICAgICB0aHJvdyBlcnJvcjtcbiAgICB9KTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gZGI7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9zZXJ2ZXIvbW9kZWxzL2luZGV4LmpzIiwiZnVuY3Rpb24gU2l0ZUNvbmZpZyAoKSB7XG4gIHRoaXMuYW5hbHl0aWNzID0ge1xuICAgIGdvb2dsZUlkOiAnZGVmYXVsdCcsXG4gIH07XG4gIHRoaXMuYXNzZXREZWZhdWx0cyA9IHtcbiAgICBkZXNjcmlwdGlvbjogJ0FuIGFzc2V0IHB1Ymxpc2hlZCBvbiBTcGVlLmNoJyxcbiAgICB0aHVtYm5haWwgIDogJ2h0dHBzOi8vc3BlZS5jaC9hc3NldHMvaW1nL3ZpZGVvX3RodW1iX2RlZmF1bHQucG5nJyxcbiAgICB0aXRsZSAgICAgIDogJ1NwZWUuY2gnLFxuICB9O1xuICB0aGlzLmF1dGggPSB7XG4gICAgc2Vzc2lvbktleTogJ2RlZmF1bHQnLFxuICB9O1xuICB0aGlzLmN1c3RvbUNvbXBvbmVudHMgPSB7fTtcbiAgdGhpcy5jdXN0b21Db250YWluZXJzID0ge307XG4gIHRoaXMuY3VzdG9tUGFnZXMgPSB7fTtcbiAgdGhpcy5kZXRhaWxzID0ge1xuICAgIGRlc2NyaXB0aW9uOiAnT3Blbi1zb3VyY2UsIGRlY2VudHJhbGl6ZWQgaW1hZ2UgYW5kIHZpZGVvIHNoYXJpbmcuJyxcbiAgICBob3N0ICAgICAgIDogJ2RlZmF1bHQnLFxuICAgIHBvcnQgICAgICAgOiAzMDAwLFxuICAgIHRpdGxlICAgICAgOiAnU3BlZS5jaCcsXG4gICAgdHdpdHRlciAgICA6ICdAc3BlZV9jaCcsXG4gIH07XG4gIHRoaXMucHVibGlzaGluZyA9IHtcbiAgICBhZGRpdGlvbmFsQ2xhaW1BZGRyZXNzZXM6IFtdLFxuICAgIGRpc2FibGVkICAgICAgICAgICAgICAgIDogZmFsc2UsXG4gICAgZGlzYWJsZWRNZXNzYWdlICAgICAgICAgOiAnUGxlYXNlIGNoZWNrIGJhY2sgc29vbi4nLFxuICAgIHByaW1hcnlDbGFpbUFkZHJlc3MgICAgIDogJ2RlZmF1bHQnLFxuICAgIHRodW1ibmFpbENoYW5uZWwgICAgICAgIDogJ2RlZmF1bHQnLFxuICAgIHRodW1ibmFpbENoYW5uZWxJZCAgICAgIDogJ2RlZmF1bHQnLFxuICAgIHVwbG9hZERpcmVjdG9yeSAgICAgICAgIDogJy9ob21lL2xicnkvVXBsb2FkcycsXG4gIH07XG4gIHRoaXMucm91dGVzID0ge307XG4gIHRoaXMudXBkYXRlID0gKGNvbmZpZykgPT4ge1xuICAgIGlmICghY29uZmlnKSB7XG4gICAgICByZXR1cm4gY29uc29sZS5sb2coJ05vIHNpdGUgY29uZmlnIHJlY2VpdmVkLicpO1xuICAgIH1cbiAgICBjb25zdCB7IGFuYWx5dGljcywgYXNzZXREZWZhdWx0cywgYXV0aCwgY3VzdG9tQ29tcG9uZW50cywgY3VzdG9tQ29udGFpbmVycywgY3VzdG9tUGFnZXMsIGRldGFpbHMsIHB1Ymxpc2hpbmcsIHJvdXRlcyB9ID0gY29uZmlnO1xuICAgIGNvbnNvbGUubG9nKCdDb25maWd1cmluZyBzaXRlIGRldGFpbHMuLi4nKTtcbiAgICB0aGlzLmFuYWx5dGljcyA9IGFuYWx5dGljcztcbiAgICB0aGlzLmFzc2V0RGVmYXVsdHMgPSBhc3NldERlZmF1bHRzO1xuICAgIHRoaXMuYXV0aCA9IGF1dGg7XG4gICAgdGhpcy5kZXRhaWxzID0gZGV0YWlscztcbiAgICB0aGlzLnB1Ymxpc2hpbmcgPSBwdWJsaXNoaW5nO1xuICAgIHRoaXMuY3VzdG9tQ29tcG9uZW50cyA9IGN1c3RvbUNvbXBvbmVudHM7XG4gICAgdGhpcy5jdXN0b21Db250YWluZXJzID0gY3VzdG9tQ29udGFpbmVycztcbiAgICB0aGlzLmN1c3RvbVBhZ2VzID0gY3VzdG9tUGFnZXM7XG4gICAgdGhpcy5yb3V0ZXMgPSByb3V0ZXM7XG4gIH07XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IG5ldyBTaXRlQ29uZmlnKCk7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9jb25maWcvc2l0ZUNvbmZpZy5qcyIsImNvbnN0IGxvZ2dlciA9IHJlcXVpcmUoJ3dpbnN0b24nKTtcbmNvbnN0IHVhID0gcmVxdWlyZSgndW5pdmVyc2FsLWFuYWx5dGljcycpO1xuY29uc3QgeyBhbmFseXRpY3MgOiB7IGdvb2dsZUlkIH0sIGRldGFpbHM6IHsgdGl0bGUgfSB9ID0gcmVxdWlyZSgnLi4vLi4vY29uZmlnL3NpdGVDb25maWcuanMnKTtcblxuZnVuY3Rpb24gY3JlYXRlU2VydmVFdmVudFBhcmFtcyAoaGVhZGVycywgaXAsIG9yaWdpbmFsVXJsKSB7XG4gIHJldHVybiB7XG4gICAgZXZlbnRDYXRlZ29yeSAgICA6ICdjbGllbnQgcmVxdWVzdHMnLFxuICAgIGV2ZW50QWN0aW9uICAgICAgOiAnc2VydmUgcmVxdWVzdCcsXG4gICAgZXZlbnRMYWJlbCAgICAgICA6IG9yaWdpbmFsVXJsLFxuICAgIGlwT3ZlcnJpZGUgICAgICAgOiBpcCxcbiAgICB1c2VyQWdlbnRPdmVycmlkZTogaGVhZGVyc1sndXNlci1hZ2VudCddLFxuICB9O1xufTtcblxuZnVuY3Rpb24gY3JlYXRlUHVibGlzaFRpbWluZ0V2ZW50UGFyYW1zIChjYXRlZ29yeSwgdmFyaWFibGUsIGxhYmVsLCBzdGFydFRpbWUsIGVuZFRpbWUpIHtcbiAgY29uc3QgZHVyYXRpb24gPSBlbmRUaW1lIC0gc3RhcnRUaW1lO1xuICByZXR1cm4ge1xuICAgIHVzZXJUaW1pbmdDYXRlZ29yeSAgICA6IGNhdGVnb3J5LFxuICAgIHVzZXJUaW1pbmdWYXJpYWJsZU5hbWU6IHZhcmlhYmxlLFxuICAgIHVzZXJUaW1pbmdUaW1lICAgICAgICA6IGR1cmF0aW9uLFxuICAgIHVzZXJUaW1pbmdMYWJlbCAgICAgICA6IGxhYmVsLFxuICB9O1xufTtcblxuZnVuY3Rpb24gc2VuZEdvb2dsZUFuYWx5dGljc0V2ZW50IChpcCwgcGFyYW1zKSB7XG4gIGNvbnN0IHZpc2l0b3JJZCA9IGlwLnJlcGxhY2UoL1xcLi9nLCAnLScpO1xuICBjb25zdCB2aXNpdG9yID0gdWEoZ29vZ2xlSWQsIHZpc2l0b3JJZCwgeyBzdHJpY3RDaWRGb3JtYXQ6IGZhbHNlLCBodHRwczogdHJ1ZSB9KTtcbiAgdmlzaXRvci5ldmVudChwYXJhbXMsIChlcnIpID0+IHtcbiAgICBpZiAoZXJyKSB7XG4gICAgICBsb2dnZXIuZXJyb3IoJ0dvb2dsZSBBbmFseXRpY3MgRXZlbnQgRXJyb3IgPj4nLCBlcnIpO1xuICAgIH1cbiAgfSk7XG59O1xuXG5mdW5jdGlvbiBzZW5kR29vZ2xlQW5hbHl0aWNzVGltaW5nICh2aXNpdG9ySWQsIHBhcmFtcykge1xuICBjb25zdCB2aXNpdG9yID0gdWEoZ29vZ2xlSWQsIHZpc2l0b3JJZCwgeyBzdHJpY3RDaWRGb3JtYXQ6IGZhbHNlLCBodHRwczogdHJ1ZSB9KTtcbiAgdmlzaXRvci50aW1pbmcocGFyYW1zLCAoZXJyKSA9PiB7XG4gICAgaWYgKGVycikge1xuICAgICAgbG9nZ2VyLmVycm9yKCdHb29nbGUgQW5hbHl0aWNzIEV2ZW50IEVycm9yID4+JywgZXJyKTtcbiAgICB9XG4gICAgbG9nZ2VyLmRlYnVnKGBUaW1pbmcgZXZlbnQgc3VjY2Vzc2Z1bGx5IHNlbnQgdG8gZ29vZ2xlIGFuYWx5dGljc2ApO1xuICB9KTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICBzZW5kR0FTZXJ2ZUV2ZW50IChoZWFkZXJzLCBpcCwgb3JpZ2luYWxVcmwpIHtcbiAgICBjb25zdCBwYXJhbXMgPSBjcmVhdGVTZXJ2ZUV2ZW50UGFyYW1zKGhlYWRlcnMsIGlwLCBvcmlnaW5hbFVybCk7XG4gICAgc2VuZEdvb2dsZUFuYWx5dGljc0V2ZW50KGlwLCBwYXJhbXMpO1xuICB9LFxuICBzZW5kR0FUaW1pbmdFdmVudCAoY2F0ZWdvcnksIHZhcmlhYmxlLCBsYWJlbCwgc3RhcnRUaW1lLCBlbmRUaW1lKSB7XG4gICAgY29uc3QgcGFyYW1zID0gY3JlYXRlUHVibGlzaFRpbWluZ0V2ZW50UGFyYW1zKGNhdGVnb3J5LCB2YXJpYWJsZSwgbGFiZWwsIHN0YXJ0VGltZSwgZW5kVGltZSk7XG4gICAgc2VuZEdvb2dsZUFuYWx5dGljc1RpbWluZyh0aXRsZSwgcGFyYW1zKTtcbiAgfSxcbiAgY2hvb3NlR2FMYnJ5bmV0UHVibGlzaExhYmVsICh7IGNoYW5uZWxfbmFtZTogY2hhbm5lbE5hbWUsIGNoYW5uZWxfaWQ6IGNoYW5uZWxJZCB9KSB7XG4gICAgcmV0dXJuIChjaGFubmVsTmFtZSB8fCBjaGFubmVsSWQgPyAnUFVCTElTSF9JTl9DSEFOTkVMX0NMQUlNJyA6ICdQVUJMSVNIX0FOT05ZTU9VU19DTEFJTScpO1xuICB9LFxufTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL3NlcnZlci9oZWxwZXJzL2dvb2dsZUFuYWx5dGljcy5qcyIsImNvbnN0IGF4aW9zID0gcmVxdWlyZSgnYXhpb3MnKTtcbmNvbnN0IGxvZ2dlciA9IHJlcXVpcmUoJ3dpbnN0b24nKTtcbmNvbnN0IHsgYXBpOiB7IGFwaUhvc3QsIGFwaVBvcnQgfSB9ID0gcmVxdWlyZSgnLi4vLi4vY29uZmlnL2xicnlDb25maWcuanMnKTtcbmNvbnN0IGxicnlBcGlVcmkgPSAnaHR0cDovLycgKyBhcGlIb3N0ICsgJzonICsgYXBpUG9ydDtcbmNvbnN0IHsgY2hvb3NlR2FMYnJ5bmV0UHVibGlzaExhYmVsLCBzZW5kR0FUaW1pbmdFdmVudCB9ID0gcmVxdWlyZSgnLi9nb29nbGVBbmFseXRpY3MuanMnKTtcblxuY29uc3QgaGFuZGxlTGJyeW5ldFJlc3BvbnNlID0gKHsgZGF0YSB9LCByZXNvbHZlLCByZWplY3QpID0+IHtcbiAgbG9nZ2VyLmRlYnVnKCdsYnJ5IGFwaSBkYXRhOicsIGRhdGEpO1xuICBpZiAoZGF0YS5yZXN1bHQpIHtcbiAgICAvLyBjaGVjayBmb3IgYW4gZXJyb3JcbiAgICBpZiAoZGF0YS5yZXN1bHQuZXJyb3IpIHtcbiAgICAgIGxvZ2dlci5kZWJ1ZygnTGJyeW5ldCBhcGkgZXJyb3I6JywgZGF0YS5yZXN1bHQuZXJyb3IpO1xuICAgICAgcmVqZWN0KG5ldyBFcnJvcihkYXRhLnJlc3VsdC5lcnJvcikpO1xuICAgICAgcmV0dXJuO1xuICAgIH07XG4gICAgcmVzb2x2ZShkYXRhLnJlc3VsdCk7XG4gICAgcmV0dXJuO1xuICB9XG4gIC8vIGZhbGxiYWNrIGluIGNhc2UgaXQganVzdCB0aW1lZCBvdXRcbiAgcmVqZWN0KEpTT04uc3RyaW5naWZ5KGRhdGEpKTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICBwdWJsaXNoQ2xhaW0gKHB1Ymxpc2hQYXJhbXMpIHtcbiAgICBsb2dnZXIuZGVidWcoYGxicnlBcGkgPj4gUHVibGlzaGluZyBjbGFpbSB0byBcIiR7cHVibGlzaFBhcmFtcy5uYW1lfVwiYCk7XG4gICAgY29uc3QgZ2FTdGFydFRpbWUgPSBEYXRlLm5vdygpO1xuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICBheGlvc1xuICAgICAgICAucG9zdChsYnJ5QXBpVXJpLCB7XG4gICAgICAgICAgbWV0aG9kOiAncHVibGlzaCcsXG4gICAgICAgICAgcGFyYW1zOiBwdWJsaXNoUGFyYW1zLFxuICAgICAgICB9KVxuICAgICAgICAudGhlbihyZXNwb25zZSA9PiB7XG4gICAgICAgICAgc2VuZEdBVGltaW5nRXZlbnQoJ2xicnluZXQnLCAncHVibGlzaCcsIGNob29zZUdhTGJyeW5ldFB1Ymxpc2hMYWJlbChwdWJsaXNoUGFyYW1zKSwgZ2FTdGFydFRpbWUsIERhdGUubm93KCkpO1xuICAgICAgICAgIGhhbmRsZUxicnluZXRSZXNwb25zZShyZXNwb25zZSwgcmVzb2x2ZSwgcmVqZWN0KTtcbiAgICAgICAgfSlcbiAgICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICB9KTtcbiAgICB9KTtcbiAgfSxcbiAgZ2V0Q2xhaW0gKHVyaSkge1xuICAgIGxvZ2dlci5kZWJ1ZyhgbGJyeUFwaSA+PiBHZXR0aW5nIENsYWltIGZvciBcIiR7dXJpfVwiYCk7XG4gICAgY29uc3QgZ2FTdGFydFRpbWUgPSBEYXRlLm5vdygpO1xuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICBheGlvc1xuICAgICAgICAucG9zdChsYnJ5QXBpVXJpLCB7XG4gICAgICAgICAgbWV0aG9kOiAnZ2V0JyxcbiAgICAgICAgICBwYXJhbXM6IHsgdXJpLCB0aW1lb3V0OiAyMCB9LFxuICAgICAgICB9KVxuICAgICAgICAudGhlbihyZXNwb25zZSA9PiB7XG4gICAgICAgICAgc2VuZEdBVGltaW5nRXZlbnQoJ2xicnluZXQnLCAnZ2V0Q2xhaW0nLCAnR0VUJywgZ2FTdGFydFRpbWUsIERhdGUubm93KCkpO1xuICAgICAgICAgIGhhbmRsZUxicnluZXRSZXNwb25zZShyZXNwb25zZSwgcmVzb2x2ZSwgcmVqZWN0KTtcbiAgICAgICAgfSlcbiAgICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICB9KTtcbiAgICB9KTtcbiAgfSxcbiAgZ2V0Q2xhaW1MaXN0IChjbGFpbU5hbWUpIHtcbiAgICBsb2dnZXIuZGVidWcoYGxicnlBcGkgPj4gR2V0dGluZyBjbGFpbV9saXN0IGZvciBcIiR7Y2xhaW1OYW1lfVwiYCk7XG4gICAgY29uc3QgZ2FTdGFydFRpbWUgPSBEYXRlLm5vdygpO1xuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICBheGlvc1xuICAgICAgICAucG9zdChsYnJ5QXBpVXJpLCB7XG4gICAgICAgICAgbWV0aG9kOiAnY2xhaW1fbGlzdCcsXG4gICAgICAgICAgcGFyYW1zOiB7IG5hbWU6IGNsYWltTmFtZSB9LFxuICAgICAgICB9KVxuICAgICAgICAudGhlbihyZXNwb25zZSA9PiB7XG4gICAgICAgICAgc2VuZEdBVGltaW5nRXZlbnQoJ2xicnluZXQnLCAnZ2V0Q2xhaW1MaXN0JywgJ0NMQUlNX0xJU1QnLCBnYVN0YXJ0VGltZSwgRGF0ZS5ub3coKSk7XG4gICAgICAgICAgaGFuZGxlTGJyeW5ldFJlc3BvbnNlKHJlc3BvbnNlLCByZXNvbHZlLCByZWplY3QpO1xuICAgICAgICB9KVxuICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgIH0pO1xuICAgIH0pO1xuICB9LFxuICByZXNvbHZlVXJpICh1cmkpIHtcbiAgICBsb2dnZXIuZGVidWcoYGxicnlBcGkgPj4gUmVzb2x2aW5nIFVSSSBmb3IgXCIke3VyaX1cImApO1xuICAgIGNvbnN0IGdhU3RhcnRUaW1lID0gRGF0ZS5ub3coKTtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgYXhpb3NcbiAgICAgICAgLnBvc3QobGJyeUFwaVVyaSwge1xuICAgICAgICAgIG1ldGhvZDogJ3Jlc29sdmUnLFxuICAgICAgICAgIHBhcmFtczogeyB1cmkgfSxcbiAgICAgICAgfSlcbiAgICAgICAgLnRoZW4oKHsgZGF0YSB9KSA9PiB7XG4gICAgICAgICAgc2VuZEdBVGltaW5nRXZlbnQoJ2xicnluZXQnLCAncmVzb2x2ZVVyaScsICdSRVNPTFZFJywgZ2FTdGFydFRpbWUsIERhdGUubm93KCkpO1xuICAgICAgICAgIGlmIChkYXRhLnJlc3VsdFt1cmldLmVycm9yKSB7ICAvLyBjaGVjayBmb3IgZXJyb3JzXG4gICAgICAgICAgICByZWplY3QoZGF0YS5yZXN1bHRbdXJpXS5lcnJvcik7XG4gICAgICAgICAgfSBlbHNlIHsgIC8vIGlmIG5vIGVycm9ycywgcmVzb2x2ZVxuICAgICAgICAgICAgcmVzb2x2ZShkYXRhLnJlc3VsdFt1cmldKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pXG4gICAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgfSk7XG4gICAgfSk7XG4gIH0sXG4gIGdldERvd25sb2FkRGlyZWN0b3J5ICgpIHtcbiAgICBsb2dnZXIuZGVidWcoJ2xicnlBcGkgPj4gUmV0cmlldmluZyB0aGUgZG93bmxvYWQgZGlyZWN0b3J5IHBhdGggZnJvbSBsYnJ5IGRhZW1vbi4uLicpO1xuICAgIGNvbnN0IGdhU3RhcnRUaW1lID0gRGF0ZS5ub3coKTtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgYXhpb3NcbiAgICAgICAgLnBvc3QobGJyeUFwaVVyaSwge1xuICAgICAgICAgIG1ldGhvZDogJ3NldHRpbmdzX2dldCcsXG4gICAgICAgIH0pXG4gICAgICAgIC50aGVuKCh7IGRhdGEgfSkgPT4ge1xuICAgICAgICAgIHNlbmRHQVRpbWluZ0V2ZW50KCdsYnJ5bmV0JywgJ2dldERvd25sb2FkRGlyZWN0b3J5JywgJ1NFVFRJTkdTX0dFVCcsIGdhU3RhcnRUaW1lLCBEYXRlLm5vdygpKTtcbiAgICAgICAgICBpZiAoZGF0YS5yZXN1bHQpIHtcbiAgICAgICAgICAgIHJlc29sdmUoZGF0YS5yZXN1bHQuZG93bmxvYWRfZGlyZWN0b3J5KTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBFcnJvcignU3VjY2Vzc2Z1bGx5IGNvbm5lY3RlZCB0byBsYnJ5IGRhZW1vbiwgYnV0IHVuYWJsZSB0byByZXRyaWV2ZSB0aGUgZG93bmxvYWQgZGlyZWN0b3J5LicpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSlcbiAgICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICBsb2dnZXIuZXJyb3IoJ0xicnluZXQgRXJyb3I6JywgZXJyb3IpO1xuICAgICAgICAgIHJlc29sdmUoJy9ob21lL2xicnkvRG93bmxvYWRzLycpO1xuICAgICAgICB9KTtcbiAgICB9KTtcbiAgfSxcbiAgY3JlYXRlQ2hhbm5lbCAobmFtZSkge1xuICAgIGxvZ2dlci5kZWJ1ZyhgbGJyeUFwaSA+PiBDcmVhdGluZyBjaGFubmVsIGZvciAke25hbWV9Li4uYCk7XG4gICAgY29uc3QgZ2FTdGFydFRpbWUgPSBEYXRlLm5vdygpO1xuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICBheGlvc1xuICAgICAgICAucG9zdChsYnJ5QXBpVXJpLCB7XG4gICAgICAgICAgbWV0aG9kOiAnY2hhbm5lbF9uZXcnLFxuICAgICAgICAgIHBhcmFtczoge1xuICAgICAgICAgICAgY2hhbm5lbF9uYW1lOiBuYW1lLFxuICAgICAgICAgICAgYW1vdW50ICAgICAgOiAwLjEsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSlcbiAgICAgICAgLnRoZW4ocmVzcG9uc2UgPT4ge1xuICAgICAgICAgIHNlbmRHQVRpbWluZ0V2ZW50KCdsYnJ5bmV0JywgJ2NyZWF0ZUNoYW5uZWwnLCAnQ0hBTk5FTF9ORVcnLCBnYVN0YXJ0VGltZSwgRGF0ZS5ub3coKSk7XG4gICAgICAgICAgaGFuZGxlTGJyeW5ldFJlc3BvbnNlKHJlc3BvbnNlLCByZXNvbHZlLCByZWplY3QpO1xuICAgICAgICB9KVxuICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgIH0pO1xuICAgIH0pO1xuICB9LFxufTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL3NlcnZlci9oZWxwZXJzL2xicnlBcGkuanMiLCJjb25zdCBkYiA9IHJlcXVpcmUoJ21vZGVscycpO1xuY29uc3QgbG9nZ2VyID0gcmVxdWlyZSgnd2luc3RvbicpO1xuY29uc3QgeyByZXR1cm5QYWdpbmF0ZWRDaGFubmVsQ2xhaW1zIH0gPSByZXF1aXJlKCdoZWxwZXJzL2NoYW5uZWxQYWdpbmF0aW9uLmpzJyk7XG5cbmNvbnN0IE5PX0NIQU5ORUwgPSAnTk9fQ0hBTk5FTCc7XG5jb25zdCBOT19DTEFJTSA9ICdOT19DTEFJTSc7XG5jb25zdCBOT19GSUxFID0gJ05PX0ZJTEUnO1xuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgZ2V0Q2xhaW1JZCAoY2hhbm5lbE5hbWUsIGNoYW5uZWxDbGFpbUlkLCBuYW1lLCBjbGFpbUlkKSB7XG4gICAgaWYgKGNoYW5uZWxOYW1lKSB7XG4gICAgICByZXR1cm4gbW9kdWxlLmV4cG9ydHMuZ2V0Q2xhaW1JZEJ5Q2hhbm5lbChjaGFubmVsTmFtZSwgY2hhbm5lbENsYWltSWQsIG5hbWUpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gbW9kdWxlLmV4cG9ydHMuZ2V0Q2xhaW1JZEJ5Q2xhaW0obmFtZSwgY2xhaW1JZCk7XG4gICAgfVxuICB9LFxuICBnZXRDbGFpbUlkQnlDbGFpbSAoY2xhaW1OYW1lLCBjbGFpbUlkKSB7XG4gICAgbG9nZ2VyLmRlYnVnKGBnZXRDbGFpbUlkQnlDbGFpbSgke2NsYWltTmFtZX0sICR7Y2xhaW1JZH0pYCk7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIGRiLkNsYWltLmdldExvbmdDbGFpbUlkKGNsYWltTmFtZSwgY2xhaW1JZClcbiAgICAgICAgLnRoZW4obG9uZ0NsYWltSWQgPT4ge1xuICAgICAgICAgIGlmICghbG9uZ0NsYWltSWQpIHtcbiAgICAgICAgICAgIHJlc29sdmUoTk9fQ0xBSU0pO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXNvbHZlKGxvbmdDbGFpbUlkKTtcbiAgICAgICAgfSlcbiAgICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICB9KTtcbiAgICB9KTtcbiAgfSxcbiAgZ2V0Q2xhaW1JZEJ5Q2hhbm5lbCAoY2hhbm5lbE5hbWUsIGNoYW5uZWxDbGFpbUlkLCBjbGFpbU5hbWUpIHtcbiAgICBsb2dnZXIuZGVidWcoYGdldENsYWltSWRCeUNoYW5uZWwoJHtjaGFubmVsTmFtZX0sICR7Y2hhbm5lbENsYWltSWR9LCAke2NsYWltTmFtZX0pYCk7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIGRiLkNlcnRpZmljYXRlLmdldExvbmdDaGFubmVsSWQoY2hhbm5lbE5hbWUsIGNoYW5uZWxDbGFpbUlkKSAvLyAxLiBnZXQgdGhlIGxvbmcgY2hhbm5lbCBpZFxuICAgICAgICAudGhlbihsb25nQ2hhbm5lbElkID0+IHtcbiAgICAgICAgICBpZiAoIWxvbmdDaGFubmVsSWQpIHtcbiAgICAgICAgICAgIHJldHVybiBbbnVsbCwgbnVsbF07XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiBQcm9taXNlLmFsbChbbG9uZ0NoYW5uZWxJZCwgZGIuQ2xhaW0uZ2V0Q2xhaW1JZEJ5TG9uZ0NoYW5uZWxJZChsb25nQ2hhbm5lbElkLCBjbGFpbU5hbWUpXSk7ICAvLyAyLiBnZXQgdGhlIGxvbmcgY2xhaW0gaWRcbiAgICAgICAgfSlcbiAgICAgICAgLnRoZW4oKFtsb25nQ2hhbm5lbElkLCBsb25nQ2xhaW1JZF0pID0+IHtcbiAgICAgICAgICBpZiAoIWxvbmdDaGFubmVsSWQpIHtcbiAgICAgICAgICAgIHJldHVybiByZXNvbHZlKE5PX0NIQU5ORUwpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoIWxvbmdDbGFpbUlkKSB7XG4gICAgICAgICAgICByZXR1cm4gcmVzb2x2ZShOT19DTEFJTSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJlc29sdmUobG9uZ0NsYWltSWQpO1xuICAgICAgICB9KVxuICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgIH0pO1xuICAgIH0pO1xuICB9LFxuICBnZXRDaGFubmVsRGF0YSAoY2hhbm5lbE5hbWUsIGNoYW5uZWxDbGFpbUlkLCBwYWdlKSB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIC8vIDEuIGdldCB0aGUgbG9uZyBjaGFubmVsIElkIChtYWtlIHN1cmUgY2hhbm5lbCBleGlzdHMpXG4gICAgICBkYi5DZXJ0aWZpY2F0ZS5nZXRMb25nQ2hhbm5lbElkKGNoYW5uZWxOYW1lLCBjaGFubmVsQ2xhaW1JZClcbiAgICAgICAgLnRoZW4obG9uZ0NoYW5uZWxDbGFpbUlkID0+IHtcbiAgICAgICAgICBpZiAoIWxvbmdDaGFubmVsQ2xhaW1JZCkge1xuICAgICAgICAgICAgcmV0dXJuIFtudWxsLCBudWxsLCBudWxsXTtcbiAgICAgICAgICB9XG4gICAgICAgICAgLy8gMi4gZ2V0IHRoZSBzaG9ydCBJRCBhbmQgYWxsIGNsYWltcyBmb3IgdGhhdCBjaGFubmVsXG4gICAgICAgICAgcmV0dXJuIFByb21pc2UuYWxsKFtsb25nQ2hhbm5lbENsYWltSWQsIGRiLkNlcnRpZmljYXRlLmdldFNob3J0Q2hhbm5lbElkRnJvbUxvbmdDaGFubmVsSWQobG9uZ0NoYW5uZWxDbGFpbUlkLCBjaGFubmVsTmFtZSldKTtcbiAgICAgICAgfSlcbiAgICAgICAgLnRoZW4oKFtsb25nQ2hhbm5lbENsYWltSWQsIHNob3J0Q2hhbm5lbENsYWltSWRdKSA9PiB7XG4gICAgICAgICAgaWYgKCFsb25nQ2hhbm5lbENsYWltSWQpIHtcbiAgICAgICAgICAgIHJldHVybiByZXNvbHZlKE5PX0NIQU5ORUwpO1xuICAgICAgICAgIH1cbiAgICAgICAgICAvLyAzLiByZXR1cm4gYWxsIHRoZSBjaGFubmVsIGluZm9ybWF0aW9uXG4gICAgICAgICAgcmVzb2x2ZSh7XG4gICAgICAgICAgICBjaGFubmVsTmFtZSxcbiAgICAgICAgICAgIGxvbmdDaGFubmVsQ2xhaW1JZCxcbiAgICAgICAgICAgIHNob3J0Q2hhbm5lbENsYWltSWQsXG4gICAgICAgICAgfSk7XG4gICAgICAgIH0pXG4gICAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgfSk7XG4gICAgfSk7XG4gIH0sXG4gIGdldENoYW5uZWxDbGFpbXMgKGNoYW5uZWxOYW1lLCBjaGFubmVsQ2xhaW1JZCwgcGFnZSkge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAvLyAxLiBnZXQgdGhlIGxvbmcgY2hhbm5lbCBJZCAobWFrZSBzdXJlIGNoYW5uZWwgZXhpc3RzKVxuICAgICAgZGIuQ2VydGlmaWNhdGUuZ2V0TG9uZ0NoYW5uZWxJZChjaGFubmVsTmFtZSwgY2hhbm5lbENsYWltSWQpXG4gICAgICAgIC50aGVuKGxvbmdDaGFubmVsQ2xhaW1JZCA9PiB7XG4gICAgICAgICAgaWYgKCFsb25nQ2hhbm5lbENsYWltSWQpIHtcbiAgICAgICAgICAgIHJldHVybiBbbnVsbCwgbnVsbCwgbnVsbF07XG4gICAgICAgICAgfVxuICAgICAgICAgIC8vIDIuIGdldCB0aGUgc2hvcnQgSUQgYW5kIGFsbCBjbGFpbXMgZm9yIHRoYXQgY2hhbm5lbFxuICAgICAgICAgIHJldHVybiBQcm9taXNlLmFsbChbbG9uZ0NoYW5uZWxDbGFpbUlkLCBkYi5DbGFpbS5nZXRBbGxDaGFubmVsQ2xhaW1zKGxvbmdDaGFubmVsQ2xhaW1JZCldKTtcbiAgICAgICAgfSlcbiAgICAgICAgLnRoZW4oKFtsb25nQ2hhbm5lbENsYWltSWQsIGNoYW5uZWxDbGFpbXNBcnJheV0pID0+IHtcbiAgICAgICAgICBpZiAoIWxvbmdDaGFubmVsQ2xhaW1JZCkge1xuICAgICAgICAgICAgcmV0dXJuIHJlc29sdmUoTk9fQ0hBTk5FTCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIC8vIDMuIGZvcm1hdCB0aGUgZGF0YSBmb3IgdGhlIHZpZXcsIGluY2x1ZGluZyBwYWdpbmF0aW9uXG4gICAgICAgICAgbGV0IHBhZ2luYXRlZENoYW5uZWxWaWV3RGF0YSA9IHJldHVyblBhZ2luYXRlZENoYW5uZWxDbGFpbXMoY2hhbm5lbE5hbWUsIGxvbmdDaGFubmVsQ2xhaW1JZCwgY2hhbm5lbENsYWltc0FycmF5LCBwYWdlKTtcbiAgICAgICAgICAvLyA0LiByZXR1cm4gYWxsIHRoZSBjaGFubmVsIGluZm9ybWF0aW9uIGFuZCBjb250ZW50c1xuICAgICAgICAgIHJlc29sdmUocGFnaW5hdGVkQ2hhbm5lbFZpZXdEYXRhKTtcbiAgICAgICAgfSlcbiAgICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICB9KTtcbiAgICB9KTtcbiAgfSxcbiAgZ2V0TG9jYWxGaWxlUmVjb3JkIChjbGFpbUlkLCBuYW1lKSB7XG4gICAgcmV0dXJuIGRiLkZpbGUuZmluZE9uZSh7d2hlcmU6IHtjbGFpbUlkLCBuYW1lfX0pXG4gICAgICAudGhlbihmaWxlID0+IHtcbiAgICAgICAgaWYgKCFmaWxlKSB7XG4gICAgICAgICAgcmV0dXJuIE5PX0ZJTEU7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZpbGUuZGF0YVZhbHVlcztcbiAgICAgIH0pO1xuICB9LFxufTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL3NlcnZlci9jb250cm9sbGVycy9zZXJ2ZUNvbnRyb2xsZXIuanMiLCJjb25zdCBwYXNzcG9ydCA9IHJlcXVpcmUoJ3Bhc3Nwb3J0Jyk7XG5jb25zdCBsb2NhbExvZ2luU3RyYXRlZ3kgPSByZXF1aXJlKCcuL2xvY2FsLWxvZ2luLmpzJyk7XG5jb25zdCBsb2NhbFNpZ251cFN0cmF0ZWd5ID0gcmVxdWlyZSgnLi9sb2NhbC1zaWdudXAuanMnKTtcbmNvbnN0IHsgc2VyaWFsaXplU3BlZWNoVXNlciwgZGVzZXJpYWxpemVTcGVlY2hVc2VyIH0gPSByZXF1aXJlKCdoZWxwZXJzL2F1dGhIZWxwZXJzLmpzJyk7XG5cbnBhc3Nwb3J0LmRlc2VyaWFsaXplVXNlcihkZXNlcmlhbGl6ZVNwZWVjaFVzZXIpO1xucGFzc3BvcnQuc2VyaWFsaXplVXNlcihzZXJpYWxpemVTcGVlY2hVc2VyKTtcbnBhc3Nwb3J0LnVzZSgnbG9jYWwtbG9naW4nLCBsb2NhbExvZ2luU3RyYXRlZ3kpO1xucGFzc3BvcnQudXNlKCdsb2NhbC1zaWdudXAnLCBsb2NhbFNpZ251cFN0cmF0ZWd5KTtcblxubW9kdWxlLmV4cG9ydHMgPSBwYXNzcG9ydDtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL3NlcnZlci9zcGVlY2hQYXNzcG9ydC9pbmRleC5qcyIsImNvbnN0IGxvZ2dlciA9IHJlcXVpcmUoJ3dpbnN0b24nKTtcbmNvbnN0IGRiID0gcmVxdWlyZSgnbW9kZWxzJyk7XG5jb25zdCBsYnJ5QXBpID0gcmVxdWlyZSgnaGVscGVycy9sYnJ5QXBpLmpzJyk7XG5jb25zdCBwdWJsaXNoSGVscGVycyA9IHJlcXVpcmUoJ2hlbHBlcnMvcHVibGlzaEhlbHBlcnMuanMnKTtcbmNvbnN0IHsgcHVibGlzaGluZzogeyBwcmltYXJ5Q2xhaW1BZGRyZXNzLCBhZGRpdGlvbmFsQ2xhaW1BZGRyZXNzZXMgfSB9ID0gcmVxdWlyZSgnc2l0ZUNvbmZpZy5qcycpO1xuY29uc3QgU2VxdWVsaXplID0gcmVxdWlyZSgnc2VxdWVsaXplJyk7XG5jb25zdCBPcCA9IFNlcXVlbGl6ZS5PcDtcblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIHB1Ymxpc2ggKHB1Ymxpc2hQYXJhbXMsIGZpbGVOYW1lLCBmaWxlVHlwZSkge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICBsZXQgcHVibGlzaFJlc3VsdHMsIGNlcnRpZmljYXRlSWQsIGNoYW5uZWxOYW1lO1xuICAgICAgLy8gcHVibGlzaCB0aGUgZmlsZVxuICAgICAgcmV0dXJuIGxicnlBcGkucHVibGlzaENsYWltKHB1Ymxpc2hQYXJhbXMpXG4gICAgICAgIC50aGVuKHR4ID0+IHtcbiAgICAgICAgICBsb2dnZXIuaW5mbyhgU3VjY2Vzc2Z1bGx5IHB1Ymxpc2hlZCAke3B1Ymxpc2hQYXJhbXMubmFtZX0gJHtmaWxlTmFtZX1gLCB0eCk7XG4gICAgICAgICAgcHVibGlzaFJlc3VsdHMgPSB0eDtcbiAgICAgICAgICAvLyBnZXQgdGhlIGNoYW5uZWwgaW5mb3JtYXRpb25cbiAgICAgICAgICBpZiAocHVibGlzaFBhcmFtcy5jaGFubmVsX25hbWUpIHtcbiAgICAgICAgICAgIGxvZ2dlci5kZWJ1ZyhgdGhpcyBjbGFpbSB3YXMgcHVibGlzaGVkIGluIGNoYW5uZWw6ICR7cHVibGlzaFBhcmFtcy5jaGFubmVsX25hbWV9YCk7XG4gICAgICAgICAgICByZXR1cm4gZGIuQ2hhbm5lbC5maW5kT25lKHtcbiAgICAgICAgICAgICAgd2hlcmU6IHtcbiAgICAgICAgICAgICAgICBjaGFubmVsTmFtZTogcHVibGlzaFBhcmFtcy5jaGFubmVsX25hbWUsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgbG9nZ2VyLmRlYnVnKCd0aGlzIGNsYWltIHdhcyBub3QgcHVibGlzaGVkIGluIGEgY2hhbm5lbCcpO1xuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgICAgfVxuICAgICAgICB9KVxuICAgICAgICAudGhlbihjaGFubmVsID0+IHtcbiAgICAgICAgLy8gc2V0IGNoYW5uZWwgaW5mb3JtYXRpb25cbiAgICAgICAgICBjZXJ0aWZpY2F0ZUlkID0gbnVsbDtcbiAgICAgICAgICBjaGFubmVsTmFtZSA9IG51bGw7XG4gICAgICAgICAgaWYgKGNoYW5uZWwpIHtcbiAgICAgICAgICAgIGNlcnRpZmljYXRlSWQgPSBjaGFubmVsLmNoYW5uZWxDbGFpbUlkO1xuICAgICAgICAgICAgY2hhbm5lbE5hbWUgPSBjaGFubmVsLmNoYW5uZWxOYW1lO1xuICAgICAgICAgIH1cbiAgICAgICAgICBsb2dnZXIuZGVidWcoYGNlcnRpZmljYXRlSWQ6ICR7Y2VydGlmaWNhdGVJZH1gKTtcbiAgICAgICAgfSlcbiAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAvLyBjcmVhdGUgdGhlIEZpbGUgcmVjb3JkXG4gICAgICAgICAgY29uc3QgZmlsZVJlY29yZCA9IHtcbiAgICAgICAgICAgIG5hbWUgICAgICAgOiBwdWJsaXNoUGFyYW1zLm5hbWUsXG4gICAgICAgICAgICBjbGFpbUlkICAgIDogcHVibGlzaFJlc3VsdHMuY2xhaW1faWQsXG4gICAgICAgICAgICB0aXRsZSAgICAgIDogcHVibGlzaFBhcmFtcy5tZXRhZGF0YS50aXRsZSxcbiAgICAgICAgICAgIGRlc2NyaXB0aW9uOiBwdWJsaXNoUGFyYW1zLm1ldGFkYXRhLmRlc2NyaXB0aW9uLFxuICAgICAgICAgICAgYWRkcmVzcyAgICA6IHB1Ymxpc2hQYXJhbXMuY2xhaW1fYWRkcmVzcyxcbiAgICAgICAgICAgIG91dHBvaW50ICAgOiBgJHtwdWJsaXNoUmVzdWx0cy50eGlkfToke3B1Ymxpc2hSZXN1bHRzLm5vdXR9YCxcbiAgICAgICAgICAgIGhlaWdodCAgICAgOiAwLFxuICAgICAgICAgICAgZmlsZU5hbWUsXG4gICAgICAgICAgICBmaWxlUGF0aCAgIDogcHVibGlzaFBhcmFtcy5maWxlX3BhdGgsXG4gICAgICAgICAgICBmaWxlVHlwZSxcbiAgICAgICAgICAgIG5zZncgICAgICAgOiBwdWJsaXNoUGFyYW1zLm1ldGFkYXRhLm5zZncsXG4gICAgICAgICAgfTtcbiAgICAgICAgICAvLyBjcmVhdGUgdGhlIENsYWltIHJlY29yZFxuICAgICAgICAgIGNvbnN0IGNsYWltUmVjb3JkID0ge1xuICAgICAgICAgICAgbmFtZSAgICAgICA6IHB1Ymxpc2hQYXJhbXMubmFtZSxcbiAgICAgICAgICAgIGNsYWltSWQgICAgOiBwdWJsaXNoUmVzdWx0cy5jbGFpbV9pZCxcbiAgICAgICAgICAgIHRpdGxlICAgICAgOiBwdWJsaXNoUGFyYW1zLm1ldGFkYXRhLnRpdGxlLFxuICAgICAgICAgICAgZGVzY3JpcHRpb246IHB1Ymxpc2hQYXJhbXMubWV0YWRhdGEuZGVzY3JpcHRpb24sXG4gICAgICAgICAgICBhZGRyZXNzICAgIDogcHVibGlzaFBhcmFtcy5jbGFpbV9hZGRyZXNzLFxuICAgICAgICAgICAgdGh1bWJuYWlsICA6IHB1Ymxpc2hQYXJhbXMubWV0YWRhdGEudGh1bWJuYWlsLFxuICAgICAgICAgICAgb3V0cG9pbnQgICA6IGAke3B1Ymxpc2hSZXN1bHRzLnR4aWR9OiR7cHVibGlzaFJlc3VsdHMubm91dH1gLFxuICAgICAgICAgICAgaGVpZ2h0ICAgICA6IDAsXG4gICAgICAgICAgICBjb250ZW50VHlwZTogZmlsZVR5cGUsXG4gICAgICAgICAgICBuc2Z3ICAgICAgIDogcHVibGlzaFBhcmFtcy5tZXRhZGF0YS5uc2Z3LFxuICAgICAgICAgICAgYW1vdW50ICAgICA6IHB1Ymxpc2hQYXJhbXMuYmlkLFxuICAgICAgICAgICAgY2VydGlmaWNhdGVJZCxcbiAgICAgICAgICAgIGNoYW5uZWxOYW1lLFxuICAgICAgICAgIH07XG4gICAgICAgICAgLy8gdXBzZXJ0IGNyaXRlcmlhXG4gICAgICAgICAgY29uc3QgdXBzZXJ0Q3JpdGVyaWEgPSB7XG4gICAgICAgICAgICBuYW1lICAgOiBwdWJsaXNoUGFyYW1zLm5hbWUsXG4gICAgICAgICAgICBjbGFpbUlkOiBwdWJsaXNoUmVzdWx0cy5jbGFpbV9pZCxcbiAgICAgICAgICB9O1xuICAgICAgICAgIC8vIHVwc2VydCB0aGUgcmVjb3Jkc1xuICAgICAgICAgIHJldHVybiBQcm9taXNlLmFsbChbZGIudXBzZXJ0KGRiLkZpbGUsIGZpbGVSZWNvcmQsIHVwc2VydENyaXRlcmlhLCAnRmlsZScpLCBkYi51cHNlcnQoZGIuQ2xhaW0sIGNsYWltUmVjb3JkLCB1cHNlcnRDcml0ZXJpYSwgJ0NsYWltJyldKTtcbiAgICAgICAgfSlcbiAgICAgICAgLnRoZW4oKFtmaWxlLCBjbGFpbV0pID0+IHtcbiAgICAgICAgICBsb2dnZXIuZGVidWcoJ0ZpbGUgYW5kIENsYWltIHJlY29yZHMgc3VjY2Vzc2Z1bGx5IGNyZWF0ZWQnKTtcbiAgICAgICAgICByZXR1cm4gUHJvbWlzZS5hbGwoW2ZpbGUuc2V0Q2xhaW0oY2xhaW0pLCBjbGFpbS5zZXRGaWxlKGZpbGUpXSk7XG4gICAgICAgIH0pXG4gICAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgICBsb2dnZXIuZGVidWcoJ0ZpbGUgYW5kIENsYWltIHJlY29yZHMgc3VjY2Vzc2Z1bGx5IGFzc29jaWF0ZWQnKTtcbiAgICAgICAgICByZXNvbHZlKHB1Ymxpc2hSZXN1bHRzKTsgLy8gcmVzb2x2ZSB0aGUgcHJvbWlzZSB3aXRoIHRoZSByZXN1bHQgZnJvbSBsYnJ5QXBpLnB1Ymxpc2hDbGFpbTtcbiAgICAgICAgfSlcbiAgICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICBsb2dnZXIuZXJyb3IoJ1BVQkxJU0ggRVJST1InLCBlcnJvcik7XG4gICAgICAgICAgcHVibGlzaEhlbHBlcnMuZGVsZXRlVGVtcG9yYXJ5RmlsZShwdWJsaXNoUGFyYW1zLmZpbGVfcGF0aCk7IC8vIGRlbGV0ZSB0aGUgbG9jYWwgZmlsZVxuICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgIH0pO1xuICAgIH0pO1xuICB9LFxuICBjbGFpbU5hbWVJc0F2YWlsYWJsZSAobmFtZSkge1xuICAgIGNvbnN0IGNsYWltQWRkcmVzc2VzID0gYWRkaXRpb25hbENsYWltQWRkcmVzc2VzIHx8IFtdO1xuICAgIGNsYWltQWRkcmVzc2VzLnB1c2gocHJpbWFyeUNsYWltQWRkcmVzcyk7XG4gICAgLy8gZmluZCBhbnkgcmVjb3JkcyB3aGVyZSB0aGUgbmFtZSBpcyB1c2VkXG4gICAgcmV0dXJuIGRiLkNsYWltXG4gICAgICAuZmluZEFsbCh7XG4gICAgICAgIGF0dHJpYnV0ZXM6IFsnYWRkcmVzcyddLFxuICAgICAgICB3aGVyZSAgICAgOiB7XG4gICAgICAgICAgbmFtZSxcbiAgICAgICAgICBhZGRyZXNzOiB7XG4gICAgICAgICAgICBbT3Aub3JdOiBjbGFpbUFkZHJlc3NlcyxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgfSlcbiAgICAgIC50aGVuKHJlc3VsdCA9PiB7XG4gICAgICAgIGlmIChyZXN1bHQubGVuZ3RoID49IDEpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1RoYXQgY2xhaW0gaXMgYWxyZWFkeSBpbiB1c2UnKTtcbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIG5hbWU7XG4gICAgICB9KVxuICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICB9KTtcbiAgfSxcbiAgY2hlY2tDaGFubmVsQXZhaWxhYmlsaXR5IChuYW1lKSB7XG4gICAgcmV0dXJuIGRiLkNoYW5uZWxcbiAgICAgIC5maW5kQWxsKHtcbiAgICAgICAgd2hlcmU6IHsgY2hhbm5lbE5hbWU6IG5hbWUgfSxcbiAgICAgIH0pXG4gICAgICAudGhlbihyZXN1bHQgPT4ge1xuICAgICAgICBpZiAocmVzdWx0Lmxlbmd0aCA+PSAxKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdUaGF0IGNoYW5uZWwgaGFzIGFscmVhZHkgYmVlbiBjbGFpbWVkJyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG5hbWU7XG4gICAgICB9KVxuICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICB9KTtcbiAgfSxcbn07XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9zZXJ2ZXIvY29udHJvbGxlcnMvcHVibGlzaENvbnRyb2xsZXIuanMiLCJjb25zdCBsb2dnZXIgPSByZXF1aXJlKCd3aW5zdG9uJyk7XG5jb25zdCBmcyA9IHJlcXVpcmUoJ2ZzJyk7XG5cbmNvbnN0IHsgZGV0YWlscywgcHVibGlzaGluZyB9ID0gcmVxdWlyZSgnLi4vLi4vY29uZmlnL3NpdGVDb25maWcuanMnKTtcblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIHBhcnNlUHVibGlzaEFwaVJlcXVlc3RCb2R5ICh7bmFtZSwgbnNmdywgbGljZW5zZSwgdGl0bGUsIGRlc2NyaXB0aW9uLCB0aHVtYm5haWx9KSB7XG4gICAgLy8gdmFsaWRhdGUgbmFtZVxuICAgIGlmICghbmFtZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdubyBuYW1lIGZpZWxkIGZvdW5kIGluIHJlcXVlc3QnKTtcbiAgICB9XG4gICAgY29uc3QgaW52YWxpZE5hbWVDaGFyYWN0ZXJzID0gL1teQS1aYS16MC05LC1dLy5leGVjKG5hbWUpO1xuICAgIGlmIChpbnZhbGlkTmFtZUNoYXJhY3RlcnMpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignVGhlIGNsYWltIG5hbWUgeW91IHByb3ZpZGVkIGlzIG5vdCBhbGxvd2VkLiAgT25seSB0aGUgZm9sbG93aW5nIGNoYXJhY3RlcnMgYXJlIGFsbG93ZWQ6IEEtWiwgYS16LCAwLTksIGFuZCBcIi1cIicpO1xuICAgIH1cbiAgICAvLyBvcHRpb25hbCBwYXJhbWV0ZXJzXG4gICAgbnNmdyA9IChuc2Z3ID09PSAndHJ1ZScpO1xuICAgIGxpY2Vuc2UgPSBsaWNlbnNlIHx8IG51bGw7XG4gICAgdGl0bGUgPSB0aXRsZSB8fCBudWxsO1xuICAgIGRlc2NyaXB0aW9uID0gZGVzY3JpcHRpb24gfHwgbnVsbDtcbiAgICB0aHVtYm5haWwgPSB0aHVtYm5haWwgfHwgbnVsbDtcbiAgICAvLyByZXR1cm4gcmVzdWx0c1xuICAgIHJldHVybiB7XG4gICAgICBuYW1lLFxuICAgICAgbnNmdyxcbiAgICAgIGxpY2Vuc2UsXG4gICAgICB0aXRsZSxcbiAgICAgIGRlc2NyaXB0aW9uLFxuICAgICAgdGh1bWJuYWlsLFxuICAgIH07XG4gIH0sXG4gIHBhcnNlUHVibGlzaEFwaVJlcXVlc3RGaWxlcyAoe2ZpbGUsIHRodW1ibmFpbH0pIHtcbiAgICAvLyBtYWtlIHN1cmUgYSBmaWxlIHdhcyBwcm92aWRlZFxuICAgIGlmICghZmlsZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdubyBmaWxlIHdpdGgga2V5IG9mIFtmaWxlXSBmb3VuZCBpbiByZXF1ZXN0Jyk7XG4gICAgfVxuICAgIGlmICghZmlsZS5wYXRoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ25vIGZpbGUgcGF0aCBmb3VuZCcpO1xuICAgIH1cbiAgICBpZiAoIWZpbGUudHlwZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdubyBmaWxlIHR5cGUgZm91bmQnKTtcbiAgICB9XG4gICAgaWYgKCFmaWxlLnNpemUpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignbm8gZmlsZSB0eXBlIGZvdW5kJyk7XG4gICAgfVxuICAgIC8vIHZhbGlkYXRlIHRoZSBmaWxlIG5hbWVcbiAgICBpZiAoLycvLnRlc3QoZmlsZS5uYW1lKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdhcG9zdHJvcGhlcyBhcmUgbm90IGFsbG93ZWQgaW4gdGhlIGZpbGUgbmFtZScpO1xuICAgIH1cbiAgICAvLyB2YWxpZGF0ZSB0aGUgZmlsZVxuICAgIG1vZHVsZS5leHBvcnRzLnZhbGlkYXRlRmlsZVR5cGVBbmRTaXplKGZpbGUpO1xuICAgIC8vIHJldHVybiByZXN1bHRzXG4gICAgcmV0dXJuIHtcbiAgICAgIGZpbGVOYW1lICAgICAgICAgOiBmaWxlLm5hbWUsXG4gICAgICBmaWxlUGF0aCAgICAgICAgIDogZmlsZS5wYXRoLFxuICAgICAgZmlsZVR5cGUgICAgICAgICA6IGZpbGUudHlwZSxcbiAgICAgIHRodW1ibmFpbEZpbGVOYW1lOiAodGh1bWJuYWlsID8gdGh1bWJuYWlsLm5hbWUgOiBudWxsKSxcbiAgICAgIHRodW1ibmFpbEZpbGVQYXRoOiAodGh1bWJuYWlsID8gdGh1bWJuYWlsLnBhdGggOiBudWxsKSxcbiAgICAgIHRodW1ibmFpbEZpbGVUeXBlOiAodGh1bWJuYWlsID8gdGh1bWJuYWlsLnR5cGUgOiBudWxsKSxcbiAgICB9O1xuICB9LFxuICB2YWxpZGF0ZUZpbGVUeXBlQW5kU2l6ZSAoZmlsZSkge1xuICAgIC8vIGNoZWNrIGZpbGUgdHlwZSBhbmQgc2l6ZVxuICAgIHN3aXRjaCAoZmlsZS50eXBlKSB7XG4gICAgICBjYXNlICdpbWFnZS9qcGVnJzpcbiAgICAgIGNhc2UgJ2ltYWdlL2pwZyc6XG4gICAgICBjYXNlICdpbWFnZS9wbmcnOlxuICAgICAgICBpZiAoZmlsZS5zaXplID4gMTAwMDAwMDApIHtcbiAgICAgICAgICBsb2dnZXIuZGVidWcoJ3B1Ymxpc2ggPiBmaWxlIHZhbGlkYXRpb24gPiAuanBlZy8uanBnLy5wbmcgd2FzIHRvbyBiaWcnKTtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1NvcnJ5LCBpbWFnZXMgYXJlIGxpbWl0ZWQgdG8gMTAgbWVnYWJ5dGVzLicpO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnaW1hZ2UvZ2lmJzpcbiAgICAgICAgaWYgKGZpbGUuc2l6ZSA+IDUwMDAwMDAwKSB7XG4gICAgICAgICAgbG9nZ2VyLmRlYnVnKCdwdWJsaXNoID4gZmlsZSB2YWxpZGF0aW9uID4gLmdpZiB3YXMgdG9vIGJpZycpO1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcignU29ycnksIC5naWZzIGFyZSBsaW1pdGVkIHRvIDUwIG1lZ2FieXRlcy4nKTtcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ3ZpZGVvL21wNCc6XG4gICAgICAgIGlmIChmaWxlLnNpemUgPiA1MDAwMDAwMCkge1xuICAgICAgICAgIGxvZ2dlci5kZWJ1ZygncHVibGlzaCA+IGZpbGUgdmFsaWRhdGlvbiA+IC5tcDQgd2FzIHRvbyBiaWcnKTtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1NvcnJ5LCB2aWRlb3MgYXJlIGxpbWl0ZWQgdG8gNTAgbWVnYWJ5dGVzLicpO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgbG9nZ2VyLmRlYnVnKCdwdWJsaXNoID4gZmlsZSB2YWxpZGF0aW9uID4gdW5yZWNvZ25pemVkIGZpbGUgdHlwZScpO1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1RoZSAnICsgZmlsZS50eXBlICsgJyBjb250ZW50IHR5cGUgaXMgbm90IHN1cHBvcnRlZC4gIE9ubHksIC5qcGVnLCAucG5nLCAuZ2lmLCBhbmQgLm1wNCBmaWxlcyBhcmUgY3VycmVudGx5IHN1cHBvcnRlZC4nKTtcbiAgICB9XG4gICAgcmV0dXJuIGZpbGU7XG4gIH0sXG4gIGNyZWF0ZUJhc2ljUHVibGlzaFBhcmFtcyAoZmlsZVBhdGgsIG5hbWUsIHRpdGxlLCBkZXNjcmlwdGlvbiwgbGljZW5zZSwgbnNmdywgdGh1bWJuYWlsKSB7XG4gICAgbG9nZ2VyLmRlYnVnKGBDcmVhdGluZyBQdWJsaXNoIFBhcmFtZXRlcnNgKTtcbiAgICAvLyBwcm92aWRlIGRlZmF1bHRzIGZvciB0aXRsZVxuICAgIGlmICh0aXRsZSA9PT0gbnVsbCB8fCB0aXRsZS50cmltKCkgPT09ICcnKSB7XG4gICAgICB0aXRsZSA9IG5hbWU7XG4gICAgfVxuICAgIC8vIHByb3ZpZGUgZGVmYXVsdCBmb3IgZGVzY3JpcHRpb25cbiAgICBpZiAoZGVzY3JpcHRpb24gPT09IG51bGwgfHwgZGVzY3JpcHRpb24udHJpbSgpID09PSAnJykge1xuICAgICAgZGVzY3JpcHRpb24gPSAnJztcbiAgICB9XG4gICAgLy8gcHJvdmlkZSBkZWZhdWx0IGZvciBsaWNlbnNlXG4gICAgaWYgKGxpY2Vuc2UgPT09IG51bGwgfHwgbGljZW5zZS50cmltKCkgPT09ICcnKSB7XG4gICAgICBsaWNlbnNlID0gJyAnOyAgLy8gZGVmYXVsdCB0byBlbXB0eSBzdHJpbmdcbiAgICB9XG4gICAgLy8gY3JlYXRlIHRoZSBwdWJsaXNoIHBhcmFtc1xuICAgIGNvbnN0IHB1Ymxpc2hQYXJhbXMgPSB7XG4gICAgICBuYW1lLFxuICAgICAgZmlsZV9wYXRoOiBmaWxlUGF0aCxcbiAgICAgIGJpZCAgICAgIDogMC4wMSxcbiAgICAgIG1ldGFkYXRhIDoge1xuICAgICAgICBkZXNjcmlwdGlvbixcbiAgICAgICAgdGl0bGUsXG4gICAgICAgIGF1dGhvciAgOiBkZXRhaWxzLnRpdGxlLFxuICAgICAgICBsYW5ndWFnZTogJ2VuJyxcbiAgICAgICAgbGljZW5zZSxcbiAgICAgICAgbnNmdyxcbiAgICAgIH0sXG4gICAgICBjbGFpbV9hZGRyZXNzOiBwdWJsaXNoaW5nLnByaW1hcnlDbGFpbUFkZHJlc3MsXG4gICAgfTtcbiAgICAvLyBhZGQgdGh1bWJuYWlsIHRvIGNoYW5uZWwgaWYgdmlkZW9cbiAgICBpZiAodGh1bWJuYWlsKSB7XG4gICAgICBwdWJsaXNoUGFyYW1zWydtZXRhZGF0YSddWyd0aHVtYm5haWwnXSA9IHRodW1ibmFpbDtcbiAgICB9XG4gICAgcmV0dXJuIHB1Ymxpc2hQYXJhbXM7XG4gIH0sXG4gIGNyZWF0ZVRodW1ibmFpbFB1Ymxpc2hQYXJhbXMgKHRodW1ibmFpbEZpbGVQYXRoLCBjbGFpbU5hbWUsIGxpY2Vuc2UsIG5zZncpIHtcbiAgICBpZiAoIXRodW1ibmFpbEZpbGVQYXRoKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGxvZ2dlci5kZWJ1ZyhgQ3JlYXRpbmcgVGh1bWJuYWlsIFB1Ymxpc2ggUGFyYW1ldGVyc2ApO1xuICAgIC8vIGNyZWF0ZSB0aGUgcHVibGlzaCBwYXJhbXNcbiAgICByZXR1cm4ge1xuICAgICAgbmFtZSAgICAgOiBgJHtjbGFpbU5hbWV9LXRodW1iYCxcbiAgICAgIGZpbGVfcGF0aDogdGh1bWJuYWlsRmlsZVBhdGgsXG4gICAgICBiaWQgICAgICA6IDAuMDEsXG4gICAgICBtZXRhZGF0YSA6IHtcbiAgICAgICAgdGl0bGUgICAgICA6IGAke2NsYWltTmFtZX0gdGh1bWJuYWlsYCxcbiAgICAgICAgZGVzY3JpcHRpb246IGBhIHRodW1ibmFpbCBmb3IgJHtjbGFpbU5hbWV9YCxcbiAgICAgICAgYXV0aG9yICAgICA6IGRldGFpbHMudGl0bGUsXG4gICAgICAgIGxhbmd1YWdlICAgOiAnZW4nLFxuICAgICAgICBsaWNlbnNlLFxuICAgICAgICBuc2Z3LFxuICAgICAgfSxcbiAgICAgIGNsYWltX2FkZHJlc3M6IHB1Ymxpc2hpbmcucHJpbWFyeUNsYWltQWRkcmVzcyxcbiAgICAgIGNoYW5uZWxfbmFtZSA6IHB1Ymxpc2hpbmcudGh1bWJuYWlsQ2hhbm5lbCxcbiAgICAgIGNoYW5uZWxfaWQgICA6IHB1Ymxpc2hpbmcudGh1bWJuYWlsQ2hhbm5lbElkLFxuICAgIH07XG4gIH0sXG4gIGRlbGV0ZVRlbXBvcmFyeUZpbGUgKGZpbGVQYXRoKSB7XG4gICAgZnMudW5saW5rKGZpbGVQYXRoLCBlcnIgPT4ge1xuICAgICAgaWYgKGVycikge1xuICAgICAgICBsb2dnZXIuZXJyb3IoYGVycm9yIGRlbGV0aW5nIHRlbXBvcmFyeSBmaWxlICR7ZmlsZVBhdGh9YCk7XG4gICAgICAgIHRocm93IGVycjtcbiAgICAgIH1cbiAgICAgIGxvZ2dlci5kZWJ1Zyhgc3VjY2Vzc2Z1bGx5IGRlbGV0ZWQgJHtmaWxlUGF0aH1gKTtcbiAgICB9KTtcbiAgfSxcbiAgYWRkR2V0UmVzdWx0c1RvRmlsZURhdGEgKGZpbGVJbmZvLCBnZXRSZXN1bHQpIHtcbiAgICBmaWxlSW5mby5maWxlTmFtZSA9IGdldFJlc3VsdC5maWxlX25hbWU7XG4gICAgZmlsZUluZm8uZmlsZVBhdGggPSBnZXRSZXN1bHQuZG93bmxvYWRfcGF0aDtcbiAgICByZXR1cm4gZmlsZUluZm87XG4gIH0sXG4gIGNyZWF0ZUZpbGVEYXRhICh7IG5hbWUsIGNsYWltSWQsIG91dHBvaW50LCBoZWlnaHQsIGFkZHJlc3MsIG5zZncsIGNvbnRlbnRUeXBlIH0pIHtcbiAgICByZXR1cm4ge1xuICAgICAgbmFtZSxcbiAgICAgIGNsYWltSWQsXG4gICAgICBvdXRwb2ludCxcbiAgICAgIGhlaWdodCxcbiAgICAgIGFkZHJlc3MsXG4gICAgICBmaWxlTmFtZTogJycsXG4gICAgICBmaWxlUGF0aDogJycsXG4gICAgICBmaWxlVHlwZTogY29udGVudFR5cGUsXG4gICAgICBuc2Z3LFxuICAgIH07XG4gIH0sXG59O1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vc2VydmVyL2hlbHBlcnMvcHVibGlzaEhlbHBlcnMuanMiLCJjb25zdCBsb2dnZXIgPSByZXF1aXJlKCd3aW5zdG9uJyk7XG5cbmZ1bmN0aW9uIG15c3FsICgpIHtcbiAgdGhpcy5kYXRhYmFzZSA9ICdkZWZhdWx0JztcbiAgdGhpcy51c2VybmFtZSA9ICdkZWZhdWx0JztcbiAgdGhpcy5wYXNzd29yZCA9ICdkZWZhdWx0JztcbiAgdGhpcy51cGRhdGUgPSAoY29uZmlnKSA9PiB7XG4gICAgaWYgKCFjb25maWcpIHtcbiAgICAgIHJldHVybiBsb2dnZXIud2FybignTm8gTXlTUUwgY29uZmlnIHJlY2VpdmVkLicpO1xuICAgIH1cbiAgICAvLyBjb25maWd1cmUgY3JlZGVudGlhbHNcbiAgICBsb2dnZXIuaW5mbygnY29uZmlndXJpbmcgbXlzcWwuLi4nKTtcbiAgICBjb25zdCB7IGRhdGFiYXNlLCB1c2VybmFtZSwgcGFzc3dvcmQgfSA9IGNvbmZpZztcbiAgICB0aGlzLmRhdGFiYXNlID0gZGF0YWJhc2U7XG4gICAgdGhpcy51c2VybmFtZSA9IHVzZXJuYW1lO1xuICAgIHRoaXMucGFzc3dvcmQgPSBwYXNzd29yZDtcbiAgfTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gbmV3IG15c3FsKCk7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9jb25maWcvbXlzcWxDb25maWcuanMiLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCJwYXNzcG9ydC1sb2NhbFwiKTtcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyBleHRlcm5hbCBcInBhc3Nwb3J0LWxvY2FsXCJcbi8vIG1vZHVsZSBpZCA9IDExXG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIm1vZHVsZS5leHBvcnRzID0ge1xuICByZXR1cm5TaG9ydElkOiBmdW5jdGlvbiAoY2xhaW1zQXJyYXksIGxvbmdJZCkge1xuICAgIGxldCBjbGFpbUluZGV4O1xuICAgIGxldCBzaG9ydElkID0gbG9uZ0lkLnN1YnN0cmluZygwLCAxKTsgLy8gZGVmYXVsdCBzaG9ydCBpZCBpcyB0aGUgZmlyc3QgbGV0dGVyXG4gICAgbGV0IHNob3J0SWRMZW5ndGggPSAwO1xuICAgIC8vIGZpbmQgdGhlIGluZGV4IG9mIHRoaXMgY2xhaW0gaWRcbiAgICBjbGFpbUluZGV4ID0gY2xhaW1zQXJyYXkuZmluZEluZGV4KGVsZW1lbnQgPT4ge1xuICAgICAgcmV0dXJuIGVsZW1lbnQuY2xhaW1JZCA9PT0gbG9uZ0lkO1xuICAgIH0pO1xuICAgIGlmIChjbGFpbUluZGV4IDwgMCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdjbGFpbSBpZCBub3QgZm91bmQgaW4gY2xhaW1zIGxpc3QnKTtcbiAgICB9XG4gICAgLy8gZ2V0IGFuIGFycmF5IG9mIGFsbCBjbGFpbXMgd2l0aCBsb3dlciBoZWlnaHRcbiAgICBsZXQgcG9zc2libGVNYXRjaGVzID0gY2xhaW1zQXJyYXkuc2xpY2UoMCwgY2xhaW1JbmRleCk7XG4gICAgLy8gcmVtb3ZlIGNlcnRpZmljYXRlcyB3aXRoIHRoZSBzYW1lIHByZWZpeGVzIHVudGlsIG5vbmUgYXJlIGxlZnQuXG4gICAgd2hpbGUgKHBvc3NpYmxlTWF0Y2hlcy5sZW5ndGggPiAwKSB7XG4gICAgICBzaG9ydElkTGVuZ3RoICs9IDE7XG4gICAgICBzaG9ydElkID0gbG9uZ0lkLnN1YnN0cmluZygwLCBzaG9ydElkTGVuZ3RoKTtcbiAgICAgIHBvc3NpYmxlTWF0Y2hlcyA9IHBvc3NpYmxlTWF0Y2hlcy5maWx0ZXIoZWxlbWVudCA9PiB7XG4gICAgICAgIHJldHVybiAoZWxlbWVudC5jbGFpbUlkICYmIChlbGVtZW50LmNsYWltSWQuc3Vic3RyaW5nKDAsIHNob3J0SWRMZW5ndGgpID09PSBzaG9ydElkKSk7XG4gICAgICB9KTtcbiAgICB9XG4gICAgcmV0dXJuIHNob3J0SWQ7XG4gIH0sXG59O1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vc2VydmVyL2hlbHBlcnMvc2VxdWVsaXplSGVscGVycy5qcyIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcInNlcXVlbGl6ZVwiKTtcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyBleHRlcm5hbCBcInNlcXVlbGl6ZVwiXG4vLyBtb2R1bGUgaWQgPSAxM1xuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJpbXBvcnQgUmVhY3QgZnJvbSAncmVhY3QnO1xuaW1wb3J0IHsgcmVuZGVyVG9TdHJpbmcgfSBmcm9tICdyZWFjdC1kb20vc2VydmVyJztcbmltcG9ydCB7IGNyZWF0ZVN0b3JlIH0gZnJvbSAncmVkdXgnO1xuaW1wb3J0IHsgUHJvdmlkZXIgfSBmcm9tICdyZWFjdC1yZWR1eCc7XG5pbXBvcnQgeyBTdGF0aWNSb3V0ZXIgfSBmcm9tICdyZWFjdC1yb3V0ZXItZG9tJztcbmltcG9ydCB7IFJlZHVjZXJzLCBHQUxpc3RlbmVyLCBBcHAgfSBmcm9tICdzcGVlLmNoLWNvbXBvbmVudHMnO1xuLypcbiAgXiBub3RlOiB0byBkbyB0aGlzIHJpZ2h0LCBtYXliZVxuICB0aGVzZSBzaG91bGQgYmUgcGFzc2VkIGluIGZyb20gdGhlIGltcGxlbWVudGF0aW9uICh3d3cuc3BlZS5jaCkgaXRzZWxmLFxuICBzbyB0aGF0IHRoZXJlIGFyZSBubyBjb25mbGljdHMgYmV0d2VlbiB0aGUgU1NSIGhlcmUgYW5kXG4gIHRoZSBidW5kbGUgc2VudCB0byB0aGUgc2VydmVyP1xuICB0aGVyZSBtaWdodCBhbHNvIGJlIGlzc3VlcyBpZiB0aGlzIHBhY2thZ2UgdXNlcyBhIGRpZmZlcmVudCB2ZXJzaW9uIG9mIHNwZWUuY2gtY29tcG9uZW50cyB0aGFuIHd3dy5zcGVlLmNoIGRvZXM/XG4qL1xuaW1wb3J0IHJlbmRlckZ1bGxQYWdlIGZyb20gJy4vcmVuZGVyRnVsbFBhZ2UuanMnO1xuaW1wb3J0IEhlbG1ldCBmcm9tICdyZWFjdC1oZWxtZXQnO1xuXG5jb25zdCBzaXRlQ29uZmlnID0gcmVxdWlyZSgnc2l0ZUNvbmZpZy5qcycpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IChyZXEsIHJlcykgPT4ge1xuICBsZXQgY29udGV4dCA9IHt9O1xuXG4gIC8vIGN1c3RvbWl6ZSB0aGUgcmVkdWNlciBieSBwYXNzaW5nIGluIGludGlhbCBzdGF0ZSBjb25maWdzXG4gIGNvbnN0IE15UmVkdWNlcnMgPSBSZWR1Y2VycyhzaXRlQ29uZmlnKTtcbiAgY29uc3QgTXlBcHAgPSBBcHAoc2l0ZUNvbmZpZyk7XG4gIGNvbnN0IE15R0FMaXN0ZW5lciA9IEdBTGlzdGVuZXIoc2l0ZUNvbmZpZyk7XG5cbiAgLy8gY3JlYXRlIGEgbmV3IFJlZHV4IHN0b3JlIGluc3RhbmNlXG4gIGNvbnN0IHN0b3JlID0gY3JlYXRlU3RvcmUoTXlSZWR1Y2Vycyk7XG5cbiAgLy8gcmVuZGVyIGNvbXBvbmVudCB0byBhIHN0cmluZ1xuICBjb25zdCBodG1sID0gcmVuZGVyVG9TdHJpbmcoXG4gICAgPFByb3ZpZGVyIHN0b3JlPXtzdG9yZX0+XG4gICAgICA8U3RhdGljUm91dGVyIGxvY2F0aW9uPXtyZXEudXJsfSBjb250ZXh0PXtjb250ZXh0fT5cbiAgICAgICAgPE15R0FMaXN0ZW5lcj5cbiAgICAgICAgICA8TXlBcHAgLz5cbiAgICAgICAgPC9NeUdBTGlzdGVuZXI+XG4gICAgICA8L1N0YXRpY1JvdXRlcj5cbiAgICA8L1Byb3ZpZGVyPlxuICApO1xuXG4gIC8vIGdldCBoZWFkIHRhZ3MgZnJvbSBoZWxtZXRcbiAgY29uc3QgaGVsbWV0ID0gSGVsbWV0LnJlbmRlclN0YXRpYygpO1xuXG4gIC8vIGNoZWNrIGZvciBhIHJlZGlyZWN0XG4gIGlmIChjb250ZXh0LnVybCkge1xuICAgIC8vIFNvbWV3aGVyZSBhIGA8UmVkaXJlY3Q+YCB3YXMgcmVuZGVyZWRcbiAgICByZXR1cm4gcmVzLnJlZGlyZWN0KDMwMSwgY29udGV4dC51cmwpO1xuICB9IGVsc2Uge1xuICAgIC8vIHdlJ3JlIGdvb2QsIHNlbmQgdGhlIHJlc3BvbnNlXG4gIH1cblxuICAvLyBnZXQgdGhlIGluaXRpYWwgc3RhdGUgZnJvbSBvdXIgUmVkdXggc3RvcmVcbiAgY29uc3QgcHJlbG9hZGVkU3RhdGUgPSBzdG9yZS5nZXRTdGF0ZSgpO1xuXG4gIC8vIHNlbmQgdGhlIHJlbmRlcmVkIHBhZ2UgYmFjayB0byB0aGUgY2xpZW50XG4gIHJlcy5zZW5kKHJlbmRlckZ1bGxQYWdlKGhlbG1ldCwgaHRtbCwgcHJlbG9hZGVkU3RhdGUpKTtcblxuICBjb25zb2xlLmxvZygnaGVsbG8gZnJvbSBzcGVlLmNoIGhhbmRsZVBhZ2VSZW5kZXIuanN4Jyk7XG59O1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vc2VydmVyL2hlbHBlcnMvaGFuZGxlUGFnZVJlbmRlci5qc3giLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCJyZWFjdFwiKTtcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyBleHRlcm5hbCBcInJlYWN0XCJcbi8vIG1vZHVsZSBpZCA9IDE1XG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcInJlYWN0LWRvbS9zZXJ2ZXJcIik7XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gZXh0ZXJuYWwgXCJyZWFjdC1kb20vc2VydmVyXCJcbi8vIG1vZHVsZSBpZCA9IDE2XG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcInJlZHV4XCIpO1xuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIGV4dGVybmFsIFwicmVkdXhcIlxuLy8gbW9kdWxlIGlkID0gMTdcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwicmVhY3QtcmVkdXhcIik7XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gZXh0ZXJuYWwgXCJyZWFjdC1yZWR1eFwiXG4vLyBtb2R1bGUgaWQgPSAxOFxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCJyZWFjdC1yb3V0ZXItZG9tXCIpO1xuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIGV4dGVybmFsIFwicmVhY3Qtcm91dGVyLWRvbVwiXG4vLyBtb2R1bGUgaWQgPSAxOVxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCJzcGVlLmNoLWNvbXBvbmVudHNcIik7XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gZXh0ZXJuYWwgXCJzcGVlLmNoLWNvbXBvbmVudHNcIlxuLy8gbW9kdWxlIGlkID0gMjBcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwibW9kdWxlLmV4cG9ydHMgPSAoaGVsbWV0LCBodG1sLCBwcmVsb2FkZWRTdGF0ZSkgPT4ge1xuICAvLyB0YWtlIHRoZSBodG1sIGFuZCBwcmVsb2FkZWRTdGF0ZSBhbmQgcmV0dXJuIHRoZSBmdWxsIHBhZ2VcbiAgcmV0dXJuIGBcbiAgICA8IURPQ1RZUEUgaHRtbD5cbiAgICA8aHRtbCBsYW5nPVwiZW5cIiBwcmVmaXg9XCJvZzogaHR0cDovL29ncC5tZS9ucyMgZmI6IGh0dHA6Ly9vZ3AubWUvbnMvZmIjXCI+XG4gICAgICAgIDxoZWFkPlxuICAgICAgICAgICAgPG1ldGEgY2hhcnNldD1cIlVURi04XCI+XG4gICAgICAgICAgICA8bWV0YSBuYW1lPVwidmlld3BvcnRcIiBjb250ZW50PVwid2lkdGg9ZGV2aWNlLXdpZHRoLCBpbml0aWFsLXNjYWxlPTEuMCwgbWF4aW11bS1zY2FsZT0xLCB1c2VyLXNjYWxhYmxlPW5vXCI+XG4gICAgICAgICAgICA8bWV0YSBodHRwLWVxdWl2PVwiWC1VQS1Db21wYXRpYmxlXCIgY29udGVudD1cImllPWVkZ2VcIj5cbiAgICAgICAgICAgIDwhLS1oZWxtZXQtLT5cbiAgICAgICAgICAgICR7aGVsbWV0LnRpdGxlLnRvU3RyaW5nKCl9XG4gICAgICAgICAgICAke2hlbG1ldC5tZXRhLnRvU3RyaW5nKCl9XG4gICAgICAgICAgICAke2hlbG1ldC5saW5rLnRvU3RyaW5nKCl9XG4gICAgICAgICAgICA8IS0tc3R5bGUgc2hlZXRzLS0+XG4gICAgICAgICAgICA8bGluayByZWw9XCJzdHlsZXNoZWV0XCIgaHJlZj1cIi9hc3NldHMvY3NzL3Jlc2V0LmNzc1wiIHR5cGU9XCJ0ZXh0L2Nzc1wiPlxuICAgICAgICAgICAgPGxpbmsgcmVsPVwic3R5bGVzaGVldFwiIGhyZWY9XCIvYXNzZXRzL2Nzcy9nZW5lcmFsLmNzc1wiIHR5cGU9XCJ0ZXh0L2Nzc1wiPlxuICAgICAgICAgICAgPGxpbmsgcmVsPVwic3R5bGVzaGVldFwiIGhyZWY9XCIvYXNzZXRzL2Nzcy9tZWRpYVF1ZXJpZXMuY3NzXCIgdHlwZT1cInRleHQvY3NzXCI+XG4gICAgICAgICAgICA8IS0tZ29vZ2xlIGZvbnQtLT5cbiAgICAgICAgICAgIDxsaW5rIGhyZWY9XCJodHRwczovL2ZvbnRzLmdvb2dsZWFwaXMuY29tL2Nzcz9mYW1pbHk9Um9ib3RvOjMwMFwiIHJlbD1cInN0eWxlc2hlZXRcIj5cbiAgICAgICAgPC9oZWFkPlxuICAgICAgICA8Ym9keSBpZD1cIm1haW4tYm9keVwiPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cInJvdyByb3ctLXRhbGwgZmxleC1jb250YWluZXItLWNvbHVtblwiPlxuICAgICAgICAgICAgICAgIDxkaXYgaWQ9XCJyZWFjdC1hcHBcIiBjbGFzcz1cInJvdyByb3ctLXRhbGwgZmxleC1jb250YWluZXItLWNvbHVtblwiPiR7aHRtbH08L2Rpdj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPHNjcmlwdD5cbiAgICAgICAgICAgICAgICB3aW5kb3cuX19QUkVMT0FERURfU1RBVEVfXyA9ICR7SlNPTi5zdHJpbmdpZnkocHJlbG9hZGVkU3RhdGUpLnJlcGxhY2UoLzwvZywgJ1xcXFxcXHUwMDNjJyl9XG4gICAgICAgICAgICA8L3NjcmlwdD5cbiAgICAgICAgICAgIDxzY3JpcHQgc3JjPVwiL2J1bmRsZS9idW5kbGUuanNcIj48L3NjcmlwdD5cbiAgICAgICAgPC9ib2R5PlxuICAgIDwvaHRtbD5cbiAgYDtcbn07XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9zZXJ2ZXIvaGVscGVycy9yZW5kZXJGdWxsUGFnZS5qcyIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcInJlYWN0LWhlbG1ldFwiKTtcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyBleHRlcm5hbCBcInJlYWN0LWhlbG1ldFwiXG4vLyBtb2R1bGUgaWQgPSAyMlxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJjb25zdCBsb2dnZXIgPSByZXF1aXJlKCd3aW5zdG9uJyk7XG5jb25zdCB7IGdldENsYWltSWQsIGdldExvY2FsRmlsZVJlY29yZCB9ID0gcmVxdWlyZSgnLi4vY29udHJvbGxlcnMvc2VydmVDb250cm9sbGVyLmpzJyk7XG5jb25zdCB7IGhhbmRsZUVycm9yUmVzcG9uc2UgfSA9IHJlcXVpcmUoJy4vZXJyb3JIYW5kbGVycy5qcycpO1xuXG5jb25zdCBTRVJWRSA9ICdTRVJWRSc7XG5jb25zdCBTSE9XID0gJ1NIT1cnO1xuY29uc3QgTk9fRklMRSA9ICdOT19GSUxFJztcbmNvbnN0IE5PX0NIQU5ORUwgPSAnTk9fQ0hBTk5FTCc7XG5jb25zdCBOT19DTEFJTSA9ICdOT19DTEFJTSc7XG5cbmZ1bmN0aW9uIGNsaWVudEFjY2VwdHNIdG1sICh7YWNjZXB0fSkge1xuICByZXR1cm4gYWNjZXB0ICYmIGFjY2VwdC5tYXRjaCgvdGV4dFxcL2h0bWwvKTtcbn07XG5cbmZ1bmN0aW9uIHJlcXVlc3RJc0Zyb21Ccm93c2VyIChoZWFkZXJzKSB7XG4gIHJldHVybiBoZWFkZXJzWyd1c2VyLWFnZW50J10gJiYgaGVhZGVyc1sndXNlci1hZ2VudCddLm1hdGNoKC9Nb3ppbGxhLyk7XG59O1xuXG5mdW5jdGlvbiBjbGllbnRXYW50c0Fzc2V0ICh7YWNjZXB0LCByYW5nZX0pIHtcbiAgY29uc3QgaW1hZ2VJc1dhbnRlZCA9IGFjY2VwdCAmJiBhY2NlcHQubWF0Y2goL2ltYWdlXFwvLiovKSAmJiAhYWNjZXB0Lm1hdGNoKC90ZXh0XFwvaHRtbC8pICYmICFhY2NlcHQubWF0Y2goL3RleHRcXC9cXCovKTtcbiAgY29uc3QgdmlkZW9Jc1dhbnRlZCA9IGFjY2VwdCAmJiByYW5nZTtcbiAgcmV0dXJuIGltYWdlSXNXYW50ZWQgfHwgdmlkZW9Jc1dhbnRlZDtcbn07XG5cbmZ1bmN0aW9uIGlzVmFsaWRDbGFpbUlkIChjbGFpbUlkKSB7XG4gIHJldHVybiAoKGNsYWltSWQubGVuZ3RoID09PSA0MCkgJiYgIS9bXkEtWmEtejAtOV0vZy50ZXN0KGNsYWltSWQpKTtcbn07XG5cbmZ1bmN0aW9uIGlzVmFsaWRTaG9ydElkIChjbGFpbUlkKSB7XG4gIHJldHVybiBjbGFpbUlkLmxlbmd0aCA9PT0gMTsgIC8vIGl0IHNob3VsZCByZWFsbHkgZXZhbHVhdGUgdGhlIHNob3J0IHVybCBpdHNlbGZcbn07XG5cbmZ1bmN0aW9uIGlzVmFsaWRTaG9ydElkT3JDbGFpbUlkIChpbnB1dCkge1xuICByZXR1cm4gKGlzVmFsaWRDbGFpbUlkKGlucHV0KSB8fCBpc1ZhbGlkU2hvcnRJZChpbnB1dCkpO1xufTtcblxuZnVuY3Rpb24gc2VydmVBc3NldFRvQ2xpZW50IChjbGFpbUlkLCBuYW1lLCByZXMpIHtcbiAgcmV0dXJuIGdldExvY2FsRmlsZVJlY29yZChjbGFpbUlkLCBuYW1lKVxuICAgIC50aGVuKGZpbGVSZWNvcmQgPT4ge1xuICAgICAgLy8gY2hlY2sgdGhhdCBhIGxvY2FsIHJlY29yZCB3YXMgZm91bmRcbiAgICAgIGlmIChmaWxlUmVjb3JkID09PSBOT19GSUxFKSB7XG4gICAgICAgIHJldHVybiByZXMuc3RhdHVzKDMwNykucmVkaXJlY3QoYC9hcGkvY2xhaW0vZ2V0LyR7bmFtZX0vJHtjbGFpbUlkfWApO1xuICAgICAgfVxuICAgICAgLy8gc2VydmUgdGhlIGZpbGVcbiAgICAgIGNvbnN0IHtmaWxlUGF0aCwgZmlsZVR5cGV9ID0gZmlsZVJlY29yZDtcbiAgICAgIGxvZ2dlci52ZXJib3NlKGBzZXJ2aW5nIGZpbGU6ICR7ZmlsZVBhdGh9YCk7XG4gICAgICBjb25zdCBzZW5kRmlsZU9wdGlvbnMgPSB7XG4gICAgICAgIGhlYWRlcnM6IHtcbiAgICAgICAgICAnWC1Db250ZW50LVR5cGUtT3B0aW9ucyc6ICdub3NuaWZmJyxcbiAgICAgICAgICAnQ29udGVudC1UeXBlJyAgICAgICAgICA6IGZpbGVUeXBlIHx8ICdpbWFnZS9qcGVnJyxcbiAgICAgICAgfSxcbiAgICAgIH07XG4gICAgICByZXMuc3RhdHVzKDIwMCkuc2VuZEZpbGUoZmlsZVBhdGgsIHNlbmRGaWxlT3B0aW9ucyk7XG4gICAgfSlcbiAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgdGhyb3cgZXJyb3I7XG4gICAgfSk7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgZ2V0Q2xhaW1JZEFuZFNlcnZlQXNzZXQgKGNoYW5uZWxOYW1lLCBjaGFubmVsQ2xhaW1JZCwgY2xhaW1OYW1lLCBjbGFpbUlkLCBvcmlnaW5hbFVybCwgaXAsIHJlcykge1xuICAgIC8vIGdldCB0aGUgY2xhaW0gSWQgYW5kIHRoZW4gc2VydmUgdGhlIGFzc2V0XG4gICAgZ2V0Q2xhaW1JZChjaGFubmVsTmFtZSwgY2hhbm5lbENsYWltSWQsIGNsYWltTmFtZSwgY2xhaW1JZClcbiAgICAgIC50aGVuKGZ1bGxDbGFpbUlkID0+IHtcbiAgICAgICAgaWYgKGZ1bGxDbGFpbUlkID09PSBOT19DTEFJTSkge1xuICAgICAgICAgIHJldHVybiByZXMuc3RhdHVzKDQwNCkuanNvbih7c3VjY2VzczogZmFsc2UsIG1lc3NhZ2U6ICdubyBjbGFpbSBpZCBjb3VsZCBiZSBmb3VuZCd9KTtcbiAgICAgICAgfSBlbHNlIGlmIChmdWxsQ2xhaW1JZCA9PT0gTk9fQ0hBTk5FTCkge1xuICAgICAgICAgIHJldHVybiByZXMuc3RhdHVzKDQwNCkuanNvbih7c3VjY2VzczogZmFsc2UsIG1lc3NhZ2U6ICdubyBjaGFubmVsIGlkIGNvdWxkIGJlIGZvdW5kJ30pO1xuICAgICAgICB9XG4gICAgICAgIHNlcnZlQXNzZXRUb0NsaWVudChmdWxsQ2xhaW1JZCwgY2xhaW1OYW1lLCByZXMpO1xuICAgICAgICAvLyBwb3N0VG9TdGF0cyhyZXNwb25zZVR5cGUsIG9yaWdpbmFsVXJsLCBpcCwgY2xhaW1OYW1lLCBmdWxsQ2xhaW1JZCwgJ3N1Y2Nlc3MnKTtcbiAgICAgIH0pXG4gICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICBoYW5kbGVFcnJvclJlc3BvbnNlKG9yaWdpbmFsVXJsLCBpcCwgZXJyb3IsIHJlcyk7XG4gICAgICAgIC8vIHBvc3RUb1N0YXRzKHJlc3BvbnNlVHlwZSwgb3JpZ2luYWxVcmwsIGlwLCBjbGFpbU5hbWUsIGZ1bGxDbGFpbUlkLCAnZmFpbCcpO1xuICAgICAgfSk7XG4gIH0sXG4gIGRldGVybWluZVJlc3BvbnNlVHlwZSAoaGFzRmlsZUV4dGVuc2lvbiwgaGVhZGVycykge1xuICAgIGxldCByZXNwb25zZVR5cGU7XG4gICAgaWYgKGhhc0ZpbGVFeHRlbnNpb24pIHtcbiAgICAgIHJlc3BvbnNlVHlwZSA9IFNFUlZFOyAgLy8gYXNzdW1lIGEgc2VydmUgcmVxdWVzdCBpZiBmaWxlIGV4dGVuc2lvbiBpcyBwcmVzZW50XG4gICAgICBpZiAoY2xpZW50QWNjZXB0c0h0bWwoaGVhZGVycykpIHsgIC8vIGlmIHRoZSByZXF1ZXN0IGNvbWVzIGZyb20gYSBicm93c2VyLCBjaGFuZ2UgaXQgdG8gYSBzaG93IHJlcXVlc3RcbiAgICAgICAgcmVzcG9uc2VUeXBlID0gU0hPVztcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgcmVzcG9uc2VUeXBlID0gU0hPVztcbiAgICAgIGlmIChjbGllbnRXYW50c0Fzc2V0KGhlYWRlcnMpICYmIHJlcXVlc3RJc0Zyb21Ccm93c2VyKGhlYWRlcnMpKSB7ICAvLyB0aGlzIGlzIGluIGNhc2Ugc29tZW9uZSBlbWJlZHMgYSBzaG93IHVybFxuICAgICAgICBsb2dnZXIuZGVidWcoJ1Nob3cgcmVxdWVzdCBjYW1lIGZyb20gYnJvd3NlciBidXQgd2FudHMgYW4gaW1hZ2UvdmlkZW8uIENoYW5naW5nIHJlc3BvbnNlIHRvIHNlcnZlLi4uJyk7XG4gICAgICAgIHJlc3BvbnNlVHlwZSA9IFNFUlZFO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gcmVzcG9uc2VUeXBlO1xuICB9LFxuICBmbGlwQ2xhaW1OYW1lQW5kSWRGb3JCYWNrd2FyZHNDb21wYXRpYmlsaXR5IChpZGVudGlmaWVyLCBuYW1lKSB7XG4gICAgLy8gdGhpcyBpcyBhIHBhdGNoIGZvciBiYWNrd2FyZHMgY29tcGF0YWJpbGl0eSB3aXRoICcvbmFtZS9jbGFpbV9pZCcgdXJsIGZvcm1hdFxuICAgIGlmIChpc1ZhbGlkU2hvcnRJZE9yQ2xhaW1JZChuYW1lKSAmJiAhaXNWYWxpZFNob3J0SWRPckNsYWltSWQoaWRlbnRpZmllcikpIHtcbiAgICAgIGNvbnN0IHRlbXBOYW1lID0gbmFtZTtcbiAgICAgIG5hbWUgPSBpZGVudGlmaWVyO1xuICAgICAgaWRlbnRpZmllciA9IHRlbXBOYW1lO1xuICAgIH1cbiAgICByZXR1cm4gW2lkZW50aWZpZXIsIG5hbWVdO1xuICB9LFxuICBsb2dSZXF1ZXN0RGF0YSAocmVzcG9uc2VUeXBlLCBjbGFpbU5hbWUsIGNoYW5uZWxOYW1lLCBjbGFpbUlkKSB7XG4gICAgbG9nZ2VyLmRlYnVnKCdyZXNwb25zZVR5cGUgPT09JywgcmVzcG9uc2VUeXBlKTtcbiAgICBsb2dnZXIuZGVidWcoJ2NsYWltIG5hbWUgPT09ICcsIGNsYWltTmFtZSk7XG4gICAgbG9nZ2VyLmRlYnVnKCdjaGFubmVsIG5hbWUgPT09JywgY2hhbm5lbE5hbWUpO1xuICAgIGxvZ2dlci5kZWJ1ZygnY2xhaW0gaWQgPT09JywgY2xhaW1JZCk7XG4gIH0sXG59O1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vc2VydmVyL2hlbHBlcnMvc2VydmVIZWxwZXJzLmpzIiwiY29uc3QgbG9nZ2VyID0gcmVxdWlyZSgnd2luc3RvbicpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgUkVHRVhQX0lOVkFMSURfQ0xBSU0gIDogL1teQS1aYS16MC05LV0vZyxcbiAgUkVHRVhQX0lOVkFMSURfQ0hBTk5FTDogL1teQS1aYS16MC05LUBdL2csXG4gIFJFR0VYUF9BRERSRVNTICAgICAgICA6IC9eYig/PVteME9JbF17MzIsMzN9KVswLTlBLVphLXpdezMyLDMzfSQvLFxuICBDSEFOTkVMX0NIQVIgICAgICAgICAgOiAnQCcsXG4gIHBhcnNlSWRlbnRpZmllciAgICAgICA6IGZ1bmN0aW9uIChpZGVudGlmaWVyKSB7XG4gICAgbG9nZ2VyLmRlYnVnKCdwYXJzaW5nIGlkZW50aWZpZXI6JywgaWRlbnRpZmllcik7XG4gICAgY29uc3QgY29tcG9uZW50c1JlZ2V4ID0gbmV3IFJlZ0V4cChcbiAgICAgICcoW146JCMvXSopJyArIC8vIHZhbHVlIChzdG9wcyBhdCB0aGUgZmlyc3Qgc2VwYXJhdG9yIG9yIGVuZClcbiAgICAgICcoWzokI10/KShbXi9dKiknIC8vIG1vZGlmaWVyIHNlcGFyYXRvciwgbW9kaWZpZXIgKHN0b3BzIGF0IHRoZSBmaXJzdCBwYXRoIHNlcGFyYXRvciBvciBlbmQpXG4gICAgKTtcbiAgICBjb25zdCBbcHJvdG8sIHZhbHVlLCBtb2RpZmllclNlcGVyYXRvciwgbW9kaWZpZXJdID0gY29tcG9uZW50c1JlZ2V4XG4gICAgICAuZXhlYyhpZGVudGlmaWVyKVxuICAgICAgLm1hcChtYXRjaCA9PiBtYXRjaCB8fCBudWxsKTtcbiAgICBsb2dnZXIuZGVidWcoYCR7cHJvdG99LCAke3ZhbHVlfSwgJHttb2RpZmllclNlcGVyYXRvcn0sICR7bW9kaWZpZXJ9YCk7XG5cbiAgICAvLyBWYWxpZGF0ZSBhbmQgcHJvY2VzcyBuYW1lXG4gICAgaWYgKCF2YWx1ZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBDaGVjayB5b3VyIHVybC4gIE5vIGNoYW5uZWwgbmFtZSBwcm92aWRlZCBiZWZvcmUgXCIke21vZGlmaWVyU2VwZXJhdG9yfVwiYCk7XG4gICAgfVxuICAgIGNvbnN0IGlzQ2hhbm5lbCA9IHZhbHVlLnN0YXJ0c1dpdGgobW9kdWxlLmV4cG9ydHMuQ0hBTk5FTF9DSEFSKTtcbiAgICBjb25zdCBjaGFubmVsTmFtZSA9IGlzQ2hhbm5lbCA/IHZhbHVlIDogbnVsbDtcbiAgICBsZXQgY2xhaW1JZDtcbiAgICBpZiAoaXNDaGFubmVsKSB7XG4gICAgICBpZiAoIWNoYW5uZWxOYW1lKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignTm8gY2hhbm5lbCBuYW1lIGFmdGVyIEAuJyk7XG4gICAgICB9XG4gICAgICBjb25zdCBuYW1lQmFkQ2hhcnMgPSAoY2hhbm5lbE5hbWUpLm1hdGNoKG1vZHVsZS5leHBvcnRzLlJFR0VYUF9JTlZBTElEX0NIQU5ORUwpO1xuICAgICAgaWYgKG5hbWVCYWRDaGFycykge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEludmFsaWQgY2hhcmFjdGVycyBpbiBjaGFubmVsIG5hbWU6ICR7bmFtZUJhZENoYXJzLmpvaW4oJywgJyl9LmApO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBjbGFpbUlkID0gdmFsdWU7XG4gICAgfVxuXG4gICAgLy8gVmFsaWRhdGUgYW5kIHByb2Nlc3MgbW9kaWZpZXJcbiAgICBsZXQgY2hhbm5lbENsYWltSWQ7XG4gICAgaWYgKG1vZGlmaWVyU2VwZXJhdG9yKSB7XG4gICAgICBpZiAoIW1vZGlmaWVyKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgTm8gbW9kaWZpZXIgcHJvdmlkZWQgYWZ0ZXIgc2VwYXJhdG9yIFwiJHttb2RpZmllclNlcGVyYXRvcn1cImApO1xuICAgICAgfVxuXG4gICAgICBpZiAobW9kaWZpZXJTZXBlcmF0b3IgPT09ICc6Jykge1xuICAgICAgICBjaGFubmVsQ2xhaW1JZCA9IG1vZGlmaWVyO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBUaGUgXCIke21vZGlmaWVyU2VwZXJhdG9yfVwiIG1vZGlmaWVyIGlzIG5vdCBjdXJyZW50bHkgc3VwcG9ydGVkYCk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiB7XG4gICAgICBpc0NoYW5uZWwsXG4gICAgICBjaGFubmVsTmFtZSxcbiAgICAgIGNoYW5uZWxDbGFpbUlkLFxuICAgICAgY2xhaW1JZCxcbiAgICB9O1xuICB9LFxuICBwYXJzZUNsYWltOiBmdW5jdGlvbiAoY2xhaW0pIHtcbiAgICBsb2dnZXIuZGVidWcoJ3BhcnNpbmcgbmFtZTonLCBjbGFpbSk7XG4gICAgY29uc3QgY29tcG9uZW50c1JlZ2V4ID0gbmV3IFJlZ0V4cChcbiAgICAgICcoW146JCMvLl0qKScgKyAvLyBuYW1lIChzdG9wcyBhdCB0aGUgZmlyc3QgbW9kaWZpZXIpXG4gICAgICAnKFs6JCMuXT8pKFteL10qKScgLy8gbW9kaWZpZXIgc2VwYXJhdG9yLCBtb2RpZmllciAoc3RvcHMgYXQgdGhlIGZpcnN0IHBhdGggc2VwYXJhdG9yIG9yIGVuZClcbiAgICApO1xuICAgIGNvbnN0IFtwcm90bywgY2xhaW1OYW1lLCBtb2RpZmllclNlcGVyYXRvciwgbW9kaWZpZXJdID0gY29tcG9uZW50c1JlZ2V4XG4gICAgICAuZXhlYyhjbGFpbSlcbiAgICAgIC5tYXAobWF0Y2ggPT4gbWF0Y2ggfHwgbnVsbCk7XG4gICAgbG9nZ2VyLmRlYnVnKGAke3Byb3RvfSwgJHtjbGFpbU5hbWV9LCAke21vZGlmaWVyU2VwZXJhdG9yfSwgJHttb2RpZmllcn1gKTtcblxuICAgIC8vIFZhbGlkYXRlIGFuZCBwcm9jZXNzIG5hbWVcbiAgICBpZiAoIWNsYWltTmFtZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdObyBjbGFpbSBuYW1lIHByb3ZpZGVkIGJlZm9yZSAuJyk7XG4gICAgfVxuICAgIGNvbnN0IG5hbWVCYWRDaGFycyA9IChjbGFpbU5hbWUpLm1hdGNoKG1vZHVsZS5leHBvcnRzLlJFR0VYUF9JTlZBTElEX0NMQUlNKTtcbiAgICBpZiAobmFtZUJhZENoYXJzKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYEludmFsaWQgY2hhcmFjdGVycyBpbiBjbGFpbSBuYW1lOiAke25hbWVCYWRDaGFycy5qb2luKCcsICcpfS5gKTtcbiAgICB9XG4gICAgLy8gVmFsaWRhdGUgYW5kIHByb2Nlc3MgbW9kaWZpZXJcbiAgICBpZiAobW9kaWZpZXJTZXBlcmF0b3IpIHtcbiAgICAgIGlmICghbW9kaWZpZXIpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBObyBmaWxlIGV4dGVuc2lvbiBwcm92aWRlZCBhZnRlciBzZXBhcmF0b3IgJHttb2RpZmllclNlcGVyYXRvcn0uYCk7XG4gICAgICB9XG4gICAgICBpZiAobW9kaWZpZXJTZXBlcmF0b3IgIT09ICcuJykge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFRoZSAke21vZGlmaWVyU2VwZXJhdG9yfSBtb2RpZmllciBpcyBub3Qgc3VwcG9ydGVkIGluIHRoZSBjbGFpbSBuYW1lYCk7XG4gICAgICB9XG4gICAgfVxuICAgIC8vIHJldHVybiByZXN1bHRzXG4gICAgcmV0dXJuIHtcbiAgICAgIGNsYWltTmFtZSxcbiAgICB9O1xuICB9LFxuICBwYXJzZU1vZGlmaWVyOiBmdW5jdGlvbiAoY2xhaW0pIHtcbiAgICBsb2dnZXIuZGVidWcoJ3BhcnNpbmcgbW9kaWZpZXI6JywgY2xhaW0pO1xuICAgIGNvbnN0IGNvbXBvbmVudHNSZWdleCA9IG5ldyBSZWdFeHAoXG4gICAgICAnKFteOiQjLy5dKiknICsgLy8gbmFtZSAoc3RvcHMgYXQgdGhlIGZpcnN0IG1vZGlmaWVyKVxuICAgICAgJyhbOiQjLl0/KShbXi9dKiknIC8vIG1vZGlmaWVyIHNlcGFyYXRvciwgbW9kaWZpZXIgKHN0b3BzIGF0IHRoZSBmaXJzdCBwYXRoIHNlcGFyYXRvciBvciBlbmQpXG4gICAgKTtcbiAgICBjb25zdCBbcHJvdG8sIGNsYWltTmFtZSwgbW9kaWZpZXJTZXBlcmF0b3IsIG1vZGlmaWVyXSA9IGNvbXBvbmVudHNSZWdleFxuICAgICAgLmV4ZWMoY2xhaW0pXG4gICAgICAubWFwKG1hdGNoID0+IG1hdGNoIHx8IG51bGwpO1xuICAgIGxvZ2dlci5kZWJ1ZyhgJHtwcm90b30sICR7Y2xhaW1OYW1lfSwgJHttb2RpZmllclNlcGVyYXRvcn0sICR7bW9kaWZpZXJ9YCk7XG4gICAgLy8gVmFsaWRhdGUgYW5kIHByb2Nlc3MgbW9kaWZpZXJcbiAgICBsZXQgaGFzRmlsZUV4dGVuc2lvbiA9IGZhbHNlO1xuICAgIGlmIChtb2RpZmllclNlcGVyYXRvcikge1xuICAgICAgaGFzRmlsZUV4dGVuc2lvbiA9IHRydWU7XG4gICAgfVxuICAgIHJldHVybiB7XG4gICAgICBoYXNGaWxlRXh0ZW5zaW9uLFxuICAgIH07XG4gIH0sXG59O1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vc2VydmVyL2hlbHBlcnMvbGJyeVVyaS5qcyIsImltcG9ydCBSZWFjdCBmcm9tICdyZWFjdCc7XG5pbXBvcnQgeyByZW5kZXJUb1N0cmluZyB9IGZyb20gJ3JlYWN0LWRvbS9zZXJ2ZXInO1xuaW1wb3J0IHsgY3JlYXRlU3RvcmUsIGFwcGx5TWlkZGxld2FyZSB9IGZyb20gJ3JlZHV4JztcbmltcG9ydCB7IFByb3ZpZGVyIH0gZnJvbSAncmVhY3QtcmVkdXgnO1xuaW1wb3J0IHsgU3RhdGljUm91dGVyIH0gZnJvbSAncmVhY3Qtcm91dGVyLWRvbSc7XG5pbXBvcnQgcmVuZGVyRnVsbFBhZ2UgZnJvbSAnLi9yZW5kZXJGdWxsUGFnZSc7XG5pbXBvcnQgY3JlYXRlU2FnYU1pZGRsZXdhcmUgZnJvbSAncmVkdXgtc2FnYSc7XG5pbXBvcnQgeyBjYWxsIH0gZnJvbSAncmVkdXgtc2FnYS9lZmZlY3RzJztcbmltcG9ydCB7IFJlZHVjZXJzLCBHQUxpc3RlbmVyLCBBcHAsIFNhZ2FzLCBBY3Rpb25zIH0gZnJvbSAnc3BlZS5jaC1jb21wb25lbnRzJztcbi8qXG4gIF4gbm90ZTogdG8gZG8gdGhpcyByaWdodCwgbWF5YmVcbiAgdGhlc2Ugc2hvdWxkIGJlIHBhc3NlZCBpbiBmcm9tIHRoZSBpbXBsZW1lbnRhdGlvbiAod3d3LnNwZWUuY2gpIGl0c2VsZixcbiAgc28gdGhhdCB0aGVyZSBhcmUgbm8gY29uZmxpY3RzIGJldHdlZW4gdGhlIFNTUiBoZXJlIGFuZFxuICB0aGUgYnVuZGxlIHNlbnQgdG8gdGhlIHNlcnZlcj9cbiAgdGhlcmUgbWlnaHQgYWxzbyBiZSBpc3N1ZXMgaWYgdGhpcyBwYWNrYWdlIHVzZXMgYSBkaWZmZXJlbnQgdmVyc2lvbiBvZiBzcGVlLmNoLWNvbXBvbmVudHMgdGhhbiB3d3cuc3BlZS5jaCBkb2VzP1xuKi9cbmltcG9ydCBIZWxtZXQgZnJvbSAncmVhY3QtaGVsbWV0JztcblxuLy8gY29uZmlndXJlIHRoZSByZWR1Y2VycyBieSBwYXNzaW5nIGluaXRpYWwgc3RhdGUgY29uZmlnc1xuY29uc3Qgc2l0ZUNvbmZpZyA9IHJlcXVpcmUoJ3NpdGVDb25maWcuanMnKTtcbmNvbnN0IE15UmVkdWNlcnMgPSBSZWR1Y2VycyhzaXRlQ29uZmlnKTtcbmNvbnN0IE15QXBwID0gQXBwKHNpdGVDb25maWcpO1xuY29uc3QgTXlHQUxpc3RlbmVyID0gR0FMaXN0ZW5lcihzaXRlQ29uZmlnKTtcblxuY29uc3QgcmV0dXJuU2FnYVdpdGhQYXJhbXMgPSAoc2FnYSwgcGFyYW1zKSA9PiB7XG4gIHJldHVybiBmdW5jdGlvbiAqICgpIHtcbiAgICB5aWVsZCBjYWxsKHNhZ2EsIHBhcmFtcyk7XG4gIH07XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IChyZXEsIHJlcykgPT4ge1xuICBsZXQgY29udGV4dCA9IHt9O1xuXG4gIC8vIGNyZWF0ZSBhbmQgYXBwbHkgbWlkZGxld2FyZVxuICBjb25zdCBzYWdhTWlkZGxld2FyZSA9IGNyZWF0ZVNhZ2FNaWRkbGV3YXJlKCk7XG4gIGNvbnN0IG1pZGRsZXdhcmUgPSBhcHBseU1pZGRsZXdhcmUoc2FnYU1pZGRsZXdhcmUpO1xuXG4gIC8vIGNyZWF0ZSBhIG5ldyBSZWR1eCBzdG9yZSBpbnN0YW5jZVxuICBjb25zdCBzdG9yZSA9IGNyZWF0ZVN0b3JlKE15UmVkdWNlcnMsIG1pZGRsZXdhcmUpO1xuXG4gIC8vIGNyZWF0ZSBzYWdhXG4gIGNvbnN0IGFjdGlvbiA9IEFjdGlvbnMub25IYW5kbGVTaG93UGFnZVVyaShyZXEucGFyYW1zKTtcbiAgY29uc3Qgc2FnYSA9IHJldHVyblNhZ2FXaXRoUGFyYW1zKFNhZ2FzLmhhbmRsZVNob3dQYWdlVXJpLCBhY3Rpb24pO1xuXG4gIC8vIHJ1biB0aGUgc2FnYSBtaWRkbGV3YXJlXG4gIHNhZ2FNaWRkbGV3YXJlXG4gICAgLnJ1bihzYWdhKVxuICAgIC5kb25lXG4gICAgLnRoZW4oKCkgPT4ge1xuICAgICAgLy8gcmVuZGVyIGNvbXBvbmVudCB0byBhIHN0cmluZ1xuICAgICAgY29uc3QgaHRtbCA9IHJlbmRlclRvU3RyaW5nKFxuICAgICAgICA8UHJvdmlkZXIgc3RvcmU9e3N0b3JlfT5cbiAgICAgICAgICA8U3RhdGljUm91dGVyIGxvY2F0aW9uPXtyZXEudXJsfSBjb250ZXh0PXtjb250ZXh0fT5cbiAgICAgICAgICAgIDxNeUdBTGlzdGVuZXI+XG4gICAgICAgICAgICAgIDxNeUFwcCAvPlxuICAgICAgICAgICAgPC9NeUdBTGlzdGVuZXI+XG4gICAgICAgICAgPC9TdGF0aWNSb3V0ZXI+XG4gICAgICAgIDwvUHJvdmlkZXI+XG4gICAgICApO1xuXG4gICAgICAvLyBnZXQgaGVhZCB0YWdzIGZyb20gaGVsbWV0XG4gICAgICBjb25zdCBoZWxtZXQgPSBIZWxtZXQucmVuZGVyU3RhdGljKCk7XG5cbiAgICAgIC8vIGNoZWNrIGZvciBhIHJlZGlyZWN0XG4gICAgICBpZiAoY29udGV4dC51cmwpIHtcbiAgICAgICAgcmV0dXJuIHJlcy5yZWRpcmVjdCgzMDEsIGNvbnRleHQudXJsKTtcbiAgICAgIH1cblxuICAgICAgLy8gZ2V0IHRoZSBpbml0aWFsIHN0YXRlIGZyb20gb3VyIFJlZHV4IHN0b3JlXG4gICAgICBjb25zdCBwcmVsb2FkZWRTdGF0ZSA9IHN0b3JlLmdldFN0YXRlKCk7XG5cbiAgICAgIC8vIHNlbmQgdGhlIHJlbmRlcmVkIHBhZ2UgYmFjayB0byB0aGUgY2xpZW50XG4gICAgICByZXMuc2VuZChyZW5kZXJGdWxsUGFnZShoZWxtZXQsIGh0bWwsIHByZWxvYWRlZFN0YXRlKSk7XG4gICAgfSk7XG5cbiAgY29uc29sZS5sb2coJ2hlbGxvIGZyb20gc3BlZS5jaCBoYW5kbGVTaG93UmVuZGVyLmpzeCcpO1xufTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL3NlcnZlci9oZWxwZXJzL2hhbmRsZVNob3dSZW5kZXIuanN4IiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwiYmFiZWwtcG9seWZpbGxcIik7XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gZXh0ZXJuYWwgXCJiYWJlbC1wb2x5ZmlsbFwiXG4vLyBtb2R1bGUgaWQgPSAyN1xuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCJ3aGF0d2ctZmV0Y2hcIik7XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gZXh0ZXJuYWwgXCJ3aGF0d2ctZmV0Y2hcIlxuLy8gbW9kdWxlIGlkID0gMjhcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiY29uc3QgU2VydmVyID0gcmVxdWlyZSgnLi9zZXJ2ZXInKTtcblxuY29uc3QgZXhwb3J0cyA9IHtcbiAgU2VydmVyLFxufTtcblxubW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzO1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vc3BlZWNoLmpzIiwiLy8gYXBwIGRlcGVuZGVuY2llc1xuY29uc3QgZXhwcmVzcyA9IHJlcXVpcmUoJ2V4cHJlc3MnKTtcbmNvbnN0IGJvZHlQYXJzZXIgPSByZXF1aXJlKCdib2R5LXBhcnNlcicpO1xuY29uc3QgZXhwcmVzc0hhbmRsZWJhcnMgPSByZXF1aXJlKCdleHByZXNzLWhhbmRsZWJhcnMnKTtcbmNvbnN0IEhhbmRsZWJhcnMgPSByZXF1aXJlKCdoYW5kbGViYXJzJyk7XG5jb25zdCBoZWxtZXQgPSByZXF1aXJlKCdoZWxtZXQnKTtcbmNvbnN0IGNvb2tpZVNlc3Npb24gPSByZXF1aXJlKCdjb29raWUtc2Vzc2lvbicpO1xuY29uc3QgaHR0cCA9IHJlcXVpcmUoJ2h0dHAnKTtcbmNvbnN0IGxvZ2dlciA9IHJlcXVpcmUoJ3dpbnN0b24nKTtcbmNvbnN0IHJlcXVlc3RMb2dnZXIgPSByZXF1aXJlKCdtaWRkbGV3YXJlL3JlcXVlc3RMb2dnZXIuanMnKTtcbmNvbnN0IFBhdGggPSByZXF1aXJlKCdwYXRoJyk7XG5jb25zdCBsb2dnZXJDb25maWcgPSByZXF1aXJlKCdsb2dnZXJDb25maWcuanMnKTtcbmNvbnN0IG15c3FsQ29uZmlnID0gcmVxdWlyZSgnbXlzcWxDb25maWcuanMnKTtcbmNvbnN0IHNpdGVDb25maWcgPSByZXF1aXJlKCdzaXRlQ29uZmlnLmpzJyk7XG5jb25zdCBzbGFja0NvbmZpZyA9IHJlcXVpcmUoJ3NsYWNrQ29uZmlnLmpzJyk7XG5cbmZ1bmN0aW9uIFNlcnZlciAoKSB7XG4gIHRoaXMuY29uZmlndXJlTG9nZ2VyID0gKHVzZXJDb25maWcpID0+IHtcbiAgICBsb2dnZXJDb25maWcudXBkYXRlKHVzZXJDb25maWcpO1xuICB9O1xuICB0aGlzLmNvbmZpZ3VyZU15c3FsID0gKHVzZXJDb25maWcpID0+IHtcbiAgICBteXNxbENvbmZpZy51cGRhdGUodXNlckNvbmZpZyk7XG4gIH07XG4gIHRoaXMuY29uZmlndXJlU2l0ZURldGFpbHMgPSAodXNlckNvbmZpZykgPT4ge1xuICAgIHNpdGVDb25maWcudXBkYXRlKHVzZXJDb25maWcpO1xuICB9O1xuICB0aGlzLmNvbmZpZ3VyZVNsYWNrID0gKHVzZXJDb25maWcpID0+IHtcbiAgICBzbGFja0NvbmZpZy51cGRhdGUodXNlckNvbmZpZyk7XG4gIH07XG4gIHRoaXMuY29uZmlndXJlQ2xpZW50QnVuZGxlID0gKCkgPT4ge1xuICAgIGxvZ2dlci5kZWJ1ZygnY29uZmlndXJlIHRoZSBjbGllbnQgaGVyZSBieSBwYXNzaW5nIGluIHRoZSBidW5kbGUgYW5kIGNvbmZpZ3VyaW5nIGl0LCBvciBiZXR0ZXIgeWV0OiB0YWtpbmcgaW4gdGhlIGNvbXBvbmVudHMgdG8gdXNlIGR5bmFtaWNhbGx5IGZyb20gaGVyZS4nKTtcbiAgfTtcbiAgdGhpcy5jb25maWd1cmVNb2RlbHMgPSAoKSA9PiB7XG4gICAgbG9nZ2VyLmRlYnVnKCdoZXJlIGlzIHdoZXJlIHlvdSBjb3VsZCBhZGQvb3ZlcndyaXRlIHRoZSBkZWZhdWx0IG1vZGVscycpXG4gIH07XG4gIHRoaXMuY29uZmlndXJlUm91dGVzID0gKCkgPT4ge1xuICAgIGxvZ2dlci5kZWJ1ZygnaGVyZSBpcyB3aGVyZSB5b3UgY291bGQgYWRkL292ZXJ3cml0ZSB0aGUgZGVmYXVsdCByb3V0ZXMnKVxuICB9O1xuICB0aGlzLmNyZWF0ZUFwcCA9ICgpID0+IHtcbiAgICAvLyBjcmVhdGUgYW4gRXhwcmVzcyBhcHBsaWNhdGlvblxuICAgIGNvbnN0IGFwcCA9IGV4cHJlc3MoKTtcblxuICAgIC8vIHRydXN0IHRoZSBwcm94eSB0byBnZXQgaXAgYWRkcmVzcyBmb3IgdXNcbiAgICBhcHAuZW5hYmxlKCd0cnVzdCBwcm94eScpO1xuXG4gICAgLyogYWRkIG1pZGRsZXdhcmUgKi9cbiAgICAvLyBzZXQgSFRUUCBoZWFkZXJzIHRvIHByb3RlY3QgYWdhaW5zdCB3ZWxsLWtub3duIHdlYiB2dWxuZXJhYmlsdGllc1xuICAgIGFwcC51c2UoaGVsbWV0KCkpO1xuICAgIC8vICdleHByZXNzLnN0YXRpYycgdG8gc2VydmUgc3RhdGljIGZpbGVzIGZyb20gcHVibGljIGRpcmVjdG9yeVxuICAgIGlmIChzaXRlQ29uZmlnLnJvdXRlcy5wdWJsaWNGb2xkZXIpIHtcbiAgICAgIC8vIHRha2UgaW4gYSBkaWZmZXJlbnQgcHVibGljIGZvbGRlciwgc28gaXQgY2FuIHNlcnZlIGl0J3Mgb3duIGJ1bmRsZSBpZiBuZWVkZWRcbiAgICAgIGNvbnN0IHB1YmxpY0ZvbGRlciA9IFBhdGgucmVzb2x2ZShwcm9jZXNzLmN3ZCgpLCBzaXRlQ29uZmlnLnJvdXRlcy5wdWJsaWNGb2xkZXIpO1xuICAgICAgYXBwLnVzZShleHByZXNzLnN0YXRpYyhwdWJsaWNGb2xkZXIpKTtcbiAgICAgIGxvZ2dlci5pbmZvKCdzZXJ2aW5nIHN0YXRpYyBmaWxlcyBmcm9tIGN1c3RvbSBwYXRoOicsIHB1YmxpY0ZvbGRlcik7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IHB1YmxpY1BhdGggPSBQYXRoLnJlc29sdmUoX19kaXJuYW1lLCAncHVibGljJyk7XG4gICAgICBhcHAudXNlKGV4cHJlc3Muc3RhdGljKHB1YmxpY1BhdGgpKTtcbiAgICAgIGxvZ2dlci5pbmZvKCdzZXJ2aW5nIHN0YXRpYyBmaWxlcyBmcm9tIGRlZmF1bHQgcGF0aDonLCBwdWJsaWNQYXRoKTtcbiAgICB9O1xuICAgIC8vICdib2R5IHBhcnNlcicgZm9yIHBhcnNpbmcgYXBwbGljYXRpb24vanNvblxuICAgIGFwcC51c2UoYm9keVBhcnNlci5qc29uKCkpO1xuICAgIC8vICdib2R5IHBhcnNlcicgZm9yIHBhcnNpbmcgYXBwbGljYXRpb24veC13d3ctZm9ybS11cmxlbmNvZGVkXG4gICAgYXBwLnVzZShib2R5UGFyc2VyLnVybGVuY29kZWQoeyBleHRlbmRlZDogdHJ1ZSB9KSk7XG5cbiAgICAvLyBhZGQgY3VzdG9tIG1pZGRsZXdhcmUgKG5vdGU6IGJ1aWxkIG91dCB0byBhY2NlcHQgZHluYW1pY2FsbHkgdXNlIHdoYXQgaXMgaW4gc2VydmVyL21pZGRsZXdhcmUvXG4gICAgYXBwLnVzZShyZXF1ZXN0TG9nZ2VyKTtcblxuICAgIC8vIGNvbmZpZ3VyZSBwYXNzcG9ydFxuICAgIGNvbnN0IHNwZWVjaFBhc3Nwb3J0ID0gcmVxdWlyZSgnc3BlZWNoUGFzc3BvcnQnKTtcbiAgICAvLyBpbml0aWFsaXplIHBhc3Nwb3J0XG4gICAgY29uc3Qgc2Vzc2lvbktleSA9IHNpdGVDb25maWcuYXV0aC5zZXNzaW9uS2V5O1xuICAgIGFwcC51c2UoY29va2llU2Vzc2lvbih7XG4gICAgICBuYW1lICA6ICdzZXNzaW9uJyxcbiAgICAgIGtleXMgIDogW3Nlc3Npb25LZXldLFxuICAgICAgbWF4QWdlOiAyNCAqIDYwICogNjAgKiAxMDAwLCAvLyBpLmUuIDI0IGhvdXJzXG4gICAgfSkpO1xuICAgIGFwcC51c2Uoc3BlZWNoUGFzc3BvcnQuaW5pdGlhbGl6ZSgpKTtcbiAgICBhcHAudXNlKHNwZWVjaFBhc3Nwb3J0LnNlc3Npb24oKSk7XG5cbiAgICAvLyBjb25maWd1cmUgaGFuZGxlYmFycyAmIHJlZ2lzdGVyIGl0IHdpdGggZXhwcmVzcyBhcHBcbiAgICBjb25zdCBoYnMgPSBleHByZXNzSGFuZGxlYmFycy5jcmVhdGUoe1xuICAgICAgZGVmYXVsdExheW91dDogJ2VtYmVkJyxcbiAgICAgIGhhbmRsZWJhcnMgICA6IEhhbmRsZWJhcnMsXG4gICAgfSk7XG4gICAgYXBwLmVuZ2luZSgnaGFuZGxlYmFycycsIGhicy5lbmdpbmUpO1xuICAgIGFwcC5zZXQoJ3ZpZXcgZW5naW5lJywgJ2hhbmRsZWJhcnMnKTtcblxuICAgIC8vIHNldCB0aGUgcm91dGVzIG9uIHRoZSBhcHBcbiAgICByZXF1aXJlKCcuL3JvdXRlcy9hdXRoLycpKGFwcCk7XG4gICAgcmVxdWlyZSgnLi9yb3V0ZXMvYXBpLycpKGFwcCk7XG4gICAgcmVxdWlyZSgnLi9yb3V0ZXMvcGFnZXMvJykoYXBwKTtcbiAgICByZXF1aXJlKCcuL3JvdXRlcy9hc3NldHMvJykoYXBwKTtcbiAgICByZXF1aXJlKCcuL3JvdXRlcy9mYWxsYmFjay8nKShhcHApO1xuXG4gICAgdGhpcy5hcHAgPSBhcHA7XG4gIH07XG4gIHRoaXMuaW5pdGlhbGl6ZSA9ICgpID0+IHtcbiAgICB0aGlzLmNyZWF0ZUFwcCgpO1xuICAgIHRoaXMuc2VydmVyID0gaHR0cC5TZXJ2ZXIodGhpcy5hcHApO1xuICB9O1xuICB0aGlzLnN0YXJ0ID0gKCkgPT4ge1xuICAgIGNvbnN0IGRiID0gcmVxdWlyZSgnbW9kZWxzJyk7XG4gICAgY29uc3QgUE9SVCA9IHNpdGVDb25maWcuZGV0YWlscy5wb3J0O1xuICAgIC8vIHN5bmMgc2VxdWVsaXplXG4gICAgZGIuc2VxdWVsaXplLnN5bmMoKVxuICAgIC8vIHN0YXJ0IHRoZSBzZXJ2ZXJcbiAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgdGhpcy5zZXJ2ZXIubGlzdGVuKFBPUlQsICgpID0+IHtcbiAgICAgICAgICBsb2dnZXIuaW5mbyhgU2VydmVyIGlzIGxpc3RlbmluZyBvbiBQT1JUICR7UE9SVH1gKTtcbiAgICAgICAgfSk7XG4gICAgICB9KVxuICAgICAgLmNhdGNoKChlcnJvcikgPT4ge1xuICAgICAgICBsb2dnZXIuZXJyb3IoYFN0YXJ0dXAgRXJyb3I6YCwgZXJyb3IpO1xuICAgICAgfSk7XG4gIH07XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IFNlcnZlcjtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL3NlcnZlci9pbmRleC5qcyIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcImV4cHJlc3NcIik7XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gZXh0ZXJuYWwgXCJleHByZXNzXCJcbi8vIG1vZHVsZSBpZCA9IDMxXG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcImJvZHktcGFyc2VyXCIpO1xuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIGV4dGVybmFsIFwiYm9keS1wYXJzZXJcIlxuLy8gbW9kdWxlIGlkID0gMzJcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwiZXhwcmVzcy1oYW5kbGViYXJzXCIpO1xuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIGV4dGVybmFsIFwiZXhwcmVzcy1oYW5kbGViYXJzXCJcbi8vIG1vZHVsZSBpZCA9IDMzXG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcImhhbmRsZWJhcnNcIik7XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gZXh0ZXJuYWwgXCJoYW5kbGViYXJzXCJcbi8vIG1vZHVsZSBpZCA9IDM0XG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcImhlbG1ldFwiKTtcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyBleHRlcm5hbCBcImhlbG1ldFwiXG4vLyBtb2R1bGUgaWQgPSAzNVxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCJjb29raWUtc2Vzc2lvblwiKTtcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyBleHRlcm5hbCBcImNvb2tpZS1zZXNzaW9uXCJcbi8vIG1vZHVsZSBpZCA9IDM2XG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcImh0dHBcIik7XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gZXh0ZXJuYWwgXCJodHRwXCJcbi8vIG1vZHVsZSBpZCA9IDM3XG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsImNvbnN0IGxvZ2dlciA9IHJlcXVpcmUoJ3dpbnN0b24nKTtcblxuY29uc3QgcmVxdWVzdExvZ2dlciA9IChyZXEsIHJlcywgbmV4dCkgPT4geyAgLy8gY3VzdG9tIGxvZ2dpbmcgbWlkZGxld2FyZSB0byBsb2cgYWxsIGluY29taW5nIGh0dHAgcmVxdWVzdHNcbiAgbG9nZ2VyLnZlcmJvc2UoYFJlcXVlc3Qgb24gJHtyZXEub3JpZ2luYWxVcmx9IGZyb20gJHtyZXEuaXB9YCk7XG4gIG5leHQoKTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gcmVxdWVzdExvZ2dlcjtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL3NlcnZlci9taWRkbGV3YXJlL3JlcXVlc3RMb2dnZXIuanMiLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCJwYXRoXCIpO1xuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIGV4dGVybmFsIFwicGF0aFwiXG4vLyBtb2R1bGUgaWQgPSAzOVxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJjb25zdCBsb2dnZXIgPSByZXF1aXJlKCd3aW5zdG9uJyk7XG5cbmZ1bmN0aW9uIExvZ2dlckNvbmZpZyAoKSB7XG4gIHRoaXMubG9nTGV2ZWwgPSAnZGVidWcnO1xuICB0aGlzLnVwZGF0ZSA9IChjb25maWcpID0+IHtcbiAgICBpZiAoIWNvbmZpZykge1xuICAgICAgcmV0dXJuIGxvZ2dlci53YXJuKCdObyBsb2dnZXIgY29uZmlnIHJlY2VpdmVkLicpO1xuICAgIH1cbiAgICBsb2dnZXIuaW5mbygnY29uZmlndXJpbmcgd2luc3RvbiBsb2dnZXIuLi4nKTtcbiAgICAvLyB1cGRhdGUgdmFsdWVzIHdpdGggbG9jYWwgY29uZmlnIHBhcmFtc1xuICAgIGNvbnN0IHtsb2dMZXZlbH0gPSBjb25maWc7XG4gICAgdGhpcy5sb2dMZXZlbCA9IGxvZ0xldmVsO1xuICAgIC8vIGNvbmZpZ3VyZSB0aGUgd2luc3RvbiBsb2dnZXJcbiAgICBsb2dnZXIuY29uZmlndXJlKHtcbiAgICAgIHRyYW5zcG9ydHM6IFtcbiAgICAgICAgbmV3IChsb2dnZXIudHJhbnNwb3J0cy5Db25zb2xlKSh7XG4gICAgICAgICAgbGV2ZWwgICAgICAgICAgICAgICAgICAgICAgICAgIDogdGhpcy5sb2dMZXZlbCxcbiAgICAgICAgICB0aW1lc3RhbXAgICAgICAgICAgICAgICAgICAgICAgOiBmYWxzZSxcbiAgICAgICAgICBjb2xvcml6ZSAgICAgICAgICAgICAgICAgICAgICAgOiB0cnVlLFxuICAgICAgICAgIHByZXR0eVByaW50ICAgICAgICAgICAgICAgICAgICA6IHRydWUsXG4gICAgICAgICAgaGFuZGxlRXhjZXB0aW9ucyAgICAgICAgICAgICAgIDogdHJ1ZSxcbiAgICAgICAgICBodW1hblJlYWRhYmxlVW5oYW5kbGVkRXhjZXB0aW9uOiB0cnVlLFxuICAgICAgICB9KSxcbiAgICAgIF0sXG4gICAgfSk7XG4gICAgLy8gdGVzdCBhbGwgdGhlIGxvZyBsZXZlbHNcbiAgICBsb2dnZXIuaW5mbygndGVzdGluZyB3aW5zdG9uIGxvZyBsZXZlbHMuLi4nKTtcbiAgICBsb2dnZXIuZXJyb3IoJ0xldmVsIDAnKTtcbiAgICBsb2dnZXIud2FybignTGV2ZWwgMScpO1xuICAgIGxvZ2dlci5pbmZvKCdMZXZlbCAyJyk7XG4gICAgbG9nZ2VyLnZlcmJvc2UoJ0xldmVsIDMnKTtcbiAgICBsb2dnZXIuZGVidWcoJ0xldmVsIDQnKTtcbiAgICBsb2dnZXIuc2lsbHkoJ0xldmVsIDUnKTtcbiAgfTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gbmV3IExvZ2dlckNvbmZpZygpO1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vY29uZmlnL2xvZ2dlckNvbmZpZy5qcyIsImNvbnN0IHdpbnN0b25TbGFja1dlYkhvb2sgPSByZXF1aXJlKCd3aW5zdG9uLXNsYWNrLXdlYmhvb2snKS5TbGFja1dlYkhvb2s7XG5jb25zdCB3aW5zdG9uID0gcmVxdWlyZSgnd2luc3RvbicpO1xuXG5mdW5jdGlvbiBTbGFja0NvbmZpZyAoKSB7XG4gIHRoaXMuc2xhY2tXZWJIb29rICAgICAgPSAnZGVmYXVsdCc7XG4gIHRoaXMuc2xhY2tFcnJvckNoYW5uZWwgPSAnZGVmYXVsdCc7XG4gIHRoaXMuc2xhY2tJbmZvQ2hhbm5lbCAgPSAnZGVmYXVsdCc7XG4gIHRoaXMudXBkYXRlID0gKGNvbmZpZykgPT4ge1xuICAgIGlmICghY29uZmlnKSB7XG4gICAgICByZXR1cm4gd2luc3Rvbi53YXJuKCdObyBzbGFjayBjb25maWcgcmVjZWl2ZWQnKTtcbiAgICB9XG4gICAgLy8gdXBkYXRlIHZhcmlhYmxlc1xuICAgIHdpbnN0b24uaW5mbygnY29uZmlndXJpbmcgc2xhY2sgbG9nZ2VyLi4uJyk7XG4gICAgY29uc3Qge3NsYWNrV2ViSG9vaywgc2xhY2tFcnJvckNoYW5uZWwsIHNsYWNrSW5mb0NoYW5uZWx9ID0gY29uZmlnO1xuICAgIHRoaXMuc2xhY2tXZWJIb29rID0gc2xhY2tXZWJIb29rO1xuICAgIHRoaXMuc2xhY2tFcnJvckNoYW5uZWwgPSBzbGFja0Vycm9yQ2hhbm5lbDtcbiAgICB0aGlzLnNsYWNrSW5mb0NoYW5uZWwgPSBzbGFja0luZm9DaGFubmVsO1xuICAgIC8vIHVwZGF0ZSBzbGFjayB3ZWJob29rIHNldHRpbmdzXG4gICAgaWYgKHRoaXMuc2xhY2tXZWJIb29rKSB7XG4gICAgICAvLyBhZGQgYSB0cmFuc3BvcnQgZm9yIGVycm9ycyB0byBzbGFja1xuICAgICAgaWYgKHRoaXMuc2xhY2tFcnJvckNoYW5uZWwpIHtcbiAgICAgICAgd2luc3Rvbi5hZGQod2luc3RvblNsYWNrV2ViSG9vaywge1xuICAgICAgICAgIG5hbWUgICAgICA6ICdzbGFjay1lcnJvcnMtdHJhbnNwb3J0JyxcbiAgICAgICAgICBsZXZlbCAgICAgOiAnd2FybicsXG4gICAgICAgICAgd2ViaG9va1VybDogdGhpcy5zbGFja1dlYkhvb2ssXG4gICAgICAgICAgY2hhbm5lbCAgIDogdGhpcy5zbGFja0Vycm9yQ2hhbm5lbCxcbiAgICAgICAgICB1c2VybmFtZSAgOiAnc3BlZS5jaCcsXG4gICAgICAgICAgaWNvbkVtb2ppIDogJzpmYWNlX3dpdGhfaGVhZF9iYW5kYWdlOicsXG4gICAgICAgIH0pO1xuICAgICAgfTtcbiAgICAgIGlmIChzbGFja0luZm9DaGFubmVsKSB7XG4gICAgICAgIHdpbnN0b24uYWRkKHdpbnN0b25TbGFja1dlYkhvb2ssIHtcbiAgICAgICAgICBuYW1lICAgICAgOiAnc2xhY2staW5mby10cmFuc3BvcnQnLFxuICAgICAgICAgIGxldmVsICAgICA6ICdpbmZvJyxcbiAgICAgICAgICB3ZWJob29rVXJsOiB0aGlzLnNsYWNrV2ViSG9vayxcbiAgICAgICAgICBjaGFubmVsICAgOiB0aGlzLnNsYWNrSW5mb0NoYW5uZWwsXG4gICAgICAgICAgdXNlcm5hbWUgIDogJ3NwZWUuY2gnLFxuICAgICAgICAgIGljb25FbW9qaSA6ICc6bmVyZF9mYWNlOicsXG4gICAgICAgIH0pO1xuICAgICAgfTtcbiAgICAgIC8vIHNlbmQgdGVzdCBtZXNzYWdlc1xuICAgICAgd2luc3Rvbi5pbmZvKCd0ZXN0aW5nIHNsYWNrIGxvZ2dlci4uLicpO1xuICAgICAgd2luc3Rvbi5lcnJvcignU2xhY2sgXCJlcnJvclwiIGxvZ2dpbmcgaXMgb25saW5lLicpO1xuICAgICAgd2luc3Rvbi5pbmZvKCdTbGFjayBcImluZm9cIiBsb2dnaW5nIGlzIG9ubGluZS4nKTtcbiAgICB9IGVsc2Uge1xuICAgICAgd2luc3Rvbi53YXJuKCdTbGFjayBsb2dnaW5nIGlzIG5vdCBlbmFibGVkIGJlY2F1c2Ugbm8gc2xhY2tXZWJIb29rIGNvbmZpZyB2YXIgcHJvdmlkZWQuJyk7XG4gICAgfVxuICB9O1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSBuZXcgU2xhY2tDb25maWcoKTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL2NvbmZpZy9zbGFja0NvbmZpZy5qcyIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcIndpbnN0b24tc2xhY2std2ViaG9va1wiKTtcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyBleHRlcm5hbCBcIndpbnN0b24tc2xhY2std2ViaG9va1wiXG4vLyBtb2R1bGUgaWQgPSA0MlxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCJwYXNzcG9ydFwiKTtcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyBleHRlcm5hbCBcInBhc3Nwb3J0XCJcbi8vIG1vZHVsZSBpZCA9IDQzXG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsImNvbnN0IFBhc3Nwb3J0TG9jYWxTdHJhdGVneSA9IHJlcXVpcmUoJ3Bhc3Nwb3J0LWxvY2FsJykuU3RyYXRlZ3k7XG5jb25zdCBsb2dnZXIgPSByZXF1aXJlKCd3aW5zdG9uJyk7XG5jb25zdCBkYiA9IHJlcXVpcmUoJ21vZGVscycpO1xuXG5jb25zdCByZXR1cm5Vc2VyQW5kQ2hhbm5lbEluZm8gPSAodXNlckluc3RhbmNlKSA9PiB7XG4gIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgbGV0IHVzZXJJbmZvID0ge307XG4gICAgdXNlckluZm9bJ2lkJ10gPSB1c2VySW5zdGFuY2UuaWQ7XG4gICAgdXNlckluZm9bJ3VzZXJOYW1lJ10gPSB1c2VySW5zdGFuY2UudXNlck5hbWU7XG4gICAgdXNlckluc3RhbmNlXG4gICAgICAuZ2V0Q2hhbm5lbCgpXG4gICAgICAudGhlbigoe2NoYW5uZWxOYW1lLCBjaGFubmVsQ2xhaW1JZH0pID0+IHtcbiAgICAgICAgdXNlckluZm9bJ2NoYW5uZWxOYW1lJ10gPSBjaGFubmVsTmFtZTtcbiAgICAgICAgdXNlckluZm9bJ2NoYW5uZWxDbGFpbUlkJ10gPSBjaGFubmVsQ2xhaW1JZDtcbiAgICAgICAgcmV0dXJuIGRiLkNlcnRpZmljYXRlLmdldFNob3J0Q2hhbm5lbElkRnJvbUxvbmdDaGFubmVsSWQoY2hhbm5lbENsYWltSWQsIGNoYW5uZWxOYW1lKTtcbiAgICAgIH0pXG4gICAgICAudGhlbihzaG9ydENoYW5uZWxJZCA9PiB7XG4gICAgICAgIHVzZXJJbmZvWydzaG9ydENoYW5uZWxJZCddID0gc2hvcnRDaGFubmVsSWQ7XG4gICAgICAgIHJlc29sdmUodXNlckluZm8pO1xuICAgICAgfSlcbiAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICB9KTtcbiAgfSk7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IG5ldyBQYXNzcG9ydExvY2FsU3RyYXRlZ3koXG4gIHtcbiAgICB1c2VybmFtZUZpZWxkOiAndXNlcm5hbWUnLFxuICAgIHBhc3N3b3JkRmllbGQ6ICdwYXNzd29yZCcsXG4gIH0sXG4gICh1c2VybmFtZSwgcGFzc3dvcmQsIGRvbmUpID0+IHtcbiAgICByZXR1cm4gZGIuVXNlclxuICAgICAgLmZpbmRPbmUoe1xuICAgICAgICB3aGVyZToge3VzZXJOYW1lOiB1c2VybmFtZX0sXG4gICAgICB9KVxuICAgICAgLnRoZW4odXNlciA9PiB7XG4gICAgICAgIGlmICghdXNlcikge1xuICAgICAgICAgIGxvZ2dlci5kZWJ1Zygnbm8gdXNlciBmb3VuZCcpO1xuICAgICAgICAgIHJldHVybiBkb25lKG51bGwsIGZhbHNlLCB7bWVzc2FnZTogJ0luY29ycmVjdCB1c2VybmFtZSBvciBwYXNzd29yZCd9KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdXNlci5jb21wYXJlUGFzc3dvcmQocGFzc3dvcmQpXG4gICAgICAgICAgLnRoZW4oaXNNYXRjaCA9PiB7XG4gICAgICAgICAgICBpZiAoIWlzTWF0Y2gpIHtcbiAgICAgICAgICAgICAgbG9nZ2VyLmRlYnVnKCdpbmNvcnJlY3QgcGFzc3dvcmQnKTtcbiAgICAgICAgICAgICAgcmV0dXJuIGRvbmUobnVsbCwgZmFsc2UsIHttZXNzYWdlOiAnSW5jb3JyZWN0IHVzZXJuYW1lIG9yIHBhc3N3b3JkJ30pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbG9nZ2VyLmRlYnVnKCdQYXNzd29yZCB3YXMgYSBtYXRjaCwgcmV0dXJuaW5nIFVzZXInKTtcbiAgICAgICAgICAgIHJldHVybiByZXR1cm5Vc2VyQW5kQ2hhbm5lbEluZm8odXNlcilcbiAgICAgICAgICAgICAgLnRoZW4odXNlckluZm8gPT4ge1xuICAgICAgICAgICAgICAgIHJldHVybiBkb25lKG51bGwsIHVzZXJJbmZvKTtcbiAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZXJyb3I7XG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH0pXG4gICAgICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICAgIHJldHVybiBlcnJvcjtcbiAgICAgICAgICB9KTtcbiAgICAgIH0pXG4gICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICByZXR1cm4gZG9uZShlcnJvcik7XG4gICAgICB9KTtcbiAgfSxcbik7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9zZXJ2ZXIvc3BlZWNoUGFzc3BvcnQvbG9jYWwtbG9naW4uanMiLCJjb25zdCBsb2dnZXIgPSByZXF1aXJlKCd3aW5zdG9uJyk7XG5jb25zdCB7IHJldHVyblNob3J0SWQgfSA9IHJlcXVpcmUoJy4uL2hlbHBlcnMvc2VxdWVsaXplSGVscGVycy5qcycpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IChzZXF1ZWxpemUsIHsgU1RSSU5HLCBCT09MRUFOLCBJTlRFR0VSLCBURVhULCBERUNJTUFMIH0pID0+IHtcbiAgY29uc3QgQ2VydGlmaWNhdGUgPSBzZXF1ZWxpemUuZGVmaW5lKFxuICAgICdDZXJ0aWZpY2F0ZScsXG4gICAge1xuICAgICAgYWRkcmVzczoge1xuICAgICAgICB0eXBlICAgOiBTVFJJTkcsXG4gICAgICAgIGRlZmF1bHQ6IG51bGwsXG4gICAgICB9LFxuICAgICAgYW1vdW50OiB7XG4gICAgICAgIHR5cGUgICA6IERFQ0lNQUwoMTksIDgpLFxuICAgICAgICBkZWZhdWx0OiBudWxsLFxuICAgICAgfSxcbiAgICAgIGNsYWltSWQ6IHtcbiAgICAgICAgdHlwZSAgIDogU1RSSU5HLFxuICAgICAgICBkZWZhdWx0OiBudWxsLFxuICAgICAgfSxcbiAgICAgIGNsYWltU2VxdWVuY2U6IHtcbiAgICAgICAgdHlwZSAgIDogSU5URUdFUixcbiAgICAgICAgZGVmYXVsdDogbnVsbCxcbiAgICAgIH0sXG4gICAgICBkZWNvZGVkQ2xhaW06IHtcbiAgICAgICAgdHlwZSAgIDogQk9PTEVBTixcbiAgICAgICAgZGVmYXVsdDogbnVsbCxcbiAgICAgIH0sXG4gICAgICBkZXB0aDoge1xuICAgICAgICB0eXBlICAgOiBJTlRFR0VSLFxuICAgICAgICBkZWZhdWx0OiBudWxsLFxuICAgICAgfSxcbiAgICAgIGVmZmVjdGl2ZUFtb3VudDoge1xuICAgICAgICB0eXBlICAgOiBERUNJTUFMKDE5LCA4KSxcbiAgICAgICAgZGVmYXVsdDogbnVsbCxcbiAgICAgIH0sXG4gICAgICBoYXNTaWduYXR1cmU6IHtcbiAgICAgICAgdHlwZSAgIDogQk9PTEVBTixcbiAgICAgICAgZGVmYXVsdDogbnVsbCxcbiAgICAgIH0sXG4gICAgICBoZWlnaHQ6IHtcbiAgICAgICAgdHlwZSAgIDogSU5URUdFUixcbiAgICAgICAgZGVmYXVsdDogbnVsbCxcbiAgICAgIH0sXG4gICAgICBoZXg6IHtcbiAgICAgICAgdHlwZSAgIDogVEVYVCgnbG9uZycpLFxuICAgICAgICBkZWZhdWx0OiBudWxsLFxuICAgICAgfSxcbiAgICAgIG5hbWU6IHtcbiAgICAgICAgdHlwZSAgIDogU1RSSU5HLFxuICAgICAgICBkZWZhdWx0OiBudWxsLFxuICAgICAgfSxcbiAgICAgIG5vdXQ6IHtcbiAgICAgICAgdHlwZSAgIDogSU5URUdFUixcbiAgICAgICAgZGVmYXVsdDogbnVsbCxcbiAgICAgIH0sXG4gICAgICB0eGlkOiB7XG4gICAgICAgIHR5cGUgICA6IFNUUklORyxcbiAgICAgICAgZGVmYXVsdDogbnVsbCxcbiAgICAgIH0sXG4gICAgICB2YWxpZEF0SGVpZ2h0OiB7XG4gICAgICAgIHR5cGUgICA6IElOVEVHRVIsXG4gICAgICAgIGRlZmF1bHQ6IG51bGwsXG4gICAgICB9LFxuICAgICAgb3V0cG9pbnQ6IHtcbiAgICAgICAgdHlwZSAgIDogU1RSSU5HLFxuICAgICAgICBkZWZhdWx0OiBudWxsLFxuICAgICAgfSxcbiAgICAgIHZhbHVlVmVyc2lvbjoge1xuICAgICAgICB0eXBlICAgOiBTVFJJTkcsXG4gICAgICAgIGRlZmF1bHQ6IG51bGwsXG4gICAgICB9LFxuICAgICAgY2xhaW1UeXBlOiB7XG4gICAgICAgIHR5cGUgICA6IFNUUklORyxcbiAgICAgICAgZGVmYXVsdDogbnVsbCxcbiAgICAgIH0sXG4gICAgICBjZXJ0aWZpY2F0ZVZlcnNpb246IHtcbiAgICAgICAgdHlwZSAgIDogU1RSSU5HLFxuICAgICAgICBkZWZhdWx0OiBudWxsLFxuICAgICAgfSxcbiAgICAgIGtleVR5cGU6IHtcbiAgICAgICAgdHlwZSAgIDogU1RSSU5HLFxuICAgICAgICBkZWZhdWx0OiBudWxsLFxuICAgICAgfSxcbiAgICAgIHB1YmxpY0tleToge1xuICAgICAgICB0eXBlICAgOiBURVhUKCdsb25nJyksXG4gICAgICAgIGRlZmF1bHQ6IG51bGwsXG4gICAgICB9LFxuICAgIH0sXG4gICAge1xuICAgICAgZnJlZXplVGFibGVOYW1lOiB0cnVlLFxuICAgIH1cbiAgKTtcblxuICBDZXJ0aWZpY2F0ZS5hc3NvY2lhdGUgPSBkYiA9PiB7XG4gICAgQ2VydGlmaWNhdGUuYmVsb25nc1RvKGRiLkNoYW5uZWwsIHtcbiAgICAgIGZvcmVpZ25LZXk6IHtcbiAgICAgICAgYWxsb3dOdWxsOiB0cnVlLFxuICAgICAgfSxcbiAgICB9KTtcbiAgfTtcblxuICBDZXJ0aWZpY2F0ZS5nZXRTaG9ydENoYW5uZWxJZEZyb21Mb25nQ2hhbm5lbElkID0gZnVuY3Rpb24gKGxvbmdDaGFubmVsSWQsIGNoYW5uZWxOYW1lKSB7XG4gICAgbG9nZ2VyLmRlYnVnKGBnZXRTaG9ydENoYW5uZWxJZEZyb21Mb25nQ2hhbm5lbElkICR7Y2hhbm5lbE5hbWV9OiR7bG9uZ0NoYW5uZWxJZH1gKTtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgdGhpc1xuICAgICAgICAuZmluZEFsbCh7XG4gICAgICAgICAgd2hlcmU6IHtuYW1lOiBjaGFubmVsTmFtZX0sXG4gICAgICAgICAgb3JkZXI6IFtbJ2hlaWdodCcsICdBU0MnXV0sXG4gICAgICAgIH0pXG4gICAgICAgIC50aGVuKHJlc3VsdCA9PiB7XG4gICAgICAgICAgc3dpdGNoIChyZXN1bHQubGVuZ3RoKSB7XG4gICAgICAgICAgICBjYXNlIDA6XG4gICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignTm8gY2hhbm5lbChzKSBmb3VuZCB3aXRoIHRoYXQgY2hhbm5lbCBuYW1lJyk7XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICByZXR1cm4gcmVzb2x2ZShyZXR1cm5TaG9ydElkKHJlc3VsdCwgbG9uZ0NoYW5uZWxJZCkpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSlcbiAgICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICB9KTtcbiAgICB9KTtcbiAgfTtcblxuICBDZXJ0aWZpY2F0ZS5nZXRMb25nQ2hhbm5lbElkRnJvbVNob3J0Q2hhbm5lbElkID0gZnVuY3Rpb24gKGNoYW5uZWxOYW1lLCBjaGFubmVsQ2xhaW1JZCkge1xuICAgIGxvZ2dlci5kZWJ1ZyhgZ2V0TG9uZ0NoYW5uZWxJZEZyb21TaG9ydENoYW5uZWxJZCgke2NoYW5uZWxOYW1lfSwgJHtjaGFubmVsQ2xhaW1JZH0pYCk7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIHRoaXNcbiAgICAgICAgLmZpbmRBbGwoe1xuICAgICAgICAgIHdoZXJlOiB7XG4gICAgICAgICAgICBuYW1lICAgOiBjaGFubmVsTmFtZSxcbiAgICAgICAgICAgIGNsYWltSWQ6IHtcbiAgICAgICAgICAgICAgJGxpa2U6IGAke2NoYW5uZWxDbGFpbUlkfSVgLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIG9yZGVyOiBbWydoZWlnaHQnLCAnQVNDJ11dLFxuICAgICAgICB9KVxuICAgICAgICAudGhlbihyZXN1bHQgPT4ge1xuICAgICAgICAgIHN3aXRjaCAocmVzdWx0Lmxlbmd0aCkge1xuICAgICAgICAgICAgY2FzZSAwOlxuICAgICAgICAgICAgICByZXR1cm4gcmVzb2x2ZShudWxsKTtcbiAgICAgICAgICAgIGRlZmF1bHQ6IC8vIG5vdGUgcmVzdWx0cyBtdXN0IGJlIHNvcnRlZFxuICAgICAgICAgICAgICByZXR1cm4gcmVzb2x2ZShyZXN1bHRbMF0uY2xhaW1JZCk7XG4gICAgICAgICAgfVxuICAgICAgICB9KVxuICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgIH0pO1xuICAgIH0pO1xuICB9O1xuXG4gIENlcnRpZmljYXRlLmdldExvbmdDaGFubmVsSWRGcm9tQ2hhbm5lbE5hbWUgPSBmdW5jdGlvbiAoY2hhbm5lbE5hbWUpIHtcbiAgICBsb2dnZXIuZGVidWcoYGdldExvbmdDaGFubmVsSWRGcm9tQ2hhbm5lbE5hbWUoJHtjaGFubmVsTmFtZX0pYCk7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIHRoaXNcbiAgICAgICAgLmZpbmRBbGwoe1xuICAgICAgICAgIHdoZXJlOiB7IG5hbWU6IGNoYW5uZWxOYW1lIH0sXG4gICAgICAgICAgb3JkZXI6IFtbJ2VmZmVjdGl2ZUFtb3VudCcsICdERVNDJ10sIFsnaGVpZ2h0JywgJ0FTQyddXSxcbiAgICAgICAgfSlcbiAgICAgICAgLnRoZW4ocmVzdWx0ID0+IHtcbiAgICAgICAgICBzd2l0Y2ggKHJlc3VsdC5sZW5ndGgpIHtcbiAgICAgICAgICAgIGNhc2UgMDpcbiAgICAgICAgICAgICAgcmV0dXJuIHJlc29sdmUobnVsbCk7XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICByZXR1cm4gcmVzb2x2ZShyZXN1bHRbMF0uY2xhaW1JZCk7XG4gICAgICAgICAgfVxuICAgICAgICB9KVxuICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgIH0pO1xuICAgIH0pO1xuICB9O1xuXG4gIENlcnRpZmljYXRlLnZhbGlkYXRlTG9uZ0NoYW5uZWxJZCA9IGZ1bmN0aW9uIChuYW1lLCBjbGFpbUlkKSB7XG4gICAgbG9nZ2VyLmRlYnVnKGB2YWxpZGF0ZUxvbmdDaGFubmVsSWQoJHtuYW1lfSwgJHtjbGFpbUlkfSlgKTtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgdGhpcy5maW5kT25lKHtcbiAgICAgICAgd2hlcmU6IHtuYW1lLCBjbGFpbUlkfSxcbiAgICAgIH0pXG4gICAgICAgIC50aGVuKHJlc3VsdCA9PiB7XG4gICAgICAgICAgaWYgKCFyZXN1bHQpIHtcbiAgICAgICAgICAgIHJldHVybiByZXNvbHZlKG51bGwpO1xuICAgICAgICAgIH07XG4gICAgICAgICAgcmVzb2x2ZShjbGFpbUlkKTtcbiAgICAgICAgfSlcbiAgICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICB9KTtcbiAgICB9KTtcbiAgfTtcblxuICBDZXJ0aWZpY2F0ZS5nZXRMb25nQ2hhbm5lbElkID0gZnVuY3Rpb24gKGNoYW5uZWxOYW1lLCBjaGFubmVsQ2xhaW1JZCkge1xuICAgIGxvZ2dlci5kZWJ1ZyhgZ2V0TG9uZ0NoYW5uZWxJZCgke2NoYW5uZWxOYW1lfSwgJHtjaGFubmVsQ2xhaW1JZH0pYCk7XG4gICAgaWYgKGNoYW5uZWxDbGFpbUlkICYmIChjaGFubmVsQ2xhaW1JZC5sZW5ndGggPT09IDQwKSkgeyAgLy8gaWYgYSBmdWxsIGNoYW5uZWwgaWQgaXMgcHJvdmlkZWRcbiAgICAgIHJldHVybiB0aGlzLnZhbGlkYXRlTG9uZ0NoYW5uZWxJZChjaGFubmVsTmFtZSwgY2hhbm5lbENsYWltSWQpO1xuICAgIH0gZWxzZSBpZiAoY2hhbm5lbENsYWltSWQgJiYgY2hhbm5lbENsYWltSWQubGVuZ3RoIDwgNDApIHsgIC8vIGlmIGEgc2hvcnQgY2hhbm5lbCBpZCBpcyBwcm92aWRlZFxuICAgICAgcmV0dXJuIHRoaXMuZ2V0TG9uZ0NoYW5uZWxJZEZyb21TaG9ydENoYW5uZWxJZChjaGFubmVsTmFtZSwgY2hhbm5lbENsYWltSWQpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gdGhpcy5nZXRMb25nQ2hhbm5lbElkRnJvbUNoYW5uZWxOYW1lKGNoYW5uZWxOYW1lKTsgIC8vIGlmIG5vIGNoYW5uZWwgaWQgcHJvdmlkZWRcbiAgICB9XG4gIH07XG5cbiAgcmV0dXJuIENlcnRpZmljYXRlO1xufTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL3NlcnZlci9tb2RlbHMvY2VydGlmaWNhdGUuanMiLCJtb2R1bGUuZXhwb3J0cyA9IChzZXF1ZWxpemUsIHsgU1RSSU5HIH0pID0+IHtcbiAgY29uc3QgQ2hhbm5lbCA9IHNlcXVlbGl6ZS5kZWZpbmUoXG4gICAgJ0NoYW5uZWwnLFxuICAgIHtcbiAgICAgIGNoYW5uZWxOYW1lOiB7XG4gICAgICAgIHR5cGUgICAgIDogU1RSSU5HLFxuICAgICAgICBhbGxvd051bGw6IGZhbHNlLFxuICAgICAgfSxcbiAgICAgIGNoYW5uZWxDbGFpbUlkOiB7XG4gICAgICAgIHR5cGUgICAgIDogU1RSSU5HLFxuICAgICAgICBhbGxvd051bGw6IGZhbHNlLFxuICAgICAgfSxcbiAgICB9LFxuICAgIHtcbiAgICAgIGZyZWV6ZVRhYmxlTmFtZTogdHJ1ZSxcbiAgICB9XG4gICk7XG5cbiAgQ2hhbm5lbC5hc3NvY2lhdGUgPSBkYiA9PiB7XG4gICAgQ2hhbm5lbC5iZWxvbmdzVG8oZGIuVXNlcik7XG4gICAgQ2hhbm5lbC5oYXNPbmUoZGIuQ2VydGlmaWNhdGUpO1xuICB9O1xuXG4gIHJldHVybiBDaGFubmVsO1xufTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL3NlcnZlci9tb2RlbHMvY2hhbm5lbC5qcyIsImNvbnN0IGxvZ2dlciA9IHJlcXVpcmUoJ3dpbnN0b24nKTtcbmNvbnN0IHsgcmV0dXJuU2hvcnRJZCB9ID0gcmVxdWlyZSgnLi4vaGVscGVycy9zZXF1ZWxpemVIZWxwZXJzLmpzJyk7XG5jb25zdCB7IGFzc2V0RGVmYXVsdHM6IHsgdGh1bWJuYWlsOiBkZWZhdWx0VGh1bWJuYWlsIH0sIGRldGFpbHM6IHsgaG9zdCB9IH0gPSByZXF1aXJlKCcuLi8uLi9jb25maWcvc2l0ZUNvbmZpZy5qcycpO1xuXG5mdW5jdGlvbiBkZXRlcm1pbmVGaWxlRXh0ZW5zaW9uRnJvbUNvbnRlbnRUeXBlIChjb250ZW50VHlwZSkge1xuICBzd2l0Y2ggKGNvbnRlbnRUeXBlKSB7XG4gICAgY2FzZSAnaW1hZ2UvanBlZyc6XG4gICAgY2FzZSAnaW1hZ2UvanBnJzpcbiAgICAgIHJldHVybiAnanBlZyc7XG4gICAgY2FzZSAnaW1hZ2UvcG5nJzpcbiAgICAgIHJldHVybiAncG5nJztcbiAgICBjYXNlICdpbWFnZS9naWYnOlxuICAgICAgcmV0dXJuICdnaWYnO1xuICAgIGNhc2UgJ3ZpZGVvL21wNCc6XG4gICAgICByZXR1cm4gJ21wNCc7XG4gICAgZGVmYXVsdDpcbiAgICAgIGxvZ2dlci5kZWJ1Zygnc2V0dGluZyB1bmtub3duIGZpbGUgdHlwZSBhcyBmaWxlIGV4dGVuc2lvbiBqcGVnJyk7XG4gICAgICByZXR1cm4gJ2pwZWcnO1xuICB9XG59O1xuXG5mdW5jdGlvbiBkZXRlcm1pbmVUaHVtYm5haWwgKHN0b3JlZFRodW1ibmFpbCwgZGVmYXVsdFRodW1ibmFpbCkge1xuICBpZiAoc3RvcmVkVGh1bWJuYWlsID09PSAnJykge1xuICAgIHJldHVybiBkZWZhdWx0VGh1bWJuYWlsO1xuICB9XG4gIHJldHVybiBzdG9yZWRUaHVtYm5haWw7XG59O1xuXG5mdW5jdGlvbiBwcmVwYXJlQ2xhaW1EYXRhIChjbGFpbSkge1xuICAvLyBsb2dnZXIuZGVidWcoJ3ByZXBhcmluZyBjbGFpbSBkYXRhIGJhc2VkIG9uIHJlc29sdmVkIGRhdGE6JywgY2xhaW0pO1xuICBjbGFpbVsndGh1bWJuYWlsJ10gPSBkZXRlcm1pbmVUaHVtYm5haWwoY2xhaW0udGh1bWJuYWlsLCBkZWZhdWx0VGh1bWJuYWlsKTtcbiAgY2xhaW1bJ2ZpbGVFeHQnXSA9IGRldGVybWluZUZpbGVFeHRlbnNpb25Gcm9tQ29udGVudFR5cGUoY2xhaW0uY29udGVudFR5cGUpO1xuICBjbGFpbVsnaG9zdCddID0gaG9zdDtcbiAgcmV0dXJuIGNsYWltO1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSAoc2VxdWVsaXplLCB7IFNUUklORywgQk9PTEVBTiwgSU5URUdFUiwgVEVYVCwgREVDSU1BTCB9KSA9PiB7XG4gIGNvbnN0IENsYWltID0gc2VxdWVsaXplLmRlZmluZShcbiAgICAnQ2xhaW0nLFxuICAgIHtcbiAgICAgIGFkZHJlc3M6IHtcbiAgICAgICAgdHlwZSAgIDogU1RSSU5HLFxuICAgICAgICBkZWZhdWx0OiBudWxsLFxuICAgICAgfSxcbiAgICAgIGFtb3VudDoge1xuICAgICAgICB0eXBlICAgOiBERUNJTUFMKDE5LCA4KSxcbiAgICAgICAgZGVmYXVsdDogbnVsbCxcbiAgICAgIH0sXG4gICAgICBjbGFpbUlkOiB7XG4gICAgICAgIHR5cGUgICA6IFNUUklORyxcbiAgICAgICAgZGVmYXVsdDogbnVsbCxcbiAgICAgIH0sXG4gICAgICBjbGFpbVNlcXVlbmNlOiB7XG4gICAgICAgIHR5cGUgICA6IElOVEVHRVIsXG4gICAgICAgIGRlZmF1bHQ6IG51bGwsXG4gICAgICB9LFxuICAgICAgZGVjb2RlZENsYWltOiB7XG4gICAgICAgIHR5cGUgICA6IEJPT0xFQU4sXG4gICAgICAgIGRlZmF1bHQ6IG51bGwsXG4gICAgICB9LFxuICAgICAgZGVwdGg6IHtcbiAgICAgICAgdHlwZSAgIDogSU5URUdFUixcbiAgICAgICAgZGVmYXVsdDogbnVsbCxcbiAgICAgIH0sXG4gICAgICBlZmZlY3RpdmVBbW91bnQ6IHtcbiAgICAgICAgdHlwZSAgIDogREVDSU1BTCgxOSwgOCksXG4gICAgICAgIGRlZmF1bHQ6IG51bGwsXG4gICAgICB9LFxuICAgICAgaGFzU2lnbmF0dXJlOiB7XG4gICAgICAgIHR5cGUgICA6IEJPT0xFQU4sXG4gICAgICAgIGRlZmF1bHQ6IG51bGwsXG4gICAgICB9LFxuICAgICAgaGVpZ2h0OiB7XG4gICAgICAgIHR5cGUgICA6IElOVEVHRVIsXG4gICAgICAgIGRlZmF1bHQ6IG51bGwsXG4gICAgICB9LFxuICAgICAgaGV4OiB7XG4gICAgICAgIHR5cGUgICA6IFRFWFQoJ2xvbmcnKSxcbiAgICAgICAgZGVmYXVsdDogbnVsbCxcbiAgICAgIH0sXG4gICAgICBuYW1lOiB7XG4gICAgICAgIHR5cGUgICA6IFNUUklORyxcbiAgICAgICAgZGVmYXVsdDogbnVsbCxcbiAgICAgIH0sXG4gICAgICBub3V0OiB7XG4gICAgICAgIHR5cGUgICA6IElOVEVHRVIsXG4gICAgICAgIGRlZmF1bHQ6IG51bGwsXG4gICAgICB9LFxuICAgICAgdHhpZDoge1xuICAgICAgICB0eXBlICAgOiBTVFJJTkcsXG4gICAgICAgIGRlZmF1bHQ6IG51bGwsXG4gICAgICB9LFxuICAgICAgdmFsaWRBdEhlaWdodDoge1xuICAgICAgICB0eXBlICAgOiBJTlRFR0VSLFxuICAgICAgICBkZWZhdWx0OiBudWxsLFxuICAgICAgfSxcbiAgICAgIG91dHBvaW50OiB7XG4gICAgICAgIHR5cGUgICA6IFNUUklORyxcbiAgICAgICAgZGVmYXVsdDogbnVsbCxcbiAgICAgIH0sXG4gICAgICBjbGFpbVR5cGU6IHtcbiAgICAgICAgdHlwZSAgIDogU1RSSU5HLFxuICAgICAgICBkZWZhdWx0OiBudWxsLFxuICAgICAgfSxcbiAgICAgIGNlcnRpZmljYXRlSWQ6IHtcbiAgICAgICAgdHlwZSAgIDogU1RSSU5HLFxuICAgICAgICBkZWZhdWx0OiBudWxsLFxuICAgICAgfSxcbiAgICAgIGF1dGhvcjoge1xuICAgICAgICB0eXBlICAgOiBTVFJJTkcsXG4gICAgICAgIGRlZmF1bHQ6IG51bGwsXG4gICAgICB9LFxuICAgICAgZGVzY3JpcHRpb246IHtcbiAgICAgICAgdHlwZSAgIDogVEVYVCgnbG9uZycpLFxuICAgICAgICBkZWZhdWx0OiBudWxsLFxuICAgICAgfSxcbiAgICAgIGxhbmd1YWdlOiB7XG4gICAgICAgIHR5cGUgICA6IFNUUklORyxcbiAgICAgICAgZGVmYXVsdDogbnVsbCxcbiAgICAgIH0sXG4gICAgICBsaWNlbnNlOiB7XG4gICAgICAgIHR5cGUgICA6IFNUUklORyxcbiAgICAgICAgZGVmYXVsdDogbnVsbCxcbiAgICAgIH0sXG4gICAgICBsaWNlbnNlVXJsOiB7XG4gICAgICAgIHR5cGUgICA6IFNUUklORyxcbiAgICAgICAgZGVmYXVsdDogbnVsbCxcbiAgICAgIH0sXG4gICAgICBuc2Z3OiB7XG4gICAgICAgIHR5cGUgICA6IEJPT0xFQU4sXG4gICAgICAgIGRlZmF1bHQ6IG51bGwsXG4gICAgICB9LFxuICAgICAgcHJldmlldzoge1xuICAgICAgICB0eXBlICAgOiBTVFJJTkcsXG4gICAgICAgIGRlZmF1bHQ6IG51bGwsXG4gICAgICB9LFxuICAgICAgdGh1bWJuYWlsOiB7XG4gICAgICAgIHR5cGUgICA6IFNUUklORyxcbiAgICAgICAgZGVmYXVsdDogbnVsbCxcbiAgICAgIH0sXG4gICAgICB0aXRsZToge1xuICAgICAgICB0eXBlICAgOiBTVFJJTkcsXG4gICAgICAgIGRlZmF1bHQ6IG51bGwsXG4gICAgICB9LFxuICAgICAgbWV0YWRhdGFWZXJzaW9uOiB7XG4gICAgICAgIHR5cGUgICA6IFNUUklORyxcbiAgICAgICAgZGVmYXVsdDogbnVsbCxcbiAgICAgIH0sXG4gICAgICBjb250ZW50VHlwZToge1xuICAgICAgICB0eXBlICAgOiBTVFJJTkcsXG4gICAgICAgIGRlZmF1bHQ6IG51bGwsXG4gICAgICB9LFxuICAgICAgc291cmNlOiB7XG4gICAgICAgIHR5cGUgICA6IFNUUklORyxcbiAgICAgICAgZGVmYXVsdDogbnVsbCxcbiAgICAgIH0sXG4gICAgICBzb3VyY2VUeXBlOiB7XG4gICAgICAgIHR5cGUgICA6IFNUUklORyxcbiAgICAgICAgZGVmYXVsdDogbnVsbCxcbiAgICAgIH0sXG4gICAgICBzb3VyY2VWZXJzaW9uOiB7XG4gICAgICAgIHR5cGUgICA6IFNUUklORyxcbiAgICAgICAgZGVmYXVsdDogbnVsbCxcbiAgICAgIH0sXG4gICAgICBzdHJlYW1WZXJzaW9uOiB7XG4gICAgICAgIHR5cGUgICA6IFNUUklORyxcbiAgICAgICAgZGVmYXVsdDogbnVsbCxcbiAgICAgIH0sXG4gICAgICB2YWx1ZVZlcnNpb246IHtcbiAgICAgICAgdHlwZSAgIDogU1RSSU5HLFxuICAgICAgICBkZWZhdWx0OiBudWxsLFxuICAgICAgfSxcbiAgICAgIGNoYW5uZWxOYW1lOiB7XG4gICAgICAgIHR5cGUgICAgIDogU1RSSU5HLFxuICAgICAgICBhbGxvd051bGw6IHRydWUsXG4gICAgICAgIGRlZmF1bHQgIDogbnVsbCxcbiAgICAgIH0sXG4gICAgfSxcbiAgICB7XG4gICAgICBmcmVlemVUYWJsZU5hbWU6IHRydWUsXG4gICAgfVxuICApO1xuXG4gIENsYWltLmFzc29jaWF0ZSA9IGRiID0+IHtcbiAgICBDbGFpbS5iZWxvbmdzVG8oZGIuRmlsZSwge1xuICAgICAgZm9yZWlnbktleToge1xuICAgICAgICBhbGxvd051bGw6IHRydWUsXG4gICAgICB9LFxuICAgIH0pO1xuICB9O1xuXG4gIENsYWltLmdldFNob3J0Q2xhaW1JZEZyb21Mb25nQ2xhaW1JZCA9IGZ1bmN0aW9uIChjbGFpbUlkLCBjbGFpbU5hbWUpIHtcbiAgICBsb2dnZXIuZGVidWcoYENsYWltLmdldFNob3J0Q2xhaW1JZEZyb21Mb25nQ2xhaW1JZCBmb3IgJHtjbGFpbU5hbWV9IyR7Y2xhaW1JZH1gKTtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgdGhpc1xuICAgICAgICAuZmluZEFsbCh7XG4gICAgICAgICAgd2hlcmU6IHsgbmFtZTogY2xhaW1OYW1lIH0sXG4gICAgICAgICAgb3JkZXI6IFtbJ2hlaWdodCcsICdBU0MnXV0sXG4gICAgICAgIH0pXG4gICAgICAgIC50aGVuKHJlc3VsdCA9PiB7XG4gICAgICAgICAgc3dpdGNoIChyZXN1bHQubGVuZ3RoKSB7XG4gICAgICAgICAgICBjYXNlIDA6XG4gICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignTm8gY2xhaW0ocykgZm91bmQgd2l0aCB0aGF0IGNsYWltIG5hbWUnKTtcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgIHJlc29sdmUocmV0dXJuU2hvcnRJZChyZXN1bHQsIGNsYWltSWQpKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pXG4gICAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgfSk7XG4gICAgfSk7XG4gIH07XG5cbiAgQ2xhaW0uZ2V0QWxsQ2hhbm5lbENsYWltcyA9IGZ1bmN0aW9uIChjaGFubmVsQ2xhaW1JZCkge1xuICAgIGxvZ2dlci5kZWJ1ZyhgQ2xhaW0uZ2V0QWxsQ2hhbm5lbENsYWltcyBmb3IgJHtjaGFubmVsQ2xhaW1JZH1gKTtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgdGhpc1xuICAgICAgICAuZmluZEFsbCh7XG4gICAgICAgICAgd2hlcmU6IHsgY2VydGlmaWNhdGVJZDogY2hhbm5lbENsYWltSWQgfSxcbiAgICAgICAgICBvcmRlcjogW1snaGVpZ2h0JywgJ0FTQyddXSxcbiAgICAgICAgICByYXcgIDogdHJ1ZSwgIC8vIHJldHVybnMgYW4gYXJyYXkgb2Ygb25seSBkYXRhLCBub3QgYW4gYXJyYXkgb2YgaW5zdGFuY2VzXG4gICAgICAgIH0pXG4gICAgICAgIC50aGVuKGNoYW5uZWxDbGFpbXNBcnJheSA9PiB7XG4gICAgICAgICAgLy8gbG9nZ2VyLmRlYnVnKCdjaGFubmVsY2xhaW1zYXJyYXkgbGVuZ3RoOicsIGNoYW5uZWxDbGFpbXNBcnJheS5sZW5ndGgpO1xuICAgICAgICAgIHN3aXRjaCAoY2hhbm5lbENsYWltc0FycmF5Lmxlbmd0aCkge1xuICAgICAgICAgICAgY2FzZSAwOlxuICAgICAgICAgICAgICByZXR1cm4gcmVzb2x2ZShudWxsKTtcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgIGNoYW5uZWxDbGFpbXNBcnJheS5mb3JFYWNoKGNsYWltID0+IHtcbiAgICAgICAgICAgICAgICBjbGFpbVsnZmlsZUV4dCddID0gZGV0ZXJtaW5lRmlsZUV4dGVuc2lvbkZyb21Db250ZW50VHlwZShjbGFpbS5jb250ZW50VHlwZSk7XG4gICAgICAgICAgICAgICAgY2xhaW1bJ3RodW1ibmFpbCddID0gZGV0ZXJtaW5lVGh1bWJuYWlsKGNsYWltLnRodW1ibmFpbCwgZGVmYXVsdFRodW1ibmFpbCk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGNsYWltO1xuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgcmV0dXJuIHJlc29sdmUoY2hhbm5lbENsYWltc0FycmF5KTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pXG4gICAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgfSk7XG4gICAgfSk7XG4gIH07XG5cbiAgQ2xhaW0uZ2V0Q2xhaW1JZEJ5TG9uZ0NoYW5uZWxJZCA9IGZ1bmN0aW9uIChjaGFubmVsQ2xhaW1JZCwgY2xhaW1OYW1lKSB7XG4gICAgbG9nZ2VyLmRlYnVnKGBmaW5kaW5nIGNsYWltIGlkIGZvciBjbGFpbSAke2NsYWltTmFtZX0gZnJvbSBjaGFubmVsICR7Y2hhbm5lbENsYWltSWR9YCk7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIHRoaXNcbiAgICAgICAgLmZpbmRBbGwoe1xuICAgICAgICAgIHdoZXJlOiB7IG5hbWU6IGNsYWltTmFtZSwgY2VydGlmaWNhdGVJZDogY2hhbm5lbENsYWltSWQgfSxcbiAgICAgICAgICBvcmRlcjogW1snaWQnLCAnQVNDJ11dLFxuICAgICAgICB9KVxuICAgICAgICAudGhlbihyZXN1bHQgPT4ge1xuICAgICAgICAgIHN3aXRjaCAocmVzdWx0Lmxlbmd0aCkge1xuICAgICAgICAgICAgY2FzZSAwOlxuICAgICAgICAgICAgICByZXR1cm4gcmVzb2x2ZShudWxsKTtcbiAgICAgICAgICAgIGNhc2UgMTpcbiAgICAgICAgICAgICAgcmV0dXJuIHJlc29sdmUocmVzdWx0WzBdLmNsYWltSWQpO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgbG9nZ2VyLmVycm9yKGAke3Jlc3VsdC5sZW5ndGh9IHJlY29yZHMgZm91bmQgZm9yIFwiJHtjbGFpbU5hbWV9XCIgaW4gY2hhbm5lbCBcIiR7Y2hhbm5lbENsYWltSWR9XCJgKTtcbiAgICAgICAgICAgICAgcmV0dXJuIHJlc29sdmUocmVzdWx0WzBdLmNsYWltSWQpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSlcbiAgICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICB9KTtcbiAgICB9KTtcbiAgfTtcblxuICBDbGFpbS5nZXRMb25nQ2xhaW1JZEZyb21TaG9ydENsYWltSWQgPSBmdW5jdGlvbiAobmFtZSwgc2hvcnRJZCkge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICB0aGlzXG4gICAgICAgIC5maW5kQWxsKHtcbiAgICAgICAgICB3aGVyZToge1xuICAgICAgICAgICAgbmFtZSxcbiAgICAgICAgICAgIGNsYWltSWQ6IHtcbiAgICAgICAgICAgICAgJGxpa2U6IGAke3Nob3J0SWR9JWAsXG4gICAgICAgICAgICB9fSxcbiAgICAgICAgICBvcmRlcjogW1snaGVpZ2h0JywgJ0FTQyddXSxcbiAgICAgICAgfSlcbiAgICAgICAgLnRoZW4ocmVzdWx0ID0+IHtcbiAgICAgICAgICBzd2l0Y2ggKHJlc3VsdC5sZW5ndGgpIHtcbiAgICAgICAgICAgIGNhc2UgMDpcbiAgICAgICAgICAgICAgcmV0dXJuIHJlc29sdmUobnVsbCk7XG4gICAgICAgICAgICBkZWZhdWx0OiAvLyBub3RlIHJlc3VsdHMgbXVzdCBiZSBzb3J0ZWRcbiAgICAgICAgICAgICAgcmV0dXJuIHJlc29sdmUocmVzdWx0WzBdLmNsYWltSWQpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSlcbiAgICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICB9KTtcbiAgICB9KTtcbiAgfTtcblxuICBDbGFpbS5nZXRUb3BGcmVlQ2xhaW1JZEJ5Q2xhaW1OYW1lID0gZnVuY3Rpb24gKG5hbWUpIHtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgdGhpc1xuICAgICAgICAuZmluZEFsbCh7XG4gICAgICAgICAgd2hlcmU6IHsgbmFtZSB9LFxuICAgICAgICAgIG9yZGVyOiBbWydlZmZlY3RpdmVBbW91bnQnLCAnREVTQyddLCBbJ2hlaWdodCcsICdBU0MnXV0sICAvLyBub3RlOiBtYXliZSBoZWlnaHQgYW5kIGVmZmVjdGl2ZSBhbW91bnQgbmVlZCB0byBzd2l0Y2g/XG4gICAgICAgIH0pXG4gICAgICAgIC50aGVuKHJlc3VsdCA9PiB7XG4gICAgICAgICAgbG9nZ2VyLmRlYnVnKCdsZW5ndGggb2YgcmVzdWx0JywgcmVzdWx0Lmxlbmd0aCk7XG4gICAgICAgICAgc3dpdGNoIChyZXN1bHQubGVuZ3RoKSB7XG4gICAgICAgICAgICBjYXNlIDA6XG4gICAgICAgICAgICAgIHJldHVybiByZXNvbHZlKG51bGwpO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgcmV0dXJuIHJlc29sdmUocmVzdWx0WzBdLmRhdGFWYWx1ZXMuY2xhaW1JZCk7XG4gICAgICAgICAgfVxuICAgICAgICB9KVxuICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgIH0pO1xuICAgIH0pO1xuICB9O1xuXG4gIENsYWltLnZhbGlkYXRlTG9uZ0NsYWltSWQgPSBmdW5jdGlvbiAobmFtZSwgY2xhaW1JZCkge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICB0aGlzLmZpbmRPbmUoe1xuICAgICAgICB3aGVyZToge25hbWUsIGNsYWltSWR9LFxuICAgICAgfSlcbiAgICAgICAgLnRoZW4ocmVzdWx0ID0+IHtcbiAgICAgICAgICBpZiAoIXJlc3VsdCkge1xuICAgICAgICAgICAgcmV0dXJuIHJlc29sdmUobnVsbCk7XG4gICAgICAgICAgfTtcbiAgICAgICAgICByZXNvbHZlKGNsYWltSWQpO1xuICAgICAgICB9KVxuICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgIH0pO1xuICAgIH0pO1xuICB9O1xuXG4gIENsYWltLmdldExvbmdDbGFpbUlkID0gZnVuY3Rpb24gKGNsYWltTmFtZSwgY2xhaW1JZCkge1xuICAgIGxvZ2dlci5kZWJ1ZyhgZ2V0TG9uZ0NsYWltSWQoJHtjbGFpbU5hbWV9LCAke2NsYWltSWR9KWApO1xuICAgIGlmIChjbGFpbUlkICYmIChjbGFpbUlkLmxlbmd0aCA9PT0gNDApKSB7ICAvLyBpZiBhIGZ1bGwgY2xhaW0gaWQgaXMgcHJvdmlkZWRcbiAgICAgIHJldHVybiB0aGlzLnZhbGlkYXRlTG9uZ0NsYWltSWQoY2xhaW1OYW1lLCBjbGFpbUlkKTtcbiAgICB9IGVsc2UgaWYgKGNsYWltSWQgJiYgY2xhaW1JZC5sZW5ndGggPCA0MCkge1xuICAgICAgcmV0dXJuIHRoaXMuZ2V0TG9uZ0NsYWltSWRGcm9tU2hvcnRDbGFpbUlkKGNsYWltTmFtZSwgY2xhaW1JZCk7ICAvLyBpZiBhIHNob3J0IGNsYWltIGlkIGlzIHByb3ZpZGVkXG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiB0aGlzLmdldFRvcEZyZWVDbGFpbUlkQnlDbGFpbU5hbWUoY2xhaW1OYW1lKTsgIC8vIGlmIG5vIGNsYWltIGlkIGlzIHByb3ZpZGVkXG4gICAgfVxuICB9O1xuXG4gIENsYWltLnJlc29sdmVDbGFpbSA9IGZ1bmN0aW9uIChuYW1lLCBjbGFpbUlkKSB7XG4gICAgbG9nZ2VyLmRlYnVnKGBDbGFpbS5yZXNvbHZlQ2xhaW06ICR7bmFtZX0gJHtjbGFpbUlkfWApO1xuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICB0aGlzXG4gICAgICAgIC5maW5kQWxsKHtcbiAgICAgICAgICB3aGVyZTogeyBuYW1lLCBjbGFpbUlkIH0sXG4gICAgICAgIH0pXG4gICAgICAgIC50aGVuKGNsYWltQXJyYXkgPT4ge1xuICAgICAgICAgIHN3aXRjaCAoY2xhaW1BcnJheS5sZW5ndGgpIHtcbiAgICAgICAgICAgIGNhc2UgMDpcbiAgICAgICAgICAgICAgcmV0dXJuIHJlc29sdmUobnVsbCk7XG4gICAgICAgICAgICBjYXNlIDE6XG4gICAgICAgICAgICAgIHJldHVybiByZXNvbHZlKHByZXBhcmVDbGFpbURhdGEoY2xhaW1BcnJheVswXS5kYXRhVmFsdWVzKSk7XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICBsb2dnZXIuZXJyb3IoYG1vcmUgdGhhbiBvbmUgcmVjb3JkIG1hdGNoZXMgJHtuYW1lfSMke2NsYWltSWR9IGluIGRiLkNsYWltYCk7XG4gICAgICAgICAgICAgIHJldHVybiByZXNvbHZlKHByZXBhcmVDbGFpbURhdGEoY2xhaW1BcnJheVswXS5kYXRhVmFsdWVzKSk7XG4gICAgICAgICAgfVxuICAgICAgICB9KVxuICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgIH0pO1xuICAgIH0pO1xuICB9O1xuXG4gIHJldHVybiBDbGFpbTtcbn07XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9zZXJ2ZXIvbW9kZWxzL2NsYWltLmpzIiwibW9kdWxlLmV4cG9ydHMgPSAoc2VxdWVsaXplLCB7IFNUUklORywgQk9PTEVBTiwgSU5URUdFUiB9KSA9PiB7XG4gIGNvbnN0IEZpbGUgPSBzZXF1ZWxpemUuZGVmaW5lKFxuICAgICdGaWxlJyxcbiAgICB7XG4gICAgICBuYW1lOiB7XG4gICAgICAgIHR5cGUgICAgIDogU1RSSU5HLFxuICAgICAgICBhbGxvd051bGw6IGZhbHNlLFxuICAgICAgfSxcbiAgICAgIGNsYWltSWQ6IHtcbiAgICAgICAgdHlwZSAgICAgOiBTVFJJTkcsXG4gICAgICAgIGFsbG93TnVsbDogZmFsc2UsXG4gICAgICB9LFxuICAgICAgYWRkcmVzczoge1xuICAgICAgICB0eXBlICAgICA6IFNUUklORyxcbiAgICAgICAgYWxsb3dOdWxsOiBmYWxzZSxcbiAgICAgIH0sXG4gICAgICBvdXRwb2ludDoge1xuICAgICAgICB0eXBlICAgICA6IFNUUklORyxcbiAgICAgICAgYWxsb3dOdWxsOiBmYWxzZSxcbiAgICAgIH0sXG4gICAgICBoZWlnaHQ6IHtcbiAgICAgICAgdHlwZSAgICAgOiBJTlRFR0VSLFxuICAgICAgICBhbGxvd051bGw6IGZhbHNlLFxuICAgICAgICBkZWZhdWx0ICA6IDAsXG4gICAgICB9LFxuICAgICAgZmlsZU5hbWU6IHtcbiAgICAgICAgdHlwZSAgICAgOiBTVFJJTkcsXG4gICAgICAgIGFsbG93TnVsbDogZmFsc2UsXG4gICAgICB9LFxuICAgICAgZmlsZVBhdGg6IHtcbiAgICAgICAgdHlwZSAgICAgOiBTVFJJTkcsXG4gICAgICAgIGFsbG93TnVsbDogZmFsc2UsXG4gICAgICB9LFxuICAgICAgZmlsZVR5cGU6IHtcbiAgICAgICAgdHlwZTogU1RSSU5HLFxuICAgICAgfSxcbiAgICAgIG5zZnc6IHtcbiAgICAgICAgdHlwZSAgICAgICAgOiBCT09MRUFOLFxuICAgICAgICBhbGxvd051bGwgICA6IGZhbHNlLFxuICAgICAgICBkZWZhdWx0VmFsdWU6IGZhbHNlLFxuICAgICAgfSxcbiAgICAgIHRyZW5kaW5nRWxpZ2libGU6IHtcbiAgICAgICAgdHlwZSAgICAgICAgOiBCT09MRUFOLFxuICAgICAgICBhbGxvd051bGwgICA6IGZhbHNlLFxuICAgICAgICBkZWZhdWx0VmFsdWU6IHRydWUsXG4gICAgICB9LFxuICAgIH0sXG4gICAge1xuICAgICAgZnJlZXplVGFibGVOYW1lOiB0cnVlLFxuICAgIH1cbiAgKTtcblxuICBGaWxlLmFzc29jaWF0ZSA9IGRiID0+IHtcbiAgICBGaWxlLmhhc01hbnkoZGIuUmVxdWVzdCk7XG4gICAgRmlsZS5oYXNPbmUoZGIuQ2xhaW0pO1xuICB9O1xuXG4gIEZpbGUuZ2V0UmVjZW50Q2xhaW1zID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiB0aGlzLmZpbmRBbGwoe1xuICAgICAgd2hlcmU6IHsgbnNmdzogZmFsc2UsIHRyZW5kaW5nRWxpZ2libGU6IHRydWUgfSxcbiAgICAgIG9yZGVyOiBbWydjcmVhdGVkQXQnLCAnREVTQyddXSxcbiAgICAgIGxpbWl0OiAyNSxcbiAgICB9KTtcbiAgfTtcblxuICByZXR1cm4gRmlsZTtcbn07XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9zZXJ2ZXIvbW9kZWxzL2ZpbGUuanMiLCJtb2R1bGUuZXhwb3J0cyA9IChzZXF1ZWxpemUsIHsgU1RSSU5HLCBCT09MRUFOLCBURVhUIH0pID0+IHtcbiAgY29uc3QgUmVxdWVzdCA9IHNlcXVlbGl6ZS5kZWZpbmUoXG4gICAgJ1JlcXVlc3QnLFxuICAgIHtcbiAgICAgIGFjdGlvbjoge1xuICAgICAgICB0eXBlICAgICA6IFNUUklORyxcbiAgICAgICAgYWxsb3dOdWxsOiBmYWxzZSxcbiAgICAgIH0sXG4gICAgICB1cmw6IHtcbiAgICAgICAgdHlwZSAgICAgOiBTVFJJTkcsXG4gICAgICAgIGFsbG93TnVsbDogZmFsc2UsXG4gICAgICB9LFxuICAgICAgaXBBZGRyZXNzOiB7XG4gICAgICAgIHR5cGUgICAgIDogU1RSSU5HLFxuICAgICAgICBhbGxvd051bGw6IHRydWUsXG4gICAgICB9LFxuICAgICAgcmVzdWx0OiB7XG4gICAgICAgIHR5cGUgICAgIDogVEVYVCgnbG9uZycpLFxuICAgICAgICBhbGxvd051bGw6IHRydWUsXG4gICAgICAgIGRlZmF1bHQgIDogbnVsbCxcbiAgICAgIH0sXG4gICAgfSxcbiAgICB7XG4gICAgICBmcmVlemVUYWJsZU5hbWU6IHRydWUsXG4gICAgfVxuICApO1xuXG4gIFJlcXVlc3QuYXNzb2NpYXRlID0gZGIgPT4ge1xuICAgIFJlcXVlc3QuYmVsb25nc1RvKGRiLkZpbGUsIHtcbiAgICAgIGZvcmVpZ25LZXk6IHtcbiAgICAgICAgYWxsb3dOdWxsOiB0cnVlLFxuICAgICAgfSxcbiAgICB9KTtcbiAgfTtcblxuICByZXR1cm4gUmVxdWVzdDtcbn07XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9zZXJ2ZXIvbW9kZWxzL3JlcXVlc3QuanMiLCIndXNlIHN0cmljdCc7XG5jb25zdCBiY3J5cHQgPSByZXF1aXJlKCdiY3J5cHQnKTtcbmNvbnN0IGxvZ2dlciA9IHJlcXVpcmUoJ3dpbnN0b24nKTtcblxubW9kdWxlLmV4cG9ydHMgPSAoc2VxdWVsaXplLCB7IFNUUklORyB9KSA9PiB7XG4gIGNvbnN0IFVzZXIgPSBzZXF1ZWxpemUuZGVmaW5lKFxuICAgICdVc2VyJyxcbiAgICB7XG4gICAgICB1c2VyTmFtZToge1xuICAgICAgICB0eXBlICAgICA6IFNUUklORyxcbiAgICAgICAgYWxsb3dOdWxsOiBmYWxzZSxcbiAgICAgIH0sXG4gICAgICBwYXNzd29yZDoge1xuICAgICAgICB0eXBlICAgICA6IFNUUklORyxcbiAgICAgICAgYWxsb3dOdWxsOiBmYWxzZSxcbiAgICAgIH0sXG4gICAgfSxcbiAgICB7XG4gICAgICBmcmVlemVUYWJsZU5hbWU6IHRydWUsXG4gICAgfVxuICApO1xuXG4gIFVzZXIuYXNzb2NpYXRlID0gZGIgPT4ge1xuICAgIFVzZXIuaGFzT25lKGRiLkNoYW5uZWwpO1xuICB9O1xuXG4gIFVzZXIucHJvdG90eXBlLmNvbXBhcmVQYXNzd29yZCA9IGZ1bmN0aW9uIChwYXNzd29yZCkge1xuICAgIHJldHVybiBiY3J5cHQuY29tcGFyZShwYXNzd29yZCwgdGhpcy5wYXNzd29yZCk7XG4gIH07XG5cbiAgVXNlci5wcm90b3R5cGUuY2hhbmdlUGFzc3dvcmQgPSBmdW5jdGlvbiAobmV3UGFzc3dvcmQpIHtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgLy8gZ2VuZXJhdGUgYSBzYWx0IHN0cmluZyB0byB1c2UgZm9yIGhhc2hpbmdcbiAgICAgIGJjcnlwdC5nZW5TYWx0KChzYWx0RXJyb3IsIHNhbHQpID0+IHtcbiAgICAgICAgaWYgKHNhbHRFcnJvcikge1xuICAgICAgICAgIGxvZ2dlci5lcnJvcignc2FsdCBlcnJvcicsIHNhbHRFcnJvcik7XG4gICAgICAgICAgcmVqZWN0KHNhbHRFcnJvcik7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIC8vIGdlbmVyYXRlIGEgaGFzaGVkIHZlcnNpb24gb2YgdGhlIHVzZXIncyBwYXNzd29yZFxuICAgICAgICBiY3J5cHQuaGFzaChuZXdQYXNzd29yZCwgc2FsdCwgKGhhc2hFcnJvciwgaGFzaCkgPT4ge1xuICAgICAgICAgIC8vIGlmIHRoZXJlIGlzIGFuIGVycm9yIHdpdGggdGhlIGhhc2ggZ2VuZXJhdGlvbiByZXR1cm4gdGhlIGVycm9yXG4gICAgICAgICAgaWYgKGhhc2hFcnJvcikge1xuICAgICAgICAgICAgbG9nZ2VyLmVycm9yKCdoYXNoIGVycm9yJywgaGFzaEVycm9yKTtcbiAgICAgICAgICAgIHJlamVjdChoYXNoRXJyb3IpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgIH1cbiAgICAgICAgICAvLyByZXBsYWNlIHRoZSBjdXJyZW50IHBhc3N3b3JkIHdpdGggdGhlIG5ldyBoYXNoXG4gICAgICAgICAgdGhpc1xuICAgICAgICAgICAgLnVwZGF0ZSh7cGFzc3dvcmQ6IGhhc2h9KVxuICAgICAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9O1xuXG4gIC8vIHByZS1zYXZlIGhvb2sgbWV0aG9kIHRvIGhhc2ggdGhlIHVzZXIncyBwYXNzd29yZCBiZWZvcmUgdGhlIHVzZXIncyBpbmZvIGlzIHNhdmVkIHRvIHRoZSBkYi5cbiAgVXNlci5ob29rKCdiZWZvcmVDcmVhdGUnLCAodXNlciwgb3B0aW9ucykgPT4ge1xuICAgIGxvZ2dlci5kZWJ1ZygnVXNlci5iZWZvcmVDcmVhdGUgaG9vay4uLicpO1xuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAvLyBnZW5lcmF0ZSBhIHNhbHQgc3RyaW5nIHRvIHVzZSBmb3IgaGFzaGluZ1xuICAgICAgYmNyeXB0LmdlblNhbHQoKHNhbHRFcnJvciwgc2FsdCkgPT4ge1xuICAgICAgICBpZiAoc2FsdEVycm9yKSB7XG4gICAgICAgICAgbG9nZ2VyLmVycm9yKCdzYWx0IGVycm9yJywgc2FsdEVycm9yKTtcbiAgICAgICAgICByZWplY3Qoc2FsdEVycm9yKTtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgLy8gZ2VuZXJhdGUgYSBoYXNoZWQgdmVyc2lvbiBvZiB0aGUgdXNlcidzIHBhc3N3b3JkXG4gICAgICAgIGJjcnlwdC5oYXNoKHVzZXIucGFzc3dvcmQsIHNhbHQsIChoYXNoRXJyb3IsIGhhc2gpID0+IHtcbiAgICAgICAgICAvLyBpZiB0aGVyZSBpcyBhbiBlcnJvciB3aXRoIHRoZSBoYXNoIGdlbmVyYXRpb24gcmV0dXJuIHRoZSBlcnJvclxuICAgICAgICAgIGlmIChoYXNoRXJyb3IpIHtcbiAgICAgICAgICAgIGxvZ2dlci5lcnJvcignaGFzaCBlcnJvcicsIGhhc2hFcnJvcik7XG4gICAgICAgICAgICByZWplY3QoaGFzaEVycm9yKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICB9XG4gICAgICAgICAgLy8gcmVwbGFjZSB0aGUgcGFzc3dvcmQgc3RyaW5nIHdpdGggdGhlIGhhc2ggcGFzc3dvcmQgdmFsdWVcbiAgICAgICAgICB1c2VyLnBhc3N3b3JkID0gaGFzaDtcbiAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIHJldHVybiBVc2VyO1xufTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL3NlcnZlci9tb2RlbHMvdXNlci5qcyIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcImJjcnlwdFwiKTtcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyBleHRlcm5hbCBcImJjcnlwdFwiXG4vLyBtb2R1bGUgaWQgPSA1MVxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJjb25zdCBQYXNzcG9ydExvY2FsU3RyYXRlZ3kgPSByZXF1aXJlKCdwYXNzcG9ydC1sb2NhbCcpLlN0cmF0ZWd5O1xuY29uc3QgbGJyeUFwaSA9IHJlcXVpcmUoJy4uL2hlbHBlcnMvbGJyeUFwaS5qcycpO1xuY29uc3QgbG9nZ2VyID0gcmVxdWlyZSgnd2luc3RvbicpO1xuY29uc3QgZGIgPSByZXF1aXJlKCdtb2RlbHMnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBuZXcgUGFzc3BvcnRMb2NhbFN0cmF0ZWd5KFxuICB7XG4gICAgdXNlcm5hbWVGaWVsZDogJ3VzZXJuYW1lJyxcbiAgICBwYXNzd29yZEZpZWxkOiAncGFzc3dvcmQnLFxuICB9LFxuICAodXNlcm5hbWUsIHBhc3N3b3JkLCBkb25lKSA9PiB7XG4gICAgbG9nZ2VyLnZlcmJvc2UoYG5ldyBjaGFubmVsIHNpZ251cCByZXF1ZXN0LiB1c2VyOiAke3VzZXJuYW1lfSBwYXNzOiAke3Bhc3N3b3JkfSAuYCk7XG4gICAgbGV0IHVzZXJJbmZvID0ge307XG4gICAgLy8gc2VydmVyLXNpZGUgdmFsaWRhdG9uIG9mIGlucHV0cyAodXNlcm5hbWUsIHBhc3N3b3JkKVxuXG4gICAgLy8gY3JlYXRlIHRoZSBjaGFubmVsIGFuZCByZXRyaWV2ZSB0aGUgbWV0YWRhdGFcbiAgICByZXR1cm4gbGJyeUFwaS5jcmVhdGVDaGFubmVsKGBAJHt1c2VybmFtZX1gKVxuICAgICAgLnRoZW4odHggPT4ge1xuICAgICAgICAvLyBjcmVhdGUgdXNlciByZWNvcmRcbiAgICAgICAgY29uc3QgdXNlckRhdGEgPSB7XG4gICAgICAgICAgdXNlck5hbWU6IHVzZXJuYW1lLFxuICAgICAgICAgIHBhc3N3b3JkOiBwYXNzd29yZCxcbiAgICAgICAgfTtcbiAgICAgICAgbG9nZ2VyLnZlcmJvc2UoJ3VzZXJEYXRhID4nLCB1c2VyRGF0YSk7XG4gICAgICAgIC8vIGNyZWF0ZSB1c2VyIHJlY29yZFxuICAgICAgICBjb25zdCBjaGFubmVsRGF0YSA9IHtcbiAgICAgICAgICBjaGFubmVsTmFtZSAgIDogYEAke3VzZXJuYW1lfWAsXG4gICAgICAgICAgY2hhbm5lbENsYWltSWQ6IHR4LmNsYWltX2lkLFxuICAgICAgICB9O1xuICAgICAgICBsb2dnZXIudmVyYm9zZSgnY2hhbm5lbERhdGEgPicsIGNoYW5uZWxEYXRhKTtcbiAgICAgICAgLy8gY3JlYXRlIGNlcnRpZmljYXRlIHJlY29yZFxuICAgICAgICBjb25zdCBjZXJ0aWZpY2F0ZURhdGEgPSB7XG4gICAgICAgICAgY2xhaW1JZDogdHguY2xhaW1faWQsXG4gICAgICAgICAgbmFtZSAgIDogYEAke3VzZXJuYW1lfWAsXG4gICAgICAgICAgLy8gYWRkcmVzcyxcbiAgICAgICAgfTtcbiAgICAgICAgbG9nZ2VyLnZlcmJvc2UoJ2NlcnRpZmljYXRlRGF0YSA+JywgY2VydGlmaWNhdGVEYXRhKTtcbiAgICAgICAgLy8gc2F2ZSB1c2VyIGFuZCBjZXJ0aWZpY2F0ZSB0byBkYlxuICAgICAgICByZXR1cm4gUHJvbWlzZS5hbGwoW2RiLlVzZXIuY3JlYXRlKHVzZXJEYXRhKSwgZGIuQ2hhbm5lbC5jcmVhdGUoY2hhbm5lbERhdGEpLCBkYi5DZXJ0aWZpY2F0ZS5jcmVhdGUoY2VydGlmaWNhdGVEYXRhKV0pO1xuICAgICAgfSlcbiAgICAgIC50aGVuKChbbmV3VXNlciwgbmV3Q2hhbm5lbCwgbmV3Q2VydGlmaWNhdGVdKSA9PiB7XG4gICAgICAgIGxvZ2dlci52ZXJib3NlKCd1c2VyIGFuZCBjZXJ0aWZpY2F0ZSBzdWNjZXNzZnVsbHkgY3JlYXRlZCcpO1xuICAgICAgICAvLyBzdG9yZSB0aGUgcmVsZXZhbnQgbmV3VXNlciBpbmZvIHRvIGJlIHBhc3NlZCBiYWNrIGZvciByZXEuVXNlclxuICAgICAgICB1c2VySW5mb1snaWQnXSA9IG5ld1VzZXIuaWQ7XG4gICAgICAgIHVzZXJJbmZvWyd1c2VyTmFtZSddID0gbmV3VXNlci51c2VyTmFtZTtcbiAgICAgICAgdXNlckluZm9bJ2NoYW5uZWxOYW1lJ10gPSBuZXdDaGFubmVsLmNoYW5uZWxOYW1lO1xuICAgICAgICB1c2VySW5mb1snY2hhbm5lbENsYWltSWQnXSA9IG5ld0NoYW5uZWwuY2hhbm5lbENsYWltSWQ7XG4gICAgICAgIC8vIGFzc29jaWF0ZSB0aGUgaW5zdGFuY2VzXG4gICAgICAgIHJldHVybiBQcm9taXNlLmFsbChbbmV3Q2VydGlmaWNhdGUuc2V0Q2hhbm5lbChuZXdDaGFubmVsKSwgbmV3Q2hhbm5lbC5zZXRVc2VyKG5ld1VzZXIpXSk7XG4gICAgICB9KVxuICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICBsb2dnZXIudmVyYm9zZSgndXNlciBhbmQgY2VydGlmaWNhdGUgc3VjY2Vzc2Z1bGx5IGFzc29jaWF0ZWQnKTtcbiAgICAgICAgcmV0dXJuIGRiLkNlcnRpZmljYXRlLmdldFNob3J0Q2hhbm5lbElkRnJvbUxvbmdDaGFubmVsSWQodXNlckluZm8uY2hhbm5lbENsYWltSWQsIHVzZXJJbmZvLmNoYW5uZWxOYW1lKTtcbiAgICAgIH0pXG4gICAgICAudGhlbihzaG9ydENoYW5uZWxJZCA9PiB7XG4gICAgICAgIHVzZXJJbmZvWydzaG9ydENoYW5uZWxJZCddID0gc2hvcnRDaGFubmVsSWQ7XG4gICAgICAgIHJldHVybiBkb25lKG51bGwsIHVzZXJJbmZvKTtcbiAgICAgIH0pXG4gICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICBsb2dnZXIuZXJyb3IoJ3NpZ251cCBlcnJvcicsIGVycm9yKTtcbiAgICAgICAgcmV0dXJuIGRvbmUoZXJyb3IpO1xuICAgICAgfSk7XG4gIH1cbik7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9zZXJ2ZXIvc3BlZWNoUGFzc3BvcnQvbG9jYWwtc2lnbnVwLmpzIiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwiYXhpb3NcIik7XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gZXh0ZXJuYWwgXCJheGlvc1wiXG4vLyBtb2R1bGUgaWQgPSA1M1xuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJjb25zdCBsYnJ5Q29uZmlnID0ge1xuICBhcGk6IHtcbiAgICBhcGlIb3N0OiAnbG9jYWxob3N0JyxcbiAgICBhcGlQb3J0OiAnNTI3OScsXG4gIH0sXG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IGxicnlDb25maWc7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9jb25maWcvbGJyeUNvbmZpZy5qcyIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcInVuaXZlcnNhbC1hbmFseXRpY3NcIik7XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gZXh0ZXJuYWwgXCJ1bml2ZXJzYWwtYW5hbHl0aWNzXCJcbi8vIG1vZHVsZSBpZCA9IDU1XG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIm1vZHVsZS5leHBvcnRzID0ge1xuICBzZXJpYWxpemVTcGVlY2hVc2VyICh1c2VyLCBkb25lKSB7ICAvLyByZXR1cm5zIHVzZXIgZGF0YSB0byBiZSBzZXJpYWxpemVkIGludG8gc2Vzc2lvblxuICAgIGNvbnNvbGUubG9nKCdzZXJpYWxpemluZyB1c2VyJyk7XG4gICAgZG9uZShudWxsLCB1c2VyKTtcbiAgfSxcbiAgZGVzZXJpYWxpemVTcGVlY2hVc2VyICh1c2VyLCBkb25lKSB7ICAvLyBkZXNlcmlhbGl6ZXMgc2Vzc2lvbiBhbmQgcG9wdWxhdGVzIGFkZGl0aW9uYWwgaW5mbyB0byByZXEudXNlclxuICAgIGNvbnNvbGUubG9nKCdkZXNlcmlhbGl6aW5nIHVzZXInKTtcbiAgICBkb25lKG51bGwsIHVzZXIpO1xuICB9LFxufTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL3NlcnZlci9oZWxwZXJzL2F1dGhIZWxwZXJzLmpzIiwiY29uc3Qgc3BlZWNoUGFzc3BvcnQgPSByZXF1aXJlKCdzcGVlY2hQYXNzcG9ydCcpO1xuY29uc3QgaGFuZGxlU2lnbnVwUmVxdWVzdCA9IHJlcXVpcmUoJy4vc2lnbnVwJyk7XG5jb25zdCBoYW5kbGVMb2dpblJlcXVlc3QgPSByZXF1aXJlKCcuL2xvZ2luJyk7XG5jb25zdCBoYW5kbGVMb2dvdXRSZXF1ZXN0ID0gcmVxdWlyZSgnLi9sb2dvdXQnKTtcbmNvbnN0IGhhbmRsZVVzZXJSZXF1ZXN0ID0gcmVxdWlyZSgnLi91c2VyJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gKGFwcCkgPT4ge1xuICBhcHAucG9zdCgnL3NpZ251cCcsIHNwZWVjaFBhc3Nwb3J0LmF1dGhlbnRpY2F0ZSgnbG9jYWwtc2lnbnVwJyksIGhhbmRsZVNpZ251cFJlcXVlc3QpO1xuICBhcHAucG9zdCgnL2xvZ2luJywgaGFuZGxlTG9naW5SZXF1ZXN0KTtcbiAgYXBwLmdldCgnL2xvZ291dCcsIGhhbmRsZUxvZ291dFJlcXVlc3QpO1xuICBhcHAuZ2V0KCcvdXNlcicsIGhhbmRsZVVzZXJSZXF1ZXN0KTtcbn07XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9zZXJ2ZXIvcm91dGVzL2F1dGgvaW5kZXguanMiLCJjb25zdCBzaWdudXAgPSAocmVxLCByZXMpID0+IHtcbiAgcmVzLnN0YXR1cygyMDApLmpzb24oe1xuICAgIHN1Y2Nlc3MgICAgICAgOiB0cnVlLFxuICAgIGNoYW5uZWxOYW1lICAgOiByZXEudXNlci5jaGFubmVsTmFtZSxcbiAgICBjaGFubmVsQ2xhaW1JZDogcmVxLnVzZXIuY2hhbm5lbENsYWltSWQsXG4gICAgc2hvcnRDaGFubmVsSWQ6IHJlcS51c2VyLnNob3J0Q2hhbm5lbElkLFxuICB9KTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gc2lnbnVwO1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vc2VydmVyL3JvdXRlcy9hdXRoL3NpZ251cC5qcyIsImNvbnN0IHNwZWVjaFBhc3Nwb3J0ID0gcmVxdWlyZSgnc3BlZWNoUGFzc3BvcnQnKTtcblxuY29uc3QgbG9naW4gPSAocmVxLCByZXMsIG5leHQpID0+IHtcbiAgc3BlZWNoUGFzc3BvcnQuYXV0aGVudGljYXRlKCdsb2NhbC1sb2dpbicsIChlcnIsIHVzZXIsIGluZm8pID0+IHtcbiAgICBpZiAoZXJyKSB7XG4gICAgICByZXR1cm4gbmV4dChlcnIpO1xuICAgIH1cbiAgICBpZiAoIXVzZXIpIHtcbiAgICAgIHJldHVybiByZXMuc3RhdHVzKDQwMCkuanNvbih7XG4gICAgICAgIHN1Y2Nlc3M6IGZhbHNlLFxuICAgICAgICBtZXNzYWdlOiBpbmZvLm1lc3NhZ2UsXG4gICAgICB9KTtcbiAgICB9XG4gICAgcmVxLmxvZ0luKHVzZXIsIChlcnIpID0+IHtcbiAgICAgIGlmIChlcnIpIHtcbiAgICAgICAgcmV0dXJuIG5leHQoZXJyKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiByZXMuc3RhdHVzKDIwMCkuanNvbih7XG4gICAgICAgIHN1Y2Nlc3MgICAgICAgOiB0cnVlLFxuICAgICAgICBjaGFubmVsTmFtZSAgIDogcmVxLnVzZXIuY2hhbm5lbE5hbWUsXG4gICAgICAgIGNoYW5uZWxDbGFpbUlkOiByZXEudXNlci5jaGFubmVsQ2xhaW1JZCxcbiAgICAgICAgc2hvcnRDaGFubmVsSWQ6IHJlcS51c2VyLnNob3J0Q2hhbm5lbElkLFxuICAgICAgfSk7XG4gICAgfSk7XG4gIH0pKHJlcSwgcmVzLCBuZXh0KTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gbG9naW47XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9zZXJ2ZXIvcm91dGVzL2F1dGgvbG9naW4uanMiLCJjb25zdCBsb2dvdXQgPSAocmVxLCByZXMpID0+IHtcbiAgcmVxLmxvZ291dCgpO1xuICByZXMuc3RhdHVzKDIwMCkuanNvbih7c3VjY2VzczogdHJ1ZSwgbWVzc2FnZTogJ3lvdSBzdWNjZXNzZnVsbHkgbG9nZ2VkIG91dCd9KTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gbG9nb3V0O1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vc2VydmVyL3JvdXRlcy9hdXRoL2xvZ291dC5qcyIsImNvbnN0IHVzZXIgPSAocmVxLCByZXMpID0+IHtcbiAgaWYgKHJlcS51c2VyKSB7XG4gICAgcmVzLnN0YXR1cygyMDApLmpzb24oe3N1Y2Nlc3M6IHRydWUsIGRhdGE6IHJlcS51c2VyfSk7XG4gIH0gZWxzZSB7XG4gICAgcmVzLnN0YXR1cyg0MDEpLmpzb24oe3N1Y2Nlc3M6IGZhbHNlLCBtZXNzYWdlOiAndXNlciBpcyBub3QgbG9nZ2VkIGluJ30pO1xuICB9XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IHVzZXI7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9zZXJ2ZXIvcm91dGVzL2F1dGgvdXNlci5qcyIsImNvbnN0IGNoYW5uZWxBdmFpbGFiaWxpdHkgPSByZXF1aXJlKCcuL2NoYW5uZWxBdmFpbGFiaWxpdHknKTtcbmNvbnN0IGNoYW5uZWxDbGFpbXMgPSByZXF1aXJlKCcuL2NoYW5uZWxDbGFpbXMnKTtcbmNvbnN0IGNoYW5uZWxEYXRhID0gcmVxdWlyZSgnLi9jaGFubmVsRGF0YScpO1xuY29uc3QgY2hhbm5lbFNob3J0SWQgPSByZXF1aXJlKCcuL2NoYW5uZWxTaG9ydElkJyk7XG5jb25zdCBjbGFpbUF2YWlsYWJpbGl0eSA9IHJlcXVpcmUoJy4vY2xhaW1BdmFpbGFiaWxpdHknKTtcbmNvbnN0IGNsYWltRGF0YSA9IHJlcXVpcmUoJy4vY2xhaW1EYXRhJyk7XG5jb25zdCBjbGFpbUdldCA9IHJlcXVpcmUoJy4vY2xhaW1HZXQnKTtcbmNvbnN0IGNsYWltTG9uZ0lkID0gcmVxdWlyZSgnLi9jbGFpbUxvbmdJZCcpO1xuY29uc3QgY2xhaW1QdWJsaXNoID0gcmVxdWlyZSgnLi9jbGFpbVB1Ymxpc2gnKTtcbmNvbnN0IGNsYWltUmVzb2x2ZSA9IHJlcXVpcmUoJy4vY2xhaW1SZXNvbHZlJyk7XG5jb25zdCBjbGFpbVNob3J0SWQgPSByZXF1aXJlKCcuL2NsYWltU2hvcnRJZCcpO1xuY29uc3QgY2xhaW1MaXN0ID0gcmVxdWlyZSgnLi9jbGFpbUxpc3QnKTtcbmNvbnN0IGZpbGVBdmFpbGFiaWxpdHkgPSByZXF1aXJlKCcuL2ZpbGVBdmFpbGFiaWxpdHknKTtcblxuY29uc3QgbXVsdGlwYXJ0TWlkZGxld2FyZSA9IHJlcXVpcmUoJ2hlbHBlcnMvbXVsdGlwYXJ0TWlkZGxld2FyZScpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IChhcHApID0+IHtcbiAgLy8gY2hhbm5lbCByb3V0ZXNcbiAgYXBwLmdldCgnL2FwaS9jaGFubmVsL2F2YWlsYWJpbGl0eS86bmFtZScsIGNoYW5uZWxBdmFpbGFiaWxpdHkpO1xuICBhcHAuZ2V0KCcvYXBpL2NoYW5uZWwvc2hvcnQtaWQvOmxvbmdJZC86bmFtZScsIGNoYW5uZWxTaG9ydElkKTtcbiAgYXBwLmdldCgnL2FwaS9jaGFubmVsL2RhdGEvOmNoYW5uZWxOYW1lLzpjaGFubmVsQ2xhaW1JZCcsIGNoYW5uZWxEYXRhKTtcbiAgYXBwLmdldCgnL2FwaS9jaGFubmVsL2NsYWltcy86Y2hhbm5lbE5hbWUvOmNoYW5uZWxDbGFpbUlkLzpwYWdlJywgY2hhbm5lbENsYWltcyk7XG4gIC8vIGNsYWltIHJvdXRlc1xuICBhcHAuZ2V0KCcvYXBpL2NsYWltL2xpc3QvOm5hbWUnLCBjbGFpbUxpc3QpO1xuICBhcHAuZ2V0KCcvYXBpL2NsYWltL2dldC86bmFtZS86Y2xhaW1JZCcsIGNsYWltR2V0KTtcbiAgYXBwLmdldCgnL2FwaS9jbGFpbS9hdmFpbGFiaWxpdHkvOm5hbWUnLCBjbGFpbUF2YWlsYWJpbGl0eSk7XG4gIGFwcC5nZXQoJy9hcGkvY2xhaW0vcmVzb2x2ZS86bmFtZS86Y2xhaW1JZCcsIGNsYWltUmVzb2x2ZSk7XG4gIGFwcC5wb3N0KCcvYXBpL2NsYWltL3B1Ymxpc2gnLCBtdWx0aXBhcnRNaWRkbGV3YXJlLCBjbGFpbVB1Ymxpc2gpO1xuICBhcHAuZ2V0KCcvYXBpL2NsYWltL3Nob3J0LWlkLzpsb25nSWQvOm5hbWUnLCBjbGFpbVNob3J0SWQpO1xuICBhcHAucG9zdCgnL2FwaS9jbGFpbS9sb25nLWlkJywgY2xhaW1Mb25nSWQpO1xuICBhcHAuZ2V0KCcvYXBpL2NsYWltL2RhdGEvOmNsYWltTmFtZS86Y2xhaW1JZCcsIGNsYWltRGF0YSk7XG4gIC8vIGZpbGUgcm91dGVzXG4gIGFwcC5nZXQoJy9hcGkvZmlsZS9hdmFpbGFiaWxpdHkvOm5hbWUvOmNsYWltSWQnLCBmaWxlQXZhaWxhYmlsaXR5KTtcbn07XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9zZXJ2ZXIvcm91dGVzL2FwaS9pbmRleC5qcyIsImNvbnN0IHsgY2hlY2tDaGFubmVsQXZhaWxhYmlsaXR5IH0gPSByZXF1aXJlKCdjb250cm9sbGVycy9wdWJsaXNoQ29udHJvbGxlci5qcycpO1xuY29uc3QgeyBzZW5kR0FUaW1pbmdFdmVudCB9ID0gcmVxdWlyZSgnaGVscGVycy9nb29nbGVBbmFseXRpY3MuanMnKTtcbmNvbnN0IHsgaGFuZGxlRXJyb3JSZXNwb25zZSB9ID0gcmVxdWlyZSgnaGVscGVycy9lcnJvckhhbmRsZXJzLmpzJyk7XG5cbi8qXG5cbiAgcm91dGUgdG8gY2hlY2sgd2hldGhlciBzaXRlIGhhcyBwdWJsaXNoZWQgdG8gYSBjaGFubmVsXG5cbiovXG5cbmNvbnN0IGNoYW5uZWxBdmFpbGFiaWxpdHkgPSAoeyBpcCwgb3JpZ2luYWxVcmwsIHBhcmFtczogeyBuYW1lIH0gfSwgcmVzKSA9PiB7XG4gIGNvbnN0IGdhU3RhcnRUaW1lID0gRGF0ZS5ub3coKTtcbiAgY2hlY2tDaGFubmVsQXZhaWxhYmlsaXR5KG5hbWUpXG4gICAgLnRoZW4oYXZhaWxhYmxlTmFtZSA9PiB7XG4gICAgICByZXMuc3RhdHVzKDIwMCkuanNvbihhdmFpbGFibGVOYW1lKTtcbiAgICAgIHNlbmRHQVRpbWluZ0V2ZW50KCdlbmQtdG8tZW5kJywgJ2NsYWltIG5hbWUgYXZhaWxhYmlsaXR5JywgbmFtZSwgZ2FTdGFydFRpbWUsIERhdGUubm93KCkpO1xuICAgIH0pXG4gICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgIGhhbmRsZUVycm9yUmVzcG9uc2Uob3JpZ2luYWxVcmwsIGlwLCBlcnJvciwgcmVzKTtcbiAgICB9KTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gY2hhbm5lbEF2YWlsYWJpbGl0eTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL3NlcnZlci9yb3V0ZXMvYXBpL2NoYW5uZWxBdmFpbGFiaWxpdHkuanMiLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCJmc1wiKTtcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyBleHRlcm5hbCBcImZzXCJcbi8vIG1vZHVsZSBpZCA9IDY0XG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsImNvbnN0IHsgZ2V0Q2hhbm5lbENsYWltcyB9ID0gcmVxdWlyZSgnY29udHJvbGxlcnMvc2VydmVDb250cm9sbGVyLmpzJyk7XG5jb25zdCB7IGhhbmRsZUVycm9yUmVzcG9uc2UgfSA9IHJlcXVpcmUoJ2hlbHBlcnMvZXJyb3JIYW5kbGVycy5qcycpO1xuXG5jb25zdCBOT19DSEFOTkVMID0gJ05PX0NIQU5ORUwnO1xuXG4vKlxuXG4gIHJvdXRlIHRvIGdldCBhbGwgY2xhaW1zIGZvciBjaGFubmVsXG5cbiovXG5cbmNvbnN0IGNoYW5uZWxDbGFpbXMgPSAoeyBpcCwgb3JpZ2luYWxVcmwsIGJvZHksIHBhcmFtcyB9LCByZXMpID0+IHtcbiAgY29uc3QgY2hhbm5lbE5hbWUgPSBwYXJhbXMuY2hhbm5lbE5hbWU7XG4gIGxldCBjaGFubmVsQ2xhaW1JZCA9IHBhcmFtcy5jaGFubmVsQ2xhaW1JZDtcbiAgaWYgKGNoYW5uZWxDbGFpbUlkID09PSAnbm9uZScpIGNoYW5uZWxDbGFpbUlkID0gbnVsbDtcbiAgY29uc3QgcGFnZSA9IHBhcmFtcy5wYWdlO1xuICBnZXRDaGFubmVsQ2xhaW1zKGNoYW5uZWxOYW1lLCBjaGFubmVsQ2xhaW1JZCwgcGFnZSlcbiAgICAudGhlbihkYXRhID0+IHtcbiAgICAgIGlmIChkYXRhID09PSBOT19DSEFOTkVMKSB7XG4gICAgICAgIHJldHVybiByZXMuc3RhdHVzKDQwNCkuanNvbih7c3VjY2VzczogZmFsc2UsIG1lc3NhZ2U6ICdObyBtYXRjaGluZyBjaGFubmVsIHdhcyBmb3VuZCd9KTtcbiAgICAgIH1cbiAgICAgIHJlcy5zdGF0dXMoMjAwKS5qc29uKHtzdWNjZXNzOiB0cnVlLCBkYXRhfSk7XG4gICAgfSlcbiAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgaGFuZGxlRXJyb3JSZXNwb25zZShvcmlnaW5hbFVybCwgaXAsIGVycm9yLCByZXMpO1xuICAgIH0pO1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSBjaGFubmVsQ2xhaW1zO1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vc2VydmVyL3JvdXRlcy9hcGkvY2hhbm5lbENsYWltcy5qcyIsImNvbnN0IENMQUlNU19QRVJfUEFHRSA9IDEyO1xuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgcmV0dXJuUGFnaW5hdGVkQ2hhbm5lbENsYWltcyAoY2hhbm5lbE5hbWUsIGxvbmdDaGFubmVsQ2xhaW1JZCwgY2xhaW1zLCBwYWdlKSB7XG4gICAgY29uc3QgdG90YWxQYWdlcyA9IG1vZHVsZS5leHBvcnRzLmRldGVybWluZVRvdGFsUGFnZXMoY2xhaW1zKTtcbiAgICBjb25zdCBwYWdpbmF0aW9uUGFnZSA9IG1vZHVsZS5leHBvcnRzLmdldFBhZ2VGcm9tUXVlcnkocGFnZSk7XG4gICAgY29uc3Qgdmlld0RhdGEgPSB7XG4gICAgICBjaGFubmVsTmFtZSAgICAgICA6IGNoYW5uZWxOYW1lLFxuICAgICAgbG9uZ0NoYW5uZWxDbGFpbUlkOiBsb25nQ2hhbm5lbENsYWltSWQsXG4gICAgICBjbGFpbXMgICAgICAgICAgICA6IG1vZHVsZS5leHBvcnRzLmV4dHJhY3RQYWdlRnJvbUNsYWltcyhjbGFpbXMsIHBhZ2luYXRpb25QYWdlKSxcbiAgICAgIHByZXZpb3VzUGFnZSAgICAgIDogbW9kdWxlLmV4cG9ydHMuZGV0ZXJtaW5lUHJldmlvdXNQYWdlKHBhZ2luYXRpb25QYWdlKSxcbiAgICAgIGN1cnJlbnRQYWdlICAgICAgIDogcGFnaW5hdGlvblBhZ2UsXG4gICAgICBuZXh0UGFnZSAgICAgICAgICA6IG1vZHVsZS5leHBvcnRzLmRldGVybWluZU5leHRQYWdlKHRvdGFsUGFnZXMsIHBhZ2luYXRpb25QYWdlKSxcbiAgICAgIHRvdGFsUGFnZXMgICAgICAgIDogdG90YWxQYWdlcyxcbiAgICAgIHRvdGFsUmVzdWx0cyAgICAgIDogbW9kdWxlLmV4cG9ydHMuZGV0ZXJtaW5lVG90YWxDbGFpbXMoY2xhaW1zKSxcbiAgICB9O1xuICAgIHJldHVybiB2aWV3RGF0YTtcbiAgfSxcbiAgZ2V0UGFnZUZyb21RdWVyeSAocGFnZSkge1xuICAgIGlmIChwYWdlKSB7XG4gICAgICByZXR1cm4gcGFyc2VJbnQocGFnZSk7XG4gICAgfVxuICAgIHJldHVybiAxO1xuICB9LFxuICBleHRyYWN0UGFnZUZyb21DbGFpbXMgKGNsYWltcywgcGFnZU51bWJlcikge1xuICAgIGlmICghY2xhaW1zKSB7XG4gICAgICByZXR1cm4gW107ICAvLyBpZiBubyBjbGFpbXMsIHJldHVybiB0aGlzIGRlZmF1bHRcbiAgICB9XG4gICAgLy8gbG9nZ2VyLmRlYnVnKCdjbGFpbXMgaXMgYXJyYXk/JywgQXJyYXkuaXNBcnJheShjbGFpbXMpKTtcbiAgICAvLyBsb2dnZXIuZGVidWcoYHBhZ2VOdW1iZXIgJHtwYWdlTnVtYmVyfSBpcyBudW1iZXI/YCwgTnVtYmVyLmlzSW50ZWdlcihwYWdlTnVtYmVyKSk7XG4gICAgY29uc3QgY2xhaW1TdGFydEluZGV4ID0gKHBhZ2VOdW1iZXIgLSAxKSAqIENMQUlNU19QRVJfUEFHRTtcbiAgICBjb25zdCBjbGFpbUVuZEluZGV4ID0gY2xhaW1TdGFydEluZGV4ICsgQ0xBSU1TX1BFUl9QQUdFO1xuICAgIGNvbnN0IHBhZ2VPZkNsYWltcyA9IGNsYWltcy5zbGljZShjbGFpbVN0YXJ0SW5kZXgsIGNsYWltRW5kSW5kZXgpO1xuICAgIHJldHVybiBwYWdlT2ZDbGFpbXM7XG4gIH0sXG4gIGRldGVybWluZVRvdGFsUGFnZXMgKGNsYWltcykge1xuICAgIGlmICghY2xhaW1zKSB7XG4gICAgICByZXR1cm4gMDtcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3QgdG90YWxDbGFpbXMgPSBjbGFpbXMubGVuZ3RoO1xuICAgICAgaWYgKHRvdGFsQ2xhaW1zIDwgQ0xBSU1TX1BFUl9QQUdFKSB7XG4gICAgICAgIHJldHVybiAxO1xuICAgICAgfVxuICAgICAgY29uc3QgZnVsbFBhZ2VzID0gTWF0aC5mbG9vcih0b3RhbENsYWltcyAvIENMQUlNU19QRVJfUEFHRSk7XG4gICAgICBjb25zdCByZW1haW5kZXIgPSB0b3RhbENsYWltcyAlIENMQUlNU19QRVJfUEFHRTtcbiAgICAgIGlmIChyZW1haW5kZXIgPT09IDApIHtcbiAgICAgICAgcmV0dXJuIGZ1bGxQYWdlcztcbiAgICAgIH1cbiAgICAgIHJldHVybiBmdWxsUGFnZXMgKyAxO1xuICAgIH1cbiAgfSxcbiAgZGV0ZXJtaW5lUHJldmlvdXNQYWdlIChjdXJyZW50UGFnZSkge1xuICAgIGlmIChjdXJyZW50UGFnZSA9PT0gMSkge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICAgIHJldHVybiBjdXJyZW50UGFnZSAtIDE7XG4gIH0sXG4gIGRldGVybWluZU5leHRQYWdlICh0b3RhbFBhZ2VzLCBjdXJyZW50UGFnZSkge1xuICAgIGlmIChjdXJyZW50UGFnZSA9PT0gdG90YWxQYWdlcykge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICAgIHJldHVybiBjdXJyZW50UGFnZSArIDE7XG4gIH0sXG4gIGRldGVybWluZVRvdGFsQ2xhaW1zIChjbGFpbXMpIHtcbiAgICBpZiAoIWNsYWltcykge1xuICAgICAgcmV0dXJuIDA7XG4gICAgfVxuICAgIHJldHVybiBjbGFpbXMubGVuZ3RoO1xuICB9LFxufTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL3NlcnZlci9oZWxwZXJzL2NoYW5uZWxQYWdpbmF0aW9uLmpzIiwiY29uc3QgeyBnZXRDaGFubmVsRGF0YSB9ID0gcmVxdWlyZSgnY29udHJvbGxlcnMvc2VydmVDb250cm9sbGVyLmpzJyk7XG5jb25zdCB7IGhhbmRsZUVycm9yUmVzcG9uc2UgfSA9IHJlcXVpcmUoJ2hlbHBlcnMvZXJyb3JIYW5kbGVycy5qcycpO1xuXG5jb25zdCBOT19DSEFOTkVMID0gJ05PX0NIQU5ORUwnO1xuXG4vKlxuXG4gIHJvdXRlIHRvIGdldCBkYXRhIGZvciBhIGNoYW5uZWxcblxuKi9cblxuY29uc3QgY2hhbm5lbERhdGEgPSAoeyBpcCwgb3JpZ2luYWxVcmwsIGJvZHksIHBhcmFtcyB9LCByZXMpID0+IHtcbiAgY29uc3QgY2hhbm5lbE5hbWUgPSBwYXJhbXMuY2hhbm5lbE5hbWU7XG4gIGxldCBjaGFubmVsQ2xhaW1JZCA9IHBhcmFtcy5jaGFubmVsQ2xhaW1JZDtcbiAgaWYgKGNoYW5uZWxDbGFpbUlkID09PSAnbm9uZScpIGNoYW5uZWxDbGFpbUlkID0gbnVsbDtcbiAgZ2V0Q2hhbm5lbERhdGEoY2hhbm5lbE5hbWUsIGNoYW5uZWxDbGFpbUlkLCAwKVxuICAgIC50aGVuKGRhdGEgPT4ge1xuICAgICAgaWYgKGRhdGEgPT09IE5PX0NIQU5ORUwpIHtcbiAgICAgICAgcmV0dXJuIHJlcy5zdGF0dXMoNDA0KS5qc29uKHtzdWNjZXNzOiBmYWxzZSwgbWVzc2FnZTogJ05vIG1hdGNoaW5nIGNoYW5uZWwgd2FzIGZvdW5kJ30pO1xuICAgICAgfVxuICAgICAgcmVzLnN0YXR1cygyMDApLmpzb24oe3N1Y2Nlc3M6IHRydWUsIGRhdGF9KTtcbiAgICB9KVxuICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICBoYW5kbGVFcnJvclJlc3BvbnNlKG9yaWdpbmFsVXJsLCBpcCwgZXJyb3IsIHJlcyk7XG4gICAgfSk7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IGNoYW5uZWxEYXRhO1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vc2VydmVyL3JvdXRlcy9hcGkvY2hhbm5lbERhdGEuanMiLCJjb25zdCB7IGhhbmRsZUVycm9yUmVzcG9uc2UgfSA9IHJlcXVpcmUoJ2hlbHBlcnMvZXJyb3JIYW5kbGVycy5qcycpO1xuY29uc3QgZGIgPSByZXF1aXJlKCdtb2RlbHMnKTtcblxuLypcblxucm91dGUgdG8gZ2V0IGEgc2hvcnQgY2hhbm5lbCBpZCBmcm9tIGxvbmcgY2hhbm5lbCBJZFxuXG4qL1xuXG5jb25zdCBjaGFubmVsU2hvcnRJZFJvdXRlID0gKHsgaXAsIG9yaWdpbmFsVXJsLCBwYXJhbXMgfSwgcmVzKSA9PiB7XG4gIGRiLkNlcnRpZmljYXRlLmdldFNob3J0Q2hhbm5lbElkRnJvbUxvbmdDaGFubmVsSWQocGFyYW1zLmxvbmdJZCwgcGFyYW1zLm5hbWUpXG4gICAgLnRoZW4oc2hvcnRJZCA9PiB7XG4gICAgICByZXMuc3RhdHVzKDIwMCkuanNvbihzaG9ydElkKTtcbiAgICB9KVxuICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICBoYW5kbGVFcnJvclJlc3BvbnNlKG9yaWdpbmFsVXJsLCBpcCwgZXJyb3IsIHJlcyk7XG4gICAgfSk7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IGNoYW5uZWxTaG9ydElkUm91dGU7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9zZXJ2ZXIvcm91dGVzL2FwaS9jaGFubmVsU2hvcnRJZC5qcyIsImNvbnN0IHsgY2xhaW1OYW1lSXNBdmFpbGFibGUgfSA9IHJlcXVpcmUoJ2NvbnRyb2xsZXJzL3B1Ymxpc2hDb250cm9sbGVyLmpzJyk7XG5jb25zdCB7IHNlbmRHQVRpbWluZ0V2ZW50IH0gPSByZXF1aXJlKCdoZWxwZXJzL2dvb2dsZUFuYWx5dGljcy5qcycpO1xuY29uc3QgeyBoYW5kbGVFcnJvclJlc3BvbnNlIH0gPSByZXF1aXJlKCdoZWxwZXJzL2Vycm9ySGFuZGxlcnMuanMnKTtcblxuLypcblxuICByb3V0ZSB0byBjaGVjayB3aGV0aGVyIHRoaXMgc2l0ZSBwdWJsaXNoZWQgdG8gYSBjbGFpbVxuXG4qL1xuXG5jb25zdCBjbGFpbUF2YWlsYWJpbGl0eSA9ICh7IGlwLCBvcmlnaW5hbFVybCwgcGFyYW1zOiB7IG5hbWUgfSB9LCByZXMpID0+IHtcbiAgY29uc3QgZ2FTdGFydFRpbWUgPSBEYXRlLm5vdygpO1xuICBjbGFpbU5hbWVJc0F2YWlsYWJsZShuYW1lKVxuICAgIC50aGVuKHJlc3VsdCA9PiB7XG4gICAgICByZXMuc3RhdHVzKDIwMCkuanNvbihyZXN1bHQpO1xuICAgICAgc2VuZEdBVGltaW5nRXZlbnQoJ2VuZC10by1lbmQnLCAnY2xhaW0gbmFtZSBhdmFpbGFiaWxpdHknLCBuYW1lLCBnYVN0YXJ0VGltZSwgRGF0ZS5ub3coKSk7XG4gICAgfSlcbiAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgaGFuZGxlRXJyb3JSZXNwb25zZShvcmlnaW5hbFVybCwgaXAsIGVycm9yLCByZXMpO1xuICAgIH0pO1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSBjbGFpbUF2YWlsYWJpbGl0eTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL3NlcnZlci9yb3V0ZXMvYXBpL2NsYWltQXZhaWxhYmlsaXR5LmpzIiwiY29uc3QgeyBoYW5kbGVFcnJvclJlc3BvbnNlIH0gPSByZXF1aXJlKCdoZWxwZXJzL2Vycm9ySGFuZGxlcnMuanMnKTtcbmNvbnN0IGRiID0gcmVxdWlyZSgnbW9kZWxzJyk7XG5cbi8qXG5cbiAgcm91dGUgdG8gcmV0dXJuIGRhdGEgZm9yIGEgY2xhaW1cblxuKi9cblxuY29uc3QgY2xhaW1EYXRhID0gKHsgaXAsIG9yaWdpbmFsVXJsLCBib2R5LCBwYXJhbXMgfSwgcmVzKSA9PiB7XG4gIGNvbnN0IGNsYWltTmFtZSA9IHBhcmFtcy5jbGFpbU5hbWU7XG4gIGxldCBjbGFpbUlkID0gcGFyYW1zLmNsYWltSWQ7XG4gIGlmIChjbGFpbUlkID09PSAnbm9uZScpIGNsYWltSWQgPSBudWxsO1xuICBkYi5DbGFpbS5yZXNvbHZlQ2xhaW0oY2xhaW1OYW1lLCBjbGFpbUlkKVxuICAgIC50aGVuKGNsYWltSW5mbyA9PiB7XG4gICAgICBpZiAoIWNsYWltSW5mbykge1xuICAgICAgICByZXR1cm4gcmVzLnN0YXR1cyg0MDQpLmpzb24oe3N1Y2Nlc3M6IGZhbHNlLCBtZXNzYWdlOiAnTm8gY2xhaW0gY291bGQgYmUgZm91bmQnfSk7XG4gICAgICB9XG4gICAgICByZXMuc3RhdHVzKDIwMCkuanNvbih7c3VjY2VzczogdHJ1ZSwgZGF0YTogY2xhaW1JbmZvfSk7XG4gICAgfSlcbiAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgaGFuZGxlRXJyb3JSZXNwb25zZShvcmlnaW5hbFVybCwgaXAsIGVycm9yLCByZXMpO1xuICAgIH0pO1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSBjbGFpbURhdGE7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9zZXJ2ZXIvcm91dGVzL2FwaS9jbGFpbURhdGEuanMiLCJjb25zdCB7IGdldENsYWltIH0gPSByZXF1aXJlKCdoZWxwZXJzL2xicnlBcGkuanMnKTtcbmNvbnN0IHsgYWRkR2V0UmVzdWx0c1RvRmlsZURhdGEsIGNyZWF0ZUZpbGVEYXRhIH0gPSByZXF1aXJlKCcuLi8uLi9oZWxwZXJzL3B1Ymxpc2hIZWxwZXJzLmpzJyk7XG5jb25zdCB7IGhhbmRsZUVycm9yUmVzcG9uc2UgfSA9IHJlcXVpcmUoJ2hlbHBlcnMvZXJyb3JIYW5kbGVycy5qcycpO1xuY29uc3QgZGIgPSByZXF1aXJlKCdtb2RlbHMnKTtcblxuLypcblxuICByb3V0ZSB0byBnZXQgYSBjbGFpbVxuXG4qL1xuXG5jb25zdCBjbGFpbUdldCA9ICh7IGlwLCBvcmlnaW5hbFVybCwgcGFyYW1zIH0sIHJlcykgPT4ge1xuICBjb25zdCBuYW1lID0gcGFyYW1zLm5hbWU7XG4gIGNvbnN0IGNsYWltSWQgPSBwYXJhbXMuY2xhaW1JZDtcbiAgLy8gcmVzb2x2ZSB0aGUgY2xhaW1cbiAgZGIuQ2xhaW0ucmVzb2x2ZUNsYWltKG5hbWUsIGNsYWltSWQpXG4gICAgLnRoZW4ocmVzb2x2ZVJlc3VsdCA9PiB7XG4gICAgICAvLyBtYWtlIHN1cmUgYSBjbGFpbSBhY3R1YWxseSBleGlzdHMgYXQgdGhhdCB1cmlcbiAgICAgIGlmICghcmVzb2x2ZVJlc3VsdCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ05vIG1hdGNoaW5nIHVyaSBmb3VuZCBpbiBDbGFpbSB0YWJsZScpO1xuICAgICAgfVxuICAgICAgbGV0IGZpbGVEYXRhID0gY3JlYXRlRmlsZURhdGEocmVzb2x2ZVJlc3VsdCk7XG4gICAgICAvLyBnZXQgdGhlIGNsYWltXG4gICAgICByZXR1cm4gUHJvbWlzZS5hbGwoW2ZpbGVEYXRhLCBnZXRDbGFpbShgJHtuYW1lfSMke2NsYWltSWR9YCldKTtcbiAgICB9KVxuICAgIC50aGVuKChbIGZpbGVEYXRhLCBnZXRSZXN1bHQgXSkgPT4ge1xuICAgICAgZmlsZURhdGEgPSBhZGRHZXRSZXN1bHRzVG9GaWxlRGF0YShmaWxlRGF0YSwgZ2V0UmVzdWx0KTtcbiAgICAgIHJldHVybiBQcm9taXNlLmFsbChbZGIudXBzZXJ0KGRiLkZpbGUsIGZpbGVEYXRhLCB7bmFtZSwgY2xhaW1JZH0sICdGaWxlJyksIGdldFJlc3VsdF0pO1xuICAgIH0pXG4gICAgLnRoZW4oKFsgZmlsZVJlY29yZCwge21lc3NhZ2UsIGNvbXBsZXRlZH0gXSkgPT4ge1xuICAgICAgcmVzLnN0YXR1cygyMDApLmpzb24oeyBzdWNjZXNzOiB0cnVlLCBtZXNzYWdlLCBjb21wbGV0ZWQgfSk7XG4gICAgfSlcbiAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgaGFuZGxlRXJyb3JSZXNwb25zZShvcmlnaW5hbFVybCwgaXAsIGVycm9yLCByZXMpO1xuICAgIH0pO1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSBjbGFpbUdldDtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL3NlcnZlci9yb3V0ZXMvYXBpL2NsYWltR2V0LmpzIiwiY29uc3QgeyBnZXRDbGFpbUlkIH0gPSByZXF1aXJlKCdjb250cm9sbGVycy9zZXJ2ZUNvbnRyb2xsZXIuanMnKTtcbmNvbnN0IHsgaGFuZGxlRXJyb3JSZXNwb25zZSB9ID0gcmVxdWlyZSgnaGVscGVycy9lcnJvckhhbmRsZXJzLmpzJyk7XG5cbmNvbnN0IE5PX0NIQU5ORUwgPSAnTk9fQ0hBTk5FTCc7XG5jb25zdCBOT19DTEFJTSA9ICdOT19DTEFJTSc7XG5cbi8qXG5cbiAgcm91dGUgdG8gZ2V0IGEgbG9uZyBjbGFpbSBpZFxuXG4qL1xuXG5jb25zdCBjbGFpbUxvbmdJZCA9ICh7IGlwLCBvcmlnaW5hbFVybCwgYm9keSwgcGFyYW1zIH0sIHJlcykgPT4ge1xuICBjb25zdCBjaGFubmVsTmFtZSA9IGJvZHkuY2hhbm5lbE5hbWU7XG4gIGNvbnN0IGNoYW5uZWxDbGFpbUlkID0gYm9keS5jaGFubmVsQ2xhaW1JZDtcbiAgY29uc3QgY2xhaW1OYW1lID0gYm9keS5jbGFpbU5hbWU7XG4gIGNvbnN0IGNsYWltSWQgPSBib2R5LmNsYWltSWQ7XG4gIGdldENsYWltSWQoY2hhbm5lbE5hbWUsIGNoYW5uZWxDbGFpbUlkLCBjbGFpbU5hbWUsIGNsYWltSWQpXG4gICAgLnRoZW4ocmVzdWx0ID0+IHtcbiAgICAgIGlmIChyZXN1bHQgPT09IE5PX0NIQU5ORUwpIHtcbiAgICAgICAgcmV0dXJuIHJlcy5zdGF0dXMoNDA0KS5qc29uKHtzdWNjZXNzOiBmYWxzZSwgbWVzc2FnZTogJ05vIG1hdGNoaW5nIGNoYW5uZWwgY291bGQgYmUgZm91bmQnfSk7XG4gICAgICB9XG4gICAgICBpZiAocmVzdWx0ID09PSBOT19DTEFJTSkge1xuICAgICAgICByZXR1cm4gcmVzLnN0YXR1cyg0MDQpLmpzb24oe3N1Y2Nlc3M6IGZhbHNlLCBtZXNzYWdlOiAnTm8gbWF0Y2hpbmcgY2xhaW0gaWQgY291bGQgYmUgZm91bmQnfSk7XG4gICAgICB9XG4gICAgICByZXMuc3RhdHVzKDIwMCkuanNvbih7c3VjY2VzczogdHJ1ZSwgZGF0YTogcmVzdWx0fSk7XG4gICAgfSlcbiAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgaGFuZGxlRXJyb3JSZXNwb25zZShvcmlnaW5hbFVybCwgaXAsIGVycm9yLCByZXMpO1xuICAgIH0pO1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSBjbGFpbUxvbmdJZDtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL3NlcnZlci9yb3V0ZXMvYXBpL2NsYWltTG9uZ0lkLmpzIiwiY29uc3QgeyBjcmVhdGVCYXNpY1B1Ymxpc2hQYXJhbXMsIGNyZWF0ZVRodW1ibmFpbFB1Ymxpc2hQYXJhbXMsIHBhcnNlUHVibGlzaEFwaVJlcXVlc3RCb2R5LCBwYXJzZVB1Ymxpc2hBcGlSZXF1ZXN0RmlsZXMgfSA9IHJlcXVpcmUoJ2hlbHBlcnMvcHVibGlzaEhlbHBlcnMuanMnKTtcbmNvbnN0IHsgY2xhaW1OYW1lSXNBdmFpbGFibGUsIHB1Ymxpc2ggfSA9IHJlcXVpcmUoJ2NvbnRyb2xsZXJzL3B1Ymxpc2hDb250cm9sbGVyLmpzJyk7XG5jb25zdCB7IGF1dGhlbnRpY2F0ZVVzZXIgfSA9IHJlcXVpcmUoJ2F1dGgvYXV0aGVudGljYXRpb24uanMnKTtcbmNvbnN0IHsgc2VuZEdBVGltaW5nRXZlbnQgfSA9IHJlcXVpcmUoJ2hlbHBlcnMvZ29vZ2xlQW5hbHl0aWNzLmpzJyk7XG5jb25zdCB7IGhhbmRsZUVycm9yUmVzcG9uc2UgfSA9IHJlcXVpcmUoJ2hlbHBlcnMvZXJyb3JIYW5kbGVycy5qcycpO1xuY29uc3QgeyBkZXRhaWxzOiB7IGhvc3QgfSB9ID0gcmVxdWlyZSgnc2l0ZUNvbmZpZy5qcycpO1xuXG4vKlxuXG4gIHJvdXRlIHRvIHB1Ymxpc2ggYSBjbGFpbSB0aHJvdWdoIHRoZSBkYWVtb25cblxuKi9cblxuY29uc3QgY2xhaW1QdWJsaXNoID0gKHsgYm9keSwgZmlsZXMsIGhlYWRlcnMsIGlwLCBvcmlnaW5hbFVybCwgdXNlciB9LCByZXMpID0+IHtcbiAgLy8gZGVmaW5lIHZhcmlhYmxlc1xuICBsZXQgIGNoYW5uZWxOYW1lLCBjaGFubmVsSWQsIGNoYW5uZWxQYXNzd29yZCwgZGVzY3JpcHRpb24sIGZpbGVOYW1lLCBmaWxlUGF0aCwgZmlsZVR5cGUsIGdhU3RhcnRUaW1lLCBsaWNlbnNlLCBuYW1lLCBuc2Z3LCB0aHVtYm5haWwsIHRodW1ibmFpbEZpbGVOYW1lLCB0aHVtYm5haWxGaWxlUGF0aCwgdGh1bWJuYWlsRmlsZVR5cGUsIHRpdGxlO1xuICAvLyByZWNvcmQgdGhlIHN0YXJ0IHRpbWUgb2YgdGhlIHJlcXVlc3RcbiAgZ2FTdGFydFRpbWUgPSBEYXRlLm5vdygpO1xuICAvLyB2YWxpZGF0ZSB0aGUgYm9keSBhbmQgZmlsZXMgb2YgdGhlIHJlcXVlc3RcbiAgdHJ5IHtcbiAgICAvLyB2YWxpZGF0ZUFwaVB1Ymxpc2hSZXF1ZXN0KGJvZHksIGZpbGVzKTtcbiAgICAoe25hbWUsIG5zZncsIGxpY2Vuc2UsIHRpdGxlLCBkZXNjcmlwdGlvbiwgdGh1bWJuYWlsfSA9IHBhcnNlUHVibGlzaEFwaVJlcXVlc3RCb2R5KGJvZHkpKTtcbiAgICAoe2ZpbGVOYW1lLCBmaWxlUGF0aCwgZmlsZVR5cGUsIHRodW1ibmFpbEZpbGVOYW1lLCB0aHVtYm5haWxGaWxlUGF0aCwgdGh1bWJuYWlsRmlsZVR5cGV9ID0gcGFyc2VQdWJsaXNoQXBpUmVxdWVzdEZpbGVzKGZpbGVzKSk7XG4gICAgKHtjaGFubmVsTmFtZSwgY2hhbm5lbElkLCBjaGFubmVsUGFzc3dvcmR9ID0gYm9keSk7XG4gIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgcmV0dXJuIHJlcy5zdGF0dXMoNDAwKS5qc29uKHtzdWNjZXNzOiBmYWxzZSwgbWVzc2FnZTogZXJyb3IubWVzc2FnZX0pO1xuICB9XG4gIC8vIGNoZWNrIGNoYW5uZWwgYXV0aG9yaXphdGlvblxuICBQcm9taXNlXG4gICAgLmFsbChbXG4gICAgICBhdXRoZW50aWNhdGVVc2VyKGNoYW5uZWxOYW1lLCBjaGFubmVsSWQsIGNoYW5uZWxQYXNzd29yZCwgdXNlciksXG4gICAgICBjbGFpbU5hbWVJc0F2YWlsYWJsZShuYW1lKSxcbiAgICAgIGNyZWF0ZUJhc2ljUHVibGlzaFBhcmFtcyhmaWxlUGF0aCwgbmFtZSwgdGl0bGUsIGRlc2NyaXB0aW9uLCBsaWNlbnNlLCBuc2Z3LCB0aHVtYm5haWwpLFxuICAgICAgY3JlYXRlVGh1bWJuYWlsUHVibGlzaFBhcmFtcyh0aHVtYm5haWxGaWxlUGF0aCwgbmFtZSwgbGljZW5zZSwgbnNmdyksXG4gICAgXSlcbiAgICAudGhlbigoW3tjaGFubmVsTmFtZSwgY2hhbm5lbENsYWltSWR9LCB2YWxpZGF0ZWRDbGFpbU5hbWUsIHB1Ymxpc2hQYXJhbXMsIHRodW1ibmFpbFB1Ymxpc2hQYXJhbXNdKSA9PiB7XG4gICAgICAvLyBhZGQgY2hhbm5lbCBkZXRhaWxzIHRvIHRoZSBwdWJsaXNoIHBhcmFtc1xuICAgICAgaWYgKGNoYW5uZWxOYW1lICYmIGNoYW5uZWxDbGFpbUlkKSB7XG4gICAgICAgIHB1Ymxpc2hQYXJhbXNbJ2NoYW5uZWxfbmFtZSddID0gY2hhbm5lbE5hbWU7XG4gICAgICAgIHB1Ymxpc2hQYXJhbXNbJ2NoYW5uZWxfaWQnXSA9IGNoYW5uZWxDbGFpbUlkO1xuICAgICAgfVxuICAgICAgLy8gcHVibGlzaCB0aGUgdGh1bWJuYWlsXG4gICAgICBpZiAodGh1bWJuYWlsUHVibGlzaFBhcmFtcykge1xuICAgICAgICBwdWJsaXNoKHRodW1ibmFpbFB1Ymxpc2hQYXJhbXMsIHRodW1ibmFpbEZpbGVOYW1lLCB0aHVtYm5haWxGaWxlVHlwZSk7XG4gICAgICB9XG4gICAgICAvLyBwdWJsaXNoIHRoZSBhc3NldFxuICAgICAgcmV0dXJuIHB1Ymxpc2gocHVibGlzaFBhcmFtcywgZmlsZU5hbWUsIGZpbGVUeXBlKTtcbiAgICB9KVxuICAgIC50aGVuKHJlc3VsdCA9PiB7XG4gICAgICByZXMuc3RhdHVzKDIwMCkuanNvbih7XG4gICAgICAgIHN1Y2Nlc3M6IHRydWUsXG4gICAgICAgIG1lc3NhZ2U6ICdwdWJsaXNoIGNvbXBsZXRlZCBzdWNjZXNzZnVsbHknLFxuICAgICAgICBkYXRhICAgOiB7XG4gICAgICAgICAgbmFtZSxcbiAgICAgICAgICBjbGFpbUlkOiByZXN1bHQuY2xhaW1faWQsXG4gICAgICAgICAgdXJsICAgIDogYCR7aG9zdH0vJHtyZXN1bHQuY2xhaW1faWR9LyR7bmFtZX1gLFxuICAgICAgICAgIGxicnlUeCA6IHJlc3VsdCxcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuICAgICAgLy8gcmVjb3JkIHRoZSBwdWJsaXNoIGVuZCB0aW1lIGFuZCBzZW5kIHRvIGdvb2dsZSBhbmFseXRpY3NcbiAgICAgIHNlbmRHQVRpbWluZ0V2ZW50KCdlbmQtdG8tZW5kJywgJ3B1Ymxpc2gnLCBmaWxlVHlwZSwgZ2FTdGFydFRpbWUsIERhdGUubm93KCkpO1xuICAgIH0pXG4gICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgIGhhbmRsZUVycm9yUmVzcG9uc2Uob3JpZ2luYWxVcmwsIGlwLCBlcnJvciwgcmVzKTtcbiAgICB9KTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gY2xhaW1QdWJsaXNoO1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vc2VydmVyL3JvdXRlcy9hcGkvY2xhaW1QdWJsaXNoLmpzIiwiY29uc3QgZGIgPSByZXF1aXJlKCdtb2RlbHMnKTtcbmNvbnN0IGxvZ2dlciA9IHJlcXVpcmUoJ3dpbnN0b24nKTtcblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIGF1dGhlbnRpY2F0ZVVzZXIgKGNoYW5uZWxOYW1lLCBjaGFubmVsSWQsIGNoYW5uZWxQYXNzd29yZCwgdXNlcikge1xuICAgIC8vIGNhc2U6IG5vIGNoYW5uZWxOYW1lIG9yIGNoYW5uZWwgSWQgYXJlIHByb3ZpZGVkIChhbm9ueW1vdXMpLCByZWdhcmRsZXNzIG9mIHdoZXRoZXIgdXNlciB0b2tlbiBpcyBwcm92aWRlZFxuICAgIGlmICghY2hhbm5lbE5hbWUgJiYgIWNoYW5uZWxJZCkge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgY2hhbm5lbE5hbWUgICA6IG51bGwsXG4gICAgICAgIGNoYW5uZWxDbGFpbUlkOiBudWxsLFxuICAgICAgfTtcbiAgICB9XG4gICAgLy8gY2FzZTogY2hhbm5lbE5hbWUgb3IgY2hhbm5lbCBJZCBhcmUgcHJvdmlkZWQgd2l0aCB1c2VyIHRva2VuXG4gICAgaWYgKHVzZXIpIHtcbiAgICAgIGlmIChjaGFubmVsTmFtZSAmJiBjaGFubmVsTmFtZSAhPT0gdXNlci5jaGFubmVsTmFtZSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ3RoZSBwcm92aWRlZCBjaGFubmVsIG5hbWUgZG9lcyBub3QgbWF0Y2ggdXNlciBjcmVkZW50aWFscycpO1xuICAgICAgfVxuICAgICAgaWYgKGNoYW5uZWxJZCAmJiBjaGFubmVsSWQgIT09IHVzZXIuY2hhbm5lbENsYWltSWQpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCd0aGUgcHJvdmlkZWQgY2hhbm5lbCBpZCBkb2VzIG5vdCBtYXRjaCB1c2VyIGNyZWRlbnRpYWxzJyk7XG4gICAgICB9XG4gICAgICByZXR1cm4ge1xuICAgICAgICBjaGFubmVsTmFtZSAgIDogdXNlci5jaGFubmVsTmFtZSxcbiAgICAgICAgY2hhbm5lbENsYWltSWQ6IHVzZXIuY2hhbm5lbENsYWltSWQsXG4gICAgICB9O1xuICAgIH1cbiAgICAvLyBjYXNlOiBjaGFubmVsTmFtZSBvciBjaGFubmVsIElkIGFyZSBwcm92aWRlZCB3aXRoIHBhc3N3b3JkIGluc3RlYWQgb2YgdXNlciB0b2tlblxuICAgIGlmICghY2hhbm5lbFBhc3N3b3JkKSB0aHJvdyBuZXcgRXJyb3IoJ25vIGNoYW5uZWwgcGFzc3dvcmQgcHJvdmlkZWQnKTtcbiAgICByZXR1cm4gbW9kdWxlLmV4cG9ydHMuYXV0aGVudGljYXRlQ2hhbm5lbENyZWRlbnRpYWxzKGNoYW5uZWxOYW1lLCBjaGFubmVsSWQsIGNoYW5uZWxQYXNzd29yZCk7XG4gIH0sXG4gIGF1dGhlbnRpY2F0ZUNoYW5uZWxDcmVkZW50aWFscyAoY2hhbm5lbE5hbWUsIGNoYW5uZWxJZCwgdXNlclBhc3N3b3JkKSB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIC8vIGhvaXN0ZWQgdmFyaWFibGVzXG4gICAgICBsZXQgY2hhbm5lbERhdGE7XG4gICAgICAvLyBidWlsZCB0aGUgcGFyYW1zIGZvciBmaW5kaW5nIHRoZSBjaGFubmVsXG4gICAgICBsZXQgY2hhbm5lbEZpbmRQYXJhbXMgPSB7fTtcbiAgICAgIGlmIChjaGFubmVsTmFtZSkgY2hhbm5lbEZpbmRQYXJhbXNbJ2NoYW5uZWxOYW1lJ10gPSBjaGFubmVsTmFtZTtcbiAgICAgIGlmIChjaGFubmVsSWQpIGNoYW5uZWxGaW5kUGFyYW1zWydjaGFubmVsQ2xhaW1JZCddID0gY2hhbm5lbElkO1xuICAgICAgLy8gZmluZCB0aGUgY2hhbm5lbFxuICAgICAgZGIuQ2hhbm5lbFxuICAgICAgICAuZmluZE9uZSh7XG4gICAgICAgICAgd2hlcmU6IGNoYW5uZWxGaW5kUGFyYW1zLFxuICAgICAgICB9KVxuICAgICAgICAudGhlbihjaGFubmVsID0+IHtcbiAgICAgICAgICBpZiAoIWNoYW5uZWwpIHtcbiAgICAgICAgICAgIGxvZ2dlci5kZWJ1Zygnbm8gY2hhbm5lbCBmb3VuZCcpO1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdBdXRoZW50aWNhdGlvbiBmYWlsZWQsIHlvdSBkbyBub3QgaGF2ZSBhY2Nlc3MgdG8gdGhhdCBjaGFubmVsJyk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNoYW5uZWxEYXRhID0gY2hhbm5lbC5nZXQoKTtcbiAgICAgICAgICBsb2dnZXIuZGVidWcoJ2NoYW5uZWwgZGF0YTonLCBjaGFubmVsRGF0YSk7XG4gICAgICAgICAgcmV0dXJuIGRiLlVzZXIuZmluZE9uZSh7XG4gICAgICAgICAgICB3aGVyZTogeyB1c2VyTmFtZTogY2hhbm5lbERhdGEuY2hhbm5lbE5hbWUuc3Vic3RyaW5nKDEpIH0sXG4gICAgICAgICAgfSk7XG4gICAgICAgIH0pXG4gICAgICAgIC50aGVuKHVzZXIgPT4ge1xuICAgICAgICAgIGlmICghdXNlcikge1xuICAgICAgICAgICAgbG9nZ2VyLmRlYnVnKCdubyB1c2VyIGZvdW5kJyk7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0F1dGhlbnRpY2F0aW9uIGZhaWxlZCwgeW91IGRvIG5vdCBoYXZlIGFjY2VzcyB0byB0aGF0IGNoYW5uZWwnKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIHVzZXIuY29tcGFyZVBhc3N3b3JkKHVzZXJQYXNzd29yZCk7XG4gICAgICAgIH0pXG4gICAgICAgIC50aGVuKGlzTWF0Y2ggPT4ge1xuICAgICAgICAgIGlmICghaXNNYXRjaCkge1xuICAgICAgICAgICAgbG9nZ2VyLmRlYnVnKCdpbmNvcnJlY3QgcGFzc3dvcmQnKTtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignQXV0aGVudGljYXRpb24gZmFpbGVkLCB5b3UgZG8gbm90IGhhdmUgYWNjZXNzIHRvIHRoYXQgY2hhbm5lbCcpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBsb2dnZXIuZGVidWcoJy4uLnBhc3N3b3JkIHdhcyBhIG1hdGNoLi4uJyk7XG4gICAgICAgICAgcmVzb2x2ZShjaGFubmVsRGF0YSk7XG4gICAgICAgIH0pXG4gICAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgfSk7XG4gICAgfSk7XG4gIH0sXG59O1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vc2VydmVyL2F1dGgvYXV0aGVudGljYXRpb24uanMiLCJjb25zdCB7IHJlc29sdmVVcmkgfSA9IHJlcXVpcmUoJ2hlbHBlcnMvbGJyeUFwaS5qcycpO1xuY29uc3QgeyBoYW5kbGVFcnJvclJlc3BvbnNlIH0gPSByZXF1aXJlKCdoZWxwZXJzL2Vycm9ySGFuZGxlcnMuanMnKTtcblxuLypcblxuICByb3V0ZSB0byBydW4gYSByZXNvbHZlIHJlcXVlc3Qgb24gdGhlIGRhZW1vblxuXG4qL1xuXG5jb25zdCBjbGFpbVJlc29sdmUgPSAoeyBoZWFkZXJzLCBpcCwgb3JpZ2luYWxVcmwsIHBhcmFtcyB9LCByZXMpID0+IHtcbiAgcmVzb2x2ZVVyaShgJHtwYXJhbXMubmFtZX0jJHtwYXJhbXMuY2xhaW1JZH1gKVxuICAgIC50aGVuKHJlc29sdmVkVXJpID0+IHtcbiAgICAgIHJlcy5zdGF0dXMoMjAwKS5qc29uKHJlc29sdmVkVXJpKTtcbiAgICB9KVxuICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICBoYW5kbGVFcnJvclJlc3BvbnNlKG9yaWdpbmFsVXJsLCBpcCwgZXJyb3IsIHJlcyk7XG4gICAgfSk7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IGNsYWltUmVzb2x2ZTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL3NlcnZlci9yb3V0ZXMvYXBpL2NsYWltUmVzb2x2ZS5qcyIsImNvbnN0IHsgaGFuZGxlRXJyb3JSZXNwb25zZSB9ID0gcmVxdWlyZSgnaGVscGVycy9lcnJvckhhbmRsZXJzLmpzJyk7XG5jb25zdCBkYiA9IHJlcXVpcmUoJ21vZGVscycpO1xuXG4vKlxuXG4gIHJvdXRlIHRvIGdldCBhIHNob3J0IGNsYWltIGlkIGZyb20gbG9uZyBjbGFpbSBJZFxuXG4qL1xuXG5jb25zdCBjbGFpbVNob3J0SWQgPSAoeyBpcCwgb3JpZ2luYWxVcmwsIGJvZHksIHBhcmFtcyB9LCByZXMpID0+IHtcbiAgZGIuQ2xhaW0uZ2V0U2hvcnRDbGFpbUlkRnJvbUxvbmdDbGFpbUlkKHBhcmFtcy5sb25nSWQsIHBhcmFtcy5uYW1lKVxuICAgIC50aGVuKHNob3J0SWQgPT4ge1xuICAgICAgcmVzLnN0YXR1cygyMDApLmpzb24oe3N1Y2Nlc3M6IHRydWUsIGRhdGE6IHNob3J0SWR9KTtcbiAgICB9KVxuICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICBoYW5kbGVFcnJvclJlc3BvbnNlKG9yaWdpbmFsVXJsLCBpcCwgZXJyb3IsIHJlcyk7XG4gICAgfSk7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IGNsYWltU2hvcnRJZDtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL3NlcnZlci9yb3V0ZXMvYXBpL2NsYWltU2hvcnRJZC5qcyIsImNvbnN0IHsgZ2V0Q2xhaW1MaXN0IH0gPSByZXF1aXJlKCdoZWxwZXJzL2xicnlBcGkuanMnKTtcbmNvbnN0IHsgaGFuZGxlRXJyb3JSZXNwb25zZSB9ID0gcmVxdWlyZSgnaGVscGVycy9lcnJvckhhbmRsZXJzLmpzJyk7XG5cbi8qXG5cbiAgcm91dGUgdG8gZ2V0IGxpc3Qgb2YgY2xhaW1zXG5cbiovXG5cbmNvbnN0IGNsYWltTGlzdCA9ICh7IGlwLCBvcmlnaW5hbFVybCwgcGFyYW1zIH0sIHJlcykgPT4ge1xuICBnZXRDbGFpbUxpc3QocGFyYW1zLm5hbWUpXG4gICAgLnRoZW4oY2xhaW1zTGlzdCA9PiB7XG4gICAgICByZXMuc3RhdHVzKDIwMCkuanNvbihjbGFpbXNMaXN0KTtcbiAgICB9KVxuICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICBoYW5kbGVFcnJvclJlc3BvbnNlKG9yaWdpbmFsVXJsLCBpcCwgZXJyb3IsIHJlcyk7XG4gICAgfSk7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IGNsYWltTGlzdDtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL3NlcnZlci9yb3V0ZXMvYXBpL2NsYWltTGlzdC5qcyIsImNvbnN0IHsgaGFuZGxlRXJyb3JSZXNwb25zZSB9ID0gcmVxdWlyZSgnaGVscGVycy9lcnJvckhhbmRsZXJzLmpzJyk7XG5jb25zdCBkYiA9IHJlcXVpcmUoJ21vZGVscycpO1xuXG4vKlxuXG4gIHJvdXRlIHRvIHNlZSBpZiBhc3NldCBpcyBhdmFpbGFibGUgbG9jYWxseVxuXG4qL1xuXG5jb25zdCBmaWxlQXZhaWxhYmlsaXR5ID0gKHsgaXAsIG9yaWdpbmFsVXJsLCBwYXJhbXMgfSwgcmVzKSA9PiB7XG4gIGNvbnN0IG5hbWUgPSBwYXJhbXMubmFtZTtcbiAgY29uc3QgY2xhaW1JZCA9IHBhcmFtcy5jbGFpbUlkO1xuICBkYi5GaWxlXG4gICAgLmZpbmRPbmUoe1xuICAgICAgd2hlcmU6IHtcbiAgICAgICAgbmFtZSxcbiAgICAgICAgY2xhaW1JZCxcbiAgICAgIH0sXG4gICAgfSlcbiAgICAudGhlbihyZXN1bHQgPT4ge1xuICAgICAgaWYgKHJlc3VsdCkge1xuICAgICAgICByZXR1cm4gcmVzLnN0YXR1cygyMDApLmpzb24oe3N1Y2Nlc3M6IHRydWUsIGRhdGE6IHRydWV9KTtcbiAgICAgIH1cbiAgICAgIHJlcy5zdGF0dXMoMjAwKS5qc29uKHtzdWNjZXNzOiB0cnVlLCBkYXRhOiBmYWxzZX0pO1xuICAgIH0pXG4gICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgIGhhbmRsZUVycm9yUmVzcG9uc2Uob3JpZ2luYWxVcmwsIGlwLCBlcnJvciwgcmVzKTtcbiAgICB9KTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gZmlsZUF2YWlsYWJpbGl0eTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL3NlcnZlci9yb3V0ZXMvYXBpL2ZpbGVBdmFpbGFiaWxpdHkuanMiLCJjb25zdCBtdWx0aXBhcnQgPSByZXF1aXJlKCdjb25uZWN0LW11bHRpcGFydHknKTtcbmNvbnN0IHsgcHVibGlzaGluZzogeyB1cGxvYWREaXJlY3RvcnkgfSB9ID0gcmVxdWlyZSgnc2l0ZUNvbmZpZy5qcycpO1xuY29uc3QgbXVsdGlwYXJ0TWlkZGxld2FyZSA9IG11bHRpcGFydCh7dXBsb2FkRGlyOiB1cGxvYWREaXJlY3Rvcnl9KTtcblxubW9kdWxlLmV4cG9ydHMgPSBtdWx0aXBhcnRNaWRkbGV3YXJlO1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vc2VydmVyL2hlbHBlcnMvbXVsdGlwYXJ0TWlkZGxld2FyZS5qcyIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcImNvbm5lY3QtbXVsdGlwYXJ0eVwiKTtcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyBleHRlcm5hbCBcImNvbm5lY3QtbXVsdGlwYXJ0eVwiXG4vLyBtb2R1bGUgaWQgPSA4MFxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJjb25zdCBoYW5kbGVQYWdlUmVxdWVzdCA9IHJlcXVpcmUoJy4vc2VuZFJlYWN0QXBwJyk7XG5jb25zdCBoYW5kbGVFbWJlZFJlcXVlc3QgPSByZXF1aXJlKCcuL3NlbmRFbWJlZFBhZ2UnKTtcbmNvbnN0IHJlZGlyZWN0ID0gcmVxdWlyZSgnLi9yZWRpcmVjdCcpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IChhcHApID0+IHtcbiAgYXBwLmdldCgnLycsIGhhbmRsZVBhZ2VSZXF1ZXN0KTtcbiAgYXBwLmdldCgnL2xvZ2luJywgaGFuZGxlUGFnZVJlcXVlc3QpO1xuICBhcHAuZ2V0KCcvYWJvdXQnLCBoYW5kbGVQYWdlUmVxdWVzdCk7XG4gIGFwcC5nZXQoJy90cmVuZGluZycsIHJlZGlyZWN0KCcvcG9wdWxhcicpKTtcbiAgYXBwLmdldCgnL3BvcHVsYXInLCBoYW5kbGVQYWdlUmVxdWVzdCk7XG4gIGFwcC5nZXQoJy9uZXcnLCBoYW5kbGVQYWdlUmVxdWVzdCk7XG4gIGFwcC5nZXQoJy9lbWJlZC86Y2xhaW1JZC86bmFtZScsIGhhbmRsZUVtYmVkUmVxdWVzdCk7ICAvLyByb3V0ZSB0byBzZW5kIGVtYmVkYWJsZSB2aWRlbyBwbGF5ZXIgKGZvciB0d2l0dGVyKVxufTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL3NlcnZlci9yb3V0ZXMvcGFnZXMvaW5kZXguanMiLCJjb25zdCBoYW5kbGVQYWdlUmVuZGVyID0gcmVxdWlyZSgnaGVscGVycy9oYW5kbGVQYWdlUmVuZGVyLmpzeCcpO1xuXG5jb25zdCBzZW5kUmVhY3RBcHAgPSAocmVxLCByZXMpID0+IHtcbiAgaGFuZGxlUGFnZVJlbmRlcihyZXEsIHJlcyk7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IHNlbmRSZWFjdEFwcDtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL3NlcnZlci9yb3V0ZXMvcGFnZXMvc2VuZFJlYWN0QXBwLmpzIiwiY29uc3QgeyBkZXRhaWxzOiB7IGhvc3QgfSB9ID0gcmVxdWlyZSgnc2l0ZUNvbmZpZy5qcycpO1xuXG5jb25zdCBzZW5kRW1iZWRQYWdlID0gKHsgcGFyYW1zIH0sIHJlcykgPT4ge1xuICBjb25zdCBjbGFpbUlkID0gcGFyYW1zLmNsYWltSWQ7XG4gIGNvbnN0IG5hbWUgPSBwYXJhbXMubmFtZTtcbiAgLy8gZ2V0IGFuZCByZW5kZXIgdGhlIGNvbnRlbnRcbiAgcmVzLnN0YXR1cygyMDApLnJlbmRlcignZW1iZWQnLCB7IGxheW91dDogJ2VtYmVkJywgaG9zdCwgY2xhaW1JZCwgbmFtZSB9KTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gc2VuZEVtYmVkUGFnZTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL3NlcnZlci9yb3V0ZXMvcGFnZXMvc2VuZEVtYmVkUGFnZS5qcyIsImNvbnN0IHJlZGlyZWN0ID0gKHJvdXRlKSA9PiB7XG4gIHJldHVybiAocmVxLCByZXMpID0+IHtcbiAgICByZXMuc3RhdHVzKDMwMSkucmVkaXJlY3Qocm91dGUpO1xuICB9O1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSByZWRpcmVjdDtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL3NlcnZlci9yb3V0ZXMvcGFnZXMvcmVkaXJlY3QuanMiLCJjb25zdCBzZXJ2ZUFzc2V0QnlDbGFpbSA9IHJlcXVpcmUoJy4vc2VydmVBc3NldEJ5Q2xhaW0nKTtcbmNvbnN0IHNlcnZlQXNzZXRCeUlkZW50aWZpZXJBbmRDbGFpbSA9IHJlcXVpcmUoJy4vc2VydmVBc3NldEJ5SWRlbnRpZmllckFuZENsYWltJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gKGFwcCwgZGIpID0+IHtcbiAgYXBwLmdldCgnLzppZGVudGlmaWVyLzpjbGFpbScsIHNlcnZlQXNzZXRCeUlkZW50aWZpZXJBbmRDbGFpbSk7XG4gIGFwcC5nZXQoJy86Y2xhaW0nLCBzZXJ2ZUFzc2V0QnlDbGFpbSk7XG59O1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vc2VydmVyL3JvdXRlcy9hc3NldHMvaW5kZXguanMiLCJjb25zdCB7IHNlbmRHQVNlcnZlRXZlbnQgfSA9IHJlcXVpcmUoJ2hlbHBlcnMvZ29vZ2xlQW5hbHl0aWNzJyk7XG5jb25zdCB7IGRldGVybWluZVJlc3BvbnNlVHlwZSwgbG9nUmVxdWVzdERhdGEsIGdldENsYWltSWRBbmRTZXJ2ZUFzc2V0IH0gPSByZXF1aXJlKCdoZWxwZXJzL3NlcnZlSGVscGVycy5qcycpO1xuY29uc3QgbGJyeVVyaSA9IHJlcXVpcmUoJ2hlbHBlcnMvbGJyeVVyaS5qcycpO1xuY29uc3QgaGFuZGxlU2hvd1JlbmRlciA9IHJlcXVpcmUoJ2hlbHBlcnMvaGFuZGxlU2hvd1JlbmRlci5qc3gnKTtcbmNvbnN0IFNFUlZFID0gJ1NFUlZFJztcblxuLypcblxuICByb3V0ZSB0byBzZXJ2ZSBhbiBhc3NldCBvciB0aGUgcmVhY3QgYXBwIHZpYSB0aGUgY2xhaW0gbmFtZSBvbmx5XG5cbiovXG5cbmNvbnN0IHNlcnZlckFzc2V0QnlDbGFpbSA9IChyZXEsIHJlcykgPT4ge1xuICBjb25zdCB7IGhlYWRlcnMsIGlwLCBvcmlnaW5hbFVybCwgcGFyYW1zIH0gPSByZXE7XG4gIC8vIGRlY2lkZSBpZiB0aGlzIGlzIGEgc2hvdyByZXF1ZXN0XG4gIGxldCBoYXNGaWxlRXh0ZW5zaW9uO1xuICB0cnkge1xuICAgICh7IGhhc0ZpbGVFeHRlbnNpb24gfSA9IGxicnlVcmkucGFyc2VNb2RpZmllcihwYXJhbXMuY2xhaW0pKTtcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICByZXR1cm4gcmVzLnN0YXR1cyg0MDApLmpzb24oe3N1Y2Nlc3M6IGZhbHNlLCBtZXNzYWdlOiBlcnJvci5tZXNzYWdlfSk7XG4gIH1cbiAgbGV0IHJlc3BvbnNlVHlwZSA9IGRldGVybWluZVJlc3BvbnNlVHlwZShoYXNGaWxlRXh0ZW5zaW9uLCBoZWFkZXJzKTtcbiAgaWYgKHJlc3BvbnNlVHlwZSAhPT0gU0VSVkUpIHtcbiAgICByZXR1cm4gaGFuZGxlU2hvd1JlbmRlcihyZXEsIHJlcyk7XG4gIH1cbiAgLy8gaGFuZGxlIHNlcnZlIHJlcXVlc3RcbiAgLy8gc2VuZCBnb29nbGUgYW5hbHl0aWNzXG4gIHNlbmRHQVNlcnZlRXZlbnQoaGVhZGVycywgaXAsIG9yaWdpbmFsVXJsKTtcbiAgLy8gcGFyc2UgdGhlIGNsYWltXG4gIGxldCBjbGFpbU5hbWU7XG4gIHRyeSB7XG4gICAgKHtjbGFpbU5hbWV9ID0gbGJyeVVyaS5wYXJzZUNsYWltKHBhcmFtcy5jbGFpbSkpO1xuICB9IGNhdGNoIChlcnJvcikge1xuICAgIHJldHVybiByZXMuc3RhdHVzKDQwMCkuanNvbih7c3VjY2VzczogZmFsc2UsIG1lc3NhZ2U6IGVycm9yLm1lc3NhZ2V9KTtcbiAgfVxuICAvLyBsb2cgdGhlIHJlcXVlc3QgZGF0YSBmb3IgZGVidWdnaW5nXG4gIGxvZ1JlcXVlc3REYXRhKHJlc3BvbnNlVHlwZSwgY2xhaW1OYW1lLCBudWxsLCBudWxsKTtcbiAgLy8gZ2V0IHRoZSBjbGFpbSBJZCBhbmQgdGhlbiBzZXJ2ZSB0aGUgYXNzZXRcbiAgZ2V0Q2xhaW1JZEFuZFNlcnZlQXNzZXQobnVsbCwgbnVsbCwgY2xhaW1OYW1lLCBudWxsLCBvcmlnaW5hbFVybCwgaXAsIHJlcyk7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IHNlcnZlckFzc2V0QnlDbGFpbTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL3NlcnZlci9yb3V0ZXMvYXNzZXRzL3NlcnZlQXNzZXRCeUNsYWltLmpzIiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwicmVkdXgtc2FnYVwiKTtcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyBleHRlcm5hbCBcInJlZHV4LXNhZ2FcIlxuLy8gbW9kdWxlIGlkID0gODdcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwicmVkdXgtc2FnYS9lZmZlY3RzXCIpO1xuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIGV4dGVybmFsIFwicmVkdXgtc2FnYS9lZmZlY3RzXCJcbi8vIG1vZHVsZSBpZCA9IDg4XG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsImNvbnN0IHsgc2VuZEdBU2VydmVFdmVudCB9ID0gcmVxdWlyZSgnaGVscGVycy9nb29nbGVBbmFseXRpY3MnKTtcbmNvbnN0IHtcbiAgZGV0ZXJtaW5lUmVzcG9uc2VUeXBlLFxuICBmbGlwQ2xhaW1OYW1lQW5kSWRGb3JCYWNrd2FyZHNDb21wYXRpYmlsaXR5LFxuICBsb2dSZXF1ZXN0RGF0YSxcbiAgZ2V0Q2xhaW1JZEFuZFNlcnZlQXNzZXQsXG59ID0gcmVxdWlyZSgnaGVscGVycy9zZXJ2ZUhlbHBlcnMuanMnKTtcbmNvbnN0IGxicnlVcmkgPSByZXF1aXJlKCdoZWxwZXJzL2xicnlVcmkuanMnKTtcbmNvbnN0IGhhbmRsZVNob3dSZW5kZXIgPSByZXF1aXJlKCdoZWxwZXJzL2hhbmRsZVNob3dSZW5kZXIuanN4Jyk7XG5cbmNvbnN0IFNFUlZFID0gJ1NFUlZFJztcblxuLypcblxuICByb3V0ZSB0byBzZXJ2ZSBhbiBhc3NldCBvciB0aGUgcmVhY3QgYXBwIHZpYSB0aGUgY2xhaW0gbmFtZSBhbmQgYW4gaWRlbnRpZmllclxuXG4qL1xuXG5jb25zdCBzZXJ2ZXJBc3NldEJ5SWRlbnRpZmllckFuZENsYWltID0gKHJlcSwgcmVzKSA9PiB7XG4gIGNvbnN0IHsgaGVhZGVycywgaXAsIG9yaWdpbmFsVXJsLCBwYXJhbXMgfSA9IHJlcTtcbiAgLy8gZGVjaWRlIGlmIHRoaXMgaXMgYSBzaG93IHJlcXVlc3RcbiAgbGV0IGhhc0ZpbGVFeHRlbnNpb247XG4gIHRyeSB7XG4gICAgKHsgaGFzRmlsZUV4dGVuc2lvbiB9ID0gbGJyeVVyaS5wYXJzZU1vZGlmaWVyKHBhcmFtcy5jbGFpbSkpO1xuICB9IGNhdGNoIChlcnJvcikge1xuICAgIHJldHVybiByZXMuc3RhdHVzKDQwMCkuanNvbih7c3VjY2VzczogZmFsc2UsIG1lc3NhZ2U6IGVycm9yLm1lc3NhZ2V9KTtcbiAgfVxuICBsZXQgcmVzcG9uc2VUeXBlID0gZGV0ZXJtaW5lUmVzcG9uc2VUeXBlKGhhc0ZpbGVFeHRlbnNpb24sIGhlYWRlcnMpO1xuICBpZiAocmVzcG9uc2VUeXBlICE9PSBTRVJWRSkge1xuICAgIHJldHVybiBoYW5kbGVTaG93UmVuZGVyKHJlcSwgcmVzKTtcbiAgfVxuICAvLyBoYW5kbGUgc2VydmUgcmVxdWVzdFxuICAvLyBzZW5kIGdvb2dsZSBhbmFseXRpY3NcbiAgc2VuZEdBU2VydmVFdmVudChoZWFkZXJzLCBpcCwgb3JpZ2luYWxVcmwpO1xuICAvLyBwYXJzZSB0aGUgY2xhaW1cbiAgbGV0IGNsYWltTmFtZTtcbiAgdHJ5IHtcbiAgICAoeyBjbGFpbU5hbWUgfSA9IGxicnlVcmkucGFyc2VDbGFpbShwYXJhbXMuY2xhaW0pKTtcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICByZXR1cm4gcmVzLnN0YXR1cyg0MDApLmpzb24oe3N1Y2Nlc3M6IGZhbHNlLCBtZXNzYWdlOiBlcnJvci5tZXNzYWdlfSk7XG4gIH1cbiAgLy8gcGFyc2UgdGhlIGlkZW50aWZpZXJcbiAgbGV0IGlzQ2hhbm5lbCwgY2hhbm5lbE5hbWUsIGNoYW5uZWxDbGFpbUlkLCBjbGFpbUlkO1xuICB0cnkge1xuICAgICh7IGlzQ2hhbm5lbCwgY2hhbm5lbE5hbWUsIGNoYW5uZWxDbGFpbUlkLCBjbGFpbUlkIH0gPSBsYnJ5VXJpLnBhcnNlSWRlbnRpZmllcihwYXJhbXMuaWRlbnRpZmllcikpO1xuICB9IGNhdGNoIChlcnJvcikge1xuICAgIHJldHVybiByZXMuc3RhdHVzKDQwMCkuanNvbih7c3VjY2VzczogZmFsc2UsIG1lc3NhZ2U6IGVycm9yLm1lc3NhZ2V9KTtcbiAgfVxuICBpZiAoIWlzQ2hhbm5lbCkge1xuICAgIFtjbGFpbUlkLCBjbGFpbU5hbWVdID0gZmxpcENsYWltTmFtZUFuZElkRm9yQmFja3dhcmRzQ29tcGF0aWJpbGl0eShjbGFpbUlkLCBjbGFpbU5hbWUpO1xuICB9XG4gIC8vIGxvZyB0aGUgcmVxdWVzdCBkYXRhIGZvciBkZWJ1Z2dpbmdcbiAgbG9nUmVxdWVzdERhdGEocmVzcG9uc2VUeXBlLCBjbGFpbU5hbWUsIGNoYW5uZWxOYW1lLCBjbGFpbUlkKTtcbiAgLy8gZ2V0IHRoZSBjbGFpbSBJZCBhbmQgdGhlbiBzZXJ2ZSB0aGUgYXNzZXRcbiAgZ2V0Q2xhaW1JZEFuZFNlcnZlQXNzZXQoY2hhbm5lbE5hbWUsIGNoYW5uZWxDbGFpbUlkLCBjbGFpbU5hbWUsIGNsYWltSWQsIG9yaWdpbmFsVXJsLCBpcCwgcmVzKTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gc2VydmVyQXNzZXRCeUlkZW50aWZpZXJBbmRDbGFpbTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL3NlcnZlci9yb3V0ZXMvYXNzZXRzL3NlcnZlQXNzZXRCeUlkZW50aWZpZXJBbmRDbGFpbS5qcyIsImNvbnN0IGhhbmRsZVBhZ2VSZXF1ZXN0ID0gcmVxdWlyZSgnLi9zZW5kUmVhY3RBcHAnKTtcblxubW9kdWxlLmV4cG9ydHMgPSAoYXBwKSA9PiB7XG4gIGFwcC5nZXQoJyonLCBoYW5kbGVQYWdlUmVxdWVzdCk7XG59O1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vc2VydmVyL3JvdXRlcy9mYWxsYmFjay9pbmRleC5qcyIsImNvbnN0IGhhbmRsZVBhZ2VSZW5kZXIgPSByZXF1aXJlKCdoZWxwZXJzL2hhbmRsZVBhZ2VSZW5kZXIuanN4Jyk7XG5cbmNvbnN0IHNlbmRSZWFjdEFwcCA9IChyZXEsIHJlcykgPT4ge1xuICBoYW5kbGVQYWdlUmVuZGVyKHJlcSwgcmVzKTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gc2VuZFJlYWN0QXBwO1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vc2VydmVyL3JvdXRlcy9mYWxsYmFjay9zZW5kUmVhY3RBcHAuanMiXSwic291cmNlUm9vdCI6IiJ9