11849 lines
No EOL
934 KiB
JavaScript
11849 lines
No EOL
934 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 = 49);
|
|
/******/ })
|
|
/************************************************************************/
|
|
/******/ ([
|
|
/* 0 */
|
|
/***/ (function(module, exports) {
|
|
|
|
module.exports = require("react");
|
|
|
|
/***/ }),
|
|
/* 1 */
|
|
/***/ (function(module, exports) {
|
|
|
|
module.exports = require("react-redux");
|
|
|
|
/***/ }),
|
|
/* 2 */
|
|
/***/ (function(module, exports) {
|
|
|
|
module.exports = require("winston");
|
|
|
|
/***/ }),
|
|
/* 3 */
|
|
/***/ (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__(2);
|
|
|
|
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
|
|
};
|
|
}
|
|
};
|
|
|
|
/***/ }),
|
|
/* 4 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
exports.selectFile = selectFile;
|
|
exports.clearFile = clearFile;
|
|
exports.updateMetadata = updateMetadata;
|
|
exports.updateClaim = updateClaim;
|
|
exports.setPublishInChannel = setPublishInChannel;
|
|
exports.updatePublishStatus = updatePublishStatus;
|
|
exports.updateError = updateError;
|
|
exports.updateSelectedChannel = updateSelectedChannel;
|
|
exports.toggleMetadataInputs = toggleMetadataInputs;
|
|
exports.onNewThumbnail = onNewThumbnail;
|
|
exports.startPublish = startPublish;
|
|
|
|
var _publish_action_types = __webpack_require__(22);
|
|
|
|
var actions = _interopRequireWildcard(_publish_action_types);
|
|
|
|
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
|
|
|
|
// export action creators
|
|
function selectFile(file) {
|
|
return {
|
|
type: actions.FILE_SELECTED,
|
|
data: file
|
|
};
|
|
};
|
|
|
|
function clearFile() {
|
|
return {
|
|
type: actions.FILE_CLEAR
|
|
};
|
|
};
|
|
|
|
function updateMetadata(name, value) {
|
|
return {
|
|
type: actions.METADATA_UPDATE,
|
|
data: {
|
|
name: name,
|
|
value: value
|
|
}
|
|
};
|
|
};
|
|
|
|
function updateClaim(value) {
|
|
return {
|
|
type: actions.CLAIM_UPDATE,
|
|
data: value
|
|
};
|
|
};
|
|
|
|
function setPublishInChannel(channel) {
|
|
return {
|
|
type: actions.SET_PUBLISH_IN_CHANNEL,
|
|
channel: channel
|
|
};
|
|
};
|
|
|
|
function updatePublishStatus(status, message) {
|
|
return {
|
|
type: actions.PUBLISH_STATUS_UPDATE,
|
|
data: {
|
|
status: status,
|
|
message: message
|
|
}
|
|
};
|
|
};
|
|
|
|
function updateError(name, value) {
|
|
return {
|
|
type: actions.ERROR_UPDATE,
|
|
data: {
|
|
name: name,
|
|
value: value
|
|
}
|
|
};
|
|
};
|
|
|
|
function updateSelectedChannel(channelName) {
|
|
return {
|
|
type: actions.SELECTED_CHANNEL_UPDATE,
|
|
data: channelName
|
|
};
|
|
};
|
|
|
|
function toggleMetadataInputs(showMetadataInputs) {
|
|
return {
|
|
type: actions.TOGGLE_METADATA_INPUTS,
|
|
data: showMetadataInputs
|
|
};
|
|
};
|
|
|
|
function onNewThumbnail(file) {
|
|
return {
|
|
type: actions.THUMBNAIL_NEW,
|
|
data: file
|
|
};
|
|
};
|
|
|
|
function startPublish(history) {
|
|
return {
|
|
type: actions.PUBLISH_START,
|
|
data: { history: history }
|
|
};
|
|
}
|
|
|
|
/***/ }),
|
|
/* 5 */
|
|
/***/ (function(module, exports) {
|
|
|
|
module.exports = require("react-router-dom");
|
|
|
|
/***/ }),
|
|
/* 6 */
|
|
/***/ (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 = {
|
|
components: {},
|
|
containers: {},
|
|
pages: {}
|
|
};
|
|
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.configure = function (config) {
|
|
if (!config) {
|
|
return console.log('No site config received.');
|
|
}
|
|
var analytics = config.analytics,
|
|
assetDefaults = config.assetDefaults,
|
|
auth = config.auth,
|
|
customComponents = config.customComponents,
|
|
details = config.details,
|
|
publishing = config.publishing;
|
|
|
|
_this.analytics = analytics;
|
|
_this.assetDefaults = assetDefaults;
|
|
_this.auth = auth;
|
|
_this.details = details;
|
|
_this.publishing = publishing;
|
|
_this.customComponents = customComponents;
|
|
};
|
|
};
|
|
|
|
module.exports = new SiteConfig();
|
|
|
|
/***/ }),
|
|
/* 7 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
exports.onHandleShowPageUri = onHandleShowPageUri;
|
|
exports.onRequestError = onRequestError;
|
|
exports.onNewChannelRequest = onNewChannelRequest;
|
|
exports.onNewAssetRequest = onNewAssetRequest;
|
|
exports.onRequestUpdate = onRequestUpdate;
|
|
exports.addRequestToRequestList = addRequestToRequestList;
|
|
exports.addAssetToAssetList = addAssetToAssetList;
|
|
exports.addNewChannelToChannelList = addNewChannelToChannelList;
|
|
exports.onUpdateChannelClaims = onUpdateChannelClaims;
|
|
exports.updateChannelClaims = updateChannelClaims;
|
|
exports.fileRequested = fileRequested;
|
|
exports.updateFileAvailability = updateFileAvailability;
|
|
exports.updateDisplayAssetError = updateDisplayAssetError;
|
|
|
|
var _show_action_types = __webpack_require__(13);
|
|
|
|
var actions = _interopRequireWildcard(_show_action_types);
|
|
|
|
var _show_request_types = __webpack_require__(35);
|
|
|
|
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
|
|
|
|
// basic request parsing
|
|
function onHandleShowPageUri(params) {
|
|
return {
|
|
type: actions.HANDLE_SHOW_URI,
|
|
data: params
|
|
};
|
|
};
|
|
|
|
function onRequestError(error) {
|
|
return {
|
|
type: actions.REQUEST_ERROR,
|
|
data: error
|
|
};
|
|
};
|
|
|
|
function onNewChannelRequest(channelName, channelId) {
|
|
var requestType = _show_request_types.CHANNEL;
|
|
var requestId = 'cr#' + channelName + '#' + channelId;
|
|
return {
|
|
type: actions.CHANNEL_REQUEST_NEW,
|
|
data: { requestType: requestType, requestId: requestId, channelName: channelName, channelId: channelId }
|
|
};
|
|
};
|
|
|
|
function onNewAssetRequest(name, id, channelName, channelId, extension) {
|
|
var requestType = extension ? _show_request_types.ASSET_LITE : _show_request_types.ASSET_DETAILS;
|
|
var requestId = 'ar#' + name + '#' + id + '#' + channelName + '#' + channelId;
|
|
return {
|
|
type: actions.ASSET_REQUEST_NEW,
|
|
data: {
|
|
requestType: requestType,
|
|
requestId: requestId,
|
|
name: name,
|
|
modifier: {
|
|
id: id,
|
|
channel: {
|
|
name: channelName,
|
|
id: channelId
|
|
}
|
|
}
|
|
}
|
|
};
|
|
};
|
|
|
|
function onRequestUpdate(requestType, requestId) {
|
|
return {
|
|
type: actions.REQUEST_UPDATE,
|
|
data: {
|
|
requestType: requestType,
|
|
requestId: requestId
|
|
}
|
|
};
|
|
};
|
|
|
|
function addRequestToRequestList(id, error, key) {
|
|
return {
|
|
type: actions.REQUEST_LIST_ADD,
|
|
data: { id: id, error: error, key: key }
|
|
};
|
|
};
|
|
|
|
// asset actions
|
|
|
|
function addAssetToAssetList(id, error, name, claimId, shortId, claimData) {
|
|
return {
|
|
type: actions.ASSET_ADD,
|
|
data: { id: id, error: error, name: name, claimId: claimId, shortId: shortId, claimData: claimData }
|
|
};
|
|
}
|
|
|
|
// channel actions
|
|
|
|
function addNewChannelToChannelList(id, name, shortId, longId, claimsData) {
|
|
return {
|
|
type: actions.CHANNEL_ADD,
|
|
data: { id: id, name: name, shortId: shortId, longId: longId, claimsData: claimsData }
|
|
};
|
|
};
|
|
|
|
function onUpdateChannelClaims(channelKey, name, longId, page) {
|
|
return {
|
|
type: actions.CHANNEL_CLAIMS_UPDATE_ASYNC,
|
|
data: { channelKey: channelKey, name: name, longId: longId, page: page }
|
|
};
|
|
};
|
|
|
|
function updateChannelClaims(channelListId, claimsData) {
|
|
return {
|
|
type: actions.CHANNEL_CLAIMS_UPDATE_SUCCESS,
|
|
data: { channelListId: channelListId, claimsData: claimsData }
|
|
};
|
|
};
|
|
|
|
// display a file
|
|
|
|
function fileRequested(name, claimId) {
|
|
return {
|
|
type: actions.FILE_REQUESTED,
|
|
data: { name: name, claimId: claimId }
|
|
};
|
|
};
|
|
|
|
function updateFileAvailability(status) {
|
|
return {
|
|
type: actions.FILE_AVAILABILITY_UPDATE,
|
|
data: status
|
|
};
|
|
};
|
|
|
|
function updateDisplayAssetError(error) {
|
|
return {
|
|
type: actions.DISPLAY_ASSET_ERROR,
|
|
data: error
|
|
};
|
|
};
|
|
|
|
/***/ }),
|
|
/* 8 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
|
|
var _reactRedux = __webpack_require__(1);
|
|
|
|
var _channel = __webpack_require__(21);
|
|
|
|
var _publish = __webpack_require__(4);
|
|
|
|
var _view = __webpack_require__(58);
|
|
|
|
var _view2 = _interopRequireDefault(_view);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
var mapStateToProps = function mapStateToProps(_ref) {
|
|
var channel = _ref.channel,
|
|
site = _ref.site;
|
|
|
|
return {
|
|
channelName: channel.loggedInChannel.name,
|
|
channelShortId: channel.loggedInChannel.shortId,
|
|
channelLongId: channel.loggedInChannel.longId,
|
|
siteDescription: site.description
|
|
};
|
|
};
|
|
|
|
var mapDispatchToProps = function mapDispatchToProps(dispatch) {
|
|
return {
|
|
onChannelLogin: function onChannelLogin(name, shortId, longId) {
|
|
dispatch((0, _channel.updateLoggedInChannel)(name, shortId, longId));
|
|
dispatch((0, _publish.updateSelectedChannel)(name));
|
|
},
|
|
onChannelLogout: function onChannelLogout() {
|
|
dispatch((0, _channel.updateLoggedInChannel)(null, null, null));
|
|
}
|
|
};
|
|
};
|
|
|
|
exports.default = (0, _reactRedux.connect)(mapStateToProps, mapDispatchToProps)(_view2.default);
|
|
|
|
/***/ }),
|
|
/* 9 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
|
|
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"); } }; }();
|
|
|
|
exports.default = request;
|
|
|
|
__webpack_require__(61);
|
|
|
|
/**
|
|
* Parses the JSON returned by a network request
|
|
*
|
|
* @param {object} response A response from a network request
|
|
*
|
|
* @return {object} The parsed JSON from the request
|
|
*/
|
|
function parseJSON(response) {
|
|
if (response.status === 204 || response.status === 205) {
|
|
return null;
|
|
}
|
|
return response.json();
|
|
}
|
|
|
|
/**
|
|
* Parses the status returned by a network request
|
|
*
|
|
* @param {object} response A response from a network request
|
|
* @param {object} response The parsed JSON from the network request
|
|
*
|
|
* @return {object | undefined} Returns object with status and statusText, or undefined
|
|
*/
|
|
function checkStatus(response, jsonResponse) {
|
|
if (response.status >= 200 && response.status < 300) {
|
|
return jsonResponse;
|
|
}
|
|
var error = new Error(jsonResponse.message);
|
|
error.response = response;
|
|
throw error;
|
|
}
|
|
|
|
/**
|
|
* Requests a URL, returning a promise
|
|
*
|
|
* @param {string} url The URL we want to request
|
|
* @param {object} [options] The options we want to pass to "fetch"
|
|
*
|
|
* @return {object} The response data
|
|
*/
|
|
|
|
function request(url, options) {
|
|
return fetch(url, options).then(function (response) {
|
|
return Promise.all([response, parseJSON(response)]);
|
|
}).then(function (_ref) {
|
|
var _ref2 = _slicedToArray(_ref, 2),
|
|
response = _ref2[0],
|
|
jsonResponse = _ref2[1];
|
|
|
|
return checkStatus(response, jsonResponse);
|
|
});
|
|
}
|
|
|
|
/***/ }),
|
|
/* 10 */
|
|
/***/ (function(module, exports) {
|
|
|
|
module.exports = require("redux-saga/effects");
|
|
|
|
/***/ }),
|
|
/* 11 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
|
|
var _reactRedux = __webpack_require__(1);
|
|
|
|
var _view = __webpack_require__(54);
|
|
|
|
var _view2 = _interopRequireDefault(_view);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
var mapStateToProps = function mapStateToProps(_ref) {
|
|
var site = _ref.site;
|
|
var defaultDescription = site.defaultDescription,
|
|
defaultThumbnail = site.defaultThumbnail,
|
|
siteDescription = site.description,
|
|
siteHost = site.host,
|
|
siteTitle = site.title,
|
|
siteTwitter = site.twitter;
|
|
|
|
return {
|
|
defaultDescription: defaultDescription,
|
|
defaultThumbnail: defaultThumbnail,
|
|
siteDescription: siteDescription,
|
|
siteHost: siteHost,
|
|
siteTitle: siteTitle,
|
|
siteTwitter: siteTwitter
|
|
};
|
|
};
|
|
|
|
exports.default = (0, _reactRedux.connect)(mapStateToProps, null)(_view2.default);
|
|
|
|
/***/ }),
|
|
/* 12 */
|
|
/***/ (function(module, exports) {
|
|
|
|
module.exports = require("prop-types");
|
|
|
|
/***/ }),
|
|
/* 13 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
// request actions
|
|
var HANDLE_SHOW_URI = exports.HANDLE_SHOW_URI = 'HANDLE_SHOW_URI';
|
|
var REQUEST_ERROR = exports.REQUEST_ERROR = 'REQUEST_ERROR';
|
|
var REQUEST_UPDATE = exports.REQUEST_UPDATE = 'REQUEST_UPDATE';
|
|
var ASSET_REQUEST_NEW = exports.ASSET_REQUEST_NEW = 'ASSET_REQUEST_NEW';
|
|
var CHANNEL_REQUEST_NEW = exports.CHANNEL_REQUEST_NEW = 'CHANNEL_REQUEST_NEW';
|
|
var REQUEST_LIST_ADD = exports.REQUEST_LIST_ADD = 'REQUEST_LIST_ADD';
|
|
|
|
// asset actions
|
|
var ASSET_ADD = exports.ASSET_ADD = 'ASSET_ADD';
|
|
|
|
// channel actions
|
|
var CHANNEL_ADD = exports.CHANNEL_ADD = 'CHANNEL_ADD';
|
|
|
|
var CHANNEL_CLAIMS_UPDATE_ASYNC = exports.CHANNEL_CLAIMS_UPDATE_ASYNC = 'CHANNEL_CLAIMS_UPDATE_ASYNC';
|
|
var CHANNEL_CLAIMS_UPDATE_SUCCESS = exports.CHANNEL_CLAIMS_UPDATE_SUCCESS = 'CHANNEL_CLAIMS_UPDATE_SUCCESS';
|
|
|
|
// asset/file display actions
|
|
var FILE_REQUESTED = exports.FILE_REQUESTED = 'FILE_REQUESTED';
|
|
var FILE_AVAILABILITY_UPDATE = exports.FILE_AVAILABILITY_UPDATE = 'FILE_AVAILABILITY_UPDATE';
|
|
var DISPLAY_ASSET_ERROR = exports.DISPLAY_ASSET_ERROR = 'DISPLAY_ASSET_ERROR';
|
|
|
|
/***/ }),
|
|
/* 14 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
function mysql() {
|
|
var _this = this;
|
|
|
|
this.db = {};
|
|
this.configure = function (db) {
|
|
if (!db) {
|
|
return console.log('No MySQL config received.');
|
|
}
|
|
// configure credentials
|
|
console.log('configuring mysql...');
|
|
_this.db = db;
|
|
};
|
|
};
|
|
|
|
module.exports = new mysql();
|
|
|
|
/***/ }),
|
|
/* 15 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
var logger = __webpack_require__(2);
|
|
var ua = __webpack_require__(132);
|
|
|
|
var _require = __webpack_require__(6),
|
|
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';
|
|
}
|
|
};
|
|
|
|
/***/ }),
|
|
/* 16 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
var selectAsset = exports.selectAsset = function selectAsset(show) {
|
|
var request = show.requestList[show.request.id];
|
|
var assetKey = request.key;
|
|
return show.assetList[assetKey];
|
|
};
|
|
|
|
var selectShowState = exports.selectShowState = function selectShowState(state) {
|
|
return state.show;
|
|
};
|
|
|
|
/***/ }),
|
|
/* 17 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
var selectSiteState = exports.selectSiteState = function selectSiteState(state) {
|
|
return state.site;
|
|
};
|
|
|
|
var selectSiteHost = exports.selectSiteHost = function selectSiteHost(state) {
|
|
return state.site.host;
|
|
};
|
|
|
|
/***/ }),
|
|
/* 18 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
var axios = __webpack_require__(130);
|
|
var logger = __webpack_require__(2);
|
|
|
|
var _require = __webpack_require__(131),
|
|
_require$api = _require.api,
|
|
apiHost = _require$api.apiHost,
|
|
apiPort = _require$api.apiPort;
|
|
|
|
var lbryApiUri = 'http://' + apiHost + ':' + apiPort;
|
|
|
|
var _require2 = __webpack_require__(15),
|
|
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);
|
|
});
|
|
});
|
|
}
|
|
};
|
|
|
|
/***/ }),
|
|
/* 19 */
|
|
/***/ (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__(14),
|
|
db = _require.db;
|
|
|
|
var logger = __webpack_require__(2);
|
|
|
|
var _require2 = __webpack_require__(136),
|
|
returnPaginatedChannelClaims = _require2.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;
|
|
});
|
|
}
|
|
};
|
|
|
|
/***/ }),
|
|
/* 20 */
|
|
/***/ (function(module, exports) {
|
|
|
|
module.exports = require("react-helmet");
|
|
|
|
/***/ }),
|
|
/* 21 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
exports.updateLoggedInChannel = updateLoggedInChannel;
|
|
|
|
var _channel_action_types = __webpack_require__(29);
|
|
|
|
var actions = _interopRequireWildcard(_channel_action_types);
|
|
|
|
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
|
|
|
|
// export action creators
|
|
|
|
function updateLoggedInChannel(name, shortId, longId) {
|
|
return {
|
|
type: actions.CHANNEL_UPDATE,
|
|
data: {
|
|
name: name,
|
|
shortId: shortId,
|
|
longId: longId
|
|
}
|
|
};
|
|
};
|
|
|
|
/***/ }),
|
|
/* 22 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
var FILE_SELECTED = exports.FILE_SELECTED = 'FILE_SELECTED';
|
|
var FILE_CLEAR = exports.FILE_CLEAR = 'FILE_CLEAR';
|
|
var METADATA_UPDATE = exports.METADATA_UPDATE = 'METADATA_UPDATE';
|
|
var CLAIM_UPDATE = exports.CLAIM_UPDATE = 'CLAIM_UPDATE';
|
|
var SET_PUBLISH_IN_CHANNEL = exports.SET_PUBLISH_IN_CHANNEL = 'SET_PUBLISH_IN_CHANNEL';
|
|
var PUBLISH_STATUS_UPDATE = exports.PUBLISH_STATUS_UPDATE = 'PUBLISH_STATUS_UPDATE';
|
|
var ERROR_UPDATE = exports.ERROR_UPDATE = 'ERROR_UPDATE';
|
|
var SELECTED_CHANNEL_UPDATE = exports.SELECTED_CHANNEL_UPDATE = 'SELECTED_CHANNEL_UPDATE';
|
|
var TOGGLE_METADATA_INPUTS = exports.TOGGLE_METADATA_INPUTS = 'TOGGLE_METADATA_INPUTS';
|
|
var THUMBNAIL_NEW = exports.THUMBNAIL_NEW = 'THUMBNAIL_NEW';
|
|
var PUBLISH_START = exports.PUBLISH_START = 'PUBLISH_START';
|
|
|
|
/***/ }),
|
|
/* 23 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
|
|
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
|
|
|
var _react = __webpack_require__(0);
|
|
|
|
var _react2 = _interopRequireDefault(_react);
|
|
|
|
var _propTypes = __webpack_require__(12);
|
|
|
|
var _propTypes2 = _interopRequireDefault(_propTypes);
|
|
|
|
var _ActiveStatusBar = __webpack_require__(83);
|
|
|
|
var _ActiveStatusBar2 = _interopRequireDefault(_ActiveStatusBar);
|
|
|
|
var _InactiveStatusBar = __webpack_require__(84);
|
|
|
|
var _InactiveStatusBar2 = _interopRequireDefault(_InactiveStatusBar);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
|
|
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
|
|
|
|
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
|
|
|
|
var ProgressBar = function (_React$Component) {
|
|
_inherits(ProgressBar, _React$Component);
|
|
|
|
function ProgressBar(props) {
|
|
_classCallCheck(this, ProgressBar);
|
|
|
|
var _this = _possibleConstructorReturn(this, (ProgressBar.__proto__ || Object.getPrototypeOf(ProgressBar)).call(this, props));
|
|
|
|
_this.state = {
|
|
bars: [],
|
|
index: 0,
|
|
incrementer: 1
|
|
};
|
|
_this.createBars = _this.createBars.bind(_this);
|
|
_this.startProgressBar = _this.startProgressBar.bind(_this);
|
|
_this.updateProgressBar = _this.updateProgressBar.bind(_this);
|
|
_this.stopProgressBar = _this.stopProgressBar.bind(_this);
|
|
return _this;
|
|
}
|
|
|
|
_createClass(ProgressBar, [{
|
|
key: 'componentDidMount',
|
|
value: function componentDidMount() {
|
|
this.createBars();
|
|
this.startProgressBar();
|
|
}
|
|
}, {
|
|
key: 'componentWillUnmount',
|
|
value: function componentWillUnmount() {
|
|
this.stopProgressBar();
|
|
}
|
|
}, {
|
|
key: 'createBars',
|
|
value: function createBars() {
|
|
var bars = [];
|
|
for (var i = 0; i <= this.props.size; i++) {
|
|
bars.push({ isActive: false });
|
|
}
|
|
this.setState({ bars: bars });
|
|
}
|
|
}, {
|
|
key: 'startProgressBar',
|
|
value: function startProgressBar() {
|
|
this.updateInterval = setInterval(this.updateProgressBar.bind(this), 300);
|
|
}
|
|
}, {
|
|
key: 'updateProgressBar',
|
|
value: function updateProgressBar() {
|
|
var index = this.state.index;
|
|
var incrementer = this.state.incrementer;
|
|
var bars = this.state.bars;
|
|
// flip incrementer if necessary, to stay in bounds
|
|
if (index < 0 || index > this.props.size) {
|
|
incrementer = incrementer * -1;
|
|
index += incrementer;
|
|
}
|
|
// update the indexed bar
|
|
if (incrementer > 0) {
|
|
bars[index].isActive = true;
|
|
} else {
|
|
bars[index].isActive = false;
|
|
};
|
|
// increment index
|
|
index += incrementer;
|
|
// update state
|
|
this.setState({
|
|
bars: bars,
|
|
incrementer: incrementer,
|
|
index: index
|
|
});
|
|
}
|
|
}, {
|
|
key: 'stopProgressBar',
|
|
value: function stopProgressBar() {
|
|
clearInterval(this.updateInterval);
|
|
}
|
|
}, {
|
|
key: 'render',
|
|
value: function render() {
|
|
return _react2.default.createElement(
|
|
'div',
|
|
null,
|
|
this.state.bars.map(function (bar, index) {
|
|
return bar.isActive ? _react2.default.createElement(_ActiveStatusBar2.default, { key: index }) : _react2.default.createElement(_InactiveStatusBar2.default, { key: index });
|
|
})
|
|
);
|
|
}
|
|
}]);
|
|
|
|
return ProgressBar;
|
|
}(_react2.default.Component);
|
|
|
|
;
|
|
|
|
ProgressBar.propTypes = {
|
|
size: _propTypes2.default.number.isRequired
|
|
};
|
|
|
|
exports.default = ProgressBar;
|
|
|
|
/***/ }),
|
|
/* 24 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
|
|
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
|
|
|
var _react = __webpack_require__(0);
|
|
|
|
var _react2 = _interopRequireDefault(_react);
|
|
|
|
var _propTypes = __webpack_require__(12);
|
|
|
|
var _propTypes2 = _interopRequireDefault(_propTypes);
|
|
|
|
var _NavBar = __webpack_require__(8);
|
|
|
|
var _NavBar2 = _interopRequireDefault(_NavBar);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
|
|
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
|
|
|
|
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
|
|
|
|
var ErrorPage = function (_React$Component) {
|
|
_inherits(ErrorPage, _React$Component);
|
|
|
|
function ErrorPage() {
|
|
_classCallCheck(this, ErrorPage);
|
|
|
|
return _possibleConstructorReturn(this, (ErrorPage.__proto__ || Object.getPrototypeOf(ErrorPage)).apply(this, arguments));
|
|
}
|
|
|
|
_createClass(ErrorPage, [{
|
|
key: 'render',
|
|
value: function render() {
|
|
var error = this.props.error;
|
|
|
|
return _react2.default.createElement(
|
|
'div',
|
|
null,
|
|
_react2.default.createElement(_NavBar2.default, null),
|
|
_react2.default.createElement(
|
|
'div',
|
|
{ className: 'row row--padded' },
|
|
_react2.default.createElement(
|
|
'p',
|
|
null,
|
|
error
|
|
)
|
|
)
|
|
);
|
|
}
|
|
}]);
|
|
|
|
return ErrorPage;
|
|
}(_react2.default.Component);
|
|
|
|
;
|
|
|
|
ErrorPage.propTypes = {
|
|
error: _propTypes2.default.string.isRequired
|
|
};
|
|
|
|
exports.default = ErrorPage;
|
|
|
|
/***/ }),
|
|
/* 25 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
var LOCAL_CHECK = exports.LOCAL_CHECK = 'LOCAL_CHECK';
|
|
var UNAVAILABLE = exports.UNAVAILABLE = 'UNAVAILABLE';
|
|
var ERROR = exports.ERROR = 'ERROR';
|
|
var AVAILABLE = exports.AVAILABLE = 'AVAILABLE';
|
|
|
|
/***/ }),
|
|
/* 26 */
|
|
/***/ (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__(2);
|
|
|
|
var _require = __webpack_require__(14),
|
|
db = _require.db;
|
|
|
|
var lbryApi = __webpack_require__(18);
|
|
var publishHelpers = __webpack_require__(27);
|
|
|
|
var _require2 = __webpack_require__(6),
|
|
_require2$publishing = _require2.publishing,
|
|
primaryClaimAddress = _require2$publishing.primaryClaimAddress,
|
|
additionalClaimAddresses = _require2$publishing.additionalClaimAddresses;
|
|
|
|
var Sequelize = __webpack_require__(134);
|
|
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;
|
|
});
|
|
}
|
|
};
|
|
|
|
/***/ }),
|
|
/* 27 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
var logger = __webpack_require__(2);
|
|
var fs = __webpack_require__(133);
|
|
|
|
var _require = __webpack_require__(6),
|
|
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
|
|
};
|
|
}
|
|
};
|
|
|
|
/***/ }),
|
|
/* 28 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
|
|
var _react = __webpack_require__(0);
|
|
|
|
var _react2 = _interopRequireDefault(_react);
|
|
|
|
var _reactRouterDom = __webpack_require__(5);
|
|
|
|
var _HomePage = __webpack_require__(53);
|
|
|
|
var _HomePage2 = _interopRequireDefault(_HomePage);
|
|
|
|
var _AboutPage = __webpack_require__(89);
|
|
|
|
var _AboutPage2 = _interopRequireDefault(_AboutPage);
|
|
|
|
var _LoginPage = __webpack_require__(90);
|
|
|
|
var _LoginPage2 = _interopRequireDefault(_LoginPage);
|
|
|
|
var _ShowPage = __webpack_require__(92);
|
|
|
|
var _ShowPage2 = _interopRequireDefault(_ShowPage);
|
|
|
|
var _FourOhFourPage = __webpack_require__(109);
|
|
|
|
var _FourOhFourPage2 = _interopRequireDefault(_FourOhFourPage);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
// import { dynamicImport } from 'utils/dynamicImport';
|
|
// const HomePage = dynamicImport('pages/HomePage'); // or use the provided local homepage
|
|
|
|
var App = function App() {
|
|
return _react2.default.createElement(
|
|
_reactRouterDom.Switch,
|
|
null,
|
|
_react2.default.createElement(_reactRouterDom.Route, { exact: true, path: '/', component: _HomePage2.default }),
|
|
_react2.default.createElement(_reactRouterDom.Route, { exact: true, path: '/about', component: _AboutPage2.default }),
|
|
_react2.default.createElement(_reactRouterDom.Route, { exact: true, path: '/login', component: _LoginPage2.default }),
|
|
_react2.default.createElement(_reactRouterDom.Route, { exact: true, path: '/:identifier/:claim', component: _ShowPage2.default }),
|
|
_react2.default.createElement(_reactRouterDom.Route, { exact: true, path: '/:claim', component: _ShowPage2.default }),
|
|
_react2.default.createElement(_reactRouterDom.Route, { component: _FourOhFourPage2.default })
|
|
);
|
|
};
|
|
|
|
exports.default = App;
|
|
|
|
/***/ }),
|
|
/* 29 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
var CHANNEL_UPDATE = exports.CHANNEL_UPDATE = 'CHANNEL_UPDATE';
|
|
|
|
/***/ }),
|
|
/* 30 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
|
|
var _reactRedux = __webpack_require__(1);
|
|
|
|
var _publish = __webpack_require__(4);
|
|
|
|
var _view = __webpack_require__(64);
|
|
|
|
var _view2 = _interopRequireDefault(_view);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
var mapStateToProps = function mapStateToProps(_ref) {
|
|
var publish = _ref.publish;
|
|
|
|
return {
|
|
file: publish.file,
|
|
thumbnail: publish.thumbnail,
|
|
fileError: publish.error.file
|
|
};
|
|
};
|
|
|
|
var mapDispatchToProps = function mapDispatchToProps(dispatch) {
|
|
return {
|
|
selectFile: function selectFile(file) {
|
|
dispatch((0, _publish.selectFile)(file));
|
|
},
|
|
setFileError: function setFileError(value) {
|
|
dispatch((0, _publish.clearFile)());
|
|
dispatch((0, _publish.updateError)('file', value));
|
|
}
|
|
};
|
|
};
|
|
|
|
exports.default = (0, _reactRedux.connect)(mapStateToProps, mapDispatchToProps)(_view2.default);
|
|
|
|
/***/ }),
|
|
/* 31 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
|
|
var _reactRedux = __webpack_require__(1);
|
|
|
|
var _channel = __webpack_require__(21);
|
|
|
|
var _view = __webpack_require__(81);
|
|
|
|
var _view2 = _interopRequireDefault(_view);
|
|
|
|
var _publish = __webpack_require__(4);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
var mapDispatchToProps = function mapDispatchToProps(dispatch) {
|
|
return {
|
|
onChannelLogin: function onChannelLogin(name, shortId, longId) {
|
|
dispatch((0, _channel.updateLoggedInChannel)(name, shortId, longId));
|
|
dispatch((0, _publish.updateSelectedChannel)(name));
|
|
}
|
|
};
|
|
};
|
|
|
|
exports.default = (0, _reactRedux.connect)(null, mapDispatchToProps)(_view2.default);
|
|
|
|
/***/ }),
|
|
/* 32 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
|
|
var _reactRedux = __webpack_require__(1);
|
|
|
|
var _channel = __webpack_require__(21);
|
|
|
|
var _view = __webpack_require__(82);
|
|
|
|
var _view2 = _interopRequireDefault(_view);
|
|
|
|
var _publish = __webpack_require__(4);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
var mapDispatchToProps = function mapDispatchToProps(dispatch) {
|
|
return {
|
|
onChannelLogin: function onChannelLogin(name, shortId, longId) {
|
|
dispatch((0, _channel.updateLoggedInChannel)(name, shortId, longId));
|
|
dispatch((0, _publish.updateSelectedChannel)(name));
|
|
}
|
|
};
|
|
};
|
|
|
|
exports.default = (0, _reactRedux.connect)(null, mapDispatchToProps)(_view2.default);
|
|
|
|
/***/ }),
|
|
/* 33 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
var LOGIN = exports.LOGIN = 'Existing';
|
|
var CREATE = exports.CREATE = 'New';
|
|
|
|
/***/ }),
|
|
/* 34 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
var LOAD_START = exports.LOAD_START = 'LOAD_START';
|
|
var LOADING = exports.LOADING = 'LOADING';
|
|
var PUBLISHING = exports.PUBLISHING = 'PUBLISHING';
|
|
var SUCCESS = exports.SUCCESS = 'SUCCESS';
|
|
var FAILED = exports.FAILED = 'FAILED';
|
|
|
|
/***/ }),
|
|
/* 35 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
var CHANNEL = exports.CHANNEL = 'CHANNEL';
|
|
var ASSET_LITE = exports.ASSET_LITE = 'ASSET_LITE';
|
|
var ASSET_DETAILS = exports.ASSET_DETAILS = 'ASSET_DETAILS';
|
|
|
|
/***/ }),
|
|
/* 36 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
|
|
var _reactRedux = __webpack_require__(1);
|
|
|
|
var _view = __webpack_require__(96);
|
|
|
|
var _view2 = _interopRequireDefault(_view);
|
|
|
|
var _show = __webpack_require__(7);
|
|
|
|
var _show2 = __webpack_require__(16);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
var mapStateToProps = function mapStateToProps(_ref) {
|
|
var show = _ref.show;
|
|
|
|
// select error and status
|
|
var error = show.displayAsset.error;
|
|
var status = show.displayAsset.status;
|
|
// select asset
|
|
var asset = (0, _show2.selectAsset)(show);
|
|
// return props
|
|
return {
|
|
error: error,
|
|
status: status,
|
|
asset: asset
|
|
};
|
|
};
|
|
|
|
var mapDispatchToProps = function mapDispatchToProps(dispatch) {
|
|
return {
|
|
onFileRequest: function onFileRequest(name, claimId) {
|
|
dispatch((0, _show.fileRequested)(name, claimId));
|
|
}
|
|
};
|
|
};
|
|
|
|
exports.default = (0, _reactRedux.connect)(mapStateToProps, mapDispatchToProps)(_view2.default);
|
|
|
|
/***/ }),
|
|
/* 37 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
|
|
var _redux = __webpack_require__(38);
|
|
|
|
var _publish = __webpack_require__(111);
|
|
|
|
var _publish2 = _interopRequireDefault(_publish);
|
|
|
|
var _channel = __webpack_require__(112);
|
|
|
|
var _channel2 = _interopRequireDefault(_channel);
|
|
|
|
var _show = __webpack_require__(113);
|
|
|
|
var _show2 = _interopRequireDefault(_show);
|
|
|
|
var _site = __webpack_require__(114);
|
|
|
|
var _site2 = _interopRequireDefault(_site);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
exports.default = (0, _redux.combineReducers)({
|
|
channel: _channel2.default,
|
|
publish: _publish2.default,
|
|
show: _show2.default,
|
|
site: _site2.default
|
|
});
|
|
|
|
/***/ }),
|
|
/* 38 */
|
|
/***/ (function(module, exports) {
|
|
|
|
module.exports = require("redux");
|
|
|
|
/***/ }),
|
|
/* 39 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
exports.handleShowPageUri = handleShowPageUri;
|
|
exports.watchHandleShowPageUri = watchHandleShowPageUri;
|
|
|
|
var _effects = __webpack_require__(10);
|
|
|
|
var _show_action_types = __webpack_require__(13);
|
|
|
|
var actions = _interopRequireWildcard(_show_action_types);
|
|
|
|
var _show = __webpack_require__(7);
|
|
|
|
var _show_asset = __webpack_require__(40);
|
|
|
|
var _show_channel = __webpack_require__(41);
|
|
|
|
var _lbryUri = __webpack_require__(118);
|
|
|
|
var _lbryUri2 = _interopRequireDefault(_lbryUri);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
|
|
|
|
var _marked = /*#__PURE__*/regeneratorRuntime.mark(parseAndUpdateIdentifierAndClaim),
|
|
_marked2 = /*#__PURE__*/regeneratorRuntime.mark(parseAndUpdateClaimOnly),
|
|
_marked3 = /*#__PURE__*/regeneratorRuntime.mark(handleShowPageUri),
|
|
_marked4 = /*#__PURE__*/regeneratorRuntime.mark(watchHandleShowPageUri);
|
|
|
|
function parseAndUpdateIdentifierAndClaim(modifier, claim) {
|
|
var isChannel, channelName, channelClaimId, claimId, claimName, extension, _lbryUri$parseIdentif, _lbryUri$parseClaim;
|
|
|
|
return regeneratorRuntime.wrap(function parseAndUpdateIdentifierAndClaim$(_context) {
|
|
while (1) {
|
|
switch (_context.prev = _context.next) {
|
|
case 0:
|
|
// this is a request for an asset
|
|
// claim will be an asset claim
|
|
// the identifier could be a channel or a claim id
|
|
isChannel = void 0, channelName = void 0, channelClaimId = void 0, claimId = void 0, claimName = void 0, extension = void 0;
|
|
_context.prev = 1;
|
|
_lbryUri$parseIdentif = _lbryUri2.default.parseIdentifier(modifier);
|
|
isChannel = _lbryUri$parseIdentif.isChannel;
|
|
channelName = _lbryUri$parseIdentif.channelName;
|
|
channelClaimId = _lbryUri$parseIdentif.channelClaimId;
|
|
claimId = _lbryUri$parseIdentif.claimId;
|
|
_lbryUri$parseClaim = _lbryUri2.default.parseClaim(claim);
|
|
claimName = _lbryUri$parseClaim.claimName;
|
|
extension = _lbryUri$parseClaim.extension;
|
|
_context.next = 17;
|
|
break;
|
|
|
|
case 12:
|
|
_context.prev = 12;
|
|
_context.t0 = _context['catch'](1);
|
|
_context.next = 16;
|
|
return (0, _effects.put)((0, _show.onRequestError)(_context.t0.message));
|
|
|
|
case 16:
|
|
return _context.abrupt('return', _context.sent);
|
|
|
|
case 17:
|
|
if (!isChannel) {
|
|
_context.next = 21;
|
|
break;
|
|
}
|
|
|
|
_context.next = 20;
|
|
return (0, _effects.call)(_show_asset.newAssetRequest, (0, _show.onNewAssetRequest)(claimName, null, channelName, channelClaimId, extension));
|
|
|
|
case 20:
|
|
return _context.abrupt('return', _context.sent);
|
|
|
|
case 21:
|
|
;
|
|
_context.next = 24;
|
|
return (0, _effects.call)(_show_asset.newAssetRequest, (0, _show.onNewAssetRequest)(claimName, claimId, null, null, extension));
|
|
|
|
case 24:
|
|
case 'end':
|
|
return _context.stop();
|
|
}
|
|
}
|
|
}, _marked, this, [[1, 12]]);
|
|
}
|
|
function parseAndUpdateClaimOnly(claim) {
|
|
var isChannel, channelName, channelClaimId, _lbryUri$parseIdentif2, claimName, extension, _lbryUri$parseClaim2;
|
|
|
|
return regeneratorRuntime.wrap(function parseAndUpdateClaimOnly$(_context2) {
|
|
while (1) {
|
|
switch (_context2.prev = _context2.next) {
|
|
case 0:
|
|
// this could be a request for an asset or a channel page
|
|
// claim could be an asset claim or a channel claim
|
|
isChannel = void 0, channelName = void 0, channelClaimId = void 0;
|
|
_context2.prev = 1;
|
|
_lbryUri$parseIdentif2 = _lbryUri2.default.parseIdentifier(claim);
|
|
isChannel = _lbryUri$parseIdentif2.isChannel;
|
|
channelName = _lbryUri$parseIdentif2.channelName;
|
|
channelClaimId = _lbryUri$parseIdentif2.channelClaimId;
|
|
_context2.next = 13;
|
|
break;
|
|
|
|
case 8:
|
|
_context2.prev = 8;
|
|
_context2.t0 = _context2['catch'](1);
|
|
_context2.next = 12;
|
|
return (0, _effects.put)((0, _show.onRequestError)(_context2.t0.message));
|
|
|
|
case 12:
|
|
return _context2.abrupt('return', _context2.sent);
|
|
|
|
case 13:
|
|
if (!isChannel) {
|
|
_context2.next = 17;
|
|
break;
|
|
}
|
|
|
|
_context2.next = 16;
|
|
return (0, _effects.call)(_show_channel.newChannelRequest, (0, _show.onNewChannelRequest)(channelName, channelClaimId));
|
|
|
|
case 16:
|
|
return _context2.abrupt('return', _context2.sent);
|
|
|
|
case 17:
|
|
// if not for a channel, parse the claim request
|
|
claimName = void 0, extension = void 0;
|
|
_context2.prev = 18;
|
|
_lbryUri$parseClaim2 = _lbryUri2.default.parseClaim(claim);
|
|
claimName = _lbryUri$parseClaim2.claimName;
|
|
extension = _lbryUri$parseClaim2.extension;
|
|
_context2.next = 29;
|
|
break;
|
|
|
|
case 24:
|
|
_context2.prev = 24;
|
|
_context2.t1 = _context2['catch'](18);
|
|
_context2.next = 28;
|
|
return (0, _effects.put)((0, _show.onRequestError)(_context2.t1.message));
|
|
|
|
case 28:
|
|
return _context2.abrupt('return', _context2.sent);
|
|
|
|
case 29:
|
|
_context2.next = 31;
|
|
return (0, _effects.call)(_show_asset.newAssetRequest, (0, _show.onNewAssetRequest)(claimName, null, null, null, extension));
|
|
|
|
case 31:
|
|
case 'end':
|
|
return _context2.stop();
|
|
}
|
|
}
|
|
}, _marked2, this, [[1, 8], [18, 24]]);
|
|
}
|
|
|
|
function handleShowPageUri(action) {
|
|
var _action$data, identifier, claim;
|
|
|
|
return regeneratorRuntime.wrap(function handleShowPageUri$(_context3) {
|
|
while (1) {
|
|
switch (_context3.prev = _context3.next) {
|
|
case 0:
|
|
_action$data = action.data, identifier = _action$data.identifier, claim = _action$data.claim;
|
|
|
|
if (!identifier) {
|
|
_context3.next = 5;
|
|
break;
|
|
}
|
|
|
|
_context3.next = 4;
|
|
return (0, _effects.call)(parseAndUpdateIdentifierAndClaim, identifier, claim);
|
|
|
|
case 4:
|
|
return _context3.abrupt('return', _context3.sent);
|
|
|
|
case 5:
|
|
_context3.next = 7;
|
|
return (0, _effects.call)(parseAndUpdateClaimOnly, claim);
|
|
|
|
case 7:
|
|
case 'end':
|
|
return _context3.stop();
|
|
}
|
|
}
|
|
}, _marked3, this);
|
|
};
|
|
|
|
function watchHandleShowPageUri() {
|
|
return regeneratorRuntime.wrap(function watchHandleShowPageUri$(_context4) {
|
|
while (1) {
|
|
switch (_context4.prev = _context4.next) {
|
|
case 0:
|
|
_context4.next = 2;
|
|
return (0, _effects.takeLatest)(actions.HANDLE_SHOW_URI, handleShowPageUri);
|
|
|
|
case 2:
|
|
case 'end':
|
|
return _context4.stop();
|
|
}
|
|
}
|
|
}, _marked4, this);
|
|
};
|
|
|
|
/***/ }),
|
|
/* 40 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
exports.newAssetRequest = newAssetRequest;
|
|
exports.watchNewAssetRequest = watchNewAssetRequest;
|
|
|
|
var _effects = __webpack_require__(10);
|
|
|
|
var _show_action_types = __webpack_require__(13);
|
|
|
|
var actions = _interopRequireWildcard(_show_action_types);
|
|
|
|
var _show = __webpack_require__(7);
|
|
|
|
var _assetApi = __webpack_require__(116);
|
|
|
|
var _show2 = __webpack_require__(16);
|
|
|
|
var _site = __webpack_require__(17);
|
|
|
|
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
|
|
|
|
var _marked = /*#__PURE__*/regeneratorRuntime.mark(newAssetRequest),
|
|
_marked2 = /*#__PURE__*/regeneratorRuntime.mark(watchNewAssetRequest);
|
|
|
|
function newAssetRequest(action) {
|
|
var _action$data, requestType, requestId, name, modifier, state, host, longId, _ref, assetKey, shortId, _ref2, claimData, _ref3;
|
|
|
|
return regeneratorRuntime.wrap(function newAssetRequest$(_context) {
|
|
while (1) {
|
|
switch (_context.prev = _context.next) {
|
|
case 0:
|
|
_action$data = action.data, requestType = _action$data.requestType, requestId = _action$data.requestId, name = _action$data.name, modifier = _action$data.modifier;
|
|
// put an action to update the request in redux
|
|
|
|
_context.next = 3;
|
|
return (0, _effects.put)((0, _show.onRequestUpdate)(requestType, requestId));
|
|
|
|
case 3:
|
|
_context.next = 5;
|
|
return (0, _effects.select)(_show2.selectShowState);
|
|
|
|
case 5:
|
|
state = _context.sent;
|
|
_context.next = 8;
|
|
return (0, _effects.select)(_site.selectSiteHost);
|
|
|
|
case 8:
|
|
host = _context.sent;
|
|
|
|
if (!state.requestList[requestId]) {
|
|
_context.next = 11;
|
|
break;
|
|
}
|
|
|
|
return _context.abrupt('return', null);
|
|
|
|
case 11:
|
|
// get long id && add request to request list
|
|
longId = void 0;
|
|
_context.prev = 12;
|
|
_context.next = 15;
|
|
return (0, _effects.call)(_assetApi.getLongClaimId, host, name, modifier);
|
|
|
|
case 15:
|
|
_ref = _context.sent;
|
|
longId = _ref.data;
|
|
_context.next = 24;
|
|
break;
|
|
|
|
case 19:
|
|
_context.prev = 19;
|
|
_context.t0 = _context['catch'](12);
|
|
_context.next = 23;
|
|
return (0, _effects.put)((0, _show.onRequestError)(_context.t0.message));
|
|
|
|
case 23:
|
|
return _context.abrupt('return', _context.sent);
|
|
|
|
case 24:
|
|
assetKey = 'a#' + name + '#' + longId;
|
|
_context.next = 27;
|
|
return (0, _effects.put)((0, _show.addRequestToRequestList)(requestId, null, assetKey));
|
|
|
|
case 27:
|
|
if (!state.assetList[assetKey]) {
|
|
_context.next = 29;
|
|
break;
|
|
}
|
|
|
|
return _context.abrupt('return', null);
|
|
|
|
case 29:
|
|
// get short Id
|
|
shortId = void 0;
|
|
_context.prev = 30;
|
|
_context.next = 33;
|
|
return (0, _effects.call)(_assetApi.getShortId, host, name, longId);
|
|
|
|
case 33:
|
|
_ref2 = _context.sent;
|
|
shortId = _ref2.data;
|
|
_context.next = 42;
|
|
break;
|
|
|
|
case 37:
|
|
_context.prev = 37;
|
|
_context.t1 = _context['catch'](30);
|
|
_context.next = 41;
|
|
return (0, _effects.put)((0, _show.onRequestError)(_context.t1.message));
|
|
|
|
case 41:
|
|
return _context.abrupt('return', _context.sent);
|
|
|
|
case 42:
|
|
// get asset claim data
|
|
claimData = void 0;
|
|
_context.prev = 43;
|
|
_context.next = 46;
|
|
return (0, _effects.call)(_assetApi.getClaimData, host, name, longId);
|
|
|
|
case 46:
|
|
_ref3 = _context.sent;
|
|
claimData = _ref3.data;
|
|
_context.next = 55;
|
|
break;
|
|
|
|
case 50:
|
|
_context.prev = 50;
|
|
_context.t2 = _context['catch'](43);
|
|
_context.next = 54;
|
|
return (0, _effects.put)((0, _show.onRequestError)(_context.t2.message));
|
|
|
|
case 54:
|
|
return _context.abrupt('return', _context.sent);
|
|
|
|
case 55:
|
|
_context.next = 57;
|
|
return (0, _effects.put)((0, _show.addAssetToAssetList)(assetKey, null, name, longId, shortId, claimData));
|
|
|
|
case 57:
|
|
_context.next = 59;
|
|
return (0, _effects.put)((0, _show.onRequestError)(null));
|
|
|
|
case 59:
|
|
case 'end':
|
|
return _context.stop();
|
|
}
|
|
}
|
|
}, _marked, this, [[12, 19], [30, 37], [43, 50]]);
|
|
};
|
|
|
|
function watchNewAssetRequest() {
|
|
return regeneratorRuntime.wrap(function watchNewAssetRequest$(_context2) {
|
|
while (1) {
|
|
switch (_context2.prev = _context2.next) {
|
|
case 0:
|
|
_context2.next = 2;
|
|
return (0, _effects.takeLatest)(actions.ASSET_REQUEST_NEW, newAssetRequest);
|
|
|
|
case 2:
|
|
case 'end':
|
|
return _context2.stop();
|
|
}
|
|
}
|
|
}, _marked2, this);
|
|
};
|
|
|
|
/***/ }),
|
|
/* 41 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
exports.newChannelRequest = newChannelRequest;
|
|
exports.watchNewChannelRequest = watchNewChannelRequest;
|
|
exports.watchUpdateChannelClaims = watchUpdateChannelClaims;
|
|
|
|
var _effects = __webpack_require__(10);
|
|
|
|
var _show_action_types = __webpack_require__(13);
|
|
|
|
var actions = _interopRequireWildcard(_show_action_types);
|
|
|
|
var _show = __webpack_require__(7);
|
|
|
|
var _channelApi = __webpack_require__(117);
|
|
|
|
var _show2 = __webpack_require__(16);
|
|
|
|
var _site = __webpack_require__(17);
|
|
|
|
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
|
|
|
|
var _marked = /*#__PURE__*/regeneratorRuntime.mark(newChannelRequest),
|
|
_marked2 = /*#__PURE__*/regeneratorRuntime.mark(watchNewChannelRequest),
|
|
_marked3 = /*#__PURE__*/regeneratorRuntime.mark(getNewClaimsAndUpdateChannel),
|
|
_marked4 = /*#__PURE__*/regeneratorRuntime.mark(watchUpdateChannelClaims);
|
|
|
|
function newChannelRequest(action) {
|
|
var _action$data, requestType, requestId, channelName, channelId, state, host, longId, shortId, _ref, _ref$data, channelKey, claimsData, _ref2;
|
|
|
|
return regeneratorRuntime.wrap(function newChannelRequest$(_context) {
|
|
while (1) {
|
|
switch (_context.prev = _context.next) {
|
|
case 0:
|
|
_action$data = action.data, requestType = _action$data.requestType, requestId = _action$data.requestId, channelName = _action$data.channelName, channelId = _action$data.channelId;
|
|
// put an action to update the request in redux
|
|
|
|
_context.next = 3;
|
|
return (0, _effects.put)((0, _show.onRequestUpdate)(requestType, requestId));
|
|
|
|
case 3:
|
|
_context.next = 5;
|
|
return (0, _effects.select)(_show2.selectShowState);
|
|
|
|
case 5:
|
|
state = _context.sent;
|
|
_context.next = 8;
|
|
return (0, _effects.select)(_site.selectSiteHost);
|
|
|
|
case 8:
|
|
host = _context.sent;
|
|
|
|
if (!state.requestList[requestId]) {
|
|
_context.next = 11;
|
|
break;
|
|
}
|
|
|
|
return _context.abrupt('return', null);
|
|
|
|
case 11:
|
|
// get channel long id
|
|
longId = void 0, shortId = void 0;
|
|
_context.prev = 12;
|
|
_context.next = 15;
|
|
return (0, _effects.call)(_channelApi.getChannelData, host, channelName, channelId);
|
|
|
|
case 15:
|
|
_ref = _context.sent;
|
|
_ref$data = _ref.data;
|
|
longId = _ref$data.longChannelClaimId;
|
|
shortId = _ref$data.shortChannelClaimId;
|
|
_context.next = 26;
|
|
break;
|
|
|
|
case 21:
|
|
_context.prev = 21;
|
|
_context.t0 = _context['catch'](12);
|
|
_context.next = 25;
|
|
return (0, _effects.put)((0, _show.onRequestError)(_context.t0.message));
|
|
|
|
case 25:
|
|
return _context.abrupt('return', _context.sent);
|
|
|
|
case 26:
|
|
// store the request in the channel requests list
|
|
channelKey = 'c#' + channelName + '#' + longId;
|
|
_context.next = 29;
|
|
return (0, _effects.put)((0, _show.addRequestToRequestList)(requestId, null, channelKey));
|
|
|
|
case 29:
|
|
if (!state.channelList[channelKey]) {
|
|
_context.next = 31;
|
|
break;
|
|
}
|
|
|
|
return _context.abrupt('return', null);
|
|
|
|
case 31:
|
|
// get channel claims data
|
|
claimsData = void 0;
|
|
_context.prev = 32;
|
|
_context.next = 35;
|
|
return (0, _effects.call)(_channelApi.getChannelClaims, host, longId, channelName, 1);
|
|
|
|
case 35:
|
|
_ref2 = _context.sent;
|
|
claimsData = _ref2.data;
|
|
_context.next = 44;
|
|
break;
|
|
|
|
case 39:
|
|
_context.prev = 39;
|
|
_context.t1 = _context['catch'](32);
|
|
_context.next = 43;
|
|
return (0, _effects.put)((0, _show.onRequestError)(_context.t1.message));
|
|
|
|
case 43:
|
|
return _context.abrupt('return', _context.sent);
|
|
|
|
case 44:
|
|
_context.next = 46;
|
|
return (0, _effects.put)((0, _show.addNewChannelToChannelList)(channelKey, channelName, shortId, longId, claimsData));
|
|
|
|
case 46:
|
|
_context.next = 48;
|
|
return (0, _effects.put)((0, _show.onRequestError)(null));
|
|
|
|
case 48:
|
|
case 'end':
|
|
return _context.stop();
|
|
}
|
|
}
|
|
}, _marked, this, [[12, 21], [32, 39]]);
|
|
}
|
|
|
|
function watchNewChannelRequest() {
|
|
return regeneratorRuntime.wrap(function watchNewChannelRequest$(_context2) {
|
|
while (1) {
|
|
switch (_context2.prev = _context2.next) {
|
|
case 0:
|
|
_context2.next = 2;
|
|
return (0, _effects.takeLatest)(actions.CHANNEL_REQUEST_NEW, newChannelRequest);
|
|
|
|
case 2:
|
|
case 'end':
|
|
return _context2.stop();
|
|
}
|
|
}
|
|
}, _marked2, this);
|
|
};
|
|
|
|
function getNewClaimsAndUpdateChannel(action) {
|
|
var _action$data2, channelKey, name, longId, page, host, claimsData, _ref3;
|
|
|
|
return regeneratorRuntime.wrap(function getNewClaimsAndUpdateChannel$(_context3) {
|
|
while (1) {
|
|
switch (_context3.prev = _context3.next) {
|
|
case 0:
|
|
_action$data2 = action.data, channelKey = _action$data2.channelKey, name = _action$data2.name, longId = _action$data2.longId, page = _action$data2.page;
|
|
_context3.next = 3;
|
|
return (0, _effects.select)(_site.selectSiteHost);
|
|
|
|
case 3:
|
|
host = _context3.sent;
|
|
claimsData = void 0;
|
|
_context3.prev = 5;
|
|
_context3.next = 8;
|
|
return (0, _effects.call)(_channelApi.getChannelClaims, host, longId, name, page);
|
|
|
|
case 8:
|
|
_ref3 = _context3.sent;
|
|
claimsData = _ref3.data;
|
|
_context3.next = 17;
|
|
break;
|
|
|
|
case 12:
|
|
_context3.prev = 12;
|
|
_context3.t0 = _context3['catch'](5);
|
|
_context3.next = 16;
|
|
return (0, _effects.put)((0, _show.onRequestError)(_context3.t0.message));
|
|
|
|
case 16:
|
|
return _context3.abrupt('return', _context3.sent);
|
|
|
|
case 17:
|
|
_context3.next = 19;
|
|
return (0, _effects.put)((0, _show.updateChannelClaims)(channelKey, claimsData));
|
|
|
|
case 19:
|
|
case 'end':
|
|
return _context3.stop();
|
|
}
|
|
}
|
|
}, _marked3, this, [[5, 12]]);
|
|
}
|
|
|
|
function watchUpdateChannelClaims() {
|
|
return regeneratorRuntime.wrap(function watchUpdateChannelClaims$(_context4) {
|
|
while (1) {
|
|
switch (_context4.prev = _context4.next) {
|
|
case 0:
|
|
_context4.next = 2;
|
|
return (0, _effects.takeLatest)(actions.CHANNEL_CLAIMS_UPDATE_ASYNC, getNewClaimsAndUpdateChannel);
|
|
|
|
case 2:
|
|
case 'end':
|
|
return _context4.stop();
|
|
}
|
|
}
|
|
}, _marked4, this);
|
|
}
|
|
|
|
/***/ }),
|
|
/* 42 */
|
|
/***/ (function(module, exports) {
|
|
|
|
module.exports = require("redux-saga");
|
|
|
|
/***/ }),
|
|
/* 43 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
|
|
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
|
|
|
var _react = __webpack_require__(0);
|
|
|
|
var _react2 = _interopRequireDefault(_react);
|
|
|
|
var _reactGa = __webpack_require__(127);
|
|
|
|
var _reactGa2 = _interopRequireDefault(_reactGa);
|
|
|
|
var _reactRouterDom = __webpack_require__(5);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
|
|
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
|
|
|
|
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
|
|
|
|
var _require = __webpack_require__(6),
|
|
googleId = _require.analytics.googleId;
|
|
|
|
_reactGa2.default.initialize(googleId);
|
|
|
|
var GAListener = function (_React$Component) {
|
|
_inherits(GAListener, _React$Component);
|
|
|
|
function GAListener() {
|
|
_classCallCheck(this, GAListener);
|
|
|
|
return _possibleConstructorReturn(this, (GAListener.__proto__ || Object.getPrototypeOf(GAListener)).apply(this, arguments));
|
|
}
|
|
|
|
_createClass(GAListener, [{
|
|
key: 'componentDidMount',
|
|
value: function componentDidMount() {
|
|
this.sendPageView(this.props.history.location);
|
|
this.props.history.listen(this.sendPageView);
|
|
}
|
|
}, {
|
|
key: 'sendPageView',
|
|
value: function sendPageView(location) {
|
|
_reactGa2.default.set({ page: location.pathname });
|
|
_reactGa2.default.pageview(location.pathname);
|
|
}
|
|
}, {
|
|
key: 'render',
|
|
value: function render() {
|
|
return this.props.children;
|
|
}
|
|
}]);
|
|
|
|
return GAListener;
|
|
}(_react2.default.Component);
|
|
|
|
exports.default = (0, _reactRouterDom.withRouter)(GAListener);
|
|
|
|
/***/ }),
|
|
/* 44 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
var logger = __webpack_require__(2);
|
|
|
|
var _require = __webpack_require__(19),
|
|
getClaimId = _require.getClaimId,
|
|
getLocalFileRecord = _require.getLocalFileRecord;
|
|
|
|
var _require2 = __webpack_require__(3),
|
|
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);
|
|
}
|
|
};
|
|
|
|
/***/ }),
|
|
/* 45 */
|
|
/***/ (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__(2);
|
|
|
|
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
|
|
};
|
|
}
|
|
};
|
|
|
|
/***/ }),
|
|
/* 46 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
var _react = __webpack_require__(0);
|
|
|
|
var _react2 = _interopRequireDefault(_react);
|
|
|
|
var _server = __webpack_require__(150);
|
|
|
|
var _redux = __webpack_require__(38);
|
|
|
|
var _index = __webpack_require__(37);
|
|
|
|
var _index2 = _interopRequireDefault(_index);
|
|
|
|
var _reactRedux = __webpack_require__(1);
|
|
|
|
var _reactRouterDom = __webpack_require__(5);
|
|
|
|
var _index3 = __webpack_require__(43);
|
|
|
|
var _index4 = _interopRequireDefault(_index3);
|
|
|
|
var _app = __webpack_require__(28);
|
|
|
|
var _app2 = _interopRequireDefault(_app);
|
|
|
|
var _renderFullPage = __webpack_require__(151);
|
|
|
|
var _renderFullPage2 = _interopRequireDefault(_renderFullPage);
|
|
|
|
var _reduxSaga = __webpack_require__(42);
|
|
|
|
var _reduxSaga2 = _interopRequireDefault(_reduxSaga);
|
|
|
|
var _effects = __webpack_require__(10);
|
|
|
|
var _show_uri = __webpack_require__(39);
|
|
|
|
var _show = __webpack_require__(7);
|
|
|
|
var _reactHelmet = __webpack_require__(20);
|
|
|
|
var _reactHelmet2 = _interopRequireDefault(_reactHelmet);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
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)(_index2.default, middleware);
|
|
|
|
// create saga
|
|
var action = (0, _show.onHandleShowPageUri)(req.params);
|
|
var saga = returnSagaWithParams(_show_uri.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(
|
|
_index4.default,
|
|
null,
|
|
_react2.default.createElement(_app2.default, 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));
|
|
});
|
|
};
|
|
|
|
/***/ }),
|
|
/* 47 */
|
|
/***/ (function(module, exports) {
|
|
|
|
module.exports = require("passport-local");
|
|
|
|
/***/ }),
|
|
/* 48 */
|
|
/***/ (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;
|
|
}
|
|
};
|
|
|
|
/***/ }),
|
|
/* 49 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
__webpack_require__(50);
|
|
__webpack_require__(51);
|
|
module.exports = __webpack_require__(52);
|
|
|
|
|
|
/***/ }),
|
|
/* 50 */
|
|
/***/ (function(module, exports) {
|
|
|
|
module.exports = require("babel-polyfill");
|
|
|
|
/***/ }),
|
|
/* 51 */
|
|
/***/ (function(module, exports) {
|
|
|
|
module.exports = require("whatwg-fetch");
|
|
|
|
/***/ }),
|
|
/* 52 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
var _app = __webpack_require__(28);
|
|
|
|
var _app2 = _interopRequireDefault(_app);
|
|
|
|
var _reducers = __webpack_require__(37);
|
|
|
|
var _reducers2 = _interopRequireDefault(_reducers);
|
|
|
|
var _sagas = __webpack_require__(115);
|
|
|
|
var _sagas2 = _interopRequireDefault(_sagas);
|
|
|
|
var _GAListener = __webpack_require__(43);
|
|
|
|
var _GAListener2 = _interopRequireDefault(_GAListener);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
var api = __webpack_require__(128);
|
|
var asset = __webpack_require__(148);
|
|
var auth = __webpack_require__(153);
|
|
var page = __webpack_require__(175);
|
|
var logger = __webpack_require__(158);
|
|
var mysql = __webpack_require__(14);
|
|
var site = __webpack_require__(6);
|
|
var slack = __webpack_require__(159);
|
|
var passport = __webpack_require__(161);
|
|
var models = __webpack_require__(166);
|
|
|
|
var _exports = {
|
|
App: _app2.default,
|
|
Reducer: _reducers2.default,
|
|
rootSaga: _sagas2.default,
|
|
GAListener: _GAListener2.default,
|
|
logger: logger,
|
|
models: models,
|
|
mysql: mysql,
|
|
passport: passport,
|
|
site: site,
|
|
slack: slack,
|
|
routes: {
|
|
api: api,
|
|
asset: asset,
|
|
auth: auth,
|
|
page: page
|
|
}
|
|
};
|
|
|
|
module.exports = _exports;
|
|
|
|
/***/ }),
|
|
/* 53 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
|
|
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
|
|
|
var _react = __webpack_require__(0);
|
|
|
|
var _react2 = _interopRequireDefault(_react);
|
|
|
|
var _SEO = __webpack_require__(11);
|
|
|
|
var _SEO2 = _interopRequireDefault(_SEO);
|
|
|
|
var _NavBar = __webpack_require__(8);
|
|
|
|
var _NavBar2 = _interopRequireDefault(_NavBar);
|
|
|
|
var _PublishTool = __webpack_require__(62);
|
|
|
|
var _PublishTool2 = _interopRequireDefault(_PublishTool);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
|
|
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
|
|
|
|
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
|
|
|
|
var HomePage = function (_React$Component) {
|
|
_inherits(HomePage, _React$Component);
|
|
|
|
function HomePage() {
|
|
_classCallCheck(this, HomePage);
|
|
|
|
return _possibleConstructorReturn(this, (HomePage.__proto__ || Object.getPrototypeOf(HomePage)).apply(this, arguments));
|
|
}
|
|
|
|
_createClass(HomePage, [{
|
|
key: 'render',
|
|
value: function render() {
|
|
return _react2.default.createElement(
|
|
'div',
|
|
{ className: 'row row--tall flex-container--column' },
|
|
_react2.default.createElement(_SEO2.default, null),
|
|
_react2.default.createElement(_NavBar2.default, null),
|
|
_react2.default.createElement(
|
|
'div',
|
|
{ className: 'row row--tall row--padded flex-container--column' },
|
|
_react2.default.createElement(_PublishTool2.default, null)
|
|
)
|
|
);
|
|
}
|
|
}]);
|
|
|
|
return HomePage;
|
|
}(_react2.default.Component);
|
|
|
|
;
|
|
|
|
exports.default = HomePage;
|
|
|
|
/***/ }),
|
|
/* 54 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
|
|
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
|
|
|
var _react = __webpack_require__(0);
|
|
|
|
var _react2 = _interopRequireDefault(_react);
|
|
|
|
var _reactHelmet = __webpack_require__(20);
|
|
|
|
var _reactHelmet2 = _interopRequireDefault(_reactHelmet);
|
|
|
|
var _propTypes = __webpack_require__(12);
|
|
|
|
var _propTypes2 = _interopRequireDefault(_propTypes);
|
|
|
|
var _pageTitle = __webpack_require__(55);
|
|
|
|
var _metaTags = __webpack_require__(56);
|
|
|
|
var _canonicalLink = __webpack_require__(57);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
|
|
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
|
|
|
|
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
|
|
|
|
var SEO = function (_React$Component) {
|
|
_inherits(SEO, _React$Component);
|
|
|
|
function SEO() {
|
|
_classCallCheck(this, SEO);
|
|
|
|
return _possibleConstructorReturn(this, (SEO.__proto__ || Object.getPrototypeOf(SEO)).apply(this, arguments));
|
|
}
|
|
|
|
_createClass(SEO, [{
|
|
key: 'render',
|
|
value: function render() {
|
|
// props from state
|
|
var _props = this.props,
|
|
defaultDescription = _props.defaultDescription,
|
|
defaultThumbnail = _props.defaultThumbnail,
|
|
siteDescription = _props.siteDescription,
|
|
siteHost = _props.siteHost,
|
|
siteTitle = _props.siteTitle,
|
|
siteTwitter = _props.siteTwitter;
|
|
// props from parent
|
|
|
|
var _props2 = this.props,
|
|
asset = _props2.asset,
|
|
channel = _props2.channel,
|
|
pageUri = _props2.pageUri;
|
|
var pageTitle = this.props.pageTitle;
|
|
// create page title, tags, and canonical link
|
|
|
|
pageTitle = (0, _pageTitle.createPageTitle)(siteTitle, pageTitle);
|
|
var metaTags = (0, _metaTags.createMetaTags)(siteDescription, siteHost, siteTitle, siteTwitter, asset, channel, defaultDescription, defaultThumbnail);
|
|
var canonicalLink = (0, _canonicalLink.createCanonicalLink)(asset, channel, pageUri, siteHost);
|
|
// render results
|
|
return _react2.default.createElement(_reactHelmet2.default, {
|
|
title: pageTitle,
|
|
meta: metaTags,
|
|
link: [{ rel: 'canonical', href: canonicalLink }]
|
|
});
|
|
}
|
|
}]);
|
|
|
|
return SEO;
|
|
}(_react2.default.Component);
|
|
|
|
;
|
|
|
|
SEO.propTypes = {
|
|
pageTitle: _propTypes2.default.string,
|
|
pageUri: _propTypes2.default.string,
|
|
channel: _propTypes2.default.object,
|
|
asset: _propTypes2.default.object
|
|
};
|
|
|
|
exports.default = SEO;
|
|
|
|
/***/ }),
|
|
/* 55 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
var createPageTitle = exports.createPageTitle = function createPageTitle(siteTitle, pageTitle) {
|
|
if (!pageTitle) {
|
|
return "" + siteTitle;
|
|
}
|
|
return siteTitle + " - " + pageTitle;
|
|
};
|
|
|
|
/***/ }),
|
|
/* 56 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
var determineOgThumbnailContentType = function determineOgThumbnailContentType(thumbnail) {
|
|
if (thumbnail) {
|
|
var fileExt = thumbnail.substring(thumbnail.lastIndexOf('.'));
|
|
switch (fileExt) {
|
|
case 'jpeg':
|
|
case 'jpg':
|
|
return 'image/jpeg';
|
|
case 'png':
|
|
return 'image/png';
|
|
case 'gif':
|
|
return 'image/gif';
|
|
case 'mp4':
|
|
return 'video/mp4';
|
|
default:
|
|
return 'image/jpeg';
|
|
}
|
|
}
|
|
return '';
|
|
};
|
|
|
|
var createBasicMetaTags = function createBasicMetaTags(siteHost, siteDescription, siteTitle, siteTwitter) {
|
|
return [{ property: 'og:title', content: siteTitle }, { property: 'og:url', content: siteHost }, { property: 'og:site_name', content: siteTitle }, { property: 'og:description', content: siteDescription }, { property: 'twitter:site', content: siteTwitter }, { property: 'twitter:card', content: 'summary' }];
|
|
};
|
|
|
|
var createChannelMetaTags = function createChannelMetaTags(siteTitle, siteHost, siteTwitter, channel) {
|
|
var name = channel.name,
|
|
longId = channel.longId;
|
|
|
|
return [{ property: 'og:title', content: name + ' on ' + siteTitle }, { property: 'og:url', content: siteHost + '/' + name + ':' + longId }, { property: 'og:site_name', content: siteTitle }, { property: 'og:description', content: name + ', a channel on ' + siteTitle }, { property: 'twitter:site', content: siteTwitter }, { property: 'twitter:card', content: 'summary' }];
|
|
};
|
|
|
|
var createAssetMetaTags = function createAssetMetaTags(siteHost, siteTitle, siteTwitter, asset, defaultDescription, defaultThumbnail) {
|
|
var claimData = asset.claimData;
|
|
var contentType = claimData.contentType;
|
|
|
|
var embedUrl = siteHost + '/' + claimData.claimId + '/' + claimData.name;
|
|
var showUrl = siteHost + '/' + claimData.claimId + '/' + claimData.name;
|
|
var source = siteHost + '/' + claimData.claimId + '/' + claimData.name + '.' + claimData.fileExt;
|
|
var ogTitle = claimData.title || claimData.name;
|
|
var ogDescription = claimData.description || defaultDescription;
|
|
var ogThumbnailContentType = determineOgThumbnailContentType(claimData.thumbnail);
|
|
var ogThumbnail = claimData.thumbnail || defaultThumbnail;
|
|
var metaTags = [{ property: 'og:title', content: ogTitle }, { property: 'og:url', content: showUrl }, { property: 'og:site_name', content: siteTitle }, { property: 'og:description', content: ogDescription }, { property: 'og:image:width', content: 600 }, { property: 'og:image:height', content: 315 }, { property: 'twitter:site', content: siteTwitter }];
|
|
if (contentType === 'video/mp4' || contentType === 'video/webm') {
|
|
metaTags.push({ property: 'og:video', content: source });
|
|
metaTags.push({ property: 'og:video:secure_url', content: source });
|
|
metaTags.push({ property: 'og:video:type', content: contentType });
|
|
metaTags.push({ property: 'og:image', content: ogThumbnail });
|
|
metaTags.push({ property: 'og:image:type', content: ogThumbnailContentType });
|
|
metaTags.push({ property: 'og:type', content: 'video' });
|
|
metaTags.push({ property: 'twitter:card', content: 'player' });
|
|
metaTags.push({ property: 'twitter:player', content: embedUrl });
|
|
metaTags.push({ property: 'twitter:player:width', content: 600 });
|
|
metaTags.push({ property: 'twitter:text:player_width', content: 600 });
|
|
metaTags.push({ property: 'twitter:player:height', content: 337 });
|
|
metaTags.push({ property: 'twitter:player:stream', content: source });
|
|
metaTags.push({ property: 'twitter:player:stream:content_type', content: contentType });
|
|
} else {
|
|
metaTags.push({ property: 'og:image', content: source });
|
|
metaTags.push({ property: 'og:image:type', content: contentType });
|
|
metaTags.push({ property: 'og:type', content: 'article' });
|
|
metaTags.push({ property: 'twitter:card', content: 'summary_large_image' });
|
|
}
|
|
return metaTags;
|
|
};
|
|
|
|
var createMetaTags = exports.createMetaTags = function createMetaTags(siteDescription, siteHost, siteTitle, siteTwitter, asset, channel, defaultDescription, defaultThumbnail) {
|
|
if (asset) {
|
|
return createAssetMetaTags(siteHost, siteTitle, siteTwitter, asset, defaultDescription, defaultThumbnail);
|
|
};
|
|
if (channel) {
|
|
return createChannelMetaTags(siteHost, siteTitle, siteTwitter, channel);
|
|
};
|
|
return createBasicMetaTags(siteDescription, siteHost, siteTitle, siteTwitter);
|
|
};
|
|
|
|
/***/ }),
|
|
/* 57 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
var createBasicCanonicalLink = function createBasicCanonicalLink(page, siteHost) {
|
|
return siteHost + "/" + page;
|
|
};
|
|
|
|
var createAssetCanonicalLink = function createAssetCanonicalLink(asset, siteHost) {
|
|
var channelName = void 0,
|
|
certificateId = void 0,
|
|
name = void 0,
|
|
claimId = void 0;
|
|
if (asset.claimData) {
|
|
var _asset$claimData = asset.claimData;
|
|
channelName = _asset$claimData.channelName;
|
|
certificateId = _asset$claimData.certificateId;
|
|
name = _asset$claimData.name;
|
|
claimId = _asset$claimData.claimId;
|
|
};
|
|
if (channelName) {
|
|
return siteHost + "/" + channelName + ":" + certificateId + "/" + name;
|
|
};
|
|
return siteHost + "/" + claimId + "/" + name;
|
|
};
|
|
|
|
var createChannelCanonicalLink = function createChannelCanonicalLink(channel, siteHost) {
|
|
var name = channel.name,
|
|
longId = channel.longId;
|
|
|
|
return siteHost + "/" + name + ":" + longId;
|
|
};
|
|
|
|
var createCanonicalLink = exports.createCanonicalLink = function createCanonicalLink(asset, channel, page, siteHost) {
|
|
if (asset) {
|
|
return createAssetCanonicalLink(asset, siteHost);
|
|
}
|
|
if (channel) {
|
|
return createChannelCanonicalLink(channel, siteHost);
|
|
}
|
|
return createBasicCanonicalLink(page, siteHost);
|
|
};
|
|
|
|
/***/ }),
|
|
/* 58 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
|
|
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
|
|
|
var _react = __webpack_require__(0);
|
|
|
|
var _react2 = _interopRequireDefault(_react);
|
|
|
|
var _reactRouterDom = __webpack_require__(5);
|
|
|
|
var _Logo = __webpack_require__(59);
|
|
|
|
var _Logo2 = _interopRequireDefault(_Logo);
|
|
|
|
var _NavBarChannelOptionsDropdown = __webpack_require__(60);
|
|
|
|
var _NavBarChannelOptionsDropdown2 = _interopRequireDefault(_NavBarChannelOptionsDropdown);
|
|
|
|
var _request = __webpack_require__(9);
|
|
|
|
var _request2 = _interopRequireDefault(_request);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
|
|
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
|
|
|
|
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
|
|
|
|
var VIEW = 'VIEW';
|
|
var LOGOUT = 'LOGOUT';
|
|
|
|
var NavBar = function (_React$Component) {
|
|
_inherits(NavBar, _React$Component);
|
|
|
|
function NavBar(props) {
|
|
_classCallCheck(this, NavBar);
|
|
|
|
var _this = _possibleConstructorReturn(this, (NavBar.__proto__ || Object.getPrototypeOf(NavBar)).call(this, props));
|
|
|
|
_this.checkForLoggedInUser = _this.checkForLoggedInUser.bind(_this);
|
|
_this.logoutUser = _this.logoutUser.bind(_this);
|
|
_this.handleSelection = _this.handleSelection.bind(_this);
|
|
return _this;
|
|
}
|
|
|
|
_createClass(NavBar, [{
|
|
key: 'componentDidMount',
|
|
value: function componentDidMount() {
|
|
// check to see if the user is already logged in
|
|
this.checkForLoggedInUser();
|
|
}
|
|
}, {
|
|
key: 'checkForLoggedInUser',
|
|
value: function checkForLoggedInUser() {
|
|
var _this2 = this;
|
|
|
|
var params = { credentials: 'include' };
|
|
(0, _request2.default)('/user', params).then(function (_ref) {
|
|
var data = _ref.data;
|
|
|
|
_this2.props.onChannelLogin(data.channelName, data.shortChannelId, data.channelClaimId);
|
|
}).catch(function (error) {
|
|
console.log('/user error:', error.message);
|
|
});
|
|
}
|
|
}, {
|
|
key: 'logoutUser',
|
|
value: function logoutUser() {
|
|
var _this3 = this;
|
|
|
|
var params = { credentials: 'include' };
|
|
(0, _request2.default)('/logout', params).then(function () {
|
|
_this3.props.onChannelLogout();
|
|
}).catch(function (error) {
|
|
console.log('/logout error', error.message);
|
|
});
|
|
}
|
|
}, {
|
|
key: 'handleSelection',
|
|
value: function handleSelection(event) {
|
|
var value = event.target.selectedOptions[0].value;
|
|
switch (value) {
|
|
case LOGOUT:
|
|
this.logoutUser();
|
|
break;
|
|
case VIEW:
|
|
// redirect to channel page
|
|
this.props.history.push('/' + this.props.channelName + ':' + this.props.channelLongId);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
}, {
|
|
key: 'render',
|
|
value: function render() {
|
|
var siteDescription = this.props.siteDescription;
|
|
|
|
return _react2.default.createElement(
|
|
'div',
|
|
{ className: 'row row--wide nav-bar' },
|
|
_react2.default.createElement(
|
|
'div',
|
|
{ className: 'row row--padded row--short flex-container--row flex-container--space-between-center' },
|
|
_react2.default.createElement(_Logo2.default, null),
|
|
_react2.default.createElement(
|
|
'div',
|
|
{ className: 'nav-bar--center' },
|
|
_react2.default.createElement(
|
|
'span',
|
|
{ className: 'nav-bar-tagline' },
|
|
siteDescription
|
|
)
|
|
),
|
|
_react2.default.createElement(
|
|
'div',
|
|
{ className: 'nav-bar--right' },
|
|
_react2.default.createElement(
|
|
_reactRouterDom.NavLink,
|
|
{ className: 'nav-bar-link link--nav', activeClassName: 'link--nav-active', to: '/', exact: true },
|
|
'Publish'
|
|
),
|
|
_react2.default.createElement(
|
|
_reactRouterDom.NavLink,
|
|
{ className: 'nav-bar-link link--nav', activeClassName: 'link--nav-active', to: '/about' },
|
|
'About'
|
|
),
|
|
this.props.channelName ? _react2.default.createElement(_NavBarChannelOptionsDropdown2.default, {
|
|
channelName: this.props.channelName,
|
|
handleSelection: this.handleSelection,
|
|
defaultSelection: this.props.channelName,
|
|
VIEW: VIEW,
|
|
LOGOUT: LOGOUT
|
|
}) : _react2.default.createElement(
|
|
_reactRouterDom.NavLink,
|
|
{ id: 'nav-bar-login-link', className: 'nav-bar-link link--nav', activeClassName: 'link--nav-active', to: '/login' },
|
|
'Channel'
|
|
)
|
|
)
|
|
)
|
|
);
|
|
}
|
|
}]);
|
|
|
|
return NavBar;
|
|
}(_react2.default.Component);
|
|
|
|
exports.default = (0, _reactRouterDom.withRouter)(NavBar);
|
|
|
|
/***/ }),
|
|
/* 59 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
|
|
var _react = __webpack_require__(0);
|
|
|
|
var _react2 = _interopRequireDefault(_react);
|
|
|
|
var _reactRouterDom = __webpack_require__(5);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
function Logo() {
|
|
return _react2.default.createElement(
|
|
'svg',
|
|
{ version: '1.1', id: 'Layer_1', x: '0px', y: '0px', height: '24px', viewBox: '0 0 80 31', enableBackground: 'new 0 0 80 31', className: 'nav-bar-logo' },
|
|
_react2.default.createElement(
|
|
_reactRouterDom.Link,
|
|
{ to: '/' },
|
|
_react2.default.createElement(
|
|
'title',
|
|
null,
|
|
'Logo'
|
|
),
|
|
_react2.default.createElement(
|
|
'desc',
|
|
null,
|
|
'Spee.ch logo'
|
|
),
|
|
_react2.default.createElement(
|
|
'g',
|
|
{ id: 'About' },
|
|
_react2.default.createElement(
|
|
'g',
|
|
{ id: 'Publish-Form-V2-_x28_filled_x29_', transform: 'translate(-42.000000, -23.000000)' },
|
|
_react2.default.createElement(
|
|
'g',
|
|
{ id: 'Group-17', transform: 'translate(42.000000, 22.000000)' },
|
|
_react2.default.createElement(
|
|
'text',
|
|
{ transform: 'matrix(1 0 0 1 0 20)', fontSize: '25', fontFamily: 'Roboto' },
|
|
'Spee<h'
|
|
),
|
|
_react2.default.createElement(
|
|
'g',
|
|
{ id: 'Group-16', transform: 'translate(0.000000, 30.000000)' },
|
|
_react2.default.createElement('path', { id: 'Line-8', fill: 'none', stroke: '#09F911', strokeWidth: '1', strokeLinecap: 'square', d: 'M0.5,1.5h15' }),
|
|
_react2.default.createElement('path', { id: 'Line-8-Copy', fill: 'none', stroke: '#029D74', strokeWidth: '1', strokeLinecap: 'square', d: 'M16.5,1.5h15' }),
|
|
_react2.default.createElement('path', { id: 'Line-8-Copy-2', fill: 'none', stroke: '#E35BD8', strokeWidth: '1', strokeLinecap: 'square', d: 'M32.5,1.5h15' }),
|
|
_react2.default.createElement('path', { id: 'Line-8-Copy-3', fill: 'none', stroke: '#4156C5', strokeWidth: '1', strokeLinecap: 'square', d: 'M48.5,1.5h15' }),
|
|
_react2.default.createElement('path', { id: 'Line-8-Copy-4', fill: 'none', stroke: '#635688', strokeWidth: '1', strokeLinecap: 'square', d: 'M64.5,1.5h15' })
|
|
)
|
|
)
|
|
)
|
|
)
|
|
)
|
|
);
|
|
};
|
|
|
|
exports.default = Logo;
|
|
|
|
/***/ }),
|
|
/* 60 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
|
|
var _react = __webpack_require__(0);
|
|
|
|
var _react2 = _interopRequireDefault(_react);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
function NavBarChannelDropdown(_ref) {
|
|
var channelName = _ref.channelName,
|
|
handleSelection = _ref.handleSelection,
|
|
defaultSelection = _ref.defaultSelection,
|
|
VIEW = _ref.VIEW,
|
|
LOGOUT = _ref.LOGOUT;
|
|
|
|
return _react2.default.createElement(
|
|
'select',
|
|
{ type: 'text', id: 'nav-bar-channel-select', className: 'select select--arrow link--nav', onChange: handleSelection, value: defaultSelection },
|
|
_react2.default.createElement(
|
|
'option',
|
|
{ id: 'nav-bar-channel-select-channel-option' },
|
|
channelName
|
|
),
|
|
_react2.default.createElement(
|
|
'option',
|
|
{ value: VIEW },
|
|
'View'
|
|
),
|
|
_react2.default.createElement(
|
|
'option',
|
|
{ value: LOGOUT },
|
|
'Logout'
|
|
)
|
|
);
|
|
};
|
|
|
|
exports.default = NavBarChannelDropdown;
|
|
|
|
/***/ }),
|
|
/* 61 */
|
|
/***/ (function(module, exports) {
|
|
|
|
module.exports = require("cross-fetch/polyfill");
|
|
|
|
/***/ }),
|
|
/* 62 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
|
|
var _reactRedux = __webpack_require__(1);
|
|
|
|
var _view = __webpack_require__(63);
|
|
|
|
var _view2 = _interopRequireDefault(_view);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
var mapStateToProps = function mapStateToProps(_ref) {
|
|
var publish = _ref.publish;
|
|
|
|
return {
|
|
disabled: publish.disabled,
|
|
file: publish.file,
|
|
status: publish.status.status
|
|
};
|
|
};
|
|
|
|
exports.default = (0, _reactRedux.connect)(mapStateToProps, null)(_view2.default);
|
|
|
|
/***/ }),
|
|
/* 63 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
|
|
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
|
|
|
var _react = __webpack_require__(0);
|
|
|
|
var _react2 = _interopRequireDefault(_react);
|
|
|
|
var _Dropzone = __webpack_require__(30);
|
|
|
|
var _Dropzone2 = _interopRequireDefault(_Dropzone);
|
|
|
|
var _PublishDetails = __webpack_require__(67);
|
|
|
|
var _PublishDetails2 = _interopRequireDefault(_PublishDetails);
|
|
|
|
var _PublishStatus = __webpack_require__(85);
|
|
|
|
var _PublishStatus2 = _interopRequireDefault(_PublishStatus);
|
|
|
|
var _PublishDisabledMessage = __webpack_require__(87);
|
|
|
|
var _PublishDisabledMessage2 = _interopRequireDefault(_PublishDisabledMessage);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
|
|
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
|
|
|
|
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
|
|
|
|
var PublishTool = function (_React$Component) {
|
|
_inherits(PublishTool, _React$Component);
|
|
|
|
function PublishTool() {
|
|
_classCallCheck(this, PublishTool);
|
|
|
|
return _possibleConstructorReturn(this, (PublishTool.__proto__ || Object.getPrototypeOf(PublishTool)).apply(this, arguments));
|
|
}
|
|
|
|
_createClass(PublishTool, [{
|
|
key: 'render',
|
|
value: function render() {
|
|
if (this.props.disabled) {
|
|
console.log('publish is disabled');
|
|
return _react2.default.createElement(_PublishDisabledMessage2.default, null);
|
|
} else {
|
|
console.log('publish is not disabled');
|
|
if (this.props.file) {
|
|
if (this.props.status) {
|
|
return _react2.default.createElement(_PublishStatus2.default, null);
|
|
} else {
|
|
return _react2.default.createElement(_PublishDetails2.default, null);
|
|
}
|
|
}
|
|
return _react2.default.createElement(_Dropzone2.default, null);
|
|
}
|
|
}
|
|
}]);
|
|
|
|
return PublishTool;
|
|
}(_react2.default.Component);
|
|
|
|
;
|
|
|
|
exports.default = PublishTool;
|
|
|
|
/***/ }),
|
|
/* 64 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
|
|
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
|
|
|
var _react = __webpack_require__(0);
|
|
|
|
var _react2 = _interopRequireDefault(_react);
|
|
|
|
var _file = __webpack_require__(65);
|
|
|
|
var _PublishPreview = __webpack_require__(66);
|
|
|
|
var _PublishPreview2 = _interopRequireDefault(_PublishPreview);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
|
|
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
|
|
|
|
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
|
|
|
|
var Dropzone = function (_React$Component) {
|
|
_inherits(Dropzone, _React$Component);
|
|
|
|
function Dropzone(props) {
|
|
_classCallCheck(this, Dropzone);
|
|
|
|
var _this = _possibleConstructorReturn(this, (Dropzone.__proto__ || Object.getPrototypeOf(Dropzone)).call(this, props));
|
|
|
|
_this.state = {
|
|
dragOver: false,
|
|
mouseOver: false,
|
|
dimPreview: false
|
|
};
|
|
_this.handleDrop = _this.handleDrop.bind(_this);
|
|
_this.handleDragOver = _this.handleDragOver.bind(_this);
|
|
_this.handleDragEnd = _this.handleDragEnd.bind(_this);
|
|
_this.handleDragEnter = _this.handleDragEnter.bind(_this);
|
|
_this.handleDragLeave = _this.handleDragLeave.bind(_this);
|
|
_this.handleMouseEnter = _this.handleMouseEnter.bind(_this);
|
|
_this.handleMouseLeave = _this.handleMouseLeave.bind(_this);
|
|
_this.handleClick = _this.handleClick.bind(_this);
|
|
_this.handleFileInput = _this.handleFileInput.bind(_this);
|
|
_this.chooseFile = _this.chooseFile.bind(_this);
|
|
return _this;
|
|
}
|
|
|
|
_createClass(Dropzone, [{
|
|
key: 'handleDrop',
|
|
value: function handleDrop(event) {
|
|
event.preventDefault();
|
|
this.setState({ dragOver: false });
|
|
// if dropped items aren't files, reject them
|
|
var dt = event.dataTransfer;
|
|
if (dt.items) {
|
|
if (dt.items[0].kind === 'file') {
|
|
var droppedFile = dt.items[0].getAsFile();
|
|
this.chooseFile(droppedFile);
|
|
}
|
|
}
|
|
}
|
|
}, {
|
|
key: 'handleDragOver',
|
|
value: function handleDragOver(event) {
|
|
event.preventDefault();
|
|
}
|
|
}, {
|
|
key: 'handleDragEnd',
|
|
value: function handleDragEnd(event) {
|
|
var dt = event.dataTransfer;
|
|
if (dt.items) {
|
|
for (var i = 0; i < dt.items.length; i++) {
|
|
dt.items.remove(i);
|
|
}
|
|
} else {
|
|
event.dataTransfer.clearData();
|
|
}
|
|
}
|
|
}, {
|
|
key: 'handleDragEnter',
|
|
value: function handleDragEnter() {
|
|
this.setState({ dragOver: true, dimPreview: true });
|
|
}
|
|
}, {
|
|
key: 'handleDragLeave',
|
|
value: function handleDragLeave() {
|
|
this.setState({ dragOver: false, dimPreview: false });
|
|
}
|
|
}, {
|
|
key: 'handleMouseEnter',
|
|
value: function handleMouseEnter() {
|
|
this.setState({ mouseOver: true, dimPreview: true });
|
|
}
|
|
}, {
|
|
key: 'handleMouseLeave',
|
|
value: function handleMouseLeave() {
|
|
this.setState({ mouseOver: false, dimPreview: false });
|
|
}
|
|
}, {
|
|
key: 'handleClick',
|
|
value: function handleClick(event) {
|
|
event.preventDefault();
|
|
document.getElementById('file_input').click();
|
|
}
|
|
}, {
|
|
key: 'handleFileInput',
|
|
value: function handleFileInput(event) {
|
|
event.preventDefault();
|
|
var fileList = event.target.files;
|
|
this.chooseFile(fileList[0]);
|
|
}
|
|
}, {
|
|
key: 'chooseFile',
|
|
value: function chooseFile(file) {
|
|
if (file) {
|
|
try {
|
|
(0, _file.validateFile)(file); // validate the file's name, type, and size
|
|
} catch (error) {
|
|
return this.props.setFileError(error.message);
|
|
}
|
|
// stage it so it will be ready when the publish button is clicked
|
|
this.props.selectFile(file);
|
|
}
|
|
}
|
|
}, {
|
|
key: 'render',
|
|
value: function render() {
|
|
return _react2.default.createElement(
|
|
'div',
|
|
{ className: 'row row--tall flex-container--column' },
|
|
_react2.default.createElement(
|
|
'form',
|
|
null,
|
|
_react2.default.createElement('input', { className: 'input-file', type: 'file', id: 'file_input', name: 'file_input', accept: 'video/*,image/*', onChange: this.handleFileInput, encType: 'multipart/form-data' })
|
|
),
|
|
_react2.default.createElement(
|
|
'div',
|
|
{ id: 'preview-dropzone', className: 'row row--padded row--tall dropzone' + (this.state.dragOver ? ' dropzone--drag-over' : ''), onDrop: this.handleDrop, onDragOver: this.handleDragOver, onDragEnd: this.handleDragEnd, onDragEnter: this.handleDragEnter, onDragLeave: this.handleDragLeave, onMouseEnter: this.handleMouseEnter, onMouseLeave: this.handleMouseLeave, onClick: this.handleClick },
|
|
this.props.file ? _react2.default.createElement(
|
|
'div',
|
|
null,
|
|
_react2.default.createElement(_PublishPreview2.default, {
|
|
dimPreview: this.state.dimPreview,
|
|
file: this.props.file,
|
|
thumbnail: this.props.thumbnail
|
|
}),
|
|
_react2.default.createElement(
|
|
'div',
|
|
{ id: 'dropzone-text-holder', className: 'flex-container--column flex-container--center-center' },
|
|
this.state.dragOver ? _react2.default.createElement(
|
|
'div',
|
|
{ id: 'dropzone-dragover' },
|
|
_react2.default.createElement(
|
|
'p',
|
|
{ className: 'blue' },
|
|
'Drop it.'
|
|
)
|
|
) : null,
|
|
this.state.mouseOver ? _react2.default.createElement(
|
|
'div',
|
|
{ id: 'dropzone-instructions' },
|
|
_react2.default.createElement(
|
|
'p',
|
|
{ className: 'info-message-placeholder info-message--failure', id: 'input-error-file-selection' },
|
|
this.props.fileError
|
|
),
|
|
_react2.default.createElement(
|
|
'p',
|
|
null,
|
|
'Drag & drop image or video here to publish'
|
|
),
|
|
_react2.default.createElement(
|
|
'p',
|
|
{ className: 'fine-print' },
|
|
'OR'
|
|
),
|
|
_react2.default.createElement(
|
|
'p',
|
|
{ className: 'blue--underlined' },
|
|
'CHOOSE FILE'
|
|
)
|
|
) : null
|
|
)
|
|
) : _react2.default.createElement(
|
|
'div',
|
|
{ id: 'dropzone-text-holder', className: 'flex-container--column flex-container--center-center' },
|
|
this.state.dragOver ? _react2.default.createElement(
|
|
'div',
|
|
{ id: 'dropzone-dragover' },
|
|
_react2.default.createElement(
|
|
'p',
|
|
{ className: 'blue' },
|
|
'Drop it.'
|
|
)
|
|
) : _react2.default.createElement(
|
|
'div',
|
|
{ id: 'dropzone-instructions' },
|
|
_react2.default.createElement(
|
|
'p',
|
|
{ className: 'info-message-placeholder info-message--failure', id: 'input-error-file-selection' },
|
|
this.props.fileError
|
|
),
|
|
_react2.default.createElement(
|
|
'p',
|
|
null,
|
|
'Drag & drop image or video here to publish'
|
|
),
|
|
_react2.default.createElement(
|
|
'p',
|
|
{ className: 'fine-print' },
|
|
'OR'
|
|
),
|
|
_react2.default.createElement(
|
|
'p',
|
|
{ className: 'blue--underlined' },
|
|
'CHOOSE FILE'
|
|
)
|
|
)
|
|
)
|
|
)
|
|
);
|
|
}
|
|
}]);
|
|
|
|
return Dropzone;
|
|
}(_react2.default.Component);
|
|
|
|
;
|
|
|
|
exports.default = Dropzone;
|
|
|
|
/***/ }),
|
|
/* 65 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
module.exports = {
|
|
validateFile: function validateFile(file) {
|
|
if (!file) {
|
|
throw new Error('no file provided');
|
|
}
|
|
if (/'/.test(file.name)) {
|
|
throw new Error('apostrophes are not allowed in the file name');
|
|
}
|
|
// validate size and type
|
|
switch (file.type) {
|
|
case 'image/jpeg':
|
|
case 'image/jpg':
|
|
case 'image/png':
|
|
if (file.size > 10000000) {
|
|
throw new Error('Sorry, images are limited to 10 megabytes.');
|
|
}
|
|
break;
|
|
case 'image/gif':
|
|
if (file.size > 50000000) {
|
|
throw new Error('Sorry, GIFs are limited to 50 megabytes.');
|
|
}
|
|
break;
|
|
case 'video/mp4':
|
|
if (file.size > 50000000) {
|
|
throw new Error('Sorry, videos are limited to 50 megabytes.');
|
|
}
|
|
break;
|
|
default:
|
|
throw new Error(file.type + ' is not a supported file type. Only, .jpeg, .png, .gif, and .mp4 files are currently supported.');
|
|
}
|
|
}
|
|
};
|
|
|
|
/***/ }),
|
|
/* 66 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
|
|
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
|
|
|
var _react = __webpack_require__(0);
|
|
|
|
var _react2 = _interopRequireDefault(_react);
|
|
|
|
var _propTypes = __webpack_require__(12);
|
|
|
|
var _propTypes2 = _interopRequireDefault(_propTypes);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
|
|
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
|
|
|
|
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
|
|
|
|
var PublishPreview = function (_React$Component) {
|
|
_inherits(PublishPreview, _React$Component);
|
|
|
|
function PublishPreview(props) {
|
|
_classCallCheck(this, PublishPreview);
|
|
|
|
var _this = _possibleConstructorReturn(this, (PublishPreview.__proto__ || Object.getPrototypeOf(PublishPreview)).call(this, props));
|
|
|
|
_this.state = {
|
|
imgSource: '',
|
|
defaultThumbnail: '/assets/img/video_thumb_default.png'
|
|
};
|
|
return _this;
|
|
}
|
|
|
|
_createClass(PublishPreview, [{
|
|
key: 'componentDidMount',
|
|
value: function componentDidMount() {
|
|
this.setPreviewImageSource(this.props.file);
|
|
}
|
|
}, {
|
|
key: 'componentWillReceiveProps',
|
|
value: function componentWillReceiveProps(newProps) {
|
|
if (newProps.file !== this.props.file) {
|
|
this.setPreviewImageSource(newProps.file);
|
|
}
|
|
if (newProps.thumbnail !== this.props.thumbnail) {
|
|
if (newProps.thumbnail) {
|
|
this.setPreviewImageSourceFromFile(newProps.thumbnail);
|
|
} else {
|
|
this.setState({ imgSource: this.state.defaultThumbnail });
|
|
}
|
|
}
|
|
}
|
|
}, {
|
|
key: 'setPreviewImageSourceFromFile',
|
|
value: function setPreviewImageSourceFromFile(file) {
|
|
var _this2 = this;
|
|
|
|
var previewReader = new FileReader();
|
|
previewReader.readAsDataURL(file);
|
|
previewReader.onloadend = function () {
|
|
_this2.setState({ imgSource: previewReader.result });
|
|
};
|
|
}
|
|
}, {
|
|
key: 'setPreviewImageSource',
|
|
value: function setPreviewImageSource(file) {
|
|
if (file.type !== 'video/mp4') {
|
|
this.setPreviewImageSourceFromFile(file);
|
|
} else {
|
|
if (this.props.thumbnail) {
|
|
this.setPreviewImageSourceFromFile(this.props.thumbnail);
|
|
}
|
|
this.setState({ imgSource: this.state.defaultThumbnail });
|
|
}
|
|
}
|
|
}, {
|
|
key: 'render',
|
|
value: function render() {
|
|
return _react2.default.createElement('img', {
|
|
id: 'dropzone-preview',
|
|
src: this.state.imgSource,
|
|
className: this.props.dimPreview ? 'dim' : '',
|
|
alt: 'publish preview'
|
|
});
|
|
}
|
|
}]);
|
|
|
|
return PublishPreview;
|
|
}(_react2.default.Component);
|
|
|
|
;
|
|
|
|
PublishPreview.propTypes = {
|
|
dimPreview: _propTypes2.default.bool.isRequired,
|
|
file: _propTypes2.default.object.isRequired,
|
|
thumbnail: _propTypes2.default.object
|
|
};
|
|
|
|
exports.default = PublishPreview;
|
|
|
|
/***/ }),
|
|
/* 67 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
|
|
var _reactRedux = __webpack_require__(1);
|
|
|
|
var _publish = __webpack_require__(4);
|
|
|
|
var _view = __webpack_require__(68);
|
|
|
|
var _view2 = _interopRequireDefault(_view);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
var mapStateToProps = function mapStateToProps(_ref) {
|
|
var channel = _ref.channel,
|
|
publish = _ref.publish;
|
|
|
|
return {
|
|
file: publish.file
|
|
};
|
|
};
|
|
|
|
var mapDispatchToProps = {
|
|
clearFile: _publish.clearFile,
|
|
startPublish: _publish.startPublish
|
|
};
|
|
|
|
exports.default = (0, _reactRedux.connect)(mapStateToProps, mapDispatchToProps)(_view2.default);
|
|
|
|
/***/ }),
|
|
/* 68 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
|
|
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
|
|
|
var _react = __webpack_require__(0);
|
|
|
|
var _react2 = _interopRequireDefault(_react);
|
|
|
|
var _reactRouterDom = __webpack_require__(5);
|
|
|
|
var _Dropzone = __webpack_require__(30);
|
|
|
|
var _Dropzone2 = _interopRequireDefault(_Dropzone);
|
|
|
|
var _PublishTitleInput = __webpack_require__(69);
|
|
|
|
var _PublishTitleInput2 = _interopRequireDefault(_PublishTitleInput);
|
|
|
|
var _PublishUrlInput = __webpack_require__(71);
|
|
|
|
var _PublishUrlInput2 = _interopRequireDefault(_PublishUrlInput);
|
|
|
|
var _PublishThumbnailInput = __webpack_require__(74);
|
|
|
|
var _PublishThumbnailInput2 = _interopRequireDefault(_PublishThumbnailInput);
|
|
|
|
var _PublishMetadataInputs = __webpack_require__(76);
|
|
|
|
var _PublishMetadataInputs2 = _interopRequireDefault(_PublishMetadataInputs);
|
|
|
|
var _ChannelSelect = __webpack_require__(79);
|
|
|
|
var _ChannelSelect2 = _interopRequireDefault(_ChannelSelect);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
|
|
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
|
|
|
|
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
|
|
|
|
var PublishDetails = function (_React$Component) {
|
|
_inherits(PublishDetails, _React$Component);
|
|
|
|
function PublishDetails(props) {
|
|
_classCallCheck(this, PublishDetails);
|
|
|
|
var _this = _possibleConstructorReturn(this, (PublishDetails.__proto__ || Object.getPrototypeOf(PublishDetails)).call(this, props));
|
|
|
|
_this.onPublishSubmit = _this.onPublishSubmit.bind(_this);
|
|
return _this;
|
|
}
|
|
|
|
_createClass(PublishDetails, [{
|
|
key: 'onPublishSubmit',
|
|
value: function onPublishSubmit() {
|
|
this.props.startPublish(this.props.history);
|
|
}
|
|
}, {
|
|
key: 'render',
|
|
value: function render() {
|
|
return _react2.default.createElement(
|
|
'div',
|
|
{ className: 'row row--no-bottom' },
|
|
_react2.default.createElement(
|
|
'div',
|
|
{ className: 'column column--10' },
|
|
_react2.default.createElement(_PublishTitleInput2.default, null)
|
|
),
|
|
_react2.default.createElement(
|
|
'div',
|
|
{ className: 'column column--5 column--sml-10' },
|
|
_react2.default.createElement(
|
|
'div',
|
|
{ className: 'row row--padded' },
|
|
_react2.default.createElement(_Dropzone2.default, null)
|
|
)
|
|
),
|
|
_react2.default.createElement(
|
|
'div',
|
|
{ className: 'column column--5 column--sml-10 align-content-top' },
|
|
_react2.default.createElement(
|
|
'div',
|
|
{ id: 'publish-active-area', className: 'row row--padded' },
|
|
_react2.default.createElement(
|
|
'div',
|
|
{ className: 'row row--padded row--no-top row--wide' },
|
|
_react2.default.createElement(_PublishUrlInput2.default, null)
|
|
),
|
|
_react2.default.createElement(
|
|
'div',
|
|
{ className: 'row row--padded row--no-top row--wide' },
|
|
_react2.default.createElement(_ChannelSelect2.default, null)
|
|
),
|
|
this.props.file.type === 'video/mp4' && _react2.default.createElement(
|
|
'div',
|
|
{ className: 'row row--padded row--no-top row--wide ' },
|
|
_react2.default.createElement(_PublishThumbnailInput2.default, null)
|
|
),
|
|
_react2.default.createElement(
|
|
'div',
|
|
{ className: 'row row--padded row--no-top row--no-bottom row--wide' },
|
|
_react2.default.createElement(_PublishMetadataInputs2.default, null)
|
|
),
|
|
_react2.default.createElement(
|
|
'div',
|
|
{ className: 'row row--wide align-content-center' },
|
|
_react2.default.createElement(
|
|
'button',
|
|
{ id: 'publish-submit', className: 'button--primary button--large', onClick: this.onPublishSubmit },
|
|
'Publish'
|
|
)
|
|
),
|
|
_react2.default.createElement(
|
|
'div',
|
|
{ className: 'row row--padded row--no-bottom align-content-center' },
|
|
_react2.default.createElement(
|
|
'button',
|
|
{ className: 'button--cancel', onClick: this.props.clearFile },
|
|
'Cancel'
|
|
)
|
|
),
|
|
_react2.default.createElement(
|
|
'div',
|
|
{ className: 'row row--short align-content-center' },
|
|
_react2.default.createElement(
|
|
'p',
|
|
{ className: 'fine-print' },
|
|
'By clicking \'Publish\', you affirm that you have the rights to publish this content to the LBRY network, and that you understand the properties of publishing it to a decentralized, user-controlled network. ',
|
|
_react2.default.createElement(
|
|
'a',
|
|
{ className: 'link--primary', target: '_blank', href: 'https://lbry.io/learn' },
|
|
'Read more.'
|
|
)
|
|
)
|
|
)
|
|
)
|
|
)
|
|
);
|
|
}
|
|
}]);
|
|
|
|
return PublishDetails;
|
|
}(_react2.default.Component);
|
|
|
|
;
|
|
|
|
exports.default = (0, _reactRouterDom.withRouter)(PublishDetails);
|
|
|
|
/***/ }),
|
|
/* 69 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
|
|
var _reactRedux = __webpack_require__(1);
|
|
|
|
var _publish = __webpack_require__(4);
|
|
|
|
var _view = __webpack_require__(70);
|
|
|
|
var _view2 = _interopRequireDefault(_view);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
var mapStateToProps = function mapStateToProps(_ref) {
|
|
var publish = _ref.publish;
|
|
|
|
return {
|
|
title: publish.metadata.title
|
|
};
|
|
};
|
|
|
|
var mapDispatchToProps = function mapDispatchToProps(dispatch) {
|
|
return {
|
|
onMetadataChange: function onMetadataChange(name, value) {
|
|
dispatch((0, _publish.updateMetadata)(name, value));
|
|
}
|
|
};
|
|
};
|
|
|
|
exports.default = (0, _reactRedux.connect)(mapStateToProps, mapDispatchToProps)(_view2.default);
|
|
|
|
/***/ }),
|
|
/* 70 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
|
|
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
|
|
|
var _react = __webpack_require__(0);
|
|
|
|
var _react2 = _interopRequireDefault(_react);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
|
|
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
|
|
|
|
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
|
|
|
|
var PublishTitleInput = function (_React$Component) {
|
|
_inherits(PublishTitleInput, _React$Component);
|
|
|
|
function PublishTitleInput(props) {
|
|
_classCallCheck(this, PublishTitleInput);
|
|
|
|
var _this = _possibleConstructorReturn(this, (PublishTitleInput.__proto__ || Object.getPrototypeOf(PublishTitleInput)).call(this, props));
|
|
|
|
_this.handleInput = _this.handleInput.bind(_this);
|
|
return _this;
|
|
}
|
|
|
|
_createClass(PublishTitleInput, [{
|
|
key: 'handleInput',
|
|
value: function handleInput(e) {
|
|
var name = e.target.name;
|
|
var value = e.target.value;
|
|
this.props.onMetadataChange(name, value);
|
|
}
|
|
}, {
|
|
key: 'render',
|
|
value: function render() {
|
|
return _react2.default.createElement('input', { type: 'text', id: 'publish-title', className: 'input-text text--large input-text--full-width', name: 'title', placeholder: 'Give your post a title...', onChange: this.handleInput, value: this.props.title });
|
|
}
|
|
}]);
|
|
|
|
return PublishTitleInput;
|
|
}(_react2.default.Component);
|
|
|
|
exports.default = PublishTitleInput;
|
|
|
|
/***/ }),
|
|
/* 71 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
|
|
var _publish = __webpack_require__(4);
|
|
|
|
var _reactRedux = __webpack_require__(1);
|
|
|
|
var _view = __webpack_require__(72);
|
|
|
|
var _view2 = _interopRequireDefault(_view);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
var mapStateToProps = function mapStateToProps(_ref) {
|
|
var channel = _ref.channel,
|
|
publish = _ref.publish;
|
|
|
|
return {
|
|
loggedInChannelName: channel.loggedInChannel.name,
|
|
loggedInChannelShortId: channel.loggedInChannel.shortId,
|
|
fileName: publish.file.name,
|
|
publishInChannel: publish.publishInChannel,
|
|
selectedChannel: publish.selectedChannel,
|
|
claim: publish.claim,
|
|
urlError: publish.error.url
|
|
};
|
|
};
|
|
|
|
var mapDispatchToProps = function mapDispatchToProps(dispatch) {
|
|
return {
|
|
onClaimChange: function onClaimChange(value) {
|
|
dispatch((0, _publish.updateClaim)(value));
|
|
dispatch((0, _publish.updateError)('publishSubmit', null));
|
|
},
|
|
onUrlError: function onUrlError(value) {
|
|
dispatch((0, _publish.updateError)('url', value));
|
|
}
|
|
};
|
|
};
|
|
|
|
exports.default = (0, _reactRedux.connect)(mapStateToProps, mapDispatchToProps)(_view2.default);
|
|
|
|
/***/ }),
|
|
/* 72 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
|
|
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
|
|
|
var _react = __webpack_require__(0);
|
|
|
|
var _react2 = _interopRequireDefault(_react);
|
|
|
|
var _request = __webpack_require__(9);
|
|
|
|
var _request2 = _interopRequireDefault(_request);
|
|
|
|
var _PublishUrlMiddleDisplay = __webpack_require__(73);
|
|
|
|
var _PublishUrlMiddleDisplay2 = _interopRequireDefault(_PublishUrlMiddleDisplay);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
|
|
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
|
|
|
|
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
|
|
|
|
var PublishUrlInput = function (_React$Component) {
|
|
_inherits(PublishUrlInput, _React$Component);
|
|
|
|
function PublishUrlInput(props) {
|
|
_classCallCheck(this, PublishUrlInput);
|
|
|
|
var _this = _possibleConstructorReturn(this, (PublishUrlInput.__proto__ || Object.getPrototypeOf(PublishUrlInput)).call(this, props));
|
|
|
|
_this.handleInput = _this.handleInput.bind(_this);
|
|
return _this;
|
|
}
|
|
|
|
_createClass(PublishUrlInput, [{
|
|
key: 'componentDidMount',
|
|
value: function componentDidMount() {
|
|
var _props = this.props,
|
|
claim = _props.claim,
|
|
fileName = _props.fileName;
|
|
|
|
if (!claim) {
|
|
this.setClaimName(fileName);
|
|
}
|
|
}
|
|
}, {
|
|
key: 'componentWillReceiveProps',
|
|
value: function componentWillReceiveProps(_ref) {
|
|
var claim = _ref.claim,
|
|
fileName = _ref.fileName;
|
|
|
|
// if a new file was chosen, update the claim name
|
|
if (fileName !== this.props.fileName) {
|
|
return this.setClaimName(fileName);
|
|
}
|
|
// if the claim has updated, check its availability
|
|
if (claim !== this.props.claim) {
|
|
this.validateClaim(claim);
|
|
}
|
|
}
|
|
}, {
|
|
key: 'handleInput',
|
|
value: function handleInput(event) {
|
|
var value = event.target.value;
|
|
value = this.cleanseInput(value);
|
|
// update the state
|
|
this.props.onClaimChange(value);
|
|
}
|
|
}, {
|
|
key: 'cleanseInput',
|
|
value: function cleanseInput(input) {
|
|
input = input.replace(/\s+/g, '-'); // replace spaces with dashes
|
|
input = input.replace(/[^A-Za-z0-9-]/g, ''); // remove all characters that are not A-Z, a-z, 0-9, or '-'
|
|
return input;
|
|
}
|
|
}, {
|
|
key: 'setClaimName',
|
|
value: function setClaimName(fileName) {
|
|
var fileNameWithoutEnding = fileName.substring(0, fileName.lastIndexOf('.'));
|
|
var cleanClaimName = this.cleanseInput(fileNameWithoutEnding);
|
|
this.props.onClaimChange(cleanClaimName);
|
|
}
|
|
}, {
|
|
key: 'validateClaim',
|
|
value: function validateClaim(claim) {
|
|
var _this2 = this;
|
|
|
|
if (!claim) {
|
|
return this.props.onUrlError('Enter a url above');
|
|
}
|
|
(0, _request2.default)('/api/claim/availability/' + claim).then(function () {
|
|
_this2.props.onUrlError(null);
|
|
}).catch(function (error) {
|
|
_this2.props.onUrlError(error.message);
|
|
});
|
|
}
|
|
}, {
|
|
key: 'render',
|
|
value: function render() {
|
|
var _props2 = this.props,
|
|
claim = _props2.claim,
|
|
loggedInChannelName = _props2.loggedInChannelName,
|
|
loggedInChannelShortId = _props2.loggedInChannelShortId,
|
|
publishInChannel = _props2.publishInChannel,
|
|
selectedChannel = _props2.selectedChannel,
|
|
urlError = _props2.urlError;
|
|
|
|
return _react2.default.createElement(
|
|
'div',
|
|
{ className: 'column column--10 column--sml-10' },
|
|
_react2.default.createElement(
|
|
'div',
|
|
{ className: 'input-text--primary span--relative' },
|
|
_react2.default.createElement(
|
|
'span',
|
|
{ className: 'url-text--secondary' },
|
|
'spee.ch / '
|
|
),
|
|
_react2.default.createElement(_PublishUrlMiddleDisplay2.default, {
|
|
publishInChannel: publishInChannel,
|
|
selectedChannel: selectedChannel,
|
|
loggedInChannelName: loggedInChannelName,
|
|
loggedInChannelShortId: loggedInChannelShortId
|
|
}),
|
|
_react2.default.createElement('input', { type: 'text', id: 'claim-name-input', className: 'input-text', name: 'claim', placeholder: 'your-url-here', onChange: this.handleInput, value: claim }),
|
|
claim && !urlError && _react2.default.createElement(
|
|
'span',
|
|
{ id: 'input-success-claim-name', className: 'info-message--success span--absolute' },
|
|
'\u2713'
|
|
),
|
|
urlError && _react2.default.createElement(
|
|
'span',
|
|
{ id: 'input-success-channel-name', className: 'info-message--failure span--absolute' },
|
|
'\u2716'
|
|
)
|
|
),
|
|
_react2.default.createElement(
|
|
'div',
|
|
null,
|
|
urlError ? _react2.default.createElement(
|
|
'p',
|
|
{ id: 'input-error-claim-name', className: 'info-message--failure' },
|
|
urlError
|
|
) : _react2.default.createElement(
|
|
'p',
|
|
{ className: 'info-message' },
|
|
'Choose a custom url'
|
|
)
|
|
)
|
|
);
|
|
}
|
|
}]);
|
|
|
|
return PublishUrlInput;
|
|
}(_react2.default.Component);
|
|
|
|
exports.default = PublishUrlInput;
|
|
|
|
/***/ }),
|
|
/* 73 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
|
|
var _react = __webpack_require__(0);
|
|
|
|
var _react2 = _interopRequireDefault(_react);
|
|
|
|
var _propTypes = __webpack_require__(12);
|
|
|
|
var _propTypes2 = _interopRequireDefault(_propTypes);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
function UrlMiddle(_ref) {
|
|
var publishInChannel = _ref.publishInChannel,
|
|
selectedChannel = _ref.selectedChannel,
|
|
loggedInChannelName = _ref.loggedInChannelName,
|
|
loggedInChannelShortId = _ref.loggedInChannelShortId;
|
|
|
|
if (publishInChannel) {
|
|
if (selectedChannel === loggedInChannelName) {
|
|
return _react2.default.createElement(
|
|
'span',
|
|
{ id: 'url-channel', className: 'url-text--secondary' },
|
|
loggedInChannelName,
|
|
':',
|
|
loggedInChannelShortId,
|
|
' /'
|
|
);
|
|
}
|
|
return _react2.default.createElement(
|
|
'span',
|
|
{ id: 'url-channel-placeholder', className: 'url-text--secondary tooltip' },
|
|
'@channel',
|
|
_react2.default.createElement(
|
|
'span',
|
|
{
|
|
className: 'tooltip-text' },
|
|
'Select a channel below'
|
|
),
|
|
' /'
|
|
);
|
|
}
|
|
return _react2.default.createElement(
|
|
'span',
|
|
{ id: 'url-no-channel-placeholder', className: 'url-text--secondary tooltip' },
|
|
'xyz',
|
|
_react2.default.createElement(
|
|
'span',
|
|
{ className: 'tooltip-text' },
|
|
'This will be a random id'
|
|
),
|
|
' /'
|
|
);
|
|
}
|
|
|
|
UrlMiddle.propTypes = {
|
|
publishInChannel: _propTypes2.default.bool.isRequired,
|
|
loggedInChannelName: _propTypes2.default.string,
|
|
loggedInChannelShortId: _propTypes2.default.string
|
|
};
|
|
|
|
exports.default = UrlMiddle;
|
|
|
|
/***/ }),
|
|
/* 74 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
|
|
var _reactRedux = __webpack_require__(1);
|
|
|
|
var _publish = __webpack_require__(4);
|
|
|
|
var _view = __webpack_require__(75);
|
|
|
|
var _view2 = _interopRequireDefault(_view);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
var mapStateToProps = function mapStateToProps(_ref) {
|
|
var file = _ref.publish.file;
|
|
|
|
return {
|
|
file: file
|
|
};
|
|
};
|
|
|
|
var mapDispatchToProps = {
|
|
onNewThumbnail: _publish.onNewThumbnail
|
|
};
|
|
|
|
exports.default = (0, _reactRedux.connect)(mapStateToProps, mapDispatchToProps)(_view2.default);
|
|
|
|
/***/ }),
|
|
/* 75 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
|
|
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
|
|
|
var _react = __webpack_require__(0);
|
|
|
|
var _react2 = _interopRequireDefault(_react);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
|
|
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
|
|
|
|
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
|
|
|
|
function dataURItoBlob(dataURI) {
|
|
// convert base64/URLEncoded data component to raw binary data held in a string
|
|
var byteString = atob(dataURI.split(',')[1]);
|
|
// separate out the mime component
|
|
var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];
|
|
// write the bytes of the string to a typed array
|
|
var ia = new Uint8Array(byteString.length);
|
|
for (var i = 0; i < byteString.length; i++) {
|
|
ia[i] = byteString.charCodeAt(i);
|
|
}
|
|
return new Blob([ia], { type: mimeString });
|
|
}
|
|
|
|
var PublishThumbnailInput = function (_React$Component) {
|
|
_inherits(PublishThumbnailInput, _React$Component);
|
|
|
|
function PublishThumbnailInput(props) {
|
|
_classCallCheck(this, PublishThumbnailInput);
|
|
|
|
var _this = _possibleConstructorReturn(this, (PublishThumbnailInput.__proto__ || Object.getPrototypeOf(PublishThumbnailInput)).call(this, props));
|
|
|
|
_this.state = {
|
|
videoSource: null,
|
|
error: null,
|
|
sliderMinRange: 1,
|
|
sliderMaxRange: null,
|
|
sliderValue: null
|
|
};
|
|
_this.handleVideoLoadedData = _this.handleVideoLoadedData.bind(_this);
|
|
_this.handleSliderChange = _this.handleSliderChange.bind(_this);
|
|
_this.createThumbnail = _this.createThumbnail.bind(_this);
|
|
return _this;
|
|
}
|
|
|
|
_createClass(PublishThumbnailInput, [{
|
|
key: 'componentDidMount',
|
|
value: function componentDidMount() {
|
|
var file = this.props.file;
|
|
|
|
this.setVideoSource(file);
|
|
}
|
|
}, {
|
|
key: 'componentWillReceiveProps',
|
|
value: function componentWillReceiveProps(nextProps) {
|
|
// if file changes
|
|
if (nextProps.file && nextProps.file !== this.props.file) {
|
|
var file = nextProps.file;
|
|
|
|
this.setVideoSource(file);
|
|
};
|
|
}
|
|
}, {
|
|
key: 'setVideoSource',
|
|
value: function setVideoSource(file) {
|
|
var _this2 = this;
|
|
|
|
var previewReader = new FileReader();
|
|
previewReader.readAsDataURL(file);
|
|
previewReader.onloadend = function () {
|
|
var dataUri = previewReader.result;
|
|
var blob = dataURItoBlob(dataUri);
|
|
var videoSource = URL.createObjectURL(blob);
|
|
_this2.setState({ videoSource: videoSource });
|
|
};
|
|
}
|
|
}, {
|
|
key: 'handleVideoLoadedData',
|
|
value: function handleVideoLoadedData(event) {
|
|
var duration = event.target.duration;
|
|
var totalMinutes = Math.floor(duration / 60);
|
|
var totalSeconds = Math.floor(duration % 60);
|
|
// set the slider
|
|
this.setState({
|
|
sliderMaxRange: duration * 100,
|
|
sliderValue: duration * 100 / 2,
|
|
totalMinutes: totalMinutes,
|
|
totalSeconds: totalSeconds
|
|
});
|
|
// update the current time of the video
|
|
var video = document.getElementById('video-thumb-player');
|
|
video.currentTime = duration / 2;
|
|
}
|
|
}, {
|
|
key: 'handleSliderChange',
|
|
value: function handleSliderChange(event) {
|
|
var value = parseInt(event.target.value);
|
|
// update the slider value
|
|
this.setState({
|
|
sliderValue: value
|
|
});
|
|
// update the current time of the video
|
|
var video = document.getElementById('video-thumb-player');
|
|
video.currentTime = value / 100;
|
|
}
|
|
}, {
|
|
key: 'createThumbnail',
|
|
value: function createThumbnail() {
|
|
// take a snapshot
|
|
var video = document.getElementById('video-thumb-player');
|
|
var canvas = document.createElement('canvas');
|
|
canvas.width = video.videoWidth;
|
|
canvas.height = video.videoHeight;
|
|
canvas.getContext('2d').drawImage(video, 0, 0, canvas.width, canvas.height);
|
|
var dataUrl = canvas.toDataURL();
|
|
var blob = dataURItoBlob(dataUrl);
|
|
var snapshot = new File([blob], 'thumbnail.png', {
|
|
type: 'image/png'
|
|
});
|
|
// set the thumbnail in redux store
|
|
if (snapshot) {
|
|
this.props.onNewThumbnail(snapshot);
|
|
}
|
|
}
|
|
}, {
|
|
key: 'render',
|
|
value: function render() {
|
|
var _state = this.state,
|
|
error = _state.error,
|
|
videoSource = _state.videoSource,
|
|
sliderMinRange = _state.sliderMinRange,
|
|
sliderMaxRange = _state.sliderMaxRange,
|
|
sliderValue = _state.sliderValue,
|
|
totalMinutes = _state.totalMinutes,
|
|
totalSeconds = _state.totalSeconds;
|
|
|
|
return _react2.default.createElement(
|
|
'div',
|
|
null,
|
|
_react2.default.createElement(
|
|
'label',
|
|
{ className: 'label' },
|
|
'Thumbnail:'
|
|
),
|
|
_react2.default.createElement('video', {
|
|
id: 'video-thumb-player',
|
|
preload: 'metadata',
|
|
muted: true,
|
|
style: { display: 'none' },
|
|
playsInline: true,
|
|
onLoadedData: this.handleVideoLoadedData,
|
|
src: videoSource,
|
|
onSeeked: this.createThumbnail
|
|
}),
|
|
sliderValue ? _react2.default.createElement(
|
|
'div',
|
|
null,
|
|
_react2.default.createElement(
|
|
'div',
|
|
{ className: 'flex-container--row flex-container--space-between-center', style: { width: '100%' } },
|
|
_react2.default.createElement(
|
|
'span',
|
|
{ className: 'info-message' },
|
|
'0\'00"'
|
|
),
|
|
_react2.default.createElement(
|
|
'span',
|
|
{ className: 'info-message' },
|
|
totalMinutes,
|
|
'\'',
|
|
totalSeconds,
|
|
'"'
|
|
)
|
|
),
|
|
_react2.default.createElement(
|
|
'div',
|
|
null,
|
|
_react2.default.createElement('input', {
|
|
type: 'range',
|
|
min: sliderMinRange,
|
|
max: sliderMaxRange,
|
|
value: sliderValue,
|
|
className: 'slider',
|
|
onChange: this.handleSliderChange
|
|
})
|
|
)
|
|
) : _react2.default.createElement(
|
|
'p',
|
|
{ className: 'info-message' },
|
|
'loading... '
|
|
),
|
|
error ? _react2.default.createElement(
|
|
'p',
|
|
{ className: 'info-message--failure' },
|
|
error
|
|
) : _react2.default.createElement(
|
|
'p',
|
|
{ className: 'info-message' },
|
|
'Use slider to set thumbnail'
|
|
)
|
|
);
|
|
}
|
|
}]);
|
|
|
|
return PublishThumbnailInput;
|
|
}(_react2.default.Component);
|
|
|
|
exports.default = PublishThumbnailInput;
|
|
|
|
/***/ }),
|
|
/* 76 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
|
|
var _reactRedux = __webpack_require__(1);
|
|
|
|
var _publish = __webpack_require__(4);
|
|
|
|
var _view = __webpack_require__(77);
|
|
|
|
var _view2 = _interopRequireDefault(_view);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
var mapStateToProps = function mapStateToProps(_ref) {
|
|
var publish = _ref.publish;
|
|
|
|
return {
|
|
showMetadataInputs: publish.showMetadataInputs,
|
|
description: publish.metadata.description,
|
|
license: publish.metadata.license,
|
|
nsfw: publish.metadata.nsfw
|
|
};
|
|
};
|
|
|
|
var mapDispatchToProps = function mapDispatchToProps(dispatch) {
|
|
return {
|
|
onMetadataChange: function onMetadataChange(name, value) {
|
|
dispatch((0, _publish.updateMetadata)(name, value));
|
|
},
|
|
onToggleMetadataInputs: function onToggleMetadataInputs(value) {
|
|
dispatch((0, _publish.toggleMetadataInputs)(value));
|
|
}
|
|
};
|
|
};
|
|
|
|
exports.default = (0, _reactRedux.connect)(mapStateToProps, mapDispatchToProps)(_view2.default);
|
|
|
|
/***/ }),
|
|
/* 77 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
|
|
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
|
|
|
var _react = __webpack_require__(0);
|
|
|
|
var _react2 = _interopRequireDefault(_react);
|
|
|
|
var _ExpandingTextArea = __webpack_require__(78);
|
|
|
|
var _ExpandingTextArea2 = _interopRequireDefault(_ExpandingTextArea);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
|
|
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
|
|
|
|
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
|
|
|
|
var PublishMetadataInputs = function (_React$Component) {
|
|
_inherits(PublishMetadataInputs, _React$Component);
|
|
|
|
function PublishMetadataInputs(props) {
|
|
_classCallCheck(this, PublishMetadataInputs);
|
|
|
|
var _this = _possibleConstructorReturn(this, (PublishMetadataInputs.__proto__ || Object.getPrototypeOf(PublishMetadataInputs)).call(this, props));
|
|
|
|
_this.toggleShowInputs = _this.toggleShowInputs.bind(_this);
|
|
_this.handleInput = _this.handleInput.bind(_this);
|
|
_this.handleSelect = _this.handleSelect.bind(_this);
|
|
return _this;
|
|
}
|
|
|
|
_createClass(PublishMetadataInputs, [{
|
|
key: 'toggleShowInputs',
|
|
value: function toggleShowInputs() {
|
|
this.props.onToggleMetadataInputs(!this.props.showMetadataInputs);
|
|
}
|
|
}, {
|
|
key: 'handleInput',
|
|
value: function handleInput(event) {
|
|
var target = event.target;
|
|
var value = target.type === 'checkbox' ? target.checked : target.value;
|
|
var name = target.name;
|
|
this.props.onMetadataChange(name, value);
|
|
}
|
|
}, {
|
|
key: 'handleSelect',
|
|
value: function handleSelect(event) {
|
|
var name = event.target.name;
|
|
var selectedOption = event.target.selectedOptions[0].value;
|
|
this.props.onMetadataChange(name, selectedOption);
|
|
}
|
|
}, {
|
|
key: 'render',
|
|
value: function render() {
|
|
return _react2.default.createElement(
|
|
'div',
|
|
{ id: 'publish-details', className: 'row row--padded row--no-top row--wide' },
|
|
this.props.showMetadataInputs && _react2.default.createElement(
|
|
'div',
|
|
null,
|
|
_react2.default.createElement(
|
|
'div',
|
|
{ className: 'row row--no-top' },
|
|
_react2.default.createElement(
|
|
'div',
|
|
{ className: 'column column--3 column--med-10 align-content-top' },
|
|
_react2.default.createElement(
|
|
'label',
|
|
{ htmlFor: 'publish-license', className: 'label' },
|
|
'Description:'
|
|
)
|
|
),
|
|
_react2.default.createElement(
|
|
'div',
|
|
{ className: 'column column--7 column--sml-10' },
|
|
_react2.default.createElement(_ExpandingTextArea2.default, {
|
|
id: 'publish-description',
|
|
className: 'textarea textarea--primary textarea--full-width',
|
|
rows: 1,
|
|
maxLength: 2000,
|
|
style: { maxHeight: 200 },
|
|
name: 'description',
|
|
placeholder: 'Optional description',
|
|
value: this.props.description,
|
|
onChange: this.handleInput })
|
|
)
|
|
),
|
|
_react2.default.createElement(
|
|
'div',
|
|
{ className: 'row row--no-top' },
|
|
_react2.default.createElement(
|
|
'div',
|
|
{ className: 'column column--3 column--med-10' },
|
|
_react2.default.createElement(
|
|
'label',
|
|
{ htmlFor: 'publish-license', className: 'label' },
|
|
'License:'
|
|
)
|
|
),
|
|
_react2.default.createElement(
|
|
'div',
|
|
{ className: 'column column--7 column--sml-10' },
|
|
_react2.default.createElement(
|
|
'select',
|
|
{ type: 'text', name: 'license', id: 'publish-license', className: 'select select--primary', onChange: this.handleSelect },
|
|
_react2.default.createElement(
|
|
'option',
|
|
{ value: ' ' },
|
|
'Unspecified'
|
|
),
|
|
_react2.default.createElement(
|
|
'option',
|
|
{ value: 'Public Domain' },
|
|
'Public Domain'
|
|
),
|
|
_react2.default.createElement(
|
|
'option',
|
|
{ value: 'Creative Commons' },
|
|
'Creative Commons'
|
|
)
|
|
)
|
|
)
|
|
),
|
|
_react2.default.createElement(
|
|
'div',
|
|
{ className: 'row row--no-top' },
|
|
_react2.default.createElement(
|
|
'div',
|
|
{ className: 'column column--3' },
|
|
_react2.default.createElement(
|
|
'label',
|
|
{ htmlFor: 'publish-nsfw', className: 'label' },
|
|
'Mature:'
|
|
)
|
|
),
|
|
_react2.default.createElement(
|
|
'div',
|
|
{ className: 'column column--7' },
|
|
_react2.default.createElement('input', { className: 'input-checkbox', type: 'checkbox', id: 'publish-nsfw', name: 'nsfw', value: this.props.nsfw, onChange: this.handleInput })
|
|
)
|
|
)
|
|
),
|
|
_react2.default.createElement(
|
|
'button',
|
|
{ className: 'button--secondary', onClick: this.toggleShowInputs },
|
|
this.props.showMetadataInputs ? 'less' : 'more'
|
|
)
|
|
);
|
|
}
|
|
}]);
|
|
|
|
return PublishMetadataInputs;
|
|
}(_react2.default.Component);
|
|
|
|
exports.default = PublishMetadataInputs;
|
|
|
|
/***/ }),
|
|
/* 78 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
|
|
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
|
|
|
|
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
|
|
|
var _react = __webpack_require__(0);
|
|
|
|
var _react2 = _interopRequireDefault(_react);
|
|
|
|
var _propTypes = __webpack_require__(12);
|
|
|
|
var _propTypes2 = _interopRequireDefault(_propTypes);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; }
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
|
|
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
|
|
|
|
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
|
|
|
|
var ExpandingTextarea = function (_Component) {
|
|
_inherits(ExpandingTextarea, _Component);
|
|
|
|
function ExpandingTextarea(props) {
|
|
_classCallCheck(this, ExpandingTextarea);
|
|
|
|
var _this = _possibleConstructorReturn(this, (ExpandingTextarea.__proto__ || Object.getPrototypeOf(ExpandingTextarea)).call(this, props));
|
|
|
|
_this._handleChange = _this._handleChange.bind(_this);
|
|
return _this;
|
|
}
|
|
|
|
_createClass(ExpandingTextarea, [{
|
|
key: 'componentDidMount',
|
|
value: function componentDidMount() {
|
|
this.adjustTextarea({});
|
|
}
|
|
}, {
|
|
key: '_handleChange',
|
|
value: function _handleChange(event) {
|
|
var onChange = this.props.onChange;
|
|
|
|
if (onChange) onChange(event);
|
|
this.adjustTextarea(event);
|
|
}
|
|
}, {
|
|
key: 'adjustTextarea',
|
|
value: function adjustTextarea(_ref) {
|
|
var _ref$target = _ref.target,
|
|
target = _ref$target === undefined ? this.el : _ref$target;
|
|
|
|
target.style.height = 0;
|
|
target.style.height = target.scrollHeight + 'px';
|
|
}
|
|
}, {
|
|
key: 'render',
|
|
value: function render() {
|
|
var _this2 = this;
|
|
|
|
var rest = _objectWithoutProperties(this.props, []);
|
|
|
|
return _react2.default.createElement('textarea', _extends({}, rest, {
|
|
ref: function ref(x) {
|
|
return _this2.el = x;
|
|
},
|
|
onChange: this._handleChange
|
|
}));
|
|
}
|
|
}]);
|
|
|
|
return ExpandingTextarea;
|
|
}(_react.Component);
|
|
|
|
ExpandingTextarea.propTypes = {
|
|
onChange: _propTypes2.default.func
|
|
};
|
|
|
|
exports.default = ExpandingTextarea;
|
|
|
|
/***/ }),
|
|
/* 79 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
|
|
var _reactRedux = __webpack_require__(1);
|
|
|
|
var _publish = __webpack_require__(4);
|
|
|
|
var _view = __webpack_require__(80);
|
|
|
|
var _view2 = _interopRequireDefault(_view);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
var mapStateToProps = function mapStateToProps(_ref) {
|
|
var channel = _ref.channel,
|
|
publish = _ref.publish;
|
|
|
|
return {
|
|
loggedInChannelName: channel.loggedInChannel.name,
|
|
publishInChannel: publish.publishInChannel,
|
|
selectedChannel: publish.selectedChannel,
|
|
channelError: publish.error.channel
|
|
};
|
|
};
|
|
|
|
var mapDispatchToProps = function mapDispatchToProps(dispatch) {
|
|
return {
|
|
onPublishInChannelChange: function onPublishInChannelChange(value) {
|
|
dispatch((0, _publish.updateError)('channel', null));
|
|
dispatch((0, _publish.setPublishInChannel)(value));
|
|
},
|
|
onChannelSelect: function onChannelSelect(value) {
|
|
dispatch((0, _publish.updateError)('channel', null));
|
|
dispatch((0, _publish.updateSelectedChannel)(value));
|
|
}
|
|
};
|
|
};
|
|
|
|
exports.default = (0, _reactRedux.connect)(mapStateToProps, mapDispatchToProps)(_view2.default);
|
|
|
|
/***/ }),
|
|
/* 80 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
|
|
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
|
|
|
var _react = __webpack_require__(0);
|
|
|
|
var _react2 = _interopRequireDefault(_react);
|
|
|
|
var _ChannelLoginForm = __webpack_require__(31);
|
|
|
|
var _ChannelLoginForm2 = _interopRequireDefault(_ChannelLoginForm);
|
|
|
|
var _ChannelCreateForm = __webpack_require__(32);
|
|
|
|
var _ChannelCreateForm2 = _interopRequireDefault(_ChannelCreateForm);
|
|
|
|
var _publish_channel_select_states = __webpack_require__(33);
|
|
|
|
var states = _interopRequireWildcard(_publish_channel_select_states);
|
|
|
|
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
|
|
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
|
|
|
|
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
|
|
|
|
var ChannelSelect = function (_React$Component) {
|
|
_inherits(ChannelSelect, _React$Component);
|
|
|
|
function ChannelSelect(props) {
|
|
_classCallCheck(this, ChannelSelect);
|
|
|
|
var _this = _possibleConstructorReturn(this, (ChannelSelect.__proto__ || Object.getPrototypeOf(ChannelSelect)).call(this, props));
|
|
|
|
_this.toggleAnonymousPublish = _this.toggleAnonymousPublish.bind(_this);
|
|
_this.handleSelection = _this.handleSelection.bind(_this);
|
|
return _this;
|
|
}
|
|
|
|
_createClass(ChannelSelect, [{
|
|
key: 'toggleAnonymousPublish',
|
|
value: function toggleAnonymousPublish(event) {
|
|
var value = event.target.value;
|
|
if (value === 'anonymous') {
|
|
this.props.onPublishInChannelChange(false);
|
|
} else {
|
|
this.props.onPublishInChannelChange(true);
|
|
}
|
|
}
|
|
}, {
|
|
key: 'handleSelection',
|
|
value: function handleSelection(event) {
|
|
var selectedOption = event.target.selectedOptions[0].value;
|
|
this.props.onChannelSelect(selectedOption);
|
|
}
|
|
}, {
|
|
key: 'render',
|
|
value: function render() {
|
|
return _react2.default.createElement(
|
|
'div',
|
|
null,
|
|
_react2.default.createElement(
|
|
'form',
|
|
null,
|
|
_react2.default.createElement(
|
|
'div',
|
|
{ className: 'column column--3 column--med-10' },
|
|
_react2.default.createElement('input', { type: 'radio', name: 'anonymous-or-channel', id: 'anonymous-radio', className: 'input-radio', value: 'anonymous', checked: !this.props.publishInChannel, onChange: this.toggleAnonymousPublish }),
|
|
_react2.default.createElement(
|
|
'label',
|
|
{ className: 'label label--pointer', htmlFor: 'anonymous-radio' },
|
|
'Anonymous'
|
|
)
|
|
),
|
|
_react2.default.createElement(
|
|
'div',
|
|
{ className: 'column column--7 column--med-10' },
|
|
_react2.default.createElement('input', { type: 'radio', name: 'anonymous-or-channel', id: 'channel-radio', className: 'input-radio', value: 'in a channel', checked: this.props.publishInChannel, onChange: this.toggleAnonymousPublish }),
|
|
_react2.default.createElement(
|
|
'label',
|
|
{ className: 'label label--pointer', htmlFor: 'channel-radio' },
|
|
'In a channel'
|
|
)
|
|
),
|
|
this.props.channelError ? _react2.default.createElement(
|
|
'p',
|
|
{ className: 'info-message--failure' },
|
|
this.props.channelError
|
|
) : _react2.default.createElement(
|
|
'p',
|
|
{ className: 'info-message' },
|
|
'Publish anonymously or in a channel'
|
|
)
|
|
),
|
|
this.props.publishInChannel && _react2.default.createElement(
|
|
'div',
|
|
null,
|
|
_react2.default.createElement(
|
|
'div',
|
|
{ className: 'column column--3' },
|
|
_react2.default.createElement(
|
|
'label',
|
|
{ className: 'label', htmlFor: 'channel-name-select' },
|
|
'Channel:'
|
|
)
|
|
),
|
|
_react2.default.createElement(
|
|
'div',
|
|
{ className: 'column column--7' },
|
|
_react2.default.createElement(
|
|
'select',
|
|
{ type: 'text', id: 'channel-name-select', className: 'select select--arrow', value: this.props.selectedChannel, onChange: this.handleSelection },
|
|
this.props.loggedInChannelName && _react2.default.createElement(
|
|
'option',
|
|
{ value: this.props.loggedInChannelName, id: 'publish-channel-select-channel-option' },
|
|
this.props.loggedInChannelName
|
|
),
|
|
_react2.default.createElement(
|
|
'option',
|
|
{ value: states.LOGIN },
|
|
'Existing'
|
|
),
|
|
_react2.default.createElement(
|
|
'option',
|
|
{ value: states.CREATE },
|
|
'New'
|
|
)
|
|
)
|
|
),
|
|
this.props.selectedChannel === states.LOGIN && _react2.default.createElement(_ChannelLoginForm2.default, null),
|
|
this.props.selectedChannel === states.CREATE && _react2.default.createElement(_ChannelCreateForm2.default, null)
|
|
)
|
|
);
|
|
}
|
|
}]);
|
|
|
|
return ChannelSelect;
|
|
}(_react2.default.Component);
|
|
|
|
exports.default = ChannelSelect;
|
|
|
|
/***/ }),
|
|
/* 81 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
|
|
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
|
|
|
var _react = __webpack_require__(0);
|
|
|
|
var _react2 = _interopRequireDefault(_react);
|
|
|
|
var _request = __webpack_require__(9);
|
|
|
|
var _request2 = _interopRequireDefault(_request);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
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; }
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
|
|
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
|
|
|
|
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
|
|
|
|
var ChannelLoginForm = function (_React$Component) {
|
|
_inherits(ChannelLoginForm, _React$Component);
|
|
|
|
function ChannelLoginForm(props) {
|
|
_classCallCheck(this, ChannelLoginForm);
|
|
|
|
var _this = _possibleConstructorReturn(this, (ChannelLoginForm.__proto__ || Object.getPrototypeOf(ChannelLoginForm)).call(this, props));
|
|
|
|
_this.state = {
|
|
error: null,
|
|
name: '',
|
|
password: ''
|
|
};
|
|
_this.handleInput = _this.handleInput.bind(_this);
|
|
_this.loginToChannel = _this.loginToChannel.bind(_this);
|
|
return _this;
|
|
}
|
|
|
|
_createClass(ChannelLoginForm, [{
|
|
key: 'handleInput',
|
|
value: function handleInput(event) {
|
|
var name = event.target.name;
|
|
var value = event.target.value;
|
|
this.setState(_defineProperty({}, name, value));
|
|
}
|
|
}, {
|
|
key: 'loginToChannel',
|
|
value: function loginToChannel(event) {
|
|
var _this2 = this;
|
|
|
|
event.preventDefault();
|
|
var params = {
|
|
method: 'POST',
|
|
body: JSON.stringify({ username: this.state.name, password: this.state.password }),
|
|
headers: new Headers({
|
|
'Content-Type': 'application/json'
|
|
}),
|
|
credentials: 'include'
|
|
};
|
|
(0, _request2.default)('login', params).then(function (_ref) {
|
|
var success = _ref.success,
|
|
channelName = _ref.channelName,
|
|
shortChannelId = _ref.shortChannelId,
|
|
channelClaimId = _ref.channelClaimId,
|
|
message = _ref.message;
|
|
|
|
if (success) {
|
|
_this2.props.onChannelLogin(channelName, shortChannelId, channelClaimId);
|
|
} else {
|
|
_this2.setState({ 'error': message });
|
|
};
|
|
}).catch(function (error) {
|
|
if (error.message) {
|
|
_this2.setState({ 'error': error.message });
|
|
} else {
|
|
_this2.setState({ 'error': error });
|
|
}
|
|
});
|
|
}
|
|
}, {
|
|
key: 'render',
|
|
value: function render() {
|
|
return _react2.default.createElement(
|
|
'form',
|
|
{ id: 'channel-login-form' },
|
|
_react2.default.createElement(
|
|
'div',
|
|
{ className: 'row row--wide row--short' },
|
|
_react2.default.createElement(
|
|
'div',
|
|
{ className: 'column column--3 column--sml-10' },
|
|
_react2.default.createElement(
|
|
'label',
|
|
{ className: 'label', htmlFor: 'channel-login-name-input' },
|
|
'Name:'
|
|
)
|
|
),
|
|
_react2.default.createElement(
|
|
'div',
|
|
{ className: 'column column--6 column--sml-10' },
|
|
_react2.default.createElement(
|
|
'div',
|
|
{ className: 'input-text--primary flex-container--row flex-container--left-bottom' },
|
|
_react2.default.createElement(
|
|
'span',
|
|
null,
|
|
'@'
|
|
),
|
|
_react2.default.createElement('input', { type: 'text', id: 'channel-login-name-input', className: 'input-text', name: 'name', placeholder: 'Your Channel Name', value: this.state.channelName, onChange: this.handleInput })
|
|
)
|
|
)
|
|
),
|
|
_react2.default.createElement(
|
|
'div',
|
|
{ className: 'row row--wide row--short' },
|
|
_react2.default.createElement(
|
|
'div',
|
|
{ className: 'column column--3 column--sml-10' },
|
|
_react2.default.createElement(
|
|
'label',
|
|
{ className: 'label', htmlFor: 'channel-login-password-input' },
|
|
'Password:'
|
|
)
|
|
),
|
|
_react2.default.createElement(
|
|
'div',
|
|
{ className: 'column column--6 column--sml-10' },
|
|
_react2.default.createElement(
|
|
'div',
|
|
{ className: 'input-text--primary' },
|
|
_react2.default.createElement('input', { type: 'password', id: 'channel-login-password-input', name: 'password', className: 'input-text', placeholder: '', value: this.state.channelPassword, onChange: this.handleInput })
|
|
)
|
|
)
|
|
),
|
|
this.state.error ? _react2.default.createElement(
|
|
'p',
|
|
{ className: 'info-message--failure' },
|
|
this.state.error
|
|
) : _react2.default.createElement(
|
|
'p',
|
|
{ className: 'info-message' },
|
|
'Enter the name and password for your channel'
|
|
),
|
|
_react2.default.createElement(
|
|
'div',
|
|
{ className: 'row row--wide' },
|
|
_react2.default.createElement(
|
|
'button',
|
|
{ className: 'button--primary', onClick: this.loginToChannel },
|
|
'Authenticate'
|
|
)
|
|
)
|
|
);
|
|
}
|
|
}]);
|
|
|
|
return ChannelLoginForm;
|
|
}(_react2.default.Component);
|
|
|
|
exports.default = ChannelLoginForm;
|
|
|
|
/***/ }),
|
|
/* 82 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
|
|
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
|
|
|
var _react = __webpack_require__(0);
|
|
|
|
var _react2 = _interopRequireDefault(_react);
|
|
|
|
var _ProgressBar = __webpack_require__(23);
|
|
|
|
var _ProgressBar2 = _interopRequireDefault(_ProgressBar);
|
|
|
|
var _request = __webpack_require__(9);
|
|
|
|
var _request2 = _interopRequireDefault(_request);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
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; }
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
|
|
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
|
|
|
|
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
|
|
|
|
var ChannelCreateForm = function (_React$Component) {
|
|
_inherits(ChannelCreateForm, _React$Component);
|
|
|
|
function ChannelCreateForm(props) {
|
|
_classCallCheck(this, ChannelCreateForm);
|
|
|
|
var _this = _possibleConstructorReturn(this, (ChannelCreateForm.__proto__ || Object.getPrototypeOf(ChannelCreateForm)).call(this, props));
|
|
|
|
_this.state = {
|
|
error: null,
|
|
channel: '',
|
|
password: '',
|
|
status: null
|
|
};
|
|
_this.handleChannelInput = _this.handleChannelInput.bind(_this);
|
|
_this.handleInput = _this.handleInput.bind(_this);
|
|
_this.createChannel = _this.createChannel.bind(_this);
|
|
return _this;
|
|
}
|
|
|
|
_createClass(ChannelCreateForm, [{
|
|
key: 'cleanseChannelInput',
|
|
value: function cleanseChannelInput(input) {
|
|
input = input.replace(/\s+/g, '-'); // replace spaces with dashes
|
|
input = input.replace(/[^A-Za-z0-9-]/g, ''); // remove all characters that are not A-Z, a-z, 0-9, or '-'
|
|
return input;
|
|
}
|
|
}, {
|
|
key: 'handleChannelInput',
|
|
value: function handleChannelInput(event) {
|
|
var value = event.target.value;
|
|
value = this.cleanseChannelInput(value);
|
|
this.setState({ channel: value });
|
|
if (value) {
|
|
this.updateIsChannelAvailable(value);
|
|
} else {
|
|
this.setState({ error: 'Please enter a channel name' });
|
|
}
|
|
}
|
|
}, {
|
|
key: 'handleInput',
|
|
value: function handleInput(event) {
|
|
var name = event.target.name;
|
|
var value = event.target.value;
|
|
this.setState(_defineProperty({}, name, value));
|
|
}
|
|
}, {
|
|
key: 'updateIsChannelAvailable',
|
|
value: function updateIsChannelAvailable(channel) {
|
|
var _this2 = this;
|
|
|
|
var channelWithAtSymbol = '@' + channel;
|
|
(0, _request2.default)('/api/channel/availability/' + channelWithAtSymbol).then(function () {
|
|
_this2.setState({ 'error': null });
|
|
}).catch(function (error) {
|
|
_this2.setState({ 'error': error.message });
|
|
});
|
|
}
|
|
}, {
|
|
key: 'checkIsChannelAvailable',
|
|
value: function checkIsChannelAvailable(channel) {
|
|
var channelWithAtSymbol = '@' + channel;
|
|
return (0, _request2.default)('/api/channel/availability/' + channelWithAtSymbol);
|
|
}
|
|
}, {
|
|
key: 'checkIsPasswordProvided',
|
|
value: function checkIsPasswordProvided(password) {
|
|
return new Promise(function (resolve, reject) {
|
|
if (!password || password.length < 1) {
|
|
return reject(new Error('Please provide a password'));
|
|
}
|
|
resolve();
|
|
});
|
|
}
|
|
}, {
|
|
key: 'makePublishChannelRequest',
|
|
value: function makePublishChannelRequest(username, password) {
|
|
var params = {
|
|
method: 'POST',
|
|
body: JSON.stringify({ username: username, password: password }),
|
|
headers: new Headers({
|
|
'Content-Type': 'application/json'
|
|
}),
|
|
credentials: 'include'
|
|
};
|
|
return new Promise(function (resolve, reject) {
|
|
(0, _request2.default)('/signup', params).then(function (result) {
|
|
return resolve(result);
|
|
}).catch(function (error) {
|
|
reject(new Error('Unfortunately, we encountered an error while creating your channel. Please let us know in Discord! ' + error.message));
|
|
});
|
|
});
|
|
}
|
|
}, {
|
|
key: 'createChannel',
|
|
value: function createChannel(event) {
|
|
var _this3 = this;
|
|
|
|
event.preventDefault();
|
|
this.checkIsPasswordProvided(this.state.password).then(function () {
|
|
return _this3.checkIsChannelAvailable(_this3.state.channel);
|
|
}).then(function () {
|
|
_this3.setState({ status: 'We are publishing your new channel. Sit tight...' });
|
|
return _this3.makePublishChannelRequest(_this3.state.channel, _this3.state.password);
|
|
}).then(function (result) {
|
|
_this3.setState({ status: null });
|
|
_this3.props.onChannelLogin(result.channelName, result.shortChannelId, result.channelClaimId);
|
|
}).catch(function (error) {
|
|
if (error.message) {
|
|
_this3.setState({ 'error': error.message, status: null });
|
|
} else {
|
|
_this3.setState({ 'error': error, status: null });
|
|
};
|
|
});
|
|
}
|
|
}, {
|
|
key: 'render',
|
|
value: function render() {
|
|
return _react2.default.createElement(
|
|
'div',
|
|
null,
|
|
!this.state.status ? _react2.default.createElement(
|
|
'form',
|
|
{ id: 'publish-channel-form' },
|
|
_react2.default.createElement(
|
|
'div',
|
|
{ className: 'row row--wide row--short' },
|
|
_react2.default.createElement(
|
|
'div',
|
|
{ className: 'column column--3 column--sml-10' },
|
|
_react2.default.createElement(
|
|
'label',
|
|
{ className: 'label', htmlFor: 'new-channel-name' },
|
|
'Name:'
|
|
)
|
|
),
|
|
_react2.default.createElement(
|
|
'div',
|
|
{ className: 'column column--6 column--sml-10' },
|
|
_react2.default.createElement(
|
|
'div',
|
|
{ className: 'input-text--primary flex-container--row flex-container--left-bottom span--relative' },
|
|
_react2.default.createElement(
|
|
'span',
|
|
null,
|
|
'@'
|
|
),
|
|
_react2.default.createElement('input', { type: 'text', name: 'channel', id: 'new-channel-name', className: 'input-text', placeholder: 'exampleChannelName', value: this.state.channel, onChange: this.handleChannelInput }),
|
|
this.state.channel && !this.state.error && _react2.default.createElement(
|
|
'span',
|
|
{ id: 'input-success-channel-name', className: 'info-message--success span--absolute' },
|
|
'\u2713'
|
|
),
|
|
this.state.error && _react2.default.createElement(
|
|
'span',
|
|
{ id: 'input-success-channel-name', className: 'info-message--failure span--absolute' },
|
|
'\u2716'
|
|
)
|
|
)
|
|
)
|
|
),
|
|
_react2.default.createElement(
|
|
'div',
|
|
{ className: 'row row--wide row--short' },
|
|
_react2.default.createElement(
|
|
'div',
|
|
{ className: 'column column--3 column--sml-10' },
|
|
_react2.default.createElement(
|
|
'label',
|
|
{ className: 'label', htmlFor: 'new-channel-password' },
|
|
'Password:'
|
|
)
|
|
),
|
|
_react2.default.createElement(
|
|
'div',
|
|
{ className: 'column column--6 column--sml-10' },
|
|
_react2.default.createElement(
|
|
'div',
|
|
{ className: 'input-text--primary' },
|
|
_react2.default.createElement('input', { type: 'password', name: 'password', id: 'new-channel-password', className: 'input-text', placeholder: '', value: this.state.password, onChange: this.handleInput })
|
|
)
|
|
)
|
|
),
|
|
this.state.error ? _react2.default.createElement(
|
|
'p',
|
|
{ className: 'info-message--failure' },
|
|
this.state.error
|
|
) : _react2.default.createElement(
|
|
'p',
|
|
{ className: 'info-message' },
|
|
'Choose a name and password for your channel'
|
|
),
|
|
_react2.default.createElement(
|
|
'div',
|
|
{ className: 'row row--wide' },
|
|
_react2.default.createElement(
|
|
'button',
|
|
{ className: 'button--primary', onClick: this.createChannel },
|
|
'Create Channel'
|
|
)
|
|
)
|
|
) : _react2.default.createElement(
|
|
'div',
|
|
null,
|
|
_react2.default.createElement(
|
|
'p',
|
|
{ className: 'fine-print' },
|
|
this.state.status
|
|
),
|
|
_react2.default.createElement(_ProgressBar2.default, { size: 12 })
|
|
)
|
|
);
|
|
}
|
|
}]);
|
|
|
|
return ChannelCreateForm;
|
|
}(_react2.default.Component);
|
|
|
|
exports.default = ChannelCreateForm;
|
|
|
|
/***/ }),
|
|
/* 83 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
|
|
var _react = __webpack_require__(0);
|
|
|
|
var _react2 = _interopRequireDefault(_react);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
var ActiveStatusBar = function ActiveStatusBar() {
|
|
return _react2.default.createElement(
|
|
'span',
|
|
{ className: 'progress-bar progress-bar--active' },
|
|
'| '
|
|
);
|
|
};
|
|
|
|
exports.default = ActiveStatusBar;
|
|
|
|
/***/ }),
|
|
/* 84 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
|
|
var _react = __webpack_require__(0);
|
|
|
|
var _react2 = _interopRequireDefault(_react);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
var InactiveStatusBar = function InactiveStatusBar() {
|
|
return _react2.default.createElement(
|
|
'span',
|
|
{ className: 'progress-bar progress-bar--inactive' },
|
|
'| '
|
|
);
|
|
};
|
|
|
|
exports.default = InactiveStatusBar;
|
|
|
|
/***/ }),
|
|
/* 85 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
|
|
var _reactRedux = __webpack_require__(1);
|
|
|
|
var _publish = __webpack_require__(4);
|
|
|
|
var _view = __webpack_require__(86);
|
|
|
|
var _view2 = _interopRequireDefault(_view);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
var mapStateToProps = function mapStateToProps(_ref) {
|
|
var publish = _ref.publish;
|
|
|
|
return {
|
|
status: publish.status.status,
|
|
message: publish.status.message
|
|
};
|
|
};
|
|
|
|
var mapDispatchToProps = {
|
|
clearFile: _publish.clearFile
|
|
};
|
|
|
|
exports.default = (0, _reactRedux.connect)(mapStateToProps, mapDispatchToProps)(_view2.default);
|
|
|
|
/***/ }),
|
|
/* 86 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
|
|
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
|
|
|
var _react = __webpack_require__(0);
|
|
|
|
var _react2 = _interopRequireDefault(_react);
|
|
|
|
var _ProgressBar = __webpack_require__(23);
|
|
|
|
var _ProgressBar2 = _interopRequireDefault(_ProgressBar);
|
|
|
|
var _publish_claim_states = __webpack_require__(34);
|
|
|
|
var publishStates = _interopRequireWildcard(_publish_claim_states);
|
|
|
|
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
|
|
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
|
|
|
|
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
|
|
|
|
var PublishStatus = function (_React$Component) {
|
|
_inherits(PublishStatus, _React$Component);
|
|
|
|
function PublishStatus() {
|
|
_classCallCheck(this, PublishStatus);
|
|
|
|
return _possibleConstructorReturn(this, (PublishStatus.__proto__ || Object.getPrototypeOf(PublishStatus)).apply(this, arguments));
|
|
}
|
|
|
|
_createClass(PublishStatus, [{
|
|
key: 'render',
|
|
value: function render() {
|
|
var _props = this.props,
|
|
status = _props.status,
|
|
message = _props.message,
|
|
clearFile = _props.clearFile;
|
|
|
|
return _react2.default.createElement(
|
|
'div',
|
|
{ className: 'row row--tall flex-container--column flex-container--center-center' },
|
|
status === publishStates.LOAD_START && _react2.default.createElement(
|
|
'div',
|
|
{ className: 'row align-content-center' },
|
|
_react2.default.createElement(
|
|
'p',
|
|
null,
|
|
'File is loading to server'
|
|
),
|
|
_react2.default.createElement(
|
|
'p',
|
|
{ className: 'blue' },
|
|
'0%'
|
|
)
|
|
),
|
|
status === publishStates.LOADING && _react2.default.createElement(
|
|
'div',
|
|
null,
|
|
_react2.default.createElement(
|
|
'div',
|
|
{ className: 'row align-content-center' },
|
|
_react2.default.createElement(
|
|
'p',
|
|
null,
|
|
'File is loading to server'
|
|
),
|
|
_react2.default.createElement(
|
|
'p',
|
|
{ className: 'blue' },
|
|
message
|
|
)
|
|
)
|
|
),
|
|
status === publishStates.PUBLISHING && _react2.default.createElement(
|
|
'div',
|
|
{ className: 'row align-content-center' },
|
|
_react2.default.createElement(
|
|
'p',
|
|
null,
|
|
'Upload complete. Your file is now being published on the blockchain...'
|
|
),
|
|
_react2.default.createElement(_ProgressBar2.default, { size: 12 }),
|
|
_react2.default.createElement(
|
|
'p',
|
|
null,
|
|
'Curious what magic is happening here? ',
|
|
_react2.default.createElement(
|
|
'a',
|
|
{ className: 'link--primary', target: 'blank', href: 'https://lbry.io/faq/what-is-lbry' },
|
|
'Learn more.'
|
|
)
|
|
)
|
|
),
|
|
status === publishStates.SUCCESS && _react2.default.createElement(
|
|
'div',
|
|
{ className: 'row align-content-center' },
|
|
_react2.default.createElement(
|
|
'p',
|
|
null,
|
|
'Your publish is complete! You are being redirected to it now.'
|
|
),
|
|
_react2.default.createElement(
|
|
'p',
|
|
null,
|
|
'If you are not automatically redirected, ',
|
|
_react2.default.createElement(
|
|
'a',
|
|
{ className: 'link--primary', target: '_blank', href: message },
|
|
'click here.'
|
|
)
|
|
)
|
|
),
|
|
status === publishStates.FAILED && _react2.default.createElement(
|
|
'div',
|
|
{ className: 'row align-content-center' },
|
|
_react2.default.createElement(
|
|
'p',
|
|
null,
|
|
'Something went wrong...'
|
|
),
|
|
_react2.default.createElement(
|
|
'p',
|
|
null,
|
|
_react2.default.createElement(
|
|
'strong',
|
|
null,
|
|
message
|
|
)
|
|
),
|
|
_react2.default.createElement(
|
|
'p',
|
|
null,
|
|
'For help, post the above error text in the #speech channel on the ',
|
|
_react2.default.createElement(
|
|
'a',
|
|
{ className: 'link--primary', href: 'https://discord.gg/YjYbwhS', target: '_blank' },
|
|
'lbry discord'
|
|
)
|
|
),
|
|
_react2.default.createElement(
|
|
'button',
|
|
{ className: 'button--secondary', onClick: clearFile },
|
|
'Reset'
|
|
)
|
|
)
|
|
);
|
|
}
|
|
}]);
|
|
|
|
return PublishStatus;
|
|
}(_react2.default.Component);
|
|
|
|
;
|
|
|
|
exports.default = PublishStatus;
|
|
|
|
/***/ }),
|
|
/* 87 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
|
|
var _reactRedux = __webpack_require__(1);
|
|
|
|
var _view = __webpack_require__(88);
|
|
|
|
var _view2 = _interopRequireDefault(_view);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
var mapStateToProps = function mapStateToProps(_ref) {
|
|
var publish = _ref.publish;
|
|
|
|
return {
|
|
message: publish.disabledMessage
|
|
};
|
|
};
|
|
|
|
exports.default = (0, _reactRedux.connect)(mapStateToProps, null)(_view2.default);
|
|
|
|
/***/ }),
|
|
/* 88 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
|
|
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
|
|
|
var _react = __webpack_require__(0);
|
|
|
|
var _react2 = _interopRequireDefault(_react);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
|
|
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
|
|
|
|
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
|
|
|
|
var PublishDisabledMessage = function (_React$Component) {
|
|
_inherits(PublishDisabledMessage, _React$Component);
|
|
|
|
function PublishDisabledMessage() {
|
|
_classCallCheck(this, PublishDisabledMessage);
|
|
|
|
return _possibleConstructorReturn(this, (PublishDisabledMessage.__proto__ || Object.getPrototypeOf(PublishDisabledMessage)).apply(this, arguments));
|
|
}
|
|
|
|
_createClass(PublishDisabledMessage, [{
|
|
key: 'render',
|
|
value: function render() {
|
|
var message = this.props.message;
|
|
console.log('this.props.message:', message);
|
|
return _react2.default.createElement(
|
|
'div',
|
|
{ className: 'row dropzone--disabled row--tall flex-container--column flex-container--center-center' },
|
|
_react2.default.createElement(
|
|
'p',
|
|
{ className: 'text--disabled' },
|
|
'Publishing is currently disabled.'
|
|
),
|
|
_react2.default.createElement(
|
|
'p',
|
|
{ className: 'text--disabled' },
|
|
message
|
|
)
|
|
);
|
|
}
|
|
}]);
|
|
|
|
return PublishDisabledMessage;
|
|
}(_react2.default.Component);
|
|
|
|
exports.default = PublishDisabledMessage;
|
|
|
|
/***/ }),
|
|
/* 89 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
|
|
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
|
|
|
var _react = __webpack_require__(0);
|
|
|
|
var _react2 = _interopRequireDefault(_react);
|
|
|
|
var _NavBar = __webpack_require__(8);
|
|
|
|
var _NavBar2 = _interopRequireDefault(_NavBar);
|
|
|
|
var _SEO = __webpack_require__(11);
|
|
|
|
var _SEO2 = _interopRequireDefault(_SEO);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
|
|
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
|
|
|
|
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
|
|
|
|
var AboutPage = function (_React$Component) {
|
|
_inherits(AboutPage, _React$Component);
|
|
|
|
function AboutPage() {
|
|
_classCallCheck(this, AboutPage);
|
|
|
|
return _possibleConstructorReturn(this, (AboutPage.__proto__ || Object.getPrototypeOf(AboutPage)).apply(this, arguments));
|
|
}
|
|
|
|
_createClass(AboutPage, [{
|
|
key: 'render',
|
|
value: function render() {
|
|
return _react2.default.createElement(
|
|
'div',
|
|
null,
|
|
_react2.default.createElement(_SEO2.default, { pageTitle: 'About', pageUri: 'about' }),
|
|
_react2.default.createElement(_NavBar2.default, null),
|
|
_react2.default.createElement(
|
|
'div',
|
|
{ className: 'row row--padded' },
|
|
_react2.default.createElement(
|
|
'div',
|
|
{ className: 'column column--5 column--med-10 align-content-top' },
|
|
_react2.default.createElement(
|
|
'div',
|
|
{ className: 'column column--8 column--med-10' },
|
|
_react2.default.createElement(
|
|
'p',
|
|
{ className: 'pull-quote' },
|
|
'Spee.ch is an open-source project. Please contribute to the existing site, or fork it and make your own.'
|
|
),
|
|
_react2.default.createElement(
|
|
'p',
|
|
null,
|
|
_react2.default.createElement(
|
|
'a',
|
|
{ className: 'link--primary', target: '_blank', href: 'https://twitter.com/spee_ch' },
|
|
'TWITTER'
|
|
)
|
|
),
|
|
_react2.default.createElement(
|
|
'p',
|
|
null,
|
|
_react2.default.createElement(
|
|
'a',
|
|
{ className: 'link--primary', target: '_blank', href: 'https://github.com/lbryio/spee.ch' },
|
|
'GITHUB'
|
|
)
|
|
),
|
|
_react2.default.createElement(
|
|
'p',
|
|
null,
|
|
_react2.default.createElement(
|
|
'a',
|
|
{ className: 'link--primary', target: '_blank', href: 'https://discord.gg/YjYbwhS' },
|
|
'DISCORD CHANNEL'
|
|
)
|
|
),
|
|
_react2.default.createElement(
|
|
'p',
|
|
null,
|
|
_react2.default.createElement(
|
|
'a',
|
|
{ className: 'link--primary', target: '_blank', href: 'https://github.com/lbryio/spee.ch/blob/master/README.md' },
|
|
'DOCUMENTATION'
|
|
)
|
|
)
|
|
)
|
|
),
|
|
_react2.default.createElement(
|
|
'div',
|
|
{ className: 'column column--5 column--med-10 align-content-top' },
|
|
_react2.default.createElement(
|
|
'div',
|
|
{ className: 'column column--8 column--med-10' },
|
|
_react2.default.createElement(
|
|
'p',
|
|
null,
|
|
'Spee.ch is a media-hosting site that reads from and publishes content to the ',
|
|
_react2.default.createElement(
|
|
'a',
|
|
{ className: 'link--primary', href: 'https://lbry.io' },
|
|
'LBRY'
|
|
),
|
|
' blockchain.'
|
|
),
|
|
_react2.default.createElement(
|
|
'p',
|
|
null,
|
|
'Spee.ch is a hosting service, but with the added benefit that it stores your content on a decentralized network of computers -- the ',
|
|
_react2.default.createElement(
|
|
'a',
|
|
{ className: 'link--primary', href: 'https://lbry.io/get' },
|
|
'LBRY'
|
|
),
|
|
' network. This means that your images are stored in multiple locations without a single point of failure.'
|
|
),
|
|
_react2.default.createElement(
|
|
'h3',
|
|
null,
|
|
'Contribute'
|
|
),
|
|
_react2.default.createElement(
|
|
'p',
|
|
null,
|
|
'If you have an idea for your own spee.ch-like site on top of LBRY, fork our ',
|
|
_react2.default.createElement(
|
|
'a',
|
|
{ className: 'link--primary', href: 'https://github.com/lbryio/spee.ch' },
|
|
'github repo'
|
|
),
|
|
' and go to town!'
|
|
),
|
|
_react2.default.createElement(
|
|
'p',
|
|
null,
|
|
'If you want to improve spee.ch, join our ',
|
|
_react2.default.createElement(
|
|
'a',
|
|
{ className: 'link--primary', href: 'https://discord.gg/YjYbwhS' },
|
|
'discord channel'
|
|
),
|
|
' or solve one of our ',
|
|
_react2.default.createElement(
|
|
'a',
|
|
{ className: 'link--primary', href: 'https://github.com/lbryio/spee.ch/issues' },
|
|
'github issues'
|
|
),
|
|
'.'
|
|
)
|
|
)
|
|
)
|
|
)
|
|
);
|
|
}
|
|
}]);
|
|
|
|
return AboutPage;
|
|
}(_react2.default.Component);
|
|
|
|
;
|
|
|
|
exports.default = AboutPage;
|
|
|
|
/***/ }),
|
|
/* 90 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
|
|
var _reactRedux = __webpack_require__(1);
|
|
|
|
var _view = __webpack_require__(91);
|
|
|
|
var _view2 = _interopRequireDefault(_view);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
var mapStateToProps = function mapStateToProps(_ref) {
|
|
var channel = _ref.channel;
|
|
|
|
return {
|
|
loggedInChannelName: channel.loggedInChannel.name
|
|
};
|
|
};
|
|
|
|
exports.default = (0, _reactRedux.connect)(mapStateToProps, null)(_view2.default);
|
|
|
|
/***/ }),
|
|
/* 91 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
|
|
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
|
|
|
var _react = __webpack_require__(0);
|
|
|
|
var _react2 = _interopRequireDefault(_react);
|
|
|
|
var _reactRouterDom = __webpack_require__(5);
|
|
|
|
var _SEO = __webpack_require__(11);
|
|
|
|
var _SEO2 = _interopRequireDefault(_SEO);
|
|
|
|
var _NavBar = __webpack_require__(8);
|
|
|
|
var _NavBar2 = _interopRequireDefault(_NavBar);
|
|
|
|
var _ChannelLoginForm = __webpack_require__(31);
|
|
|
|
var _ChannelLoginForm2 = _interopRequireDefault(_ChannelLoginForm);
|
|
|
|
var _ChannelCreateForm = __webpack_require__(32);
|
|
|
|
var _ChannelCreateForm2 = _interopRequireDefault(_ChannelCreateForm);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
|
|
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
|
|
|
|
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
|
|
|
|
var LoginPage = function (_React$Component) {
|
|
_inherits(LoginPage, _React$Component);
|
|
|
|
function LoginPage() {
|
|
_classCallCheck(this, LoginPage);
|
|
|
|
return _possibleConstructorReturn(this, (LoginPage.__proto__ || Object.getPrototypeOf(LoginPage)).apply(this, arguments));
|
|
}
|
|
|
|
_createClass(LoginPage, [{
|
|
key: 'componentWillReceiveProps',
|
|
value: function componentWillReceiveProps(newProps) {
|
|
// re-route the user to the homepage if the user is logged in
|
|
if (newProps.loggedInChannelName !== this.props.loggedInChannelName) {
|
|
this.props.history.push('/');
|
|
}
|
|
}
|
|
}, {
|
|
key: 'render',
|
|
value: function render() {
|
|
return _react2.default.createElement(
|
|
'div',
|
|
null,
|
|
_react2.default.createElement(_SEO2.default, { pageTitle: 'Login', pageUri: 'login' }),
|
|
_react2.default.createElement(_NavBar2.default, null),
|
|
_react2.default.createElement(
|
|
'div',
|
|
{ className: 'row row--padded' },
|
|
_react2.default.createElement(
|
|
'div',
|
|
{ className: 'column column--5 column--med-10 align-content-top' },
|
|
_react2.default.createElement(
|
|
'div',
|
|
{ className: 'column column--8 column--med-10' },
|
|
_react2.default.createElement(
|
|
'p',
|
|
null,
|
|
'Channels allow you to publish and group content under an identity. You can create a channel for yourself, or share one with like-minded friends. You can create 1 channel, or 100, so whether you\'re ',
|
|
_react2.default.createElement(
|
|
'a',
|
|
{ className: 'link--primary', target: '_blank', href: '/@catalonia2017:43dcf47163caa21d8404d9fe9b30f78ef3e146a8' },
|
|
'documenting important events'
|
|
),
|
|
', or making a public repository for ',
|
|
_react2.default.createElement(
|
|
'a',
|
|
{ className: 'link--primary', target: '_blank', href: '/@catGifs' },
|
|
'cat gifs'
|
|
),
|
|
' (password: \'1234\'), try creating a channel for it!'
|
|
)
|
|
)
|
|
),
|
|
_react2.default.createElement(
|
|
'div',
|
|
{ className: 'column column--5 column--med-10 align-content-top' },
|
|
_react2.default.createElement(
|
|
'div',
|
|
{ className: 'column column--8 column--med-10' },
|
|
_react2.default.createElement(
|
|
'h3',
|
|
{ className: 'h3--no-bottom' },
|
|
'Log in to an existing channel:'
|
|
),
|
|
_react2.default.createElement(_ChannelLoginForm2.default, null),
|
|
_react2.default.createElement(
|
|
'h3',
|
|
{ className: 'h3--no-bottom' },
|
|
'Create a brand new channel:'
|
|
),
|
|
_react2.default.createElement(_ChannelCreateForm2.default, null)
|
|
)
|
|
)
|
|
)
|
|
);
|
|
}
|
|
}]);
|
|
|
|
return LoginPage;
|
|
}(_react2.default.Component);
|
|
|
|
;
|
|
|
|
exports.default = (0, _reactRouterDom.withRouter)(LoginPage);
|
|
|
|
/***/ }),
|
|
/* 92 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
|
|
var _reactRedux = __webpack_require__(1);
|
|
|
|
var _show = __webpack_require__(7);
|
|
|
|
var _view = __webpack_require__(93);
|
|
|
|
var _view2 = _interopRequireDefault(_view);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
var mapStateToProps = function mapStateToProps(_ref) {
|
|
var show = _ref.show;
|
|
|
|
return {
|
|
error: show.request.error,
|
|
requestType: show.request.type
|
|
};
|
|
};
|
|
|
|
var mapDispatchToProps = {
|
|
onHandleShowPageUri: _show.onHandleShowPageUri
|
|
};
|
|
|
|
exports.default = (0, _reactRedux.connect)(mapStateToProps, mapDispatchToProps)(_view2.default);
|
|
|
|
/***/ }),
|
|
/* 93 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
|
|
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
|
|
|
var _react = __webpack_require__(0);
|
|
|
|
var _react2 = _interopRequireDefault(_react);
|
|
|
|
var _ErrorPage = __webpack_require__(24);
|
|
|
|
var _ErrorPage2 = _interopRequireDefault(_ErrorPage);
|
|
|
|
var _ShowAssetLite = __webpack_require__(94);
|
|
|
|
var _ShowAssetLite2 = _interopRequireDefault(_ShowAssetLite);
|
|
|
|
var _ShowAssetDetails = __webpack_require__(97);
|
|
|
|
var _ShowAssetDetails2 = _interopRequireDefault(_ShowAssetDetails);
|
|
|
|
var _ShowChannel = __webpack_require__(103);
|
|
|
|
var _ShowChannel2 = _interopRequireDefault(_ShowChannel);
|
|
|
|
var _show_request_types = __webpack_require__(35);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
|
|
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
|
|
|
|
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
|
|
|
|
var ShowPage = function (_React$Component) {
|
|
_inherits(ShowPage, _React$Component);
|
|
|
|
function ShowPage() {
|
|
_classCallCheck(this, ShowPage);
|
|
|
|
return _possibleConstructorReturn(this, (ShowPage.__proto__ || Object.getPrototypeOf(ShowPage)).apply(this, arguments));
|
|
}
|
|
|
|
_createClass(ShowPage, [{
|
|
key: 'componentDidMount',
|
|
value: function componentDidMount() {
|
|
this.props.onHandleShowPageUri(this.props.match.params);
|
|
}
|
|
}, {
|
|
key: 'componentWillReceiveProps',
|
|
value: function componentWillReceiveProps(nextProps) {
|
|
if (nextProps.match.params !== this.props.match.params) {
|
|
this.props.onHandleShowPageUri(nextProps.match.params);
|
|
}
|
|
}
|
|
}, {
|
|
key: 'render',
|
|
value: function render() {
|
|
var _props = this.props,
|
|
error = _props.error,
|
|
requestType = _props.requestType;
|
|
|
|
if (error) {
|
|
return _react2.default.createElement(_ErrorPage2.default, { error: error });
|
|
}
|
|
switch (requestType) {
|
|
case _show_request_types.CHANNEL:
|
|
return _react2.default.createElement(_ShowChannel2.default, null);
|
|
case _show_request_types.ASSET_LITE:
|
|
return _react2.default.createElement(_ShowAssetLite2.default, null);
|
|
case _show_request_types.ASSET_DETAILS:
|
|
return _react2.default.createElement(_ShowAssetDetails2.default, null);
|
|
default:
|
|
return _react2.default.createElement(
|
|
'p',
|
|
null,
|
|
'loading...'
|
|
);
|
|
}
|
|
}
|
|
}]);
|
|
|
|
return ShowPage;
|
|
}(_react2.default.Component);
|
|
|
|
;
|
|
|
|
exports.default = ShowPage;
|
|
|
|
/***/ }),
|
|
/* 94 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
|
|
var _reactRedux = __webpack_require__(1);
|
|
|
|
var _view = __webpack_require__(95);
|
|
|
|
var _view2 = _interopRequireDefault(_view);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
var mapStateToProps = function mapStateToProps(_ref) {
|
|
var show = _ref.show;
|
|
|
|
// select request info
|
|
var requestId = show.request.id;
|
|
// select asset info
|
|
var asset = void 0;
|
|
var request = show.requestList[requestId] || null;
|
|
var assetList = show.assetList;
|
|
if (request && assetList) {
|
|
var assetKey = request.key; // note: just store this in the request
|
|
asset = assetList[assetKey] || null;
|
|
};
|
|
// return props
|
|
return {
|
|
asset: asset
|
|
};
|
|
};
|
|
|
|
exports.default = (0, _reactRedux.connect)(mapStateToProps, null)(_view2.default);
|
|
|
|
/***/ }),
|
|
/* 95 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
|
|
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
|
|
|
var _react = __webpack_require__(0);
|
|
|
|
var _react2 = _interopRequireDefault(_react);
|
|
|
|
var _SEO = __webpack_require__(11);
|
|
|
|
var _SEO2 = _interopRequireDefault(_SEO);
|
|
|
|
var _reactRouterDom = __webpack_require__(5);
|
|
|
|
var _AssetDisplay = __webpack_require__(36);
|
|
|
|
var _AssetDisplay2 = _interopRequireDefault(_AssetDisplay);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
|
|
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
|
|
|
|
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
|
|
|
|
var ShowLite = function (_React$Component) {
|
|
_inherits(ShowLite, _React$Component);
|
|
|
|
function ShowLite() {
|
|
_classCallCheck(this, ShowLite);
|
|
|
|
return _possibleConstructorReturn(this, (ShowLite.__proto__ || Object.getPrototypeOf(ShowLite)).apply(this, arguments));
|
|
}
|
|
|
|
_createClass(ShowLite, [{
|
|
key: 'render',
|
|
value: function render() {
|
|
var asset = this.props.asset;
|
|
|
|
if (asset) {
|
|
var _asset$claimData = asset.claimData,
|
|
name = _asset$claimData.name,
|
|
claimId = _asset$claimData.claimId;
|
|
|
|
return _react2.default.createElement(
|
|
'div',
|
|
{ className: 'row row--tall flex-container--column flex-container--center-center show-lite-container' },
|
|
_react2.default.createElement(_SEO2.default, { pageTitle: name, asset: asset }),
|
|
_react2.default.createElement(_AssetDisplay2.default, null),
|
|
_react2.default.createElement(
|
|
_reactRouterDom.Link,
|
|
{ id: 'asset-boilerpate', className: 'link--primary fine-print', to: '/' + claimId + '/' + name },
|
|
'hosted via Spee.ch'
|
|
)
|
|
);
|
|
}
|
|
return _react2.default.createElement(
|
|
'div',
|
|
{ className: 'row row--tall row--padded flex-container--column flex-container--center-center' },
|
|
_react2.default.createElement(
|
|
'p',
|
|
null,
|
|
'loading asset data...'
|
|
)
|
|
);
|
|
}
|
|
}]);
|
|
|
|
return ShowLite;
|
|
}(_react2.default.Component);
|
|
|
|
;
|
|
|
|
exports.default = ShowLite;
|
|
|
|
/***/ }),
|
|
/* 96 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
|
|
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
|
|
|
var _react = __webpack_require__(0);
|
|
|
|
var _react2 = _interopRequireDefault(_react);
|
|
|
|
var _ProgressBar = __webpack_require__(23);
|
|
|
|
var _ProgressBar2 = _interopRequireDefault(_ProgressBar);
|
|
|
|
var _asset_display_states = __webpack_require__(25);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
|
|
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
|
|
|
|
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
|
|
|
|
var AssetDisplay = function (_React$Component) {
|
|
_inherits(AssetDisplay, _React$Component);
|
|
|
|
function AssetDisplay() {
|
|
_classCallCheck(this, AssetDisplay);
|
|
|
|
return _possibleConstructorReturn(this, (AssetDisplay.__proto__ || Object.getPrototypeOf(AssetDisplay)).apply(this, arguments));
|
|
}
|
|
|
|
_createClass(AssetDisplay, [{
|
|
key: 'componentDidMount',
|
|
value: function componentDidMount() {
|
|
var _props$asset$claimDat = this.props.asset.claimData,
|
|
name = _props$asset$claimDat.name,
|
|
claimId = _props$asset$claimDat.claimId;
|
|
|
|
this.props.onFileRequest(name, claimId);
|
|
}
|
|
}, {
|
|
key: 'render',
|
|
value: function render() {
|
|
var _props = this.props,
|
|
status = _props.status,
|
|
error = _props.error,
|
|
_props$asset$claimDat2 = _props.asset.claimData,
|
|
name = _props$asset$claimDat2.name,
|
|
claimId = _props$asset$claimDat2.claimId,
|
|
contentType = _props$asset$claimDat2.contentType,
|
|
fileExt = _props$asset$claimDat2.fileExt,
|
|
thumbnail = _props$asset$claimDat2.thumbnail;
|
|
|
|
return _react2.default.createElement(
|
|
'div',
|
|
{ id: 'asset-display-component' },
|
|
status === _asset_display_states.LOCAL_CHECK && _react2.default.createElement(
|
|
'div',
|
|
null,
|
|
_react2.default.createElement(
|
|
'p',
|
|
null,
|
|
'Checking to see if Spee.ch has your asset locally...'
|
|
)
|
|
),
|
|
status === _asset_display_states.UNAVAILABLE && _react2.default.createElement(
|
|
'div',
|
|
null,
|
|
_react2.default.createElement(
|
|
'p',
|
|
null,
|
|
'Sit tight, we\'re searching the LBRY blockchain for your asset!'
|
|
),
|
|
_react2.default.createElement(_ProgressBar2.default, { size: 12 }),
|
|
_react2.default.createElement(
|
|
'p',
|
|
null,
|
|
'Curious what magic is happening here? ',
|
|
_react2.default.createElement(
|
|
'a',
|
|
{ className: 'link--primary', target: 'blank', href: 'https://lbry.io/faq/what-is-lbry' },
|
|
'Learn more.'
|
|
)
|
|
)
|
|
),
|
|
status === _asset_display_states.ERROR && _react2.default.createElement(
|
|
'div',
|
|
null,
|
|
_react2.default.createElement(
|
|
'p',
|
|
null,
|
|
'Unfortunately, we couldn\'t download your asset from LBRY. You can help us out by sharing the below error message in the ',
|
|
_react2.default.createElement(
|
|
'a',
|
|
{ className: 'link--primary', href: 'https://discord.gg/YjYbwhS', target: '_blank' },
|
|
'LBRY discord'
|
|
),
|
|
'.'
|
|
),
|
|
_react2.default.createElement(
|
|
'i',
|
|
null,
|
|
_react2.default.createElement(
|
|
'p',
|
|
{ id: 'error-message' },
|
|
error
|
|
)
|
|
)
|
|
),
|
|
status === _asset_display_states.AVAILABLE && function () {
|
|
switch (contentType) {
|
|
case 'image/jpeg':
|
|
case 'image/jpg':
|
|
case 'image/png':
|
|
return _react2.default.createElement('img', {
|
|
className: 'asset',
|
|
src: '/' + claimId + '/' + name + '.' + fileExt,
|
|
alt: name });
|
|
case 'image/gif':
|
|
return _react2.default.createElement('img', {
|
|
className: 'asset',
|
|
src: '/' + claimId + '/' + name + '.' + fileExt,
|
|
alt: name
|
|
});
|
|
case 'video/mp4':
|
|
return _react2.default.createElement(
|
|
'video',
|
|
{ className: 'asset video', controls: true, poster: thumbnail },
|
|
_react2.default.createElement('source', {
|
|
src: '/' + claimId + '/' + name + '.' + fileExt
|
|
}),
|
|
_react2.default.createElement(
|
|
'p',
|
|
null,
|
|
'Your browser does not support the ',
|
|
_react2.default.createElement(
|
|
'code',
|
|
null,
|
|
'video'
|
|
),
|
|
' element.'
|
|
)
|
|
);
|
|
default:
|
|
return _react2.default.createElement(
|
|
'p',
|
|
null,
|
|
'Unsupported file type'
|
|
);
|
|
}
|
|
}()
|
|
);
|
|
}
|
|
}]);
|
|
|
|
return AssetDisplay;
|
|
}(_react2.default.Component);
|
|
|
|
;
|
|
|
|
exports.default = AssetDisplay;
|
|
|
|
/***/ }),
|
|
/* 97 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
|
|
var _reactRedux = __webpack_require__(1);
|
|
|
|
var _view = __webpack_require__(98);
|
|
|
|
var _view2 = _interopRequireDefault(_view);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
var mapStateToProps = function mapStateToProps(_ref) {
|
|
var show = _ref.show;
|
|
|
|
// select request info
|
|
var requestId = show.request.id;
|
|
// select asset info
|
|
var asset = void 0;
|
|
var request = show.requestList[requestId] || null;
|
|
var assetList = show.assetList;
|
|
if (request && assetList) {
|
|
var assetKey = request.key; // note: just store this in the request
|
|
asset = assetList[assetKey] || null;
|
|
};
|
|
// return props
|
|
return {
|
|
asset: asset
|
|
};
|
|
};
|
|
|
|
exports.default = (0, _reactRedux.connect)(mapStateToProps, null)(_view2.default);
|
|
|
|
/***/ }),
|
|
/* 98 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
|
|
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
|
|
|
var _react = __webpack_require__(0);
|
|
|
|
var _react2 = _interopRequireDefault(_react);
|
|
|
|
var _SEO = __webpack_require__(11);
|
|
|
|
var _SEO2 = _interopRequireDefault(_SEO);
|
|
|
|
var _NavBar = __webpack_require__(8);
|
|
|
|
var _NavBar2 = _interopRequireDefault(_NavBar);
|
|
|
|
var _ErrorPage = __webpack_require__(24);
|
|
|
|
var _ErrorPage2 = _interopRequireDefault(_ErrorPage);
|
|
|
|
var _AssetTitle = __webpack_require__(99);
|
|
|
|
var _AssetTitle2 = _interopRequireDefault(_AssetTitle);
|
|
|
|
var _AssetDisplay = __webpack_require__(36);
|
|
|
|
var _AssetDisplay2 = _interopRequireDefault(_AssetDisplay);
|
|
|
|
var _AssetInfo = __webpack_require__(101);
|
|
|
|
var _AssetInfo2 = _interopRequireDefault(_AssetInfo);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
|
|
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
|
|
|
|
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
|
|
|
|
var ShowAssetDetails = function (_React$Component) {
|
|
_inherits(ShowAssetDetails, _React$Component);
|
|
|
|
function ShowAssetDetails() {
|
|
_classCallCheck(this, ShowAssetDetails);
|
|
|
|
return _possibleConstructorReturn(this, (ShowAssetDetails.__proto__ || Object.getPrototypeOf(ShowAssetDetails)).apply(this, arguments));
|
|
}
|
|
|
|
_createClass(ShowAssetDetails, [{
|
|
key: 'render',
|
|
value: function render() {
|
|
var asset = this.props.asset;
|
|
|
|
if (asset) {
|
|
var name = asset.claimData.name;
|
|
|
|
return _react2.default.createElement(
|
|
'div',
|
|
null,
|
|
_react2.default.createElement(_SEO2.default, { pageTitle: name + ' - details', asset: asset }),
|
|
_react2.default.createElement(_NavBar2.default, null),
|
|
_react2.default.createElement(
|
|
'div',
|
|
{ className: 'row row--tall row--padded' },
|
|
_react2.default.createElement(
|
|
'div',
|
|
{ className: 'column column--10' },
|
|
_react2.default.createElement(_AssetTitle2.default, null)
|
|
),
|
|
_react2.default.createElement(
|
|
'div',
|
|
{ className: 'column column--5 column--sml-10 align-content-top' },
|
|
_react2.default.createElement(
|
|
'div',
|
|
{ className: 'row row--padded show-details-container' },
|
|
_react2.default.createElement(_AssetDisplay2.default, null)
|
|
)
|
|
),
|
|
_react2.default.createElement(
|
|
'div',
|
|
{ className: 'column column--5 column--sml-10 align-content-top' },
|
|
_react2.default.createElement(
|
|
'div',
|
|
{ className: 'row row--padded' },
|
|
_react2.default.createElement(_AssetInfo2.default, null)
|
|
)
|
|
)
|
|
)
|
|
);
|
|
};
|
|
return _react2.default.createElement(_ErrorPage2.default, { error: 'loading asset data...' });
|
|
}
|
|
}]);
|
|
|
|
return ShowAssetDetails;
|
|
}(_react2.default.Component);
|
|
|
|
;
|
|
|
|
exports.default = ShowAssetDetails;
|
|
|
|
/***/ }),
|
|
/* 99 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
|
|
var _reactRedux = __webpack_require__(1);
|
|
|
|
var _view = __webpack_require__(100);
|
|
|
|
var _view2 = _interopRequireDefault(_view);
|
|
|
|
var _show = __webpack_require__(16);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
var mapStateToProps = function mapStateToProps(_ref) {
|
|
var show = _ref.show;
|
|
|
|
var _selectAsset = (0, _show.selectAsset)(show),
|
|
title = _selectAsset.claimData.title;
|
|
|
|
return {
|
|
title: title
|
|
};
|
|
};
|
|
|
|
exports.default = (0, _reactRedux.connect)(mapStateToProps, null)(_view2.default);
|
|
|
|
/***/ }),
|
|
/* 100 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
|
|
var _react = __webpack_require__(0);
|
|
|
|
var _react2 = _interopRequireDefault(_react);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
var AssetTitle = function AssetTitle(_ref) {
|
|
var title = _ref.title;
|
|
|
|
return _react2.default.createElement(
|
|
'div',
|
|
null,
|
|
_react2.default.createElement(
|
|
'span',
|
|
{ className: 'text--large' },
|
|
title
|
|
)
|
|
);
|
|
};
|
|
|
|
exports.default = AssetTitle;
|
|
|
|
/***/ }),
|
|
/* 101 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
|
|
var _reactRedux = __webpack_require__(1);
|
|
|
|
var _view = __webpack_require__(102);
|
|
|
|
var _view2 = _interopRequireDefault(_view);
|
|
|
|
var _show = __webpack_require__(16);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
var mapStateToProps = function mapStateToProps(_ref) {
|
|
var show = _ref.show;
|
|
|
|
// select asset
|
|
var asset = (0, _show.selectAsset)(show);
|
|
// return props
|
|
return {
|
|
asset: asset
|
|
};
|
|
};
|
|
|
|
exports.default = (0, _reactRedux.connect)(mapStateToProps, null)(_view2.default);
|
|
|
|
/***/ }),
|
|
/* 102 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
|
|
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
|
|
|
var _react = __webpack_require__(0);
|
|
|
|
var _react2 = _interopRequireDefault(_react);
|
|
|
|
var _reactRouterDom = __webpack_require__(5);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
|
|
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
|
|
|
|
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
|
|
|
|
var AssetInfo = function (_React$Component) {
|
|
_inherits(AssetInfo, _React$Component);
|
|
|
|
function AssetInfo(props) {
|
|
_classCallCheck(this, AssetInfo);
|
|
|
|
var _this = _possibleConstructorReturn(this, (AssetInfo.__proto__ || Object.getPrototypeOf(AssetInfo)).call(this, props));
|
|
|
|
_this.copyToClipboard = _this.copyToClipboard.bind(_this);
|
|
return _this;
|
|
}
|
|
|
|
_createClass(AssetInfo, [{
|
|
key: 'copyToClipboard',
|
|
value: function copyToClipboard(event) {
|
|
var elementToCopy = event.target.dataset.elementtocopy;
|
|
var element = document.getElementById(elementToCopy);
|
|
element.select();
|
|
try {
|
|
document.execCommand('copy');
|
|
} catch (err) {
|
|
this.setState({ error: 'Oops, unable to copy' });
|
|
}
|
|
}
|
|
}, {
|
|
key: 'render',
|
|
value: function render() {
|
|
var _props$asset = this.props.asset,
|
|
shortId = _props$asset.shortId,
|
|
_props$asset$claimDat = _props$asset.claimData,
|
|
channelName = _props$asset$claimDat.channelName,
|
|
certificateId = _props$asset$claimDat.certificateId,
|
|
description = _props$asset$claimDat.description,
|
|
name = _props$asset$claimDat.name,
|
|
claimId = _props$asset$claimDat.claimId,
|
|
fileExt = _props$asset$claimDat.fileExt,
|
|
contentType = _props$asset$claimDat.contentType,
|
|
thumbnail = _props$asset$claimDat.thumbnail,
|
|
host = _props$asset$claimDat.host;
|
|
|
|
return _react2.default.createElement(
|
|
'div',
|
|
null,
|
|
channelName && _react2.default.createElement(
|
|
'div',
|
|
{ className: 'row row--padded row--wide row--no-top' },
|
|
_react2.default.createElement(
|
|
'div',
|
|
{ className: 'column column--2 column--med-10' },
|
|
_react2.default.createElement(
|
|
'span',
|
|
{ className: 'text' },
|
|
'Channel:'
|
|
)
|
|
),
|
|
_react2.default.createElement(
|
|
'div',
|
|
{ className: 'column column--8 column--med-10' },
|
|
_react2.default.createElement(
|
|
'span',
|
|
{ className: 'text' },
|
|
_react2.default.createElement(
|
|
_reactRouterDom.Link,
|
|
{ to: '/' + channelName + ':' + certificateId },
|
|
channelName
|
|
)
|
|
)
|
|
)
|
|
),
|
|
description && _react2.default.createElement(
|
|
'div',
|
|
{ className: 'row row--padded row--wide row--no-top' },
|
|
_react2.default.createElement(
|
|
'span',
|
|
{ className: 'text' },
|
|
description
|
|
)
|
|
),
|
|
_react2.default.createElement(
|
|
'div',
|
|
{ id: 'show-share-buttons' },
|
|
_react2.default.createElement(
|
|
'div',
|
|
{ className: 'row row--padded row--wide row--no-top' },
|
|
_react2.default.createElement(
|
|
'div',
|
|
{ className: 'column column--2 column--med-10' },
|
|
_react2.default.createElement(
|
|
'span',
|
|
{ className: 'text' },
|
|
'Share:'
|
|
)
|
|
),
|
|
_react2.default.createElement(
|
|
'div',
|
|
{ className: 'column column--8 column--med-10' },
|
|
_react2.default.createElement(
|
|
'div',
|
|
{
|
|
className: 'row row--short row--wide flex-container--row flex-container--space-between-bottom flex-container--wrap' },
|
|
_react2.default.createElement(
|
|
'a',
|
|
{ className: 'link--primary', target: '_blank', href: 'https://twitter.com/intent/tweet?text=' + host + '/' + shortId + '/' + name },
|
|
'twitter'
|
|
),
|
|
_react2.default.createElement(
|
|
'a',
|
|
{ className: 'link--primary', target: '_blank', href: 'https://www.facebook.com/sharer/sharer.php?u=' + host + '/' + shortId + '/' + name },
|
|
'facebook'
|
|
),
|
|
_react2.default.createElement(
|
|
'a',
|
|
{ className: 'link--primary', target: '_blank', href: 'http://tumblr.com/widgets/share/tool?canonicalUrl=' + host + '/' + shortId + '/' + name },
|
|
'tumblr'
|
|
),
|
|
_react2.default.createElement(
|
|
'a',
|
|
{ className: 'link--primary', target: '_blank', href: 'https://www.reddit.com/submit?url=' + host + '/' + shortId + '/' + name + '&title=' + name },
|
|
'reddit'
|
|
)
|
|
)
|
|
)
|
|
)
|
|
),
|
|
_react2.default.createElement(
|
|
'div',
|
|
{ className: 'row row--padded row--wide row--no-top' },
|
|
_react2.default.createElement(
|
|
'div',
|
|
{ id: 'show-short-link' },
|
|
_react2.default.createElement(
|
|
'div',
|
|
{ className: 'column column--2 column--med-10' },
|
|
_react2.default.createElement(
|
|
'span',
|
|
{ className: 'text' },
|
|
'Link:'
|
|
)
|
|
),
|
|
_react2.default.createElement(
|
|
'div',
|
|
{ className: 'column column--8 column--med-10' },
|
|
_react2.default.createElement(
|
|
'div',
|
|
{ className: 'row row--short row--wide' },
|
|
_react2.default.createElement(
|
|
'div',
|
|
{ className: 'column column--7' },
|
|
_react2.default.createElement(
|
|
'div',
|
|
{ className: 'input-error', id: 'input-error-copy-short-link', hidden: 'true' },
|
|
'error here'
|
|
),
|
|
_react2.default.createElement('input', { type: 'text', id: 'short-link', className: 'input-disabled input-text--full-width', readOnly: true,
|
|
spellCheck: 'false',
|
|
value: host + '/' + shortId + '/' + name + '.' + fileExt,
|
|
onClick: this.select })
|
|
),
|
|
_react2.default.createElement('div', { className: 'column column--1' }),
|
|
_react2.default.createElement(
|
|
'div',
|
|
{ className: 'column column--2' },
|
|
_react2.default.createElement(
|
|
'button',
|
|
{ className: 'button--primary button--wide', 'data-elementtocopy': 'short-link',
|
|
onClick: this.copyToClipboard },
|
|
'copy'
|
|
)
|
|
)
|
|
)
|
|
)
|
|
),
|
|
_react2.default.createElement(
|
|
'div',
|
|
{ id: 'show-embed-code' },
|
|
_react2.default.createElement(
|
|
'div',
|
|
{ className: 'column column--2 column--med-10' },
|
|
_react2.default.createElement(
|
|
'span',
|
|
{ className: 'text' },
|
|
'Embed:'
|
|
)
|
|
),
|
|
_react2.default.createElement(
|
|
'div',
|
|
{ className: 'column column--8 column--med-10' },
|
|
_react2.default.createElement(
|
|
'div',
|
|
{ className: 'row row--short row--wide' },
|
|
_react2.default.createElement(
|
|
'div',
|
|
{ className: 'column column--7' },
|
|
_react2.default.createElement(
|
|
'div',
|
|
{ className: 'input-error', id: 'input-error-copy-embed-text', hidden: 'true' },
|
|
'error here'
|
|
),
|
|
contentType === 'video/mp4' ? _react2.default.createElement('input', { type: 'text', id: 'embed-text', className: 'input-disabled input-text--full-width', readOnly: true,
|
|
onClick: this.select, spellCheck: 'false',
|
|
value: '<video width="100%" controls poster="' + thumbnail + '" src="' + host + '/' + claimId + '/' + name + '.' + fileExt + '"/></video>' }) : _react2.default.createElement('input', { type: 'text', id: 'embed-text', className: 'input-disabled input-text--full-width', readOnly: true,
|
|
onClick: this.select, spellCheck: 'false',
|
|
value: '<img src="' + host + '/' + claimId + '/' + name + '.' + fileExt + '"/>'
|
|
})
|
|
),
|
|
_react2.default.createElement('div', { className: 'column column--1' }),
|
|
_react2.default.createElement(
|
|
'div',
|
|
{ className: 'column column--2' },
|
|
_react2.default.createElement(
|
|
'button',
|
|
{ className: 'button--primary button--wide', 'data-elementtocopy': 'embed-text',
|
|
onClick: this.copyToClipboard },
|
|
'copy'
|
|
)
|
|
)
|
|
)
|
|
)
|
|
)
|
|
),
|
|
_react2.default.createElement(
|
|
'div',
|
|
{ className: 'flex-container--row flex-container--space-between-bottom' },
|
|
_react2.default.createElement(
|
|
_reactRouterDom.Link,
|
|
{ className: 'link--primary', to: '/' + shortId + '/' + name + '.' + fileExt },
|
|
_react2.default.createElement(
|
|
'span',
|
|
{
|
|
className: 'text' },
|
|
'Direct Link'
|
|
)
|
|
),
|
|
_react2.default.createElement(
|
|
'a',
|
|
{ className: 'link--primary', href: host + '/' + claimId + '/' + name + '.' + fileExt, download: name },
|
|
'Download'
|
|
),
|
|
_react2.default.createElement(
|
|
'a',
|
|
{ className: 'link--primary', target: '_blank', href: 'https://lbry.io/dmca' },
|
|
'Report'
|
|
)
|
|
)
|
|
);
|
|
}
|
|
}]);
|
|
|
|
return AssetInfo;
|
|
}(_react2.default.Component);
|
|
|
|
;
|
|
|
|
exports.default = AssetInfo;
|
|
|
|
/***/ }),
|
|
/* 103 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
|
|
var _reactRedux = __webpack_require__(1);
|
|
|
|
var _view = __webpack_require__(104);
|
|
|
|
var _view2 = _interopRequireDefault(_view);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
var mapStateToProps = function mapStateToProps(_ref) {
|
|
var show = _ref.show;
|
|
|
|
// select request info
|
|
var requestId = show.request.id;
|
|
// select request
|
|
var previousRequest = show.requestList[requestId] || null;
|
|
// select channel
|
|
var channel = void 0;
|
|
if (previousRequest) {
|
|
var channelKey = previousRequest.key;
|
|
channel = show.channelList[channelKey] || null;
|
|
}
|
|
return {
|
|
channel: channel
|
|
};
|
|
};
|
|
|
|
exports.default = (0, _reactRedux.connect)(mapStateToProps, null)(_view2.default);
|
|
|
|
/***/ }),
|
|
/* 104 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
|
|
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
|
|
|
var _react = __webpack_require__(0);
|
|
|
|
var _react2 = _interopRequireDefault(_react);
|
|
|
|
var _SEO = __webpack_require__(11);
|
|
|
|
var _SEO2 = _interopRequireDefault(_SEO);
|
|
|
|
var _ErrorPage = __webpack_require__(24);
|
|
|
|
var _ErrorPage2 = _interopRequireDefault(_ErrorPage);
|
|
|
|
var _NavBar = __webpack_require__(8);
|
|
|
|
var _NavBar2 = _interopRequireDefault(_NavBar);
|
|
|
|
var _ChannelClaimsDisplay = __webpack_require__(105);
|
|
|
|
var _ChannelClaimsDisplay2 = _interopRequireDefault(_ChannelClaimsDisplay);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
|
|
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
|
|
|
|
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
|
|
|
|
var ShowChannel = function (_React$Component) {
|
|
_inherits(ShowChannel, _React$Component);
|
|
|
|
function ShowChannel() {
|
|
_classCallCheck(this, ShowChannel);
|
|
|
|
return _possibleConstructorReturn(this, (ShowChannel.__proto__ || Object.getPrototypeOf(ShowChannel)).apply(this, arguments));
|
|
}
|
|
|
|
_createClass(ShowChannel, [{
|
|
key: 'render',
|
|
value: function render() {
|
|
var channel = this.props.channel;
|
|
|
|
if (channel) {
|
|
var name = channel.name,
|
|
longId = channel.longId,
|
|
shortId = channel.shortId;
|
|
|
|
return _react2.default.createElement(
|
|
'div',
|
|
null,
|
|
_react2.default.createElement(_SEO2.default, { pageTitle: name, channel: channel }),
|
|
_react2.default.createElement(_NavBar2.default, null),
|
|
_react2.default.createElement(
|
|
'div',
|
|
{ className: 'row row--tall row--padded' },
|
|
_react2.default.createElement(
|
|
'div',
|
|
{ className: 'column column--10' },
|
|
_react2.default.createElement(
|
|
'h2',
|
|
null,
|
|
'channel name: ',
|
|
name
|
|
),
|
|
_react2.default.createElement(
|
|
'p',
|
|
{ className: 'fine-print' },
|
|
'full channel id: ',
|
|
longId
|
|
),
|
|
_react2.default.createElement(
|
|
'p',
|
|
{ className: 'fine-print' },
|
|
'short channel id: ',
|
|
shortId
|
|
)
|
|
),
|
|
_react2.default.createElement(
|
|
'div',
|
|
{ className: 'column column--10' },
|
|
_react2.default.createElement(_ChannelClaimsDisplay2.default, null)
|
|
)
|
|
)
|
|
);
|
|
};
|
|
return _react2.default.createElement(_ErrorPage2.default, { error: 'loading channel data...' });
|
|
}
|
|
}]);
|
|
|
|
return ShowChannel;
|
|
}(_react2.default.Component);
|
|
|
|
;
|
|
|
|
exports.default = ShowChannel;
|
|
|
|
/***/ }),
|
|
/* 105 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
|
|
var _reactRedux = __webpack_require__(1);
|
|
|
|
var _show = __webpack_require__(7);
|
|
|
|
var _view = __webpack_require__(106);
|
|
|
|
var _view2 = _interopRequireDefault(_view);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
var mapStateToProps = function mapStateToProps(_ref) {
|
|
var show = _ref.show;
|
|
|
|
// select channel key
|
|
var request = show.requestList[show.request.id];
|
|
var channelKey = request.key;
|
|
// select channel claims
|
|
var channel = show.channelList[channelKey] || null;
|
|
// return props
|
|
return {
|
|
channelKey: channelKey,
|
|
channel: channel
|
|
};
|
|
};
|
|
|
|
var mapDispatchToProps = {
|
|
onUpdateChannelClaims: _show.onUpdateChannelClaims
|
|
};
|
|
|
|
exports.default = (0, _reactRedux.connect)(mapStateToProps, mapDispatchToProps)(_view2.default);
|
|
|
|
/***/ }),
|
|
/* 106 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
|
|
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
|
|
|
var _react = __webpack_require__(0);
|
|
|
|
var _react2 = _interopRequireDefault(_react);
|
|
|
|
var _AssetPreview = __webpack_require__(107);
|
|
|
|
var _AssetPreview2 = _interopRequireDefault(_AssetPreview);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
|
|
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
|
|
|
|
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
|
|
|
|
var ChannelClaimsDisplay = function (_React$Component) {
|
|
_inherits(ChannelClaimsDisplay, _React$Component);
|
|
|
|
function ChannelClaimsDisplay(props) {
|
|
_classCallCheck(this, ChannelClaimsDisplay);
|
|
|
|
var _this = _possibleConstructorReturn(this, (ChannelClaimsDisplay.__proto__ || Object.getPrototypeOf(ChannelClaimsDisplay)).call(this, props));
|
|
|
|
_this.showNextResultsPage = _this.showNextResultsPage.bind(_this);
|
|
_this.showPreviousResultsPage = _this.showPreviousResultsPage.bind(_this);
|
|
return _this;
|
|
}
|
|
|
|
_createClass(ChannelClaimsDisplay, [{
|
|
key: 'showPreviousResultsPage',
|
|
value: function showPreviousResultsPage() {
|
|
var currentPage = this.props.channel.claimsData.currentPage;
|
|
|
|
var previousPage = parseInt(currentPage) - 1;
|
|
this.showNewPage(previousPage);
|
|
}
|
|
}, {
|
|
key: 'showNextResultsPage',
|
|
value: function showNextResultsPage() {
|
|
var currentPage = this.props.channel.claimsData.currentPage;
|
|
|
|
var nextPage = parseInt(currentPage) + 1;
|
|
this.showNewPage(nextPage);
|
|
}
|
|
}, {
|
|
key: 'showNewPage',
|
|
value: function showNewPage(page) {
|
|
var _props = this.props,
|
|
channelKey = _props.channelKey,
|
|
_props$channel = _props.channel,
|
|
name = _props$channel.name,
|
|
longId = _props$channel.longId;
|
|
|
|
this.props.onUpdateChannelClaims(channelKey, name, longId, page);
|
|
}
|
|
}, {
|
|
key: 'render',
|
|
value: function render() {
|
|
var _props$channel$claims = this.props.channel.claimsData,
|
|
claims = _props$channel$claims.claims,
|
|
currentPage = _props$channel$claims.currentPage,
|
|
totalPages = _props$channel$claims.totalPages;
|
|
|
|
return _react2.default.createElement(
|
|
'div',
|
|
{ className: 'row row--tall' },
|
|
claims.length > 0 ? _react2.default.createElement(
|
|
'div',
|
|
null,
|
|
claims.map(function (claim, index) {
|
|
return _react2.default.createElement(_AssetPreview2.default, {
|
|
claimData: claim,
|
|
key: claim.name + '-' + index
|
|
});
|
|
}),
|
|
_react2.default.createElement(
|
|
'div',
|
|
null,
|
|
currentPage > 1 && _react2.default.createElement(
|
|
'button',
|
|
{ className: 'button--secondary', onClick: this.showPreviousResultsPage },
|
|
'Previous Page'
|
|
),
|
|
currentPage < totalPages && _react2.default.createElement(
|
|
'button',
|
|
{ className: 'button--secondary', onClick: this.showNextResultsPage },
|
|
'Next Page'
|
|
)
|
|
)
|
|
) : _react2.default.createElement(
|
|
'p',
|
|
null,
|
|
'There are no claims in this channel'
|
|
)
|
|
);
|
|
}
|
|
}]);
|
|
|
|
return ChannelClaimsDisplay;
|
|
}(_react2.default.Component);
|
|
|
|
;
|
|
|
|
exports.default = ChannelClaimsDisplay;
|
|
|
|
/***/ }),
|
|
/* 107 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
|
|
var _reactRedux = __webpack_require__(1);
|
|
|
|
var _view = __webpack_require__(108);
|
|
|
|
var _view2 = _interopRequireDefault(_view);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
var mapStateToProps = function mapStateToProps(_ref) {
|
|
var defaultThumbnail = _ref.site.defaults.defaultThumbnail;
|
|
|
|
return {
|
|
defaultThumbnail: defaultThumbnail
|
|
};
|
|
};
|
|
|
|
exports.default = (0, _reactRedux.connect)(mapStateToProps, null)(_view2.default);
|
|
|
|
/***/ }),
|
|
/* 108 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
|
|
var _react = __webpack_require__(0);
|
|
|
|
var _react2 = _interopRequireDefault(_react);
|
|
|
|
var _reactRouterDom = __webpack_require__(5);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
var AssetPreview = function AssetPreview(_ref) {
|
|
var defaultThumbnail = _ref.defaultThumbnail,
|
|
_ref$claimData = _ref.claimData,
|
|
name = _ref$claimData.name,
|
|
claimId = _ref$claimData.claimId,
|
|
fileExt = _ref$claimData.fileExt,
|
|
contentType = _ref$claimData.contentType,
|
|
thumbnail = _ref$claimData.thumbnail;
|
|
|
|
var directSourceLink = claimId + '/' + name + '.' + fileExt;
|
|
var showUrlLink = '/' + claimId + '/' + name;
|
|
return _react2.default.createElement(
|
|
'div',
|
|
{ className: 'asset-holder' },
|
|
_react2.default.createElement(
|
|
_reactRouterDom.Link,
|
|
{ to: showUrlLink },
|
|
function () {
|
|
switch (contentType) {
|
|
case 'image/jpeg':
|
|
case 'image/jpg':
|
|
case 'image/png':
|
|
case 'image/gif':
|
|
return _react2.default.createElement('img', {
|
|
className: 'asset-preview',
|
|
src: directSourceLink,
|
|
alt: name
|
|
});
|
|
case 'video/mp4':
|
|
return _react2.default.createElement('img', {
|
|
className: 'asset-preview video',
|
|
src: thumbnail || defaultThumbnail,
|
|
alt: name
|
|
});
|
|
default:
|
|
return _react2.default.createElement(
|
|
'p',
|
|
null,
|
|
'unsupported file type'
|
|
);
|
|
}
|
|
}()
|
|
)
|
|
);
|
|
};
|
|
|
|
exports.default = AssetPreview;
|
|
|
|
/***/ }),
|
|
/* 109 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
|
|
var _reactRedux = __webpack_require__(1);
|
|
|
|
var _view = __webpack_require__(110);
|
|
|
|
var _view2 = _interopRequireDefault(_view);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
var mapStateToProps = function mapStateToProps(_ref) {
|
|
var _ref$site = _ref.site,
|
|
host = _ref$site.host,
|
|
title = _ref$site.title;
|
|
|
|
return {
|
|
host: host,
|
|
title: title
|
|
};
|
|
};
|
|
|
|
exports.default = (0, _reactRedux.connect)(mapStateToProps, null)(_view2.default);
|
|
|
|
/***/ }),
|
|
/* 110 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
|
|
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
|
|
|
var _react = __webpack_require__(0);
|
|
|
|
var _react2 = _interopRequireDefault(_react);
|
|
|
|
var _NavBar = __webpack_require__(8);
|
|
|
|
var _NavBar2 = _interopRequireDefault(_NavBar);
|
|
|
|
var _reactHelmet = __webpack_require__(20);
|
|
|
|
var _reactHelmet2 = _interopRequireDefault(_reactHelmet);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
|
|
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
|
|
|
|
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
|
|
|
|
var FourOhForPage = function (_React$Component) {
|
|
_inherits(FourOhForPage, _React$Component);
|
|
|
|
function FourOhForPage() {
|
|
_classCallCheck(this, FourOhForPage);
|
|
|
|
return _possibleConstructorReturn(this, (FourOhForPage.__proto__ || Object.getPrototypeOf(FourOhForPage)).apply(this, arguments));
|
|
}
|
|
|
|
_createClass(FourOhForPage, [{
|
|
key: 'render',
|
|
value: function render() {
|
|
var _props = this.props,
|
|
title = _props.title,
|
|
host = _props.host;
|
|
|
|
return _react2.default.createElement(
|
|
'div',
|
|
null,
|
|
_react2.default.createElement(
|
|
_reactHelmet2.default,
|
|
null,
|
|
_react2.default.createElement(
|
|
'title',
|
|
null,
|
|
title,
|
|
' - 404'
|
|
),
|
|
_react2.default.createElement('link', { rel: 'canonical', href: host + '/404' })
|
|
),
|
|
_react2.default.createElement(_NavBar2.default, null),
|
|
_react2.default.createElement(
|
|
'div',
|
|
{ className: 'row row--padded' },
|
|
_react2.default.createElement(
|
|
'h2',
|
|
null,
|
|
'404'
|
|
),
|
|
_react2.default.createElement(
|
|
'p',
|
|
null,
|
|
'That page does not exist'
|
|
)
|
|
)
|
|
);
|
|
}
|
|
}]);
|
|
|
|
return FourOhForPage;
|
|
}(_react2.default.Component);
|
|
|
|
;
|
|
|
|
exports.default = FourOhForPage;
|
|
|
|
/***/ }),
|
|
/* 111 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
|
|
exports.default = function () {
|
|
var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : initialState;
|
|
var action = arguments[1];
|
|
|
|
switch (action.type) {
|
|
case actions.FILE_SELECTED:
|
|
return Object.assign({}, initialState, { // note: clears to initial state
|
|
file: action.data
|
|
});
|
|
case actions.FILE_CLEAR:
|
|
return initialState;
|
|
case actions.METADATA_UPDATE:
|
|
return Object.assign({}, state, {
|
|
metadata: Object.assign({}, state.metadata, _defineProperty({}, action.data.name, action.data.value))
|
|
});
|
|
case actions.CLAIM_UPDATE:
|
|
return Object.assign({}, state, {
|
|
claim: action.data
|
|
});
|
|
case actions.SET_PUBLISH_IN_CHANNEL:
|
|
return Object.assign({}, state, {
|
|
publishInChannel: action.channel
|
|
});
|
|
case actions.PUBLISH_STATUS_UPDATE:
|
|
return Object.assign({}, state, {
|
|
status: action.data
|
|
});
|
|
case actions.ERROR_UPDATE:
|
|
return Object.assign({}, state, {
|
|
error: Object.assign({}, state.error, _defineProperty({}, action.data.name, action.data.value))
|
|
});
|
|
case actions.SELECTED_CHANNEL_UPDATE:
|
|
return Object.assign({}, state, {
|
|
selectedChannel: action.data
|
|
});
|
|
case actions.TOGGLE_METADATA_INPUTS:
|
|
return Object.assign({}, state, {
|
|
showMetadataInputs: action.data
|
|
});
|
|
case actions.THUMBNAIL_NEW:
|
|
return Object.assign({}, state, {
|
|
thumbnail: action.data
|
|
});
|
|
default:
|
|
return state;
|
|
}
|
|
};
|
|
|
|
var _publish_action_types = __webpack_require__(22);
|
|
|
|
var actions = _interopRequireWildcard(_publish_action_types);
|
|
|
|
var _publish_channel_select_states = __webpack_require__(33);
|
|
|
|
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
|
|
|
|
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 _require = __webpack_require__(6),
|
|
publishing = _require.publishing;
|
|
|
|
var initialState = {
|
|
disabled: publishing.disabled,
|
|
disabledMessage: publishing.disabledMessage,
|
|
publishInChannel: false,
|
|
selectedChannel: _publish_channel_select_states.LOGIN,
|
|
showMetadataInputs: false,
|
|
status: {
|
|
status: null,
|
|
message: null
|
|
},
|
|
error: {
|
|
file: null,
|
|
url: null,
|
|
channel: null,
|
|
publishSubmit: null
|
|
},
|
|
file: null,
|
|
claim: '',
|
|
metadata: {
|
|
title: '',
|
|
description: '',
|
|
license: '',
|
|
nsfw: false
|
|
},
|
|
thumbnail: null
|
|
};
|
|
|
|
/***/ }),
|
|
/* 112 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
|
|
exports.default = function () {
|
|
var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : initialState;
|
|
var action = arguments[1];
|
|
|
|
switch (action.type) {
|
|
case actions.CHANNEL_UPDATE:
|
|
return Object.assign({}, state, {
|
|
loggedInChannel: action.data
|
|
});
|
|
default:
|
|
return state;
|
|
}
|
|
};
|
|
|
|
var _channel_action_types = __webpack_require__(29);
|
|
|
|
var actions = _interopRequireWildcard(_channel_action_types);
|
|
|
|
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
|
|
|
|
var initialState = {
|
|
loggedInChannel: {
|
|
name: null,
|
|
shortId: null,
|
|
longId: null
|
|
}
|
|
};
|
|
|
|
/***/ }),
|
|
/* 113 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
|
|
exports.default = function () {
|
|
var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : initialState;
|
|
var action = arguments[1];
|
|
|
|
switch (action.type) {
|
|
// handle request
|
|
case actions.REQUEST_ERROR:
|
|
return Object.assign({}, state, {
|
|
request: Object.assign({}, state.request, {
|
|
error: action.data
|
|
})
|
|
});
|
|
case actions.REQUEST_UPDATE:
|
|
return Object.assign({}, state, {
|
|
request: Object.assign({}, state.request, {
|
|
type: action.data.requestType,
|
|
id: action.data.requestId
|
|
})
|
|
});
|
|
// store requests
|
|
case actions.REQUEST_LIST_ADD:
|
|
return Object.assign({}, state, {
|
|
requestList: Object.assign({}, state.requestList, _defineProperty({}, action.data.id, {
|
|
error: action.data.error,
|
|
key: action.data.key
|
|
}))
|
|
});
|
|
// asset data
|
|
case actions.ASSET_ADD:
|
|
return Object.assign({}, state, {
|
|
assetList: Object.assign({}, state.assetList, _defineProperty({}, action.data.id, {
|
|
error: action.data.error,
|
|
name: action.data.name,
|
|
claimId: action.data.claimId,
|
|
shortId: action.data.shortId,
|
|
claimData: action.data.claimData
|
|
}))
|
|
});
|
|
// channel data
|
|
case actions.CHANNEL_ADD:
|
|
return Object.assign({}, state, {
|
|
channelList: Object.assign({}, state.channelList, _defineProperty({}, action.data.id, {
|
|
name: action.data.name,
|
|
longId: action.data.longId,
|
|
shortId: action.data.shortId,
|
|
claimsData: action.data.claimsData
|
|
}))
|
|
});
|
|
case actions.CHANNEL_CLAIMS_UPDATE_SUCCESS:
|
|
return Object.assign({}, state, {
|
|
channelList: Object.assign({}, state.channelList, _defineProperty({}, action.data.channelListId, Object.assign({}, state.channelList[action.data.channelListId], {
|
|
claimsData: action.data.claimsData
|
|
})))
|
|
});
|
|
// display an asset
|
|
case actions.FILE_AVAILABILITY_UPDATE:
|
|
return Object.assign({}, state, {
|
|
displayAsset: Object.assign({}, state.displayAsset, {
|
|
status: action.data
|
|
})
|
|
});
|
|
case actions.DISPLAY_ASSET_ERROR:
|
|
return Object.assign({}, state, {
|
|
displayAsset: Object.assign({}, state.displayAsset, {
|
|
error: action.data,
|
|
status: _asset_display_states.ERROR
|
|
})
|
|
});
|
|
default:
|
|
return state;
|
|
}
|
|
};
|
|
|
|
var _show_action_types = __webpack_require__(13);
|
|
|
|
var actions = _interopRequireWildcard(_show_action_types);
|
|
|
|
var _asset_display_states = __webpack_require__(25);
|
|
|
|
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
|
|
|
|
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 initialState = {
|
|
request: {
|
|
error: null,
|
|
type: null,
|
|
id: null
|
|
},
|
|
requestList: {},
|
|
channelList: {},
|
|
assetList: {},
|
|
displayAsset: {
|
|
error: null,
|
|
status: _asset_display_states.LOCAL_CHECK
|
|
}
|
|
};
|
|
|
|
/***/ }),
|
|
/* 114 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
|
|
exports.default = function () {
|
|
var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : initialState;
|
|
var action = arguments[1];
|
|
|
|
switch (action.type) {
|
|
default:
|
|
return state;
|
|
}
|
|
};
|
|
|
|
var siteConfig = __webpack_require__(6);
|
|
|
|
var googleAnalyticsId = siteConfig.analytics.googleId,
|
|
_siteConfig$assetDefa = siteConfig.assetDefaults,
|
|
defaultThumbnail = _siteConfig$assetDefa.thumbnail,
|
|
defaultDescription = _siteConfig$assetDefa.description,
|
|
_siteConfig$details = siteConfig.details,
|
|
description = _siteConfig$details.description,
|
|
host = _siteConfig$details.host,
|
|
title = _siteConfig$details.title,
|
|
twitter = _siteConfig$details.twitter;
|
|
|
|
|
|
var initialState = {
|
|
description: description,
|
|
googleAnalyticsId: googleAnalyticsId,
|
|
host: host,
|
|
title: title,
|
|
twitter: twitter,
|
|
defaultDescription: defaultDescription,
|
|
defaultThumbnail: defaultThumbnail
|
|
};
|
|
|
|
/***/ }),
|
|
/* 115 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
exports.default = rootSaga;
|
|
|
|
var _effects = __webpack_require__(10);
|
|
|
|
var _show_uri = __webpack_require__(39);
|
|
|
|
var _show_asset = __webpack_require__(40);
|
|
|
|
var _show_channel = __webpack_require__(41);
|
|
|
|
var _file = __webpack_require__(119);
|
|
|
|
var _publish = __webpack_require__(121);
|
|
|
|
var _marked = /*#__PURE__*/regeneratorRuntime.mark(rootSaga);
|
|
|
|
function rootSaga() {
|
|
return regeneratorRuntime.wrap(function rootSaga$(_context) {
|
|
while (1) {
|
|
switch (_context.prev = _context.next) {
|
|
case 0:
|
|
_context.next = 2;
|
|
return (0, _effects.all)([(0, _show_uri.watchHandleShowPageUri)(), (0, _show_asset.watchNewAssetRequest)(), (0, _show_channel.watchNewChannelRequest)(), (0, _show_channel.watchUpdateChannelClaims)(), (0, _file.watchFileIsRequested)(), (0, _publish.watchPublishStart)()]);
|
|
|
|
case 2:
|
|
case 'end':
|
|
return _context.stop();
|
|
}
|
|
}
|
|
}, _marked, this);
|
|
}
|
|
|
|
/***/ }),
|
|
/* 116 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
exports.getLongClaimId = getLongClaimId;
|
|
exports.getShortId = getShortId;
|
|
exports.getClaimData = getClaimData;
|
|
|
|
var _request = __webpack_require__(9);
|
|
|
|
var _request2 = _interopRequireDefault(_request);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
function getLongClaimId(host, name, modifier) {
|
|
var body = {};
|
|
// create request params
|
|
if (modifier) {
|
|
if (modifier.id) {
|
|
body['claimId'] = modifier.id;
|
|
} else {
|
|
body['channelName'] = modifier.channel.name;
|
|
body['channelClaimId'] = modifier.channel.id;
|
|
}
|
|
}
|
|
body['claimName'] = name;
|
|
var params = {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify(body)
|
|
};
|
|
// create url
|
|
var url = host + '/api/claim/long-id';
|
|
// return the request promise
|
|
return (0, _request2.default)(url, params);
|
|
};
|
|
|
|
function getShortId(host, name, claimId) {
|
|
var url = host + '/api/claim/short-id/' + claimId + '/' + name;
|
|
return (0, _request2.default)(url);
|
|
};
|
|
|
|
function getClaimData(host, name, claimId) {
|
|
var url = host + '/api/claim/data/' + name + '/' + claimId;
|
|
return (0, _request2.default)(url);
|
|
};
|
|
|
|
/***/ }),
|
|
/* 117 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
exports.getChannelData = getChannelData;
|
|
exports.getChannelClaims = getChannelClaims;
|
|
|
|
var _request = __webpack_require__(9);
|
|
|
|
var _request2 = _interopRequireDefault(_request);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
function getChannelData(host, id, name) {
|
|
if (!id) id = 'none';
|
|
var url = host + '/api/channel/data/' + name + '/' + id;
|
|
return (0, _request2.default)(url);
|
|
};
|
|
|
|
function getChannelClaims(host, longId, name, page) {
|
|
if (!page) page = 1;
|
|
var url = host + '/api/channel/claims/' + name + '/' + longId + '/' + page;
|
|
return (0, _request2.default)(url);
|
|
};
|
|
|
|
/***/ }),
|
|
/* 118 */
|
|
/***/ (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"); } }; }();
|
|
|
|
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) {
|
|
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 // eslint-disable-line no-unused-vars
|
|
.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];
|
|
|
|
// 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('Check your URL. No channel name after "@".');
|
|
}
|
|
var nameBadChars = channelName.match(module.exports.REGEXP_INVALID_CHANNEL);
|
|
if (nameBadChars) {
|
|
throw new Error('Check your URL. 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('Check your URL. No modifier provided after separator "' + modifierSeperator + '"');
|
|
}
|
|
|
|
if (modifierSeperator === ':') {
|
|
channelClaimId = modifier;
|
|
} else {
|
|
throw new Error('Check your URL. The "' + modifierSeperator + '" modifier is not currently supported');
|
|
}
|
|
}
|
|
return {
|
|
isChannel: isChannel,
|
|
channelName: channelName,
|
|
channelClaimId: channelClaimId || null,
|
|
claimId: claimId || null
|
|
};
|
|
},
|
|
parseClaim: function parseClaim(name) {
|
|
var componentsRegex = new RegExp('([^:$#/.]*)' + // name (stops at the first extension)
|
|
'([:$#.]?)([^/]*)' // extension separator, extension (stops at the first path separator or end)
|
|
);
|
|
|
|
var _componentsRegex$exec3 = componentsRegex // eslint-disable-line no-unused-vars
|
|
.exec(name).map(function (match) {
|
|
return match || null;
|
|
}),
|
|
_componentsRegex$exec4 = _slicedToArray(_componentsRegex$exec3, 4),
|
|
proto = _componentsRegex$exec4[0],
|
|
claimName = _componentsRegex$exec4[1],
|
|
extensionSeperator = _componentsRegex$exec4[2],
|
|
extension = _componentsRegex$exec4[3];
|
|
|
|
// Validate and process name
|
|
|
|
|
|
if (!claimName) {
|
|
throw new Error('Check your URL. No claim name provided before "."');
|
|
}
|
|
var nameBadChars = claimName.match(module.exports.REGEXP_INVALID_CLAIM);
|
|
if (nameBadChars) {
|
|
throw new Error('Check your URL. Invalid characters in claim name: "' + nameBadChars.join(', ') + '".');
|
|
}
|
|
// Validate and process extension
|
|
if (extensionSeperator) {
|
|
if (!extension) {
|
|
throw new Error('Check your URL. No file extension provided after separator "' + extensionSeperator + '".');
|
|
}
|
|
if (extensionSeperator !== '.') {
|
|
throw new Error('Check your URL. The "' + extensionSeperator + '" separator is not supported in the claim name.');
|
|
}
|
|
}
|
|
return {
|
|
claimName: claimName,
|
|
extension: extension || null
|
|
};
|
|
}
|
|
};
|
|
|
|
/***/ }),
|
|
/* 119 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
exports.watchFileIsRequested = watchFileIsRequested;
|
|
|
|
var _effects = __webpack_require__(10);
|
|
|
|
var _show_action_types = __webpack_require__(13);
|
|
|
|
var actions = _interopRequireWildcard(_show_action_types);
|
|
|
|
var _show = __webpack_require__(7);
|
|
|
|
var _asset_display_states = __webpack_require__(25);
|
|
|
|
var _fileApi = __webpack_require__(120);
|
|
|
|
var _site = __webpack_require__(17);
|
|
|
|
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
|
|
|
|
var _marked = /*#__PURE__*/regeneratorRuntime.mark(retrieveFile),
|
|
_marked2 = /*#__PURE__*/regeneratorRuntime.mark(watchFileIsRequested);
|
|
|
|
function retrieveFile(action) {
|
|
var name, claimId, host, isAvailable, _ref;
|
|
|
|
return regeneratorRuntime.wrap(function retrieveFile$(_context) {
|
|
while (1) {
|
|
switch (_context.prev = _context.next) {
|
|
case 0:
|
|
name = action.data.name;
|
|
claimId = action.data.claimId;
|
|
_context.next = 4;
|
|
return (0, _effects.select)(_site.selectSiteHost);
|
|
|
|
case 4:
|
|
host = _context.sent;
|
|
|
|
// see if the file is available
|
|
isAvailable = void 0;
|
|
_context.prev = 6;
|
|
_context.next = 9;
|
|
return (0, _effects.call)(_fileApi.checkFileAvailability, claimId, host, name);
|
|
|
|
case 9:
|
|
_ref = _context.sent;
|
|
isAvailable = _ref.data;
|
|
_context.next = 18;
|
|
break;
|
|
|
|
case 13:
|
|
_context.prev = 13;
|
|
_context.t0 = _context['catch'](6);
|
|
_context.next = 17;
|
|
return (0, _effects.put)((0, _show.updateDisplayAssetError)(_context.t0.message));
|
|
|
|
case 17:
|
|
return _context.abrupt('return', _context.sent);
|
|
|
|
case 18:
|
|
;
|
|
|
|
if (!isAvailable) {
|
|
_context.next = 25;
|
|
break;
|
|
}
|
|
|
|
_context.next = 22;
|
|
return (0, _effects.put)((0, _show.updateDisplayAssetError)(null));
|
|
|
|
case 22:
|
|
_context.next = 24;
|
|
return (0, _effects.put)((0, _show.updateFileAvailability)(_asset_display_states.AVAILABLE));
|
|
|
|
case 24:
|
|
return _context.abrupt('return', _context.sent);
|
|
|
|
case 25:
|
|
_context.next = 27;
|
|
return (0, _effects.put)((0, _show.updateFileAvailability)(_asset_display_states.UNAVAILABLE));
|
|
|
|
case 27:
|
|
_context.prev = 27;
|
|
_context.next = 30;
|
|
return (0, _effects.call)(_fileApi.triggerClaimGet, claimId, host, name);
|
|
|
|
case 30:
|
|
_context.next = 37;
|
|
break;
|
|
|
|
case 32:
|
|
_context.prev = 32;
|
|
_context.t1 = _context['catch'](27);
|
|
_context.next = 36;
|
|
return (0, _effects.put)((0, _show.updateDisplayAssetError)(_context.t1.message));
|
|
|
|
case 36:
|
|
return _context.abrupt('return', _context.sent);
|
|
|
|
case 37:
|
|
;
|
|
_context.next = 40;
|
|
return (0, _effects.put)((0, _show.updateFileAvailability)(_asset_display_states.AVAILABLE));
|
|
|
|
case 40:
|
|
case 'end':
|
|
return _context.stop();
|
|
}
|
|
}
|
|
}, _marked, this, [[6, 13], [27, 32]]);
|
|
};
|
|
|
|
function watchFileIsRequested() {
|
|
return regeneratorRuntime.wrap(function watchFileIsRequested$(_context2) {
|
|
while (1) {
|
|
switch (_context2.prev = _context2.next) {
|
|
case 0:
|
|
_context2.next = 2;
|
|
return (0, _effects.takeLatest)(actions.FILE_REQUESTED, retrieveFile);
|
|
|
|
case 2:
|
|
case 'end':
|
|
return _context2.stop();
|
|
}
|
|
}
|
|
}, _marked2, this);
|
|
};
|
|
|
|
/***/ }),
|
|
/* 120 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
exports.checkFileAvailability = checkFileAvailability;
|
|
exports.triggerClaimGet = triggerClaimGet;
|
|
|
|
var _request = __webpack_require__(9);
|
|
|
|
var _request2 = _interopRequireDefault(_request);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
function checkFileAvailability(claimId, host, name) {
|
|
var url = host + '/api/file/availability/' + name + '/' + claimId;
|
|
return (0, _request2.default)(url);
|
|
}
|
|
|
|
function triggerClaimGet(claimId, host, name) {
|
|
var url = host + '/api/claim/get/' + name + '/' + claimId;
|
|
return (0, _request2.default)(url);
|
|
}
|
|
|
|
/***/ }),
|
|
/* 121 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
exports.watchPublishStart = watchPublishStart;
|
|
|
|
var _effects = __webpack_require__(10);
|
|
|
|
var _publish_action_types = __webpack_require__(22);
|
|
|
|
var actions = _interopRequireWildcard(_publish_action_types);
|
|
|
|
var _publish_claim_states = __webpack_require__(34);
|
|
|
|
var publishStates = _interopRequireWildcard(_publish_claim_states);
|
|
|
|
var _publish = __webpack_require__(4);
|
|
|
|
var _publish2 = __webpack_require__(122);
|
|
|
|
var _channel = __webpack_require__(123);
|
|
|
|
var _site = __webpack_require__(17);
|
|
|
|
var _validate = __webpack_require__(124);
|
|
|
|
var _publish3 = __webpack_require__(125);
|
|
|
|
var _publish4 = __webpack_require__(126);
|
|
|
|
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
|
|
|
|
var _marked = /*#__PURE__*/regeneratorRuntime.mark(publishFile),
|
|
_marked2 = /*#__PURE__*/regeneratorRuntime.mark(watchPublishStart);
|
|
|
|
function publishFile(action) {
|
|
var history, _ref, publishInChannel, selectedChannel, file, claim, metadata, thumbnailChannel, thumbnailChannelId, thumbnail, urlError, _ref2, loggedInChannel, _ref3, host, publishMetadata, publishFormData, publishChannel, _ref4, loadStart, progress, load, success, error;
|
|
|
|
return regeneratorRuntime.wrap(function publishFile$(_context) {
|
|
while (1) {
|
|
switch (_context.prev = _context.next) {
|
|
case 0:
|
|
history = action.data.history;
|
|
_context.next = 3;
|
|
return (0, _effects.select)(_publish2.selectPublishState);
|
|
|
|
case 3:
|
|
_ref = _context.sent;
|
|
publishInChannel = _ref.publishInChannel;
|
|
selectedChannel = _ref.selectedChannel;
|
|
file = _ref.file;
|
|
claim = _ref.claim;
|
|
metadata = _ref.metadata;
|
|
thumbnailChannel = _ref.thumbnailChannel;
|
|
thumbnailChannelId = _ref.thumbnailChannelId;
|
|
thumbnail = _ref.thumbnail;
|
|
urlError = _ref.error.url;
|
|
_context.next = 15;
|
|
return (0, _effects.select)(_channel.selectChannelState);
|
|
|
|
case 15:
|
|
_ref2 = _context.sent;
|
|
loggedInChannel = _ref2.loggedInChannel;
|
|
_context.next = 19;
|
|
return (0, _effects.select)(_site.selectSiteState);
|
|
|
|
case 19:
|
|
_ref3 = _context.sent;
|
|
host = _ref3.host;
|
|
_context.prev = 21;
|
|
|
|
(0, _validate.validateChannelSelection)(publishInChannel, selectedChannel, loggedInChannel);
|
|
_context.next = 30;
|
|
break;
|
|
|
|
case 25:
|
|
_context.prev = 25;
|
|
_context.t0 = _context['catch'](21);
|
|
_context.next = 29;
|
|
return (0, _effects.put)((0, _publish.updateError)('channel', _context.t0.message));
|
|
|
|
case 29:
|
|
return _context.abrupt('return', _context.sent);
|
|
|
|
case 30:
|
|
;
|
|
// validate publish parameters
|
|
_context.prev = 31;
|
|
|
|
(0, _validate.validatePublishParams)(file, claim, urlError);
|
|
_context.next = 40;
|
|
break;
|
|
|
|
case 35:
|
|
_context.prev = 35;
|
|
_context.t1 = _context['catch'](31);
|
|
_context.next = 39;
|
|
return (0, _effects.put)((0, _publish.updateError)('publishSubmit', _context.t1.message));
|
|
|
|
case 39:
|
|
return _context.abrupt('return', _context.sent);
|
|
|
|
case 40:
|
|
// create metadata
|
|
publishMetadata = (0, _publish3.createPublishMetadata)(claim, file, metadata, publishInChannel, selectedChannel);
|
|
|
|
if (thumbnail) {
|
|
// add thumbnail to publish metadata
|
|
publishMetadata['thumbnail'] = (0, _publish3.createThumbnailUrl)(thumbnailChannel, thumbnailChannelId, claim, host);
|
|
}
|
|
// create form data for main publish
|
|
publishFormData = (0, _publish3.createPublishFormData)(file, thumbnail, publishMetadata);
|
|
// make the publish request
|
|
|
|
_context.next = 45;
|
|
return (0, _effects.call)(_publish4.makePublishRequestChannel, publishFormData);
|
|
|
|
case 45:
|
|
publishChannel = _context.sent;
|
|
|
|
case 46:
|
|
if (false) {
|
|
_context.next = 74;
|
|
break;
|
|
}
|
|
|
|
_context.next = 49;
|
|
return (0, _effects.take)(publishChannel);
|
|
|
|
case 49:
|
|
_ref4 = _context.sent;
|
|
loadStart = _ref4.loadStart;
|
|
progress = _ref4.progress;
|
|
load = _ref4.load;
|
|
success = _ref4.success;
|
|
error = _ref4.error;
|
|
|
|
if (!error) {
|
|
_context.next = 59;
|
|
break;
|
|
}
|
|
|
|
_context.next = 58;
|
|
return (0, _effects.put)((0, _publish.updatePublishStatus)(publishStates.FAILED, error.message));
|
|
|
|
case 58:
|
|
return _context.abrupt('return', _context.sent);
|
|
|
|
case 59:
|
|
if (!success) {
|
|
_context.next = 63;
|
|
break;
|
|
}
|
|
|
|
_context.next = 62;
|
|
return (0, _effects.put)((0, _publish.clearFile)());
|
|
|
|
case 62:
|
|
return _context.abrupt('return', history.push('/' + success.data.claimId + '/' + success.data.name));
|
|
|
|
case 63:
|
|
if (!loadStart) {
|
|
_context.next = 66;
|
|
break;
|
|
}
|
|
|
|
_context.next = 66;
|
|
return (0, _effects.put)((0, _publish.updatePublishStatus)(publishStates.LOAD_START, null));
|
|
|
|
case 66:
|
|
if (!progress) {
|
|
_context.next = 69;
|
|
break;
|
|
}
|
|
|
|
_context.next = 69;
|
|
return (0, _effects.put)((0, _publish.updatePublishStatus)(publishStates.LOADING, progress + '%'));
|
|
|
|
case 69:
|
|
if (!load) {
|
|
_context.next = 72;
|
|
break;
|
|
}
|
|
|
|
_context.next = 72;
|
|
return (0, _effects.put)((0, _publish.updatePublishStatus)(publishStates.PUBLISHING, null));
|
|
|
|
case 72:
|
|
_context.next = 46;
|
|
break;
|
|
|
|
case 74:
|
|
case 'end':
|
|
return _context.stop();
|
|
}
|
|
}
|
|
}, _marked, this, [[21, 25], [31, 35]]);
|
|
};
|
|
|
|
function watchPublishStart() {
|
|
return regeneratorRuntime.wrap(function watchPublishStart$(_context2) {
|
|
while (1) {
|
|
switch (_context2.prev = _context2.next) {
|
|
case 0:
|
|
_context2.next = 2;
|
|
return (0, _effects.takeLatest)(actions.PUBLISH_START, publishFile);
|
|
|
|
case 2:
|
|
case 'end':
|
|
return _context2.stop();
|
|
}
|
|
}
|
|
}, _marked2, this);
|
|
};
|
|
|
|
/***/ }),
|
|
/* 122 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
var selectPublishState = exports.selectPublishState = function selectPublishState(state) {
|
|
return state.publish;
|
|
};
|
|
|
|
/***/ }),
|
|
/* 123 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
var selectChannelState = exports.selectChannelState = function selectChannelState(state) {
|
|
return state.channel;
|
|
};
|
|
|
|
/***/ }),
|
|
/* 124 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
var validateChannelSelection = exports.validateChannelSelection = function validateChannelSelection(publishInChannel, selectedChannel, loggedInChannel) {
|
|
if (publishInChannel && selectedChannel !== loggedInChannel.name) {
|
|
throw new Error('Log in to a channel or select Anonymous');
|
|
}
|
|
};
|
|
|
|
var validatePublishParams = exports.validatePublishParams = function validatePublishParams(file, claim, urlError) {
|
|
if (!file) {
|
|
throw new Error('Please choose a file');
|
|
}
|
|
if (!claim) {
|
|
throw new Error('Please enter a URL');
|
|
}
|
|
if (urlError) {
|
|
throw new Error('Fix the url');
|
|
}
|
|
};
|
|
|
|
/***/ }),
|
|
/* 125 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
var createPublishMetadata = exports.createPublishMetadata = function createPublishMetadata(claim, _ref, _ref2, publishInChannel, selectedChannel) {
|
|
var type = _ref.type;
|
|
var title = _ref2.title,
|
|
description = _ref2.description,
|
|
license = _ref2.license,
|
|
nsfw = _ref2.nsfw;
|
|
|
|
var metadata = {
|
|
name: claim,
|
|
title: title,
|
|
description: description,
|
|
license: license,
|
|
nsfw: nsfw,
|
|
type: type
|
|
};
|
|
if (publishInChannel) {
|
|
metadata['channelName'] = selectedChannel;
|
|
}
|
|
return metadata;
|
|
};
|
|
|
|
var createPublishFormData = exports.createPublishFormData = function createPublishFormData(file, thumbnail, metadata) {
|
|
var fd = new FormData();
|
|
// append file
|
|
fd.append('file', file);
|
|
// append thumbnail
|
|
if (thumbnail) {
|
|
fd.append('thumbnail', thumbnail);
|
|
}
|
|
// append metadata
|
|
for (var key in metadata) {
|
|
if (metadata.hasOwnProperty(key)) {
|
|
fd.append(key, metadata[key]);
|
|
}
|
|
}
|
|
return fd;
|
|
};
|
|
|
|
var createThumbnailUrl = exports.createThumbnailUrl = function createThumbnailUrl(channel, channelId, claim, host) {
|
|
return host + '/' + channel + ':' + channelId + '/' + claim + '-thumb.png';
|
|
};
|
|
|
|
/***/ }),
|
|
/* 126 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
exports.makePublishRequestChannel = undefined;
|
|
|
|
var _reduxSaga = __webpack_require__(42);
|
|
|
|
var makePublishRequestChannel = exports.makePublishRequestChannel = function makePublishRequestChannel(fd) {
|
|
return (0, _reduxSaga.eventChannel)(function (emitter) {
|
|
var uri = '/api/claim/publish';
|
|
var xhr = new XMLHttpRequest();
|
|
// add event listeners
|
|
var onLoadStart = function onLoadStart() {
|
|
emitter({ loadStart: true });
|
|
};
|
|
var onProgress = function onProgress(event) {
|
|
if (event.lengthComputable) {
|
|
var percentage = Math.round(event.loaded * 100 / event.total);
|
|
emitter({ progress: percentage });
|
|
}
|
|
};
|
|
var onLoad = function onLoad() {
|
|
emitter({ load: true });
|
|
};
|
|
xhr.upload.addEventListener('loadstart', onLoadStart);
|
|
xhr.upload.addEventListener('progress', onProgress);
|
|
xhr.upload.addEventListener('load', onLoad);
|
|
// set state change handler
|
|
xhr.onreadystatechange = function () {
|
|
if (xhr.readyState === 4) {
|
|
var response = JSON.parse(xhr.response);
|
|
if (xhr.status === 200 && response.success) {
|
|
emitter({ success: response });
|
|
emitter(_reduxSaga.END);
|
|
} else {
|
|
emitter({ error: new Error(response.message) });
|
|
emitter(_reduxSaga.END);
|
|
}
|
|
}
|
|
};
|
|
// open and send
|
|
xhr.open('POST', uri, true);
|
|
xhr.send(fd);
|
|
// clean up
|
|
return function () {
|
|
xhr.upload.removeEventListener('loadstart', onLoadStart);
|
|
xhr.upload.removeEventListener('progress', onProgress);
|
|
xhr.upload.removeEventListener('load', onLoad);
|
|
xhr.onreadystatechange = null;
|
|
xhr.abort();
|
|
};
|
|
}, _reduxSaga.buffers.sliding(2));
|
|
};
|
|
|
|
/***/ }),
|
|
/* 127 */
|
|
/***/ (function(module, exports) {
|
|
|
|
module.exports = require("react-ga");
|
|
|
|
/***/ }),
|
|
/* 128 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
var channelAvailability = __webpack_require__(129);
|
|
var channelClaims = __webpack_require__(135);
|
|
var channelData = __webpack_require__(137);
|
|
var channelShortId = __webpack_require__(138);
|
|
var claimAvailability = __webpack_require__(139);
|
|
var claimData = __webpack_require__(140);
|
|
var claimGet = __webpack_require__(141);
|
|
var claimLongId = __webpack_require__(142);
|
|
var claimPublish = __webpack_require__(143);
|
|
var claimResolve = __webpack_require__(145);
|
|
var claimShortId = __webpack_require__(146);
|
|
var claimList = __webpack_require__(174);
|
|
var fileAvailability = __webpack_require__(147);
|
|
|
|
module.exports = {
|
|
channelAvailability: channelAvailability,
|
|
channelClaims: channelClaims,
|
|
channelData: channelData,
|
|
channelShortId: channelShortId,
|
|
claimAvailability: claimAvailability,
|
|
claimData: claimData,
|
|
claimGet: claimGet,
|
|
claimLongId: claimLongId,
|
|
claimPublish: claimPublish,
|
|
claimResolve: claimResolve,
|
|
claimShortId: claimShortId,
|
|
claimList: claimList,
|
|
fileAvailability: fileAvailability
|
|
};
|
|
|
|
/***/ }),
|
|
/* 129 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
var _require = __webpack_require__(26),
|
|
checkChannelAvailability = _require.checkChannelAvailability;
|
|
|
|
var _require2 = __webpack_require__(15),
|
|
sendGATimingEvent = _require2.sendGATimingEvent;
|
|
|
|
var _require3 = __webpack_require__(3),
|
|
handleErrorResponse = _require3.handleErrorResponse;
|
|
|
|
/*
|
|
|
|
route to check whether site has published to a channel
|
|
|
|
*/
|
|
|
|
var channelAvailability = function channelAvailability() {
|
|
return function (_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;
|
|
|
|
/***/ }),
|
|
/* 130 */
|
|
/***/ (function(module, exports) {
|
|
|
|
module.exports = require("axios");
|
|
|
|
/***/ }),
|
|
/* 131 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
var lbryConfig = {
|
|
api: {
|
|
apiHost: 'localhost',
|
|
apiPort: '5279'
|
|
}
|
|
};
|
|
|
|
module.exports = lbryConfig;
|
|
|
|
/***/ }),
|
|
/* 132 */
|
|
/***/ (function(module, exports) {
|
|
|
|
module.exports = require("universal-analytics");
|
|
|
|
/***/ }),
|
|
/* 133 */
|
|
/***/ (function(module, exports) {
|
|
|
|
module.exports = require("fs");
|
|
|
|
/***/ }),
|
|
/* 134 */
|
|
/***/ (function(module, exports) {
|
|
|
|
module.exports = require("sequelize");
|
|
|
|
/***/ }),
|
|
/* 135 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
var _require = __webpack_require__(19),
|
|
getChannelClaims = _require.getChannelClaims;
|
|
|
|
var _require2 = __webpack_require__(3),
|
|
handleErrorResponse = _require2.handleErrorResponse;
|
|
|
|
var NO_CHANNEL = 'NO_CHANNEL';
|
|
|
|
/*
|
|
|
|
route to get all claims for channel
|
|
|
|
*/
|
|
|
|
var channelClaims = function channelClaims() {
|
|
return function (_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;
|
|
|
|
/***/ }),
|
|
/* 136 */
|
|
/***/ (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;
|
|
}
|
|
};
|
|
|
|
/***/ }),
|
|
/* 137 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
var _require = __webpack_require__(19),
|
|
getChannelData = _require.getChannelData;
|
|
|
|
var _require2 = __webpack_require__(3),
|
|
handleErrorResponse = _require2.handleErrorResponse;
|
|
|
|
var NO_CHANNEL = 'NO_CHANNEL';
|
|
|
|
/*
|
|
|
|
route to get data for a channel
|
|
|
|
*/
|
|
|
|
var channelData = function channelData() {
|
|
return function (_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;
|
|
|
|
/***/ }),
|
|
/* 138 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
var _require = __webpack_require__(3),
|
|
handleErrorResponse = _require.handleErrorResponse;
|
|
|
|
/*
|
|
|
|
route to get a short channel id from long channel Id
|
|
|
|
*/
|
|
|
|
var channelShortIdRoute = function channelShortIdRoute(db) {
|
|
return function (_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;
|
|
|
|
/***/ }),
|
|
/* 139 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
var _require = __webpack_require__(26),
|
|
claimNameIsAvailable = _require.claimNameIsAvailable;
|
|
|
|
var _require2 = __webpack_require__(15),
|
|
sendGATimingEvent = _require2.sendGATimingEvent;
|
|
|
|
var _require3 = __webpack_require__(3),
|
|
handleErrorResponse = _require3.handleErrorResponse;
|
|
|
|
/*
|
|
|
|
route to check whether this site published to a claim
|
|
|
|
*/
|
|
|
|
var claimAvailability = function claimAvailability() {
|
|
return function (_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;
|
|
|
|
/***/ }),
|
|
/* 140 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
var _require = __webpack_require__(3),
|
|
handleErrorResponse = _require.handleErrorResponse;
|
|
|
|
/*
|
|
|
|
route to return data for a claim
|
|
|
|
*/
|
|
|
|
var claimData = function claimData(db) {
|
|
return function (_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;
|
|
|
|
/***/ }),
|
|
/* 141 */
|
|
/***/ (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__(18),
|
|
getClaim = _require.getClaim;
|
|
|
|
var _require2 = __webpack_require__(27),
|
|
addGetResultsToFileData = _require2.addGetResultsToFileData,
|
|
createFileData = _require2.createFileData;
|
|
|
|
var _require3 = __webpack_require__(3),
|
|
handleErrorResponse = _require3.handleErrorResponse;
|
|
|
|
/*
|
|
|
|
route to get a claim
|
|
|
|
*/
|
|
|
|
var claimGet = function claimGet(db) {
|
|
return function (_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;
|
|
|
|
/***/ }),
|
|
/* 142 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
var _require = __webpack_require__(19),
|
|
getClaimId = _require.getClaimId;
|
|
|
|
var _require2 = __webpack_require__(3),
|
|
handleErrorResponse = _require2.handleErrorResponse;
|
|
|
|
var NO_CHANNEL = 'NO_CHANNEL';
|
|
var NO_CLAIM = 'NO_CLAIM';
|
|
|
|
/*
|
|
|
|
route to get a long claim id
|
|
|
|
*/
|
|
|
|
var claimLongId = function claimLongId() {
|
|
return function (_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;
|
|
|
|
/***/ }),
|
|
/* 143 */
|
|
/***/ (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__(27),
|
|
createBasicPublishParams = _require.createBasicPublishParams,
|
|
createThumbnailPublishParams = _require.createThumbnailPublishParams,
|
|
parsePublishApiRequestBody = _require.parsePublishApiRequestBody,
|
|
parsePublishApiRequestFiles = _require.parsePublishApiRequestFiles;
|
|
|
|
var _require2 = __webpack_require__(26),
|
|
claimNameIsAvailable = _require2.claimNameIsAvailable,
|
|
publish = _require2.publish;
|
|
|
|
var _require3 = __webpack_require__(144),
|
|
authenticateUser = _require3.authenticateUser;
|
|
|
|
var _require4 = __webpack_require__(15),
|
|
sendGATimingEvent = _require4.sendGATimingEvent;
|
|
|
|
var _require5 = __webpack_require__(3),
|
|
handleErrorResponse = _require5.handleErrorResponse;
|
|
|
|
var _require6 = __webpack_require__(6),
|
|
host = _require6.details.host;
|
|
|
|
/*
|
|
|
|
route to publish a claim through the daemon
|
|
|
|
*/
|
|
|
|
var claimPublish = function claimPublish(db) {
|
|
return function (_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;
|
|
|
|
/***/ }),
|
|
/* 144 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
var _require = __webpack_require__(14),
|
|
db = _require.db;
|
|
|
|
var logger = __webpack_require__(2);
|
|
|
|
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);
|
|
});
|
|
});
|
|
}
|
|
};
|
|
|
|
/***/ }),
|
|
/* 145 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
var _require = __webpack_require__(18),
|
|
resolveUri = _require.resolveUri;
|
|
|
|
var _require2 = __webpack_require__(3),
|
|
handleErrorResponse = _require2.handleErrorResponse;
|
|
|
|
/*
|
|
|
|
route to run a resolve request on the daemon
|
|
|
|
*/
|
|
|
|
var claimResolve = function claimResolve() {
|
|
return function (_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;
|
|
|
|
/***/ }),
|
|
/* 146 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
var _require = __webpack_require__(3),
|
|
handleErrorResponse = _require.handleErrorResponse;
|
|
|
|
/*
|
|
|
|
route to get a short claim id from long claim Id
|
|
|
|
*/
|
|
|
|
var claimShortId = function claimShortId(db) {
|
|
return function (_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;
|
|
|
|
/***/ }),
|
|
/* 147 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
var _require = __webpack_require__(3),
|
|
handleErrorResponse = _require.handleErrorResponse;
|
|
|
|
/*
|
|
|
|
route to see if asset is available locally
|
|
|
|
*/
|
|
|
|
var fileAvailability = function fileAvailability(db) {
|
|
return function (_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;
|
|
|
|
/***/ }),
|
|
/* 148 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
var serveAssetByClaim = __webpack_require__(149);
|
|
var serveAssetByIdentifierAndClaim = __webpack_require__(152);
|
|
|
|
module.exports = {
|
|
serveAssetByClaim: serveAssetByClaim,
|
|
serveAssetByIdentifierAndClaim: serveAssetByIdentifierAndClaim
|
|
};
|
|
|
|
/***/ }),
|
|
/* 149 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
var _require = __webpack_require__(15),
|
|
sendGAServeEvent = _require.sendGAServeEvent;
|
|
|
|
var _require2 = __webpack_require__(44),
|
|
determineResponseType = _require2.determineResponseType,
|
|
logRequestData = _require2.logRequestData,
|
|
getClaimIdAndServeAsset = _require2.getClaimIdAndServeAsset;
|
|
|
|
var lbryUri = __webpack_require__(45);
|
|
var handleShowRender = __webpack_require__(46);
|
|
var SERVE = 'SERVE';
|
|
|
|
/*
|
|
|
|
route to serve an asset or the react app via the claim name only
|
|
|
|
*/
|
|
|
|
var claim = function claim() {
|
|
return function (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 = claim;
|
|
|
|
/***/ }),
|
|
/* 150 */
|
|
/***/ (function(module, exports) {
|
|
|
|
module.exports = require("react-dom/server");
|
|
|
|
/***/ }),
|
|
/* 151 */
|
|
/***/ (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 ';
|
|
};
|
|
|
|
/***/ }),
|
|
/* 152 */
|
|
/***/ (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__(15),
|
|
sendGAServeEvent = _require.sendGAServeEvent;
|
|
|
|
var _require2 = __webpack_require__(44),
|
|
determineResponseType = _require2.determineResponseType,
|
|
flipClaimNameAndIdForBackwardsCompatibility = _require2.flipClaimNameAndIdForBackwardsCompatibility,
|
|
logRequestData = _require2.logRequestData,
|
|
getClaimIdAndServeAsset = _require2.getClaimIdAndServeAsset;
|
|
|
|
var lbryUri = __webpack_require__(45);
|
|
var handleShowRender = __webpack_require__(46);
|
|
|
|
var SERVE = 'SERVE';
|
|
|
|
/*
|
|
|
|
route to serve an asset or the react app via the claim name and an identifier
|
|
|
|
*/
|
|
|
|
var identifierClaim = function identifierClaim() {
|
|
return function (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 = identifierClaim;
|
|
|
|
/***/ }),
|
|
/* 153 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
var signup = __webpack_require__(154);
|
|
var login = __webpack_require__(155);
|
|
var logout = __webpack_require__(156);
|
|
var user = __webpack_require__(157);
|
|
|
|
module.exports = {
|
|
signup: signup,
|
|
login: login,
|
|
logout: logout,
|
|
user: user
|
|
};
|
|
|
|
/***/ }),
|
|
/* 154 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
var signup = function signup() {
|
|
return function (req, res) {
|
|
res.status(200).json({
|
|
success: true,
|
|
channelName: req.user.channelName,
|
|
channelClaimId: req.user.channelClaimId,
|
|
shortChannelId: req.user.shortChannelId
|
|
});
|
|
};
|
|
};
|
|
|
|
module.exports = signup;
|
|
|
|
/***/ }),
|
|
/* 155 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
var login = function login(passport) {
|
|
return function (req, res, next) {
|
|
passport.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;
|
|
|
|
/***/ }),
|
|
/* 156 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
var logout = function logout() {
|
|
return function (req, res) {
|
|
req.logout();
|
|
res.status(200).json({ success: true, message: 'you successfully logged out' });
|
|
};
|
|
};
|
|
|
|
module.exports = logout;
|
|
|
|
/***/ }),
|
|
/* 157 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
var user = function user() {
|
|
return function (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;
|
|
|
|
/***/ }),
|
|
/* 158 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
var logger = __webpack_require__(2);
|
|
|
|
function LoggerConfig() {
|
|
var _this = this;
|
|
|
|
this.logLevel = 'debug';
|
|
this.configure = function (config) {
|
|
if (!config) {
|
|
return console.log('No logger config received.');
|
|
}
|
|
console.log('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
|
|
console.log('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();
|
|
|
|
/***/ }),
|
|
/* 159 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
var winstonSlackWebHook = __webpack_require__(160).SlackWebHook;
|
|
var winston = __webpack_require__(2);
|
|
|
|
function SlackConfig() {
|
|
var _this = this;
|
|
|
|
this.slackWebHook = 'default';
|
|
this.slackErrorChannel = 'default';
|
|
this.slackInfoChannel = 'default';
|
|
this.configure = function (config) {
|
|
if (!config) {
|
|
return console.log('no slack config received');
|
|
}
|
|
// update variables
|
|
console.log('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
|
|
console.log('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();
|
|
|
|
/***/ }),
|
|
/* 160 */
|
|
/***/ (function(module, exports) {
|
|
|
|
module.exports = require("winston-slack-webhook");
|
|
|
|
/***/ }),
|
|
/* 161 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
var passport = __webpack_require__(162);
|
|
var localLoginStrategy = __webpack_require__(163);
|
|
var localSignupStrategy = __webpack_require__(164);
|
|
|
|
var _require = __webpack_require__(165),
|
|
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;
|
|
|
|
/***/ }),
|
|
/* 162 */
|
|
/***/ (function(module, exports) {
|
|
|
|
module.exports = require("passport");
|
|
|
|
/***/ }),
|
|
/* 163 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
var PassportLocalStrategy = __webpack_require__(47).Strategy;
|
|
var logger = __webpack_require__(2);
|
|
|
|
var _require = __webpack_require__(14),
|
|
db = _require.db;
|
|
|
|
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);
|
|
});
|
|
});
|
|
|
|
/***/ }),
|
|
/* 164 */
|
|
/***/ (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__(47).Strategy;
|
|
var lbryApi = __webpack_require__(18);
|
|
var logger = __webpack_require__(2);
|
|
|
|
var _require = __webpack_require__(14),
|
|
db = _require.db;
|
|
|
|
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);
|
|
});
|
|
});
|
|
|
|
/***/ }),
|
|
/* 165 */
|
|
/***/ (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);
|
|
}
|
|
};
|
|
|
|
/***/ }),
|
|
/* 166 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
var Certificate = __webpack_require__(167);
|
|
var Channel = __webpack_require__(168);
|
|
var Claim = __webpack_require__(169);
|
|
var File = __webpack_require__(170);
|
|
var Request = __webpack_require__(171);
|
|
var User = __webpack_require__(172);
|
|
|
|
module.exports = {
|
|
Certificate: Certificate,
|
|
Channel: Channel,
|
|
Claim: Claim,
|
|
File: File,
|
|
Request: Request,
|
|
User: User
|
|
};
|
|
|
|
/***/ }),
|
|
/* 167 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
var logger = __webpack_require__(2);
|
|
|
|
var _require = __webpack_require__(48),
|
|
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;
|
|
};
|
|
|
|
/***/ }),
|
|
/* 168 */
|
|
/***/ (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;
|
|
};
|
|
|
|
/***/ }),
|
|
/* 169 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
var logger = __webpack_require__(2);
|
|
|
|
var _require = __webpack_require__(48),
|
|
returnShortId = _require.returnShortId;
|
|
|
|
var _require2 = __webpack_require__(6),
|
|
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;
|
|
};
|
|
|
|
/***/ }),
|
|
/* 170 */
|
|
/***/ (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;
|
|
};
|
|
|
|
/***/ }),
|
|
/* 171 */
|
|
/***/ (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;
|
|
};
|
|
|
|
/***/ }),
|
|
/* 172 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
var bcrypt = __webpack_require__(173);
|
|
var logger = __webpack_require__(2);
|
|
|
|
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;
|
|
};
|
|
|
|
/***/ }),
|
|
/* 173 */
|
|
/***/ (function(module, exports) {
|
|
|
|
module.exports = require("bcrypt");
|
|
|
|
/***/ }),
|
|
/* 174 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
var _require = __webpack_require__(18),
|
|
getClaimList = _require.getClaimList;
|
|
|
|
var _require2 = __webpack_require__(3),
|
|
handleErrorResponse = _require2.handleErrorResponse;
|
|
|
|
/*
|
|
|
|
route to get list of claims
|
|
|
|
*/
|
|
|
|
var claimList = function claimList(db) {
|
|
return function (_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;
|
|
|
|
/***/ }),
|
|
/* 175 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
var sendReactApp = __webpack_require__(176);
|
|
var sendEmbedPage = __webpack_require__(178);
|
|
var redirect = __webpack_require__(179);
|
|
|
|
module.exports = {
|
|
sendReactApp: sendReactApp,
|
|
sendEmbedPage: sendEmbedPage,
|
|
redirect: redirect
|
|
};
|
|
|
|
/***/ }),
|
|
/* 176 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
var handlePageRender = __webpack_require__(177);
|
|
|
|
var sendReactApp = function sendReactApp() {
|
|
return function (req, res) {
|
|
handlePageRender(req, res);
|
|
};
|
|
};
|
|
|
|
module.exports = sendReactApp;
|
|
|
|
/***/ }),
|
|
/* 177 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
var _react = __webpack_require__(0);
|
|
|
|
var _react2 = _interopRequireDefault(_react);
|
|
|
|
var _server = __webpack_require__(150);
|
|
|
|
var _redux = __webpack_require__(38);
|
|
|
|
var _reducers = __webpack_require__(37);
|
|
|
|
var _reducers2 = _interopRequireDefault(_reducers);
|
|
|
|
var _reactRedux = __webpack_require__(1);
|
|
|
|
var _reactRouterDom = __webpack_require__(5);
|
|
|
|
var _GAListener = __webpack_require__(43);
|
|
|
|
var _GAListener2 = _interopRequireDefault(_GAListener);
|
|
|
|
var _app = __webpack_require__(28);
|
|
|
|
var _app2 = _interopRequireDefault(_app);
|
|
|
|
var _renderFullPage = __webpack_require__(151);
|
|
|
|
var _renderFullPage2 = _interopRequireDefault(_renderFullPage);
|
|
|
|
var _reactHelmet = __webpack_require__(20);
|
|
|
|
var _reactHelmet2 = _interopRequireDefault(_reactHelmet);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
module.exports = function (req, res) {
|
|
var context = {};
|
|
|
|
// create a new Redux store instance
|
|
var store = (0, _redux.createStore)(_reducers2.default);
|
|
|
|
// 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(
|
|
_GAListener2.default,
|
|
null,
|
|
_react2.default.createElement(_app2.default, 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));
|
|
};
|
|
|
|
/***/ }),
|
|
/* 178 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
var _require = __webpack_require__(6),
|
|
host = _require.details.host;
|
|
|
|
var sendEmbedPage = function sendEmbedPage() {
|
|
return function (_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;
|
|
|
|
/***/ }),
|
|
/* 179 */
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
"use strict";
|
|
|
|
|
|
var redirect = function redirect(route) {
|
|
return function (req, res) {
|
|
res.status(301).redirect(route);
|
|
};
|
|
};
|
|
|
|
module.exports = redirect;
|
|
|
|
/***/ })
|
|
/******/ ]);
|
|
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vd2VicGFjay9ib290c3RyYXAgNWY0MDQ1Yjk2YTY3MjJhODZkZTEiLCJ3ZWJwYWNrOi8vL2V4dGVybmFsIFwicmVhY3RcIiIsIndlYnBhY2s6Ly8vZXh0ZXJuYWwgXCJyZWFjdC1yZWR1eFwiIiwid2VicGFjazovLy9leHRlcm5hbCBcIndpbnN0b25cIiIsIndlYnBhY2s6Ly8vLi9zZXJ2ZXIvaGVscGVycy9lcnJvckhhbmRsZXJzLmpzIiwid2VicGFjazovLy8uL2NsaWVudC9hY3Rpb25zL3B1Ymxpc2guanMiLCJ3ZWJwYWNrOi8vL2V4dGVybmFsIFwicmVhY3Qtcm91dGVyLWRvbVwiIiwid2VicGFjazovLy8uL2NvbmZpZy9zaXRlQ29uZmlnLmpzIiwid2VicGFjazovLy8uL2NsaWVudC9hY3Rpb25zL3Nob3cuanMiLCJ3ZWJwYWNrOi8vLy4vY2xpZW50L2NvbnRhaW5lcnMvTmF2QmFyL2luZGV4LmpzIiwid2VicGFjazovLy8uL2NsaWVudC91dGlscy9yZXF1ZXN0LmpzIiwid2VicGFjazovLy9leHRlcm5hbCBcInJlZHV4LXNhZ2EvZWZmZWN0c1wiIiwid2VicGFjazovLy8uL2NsaWVudC9jb21wb25lbnRzL1NFTy9pbmRleC5qcyIsIndlYnBhY2s6Ly8vZXh0ZXJuYWwgXCJwcm9wLXR5cGVzXCIiLCJ3ZWJwYWNrOi8vLy4vY2xpZW50L2NvbnN0YW50cy9zaG93X2FjdGlvbl90eXBlcy5qcyIsIndlYnBhY2s6Ly8vLi9jb25maWcvbXlzcWxDb25maWcuanMiLCJ3ZWJwYWNrOi8vLy4vc2VydmVyL2hlbHBlcnMvZ29vZ2xlQW5hbHl0aWNzLmpzIiwid2VicGFjazovLy8uL2NsaWVudC9zZWxlY3RvcnMvc2hvdy5qcyIsIndlYnBhY2s6Ly8vLi9jbGllbnQvc2VsZWN0b3JzL3NpdGUuanMiLCJ3ZWJwYWNrOi8vLy4vc2VydmVyL2hlbHBlcnMvbGJyeUFwaS5qcyIsIndlYnBhY2s6Ly8vLi9zZXJ2ZXIvY29udHJvbGxlcnMvc2VydmVDb250cm9sbGVyLmpzIiwid2VicGFjazovLy9leHRlcm5hbCBcInJlYWN0LWhlbG1ldFwiIiwid2VicGFjazovLy8uL2NsaWVudC9hY3Rpb25zL2NoYW5uZWwuanMiLCJ3ZWJwYWNrOi8vLy4vY2xpZW50L2NvbnN0YW50cy9wdWJsaXNoX2FjdGlvbl90eXBlcy5qcyIsIndlYnBhY2s6Ly8vLi9jbGllbnQvY29tcG9uZW50cy9Qcm9ncmVzc0Jhci9pbmRleC5qc3giLCJ3ZWJwYWNrOi8vLy4vY2xpZW50L3BhZ2VzL0Vycm9yUGFnZS9pbmRleC5qc3giLCJ3ZWJwYWNrOi8vLy4vY2xpZW50L2NvbnN0YW50cy9hc3NldF9kaXNwbGF5X3N0YXRlcy5qcyIsIndlYnBhY2s6Ly8vLi9zZXJ2ZXIvY29udHJvbGxlcnMvcHVibGlzaENvbnRyb2xsZXIuanMiLCJ3ZWJwYWNrOi8vLy4vc2VydmVyL2hlbHBlcnMvcHVibGlzaEhlbHBlcnMuanMiLCJ3ZWJwYWNrOi8vLy4vY2xpZW50L2FwcC5qcyIsIndlYnBhY2s6Ly8vLi9jbGllbnQvY29uc3RhbnRzL2NoYW5uZWxfYWN0aW9uX3R5cGVzLmpzIiwid2VicGFjazovLy8uL2NsaWVudC9jb250YWluZXJzL0Ryb3B6b25lL2luZGV4LmpzIiwid2VicGFjazovLy8uL2NsaWVudC9jb250YWluZXJzL0NoYW5uZWxMb2dpbkZvcm0vaW5kZXguanMiLCJ3ZWJwYWNrOi8vLy4vY2xpZW50L2NvbnRhaW5lcnMvQ2hhbm5lbENyZWF0ZUZvcm0vaW5kZXguanMiLCJ3ZWJwYWNrOi8vLy4vY2xpZW50L2NvbnN0YW50cy9wdWJsaXNoX2NoYW5uZWxfc2VsZWN0X3N0YXRlcy5qcyIsIndlYnBhY2s6Ly8vLi9jbGllbnQvY29uc3RhbnRzL3B1Ymxpc2hfY2xhaW1fc3RhdGVzLmpzIiwid2VicGFjazovLy8uL2NsaWVudC9jb25zdGFudHMvc2hvd19yZXF1ZXN0X3R5cGVzLmpzIiwid2VicGFjazovLy8uL2NsaWVudC9jb250YWluZXJzL0Fzc2V0RGlzcGxheS9pbmRleC5qcyIsIndlYnBhY2s6Ly8vLi9jbGllbnQvcmVkdWNlcnMvaW5kZXguanMiLCJ3ZWJwYWNrOi8vL2V4dGVybmFsIFwicmVkdXhcIiIsIndlYnBhY2s6Ly8vLi9jbGllbnQvc2FnYXMvc2hvd191cmkuanMiLCJ3ZWJwYWNrOi8vLy4vY2xpZW50L3NhZ2FzL3Nob3dfYXNzZXQuanMiLCJ3ZWJwYWNrOi8vLy4vY2xpZW50L3NhZ2FzL3Nob3dfY2hhbm5lbC5qcyIsIndlYnBhY2s6Ly8vZXh0ZXJuYWwgXCJyZWR1eC1zYWdhXCIiLCJ3ZWJwYWNrOi8vLy4vY2xpZW50L2NvbXBvbmVudHMvR0FMaXN0ZW5lci9pbmRleC5qc3giLCJ3ZWJwYWNrOi8vLy4vc2VydmVyL2hlbHBlcnMvc2VydmVIZWxwZXJzLmpzIiwid2VicGFjazovLy8uL3NlcnZlci9oZWxwZXJzL2xicnlVcmkuanMiLCJ3ZWJwYWNrOi8vLy4vc2VydmVyL2hlbHBlcnMvaGFuZGxlU2hvd1JlbmRlci5qc3giLCJ3ZWJwYWNrOi8vL2V4dGVybmFsIFwicGFzc3BvcnQtbG9jYWxcIiIsIndlYnBhY2s6Ly8vLi9zZXJ2ZXIvaGVscGVycy9zZXF1ZWxpemVIZWxwZXJzLmpzIiwid2VicGFjazovLy9leHRlcm5hbCBcImJhYmVsLXBvbHlmaWxsXCIiLCJ3ZWJwYWNrOi8vL2V4dGVybmFsIFwid2hhdHdnLWZldGNoXCIiLCJ3ZWJwYWNrOi8vLy4vc3BlZWNoLmpzIiwid2VicGFjazovLy8uL2NsaWVudC9wYWdlcy9Ib21lUGFnZS9pbmRleC5qc3giLCJ3ZWJwYWNrOi8vLy4vY2xpZW50L2NvbXBvbmVudHMvU0VPL3ZpZXcuanN4Iiwid2VicGFjazovLy8uL2NsaWVudC91dGlscy9wYWdlVGl0bGUuanMiLCJ3ZWJwYWNrOi8vLy4vY2xpZW50L3V0aWxzL21ldGFUYWdzLmpzIiwid2VicGFjazovLy8uL2NsaWVudC91dGlscy9jYW5vbmljYWxMaW5rLmpzIiwid2VicGFjazovLy8uL2NsaWVudC9jb250YWluZXJzL05hdkJhci92aWV3LmpzeCIsIndlYnBhY2s6Ly8vLi9jbGllbnQvY29tcG9uZW50cy9Mb2dvL2luZGV4LmpzeCIsIndlYnBhY2s6Ly8vLi9jbGllbnQvY29tcG9uZW50cy9OYXZCYXJDaGFubmVsT3B0aW9uc0Ryb3Bkb3duL2luZGV4LmpzeCIsIndlYnBhY2s6Ly8vZXh0ZXJuYWwgXCJjcm9zcy1mZXRjaC9wb2x5ZmlsbFwiIiwid2VicGFjazovLy8uL2NsaWVudC9jb250YWluZXJzL1B1Ymxpc2hUb29sL2luZGV4LmpzIiwid2VicGFjazovLy8uL2NsaWVudC9jb250YWluZXJzL1B1Ymxpc2hUb29sL3ZpZXcuanN4Iiwid2VicGFjazovLy8uL2NsaWVudC9jb250YWluZXJzL0Ryb3B6b25lL3ZpZXcuanN4Iiwid2VicGFjazovLy8uL2NsaWVudC91dGlscy9maWxlLmpzIiwid2VicGFjazovLy8uL2NsaWVudC9jb21wb25lbnRzL1B1Ymxpc2hQcmV2aWV3L2luZGV4LmpzeCIsIndlYnBhY2s6Ly8vLi9jbGllbnQvY29udGFpbmVycy9QdWJsaXNoRGV0YWlscy9pbmRleC5qcyIsIndlYnBhY2s6Ly8vLi9jbGllbnQvY29udGFpbmVycy9QdWJsaXNoRGV0YWlscy92aWV3LmpzeCIsIndlYnBhY2s6Ly8vLi9jbGllbnQvY29udGFpbmVycy9QdWJsaXNoVGl0bGVJbnB1dC9pbmRleC5qcyIsIndlYnBhY2s6Ly8vLi9jbGllbnQvY29udGFpbmVycy9QdWJsaXNoVGl0bGVJbnB1dC92aWV3LmpzeCIsIndlYnBhY2s6Ly8vLi9jbGllbnQvY29udGFpbmVycy9QdWJsaXNoVXJsSW5wdXQvaW5kZXguanMiLCJ3ZWJwYWNrOi8vLy4vY2xpZW50L2NvbnRhaW5lcnMvUHVibGlzaFVybElucHV0L3ZpZXcuanN4Iiwid2VicGFjazovLy8uL2NsaWVudC9jb21wb25lbnRzL1B1Ymxpc2hVcmxNaWRkbGVEaXNwbGF5L2luZGV4LmpzeCIsIndlYnBhY2s6Ly8vLi9jbGllbnQvY29udGFpbmVycy9QdWJsaXNoVGh1bWJuYWlsSW5wdXQvaW5kZXguanMiLCJ3ZWJwYWNrOi8vLy4vY2xpZW50L2NvbnRhaW5lcnMvUHVibGlzaFRodW1ibmFpbElucHV0L3ZpZXcuanN4Iiwid2VicGFjazovLy8uL2NsaWVudC9jb250YWluZXJzL1B1Ymxpc2hNZXRhZGF0YUlucHV0cy9pbmRleC5qcyIsIndlYnBhY2s6Ly8vLi9jbGllbnQvY29udGFpbmVycy9QdWJsaXNoTWV0YWRhdGFJbnB1dHMvdmlldy5qc3giLCJ3ZWJwYWNrOi8vLy4vY2xpZW50L2NvbXBvbmVudHMvRXhwYW5kaW5nVGV4dEFyZWEvaW5kZXguanN4Iiwid2VicGFjazovLy8uL2NsaWVudC9jb250YWluZXJzL0NoYW5uZWxTZWxlY3QvaW5kZXguanMiLCJ3ZWJwYWNrOi8vLy4vY2xpZW50L2NvbnRhaW5lcnMvQ2hhbm5lbFNlbGVjdC92aWV3LmpzeCIsIndlYnBhY2s6Ly8vLi9jbGllbnQvY29udGFpbmVycy9DaGFubmVsTG9naW5Gb3JtL3ZpZXcuanN4Iiwid2VicGFjazovLy8uL2NsaWVudC9jb250YWluZXJzL0NoYW5uZWxDcmVhdGVGb3JtL3ZpZXcuanN4Iiwid2VicGFjazovLy8uL2NsaWVudC9jb21wb25lbnRzL0FjdGl2ZVN0YXR1c0Jhci9pbmRleC5qc3giLCJ3ZWJwYWNrOi8vLy4vY2xpZW50L2NvbXBvbmVudHMvSW5hY3RpdmVTdGF0dXNCYXIvaW5kZXguanN4Iiwid2VicGFjazovLy8uL2NsaWVudC9jb250YWluZXJzL1B1Ymxpc2hTdGF0dXMvaW5kZXguanMiLCJ3ZWJwYWNrOi8vLy4vY2xpZW50L2NvbnRhaW5lcnMvUHVibGlzaFN0YXR1cy92aWV3LmpzeCIsIndlYnBhY2s6Ly8vLi9jbGllbnQvY29udGFpbmVycy9QdWJsaXNoRGlzYWJsZWRNZXNzYWdlL2luZGV4LmpzIiwid2VicGFjazovLy8uL2NsaWVudC9jb250YWluZXJzL1B1Ymxpc2hEaXNhYmxlZE1lc3NhZ2Uvdmlldy5qc3giLCJ3ZWJwYWNrOi8vLy4vY2xpZW50L3BhZ2VzL0Fib3V0UGFnZS9pbmRleC5qc3giLCJ3ZWJwYWNrOi8vLy4vY2xpZW50L3BhZ2VzL0xvZ2luUGFnZS9pbmRleC5qcyIsIndlYnBhY2s6Ly8vLi9jbGllbnQvcGFnZXMvTG9naW5QYWdlL3ZpZXcuanN4Iiwid2VicGFjazovLy8uL2NsaWVudC9wYWdlcy9TaG93UGFnZS9pbmRleC5qcyIsIndlYnBhY2s6Ly8vLi9jbGllbnQvcGFnZXMvU2hvd1BhZ2Uvdmlldy5qc3giLCJ3ZWJwYWNrOi8vLy4vY2xpZW50L2NvbnRhaW5lcnMvU2hvd0Fzc2V0TGl0ZS9pbmRleC5qcyIsIndlYnBhY2s6Ly8vLi9jbGllbnQvY29udGFpbmVycy9TaG93QXNzZXRMaXRlL3ZpZXcuanN4Iiwid2VicGFjazovLy8uL2NsaWVudC9jb250YWluZXJzL0Fzc2V0RGlzcGxheS92aWV3LmpzeCIsIndlYnBhY2s6Ly8vLi9jbGllbnQvY29udGFpbmVycy9TaG93QXNzZXREZXRhaWxzL2luZGV4LmpzIiwid2VicGFjazovLy8uL2NsaWVudC9jb250YWluZXJzL1Nob3dBc3NldERldGFpbHMvdmlldy5qc3giLCJ3ZWJwYWNrOi8vLy4vY2xpZW50L2NvbnRhaW5lcnMvQXNzZXRUaXRsZS9pbmRleC5qcyIsIndlYnBhY2s6Ly8vLi9jbGllbnQvY29udGFpbmVycy9Bc3NldFRpdGxlL3ZpZXcuanN4Iiwid2VicGFjazovLy8uL2NsaWVudC9jb250YWluZXJzL0Fzc2V0SW5mby9pbmRleC5qcyIsIndlYnBhY2s6Ly8vLi9jbGllbnQvY29udGFpbmVycy9Bc3NldEluZm8vdmlldy5qc3giLCJ3ZWJwYWNrOi8vLy4vY2xpZW50L2NvbnRhaW5lcnMvU2hvd0NoYW5uZWwvaW5kZXguanMiLCJ3ZWJwYWNrOi8vLy4vY2xpZW50L2NvbnRhaW5lcnMvU2hvd0NoYW5uZWwvdmlldy5qc3giLCJ3ZWJwYWNrOi8vLy4vY2xpZW50L2NvbnRhaW5lcnMvQ2hhbm5lbENsYWltc0Rpc3BsYXkvaW5kZXguanMiLCJ3ZWJwYWNrOi8vLy4vY2xpZW50L2NvbnRhaW5lcnMvQ2hhbm5lbENsYWltc0Rpc3BsYXkvdmlldy5qc3giLCJ3ZWJwYWNrOi8vLy4vY2xpZW50L2NvbXBvbmVudHMvQXNzZXRQcmV2aWV3L2luZGV4LmpzIiwid2VicGFjazovLy8uL2NsaWVudC9jb21wb25lbnRzL0Fzc2V0UHJldmlldy92aWV3LmpzeCIsIndlYnBhY2s6Ly8vLi9jbGllbnQvY29udGFpbmVycy9Gb3VyT2hGb3VyUGFnZS9pbmRleC5qc3giLCJ3ZWJwYWNrOi8vLy4vY2xpZW50L2NvbnRhaW5lcnMvRm91ck9oRm91clBhZ2Uvdmlldy5qc3giLCJ3ZWJwYWNrOi8vLy4vY2xpZW50L3JlZHVjZXJzL3B1Ymxpc2guanMiLCJ3ZWJwYWNrOi8vLy4vY2xpZW50L3JlZHVjZXJzL2NoYW5uZWwuanMiLCJ3ZWJwYWNrOi8vLy4vY2xpZW50L3JlZHVjZXJzL3Nob3cuanMiLCJ3ZWJwYWNrOi8vLy4vY2xpZW50L3JlZHVjZXJzL3NpdGUuanMiLCJ3ZWJwYWNrOi8vLy4vY2xpZW50L3NhZ2FzL2luZGV4LmpzIiwid2VicGFjazovLy8uL2NsaWVudC9hcGkvYXNzZXRBcGkuanMiLCJ3ZWJwYWNrOi8vLy4vY2xpZW50L2FwaS9jaGFubmVsQXBpLmpzIiwid2VicGFjazovLy8uL2NsaWVudC91dGlscy9sYnJ5VXJpLmpzIiwid2VicGFjazovLy8uL2NsaWVudC9zYWdhcy9maWxlLmpzIiwid2VicGFjazovLy8uL2NsaWVudC9hcGkvZmlsZUFwaS5qcyIsIndlYnBhY2s6Ly8vLi9jbGllbnQvc2FnYXMvcHVibGlzaC5qcyIsIndlYnBhY2s6Ly8vLi9jbGllbnQvc2VsZWN0b3JzL3B1Ymxpc2guanMiLCJ3ZWJwYWNrOi8vLy4vY2xpZW50L3NlbGVjdG9ycy9jaGFubmVsLmpzIiwid2VicGFjazovLy8uL2NsaWVudC91dGlscy92YWxpZGF0ZS5qcyIsIndlYnBhY2s6Ly8vLi9jbGllbnQvdXRpbHMvcHVibGlzaC5qcyIsIndlYnBhY2s6Ly8vLi9jbGllbnQvY2hhbm5lbHMvcHVibGlzaC5qcyIsIndlYnBhY2s6Ly8vZXh0ZXJuYWwgXCJyZWFjdC1nYVwiIiwid2VicGFjazovLy8uL3NlcnZlci9yb3V0ZXMvYXBpL2luZGV4LmpzIiwid2VicGFjazovLy8uL3NlcnZlci9yb3V0ZXMvYXBpL2NoYW5uZWxBdmFpbGFiaWxpdHkuanMiLCJ3ZWJwYWNrOi8vL2V4dGVybmFsIFwiYXhpb3NcIiIsIndlYnBhY2s6Ly8vLi9jb25maWcvbGJyeUNvbmZpZy5qcyIsIndlYnBhY2s6Ly8vZXh0ZXJuYWwgXCJ1bml2ZXJzYWwtYW5hbHl0aWNzXCIiLCJ3ZWJwYWNrOi8vL2V4dGVybmFsIFwiZnNcIiIsIndlYnBhY2s6Ly8vZXh0ZXJuYWwgXCJzZXF1ZWxpemVcIiIsIndlYnBhY2s6Ly8vLi9zZXJ2ZXIvcm91dGVzL2FwaS9jaGFubmVsQ2xhaW1zLmpzIiwid2VicGFjazovLy8uL3NlcnZlci9oZWxwZXJzL2NoYW5uZWxQYWdpbmF0aW9uLmpzIiwid2VicGFjazovLy8uL3NlcnZlci9yb3V0ZXMvYXBpL2NoYW5uZWxEYXRhLmpzIiwid2VicGFjazovLy8uL3NlcnZlci9yb3V0ZXMvYXBpL2NoYW5uZWxTaG9ydElkLmpzIiwid2VicGFjazovLy8uL3NlcnZlci9yb3V0ZXMvYXBpL2NsYWltQXZhaWxhYmlsaXR5LmpzIiwid2VicGFjazovLy8uL3NlcnZlci9yb3V0ZXMvYXBpL2NsYWltRGF0YS5qcyIsIndlYnBhY2s6Ly8vLi9zZXJ2ZXIvcm91dGVzL2FwaS9jbGFpbUdldC5qcyIsIndlYnBhY2s6Ly8vLi9zZXJ2ZXIvcm91dGVzL2FwaS9jbGFpbUxvbmdJZC5qcyIsIndlYnBhY2s6Ly8vLi9zZXJ2ZXIvcm91dGVzL2FwaS9jbGFpbVB1Ymxpc2guanMiLCJ3ZWJwYWNrOi8vLy4vc2VydmVyL2F1dGgvYXV0aGVudGljYXRpb24uanMiLCJ3ZWJwYWNrOi8vLy4vc2VydmVyL3JvdXRlcy9hcGkvY2xhaW1SZXNvbHZlLmpzIiwid2VicGFjazovLy8uL3NlcnZlci9yb3V0ZXMvYXBpL2NsYWltU2hvcnRJZC5qcyIsIndlYnBhY2s6Ly8vLi9zZXJ2ZXIvcm91dGVzL2FwaS9maWxlQXZhaWxhYmlsaXR5LmpzIiwid2VicGFjazovLy8uL3NlcnZlci9yb3V0ZXMvYXNzZXQvaW5kZXguanMiLCJ3ZWJwYWNrOi8vLy4vc2VydmVyL3JvdXRlcy9hc3NldC9zZXJ2ZUFzc2V0QnlDbGFpbS5qcyIsIndlYnBhY2s6Ly8vZXh0ZXJuYWwgXCJyZWFjdC1kb20vc2VydmVyXCIiLCJ3ZWJwYWNrOi8vLy4vc2VydmVyL2hlbHBlcnMvcmVuZGVyRnVsbFBhZ2UuanMiLCJ3ZWJwYWNrOi8vLy4vc2VydmVyL3JvdXRlcy9hc3NldC9zZXJ2ZUFzc2V0QnlJZGVudGlmaWVyQW5kQ2xhaW0uanMiLCJ3ZWJwYWNrOi8vLy4vc2VydmVyL3JvdXRlcy9hdXRoL2luZGV4LmpzIiwid2VicGFjazovLy8uL3NlcnZlci9yb3V0ZXMvYXV0aC9zaWdudXAuanMiLCJ3ZWJwYWNrOi8vLy4vc2VydmVyL3JvdXRlcy9hdXRoL2xvZ2luLmpzIiwid2VicGFjazovLy8uL3NlcnZlci9yb3V0ZXMvYXV0aC9sb2dvdXQuanMiLCJ3ZWJwYWNrOi8vLy4vc2VydmVyL3JvdXRlcy9hdXRoL3VzZXIuanMiLCJ3ZWJwYWNrOi8vLy4vY29uZmlnL2xvZ2dlckNvbmZpZy5qcyIsIndlYnBhY2s6Ly8vLi9jb25maWcvc2xhY2tDb25maWcuanMiLCJ3ZWJwYWNrOi8vL2V4dGVybmFsIFwid2luc3Rvbi1zbGFjay13ZWJob29rXCIiLCJ3ZWJwYWNrOi8vLy4vc2VydmVyL3Bhc3Nwb3J0L2luZGV4LmpzIiwid2VicGFjazovLy9leHRlcm5hbCBcInBhc3Nwb3J0XCIiLCJ3ZWJwYWNrOi8vLy4vc2VydmVyL3Bhc3Nwb3J0L2xvY2FsLWxvZ2luLmpzIiwid2VicGFjazovLy8uL3NlcnZlci9wYXNzcG9ydC9sb2NhbC1zaWdudXAuanMiLCJ3ZWJwYWNrOi8vLy4vc2VydmVyL2hlbHBlcnMvYXV0aEhlbHBlcnMuanMiLCJ3ZWJwYWNrOi8vLy4vc2VydmVyL21vZGVscy9pbmRleC5qcyIsIndlYnBhY2s6Ly8vLi9zZXJ2ZXIvbW9kZWxzL2NlcnRpZmljYXRlLmpzIiwid2VicGFjazovLy8uL3NlcnZlci9tb2RlbHMvY2hhbm5lbC5qcyIsIndlYnBhY2s6Ly8vLi9zZXJ2ZXIvbW9kZWxzL2NsYWltLmpzIiwid2VicGFjazovLy8uL3NlcnZlci9tb2RlbHMvZmlsZS5qcyIsIndlYnBhY2s6Ly8vLi9zZXJ2ZXIvbW9kZWxzL3JlcXVlc3QuanMiLCJ3ZWJwYWNrOi8vLy4vc2VydmVyL21vZGVscy91c2VyLmpzIiwid2VicGFjazovLy9leHRlcm5hbCBcImJjcnlwdFwiIiwid2VicGFjazovLy8uL3NlcnZlci9yb3V0ZXMvYXBpL2NsYWltTGlzdC5qcyIsIndlYnBhY2s6Ly8vLi9zZXJ2ZXIvcm91dGVzL3BhZ2UvaW5kZXguanMiLCJ3ZWJwYWNrOi8vLy4vc2VydmVyL3JvdXRlcy9wYWdlL3NlbmRSZWFjdEFwcC5qcyIsIndlYnBhY2s6Ly8vLi9zZXJ2ZXIvaGVscGVycy9oYW5kbGVQYWdlUmVuZGVyLmpzeCIsIndlYnBhY2s6Ly8vLi9zZXJ2ZXIvcm91dGVzL3BhZ2Uvc2VuZEVtYmVkUGFnZS5qcyIsIndlYnBhY2s6Ly8vLi9zZXJ2ZXIvcm91dGVzL3BhZ2UvcmVkaXJlY3QuanMiXSwibmFtZXMiOlsibG9nZ2VyIiwicmVxdWlyZSIsIm1vZHVsZSIsImV4cG9ydHMiLCJoYW5kbGVFcnJvclJlc3BvbnNlIiwib3JpZ2luYWxVcmwiLCJpcCIsImVycm9yIiwicmVzIiwidXNlT2JqZWN0UHJvcGVydGllc0lmTm9LZXlzIiwicmV0dXJuRXJyb3JNZXNzYWdlQW5kU3RhdHVzIiwic3RhdHVzIiwibWVzc2FnZSIsImpzb24iLCJjcmVhdGVFcnJvclJlc3BvbnNlUGF5bG9hZCIsImNvZGUiLCJlcnIiLCJPYmplY3QiLCJrZXlzIiwibGVuZ3RoIiwibmV3RXJyb3JPYmplY3QiLCJnZXRPd25Qcm9wZXJ0eU5hbWVzIiwiZm9yRWFjaCIsImtleSIsInN1Y2Nlc3MiLCJzZWxlY3RGaWxlIiwiY2xlYXJGaWxlIiwidXBkYXRlTWV0YWRhdGEiLCJ1cGRhdGVDbGFpbSIsInNldFB1Ymxpc2hJbkNoYW5uZWwiLCJ1cGRhdGVQdWJsaXNoU3RhdHVzIiwidXBkYXRlRXJyb3IiLCJ1cGRhdGVTZWxlY3RlZENoYW5uZWwiLCJ0b2dnbGVNZXRhZGF0YUlucHV0cyIsIm9uTmV3VGh1bWJuYWlsIiwic3RhcnRQdWJsaXNoIiwiYWN0aW9ucyIsImZpbGUiLCJ0eXBlIiwiRklMRV9TRUxFQ1RFRCIsImRhdGEiLCJGSUxFX0NMRUFSIiwibmFtZSIsInZhbHVlIiwiTUVUQURBVEFfVVBEQVRFIiwiQ0xBSU1fVVBEQVRFIiwiY2hhbm5lbCIsIlNFVF9QVUJMSVNIX0lOX0NIQU5ORUwiLCJQVUJMSVNIX1NUQVRVU19VUERBVEUiLCJFUlJPUl9VUERBVEUiLCJjaGFubmVsTmFtZSIsIlNFTEVDVEVEX0NIQU5ORUxfVVBEQVRFIiwic2hvd01ldGFkYXRhSW5wdXRzIiwiVE9HR0xFX01FVEFEQVRBX0lOUFVUUyIsIlRIVU1CTkFJTF9ORVciLCJoaXN0b3J5IiwiUFVCTElTSF9TVEFSVCIsIlNpdGVDb25maWciLCJhbmFseXRpY3MiLCJnb29nbGVJZCIsImFzc2V0RGVmYXVsdHMiLCJkZXNjcmlwdGlvbiIsInRodW1ibmFpbCIsInRpdGxlIiwiYXV0aCIsInNlc3Npb25LZXkiLCJjdXN0b21Db21wb25lbnRzIiwiY29tcG9uZW50cyIsImNvbnRhaW5lcnMiLCJwYWdlcyIsImRldGFpbHMiLCJob3N0IiwicG9ydCIsInR3aXR0ZXIiLCJwdWJsaXNoaW5nIiwiYWRkaXRpb25hbENsYWltQWRkcmVzc2VzIiwiZGlzYWJsZWQiLCJkaXNhYmxlZE1lc3NhZ2UiLCJwcmltYXJ5Q2xhaW1BZGRyZXNzIiwidGh1bWJuYWlsQ2hhbm5lbCIsInRodW1ibmFpbENoYW5uZWxJZCIsInVwbG9hZERpcmVjdG9yeSIsImNvbmZpZ3VyZSIsImNvbmZpZyIsImNvbnNvbGUiLCJsb2ciLCJvbkhhbmRsZVNob3dQYWdlVXJpIiwib25SZXF1ZXN0RXJyb3IiLCJvbk5ld0NoYW5uZWxSZXF1ZXN0Iiwib25OZXdBc3NldFJlcXVlc3QiLCJvblJlcXVlc3RVcGRhdGUiLCJhZGRSZXF1ZXN0VG9SZXF1ZXN0TGlzdCIsImFkZEFzc2V0VG9Bc3NldExpc3QiLCJhZGROZXdDaGFubmVsVG9DaGFubmVsTGlzdCIsIm9uVXBkYXRlQ2hhbm5lbENsYWltcyIsInVwZGF0ZUNoYW5uZWxDbGFpbXMiLCJmaWxlUmVxdWVzdGVkIiwidXBkYXRlRmlsZUF2YWlsYWJpbGl0eSIsInVwZGF0ZURpc3BsYXlBc3NldEVycm9yIiwicGFyYW1zIiwiSEFORExFX1NIT1dfVVJJIiwiUkVRVUVTVF9FUlJPUiIsImNoYW5uZWxJZCIsInJlcXVlc3RUeXBlIiwicmVxdWVzdElkIiwiQ0hBTk5FTF9SRVFVRVNUX05FVyIsImlkIiwiZXh0ZW5zaW9uIiwiQVNTRVRfUkVRVUVTVF9ORVciLCJtb2RpZmllciIsIlJFUVVFU1RfVVBEQVRFIiwiUkVRVUVTVF9MSVNUX0FERCIsImNsYWltSWQiLCJzaG9ydElkIiwiY2xhaW1EYXRhIiwiQVNTRVRfQUREIiwibG9uZ0lkIiwiY2xhaW1zRGF0YSIsIkNIQU5ORUxfQUREIiwiY2hhbm5lbEtleSIsInBhZ2UiLCJDSEFOTkVMX0NMQUlNU19VUERBVEVfQVNZTkMiLCJjaGFubmVsTGlzdElkIiwiQ0hBTk5FTF9DTEFJTVNfVVBEQVRFX1NVQ0NFU1MiLCJGSUxFX1JFUVVFU1RFRCIsIkZJTEVfQVZBSUxBQklMSVRZX1VQREFURSIsIkRJU1BMQVlfQVNTRVRfRVJST1IiLCJtYXBTdGF0ZVRvUHJvcHMiLCJzaXRlIiwibG9nZ2VkSW5DaGFubmVsIiwiY2hhbm5lbFNob3J0SWQiLCJjaGFubmVsTG9uZ0lkIiwic2l0ZURlc2NyaXB0aW9uIiwibWFwRGlzcGF0Y2hUb1Byb3BzIiwib25DaGFubmVsTG9naW4iLCJkaXNwYXRjaCIsIm9uQ2hhbm5lbExvZ291dCIsInJlcXVlc3QiLCJwYXJzZUpTT04iLCJyZXNwb25zZSIsImNoZWNrU3RhdHVzIiwianNvblJlc3BvbnNlIiwiRXJyb3IiLCJ1cmwiLCJvcHRpb25zIiwiZmV0Y2giLCJ0aGVuIiwiUHJvbWlzZSIsImFsbCIsImRlZmF1bHREZXNjcmlwdGlvbiIsImRlZmF1bHRUaHVtYm5haWwiLCJzaXRlSG9zdCIsInNpdGVUaXRsZSIsInNpdGVUd2l0dGVyIiwibXlzcWwiLCJkYiIsInVhIiwiY3JlYXRlU2VydmVFdmVudFBhcmFtcyIsImhlYWRlcnMiLCJldmVudENhdGVnb3J5IiwiZXZlbnRBY3Rpb24iLCJldmVudExhYmVsIiwiaXBPdmVycmlkZSIsInVzZXJBZ2VudE92ZXJyaWRlIiwiY3JlYXRlUHVibGlzaFRpbWluZ0V2ZW50UGFyYW1zIiwiY2F0ZWdvcnkiLCJ2YXJpYWJsZSIsImxhYmVsIiwic3RhcnRUaW1lIiwiZW5kVGltZSIsImR1cmF0aW9uIiwidXNlclRpbWluZ0NhdGVnb3J5IiwidXNlclRpbWluZ1ZhcmlhYmxlTmFtZSIsInVzZXJUaW1pbmdUaW1lIiwidXNlclRpbWluZ0xhYmVsIiwic2VuZEdvb2dsZUFuYWx5dGljc0V2ZW50IiwidmlzaXRvcklkIiwicmVwbGFjZSIsInZpc2l0b3IiLCJzdHJpY3RDaWRGb3JtYXQiLCJodHRwcyIsImV2ZW50Iiwic2VuZEdvb2dsZUFuYWx5dGljc1RpbWluZyIsInRpbWluZyIsImRlYnVnIiwic2VuZEdBU2VydmVFdmVudCIsInNlbmRHQVRpbWluZ0V2ZW50IiwiY2hvb3NlR2FMYnJ5bmV0UHVibGlzaExhYmVsIiwiY2hhbm5lbF9uYW1lIiwiY2hhbm5lbF9pZCIsInNlbGVjdEFzc2V0Iiwic2hvdyIsInJlcXVlc3RMaXN0IiwiYXNzZXRLZXkiLCJhc3NldExpc3QiLCJzZWxlY3RTaG93U3RhdGUiLCJzdGF0ZSIsInNlbGVjdFNpdGVTdGF0ZSIsInNlbGVjdFNpdGVIb3N0IiwiYXhpb3MiLCJhcGkiLCJhcGlIb3N0IiwiYXBpUG9ydCIsImxicnlBcGlVcmkiLCJoYW5kbGVMYnJ5bmV0UmVzcG9uc2UiLCJyZXNvbHZlIiwicmVqZWN0IiwicmVzdWx0IiwiSlNPTiIsInN0cmluZ2lmeSIsInB1Ymxpc2hDbGFpbSIsInB1Ymxpc2hQYXJhbXMiLCJnYVN0YXJ0VGltZSIsIkRhdGUiLCJub3ciLCJwb3N0IiwibWV0aG9kIiwiY2F0Y2giLCJnZXRDbGFpbSIsInVyaSIsInRpbWVvdXQiLCJnZXRDbGFpbUxpc3QiLCJjbGFpbU5hbWUiLCJyZXNvbHZlVXJpIiwiZ2V0RG93bmxvYWREaXJlY3RvcnkiLCJkb3dubG9hZF9kaXJlY3RvcnkiLCJjcmVhdGVDaGFubmVsIiwiYW1vdW50IiwicmV0dXJuUGFnaW5hdGVkQ2hhbm5lbENsYWltcyIsIk5PX0NIQU5ORUwiLCJOT19DTEFJTSIsIk5PX0ZJTEUiLCJnZXRDbGFpbUlkIiwiY2hhbm5lbENsYWltSWQiLCJnZXRDbGFpbUlkQnlDaGFubmVsIiwiZ2V0Q2xhaW1JZEJ5Q2xhaW0iLCJDbGFpbSIsImdldExvbmdDbGFpbUlkIiwibG9uZ0NsYWltSWQiLCJDZXJ0aWZpY2F0ZSIsImdldExvbmdDaGFubmVsSWQiLCJsb25nQ2hhbm5lbElkIiwiZ2V0Q2xhaW1JZEJ5TG9uZ0NoYW5uZWxJZCIsImdldENoYW5uZWxEYXRhIiwibG9uZ0NoYW5uZWxDbGFpbUlkIiwiZ2V0U2hvcnRDaGFubmVsSWRGcm9tTG9uZ0NoYW5uZWxJZCIsInNob3J0Q2hhbm5lbENsYWltSWQiLCJnZXRDaGFubmVsQ2xhaW1zIiwiZ2V0QWxsQ2hhbm5lbENsYWltcyIsImNoYW5uZWxDbGFpbXNBcnJheSIsInBhZ2luYXRlZENoYW5uZWxWaWV3RGF0YSIsImdldExvY2FsRmlsZVJlY29yZCIsIkZpbGUiLCJmaW5kT25lIiwid2hlcmUiLCJkYXRhVmFsdWVzIiwidXBkYXRlTG9nZ2VkSW5DaGFubmVsIiwiQ0hBTk5FTF9VUERBVEUiLCJQcm9ncmVzc0JhciIsInByb3BzIiwiYmFycyIsImluZGV4IiwiaW5jcmVtZW50ZXIiLCJjcmVhdGVCYXJzIiwiYmluZCIsInN0YXJ0UHJvZ3Jlc3NCYXIiLCJ1cGRhdGVQcm9ncmVzc0JhciIsInN0b3BQcm9ncmVzc0JhciIsImkiLCJzaXplIiwicHVzaCIsImlzQWN0aXZlIiwic2V0U3RhdGUiLCJ1cGRhdGVJbnRlcnZhbCIsInNldEludGVydmFsIiwiY2xlYXJJbnRlcnZhbCIsIm1hcCIsImJhciIsIkNvbXBvbmVudCIsInByb3BUeXBlcyIsIm51bWJlciIsImlzUmVxdWlyZWQiLCJFcnJvclBhZ2UiLCJzdHJpbmciLCJMT0NBTF9DSEVDSyIsIlVOQVZBSUxBQkxFIiwiRVJST1IiLCJBVkFJTEFCTEUiLCJsYnJ5QXBpIiwicHVibGlzaEhlbHBlcnMiLCJTZXF1ZWxpemUiLCJPcCIsInB1Ymxpc2giLCJmaWxlTmFtZSIsImZpbGVUeXBlIiwicHVibGlzaFJlc3VsdHMiLCJjZXJ0aWZpY2F0ZUlkIiwiaW5mbyIsInR4IiwiQ2hhbm5lbCIsImZpbGVSZWNvcmQiLCJjbGFpbV9pZCIsIm1ldGFkYXRhIiwiYWRkcmVzcyIsImNsYWltX2FkZHJlc3MiLCJvdXRwb2ludCIsInR4aWQiLCJub3V0IiwiaGVpZ2h0IiwiZmlsZVBhdGgiLCJmaWxlX3BhdGgiLCJuc2Z3IiwiY2xhaW1SZWNvcmQiLCJjb250ZW50VHlwZSIsImJpZCIsInVwc2VydENyaXRlcmlhIiwidXBzZXJ0IiwiY2xhaW0iLCJzZXRDbGFpbSIsInNldEZpbGUiLCJkZWxldGVUZW1wb3JhcnlGaWxlIiwiY2xhaW1OYW1lSXNBdmFpbGFibGUiLCJjbGFpbUFkZHJlc3NlcyIsImZpbmRBbGwiLCJhdHRyaWJ1dGVzIiwib3IiLCJjaGVja0NoYW5uZWxBdmFpbGFiaWxpdHkiLCJmcyIsInBhcnNlUHVibGlzaEFwaVJlcXVlc3RCb2R5IiwibGljZW5zZSIsImludmFsaWROYW1lQ2hhcmFjdGVycyIsImV4ZWMiLCJwYXJzZVB1Ymxpc2hBcGlSZXF1ZXN0RmlsZXMiLCJwYXRoIiwidGVzdCIsInZhbGlkYXRlRmlsZVR5cGVBbmRTaXplIiwidGh1bWJuYWlsRmlsZU5hbWUiLCJ0aHVtYm5haWxGaWxlUGF0aCIsInRodW1ibmFpbEZpbGVUeXBlIiwiY3JlYXRlQmFzaWNQdWJsaXNoUGFyYW1zIiwidHJpbSIsImF1dGhvciIsImxhbmd1YWdlIiwiY3JlYXRlVGh1bWJuYWlsUHVibGlzaFBhcmFtcyIsInVubGluayIsImFkZEdldFJlc3VsdHNUb0ZpbGVEYXRhIiwiZmlsZUluZm8iLCJnZXRSZXN1bHQiLCJmaWxlX25hbWUiLCJkb3dubG9hZF9wYXRoIiwiY3JlYXRlRmlsZURhdGEiLCJBcHAiLCJmaWxlRXJyb3IiLCJzZXRGaWxlRXJyb3IiLCJMT0dJTiIsIkNSRUFURSIsIkxPQURfU1RBUlQiLCJMT0FESU5HIiwiUFVCTElTSElORyIsIlNVQ0NFU1MiLCJGQUlMRUQiLCJDSEFOTkVMIiwiQVNTRVRfTElURSIsIkFTU0VUX0RFVEFJTFMiLCJkaXNwbGF5QXNzZXQiLCJhc3NldCIsIm9uRmlsZVJlcXVlc3QiLCJoYW5kbGVTaG93UGFnZVVyaSIsIndhdGNoSGFuZGxlU2hvd1BhZ2VVcmkiLCJwYXJzZUFuZFVwZGF0ZUlkZW50aWZpZXJBbmRDbGFpbSIsInBhcnNlQW5kVXBkYXRlQ2xhaW1Pbmx5IiwiaXNDaGFubmVsIiwicGFyc2VJZGVudGlmaWVyIiwicGFyc2VDbGFpbSIsImFjdGlvbiIsImlkZW50aWZpZXIiLCJuZXdBc3NldFJlcXVlc3QiLCJ3YXRjaE5ld0Fzc2V0UmVxdWVzdCIsIm5ld0NoYW5uZWxSZXF1ZXN0Iiwid2F0Y2hOZXdDaGFubmVsUmVxdWVzdCIsIndhdGNoVXBkYXRlQ2hhbm5lbENsYWltcyIsImdldE5ld0NsYWltc0FuZFVwZGF0ZUNoYW5uZWwiLCJjaGFubmVsTGlzdCIsImluaXRpYWxpemUiLCJHQUxpc3RlbmVyIiwic2VuZFBhZ2VWaWV3IiwibG9jYXRpb24iLCJsaXN0ZW4iLCJzZXQiLCJwYXRobmFtZSIsInBhZ2V2aWV3IiwiY2hpbGRyZW4iLCJTRVJWRSIsIlNIT1ciLCJjbGllbnRBY2NlcHRzSHRtbCIsImFjY2VwdCIsIm1hdGNoIiwicmVxdWVzdElzRnJvbUJyb3dzZXIiLCJjbGllbnRXYW50c0Fzc2V0IiwicmFuZ2UiLCJpbWFnZUlzV2FudGVkIiwidmlkZW9Jc1dhbnRlZCIsImlzVmFsaWRDbGFpbUlkIiwiaXNWYWxpZFNob3J0SWQiLCJpc1ZhbGlkU2hvcnRJZE9yQ2xhaW1JZCIsImlucHV0Iiwic2VydmVBc3NldFRvQ2xpZW50IiwicmVkaXJlY3QiLCJ2ZXJib3NlIiwic2VuZEZpbGVPcHRpb25zIiwic2VuZEZpbGUiLCJnZXRDbGFpbUlkQW5kU2VydmVBc3NldCIsImZ1bGxDbGFpbUlkIiwiZGV0ZXJtaW5lUmVzcG9uc2VUeXBlIiwiaGFzRmlsZUV4dGVuc2lvbiIsInJlc3BvbnNlVHlwZSIsImZsaXBDbGFpbU5hbWVBbmRJZEZvckJhY2t3YXJkc0NvbXBhdGliaWxpdHkiLCJ0ZW1wTmFtZSIsImxvZ1JlcXVlc3REYXRhIiwiUkVHRVhQX0lOVkFMSURfQ0xBSU0iLCJSRUdFWFBfSU5WQUxJRF9DSEFOTkVMIiwiUkVHRVhQX0FERFJFU1MiLCJDSEFOTkVMX0NIQVIiLCJjb21wb25lbnRzUmVnZXgiLCJSZWdFeHAiLCJwcm90byIsIm1vZGlmaWVyU2VwZXJhdG9yIiwic3RhcnRzV2l0aCIsIm5hbWVCYWRDaGFycyIsImpvaW4iLCJwYXJzZU1vZGlmaWVyIiwicmV0dXJuU2FnYVdpdGhQYXJhbXMiLCJzYWdhIiwicmVxIiwiY29udGV4dCIsInNhZ2FNaWRkbGV3YXJlIiwibWlkZGxld2FyZSIsInN0b3JlIiwicnVuIiwiZG9uZSIsImh0bWwiLCJoZWxtZXQiLCJyZW5kZXJTdGF0aWMiLCJwcmVsb2FkZWRTdGF0ZSIsImdldFN0YXRlIiwic2VuZCIsInJldHVyblNob3J0SWQiLCJjbGFpbXNBcnJheSIsImNsYWltSW5kZXgiLCJzdWJzdHJpbmciLCJzaG9ydElkTGVuZ3RoIiwiZmluZEluZGV4IiwiZWxlbWVudCIsInBvc3NpYmxlTWF0Y2hlcyIsInNsaWNlIiwiZmlsdGVyIiwic2xhY2siLCJwYXNzcG9ydCIsIm1vZGVscyIsIlJlZHVjZXIiLCJyb290U2FnYSIsInJvdXRlcyIsIkhvbWVQYWdlIiwiU0VPIiwicGFnZVVyaSIsInBhZ2VUaXRsZSIsIm1ldGFUYWdzIiwiY2Fub25pY2FsTGluayIsInJlbCIsImhyZWYiLCJvYmplY3QiLCJjcmVhdGVQYWdlVGl0bGUiLCJkZXRlcm1pbmVPZ1RodW1ibmFpbENvbnRlbnRUeXBlIiwiZmlsZUV4dCIsImxhc3RJbmRleE9mIiwiY3JlYXRlQmFzaWNNZXRhVGFncyIsInByb3BlcnR5IiwiY29udGVudCIsImNyZWF0ZUNoYW5uZWxNZXRhVGFncyIsImNyZWF0ZUFzc2V0TWV0YVRhZ3MiLCJlbWJlZFVybCIsInNob3dVcmwiLCJzb3VyY2UiLCJvZ1RpdGxlIiwib2dEZXNjcmlwdGlvbiIsIm9nVGh1bWJuYWlsQ29udGVudFR5cGUiLCJvZ1RodW1ibmFpbCIsImNyZWF0ZU1ldGFUYWdzIiwiY3JlYXRlQmFzaWNDYW5vbmljYWxMaW5rIiwiY3JlYXRlQXNzZXRDYW5vbmljYWxMaW5rIiwiY3JlYXRlQ2hhbm5lbENhbm9uaWNhbExpbmsiLCJjcmVhdGVDYW5vbmljYWxMaW5rIiwiVklFVyIsIkxPR09VVCIsIk5hdkJhciIsImNoZWNrRm9yTG9nZ2VkSW5Vc2VyIiwibG9nb3V0VXNlciIsImhhbmRsZVNlbGVjdGlvbiIsImNyZWRlbnRpYWxzIiwic2hvcnRDaGFubmVsSWQiLCJ0YXJnZXQiLCJzZWxlY3RlZE9wdGlvbnMiLCJMb2dvIiwiTmF2QmFyQ2hhbm5lbERyb3Bkb3duIiwiZGVmYXVsdFNlbGVjdGlvbiIsIlB1Ymxpc2hUb29sIiwiRHJvcHpvbmUiLCJkcmFnT3ZlciIsIm1vdXNlT3ZlciIsImRpbVByZXZpZXciLCJoYW5kbGVEcm9wIiwiaGFuZGxlRHJhZ092ZXIiLCJoYW5kbGVEcmFnRW5kIiwiaGFuZGxlRHJhZ0VudGVyIiwiaGFuZGxlRHJhZ0xlYXZlIiwiaGFuZGxlTW91c2VFbnRlciIsImhhbmRsZU1vdXNlTGVhdmUiLCJoYW5kbGVDbGljayIsImhhbmRsZUZpbGVJbnB1dCIsImNob29zZUZpbGUiLCJwcmV2ZW50RGVmYXVsdCIsImR0IiwiZGF0YVRyYW5zZmVyIiwiaXRlbXMiLCJraW5kIiwiZHJvcHBlZEZpbGUiLCJnZXRBc0ZpbGUiLCJyZW1vdmUiLCJjbGVhckRhdGEiLCJkb2N1bWVudCIsImdldEVsZW1lbnRCeUlkIiwiY2xpY2siLCJmaWxlTGlzdCIsImZpbGVzIiwidmFsaWRhdGVGaWxlIiwiUHVibGlzaFByZXZpZXciLCJpbWdTb3VyY2UiLCJzZXRQcmV2aWV3SW1hZ2VTb3VyY2UiLCJuZXdQcm9wcyIsInNldFByZXZpZXdJbWFnZVNvdXJjZUZyb21GaWxlIiwicHJldmlld1JlYWRlciIsIkZpbGVSZWFkZXIiLCJyZWFkQXNEYXRhVVJMIiwib25sb2FkZW5kIiwiYm9vbCIsIlB1Ymxpc2hEZXRhaWxzIiwib25QdWJsaXNoU3VibWl0Iiwib25NZXRhZGF0YUNoYW5nZSIsIlB1Ymxpc2hUaXRsZUlucHV0IiwiaGFuZGxlSW5wdXQiLCJlIiwibG9nZ2VkSW5DaGFubmVsTmFtZSIsImxvZ2dlZEluQ2hhbm5lbFNob3J0SWQiLCJwdWJsaXNoSW5DaGFubmVsIiwic2VsZWN0ZWRDaGFubmVsIiwidXJsRXJyb3IiLCJvbkNsYWltQ2hhbmdlIiwib25VcmxFcnJvciIsIlB1Ymxpc2hVcmxJbnB1dCIsInNldENsYWltTmFtZSIsInZhbGlkYXRlQ2xhaW0iLCJjbGVhbnNlSW5wdXQiLCJmaWxlTmFtZVdpdGhvdXRFbmRpbmciLCJjbGVhbkNsYWltTmFtZSIsIlVybE1pZGRsZSIsImRhdGFVUkl0b0Jsb2IiLCJkYXRhVVJJIiwiYnl0ZVN0cmluZyIsImF0b2IiLCJzcGxpdCIsIm1pbWVTdHJpbmciLCJpYSIsIlVpbnQ4QXJyYXkiLCJjaGFyQ29kZUF0IiwiQmxvYiIsIlB1Ymxpc2hUaHVtYm5haWxJbnB1dCIsInZpZGVvU291cmNlIiwic2xpZGVyTWluUmFuZ2UiLCJzbGlkZXJNYXhSYW5nZSIsInNsaWRlclZhbHVlIiwiaGFuZGxlVmlkZW9Mb2FkZWREYXRhIiwiaGFuZGxlU2xpZGVyQ2hhbmdlIiwiY3JlYXRlVGh1bWJuYWlsIiwic2V0VmlkZW9Tb3VyY2UiLCJuZXh0UHJvcHMiLCJkYXRhVXJpIiwiYmxvYiIsIlVSTCIsImNyZWF0ZU9iamVjdFVSTCIsInRvdGFsTWludXRlcyIsIk1hdGgiLCJmbG9vciIsInRvdGFsU2Vjb25kcyIsInZpZGVvIiwiY3VycmVudFRpbWUiLCJwYXJzZUludCIsImNhbnZhcyIsImNyZWF0ZUVsZW1lbnQiLCJ3aWR0aCIsInZpZGVvV2lkdGgiLCJ2aWRlb0hlaWdodCIsImdldENvbnRleHQiLCJkcmF3SW1hZ2UiLCJkYXRhVXJsIiwidG9EYXRhVVJMIiwic25hcHNob3QiLCJkaXNwbGF5Iiwib25Ub2dnbGVNZXRhZGF0YUlucHV0cyIsIlB1Ymxpc2hNZXRhZGF0YUlucHV0cyIsInRvZ2dsZVNob3dJbnB1dHMiLCJoYW5kbGVTZWxlY3QiLCJjaGVja2VkIiwic2VsZWN0ZWRPcHRpb24iLCJtYXhIZWlnaHQiLCJFeHBhbmRpbmdUZXh0YXJlYSIsIl9oYW5kbGVDaGFuZ2UiLCJhZGp1c3RUZXh0YXJlYSIsIm9uQ2hhbmdlIiwiZWwiLCJzdHlsZSIsInNjcm9sbEhlaWdodCIsInJlc3QiLCJ4IiwiZnVuYyIsImNoYW5uZWxFcnJvciIsIm9uUHVibGlzaEluQ2hhbm5lbENoYW5nZSIsIm9uQ2hhbm5lbFNlbGVjdCIsInN0YXRlcyIsIkNoYW5uZWxTZWxlY3QiLCJ0b2dnbGVBbm9ueW1vdXNQdWJsaXNoIiwiQ2hhbm5lbExvZ2luRm9ybSIsInBhc3N3b3JkIiwibG9naW5Ub0NoYW5uZWwiLCJib2R5IiwidXNlcm5hbWUiLCJIZWFkZXJzIiwiY2hhbm5lbFBhc3N3b3JkIiwiQ2hhbm5lbENyZWF0ZUZvcm0iLCJoYW5kbGVDaGFubmVsSW5wdXQiLCJjbGVhbnNlQ2hhbm5lbElucHV0IiwidXBkYXRlSXNDaGFubmVsQXZhaWxhYmxlIiwiY2hhbm5lbFdpdGhBdFN5bWJvbCIsImNoZWNrSXNQYXNzd29yZFByb3ZpZGVkIiwiY2hlY2tJc0NoYW5uZWxBdmFpbGFibGUiLCJtYWtlUHVibGlzaENoYW5uZWxSZXF1ZXN0IiwiQWN0aXZlU3RhdHVzQmFyIiwiSW5hY3RpdmVTdGF0dXNCYXIiLCJwdWJsaXNoU3RhdGVzIiwiUHVibGlzaFN0YXR1cyIsIlB1Ymxpc2hEaXNhYmxlZE1lc3NhZ2UiLCJBYm91dFBhZ2UiLCJMb2dpblBhZ2UiLCJTaG93UGFnZSIsIlNob3dMaXRlIiwiQXNzZXREaXNwbGF5IiwiU2hvd0Fzc2V0RGV0YWlscyIsIkFzc2V0VGl0bGUiLCJBc3NldEluZm8iLCJjb3B5VG9DbGlwYm9hcmQiLCJlbGVtZW50VG9Db3B5IiwiZGF0YXNldCIsImVsZW1lbnR0b2NvcHkiLCJzZWxlY3QiLCJleGVjQ29tbWFuZCIsInByZXZpb3VzUmVxdWVzdCIsIlNob3dDaGFubmVsIiwiQ2hhbm5lbENsYWltc0Rpc3BsYXkiLCJzaG93TmV4dFJlc3VsdHNQYWdlIiwic2hvd1ByZXZpb3VzUmVzdWx0c1BhZ2UiLCJjdXJyZW50UGFnZSIsInByZXZpb3VzUGFnZSIsInNob3dOZXdQYWdlIiwibmV4dFBhZ2UiLCJjbGFpbXMiLCJ0b3RhbFBhZ2VzIiwiZGVmYXVsdHMiLCJBc3NldFByZXZpZXciLCJkaXJlY3RTb3VyY2VMaW5rIiwic2hvd1VybExpbmsiLCJGb3VyT2hGb3JQYWdlIiwiaW5pdGlhbFN0YXRlIiwiYXNzaWduIiwicHVibGlzaFN1Ym1pdCIsInNpdGVDb25maWciLCJnb29nbGVBbmFseXRpY3NJZCIsImdldFNob3J0SWQiLCJnZXRDbGFpbURhdGEiLCJleHRlbnNpb25TZXBlcmF0b3IiLCJ3YXRjaEZpbGVJc1JlcXVlc3RlZCIsInJldHJpZXZlRmlsZSIsImlzQXZhaWxhYmxlIiwiY2hlY2tGaWxlQXZhaWxhYmlsaXR5IiwidHJpZ2dlckNsYWltR2V0Iiwid2F0Y2hQdWJsaXNoU3RhcnQiLCJwdWJsaXNoRmlsZSIsInB1Ymxpc2hNZXRhZGF0YSIsInB1Ymxpc2hGb3JtRGF0YSIsInB1Ymxpc2hDaGFubmVsIiwibG9hZFN0YXJ0IiwicHJvZ3Jlc3MiLCJsb2FkIiwic2VsZWN0UHVibGlzaFN0YXRlIiwic2VsZWN0Q2hhbm5lbFN0YXRlIiwidmFsaWRhdGVDaGFubmVsU2VsZWN0aW9uIiwidmFsaWRhdGVQdWJsaXNoUGFyYW1zIiwiY3JlYXRlUHVibGlzaE1ldGFkYXRhIiwiY3JlYXRlUHVibGlzaEZvcm1EYXRhIiwiZmQiLCJGb3JtRGF0YSIsImFwcGVuZCIsImhhc093blByb3BlcnR5IiwiY3JlYXRlVGh1bWJuYWlsVXJsIiwibWFrZVB1Ymxpc2hSZXF1ZXN0Q2hhbm5lbCIsInhociIsIlhNTEh0dHBSZXF1ZXN0Iiwib25Mb2FkU3RhcnQiLCJlbWl0dGVyIiwib25Qcm9ncmVzcyIsImxlbmd0aENvbXB1dGFibGUiLCJwZXJjZW50YWdlIiwicm91bmQiLCJsb2FkZWQiLCJ0b3RhbCIsIm9uTG9hZCIsInVwbG9hZCIsImFkZEV2ZW50TGlzdGVuZXIiLCJvbnJlYWR5c3RhdGVjaGFuZ2UiLCJyZWFkeVN0YXRlIiwicGFyc2UiLCJvcGVuIiwicmVtb3ZlRXZlbnRMaXN0ZW5lciIsImFib3J0Iiwic2xpZGluZyIsImNoYW5uZWxBdmFpbGFiaWxpdHkiLCJjaGFubmVsQ2xhaW1zIiwiY2hhbm5lbERhdGEiLCJjbGFpbUF2YWlsYWJpbGl0eSIsImNsYWltR2V0IiwiY2xhaW1Mb25nSWQiLCJjbGFpbVB1Ymxpc2giLCJjbGFpbVJlc29sdmUiLCJjbGFpbVNob3J0SWQiLCJjbGFpbUxpc3QiLCJmaWxlQXZhaWxhYmlsaXR5IiwiYXZhaWxhYmxlTmFtZSIsImxicnlDb25maWciLCJDTEFJTVNfUEVSX1BBR0UiLCJkZXRlcm1pbmVUb3RhbFBhZ2VzIiwicGFnaW5hdGlvblBhZ2UiLCJnZXRQYWdlRnJvbVF1ZXJ5Iiwidmlld0RhdGEiLCJleHRyYWN0UGFnZUZyb21DbGFpbXMiLCJkZXRlcm1pbmVQcmV2aW91c1BhZ2UiLCJkZXRlcm1pbmVOZXh0UGFnZSIsInRvdGFsUmVzdWx0cyIsImRldGVybWluZVRvdGFsQ2xhaW1zIiwicGFnZU51bWJlciIsImNsYWltU3RhcnRJbmRleCIsImNsYWltRW5kSW5kZXgiLCJwYWdlT2ZDbGFpbXMiLCJ0b3RhbENsYWltcyIsImZ1bGxQYWdlcyIsInJlbWFpbmRlciIsImNoYW5uZWxTaG9ydElkUm91dGUiLCJyZXNvbHZlQ2xhaW0iLCJjbGFpbUluZm8iLCJyZXNvbHZlUmVzdWx0IiwiZmlsZURhdGEiLCJjb21wbGV0ZWQiLCJhdXRoZW50aWNhdGVVc2VyIiwidXNlciIsInZhbGlkYXRlZENsYWltTmFtZSIsInRodW1ibmFpbFB1Ymxpc2hQYXJhbXMiLCJsYnJ5VHgiLCJhdXRoZW50aWNhdGVDaGFubmVsQ3JlZGVudGlhbHMiLCJ1c2VyUGFzc3dvcmQiLCJjaGFubmVsRmluZFBhcmFtcyIsImdldCIsIlVzZXIiLCJ1c2VyTmFtZSIsImNvbXBhcmVQYXNzd29yZCIsImlzTWF0Y2giLCJyZXNvbHZlZFVyaSIsImdldFNob3J0Q2xhaW1JZEZyb21Mb25nQ2xhaW1JZCIsInNlcnZlQXNzZXRCeUNsYWltIiwic2VydmVBc3NldEJ5SWRlbnRpZmllckFuZENsYWltIiwibGJyeVVyaSIsImhhbmRsZVNob3dSZW5kZXIiLCJ0b1N0cmluZyIsIm1ldGEiLCJsaW5rIiwiaWRlbnRpZmllckNsYWltIiwic2lnbnVwIiwibG9naW4iLCJsb2dvdXQiLCJuZXh0IiwiYXV0aGVudGljYXRlIiwibG9nSW4iLCJMb2dnZXJDb25maWciLCJsb2dMZXZlbCIsInRyYW5zcG9ydHMiLCJDb25zb2xlIiwibGV2ZWwiLCJ0aW1lc3RhbXAiLCJjb2xvcml6ZSIsInByZXR0eVByaW50IiwiaGFuZGxlRXhjZXB0aW9ucyIsImh1bWFuUmVhZGFibGVVbmhhbmRsZWRFeGNlcHRpb24iLCJ3YXJuIiwic2lsbHkiLCJ3aW5zdG9uU2xhY2tXZWJIb29rIiwiU2xhY2tXZWJIb29rIiwid2luc3RvbiIsIlNsYWNrQ29uZmlnIiwic2xhY2tXZWJIb29rIiwic2xhY2tFcnJvckNoYW5uZWwiLCJzbGFja0luZm9DaGFubmVsIiwiYWRkIiwid2ViaG9va1VybCIsImljb25FbW9qaSIsImxvY2FsTG9naW5TdHJhdGVneSIsImxvY2FsU2lnbnVwU3RyYXRlZ3kiLCJzZXJpYWxpemVTcGVlY2hVc2VyIiwiZGVzZXJpYWxpemVTcGVlY2hVc2VyIiwiZGVzZXJpYWxpemVVc2VyIiwic2VyaWFsaXplVXNlciIsInVzZSIsIlBhc3Nwb3J0TG9jYWxTdHJhdGVneSIsIlN0cmF0ZWd5IiwicmV0dXJuVXNlckFuZENoYW5uZWxJbmZvIiwidXNlckluc3RhbmNlIiwidXNlckluZm8iLCJnZXRDaGFubmVsIiwidXNlcm5hbWVGaWVsZCIsInBhc3N3b3JkRmllbGQiLCJ1c2VyRGF0YSIsImNlcnRpZmljYXRlRGF0YSIsImNyZWF0ZSIsIm5ld1VzZXIiLCJuZXdDaGFubmVsIiwibmV3Q2VydGlmaWNhdGUiLCJzZXRDaGFubmVsIiwic2V0VXNlciIsIlJlcXVlc3QiLCJzZXF1ZWxpemUiLCJTVFJJTkciLCJCT09MRUFOIiwiSU5URUdFUiIsIlRFWFQiLCJERUNJTUFMIiwiZGVmaW5lIiwiZGVmYXVsdCIsImNsYWltU2VxdWVuY2UiLCJkZWNvZGVkQ2xhaW0iLCJkZXB0aCIsImVmZmVjdGl2ZUFtb3VudCIsImhhc1NpZ25hdHVyZSIsImhleCIsInZhbGlkQXRIZWlnaHQiLCJ2YWx1ZVZlcnNpb24iLCJjbGFpbVR5cGUiLCJjZXJ0aWZpY2F0ZVZlcnNpb24iLCJrZXlUeXBlIiwicHVibGljS2V5IiwiZnJlZXplVGFibGVOYW1lIiwiYXNzb2NpYXRlIiwiYmVsb25nc1RvIiwiZm9yZWlnbktleSIsImFsbG93TnVsbCIsIm9yZGVyIiwiZ2V0TG9uZ0NoYW5uZWxJZEZyb21TaG9ydENoYW5uZWxJZCIsIiRsaWtlIiwiZ2V0TG9uZ0NoYW5uZWxJZEZyb21DaGFubmVsTmFtZSIsInZhbGlkYXRlTG9uZ0NoYW5uZWxJZCIsImhhc09uZSIsImRldGVybWluZUZpbGVFeHRlbnNpb25Gcm9tQ29udGVudFR5cGUiLCJkZXRlcm1pbmVUaHVtYm5haWwiLCJzdG9yZWRUaHVtYm5haWwiLCJwcmVwYXJlQ2xhaW1EYXRhIiwibGljZW5zZVVybCIsInByZXZpZXciLCJtZXRhZGF0YVZlcnNpb24iLCJzb3VyY2VUeXBlIiwic291cmNlVmVyc2lvbiIsInN0cmVhbVZlcnNpb24iLCJyYXciLCJnZXRMb25nQ2xhaW1JZEZyb21TaG9ydENsYWltSWQiLCJnZXRUb3BGcmVlQ2xhaW1JZEJ5Q2xhaW1OYW1lIiwidmFsaWRhdGVMb25nQ2xhaW1JZCIsImNsYWltQXJyYXkiLCJkZWZhdWx0VmFsdWUiLCJ0cmVuZGluZ0VsaWdpYmxlIiwiaGFzTWFueSIsImdldFJlY2VudENsYWltcyIsImxpbWl0IiwiaXBBZGRyZXNzIiwiYmNyeXB0IiwicHJvdG90eXBlIiwiY29tcGFyZSIsImNoYW5nZVBhc3N3b3JkIiwibmV3UGFzc3dvcmQiLCJnZW5TYWx0Iiwic2FsdEVycm9yIiwic2FsdCIsImhhc2giLCJoYXNoRXJyb3IiLCJ1cGRhdGUiLCJob29rIiwiY2xhaW1zTGlzdCIsInNlbmRSZWFjdEFwcCIsInNlbmRFbWJlZFBhZ2UiLCJoYW5kbGVQYWdlUmVuZGVyIiwicmVuZGVyIiwibGF5b3V0Iiwicm91dGUiXSwibWFwcGluZ3MiOiI7O0FBQUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQUs7QUFDTDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLG1DQUEyQiwwQkFBMEIsRUFBRTtBQUN2RCx5Q0FBaUMsZUFBZTtBQUNoRDtBQUNBO0FBQ0E7O0FBRUE7QUFDQSw4REFBc0QsK0RBQStEOztBQUVySDtBQUNBOztBQUVBO0FBQ0E7Ozs7Ozs7QUM3REEsa0M7Ozs7OztBQ0FBLHdDOzs7Ozs7QUNBQSxvQzs7Ozs7Ozs7Ozs7QUNBQSxJQUFNQSxTQUFTLG1CQUFBQyxDQUFRLENBQVIsQ0FBZjs7QUFFQUMsT0FBT0MsT0FBUCxHQUFpQjtBQUNmQyx1QkFBcUIsNkJBQVVDLFdBQVYsRUFBdUJDLEVBQXZCLEVBQTJCQyxLQUEzQixFQUFrQ0MsR0FBbEMsRUFBdUM7QUFDMURSLFdBQU9PLEtBQVAsZUFB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LE1BQUlxYixJQUFKLENBQVMsOEJBQWVKLE1BQWYsRUFBdUJELElBQXZCLEVBQTZCRyxjQUE3QixDQUFUO0FBQ0QsQ0FqQ0QsQzs7Ozs7Ozs7O2VDWDhCLG1CQUFBMWIsQ0FBUSxDQUFSLEM7SUFBWHNFLEksWUFBWEQsTyxDQUFXQyxJOztBQUVuQixJQUFNdTBCLGdCQUFnQixTQUFoQkEsYUFBZ0IsR0FBTTtBQUMxQixTQUFPLGdCQUFhdDRCLEdBQWIsRUFBcUI7QUFBQSxRQUFsQjJGLE1BQWtCLFFBQWxCQSxNQUFrQjs7QUFDMUIsUUFBTWEsVUFBVWIsT0FBT2EsT0FBdkI7QUFDQSxRQUFNdEUsT0FBT3lELE9BQU96RCxJQUFwQjtBQUNBO0FBQ0FsQyxRQUFJRyxNQUFKLENBQVcsR0FBWCxFQUFnQnE0QixNQUFoQixDQUF1QixPQUF2QixFQUFnQyxFQUFFQyxRQUFRLE9BQVYsRUFBbUIxMEIsVUFBbkIsRUFBeUJ5QyxnQkFBekIsRUFBa0N0RSxVQUFsQyxFQUFoQztBQUNELEdBTEQ7QUFNRCxDQVBEOztBQVNBeEMsT0FBT0MsT0FBUCxHQUFpQjI0QixhQUFqQixDOzs7Ozs7Ozs7QUNYQSxJQUFNdmYsV0FBVyxTQUFYQSxRQUFXLENBQUMyZixLQUFELEVBQVc7QUFDMUIsU0FBTyxVQUFDamUsR0FBRCxFQUFNemEsR0FBTixFQUFjO0FBQ25CQSxRQUFJRyxNQUFKLENBQVcsR0FBWCxFQUFnQjRZLFFBQWhCLENBQXlCMmYsS0FBekI7QUFDRCxHQUZEO0FBR0QsQ0FKRDs7QUFNQWg1QixPQUFPQyxPQUFQLEdBQWlCb1osUUFBakIsQyIsImZpbGUiOiJpbmRleC5qcyIsInNvdXJjZXNDb250ZW50IjpbIiBcdC8vIFRoZSBtb2R1bGUgY2FjaGVcbiBcdHZhciBpbnN0YWxsZWRNb2R1bGVzID0ge307XG5cbiBcdC8vIFRoZSByZXF1aXJlIGZ1bmN0aW9uXG4gXHRmdW5jdGlvbiBfX3dlYnBhY2tfcmVxdWlyZV9fKG1vZHVsZUlkKSB7XG5cbiBcdFx0Ly8gQ2hlY2sgaWYgbW9kdWxlIGlzIGluIGNhY2hlXG4gXHRcdGlmKGluc3RhbGxlZE1vZHVsZXNbbW9kdWxlSWRdKSB7XG4gXHRcdFx0cmV0dXJuIGluc3RhbGxlZE1vZHVsZXNbbW9kdWxlSWRdLmV4cG9ydHM7XG4gXHRcdH1cbiBcdFx0Ly8gQ3JlYXRlIGEgbmV3IG1vZHVsZSAoYW5kIHB1dCBpdCBpbnRvIHRoZSBjYWNoZSlcbiBcdFx0dmFyIG1vZHVsZSA9IGluc3RhbGxlZE1vZHVsZXNbbW9kdWxlSWRdID0ge1xuIFx0XHRcdGk6IG1vZHVsZUlkLFxuIFx0XHRcdGw6IGZhbHNlLFxuIFx0XHRcdGV4cG9ydHM6IHt9XG4gXHRcdH07XG5cbiBcdFx0Ly8gRXhlY3V0ZSB0aGUgbW9kdWxlIGZ1bmN0aW9uXG4gXHRcdG1vZHVsZXNbbW9kdWxlSWRdLmNhbGwobW9kdWxlLmV4cG9ydHMsIG1vZHVsZSwgbW9kdWxlLmV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pO1xuXG4gXHRcdC8vIEZsYWcgdGhlIG1vZHVsZSBhcyBsb2FkZWRcbiBcdFx0bW9kdWxlLmwgPSB0cnVlO1xuXG4gXHRcdC8vIFJldHVybiB0aGUgZXhwb3J0cyBvZiB0aGUgbW9kdWxlXG4gXHRcdHJldHVybiBtb2R1bGUuZXhwb3J0cztcbiBcdH1cblxuXG4gXHQvLyBleHBvc2UgdGhlIG1vZHVsZXMgb2JqZWN0IChfX3dlYnBhY2tfbW9kdWxlc19fKVxuIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5tID0gbW9kdWxlcztcblxuIFx0Ly8gZXhwb3NlIHRoZSBtb2R1bGUgY2FjaGVcbiBcdF9fd2VicGFja19yZXF1aXJlX18uYyA9IGluc3RhbGxlZE1vZHVsZXM7XG5cbiBcdC8vIGRlZmluZSBnZXR0ZXIgZnVuY3Rpb24gZm9yIGhhcm1vbnkgZXhwb3J0c1xuIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5kID0gZnVuY3Rpb24oZXhwb3J0cywgbmFtZSwgZ2V0dGVyKSB7XG4gXHRcdGlmKCFfX3dlYnBhY2tfcmVxdWlyZV9fLm8oZXhwb3J0cywgbmFtZSkpIHtcbiBcdFx0XHRPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgbmFtZSwge1xuIFx0XHRcdFx0Y29uZmlndXJhYmxlOiBmYWxzZSxcbiBcdFx0XHRcdGVudW1lcmFibGU6IHRydWUsXG4gXHRcdFx0XHRnZXQ6IGdldHRlclxuIFx0XHRcdH0pO1xuIFx0XHR9XG4gXHR9O1xuXG4gXHQvLyBnZXREZWZhdWx0RXhwb3J0IGZ1bmN0aW9uIGZvciBjb21wYXRpYmlsaXR5IHdpdGggbm9uLWhhcm1vbnkgbW9kdWxlc1xuIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5uID0gZnVuY3Rpb24obW9kdWxlKSB7XG4gXHRcdHZhciBnZXR0ZXIgPSBtb2R1bGUgJiYgbW9kdWxlLl9fZXNNb2R1bGUgP1xuIFx0XHRcdGZ1bmN0aW9uIGdldERlZmF1bHQoKSB7IHJldHVybiBtb2R1bGVbJ2RlZmF1bHQnXTsgfSA6XG4gXHRcdFx0ZnVuY3Rpb24gZ2V0TW9kdWxlRXhwb3J0cygpIHsgcmV0dXJuIG1vZHVsZTsgfTtcbiBcdFx0X193ZWJwYWNrX3JlcXVpcmVfXy5kKGdldHRlciwgJ2EnLCBnZXR0ZXIpO1xuIFx0XHRyZXR1cm4gZ2V0dGVyO1xuIFx0fTtcblxuIFx0Ly8gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsXG4gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLm8gPSBmdW5jdGlvbihvYmplY3QsIHByb3BlcnR5KSB7IHJldHVybiBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwob2JqZWN0LCBwcm9wZXJ0eSk7IH07XG5cbiBcdC8vIF9fd2VicGFja19wdWJsaWNfcGF0aF9fXG4gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLnAgPSBcIi9cIjtcblxuIFx0Ly8gTG9hZCBlbnRyeSBtb2R1bGUgYW5kIHJldHVybiBleHBvcnRzXG4gXHRyZXR1cm4gX193ZWJwYWNrX3JlcXVpcmVfXyhfX3dlYnBhY2tfcmVxdWlyZV9fLnMgPSA0OSk7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gd2VicGFjay9ib290c3RyYXAgNWY0MDQ1Yjk2YTY3MjJhODZkZTEiLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCJyZWFjdFwiKTtcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyBleHRlcm5hbCBcInJlYWN0XCJcbi8vIG1vZHVsZSBpZCA9IDBcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwicmVhY3QtcmVkdXhcIik7XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gZXh0ZXJuYWwgXCJyZWFjdC1yZWR1eFwiXG4vLyBtb2R1bGUgaWQgPSAxXG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcIndpbnN0b25cIik7XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gZXh0ZXJuYWwgXCJ3aW5zdG9uXCJcbi8vIG1vZHVsZSBpZCA9IDJcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiY29uc3QgbG9nZ2VyID0gcmVxdWlyZSgnd2luc3RvbicpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgaGFuZGxlRXJyb3JSZXNwb25zZTogZnVuY3Rpb24gKG9yaWdpbmFsVXJsLCBpcCwgZXJyb3IsIHJlcykge1xuICAgIGxvZ2dlci5lcnJvcihgRXJyb3Igb24gJHtvcmlnaW5hbFVybH1gLCBtb2R1bGUuZXhwb3J0cy51c2VPYmplY3RQcm9wZXJ0aWVzSWZOb0tleXMoZXJyb3IpKTtcbiAgICBjb25zdCBbc3RhdHVzLCBtZXNzYWdlXSA9IG1vZHVsZS5leHBvcnRzLnJldHVybkVycm9yTWVzc2FnZUFuZFN0YXR1cyhlcnJvcik7XG4gICAgcmVzXG4gICAgICAuc3RhdHVzKHN0YXR1cylcbiAgICAgIC5qc29uKG1vZHVsZS5leHBvcnRzLmNyZWF0ZUVycm9yUmVzcG9uc2VQYXlsb2FkKHN0YXR1cywgbWVzc2FnZSkpO1xuICB9LFxuICByZXR1cm5FcnJvck1lc3NhZ2VBbmRTdGF0dXM6IGZ1bmN0aW9uIChlcnJvcikge1xuICAgIGxldCBzdGF0dXMsIG1lc3NhZ2U7XG4gICAgLy8gY2hlY2sgZm9yIGRhZW1vbiBiZWluZyB0dXJuZWQgb2ZmXG4gICAgaWYgKGVycm9yLmNvZGUgPT09ICdFQ09OTlJFRlVTRUQnKSB7XG4gICAgICBzdGF0dXMgPSA1MDM7XG4gICAgICBtZXNzYWdlID0gJ0Nvbm5lY3Rpb24gcmVmdXNlZC4gIFRoZSBkYWVtb24gbWF5IG5vdCBiZSBydW5uaW5nLic7XG4gICAgICAvLyBmYWxsYmFjayBmb3IgZXZlcnl0aGluZyBlbHNlXG4gICAgfSBlbHNlIHtcbiAgICAgIHN0YXR1cyA9IDQwMDtcbiAgICAgIGlmIChlcnJvci5tZXNzYWdlKSB7XG4gICAgICAgIG1lc3NhZ2UgPSBlcnJvci5tZXNzYWdlO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbWVzc2FnZSA9IGVycm9yO1xuICAgICAgfTtcbiAgICB9O1xuICAgIHJldHVybiBbc3RhdHVzLCBtZXNzYWdlXTtcbiAgfSxcbiAgdXNlT2JqZWN0UHJvcGVydGllc0lmTm9LZXlzOiBmdW5jdGlvbiAoZXJyKSB7XG4gICAgaWYgKE9iamVjdC5rZXlzKGVycikubGVuZ3RoID09PSAwKSB7XG4gICAgICBsZXQgbmV3RXJyb3JPYmplY3QgPSB7fTtcbiAgICAgIE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzKGVycikuZm9yRWFjaCgoa2V5KSA9PiB7XG4gICAgICAgIG5ld0Vycm9yT2JqZWN0W2tleV0gPSBlcnJba2V5XTtcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIG5ld0Vycm9yT2JqZWN0O1xuICAgIH1cbiAgICByZXR1cm4gZXJyO1xuICB9LFxuICBjcmVhdGVFcnJvclJlc3BvbnNlUGF5bG9hZCAoc3RhdHVzLCBtZXNzYWdlKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHN0YXR1cyxcbiAgICAgIHN1Y2Nlc3M6IGZhbHNlLFxuICAgICAgbWVzc2FnZSxcbiAgICB9O1xuICB9LFxufTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL3NlcnZlci9oZWxwZXJzL2Vycm9ySGFuZGxlcnMuanMiLCJpbXBvcnQgKiBhcyBhY3Rpb25zIGZyb20gJ2NvbnN0YW50cy9wdWJsaXNoX2FjdGlvbl90eXBlcyc7XG5cbi8vIGV4cG9ydCBhY3Rpb24gY3JlYXRvcnNcbmV4cG9ydCBmdW5jdGlvbiBzZWxlY3RGaWxlIChmaWxlKSB7XG4gIHJldHVybiB7XG4gICAgdHlwZTogYWN0aW9ucy5GSUxFX1NFTEVDVEVELFxuICAgIGRhdGE6IGZpbGUsXG4gIH07XG59O1xuXG5leHBvcnQgZnVuY3Rpb24gY2xlYXJGaWxlICgpIHtcbiAgcmV0dXJuIHtcbiAgICB0eXBlOiBhY3Rpb25zLkZJTEVfQ0xFQVIsXG4gIH07XG59O1xuXG5leHBvcnQgZnVuY3Rpb24gdXBkYXRlTWV0YWRhdGEgKG5hbWUsIHZhbHVlKSB7XG4gIHJldHVybiB7XG4gICAgdHlwZTogYWN0aW9ucy5NRVRBREFUQV9VUERBVEUsXG4gICAgZGF0YToge1xuICAgICAgbmFtZSxcbiAgICAgIHZhbHVlLFxuICAgIH0sXG4gIH07XG59O1xuXG5leHBvcnQgZnVuY3Rpb24gdXBkYXRlQ2xhaW0gKHZhbHVlKSB7XG4gIHJldHVybiB7XG4gICAgdHlwZTogYWN0aW9ucy5DTEFJTV9VUERBVEUsXG4gICAgZGF0YTogdmFsdWUsXG4gIH07XG59O1xuXG5leHBvcnQgZnVuY3Rpb24gc2V0UHVibGlzaEluQ2hhbm5lbCAoY2hhbm5lbCkge1xuICByZXR1cm4ge1xuICAgIHR5cGU6IGFjdGlvbnMuU0VUX1BVQkxJU0hfSU5fQ0hBTk5FTCxcbiAgICBjaGFubmVsLFxuICB9O1xufTtcblxuZXhwb3J0IGZ1bmN0aW9uIHVwZGF0ZVB1Ymxpc2hTdGF0dXMgKHN0YXR1cywgbWVzc2FnZSkge1xuICByZXR1cm4ge1xuICAgIHR5cGU6IGFjdGlvbnMuUFVCTElTSF9TVEFUVVNfVVBEQVRFLFxuICAgIGRhdGE6IHtcbiAgICAgIHN0YXR1cyxcbiAgICAgIG1lc3NhZ2UsXG4gICAgfSxcbiAgfTtcbn07XG5cbmV4cG9ydCBmdW5jdGlvbiB1cGRhdGVFcnJvciAobmFtZSwgdmFsdWUpIHtcbiAgcmV0dXJuIHtcbiAgICB0eXBlOiBhY3Rpb25zLkVSUk9SX1VQREFURSxcbiAgICBkYXRhOiB7XG4gICAgICBuYW1lLFxuICAgICAgdmFsdWUsXG4gICAgfSxcbiAgfTtcbn07XG5cbmV4cG9ydCBmdW5jdGlvbiB1cGRhdGVTZWxlY3RlZENoYW5uZWwgKGNoYW5uZWxOYW1lKSB7XG4gIHJldHVybiB7XG4gICAgdHlwZTogYWN0aW9ucy5TRUxFQ1RFRF9DSEFOTkVMX1VQREFURSxcbiAgICBkYXRhOiBjaGFubmVsTmFtZSxcbiAgfTtcbn07XG5cbmV4cG9ydCBmdW5jdGlvbiB0b2dnbGVNZXRhZGF0YUlucHV0cyAoc2hvd01ldGFkYXRhSW5wdXRzKSB7XG4gIHJldHVybiB7XG4gICAgdHlwZTogYWN0aW9ucy5UT0dHTEVfTUVUQURBVEFfSU5QVVRTLFxuICAgIGRhdGE6IHNob3dNZXRhZGF0YUlucHV0cyxcbiAgfTtcbn07XG5cbmV4cG9ydCBmdW5jdGlvbiBvbk5ld1RodW1ibmFpbCAoZmlsZSkge1xuICByZXR1cm4ge1xuICAgIHR5cGU6IGFjdGlvbnMuVEhVTUJOQUlMX05FVyxcbiAgICBkYXRhOiBmaWxlLFxuICB9O1xufTtcblxuZXhwb3J0IGZ1bmN0aW9uIHN0YXJ0UHVibGlzaCAoaGlzdG9yeSkge1xuICByZXR1cm4ge1xuICAgIHR5cGU6IGFjdGlvbnMuUFVCTElTSF9TVEFSVCxcbiAgICBkYXRhOiB7IGhpc3RvcnkgfSxcbiAgfTtcbn1cblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL2NsaWVudC9hY3Rpb25zL3B1Ymxpc2guanMiLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCJyZWFjdC1yb3V0ZXItZG9tXCIpO1xuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIGV4dGVybmFsIFwicmVhY3Qtcm91dGVyLWRvbVwiXG4vLyBtb2R1bGUgaWQgPSA1XG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsImZ1bmN0aW9uIFNpdGVDb25maWcgKCkge1xuICB0aGlzLmFuYWx5dGljcyA9IHtcbiAgICBnb29nbGVJZDogJ2RlZmF1bHQnLFxuICB9O1xuICB0aGlzLmFzc2V0RGVmYXVsdHMgPSB7XG4gICAgZGVzY3JpcHRpb246ICdBbiBhc3NldCBwdWJsaXNoZWQgb24gU3BlZS5jaCcsXG4gICAgdGh1bWJuYWlsICA6ICdodHRwczovL3NwZWUuY2gvYXNzZXRzL2ltZy92aWRlb190aHVtYl9kZWZhdWx0LnBuZycsXG4gICAgdGl0bGUgICAgICA6ICdTcGVlLmNoJyxcbiAgfTtcbiAgdGhpcy5hdXRoID0ge1xuICAgIHNlc3Npb25LZXk6ICdkZWZhdWx0JyxcbiAgfTtcbiAgdGhpcy5jdXN0b21Db21wb25lbnRzID0ge1xuICAgIGNvbXBvbmVudHM6IHt9LFxuICAgIGNvbnRhaW5lcnM6IHt9LFxuICAgIHBhZ2VzICAgICA6IHt9LFxuICB9O1xuICB0aGlzLmRldGFpbHMgPSB7XG4gICAgZGVzY3JpcHRpb246ICdPcGVuLXNvdXJjZSwgZGVjZW50cmFsaXplZCBpbWFnZSBhbmQgdmlkZW8gc2hhcmluZy4nLFxuICAgIGhvc3QgICAgICAgOiAnZGVmYXVsdCcsXG4gICAgcG9ydCAgICAgICA6IDMwMDAsXG4gICAgdGl0bGUgICAgICA6ICdTcGVlLmNoJyxcbiAgICB0d2l0dGVyICAgIDogJ0BzcGVlX2NoJyxcbiAgfTtcbiAgdGhpcy5wdWJsaXNoaW5nID0ge1xuICAgIGFkZGl0aW9uYWxDbGFpbUFkZHJlc3NlczogW10sXG4gICAgZGlzYWJsZWQgICAgICAgICAgICAgICAgOiBmYWxzZSxcbiAgICBkaXNhYmxlZE1lc3NhZ2UgICAgICAgICA6ICdQbGVhc2UgY2hlY2sgYmFjayBzb29uLicsXG4gICAgcHJpbWFyeUNsYWltQWRkcmVzcyAgICAgOiAnZGVmYXVsdCcsXG4gICAgdGh1bWJuYWlsQ2hhbm5lbCAgICAgICAgOiAnZGVmYXVsdCcsXG4gICAgdGh1bWJuYWlsQ2hhbm5lbElkICAgICAgOiAnZGVmYXVsdCcsXG4gICAgdXBsb2FkRGlyZWN0b3J5ICAgICAgICAgOiAnL2hvbWUvbGJyeS9VcGxvYWRzJyxcbiAgfTtcbiAgdGhpcy5jb25maWd1cmUgPSAoY29uZmlnKSA9PiB7XG4gICAgaWYgKCFjb25maWcpIHtcbiAgICAgIHJldHVybiBjb25zb2xlLmxvZygnTm8gc2l0ZSBjb25maWcgcmVjZWl2ZWQuJyk7XG4gICAgfVxuICAgIGNvbnN0IHsgYW5hbHl0aWNzLCBhc3NldERlZmF1bHRzLCBhdXRoLCBjdXN0b21Db21wb25lbnRzLCBkZXRhaWxzLCBwdWJsaXNoaW5nIH0gPSBjb25maWc7XG4gICAgdGhpcy5hbmFseXRpY3MgPSBhbmFseXRpY3M7XG4gICAgdGhpcy5hc3NldERlZmF1bHRzID0gYXNzZXREZWZhdWx0cztcbiAgICB0aGlzLmF1dGggPSBhdXRoO1xuICAgIHRoaXMuZGV0YWlscyA9IGRldGFpbHM7XG4gICAgdGhpcy5wdWJsaXNoaW5nID0gcHVibGlzaGluZztcbiAgICB0aGlzLmN1c3RvbUNvbXBvbmVudHMgPSBjdXN0b21Db21wb25lbnRzO1xuICB9O1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSBuZXcgU2l0ZUNvbmZpZygpO1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vY29uZmlnL3NpdGVDb25maWcuanMiLCJpbXBvcnQgKiBhcyBhY3Rpb25zIGZyb20gJ2NvbnN0YW50cy9zaG93X2FjdGlvbl90eXBlcyc7XG5cbmltcG9ydCB7IENIQU5ORUwsIEFTU0VUX0xJVEUsIEFTU0VUX0RFVEFJTFMgfSBmcm9tICdjb25zdGFudHMvc2hvd19yZXF1ZXN0X3R5cGVzJztcblxuLy8gYmFzaWMgcmVxdWVzdCBwYXJzaW5nXG5leHBvcnQgZnVuY3Rpb24gb25IYW5kbGVTaG93UGFnZVVyaSAocGFyYW1zKSB7XG4gIHJldHVybiB7XG4gICAgdHlwZTogYWN0aW9ucy5IQU5ETEVfU0hPV19VUkksXG4gICAgZGF0YTogcGFyYW1zLFxuICB9O1xufTtcblxuZXhwb3J0IGZ1bmN0aW9uIG9uUmVxdWVzdEVycm9yIChlcnJvcikge1xuICByZXR1cm4ge1xuICAgIHR5cGU6IGFjdGlvbnMuUkVRVUVTVF9FUlJPUixcbiAgICBkYXRhOiBlcnJvcixcbiAgfTtcbn07XG5cbmV4cG9ydCBmdW5jdGlvbiBvbk5ld0NoYW5uZWxSZXF1ZXN0IChjaGFubmVsTmFtZSwgY2hhbm5lbElkKSB7XG4gIGNvbnN0IHJlcXVlc3RUeXBlID0gQ0hBTk5FTDtcbiAgY29uc3QgcmVxdWVzdElkID0gYGNyIyR7Y2hhbm5lbE5hbWV9IyR7Y2hhbm5lbElkfWA7XG4gIHJldHVybiB7XG4gICAgdHlwZTogYWN0aW9ucy5DSEFOTkVMX1JFUVVFU1RfTkVXLFxuICAgIGRhdGE6IHsgcmVxdWVzdFR5cGUsIHJlcXVlc3RJZCwgY2hhbm5lbE5hbWUsIGNoYW5uZWxJZCB9LFxuICB9O1xufTtcblxuZXhwb3J0IGZ1bmN0aW9uIG9uTmV3QXNzZXRSZXF1ZXN0IChuYW1lLCBpZCwgY2hhbm5lbE5hbWUsIGNoYW5uZWxJZCwgZXh0ZW5zaW9uKSB7XG4gIGNvbnN0IHJlcXVlc3RUeXBlID0gZXh0ZW5zaW9uID8gQVNTRVRfTElURSA6IEFTU0VUX0RFVEFJTFM7XG4gIGNvbnN0IHJlcXVlc3RJZCA9IGBhciMke25hbWV9IyR7aWR9IyR7Y2hhbm5lbE5hbWV9IyR7Y2hhbm5lbElkfWA7XG4gIHJldHVybiB7XG4gICAgdHlwZTogYWN0aW9ucy5BU1NFVF9SRVFVRVNUX05FVyxcbiAgICBkYXRhOiB7XG4gICAgICByZXF1ZXN0VHlwZSxcbiAgICAgIHJlcXVlc3RJZCxcbiAgICAgIG5hbWUsXG4gICAgICBtb2RpZmllcjoge1xuICAgICAgICBpZCxcbiAgICAgICAgY2hhbm5lbDoge1xuICAgICAgICAgIG5hbWU6IGNoYW5uZWxOYW1lLFxuICAgICAgICAgIGlkICA6IGNoYW5uZWxJZCxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgfSxcbiAgfTtcbn07XG5cbmV4cG9ydCBmdW5jdGlvbiBvblJlcXVlc3RVcGRhdGUgKHJlcXVlc3RUeXBlLCByZXF1ZXN0SWQpIHtcbiAgcmV0dXJuIHtcbiAgICB0eXBlOiBhY3Rpb25zLlJFUVVFU1RfVVBEQVRFLFxuICAgIGRhdGE6IHtcbiAgICAgIHJlcXVlc3RUeXBlLFxuICAgICAgcmVxdWVzdElkLFxuICAgIH0sXG4gIH07XG59O1xuXG5leHBvcnQgZnVuY3Rpb24gYWRkUmVxdWVzdFRvUmVxdWVzdExpc3QgKGlkLCBlcnJvciwga2V5KSB7XG4gIHJldHVybiB7XG4gICAgdHlwZTogYWN0aW9ucy5SRVFVRVNUX0xJU1RfQURELFxuICAgIGRhdGE6IHsgaWQsIGVycm9yLCBrZXkgfSxcbiAgfTtcbn07XG5cbi8vIGFzc2V0IGFjdGlvbnNcblxuZXhwb3J0IGZ1bmN0aW9uIGFkZEFzc2V0VG9Bc3NldExpc3QgKGlkLCBlcnJvciwgbmFtZSwgY2xhaW1JZCwgc2hvcnRJZCwgY2xhaW1EYXRhKSB7XG4gIHJldHVybiB7XG4gICAgdHlwZTogYWN0aW9ucy5BU1NFVF9BREQsXG4gICAgZGF0YTogeyBpZCwgZXJyb3IsIG5hbWUsIGNsYWltSWQsIHNob3J0SWQsIGNsYWltRGF0YSB9LFxuICB9O1xufVxuXG4vLyBjaGFubmVsIGFjdGlvbnNcblxuZXhwb3J0IGZ1bmN0aW9uIGFkZE5ld0NoYW5uZWxUb0NoYW5uZWxMaXN0IChpZCwgbmFtZSwgc2hvcnRJZCwgbG9uZ0lkLCBjbGFpbXNEYXRhKSB7XG4gIHJldHVybiB7XG4gICAgdHlwZTogYWN0aW9ucy5DSEFOTkVMX0FERCxcbiAgICBkYXRhOiB7IGlkLCBuYW1lLCBzaG9ydElkLCBsb25nSWQsIGNsYWltc0RhdGEgfSxcbiAgfTtcbn07XG5cbmV4cG9ydCBmdW5jdGlvbiBvblVwZGF0ZUNoYW5uZWxDbGFpbXMgKGNoYW5uZWxLZXksIG5hbWUsIGxvbmdJZCwgcGFnZSkge1xuICByZXR1cm4ge1xuICAgIHR5cGU6IGFjdGlvbnMuQ0hBTk5FTF9DTEFJTVNfVVBEQVRFX0FTWU5DLFxuICAgIGRhdGE6IHtjaGFubmVsS2V5LCBuYW1lLCBsb25nSWQsIHBhZ2V9LFxuICB9O1xufTtcblxuZXhwb3J0IGZ1bmN0aW9uIHVwZGF0ZUNoYW5uZWxDbGFpbXMgKGNoYW5uZWxMaXN0SWQsIGNsYWltc0RhdGEpIHtcbiAgcmV0dXJuIHtcbiAgICB0eXBlOiBhY3Rpb25zLkNIQU5ORUxfQ0xBSU1TX1VQREFURV9TVUNDRVNTLFxuICAgIGRhdGE6IHtjaGFubmVsTGlzdElkLCBjbGFpbXNEYXRhfSxcbiAgfTtcbn07XG5cbi8vIGRpc3BsYXkgYSBmaWxlXG5cbmV4cG9ydCBmdW5jdGlvbiBmaWxlUmVxdWVzdGVkIChuYW1lLCBjbGFpbUlkKSB7XG4gIHJldHVybiB7XG4gICAgdHlwZTogYWN0aW9ucy5GSUxFX1JFUVVFU1RFRCxcbiAgICBkYXRhOiB7IG5hbWUsIGNsYWltSWQgfSxcbiAgfTtcbn07XG5cbmV4cG9ydCBmdW5jdGlvbiB1cGRhdGVGaWxlQXZhaWxhYmlsaXR5IChzdGF0dXMpIHtcbiAgcmV0dXJuIHtcbiAgICB0eXBlOiBhY3Rpb25zLkZJTEVfQVZBSUxBQklMSVRZX1VQREFURSxcbiAgICBkYXRhOiBzdGF0dXMsXG4gIH07XG59O1xuXG5leHBvcnQgZnVuY3Rpb24gdXBkYXRlRGlzcGxheUFzc2V0RXJyb3IgKGVycm9yKSB7XG4gIHJldHVybiB7XG4gICAgdHlwZTogYWN0aW9ucy5ESVNQTEFZX0FTU0VUX0VSUk9SLFxuICAgIGRhdGE6IGVycm9yLFxuICB9O1xufTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL2NsaWVudC9hY3Rpb25zL3Nob3cuanMiLCJpbXBvcnQgeyBjb25uZWN0IH0gZnJvbSAncmVhY3QtcmVkdXgnO1xuaW1wb3J0IHsgdXBkYXRlTG9nZ2VkSW5DaGFubmVsIH0gZnJvbSAnYWN0aW9ucy9jaGFubmVsJztcbmltcG9ydCB7dXBkYXRlU2VsZWN0ZWRDaGFubmVsfSBmcm9tICdhY3Rpb25zL3B1Ymxpc2gnO1xuaW1wb3J0IFZpZXcgZnJvbSAnLi92aWV3JztcblxuY29uc3QgbWFwU3RhdGVUb1Byb3BzID0gKHsgY2hhbm5lbCwgc2l0ZSB9KSA9PiB7XG4gIHJldHVybiB7XG4gICAgY2hhbm5lbE5hbWUgICA6IGNoYW5uZWwubG9nZ2VkSW5DaGFubmVsLm5hbWUsXG4gICAgY2hhbm5lbFNob3J0SWQ6IGNoYW5uZWwubG9nZ2VkSW5DaGFubmVsLnNob3J0SWQsXG4gICAgY2hhbm5lbExvbmdJZCA6IGNoYW5uZWwubG9nZ2VkSW5DaGFubmVsLmxvbmdJZCxcbiAgICBzaXRlRGVzY3JpcHRpb246IHNpdGUuZGVzY3JpcHRpb24sXG4gIH07XG59O1xuXG5jb25zdCBtYXBEaXNwYXRjaFRvUHJvcHMgPSBkaXNwYXRjaCA9PiB7XG4gIHJldHVybiB7XG4gICAgb25DaGFubmVsTG9naW46IChuYW1lLCBzaG9ydElkLCBsb25nSWQpID0+IHtcbiAgICAgIGRpc3BhdGNoKHVwZGF0ZUxvZ2dlZEluQ2hhbm5lbChuYW1lLCBzaG9ydElkLCBsb25nSWQpKTtcbiAgICAgIGRpc3BhdGNoKHVwZGF0ZVNlbGVjdGVkQ2hhbm5lbChuYW1lKSk7XG4gICAgfSxcbiAgICBvbkNoYW5uZWxMb2dvdXQ6ICgpID0+IHtcbiAgICAgIGRpc3BhdGNoKHVwZGF0ZUxvZ2dlZEluQ2hhbm5lbChudWxsLCBudWxsLCBudWxsKSk7XG4gICAgfSxcbiAgfTtcbn07XG5cbmV4cG9ydCBkZWZhdWx0IGNvbm5lY3QobWFwU3RhdGVUb1Byb3BzLCBtYXBEaXNwYXRjaFRvUHJvcHMpKFZpZXcpO1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vY2xpZW50L2NvbnRhaW5lcnMvTmF2QmFyL2luZGV4LmpzIiwiaW1wb3J0ICdjcm9zcy1mZXRjaC9wb2x5ZmlsbCc7XG5cbi8qKlxuICogUGFyc2VzIHRoZSBKU09OIHJldHVybmVkIGJ5IGEgbmV0d29yayByZXF1ZXN0XG4gKlxuICogQHBhcmFtICB7b2JqZWN0fSByZXNwb25zZSBBIHJlc3BvbnNlIGZyb20gYSBuZXR3b3JrIHJlcXVlc3RcbiAqXG4gKiBAcmV0dXJuIHtvYmplY3R9ICAgICAgICAgIFRoZSBwYXJzZWQgSlNPTiBmcm9tIHRoZSByZXF1ZXN0XG4gKi9cbmZ1bmN0aW9uIHBhcnNlSlNPTiAocmVzcG9uc2UpIHtcbiAgaWYgKHJlc3BvbnNlLnN0YXR1cyA9PT0gMjA0IHx8IHJlc3BvbnNlLnN0YXR1cyA9PT0gMjA1KSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cbiAgcmV0dXJuIHJlc3BvbnNlLmpzb24oKTtcbn1cblxuLyoqXG4gKiBQYXJzZXMgdGhlIHN0YXR1cyByZXR1cm5lZCBieSBhIG5ldHdvcmsgcmVxdWVzdFxuICpcbiAqIEBwYXJhbSAge29iamVjdH0gcmVzcG9uc2UgICBBIHJlc3BvbnNlIGZyb20gYSBuZXR3b3JrIHJlcXVlc3RcbiAqIEBwYXJhbSAge29iamVjdH0gcmVzcG9uc2UgICBUaGUgcGFyc2VkIEpTT04gZnJvbSB0aGUgbmV0d29yayByZXF1ZXN0XG4gKlxuICogQHJldHVybiB7b2JqZWN0IHwgdW5kZWZpbmVkfSBSZXR1cm5zIG9iamVjdCB3aXRoIHN0YXR1cyBhbmQgc3RhdHVzVGV4dCwgb3IgdW5kZWZpbmVkXG4gKi9cbmZ1bmN0aW9uIGNoZWNrU3RhdHVzIChyZXNwb25zZSwganNvblJlc3BvbnNlKSB7XG4gIGlmIChyZXNwb25zZS5zdGF0dXMgPj0gMjAwICYmIHJlc3BvbnNlLnN0YXR1cyA8IDMwMCkge1xuICAgIHJldHVybiBqc29uUmVzcG9uc2U7XG4gIH1cbiAgY29uc3QgZXJyb3IgPSBuZXcgRXJyb3IoanNvblJlc3BvbnNlLm1lc3NhZ2UpO1xuICBlcnJvci5yZXNwb25zZSA9IHJlc3BvbnNlO1xuICB0aHJvdyBlcnJvcjtcbn1cblxuLyoqXG4gKiBSZXF1ZXN0cyBhIFVSTCwgcmV0dXJuaW5nIGEgcHJvbWlzZVxuICpcbiAqIEBwYXJhbSAge3N0cmluZ30gdXJsICAgICAgIFRoZSBVUkwgd2Ugd2FudCB0byByZXF1ZXN0XG4gKiBAcGFyYW0gIHtvYmplY3R9IFtvcHRpb25zXSBUaGUgb3B0aW9ucyB3ZSB3YW50IHRvIHBhc3MgdG8gXCJmZXRjaFwiXG4gKlxuICogQHJldHVybiB7b2JqZWN0fSAgICAgICAgICAgVGhlIHJlc3BvbnNlIGRhdGFcbiAqL1xuXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiByZXF1ZXN0ICh1cmwsIG9wdGlvbnMpIHtcbiAgcmV0dXJuIGZldGNoKHVybCwgb3B0aW9ucylcbiAgICAudGhlbihyZXNwb25zZSA9PiB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5hbGwoW3Jlc3BvbnNlLCBwYXJzZUpTT04ocmVzcG9uc2UpXSk7XG4gICAgfSlcbiAgICAudGhlbigoW3Jlc3BvbnNlLCBqc29uUmVzcG9uc2VdKSA9PiB7XG4gICAgICByZXR1cm4gY2hlY2tTdGF0dXMocmVzcG9uc2UsIGpzb25SZXNwb25zZSk7XG4gICAgfSk7XG59XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9jbGllbnQvdXRpbHMvcmVxdWVzdC5qcyIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcInJlZHV4LXNhZ2EvZWZmZWN0c1wiKTtcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyBleHRlcm5hbCBcInJlZHV4LXNhZ2EvZWZmZWN0c1wiXG4vLyBtb2R1bGUgaWQgPSAxMFxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJpbXBvcnQgeyBjb25uZWN0IH0gZnJvbSAncmVhY3QtcmVkdXgnO1xuaW1wb3J0IFZpZXcgZnJvbSAnLi92aWV3JztcblxuY29uc3QgbWFwU3RhdGVUb1Byb3BzID0gKHsgc2l0ZSB9KSA9PiB7XG4gIGNvbnN0IHsgZGVmYXVsdERlc2NyaXB0aW9uLCBkZWZhdWx0VGh1bWJuYWlsLCBkZXNjcmlwdGlvbjogc2l0ZURlc2NyaXB0aW9uLCBob3N0OiBzaXRlSG9zdCwgdGl0bGU6IHNpdGVUaXRsZSwgdHdpdHRlcjogc2l0ZVR3aXR0ZXIgfSA9IHNpdGU7XG4gIHJldHVybiB7XG4gICAgZGVmYXVsdERlc2NyaXB0aW9uLFxuICAgIGRlZmF1bHRUaHVtYm5haWwsXG4gICAgc2l0ZURlc2NyaXB0aW9uLFxuICAgIHNpdGVIb3N0LFxuICAgIHNpdGVUaXRsZSxcbiAgICBzaXRlVHdpdHRlcixcbiAgfTtcbn07XG5cbmV4cG9ydCBkZWZhdWx0IGNvbm5lY3QobWFwU3RhdGVUb1Byb3BzLCBudWxsKShWaWV3KTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL2NsaWVudC9jb21wb25lbnRzL1NFTy9pbmRleC5qcyIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcInByb3AtdHlwZXNcIik7XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gZXh0ZXJuYWwgXCJwcm9wLXR5cGVzXCJcbi8vIG1vZHVsZSBpZCA9IDEyXG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIi8vIHJlcXVlc3QgYWN0aW9uc1xuZXhwb3J0IGNvbnN0IEhBTkRMRV9TSE9XX1VSSSA9ICdIQU5ETEVfU0hPV19VUkknO1xuZXhwb3J0IGNvbnN0IFJFUVVFU1RfRVJST1IgPSAnUkVRVUVTVF9FUlJPUic7XG5leHBvcnQgY29uc3QgUkVRVUVTVF9VUERBVEUgPSAnUkVRVUVTVF9VUERBVEUnO1xuZXhwb3J0IGNvbnN0IEFTU0VUX1JFUVVFU1RfTkVXID0gJ0FTU0VUX1JFUVVFU1RfTkVXJztcbmV4cG9ydCBjb25zdCBDSEFOTkVMX1JFUVVFU1RfTkVXID0gJ0NIQU5ORUxfUkVRVUVTVF9ORVcnO1xuZXhwb3J0IGNvbnN0IFJFUVVFU1RfTElTVF9BREQgPSAnUkVRVUVTVF9MSVNUX0FERCc7XG5cbi8vIGFzc2V0IGFjdGlvbnNcbmV4cG9ydCBjb25zdCBBU1NFVF9BREQgPSBgQVNTRVRfQUREYDtcblxuLy8gY2hhbm5lbCBhY3Rpb25zXG5leHBvcnQgY29uc3QgQ0hBTk5FTF9BREQgPSAnQ0hBTk5FTF9BREQnO1xuXG5leHBvcnQgY29uc3QgQ0hBTk5FTF9DTEFJTVNfVVBEQVRFX0FTWU5DID0gJ0NIQU5ORUxfQ0xBSU1TX1VQREFURV9BU1lOQyc7XG5leHBvcnQgY29uc3QgQ0hBTk5FTF9DTEFJTVNfVVBEQVRFX1NVQ0NFU1MgPSAnQ0hBTk5FTF9DTEFJTVNfVVBEQVRFX1NVQ0NFU1MnO1xuXG4vLyBhc3NldC9maWxlIGRpc3BsYXkgYWN0aW9uc1xuZXhwb3J0IGNvbnN0IEZJTEVfUkVRVUVTVEVEID0gJ0ZJTEVfUkVRVUVTVEVEJztcbmV4cG9ydCBjb25zdCBGSUxFX0FWQUlMQUJJTElUWV9VUERBVEUgPSAnRklMRV9BVkFJTEFCSUxJVFlfVVBEQVRFJztcbmV4cG9ydCBjb25zdCBESVNQTEFZX0FTU0VUX0VSUk9SID0gJ0RJU1BMQVlfQVNTRVRfRVJST1InO1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vY2xpZW50L2NvbnN0YW50cy9zaG93X2FjdGlvbl90eXBlcy5qcyIsImZ1bmN0aW9uIG15c3FsICgpIHtcbiAgdGhpcy5kYiA9IHt9O1xuICB0aGlzLmNvbmZpZ3VyZSA9IChkYikgPT4ge1xuICAgIGlmICghZGIpIHtcbiAgICAgIHJldHVybiBjb25zb2xlLmxvZygnTm8gTXlTUUwgY29uZmlnIHJlY2VpdmVkLicpO1xuICAgIH1cbiAgICAvLyBjb25maWd1cmUgY3JlZGVudGlhbHNcbiAgICBjb25zb2xlLmxvZygnY29uZmlndXJpbmcgbXlzcWwuLi4nKTtcbiAgICB0aGlzLmRiID0gZGI7XG4gIH07XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IG5ldyBteXNxbCgpO1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vY29uZmlnL215c3FsQ29uZmlnLmpzIiwiY29uc3QgbG9nZ2VyID0gcmVxdWlyZSgnd2luc3RvbicpO1xuY29uc3QgdWEgPSByZXF1aXJlKCd1bml2ZXJzYWwtYW5hbHl0aWNzJyk7XG5jb25zdCB7IGFuYWx5dGljcyA6IHsgZ29vZ2xlSWQgfSwgZGV0YWlsczogeyB0aXRsZSB9IH0gPSByZXF1aXJlKCcuLi8uLi9jb25maWcvc2l0ZUNvbmZpZy5qcycpO1xuXG5mdW5jdGlvbiBjcmVhdGVTZXJ2ZUV2ZW50UGFyYW1zIChoZWFkZXJzLCBpcCwgb3JpZ2luYWxVcmwpIHtcbiAgcmV0dXJuIHtcbiAgICBldmVudENhdGVnb3J5ICAgIDogJ2NsaWVudCByZXF1ZXN0cycsXG4gICAgZXZlbnRBY3Rpb24gICAgICA6ICdzZXJ2ZSByZXF1ZXN0JyxcbiAgICBldmVudExhYmVsICAgICAgIDogb3JpZ2luYWxVcmwsXG4gICAgaXBPdmVycmlkZSAgICAgICA6IGlwLFxuICAgIHVzZXJBZ2VudE92ZXJyaWRlOiBoZWFkZXJzWyd1c2VyLWFnZW50J10sXG4gIH07XG59O1xuXG5mdW5jdGlvbiBjcmVhdGVQdWJsaXNoVGltaW5nRXZlbnRQYXJhbXMgKGNhdGVnb3J5LCB2YXJpYWJsZSwgbGFiZWwsIHN0YXJ0VGltZSwgZW5kVGltZSkge1xuICBjb25zdCBkdXJhdGlvbiA9IGVuZFRpbWUgLSBzdGFydFRpbWU7XG4gIHJldHVybiB7XG4gICAgdXNlclRpbWluZ0NhdGVnb3J5ICAgIDogY2F0ZWdvcnksXG4gICAgdXNlclRpbWluZ1ZhcmlhYmxlTmFtZTogdmFyaWFibGUsXG4gICAgdXNlclRpbWluZ1RpbWUgICAgICAgIDogZHVyYXRpb24sXG4gICAgdXNlclRpbWluZ0xhYmVsICAgICAgIDogbGFiZWwsXG4gIH07XG59O1xuXG5mdW5jdGlvbiBzZW5kR29vZ2xlQW5hbHl0aWNzRXZlbnQgKGlwLCBwYXJhbXMpIHtcbiAgY29uc3QgdmlzaXRvcklkID0gaXAucmVwbGFjZSgvXFwuL2csICctJyk7XG4gIGNvbnN0IHZpc2l0b3IgPSB1YShnb29nbGVJZCwgdmlzaXRvcklkLCB7IHN0cmljdENpZEZvcm1hdDogZmFsc2UsIGh0dHBzOiB0cnVlIH0pO1xuICB2aXNpdG9yLmV2ZW50KHBhcmFtcywgKGVycikgPT4ge1xuICAgIGlmIChlcnIpIHtcbiAgICAgIGxvZ2dlci5lcnJvcignR29vZ2xlIEFuYWx5dGljcyBFdmVudCBFcnJvciA+PicsIGVycik7XG4gICAgfVxuICB9KTtcbn07XG5cbmZ1bmN0aW9uIHNlbmRHb29nbGVBbmFseXRpY3NUaW1pbmcgKHZpc2l0b3JJZCwgcGFyYW1zKSB7XG4gIGNvbnN0IHZpc2l0b3IgPSB1YShnb29nbGVJZCwgdmlzaXRvcklkLCB7IHN0cmljdENpZEZvcm1hdDogZmFsc2UsIGh0dHBzOiB0cnVlIH0pO1xuICB2aXNpdG9yLnRpbWluZyhwYXJhbXMsIChlcnIpID0+IHtcbiAgICBpZiAoZXJyKSB7XG4gICAgICBsb2dnZXIuZXJyb3IoJ0dvb2dsZSBBbmFseXRpY3MgRXZlbnQgRXJyb3IgPj4nLCBlcnIpO1xuICAgIH1cbiAgICBsb2dnZXIuZGVidWcoYFRpbWluZyBldmVudCBzdWNjZXNzZnVsbHkgc2VudCB0byBnb29nbGUgYW5hbHl0aWNzYCk7XG4gIH0pO1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIHNlbmRHQVNlcnZlRXZlbnQgKGhlYWRlcnMsIGlwLCBvcmlnaW5hbFVybCkge1xuICAgIGNvbnN0IHBhcmFtcyA9IGNyZWF0ZVNlcnZlRXZlbnRQYXJhbXMoaGVhZGVycywgaXAsIG9yaWdpbmFsVXJsKTtcbiAgICBzZW5kR29vZ2xlQW5hbHl0aWNzRXZlbnQoaXAsIHBhcmFtcyk7XG4gIH0sXG4gIHNlbmRHQVRpbWluZ0V2ZW50IChjYXRlZ29yeSwgdmFyaWFibGUsIGxhYmVsLCBzdGFydFRpbWUsIGVuZFRpbWUpIHtcbiAgICBjb25zdCBwYXJhbXMgPSBjcmVhdGVQdWJsaXNoVGltaW5nRXZlbnRQYXJhbXMoY2F0ZWdvcnksIHZhcmlhYmxlLCBsYWJlbCwgc3RhcnRUaW1lLCBlbmRUaW1lKTtcbiAgICBzZW5kR29vZ2xlQW5hbHl0aWNzVGltaW5nKHRpdGxlLCBwYXJhbXMpO1xuICB9LFxuICBjaG9vc2VHYUxicnluZXRQdWJsaXNoTGFiZWwgKHsgY2hhbm5lbF9uYW1lOiBjaGFubmVsTmFtZSwgY2hhbm5lbF9pZDogY2hhbm5lbElkIH0pIHtcbiAgICByZXR1cm4gKGNoYW5uZWxOYW1lIHx8IGNoYW5uZWxJZCA/ICdQVUJMSVNIX0lOX0NIQU5ORUxfQ0xBSU0nIDogJ1BVQkxJU0hfQU5PTllNT1VTX0NMQUlNJyk7XG4gIH0sXG59O1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vc2VydmVyL2hlbHBlcnMvZ29vZ2xlQW5hbHl0aWNzLmpzIiwiZXhwb3J0IGNvbnN0IHNlbGVjdEFzc2V0ID0gKHNob3cpID0+IHtcbiAgY29uc3QgcmVxdWVzdCA9IHNob3cucmVxdWVzdExpc3Rbc2hvdy5yZXF1ZXN0LmlkXTtcbiAgY29uc3QgYXNzZXRLZXkgPSByZXF1ZXN0LmtleTtcbiAgcmV0dXJuIHNob3cuYXNzZXRMaXN0W2Fzc2V0S2V5XTtcbn07XG5cbmV4cG9ydCBjb25zdCBzZWxlY3RTaG93U3RhdGUgPSAoc3RhdGUpID0+IHtcbiAgcmV0dXJuIHN0YXRlLnNob3c7XG59O1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vY2xpZW50L3NlbGVjdG9ycy9zaG93LmpzIiwiZXhwb3J0IGNvbnN0IHNlbGVjdFNpdGVTdGF0ZSA9IChzdGF0ZSkgPT4ge1xuICByZXR1cm4gc3RhdGUuc2l0ZTtcbn07XG5cbmV4cG9ydCBjb25zdCBzZWxlY3RTaXRlSG9zdCA9IChzdGF0ZSkgPT4ge1xuICByZXR1cm4gc3RhdGUuc2l0ZS5ob3N0O1xufTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL2NsaWVudC9zZWxlY3RvcnMvc2l0ZS5qcyIsImNvbnN0IGF4aW9zID0gcmVxdWlyZSgnYXhpb3MnKTtcbmNvbnN0IGxvZ2dlciA9IHJlcXVpcmUoJ3dpbnN0b24nKTtcbmNvbnN0IHsgYXBpOiB7IGFwaUhvc3QsIGFwaVBvcnQgfSB9ID0gcmVxdWlyZSgnLi4vLi4vY29uZmlnL2xicnlDb25maWcuanMnKTtcbmNvbnN0IGxicnlBcGlVcmkgPSAnaHR0cDovLycgKyBhcGlIb3N0ICsgJzonICsgYXBpUG9ydDtcbmNvbnN0IHsgY2hvb3NlR2FMYnJ5bmV0UHVibGlzaExhYmVsLCBzZW5kR0FUaW1pbmdFdmVudCB9ID0gcmVxdWlyZSgnLi9nb29nbGVBbmFseXRpY3MuanMnKTtcblxuY29uc3QgaGFuZGxlTGJyeW5ldFJlc3BvbnNlID0gKHsgZGF0YSB9LCByZXNvbHZlLCByZWplY3QpID0+IHtcbiAgbG9nZ2VyLmRlYnVnKCdsYnJ5IGFwaSBkYXRhOicsIGRhdGEpO1xuICBpZiAoZGF0YS5yZXN1bHQpIHtcbiAgICAvLyBjaGVjayBmb3IgYW4gZXJyb3JcbiAgICBpZiAoZGF0YS5yZXN1bHQuZXJyb3IpIHtcbiAgICAgIGxvZ2dlci5kZWJ1ZygnTGJyeW5ldCBhcGkgZXJyb3I6JywgZGF0YS5yZXN1bHQuZXJyb3IpO1xuICAgICAgcmVqZWN0KG5ldyBFcnJvcihkYXRhLnJlc3VsdC5lcnJvcikpO1xuICAgICAgcmV0dXJuO1xuICAgIH07XG4gICAgcmVzb2x2ZShkYXRhLnJlc3VsdCk7XG4gICAgcmV0dXJuO1xuICB9XG4gIC8vIGZhbGxiYWNrIGluIGNhc2UgaXQganVzdCB0aW1lZCBvdXRcbiAgcmVqZWN0KEpTT04uc3RyaW5naWZ5KGRhdGEpKTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICBwdWJsaXNoQ2xhaW0gKHB1Ymxpc2hQYXJhbXMpIHtcbiAgICBsb2dnZXIuZGVidWcoYGxicnlBcGkgPj4gUHVibGlzaGluZyBjbGFpbSB0byBcIiR7cHVibGlzaFBhcmFtcy5uYW1lfVwiYCk7XG4gICAgY29uc3QgZ2FTdGFydFRpbWUgPSBEYXRlLm5vdygpO1xuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICBheGlvc1xuICAgICAgICAucG9zdChsYnJ5QXBpVXJpLCB7XG4gICAgICAgICAgbWV0aG9kOiAncHVibGlzaCcsXG4gICAgICAgICAgcGFyYW1zOiBwdWJsaXNoUGFyYW1zLFxuICAgICAgICB9KVxuICAgICAgICAudGhlbihyZXNwb25zZSA9PiB7XG4gICAgICAgICAgc2VuZEdBVGltaW5nRXZlbnQoJ2xicnluZXQnLCAncHVibGlzaCcsIGNob29zZUdhTGJyeW5ldFB1Ymxpc2hMYWJlbChwdWJsaXNoUGFyYW1zKSwgZ2FTdGFydFRpbWUsIERhdGUubm93KCkpO1xuICAgICAgICAgIGhhbmRsZUxicnluZXRSZXNwb25zZShyZXNwb25zZSwgcmVzb2x2ZSwgcmVqZWN0KTtcbiAgICAgICAgfSlcbiAgICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICB9KTtcbiAgICB9KTtcbiAgfSxcbiAgZ2V0Q2xhaW0gKHVyaSkge1xuICAgIGxvZ2dlci5kZWJ1ZyhgbGJyeUFwaSA+PiBHZXR0aW5nIENsYWltIGZvciBcIiR7dXJpfVwiYCk7XG4gICAgY29uc3QgZ2FTdGFydFRpbWUgPSBEYXRlLm5vdygpO1xuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICBheGlvc1xuICAgICAgICAucG9zdChsYnJ5QXBpVXJpLCB7XG4gICAgICAgICAgbWV0aG9kOiAnZ2V0JyxcbiAgICAgICAgICBwYXJhbXM6IHsgdXJpLCB0aW1lb3V0OiAyMCB9LFxuICAgICAgICB9KVxuICAgICAgICAudGhlbihyZXNwb25zZSA9PiB7XG4gICAgICAgICAgc2VuZEdBVGltaW5nRXZlbnQoJ2xicnluZXQnLCAnZ2V0Q2xhaW0nLCAnR0VUJywgZ2FTdGFydFRpbWUsIERhdGUubm93KCkpO1xuICAgICAgICAgIGhhbmRsZUxicnluZXRSZXNwb25zZShyZXNwb25zZSwgcmVzb2x2ZSwgcmVqZWN0KTtcbiAgICAgICAgfSlcbiAgICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICB9KTtcbiAgICB9KTtcbiAgfSxcbiAgZ2V0Q2xhaW1MaXN0IChjbGFpbU5hbWUpIHtcbiAgICBsb2dnZXIuZGVidWcoYGxicnlBcGkgPj4gR2V0dGluZyBjbGFpbV9saXN0IGZvciBcIiR7Y2xhaW1OYW1lfVwiYCk7XG4gICAgY29uc3QgZ2FTdGFydFRpbWUgPSBEYXRlLm5vdygpO1xuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICBheGlvc1xuICAgICAgICAucG9zdChsYnJ5QXBpVXJpLCB7XG4gICAgICAgICAgbWV0aG9kOiAnY2xhaW1fbGlzdCcsXG4gICAgICAgICAgcGFyYW1zOiB7IG5hbWU6IGNsYWltTmFtZSB9LFxuICAgICAgICB9KVxuICAgICAgICAudGhlbihyZXNwb25zZSA9PiB7XG4gICAgICAgICAgc2VuZEdBVGltaW5nRXZlbnQoJ2xicnluZXQnLCAnZ2V0Q2xhaW1MaXN0JywgJ0NMQUlNX0xJU1QnLCBnYVN0YXJ0VGltZSwgRGF0ZS5ub3coKSk7XG4gICAgICAgICAgaGFuZGxlTGJyeW5ldFJlc3BvbnNlKHJlc3BvbnNlLCByZXNvbHZlLCByZWplY3QpO1xuICAgICAgICB9KVxuICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgIH0pO1xuICAgIH0pO1xuICB9LFxuICByZXNvbHZlVXJpICh1cmkpIHtcbiAgICBsb2dnZXIuZGVidWcoYGxicnlBcGkgPj4gUmVzb2x2aW5nIFVSSSBmb3IgXCIke3VyaX1cImApO1xuICAgIGNvbnN0IGdhU3RhcnRUaW1lID0gRGF0ZS5ub3coKTtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgYXhpb3NcbiAgICAgICAgLnBvc3QobGJyeUFwaVVyaSwge1xuICAgICAgICAgIG1ldGhvZDogJ3Jlc29sdmUnLFxuICAgICAgICAgIHBhcmFtczogeyB1cmkgfSxcbiAgICAgICAgfSlcbiAgICAgICAgLnRoZW4oKHsgZGF0YSB9KSA9PiB7XG4gICAgICAgICAgc2VuZEdBVGltaW5nRXZlbnQoJ2xicnluZXQnLCAncmVzb2x2ZVVyaScsICdSRVNPTFZFJywgZ2FTdGFydFRpbWUsIERhdGUubm93KCkpO1xuICAgICAgICAgIGlmIChkYXRhLnJlc3VsdFt1cmldLmVycm9yKSB7ICAvLyBjaGVjayBmb3IgZXJyb3JzXG4gICAgICAgICAgICByZWplY3QoZGF0YS5yZXN1bHRbdXJpXS5lcnJvcik7XG4gICAgICAgICAgfSBlbHNlIHsgIC8vIGlmIG5vIGVycm9ycywgcmVzb2x2ZVxuICAgICAgICAgICAgcmVzb2x2ZShkYXRhLnJlc3VsdFt1cmldKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pXG4gICAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgfSk7XG4gICAgfSk7XG4gIH0sXG4gIGdldERvd25sb2FkRGlyZWN0b3J5ICgpIHtcbiAgICBsb2dnZXIuZGVidWcoJ2xicnlBcGkgPj4gUmV0cmlldmluZyB0aGUgZG93bmxvYWQgZGlyZWN0b3J5IHBhdGggZnJvbSBsYnJ5IGRhZW1vbi4uLicpO1xuICAgIGNvbnN0IGdhU3RhcnRUaW1lID0gRGF0ZS5ub3coKTtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgYXhpb3NcbiAgICAgICAgLnBvc3QobGJyeUFwaVVyaSwge1xuICAgICAgICAgIG1ldGhvZDogJ3NldHRpbmdzX2dldCcsXG4gICAgICAgIH0pXG4gICAgICAgIC50aGVuKCh7IGRhdGEgfSkgPT4ge1xuICAgICAgICAgIHNlbmRHQVRpbWluZ0V2ZW50KCdsYnJ5bmV0JywgJ2dldERvd25sb2FkRGlyZWN0b3J5JywgJ1NFVFRJTkdTX0dFVCcsIGdhU3RhcnRUaW1lLCBEYXRlLm5vdygpKTtcbiAgICAgICAgICBpZiAoZGF0YS5yZXN1bHQpIHtcbiAgICAgICAgICAgIHJlc29sdmUoZGF0YS5yZXN1bHQuZG93bmxvYWRfZGlyZWN0b3J5KTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBFcnJvcignU3VjY2Vzc2Z1bGx5IGNvbm5lY3RlZCB0byBsYnJ5IGRhZW1vbiwgYnV0IHVuYWJsZSB0byByZXRyaWV2ZSB0aGUgZG93bmxvYWQgZGlyZWN0b3J5LicpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSlcbiAgICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICBsb2dnZXIuZXJyb3IoJ0xicnluZXQgRXJyb3I6JywgZXJyb3IpO1xuICAgICAgICAgIHJlc29sdmUoJy9ob21lL2xicnkvRG93bmxvYWRzLycpO1xuICAgICAgICB9KTtcbiAgICB9KTtcbiAgfSxcbiAgY3JlYXRlQ2hhbm5lbCAobmFtZSkge1xuICAgIGxvZ2dlci5kZWJ1ZyhgbGJyeUFwaSA+PiBDcmVhdGluZyBjaGFubmVsIGZvciAke25hbWV9Li4uYCk7XG4gICAgY29uc3QgZ2FTdGFydFRpbWUgPSBEYXRlLm5vdygpO1xuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICBheGlvc1xuICAgICAgICAucG9zdChsYnJ5QXBpVXJpLCB7XG4gICAgICAgICAgbWV0aG9kOiAnY2hhbm5lbF9uZXcnLFxuICAgICAgICAgIHBhcmFtczoge1xuICAgICAgICAgICAgY2hhbm5lbF9uYW1lOiBuYW1lLFxuICAgICAgICAgICAgYW1vdW50ICAgICAgOiAwLjEsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSlcbiAgICAgICAgLnRoZW4ocmVzcG9uc2UgPT4ge1xuICAgICAgICAgIHNlbmRHQVRpbWluZ0V2ZW50KCdsYnJ5bmV0JywgJ2NyZWF0ZUNoYW5uZWwnLCAnQ0hBTk5FTF9ORVcnLCBnYVN0YXJ0VGltZSwgRGF0ZS5ub3coKSk7XG4gICAgICAgICAgaGFuZGxlTGJyeW5ldFJlc3BvbnNlKHJlc3BvbnNlLCByZXNvbHZlLCByZWplY3QpO1xuICAgICAgICB9KVxuICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgIH0pO1xuICAgIH0pO1xuICB9LFxufTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL3NlcnZlci9oZWxwZXJzL2xicnlBcGkuanMiLCJjb25zdCB7IGRiIH0gPSByZXF1aXJlKCdteXNxbENvbmZpZycpO1xuY29uc3QgbG9nZ2VyID0gcmVxdWlyZSgnd2luc3RvbicpO1xuY29uc3QgeyByZXR1cm5QYWdpbmF0ZWRDaGFubmVsQ2xhaW1zIH0gPSByZXF1aXJlKCcuLi9oZWxwZXJzL2NoYW5uZWxQYWdpbmF0aW9uLmpzJyk7XG5cbmNvbnN0IE5PX0NIQU5ORUwgPSAnTk9fQ0hBTk5FTCc7XG5jb25zdCBOT19DTEFJTSA9ICdOT19DTEFJTSc7XG5jb25zdCBOT19GSUxFID0gJ05PX0ZJTEUnO1xuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgZ2V0Q2xhaW1JZCAoY2hhbm5lbE5hbWUsIGNoYW5uZWxDbGFpbUlkLCBuYW1lLCBjbGFpbUlkKSB7XG4gICAgaWYgKGNoYW5uZWxOYW1lKSB7XG4gICAgICByZXR1cm4gbW9kdWxlLmV4cG9ydHMuZ2V0Q2xhaW1JZEJ5Q2hhbm5lbChjaGFubmVsTmFtZSwgY2hhbm5lbENsYWltSWQsIG5hbWUpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gbW9kdWxlLmV4cG9ydHMuZ2V0Q2xhaW1JZEJ5Q2xhaW0obmFtZSwgY2xhaW1JZCk7XG4gICAgfVxuICB9LFxuICBnZXRDbGFpbUlkQnlDbGFpbSAoY2xhaW1OYW1lLCBjbGFpbUlkKSB7XG4gICAgbG9nZ2VyLmRlYnVnKGBnZXRDbGFpbUlkQnlDbGFpbSgke2NsYWltTmFtZX0sICR7Y2xhaW1JZH0pYCk7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIGRiLkNsYWltLmdldExvbmdDbGFpbUlkKGNsYWltTmFtZSwgY2xhaW1JZClcbiAgICAgICAgLnRoZW4obG9uZ0NsYWltSWQgPT4ge1xuICAgICAgICAgIGlmICghbG9uZ0NsYWltSWQpIHtcbiAgICAgICAgICAgIHJlc29sdmUoTk9fQ0xBSU0pO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXNvbHZlKGxvbmdDbGFpbUlkKTtcbiAgICAgICAgfSlcbiAgICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICB9KTtcbiAgICB9KTtcbiAgfSxcbiAgZ2V0Q2xhaW1JZEJ5Q2hhbm5lbCAoY2hhbm5lbE5hbWUsIGNoYW5uZWxDbGFpbUlkLCBjbGFpbU5hbWUpIHtcbiAgICBsb2dnZXIuZGVidWcoYGdldENsYWltSWRCeUNoYW5uZWwoJHtjaGFubmVsTmFtZX0sICR7Y2hhbm5lbENsYWltSWR9LCAke2NsYWltTmFtZX0pYCk7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIGRiLkNlcnRpZmljYXRlLmdldExvbmdDaGFubmVsSWQoY2hhbm5lbE5hbWUsIGNoYW5uZWxDbGFpbUlkKSAvLyAxLiBnZXQgdGhlIGxvbmcgY2hhbm5lbCBpZFxuICAgICAgICAudGhlbihsb25nQ2hhbm5lbElkID0+IHtcbiAgICAgICAgICBpZiAoIWxvbmdDaGFubmVsSWQpIHtcbiAgICAgICAgICAgIHJldHVybiBbbnVsbCwgbnVsbF07XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiBQcm9taXNlLmFsbChbbG9uZ0NoYW5uZWxJZCwgZGIuQ2xhaW0uZ2V0Q2xhaW1JZEJ5TG9uZ0NoYW5uZWxJZChsb25nQ2hhbm5lbElkLCBjbGFpbU5hbWUpXSk7ICAvLyAyLiBnZXQgdGhlIGxvbmcgY2xhaW0gaWRcbiAgICAgICAgfSlcbiAgICAgICAgLnRoZW4oKFtsb25nQ2hhbm5lbElkLCBsb25nQ2xhaW1JZF0pID0+IHtcbiAgICAgICAgICBpZiAoIWxvbmdDaGFubmVsSWQpIHtcbiAgICAgICAgICAgIHJldHVybiByZXNvbHZlKE5PX0NIQU5ORUwpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoIWxvbmdDbGFpbUlkKSB7XG4gICAgICAgICAgICByZXR1cm4gcmVzb2x2ZShOT19DTEFJTSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJlc29sdmUobG9uZ0NsYWltSWQpO1xuICAgICAgICB9KVxuICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgIH0pO1xuICAgIH0pO1xuICB9LFxuICBnZXRDaGFubmVsRGF0YSAoY2hhbm5lbE5hbWUsIGNoYW5uZWxDbGFpbUlkLCBwYWdlKSB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIC8vIDEuIGdldCB0aGUgbG9uZyBjaGFubmVsIElkIChtYWtlIHN1cmUgY2hhbm5lbCBleGlzdHMpXG4gICAgICBkYi5DZXJ0aWZpY2F0ZS5nZXRMb25nQ2hhbm5lbElkKGNoYW5uZWxOYW1lLCBjaGFubmVsQ2xhaW1JZClcbiAgICAgICAgLnRoZW4obG9uZ0NoYW5uZWxDbGFpbUlkID0+IHtcbiAgICAgICAgICBpZiAoIWxvbmdDaGFubmVsQ2xhaW1JZCkge1xuICAgICAgICAgICAgcmV0dXJuIFtudWxsLCBudWxsLCBudWxsXTtcbiAgICAgICAgICB9XG4gICAgICAgICAgLy8gMi4gZ2V0IHRoZSBzaG9ydCBJRCBhbmQgYWxsIGNsYWltcyBmb3IgdGhhdCBjaGFubmVsXG4gICAgICAgICAgcmV0dXJuIFByb21pc2UuYWxsKFtsb25nQ2hhbm5lbENsYWltSWQsIGRiLkNlcnRpZmljYXRlLmdldFNob3J0Q2hhbm5lbElkRnJvbUxvbmdDaGFubmVsSWQobG9uZ0NoYW5uZWxDbGFpbUlkLCBjaGFubmVsTmFtZSldKTtcbiAgICAgICAgfSlcbiAgICAgICAgLnRoZW4oKFtsb25nQ2hhbm5lbENsYWltSWQsIHNob3J0Q2hhbm5lbENsYWltSWRdKSA9PiB7XG4gICAgICAgICAgaWYgKCFsb25nQ2hhbm5lbENsYWltSWQpIHtcbiAgICAgICAgICAgIHJldHVybiByZXNvbHZlKE5PX0NIQU5ORUwpO1xuICAgICAgICAgIH1cbiAgICAgICAgICAvLyAzLiByZXR1cm4gYWxsIHRoZSBjaGFubmVsIGluZm9ybWF0aW9uXG4gICAgICAgICAgcmVzb2x2ZSh7XG4gICAgICAgICAgICBjaGFubmVsTmFtZSxcbiAgICAgICAgICAgIGxvbmdDaGFubmVsQ2xhaW1JZCxcbiAgICAgICAgICAgIHNob3J0Q2hhbm5lbENsYWltSWQsXG4gICAgICAgICAgfSk7XG4gICAgICAgIH0pXG4gICAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgfSk7XG4gICAgfSk7XG4gIH0sXG4gIGdldENoYW5uZWxDbGFpbXMgKGNoYW5uZWxOYW1lLCBjaGFubmVsQ2xhaW1JZCwgcGFnZSkge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAvLyAxLiBnZXQgdGhlIGxvbmcgY2hhbm5lbCBJZCAobWFrZSBzdXJlIGNoYW5uZWwgZXhpc3RzKVxuICAgICAgZGIuQ2VydGlmaWNhdGUuZ2V0TG9uZ0NoYW5uZWxJZChjaGFubmVsTmFtZSwgY2hhbm5lbENsYWltSWQpXG4gICAgICAgIC50aGVuKGxvbmdDaGFubmVsQ2xhaW1JZCA9PiB7XG4gICAgICAgICAgaWYgKCFsb25nQ2hhbm5lbENsYWltSWQpIHtcbiAgICAgICAgICAgIHJldHVybiBbbnVsbCwgbnVsbCwgbnVsbF07XG4gICAgICAgICAgfVxuICAgICAgICAgIC8vIDIuIGdldCB0aGUgc2hvcnQgSUQgYW5kIGFsbCBjbGFpbXMgZm9yIHRoYXQgY2hhbm5lbFxuICAgICAgICAgIHJldHVybiBQcm9taXNlLmFsbChbbG9uZ0NoYW5uZWxDbGFpbUlkLCBkYi5DbGFpbS5nZXRBbGxDaGFubmVsQ2xhaW1zKGxvbmdDaGFubmVsQ2xhaW1JZCldKTtcbiAgICAgICAgfSlcbiAgICAgICAgLnRoZW4oKFtsb25nQ2hhbm5lbENsYWltSWQsIGNoYW5uZWxDbGFpbXNBcnJheV0pID0+IHtcbiAgICAgICAgICBpZiAoIWxvbmdDaGFubmVsQ2xhaW1JZCkge1xuICAgICAgICAgICAgcmV0dXJuIHJlc29sdmUoTk9fQ0hBTk5FTCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIC8vIDMuIGZvcm1hdCB0aGUgZGF0YSBmb3IgdGhlIHZpZXcsIGluY2x1ZGluZyBwYWdpbmF0aW9uXG4gICAgICAgICAgbGV0IHBhZ2luYXRlZENoYW5uZWxWaWV3RGF0YSA9IHJldHVyblBhZ2luYXRlZENoYW5uZWxDbGFpbXMoY2hhbm5lbE5hbWUsIGxvbmdDaGFubmVsQ2xhaW1JZCwgY2hhbm5lbENsYWltc0FycmF5LCBwYWdlKTtcbiAgICAgICAgICAvLyA0LiByZXR1cm4gYWxsIHRoZSBjaGFubmVsIGluZm9ybWF0aW9uIGFuZCBjb250ZW50c1xuICAgICAgICAgIHJlc29sdmUocGFnaW5hdGVkQ2hhbm5lbFZpZXdEYXRhKTtcbiAgICAgICAgfSlcbiAgICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICB9KTtcbiAgICB9KTtcbiAgfSxcbiAgZ2V0TG9jYWxGaWxlUmVjb3JkIChjbGFpbUlkLCBuYW1lKSB7XG4gICAgcmV0dXJuIGRiLkZpbGUuZmluZE9uZSh7d2hlcmU6IHtjbGFpbUlkLCBuYW1lfX0pXG4gICAgICAudGhlbihmaWxlID0+IHtcbiAgICAgICAgaWYgKCFmaWxlKSB7XG4gICAgICAgICAgcmV0dXJuIE5PX0ZJTEU7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZpbGUuZGF0YVZhbHVlcztcbiAgICAgIH0pO1xuICB9LFxufTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL3NlcnZlci9jb250cm9sbGVycy9zZXJ2ZUNvbnRyb2xsZXIuanMiLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCJyZWFjdC1oZWxtZXRcIik7XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gZXh0ZXJuYWwgXCJyZWFjdC1oZWxtZXRcIlxuLy8gbW9kdWxlIGlkID0gMjBcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiaW1wb3J0ICogYXMgYWN0aW9ucyBmcm9tICdjb25zdGFudHMvY2hhbm5lbF9hY3Rpb25fdHlwZXMnO1xuXG4vLyBleHBvcnQgYWN0aW9uIGNyZWF0b3JzXG5cbmV4cG9ydCBmdW5jdGlvbiB1cGRhdGVMb2dnZWRJbkNoYW5uZWwgKG5hbWUsIHNob3J0SWQsIGxvbmdJZCkge1xuICByZXR1cm4ge1xuICAgIHR5cGU6IGFjdGlvbnMuQ0hBTk5FTF9VUERBVEUsXG4gICAgZGF0YToge1xuICAgICAgbmFtZSxcbiAgICAgIHNob3J0SWQsXG4gICAgICBsb25nSWQsXG4gICAgfSxcbiAgfTtcbn07XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9jbGllbnQvYWN0aW9ucy9jaGFubmVsLmpzIiwiZXhwb3J0IGNvbnN0IEZJTEVfU0VMRUNURUQgPSAnRklMRV9TRUxFQ1RFRCc7XG5leHBvcnQgY29uc3QgRklMRV9DTEVBUiA9ICdGSUxFX0NMRUFSJztcbmV4cG9ydCBjb25zdCBNRVRBREFUQV9VUERBVEUgPSAnTUVUQURBVEFfVVBEQVRFJztcbmV4cG9ydCBjb25zdCBDTEFJTV9VUERBVEUgPSAnQ0xBSU1fVVBEQVRFJztcbmV4cG9ydCBjb25zdCBTRVRfUFVCTElTSF9JTl9DSEFOTkVMID0gJ1NFVF9QVUJMSVNIX0lOX0NIQU5ORUwnO1xuZXhwb3J0IGNvbnN0IFBVQkxJU0hfU1RBVFVTX1VQREFURSA9ICdQVUJMSVNIX1NUQVRVU19VUERBVEUnO1xuZXhwb3J0IGNvbnN0IEVSUk9SX1VQREFURSA9ICdFUlJPUl9VUERBVEUnO1xuZXhwb3J0IGNvbnN0IFNFTEVDVEVEX0NIQU5ORUxfVVBEQVRFID0gJ1NFTEVDVEVEX0NIQU5ORUxfVVBEQVRFJztcbmV4cG9ydCBjb25zdCBUT0dHTEVfTUVUQURBVEFfSU5QVVRTID0gJ1RPR0dMRV9NRVRBREFUQV9JTlBVVFMnO1xuZXhwb3J0IGNvbnN0IFRIVU1CTkFJTF9ORVcgPSAnVEhVTUJOQUlMX05FVyc7XG5leHBvcnQgY29uc3QgUFVCTElTSF9TVEFSVCA9ICdQVUJMSVNIX1NUQVJUJztcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL2NsaWVudC9jb25zdGFudHMvcHVibGlzaF9hY3Rpb25fdHlwZXMuanMiLCJpbXBvcnQgUmVhY3QgZnJvbSAncmVhY3QnO1xuaW1wb3J0IFByb3BUeXBlcyBmcm9tICdwcm9wLXR5cGVzJztcbmltcG9ydCBBY3RpdmVTdGF0dXNCYXIgZnJvbSAnY29tcG9uZW50cy9BY3RpdmVTdGF0dXNCYXInO1xuaW1wb3J0IEluYWN0aXZlU3RhdHVzQmFyIGZyb20gJ2NvbXBvbmVudHMvSW5hY3RpdmVTdGF0dXNCYXInO1xuXG5jbGFzcyBQcm9ncmVzc0JhciBleHRlbmRzIFJlYWN0LkNvbXBvbmVudCB7XG4gIGNvbnN0cnVjdG9yIChwcm9wcykge1xuICAgIHN1cGVyKHByb3BzKTtcbiAgICB0aGlzLnN0YXRlID0ge1xuICAgICAgYmFycyAgICAgICA6IFtdLFxuICAgICAgaW5kZXggICAgICA6IDAsXG4gICAgICBpbmNyZW1lbnRlcjogMSxcbiAgICB9O1xuICAgIHRoaXMuY3JlYXRlQmFycyA9IHRoaXMuY3JlYXRlQmFycy5iaW5kKHRoaXMpO1xuICAgIHRoaXMuc3RhcnRQcm9ncmVzc0JhciA9IHRoaXMuc3RhcnRQcm9ncmVzc0Jhci5iaW5kKHRoaXMpO1xuICAgIHRoaXMudXBkYXRlUHJvZ3Jlc3NCYXIgPSB0aGlzLnVwZGF0ZVByb2dyZXNzQmFyLmJpbmQodGhpcyk7XG4gICAgdGhpcy5zdG9wUHJvZ3Jlc3NCYXIgPSB0aGlzLnN0b3BQcm9ncmVzc0Jhci5iaW5kKHRoaXMpO1xuICB9XG4gIGNvbXBvbmVudERpZE1vdW50ICgpIHtcbiAgICB0aGlzLmNyZWF0ZUJhcnMoKTtcbiAgICB0aGlzLnN0YXJ0UHJvZ3Jlc3NCYXIoKTtcbiAgfVxuICBjb21wb25lbnRXaWxsVW5tb3VudCAoKSB7XG4gICAgdGhpcy5zdG9wUHJvZ3Jlc3NCYXIoKTtcbiAgfVxuICBjcmVhdGVCYXJzICgpIHtcbiAgICBjb25zdCBiYXJzID0gW107XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPD0gdGhpcy5wcm9wcy5zaXplOyBpKyspIHtcbiAgICAgIGJhcnMucHVzaCh7aXNBY3RpdmU6IGZhbHNlfSk7XG4gICAgfVxuICAgIHRoaXMuc2V0U3RhdGUoeyBiYXJzIH0pO1xuICB9XG4gIHN0YXJ0UHJvZ3Jlc3NCYXIgKCkge1xuICAgIHRoaXMudXBkYXRlSW50ZXJ2YWwgPSBzZXRJbnRlcnZhbCh0aGlzLnVwZGF0ZVByb2dyZXNzQmFyLmJpbmQodGhpcyksIDMwMCk7XG4gIH07XG4gIHVwZGF0ZVByb2dyZXNzQmFyICgpIHtcbiAgICBsZXQgaW5kZXggPSB0aGlzLnN0YXRlLmluZGV4O1xuICAgIGxldCBpbmNyZW1lbnRlciA9IHRoaXMuc3RhdGUuaW5jcmVtZW50ZXI7XG4gICAgbGV0IGJhcnMgPSB0aGlzLnN0YXRlLmJhcnM7XG4gICAgLy8gZmxpcCBpbmNyZW1lbnRlciBpZiBuZWNlc3NhcnksIHRvIHN0YXkgaW4gYm91bmRzXG4gICAgaWYgKChpbmRleCA8IDApIHx8IChpbmRleCA+IHRoaXMucHJvcHMuc2l6ZSkpIHtcbiAgICAgIGluY3JlbWVudGVyID0gaW5jcmVtZW50ZXIgKiAtMTtcbiAgICAgIGluZGV4ICs9IGluY3JlbWVudGVyO1xuICAgIH1cbiAgICAvLyB1cGRhdGUgdGhlIGluZGV4ZWQgYmFyXG4gICAgaWYgKGluY3JlbWVudGVyID4gMCkge1xuICAgICAgYmFyc1tpbmRleF0uaXNBY3RpdmUgPSB0cnVlO1xuICAgIH0gZWxzZSB7XG4gICAgICBiYXJzW2luZGV4XS5pc0FjdGl2ZSA9IGZhbHNlO1xuICAgIH07XG4gICAgLy8gaW5jcmVtZW50IGluZGV4XG4gICAgaW5kZXggKz0gaW5jcmVtZW50ZXI7XG4gICAgLy8gdXBkYXRlIHN0YXRlXG4gICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICBiYXJzLFxuICAgICAgaW5jcmVtZW50ZXIsXG4gICAgICBpbmRleCxcbiAgICB9KTtcbiAgfTtcbiAgc3RvcFByb2dyZXNzQmFyICgpIHtcbiAgICBjbGVhckludGVydmFsKHRoaXMudXBkYXRlSW50ZXJ2YWwpO1xuICB9O1xuICByZW5kZXIgKCkge1xuICAgIHJldHVybiAoXG4gICAgICA8ZGl2PlxuICAgICAgICB7dGhpcy5zdGF0ZS5iYXJzLm1hcCgoYmFyLCBpbmRleCkgPT4gYmFyLmlzQWN0aXZlID8gPEFjdGl2ZVN0YXR1c0JhciBrZXk9e2luZGV4fSAvPiA6IDxJbmFjdGl2ZVN0YXR1c0JhciBrZXk9e2luZGV4fS8+KX1cbiAgICAgIDwvZGl2PlxuICAgICk7XG4gIH1cbn07XG5cblByb2dyZXNzQmFyLnByb3BUeXBlcyA9IHtcbiAgc2l6ZTogUHJvcFR5cGVzLm51bWJlci5pc1JlcXVpcmVkLFxufTtcblxuZXhwb3J0IGRlZmF1bHQgUHJvZ3Jlc3NCYXI7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9jbGllbnQvY29tcG9uZW50cy9Qcm9ncmVzc0Jhci9pbmRleC5qc3giLCJpbXBvcnQgUmVhY3QgZnJvbSAncmVhY3QnO1xuaW1wb3J0IFByb3BUeXBlcyBmcm9tICdwcm9wLXR5cGVzJztcbmltcG9ydCBOYXZCYXIgZnJvbSAnY29udGFpbmVycy9OYXZCYXInO1xuXG5jbGFzcyBFcnJvclBhZ2UgZXh0ZW5kcyBSZWFjdC5Db21wb25lbnQge1xuICByZW5kZXIgKCkge1xuICAgIGNvbnN0IHsgZXJyb3IgfSA9IHRoaXMucHJvcHM7XG4gICAgcmV0dXJuIChcbiAgICAgIDxkaXY+XG4gICAgICAgIDxOYXZCYXIgLz5cbiAgICAgICAgPGRpdiBjbGFzc05hbWU9J3JvdyByb3ctLXBhZGRlZCc+XG4gICAgICAgICAgPHA+e2Vycm9yfTwvcD5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cbiAgICApO1xuICB9XG59O1xuXG5FcnJvclBhZ2UucHJvcFR5cGVzID0ge1xuICBlcnJvcjogUHJvcFR5cGVzLnN0cmluZy5pc1JlcXVpcmVkLFxufTtcblxuZXhwb3J0IGRlZmF1bHQgRXJyb3JQYWdlO1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vY2xpZW50L3BhZ2VzL0Vycm9yUGFnZS9pbmRleC5qc3giLCJleHBvcnQgY29uc3QgTE9DQUxfQ0hFQ0sgPSAnTE9DQUxfQ0hFQ0snO1xuZXhwb3J0IGNvbnN0IFVOQVZBSUxBQkxFID0gJ1VOQVZBSUxBQkxFJztcbmV4cG9ydCBjb25zdCBFUlJPUiA9ICdFUlJPUic7XG5leHBvcnQgY29uc3QgQVZBSUxBQkxFID0gJ0FWQUlMQUJMRSc7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9jbGllbnQvY29uc3RhbnRzL2Fzc2V0X2Rpc3BsYXlfc3RhdGVzLmpzIiwiY29uc3QgbG9nZ2VyID0gcmVxdWlyZSgnd2luc3RvbicpO1xuY29uc3QgeyBkYiB9ID0gcmVxdWlyZSgnbXlzcWxDb25maWcnKTtcbmNvbnN0IGxicnlBcGkgPSByZXF1aXJlKCcuLi9oZWxwZXJzL2xicnlBcGkuanMnKTtcbmNvbnN0IHB1Ymxpc2hIZWxwZXJzID0gcmVxdWlyZSgnLi4vaGVscGVycy9wdWJsaXNoSGVscGVycy5qcycpO1xuY29uc3QgeyBwdWJsaXNoaW5nOiB7IHByaW1hcnlDbGFpbUFkZHJlc3MsIGFkZGl0aW9uYWxDbGFpbUFkZHJlc3NlcyB9IH0gPSByZXF1aXJlKCcuLi8uLi9jb25maWcvc2l0ZUNvbmZpZy5qcycpO1xuY29uc3QgU2VxdWVsaXplID0gcmVxdWlyZSgnc2VxdWVsaXplJyk7XG5jb25zdCBPcCA9IFNlcXVlbGl6ZS5PcDtcblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIHB1Ymxpc2ggKHB1Ymxpc2hQYXJhbXMsIGZpbGVOYW1lLCBmaWxlVHlwZSkge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICBsZXQgcHVibGlzaFJlc3VsdHMsIGNlcnRpZmljYXRlSWQsIGNoYW5uZWxOYW1lO1xuICAgICAgLy8gcHVibGlzaCB0aGUgZmlsZVxuICAgICAgcmV0dXJuIGxicnlBcGkucHVibGlzaENsYWltKHB1Ymxpc2hQYXJhbXMpXG4gICAgICAgIC50aGVuKHR4ID0+IHtcbiAgICAgICAgICBsb2dnZXIuaW5mbyhgU3VjY2Vzc2Z1bGx5IHB1Ymxpc2hlZCAke3B1Ymxpc2hQYXJhbXMubmFtZX0gJHtmaWxlTmFtZX1gLCB0eCk7XG4gICAgICAgICAgcHVibGlzaFJlc3VsdHMgPSB0eDtcbiAgICAgICAgICAvLyBnZXQgdGhlIGNoYW5uZWwgaW5mb3JtYXRpb25cbiAgICAgICAgICBpZiAocHVibGlzaFBhcmFtcy5jaGFubmVsX25hbWUpIHtcbiAgICAgICAgICAgIGxvZ2dlci5kZWJ1ZyhgdGhpcyBjbGFpbSB3YXMgcHVibGlzaGVkIGluIGNoYW5uZWw6ICR7cHVibGlzaFBhcmFtcy5jaGFubmVsX25hbWV9YCk7XG4gICAgICAgICAgICByZXR1cm4gZGIuQ2hhbm5lbC5maW5kT25lKHt3aGVyZToge2NoYW5uZWxOYW1lOiBwdWJsaXNoUGFyYW1zLmNoYW5uZWxfbmFtZX19KTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgbG9nZ2VyLmRlYnVnKCd0aGlzIGNsYWltIHdhcyBub3QgcHVibGlzaGVkIGluIGEgY2hhbm5lbCcpO1xuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgICAgfVxuICAgICAgICB9KVxuICAgICAgICAudGhlbihjaGFubmVsID0+IHtcbiAgICAgICAgLy8gc2V0IGNoYW5uZWwgaW5mb3JtYXRpb25cbiAgICAgICAgICBjZXJ0aWZpY2F0ZUlkID0gbnVsbDtcbiAgICAgICAgICBjaGFubmVsTmFtZSA9IG51bGw7XG4gICAgICAgICAgaWYgKGNoYW5uZWwpIHtcbiAgICAgICAgICAgIGNlcnRpZmljYXRlSWQgPSBjaGFubmVsLmNoYW5uZWxDbGFpbUlkO1xuICAgICAgICAgICAgY2hhbm5lbE5hbWUgPSBjaGFubmVsLmNoYW5uZWxOYW1lO1xuICAgICAgICAgIH1cbiAgICAgICAgICBsb2dnZXIuZGVidWcoYGNlcnRpZmljYXRlSWQ6ICR7Y2VydGlmaWNhdGVJZH1gKTtcbiAgICAgICAgfSlcbiAgICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICAvLyBjcmVhdGUgdGhlIEZpbGUgcmVjb3JkXG4gICAgICAgICAgY29uc3QgZmlsZVJlY29yZCA9IHtcbiAgICAgICAgICAgIG5hbWUgICAgICAgOiBwdWJsaXNoUGFyYW1zLm5hbWUsXG4gICAgICAgICAgICBjbGFpbUlkICAgIDogcHVibGlzaFJlc3VsdHMuY2xhaW1faWQsXG4gICAgICAgICAgICB0aXRsZSAgICAgIDogcHVibGlzaFBhcmFtcy5tZXRhZGF0YS50aXRsZSxcbiAgICAgICAgICAgIGRlc2NyaXB0aW9uOiBwdWJsaXNoUGFyYW1zLm1ldGFkYXRhLmRlc2NyaXB0aW9uLFxuICAgICAgICAgICAgYWRkcmVzcyAgICA6IHB1Ymxpc2hQYXJhbXMuY2xhaW1fYWRkcmVzcyxcbiAgICAgICAgICAgIG91dHBvaW50ICAgOiBgJHtwdWJsaXNoUmVzdWx0cy50eGlkfToke3B1Ymxpc2hSZXN1bHRzLm5vdXR9YCxcbiAgICAgICAgICAgIGhlaWdodCAgICAgOiAwLFxuICAgICAgICAgICAgZmlsZU5hbWUsXG4gICAgICAgICAgICBmaWxlUGF0aCAgIDogcHVibGlzaFBhcmFtcy5maWxlX3BhdGgsXG4gICAgICAgICAgICBmaWxlVHlwZSxcbiAgICAgICAgICAgIG5zZncgICAgICAgOiBwdWJsaXNoUGFyYW1zLm1ldGFkYXRhLm5zZncsXG4gICAgICAgICAgfTtcbiAgICAgICAgICAvLyBjcmVhdGUgdGhlIENsYWltIHJlY29yZFxuICAgICAgICAgIGNvbnN0IGNsYWltUmVjb3JkID0ge1xuICAgICAgICAgICAgbmFtZSAgICAgICA6IHB1Ymxpc2hQYXJhbXMubmFtZSxcbiAgICAgICAgICAgIGNsYWltSWQgICAgOiBwdWJsaXNoUmVzdWx0cy5jbGFpbV9pZCxcbiAgICAgICAgICAgIHRpdGxlICAgICAgOiBwdWJsaXNoUGFyYW1zLm1ldGFkYXRhLnRpdGxlLFxuICAgICAgICAgICAgZGVzY3JpcHRpb246IHB1Ymxpc2hQYXJhbXMubWV0YWRhdGEuZGVzY3JpcHRpb24sXG4gICAgICAgICAgICBhZGRyZXNzICAgIDogcHVibGlzaFBhcmFtcy5jbGFpbV9hZGRyZXNzLFxuICAgICAgICAgICAgdGh1bWJuYWlsICA6IHB1Ymxpc2hQYXJhbXMubWV0YWRhdGEudGh1bWJuYWlsLFxuICAgICAgICAgICAgb3V0cG9pbnQgICA6IGAke3B1Ymxpc2hSZXN1bHRzLnR4aWR9OiR7cHVibGlzaFJlc3VsdHMubm91dH1gLFxuICAgICAgICAgICAgaGVpZ2h0ICAgICA6IDAsXG4gICAgICAgICAgICBjb250ZW50VHlwZTogZmlsZVR5cGUsXG4gICAgICAgICAgICBuc2Z3ICAgICAgIDogcHVibGlzaFBhcmFtcy5tZXRhZGF0YS5uc2Z3LFxuICAgICAgICAgICAgYW1vdW50ICAgICA6IHB1Ymxpc2hQYXJhbXMuYmlkLFxuICAgICAgICAgICAgY2VydGlmaWNhdGVJZCxcbiAgICAgICAgICAgIGNoYW5uZWxOYW1lLFxuICAgICAgICAgIH07XG4gICAgICAgICAgLy8gdXBzZXJ0IGNyaXRlcmlhXG4gICAgICAgICAgY29uc3QgdXBzZXJ0Q3JpdGVyaWEgPSB7XG4gICAgICAgICAgICBuYW1lICAgOiBwdWJsaXNoUGFyYW1zLm5hbWUsXG4gICAgICAgICAgICBjbGFpbUlkOiBwdWJsaXNoUmVzdWx0cy5jbGFpbV9pZCxcbiAgICAgICAgICB9O1xuICAgICAgICAgIC8vIHVwc2VydCB0aGUgcmVjb3Jkc1xuICAgICAgICAgIHJldHVybiBQcm9taXNlLmFsbChbZGIudXBzZXJ0KGRiLkZpbGUsIGZpbGVSZWNvcmQsIHVwc2VydENyaXRlcmlhLCAnRmlsZScpLCBkYi51cHNlcnQoZGIuQ2xhaW0sIGNsYWltUmVjb3JkLCB1cHNlcnRDcml0ZXJpYSwgJ0NsYWltJyldKTtcbiAgICAgICAgfSlcbiAgICAgICAgLnRoZW4oKFtmaWxlLCBjbGFpbV0pID0+IHtcbiAgICAgICAgICBsb2dnZXIuZGVidWcoJ0ZpbGUgYW5kIENsYWltIHJlY29yZHMgc3VjY2Vzc2Z1bGx5IGNyZWF0ZWQnKTtcbiAgICAgICAgICByZXR1cm4gUHJvbWlzZS5hbGwoW2ZpbGUuc2V0Q2xhaW0oY2xhaW0pLCBjbGFpbS5zZXRGaWxlKGZpbGUpXSk7XG4gICAgICAgIH0pXG4gICAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgICBsb2dnZXIuZGVidWcoJ0ZpbGUgYW5kIENsYWltIHJlY29yZHMgc3VjY2Vzc2Z1bGx5IGFzc29jaWF0ZWQnKTtcbiAgICAgICAgICByZXNvbHZlKHB1Ymxpc2hSZXN1bHRzKTsgLy8gcmVzb2x2ZSB0aGUgcHJvbWlzZSB3aXRoIHRoZSByZXN1bHQgZnJvbSBsYnJ5QXBpLnB1Ymxpc2hDbGFpbTtcbiAgICAgICAgfSlcbiAgICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICBsb2dnZXIuZXJyb3IoJ1BVQkxJU0ggRVJST1InLCBlcnJvcik7XG4gICAgICAgICAgcHVibGlzaEhlbHBlcnMuZGVsZXRlVGVtcG9yYXJ5RmlsZShwdWJsaXNoUGFyYW1zLmZpbGVfcGF0aCk7IC8vIGRlbGV0ZSB0aGUgbG9jYWwgZmlsZVxuICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgIH0pO1xuICAgIH0pO1xuICB9LFxuICBjbGFpbU5hbWVJc0F2YWlsYWJsZSAobmFtZSkge1xuICAgIGNvbnN0IGNsYWltQWRkcmVzc2VzID0gYWRkaXRpb25hbENsYWltQWRkcmVzc2VzIHx8IFtdO1xuICAgIGNsYWltQWRkcmVzc2VzLnB1c2gocHJpbWFyeUNsYWltQWRkcmVzcyk7XG4gICAgLy8gZmluZCBhbnkgcmVjb3JkcyB3aGVyZSB0aGUgbmFtZSBpcyB1c2VkXG4gICAgcmV0dXJuIGRiLkNsYWltXG4gICAgICAuZmluZEFsbCh7XG4gICAgICAgIGF0dHJpYnV0ZXM6IFsnYWRkcmVzcyddLFxuICAgICAgICB3aGVyZSAgICAgOiB7XG4gICAgICAgICAgbmFtZSxcbiAgICAgICAgICBhZGRyZXNzOiB7XG4gICAgICAgICAgICBbT3Aub3JdOiBjbGFpbUFkZHJlc3NlcyxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgfSlcbiAgICAgIC50aGVuKHJlc3VsdCA9PiB7XG4gICAgICAgIGlmIChyZXN1bHQubGVuZ3RoID49IDEpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1RoYXQgY2xhaW0gaXMgYWxyZWFkeSBpbiB1c2UnKTtcbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIG5hbWU7XG4gICAgICB9KVxuICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICB9KTtcbiAgfSxcbiAgY2hlY2tDaGFubmVsQXZhaWxhYmlsaXR5IChuYW1lKSB7XG4gICAgcmV0dXJuIGRiLkNoYW5uZWxcbiAgICAgIC5maW5kQWxsKHtcbiAgICAgICAgd2hlcmU6IHsgY2hhbm5lbE5hbWU6IG5hbWUgfSxcbiAgICAgIH0pXG4gICAgICAudGhlbihyZXN1bHQgPT4ge1xuICAgICAgICBpZiAocmVzdWx0Lmxlbmd0aCA+PSAxKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdUaGF0IGNoYW5uZWwgaGFzIGFscmVhZHkgYmVlbiBjbGFpbWVkJyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG5hbWU7XG4gICAgICB9KVxuICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICB9KTtcbiAgfSxcbn07XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9zZXJ2ZXIvY29udHJvbGxlcnMvcHVibGlzaENvbnRyb2xsZXIuanMiLCJjb25zdCBsb2dnZXIgPSByZXF1aXJlKCd3aW5zdG9uJyk7XG5jb25zdCBmcyA9IHJlcXVpcmUoJ2ZzJyk7XG5cbmNvbnN0IHsgZGV0YWlscywgcHVibGlzaGluZyB9ID0gcmVxdWlyZSgnLi4vLi4vY29uZmlnL3NpdGVDb25maWcuanMnKTtcblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIHBhcnNlUHVibGlzaEFwaVJlcXVlc3RCb2R5ICh7bmFtZSwgbnNmdywgbGljZW5zZSwgdGl0bGUsIGRlc2NyaXB0aW9uLCB0aHVtYm5haWx9KSB7XG4gICAgLy8gdmFsaWRhdGUgbmFtZVxuICAgIGlmICghbmFtZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdubyBuYW1lIGZpZWxkIGZvdW5kIGluIHJlcXVlc3QnKTtcbiAgICB9XG4gICAgY29uc3QgaW52YWxpZE5hbWVDaGFyYWN0ZXJzID0gL1teQS1aYS16MC05LC1dLy5leGVjKG5hbWUpO1xuICAgIGlmIChpbnZhbGlkTmFtZUNoYXJhY3RlcnMpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignVGhlIGNsYWltIG5hbWUgeW91IHByb3ZpZGVkIGlzIG5vdCBhbGxvd2VkLiAgT25seSB0aGUgZm9sbG93aW5nIGNoYXJhY3RlcnMgYXJlIGFsbG93ZWQ6IEEtWiwgYS16LCAwLTksIGFuZCBcIi1cIicpO1xuICAgIH1cbiAgICAvLyBvcHRpb25hbCBwYXJhbWV0ZXJzXG4gICAgbnNmdyA9IChuc2Z3ID09PSAndHJ1ZScpO1xuICAgIGxpY2Vuc2UgPSBsaWNlbnNlIHx8IG51bGw7XG4gICAgdGl0bGUgPSB0aXRsZSB8fCBudWxsO1xuICAgIGRlc2NyaXB0aW9uID0gZGVzY3JpcHRpb24gfHwgbnVsbDtcbiAgICB0aHVtYm5haWwgPSB0aHVtYm5haWwgfHwgbnVsbDtcbiAgICAvLyByZXR1cm4gcmVzdWx0c1xuICAgIHJldHVybiB7XG4gICAgICBuYW1lLFxuICAgICAgbnNmdyxcbiAgICAgIGxpY2Vuc2UsXG4gICAgICB0aXRsZSxcbiAgICAgIGRlc2NyaXB0aW9uLFxuICAgICAgdGh1bWJuYWlsLFxuICAgIH07XG4gIH0sXG4gIHBhcnNlUHVibGlzaEFwaVJlcXVlc3RGaWxlcyAoe2ZpbGUsIHRodW1ibmFpbH0pIHtcbiAgICAvLyBtYWtlIHN1cmUgYSBmaWxlIHdhcyBwcm92aWRlZFxuICAgIGlmICghZmlsZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdubyBmaWxlIHdpdGgga2V5IG9mIFtmaWxlXSBmb3VuZCBpbiByZXF1ZXN0Jyk7XG4gICAgfVxuICAgIGlmICghZmlsZS5wYXRoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ25vIGZpbGUgcGF0aCBmb3VuZCcpO1xuICAgIH1cbiAgICBpZiAoIWZpbGUudHlwZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdubyBmaWxlIHR5cGUgZm91bmQnKTtcbiAgICB9XG4gICAgaWYgKCFmaWxlLnNpemUpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignbm8gZmlsZSB0eXBlIGZvdW5kJyk7XG4gICAgfVxuICAgIC8vIHZhbGlkYXRlIHRoZSBmaWxlIG5hbWVcbiAgICBpZiAoLycvLnRlc3QoZmlsZS5uYW1lKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdhcG9zdHJvcGhlcyBhcmUgbm90IGFsbG93ZWQgaW4gdGhlIGZpbGUgbmFtZScpO1xuICAgIH1cbiAgICAvLyB2YWxpZGF0ZSB0aGUgZmlsZVxuICAgIG1vZHVsZS5leHBvcnRzLnZhbGlkYXRlRmlsZVR5cGVBbmRTaXplKGZpbGUpO1xuICAgIC8vIHJldHVybiByZXN1bHRzXG4gICAgcmV0dXJuIHtcbiAgICAgIGZpbGVOYW1lICAgICAgICAgOiBmaWxlLm5hbWUsXG4gICAgICBmaWxlUGF0aCAgICAgICAgIDogZmlsZS5wYXRoLFxuICAgICAgZmlsZVR5cGUgICAgICAgICA6IGZpbGUudHlwZSxcbiAgICAgIHRodW1ibmFpbEZpbGVOYW1lOiAodGh1bWJuYWlsID8gdGh1bWJuYWlsLm5hbWUgOiBudWxsKSxcbiAgICAgIHRodW1ibmFpbEZpbGVQYXRoOiAodGh1bWJuYWlsID8gdGh1bWJuYWlsLnBhdGggOiBudWxsKSxcbiAgICAgIHRodW1ibmFpbEZpbGVUeXBlOiAodGh1bWJuYWlsID8gdGh1bWJuYWlsLnR5cGUgOiBudWxsKSxcbiAgICB9O1xuICB9LFxuICB2YWxpZGF0ZUZpbGVUeXBlQW5kU2l6ZSAoZmlsZSkge1xuICAgIC8vIGNoZWNrIGZpbGUgdHlwZSBhbmQgc2l6ZVxuICAgIHN3aXRjaCAoZmlsZS50eXBlKSB7XG4gICAgICBjYXNlICdpbWFnZS9qcGVnJzpcbiAgICAgIGNhc2UgJ2ltYWdlL2pwZyc6XG4gICAgICBjYXNlICdpbWFnZS9wbmcnOlxuICAgICAgICBpZiAoZmlsZS5zaXplID4gMTAwMDAwMDApIHtcbiAgICAgICAgICBsb2dnZXIuZGVidWcoJ3B1Ymxpc2ggPiBmaWxlIHZhbGlkYXRpb24gPiAuanBlZy8uanBnLy5wbmcgd2FzIHRvbyBiaWcnKTtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1NvcnJ5LCBpbWFnZXMgYXJlIGxpbWl0ZWQgdG8gMTAgbWVnYWJ5dGVzLicpO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnaW1hZ2UvZ2lmJzpcbiAgICAgICAgaWYgKGZpbGUuc2l6ZSA+IDUwMDAwMDAwKSB7XG4gICAgICAgICAgbG9nZ2VyLmRlYnVnKCdwdWJsaXNoID4gZmlsZSB2YWxpZGF0aW9uID4gLmdpZiB3YXMgdG9vIGJpZycpO1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcignU29ycnksIC5naWZzIGFyZSBsaW1pdGVkIHRvIDUwIG1lZ2FieXRlcy4nKTtcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ3ZpZGVvL21wNCc6XG4gICAgICAgIGlmIChmaWxlLnNpemUgPiA1MDAwMDAwMCkge1xuICAgICAgICAgIGxvZ2dlci5kZWJ1ZygncHVibGlzaCA+IGZpbGUgdmFsaWRhdGlvbiA+IC5tcDQgd2FzIHRvbyBiaWcnKTtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1NvcnJ5LCB2aWRlb3MgYXJlIGxpbWl0ZWQgdG8gNTAgbWVnYWJ5dGVzLicpO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgbG9nZ2VyLmRlYnVnKCdwdWJsaXNoID4gZmlsZSB2YWxpZGF0aW9uID4gdW5yZWNvZ25pemVkIGZpbGUgdHlwZScpO1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1RoZSAnICsgZmlsZS50eXBlICsgJyBjb250ZW50IHR5cGUgaXMgbm90IHN1cHBvcnRlZC4gIE9ubHksIC5qcGVnLCAucG5nLCAuZ2lmLCBhbmQgLm1wNCBmaWxlcyBhcmUgY3VycmVudGx5IHN1cHBvcnRlZC4nKTtcbiAgICB9XG4gICAgcmV0dXJuIGZpbGU7XG4gIH0sXG4gIGNyZWF0ZUJhc2ljUHVibGlzaFBhcmFtcyAoZmlsZVBhdGgsIG5hbWUsIHRpdGxlLCBkZXNjcmlwdGlvbiwgbGljZW5zZSwgbnNmdywgdGh1bWJuYWlsKSB7XG4gICAgbG9nZ2VyLmRlYnVnKGBDcmVhdGluZyBQdWJsaXNoIFBhcmFtZXRlcnNgKTtcbiAgICAvLyBwcm92aWRlIGRlZmF1bHRzIGZvciB0aXRsZVxuICAgIGlmICh0aXRsZSA9PT0gbnVsbCB8fCB0aXRsZS50cmltKCkgPT09ICcnKSB7XG4gICAgICB0aXRsZSA9IG5hbWU7XG4gICAgfVxuICAgIC8vIHByb3ZpZGUgZGVmYXVsdCBmb3IgZGVzY3JpcHRpb25cbiAgICBpZiAoZGVzY3JpcHRpb24gPT09IG51bGwgfHwgZGVzY3JpcHRpb24udHJpbSgpID09PSAnJykge1xuICAgICAgZGVzY3JpcHRpb24gPSAnJztcbiAgICB9XG4gICAgLy8gcHJvdmlkZSBkZWZhdWx0IGZvciBsaWNlbnNlXG4gICAgaWYgKGxpY2Vuc2UgPT09IG51bGwgfHwgbGljZW5zZS50cmltKCkgPT09ICcnKSB7XG4gICAgICBsaWNlbnNlID0gJyAnOyAgLy8gZGVmYXVsdCB0byBlbXB0eSBzdHJpbmdcbiAgICB9XG4gICAgLy8gY3JlYXRlIHRoZSBwdWJsaXNoIHBhcmFtc1xuICAgIGNvbnN0IHB1Ymxpc2hQYXJhbXMgPSB7XG4gICAgICBuYW1lLFxuICAgICAgZmlsZV9wYXRoOiBmaWxlUGF0aCxcbiAgICAgIGJpZCAgICAgIDogMC4wMSxcbiAgICAgIG1ldGFkYXRhIDoge1xuICAgICAgICBkZXNjcmlwdGlvbixcbiAgICAgICAgdGl0bGUsXG4gICAgICAgIGF1dGhvciAgOiBkZXRhaWxzLnRpdGxlLFxuICAgICAgICBsYW5ndWFnZTogJ2VuJyxcbiAgICAgICAgbGljZW5zZSxcbiAgICAgICAgbnNmdyxcbiAgICAgIH0sXG4gICAgICBjbGFpbV9hZGRyZXNzOiBwdWJsaXNoaW5nLnByaW1hcnlDbGFpbUFkZHJlc3MsXG4gICAgfTtcbiAgICAvLyBhZGQgdGh1bWJuYWlsIHRvIGNoYW5uZWwgaWYgdmlkZW9cbiAgICBpZiAodGh1bWJuYWlsKSB7XG4gICAgICBwdWJsaXNoUGFyYW1zWydtZXRhZGF0YSddWyd0aHVtYm5haWwnXSA9IHRodW1ibmFpbDtcbiAgICB9XG4gICAgcmV0dXJuIHB1Ymxpc2hQYXJhbXM7XG4gIH0sXG4gIGNyZWF0ZVRodW1ibmFpbFB1Ymxpc2hQYXJhbXMgKHRodW1ibmFpbEZpbGVQYXRoLCBjbGFpbU5hbWUsIGxpY2Vuc2UsIG5zZncpIHtcbiAgICBpZiAoIXRodW1ibmFpbEZpbGVQYXRoKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGxvZ2dlci5kZWJ1ZyhgQ3JlYXRpbmcgVGh1bWJuYWlsIFB1Ymxpc2ggUGFyYW1ldGVyc2ApO1xuICAgIC8vIGNyZWF0ZSB0aGUgcHVibGlzaCBwYXJhbXNcbiAgICByZXR1cm4ge1xuICAgICAgbmFtZSAgICAgOiBgJHtjbGFpbU5hbWV9LXRodW1iYCxcbiAgICAgIGZpbGVfcGF0aDogdGh1bWJuYWlsRmlsZVBhdGgsXG4gICAgICBiaWQgICAgICA6IDAuMDEsXG4gICAgICBtZXRhZGF0YSA6IHtcbiAgICAgICAgdGl0bGUgICAgICA6IGAke2NsYWltTmFtZX0gdGh1bWJuYWlsYCxcbiAgICAgICAgZGVzY3JpcHRpb246IGBhIHRodW1ibmFpbCBmb3IgJHtjbGFpbU5hbWV9YCxcbiAgICAgICAgYXV0aG9yICAgICA6IGRldGFpbHMudGl0bGUsXG4gICAgICAgIGxhbmd1YWdlICAgOiAnZW4nLFxuICAgICAgICBsaWNlbnNlLFxuICAgICAgICBuc2Z3LFxuICAgICAgfSxcbiAgICAgIGNsYWltX2FkZHJlc3M6IHB1Ymxpc2hpbmcucHJpbWFyeUNsYWltQWRkcmVzcyxcbiAgICAgIGNoYW5uZWxfbmFtZSA6IHB1Ymxpc2hpbmcudGh1bWJuYWlsQ2hhbm5lbCxcbiAgICAgIGNoYW5uZWxfaWQgICA6IHB1Ymxpc2hpbmcudGh1bWJuYWlsQ2hhbm5lbElkLFxuICAgIH07XG4gIH0sXG4gIGRlbGV0ZVRlbXBvcmFyeUZpbGUgKGZpbGVQYXRoKSB7XG4gICAgZnMudW5saW5rKGZpbGVQYXRoLCBlcnIgPT4ge1xuICAgICAgaWYgKGVycikge1xuICAgICAgICBsb2dnZXIuZXJyb3IoYGVycm9yIGRlbGV0aW5nIHRlbXBvcmFyeSBmaWxlICR7ZmlsZVBhdGh9YCk7XG4gICAgICAgIHRocm93IGVycjtcbiAgICAgIH1cbiAgICAgIGxvZ2dlci5kZWJ1Zyhgc3VjY2Vzc2Z1bGx5IGRlbGV0ZWQgJHtmaWxlUGF0aH1gKTtcbiAgICB9KTtcbiAgfSxcbiAgYWRkR2V0UmVzdWx0c1RvRmlsZURhdGEgKGZpbGVJbmZvLCBnZXRSZXN1bHQpIHtcbiAgICBmaWxlSW5mby5maWxlTmFtZSA9IGdldFJlc3VsdC5maWxlX25hbWU7XG4gICAgZmlsZUluZm8uZmlsZVBhdGggPSBnZXRSZXN1bHQuZG93bmxvYWRfcGF0aDtcbiAgICByZXR1cm4gZmlsZUluZm87XG4gIH0sXG4gIGNyZWF0ZUZpbGVEYXRhICh7IG5hbWUsIGNsYWltSWQsIG91dHBvaW50LCBoZWlnaHQsIGFkZHJlc3MsIG5zZncsIGNvbnRlbnRUeXBlIH0pIHtcbiAgICByZXR1cm4ge1xuICAgICAgbmFtZSxcbiAgICAgIGNsYWltSWQsXG4gICAgICBvdXRwb2ludCxcbiAgICAgIGhlaWdodCxcbiAgICAgIGFkZHJlc3MsXG4gICAgICBmaWxlTmFtZTogJycsXG4gICAgICBmaWxlUGF0aDogJycsXG4gICAgICBmaWxlVHlwZTogY29udGVudFR5cGUsXG4gICAgICBuc2Z3LFxuICAgIH07XG4gIH0sXG59O1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vc2VydmVyL2hlbHBlcnMvcHVibGlzaEhlbHBlcnMuanMiLCJpbXBvcnQgUmVhY3QgZnJvbSAncmVhY3QnO1xuaW1wb3J0IHsgUm91dGUsIFN3aXRjaCB9IGZyb20gJ3JlYWN0LXJvdXRlci1kb20nO1xuaW1wb3J0IEhvbWVQYWdlIGZyb20gJ3BhZ2VzL0hvbWVQYWdlJztcbmltcG9ydCBBYm91dFBhZ2UgZnJvbSAncGFnZXMvQWJvdXRQYWdlJztcbmltcG9ydCBMb2dpblBhZ2UgZnJvbSAncGFnZXMvTG9naW5QYWdlJztcbmltcG9ydCBTaG93UGFnZSBmcm9tICdwYWdlcy9TaG93UGFnZSc7XG5pbXBvcnQgRm91ck9oRm91clBhZ2UgZnJvbSAnY29udGFpbmVycy9Gb3VyT2hGb3VyUGFnZSc7XG4vLyBpbXBvcnQgeyBkeW5hbWljSW1wb3J0IH0gZnJvbSAndXRpbHMvZHluYW1pY0ltcG9ydCc7XG4vLyBjb25zdCBIb21lUGFnZSA9IGR5bmFtaWNJbXBvcnQoJ3BhZ2VzL0hvbWVQYWdlJyk7IC8vIG9yIHVzZSB0aGUgcHJvdmlkZWQgbG9jYWwgaG9tZXBhZ2VcblxuY29uc3QgQXBwID0gKCkgPT4ge1xuICByZXR1cm4gKFxuICAgIDxTd2l0Y2g+XG4gICAgICA8Um91dGUgZXhhY3QgcGF0aD0nLycgY29tcG9uZW50PXtIb21lUGFnZX0gLz5cbiAgICAgIDxSb3V0ZSBleGFjdCBwYXRoPScvYWJvdXQnIGNvbXBvbmVudD17QWJvdXRQYWdlfSAvPlxuICAgICAgPFJvdXRlIGV4YWN0IHBhdGg9Jy9sb2dpbicgY29tcG9uZW50PXtMb2dpblBhZ2V9IC8+XG4gICAgICA8Um91dGUgZXhhY3QgcGF0aD0nLzppZGVudGlmaWVyLzpjbGFpbScgY29tcG9uZW50PXtTaG93UGFnZX0gLz5cbiAgICAgIDxSb3V0ZSBleGFjdCBwYXRoPScvOmNsYWltJyBjb21wb25lbnQ9e1Nob3dQYWdlfSAvPlxuICAgICAgPFJvdXRlIGNvbXBvbmVudD17Rm91ck9oRm91clBhZ2V9IC8+XG4gICAgPC9Td2l0Y2g+XG4gICk7XG59O1xuXG5leHBvcnQgZGVmYXVsdCBBcHA7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9jbGllbnQvYXBwLmpzIiwiZXhwb3J0IGNvbnN0IENIQU5ORUxfVVBEQVRFID0gJ0NIQU5ORUxfVVBEQVRFJztcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL2NsaWVudC9jb25zdGFudHMvY2hhbm5lbF9hY3Rpb25fdHlwZXMuanMiLCJpbXBvcnQgeyBjb25uZWN0IH0gZnJvbSAncmVhY3QtcmVkdXgnO1xuaW1wb3J0IHsgc2VsZWN0RmlsZSwgdXBkYXRlRXJyb3IsIGNsZWFyRmlsZSB9IGZyb20gJ2FjdGlvbnMvcHVibGlzaCc7XG5pbXBvcnQgVmlldyBmcm9tICcuL3ZpZXcnO1xuXG5jb25zdCBtYXBTdGF0ZVRvUHJvcHMgPSAoeyBwdWJsaXNoIH0pID0+IHtcbiAgcmV0dXJuIHtcbiAgICBmaWxlICAgICA6IHB1Ymxpc2guZmlsZSxcbiAgICB0aHVtYm5haWw6IHB1Ymxpc2gudGh1bWJuYWlsLFxuICAgIGZpbGVFcnJvcjogcHVibGlzaC5lcnJvci5maWxlLFxuICB9O1xufTtcblxuY29uc3QgbWFwRGlzcGF0Y2hUb1Byb3BzID0gZGlzcGF0Y2ggPT4ge1xuICByZXR1cm4ge1xuICAgIHNlbGVjdEZpbGU6IChmaWxlKSA9PiB7XG4gICAgICBkaXNwYXRjaChzZWxlY3RGaWxlKGZpbGUpKTtcbiAgICB9LFxuICAgIHNldEZpbGVFcnJvcjogKHZhbHVlKSA9PiB7XG4gICAgICBkaXNwYXRjaChjbGVhckZpbGUoKSk7XG4gICAgICBkaXNwYXRjaCh1cGRhdGVFcnJvcignZmlsZScsIHZhbHVlKSk7XG4gICAgfSxcbiAgfTtcbn07XG5cbmV4cG9ydCBkZWZhdWx0IGNvbm5lY3QobWFwU3RhdGVUb1Byb3BzLCBtYXBEaXNwYXRjaFRvUHJvcHMpKFZpZXcpO1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vY2xpZW50L2NvbnRhaW5lcnMvRHJvcHpvbmUvaW5kZXguanMiLCJpbXBvcnQgeyBjb25uZWN0IH0gZnJvbSAncmVhY3QtcmVkdXgnO1xuaW1wb3J0IHsgdXBkYXRlTG9nZ2VkSW5DaGFubmVsIH0gZnJvbSAnYWN0aW9ucy9jaGFubmVsJztcbmltcG9ydCBWaWV3IGZyb20gJy4vdmlldyc7XG5pbXBvcnQge3VwZGF0ZVNlbGVjdGVkQ2hhbm5lbH0gZnJvbSAnLi4vLi4vYWN0aW9ucy9wdWJsaXNoJztcblxuY29uc3QgbWFwRGlzcGF0Y2hUb1Byb3BzID0gZGlzcGF0Y2ggPT4ge1xuICByZXR1cm4ge1xuICAgIG9uQ2hhbm5lbExvZ2luOiAobmFtZSwgc2hvcnRJZCwgbG9uZ0lkKSA9PiB7XG4gICAgICBkaXNwYXRjaCh1cGRhdGVMb2dnZWRJbkNoYW5uZWwobmFtZSwgc2hvcnRJZCwgbG9uZ0lkKSk7XG4gICAgICBkaXNwYXRjaCh1cGRhdGVTZWxlY3RlZENoYW5uZWwobmFtZSkpO1xuICAgIH0sXG4gIH07XG59O1xuXG5leHBvcnQgZGVmYXVsdCBjb25uZWN0KG51bGwsIG1hcERpc3BhdGNoVG9Qcm9wcykoVmlldyk7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9jbGllbnQvY29udGFpbmVycy9DaGFubmVsTG9naW5Gb3JtL2luZGV4LmpzIiwiaW1wb3J0IHsgY29ubmVjdCB9IGZyb20gJ3JlYWN0LXJlZHV4JztcbmltcG9ydCB7IHVwZGF0ZUxvZ2dlZEluQ2hhbm5lbCB9IGZyb20gJ2FjdGlvbnMvY2hhbm5lbCc7XG5pbXBvcnQgVmlldyBmcm9tICcuL3ZpZXcnO1xuaW1wb3J0IHt1cGRhdGVTZWxlY3RlZENoYW5uZWx9IGZyb20gJ2FjdGlvbnMvcHVibGlzaCc7XG5cbmNvbnN0IG1hcERpc3BhdGNoVG9Qcm9wcyA9IGRpc3BhdGNoID0+IHtcbiAgcmV0dXJuIHtcbiAgICBvbkNoYW5uZWxMb2dpbjogKG5hbWUsIHNob3J0SWQsIGxvbmdJZCkgPT4ge1xuICAgICAgZGlzcGF0Y2godXBkYXRlTG9nZ2VkSW5DaGFubmVsKG5hbWUsIHNob3J0SWQsIGxvbmdJZCkpO1xuICAgICAgZGlzcGF0Y2godXBkYXRlU2VsZWN0ZWRDaGFubmVsKG5hbWUpKTtcbiAgICB9LFxuICB9O1xufTtcblxuZXhwb3J0IGRlZmF1bHQgY29ubmVjdChudWxsLCBtYXBEaXNwYXRjaFRvUHJvcHMpKFZpZXcpO1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vY2xpZW50L2NvbnRhaW5lcnMvQ2hhbm5lbENyZWF0ZUZvcm0vaW5kZXguanMiLCJleHBvcnQgY29uc3QgTE9HSU4gPSAnRXhpc3RpbmcnO1xuZXhwb3J0IGNvbnN0IENSRUFURSA9ICdOZXcnO1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vY2xpZW50L2NvbnN0YW50cy9wdWJsaXNoX2NoYW5uZWxfc2VsZWN0X3N0YXRlcy5qcyIsImV4cG9ydCBjb25zdCBMT0FEX1NUQVJUID0gJ0xPQURfU1RBUlQnO1xuZXhwb3J0IGNvbnN0IExPQURJTkcgPSAnTE9BRElORyc7XG5leHBvcnQgY29uc3QgUFVCTElTSElORyA9ICdQVUJMSVNISU5HJztcbmV4cG9ydCBjb25zdCBTVUNDRVNTID0gJ1NVQ0NFU1MnO1xuZXhwb3J0IGNvbnN0IEZBSUxFRCA9ICdGQUlMRUQnO1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vY2xpZW50L2NvbnN0YW50cy9wdWJsaXNoX2NsYWltX3N0YXRlcy5qcyIsImV4cG9ydCBjb25zdCBDSEFOTkVMID0gJ0NIQU5ORUwnO1xuZXhwb3J0IGNvbnN0IEFTU0VUX0xJVEUgPSAnQVNTRVRfTElURSc7XG5leHBvcnQgY29uc3QgQVNTRVRfREVUQUlMUyA9ICdBU1NFVF9ERVRBSUxTJztcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL2NsaWVudC9jb25zdGFudHMvc2hvd19yZXF1ZXN0X3R5cGVzLmpzIiwiaW1wb3J0IHsgY29ubmVjdCB9IGZyb20gJ3JlYWN0LXJlZHV4JztcbmltcG9ydCBWaWV3IGZyb20gJy4vdmlldyc7XG5pbXBvcnQgeyBmaWxlUmVxdWVzdGVkIH0gZnJvbSAnYWN0aW9ucy9zaG93JztcbmltcG9ydCB7IHNlbGVjdEFzc2V0IH0gZnJvbSAnc2VsZWN0b3JzL3Nob3cnO1xuXG5jb25zdCBtYXBTdGF0ZVRvUHJvcHMgPSAoeyBzaG93IH0pID0+IHtcbiAgLy8gc2VsZWN0IGVycm9yIGFuZCBzdGF0dXNcbiAgY29uc3QgZXJyb3IgID0gc2hvdy5kaXNwbGF5QXNzZXQuZXJyb3I7XG4gIGNvbnN0IHN0YXR1cyA9IHNob3cuZGlzcGxheUFzc2V0LnN0YXR1cztcbiAgLy8gc2VsZWN0IGFzc2V0XG4gIGNvbnN0IGFzc2V0ID0gc2VsZWN0QXNzZXQoc2hvdyk7XG4gIC8vICByZXR1cm4gcHJvcHNcbiAgcmV0dXJuIHtcbiAgICBlcnJvcixcbiAgICBzdGF0dXMsXG4gICAgYXNzZXQsXG4gIH07XG59O1xuXG5jb25zdCBtYXBEaXNwYXRjaFRvUHJvcHMgPSBkaXNwYXRjaCA9PiB7XG4gIHJldHVybiB7XG4gICAgb25GaWxlUmVxdWVzdDogKG5hbWUsIGNsYWltSWQpID0+IHtcbiAgICAgIGRpc3BhdGNoKGZpbGVSZXF1ZXN0ZWQobmFtZSwgY2xhaW1JZCkpO1xuICAgIH0sXG4gIH07XG59O1xuXG5leHBvcnQgZGVmYXVsdCBjb25uZWN0KG1hcFN0YXRlVG9Qcm9wcywgbWFwRGlzcGF0Y2hUb1Byb3BzKShWaWV3KTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL2NsaWVudC9jb250YWluZXJzL0Fzc2V0RGlzcGxheS9pbmRleC5qcyIsImltcG9ydCB7IGNvbWJpbmVSZWR1Y2VycyB9IGZyb20gJ3JlZHV4JztcbmltcG9ydCBQdWJsaXNoUmVkdWNlciBmcm9tICdyZWR1Y2Vycy9wdWJsaXNoJztcbmltcG9ydCBDaGFubmVsUmVkdWNlciBmcm9tICdyZWR1Y2Vycy9jaGFubmVsJztcbmltcG9ydCBTaG93UmVkdWNlciBmcm9tICdyZWR1Y2Vycy9zaG93JztcbmltcG9ydCBTaXRlUmVkdWNlciBmcm9tICdyZWR1Y2Vycy9zaXRlJztcblxuZXhwb3J0IGRlZmF1bHQgY29tYmluZVJlZHVjZXJzKHtcbiAgY2hhbm5lbDogQ2hhbm5lbFJlZHVjZXIsXG4gIHB1Ymxpc2g6IFB1Ymxpc2hSZWR1Y2VyLFxuICBzaG93ICAgOiBTaG93UmVkdWNlcixcbiAgc2l0ZSAgIDogU2l0ZVJlZHVjZXIsXG59KTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL2NsaWVudC9yZWR1Y2Vycy9pbmRleC5qcyIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcInJlZHV4XCIpO1xuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIGV4dGVybmFsIFwicmVkdXhcIlxuLy8gbW9kdWxlIGlkID0gMzhcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiaW1wb3J0IHsgY2FsbCwgcHV0LCB0YWtlTGF0ZXN0IH0gZnJvbSAncmVkdXgtc2FnYS9lZmZlY3RzJztcbmltcG9ydCAqIGFzIGFjdGlvbnMgZnJvbSAnY29uc3RhbnRzL3Nob3dfYWN0aW9uX3R5cGVzJztcbmltcG9ydCB7IG9uUmVxdWVzdEVycm9yLCBvbk5ld0NoYW5uZWxSZXF1ZXN0LCBvbk5ld0Fzc2V0UmVxdWVzdCB9IGZyb20gJ2FjdGlvbnMvc2hvdyc7XG5pbXBvcnQgeyBuZXdBc3NldFJlcXVlc3QgfSBmcm9tICdzYWdhcy9zaG93X2Fzc2V0JztcbmltcG9ydCB7IG5ld0NoYW5uZWxSZXF1ZXN0IH0gZnJvbSAnc2FnYXMvc2hvd19jaGFubmVsJztcbmltcG9ydCBsYnJ5VXJpIGZyb20gJ3V0aWxzL2xicnlVcmknO1xuXG5mdW5jdGlvbiAqIHBhcnNlQW5kVXBkYXRlSWRlbnRpZmllckFuZENsYWltIChtb2RpZmllciwgY2xhaW0pIHtcbiAgLy8gdGhpcyBpcyBhIHJlcXVlc3QgZm9yIGFuIGFzc2V0XG4gIC8vIGNsYWltIHdpbGwgYmUgYW4gYXNzZXQgY2xhaW1cbiAgLy8gdGhlIGlkZW50aWZpZXIgY291bGQgYmUgYSBjaGFubmVsIG9yIGEgY2xhaW0gaWRcbiAgbGV0IGlzQ2hhbm5lbCwgY2hhbm5lbE5hbWUsIGNoYW5uZWxDbGFpbUlkLCBjbGFpbUlkLCBjbGFpbU5hbWUsIGV4dGVuc2lvbjtcbiAgdHJ5IHtcbiAgICAoeyBpc0NoYW5uZWwsIGNoYW5uZWxOYW1lLCBjaGFubmVsQ2xhaW1JZCwgY2xhaW1JZCB9ID0gbGJyeVVyaS5wYXJzZUlkZW50aWZpZXIobW9kaWZpZXIpKTtcbiAgICAoeyBjbGFpbU5hbWUsIGV4dGVuc2lvbiB9ID0gbGJyeVVyaS5wYXJzZUNsYWltKGNsYWltKSk7XG4gIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgcmV0dXJuIHlpZWxkIHB1dChvblJlcXVlc3RFcnJvcihlcnJvci5tZXNzYWdlKSk7XG4gIH1cbiAgLy8gdHJpZ2dlciBhbiBuZXcgYWN0aW9uIHRvIHVwZGF0ZSB0aGUgc3RvcmVcbiAgaWYgKGlzQ2hhbm5lbCkge1xuICAgIHJldHVybiB5aWVsZCBjYWxsKG5ld0Fzc2V0UmVxdWVzdCwgb25OZXdBc3NldFJlcXVlc3QoY2xhaW1OYW1lLCBudWxsLCBjaGFubmVsTmFtZSwgY2hhbm5lbENsYWltSWQsIGV4dGVuc2lvbikpO1xuICB9O1xuICB5aWVsZCBjYWxsKG5ld0Fzc2V0UmVxdWVzdCwgb25OZXdBc3NldFJlcXVlc3QoY2xhaW1OYW1lLCBjbGFpbUlkLCBudWxsLCBudWxsLCBleHRlbnNpb24pKTtcbn1cbmZ1bmN0aW9uICogcGFyc2VBbmRVcGRhdGVDbGFpbU9ubHkgKGNsYWltKSB7XG4gIC8vIHRoaXMgY291bGQgYmUgYSByZXF1ZXN0IGZvciBhbiBhc3NldCBvciBhIGNoYW5uZWwgcGFnZVxuICAvLyBjbGFpbSBjb3VsZCBiZSBhbiBhc3NldCBjbGFpbSBvciBhIGNoYW5uZWwgY2xhaW1cbiAgbGV0IGlzQ2hhbm5lbCwgY2hhbm5lbE5hbWUsIGNoYW5uZWxDbGFpbUlkO1xuICB0cnkge1xuICAgICh7IGlzQ2hhbm5lbCwgY2hhbm5lbE5hbWUsIGNoYW5uZWxDbGFpbUlkIH0gPSBsYnJ5VXJpLnBhcnNlSWRlbnRpZmllcihjbGFpbSkpO1xuICB9IGNhdGNoIChlcnJvcikge1xuICAgIHJldHVybiB5aWVsZCBwdXQob25SZXF1ZXN0RXJyb3IoZXJyb3IubWVzc2FnZSkpO1xuICB9XG4gIC8vIHRyaWdnZXIgYW4gbmV3IGFjdGlvbiB0byB1cGRhdGUgdGhlIHN0b3JlXG4gIC8vIHJldHVybiBlYXJseSBpZiB0aGlzIHJlcXVlc3QgaXMgZm9yIGEgY2hhbm5lbFxuICBpZiAoaXNDaGFubmVsKSB7XG4gICAgcmV0dXJuIHlpZWxkIGNhbGwobmV3Q2hhbm5lbFJlcXVlc3QsIG9uTmV3Q2hhbm5lbFJlcXVlc3QoY2hhbm5lbE5hbWUsIGNoYW5uZWxDbGFpbUlkKSk7XG4gIH1cbiAgLy8gaWYgbm90IGZvciBhIGNoYW5uZWwsIHBhcnNlIHRoZSBjbGFpbSByZXF1ZXN0XG4gIGxldCBjbGFpbU5hbWUsIGV4dGVuc2lvbjtcbiAgdHJ5IHtcbiAgICAoe2NsYWltTmFtZSwgZXh0ZW5zaW9ufSA9IGxicnlVcmkucGFyc2VDbGFpbShjbGFpbSkpO1xuICB9IGNhdGNoIChlcnJvcikge1xuICAgIHJldHVybiB5aWVsZCBwdXQob25SZXF1ZXN0RXJyb3IoZXJyb3IubWVzc2FnZSkpO1xuICB9XG4gIHlpZWxkIGNhbGwobmV3QXNzZXRSZXF1ZXN0LCBvbk5ld0Fzc2V0UmVxdWVzdChjbGFpbU5hbWUsIG51bGwsIG51bGwsIG51bGwsIGV4dGVuc2lvbikpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gKiBoYW5kbGVTaG93UGFnZVVyaSAoYWN0aW9uKSB7XG4gIGNvbnN0IHsgaWRlbnRpZmllciwgY2xhaW0gfSA9IGFjdGlvbi5kYXRhO1xuICBpZiAoaWRlbnRpZmllcikge1xuICAgIHJldHVybiB5aWVsZCBjYWxsKHBhcnNlQW5kVXBkYXRlSWRlbnRpZmllckFuZENsYWltLCBpZGVudGlmaWVyLCBjbGFpbSk7XG4gIH1cbiAgeWllbGQgY2FsbChwYXJzZUFuZFVwZGF0ZUNsYWltT25seSwgY2xhaW0pO1xufTtcblxuZXhwb3J0IGZ1bmN0aW9uICogd2F0Y2hIYW5kbGVTaG93UGFnZVVyaSAoKSB7XG4gIHlpZWxkIHRha2VMYXRlc3QoYWN0aW9ucy5IQU5ETEVfU0hPV19VUkksIGhhbmRsZVNob3dQYWdlVXJpKTtcbn07XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9jbGllbnQvc2FnYXMvc2hvd191cmkuanMiLCJpbXBvcnQgeyBjYWxsLCBwdXQsIHNlbGVjdCwgdGFrZUxhdGVzdCB9IGZyb20gJ3JlZHV4LXNhZ2EvZWZmZWN0cyc7XG5pbXBvcnQgKiBhcyBhY3Rpb25zIGZyb20gJ2NvbnN0YW50cy9zaG93X2FjdGlvbl90eXBlcyc7XG5pbXBvcnQgeyBhZGRSZXF1ZXN0VG9SZXF1ZXN0TGlzdCwgb25SZXF1ZXN0RXJyb3IsIG9uUmVxdWVzdFVwZGF0ZSwgYWRkQXNzZXRUb0Fzc2V0TGlzdCB9IGZyb20gJ2FjdGlvbnMvc2hvdyc7XG5pbXBvcnQgeyBnZXRMb25nQ2xhaW1JZCwgZ2V0U2hvcnRJZCwgZ2V0Q2xhaW1EYXRhIH0gZnJvbSAnYXBpL2Fzc2V0QXBpJztcbmltcG9ydCB7IHNlbGVjdFNob3dTdGF0ZSB9IGZyb20gJ3NlbGVjdG9ycy9zaG93JztcbmltcG9ydCB7IHNlbGVjdFNpdGVIb3N0IH0gZnJvbSAnc2VsZWN0b3JzL3NpdGUnO1xuXG5leHBvcnQgZnVuY3Rpb24gKiBuZXdBc3NldFJlcXVlc3QgKGFjdGlvbikge1xuICBjb25zdCB7IHJlcXVlc3RUeXBlLCByZXF1ZXN0SWQsIG5hbWUsIG1vZGlmaWVyIH0gPSBhY3Rpb24uZGF0YTtcbiAgLy8gcHV0IGFuIGFjdGlvbiB0byB1cGRhdGUgdGhlIHJlcXVlc3QgaW4gcmVkdXhcbiAgeWllbGQgcHV0KG9uUmVxdWVzdFVwZGF0ZShyZXF1ZXN0VHlwZSwgcmVxdWVzdElkKSk7XG4gIC8vIGlzIHRoaXMgYW4gZXhpc3RpbmcgcmVxdWVzdD9cbiAgLy8gSWYgdGhpcyB1cmkgaXMgaW4gdGhlIHJlcXVlc3QgbGlzdCwgaXQncyBhbHJlYWR5IGJlZW4gZmV0Y2hlZFxuICBjb25zdCBzdGF0ZSA9IHlpZWxkIHNlbGVjdChzZWxlY3RTaG93U3RhdGUpO1xuICBjb25zdCBob3N0ID0geWllbGQgc2VsZWN0KHNlbGVjdFNpdGVIb3N0KTtcbiAgaWYgKHN0YXRlLnJlcXVlc3RMaXN0W3JlcXVlc3RJZF0pIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuICAvLyBnZXQgbG9uZyBpZCAmJiBhZGQgcmVxdWVzdCB0byByZXF1ZXN0IGxpc3RcbiAgbGV0IGxvbmdJZDtcbiAgdHJ5IHtcbiAgICAoe2RhdGE6IGxvbmdJZH0gPSB5aWVsZCBjYWxsKGdldExvbmdDbGFpbUlkLCBob3N0LCBuYW1lLCBtb2RpZmllcikpO1xuICB9IGNhdGNoIChlcnJvcikge1xuICAgIHJldHVybiB5aWVsZCBwdXQob25SZXF1ZXN0RXJyb3IoZXJyb3IubWVzc2FnZSkpO1xuICB9XG4gIGNvbnN0IGFzc2V0S2V5ID0gYGEjJHtuYW1lfSMke2xvbmdJZH1gO1xuICB5aWVsZCBwdXQoYWRkUmVxdWVzdFRvUmVxdWVzdExpc3QocmVxdWVzdElkLCBudWxsLCBhc3NldEtleSkpO1xuICAvLyBpcyB0aGlzIGFuIGV4aXN0aW5nIGFzc2V0P1xuICAvLyBJZiB0aGlzIGFzc2V0IGlzIGluIHRoZSBhc3NldCBsaXN0LCBpdCdzIGFscmVhZHkgYmVlbiBmZXRjaGVkXG4gIGlmIChzdGF0ZS5hc3NldExpc3RbYXNzZXRLZXldKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cbiAgLy8gZ2V0IHNob3J0IElkXG4gIGxldCBzaG9ydElkO1xuICB0cnkge1xuICAgICh7ZGF0YTogc2hvcnRJZH0gPSB5aWVsZCBjYWxsKGdldFNob3J0SWQsIGhvc3QsIG5hbWUsIGxvbmdJZCkpO1xuICB9IGNhdGNoIChlcnJvcikge1xuICAgIHJldHVybiB5aWVsZCBwdXQob25SZXF1ZXN0RXJyb3IoZXJyb3IubWVzc2FnZSkpO1xuICB9XG4gIC8vIGdldCBhc3NldCBjbGFpbSBkYXRhXG4gIGxldCBjbGFpbURhdGE7XG4gIHRyeSB7XG4gICAgKHtkYXRhOiBjbGFpbURhdGF9ID0geWllbGQgY2FsbChnZXRDbGFpbURhdGEsIGhvc3QsIG5hbWUsIGxvbmdJZCkpO1xuICB9IGNhdGNoIChlcnJvcikge1xuICAgIHJldHVybiB5aWVsZCBwdXQob25SZXF1ZXN0RXJyb3IoZXJyb3IubWVzc2FnZSkpO1xuICB9XG4gIC8vIGFkZCBhc3NldCB0byBhc3NldCBsaXN0XG4gIHlpZWxkIHB1dChhZGRBc3NldFRvQXNzZXRMaXN0KGFzc2V0S2V5LCBudWxsLCBuYW1lLCBsb25nSWQsIHNob3J0SWQsIGNsYWltRGF0YSkpO1xuICAvLyBjbGVhciBhbnkgZXJyb3JzIGluIHJlcXVlc3QgZXJyb3JcbiAgeWllbGQgcHV0KG9uUmVxdWVzdEVycm9yKG51bGwpKTtcbn07XG5cbmV4cG9ydCBmdW5jdGlvbiAqIHdhdGNoTmV3QXNzZXRSZXF1ZXN0ICgpIHtcbiAgeWllbGQgdGFrZUxhdGVzdChhY3Rpb25zLkFTU0VUX1JFUVVFU1RfTkVXLCBuZXdBc3NldFJlcXVlc3QpO1xufTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL2NsaWVudC9zYWdhcy9zaG93X2Fzc2V0LmpzIiwiaW1wb3J0IHtjYWxsLCBwdXQsIHNlbGVjdCwgdGFrZUxhdGVzdH0gZnJvbSAncmVkdXgtc2FnYS9lZmZlY3RzJztcbmltcG9ydCAqIGFzIGFjdGlvbnMgZnJvbSAnY29uc3RhbnRzL3Nob3dfYWN0aW9uX3R5cGVzJztcbmltcG9ydCB7IGFkZE5ld0NoYW5uZWxUb0NoYW5uZWxMaXN0LCBhZGRSZXF1ZXN0VG9SZXF1ZXN0TGlzdCwgb25SZXF1ZXN0RXJyb3IsIG9uUmVxdWVzdFVwZGF0ZSwgdXBkYXRlQ2hhbm5lbENsYWltcyB9IGZyb20gJ2FjdGlvbnMvc2hvdyc7XG5pbXBvcnQgeyBnZXRDaGFubmVsQ2xhaW1zLCBnZXRDaGFubmVsRGF0YSB9IGZyb20gJ2FwaS9jaGFubmVsQXBpJztcbmltcG9ydCB7IHNlbGVjdFNob3dTdGF0ZSB9IGZyb20gJ3NlbGVjdG9ycy9zaG93JztcbmltcG9ydCB7IHNlbGVjdFNpdGVIb3N0IH0gZnJvbSAnc2VsZWN0b3JzL3NpdGUnO1xuXG5leHBvcnQgZnVuY3Rpb24gKiBuZXdDaGFubmVsUmVxdWVzdCAoYWN0aW9uKSB7XG4gIGNvbnN0IHsgcmVxdWVzdFR5cGUsIHJlcXVlc3RJZCwgY2hhbm5lbE5hbWUsIGNoYW5uZWxJZCB9ID0gYWN0aW9uLmRhdGE7XG4gIC8vIHB1dCBhbiBhY3Rpb24gdG8gdXBkYXRlIHRoZSByZXF1ZXN0IGluIHJlZHV4XG4gIHlpZWxkIHB1dChvblJlcXVlc3RVcGRhdGUocmVxdWVzdFR5cGUsIHJlcXVlc3RJZCkpO1xuICAvLyBpcyB0aGlzIGFuIGV4aXN0aW5nIHJlcXVlc3Q/XG4gIC8vIElmIHRoaXMgdXJpIGlzIGluIHRoZSByZXF1ZXN0IGxpc3QsIGl0J3MgYWxyZWFkeSBiZWVuIGZldGNoZWRcbiAgY29uc3Qgc3RhdGUgPSB5aWVsZCBzZWxlY3Qoc2VsZWN0U2hvd1N0YXRlKTtcbiAgY29uc3QgaG9zdCA9IHlpZWxkIHNlbGVjdChzZWxlY3RTaXRlSG9zdCk7XG4gIGlmIChzdGF0ZS5yZXF1ZXN0TGlzdFtyZXF1ZXN0SWRdKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cbiAgLy8gZ2V0IGNoYW5uZWwgbG9uZyBpZFxuICBsZXQgbG9uZ0lkLCBzaG9ydElkO1xuICB0cnkge1xuICAgICh7IGRhdGE6IHtsb25nQ2hhbm5lbENsYWltSWQ6IGxvbmdJZCwgc2hvcnRDaGFubmVsQ2xhaW1JZDogc2hvcnRJZH0gfSA9IHlpZWxkIGNhbGwoZ2V0Q2hhbm5lbERhdGEsIGhvc3QsIGNoYW5uZWxOYW1lLCBjaGFubmVsSWQpKTtcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICByZXR1cm4geWllbGQgcHV0KG9uUmVxdWVzdEVycm9yKGVycm9yLm1lc3NhZ2UpKTtcbiAgfVxuICAvLyBzdG9yZSB0aGUgcmVxdWVzdCBpbiB0aGUgY2hhbm5lbCByZXF1ZXN0cyBsaXN0XG4gIGNvbnN0IGNoYW5uZWxLZXkgPSBgYyMke2NoYW5uZWxOYW1lfSMke2xvbmdJZH1gO1xuICB5aWVsZCBwdXQoYWRkUmVxdWVzdFRvUmVxdWVzdExpc3QocmVxdWVzdElkLCBudWxsLCBjaGFubmVsS2V5KSk7XG4gIC8vIGlzIHRoaXMgYW4gZXhpc3RpbmcgY2hhbm5lbD9cbiAgLy8gSWYgdGhpcyBjaGFubmVsIGlzIGluIHRoZSBjaGFubmVsIGxpc3QsIGl0J3MgYWxyZWFkeSBiZWVuIGZldGNoZWRcbiAgaWYgKHN0YXRlLmNoYW5uZWxMaXN0W2NoYW5uZWxLZXldKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cbiAgLy8gZ2V0IGNoYW5uZWwgY2xhaW1zIGRhdGFcbiAgbGV0IGNsYWltc0RhdGE7XG4gIHRyeSB7XG4gICAgKHsgZGF0YTogY2xhaW1zRGF0YSB9ID0geWllbGQgY2FsbChnZXRDaGFubmVsQ2xhaW1zLCBob3N0LCBsb25nSWQsIGNoYW5uZWxOYW1lLCAxKSk7XG4gIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgcmV0dXJuIHlpZWxkIHB1dChvblJlcXVlc3RFcnJvcihlcnJvci5tZXNzYWdlKSk7XG4gIH1cbiAgLy8gc3RvcmUgdGhlIGNoYW5uZWwgZGF0YSBpbiB0aGUgY2hhbm5lbCBsaXN0XG4gIHlpZWxkIHB1dChhZGROZXdDaGFubmVsVG9DaGFubmVsTGlzdChjaGFubmVsS2V5LCBjaGFubmVsTmFtZSwgc2hvcnRJZCwgbG9uZ0lkLCBjbGFpbXNEYXRhKSk7XG4gIC8vIGNsZWFyIGFueSByZXF1ZXN0IGVycm9yc1xuICB5aWVsZCBwdXQob25SZXF1ZXN0RXJyb3IobnVsbCkpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gKiB3YXRjaE5ld0NoYW5uZWxSZXF1ZXN0ICgpIHtcbiAgeWllbGQgdGFrZUxhdGVzdChhY3Rpb25zLkNIQU5ORUxfUkVRVUVTVF9ORVcsIG5ld0NoYW5uZWxSZXF1ZXN0KTtcbn07XG5cbmZ1bmN0aW9uICogZ2V0TmV3Q2xhaW1zQW5kVXBkYXRlQ2hhbm5lbCAoYWN0aW9uKSB7XG4gIGNvbnN0IHsgY2hhbm5lbEtleSwgbmFtZSwgbG9uZ0lkLCBwYWdlIH0gPSBhY3Rpb24uZGF0YTtcbiAgY29uc3QgaG9zdCA9IHlpZWxkIHNlbGVjdChzZWxlY3RTaXRlSG9zdCk7XG4gIGxldCBjbGFpbXNEYXRhO1xuICB0cnkge1xuICAgICh7IGRhdGE6IGNsYWltc0RhdGEgfSA9IHlpZWxkIGNhbGwoZ2V0Q2hhbm5lbENsYWltcywgaG9zdCwgbG9uZ0lkLCBuYW1lLCBwYWdlKSk7XG4gIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgcmV0dXJuIHlpZWxkIHB1dChvblJlcXVlc3RFcnJvcihlcnJvci5tZXNzYWdlKSk7XG4gIH1cbiAgeWllbGQgcHV0KHVwZGF0ZUNoYW5uZWxDbGFpbXMoY2hhbm5lbEtleSwgY2xhaW1zRGF0YSkpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gKiB3YXRjaFVwZGF0ZUNoYW5uZWxDbGFpbXMgKCkge1xuICB5aWVsZCB0YWtlTGF0ZXN0KGFjdGlvbnMuQ0hBTk5FTF9DTEFJTVNfVVBEQVRFX0FTWU5DLCBnZXROZXdDbGFpbXNBbmRVcGRhdGVDaGFubmVsKTtcbn1cblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL2NsaWVudC9zYWdhcy9zaG93X2NoYW5uZWwuanMiLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCJyZWR1eC1zYWdhXCIpO1xuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIGV4dGVybmFsIFwicmVkdXgtc2FnYVwiXG4vLyBtb2R1bGUgaWQgPSA0MlxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJpbXBvcnQgUmVhY3QgZnJvbSAncmVhY3QnO1xuaW1wb3J0IEdvb2dsZUFuYWx5dGljcyBmcm9tICdyZWFjdC1nYSc7XG5pbXBvcnQgeyB3aXRoUm91dGVyIH0gZnJvbSAncmVhY3Qtcm91dGVyLWRvbSc7XG5jb25zdCB7IGFuYWx5dGljczogeyBnb29nbGVJZCB9IH0gPSByZXF1aXJlKCcuLi8uLi8uLi9jb25maWcvc2l0ZUNvbmZpZy5qcycpO1xuXG5Hb29nbGVBbmFseXRpY3MuaW5pdGlhbGl6ZShnb29nbGVJZCk7XG5cbmNsYXNzIEdBTGlzdGVuZXIgZXh0ZW5kcyBSZWFjdC5Db21wb25lbnQge1xuICBjb21wb25lbnREaWRNb3VudCAoKSB7XG4gICAgdGhpcy5zZW5kUGFnZVZpZXcodGhpcy5wcm9wcy5oaXN0b3J5LmxvY2F0aW9uKTtcbiAgICB0aGlzLnByb3BzLmhpc3RvcnkubGlzdGVuKHRoaXMuc2VuZFBhZ2VWaWV3KTtcbiAgfVxuXG4gIHNlbmRQYWdlVmlldyAobG9jYXRpb24pIHtcbiAgICBHb29nbGVBbmFseXRpY3Muc2V0KHsgcGFnZTogbG9jYXRpb24ucGF0aG5hbWUgfSk7XG4gICAgR29vZ2xlQW5hbHl0aWNzLnBhZ2V2aWV3KGxvY2F0aW9uLnBhdGhuYW1lKTtcbiAgfVxuXG4gIHJlbmRlciAoKSB7XG4gICAgcmV0dXJuIHRoaXMucHJvcHMuY2hpbGRyZW47XG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgd2l0aFJvdXRlcihHQUxpc3RlbmVyKTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL2NsaWVudC9jb21wb25lbnRzL0dBTGlzdGVuZXIvaW5kZXguanN4IiwiY29uc3QgbG9nZ2VyID0gcmVxdWlyZSgnd2luc3RvbicpO1xuY29uc3QgeyBnZXRDbGFpbUlkLCBnZXRMb2NhbEZpbGVSZWNvcmQgfSA9IHJlcXVpcmUoJy4uL2NvbnRyb2xsZXJzL3NlcnZlQ29udHJvbGxlci5qcycpO1xuY29uc3QgeyBoYW5kbGVFcnJvclJlc3BvbnNlIH0gPSByZXF1aXJlKCcuL2Vycm9ySGFuZGxlcnMuanMnKTtcblxuY29uc3QgU0VSVkUgPSAnU0VSVkUnO1xuY29uc3QgU0hPVyA9ICdTSE9XJztcbmNvbnN0IE5PX0ZJTEUgPSAnTk9fRklMRSc7XG5jb25zdCBOT19DSEFOTkVMID0gJ05PX0NIQU5ORUwnO1xuY29uc3QgTk9fQ0xBSU0gPSAnTk9fQ0xBSU0nO1xuXG5mdW5jdGlvbiBjbGllbnRBY2NlcHRzSHRtbCAoe2FjY2VwdH0pIHtcbiAgcmV0dXJuIGFjY2VwdCAmJiBhY2NlcHQubWF0Y2goL3RleHRcXC9odG1sLyk7XG59O1xuXG5mdW5jdGlvbiByZXF1ZXN0SXNGcm9tQnJvd3NlciAoaGVhZGVycykge1xuICByZXR1cm4gaGVhZGVyc1sndXNlci1hZ2VudCddICYmIGhlYWRlcnNbJ3VzZXItYWdlbnQnXS5tYXRjaCgvTW96aWxsYS8pO1xufTtcblxuZnVuY3Rpb24gY2xpZW50V2FudHNBc3NldCAoe2FjY2VwdCwgcmFuZ2V9KSB7XG4gIGNvbnN0IGltYWdlSXNXYW50ZWQgPSBhY2NlcHQgJiYgYWNjZXB0Lm1hdGNoKC9pbWFnZVxcLy4qLykgJiYgIWFjY2VwdC5tYXRjaCgvdGV4dFxcL2h0bWwvKSAmJiAhYWNjZXB0Lm1hdGNoKC90ZXh0XFwvXFwqLyk7XG4gIGNvbnN0IHZpZGVvSXNXYW50ZWQgPSBhY2NlcHQgJiYgcmFuZ2U7XG4gIHJldHVybiBpbWFnZUlzV2FudGVkIHx8IHZpZGVvSXNXYW50ZWQ7XG59O1xuXG5mdW5jdGlvbiBpc1ZhbGlkQ2xhaW1JZCAoY2xhaW1JZCkge1xuICByZXR1cm4gKChjbGFpbUlkLmxlbmd0aCA9PT0gNDApICYmICEvW15BLVphLXowLTldL2cudGVzdChjbGFpbUlkKSk7XG59O1xuXG5mdW5jdGlvbiBpc1ZhbGlkU2hvcnRJZCAoY2xhaW1JZCkge1xuICByZXR1cm4gY2xhaW1JZC5sZW5ndGggPT09IDE7ICAvLyBpdCBzaG91bGQgcmVhbGx5IGV2YWx1YXRlIHRoZSBzaG9ydCB1cmwgaXRzZWxmXG59O1xuXG5mdW5jdGlvbiBpc1ZhbGlkU2hvcnRJZE9yQ2xhaW1JZCAoaW5wdXQpIHtcbiAgcmV0dXJuIChpc1ZhbGlkQ2xhaW1JZChpbnB1dCkgfHwgaXNWYWxpZFNob3J0SWQoaW5wdXQpKTtcbn07XG5cbmZ1bmN0aW9uIHNlcnZlQXNzZXRUb0NsaWVudCAoY2xhaW1JZCwgbmFtZSwgcmVzKSB7XG4gIHJldHVybiBnZXRMb2NhbEZpbGVSZWNvcmQoY2xhaW1JZCwgbmFtZSlcbiAgICAudGhlbihmaWxlUmVjb3JkID0+IHtcbiAgICAgIC8vIGNoZWNrIHRoYXQgYSBsb2NhbCByZWNvcmQgd2FzIGZvdW5kXG4gICAgICBpZiAoZmlsZVJlY29yZCA9PT0gTk9fRklMRSkge1xuICAgICAgICByZXR1cm4gcmVzLnN0YXR1cygzMDcpLnJlZGlyZWN0KGAvYXBpL2NsYWltL2dldC8ke25hbWV9LyR7Y2xhaW1JZH1gKTtcbiAgICAgIH1cbiAgICAgIC8vIHNlcnZlIHRoZSBmaWxlXG4gICAgICBjb25zdCB7ZmlsZVBhdGgsIGZpbGVUeXBlfSA9IGZpbGVSZWNvcmQ7XG4gICAgICBsb2dnZXIudmVyYm9zZShgc2VydmluZyBmaWxlOiAke2ZpbGVQYXRofWApO1xuICAgICAgY29uc3Qgc2VuZEZpbGVPcHRpb25zID0ge1xuICAgICAgICBoZWFkZXJzOiB7XG4gICAgICAgICAgJ1gtQ29udGVudC1UeXBlLU9wdGlvbnMnOiAnbm9zbmlmZicsXG4gICAgICAgICAgJ0NvbnRlbnQtVHlwZScgICAgICAgICAgOiBmaWxlVHlwZSB8fCAnaW1hZ2UvanBlZycsXG4gICAgICAgIH0sXG4gICAgICB9O1xuICAgICAgcmVzLnN0YXR1cygyMDApLnNlbmRGaWxlKGZpbGVQYXRoLCBzZW5kRmlsZU9wdGlvbnMpO1xuICAgIH0pXG4gICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgIHRocm93IGVycm9yO1xuICAgIH0pO1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIGdldENsYWltSWRBbmRTZXJ2ZUFzc2V0IChjaGFubmVsTmFtZSwgY2hhbm5lbENsYWltSWQsIGNsYWltTmFtZSwgY2xhaW1JZCwgb3JpZ2luYWxVcmwsIGlwLCByZXMpIHtcbiAgICAvLyBnZXQgdGhlIGNsYWltIElkIGFuZCB0aGVuIHNlcnZlIHRoZSBhc3NldFxuICAgIGdldENsYWltSWQoY2hhbm5lbE5hbWUsIGNoYW5uZWxDbGFpbUlkLCBjbGFpbU5hbWUsIGNsYWltSWQpXG4gICAgICAudGhlbihmdWxsQ2xhaW1JZCA9PiB7XG4gICAgICAgIGlmIChmdWxsQ2xhaW1JZCA9PT0gTk9fQ0xBSU0pIHtcbiAgICAgICAgICByZXR1cm4gcmVzLnN0YXR1cyg0MDQpLmpzb24oe3N1Y2Nlc3M6IGZhbHNlLCBtZXNzYWdlOiAnbm8gY2xhaW0gaWQgY291bGQgYmUgZm91bmQnfSk7XG4gICAgICAgIH0gZWxzZSBpZiAoZnVsbENsYWltSWQgPT09IE5PX0NIQU5ORUwpIHtcbiAgICAgICAgICByZXR1cm4gcmVzLnN0YXR1cyg0MDQpLmpzb24oe3N1Y2Nlc3M6IGZhbHNlLCBtZXNzYWdlOiAnbm8gY2hhbm5lbCBpZCBjb3VsZCBiZSBmb3VuZCd9KTtcbiAgICAgICAgfVxuICAgICAgICBzZXJ2ZUFzc2V0VG9DbGllbnQoZnVsbENsYWltSWQsIGNsYWltTmFtZSwgcmVzKTtcbiAgICAgICAgLy8gcG9zdFRvU3RhdHMocmVzcG9uc2VUeXBlLCBvcmlnaW5hbFVybCwgaXAsIGNsYWltTmFtZSwgZnVsbENsYWltSWQsICdzdWNjZXNzJyk7XG4gICAgICB9KVxuICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgaGFuZGxlRXJyb3JSZXNwb25zZShvcmlnaW5hbFVybCwgaXAsIGVycm9yLCByZXMpO1xuICAgICAgICAvLyBwb3N0VG9TdGF0cyhyZXNwb25zZVR5cGUsIG9yaWdpbmFsVXJsLCBpcCwgY2xhaW1OYW1lLCBmdWxsQ2xhaW1JZCwgJ2ZhaWwnKTtcbiAgICAgIH0pO1xuICB9LFxuICBkZXRlcm1pbmVSZXNwb25zZVR5cGUgKGhhc0ZpbGVFeHRlbnNpb24sIGhlYWRlcnMpIHtcbiAgICBsZXQgcmVzcG9uc2VUeXBlO1xuICAgIGlmIChoYXNGaWxlRXh0ZW5zaW9uKSB7XG4gICAgICByZXNwb25zZVR5cGUgPSBTRVJWRTsgIC8vIGFzc3VtZSBhIHNlcnZlIHJlcXVlc3QgaWYgZmlsZSBleHRlbnNpb24gaXMgcHJlc2VudFxuICAgICAgaWYgKGNsaWVudEFjY2VwdHNIdG1sKGhlYWRlcnMpKSB7ICAvLyBpZiB0aGUgcmVxdWVzdCBjb21lcyBmcm9tIGEgYnJvd3NlciwgY2hhbmdlIGl0IHRvIGEgc2hvdyByZXF1ZXN0XG4gICAgICAgIHJlc3BvbnNlVHlwZSA9IFNIT1c7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHJlc3BvbnNlVHlwZSA9IFNIT1c7XG4gICAgICBpZiAoY2xpZW50V2FudHNBc3NldChoZWFkZXJzKSAmJiByZXF1ZXN0SXNGcm9tQnJvd3NlcihoZWFkZXJzKSkgeyAgLy8gdGhpcyBpcyBpbiBjYXNlIHNvbWVvbmUgZW1iZWRzIGEgc2hvdyB1cmxcbiAgICAgICAgbG9nZ2VyLmRlYnVnKCdTaG93IHJlcXVlc3QgY2FtZSBmcm9tIGJyb3dzZXIgYnV0IHdhbnRzIGFuIGltYWdlL3ZpZGVvLiBDaGFuZ2luZyByZXNwb25zZSB0byBzZXJ2ZS4uLicpO1xuICAgICAgICByZXNwb25zZVR5cGUgPSBTRVJWRTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHJlc3BvbnNlVHlwZTtcbiAgfSxcbiAgZmxpcENsYWltTmFtZUFuZElkRm9yQmFja3dhcmRzQ29tcGF0aWJpbGl0eSAoaWRlbnRpZmllciwgbmFtZSkge1xuICAgIC8vIHRoaXMgaXMgYSBwYXRjaCBmb3IgYmFja3dhcmRzIGNvbXBhdGFiaWxpdHkgd2l0aCAnL25hbWUvY2xhaW1faWQnIHVybCBmb3JtYXRcbiAgICBpZiAoaXNWYWxpZFNob3J0SWRPckNsYWltSWQobmFtZSkgJiYgIWlzVmFsaWRTaG9ydElkT3JDbGFpbUlkKGlkZW50aWZpZXIpKSB7XG4gICAgICBjb25zdCB0ZW1wTmFtZSA9IG5hbWU7XG4gICAgICBuYW1lID0gaWRlbnRpZmllcjtcbiAgICAgIGlkZW50aWZpZXIgPSB0ZW1wTmFtZTtcbiAgICB9XG4gICAgcmV0dXJuIFtpZGVudGlmaWVyLCBuYW1lXTtcbiAgfSxcbiAgbG9nUmVxdWVzdERhdGEgKHJlc3BvbnNlVHlwZSwgY2xhaW1OYW1lLCBjaGFubmVsTmFtZSwgY2xhaW1JZCkge1xuICAgIGxvZ2dlci5kZWJ1ZygncmVzcG9uc2VUeXBlID09PScsIHJlc3BvbnNlVHlwZSk7XG4gICAgbG9nZ2VyLmRlYnVnKCdjbGFpbSBuYW1lID09PSAnLCBjbGFpbU5hbWUpO1xuICAgIGxvZ2dlci5kZWJ1ZygnY2hhbm5lbCBuYW1lID09PScsIGNoYW5uZWxOYW1lKTtcbiAgICBsb2dnZXIuZGVidWcoJ2NsYWltIGlkID09PScsIGNsYWltSWQpO1xuICB9LFxufTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL3NlcnZlci9oZWxwZXJzL3NlcnZlSGVscGVycy5qcyIsImNvbnN0IGxvZ2dlciA9IHJlcXVpcmUoJ3dpbnN0b24nKTtcblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIFJFR0VYUF9JTlZBTElEX0NMQUlNICA6IC9bXkEtWmEtejAtOS1dL2csXG4gIFJFR0VYUF9JTlZBTElEX0NIQU5ORUw6IC9bXkEtWmEtejAtOS1AXS9nLFxuICBSRUdFWFBfQUREUkVTUyAgICAgICAgOiAvXmIoPz1bXjBPSWxdezMyLDMzfSlbMC05QS1aYS16XXszMiwzM30kLyxcbiAgQ0hBTk5FTF9DSEFSICAgICAgICAgIDogJ0AnLFxuICBwYXJzZUlkZW50aWZpZXIgICAgICAgOiBmdW5jdGlvbiAoaWRlbnRpZmllcikge1xuICAgIGxvZ2dlci5kZWJ1ZygncGFyc2luZyBpZGVudGlmaWVyOicsIGlkZW50aWZpZXIpO1xuICAgIGNvbnN0IGNvbXBvbmVudHNSZWdleCA9IG5ldyBSZWdFeHAoXG4gICAgICAnKFteOiQjL10qKScgKyAvLyB2YWx1ZSAoc3RvcHMgYXQgdGhlIGZpcnN0IHNlcGFyYXRvciBvciBlbmQpXG4gICAgICAnKFs6JCNdPykoW14vXSopJyAvLyBtb2RpZmllciBzZXBhcmF0b3IsIG1vZGlmaWVyIChzdG9wcyBhdCB0aGUgZmlyc3QgcGF0aCBzZXBhcmF0b3Igb3IgZW5kKVxuICAgICk7XG4gICAgY29uc3QgW3Byb3RvLCB2YWx1ZSwgbW9kaWZpZXJTZXBlcmF0b3IsIG1vZGlmaWVyXSA9IGNvbXBvbmVudHNSZWdleFxuICAgICAgLmV4ZWMoaWRlbnRpZmllcilcbiAgICAgIC5tYXAobWF0Y2ggPT4gbWF0Y2ggfHwgbnVsbCk7XG4gICAgbG9nZ2VyLmRlYnVnKGAke3Byb3RvfSwgJHt2YWx1ZX0sICR7bW9kaWZpZXJTZXBlcmF0b3J9LCAke21vZGlmaWVyfWApO1xuXG4gICAgLy8gVmFsaWRhdGUgYW5kIHByb2Nlc3MgbmFtZVxuICAgIGlmICghdmFsdWUpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgQ2hlY2sgeW91ciB1cmwuICBObyBjaGFubmVsIG5hbWUgcHJvdmlkZWQgYmVmb3JlIFwiJHttb2RpZmllclNlcGVyYXRvcn1cImApO1xuICAgIH1cbiAgICBjb25zdCBpc0NoYW5uZWwgPSB2YWx1ZS5zdGFydHNXaXRoKG1vZHVsZS5leHBvcnRzLkNIQU5ORUxfQ0hBUik7XG4gICAgY29uc3QgY2hhbm5lbE5hbWUgPSBpc0NoYW5uZWwgPyB2YWx1ZSA6IG51bGw7XG4gICAgbGV0IGNsYWltSWQ7XG4gICAgaWYgKGlzQ2hhbm5lbCkge1xuICAgICAgaWYgKCFjaGFubmVsTmFtZSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ05vIGNoYW5uZWwgbmFtZSBhZnRlciBALicpO1xuICAgICAgfVxuICAgICAgY29uc3QgbmFtZUJhZENoYXJzID0gKGNoYW5uZWxOYW1lKS5tYXRjaChtb2R1bGUuZXhwb3J0cy5SRUdFWFBfSU5WQUxJRF9DSEFOTkVMKTtcbiAgICAgIGlmIChuYW1lQmFkQ2hhcnMpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBJbnZhbGlkIGNoYXJhY3RlcnMgaW4gY2hhbm5lbCBuYW1lOiAke25hbWVCYWRDaGFycy5qb2luKCcsICcpfS5gKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgY2xhaW1JZCA9IHZhbHVlO1xuICAgIH1cblxuICAgIC8vIFZhbGlkYXRlIGFuZCBwcm9jZXNzIG1vZGlmaWVyXG4gICAgbGV0IGNoYW5uZWxDbGFpbUlkO1xuICAgIGlmIChtb2RpZmllclNlcGVyYXRvcikge1xuICAgICAgaWYgKCFtb2RpZmllcikge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYE5vIG1vZGlmaWVyIHByb3ZpZGVkIGFmdGVyIHNlcGFyYXRvciBcIiR7bW9kaWZpZXJTZXBlcmF0b3J9XCJgKTtcbiAgICAgIH1cblxuICAgICAgaWYgKG1vZGlmaWVyU2VwZXJhdG9yID09PSAnOicpIHtcbiAgICAgICAgY2hhbm5lbENsYWltSWQgPSBtb2RpZmllcjtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgVGhlIFwiJHttb2RpZmllclNlcGVyYXRvcn1cIiBtb2RpZmllciBpcyBub3QgY3VycmVudGx5IHN1cHBvcnRlZGApO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4ge1xuICAgICAgaXNDaGFubmVsLFxuICAgICAgY2hhbm5lbE5hbWUsXG4gICAgICBjaGFubmVsQ2xhaW1JZCxcbiAgICAgIGNsYWltSWQsXG4gICAgfTtcbiAgfSxcbiAgcGFyc2VDbGFpbTogZnVuY3Rpb24gKGNsYWltKSB7XG4gICAgbG9nZ2VyLmRlYnVnKCdwYXJzaW5nIG5hbWU6JywgY2xhaW0pO1xuICAgIGNvbnN0IGNvbXBvbmVudHNSZWdleCA9IG5ldyBSZWdFeHAoXG4gICAgICAnKFteOiQjLy5dKiknICsgLy8gbmFtZSAoc3RvcHMgYXQgdGhlIGZpcnN0IG1vZGlmaWVyKVxuICAgICAgJyhbOiQjLl0/KShbXi9dKiknIC8vIG1vZGlmaWVyIHNlcGFyYXRvciwgbW9kaWZpZXIgKHN0b3BzIGF0IHRoZSBmaXJzdCBwYXRoIHNlcGFyYXRvciBvciBlbmQpXG4gICAgKTtcbiAgICBjb25zdCBbcHJvdG8sIGNsYWltTmFtZSwgbW9kaWZpZXJTZXBlcmF0b3IsIG1vZGlmaWVyXSA9IGNvbXBvbmVudHNSZWdleFxuICAgICAgLmV4ZWMoY2xhaW0pXG4gICAgICAubWFwKG1hdGNoID0+IG1hdGNoIHx8IG51bGwpO1xuICAgIGxvZ2dlci5kZWJ1ZyhgJHtwcm90b30sICR7Y2xhaW1OYW1lfSwgJHttb2RpZmllclNlcGVyYXRvcn0sICR7bW9kaWZpZXJ9YCk7XG5cbiAgICAvLyBWYWxpZGF0ZSBhbmQgcHJvY2VzcyBuYW1lXG4gICAgaWYgKCFjbGFpbU5hbWUpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignTm8gY2xhaW0gbmFtZSBwcm92aWRlZCBiZWZvcmUgLicpO1xuICAgIH1cbiAgICBjb25zdCBuYW1lQmFkQ2hhcnMgPSAoY2xhaW1OYW1lKS5tYXRjaChtb2R1bGUuZXhwb3J0cy5SRUdFWFBfSU5WQUxJRF9DTEFJTSk7XG4gICAgaWYgKG5hbWVCYWRDaGFycykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBJbnZhbGlkIGNoYXJhY3RlcnMgaW4gY2xhaW0gbmFtZTogJHtuYW1lQmFkQ2hhcnMuam9pbignLCAnKX0uYCk7XG4gICAgfVxuICAgIC8vIFZhbGlkYXRlIGFuZCBwcm9jZXNzIG1vZGlmaWVyXG4gICAgaWYgKG1vZGlmaWVyU2VwZXJhdG9yKSB7XG4gICAgICBpZiAoIW1vZGlmaWVyKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgTm8gZmlsZSBleHRlbnNpb24gcHJvdmlkZWQgYWZ0ZXIgc2VwYXJhdG9yICR7bW9kaWZpZXJTZXBlcmF0b3J9LmApO1xuICAgICAgfVxuICAgICAgaWYgKG1vZGlmaWVyU2VwZXJhdG9yICE9PSAnLicpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBUaGUgJHttb2RpZmllclNlcGVyYXRvcn0gbW9kaWZpZXIgaXMgbm90IHN1cHBvcnRlZCBpbiB0aGUgY2xhaW0gbmFtZWApO1xuICAgICAgfVxuICAgIH1cbiAgICAvLyByZXR1cm4gcmVzdWx0c1xuICAgIHJldHVybiB7XG4gICAgICBjbGFpbU5hbWUsXG4gICAgfTtcbiAgfSxcbiAgcGFyc2VNb2RpZmllcjogZnVuY3Rpb24gKGNsYWltKSB7XG4gICAgbG9nZ2VyLmRlYnVnKCdwYXJzaW5nIG1vZGlmaWVyOicsIGNsYWltKTtcbiAgICBjb25zdCBjb21wb25lbnRzUmVnZXggPSBuZXcgUmVnRXhwKFxuICAgICAgJyhbXjokIy8uXSopJyArIC8vIG5hbWUgKHN0b3BzIGF0IHRoZSBmaXJzdCBtb2RpZmllcilcbiAgICAgICcoWzokIy5dPykoW14vXSopJyAvLyBtb2RpZmllciBzZXBhcmF0b3IsIG1vZGlmaWVyIChzdG9wcyBhdCB0aGUgZmlyc3QgcGF0aCBzZXBhcmF0b3Igb3IgZW5kKVxuICAgICk7XG4gICAgY29uc3QgW3Byb3RvLCBjbGFpbU5hbWUsIG1vZGlmaWVyU2VwZXJhdG9yLCBtb2RpZmllcl0gPSBjb21wb25lbnRzUmVnZXhcbiAgICAgIC5leGVjKGNsYWltKVxuICAgICAgLm1hcChtYXRjaCA9PiBtYXRjaCB8fCBudWxsKTtcbiAgICBsb2dnZXIuZGVidWcoYCR7cHJvdG99LCAke2NsYWltTmFtZX0sICR7bW9kaWZpZXJTZXBlcmF0b3J9LCAke21vZGlmaWVyfWApO1xuICAgIC8vIFZhbGlkYXRlIGFuZCBwcm9jZXNzIG1vZGlmaWVyXG4gICAgbGV0IGhhc0ZpbGVFeHRlbnNpb24gPSBmYWxzZTtcbiAgICBpZiAobW9kaWZpZXJTZXBlcmF0b3IpIHtcbiAgICAgIGhhc0ZpbGVFeHRlbnNpb24gPSB0cnVlO1xuICAgIH1cbiAgICByZXR1cm4ge1xuICAgICAgaGFzRmlsZUV4dGVuc2lvbixcbiAgICB9O1xuICB9LFxufTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL3NlcnZlci9oZWxwZXJzL2xicnlVcmkuanMiLCJpbXBvcnQgUmVhY3QgZnJvbSAncmVhY3QnO1xuaW1wb3J0IHsgcmVuZGVyVG9TdHJpbmcgfSBmcm9tICdyZWFjdC1kb20vc2VydmVyJztcbmltcG9ydCB7IGNyZWF0ZVN0b3JlLCBhcHBseU1pZGRsZXdhcmUgfSBmcm9tICdyZWR1eCc7XG5pbXBvcnQgUmVkdWNlciBmcm9tICcuLi8uLi9jbGllbnQvcmVkdWNlcnMvaW5kZXgnO1xuaW1wb3J0IHsgUHJvdmlkZXIgfSBmcm9tICdyZWFjdC1yZWR1eCc7XG5pbXBvcnQgeyBTdGF0aWNSb3V0ZXIgfSBmcm9tICdyZWFjdC1yb3V0ZXItZG9tJztcbmltcG9ydCBHQUxpc3RlbmVyIGZyb20gJy4uLy4uL2NsaWVudC9jb21wb25lbnRzL0dBTGlzdGVuZXIvaW5kZXgnO1xuaW1wb3J0IEFwcCBmcm9tICcuLi8uLi9jbGllbnQvYXBwJztcbmltcG9ydCByZW5kZXJGdWxsUGFnZSBmcm9tICcuL3JlbmRlckZ1bGxQYWdlJztcbmltcG9ydCBjcmVhdGVTYWdhTWlkZGxld2FyZSBmcm9tICdyZWR1eC1zYWdhJztcbmltcG9ydCB7IGNhbGwgfSBmcm9tICdyZWR1eC1zYWdhL2VmZmVjdHMnO1xuaW1wb3J0IHsgaGFuZGxlU2hvd1BhZ2VVcmkgfSBmcm9tICcuLi8uLi9jbGllbnQvc2FnYXMvc2hvd191cmknO1xuaW1wb3J0IHsgb25IYW5kbGVTaG93UGFnZVVyaSB9IGZyb20gJy4uLy4uL2NsaWVudC9hY3Rpb25zL3Nob3cnO1xuXG5pbXBvcnQgSGVsbWV0IGZyb20gJ3JlYWN0LWhlbG1ldCc7XG5cbmNvbnN0IHJldHVyblNhZ2FXaXRoUGFyYW1zID0gKHNhZ2EsIHBhcmFtcykgPT4ge1xuICByZXR1cm4gZnVuY3Rpb24gKiAoKSB7XG4gICAgeWllbGQgY2FsbChzYWdhLCBwYXJhbXMpO1xuICB9O1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSAocmVxLCByZXMpID0+IHtcbiAgbGV0IGNvbnRleHQgPSB7fTtcblxuICAvLyBjcmVhdGUgYW5kIGFwcGx5IG1pZGRsZXdhcmVcbiAgY29uc3Qgc2FnYU1pZGRsZXdhcmUgPSBjcmVhdGVTYWdhTWlkZGxld2FyZSgpO1xuICBjb25zdCBtaWRkbGV3YXJlID0gYXBwbHlNaWRkbGV3YXJlKHNhZ2FNaWRkbGV3YXJlKTtcblxuICAvLyBjcmVhdGUgYSBuZXcgUmVkdXggc3RvcmUgaW5zdGFuY2VcbiAgY29uc3Qgc3RvcmUgPSBjcmVhdGVTdG9yZShSZWR1Y2VyLCBtaWRkbGV3YXJlKTtcblxuICAvLyBjcmVhdGUgc2FnYVxuICBjb25zdCBhY3Rpb24gPSBvbkhhbmRsZVNob3dQYWdlVXJpKHJlcS5wYXJhbXMpO1xuICBjb25zdCBzYWdhID0gcmV0dXJuU2FnYVdpdGhQYXJhbXMoaGFuZGxlU2hvd1BhZ2VVcmksIGFjdGlvbik7XG5cbiAgLy8gcnVuIHRoZSBzYWdhIG1pZGRsZXdhcmVcbiAgc2FnYU1pZGRsZXdhcmVcbiAgICAucnVuKHNhZ2EpXG4gICAgLmRvbmVcbiAgICAudGhlbigoKSA9PiB7XG4gICAgICAvLyByZW5kZXIgY29tcG9uZW50IHRvIGEgc3RyaW5nXG4gICAgICBjb25zdCBodG1sID0gcmVuZGVyVG9TdHJpbmcoXG4gICAgICAgIDxQcm92aWRlciBzdG9yZT17c3RvcmV9PlxuICAgICAgICAgIDxTdGF0aWNSb3V0ZXIgbG9jYXRpb249e3JlcS51cmx9IGNvbnRleHQ9e2NvbnRleHR9PlxuICAgICAgICAgICAgPEdBTGlzdGVuZXI+XG4gICAgICAgICAgICAgIDxBcHAgLz5cbiAgICAgICAgICAgIDwvR0FMaXN0ZW5lcj5cbiAgICAgICAgICA8L1N0YXRpY1JvdXRlcj5cbiAgICAgICAgPC9Qcm92aWRlcj5cbiAgICAgICk7XG5cbiAgICAgIC8vIGdldCBoZWFkIHRhZ3MgZnJvbSBoZWxtZXRcbiAgICAgIGNvbnN0IGhlbG1ldCA9IEhlbG1ldC5yZW5kZXJTdGF0aWMoKTtcblxuICAgICAgLy8gY2hlY2sgZm9yIGEgcmVkaXJlY3RcbiAgICAgIGlmIChjb250ZXh0LnVybCkge1xuICAgICAgICByZXR1cm4gcmVzLnJlZGlyZWN0KDMwMSwgY29udGV4dC51cmwpO1xuICAgICAgfVxuXG4gICAgICAvLyBnZXQgdGhlIGluaXRpYWwgc3RhdGUgZnJvbSBvdXIgUmVkdXggc3RvcmVcbiAgICAgIGNvbnN0IHByZWxvYWRlZFN0YXRlID0gc3RvcmUuZ2V0U3RhdGUoKTtcblxuICAgICAgLy8gc2VuZCB0aGUgcmVuZGVyZWQgcGFnZSBiYWNrIHRvIHRoZSBjbGllbnRcbiAgICAgIHJlcy5zZW5kKHJlbmRlckZ1bGxQYWdlKGhlbG1ldCwgaHRtbCwgcHJlbG9hZGVkU3RhdGUpKTtcbiAgICB9KTtcbn07XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9zZXJ2ZXIvaGVscGVycy9oYW5kbGVTaG93UmVuZGVyLmpzeCIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcInBhc3Nwb3J0LWxvY2FsXCIpO1xuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIGV4dGVybmFsIFwicGFzc3BvcnQtbG9jYWxcIlxuLy8gbW9kdWxlIGlkID0gNDdcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwibW9kdWxlLmV4cG9ydHMgPSB7XG4gIHJldHVyblNob3J0SWQ6IGZ1bmN0aW9uIChjbGFpbXNBcnJheSwgbG9uZ0lkKSB7XG4gICAgbGV0IGNsYWltSW5kZXg7XG4gICAgbGV0IHNob3J0SWQgPSBsb25nSWQuc3Vic3RyaW5nKDAsIDEpOyAvLyBkZWZhdWx0IHNob3J0IGlkIGlzIHRoZSBmaXJzdCBsZXR0ZXJcbiAgICBsZXQgc2hvcnRJZExlbmd0aCA9IDA7XG4gICAgLy8gZmluZCB0aGUgaW5kZXggb2YgdGhpcyBjbGFpbSBpZFxuICAgIGNsYWltSW5kZXggPSBjbGFpbXNBcnJheS5maW5kSW5kZXgoZWxlbWVudCA9PiB7XG4gICAgICByZXR1cm4gZWxlbWVudC5jbGFpbUlkID09PSBsb25nSWQ7XG4gICAgfSk7XG4gICAgaWYgKGNsYWltSW5kZXggPCAwKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2NsYWltIGlkIG5vdCBmb3VuZCBpbiBjbGFpbXMgbGlzdCcpO1xuICAgIH1cbiAgICAvLyBnZXQgYW4gYXJyYXkgb2YgYWxsIGNsYWltcyB3aXRoIGxvd2VyIGhlaWdodFxuICAgIGxldCBwb3NzaWJsZU1hdGNoZXMgPSBjbGFpbXNBcnJheS5zbGljZSgwLCBjbGFpbUluZGV4KTtcbiAgICAvLyByZW1vdmUgY2VydGlmaWNhdGVzIHdpdGggdGhlIHNhbWUgcHJlZml4ZXMgdW50aWwgbm9uZSBhcmUgbGVmdC5cbiAgICB3aGlsZSAocG9zc2libGVNYXRjaGVzLmxlbmd0aCA+IDApIHtcbiAgICAgIHNob3J0SWRMZW5ndGggKz0gMTtcbiAgICAgIHNob3J0SWQgPSBsb25nSWQuc3Vic3RyaW5nKDAsIHNob3J0SWRMZW5ndGgpO1xuICAgICAgcG9zc2libGVNYXRjaGVzID0gcG9zc2libGVNYXRjaGVzLmZpbHRlcihlbGVtZW50ID0+IHtcbiAgICAgICAgcmV0dXJuIChlbGVtZW50LmNsYWltSWQgJiYgKGVsZW1lbnQuY2xhaW1JZC5zdWJzdHJpbmcoMCwgc2hvcnRJZExlbmd0aCkgPT09IHNob3J0SWQpKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgICByZXR1cm4gc2hvcnRJZDtcbiAgfSxcbn07XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9zZXJ2ZXIvaGVscGVycy9zZXF1ZWxpemVIZWxwZXJzLmpzIiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwiYmFiZWwtcG9seWZpbGxcIik7XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gZXh0ZXJuYWwgXCJiYWJlbC1wb2x5ZmlsbFwiXG4vLyBtb2R1bGUgaWQgPSA1MFxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCJ3aGF0d2ctZmV0Y2hcIik7XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gZXh0ZXJuYWwgXCJ3aGF0d2ctZmV0Y2hcIlxuLy8gbW9kdWxlIGlkID0gNTFcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiaW1wb3J0IEFwcCBmcm9tICdhcHAnO1xuaW1wb3J0IFJlZHVjZXIgZnJvbSAncmVkdWNlcnMnO1xuaW1wb3J0IHJvb3RTYWdhICBmcm9tICdzYWdhcyc7XG5pbXBvcnQgR0FMaXN0ZW5lciBmcm9tICdjb21wb25lbnRzL0dBTGlzdGVuZXInO1xuXG5jb25zdCBhcGkgPSByZXF1aXJlKCcuL3NlcnZlci9yb3V0ZXMvYXBpLycpO1xuY29uc3QgYXNzZXQgPSByZXF1aXJlKCcuL3NlcnZlci9yb3V0ZXMvYXNzZXQvJyk7XG5jb25zdCBhdXRoID0gcmVxdWlyZSgnLi9zZXJ2ZXIvcm91dGVzL2F1dGgvJyk7XG5jb25zdCBwYWdlID0gcmVxdWlyZSgnLi9zZXJ2ZXIvcm91dGVzL3BhZ2UvJyk7XG5jb25zdCBsb2dnZXIgPSByZXF1aXJlKCcuL2NvbmZpZy9sb2dnZXJDb25maWcuanMnKTtcbmNvbnN0IG15c3FsID0gcmVxdWlyZSgnLi9jb25maWcvbXlzcWxDb25maWcnKTtcbmNvbnN0IHNpdGUgPSByZXF1aXJlKCcuL2NvbmZpZy9zaXRlQ29uZmlnJyk7XG5jb25zdCBzbGFjayA9IHJlcXVpcmUoJy4vY29uZmlnL3NsYWNrQ29uZmlnLmpzJyk7XG5jb25zdCBwYXNzcG9ydCA9IHJlcXVpcmUoJy4vc2VydmVyL3Bhc3Nwb3J0LycpO1xuY29uc3QgbW9kZWxzID0gcmVxdWlyZSgnLi9zZXJ2ZXIvbW9kZWxzLycpO1xuXG5jb25zdCBleHBvcnRzID0ge1xuICBBcHAsXG4gIFJlZHVjZXIsXG4gIHJvb3RTYWdhLFxuICBHQUxpc3RlbmVyLFxuICBsb2dnZXIsXG4gIG1vZGVscyxcbiAgbXlzcWwsXG4gIHBhc3Nwb3J0LFxuICBzaXRlLFxuICBzbGFjayxcbiAgcm91dGVzOiB7XG4gICAgYXBpLFxuICAgIGFzc2V0LFxuICAgIGF1dGgsXG4gICAgcGFnZSxcbiAgfSxcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gZXhwb3J0cztcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL3NwZWVjaC5qcyIsImltcG9ydCBSZWFjdCBmcm9tICdyZWFjdCc7XG5pbXBvcnQgU0VPIGZyb20gJ2NvbXBvbmVudHMvU0VPJztcbmltcG9ydCBOYXZCYXIgZnJvbSAnY29udGFpbmVycy9OYXZCYXInO1xuaW1wb3J0IFB1Ymxpc2hUb29sIGZyb20gJ2NvbnRhaW5lcnMvUHVibGlzaFRvb2wnO1xuXG5jbGFzcyBIb21lUGFnZSBleHRlbmRzIFJlYWN0LkNvbXBvbmVudCB7XG4gIHJlbmRlciAoKSB7XG4gICAgcmV0dXJuIChcbiAgICAgIDxkaXYgY2xhc3NOYW1lPXsncm93IHJvdy0tdGFsbCBmbGV4LWNvbnRhaW5lci0tY29sdW1uJ30+XG4gICAgICAgIDxTRU8gLz5cbiAgICAgICAgPE5hdkJhciAvPlxuICAgICAgICA8ZGl2IGNsYXNzTmFtZT17J3JvdyByb3ctLXRhbGwgcm93LS1wYWRkZWQgZmxleC1jb250YWluZXItLWNvbHVtbid9PlxuICAgICAgICAgIDxQdWJsaXNoVG9vbCAvPlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuICAgICk7XG4gIH1cbn07XG5cbmV4cG9ydCBkZWZhdWx0IEhvbWVQYWdlO1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vY2xpZW50L3BhZ2VzL0hvbWVQYWdlL2luZGV4LmpzeCIsImltcG9ydCBSZWFjdCBmcm9tICdyZWFjdCc7XG5pbXBvcnQgSGVsbWV0IGZyb20gJ3JlYWN0LWhlbG1ldCc7XG5pbXBvcnQgUHJvcFR5cGVzIGZyb20gJ3Byb3AtdHlwZXMnO1xuXG5pbXBvcnQgeyBjcmVhdGVQYWdlVGl0bGUgfSBmcm9tICd1dGlscy9wYWdlVGl0bGUnO1xuaW1wb3J0IHsgY3JlYXRlTWV0YVRhZ3MgfSBmcm9tICd1dGlscy9tZXRhVGFncyc7XG5pbXBvcnQgeyBjcmVhdGVDYW5vbmljYWxMaW5rIH0gZnJvbSAndXRpbHMvY2Fub25pY2FsTGluayc7XG5cbmNsYXNzIFNFTyBleHRlbmRzIFJlYWN0LkNvbXBvbmVudCB7XG4gIHJlbmRlciAoKSB7XG4gICAgLy8gcHJvcHMgZnJvbSBzdGF0ZVxuICAgIGNvbnN0IHsgZGVmYXVsdERlc2NyaXB0aW9uLCBkZWZhdWx0VGh1bWJuYWlsLCBzaXRlRGVzY3JpcHRpb24sIHNpdGVIb3N0LCBzaXRlVGl0bGUsIHNpdGVUd2l0dGVyIH0gPSB0aGlzLnByb3BzO1xuICAgIC8vIHByb3BzIGZyb20gcGFyZW50XG4gICAgY29uc3QgeyBhc3NldCwgY2hhbm5lbCwgcGFnZVVyaSB9ID0gdGhpcy5wcm9wcztcbiAgICBsZXQgeyBwYWdlVGl0bGUgfSA9IHRoaXMucHJvcHM7XG4gICAgLy8gY3JlYXRlIHBhZ2UgdGl0bGUsIHRhZ3MsIGFuZCBjYW5vbmljYWwgbGlua1xuICAgIHBhZ2VUaXRsZSA9IGNyZWF0ZVBhZ2VUaXRsZShzaXRlVGl0bGUsIHBhZ2VUaXRsZSk7XG4gICAgY29uc3QgbWV0YVRhZ3MgPSBjcmVhdGVNZXRhVGFncyhzaXRlRGVzY3JpcHRpb24sIHNpdGVIb3N0LCBzaXRlVGl0bGUsIHNpdGVUd2l0dGVyLCBhc3NldCwgY2hhbm5lbCwgZGVmYXVsdERlc2NyaXB0aW9uLCBkZWZhdWx0VGh1bWJuYWlsKTtcbiAgICBjb25zdCBjYW5vbmljYWxMaW5rID0gY3JlYXRlQ2Fub25pY2FsTGluayhhc3NldCwgY2hhbm5lbCwgcGFnZVVyaSwgc2l0ZUhvc3QpO1xuICAgIC8vIHJlbmRlciByZXN1bHRzXG4gICAgcmV0dXJuIChcbiAgICAgIDxIZWxtZXRcbiAgICAgICAgdGl0bGU9e3BhZ2VUaXRsZX1cbiAgICAgICAgbWV0YT17bWV0YVRhZ3N9XG4gICAgICAgIGxpbms9e1t7cmVsOiAnY2Fub25pY2FsJywgaHJlZjogY2Fub25pY2FsTGlua31dfVxuICAgICAgLz5cbiAgICApO1xuICB9XG59O1xuXG5TRU8ucHJvcFR5cGVzID0ge1xuICBwYWdlVGl0bGU6IFByb3BUeXBlcy5zdHJpbmcsXG4gIHBhZ2VVcmkgIDogUHJvcFR5cGVzLnN0cmluZyxcbiAgY2hhbm5lbCAgOiBQcm9wVHlwZXMub2JqZWN0LFxuICBhc3NldCAgICA6IFByb3BUeXBlcy5vYmplY3QsXG59O1xuXG5leHBvcnQgZGVmYXVsdCBTRU87XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9jbGllbnQvY29tcG9uZW50cy9TRU8vdmlldy5qc3giLCJleHBvcnQgY29uc3QgY3JlYXRlUGFnZVRpdGxlID0gKHNpdGVUaXRsZSwgcGFnZVRpdGxlKSA9PiB7XG4gIGlmICghcGFnZVRpdGxlKSB7XG4gICAgcmV0dXJuIGAke3NpdGVUaXRsZX1gO1xuICB9XG4gIHJldHVybiBgJHtzaXRlVGl0bGV9IC0gJHtwYWdlVGl0bGV9YDtcbn07XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9jbGllbnQvdXRpbHMvcGFnZVRpdGxlLmpzIiwiY29uc3QgZGV0ZXJtaW5lT2dUaHVtYm5haWxDb250ZW50VHlwZSA9ICh0aHVtYm5haWwpID0+IHtcbiAgaWYgKHRodW1ibmFpbCkge1xuICAgIGNvbnN0IGZpbGVFeHQgPSB0aHVtYm5haWwuc3Vic3RyaW5nKHRodW1ibmFpbC5sYXN0SW5kZXhPZignLicpKTtcbiAgICBzd2l0Y2ggKGZpbGVFeHQpIHtcbiAgICAgIGNhc2UgJ2pwZWcnOlxuICAgICAgY2FzZSAnanBnJzpcbiAgICAgICAgcmV0dXJuICdpbWFnZS9qcGVnJztcbiAgICAgIGNhc2UgJ3BuZyc6XG4gICAgICAgIHJldHVybiAnaW1hZ2UvcG5nJztcbiAgICAgIGNhc2UgJ2dpZic6XG4gICAgICAgIHJldHVybiAnaW1hZ2UvZ2lmJztcbiAgICAgIGNhc2UgJ21wNCc6XG4gICAgICAgIHJldHVybiAndmlkZW8vbXA0JztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHJldHVybiAnaW1hZ2UvanBlZyc7XG4gICAgfVxuICB9XG4gIHJldHVybiAnJztcbn07XG5cbmNvbnN0IGNyZWF0ZUJhc2ljTWV0YVRhZ3MgPSAoc2l0ZUhvc3QsIHNpdGVEZXNjcmlwdGlvbiwgc2l0ZVRpdGxlLCBzaXRlVHdpdHRlcikgPT4ge1xuICByZXR1cm4gW1xuICAgIHtwcm9wZXJ0eTogJ29nOnRpdGxlJywgY29udGVudDogc2l0ZVRpdGxlfSxcbiAgICB7cHJvcGVydHk6ICdvZzp1cmwnLCBjb250ZW50OiBzaXRlSG9zdH0sXG4gICAge3Byb3BlcnR5OiAnb2c6c2l0ZV9uYW1lJywgY29udGVudDogc2l0ZVRpdGxlfSxcbiAgICB7cHJvcGVydHk6ICdvZzpkZXNjcmlwdGlvbicsIGNvbnRlbnQ6IHNpdGVEZXNjcmlwdGlvbn0sXG4gICAge3Byb3BlcnR5OiAndHdpdHRlcjpzaXRlJywgY29udGVudDogc2l0ZVR3aXR0ZXJ9LFxuICAgIHtwcm9wZXJ0eTogJ3R3aXR0ZXI6Y2FyZCcsIGNvbnRlbnQ6ICdzdW1tYXJ5J30sXG4gIF07XG59O1xuXG5jb25zdCBjcmVhdGVDaGFubmVsTWV0YVRhZ3MgPSAoc2l0ZVRpdGxlLCBzaXRlSG9zdCwgc2l0ZVR3aXR0ZXIsIGNoYW5uZWwpID0+IHtcbiAgY29uc3QgeyBuYW1lLCBsb25nSWQgfSA9IGNoYW5uZWw7XG4gIHJldHVybiBbXG4gICAge3Byb3BlcnR5OiAnb2c6dGl0bGUnLCBjb250ZW50OiBgJHtuYW1lfSBvbiAke3NpdGVUaXRsZX1gfSxcbiAgICB7cHJvcGVydHk6ICdvZzp1cmwnLCBjb250ZW50OiBgJHtzaXRlSG9zdH0vJHtuYW1lfToke2xvbmdJZH1gfSxcbiAgICB7cHJvcGVydHk6ICdvZzpzaXRlX25hbWUnLCBjb250ZW50OiBzaXRlVGl0bGV9LFxuICAgIHtwcm9wZXJ0eTogJ29nOmRlc2NyaXB0aW9uJywgY29udGVudDogYCR7bmFtZX0sIGEgY2hhbm5lbCBvbiAke3NpdGVUaXRsZX1gfSxcbiAgICB7cHJvcGVydHk6ICd0d2l0dGVyOnNpdGUnLCBjb250ZW50OiBzaXRlVHdpdHRlcn0sXG4gICAge3Byb3BlcnR5OiAndHdpdHRlcjpjYXJkJywgY29udGVudDogJ3N1bW1hcnknfSxcbiAgXTtcbn07XG5cbmNvbnN0IGNyZWF0ZUFzc2V0TWV0YVRhZ3MgPSAoc2l0ZUhvc3QsIHNpdGVUaXRsZSwgc2l0ZVR3aXR0ZXIsIGFzc2V0LCBkZWZhdWx0RGVzY3JpcHRpb24sIGRlZmF1bHRUaHVtYm5haWwpID0+IHtcbiAgY29uc3QgeyBjbGFpbURhdGEgfSA9IGFzc2V0O1xuICBjb25zdCB7IGNvbnRlbnRUeXBlIH0gPSBjbGFpbURhdGE7XG4gIGNvbnN0IGVtYmVkVXJsID0gYCR7c2l0ZUhvc3R9LyR7Y2xhaW1EYXRhLmNsYWltSWR9LyR7Y2xhaW1EYXRhLm5hbWV9YDtcbiAgY29uc3Qgc2hvd1VybCA9IGAke3NpdGVIb3N0fS8ke2NsYWltRGF0YS5jbGFpbUlkfS8ke2NsYWltRGF0YS5uYW1lfWA7XG4gIGNvbnN0IHNvdXJjZSA9IGAke3NpdGVIb3N0fS8ke2NsYWltRGF0YS5jbGFpbUlkfS8ke2NsYWltRGF0YS5uYW1lfS4ke2NsYWltRGF0YS5maWxlRXh0fWA7XG4gIGNvbnN0IG9nVGl0bGUgPSBjbGFpbURhdGEudGl0bGUgfHwgY2xhaW1EYXRhLm5hbWU7XG4gIGNvbnN0IG9nRGVzY3JpcHRpb24gPSBjbGFpbURhdGEuZGVzY3JpcHRpb24gfHwgZGVmYXVsdERlc2NyaXB0aW9uO1xuICBjb25zdCBvZ1RodW1ibmFpbENvbnRlbnRUeXBlID0gZGV0ZXJtaW5lT2dUaHVtYm5haWxDb250ZW50VHlwZShjbGFpbURhdGEudGh1bWJuYWlsKTtcbiAgY29uc3Qgb2dUaHVtYm5haWwgPSBjbGFpbURhdGEudGh1bWJuYWlsIHx8IGRlZmF1bHRUaHVtYm5haWw7XG4gIGNvbnN0IG1ldGFUYWdzID0gW1xuICAgIHtwcm9wZXJ0eTogJ29nOnRpdGxlJywgY29udGVudDogb2dUaXRsZX0sXG4gICAge3Byb3BlcnR5OiAnb2c6dXJsJywgY29udGVudDogc2hvd1VybH0sXG4gICAge3Byb3BlcnR5OiAnb2c6c2l0ZV9uYW1lJywgY29udGVudDogc2l0ZVRpdGxlfSxcbiAgICB7cHJvcGVydHk6ICdvZzpkZXNjcmlwdGlvbicsIGNvbnRlbnQ6IG9nRGVzY3JpcHRpb259LFxuICAgIHtwcm9wZXJ0eTogJ29nOmltYWdlOndpZHRoJywgY29udGVudDogNjAwfSxcbiAgICB7cHJvcGVydHk6ICdvZzppbWFnZTpoZWlnaHQnLCBjb250ZW50OiAzMTV9LFxuICAgIHtwcm9wZXJ0eTogJ3R3aXR0ZXI6c2l0ZScsIGNvbnRlbnQ6IHNpdGVUd2l0dGVyfSxcbiAgXTtcbiAgaWYgKGNvbnRlbnRUeXBlID09PSAndmlkZW8vbXA0JyB8fCBjb250ZW50VHlwZSA9PT0gJ3ZpZGVvL3dlYm0nKSB7XG4gICAgbWV0YVRhZ3MucHVzaCh7cHJvcGVydHk6ICdvZzp2aWRlbycsIGNvbnRlbnQ6IHNvdXJjZX0pO1xuICAgIG1ldGFUYWdzLnB1c2goe3Byb3BlcnR5OiAnb2c6dmlkZW86c2VjdXJlX3VybCcsIGNvbnRlbnQ6IHNvdXJjZX0pO1xuICAgIG1ldGFUYWdzLnB1c2goe3Byb3BlcnR5OiAnb2c6dmlkZW86dHlwZScsIGNvbnRlbnQ6IGNvbnRlbnRUeXBlfSk7XG4gICAgbWV0YVRhZ3MucHVzaCh7cHJvcGVydHk6ICdvZzppbWFnZScsIGNvbnRlbnQ6IG9nVGh1bWJuYWlsfSk7XG4gICAgbWV0YVRhZ3MucHVzaCh7cHJvcGVydHk6ICdvZzppbWFnZTp0eXBlJywgY29udGVudDogb2dUaHVtYm5haWxDb250ZW50VHlwZX0pO1xuICAgIG1ldGFUYWdzLnB1c2goe3Byb3BlcnR5OiAnb2c6dHlwZScsIGNvbnRlbnQ6ICd2aWRlbyd9KTtcbiAgICBtZXRhVGFncy5wdXNoKHtwcm9wZXJ0eTogJ3R3aXR0ZXI6Y2FyZCcsIGNvbnRlbnQ6ICdwbGF5ZXInfSk7XG4gICAgbWV0YVRhZ3MucHVzaCh7cHJvcGVydHk6ICd0d2l0dGVyOnBsYXllcicsIGNvbnRlbnQ6IGVtYmVkVXJsfSk7XG4gICAgbWV0YVRhZ3MucHVzaCh7cHJvcGVydHk6ICd0d2l0dGVyOnBsYXllcjp3aWR0aCcsIGNvbnRlbnQ6IDYwMH0pO1xuICAgIG1ldGFUYWdzLnB1c2goe3Byb3BlcnR5OiAndHdpdHRlcjp0ZXh0OnBsYXllcl93aWR0aCcsIGNvbnRlbnQ6IDYwMH0pO1xuICAgIG1ldGFUYWdzLnB1c2goe3Byb3BlcnR5OiAndHdpdHRlcjpwbGF5ZXI6aGVpZ2h0JywgY29udGVudDogMzM3fSk7XG4gICAgbWV0YVRhZ3MucHVzaCh7cHJvcGVydHk6ICd0d2l0dGVyOnBsYXllcjpzdHJlYW0nLCBjb250ZW50OiBzb3VyY2V9KTtcbiAgICBtZXRhVGFncy5wdXNoKHtwcm9wZXJ0eTogJ3R3aXR0ZXI6cGxheWVyOnN0cmVhbTpjb250ZW50X3R5cGUnLCBjb250ZW50OiBjb250ZW50VHlwZX0pO1xuICB9IGVsc2Uge1xuICAgIG1ldGFUYWdzLnB1c2goe3Byb3BlcnR5OiAnb2c6aW1hZ2UnLCBjb250ZW50OiBzb3VyY2V9KTtcbiAgICBtZXRhVGFncy5wdXNoKHtwcm9wZXJ0eTogJ29nOmltYWdlOnR5cGUnLCBjb250ZW50OiBjb250ZW50VHlwZX0pO1xuICAgIG1ldGFUYWdzLnB1c2goe3Byb3BlcnR5OiAnb2c6dHlwZScsIGNvbnRlbnQ6ICdhcnRpY2xlJ30pO1xuICAgIG1ldGFUYWdzLnB1c2goe3Byb3BlcnR5OiAndHdpdHRlcjpjYXJkJywgY29udGVudDogJ3N1bW1hcnlfbGFyZ2VfaW1hZ2UnfSk7XG4gIH1cbiAgcmV0dXJuIG1ldGFUYWdzO1xufTtcblxuZXhwb3J0IGNvbnN0IGNyZWF0ZU1ldGFUYWdzID0gKHNpdGVEZXNjcmlwdGlvbiwgc2l0ZUhvc3QsIHNpdGVUaXRsZSwgc2l0ZVR3aXR0ZXIsIGFzc2V0LCBjaGFubmVsLCBkZWZhdWx0RGVzY3JpcHRpb24sIGRlZmF1bHRUaHVtYm5haWwpID0+IHtcbiAgaWYgKGFzc2V0KSB7XG4gICAgcmV0dXJuIGNyZWF0ZUFzc2V0TWV0YVRhZ3Moc2l0ZUhvc3QsIHNpdGVUaXRsZSwgc2l0ZVR3aXR0ZXIsIGFzc2V0LCBkZWZhdWx0RGVzY3JpcHRpb24sIGRlZmF1bHRUaHVtYm5haWwpO1xuICB9O1xuICBpZiAoY2hhbm5lbCkge1xuICAgIHJldHVybiBjcmVhdGVDaGFubmVsTWV0YVRhZ3Moc2l0ZUhvc3QsIHNpdGVUaXRsZSwgc2l0ZVR3aXR0ZXIsIGNoYW5uZWwpO1xuICB9O1xuICByZXR1cm4gY3JlYXRlQmFzaWNNZXRhVGFncyhzaXRlRGVzY3JpcHRpb24sIHNpdGVIb3N0LCBzaXRlVGl0bGUsIHNpdGVUd2l0dGVyKTtcbn07XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9jbGllbnQvdXRpbHMvbWV0YVRhZ3MuanMiLCJjb25zdCBjcmVhdGVCYXNpY0Nhbm9uaWNhbExpbmsgPSAocGFnZSwgc2l0ZUhvc3QpID0+IHtcbiAgcmV0dXJuIGAke3NpdGVIb3N0fS8ke3BhZ2V9YDtcbn07XG5cbmNvbnN0IGNyZWF0ZUFzc2V0Q2Fub25pY2FsTGluayA9IChhc3NldCwgc2l0ZUhvc3QpID0+IHtcbiAgbGV0IGNoYW5uZWxOYW1lLCBjZXJ0aWZpY2F0ZUlkLCBuYW1lLCBjbGFpbUlkO1xuICBpZiAoYXNzZXQuY2xhaW1EYXRhKSB7XG4gICAgKHsgY2hhbm5lbE5hbWUsIGNlcnRpZmljYXRlSWQsIG5hbWUsIGNsYWltSWQgfSA9IGFzc2V0LmNsYWltRGF0YSk7XG4gIH07XG4gIGlmIChjaGFubmVsTmFtZSkge1xuICAgIHJldHVybiBgJHtzaXRlSG9zdH0vJHtjaGFubmVsTmFtZX06JHtjZXJ0aWZpY2F0ZUlkfS8ke25hbWV9YDtcbiAgfTtcbiAgcmV0dXJuIGAke3NpdGVIb3N0fS8ke2NsYWltSWR9LyR7bmFtZX1gO1xufTtcblxuY29uc3QgY3JlYXRlQ2hhbm5lbENhbm9uaWNhbExpbmsgPSAoY2hhbm5lbCwgc2l0ZUhvc3QpID0+IHtcbiAgY29uc3QgeyBuYW1lLCBsb25nSWQgfSA9IGNoYW5uZWw7XG4gIHJldHVybiBgJHtzaXRlSG9zdH0vJHtuYW1lfToke2xvbmdJZH1gO1xufTtcblxuZXhwb3J0IGNvbnN0IGNyZWF0ZUNhbm9uaWNhbExpbmsgPSAoYXNzZXQsIGNoYW5uZWwsIHBhZ2UsIHNpdGVIb3N0KSA9PiB7XG4gIGlmIChhc3NldCkge1xuICAgIHJldHVybiBjcmVhdGVBc3NldENhbm9uaWNhbExpbmsoYXNzZXQsIHNpdGVIb3N0KTtcbiAgfVxuICBpZiAoY2hhbm5lbCkge1xuICAgIHJldHVybiBjcmVhdGVDaGFubmVsQ2Fub25pY2FsTGluayhjaGFubmVsLCBzaXRlSG9zdCk7XG4gIH1cbiAgcmV0dXJuIGNyZWF0ZUJhc2ljQ2Fub25pY2FsTGluayhwYWdlLCBzaXRlSG9zdCk7XG59O1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vY2xpZW50L3V0aWxzL2Nhbm9uaWNhbExpbmsuanMiLCJpbXBvcnQgUmVhY3QgZnJvbSAncmVhY3QnO1xuaW1wb3J0IHsgTmF2TGluaywgd2l0aFJvdXRlciB9IGZyb20gJ3JlYWN0LXJvdXRlci1kb20nO1xuaW1wb3J0IExvZ28gZnJvbSAnY29tcG9uZW50cy9Mb2dvJztcbmltcG9ydCBOYXZCYXJDaGFubmVsRHJvcGRvd24gZnJvbSAnY29tcG9uZW50cy9OYXZCYXJDaGFubmVsT3B0aW9uc0Ryb3Bkb3duJztcbmltcG9ydCByZXF1ZXN0IGZyb20gJ3V0aWxzL3JlcXVlc3QnO1xuXG5jb25zdCBWSUVXID0gJ1ZJRVcnO1xuY29uc3QgTE9HT1VUID0gJ0xPR09VVCc7XG5cbmNsYXNzIE5hdkJhciBleHRlbmRzIFJlYWN0LkNvbXBvbmVudCB7XG4gIGNvbnN0cnVjdG9yIChwcm9wcykge1xuICAgIHN1cGVyKHByb3BzKTtcbiAgICB0aGlzLmNoZWNrRm9yTG9nZ2VkSW5Vc2VyID0gdGhpcy5jaGVja0ZvckxvZ2dlZEluVXNlci5iaW5kKHRoaXMpO1xuICAgIHRoaXMubG9nb3V0VXNlciA9IHRoaXMubG9nb3V0VXNlci5iaW5kKHRoaXMpO1xuICAgIHRoaXMuaGFuZGxlU2VsZWN0aW9uID0gdGhpcy5oYW5kbGVTZWxlY3Rpb24uYmluZCh0aGlzKTtcbiAgfVxuICBjb21wb25lbnREaWRNb3VudCAoKSB7XG4gICAgLy8gY2hlY2sgdG8gc2VlIGlmIHRoZSB1c2VyIGlzIGFscmVhZHkgbG9nZ2VkIGluXG4gICAgdGhpcy5jaGVja0ZvckxvZ2dlZEluVXNlcigpO1xuICB9XG4gIGNoZWNrRm9yTG9nZ2VkSW5Vc2VyICgpIHtcbiAgICBjb25zdCBwYXJhbXMgPSB7Y3JlZGVudGlhbHM6ICdpbmNsdWRlJ307XG4gICAgcmVxdWVzdCgnL3VzZXInLCBwYXJhbXMpXG4gICAgICAudGhlbigoeyBkYXRhIH0pID0+IHtcbiAgICAgICAgdGhpcy5wcm9wcy5vbkNoYW5uZWxMb2dpbihkYXRhLmNoYW5uZWxOYW1lLCBkYXRhLnNob3J0Q2hhbm5lbElkLCBkYXRhLmNoYW5uZWxDbGFpbUlkKTtcbiAgICAgIH0pXG4gICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICBjb25zb2xlLmxvZygnL3VzZXIgZXJyb3I6JywgZXJyb3IubWVzc2FnZSk7XG4gICAgICB9KTtcbiAgfVxuICBsb2dvdXRVc2VyICgpIHtcbiAgICBjb25zdCBwYXJhbXMgPSB7Y3JlZGVudGlhbHM6ICdpbmNsdWRlJ307XG4gICAgcmVxdWVzdCgnL2xvZ291dCcsIHBhcmFtcylcbiAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgdGhpcy5wcm9wcy5vbkNoYW5uZWxMb2dvdXQoKTtcbiAgICAgIH0pXG4gICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICBjb25zb2xlLmxvZygnL2xvZ291dCBlcnJvcicsIGVycm9yLm1lc3NhZ2UpO1xuICAgICAgfSk7XG4gIH1cbiAgaGFuZGxlU2VsZWN0aW9uIChldmVudCkge1xuICAgIGNvbnN0IHZhbHVlID0gZXZlbnQudGFyZ2V0LnNlbGVjdGVkT3B0aW9uc1swXS52YWx1ZTtcbiAgICBzd2l0Y2ggKHZhbHVlKSB7XG4gICAgICBjYXNlIExPR09VVDpcbiAgICAgICAgdGhpcy5sb2dvdXRVc2VyKCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBWSUVXOlxuICAgICAgICAvLyByZWRpcmVjdCB0byBjaGFubmVsIHBhZ2VcbiAgICAgICAgdGhpcy5wcm9wcy5oaXN0b3J5LnB1c2goYC8ke3RoaXMucHJvcHMuY2hhbm5lbE5hbWV9OiR7dGhpcy5wcm9wcy5jaGFubmVsTG9uZ0lkfWApO1xuICAgICAgICBicmVhaztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuICByZW5kZXIgKCkge1xuICAgIGNvbnN0IHsgc2l0ZURlc2NyaXB0aW9uIH0gPSAgdGhpcy5wcm9wcztcbiAgICByZXR1cm4gKFxuICAgICAgPGRpdiBjbGFzc05hbWU9J3JvdyByb3ctLXdpZGUgbmF2LWJhcic+XG4gICAgICAgIDxkaXYgY2xhc3NOYW1lPSdyb3cgcm93LS1wYWRkZWQgcm93LS1zaG9ydCBmbGV4LWNvbnRhaW5lci0tcm93IGZsZXgtY29udGFpbmVyLS1zcGFjZS1iZXR3ZWVuLWNlbnRlcic+XG4gICAgICAgICAgPExvZ28gLz5cbiAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT0nbmF2LWJhci0tY2VudGVyJz5cbiAgICAgICAgICAgIDxzcGFuIGNsYXNzTmFtZT0nbmF2LWJhci10YWdsaW5lJz57c2l0ZURlc2NyaXB0aW9ufTwvc3Bhbj5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT0nbmF2LWJhci0tcmlnaHQnPlxuICAgICAgICAgICAgPE5hdkxpbmsgY2xhc3NOYW1lPSduYXYtYmFyLWxpbmsgbGluay0tbmF2JyBhY3RpdmVDbGFzc05hbWU9J2xpbmstLW5hdi1hY3RpdmUnIHRvPScvJyBleGFjdD5QdWJsaXNoPC9OYXZMaW5rPlxuICAgICAgICAgICAgPE5hdkxpbmsgY2xhc3NOYW1lPSduYXYtYmFyLWxpbmsgbGluay0tbmF2JyAgYWN0aXZlQ2xhc3NOYW1lPSdsaW5rLS1uYXYtYWN0aXZlJyB0bz0nL2Fib3V0Jz5BYm91dDwvTmF2TGluaz5cbiAgICAgICAgICAgIHsgdGhpcy5wcm9wcy5jaGFubmVsTmFtZSA/IChcbiAgICAgICAgICAgICAgPE5hdkJhckNoYW5uZWxEcm9wZG93blxuICAgICAgICAgICAgICAgIGNoYW5uZWxOYW1lPXt0aGlzLnByb3BzLmNoYW5uZWxOYW1lfVxuICAgICAgICAgICAgICAgIGhhbmRsZVNlbGVjdGlvbj17dGhpcy5oYW5kbGVTZWxlY3Rpb259XG4gICAgICAgICAgICAgICAgZGVmYXVsdFNlbGVjdGlvbj17dGhpcy5wcm9wcy5jaGFubmVsTmFtZX1cbiAgICAgICAgICAgICAgICBWSUVXPXtWSUVXfVxuICAgICAgICAgICAgICAgIExPR09VVD17TE9HT1VUfVxuICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgKSA6IChcbiAgICAgICAgICAgICAgPE5hdkxpbmsgaWQ9J25hdi1iYXItbG9naW4tbGluaycgY2xhc3NOYW1lPSduYXYtYmFyLWxpbmsgbGluay0tbmF2JyBhY3RpdmVDbGFzc05hbWU9J2xpbmstLW5hdi1hY3RpdmUnIHRvPScvbG9naW4nPkNoYW5uZWw8L05hdkxpbms+XG4gICAgICAgICAgICApfVxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuICAgICk7XG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgd2l0aFJvdXRlcihOYXZCYXIpO1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vY2xpZW50L2NvbnRhaW5lcnMvTmF2QmFyL3ZpZXcuanN4IiwiaW1wb3J0IFJlYWN0IGZyb20gJ3JlYWN0JztcbmltcG9ydCB7IExpbmsgfSBmcm9tICdyZWFjdC1yb3V0ZXItZG9tJztcblxuZnVuY3Rpb24gTG9nbyAoKSB7XG4gIHJldHVybiAoXG4gICAgPHN2ZyB2ZXJzaW9uPScxLjEnIGlkPSdMYXllcl8xJyB4PScwcHgnIHk9JzBweCcgaGVpZ2h0PScyNHB4JyB2aWV3Qm94PScwIDAgODAgMzEnIGVuYWJsZUJhY2tncm91bmQ9J25ldyAwIDAgODAgMzEnIGNsYXNzTmFtZT0nbmF2LWJhci1sb2dvJz5cbiAgICAgIDxMaW5rIHRvPScvJz5cbiAgICAgICAgPHRpdGxlPkxvZ288L3RpdGxlPlxuICAgICAgICA8ZGVzYz5TcGVlLmNoIGxvZ288L2Rlc2M+XG4gICAgICAgIDxnIGlkPSdBYm91dCc+XG4gICAgICAgICAgPGcgaWQ9J1B1Ymxpc2gtRm9ybS1WMi1feDI4X2ZpbGxlZF94MjlfJyB0cmFuc2Zvcm09J3RyYW5zbGF0ZSgtNDIuMDAwMDAwLCAtMjMuMDAwMDAwKSc+XG4gICAgICAgICAgICA8ZyBpZD0nR3JvdXAtMTcnIHRyYW5zZm9ybT0ndHJhbnNsYXRlKDQyLjAwMDAwMCwgMjIuMDAwMDAwKSc+XG4gICAgICAgICAgICAgIDx0ZXh0IHRyYW5zZm9ybT0nbWF0cml4KDEgMCAwIDEgMCAyMCknIGZvbnRTaXplPScyNScgZm9udEZhbWlseT0nUm9ib3RvJz5TcGVlJmx0O2g8L3RleHQ+XG4gICAgICAgICAgICAgIDxnIGlkPSdHcm91cC0xNicgdHJhbnNmb3JtPSd0cmFuc2xhdGUoMC4wMDAwMDAsIDMwLjAwMDAwMCknPlxuICAgICAgICAgICAgICAgIDxwYXRoIGlkPSdMaW5lLTgnIGZpbGw9J25vbmUnIHN0cm9rZT0nIzA5RjkxMScgc3Ryb2tlV2lkdGg9JzEnIHN0cm9rZUxpbmVjYXA9J3NxdWFyZScgZD0nTTAuNSwxLjVoMTUnIC8+XG4gICAgICAgICAgICAgICAgPHBhdGggaWQ9J0xpbmUtOC1Db3B5JyBmaWxsPSdub25lJyBzdHJva2U9JyMwMjlENzQnIHN0cm9rZVdpZHRoPScxJyBzdHJva2VMaW5lY2FwPSdzcXVhcmUnIGQ9J00xNi41LDEuNWgxNScgLz5cbiAgICAgICAgICAgICAgICA8cGF0aCBpZD0nTGluZS04LUNvcHktMicgZmlsbD0nbm9uZScgc3Ryb2tlPScjRTM1QkQ4JyBzdHJva2VXaWR0aD0nMScgc3Ryb2tlTGluZWNhcD0nc3F1YXJlJyBkPSdNMzIuNSwxLjVoMTUnIC8+XG4gICAgICAgICAgICAgICAgPHBhdGggaWQ9J0xpbmUtOC1Db3B5LTMnIGZpbGw9J25vbmUnIHN0cm9rZT0nIzQxNTZDNScgc3Ryb2tlV2lkdGg9JzEnIHN0cm9rZUxpbmVjYXA9J3NxdWFyZScgZD0nTTQ4LjUsMS41aDE1JyAvPlxuICAgICAgICAgICAgICAgIDxwYXRoIGlkPSdMaW5lLTgtQ29weS00JyBmaWxsPSdub25lJyBzdHJva2U9JyM2MzU2ODgnIHN0cm9rZVdpZHRoPScxJyBzdHJva2VMaW5lY2FwPSdzcXVhcmUnIGQ9J002NC41LDEuNWgxNScgLz5cbiAgICAgICAgICAgICAgPC9nPlxuICAgICAgICAgICAgPC9nPlxuICAgICAgICAgIDwvZz5cbiAgICAgICAgPC9nPlxuICAgICAgPC9MaW5rPlxuICAgIDwvc3ZnPlxuICApO1xufTtcblxuZXhwb3J0IGRlZmF1bHQgTG9nbztcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL2NsaWVudC9jb21wb25lbnRzL0xvZ28vaW5kZXguanN4IiwiaW1wb3J0IFJlYWN0IGZyb20gJ3JlYWN0JztcblxuZnVuY3Rpb24gTmF2QmFyQ2hhbm5lbERyb3Bkb3duICh7IGNoYW5uZWxOYW1lLCBoYW5kbGVTZWxlY3Rpb24sIGRlZmF1bHRTZWxlY3Rpb24sIFZJRVcsIExPR09VVCB9KSB7XG4gIHJldHVybiAoXG4gICAgPHNlbGVjdCB0eXBlPSd0ZXh0JyBpZD0nbmF2LWJhci1jaGFubmVsLXNlbGVjdCcgY2xhc3NOYW1lPSdzZWxlY3Qgc2VsZWN0LS1hcnJvdyBsaW5rLS1uYXYnIG9uQ2hhbmdlPXtoYW5kbGVTZWxlY3Rpb259IHZhbHVlPXtkZWZhdWx0U2VsZWN0aW9ufT5cbiAgICAgIDxvcHRpb24gaWQ9J25hdi1iYXItY2hhbm5lbC1zZWxlY3QtY2hhbm5lbC1vcHRpb24nPntjaGFubmVsTmFtZX08L29wdGlvbj5cbiAgICAgIDxvcHRpb24gdmFsdWU9e1ZJRVd9PlZpZXc8L29wdGlvbj5cbiAgICAgIDxvcHRpb24gdmFsdWU9e0xPR09VVH0+TG9nb3V0PC9vcHRpb24+XG4gICAgPC9zZWxlY3Q+XG4gICk7XG59O1xuXG5leHBvcnQgZGVmYXVsdCBOYXZCYXJDaGFubmVsRHJvcGRvd247XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9jbGllbnQvY29tcG9uZW50cy9OYXZCYXJDaGFubmVsT3B0aW9uc0Ryb3Bkb3duL2luZGV4LmpzeCIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcImNyb3NzLWZldGNoL3BvbHlmaWxsXCIpO1xuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIGV4dGVybmFsIFwiY3Jvc3MtZmV0Y2gvcG9seWZpbGxcIlxuLy8gbW9kdWxlIGlkID0gNjFcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiaW1wb3J0IHtjb25uZWN0fSBmcm9tICdyZWFjdC1yZWR1eCc7XG5pbXBvcnQgVmlldyBmcm9tICcuL3ZpZXcnO1xuXG5jb25zdCBtYXBTdGF0ZVRvUHJvcHMgPSAoeyBwdWJsaXNoIH0pID0+IHtcbiAgcmV0dXJuIHtcbiAgICBkaXNhYmxlZDogcHVibGlzaC5kaXNhYmxlZCxcbiAgICBmaWxlICAgIDogcHVibGlzaC5maWxlLFxuICAgIHN0YXR1cyAgOiBwdWJsaXNoLnN0YXR1cy5zdGF0dXMsXG4gIH07XG59O1xuXG5leHBvcnQgZGVmYXVsdCBjb25uZWN0KG1hcFN0YXRlVG9Qcm9wcywgbnVsbCkoVmlldyk7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9jbGllbnQvY29udGFpbmVycy9QdWJsaXNoVG9vbC9pbmRleC5qcyIsImltcG9ydCBSZWFjdCBmcm9tICdyZWFjdCc7XG5pbXBvcnQgRHJvcHpvbmUgZnJvbSAnY29udGFpbmVycy9Ecm9wem9uZSc7XG5pbXBvcnQgUHVibGlzaERldGFpbHMgZnJvbSAnY29udGFpbmVycy9QdWJsaXNoRGV0YWlscyc7XG5pbXBvcnQgUHVibGlzaFN0YXR1cyBmcm9tICdjb250YWluZXJzL1B1Ymxpc2hTdGF0dXMnO1xuaW1wb3J0IFB1Ymxpc2hEaXNhYmxlZE1lc3NhZ2UgZnJvbSAnY29udGFpbmVycy9QdWJsaXNoRGlzYWJsZWRNZXNzYWdlJztcblxuY2xhc3MgUHVibGlzaFRvb2wgZXh0ZW5kcyBSZWFjdC5Db21wb25lbnQge1xuICByZW5kZXIgKCkge1xuICAgIGlmICh0aGlzLnByb3BzLmRpc2FibGVkKSB7XG4gICAgICBjb25zb2xlLmxvZygncHVibGlzaCBpcyBkaXNhYmxlZCcpO1xuICAgICAgcmV0dXJuIChcbiAgICAgICAgPFB1Ymxpc2hEaXNhYmxlZE1lc3NhZ2UgLz5cbiAgICAgICk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnNvbGUubG9nKCdwdWJsaXNoIGlzIG5vdCBkaXNhYmxlZCcpO1xuICAgICAgaWYgKHRoaXMucHJvcHMuZmlsZSkge1xuICAgICAgICBpZiAodGhpcy5wcm9wcy5zdGF0dXMpIHtcbiAgICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgPFB1Ymxpc2hTdGF0dXMgLz5cbiAgICAgICAgICApO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldHVybiA8UHVibGlzaERldGFpbHMgLz47XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiA8RHJvcHpvbmUgLz47XG4gICAgfVxuICB9XG59O1xuXG5leHBvcnQgZGVmYXVsdCBQdWJsaXNoVG9vbDtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL2NsaWVudC9jb250YWluZXJzL1B1Ymxpc2hUb29sL3ZpZXcuanN4IiwiaW1wb3J0IFJlYWN0IGZyb20gJ3JlYWN0JztcbmltcG9ydCB7IHZhbGlkYXRlRmlsZSB9IGZyb20gJ3V0aWxzL2ZpbGUnO1xuaW1wb3J0IFB1Ymxpc2hQcmV2aWV3IGZyb20gJ2NvbXBvbmVudHMvUHVibGlzaFByZXZpZXcnO1xuXG5jbGFzcyBEcm9wem9uZSBleHRlbmRzIFJlYWN0LkNvbXBvbmVudCB7XG4gIGNvbnN0cnVjdG9yIChwcm9wcykge1xuICAgIHN1cGVyKHByb3BzKTtcbiAgICB0aGlzLnN0YXRlID0ge1xuICAgICAgZHJhZ092ZXIgIDogZmFsc2UsXG4gICAgICBtb3VzZU92ZXIgOiBmYWxzZSxcbiAgICAgIGRpbVByZXZpZXc6IGZhbHNlLFxuICAgIH07XG4gICAgdGhpcy5oYW5kbGVEcm9wID0gdGhpcy5oYW5kbGVEcm9wLmJpbmQodGhpcyk7XG4gICAgdGhpcy5oYW5kbGVEcmFnT3ZlciA9IHRoaXMuaGFuZGxlRHJhZ092ZXIuYmluZCh0aGlzKTtcbiAgICB0aGlzLmhhbmRsZURyYWdFbmQgPSB0aGlzLmhhbmRsZURyYWdFbmQuYmluZCh0aGlzKTtcbiAgICB0aGlzLmhhbmRsZURyYWdFbnRlciA9IHRoaXMuaGFuZGxlRHJhZ0VudGVyLmJpbmQodGhpcyk7XG4gICAgdGhpcy5oYW5kbGVEcmFnTGVhdmUgPSB0aGlzLmhhbmRsZURyYWdMZWF2ZS5iaW5kKHRoaXMpO1xuICAgIHRoaXMuaGFuZGxlTW91c2VFbnRlciA9IHRoaXMuaGFuZGxlTW91c2VFbnRlci5iaW5kKHRoaXMpO1xuICAgIHRoaXMuaGFuZGxlTW91c2VMZWF2ZSA9IHRoaXMuaGFuZGxlTW91c2VMZWF2ZS5iaW5kKHRoaXMpO1xuICAgIHRoaXMuaGFuZGxlQ2xpY2sgPSB0aGlzLmhhbmRsZUNsaWNrLmJpbmQodGhpcyk7XG4gICAgdGhpcy5oYW5kbGVGaWxlSW5wdXQgPSB0aGlzLmhhbmRsZUZpbGVJbnB1dC5iaW5kKHRoaXMpO1xuICAgIHRoaXMuY2hvb3NlRmlsZSA9IHRoaXMuY2hvb3NlRmlsZS5iaW5kKHRoaXMpO1xuICB9XG4gIGhhbmRsZURyb3AgKGV2ZW50KSB7XG4gICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICB0aGlzLnNldFN0YXRlKHtkcmFnT3ZlcjogZmFsc2V9KTtcbiAgICAvLyBpZiBkcm9wcGVkIGl0ZW1zIGFyZW4ndCBmaWxlcywgcmVqZWN0IHRoZW1cbiAgICBjb25zdCBkdCA9IGV2ZW50LmRhdGFUcmFuc2ZlcjtcbiAgICBpZiAoZHQuaXRlbXMpIHtcbiAgICAgIGlmIChkdC5pdGVtc1swXS5raW5kID09PSAnZmlsZScpIHtcbiAgICAgICAgY29uc3QgZHJvcHBlZEZpbGUgPSBkdC5pdGVtc1swXS5nZXRBc0ZpbGUoKTtcbiAgICAgICAgdGhpcy5jaG9vc2VGaWxlKGRyb3BwZWRGaWxlKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgaGFuZGxlRHJhZ092ZXIgKGV2ZW50KSB7XG4gICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgfVxuICBoYW5kbGVEcmFnRW5kIChldmVudCkge1xuICAgIHZhciBkdCA9IGV2ZW50LmRhdGFUcmFuc2ZlcjtcbiAgICBpZiAoZHQuaXRlbXMpIHtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZHQuaXRlbXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgZHQuaXRlbXMucmVtb3ZlKGkpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBldmVudC5kYXRhVHJhbnNmZXIuY2xlYXJEYXRhKCk7XG4gICAgfVxuICB9XG4gIGhhbmRsZURyYWdFbnRlciAoKSB7XG4gICAgdGhpcy5zZXRTdGF0ZSh7ZHJhZ092ZXI6IHRydWUsIGRpbVByZXZpZXc6IHRydWV9KTtcbiAgfVxuICBoYW5kbGVEcmFnTGVhdmUgKCkge1xuICAgIHRoaXMuc2V0U3RhdGUoe2RyYWdPdmVyOiBmYWxzZSwgZGltUHJldmlldzogZmFsc2V9KTtcbiAgfVxuICBoYW5kbGVNb3VzZUVudGVyICgpIHtcbiAgICB0aGlzLnNldFN0YXRlKHttb3VzZU92ZXI6IHRydWUsIGRpbVByZXZpZXc6IHRydWV9KTtcbiAgfVxuICBoYW5kbGVNb3VzZUxlYXZlICgpIHtcbiAgICB0aGlzLnNldFN0YXRlKHttb3VzZU92ZXI6IGZhbHNlLCBkaW1QcmV2aWV3OiBmYWxzZX0pO1xuICB9XG4gIGhhbmRsZUNsaWNrIChldmVudCkge1xuICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2ZpbGVfaW5wdXQnKS5jbGljaygpO1xuICB9XG4gIGhhbmRsZUZpbGVJbnB1dCAoZXZlbnQpIHtcbiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIGNvbnN0IGZpbGVMaXN0ID0gZXZlbnQudGFyZ2V0LmZpbGVzO1xuICAgIHRoaXMuY2hvb3NlRmlsZShmaWxlTGlzdFswXSk7XG4gIH1cbiAgY2hvb3NlRmlsZSAoZmlsZSkge1xuICAgIGlmIChmaWxlKSB7XG4gICAgICB0cnkge1xuICAgICAgICB2YWxpZGF0ZUZpbGUoZmlsZSk7IC8vIHZhbGlkYXRlIHRoZSBmaWxlJ3MgbmFtZSwgdHlwZSwgYW5kIHNpemVcbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnByb3BzLnNldEZpbGVFcnJvcihlcnJvci5tZXNzYWdlKTtcbiAgICAgIH1cbiAgICAgIC8vIHN0YWdlIGl0IHNvIGl0IHdpbGwgYmUgcmVhZHkgd2hlbiB0aGUgcHVibGlzaCBidXR0b24gaXMgY2xpY2tlZFxuICAgICAgdGhpcy5wcm9wcy5zZWxlY3RGaWxlKGZpbGUpO1xuICAgIH1cbiAgfVxuICByZW5kZXIgKCkge1xuICAgIHJldHVybiAoXG4gICAgICA8ZGl2IGNsYXNzTmFtZT0ncm93IHJvdy0tdGFsbCBmbGV4LWNvbnRhaW5lci0tY29sdW1uJz5cbiAgICAgICAgPGZvcm0+XG4gICAgICAgICAgPGlucHV0IGNsYXNzTmFtZT0naW5wdXQtZmlsZScgdHlwZT0nZmlsZScgaWQ9J2ZpbGVfaW5wdXQnIG5hbWU9J2ZpbGVfaW5wdXQnIGFjY2VwdD0ndmlkZW8vKixpbWFnZS8qJyBvbkNoYW5nZT17dGhpcy5oYW5kbGVGaWxlSW5wdXR9IGVuY1R5cGU9J211bHRpcGFydC9mb3JtLWRhdGEnIC8+XG4gICAgICAgIDwvZm9ybT5cbiAgICAgICAgPGRpdiBpZD0ncHJldmlldy1kcm9wem9uZScgY2xhc3NOYW1lPXsncm93IHJvdy0tcGFkZGVkIHJvdy0tdGFsbCBkcm9wem9uZScgKyAodGhpcy5zdGF0ZS5kcmFnT3ZlciA/ICcgZHJvcHpvbmUtLWRyYWctb3ZlcicgOiAnJyl9IG9uRHJvcD17dGhpcy5oYW5kbGVEcm9wfSBvbkRyYWdPdmVyPXt0aGlzLmhhbmRsZURyYWdPdmVyfSBvbkRyYWdFbmQ9e3RoaXMuaGFuZGxlRHJhZ0VuZH0gb25EcmFnRW50ZXI9e3RoaXMuaGFuZGxlRHJhZ0VudGVyfSBvbkRyYWdMZWF2ZT17dGhpcy5oYW5kbGVEcmFnTGVhdmV9IG9uTW91c2VFbnRlcj17dGhpcy5oYW5kbGVNb3VzZUVudGVyfSBvbk1vdXNlTGVhdmU9e3RoaXMuaGFuZGxlTW91c2VMZWF2ZX0gb25DbGljaz17dGhpcy5oYW5kbGVDbGlja30+XG4gICAgICAgICAge3RoaXMucHJvcHMuZmlsZSA/IChcbiAgICAgICAgICAgIDxkaXY+XG4gICAgICAgICAgICAgIDxQdWJsaXNoUHJldmlld1xuICAgICAgICAgICAgICAgIGRpbVByZXZpZXc9e3RoaXMuc3RhdGUuZGltUHJldmlld31cbiAgICAgICAgICAgICAgICBmaWxlPXt0aGlzLnByb3BzLmZpbGV9XG4gICAgICAgICAgICAgICAgdGh1bWJuYWlsPXt0aGlzLnByb3BzLnRodW1ibmFpbH1cbiAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgPGRpdiBpZD0nZHJvcHpvbmUtdGV4dC1ob2xkZXInIGNsYXNzTmFtZT17J2ZsZXgtY29udGFpbmVyLS1jb2x1bW4gZmxleC1jb250YWluZXItLWNlbnRlci1jZW50ZXInfT5cbiAgICAgICAgICAgICAgICB7IHRoaXMuc3RhdGUuZHJhZ092ZXIgPyAoXG4gICAgICAgICAgICAgICAgICA8ZGl2IGlkPSdkcm9wem9uZS1kcmFnb3Zlcic+XG4gICAgICAgICAgICAgICAgICAgIDxwIGNsYXNzTmFtZT0nYmx1ZSc+RHJvcCBpdC48L3A+XG4gICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICApIDogKFxuICAgICAgICAgICAgICAgICAgbnVsbFxuICAgICAgICAgICAgICAgICl9XG4gICAgICAgICAgICAgICAgeyB0aGlzLnN0YXRlLm1vdXNlT3ZlciA/IChcbiAgICAgICAgICAgICAgICAgIDxkaXYgaWQ9J2Ryb3B6b25lLWluc3RydWN0aW9ucyc+XG4gICAgICAgICAgICAgICAgICAgIDxwIGNsYXNzTmFtZT0naW5mby1tZXNzYWdlLXBsYWNlaG9sZGVyIGluZm8tbWVzc2FnZS0tZmFpbHVyZScgaWQ9J2lucHV0LWVycm9yLWZpbGUtc2VsZWN0aW9uJz57dGhpcy5wcm9wcy5maWxlRXJyb3J9PC9wPlxuICAgICAgICAgICAgICAgICAgICA8cD5EcmFnICYgZHJvcCBpbWFnZSBvciB2aWRlbyBoZXJlIHRvIHB1Ymxpc2g8L3A+XG4gICAgICAgICAgICAgICAgICAgIDxwIGNsYXNzTmFtZT0nZmluZS1wcmludCc+T1I8L3A+XG4gICAgICAgICAgICAgICAgICAgIDxwIGNsYXNzTmFtZT0nYmx1ZS0tdW5kZXJsaW5lZCc+Q0hPT1NFIEZJTEU8L3A+XG4gICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICApIDogKFxuICAgICAgICAgICAgICAgICAgbnVsbFxuICAgICAgICAgICAgICAgICl9XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgKSA6IChcbiAgICAgICAgICAgIDxkaXYgaWQ9J2Ryb3B6b25lLXRleHQtaG9sZGVyJyBjbGFzc05hbWU9eydmbGV4LWNvbnRhaW5lci0tY29sdW1uIGZsZXgtY29udGFpbmVyLS1jZW50ZXItY2VudGVyJ30+XG4gICAgICAgICAgICAgIHsgdGhpcy5zdGF0ZS5kcmFnT3ZlciA/IChcbiAgICAgICAgICAgICAgICA8ZGl2IGlkPSdkcm9wem9uZS1kcmFnb3Zlcic+XG4gICAgICAgICAgICAgICAgICA8cCBjbGFzc05hbWU9J2JsdWUnPkRyb3AgaXQuPC9wPlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICApIDogKFxuICAgICAgICAgICAgICAgIDxkaXYgaWQ9J2Ryb3B6b25lLWluc3RydWN0aW9ucyc+XG4gICAgICAgICAgICAgICAgICA8cCBjbGFzc05hbWU9J2luZm8tbWVzc2FnZS1wbGFjZWhvbGRlciBpbmZvLW1lc3NhZ2UtLWZhaWx1cmUnIGlkPSdpbnB1dC1lcnJvci1maWxlLXNlbGVjdGlvbic+e3RoaXMucHJvcHMuZmlsZUVycm9yfTwvcD5cbiAgICAgICAgICAgICAgICAgIDxwPkRyYWcgJiBkcm9wIGltYWdlIG9yIHZpZGVvIGhlcmUgdG8gcHVibGlzaDwvcD5cbiAgICAgICAgICAgICAgICAgIDxwIGNsYXNzTmFtZT0nZmluZS1wcmludCc+T1I8L3A+XG4gICAgICAgICAgICAgICAgICA8cCBjbGFzc05hbWU9J2JsdWUtLXVuZGVybGluZWQnPkNIT09TRSBGSUxFPC9wPlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICApfVxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgKX1cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cbiAgICApO1xuICB9XG59O1xuXG5leHBvcnQgZGVmYXVsdCBEcm9wem9uZTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL2NsaWVudC9jb250YWluZXJzL0Ryb3B6b25lL3ZpZXcuanN4IiwibW9kdWxlLmV4cG9ydHMgPSB7XG4gIHZhbGlkYXRlRmlsZSAoZmlsZSkge1xuICAgIGlmICghZmlsZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdubyBmaWxlIHByb3ZpZGVkJyk7XG4gICAgfVxuICAgIGlmICgvJy8udGVzdChmaWxlLm5hbWUpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2Fwb3N0cm9waGVzIGFyZSBub3QgYWxsb3dlZCBpbiB0aGUgZmlsZSBuYW1lJyk7XG4gICAgfVxuICAgIC8vIHZhbGlkYXRlIHNpemUgYW5kIHR5cGVcbiAgICBzd2l0Y2ggKGZpbGUudHlwZSkge1xuICAgICAgY2FzZSAnaW1hZ2UvanBlZyc6XG4gICAgICBjYXNlICdpbWFnZS9qcGcnOlxuICAgICAgY2FzZSAnaW1hZ2UvcG5nJzpcbiAgICAgICAgaWYgKGZpbGUuc2l6ZSA+IDEwMDAwMDAwKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdTb3JyeSwgaW1hZ2VzIGFyZSBsaW1pdGVkIHRvIDEwIG1lZ2FieXRlcy4nKTtcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ2ltYWdlL2dpZic6XG4gICAgICAgIGlmIChmaWxlLnNpemUgPiA1MDAwMDAwMCkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcignU29ycnksIEdJRnMgYXJlIGxpbWl0ZWQgdG8gNTAgbWVnYWJ5dGVzLicpO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAndmlkZW8vbXA0JzpcbiAgICAgICAgaWYgKGZpbGUuc2l6ZSA+IDUwMDAwMDAwKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdTb3JyeSwgdmlkZW9zIGFyZSBsaW1pdGVkIHRvIDUwIG1lZ2FieXRlcy4nKTtcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihmaWxlLnR5cGUgKyAnIGlzIG5vdCBhIHN1cHBvcnRlZCBmaWxlIHR5cGUuIE9ubHksIC5qcGVnLCAucG5nLCAuZ2lmLCBhbmQgLm1wNCBmaWxlcyBhcmUgY3VycmVudGx5IHN1cHBvcnRlZC4nKTtcbiAgICB9XG4gIH0sXG59O1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vY2xpZW50L3V0aWxzL2ZpbGUuanMiLCJpbXBvcnQgUmVhY3QgZnJvbSAncmVhY3QnO1xuaW1wb3J0IFByb3BUeXBlcyBmcm9tICdwcm9wLXR5cGVzJztcblxuY2xhc3MgUHVibGlzaFByZXZpZXcgZXh0ZW5kcyBSZWFjdC5Db21wb25lbnQge1xuICBjb25zdHJ1Y3RvciAocHJvcHMpIHtcbiAgICBzdXBlcihwcm9wcyk7XG4gICAgdGhpcy5zdGF0ZSA9IHtcbiAgICAgIGltZ1NvdXJjZSAgICAgICA6ICcnLFxuICAgICAgZGVmYXVsdFRodW1ibmFpbDogJy9hc3NldHMvaW1nL3ZpZGVvX3RodW1iX2RlZmF1bHQucG5nJyxcbiAgICB9O1xuICB9XG4gIGNvbXBvbmVudERpZE1vdW50ICgpIHtcbiAgICB0aGlzLnNldFByZXZpZXdJbWFnZVNvdXJjZSh0aGlzLnByb3BzLmZpbGUpO1xuICB9XG4gIGNvbXBvbmVudFdpbGxSZWNlaXZlUHJvcHMgKG5ld1Byb3BzKSB7XG4gICAgaWYgKG5ld1Byb3BzLmZpbGUgIT09IHRoaXMucHJvcHMuZmlsZSkge1xuICAgICAgdGhpcy5zZXRQcmV2aWV3SW1hZ2VTb3VyY2UobmV3UHJvcHMuZmlsZSk7XG4gICAgfVxuICAgIGlmIChuZXdQcm9wcy50aHVtYm5haWwgIT09IHRoaXMucHJvcHMudGh1bWJuYWlsKSB7XG4gICAgICBpZiAobmV3UHJvcHMudGh1bWJuYWlsKSB7XG4gICAgICAgIHRoaXMuc2V0UHJldmlld0ltYWdlU291cmNlRnJvbUZpbGUobmV3UHJvcHMudGh1bWJuYWlsKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoe2ltZ1NvdXJjZTogdGhpcy5zdGF0ZS5kZWZhdWx0VGh1bWJuYWlsfSk7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIHNldFByZXZpZXdJbWFnZVNvdXJjZUZyb21GaWxlIChmaWxlKSB7XG4gICAgY29uc3QgcHJldmlld1JlYWRlciA9IG5ldyBGaWxlUmVhZGVyKCk7XG4gICAgcHJldmlld1JlYWRlci5yZWFkQXNEYXRhVVJMKGZpbGUpO1xuICAgIHByZXZpZXdSZWFkZXIub25sb2FkZW5kID0gKCkgPT4ge1xuICAgICAgdGhpcy5zZXRTdGF0ZSh7aW1nU291cmNlOiBwcmV2aWV3UmVhZGVyLnJlc3VsdH0pO1xuICAgIH07XG4gIH1cbiAgc2V0UHJldmlld0ltYWdlU291cmNlIChmaWxlKSB7XG4gICAgaWYgKGZpbGUudHlwZSAhPT0gJ3ZpZGVvL21wNCcpIHtcbiAgICAgIHRoaXMuc2V0UHJldmlld0ltYWdlU291cmNlRnJvbUZpbGUoZmlsZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmICh0aGlzLnByb3BzLnRodW1ibmFpbCkge1xuICAgICAgICB0aGlzLnNldFByZXZpZXdJbWFnZVNvdXJjZUZyb21GaWxlKHRoaXMucHJvcHMudGh1bWJuYWlsKTtcbiAgICAgIH1cbiAgICAgIHRoaXMuc2V0U3RhdGUoe2ltZ1NvdXJjZTogdGhpcy5zdGF0ZS5kZWZhdWx0VGh1bWJuYWlsfSk7XG4gICAgfVxuICB9XG4gIHJlbmRlciAoKSB7XG4gICAgcmV0dXJuIChcbiAgICAgIDxpbWdcbiAgICAgICAgaWQ9J2Ryb3B6b25lLXByZXZpZXcnXG4gICAgICAgIHNyYz17dGhpcy5zdGF0ZS5pbWdTb3VyY2V9XG4gICAgICAgIGNsYXNzTmFtZT17dGhpcy5wcm9wcy5kaW1QcmV2aWV3ID8gJ2RpbScgOiAnJ31cbiAgICAgICAgYWx0PSdwdWJsaXNoIHByZXZpZXcnXG4gICAgICAvPlxuICAgICk7XG4gIH1cbn07XG5cblB1Ymxpc2hQcmV2aWV3LnByb3BUeXBlcyA9IHtcbiAgZGltUHJldmlldzogUHJvcFR5cGVzLmJvb2wuaXNSZXF1aXJlZCxcbiAgZmlsZSAgICAgIDogUHJvcFR5cGVzLm9iamVjdC5pc1JlcXVpcmVkLFxuICB0aHVtYm5haWwgOiBQcm9wVHlwZXMub2JqZWN0LFxufTtcblxuZXhwb3J0IGRlZmF1bHQgUHVibGlzaFByZXZpZXc7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9jbGllbnQvY29tcG9uZW50cy9QdWJsaXNoUHJldmlldy9pbmRleC5qc3giLCJpbXBvcnQge2Nvbm5lY3R9IGZyb20gJ3JlYWN0LXJlZHV4JztcbmltcG9ydCB7Y2xlYXJGaWxlLCBzdGFydFB1Ymxpc2h9IGZyb20gJ2FjdGlvbnMvcHVibGlzaCc7XG5pbXBvcnQgVmlldyBmcm9tICcuL3ZpZXcnO1xuXG5jb25zdCBtYXBTdGF0ZVRvUHJvcHMgPSAoeyBjaGFubmVsLCBwdWJsaXNoIH0pID0+IHtcbiAgcmV0dXJuIHtcbiAgICBmaWxlOiBwdWJsaXNoLmZpbGUsXG4gIH07XG59O1xuXG5jb25zdCBtYXBEaXNwYXRjaFRvUHJvcHMgPSB7XG4gIGNsZWFyRmlsZSxcbiAgc3RhcnRQdWJsaXNoLFxufTtcblxuZXhwb3J0IGRlZmF1bHQgY29ubmVjdChtYXBTdGF0ZVRvUHJvcHMsIG1hcERpc3BhdGNoVG9Qcm9wcykoVmlldyk7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9jbGllbnQvY29udGFpbmVycy9QdWJsaXNoRGV0YWlscy9pbmRleC5qcyIsImltcG9ydCBSZWFjdCBmcm9tICdyZWFjdCc7XG5pbXBvcnQgeyB3aXRoUm91dGVyIH0gZnJvbSAncmVhY3Qtcm91dGVyLWRvbSc7XG5pbXBvcnQgRHJvcHpvbmUgZnJvbSAnY29udGFpbmVycy9Ecm9wem9uZSc7XG5pbXBvcnQgUHVibGlzaFRpdGxlSW5wdXQgZnJvbSAnY29udGFpbmVycy9QdWJsaXNoVGl0bGVJbnB1dCc7XG5pbXBvcnQgUHVibGlzaFVybElucHV0IGZyb20gJ2NvbnRhaW5lcnMvUHVibGlzaFVybElucHV0JztcbmltcG9ydCBQdWJsaXNoVGh1bWJuYWlsSW5wdXQgZnJvbSAnY29udGFpbmVycy9QdWJsaXNoVGh1bWJuYWlsSW5wdXQnO1xuaW1wb3J0IFB1Ymxpc2hNZXRhZGF0YUlucHV0cyBmcm9tICdjb250YWluZXJzL1B1Ymxpc2hNZXRhZGF0YUlucHV0cyc7XG5pbXBvcnQgQ2hhbm5lbFNlbGVjdCBmcm9tICdjb250YWluZXJzL0NoYW5uZWxTZWxlY3QnO1xuXG5jbGFzcyBQdWJsaXNoRGV0YWlscyBleHRlbmRzIFJlYWN0LkNvbXBvbmVudCB7XG4gIGNvbnN0cnVjdG9yIChwcm9wcykge1xuICAgIHN1cGVyKHByb3BzKVxuICAgIHRoaXMub25QdWJsaXNoU3VibWl0ID0gdGhpcy5vblB1Ymxpc2hTdWJtaXQuYmluZCh0aGlzKTtcbiAgfVxuICBvblB1Ymxpc2hTdWJtaXQgKCkge1xuICAgIHRoaXMucHJvcHMuc3RhcnRQdWJsaXNoKHRoaXMucHJvcHMuaGlzdG9yeSk7XG4gIH1cbiAgcmVuZGVyICgpIHtcbiAgICByZXR1cm4gKFxuICAgICAgPGRpdiBjbGFzc05hbWU9J3JvdyByb3ctLW5vLWJvdHRvbSc+XG4gICAgICAgIDxkaXYgY2xhc3NOYW1lPSdjb2x1bW4gY29sdW1uLS0xMCc+XG4gICAgICAgICAgPFB1Ymxpc2hUaXRsZUlucHV0IC8+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICB7LyogbGVmdCBjb2x1bW4gKi99XG4gICAgICAgIDxkaXYgY2xhc3NOYW1lPSdjb2x1bW4gY29sdW1uLS01IGNvbHVtbi0tc21sLTEwJyA+XG4gICAgICAgICAgPGRpdiBjbGFzc05hbWU9J3JvdyByb3ctLXBhZGRlZCc+XG4gICAgICAgICAgICA8RHJvcHpvbmUgLz5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIHsvKiByaWdodCBjb2x1bW4gKi99XG4gICAgICAgIDxkaXYgY2xhc3NOYW1lPSdjb2x1bW4gY29sdW1uLS01IGNvbHVtbi0tc21sLTEwIGFsaWduLWNvbnRlbnQtdG9wJz5cbiAgICAgICAgICA8ZGl2IGlkPSdwdWJsaXNoLWFjdGl2ZS1hcmVhJyBjbGFzc05hbWU9J3JvdyByb3ctLXBhZGRlZCc+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT0ncm93IHJvdy0tcGFkZGVkIHJvdy0tbm8tdG9wIHJvdy0td2lkZSc+XG4gICAgICAgICAgICAgIDxQdWJsaXNoVXJsSW5wdXQgLz5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9J3JvdyByb3ctLXBhZGRlZCByb3ctLW5vLXRvcCByb3ctLXdpZGUnPlxuICAgICAgICAgICAgICA8Q2hhbm5lbFNlbGVjdCAvPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICB7ICh0aGlzLnByb3BzLmZpbGUudHlwZSA9PT0gJ3ZpZGVvL21wNCcpICYmIChcbiAgICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9J3JvdyByb3ctLXBhZGRlZCByb3ctLW5vLXRvcCByb3ctLXdpZGUgJz5cbiAgICAgICAgICAgICAgICA8UHVibGlzaFRodW1ibmFpbElucHV0IC8+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgKX1cbiAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPSdyb3cgcm93LS1wYWRkZWQgcm93LS1uby10b3Agcm93LS1uby1ib3R0b20gcm93LS13aWRlJz5cbiAgICAgICAgICAgICAgPFB1Ymxpc2hNZXRhZGF0YUlucHV0cyAvPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT0ncm93IHJvdy0td2lkZSBhbGlnbi1jb250ZW50LWNlbnRlcic+XG4gICAgICAgICAgICAgIDxidXR0b24gaWQ9J3B1Ymxpc2gtc3VibWl0JyBjbGFzc05hbWU9J2J1dHRvbi0tcHJpbWFyeSBidXR0b24tLWxhcmdlJyBvbkNsaWNrPXt0aGlzLm9uUHVibGlzaFN1Ym1pdH0+UHVibGlzaDwvYnV0dG9uPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT0ncm93IHJvdy0tcGFkZGVkIHJvdy0tbm8tYm90dG9tIGFsaWduLWNvbnRlbnQtY2VudGVyJz5cbiAgICAgICAgICAgICAgPGJ1dHRvbiBjbGFzc05hbWU9J2J1dHRvbi0tY2FuY2VsJyBvbkNsaWNrPXt0aGlzLnByb3BzLmNsZWFyRmlsZX0+Q2FuY2VsPC9idXR0b24+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPSdyb3cgcm93LS1zaG9ydCBhbGlnbi1jb250ZW50LWNlbnRlcic+XG4gICAgICAgICAgICAgIDxwIGNsYXNzTmFtZT0nZmluZS1wcmludCc+QnkgY2xpY2tpbmcgJ1B1Ymxpc2gnLCB5b3UgYWZmaXJtIHRoYXQgeW91IGhhdmUgdGhlIHJpZ2h0cyB0byBwdWJsaXNoIHRoaXMgY29udGVudCB0byB0aGUgTEJSWSBuZXR3b3JrLCBhbmQgdGhhdCB5b3UgdW5kZXJzdGFuZCB0aGUgcHJvcGVydGllcyBvZiBwdWJsaXNoaW5nIGl0IHRvIGEgZGVjZW50cmFsaXplZCwgdXNlci1jb250cm9sbGVkIG5ldHdvcmsuIDxhIGNsYXNzTmFtZT0nbGluay0tcHJpbWFyeScgdGFyZ2V0PSdfYmxhbmsnIGhyZWY9J2h0dHBzOi8vbGJyeS5pby9sZWFybic+UmVhZCBtb3JlLjwvYT48L3A+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cbiAgICApO1xuICB9XG59O1xuXG5leHBvcnQgZGVmYXVsdCB3aXRoUm91dGVyKFB1Ymxpc2hEZXRhaWxzKTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL2NsaWVudC9jb250YWluZXJzL1B1Ymxpc2hEZXRhaWxzL3ZpZXcuanN4IiwiaW1wb3J0IHtjb25uZWN0fSBmcm9tICdyZWFjdC1yZWR1eCc7XG5pbXBvcnQge3VwZGF0ZU1ldGFkYXRhfSBmcm9tICdhY3Rpb25zL3B1Ymxpc2gnO1xuaW1wb3J0IFZpZXcgZnJvbSAnLi92aWV3JztcblxuY29uc3QgbWFwU3RhdGVUb1Byb3BzID0gKHsgcHVibGlzaCB9KSA9PiB7XG4gIHJldHVybiB7XG4gICAgdGl0bGU6IHB1Ymxpc2gubWV0YWRhdGEudGl0bGUsXG4gIH07XG59O1xuXG5jb25zdCBtYXBEaXNwYXRjaFRvUHJvcHMgPSBkaXNwYXRjaCA9PiB7XG4gIHJldHVybiB7XG4gICAgb25NZXRhZGF0YUNoYW5nZTogKG5hbWUsIHZhbHVlKSA9PiB7XG4gICAgICBkaXNwYXRjaCh1cGRhdGVNZXRhZGF0YShuYW1lLCB2YWx1ZSkpO1xuICAgIH0sXG4gIH07XG59O1xuXG5leHBvcnQgZGVmYXVsdCBjb25uZWN0KG1hcFN0YXRlVG9Qcm9wcywgbWFwRGlzcGF0Y2hUb1Byb3BzKShWaWV3KTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL2NsaWVudC9jb250YWluZXJzL1B1Ymxpc2hUaXRsZUlucHV0L2luZGV4LmpzIiwiaW1wb3J0IFJlYWN0IGZyb20gJ3JlYWN0JztcblxuY2xhc3MgUHVibGlzaFRpdGxlSW5wdXQgZXh0ZW5kcyBSZWFjdC5Db21wb25lbnQge1xuICBjb25zdHJ1Y3RvciAocHJvcHMpIHtcbiAgICBzdXBlcihwcm9wcyk7XG4gICAgdGhpcy5oYW5kbGVJbnB1dCA9IHRoaXMuaGFuZGxlSW5wdXQuYmluZCh0aGlzKTtcbiAgfVxuICBoYW5kbGVJbnB1dCAoZSkge1xuICAgIGNvbnN0IG5hbWUgPSBlLnRhcmdldC5uYW1lO1xuICAgIGNvbnN0IHZhbHVlID0gZS50YXJnZXQudmFsdWU7XG4gICAgdGhpcy5wcm9wcy5vbk1ldGFkYXRhQ2hhbmdlKG5hbWUsIHZhbHVlKTtcbiAgfVxuICByZW5kZXIgKCkge1xuICAgIHJldHVybiAoXG4gICAgICA8aW5wdXQgdHlwZT0ndGV4dCcgaWQ9J3B1Ymxpc2gtdGl0bGUnIGNsYXNzTmFtZT0naW5wdXQtdGV4dCB0ZXh0LS1sYXJnZSBpbnB1dC10ZXh0LS1mdWxsLXdpZHRoJyBuYW1lPSd0aXRsZScgcGxhY2Vob2xkZXI9J0dpdmUgeW91ciBwb3N0IGEgdGl0bGUuLi4nIG9uQ2hhbmdlPXt0aGlzLmhhbmRsZUlucHV0fSB2YWx1ZT17dGhpcy5wcm9wcy50aXRsZX0gLz5cbiAgICApO1xuICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IFB1Ymxpc2hUaXRsZUlucHV0O1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vY2xpZW50L2NvbnRhaW5lcnMvUHVibGlzaFRpdGxlSW5wdXQvdmlldy5qc3giLCJpbXBvcnQge3VwZGF0ZUNsYWltLCB1cGRhdGVFcnJvcn0gZnJvbSAnYWN0aW9ucy9wdWJsaXNoJztcbmltcG9ydCB7Y29ubmVjdH0gZnJvbSAncmVhY3QtcmVkdXgnO1xuaW1wb3J0IFZpZXcgZnJvbSAnLi92aWV3JztcblxuY29uc3QgbWFwU3RhdGVUb1Byb3BzID0gKHsgY2hhbm5lbCwgcHVibGlzaCB9KSA9PiB7XG4gIHJldHVybiB7XG4gICAgbG9nZ2VkSW5DaGFubmVsTmFtZSAgIDogY2hhbm5lbC5sb2dnZWRJbkNoYW5uZWwubmFtZSxcbiAgICBsb2dnZWRJbkNoYW5uZWxTaG9ydElkOiBjaGFubmVsLmxvZ2dlZEluQ2hhbm5lbC5zaG9ydElkLFxuICAgIGZpbGVOYW1lICAgICAgICAgICAgICA6IHB1Ymxpc2guZmlsZS5uYW1lLFxuICAgIHB1Ymxpc2hJbkNoYW5uZWwgICAgICA6IHB1Ymxpc2gucHVibGlzaEluQ2hhbm5lbCxcbiAgICBzZWxlY3RlZENoYW5uZWwgICAgICAgOiBwdWJsaXNoLnNlbGVjdGVkQ2hhbm5lbCxcbiAgICBjbGFpbSAgICAgICAgICAgICAgICAgOiBwdWJsaXNoLmNsYWltLFxuICAgIHVybEVycm9yICAgICAgICAgICAgICA6IHB1Ymxpc2guZXJyb3IudXJsLFxuICB9O1xufTtcblxuY29uc3QgbWFwRGlzcGF0Y2hUb1Byb3BzID0gZGlzcGF0Y2ggPT4ge1xuICByZXR1cm4ge1xuICAgIG9uQ2xhaW1DaGFuZ2U6ICh2YWx1ZSkgPT4ge1xuICAgICAgZGlzcGF0Y2godXBkYXRlQ2xhaW0odmFsdWUpKTtcbiAgICAgIGRpc3BhdGNoKHVwZGF0ZUVycm9yKCdwdWJsaXNoU3VibWl0JywgbnVsbCkpO1xuICAgIH0sXG4gICAgb25VcmxFcnJvcjogKHZhbHVlKSA9PiB7XG4gICAgICBkaXNwYXRjaCh1cGRhdGVFcnJvcigndXJsJywgdmFsdWUpKTtcbiAgICB9LFxuICB9O1xufTtcblxuZXhwb3J0IGRlZmF1bHQgY29ubmVjdChtYXBTdGF0ZVRvUHJvcHMsIG1hcERpc3BhdGNoVG9Qcm9wcykoVmlldyk7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9jbGllbnQvY29udGFpbmVycy9QdWJsaXNoVXJsSW5wdXQvaW5kZXguanMiLCJpbXBvcnQgUmVhY3QgZnJvbSAncmVhY3QnO1xuaW1wb3J0IHJlcXVlc3QgZnJvbSAndXRpbHMvcmVxdWVzdCc7XG5pbXBvcnQgVXJsTWlkZGxlIGZyb20gJ2NvbXBvbmVudHMvUHVibGlzaFVybE1pZGRsZURpc3BsYXknO1xuXG5jbGFzcyBQdWJsaXNoVXJsSW5wdXQgZXh0ZW5kcyBSZWFjdC5Db21wb25lbnQge1xuICBjb25zdHJ1Y3RvciAocHJvcHMpIHtcbiAgICBzdXBlcihwcm9wcyk7XG4gICAgdGhpcy5oYW5kbGVJbnB1dCA9IHRoaXMuaGFuZGxlSW5wdXQuYmluZCh0aGlzKTtcbiAgfVxuICBjb21wb25lbnREaWRNb3VudCAoKSB7XG4gICAgY29uc3QgeyBjbGFpbSwgZmlsZU5hbWUgfSA9IHRoaXMucHJvcHM7XG4gICAgaWYgKCFjbGFpbSkge1xuICAgICAgdGhpcy5zZXRDbGFpbU5hbWUoZmlsZU5hbWUpO1xuICAgIH1cbiAgfVxuICBjb21wb25lbnRXaWxsUmVjZWl2ZVByb3BzICh7IGNsYWltLCBmaWxlTmFtZSB9KSB7XG4gICAgLy8gaWYgYSBuZXcgZmlsZSB3YXMgY2hvc2VuLCB1cGRhdGUgdGhlIGNsYWltIG5hbWVcbiAgICBpZiAoZmlsZU5hbWUgIT09IHRoaXMucHJvcHMuZmlsZU5hbWUpIHtcbiAgICAgIHJldHVybiB0aGlzLnNldENsYWltTmFtZShmaWxlTmFtZSk7XG4gICAgfVxuICAgIC8vIGlmIHRoZSBjbGFpbSBoYXMgdXBkYXRlZCwgY2hlY2sgaXRzIGF2YWlsYWJpbGl0eVxuICAgIGlmIChjbGFpbSAhPT0gdGhpcy5wcm9wcy5jbGFpbSkge1xuICAgICAgdGhpcy52YWxpZGF0ZUNsYWltKGNsYWltKTtcbiAgICB9XG4gIH1cbiAgaGFuZGxlSW5wdXQgKGV2ZW50KSB7XG4gICAgbGV0IHZhbHVlID0gZXZlbnQudGFyZ2V0LnZhbHVlO1xuICAgIHZhbHVlID0gdGhpcy5jbGVhbnNlSW5wdXQodmFsdWUpO1xuICAgIC8vIHVwZGF0ZSB0aGUgc3RhdGVcbiAgICB0aGlzLnByb3BzLm9uQ2xhaW1DaGFuZ2UodmFsdWUpO1xuICB9XG4gIGNsZWFuc2VJbnB1dCAoaW5wdXQpIHtcbiAgICBpbnB1dCA9IGlucHV0LnJlcGxhY2UoL1xccysvZywgJy0nKTsgLy8gcmVwbGFjZSBzcGFjZXMgd2l0aCBkYXNoZXNcbiAgICBpbnB1dCA9IGlucHV0LnJlcGxhY2UoL1teQS1aYS16MC05LV0vZywgJycpOyAgLy8gcmVtb3ZlIGFsbCBjaGFyYWN0ZXJzIHRoYXQgYXJlIG5vdCBBLVosIGEteiwgMC05LCBvciAnLSdcbiAgICByZXR1cm4gaW5wdXQ7XG4gIH1cbiAgc2V0Q2xhaW1OYW1lIChmaWxlTmFtZSkge1xuICAgIGNvbnN0IGZpbGVOYW1lV2l0aG91dEVuZGluZyA9IGZpbGVOYW1lLnN1YnN0cmluZygwLCBmaWxlTmFtZS5sYXN0SW5kZXhPZignLicpKTtcbiAgICBjb25zdCBjbGVhbkNsYWltTmFtZSA9IHRoaXMuY2xlYW5zZUlucHV0KGZpbGVOYW1lV2l0aG91dEVuZGluZyk7XG4gICAgdGhpcy5wcm9wcy5vbkNsYWltQ2hhbmdlKGNsZWFuQ2xhaW1OYW1lKTtcbiAgfVxuICB2YWxpZGF0ZUNsYWltIChjbGFpbSkge1xuICAgIGlmICghY2xhaW0pIHtcbiAgICAgIHJldHVybiB0aGlzLnByb3BzLm9uVXJsRXJyb3IoJ0VudGVyIGEgdXJsIGFib3ZlJyk7XG4gICAgfVxuICAgIHJlcXVlc3QoYC9hcGkvY2xhaW0vYXZhaWxhYmlsaXR5LyR7Y2xhaW19YClcbiAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgdGhpcy5wcm9wcy5vblVybEVycm9yKG51bGwpO1xuICAgICAgfSlcbiAgICAgIC5jYXRjaCgoZXJyb3IpID0+IHtcbiAgICAgICAgdGhpcy5wcm9wcy5vblVybEVycm9yKGVycm9yLm1lc3NhZ2UpO1xuICAgICAgfSk7XG4gIH1cbiAgcmVuZGVyICgpIHtcbiAgICBjb25zdCB7IGNsYWltLCBsb2dnZWRJbkNoYW5uZWxOYW1lLCBsb2dnZWRJbkNoYW5uZWxTaG9ydElkLCBwdWJsaXNoSW5DaGFubmVsLCBzZWxlY3RlZENoYW5uZWwsIHVybEVycm9yIH0gPSB0aGlzLnByb3BzO1xuICAgIHJldHVybiAoXG4gICAgICA8ZGl2IGNsYXNzTmFtZT0nY29sdW1uIGNvbHVtbi0tMTAgY29sdW1uLS1zbWwtMTAnPlxuICAgICAgICA8ZGl2IGNsYXNzTmFtZT0naW5wdXQtdGV4dC0tcHJpbWFyeSBzcGFuLS1yZWxhdGl2ZSc+XG4gICAgICAgICAgPHNwYW4gY2xhc3NOYW1lPSd1cmwtdGV4dC0tc2Vjb25kYXJ5Jz5zcGVlLmNoIC8gPC9zcGFuPlxuICAgICAgICAgIDxVcmxNaWRkbGVcbiAgICAgICAgICAgIHB1Ymxpc2hJbkNoYW5uZWw9e3B1Ymxpc2hJbkNoYW5uZWx9XG4gICAgICAgICAgICBzZWxlY3RlZENoYW5uZWw9e3NlbGVjdGVkQ2hhbm5lbH1cbiAgICAgICAgICAgIGxvZ2dlZEluQ2hhbm5lbE5hbWU9e2xvZ2dlZEluQ2hhbm5lbE5hbWV9XG4gICAgICAgICAgICBsb2dnZWRJbkNoYW5uZWxTaG9ydElkPXtsb2dnZWRJbkNoYW5uZWxTaG9ydElkfVxuICAgICAgICAgIC8+XG4gICAgICAgICAgPGlucHV0IHR5cGU9J3RleHQnIGlkPSdjbGFpbS1uYW1lLWlucHV0JyBjbGFzc05hbWU9J2lucHV0LXRleHQnIG5hbWU9J2NsYWltJyBwbGFjZWhvbGRlcj0neW91ci11cmwtaGVyZScgb25DaGFuZ2U9e3RoaXMuaGFuZGxlSW5wdXR9IHZhbHVlPXtjbGFpbX0gLz5cbiAgICAgICAgICB7IChjbGFpbSAmJiAhdXJsRXJyb3IpICYmIDxzcGFuIGlkPSdpbnB1dC1zdWNjZXNzLWNsYWltLW5hbWUnIGNsYXNzTmFtZT0naW5mby1tZXNzYWdlLS1zdWNjZXNzIHNwYW4tLWFic29sdXRlJz57J1xcdTI3MTMnfTwvc3Bhbj4gfVxuICAgICAgICAgIHsgdXJsRXJyb3IgJiYgPHNwYW4gaWQ9J2lucHV0LXN1Y2Nlc3MtY2hhbm5lbC1uYW1lJyBjbGFzc05hbWU9J2luZm8tbWVzc2FnZS0tZmFpbHVyZSBzcGFuLS1hYnNvbHV0ZSc+eydcXHUyNzE2J308L3NwYW4+IH1cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIDxkaXY+XG4gICAgICAgICAgeyB1cmxFcnJvciA/IChcbiAgICAgICAgICAgIDxwIGlkPSdpbnB1dC1lcnJvci1jbGFpbS1uYW1lJyBjbGFzc05hbWU9J2luZm8tbWVzc2FnZS0tZmFpbHVyZSc+e3VybEVycm9yfTwvcD5cbiAgICAgICAgICApIDogKFxuICAgICAgICAgICAgPHAgY2xhc3NOYW1lPSdpbmZvLW1lc3NhZ2UnPkNob29zZSBhIGN1c3RvbSB1cmw8L3A+XG4gICAgICAgICAgKX1cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cbiAgICApO1xuICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IFB1Ymxpc2hVcmxJbnB1dDtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL2NsaWVudC9jb250YWluZXJzL1B1Ymxpc2hVcmxJbnB1dC92aWV3LmpzeCIsImltcG9ydCBSZWFjdCBmcm9tICdyZWFjdCc7XG5pbXBvcnQgUHJvcFR5cGVzIGZyb20gJ3Byb3AtdHlwZXMnO1xuXG5mdW5jdGlvbiBVcmxNaWRkbGUgKHtwdWJsaXNoSW5DaGFubmVsLCBzZWxlY3RlZENoYW5uZWwsIGxvZ2dlZEluQ2hhbm5lbE5hbWUsIGxvZ2dlZEluQ2hhbm5lbFNob3J0SWR9KSB7XG4gIGlmIChwdWJsaXNoSW5DaGFubmVsKSB7XG4gICAgaWYgKHNlbGVjdGVkQ2hhbm5lbCA9PT0gbG9nZ2VkSW5DaGFubmVsTmFtZSkge1xuICAgICAgcmV0dXJuIDxzcGFuIGlkPSd1cmwtY2hhbm5lbCcgY2xhc3NOYW1lPSd1cmwtdGV4dC0tc2Vjb25kYXJ5Jz57bG9nZ2VkSW5DaGFubmVsTmFtZX06e2xvZ2dlZEluQ2hhbm5lbFNob3J0SWR9IC88L3NwYW4+O1xuICAgIH1cbiAgICByZXR1cm4gPHNwYW4gaWQ9J3VybC1jaGFubmVsLXBsYWNlaG9sZGVyJyBjbGFzc05hbWU9J3VybC10ZXh0LS1zZWNvbmRhcnkgdG9vbHRpcCc+QGNoYW5uZWw8c3BhblxuICAgICAgY2xhc3NOYW1lPSd0b29sdGlwLXRleHQnPlNlbGVjdCBhIGNoYW5uZWwgYmVsb3c8L3NwYW4+IC88L3NwYW4+O1xuICB9XG4gIHJldHVybiAoXG4gICAgPHNwYW4gaWQ9J3VybC1uby1jaGFubmVsLXBsYWNlaG9sZGVyJyBjbGFzc05hbWU9J3VybC10ZXh0LS1zZWNvbmRhcnkgdG9vbHRpcCc+eHl6PHNwYW4gY2xhc3NOYW1lPSd0b29sdGlwLXRleHQnPlRoaXMgd2lsbCBiZSBhIHJhbmRvbSBpZDwvc3Bhbj4gLzwvc3Bhbj5cbiAgKTtcbn1cblxuVXJsTWlkZGxlLnByb3BUeXBlcyA9IHtcbiAgcHVibGlzaEluQ2hhbm5lbCAgICAgIDogUHJvcFR5cGVzLmJvb2wuaXNSZXF1aXJlZCxcbiAgbG9nZ2VkSW5DaGFubmVsTmFtZSAgIDogUHJvcFR5cGVzLnN0cmluZyxcbiAgbG9nZ2VkSW5DaGFubmVsU2hvcnRJZDogUHJvcFR5cGVzLnN0cmluZyxcbn07XG5cbmV4cG9ydCBkZWZhdWx0IFVybE1pZGRsZTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL2NsaWVudC9jb21wb25lbnRzL1B1Ymxpc2hVcmxNaWRkbGVEaXNwbGF5L2luZGV4LmpzeCIsImltcG9ydCB7IGNvbm5lY3QgfSBmcm9tICdyZWFjdC1yZWR1eCc7XG5pbXBvcnQgeyBvbk5ld1RodW1ibmFpbCB9IGZyb20gJ2FjdGlvbnMvcHVibGlzaCc7XG5pbXBvcnQgVmlldyBmcm9tICcuL3ZpZXcnO1xuXG5jb25zdCBtYXBTdGF0ZVRvUHJvcHMgPSAoeyBwdWJsaXNoOiB7IGZpbGUgfSB9KSA9PiB7XG4gIHJldHVybiB7XG4gICAgZmlsZSxcbiAgfTtcbn07XG5cbmNvbnN0IG1hcERpc3BhdGNoVG9Qcm9wcyA9IHtcbiAgb25OZXdUaHVtYm5haWwsXG59O1xuXG5leHBvcnQgZGVmYXVsdCBjb25uZWN0KG1hcFN0YXRlVG9Qcm9wcywgbWFwRGlzcGF0Y2hUb1Byb3BzKShWaWV3KTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL2NsaWVudC9jb250YWluZXJzL1B1Ymxpc2hUaHVtYm5haWxJbnB1dC9pbmRleC5qcyIsImltcG9ydCBSZWFjdCBmcm9tICdyZWFjdCc7XG5cbmZ1bmN0aW9uIGRhdGFVUkl0b0Jsb2IoZGF0YVVSSSkge1xuICAvLyBjb252ZXJ0IGJhc2U2NC9VUkxFbmNvZGVkIGRhdGEgY29tcG9uZW50IHRvIHJhdyBiaW5hcnkgZGF0YSBoZWxkIGluIGEgc3RyaW5nXG4gIGxldCBieXRlU3RyaW5nID0gYXRvYihkYXRhVVJJLnNwbGl0KCcsJylbMV0pO1xuICAvLyBzZXBhcmF0ZSBvdXQgdGhlIG1pbWUgY29tcG9uZW50XG4gIGxldCBtaW1lU3RyaW5nID0gZGF0YVVSSS5zcGxpdCgnLCcpWzBdLnNwbGl0KCc6JylbMV0uc3BsaXQoJzsnKVswXTtcbiAgLy8gd3JpdGUgdGhlIGJ5dGVzIG9mIHRoZSBzdHJpbmcgdG8gYSB0eXBlZCBhcnJheVxuICBsZXQgaWEgPSBuZXcgVWludDhBcnJheShieXRlU3RyaW5nLmxlbmd0aCk7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgYnl0ZVN0cmluZy5sZW5ndGg7IGkrKykge1xuICAgIGlhW2ldID0gYnl0ZVN0cmluZy5jaGFyQ29kZUF0KGkpO1xuICB9XG4gIHJldHVybiBuZXcgQmxvYihbaWFdLCB7dHlwZTogbWltZVN0cmluZ30pO1xufVxuXG5jbGFzcyBQdWJsaXNoVGh1bWJuYWlsSW5wdXQgZXh0ZW5kcyBSZWFjdC5Db21wb25lbnQge1xuICBjb25zdHJ1Y3RvciAocHJvcHMpIHtcbiAgICBzdXBlcihwcm9wcyk7XG4gICAgdGhpcy5zdGF0ZSA9IHtcbiAgICAgIHZpZGVvU291cmNlICAgOiBudWxsLFxuICAgICAgZXJyb3IgICAgICAgICA6IG51bGwsXG4gICAgICBzbGlkZXJNaW5SYW5nZTogMSxcbiAgICAgIHNsaWRlck1heFJhbmdlOiBudWxsLFxuICAgICAgc2xpZGVyVmFsdWUgICA6IG51bGwsXG4gICAgfTtcbiAgICB0aGlzLmhhbmRsZVZpZGVvTG9hZGVkRGF0YSA9IHRoaXMuaGFuZGxlVmlkZW9Mb2FkZWREYXRhLmJpbmQodGhpcyk7XG4gICAgdGhpcy5oYW5kbGVTbGlkZXJDaGFuZ2UgPSB0aGlzLmhhbmRsZVNsaWRlckNoYW5nZS5iaW5kKHRoaXMpO1xuICAgIHRoaXMuY3JlYXRlVGh1bWJuYWlsID0gdGhpcy5jcmVhdGVUaHVtYm5haWwuYmluZCh0aGlzKTtcbiAgfVxuICBjb21wb25lbnREaWRNb3VudCAoKSB7XG4gICAgY29uc3QgeyBmaWxlIH0gPSB0aGlzLnByb3BzO1xuICAgIHRoaXMuc2V0VmlkZW9Tb3VyY2UoZmlsZSk7XG4gIH1cbiAgY29tcG9uZW50V2lsbFJlY2VpdmVQcm9wcyAobmV4dFByb3BzKSB7XG4gICAgLy8gaWYgZmlsZSBjaGFuZ2VzXG4gICAgaWYgKG5leHRQcm9wcy5maWxlICYmIG5leHRQcm9wcy5maWxlICE9PSB0aGlzLnByb3BzLmZpbGUpIHtcbiAgICAgIGNvbnN0IHsgZmlsZSB9ID0gbmV4dFByb3BzO1xuICAgICAgdGhpcy5zZXRWaWRlb1NvdXJjZShmaWxlKTtcbiAgICB9O1xuICB9XG4gIHNldFZpZGVvU291cmNlIChmaWxlKSB7XG4gICAgY29uc3QgcHJldmlld1JlYWRlciA9IG5ldyBGaWxlUmVhZGVyKCk7XG4gICAgcHJldmlld1JlYWRlci5yZWFkQXNEYXRhVVJMKGZpbGUpO1xuICAgIHByZXZpZXdSZWFkZXIub25sb2FkZW5kID0gKCkgPT4ge1xuICAgICAgY29uc3QgZGF0YVVyaSA9IHByZXZpZXdSZWFkZXIucmVzdWx0O1xuICAgICAgY29uc3QgYmxvYiA9IGRhdGFVUkl0b0Jsb2IoZGF0YVVyaSk7XG4gICAgICBjb25zdCB2aWRlb1NvdXJjZSA9IFVSTC5jcmVhdGVPYmplY3RVUkwoYmxvYik7XG4gICAgICB0aGlzLnNldFN0YXRlKHsgdmlkZW9Tb3VyY2UgfSk7XG4gICAgfTtcbiAgfVxuICBoYW5kbGVWaWRlb0xvYWRlZERhdGEgKGV2ZW50KSB7XG4gICAgY29uc3QgZHVyYXRpb24gPSBldmVudC50YXJnZXQuZHVyYXRpb247XG4gICAgY29uc3QgdG90YWxNaW51dGVzID0gTWF0aC5mbG9vcihkdXJhdGlvbiAvIDYwKTtcbiAgICBjb25zdCB0b3RhbFNlY29uZHMgPSBNYXRoLmZsb29yKGR1cmF0aW9uICUgNjApO1xuICAgIC8vIHNldCB0aGUgc2xpZGVyXG4gICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICBzbGlkZXJNYXhSYW5nZTogZHVyYXRpb24gKiAxMDAsXG4gICAgICBzbGlkZXJWYWx1ZSAgIDogZHVyYXRpb24gKiAxMDAgLyAyLFxuICAgICAgdG90YWxNaW51dGVzLFxuICAgICAgdG90YWxTZWNvbmRzLFxuICAgIH0pO1xuICAgIC8vIHVwZGF0ZSB0aGUgY3VycmVudCB0aW1lIG9mIHRoZSB2aWRlb1xuICAgIGxldCB2aWRlbyA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCd2aWRlby10aHVtYi1wbGF5ZXInKTtcbiAgICB2aWRlby5jdXJyZW50VGltZSA9IGR1cmF0aW9uIC8gMjtcbiAgfVxuICBoYW5kbGVTbGlkZXJDaGFuZ2UgKGV2ZW50KSB7XG4gICAgY29uc3QgdmFsdWUgPSBwYXJzZUludChldmVudC50YXJnZXQudmFsdWUpO1xuICAgIC8vIHVwZGF0ZSB0aGUgc2xpZGVyIHZhbHVlXG4gICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICBzbGlkZXJWYWx1ZTogdmFsdWUsXG4gICAgfSk7XG4gICAgLy8gdXBkYXRlIHRoZSBjdXJyZW50IHRpbWUgb2YgdGhlIHZpZGVvXG4gICAgbGV0IHZpZGVvID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3ZpZGVvLXRodW1iLXBsYXllcicpO1xuICAgIHZpZGVvLmN1cnJlbnRUaW1lID0gdmFsdWUgLyAxMDA7XG4gIH1cbiAgY3JlYXRlVGh1bWJuYWlsICgpIHtcbiAgICAvLyB0YWtlIGEgc25hcHNob3RcbiAgICBsZXQgdmlkZW8gPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgndmlkZW8tdGh1bWItcGxheWVyJyk7XG4gICAgbGV0IGNhbnZhcyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2NhbnZhcycpO1xuICAgIGNhbnZhcy53aWR0aCA9IHZpZGVvLnZpZGVvV2lkdGg7XG4gICAgY2FudmFzLmhlaWdodCA9IHZpZGVvLnZpZGVvSGVpZ2h0O1xuICAgIGNhbnZhcy5nZXRDb250ZXh0KCcyZCcpLmRyYXdJbWFnZSh2aWRlbywgMCwgMCwgY2FudmFzLndpZHRoLCBjYW52YXMuaGVpZ2h0KTtcbiAgICBjb25zdCBkYXRhVXJsID0gY2FudmFzLnRvRGF0YVVSTCgpO1xuICAgIGNvbnN0IGJsb2IgPSBkYXRhVVJJdG9CbG9iKGRhdGFVcmwpO1xuICAgIGNvbnN0IHNuYXBzaG90ID0gbmV3IEZpbGUoW2Jsb2JdLCBgdGh1bWJuYWlsLnBuZ2AsIHtcbiAgICAgIHR5cGU6ICdpbWFnZS9wbmcnLFxuICAgIH0pO1xuICAgIC8vIHNldCB0aGUgdGh1bWJuYWlsIGluIHJlZHV4IHN0b3JlXG4gICAgaWYgKHNuYXBzaG90KSB7XG4gICAgICB0aGlzLnByb3BzLm9uTmV3VGh1bWJuYWlsKHNuYXBzaG90KTtcbiAgICB9XG4gIH1cbiAgcmVuZGVyICgpIHtcbiAgICBjb25zdCB7IGVycm9yLCB2aWRlb1NvdXJjZSwgc2xpZGVyTWluUmFuZ2UsIHNsaWRlck1heFJhbmdlLCBzbGlkZXJWYWx1ZSwgdG90YWxNaW51dGVzLCB0b3RhbFNlY29uZHMgfSA9IHRoaXMuc3RhdGU7XG4gICAgcmV0dXJuIChcbiAgICAgIDxkaXY+XG4gICAgICAgIDxsYWJlbCBjbGFzc05hbWU9J2xhYmVsJz5UaHVtYm5haWw6PC9sYWJlbD5cbiAgICAgICAgPHZpZGVvXG4gICAgICAgICAgaWQ9J3ZpZGVvLXRodW1iLXBsYXllcidcbiAgICAgICAgICBwcmVsb2FkPSdtZXRhZGF0YSdcbiAgICAgICAgICBtdXRlZFxuICAgICAgICAgIHN0eWxlPXt7ZGlzcGxheTogJ25vbmUnfX1cbiAgICAgICAgICBwbGF5c0lubGluZVxuICAgICAgICAgIG9uTG9hZGVkRGF0YT17dGhpcy5oYW5kbGVWaWRlb0xvYWRlZERhdGF9XG4gICAgICAgICAgc3JjPXt2aWRlb1NvdXJjZX1cbiAgICAgICAgICBvblNlZWtlZD17dGhpcy5jcmVhdGVUaHVtYm5haWx9XG4gICAgICAgIC8+XG4gICAgICAgIHtcbiAgICAgICAgICBzbGlkZXJWYWx1ZSA/IChcbiAgICAgICAgICAgIDxkaXY+XG4gICAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPSdmbGV4LWNvbnRhaW5lci0tcm93IGZsZXgtY29udGFpbmVyLS1zcGFjZS1iZXR3ZWVuLWNlbnRlcicgc3R5bGU9e3t3aWR0aDogJzEwMCUnfX0+XG4gICAgICAgICAgICAgICAgPHNwYW4gY2xhc3NOYW1lPSdpbmZvLW1lc3NhZ2UnPjAnMDBcIjwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8c3BhbiBjbGFzc05hbWU9J2luZm8tbWVzc2FnZSc+e3RvdGFsTWludXRlc30ne3RvdGFsU2Vjb25kc31cIjwvc3Bhbj5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgIDxkaXY+XG4gICAgICAgICAgICAgICAgPGlucHV0XG4gICAgICAgICAgICAgICAgICB0eXBlPSdyYW5nZSdcbiAgICAgICAgICAgICAgICAgIG1pbj17c2xpZGVyTWluUmFuZ2V9XG4gICAgICAgICAgICAgICAgICBtYXg9e3NsaWRlck1heFJhbmdlfVxuICAgICAgICAgICAgICAgICAgdmFsdWU9e3NsaWRlclZhbHVlfVxuICAgICAgICAgICAgICAgICAgY2xhc3NOYW1lPSdzbGlkZXInXG4gICAgICAgICAgICAgICAgICBvbkNoYW5nZT17dGhpcy5oYW5kbGVTbGlkZXJDaGFuZ2V9XG4gICAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICApIDogKFxuICAgICAgICAgICAgPHAgY2xhc3NOYW1lPSdpbmZvLW1lc3NhZ2UnID5sb2FkaW5nLi4uIDwvcD5cbiAgICAgICAgICApXG4gICAgICAgIH1cbiAgICAgICAgeyBlcnJvciA/IChcbiAgICAgICAgICA8cCBjbGFzc05hbWU9J2luZm8tbWVzc2FnZS0tZmFpbHVyZSc+e2Vycm9yfTwvcD5cbiAgICAgICAgKSA6IChcbiAgICAgICAgICA8cCBjbGFzc05hbWU9J2luZm8tbWVzc2FnZSc+VXNlIHNsaWRlciB0byBzZXQgdGh1bWJuYWlsPC9wPlxuICAgICAgICApfVxuICAgICAgPC9kaXY+XG4gICAgKTtcbiAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBQdWJsaXNoVGh1bWJuYWlsSW5wdXQ7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9jbGllbnQvY29udGFpbmVycy9QdWJsaXNoVGh1bWJuYWlsSW5wdXQvdmlldy5qc3giLCJpbXBvcnQge2Nvbm5lY3R9IGZyb20gJ3JlYWN0LXJlZHV4JztcbmltcG9ydCB7dXBkYXRlTWV0YWRhdGEsIHRvZ2dsZU1ldGFkYXRhSW5wdXRzfSBmcm9tICdhY3Rpb25zL3B1Ymxpc2gnO1xuaW1wb3J0IFZpZXcgZnJvbSAnLi92aWV3JztcblxuY29uc3QgbWFwU3RhdGVUb1Byb3BzID0gKHsgcHVibGlzaCB9KSA9PiB7XG4gIHJldHVybiB7XG4gICAgc2hvd01ldGFkYXRhSW5wdXRzOiBwdWJsaXNoLnNob3dNZXRhZGF0YUlucHV0cyxcbiAgICBkZXNjcmlwdGlvbiAgICAgICA6IHB1Ymxpc2gubWV0YWRhdGEuZGVzY3JpcHRpb24sXG4gICAgbGljZW5zZSAgICAgICAgICAgOiBwdWJsaXNoLm1ldGFkYXRhLmxpY2Vuc2UsXG4gICAgbnNmdyAgICAgICAgICAgICAgOiBwdWJsaXNoLm1ldGFkYXRhLm5zZncsXG4gIH07XG59O1xuXG5jb25zdCBtYXBEaXNwYXRjaFRvUHJvcHMgPSBkaXNwYXRjaCA9PiB7XG4gIHJldHVybiB7XG4gICAgb25NZXRhZGF0YUNoYW5nZTogKG5hbWUsIHZhbHVlKSA9PiB7XG4gICAgICBkaXNwYXRjaCh1cGRhdGVNZXRhZGF0YShuYW1lLCB2YWx1ZSkpO1xuICAgIH0sXG4gICAgb25Ub2dnbGVNZXRhZGF0YUlucHV0czogKHZhbHVlKSA9PiB7XG4gICAgICBkaXNwYXRjaCh0b2dnbGVNZXRhZGF0YUlucHV0cyh2YWx1ZSkpO1xuICAgIH0sXG4gIH07XG59O1xuXG5leHBvcnQgZGVmYXVsdCBjb25uZWN0KG1hcFN0YXRlVG9Qcm9wcywgbWFwRGlzcGF0Y2hUb1Byb3BzKShWaWV3KTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL2NsaWVudC9jb250YWluZXJzL1B1Ymxpc2hNZXRhZGF0YUlucHV0cy9pbmRleC5qcyIsImltcG9ydCBSZWFjdCBmcm9tICdyZWFjdCc7XG5pbXBvcnQgRXhwYW5kaW5nVGV4dEFyZWEgZnJvbSAnY29tcG9uZW50cy9FeHBhbmRpbmdUZXh0QXJlYSc7XG5cbmNsYXNzIFB1Ymxpc2hNZXRhZGF0YUlucHV0cyBleHRlbmRzIFJlYWN0LkNvbXBvbmVudCB7XG4gIGNvbnN0cnVjdG9yIChwcm9wcykge1xuICAgIHN1cGVyKHByb3BzKTtcbiAgICB0aGlzLnRvZ2dsZVNob3dJbnB1dHMgPSB0aGlzLnRvZ2dsZVNob3dJbnB1dHMuYmluZCh0aGlzKTtcbiAgICB0aGlzLmhhbmRsZUlucHV0ID0gdGhpcy5oYW5kbGVJbnB1dC5iaW5kKHRoaXMpO1xuICAgIHRoaXMuaGFuZGxlU2VsZWN0ID0gdGhpcy5oYW5kbGVTZWxlY3QuYmluZCh0aGlzKTtcbiAgfVxuICB0b2dnbGVTaG93SW5wdXRzICgpIHtcbiAgICB0aGlzLnByb3BzLm9uVG9nZ2xlTWV0YWRhdGFJbnB1dHMoIXRoaXMucHJvcHMuc2hvd01ldGFkYXRhSW5wdXRzKTtcbiAgfVxuICBoYW5kbGVJbnB1dCAoZXZlbnQpIHtcbiAgICBjb25zdCB0YXJnZXQgPSBldmVudC50YXJnZXQ7XG4gICAgY29uc3QgdmFsdWUgPSB0YXJnZXQudHlwZSA9PT0gJ2NoZWNrYm94JyA/IHRhcmdldC5jaGVja2VkIDogdGFyZ2V0LnZhbHVlO1xuICAgIGNvbnN0IG5hbWUgPSB0YXJnZXQubmFtZTtcbiAgICB0aGlzLnByb3BzLm9uTWV0YWRhdGFDaGFuZ2UobmFtZSwgdmFsdWUpO1xuICB9XG4gIGhhbmRsZVNlbGVjdCAoZXZlbnQpIHtcbiAgICBjb25zdCBuYW1lID0gZXZlbnQudGFyZ2V0Lm5hbWU7XG4gICAgY29uc3Qgc2VsZWN0ZWRPcHRpb24gPSBldmVudC50YXJnZXQuc2VsZWN0ZWRPcHRpb25zWzBdLnZhbHVlO1xuICAgIHRoaXMucHJvcHMub25NZXRhZGF0YUNoYW5nZShuYW1lLCBzZWxlY3RlZE9wdGlvbik7XG4gIH1cbiAgcmVuZGVyICgpIHtcbiAgICByZXR1cm4gKFxuICAgICAgPGRpdiBpZD0ncHVibGlzaC1kZXRhaWxzJyBjbGFzc05hbWU9J3JvdyByb3ctLXBhZGRlZCByb3ctLW5vLXRvcCByb3ctLXdpZGUnPlxuICAgICAgICB7dGhpcy5wcm9wcy5zaG93TWV0YWRhdGFJbnB1dHMgJiYgKFxuICAgICAgICAgIDxkaXY+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT0ncm93IHJvdy0tbm8tdG9wJz5cbiAgICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9J2NvbHVtbiBjb2x1bW4tLTMgY29sdW1uLS1tZWQtMTAgYWxpZ24tY29udGVudC10b3AnPlxuICAgICAgICAgICAgICAgIDxsYWJlbCBodG1sRm9yPSdwdWJsaXNoLWxpY2Vuc2UnIGNsYXNzTmFtZT0nbGFiZWwnPkRlc2NyaXB0aW9uOjwvbGFiZWw+XG4gICAgICAgICAgICAgIDwvZGl2PjxkaXYgY2xhc3NOYW1lPSdjb2x1bW4gY29sdW1uLS03IGNvbHVtbi0tc21sLTEwJz5cbiAgICAgICAgICAgICAgICA8RXhwYW5kaW5nVGV4dEFyZWFcbiAgICAgICAgICAgICAgICAgIGlkPSdwdWJsaXNoLWRlc2NyaXB0aW9uJ1xuICAgICAgICAgICAgICAgICAgY2xhc3NOYW1lPSd0ZXh0YXJlYSB0ZXh0YXJlYS0tcHJpbWFyeSB0ZXh0YXJlYS0tZnVsbC13aWR0aCdcbiAgICAgICAgICAgICAgICAgIHJvd3M9ezF9XG4gICAgICAgICAgICAgICAgICBtYXhMZW5ndGg9ezIwMDB9XG4gICAgICAgICAgICAgICAgICBzdHlsZT17eyBtYXhIZWlnaHQ6IDIwMCB9fVxuICAgICAgICAgICAgICAgICAgbmFtZT0nZGVzY3JpcHRpb24nXG4gICAgICAgICAgICAgICAgICBwbGFjZWhvbGRlcj0nT3B0aW9uYWwgZGVzY3JpcHRpb24nXG4gICAgICAgICAgICAgICAgICB2YWx1ZT17dGhpcy5wcm9wcy5kZXNjcmlwdGlvbn1cbiAgICAgICAgICAgICAgICAgIG9uQ2hhbmdlPXt0aGlzLmhhbmRsZUlucHV0fSAvPlxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT0ncm93IHJvdy0tbm8tdG9wJz5cbiAgICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9J2NvbHVtbiBjb2x1bW4tLTMgY29sdW1uLS1tZWQtMTAnPlxuICAgICAgICAgICAgICAgIDxsYWJlbCBodG1sRm9yPSdwdWJsaXNoLWxpY2Vuc2UnIGNsYXNzTmFtZT0nbGFiZWwnPkxpY2Vuc2U6PC9sYWJlbD5cbiAgICAgICAgICAgICAgPC9kaXY+PGRpdiBjbGFzc05hbWU9J2NvbHVtbiBjb2x1bW4tLTcgY29sdW1uLS1zbWwtMTAnPlxuICAgICAgICAgICAgICAgIDxzZWxlY3QgdHlwZT0ndGV4dCcgbmFtZT0nbGljZW5zZScgaWQ9J3B1Ymxpc2gtbGljZW5zZScgY2xhc3NOYW1lPSdzZWxlY3Qgc2VsZWN0LS1wcmltYXJ5JyBvbkNoYW5nZT17dGhpcy5oYW5kbGVTZWxlY3R9PlxuICAgICAgICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT0nICc+VW5zcGVjaWZpZWQ8L29wdGlvbj5cbiAgICAgICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9J1B1YmxpYyBEb21haW4nPlB1YmxpYyBEb21haW48L29wdGlvbj5cbiAgICAgICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9J0NyZWF0aXZlIENvbW1vbnMnPkNyZWF0aXZlIENvbW1vbnM8L29wdGlvbj5cbiAgICAgICAgICAgICAgICA8L3NlbGVjdD5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9J3JvdyByb3ctLW5vLXRvcCc+XG4gICAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPSdjb2x1bW4gY29sdW1uLS0zJz5cbiAgICAgICAgICAgICAgICA8bGFiZWwgaHRtbEZvcj0ncHVibGlzaC1uc2Z3JyBjbGFzc05hbWU9J2xhYmVsJz5NYXR1cmU6PC9sYWJlbD5cbiAgICAgICAgICAgICAgPC9kaXY+PGRpdiBjbGFzc05hbWU9J2NvbHVtbiBjb2x1bW4tLTcnPlxuICAgICAgICAgICAgICAgIDxpbnB1dCBjbGFzc05hbWU9J2lucHV0LWNoZWNrYm94JyB0eXBlPSdjaGVja2JveCcgaWQ9J3B1Ymxpc2gtbnNmdycgbmFtZT0nbnNmdycgdmFsdWU9e3RoaXMucHJvcHMubnNmd30gb25DaGFuZ2U9e3RoaXMuaGFuZGxlSW5wdXR9IC8+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgICl9XG4gICAgICAgIDxidXR0b24gY2xhc3NOYW1lPSdidXR0b24tLXNlY29uZGFyeScgb25DbGljaz17dGhpcy50b2dnbGVTaG93SW5wdXRzfT57dGhpcy5wcm9wcy5zaG93TWV0YWRhdGFJbnB1dHMgPyAnbGVzcycgOiAnbW9yZSd9PC9idXR0b24+XG4gICAgICA8L2Rpdj5cbiAgICApO1xuICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IFB1Ymxpc2hNZXRhZGF0YUlucHV0cztcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL2NsaWVudC9jb250YWluZXJzL1B1Ymxpc2hNZXRhZGF0YUlucHV0cy92aWV3LmpzeCIsImltcG9ydCBSZWFjdCwgeyBDb21wb25lbnQgfSBmcm9tICdyZWFjdCc7XG5pbXBvcnQgUHJvcFR5cGVzIGZyb20gJ3Byb3AtdHlwZXMnO1xuXG5jbGFzcyBFeHBhbmRpbmdUZXh0YXJlYSBleHRlbmRzIENvbXBvbmVudCB7XG4gIGNvbnN0cnVjdG9yIChwcm9wcykge1xuICAgIHN1cGVyKHByb3BzKTtcbiAgICB0aGlzLl9oYW5kbGVDaGFuZ2UgPSB0aGlzLl9oYW5kbGVDaGFuZ2UuYmluZCh0aGlzKTtcbiAgfVxuICBjb21wb25lbnREaWRNb3VudCAoKSB7XG4gICAgdGhpcy5hZGp1c3RUZXh0YXJlYSh7fSk7XG4gIH1cbiAgX2hhbmRsZUNoYW5nZSAoZXZlbnQpIHtcbiAgICBjb25zdCB7IG9uQ2hhbmdlIH0gPSB0aGlzLnByb3BzO1xuICAgIGlmIChvbkNoYW5nZSkgb25DaGFuZ2UoZXZlbnQpO1xuICAgIHRoaXMuYWRqdXN0VGV4dGFyZWEoZXZlbnQpO1xuICB9XG4gIGFkanVzdFRleHRhcmVhICh7IHRhcmdldCA9IHRoaXMuZWwgfSkge1xuICAgIHRhcmdldC5zdHlsZS5oZWlnaHQgPSAwO1xuICAgIHRhcmdldC5zdHlsZS5oZWlnaHQgPSBgJHt0YXJnZXQuc2Nyb2xsSGVpZ2h0fXB4YDtcbiAgfVxuICByZW5kZXIgKCkge1xuICAgIGNvbnN0IHsgLi4ucmVzdCB9ID0gdGhpcy5wcm9wcztcbiAgICByZXR1cm4gKFxuICAgICAgPHRleHRhcmVhXG4gICAgICAgIHsuLi5yZXN0fVxuICAgICAgICByZWY9e3ggPT4gdGhpcy5lbCA9IHh9XG4gICAgICAgIG9uQ2hhbmdlPXt0aGlzLl9oYW5kbGVDaGFuZ2V9XG4gICAgICAvPlxuICAgICk7XG4gIH1cbn1cblxuRXhwYW5kaW5nVGV4dGFyZWEucHJvcFR5cGVzID0ge1xuICBvbkNoYW5nZTogUHJvcFR5cGVzLmZ1bmMsXG59O1xuXG5leHBvcnQgZGVmYXVsdCBFeHBhbmRpbmdUZXh0YXJlYTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL2NsaWVudC9jb21wb25lbnRzL0V4cGFuZGluZ1RleHRBcmVhL2luZGV4LmpzeCIsImltcG9ydCB7Y29ubmVjdH0gZnJvbSAncmVhY3QtcmVkdXgnO1xuaW1wb3J0IHtzZXRQdWJsaXNoSW5DaGFubmVsLCB1cGRhdGVTZWxlY3RlZENoYW5uZWwsIHVwZGF0ZUVycm9yfSBmcm9tICdhY3Rpb25zL3B1Ymxpc2gnO1xuaW1wb3J0IFZpZXcgZnJvbSAnLi92aWV3JztcblxuY29uc3QgbWFwU3RhdGVUb1Byb3BzID0gKHsgY2hhbm5lbCwgcHVibGlzaCB9KSA9PiB7XG4gIHJldHVybiB7XG4gICAgbG9nZ2VkSW5DaGFubmVsTmFtZTogY2hhbm5lbC5sb2dnZWRJbkNoYW5uZWwubmFtZSxcbiAgICBwdWJsaXNoSW5DaGFubmVsICAgOiBwdWJsaXNoLnB1Ymxpc2hJbkNoYW5uZWwsXG4gICAgc2VsZWN0ZWRDaGFubmVsICAgIDogcHVibGlzaC5zZWxlY3RlZENoYW5uZWwsXG4gICAgY2hhbm5lbEVycm9yICAgICAgIDogcHVibGlzaC5lcnJvci5jaGFubmVsLFxuICB9O1xufTtcblxuY29uc3QgbWFwRGlzcGF0Y2hUb1Byb3BzID0gZGlzcGF0Y2ggPT4ge1xuICByZXR1cm4ge1xuICAgIG9uUHVibGlzaEluQ2hhbm5lbENoYW5nZTogKHZhbHVlKSA9PiB7XG4gICAgICBkaXNwYXRjaCh1cGRhdGVFcnJvcignY2hhbm5lbCcsIG51bGwpKTtcbiAgICAgIGRpc3BhdGNoKHNldFB1Ymxpc2hJbkNoYW5uZWwodmFsdWUpKTtcbiAgICB9LFxuICAgIG9uQ2hhbm5lbFNlbGVjdDogKHZhbHVlKSA9PiB7XG4gICAgICBkaXNwYXRjaCh1cGRhdGVFcnJvcignY2hhbm5lbCcsIG51bGwpKTtcbiAgICAgIGRpc3BhdGNoKHVwZGF0ZVNlbGVjdGVkQ2hhbm5lbCh2YWx1ZSkpO1xuICAgIH0sXG4gIH07XG59O1xuXG5leHBvcnQgZGVmYXVsdCBjb25uZWN0KG1hcFN0YXRlVG9Qcm9wcywgbWFwRGlzcGF0Y2hUb1Byb3BzKShWaWV3KTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL2NsaWVudC9jb250YWluZXJzL0NoYW5uZWxTZWxlY3QvaW5kZXguanMiLCJpbXBvcnQgUmVhY3QgZnJvbSAncmVhY3QnO1xuaW1wb3J0IENoYW5uZWxMb2dpbkZvcm0gZnJvbSAnY29udGFpbmVycy9DaGFubmVsTG9naW5Gb3JtJztcbmltcG9ydCBDaGFubmVsQ3JlYXRlRm9ybSBmcm9tICdjb250YWluZXJzL0NoYW5uZWxDcmVhdGVGb3JtJztcbmltcG9ydCAqIGFzIHN0YXRlcyBmcm9tICdjb25zdGFudHMvcHVibGlzaF9jaGFubmVsX3NlbGVjdF9zdGF0ZXMnO1xuXG5jbGFzcyBDaGFubmVsU2VsZWN0IGV4dGVuZHMgUmVhY3QuQ29tcG9uZW50IHtcbiAgY29uc3RydWN0b3IgKHByb3BzKSB7XG4gICAgc3VwZXIocHJvcHMpO1xuICAgIHRoaXMudG9nZ2xlQW5vbnltb3VzUHVibGlzaCA9IHRoaXMudG9nZ2xlQW5vbnltb3VzUHVibGlzaC5iaW5kKHRoaXMpO1xuICAgIHRoaXMuaGFuZGxlU2VsZWN0aW9uID0gdGhpcy5oYW5kbGVTZWxlY3Rpb24uYmluZCh0aGlzKTtcbiAgfVxuICB0b2dnbGVBbm9ueW1vdXNQdWJsaXNoIChldmVudCkge1xuICAgIGNvbnN0IHZhbHVlID0gZXZlbnQudGFyZ2V0LnZhbHVlO1xuICAgIGlmICh2YWx1ZSA9PT0gJ2Fub255bW91cycpIHtcbiAgICAgIHRoaXMucHJvcHMub25QdWJsaXNoSW5DaGFubmVsQ2hhbmdlKGZhbHNlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5wcm9wcy5vblB1Ymxpc2hJbkNoYW5uZWxDaGFuZ2UodHJ1ZSk7XG4gICAgfVxuICB9XG4gIGhhbmRsZVNlbGVjdGlvbiAoZXZlbnQpIHtcbiAgICBjb25zdCBzZWxlY3RlZE9wdGlvbiA9IGV2ZW50LnRhcmdldC5zZWxlY3RlZE9wdGlvbnNbMF0udmFsdWU7XG4gICAgdGhpcy5wcm9wcy5vbkNoYW5uZWxTZWxlY3Qoc2VsZWN0ZWRPcHRpb24pO1xuICB9XG4gIHJlbmRlciAoKSB7XG4gICAgcmV0dXJuIChcbiAgICAgIDxkaXY+XG4gICAgICAgIDxmb3JtPlxuICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPSdjb2x1bW4gY29sdW1uLS0zIGNvbHVtbi0tbWVkLTEwJz5cbiAgICAgICAgICAgIDxpbnB1dCB0eXBlPSdyYWRpbycgbmFtZT0nYW5vbnltb3VzLW9yLWNoYW5uZWwnIGlkPSdhbm9ueW1vdXMtcmFkaW8nIGNsYXNzTmFtZT0naW5wdXQtcmFkaW8nIHZhbHVlPSdhbm9ueW1vdXMnIGNoZWNrZWQ9eyF0aGlzLnByb3BzLnB1Ymxpc2hJbkNoYW5uZWx9IG9uQ2hhbmdlPXt0aGlzLnRvZ2dsZUFub255bW91c1B1Ymxpc2h9IC8+XG4gICAgICAgICAgICA8bGFiZWwgY2xhc3NOYW1lPSdsYWJlbCBsYWJlbC0tcG9pbnRlcicgaHRtbEZvcj0nYW5vbnltb3VzLXJhZGlvJz5Bbm9ueW1vdXM8L2xhYmVsPlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPSdjb2x1bW4gY29sdW1uLS03IGNvbHVtbi0tbWVkLTEwJz5cbiAgICAgICAgICAgIDxpbnB1dCB0eXBlPSdyYWRpbycgbmFtZT0nYW5vbnltb3VzLW9yLWNoYW5uZWwnIGlkPSdjaGFubmVsLXJhZGlvJyBjbGFzc05hbWU9J2lucHV0LXJhZGlvJyB2YWx1ZT0naW4gYSBjaGFubmVsJyBjaGVja2VkPXt0aGlzLnByb3BzLnB1Ymxpc2hJbkNoYW5uZWx9IG9uQ2hhbmdlPXt0aGlzLnRvZ2dsZUFub255bW91c1B1Ymxpc2h9IC8+XG4gICAgICAgICAgICA8bGFiZWwgY2xhc3NOYW1lPSdsYWJlbCBsYWJlbC0tcG9pbnRlcicgaHRtbEZvcj0nY2hhbm5lbC1yYWRpbyc+SW4gYSBjaGFubmVsPC9sYWJlbD5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICB7IHRoaXMucHJvcHMuY2hhbm5lbEVycm9yID8gKFxuICAgICAgICAgICAgPHAgY2xhc3NOYW1lPSdpbmZvLW1lc3NhZ2UtLWZhaWx1cmUnPnt0aGlzLnByb3BzLmNoYW5uZWxFcnJvcn08L3A+XG4gICAgICAgICAgKSA6IChcbiAgICAgICAgICAgIDxwIGNsYXNzTmFtZT0naW5mby1tZXNzYWdlJz5QdWJsaXNoIGFub255bW91c2x5IG9yIGluIGEgY2hhbm5lbDwvcD5cbiAgICAgICAgICApfVxuICAgICAgICA8L2Zvcm0+XG4gICAgICAgIHsgdGhpcy5wcm9wcy5wdWJsaXNoSW5DaGFubmVsICYmIChcbiAgICAgICAgICA8ZGl2PlxuICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9J2NvbHVtbiBjb2x1bW4tLTMnPlxuICAgICAgICAgICAgICA8bGFiZWwgY2xhc3NOYW1lPSdsYWJlbCcgaHRtbEZvcj0nY2hhbm5lbC1uYW1lLXNlbGVjdCc+Q2hhbm5lbDo8L2xhYmVsPlxuICAgICAgICAgICAgPC9kaXY+PGRpdiBjbGFzc05hbWU9J2NvbHVtbiBjb2x1bW4tLTcnPlxuICAgICAgICAgICAgICA8c2VsZWN0IHR5cGU9J3RleHQnIGlkPSdjaGFubmVsLW5hbWUtc2VsZWN0JyBjbGFzc05hbWU9J3NlbGVjdCBzZWxlY3QtLWFycm93JyB2YWx1ZT17dGhpcy5wcm9wcy5zZWxlY3RlZENoYW5uZWx9IG9uQ2hhbmdlPXt0aGlzLmhhbmRsZVNlbGVjdGlvbn0+XG4gICAgICAgICAgICAgICAgeyB0aGlzLnByb3BzLmxvZ2dlZEluQ2hhbm5lbE5hbWUgJiYgPG9wdGlvbiB2YWx1ZT17dGhpcy5wcm9wcy5sb2dnZWRJbkNoYW5uZWxOYW1lfSBpZD0ncHVibGlzaC1jaGFubmVsLXNlbGVjdC1jaGFubmVsLW9wdGlvbic+e3RoaXMucHJvcHMubG9nZ2VkSW5DaGFubmVsTmFtZX08L29wdGlvbj4gfVxuICAgICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9e3N0YXRlcy5MT0dJTn0+RXhpc3Rpbmc8L29wdGlvbj5cbiAgICAgICAgICAgICAgICA8b3B0aW9uIHZhbHVlPXtzdGF0ZXMuQ1JFQVRFfT5OZXc8L29wdGlvbj5cbiAgICAgICAgICAgICAgPC9zZWxlY3Q+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIHsgKHRoaXMucHJvcHMuc2VsZWN0ZWRDaGFubmVsID09PSBzdGF0ZXMuTE9HSU4pICYmIDxDaGFubmVsTG9naW5Gb3JtIC8+IH1cbiAgICAgICAgICAgIHsgKHRoaXMucHJvcHMuc2VsZWN0ZWRDaGFubmVsID09PSBzdGF0ZXMuQ1JFQVRFKSAmJiA8Q2hhbm5lbENyZWF0ZUZvcm0gLz4gfVxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICApfVxuICAgICAgPC9kaXY+XG4gICAgKTtcbiAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBDaGFubmVsU2VsZWN0O1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vY2xpZW50L2NvbnRhaW5lcnMvQ2hhbm5lbFNlbGVjdC92aWV3LmpzeCIsImltcG9ydCBSZWFjdCBmcm9tICdyZWFjdCc7XG5pbXBvcnQgcmVxdWVzdCBmcm9tICd1dGlscy9yZXF1ZXN0JztcblxuY2xhc3MgQ2hhbm5lbExvZ2luRm9ybSBleHRlbmRzIFJlYWN0LkNvbXBvbmVudCB7XG4gIGNvbnN0cnVjdG9yIChwcm9wcykge1xuICAgIHN1cGVyKHByb3BzKTtcbiAgICB0aGlzLnN0YXRlID0ge1xuICAgICAgZXJyb3IgICA6IG51bGwsXG4gICAgICBuYW1lICAgIDogJycsXG4gICAgICBwYXNzd29yZDogJycsXG4gICAgfTtcbiAgICB0aGlzLmhhbmRsZUlucHV0ID0gdGhpcy5oYW5kbGVJbnB1dC5iaW5kKHRoaXMpO1xuICAgIHRoaXMubG9naW5Ub0NoYW5uZWwgPSB0aGlzLmxvZ2luVG9DaGFubmVsLmJpbmQodGhpcyk7XG4gIH1cbiAgaGFuZGxlSW5wdXQgKGV2ZW50KSB7XG4gICAgY29uc3QgbmFtZSA9IGV2ZW50LnRhcmdldC5uYW1lO1xuICAgIGNvbnN0IHZhbHVlID0gZXZlbnQudGFyZ2V0LnZhbHVlO1xuICAgIHRoaXMuc2V0U3RhdGUoe1tuYW1lXTogdmFsdWV9KTtcbiAgfVxuICBsb2dpblRvQ2hhbm5lbCAoZXZlbnQpIHtcbiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIGNvbnN0IHBhcmFtcyA9IHtcbiAgICAgIG1ldGhvZCA6ICdQT1NUJyxcbiAgICAgIGJvZHkgICA6IEpTT04uc3RyaW5naWZ5KHt1c2VybmFtZTogdGhpcy5zdGF0ZS5uYW1lLCBwYXNzd29yZDogdGhpcy5zdGF0ZS5wYXNzd29yZH0pLFxuICAgICAgaGVhZGVyczogbmV3IEhlYWRlcnMoe1xuICAgICAgICAnQ29udGVudC1UeXBlJzogJ2FwcGxpY2F0aW9uL2pzb24nLFxuICAgICAgfSksXG4gICAgICBjcmVkZW50aWFsczogJ2luY2x1ZGUnLFxuICAgIH07XG4gICAgcmVxdWVzdCgnbG9naW4nLCBwYXJhbXMpXG4gICAgICAudGhlbigoe3N1Y2Nlc3MsIGNoYW5uZWxOYW1lLCBzaG9ydENoYW5uZWxJZCwgY2hhbm5lbENsYWltSWQsIG1lc3NhZ2V9KSA9PiB7XG4gICAgICAgIGlmIChzdWNjZXNzKSB7XG4gICAgICAgICAgdGhpcy5wcm9wcy5vbkNoYW5uZWxMb2dpbihjaGFubmVsTmFtZSwgc2hvcnRDaGFubmVsSWQsIGNoYW5uZWxDbGFpbUlkKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aGlzLnNldFN0YXRlKHsnZXJyb3InOiBtZXNzYWdlfSk7XG4gICAgICAgIH07XG4gICAgICB9KVxuICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgaWYgKGVycm9yLm1lc3NhZ2UpIHtcbiAgICAgICAgICB0aGlzLnNldFN0YXRlKHsnZXJyb3InOiBlcnJvci5tZXNzYWdlfSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7J2Vycm9yJzogZXJyb3J9KTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gIH1cbiAgcmVuZGVyICgpIHtcbiAgICByZXR1cm4gKFxuICAgICAgPGZvcm0gaWQ9J2NoYW5uZWwtbG9naW4tZm9ybSc+XG4gICAgICAgIDxkaXYgY2xhc3NOYW1lPSdyb3cgcm93LS13aWRlIHJvdy0tc2hvcnQnPlxuICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPSdjb2x1bW4gY29sdW1uLS0zIGNvbHVtbi0tc21sLTEwJz5cbiAgICAgICAgICAgIDxsYWJlbCBjbGFzc05hbWU9J2xhYmVsJyBodG1sRm9yPSdjaGFubmVsLWxvZ2luLW5hbWUtaW5wdXQnPk5hbWU6PC9sYWJlbD5cbiAgICAgICAgICA8L2Rpdj48ZGl2IGNsYXNzTmFtZT0nY29sdW1uIGNvbHVtbi0tNiBjb2x1bW4tLXNtbC0xMCc+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT0naW5wdXQtdGV4dC0tcHJpbWFyeSBmbGV4LWNvbnRhaW5lci0tcm93IGZsZXgtY29udGFpbmVyLS1sZWZ0LWJvdHRvbSc+XG4gICAgICAgICAgICAgIDxzcGFuPkA8L3NwYW4+XG4gICAgICAgICAgICAgIDxpbnB1dCB0eXBlPSd0ZXh0JyBpZD0nY2hhbm5lbC1sb2dpbi1uYW1lLWlucHV0JyBjbGFzc05hbWU9J2lucHV0LXRleHQnIG5hbWU9J25hbWUnIHBsYWNlaG9sZGVyPSdZb3VyIENoYW5uZWwgTmFtZScgdmFsdWU9e3RoaXMuc3RhdGUuY2hhbm5lbE5hbWV9IG9uQ2hhbmdlPXt0aGlzLmhhbmRsZUlucHV0fSAvPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICA8ZGl2IGNsYXNzTmFtZT0ncm93IHJvdy0td2lkZSByb3ctLXNob3J0Jz5cbiAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT0nY29sdW1uIGNvbHVtbi0tMyBjb2x1bW4tLXNtbC0xMCc+XG4gICAgICAgICAgICA8bGFiZWwgY2xhc3NOYW1lPSdsYWJlbCcgaHRtbEZvcj0nY2hhbm5lbC1sb2dpbi1wYXNzd29yZC1pbnB1dCcgPlBhc3N3b3JkOjwvbGFiZWw+XG4gICAgICAgICAgPC9kaXY+PGRpdiBjbGFzc05hbWU9J2NvbHVtbiBjb2x1bW4tLTYgY29sdW1uLS1zbWwtMTAnPlxuICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9J2lucHV0LXRleHQtLXByaW1hcnknPlxuICAgICAgICAgICAgICA8aW5wdXQgdHlwZT0ncGFzc3dvcmQnIGlkPSdjaGFubmVsLWxvZ2luLXBhc3N3b3JkLWlucHV0JyBuYW1lPSdwYXNzd29yZCcgY2xhc3NOYW1lPSdpbnB1dC10ZXh0JyBwbGFjZWhvbGRlcj0nJyB2YWx1ZT17dGhpcy5zdGF0ZS5jaGFubmVsUGFzc3dvcmR9IG9uQ2hhbmdlPXt0aGlzLmhhbmRsZUlucHV0fSAvPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICB7IHRoaXMuc3RhdGUuZXJyb3IgPyAoXG4gICAgICAgICAgPHAgY2xhc3NOYW1lPSdpbmZvLW1lc3NhZ2UtLWZhaWx1cmUnPnt0aGlzLnN0YXRlLmVycm9yfTwvcD5cbiAgICAgICAgKSA6IChcbiAgICAgICAgICA8cCBjbGFzc05hbWU9J2luZm8tbWVzc2FnZSc+RW50ZXIgdGhlIG5hbWUgYW5kIHBhc3N3b3JkIGZvciB5b3VyIGNoYW5uZWw8L3A+XG4gICAgICAgICl9XG4gICAgICAgIDxkaXYgY2xhc3NOYW1lPSdyb3cgcm93LS13aWRlJz5cbiAgICAgICAgICA8YnV0dG9uIGNsYXNzTmFtZT0nYnV0dG9uLS1wcmltYXJ5JyBvbkNsaWNrPXt0aGlzLmxvZ2luVG9DaGFubmVsfT5BdXRoZW50aWNhdGU8L2J1dHRvbj5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Zvcm0+XG4gICAgKTtcbiAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBDaGFubmVsTG9naW5Gb3JtO1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vY2xpZW50L2NvbnRhaW5lcnMvQ2hhbm5lbExvZ2luRm9ybS92aWV3LmpzeCIsImltcG9ydCBSZWFjdCBmcm9tICdyZWFjdCc7XG5pbXBvcnQgUHJvZ3Jlc3NCYXIgZnJvbSAnY29tcG9uZW50cy9Qcm9ncmVzc0Jhcic7XG5pbXBvcnQgcmVxdWVzdCBmcm9tICd1dGlscy9yZXF1ZXN0JztcblxuY2xhc3MgQ2hhbm5lbENyZWF0ZUZvcm0gZXh0ZW5kcyBSZWFjdC5Db21wb25lbnQge1xuICBjb25zdHJ1Y3RvciAocHJvcHMpIHtcbiAgICBzdXBlcihwcm9wcyk7XG4gICAgdGhpcy5zdGF0ZSA9IHtcbiAgICAgIGVycm9yICAgOiBudWxsLFxuICAgICAgY2hhbm5lbCA6ICcnLFxuICAgICAgcGFzc3dvcmQ6ICcnLFxuICAgICAgc3RhdHVzICA6IG51bGwsXG4gICAgfTtcbiAgICB0aGlzLmhhbmRsZUNoYW5uZWxJbnB1dCA9IHRoaXMuaGFuZGxlQ2hhbm5lbElucHV0LmJpbmQodGhpcyk7XG4gICAgdGhpcy5oYW5kbGVJbnB1dCA9IHRoaXMuaGFuZGxlSW5wdXQuYmluZCh0aGlzKTtcbiAgICB0aGlzLmNyZWF0ZUNoYW5uZWwgPSB0aGlzLmNyZWF0ZUNoYW5uZWwuYmluZCh0aGlzKTtcbiAgfVxuICBjbGVhbnNlQ2hhbm5lbElucHV0IChpbnB1dCkge1xuICAgIGlucHV0ID0gaW5wdXQucmVwbGFjZSgvXFxzKy9nLCAnLScpOyAvLyByZXBsYWNlIHNwYWNlcyB3aXRoIGRhc2hlc1xuICAgIGlucHV0ID0gaW5wdXQucmVwbGFjZSgvW15BLVphLXowLTktXS9nLCAnJyk7ICAvLyByZW1vdmUgYWxsIGNoYXJhY3RlcnMgdGhhdCBhcmUgbm90IEEtWiwgYS16LCAwLTksIG9yICctJ1xuICAgIHJldHVybiBpbnB1dDtcbiAgfVxuICBoYW5kbGVDaGFubmVsSW5wdXQgKGV2ZW50KSB7XG4gICAgbGV0IHZhbHVlID0gZXZlbnQudGFyZ2V0LnZhbHVlO1xuICAgIHZhbHVlID0gdGhpcy5jbGVhbnNlQ2hhbm5lbElucHV0KHZhbHVlKTtcbiAgICB0aGlzLnNldFN0YXRlKHtjaGFubmVsOiB2YWx1ZX0pO1xuICAgIGlmICh2YWx1ZSkge1xuICAgICAgdGhpcy51cGRhdGVJc0NoYW5uZWxBdmFpbGFibGUodmFsdWUpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnNldFN0YXRlKHtlcnJvcjogJ1BsZWFzZSBlbnRlciBhIGNoYW5uZWwgbmFtZSd9KTtcbiAgICB9XG4gIH1cbiAgaGFuZGxlSW5wdXQgKGV2ZW50KSB7XG4gICAgY29uc3QgbmFtZSA9IGV2ZW50LnRhcmdldC5uYW1lO1xuICAgIGNvbnN0IHZhbHVlID0gZXZlbnQudGFyZ2V0LnZhbHVlO1xuICAgIHRoaXMuc2V0U3RhdGUoe1tuYW1lXTogdmFsdWV9KTtcbiAgfVxuICB1cGRhdGVJc0NoYW5uZWxBdmFpbGFibGUgKGNoYW5uZWwpIHtcbiAgICBjb25zdCBjaGFubmVsV2l0aEF0U3ltYm9sID0gYEAke2NoYW5uZWx9YDtcbiAgICByZXF1ZXN0KGAvYXBpL2NoYW5uZWwvYXZhaWxhYmlsaXR5LyR7Y2hhbm5lbFdpdGhBdFN5bWJvbH1gKVxuICAgICAgLnRoZW4oKCkgPT4ge1xuICAgICAgICB0aGlzLnNldFN0YXRlKHsnZXJyb3InOiBudWxsfSk7XG4gICAgICB9KVxuICAgICAgLmNhdGNoKChlcnJvcikgPT4ge1xuICAgICAgICB0aGlzLnNldFN0YXRlKHsnZXJyb3InOiBlcnJvci5tZXNzYWdlfSk7XG4gICAgICB9KTtcbiAgfVxuICBjaGVja0lzQ2hhbm5lbEF2YWlsYWJsZSAoY2hhbm5lbCkge1xuICAgIGNvbnN0IGNoYW5uZWxXaXRoQXRTeW1ib2wgPSBgQCR7Y2hhbm5lbH1gO1xuICAgIHJldHVybiByZXF1ZXN0KGAvYXBpL2NoYW5uZWwvYXZhaWxhYmlsaXR5LyR7Y2hhbm5lbFdpdGhBdFN5bWJvbH1gKTtcbiAgfVxuICBjaGVja0lzUGFzc3dvcmRQcm92aWRlZCAocGFzc3dvcmQpIHtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgaWYgKCFwYXNzd29yZCB8fCBwYXNzd29yZC5sZW5ndGggPCAxKSB7XG4gICAgICAgIHJldHVybiByZWplY3QobmV3IEVycm9yKCdQbGVhc2UgcHJvdmlkZSBhIHBhc3N3b3JkJykpO1xuICAgICAgfVxuICAgICAgcmVzb2x2ZSgpO1xuICAgIH0pO1xuICB9XG4gIG1ha2VQdWJsaXNoQ2hhbm5lbFJlcXVlc3QgKHVzZXJuYW1lLCBwYXNzd29yZCkge1xuICAgIGNvbnN0IHBhcmFtcyA9IHtcbiAgICAgIG1ldGhvZCA6ICdQT1NUJyxcbiAgICAgIGJvZHkgICA6IEpTT04uc3RyaW5naWZ5KHt1c2VybmFtZSwgcGFzc3dvcmR9KSxcbiAgICAgIGhlYWRlcnM6IG5ldyBIZWFkZXJzKHtcbiAgICAgICAgJ0NvbnRlbnQtVHlwZSc6ICdhcHBsaWNhdGlvbi9qc29uJyxcbiAgICAgIH0pLFxuICAgICAgY3JlZGVudGlhbHM6ICdpbmNsdWRlJyxcbiAgICB9O1xuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICByZXF1ZXN0KCcvc2lnbnVwJywgcGFyYW1zKVxuICAgICAgICAudGhlbihyZXN1bHQgPT4ge1xuICAgICAgICAgIHJldHVybiByZXNvbHZlKHJlc3VsdCk7XG4gICAgICAgIH0pXG4gICAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgICAgcmVqZWN0KG5ldyBFcnJvcihgVW5mb3J0dW5hdGVseSwgd2UgZW5jb3VudGVyZWQgYW4gZXJyb3Igd2hpbGUgY3JlYXRpbmcgeW91ciBjaGFubmVsLiBQbGVhc2UgbGV0IHVzIGtub3cgaW4gRGlzY29yZCEgJHtlcnJvci5tZXNzYWdlfWApKTtcbiAgICAgICAgfSk7XG4gICAgfSk7XG4gIH1cbiAgY3JlYXRlQ2hhbm5lbCAoZXZlbnQpIHtcbiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIHRoaXMuY2hlY2tJc1Bhc3N3b3JkUHJvdmlkZWQodGhpcy5zdGF0ZS5wYXNzd29yZClcbiAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY2hlY2tJc0NoYW5uZWxBdmFpbGFibGUodGhpcy5zdGF0ZS5jaGFubmVsKTtcbiAgICAgIH0pXG4gICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoe3N0YXR1czogJ1dlIGFyZSBwdWJsaXNoaW5nIHlvdXIgbmV3IGNoYW5uZWwuICBTaXQgdGlnaHQuLi4nfSk7XG4gICAgICAgIHJldHVybiB0aGlzLm1ha2VQdWJsaXNoQ2hhbm5lbFJlcXVlc3QodGhpcy5zdGF0ZS5jaGFubmVsLCB0aGlzLnN0YXRlLnBhc3N3b3JkKTtcbiAgICAgIH0pXG4gICAgICAudGhlbihyZXN1bHQgPT4ge1xuICAgICAgICB0aGlzLnNldFN0YXRlKHtzdGF0dXM6IG51bGx9KTtcbiAgICAgICAgdGhpcy5wcm9wcy5vbkNoYW5uZWxMb2dpbihyZXN1bHQuY2hhbm5lbE5hbWUsIHJlc3VsdC5zaG9ydENoYW5uZWxJZCwgcmVzdWx0LmNoYW5uZWxDbGFpbUlkKTtcbiAgICAgIH0pXG4gICAgICAuY2F0Y2goKGVycm9yKSA9PiB7XG4gICAgICAgIGlmIChlcnJvci5tZXNzYWdlKSB7XG4gICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7J2Vycm9yJzogZXJyb3IubWVzc2FnZSwgc3RhdHVzOiBudWxsfSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7J2Vycm9yJzogZXJyb3IsIHN0YXR1czogbnVsbH0pO1xuICAgICAgICB9O1xuICAgICAgfSk7XG4gIH1cbiAgcmVuZGVyICgpIHtcbiAgICByZXR1cm4gKFxuICAgICAgPGRpdj5cbiAgICAgICAgeyAhdGhpcy5zdGF0ZS5zdGF0dXMgPyAoXG4gICAgICAgICAgPGZvcm0gaWQ9J3B1Ymxpc2gtY2hhbm5lbC1mb3JtJz5cbiAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPSdyb3cgcm93LS13aWRlIHJvdy0tc2hvcnQnPlxuICAgICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT0nY29sdW1uIGNvbHVtbi0tMyBjb2x1bW4tLXNtbC0xMCc+XG4gICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzTmFtZT0nbGFiZWwnIGh0bWxGb3I9J25ldy1jaGFubmVsLW5hbWUnPk5hbWU6PC9sYWJlbD5cbiAgICAgICAgICAgICAgPC9kaXY+PGRpdiBjbGFzc05hbWU9J2NvbHVtbiBjb2x1bW4tLTYgY29sdW1uLS1zbWwtMTAnPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPSdpbnB1dC10ZXh0LS1wcmltYXJ5IGZsZXgtY29udGFpbmVyLS1yb3cgZmxleC1jb250YWluZXItLWxlZnQtYm90dG9tIHNwYW4tLXJlbGF0aXZlJz5cbiAgICAgICAgICAgICAgICAgIDxzcGFuPkA8L3NwYW4+XG4gICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT0ndGV4dCcgbmFtZT0nY2hhbm5lbCcgaWQ9J25ldy1jaGFubmVsLW5hbWUnIGNsYXNzTmFtZT0naW5wdXQtdGV4dCcgcGxhY2Vob2xkZXI9J2V4YW1wbGVDaGFubmVsTmFtZScgdmFsdWU9e3RoaXMuc3RhdGUuY2hhbm5lbH0gb25DaGFuZ2U9e3RoaXMuaGFuZGxlQ2hhbm5lbElucHV0fSAvPlxuICAgICAgICAgICAgICAgICAgeyAodGhpcy5zdGF0ZS5jaGFubmVsICYmICF0aGlzLnN0YXRlLmVycm9yKSAmJiA8c3BhbiBpZD0naW5wdXQtc3VjY2Vzcy1jaGFubmVsLW5hbWUnIGNsYXNzTmFtZT0naW5mby1tZXNzYWdlLS1zdWNjZXNzIHNwYW4tLWFic29sdXRlJz57J1xcdTI3MTMnfTwvc3Bhbj4gfVxuICAgICAgICAgICAgICAgICAgeyB0aGlzLnN0YXRlLmVycm9yICYmIDxzcGFuIGlkPSdpbnB1dC1zdWNjZXNzLWNoYW5uZWwtbmFtZScgY2xhc3NOYW1lPSdpbmZvLW1lc3NhZ2UtLWZhaWx1cmUgc3Bhbi0tYWJzb2x1dGUnPnsnXFx1MjcxNid9PC9zcGFuPiB9XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT0ncm93IHJvdy0td2lkZSByb3ctLXNob3J0Jz5cbiAgICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9J2NvbHVtbiBjb2x1bW4tLTMgY29sdW1uLS1zbWwtMTAnPlxuICAgICAgICAgICAgICAgIDxsYWJlbCBjbGFzc05hbWU9J2xhYmVsJyBodG1sRm9yPSduZXctY2hhbm5lbC1wYXNzd29yZCc+UGFzc3dvcmQ6PC9sYWJlbD5cbiAgICAgICAgICAgICAgPC9kaXY+PGRpdiBjbGFzc05hbWU9J2NvbHVtbiBjb2x1bW4tLTYgY29sdW1uLS1zbWwtMTAnPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPSdpbnB1dC10ZXh0LS1wcmltYXJ5Jz5cbiAgICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPSdwYXNzd29yZCcgbmFtZT0ncGFzc3dvcmQnIGlkPSduZXctY2hhbm5lbC1wYXNzd29yZCcgY2xhc3NOYW1lPSdpbnB1dC10ZXh0JyAgcGxhY2Vob2xkZXI9JycgdmFsdWU9e3RoaXMuc3RhdGUucGFzc3dvcmR9IG9uQ2hhbmdlPXt0aGlzLmhhbmRsZUlucHV0fSAvPlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAge3RoaXMuc3RhdGUuZXJyb3IgPyAoXG4gICAgICAgICAgICAgIDxwIGNsYXNzTmFtZT0naW5mby1tZXNzYWdlLS1mYWlsdXJlJz57dGhpcy5zdGF0ZS5lcnJvcn08L3A+XG4gICAgICAgICAgICApIDogKFxuICAgICAgICAgICAgICA8cCBjbGFzc05hbWU9J2luZm8tbWVzc2FnZSc+Q2hvb3NlIGEgbmFtZSBhbmQgcGFzc3dvcmQgZm9yIHlvdXIgY2hhbm5lbDwvcD5cbiAgICAgICAgICAgICl9XG4gICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT0ncm93IHJvdy0td2lkZSc+XG4gICAgICAgICAgICAgIDxidXR0b24gY2xhc3NOYW1lPSdidXR0b24tLXByaW1hcnknIG9uQ2xpY2s9e3RoaXMuY3JlYXRlQ2hhbm5lbH0+Q3JlYXRlIENoYW5uZWw8L2J1dHRvbj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwvZm9ybT5cbiAgICAgICAgKSA6IChcbiAgICAgICAgICA8ZGl2PlxuICAgICAgICAgICAgPHAgY2xhc3NOYW1lPSdmaW5lLXByaW50Jz57dGhpcy5zdGF0ZS5zdGF0dXN9PC9wPlxuICAgICAgICAgICAgPFByb2dyZXNzQmFyIHNpemU9ezEyfSAvPlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICApfVxuICAgICAgPC9kaXY+XG4gICAgKTtcbiAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBDaGFubmVsQ3JlYXRlRm9ybTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL2NsaWVudC9jb250YWluZXJzL0NoYW5uZWxDcmVhdGVGb3JtL3ZpZXcuanN4IiwiaW1wb3J0IFJlYWN0IGZyb20gJ3JlYWN0JztcblxuY29uc3QgQWN0aXZlU3RhdHVzQmFyID0gKCkgPT4ge1xuICByZXR1cm4gPHNwYW4gY2xhc3NOYW1lPSdwcm9ncmVzcy1iYXIgcHJvZ3Jlc3MtYmFyLS1hY3RpdmUnPnwgPC9zcGFuPjtcbn07XG5cbmV4cG9ydCBkZWZhdWx0IEFjdGl2ZVN0YXR1c0JhcjtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL2NsaWVudC9jb21wb25lbnRzL0FjdGl2ZVN0YXR1c0Jhci9pbmRleC5qc3giLCJpbXBvcnQgUmVhY3QgZnJvbSAncmVhY3QnO1xuXG5jb25zdCBJbmFjdGl2ZVN0YXR1c0JhciA9ICgpID0+IHtcbiAgcmV0dXJuIDxzcGFuIGNsYXNzTmFtZT0ncHJvZ3Jlc3MtYmFyIHByb2dyZXNzLWJhci0taW5hY3RpdmUnPnwgPC9zcGFuPjtcbn07XG5cbmV4cG9ydCBkZWZhdWx0IEluYWN0aXZlU3RhdHVzQmFyO1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vY2xpZW50L2NvbXBvbmVudHMvSW5hY3RpdmVTdGF0dXNCYXIvaW5kZXguanN4IiwiaW1wb3J0IHtjb25uZWN0fSBmcm9tICdyZWFjdC1yZWR1eCc7XG5pbXBvcnQge2NsZWFyRmlsZX0gZnJvbSAnYWN0aW9ucy9wdWJsaXNoJztcbmltcG9ydCBWaWV3IGZyb20gJy4vdmlldyc7XG5cbmNvbnN0IG1hcFN0YXRlVG9Qcm9wcyA9ICh7IHB1Ymxpc2ggfSkgPT4ge1xuICByZXR1cm4ge1xuICAgIHN0YXR1cyA6IHB1Ymxpc2guc3RhdHVzLnN0YXR1cyxcbiAgICBtZXNzYWdlOiBwdWJsaXNoLnN0YXR1cy5tZXNzYWdlLFxuICB9O1xufTtcblxuY29uc3QgbWFwRGlzcGF0Y2hUb1Byb3BzID0ge1xuICBjbGVhckZpbGUsXG59O1xuXG5leHBvcnQgZGVmYXVsdCBjb25uZWN0KG1hcFN0YXRlVG9Qcm9wcywgbWFwRGlzcGF0Y2hUb1Byb3BzKShWaWV3KTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL2NsaWVudC9jb250YWluZXJzL1B1Ymxpc2hTdGF0dXMvaW5kZXguanMiLCJpbXBvcnQgUmVhY3QgZnJvbSAncmVhY3QnO1xuaW1wb3J0IFByb2dyZXNzQmFyIGZyb20gJ2NvbXBvbmVudHMvUHJvZ3Jlc3NCYXInO1xuaW1wb3J0ICogYXMgcHVibGlzaFN0YXRlcyBmcm9tICdjb25zdGFudHMvcHVibGlzaF9jbGFpbV9zdGF0ZXMnO1xuXG5jbGFzcyBQdWJsaXNoU3RhdHVzIGV4dGVuZHMgUmVhY3QuQ29tcG9uZW50IHtcbiAgcmVuZGVyICgpIHtcbiAgICBjb25zdCB7IHN0YXR1cywgbWVzc2FnZSwgY2xlYXJGaWxlIH0gPSB0aGlzLnByb3BzO1xuICAgIHJldHVybiAoXG4gICAgICA8ZGl2IGNsYXNzTmFtZT0ncm93IHJvdy0tdGFsbCBmbGV4LWNvbnRhaW5lci0tY29sdW1uIGZsZXgtY29udGFpbmVyLS1jZW50ZXItY2VudGVyJz5cbiAgICAgICAge3N0YXR1cyA9PT0gcHVibGlzaFN0YXRlcy5MT0FEX1NUQVJUICYmXG4gICAgICAgIDxkaXYgY2xhc3NOYW1lPSdyb3cgYWxpZ24tY29udGVudC1jZW50ZXInPlxuICAgICAgICAgIDxwPkZpbGUgaXMgbG9hZGluZyB0byBzZXJ2ZXI8L3A+XG4gICAgICAgICAgPHAgY2xhc3NOYW1lPSdibHVlJz4wJTwvcD5cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIH1cbiAgICAgICAge3N0YXR1cyA9PT0gcHVibGlzaFN0YXRlcy5MT0FESU5HICYmXG4gICAgICAgIDxkaXY+XG4gICAgICAgICAgPGRpdiBjbGFzc05hbWU9J3JvdyBhbGlnbi1jb250ZW50LWNlbnRlcic+XG4gICAgICAgICAgICA8cD5GaWxlIGlzIGxvYWRpbmcgdG8gc2VydmVyPC9wPlxuICAgICAgICAgICAgPHAgY2xhc3NOYW1lPSdibHVlJz57bWVzc2FnZX08L3A+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICB9XG4gICAgICAgIHtzdGF0dXMgPT09IHB1Ymxpc2hTdGF0ZXMuUFVCTElTSElORyAmJlxuICAgICAgICA8ZGl2IGNsYXNzTmFtZT0ncm93IGFsaWduLWNvbnRlbnQtY2VudGVyJz5cbiAgICAgICAgICA8cD5VcGxvYWQgY29tcGxldGUuICBZb3VyIGZpbGUgaXMgbm93IGJlaW5nIHB1Ymxpc2hlZCBvbiB0aGUgYmxvY2tjaGFpbi4uLjwvcD5cbiAgICAgICAgICA8UHJvZ3Jlc3NCYXIgc2l6ZT17MTJ9IC8+XG4gICAgICAgICAgPHA+Q3VyaW91cyB3aGF0IG1hZ2ljIGlzIGhhcHBlbmluZyBoZXJlPyA8YSBjbGFzc05hbWU9J2xpbmstLXByaW1hcnknIHRhcmdldD0nYmxhbmsnIGhyZWY9J2h0dHBzOi8vbGJyeS5pby9mYXEvd2hhdC1pcy1sYnJ5Jz5MZWFybiBtb3JlLjwvYT48L3A+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICB9XG4gICAgICAgIHtzdGF0dXMgPT09IHB1Ymxpc2hTdGF0ZXMuU1VDQ0VTUyAmJlxuICAgICAgICA8ZGl2IGNsYXNzTmFtZT0ncm93IGFsaWduLWNvbnRlbnQtY2VudGVyJz5cbiAgICAgICAgICA8cD5Zb3VyIHB1Ymxpc2ggaXMgY29tcGxldGUhIFlvdSBhcmUgYmVpbmcgcmVkaXJlY3RlZCB0byBpdCBub3cuPC9wPlxuICAgICAgICAgIDxwPklmIHlvdSBhcmUgbm90IGF1dG9tYXRpY2FsbHkgcmVkaXJlY3RlZCwgPGEgY2xhc3NOYW1lPSdsaW5rLS1wcmltYXJ5JyB0YXJnZXQ9J19ibGFuaycgaHJlZj17bWVzc2FnZX0+Y2xpY2sgaGVyZS48L2E+PC9wPlxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgfVxuICAgICAgICB7c3RhdHVzID09PSBwdWJsaXNoU3RhdGVzLkZBSUxFRCAmJlxuICAgICAgICA8ZGl2IGNsYXNzTmFtZT0ncm93IGFsaWduLWNvbnRlbnQtY2VudGVyJz5cbiAgICAgICAgICA8cD5Tb21ldGhpbmcgd2VudCB3cm9uZy4uLjwvcD5cbiAgICAgICAgICA8cD48c3Ryb25nPnttZXNzYWdlfTwvc3Ryb25nPjwvcD5cbiAgICAgICAgICA8cD5Gb3IgaGVscCwgcG9zdCB0aGUgYWJvdmUgZXJyb3IgdGV4dCBpbiB0aGUgI3NwZWVjaCBjaGFubmVsIG9uIHRoZSA8YSBjbGFzc05hbWU9J2xpbmstLXByaW1hcnknIGhyZWY9J2h0dHBzOi8vZGlzY29yZC5nZy9Zallid2hTJyB0YXJnZXQ9J19ibGFuayc+bGJyeSBkaXNjb3JkPC9hPjwvcD5cbiAgICAgICAgICA8YnV0dG9uIGNsYXNzTmFtZT0nYnV0dG9uLS1zZWNvbmRhcnknIG9uQ2xpY2s9e2NsZWFyRmlsZX0+UmVzZXQ8L2J1dHRvbj5cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIH1cbiAgICAgIDwvZGl2PlxuICAgICk7XG4gIH1cbn07XG5cbmV4cG9ydCBkZWZhdWx0IFB1Ymxpc2hTdGF0dXM7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9jbGllbnQvY29udGFpbmVycy9QdWJsaXNoU3RhdHVzL3ZpZXcuanN4IiwiaW1wb3J0IHtjb25uZWN0fSBmcm9tICdyZWFjdC1yZWR1eCc7XG5pbXBvcnQgVmlldyBmcm9tICcuL3ZpZXcnO1xuXG5jb25zdCBtYXBTdGF0ZVRvUHJvcHMgPSAoeyBwdWJsaXNoIH0pID0+IHtcbiAgcmV0dXJuIHtcbiAgICBtZXNzYWdlOiBwdWJsaXNoLmRpc2FibGVkTWVzc2FnZSxcbiAgfTtcbn07XG5cbmV4cG9ydCBkZWZhdWx0IGNvbm5lY3QobWFwU3RhdGVUb1Byb3BzLCBudWxsKShWaWV3KTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL2NsaWVudC9jb250YWluZXJzL1B1Ymxpc2hEaXNhYmxlZE1lc3NhZ2UvaW5kZXguanMiLCJpbXBvcnQgUmVhY3QgZnJvbSAncmVhY3QnO1xuXG5jbGFzcyBQdWJsaXNoRGlzYWJsZWRNZXNzYWdlIGV4dGVuZHMgUmVhY3QuQ29tcG9uZW50IHtcbiAgcmVuZGVyICgpIHtcbiAgICBjb25zdCBtZXNzYWdlID0gdGhpcy5wcm9wcy5tZXNzYWdlO1xuICAgIGNvbnNvbGUubG9nKCd0aGlzLnByb3BzLm1lc3NhZ2U6JywgbWVzc2FnZSk7XG4gICAgcmV0dXJuIChcbiAgICAgIDxkaXYgY2xhc3NOYW1lPSdyb3cgZHJvcHpvbmUtLWRpc2FibGVkIHJvdy0tdGFsbCBmbGV4LWNvbnRhaW5lci0tY29sdW1uIGZsZXgtY29udGFpbmVyLS1jZW50ZXItY2VudGVyJz5cbiAgICAgICAgPHAgY2xhc3NOYW1lPSd0ZXh0LS1kaXNhYmxlZCc+UHVibGlzaGluZyBpcyBjdXJyZW50bHkgZGlzYWJsZWQuPC9wPlxuICAgICAgICA8cCBjbGFzc05hbWU9J3RleHQtLWRpc2FibGVkJz57bWVzc2FnZX08L3A+XG4gICAgICA8L2Rpdj5cbiAgICApO1xuICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IFB1Ymxpc2hEaXNhYmxlZE1lc3NhZ2U7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9jbGllbnQvY29udGFpbmVycy9QdWJsaXNoRGlzYWJsZWRNZXNzYWdlL3ZpZXcuanN4IiwiaW1wb3J0IFJlYWN0IGZyb20gJ3JlYWN0JztcbmltcG9ydCBOYXZCYXIgZnJvbSAnY29udGFpbmVycy9OYXZCYXInO1xuaW1wb3J0IFNFTyBmcm9tICdjb21wb25lbnRzL1NFTyc7XG5cbmNsYXNzIEFib3V0UGFnZSBleHRlbmRzIFJlYWN0LkNvbXBvbmVudCB7XG4gIHJlbmRlciAoKSB7XG4gICAgcmV0dXJuIChcbiAgICAgIDxkaXY+XG4gICAgICAgIDxTRU8gcGFnZVRpdGxlPXsnQWJvdXQnfSBwYWdlVXJpPXsnYWJvdXQnfSAvPlxuICAgICAgICA8TmF2QmFyIC8+XG4gICAgICAgIDxkaXYgY2xhc3NOYW1lPSdyb3cgcm93LS1wYWRkZWQnPlxuICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPSdjb2x1bW4gY29sdW1uLS01IGNvbHVtbi0tbWVkLTEwIGFsaWduLWNvbnRlbnQtdG9wJz5cbiAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPSdjb2x1bW4gY29sdW1uLS04IGNvbHVtbi0tbWVkLTEwJz5cbiAgICAgICAgICAgICAgPHAgY2xhc3NOYW1lPSdwdWxsLXF1b3RlJz5TcGVlLmNoIGlzIGFuIG9wZW4tc291cmNlIHByb2plY3QuICBQbGVhc2UgY29udHJpYnV0ZSB0byB0aGUgZXhpc3Rpbmcgc2l0ZSwgb3IgZm9yayBpdCBhbmQgbWFrZSB5b3VyIG93bi48L3A+XG4gICAgICAgICAgICAgIDxwPjxhIGNsYXNzTmFtZT0nbGluay0tcHJpbWFyeScgdGFyZ2V0PSdfYmxhbmsnIGhyZWY9J2h0dHBzOi8vdHdpdHRlci5jb20vc3BlZV9jaCc+VFdJVFRFUjwvYT48L3A+XG4gICAgICAgICAgICAgIDxwPjxhIGNsYXNzTmFtZT0nbGluay0tcHJpbWFyeScgdGFyZ2V0PSdfYmxhbmsnIGhyZWY9J2h0dHBzOi8vZ2l0aHViLmNvbS9sYnJ5aW8vc3BlZS5jaCc+R0lUSFVCPC9hPjwvcD5cbiAgICAgICAgICAgICAgPHA+PGEgY2xhc3NOYW1lPSdsaW5rLS1wcmltYXJ5JyB0YXJnZXQ9J19ibGFuaycgaHJlZj0naHR0cHM6Ly9kaXNjb3JkLmdnL1lqWWJ3aFMnPkRJU0NPUkQgQ0hBTk5FTDwvYT48L3A+XG4gICAgICAgICAgICAgIDxwPjxhIGNsYXNzTmFtZT0nbGluay0tcHJpbWFyeScgdGFyZ2V0PSdfYmxhbmsnIGhyZWY9J2h0dHBzOi8vZ2l0aHViLmNvbS9sYnJ5aW8vc3BlZS5jaC9ibG9iL21hc3Rlci9SRUFETUUubWQnPkRPQ1VNRU5UQVRJT048L2E+PC9wPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC9kaXY+PGRpdiBjbGFzc05hbWU9J2NvbHVtbiBjb2x1bW4tLTUgY29sdW1uLS1tZWQtMTAgYWxpZ24tY29udGVudC10b3AnPlxuICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9J2NvbHVtbiBjb2x1bW4tLTggY29sdW1uLS1tZWQtMTAnPlxuICAgICAgICAgICAgICA8cD5TcGVlLmNoIGlzIGEgbWVkaWEtaG9zdGluZyBzaXRlIHRoYXQgcmVhZHMgZnJvbSBhbmQgcHVibGlzaGVzIGNvbnRlbnQgdG8gdGhlIDxhIGNsYXNzTmFtZT0nbGluay0tcHJpbWFyeScgaHJlZj0naHR0cHM6Ly9sYnJ5LmlvJz5MQlJZPC9hPiBibG9ja2NoYWluLjwvcD5cbiAgICAgICAgICAgICAgPHA+U3BlZS5jaCBpcyBhIGhvc3Rpbmcgc2VydmljZSwgYnV0IHdpdGggdGhlIGFkZGVkIGJlbmVmaXQgdGhhdCBpdCBzdG9yZXMgeW91ciBjb250ZW50IG9uIGEgZGVjZW50cmFsaXplZCBuZXR3b3JrIG9mIGNvbXB1dGVycyAtLSB0aGUgPGEgY2xhc3NOYW1lPSdsaW5rLS1wcmltYXJ5JyBocmVmPSdodHRwczovL2xicnkuaW8vZ2V0Jz5MQlJZPC9hPiBuZXR3b3JrLiAgVGhpcyBtZWFucyB0aGF0IHlvdXIgaW1hZ2VzIGFyZSBzdG9yZWQgaW4gbXVsdGlwbGUgbG9jYXRpb25zIHdpdGhvdXQgYSBzaW5nbGUgcG9pbnQgb2YgZmFpbHVyZS48L3A+XG4gICAgICAgICAgICAgIDxoMz5Db250cmlidXRlPC9oMz5cbiAgICAgICAgICAgICAgPHA+SWYgeW91IGhhdmUgYW4gaWRlYSBmb3IgeW91ciBvd24gc3BlZS5jaC1saWtlIHNpdGUgb24gdG9wIG9mIExCUlksIGZvcmsgb3VyIDxhIGNsYXNzTmFtZT0nbGluay0tcHJpbWFyeScgaHJlZj0naHR0cHM6Ly9naXRodWIuY29tL2xicnlpby9zcGVlLmNoJz5naXRodWIgcmVwbzwvYT4gYW5kIGdvIHRvIHRvd24hPC9wPlxuICAgICAgICAgICAgICA8cD5JZiB5b3Ugd2FudCB0byBpbXByb3ZlIHNwZWUuY2gsIGpvaW4gb3VyIDxhIGNsYXNzTmFtZT0nbGluay0tcHJpbWFyeScgaHJlZj0naHR0cHM6Ly9kaXNjb3JkLmdnL1lqWWJ3aFMnPmRpc2NvcmQgY2hhbm5lbDwvYT4gb3Igc29sdmUgb25lIG9mIG91ciA8YSBjbGFzc05hbWU9J2xpbmstLXByaW1hcnknIGhyZWY9J2h0dHBzOi8vZ2l0aHViLmNvbS9sYnJ5aW8vc3BlZS5jaC9pc3N1ZXMnPmdpdGh1YiBpc3N1ZXM8L2E+LjwvcD5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuICAgICk7XG4gIH1cbn07XG5cbmV4cG9ydCBkZWZhdWx0IEFib3V0UGFnZTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL2NsaWVudC9wYWdlcy9BYm91dFBhZ2UvaW5kZXguanN4IiwiaW1wb3J0IHtjb25uZWN0fSBmcm9tICdyZWFjdC1yZWR1eCc7XG5pbXBvcnQgVmlldyBmcm9tICcuL3ZpZXcnO1xuXG5jb25zdCBtYXBTdGF0ZVRvUHJvcHMgPSAoeyBjaGFubmVsIH0pID0+IHtcbiAgcmV0dXJuIHtcbiAgICBsb2dnZWRJbkNoYW5uZWxOYW1lOiBjaGFubmVsLmxvZ2dlZEluQ2hhbm5lbC5uYW1lLFxuICB9O1xufTtcblxuZXhwb3J0IGRlZmF1bHQgY29ubmVjdChtYXBTdGF0ZVRvUHJvcHMsIG51bGwpKFZpZXcpO1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vY2xpZW50L3BhZ2VzL0xvZ2luUGFnZS9pbmRleC5qcyIsImltcG9ydCBSZWFjdCBmcm9tICdyZWFjdCc7XG5pbXBvcnQgeyB3aXRoUm91dGVyIH0gZnJvbSAncmVhY3Qtcm91dGVyLWRvbSc7XG5pbXBvcnQgU0VPIGZyb20gJ2NvbXBvbmVudHMvU0VPJztcbmltcG9ydCBOYXZCYXIgZnJvbSAnY29udGFpbmVycy9OYXZCYXInO1xuaW1wb3J0IENoYW5uZWxMb2dpbkZvcm0gZnJvbSAnY29udGFpbmVycy9DaGFubmVsTG9naW5Gb3JtJztcbmltcG9ydCBDaGFubmVsQ3JlYXRlRm9ybSBmcm9tICdjb250YWluZXJzL0NoYW5uZWxDcmVhdGVGb3JtJztcblxuY2xhc3MgTG9naW5QYWdlIGV4dGVuZHMgUmVhY3QuQ29tcG9uZW50IHtcbiAgY29tcG9uZW50V2lsbFJlY2VpdmVQcm9wcyAobmV3UHJvcHMpIHtcbiAgICAvLyByZS1yb3V0ZSB0aGUgdXNlciB0byB0aGUgaG9tZXBhZ2UgaWYgdGhlIHVzZXIgaXMgbG9nZ2VkIGluXG4gICAgaWYgKG5ld1Byb3BzLmxvZ2dlZEluQ2hhbm5lbE5hbWUgIT09IHRoaXMucHJvcHMubG9nZ2VkSW5DaGFubmVsTmFtZSkge1xuICAgICAgdGhpcy5wcm9wcy5oaXN0b3J5LnB1c2goYC9gKTtcbiAgICB9XG4gIH1cbiAgcmVuZGVyICgpIHtcbiAgICByZXR1cm4gKFxuICAgICAgPGRpdj5cbiAgICAgICAgPFNFTyBwYWdlVGl0bGU9eydMb2dpbid9IHBhZ2VVcmk9eydsb2dpbid9IC8+XG4gICAgICAgIDxOYXZCYXIgLz5cbiAgICAgICAgPGRpdiBjbGFzc05hbWU9J3JvdyByb3ctLXBhZGRlZCc+XG4gICAgICAgICAgPGRpdiBjbGFzc05hbWU9J2NvbHVtbiBjb2x1bW4tLTUgY29sdW1uLS1tZWQtMTAgYWxpZ24tY29udGVudC10b3AnPlxuICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9J2NvbHVtbiBjb2x1bW4tLTggY29sdW1uLS1tZWQtMTAnPlxuICAgICAgICAgICAgICA8cD5DaGFubmVscyBhbGxvdyB5b3UgdG8gcHVibGlzaCBhbmQgZ3JvdXAgY29udGVudCB1bmRlciBhbiBpZGVudGl0eS4gWW91IGNhbiBjcmVhdGUgYSBjaGFubmVsIGZvciB5b3Vyc2VsZiwgb3Igc2hhcmUgb25lIHdpdGggbGlrZS1taW5kZWQgZnJpZW5kcy4gIFlvdSBjYW4gY3JlYXRlIDEgY2hhbm5lbCwgb3IgMTAwLCBzbyB3aGV0aGVyIHlvdSdyZSA8YSBjbGFzc05hbWU9J2xpbmstLXByaW1hcnknIHRhcmdldD0nX2JsYW5rJyBocmVmPScvQGNhdGFsb25pYTIwMTc6NDNkY2Y0NzE2M2NhYTIxZDg0MDRkOWZlOWIzMGY3OGVmM2UxNDZhOCc+ZG9jdW1lbnRpbmcgaW1wb3J0YW50IGV2ZW50czwvYT4sIG9yIG1ha2luZyBhIHB1YmxpYyByZXBvc2l0b3J5IGZvciA8YSBjbGFzc05hbWU9J2xpbmstLXByaW1hcnknIHRhcmdldD0nX2JsYW5rJyBocmVmPScvQGNhdEdpZnMnPmNhdCBnaWZzPC9hPiAocGFzc3dvcmQ6ICcxMjM0JyksIHRyeSBjcmVhdGluZyBhIGNoYW5uZWwgZm9yIGl0ITwvcD5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwvZGl2PjxkaXYgY2xhc3NOYW1lPSdjb2x1bW4gY29sdW1uLS01IGNvbHVtbi0tbWVkLTEwIGFsaWduLWNvbnRlbnQtdG9wJz5cbiAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPSdjb2x1bW4gY29sdW1uLS04IGNvbHVtbi0tbWVkLTEwJz5cbiAgICAgICAgICAgICAgPGgzIGNsYXNzTmFtZT0naDMtLW5vLWJvdHRvbSc+TG9nIGluIHRvIGFuIGV4aXN0aW5nIGNoYW5uZWw6PC9oMz5cbiAgICAgICAgICAgICAgPENoYW5uZWxMb2dpbkZvcm0gLz5cbiAgICAgICAgICAgICAgPGgzIGNsYXNzTmFtZT0naDMtLW5vLWJvdHRvbSc+Q3JlYXRlIGEgYnJhbmQgbmV3IGNoYW5uZWw6PC9oMz5cbiAgICAgICAgICAgICAgPENoYW5uZWxDcmVhdGVGb3JtIC8+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cbiAgICApO1xuICB9XG59O1xuXG5leHBvcnQgZGVmYXVsdCB3aXRoUm91dGVyKExvZ2luUGFnZSk7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9jbGllbnQvcGFnZXMvTG9naW5QYWdlL3ZpZXcuanN4IiwiaW1wb3J0IHsgY29ubmVjdCB9IGZyb20gJ3JlYWN0LXJlZHV4JztcbmltcG9ydCB7IG9uSGFuZGxlU2hvd1BhZ2VVcmkgfSBmcm9tICdhY3Rpb25zL3Nob3cnO1xuaW1wb3J0IFZpZXcgZnJvbSAnLi92aWV3JztcblxuY29uc3QgbWFwU3RhdGVUb1Byb3BzID0gKHsgc2hvdyB9KSA9PiB7XG4gIHJldHVybiB7XG4gICAgZXJyb3IgICAgICA6IHNob3cucmVxdWVzdC5lcnJvcixcbiAgICByZXF1ZXN0VHlwZTogc2hvdy5yZXF1ZXN0LnR5cGUsXG4gIH07XG59O1xuXG5jb25zdCBtYXBEaXNwYXRjaFRvUHJvcHMgPSB7XG4gIG9uSGFuZGxlU2hvd1BhZ2VVcmksXG59O1xuXG5leHBvcnQgZGVmYXVsdCBjb25uZWN0KG1hcFN0YXRlVG9Qcm9wcywgbWFwRGlzcGF0Y2hUb1Byb3BzKShWaWV3KTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL2NsaWVudC9wYWdlcy9TaG93UGFnZS9pbmRleC5qcyIsImltcG9ydCBSZWFjdCBmcm9tICdyZWFjdCc7XG5pbXBvcnQgRXJyb3JQYWdlIGZyb20gJ3BhZ2VzL0Vycm9yUGFnZSc7XG5pbXBvcnQgU2hvd0Fzc2V0TGl0ZSBmcm9tICdjb250YWluZXJzL1Nob3dBc3NldExpdGUnO1xuaW1wb3J0IFNob3dBc3NldERldGFpbHMgZnJvbSAnY29udGFpbmVycy9TaG93QXNzZXREZXRhaWxzJztcbmltcG9ydCBTaG93Q2hhbm5lbCBmcm9tICdjb250YWluZXJzL1Nob3dDaGFubmVsJztcblxuaW1wb3J0IHsgQ0hBTk5FTCwgQVNTRVRfTElURSwgQVNTRVRfREVUQUlMUyB9IGZyb20gJ2NvbnN0YW50cy9zaG93X3JlcXVlc3RfdHlwZXMnO1xuXG5jbGFzcyBTaG93UGFnZSBleHRlbmRzIFJlYWN0LkNvbXBvbmVudCB7XG4gIGNvbXBvbmVudERpZE1vdW50ICgpIHtcbiAgICB0aGlzLnByb3BzLm9uSGFuZGxlU2hvd1BhZ2VVcmkodGhpcy5wcm9wcy5tYXRjaC5wYXJhbXMpO1xuICB9XG4gIGNvbXBvbmVudFdpbGxSZWNlaXZlUHJvcHMgKG5leHRQcm9wcykge1xuICAgIGlmIChuZXh0UHJvcHMubWF0Y2gucGFyYW1zICE9PSB0aGlzLnByb3BzLm1hdGNoLnBhcmFtcykge1xuICAgICAgdGhpcy5wcm9wcy5vbkhhbmRsZVNob3dQYWdlVXJpKG5leHRQcm9wcy5tYXRjaC5wYXJhbXMpO1xuICAgIH1cbiAgfVxuICByZW5kZXIgKCkge1xuICAgIGNvbnN0IHsgZXJyb3IsIHJlcXVlc3RUeXBlIH0gPSB0aGlzLnByb3BzO1xuICAgIGlmIChlcnJvcikge1xuICAgICAgcmV0dXJuIChcbiAgICAgICAgPEVycm9yUGFnZSBlcnJvcj17ZXJyb3J9IC8+XG4gICAgICApO1xuICAgIH1cbiAgICBzd2l0Y2ggKHJlcXVlc3RUeXBlKSB7XG4gICAgICBjYXNlIENIQU5ORUw6XG4gICAgICAgIHJldHVybiA8U2hvd0NoYW5uZWwgLz47XG4gICAgICBjYXNlIEFTU0VUX0xJVEU6XG4gICAgICAgIHJldHVybiA8U2hvd0Fzc2V0TGl0ZSAvPjtcbiAgICAgIGNhc2UgQVNTRVRfREVUQUlMUzpcbiAgICAgICAgcmV0dXJuIDxTaG93QXNzZXREZXRhaWxzIC8+O1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgcmV0dXJuIDxwPmxvYWRpbmcuLi48L3A+O1xuICAgIH1cbiAgfVxufTtcblxuZXhwb3J0IGRlZmF1bHQgU2hvd1BhZ2U7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9jbGllbnQvcGFnZXMvU2hvd1BhZ2Uvdmlldy5qc3giLCJpbXBvcnQgeyBjb25uZWN0IH0gZnJvbSAncmVhY3QtcmVkdXgnO1xuaW1wb3J0IFZpZXcgZnJvbSAnLi92aWV3JztcblxuY29uc3QgbWFwU3RhdGVUb1Byb3BzID0gKHsgc2hvdyB9KSA9PiB7XG4gIC8vIHNlbGVjdCByZXF1ZXN0IGluZm9cbiAgY29uc3QgcmVxdWVzdElkID0gc2hvdy5yZXF1ZXN0LmlkO1xuICAvLyBzZWxlY3QgYXNzZXQgaW5mb1xuICBsZXQgYXNzZXQ7XG4gIGNvbnN0IHJlcXVlc3QgPSBzaG93LnJlcXVlc3RMaXN0W3JlcXVlc3RJZF0gfHwgbnVsbDtcbiAgY29uc3QgYXNzZXRMaXN0ID0gc2hvdy5hc3NldExpc3Q7XG4gIGlmIChyZXF1ZXN0ICYmIGFzc2V0TGlzdCkge1xuICAgIGNvbnN0IGFzc2V0S2V5ID0gcmVxdWVzdC5rZXk7ICAvLyBub3RlOiBqdXN0IHN0b3JlIHRoaXMgaW4gdGhlIHJlcXVlc3RcbiAgICBhc3NldCA9IGFzc2V0TGlzdFthc3NldEtleV0gfHwgbnVsbDtcbiAgfTtcbiAgLy8gcmV0dXJuIHByb3BzXG4gIHJldHVybiB7XG4gICAgYXNzZXQsXG4gIH07XG59O1xuXG5leHBvcnQgZGVmYXVsdCBjb25uZWN0KG1hcFN0YXRlVG9Qcm9wcywgbnVsbCkoVmlldyk7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9jbGllbnQvY29udGFpbmVycy9TaG93QXNzZXRMaXRlL2luZGV4LmpzIiwiaW1wb3J0IFJlYWN0IGZyb20gJ3JlYWN0JztcbmltcG9ydCBTRU8gZnJvbSAnY29tcG9uZW50cy9TRU8nO1xuaW1wb3J0IHsgTGluayB9IGZyb20gJ3JlYWN0LXJvdXRlci1kb20nO1xuaW1wb3J0IEFzc2V0RGlzcGxheSBmcm9tICdjb250YWluZXJzL0Fzc2V0RGlzcGxheSc7XG5cbmNsYXNzIFNob3dMaXRlIGV4dGVuZHMgUmVhY3QuQ29tcG9uZW50IHtcbiAgcmVuZGVyICgpIHtcbiAgICBjb25zdCB7IGFzc2V0IH0gPSB0aGlzLnByb3BzO1xuICAgIGlmIChhc3NldCkge1xuICAgICAgY29uc3QgeyBuYW1lLCBjbGFpbUlkIH0gPSBhc3NldC5jbGFpbURhdGE7XG4gICAgICByZXR1cm4gKFxuICAgICAgICA8ZGl2IGNsYXNzTmFtZT0ncm93IHJvdy0tdGFsbCBmbGV4LWNvbnRhaW5lci0tY29sdW1uIGZsZXgtY29udGFpbmVyLS1jZW50ZXItY2VudGVyIHNob3ctbGl0ZS1jb250YWluZXInPlxuICAgICAgICAgIDxTRU8gcGFnZVRpdGxlPXtuYW1lfSBhc3NldD17YXNzZXR9IC8+XG4gICAgICAgICAgPEFzc2V0RGlzcGxheSAvPlxuICAgICAgICAgIDxMaW5rIGlkPSdhc3NldC1ib2lsZXJwYXRlJyBjbGFzc05hbWU9J2xpbmstLXByaW1hcnkgZmluZS1wcmludCcgdG89e2AvJHtjbGFpbUlkfS8ke25hbWV9YH0+aG9zdGVkXG4gICAgICAgICAgICB2aWEgU3BlZS5jaDwvTGluaz5cbiAgICAgICAgPC9kaXY+XG4gICAgICApO1xuICAgIH1cbiAgICByZXR1cm4gKFxuICAgICAgPGRpdiBjbGFzc05hbWU9J3JvdyByb3ctLXRhbGwgcm93LS1wYWRkZWQgZmxleC1jb250YWluZXItLWNvbHVtbiBmbGV4LWNvbnRhaW5lci0tY2VudGVyLWNlbnRlcic+XG4gICAgICAgIDxwPmxvYWRpbmcgYXNzZXQgZGF0YS4uLjwvcD5cbiAgICAgIDwvZGl2PlxuICAgICk7XG4gIH1cbn07XG5cbmV4cG9ydCBkZWZhdWx0IFNob3dMaXRlO1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vY2xpZW50L2NvbnRhaW5lcnMvU2hvd0Fzc2V0TGl0ZS92aWV3LmpzeCIsImltcG9ydCBSZWFjdCBmcm9tICdyZWFjdCc7XG5pbXBvcnQgUHJvZ3Jlc3NCYXIgZnJvbSAnY29tcG9uZW50cy9Qcm9ncmVzc0Jhcic7XG5pbXBvcnQgeyBMT0NBTF9DSEVDSywgVU5BVkFJTEFCTEUsIEVSUk9SLCBBVkFJTEFCTEUgfSBmcm9tICdjb25zdGFudHMvYXNzZXRfZGlzcGxheV9zdGF0ZXMnO1xuXG5jbGFzcyBBc3NldERpc3BsYXkgZXh0ZW5kcyBSZWFjdC5Db21wb25lbnQge1xuICBjb21wb25lbnREaWRNb3VudCAoKSB7XG4gICAgY29uc3QgeyBhc3NldDogeyBjbGFpbURhdGE6IHsgbmFtZSwgY2xhaW1JZCB9IH0gfSA9IHRoaXMucHJvcHM7XG4gICAgdGhpcy5wcm9wcy5vbkZpbGVSZXF1ZXN0KG5hbWUsIGNsYWltSWQpO1xuICB9XG4gIHJlbmRlciAoKSB7XG4gICAgY29uc3QgeyBzdGF0dXMsIGVycm9yLCBhc3NldDogeyBjbGFpbURhdGE6IHsgbmFtZSwgY2xhaW1JZCwgY29udGVudFR5cGUsIGZpbGVFeHQsIHRodW1ibmFpbCB9IH0gfSA9IHRoaXMucHJvcHM7XG4gICAgcmV0dXJuIChcbiAgICAgIDxkaXYgaWQ9J2Fzc2V0LWRpc3BsYXktY29tcG9uZW50Jz5cbiAgICAgICAgeyhzdGF0dXMgPT09IExPQ0FMX0NIRUNLKSAmJlxuICAgICAgICA8ZGl2PlxuICAgICAgICAgIDxwPkNoZWNraW5nIHRvIHNlZSBpZiBTcGVlLmNoIGhhcyB5b3VyIGFzc2V0IGxvY2FsbHkuLi48L3A+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICB9XG4gICAgICAgIHsoc3RhdHVzID09PSBVTkFWQUlMQUJMRSkgJiZcbiAgICAgICAgPGRpdj5cbiAgICAgICAgICA8cD5TaXQgdGlnaHQsIHdlJ3JlIHNlYXJjaGluZyB0aGUgTEJSWSBibG9ja2NoYWluIGZvciB5b3VyIGFzc2V0ITwvcD5cbiAgICAgICAgICA8UHJvZ3Jlc3NCYXIgc2l6ZT17MTJ9IC8+XG4gICAgICAgICAgPHA+Q3VyaW91cyB3aGF0IG1hZ2ljIGlzIGhhcHBlbmluZyBoZXJlPyA8YSBjbGFzc05hbWU9J2xpbmstLXByaW1hcnknIHRhcmdldD0nYmxhbmsnIGhyZWY9J2h0dHBzOi8vbGJyeS5pby9mYXEvd2hhdC1pcy1sYnJ5Jz5MZWFybiBtb3JlLjwvYT48L3A+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICB9XG4gICAgICAgIHsoc3RhdHVzID09PSBFUlJPUikgJiZcbiAgICAgICAgPGRpdj5cbiAgICAgICAgICA8cD5VbmZvcnR1bmF0ZWx5LCB3ZSBjb3VsZG4ndCBkb3dubG9hZCB5b3VyIGFzc2V0IGZyb20gTEJSWS4gIFlvdSBjYW4gaGVscCB1cyBvdXQgYnkgc2hhcmluZyB0aGUgYmVsb3cgZXJyb3IgbWVzc2FnZSBpbiB0aGUgPGEgY2xhc3NOYW1lPSdsaW5rLS1wcmltYXJ5JyBocmVmPSdodHRwczovL2Rpc2NvcmQuZ2cvWWpZYndoUycgdGFyZ2V0PSdfYmxhbmsnPkxCUlkgZGlzY29yZDwvYT4uPC9wPlxuICAgICAgICAgIDxpPjxwIGlkPSdlcnJvci1tZXNzYWdlJz57ZXJyb3J9PC9wPjwvaT5cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIH1cbiAgICAgICAgeyhzdGF0dXMgPT09IEFWQUlMQUJMRSkgJiZcbiAgICAgICAgKCgpID0+IHtcbiAgICAgICAgICBzd2l0Y2ggKGNvbnRlbnRUeXBlKSB7XG4gICAgICAgICAgICBjYXNlICdpbWFnZS9qcGVnJzpcbiAgICAgICAgICAgIGNhc2UgJ2ltYWdlL2pwZyc6XG4gICAgICAgICAgICBjYXNlICdpbWFnZS9wbmcnOlxuICAgICAgICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgICAgIDxpbWdcbiAgICAgICAgICAgICAgICAgIGNsYXNzTmFtZT0nYXNzZXQnXG4gICAgICAgICAgICAgICAgICBzcmM9e2AvJHtjbGFpbUlkfS8ke25hbWV9LiR7ZmlsZUV4dH1gfVxuICAgICAgICAgICAgICAgICAgYWx0PXtuYW1lfSAvPlxuICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgY2FzZSAnaW1hZ2UvZ2lmJzpcbiAgICAgICAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgICAgICA8aW1nXG4gICAgICAgICAgICAgICAgICBjbGFzc05hbWU9J2Fzc2V0J1xuICAgICAgICAgICAgICAgICAgc3JjPXtgLyR7Y2xhaW1JZH0vJHtuYW1lfS4ke2ZpbGVFeHR9YH1cbiAgICAgICAgICAgICAgICAgIGFsdD17bmFtZX1cbiAgICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgY2FzZSAndmlkZW8vbXA0JzpcbiAgICAgICAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgICAgICA8dmlkZW8gY2xhc3NOYW1lPSdhc3NldCB2aWRlbycgY29udHJvbHMgcG9zdGVyPXt0aHVtYm5haWx9PlxuICAgICAgICAgICAgICAgICAgPHNvdXJjZVxuICAgICAgICAgICAgICAgICAgICBzcmM9e2AvJHtjbGFpbUlkfS8ke25hbWV9LiR7ZmlsZUV4dH1gfVxuICAgICAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgICAgIDxwPllvdXIgYnJvd3NlciBkb2VzIG5vdCBzdXBwb3J0IHRoZSA8Y29kZT52aWRlbzwvY29kZT4gZWxlbWVudC48L3A+XG4gICAgICAgICAgICAgICAgPC92aWRlbz5cbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICAgICAgPHA+VW5zdXBwb3J0ZWQgZmlsZSB0eXBlPC9wPlxuICAgICAgICAgICAgICApO1xuICAgICAgICAgIH1cbiAgICAgICAgfSkoKVxuICAgICAgICB9XG4gICAgICA8L2Rpdj5cbiAgICApO1xuICB9XG59O1xuXG5leHBvcnQgZGVmYXVsdCBBc3NldERpc3BsYXk7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9jbGllbnQvY29udGFpbmVycy9Bc3NldERpc3BsYXkvdmlldy5qc3giLCJpbXBvcnQgeyBjb25uZWN0IH0gZnJvbSAncmVhY3QtcmVkdXgnO1xuaW1wb3J0IFZpZXcgZnJvbSAnLi92aWV3JztcblxuY29uc3QgbWFwU3RhdGVUb1Byb3BzID0gKHsgc2hvdyB9KSA9PiB7XG4gIC8vIHNlbGVjdCByZXF1ZXN0IGluZm9cbiAgY29uc3QgcmVxdWVzdElkID0gc2hvdy5yZXF1ZXN0LmlkO1xuICAvLyBzZWxlY3QgYXNzZXQgaW5mb1xuICBsZXQgYXNzZXQ7XG4gIGNvbnN0IHJlcXVlc3QgPSBzaG93LnJlcXVlc3RMaXN0W3JlcXVlc3RJZF0gfHwgbnVsbDtcbiAgY29uc3QgYXNzZXRMaXN0ID0gc2hvdy5hc3NldExpc3Q7XG4gIGlmIChyZXF1ZXN0ICYmIGFzc2V0TGlzdCkge1xuICAgIGNvbnN0IGFzc2V0S2V5ID0gcmVxdWVzdC5rZXk7ICAvLyBub3RlOiBqdXN0IHN0b3JlIHRoaXMgaW4gdGhlIHJlcXVlc3RcbiAgICBhc3NldCA9IGFzc2V0TGlzdFthc3NldEtleV0gfHwgbnVsbDtcbiAgfTtcbiAgLy8gcmV0dXJuIHByb3BzXG4gIHJldHVybiB7XG4gICAgYXNzZXQsXG4gIH07XG59O1xuXG5leHBvcnQgZGVmYXVsdCBjb25uZWN0KG1hcFN0YXRlVG9Qcm9wcywgbnVsbCkoVmlldyk7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9jbGllbnQvY29udGFpbmVycy9TaG93QXNzZXREZXRhaWxzL2luZGV4LmpzIiwiaW1wb3J0IFJlYWN0IGZyb20gJ3JlYWN0JztcbmltcG9ydCBTRU8gZnJvbSAnY29tcG9uZW50cy9TRU8nO1xuaW1wb3J0IE5hdkJhciBmcm9tICdjb250YWluZXJzL05hdkJhcic7XG5pbXBvcnQgRXJyb3JQYWdlIGZyb20gJ3BhZ2VzL0Vycm9yUGFnZSc7XG5pbXBvcnQgQXNzZXRUaXRsZSBmcm9tICdjb250YWluZXJzL0Fzc2V0VGl0bGUnO1xuaW1wb3J0IEFzc2V0RGlzcGxheSBmcm9tICdjb250YWluZXJzL0Fzc2V0RGlzcGxheSc7XG5pbXBvcnQgQXNzZXRJbmZvIGZyb20gJ2NvbnRhaW5lcnMvQXNzZXRJbmZvJztcblxuY2xhc3MgU2hvd0Fzc2V0RGV0YWlscyBleHRlbmRzIFJlYWN0LkNvbXBvbmVudCB7XG4gIHJlbmRlciAoKSB7XG4gICAgY29uc3QgeyBhc3NldCB9ID0gdGhpcy5wcm9wcztcbiAgICBpZiAoYXNzZXQpIHtcbiAgICAgIGNvbnN0IHsgY2xhaW1EYXRhOiB7IG5hbWUgfSB9ID0gYXNzZXQ7XG4gICAgICByZXR1cm4gKFxuICAgICAgICA8ZGl2PlxuICAgICAgICAgIDxTRU8gcGFnZVRpdGxlPXtgJHtuYW1lfSAtIGRldGFpbHNgfSBhc3NldD17YXNzZXR9IC8+XG4gICAgICAgICAgPE5hdkJhciAvPlxuICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPSdyb3cgcm93LS10YWxsIHJvdy0tcGFkZGVkJz5cbiAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPSdjb2x1bW4gY29sdW1uLS0xMCc+XG4gICAgICAgICAgICAgIDxBc3NldFRpdGxlIC8+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPSdjb2x1bW4gY29sdW1uLS01IGNvbHVtbi0tc21sLTEwIGFsaWduLWNvbnRlbnQtdG9wJz5cbiAgICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9J3JvdyByb3ctLXBhZGRlZCBzaG93LWRldGFpbHMtY29udGFpbmVyJz5cbiAgICAgICAgICAgICAgICA8QXNzZXREaXNwbGF5IC8+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+PGRpdiBjbGFzc05hbWU9J2NvbHVtbiBjb2x1bW4tLTUgY29sdW1uLS1zbWwtMTAgYWxpZ24tY29udGVudC10b3AnPlxuICAgICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT0ncm93IHJvdy0tcGFkZGVkJz5cbiAgICAgICAgICAgICAgICA8QXNzZXRJbmZvIC8+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgICAgKTtcbiAgICB9O1xuICAgIHJldHVybiAoXG4gICAgICA8RXJyb3JQYWdlIGVycm9yPXsnbG9hZGluZyBhc3NldCBkYXRhLi4uJ30gLz5cbiAgICApO1xuICB9XG59O1xuXG5leHBvcnQgZGVmYXVsdCBTaG93QXNzZXREZXRhaWxzO1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vY2xpZW50L2NvbnRhaW5lcnMvU2hvd0Fzc2V0RGV0YWlscy92aWV3LmpzeCIsImltcG9ydCB7IGNvbm5lY3QgfSBmcm9tICdyZWFjdC1yZWR1eCc7XG5pbXBvcnQgVmlldyBmcm9tICcuL3ZpZXcnO1xuaW1wb3J0IHsgc2VsZWN0QXNzZXQgfSBmcm9tICdzZWxlY3RvcnMvc2hvdyc7XG5cbmNvbnN0IG1hcFN0YXRlVG9Qcm9wcyA9ICh7IHNob3cgfSkgPT4ge1xuICBjb25zdCB7IGNsYWltRGF0YTogeyB0aXRsZSB9IH0gPSBzZWxlY3RBc3NldChzaG93KTtcbiAgcmV0dXJuIHtcbiAgICB0aXRsZSxcbiAgfTtcbn07XG5cbmV4cG9ydCBkZWZhdWx0IGNvbm5lY3QobWFwU3RhdGVUb1Byb3BzLCBudWxsKShWaWV3KTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL2NsaWVudC9jb250YWluZXJzL0Fzc2V0VGl0bGUvaW5kZXguanMiLCJpbXBvcnQgUmVhY3QgZnJvbSAncmVhY3QnO1xuXG5jb25zdCBBc3NldFRpdGxlID0gKHsgdGl0bGUgfSkgPT4ge1xuICByZXR1cm4gKFxuICAgIDxkaXY+XG4gICAgICA8c3BhbiBjbGFzc05hbWU9J3RleHQtLWxhcmdlJz57dGl0bGV9PC9zcGFuPlxuICAgIDwvZGl2PlxuICApO1xufTtcblxuZXhwb3J0IGRlZmF1bHQgQXNzZXRUaXRsZTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL2NsaWVudC9jb250YWluZXJzL0Fzc2V0VGl0bGUvdmlldy5qc3giLCJpbXBvcnQgeyBjb25uZWN0IH0gZnJvbSAncmVhY3QtcmVkdXgnO1xuaW1wb3J0IFZpZXcgZnJvbSAnLi92aWV3JztcbmltcG9ydCB7IHNlbGVjdEFzc2V0IH0gZnJvbSAnc2VsZWN0b3JzL3Nob3cnO1xuXG5jb25zdCBtYXBTdGF0ZVRvUHJvcHMgPSAoeyBzaG93IH0pID0+IHtcbiAgLy8gc2VsZWN0IGFzc2V0XG4gIGNvbnN0IGFzc2V0ID0gc2VsZWN0QXNzZXQoc2hvdyk7XG4gIC8vICByZXR1cm4gcHJvcHNcbiAgcmV0dXJuIHtcbiAgICBhc3NldCxcbiAgfTtcbn07XG5cbmV4cG9ydCBkZWZhdWx0IGNvbm5lY3QobWFwU3RhdGVUb1Byb3BzLCBudWxsKShWaWV3KTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL2NsaWVudC9jb250YWluZXJzL0Fzc2V0SW5mby9pbmRleC5qcyIsImltcG9ydCBSZWFjdCBmcm9tICdyZWFjdCc7XG5pbXBvcnQgeyBMaW5rIH0gZnJvbSAncmVhY3Qtcm91dGVyLWRvbSc7XG5cbmNsYXNzIEFzc2V0SW5mbyBleHRlbmRzIFJlYWN0LkNvbXBvbmVudCB7XG4gIGNvbnN0cnVjdG9yIChwcm9wcykge1xuICAgIHN1cGVyKHByb3BzKTtcbiAgICB0aGlzLmNvcHlUb0NsaXBib2FyZCA9IHRoaXMuY29weVRvQ2xpcGJvYXJkLmJpbmQodGhpcyk7XG4gIH1cbiAgY29weVRvQ2xpcGJvYXJkIChldmVudCkge1xuICAgIHZhciBlbGVtZW50VG9Db3B5ID0gZXZlbnQudGFyZ2V0LmRhdGFzZXQuZWxlbWVudHRvY29weTtcbiAgICB2YXIgZWxlbWVudCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGVsZW1lbnRUb0NvcHkpO1xuICAgIGVsZW1lbnQuc2VsZWN0KCk7XG4gICAgdHJ5IHtcbiAgICAgIGRvY3VtZW50LmV4ZWNDb21tYW5kKCdjb3B5Jyk7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICB0aGlzLnNldFN0YXRlKHtlcnJvcjogJ09vcHMsIHVuYWJsZSB0byBjb3B5J30pO1xuICAgIH1cbiAgfVxuICByZW5kZXIgKCkge1xuICAgIGNvbnN0IHsgYXNzZXQ6IHsgc2hvcnRJZCwgY2xhaW1EYXRhIDogeyBjaGFubmVsTmFtZSwgY2VydGlmaWNhdGVJZCwgZGVzY3JpcHRpb24sIG5hbWUsIGNsYWltSWQsIGZpbGVFeHQsIGNvbnRlbnRUeXBlLCB0aHVtYm5haWwsIGhvc3QgfSB9IH0gPSB0aGlzLnByb3BzO1xuICAgIHJldHVybiAoXG4gICAgICA8ZGl2PlxuICAgICAgICB7Y2hhbm5lbE5hbWUgJiZcbiAgICAgICAgPGRpdiBjbGFzc05hbWU9J3JvdyByb3ctLXBhZGRlZCByb3ctLXdpZGUgcm93LS1uby10b3AnPlxuICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPSdjb2x1bW4gY29sdW1uLS0yIGNvbHVtbi0tbWVkLTEwJz5cbiAgICAgICAgICAgIDxzcGFuIGNsYXNzTmFtZT0ndGV4dCc+Q2hhbm5lbDo8L3NwYW4+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPGRpdiBjbGFzc05hbWU9J2NvbHVtbiBjb2x1bW4tLTggY29sdW1uLS1tZWQtMTAnPlxuICAgICAgICAgICAgPHNwYW4gY2xhc3NOYW1lPSd0ZXh0Jz48TGluayB0bz17YC8ke2NoYW5uZWxOYW1lfToke2NlcnRpZmljYXRlSWR9YH0+e2NoYW5uZWxOYW1lfTwvTGluaz48L3NwYW4+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICB9XG5cbiAgICAgICAge2Rlc2NyaXB0aW9uICYmXG4gICAgICAgIDxkaXYgY2xhc3NOYW1lPSdyb3cgcm93LS1wYWRkZWQgcm93LS13aWRlIHJvdy0tbm8tdG9wJz5cbiAgICAgICAgICA8c3BhbiBjbGFzc05hbWU9J3RleHQnPntkZXNjcmlwdGlvbn08L3NwYW4+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICB9XG5cbiAgICAgICAgPGRpdiBpZD0nc2hvdy1zaGFyZS1idXR0b25zJz5cbiAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT0ncm93IHJvdy0tcGFkZGVkIHJvdy0td2lkZSByb3ctLW5vLXRvcCc+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT0nY29sdW1uIGNvbHVtbi0tMiBjb2x1bW4tLW1lZC0xMCc+XG4gICAgICAgICAgICAgIDxzcGFuIGNsYXNzTmFtZT0ndGV4dCc+U2hhcmU6PC9zcGFuPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT0nY29sdW1uIGNvbHVtbi0tOCBjb2x1bW4tLW1lZC0xMCc+XG4gICAgICAgICAgICAgIDxkaXZcbiAgICAgICAgICAgICAgICBjbGFzc05hbWU9J3JvdyByb3ctLXNob3J0IHJvdy0td2lkZSBmbGV4LWNvbnRhaW5lci0tcm93IGZsZXgtY29udGFpbmVyLS1zcGFjZS1iZXR3ZWVuLWJvdHRvbSBmbGV4LWNvbnRhaW5lci0td3JhcCc+XG4gICAgICAgICAgICAgICAgPGEgY2xhc3NOYW1lPSdsaW5rLS1wcmltYXJ5JyB0YXJnZXQ9J19ibGFuaycgaHJlZj17YGh0dHBzOi8vdHdpdHRlci5jb20vaW50ZW50L3R3ZWV0P3RleHQ9JHtob3N0fS8ke3Nob3J0SWR9LyR7bmFtZX1gfT50d2l0dGVyPC9hPlxuICAgICAgICAgICAgICAgIDxhIGNsYXNzTmFtZT0nbGluay0tcHJpbWFyeScgdGFyZ2V0PSdfYmxhbmsnIGhyZWY9e2BodHRwczovL3d3dy5mYWNlYm9vay5jb20vc2hhcmVyL3NoYXJlci5waHA/dT0ke2hvc3R9LyR7c2hvcnRJZH0vJHtuYW1lfWB9PmZhY2Vib29rPC9hPlxuICAgICAgICAgICAgICAgIDxhIGNsYXNzTmFtZT0nbGluay0tcHJpbWFyeScgdGFyZ2V0PSdfYmxhbmsnIGhyZWY9e2BodHRwOi8vdHVtYmxyLmNvbS93aWRnZXRzL3NoYXJlL3Rvb2w/Y2Fub25pY2FsVXJsPSR7aG9zdH0vJHtzaG9ydElkfS8ke25hbWV9YH0+dHVtYmxyPC9hPlxuICAgICAgICAgICAgICAgIDxhIGNsYXNzTmFtZT0nbGluay0tcHJpbWFyeScgdGFyZ2V0PSdfYmxhbmsnIGhyZWY9e2BodHRwczovL3d3dy5yZWRkaXQuY29tL3N1Ym1pdD91cmw9JHtob3N0fS8ke3Nob3J0SWR9LyR7bmFtZX0mdGl0bGU9JHtuYW1lfWB9PnJlZGRpdDwvYT5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgPGRpdiBjbGFzc05hbWU9J3JvdyByb3ctLXBhZGRlZCByb3ctLXdpZGUgcm93LS1uby10b3AnPlxuICAgICAgICAgIDxkaXYgaWQ9J3Nob3ctc2hvcnQtbGluayc+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT0nY29sdW1uIGNvbHVtbi0tMiBjb2x1bW4tLW1lZC0xMCc+XG4gICAgICAgICAgICAgIDxzcGFuIGNsYXNzTmFtZT0ndGV4dCc+TGluazo8L3NwYW4+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPSdjb2x1bW4gY29sdW1uLS04IGNvbHVtbi0tbWVkLTEwJz5cbiAgICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9J3JvdyByb3ctLXNob3J0IHJvdy0td2lkZSc+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9J2NvbHVtbiBjb2x1bW4tLTcnPlxuICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9J2lucHV0LWVycm9yJyBpZD0naW5wdXQtZXJyb3ItY29weS1zaG9ydC1saW5rJyBoaWRkZW49J3RydWUnPmVycm9yIGhlcmU8L2Rpdj5cbiAgICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPSd0ZXh0JyBpZD0nc2hvcnQtbGluaycgY2xhc3NOYW1lPSdpbnB1dC1kaXNhYmxlZCBpbnB1dC10ZXh0LS1mdWxsLXdpZHRoJyByZWFkT25seVxuICAgICAgICAgICAgICAgICAgICBzcGVsbENoZWNrPSdmYWxzZSdcbiAgICAgICAgICAgICAgICAgICAgdmFsdWU9e2Ake2hvc3R9LyR7c2hvcnRJZH0vJHtuYW1lfS4ke2ZpbGVFeHR9YH1cbiAgICAgICAgICAgICAgICAgICAgb25DbGljaz17dGhpcy5zZWxlY3R9IC8+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9J2NvbHVtbiBjb2x1bW4tLTEnIC8+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9J2NvbHVtbiBjb2x1bW4tLTInPlxuICAgICAgICAgICAgICAgICAgPGJ1dHRvbiBjbGFzc05hbWU9J2J1dHRvbi0tcHJpbWFyeSBidXR0b24tLXdpZGUnIGRhdGEtZWxlbWVudHRvY29weT0nc2hvcnQtbGluaydcbiAgICAgICAgICAgICAgICAgICAgb25DbGljaz17dGhpcy5jb3B5VG9DbGlwYm9hcmR9PmNvcHlcbiAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgPGRpdiBpZD0nc2hvdy1lbWJlZC1jb2RlJz5cbiAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPSdjb2x1bW4gY29sdW1uLS0yIGNvbHVtbi0tbWVkLTEwJz5cbiAgICAgICAgICAgICAgPHNwYW4gY2xhc3NOYW1lPSd0ZXh0Jz5FbWJlZDo8L3NwYW4+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPSdjb2x1bW4gY29sdW1uLS04IGNvbHVtbi0tbWVkLTEwJz5cbiAgICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9J3JvdyByb3ctLXNob3J0IHJvdy0td2lkZSc+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9J2NvbHVtbiBjb2x1bW4tLTcnPlxuICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9J2lucHV0LWVycm9yJyBpZD0naW5wdXQtZXJyb3ItY29weS1lbWJlZC10ZXh0JyBoaWRkZW49J3RydWUnPmVycm9yIGhlcmU8L2Rpdj5cbiAgICAgICAgICAgICAgICAgIHsoY29udGVudFR5cGUgPT09ICd2aWRlby9tcDQnKSA/IChcbiAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9J3RleHQnIGlkPSdlbWJlZC10ZXh0JyBjbGFzc05hbWU9J2lucHV0LWRpc2FibGVkIGlucHV0LXRleHQtLWZ1bGwtd2lkdGgnIHJlYWRPbmx5XG4gICAgICAgICAgICAgICAgICAgICAgb25DbGljaz17dGhpcy5zZWxlY3R9IHNwZWxsQ2hlY2s9J2ZhbHNlJ1xuICAgICAgICAgICAgICAgICAgICAgIHZhbHVlPXtgPHZpZGVvIHdpZHRoPVwiMTAwJVwiIGNvbnRyb2xzIHBvc3Rlcj1cIiR7dGh1bWJuYWlsfVwiIHNyYz1cIiR7aG9zdH0vJHtjbGFpbUlkfS8ke25hbWV9LiR7ZmlsZUV4dH1cIi8+PC92aWRlbz5gfSAvPlxuICAgICAgICAgICAgICAgICAgKSA6IChcbiAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9J3RleHQnIGlkPSdlbWJlZC10ZXh0JyBjbGFzc05hbWU9J2lucHV0LWRpc2FibGVkIGlucHV0LXRleHQtLWZ1bGwtd2lkdGgnIHJlYWRPbmx5XG4gICAgICAgICAgICAgICAgICAgICAgb25DbGljaz17dGhpcy5zZWxlY3R9IHNwZWxsQ2hlY2s9J2ZhbHNlJ1xuICAgICAgICAgICAgICAgICAgICAgIHZhbHVlPXtgPGltZyBzcmM9XCIke2hvc3R9LyR7Y2xhaW1JZH0vJHtuYW1lfS4ke2ZpbGVFeHR9XCIvPmB9XG4gICAgICAgICAgICAgICAgICAgIC8+XG4gICAgICAgICAgICAgICAgICApfVxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPSdjb2x1bW4gY29sdW1uLS0xJyAvPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPSdjb2x1bW4gY29sdW1uLS0yJz5cbiAgICAgICAgICAgICAgICAgIDxidXR0b24gY2xhc3NOYW1lPSdidXR0b24tLXByaW1hcnkgYnV0dG9uLS13aWRlJyBkYXRhLWVsZW1lbnR0b2NvcHk9J2VtYmVkLXRleHQnXG4gICAgICAgICAgICAgICAgICAgIG9uQ2xpY2s9e3RoaXMuY29weVRvQ2xpcGJvYXJkfT5jb3B5XG4gICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgPGRpdiBjbGFzc05hbWU9J2ZsZXgtY29udGFpbmVyLS1yb3cgZmxleC1jb250YWluZXItLXNwYWNlLWJldHdlZW4tYm90dG9tJz5cbiAgICAgICAgICA8TGluayBjbGFzc05hbWU9J2xpbmstLXByaW1hcnknIHRvPXtgLyR7c2hvcnRJZH0vJHtuYW1lfS4ke2ZpbGVFeHR9YH0+PHNwYW5cbiAgICAgICAgICAgIGNsYXNzTmFtZT0ndGV4dCc+RGlyZWN0IExpbms8L3NwYW4+PC9MaW5rPlxuICAgICAgICAgIDxhIGNsYXNzTmFtZT0nbGluay0tcHJpbWFyeScgaHJlZj17YCR7aG9zdH0vJHtjbGFpbUlkfS8ke25hbWV9LiR7ZmlsZUV4dH1gfSBkb3dubG9hZD17bmFtZX0+RG93bmxvYWQ8L2E+XG4gICAgICAgICAgPGEgY2xhc3NOYW1lPSdsaW5rLS1wcmltYXJ5JyB0YXJnZXQ9J19ibGFuaycgaHJlZj0naHR0cHM6Ly9sYnJ5LmlvL2RtY2EnPlJlcG9ydDwvYT5cbiAgICAgICAgPC9kaXY+XG5cbiAgICAgIDwvZGl2PlxuICAgICk7XG4gIH1cbn07XG5cbmV4cG9ydCBkZWZhdWx0IEFzc2V0SW5mbztcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL2NsaWVudC9jb250YWluZXJzL0Fzc2V0SW5mby92aWV3LmpzeCIsImltcG9ydCB7IGNvbm5lY3QgfSBmcm9tICdyZWFjdC1yZWR1eCc7XG5pbXBvcnQgVmlldyBmcm9tICcuL3ZpZXcnO1xuXG5jb25zdCBtYXBTdGF0ZVRvUHJvcHMgPSAoeyBzaG93IH0pID0+IHtcbiAgLy8gc2VsZWN0IHJlcXVlc3QgaW5mb1xuICBjb25zdCByZXF1ZXN0SWQgPSBzaG93LnJlcXVlc3QuaWQ7XG4gIC8vIHNlbGVjdCByZXF1ZXN0XG4gIGNvbnN0IHByZXZpb3VzUmVxdWVzdCA9IHNob3cucmVxdWVzdExpc3RbcmVxdWVzdElkXSB8fCBudWxsO1xuICAvLyBzZWxlY3QgY2hhbm5lbFxuICBsZXQgY2hhbm5lbDtcbiAgaWYgKHByZXZpb3VzUmVxdWVzdCkge1xuICAgIGNvbnN0IGNoYW5uZWxLZXkgPSBwcmV2aW91c1JlcXVlc3Qua2V5O1xuICAgIGNoYW5uZWwgPSBzaG93LmNoYW5uZWxMaXN0W2NoYW5uZWxLZXldIHx8IG51bGw7XG4gIH1cbiAgcmV0dXJuIHtcbiAgICBjaGFubmVsLFxuICB9O1xufTtcblxuZXhwb3J0IGRlZmF1bHQgY29ubmVjdChtYXBTdGF0ZVRvUHJvcHMsIG51bGwpKFZpZXcpO1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vY2xpZW50L2NvbnRhaW5lcnMvU2hvd0NoYW5uZWwvaW5kZXguanMiLCJpbXBvcnQgUmVhY3QgZnJvbSAncmVhY3QnO1xuaW1wb3J0IFNFTyBmcm9tICdjb21wb25lbnRzL1NFTyc7XG5pbXBvcnQgRXJyb3JQYWdlIGZyb20gJ3BhZ2VzL0Vycm9yUGFnZSc7XG5pbXBvcnQgTmF2QmFyIGZyb20gJ2NvbnRhaW5lcnMvTmF2QmFyJztcbmltcG9ydCBDaGFubmVsQ2xhaW1zRGlzcGxheSBmcm9tICdjb250YWluZXJzL0NoYW5uZWxDbGFpbXNEaXNwbGF5JztcblxuY2xhc3MgU2hvd0NoYW5uZWwgZXh0ZW5kcyBSZWFjdC5Db21wb25lbnQge1xuICByZW5kZXIgKCkge1xuICAgIGNvbnN0IHsgY2hhbm5lbCB9ID0gdGhpcy5wcm9wcztcbiAgICBpZiAoY2hhbm5lbCkge1xuICAgICAgY29uc3QgeyBuYW1lLCBsb25nSWQsIHNob3J0SWQgfSA9IGNoYW5uZWw7XG4gICAgICByZXR1cm4gKFxuICAgICAgICA8ZGl2PlxuICAgICAgICAgIDxTRU8gcGFnZVRpdGxlPXtuYW1lfSBjaGFubmVsPXtjaGFubmVsfSAvPlxuICAgICAgICAgIDxOYXZCYXIgLz5cbiAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT0ncm93IHJvdy0tdGFsbCByb3ctLXBhZGRlZCc+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT0nY29sdW1uIGNvbHVtbi0tMTAnPlxuICAgICAgICAgICAgICA8aDI+Y2hhbm5lbCBuYW1lOiB7bmFtZX08L2gyPlxuICAgICAgICAgICAgICA8cCBjbGFzc05hbWU9eydmaW5lLXByaW50J30+ZnVsbCBjaGFubmVsIGlkOiB7bG9uZ0lkfTwvcD5cbiAgICAgICAgICAgICAgPHAgY2xhc3NOYW1lPXsnZmluZS1wcmludCd9PnNob3J0IGNoYW5uZWwgaWQ6IHtzaG9ydElkfTwvcD5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9J2NvbHVtbiBjb2x1bW4tLTEwJz5cbiAgICAgICAgICAgICAgPENoYW5uZWxDbGFpbXNEaXNwbGF5IC8+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgICApO1xuICAgIH07XG4gICAgcmV0dXJuIChcbiAgICAgIDxFcnJvclBhZ2UgZXJyb3I9eydsb2FkaW5nIGNoYW5uZWwgZGF0YS4uLid9IC8+XG4gICAgKTtcbiAgfVxufTtcblxuZXhwb3J0IGRlZmF1bHQgU2hvd0NoYW5uZWw7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9jbGllbnQvY29udGFpbmVycy9TaG93Q2hhbm5lbC92aWV3LmpzeCIsImltcG9ydCB7IGNvbm5lY3QgfSBmcm9tICdyZWFjdC1yZWR1eCc7XG5pbXBvcnQgeyBvblVwZGF0ZUNoYW5uZWxDbGFpbXMgfSBmcm9tICdhY3Rpb25zL3Nob3cnO1xuaW1wb3J0IFZpZXcgZnJvbSAnLi92aWV3JztcblxuY29uc3QgbWFwU3RhdGVUb1Byb3BzID0gKHsgc2hvdyB9KSA9PiB7XG4gIC8vIHNlbGVjdCBjaGFubmVsIGtleVxuICBjb25zdCByZXF1ZXN0ID0gc2hvdy5yZXF1ZXN0TGlzdFtzaG93LnJlcXVlc3QuaWRdO1xuICBjb25zdCBjaGFubmVsS2V5ID0gcmVxdWVzdC5rZXk7XG4gIC8vIHNlbGVjdCBjaGFubmVsIGNsYWltc1xuICBjb25zdCBjaGFubmVsID0gc2hvdy5jaGFubmVsTGlzdFtjaGFubmVsS2V5XSB8fCBudWxsO1xuICAvLyByZXR1cm4gcHJvcHNcbiAgcmV0dXJuIHtcbiAgICBjaGFubmVsS2V5LFxuICAgIGNoYW5uZWwsXG4gIH07XG59O1xuXG5jb25zdCBtYXBEaXNwYXRjaFRvUHJvcHMgPSB7XG4gIG9uVXBkYXRlQ2hhbm5lbENsYWltcyxcbn07XG5cbmV4cG9ydCBkZWZhdWx0IGNvbm5lY3QobWFwU3RhdGVUb1Byb3BzLCBtYXBEaXNwYXRjaFRvUHJvcHMpKFZpZXcpO1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vY2xpZW50L2NvbnRhaW5lcnMvQ2hhbm5lbENsYWltc0Rpc3BsYXkvaW5kZXguanMiLCJpbXBvcnQgUmVhY3QgZnJvbSAncmVhY3QnO1xuaW1wb3J0IEFzc2V0UHJldmlldyBmcm9tICdjb21wb25lbnRzL0Fzc2V0UHJldmlldyc7XG5cbmNsYXNzIENoYW5uZWxDbGFpbXNEaXNwbGF5IGV4dGVuZHMgUmVhY3QuQ29tcG9uZW50IHtcbiAgY29uc3RydWN0b3IgKHByb3BzKSB7XG4gICAgc3VwZXIocHJvcHMpO1xuICAgIHRoaXMuc2hvd05leHRSZXN1bHRzUGFnZSA9IHRoaXMuc2hvd05leHRSZXN1bHRzUGFnZS5iaW5kKHRoaXMpO1xuICAgIHRoaXMuc2hvd1ByZXZpb3VzUmVzdWx0c1BhZ2UgPSB0aGlzLnNob3dQcmV2aW91c1Jlc3VsdHNQYWdlLmJpbmQodGhpcyk7XG4gIH1cbiAgc2hvd1ByZXZpb3VzUmVzdWx0c1BhZ2UgKCkge1xuICAgIGNvbnN0IHsgY2hhbm5lbDogeyBjbGFpbXNEYXRhOiB7IGN1cnJlbnRQYWdlIH0gfSB9ID0gdGhpcy5wcm9wcztcbiAgICBjb25zdCBwcmV2aW91c1BhZ2UgPSBwYXJzZUludChjdXJyZW50UGFnZSkgLSAxO1xuICAgIHRoaXMuc2hvd05ld1BhZ2UocHJldmlvdXNQYWdlKTtcbiAgfVxuICBzaG93TmV4dFJlc3VsdHNQYWdlICgpIHtcbiAgICBjb25zdCB7IGNoYW5uZWw6IHsgY2xhaW1zRGF0YTogeyBjdXJyZW50UGFnZSB9IH0gfSA9IHRoaXMucHJvcHM7XG4gICAgY29uc3QgbmV4dFBhZ2UgPSBwYXJzZUludChjdXJyZW50UGFnZSkgKyAxO1xuICAgIHRoaXMuc2hvd05ld1BhZ2UobmV4dFBhZ2UpO1xuICB9XG4gIHNob3dOZXdQYWdlIChwYWdlKSB7XG4gICAgY29uc3QgeyBjaGFubmVsS2V5LCBjaGFubmVsOiB7IG5hbWUsIGxvbmdJZCB9IH0gPSB0aGlzLnByb3BzO1xuICAgIHRoaXMucHJvcHMub25VcGRhdGVDaGFubmVsQ2xhaW1zKGNoYW5uZWxLZXksIG5hbWUsIGxvbmdJZCwgcGFnZSk7XG4gIH1cbiAgcmVuZGVyICgpIHtcbiAgICBjb25zdCB7IGNoYW5uZWw6IHsgY2xhaW1zRGF0YTogeyBjbGFpbXMsIGN1cnJlbnRQYWdlLCB0b3RhbFBhZ2VzIH0gfSB9ID0gdGhpcy5wcm9wcztcbiAgICByZXR1cm4gKFxuICAgICAgPGRpdiBjbGFzc05hbWU9J3JvdyByb3ctLXRhbGwnPlxuICAgICAgICB7KGNsYWltcy5sZW5ndGggPiAwKSA/IChcbiAgICAgICAgICA8ZGl2PlxuICAgICAgICAgICAge2NsYWltcy5tYXAoKGNsYWltLCBpbmRleCkgPT4gPEFzc2V0UHJldmlld1xuICAgICAgICAgICAgICBjbGFpbURhdGE9e2NsYWltfVxuICAgICAgICAgICAgICBrZXk9e2Ake2NsYWltLm5hbWV9LSR7aW5kZXh9YH1cbiAgICAgICAgICAgIC8+KX1cbiAgICAgICAgICAgIDxkaXY+XG4gICAgICAgICAgICAgIHsoY3VycmVudFBhZ2UgPiAxKSAmJlxuICAgICAgICAgICAgICA8YnV0dG9uIGNsYXNzTmFtZT17J2J1dHRvbi0tc2Vjb25kYXJ5J30gb25DbGljaz17dGhpcy5zaG93UHJldmlvdXNSZXN1bHRzUGFnZX0+UHJldmlvdXMgUGFnZTwvYnV0dG9uPlxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIHsoY3VycmVudFBhZ2UgPCB0b3RhbFBhZ2VzKSAmJlxuICAgICAgICAgICAgICA8YnV0dG9uIGNsYXNzTmFtZT17J2J1dHRvbi0tc2Vjb25kYXJ5J30gb25DbGljaz17dGhpcy5zaG93TmV4dFJlc3VsdHNQYWdlfT5OZXh0IFBhZ2U8L2J1dHRvbj5cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgICkgOiAoXG4gICAgICAgICAgPHA+VGhlcmUgYXJlIG5vIGNsYWltcyBpbiB0aGlzIGNoYW5uZWw8L3A+XG4gICAgICAgICl9XG4gICAgICA8L2Rpdj5cbiAgICApO1xuICB9XG59O1xuXG5leHBvcnQgZGVmYXVsdCBDaGFubmVsQ2xhaW1zRGlzcGxheTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL2NsaWVudC9jb250YWluZXJzL0NoYW5uZWxDbGFpbXNEaXNwbGF5L3ZpZXcuanN4IiwiaW1wb3J0IHsgY29ubmVjdCB9IGZyb20gJ3JlYWN0LXJlZHV4JztcbmltcG9ydCBWaWV3IGZyb20gJy4vdmlldyc7XG5cbmNvbnN0IG1hcFN0YXRlVG9Qcm9wcyA9ICh7c2l0ZToge2RlZmF1bHRzOiB7IGRlZmF1bHRUaHVtYm5haWwgfX19KSA9PiB7XG4gIHJldHVybiB7XG4gICAgZGVmYXVsdFRodW1ibmFpbCxcbiAgfTtcbn07XG5cbmV4cG9ydCBkZWZhdWx0IGNvbm5lY3QobWFwU3RhdGVUb1Byb3BzLCBudWxsKShWaWV3KTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL2NsaWVudC9jb21wb25lbnRzL0Fzc2V0UHJldmlldy9pbmRleC5qcyIsImltcG9ydCBSZWFjdCBmcm9tICdyZWFjdCc7XG5pbXBvcnQgeyBMaW5rIH0gZnJvbSAncmVhY3Qtcm91dGVyLWRvbSc7XG5cbmNvbnN0IEFzc2V0UHJldmlldyA9ICh7IGRlZmF1bHRUaHVtYm5haWwsIGNsYWltRGF0YTogeyBuYW1lLCBjbGFpbUlkLCBmaWxlRXh0LCBjb250ZW50VHlwZSwgdGh1bWJuYWlsIH0gfSkgPT4ge1xuICBjb25zdCBkaXJlY3RTb3VyY2VMaW5rID0gYCR7Y2xhaW1JZH0vJHtuYW1lfS4ke2ZpbGVFeHR9YDtcbiAgY29uc3Qgc2hvd1VybExpbmsgPSBgLyR7Y2xhaW1JZH0vJHtuYW1lfWA7XG4gIHJldHVybiAoXG4gICAgPGRpdiBjbGFzc05hbWU9J2Fzc2V0LWhvbGRlcic+XG4gICAgICA8TGluayB0bz17c2hvd1VybExpbmt9ID5cbiAgICAgICAgeygoKSA9PiB7XG4gICAgICAgICAgc3dpdGNoIChjb250ZW50VHlwZSkge1xuICAgICAgICAgICAgY2FzZSAnaW1hZ2UvanBlZyc6XG4gICAgICAgICAgICBjYXNlICdpbWFnZS9qcGcnOlxuICAgICAgICAgICAgY2FzZSAnaW1hZ2UvcG5nJzpcbiAgICAgICAgICAgIGNhc2UgJ2ltYWdlL2dpZic6XG4gICAgICAgICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICAgICAgPGltZ1xuICAgICAgICAgICAgICAgICAgY2xhc3NOYW1lPXsnYXNzZXQtcHJldmlldyd9XG4gICAgICAgICAgICAgICAgICBzcmM9e2RpcmVjdFNvdXJjZUxpbmt9XG4gICAgICAgICAgICAgICAgICBhbHQ9e25hbWV9XG4gICAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIGNhc2UgJ3ZpZGVvL21wNCc6XG4gICAgICAgICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICAgICAgPGltZ1xuICAgICAgICAgICAgICAgICAgY2xhc3NOYW1lPXsnYXNzZXQtcHJldmlldyB2aWRlbyd9XG4gICAgICAgICAgICAgICAgICBzcmM9e3RodW1ibmFpbCB8fCBkZWZhdWx0VGh1bWJuYWlsfVxuICAgICAgICAgICAgICAgICAgYWx0PXtuYW1lfVxuICAgICAgICAgICAgICAgIC8+XG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgICAgIDxwPnVuc3VwcG9ydGVkIGZpbGUgdHlwZTwvcD5cbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pKCl9XG4gICAgICA8L0xpbms+XG4gICAgPC9kaXY+XG4gICk7XG59O1xuXG5leHBvcnQgZGVmYXVsdCBBc3NldFByZXZpZXc7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9jbGllbnQvY29tcG9uZW50cy9Bc3NldFByZXZpZXcvdmlldy5qc3giLCJpbXBvcnQgeyBjb25uZWN0IH0gZnJvbSAncmVhY3QtcmVkdXgnO1xuaW1wb3J0IFZpZXcgZnJvbSAnLi92aWV3JztcblxuY29uc3QgbWFwU3RhdGVUb1Byb3BzID0gKHsgc2l0ZTogeyBob3N0LCB0aXRsZSB9IH0pID0+IHtcbiAgcmV0dXJuIHtcbiAgICBob3N0LFxuICAgIHRpdGxlLFxuICB9O1xufTtcblxuZXhwb3J0IGRlZmF1bHQgY29ubmVjdChtYXBTdGF0ZVRvUHJvcHMsIG51bGwpKFZpZXcpO1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vY2xpZW50L2NvbnRhaW5lcnMvRm91ck9oRm91clBhZ2UvaW5kZXguanN4IiwiaW1wb3J0IFJlYWN0IGZyb20gJ3JlYWN0JztcbmltcG9ydCBOYXZCYXIgZnJvbSAnY29udGFpbmVycy9OYXZCYXInO1xuaW1wb3J0IEhlbG1ldCBmcm9tICdyZWFjdC1oZWxtZXQnO1xuXG5jbGFzcyBGb3VyT2hGb3JQYWdlIGV4dGVuZHMgUmVhY3QuQ29tcG9uZW50IHtcbiAgcmVuZGVyICgpIHtcbiAgICBjb25zdCB7dGl0bGUsIGhvc3R9ID0gdGhpcy5wcm9wcztcbiAgICByZXR1cm4gKFxuICAgICAgPGRpdj5cbiAgICAgICAgPEhlbG1ldD5cbiAgICAgICAgICA8dGl0bGU+e3RpdGxlfSAtIDQwNDwvdGl0bGU+XG4gICAgICAgICAgPGxpbmsgcmVsPSdjYW5vbmljYWwnIGhyZWY9e2Ake2hvc3R9LzQwNGB9IC8+XG4gICAgICAgIDwvSGVsbWV0PlxuICAgICAgICA8TmF2QmFyIC8+XG4gICAgICAgIDxkaXYgY2xhc3NOYW1lPSdyb3cgcm93LS1wYWRkZWQnPlxuICAgICAgICAgIDxoMj40MDQ8L2gyPlxuICAgICAgICAgIDxwPlRoYXQgcGFnZSBkb2VzIG5vdCBleGlzdDwvcD5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cbiAgICApO1xuICB9XG59O1xuXG5leHBvcnQgZGVmYXVsdCBGb3VyT2hGb3JQYWdlO1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vY2xpZW50L2NvbnRhaW5lcnMvRm91ck9oRm91clBhZ2Uvdmlldy5qc3giLCJpbXBvcnQgKiBhcyBhY3Rpb25zIGZyb20gJ2NvbnN0YW50cy9wdWJsaXNoX2FjdGlvbl90eXBlcyc7XG5pbXBvcnQgeyBMT0dJTiB9IGZyb20gJ2NvbnN0YW50cy9wdWJsaXNoX2NoYW5uZWxfc2VsZWN0X3N0YXRlcyc7XG5jb25zdCB7IHB1Ymxpc2hpbmcgfSA9IHJlcXVpcmUoJy4uLy4uL2NvbmZpZy9zaXRlQ29uZmlnLmpzJyk7XG5cbmNvbnN0IGluaXRpYWxTdGF0ZSA9IHtcbiAgZGlzYWJsZWQgICAgICAgICAgOiBwdWJsaXNoaW5nLmRpc2FibGVkLFxuICBkaXNhYmxlZE1lc3NhZ2UgICA6IHB1Ymxpc2hpbmcuZGlzYWJsZWRNZXNzYWdlLFxuICBwdWJsaXNoSW5DaGFubmVsICA6IGZhbHNlLFxuICBzZWxlY3RlZENoYW5uZWwgICA6IExPR0lOLFxuICBzaG93TWV0YWRhdGFJbnB1dHM6IGZhbHNlLFxuICBzdGF0dXMgICAgICAgICAgICA6IHtcbiAgICBzdGF0dXMgOiBudWxsLFxuICAgIG1lc3NhZ2U6IG51bGwsXG4gIH0sXG4gIGVycm9yOiB7XG4gICAgZmlsZSAgICAgICAgIDogbnVsbCxcbiAgICB1cmwgICAgICAgICAgOiBudWxsLFxuICAgIGNoYW5uZWwgICAgICA6IG51bGwsXG4gICAgcHVibGlzaFN1Ym1pdDogbnVsbCxcbiAgfSxcbiAgZmlsZSAgICA6IG51bGwsXG4gIGNsYWltICAgOiAnJyxcbiAgbWV0YWRhdGE6IHtcbiAgICB0aXRsZSAgICAgIDogJycsXG4gICAgZGVzY3JpcHRpb246ICcnLFxuICAgIGxpY2Vuc2UgICAgOiAnJyxcbiAgICBuc2Z3ICAgICAgIDogZmFsc2UsXG4gIH0sXG4gIHRodW1ibmFpbDogbnVsbCxcbn07XG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIChzdGF0ZSA9IGluaXRpYWxTdGF0ZSwgYWN0aW9uKSB7XG4gIHN3aXRjaCAoYWN0aW9uLnR5cGUpIHtcbiAgICBjYXNlIGFjdGlvbnMuRklMRV9TRUxFQ1RFRDpcbiAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKHt9LCBpbml0aWFsU3RhdGUsIHsgIC8vIG5vdGU6IGNsZWFycyB0byBpbml0aWFsIHN0YXRlXG4gICAgICAgIGZpbGU6IGFjdGlvbi5kYXRhLFxuICAgICAgfSk7XG4gICAgY2FzZSBhY3Rpb25zLkZJTEVfQ0xFQVI6XG4gICAgICByZXR1cm4gaW5pdGlhbFN0YXRlO1xuICAgIGNhc2UgYWN0aW9ucy5NRVRBREFUQV9VUERBVEU6XG4gICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbih7fSwgc3RhdGUsIHtcbiAgICAgICAgbWV0YWRhdGE6IE9iamVjdC5hc3NpZ24oe30sIHN0YXRlLm1ldGFkYXRhLCB7XG4gICAgICAgICAgW2FjdGlvbi5kYXRhLm5hbWVdOiBhY3Rpb24uZGF0YS52YWx1ZSxcbiAgICAgICAgfSksXG4gICAgICB9KTtcbiAgICBjYXNlIGFjdGlvbnMuQ0xBSU1fVVBEQVRFOlxuICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oe30sIHN0YXRlLCB7XG4gICAgICAgIGNsYWltOiBhY3Rpb24uZGF0YSxcbiAgICAgIH0pO1xuICAgIGNhc2UgYWN0aW9ucy5TRVRfUFVCTElTSF9JTl9DSEFOTkVMOlxuICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oe30sIHN0YXRlLCB7XG4gICAgICAgIHB1Ymxpc2hJbkNoYW5uZWw6IGFjdGlvbi5jaGFubmVsLFxuICAgICAgfSk7XG4gICAgY2FzZSBhY3Rpb25zLlBVQkxJU0hfU1RBVFVTX1VQREFURTpcbiAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKHt9LCBzdGF0ZSwge1xuICAgICAgICBzdGF0dXM6IGFjdGlvbi5kYXRhLFxuICAgICAgfSk7XG4gICAgY2FzZSBhY3Rpb25zLkVSUk9SX1VQREFURTpcbiAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKHt9LCBzdGF0ZSwge1xuICAgICAgICBlcnJvcjogT2JqZWN0LmFzc2lnbih7fSwgc3RhdGUuZXJyb3IsIHtcbiAgICAgICAgICBbYWN0aW9uLmRhdGEubmFtZV06IGFjdGlvbi5kYXRhLnZhbHVlLFxuICAgICAgICB9KSxcbiAgICAgIH0pO1xuICAgIGNhc2UgYWN0aW9ucy5TRUxFQ1RFRF9DSEFOTkVMX1VQREFURTpcbiAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKHt9LCBzdGF0ZSwge1xuICAgICAgICBzZWxlY3RlZENoYW5uZWw6IGFjdGlvbi5kYXRhLFxuICAgICAgfSk7XG4gICAgY2FzZSBhY3Rpb25zLlRPR0dMRV9NRVRBREFUQV9JTlBVVFM6XG4gICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbih7fSwgc3RhdGUsIHtcbiAgICAgICAgc2hvd01ldGFkYXRhSW5wdXRzOiBhY3Rpb24uZGF0YSxcbiAgICAgIH0pO1xuICAgIGNhc2UgYWN0aW9ucy5USFVNQk5BSUxfTkVXOlxuICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oe30sIHN0YXRlLCB7XG4gICAgICAgIHRodW1ibmFpbDogYWN0aW9uLmRhdGEsXG4gICAgICB9KTtcbiAgICBkZWZhdWx0OlxuICAgICAgcmV0dXJuIHN0YXRlO1xuICB9XG59XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9jbGllbnQvcmVkdWNlcnMvcHVibGlzaC5qcyIsImltcG9ydCAqIGFzIGFjdGlvbnMgZnJvbSAnY29uc3RhbnRzL2NoYW5uZWxfYWN0aW9uX3R5cGVzJztcblxuY29uc3QgaW5pdGlhbFN0YXRlID0ge1xuICBsb2dnZWRJbkNoYW5uZWw6IHtcbiAgICBuYW1lICAgOiBudWxsLFxuICAgIHNob3J0SWQ6IG51bGwsXG4gICAgbG9uZ0lkIDogbnVsbCxcbiAgfSxcbn07XG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIChzdGF0ZSA9IGluaXRpYWxTdGF0ZSwgYWN0aW9uKSB7XG4gIHN3aXRjaCAoYWN0aW9uLnR5cGUpIHtcbiAgICBjYXNlIGFjdGlvbnMuQ0hBTk5FTF9VUERBVEU6XG4gICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbih7fSwgc3RhdGUsIHtcbiAgICAgICAgbG9nZ2VkSW5DaGFubmVsOiBhY3Rpb24uZGF0YSxcbiAgICAgIH0pO1xuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gc3RhdGU7XG4gIH1cbn1cblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL2NsaWVudC9yZWR1Y2Vycy9jaGFubmVsLmpzIiwiaW1wb3J0ICogYXMgYWN0aW9ucyBmcm9tICdjb25zdGFudHMvc2hvd19hY3Rpb25fdHlwZXMnO1xuaW1wb3J0IHsgTE9DQUxfQ0hFQ0ssIEVSUk9SIH0gZnJvbSAnY29uc3RhbnRzL2Fzc2V0X2Rpc3BsYXlfc3RhdGVzJztcblxuY29uc3QgaW5pdGlhbFN0YXRlID0ge1xuICByZXF1ZXN0OiB7XG4gICAgZXJyb3I6IG51bGwsXG4gICAgdHlwZSA6IG51bGwsXG4gICAgaWQgICA6IG51bGwsXG4gIH0sXG4gIHJlcXVlc3RMaXN0IDoge30sXG4gIGNoYW5uZWxMaXN0IDoge30sXG4gIGFzc2V0TGlzdCAgIDoge30sXG4gIGRpc3BsYXlBc3NldDoge1xuICAgIGVycm9yIDogbnVsbCxcbiAgICBzdGF0dXM6IExPQ0FMX0NIRUNLLFxuICB9LFxufTtcblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gKHN0YXRlID0gaW5pdGlhbFN0YXRlLCBhY3Rpb24pIHtcbiAgc3dpdGNoIChhY3Rpb24udHlwZSkge1xuICAgIC8vIGhhbmRsZSByZXF1ZXN0XG4gICAgY2FzZSBhY3Rpb25zLlJFUVVFU1RfRVJST1I6XG4gICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbih7fSwgc3RhdGUsIHtcbiAgICAgICAgcmVxdWVzdDogT2JqZWN0LmFzc2lnbih7fSwgc3RhdGUucmVxdWVzdCwge1xuICAgICAgICAgIGVycm9yOiBhY3Rpb24uZGF0YSxcbiAgICAgICAgfSksXG4gICAgICB9KTtcbiAgICBjYXNlIGFjdGlvbnMuUkVRVUVTVF9VUERBVEU6XG4gICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbih7fSwgc3RhdGUsIHtcbiAgICAgICAgcmVxdWVzdDogT2JqZWN0LmFzc2lnbih7fSwgc3RhdGUucmVxdWVzdCwge1xuICAgICAgICAgIHR5cGU6IGFjdGlvbi5kYXRhLnJlcXVlc3RUeXBlLFxuICAgICAgICAgIGlkICA6IGFjdGlvbi5kYXRhLnJlcXVlc3RJZCxcbiAgICAgICAgfSksXG4gICAgICB9KTtcbiAgICAvLyBzdG9yZSByZXF1ZXN0c1xuICAgIGNhc2UgYWN0aW9ucy5SRVFVRVNUX0xJU1RfQUREOlxuICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oe30sIHN0YXRlLCB7XG4gICAgICAgIHJlcXVlc3RMaXN0OiBPYmplY3QuYXNzaWduKHt9LCBzdGF0ZS5yZXF1ZXN0TGlzdCwge1xuICAgICAgICAgIFthY3Rpb24uZGF0YS5pZF06IHtcbiAgICAgICAgICAgIGVycm9yOiBhY3Rpb24uZGF0YS5lcnJvcixcbiAgICAgICAgICAgIGtleSAgOiBhY3Rpb24uZGF0YS5rZXksXG4gICAgICAgICAgfSxcbiAgICAgICAgfSksXG4gICAgICB9KTtcbiAgICAvLyBhc3NldCBkYXRhXG4gICAgY2FzZSBhY3Rpb25zLkFTU0VUX0FERDpcbiAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKHt9LCBzdGF0ZSwge1xuICAgICAgICBhc3NldExpc3Q6IE9iamVjdC5hc3NpZ24oe30sIHN0YXRlLmFzc2V0TGlzdCwge1xuICAgICAgICAgIFthY3Rpb24uZGF0YS5pZF06IHtcbiAgICAgICAgICAgIGVycm9yICAgIDogYWN0aW9uLmRhdGEuZXJyb3IsXG4gICAgICAgICAgICBuYW1lICAgICA6IGFjdGlvbi5kYXRhLm5hbWUsXG4gICAgICAgICAgICBjbGFpbUlkICA6IGFjdGlvbi5kYXRhLmNsYWltSWQsXG4gICAgICAgICAgICBzaG9ydElkICA6IGFjdGlvbi5kYXRhLnNob3J0SWQsXG4gICAgICAgICAgICBjbGFpbURhdGE6IGFjdGlvbi5kYXRhLmNsYWltRGF0YSxcbiAgICAgICAgICB9LFxuICAgICAgICB9KSxcbiAgICAgIH0pO1xuICAgIC8vIGNoYW5uZWwgZGF0YVxuICAgIGNhc2UgYWN0aW9ucy5DSEFOTkVMX0FERDpcbiAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKHt9LCBzdGF0ZSwge1xuICAgICAgICBjaGFubmVsTGlzdDogT2JqZWN0LmFzc2lnbih7fSwgc3RhdGUuY2hhbm5lbExpc3QsIHtcbiAgICAgICAgICBbYWN0aW9uLmRhdGEuaWRdOiB7XG4gICAgICAgICAgICBuYW1lICAgICAgOiBhY3Rpb24uZGF0YS5uYW1lLFxuICAgICAgICAgICAgbG9uZ0lkICAgIDogYWN0aW9uLmRhdGEubG9uZ0lkLFxuICAgICAgICAgICAgc2hvcnRJZCAgIDogYWN0aW9uLmRhdGEuc2hvcnRJZCxcbiAgICAgICAgICAgIGNsYWltc0RhdGE6IGFjdGlvbi5kYXRhLmNsYWltc0RhdGEsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSksXG4gICAgICB9KTtcbiAgICBjYXNlIGFjdGlvbnMuQ0hBTk5FTF9DTEFJTVNfVVBEQVRFX1NVQ0NFU1M6XG4gICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbih7fSwgc3RhdGUsIHtcbiAgICAgICAgY2hhbm5lbExpc3Q6IE9iamVjdC5hc3NpZ24oe30sIHN0YXRlLmNoYW5uZWxMaXN0LCB7XG4gICAgICAgICAgW2FjdGlvbi5kYXRhLmNoYW5uZWxMaXN0SWRdOiBPYmplY3QuYXNzaWduKHt9LCBzdGF0ZS5jaGFubmVsTGlzdFthY3Rpb24uZGF0YS5jaGFubmVsTGlzdElkXSwge1xuICAgICAgICAgICAgY2xhaW1zRGF0YTogYWN0aW9uLmRhdGEuY2xhaW1zRGF0YSxcbiAgICAgICAgICB9KSxcbiAgICAgICAgfSksXG4gICAgICB9KTtcbiAgICAvLyBkaXNwbGF5IGFuIGFzc2V0XG4gICAgY2FzZSBhY3Rpb25zLkZJTEVfQVZBSUxBQklMSVRZX1VQREFURTpcbiAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKHt9LCBzdGF0ZSwge1xuICAgICAgICBkaXNwbGF5QXNzZXQ6IE9iamVjdC5hc3NpZ24oe30sIHN0YXRlLmRpc3BsYXlBc3NldCwge1xuICAgICAgICAgIHN0YXR1czogYWN0aW9uLmRhdGEsXG4gICAgICAgIH0pLFxuICAgICAgfSk7XG4gICAgY2FzZSBhY3Rpb25zLkRJU1BMQVlfQVNTRVRfRVJST1I6XG4gICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbih7fSwgc3RhdGUsIHtcbiAgICAgICAgZGlzcGxheUFzc2V0OiBPYmplY3QuYXNzaWduKHt9LCBzdGF0ZS5kaXNwbGF5QXNzZXQsIHtcbiAgICAgICAgICBlcnJvciA6IGFjdGlvbi5kYXRhLFxuICAgICAgICAgIHN0YXR1czogRVJST1IsXG4gICAgICAgIH0pLFxuICAgICAgfSk7XG4gICAgZGVmYXVsdDpcbiAgICAgIHJldHVybiBzdGF0ZTtcbiAgfVxufVxuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vY2xpZW50L3JlZHVjZXJzL3Nob3cuanMiLCJjb25zdCBzaXRlQ29uZmlnID0gcmVxdWlyZSgnLi4vLi4vY29uZmlnL3NpdGVDb25maWcuanMnKTtcblxuY29uc3Qge1xuICBhbmFseXRpY3M6IHtcbiAgICBnb29nbGVJZDogZ29vZ2xlQW5hbHl0aWNzSWQsXG4gIH0sXG4gIGFzc2V0RGVmYXVsdHM6IHtcbiAgICB0aHVtYm5haWw6IGRlZmF1bHRUaHVtYm5haWwsXG4gICAgZGVzY3JpcHRpb246IGRlZmF1bHREZXNjcmlwdGlvbixcbiAgfSxcbiAgZGV0YWlsczoge1xuICAgIGRlc2NyaXB0aW9uLFxuICAgIGhvc3QsXG4gICAgdGl0bGUsXG4gICAgdHdpdHRlcixcbiAgfSxcbn0gPSBzaXRlQ29uZmlnO1xuXG5jb25zdCBpbml0aWFsU3RhdGUgPSB7XG4gIGRlc2NyaXB0aW9uLFxuICBnb29nbGVBbmFseXRpY3NJZCxcbiAgaG9zdCxcbiAgdGl0bGUsXG4gIHR3aXR0ZXIsXG4gIGRlZmF1bHREZXNjcmlwdGlvbixcbiAgZGVmYXVsdFRodW1ibmFpbCxcbn07XG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIChzdGF0ZSA9IGluaXRpYWxTdGF0ZSwgYWN0aW9uKSB7XG4gIHN3aXRjaCAoYWN0aW9uLnR5cGUpIHtcbiAgICBkZWZhdWx0OlxuICAgICAgcmV0dXJuIHN0YXRlO1xuICB9XG59XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9jbGllbnQvcmVkdWNlcnMvc2l0ZS5qcyIsImltcG9ydCB7IGFsbCB9IGZyb20gJ3JlZHV4LXNhZ2EvZWZmZWN0cyc7XG5pbXBvcnQgeyB3YXRjaEhhbmRsZVNob3dQYWdlVXJpIH0gZnJvbSAnLi9zaG93X3VyaSc7XG5pbXBvcnQgeyB3YXRjaE5ld0Fzc2V0UmVxdWVzdCB9IGZyb20gJy4vc2hvd19hc3NldCc7XG5pbXBvcnQgeyB3YXRjaE5ld0NoYW5uZWxSZXF1ZXN0LCB3YXRjaFVwZGF0ZUNoYW5uZWxDbGFpbXMgfSBmcm9tICcuL3Nob3dfY2hhbm5lbCc7XG5pbXBvcnQgeyB3YXRjaEZpbGVJc1JlcXVlc3RlZCB9IGZyb20gJy4vZmlsZSc7XG5pbXBvcnQgeyB3YXRjaFB1Ymxpc2hTdGFydCB9IGZyb20gJy4vcHVibGlzaCc7XG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uICogcm9vdFNhZ2EgKCkge1xuICB5aWVsZCBhbGwoW1xuICAgIHdhdGNoSGFuZGxlU2hvd1BhZ2VVcmkoKSxcbiAgICB3YXRjaE5ld0Fzc2V0UmVxdWVzdCgpLFxuICAgIHdhdGNoTmV3Q2hhbm5lbFJlcXVlc3QoKSxcbiAgICB3YXRjaFVwZGF0ZUNoYW5uZWxDbGFpbXMoKSxcbiAgICB3YXRjaEZpbGVJc1JlcXVlc3RlZCgpLFxuICAgIHdhdGNoUHVibGlzaFN0YXJ0KCksXG4gIF0pO1xufVxuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vY2xpZW50L3NhZ2FzL2luZGV4LmpzIiwiaW1wb3J0IFJlcXVlc3QgZnJvbSAndXRpbHMvcmVxdWVzdCc7XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRMb25nQ2xhaW1JZCAoaG9zdCwgbmFtZSwgbW9kaWZpZXIpIHtcbiAgbGV0IGJvZHkgPSB7fTtcbiAgLy8gY3JlYXRlIHJlcXVlc3QgcGFyYW1zXG4gIGlmIChtb2RpZmllcikge1xuICAgIGlmIChtb2RpZmllci5pZCkge1xuICAgICAgYm9keVsnY2xhaW1JZCddID0gbW9kaWZpZXIuaWQ7XG4gICAgfSBlbHNlIHtcbiAgICAgIGJvZHlbJ2NoYW5uZWxOYW1lJ10gPSBtb2RpZmllci5jaGFubmVsLm5hbWU7XG4gICAgICBib2R5WydjaGFubmVsQ2xhaW1JZCddID0gbW9kaWZpZXIuY2hhbm5lbC5pZDtcbiAgICB9XG4gIH1cbiAgYm9keVsnY2xhaW1OYW1lJ10gPSBuYW1lO1xuICBjb25zdCBwYXJhbXMgPSB7XG4gICAgbWV0aG9kIDogJ1BPU1QnLFxuICAgIGhlYWRlcnM6IHsgJ0NvbnRlbnQtVHlwZSc6ICdhcHBsaWNhdGlvbi9qc29uJyB9LFxuICAgIGJvZHkgICA6IEpTT04uc3RyaW5naWZ5KGJvZHkpLFxuICB9O1xuICAvLyBjcmVhdGUgdXJsXG4gIGNvbnN0IHVybCA9IGAke2hvc3R9L2FwaS9jbGFpbS9sb25nLWlkYDtcbiAgLy8gcmV0dXJuIHRoZSByZXF1ZXN0IHByb21pc2VcbiAgcmV0dXJuIFJlcXVlc3QodXJsLCBwYXJhbXMpO1xufTtcblxuZXhwb3J0IGZ1bmN0aW9uIGdldFNob3J0SWQgKGhvc3QsIG5hbWUsIGNsYWltSWQpIHtcbiAgY29uc3QgdXJsID0gYCR7aG9zdH0vYXBpL2NsYWltL3Nob3J0LWlkLyR7Y2xhaW1JZH0vJHtuYW1lfWA7XG4gIHJldHVybiBSZXF1ZXN0KHVybCk7XG59O1xuXG5leHBvcnQgZnVuY3Rpb24gZ2V0Q2xhaW1EYXRhIChob3N0LCBuYW1lLCBjbGFpbUlkKSB7XG4gIGNvbnN0IHVybCA9IGAke2hvc3R9L2FwaS9jbGFpbS9kYXRhLyR7bmFtZX0vJHtjbGFpbUlkfWA7XG4gIHJldHVybiBSZXF1ZXN0KHVybCk7XG59O1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vY2xpZW50L2FwaS9hc3NldEFwaS5qcyIsImltcG9ydCBSZXF1ZXN0IGZyb20gJ3V0aWxzL3JlcXVlc3QnO1xuXG5leHBvcnQgZnVuY3Rpb24gZ2V0Q2hhbm5lbERhdGEgKGhvc3QsIGlkLCBuYW1lKSB7XG4gIGlmICghaWQpIGlkID0gJ25vbmUnO1xuICBjb25zdCB1cmwgPSBgJHtob3N0fS9hcGkvY2hhbm5lbC9kYXRhLyR7bmFtZX0vJHtpZH1gO1xuICByZXR1cm4gUmVxdWVzdCh1cmwpO1xufTtcblxuZXhwb3J0IGZ1bmN0aW9uIGdldENoYW5uZWxDbGFpbXMgKGhvc3QsIGxvbmdJZCwgbmFtZSwgcGFnZSkge1xuICBpZiAoIXBhZ2UpIHBhZ2UgPSAxO1xuICBjb25zdCB1cmwgPSBgJHtob3N0fS9hcGkvY2hhbm5lbC9jbGFpbXMvJHtuYW1lfS8ke2xvbmdJZH0vJHtwYWdlfWA7XG4gIHJldHVybiBSZXF1ZXN0KHVybCk7XG59O1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vY2xpZW50L2FwaS9jaGFubmVsQXBpLmpzIiwibW9kdWxlLmV4cG9ydHMgPSB7XG4gIFJFR0VYUF9JTlZBTElEX0NMQUlNICA6IC9bXkEtWmEtejAtOS1dL2csXG4gIFJFR0VYUF9JTlZBTElEX0NIQU5ORUw6IC9bXkEtWmEtejAtOS1AXS9nLFxuICBSRUdFWFBfQUREUkVTUyAgICAgICAgOiAvXmIoPz1bXjBPSWxdezMyLDMzfSlbMC05QS1aYS16XXszMiwzM30kLyxcbiAgQ0hBTk5FTF9DSEFSICAgICAgICAgIDogJ0AnLFxuICBwYXJzZUlkZW50aWZpZXIgICAgICAgOiBmdW5jdGlvbiAoaWRlbnRpZmllcikge1xuICAgIGNvbnN0IGNvbXBvbmVudHNSZWdleCA9IG5ldyBSZWdFeHAoXG4gICAgICAnKFteOiQjL10qKScgKyAvLyB2YWx1ZSAoc3RvcHMgYXQgdGhlIGZpcnN0IHNlcGFyYXRvciBvciBlbmQpXG4gICAgICAnKFs6JCNdPykoW14vXSopJyAvLyBtb2RpZmllciBzZXBhcmF0b3IsIG1vZGlmaWVyIChzdG9wcyBhdCB0aGUgZmlyc3QgcGF0aCBzZXBhcmF0b3Igb3IgZW5kKVxuICAgICk7XG4gICAgY29uc3QgW3Byb3RvLCB2YWx1ZSwgbW9kaWZpZXJTZXBlcmF0b3IsIG1vZGlmaWVyXSA9IGNvbXBvbmVudHNSZWdleCAgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby11bnVzZWQtdmFyc1xuICAgICAgLmV4ZWMoaWRlbnRpZmllcilcbiAgICAgIC5tYXAobWF0Y2ggPT4gbWF0Y2ggfHwgbnVsbCk7XG5cbiAgICAvLyBWYWxpZGF0ZSBhbmQgcHJvY2VzcyBuYW1lXG4gICAgaWYgKCF2YWx1ZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBDaGVjayB5b3VyIFVSTC4gIE5vIGNoYW5uZWwgbmFtZSBwcm92aWRlZCBiZWZvcmUgXCIke21vZGlmaWVyU2VwZXJhdG9yfVwiYCk7XG4gICAgfVxuICAgIGNvbnN0IGlzQ2hhbm5lbCA9IHZhbHVlLnN0YXJ0c1dpdGgobW9kdWxlLmV4cG9ydHMuQ0hBTk5FTF9DSEFSKTtcbiAgICBjb25zdCBjaGFubmVsTmFtZSA9IGlzQ2hhbm5lbCA/IHZhbHVlIDogbnVsbDtcbiAgICBsZXQgY2xhaW1JZDtcbiAgICBpZiAoaXNDaGFubmVsKSB7XG4gICAgICBpZiAoIWNoYW5uZWxOYW1lKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignQ2hlY2sgeW91ciBVUkwuICBObyBjaGFubmVsIG5hbWUgYWZ0ZXIgXCJAXCIuJyk7XG4gICAgICB9XG4gICAgICBjb25zdCBuYW1lQmFkQ2hhcnMgPSAoY2hhbm5lbE5hbWUpLm1hdGNoKG1vZHVsZS5leHBvcnRzLlJFR0VYUF9JTlZBTElEX0NIQU5ORUwpO1xuICAgICAgaWYgKG5hbWVCYWRDaGFycykge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYENoZWNrIHlvdXIgVVJMLiAgSW52YWxpZCBjaGFyYWN0ZXJzIGluIGNoYW5uZWwgbmFtZTogXCIke25hbWVCYWRDaGFycy5qb2luKCcsICcpfVwiLmApO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBjbGFpbUlkID0gdmFsdWU7XG4gICAgfVxuXG4gICAgLy8gVmFsaWRhdGUgYW5kIHByb2Nlc3MgbW9kaWZpZXJcbiAgICBsZXQgY2hhbm5lbENsYWltSWQ7XG4gICAgaWYgKG1vZGlmaWVyU2VwZXJhdG9yKSB7XG4gICAgICBpZiAoIW1vZGlmaWVyKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgQ2hlY2sgeW91ciBVUkwuICBObyBtb2RpZmllciBwcm92aWRlZCBhZnRlciBzZXBhcmF0b3IgXCIke21vZGlmaWVyU2VwZXJhdG9yfVwiYCk7XG4gICAgICB9XG5cbiAgICAgIGlmIChtb2RpZmllclNlcGVyYXRvciA9PT0gJzonKSB7XG4gICAgICAgIGNoYW5uZWxDbGFpbUlkID0gbW9kaWZpZXI7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYENoZWNrIHlvdXIgVVJMLiAgVGhlIFwiJHttb2RpZmllclNlcGVyYXRvcn1cIiBtb2RpZmllciBpcyBub3QgY3VycmVudGx5IHN1cHBvcnRlZGApO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4ge1xuICAgICAgaXNDaGFubmVsLFxuICAgICAgY2hhbm5lbE5hbWUsXG4gICAgICBjaGFubmVsQ2xhaW1JZDogY2hhbm5lbENsYWltSWQgfHwgbnVsbCxcbiAgICAgIGNsYWltSWQgICAgICAgOiBjbGFpbUlkIHx8IG51bGwsXG4gICAgfTtcbiAgfSxcbiAgcGFyc2VDbGFpbTogZnVuY3Rpb24gKG5hbWUpIHtcbiAgICBjb25zdCBjb21wb25lbnRzUmVnZXggPSBuZXcgUmVnRXhwKFxuICAgICAgJyhbXjokIy8uXSopJyArIC8vIG5hbWUgKHN0b3BzIGF0IHRoZSBmaXJzdCBleHRlbnNpb24pXG4gICAgICAnKFs6JCMuXT8pKFteL10qKScgLy8gZXh0ZW5zaW9uIHNlcGFyYXRvciwgZXh0ZW5zaW9uIChzdG9wcyBhdCB0aGUgZmlyc3QgcGF0aCBzZXBhcmF0b3Igb3IgZW5kKVxuICAgICk7XG4gICAgY29uc3QgW3Byb3RvLCBjbGFpbU5hbWUsIGV4dGVuc2lvblNlcGVyYXRvciwgZXh0ZW5zaW9uXSA9IGNvbXBvbmVudHNSZWdleCAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLXVudXNlZC12YXJzXG4gICAgICAuZXhlYyhuYW1lKVxuICAgICAgLm1hcChtYXRjaCA9PiBtYXRjaCB8fCBudWxsKTtcblxuICAgIC8vIFZhbGlkYXRlIGFuZCBwcm9jZXNzIG5hbWVcbiAgICBpZiAoIWNsYWltTmFtZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdDaGVjayB5b3VyIFVSTC4gIE5vIGNsYWltIG5hbWUgcHJvdmlkZWQgYmVmb3JlIFwiLlwiJyk7XG4gICAgfVxuICAgIGNvbnN0IG5hbWVCYWRDaGFycyA9IChjbGFpbU5hbWUpLm1hdGNoKG1vZHVsZS5leHBvcnRzLlJFR0VYUF9JTlZBTElEX0NMQUlNKTtcbiAgICBpZiAobmFtZUJhZENoYXJzKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYENoZWNrIHlvdXIgVVJMLiAgSW52YWxpZCBjaGFyYWN0ZXJzIGluIGNsYWltIG5hbWU6IFwiJHtuYW1lQmFkQ2hhcnMuam9pbignLCAnKX1cIi5gKTtcbiAgICB9XG4gICAgLy8gVmFsaWRhdGUgYW5kIHByb2Nlc3MgZXh0ZW5zaW9uXG4gICAgaWYgKGV4dGVuc2lvblNlcGVyYXRvcikge1xuICAgICAgaWYgKCFleHRlbnNpb24pIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBDaGVjayB5b3VyIFVSTC4gIE5vIGZpbGUgZXh0ZW5zaW9uIHByb3ZpZGVkIGFmdGVyIHNlcGFyYXRvciBcIiR7ZXh0ZW5zaW9uU2VwZXJhdG9yfVwiLmApO1xuICAgICAgfVxuICAgICAgaWYgKGV4dGVuc2lvblNlcGVyYXRvciAhPT0gJy4nKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgQ2hlY2sgeW91ciBVUkwuICBUaGUgXCIke2V4dGVuc2lvblNlcGVyYXRvcn1cIiBzZXBhcmF0b3IgaXMgbm90IHN1cHBvcnRlZCBpbiB0aGUgY2xhaW0gbmFtZS5gKTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHtcbiAgICAgIGNsYWltTmFtZSxcbiAgICAgIGV4dGVuc2lvbjogZXh0ZW5zaW9uIHx8IG51bGwsXG4gICAgfTtcbiAgfSxcbn07XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9jbGllbnQvdXRpbHMvbGJyeVVyaS5qcyIsImltcG9ydCB7Y2FsbCwgcHV0LCBzZWxlY3QsIHRha2VMYXRlc3R9IGZyb20gJ3JlZHV4LXNhZ2EvZWZmZWN0cyc7XG5pbXBvcnQgKiBhcyBhY3Rpb25zIGZyb20gJ2NvbnN0YW50cy9zaG93X2FjdGlvbl90eXBlcyc7XG5pbXBvcnQgeyB1cGRhdGVGaWxlQXZhaWxhYmlsaXR5LCB1cGRhdGVEaXNwbGF5QXNzZXRFcnJvciB9IGZyb20gJ2FjdGlvbnMvc2hvdyc7XG5pbXBvcnQgeyBVTkFWQUlMQUJMRSwgQVZBSUxBQkxFIH0gZnJvbSAnY29uc3RhbnRzL2Fzc2V0X2Rpc3BsYXlfc3RhdGVzJztcbmltcG9ydCB7IGNoZWNrRmlsZUF2YWlsYWJpbGl0eSwgdHJpZ2dlckNsYWltR2V0IH0gZnJvbSAnYXBpL2ZpbGVBcGknO1xuaW1wb3J0IHsgc2VsZWN0U2l0ZUhvc3QgfSBmcm9tICdzZWxlY3RvcnMvc2l0ZSc7XG5cbmZ1bmN0aW9uICogcmV0cmlldmVGaWxlIChhY3Rpb24pIHtcbiAgY29uc3QgbmFtZSA9IGFjdGlvbi5kYXRhLm5hbWU7XG4gIGNvbnN0IGNsYWltSWQgPSBhY3Rpb24uZGF0YS5jbGFpbUlkO1xuICBjb25zdCBob3N0ID0geWllbGQgc2VsZWN0KHNlbGVjdFNpdGVIb3N0KTtcbiAgLy8gc2VlIGlmIHRoZSBmaWxlIGlzIGF2YWlsYWJsZVxuICBsZXQgaXNBdmFpbGFibGU7XG4gIHRyeSB7XG4gICAgKHsgZGF0YTogaXNBdmFpbGFibGUgfSA9IHlpZWxkIGNhbGwoY2hlY2tGaWxlQXZhaWxhYmlsaXR5LCBjbGFpbUlkLCBob3N0LCBuYW1lKSk7XG4gIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgcmV0dXJuIHlpZWxkIHB1dCh1cGRhdGVEaXNwbGF5QXNzZXRFcnJvcihlcnJvci5tZXNzYWdlKSk7XG4gIH07XG4gIGlmIChpc0F2YWlsYWJsZSkge1xuICAgIHlpZWxkIHB1dCh1cGRhdGVEaXNwbGF5QXNzZXRFcnJvcihudWxsKSk7XG4gICAgcmV0dXJuIHlpZWxkIHB1dCh1cGRhdGVGaWxlQXZhaWxhYmlsaXR5KEFWQUlMQUJMRSkpO1xuICB9XG4gIHlpZWxkIHB1dCh1cGRhdGVGaWxlQXZhaWxhYmlsaXR5KFVOQVZBSUxBQkxFKSk7XG4gIC8vIGluaXRpYXRlIGdldCByZXF1ZXN0IGZvciB0aGUgZmlsZVxuICB0cnkge1xuICAgIHlpZWxkIGNhbGwodHJpZ2dlckNsYWltR2V0LCBjbGFpbUlkLCBob3N0LCBuYW1lKTtcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICByZXR1cm4geWllbGQgcHV0KHVwZGF0ZURpc3BsYXlBc3NldEVycm9yKGVycm9yLm1lc3NhZ2UpKTtcbiAgfTtcbiAgeWllbGQgcHV0KHVwZGF0ZUZpbGVBdmFpbGFiaWxpdHkoQVZBSUxBQkxFKSk7XG59O1xuXG5leHBvcnQgZnVuY3Rpb24gKiB3YXRjaEZpbGVJc1JlcXVlc3RlZCAoKSB7XG4gIHlpZWxkIHRha2VMYXRlc3QoYWN0aW9ucy5GSUxFX1JFUVVFU1RFRCwgcmV0cmlldmVGaWxlKTtcbn07XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9jbGllbnQvc2FnYXMvZmlsZS5qcyIsImltcG9ydCBSZXF1ZXN0IGZyb20gJ3V0aWxzL3JlcXVlc3QnO1xuXG5leHBvcnQgZnVuY3Rpb24gY2hlY2tGaWxlQXZhaWxhYmlsaXR5IChjbGFpbUlkLCBob3N0LCBuYW1lKSB7XG4gIGNvbnN0IHVybCA9IGAke2hvc3R9L2FwaS9maWxlL2F2YWlsYWJpbGl0eS8ke25hbWV9LyR7Y2xhaW1JZH1gO1xuICByZXR1cm4gUmVxdWVzdCh1cmwpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gdHJpZ2dlckNsYWltR2V0IChjbGFpbUlkLCBob3N0LCBuYW1lKSB7XG4gIGNvbnN0IHVybCA9IGAke2hvc3R9L2FwaS9jbGFpbS9nZXQvJHtuYW1lfS8ke2NsYWltSWR9YDtcbiAgcmV0dXJuIFJlcXVlc3QodXJsKTtcbn1cblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL2NsaWVudC9hcGkvZmlsZUFwaS5qcyIsImltcG9ydCB7IGNhbGwsIHB1dCwgc2VsZWN0LCB0YWtlLCB0YWtlTGF0ZXN0IH0gZnJvbSAncmVkdXgtc2FnYS9lZmZlY3RzJztcbmltcG9ydCAqIGFzIGFjdGlvbnMgZnJvbSAnY29uc3RhbnRzL3B1Ymxpc2hfYWN0aW9uX3R5cGVzJztcbmltcG9ydCAqIGFzIHB1Ymxpc2hTdGF0ZXMgZnJvbSAnY29uc3RhbnRzL3B1Ymxpc2hfY2xhaW1fc3RhdGVzJztcbmltcG9ydCB7IHVwZGF0ZUVycm9yLCB1cGRhdGVQdWJsaXNoU3RhdHVzLCBjbGVhckZpbGUgfSBmcm9tICdhY3Rpb25zL3B1Ymxpc2gnO1xuaW1wb3J0IHsgc2VsZWN0UHVibGlzaFN0YXRlIH0gZnJvbSAnc2VsZWN0b3JzL3B1Ymxpc2gnO1xuaW1wb3J0IHsgc2VsZWN0Q2hhbm5lbFN0YXRlIH0gZnJvbSAnc2VsZWN0b3JzL2NoYW5uZWwnO1xuaW1wb3J0IHsgc2VsZWN0U2l0ZVN0YXRlIH0gZnJvbSAnc2VsZWN0b3JzL3NpdGUnO1xuaW1wb3J0IHsgdmFsaWRhdGVDaGFubmVsU2VsZWN0aW9uLCB2YWxpZGF0ZVB1Ymxpc2hQYXJhbXMgfSBmcm9tICd1dGlscy92YWxpZGF0ZSc7XG5pbXBvcnQgeyBjcmVhdGVQdWJsaXNoTWV0YWRhdGEsIGNyZWF0ZVB1Ymxpc2hGb3JtRGF0YSwgY3JlYXRlVGh1bWJuYWlsVXJsIH0gZnJvbSAndXRpbHMvcHVibGlzaCc7XG5pbXBvcnQgeyBtYWtlUHVibGlzaFJlcXVlc3RDaGFubmVsIH0gZnJvbSAnY2hhbm5lbHMvcHVibGlzaCc7XG5cbmZ1bmN0aW9uICogcHVibGlzaEZpbGUgKGFjdGlvbikge1xuICBjb25zdCB7IGhpc3RvcnkgfSA9IGFjdGlvbi5kYXRhO1xuICBjb25zdCB7IHB1Ymxpc2hJbkNoYW5uZWwsIHNlbGVjdGVkQ2hhbm5lbCwgZmlsZSwgY2xhaW0sIG1ldGFkYXRhLCB0aHVtYm5haWxDaGFubmVsLCB0aHVtYm5haWxDaGFubmVsSWQsIHRodW1ibmFpbCwgZXJyb3I6IHsgdXJsOiB1cmxFcnJvciB9IH0gPSB5aWVsZCBzZWxlY3Qoc2VsZWN0UHVibGlzaFN0YXRlKTtcbiAgY29uc3QgeyBsb2dnZWRJbkNoYW5uZWwgfSA9IHlpZWxkIHNlbGVjdChzZWxlY3RDaGFubmVsU3RhdGUpO1xuICBjb25zdCB7IGhvc3QgfSA9IHlpZWxkIHNlbGVjdChzZWxlY3RTaXRlU3RhdGUpO1xuICAvLyB2YWxpZGF0ZSB0aGUgY2hhbm5lbCBzZWxlY3Rpb25cbiAgdHJ5IHtcbiAgICB2YWxpZGF0ZUNoYW5uZWxTZWxlY3Rpb24ocHVibGlzaEluQ2hhbm5lbCwgc2VsZWN0ZWRDaGFubmVsLCBsb2dnZWRJbkNoYW5uZWwpO1xuICB9IGNhdGNoIChlcnJvcikge1xuICAgIHJldHVybiB5aWVsZCBwdXQodXBkYXRlRXJyb3IoJ2NoYW5uZWwnLCBlcnJvci5tZXNzYWdlKSk7XG4gIH07XG4gIC8vIHZhbGlkYXRlIHB1Ymxpc2ggcGFyYW1ldGVyc1xuICB0cnkge1xuICAgIHZhbGlkYXRlUHVibGlzaFBhcmFtcyhmaWxlLCBjbGFpbSwgdXJsRXJyb3IpO1xuICB9IGNhdGNoIChlcnJvcikge1xuICAgIHJldHVybiB5aWVsZCBwdXQodXBkYXRlRXJyb3IoJ3B1Ymxpc2hTdWJtaXQnLCBlcnJvci5tZXNzYWdlKSk7XG4gIH1cbiAgLy8gY3JlYXRlIG1ldGFkYXRhXG4gIGxldCBwdWJsaXNoTWV0YWRhdGEgPSBjcmVhdGVQdWJsaXNoTWV0YWRhdGEoY2xhaW0sIGZpbGUsIG1ldGFkYXRhLCBwdWJsaXNoSW5DaGFubmVsLCBzZWxlY3RlZENoYW5uZWwpO1xuICBpZiAodGh1bWJuYWlsKSB7XG4gICAgLy8gYWRkIHRodW1ibmFpbCB0byBwdWJsaXNoIG1ldGFkYXRhXG4gICAgcHVibGlzaE1ldGFkYXRhWyd0aHVtYm5haWwnXSA9IGNyZWF0ZVRodW1ibmFpbFVybCh0aHVtYm5haWxDaGFubmVsLCB0aHVtYm5haWxDaGFubmVsSWQsICBjbGFpbSwgaG9zdCk7XG4gIH1cbiAgLy8gY3JlYXRlIGZvcm0gZGF0YSBmb3IgbWFpbiBwdWJsaXNoXG4gIGNvbnN0IHB1Ymxpc2hGb3JtRGF0YSA9IGNyZWF0ZVB1Ymxpc2hGb3JtRGF0YShmaWxlLCB0aHVtYm5haWwsIHB1Ymxpc2hNZXRhZGF0YSk7XG4gIC8vIG1ha2UgdGhlIHB1Ymxpc2ggcmVxdWVzdFxuICBjb25zdCBwdWJsaXNoQ2hhbm5lbCA9IHlpZWxkIGNhbGwobWFrZVB1Ymxpc2hSZXF1ZXN0Q2hhbm5lbCwgcHVibGlzaEZvcm1EYXRhKTtcbiAgd2hpbGUgKHRydWUpIHtcbiAgICBjb25zdCB7bG9hZFN0YXJ0LCBwcm9ncmVzcywgbG9hZCwgc3VjY2VzcywgZXJyb3J9ID0geWllbGQgdGFrZShwdWJsaXNoQ2hhbm5lbCk7XG4gICAgaWYgKGVycm9yKSB7XG4gICAgICByZXR1cm4geWllbGQgcHV0KHVwZGF0ZVB1Ymxpc2hTdGF0dXMocHVibGlzaFN0YXRlcy5GQUlMRUQsIGVycm9yLm1lc3NhZ2UpKTtcbiAgICB9XG4gICAgaWYgKHN1Y2Nlc3MpIHtcbiAgICAgIHlpZWxkIHB1dChjbGVhckZpbGUoKSk7XG4gICAgICByZXR1cm4gaGlzdG9yeS5wdXNoKGAvJHtzdWNjZXNzLmRhdGEuY2xhaW1JZH0vJHtzdWNjZXNzLmRhdGEubmFtZX1gKTtcbiAgICB9XG4gICAgaWYgKGxvYWRTdGFydCkge1xuICAgICAgeWllbGQgcHV0KHVwZGF0ZVB1Ymxpc2hTdGF0dXMocHVibGlzaFN0YXRlcy5MT0FEX1NUQVJULCBudWxsKSk7XG4gICAgfVxuICAgIGlmIChwcm9ncmVzcykge1xuICAgICAgeWllbGQgcHV0KHVwZGF0ZVB1Ymxpc2hTdGF0dXMocHVibGlzaFN0YXRlcy5MT0FESU5HLCBgJHtwcm9ncmVzc30lYCkpO1xuICAgIH1cbiAgICBpZiAobG9hZCkge1xuICAgICAgeWllbGQgcHV0KHVwZGF0ZVB1Ymxpc2hTdGF0dXMocHVibGlzaFN0YXRlcy5QVUJMSVNISU5HLCBudWxsKSk7XG4gICAgfVxuICB9XG59O1xuXG5leHBvcnQgZnVuY3Rpb24gKiB3YXRjaFB1Ymxpc2hTdGFydCAoKSB7XG4gIHlpZWxkIHRha2VMYXRlc3QoYWN0aW9ucy5QVUJMSVNIX1NUQVJULCBwdWJsaXNoRmlsZSk7XG59O1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vY2xpZW50L3NhZ2FzL3B1Ymxpc2guanMiLCJleHBvcnQgY29uc3Qgc2VsZWN0UHVibGlzaFN0YXRlID0gKHN0YXRlKSA9PiB7XG4gIHJldHVybiBzdGF0ZS5wdWJsaXNoO1xufTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL2NsaWVudC9zZWxlY3RvcnMvcHVibGlzaC5qcyIsImV4cG9ydCBjb25zdCBzZWxlY3RDaGFubmVsU3RhdGUgPSAoc3RhdGUpID0+IHtcbiAgcmV0dXJuIHN0YXRlLmNoYW5uZWw7XG59O1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vY2xpZW50L3NlbGVjdG9ycy9jaGFubmVsLmpzIiwiZXhwb3J0IGNvbnN0IHZhbGlkYXRlQ2hhbm5lbFNlbGVjdGlvbiA9IChwdWJsaXNoSW5DaGFubmVsLCBzZWxlY3RlZENoYW5uZWwsIGxvZ2dlZEluQ2hhbm5lbCkgPT4ge1xuICBpZiAocHVibGlzaEluQ2hhbm5lbCAmJiAoc2VsZWN0ZWRDaGFubmVsICE9PSBsb2dnZWRJbkNoYW5uZWwubmFtZSkpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0xvZyBpbiB0byBhIGNoYW5uZWwgb3Igc2VsZWN0IEFub255bW91cycpO1xuICB9XG59O1xuXG5leHBvcnQgY29uc3QgdmFsaWRhdGVQdWJsaXNoUGFyYW1zID0gKGZpbGUsIGNsYWltLCB1cmxFcnJvcikgPT4ge1xuICBpZiAoIWZpbGUpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1BsZWFzZSBjaG9vc2UgYSBmaWxlJyk7XG4gIH1cbiAgaWYgKCFjbGFpbSkge1xuICAgIHRocm93IG5ldyBFcnJvcignUGxlYXNlIGVudGVyIGEgVVJMJyk7XG4gIH1cbiAgaWYgKHVybEVycm9yKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdGaXggdGhlIHVybCcpO1xuICB9XG59O1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vY2xpZW50L3V0aWxzL3ZhbGlkYXRlLmpzIiwiZXhwb3J0IGNvbnN0IGNyZWF0ZVB1Ymxpc2hNZXRhZGF0YSA9IChjbGFpbSwgeyB0eXBlIH0sIHsgdGl0bGUsIGRlc2NyaXB0aW9uLCBsaWNlbnNlLCBuc2Z3IH0sIHB1Ymxpc2hJbkNoYW5uZWwsIHNlbGVjdGVkQ2hhbm5lbCkgPT4ge1xuICBsZXQgbWV0YWRhdGEgPSB7XG4gICAgbmFtZTogY2xhaW0sXG4gICAgdGl0bGUsXG4gICAgZGVzY3JpcHRpb24sXG4gICAgbGljZW5zZSxcbiAgICBuc2Z3LFxuICAgIHR5cGUsXG4gIH07XG4gIGlmIChwdWJsaXNoSW5DaGFubmVsKSB7XG4gICAgbWV0YWRhdGFbJ2NoYW5uZWxOYW1lJ10gPSBzZWxlY3RlZENoYW5uZWw7XG4gIH1cbiAgcmV0dXJuIG1ldGFkYXRhO1xufTtcblxuZXhwb3J0IGNvbnN0IGNyZWF0ZVB1Ymxpc2hGb3JtRGF0YSA9IChmaWxlLCB0aHVtYm5haWwsIG1ldGFkYXRhKSA9PiB7XG4gIGxldCBmZCA9IG5ldyBGb3JtRGF0YSgpO1xuICAvLyBhcHBlbmQgZmlsZVxuICBmZC5hcHBlbmQoJ2ZpbGUnLCBmaWxlKTtcbiAgLy8gYXBwZW5kIHRodW1ibmFpbFxuICBpZiAodGh1bWJuYWlsKSB7XG4gICAgZmQuYXBwZW5kKCd0aHVtYm5haWwnLCB0aHVtYm5haWwpO1xuICB9XG4gIC8vIGFwcGVuZCBtZXRhZGF0YVxuICBmb3IgKGxldCBrZXkgaW4gbWV0YWRhdGEpIHtcbiAgICBpZiAobWV0YWRhdGEuaGFzT3duUHJvcGVydHkoa2V5KSkge1xuICAgICAgZmQuYXBwZW5kKGtleSwgbWV0YWRhdGFba2V5XSk7XG4gICAgfVxuICB9XG4gIHJldHVybiBmZDtcbn07XG5cbmV4cG9ydCBjb25zdCBjcmVhdGVUaHVtYm5haWxVcmwgPSAoY2hhbm5lbCwgY2hhbm5lbElkLCBjbGFpbSwgaG9zdCkgPT4ge1xuICByZXR1cm4gYCR7aG9zdH0vJHtjaGFubmVsfToke2NoYW5uZWxJZH0vJHtjbGFpbX0tdGh1bWIucG5nYDtcbn07XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9jbGllbnQvdXRpbHMvcHVibGlzaC5qcyIsImltcG9ydCB7YnVmZmVycywgRU5ELCBldmVudENoYW5uZWx9IGZyb20gJ3JlZHV4LXNhZ2EnO1xuXG5leHBvcnQgY29uc3QgbWFrZVB1Ymxpc2hSZXF1ZXN0Q2hhbm5lbCA9IChmZCkgPT4ge1xuICByZXR1cm4gZXZlbnRDaGFubmVsKGVtaXR0ZXIgPT4ge1xuICAgIGNvbnN0IHVyaSA9ICcvYXBpL2NsYWltL3B1Ymxpc2gnO1xuICAgIGNvbnN0IHhociA9IG5ldyBYTUxIdHRwUmVxdWVzdCgpO1xuICAgIC8vIGFkZCBldmVudCBsaXN0ZW5lcnNcbiAgICBjb25zdCBvbkxvYWRTdGFydCA9ICgpID0+IHtcbiAgICAgIGVtaXR0ZXIoe2xvYWRTdGFydDogdHJ1ZX0pO1xuICAgIH07XG4gICAgY29uc3Qgb25Qcm9ncmVzcyA9IChldmVudCkgPT4ge1xuICAgICAgaWYgKGV2ZW50Lmxlbmd0aENvbXB1dGFibGUpIHtcbiAgICAgICAgY29uc3QgcGVyY2VudGFnZSA9IE1hdGgucm91bmQoKGV2ZW50LmxvYWRlZCAqIDEwMCkgLyBldmVudC50b3RhbCk7XG4gICAgICAgIGVtaXR0ZXIoe3Byb2dyZXNzOiBwZXJjZW50YWdlfSk7XG4gICAgICB9XG4gICAgfTtcbiAgICBjb25zdCBvbkxvYWQgPSAoKSA9PiB7XG4gICAgICBlbWl0dGVyKHtsb2FkOiB0cnVlfSk7XG4gICAgfTtcbiAgICB4aHIudXBsb2FkLmFkZEV2ZW50TGlzdGVuZXIoJ2xvYWRzdGFydCcsIG9uTG9hZFN0YXJ0KTtcbiAgICB4aHIudXBsb2FkLmFkZEV2ZW50TGlzdGVuZXIoJ3Byb2dyZXNzJywgb25Qcm9ncmVzcyk7XG4gICAgeGhyLnVwbG9hZC5hZGRFdmVudExpc3RlbmVyKCdsb2FkJywgb25Mb2FkKTtcbiAgICAvLyBzZXQgc3RhdGUgY2hhbmdlIGhhbmRsZXJcbiAgICB4aHIub25yZWFkeXN0YXRlY2hhbmdlID0gKCkgPT4ge1xuICAgICAgaWYgKHhoci5yZWFkeVN0YXRlID09PSA0KSB7XG4gICAgICAgIGNvbnN0IHJlc3BvbnNlID0gSlNPTi5wYXJzZSh4aHIucmVzcG9uc2UpO1xuICAgICAgICBpZiAoKHhoci5zdGF0dXMgPT09IDIwMCkgJiYgcmVzcG9uc2Uuc3VjY2Vzcykge1xuICAgICAgICAgIGVtaXR0ZXIoe3N1Y2Nlc3M6IHJlc3BvbnNlfSk7XG4gICAgICAgICAgZW1pdHRlcihFTkQpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGVtaXR0ZXIoe2Vycm9yOiBuZXcgRXJyb3IocmVzcG9uc2UubWVzc2FnZSl9KTtcbiAgICAgICAgICBlbWl0dGVyKEVORCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9O1xuICAgIC8vIG9wZW4gYW5kIHNlbmRcbiAgICB4aHIub3BlbignUE9TVCcsIHVyaSwgdHJ1ZSk7XG4gICAgeGhyLnNlbmQoZmQpO1xuICAgIC8vIGNsZWFuIHVwXG4gICAgcmV0dXJuICgpID0+IHtcbiAgICAgIHhoci51cGxvYWQucmVtb3ZlRXZlbnRMaXN0ZW5lcignbG9hZHN0YXJ0Jywgb25Mb2FkU3RhcnQpO1xuICAgICAgeGhyLnVwbG9hZC5yZW1vdmVFdmVudExpc3RlbmVyKCdwcm9ncmVzcycsIG9uUHJvZ3Jlc3MpO1xuICAgICAgeGhyLnVwbG9hZC5yZW1vdmVFdmVudExpc3RlbmVyKCdsb2FkJywgb25Mb2FkKTtcbiAgICAgIHhoci5vbnJlYWR5c3RhdGVjaGFuZ2UgPSBudWxsO1xuICAgICAgeGhyLmFib3J0KCk7XG4gICAgfTtcbiAgfSwgYnVmZmVycy5zbGlkaW5nKDIpKTtcbn07XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9jbGllbnQvY2hhbm5lbHMvcHVibGlzaC5qcyIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcInJlYWN0LWdhXCIpO1xuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIGV4dGVybmFsIFwicmVhY3QtZ2FcIlxuLy8gbW9kdWxlIGlkID0gMTI3XG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsImNvbnN0IGNoYW5uZWxBdmFpbGFiaWxpdHkgPSByZXF1aXJlKCcuL2NoYW5uZWxBdmFpbGFiaWxpdHknKTtcclxuY29uc3QgY2hhbm5lbENsYWltcyA9IHJlcXVpcmUoJy4vY2hhbm5lbENsYWltcycpO1xyXG5jb25zdCBjaGFubmVsRGF0YSA9IHJlcXVpcmUoJy4vY2hhbm5lbERhdGEnKTtcclxuY29uc3QgY2hhbm5lbFNob3J0SWQgPSByZXF1aXJlKCcuL2NoYW5uZWxTaG9ydElkJyk7XHJcbmNvbnN0IGNsYWltQXZhaWxhYmlsaXR5ID0gcmVxdWlyZSgnLi9jbGFpbUF2YWlsYWJpbGl0eScpO1xyXG5jb25zdCBjbGFpbURhdGEgPSByZXF1aXJlKCcuL2NsYWltRGF0YScpO1xyXG5jb25zdCBjbGFpbUdldCA9IHJlcXVpcmUoJy4vY2xhaW1HZXQnKTtcclxuY29uc3QgY2xhaW1Mb25nSWQgPSByZXF1aXJlKCcuL2NsYWltTG9uZ0lkJyk7XHJcbmNvbnN0IGNsYWltUHVibGlzaCA9IHJlcXVpcmUoJy4vY2xhaW1QdWJsaXNoJyk7XHJcbmNvbnN0IGNsYWltUmVzb2x2ZSA9IHJlcXVpcmUoJy4vY2xhaW1SZXNvbHZlJyk7XHJcbmNvbnN0IGNsYWltU2hvcnRJZCA9IHJlcXVpcmUoJy4vY2xhaW1TaG9ydElkJyk7XHJcbmNvbnN0IGNsYWltTGlzdCA9IHJlcXVpcmUoJy4vY2xhaW1MaXN0Jyk7XHJcbmNvbnN0IGZpbGVBdmFpbGFiaWxpdHkgPSByZXF1aXJlKCcuL2ZpbGVBdmFpbGFiaWxpdHknKTtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0ge1xyXG4gIGNoYW5uZWxBdmFpbGFiaWxpdHksXHJcbiAgY2hhbm5lbENsYWltcyxcclxuICBjaGFubmVsRGF0YSxcclxuICBjaGFubmVsU2hvcnRJZCxcclxuICBjbGFpbUF2YWlsYWJpbGl0eSxcclxuICBjbGFpbURhdGEsXHJcbiAgY2xhaW1HZXQsXHJcbiAgY2xhaW1Mb25nSWQsXHJcbiAgY2xhaW1QdWJsaXNoLFxyXG4gIGNsYWltUmVzb2x2ZSxcclxuICBjbGFpbVNob3J0SWQsXHJcbiAgY2xhaW1MaXN0LFxyXG4gIGZpbGVBdmFpbGFiaWxpdHksXHJcbn07XHJcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL3NlcnZlci9yb3V0ZXMvYXBpL2luZGV4LmpzIiwiY29uc3QgeyBjaGVja0NoYW5uZWxBdmFpbGFiaWxpdHkgfSA9IHJlcXVpcmUoJ2NvbnRyb2xsZXJzL3B1Ymxpc2hDb250cm9sbGVyLmpzJyk7XHJcbmNvbnN0IHsgc2VuZEdBVGltaW5nRXZlbnQgfSA9IHJlcXVpcmUoJ2hlbHBlcnMvZ29vZ2xlQW5hbHl0aWNzLmpzJyk7XHJcbmNvbnN0IHsgaGFuZGxlRXJyb3JSZXNwb25zZSB9ID0gcmVxdWlyZSgnaGVscGVycy9lcnJvckhhbmRsZXJzLmpzJyk7XHJcblxyXG4vKlxyXG5cclxuICByb3V0ZSB0byBjaGVjayB3aGV0aGVyIHNpdGUgaGFzIHB1Ymxpc2hlZCB0byBhIGNoYW5uZWxcclxuXHJcbiovXHJcblxyXG5jb25zdCBjaGFubmVsQXZhaWxhYmlsaXR5ID0gKCkgPT4ge1xyXG4gIHJldHVybiAoeyBpcCwgb3JpZ2luYWxVcmwsIHBhcmFtczogeyBuYW1lIH0gfSwgcmVzKSA9PiB7XHJcbiAgICBjb25zdCBnYVN0YXJ0VGltZSA9IERhdGUubm93KCk7XHJcbiAgICBjaGVja0NoYW5uZWxBdmFpbGFiaWxpdHkobmFtZSlcclxuICAgICAgLnRoZW4oYXZhaWxhYmxlTmFtZSA9PiB7XHJcbiAgICAgICAgcmVzLnN0YXR1cygyMDApLmpzb24oYXZhaWxhYmxlTmFtZSk7XHJcbiAgICAgICAgc2VuZEdBVGltaW5nRXZlbnQoJ2VuZC10by1lbmQnLCAnY2xhaW0gbmFtZSBhdmFpbGFiaWxpdHknLCBuYW1lLCBnYVN0YXJ0VGltZSwgRGF0ZS5ub3coKSk7XHJcbiAgICAgIH0pXHJcbiAgICAgIC5jYXRjaChlcnJvciA9PiB7XHJcbiAgICAgICAgaGFuZGxlRXJyb3JSZXNwb25zZShvcmlnaW5hbFVybCwgaXAsIGVycm9yLCByZXMpO1xyXG4gICAgICB9KTtcclxuICB9O1xyXG59O1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBjaGFubmVsQXZhaWxhYmlsaXR5O1xyXG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9zZXJ2ZXIvcm91dGVzL2FwaS9jaGFubmVsQXZhaWxhYmlsaXR5LmpzIiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwiYXhpb3NcIik7XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gZXh0ZXJuYWwgXCJheGlvc1wiXG4vLyBtb2R1bGUgaWQgPSAxMzBcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiY29uc3QgbGJyeUNvbmZpZyA9IHtcbiAgYXBpOiB7XG4gICAgYXBpSG9zdDogJ2xvY2FsaG9zdCcsXG4gICAgYXBpUG9ydDogJzUyNzknLFxuICB9LFxufTtcblxubW9kdWxlLmV4cG9ydHMgPSBsYnJ5Q29uZmlnO1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vY29uZmlnL2xicnlDb25maWcuanMiLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCJ1bml2ZXJzYWwtYW5hbHl0aWNzXCIpO1xuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIGV4dGVybmFsIFwidW5pdmVyc2FsLWFuYWx5dGljc1wiXG4vLyBtb2R1bGUgaWQgPSAxMzJcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwiZnNcIik7XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gZXh0ZXJuYWwgXCJmc1wiXG4vLyBtb2R1bGUgaWQgPSAxMzNcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwic2VxdWVsaXplXCIpO1xuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIGV4dGVybmFsIFwic2VxdWVsaXplXCJcbi8vIG1vZHVsZSBpZCA9IDEzNFxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJjb25zdCB7IGdldENoYW5uZWxDbGFpbXMgfSA9IHJlcXVpcmUoJ2NvbnRyb2xsZXJzL3NlcnZlQ29udHJvbGxlci5qcycpO1xyXG5jb25zdCB7IGhhbmRsZUVycm9yUmVzcG9uc2UgfSA9IHJlcXVpcmUoJ2hlbHBlcnMvZXJyb3JIYW5kbGVycy5qcycpO1xyXG5cclxuY29uc3QgTk9fQ0hBTk5FTCA9ICdOT19DSEFOTkVMJztcclxuXHJcbi8qXHJcblxyXG4gIHJvdXRlIHRvIGdldCBhbGwgY2xhaW1zIGZvciBjaGFubmVsXHJcblxyXG4qL1xyXG5cclxuY29uc3QgY2hhbm5lbENsYWltcyA9ICgpID0+IHtcclxuICByZXR1cm4gKHsgaXAsIG9yaWdpbmFsVXJsLCBib2R5LCBwYXJhbXMgfSwgcmVzKSA9PiB7XHJcbiAgICBjb25zdCBjaGFubmVsTmFtZSA9IHBhcmFtcy5jaGFubmVsTmFtZTtcclxuICAgIGxldCBjaGFubmVsQ2xhaW1JZCA9IHBhcmFtcy5jaGFubmVsQ2xhaW1JZDtcclxuICAgIGlmIChjaGFubmVsQ2xhaW1JZCA9PT0gJ25vbmUnKSBjaGFubmVsQ2xhaW1JZCA9IG51bGw7XHJcbiAgICBjb25zdCBwYWdlID0gcGFyYW1zLnBhZ2U7XHJcbiAgICBnZXRDaGFubmVsQ2xhaW1zKGNoYW5uZWxOYW1lLCBjaGFubmVsQ2xhaW1JZCwgcGFnZSlcclxuICAgICAgLnRoZW4oZGF0YSA9PiB7XHJcbiAgICAgICAgaWYgKGRhdGEgPT09IE5PX0NIQU5ORUwpIHtcclxuICAgICAgICAgIHJldHVybiByZXMuc3RhdHVzKDQwNCkuanNvbih7c3VjY2VzczogZmFsc2UsIG1lc3NhZ2U6ICdObyBtYXRjaGluZyBjaGFubmVsIHdhcyBmb3VuZCd9KTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmVzLnN0YXR1cygyMDApLmpzb24oe3N1Y2Nlc3M6IHRydWUsIGRhdGF9KTtcclxuICAgICAgfSlcclxuICAgICAgLmNhdGNoKGVycm9yID0+IHtcclxuICAgICAgICBoYW5kbGVFcnJvclJlc3BvbnNlKG9yaWdpbmFsVXJsLCBpcCwgZXJyb3IsIHJlcyk7XHJcbiAgICAgIH0pO1xyXG4gIH07XHJcbn07XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IGNoYW5uZWxDbGFpbXM7XHJcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL3NlcnZlci9yb3V0ZXMvYXBpL2NoYW5uZWxDbGFpbXMuanMiLCJjb25zdCBDTEFJTVNfUEVSX1BBR0UgPSAxMjtcblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIHJldHVyblBhZ2luYXRlZENoYW5uZWxDbGFpbXMgKGNoYW5uZWxOYW1lLCBsb25nQ2hhbm5lbENsYWltSWQsIGNsYWltcywgcGFnZSkge1xuICAgIGNvbnN0IHRvdGFsUGFnZXMgPSBtb2R1bGUuZXhwb3J0cy5kZXRlcm1pbmVUb3RhbFBhZ2VzKGNsYWltcyk7XG4gICAgY29uc3QgcGFnaW5hdGlvblBhZ2UgPSBtb2R1bGUuZXhwb3J0cy5nZXRQYWdlRnJvbVF1ZXJ5KHBhZ2UpO1xuICAgIGNvbnN0IHZpZXdEYXRhID0ge1xuICAgICAgY2hhbm5lbE5hbWUgICAgICAgOiBjaGFubmVsTmFtZSxcbiAgICAgIGxvbmdDaGFubmVsQ2xhaW1JZDogbG9uZ0NoYW5uZWxDbGFpbUlkLFxuICAgICAgY2xhaW1zICAgICAgICAgICAgOiBtb2R1bGUuZXhwb3J0cy5leHRyYWN0UGFnZUZyb21DbGFpbXMoY2xhaW1zLCBwYWdpbmF0aW9uUGFnZSksXG4gICAgICBwcmV2aW91c1BhZ2UgICAgICA6IG1vZHVsZS5leHBvcnRzLmRldGVybWluZVByZXZpb3VzUGFnZShwYWdpbmF0aW9uUGFnZSksXG4gICAgICBjdXJyZW50UGFnZSAgICAgICA6IHBhZ2luYXRpb25QYWdlLFxuICAgICAgbmV4dFBhZ2UgICAgICAgICAgOiBtb2R1bGUuZXhwb3J0cy5kZXRlcm1pbmVOZXh0UGFnZSh0b3RhbFBhZ2VzLCBwYWdpbmF0aW9uUGFnZSksXG4gICAgICB0b3RhbFBhZ2VzICAgICAgICA6IHRvdGFsUGFnZXMsXG4gICAgICB0b3RhbFJlc3VsdHMgICAgICA6IG1vZHVsZS5leHBvcnRzLmRldGVybWluZVRvdGFsQ2xhaW1zKGNsYWltcyksXG4gICAgfTtcbiAgICByZXR1cm4gdmlld0RhdGE7XG4gIH0sXG4gIGdldFBhZ2VGcm9tUXVlcnkgKHBhZ2UpIHtcbiAgICBpZiAocGFnZSkge1xuICAgICAgcmV0dXJuIHBhcnNlSW50KHBhZ2UpO1xuICAgIH1cbiAgICByZXR1cm4gMTtcbiAgfSxcbiAgZXh0cmFjdFBhZ2VGcm9tQ2xhaW1zIChjbGFpbXMsIHBhZ2VOdW1iZXIpIHtcbiAgICBpZiAoIWNsYWltcykge1xuICAgICAgcmV0dXJuIFtdOyAgLy8gaWYgbm8gY2xhaW1zLCByZXR1cm4gdGhpcyBkZWZhdWx0XG4gICAgfVxuICAgIC8vIGxvZ2dlci5kZWJ1ZygnY2xhaW1zIGlzIGFycmF5PycsIEFycmF5LmlzQXJyYXkoY2xhaW1zKSk7XG4gICAgLy8gbG9nZ2VyLmRlYnVnKGBwYWdlTnVtYmVyICR7cGFnZU51bWJlcn0gaXMgbnVtYmVyP2AsIE51bWJlci5pc0ludGVnZXIocGFnZU51bWJlcikpO1xuICAgIGNvbnN0IGNsYWltU3RhcnRJbmRleCA9IChwYWdlTnVtYmVyIC0gMSkgKiBDTEFJTVNfUEVSX1BBR0U7XG4gICAgY29uc3QgY2xhaW1FbmRJbmRleCA9IGNsYWltU3RhcnRJbmRleCArIENMQUlNU19QRVJfUEFHRTtcbiAgICBjb25zdCBwYWdlT2ZDbGFpbXMgPSBjbGFpbXMuc2xpY2UoY2xhaW1TdGFydEluZGV4LCBjbGFpbUVuZEluZGV4KTtcbiAgICByZXR1cm4gcGFnZU9mQ2xhaW1zO1xuICB9LFxuICBkZXRlcm1pbmVUb3RhbFBhZ2VzIChjbGFpbXMpIHtcbiAgICBpZiAoIWNsYWltcykge1xuICAgICAgcmV0dXJuIDA7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IHRvdGFsQ2xhaW1zID0gY2xhaW1zLmxlbmd0aDtcbiAgICAgIGlmICh0b3RhbENsYWltcyA8IENMQUlNU19QRVJfUEFHRSkge1xuICAgICAgICByZXR1cm4gMTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGZ1bGxQYWdlcyA9IE1hdGguZmxvb3IodG90YWxDbGFpbXMgLyBDTEFJTVNfUEVSX1BBR0UpO1xuICAgICAgY29uc3QgcmVtYWluZGVyID0gdG90YWxDbGFpbXMgJSBDTEFJTVNfUEVSX1BBR0U7XG4gICAgICBpZiAocmVtYWluZGVyID09PSAwKSB7XG4gICAgICAgIHJldHVybiBmdWxsUGFnZXM7XG4gICAgICB9XG4gICAgICByZXR1cm4gZnVsbFBhZ2VzICsgMTtcbiAgICB9XG4gIH0sXG4gIGRldGVybWluZVByZXZpb3VzUGFnZSAoY3VycmVudFBhZ2UpIHtcbiAgICBpZiAoY3VycmVudFBhZ2UgPT09IDEpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICByZXR1cm4gY3VycmVudFBhZ2UgLSAxO1xuICB9LFxuICBkZXRlcm1pbmVOZXh0UGFnZSAodG90YWxQYWdlcywgY3VycmVudFBhZ2UpIHtcbiAgICBpZiAoY3VycmVudFBhZ2UgPT09IHRvdGFsUGFnZXMpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICByZXR1cm4gY3VycmVudFBhZ2UgKyAxO1xuICB9LFxuICBkZXRlcm1pbmVUb3RhbENsYWltcyAoY2xhaW1zKSB7XG4gICAgaWYgKCFjbGFpbXMpIHtcbiAgICAgIHJldHVybiAwO1xuICAgIH1cbiAgICByZXR1cm4gY2xhaW1zLmxlbmd0aDtcbiAgfSxcbn07XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9zZXJ2ZXIvaGVscGVycy9jaGFubmVsUGFnaW5hdGlvbi5qcyIsImNvbnN0IHsgZ2V0Q2hhbm5lbERhdGEgfSA9IHJlcXVpcmUoJ2NvbnRyb2xsZXJzL3NlcnZlQ29udHJvbGxlci5qcycpO1xyXG5jb25zdCB7IGhhbmRsZUVycm9yUmVzcG9uc2UgfSA9IHJlcXVpcmUoJ2hlbHBlcnMvZXJyb3JIYW5kbGVycy5qcycpO1xyXG5cclxuY29uc3QgTk9fQ0hBTk5FTCA9ICdOT19DSEFOTkVMJztcclxuXHJcbi8qXHJcblxyXG4gIHJvdXRlIHRvIGdldCBkYXRhIGZvciBhIGNoYW5uZWxcclxuXHJcbiovXHJcblxyXG5jb25zdCBjaGFubmVsRGF0YSA9ICgpID0+IHtcclxuICByZXR1cm4gKHsgaXAsIG9yaWdpbmFsVXJsLCBib2R5LCBwYXJhbXMgfSwgcmVzKSA9PiB7XHJcbiAgICBjb25zdCBjaGFubmVsTmFtZSA9IHBhcmFtcy5jaGFubmVsTmFtZTtcclxuICAgIGxldCBjaGFubmVsQ2xhaW1JZCA9IHBhcmFtcy5jaGFubmVsQ2xhaW1JZDtcclxuICAgIGlmIChjaGFubmVsQ2xhaW1JZCA9PT0gJ25vbmUnKSBjaGFubmVsQ2xhaW1JZCA9IG51bGw7XHJcbiAgICBnZXRDaGFubmVsRGF0YShjaGFubmVsTmFtZSwgY2hhbm5lbENsYWltSWQsIDApXHJcbiAgICAgIC50aGVuKGRhdGEgPT4ge1xyXG4gICAgICAgIGlmIChkYXRhID09PSBOT19DSEFOTkVMKSB7XHJcbiAgICAgICAgICByZXR1cm4gcmVzLnN0YXR1cyg0MDQpLmpzb24oe3N1Y2Nlc3M6IGZhbHNlLCBtZXNzYWdlOiAnTm8gbWF0Y2hpbmcgY2hhbm5lbCB3YXMgZm91bmQnfSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJlcy5zdGF0dXMoMjAwKS5qc29uKHtzdWNjZXNzOiB0cnVlLCBkYXRhfSk7XHJcbiAgICAgIH0pXHJcbiAgICAgIC5jYXRjaChlcnJvciA9PiB7XHJcbiAgICAgICAgaGFuZGxlRXJyb3JSZXNwb25zZShvcmlnaW5hbFVybCwgaXAsIGVycm9yLCByZXMpO1xyXG4gICAgICB9KTtcclxuICB9O1xyXG59O1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBjaGFubmVsRGF0YTtcclxuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vc2VydmVyL3JvdXRlcy9hcGkvY2hhbm5lbERhdGEuanMiLCJjb25zdCB7IGhhbmRsZUVycm9yUmVzcG9uc2UgfSA9IHJlcXVpcmUoJ2hlbHBlcnMvZXJyb3JIYW5kbGVycy5qcycpO1xyXG5cclxuLypcclxuXHJcbnJvdXRlIHRvIGdldCBhIHNob3J0IGNoYW5uZWwgaWQgZnJvbSBsb25nIGNoYW5uZWwgSWRcclxuXHJcbiovXHJcblxyXG5jb25zdCBjaGFubmVsU2hvcnRJZFJvdXRlID0gKGRiKSA9PiB7XHJcbiAgcmV0dXJuICh7IGlwLCBvcmlnaW5hbFVybCwgcGFyYW1zIH0sIHJlcykgPT4ge1xyXG4gICAgZGIuQ2VydGlmaWNhdGUuZ2V0U2hvcnRDaGFubmVsSWRGcm9tTG9uZ0NoYW5uZWxJZChwYXJhbXMubG9uZ0lkLCBwYXJhbXMubmFtZSlcclxuICAgICAgLnRoZW4oc2hvcnRJZCA9PiB7XHJcbiAgICAgICAgcmVzLnN0YXR1cygyMDApLmpzb24oc2hvcnRJZCk7XHJcbiAgICAgIH0pXHJcbiAgICAgIC5jYXRjaChlcnJvciA9PiB7XHJcbiAgICAgICAgaGFuZGxlRXJyb3JSZXNwb25zZShvcmlnaW5hbFVybCwgaXAsIGVycm9yLCByZXMpO1xyXG4gICAgICB9KTtcclxuICB9O1xyXG59O1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBjaGFubmVsU2hvcnRJZFJvdXRlO1xyXG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9zZXJ2ZXIvcm91dGVzL2FwaS9jaGFubmVsU2hvcnRJZC5qcyIsImNvbnN0IHsgY2xhaW1OYW1lSXNBdmFpbGFibGUgfSA9IHJlcXVpcmUoJ2NvbnRyb2xsZXJzL3B1Ymxpc2hDb250cm9sbGVyLmpzJyk7XHJcbmNvbnN0IHsgc2VuZEdBVGltaW5nRXZlbnQgfSA9IHJlcXVpcmUoJ2hlbHBlcnMvZ29vZ2xlQW5hbHl0aWNzLmpzJyk7XHJcbmNvbnN0IHsgaGFuZGxlRXJyb3JSZXNwb25zZSB9ID0gcmVxdWlyZSgnaGVscGVycy9lcnJvckhhbmRsZXJzLmpzJyk7XHJcblxyXG4vKlxyXG5cclxuICByb3V0ZSB0byBjaGVjayB3aGV0aGVyIHRoaXMgc2l0ZSBwdWJsaXNoZWQgdG8gYSBjbGFpbVxyXG5cclxuKi9cclxuXHJcbmNvbnN0IGNsYWltQXZhaWxhYmlsaXR5ID0gKCkgPT4ge1xyXG4gIHJldHVybiAoeyBpcCwgb3JpZ2luYWxVcmwsIHBhcmFtczogeyBuYW1lIH0gfSwgcmVzKSA9PiB7XHJcbiAgICBjb25zdCBnYVN0YXJ0VGltZSA9IERhdGUubm93KCk7XHJcbiAgICBjbGFpbU5hbWVJc0F2YWlsYWJsZShuYW1lKVxyXG4gICAgICAudGhlbihyZXN1bHQgPT4ge1xyXG4gICAgICAgIHJlcy5zdGF0dXMoMjAwKS5qc29uKHJlc3VsdCk7XHJcbiAgICAgICAgc2VuZEdBVGltaW5nRXZlbnQoJ2VuZC10by1lbmQnLCAnY2xhaW0gbmFtZSBhdmFpbGFiaWxpdHknLCBuYW1lLCBnYVN0YXJ0VGltZSwgRGF0ZS5ub3coKSk7XHJcbiAgICAgIH0pXHJcbiAgICAgIC5jYXRjaChlcnJvciA9PiB7XHJcbiAgICAgICAgaGFuZGxlRXJyb3JSZXNwb25zZShvcmlnaW5hbFVybCwgaXAsIGVycm9yLCByZXMpO1xyXG4gICAgICB9KTtcclxuICB9O1xyXG59O1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBjbGFpbUF2YWlsYWJpbGl0eTtcclxuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vc2VydmVyL3JvdXRlcy9hcGkvY2xhaW1BdmFpbGFiaWxpdHkuanMiLCJjb25zdCB7IGhhbmRsZUVycm9yUmVzcG9uc2UgfSA9IHJlcXVpcmUoJ2hlbHBlcnMvZXJyb3JIYW5kbGVycy5qcycpO1xyXG5cclxuLypcclxuXHJcbiAgcm91dGUgdG8gcmV0dXJuIGRhdGEgZm9yIGEgY2xhaW1cclxuXHJcbiovXHJcblxyXG5jb25zdCBjbGFpbURhdGEgPSAoZGIpID0+IHtcclxuICByZXR1cm4gKHsgaXAsIG9yaWdpbmFsVXJsLCBib2R5LCBwYXJhbXMgfSwgcmVzKSA9PiB7XHJcbiAgICBjb25zdCBjbGFpbU5hbWUgPSBwYXJhbXMuY2xhaW1OYW1lO1xyXG4gICAgbGV0IGNsYWltSWQgPSBwYXJhbXMuY2xhaW1JZDtcclxuICAgIGlmIChjbGFpbUlkID09PSAnbm9uZScpIGNsYWltSWQgPSBudWxsO1xyXG4gICAgZGIuQ2xhaW0ucmVzb2x2ZUNsYWltKGNsYWltTmFtZSwgY2xhaW1JZClcclxuICAgICAgLnRoZW4oY2xhaW1JbmZvID0+IHtcclxuICAgICAgICBpZiAoIWNsYWltSW5mbykge1xyXG4gICAgICAgICAgcmV0dXJuIHJlcy5zdGF0dXMoNDA0KS5qc29uKHtzdWNjZXNzOiBmYWxzZSwgbWVzc2FnZTogJ05vIGNsYWltIGNvdWxkIGJlIGZvdW5kJ30pO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXMuc3RhdHVzKDIwMCkuanNvbih7c3VjY2VzczogdHJ1ZSwgZGF0YTogY2xhaW1JbmZvfSk7XHJcbiAgICAgIH0pXHJcbiAgICAgIC5jYXRjaChlcnJvciA9PiB7XHJcbiAgICAgICAgaGFuZGxlRXJyb3JSZXNwb25zZShvcmlnaW5hbFVybCwgaXAsIGVycm9yLCByZXMpO1xyXG4gICAgICB9KTtcclxuICB9O1xyXG59O1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBjbGFpbURhdGE7XHJcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL3NlcnZlci9yb3V0ZXMvYXBpL2NsYWltRGF0YS5qcyIsImNvbnN0IHsgZ2V0Q2xhaW0gfSA9IHJlcXVpcmUoJ2hlbHBlcnMvbGJyeUFwaS5qcycpO1xyXG5jb25zdCB7IGFkZEdldFJlc3VsdHNUb0ZpbGVEYXRhLCBjcmVhdGVGaWxlRGF0YSB9ID0gcmVxdWlyZSgnLi4vLi4vaGVscGVycy9wdWJsaXNoSGVscGVycy5qcycpO1xyXG5jb25zdCB7IGhhbmRsZUVycm9yUmVzcG9uc2UgfSA9IHJlcXVpcmUoJ2hlbHBlcnMvZXJyb3JIYW5kbGVycy5qcycpO1xyXG5cclxuLypcclxuXHJcbiAgcm91dGUgdG8gZ2V0IGEgY2xhaW1cclxuXHJcbiovXHJcblxyXG5jb25zdCBjbGFpbUdldCA9IChkYikgPT4ge1xyXG4gIHJldHVybiAoeyBpcCwgb3JpZ2luYWxVcmwsIHBhcmFtcyB9LCByZXMpID0+IHtcclxuICAgIGNvbnN0IG5hbWUgPSBwYXJhbXMubmFtZTtcclxuICAgIGNvbnN0IGNsYWltSWQgPSBwYXJhbXMuY2xhaW1JZDtcclxuICAgIC8vIHJlc29sdmUgdGhlIGNsYWltXHJcbiAgICBkYi5DbGFpbS5yZXNvbHZlQ2xhaW0obmFtZSwgY2xhaW1JZClcclxuICAgICAgLnRoZW4ocmVzb2x2ZVJlc3VsdCA9PiB7XHJcbiAgICAgICAgLy8gbWFrZSBzdXJlIGEgY2xhaW0gYWN0dWFsbHkgZXhpc3RzIGF0IHRoYXQgdXJpXHJcbiAgICAgICAgaWYgKCFyZXNvbHZlUmVzdWx0KSB7XHJcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ05vIG1hdGNoaW5nIHVyaSBmb3VuZCBpbiBDbGFpbSB0YWJsZScpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBsZXQgZmlsZURhdGEgPSBjcmVhdGVGaWxlRGF0YShyZXNvbHZlUmVzdWx0KTtcclxuICAgICAgICAvLyBnZXQgdGhlIGNsYWltXHJcbiAgICAgICAgcmV0dXJuIFByb21pc2UuYWxsKFtmaWxlRGF0YSwgZ2V0Q2xhaW0oYCR7bmFtZX0jJHtjbGFpbUlkfWApXSk7XHJcbiAgICAgIH0pXHJcbiAgICAgIC50aGVuKChbIGZpbGVEYXRhLCBnZXRSZXN1bHQgXSkgPT4ge1xyXG4gICAgICAgIGZpbGVEYXRhID0gYWRkR2V0UmVzdWx0c1RvRmlsZURhdGEoZmlsZURhdGEsIGdldFJlc3VsdCk7XHJcbiAgICAgICAgcmV0dXJuIFByb21pc2UuYWxsKFtkYi51cHNlcnQoZGIuRmlsZSwgZmlsZURhdGEsIHtuYW1lLCBjbGFpbUlkfSwgJ0ZpbGUnKSwgZ2V0UmVzdWx0XSk7XHJcbiAgICAgIH0pXHJcbiAgICAgIC50aGVuKChbIGZpbGVSZWNvcmQsIHttZXNzYWdlLCBjb21wbGV0ZWR9IF0pID0+IHtcclxuICAgICAgICByZXMuc3RhdHVzKDIwMCkuanNvbih7IHN1Y2Nlc3M6IHRydWUsIG1lc3NhZ2UsIGNvbXBsZXRlZCB9KTtcclxuICAgICAgfSlcclxuICAgICAgLmNhdGNoKGVycm9yID0+IHtcclxuICAgICAgICBoYW5kbGVFcnJvclJlc3BvbnNlKG9yaWdpbmFsVXJsLCBpcCwgZXJyb3IsIHJlcyk7XHJcbiAgICAgIH0pO1xyXG4gIH07XHJcbn07XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IGNsYWltR2V0O1xyXG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9zZXJ2ZXIvcm91dGVzL2FwaS9jbGFpbUdldC5qcyIsImNvbnN0IHsgZ2V0Q2xhaW1JZCB9ID0gcmVxdWlyZSgnY29udHJvbGxlcnMvc2VydmVDb250cm9sbGVyLmpzJyk7XHJcbmNvbnN0IHsgaGFuZGxlRXJyb3JSZXNwb25zZSB9ID0gcmVxdWlyZSgnaGVscGVycy9lcnJvckhhbmRsZXJzLmpzJyk7XHJcblxyXG5jb25zdCBOT19DSEFOTkVMID0gJ05PX0NIQU5ORUwnO1xyXG5jb25zdCBOT19DTEFJTSA9ICdOT19DTEFJTSc7XHJcblxyXG4vKlxyXG5cclxuICByb3V0ZSB0byBnZXQgYSBsb25nIGNsYWltIGlkXHJcblxyXG4qL1xyXG5cclxuY29uc3QgY2xhaW1Mb25nSWQgPSAoKSA9PiB7XHJcbiAgcmV0dXJuICh7IGlwLCBvcmlnaW5hbFVybCwgYm9keSwgcGFyYW1zIH0sIHJlcykgPT4ge1xyXG4gICAgY29uc3QgY2hhbm5lbE5hbWUgPSBib2R5LmNoYW5uZWxOYW1lO1xyXG4gICAgY29uc3QgY2hhbm5lbENsYWltSWQgPSBib2R5LmNoYW5uZWxDbGFpbUlkO1xyXG4gICAgY29uc3QgY2xhaW1OYW1lID0gYm9keS5jbGFpbU5hbWU7XHJcbiAgICBjb25zdCBjbGFpbUlkID0gYm9keS5jbGFpbUlkO1xyXG4gICAgZ2V0Q2xhaW1JZChjaGFubmVsTmFtZSwgY2hhbm5lbENsYWltSWQsIGNsYWltTmFtZSwgY2xhaW1JZClcclxuICAgICAgLnRoZW4ocmVzdWx0ID0+IHtcclxuICAgICAgICBpZiAocmVzdWx0ID09PSBOT19DSEFOTkVMKSB7XHJcbiAgICAgICAgICByZXR1cm4gcmVzLnN0YXR1cyg0MDQpLmpzb24oe3N1Y2Nlc3M6IGZhbHNlLCBtZXNzYWdlOiAnTm8gbWF0Y2hpbmcgY2hhbm5lbCBjb3VsZCBiZSBmb3VuZCd9KTtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKHJlc3VsdCA9PT0gTk9fQ0xBSU0pIHtcclxuICAgICAgICAgIHJldHVybiByZXMuc3RhdHVzKDQwNCkuanNvbih7c3VjY2VzczogZmFsc2UsIG1lc3NhZ2U6ICdObyBtYXRjaGluZyBjbGFpbSBpZCBjb3VsZCBiZSBmb3VuZCd9KTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmVzLnN0YXR1cygyMDApLmpzb24oe3N1Y2Nlc3M6IHRydWUsIGRhdGE6IHJlc3VsdH0pO1xyXG4gICAgICB9KVxyXG4gICAgICAuY2F0Y2goZXJyb3IgPT4ge1xyXG4gICAgICAgIGhhbmRsZUVycm9yUmVzcG9uc2Uob3JpZ2luYWxVcmwsIGlwLCBlcnJvciwgcmVzKTtcclxuICAgICAgfSk7XHJcbiAgfTtcclxufTtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gY2xhaW1Mb25nSWQ7XHJcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL3NlcnZlci9yb3V0ZXMvYXBpL2NsYWltTG9uZ0lkLmpzIiwiY29uc3QgeyBjcmVhdGVCYXNpY1B1Ymxpc2hQYXJhbXMsIGNyZWF0ZVRodW1ibmFpbFB1Ymxpc2hQYXJhbXMsIHBhcnNlUHVibGlzaEFwaVJlcXVlc3RCb2R5LCBwYXJzZVB1Ymxpc2hBcGlSZXF1ZXN0RmlsZXMgfSA9IHJlcXVpcmUoJ2hlbHBlcnMvcHVibGlzaEhlbHBlcnMuanMnKTtcclxuY29uc3QgeyBjbGFpbU5hbWVJc0F2YWlsYWJsZSwgcHVibGlzaCB9ID0gcmVxdWlyZSgnY29udHJvbGxlcnMvcHVibGlzaENvbnRyb2xsZXIuanMnKTtcclxuY29uc3QgeyBhdXRoZW50aWNhdGVVc2VyIH0gPSByZXF1aXJlKCdhdXRoL2F1dGhlbnRpY2F0aW9uLmpzJyk7XHJcbmNvbnN0IHsgc2VuZEdBVGltaW5nRXZlbnQgfSA9IHJlcXVpcmUoJ2hlbHBlcnMvZ29vZ2xlQW5hbHl0aWNzLmpzJyk7XHJcbmNvbnN0IHsgaGFuZGxlRXJyb3JSZXNwb25zZSB9ID0gcmVxdWlyZSgnaGVscGVycy9lcnJvckhhbmRsZXJzLmpzJyk7XHJcbmNvbnN0IHsgZGV0YWlsczogeyBob3N0IH0gfSA9IHJlcXVpcmUoJ3NpdGVDb25maWcuanMnKTtcclxuXHJcbi8qXHJcblxyXG4gIHJvdXRlIHRvIHB1Ymxpc2ggYSBjbGFpbSB0aHJvdWdoIHRoZSBkYWVtb25cclxuXHJcbiovXHJcblxyXG5jb25zdCBjbGFpbVB1Ymxpc2ggPSAoZGIpID0+IHtcclxuICByZXR1cm4gKHsgYm9keSwgZmlsZXMsIGhlYWRlcnMsIGlwLCBvcmlnaW5hbFVybCwgdXNlciB9LCByZXMpID0+IHtcclxuICAgIC8vIGRlZmluZSB2YXJpYWJsZXNcclxuICAgIGxldCAgY2hhbm5lbE5hbWUsIGNoYW5uZWxJZCwgY2hhbm5lbFBhc3N3b3JkLCBkZXNjcmlwdGlvbiwgZmlsZU5hbWUsIGZpbGVQYXRoLCBmaWxlVHlwZSwgZ2FTdGFydFRpbWUsIGxpY2Vuc2UsIG5hbWUsIG5zZncsIHRodW1ibmFpbCwgdGh1bWJuYWlsRmlsZU5hbWUsIHRodW1ibmFpbEZpbGVQYXRoLCB0aHVtYm5haWxGaWxlVHlwZSwgdGl0bGU7XHJcbiAgICAvLyByZWNvcmQgdGhlIHN0YXJ0IHRpbWUgb2YgdGhlIHJlcXVlc3RcclxuICAgIGdhU3RhcnRUaW1lID0gRGF0ZS5ub3coKTtcclxuICAgIC8vIHZhbGlkYXRlIHRoZSBib2R5IGFuZCBmaWxlcyBvZiB0aGUgcmVxdWVzdFxyXG4gICAgdHJ5IHtcclxuICAgICAgLy8gdmFsaWRhdGVBcGlQdWJsaXNoUmVxdWVzdChib2R5LCBmaWxlcyk7XHJcbiAgICAgICh7bmFtZSwgbnNmdywgbGljZW5zZSwgdGl0bGUsIGRlc2NyaXB0aW9uLCB0aHVtYm5haWx9ID0gcGFyc2VQdWJsaXNoQXBpUmVxdWVzdEJvZHkoYm9keSkpO1xyXG4gICAgICAoe2ZpbGVOYW1lLCBmaWxlUGF0aCwgZmlsZVR5cGUsIHRodW1ibmFpbEZpbGVOYW1lLCB0aHVtYm5haWxGaWxlUGF0aCwgdGh1bWJuYWlsRmlsZVR5cGV9ID0gcGFyc2VQdWJsaXNoQXBpUmVxdWVzdEZpbGVzKGZpbGVzKSk7XHJcbiAgICAgICh7Y2hhbm5lbE5hbWUsIGNoYW5uZWxJZCwgY2hhbm5lbFBhc3N3b3JkfSA9IGJvZHkpO1xyXG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcclxuICAgICAgcmV0dXJuIHJlcy5zdGF0dXMoNDAwKS5qc29uKHtzdWNjZXNzOiBmYWxzZSwgbWVzc2FnZTogZXJyb3IubWVzc2FnZX0pO1xyXG4gICAgfVxyXG4gICAgLy8gY2hlY2sgY2hhbm5lbCBhdXRob3JpemF0aW9uXHJcbiAgICBQcm9taXNlXHJcbiAgICAgIC5hbGwoW1xyXG4gICAgICAgIGF1dGhlbnRpY2F0ZVVzZXIoY2hhbm5lbE5hbWUsIGNoYW5uZWxJZCwgY2hhbm5lbFBhc3N3b3JkLCB1c2VyKSxcclxuICAgICAgICBjbGFpbU5hbWVJc0F2YWlsYWJsZShuYW1lKSxcclxuICAgICAgICBjcmVhdGVCYXNpY1B1Ymxpc2hQYXJhbXMoZmlsZVBhdGgsIG5hbWUsIHRpdGxlLCBkZXNjcmlwdGlvbiwgbGljZW5zZSwgbnNmdywgdGh1bWJuYWlsKSxcclxuICAgICAgICBjcmVhdGVUaHVtYm5haWxQdWJsaXNoUGFyYW1zKHRodW1ibmFpbEZpbGVQYXRoLCBuYW1lLCBsaWNlbnNlLCBuc2Z3KSxcclxuICAgICAgXSlcclxuICAgICAgLnRoZW4oKFt7Y2hhbm5lbE5hbWUsIGNoYW5uZWxDbGFpbUlkfSwgdmFsaWRhdGVkQ2xhaW1OYW1lLCBwdWJsaXNoUGFyYW1zLCB0aHVtYm5haWxQdWJsaXNoUGFyYW1zXSkgPT4ge1xyXG4gICAgICAgIC8vIGFkZCBjaGFubmVsIGRldGFpbHMgdG8gdGhlIHB1Ymxpc2ggcGFyYW1zXHJcbiAgICAgICAgaWYgKGNoYW5uZWxOYW1lICYmIGNoYW5uZWxDbGFpbUlkKSB7XHJcbiAgICAgICAgICBwdWJsaXNoUGFyYW1zWydjaGFubmVsX25hbWUnXSA9IGNoYW5uZWxOYW1lO1xyXG4gICAgICAgICAgcHVibGlzaFBhcmFtc1snY2hhbm5lbF9pZCddID0gY2hhbm5lbENsYWltSWQ7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIHB1Ymxpc2ggdGhlIHRodW1ibmFpbFxyXG4gICAgICAgIGlmICh0aHVtYm5haWxQdWJsaXNoUGFyYW1zKSB7XHJcbiAgICAgICAgICBwdWJsaXNoKHRodW1ibmFpbFB1Ymxpc2hQYXJhbXMsIHRodW1ibmFpbEZpbGVOYW1lLCB0aHVtYm5haWxGaWxlVHlwZSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIHB1Ymxpc2ggdGhlIGFzc2V0XHJcbiAgICAgICAgcmV0dXJuIHB1Ymxpc2gocHVibGlzaFBhcmFtcywgZmlsZU5hbWUsIGZpbGVUeXBlKTtcclxuICAgICAgfSlcclxuICAgICAgLnRoZW4ocmVzdWx0ID0+IHtcclxuICAgICAgICByZXMuc3RhdHVzKDIwMCkuanNvbih7XHJcbiAgICAgICAgICBzdWNjZXNzOiB0cnVlLFxyXG4gICAgICAgICAgbWVzc2FnZTogJ3B1Ymxpc2ggY29tcGxldGVkIHN1Y2Nlc3NmdWxseScsXHJcbiAgICAgICAgICBkYXRhICAgOiB7XHJcbiAgICAgICAgICAgIG5hbWUsXHJcbiAgICAgICAgICAgIGNsYWltSWQ6IHJlc3VsdC5jbGFpbV9pZCxcclxuICAgICAgICAgICAgdXJsICAgIDogYCR7aG9zdH0vJHtyZXN1bHQuY2xhaW1faWR9LyR7bmFtZX1gLFxyXG4gICAgICAgICAgICBsYnJ5VHggOiByZXN1bHQsXHJcbiAgICAgICAgICB9LFxyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIC8vIHJlY29yZCB0aGUgcHVibGlzaCBlbmQgdGltZSBhbmQgc2VuZCB0byBnb29nbGUgYW5hbHl0aWNzXHJcbiAgICAgICAgc2VuZEdBVGltaW5nRXZlbnQoJ2VuZC10by1lbmQnLCAncHVibGlzaCcsIGZpbGVUeXBlLCBnYVN0YXJ0VGltZSwgRGF0ZS5ub3coKSk7XHJcbiAgICAgIH0pXHJcbiAgICAgIC5jYXRjaChlcnJvciA9PiB7XHJcbiAgICAgICAgaGFuZGxlRXJyb3JSZXNwb25zZShvcmlnaW5hbFVybCwgaXAsIGVycm9yLCByZXMpO1xyXG4gICAgICB9KTtcclxuICB9O1xyXG59O1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBjbGFpbVB1Ymxpc2g7XHJcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL3NlcnZlci9yb3V0ZXMvYXBpL2NsYWltUHVibGlzaC5qcyIsImNvbnN0IHsgZGIgfSA9IHJlcXVpcmUoJ215c3FsQ29uZmlnJyk7XG5jb25zdCBsb2dnZXIgPSByZXF1aXJlKCd3aW5zdG9uJyk7XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICBhdXRoZW50aWNhdGVVc2VyIChjaGFubmVsTmFtZSwgY2hhbm5lbElkLCBjaGFubmVsUGFzc3dvcmQsIHVzZXIpIHtcbiAgICAvLyBjYXNlOiBubyBjaGFubmVsTmFtZSBvciBjaGFubmVsIElkIGFyZSBwcm92aWRlZCAoYW5vbnltb3VzKSwgcmVnYXJkbGVzcyBvZiB3aGV0aGVyIHVzZXIgdG9rZW4gaXMgcHJvdmlkZWRcbiAgICBpZiAoIWNoYW5uZWxOYW1lICYmICFjaGFubmVsSWQpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGNoYW5uZWxOYW1lICAgOiBudWxsLFxuICAgICAgICBjaGFubmVsQ2xhaW1JZDogbnVsbCxcbiAgICAgIH07XG4gICAgfVxuICAgIC8vIGNhc2U6IGNoYW5uZWxOYW1lIG9yIGNoYW5uZWwgSWQgYXJlIHByb3ZpZGVkIHdpdGggdXNlciB0b2tlblxuICAgIGlmICh1c2VyKSB7XG4gICAgICBpZiAoY2hhbm5lbE5hbWUgJiYgY2hhbm5lbE5hbWUgIT09IHVzZXIuY2hhbm5lbE5hbWUpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCd0aGUgcHJvdmlkZWQgY2hhbm5lbCBuYW1lIGRvZXMgbm90IG1hdGNoIHVzZXIgY3JlZGVudGlhbHMnKTtcbiAgICAgIH1cbiAgICAgIGlmIChjaGFubmVsSWQgJiYgY2hhbm5lbElkICE9PSB1c2VyLmNoYW5uZWxDbGFpbUlkKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcigndGhlIHByb3ZpZGVkIGNoYW5uZWwgaWQgZG9lcyBub3QgbWF0Y2ggdXNlciBjcmVkZW50aWFscycpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgY2hhbm5lbE5hbWUgICA6IHVzZXIuY2hhbm5lbE5hbWUsXG4gICAgICAgIGNoYW5uZWxDbGFpbUlkOiB1c2VyLmNoYW5uZWxDbGFpbUlkLFxuICAgICAgfTtcbiAgICB9XG4gICAgLy8gY2FzZTogY2hhbm5lbE5hbWUgb3IgY2hhbm5lbCBJZCBhcmUgcHJvdmlkZWQgd2l0aCBwYXNzd29yZCBpbnN0ZWFkIG9mIHVzZXIgdG9rZW5cbiAgICBpZiAoIWNoYW5uZWxQYXNzd29yZCkgdGhyb3cgbmV3IEVycm9yKCdubyBjaGFubmVsIHBhc3N3b3JkIHByb3ZpZGVkJyk7XG4gICAgcmV0dXJuIG1vZHVsZS5leHBvcnRzLmF1dGhlbnRpY2F0ZUNoYW5uZWxDcmVkZW50aWFscyhjaGFubmVsTmFtZSwgY2hhbm5lbElkLCBjaGFubmVsUGFzc3dvcmQpO1xuICB9LFxuICBhdXRoZW50aWNhdGVDaGFubmVsQ3JlZGVudGlhbHMgKGNoYW5uZWxOYW1lLCBjaGFubmVsSWQsIHVzZXJQYXNzd29yZCkge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAvLyBob2lzdGVkIHZhcmlhYmxlc1xuICAgICAgbGV0IGNoYW5uZWxEYXRhO1xuICAgICAgLy8gYnVpbGQgdGhlIHBhcmFtcyBmb3IgZmluZGluZyB0aGUgY2hhbm5lbFxuICAgICAgbGV0IGNoYW5uZWxGaW5kUGFyYW1zID0ge307XG4gICAgICBpZiAoY2hhbm5lbE5hbWUpIGNoYW5uZWxGaW5kUGFyYW1zWydjaGFubmVsTmFtZSddID0gY2hhbm5lbE5hbWU7XG4gICAgICBpZiAoY2hhbm5lbElkKSBjaGFubmVsRmluZFBhcmFtc1snY2hhbm5lbENsYWltSWQnXSA9IGNoYW5uZWxJZDtcbiAgICAgIC8vIGZpbmQgdGhlIGNoYW5uZWxcbiAgICAgIGRiLkNoYW5uZWxcbiAgICAgICAgLmZpbmRPbmUoe1xuICAgICAgICAgIHdoZXJlOiBjaGFubmVsRmluZFBhcmFtcyxcbiAgICAgICAgfSlcbiAgICAgICAgLnRoZW4oY2hhbm5lbCA9PiB7XG4gICAgICAgICAgaWYgKCFjaGFubmVsKSB7XG4gICAgICAgICAgICBsb2dnZXIuZGVidWcoJ25vIGNoYW5uZWwgZm91bmQnKTtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignQXV0aGVudGljYXRpb24gZmFpbGVkLCB5b3UgZG8gbm90IGhhdmUgYWNjZXNzIHRvIHRoYXQgY2hhbm5lbCcpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjaGFubmVsRGF0YSA9IGNoYW5uZWwuZ2V0KCk7XG4gICAgICAgICAgbG9nZ2VyLmRlYnVnKCdjaGFubmVsIGRhdGE6JywgY2hhbm5lbERhdGEpO1xuICAgICAgICAgIHJldHVybiBkYi5Vc2VyLmZpbmRPbmUoe1xuICAgICAgICAgICAgd2hlcmU6IHsgdXNlck5hbWU6IGNoYW5uZWxEYXRhLmNoYW5uZWxOYW1lLnN1YnN0cmluZygxKSB9LFxuICAgICAgICAgIH0pO1xuICAgICAgICB9KVxuICAgICAgICAudGhlbih1c2VyID0+IHtcbiAgICAgICAgICBpZiAoIXVzZXIpIHtcbiAgICAgICAgICAgIGxvZ2dlci5kZWJ1Zygnbm8gdXNlciBmb3VuZCcpO1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdBdXRoZW50aWNhdGlvbiBmYWlsZWQsIHlvdSBkbyBub3QgaGF2ZSBhY2Nlc3MgdG8gdGhhdCBjaGFubmVsJyk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiB1c2VyLmNvbXBhcmVQYXNzd29yZCh1c2VyUGFzc3dvcmQpO1xuICAgICAgICB9KVxuICAgICAgICAudGhlbihpc01hdGNoID0+IHtcbiAgICAgICAgICBpZiAoIWlzTWF0Y2gpIHtcbiAgICAgICAgICAgIGxvZ2dlci5kZWJ1ZygnaW5jb3JyZWN0IHBhc3N3b3JkJyk7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0F1dGhlbnRpY2F0aW9uIGZhaWxlZCwgeW91IGRvIG5vdCBoYXZlIGFjY2VzcyB0byB0aGF0IGNoYW5uZWwnKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgbG9nZ2VyLmRlYnVnKCcuLi5wYXNzd29yZCB3YXMgYSBtYXRjaC4uLicpO1xuICAgICAgICAgIHJlc29sdmUoY2hhbm5lbERhdGEpO1xuICAgICAgICB9KVxuICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgIH0pO1xuICAgIH0pO1xuICB9LFxufTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL3NlcnZlci9hdXRoL2F1dGhlbnRpY2F0aW9uLmpzIiwiY29uc3QgeyByZXNvbHZlVXJpIH0gPSByZXF1aXJlKCdoZWxwZXJzL2xicnlBcGkuanMnKTtcclxuY29uc3QgeyBoYW5kbGVFcnJvclJlc3BvbnNlIH0gPSByZXF1aXJlKCdoZWxwZXJzL2Vycm9ySGFuZGxlcnMuanMnKTtcclxuXHJcbi8qXHJcblxyXG4gIHJvdXRlIHRvIHJ1biBhIHJlc29sdmUgcmVxdWVzdCBvbiB0aGUgZGFlbW9uXHJcblxyXG4qL1xyXG5cclxuY29uc3QgY2xhaW1SZXNvbHZlID0gKCkgPT4ge1xyXG4gIHJldHVybiAoeyBoZWFkZXJzLCBpcCwgb3JpZ2luYWxVcmwsIHBhcmFtcyB9LCByZXMpID0+IHtcclxuICAgIHJlc29sdmVVcmkoYCR7cGFyYW1zLm5hbWV9IyR7cGFyYW1zLmNsYWltSWR9YClcclxuICAgICAgLnRoZW4ocmVzb2x2ZWRVcmkgPT4ge1xyXG4gICAgICAgIHJlcy5zdGF0dXMoMjAwKS5qc29uKHJlc29sdmVkVXJpKTtcclxuICAgICAgfSlcclxuICAgICAgLmNhdGNoKGVycm9yID0+IHtcclxuICAgICAgICBoYW5kbGVFcnJvclJlc3BvbnNlKG9yaWdpbmFsVXJsLCBpcCwgZXJyb3IsIHJlcyk7XHJcbiAgICAgIH0pO1xyXG4gIH07XHJcbn07XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IGNsYWltUmVzb2x2ZTtcclxuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vc2VydmVyL3JvdXRlcy9hcGkvY2xhaW1SZXNvbHZlLmpzIiwiY29uc3QgeyBoYW5kbGVFcnJvclJlc3BvbnNlIH0gPSByZXF1aXJlKCdoZWxwZXJzL2Vycm9ySGFuZGxlcnMuanMnKTtcclxuXHJcbi8qXHJcblxyXG4gIHJvdXRlIHRvIGdldCBhIHNob3J0IGNsYWltIGlkIGZyb20gbG9uZyBjbGFpbSBJZFxyXG5cclxuKi9cclxuXHJcbmNvbnN0IGNsYWltU2hvcnRJZCA9IChkYikgPT4ge1xyXG4gIHJldHVybiAoeyBpcCwgb3JpZ2luYWxVcmwsIGJvZHksIHBhcmFtcyB9LCByZXMpID0+IHtcclxuICAgIGRiLkNsYWltLmdldFNob3J0Q2xhaW1JZEZyb21Mb25nQ2xhaW1JZChwYXJhbXMubG9uZ0lkLCBwYXJhbXMubmFtZSlcclxuICAgICAgLnRoZW4oc2hvcnRJZCA9PiB7XHJcbiAgICAgICAgcmVzLnN0YXR1cygyMDApLmpzb24oe3N1Y2Nlc3M6IHRydWUsIGRhdGE6IHNob3J0SWR9KTtcclxuICAgICAgfSlcclxuICAgICAgLmNhdGNoKGVycm9yID0+IHtcclxuICAgICAgICBoYW5kbGVFcnJvclJlc3BvbnNlKG9yaWdpbmFsVXJsLCBpcCwgZXJyb3IsIHJlcyk7XHJcbiAgICAgIH0pO1xyXG4gIH07XHJcbn07XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IGNsYWltU2hvcnRJZDtcclxuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vc2VydmVyL3JvdXRlcy9hcGkvY2xhaW1TaG9ydElkLmpzIiwiXHJcbmNvbnN0IHsgaGFuZGxlRXJyb3JSZXNwb25zZSB9ID0gcmVxdWlyZSgnaGVscGVycy9lcnJvckhhbmRsZXJzLmpzJyk7XHJcblxyXG4vKlxyXG5cclxuICByb3V0ZSB0byBzZWUgaWYgYXNzZXQgaXMgYXZhaWxhYmxlIGxvY2FsbHlcclxuXHJcbiovXHJcblxyXG5jb25zdCBmaWxlQXZhaWxhYmlsaXR5ID0gKGRiKSA9PiB7XHJcbiAgcmV0dXJuICh7IGlwLCBvcmlnaW5hbFVybCwgcGFyYW1zIH0sIHJlcykgPT4ge1xyXG4gICAgY29uc3QgbmFtZSA9IHBhcmFtcy5uYW1lO1xyXG4gICAgY29uc3QgY2xhaW1JZCA9IHBhcmFtcy5jbGFpbUlkO1xyXG4gICAgZGIuRmlsZVxyXG4gICAgICAuZmluZE9uZSh7XHJcbiAgICAgICAgd2hlcmU6IHtcclxuICAgICAgICAgIG5hbWUsXHJcbiAgICAgICAgICBjbGFpbUlkLFxyXG4gICAgICAgIH0sXHJcbiAgICAgIH0pXHJcbiAgICAgIC50aGVuKHJlc3VsdCA9PiB7XHJcbiAgICAgICAgaWYgKHJlc3VsdCkge1xyXG4gICAgICAgICAgcmV0dXJuIHJlcy5zdGF0dXMoMjAwKS5qc29uKHtzdWNjZXNzOiB0cnVlLCBkYXRhOiB0cnVlfSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJlcy5zdGF0dXMoMjAwKS5qc29uKHtzdWNjZXNzOiB0cnVlLCBkYXRhOiBmYWxzZX0pO1xyXG4gICAgICB9KVxyXG4gICAgICAuY2F0Y2goZXJyb3IgPT4ge1xyXG4gICAgICAgIGhhbmRsZUVycm9yUmVzcG9uc2Uob3JpZ2luYWxVcmwsIGlwLCBlcnJvciwgcmVzKTtcclxuICAgICAgfSk7XHJcbiAgfTtcclxufTtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gZmlsZUF2YWlsYWJpbGl0eTtcclxuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vc2VydmVyL3JvdXRlcy9hcGkvZmlsZUF2YWlsYWJpbGl0eS5qcyIsImNvbnN0IHNlcnZlQXNzZXRCeUNsYWltID0gcmVxdWlyZSgnLi9zZXJ2ZUFzc2V0QnlDbGFpbScpO1xuY29uc3Qgc2VydmVBc3NldEJ5SWRlbnRpZmllckFuZENsYWltID0gcmVxdWlyZSgnLi9zZXJ2ZUFzc2V0QnlJZGVudGlmaWVyQW5kQ2xhaW0nKTtcblxuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgc2VydmVBc3NldEJ5Q2xhaW0sXG4gIHNlcnZlQXNzZXRCeUlkZW50aWZpZXJBbmRDbGFpbSxcbn07XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9zZXJ2ZXIvcm91dGVzL2Fzc2V0L2luZGV4LmpzIiwiY29uc3QgeyBzZW5kR0FTZXJ2ZUV2ZW50IH0gPSByZXF1aXJlKCdoZWxwZXJzL2dvb2dsZUFuYWx5dGljcycpO1xyXG5jb25zdCB7IGRldGVybWluZVJlc3BvbnNlVHlwZSwgbG9nUmVxdWVzdERhdGEsIGdldENsYWltSWRBbmRTZXJ2ZUFzc2V0IH0gPSByZXF1aXJlKCdoZWxwZXJzL3NlcnZlSGVscGVycy5qcycpO1xyXG5jb25zdCBsYnJ5VXJpID0gcmVxdWlyZSgnaGVscGVycy9sYnJ5VXJpLmpzJyk7XHJcbmNvbnN0IGhhbmRsZVNob3dSZW5kZXIgPSByZXF1aXJlKCdoZWxwZXJzL2hhbmRsZVNob3dSZW5kZXIuanN4Jyk7XHJcbmNvbnN0IFNFUlZFID0gJ1NFUlZFJztcclxuXHJcbi8qXHJcblxyXG4gIHJvdXRlIHRvIHNlcnZlIGFuIGFzc2V0IG9yIHRoZSByZWFjdCBhcHAgdmlhIHRoZSBjbGFpbSBuYW1lIG9ubHlcclxuXHJcbiovXHJcblxyXG5jb25zdCBjbGFpbSA9ICgpID0+IHtcclxuICByZXR1cm4gKHJlcSwgcmVzKSA9PiB7XHJcbiAgICBjb25zdCB7IGhlYWRlcnMsIGlwLCBvcmlnaW5hbFVybCwgcGFyYW1zIH0gPSByZXE7XHJcbiAgICAvLyBkZWNpZGUgaWYgdGhpcyBpcyBhIHNob3cgcmVxdWVzdFxyXG4gICAgbGV0IGhhc0ZpbGVFeHRlbnNpb247XHJcbiAgICB0cnkge1xyXG4gICAgICAoeyBoYXNGaWxlRXh0ZW5zaW9uIH0gPSBsYnJ5VXJpLnBhcnNlTW9kaWZpZXIocGFyYW1zLmNsYWltKSk7XHJcbiAgICB9IGNhdGNoIChlcnJvcikge1xyXG4gICAgICByZXR1cm4gcmVzLnN0YXR1cyg0MDApLmpzb24oe3N1Y2Nlc3M6IGZhbHNlLCBtZXNzYWdlOiBlcnJvci5tZXNzYWdlfSk7XHJcbiAgICB9XHJcbiAgICBsZXQgcmVzcG9uc2VUeXBlID0gZGV0ZXJtaW5lUmVzcG9uc2VUeXBlKGhhc0ZpbGVFeHRlbnNpb24sIGhlYWRlcnMpO1xyXG4gICAgaWYgKHJlc3BvbnNlVHlwZSAhPT0gU0VSVkUpIHtcclxuICAgICAgcmV0dXJuIGhhbmRsZVNob3dSZW5kZXIocmVxLCByZXMpO1xyXG4gICAgfVxyXG4gICAgLy8gaGFuZGxlIHNlcnZlIHJlcXVlc3RcclxuICAgIC8vIHNlbmQgZ29vZ2xlIGFuYWx5dGljc1xyXG4gICAgc2VuZEdBU2VydmVFdmVudChoZWFkZXJzLCBpcCwgb3JpZ2luYWxVcmwpO1xyXG4gICAgLy8gcGFyc2UgdGhlIGNsYWltXHJcbiAgICBsZXQgY2xhaW1OYW1lO1xyXG4gICAgdHJ5IHtcclxuICAgICAgKHtjbGFpbU5hbWV9ID0gbGJyeVVyaS5wYXJzZUNsYWltKHBhcmFtcy5jbGFpbSkpO1xyXG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcclxuICAgICAgcmV0dXJuIHJlcy5zdGF0dXMoNDAwKS5qc29uKHtzdWNjZXNzOiBmYWxzZSwgbWVzc2FnZTogZXJyb3IubWVzc2FnZX0pO1xyXG4gICAgfVxyXG4gICAgLy8gbG9nIHRoZSByZXF1ZXN0IGRhdGEgZm9yIGRlYnVnZ2luZ1xyXG4gICAgbG9nUmVxdWVzdERhdGEocmVzcG9uc2VUeXBlLCBjbGFpbU5hbWUsIG51bGwsIG51bGwpO1xyXG4gICAgLy8gZ2V0IHRoZSBjbGFpbSBJZCBhbmQgdGhlbiBzZXJ2ZSB0aGUgYXNzZXRcclxuICAgIGdldENsYWltSWRBbmRTZXJ2ZUFzc2V0KG51bGwsIG51bGwsIGNsYWltTmFtZSwgbnVsbCwgb3JpZ2luYWxVcmwsIGlwLCByZXMpO1xyXG4gIH07XHJcbn07XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IGNsYWltO1xyXG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9zZXJ2ZXIvcm91dGVzL2Fzc2V0L3NlcnZlQXNzZXRCeUNsYWltLmpzIiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwicmVhY3QtZG9tL3NlcnZlclwiKTtcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyBleHRlcm5hbCBcInJlYWN0LWRvbS9zZXJ2ZXJcIlxuLy8gbW9kdWxlIGlkID0gMTUwXG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIm1vZHVsZS5leHBvcnRzID0gKGhlbG1ldCwgaHRtbCwgcHJlbG9hZGVkU3RhdGUpID0+IHtcbiAgLy8gdGFrZSB0aGUgaHRtbCBhbmQgcHJlbG9hZGVkU3RhdGUgYW5kIHJldHVybiB0aGUgZnVsbCBwYWdlXG4gIHJldHVybiBgXG4gICAgPCFET0NUWVBFIGh0bWw+XG4gICAgPGh0bWwgbGFuZz1cImVuXCIgcHJlZml4PVwib2c6IGh0dHA6Ly9vZ3AubWUvbnMjIGZiOiBodHRwOi8vb2dwLm1lL25zL2ZiI1wiPlxuICAgICAgICA8aGVhZD5cbiAgICAgICAgICAgIDxtZXRhIGNoYXJzZXQ9XCJVVEYtOFwiPlxuICAgICAgICAgICAgPG1ldGEgbmFtZT1cInZpZXdwb3J0XCIgY29udGVudD1cIndpZHRoPWRldmljZS13aWR0aCwgaW5pdGlhbC1zY2FsZT0xLjAsIG1heGltdW0tc2NhbGU9MSwgdXNlci1zY2FsYWJsZT1ub1wiPlxuICAgICAgICAgICAgPG1ldGEgaHR0cC1lcXVpdj1cIlgtVUEtQ29tcGF0aWJsZVwiIGNvbnRlbnQ9XCJpZT1lZGdlXCI+XG4gICAgICAgICAgICA8IS0taGVsbWV0LS0+XG4gICAgICAgICAgICAke2hlbG1ldC50aXRsZS50b1N0cmluZygpfVxuICAgICAgICAgICAgJHtoZWxtZXQubWV0YS50b1N0cmluZygpfVxuICAgICAgICAgICAgJHtoZWxtZXQubGluay50b1N0cmluZygpfVxuICAgICAgICAgICAgPCEtLXN0eWxlIHNoZWV0cy0tPlxuICAgICAgICAgICAgPGxpbmsgcmVsPVwic3R5bGVzaGVldFwiIGhyZWY9XCIvYXNzZXRzL2Nzcy9yZXNldC5jc3NcIiB0eXBlPVwidGV4dC9jc3NcIj5cbiAgICAgICAgICAgIDxsaW5rIHJlbD1cInN0eWxlc2hlZXRcIiBocmVmPVwiL2Fzc2V0cy9jc3MvZ2VuZXJhbC5jc3NcIiB0eXBlPVwidGV4dC9jc3NcIj5cbiAgICAgICAgICAgIDxsaW5rIHJlbD1cInN0eWxlc2hlZXRcIiBocmVmPVwiL2Fzc2V0cy9jc3MvbWVkaWFRdWVyaWVzLmNzc1wiIHR5cGU9XCJ0ZXh0L2Nzc1wiPlxuICAgICAgICAgICAgPCEtLWdvb2dsZSBmb250LS0+XG4gICAgICAgICAgICA8bGluayBocmVmPVwiaHR0cHM6Ly9mb250cy5nb29nbGVhcGlzLmNvbS9jc3M/ZmFtaWx5PVJvYm90bzozMDBcIiByZWw9XCJzdHlsZXNoZWV0XCI+XG4gICAgICAgIDwvaGVhZD5cbiAgICAgICAgPGJvZHkgaWQ9XCJtYWluLWJvZHlcIj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJyb3cgcm93LS10YWxsIGZsZXgtY29udGFpbmVyLS1jb2x1bW5cIj5cbiAgICAgICAgICAgICAgICA8ZGl2IGlkPVwicmVhY3QtYXBwXCIgY2xhc3M9XCJyb3cgcm93LS10YWxsIGZsZXgtY29udGFpbmVyLS1jb2x1bW5cIj4ke2h0bWx9PC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDxzY3JpcHQ+XG4gICAgICAgICAgICAgICAgd2luZG93Ll9fUFJFTE9BREVEX1NUQVRFX18gPSAke0pTT04uc3RyaW5naWZ5KHByZWxvYWRlZFN0YXRlKS5yZXBsYWNlKC88L2csICdcXFxcXFx1MDAzYycpfVxuICAgICAgICAgICAgPC9zY3JpcHQ+XG4gICAgICAgICAgICA8c2NyaXB0IHNyYz1cIi9idW5kbGUvYnVuZGxlLmpzXCI+PC9zY3JpcHQ+XG4gICAgICAgIDwvYm9keT5cbiAgICA8L2h0bWw+XG4gIGA7XG59O1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vc2VydmVyL2hlbHBlcnMvcmVuZGVyRnVsbFBhZ2UuanMiLCJjb25zdCB7IHNlbmRHQVNlcnZlRXZlbnQgfSA9IHJlcXVpcmUoJ2hlbHBlcnMvZ29vZ2xlQW5hbHl0aWNzJyk7XHJcbmNvbnN0IHsgZGV0ZXJtaW5lUmVzcG9uc2VUeXBlLCBmbGlwQ2xhaW1OYW1lQW5kSWRGb3JCYWNrd2FyZHNDb21wYXRpYmlsaXR5LCBsb2dSZXF1ZXN0RGF0YSwgZ2V0Q2xhaW1JZEFuZFNlcnZlQXNzZXQgfSA9IHJlcXVpcmUoJ2hlbHBlcnMvc2VydmVIZWxwZXJzLmpzJyk7XHJcbmNvbnN0IGxicnlVcmkgPSByZXF1aXJlKCdoZWxwZXJzL2xicnlVcmkuanMnKTtcclxuY29uc3QgaGFuZGxlU2hvd1JlbmRlciA9IHJlcXVpcmUoJ2hlbHBlcnMvaGFuZGxlU2hvd1JlbmRlci5qc3gnKTtcclxuXHJcbmNvbnN0IFNFUlZFID0gJ1NFUlZFJztcclxuXHJcbi8qXHJcblxyXG4gIHJvdXRlIHRvIHNlcnZlIGFuIGFzc2V0IG9yIHRoZSByZWFjdCBhcHAgdmlhIHRoZSBjbGFpbSBuYW1lIGFuZCBhbiBpZGVudGlmaWVyXHJcblxyXG4qL1xyXG5cclxuY29uc3QgaWRlbnRpZmllckNsYWltID0gKCkgPT4ge1xyXG4gIHJldHVybiAocmVxLCByZXMpID0+IHtcclxuICAgIGNvbnN0IHsgaGVhZGVycywgaXAsIG9yaWdpbmFsVXJsLCBwYXJhbXMgfSA9IHJlcTtcclxuICAgIC8vIGRlY2lkZSBpZiB0aGlzIGlzIGEgc2hvdyByZXF1ZXN0XHJcbiAgICBsZXQgaGFzRmlsZUV4dGVuc2lvbjtcclxuICAgIHRyeSB7XHJcbiAgICAgICh7IGhhc0ZpbGVFeHRlbnNpb24gfSA9IGxicnlVcmkucGFyc2VNb2RpZmllcihwYXJhbXMuY2xhaW0pKTtcclxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XHJcbiAgICAgIHJldHVybiByZXMuc3RhdHVzKDQwMCkuanNvbih7c3VjY2VzczogZmFsc2UsIG1lc3NhZ2U6IGVycm9yLm1lc3NhZ2V9KTtcclxuICAgIH1cclxuICAgIGxldCByZXNwb25zZVR5cGUgPSBkZXRlcm1pbmVSZXNwb25zZVR5cGUoaGFzRmlsZUV4dGVuc2lvbiwgaGVhZGVycyk7XHJcbiAgICBpZiAocmVzcG9uc2VUeXBlICE9PSBTRVJWRSkge1xyXG4gICAgICByZXR1cm4gaGFuZGxlU2hvd1JlbmRlcihyZXEsIHJlcyk7XHJcbiAgICB9XHJcbiAgICAvLyBoYW5kbGUgc2VydmUgcmVxdWVzdFxyXG4gICAgLy8gc2VuZCBnb29nbGUgYW5hbHl0aWNzXHJcbiAgICBzZW5kR0FTZXJ2ZUV2ZW50KGhlYWRlcnMsIGlwLCBvcmlnaW5hbFVybCk7XHJcbiAgICAvLyBwYXJzZSB0aGUgY2xhaW1cclxuICAgIGxldCBjbGFpbU5hbWU7XHJcbiAgICB0cnkge1xyXG4gICAgICAoeyBjbGFpbU5hbWUgfSA9IGxicnlVcmkucGFyc2VDbGFpbShwYXJhbXMuY2xhaW0pKTtcclxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XHJcbiAgICAgIHJldHVybiByZXMuc3RhdHVzKDQwMCkuanNvbih7c3VjY2VzczogZmFsc2UsIG1lc3NhZ2U6IGVycm9yLm1lc3NhZ2V9KTtcclxuICAgIH1cclxuICAgIC8vIHBhcnNlIHRoZSBpZGVudGlmaWVyXHJcbiAgICBsZXQgaXNDaGFubmVsLCBjaGFubmVsTmFtZSwgY2hhbm5lbENsYWltSWQsIGNsYWltSWQ7XHJcbiAgICB0cnkge1xyXG4gICAgICAoeyBpc0NoYW5uZWwsIGNoYW5uZWxOYW1lLCBjaGFubmVsQ2xhaW1JZCwgY2xhaW1JZCB9ID0gbGJyeVVyaS5wYXJzZUlkZW50aWZpZXIocGFyYW1zLmlkZW50aWZpZXIpKTtcclxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XHJcbiAgICAgIHJldHVybiByZXMuc3RhdHVzKDQwMCkuanNvbih7c3VjY2VzczogZmFsc2UsIG1lc3NhZ2U6IGVycm9yLm1lc3NhZ2V9KTtcclxuICAgIH1cclxuICAgIGlmICghaXNDaGFubmVsKSB7XHJcbiAgICAgIFtjbGFpbUlkLCBjbGFpbU5hbWVdID0gZmxpcENsYWltTmFtZUFuZElkRm9yQmFja3dhcmRzQ29tcGF0aWJpbGl0eShjbGFpbUlkLCBjbGFpbU5hbWUpO1xyXG4gICAgfVxyXG4gICAgLy8gbG9nIHRoZSByZXF1ZXN0IGRhdGEgZm9yIGRlYnVnZ2luZ1xyXG4gICAgbG9nUmVxdWVzdERhdGEocmVzcG9uc2VUeXBlLCBjbGFpbU5hbWUsIGNoYW5uZWxOYW1lLCBjbGFpbUlkKTtcclxuICAgIC8vIGdldCB0aGUgY2xhaW0gSWQgYW5kIHRoZW4gc2VydmUgdGhlIGFzc2V0XHJcbiAgICBnZXRDbGFpbUlkQW5kU2VydmVBc3NldChjaGFubmVsTmFtZSwgY2hhbm5lbENsYWltSWQsIGNsYWltTmFtZSwgY2xhaW1JZCwgb3JpZ2luYWxVcmwsIGlwLCByZXMpO1xyXG4gIH07XHJcbn07XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IGlkZW50aWZpZXJDbGFpbTtcclxuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vc2VydmVyL3JvdXRlcy9hc3NldC9zZXJ2ZUFzc2V0QnlJZGVudGlmaWVyQW5kQ2xhaW0uanMiLCJjb25zdCBzaWdudXAgPSByZXF1aXJlKCcuL3NpZ251cCcpO1xuY29uc3QgbG9naW4gPSByZXF1aXJlKCcuL2xvZ2luJyk7XG5jb25zdCBsb2dvdXQgPSByZXF1aXJlKCcuL2xvZ291dCcpO1xuY29uc3QgdXNlciA9IHJlcXVpcmUoJy4vdXNlcicpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgc2lnbnVwLFxuICBsb2dpbixcbiAgbG9nb3V0LFxuICB1c2VyLFxufTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL3NlcnZlci9yb3V0ZXMvYXV0aC9pbmRleC5qcyIsImNvbnN0IHNpZ251cCA9ICgpID0+IHtcclxuICByZXR1cm4gKHJlcSwgcmVzKSA9PiB7XHJcbiAgICByZXMuc3RhdHVzKDIwMCkuanNvbih7XHJcbiAgICAgIHN1Y2Nlc3MgICAgICAgOiB0cnVlLFxyXG4gICAgICBjaGFubmVsTmFtZSAgIDogcmVxLnVzZXIuY2hhbm5lbE5hbWUsXHJcbiAgICAgIGNoYW5uZWxDbGFpbUlkOiByZXEudXNlci5jaGFubmVsQ2xhaW1JZCxcclxuICAgICAgc2hvcnRDaGFubmVsSWQ6IHJlcS51c2VyLnNob3J0Q2hhbm5lbElkLFxyXG4gICAgfSk7XHJcbiAgfTtcclxufTtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gc2lnbnVwO1xyXG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9zZXJ2ZXIvcm91dGVzL2F1dGgvc2lnbnVwLmpzIiwiY29uc3QgbG9naW4gPSAocGFzc3BvcnQpID0+IHtcclxuICByZXR1cm4gKHJlcSwgcmVzLCBuZXh0KSA9PiB7XHJcbiAgICBwYXNzcG9ydC5hdXRoZW50aWNhdGUoJ2xvY2FsLWxvZ2luJywgKGVyciwgdXNlciwgaW5mbykgPT4ge1xyXG4gICAgICBpZiAoZXJyKSB7XHJcbiAgICAgICAgcmV0dXJuIG5leHQoZXJyKTtcclxuICAgICAgfVxyXG4gICAgICBpZiAoIXVzZXIpIHtcclxuICAgICAgICByZXR1cm4gcmVzLnN0YXR1cyg0MDApLmpzb24oe1xyXG4gICAgICAgICAgc3VjY2VzczogZmFsc2UsXHJcbiAgICAgICAgICBtZXNzYWdlOiBpbmZvLm1lc3NhZ2UsXHJcbiAgICAgICAgfSk7XHJcbiAgICAgIH1cclxuICAgICAgcmVxLmxvZ0luKHVzZXIsIChlcnIpID0+IHtcclxuICAgICAgICBpZiAoZXJyKSB7XHJcbiAgICAgICAgICByZXR1cm4gbmV4dChlcnIpO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gcmVzLnN0YXR1cygyMDApLmpzb24oe1xyXG4gICAgICAgICAgc3VjY2VzcyAgICAgICA6IHRydWUsXHJcbiAgICAgICAgICBjaGFubmVsTmFtZSAgIDogcmVxLnVzZXIuY2hhbm5lbE5hbWUsXHJcbiAgICAgICAgICBjaGFubmVsQ2xhaW1JZDogcmVxLnVzZXIuY2hhbm5lbENsYWltSWQsXHJcbiAgICAgICAgICBzaG9ydENoYW5uZWxJZDogcmVxLnVzZXIuc2hvcnRDaGFubmVsSWQsXHJcbiAgICAgICAgfSk7XHJcbiAgICAgIH0pO1xyXG4gICAgfSkocmVxLCByZXMsIG5leHQpO1xyXG4gIH07XHJcbn07XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IGxvZ2luO1xyXG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9zZXJ2ZXIvcm91dGVzL2F1dGgvbG9naW4uanMiLCJjb25zdCBsb2dvdXQgPSAoKSA9PiB7XHJcbiAgcmV0dXJuIChyZXEsIHJlcykgPT4ge1xyXG4gICAgcmVxLmxvZ291dCgpO1xyXG4gICAgcmVzLnN0YXR1cygyMDApLmpzb24oe3N1Y2Nlc3M6IHRydWUsIG1lc3NhZ2U6ICd5b3Ugc3VjY2Vzc2Z1bGx5IGxvZ2dlZCBvdXQnfSk7XHJcbiAgfTtcclxufTtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gbG9nb3V0O1xyXG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9zZXJ2ZXIvcm91dGVzL2F1dGgvbG9nb3V0LmpzIiwiY29uc3QgdXNlciA9ICgpID0+IHtcclxuICByZXR1cm4gKHJlcSwgcmVzKSA9PiB7XHJcbiAgICBpZiAocmVxLnVzZXIpIHtcclxuICAgICAgcmVzLnN0YXR1cygyMDApLmpzb24oe3N1Y2Nlc3M6IHRydWUsIGRhdGE6IHJlcS51c2VyfSk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICByZXMuc3RhdHVzKDQwMSkuanNvbih7c3VjY2VzczogZmFsc2UsIG1lc3NhZ2U6ICd1c2VyIGlzIG5vdCBsb2dnZWQgaW4nfSk7XHJcbiAgICB9XHJcbiAgfTtcclxufTtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gdXNlcjtcclxuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vc2VydmVyL3JvdXRlcy9hdXRoL3VzZXIuanMiLCJjb25zdCBsb2dnZXIgPSByZXF1aXJlKCd3aW5zdG9uJyk7XG5cbmZ1bmN0aW9uIExvZ2dlckNvbmZpZyAoKSB7XG4gIHRoaXMubG9nTGV2ZWwgPSAnZGVidWcnO1xuICB0aGlzLmNvbmZpZ3VyZSA9IChjb25maWcpID0+IHtcbiAgICBpZiAoIWNvbmZpZykge1xuICAgICAgcmV0dXJuIGNvbnNvbGUubG9nKCdObyBsb2dnZXIgY29uZmlnIHJlY2VpdmVkLicpO1xuICAgIH1cbiAgICBjb25zb2xlLmxvZygnY29uZmlndXJpbmcgd2luc3RvbiBsb2dnZXIuLi4nKTtcbiAgICAvLyB1cGRhdGUgdmFsdWVzIHdpdGggbG9jYWwgY29uZmlnIHBhcmFtc1xuICAgIGNvbnN0IHtsb2dMZXZlbH0gPSBjb25maWc7XG4gICAgdGhpcy5sb2dMZXZlbCA9IGxvZ0xldmVsO1xuICAgIC8vIGNvbmZpZ3VyZSB0aGUgd2luc3RvbiBsb2dnZXJcbiAgICBsb2dnZXIuY29uZmlndXJlKHtcbiAgICAgIHRyYW5zcG9ydHM6IFtcbiAgICAgICAgbmV3IChsb2dnZXIudHJhbnNwb3J0cy5Db25zb2xlKSh7XG4gICAgICAgICAgbGV2ZWwgICAgICAgICAgICAgICAgICAgICAgICAgIDogdGhpcy5sb2dMZXZlbCxcbiAgICAgICAgICB0aW1lc3RhbXAgICAgICAgICAgICAgICAgICAgICAgOiBmYWxzZSxcbiAgICAgICAgICBjb2xvcml6ZSAgICAgICAgICAgICAgICAgICAgICAgOiB0cnVlLFxuICAgICAgICAgIHByZXR0eVByaW50ICAgICAgICAgICAgICAgICAgICA6IHRydWUsXG4gICAgICAgICAgaGFuZGxlRXhjZXB0aW9ucyAgICAgICAgICAgICAgIDogdHJ1ZSxcbiAgICAgICAgICBodW1hblJlYWRhYmxlVW5oYW5kbGVkRXhjZXB0aW9uOiB0cnVlLFxuICAgICAgICB9KSxcbiAgICAgIF0sXG4gICAgfSk7XG4gICAgLy8gdGVzdCBhbGwgdGhlIGxvZyBsZXZlbHNcbiAgICBjb25zb2xlLmxvZygndGVzdGluZyB3aW5zdG9uIGxvZyBsZXZlbHMuLi4nKTtcbiAgICBsb2dnZXIuZXJyb3IoJ0xldmVsIDAnKTtcbiAgICBsb2dnZXIud2FybignTGV2ZWwgMScpO1xuICAgIGxvZ2dlci5pbmZvKCdMZXZlbCAyJyk7XG4gICAgbG9nZ2VyLnZlcmJvc2UoJ0xldmVsIDMnKTtcbiAgICBsb2dnZXIuZGVidWcoJ0xldmVsIDQnKTtcbiAgICBsb2dnZXIuc2lsbHkoJ0xldmVsIDUnKTtcbiAgfTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gbmV3IExvZ2dlckNvbmZpZygpO1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vY29uZmlnL2xvZ2dlckNvbmZpZy5qcyIsImNvbnN0IHdpbnN0b25TbGFja1dlYkhvb2sgPSByZXF1aXJlKCd3aW5zdG9uLXNsYWNrLXdlYmhvb2snKS5TbGFja1dlYkhvb2s7XG5jb25zdCB3aW5zdG9uID0gcmVxdWlyZSgnd2luc3RvbicpO1xuXG5mdW5jdGlvbiBTbGFja0NvbmZpZyAoKSB7XG4gIHRoaXMuc2xhY2tXZWJIb29rICAgICAgPSAnZGVmYXVsdCc7XG4gIHRoaXMuc2xhY2tFcnJvckNoYW5uZWwgPSAnZGVmYXVsdCc7XG4gIHRoaXMuc2xhY2tJbmZvQ2hhbm5lbCAgPSAnZGVmYXVsdCc7XG4gIHRoaXMuY29uZmlndXJlID0gKGNvbmZpZykgPT4ge1xuICAgIGlmICghY29uZmlnKSB7XG4gICAgICByZXR1cm4gY29uc29sZS5sb2coJ25vIHNsYWNrIGNvbmZpZyByZWNlaXZlZCcpO1xuICAgIH1cbiAgICAvLyB1cGRhdGUgdmFyaWFibGVzXG4gICAgY29uc29sZS5sb2coJ2NvbmZpZ3VyaW5nIHNsYWNrIGxvZ2dlci4uLicpO1xuICAgIGNvbnN0IHtzbGFja1dlYkhvb2ssIHNsYWNrRXJyb3JDaGFubmVsLCBzbGFja0luZm9DaGFubmVsfSA9IGNvbmZpZztcbiAgICB0aGlzLnNsYWNrV2ViSG9vayA9IHNsYWNrV2ViSG9vaztcbiAgICB0aGlzLnNsYWNrRXJyb3JDaGFubmVsID0gc2xhY2tFcnJvckNoYW5uZWw7XG4gICAgdGhpcy5zbGFja0luZm9DaGFubmVsID0gc2xhY2tJbmZvQ2hhbm5lbDtcbiAgICAvLyB1cGRhdGUgc2xhY2sgd2ViaG9vayBzZXR0aW5nc1xuICAgIGlmICh0aGlzLnNsYWNrV2ViSG9vaykge1xuICAgICAgLy8gYWRkIGEgdHJhbnNwb3J0IGZvciBlcnJvcnMgdG8gc2xhY2tcbiAgICAgIGlmICh0aGlzLnNsYWNrRXJyb3JDaGFubmVsKSB7XG4gICAgICAgIHdpbnN0b24uYWRkKHdpbnN0b25TbGFja1dlYkhvb2ssIHtcbiAgICAgICAgICBuYW1lICAgICAgOiAnc2xhY2stZXJyb3JzLXRyYW5zcG9ydCcsXG4gICAgICAgICAgbGV2ZWwgICAgIDogJ3dhcm4nLFxuICAgICAgICAgIHdlYmhvb2tVcmw6IHRoaXMuc2xhY2tXZWJIb29rLFxuICAgICAgICAgIGNoYW5uZWwgICA6IHRoaXMuc2xhY2tFcnJvckNoYW5uZWwsXG4gICAgICAgICAgdXNlcm5hbWUgIDogJ3NwZWUuY2gnLFxuICAgICAgICAgIGljb25FbW9qaSA6ICc6ZmFjZV93aXRoX2hlYWRfYmFuZGFnZTonLFxuICAgICAgICB9KTtcbiAgICAgIH07XG4gICAgICBpZiAoc2xhY2tJbmZvQ2hhbm5lbCkge1xuICAgICAgICB3aW5zdG9uLmFkZCh3aW5zdG9uU2xhY2tXZWJIb29rLCB7XG4gICAgICAgICAgbmFtZSAgICAgIDogJ3NsYWNrLWluZm8tdHJhbnNwb3J0JyxcbiAgICAgICAgICBsZXZlbCAgICAgOiAnaW5mbycsXG4gICAgICAgICAgd2ViaG9va1VybDogdGhpcy5zbGFja1dlYkhvb2ssXG4gICAgICAgICAgY2hhbm5lbCAgIDogdGhpcy5zbGFja0luZm9DaGFubmVsLFxuICAgICAgICAgIHVzZXJuYW1lICA6ICdzcGVlLmNoJyxcbiAgICAgICAgICBpY29uRW1vamkgOiAnOm5lcmRfZmFjZTonLFxuICAgICAgICB9KTtcbiAgICAgIH07XG4gICAgICAvLyBzZW5kIHRlc3QgbWVzc2FnZXNcbiAgICAgIGNvbnNvbGUubG9nKCd0ZXN0aW5nIHNsYWNrIGxvZ2dlci4uLicpO1xuICAgICAgd2luc3Rvbi5lcnJvcignU2xhY2sgXCJlcnJvclwiIGxvZ2dpbmcgaXMgb25saW5lLicpO1xuICAgICAgd2luc3Rvbi5pbmZvKCdTbGFjayBcImluZm9cIiBsb2dnaW5nIGlzIG9ubGluZS4nKTtcbiAgICB9IGVsc2Uge1xuICAgICAgd2luc3Rvbi53YXJuKCdTbGFjayBsb2dnaW5nIGlzIG5vdCBlbmFibGVkIGJlY2F1c2Ugbm8gc2xhY2tXZWJIb29rIGNvbmZpZyB2YXIgcHJvdmlkZWQuJyk7XG4gICAgfVxuICB9O1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSBuZXcgU2xhY2tDb25maWcoKTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL2NvbmZpZy9zbGFja0NvbmZpZy5qcyIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcIndpbnN0b24tc2xhY2std2ViaG9va1wiKTtcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyBleHRlcm5hbCBcIndpbnN0b24tc2xhY2std2ViaG9va1wiXG4vLyBtb2R1bGUgaWQgPSAxNjBcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiY29uc3QgcGFzc3BvcnQgPSByZXF1aXJlKCdwYXNzcG9ydCcpO1xyXG5jb25zdCBsb2NhbExvZ2luU3RyYXRlZ3kgPSByZXF1aXJlKCcuL2xvY2FsLWxvZ2luLmpzJyk7XHJcbmNvbnN0IGxvY2FsU2lnbnVwU3RyYXRlZ3kgPSByZXF1aXJlKCcuL2xvY2FsLXNpZ251cC5qcycpO1xyXG5jb25zdCB7IHNlcmlhbGl6ZVNwZWVjaFVzZXIsIGRlc2VyaWFsaXplU3BlZWNoVXNlciB9ID0gcmVxdWlyZSgnaGVscGVycy9hdXRoSGVscGVycy5qcycpO1xyXG5cclxucGFzc3BvcnQuZGVzZXJpYWxpemVVc2VyKGRlc2VyaWFsaXplU3BlZWNoVXNlcik7XHJcbnBhc3Nwb3J0LnNlcmlhbGl6ZVVzZXIoc2VyaWFsaXplU3BlZWNoVXNlcik7XHJcbnBhc3Nwb3J0LnVzZSgnbG9jYWwtbG9naW4nLCBsb2NhbExvZ2luU3RyYXRlZ3kpO1xyXG5wYXNzcG9ydC51c2UoJ2xvY2FsLXNpZ251cCcsIGxvY2FsU2lnbnVwU3RyYXRlZ3kpO1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBwYXNzcG9ydDtcclxuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vc2VydmVyL3Bhc3Nwb3J0L2luZGV4LmpzIiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwicGFzc3BvcnRcIik7XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gZXh0ZXJuYWwgXCJwYXNzcG9ydFwiXG4vLyBtb2R1bGUgaWQgPSAxNjJcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiY29uc3QgUGFzc3BvcnRMb2NhbFN0cmF0ZWd5ID0gcmVxdWlyZSgncGFzc3BvcnQtbG9jYWwnKS5TdHJhdGVneTtcbmNvbnN0IGxvZ2dlciA9IHJlcXVpcmUoJ3dpbnN0b24nKTtcbmNvbnN0IHsgZGIgfSA9IHJlcXVpcmUoJ215c3FsQ29uZmlnJyk7XG5cbmNvbnN0IHJldHVyblVzZXJBbmRDaGFubmVsSW5mbyA9ICh1c2VySW5zdGFuY2UpID0+IHtcbiAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICBsZXQgdXNlckluZm8gPSB7fTtcbiAgICB1c2VySW5mb1snaWQnXSA9IHVzZXJJbnN0YW5jZS5pZDtcbiAgICB1c2VySW5mb1sndXNlck5hbWUnXSA9IHVzZXJJbnN0YW5jZS51c2VyTmFtZTtcbiAgICB1c2VySW5zdGFuY2VcbiAgICAgIC5nZXRDaGFubmVsKClcbiAgICAgIC50aGVuKCh7Y2hhbm5lbE5hbWUsIGNoYW5uZWxDbGFpbUlkfSkgPT4ge1xuICAgICAgICB1c2VySW5mb1snY2hhbm5lbE5hbWUnXSA9IGNoYW5uZWxOYW1lO1xuICAgICAgICB1c2VySW5mb1snY2hhbm5lbENsYWltSWQnXSA9IGNoYW5uZWxDbGFpbUlkO1xuICAgICAgICByZXR1cm4gZGIuQ2VydGlmaWNhdGUuZ2V0U2hvcnRDaGFubmVsSWRGcm9tTG9uZ0NoYW5uZWxJZChjaGFubmVsQ2xhaW1JZCwgY2hhbm5lbE5hbWUpO1xuICAgICAgfSlcbiAgICAgIC50aGVuKHNob3J0Q2hhbm5lbElkID0+IHtcbiAgICAgICAgdXNlckluZm9bJ3Nob3J0Q2hhbm5lbElkJ10gPSBzaG9ydENoYW5uZWxJZDtcbiAgICAgICAgcmVzb2x2ZSh1c2VySW5mbyk7XG4gICAgICB9KVxuICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgIH0pO1xuICB9KTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gbmV3IFBhc3Nwb3J0TG9jYWxTdHJhdGVneShcbiAge1xuICAgIHVzZXJuYW1lRmllbGQ6ICd1c2VybmFtZScsXG4gICAgcGFzc3dvcmRGaWVsZDogJ3Bhc3N3b3JkJyxcbiAgfSxcbiAgKHVzZXJuYW1lLCBwYXNzd29yZCwgZG9uZSkgPT4ge1xuICAgIHJldHVybiBkYi5Vc2VyXG4gICAgICAuZmluZE9uZSh7XG4gICAgICAgIHdoZXJlOiB7dXNlck5hbWU6IHVzZXJuYW1lfSxcbiAgICAgIH0pXG4gICAgICAudGhlbih1c2VyID0+IHtcbiAgICAgICAgaWYgKCF1c2VyKSB7XG4gICAgICAgICAgbG9nZ2VyLmRlYnVnKCdubyB1c2VyIGZvdW5kJyk7XG4gICAgICAgICAgcmV0dXJuIGRvbmUobnVsbCwgZmFsc2UsIHttZXNzYWdlOiAnSW5jb3JyZWN0IHVzZXJuYW1lIG9yIHBhc3N3b3JkJ30pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB1c2VyLmNvbXBhcmVQYXNzd29yZChwYXNzd29yZClcbiAgICAgICAgICAudGhlbihpc01hdGNoID0+IHtcbiAgICAgICAgICAgIGlmICghaXNNYXRjaCkge1xuICAgICAgICAgICAgICBsb2dnZXIuZGVidWcoJ2luY29ycmVjdCBwYXNzd29yZCcpO1xuICAgICAgICAgICAgICByZXR1cm4gZG9uZShudWxsLCBmYWxzZSwge21lc3NhZ2U6ICdJbmNvcnJlY3QgdXNlcm5hbWUgb3IgcGFzc3dvcmQnfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBsb2dnZXIuZGVidWcoJ1Bhc3N3b3JkIHdhcyBhIG1hdGNoLCByZXR1cm5pbmcgVXNlcicpO1xuICAgICAgICAgICAgcmV0dXJuIHJldHVyblVzZXJBbmRDaGFubmVsSW5mbyh1c2VyKVxuICAgICAgICAgICAgICAudGhlbih1c2VySW5mbyA9PiB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGRvbmUobnVsbCwgdXNlckluZm8pO1xuICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgIHJldHVybiBlcnJvcjtcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfSlcbiAgICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIGVycm9yO1xuICAgICAgICAgIH0pO1xuICAgICAgfSlcbiAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgIHJldHVybiBkb25lKGVycm9yKTtcbiAgICAgIH0pO1xuICB9LFxuKTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL3NlcnZlci9wYXNzcG9ydC9sb2NhbC1sb2dpbi5qcyIsImNvbnN0IFBhc3Nwb3J0TG9jYWxTdHJhdGVneSA9IHJlcXVpcmUoJ3Bhc3Nwb3J0LWxvY2FsJykuU3RyYXRlZ3k7XG5jb25zdCBsYnJ5QXBpID0gcmVxdWlyZSgnLi4vaGVscGVycy9sYnJ5QXBpLmpzJyk7XG5jb25zdCBsb2dnZXIgPSByZXF1aXJlKCd3aW5zdG9uJyk7XG5jb25zdCB7IGRiIH0gPSByZXF1aXJlKCdteXNxbENvbmZpZycpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IG5ldyBQYXNzcG9ydExvY2FsU3RyYXRlZ3koXG4gIHtcbiAgICB1c2VybmFtZUZpZWxkOiAndXNlcm5hbWUnLFxuICAgIHBhc3N3b3JkRmllbGQ6ICdwYXNzd29yZCcsXG4gIH0sXG4gICh1c2VybmFtZSwgcGFzc3dvcmQsIGRvbmUpID0+IHtcbiAgICBsb2dnZXIudmVyYm9zZShgbmV3IGNoYW5uZWwgc2lnbnVwIHJlcXVlc3QuIHVzZXI6ICR7dXNlcm5hbWV9IHBhc3M6ICR7cGFzc3dvcmR9IC5gKTtcbiAgICBsZXQgdXNlckluZm8gPSB7fTtcbiAgICAvLyBzZXJ2ZXItc2lkZSB2YWxpZGF0b24gb2YgaW5wdXRzICh1c2VybmFtZSwgcGFzc3dvcmQpXG5cbiAgICAvLyBjcmVhdGUgdGhlIGNoYW5uZWwgYW5kIHJldHJpZXZlIHRoZSBtZXRhZGF0YVxuICAgIHJldHVybiBsYnJ5QXBpLmNyZWF0ZUNoYW5uZWwoYEAke3VzZXJuYW1lfWApXG4gICAgICAudGhlbih0eCA9PiB7XG4gICAgICAgIC8vIGNyZWF0ZSB1c2VyIHJlY29yZFxuICAgICAgICBjb25zdCB1c2VyRGF0YSA9IHtcbiAgICAgICAgICB1c2VyTmFtZTogdXNlcm5hbWUsXG4gICAgICAgICAgcGFzc3dvcmQ6IHBhc3N3b3JkLFxuICAgICAgICB9O1xuICAgICAgICBsb2dnZXIudmVyYm9zZSgndXNlckRhdGEgPicsIHVzZXJEYXRhKTtcbiAgICAgICAgLy8gY3JlYXRlIHVzZXIgcmVjb3JkXG4gICAgICAgIGNvbnN0IGNoYW5uZWxEYXRhID0ge1xuICAgICAgICAgIGNoYW5uZWxOYW1lICAgOiBgQCR7dXNlcm5hbWV9YCxcbiAgICAgICAgICBjaGFubmVsQ2xhaW1JZDogdHguY2xhaW1faWQsXG4gICAgICAgIH07XG4gICAgICAgIGxvZ2dlci52ZXJib3NlKCdjaGFubmVsRGF0YSA+JywgY2hhbm5lbERhdGEpO1xuICAgICAgICAvLyBjcmVhdGUgY2VydGlmaWNhdGUgcmVjb3JkXG4gICAgICAgIGNvbnN0IGNlcnRpZmljYXRlRGF0YSA9IHtcbiAgICAgICAgICBjbGFpbUlkOiB0eC5jbGFpbV9pZCxcbiAgICAgICAgICBuYW1lICAgOiBgQCR7dXNlcm5hbWV9YCxcbiAgICAgICAgICAvLyBhZGRyZXNzLFxuICAgICAgICB9O1xuICAgICAgICBsb2dnZXIudmVyYm9zZSgnY2VydGlmaWNhdGVEYXRhID4nLCBjZXJ0aWZpY2F0ZURhdGEpO1xuICAgICAgICAvLyBzYXZlIHVzZXIgYW5kIGNlcnRpZmljYXRlIHRvIGRiXG4gICAgICAgIHJldHVybiBQcm9taXNlLmFsbChbZGIuVXNlci5jcmVhdGUodXNlckRhdGEpLCBkYi5DaGFubmVsLmNyZWF0ZShjaGFubmVsRGF0YSksIGRiLkNlcnRpZmljYXRlLmNyZWF0ZShjZXJ0aWZpY2F0ZURhdGEpXSk7XG4gICAgICB9KVxuICAgICAgLnRoZW4oKFtuZXdVc2VyLCBuZXdDaGFubmVsLCBuZXdDZXJ0aWZpY2F0ZV0pID0+IHtcbiAgICAgICAgbG9nZ2VyLnZlcmJvc2UoJ3VzZXIgYW5kIGNlcnRpZmljYXRlIHN1Y2Nlc3NmdWxseSBjcmVhdGVkJyk7XG4gICAgICAgIC8vIHN0b3JlIHRoZSByZWxldmFudCBuZXdVc2VyIGluZm8gdG8gYmUgcGFzc2VkIGJhY2sgZm9yIHJlcS5Vc2VyXG4gICAgICAgIHVzZXJJbmZvWydpZCddID0gbmV3VXNlci5pZDtcbiAgICAgICAgdXNlckluZm9bJ3VzZXJOYW1lJ10gPSBuZXdVc2VyLnVzZXJOYW1lO1xuICAgICAgICB1c2VySW5mb1snY2hhbm5lbE5hbWUnXSA9IG5ld0NoYW5uZWwuY2hhbm5lbE5hbWU7XG4gICAgICAgIHVzZXJJbmZvWydjaGFubmVsQ2xhaW1JZCddID0gbmV3Q2hhbm5lbC5jaGFubmVsQ2xhaW1JZDtcbiAgICAgICAgLy8gYXNzb2NpYXRlIHRoZSBpbnN0YW5jZXNcbiAgICAgICAgcmV0dXJuIFByb21pc2UuYWxsKFtuZXdDZXJ0aWZpY2F0ZS5zZXRDaGFubmVsKG5ld0NoYW5uZWwpLCBuZXdDaGFubmVsLnNldFVzZXIobmV3VXNlcildKTtcbiAgICAgIH0pXG4gICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgIGxvZ2dlci52ZXJib3NlKCd1c2VyIGFuZCBjZXJ0aWZpY2F0ZSBzdWNjZXNzZnVsbHkgYXNzb2NpYXRlZCcpO1xuICAgICAgICByZXR1cm4gZGIuQ2VydGlmaWNhdGUuZ2V0U2hvcnRDaGFubmVsSWRGcm9tTG9uZ0NoYW5uZWxJZCh1c2VySW5mby5jaGFubmVsQ2xhaW1JZCwgdXNlckluZm8uY2hhbm5lbE5hbWUpO1xuICAgICAgfSlcbiAgICAgIC50aGVuKHNob3J0Q2hhbm5lbElkID0+IHtcbiAgICAgICAgdXNlckluZm9bJ3Nob3J0Q2hhbm5lbElkJ10gPSBzaG9ydENoYW5uZWxJZDtcbiAgICAgICAgcmV0dXJuIGRvbmUobnVsbCwgdXNlckluZm8pO1xuICAgICAgfSlcbiAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgIGxvZ2dlci5lcnJvcignc2lnbnVwIGVycm9yJywgZXJyb3IpO1xuICAgICAgICByZXR1cm4gZG9uZShlcnJvcik7XG4gICAgICB9KTtcbiAgfVxuKTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL3NlcnZlci9wYXNzcG9ydC9sb2NhbC1zaWdudXAuanMiLCJtb2R1bGUuZXhwb3J0cyA9IHtcbiAgc2VyaWFsaXplU3BlZWNoVXNlciAodXNlciwgZG9uZSkgeyAgLy8gcmV0dXJucyB1c2VyIGRhdGEgdG8gYmUgc2VyaWFsaXplZCBpbnRvIHNlc3Npb25cbiAgICBjb25zb2xlLmxvZygnc2VyaWFsaXppbmcgdXNlcicpO1xuICAgIGRvbmUobnVsbCwgdXNlcik7XG4gIH0sXG4gIGRlc2VyaWFsaXplU3BlZWNoVXNlciAodXNlciwgZG9uZSkgeyAgLy8gZGVzZXJpYWxpemVzIHNlc3Npb24gYW5kIHBvcHVsYXRlcyBhZGRpdGlvbmFsIGluZm8gdG8gcmVxLnVzZXJcbiAgICBjb25zb2xlLmxvZygnZGVzZXJpYWxpemluZyB1c2VyJyk7XG4gICAgZG9uZShudWxsLCB1c2VyKTtcbiAgfSxcbn07XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9zZXJ2ZXIvaGVscGVycy9hdXRoSGVscGVycy5qcyIsImNvbnN0IENlcnRpZmljYXRlID0gcmVxdWlyZSgnbW9kZWxzL2NlcnRpZmljYXRlLmpzJyk7XHJcbmNvbnN0IENoYW5uZWwgPSByZXF1aXJlKCdtb2RlbHMvY2hhbm5lbC5qcycpO1xyXG5jb25zdCBDbGFpbSA9IHJlcXVpcmUoJ21vZGVscy9jbGFpbS5qcycpO1xyXG5jb25zdCBGaWxlID0gcmVxdWlyZSgnbW9kZWxzL2ZpbGUuanMnKTtcclxuY29uc3QgUmVxdWVzdCA9IHJlcXVpcmUoJ21vZGVscy9yZXF1ZXN0LmpzJyk7XHJcbmNvbnN0IFVzZXIgPSByZXF1aXJlKCdtb2RlbHMvdXNlci5qcycpO1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSB7XHJcbiAgQ2VydGlmaWNhdGUsXHJcbiAgQ2hhbm5lbCxcclxuICBDbGFpbSxcclxuICBGaWxlLFxyXG4gIFJlcXVlc3QsXHJcbiAgVXNlcixcclxufVxyXG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9zZXJ2ZXIvbW9kZWxzL2luZGV4LmpzIiwiY29uc3QgbG9nZ2VyID0gcmVxdWlyZSgnd2luc3RvbicpO1xuY29uc3QgeyByZXR1cm5TaG9ydElkIH0gPSByZXF1aXJlKCcuLi9oZWxwZXJzL3NlcXVlbGl6ZUhlbHBlcnMuanMnKTtcblxubW9kdWxlLmV4cG9ydHMgPSAoc2VxdWVsaXplLCB7IFNUUklORywgQk9PTEVBTiwgSU5URUdFUiwgVEVYVCwgREVDSU1BTCB9KSA9PiB7XG4gIGNvbnN0IENlcnRpZmljYXRlID0gc2VxdWVsaXplLmRlZmluZShcbiAgICAnQ2VydGlmaWNhdGUnLFxuICAgIHtcbiAgICAgIGFkZHJlc3M6IHtcbiAgICAgICAgdHlwZSAgIDogU1RSSU5HLFxuICAgICAgICBkZWZhdWx0OiBudWxsLFxuICAgICAgfSxcbiAgICAgIGFtb3VudDoge1xuICAgICAgICB0eXBlICAgOiBERUNJTUFMKDE5LCA4KSxcbiAgICAgICAgZGVmYXVsdDogbnVsbCxcbiAgICAgIH0sXG4gICAgICBjbGFpbUlkOiB7XG4gICAgICAgIHR5cGUgICA6IFNUUklORyxcbiAgICAgICAgZGVmYXVsdDogbnVsbCxcbiAgICAgIH0sXG4gICAgICBjbGFpbVNlcXVlbmNlOiB7XG4gICAgICAgIHR5cGUgICA6IElOVEVHRVIsXG4gICAgICAgIGRlZmF1bHQ6IG51bGwsXG4gICAgICB9LFxuICAgICAgZGVjb2RlZENsYWltOiB7XG4gICAgICAgIHR5cGUgICA6IEJPT0xFQU4sXG4gICAgICAgIGRlZmF1bHQ6IG51bGwsXG4gICAgICB9LFxuICAgICAgZGVwdGg6IHtcbiAgICAgICAgdHlwZSAgIDogSU5URUdFUixcbiAgICAgICAgZGVmYXVsdDogbnVsbCxcbiAgICAgIH0sXG4gICAgICBlZmZlY3RpdmVBbW91bnQ6IHtcbiAgICAgICAgdHlwZSAgIDogREVDSU1BTCgxOSwgOCksXG4gICAgICAgIGRlZmF1bHQ6IG51bGwsXG4gICAgICB9LFxuICAgICAgaGFzU2lnbmF0dXJlOiB7XG4gICAgICAgIHR5cGUgICA6IEJPT0xFQU4sXG4gICAgICAgIGRlZmF1bHQ6IG51bGwsXG4gICAgICB9LFxuICAgICAgaGVpZ2h0OiB7XG4gICAgICAgIHR5cGUgICA6IElOVEVHRVIsXG4gICAgICAgIGRlZmF1bHQ6IG51bGwsXG4gICAgICB9LFxuICAgICAgaGV4OiB7XG4gICAgICAgIHR5cGUgICA6IFRFWFQoJ2xvbmcnKSxcbiAgICAgICAgZGVmYXVsdDogbnVsbCxcbiAgICAgIH0sXG4gICAgICBuYW1lOiB7XG4gICAgICAgIHR5cGUgICA6IFNUUklORyxcbiAgICAgICAgZGVmYXVsdDogbnVsbCxcbiAgICAgIH0sXG4gICAgICBub3V0OiB7XG4gICAgICAgIHR5cGUgICA6IElOVEVHRVIsXG4gICAgICAgIGRlZmF1bHQ6IG51bGwsXG4gICAgICB9LFxuICAgICAgdHhpZDoge1xuICAgICAgICB0eXBlICAgOiBTVFJJTkcsXG4gICAgICAgIGRlZmF1bHQ6IG51bGwsXG4gICAgICB9LFxuICAgICAgdmFsaWRBdEhlaWdodDoge1xuICAgICAgICB0eXBlICAgOiBJTlRFR0VSLFxuICAgICAgICBkZWZhdWx0OiBudWxsLFxuICAgICAgfSxcbiAgICAgIG91dHBvaW50OiB7XG4gICAgICAgIHR5cGUgICA6IFNUUklORyxcbiAgICAgICAgZGVmYXVsdDogbnVsbCxcbiAgICAgIH0sXG4gICAgICB2YWx1ZVZlcnNpb246IHtcbiAgICAgICAgdHlwZSAgIDogU1RSSU5HLFxuICAgICAgICBkZWZhdWx0OiBudWxsLFxuICAgICAgfSxcbiAgICAgIGNsYWltVHlwZToge1xuICAgICAgICB0eXBlICAgOiBTVFJJTkcsXG4gICAgICAgIGRlZmF1bHQ6IG51bGwsXG4gICAgICB9LFxuICAgICAgY2VydGlmaWNhdGVWZXJzaW9uOiB7XG4gICAgICAgIHR5cGUgICA6IFNUUklORyxcbiAgICAgICAgZGVmYXVsdDogbnVsbCxcbiAgICAgIH0sXG4gICAgICBrZXlUeXBlOiB7XG4gICAgICAgIHR5cGUgICA6IFNUUklORyxcbiAgICAgICAgZGVmYXVsdDogbnVsbCxcbiAgICAgIH0sXG4gICAgICBwdWJsaWNLZXk6IHtcbiAgICAgICAgdHlwZSAgIDogVEVYVCgnbG9uZycpLFxuICAgICAgICBkZWZhdWx0OiBudWxsLFxuICAgICAgfSxcbiAgICB9LFxuICAgIHtcbiAgICAgIGZyZWV6ZVRhYmxlTmFtZTogdHJ1ZSxcbiAgICB9XG4gICk7XG5cbiAgQ2VydGlmaWNhdGUuYXNzb2NpYXRlID0gZGIgPT4ge1xuICAgIENlcnRpZmljYXRlLmJlbG9uZ3NUbyhkYi5DaGFubmVsLCB7XG4gICAgICBmb3JlaWduS2V5OiB7XG4gICAgICAgIGFsbG93TnVsbDogdHJ1ZSxcbiAgICAgIH0sXG4gICAgfSk7XG4gIH07XG5cbiAgQ2VydGlmaWNhdGUuZ2V0U2hvcnRDaGFubmVsSWRGcm9tTG9uZ0NoYW5uZWxJZCA9IGZ1bmN0aW9uIChsb25nQ2hhbm5lbElkLCBjaGFubmVsTmFtZSkge1xuICAgIGxvZ2dlci5kZWJ1ZyhgZ2V0U2hvcnRDaGFubmVsSWRGcm9tTG9uZ0NoYW5uZWxJZCAke2NoYW5uZWxOYW1lfToke2xvbmdDaGFubmVsSWR9YCk7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIHRoaXNcbiAgICAgICAgLmZpbmRBbGwoe1xuICAgICAgICAgIHdoZXJlOiB7bmFtZTogY2hhbm5lbE5hbWV9LFxuICAgICAgICAgIG9yZGVyOiBbWydoZWlnaHQnLCAnQVNDJ11dLFxuICAgICAgICB9KVxuICAgICAgICAudGhlbihyZXN1bHQgPT4ge1xuICAgICAgICAgIHN3aXRjaCAocmVzdWx0Lmxlbmd0aCkge1xuICAgICAgICAgICAgY2FzZSAwOlxuICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ05vIGNoYW5uZWwocykgZm91bmQgd2l0aCB0aGF0IGNoYW5uZWwgbmFtZScpO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgcmV0dXJuIHJlc29sdmUocmV0dXJuU2hvcnRJZChyZXN1bHQsIGxvbmdDaGFubmVsSWQpKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pXG4gICAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgfSk7XG4gICAgfSk7XG4gIH07XG5cbiAgQ2VydGlmaWNhdGUuZ2V0TG9uZ0NoYW5uZWxJZEZyb21TaG9ydENoYW5uZWxJZCA9IGZ1bmN0aW9uIChjaGFubmVsTmFtZSwgY2hhbm5lbENsYWltSWQpIHtcbiAgICBsb2dnZXIuZGVidWcoYGdldExvbmdDaGFubmVsSWRGcm9tU2hvcnRDaGFubmVsSWQoJHtjaGFubmVsTmFtZX0sICR7Y2hhbm5lbENsYWltSWR9KWApO1xuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICB0aGlzXG4gICAgICAgIC5maW5kQWxsKHtcbiAgICAgICAgICB3aGVyZToge1xuICAgICAgICAgICAgbmFtZSAgIDogY2hhbm5lbE5hbWUsXG4gICAgICAgICAgICBjbGFpbUlkOiB7XG4gICAgICAgICAgICAgICRsaWtlOiBgJHtjaGFubmVsQ2xhaW1JZH0lYCxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSxcbiAgICAgICAgICBvcmRlcjogW1snaGVpZ2h0JywgJ0FTQyddXSxcbiAgICAgICAgfSlcbiAgICAgICAgLnRoZW4ocmVzdWx0ID0+IHtcbiAgICAgICAgICBzd2l0Y2ggKHJlc3VsdC5sZW5ndGgpIHtcbiAgICAgICAgICAgIGNhc2UgMDpcbiAgICAgICAgICAgICAgcmV0dXJuIHJlc29sdmUobnVsbCk7XG4gICAgICAgICAgICBkZWZhdWx0OiAvLyBub3RlIHJlc3VsdHMgbXVzdCBiZSBzb3J0ZWRcbiAgICAgICAgICAgICAgcmV0dXJuIHJlc29sdmUocmVzdWx0WzBdLmNsYWltSWQpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSlcbiAgICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICB9KTtcbiAgICB9KTtcbiAgfTtcblxuICBDZXJ0aWZpY2F0ZS5nZXRMb25nQ2hhbm5lbElkRnJvbUNoYW5uZWxOYW1lID0gZnVuY3Rpb24gKGNoYW5uZWxOYW1lKSB7XG4gICAgbG9nZ2VyLmRlYnVnKGBnZXRMb25nQ2hhbm5lbElkRnJvbUNoYW5uZWxOYW1lKCR7Y2hhbm5lbE5hbWV9KWApO1xuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICB0aGlzXG4gICAgICAgIC5maW5kQWxsKHtcbiAgICAgICAgICB3aGVyZTogeyBuYW1lOiBjaGFubmVsTmFtZSB9LFxuICAgICAgICAgIG9yZGVyOiBbWydlZmZlY3RpdmVBbW91bnQnLCAnREVTQyddLCBbJ2hlaWdodCcsICdBU0MnXV0sXG4gICAgICAgIH0pXG4gICAgICAgIC50aGVuKHJlc3VsdCA9PiB7XG4gICAgICAgICAgc3dpdGNoIChyZXN1bHQubGVuZ3RoKSB7XG4gICAgICAgICAgICBjYXNlIDA6XG4gICAgICAgICAgICAgIHJldHVybiByZXNvbHZlKG51bGwpO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgcmV0dXJuIHJlc29sdmUocmVzdWx0WzBdLmNsYWltSWQpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSlcbiAgICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICB9KTtcbiAgICB9KTtcbiAgfTtcblxuICBDZXJ0aWZpY2F0ZS52YWxpZGF0ZUxvbmdDaGFubmVsSWQgPSBmdW5jdGlvbiAobmFtZSwgY2xhaW1JZCkge1xuICAgIGxvZ2dlci5kZWJ1ZyhgdmFsaWRhdGVMb25nQ2hhbm5lbElkKCR7bmFtZX0sICR7Y2xhaW1JZH0pYCk7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIHRoaXMuZmluZE9uZSh7XG4gICAgICAgIHdoZXJlOiB7bmFtZSwgY2xhaW1JZH0sXG4gICAgICB9KVxuICAgICAgICAudGhlbihyZXN1bHQgPT4ge1xuICAgICAgICAgIGlmICghcmVzdWx0KSB7XG4gICAgICAgICAgICByZXR1cm4gcmVzb2x2ZShudWxsKTtcbiAgICAgICAgICB9O1xuICAgICAgICAgIHJlc29sdmUoY2xhaW1JZCk7XG4gICAgICAgIH0pXG4gICAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgfSk7XG4gICAgfSk7XG4gIH07XG5cbiAgQ2VydGlmaWNhdGUuZ2V0TG9uZ0NoYW5uZWxJZCA9IGZ1bmN0aW9uIChjaGFubmVsTmFtZSwgY2hhbm5lbENsYWltSWQpIHtcbiAgICBsb2dnZXIuZGVidWcoYGdldExvbmdDaGFubmVsSWQoJHtjaGFubmVsTmFtZX0sICR7Y2hhbm5lbENsYWltSWR9KWApO1xuICAgIGlmIChjaGFubmVsQ2xhaW1JZCAmJiAoY2hhbm5lbENsYWltSWQubGVuZ3RoID09PSA0MCkpIHsgIC8vIGlmIGEgZnVsbCBjaGFubmVsIGlkIGlzIHByb3ZpZGVkXG4gICAgICByZXR1cm4gdGhpcy52YWxpZGF0ZUxvbmdDaGFubmVsSWQoY2hhbm5lbE5hbWUsIGNoYW5uZWxDbGFpbUlkKTtcbiAgICB9IGVsc2UgaWYgKGNoYW5uZWxDbGFpbUlkICYmIGNoYW5uZWxDbGFpbUlkLmxlbmd0aCA8IDQwKSB7ICAvLyBpZiBhIHNob3J0IGNoYW5uZWwgaWQgaXMgcHJvdmlkZWRcbiAgICAgIHJldHVybiB0aGlzLmdldExvbmdDaGFubmVsSWRGcm9tU2hvcnRDaGFubmVsSWQoY2hhbm5lbE5hbWUsIGNoYW5uZWxDbGFpbUlkKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHRoaXMuZ2V0TG9uZ0NoYW5uZWxJZEZyb21DaGFubmVsTmFtZShjaGFubmVsTmFtZSk7ICAvLyBpZiBubyBjaGFubmVsIGlkIHByb3ZpZGVkXG4gICAgfVxuICB9O1xuXG4gIHJldHVybiBDZXJ0aWZpY2F0ZTtcbn07XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9zZXJ2ZXIvbW9kZWxzL2NlcnRpZmljYXRlLmpzIiwibW9kdWxlLmV4cG9ydHMgPSAoc2VxdWVsaXplLCB7IFNUUklORyB9KSA9PiB7XG4gIGNvbnN0IENoYW5uZWwgPSBzZXF1ZWxpemUuZGVmaW5lKFxuICAgICdDaGFubmVsJyxcbiAgICB7XG4gICAgICBjaGFubmVsTmFtZToge1xuICAgICAgICB0eXBlICAgICA6IFNUUklORyxcbiAgICAgICAgYWxsb3dOdWxsOiBmYWxzZSxcbiAgICAgIH0sXG4gICAgICBjaGFubmVsQ2xhaW1JZDoge1xuICAgICAgICB0eXBlICAgICA6IFNUUklORyxcbiAgICAgICAgYWxsb3dOdWxsOiBmYWxzZSxcbiAgICAgIH0sXG4gICAgfSxcbiAgICB7XG4gICAgICBmcmVlemVUYWJsZU5hbWU6IHRydWUsXG4gICAgfVxuICApO1xuXG4gIENoYW5uZWwuYXNzb2NpYXRlID0gZGIgPT4ge1xuICAgIENoYW5uZWwuYmVsb25nc1RvKGRiLlVzZXIpO1xuICAgIENoYW5uZWwuaGFzT25lKGRiLkNlcnRpZmljYXRlKTtcbiAgfTtcblxuICByZXR1cm4gQ2hhbm5lbDtcbn07XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9zZXJ2ZXIvbW9kZWxzL2NoYW5uZWwuanMiLCJjb25zdCBsb2dnZXIgPSByZXF1aXJlKCd3aW5zdG9uJyk7XG5jb25zdCB7IHJldHVyblNob3J0SWQgfSA9IHJlcXVpcmUoJy4uL2hlbHBlcnMvc2VxdWVsaXplSGVscGVycy5qcycpO1xuY29uc3QgeyBhc3NldERlZmF1bHRzOiB7IHRodW1ibmFpbDogZGVmYXVsdFRodW1ibmFpbCB9LCBkZXRhaWxzOiB7IGhvc3QgfSB9ID0gcmVxdWlyZSgnLi4vLi4vY29uZmlnL3NpdGVDb25maWcuanMnKTtcblxuZnVuY3Rpb24gZGV0ZXJtaW5lRmlsZUV4dGVuc2lvbkZyb21Db250ZW50VHlwZSAoY29udGVudFR5cGUpIHtcbiAgc3dpdGNoIChjb250ZW50VHlwZSkge1xuICAgIGNhc2UgJ2ltYWdlL2pwZWcnOlxuICAgIGNhc2UgJ2ltYWdlL2pwZyc6XG4gICAgICByZXR1cm4gJ2pwZWcnO1xuICAgIGNhc2UgJ2ltYWdlL3BuZyc6XG4gICAgICByZXR1cm4gJ3BuZyc7XG4gICAgY2FzZSAnaW1hZ2UvZ2lmJzpcbiAgICAgIHJldHVybiAnZ2lmJztcbiAgICBjYXNlICd2aWRlby9tcDQnOlxuICAgICAgcmV0dXJuICdtcDQnO1xuICAgIGRlZmF1bHQ6XG4gICAgICBsb2dnZXIuZGVidWcoJ3NldHRpbmcgdW5rbm93biBmaWxlIHR5cGUgYXMgZmlsZSBleHRlbnNpb24ganBlZycpO1xuICAgICAgcmV0dXJuICdqcGVnJztcbiAgfVxufTtcblxuZnVuY3Rpb24gZGV0ZXJtaW5lVGh1bWJuYWlsIChzdG9yZWRUaHVtYm5haWwsIGRlZmF1bHRUaHVtYm5haWwpIHtcbiAgaWYgKHN0b3JlZFRodW1ibmFpbCA9PT0gJycpIHtcbiAgICByZXR1cm4gZGVmYXVsdFRodW1ibmFpbDtcbiAgfVxuICByZXR1cm4gc3RvcmVkVGh1bWJuYWlsO1xufTtcblxuZnVuY3Rpb24gcHJlcGFyZUNsYWltRGF0YSAoY2xhaW0pIHtcbiAgLy8gbG9nZ2VyLmRlYnVnKCdwcmVwYXJpbmcgY2xhaW0gZGF0YSBiYXNlZCBvbiByZXNvbHZlZCBkYXRhOicsIGNsYWltKTtcbiAgY2xhaW1bJ3RodW1ibmFpbCddID0gZGV0ZXJtaW5lVGh1bWJuYWlsKGNsYWltLnRodW1ibmFpbCwgZGVmYXVsdFRodW1ibmFpbCk7XG4gIGNsYWltWydmaWxlRXh0J10gPSBkZXRlcm1pbmVGaWxlRXh0ZW5zaW9uRnJvbUNvbnRlbnRUeXBlKGNsYWltLmNvbnRlbnRUeXBlKTtcbiAgY2xhaW1bJ2hvc3QnXSA9IGhvc3Q7XG4gIHJldHVybiBjbGFpbTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gKHNlcXVlbGl6ZSwgeyBTVFJJTkcsIEJPT0xFQU4sIElOVEVHRVIsIFRFWFQsIERFQ0lNQUwgfSkgPT4ge1xuICBjb25zdCBDbGFpbSA9IHNlcXVlbGl6ZS5kZWZpbmUoXG4gICAgJ0NsYWltJyxcbiAgICB7XG4gICAgICBhZGRyZXNzOiB7XG4gICAgICAgIHR5cGUgICA6IFNUUklORyxcbiAgICAgICAgZGVmYXVsdDogbnVsbCxcbiAgICAgIH0sXG4gICAgICBhbW91bnQ6IHtcbiAgICAgICAgdHlwZSAgIDogREVDSU1BTCgxOSwgOCksXG4gICAgICAgIGRlZmF1bHQ6IG51bGwsXG4gICAgICB9LFxuICAgICAgY2xhaW1JZDoge1xuICAgICAgICB0eXBlICAgOiBTVFJJTkcsXG4gICAgICAgIGRlZmF1bHQ6IG51bGwsXG4gICAgICB9LFxuICAgICAgY2xhaW1TZXF1ZW5jZToge1xuICAgICAgICB0eXBlICAgOiBJTlRFR0VSLFxuICAgICAgICBkZWZhdWx0OiBudWxsLFxuICAgICAgfSxcbiAgICAgIGRlY29kZWRDbGFpbToge1xuICAgICAgICB0eXBlICAgOiBCT09MRUFOLFxuICAgICAgICBkZWZhdWx0OiBudWxsLFxuICAgICAgfSxcbiAgICAgIGRlcHRoOiB7XG4gICAgICAgIHR5cGUgICA6IElOVEVHRVIsXG4gICAgICAgIGRlZmF1bHQ6IG51bGwsXG4gICAgICB9LFxuICAgICAgZWZmZWN0aXZlQW1vdW50OiB7XG4gICAgICAgIHR5cGUgICA6IERFQ0lNQUwoMTksIDgpLFxuICAgICAgICBkZWZhdWx0OiBudWxsLFxuICAgICAgfSxcbiAgICAgIGhhc1NpZ25hdHVyZToge1xuICAgICAgICB0eXBlICAgOiBCT09MRUFOLFxuICAgICAgICBkZWZhdWx0OiBudWxsLFxuICAgICAgfSxcbiAgICAgIGhlaWdodDoge1xuICAgICAgICB0eXBlICAgOiBJTlRFR0VSLFxuICAgICAgICBkZWZhdWx0OiBudWxsLFxuICAgICAgfSxcbiAgICAgIGhleDoge1xuICAgICAgICB0eXBlICAgOiBURVhUKCdsb25nJyksXG4gICAgICAgIGRlZmF1bHQ6IG51bGwsXG4gICAgICB9LFxuICAgICAgbmFtZToge1xuICAgICAgICB0eXBlICAgOiBTVFJJTkcsXG4gICAgICAgIGRlZmF1bHQ6IG51bGwsXG4gICAgICB9LFxuICAgICAgbm91dDoge1xuICAgICAgICB0eXBlICAgOiBJTlRFR0VSLFxuICAgICAgICBkZWZhdWx0OiBudWxsLFxuICAgICAgfSxcbiAgICAgIHR4aWQ6IHtcbiAgICAgICAgdHlwZSAgIDogU1RSSU5HLFxuICAgICAgICBkZWZhdWx0OiBudWxsLFxuICAgICAgfSxcbiAgICAgIHZhbGlkQXRIZWlnaHQ6IHtcbiAgICAgICAgdHlwZSAgIDogSU5URUdFUixcbiAgICAgICAgZGVmYXVsdDogbnVsbCxcbiAgICAgIH0sXG4gICAgICBvdXRwb2ludDoge1xuICAgICAgICB0eXBlICAgOiBTVFJJTkcsXG4gICAgICAgIGRlZmF1bHQ6IG51bGwsXG4gICAgICB9LFxuICAgICAgY2xhaW1UeXBlOiB7XG4gICAgICAgIHR5cGUgICA6IFNUUklORyxcbiAgICAgICAgZGVmYXVsdDogbnVsbCxcbiAgICAgIH0sXG4gICAgICBjZXJ0aWZpY2F0ZUlkOiB7XG4gICAgICAgIHR5cGUgICA6IFNUUklORyxcbiAgICAgICAgZGVmYXVsdDogbnVsbCxcbiAgICAgIH0sXG4gICAgICBhdXRob3I6IHtcbiAgICAgICAgdHlwZSAgIDogU1RSSU5HLFxuICAgICAgICBkZWZhdWx0OiBudWxsLFxuICAgICAgfSxcbiAgICAgIGRlc2NyaXB0aW9uOiB7XG4gICAgICAgIHR5cGUgICA6IFRFWFQoJ2xvbmcnKSxcbiAgICAgICAgZGVmYXVsdDogbnVsbCxcbiAgICAgIH0sXG4gICAgICBsYW5ndWFnZToge1xuICAgICAgICB0eXBlICAgOiBTVFJJTkcsXG4gICAgICAgIGRlZmF1bHQ6IG51bGwsXG4gICAgICB9LFxuICAgICAgbGljZW5zZToge1xuICAgICAgICB0eXBlICAgOiBTVFJJTkcsXG4gICAgICAgIGRlZmF1bHQ6IG51bGwsXG4gICAgICB9LFxuICAgICAgbGljZW5zZVVybDoge1xuICAgICAgICB0eXBlICAgOiBTVFJJTkcsXG4gICAgICAgIGRlZmF1bHQ6IG51bGwsXG4gICAgICB9LFxuICAgICAgbnNmdzoge1xuICAgICAgICB0eXBlICAgOiBCT09MRUFOLFxuICAgICAgICBkZWZhdWx0OiBudWxsLFxuICAgICAgfSxcbiAgICAgIHByZXZpZXc6IHtcbiAgICAgICAgdHlwZSAgIDogU1RSSU5HLFxuICAgICAgICBkZWZhdWx0OiBudWxsLFxuICAgICAgfSxcbiAgICAgIHRodW1ibmFpbDoge1xuICAgICAgICB0eXBlICAgOiBTVFJJTkcsXG4gICAgICAgIGRlZmF1bHQ6IG51bGwsXG4gICAgICB9LFxuICAgICAgdGl0bGU6IHtcbiAgICAgICAgdHlwZSAgIDogU1RSSU5HLFxuICAgICAgICBkZWZhdWx0OiBudWxsLFxuICAgICAgfSxcbiAgICAgIG1ldGFkYXRhVmVyc2lvbjoge1xuICAgICAgICB0eXBlICAgOiBTVFJJTkcsXG4gICAgICAgIGRlZmF1bHQ6IG51bGwsXG4gICAgICB9LFxuICAgICAgY29udGVudFR5cGU6IHtcbiAgICAgICAgdHlwZSAgIDogU1RSSU5HLFxuICAgICAgICBkZWZhdWx0OiBudWxsLFxuICAgICAgfSxcbiAgICAgIHNvdXJjZToge1xuICAgICAgICB0eXBlICAgOiBTVFJJTkcsXG4gICAgICAgIGRlZmF1bHQ6IG51bGwsXG4gICAgICB9LFxuICAgICAgc291cmNlVHlwZToge1xuICAgICAgICB0eXBlICAgOiBTVFJJTkcsXG4gICAgICAgIGRlZmF1bHQ6IG51bGwsXG4gICAgICB9LFxuICAgICAgc291cmNlVmVyc2lvbjoge1xuICAgICAgICB0eXBlICAgOiBTVFJJTkcsXG4gICAgICAgIGRlZmF1bHQ6IG51bGwsXG4gICAgICB9LFxuICAgICAgc3RyZWFtVmVyc2lvbjoge1xuICAgICAgICB0eXBlICAgOiBTVFJJTkcsXG4gICAgICAgIGRlZmF1bHQ6IG51bGwsXG4gICAgICB9LFxuICAgICAgdmFsdWVWZXJzaW9uOiB7XG4gICAgICAgIHR5cGUgICA6IFNUUklORyxcbiAgICAgICAgZGVmYXVsdDogbnVsbCxcbiAgICAgIH0sXG4gICAgICBjaGFubmVsTmFtZToge1xuICAgICAgICB0eXBlICAgICA6IFNUUklORyxcbiAgICAgICAgYWxsb3dOdWxsOiB0cnVlLFxuICAgICAgICBkZWZhdWx0ICA6IG51bGwsXG4gICAgICB9LFxuICAgIH0sXG4gICAge1xuICAgICAgZnJlZXplVGFibGVOYW1lOiB0cnVlLFxuICAgIH1cbiAgKTtcblxuICBDbGFpbS5hc3NvY2lhdGUgPSBkYiA9PiB7XG4gICAgQ2xhaW0uYmVsb25nc1RvKGRiLkZpbGUsIHtcbiAgICAgIGZvcmVpZ25LZXk6IHtcbiAgICAgICAgYWxsb3dOdWxsOiB0cnVlLFxuICAgICAgfSxcbiAgICB9KTtcbiAgfTtcblxuICBDbGFpbS5nZXRTaG9ydENsYWltSWRGcm9tTG9uZ0NsYWltSWQgPSBmdW5jdGlvbiAoY2xhaW1JZCwgY2xhaW1OYW1lKSB7XG4gICAgbG9nZ2VyLmRlYnVnKGBDbGFpbS5nZXRTaG9ydENsYWltSWRGcm9tTG9uZ0NsYWltSWQgZm9yICR7Y2xhaW1OYW1lfSMke2NsYWltSWR9YCk7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIHRoaXNcbiAgICAgICAgLmZpbmRBbGwoe1xuICAgICAgICAgIHdoZXJlOiB7IG5hbWU6IGNsYWltTmFtZSB9LFxuICAgICAgICAgIG9yZGVyOiBbWydoZWlnaHQnLCAnQVNDJ11dLFxuICAgICAgICB9KVxuICAgICAgICAudGhlbihyZXN1bHQgPT4ge1xuICAgICAgICAgIHN3aXRjaCAocmVzdWx0Lmxlbmd0aCkge1xuICAgICAgICAgICAgY2FzZSAwOlxuICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ05vIGNsYWltKHMpIGZvdW5kIHdpdGggdGhhdCBjbGFpbSBuYW1lJyk7XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICByZXNvbHZlKHJldHVyblNob3J0SWQocmVzdWx0LCBjbGFpbUlkKSk7XG4gICAgICAgICAgfVxuICAgICAgICB9KVxuICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgIH0pO1xuICAgIH0pO1xuICB9O1xuXG4gIENsYWltLmdldEFsbENoYW5uZWxDbGFpbXMgPSBmdW5jdGlvbiAoY2hhbm5lbENsYWltSWQpIHtcbiAgICBsb2dnZXIuZGVidWcoYENsYWltLmdldEFsbENoYW5uZWxDbGFpbXMgZm9yICR7Y2hhbm5lbENsYWltSWR9YCk7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIHRoaXNcbiAgICAgICAgLmZpbmRBbGwoe1xuICAgICAgICAgIHdoZXJlOiB7IGNlcnRpZmljYXRlSWQ6IGNoYW5uZWxDbGFpbUlkIH0sXG4gICAgICAgICAgb3JkZXI6IFtbJ2hlaWdodCcsICdBU0MnXV0sXG4gICAgICAgICAgcmF3ICA6IHRydWUsICAvLyByZXR1cm5zIGFuIGFycmF5IG9mIG9ubHkgZGF0YSwgbm90IGFuIGFycmF5IG9mIGluc3RhbmNlc1xuICAgICAgICB9KVxuICAgICAgICAudGhlbihjaGFubmVsQ2xhaW1zQXJyYXkgPT4ge1xuICAgICAgICAgIC8vIGxvZ2dlci5kZWJ1ZygnY2hhbm5lbGNsYWltc2FycmF5IGxlbmd0aDonLCBjaGFubmVsQ2xhaW1zQXJyYXkubGVuZ3RoKTtcbiAgICAgICAgICBzd2l0Y2ggKGNoYW5uZWxDbGFpbXNBcnJheS5sZW5ndGgpIHtcbiAgICAgICAgICAgIGNhc2UgMDpcbiAgICAgICAgICAgICAgcmV0dXJuIHJlc29sdmUobnVsbCk7XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICBjaGFubmVsQ2xhaW1zQXJyYXkuZm9yRWFjaChjbGFpbSA9PiB7XG4gICAgICAgICAgICAgICAgY2xhaW1bJ2ZpbGVFeHQnXSA9IGRldGVybWluZUZpbGVFeHRlbnNpb25Gcm9tQ29udGVudFR5cGUoY2xhaW0uY29udGVudFR5cGUpO1xuICAgICAgICAgICAgICAgIGNsYWltWyd0aHVtYm5haWwnXSA9IGRldGVybWluZVRodW1ibmFpbChjbGFpbS50aHVtYm5haWwsIGRlZmF1bHRUaHVtYm5haWwpO1xuICAgICAgICAgICAgICAgIHJldHVybiBjbGFpbTtcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgIHJldHVybiByZXNvbHZlKGNoYW5uZWxDbGFpbXNBcnJheSk7XG4gICAgICAgICAgfVxuICAgICAgICB9KVxuICAgICAgICAuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgIH0pO1xuICAgIH0pO1xuICB9O1xuXG4gIENsYWltLmdldENsYWltSWRCeUxvbmdDaGFubmVsSWQgPSBmdW5jdGlvbiAoY2hhbm5lbENsYWltSWQsIGNsYWltTmFtZSkge1xuICAgIGxvZ2dlci5kZWJ1ZyhgZmluZGluZyBjbGFpbSBpZCBmb3IgY2xhaW0gJHtjbGFpbU5hbWV9IGZyb20gY2hhbm5lbCAke2NoYW5uZWxDbGFpbUlkfWApO1xuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICB0aGlzXG4gICAgICAgIC5maW5kQWxsKHtcbiAgICAgICAgICB3aGVyZTogeyBuYW1lOiBjbGFpbU5hbWUsIGNlcnRpZmljYXRlSWQ6IGNoYW5uZWxDbGFpbUlkIH0sXG4gICAgICAgICAgb3JkZXI6IFtbJ2lkJywgJ0FTQyddXSxcbiAgICAgICAgfSlcbiAgICAgICAgLnRoZW4ocmVzdWx0ID0+IHtcbiAgICAgICAgICBzd2l0Y2ggKHJlc3VsdC5sZW5ndGgpIHtcbiAgICAgICAgICAgIGNhc2UgMDpcbiAgICAgICAgICAgICAgcmV0dXJuIHJlc29sdmUobnVsbCk7XG4gICAgICAgICAgICBjYXNlIDE6XG4gICAgICAgICAgICAgIHJldHVybiByZXNvbHZlKHJlc3VsdFswXS5jbGFpbUlkKTtcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgIGxvZ2dlci5lcnJvcihgJHtyZXN1bHQubGVuZ3RofSByZWNvcmRzIGZvdW5kIGZvciBcIiR7Y2xhaW1OYW1lfVwiIGluIGNoYW5uZWwgXCIke2NoYW5uZWxDbGFpbUlkfVwiYCk7XG4gICAgICAgICAgICAgIHJldHVybiByZXNvbHZlKHJlc3VsdFswXS5jbGFpbUlkKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pXG4gICAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgfSk7XG4gICAgfSk7XG4gIH07XG5cbiAgQ2xhaW0uZ2V0TG9uZ0NsYWltSWRGcm9tU2hvcnRDbGFpbUlkID0gZnVuY3Rpb24gKG5hbWUsIHNob3J0SWQpIHtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgdGhpc1xuICAgICAgICAuZmluZEFsbCh7XG4gICAgICAgICAgd2hlcmU6IHtcbiAgICAgICAgICAgIG5hbWUsXG4gICAgICAgICAgICBjbGFpbUlkOiB7XG4gICAgICAgICAgICAgICRsaWtlOiBgJHtzaG9ydElkfSVgLFxuICAgICAgICAgICAgfX0sXG4gICAgICAgICAgb3JkZXI6IFtbJ2hlaWdodCcsICdBU0MnXV0sXG4gICAgICAgIH0pXG4gICAgICAgIC50aGVuKHJlc3VsdCA9PiB7XG4gICAgICAgICAgc3dpdGNoIChyZXN1bHQubGVuZ3RoKSB7XG4gICAgICAgICAgICBjYXNlIDA6XG4gICAgICAgICAgICAgIHJldHVybiByZXNvbHZlKG51bGwpO1xuICAgICAgICAgICAgZGVmYXVsdDogLy8gbm90ZSByZXN1bHRzIG11c3QgYmUgc29ydGVkXG4gICAgICAgICAgICAgIHJldHVybiByZXNvbHZlKHJlc3VsdFswXS5jbGFpbUlkKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pXG4gICAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgfSk7XG4gICAgfSk7XG4gIH07XG5cbiAgQ2xhaW0uZ2V0VG9wRnJlZUNsYWltSWRCeUNsYWltTmFtZSA9IGZ1bmN0aW9uIChuYW1lKSB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIHRoaXNcbiAgICAgICAgLmZpbmRBbGwoe1xuICAgICAgICAgIHdoZXJlOiB7IG5hbWUgfSxcbiAgICAgICAgICBvcmRlcjogW1snZWZmZWN0aXZlQW1vdW50JywgJ0RFU0MnXSwgWydoZWlnaHQnLCAnQVNDJ11dLCAgLy8gbm90ZTogbWF5YmUgaGVpZ2h0IGFuZCBlZmZlY3RpdmUgYW1vdW50IG5lZWQgdG8gc3dpdGNoP1xuICAgICAgICB9KVxuICAgICAgICAudGhlbihyZXN1bHQgPT4ge1xuICAgICAgICAgIGxvZ2dlci5kZWJ1ZygnbGVuZ3RoIG9mIHJlc3VsdCcsIHJlc3VsdC5sZW5ndGgpO1xuICAgICAgICAgIHN3aXRjaCAocmVzdWx0Lmxlbmd0aCkge1xuICAgICAgICAgICAgY2FzZSAwOlxuICAgICAgICAgICAgICByZXR1cm4gcmVzb2x2ZShudWxsKTtcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgIHJldHVybiByZXNvbHZlKHJlc3VsdFswXS5kYXRhVmFsdWVzLmNsYWltSWQpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSlcbiAgICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICB9KTtcbiAgICB9KTtcbiAgfTtcblxuICBDbGFpbS52YWxpZGF0ZUxvbmdDbGFpbUlkID0gZnVuY3Rpb24gKG5hbWUsIGNsYWltSWQpIHtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgdGhpcy5maW5kT25lKHtcbiAgICAgICAgd2hlcmU6IHtuYW1lLCBjbGFpbUlkfSxcbiAgICAgIH0pXG4gICAgICAgIC50aGVuKHJlc3VsdCA9PiB7XG4gICAgICAgICAgaWYgKCFyZXN1bHQpIHtcbiAgICAgICAgICAgIHJldHVybiByZXNvbHZlKG51bGwpO1xuICAgICAgICAgIH07XG4gICAgICAgICAgcmVzb2x2ZShjbGFpbUlkKTtcbiAgICAgICAgfSlcbiAgICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICB9KTtcbiAgICB9KTtcbiAgfTtcblxuICBDbGFpbS5nZXRMb25nQ2xhaW1JZCA9IGZ1bmN0aW9uIChjbGFpbU5hbWUsIGNsYWltSWQpIHtcbiAgICBsb2dnZXIuZGVidWcoYGdldExvbmdDbGFpbUlkKCR7Y2xhaW1OYW1lfSwgJHtjbGFpbUlkfSlgKTtcbiAgICBpZiAoY2xhaW1JZCAmJiAoY2xhaW1JZC5sZW5ndGggPT09IDQwKSkgeyAgLy8gaWYgYSBmdWxsIGNsYWltIGlkIGlzIHByb3ZpZGVkXG4gICAgICByZXR1cm4gdGhpcy52YWxpZGF0ZUxvbmdDbGFpbUlkKGNsYWltTmFtZSwgY2xhaW1JZCk7XG4gICAgfSBlbHNlIGlmIChjbGFpbUlkICYmIGNsYWltSWQubGVuZ3RoIDwgNDApIHtcbiAgICAgIHJldHVybiB0aGlzLmdldExvbmdDbGFpbUlkRnJvbVNob3J0Q2xhaW1JZChjbGFpbU5hbWUsIGNsYWltSWQpOyAgLy8gaWYgYSBzaG9ydCBjbGFpbSBpZCBpcyBwcm92aWRlZFxuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gdGhpcy5nZXRUb3BGcmVlQ2xhaW1JZEJ5Q2xhaW1OYW1lKGNsYWltTmFtZSk7ICAvLyBpZiBubyBjbGFpbSBpZCBpcyBwcm92aWRlZFxuICAgIH1cbiAgfTtcblxuICBDbGFpbS5yZXNvbHZlQ2xhaW0gPSBmdW5jdGlvbiAobmFtZSwgY2xhaW1JZCkge1xuICAgIGxvZ2dlci5kZWJ1ZyhgQ2xhaW0ucmVzb2x2ZUNsYWltOiAke25hbWV9ICR7Y2xhaW1JZH1gKTtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgdGhpc1xuICAgICAgICAuZmluZEFsbCh7XG4gICAgICAgICAgd2hlcmU6IHsgbmFtZSwgY2xhaW1JZCB9LFxuICAgICAgICB9KVxuICAgICAgICAudGhlbihjbGFpbUFycmF5ID0+IHtcbiAgICAgICAgICBzd2l0Y2ggKGNsYWltQXJyYXkubGVuZ3RoKSB7XG4gICAgICAgICAgICBjYXNlIDA6XG4gICAgICAgICAgICAgIHJldHVybiByZXNvbHZlKG51bGwpO1xuICAgICAgICAgICAgY2FzZSAxOlxuICAgICAgICAgICAgICByZXR1cm4gcmVzb2x2ZShwcmVwYXJlQ2xhaW1EYXRhKGNsYWltQXJyYXlbMF0uZGF0YVZhbHVlcykpO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgbG9nZ2VyLmVycm9yKGBtb3JlIHRoYW4gb25lIHJlY29yZCBtYXRjaGVzICR7bmFtZX0jJHtjbGFpbUlkfSBpbiBkYi5DbGFpbWApO1xuICAgICAgICAgICAgICByZXR1cm4gcmVzb2x2ZShwcmVwYXJlQ2xhaW1EYXRhKGNsYWltQXJyYXlbMF0uZGF0YVZhbHVlcykpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSlcbiAgICAgICAgLmNhdGNoKGVycm9yID0+IHtcbiAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICB9KTtcbiAgICB9KTtcbiAgfTtcblxuICByZXR1cm4gQ2xhaW07XG59O1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vc2VydmVyL21vZGVscy9jbGFpbS5qcyIsIm1vZHVsZS5leHBvcnRzID0gKHNlcXVlbGl6ZSwgeyBTVFJJTkcsIEJPT0xFQU4sIElOVEVHRVIgfSkgPT4ge1xuICBjb25zdCBGaWxlID0gc2VxdWVsaXplLmRlZmluZShcbiAgICAnRmlsZScsXG4gICAge1xuICAgICAgbmFtZToge1xuICAgICAgICB0eXBlICAgICA6IFNUUklORyxcbiAgICAgICAgYWxsb3dOdWxsOiBmYWxzZSxcbiAgICAgIH0sXG4gICAgICBjbGFpbUlkOiB7XG4gICAgICAgIHR5cGUgICAgIDogU1RSSU5HLFxuICAgICAgICBhbGxvd051bGw6IGZhbHNlLFxuICAgICAgfSxcbiAgICAgIGFkZHJlc3M6IHtcbiAgICAgICAgdHlwZSAgICAgOiBTVFJJTkcsXG4gICAgICAgIGFsbG93TnVsbDogZmFsc2UsXG4gICAgICB9LFxuICAgICAgb3V0cG9pbnQ6IHtcbiAgICAgICAgdHlwZSAgICAgOiBTVFJJTkcsXG4gICAgICAgIGFsbG93TnVsbDogZmFsc2UsXG4gICAgICB9LFxuICAgICAgaGVpZ2h0OiB7XG4gICAgICAgIHR5cGUgICAgIDogSU5URUdFUixcbiAgICAgICAgYWxsb3dOdWxsOiBmYWxzZSxcbiAgICAgICAgZGVmYXVsdCAgOiAwLFxuICAgICAgfSxcbiAgICAgIGZpbGVOYW1lOiB7XG4gICAgICAgIHR5cGUgICAgIDogU1RSSU5HLFxuICAgICAgICBhbGxvd051bGw6IGZhbHNlLFxuICAgICAgfSxcbiAgICAgIGZpbGVQYXRoOiB7XG4gICAgICAgIHR5cGUgICAgIDogU1RSSU5HLFxuICAgICAgICBhbGxvd051bGw6IGZhbHNlLFxuICAgICAgfSxcbiAgICAgIGZpbGVUeXBlOiB7XG4gICAgICAgIHR5cGU6IFNUUklORyxcbiAgICAgIH0sXG4gICAgICBuc2Z3OiB7XG4gICAgICAgIHR5cGUgICAgICAgIDogQk9PTEVBTixcbiAgICAgICAgYWxsb3dOdWxsICAgOiBmYWxzZSxcbiAgICAgICAgZGVmYXVsdFZhbHVlOiBmYWxzZSxcbiAgICAgIH0sXG4gICAgICB0cmVuZGluZ0VsaWdpYmxlOiB7XG4gICAgICAgIHR5cGUgICAgICAgIDogQk9PTEVBTixcbiAgICAgICAgYWxsb3dOdWxsICAgOiBmYWxzZSxcbiAgICAgICAgZGVmYXVsdFZhbHVlOiB0cnVlLFxuICAgICAgfSxcbiAgICB9LFxuICAgIHtcbiAgICAgIGZyZWV6ZVRhYmxlTmFtZTogdHJ1ZSxcbiAgICB9XG4gICk7XG5cbiAgRmlsZS5hc3NvY2lhdGUgPSBkYiA9PiB7XG4gICAgRmlsZS5oYXNNYW55KGRiLlJlcXVlc3QpO1xuICAgIEZpbGUuaGFzT25lKGRiLkNsYWltKTtcbiAgfTtcblxuICBGaWxlLmdldFJlY2VudENsYWltcyA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5maW5kQWxsKHtcbiAgICAgIHdoZXJlOiB7IG5zZnc6IGZhbHNlLCB0cmVuZGluZ0VsaWdpYmxlOiB0cnVlIH0sXG4gICAgICBvcmRlcjogW1snY3JlYXRlZEF0JywgJ0RFU0MnXV0sXG4gICAgICBsaW1pdDogMjUsXG4gICAgfSk7XG4gIH07XG5cbiAgcmV0dXJuIEZpbGU7XG59O1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vc2VydmVyL21vZGVscy9maWxlLmpzIiwibW9kdWxlLmV4cG9ydHMgPSAoc2VxdWVsaXplLCB7IFNUUklORywgQk9PTEVBTiwgVEVYVCB9KSA9PiB7XG4gIGNvbnN0IFJlcXVlc3QgPSBzZXF1ZWxpemUuZGVmaW5lKFxuICAgICdSZXF1ZXN0JyxcbiAgICB7XG4gICAgICBhY3Rpb246IHtcbiAgICAgICAgdHlwZSAgICAgOiBTVFJJTkcsXG4gICAgICAgIGFsbG93TnVsbDogZmFsc2UsXG4gICAgICB9LFxuICAgICAgdXJsOiB7XG4gICAgICAgIHR5cGUgICAgIDogU1RSSU5HLFxuICAgICAgICBhbGxvd051bGw6IGZhbHNlLFxuICAgICAgfSxcbiAgICAgIGlwQWRkcmVzczoge1xuICAgICAgICB0eXBlICAgICA6IFNUUklORyxcbiAgICAgICAgYWxsb3dOdWxsOiB0cnVlLFxuICAgICAgfSxcbiAgICAgIHJlc3VsdDoge1xuICAgICAgICB0eXBlICAgICA6IFRFWFQoJ2xvbmcnKSxcbiAgICAgICAgYWxsb3dOdWxsOiB0cnVlLFxuICAgICAgICBkZWZhdWx0ICA6IG51bGwsXG4gICAgICB9LFxuICAgIH0sXG4gICAge1xuICAgICAgZnJlZXplVGFibGVOYW1lOiB0cnVlLFxuICAgIH1cbiAgKTtcblxuICBSZXF1ZXN0LmFzc29jaWF0ZSA9IGRiID0+IHtcbiAgICBSZXF1ZXN0LmJlbG9uZ3NUbyhkYi5GaWxlLCB7XG4gICAgICBmb3JlaWduS2V5OiB7XG4gICAgICAgIGFsbG93TnVsbDogdHJ1ZSxcbiAgICAgIH0sXG4gICAgfSk7XG4gIH07XG5cbiAgcmV0dXJuIFJlcXVlc3Q7XG59O1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vc2VydmVyL21vZGVscy9yZXF1ZXN0LmpzIiwiJ3VzZSBzdHJpY3QnO1xuY29uc3QgYmNyeXB0ID0gcmVxdWlyZSgnYmNyeXB0Jyk7XG5jb25zdCBsb2dnZXIgPSByZXF1aXJlKCd3aW5zdG9uJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gKHNlcXVlbGl6ZSwgeyBTVFJJTkcgfSkgPT4ge1xuICBjb25zdCBVc2VyID0gc2VxdWVsaXplLmRlZmluZShcbiAgICAnVXNlcicsXG4gICAge1xuICAgICAgdXNlck5hbWU6IHtcbiAgICAgICAgdHlwZSAgICAgOiBTVFJJTkcsXG4gICAgICAgIGFsbG93TnVsbDogZmFsc2UsXG4gICAgICB9LFxuICAgICAgcGFzc3dvcmQ6IHtcbiAgICAgICAgdHlwZSAgICAgOiBTVFJJTkcsXG4gICAgICAgIGFsbG93TnVsbDogZmFsc2UsXG4gICAgICB9LFxuICAgIH0sXG4gICAge1xuICAgICAgZnJlZXplVGFibGVOYW1lOiB0cnVlLFxuICAgIH1cbiAgKTtcblxuICBVc2VyLmFzc29jaWF0ZSA9IGRiID0+IHtcbiAgICBVc2VyLmhhc09uZShkYi5DaGFubmVsKTtcbiAgfTtcblxuICBVc2VyLnByb3RvdHlwZS5jb21wYXJlUGFzc3dvcmQgPSBmdW5jdGlvbiAocGFzc3dvcmQpIHtcbiAgICByZXR1cm4gYmNyeXB0LmNvbXBhcmUocGFzc3dvcmQsIHRoaXMucGFzc3dvcmQpO1xuICB9O1xuXG4gIFVzZXIucHJvdG90eXBlLmNoYW5nZVBhc3N3b3JkID0gZnVuY3Rpb24gKG5ld1Bhc3N3b3JkKSB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIC8vIGdlbmVyYXRlIGEgc2FsdCBzdHJpbmcgdG8gdXNlIGZvciBoYXNoaW5nXG4gICAgICBiY3J5cHQuZ2VuU2FsdCgoc2FsdEVycm9yLCBzYWx0KSA9PiB7XG4gICAgICAgIGlmIChzYWx0RXJyb3IpIHtcbiAgICAgICAgICBsb2dnZXIuZXJyb3IoJ3NhbHQgZXJyb3InLCBzYWx0RXJyb3IpO1xuICAgICAgICAgIHJlamVjdChzYWx0RXJyb3IpO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICAvLyBnZW5lcmF0ZSBhIGhhc2hlZCB2ZXJzaW9uIG9mIHRoZSB1c2VyJ3MgcGFzc3dvcmRcbiAgICAgICAgYmNyeXB0Lmhhc2gobmV3UGFzc3dvcmQsIHNhbHQsIChoYXNoRXJyb3IsIGhhc2gpID0+IHtcbiAgICAgICAgICAvLyBpZiB0aGVyZSBpcyBhbiBlcnJvciB3aXRoIHRoZSBoYXNoIGdlbmVyYXRpb24gcmV0dXJuIHRoZSBlcnJvclxuICAgICAgICAgIGlmIChoYXNoRXJyb3IpIHtcbiAgICAgICAgICAgIGxvZ2dlci5lcnJvcignaGFzaCBlcnJvcicsIGhhc2hFcnJvcik7XG4gICAgICAgICAgICByZWplY3QoaGFzaEVycm9yKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICB9XG4gICAgICAgICAgLy8gcmVwbGFjZSB0aGUgY3VycmVudCBwYXNzd29yZCB3aXRoIHRoZSBuZXcgaGFzaFxuICAgICAgICAgIHRoaXNcbiAgICAgICAgICAgIC51cGRhdGUoe3Bhc3N3b3JkOiBoYXNofSlcbiAgICAgICAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfTtcblxuICAvLyBwcmUtc2F2ZSBob29rIG1ldGhvZCB0byBoYXNoIHRoZSB1c2VyJ3MgcGFzc3dvcmQgYmVmb3JlIHRoZSB1c2VyJ3MgaW5mbyBpcyBzYXZlZCB0byB0aGUgZGIuXG4gIFVzZXIuaG9vaygnYmVmb3JlQ3JlYXRlJywgKHVzZXIsIG9wdGlvbnMpID0+IHtcbiAgICBsb2dnZXIuZGVidWcoJ1VzZXIuYmVmb3JlQ3JlYXRlIGhvb2suLi4nKTtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgLy8gZ2VuZXJhdGUgYSBzYWx0IHN0cmluZyB0byB1c2UgZm9yIGhhc2hpbmdcbiAgICAgIGJjcnlwdC5nZW5TYWx0KChzYWx0RXJyb3IsIHNhbHQpID0+IHtcbiAgICAgICAgaWYgKHNhbHRFcnJvcikge1xuICAgICAgICAgIGxvZ2dlci5lcnJvcignc2FsdCBlcnJvcicsIHNhbHRFcnJvcik7XG4gICAgICAgICAgcmVqZWN0KHNhbHRFcnJvcik7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIC8vIGdlbmVyYXRlIGEgaGFzaGVkIHZlcnNpb24gb2YgdGhlIHVzZXIncyBwYXNzd29yZFxuICAgICAgICBiY3J5cHQuaGFzaCh1c2VyLnBhc3N3b3JkLCBzYWx0LCAoaGFzaEVycm9yLCBoYXNoKSA9PiB7XG4gICAgICAgICAgLy8gaWYgdGhlcmUgaXMgYW4gZXJyb3Igd2l0aCB0aGUgaGFzaCBnZW5lcmF0aW9uIHJldHVybiB0aGUgZXJyb3JcbiAgICAgICAgICBpZiAoaGFzaEVycm9yKSB7XG4gICAgICAgICAgICBsb2dnZXIuZXJyb3IoJ2hhc2ggZXJyb3InLCBoYXNoRXJyb3IpO1xuICAgICAgICAgICAgcmVqZWN0KGhhc2hFcnJvcik7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgfVxuICAgICAgICAgIC8vIHJlcGxhY2UgdGhlIHBhc3N3b3JkIHN0cmluZyB3aXRoIHRoZSBoYXNoIHBhc3N3b3JkIHZhbHVlXG4gICAgICAgICAgdXNlci5wYXNzd29yZCA9IGhhc2g7XG4gICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9KTtcblxuICByZXR1cm4gVXNlcjtcbn07XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9zZXJ2ZXIvbW9kZWxzL3VzZXIuanMiLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCJiY3J5cHRcIik7XG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gZXh0ZXJuYWwgXCJiY3J5cHRcIlxuLy8gbW9kdWxlIGlkID0gMTczXG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsImNvbnN0IHsgZ2V0Q2xhaW1MaXN0IH0gPSByZXF1aXJlKCdoZWxwZXJzL2xicnlBcGkuanMnKTtcclxuY29uc3QgeyBoYW5kbGVFcnJvclJlc3BvbnNlIH0gPSByZXF1aXJlKCdoZWxwZXJzL2Vycm9ySGFuZGxlcnMuanMnKTtcclxuXHJcbi8qXHJcblxyXG4gIHJvdXRlIHRvIGdldCBsaXN0IG9mIGNsYWltc1xyXG5cclxuKi9cclxuXHJcbmNvbnN0IGNsYWltTGlzdCA9IChkYikgPT4ge1xyXG4gIHJldHVybiAoeyBpcCwgb3JpZ2luYWxVcmwsIHBhcmFtcyB9LCByZXMpID0+IHtcclxuICAgIGdldENsYWltTGlzdChwYXJhbXMubmFtZSlcclxuICAgICAgLnRoZW4oY2xhaW1zTGlzdCA9PiB7XHJcbiAgICAgICAgcmVzLnN0YXR1cygyMDApLmpzb24oY2xhaW1zTGlzdCk7XHJcbiAgICAgIH0pXHJcbiAgICAgIC5jYXRjaChlcnJvciA9PiB7XHJcbiAgICAgICAgaGFuZGxlRXJyb3JSZXNwb25zZShvcmlnaW5hbFVybCwgaXAsIGVycm9yLCByZXMpO1xyXG4gICAgICB9KTtcclxuICB9O1xyXG59O1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBjbGFpbUxpc3Q7XHJcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL3NlcnZlci9yb3V0ZXMvYXBpL2NsYWltTGlzdC5qcyIsImNvbnN0IHNlbmRSZWFjdEFwcCA9IHJlcXVpcmUoJy4vc2VuZFJlYWN0QXBwJyk7XG5jb25zdCBzZW5kRW1iZWRQYWdlID0gcmVxdWlyZSgnLi9zZW5kRW1iZWRQYWdlJyk7XG5jb25zdCByZWRpcmVjdCA9IHJlcXVpcmUoJy4vcmVkaXJlY3QnKTtcblxuXG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICBzZW5kUmVhY3RBcHAsXG4gIHNlbmRFbWJlZFBhZ2UsXG4gIHJlZGlyZWN0LFxufTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL3NlcnZlci9yb3V0ZXMvcGFnZS9pbmRleC5qcyIsImNvbnN0IGhhbmRsZVBhZ2VSZW5kZXIgPSByZXF1aXJlKCdoZWxwZXJzL2hhbmRsZVBhZ2VSZW5kZXIuanN4Jyk7XHJcblxyXG5jb25zdCBzZW5kUmVhY3RBcHAgPSAoKSA9PiB7XHJcbiAgcmV0dXJuIChyZXEsIHJlcykgPT4ge1xyXG4gICAgaGFuZGxlUGFnZVJlbmRlcihyZXEsIHJlcyk7XHJcbiAgfTtcclxufTtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gc2VuZFJlYWN0QXBwO1xyXG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gLi9zZXJ2ZXIvcm91dGVzL3BhZ2Uvc2VuZFJlYWN0QXBwLmpzIiwiaW1wb3J0IFJlYWN0IGZyb20gJ3JlYWN0JztcbmltcG9ydCB7IHJlbmRlclRvU3RyaW5nIH0gZnJvbSAncmVhY3QtZG9tL3NlcnZlcic7XG5pbXBvcnQgeyBjcmVhdGVTdG9yZSB9IGZyb20gJ3JlZHV4JztcbmltcG9ydCBSZWR1Y2VyIGZyb20gJ2NsaWVudC9yZWR1Y2Vycyc7XG5pbXBvcnQgeyBQcm92aWRlciB9IGZyb20gJ3JlYWN0LXJlZHV4JztcbmltcG9ydCB7IFN0YXRpY1JvdXRlciB9IGZyb20gJ3JlYWN0LXJvdXRlci1kb20nO1xuaW1wb3J0IEdBTGlzdGVuZXIgZnJvbSAnY2xpZW50L2NvbXBvbmVudHMvR0FMaXN0ZW5lci8nO1xuaW1wb3J0IEFwcCBmcm9tICdjbGllbnQvYXBwJztcbmltcG9ydCByZW5kZXJGdWxsUGFnZSBmcm9tICcuL3JlbmRlckZ1bGxQYWdlLmpzJztcbmltcG9ydCBIZWxtZXQgZnJvbSAncmVhY3QtaGVsbWV0JztcblxubW9kdWxlLmV4cG9ydHMgPSAocmVxLCByZXMpID0+IHtcbiAgbGV0IGNvbnRleHQgPSB7fTtcblxuICAvLyBjcmVhdGUgYSBuZXcgUmVkdXggc3RvcmUgaW5zdGFuY2VcbiAgY29uc3Qgc3RvcmUgPSBjcmVhdGVTdG9yZShSZWR1Y2VyKTtcblxuICAvLyByZW5kZXIgY29tcG9uZW50IHRvIGEgc3RyaW5nXG4gIGNvbnN0IGh0bWwgPSByZW5kZXJUb1N0cmluZyhcbiAgICA8UHJvdmlkZXIgc3RvcmU9e3N0b3JlfT5cbiAgICAgIDxTdGF0aWNSb3V0ZXIgbG9jYXRpb249e3JlcS51cmx9IGNvbnRleHQ9e2NvbnRleHR9PlxuICAgICAgICA8R0FMaXN0ZW5lcj5cbiAgICAgICAgICA8QXBwIC8+XG4gICAgICAgIDwvR0FMaXN0ZW5lcj5cbiAgICAgIDwvU3RhdGljUm91dGVyPlxuICAgIDwvUHJvdmlkZXI+XG4gICk7XG5cbiAgLy8gZ2V0IGhlYWQgdGFncyBmcm9tIGhlbG1ldFxuICBjb25zdCBoZWxtZXQgPSBIZWxtZXQucmVuZGVyU3RhdGljKCk7XG5cbiAgLy8gY2hlY2sgZm9yIGEgcmVkaXJlY3RcbiAgaWYgKGNvbnRleHQudXJsKSB7XG4gICAgLy8gU29tZXdoZXJlIGEgYDxSZWRpcmVjdD5gIHdhcyByZW5kZXJlZFxuICAgIHJldHVybiByZXMucmVkaXJlY3QoMzAxLCBjb250ZXh0LnVybCk7XG4gIH0gZWxzZSB7XG4gICAgLy8gd2UncmUgZ29vZCwgc2VuZCB0aGUgcmVzcG9uc2VcbiAgfVxuXG4gIC8vIGdldCB0aGUgaW5pdGlhbCBzdGF0ZSBmcm9tIG91ciBSZWR1eCBzdG9yZVxuICBjb25zdCBwcmVsb2FkZWRTdGF0ZSA9IHN0b3JlLmdldFN0YXRlKCk7XG5cbiAgLy8gc2VuZCB0aGUgcmVuZGVyZWQgcGFnZSBiYWNrIHRvIHRoZSBjbGllbnRcbiAgcmVzLnNlbmQocmVuZGVyRnVsbFBhZ2UoaGVsbWV0LCBodG1sLCBwcmVsb2FkZWRTdGF0ZSkpO1xufTtcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL3NlcnZlci9oZWxwZXJzL2hhbmRsZVBhZ2VSZW5kZXIuanN4IiwiY29uc3QgeyBkZXRhaWxzOiB7IGhvc3QgfSB9ID0gcmVxdWlyZSgnc2l0ZUNvbmZpZy5qcycpO1xyXG5cclxuY29uc3Qgc2VuZEVtYmVkUGFnZSA9ICgpID0+IHtcclxuICByZXR1cm4gKHsgcGFyYW1zIH0sIHJlcykgPT4ge1xyXG4gICAgY29uc3QgY2xhaW1JZCA9IHBhcmFtcy5jbGFpbUlkO1xyXG4gICAgY29uc3QgbmFtZSA9IHBhcmFtcy5uYW1lO1xyXG4gICAgLy8gZ2V0IGFuZCByZW5kZXIgdGhlIGNvbnRlbnRcclxuICAgIHJlcy5zdGF0dXMoMjAwKS5yZW5kZXIoJ2VtYmVkJywgeyBsYXlvdXQ6ICdlbWJlZCcsIGhvc3QsIGNsYWltSWQsIG5hbWUgfSk7XHJcbiAgfTtcclxufTtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gc2VuZEVtYmVkUGFnZTtcclxuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIC4vc2VydmVyL3JvdXRlcy9wYWdlL3NlbmRFbWJlZFBhZ2UuanMiLCJjb25zdCByZWRpcmVjdCA9IChyb3V0ZSkgPT4ge1xyXG4gIHJldHVybiAocmVxLCByZXMpID0+IHtcclxuICAgIHJlcy5zdGF0dXMoMzAxKS5yZWRpcmVjdChyb3V0ZSk7XHJcbiAgfTtcclxufTtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gcmVkaXJlY3Q7XHJcblxuXG5cbi8vIFdFQlBBQ0sgRk9PVEVSIC8vXG4vLyAuL3NlcnZlci9yb3V0ZXMvcGFnZS9yZWRpcmVjdC5qcyJdLCJzb3VyY2VSb290IjoiIn0=
|