2423 lines
429 KiB
JavaScript
2423 lines
429 KiB
JavaScript
'use strict';
|
|
|
|
var logger = require('./logger-kbUbohEP.js');
|
|
var path = require('path');
|
|
var fs = require('fs-extra');
|
|
var http = require('http');
|
|
var crypto = require('crypto');
|
|
var os = require('os');
|
|
var child_process = require('child_process');
|
|
|
|
function _interopNamespaceDefault(e) {
|
|
var n = Object.create(null);
|
|
if (e) {
|
|
Object.keys(e).forEach(function (k) {
|
|
if (k !== 'default') {
|
|
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
Object.defineProperty(n, k, d.get ? d : {
|
|
enumerable: true,
|
|
get: function () { return e[k]; }
|
|
});
|
|
}
|
|
});
|
|
}
|
|
n.default = e;
|
|
return Object.freeze(n);
|
|
}
|
|
|
|
var path__namespace = /*#__PURE__*/_interopNamespaceDefault(path);
|
|
var fs__namespace = /*#__PURE__*/_interopNamespaceDefault(fs);
|
|
var http__namespace = /*#__PURE__*/_interopNamespaceDefault(http);
|
|
var crypto__namespace = /*#__PURE__*/_interopNamespaceDefault(crypto);
|
|
var os__namespace = /*#__PURE__*/_interopNamespaceDefault(os);
|
|
|
|
var polka = require('polka');
|
|
var sirv = require('sirv');
|
|
var _a = require('body-parser'), json = _a.json, urlencoded = _a.urlencoded;
|
|
var send = require('@polka/send-type');
|
|
var archiver = require('archiver');
|
|
var TemplatePlaygroundServer = /** @class */ (function () {
|
|
function TemplatePlaygroundServer(port) {
|
|
this.sessions = new Map();
|
|
this.ipToSessionId = new Map();
|
|
this.debounceTimers = new Map();
|
|
this.signalHandlers = new Map();
|
|
this.port = port || parseInt(process.env.PLAYGROUND_PORT || process.env.PORT || '3001', 10);
|
|
this.app = polka();
|
|
this.setupPaths();
|
|
this.initializeHandlebars();
|
|
this.setupMiddleware();
|
|
this.setupRoutes();
|
|
this.startSessionCleanup();
|
|
this.setupSignalHandlers();
|
|
}
|
|
/**
|
|
* Get the underlying HTTP server instance for testing purposes
|
|
* @returns HTTP server instance or null if not started
|
|
*/
|
|
TemplatePlaygroundServer.prototype.getHttpServer = function () {
|
|
var _a;
|
|
// Polka stores the actual HTTP server in the .server property
|
|
// This is needed for Supertest compatibility which expects a Node.js HTTP server
|
|
return ((_a = this.server) === null || _a === void 0 ? void 0 : _a.server) || null;
|
|
};
|
|
TemplatePlaygroundServer.prototype.setupSignalHandlers = function () {
|
|
var _this = this;
|
|
// Skip signal handlers entirely in test environment to prevent memory leaks
|
|
if (process.env.NODE_ENV === 'test') {
|
|
return;
|
|
}
|
|
// Handle CTRL+C (SIGINT) and other termination signals
|
|
var signals = ['SIGINT', 'SIGTERM', 'SIGUSR2'];
|
|
signals.forEach(function (signal) {
|
|
var handler = function () { return logger.__awaiter(_this, void 0, void 0, function () {
|
|
var error_1;
|
|
return logger.__generator(this, function (_a) {
|
|
switch (_a.label) {
|
|
case 0:
|
|
logger.logger.info("Received ".concat(signal, ", shutting down Template Playground server gracefully..."));
|
|
_a.label = 1;
|
|
case 1:
|
|
_a.trys.push([1, 3, , 4]);
|
|
return [4 /*yield*/, this.stop()];
|
|
case 2:
|
|
_a.sent();
|
|
logger.logger.info('Server shutdown complete');
|
|
process.exit(0);
|
|
return [3 /*break*/, 4];
|
|
case 3:
|
|
error_1 = _a.sent();
|
|
logger.logger.error('Error during server shutdown:', error_1);
|
|
process.exit(1);
|
|
return [3 /*break*/, 4];
|
|
case 4: return [2 /*return*/];
|
|
}
|
|
});
|
|
}); };
|
|
_this.signalHandlers.set(signal, handler);
|
|
process.on(signal, handler);
|
|
});
|
|
// Handle uncaught exceptions (only if not already handled)
|
|
if (process.listenerCount('uncaughtException') === 0) {
|
|
var uncaughtHandler = function (error) { return logger.__awaiter(_this, void 0, void 0, function () {
|
|
var stopError_1;
|
|
return logger.__generator(this, function (_a) {
|
|
switch (_a.label) {
|
|
case 0:
|
|
logger.logger.error('Uncaught exception:', error);
|
|
_a.label = 1;
|
|
case 1:
|
|
_a.trys.push([1, 3, , 4]);
|
|
return [4 /*yield*/, this.stop()];
|
|
case 2:
|
|
_a.sent();
|
|
return [3 /*break*/, 4];
|
|
case 3:
|
|
stopError_1 = _a.sent();
|
|
logger.logger.error('Error during emergency shutdown:', stopError_1);
|
|
return [3 /*break*/, 4];
|
|
case 4:
|
|
process.exit(1);
|
|
return [2 /*return*/];
|
|
}
|
|
});
|
|
}); };
|
|
this.signalHandlers.set('uncaughtException', uncaughtHandler);
|
|
process.on('uncaughtException', uncaughtHandler);
|
|
}
|
|
// Handle unhandled promise rejections (only if not already handled)
|
|
if (process.listenerCount('unhandledRejection') === 0) {
|
|
var rejectionHandler = function (reason, promise) { return logger.__awaiter(_this, void 0, void 0, function () {
|
|
var stopError_2;
|
|
return logger.__generator(this, function (_a) {
|
|
switch (_a.label) {
|
|
case 0:
|
|
logger.logger.error('Unhandled rejection at:', promise, 'reason:', reason);
|
|
_a.label = 1;
|
|
case 1:
|
|
_a.trys.push([1, 3, , 4]);
|
|
return [4 /*yield*/, this.stop()];
|
|
case 2:
|
|
_a.sent();
|
|
return [3 /*break*/, 4];
|
|
case 3:
|
|
stopError_2 = _a.sent();
|
|
logger.logger.error('Error during emergency shutdown:', stopError_2);
|
|
return [3 /*break*/, 4];
|
|
case 4:
|
|
process.exit(1);
|
|
return [2 /*return*/];
|
|
}
|
|
});
|
|
}); };
|
|
this.signalHandlers.set('unhandledRejection', rejectionHandler);
|
|
process.on('unhandledRejection', rejectionHandler);
|
|
}
|
|
};
|
|
TemplatePlaygroundServer.prototype.setupPaths = function () {
|
|
// Try to find paths for distributed package first, then fall back to development paths
|
|
// For playground-demo: check resources/playground-demo first, then src directory
|
|
var distributedFakeProjectPath = path__namespace.join(__dirname, 'resources', 'playground-demo');
|
|
var devFakeProjectPath = path__namespace.join(process.cwd(), 'src', 'playground-demo');
|
|
if (fs__namespace.existsSync(distributedFakeProjectPath)) {
|
|
this.fakeProjectPath = distributedFakeProjectPath;
|
|
}
|
|
else if (fs__namespace.existsSync(devFakeProjectPath)) {
|
|
this.fakeProjectPath = devFakeProjectPath;
|
|
}
|
|
else {
|
|
throw new Error('playground-demo directory not found. Please ensure it exists.');
|
|
}
|
|
// For templates: check if we're running from dist (distributed) or development
|
|
var distributedTemplatesPath = path__namespace.join(__dirname, 'templates'); // When running from dist/, this is dist/templates
|
|
var devTemplatesPath = path__namespace.join(process.cwd(), 'src', 'templates');
|
|
var legacyTemplatesPath = path__namespace.join(process.cwd(), 'hbs-templates-copy');
|
|
if (fs__namespace.existsSync(distributedTemplatesPath)) {
|
|
this.originalTemplatesPath = distributedTemplatesPath;
|
|
}
|
|
else if (fs__namespace.existsSync(devTemplatesPath)) {
|
|
this.originalTemplatesPath = devTemplatesPath;
|
|
}
|
|
else if (fs__namespace.existsSync(legacyTemplatesPath)) {
|
|
// Keep legacy support for existing hbs-templates-copy
|
|
this.originalTemplatesPath = legacyTemplatesPath;
|
|
}
|
|
else {
|
|
throw new Error('Templates directory not found. Please ensure src/templates or dist/templates exists.');
|
|
}
|
|
};
|
|
TemplatePlaygroundServer.prototype.getClientIP = function (req) {
|
|
var _a;
|
|
// Get IP address from various headers (handles proxies, load balancers, etc.)
|
|
var forwarded = req.headers['x-forwarded-for'];
|
|
var realIP = req.headers['x-real-ip'];
|
|
var remoteAddr = ((_a = req.socket) === null || _a === void 0 ? void 0 : _a.remoteAddress) || 'unknown';
|
|
var ip = (forwarded === null || forwarded === void 0 ? void 0 : forwarded.split(',')[0]) || realIP || remoteAddr || 'unknown';
|
|
// Clean up IPv6 localhost
|
|
if (ip === '::1' || ip === '::ffff:127.0.0.1') {
|
|
ip = '127.0.0.1';
|
|
}
|
|
return ip;
|
|
};
|
|
TemplatePlaygroundServer.prototype.generateSessionIdFromIP = function (ip) {
|
|
// Create a consistent hash from IP address
|
|
return crypto__namespace.createHash('md5').update(ip + 'template-playground-salt').digest('hex');
|
|
};
|
|
TemplatePlaygroundServer.prototype.createOrGetSessionByIP = function (ip) {
|
|
// Check if session already exists for this IP
|
|
var existingSessionId = this.ipToSessionId.get(ip);
|
|
if (existingSessionId && this.sessions.has(existingSessionId)) {
|
|
var session_1 = this.sessions.get(existingSessionId);
|
|
// Update last activity
|
|
session_1.lastActivity = Date.now();
|
|
logger.logger.info("\u267B\uFE0F Reusing existing session for IP ".concat(ip, ": ").concat(existingSessionId));
|
|
return session_1;
|
|
}
|
|
// Create new session
|
|
var sessionId = this.generateSessionIdFromIP(ip);
|
|
var templateDir = path__namespace.join(os__namespace.tmpdir(), "hbs-templates-copy-".concat(sessionId));
|
|
var documentationDir = path__namespace.join(os__namespace.tmpdir(), "generated-documentation-".concat(sessionId));
|
|
// Clean up any existing directories from previous sessions
|
|
if (fs__namespace.existsSync(templateDir)) {
|
|
fs__namespace.removeSync(templateDir);
|
|
}
|
|
if (fs__namespace.existsSync(documentationDir)) {
|
|
fs__namespace.removeSync(documentationDir);
|
|
}
|
|
// Copy original templates to session directory
|
|
fs__namespace.copySync(this.originalTemplatesPath, templateDir);
|
|
fs__namespace.ensureDirSync(documentationDir);
|
|
var session = {
|
|
id: sessionId,
|
|
templateDir: templateDir,
|
|
documentationDir: documentationDir,
|
|
lastActivity: Date.now(),
|
|
config: {
|
|
hideGenerator: false,
|
|
disableSourceCode: false,
|
|
disableGraph: false,
|
|
disableCoverage: false,
|
|
disablePrivate: false,
|
|
disableProtected: false,
|
|
disableInternal: false
|
|
}
|
|
};
|
|
this.sessions.set(sessionId, session);
|
|
this.ipToSessionId.set(ip, sessionId);
|
|
logger.logger.info("\uD83C\uDD95 Created new session for IP ".concat(ip, ": ").concat(sessionId));
|
|
// Generate initial documentation (skip in test mode to avoid template issues)
|
|
if (process.env.NODE_ENV !== 'test') {
|
|
this.generateDocumentation(sessionId);
|
|
}
|
|
return session;
|
|
};
|
|
TemplatePlaygroundServer.prototype.createNewSession = function (ip) {
|
|
// Generate a unique session ID (not based on IP)
|
|
var sessionId = crypto__namespace.randomBytes(16).toString('hex');
|
|
var templateDir = path__namespace.join(os__namespace.tmpdir(), "hbs-templates-copy-".concat(sessionId));
|
|
var documentationDir = path__namespace.join(os__namespace.tmpdir(), "generated-documentation-".concat(sessionId));
|
|
// Clean up any existing directories from previous sessions
|
|
if (fs__namespace.existsSync(templateDir)) {
|
|
fs__namespace.removeSync(templateDir);
|
|
}
|
|
if (fs__namespace.existsSync(documentationDir)) {
|
|
fs__namespace.removeSync(documentationDir);
|
|
}
|
|
// Copy original templates to session directory
|
|
fs__namespace.copySync(this.originalTemplatesPath, templateDir);
|
|
fs__namespace.ensureDirSync(documentationDir);
|
|
var session = {
|
|
id: sessionId,
|
|
templateDir: templateDir,
|
|
documentationDir: documentationDir,
|
|
lastActivity: Date.now(),
|
|
config: {
|
|
hideGenerator: false,
|
|
disableSourceCode: false,
|
|
disableGraph: false,
|
|
disableCoverage: false,
|
|
disablePrivate: false,
|
|
disableProtected: false,
|
|
disableInternal: false,
|
|
disableFilePath: false,
|
|
disableOverview: false
|
|
}
|
|
};
|
|
this.sessions.set(sessionId, session);
|
|
// Don't update ipToSessionId mapping for new sessions to allow multiple sessions per IP
|
|
logger.logger.info("\uD83C\uDD95 Created new session for IP ".concat(ip, ": ").concat(sessionId));
|
|
// Generate initial documentation (skip in test mode to avoid template issues)
|
|
if (process.env.NODE_ENV !== 'test') {
|
|
this.generateDocumentation(sessionId);
|
|
}
|
|
return session;
|
|
};
|
|
TemplatePlaygroundServer.prototype.updateSessionActivity = function (sessionId) {
|
|
var session = this.sessions.get(sessionId);
|
|
if (session) {
|
|
session.lastActivity = Date.now();
|
|
}
|
|
};
|
|
TemplatePlaygroundServer.prototype.generateDocumentation = function (sessionId, debounce) {
|
|
var _this = this;
|
|
if (debounce === void 0) { debounce = false; }
|
|
if (debounce) {
|
|
// Clear existing timer
|
|
var existingTimer = this.debounceTimers.get(sessionId);
|
|
if (existingTimer) {
|
|
clearTimeout(existingTimer);
|
|
}
|
|
// Set new timer for 300ms
|
|
var timer = setTimeout(function () {
|
|
_this.runCompoDocForSession(sessionId);
|
|
_this.debounceTimers.delete(sessionId);
|
|
}, 300);
|
|
this.debounceTimers.set(sessionId, timer);
|
|
}
|
|
else {
|
|
// Generate immediately
|
|
this.runCompoDocForSession(sessionId);
|
|
}
|
|
};
|
|
TemplatePlaygroundServer.prototype.runCompoDocForSession = function (sessionId) {
|
|
return logger.__awaiter(this, void 0, void 0, function () {
|
|
var session, fakeProjectTsConfigPath, cliPath, cmd, config, booleanFlags, valueFlags, booleanFlags_1, booleanFlags_1_1, flag, valueFlags_1, valueFlags_1_1, flag, value, fullCmd;
|
|
var e_1, _a, e_2, _b;
|
|
return logger.__generator(this, function (_c) {
|
|
session = this.sessions.get(sessionId);
|
|
if (!session) {
|
|
logger.logger.error("Session ".concat(sessionId, " not found"));
|
|
return [2 /*return*/];
|
|
}
|
|
try {
|
|
logger.logger.info("\uD83D\uDE80 Generating documentation for session ".concat(sessionId));
|
|
fakeProjectTsConfigPath = path__namespace.join(this.fakeProjectPath, 'tsconfig.json');
|
|
cliPath = path__namespace.resolve(process.cwd(), 'bin', 'index-cli.js');
|
|
// In test mode, check if CLI exists before proceeding
|
|
if (process.env.NODE_ENV === 'test' && !fs__namespace.existsSync(cliPath)) {
|
|
logger.logger.warn("CLI not found in test environment: ".concat(cliPath, ". Skipping documentation generation."));
|
|
session.documentationGenerated = true; // Mark as generated to avoid retries
|
|
return [2 /*return*/];
|
|
}
|
|
cmd = [
|
|
"node \"".concat(cliPath, "\""),
|
|
"-p \"".concat(fakeProjectTsConfigPath, "\""),
|
|
"-d \"".concat(session.documentationDir, "\""),
|
|
"--templates \"".concat(session.templateDir, "\"")
|
|
];
|
|
config = session.config || {};
|
|
booleanFlags = [
|
|
'hideGenerator', 'disableSourceCode', 'disableGraph', 'disableCoverage', 'disablePrivate', 'disableProtected', 'disableInternal',
|
|
'disableLifeCycleHooks', 'disableConstructors', 'disableRoutesGraph', 'disableSearch', 'disableDependencies', 'disableProperties',
|
|
'disableDomTree', 'disableTemplateTab', 'disableStyleTab', 'disableMainGraph', 'disableFilePath', 'disableOverview', 'hideDarkModeToggle', 'minimal', 'serve', 'open', 'watch', 'silent',
|
|
'coverageTest', 'coverageTestThresholdFail', 'coverageTestShowOnlyFailed'
|
|
];
|
|
valueFlags = [
|
|
'theme', 'language', 'base', 'customFavicon', 'customLogo', 'assetsFolder', 'extTheme', 'includes', 'includesName', 'output', 'port', 'hostname',
|
|
'exportFormat', 'coverageTestThreshold', 'coverageMinimumPerFile', 'unitTestCoverage', 'gaID', 'gaSite', 'maxSearchResults', 'toggleMenuItems', 'navTabConfig'
|
|
];
|
|
try {
|
|
for (booleanFlags_1 = logger.__values(booleanFlags), booleanFlags_1_1 = booleanFlags_1.next(); !booleanFlags_1_1.done; booleanFlags_1_1 = booleanFlags_1.next()) {
|
|
flag = booleanFlags_1_1.value;
|
|
if (config[flag] === true) {
|
|
cmd.push("--".concat(flag));
|
|
}
|
|
}
|
|
}
|
|
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
finally {
|
|
try {
|
|
if (booleanFlags_1_1 && !booleanFlags_1_1.done && (_a = booleanFlags_1.return)) _a.call(booleanFlags_1);
|
|
}
|
|
finally { if (e_1) throw e_1.error; }
|
|
}
|
|
try {
|
|
for (valueFlags_1 = logger.__values(valueFlags), valueFlags_1_1 = valueFlags_1.next(); !valueFlags_1_1.done; valueFlags_1_1 = valueFlags_1.next()) {
|
|
flag = valueFlags_1_1.value;
|
|
if (config[flag] !== undefined && config[flag] !== "") {
|
|
value = config[flag];
|
|
// For arrays/objects, stringify
|
|
if (Array.isArray(value) || typeof value === 'object') {
|
|
value = JSON.stringify(value);
|
|
}
|
|
cmd.push("--".concat(flag, " \"").concat(value, "\""));
|
|
}
|
|
}
|
|
}
|
|
catch (e_2_1) { e_2 = { error: e_2_1 }; }
|
|
finally {
|
|
try {
|
|
if (valueFlags_1_1 && !valueFlags_1_1.done && (_b = valueFlags_1.return)) _b.call(valueFlags_1);
|
|
}
|
|
finally { if (e_2) throw e_2.error; }
|
|
}
|
|
fullCmd = cmd.join(' ');
|
|
logger.logger.info("\uD83D\uDE80 Executing CompoDoc command: ".concat(fullCmd));
|
|
// Log the command to a file for debugging
|
|
require('fs').appendFileSync('server-commands.log', "".concat(new Date().toISOString(), " - ").concat(fullCmd, "\n"));
|
|
// Execute with proper error handling (inherit stdio to see errors)
|
|
child_process.execSync(fullCmd, {
|
|
cwd: process.cwd(),
|
|
stdio: 'inherit' // Show output/errors instead of hiding them
|
|
});
|
|
this.updateSessionActivity(sessionId);
|
|
logger.logger.info("\u2705 Documentation generated successfully for session ".concat(sessionId));
|
|
}
|
|
catch (error) {
|
|
logger.logger.error("\u274C Error generating documentation for session ".concat(sessionId, ":"), error);
|
|
}
|
|
return [2 /*return*/];
|
|
});
|
|
});
|
|
};
|
|
TemplatePlaygroundServer.prototype.startSessionCleanup = function () {
|
|
var _this = this;
|
|
// Clean up sessions older than 1 hour every 10 minutes
|
|
this.cleanupInterval = setInterval(function () {
|
|
var e_3, _a;
|
|
var cutoffTime = Date.now() - (60 * 60 * 1000); // 1 hour ago
|
|
try {
|
|
for (var _b = logger.__values(_this.sessions.entries()), _c = _b.next(); !_c.done; _c = _b.next()) {
|
|
var _d = logger.__read(_c.value, 2), sessionId = _d[0], session = _d[1];
|
|
if (session.lastActivity < cutoffTime) {
|
|
_this.cleanupSession(sessionId);
|
|
}
|
|
}
|
|
}
|
|
catch (e_3_1) { e_3 = { error: e_3_1 }; }
|
|
finally {
|
|
try {
|
|
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
|
|
}
|
|
finally { if (e_3) throw e_3.error; }
|
|
}
|
|
}, 10 * 60 * 1000); // Every 10 minutes
|
|
};
|
|
TemplatePlaygroundServer.prototype.cleanupSession = function (sessionId) {
|
|
var e_4, _a;
|
|
var session = this.sessions.get(sessionId);
|
|
if (session) {
|
|
try {
|
|
// Remove directories
|
|
if (fs__namespace.existsSync(session.templateDir)) {
|
|
fs__namespace.removeSync(session.templateDir);
|
|
}
|
|
if (fs__namespace.existsSync(session.documentationDir)) {
|
|
fs__namespace.removeSync(session.documentationDir);
|
|
}
|
|
// Clear timer if exists
|
|
var timer = this.debounceTimers.get(sessionId);
|
|
if (timer) {
|
|
clearTimeout(timer);
|
|
this.debounceTimers.delete(sessionId);
|
|
}
|
|
try {
|
|
// Remove IP mapping
|
|
for (var _b = logger.__values(this.ipToSessionId.entries()), _c = _b.next(); !_c.done; _c = _b.next()) {
|
|
var _d = logger.__read(_c.value, 2), ip = _d[0], id = _d[1];
|
|
if (id === sessionId) {
|
|
this.ipToSessionId.delete(ip);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
catch (e_4_1) { e_4 = { error: e_4_1 }; }
|
|
finally {
|
|
try {
|
|
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
|
|
}
|
|
finally { if (e_4) throw e_4.error; }
|
|
}
|
|
this.sessions.delete(sessionId);
|
|
logger.logger.info("\uD83E\uDDF9 Cleaned up session: ".concat(sessionId));
|
|
}
|
|
catch (error) {
|
|
logger.logger.error("Error cleaning up session ".concat(sessionId, ":"), error);
|
|
}
|
|
}
|
|
};
|
|
TemplatePlaygroundServer.prototype.initializeHandlebars = function () {
|
|
this.handlebars = require('handlebars');
|
|
this.registerHandlebarsHelpers(this.handlebars, {});
|
|
};
|
|
TemplatePlaygroundServer.prototype.registerAvailablePartials = function () {
|
|
return logger.__awaiter(this, void 0, void 0, function () {
|
|
var partialsDir, partialFiles, partialFiles_1, partialFiles_1_1, file, partialName, partialPath, partialContent;
|
|
var e_5, _a;
|
|
return logger.__generator(this, function (_b) {
|
|
try {
|
|
partialsDir = path__namespace.join(process.cwd(), 'dist/templates/partials');
|
|
logger.logger.info("\uD83D\uDD0D Looking for partials in: ".concat(partialsDir));
|
|
logger.logger.info("\uD83D\uDD0D Partials directory exists: ".concat(fs__namespace.existsSync(partialsDir)));
|
|
if (fs__namespace.existsSync(partialsDir)) {
|
|
partialFiles = fs__namespace.readdirSync(partialsDir).filter(function (file) { return file.endsWith('.hbs'); });
|
|
logger.logger.info("\uD83D\uDCC1 Found ".concat(partialFiles.length, " partial files: ").concat(JSON.stringify(partialFiles)));
|
|
try {
|
|
for (partialFiles_1 = logger.__values(partialFiles), partialFiles_1_1 = partialFiles_1.next(); !partialFiles_1_1.done; partialFiles_1_1 = partialFiles_1.next()) {
|
|
file = partialFiles_1_1.value;
|
|
partialName = file.replace('.hbs', '');
|
|
partialPath = path__namespace.join(partialsDir, file);
|
|
partialContent = fs__namespace.readFileSync(partialPath, 'utf8');
|
|
// Register the partial
|
|
this.handlebars.registerPartial(partialName, partialContent);
|
|
logger.logger.info("\u2705 Registered partial: ".concat(partialName));
|
|
}
|
|
}
|
|
catch (e_5_1) { e_5 = { error: e_5_1 }; }
|
|
finally {
|
|
try {
|
|
if (partialFiles_1_1 && !partialFiles_1_1.done && (_a = partialFiles_1.return)) _a.call(partialFiles_1);
|
|
}
|
|
finally { if (e_5) throw e_5.error; }
|
|
}
|
|
}
|
|
else {
|
|
logger.logger.warn("\u26A0\uFE0F Partials directory not found at: ".concat(partialsDir));
|
|
}
|
|
}
|
|
catch (error) {
|
|
logger.logger.error("\u274C Error registering partials:", error);
|
|
}
|
|
return [2 /*return*/];
|
|
});
|
|
});
|
|
};
|
|
TemplatePlaygroundServer.prototype.setupMiddleware = function () {
|
|
// Add request logging for debugging
|
|
this.app.use(function (req, res, next) {
|
|
var headers = req.headers;
|
|
logger.logger.info("\uD83D\uDD0D REQUEST: ".concat(req.method, " ").concat(req.url, " - User-Agent: ").concat(headers['user-agent'] || 'unknown'));
|
|
next();
|
|
});
|
|
// Enable CORS for development
|
|
this.app.use(function (req, res, next) {
|
|
res.setHeader('Access-Control-Allow-Origin', '*');
|
|
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
|
|
res.setHeader('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept, Authorization');
|
|
if (req.method === 'OPTIONS') {
|
|
res.statusCode = 200;
|
|
res.end();
|
|
}
|
|
else {
|
|
next();
|
|
}
|
|
});
|
|
// Serve Compodoc resources at root level for relative path compatibility
|
|
// Try dist/resources first (production), then src/resources (development/testing)
|
|
var compodocResourcesPathDist = path__namespace.join(process.cwd(), 'dist/resources');
|
|
var compodocResourcesPathSrc = path__namespace.join(process.cwd(), 'src/resources');
|
|
var compodocResourcesPath = fs__namespace.existsSync(compodocResourcesPathDist) ? compodocResourcesPathDist : compodocResourcesPathSrc;
|
|
logger.logger.info("\uD83D\uDCC1 Setting up root-level static files from: ".concat(compodocResourcesPath));
|
|
logger.logger.info("\uD83D\uDCC1 Compodoc resources path exists: ".concat(fs__namespace.existsSync(compodocResourcesPath)));
|
|
// Serve styles, js, images, and other resources at root level using sirv
|
|
this.app.use('/styles', sirv(path__namespace.join(compodocResourcesPath, 'styles'), { dev: true }));
|
|
this.app.use('/js', sirv(path__namespace.join(compodocResourcesPath, 'js'), { dev: true }));
|
|
this.app.use('/images', sirv(path__namespace.join(compodocResourcesPath, 'images'), { dev: true }));
|
|
this.app.use('/fonts', sirv(path__namespace.join(compodocResourcesPath, 'fonts'), { dev: true }));
|
|
// Serve Compodoc resources under /resources path as well (for backward compatibility)
|
|
this.app.use('/resources', sirv(compodocResourcesPath, { dev: true }));
|
|
// Serve static files from template playground directory (index.html, app.js)
|
|
// Try dist/resources first (production), then src/resources (development/testing)
|
|
var playgroundStaticPathDist = path__namespace.join(process.cwd(), 'dist/resources/template-playground-app');
|
|
var playgroundStaticPathSrc = path__namespace.join(process.cwd(), 'src/resources/template-playground-app');
|
|
var playgroundStaticPath = fs__namespace.existsSync(playgroundStaticPathDist) ? playgroundStaticPathDist : playgroundStaticPathSrc;
|
|
logger.logger.info("\uD83D\uDCC1 Setting up playground static files from: ".concat(playgroundStaticPath));
|
|
logger.logger.info("\uD83D\uDCC1 Playground static path exists: ".concat(fs__namespace.existsSync(playgroundStaticPath)));
|
|
this.app.use(sirv(playgroundStaticPath, { dev: true }));
|
|
// Parse JSON bodies and form data using body-parser
|
|
this.app.use(json({ limit: '10mb' }));
|
|
this.app.use(urlencoded({ extended: true, limit: '10mb' }));
|
|
};
|
|
TemplatePlaygroundServer.prototype.setupRoutes = function () {
|
|
var _this = this;
|
|
// API route to get available templates
|
|
this.app.get('/api/templates', this.getTemplates.bind(this));
|
|
// API route to get template content
|
|
this.app.get('/api/templates/:templateName', this.getTemplate.bind(this));
|
|
// API route to get example data
|
|
this.app.get('/api/example-data/:dataType', this.getExampleData.bind(this));
|
|
// API route to render template with custom data
|
|
this.app.post('/api/render', this.renderTemplate.bind(this));
|
|
// API route to render complete page with template
|
|
this.app.post('/api/render-page', this.renderCompletePage.bind(this));
|
|
// API route to generate documentation with CompoDoc CLI
|
|
this.app.post('/api/generate-docs', this.generateDocs.bind(this));
|
|
// API route to download template package
|
|
this.app.post('/api/download-template', this.downloadTemplatePackage.bind(this));
|
|
// API route to download template ZIP (server-side creation)
|
|
this.app.post('/api/session/:sessionId/download-zip', this.downloadSessionTemplateZip.bind(this));
|
|
this.app.post('/api/session/:sessionId/download-all-templates', this.downloadAllSessionTemplates.bind(this));
|
|
this.app.get('/api/session/:sessionId/download/all', this.downloadAllSessionTemplates.bind(this)); // Alias for compatibility
|
|
// Session management API routes
|
|
this.app.post('/api/session', this.createSessionAPI.bind(this));
|
|
this.app.post('/api/session/create', this.createSessionAPI.bind(this));
|
|
this.app.get('/api/session/:sessionId/templates', this.getSessionTemplates.bind(this));
|
|
this.app.get('/api/session/:sessionId/template/*', this.getSessionTemplate.bind(this));
|
|
this.app.post('/api/session/:sessionId/template/*', this.saveSessionTemplate.bind(this));
|
|
this.app.get('/api/session/:sessionId/template-data/*', this.getSessionTemplateData.bind(this));
|
|
this.app.post('/api/session/:sessionId/generate-docs', this.generateSessionDocs.bind(this));
|
|
this.app.post('/api/session/:sessionId/generate', this.generateSessionDocs.bind(this)); // Alias for compatibility
|
|
this.app.get('/api/session/:sessionId/config', this.getSessionConfig.bind(this));
|
|
this.app.post('/api/session/:sessionId/config', this.updateSessionConfig.bind(this));
|
|
// Serve session-specific generated documentation
|
|
this.app.get('/api/session/:sessionId/docs/*', this.serveSessionDocs.bind(this));
|
|
// Serve session-specific generated documentation at the expected URL pattern
|
|
// These routes MUST come before the catch-all route
|
|
this.app.get('/docs/:sessionId/index.html', function (req, res) {
|
|
logger.logger.info("\uD83D\uDD0D Docs index route hit: /docs/".concat(req.params.sessionId, "/index.html"));
|
|
var sessionId = req.params.sessionId;
|
|
var session = _this.sessions.get(sessionId);
|
|
if (!session) {
|
|
logger.logger.error("\u274C Session not found: ".concat(sessionId));
|
|
send(res, 404, { success: false, message: 'Session not found' });
|
|
return;
|
|
}
|
|
_this.updateSessionActivity(sessionId);
|
|
var fullPath = path__namespace.join(session.documentationDir, 'index.html');
|
|
logger.logger.info("\uD83D\uDCC2 Looking for file: ".concat(fullPath));
|
|
if (fs__namespace.existsSync(fullPath)) {
|
|
logger.logger.info("\u2705 Serving file: ".concat(fullPath));
|
|
var content = fs__namespace.readFileSync(fullPath);
|
|
res.setHeader('Content-Type', 'text/html');
|
|
res.end(content);
|
|
}
|
|
else {
|
|
logger.logger.error("\u274C File not found: ".concat(fullPath));
|
|
res.statusCode = 404;
|
|
res.end('Documentation file not found');
|
|
}
|
|
});
|
|
// Serve any file within session documentation using dynamic sirv middleware
|
|
this.app.get('/docs/:sessionId/*', function (req, res) {
|
|
var sessionId = req.params.sessionId;
|
|
var session = _this.sessions.get(sessionId);
|
|
if (!session) {
|
|
logger.logger.error("\u274C Session not found: ".concat(sessionId));
|
|
send(res, 404, { success: false, message: 'Session not found' });
|
|
return;
|
|
}
|
|
_this.updateSessionActivity(sessionId);
|
|
// Use sirv to serve files from the session documentation directory
|
|
var sessionSirv = sirv(session.documentationDir, {
|
|
dev: true,
|
|
single: false,
|
|
setHeaders: function (res, pathname) {
|
|
logger.logger.info("\u2705 Serving file via sirv: ".concat(pathname));
|
|
}
|
|
});
|
|
// Remove the session prefix from the URL for sirv
|
|
var originalUrl = req.url;
|
|
var sessionPrefix = "/docs/".concat(sessionId);
|
|
if (originalUrl && originalUrl.startsWith(sessionPrefix)) {
|
|
req.url = originalUrl.substring(sessionPrefix.length) || '/';
|
|
logger.logger.info("\uD83D\uDD0D Sirv serving: ".concat(req.url, " from ").concat(session.documentationDir));
|
|
}
|
|
sessionSirv(req, res, function () {
|
|
// If sirv doesn't handle it, restore original URL and return 404
|
|
req.url = originalUrl;
|
|
logger.logger.error("\u274C File not found in session docs: ".concat(req.url));
|
|
res.statusCode = 404;
|
|
res.end('Documentation file not found');
|
|
});
|
|
});
|
|
// Handle direct access to session documentation root (index.html)
|
|
this.app.get('/docs/:sessionId', function (req, res) {
|
|
logger.logger.info("\uD83D\uDD0D Docs root route hit: /docs/".concat(req.params.sessionId));
|
|
var sessionId = req.params.sessionId;
|
|
var session = _this.sessions.get(sessionId);
|
|
if (!session) {
|
|
logger.logger.error("\u274C Session not found: ".concat(sessionId));
|
|
send(res, 404, { success: false, message: 'Session not found' });
|
|
return;
|
|
}
|
|
_this.updateSessionActivity(sessionId);
|
|
var fullPath = path__namespace.join(session.documentationDir, 'index.html');
|
|
logger.logger.info("\uD83D\uDCC2 Looking for file: ".concat(fullPath));
|
|
if (fs__namespace.existsSync(fullPath)) {
|
|
logger.logger.info("\u2705 Serving file: ".concat(fullPath));
|
|
var content = fs__namespace.readFileSync(fullPath);
|
|
res.setHeader('Content-Type', 'text/html');
|
|
res.end(content);
|
|
}
|
|
else {
|
|
logger.logger.error("\u274C File not found: ".concat(fullPath));
|
|
res.statusCode = 404;
|
|
res.end('Documentation file not found');
|
|
}
|
|
});
|
|
// Serve generated documentation files (legacy) - MUST come after session-specific routes
|
|
// TEMPORARILY COMMENTED OUT TO TEST SESSION ROUTES
|
|
// this.app.use('/docs', express.static(this.fakeProjectPath)); // Serve generated docs from playground-demo
|
|
// Serve the main playground app for root path only
|
|
this.app.get('/', function (req, res) {
|
|
// Try dist/resources first (production), then src/resources (development/testing)
|
|
var indexPathDist = path__namespace.join(process.cwd(), 'dist/resources/template-playground-app/index.html');
|
|
var indexPathSrc = path__namespace.join(process.cwd(), 'src/resources/template-playground-app/index.html');
|
|
var indexPath = fs__namespace.existsSync(indexPathDist) ? indexPathDist : indexPathSrc;
|
|
if (fs__namespace.existsSync(indexPath)) {
|
|
var content = fs__namespace.readFileSync(indexPath);
|
|
res.setHeader('Content-Type', 'text/html');
|
|
res.end(content);
|
|
}
|
|
else {
|
|
res.statusCode = 404;
|
|
res.end('Template Playground not built. Please run the build process.');
|
|
}
|
|
});
|
|
// Handle any remaining non-API routes by serving the main app (for SPA routing)
|
|
// Note: This catch-all route should be last and will handle all unmatched routes
|
|
this.app.get('*', function (req, res) {
|
|
// Skip API, resources, and docs routes as they are handled above
|
|
if (req.url.startsWith('/api') || req.url.startsWith('/resources') || req.url.startsWith('/docs')) {
|
|
res.statusCode = 404;
|
|
res.end('Not Found');
|
|
return;
|
|
}
|
|
logger.logger.warn("\u26A0\uFE0F CATCH-ALL ROUTE HIT: ".concat(req.method, " ").concat(req.url));
|
|
// Try dist/resources first (production), then src/resources (development/testing)
|
|
var indexPathDist = path__namespace.join(process.cwd(), 'dist/resources/template-playground-app/index.html');
|
|
var indexPathSrc = path__namespace.join(process.cwd(), 'src/resources/template-playground-app/index.html');
|
|
var indexPath = fs__namespace.existsSync(indexPathDist) ? indexPathDist : indexPathSrc;
|
|
if (fs__namespace.existsSync(indexPath)) {
|
|
var content = fs__namespace.readFileSync(indexPath);
|
|
res.setHeader('Content-Type', 'text/html');
|
|
res.end(content);
|
|
}
|
|
else {
|
|
res.statusCode = 404;
|
|
res.end('Template Playground not built. Please run the build process.');
|
|
}
|
|
});
|
|
};
|
|
TemplatePlaygroundServer.prototype.getTemplates = function (req, res) {
|
|
return logger.__awaiter(this, void 0, void 0, function () {
|
|
var templatesDir_1, files, templates, error_2;
|
|
return logger.__generator(this, function (_a) {
|
|
switch (_a.label) {
|
|
case 0:
|
|
_a.trys.push([0, 2, , 3]);
|
|
templatesDir_1 = path__namespace.join(process.cwd(), 'dist/templates/partials');
|
|
return [4 /*yield*/, fs__namespace.readdir(templatesDir_1)];
|
|
case 1:
|
|
files = _a.sent();
|
|
templates = files
|
|
.filter(function (file) { return file.endsWith('.hbs'); })
|
|
.map(function (file) { return ({
|
|
name: file.replace('.hbs', ''),
|
|
filename: file,
|
|
path: path__namespace.join(templatesDir_1, file)
|
|
}); });
|
|
send(res, 200, templates);
|
|
return [3 /*break*/, 3];
|
|
case 2:
|
|
error_2 = _a.sent();
|
|
logger.logger.error('Error reading templates:', error_2);
|
|
send(res, 500, { error: 'Failed to read templates' });
|
|
return [3 /*break*/, 3];
|
|
case 3: return [2 /*return*/];
|
|
}
|
|
});
|
|
});
|
|
};
|
|
TemplatePlaygroundServer.prototype.getTemplate = function (req, res) {
|
|
return logger.__awaiter(this, void 0, void 0, function () {
|
|
var templateName, templatePath, content, error_3;
|
|
return logger.__generator(this, function (_a) {
|
|
switch (_a.label) {
|
|
case 0:
|
|
_a.trys.push([0, 3, , 4]);
|
|
templateName = req.params.templateName;
|
|
templatePath = path__namespace.join(process.cwd(), 'dist/templates/partials', "".concat(templateName, ".hbs"));
|
|
return [4 /*yield*/, fs__namespace.pathExists(templatePath)];
|
|
case 1:
|
|
if (!(_a.sent())) {
|
|
send(res, 404, { error: 'Template not found' });
|
|
return [2 /*return*/];
|
|
}
|
|
return [4 /*yield*/, fs__namespace.readFile(templatePath, 'utf-8')];
|
|
case 2:
|
|
content = _a.sent();
|
|
send(res, 200, {
|
|
name: templateName,
|
|
content: content,
|
|
path: templatePath
|
|
});
|
|
return [3 /*break*/, 4];
|
|
case 3:
|
|
error_3 = _a.sent();
|
|
logger.logger.error('Error reading template:', error_3);
|
|
send(res, 500, { error: 'Failed to read template' });
|
|
return [3 /*break*/, 4];
|
|
case 4: return [2 /*return*/];
|
|
}
|
|
});
|
|
});
|
|
};
|
|
TemplatePlaygroundServer.prototype.getExampleData = function (req, res) {
|
|
return logger.__awaiter(this, void 0, void 0, function () {
|
|
var dataType, _a, EXAMPLE_DATA, TEMPLATE_CONTEXT, wrappedData, error_4;
|
|
var _b;
|
|
return logger.__generator(this, function (_c) {
|
|
switch (_c.label) {
|
|
case 0:
|
|
_c.trys.push([0, 2, , 3]);
|
|
dataType = req.params.dataType;
|
|
return [4 /*yield*/, Promise.resolve().then(function () { return require('./example-data-DR3xY3Rr.js'); })];
|
|
case 1:
|
|
_a = _c.sent(), EXAMPLE_DATA = _a.EXAMPLE_DATA, TEMPLATE_CONTEXT = _a.TEMPLATE_CONTEXT;
|
|
if (!EXAMPLE_DATA[dataType]) {
|
|
send(res, 404, { error: 'Example data type not found' });
|
|
return [2 /*return*/];
|
|
}
|
|
wrappedData = dataType === 'component' || dataType === 'directive' || dataType === 'pipe' ||
|
|
dataType === 'guard' || dataType === 'interceptor' || dataType === 'injectable' ||
|
|
dataType === 'class' || dataType === 'interface' || dataType === 'entity' ? logger.__assign((_b = {}, _b[dataType] = EXAMPLE_DATA[dataType], _b), EXAMPLE_DATA[dataType]) :
|
|
EXAMPLE_DATA[dataType];
|
|
send(res, 200, {
|
|
data: wrappedData,
|
|
context: TEMPLATE_CONTEXT
|
|
});
|
|
return [3 /*break*/, 3];
|
|
case 2:
|
|
error_4 = _c.sent();
|
|
logger.logger.error('Error getting example data:', error_4);
|
|
send(res, 500, { error: 'Failed to get example data' });
|
|
return [3 /*break*/, 3];
|
|
case 3: return [2 /*return*/];
|
|
}
|
|
});
|
|
});
|
|
};
|
|
TemplatePlaygroundServer.prototype.renderTemplate = function (req, res) {
|
|
return logger.__awaiter(this, void 0, void 0, function () {
|
|
var _a, templateContent, templateData, templateContext, template, rendered;
|
|
return logger.__generator(this, function (_b) {
|
|
try {
|
|
_a = req.body, templateContent = _a.templateContent, templateData = _a.templateData, templateContext = _a.templateContext;
|
|
if (!templateContent) {
|
|
send(res, 400, { error: 'Template content is required' });
|
|
return [2 /*return*/];
|
|
}
|
|
template = this.handlebars.compile(templateContent);
|
|
rendered = template(templateData || {});
|
|
send(res, 200, { rendered: rendered });
|
|
}
|
|
catch (error) {
|
|
logger.logger.error('Error rendering template:', error);
|
|
send(res, 500, {
|
|
error: 'Failed to render template',
|
|
details: error.message
|
|
});
|
|
}
|
|
return [2 /*return*/];
|
|
});
|
|
});
|
|
};
|
|
TemplatePlaygroundServer.prototype.renderCompletePage = function (req, res) {
|
|
return logger.__awaiter(this, void 0, void 0, function () {
|
|
var _a, templateContent, templateData, templateContext, renderedContent, completePage;
|
|
return logger.__generator(this, function (_b) {
|
|
try {
|
|
_a = req.body, templateContent = _a.templateContent, templateData = _a.templateData, templateContext = _a.templateContext;
|
|
// Handle form data by parsing JSON strings
|
|
if (typeof templateData === 'string') {
|
|
try {
|
|
templateData = JSON.parse(templateData);
|
|
}
|
|
catch (e) {
|
|
templateData = {};
|
|
}
|
|
}
|
|
if (typeof templateContext === 'string') {
|
|
try {
|
|
templateContext = JSON.parse(templateContext);
|
|
}
|
|
catch (e) {
|
|
templateContext = {};
|
|
}
|
|
}
|
|
if (!templateContent) {
|
|
send(res, 400, { error: 'Template content is required' });
|
|
return [2 /*return*/];
|
|
}
|
|
renderedContent = this.generateCompodocHtml(templateData || {});
|
|
completePage = "<!doctype html>\n<html class=\"no-js\" lang=\"\">\n <head>\n <meta charset=\"utf-8\">\n <meta http-equiv=\"x-ua-compatible\" content=\"ie=edge\">\n <title>Template Preview - Compodoc</title>\n <meta name=\"description\" content=\"\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n\n <link rel=\"icon\" type=\"image/x-icon\" href=\"/resources/images/favicon.ico\">\n <link rel=\"stylesheet\" href=\"/resources/styles/bootstrap.min.css\">\n <link rel=\"stylesheet\" href=\"/resources/styles/compodoc.css\">\n <link rel=\"stylesheet\" href=\"/resources/styles/prism.css\">\n <link rel=\"stylesheet\" href=\"/resources/styles/dark.css\">\n <link rel=\"stylesheet\" href=\"/resources/styles/style.css\">\n </head>\n <body>\n <script>\n // Blocking script to avoid flickering dark mode\n var useDark = window.matchMedia('(prefers-color-scheme: dark)');\n var darkModeState = useDark.matches;\n var darkModeStateLocal = localStorage.getItem('compodoc_darkmode-state');\n if (darkModeStateLocal) {\n darkModeState = darkModeStateLocal === 'true';\n }\n if (darkModeState) {\n document.body.classList.add('dark');\n }\n </script>\n\n <div class=\"container-fluid main\">\n <!-- START CONTENT -->\n <div class=\"content component\">\n <div class=\"content-data\">\n ".concat(renderedContent, "\n </div>\n </div>\n <!-- END CONTENT -->\n </div>\n\n <script>\n var COMPODOC_CURRENT_PAGE_DEPTH = 0;\n var COMPODOC_CURRENT_PAGE_CONTEXT = 'component';\n var COMPODOC_CURRENT_PAGE_URL = 'component.html';\n </script>\n\n <script src=\"/resources/js/libs/bootstrap-native.js\"></script>\n <script src=\"/resources/js/libs/prism.js\"></script>\n <script src=\"/resources/js/compodoc.js\"></script>\n <script src=\"/resources/js/tabs.js\"></script>\n <script src=\"/resources/js/sourceCode.js\"></script>\n </body>\n</html>");
|
|
res.setHeader('Content-Type', 'text/html');
|
|
res.end(completePage);
|
|
}
|
|
catch (error) {
|
|
logger.logger.error('Error rendering complete page:', error);
|
|
send(res, 500, {
|
|
error: 'Failed to render complete page',
|
|
details: error.message
|
|
});
|
|
}
|
|
return [2 /*return*/];
|
|
});
|
|
});
|
|
};
|
|
TemplatePlaygroundServer.prototype.generateDocs = function (req, res) {
|
|
return logger.__awaiter(this, void 0, void 0, function () {
|
|
var _a, customTemplateContent, mockData, clientIP, session, sessionId, templatePath, error_5;
|
|
return logger.__generator(this, function (_b) {
|
|
switch (_b.label) {
|
|
case 0:
|
|
_b.trys.push([0, 3, , 4]);
|
|
_a = req.body, customTemplateContent = _a.customTemplateContent, mockData = _a.mockData;
|
|
// Update mock data if provided
|
|
if (mockData) {
|
|
// This part of the logic needs to be adapted to work with the new session-based system
|
|
// For now, we'll just log that it's not directly applicable here
|
|
logger.logger.warn('mockData parameter is not directly applicable in this session-based system. It will be ignored.');
|
|
}
|
|
clientIP = this.getClientIP(req);
|
|
session = this.createOrGetSessionByIP(clientIP);
|
|
sessionId = session.id;
|
|
if (!(customTemplateContent && req.body.templatePath)) return [3 /*break*/, 2];
|
|
templatePath = path__namespace.join(session.templateDir, req.body.templatePath);
|
|
return [4 /*yield*/, fs__namespace.writeFile(templatePath, customTemplateContent, 'utf8')];
|
|
case 1:
|
|
_b.sent();
|
|
_b.label = 2;
|
|
case 2:
|
|
// Generate documentation for the new session
|
|
this.generateDocumentation(sessionId, true); // Use debounce
|
|
send(res, 200, { success: true, message: 'Documentation generation initiated for a new session', sessionId: sessionId });
|
|
return [3 /*break*/, 4];
|
|
case 3:
|
|
error_5 = _b.sent();
|
|
logger.logger.error('Error generating documentation:', error_5);
|
|
send(res, 500, {
|
|
error: 'Failed to generate documentation',
|
|
details: error_5.message
|
|
});
|
|
return [3 /*break*/, 4];
|
|
case 4: return [2 /*return*/];
|
|
}
|
|
});
|
|
});
|
|
};
|
|
TemplatePlaygroundServer.prototype.registerHandlebarsHelpers = function (Handlebars, context) {
|
|
// Register translation helper (matches Compodoc's i18n helper pattern)
|
|
Handlebars.registerHelper('t', function () {
|
|
console.log('T HELPER CALLED');
|
|
var key = arguments[0];
|
|
var translations = {
|
|
'components': 'Components',
|
|
'modules': 'Modules',
|
|
'interfaces': 'Interfaces',
|
|
'classes': 'Classes',
|
|
'injectables': 'Injectables',
|
|
'pipes': 'Pipes',
|
|
'directives': 'Directives',
|
|
'guards': 'Guards',
|
|
'interceptors': 'Interceptors',
|
|
'entities': 'Entities',
|
|
'controllers': 'Controllers',
|
|
'info': 'Info',
|
|
'readme': 'Readme',
|
|
'source': 'Source',
|
|
'template': 'Template',
|
|
'styles': 'Styles',
|
|
'dom-tree': 'DOM Tree',
|
|
'file': 'File',
|
|
'description': 'Description',
|
|
'implements': 'Implements',
|
|
'metadata': 'Metadata',
|
|
'index': 'Index',
|
|
'methods': 'Methods',
|
|
'properties': 'Properties'
|
|
};
|
|
return translations[key] || key;
|
|
});
|
|
// Register relative URL helper
|
|
Handlebars.registerHelper('relativeURL', function (depth) {
|
|
var args = [];
|
|
for (var _i = 1; _i < arguments.length; _i++) {
|
|
args[_i - 1] = arguments[_i];
|
|
}
|
|
var depthValue = typeof depth === 'number' ? depth : (context.depth || 0);
|
|
var baseUrl = '../'.repeat(depthValue);
|
|
var pathArgs = args.slice(0, -1); // Remove Handlebars options object
|
|
return baseUrl + pathArgs.join('/');
|
|
});
|
|
// Register comparison helper (matches Compodoc's CompareHelper implementation)
|
|
Handlebars.registerHelper('compare', function () {
|
|
var context = this;
|
|
var a = arguments[0];
|
|
var operator = arguments[1];
|
|
var b = arguments[2];
|
|
var options = arguments[3];
|
|
if (arguments.length < 4) {
|
|
throw new Error('handlebars Helper {{compare}} expects 4 arguments');
|
|
}
|
|
var result = false;
|
|
switch (operator) {
|
|
case 'indexof':
|
|
result = b.indexOf(a) !== -1;
|
|
break;
|
|
case '===':
|
|
result = a === b;
|
|
break;
|
|
case '!==':
|
|
result = a !== b;
|
|
break;
|
|
case '>':
|
|
result = a > b;
|
|
break;
|
|
case '<':
|
|
result = a < b;
|
|
break;
|
|
case '>=':
|
|
result = a >= b;
|
|
break;
|
|
case '<=':
|
|
result = a <= b;
|
|
break;
|
|
case '==':
|
|
result = a == b;
|
|
break;
|
|
case '!=':
|
|
result = a != b;
|
|
break;
|
|
default:
|
|
throw new Error('helper {{compare}}: invalid operator: `' + operator + '`');
|
|
}
|
|
if (result === false) {
|
|
return options.inverse(context);
|
|
}
|
|
return options.fn(context);
|
|
});
|
|
// Register tab helpers (matches Compodoc's IsTabEnabledHelper and IsInitialTabHelper)
|
|
Handlebars.registerHelper('isTabEnabled', function () {
|
|
var context = this;
|
|
var navTabs = arguments[0];
|
|
var tabId = arguments[1];
|
|
var options = arguments[2];
|
|
var isEnabled = navTabs && navTabs.some(function (tab) { return tab.id === tabId; });
|
|
if (isEnabled) {
|
|
return options.fn(context);
|
|
}
|
|
else {
|
|
return options.inverse(context);
|
|
}
|
|
});
|
|
Handlebars.registerHelper('isInitialTab', function () {
|
|
var navTabs = arguments[0];
|
|
var tabId = arguments[1];
|
|
var isInitial = navTabs && navTabs.length > 0 && navTabs[0].id === tabId;
|
|
if (isInitial) {
|
|
return 'active in';
|
|
}
|
|
return '';
|
|
});
|
|
// Register utility helpers
|
|
Handlebars.registerHelper('orLength', function () {
|
|
var args = [];
|
|
for (var _i = 0; _i < arguments.length; _i++) {
|
|
args[_i] = arguments[_i];
|
|
}
|
|
var options = args.pop();
|
|
var hasLength = args.some(function (arg) { return arg && (Array.isArray(arg) ? arg.length > 0 : arg); });
|
|
if (hasLength) {
|
|
return options.fn(this);
|
|
}
|
|
else {
|
|
return options.inverse(this);
|
|
}
|
|
});
|
|
Handlebars.registerHelper('breakComma', function (array) {
|
|
if (Array.isArray(array)) {
|
|
return array.join(', ');
|
|
}
|
|
return array;
|
|
});
|
|
Handlebars.registerHelper('parseDescription', function (description, depth) {
|
|
// Simple markdown parsing - just return as HTML for now
|
|
return new Handlebars.SafeString(description || '');
|
|
});
|
|
Handlebars.registerHelper('escapeSimpleQuote', function (text) {
|
|
if (typeof text === 'string') {
|
|
return text.replace(/'/g, "\\'");
|
|
}
|
|
return text;
|
|
});
|
|
// Register JSDoc helper
|
|
Handlebars.registerHelper('jsdoc-code-example', function (jsdoctags, options) {
|
|
return options.fn({ tags: jsdoctags || [] });
|
|
});
|
|
// Register link-type helper as a simple partial
|
|
Handlebars.registerHelper('link-type', function (type, options) {
|
|
if (type && type.href) {
|
|
return new Handlebars.SafeString("<a href=\"".concat(type.href, "\" target=\"").concat(type.target || '_self', "\">").concat(type.raw || type, "</a>"));
|
|
}
|
|
return type;
|
|
});
|
|
// Register built-in block helpers
|
|
Handlebars.registerHelper('each', Handlebars.helpers.each);
|
|
Handlebars.registerHelper('if', Handlebars.helpers.if);
|
|
Handlebars.registerHelper('unless', Handlebars.helpers.unless);
|
|
Handlebars.registerHelper('with', Handlebars.helpers.with);
|
|
// Register common partials used in templates
|
|
Handlebars.registerPartial('component-detail', "\n <p class=\"comment\">\n <h3>{{t \"file\"}}</h3>\n </p>\n <p class=\"comment\">\n <code>{{component.file}}</code>\n </p>\n\n {{#if component.description}}\n <p class=\"comment\">\n <h3>{{t \"description\"}}</h3>\n </p>\n <p class=\"comment\">\n {{{parseDescription component.description depth}}}\n </p>\n {{/if}}\n\n {{#if component.implements}}\n <p class=\"comment\">\n <h3>{{t \"implements\"}}</h3>\n </p>\n <p class=\"comment\">\n {{#each component.implements}}\n <code>{{this}}</code>{{#unless @last}}, {{/unless}}\n {{/each}}\n </p>\n {{/if}}\n\n <section data-compodoc=\"block-metadata\">\n <h3>{{t \"metadata\"}}</h3>\n <table class=\"table table-sm table-hover metadata\">\n <tbody>\n {{#if component.selector}}\n <tr>\n <td class=\"col-md-3\">selector</td>\n <td class=\"col-md-9\"><code>{{component.selector}}</code></td>\n </tr>\n {{/if}}\n {{#if component.templateUrl}}\n <tr>\n <td class=\"col-md-3\">templateUrl</td>\n <td class=\"col-md-9\"><code>{{component.templateUrl}}</code></td>\n </tr>\n {{/if}}\n {{#if component.styleUrls}}\n <tr>\n <td class=\"col-md-3\">styleUrls</td>\n <td class=\"col-md-9\"><code>{{breakComma component.styleUrls}}</code></td>\n </tr>\n {{/if}}\n </tbody>\n </table>\n </section>\n\n {{#orLength component.properties component.methods component.inputs component.outputs}}\n <section data-compodoc=\"block-index\">\n <h3 id=\"index\">{{t \"index\"}}</h3>\n <table class=\"table table-sm table-bordered index-table\">\n <tbody>\n {{#if component.methods}}\n <tr>\n <td class=\"col-md-4\">\n <h6><b>{{t \"methods\"}}</b></h6>\n </td>\n </tr>\n <tr>\n <td class=\"col-md-4\">\n <ul class=\"index-list\">\n {{#each component.methods}}\n <li><a href=\"#{{name}}\">{{name}}</a></li>\n {{/each}}\n </ul>\n </td>\n </tr>\n {{/if}}\n {{#if component.properties}}\n <tr>\n <td class=\"col-md-4\">\n <h6><b>{{t \"properties\"}}</b></h6>\n </td>\n </tr>\n <tr>\n <td class=\"col-md-4\">\n <ul class=\"index-list\">\n {{#each component.properties}}\n <li><a href=\"#{{name}}\">{{name}}</a></li>\n {{/each}}\n </ul>\n </td>\n </tr>\n {{/if}}\n </tbody>\n </table>\n </section>\n {{/orLength}}\n\n {{#if component.methods}}\n <section data-compodoc=\"block-methods\">\n <h3 id=\"methods\">{{t \"methods\"}}</h3>\n {{#each component.methods}}\n <table class=\"table table-sm table-bordered\">\n <tbody>\n <tr>\n <td class=\"col-md-4\">\n <a name=\"{{name}}\"></a>\n <span class=\"name\">\n <span><b>{{name}}</b></span>\n <a href=\"#{{name}}\"><span class=\"icon ion-ios-link\"></span></a>\n </span>\n </td>\n </tr>\n <tr>\n <td class=\"col-md-4\">\n <code>{{name}}({{#each args}}{{name}}: {{type}}{{#unless @last}}, {{/unless}}{{/each}})</code>\n </td>\n </tr>\n {{#if description}}\n <tr>\n <td class=\"col-md-4\">\n <div class=\"io-description\">{{description}}</div>\n <div class=\"io-description\">\n <b>Returns : </b><code>{{type}}</code>\n </div>\n </td>\n </tr>\n {{/if}}\n </tbody>\n </table>\n {{/each}}\n </section>\n {{/if}}\n ");
|
|
Handlebars.registerPartial('index', '<!-- Index partial placeholder -->');
|
|
Handlebars.registerPartial('link-type', '<code>{{type}}</code>');
|
|
};
|
|
TemplatePlaygroundServer.prototype.generateCompodocHtml = function (data) {
|
|
var component = data.component || {};
|
|
var navTabs = data.navTabs || [];
|
|
// Generate navigation tabs
|
|
var tabsHtml = navTabs.map(function (tab, index) {
|
|
var isActive = index === 0;
|
|
var activeClass = isActive ? 'nav-link active' : 'nav-link';
|
|
var labelMap = {
|
|
'info': 'Info',
|
|
'readme': 'Readme',
|
|
'source': 'Source',
|
|
'template': 'Template',
|
|
'styles': 'Styles',
|
|
'dom-tree': 'DOM Tree'
|
|
};
|
|
var label = labelMap[tab.label] || tab.label;
|
|
return " <li class=\"nav-item\">\n <a href=\"".concat(tab.href, "\" class=\"").concat(activeClass, "\" role=\"tab\" id=\"").concat(tab.id, "-tab\" data-bs-toggle=\"tab\" data-link=\"").concat(tab['data-link'], "\">").concat(label, "</a>\n </li>");
|
|
}).join('\n');
|
|
// Generate tab content
|
|
var tabContentHtml = '';
|
|
// Info tab
|
|
if (navTabs.some(function (tab) { return tab.id === 'info'; })) {
|
|
var isActive = navTabs[0].id === 'info';
|
|
var activeClass = isActive ? 'active in' : '';
|
|
tabContentHtml += " <div class=\"tab-pane fade ".concat(activeClass, "\" id=\"info\">\n <p class=\"comment\">\n <h3>File</h3>\n </p>\n <p class=\"comment\">\n <code>").concat(component.file || '', "</code>\n </p>\n\n ").concat(component.description ? "\n <p class=\"comment\">\n <h3>Description</h3>\n </p>\n <p class=\"comment\">\n <p>".concat(component.description.replace(/\n/g, '</p>\n<p>'), "</p>\n </p>\n ") : '', "\n\n ").concat(component.implements && component.implements.length > 0 ? "\n <p class=\"comment\">\n <h3>Implements</h3>\n </p>\n <p class=\"comment\">\n ".concat(component.implements.map(function (impl) { return "<code>".concat(impl, "</code>"); }).join(', '), "\n </p>\n ") : '', "\n\n <section data-compodoc=\"block-metadata\">\n <h3>Metadata</h3>\n <table class=\"table table-sm table-hover metadata\">\n <tbody>\n ").concat(component.selector ? "\n <tr>\n <td class=\"col-md-3\">selector</td>\n <td class=\"col-md-9\"><code>".concat(component.selector, "</code></td>\n </tr>") : '', "\n ").concat(component.templateUrl ? "\n <tr>\n <td class=\"col-md-3\">templateUrl</td>\n <td class=\"col-md-9\"><code>".concat(component.templateUrl, "</code></td>\n </tr>") : '', "\n ").concat(component.styleUrls && component.styleUrls.length > 0 ? "\n <tr>\n <td class=\"col-md-3\">styleUrls</td>\n <td class=\"col-md-9\"><code>".concat(component.styleUrls.join(', '), "</code></td>\n </tr>") : '', "\n </tbody>\n </table>\n </section>\n\n ").concat(component.methods && component.methods.length > 0 ? "\n <section data-compodoc=\"block-index\">\n <h3 id=\"index\">Index</h3>\n <table class=\"table table-sm table-bordered index-table\">\n <tbody>\n <tr>\n <td class=\"col-md-4\">\n <h6><b>Methods</b></h6>\n </td>\n </tr>\n <tr>\n <td class=\"col-md-4\">\n <ul class=\"index-list\">\n ".concat(component.methods.map(function (method) { return "<li><a href=\"#".concat(method.name, "\">").concat(method.name, "</a></li>"); }).join('\n '), "\n </ul>\n </td>\n </tr>\n </tbody>\n </table>\n </section>\n\n <section data-compodoc=\"block-methods\">\n <h3 id=\"methods\">Methods</h3>\n ").concat(component.methods.map(function (method) { return "\n <table class=\"table table-sm table-bordered\">\n <tbody>\n <tr>\n <td class=\"col-md-4\">\n <a name=\"".concat(method.name, "\"></a>\n <span class=\"name\">\n <span><b>").concat(method.name, "</b></span>\n <a href=\"#").concat(method.name, "\"><span class=\"icon ion-ios-link\"></span></a>\n </span>\n </td>\n </tr>\n <tr>\n <td class=\"col-md-4\">\n <code>").concat(method.name, "()</code>\n </td>\n </tr>\n ").concat(method.description ? "\n <tr>\n <td class=\"col-md-4\">\n <div class=\"io-description\">".concat(method.description, "</div>\n <div class=\"io-description\">\n <b>Returns : </b><code>").concat(method.type || 'void', "</code>\n </div>\n </td>\n </tr>") : '', "\n </tbody>\n </table>"); }).join('\n '), "\n </section>") : '', "\n </div>\n");
|
|
}
|
|
// Source tab
|
|
if (navTabs.some(function (tab) { return tab.id === 'source'; })) {
|
|
var isActive = navTabs[0].id === 'source';
|
|
var activeClass = isActive ? 'active in' : '';
|
|
tabContentHtml += " <div class=\"tab-pane fade ".concat(activeClass, " tab-source-code\" id=\"source\">\n <pre class=\"line-numbers compodoc-sourcecode\"><code class=\"language-typescript\">").concat(component.sourceCode || '', "</code></pre>\n </div>\n");
|
|
}
|
|
// Generate complete HTML
|
|
return "<ol class=\"breadcrumb\">\n <li class=\"breadcrumb-item\">Components</li>\n <li class=\"breadcrumb-item\">".concat(component.name || '', "</li>\n</ol>\n\n<ul class=\"nav nav-tabs\" role=\"tablist\">\n").concat(tabsHtml, "\n</ul>\n\n<div class=\"tab-content\">\n").concat(tabContentHtml, "</div>");
|
|
};
|
|
TemplatePlaygroundServer.prototype.downloadTemplatePackage = function (req, res) {
|
|
return logger.__awaiter(this, void 0, void 0, function () {
|
|
var _a, templateType, templateContent, templateData, readme, exampleData, zipStructure;
|
|
var _b;
|
|
return logger.__generator(this, function (_c) {
|
|
try {
|
|
_a = req.body, templateType = _a.templateType, templateContent = _a.templateContent, templateData = _a.templateData;
|
|
if (!templateType || !templateContent) {
|
|
send(res, 400, { error: 'Template type and content are required' });
|
|
return [2 /*return*/];
|
|
}
|
|
readme = "# Custom Compodoc Template\n\nThis package contains your customized Compodoc template for: **".concat(templateType, "**\n\n## Files Included\n\n- `templates/partials/").concat(templateType, ".hbs` - Your modified template\n- `example-data.json` - Sample data structure for testing\n- `README.md` - This file\n\n## How to Use\n\n### Option 1: Replace in existing Compodoc installation\n\n1. Backup your original template file (usually in `node_modules/@compodoc/compodoc/dist/templates/partials/").concat(templateType, ".hbs`)\n2. Replace it with the provided `").concat(templateType, ".hbs` file\n3. Regenerate your documentation with Compodoc\n\n### Option 2: Use with custom template directory\n\n1. Create a custom templates directory in your project:\n ```\n mkdir -p custom-templates/partials\n ```\n\n2. Copy the `").concat(templateType, ".hbs` file to:\n ```\n custom-templates/partials/").concat(templateType, ".hbs\n ```\n\n3. Run Compodoc with the custom template directory:\n ```\n compodoc -p tsconfig.json -d documentation --customTemplate custom-templates\n ```\n\n## Template Variables\n\nThe template has access to these main variables:\n\n- `component` - Component information (name, description, inputs, outputs, etc.)\n- `navTabs` - Navigation tabs configuration\n- `depth` - Current page depth for relative URLs\n- `t` - Translation helper function\n\nFor a complete list of available variables, see the `example-data.json` file.\n\n## Need Help?\n\n- Compodoc Documentation: https://compodoc.app/\n- GitHub Issues: https://github.com/compodoc/compodoc/issues\n\nGenerated by Compodoc Template Playground on ").concat(new Date().toLocaleString(), "\n");
|
|
exampleData = {
|
|
template: templateType,
|
|
description: 'This is sample data that matches the structure used in Compodoc templates',
|
|
data: templateData || {}
|
|
};
|
|
zipStructure = (_b = {},
|
|
_b["templates/partials/".concat(templateType, ".hbs")] = templateContent,
|
|
_b['README.md'] = readme,
|
|
_b['example-data.json'] = JSON.stringify(exampleData, null, 2),
|
|
_b);
|
|
send(res, 200, {
|
|
success: true,
|
|
filename: "compodoc-".concat(templateType, "-template.zip"),
|
|
files: zipStructure
|
|
});
|
|
}
|
|
catch (error) {
|
|
logger.logger.error('Error creating template package:', error);
|
|
send(res, 500, {
|
|
error: 'Failed to create template package',
|
|
details: error.message
|
|
});
|
|
}
|
|
return [2 /*return*/];
|
|
});
|
|
});
|
|
};
|
|
TemplatePlaygroundServer.prototype.downloadSessionTemplateZip = function (req, res) {
|
|
return logger.__awaiter(this, void 0, void 0, function () {
|
|
var sessionId_1, _a, templatePath_1, templateContent_1, session, templateName_1, fileName_1, error_6;
|
|
var _this = this;
|
|
return logger.__generator(this, function (_b) {
|
|
switch (_b.label) {
|
|
case 0:
|
|
_b.trys.push([0, 2, , 3]);
|
|
sessionId_1 = req.params.sessionId;
|
|
_a = req.body, templatePath_1 = _a.templatePath, templateContent_1 = _a.templateContent;
|
|
if (!templatePath_1 || !templateContent_1) {
|
|
send(res, 400, { error: 'Template path and content are required' });
|
|
return [2 /*return*/];
|
|
}
|
|
session = this.sessions.get(sessionId_1);
|
|
if (!session) {
|
|
send(res, 404, { success: false, message: 'Session not found' });
|
|
return [2 /*return*/];
|
|
}
|
|
this.updateSessionActivity(sessionId_1);
|
|
templateName_1 = path__namespace.basename(templatePath_1, '.hbs');
|
|
fileName_1 = "compodoc-".concat(templateName_1, "-template.zip");
|
|
// Set response headers for file download
|
|
res.setHeader('Content-Type', 'application/zip');
|
|
res.setHeader('Content-Disposition', "attachment; filename=\"".concat(fileName_1, "\""));
|
|
// Create ZIP archive and handle it with proper promise
|
|
return [4 /*yield*/, new Promise(function (resolve, reject) {
|
|
var archive = archiver('zip', {
|
|
zlib: { level: 9 } // Maximum compression
|
|
});
|
|
// Handle archive events
|
|
archive.on('error', function (err) {
|
|
logger.logger.error('Archive error:', err);
|
|
reject(new Error("Failed to create ZIP file: ".concat(err.message)));
|
|
});
|
|
archive.on('end', function () {
|
|
logger.logger.info("\u2705 Template ZIP created successfully for session ".concat(sessionId_1, ": ").concat(fileName_1));
|
|
resolve();
|
|
});
|
|
// Pipe archive to response
|
|
archive.pipe(res);
|
|
// Add template file to ZIP
|
|
archive.append(templateContent_1, { name: "templates/partials/".concat(templateName_1, ".hbs") });
|
|
// Create README content
|
|
var readme = "# Custom Compodoc Template\n\nThis package contains your customized Compodoc template for: **".concat(templateName_1, "**\n\n## Files Included\n\n- `templates/partials/").concat(templateName_1, ".hbs` - Your modified template\n- `example-data.json` - Sample data structure for testing\n- `README.md` - This file\n\n## How to Use\n\n### Option 1: Replace in existing Compodoc installation\n\n1. Backup your original template file (usually in `node_modules/@compodoc/compodoc/dist/templates/partials/").concat(templateName_1, ".hbs`)\n2. Replace it with the provided `").concat(templateName_1, ".hbs` file\n3. Regenerate your documentation with Compodoc\n\n### Option 2: Use with custom template directory\n\n1. Create a custom templates directory in your project:\n ```\n mkdir -p custom-templates/partials\n ```\n\n2. Copy the `").concat(templateName_1, ".hbs` file to:\n ```\n custom-templates/partials/").concat(templateName_1, ".hbs\n ```\n\n3. Run Compodoc with the custom template directory:\n ```\n compodoc -p tsconfig.json -d documentation --customTemplate custom-templates\n ```\n\n## Template Variables\n\nThe template has access to these main variables:\n\n- `component` - Component information (name, description, inputs, outputs, etc.)\n- `navTabs` - Navigation tabs configuration\n- `depth` - Current page depth for relative URLs\n- `t` - Translation helper function\n\nFor a complete list of available variables, see the `example-data.json` file.\n\n## Need Help?\n\n- Compodoc Documentation: https://compodoc.app/\n- GitHub Issues: https://github.com/compodoc/compodoc/issues\n\nGenerated by Compodoc Template Playground on ").concat(new Date().toLocaleString(), "\n");
|
|
// Add README to ZIP
|
|
archive.append(readme, { name: 'README.md' });
|
|
// Try to get template data for the current session and template
|
|
_this.getSessionTemplateDataInternal(sessionId_1, templatePath_1)
|
|
.then(function (templateDataResponse) {
|
|
var exampleData = {
|
|
template: templateName_1,
|
|
description: 'This is sample data that matches the structure used in Compodoc templates',
|
|
data: templateDataResponse || {}
|
|
};
|
|
archive.append(JSON.stringify(exampleData, null, 2), { name: 'example-data.json' });
|
|
})
|
|
.catch(function (dataError) {
|
|
logger.logger.warn('Could not get template data, using basic structure:', dataError);
|
|
var basicData = {
|
|
template: templateName_1,
|
|
description: 'This is sample data that matches the structure used in Compodoc templates',
|
|
data: { note: 'Template data could not be loaded' }
|
|
};
|
|
archive.append(JSON.stringify(basicData, null, 2), { name: 'example-data.json' });
|
|
})
|
|
.finally(function () {
|
|
// Finalize the archive after adding all files
|
|
archive.finalize();
|
|
});
|
|
})];
|
|
case 1:
|
|
// Create ZIP archive and handle it with proper promise
|
|
_b.sent();
|
|
return [3 /*break*/, 3];
|
|
case 2:
|
|
error_6 = _b.sent();
|
|
logger.logger.error('Error creating session template ZIP:', error_6);
|
|
if (!res.headersSent) {
|
|
send(res, 500, {
|
|
error: 'Failed to create template ZIP',
|
|
details: error_6.message
|
|
});
|
|
}
|
|
return [3 /*break*/, 3];
|
|
case 3: return [2 /*return*/];
|
|
}
|
|
});
|
|
});
|
|
};
|
|
TemplatePlaygroundServer.prototype.downloadAllSessionTemplates = function (req, res) {
|
|
return logger.__awaiter(this, void 0, void 0, function () {
|
|
var sessionId_2, session_2, fileName_2, zipBuffer, error_7;
|
|
return logger.__generator(this, function (_a) {
|
|
switch (_a.label) {
|
|
case 0:
|
|
_a.trys.push([0, 2, , 3]);
|
|
sessionId_2 = req.params.sessionId;
|
|
session_2 = this.sessions.get(sessionId_2);
|
|
if (!session_2) {
|
|
send(res, 404, { success: false, message: 'Session not found' });
|
|
return [2 /*return*/];
|
|
}
|
|
this.updateSessionActivity(sessionId_2);
|
|
fileName_2 = "compodoc-templates-".concat(sessionId_2, ".zip");
|
|
return [4 /*yield*/, new Promise(function (resolve, reject) {
|
|
var archive = archiver('zip', {
|
|
zlib: { level: 9 } // Maximum compression
|
|
});
|
|
var chunks = [];
|
|
// Handle archive events
|
|
archive.on('error', function (err) {
|
|
logger.logger.error('Archive error:', err);
|
|
reject(new Error("Failed to create ZIP file: ".concat(err.message)));
|
|
});
|
|
archive.on('data', function (chunk) {
|
|
chunks.push(chunk);
|
|
});
|
|
archive.on('end', function () {
|
|
logger.logger.info("\u2705 All templates ZIP created successfully for session ".concat(sessionId_2, ": ").concat(fileName_2));
|
|
var buffer = Buffer.concat(chunks);
|
|
resolve(buffer);
|
|
});
|
|
// Add all files from the session's template directory
|
|
// This maintains the same structure as hbs-templates-copy-<hash>
|
|
archive.directory(session_2.templateDir, false);
|
|
// Create a comprehensive README
|
|
var readme = "# Compodoc Template Package\n\nThis package contains all customized Compodoc templates for session: **".concat(sessionId_2, "**\n\n## Structure\n\nThis template package has the same structure as Compodoc's default templates:\n\n- `page.hbs` - Main page template\n- `partials/` - Directory containing all partial templates:\n - Component templates (`component.hbs`, `directive.hbs`, etc.)\n - Block templates (`block-*.hbs`)\n - Layout templates (`menu.hbs`, `index.hbs`, etc.)\n - Utility templates (`search-*.hbs`, `coverage-*.hbs`, etc.)\n\n## How to Use\n\n### Option 1: Replace entire template directory\n\n1. Backup your original templates directory (usually in `node_modules/@compodoc/compodoc/dist/templates/`)\n2. Replace it with the contents of this ZIP file\n3. Regenerate your documentation with Compodoc\n\n### Option 2: Use with custom template directory\n\n1. Extract this ZIP to a directory in your project (e.g., `custom-templates/`)\n2. Run Compodoc with the custom template directory:\n ```\n compodoc -p tsconfig.json -d documentation --customTemplate custom-templates\n ```\n\n### Option 3: Use specific templates only\n\n1. Extract only the templates you want to customize\n2. Place them in your custom template directory maintaining the same structure\n3. Compodoc will use your custom templates and fall back to defaults for others\n\n## Template Variables\n\nTemplates have access to comprehensive data structures including:\n\n- Component/Directive/Service information\n- Navigation and routing data\n- Documentation metadata\n- Configuration options\n- Helper functions for formatting and navigation\n\n## Need Help?\n\n- Compodoc Documentation: https://compodoc.app/\n- GitHub Issues: https://github.com/compodoc/compodoc/issues\n- Template Documentation: https://compodoc.app/guides/templates.html\n\nGenerated by Compodoc Template Playground on ").concat(new Date().toLocaleString(), "\n");
|
|
// Add README to ZIP root
|
|
archive.append(readme, { name: 'README.md' });
|
|
// Finalize the archive after adding all files
|
|
archive.finalize();
|
|
})];
|
|
case 1:
|
|
zipBuffer = _a.sent();
|
|
// Set headers and send buffer response for supertest compatibility
|
|
res.setHeader('Content-Type', 'application/zip');
|
|
res.setHeader('Content-Disposition', "attachment; filename=\"".concat(fileName_2, "\""));
|
|
res.setHeader('Content-Length', zipBuffer.length.toString());
|
|
// For testing, also add a custom header with the size
|
|
res.setHeader('X-Content-Size', zipBuffer.length.toString());
|
|
res.end(zipBuffer, 'binary');
|
|
return [3 /*break*/, 3];
|
|
case 2:
|
|
error_7 = _a.sent();
|
|
logger.logger.error('Error creating all templates ZIP:', error_7);
|
|
if (!res.headersSent) {
|
|
send(res, 500, {
|
|
error: 'Failed to create all templates ZIP',
|
|
details: error_7.message
|
|
});
|
|
}
|
|
return [3 /*break*/, 3];
|
|
case 3: return [2 /*return*/];
|
|
}
|
|
});
|
|
});
|
|
};
|
|
TemplatePlaygroundServer.prototype.getSessionTemplateDataInternal = function (sessionId, templatePath) {
|
|
return logger.__awaiter(this, void 0, void 0, function () {
|
|
var templateName, data;
|
|
return logger.__generator(this, function (_a) {
|
|
// Internal method to get template data without HTTP request/response
|
|
if (!this.sessions.has(sessionId)) {
|
|
throw new Error('Session not found');
|
|
}
|
|
this.updateSessionActivity(sessionId);
|
|
templateName = path__namespace.basename(templatePath, '.hbs');
|
|
data = {};
|
|
if (templateName.includes('component')) {
|
|
data = {
|
|
name: 'ExampleComponent',
|
|
description: 'A sample Angular component for demonstration',
|
|
file: 'src/app/example.component.ts',
|
|
selector: 'app-example',
|
|
templateUrl: './example.component.html',
|
|
styleUrls: ['./example.component.scss'],
|
|
inputs: [
|
|
{ name: 'title', type: 'string', description: 'Component title' },
|
|
{ name: 'enabled', type: 'boolean', description: 'Whether component is enabled' }
|
|
],
|
|
outputs: [
|
|
{ name: 'clicked', type: 'EventEmitter<void>', description: 'Emitted when clicked' }
|
|
]
|
|
};
|
|
}
|
|
else if (templateName.includes('service') || templateName.includes('injectable')) {
|
|
data = {
|
|
name: 'ExampleService',
|
|
description: 'A sample Angular service for demonstration',
|
|
file: 'src/app/example.service.ts',
|
|
methods: [
|
|
{ name: 'getData', returnType: 'Observable<any>', description: 'Gets data from API' },
|
|
{ name: 'saveData', returnType: 'void', description: 'Saves data to storage' }
|
|
]
|
|
};
|
|
}
|
|
else {
|
|
data = {
|
|
name: "Example".concat(templateName.charAt(0).toUpperCase() + templateName.slice(1)),
|
|
description: "A sample ".concat(templateName, " for demonstration"),
|
|
file: "src/app/example.".concat(templateName, ".ts")
|
|
};
|
|
}
|
|
return [2 /*return*/, data];
|
|
});
|
|
});
|
|
};
|
|
// Session management API methods
|
|
TemplatePlaygroundServer.prototype.createSessionAPI = function (req, res) {
|
|
return logger.__awaiter(this, void 0, void 0, function () {
|
|
var clientIP, forceNew, session;
|
|
return logger.__generator(this, function (_a) {
|
|
try {
|
|
clientIP = this.getClientIP(req);
|
|
forceNew = process.env.NODE_ENV === 'test' || req.query.forceNew === 'true';
|
|
session = forceNew ? this.createNewSession(clientIP) : this.createOrGetSessionByIP(clientIP);
|
|
send(res, 200, {
|
|
sessionId: session.id,
|
|
success: true,
|
|
message: 'Session created successfully',
|
|
ip: clientIP
|
|
});
|
|
}
|
|
catch (error) {
|
|
logger.logger.error('Error creating session:', error);
|
|
send(res, 500, {
|
|
success: false,
|
|
message: 'Failed to create session',
|
|
error: error instanceof Error ? error.message : 'Unknown error'
|
|
});
|
|
}
|
|
return [2 /*return*/];
|
|
});
|
|
});
|
|
};
|
|
TemplatePlaygroundServer.prototype.getSessionTemplates = function (req, res) {
|
|
return logger.__awaiter(this, void 0, void 0, function () {
|
|
var sessionId, session, templates_1, partialsDir, mainTemplatePath, partialFiles;
|
|
return logger.__generator(this, function (_a) {
|
|
try {
|
|
sessionId = req.params.sessionId;
|
|
session = this.sessions.get(sessionId);
|
|
if (!session) {
|
|
send(res, 404, { success: false, message: 'Session not found' });
|
|
return [2 /*return*/];
|
|
}
|
|
this.updateSessionActivity(sessionId);
|
|
templates_1 = [];
|
|
partialsDir = path__namespace.join(session.templateDir, 'partials');
|
|
mainTemplatePath = path__namespace.join(session.templateDir, 'page.hbs');
|
|
if (fs__namespace.existsSync(mainTemplatePath)) {
|
|
templates_1.push({
|
|
name: 'page.hbs',
|
|
path: 'page.hbs',
|
|
type: 'template'
|
|
});
|
|
}
|
|
// Read partials
|
|
if (fs__namespace.existsSync(partialsDir)) {
|
|
partialFiles = fs__namespace.readdirSync(partialsDir).filter(function (file) { return file.endsWith('.hbs'); });
|
|
partialFiles.forEach(function (file) {
|
|
templates_1.push({
|
|
name: file,
|
|
path: "partials/".concat(file),
|
|
type: 'partial'
|
|
});
|
|
});
|
|
}
|
|
send(res, 200, { templates: templates_1, success: true });
|
|
}
|
|
catch (error) {
|
|
logger.logger.error('Error getting session templates:', error);
|
|
send(res, 500, {
|
|
success: false,
|
|
message: 'Failed to get templates',
|
|
error: error instanceof Error ? error.message : 'Unknown error'
|
|
});
|
|
}
|
|
return [2 /*return*/];
|
|
});
|
|
});
|
|
};
|
|
TemplatePlaygroundServer.prototype.getSessionTemplate = function (req, res) {
|
|
return logger.__awaiter(this, void 0, void 0, function () {
|
|
var sessionId, templateName, urlParts, templateIndex, session, templatePath, content;
|
|
return logger.__generator(this, function (_a) {
|
|
try {
|
|
sessionId = req.params.sessionId;
|
|
templateName = req.params["*"];
|
|
urlParts = req.url.split('/');
|
|
templateIndex = urlParts.findIndex(function (part) { return part === 'template'; });
|
|
if (templateIndex !== -1 && templateIndex < urlParts.length - 1) {
|
|
// Get everything after 'template/' in the URL and decode it
|
|
templateName = decodeURIComponent(urlParts.slice(templateIndex + 1).join('/'));
|
|
}
|
|
session = this.sessions.get(sessionId);
|
|
// Removed debug logging - path extraction now working correctly
|
|
if (!session) {
|
|
send(res, 404, { success: false, message: 'Session not found' });
|
|
return [2 /*return*/];
|
|
}
|
|
this.updateSessionActivity(sessionId);
|
|
templatePath = path__namespace.join(session.templateDir, templateName);
|
|
if (!fs__namespace.existsSync(templatePath)) {
|
|
send(res, 404, { success: false, message: 'Template not found' });
|
|
return [2 /*return*/];
|
|
}
|
|
content = fs__namespace.readFileSync(templatePath, 'utf8');
|
|
send(res, 200, {
|
|
content: content,
|
|
success: true,
|
|
templateName: templateName,
|
|
path: templateName
|
|
});
|
|
}
|
|
catch (error) {
|
|
logger.logger.error('Error getting session template:', error);
|
|
send(res, 500, {
|
|
success: false,
|
|
message: 'Failed to get template',
|
|
error: error instanceof Error ? error.message : 'Unknown error'
|
|
});
|
|
}
|
|
return [2 /*return*/];
|
|
});
|
|
});
|
|
};
|
|
TemplatePlaygroundServer.prototype.saveSessionTemplate = function (req, res) {
|
|
return logger.__awaiter(this, void 0, void 0, function () {
|
|
var sessionId, templateName, urlParts, templateIndex, content, session, templatePath;
|
|
return logger.__generator(this, function (_a) {
|
|
try {
|
|
sessionId = req.params.sessionId;
|
|
templateName = req.params["*"];
|
|
urlParts = req.url.split('/');
|
|
templateIndex = urlParts.findIndex(function (part) { return part === 'template'; });
|
|
if (templateIndex !== -1 && templateIndex < urlParts.length - 1) {
|
|
// Get everything after 'template/' in the URL and decode it
|
|
templateName = decodeURIComponent(urlParts.slice(templateIndex + 1).join('/'));
|
|
}
|
|
content = req.body.content;
|
|
session = this.sessions.get(sessionId);
|
|
// Validate required parameters
|
|
if (!content || typeof content !== 'string') {
|
|
send(res, 400, {
|
|
success: false,
|
|
message: 'Content is required and must be a string'
|
|
});
|
|
return [2 /*return*/];
|
|
}
|
|
if (!templateName) {
|
|
send(res, 400, {
|
|
success: false,
|
|
message: 'Template name is required'
|
|
});
|
|
return [2 /*return*/];
|
|
}
|
|
if (!session) {
|
|
send(res, 404, { success: false, message: 'Session not found' });
|
|
return [2 /*return*/];
|
|
}
|
|
this.updateSessionActivity(sessionId);
|
|
templatePath = path__namespace.join(session.templateDir, templateName);
|
|
// Ensure directory exists
|
|
fs__namespace.ensureDirSync(path__namespace.dirname(templatePath));
|
|
// Save the template content
|
|
fs__namespace.writeFileSync(templatePath, content, 'utf8');
|
|
// Trigger debounced documentation regeneration
|
|
this.generateDocumentation(sessionId, true);
|
|
send(res, 200, {
|
|
success: true,
|
|
message: 'Template saved successfully',
|
|
templateName: templateName
|
|
});
|
|
}
|
|
catch (error) {
|
|
logger.logger.error('Error saving session template:', error);
|
|
send(res, 500, {
|
|
success: false,
|
|
message: 'Failed to save template',
|
|
error: error instanceof Error ? error.message : 'Unknown error'
|
|
});
|
|
}
|
|
return [2 /*return*/];
|
|
});
|
|
});
|
|
};
|
|
TemplatePlaygroundServer.prototype.getSessionTemplateData = function (req, res) {
|
|
return logger.__awaiter(this, void 0, void 0, function () {
|
|
var sessionId, templatePath, urlParts, templateIndex, session, templateName, compodocConfig, responseData, additionalContext, templateVariables, commonContext;
|
|
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25;
|
|
return logger.__generator(this, function (_26) {
|
|
try {
|
|
sessionId = req.params.sessionId;
|
|
templatePath = req.params["*"];
|
|
// FALLBACK: If Polka doesn't capture the full path, extract it from the URL
|
|
if (!templatePath || !templatePath.includes('/')) {
|
|
urlParts = req.url.split('/');
|
|
templateIndex = urlParts.findIndex(function (part) { return part === 'template-data'; });
|
|
if (templateIndex !== -1 && templateIndex < urlParts.length - 1) {
|
|
// Get everything after 'template-data/' in the URL and decode it
|
|
templatePath = decodeURIComponent(urlParts.slice(templateIndex + 1).join('/'));
|
|
}
|
|
}
|
|
if (!this.sessions.has(sessionId)) {
|
|
send(res, 404, {
|
|
success: false,
|
|
message: 'Session not found'
|
|
});
|
|
return [2 /*return*/];
|
|
}
|
|
this.updateSessionActivity(sessionId);
|
|
session = this.sessions.get(sessionId);
|
|
templateName = path__namespace.basename(templatePath, '.hbs');
|
|
compodocConfig = {
|
|
// Documentation Metadata
|
|
name: ((_a = session === null || session === void 0 ? void 0 : session.config) === null || _a === void 0 ? void 0 : _a.name) || 'Application documentation',
|
|
// Paths and Output
|
|
output: ((_b = session === null || session === void 0 ? void 0 : session.config) === null || _b === void 0 ? void 0 : _b.output) || './documentation/',
|
|
theme: ((_c = session === null || session === void 0 ? void 0 : session.config) === null || _c === void 0 ? void 0 : _c.theme) || 'gitbook',
|
|
language: ((_d = session === null || session === void 0 ? void 0 : session.config) === null || _d === void 0 ? void 0 : _d.language) || 'en-US',
|
|
base: ((_e = session === null || session === void 0 ? void 0 : session.config) === null || _e === void 0 ? void 0 : _e.base) || '/',
|
|
// Assets and Custom UI
|
|
customFavicon: ((_f = session === null || session === void 0 ? void 0 : session.config) === null || _f === void 0 ? void 0 : _f.customFavicon) || '',
|
|
customLogo: ((_g = session === null || session === void 0 ? void 0 : session.config) === null || _g === void 0 ? void 0 : _g.customLogo) || '',
|
|
assetsFolder: ((_h = session === null || session === void 0 ? void 0 : session.config) === null || _h === void 0 ? void 0 : _h.assetsFolder) || '',
|
|
extTheme: ((_j = session === null || session === void 0 ? void 0 : session.config) === null || _j === void 0 ? void 0 : _j.extTheme) || '',
|
|
// Feature Toggles - Disable Options
|
|
disableSourceCode: ((_k = session === null || session === void 0 ? void 0 : session.config) === null || _k === void 0 ? void 0 : _k.disableSourceCode) || false,
|
|
disableGraph: ((_l = session === null || session === void 0 ? void 0 : session.config) === null || _l === void 0 ? void 0 : _l.disableGraph) || false,
|
|
disableCoverage: ((_m = session === null || session === void 0 ? void 0 : session.config) === null || _m === void 0 ? void 0 : _m.disableCoverage) || false,
|
|
disablePrivate: ((_o = session === null || session === void 0 ? void 0 : session.config) === null || _o === void 0 ? void 0 : _o.disablePrivate) || false,
|
|
disableProtected: ((_p = session === null || session === void 0 ? void 0 : session.config) === null || _p === void 0 ? void 0 : _p.disableProtected) || false,
|
|
disableInternal: ((_q = session === null || session === void 0 ? void 0 : session.config) === null || _q === void 0 ? void 0 : _q.disableInternal) || false,
|
|
disableLifeCycleHooks: ((_r = session === null || session === void 0 ? void 0 : session.config) === null || _r === void 0 ? void 0 : _r.disableLifeCycleHooks) || false,
|
|
disableConstructors: ((_s = session === null || session === void 0 ? void 0 : session.config) === null || _s === void 0 ? void 0 : _s.disableConstructors) || false,
|
|
disableRoutesGraph: ((_t = session === null || session === void 0 ? void 0 : session.config) === null || _t === void 0 ? void 0 : _t.disableRoutesGraph) || false,
|
|
disableSearch: ((_u = session === null || session === void 0 ? void 0 : session.config) === null || _u === void 0 ? void 0 : _u.disableSearch) || false,
|
|
disableDependencies: ((_v = session === null || session === void 0 ? void 0 : session.config) === null || _v === void 0 ? void 0 : _v.disableDependencies) || false,
|
|
disableProperties: ((_w = session === null || session === void 0 ? void 0 : session.config) === null || _w === void 0 ? void 0 : _w.disableProperties) || false,
|
|
disableDomTree: ((_x = session === null || session === void 0 ? void 0 : session.config) === null || _x === void 0 ? void 0 : _x.disableDomTree) || false,
|
|
disableTemplateTab: ((_y = session === null || session === void 0 ? void 0 : session.config) === null || _y === void 0 ? void 0 : _y.disableTemplateTab) || false,
|
|
disableStyleTab: ((_z = session === null || session === void 0 ? void 0 : session.config) === null || _z === void 0 ? void 0 : _z.disableStyleTab) || false,
|
|
disableMainGraph: ((_0 = session === null || session === void 0 ? void 0 : session.config) === null || _0 === void 0 ? void 0 : _0.disableMainGraph) || false,
|
|
disableFilePath: ((_1 = session === null || session === void 0 ? void 0 : session.config) === null || _1 === void 0 ? void 0 : _1.disableFilePath) || false,
|
|
disableOverview: ((_2 = session === null || session === void 0 ? void 0 : session.config) === null || _2 === void 0 ? void 0 : _2.disableOverview) || false,
|
|
// UI Options
|
|
hideGenerator: ((_3 = session === null || session === void 0 ? void 0 : session.config) === null || _3 === void 0 ? void 0 : _3.hideGenerator) || false,
|
|
hideDarkModeToggle: ((_4 = session === null || session === void 0 ? void 0 : session.config) === null || _4 === void 0 ? void 0 : _4.hideDarkModeToggle) || false,
|
|
minimal: ((_5 = session === null || session === void 0 ? void 0 : session.config) === null || _5 === void 0 ? void 0 : _5.minimal) || false,
|
|
// Additional Content
|
|
includes: ((_6 = session === null || session === void 0 ? void 0 : session.config) === null || _6 === void 0 ? void 0 : _6.includes) || '',
|
|
includesName: ((_7 = session === null || session === void 0 ? void 0 : session.config) === null || _7 === void 0 ? void 0 : _7.includesName) || 'Additional documentation',
|
|
// Serving Options
|
|
port: ((_8 = session === null || session === void 0 ? void 0 : session.config) === null || _8 === void 0 ? void 0 : _8.port) || 8080,
|
|
hostname: ((_9 = session === null || session === void 0 ? void 0 : session.config) === null || _9 === void 0 ? void 0 : _9.hostname) || '127.0.0.1',
|
|
serve: ((_10 = session === null || session === void 0 ? void 0 : session.config) === null || _10 === void 0 ? void 0 : _10.serve) || false,
|
|
open: ((_11 = session === null || session === void 0 ? void 0 : session.config) === null || _11 === void 0 ? void 0 : _11.open) || false,
|
|
watch: ((_12 = session === null || session === void 0 ? void 0 : session.config) === null || _12 === void 0 ? void 0 : _12.watch) || false,
|
|
// Export Options
|
|
exportFormat: ((_13 = session === null || session === void 0 ? void 0 : session.config) === null || _13 === void 0 ? void 0 : _13.exportFormat) || 'html',
|
|
// Coverage Options
|
|
coverageTest: ((_14 = session === null || session === void 0 ? void 0 : session.config) === null || _14 === void 0 ? void 0 : _14.coverageTest) || false,
|
|
coverageTestThreshold: ((_15 = session === null || session === void 0 ? void 0 : session.config) === null || _15 === void 0 ? void 0 : _15.coverageTestThreshold) || 70,
|
|
coverageMinimumPerFile: ((_16 = session === null || session === void 0 ? void 0 : session.config) === null || _16 === void 0 ? void 0 : _16.coverageMinimumPerFile) || 0,
|
|
coverageTestThresholdFail: ((_17 = session === null || session === void 0 ? void 0 : session.config) === null || _17 === void 0 ? void 0 : _17.coverageTestThresholdFail) || true,
|
|
coverageTestShowOnlyFailed: ((_18 = session === null || session === void 0 ? void 0 : session.config) === null || _18 === void 0 ? void 0 : _18.coverageTestShowOnlyFailed) || false,
|
|
unitTestCoverage: ((_19 = session === null || session === void 0 ? void 0 : session.config) === null || _19 === void 0 ? void 0 : _19.unitTestCoverage) || '',
|
|
// Google Analytics
|
|
gaID: ((_20 = session === null || session === void 0 ? void 0 : session.config) === null || _20 === void 0 ? void 0 : _20.gaID) || '',
|
|
gaSite: ((_21 = session === null || session === void 0 ? void 0 : session.config) === null || _21 === void 0 ? void 0 : _21.gaSite) || 'auto',
|
|
// Advanced Options
|
|
silent: ((_22 = session === null || session === void 0 ? void 0 : session.config) === null || _22 === void 0 ? void 0 : _22.silent) || false,
|
|
maxSearchResults: ((_23 = session === null || session === void 0 ? void 0 : session.config) === null || _23 === void 0 ? void 0 : _23.maxSearchResults) || 15,
|
|
// Menu Configuration (as JSON string for editing)
|
|
toggleMenuItems: JSON.stringify(((_24 = session === null || session === void 0 ? void 0 : session.config) === null || _24 === void 0 ? void 0 : _24.toggleMenuItems) || ['all']),
|
|
navTabConfig: JSON.stringify(((_25 = session === null || session === void 0 ? void 0 : session.config) === null || _25 === void 0 ? void 0 : _25.navTabConfig) || [])
|
|
};
|
|
responseData = compodocConfig;
|
|
additionalContext = {};
|
|
templateVariables = void 0;
|
|
// Determine template type and provide comprehensive realistic data
|
|
if (templateName.includes('component')) {
|
|
templateVariables = {
|
|
// Core component data
|
|
name: 'UserProfileComponent',
|
|
description: 'A comprehensive user profile management component that handles user information display and editing capabilities.',
|
|
file: 'src/app/components/user-profile/user-profile.component.ts',
|
|
selector: 'app-user-profile',
|
|
templateUrl: './user-profile.component.html',
|
|
styleUrls: ['./user-profile.component.scss', './user-profile.theme.scss'],
|
|
encapsulation: 'ViewEncapsulation.Emulated',
|
|
changeDetection: 'ChangeDetectionStrategy.OnPush',
|
|
// Component metadata
|
|
type: 'component',
|
|
sourceCode: 'export class UserProfileComponent implements OnInit, OnDestroy { ... }',
|
|
rawFile: 'user-profile.component.ts',
|
|
// Template and styles
|
|
templateData: '<div class="user-profile">\\n <h2>{{user.name}}</h2>\\n <p>{{user.email}}</p>\\n</div>',
|
|
styleUrlsData: [
|
|
'.user-profile { padding: 20px; }\\n.user-profile h2 { color: #333; }'
|
|
],
|
|
stylesData: [
|
|
':host { display: block; margin: 10px; }'
|
|
],
|
|
// Inputs and Outputs
|
|
inputs: [
|
|
{
|
|
name: 'user',
|
|
type: 'User',
|
|
description: 'The user object containing profile information',
|
|
decorators: ['@Input()'],
|
|
optional: false,
|
|
defaultValue: null
|
|
},
|
|
{
|
|
name: 'editable',
|
|
type: 'boolean',
|
|
description: 'Whether the profile can be edited',
|
|
decorators: ['@Input()'],
|
|
optional: true,
|
|
defaultValue: 'false'
|
|
},
|
|
{
|
|
name: 'showAvatar',
|
|
type: 'boolean',
|
|
description: 'Controls avatar visibility',
|
|
decorators: ['@Input()'],
|
|
optional: true,
|
|
defaultValue: 'true'
|
|
}
|
|
],
|
|
outputs: [
|
|
{
|
|
name: 'userUpdated',
|
|
type: 'EventEmitter<User>',
|
|
description: 'Emitted when user profile is updated',
|
|
decorators: ['@Output()']
|
|
},
|
|
{
|
|
name: 'avatarClicked',
|
|
type: 'EventEmitter<MouseEvent>',
|
|
description: 'Emitted when user clicks on avatar',
|
|
decorators: ['@Output()']
|
|
}
|
|
],
|
|
// Methods
|
|
methods: [
|
|
{
|
|
name: 'ngOnInit',
|
|
type: 'void',
|
|
description: 'Angular lifecycle hook for component initialization',
|
|
args: [],
|
|
returnType: 'void',
|
|
modifierKind: 'public'
|
|
},
|
|
{
|
|
name: 'updateProfile',
|
|
type: 'Promise<void>',
|
|
description: 'Updates the user profile with new information',
|
|
args: [
|
|
{ name: 'userData', type: 'Partial<User>' }
|
|
],
|
|
returnType: 'Promise<void>',
|
|
modifierKind: 'public'
|
|
},
|
|
{
|
|
name: 'validateForm',
|
|
type: 'boolean',
|
|
description: 'Validates the profile form data',
|
|
args: [],
|
|
returnType: 'boolean',
|
|
modifierKind: 'private'
|
|
}
|
|
],
|
|
// Properties
|
|
properties: [
|
|
{
|
|
name: 'isLoading',
|
|
type: 'boolean',
|
|
description: 'Indicates if component is in loading state',
|
|
defaultValue: 'false',
|
|
modifierKind: 'public'
|
|
},
|
|
{
|
|
name: 'form',
|
|
type: 'FormGroup',
|
|
description: 'Reactive form for user profile editing',
|
|
modifierKind: 'public'
|
|
}
|
|
],
|
|
// Host listeners and bindings
|
|
hostListeners: [
|
|
{
|
|
name: 'click',
|
|
args: ['$event'],
|
|
description: 'Handles click events on the component'
|
|
}
|
|
],
|
|
hostBindings: [
|
|
{
|
|
name: 'class.active',
|
|
value: 'isActive'
|
|
}
|
|
],
|
|
// Lifecycle hooks
|
|
implements: ['OnInit', 'OnDestroy', 'AfterViewInit'],
|
|
// Dependency injection
|
|
constructorObj: {
|
|
name: 'constructor',
|
|
description: 'Component constructor with dependency injection',
|
|
args: [
|
|
{ name: 'userService', type: 'UserService' },
|
|
{ name: 'router', type: 'Router' },
|
|
{ name: 'cd', type: 'ChangeDetectorRef' }
|
|
]
|
|
},
|
|
// Angular-specific metadata
|
|
providers: ['UserService'],
|
|
viewProviders: [],
|
|
queries: [],
|
|
exportAs: 'userProfile',
|
|
// Documentation metadata
|
|
jsdoctags: [
|
|
{
|
|
tagName: { text: 'example' },
|
|
comment: '<app-user-profile [user]="currentUser" [editable]="true"></app-user-profile>'
|
|
}
|
|
],
|
|
// Coverage information (if enabled)
|
|
coveragePercent: 85,
|
|
coverageCount: '17/20',
|
|
status: 'good'
|
|
};
|
|
additionalContext = {
|
|
depth: 1,
|
|
breadcrumbs: [
|
|
{ name: 'Components', url: '../components.html' },
|
|
{ name: 'UserProfileComponent', url: '#' }
|
|
]
|
|
};
|
|
}
|
|
else if (templateName.includes('service') || templateName.includes('injectable')) {
|
|
templateVariables = {
|
|
name: 'UserService',
|
|
description: 'Service responsible for managing user data and authentication operations',
|
|
file: 'src/app/services/user.service.ts',
|
|
type: 'injectable',
|
|
// Injectable metadata
|
|
providedIn: 'root',
|
|
decorators: ['@Injectable()'],
|
|
// Methods
|
|
methods: [
|
|
{
|
|
name: 'getUser',
|
|
type: 'Observable<User>',
|
|
description: 'Retrieves user data by ID',
|
|
args: [{ name: 'id', type: 'string' }],
|
|
returnType: 'Observable<User>',
|
|
modifierKind: 'public'
|
|
},
|
|
{
|
|
name: 'updateUser',
|
|
type: 'Observable<User>',
|
|
description: 'Updates user information',
|
|
args: [
|
|
{ name: 'id', type: 'string' },
|
|
{ name: 'userData', type: 'Partial<User>' }
|
|
],
|
|
returnType: 'Observable<User>',
|
|
modifierKind: 'public'
|
|
},
|
|
{
|
|
name: 'deleteUser',
|
|
type: 'Observable<void>',
|
|
description: 'Deletes a user account',
|
|
args: [{ name: 'id', type: 'string' }],
|
|
returnType: 'Observable<void>',
|
|
modifierKind: 'public'
|
|
}
|
|
],
|
|
// Properties
|
|
properties: [
|
|
{
|
|
name: 'currentUser$',
|
|
type: 'BehaviorSubject<User | null>',
|
|
description: 'Observable stream of current user state',
|
|
modifierKind: 'private'
|
|
},
|
|
{
|
|
name: 'apiUrl',
|
|
type: 'string',
|
|
description: 'Base URL for user API endpoints',
|
|
defaultValue: '"/api/users"',
|
|
modifierKind: 'private'
|
|
}
|
|
],
|
|
// Constructor
|
|
constructorObj: {
|
|
name: 'constructor',
|
|
description: 'Service constructor with HTTP client injection',
|
|
args: [
|
|
{ name: 'http', type: 'HttpClient' },
|
|
{ name: 'config', type: 'AppConfig' }
|
|
]
|
|
},
|
|
// Coverage
|
|
coveragePercent: 92,
|
|
coverageCount: '23/25'
|
|
};
|
|
}
|
|
else if (templateName.includes('module')) {
|
|
templateVariables = {
|
|
name: 'UserModule',
|
|
description: 'Feature module containing user-related components and services',
|
|
file: 'src/app/modules/user/user.module.ts',
|
|
type: 'module',
|
|
// Module metadata
|
|
declarations: [
|
|
{ name: 'UserProfileComponent', type: 'component' },
|
|
{ name: 'UserListComponent', type: 'component' },
|
|
{ name: 'UserCardDirective', type: 'directive' }
|
|
],
|
|
imports: [
|
|
{ name: 'CommonModule', type: 'module' },
|
|
{ name: 'ReactiveFormsModule', type: 'module' },
|
|
{ name: 'RouterModule', type: 'module' }
|
|
],
|
|
exports: [
|
|
{ name: 'UserProfileComponent', type: 'component' },
|
|
{ name: 'UserListComponent', type: 'component' }
|
|
],
|
|
providers: [
|
|
{ name: 'UserService', type: 'service' },
|
|
{ name: 'UserResolver', type: 'resolver' }
|
|
],
|
|
bootstrap: [],
|
|
schemas: []
|
|
};
|
|
}
|
|
else if (templateName.includes('interface')) {
|
|
templateVariables = {
|
|
name: 'User',
|
|
description: 'Interface defining the structure of user objects',
|
|
file: 'src/app/interfaces/user.interface.ts',
|
|
type: 'interface',
|
|
// Interface properties
|
|
properties: [
|
|
{
|
|
name: 'id',
|
|
type: 'string',
|
|
description: 'Unique identifier for the user',
|
|
optional: false
|
|
},
|
|
{
|
|
name: 'email',
|
|
type: 'string',
|
|
description: 'User email address',
|
|
optional: false
|
|
},
|
|
{
|
|
name: 'name',
|
|
type: 'string',
|
|
description: 'Full name of the user',
|
|
optional: false
|
|
},
|
|
{
|
|
name: 'avatar',
|
|
type: 'string',
|
|
description: 'URL to user avatar image',
|
|
optional: true
|
|
},
|
|
{
|
|
name: 'role',
|
|
type: 'UserRole',
|
|
description: 'User role permissions',
|
|
optional: true
|
|
}
|
|
],
|
|
// Interface methods (if any)
|
|
methods: [],
|
|
// Index signatures
|
|
indexSignatures: []
|
|
};
|
|
}
|
|
else {
|
|
// Generic data for other templates (directive, pipe, guard, etc.)
|
|
templateVariables = {
|
|
name: 'ExampleItem',
|
|
description: 'A sample item for demonstration purposes',
|
|
file: 'src/app/example.ts',
|
|
type: 'class',
|
|
// Basic properties that most templates would have
|
|
methods: [
|
|
{
|
|
name: 'ngOnInit',
|
|
type: 'void',
|
|
description: 'Lifecycle hook',
|
|
args: [],
|
|
returnType: 'void'
|
|
}
|
|
],
|
|
properties: [
|
|
{
|
|
name: 'isActive',
|
|
type: 'boolean',
|
|
description: 'Active state',
|
|
defaultValue: 'false'
|
|
}
|
|
]
|
|
};
|
|
}
|
|
commonContext = {
|
|
// Navigation and UI
|
|
depth: additionalContext.depth || 0,
|
|
breadcrumbs: additionalContext.breadcrumbs || [],
|
|
navTabs: compodocConfig.navTabConfig,
|
|
// Helper functions available in templates
|
|
t: function (key) { return "[Translation: ".concat(key, "]"); }, // Simulates i18n function
|
|
relativeURL: function (url) { return url; }, // URL helper
|
|
// Project information
|
|
projectTitle: compodocConfig.documentationMainName || compodocConfig.name || 'Documentation',
|
|
projectDescription: compodocConfig.documentationMainDescription || 'Documentation description',
|
|
// Current page context
|
|
pageType: templateName,
|
|
pageName: templateVariables.name || 'Unknown',
|
|
// Feature flags (from config)
|
|
showSourceCode: !compodocConfig.disableSourceCode,
|
|
showGraph: !compodocConfig.disableGraph,
|
|
showCoverage: !compodocConfig.disableCoverage,
|
|
showPrivateMembers: !compodocConfig.disablePrivate,
|
|
showProtectedMembers: !compodocConfig.disableProtected,
|
|
showInternalMembers: !compodocConfig.disableInternal
|
|
};
|
|
// Return only the Compodoc configuration options
|
|
send(res, 200, {
|
|
success: true,
|
|
categories: {
|
|
compodocConfig: {
|
|
title: 'Compodoc Configuration Options',
|
|
description: 'Edit these configuration options to customize the generated documentation. Changes will automatically regenerate the documentation.',
|
|
data: compodocConfig
|
|
}
|
|
},
|
|
// Legacy format for backward compatibility
|
|
data: compodocConfig,
|
|
context: { config: compodocConfig }
|
|
});
|
|
}
|
|
catch (error) {
|
|
logger.logger.error('Error getting session template data:', error);
|
|
send(res, 500, {
|
|
success: false,
|
|
message: 'Failed to get template data',
|
|
error: error instanceof Error ? error.message : 'Unknown error'
|
|
});
|
|
}
|
|
return [2 /*return*/];
|
|
});
|
|
});
|
|
};
|
|
TemplatePlaygroundServer.prototype.generateSessionDocs = function (req, res) {
|
|
return logger.__awaiter(this, void 0, void 0, function () {
|
|
var sessionId, _a, customTemplateContent, session, templatePath, error_8;
|
|
return logger.__generator(this, function (_b) {
|
|
switch (_b.label) {
|
|
case 0:
|
|
_b.trys.push([0, 3, , 4]);
|
|
sessionId = req.params.sessionId;
|
|
_a = req.body || {}, customTemplateContent = _a.customTemplateContent, _a.mockData;
|
|
if (!this.sessions.has(sessionId)) {
|
|
send(res, 404, {
|
|
success: false,
|
|
message: 'Session not found'
|
|
});
|
|
return [2 /*return*/];
|
|
}
|
|
session = this.sessions.get(sessionId);
|
|
this.updateSessionActivity(sessionId);
|
|
if (!(customTemplateContent && req.body.templatePath)) return [3 /*break*/, 2];
|
|
templatePath = path__namespace.join(session.templateDir, req.body.templatePath);
|
|
return [4 /*yield*/, fs__namespace.writeFile(templatePath, customTemplateContent, 'utf8')];
|
|
case 1:
|
|
_b.sent();
|
|
_b.label = 2;
|
|
case 2:
|
|
// Generate documentation for this session
|
|
this.generateDocumentation(sessionId, false); // No debounce for manual generation
|
|
send(res, 200, {
|
|
success: true,
|
|
message: 'Documentation generation started',
|
|
sessionId: sessionId
|
|
});
|
|
return [3 /*break*/, 4];
|
|
case 3:
|
|
error_8 = _b.sent();
|
|
logger.logger.error('Error generating session documentation:', error_8);
|
|
send(res, 500, {
|
|
success: false,
|
|
message: 'Failed to generate documentation',
|
|
error: error_8 instanceof Error ? error_8.message : 'Unknown error'
|
|
});
|
|
return [3 /*break*/, 4];
|
|
case 4: return [2 /*return*/];
|
|
}
|
|
});
|
|
});
|
|
};
|
|
TemplatePlaygroundServer.prototype.getSessionConfig = function (req, res) {
|
|
return logger.__awaiter(this, void 0, void 0, function () {
|
|
var sessionId, session, fullConfig;
|
|
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25;
|
|
return logger.__generator(this, function (_26) {
|
|
try {
|
|
sessionId = req.params.sessionId;
|
|
session = this.sessions.get(sessionId);
|
|
if (!session) {
|
|
send(res, 404, { success: false, message: 'Session not found' });
|
|
return [2 /*return*/];
|
|
}
|
|
this.updateSessionActivity(sessionId);
|
|
fullConfig = {
|
|
// Documentation Metadata
|
|
name: ((_a = session.config) === null || _a === void 0 ? void 0 : _a.name) || 'Application documentation',
|
|
// Paths and Output
|
|
output: ((_b = session.config) === null || _b === void 0 ? void 0 : _b.output) || './documentation/',
|
|
theme: ((_c = session.config) === null || _c === void 0 ? void 0 : _c.theme) || 'gitbook',
|
|
language: ((_d = session.config) === null || _d === void 0 ? void 0 : _d.language) || 'en-US',
|
|
base: ((_e = session.config) === null || _e === void 0 ? void 0 : _e.base) || '/',
|
|
// Assets and Custom UI
|
|
customFavicon: ((_f = session.config) === null || _f === void 0 ? void 0 : _f.customFavicon) || '',
|
|
customLogo: ((_g = session.config) === null || _g === void 0 ? void 0 : _g.customLogo) || '',
|
|
assetsFolder: ((_h = session.config) === null || _h === void 0 ? void 0 : _h.assetsFolder) || '',
|
|
extTheme: ((_j = session.config) === null || _j === void 0 ? void 0 : _j.extTheme) || '',
|
|
// Feature Toggles - Disable Options
|
|
disableSourceCode: !!((_k = session.config) === null || _k === void 0 ? void 0 : _k.disableSourceCode),
|
|
disableGraph: !!((_l = session.config) === null || _l === void 0 ? void 0 : _l.disableGraph),
|
|
disableCoverage: !!((_m = session.config) === null || _m === void 0 ? void 0 : _m.disableCoverage),
|
|
disablePrivate: !!((_o = session.config) === null || _o === void 0 ? void 0 : _o.disablePrivate),
|
|
disableProtected: !!((_p = session.config) === null || _p === void 0 ? void 0 : _p.disableProtected),
|
|
disableInternal: !!((_q = session.config) === null || _q === void 0 ? void 0 : _q.disableInternal),
|
|
disableLifeCycleHooks: !!((_r = session.config) === null || _r === void 0 ? void 0 : _r.disableLifeCycleHooks),
|
|
disableConstructors: !!((_s = session.config) === null || _s === void 0 ? void 0 : _s.disableConstructors),
|
|
disableRoutesGraph: !!((_t = session.config) === null || _t === void 0 ? void 0 : _t.disableRoutesGraph),
|
|
disableSearch: !!((_u = session.config) === null || _u === void 0 ? void 0 : _u.disableSearch),
|
|
disableDependencies: !!((_v = session.config) === null || _v === void 0 ? void 0 : _v.disableDependencies),
|
|
disableProperties: !!((_w = session.config) === null || _w === void 0 ? void 0 : _w.disableProperties),
|
|
disableDomTree: !!((_x = session.config) === null || _x === void 0 ? void 0 : _x.disableDomTree),
|
|
disableTemplateTab: !!((_y = session.config) === null || _y === void 0 ? void 0 : _y.disableTemplateTab),
|
|
disableStyleTab: !!((_z = session.config) === null || _z === void 0 ? void 0 : _z.disableStyleTab),
|
|
disableMainGraph: !!((_0 = session.config) === null || _0 === void 0 ? void 0 : _0.disableMainGraph),
|
|
disableFilePath: !!((_1 = session.config) === null || _1 === void 0 ? void 0 : _1.disableFilePath),
|
|
disableOverview: !!((_2 = session.config) === null || _2 === void 0 ? void 0 : _2.disableOverview),
|
|
// UI Options
|
|
hideGenerator: !!((_3 = session.config) === null || _3 === void 0 ? void 0 : _3.hideGenerator),
|
|
hideDarkModeToggle: !!((_4 = session.config) === null || _4 === void 0 ? void 0 : _4.hideDarkModeToggle),
|
|
minimal: !!((_5 = session.config) === null || _5 === void 0 ? void 0 : _5.minimal),
|
|
// Additional Content
|
|
includes: ((_6 = session.config) === null || _6 === void 0 ? void 0 : _6.includes) || '',
|
|
includesName: ((_7 = session.config) === null || _7 === void 0 ? void 0 : _7.includesName) || 'Additional documentation',
|
|
// Serving Options
|
|
port: ((_8 = session.config) === null || _8 === void 0 ? void 0 : _8.port) || 8080,
|
|
hostname: ((_9 = session.config) === null || _9 === void 0 ? void 0 : _9.hostname) || '127.0.0.1',
|
|
serve: !!((_10 = session.config) === null || _10 === void 0 ? void 0 : _10.serve),
|
|
open: !!((_11 = session.config) === null || _11 === void 0 ? void 0 : _11.open),
|
|
watch: !!((_12 = session.config) === null || _12 === void 0 ? void 0 : _12.watch),
|
|
// Export Options
|
|
exportFormat: ((_13 = session.config) === null || _13 === void 0 ? void 0 : _13.exportFormat) || 'html',
|
|
// Coverage Options
|
|
coverageTest: !!((_14 = session.config) === null || _14 === void 0 ? void 0 : _14.coverageTest),
|
|
coverageTestThreshold: ((_15 = session.config) === null || _15 === void 0 ? void 0 : _15.coverageTestThreshold) || 70,
|
|
coverageMinimumPerFile: ((_16 = session.config) === null || _16 === void 0 ? void 0 : _16.coverageMinimumPerFile) || 0,
|
|
coverageTestThresholdFail: !!((_17 = session.config) === null || _17 === void 0 ? void 0 : _17.coverageTestThresholdFail),
|
|
coverageTestShowOnlyFailed: !!((_18 = session.config) === null || _18 === void 0 ? void 0 : _18.coverageTestShowOnlyFailed),
|
|
unitTestCoverage: ((_19 = session.config) === null || _19 === void 0 ? void 0 : _19.unitTestCoverage) || '',
|
|
// Google Analytics
|
|
gaID: ((_20 = session.config) === null || _20 === void 0 ? void 0 : _20.gaID) || '',
|
|
gaSite: ((_21 = session.config) === null || _21 === void 0 ? void 0 : _21.gaSite) || 'auto',
|
|
// Advanced Options
|
|
silent: !!((_22 = session.config) === null || _22 === void 0 ? void 0 : _22.silent),
|
|
maxSearchResults: ((_23 = session.config) === null || _23 === void 0 ? void 0 : _23.maxSearchResults) || 15,
|
|
// Menu Configuration (as JSON string for editing)
|
|
toggleMenuItems: JSON.stringify(((_24 = session.config) === null || _24 === void 0 ? void 0 : _24.toggleMenuItems) || ['all']),
|
|
navTabConfig: JSON.stringify(((_25 = session.config) === null || _25 === void 0 ? void 0 : _25.navTabConfig) || [])
|
|
};
|
|
send(res, 200, {
|
|
config: fullConfig,
|
|
success: true
|
|
});
|
|
}
|
|
catch (error) {
|
|
logger.logger.error('Error getting session config:', error);
|
|
send(res, 500, {
|
|
success: false,
|
|
message: 'Failed to get config',
|
|
error: error instanceof Error ? error.message : 'Unknown error'
|
|
});
|
|
}
|
|
return [2 /*return*/];
|
|
});
|
|
});
|
|
};
|
|
TemplatePlaygroundServer.prototype.updateSessionConfig = function (req, res) {
|
|
return logger.__awaiter(this, void 0, void 0, function () {
|
|
var sessionId, config, session;
|
|
return logger.__generator(this, function (_a) {
|
|
try {
|
|
sessionId = req.params.sessionId;
|
|
config = req.body.config;
|
|
session = this.sessions.get(sessionId);
|
|
if (!session) {
|
|
send(res, 404, { success: false, message: 'Session not found' });
|
|
return [2 /*return*/];
|
|
}
|
|
this.updateSessionActivity(sessionId);
|
|
// Update session config
|
|
session.config = logger.__assign(logger.__assign({}, session.config), config);
|
|
// Trigger debounced documentation regeneration with new config
|
|
this.generateDocumentation(sessionId, true);
|
|
send(res, 200, {
|
|
success: true,
|
|
message: 'Configuration updated successfully',
|
|
config: session.config
|
|
});
|
|
}
|
|
catch (error) {
|
|
logger.logger.error('Error updating session config:', error);
|
|
send(res, 500, {
|
|
success: false,
|
|
message: 'Failed to update config',
|
|
error: error instanceof Error ? error.message : 'Unknown error'
|
|
});
|
|
}
|
|
return [2 /*return*/];
|
|
});
|
|
});
|
|
};
|
|
TemplatePlaygroundServer.prototype.serveSessionDocs = function (req, res) {
|
|
try {
|
|
var sessionId = req.params.sessionId;
|
|
var session = this.sessions.get(sessionId);
|
|
if (!session) {
|
|
send(res, 404, { success: false, message: 'Session not found' });
|
|
return;
|
|
}
|
|
this.updateSessionActivity(sessionId);
|
|
// Remove the session part from the URL to get the file path
|
|
var filePath = req.url.replace(/^\/api\/session\/[^\/]+\/docs/, '');
|
|
var fullPath = path__namespace.join(session.documentationDir, filePath || 'index.html');
|
|
if (fs__namespace.existsSync(fullPath)) {
|
|
var content = fs__namespace.readFileSync(fullPath);
|
|
var ext = path__namespace.extname(fullPath).toLowerCase();
|
|
var contentType = ext === '.html' ? 'text/html' :
|
|
ext === '.css' ? 'text/css' :
|
|
ext === '.js' ? 'application/javascript' :
|
|
ext === '.json' ? 'application/json' :
|
|
'text/plain';
|
|
res.setHeader('Content-Type', contentType);
|
|
res.end(content);
|
|
}
|
|
else {
|
|
res.statusCode = 404;
|
|
res.end('Documentation file not found');
|
|
}
|
|
}
|
|
catch (error) {
|
|
logger.logger.error('Error serving session docs:', error);
|
|
res.statusCode = 500;
|
|
res.end('Error serving documentation');
|
|
}
|
|
};
|
|
TemplatePlaygroundServer.prototype.isPortAvailable = function (port) {
|
|
return logger.__awaiter(this, void 0, void 0, function () {
|
|
return logger.__generator(this, function (_a) {
|
|
return [2 /*return*/, new Promise(function (resolve) {
|
|
var server = http__namespace.createServer();
|
|
server.listen(port, function () {
|
|
server.close(function () { return resolve(true); });
|
|
});
|
|
server.on('error', function () { return resolve(false); });
|
|
})];
|
|
});
|
|
});
|
|
};
|
|
TemplatePlaygroundServer.prototype.findAvailablePort = function (startPort) {
|
|
return logger.__awaiter(this, void 0, void 0, function () {
|
|
var port;
|
|
return logger.__generator(this, function (_a) {
|
|
switch (_a.label) {
|
|
case 0:
|
|
port = startPort;
|
|
_a.label = 1;
|
|
case 1:
|
|
if (!(port < startPort + 100)) return [3 /*break*/, 3];
|
|
return [4 /*yield*/, this.isPortAvailable(port)];
|
|
case 2:
|
|
if (_a.sent()) {
|
|
return [2 /*return*/, port];
|
|
}
|
|
port++;
|
|
return [3 /*break*/, 1];
|
|
case 3: throw new Error("No available port found in range ".concat(startPort, "-").concat(startPort + 99));
|
|
}
|
|
});
|
|
});
|
|
};
|
|
TemplatePlaygroundServer.prototype.start = function () {
|
|
return logger.__awaiter(this, void 0, void 0, function () {
|
|
var originalPort, _a, error_10;
|
|
var _this = this;
|
|
return logger.__generator(this, function (_b) {
|
|
switch (_b.label) {
|
|
case 0:
|
|
_b.trys.push([0, 6, , 7]);
|
|
return [4 /*yield*/, this.isPortAvailable(this.port)];
|
|
case 1:
|
|
if (!!(_b.sent())) return [3 /*break*/, 5];
|
|
originalPort = this.port;
|
|
_b.label = 2;
|
|
case 2:
|
|
_b.trys.push([2, 4, , 5]);
|
|
_a = this;
|
|
return [4 /*yield*/, this.findAvailablePort(this.port + 1)];
|
|
case 3:
|
|
_a.port = _b.sent();
|
|
logger.logger.warn("\u26A0\uFE0F Port ".concat(originalPort, " is in use. Using port ").concat(this.port, " instead."));
|
|
return [3 /*break*/, 5];
|
|
case 4:
|
|
_b.sent();
|
|
throw new Error("Port ".concat(originalPort, " is in use and no alternative port could be found. Please stop the process using port ").concat(originalPort, " or specify a different port."));
|
|
case 5:
|
|
this.server = this.app.listen(this.port, function () {
|
|
logger.logger.info("\uD83C\uDFA8 Template Playground is running at: http://localhost:".concat(_this.port));
|
|
logger.logger.info('📝 Use this tool to customize and preview Compodoc templates');
|
|
logger.logger.info('🔧 Edit templates in the left panel and see live preview on the right');
|
|
logger.logger.info('💾 Export your customized templates when ready');
|
|
logger.logger.info('');
|
|
logger.logger.info('Press Ctrl+C to stop the server');
|
|
});
|
|
// Graceful shutdown
|
|
process.on('SIGTERM', this.stop.bind(this));
|
|
process.on('SIGINT', this.stop.bind(this));
|
|
return [3 /*break*/, 7];
|
|
case 6:
|
|
error_10 = _b.sent();
|
|
logger.logger.error('Failed to start Template Playground:', error_10);
|
|
throw error_10;
|
|
case 7: return [2 /*return*/];
|
|
}
|
|
});
|
|
});
|
|
};
|
|
TemplatePlaygroundServer.prototype.stop = function () {
|
|
var _this = this;
|
|
return new Promise(function (resolve) {
|
|
var e_6, _a, e_7, _b, e_8, _c;
|
|
var _d;
|
|
try {
|
|
// Remove signal handlers to prevent memory leaks
|
|
for (var _e = logger.__values(_this.signalHandlers.entries()), _f = _e.next(); !_f.done; _f = _e.next()) {
|
|
var _g = logger.__read(_f.value, 2), signal = _g[0], handler = _g[1];
|
|
process.removeListener(signal, handler);
|
|
}
|
|
}
|
|
catch (e_6_1) { e_6 = { error: e_6_1 }; }
|
|
finally {
|
|
try {
|
|
if (_f && !_f.done && (_a = _e.return)) _a.call(_e);
|
|
}
|
|
finally { if (e_6) throw e_6.error; }
|
|
}
|
|
_this.signalHandlers.clear();
|
|
// Clear cleanup interval
|
|
if (_this.cleanupInterval) {
|
|
clearInterval(_this.cleanupInterval);
|
|
_this.cleanupInterval = null;
|
|
}
|
|
try {
|
|
// Clear all debounce timers
|
|
for (var _h = logger.__values(_this.debounceTimers.values()), _j = _h.next(); !_j.done; _j = _h.next()) {
|
|
var timer = _j.value;
|
|
clearTimeout(timer);
|
|
}
|
|
}
|
|
catch (e_7_1) { e_7 = { error: e_7_1 }; }
|
|
finally {
|
|
try {
|
|
if (_j && !_j.done && (_b = _h.return)) _b.call(_h);
|
|
}
|
|
finally { if (e_7) throw e_7.error; }
|
|
}
|
|
_this.debounceTimers.clear();
|
|
try {
|
|
// Clean up all sessions
|
|
for (var _k = logger.__values(_this.sessions.keys()), _l = _k.next(); !_l.done; _l = _k.next()) {
|
|
var sessionId = _l.value;
|
|
_this.cleanupSession(sessionId);
|
|
}
|
|
}
|
|
catch (e_8_1) { e_8 = { error: e_8_1 }; }
|
|
finally {
|
|
try {
|
|
if (_l && !_l.done && (_c = _k.return)) _c.call(_k);
|
|
}
|
|
finally { if (e_8) throw e_8.error; }
|
|
}
|
|
// Get the actual HTTP server from Polka instance
|
|
var httpServer = (_d = _this.server) === null || _d === void 0 ? void 0 : _d.server;
|
|
if (httpServer && typeof httpServer.close === 'function') {
|
|
var resolved_1 = false;
|
|
httpServer.close(function (error) {
|
|
if (!resolved_1) {
|
|
resolved_1 = true;
|
|
if (error) {
|
|
logger.logger.warn('Error closing server:', error);
|
|
}
|
|
else {
|
|
logger.logger.info('Template Playground server stopped');
|
|
}
|
|
resolve();
|
|
}
|
|
});
|
|
// Force close after 1 second if it hasn't closed naturally
|
|
setTimeout(function () {
|
|
if (!resolved_1) {
|
|
resolved_1 = true;
|
|
logger.logger.info('Server close timeout - resolving anyway');
|
|
resolve();
|
|
}
|
|
}, 1000);
|
|
}
|
|
else {
|
|
logger.logger.info('No HTTP server to close or close method not available');
|
|
resolve();
|
|
}
|
|
});
|
|
};
|
|
return TemplatePlaygroundServer;
|
|
}());
|
|
|
|
exports.TemplatePlaygroundServer = TemplatePlaygroundServer;
|
|
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGVtcGxhdGUtcGxheWdyb3VuZC1zZXJ2ZXIuanMiLCJzb3VyY2VzIjpbIi4uL3NyYy90ZW1wbGF0ZS1wbGF5Z3JvdW5kL3RlbXBsYXRlLXBsYXlncm91bmQtc2VydmVyLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImNvbnN0IHBvbGthID0gcmVxdWlyZSgncG9sa2EnKTtcbmNvbnN0IHNpcnYgPSByZXF1aXJlKCdzaXJ2Jyk7XG5jb25zdCB7IGpzb24sIHVybGVuY29kZWQgfSA9IHJlcXVpcmUoJ2JvZHktcGFyc2VyJyk7XG5jb25zdCBzZW5kID0gcmVxdWlyZSgnQHBvbGthL3NlbmQtdHlwZScpO1xuaW1wb3J0IHsgSW5jb21pbmdNZXNzYWdlLCBTZXJ2ZXJSZXNwb25zZSB9IGZyb20gJ2h0dHAnO1xuaW1wb3J0IHsgUG9sa2EgfSBmcm9tICdwb2xrYSc7XG5pbXBvcnQgKiBhcyBwYXRoIGZyb20gJ3BhdGgnO1xuaW1wb3J0ICogYXMgZnMgZnJvbSAnZnMtZXh0cmEnO1xuaW1wb3J0ICogYXMgaHR0cCBmcm9tICdodHRwJztcbmltcG9ydCAqIGFzIGNyeXB0byBmcm9tICdjcnlwdG8nO1xuaW1wb3J0ICogYXMgb3MgZnJvbSAnb3MnO1xuY29uc3QgYXJjaGl2ZXIgPSByZXF1aXJlKCdhcmNoaXZlcicpO1xuaW1wb3J0IHsgZXhlY1N5bmMgfSBmcm9tICdjaGlsZF9wcm9jZXNzJztcbmltcG9ydCB7IGxvZ2dlciB9IGZyb20gJy4uL3V0aWxzL2xvZ2dlcic7XG5cbmludGVyZmFjZSBQbGF5Z3JvdW5kU2Vzc2lvbiB7XG4gICAgaWQ6IHN0cmluZztcbiAgICB0ZW1wbGF0ZURpcjogc3RyaW5nO1xuICAgIGRvY3VtZW50YXRpb25EaXI6IHN0cmluZztcbiAgICBsYXN0QWN0aXZpdHk6IG51bWJlcjtcbiAgICBjb25maWc6IENvbXBvRG9jQ29uZmlnO1xuICAgIGRvY3VtZW50YXRpb25HZW5lcmF0ZWQ/OiBib29sZWFuO1xufVxuXG5pbnRlcmZhY2UgQ29tcG9Eb2NDb25maWcge1xuICAgIC8vIERvY3VtZW50YXRpb24gTWV0YWRhdGFcbiAgICBuYW1lPzogc3RyaW5nO1xuXG4gICAgLy8gUGF0aHMgYW5kIE91dHB1dFxuICAgIG91dHB1dD86IHN0cmluZztcbiAgICB0aGVtZT86IHN0cmluZztcbiAgICBsYW5ndWFnZT86IHN0cmluZztcbiAgICBiYXNlPzogc3RyaW5nO1xuXG4gICAgLy8gQXNzZXRzIGFuZCBDdXN0b20gVUlcbiAgICBjdXN0b21GYXZpY29uPzogc3RyaW5nO1xuICAgIGN1c3RvbUxvZ28/OiBzdHJpbmc7XG4gICAgYXNzZXRzRm9sZGVyPzogc3RyaW5nO1xuICAgIGV4dFRoZW1lPzogc3RyaW5nO1xuXG4gICAgLy8gRmVhdHVyZSBUb2dnbGVzIC0gRGlzYWJsZSBPcHRpb25zXG4gICAgZGlzYWJsZVNvdXJjZUNvZGU/OiBib29sZWFuO1xuICAgIGRpc2FibGVHcmFwaD86IGJvb2xlYW47XG4gICAgZGlzYWJsZUNvdmVyYWdlPzogYm9vbGVhbjtcbiAgICBkaXNhYmxlUHJpdmF0ZT86IGJvb2xlYW47XG4gICAgZGlzYWJsZVByb3RlY3RlZD86IGJvb2xlYW47XG4gICAgZGlzYWJsZUludGVybmFsPzogYm9vbGVhbjtcbiAgICBkaXNhYmxlTGlmZUN5Y2xlSG9va3M/OiBib29sZWFuO1xuICAgIGRpc2FibGVDb25zdHJ1Y3RvcnM/OiBib29sZWFuO1xuICAgIGRpc2FibGVSb3V0ZXNHcmFwaD86IGJvb2xlYW47XG4gICAgZGlzYWJsZVNlYXJjaD86IGJvb2xlYW47XG4gICAgZGlzYWJsZURlcGVuZGVuY2llcz86IGJvb2xlYW47XG4gICAgZGlzYWJsZVByb3BlcnRpZXM/OiBib29sZWFuO1xuICAgIGRpc2FibGVEb21UcmVlPzogYm9vbGVhbjtcbiAgICBkaXNhYmxlVGVtcGxhdGVUYWI/OiBib29sZWFuO1xuICAgIGRpc2FibGVTdHlsZVRhYj86IGJvb2xlYW47XG4gICAgZGlzYWJsZU1haW5HcmFwaD86IGJvb2xlYW47XG4gICAgZGlzYWJsZUZpbGVQYXRoPzogYm9vbGVhbjtcbiAgICBkaXNhYmxlT3ZlcnZpZXc/OiBib29sZWFuO1xuXG4gICAgLy8gVUkgT3B0aW9uc1xuICAgIGhpZGVHZW5lcmF0b3I/OiBib29sZWFuO1xuICAgIGhpZGVEYXJrTW9kZVRvZ2dsZT86IGJvb2xlYW47XG4gICAgbWluaW1hbD86IGJvb2xlYW47XG5cbiAgICAvLyBBZGRpdGlvbmFsIENvbnRlbnRcbiAgICBpbmNsdWRlcz86IHN0cmluZztcbiAgICBpbmNsdWRlc05hbWU/OiBzdHJpbmc7XG5cbiAgICAvLyBTZXJ2aW5nIE9wdGlvbnNcbiAgICBwb3J0PzogbnVtYmVyO1xuICAgIGhvc3RuYW1lPzogc3RyaW5nO1xuICAgIHNlcnZlPzogYm9vbGVhbjtcbiAgICBvcGVuPzogYm9vbGVhbjtcbiAgICB3YXRjaD86IGJvb2xlYW47XG5cbiAgICAvLyBFeHBvcnQgT3B0aW9uc1xuICAgIGV4cG9ydEZvcm1hdD86IHN0cmluZztcblxuICAgIC8vIENvdmVyYWdlIE9wdGlvbnNcbiAgICBjb3ZlcmFnZVRlc3Q/OiBib29sZWFuO1xuICAgIGNvdmVyYWdlVGVzdFRocmVzaG9sZD86IG51bWJlcjtcbiAgICBjb3ZlcmFnZU1pbmltdW1QZXJGaWxlPzogbnVtYmVyO1xuICAgIGNvdmVyYWdlVGVzdFRocmVzaG9sZEZhaWw/OiBib29sZWFuO1xuICAgIGNvdmVyYWdlVGVzdFNob3dPbmx5RmFpbGVkPzogYm9vbGVhbjtcbiAgICB1bml0VGVzdENvdmVyYWdlPzogc3RyaW5nO1xuXG4gICAgLy8gR29vZ2xlIEFuYWx5dGljc1xuICAgIGdhSUQ/OiBzdHJpbmc7XG4gICAgZ2FTaXRlPzogc3RyaW5nO1xuXG4gICAgLy8gQWR2YW5jZWQgT3B0aW9uc1xuICAgIHNpbGVudD86IGJvb2xlYW47XG4gICAgbWF4U2VhcmNoUmVzdWx0cz86IG51bWJlcjtcblxuICAgIC8vIE1lbnUgQ29uZmlndXJhdGlvblxuICAgIHRvZ2dsZU1lbnVJdGVtcz86IHN0cmluZ1tdIHwgc3RyaW5nO1xuICAgIG5hdlRhYkNvbmZpZz86IGFueVtdIHwgc3RyaW5nO1xufVxuXG5leHBvcnQgY2xhc3MgVGVtcGxhdGVQbGF5Z3JvdW5kU2VydmVyIHtcbiAgICBwcml2YXRlIGFwcDogUG9sa2E7XG4gICAgcHJpdmF0ZSBzZXJ2ZXI6IGFueTtcbiAgICBwcml2YXRlIHBvcnQ6IG51bWJlcjtcbiAgICBwcml2YXRlIGhhbmRsZWJhcnM6IGFueTtcbiAgICBwcml2YXRlIHNlc3Npb25zOiBNYXA8c3RyaW5nLCBQbGF5Z3JvdW5kU2Vzc2lvbj4gPSBuZXcgTWFwKCk7XG4gICAgcHJpdmF0ZSBpcFRvU2Vzc2lvbklkOiBNYXA8c3RyaW5nLCBzdHJpbmc+ID0gbmV3IE1hcCgpO1xuICAgIHByaXZhdGUgZGVib3VuY2VUaW1lcnM6IE1hcDxzdHJpbmcsIE5vZGVKUy5UaW1lb3V0PiA9IG5ldyBNYXAoKTtcbiAgICBwcml2YXRlIGZha2VQcm9qZWN0UGF0aDogc3RyaW5nO1xuICAgIHByaXZhdGUgb3JpZ2luYWxUZW1wbGF0ZXNQYXRoOiBzdHJpbmc7XG4gICAgcHJpdmF0ZSBjbGVhbnVwSW50ZXJ2YWw6IE5vZGVKUy5UaW1lb3V0O1xuICAgIHByaXZhdGUgc2lnbmFsSGFuZGxlcnM6IE1hcDxzdHJpbmcsICguLi5hcmdzOiBhbnlbXSkgPT4gdm9pZD4gPSBuZXcgTWFwKCk7XG5cbiAgICBjb25zdHJ1Y3Rvcihwb3J0PzogbnVtYmVyKSB7XG4gICAgICAgIHRoaXMucG9ydCA9IHBvcnQgfHwgcGFyc2VJbnQocHJvY2Vzcy5lbnYuUExBWUdST1VORF9QT1JUIHx8IHByb2Nlc3MuZW52LlBPUlQgfHwgJzMwMDEnLCAxMCk7XG4gICAgICAgIHRoaXMuYXBwID0gcG9sa2EoKTtcbiAgICAgICAgdGhpcy5zZXR1cFBhdGhzKCk7XG4gICAgICAgIHRoaXMuaW5pdGlhbGl6ZUhhbmRsZWJhcnMoKTtcbiAgICAgICAgdGhpcy5zZXR1cE1pZGRsZXdhcmUoKTtcbiAgICAgICAgdGhpcy5zZXR1cFJvdXRlcygpO1xuICAgICAgICB0aGlzLnN0YXJ0U2Vzc2lvbkNsZWFudXAoKTtcbiAgICAgICAgdGhpcy5zZXR1cFNpZ25hbEhhbmRsZXJzKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0IHRoZSB1bmRlcmx5aW5nIEhUVFAgc2VydmVyIGluc3RhbmNlIGZvciB0ZXN0aW5nIHB1cnBvc2VzXG4gICAgICogQHJldHVybnMgSFRUUCBzZXJ2ZXIgaW5zdGFuY2Ugb3IgbnVsbCBpZiBub3Qgc3RhcnRlZFxuICAgICAqL1xuICAgIHB1YmxpYyBnZXRIdHRwU2VydmVyKCk6IGFueSB7XG4gICAgICAgIC8vIFBvbGthIHN0b3JlcyB0aGUgYWN0dWFsIEhUVFAgc2VydmVyIGluIHRoZSAuc2VydmVyIHByb3BlcnR5XG4gICAgICAgIC8vIFRoaXMgaXMgbmVlZGVkIGZvciBTdXBlcnRlc3QgY29tcGF0aWJpbGl0eSB3aGljaCBleHBlY3RzIGEgTm9kZS5qcyBIVFRQIHNlcnZlclxuICAgICAgICByZXR1cm4gdGhpcy5zZXJ2ZXI/LnNlcnZlciB8fCBudWxsO1xuICAgIH1cblxuICAgIHByaXZhdGUgc2V0dXBTaWduYWxIYW5kbGVycygpOiB2b2lkIHtcbiAgICAgICAgLy8gU2tpcCBzaWduYWwgaGFuZGxlcnMgZW50aXJlbHkgaW4gdGVzdCBlbnZpcm9ubWVudCB0byBwcmV2ZW50IG1lbW9yeSBsZWFrc1xuICAgICAgICBpZiAocHJvY2Vzcy5lbnYuTk9ERV9FTlYgPT09ICd0ZXN0Jykge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gSGFuZGxlIENUUkwrQyAoU0lHSU5UKSBhbmQgb3RoZXIgdGVybWluYXRpb24gc2lnbmFsc1xuICAgICAgICBjb25zdCBzaWduYWxzID0gWydTSUdJTlQnLCAnU0lHVEVSTScsICdTSUdVU1IyJ107XG4gICAgICAgIFxuICAgICAgICBzaWduYWxzLmZvckVhY2goc2lnbmFsID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGhhbmRsZXIgPSBhc3luYyAoKSA9PiB7XG4gICAgICAgICAgICAgICAgbG9nZ2VyLmluZm8oYFJlY2VpdmVkICR7c2lnbmFsfSwgc2h1dHRpbmcgZG93biBUZW1wbGF0ZSBQbGF5Z3JvdW5kIHNlcnZlciBncmFjZWZ1bGx5Li4uYCk7XG4gICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgYXdhaXQgdGhpcy5zdG9wKCk7XG4gICAgICAgICAgICAgICAgICAgIGxvZ2dlci5pbmZvKCdTZXJ2ZXIgc2h1dGRvd24gY29tcGxldGUnKTtcbiAgICAgICAgICAgICAgICAgICAgcHJvY2Vzcy5leGl0KDApO1xuICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgIGxvZ2dlci5lcnJvcignRXJyb3IgZHVyaW5nIHNlcnZlciBzaHV0ZG93bjonLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgIHByb2Nlc3MuZXhpdCgxKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgXG4gICAgICAgICAgICB0aGlzLnNpZ25hbEhhbmRsZXJzLnNldChzaWduYWwsIGhhbmRsZXIpO1xuICAgICAgICAgICAgcHJvY2Vzcy5vbihzaWduYWwsIGhhbmRsZXIpO1xuICAgICAgICB9KTtcblxuICAgICAgICAvLyBIYW5kbGUgdW5jYXVnaHQgZXhjZXB0aW9ucyAob25seSBpZiBub3QgYWxyZWFkeSBoYW5kbGVkKVxuICAgICAgICBpZiAocHJvY2Vzcy5saXN0ZW5lckNvdW50KCd1bmNhdWdodEV4Y2VwdGlvbicpID09PSAwKSB7XG4gICAgICAgICAgICBjb25zdCB1bmNhdWdodEhhbmRsZXIgPSBhc3luYyAoZXJyb3IpID0+IHtcbiAgICAgICAgICAgICAgICBsb2dnZXIuZXJyb3IoJ1VuY2F1Z2h0IGV4Y2VwdGlvbjonLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgYXdhaXQgdGhpcy5zdG9wKCk7XG4gICAgICAgICAgICAgICAgfSBjYXRjaCAoc3RvcEVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgIGxvZ2dlci5lcnJvcignRXJyb3IgZHVyaW5nIGVtZXJnZW5jeSBzaHV0ZG93bjonLCBzdG9wRXJyb3IpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBwcm9jZXNzLmV4aXQoMSk7XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgXG4gICAgICAgICAgICB0aGlzLnNpZ25hbEhhbmRsZXJzLnNldCgndW5jYXVnaHRFeGNlcHRpb24nLCB1bmNhdWdodEhhbmRsZXIpO1xuICAgICAgICAgICAgcHJvY2Vzcy5vbigndW5jYXVnaHRFeGNlcHRpb24nLCB1bmNhdWdodEhhbmRsZXIpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gSGFuZGxlIHVuaGFuZGxlZCBwcm9taXNlIHJlamVjdGlvbnMgKG9ubHkgaWYgbm90IGFscmVhZHkgaGFuZGxlZClcbiAgICAgICAgaWYgKHByb2Nlc3MubGlzdGVuZXJDb3VudCgndW5oYW5kbGVkUmVqZWN0aW9uJykgPT09IDApIHtcbiAgICAgICAgICAgIGNvbnN0IHJlamVjdGlvbkhhbmRsZXIgPSBhc3luYyAocmVhc29uLCBwcm9taXNlKSA9PiB7XG4gICAgICAgICAgICAgICAgbG9nZ2VyLmVycm9yKCdVbmhhbmRsZWQgcmVqZWN0aW9uIGF0OicsIHByb21pc2UsICdyZWFzb246JywgcmVhc29uKTtcbiAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICBhd2FpdCB0aGlzLnN0b3AoKTtcbiAgICAgICAgICAgICAgICB9IGNhdGNoIChzdG9wRXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgbG9nZ2VyLmVycm9yKCdFcnJvciBkdXJpbmcgZW1lcmdlbmN5IHNodXRkb3duOicsIHN0b3BFcnJvcik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHByb2Nlc3MuZXhpdCgxKTtcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBcbiAgICAgICAgICAgIHRoaXMuc2lnbmFsSGFuZGxlcnMuc2V0KCd1bmhhbmRsZWRSZWplY3Rpb24nLCByZWplY3Rpb25IYW5kbGVyKTtcbiAgICAgICAgICAgIHByb2Nlc3Mub24oJ3VuaGFuZGxlZFJlamVjdGlvbicsIHJlamVjdGlvbkhhbmRsZXIpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBzZXR1cFBhdGhzKCk6IHZvaWQge1xuICAgICAgICAvLyBUcnkgdG8gZmluZCBwYXRocyBmb3IgZGlzdHJpYnV0ZWQgcGFja2FnZSBmaXJzdCwgdGhlbiBmYWxsIGJhY2sgdG8gZGV2ZWxvcG1lbnQgcGF0aHNcblxuICAgICAgICAvLyBGb3IgcGxheWdyb3VuZC1kZW1vOiBjaGVjayByZXNvdXJjZXMvcGxheWdyb3VuZC1kZW1vIGZpcnN0LCB0aGVuIHNyYyBkaXJlY3RvcnlcbiAgICAgICAgY29uc3QgZGlzdHJpYnV0ZWRGYWtlUHJvamVjdFBhdGggPSBwYXRoLmpvaW4oX19kaXJuYW1lLCAncmVzb3VyY2VzJywgJ3BsYXlncm91bmQtZGVtbycpO1xuICAgICAgICBjb25zdCBkZXZGYWtlUHJvamVjdFBhdGggPSBwYXRoLmpvaW4ocHJvY2Vzcy5jd2QoKSwgJ3NyYycsICdwbGF5Z3JvdW5kLWRlbW8nKTtcblxuICAgICAgICBpZiAoZnMuZXhpc3RzU3luYyhkaXN0cmlidXRlZEZha2VQcm9qZWN0UGF0aCkpIHtcbiAgICAgICAgICAgIHRoaXMuZmFrZVByb2plY3RQYXRoID0gZGlzdHJpYnV0ZWRGYWtlUHJvamVjdFBhdGg7XG4gICAgICAgIH0gZWxzZSBpZiAoZnMuZXhpc3RzU3luYyhkZXZGYWtlUHJvamVjdFBhdGgpKSB7XG4gICAgICAgICAgICB0aGlzLmZha2VQcm9qZWN0UGF0aCA9IGRldkZha2VQcm9qZWN0UGF0aDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcigncGxheWdyb3VuZC1kZW1vIGRpcmVjdG9yeSBub3QgZm91bmQuIFBsZWFzZSBlbnN1cmUgaXQgZXhpc3RzLicpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gRm9yIHRlbXBsYXRlczogY2hlY2sgaWYgd2UncmUgcnVubmluZyBmcm9tIGRpc3QgKGRpc3RyaWJ1dGVkKSBvciBkZXZlbG9wbWVudFxuICAgICAgICBjb25zdCBkaXN0cmlidXRlZFRlbXBsYXRlc1BhdGggPSBwYXRoLmpvaW4oX19kaXJuYW1lLCAndGVtcGxhdGVzJyk7ICAvLyBXaGVuIHJ1bm5pbmcgZnJvbSBkaXN0LywgdGhpcyBpcyBkaXN0L3RlbXBsYXRlc1xuICAgICAgICBjb25zdCBkZXZUZW1wbGF0ZXNQYXRoID0gcGF0aC5qb2luKHByb2Nlc3MuY3dkKCksICdzcmMnLCAndGVtcGxhdGVzJyk7XG4gICAgICAgIGNvbnN0IGxlZ2FjeVRlbXBsYXRlc1BhdGggPSBwYXRoLmpvaW4ocHJvY2Vzcy5jd2QoKSwgJ2hicy10ZW1wbGF0ZXMtY29weScpO1xuXG4gICAgICAgIGlmIChmcy5leGlzdHNTeW5jKGRpc3RyaWJ1dGVkVGVtcGxhdGVzUGF0aCkpIHtcbiAgICAgICAgICAgIHRoaXMub3JpZ2luYWxUZW1wbGF0ZXNQYXRoID0gZGlzdHJpYnV0ZWRUZW1wbGF0ZXNQYXRoO1xuICAgICAgICB9IGVsc2UgaWYgKGZzLmV4aXN0c1N5bmMoZGV2VGVtcGxhdGVzUGF0aCkpIHtcbiAgICAgICAgICAgIHRoaXMub3JpZ2luYWxUZW1wbGF0ZXNQYXRoID0gZGV2VGVtcGxhdGVzUGF0aDtcbiAgICAgICAgfSBlbHNlIGlmIChmcy5leGlzdHNTeW5jKGxlZ2FjeVRlbXBsYXRlc1BhdGgpKSB7XG4gICAgICAgICAgICAvLyBLZWVwIGxlZ2FjeSBzdXBwb3J0IGZvciBleGlzdGluZyBoYnMtdGVtcGxhdGVzLWNvcHlcbiAgICAgICAgICAgIHRoaXMub3JpZ2luYWxUZW1wbGF0ZXNQYXRoID0gbGVnYWN5VGVtcGxhdGVzUGF0aDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignVGVtcGxhdGVzIGRpcmVjdG9yeSBub3QgZm91bmQuIFBsZWFzZSBlbnN1cmUgc3JjL3RlbXBsYXRlcyBvciBkaXN0L3RlbXBsYXRlcyBleGlzdHMuJyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIGdldENsaWVudElQKHJlcTogSW5jb21pbmdNZXNzYWdlKTogc3RyaW5nIHtcbiAgICAgICAgLy8gR2V0IElQIGFkZHJlc3MgZnJvbSB2YXJpb3VzIGhlYWRlcnMgKGhhbmRsZXMgcHJveGllcywgbG9hZCBiYWxhbmNlcnMsIGV0Yy4pXG4gICAgICAgIGNvbnN0IGZvcndhcmRlZCA9IHJlcS5oZWFkZXJzWyd4LWZvcndhcmRlZC1mb3InXSBhcyBzdHJpbmc7XG4gICAgICAgIGNvbnN0IHJlYWxJUCA9IHJlcS5oZWFkZXJzWyd4LXJlYWwtaXAnXSBhcyBzdHJpbmc7XG4gICAgICAgIGNvbnN0IHJlbW90ZUFkZHIgPSAocmVxIGFzIEluY29taW5nTWVzc2FnZSAmIHsgc29ja2V0PzogeyByZW1vdGVBZGRyZXNzPzogc3RyaW5nIH0gfSkuc29ja2V0Py5yZW1vdGVBZGRyZXNzIHx8ICd1bmtub3duJztcblxuICAgICAgICBsZXQgaXAgPSBmb3J3YXJkZWQ/LnNwbGl0KCcsJylbMF0gfHwgcmVhbElQIHx8IHJlbW90ZUFkZHIgfHwgJ3Vua25vd24nO1xuXG4gICAgICAgIC8vIENsZWFuIHVwIElQdjYgbG9jYWxob3N0XG4gICAgICAgIGlmIChpcCA9PT0gJzo6MScgfHwgaXAgPT09ICc6OmZmZmY6MTI3LjAuMC4xJykge1xuICAgICAgICAgICAgaXAgPSAnMTI3LjAuMC4xJztcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBpcDtcbiAgICB9XG5cbiAgICBwcml2YXRlIGdlbmVyYXRlU2Vzc2lvbklkRnJvbUlQKGlwOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgICAgICAvLyBDcmVhdGUgYSBjb25zaXN0ZW50IGhhc2ggZnJvbSBJUCBhZGRyZXNzXG4gICAgICAgIHJldHVybiBjcnlwdG8uY3JlYXRlSGFzaCgnbWQ1JykudXBkYXRlKGlwICsgJ3RlbXBsYXRlLXBsYXlncm91bmQtc2FsdCcpLmRpZ2VzdCgnaGV4Jyk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBjcmVhdGVPckdldFNlc3Npb25CeUlQKGlwOiBzdHJpbmcpOiBQbGF5Z3JvdW5kU2Vzc2lvbiB7XG4gICAgICAgIC8vIENoZWNrIGlmIHNlc3Npb24gYWxyZWFkeSBleGlzdHMgZm9yIHRoaXMgSVBcbiAgICAgICAgY29uc3QgZXhpc3RpbmdTZXNzaW9uSWQgPSB0aGlzLmlwVG9TZXNzaW9uSWQuZ2V0KGlwKTtcbiAgICAgICAgaWYgKGV4aXN0aW5nU2Vzc2lvbklkICYmIHRoaXMuc2Vzc2lvbnMuaGFzKGV4aXN0aW5nU2Vzc2lvbklkKSkge1xuICAgICAgICAgICAgY29uc3Qgc2Vzc2lvbiA9IHRoaXMuc2Vzc2lvbnMuZ2V0KGV4aXN0aW5nU2Vzc2lvbklkKSE7XG4gICAgICAgICAgICAvLyBVcGRhdGUgbGFzdCBhY3Rpdml0eVxuICAgICAgICAgICAgc2Vzc2lvbi5sYXN0QWN0aXZpdHkgPSBEYXRlLm5vdygpO1xuICAgICAgICAgICAgbG9nZ2VyLmluZm8oYOKZu++4jyAgUmV1c2luZyBleGlzdGluZyBzZXNzaW9uIGZvciBJUCAke2lwfTogJHtleGlzdGluZ1Nlc3Npb25JZH1gKTtcbiAgICAgICAgICAgIHJldHVybiBzZXNzaW9uO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gQ3JlYXRlIG5ldyBzZXNzaW9uXG4gICAgICAgIGNvbnN0IHNlc3Npb25JZCA9IHRoaXMuZ2VuZXJhdGVTZXNzaW9uSWRGcm9tSVAoaXApO1xuICAgICAgICBjb25zdCB0ZW1wbGF0ZURpciA9IHBhdGguam9pbihvcy50bXBkaXIoKSwgYGhicy10ZW1wbGF0ZXMtY29weS0ke3Nlc3Npb25JZH1gKTtcbiAgICAgICAgY29uc3QgZG9jdW1lbnRhdGlvbkRpciA9IHBhdGguam9pbihvcy50bXBkaXIoKSwgYGdlbmVyYXRlZC1kb2N1bWVudGF0aW9uLSR7c2Vzc2lvbklkfWApO1xuXG4gICAgICAgIC8vIENsZWFuIHVwIGFueSBleGlzdGluZyBkaXJlY3RvcmllcyBmcm9tIHByZXZpb3VzIHNlc3Npb25zXG4gICAgICAgIGlmIChmcy5leGlzdHNTeW5jKHRlbXBsYXRlRGlyKSkge1xuICAgICAgICAgICAgZnMucmVtb3ZlU3luYyh0ZW1wbGF0ZURpcik7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGZzLmV4aXN0c1N5bmMoZG9jdW1lbnRhdGlvbkRpcikpIHtcbiAgICAgICAgICAgIGZzLnJlbW92ZVN5bmMoZG9jdW1lbnRhdGlvbkRpcik7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBDb3B5IG9yaWdpbmFsIHRlbXBsYXRlcyB0byBzZXNzaW9uIGRpcmVjdG9yeVxuICAgICAgICBmcy5jb3B5U3luYyh0aGlzLm9yaWdpbmFsVGVtcGxhdGVzUGF0aCwgdGVtcGxhdGVEaXIpO1xuICAgICAgICBmcy5lbnN1cmVEaXJTeW5jKGRvY3VtZW50YXRpb25EaXIpO1xuXG4gICAgICAgIGNvbnN0IHNlc3Npb246IFBsYXlncm91bmRTZXNzaW9uID0ge1xuICAgICAgICAgICAgaWQ6IHNlc3Npb25JZCxcbiAgICAgICAgICAgIHRlbXBsYXRlRGlyLFxuICAgICAgICAgICAgZG9jdW1lbnRhdGlvbkRpcixcbiAgICAgICAgICAgIGxhc3RBY3Rpdml0eTogRGF0ZS5ub3coKSxcbiAgICAgICAgICAgIGNvbmZpZzoge1xuICAgICAgICAgICAgICAgIGhpZGVHZW5lcmF0b3I6IGZhbHNlLFxuICAgICAgICAgICAgICAgIGRpc2FibGVTb3VyY2VDb2RlOiBmYWxzZSxcbiAgICAgICAgICAgICAgICBkaXNhYmxlR3JhcGg6IGZhbHNlLFxuICAgICAgICAgICAgICAgIGRpc2FibGVDb3ZlcmFnZTogZmFsc2UsXG4gICAgICAgICAgICAgICAgZGlzYWJsZVByaXZhdGU6IGZhbHNlLFxuICAgICAgICAgICAgICAgIGRpc2FibGVQcm90ZWN0ZWQ6IGZhbHNlLFxuICAgICAgICAgICAgICAgIGRpc2FibGVJbnRlcm5hbDogZmFsc2VcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcblxuICAgICAgICB0aGlzLnNlc3Npb25zLnNldChzZXNzaW9uSWQsIHNlc3Npb24pO1xuICAgICAgICB0aGlzLmlwVG9TZXNzaW9uSWQuc2V0KGlwLCBzZXNzaW9uSWQpO1xuICAgICAgICBsb2dnZXIuaW5mbyhg8J+GlSBDcmVhdGVkIG5ldyBzZXNzaW9uIGZvciBJUCAke2lwfTogJHtzZXNzaW9uSWR9YCk7XG5cbiAgICAgICAgLy8gR2VuZXJhdGUgaW5pdGlhbCBkb2N1bWVudGF0aW9uIChza2lwIGluIHRlc3QgbW9kZSB0byBhdm9pZCB0ZW1wbGF0ZSBpc3N1ZXMpXG4gICAgICAgIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Rlc3QnKSB7XG4gICAgICAgICAgICB0aGlzLmdlbmVyYXRlRG9jdW1lbnRhdGlvbihzZXNzaW9uSWQpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHNlc3Npb247XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBjcmVhdGVOZXdTZXNzaW9uKGlwOiBzdHJpbmcpOiBQbGF5Z3JvdW5kU2Vzc2lvbiB7XG4gICAgICAgIC8vIEdlbmVyYXRlIGEgdW5pcXVlIHNlc3Npb24gSUQgKG5vdCBiYXNlZCBvbiBJUClcbiAgICAgICAgY29uc3Qgc2Vzc2lvbklkID0gY3J5cHRvLnJhbmRvbUJ5dGVzKDE2KS50b1N0cmluZygnaGV4Jyk7XG4gICAgICAgIGNvbnN0IHRlbXBsYXRlRGlyID0gcGF0aC5qb2luKG9zLnRtcGRpcigpLCBgaGJzLXRlbXBsYXRlcy1jb3B5LSR7c2Vzc2lvbklkfWApO1xuICAgICAgICBjb25zdCBkb2N1bWVudGF0aW9uRGlyID0gcGF0aC5qb2luKG9zLnRtcGRpcigpLCBgZ2VuZXJhdGVkLWRvY3VtZW50YXRpb24tJHtzZXNzaW9uSWR9YCk7XG5cbiAgICAgICAgLy8gQ2xlYW4gdXAgYW55IGV4aXN0aW5nIGRpcmVjdG9yaWVzIGZyb20gcHJldmlvdXMgc2Vzc2lvbnNcbiAgICAgICAgaWYgKGZzLmV4aXN0c1N5bmModGVtcGxhdGVEaXIpKSB7XG4gICAgICAgICAgICBmcy5yZW1vdmVTeW5jKHRlbXBsYXRlRGlyKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoZnMuZXhpc3RzU3luYyhkb2N1bWVudGF0aW9uRGlyKSkge1xuICAgICAgICAgICAgZnMucmVtb3ZlU3luYyhkb2N1bWVudGF0aW9uRGlyKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIENvcHkgb3JpZ2luYWwgdGVtcGxhdGVzIHRvIHNlc3Npb24gZGlyZWN0b3J5XG4gICAgICAgIGZzLmNvcHlTeW5jKHRoaXMub3JpZ2luYWxUZW1wbGF0ZXNQYXRoLCB0ZW1wbGF0ZURpcik7XG4gICAgICAgIGZzLmVuc3VyZURpclN5bmMoZG9jdW1lbnRhdGlvbkRpcik7XG5cbiAgICAgICAgY29uc3Qgc2Vzc2lvbjogUGxheWdyb3VuZFNlc3Npb24gPSB7XG4gICAgICAgICAgICBpZDogc2Vzc2lvbklkLFxuICAgICAgICAgICAgdGVtcGxhdGVEaXIsXG4gICAgICAgICAgICBkb2N1bWVudGF0aW9uRGlyLFxuICAgICAgICAgICAgbGFzdEFjdGl2aXR5OiBEYXRlLm5vdygpLFxuICAgICAgICAgICAgY29uZmlnOiB7XG4gICAgICAgICAgICAgICAgaGlkZUdlbmVyYXRvcjogZmFsc2UsXG4gICAgICAgICAgICAgICAgZGlzYWJsZVNvdXJjZUNvZGU6IGZhbHNlLFxuICAgICAgICAgICAgICAgIGRpc2FibGVHcmFwaDogZmFsc2UsXG4gICAgICAgICAgICAgICAgZGlzYWJsZUNvdmVyYWdlOiBmYWxzZSxcbiAgICAgICAgICAgICAgICBkaXNhYmxlUHJpdmF0ZTogZmFsc2UsXG4gICAgICAgICAgICAgICAgZGlzYWJsZVByb3RlY3RlZDogZmFsc2UsXG4gICAgICAgICAgICAgICAgZGlzYWJsZUludGVybmFsOiBmYWxzZSxcbiAgICAgICAgICAgICAgICBkaXNhYmxlRmlsZVBhdGg6IGZhbHNlLFxuICAgICAgICAgICAgICAgIGRpc2FibGVPdmVydmlldzogZmFsc2VcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcblxuICAgICAgICB0aGlzLnNlc3Npb25zLnNldChzZXNzaW9uSWQsIHNlc3Npb24pO1xuICAgICAgICAvLyBEb24ndCB1cGRhdGUgaXBUb1Nlc3Npb25JZCBtYXBwaW5nIGZvciBuZXcgc2Vzc2lvbnMgdG8gYWxsb3cgbXVsdGlwbGUgc2Vzc2lvbnMgcGVyIElQXG4gICAgICAgIGxvZ2dlci5pbmZvKGDwn4aVIENyZWF0ZWQgbmV3IHNlc3Npb24gZm9yIElQICR7aXB9OiAke3Nlc3Npb25JZH1gKTtcblxuICAgICAgICAvLyBHZW5lcmF0ZSBpbml0aWFsIGRvY3VtZW50YXRpb24gKHNraXAgaW4gdGVzdCBtb2RlIHRvIGF2b2lkIHRlbXBsYXRlIGlzc3VlcylcbiAgICAgICAgaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAndGVzdCcpIHtcbiAgICAgICAgICAgIHRoaXMuZ2VuZXJhdGVEb2N1bWVudGF0aW9uKHNlc3Npb25JZCk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gc2Vzc2lvbjtcbiAgICB9XG5cbiAgICBwcml2YXRlIHVwZGF0ZVNlc3Npb25BY3Rpdml0eShzZXNzaW9uSWQ6IHN0cmluZyk6IHZvaWQge1xuICAgICAgICBjb25zdCBzZXNzaW9uID0gdGhpcy5zZXNzaW9ucy5nZXQoc2Vzc2lvbklkKTtcbiAgICAgICAgaWYgKHNlc3Npb24pIHtcbiAgICAgICAgICAgIHNlc3Npb24ubGFzdEFjdGl2aXR5ID0gRGF0ZS5ub3coKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgZ2VuZXJhdGVEb2N1bWVudGF0aW9uKHNlc3Npb25JZDogc3RyaW5nLCBkZWJvdW5jZTogYm9vbGVhbiA9IGZhbHNlKTogdm9pZCB7XG4gICAgICAgIGlmIChkZWJvdW5jZSkge1xuICAgICAgICAgICAgLy8gQ2xlYXIgZXhpc3RpbmcgdGltZXJcbiAgICAgICAgICAgIGNvbnN0IGV4aXN0aW5nVGltZXIgPSB0aGlzLmRlYm91bmNlVGltZXJzLmdldChzZXNzaW9uSWQpO1xuICAgICAgICAgICAgaWYgKGV4aXN0aW5nVGltZXIpIHtcbiAgICAgICAgICAgICAgICBjbGVhclRpbWVvdXQoZXhpc3RpbmdUaW1lcik7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIFNldCBuZXcgdGltZXIgZm9yIDMwMG1zXG4gICAgICAgICAgICBjb25zdCB0aW1lciA9IHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMucnVuQ29tcG9Eb2NGb3JTZXNzaW9uKHNlc3Npb25JZCk7XG4gICAgICAgICAgICAgICAgdGhpcy5kZWJvdW5jZVRpbWVycy5kZWxldGUoc2Vzc2lvbklkKTtcbiAgICAgICAgICAgIH0sIDMwMCk7XG5cbiAgICAgICAgICAgIHRoaXMuZGVib3VuY2VUaW1lcnMuc2V0KHNlc3Npb25JZCwgdGltZXIpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gR2VuZXJhdGUgaW1tZWRpYXRlbHlcbiAgICAgICAgICAgIHRoaXMucnVuQ29tcG9Eb2NGb3JTZXNzaW9uKHNlc3Npb25JZCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIGFzeW5jIHJ1bkNvbXBvRG9jRm9yU2Vzc2lvbihzZXNzaW9uSWQ6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICBjb25zdCBzZXNzaW9uID0gdGhpcy5zZXNzaW9ucy5nZXQoc2Vzc2lvbklkKTtcbiAgICAgICAgaWYgKCFzZXNzaW9uKSB7XG4gICAgICAgICAgICBsb2dnZXIuZXJyb3IoYFNlc3Npb24gJHtzZXNzaW9uSWR9IG5vdCBmb3VuZGApO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGxvZ2dlci5pbmZvKGDwn5qAIEdlbmVyYXRpbmcgZG9jdW1lbnRhdGlvbiBmb3Igc2Vzc2lvbiAke3Nlc3Npb25JZH1gKTtcblxuICAgICAgICAgICAgLy8gQnVpbGQgQ29tcG9Eb2MgQ0xJIGNvbW1hbmQgdXNpbmcgYWJzb2x1dGUgcGF0aHMgZm9yIHRlbXAgZGlyZWN0b3JpZXNcbiAgICAgICAgICAgIC8vIFVzZSB0aGUgY29uZmlndXJlZCBmYWtlIHByb2plY3QgcGF0aCB3aXRoIHRzY29uZmlnLmpzb25cbiAgICAgICAgICAgIGNvbnN0IGZha2VQcm9qZWN0VHNDb25maWdQYXRoID0gcGF0aC5qb2luKHRoaXMuZmFrZVByb2plY3RQYXRoLCAndHNjb25maWcuanNvbicpO1xuXG4gICAgICAgICAgICAvLyBVc2UgYWJzb2x1dGUgcGF0aCB0byB0aGUgQ0xJIHNjcmlwdFxuICAgICAgICAgICAgY29uc3QgY2xpUGF0aCA9IHBhdGgucmVzb2x2ZShwcm9jZXNzLmN3ZCgpLCAnYmluJywgJ2luZGV4LWNsaS5qcycpO1xuICAgICAgICAgICAgXG4gICAgICAgICAgICAvLyBJbiB0ZXN0IG1vZGUsIGNoZWNrIGlmIENMSSBleGlzdHMgYmVmb3JlIHByb2NlZWRpbmdcbiAgICAgICAgICAgIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViA9PT0gJ3Rlc3QnICYmICFmcy5leGlzdHNTeW5jKGNsaVBhdGgpKSB7XG4gICAgICAgICAgICAgICAgbG9nZ2VyLndhcm4oYENMSSBub3QgZm91bmQgaW4gdGVzdCBlbnZpcm9ubWVudDogJHtjbGlQYXRofS4gU2tpcHBpbmcgZG9jdW1lbnRhdGlvbiBnZW5lcmF0aW9uLmApO1xuICAgICAgICAgICAgICAgIHNlc3Npb24uZG9jdW1lbnRhdGlvbkdlbmVyYXRlZCA9IHRydWU7IC8vIE1hcmsgYXMgZ2VuZXJhdGVkIHRvIGF2b2lkIHJldHJpZXNcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBcbiAgICAgICAgICAgIGNvbnN0IGNtZCA9IFtcbiAgICAgICAgICAgICAgICBgbm9kZSBcIiR7Y2xpUGF0aH1cImAsXG4gICAgICAgICAgICAgICAgYC1wIFwiJHtmYWtlUHJvamVjdFRzQ29uZmlnUGF0aH1cImAsXG4gICAgICAgICAgICAgICAgYC1kIFwiJHtzZXNzaW9uLmRvY3VtZW50YXRpb25EaXJ9XCJgLFxuICAgICAgICAgICAgICAgIGAtLXRlbXBsYXRlcyBcIiR7c2Vzc2lvbi50ZW1wbGF0ZURpcn1cImBcbiAgICAgICAgICAgIF07XG5cbiAgICAgICAgICAgIC8vIER5bmFtaWNhbGx5IGFkZCBhbGwgY29uZmlnIG9wdGlvbnMgYXMgQ0xJIGZsYWdzXG4gICAgICAgICAgICBjb25zdCBjb25maWcgPSBzZXNzaW9uLmNvbmZpZyB8fCB7fTtcbiAgICAgICAgICAgIGNvbnN0IGJvb2xlYW5GbGFncyA9IFtcbiAgICAgICAgICAgICAgICAnaGlkZUdlbmVyYXRvcicsICdkaXNhYmxlU291cmNlQ29kZScsICdkaXNhYmxlR3JhcGgnLCAnZGlzYWJsZUNvdmVyYWdlJywgJ2Rpc2FibGVQcml2YXRlJywgJ2Rpc2FibGVQcm90ZWN0ZWQnLCAnZGlzYWJsZUludGVybmFsJyxcbiAgICAgICAgICAgICAgICAnZGlzYWJsZUxpZmVDeWNsZUhvb2tzJywgJ2Rpc2FibGVDb25zdHJ1Y3RvcnMnLCAnZGlzYWJsZVJvdXRlc0dyYXBoJywgJ2Rpc2FibGVTZWFyY2gnLCAnZGlzYWJsZURlcGVuZGVuY2llcycsICdkaXNhYmxlUHJvcGVydGllcycsXG4gICAgICAgICAgICAgICAgJ2Rpc2FibGVEb21UcmVlJywgJ2Rpc2FibGVUZW1wbGF0ZVRhYicsICdkaXNhYmxlU3R5bGVUYWInLCAnZGlzYWJsZU1haW5HcmFwaCcsICdkaXNhYmxlRmlsZVBhdGgnLCAnZGlzYWJsZU92ZXJ2aWV3JywgJ2hpZGVEYXJrTW9kZVRvZ2dsZScsICdtaW5pbWFsJywgJ3NlcnZlJywgJ29wZW4nLCAnd2F0Y2gnLCAnc2lsZW50JyxcbiAgICAgICAgICAgICAgICAnY292ZXJhZ2VUZXN0JywgJ2NvdmVyYWdlVGVzdFRocmVzaG9sZEZhaWwnLCAnY292ZXJhZ2VUZXN0U2hvd09ubHlGYWlsZWQnXG4gICAgICAgICAgICBdO1xuICAgICAgICAgICAgY29uc3QgdmFsdWVGbGFncyA9IFtcbiAgICAgICAgICAgICAgICAndGhlbWUnLCAnbGFuZ3VhZ2UnLCAnYmFzZScsICdjdXN0b21GYXZpY29uJywgJ2N1c3RvbUxvZ28nLCAnYXNzZXRzRm9sZGVyJywgJ2V4dFRoZW1lJywgJ2luY2x1ZGVzJywgJ2luY2x1ZGVzTmFtZScsICdvdXRwdXQnLCAncG9ydCcsICdob3N0bmFtZScsXG4gICAgICAgICAgICAgICAgJ2V4cG9ydEZvcm1hdCcsICdjb3ZlcmFnZVRlc3RUaHJlc2hvbGQnLCAnY292ZXJhZ2VNaW5pbXVtUGVyRmlsZScsICd1bml0VGVzdENvdmVyYWdlJywgJ2dhSUQnLCAnZ2FTaXRlJywgJ21heFNlYXJjaFJlc3VsdHMnLCAndG9nZ2xlTWVudUl0ZW1zJywgJ25hdlRhYkNvbmZpZydcbiAgICAgICAgICAgIF07XG4gICAgICAgICAgICBmb3IgKGNvbnN0IGZsYWcgb2YgYm9vbGVhbkZsYWdzKSB7XG4gICAgICAgICAgICAgICAgaWYgKGNvbmZpZ1tmbGFnXSA9PT0gdHJ1ZSkge1xuICAgICAgICAgICAgICAgICAgICBjbWQucHVzaChgLS0ke2ZsYWd9YCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZm9yIChjb25zdCBmbGFnIG9mIHZhbHVlRmxhZ3MpIHtcbiAgICAgICAgICAgICAgICBpZiAoY29uZmlnW2ZsYWddICE9PSB1bmRlZmluZWQgJiYgY29uZmlnW2ZsYWddICE9PSBcIlwiKSB7XG4gICAgICAgICAgICAgICAgICAgIGxldCB2YWx1ZSA9IGNvbmZpZ1tmbGFnXTtcbiAgICAgICAgICAgICAgICAgICAgLy8gRm9yIGFycmF5cy9vYmplY3RzLCBzdHJpbmdpZnlcbiAgICAgICAgICAgICAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkodmFsdWUpIHx8IHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlID0gSlNPTi5zdHJpbmdpZnkodmFsdWUpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGNtZC5wdXNoKGAtLSR7ZmxhZ30gXFxcIiR7dmFsdWV9XFxcImApO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uc3QgZnVsbENtZCA9IGNtZC5qb2luKCcgJyk7XG4gICAgICAgICAgICBsb2dnZXIuaW5mbyhg8J+agCBFeGVjdXRpbmcgQ29tcG9Eb2MgY29tbWFuZDogJHtmdWxsQ21kfWApO1xuXG4gICAgICAgICAgICAvLyBMb2cgdGhlIGNvbW1hbmQgdG8gYSBmaWxlIGZvciBkZWJ1Z2dpbmdcbiAgICAgICAgICAgIHJlcXVpcmUoJ2ZzJykuYXBwZW5kRmlsZVN5bmMoJ3NlcnZlci1jb21tYW5kcy5sb2cnLCBgJHtuZXcgRGF0ZSgpLnRvSVNPU3RyaW5nKCl9IC0gJHtmdWxsQ21kfVxcbmApO1xuXG4gICAgICAgICAgICAvLyBFeGVjdXRlIHdpdGggcHJvcGVyIGVycm9yIGhhbmRsaW5nIChpbmhlcml0IHN0ZGlvIHRvIHNlZSBlcnJvcnMpXG4gICAgICAgICAgICBleGVjU3luYyhmdWxsQ21kLCB7XG4gICAgICAgICAgICAgICAgY3dkOiBwcm9jZXNzLmN3ZCgpLFxuICAgICAgICAgICAgICAgIHN0ZGlvOiAnaW5oZXJpdCcgLy8gU2hvdyBvdXRwdXQvZXJyb3JzIGluc3RlYWQgb2YgaGlkaW5nIHRoZW1cbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICB0aGlzLnVwZGF0ZVNlc3Npb25BY3Rpdml0eShzZXNzaW9uSWQpO1xuICAgICAgICAgICAgbG9nZ2VyLmluZm8oYOKchSBEb2N1bWVudGF0aW9uIGdlbmVyYXRlZCBzdWNjZXNzZnVsbHkgZm9yIHNlc3Npb24gJHtzZXNzaW9uSWR9YCk7XG5cbiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgIGxvZ2dlci5lcnJvcihg4p2MIEVycm9yIGdlbmVyYXRpbmcgZG9jdW1lbnRhdGlvbiBmb3Igc2Vzc2lvbiAke3Nlc3Npb25JZH06YCwgZXJyb3IpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBzdGFydFNlc3Npb25DbGVhbnVwKCk6IHZvaWQge1xuICAgICAgICAvLyBDbGVhbiB1cCBzZXNzaW9ucyBvbGRlciB0aGFuIDEgaG91ciBldmVyeSAxMCBtaW51dGVzXG4gICAgICAgIHRoaXMuY2xlYW51cEludGVydmFsID0gc2V0SW50ZXJ2YWwoKCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgY3V0b2ZmVGltZSA9IERhdGUubm93KCkgLSAoNjAgKiA2MCAqIDEwMDApOyAvLyAxIGhvdXIgYWdvXG5cbiAgICAgICAgICAgIGZvciAoY29uc3QgW3Nlc3Npb25JZCwgc2Vzc2lvbl0gb2YgdGhpcy5zZXNzaW9ucy5lbnRyaWVzKCkpIHtcbiAgICAgICAgICAgICAgICBpZiAoc2Vzc2lvbi5sYXN0QWN0aXZpdHkgPCBjdXRvZmZUaW1lKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY2xlYW51cFNlc3Npb24oc2Vzc2lvbklkKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sIDEwICogNjAgKiAxMDAwKTsgLy8gRXZlcnkgMTAgbWludXRlc1xuICAgIH1cblxuICAgIHByaXZhdGUgY2xlYW51cFNlc3Npb24oc2Vzc2lvbklkOiBzdHJpbmcpOiB2b2lkIHtcbiAgICAgICAgY29uc3Qgc2Vzc2lvbiA9IHRoaXMuc2Vzc2lvbnMuZ2V0KHNlc3Npb25JZCk7XG4gICAgICAgIGlmIChzZXNzaW9uKSB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIC8vIFJlbW92ZSBkaXJlY3Rvcmllc1xuICAgICAgICAgICAgICAgIGlmIChmcy5leGlzdHNTeW5jKHNlc3Npb24udGVtcGxhdGVEaXIpKSB7XG4gICAgICAgICAgICAgICAgICAgIGZzLnJlbW92ZVN5bmMoc2Vzc2lvbi50ZW1wbGF0ZURpcik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChmcy5leGlzdHNTeW5jKHNlc3Npb24uZG9jdW1lbnRhdGlvbkRpcikpIHtcbiAgICAgICAgICAgICAgICAgICAgZnMucmVtb3ZlU3luYyhzZXNzaW9uLmRvY3VtZW50YXRpb25EaXIpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIC8vIENsZWFyIHRpbWVyIGlmIGV4aXN0c1xuICAgICAgICAgICAgICAgIGNvbnN0IHRpbWVyID0gdGhpcy5kZWJvdW5jZVRpbWVycy5nZXQoc2Vzc2lvbklkKTtcbiAgICAgICAgICAgICAgICBpZiAodGltZXIpIHtcbiAgICAgICAgICAgICAgICAgICAgY2xlYXJUaW1lb3V0KHRpbWVyKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5kZWJvdW5jZVRpbWVycy5kZWxldGUoc2Vzc2lvbklkKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAvLyBSZW1vdmUgSVAgbWFwcGluZ1xuICAgICAgICAgICAgICAgIGZvciAoY29uc3QgW2lwLCBpZF0gb2YgdGhpcy5pcFRvU2Vzc2lvbklkLmVudHJpZXMoKSkge1xuICAgICAgICAgICAgICAgICAgICBpZiAoaWQgPT09IHNlc3Npb25JZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5pcFRvU2Vzc2lvbklkLmRlbGV0ZShpcCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHRoaXMuc2Vzc2lvbnMuZGVsZXRlKHNlc3Npb25JZCk7XG4gICAgICAgICAgICAgICAgbG9nZ2VyLmluZm8oYPCfp7kgQ2xlYW5lZCB1cCBzZXNzaW9uOiAke3Nlc3Npb25JZH1gKTtcbiAgICAgICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgbG9nZ2VyLmVycm9yKGBFcnJvciBjbGVhbmluZyB1cCBzZXNzaW9uICR7c2Vzc2lvbklkfTpgLCBlcnJvcik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIGluaXRpYWxpemVIYW5kbGViYXJzKCk6IHZvaWQge1xuICAgICAgICB0aGlzLmhhbmRsZWJhcnMgPSByZXF1aXJlKCdoYW5kbGViYXJzJyk7XG4gICAgICAgIHRoaXMucmVnaXN0ZXJIYW5kbGViYXJzSGVscGVycyh0aGlzLmhhbmRsZWJhcnMsIHt9KTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGFzeW5jIHJlZ2lzdGVyQXZhaWxhYmxlUGFydGlhbHMoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjb25zdCBwYXJ0aWFsc0RpciA9IHBhdGguam9pbihwcm9jZXNzLmN3ZCgpLCAnZGlzdC90ZW1wbGF0ZXMvcGFydGlhbHMnKTtcbiAgICAgICAgICAgIGxvZ2dlci5pbmZvKGDwn5SNIExvb2tpbmcgZm9yIHBhcnRpYWxzIGluOiAke3BhcnRpYWxzRGlyfWApO1xuICAgICAgICAgICAgbG9nZ2VyLmluZm8oYPCflI0gUGFydGlhbHMgZGlyZWN0b3J5IGV4aXN0czogJHtmcy5leGlzdHNTeW5jKHBhcnRpYWxzRGlyKX1gKTtcblxuICAgICAgICAgICAgaWYgKGZzLmV4aXN0c1N5bmMocGFydGlhbHNEaXIpKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgcGFydGlhbEZpbGVzID0gZnMucmVhZGRpclN5bmMocGFydGlhbHNEaXIpLmZpbHRlcihmaWxlID0+IGZpbGUuZW5kc1dpdGgoJy5oYnMnKSk7XG4gICAgICAgICAgICAgICAgbG9nZ2VyLmluZm8oYPCfk4EgRm91bmQgJHtwYXJ0aWFsRmlsZXMubGVuZ3RofSBwYXJ0aWFsIGZpbGVzOiAke0pTT04uc3RyaW5naWZ5KHBhcnRpYWxGaWxlcyl9YCk7XG5cbiAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IGZpbGUgb2YgcGFydGlhbEZpbGVzKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHBhcnRpYWxOYW1lID0gZmlsZS5yZXBsYWNlKCcuaGJzJywgJycpO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBwYXJ0aWFsUGF0aCA9IHBhdGguam9pbihwYXJ0aWFsc0RpciwgZmlsZSk7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHBhcnRpYWxDb250ZW50ID0gZnMucmVhZEZpbGVTeW5jKHBhcnRpYWxQYXRoLCAndXRmOCcpO1xuXG4gICAgICAgICAgICAgICAgICAgIC8vIFJlZ2lzdGVyIHRoZSBwYXJ0aWFsXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuaGFuZGxlYmFycy5yZWdpc3RlclBhcnRpYWwocGFydGlhbE5hbWUsIHBhcnRpYWxDb250ZW50KTtcbiAgICAgICAgICAgICAgICAgICAgbG9nZ2VyLmluZm8oYOKchSBSZWdpc3RlcmVkIHBhcnRpYWw6ICR7cGFydGlhbE5hbWV9YCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBsb2dnZXIud2Fybihg4pqg77iPIFBhcnRpYWxzIGRpcmVjdG9yeSBub3QgZm91bmQgYXQ6ICR7cGFydGlhbHNEaXJ9YCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICBsb2dnZXIuZXJyb3IoYOKdjCBFcnJvciByZWdpc3RlcmluZyBwYXJ0aWFsczpgLCBlcnJvcik7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIHNldHVwTWlkZGxld2FyZSgpOiB2b2lkIHtcbiAgICAgICAgLy8gQWRkIHJlcXVlc3QgbG9nZ2luZyBmb3IgZGVidWdnaW5nXG4gICAgICAgIHRoaXMuYXBwLnVzZSgocmVxOiBJbmNvbWluZ01lc3NhZ2UsIHJlczogU2VydmVyUmVzcG9uc2UsIG5leHQ6ICgpID0+IHZvaWQpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGhlYWRlcnMgPSByZXEuaGVhZGVycztcbiAgICAgICAgICAgIGxvZ2dlci5pbmZvKGDwn5SNIFJFUVVFU1Q6ICR7cmVxLm1ldGhvZH0gJHtyZXEudXJsfSAtIFVzZXItQWdlbnQ6ICR7aGVhZGVyc1sndXNlci1hZ2VudCddIHx8ICd1bmtub3duJ31gKTtcbiAgICAgICAgICAgIG5leHQoKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gRW5hYmxlIENPUlMgZm9yIGRldmVsb3BtZW50XG4gICAgICAgIHRoaXMuYXBwLnVzZSgocmVxOiBJbmNvbWluZ01lc3NhZ2UsIHJlczogU2VydmVyUmVzcG9uc2UsIG5leHQ6ICgpID0+IHZvaWQpID0+IHtcbiAgICAgICAgICAgIHJlcy5zZXRIZWFkZXIoJ0FjY2Vzcy1Db250cm9sLUFsbG93LU9yaWdpbicsICcqJyk7XG4gICAgICAgICAgICByZXMuc2V0SGVhZGVyKCdBY2Nlc3MtQ29udHJvbC1BbGxvdy1NZXRob2RzJywgJ0dFVCwgUE9TVCwgUFVULCBERUxFVEUsIE9QVElPTlMnKTtcbiAgICAgICAgICAgIHJlcy5zZXRIZWFkZXIoJ0FjY2Vzcy1Db250cm9sLUFsbG93LUhlYWRlcnMnLCAnT3JpZ2luLCBYLVJlcXVlc3RlZC1XaXRoLCBDb250ZW50LVR5cGUsIEFjY2VwdCwgQXV0aG9yaXphdGlvbicpO1xuICAgICAgICAgICAgaWYgKHJlcS5tZXRob2QgPT09ICdPUFRJT05TJykge1xuICAgICAgICAgICAgICAgIHJlcy5zdGF0dXNDb2RlID0gMjAwO1xuICAgICAgICAgICAgICAgIHJlcy5lbmQoKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgbmV4dCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgICAgICAvLyBTZXJ2ZSBDb21wb2RvYyByZXNvdXJjZXMgYXQgcm9vdCBsZXZlbCBmb3IgcmVsYXRpdmUgcGF0aCBjb21wYXRpYmlsaXR5XG4gICAgICAgIC8vIFRyeSBkaXN0L3Jlc291cmNlcyBmaXJzdCAocHJvZHVjdGlvbiksIHRoZW4gc3JjL3Jlc291cmNlcyAoZGV2ZWxvcG1lbnQvdGVzdGluZylcbiAgICAgICAgY29uc3QgY29tcG9kb2NSZXNvdXJjZXNQYXRoRGlzdCA9IHBhdGguam9pbihwcm9jZXNzLmN3ZCgpLCAnZGlzdC9yZXNvdXJjZXMnKTtcbiAgICAgICAgY29uc3QgY29tcG9kb2NSZXNvdXJjZXNQYXRoU3JjID0gcGF0aC5qb2luKHByb2Nlc3MuY3dkKCksICdzcmMvcmVzb3VyY2VzJyk7XG4gICAgICAgIFxuICAgICAgICBjb25zdCBjb21wb2RvY1Jlc291cmNlc1BhdGggPSBmcy5leGlzdHNTeW5jKGNvbXBvZG9jUmVzb3VyY2VzUGF0aERpc3QpID8gY29tcG9kb2NSZXNvdXJjZXNQYXRoRGlzdCA6IGNvbXBvZG9jUmVzb3VyY2VzUGF0aFNyYztcbiAgICAgICAgbG9nZ2VyLmluZm8oYPCfk4EgU2V0dGluZyB1cCByb290LWxldmVsIHN0YXRpYyBmaWxlcyBmcm9tOiAke2NvbXBvZG9jUmVzb3VyY2VzUGF0aH1gKTtcbiAgICAgICAgbG9nZ2VyLmluZm8oYPCfk4EgQ29tcG9kb2MgcmVzb3VyY2VzIHBhdGggZXhpc3RzOiAke2ZzLmV4aXN0c1N5bmMoY29tcG9kb2NSZXNvdXJjZXNQYXRoKX1gKTtcblxuICAgICAgICAvLyBTZXJ2ZSBzdHlsZXMsIGpzLCBpbWFnZXMsIGFuZCBvdGhlciByZXNvdXJjZXMgYXQgcm9vdCBsZXZlbCB1c2luZyBzaXJ2XG4gICAgICAgIHRoaXMuYXBwLnVzZSgnL3N0eWxlcycsIHNpcnYocGF0aC5qb2luKGNvbXBvZG9jUmVzb3VyY2VzUGF0aCwgJ3N0eWxlcycpLCB7IGRldjogdHJ1ZSB9KSk7XG4gICAgICAgIHRoaXMuYXBwLnVzZSgnL2pzJywgc2lydihwYXRoLmpvaW4oY29tcG9kb2NSZXNvdXJjZXNQYXRoLCAnanMnKSwgeyBkZXY6IHRydWUgfSkpO1xuICAgICAgICB0aGlzLmFwcC51c2UoJy9pbWFnZXMnLCBzaXJ2KHBhdGguam9pbihjb21wb2RvY1Jlc291cmNlc1BhdGgsICdpbWFnZXMnKSwgeyBkZXY6IHRydWUgfSkpO1xuICAgICAgICB0aGlzLmFwcC51c2UoJy9mb250cycsIHNpcnYocGF0aC5qb2luKGNvbXBvZG9jUmVzb3VyY2VzUGF0aCwgJ2ZvbnRzJyksIHsgZGV2OiB0cnVlIH0pKTtcblxuICAgICAgICAvLyBTZXJ2ZSBDb21wb2RvYyByZXNvdXJjZXMgdW5kZXIgL3Jlc291cmNlcyBwYXRoIGFzIHdlbGwgKGZvciBiYWNrd2FyZCBjb21wYXRpYmlsaXR5KVxuICAgICAgICB0aGlzLmFwcC51c2UoJy9yZXNvdXJjZXMnLCBzaXJ2KGNvbXBvZG9jUmVzb3VyY2VzUGF0aCwgeyBkZXY6IHRydWUgfSkpO1xuXG4gICAgICAgIC8vIFNlcnZlIHN0YXRpYyBmaWxlcyBmcm9tIHRlbXBsYXRlIHBsYXlncm91bmQgZGlyZWN0b3J5IChpbmRleC5odG1sLCBhcHAuanMpXG4gICAgICAgIC8vIFRyeSBkaXN0L3Jlc291cmNlcyBmaXJzdCAocHJvZHVjdGlvbiksIHRoZW4gc3JjL3Jlc291cmNlcyAoZGV2ZWxvcG1lbnQvdGVzdGluZylcbiAgICAgICAgY29uc3QgcGxheWdyb3VuZFN0YXRpY1BhdGhEaXN0ID0gcGF0aC5qb2luKHByb2Nlc3MuY3dkKCksICdkaXN0L3Jlc291cmNlcy90ZW1wbGF0ZS1wbGF5Z3JvdW5kLWFwcCcpO1xuICAgICAgICBjb25zdCBwbGF5Z3JvdW5kU3RhdGljUGF0aFNyYyA9IHBhdGguam9pbihwcm9jZXNzLmN3ZCgpLCAnc3JjL3Jlc291cmNlcy90ZW1wbGF0ZS1wbGF5Z3JvdW5kLWFwcCcpO1xuICAgICAgICBcbiAgICAgICAgY29uc3QgcGxheWdyb3VuZFN0YXRpY1BhdGggPSBmcy5leGlzdHNTeW5jKHBsYXlncm91bmRTdGF0aWNQYXRoRGlzdCkgPyBwbGF5Z3JvdW5kU3RhdGljUGF0aERpc3QgOiBwbGF5Z3JvdW5kU3RhdGljUGF0aFNyYztcbiAgICAgICAgbG9nZ2VyLmluZm8oYPCfk4EgU2V0dGluZyB1cCBwbGF5Z3JvdW5kIHN0YXRpYyBmaWxlcyBmcm9tOiAke3BsYXlncm91bmRTdGF0aWNQYXRofWApO1xuICAgICAgICBsb2dnZXIuaW5mbyhg8J+TgSBQbGF5Z3JvdW5kIHN0YXRpYyBwYXRoIGV4aXN0czogJHtmcy5leGlzdHNTeW5jKHBsYXlncm91bmRTdGF0aWNQYXRoKX1gKTtcbiAgICAgICAgdGhpcy5hcHAudXNlKHNpcnYocGxheWdyb3VuZFN0YXRpY1BhdGgsIHsgZGV2OiB0cnVlIH0pKTtcblxuICAgICAgICAvLyBQYXJzZSBKU09OIGJvZGllcyBhbmQgZm9ybSBkYXRhIHVzaW5nIGJvZHktcGFyc2VyXG4gICAgICAgIHRoaXMuYXBwLnVzZShqc29uKHsgbGltaXQ6ICcxMG1iJyB9KSk7XG4gICAgICAgIHRoaXMuYXBwLnVzZSh1cmxlbmNvZGVkKHsgZXh0ZW5kZWQ6IHRydWUsIGxpbWl0OiAnMTBtYicgfSkpO1xuICAgIH1cblxuICAgIHByaXZhdGUgc2V0dXBSb3V0ZXMoKTogdm9pZCB7XG4gICAgICAgIC8vIEFQSSByb3V0ZSB0byBnZXQgYXZhaWxhYmxlIHRlbXBsYXRlc1xuICAgICAgICB0aGlzLmFwcC5nZXQoJy9hcGkvdGVtcGxhdGVzJywgdGhpcy5nZXRUZW1wbGF0ZXMuYmluZCh0aGlzKSk7XG5cbiAgICAgICAgLy8gQVBJIHJvdXRlIHRvIGdldCB0ZW1wbGF0ZSBjb250ZW50XG4gICAgICAgIHRoaXMuYXBwLmdldCgnL2FwaS90ZW1wbGF0ZXMvOnRlbXBsYXRlTmFtZScsIHRoaXMuZ2V0VGVtcGxhdGUuYmluZCh0aGlzKSk7XG5cbiAgICAgICAgLy8gQVBJIHJvdXRlIHRvIGdldCBleGFtcGxlIGRhdGFcbiAgICAgICAgdGhpcy5hcHAuZ2V0KCcvYXBpL2V4YW1wbGUtZGF0YS86ZGF0YVR5cGUnLCB0aGlzLmdldEV4YW1wbGVEYXRhLmJpbmQodGhpcykpO1xuXG4gICAgICAgIC8vIEFQSSByb3V0ZSB0byByZW5kZXIgdGVtcGxhdGUgd2l0aCBjdXN0b20gZGF0YVxuICAgICAgICB0aGlzLmFwcC5wb3N0KCcvYXBpL3JlbmRlcicsIHRoaXMucmVuZGVyVGVtcGxhdGUuYmluZCh0aGlzKSk7XG5cbiAgICAgICAgLy8gQVBJIHJvdXRlIHRvIHJlbmRlciBjb21wbGV0ZSBwYWdlIHdpdGggdGVtcGxhdGVcbiAgICAgICAgdGhpcy5hcHAucG9zdCgnL2FwaS9yZW5kZXItcGFnZScsIHRoaXMucmVuZGVyQ29tcGxldGVQYWdlLmJpbmQodGhpcykpO1xuXG4gICAgICAgIC8vIEFQSSByb3V0ZSB0byBnZW5lcmF0ZSBkb2N1bWVudGF0aW9uIHdpdGggQ29tcG9Eb2MgQ0xJXG4gICAgICAgIHRoaXMuYXBwLnBvc3QoJy9hcGkvZ2VuZXJhdGUtZG9jcycsIHRoaXMuZ2VuZXJhdGVEb2NzLmJpbmQodGhpcykpO1xuXG4gICAgICAgIC8vIEFQSSByb3V0ZSB0byBkb3dubG9hZCB0ZW1wbGF0ZSBwYWNrYWdlXG4gICAgICAgIHRoaXMuYXBwLnBvc3QoJy9hcGkvZG93bmxvYWQtdGVtcGxhdGUnLCB0aGlzLmRvd25sb2FkVGVtcGxhdGVQYWNrYWdlLmJpbmQodGhpcykpO1xuXG4gICAgICAgIC8vIEFQSSByb3V0ZSB0byBkb3dubG9hZCB0ZW1wbGF0ZSBaSVAgKHNlcnZlci1zaWRlIGNyZWF0aW9uKVxuICAgICAgICB0aGlzLmFwcC5wb3N0KCcvYXBpL3Nlc3Npb24vOnNlc3Npb25JZC9kb3dubG9hZC16aXAnLCB0aGlzLmRvd25sb2FkU2Vzc2lvblRlbXBsYXRlWmlwLmJpbmQodGhpcykpO1xuICAgICAgICB0aGlzLmFwcC5wb3N0KCcvYXBpL3Nlc3Npb24vOnNlc3Npb25JZC9kb3dubG9hZC1hbGwtdGVtcGxhdGVzJywgdGhpcy5kb3dubG9hZEFsbFNlc3Npb25UZW1wbGF0ZXMuYmluZCh0aGlzKSk7XG4gICAgICAgIHRoaXMuYXBwLmdldCgnL2FwaS9zZXNzaW9uLzpzZXNzaW9uSWQvZG93bmxvYWQvYWxsJywgdGhpcy5kb3dubG9hZEFsbFNlc3Npb25UZW1wbGF0ZXMuYmluZCh0aGlzKSk7IC8vIEFsaWFzIGZvciBjb21wYXRpYmlsaXR5XG5cbiAgICAgICAgLy8gU2Vzc2lvbiBtYW5hZ2VtZW50IEFQSSByb3V0ZXNcbiAgICAgICAgdGhpcy5hcHAucG9zdCgnL2FwaS9zZXNzaW9uJywgdGhpcy5jcmVhdGVTZXNzaW9uQVBJLmJpbmQodGhpcykpO1xuICAgICAgICB0aGlzLmFwcC5wb3N0KCcvYXBpL3Nlc3Npb24vY3JlYXRlJywgdGhpcy5jcmVhdGVTZXNzaW9uQVBJLmJpbmQodGhpcykpO1xuICAgICAgICB0aGlzLmFwcC5nZXQoJy9hcGkvc2Vzc2lvbi86c2Vzc2lvbklkL3RlbXBsYXRlcycsIHRoaXMuZ2V0U2Vzc2lvblRlbXBsYXRlcy5iaW5kKHRoaXMpKTtcbiAgICAgICAgdGhpcy5hcHAuZ2V0KCcvYXBpL3Nlc3Npb24vOnNlc3Npb25JZC90ZW1wbGF0ZS8qJywgdGhpcy5nZXRTZXNzaW9uVGVtcGxhdGUuYmluZCh0aGlzKSk7XG4gICAgICAgIHRoaXMuYXBwLnBvc3QoJy9hcGkvc2Vzc2lvbi86c2Vzc2lvbklkL3RlbXBsYXRlLyonLCB0aGlzLnNhdmVTZXNzaW9uVGVtcGxhdGUuYmluZCh0aGlzKSk7XG4gICAgICAgIHRoaXMuYXBwLmdldCgnL2FwaS9zZXNzaW9uLzpzZXNzaW9uSWQvdGVtcGxhdGUtZGF0YS8qJywgdGhpcy5nZXRTZXNzaW9uVGVtcGxhdGVEYXRhLmJpbmQodGhpcykpO1xuICAgICAgICB0aGlzLmFwcC5wb3N0KCcvYXBpL3Nlc3Npb24vOnNlc3Npb25JZC9nZW5lcmF0ZS1kb2NzJywgdGhpcy5nZW5lcmF0ZVNlc3Npb25Eb2NzLmJpbmQodGhpcykpO1xuICAgICAgICB0aGlzLmFwcC5wb3N0KCcvYXBpL3Nlc3Npb24vOnNlc3Npb25JZC9nZW5lcmF0ZScsIHRoaXMuZ2VuZXJhdGVTZXNzaW9uRG9jcy5iaW5kKHRoaXMpKTsgLy8gQWxpYXMgZm9yIGNvbXBhdGliaWxpdHlcbiAgICAgICAgdGhpcy5hcHAuZ2V0KCcvYXBpL3Nlc3Npb24vOnNlc3Npb25JZC9jb25maWcnLCB0aGlzLmdldFNlc3Npb25Db25maWcuYmluZCh0aGlzKSk7XG4gICAgICAgIHRoaXMuYXBwLnBvc3QoJy9hcGkvc2Vzc2lvbi86c2Vzc2lvbklkL2NvbmZpZycsIHRoaXMudXBkYXRlU2Vzc2lvbkNvbmZpZy5iaW5kKHRoaXMpKTtcblxuICAgICAgICAvLyBTZXJ2ZSBzZXNzaW9uLXNwZWNpZmljIGdlbmVyYXRlZCBkb2N1bWVudGF0aW9uXG4gICAgICAgIHRoaXMuYXBwLmdldCgnL2FwaS9zZXNzaW9uLzpzZXNzaW9uSWQvZG9jcy8qJywgdGhpcy5zZXJ2ZVNlc3Npb25Eb2NzLmJpbmQodGhpcykpO1xuXG4gICAgICAgIC8vIFNlcnZlIHNlc3Npb24tc3BlY2lmaWMgZ2VuZXJhdGVkIGRvY3VtZW50YXRpb24gYXQgdGhlIGV4cGVjdGVkIFVSTCBwYXR0ZXJuXG4gICAgICAgIC8vIFRoZXNlIHJvdXRlcyBNVVNUIGNvbWUgYmVmb3JlIHRoZSBjYXRjaC1hbGwgcm91dGVcbiAgICAgICAgdGhpcy5hcHAuZ2V0KCcvZG9jcy86c2Vzc2lvbklkL2luZGV4Lmh0bWwnLCAocmVxOiBhbnksIHJlczogU2VydmVyUmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgIGxvZ2dlci5pbmZvKGDwn5SNIERvY3MgaW5kZXggcm91dGUgaGl0OiAvZG9jcy8ke3JlcS5wYXJhbXMuc2Vzc2lvbklkfS9pbmRleC5odG1sYCk7XG4gICAgICAgICAgICBjb25zdCBzZXNzaW9uSWQgPSByZXEucGFyYW1zLnNlc3Npb25JZDtcbiAgICAgICAgICAgIGNvbnN0IHNlc3Npb24gPSB0aGlzLnNlc3Npb25zLmdldChzZXNzaW9uSWQpO1xuXG4gICAgICAgICAgICBpZiAoIXNlc3Npb24pIHtcbiAgICAgICAgICAgICAgICBsb2dnZXIuZXJyb3IoYOKdjCBTZXNzaW9uIG5vdCBmb3VuZDogJHtzZXNzaW9uSWR9YCk7XG4gICAgICAgICAgICAgICAgc2VuZChyZXMsIDQwNCwgeyBzdWNjZXNzOiBmYWxzZSwgbWVzc2FnZTogJ1Nlc3Npb24gbm90IGZvdW5kJyB9KTtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHRoaXMudXBkYXRlU2Vzc2lvbkFjdGl2aXR5KHNlc3Npb25JZCk7XG5cbiAgICAgICAgICAgIGNvbnN0IGZ1bGxQYXRoID0gcGF0aC5qb2luKHNlc3Npb24uZG9jdW1lbnRhdGlvbkRpciwgJ2luZGV4Lmh0bWwnKTtcbiAgICAgICAgICAgIGxvZ2dlci5pbmZvKGDwn5OCIExvb2tpbmcgZm9yIGZpbGU6ICR7ZnVsbFBhdGh9YCk7XG5cbiAgICAgICAgICAgIGlmIChmcy5leGlzdHNTeW5jKGZ1bGxQYXRoKSkge1xuICAgICAgICAgICAgICAgIGxvZ2dlci5pbmZvKGDinIUgU2VydmluZyBmaWxlOiAke2Z1bGxQYXRofWApO1xuICAgICAgICAgICAgICAgIGNvbnN0IGNvbnRlbnQgPSBmcy5yZWFkRmlsZVN5bmMoZnVsbFBhdGgpO1xuICAgICAgICAgICAgICAgIHJlcy5zZXRIZWFkZXIoJ0NvbnRlbnQtVHlwZScsICd0ZXh0L2h0bWwnKTtcbiAgICAgICAgICAgICAgICByZXMuZW5kKGNvbnRlbnQpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBsb2dnZXIuZXJyb3IoYOKdjCBGaWxlIG5vdCBmb3VuZDogJHtmdWxsUGF0aH1gKTtcbiAgICAgICAgICAgICAgICByZXMuc3RhdHVzQ29kZSA9IDQwNDtcbiAgICAgICAgICAgICAgICByZXMuZW5kKCdEb2N1bWVudGF0aW9uIGZpbGUgbm90IGZvdW5kJyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIFNlcnZlIGFueSBmaWxlIHdpdGhpbiBzZXNzaW9uIGRvY3VtZW50YXRpb24gdXNpbmcgZHluYW1pYyBzaXJ2IG1pZGRsZXdhcmVcbiAgICAgICAgdGhpcy5hcHAuZ2V0KCcvZG9jcy86c2Vzc2lvbklkLyonLCAocmVxOiBhbnksIHJlczogU2VydmVyUmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHNlc3Npb25JZCA9IHJlcS5wYXJhbXMuc2Vzc2lvbklkO1xuICAgICAgICAgICAgY29uc3Qgc2Vzc2lvbiA9IHRoaXMuc2Vzc2lvbnMuZ2V0KHNlc3Npb25JZCk7XG5cbiAgICAgICAgICAgIGlmICghc2Vzc2lvbikge1xuICAgICAgICAgICAgICAgIGxvZ2dlci5lcnJvcihg4p2MIFNlc3Npb24gbm90IGZvdW5kOiAke3Nlc3Npb25JZH1gKTtcbiAgICAgICAgICAgICAgICBzZW5kKHJlcywgNDA0LCB7IHN1Y2Nlc3M6IGZhbHNlLCBtZXNzYWdlOiAnU2Vzc2lvbiBub3QgZm91bmQnIH0pO1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGhpcy51cGRhdGVTZXNzaW9uQWN0aXZpdHkoc2Vzc2lvbklkKTtcblxuICAgICAgICAgICAgLy8gVXNlIHNpcnYgdG8gc2VydmUgZmlsZXMgZnJvbSB0aGUgc2Vzc2lvbiBkb2N1bWVudGF0aW9uIGRpcmVjdG9yeVxuICAgICAgICAgICAgY29uc3Qgc2Vzc2lvblNpcnYgPSBzaXJ2KHNlc3Npb24uZG9jdW1lbnRhdGlvbkRpciwgeyBcbiAgICAgICAgICAgICAgICBkZXY6IHRydWUsXG4gICAgICAgICAgICAgICAgc2luZ2xlOiBmYWxzZSxcbiAgICAgICAgICAgICAgICBzZXRIZWFkZXJzOiAocmVzLCBwYXRobmFtZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBsb2dnZXIuaW5mbyhg4pyFIFNlcnZpbmcgZmlsZSB2aWEgc2lydjogJHtwYXRobmFtZX1gKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgLy8gUmVtb3ZlIHRoZSBzZXNzaW9uIHByZWZpeCBmcm9tIHRoZSBVUkwgZm9yIHNpcnZcbiAgICAgICAgICAgIGNvbnN0IG9yaWdpbmFsVXJsID0gcmVxLnVybDtcbiAgICAgICAgICAgIGNvbnN0IHNlc3Npb25QcmVmaXggPSBgL2RvY3MvJHtzZXNzaW9uSWR9YDtcbiAgICAgICAgICAgIGlmIChvcmlnaW5hbFVybCAmJiBvcmlnaW5hbFVybC5zdGFydHNXaXRoKHNlc3Npb25QcmVmaXgpKSB7XG4gICAgICAgICAgICAgICAgcmVxLnVybCA9IG9yaWdpbmFsVXJsLnN1YnN0cmluZyhzZXNzaW9uUHJlZml4Lmxlbmd0aCkgfHwgJy8nO1xuICAgICAgICAgICAgICAgIGxvZ2dlci5pbmZvKGDwn5SNIFNpcnYgc2VydmluZzogJHtyZXEudXJsfSBmcm9tICR7c2Vzc2lvbi5kb2N1bWVudGF0aW9uRGlyfWApO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBzZXNzaW9uU2lydihyZXEsIHJlcywgKCkgPT4ge1xuICAgICAgICAgICAgICAgIC8vIElmIHNpcnYgZG9lc24ndCBoYW5kbGUgaXQsIHJlc3RvcmUgb3JpZ2luYWwgVVJMIGFuZCByZXR1cm4gNDA0XG4gICAgICAgICAgICAgICAgcmVxLnVybCA9IG9yaWdpbmFsVXJsO1xuICAgICAgICAgICAgICAgIGxvZ2dlci5lcnJvcihg4p2MIEZpbGUgbm90IGZvdW5kIGluIHNlc3Npb24gZG9jczogJHtyZXEudXJsfWApO1xuICAgICAgICAgICAgICAgIHJlcy5zdGF0dXNDb2RlID0gNDA0O1xuICAgICAgICAgICAgICAgIHJlcy5lbmQoJ0RvY3VtZW50YXRpb24gZmlsZSBub3QgZm91bmQnKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcblxuICAgICAgICAvLyBIYW5kbGUgZGlyZWN0IGFjY2VzcyB0byBzZXNzaW9uIGRvY3VtZW50YXRpb24gcm9vdCAoaW5kZXguaHRtbClcbiAgICAgICAgdGhpcy5hcHAuZ2V0KCcvZG9jcy86c2Vzc2lvbklkJywgKHJlcTogYW55LCByZXM6IFNlcnZlclJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICBsb2dnZXIuaW5mbyhg8J+UjSBEb2NzIHJvb3Qgcm91dGUgaGl0OiAvZG9jcy8ke3JlcS5wYXJhbXMuc2Vzc2lvbklkfWApO1xuICAgICAgICAgICAgY29uc3Qgc2Vzc2lvbklkID0gcmVxLnBhcmFtcy5zZXNzaW9uSWQ7XG4gICAgICAgICAgICBjb25zdCBzZXNzaW9uID0gdGhpcy5zZXNzaW9ucy5nZXQoc2Vzc2lvbklkKTtcblxuICAgICAgICAgICAgaWYgKCFzZXNzaW9uKSB7XG4gICAgICAgICAgICAgICAgbG9nZ2VyLmVycm9yKGDinYwgU2Vzc2lvbiBub3QgZm91bmQ6ICR7c2Vzc2lvbklkfWApO1xuICAgICAgICAgICAgICAgIHNlbmQocmVzLCA0MDQsIHsgc3VjY2VzczogZmFsc2UsIG1lc3NhZ2U6ICdTZXNzaW9uIG5vdCBmb3VuZCcgfSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0aGlzLnVwZGF0ZVNlc3Npb25BY3Rpdml0eShzZXNzaW9uSWQpO1xuXG4gICAgICAgICAgICBjb25zdCBmdWxsUGF0aCA9IHBhdGguam9pbihzZXNzaW9uLmRvY3VtZW50YXRpb25EaXIsICdpbmRleC5odG1sJyk7XG4gICAgICAgICAgICBsb2dnZXIuaW5mbyhg8J+TgiBMb29raW5nIGZvciBmaWxlOiAke2Z1bGxQYXRofWApO1xuXG4gICAgICAgICAgICBpZiAoZnMuZXhpc3RzU3luYyhmdWxsUGF0aCkpIHtcbiAgICAgICAgICAgICAgICBsb2dnZXIuaW5mbyhg4pyFIFNlcnZpbmcgZmlsZTogJHtmdWxsUGF0aH1gKTtcbiAgICAgICAgICAgICAgICBjb25zdCBjb250ZW50ID0gZnMucmVhZEZpbGVTeW5jKGZ1bGxQYXRoKTtcbiAgICAgICAgICAgICAgICByZXMuc2V0SGVhZGVyKCdDb250ZW50LVR5cGUnLCAndGV4dC9odG1sJyk7XG4gICAgICAgICAgICAgICAgcmVzLmVuZChjb250ZW50KTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgbG9nZ2VyLmVycm9yKGDinYwgRmlsZSBub3QgZm91bmQ6ICR7ZnVsbFBhdGh9YCk7XG4gICAgICAgICAgICAgICAgcmVzLnN0YXR1c0NvZGUgPSA0MDQ7XG4gICAgICAgICAgICAgICAgcmVzLmVuZCgnRG9jdW1lbnRhdGlvbiBmaWxlIG5vdCBmb3VuZCcpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgICAgICAvLyBTZXJ2ZSBnZW5lcmF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAobGVnYWN5KSAtIE1VU1QgY29tZSBhZnRlciBzZXNzaW9uLXNwZWNpZmljIHJvdXRlc1xuICAgICAgICAvLyBURU1QT1JBUklMWSBDT01NRU5URUQgT1VUIFRPIFRFU1QgU0VTU0lPTiBST1VURVNcbiAgICAgICAgLy8gdGhpcy5hcHAudXNlKCcvZG9jcycsIGV4cHJlc3Muc3RhdGljKHRoaXMuZmFrZVByb2plY3RQYXRoKSk7IC8vIFNlcnZlIGdlbmVyYXRlZCBkb2NzIGZyb20gcGxheWdyb3VuZC1kZW1vXG5cbiAgICAgICAgLy8gU2VydmUgdGhlIG1haW4gcGxheWdyb3VuZCBhcHAgZm9yIHJvb3QgcGF0aCBvbmx5XG4gICAgICAgIHRoaXMuYXBwLmdldCgnLycsIChyZXEsIHJlcykgPT4ge1xuICAgICAgICAgICAgLy8gVHJ5IGRpc3QvcmVzb3VyY2VzIGZpcnN0IChwcm9kdWN0aW9uKSwgdGhlbiBzcmMvcmVzb3VyY2VzIChkZXZlbG9wbWVudC90ZXN0aW5nKVxuICAgICAgICAgICAgY29uc3QgaW5kZXhQYXRoRGlzdCA9IHBhdGguam9pbihwcm9jZXNzLmN3ZCgpLCAnZGlzdC9yZXNvdXJjZXMvdGVtcGxhdGUtcGxheWdyb3VuZC1hcHAvaW5kZXguaHRtbCcpO1xuICAgICAgICAgICAgY29uc3QgaW5kZXhQYXRoU3JjID0gcGF0aC5qb2luKHByb2Nlc3MuY3dkKCksICdzcmMvcmVzb3VyY2VzL3RlbXBsYXRlLXBsYXlncm91bmQtYXBwL2luZGV4Lmh0bWwnKTtcbiAgICAgICAgICAgIFxuICAgICAgICAgICAgY29uc3QgaW5kZXhQYXRoID0gZnMuZXhpc3RzU3luYyhpbmRleFBhdGhEaXN0KSA/IGluZGV4UGF0aERpc3QgOiBpbmRleFBhdGhTcmM7XG4gICAgICAgICAgICBpZiAoZnMuZXhpc3RzU3luYyhpbmRleFBhdGgpKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgY29udGVudCA9IGZzLnJlYWRGaWxlU3luYyhpbmRleFBhdGgpO1xuICAgICAgICAgICAgICAgIHJlcy5zZXRIZWFkZXIoJ0NvbnRlbnQtVHlwZScsICd0ZXh0L2h0bWwnKTtcbiAgICAgICAgICAgICAgICByZXMuZW5kKGNvbnRlbnQpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXMuc3RhdHVzQ29kZSA9IDQwNDtcbiAgICAgICAgICAgICAgICByZXMuZW5kKCdUZW1wbGF0ZSBQbGF5Z3JvdW5kIG5vdCBidWlsdC4gUGxlYXNlIHJ1biB0aGUgYnVpbGQgcHJvY2Vzcy4nKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gSGFuZGxlIGFueSByZW1haW5pbmcgbm9uLUFQSSByb3V0ZXMgYnkgc2VydmluZyB0aGUgbWFpbiBhcHAgKGZvciBTUEEgcm91dGluZylcbiAgICAgICAgLy8gTm90ZTogVGhpcyBjYXRjaC1hbGwgcm91dGUgc2hvdWxkIGJlIGxhc3QgYW5kIHdpbGwgaGFuZGxlIGFsbCB1bm1hdGNoZWQgcm91dGVzXG4gICAgICAgIHRoaXMuYXBwLmdldCgnKicsIChyZXEsIHJlcykgPT4ge1xuICAgICAgICAgICAgLy8gU2tpcCBBUEksIHJlc291cmNlcywgYW5kIGRvY3Mgcm91dGVzIGFzIHRoZXkgYXJlIGhhbmRsZWQgYWJvdmVcbiAgICAgICAgICAgIGlmIChyZXEudXJsLnN0YXJ0c1dpdGgoJy9hcGknKSB8fCByZXEudXJsLnN0YXJ0c1dpdGgoJy9yZXNvdXJjZXMnKSB8fCByZXEudXJsLnN0YXJ0c1dpdGgoJy9kb2NzJykpIHtcbiAgICAgICAgICAgICAgICByZXMuc3RhdHVzQ29kZSA9IDQwNDtcbiAgICAgICAgICAgICAgICByZXMuZW5kKCdOb3QgRm91bmQnKTtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBsb2dnZXIud2Fybihg4pqg77iPIENBVENILUFMTCBST1VURSBISVQ6ICR7cmVxLm1ldGhvZH0gJHtyZXEudXJsfWApO1xuICAgICAgICAgICAgLy8gVHJ5IGRpc3QvcmVzb3VyY2VzIGZpcnN0IChwcm9kdWN0aW9uKSwgdGhlbiBzcmMvcmVzb3VyY2VzIChkZXZlbG9wbWVudC90ZXN0aW5nKVxuICAgICAgICAgICAgY29uc3QgaW5kZXhQYXRoRGlzdCA9IHBhdGguam9pbihwcm9jZXNzLmN3ZCgpLCAnZGlzdC9yZXNvdXJjZXMvdGVtcGxhdGUtcGxheWdyb3VuZC1hcHAvaW5kZXguaHRtbCcpO1xuICAgICAgICAgICAgY29uc3QgaW5kZXhQYXRoU3JjID0gcGF0aC5qb2luKHByb2Nlc3MuY3dkKCksICdzcmMvcmVzb3VyY2VzL3RlbXBsYXRlLXBsYXlncm91bmQtYXBwL2luZGV4Lmh0bWwnKTtcbiAgICAgICAgICAgIFxuICAgICAgICAgICAgY29uc3QgaW5kZXhQYXRoID0gZnMuZXhpc3RzU3luYyhpbmRleFBhdGhEaXN0KSA/IGluZGV4UGF0aERpc3QgOiBpbmRleFBhdGhTcmM7XG4gICAgICAgICAgICBpZiAoZnMuZXhpc3RzU3luYyhpbmRleFBhdGgpKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgY29udGVudCA9IGZzLnJlYWRGaWxlU3luYyhpbmRleFBhdGgpO1xuICAgICAgICAgICAgICAgIHJlcy5zZXRIZWFkZXIoJ0NvbnRlbnQtVHlwZScsICd0ZXh0L2h0bWwnKTtcbiAgICAgICAgICAgICAgICByZXMuZW5kKGNvbnRlbnQpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXMuc3RhdHVzQ29kZSA9IDQwNDtcbiAgICAgICAgICAgICAgICByZXMuZW5kKCdUZW1wbGF0ZSBQbGF5Z3JvdW5kIG5vdCBidWlsdC4gUGxlYXNlIHJ1biB0aGUgYnVpbGQgcHJvY2Vzcy4nKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBhc3luYyBnZXRUZW1wbGF0ZXMocmVxOiBhbnksIHJlczogU2VydmVyUmVzcG9uc2UpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGNvbnN0IHRlbXBsYXRlc0RpciA9IHBhdGguam9pbihwcm9jZXNzLmN3ZCgpLCAnZGlzdC90ZW1wbGF0ZXMvcGFydGlhbHMnKTtcbiAgICAgICAgICAgIGNvbnN0IGZpbGVzID0gYXdhaXQgZnMucmVhZGRpcih0ZW1wbGF0ZXNEaXIpO1xuICAgICAgICAgICAgY29uc3QgdGVtcGxhdGVzID0gZmlsZXNcbiAgICAgICAgICAgICAgICAuZmlsdGVyKGZpbGUgPT4gZmlsZS5lbmRzV2l0aCgnLmhicycpKVxuICAgICAgICAgICAgICAgIC5tYXAoZmlsZSA9PiAoe1xuICAgICAgICAgICAgICAgICAgICBuYW1lOiBmaWxlLnJlcGxhY2UoJy5oYnMnLCAnJyksXG4gICAgICAgICAgICAgICAgICAgIGZpbGVuYW1lOiBmaWxlLFxuICAgICAgICAgICAgICAgICAgICBwYXRoOiBwYXRoLmpvaW4odGVtcGxhdGVzRGlyLCBmaWxlKVxuICAgICAgICAgICAgICAgIH0pKTtcblxuICAgICAgICAgICAgc2VuZChyZXMsIDIwMCwgdGVtcGxhdGVzKTtcbiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgIGxvZ2dlci5lcnJvcignRXJyb3IgcmVhZGluZyB0ZW1wbGF0ZXM6JywgZXJyb3IpO1xuICAgICAgICAgICAgc2VuZChyZXMsIDUwMCwgeyBlcnJvcjogJ0ZhaWxlZCB0byByZWFkIHRlbXBsYXRlcycgfSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIGFzeW5jIGdldFRlbXBsYXRlKHJlcTogYW55LCByZXM6IFNlcnZlclJlc3BvbnNlKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjb25zdCB0ZW1wbGF0ZU5hbWUgPSByZXEucGFyYW1zLnRlbXBsYXRlTmFtZTtcbiAgICAgICAgICAgIGNvbnN0IHRlbXBsYXRlUGF0aCA9IHBhdGguam9pbihwcm9jZXNzLmN3ZCgpLCAnZGlzdC90ZW1wbGF0ZXMvcGFydGlhbHMnLCBgJHt0ZW1wbGF0ZU5hbWV9Lmhic2ApO1xuXG4gICAgICAgICAgICBpZiAoIWF3YWl0IGZzLnBhdGhFeGlzdHModGVtcGxhdGVQYXRoKSkge1xuICAgICAgICAgICAgICAgIHNlbmQocmVzLCA0MDQsIHsgZXJyb3I6ICdUZW1wbGF0ZSBub3QgZm91bmQnIH0pO1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uc3QgY29udGVudCA9IGF3YWl0IGZzLnJlYWRGaWxlKHRlbXBsYXRlUGF0aCwgJ3V0Zi04Jyk7XG4gICAgICAgICAgICBzZW5kKHJlcywgMjAwLCB7XG4gICAgICAgICAgICAgICAgbmFtZTogdGVtcGxhdGVOYW1lLFxuICAgICAgICAgICAgICAgIGNvbnRlbnQ6IGNvbnRlbnQsXG4gICAgICAgICAgICAgICAgcGF0aDogdGVtcGxhdGVQYXRoXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgIGxvZ2dlci5lcnJvcignRXJyb3IgcmVhZGluZyB0ZW1wbGF0ZTonLCBlcnJvcik7XG4gICAgICAgICAgICBzZW5kKHJlcywgNTAwLCB7IGVycm9yOiAnRmFpbGVkIHRvIHJlYWQgdGVtcGxhdGUnIH0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBhc3luYyBnZXRFeGFtcGxlRGF0YShyZXE6IGFueSwgcmVzOiBTZXJ2ZXJSZXNwb25zZSk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgY29uc3QgZGF0YVR5cGUgPSByZXEucGFyYW1zLmRhdGFUeXBlO1xuXG4gICAgICAgICAgICAvLyBJbXBvcnQgZXhhbXBsZSBkYXRhIGR5bmFtaWNhbGx5XG4gICAgICAgICAgICBjb25zdCB7IEVYQU1QTEVfREFUQSwgVEVNUExBVEVfQ09OVEVYVCB9ID0gYXdhaXQgaW1wb3J0KCcuL2V4YW1wbGUtZGF0YScpO1xuXG4gICAgICAgICAgICBpZiAoIUVYQU1QTEVfREFUQVtkYXRhVHlwZV0pIHtcbiAgICAgICAgICAgICAgICBzZW5kKHJlcywgNDA0LCB7IGVycm9yOiAnRXhhbXBsZSBkYXRhIHR5cGUgbm90IGZvdW5kJyB9KTtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIFdyYXAgZGF0YSBmb3IgdGVtcGxhdGUgY29tcGF0aWJpbGl0eVxuICAgICAgICAgICAgY29uc3Qgd3JhcHBlZERhdGEgPSBkYXRhVHlwZSA9PT0gJ2NvbXBvbmVudCcgfHwgZGF0YVR5cGUgPT09ICdkaXJlY3RpdmUnIHx8IGRhdGFUeXBlID09PSAncGlwZScgfHxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhVHlwZSA9PT0gJ2d1YXJkJyB8fCBkYXRhVHlwZSA9PT0gJ2ludGVyY2VwdG9yJyB8fCBkYXRhVHlwZSA9PT0gJ2luamVjdGFibGUnIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YVR5cGUgPT09ICdjbGFzcycgfHwgZGF0YVR5cGUgPT09ICdpbnRlcmZhY2UnIHx8IGRhdGFUeXBlID09PSAnZW50aXR5JyA/XG4gICAgICAgICAgICAgICAgeyBbZGF0YVR5cGVdOiBFWEFNUExFX0RBVEFbZGF0YVR5cGVdLCAuLi5FWEFNUExFX0RBVEFbZGF0YVR5cGVdIH0gOlxuICAgICAgICAgICAgICAgIEVYQU1QTEVfREFUQVtkYXRhVHlwZV07XG5cbiAgICAgICAgICAgIHNlbmQocmVzLCAyMDAsIHtcbiAgICAgICAgICAgICAgICBkYXRhOiB3cmFwcGVkRGF0YSxcbiAgICAgICAgICAgICAgICBjb250ZXh0OiBURU1QTEFURV9DT05URVhUXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgIGxvZ2dlci5lcnJvcignRXJyb3IgZ2V0dGluZyBleGFtcGxlIGRhdGE6JywgZXJyb3IpO1xuICAgICAgICAgICAgc2VuZChyZXMsIDUwMCwgeyBlcnJvcjogJ0ZhaWxlZCB0byBnZXQgZXhhbXBsZSBkYXRhJyB9KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgYXN5bmMgcmVuZGVyVGVtcGxhdGUocmVxOiBhbnksIHJlczogU2VydmVyUmVzcG9uc2UpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGNvbnN0IHsgdGVtcGxhdGVDb250ZW50LCB0ZW1wbGF0ZURhdGEsIHRlbXBsYXRlQ29udGV4dCB9ID0gcmVxLmJvZHk7XG5cbiAgICAgICAgICAgIGlmICghdGVtcGxhdGVDb250ZW50KSB7XG4gICAgICAgICAgICAgICAgc2VuZChyZXMsIDQwMCwgeyBlcnJvcjogJ1RlbXBsYXRlIGNvbnRlbnQgaXMgcmVxdWlyZWQnIH0pO1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gVXNlIHRoZSBwcmUtaW5pdGlhbGl6ZWQgSGFuZGxlYmFycyBpbnN0YW5jZVxuICAgICAgICAgICAgY29uc3QgdGVtcGxhdGUgPSB0aGlzLmhhbmRsZWJhcnMuY29tcGlsZSh0ZW1wbGF0ZUNvbnRlbnQpO1xuICAgICAgICAgICAgY29uc3QgcmVuZGVyZWQgPSB0ZW1wbGF0ZSh0ZW1wbGF0ZURhdGEgfHwge30pO1xuXG4gICAgICAgICAgICBzZW5kKHJlcywgMjAwLCB7IHJlbmRlcmVkIH0pO1xuICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgbG9nZ2VyLmVycm9yKCdFcnJvciByZW5kZXJpbmcgdGVtcGxhdGU6JywgZXJyb3IpO1xuICAgICAgICAgICAgc2VuZChyZXMsIDUwMCwge1xuICAgICAgICAgICAgICAgIGVycm9yOiAnRmFpbGVkIHRvIHJlbmRlciB0ZW1wbGF0ZScsXG4gICAgICAgICAgICAgICAgZGV0YWlsczogZXJyb3IubWVzc2FnZVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIGFzeW5jIHJlbmRlckNvbXBsZXRlUGFnZShyZXE6IGFueSwgcmVzOiBTZXJ2ZXJSZXNwb25zZSk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgbGV0IHsgdGVtcGxhdGVDb250ZW50LCB0ZW1wbGF0ZURhdGEsIHRlbXBsYXRlQ29udGV4dCB9ID0gcmVxLmJvZHk7XG5cbiAgICAgICAgICAgIC8vIEhhbmRsZSBmb3JtIGRhdGEgYnkgcGFyc2luZyBKU09OIHN0cmluZ3NcbiAgICAgICAgICAgIGlmICh0eXBlb2YgdGVtcGxhdGVEYXRhID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgIHRlbXBsYXRlRGF0YSA9IEpTT04ucGFyc2UodGVtcGxhdGVEYXRhKTtcbiAgICAgICAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgICAgICAgIHRlbXBsYXRlRGF0YSA9IHt9O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKHR5cGVvZiB0ZW1wbGF0ZUNvbnRleHQgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgdGVtcGxhdGVDb250ZXh0ID0gSlNPTi5wYXJzZSh0ZW1wbGF0ZUNvbnRleHQpO1xuICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgICAgICAgdGVtcGxhdGVDb250ZXh0ID0ge307XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoIXRlbXBsYXRlQ29udGVudCkge1xuICAgICAgICAgICAgICAgIHNlbmQocmVzLCA0MDAsIHsgZXJyb3I6ICdUZW1wbGF0ZSBjb250ZW50IGlzIHJlcXVpcmVkJyB9KTtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIEdlbmVyYXRlIHByb3BlciBDb21wb2RvYy1zdHlsZSBIVE1MIGRpcmVjdGx5XG4gICAgICAgICAgICBjb25zdCByZW5kZXJlZENvbnRlbnQgPSB0aGlzLmdlbmVyYXRlQ29tcG9kb2NIdG1sKHRlbXBsYXRlRGF0YSB8fCB7fSk7XG5cbiAgICAgICAgICAgIC8vIENyZWF0ZSBjb21wbGV0ZSBIVE1MIHBhZ2Ugd2l0aCBDb21wb2RvYyBzdHlsaW5nXG4gICAgICAgICAgICBjb25zdCBjb21wbGV0ZVBhZ2UgPSBgPCFkb2N0eXBlIGh0bWw+XG48aHRtbCBjbGFzcz1cIm5vLWpzXCIgbGFuZz1cIlwiPlxuICAgIDxoZWFkPlxuICAgICAgICA8bWV0YSBjaGFyc2V0PVwidXRmLThcIj5cbiAgICAgICAgPG1ldGEgaHR0cC1lcXVpdj1cIngtdWEtY29tcGF0aWJsZVwiIGNvbnRlbnQ9XCJpZT1lZGdlXCI+XG4gICAgICAgIDx0aXRsZT5UZW1wbGF0ZSBQcmV2aWV3IC0gQ29tcG9kb2M8L3RpdGxlPlxuICAgICAgICA8bWV0YSBuYW1lPVwiZGVzY3JpcHRpb25cIiBjb250ZW50PVwiXCI+XG4gICAgICAgIDxtZXRhIG5hbWU9XCJ2aWV3cG9ydFwiIGNvbnRlbnQ9XCJ3aWR0aD1kZXZpY2Utd2lkdGgsIGluaXRpYWwtc2NhbGU9MVwiPlxuXG4gICAgICAgIDxsaW5rIHJlbD1cImljb25cIiB0eXBlPVwiaW1hZ2UveC1pY29uXCIgaHJlZj1cIi9yZXNvdXJjZXMvaW1hZ2VzL2Zhdmljb24uaWNvXCI+XG4gICAgICAgIDxsaW5rIHJlbD1cInN0eWxlc2hlZXRcIiBocmVmPVwiL3Jlc291cmNlcy9zdHlsZXMvYm9vdHN0cmFwLm1pbi5jc3NcIj5cbiAgICAgICAgPGxpbmsgcmVsPVwic3R5bGVzaGVldFwiIGhyZWY9XCIvcmVzb3VyY2VzL3N0eWxlcy9jb21wb2RvYy5jc3NcIj5cbiAgICAgICAgPGxpbmsgcmVsPVwic3R5bGVzaGVldFwiIGhyZWY9XCIvcmVzb3VyY2VzL3N0eWxlcy9wcmlzbS5jc3NcIj5cbiAgICAgICAgPGxpbmsgcmVsPVwic3R5bGVzaGVldFwiIGhyZWY9XCIvcmVzb3VyY2VzL3N0eWxlcy9kYXJrLmNzc1wiPlxuICAgICAgICA8bGluayByZWw9XCJzdHlsZXNoZWV0XCIgaHJlZj1cIi9yZXNvdXJjZXMvc3R5bGVzL3N0eWxlLmNzc1wiPlxuICAgIDwvaGVhZD5cbiAgICA8Ym9keT5cbiAgICAgICAgPHNjcmlwdD5cbiAgICAgICAgICAgIC8vIEJsb2NraW5nIHNjcmlwdCB0byBhdm9pZCBmbGlja2VyaW5nIGRhcmsgbW9kZVxuICAgICAgICAgICAgdmFyIHVzZURhcmsgPSB3aW5kb3cubWF0Y2hNZWRpYSgnKHByZWZlcnMtY29sb3Itc2NoZW1lOiBkYXJrKScpO1xuICAgICAgICAgICAgdmFyIGRhcmtNb2RlU3RhdGUgPSB1c2VEYXJrLm1hdGNoZXM7XG4gICAgICAgICAgICB2YXIgZGFya01vZGVTdGF0ZUxvY2FsID0gbG9jYWxTdG9yYWdlLmdldEl0ZW0oJ2NvbXBvZG9jX2Rhcmttb2RlLXN0YXRlJyk7XG4gICAgICAgICAgICBpZiAoZGFya01vZGVTdGF0ZUxvY2FsKSB7XG4gICAgICAgICAgICAgICAgZGFya01vZGVTdGF0ZSA9IGRhcmtNb2RlU3RhdGVMb2NhbCA9PT0gJ3RydWUnO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGRhcmtNb2RlU3RhdGUpIHtcbiAgICAgICAgICAgICAgICBkb2N1bWVudC5ib2R5LmNsYXNzTGlzdC5hZGQoJ2RhcmsnKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgPC9zY3JpcHQ+XG5cbiAgICAgICAgPGRpdiBjbGFzcz1cImNvbnRhaW5lci1mbHVpZCBtYWluXCI+XG4gICAgICAgICAgICA8IS0tIFNUQVJUIENPTlRFTlQgLS0+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29udGVudCBjb21wb25lbnRcIj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29udGVudC1kYXRhXCI+XG4gICAgICAgICAgICAgICAgICAgICR7cmVuZGVyZWRDb250ZW50fVxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8IS0tIEVORCBDT05URU5UIC0tPlxuICAgICAgICA8L2Rpdj5cblxuICAgICAgICA8c2NyaXB0PlxuICAgICAgICAgICAgdmFyIENPTVBPRE9DX0NVUlJFTlRfUEFHRV9ERVBUSCA9IDA7XG4gICAgICAgICAgICB2YXIgQ09NUE9ET0NfQ1VSUkVOVF9QQUdFX0NPTlRFWFQgPSAnY29tcG9uZW50JztcbiAgICAgICAgICAgIHZhciBDT01QT0RPQ19DVVJSRU5UX1BBR0VfVVJMID0gJ2NvbXBvbmVudC5odG1sJztcbiAgICAgICAgPC9zY3JpcHQ+XG5cbiAgICAgICAgPHNjcmlwdCBzcmM9XCIvcmVzb3VyY2VzL2pzL2xpYnMvYm9vdHN0cmFwLW5hdGl2ZS5qc1wiPjwvc2NyaXB0PlxuICAgICAgICA8c2NyaXB0IHNyYz1cIi9yZXNvdXJjZXMvanMvbGlicy9wcmlzbS5qc1wiPjwvc2NyaXB0PlxuICAgICAgICA8c2NyaXB0IHNyYz1cIi9yZXNvdXJjZXMvanMvY29tcG9kb2MuanNcIj48L3NjcmlwdD5cbiAgICAgICAgPHNjcmlwdCBzcmM9XCIvcmVzb3VyY2VzL2pzL3RhYnMuanNcIj48L3NjcmlwdD5cbiAgICAgICAgPHNjcmlwdCBzcmM9XCIvcmVzb3VyY2VzL2pzL3NvdXJjZUNvZGUuanNcIj48L3NjcmlwdD5cbiAgICA8L2JvZHk+XG48L2h0bWw+YDtcblxuICAgICAgICAgICAgcmVzLnNldEhlYWRlcignQ29udGVudC1UeXBlJywgJ3RleHQvaHRtbCcpO1xuICAgICAgICAgICAgcmVzLmVuZChjb21wbGV0ZVBhZ2UpO1xuICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgbG9nZ2VyLmVycm9yKCdFcnJvciByZW5kZXJpbmcgY29tcGxldGUgcGFnZTonLCBlcnJvcik7XG4gICAgICAgICAgICBzZW5kKHJlcywgNTAwLCB7XG4gICAgICAgICAgICAgICAgZXJyb3I6ICdGYWlsZWQgdG8gcmVuZGVyIGNvbXBsZXRlIHBhZ2UnLFxuICAgICAgICAgICAgICAgIGRldGFpbHM6IGVycm9yLm1lc3NhZ2VcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBhc3luYyBnZW5lcmF0ZURvY3MocmVxOiBhbnksIHJlczogU2VydmVyUmVzcG9uc2UpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGNvbnN0IHsgY3VzdG9tVGVtcGxhdGVDb250ZW50LCBtb2NrRGF0YSB9ID0gcmVxLmJvZHk7XG5cbiAgICAgICAgICAgIC8vIFVwZGF0ZSBtb2NrIGRhdGEgaWYgcHJvdmlkZWRcbiAgICAgICAgICAgIGlmIChtb2NrRGF0YSkge1xuICAgICAgICAgICAgICAgIC8vIFRoaXMgcGFydCBvZiB0aGUgbG9naWMgbmVlZHMgdG8gYmUgYWRhcHRlZCB0byB3b3JrIHdpdGggdGhlIG5ldyBzZXNzaW9uLWJhc2VkIHN5c3RlbVxuICAgICAgICAgICAgICAgIC8vIEZvciBub3csIHdlJ2xsIGp1c3QgbG9nIHRoYXQgaXQncyBub3QgZGlyZWN0bHkgYXBwbGljYWJsZSBoZXJlXG4gICAgICAgICAgICAgICAgbG9nZ2VyLndhcm4oJ21vY2tEYXRhIHBhcmFtZXRlciBpcyBub3QgZGlyZWN0bHkgYXBwbGljYWJsZSBpbiB0aGlzIHNlc3Npb24tYmFzZWQgc3lzdGVtLiBJdCB3aWxsIGJlIGlnbm9yZWQuJyk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIENyZWF0ZSBvciBnZXQgc2Vzc2lvbiBmb3IgdGhlIGRvY3VtZW50YXRpb24gZ2VuZXJhdGlvbiBiYXNlZCBvbiBjbGllbnQgSVBcbiAgICAgICAgICAgIGNvbnN0IGNsaWVudElQID0gdGhpcy5nZXRDbGllbnRJUChyZXEpO1xuICAgICAgICAgICAgY29uc3Qgc2Vzc2lvbiA9IHRoaXMuY3JlYXRlT3JHZXRTZXNzaW9uQnlJUChjbGllbnRJUCk7XG4gICAgICAgICAgICBjb25zdCBzZXNzaW9uSWQgPSBzZXNzaW9uLmlkO1xuXG4gICAgICAgICAgICAvLyBVcGRhdGUgc2Vzc2lvbiBjb25maWcgaWYgY3VzdG9tIHRlbXBsYXRlIGNvbnRlbnQgaXMgcHJvdmlkZWRcbiAgICAgICAgICAgIGlmIChjdXN0b21UZW1wbGF0ZUNvbnRlbnQgJiYgcmVxLmJvZHkudGVtcGxhdGVQYXRoKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgdGVtcGxhdGVQYXRoID0gcGF0aC5qb2luKHNlc3Npb24udGVtcGxhdGVEaXIsIHJlcS5ib2R5LnRlbXBsYXRlUGF0aCk7XG4gICAgICAgICAgICAgICAgYXdhaXQgZnMud3JpdGVGaWxlKHRlbXBsYXRlUGF0aCwgY3VzdG9tVGVtcGxhdGVDb250ZW50LCAndXRmOCcpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBHZW5lcmF0ZSBkb2N1bWVudGF0aW9uIGZvciB0aGUgbmV3IHNlc3Npb25cbiAgICAgICAgICAgIHRoaXMuZ2VuZXJhdGVEb2N1bWVudGF0aW9uKHNlc3Npb25JZCwgdHJ1ZSk7IC8vIFVzZSBkZWJvdW5jZVxuXG4gICAgICAgICAgICBzZW5kKHJlcywgMjAwLCB7IHN1Y2Nlc3M6IHRydWUsIG1lc3NhZ2U6ICdEb2N1bWVudGF0aW9uIGdlbmVyYXRpb24gaW5pdGlhdGVkIGZvciBhIG5ldyBzZXNzaW9uJywgc2Vzc2lvbklkOiBzZXNzaW9uSWQgfSk7XG4gICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICBsb2dnZXIuZXJyb3IoJ0Vycm9yIGdlbmVyYXRpbmcgZG9jdW1lbnRhdGlvbjonLCBlcnJvcik7XG4gICAgICAgICAgICBzZW5kKHJlcywgNTAwLCB7XG4gICAgICAgICAgICAgICAgZXJyb3I6ICdGYWlsZWQgdG8gZ2VuZXJhdGUgZG9jdW1lbnRhdGlvbicsXG4gICAgICAgICAgICAgICAgZGV0YWlsczogZXJyb3IubWVzc2FnZVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIHJlZ2lzdGVySGFuZGxlYmFyc0hlbHBlcnMoSGFuZGxlYmFyczogYW55LCBjb250ZXh0OiBhbnkpOiB2b2lkIHtcbiAgICAgICAgLy8gUmVnaXN0ZXIgdHJhbnNsYXRpb24gaGVscGVyIChtYXRjaGVzIENvbXBvZG9jJ3MgaTE4biBoZWxwZXIgcGF0dGVybilcbiAgICAgICAgSGFuZGxlYmFycy5yZWdpc3RlckhlbHBlcigndCcsIGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgY29uc29sZS5sb2coJ1QgSEVMUEVSIENBTExFRCcpO1xuICAgICAgICAgICAgY29uc3QgY29udGV4dCA9IHRoaXM7XG4gICAgICAgICAgICBjb25zdCBrZXkgPSBhcmd1bWVudHNbMF07XG4gICAgICAgICAgICBjb25zdCB0cmFuc2xhdGlvbnM6IHsgW2tleTogc3RyaW5nXTogc3RyaW5nIH0gPSB7XG4gICAgICAgICAgICAgICAgJ2NvbXBvbmVudHMnOiAnQ29tcG9uZW50cycsXG4gICAgICAgICAgICAgICAgJ21vZHVsZXMnOiAnTW9kdWxlcycsXG4gICAgICAgICAgICAgICAgJ2ludGVyZmFjZXMnOiAnSW50ZXJmYWNlcycsXG4gICAgICAgICAgICAgICAgJ2NsYXNzZXMnOiAnQ2xhc3NlcycsXG4gICAgICAgICAgICAgICAgJ2luamVjdGFibGVzJzogJ0luamVjdGFibGVzJyxcbiAgICAgICAgICAgICAgICAncGlwZXMnOiAnUGlwZXMnLFxuICAgICAgICAgICAgICAgICdkaXJlY3RpdmVzJzogJ0RpcmVjdGl2ZXMnLFxuICAgICAgICAgICAgICAgICdndWFyZHMnOiAnR3VhcmRzJyxcbiAgICAgICAgICAgICAgICAnaW50ZXJjZXB0b3JzJzogJ0ludGVyY2VwdG9ycycsXG4gICAgICAgICAgICAgICAgJ2VudGl0aWVzJzogJ0VudGl0aWVzJyxcbiAgICAgICAgICAgICAgICAnY29udHJvbGxlcnMnOiAnQ29udHJvbGxlcnMnLFxuICAgICAgICAgICAgICAgICdpbmZvJzogJ0luZm8nLFxuICAgICAgICAgICAgICAgICdyZWFkbWUnOiAnUmVhZG1lJyxcbiAgICAgICAgICAgICAgICAnc291cmNlJzogJ1NvdXJjZScsXG4gICAgICAgICAgICAgICAgJ3RlbXBsYXRlJzogJ1RlbXBsYXRlJyxcbiAgICAgICAgICAgICAgICAnc3R5bGVzJzogJ1N0eWxlcycsXG4gICAgICAgICAgICAgICAgJ2RvbS10cmVlJzogJ0RPTSBUcmVlJyxcbiAgICAgICAgICAgICAgICAnZmlsZSc6ICdGaWxlJyxcbiAgICAgICAgICAgICAgICAnZGVzY3JpcHRpb24nOiAnRGVzY3JpcHRpb24nLFxuICAgICAgICAgICAgICAgICdpbXBsZW1lbnRzJzogJ0ltcGxlbWVudHMnLFxuICAgICAgICAgICAgICAgICdtZXRhZGF0YSc6ICdNZXRhZGF0YScsXG4gICAgICAgICAgICAgICAgJ2luZGV4JzogJ0luZGV4JyxcbiAgICAgICAgICAgICAgICAnbWV0aG9kcyc6ICdNZXRob2RzJyxcbiAgICAgICAgICAgICAgICAncHJvcGVydGllcyc6ICdQcm9wZXJ0aWVzJ1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIHJldHVybiB0cmFuc2xhdGlvbnNba2V5XSB8fCBrZXk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIFJlZ2lzdGVyIHJlbGF0aXZlIFVSTCBoZWxwZXJcbiAgICAgICAgSGFuZGxlYmFycy5yZWdpc3RlckhlbHBlcigncmVsYXRpdmVVUkwnLCAoZGVwdGg6IGFueSwgLi4uYXJnczogYW55W10pID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGRlcHRoVmFsdWUgPSB0eXBlb2YgZGVwdGggPT09ICdudW1iZXInID8gZGVwdGggOiAoY29udGV4dC5kZXB0aCB8fCAwKTtcbiAgICAgICAgICAgIGNvbnN0IGJhc2VVcmwgPSAnLi4vJy5yZXBlYXQoZGVwdGhWYWx1ZSk7XG4gICAgICAgICAgICBjb25zdCBwYXRoQXJncyA9IGFyZ3Muc2xpY2UoMCwgLTEpOyAvLyBSZW1vdmUgSGFuZGxlYmFycyBvcHRpb25zIG9iamVjdFxuICAgICAgICAgICAgcmV0dXJuIGJhc2VVcmwgKyBwYXRoQXJncy5qb2luKCcvJyk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBSZWdpc3RlciBjb21wYXJpc29uIGhlbHBlciAobWF0Y2hlcyBDb21wb2RvYydzIENvbXBhcmVIZWxwZXIgaW1wbGVtZW50YXRpb24pXG4gICAgICAgIEhhbmRsZWJhcnMucmVnaXN0ZXJIZWxwZXIoJ2NvbXBhcmUnLCBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgIGNvbnN0IGNvbnRleHQgPSB0aGlzO1xuICAgICAgICAgICAgY29uc3QgYSA9IGFyZ3VtZW50c1swXTtcbiAgICAgICAgICAgIGNvbnN0IG9wZXJhdG9yID0gYXJndW1lbnRzWzFdO1xuICAgICAgICAgICAgY29uc3QgYiA9IGFyZ3VtZW50c1syXTtcbiAgICAgICAgICAgIGNvbnN0IG9wdGlvbnMgPSBhcmd1bWVudHNbM107XG5cbiAgICAgICAgICAgIGlmIChhcmd1bWVudHMubGVuZ3RoIDwgNCkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignaGFuZGxlYmFycyBIZWxwZXIge3tjb21wYXJlfX0gZXhwZWN0cyA0IGFyZ3VtZW50cycpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBsZXQgcmVzdWx0ID0gZmFsc2U7XG4gICAgICAgICAgICBzd2l0Y2ggKG9wZXJhdG9yKSB7XG4gICAgICAgICAgICAgICAgY2FzZSAnaW5kZXhvZic6XG4gICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IGIuaW5kZXhPZihhKSAhPT0gLTE7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGNhc2UgJz09PSc6XG4gICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IGEgPT09IGI7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGNhc2UgJyE9PSc6XG4gICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IGEgIT09IGI7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGNhc2UgJz4nOlxuICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSBhID4gYjtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgY2FzZSAnPCc6XG4gICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IGEgPCBiO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBjYXNlICc+PSc6XG4gICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IGEgPj0gYjtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgY2FzZSAnPD0nOlxuICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSBhIDw9IGI7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGNhc2UgJz09JzpcbiAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gYSA9PSBiO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBjYXNlICchPSc6XG4gICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IGEgIT0gYjtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdoZWxwZXIge3tjb21wYXJlfX06IGludmFsaWQgb3BlcmF0b3I6IGAnICsgb3BlcmF0b3IgKyAnYCcpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAocmVzdWx0ID09PSBmYWxzZSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBvcHRpb25zLmludmVyc2UoY29udGV4dCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gb3B0aW9ucy5mbihjb250ZXh0KTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gUmVnaXN0ZXIgdGFiIGhlbHBlcnMgKG1hdGNoZXMgQ29tcG9kb2MncyBJc1RhYkVuYWJsZWRIZWxwZXIgYW5kIElzSW5pdGlhbFRhYkhlbHBlcilcbiAgICAgICAgSGFuZGxlYmFycy5yZWdpc3RlckhlbHBlcignaXNUYWJFbmFibGVkJywgZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICBjb25zdCBjb250ZXh0ID0gdGhpcztcbiAgICAgICAgICAgIGNvbnN0IG5hdlRhYnMgPSBhcmd1bWVudHNbMF07XG4gICAgICAgICAgICBjb25zdCB0YWJJZCA9IGFyZ3VtZW50c1sxXTtcbiAgICAgICAgICAgIGNvbnN0IG9wdGlvbnMgPSBhcmd1bWVudHNbMl07XG5cbiAgICAgICAgICAgIGNvbnN0IGlzRW5hYmxlZCA9IG5hdlRhYnMgJiYgbmF2VGFicy5zb21lKCh0YWI6IGFueSkgPT4gdGFiLmlkID09PSB0YWJJZCk7XG4gICAgICAgICAgICBpZiAoaXNFbmFibGVkKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG9wdGlvbnMuZm4oY29udGV4dCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJldHVybiBvcHRpb25zLmludmVyc2UoY29udGV4dCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuXG4gICAgICAgIEhhbmRsZWJhcnMucmVnaXN0ZXJIZWxwZXIoJ2lzSW5pdGlhbFRhYicsIGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgY29uc3QgY29udGV4dCA9IHRoaXM7XG4gICAgICAgICAgICBjb25zdCBuYXZUYWJzID0gYXJndW1lbnRzWzBdO1xuICAgICAgICAgICAgY29uc3QgdGFiSWQgPSBhcmd1bWVudHNbMV07XG5cbiAgICAgICAgICAgIGNvbnN0IGlzSW5pdGlhbCA9IG5hdlRhYnMgJiYgbmF2VGFicy5sZW5ndGggPiAwICYmIG5hdlRhYnNbMF0uaWQgPT09IHRhYklkO1xuICAgICAgICAgICAgaWYgKGlzSW5pdGlhbCkge1xuICAgICAgICAgICAgICAgIHJldHVybiAnYWN0aXZlIGluJztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiAnJztcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gUmVnaXN0ZXIgdXRpbGl0eSBoZWxwZXJzXG4gICAgICAgIEhhbmRsZWJhcnMucmVnaXN0ZXJIZWxwZXIoJ29yTGVuZ3RoJywgZnVuY3Rpb24oLi4uYXJnczogYW55W10pIHtcbiAgICAgICAgICAgIGNvbnN0IG9wdGlvbnMgPSBhcmdzLnBvcCgpO1xuICAgICAgICAgICAgY29uc3QgaGFzTGVuZ3RoID0gYXJncy5zb21lKGFyZyA9PiBhcmcgJiYgKEFycmF5LmlzQXJyYXkoYXJnKSA/IGFyZy5sZW5ndGggPiAwIDogYXJnKSk7XG4gICAgICAgICAgICBpZiAoaGFzTGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG9wdGlvbnMuZm4odGhpcyk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJldHVybiBvcHRpb25zLmludmVyc2UodGhpcyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuXG4gICAgICAgIEhhbmRsZWJhcnMucmVnaXN0ZXJIZWxwZXIoJ2JyZWFrQ29tbWEnLCBmdW5jdGlvbihhcnJheTogYW55W10pIHtcbiAgICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KGFycmF5KSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBhcnJheS5qb2luKCcsICcpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIGFycmF5O1xuICAgICAgICB9KTtcblxuICAgICAgICBIYW5kbGViYXJzLnJlZ2lzdGVySGVscGVyKCdwYXJzZURlc2NyaXB0aW9uJywgZnVuY3Rpb24oZGVzY3JpcHRpb246IHN0cmluZywgZGVwdGg6IG51bWJlcikge1xuICAgICAgICAgICAgLy8gU2ltcGxlIG1hcmtkb3duIHBhcnNpbmcgLSBqdXN0IHJldHVybiBhcyBIVE1MIGZvciBub3dcbiAgICAgICAgICAgIHJldHVybiBuZXcgSGFuZGxlYmFycy5TYWZlU3RyaW5nKGRlc2NyaXB0aW9uIHx8ICcnKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgSGFuZGxlYmFycy5yZWdpc3RlckhlbHBlcignZXNjYXBlU2ltcGxlUXVvdGUnLCBmdW5jdGlvbih0ZXh0OiBzdHJpbmcpIHtcbiAgICAgICAgICAgIGlmICh0eXBlb2YgdGV4dCA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGV4dC5yZXBsYWNlKC8nL2csIFwiXFxcXCdcIik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gdGV4dDtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gUmVnaXN0ZXIgSlNEb2MgaGVscGVyXG4gICAgICAgIEhhbmRsZWJhcnMucmVnaXN0ZXJIZWxwZXIoJ2pzZG9jLWNvZGUtZXhhbXBsZScsIGZ1bmN0aW9uKGpzZG9jdGFnczogYW55W10sIG9wdGlvbnM6IGFueSkge1xuICAgICAgICAgICAgcmV0dXJuIG9wdGlvbnMuZm4oeyB0YWdzOiBqc2RvY3RhZ3MgfHwgW10gfSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIFJlZ2lzdGVyIGxpbmstdHlwZSBoZWxwZXIgYXMgYSBzaW1wbGUgcGFydGlhbFxuICAgICAgICBIYW5kbGViYXJzLnJlZ2lzdGVySGVscGVyKCdsaW5rLXR5cGUnLCBmdW5jdGlvbih0eXBlOiBhbnksIG9wdGlvbnM6IGFueSkge1xuICAgICAgICAgICAgaWYgKHR5cGUgJiYgdHlwZS5ocmVmKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBIYW5kbGViYXJzLlNhZmVTdHJpbmcoYDxhIGhyZWY9XCIke3R5cGUuaHJlZn1cIiB0YXJnZXQ9XCIke3R5cGUudGFyZ2V0IHx8ICdfc2VsZid9XCI+JHt0eXBlLnJhdyB8fCB0eXBlfTwvYT5gKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB0eXBlO1xuICAgICAgICB9KTtcblxuICAgICAgICAvLyBSZWdpc3RlciBidWlsdC1pbiBibG9jayBoZWxwZXJzXG4gICAgICAgIEhhbmRsZWJhcnMucmVnaXN0ZXJIZWxwZXIoJ2VhY2gnLCBIYW5kbGViYXJzLmhlbHBlcnMuZWFjaCk7XG4gICAgICAgIEhhbmRsZWJhcnMucmVnaXN0ZXJIZWxwZXIoJ2lmJywgSGFuZGxlYmFycy5oZWxwZXJzLmlmKTtcbiAgICAgICAgSGFuZGxlYmFycy5yZWdpc3RlckhlbHBlcigndW5sZXNzJywgSGFuZGxlYmFycy5oZWxwZXJzLnVubGVzcyk7XG4gICAgICAgIEhhbmRsZWJhcnMucmVnaXN0ZXJIZWxwZXIoJ3dpdGgnLCBIYW5kbGViYXJzLmhlbHBlcnMud2l0aCk7XG5cbiAgICAgICAgLy8gUmVnaXN0ZXIgY29tbW9uIHBhcnRpYWxzIHVzZWQgaW4gdGVtcGxhdGVzXG4gICAgICAgIEhhbmRsZWJhcnMucmVnaXN0ZXJQYXJ0aWFsKCdjb21wb25lbnQtZGV0YWlsJywgYFxuICAgICAgICAgICAgPHAgY2xhc3M9XCJjb21tZW50XCI+XG4gICAgICAgICAgICAgICAgPGgzPnt7dCBcImZpbGVcIn19PC9oMz5cbiAgICAgICAgICAgIDwvcD5cbiAgICAgICAgICAgIDxwIGNsYXNzPVwiY29tbWVudFwiPlxuICAgICAgICAgICAgICAgIDxjb2RlPnt7Y29tcG9uZW50LmZpbGV9fTwvY29kZT5cbiAgICAgICAgICAgIDwvcD5cblxuICAgICAgICAgICAge3sjaWYgY29tcG9uZW50LmRlc2NyaXB0aW9ufX1cbiAgICAgICAgICAgICAgICA8cCBjbGFzcz1cImNvbW1lbnRcIj5cbiAgICAgICAgICAgICAgICAgICAgPGgzPnt7dCBcImRlc2NyaXB0aW9uXCJ9fTwvaDM+XG4gICAgICAgICAgICAgICAgPC9wPlxuICAgICAgICAgICAgICAgIDxwIGNsYXNzPVwiY29tbWVudFwiPlxuICAgICAgICAgICAgICAgICAgICB7e3twYXJzZURlc2NyaXB0aW9uIGNvbXBvbmVudC5kZXNjcmlwdGlvbiBkZXB0aH19fVxuICAgICAgICAgICAgICAgIDwvcD5cbiAgICAgICAgICAgIHt7L2lmfX1cblxuICAgICAgICAgICAge3sjaWYgY29tcG9uZW50LmltcGxlbWVudHN9fVxuICAgICAgICAgICAgICAgIDxwIGNsYXNzPVwiY29tbWVudFwiPlxuICAgICAgICAgICAgICAgICAgICA8aDM+e3t0IFwiaW1wbGVtZW50c1wifX08L2gzPlxuICAgICAgICAgICAgICAgIDwvcD5cbiAgICAgICAgICAgICAgICA8cCBjbGFzcz1cImNvbW1lbnRcIj5cbiAgICAgICAgICAgICAgICAgICAge3sjZWFjaCBjb21wb25lbnQuaW1wbGVtZW50c319XG4gICAgICAgICAgICAgICAgICAgICAgICA8Y29kZT57e3RoaXN9fTwvY29kZT57eyN1bmxlc3MgQGxhc3R9fSwge3svdW5sZXNzfX1cbiAgICAgICAgICAgICAgICAgICAge3svZWFjaH19XG4gICAgICAgICAgICAgICAgPC9wPlxuICAgICAgICAgICAge3svaWZ9fVxuXG4gICAgICAgICAgICA8c2VjdGlvbiBkYXRhLWNvbXBvZG9jPVwiYmxvY2stbWV0YWRhdGFcIj5cbiAgICAgICAgICAgICAgICA8aDM+e3t0IFwibWV0YWRhdGFcIn19PC9oMz5cbiAgICAgICAgICAgICAgICA8dGFibGUgY2xhc3M9XCJ0YWJsZSB0YWJsZS1zbSB0YWJsZS1ob3ZlciBtZXRhZGF0YVwiPlxuICAgICAgICAgICAgICAgICAgICA8dGJvZHk+XG4gICAgICAgICAgICAgICAgICAgICAgICB7eyNpZiBjb21wb25lbnQuc2VsZWN0b3J9fVxuICAgICAgICAgICAgICAgICAgICAgICAgPHRyPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0ZCBjbGFzcz1cImNvbC1tZC0zXCI+c2VsZWN0b3I8L3RkPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0ZCBjbGFzcz1cImNvbC1tZC05XCI+PGNvZGU+e3tjb21wb25lbnQuc2VsZWN0b3J9fTwvY29kZT48L3RkPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC90cj5cbiAgICAgICAgICAgICAgICAgICAgICAgIHt7L2lmfX1cbiAgICAgICAgICAgICAgICAgICAgICAgIHt7I2lmIGNvbXBvbmVudC50ZW1wbGF0ZVVybH19XG4gICAgICAgICAgICAgICAgICAgICAgICA8dHI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRkIGNsYXNzPVwiY29sLW1kLTNcIj50ZW1wbGF0ZVVybDwvdGQ+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRkIGNsYXNzPVwiY29sLW1kLTlcIj48Y29kZT57e2NvbXBvbmVudC50ZW1wbGF0ZVVybH19PC9jb2RlPjwvdGQ+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L3RyPlxuICAgICAgICAgICAgICAgICAgICAgICAge3svaWZ9fVxuICAgICAgICAgICAgICAgICAgICAgICAge3sjaWYgY29tcG9uZW50LnN0eWxlVXJsc319XG4gICAgICAgICAgICAgICAgICAgICAgICA8dHI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRkIGNsYXNzPVwiY29sLW1kLTNcIj5zdHlsZVVybHM8L3RkPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0ZCBjbGFzcz1cImNvbC1tZC05XCI+PGNvZGU+e3ticmVha0NvbW1hIGNvbXBvbmVudC5zdHlsZVVybHN9fTwvY29kZT48L3RkPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC90cj5cbiAgICAgICAgICAgICAgICAgICAgICAgIHt7L2lmfX1cbiAgICAgICAgICAgICAgICAgICAgPC90Ym9keT5cbiAgICAgICAgICAgICAgICA8L3RhYmxlPlxuICAgICAgICAgICAgPC9zZWN0aW9uPlxuXG4gICAgICAgICAgICB7eyNvckxlbmd0aCBjb21wb25lbnQucHJvcGVydGllcyBjb21wb25lbnQubWV0aG9kcyBjb21wb25lbnQuaW5wdXRzIGNvbXBvbmVudC5vdXRwdXRzfX1cbiAgICAgICAgICAgICAgICA8c2VjdGlvbiBkYXRhLWNvbXBvZG9jPVwiYmxvY2staW5kZXhcIj5cbiAgICAgICAgICAgICAgICAgICAgPGgzIGlkPVwiaW5kZXhcIj57e3QgXCJpbmRleFwifX08L2gzPlxuICAgICAgICAgICAgICAgICAgICA8dGFibGUgY2xhc3M9XCJ0YWJsZSB0YWJsZS1zbSB0YWJsZS1ib3JkZXJlZCBpbmRleC10YWJsZVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPHRib2R5PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7I2lmIGNvbXBvbmVudC5tZXRob2RzfX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dHI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0ZCBjbGFzcz1cImNvbC1tZC00XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aDY+PGI+e3t0IFwibWV0aG9kc1wifX08L2I+PC9oNj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RyPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0cj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRkIGNsYXNzPVwiY29sLW1kLTRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx1bCBjbGFzcz1cImluZGV4LWxpc3RcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7eyNlYWNoIGNvbXBvbmVudC5tZXRob2RzfX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bGk+PGEgaHJlZj1cIiN7e25hbWV9fVwiPnt7bmFtZX19PC9hPjwvbGk+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3svZWFjaH19XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3VsPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdHI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAge3svaWZ9fVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7I2lmIGNvbXBvbmVudC5wcm9wZXJ0aWVzfX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dHI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0ZCBjbGFzcz1cImNvbC1tZC00XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aDY+PGI+e3t0IFwicHJvcGVydGllc1wifX08L2I+PC9oNj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RyPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0cj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRkIGNsYXNzPVwiY29sLW1kLTRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx1bCBjbGFzcz1cImluZGV4LWxpc3RcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7eyNlYWNoIGNvbXBvbmVudC5wcm9wZXJ0aWVzfX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bGk+PGEgaHJlZj1cIiN7e25hbWV9fVwiPnt7bmFtZX19PC9hPjwvbGk+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3svZWFjaH19XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3VsPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdHI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAge3svaWZ9fVxuICAgICAgICAgICAgICAgICAgICAgICAgPC90Ym9keT5cbiAgICAgICAgICAgICAgICAgICAgPC90YWJsZT5cbiAgICAgICAgICAgICAgICA8L3NlY3Rpb24+XG4gICAgICAgICAgICB7ey9vckxlbmd0aH19XG5cbiAgICAgICAgICAgIHt7I2lmIGNvbXBvbmVudC5tZXRob2RzfX1cbiAgICAgICAgICAgICAgICA8c2VjdGlvbiBkYXRhLWNvbXBvZG9jPVwiYmxvY2stbWV0aG9kc1wiPlxuICAgICAgICAgICAgICAgICAgICA8aDMgaWQ9XCJtZXRob2RzXCI+e3t0IFwibWV0aG9kc1wifX08L2gzPlxuICAgICAgICAgICAgICAgICAgICB7eyNlYWNoIGNvbXBvbmVudC5tZXRob2RzfX1cbiAgICAgICAgICAgICAgICAgICAgPHRhYmxlIGNsYXNzPVwidGFibGUgdGFibGUtc20gdGFibGUtYm9yZGVyZWRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDx0Ym9keT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dHI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0ZCBjbGFzcz1cImNvbC1tZC00XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8YSBuYW1lPVwie3tuYW1lfX1cIj48L2E+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cIm5hbWVcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3Bhbj48Yj57e25hbWV9fTwvYj48L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGEgaHJlZj1cIiN7e25hbWV9fVwiPjxzcGFuIGNsYXNzPVwiaWNvbiBpb24taW9zLWxpbmtcIj48L3NwYW4+PC9hPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdHI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRyPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGQgY2xhc3M9XCJjb2wtbWQtNFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGNvZGU+e3tuYW1lfX0oe3sjZWFjaCBhcmdzfX17e25hbWV9fToge3t0eXBlfX17eyN1bmxlc3MgQGxhc3R9fSwge3svdW5sZXNzfX17ey9lYWNofX0pPC9jb2RlPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdHI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAge3sjaWYgZGVzY3JpcHRpb259fVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0cj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRkIGNsYXNzPVwiY29sLW1kLTRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJpby1kZXNjcmlwdGlvblwiPnt7ZGVzY3JpcHRpb259fTwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImlvLWRlc2NyaXB0aW9uXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGI+UmV0dXJucyA6IDwvYj48Y29kZT57e3R5cGV9fTwvY29kZT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdHI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAge3svaWZ9fVxuICAgICAgICAgICAgICAgICAgICAgICAgPC90Ym9keT5cbiAgICAgICAgICAgICAgICAgICAgPC90YWJsZT5cbiAgICAgICAgICAgICAgICAgICAge3svZWFjaH19XG4gICAgICAgICAgICAgICAgPC9zZWN0aW9uPlxuICAgICAgICAgICAge3svaWZ9fVxuICAgICAgICBgKTtcblxuICAgICAgICBIYW5kbGViYXJzLnJlZ2lzdGVyUGFydGlhbCgnaW5kZXgnLCAnPCEtLSBJbmRleCBwYXJ0aWFsIHBsYWNlaG9sZGVyIC0tPicpO1xuICAgICAgICBIYW5kbGViYXJzLnJlZ2lzdGVyUGFydGlhbCgnbGluay10eXBlJywgJzxjb2RlPnt7dHlwZX19PC9jb2RlPicpO1xuICAgIH1cblxuICAgIHByaXZhdGUgZ2VuZXJhdGVDb21wb2RvY0h0bWwoZGF0YTogYW55KTogc3RyaW5nIHtcbiAgICAgICAgY29uc3QgY29tcG9uZW50ID0gZGF0YS5jb21wb25lbnQgfHwge307XG4gICAgICAgIGNvbnN0IG5hdlRhYnMgPSBkYXRhLm5hdlRhYnMgfHwgW107XG5cbiAgICAgICAgLy8gR2VuZXJhdGUgbmF2aWdhdGlvbiB0YWJzXG4gICAgICAgIGNvbnN0IHRhYnNIdG1sID0gbmF2VGFicy5tYXAoKHRhYiwgaW5kZXgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGlzQWN0aXZlID0gaW5kZXggPT09IDA7XG4gICAgICAgICAgICBjb25zdCBhY3RpdmVDbGFzcyA9IGlzQWN0aXZlID8gJ25hdi1saW5rIGFjdGl2ZScgOiAnbmF2LWxpbmsnO1xuICAgICAgICAgICAgY29uc3QgbGFiZWxNYXAgPSB7XG4gICAgICAgICAgICAgICAgJ2luZm8nOiAnSW5mbycsXG4gICAgICAgICAgICAgICAgJ3JlYWRtZSc6ICdSZWFkbWUnLFxuICAgICAgICAgICAgICAgICdzb3VyY2UnOiAnU291cmNlJyxcbiAgICAgICAgICAgICAgICAndGVtcGxhdGUnOiAnVGVtcGxhdGUnLFxuICAgICAgICAgICAgICAgICdzdHlsZXMnOiAnU3R5bGVzJyxcbiAgICAgICAgICAgICAgICAnZG9tLXRyZWUnOiAnRE9NIFRyZWUnXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgY29uc3QgbGFiZWwgPSBsYWJlbE1hcFt0YWIubGFiZWxdIHx8IHRhYi5sYWJlbDtcblxuICAgICAgICAgICAgcmV0dXJuIGAgICAgICAgIDxsaSBjbGFzcz1cIm5hdi1pdGVtXCI+XG4gICAgICAgICAgICA8YSBocmVmPVwiJHt0YWIuaHJlZn1cIiBjbGFzcz1cIiR7YWN0aXZlQ2xhc3N9XCIgcm9sZT1cInRhYlwiIGlkPVwiJHt0YWIuaWR9LXRhYlwiIGRhdGEtYnMtdG9nZ2xlPVwidGFiXCIgZGF0YS1saW5rPVwiJHt0YWJbJ2RhdGEtbGluayddfVwiPiR7bGFiZWx9PC9hPlxuICAgICAgICA8L2xpPmA7XG4gICAgICAgIH0pLmpvaW4oJ1xcbicpO1xuXG4gICAgICAgIC8vIEdlbmVyYXRlIHRhYiBjb250ZW50XG4gICAgICAgIGxldCB0YWJDb250ZW50SHRtbCA9ICcnO1xuXG4gICAgICAgIC8vIEluZm8gdGFiXG4gICAgICAgIGlmIChuYXZUYWJzLnNvbWUodGFiID0+IHRhYi5pZCA9PT0gJ2luZm8nKSkge1xuICAgICAgICAgICAgY29uc3QgaXNBY3RpdmUgPSBuYXZUYWJzWzBdLmlkID09PSAnaW5mbyc7XG4gICAgICAgICAgICBjb25zdCBhY3RpdmVDbGFzcyA9IGlzQWN0aXZlID8gJ2FjdGl2ZSBpbicgOiAnJztcblxuICAgICAgICAgICAgdGFiQ29udGVudEh0bWwgKz0gYCAgICA8ZGl2IGNsYXNzPVwidGFiLXBhbmUgZmFkZSAke2FjdGl2ZUNsYXNzfVwiIGlkPVwiaW5mb1wiPlxuICAgICAgICA8cCBjbGFzcz1cImNvbW1lbnRcIj5cbiAgICAgICAgICAgIDxoMz5GaWxlPC9oMz5cbiAgICAgICAgPC9wPlxuICAgICAgICA8cCBjbGFzcz1cImNvbW1lbnRcIj5cbiAgICAgICAgICAgIDxjb2RlPiR7Y29tcG9uZW50LmZpbGUgfHwgJyd9PC9jb2RlPlxuICAgICAgICA8L3A+XG5cbiAgICAgICAgJHtjb21wb25lbnQuZGVzY3JpcHRpb24gPyBgXG4gICAgICAgIDxwIGNsYXNzPVwiY29tbWVudFwiPlxuICAgICAgICAgICAgPGgzPkRlc2NyaXB0aW9uPC9oMz5cbiAgICAgICAgPC9wPlxuICAgICAgICA8cCBjbGFzcz1cImNvbW1lbnRcIj5cbiAgICAgICAgICAgIDxwPiR7Y29tcG9uZW50LmRlc2NyaXB0aW9uLnJlcGxhY2UoL1xcbi9nLCAnPC9wPlxcbjxwPicpfTwvcD5cbiAgICAgICAgPC9wPlxuICAgICAgICBgIDogJyd9XG5cbiAgICAgICAgJHtjb21wb25lbnQuaW1wbGVtZW50cyAmJiBjb21wb25lbnQuaW1wbGVtZW50cy5sZW5ndGggPiAwID8gYFxuICAgICAgICA8cCBjbGFzcz1cImNvbW1lbnRcIj5cbiAgICAgICAgICAgIDxoMz5JbXBsZW1lbnRzPC9oMz5cbiAgICAgICAgPC9wPlxuICAgICAgICA8cCBjbGFzcz1cImNvbW1lbnRcIj5cbiAgICAgICAgICAgICR7Y29tcG9uZW50LmltcGxlbWVudHMubWFwKGltcGwgPT4gYDxjb2RlPiR7aW1wbH08L2NvZGU+YCkuam9pbignLCAnKX1cbiAgICAgICAgPC9wPlxuICAgICAgICBgIDogJyd9XG5cbiAgICAgICAgPHNlY3Rpb24gZGF0YS1jb21wb2RvYz1cImJsb2NrLW1ldGFkYXRhXCI+XG4gICAgICAgICAgICA8aDM+TWV0YWRhdGE8L2gzPlxuICAgICAgICAgICAgPHRhYmxlIGNsYXNzPVwidGFibGUgdGFibGUtc20gdGFibGUtaG92ZXIgbWV0YWRhdGFcIj5cbiAgICAgICAgICAgICAgICA8dGJvZHk+XG4gICAgICAgICAgICAgICAgICAgICR7Y29tcG9uZW50LnNlbGVjdG9yID8gYFxuICAgICAgICAgICAgICAgICAgICA8dHI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8dGQgY2xhc3M9XCJjb2wtbWQtM1wiPnNlbGVjdG9yPC90ZD5cbiAgICAgICAgICAgICAgICAgICAgICAgIDx0ZCBjbGFzcz1cImNvbC1tZC05XCI+PGNvZGU+JHtjb21wb25lbnQuc2VsZWN0b3J9PC9jb2RlPjwvdGQ+XG4gICAgICAgICAgICAgICAgICAgIDwvdHI+YCA6ICcnfVxuICAgICAgICAgICAgICAgICAgICAke2NvbXBvbmVudC50ZW1wbGF0ZVVybCA/IGBcbiAgICAgICAgICAgICAgICAgICAgPHRyPlxuICAgICAgICAgICAgICAgICAgICAgICAgPHRkIGNsYXNzPVwiY29sLW1kLTNcIj50ZW1wbGF0ZVVybDwvdGQ+XG4gICAgICAgICAgICAgICAgICAgICAgICA8dGQgY2xhc3M9XCJjb2wtbWQtOVwiPjxjb2RlPiR7Y29tcG9uZW50LnRlbXBsYXRlVXJsfTwvY29kZT48L3RkPlxuICAgICAgICAgICAgICAgICAgICA8L3RyPmAgOiAnJ31cbiAgICAgICAgICAgICAgICAgICAgJHtjb21wb25lbnQuc3R5bGVVcmxzICYmIGNvbXBvbmVudC5zdHlsZVVybHMubGVuZ3RoID4gMCA/IGBcbiAgICAgICAgICAgICAgICAgICAgPHRyPlxuICAgICAgICAgICAgICAgICAgICAgICAgPHRkIGNsYXNzPVwiY29sLW1kLTNcIj5zdHlsZVVybHM8L3RkPlxuICAgICAgICAgICAgICAgICAgICAgICAgPHRkIGNsYXNzPVwiY29sLW1kLTlcIj48Y29kZT4ke2NvbXBvbmVudC5zdHlsZVVybHMuam9pbignLCAnKX08L2NvZGU+PC90ZD5cbiAgICAgICAgICAgICAgICAgICAgPC90cj5gIDogJyd9XG4gICAgICAgICAgICAgICAgPC90Ym9keT5cbiAgICAgICAgICAgIDwvdGFibGU+XG4gICAgICAgIDwvc2VjdGlvbj5cblxuICAgICAgICAke2NvbXBvbmVudC5tZXRob2RzICYmIGNvbXBvbmVudC5tZXRob2RzLmxlbmd0aCA+IDAgPyBgXG4gICAgICAgIDxzZWN0aW9uIGRhdGEtY29tcG9kb2M9XCJibG9jay1pbmRleFwiPlxuICAgICAgICAgICAgPGgzIGlkPVwiaW5kZXhcIj5JbmRleDwvaDM+XG4gICAgICAgICAgICA8dGFibGUgY2xhc3M9XCJ0YWJsZSB0YWJsZS1zbSB0YWJsZS1ib3JkZXJlZCBpbmRleC10YWJsZVwiPlxuICAgICAgICAgICAgICAgIDx0Ym9keT5cbiAgICAgICAgICAgICAgICAgICAgPHRyPlxuICAgICAgICAgICAgICAgICAgICAgICAgPHRkIGNsYXNzPVwiY29sLW1kLTRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aDY+PGI+TWV0aG9kczwvYj48L2g2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgICAgICAgICAgPC90cj5cbiAgICAgICAgICAgICAgICAgICAgPHRyPlxuICAgICAgICAgICAgICAgICAgICAgICAgPHRkIGNsYXNzPVwiY29sLW1kLTRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dWwgY2xhc3M9XCJpbmRleC1saXN0XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICR7Y29tcG9uZW50Lm1ldGhvZHMubWFwKG1ldGhvZCA9PiBgPGxpPjxhIGhyZWY9XCIjJHttZXRob2QubmFtZX1cIj4ke21ldGhvZC5uYW1lfTwvYT48L2xpPmApLmpvaW4oJ1xcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJyl9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC91bD5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICAgICAgICAgIDwvdHI+XG4gICAgICAgICAgICAgICAgPC90Ym9keT5cbiAgICAgICAgICAgIDwvdGFibGU+XG4gICAgICAgIDwvc2VjdGlvbj5cblxuICAgICAgICA8c2VjdGlvbiBkYXRhLWNvbXBvZG9jPVwiYmxvY2stbWV0aG9kc1wiPlxuICAgICAgICAgICAgPGgzIGlkPVwibWV0aG9kc1wiPk1ldGhvZHM8L2gzPlxuICAgICAgICAgICAgJHtjb21wb25lbnQubWV0aG9kcy5tYXAobWV0aG9kID0+IGBcbiAgICAgICAgICAgIDx0YWJsZSBjbGFzcz1cInRhYmxlIHRhYmxlLXNtIHRhYmxlLWJvcmRlcmVkXCI+XG4gICAgICAgICAgICAgICAgPHRib2R5PlxuICAgICAgICAgICAgICAgICAgICA8dHI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8dGQgY2xhc3M9XCJjb2wtbWQtNFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxhIG5hbWU9XCIke21ldGhvZC5uYW1lfVwiPjwvYT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cIm5hbWVcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4+PGI+JHttZXRob2QubmFtZX08L2I+PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8YSBocmVmPVwiIyR7bWV0aG9kLm5hbWV9XCI+PHNwYW4gY2xhc3M9XCJpY29uIGlvbi1pb3MtbGlua1wiPjwvc3Bhbj48L2E+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgICAgICAgICAgPC90cj5cbiAgICAgICAgICAgICAgICAgICAgPHRyPlxuICAgICAgICAgICAgICAgICAgICAgICAgPHRkIGNsYXNzPVwiY29sLW1kLTRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8Y29kZT4ke21ldGhvZC5uYW1lfSgpPC9jb2RlPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgICAgICAgICAgPC90cj5cbiAgICAgICAgICAgICAgICAgICAgJHttZXRob2QuZGVzY3JpcHRpb24gPyBgXG4gICAgICAgICAgICAgICAgICAgIDx0cj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDx0ZCBjbGFzcz1cImNvbC1tZC00XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImlvLWRlc2NyaXB0aW9uXCI+JHttZXRob2QuZGVzY3JpcHRpb259PC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImlvLWRlc2NyaXB0aW9uXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxiPlJldHVybnMgOiA8L2I+PGNvZGU+JHttZXRob2QudHlwZSB8fCAndm9pZCd9PC9jb2RlPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgICAgICAgICAgPC90cj5gIDogJyd9XG4gICAgICAgICAgICAgICAgPC90Ym9keT5cbiAgICAgICAgICAgIDwvdGFibGU+YCkuam9pbignXFxuICAgICAgICAgICAgJyl9XG4gICAgICAgIDwvc2VjdGlvbj5gIDogJyd9XG4gICAgPC9kaXY+XG5gO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gU291cmNlIHRhYlxuICAgICAgICBpZiAobmF2VGFicy5zb21lKHRhYiA9PiB0YWIuaWQgPT09ICdzb3VyY2UnKSkge1xuICAgICAgICAgICAgY29uc3QgaXNBY3RpdmUgPSBuYXZUYWJzWzBdLmlkID09PSAnc291cmNlJztcbiAgICAgICAgICAgIGNvbnN0IGFjdGl2ZUNsYXNzID0gaXNBY3RpdmUgPyAnYWN0aXZlIGluJyA6ICcnO1xuXG4gICAgICAgICAgICB0YWJDb250ZW50SHRtbCArPSBgICAgIDxkaXYgY2xhc3M9XCJ0YWItcGFuZSBmYWRlICR7YWN0aXZlQ2xhc3N9IHRhYi1zb3VyY2UtY29kZVwiIGlkPVwic291cmNlXCI+XG4gICAgICAgIDxwcmUgY2xhc3M9XCJsaW5lLW51bWJlcnMgY29tcG9kb2Mtc291cmNlY29kZVwiPjxjb2RlIGNsYXNzPVwibGFuZ3VhZ2UtdHlwZXNjcmlwdFwiPiR7Y29tcG9uZW50LnNvdXJjZUNvZGUgfHwgJyd9PC9jb2RlPjwvcHJlPlxuICAgIDwvZGl2PlxuYDtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIEdlbmVyYXRlIGNvbXBsZXRlIEhUTUxcbiAgICAgICAgcmV0dXJuIGA8b2wgY2xhc3M9XCJicmVhZGNydW1iXCI+XG4gIDxsaSBjbGFzcz1cImJyZWFkY3J1bWItaXRlbVwiPkNvbXBvbmVudHM8L2xpPlxuICA8bGkgY2xhc3M9XCJicmVhZGNydW1iLWl0ZW1cIj4ke2NvbXBvbmVudC5uYW1lIHx8ICcnfTwvbGk+XG48L29sPlxuXG48dWwgY2xhc3M9XCJuYXYgbmF2LXRhYnNcIiByb2xlPVwidGFibGlzdFwiPlxuJHt0YWJzSHRtbH1cbjwvdWw+XG5cbjxkaXYgY2xhc3M9XCJ0YWItY29udGVudFwiPlxuJHt0YWJDb250ZW50SHRtbH08L2Rpdj5gO1xuICAgIH1cblxuICAgIHByaXZhdGUgYXN5bmMgZG93bmxvYWRUZW1wbGF0ZVBhY2thZ2UocmVxOiBhbnksIHJlczogU2VydmVyUmVzcG9uc2UpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGNvbnN0IHsgdGVtcGxhdGVUeXBlLCB0ZW1wbGF0ZUNvbnRlbnQsIHRlbXBsYXRlRGF0YSB9ID0gcmVxLmJvZHk7XG5cbiAgICAgICAgICAgIGlmICghdGVtcGxhdGVUeXBlIHx8ICF0ZW1wbGF0ZUNvbnRlbnQpIHtcbiAgICAgICAgICAgICAgICBzZW5kKHJlcywgNDAwLCB7IGVycm9yOiAnVGVtcGxhdGUgdHlwZSBhbmQgY29udGVudCBhcmUgcmVxdWlyZWQnIH0pO1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gQ3JlYXRlIFJFQURNRSBjb250ZW50XG4gICAgICAgICAgICBjb25zdCByZWFkbWUgPSBgIyBDdXN0b20gQ29tcG9kb2MgVGVtcGxhdGVcblxuVGhpcyBwYWNrYWdlIGNvbnRhaW5zIHlvdXIgY3VzdG9taXplZCBDb21wb2RvYyB0ZW1wbGF0ZSBmb3I6ICoqJHt0ZW1wbGF0ZVR5cGV9KipcblxuIyMgRmlsZXMgSW5jbHVkZWRcblxuLSBcXGB0ZW1wbGF0ZXMvcGFydGlhbHMvJHt0ZW1wbGF0ZVR5cGV9Lmhic1xcYCAtIFlvdXIgbW9kaWZpZWQgdGVtcGxhdGVcbi0gXFxgZXhhbXBsZS1kYXRhLmpzb25cXGAgLSBTYW1wbGUgZGF0YSBzdHJ1Y3R1cmUgZm9yIHRlc3Rpbmdcbi0gXFxgUkVBRE1FLm1kXFxgIC0gVGhpcyBmaWxlXG5cbiMjIEhvdyB0byBVc2VcblxuIyMjIE9wdGlvbiAxOiBSZXBsYWNlIGluIGV4aXN0aW5nIENvbXBvZG9jIGluc3RhbGxhdGlvblxuXG4xLiBCYWNrdXAgeW91ciBvcmlnaW5hbCB0ZW1wbGF0ZSBmaWxlICh1c3VhbGx5IGluIFxcYG5vZGVfbW9kdWxlcy9AY29tcG9kb2MvY29tcG9kb2MvZGlzdC90ZW1wbGF0ZXMvcGFydGlhbHMvJHt0ZW1wbGF0ZVR5cGV9Lmhic1xcYClcbjIuIFJlcGxhY2UgaXQgd2l0aCB0aGUgcHJvdmlkZWQgXFxgJHt0ZW1wbGF0ZVR5cGV9Lmhic1xcYCBmaWxlXG4zLiBSZWdlbmVyYXRlIHlvdXIgZG9jdW1lbnRhdGlvbiB3aXRoIENvbXBvZG9jXG5cbiMjIyBPcHRpb24gMjogVXNlIHdpdGggY3VzdG9tIHRlbXBsYXRlIGRpcmVjdG9yeVxuXG4xLiBDcmVhdGUgYSBjdXN0b20gdGVtcGxhdGVzIGRpcmVjdG9yeSBpbiB5b3VyIHByb2plY3Q6XG4gICBcXGBcXGBcXGBcbiAgIG1rZGlyIC1wIGN1c3RvbS10ZW1wbGF0ZXMvcGFydGlhbHNcbiAgIFxcYFxcYFxcYFxuXG4yLiBDb3B5IHRoZSBcXGAke3RlbXBsYXRlVHlwZX0uaGJzXFxgIGZpbGUgdG86XG4gICBcXGBcXGBcXGBcbiAgIGN1c3RvbS10ZW1wbGF0ZXMvcGFydGlhbHMvJHt0ZW1wbGF0ZVR5cGV9Lmhic1xuICAgXFxgXFxgXFxgXG5cbjMuIFJ1biBDb21wb2RvYyB3aXRoIHRoZSBjdXN0b20gdGVtcGxhdGUgZGlyZWN0b3J5OlxuICAgXFxgXFxgXFxgXG4gICBjb21wb2RvYyAtcCB0c2NvbmZpZy5qc29uIC1kIGRvY3VtZW50YXRpb24gLS1jdXN0b21UZW1wbGF0ZSBjdXN0b20tdGVtcGxhdGVzXG4gICBcXGBcXGBcXGBcblxuIyMgVGVtcGxhdGUgVmFyaWFibGVzXG5cblRoZSB0ZW1wbGF0ZSBoYXMgYWNjZXNzIHRvIHRoZXNlIG1haW4gdmFyaWFibGVzOlxuXG4tIFxcYGNvbXBvbmVudFxcYCAtIENvbXBvbmVudCBpbmZvcm1hdGlvbiAobmFtZSwgZGVzY3JpcHRpb24sIGlucHV0cywgb3V0cHV0cywgZXRjLilcbi0gXFxgbmF2VGFic1xcYCAtIE5hdmlnYXRpb24gdGFicyBjb25maWd1cmF0aW9uXG4tIFxcYGRlcHRoXFxgIC0gQ3VycmVudCBwYWdlIGRlcHRoIGZvciByZWxhdGl2ZSBVUkxzXG4tIFxcYHRcXGAgLSBUcmFuc2xhdGlvbiBoZWxwZXIgZnVuY3Rpb25cblxuRm9yIGEgY29tcGxldGUgbGlzdCBvZiBhdmFpbGFibGUgdmFyaWFibGVzLCBzZWUgdGhlIFxcYGV4YW1wbGUtZGF0YS5qc29uXFxgIGZpbGUuXG5cbiMjIE5lZWQgSGVscD9cblxuLSBDb21wb2RvYyBEb2N1bWVudGF0aW9uOiBodHRwczovL2NvbXBvZG9jLmFwcC9cbi0gR2l0SHViIElzc3VlczogaHR0cHM6Ly9naXRodWIuY29tL2NvbXBvZG9jL2NvbXBvZG9jL2lzc3Vlc1xuXG5HZW5lcmF0ZWQgYnkgQ29tcG9kb2MgVGVtcGxhdGUgUGxheWdyb3VuZCBvbiAke25ldyBEYXRlKCkudG9Mb2NhbGVTdHJpbmcoKX1cbmA7XG5cbiAgICAgICAgICAgIC8vIENyZWF0ZSBleGFtcGxlIGRhdGFcbiAgICAgICAgICAgIGNvbnN0IGV4YW1wbGVEYXRhID0ge1xuICAgICAgICAgICAgICAgIHRlbXBsYXRlOiB0ZW1wbGF0ZVR5cGUsXG4gICAgICAgICAgICAgICAgZGVzY3JpcHRpb246ICdUaGlzIGlzIHNhbXBsZSBkYXRhIHRoYXQgbWF0Y2hlcyB0aGUgc3RydWN0dXJlIHVzZWQgaW4gQ29tcG9kb2MgdGVtcGxhdGVzJyxcbiAgICAgICAgICAgICAgICBkYXRhOiB0ZW1wbGF0ZURhdGEgfHwge31cbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIC8vIENyZWF0ZSBaSVAgc3RydWN0dXJlIGFzIEpTT04gKHRvIGJlIHByb2Nlc3NlZCBieSBmcm9udGVuZClcbiAgICAgICAgICAgIGNvbnN0IHppcFN0cnVjdHVyZSA9IHtcbiAgICAgICAgICAgICAgICBbYHRlbXBsYXRlcy9wYXJ0aWFscy8ke3RlbXBsYXRlVHlwZX0uaGJzYF06IHRlbXBsYXRlQ29udGVudCxcbiAgICAgICAgICAgICAgICAnUkVBRE1FLm1kJzogcmVhZG1lLFxuICAgICAgICAgICAgICAgICdleGFtcGxlLWRhdGEuanNvbic6IEpTT04uc3RyaW5naWZ5KGV4YW1wbGVEYXRhLCBudWxsLCAyKVxuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgc2VuZChyZXMsIDIwMCwge1xuICAgICAgICAgICAgICAgIHN1Y2Nlc3M6IHRydWUsXG4gICAgICAgICAgICAgICAgZmlsZW5hbWU6IGBjb21wb2RvYy0ke3RlbXBsYXRlVHlwZX0tdGVtcGxhdGUuemlwYCxcbiAgICAgICAgICAgICAgICBmaWxlczogemlwU3RydWN0dXJlXG4gICAgICAgICAgICB9KTtcblxuICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgbG9nZ2VyLmVycm9yKCdFcnJvciBjcmVhdGluZyB0ZW1wbGF0ZSBwYWNrYWdlOicsIGVycm9yKTtcbiAgICAgICAgICAgIHNlbmQocmVzLCA1MDAsIHtcbiAgICAgICAgICAgICAgICBlcnJvcjogJ0ZhaWxlZCB0byBjcmVhdGUgdGVtcGxhdGUgcGFja2FnZScsXG4gICAgICAgICAgICAgICAgZGV0YWlsczogZXJyb3IubWVzc2FnZVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIGFzeW5jIGRvd25sb2FkU2Vzc2lvblRlbXBsYXRlWmlwKHJlcTogYW55LCByZXM6IFNlcnZlclJlc3BvbnNlKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjb25zdCB7IHNlc3Npb25JZCB9ID0gcmVxLnBhcmFtcztcbiAgICAgICAgICAgIGNvbnN0IHsgdGVtcGxhdGVQYXRoLCB0ZW1wbGF0ZUNvbnRlbnQgfSA9IHJlcS5ib2R5O1xuXG4gICAgICAgICAgICBpZiAoIXRlbXBsYXRlUGF0aCB8fCAhdGVtcGxhdGVDb250ZW50KSB7XG4gICAgICAgICAgICAgICAgc2VuZChyZXMsIDQwMCwgeyBlcnJvcjogJ1RlbXBsYXRlIHBhdGggYW5kIGNvbnRlbnQgYXJlIHJlcXVpcmVkJyB9KTtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbnN0IHNlc3Npb24gPSB0aGlzLnNlc3Npb25zLmdldChzZXNzaW9uSWQpO1xuICAgICAgICAgICAgaWYgKCFzZXNzaW9uKSB7XG4gICAgICAgICAgICAgICAgc2VuZChyZXMsIDQwNCwgeyBzdWNjZXNzOiBmYWxzZSwgbWVzc2FnZTogJ1Nlc3Npb24gbm90IGZvdW5kJyB9KTtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHRoaXMudXBkYXRlU2Vzc2lvbkFjdGl2aXR5KHNlc3Npb25JZCk7XG5cbiAgICAgICAgICAgIC8vIEV4dHJhY3QgdGVtcGxhdGUgbmFtZSBmcm9tIHBhdGhcbiAgICAgICAgICAgIGNvbnN0IHRlbXBsYXRlTmFtZSA9IHBhdGguYmFzZW5hbWUodGVtcGxhdGVQYXRoLCAnLmhicycpO1xuICAgICAgICAgICAgY29uc3QgZmlsZU5hbWUgPSBgY29tcG9kb2MtJHt0ZW1wbGF0ZU5hbWV9LXRlbXBsYXRlLnppcGA7XG5cbiAgICAgICAgICAgIC8vIFNldCByZXNwb25zZSBoZWFkZXJzIGZvciBmaWxlIGRvd25sb2FkXG4gICAgICAgICAgICByZXMuc2V0SGVhZGVyKCdDb250ZW50LVR5cGUnLCAnYXBwbGljYXRpb24vemlwJyk7XG4gICAgICAgICAgICByZXMuc2V0SGVhZGVyKCdDb250ZW50LURpc3Bvc2l0aW9uJywgYGF0dGFjaG1lbnQ7IGZpbGVuYW1lPVwiJHtmaWxlTmFtZX1cImApO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBDcmVhdGUgWklQIGFyY2hpdmUgYW5kIGhhbmRsZSBpdCB3aXRoIHByb3BlciBwcm9taXNlXG4gICAgICAgICAgICBhd2FpdCBuZXcgUHJvbWlzZTx2b2lkPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgYXJjaGl2ZSA9IGFyY2hpdmVyKCd6aXAnLCB7XG4gICAgICAgICAgICAgICAgICAgIHpsaWI6IHsgbGV2ZWw6IDkgfSAvLyBNYXhpbXVtIGNvbXByZXNzaW9uXG4gICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgICAvLyBIYW5kbGUgYXJjaGl2ZSBldmVudHNcbiAgICAgICAgICAgICAgICBhcmNoaXZlLm9uKCdlcnJvcicsIChlcnIpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgbG9nZ2VyLmVycm9yKCdBcmNoaXZlIGVycm9yOicsIGVycik7XG4gICAgICAgICAgICAgICAgICAgIHJlamVjdChuZXcgRXJyb3IoYEZhaWxlZCB0byBjcmVhdGUgWklQIGZpbGU6ICR7ZXJyLm1lc3NhZ2V9YCkpO1xuICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICAgYXJjaGl2ZS5vbignZW5kJywgKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBsb2dnZXIuaW5mbyhg4pyFIFRlbXBsYXRlIFpJUCBjcmVhdGVkIHN1Y2Nlc3NmdWxseSBmb3Igc2Vzc2lvbiAke3Nlc3Npb25JZH06ICR7ZmlsZU5hbWV9YCk7XG4gICAgICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICAgIC8vIFBpcGUgYXJjaGl2ZSB0byByZXNwb25zZVxuICAgICAgICAgICAgICAgIGFyY2hpdmUucGlwZShyZXMpO1xuXG4gICAgICAgICAgICAgICAgLy8gQWRkIHRlbXBsYXRlIGZpbGUgdG8gWklQXG4gICAgICAgICAgICAgICAgYXJjaGl2ZS5hcHBlbmQodGVtcGxhdGVDb250ZW50LCB7IG5hbWU6IGB0ZW1wbGF0ZXMvcGFydGlhbHMvJHt0ZW1wbGF0ZU5hbWV9Lmhic2AgfSk7XG5cbiAgICAgICAgICAgICAgICAvLyBDcmVhdGUgUkVBRE1FIGNvbnRlbnRcbiAgICAgICAgICAgICAgICBjb25zdCByZWFkbWUgPSBgIyBDdXN0b20gQ29tcG9kb2MgVGVtcGxhdGVcblxuVGhpcyBwYWNrYWdlIGNvbnRhaW5zIHlvdXIgY3VzdG9taXplZCBDb21wb2RvYyB0ZW1wbGF0ZSBmb3I6ICoqJHt0ZW1wbGF0ZU5hbWV9KipcblxuIyMgRmlsZXMgSW5jbHVkZWRcblxuLSBcXGB0ZW1wbGF0ZXMvcGFydGlhbHMvJHt0ZW1wbGF0ZU5hbWV9Lmhic1xcYCAtIFlvdXIgbW9kaWZpZWQgdGVtcGxhdGVcbi0gXFxgZXhhbXBsZS1kYXRhLmpzb25cXGAgLSBTYW1wbGUgZGF0YSBzdHJ1Y3R1cmUgZm9yIHRlc3Rpbmdcbi0gXFxgUkVBRE1FLm1kXFxgIC0gVGhpcyBmaWxlXG5cbiMjIEhvdyB0byBVc2VcblxuIyMjIE9wdGlvbiAxOiBSZXBsYWNlIGluIGV4aXN0aW5nIENvbXBvZG9jIGluc3RhbGxhdGlvblxuXG4xLiBCYWNrdXAgeW91ciBvcmlnaW5hbCB0ZW1wbGF0ZSBmaWxlICh1c3VhbGx5IGluIFxcYG5vZGVfbW9kdWxlcy9AY29tcG9kb2MvY29tcG9kb2MvZGlzdC90ZW1wbGF0ZXMvcGFydGlhbHMvJHt0ZW1wbGF0ZU5hbWV9Lmhic1xcYClcbjIuIFJlcGxhY2UgaXQgd2l0aCB0aGUgcHJvdmlkZWQgXFxgJHt0ZW1wbGF0ZU5hbWV9Lmhic1xcYCBmaWxlXG4zLiBSZWdlbmVyYXRlIHlvdXIgZG9jdW1lbnRhdGlvbiB3aXRoIENvbXBvZG9jXG5cbiMjIyBPcHRpb24gMjogVXNlIHdpdGggY3VzdG9tIHRlbXBsYXRlIGRpcmVjdG9yeVxuXG4xLiBDcmVhdGUgYSBjdXN0b20gdGVtcGxhdGVzIGRpcmVjdG9yeSBpbiB5b3VyIHByb2plY3Q6XG4gICBcXGBcXGBcXGBcbiAgIG1rZGlyIC1wIGN1c3RvbS10ZW1wbGF0ZXMvcGFydGlhbHNcbiAgIFxcYFxcYFxcYFxuXG4yLiBDb3B5IHRoZSBcXGAke3RlbXBsYXRlTmFtZX0uaGJzXFxgIGZpbGUgdG86XG4gICBcXGBcXGBcXGBcbiAgIGN1c3RvbS10ZW1wbGF0ZXMvcGFydGlhbHMvJHt0ZW1wbGF0ZU5hbWV9Lmhic1xuICAgXFxgXFxgXFxgXG5cbjMuIFJ1biBDb21wb2RvYyB3aXRoIHRoZSBjdXN0b20gdGVtcGxhdGUgZGlyZWN0b3J5OlxuICAgXFxgXFxgXFxgXG4gICBjb21wb2RvYyAtcCB0c2NvbmZpZy5qc29uIC1kIGRvY3VtZW50YXRpb24gLS1jdXN0b21UZW1wbGF0ZSBjdXN0b20tdGVtcGxhdGVzXG4gICBcXGBcXGBcXGBcblxuIyMgVGVtcGxhdGUgVmFyaWFibGVzXG5cblRoZSB0ZW1wbGF0ZSBoYXMgYWNjZXNzIHRvIHRoZXNlIG1haW4gdmFyaWFibGVzOlxuXG4tIFxcYGNvbXBvbmVudFxcYCAtIENvbXBvbmVudCBpbmZvcm1hdGlvbiAobmFtZSwgZGVzY3JpcHRpb24sIGlucHV0cywgb3V0cHV0cywgZXRjLilcbi0gXFxgbmF2VGFic1xcYCAtIE5hdmlnYXRpb24gdGFicyBjb25maWd1cmF0aW9uXG4tIFxcYGRlcHRoXFxgIC0gQ3VycmVudCBwYWdlIGRlcHRoIGZvciByZWxhdGl2ZSBVUkxzXG4tIFxcYHRcXGAgLSBUcmFuc2xhdGlvbiBoZWxwZXIgZnVuY3Rpb25cblxuRm9yIGEgY29tcGxldGUgbGlzdCBvZiBhdmFpbGFibGUgdmFyaWFibGVzLCBzZWUgdGhlIFxcYGV4YW1wbGUtZGF0YS5qc29uXFxgIGZpbGUuXG5cbiMjIE5lZWQgSGVscD9cblxuLSBDb21wb2RvYyBEb2N1bWVudGF0aW9uOiBodHRwczovL2NvbXBvZG9jLmFwcC9cbi0gR2l0SHViIElzc3VlczogaHR0cHM6Ly9naXRodWIuY29tL2NvbXBvZG9jL2NvbXBvZG9jL2lzc3Vlc1xuXG5HZW5lcmF0ZWQgYnkgQ29tcG9kb2MgVGVtcGxhdGUgUGxheWdyb3VuZCBvbiAke25ldyBEYXRlKCkudG9Mb2NhbGVTdHJpbmcoKX1cbmA7XG5cbiAgICAgICAgICAgICAgICAvLyBBZGQgUkVBRE1FIHRvIFpJUFxuICAgICAgICAgICAgICAgIGFyY2hpdmUuYXBwZW5kKHJlYWRtZSwgeyBuYW1lOiAnUkVBRE1FLm1kJyB9KTtcblxuICAgICAgICAgICAgICAgIC8vIFRyeSB0byBnZXQgdGVtcGxhdGUgZGF0YSBmb3IgdGhlIGN1cnJlbnQgc2Vzc2lvbiBhbmQgdGVtcGxhdGVcbiAgICAgICAgICAgICAgICB0aGlzLmdldFNlc3Npb25UZW1wbGF0ZURhdGFJbnRlcm5hbChzZXNzaW9uSWQsIHRlbXBsYXRlUGF0aClcbiAgICAgICAgICAgICAgICAgICAgLnRoZW4odGVtcGxhdGVEYXRhUmVzcG9uc2UgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZXhhbXBsZURhdGEgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGVtcGxhdGU6IHRlbXBsYXRlTmFtZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbjogJ1RoaXMgaXMgc2FtcGxlIGRhdGEgdGhhdCBtYXRjaGVzIHRoZSBzdHJ1Y3R1cmUgdXNlZCBpbiBDb21wb2RvYyB0ZW1wbGF0ZXMnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGE6IHRlbXBsYXRlRGF0YVJlc3BvbnNlIHx8IHt9XG4gICAgICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICAgICAgYXJjaGl2ZS5hcHBlbmQoSlNPTi5zdHJpbmdpZnkoZXhhbXBsZURhdGEsIG51bGwsIDIpLCB7IG5hbWU6ICdleGFtcGxlLWRhdGEuanNvbicgfSk7XG4gICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICAgIC5jYXRjaChkYXRhRXJyb3IgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgbG9nZ2VyLndhcm4oJ0NvdWxkIG5vdCBnZXQgdGVtcGxhdGUgZGF0YSwgdXNpbmcgYmFzaWMgc3RydWN0dXJlOicsIGRhdGFFcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBiYXNpY0RhdGEgPSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGVtcGxhdGU6IHRlbXBsYXRlTmFtZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbjogJ1RoaXMgaXMgc2FtcGxlIGRhdGEgdGhhdCBtYXRjaGVzIHRoZSBzdHJ1Y3R1cmUgdXNlZCBpbiBDb21wb2RvYyB0ZW1wbGF0ZXMnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGE6IHsgbm90ZTogJ1RlbXBsYXRlIGRhdGEgY291bGQgbm90IGJlIGxvYWRlZCcgfVxuICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGFyY2hpdmUuYXBwZW5kKEpTT04uc3RyaW5naWZ5KGJhc2ljRGF0YSwgbnVsbCwgMiksIHsgbmFtZTogJ2V4YW1wbGUtZGF0YS5qc29uJyB9KTtcbiAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgLmZpbmFsbHkoKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gRmluYWxpemUgdGhlIGFyY2hpdmUgYWZ0ZXIgYWRkaW5nIGFsbCBmaWxlc1xuICAgICAgICAgICAgICAgICAgICAgICAgYXJjaGl2ZS5maW5hbGl6ZSgpO1xuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICBsb2dnZXIuZXJyb3IoJ0Vycm9yIGNyZWF0aW5nIHNlc3Npb24gdGVtcGxhdGUgWklQOicsIGVycm9yKTtcbiAgICAgICAgICAgIGlmICghcmVzLmhlYWRlcnNTZW50KSB7XG4gICAgICAgICAgICAgICAgc2VuZChyZXMsIDUwMCwge1xuICAgICAgICAgICAgICAgICAgICBlcnJvcjogJ0ZhaWxlZCB0byBjcmVhdGUgdGVtcGxhdGUgWklQJyxcbiAgICAgICAgICAgICAgICAgICAgZGV0YWlsczogZXJyb3IubWVzc2FnZVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBhc3luYyBkb3dubG9hZEFsbFNlc3Npb25UZW1wbGF0ZXMocmVxOiBhbnksIHJlczogU2VydmVyUmVzcG9uc2UpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGNvbnN0IHsgc2Vzc2lvbklkIH0gPSByZXEucGFyYW1zO1xuXG4gICAgICAgICAgICBjb25zdCBzZXNzaW9uID0gdGhpcy5zZXNzaW9ucy5nZXQoc2Vzc2lvbklkKTtcbiAgICAgICAgICAgIGlmICghc2Vzc2lvbikge1xuICAgICAgICAgICAgICAgIHNlbmQocmVzLCA0MDQsIHsgc3VjY2VzczogZmFsc2UsIG1lc3NhZ2U6ICdTZXNzaW9uIG5vdCBmb3VuZCcgfSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0aGlzLnVwZGF0ZVNlc3Npb25BY3Rpdml0eShzZXNzaW9uSWQpO1xuXG4gICAgICAgICAgICBjb25zdCBmaWxlTmFtZSA9IGBjb21wb2RvYy10ZW1wbGF0ZXMtJHtzZXNzaW9uSWR9LnppcGA7XG5cbiAgICAgICAgICAgIC8vIENyZWF0ZSBaSVAgYXJjaGl2ZSBpbiBtZW1vcnkgZm9yIHN1cGVydGVzdCBjb21wYXRpYmlsaXR5XG4gICAgICAgICAgICBjb25zdCB6aXBCdWZmZXIgPSBhd2FpdCBuZXcgUHJvbWlzZTxCdWZmZXI+KChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBhcmNoaXZlID0gYXJjaGl2ZXIoJ3ppcCcsIHtcbiAgICAgICAgICAgICAgICAgICAgemxpYjogeyBsZXZlbDogOSB9IC8vIE1heGltdW0gY29tcHJlc3Npb25cbiAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICAgIGNvbnN0IGNodW5rczogQnVmZmVyW10gPSBbXTtcblxuICAgICAgICAgICAgICAgIC8vIEhhbmRsZSBhcmNoaXZlIGV2ZW50c1xuICAgICAgICAgICAgICAgIGFyY2hpdmUub24oJ2Vycm9yJywgKGVycikgPT4ge1xuICAgICAgICAgICAgICAgICAgICBsb2dnZXIuZXJyb3IoJ0FyY2hpdmUgZXJyb3I6JywgZXJyKTtcbiAgICAgICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBFcnJvcihgRmFpbGVkIHRvIGNyZWF0ZSBaSVAgZmlsZTogJHtlcnIubWVzc2FnZX1gKSk7XG4gICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgICBhcmNoaXZlLm9uKCdkYXRhJywgKGNodW5rKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGNodW5rcy5wdXNoKGNodW5rKTtcbiAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICAgIGFyY2hpdmUub24oJ2VuZCcsICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgbG9nZ2VyLmluZm8oYOKchSBBbGwgdGVtcGxhdGVzIFpJUCBjcmVhdGVkIHN1Y2Nlc3NmdWxseSBmb3Igc2Vzc2lvbiAke3Nlc3Npb25JZH06ICR7ZmlsZU5hbWV9YCk7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGJ1ZmZlciA9IEJ1ZmZlci5jb25jYXQoY2h1bmtzKTtcbiAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZShidWZmZXIpO1xuICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICAgLy8gQWRkIGFsbCBmaWxlcyBmcm9tIHRoZSBzZXNzaW9uJ3MgdGVtcGxhdGUgZGlyZWN0b3J5XG4gICAgICAgICAgICAgICAgLy8gVGhpcyBtYWludGFpbnMgdGhlIHNhbWUgc3RydWN0dXJlIGFzIGhicy10ZW1wbGF0ZXMtY29weS08aGFzaD5cbiAgICAgICAgICAgICAgICBhcmNoaXZlLmRpcmVjdG9yeShzZXNzaW9uLnRlbXBsYXRlRGlyLCBmYWxzZSk7XG5cbiAgICAgICAgICAgICAgICAvLyBDcmVhdGUgYSBjb21wcmVoZW5zaXZlIFJFQURNRVxuICAgICAgICAgICAgICAgIGNvbnN0IHJlYWRtZSA9IGAjIENvbXBvZG9jIFRlbXBsYXRlIFBhY2thZ2VcblxuVGhpcyBwYWNrYWdlIGNvbnRhaW5zIGFsbCBjdXN0b21pemVkIENvbXBvZG9jIHRlbXBsYXRlcyBmb3Igc2Vzc2lvbjogKioke3Nlc3Npb25JZH0qKlxuXG4jIyBTdHJ1Y3R1cmVcblxuVGhpcyB0ZW1wbGF0ZSBwYWNrYWdlIGhhcyB0aGUgc2FtZSBzdHJ1Y3R1cmUgYXMgQ29tcG9kb2MncyBkZWZhdWx0IHRlbXBsYXRlczpcblxuLSBcXGBwYWdlLmhic1xcYCAtIE1haW4gcGFnZSB0ZW1wbGF0ZVxuLSBcXGBwYXJ0aWFscy9cXGAgLSBEaXJlY3RvcnkgY29udGFpbmluZyBhbGwgcGFydGlhbCB0ZW1wbGF0ZXM6XG4gIC0gQ29tcG9uZW50IHRlbXBsYXRlcyAoXFxgY29tcG9uZW50Lmhic1xcYCwgXFxgZGlyZWN0aXZlLmhic1xcYCwgZXRjLilcbiAgLSBCbG9jayB0ZW1wbGF0ZXMgKFxcYGJsb2NrLSouaGJzXFxgKVxuICAtIExheW91dCB0ZW1wbGF0ZXMgKFxcYG1lbnUuaGJzXFxgLCBcXGBpbmRleC5oYnNcXGAsIGV0Yy4pXG4gIC0gVXRpbGl0eSB0ZW1wbGF0ZXMgKFxcYHNlYXJjaC0qLmhic1xcYCwgXFxgY292ZXJhZ2UtKi5oYnNcXGAsIGV0Yy4pXG5cbiMjIEhvdyB0byBVc2VcblxuIyMjIE9wdGlvbiAxOiBSZXBsYWNlIGVudGlyZSB0ZW1wbGF0ZSBkaXJlY3RvcnlcblxuMS4gQmFja3VwIHlvdXIgb3JpZ2luYWwgdGVtcGxhdGVzIGRpcmVjdG9yeSAodXN1YWxseSBpbiBcXGBub2RlX21vZHVsZXMvQGNvbXBvZG9jL2NvbXBvZG9jL2Rpc3QvdGVtcGxhdGVzL1xcYClcbjIuIFJlcGxhY2UgaXQgd2l0aCB0aGUgY29udGVudHMgb2YgdGhpcyBaSVAgZmlsZVxuMy4gUmVnZW5lcmF0ZSB5b3VyIGRvY3VtZW50YXRpb24gd2l0aCBDb21wb2RvY1xuXG4jIyMgT3B0aW9uIDI6IFVzZSB3aXRoIGN1c3RvbSB0ZW1wbGF0ZSBkaXJlY3RvcnlcblxuMS4gRXh0cmFjdCB0aGlzIFpJUCB0byBhIGRpcmVjdG9yeSBpbiB5b3VyIHByb2plY3QgKGUuZy4sIFxcYGN1c3RvbS10ZW1wbGF0ZXMvXFxgKVxuMi4gUnVuIENvbXBvZG9jIHdpdGggdGhlIGN1c3RvbSB0ZW1wbGF0ZSBkaXJlY3Rvcnk6XG4gICBcXGBcXGBcXGBcbiAgIGNvbXBvZG9jIC1wIHRzY29uZmlnLmpzb24gLWQgZG9jdW1lbnRhdGlvbiAtLWN1c3RvbVRlbXBsYXRlIGN1c3RvbS10ZW1wbGF0ZXNcbiAgIFxcYFxcYFxcYFxuXG4jIyMgT3B0aW9uIDM6IFVzZSBzcGVjaWZpYyB0ZW1wbGF0ZXMgb25seVxuXG4xLiBFeHRyYWN0IG9ubHkgdGhlIHRlbXBsYXRlcyB5b3Ugd2FudCB0byBjdXN0b21pemVcbjIuIFBsYWNlIHRoZW0gaW4geW91ciBjdXN0b20gdGVtcGxhdGUgZGlyZWN0b3J5IG1haW50YWluaW5nIHRoZSBzYW1lIHN0cnVjdHVyZVxuMy4gQ29tcG9kb2Mgd2lsbCB1c2UgeW91ciBjdXN0b20gdGVtcGxhdGVzIGFuZCBmYWxsIGJhY2sgdG8gZGVmYXVsdHMgZm9yIG90aGVyc1xuXG4jIyBUZW1wbGF0ZSBWYXJpYWJsZXNcblxuVGVtcGxhdGVzIGhhdmUgYWNjZXNzIHRvIGNvbXByZWhlbnNpdmUgZGF0YSBzdHJ1Y3R1cmVzIGluY2x1ZGluZzpcblxuLSBDb21wb25lbnQvRGlyZWN0aXZlL1NlcnZpY2UgaW5mb3JtYXRpb25cbi0gTmF2aWdhdGlvbiBhbmQgcm91dGluZyBkYXRhXG4tIERvY3VtZW50YXRpb24gbWV0YWRhdGFcbi0gQ29uZmlndXJhdGlvbiBvcHRpb25zXG4tIEhlbHBlciBmdW5jdGlvbnMgZm9yIGZvcm1hdHRpbmcgYW5kIG5hdmlnYXRpb25cblxuIyMgTmVlZCBIZWxwP1xuXG4tIENvbXBvZG9jIERvY3VtZW50YXRpb246IGh0dHBzOi8vY29tcG9kb2MuYXBwL1xuLSBHaXRIdWIgSXNzdWVzOiBodHRwczovL2dpdGh1Yi5jb20vY29tcG9kb2MvY29tcG9kb2MvaXNzdWVzXG4tIFRlbXBsYXRlIERvY3VtZW50YXRpb246IGh0dHBzOi8vY29tcG9kb2MuYXBwL2d1aWRlcy90ZW1wbGF0ZXMuaHRtbFxuXG5HZW5lcmF0ZWQgYnkgQ29tcG9kb2MgVGVtcGxhdGUgUGxheWdyb3VuZCBvbiAke25ldyBEYXRlKCkudG9Mb2NhbGVTdHJpbmcoKX1cbmA7XG5cbiAgICAgICAgICAgICAgICAvLyBBZGQgUkVBRE1FIHRvIFpJUCByb290XG4gICAgICAgICAgICAgICAgYXJjaGl2ZS5hcHBlbmQocmVhZG1lLCB7IG5hbWU6ICdSRUFETUUubWQnIH0pO1xuXG4gICAgICAgICAgICAgICAgLy8gRmluYWxpemUgdGhlIGFyY2hpdmUgYWZ0ZXIgYWRkaW5nIGFsbCBmaWxlc1xuICAgICAgICAgICAgICAgIGFyY2hpdmUuZmluYWxpemUoKTtcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAvLyBTZXQgaGVhZGVycyBhbmQgc2VuZCBidWZmZXIgcmVzcG9uc2UgZm9yIHN1cGVydGVzdCBjb21wYXRpYmlsaXR5XG4gICAgICAgICAgICByZXMuc2V0SGVhZGVyKCdDb250ZW50LVR5cGUnLCAnYXBwbGljYXRpb24vemlwJyk7XG4gICAgICAgICAgICByZXMuc2V0SGVhZGVyKCdDb250ZW50LURpc3Bvc2l0aW9uJywgYGF0dGFjaG1lbnQ7IGZpbGVuYW1lPVwiJHtmaWxlTmFtZX1cImApO1xuICAgICAgICAgICAgcmVzLnNldEhlYWRlcignQ29udGVudC1MZW5ndGgnLCB6aXBCdWZmZXIubGVuZ3RoLnRvU3RyaW5nKCkpO1xuICAgICAgICAgICAgXG4gICAgICAgICAgICAvLyBGb3IgdGVzdGluZywgYWxzbyBhZGQgYSBjdXN0b20gaGVhZGVyIHdpdGggdGhlIHNpemVcbiAgICAgICAgICAgIHJlcy5zZXRIZWFkZXIoJ1gtQ29udGVudC1TaXplJywgemlwQnVmZmVyLmxlbmd0aC50b1N0cmluZygpKTtcbiAgICAgICAgICAgIFxuICAgICAgICAgICAgcmVzLmVuZCh6aXBCdWZmZXIsICdiaW5hcnknKTtcblxuICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgbG9nZ2VyLmVycm9yKCdFcnJvciBjcmVhdGluZyBhbGwgdGVtcGxhdGVzIFpJUDonLCBlcnJvcik7XG4gICAgICAgICAgICBpZiAoIXJlcy5oZWFkZXJzU2VudCkge1xuICAgICAgICAgICAgICAgIHNlbmQocmVzLCA1MDAsIHtcbiAgICAgICAgICAgICAgICAgICAgZXJyb3I6ICdGYWlsZWQgdG8gY3JlYXRlIGFsbCB0ZW1wbGF0ZXMgWklQJyxcbiAgICAgICAgICAgICAgICAgICAgZGV0YWlsczogZXJyb3IubWVzc2FnZVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBhc3luYyBnZXRTZXNzaW9uVGVtcGxhdGVEYXRhSW50ZXJuYWwoc2Vzc2lvbklkOiBzdHJpbmcsIHRlbXBsYXRlUGF0aDogc3RyaW5nKTogUHJvbWlzZTxhbnk+IHtcbiAgICAgICAgLy8gSW50ZXJuYWwgbWV0aG9kIHRvIGdldCB0ZW1wbGF0ZSBkYXRhIHdpdGhvdXQgSFRUUCByZXF1ZXN0L3Jlc3BvbnNlXG4gICAgICAgIGlmICghdGhpcy5zZXNzaW9ucy5oYXMoc2Vzc2lvbklkKSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdTZXNzaW9uIG5vdCBmb3VuZCcpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy51cGRhdGVTZXNzaW9uQWN0aXZpdHkoc2Vzc2lvbklkKTtcblxuICAgICAgICBjb25zdCB0ZW1wbGF0ZU5hbWUgPSBwYXRoLmJhc2VuYW1lKHRlbXBsYXRlUGF0aCwgJy5oYnMnKTtcbiAgICAgICAgbGV0IGRhdGEgPSB7fTtcblxuICAgICAgICBpZiAodGVtcGxhdGVOYW1lLmluY2x1ZGVzKCdjb21wb25lbnQnKSkge1xuICAgICAgICAgICAgZGF0YSA9IHtcbiAgICAgICAgICAgICAgICBuYW1lOiAnRXhhbXBsZUNvbXBvbmVudCcsXG4gICAgICAgICAgICAgICAgZGVzY3JpcHRpb246ICdBIHNhbXBsZSBBbmd1bGFyIGNvbXBvbmVudCBmb3IgZGVtb25zdHJhdGlvbicsXG4gICAgICAgICAgICAgICAgZmlsZTogJ3NyYy9hcHAvZXhhbXBsZS5jb21wb25lbnQudHMnLFxuICAgICAgICAgICAgICAgIHNlbGVjdG9yOiAnYXBwLWV4YW1wbGUnLFxuICAgICAgICAgICAgICAgIHRlbXBsYXRlVXJsOiAnLi9leGFtcGxlLmNvbXBvbmVudC5odG1sJyxcbiAgICAgICAgICAgICAgICBzdHlsZVVybHM6IFsnLi9leGFtcGxlLmNvbXBvbmVudC5zY3NzJ10sXG4gICAgICAgICAgICAgICAgaW5wdXRzOiBbXG4gICAgICAgICAgICAgICAgICAgIHsgbmFtZTogJ3RpdGxlJywgdHlwZTogJ3N0cmluZycsIGRlc2NyaXB0aW9uOiAnQ29tcG9uZW50IHRpdGxlJyB9LFxuICAgICAgICAgICAgICAgICAgICB7IG5hbWU6ICdlbmFibGVkJywgdHlwZTogJ2Jvb2xlYW4nLCBkZXNjcmlwdGlvbjogJ1doZXRoZXIgY29tcG9uZW50IGlzIGVuYWJsZWQnIH1cbiAgICAgICAgICAgICAgICBdLFxuICAgICAgICAgICAgICAgIG91dHB1dHM6IFtcbiAgICAgICAgICAgICAgICAgICAgeyBuYW1lOiAnY2xpY2tlZCcsIHR5cGU6ICdFdmVudEVtaXR0ZXI8dm9pZD4nLCBkZXNjcmlwdGlvbjogJ0VtaXR0ZWQgd2hlbiBjbGlja2VkJyB9XG4gICAgICAgICAgICAgICAgXVxuICAgICAgICAgICAgfTtcbiAgICAgICAgfSBlbHNlIGlmICh0ZW1wbGF0ZU5hbWUuaW5jbHVkZXMoJ3NlcnZpY2UnKSB8fCB0ZW1wbGF0ZU5hbWUuaW5jbHVkZXMoJ2luamVjdGFibGUnKSkge1xuICAgICAgICAgICAgZGF0YSA9IHtcbiAgICAgICAgICAgICAgICBuYW1lOiAnRXhhbXBsZVNlcnZpY2UnLFxuICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uOiAnQSBzYW1wbGUgQW5ndWxhciBzZXJ2aWNlIGZvciBkZW1vbnN0cmF0aW9uJyxcbiAgICAgICAgICAgICAgICBmaWxlOiAnc3JjL2FwcC9leGFtcGxlLnNlcnZpY2UudHMnLFxuICAgICAgICAgICAgICAgIG1ldGhvZHM6IFtcbiAgICAgICAgICAgICAgICAgICAgeyBuYW1lOiAnZ2V0RGF0YScsIHJldHVyblR5cGU6ICdPYnNlcnZhYmxlPGFueT4nLCBkZXNjcmlwdGlvbjogJ0dldHMgZGF0YSBmcm9tIEFQSScgfSxcbiAgICAgICAgICAgICAgICAgICAgeyBuYW1lOiAnc2F2ZURhdGEnLCByZXR1cm5UeXBlOiAndm9pZCcsIGRlc2NyaXB0aW9uOiAnU2F2ZXMgZGF0YSB0byBzdG9yYWdlJyB9XG4gICAgICAgICAgICAgICAgXVxuICAgICAgICAgICAgfTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGRhdGEgPSB7XG4gICAgICAgICAgICAgICAgbmFtZTogYEV4YW1wbGUke3RlbXBsYXRlTmFtZS5jaGFyQXQoMCkudG9VcHBlckNhc2UoKSArIHRlbXBsYXRlTmFtZS5zbGljZSgxKX1gLFxuICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uOiBgQSBzYW1wbGUgJHt0ZW1wbGF0ZU5hbWV9IGZvciBkZW1vbnN0cmF0aW9uYCxcbiAgICAgICAgICAgICAgICBmaWxlOiBgc3JjL2FwcC9leGFtcGxlLiR7dGVtcGxhdGVOYW1lfS50c2BcbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gZGF0YTtcbiAgICB9XG5cbiAgICAvLyBTZXNzaW9uIG1hbmFnZW1lbnQgQVBJIG1ldGhvZHNcbiAgICBwcml2YXRlIGFzeW5jIGNyZWF0ZVNlc3Npb25BUEkocmVxOiBhbnksIHJlczogU2VydmVyUmVzcG9uc2UpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGNvbnN0IGNsaWVudElQID0gdGhpcy5nZXRDbGllbnRJUChyZXEpO1xuICAgICAgICAgICAgXG4gICAgICAgICAgICAvLyBJbiB0ZXN0IGVudmlyb25tZW50IG9yIGlmIGZvcmNlTmV3IHF1ZXJ5IHBhcmFtIGlzIHNldCwgYWx3YXlzIGNyZWF0ZSBuZXcgc2Vzc2lvblxuICAgICAgICAgICAgLy8gT3RoZXJ3aXNlIHJldXNlIHNlc3Npb24gYnkgSVAgZm9yIG5vcm1hbCB1c2FnZVxuICAgICAgICAgICAgY29uc3QgZm9yY2VOZXcgPSBwcm9jZXNzLmVudi5OT0RFX0VOViA9PT0gJ3Rlc3QnIHx8IHJlcS5xdWVyeS5mb3JjZU5ldyA9PT0gJ3RydWUnO1xuICAgICAgICAgICAgY29uc3Qgc2Vzc2lvbiA9IGZvcmNlTmV3ID8gdGhpcy5jcmVhdGVOZXdTZXNzaW9uKGNsaWVudElQKSA6IHRoaXMuY3JlYXRlT3JHZXRTZXNzaW9uQnlJUChjbGllbnRJUCk7XG4gICAgICAgICAgICBcbiAgICAgICAgICAgIHNlbmQocmVzLCAyMDAsIHtcbiAgICAgICAgICAgICAgICBzZXNzaW9uSWQ6IHNlc3Npb24uaWQsXG4gICAgICAgICAgICAgICAgc3VjY2VzczogdHJ1ZSxcbiAgICAgICAgICAgICAgICBtZXNzYWdlOiAnU2Vzc2lvbiBjcmVhdGVkIHN1Y2Nlc3NmdWxseScsXG4gICAgICAgICAgICAgICAgaXA6IGNsaWVudElQXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgIGxvZ2dlci5lcnJvcignRXJyb3IgY3JlYXRpbmcgc2Vzc2lvbjonLCBlcnJvcik7XG4gICAgICAgICAgICBzZW5kKHJlcywgNTAwLCB7XG4gICAgICAgICAgICAgICAgc3VjY2VzczogZmFsc2UsXG4gICAgICAgICAgICAgICAgbWVzc2FnZTogJ0ZhaWxlZCB0byBjcmVhdGUgc2Vzc2lvbicsXG4gICAgICAgICAgICAgICAgZXJyb3I6IGVycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvci5tZXNzYWdlIDogJ1Vua25vd24gZXJyb3InXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgYXN5bmMgZ2V0U2Vzc2lvblRlbXBsYXRlcyhyZXE6IGFueSwgcmVzOiBTZXJ2ZXJSZXNwb25zZSk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgY29uc3Qgc2Vzc2lvbklkID0gcmVxLnBhcmFtcy5zZXNzaW9uSWQ7XG4gICAgICAgICAgICBjb25zdCBzZXNzaW9uID0gdGhpcy5zZXNzaW9ucy5nZXQoc2Vzc2lvbklkKTtcblxuICAgICAgICAgICAgaWYgKCFzZXNzaW9uKSB7XG4gICAgICAgICAgICAgICAgc2VuZChyZXMsIDQwNCwgeyBzdWNjZXNzOiBmYWxzZSwgbWVzc2FnZTogJ1Nlc3Npb24gbm90IGZvdW5kJyB9KTtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHRoaXMudXBkYXRlU2Vzc2lvbkFjdGl2aXR5KHNlc3Npb25JZCk7XG5cbiAgICAgICAgICAgIGNvbnN0IHRlbXBsYXRlczogYW55W10gPSBbXTtcbiAgICAgICAgICAgIGNvbnN0IHBhcnRpYWxzRGlyID0gcGF0aC5qb2luKHNlc3Npb24udGVtcGxhdGVEaXIsICdwYXJ0aWFscycpO1xuXG4gICAgICAgICAgICAvLyBSZWFkIG1haW4gdGVtcGxhdGVcbiAgICAgICAgICAgIGNvbnN0IG1haW5UZW1wbGF0ZVBhdGggPSBwYXRoLmpvaW4oc2Vzc2lvbi50ZW1wbGF0ZURpciwgJ3BhZ2UuaGJzJyk7XG4gICAgICAgICAgICBpZiAoZnMuZXhpc3RzU3luYyhtYWluVGVtcGxhdGVQYXRoKSkge1xuICAgICAgICAgICAgICAgIHRlbXBsYXRlcy5wdXNoKHtcbiAgICAgICAgICAgICAgICAgICAgbmFtZTogJ3BhZ2UuaGJzJyxcbiAgICAgICAgICAgICAgICAgICAgcGF0aDogJ3BhZ2UuaGJzJyxcbiAgICAgICAgICAgICAgICAgICAgdHlwZTogJ3RlbXBsYXRlJ1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBSZWFkIHBhcnRpYWxzXG4gICAgICAgICAgICBpZiAoZnMuZXhpc3RzU3luYyhwYXJ0aWFsc0RpcikpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBwYXJ0aWFsRmlsZXMgPSBmcy5yZWFkZGlyU3luYyhwYXJ0aWFsc0RpcikuZmlsdGVyKGZpbGUgPT4gZmlsZS5lbmRzV2l0aCgnLmhicycpKTtcbiAgICAgICAgICAgICAgICBwYXJ0aWFsRmlsZXMuZm9yRWFjaChmaWxlID0+IHtcbiAgICAgICAgICAgICAgICAgICAgdGVtcGxhdGVzLnB1c2goe1xuICAgICAgICAgICAgICAgICAgICAgICAgbmFtZTogZmlsZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHBhdGg6IGBwYXJ0aWFscy8ke2ZpbGV9YCxcbiAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU6ICdwYXJ0aWFsJ1xuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgc2VuZChyZXMsIDIwMCwgeyB0ZW1wbGF0ZXMsIHN1Y2Nlc3M6IHRydWUgfSk7XG4gICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICBsb2dnZXIuZXJyb3IoJ0Vycm9yIGdldHRpbmcgc2Vzc2lvbiB0ZW1wbGF0ZXM6JywgZXJyb3IpO1xuICAgICAgICAgICAgc2VuZChyZXMsIDUwMCwge1xuICAgICAgICAgICAgICAgIHN1Y2Nlc3M6IGZhbHNlLFxuICAgICAgICAgICAgICAgIG1lc3NhZ2U6ICdGYWlsZWQgdG8gZ2V0IHRlbXBsYXRlcycsXG4gICAgICAgICAgICAgICAgZXJyb3I6IGVycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvci5tZXNzYWdlIDogJ1Vua25vd24gZXJyb3InXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgYXN5bmMgZ2V0U2Vzc2lvblRlbXBsYXRlKHJlcTogYW55LCByZXM6IFNlcnZlclJlc3BvbnNlKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjb25zdCB7IHNlc3Npb25JZCB9ID0gcmVxLnBhcmFtcztcbiAgICAgICAgICAgIFxuICAgICAgICAgICAgLy8gRXh0cmFjdCB0ZW1wbGF0ZSBuYW1lIGZyb20gVVJMIChtb3JlIHJlbGlhYmxlIHRoYW4gUG9sa2EncyB3aWxkY2FyZCBwYXJhbWV0ZXIgaGFuZGxpbmcpXG4gICAgICAgICAgICBsZXQgdGVtcGxhdGVOYW1lID0gcmVxLnBhcmFtc1tcIipcIl07XG4gICAgICAgICAgICBjb25zdCB1cmxQYXJ0cyA9IHJlcS51cmwuc3BsaXQoJy8nKTtcbiAgICAgICAgICAgIGNvbnN0IHRlbXBsYXRlSW5kZXggPSB1cmxQYXJ0cy5maW5kSW5kZXgocGFydCA9PiBwYXJ0ID09PSAndGVtcGxhdGUnKTtcbiAgICAgICAgICAgIGlmICh0ZW1wbGF0ZUluZGV4ICE9PSAtMSAmJiB0ZW1wbGF0ZUluZGV4IDwgdXJsUGFydHMubGVuZ3RoIC0gMSkge1xuICAgICAgICAgICAgICAgIC8vIEdldCBldmVyeXRoaW5nIGFmdGVyICd0ZW1wbGF0ZS8nIGluIHRoZSBVUkwgYW5kIGRlY29kZSBpdFxuICAgICAgICAgICAgICAgIHRlbXBsYXRlTmFtZSA9IGRlY29kZVVSSUNvbXBvbmVudCh1cmxQYXJ0cy5zbGljZSh0ZW1wbGF0ZUluZGV4ICsgMSkuam9pbignLycpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIFxuICAgICAgICAgICAgLy8gVGVtcGxhdGUgbmFtZSBleHRyYWN0ZWQgZnJvbSBVUkwgZm9yIHJlbGlhYmxlIHBhdGggaGFuZGxpbmdcbiAgICAgICAgICAgIFxuICAgICAgICAgICAgY29uc3Qgc2Vzc2lvbiA9IHRoaXMuc2Vzc2lvbnMuZ2V0KHNlc3Npb25JZCk7XG4gICAgICAgICAgICBcbiAgICAgICAgICAgIC8vIFJlbW92ZWQgZGVidWcgbG9nZ2luZyAtIHBhdGggZXh0cmFjdGlvbiBub3cgd29ya2luZyBjb3JyZWN0bHlcblxuICAgICAgICAgICAgaWYgKCFzZXNzaW9uKSB7XG4gICAgICAgICAgICAgICAgc2VuZChyZXMsIDQwNCwgeyBzdWNjZXNzOiBmYWxzZSwgbWVzc2FnZTogJ1Nlc3Npb24gbm90IGZvdW5kJyB9KTtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHRoaXMudXBkYXRlU2Vzc2lvbkFjdGl2aXR5KHNlc3Npb25JZCk7XG5cbiAgICAgICAgICAgIGNvbnN0IHRlbXBsYXRlUGF0aCA9IHBhdGguam9pbihzZXNzaW9uLnRlbXBsYXRlRGlyLCB0ZW1wbGF0ZU5hbWUpO1xuXG4gICAgICAgICAgICBpZiAoIWZzLmV4aXN0c1N5bmModGVtcGxhdGVQYXRoKSkge1xuICAgICAgICAgICAgICAgIHNlbmQocmVzLCA0MDQsIHsgc3VjY2VzczogZmFsc2UsIG1lc3NhZ2U6ICdUZW1wbGF0ZSBub3QgZm91bmQnIH0pO1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uc3QgY29udGVudCA9IGZzLnJlYWRGaWxlU3luYyh0ZW1wbGF0ZVBhdGgsICd1dGY4Jyk7XG4gICAgICAgICAgICBzZW5kKHJlcywgMjAwLCB7XG4gICAgICAgICAgICAgICAgY29udGVudCxcbiAgICAgICAgICAgICAgICBzdWNjZXNzOiB0cnVlLFxuICAgICAgICAgICAgICAgIHRlbXBsYXRlTmFtZSxcbiAgICAgICAgICAgICAgICBwYXRoOiB0ZW1wbGF0ZU5hbWVcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgbG9nZ2VyLmVycm9yKCdFcnJvciBnZXR0aW5nIHNlc3Npb24gdGVtcGxhdGU6JywgZXJyb3IpO1xuICAgICAgICAgICAgc2VuZChyZXMsIDUwMCwge1xuICAgICAgICAgICAgICAgIHN1Y2Nlc3M6IGZhbHNlLFxuICAgICAgICAgICAgICAgIG1lc3NhZ2U6ICdGYWlsZWQgdG8gZ2V0IHRlbXBsYXRlJyxcbiAgICAgICAgICAgICAgICBlcnJvcjogZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yLm1lc3NhZ2UgOiAnVW5rbm93biBlcnJvcidcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBhc3luYyBzYXZlU2Vzc2lvblRlbXBsYXRlKHJlcTogYW55LCByZXM6IFNlcnZlclJlc3BvbnNlKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjb25zdCB7IHNlc3Npb25JZCB9ID0gcmVxLnBhcmFtcztcbiAgICAgICAgICAgIFxuICAgICAgICAgICAgLy8gRXh0cmFjdCB0ZW1wbGF0ZSBuYW1lIGZyb20gVVJMIChtb3JlIHJlbGlhYmxlIHRoYW4gUG9sa2EncyB3aWxkY2FyZCBwYXJhbWV0ZXIgaGFuZGxpbmcpXG4gICAgICAgICAgICBsZXQgdGVtcGxhdGVOYW1lID0gcmVxLnBhcmFtc1tcIipcIl07XG4gICAgICAgICAgICBjb25zdCB1cmxQYXJ0cyA9IHJlcS51cmwuc3BsaXQoJy8nKTtcbiAgICAgICAgICAgIGNvbnN0IHRlbXBsYXRlSW5kZXggPSB1cmxQYXJ0cy5maW5kSW5kZXgocGFydCA9PiBwYXJ0ID09PSAndGVtcGxhdGUnKTtcbiAgICAgICAgICAgIGlmICh0ZW1wbGF0ZUluZGV4ICE9PSAtMSAmJiB0ZW1wbGF0ZUluZGV4IDwgdXJsUGFydHMubGVuZ3RoIC0gMSkge1xuICAgICAgICAgICAgICAgIC8vIEdldCBldmVyeXRoaW5nIGFmdGVyICd0ZW1wbGF0ZS8nIGluIHRoZSBVUkwgYW5kIGRlY29kZSBpdFxuICAgICAgICAgICAgICAgIHRlbXBsYXRlTmFtZSA9IGRlY29kZVVSSUNvbXBvbmVudCh1cmxQYXJ0cy5zbGljZSh0ZW1wbGF0ZUluZGV4ICsgMSkuam9pbignLycpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIFxuICAgICAgICAgICAgLy8gVGVtcGxhdGUgbmFtZSBleHRyYWN0ZWQgZnJvbSBVUkwgZm9yIHJlbGlhYmxlIHBhdGggaGFuZGxpbmdcbiAgICAgICAgICAgIFxuICAgICAgICAgICAgY29uc3QgeyBjb250ZW50IH0gPSByZXEuYm9keTtcbiAgICAgICAgICAgIFxuICAgICAgICAgICAgY29uc3Qgc2Vzc2lvbiA9IHRoaXMuc2Vzc2lvbnMuZ2V0KHNlc3Npb25JZCk7XG5cbiAgICAgICAgICAgIC8vIFZhbGlkYXRlIHJlcXVpcmVkIHBhcmFtZXRlcnNcbiAgICAgICAgICAgIGlmICghY29udGVudCB8fCB0eXBlb2YgY29udGVudCAhPT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgICAgICBzZW5kKHJlcywgNDAwLCB7IFxuICAgICAgICAgICAgICAgICAgICBzdWNjZXNzOiBmYWxzZSwgXG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2U6ICdDb250ZW50IGlzIHJlcXVpcmVkIGFuZCBtdXN0IGJlIGEgc3RyaW5nJyBcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmICghdGVtcGxhdGVOYW1lKSB7XG4gICAgICAgICAgICAgICAgc2VuZChyZXMsIDQwMCwgeyBcbiAgICAgICAgICAgICAgICAgICAgc3VjY2VzczogZmFsc2UsIFxuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlOiAnVGVtcGxhdGUgbmFtZSBpcyByZXF1aXJlZCcgXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoIXNlc3Npb24pIHtcbiAgICAgICAgICAgICAgICBzZW5kKHJlcywgNDA0LCB7IHN1Y2Nlc3M6IGZhbHNlLCBtZXNzYWdlOiAnU2Vzc2lvbiBub3QgZm91bmQnIH0pO1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGhpcy51cGRhdGVTZXNzaW9uQWN0aXZpdHkoc2Vzc2lvbklkKTtcblxuICAgICAgICAgICAgY29uc3QgdGVtcGxhdGVQYXRoID0gcGF0aC5qb2luKHNlc3Npb24udGVtcGxhdGVEaXIsIHRlbXBsYXRlTmFtZSk7XG5cbiAgICAgICAgICAgIC8vIEVuc3VyZSBkaXJlY3RvcnkgZXhpc3RzXG4gICAgICAgICAgICBmcy5lbnN1cmVEaXJTeW5jKHBhdGguZGlybmFtZSh0ZW1wbGF0ZVBhdGgpKTtcblxuICAgICAgICAgICAgLy8gU2F2ZSB0aGUgdGVtcGxhdGUgY29udGVudFxuICAgICAgICAgICAgZnMud3JpdGVGaWxlU3luYyh0ZW1wbGF0ZVBhdGgsIGNvbnRlbnQsICd1dGY4Jyk7XG5cbiAgICAgICAgICAgIC8vIFRyaWdnZXIgZGVib3VuY2VkIGRvY3VtZW50YXRpb24gcmVnZW5lcmF0aW9uXG4gICAgICAgICAgICB0aGlzLmdlbmVyYXRlRG9jdW1lbnRhdGlvbihzZXNzaW9uSWQsIHRydWUpO1xuXG4gICAgICAgICAgICBzZW5kKHJlcywgMjAwLCB7XG4gICAgICAgICAgICAgICAgc3VjY2VzczogdHJ1ZSxcbiAgICAgICAgICAgICAgICBtZXNzYWdlOiAnVGVtcGxhdGUgc2F2ZWQgc3VjY2Vzc2Z1bGx5JyxcbiAgICAgICAgICAgICAgICB0ZW1wbGF0ZU5hbWVcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgbG9nZ2VyLmVycm9yKCdFcnJvciBzYXZpbmcgc2Vzc2lvbiB0ZW1wbGF0ZTonLCBlcnJvcik7XG4gICAgICAgICAgICBzZW5kKHJlcywgNTAwLCB7XG4gICAgICAgICAgICAgICAgc3VjY2VzczogZmFsc2UsXG4gICAgICAgICAgICAgICAgbWVzc2FnZTogJ0ZhaWxlZCB0byBzYXZlIHRlbXBsYXRlJyxcbiAgICAgICAgICAgICAgICBlcnJvcjogZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yLm1lc3NhZ2UgOiAnVW5rbm93biBlcnJvcidcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBhc3luYyBnZXRTZXNzaW9uVGVtcGxhdGVEYXRhKHJlcTogYW55LCByZXM6IFNlcnZlclJlc3BvbnNlKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjb25zdCB7IHNlc3Npb25JZCB9ID0gcmVxLnBhcmFtcztcbiAgICAgICAgICAgIGxldCB0ZW1wbGF0ZVBhdGggPSByZXEucGFyYW1zW1wiKlwiXTtcbiAgICAgICAgICAgIFxuICAgICAgICAgICAgLy8gRkFMTEJBQ0s6IElmIFBvbGthIGRvZXNuJ3QgY2FwdHVyZSB0aGUgZnVsbCBwYXRoLCBleHRyYWN0IGl0IGZyb20gdGhlIFVSTFxuICAgICAgICAgICAgaWYgKCF0ZW1wbGF0ZVBhdGggfHwgIXRlbXBsYXRlUGF0aC5pbmNsdWRlcygnLycpKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgdXJsUGFydHMgPSByZXEudXJsLnNwbGl0KCcvJyk7XG4gICAgICAgICAgICAgICAgY29uc3QgdGVtcGxhdGVJbmRleCA9IHVybFBhcnRzLmZpbmRJbmRleChwYXJ0ID0+IHBhcnQgPT09ICd0ZW1wbGF0ZS1kYXRhJyk7XG4gICAgICAgICAgICAgICAgaWYgKHRlbXBsYXRlSW5kZXggIT09IC0xICYmIHRlbXBsYXRlSW5kZXggPCB1cmxQYXJ0cy5sZW5ndGggLSAxKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIEdldCBldmVyeXRoaW5nIGFmdGVyICd0ZW1wbGF0ZS1kYXRhLycgaW4gdGhlIFVSTCBhbmQgZGVjb2RlIGl0XG4gICAgICAgICAgICAgICAgICAgIHRlbXBsYXRlUGF0aCA9IGRlY29kZVVSSUNvbXBvbmVudCh1cmxQYXJ0cy5zbGljZSh0ZW1wbGF0ZUluZGV4ICsgMSkuam9pbignLycpKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmICghdGhpcy5zZXNzaW9ucy5oYXMoc2Vzc2lvbklkKSkge1xuICAgICAgICAgICAgICAgIHNlbmQocmVzLCA0MDQsIHtcbiAgICAgICAgICAgICAgICAgICAgc3VjY2VzczogZmFsc2UsXG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2U6ICdTZXNzaW9uIG5vdCBmb3VuZCdcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHRoaXMudXBkYXRlU2Vzc2lvbkFjdGl2aXR5KHNlc3Npb25JZCk7XG4gICAgICAgICAgICBjb25zdCBzZXNzaW9uID0gdGhpcy5zZXNzaW9ucy5nZXQoc2Vzc2lvbklkKTtcblxuICAgICAgICAgICAgLy8gR2V0IGV4YW1wbGUgZGF0YSBmb3IgdGhlIHRlbXBsYXRlIHR5cGVcbiAgICAgICAgICAgIGNvbnN0IHRlbXBsYXRlTmFtZSA9IHBhdGguYmFzZW5hbWUodGVtcGxhdGVQYXRoLCAnLmhicycpO1xuXG4gICAgICAgICAgICAvLyAqKkNPTVBPRE9DIENPTkZJR1VSQVRJT04gT1BUSU9OUyoqXG4gICAgICAgICAgICAvLyBSZXR1cm4gb25seSBhY3R1YWwgQ29tcG9kb2MgY29uZmlndXJhdGlvbiBvcHRpb25zIHRoYXQgY2FuIGJlIGVkaXRlZFxuICAgICAgICAgICAgY29uc3QgY29tcG9kb2NDb25maWcgPSB7XG4gICAgICAgICAgICAgICAgLy8gRG9jdW1lbnRhdGlvbiBNZXRhZGF0YVxuICAgICAgICAgICAgICAgIG5hbWU6IHNlc3Npb24/LmNvbmZpZz8ubmFtZSB8fCAnQXBwbGljYXRpb24gZG9jdW1lbnRhdGlvbicsXG5cbiAgICAgICAgICAgICAgICAvLyBQYXRocyBhbmQgT3V0cHV0XG4gICAgICAgICAgICAgICAgb3V0cHV0OiBzZXNzaW9uPy5jb25maWc/Lm91dHB1dCB8fCAnLi9kb2N1bWVudGF0aW9uLycsXG4gICAgICAgICAgICAgICAgdGhlbWU6IHNlc3Npb24/LmNvbmZpZz8udGhlbWUgfHwgJ2dpdGJvb2snLFxuICAgICAgICAgICAgICAgIGxhbmd1YWdlOiBzZXNzaW9uPy5jb25maWc/Lmxhbmd1YWdlIHx8ICdlbi1VUycsXG4gICAgICAgICAgICAgICAgYmFzZTogc2Vzc2lvbj8uY29uZmlnPy5iYXNlIHx8ICcvJyxcblxuICAgICAgICAgICAgICAgIC8vIEFzc2V0cyBhbmQgQ3VzdG9tIFVJXG4gICAgICAgICAgICAgICAgY3VzdG9tRmF2aWNvbjogc2Vzc2lvbj8uY29uZmlnPy5jdXN0b21GYXZpY29uIHx8ICcnLFxuICAgICAgICAgICAgICAgIGN1c3RvbUxvZ286IHNlc3Npb24/LmNvbmZpZz8uY3VzdG9tTG9nbyB8fCAnJyxcbiAgICAgICAgICAgICAgICBhc3NldHNGb2xkZXI6IHNlc3Npb24/LmNvbmZpZz8uYXNzZXRzRm9sZGVyIHx8ICcnLFxuICAgICAgICAgICAgICAgIGV4dFRoZW1lOiBzZXNzaW9uPy5jb25maWc/LmV4dFRoZW1lIHx8ICcnLFxuXG4gICAgICAgICAgICAgICAgLy8gRmVhdHVyZSBUb2dnbGVzIC0gRGlzYWJsZSBPcHRpb25zXG4gICAgICAgICAgICAgICAgZGlzYWJsZVNvdXJjZUNvZGU6IHNlc3Npb24/LmNvbmZpZz8uZGlzYWJsZVNvdXJjZUNvZGUgfHwgZmFsc2UsXG4gICAgICAgICAgICAgICAgZGlzYWJsZUdyYXBoOiBzZXNzaW9uPy5jb25maWc/LmRpc2FibGVHcmFwaCB8fCBmYWxzZSxcbiAgICAgICAgICAgICAgICBkaXNhYmxlQ292ZXJhZ2U6IHNlc3Npb24/LmNvbmZpZz8uZGlzYWJsZUNvdmVyYWdlIHx8IGZhbHNlLFxuICAgICAgICAgICAgICAgIGRpc2FibGVQcml2YXRlOiBzZXNzaW9uPy5jb25maWc/LmRpc2FibGVQcml2YXRlIHx8IGZhbHNlLFxuICAgICAgICAgICAgICAgIGRpc2FibGVQcm90ZWN0ZWQ6IHNlc3Npb24/LmNvbmZpZz8uZGlzYWJsZVByb3RlY3RlZCB8fCBmYWxzZSxcbiAgICAgICAgICAgICAgICBkaXNhYmxlSW50ZXJuYWw6IHNlc3Npb24/LmNvbmZpZz8uZGlzYWJsZUludGVybmFsIHx8IGZhbHNlLFxuICAgICAgICAgICAgICAgIGRpc2FibGVMaWZlQ3ljbGVIb29rczogc2Vzc2lvbj8uY29uZmlnPy5kaXNhYmxlTGlmZUN5Y2xlSG9va3MgfHwgZmFsc2UsXG4gICAgICAgICAgICAgICAgZGlzYWJsZUNvbnN0cnVjdG9yczogc2Vzc2lvbj8uY29uZmlnPy5kaXNhYmxlQ29uc3RydWN0b3JzIHx8IGZhbHNlLFxuICAgICAgICAgICAgICAgIGRpc2FibGVSb3V0ZXNHcmFwaDogc2Vzc2lvbj8uY29uZmlnPy5kaXNhYmxlUm91dGVzR3JhcGggfHwgZmFsc2UsXG4gICAgICAgICAgICAgICAgZGlzYWJsZVNlYXJjaDogc2Vzc2lvbj8uY29uZmlnPy5kaXNhYmxlU2VhcmNoIHx8IGZhbHNlLFxuICAgICAgICAgICAgICAgIGRpc2FibGVEZXBlbmRlbmNpZXM6IHNlc3Npb24/LmNvbmZpZz8uZGlzYWJsZURlcGVuZGVuY2llcyB8fCBmYWxzZSxcbiAgICAgICAgICAgICAgICBkaXNhYmxlUHJvcGVydGllczogc2Vzc2lvbj8uY29uZmlnPy5kaXNhYmxlUHJvcGVydGllcyB8fCBmYWxzZSxcbiAgICAgICAgICAgICAgICBkaXNhYmxlRG9tVHJlZTogc2Vzc2lvbj8uY29uZmlnPy5kaXNhYmxlRG9tVHJlZSB8fCBmYWxzZSxcbiAgICAgICAgICAgICAgICBkaXNhYmxlVGVtcGxhdGVUYWI6IHNlc3Npb24/LmNvbmZpZz8uZGlzYWJsZVRlbXBsYXRlVGFiIHx8IGZhbHNlLFxuICAgICAgICAgICAgICAgIGRpc2FibGVTdHlsZVRhYjogc2Vzc2lvbj8uY29uZmlnPy5kaXNhYmxlU3R5bGVUYWIgfHwgZmFsc2UsXG4gICAgICAgICAgICAgICAgZGlzYWJsZU1haW5HcmFwaDogc2Vzc2lvbj8uY29uZmlnPy5kaXNhYmxlTWFpbkdyYXBoIHx8IGZhbHNlLFxuICAgICAgICAgICAgICAgIGRpc2FibGVGaWxlUGF0aDogc2Vzc2lvbj8uY29uZmlnPy5kaXNhYmxlRmlsZVBhdGggfHwgZmFsc2UsXG4gICAgICAgICAgICAgICAgZGlzYWJsZU92ZXJ2aWV3OiBzZXNzaW9uPy5jb25maWc/LmRpc2FibGVPdmVydmlldyB8fCBmYWxzZSxcblxuICAgICAgICAgICAgICAgIC8vIFVJIE9wdGlvbnNcbiAgICAgICAgICAgICAgICBoaWRlR2VuZXJhdG9yOiBzZXNzaW9uPy5jb25maWc/LmhpZGVHZW5lcmF0b3IgfHwgZmFsc2UsXG4gICAgICAgICAgICAgICAgaGlkZURhcmtNb2RlVG9nZ2xlOiBzZXNzaW9uPy5jb25maWc/LmhpZGVEYXJrTW9kZVRvZ2dsZSB8fCBmYWxzZSxcbiAgICAgICAgICAgICAgICBtaW5pbWFsOiBzZXNzaW9uPy5jb25maWc/Lm1pbmltYWwgfHwgZmFsc2UsXG5cbiAgICAgICAgICAgICAgICAvLyBBZGRpdGlvbmFsIENvbnRlbnRcbiAgICAgICAgICAgICAgICBpbmNsdWRlczogc2Vzc2lvbj8uY29uZmlnPy5pbmNsdWRlcyB8fCAnJyxcbiAgICAgICAgICAgICAgICBpbmNsdWRlc05hbWU6IHNlc3Npb24/LmNvbmZpZz8uaW5jbHVkZXNOYW1lIHx8ICdBZGRpdGlvbmFsIGRvY3VtZW50YXRpb24nLFxuXG4gICAgICAgICAgICAgICAgLy8gU2VydmluZyBPcHRpb25zXG4gICAgICAgICAgICAgICAgcG9ydDogc2Vzc2lvbj8uY29uZmlnPy5wb3J0IHx8IDgwODAsXG4gICAgICAgICAgICAgICAgaG9zdG5hbWU6IHNlc3Npb24/LmNvbmZpZz8uaG9zdG5hbWUgfHwgJzEyNy4wLjAuMScsXG4gICAgICAgICAgICAgICAgc2VydmU6IHNlc3Npb24/LmNvbmZpZz8uc2VydmUgfHwgZmFsc2UsXG4gICAgICAgICAgICAgICAgb3Blbjogc2Vzc2lvbj8uY29uZmlnPy5vcGVuIHx8IGZhbHNlLFxuICAgICAgICAgICAgICAgIHdhdGNoOiBzZXNzaW9uPy5jb25maWc/LndhdGNoIHx8IGZhbHNlLFxuXG4gICAgICAgICAgICAgICAgLy8gRXhwb3J0IE9wdGlvbnNcbiAgICAgICAgICAgICAgICBleHBvcnRGb3JtYXQ6IHNlc3Npb24/LmNvbmZpZz8uZXhwb3J0Rm9ybWF0IHx8ICdodG1sJyxcblxuICAgICAgICAgICAgICAgIC8vIENvdmVyYWdlIE9wdGlvbnNcbiAgICAgICAgICAgICAgICBjb3ZlcmFnZVRlc3Q6IHNlc3Npb24/LmNvbmZpZz8uY292ZXJhZ2VUZXN0IHx8IGZhbHNlLFxuICAgICAgICAgICAgICAgIGNvdmVyYWdlVGVzdFRocmVzaG9sZDogc2Vzc2lvbj8uY29uZmlnPy5jb3ZlcmFnZVRlc3RUaHJlc2hvbGQgfHwgNzAsXG4gICAgICAgICAgICAgICAgY292ZXJhZ2VNaW5pbXVtUGVyRmlsZTogc2Vzc2lvbj8uY29uZmlnPy5jb3ZlcmFnZU1pbmltdW1QZXJGaWxlIHx8IDAsXG4gICAgICAgICAgICAgICAgY292ZXJhZ2VUZXN0VGhyZXNob2xkRmFpbDogc2Vzc2lvbj8uY29uZmlnPy5jb3ZlcmFnZVRlc3RUaHJlc2hvbGRGYWlsIHx8IHRydWUsXG4gICAgICAgICAgICAgICAgY292ZXJhZ2VUZXN0U2hvd09ubHlGYWlsZWQ6IHNlc3Npb24/LmNvbmZpZz8uY292ZXJhZ2VUZXN0U2hvd09ubHlGYWlsZWQgfHwgZmFsc2UsXG4gICAgICAgICAgICAgICAgdW5pdFRlc3RDb3ZlcmFnZTogc2Vzc2lvbj8uY29uZmlnPy51bml0VGVzdENvdmVyYWdlIHx8ICcnLFxuXG4gICAgICAgICAgICAgICAgLy8gR29vZ2xlIEFuYWx5dGljc1xuICAgICAgICAgICAgICAgIGdhSUQ6IHNlc3Npb24/LmNvbmZpZz8uZ2FJRCB8fCAnJyxcbiAgICAgICAgICAgICAgICBnYVNpdGU6IHNlc3Npb24/LmNvbmZpZz8uZ2FTaXRlIHx8ICdhdXRvJyxcblxuICAgICAgICAgICAgICAgIC8vIEFkdmFuY2VkIE9wdGlvbnNcbiAgICAgICAgICAgICAgICBzaWxlbnQ6IHNlc3Npb24/LmNvbmZpZz8uc2lsZW50IHx8IGZhbHNlLFxuICAgICAgICAgICAgICAgIG1heFNlYXJjaFJlc3VsdHM6IHNlc3Npb24/LmNvbmZpZz8ubWF4U2VhcmNoUmVzdWx0cyB8fCAxNSxcblxuICAgICAgICAgICAgICAgIC8vIE1lbnUgQ29uZmlndXJhdGlvbiAoYXMgSlNPTiBzdHJpbmcgZm9yIGVkaXRpbmcpXG4gICAgICAgICAgICAgICAgdG9nZ2xlTWVudUl0ZW1zOiBKU09OLnN0cmluZ2lmeShzZXNzaW9uPy5jb25maWc/LnRvZ2dsZU1lbnVJdGVtcyB8fCBbJ2FsbCddKSxcbiAgICAgICAgICAgICAgICBuYXZUYWJDb25maWc6IEpTT04uc3RyaW5naWZ5KHNlc3Npb24/LmNvbmZpZz8ubmF2VGFiQ29uZmlnIHx8IFtdKVxuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgLy8gUmV0dXJuIG9ubHkgdGhlIENvbXBvZG9jIGNvbmZpZ3VyYXRpb24gLSBubyB0ZW1wbGF0ZSB2YXJpYWJsZXNcbiAgICAgICAgICAgIGNvbnN0IHJlc3BvbnNlRGF0YSA9IGNvbXBvZG9jQ29uZmlnO1xuICAgICAgICAgICAgbGV0IGFkZGl0aW9uYWxDb250ZXh0OiBhbnkgPSB7fTtcbiAgICAgICAgICAgIGxldCB0ZW1wbGF0ZVZhcmlhYmxlczogYW55O1xuXG4gICAgICAgICAgICAvLyBEZXRlcm1pbmUgdGVtcGxhdGUgdHlwZSBhbmQgcHJvdmlkZSBjb21wcmVoZW5zaXZlIHJlYWxpc3RpYyBkYXRhXG4gICAgICAgICAgICBpZiAodGVtcGxhdGVOYW1lLmluY2x1ZGVzKCdjb21wb25lbnQnKSkge1xuICAgICAgICAgICAgICAgIHRlbXBsYXRlVmFyaWFibGVzID0ge1xuICAgICAgICAgICAgICAgICAgICAvLyBDb3JlIGNvbXBvbmVudCBkYXRhXG4gICAgICAgICAgICAgICAgICAgIG5hbWU6ICdVc2VyUHJvZmlsZUNvbXBvbmVudCcsXG4gICAgICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uOiAnQSBjb21wcmVoZW5zaXZlIHVzZXIgcHJvZmlsZSBtYW5hZ2VtZW50IGNvbXBvbmVudCB0aGF0IGhhbmRsZXMgdXNlciBpbmZvcm1hdGlvbiBkaXNwbGF5IGFuZCBlZGl0aW5nIGNhcGFiaWxpdGllcy4nLFxuICAgICAgICAgICAgICAgICAgICBmaWxlOiAnc3JjL2FwcC9jb21wb25lbnRzL3VzZXItcHJvZmlsZS91c2VyLXByb2ZpbGUuY29tcG9uZW50LnRzJyxcbiAgICAgICAgICAgICAgICAgICAgc2VsZWN0b3I6ICdhcHAtdXNlci1wcm9maWxlJyxcbiAgICAgICAgICAgICAgICAgICAgdGVtcGxhdGVVcmw6ICcuL3VzZXItcHJvZmlsZS5jb21wb25lbnQuaHRtbCcsXG4gICAgICAgICAgICAgICAgICAgIHN0eWxlVXJsczogWycuL3VzZXItcHJvZmlsZS5jb21wb25lbnQuc2NzcycsICcuL3VzZXItcHJvZmlsZS50aGVtZS5zY3NzJ10sXG4gICAgICAgICAgICAgICAgICAgIGVuY2Fwc3VsYXRpb246ICdWaWV3RW5jYXBzdWxhdGlvbi5FbXVsYXRlZCcsXG4gICAgICAgICAgICAgICAgICAgIGNoYW5nZURldGVjdGlvbjogJ0NoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCcsXG5cbiAgICAgICAgICAgICAgICAgICAgLy8gQ29tcG9uZW50IG1ldGFkYXRhXG4gICAgICAgICAgICAgICAgICAgIHR5cGU6ICdjb21wb25lbnQnLFxuICAgICAgICAgICAgICAgICAgICBzb3VyY2VDb2RlOiAnZXhwb3J0IGNsYXNzIFVzZXJQcm9maWxlQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0LCBPbkRlc3Ryb3kgeyAuLi4gfScsXG4gICAgICAgICAgICAgICAgICAgIHJhd0ZpbGU6ICd1c2VyLXByb2ZpbGUuY29tcG9uZW50LnRzJyxcblxuICAgICAgICAgICAgICAgICAgICAvLyBUZW1wbGF0ZSBhbmQgc3R5bGVzXG4gICAgICAgICAgICAgICAgICAgIHRlbXBsYXRlRGF0YTogJzxkaXYgY2xhc3M9XCJ1c2VyLXByb2ZpbGVcIj5cXFxcbiAgPGgyPnt7dXNlci5uYW1lfX08L2gyPlxcXFxuICA8cD57e3VzZXIuZW1haWx9fTwvcD5cXFxcbjwvZGl2PicsXG4gICAgICAgICAgICAgICAgICAgIHN0eWxlVXJsc0RhdGE6IFtcbiAgICAgICAgICAgICAgICAgICAgICAgICcudXNlci1wcm9maWxlIHsgcGFkZGluZzogMjBweDsgfVxcXFxuLnVzZXItcHJvZmlsZSBoMiB7IGNvbG9yOiAjMzMzOyB9J1xuICAgICAgICAgICAgICAgICAgICBdLFxuICAgICAgICAgICAgICAgICAgICBzdHlsZXNEYXRhOiBbXG4gICAgICAgICAgICAgICAgICAgICAgICAnOmhvc3QgeyBkaXNwbGF5OiBibG9jazsgbWFyZ2luOiAxMHB4OyB9J1xuICAgICAgICAgICAgICAgICAgICBdLFxuXG4gICAgICAgICAgICAgICAgICAgIC8vIElucHV0cyBhbmQgT3V0cHV0c1xuICAgICAgICAgICAgICAgICAgICBpbnB1dHM6IFtcbiAgICAgICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lOiAndXNlcicsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZTogJ1VzZXInLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uOiAnVGhlIHVzZXIgb2JqZWN0IGNvbnRhaW5pbmcgcHJvZmlsZSBpbmZvcm1hdGlvbicsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVjb3JhdG9yczogWydASW5wdXQoKSddLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbmFsOiBmYWxzZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWZhdWx0VmFsdWU6IG51bGxcbiAgICAgICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZTogJ2VkaXRhYmxlJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlOiAnYm9vbGVhbicsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVzY3JpcHRpb246ICdXaGV0aGVyIHRoZSBwcm9maWxlIGNhbiBiZSBlZGl0ZWQnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlY29yYXRvcnM6IFsnQElucHV0KCknXSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcHRpb25hbDogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWZhdWx0VmFsdWU6ICdmYWxzZSdcbiAgICAgICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZTogJ3Nob3dBdmF0YXInLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU6ICdib29sZWFuJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbjogJ0NvbnRyb2xzIGF2YXRhciB2aXNpYmlsaXR5JyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWNvcmF0b3JzOiBbJ0BJbnB1dCgpJ10sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgb3B0aW9uYWw6IHRydWUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVmYXVsdFZhbHVlOiAndHJ1ZSdcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgXSxcbiAgICAgICAgICAgICAgICAgICAgb3V0cHV0czogW1xuICAgICAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWU6ICd1c2VyVXBkYXRlZCcsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZTogJ0V2ZW50RW1pdHRlcjxVc2VyPicsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVzY3JpcHRpb246ICdFbWl0dGVkIHdoZW4gdXNlciBwcm9maWxlIGlzIHVwZGF0ZWQnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlY29yYXRvcnM6IFsnQE91dHB1dCgpJ11cbiAgICAgICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZTogJ2F2YXRhckNsaWNrZWQnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU6ICdFdmVudEVtaXR0ZXI8TW91c2VFdmVudD4nLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uOiAnRW1pdHRlZCB3aGVuIHVzZXIgY2xpY2tzIG9uIGF2YXRhcicsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVjb3JhdG9yczogWydAT3V0cHV0KCknXVxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBdLFxuXG4gICAgICAgICAgICAgICAgICAgIC8vIE1ldGhvZHNcbiAgICAgICAgICAgICAgICAgICAgbWV0aG9kczogW1xuICAgICAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWU6ICduZ09uSW5pdCcsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZTogJ3ZvaWQnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uOiAnQW5ndWxhciBsaWZlY3ljbGUgaG9vayBmb3IgY29tcG9uZW50IGluaXRpYWxpemF0aW9uJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcmdzOiBbXSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm5UeXBlOiAndm9pZCcsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbW9kaWZpZXJLaW5kOiAncHVibGljJ1xuICAgICAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lOiAndXBkYXRlUHJvZmlsZScsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZTogJ1Byb21pc2U8dm9pZD4nLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uOiAnVXBkYXRlcyB0aGUgdXNlciBwcm9maWxlIHdpdGggbmV3IGluZm9ybWF0aW9uJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcmdzOiBbXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsgbmFtZTogJ3VzZXJEYXRhJywgdHlwZTogJ1BhcnRpYWw8VXNlcj4nIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBdLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVyblR5cGU6ICdQcm9taXNlPHZvaWQ+JyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtb2RpZmllcktpbmQ6ICdwdWJsaWMnXG4gICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWU6ICd2YWxpZGF0ZUZvcm0nLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU6ICdib29sZWFuJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbjogJ1ZhbGlkYXRlcyB0aGUgcHJvZmlsZSBmb3JtIGRhdGEnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFyZ3M6IFtdLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVyblR5cGU6ICdib29sZWFuJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtb2RpZmllcktpbmQ6ICdwcml2YXRlJ1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBdLFxuXG4gICAgICAgICAgICAgICAgICAgIC8vIFByb3BlcnRpZXNcbiAgICAgICAgICAgICAgICAgICAgcHJvcGVydGllczogW1xuICAgICAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWU6ICdpc0xvYWRpbmcnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU6ICdib29sZWFuJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbjogJ0luZGljYXRlcyBpZiBjb21wb25lbnQgaXMgaW4gbG9hZGluZyBzdGF0ZScsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVmYXVsdFZhbHVlOiAnZmFsc2UnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1vZGlmaWVyS2luZDogJ3B1YmxpYydcbiAgICAgICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZTogJ2Zvcm0nLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU6ICdGb3JtR3JvdXAnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uOiAnUmVhY3RpdmUgZm9ybSBmb3IgdXNlciBwcm9maWxlIGVkaXRpbmcnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1vZGlmaWVyS2luZDogJ3B1YmxpYydcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgXSxcblxuICAgICAgICAgICAgICAgICAgICAvLyBIb3N0IGxpc3RlbmVycyBhbmQgYmluZGluZ3NcbiAgICAgICAgICAgICAgICAgICAgaG9zdExpc3RlbmVyczogW1xuICAgICAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWU6ICdjbGljaycsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJnczogWyckZXZlbnQnXSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbjogJ0hhbmRsZXMgY2xpY2sgZXZlbnRzIG9uIHRoZSBjb21wb25lbnQnXG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIF0sXG4gICAgICAgICAgICAgICAgICAgIGhvc3RCaW5kaW5nczogW1xuICAgICAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWU6ICdjbGFzcy5hY3RpdmUnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlOiAnaXNBY3RpdmUnXG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIF0sXG5cbiAgICAgICAgICAgICAgICAgICAgLy8gTGlmZWN5Y2xlIGhvb2tzXG4gICAgICAgICAgICAgICAgICAgIGltcGxlbWVudHM6IFsnT25Jbml0JywgJ09uRGVzdHJveScsICdBZnRlclZpZXdJbml0J10sXG5cbiAgICAgICAgICAgICAgICAgICAgLy8gRGVwZW5kZW5jeSBpbmplY3Rpb25cbiAgICAgICAgICAgICAgICAgICAgY29uc3RydWN0b3JPYmo6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG5hbWU6ICdjb25zdHJ1Y3RvcicsXG4gICAgICAgICAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbjogJ0NvbXBvbmVudCBjb25zdHJ1Y3RvciB3aXRoIGRlcGVuZGVuY3kgaW5qZWN0aW9uJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIGFyZ3M6IFtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7IG5hbWU6ICd1c2VyU2VydmljZScsIHR5cGU6ICdVc2VyU2VydmljZScgfSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7IG5hbWU6ICdyb3V0ZXInLCB0eXBlOiAnUm91dGVyJyB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsgbmFtZTogJ2NkJywgdHlwZTogJ0NoYW5nZURldGVjdG9yUmVmJyB9XG4gICAgICAgICAgICAgICAgICAgICAgICBdXG4gICAgICAgICAgICAgICAgICAgIH0sXG5cbiAgICAgICAgICAgICAgICAgICAgLy8gQW5ndWxhci1zcGVjaWZpYyBtZXRhZGF0YVxuICAgICAgICAgICAgICAgICAgICBwcm92aWRlcnM6IFsnVXNlclNlcnZpY2UnXSxcbiAgICAgICAgICAgICAgICAgICAgdmlld1Byb3ZpZGVyczogW10sXG4gICAgICAgICAgICAgICAgICAgIHF1ZXJpZXM6IFtdLFxuICAgICAgICAgICAgICAgICAgICBleHBvcnRBczogJ3VzZXJQcm9maWxlJyxcblxuICAgICAgICAgICAgICAgICAgICAvLyBEb2N1bWVudGF0aW9uIG1ldGFkYXRhXG4gICAgICAgICAgICAgICAgICAgIGpzZG9jdGFnczogW1xuICAgICAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRhZ05hbWU6IHsgdGV4dDogJ2V4YW1wbGUnIH0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29tbWVudDogJzxhcHAtdXNlci1wcm9maWxlIFt1c2VyXT1cImN1cnJlbnRVc2VyXCIgW2VkaXRhYmxlXT1cInRydWVcIj48L2FwcC11c2VyLXByb2ZpbGU+J1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBdLFxuXG4gICAgICAgICAgICAgICAgICAgIC8vIENvdmVyYWdlIGluZm9ybWF0aW9uIChpZiBlbmFibGVkKVxuICAgICAgICAgICAgICAgICAgICBjb3ZlcmFnZVBlcmNlbnQ6IDg1LFxuICAgICAgICAgICAgICAgICAgICBjb3ZlcmFnZUNvdW50OiAnMTcvMjAnLFxuICAgICAgICAgICAgICAgICAgICBzdGF0dXM6ICdnb29kJ1xuICAgICAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgICAgICBhZGRpdGlvbmFsQ29udGV4dCA9IHtcbiAgICAgICAgICAgICAgICAgICAgZGVwdGg6IDEsXG4gICAgICAgICAgICAgICAgICAgIGJyZWFkY3J1bWJzOiBbXG4gICAgICAgICAgICAgICAgICAgICAgICB7IG5hbWU6ICdDb21wb25lbnRzJywgdXJsOiAnLi4vY29tcG9uZW50cy5odG1sJyB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgeyBuYW1lOiAnVXNlclByb2ZpbGVDb21wb25lbnQnLCB1cmw6ICcjJyB9XG4gICAgICAgICAgICAgICAgICAgIF1cbiAgICAgICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICB9IGVsc2UgaWYgKHRlbXBsYXRlTmFtZS5pbmNsdWRlcygnc2VydmljZScpIHx8IHRlbXBsYXRlTmFtZS5pbmNsdWRlcygnaW5qZWN0YWJsZScpKSB7XG4gICAgICAgICAgICAgICAgdGVtcGxhdGVWYXJpYWJsZXMgPSB7XG4gICAgICAgICAgICAgICAgICAgIG5hbWU6ICdVc2VyU2VydmljZScsXG4gICAgICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uOiAnU2VydmljZSByZXNwb25zaWJsZSBmb3IgbWFuYWdpbmcgdXNlciBkYXRhIGFuZCBhdXRoZW50aWNhdGlvbiBvcGVyYXRpb25zJyxcbiAgICAgICAgICAgICAgICAgICAgZmlsZTogJ3NyYy9hcHAvc2VydmljZXMvdXNlci5zZXJ2aWNlLnRzJyxcbiAgICAgICAgICAgICAgICAgICAgdHlwZTogJ2luamVjdGFibGUnLFxuXG4gICAgICAgICAgICAgICAgICAgIC8vIEluamVjdGFibGUgbWV0YWRhdGFcbiAgICAgICAgICAgICAgICAgICAgcHJvdmlkZWRJbjogJ3Jvb3QnLFxuICAgICAgICAgICAgICAgICAgICBkZWNvcmF0b3JzOiBbJ0BJbmplY3RhYmxlKCknXSxcblxuICAgICAgICAgICAgICAgICAgICAvLyBNZXRob2RzXG4gICAgICAgICAgICAgICAgICAgIG1ldGhvZHM6IFtcbiAgICAgICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lOiAnZ2V0VXNlcicsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZTogJ09ic2VydmFibGU8VXNlcj4nLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uOiAnUmV0cmlldmVzIHVzZXIgZGF0YSBieSBJRCcsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJnczogW3sgbmFtZTogJ2lkJywgdHlwZTogJ3N0cmluZycgfV0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuVHlwZTogJ09ic2VydmFibGU8VXNlcj4nLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1vZGlmaWVyS2luZDogJ3B1YmxpYydcbiAgICAgICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZTogJ3VwZGF0ZVVzZXInLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU6ICdPYnNlcnZhYmxlPFVzZXI+JyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbjogJ1VwZGF0ZXMgdXNlciBpbmZvcm1hdGlvbicsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJnczogW1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7IG5hbWU6ICdpZCcsIHR5cGU6ICdzdHJpbmcnIH0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsgbmFtZTogJ3VzZXJEYXRhJywgdHlwZTogJ1BhcnRpYWw8VXNlcj4nIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBdLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVyblR5cGU6ICdPYnNlcnZhYmxlPFVzZXI+JyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtb2RpZmllcktpbmQ6ICdwdWJsaWMnXG4gICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWU6ICdkZWxldGVVc2VyJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlOiAnT2JzZXJ2YWJsZTx2b2lkPicsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVzY3JpcHRpb246ICdEZWxldGVzIGEgdXNlciBhY2NvdW50JyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcmdzOiBbeyBuYW1lOiAnaWQnLCB0eXBlOiAnc3RyaW5nJyB9XSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm5UeXBlOiAnT2JzZXJ2YWJsZTx2b2lkPicsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbW9kaWZpZXJLaW5kOiAncHVibGljJ1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBdLFxuXG4gICAgICAgICAgICAgICAgICAgIC8vIFByb3BlcnRpZXNcbiAgICAgICAgICAgICAgICAgICAgcHJvcGVydGllczogW1xuICAgICAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWU6ICdjdXJyZW50VXNlciQnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU6ICdCZWhhdmlvclN1YmplY3Q8VXNlciB8IG51bGw+JyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbjogJ09ic2VydmFibGUgc3RyZWFtIG9mIGN1cnJlbnQgdXNlciBzdGF0ZScsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbW9kaWZpZXJLaW5kOiAncHJpdmF0ZSdcbiAgICAgICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZTogJ2FwaVVybCcsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZTogJ3N0cmluZycsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVzY3JpcHRpb246ICdCYXNlIFVSTCBmb3IgdXNlciBBUEkgZW5kcG9pbnRzJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWZhdWx0VmFsdWU6ICdcIi9hcGkvdXNlcnNcIicsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbW9kaWZpZXJLaW5kOiAncHJpdmF0ZSdcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgXSxcblxuICAgICAgICAgICAgICAgICAgICAvLyBDb25zdHJ1Y3RvclxuICAgICAgICAgICAgICAgICAgICBjb25zdHJ1Y3Rvck9iajoge1xuICAgICAgICAgICAgICAgICAgICAgICAgbmFtZTogJ2NvbnN0cnVjdG9yJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uOiAnU2VydmljZSBjb25zdHJ1Y3RvciB3aXRoIEhUVFAgY2xpZW50IGluamVjdGlvbicsXG4gICAgICAgICAgICAgICAgICAgICAgICBhcmdzOiBbXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgeyBuYW1lOiAnaHR0cCcsIHR5cGU6ICdIdHRwQ2xpZW50JyB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsgbmFtZTogJ2NvbmZpZycsIHR5cGU6ICdBcHBDb25maWcnIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIF1cbiAgICAgICAgICAgICAgICAgICAgfSxcblxuICAgICAgICAgICAgICAgICAgICAvLyBDb3ZlcmFnZVxuICAgICAgICAgICAgICAgICAgICBjb3ZlcmFnZVBlcmNlbnQ6IDkyLFxuICAgICAgICAgICAgICAgICAgICBjb3ZlcmFnZUNvdW50OiAnMjMvMjUnXG4gICAgICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgfSBlbHNlIGlmICh0ZW1wbGF0ZU5hbWUuaW5jbHVkZXMoJ21vZHVsZScpKSB7XG4gICAgICAgICAgICAgICAgdGVtcGxhdGVWYXJpYWJsZXMgPSB7XG4gICAgICAgICAgICAgICAgICAgIG5hbWU6ICdVc2VyTW9kdWxlJyxcbiAgICAgICAgICAgICAgICAgICAgZGVzY3JpcHRpb246ICdGZWF0dXJlIG1vZHVsZSBjb250YWluaW5nIHVzZXItcmVsYXRlZCBjb21wb25lbnRzIGFuZCBzZXJ2aWNlcycsXG4gICAgICAgICAgICAgICAgICAgIGZpbGU6ICdzcmMvYXBwL21vZHVsZXMvdXNlci91c2VyLm1vZHVsZS50cycsXG4gICAgICAgICAgICAgICAgICAgIHR5cGU6ICdtb2R1bGUnLFxuXG4gICAgICAgICAgICAgICAgICAgIC8vIE1vZHVsZSBtZXRhZGF0YVxuICAgICAgICAgICAgICAgICAgICBkZWNsYXJhdGlvbnM6IFtcbiAgICAgICAgICAgICAgICAgICAgICAgIHsgbmFtZTogJ1VzZXJQcm9maWxlQ29tcG9uZW50JywgdHlwZTogJ2NvbXBvbmVudCcgfSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHsgbmFtZTogJ1VzZXJMaXN0Q29tcG9uZW50JywgdHlwZTogJ2NvbXBvbmVudCcgfSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHsgbmFtZTogJ1VzZXJDYXJkRGlyZWN0aXZlJywgdHlwZTogJ2RpcmVjdGl2ZScgfVxuICAgICAgICAgICAgICAgICAgICBdLFxuICAgICAgICAgICAgICAgICAgICBpbXBvcnRzOiBbXG4gICAgICAgICAgICAgICAgICAgICAgICB7IG5hbWU6ICdDb21tb25Nb2R1bGUnLCB0eXBlOiAnbW9kdWxlJyB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgeyBuYW1lOiAnUmVhY3RpdmVGb3Jtc01vZHVsZScsIHR5cGU6ICdtb2R1bGUnIH0sXG4gICAgICAgICAgICAgICAgICAgICAgICB7IG5hbWU6ICdSb3V0ZXJNb2R1bGUnLCB0eXBlOiAnbW9kdWxlJyB9XG4gICAgICAgICAgICAgICAgICAgIF0sXG4gICAgICAgICAgICAgICAgICAgIGV4cG9ydHM6IFtcbiAgICAgICAgICAgICAgICAgICAgICAgIHsgbmFtZTogJ1VzZXJQcm9maWxlQ29tcG9uZW50JywgdHlwZTogJ2NvbXBvbmVudCcgfSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHsgbmFtZTogJ1VzZXJMaXN0Q29tcG9uZW50JywgdHlwZTogJ2NvbXBvbmVudCcgfVxuICAgICAgICAgICAgICAgICAgICBdLFxuICAgICAgICAgICAgICAgICAgICBwcm92aWRlcnM6IFtcbiAgICAgICAgICAgICAgICAgICAgICAgIHsgbmFtZTogJ1VzZXJTZXJ2aWNlJywgdHlwZTogJ3NlcnZpY2UnIH0sXG4gICAgICAgICAgICAgICAgICAgICAgICB7IG5hbWU6ICdVc2VyUmVzb2x2ZXInLCB0eXBlOiAncmVzb2x2ZXInIH1cbiAgICAgICAgICAgICAgICAgICAgXSxcbiAgICAgICAgICAgICAgICAgICAgYm9vdHN0cmFwOiBbXSxcbiAgICAgICAgICAgICAgICAgICAgc2NoZW1hczogW11cbiAgICAgICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICB9IGVsc2UgaWYgKHRlbXBsYXRlTmFtZS5pbmNsdWRlcygnaW50ZXJmYWNlJykpIHtcbiAgICAgICAgICAgICAgICB0ZW1wbGF0ZVZhcmlhYmxlcyA9IHtcbiAgICAgICAgICAgICAgICAgICAgbmFtZTogJ1VzZXInLFxuICAgICAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbjogJ0ludGVyZmFjZSBkZWZpbmluZyB0aGUgc3RydWN0dXJlIG9mIHVzZXIgb2JqZWN0cycsXG4gICAgICAgICAgICAgICAgICAgIGZpbGU6ICdzcmMvYXBwL2ludGVyZmFjZXMvdXNlci5pbnRlcmZhY2UudHMnLFxuICAgICAgICAgICAgICAgICAgICB0eXBlOiAnaW50ZXJmYWNlJyxcblxuICAgICAgICAgICAgICAgICAgICAvLyBJbnRlcmZhY2UgcHJvcGVydGllc1xuICAgICAgICAgICAgICAgICAgICBwcm9wZXJ0aWVzOiBbXG4gICAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZTogJ2lkJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbjogJ1VuaXF1ZSBpZGVudGlmaWVyIGZvciB0aGUgdXNlcicsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgb3B0aW9uYWw6IGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWU6ICdlbWFpbCcsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZTogJ3N0cmluZycsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVzY3JpcHRpb246ICdVc2VyIGVtYWlsIGFkZHJlc3MnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbmFsOiBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lOiAnbmFtZScsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZTogJ3N0cmluZycsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVzY3JpcHRpb246ICdGdWxsIG5hbWUgb2YgdGhlIHVzZXInLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbmFsOiBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lOiAnYXZhdGFyJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbjogJ1VSTCB0byB1c2VyIGF2YXRhciBpbWFnZScsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgb3B0aW9uYWw6IHRydWVcbiAgICAgICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZTogJ3JvbGUnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU6ICdVc2VyUm9sZScsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVzY3JpcHRpb246ICdVc2VyIHJvbGUgcGVybWlzc2lvbnMnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbmFsOiB0cnVlXG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIF0sXG5cbiAgICAgICAgICAgICAgICAgICAgLy8gSW50ZXJmYWNlIG1ldGhvZHMgKGlmIGFueSlcbiAgICAgICAgICAgICAgICAgICAgbWV0aG9kczogW10sXG5cbiAgICAgICAgICAgICAgICAgICAgLy8gSW5kZXggc2lnbmF0dXJlc1xuICAgICAgICAgICAgICAgICAgICBpbmRleFNpZ25hdHVyZXM6IFtdXG4gICAgICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAvLyBHZW5lcmljIGRhdGEgZm9yIG90aGVyIHRlbXBsYXRlcyAoZGlyZWN0aXZlLCBwaXBlLCBndWFyZCwgZXRjLilcbiAgICAgICAgICAgICAgICB0ZW1wbGF0ZVZhcmlhYmxlcyA9IHtcbiAgICAgICAgICAgICAgICAgICAgbmFtZTogJ0V4YW1wbGVJdGVtJyxcbiAgICAgICAgICAgICAgICAgICAgZGVzY3JpcHRpb246ICdBIHNhbXBsZSBpdGVtIGZvciBkZW1vbnN0cmF0aW9uIHB1cnBvc2VzJyxcbiAgICAgICAgICAgICAgICAgICAgZmlsZTogJ3NyYy9hcHAvZXhhbXBsZS50cycsXG4gICAgICAgICAgICAgICAgICAgIHR5cGU6ICdjbGFzcycsXG5cbiAgICAgICAgICAgICAgICAgICAgLy8gQmFzaWMgcHJvcGVydGllcyB0aGF0IG1vc3QgdGVtcGxhdGVzIHdvdWxkIGhhdmVcbiAgICAgICAgICAgICAgICAgICAgbWV0aG9kczogW1xuICAgICAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWU6ICduZ09uSW5pdCcsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZTogJ3ZvaWQnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uOiAnTGlmZWN5Y2xlIGhvb2snLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFyZ3M6IFtdLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVyblR5cGU6ICd2b2lkJ1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBdLFxuICAgICAgICAgICAgICAgICAgICBwcm9wZXJ0aWVzOiBbXG4gICAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZTogJ2lzQWN0aXZlJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlOiAnYm9vbGVhbicsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVzY3JpcHRpb246ICdBY3RpdmUgc3RhdGUnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlZmF1bHRWYWx1ZTogJ2ZhbHNlJ1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBdXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gQWRkIGNvbW1vbiB0ZW1wbGF0ZSBjb250ZXh0IHZhcmlhYmxlcyB0aGF0IGFsbCB0ZW1wbGF0ZXMgcmVjZWl2ZVxuICAgICAgICAgICAgY29uc3QgY29tbW9uQ29udGV4dCA9IHtcbiAgICAgICAgICAgICAgICAvLyBOYXZpZ2F0aW9uIGFuZCBVSVxuICAgICAgICAgICAgICAgIGRlcHRoOiBhZGRpdGlvbmFsQ29udGV4dC5kZXB0aCB8fCAwLFxuICAgICAgICAgICAgICAgIGJyZWFkY3J1bWJzOiBhZGRpdGlvbmFsQ29udGV4dC5icmVhZGNydW1icyB8fCBbXSxcbiAgICAgICAgICAgICAgICBuYXZUYWJzOiBjb21wb2RvY0NvbmZpZy5uYXZUYWJDb25maWcsXG5cbiAgICAgICAgICAgICAgICAvLyBIZWxwZXIgZnVuY3Rpb25zIGF2YWlsYWJsZSBpbiB0ZW1wbGF0ZXNcbiAgICAgICAgICAgICAgICB0OiAoa2V5OiBzdHJpbmcpID0+IGBbVHJhbnNsYXRpb246ICR7a2V5fV1gLCAvLyBTaW11bGF0ZXMgaTE4biBmdW5jdGlvblxuICAgICAgICAgICAgICAgIHJlbGF0aXZlVVJMOiAodXJsOiBzdHJpbmcpID0+IHVybCwgLy8gVVJMIGhlbHBlclxuXG4gICAgICAgICAgICAgICAgLy8gUHJvamVjdCBpbmZvcm1hdGlvblxuICAgICAgICAgICAgICAgIHByb2plY3RUaXRsZTogKGNvbXBvZG9jQ29uZmlnIGFzIGFueSkuZG9jdW1lbnRhdGlvbk1haW5OYW1lIHx8IGNvbXBvZG9jQ29uZmlnLm5hbWUgfHwgJ0RvY3VtZW50YXRpb24nLFxuICAgICAgICAgICAgICAgIHByb2plY3REZXNjcmlwdGlvbjogKGNvbXBvZG9jQ29uZmlnIGFzIGFueSkuZG9jdW1lbnRhdGlvbk1haW5EZXNjcmlwdGlvbiB8fCAnRG9jdW1lbnRhdGlvbiBkZXNjcmlwdGlvbicsXG5cbiAgICAgICAgICAgICAgICAvLyBDdXJyZW50IHBhZ2UgY29udGV4dFxuICAgICAgICAgICAgICAgIHBhZ2VUeXBlOiB0ZW1wbGF0ZU5hbWUsXG4gICAgICAgICAgICAgICAgcGFnZU5hbWU6IHRlbXBsYXRlVmFyaWFibGVzLm5hbWUgfHwgJ1Vua25vd24nLFxuXG4gICAgICAgICAgICAgICAgLy8gRmVhdHVyZSBmbGFncyAoZnJvbSBjb25maWcpXG4gICAgICAgICAgICAgICAgc2hvd1NvdXJjZUNvZGU6ICFjb21wb2RvY0NvbmZpZy5kaXNhYmxlU291cmNlQ29kZSxcbiAgICAgICAgICAgICAgICBzaG93R3JhcGg6ICFjb21wb2RvY0NvbmZpZy5kaXNhYmxlR3JhcGgsXG4gICAgICAgICAgICAgICAgc2hvd0NvdmVyYWdlOiAhY29tcG9kb2NDb25maWcuZGlzYWJsZUNvdmVyYWdlLFxuICAgICAgICAgICAgICAgIHNob3dQcml2YXRlTWVtYmVyczogIWNvbXBvZG9jQ29uZmlnLmRpc2FibGVQcml2YXRlLFxuICAgICAgICAgICAgICAgIHNob3dQcm90ZWN0ZWRNZW1iZXJzOiAhY29tcG9kb2NDb25maWcuZGlzYWJsZVByb3RlY3RlZCxcbiAgICAgICAgICAgICAgICBzaG93SW50ZXJuYWxNZW1iZXJzOiAhY29tcG9kb2NDb25maWcuZGlzYWJsZUludGVybmFsXG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAvLyBSZXR1cm4gb25seSB0aGUgQ29tcG9kb2MgY29uZmlndXJhdGlvbiBvcHRpb25zXG4gICAgICAgICAgICBzZW5kKHJlcywgMjAwLCB7XG4gICAgICAgICAgICAgICAgc3VjY2VzczogdHJ1ZSxcbiAgICAgICAgICAgICAgICBjYXRlZ29yaWVzOiB7XG4gICAgICAgICAgICAgICAgICAgIGNvbXBvZG9jQ29uZmlnOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aXRsZTogJ0NvbXBvZG9jIENvbmZpZ3VyYXRpb24gT3B0aW9ucycsXG4gICAgICAgICAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbjogJ0VkaXQgdGhlc2UgY29uZmlndXJhdGlvbiBvcHRpb25zIHRvIGN1c3RvbWl6ZSB0aGUgZ2VuZXJhdGVkIGRvY3VtZW50YXRpb24uIENoYW5nZXMgd2lsbCBhdXRvbWF0aWNhbGx5IHJlZ2VuZXJhdGUgdGhlIGRvY3VtZW50YXRpb24uJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIGRhdGE6IGNvbXBvZG9jQ29uZmlnXG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9LFxuXG4gICAgICAgICAgICAgICAgLy8gTGVnYWN5IGZvcm1hdCBmb3IgYmFja3dhcmQgY29tcGF0aWJpbGl0eVxuICAgICAgICAgICAgICAgIGRhdGE6IGNvbXBvZG9jQ29uZmlnLFxuICAgICAgICAgICAgICAgIGNvbnRleHQ6IHsgY29uZmlnOiBjb21wb2RvY0NvbmZpZyB9XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgbG9nZ2VyLmVycm9yKCdFcnJvciBnZXR0aW5nIHNlc3Npb24gdGVtcGxhdGUgZGF0YTonLCBlcnJvcik7XG4gICAgICAgICAgICBzZW5kKHJlcywgNTAwLCB7XG4gICAgICAgICAgICAgICAgc3VjY2VzczogZmFsc2UsXG4gICAgICAgICAgICAgICAgbWVzc2FnZTogJ0ZhaWxlZCB0byBnZXQgdGVtcGxhdGUgZGF0YScsXG4gICAgICAgICAgICAgICAgZXJyb3I6IGVycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvci5tZXNzYWdlIDogJ1Vua25vd24gZXJyb3InXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgYXN5bmMgZ2VuZXJhdGVTZXNzaW9uRG9jcyhyZXE6IGFueSwgcmVzOiBTZXJ2ZXJSZXNwb25zZSk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgY29uc3QgeyBzZXNzaW9uSWQgfSA9IHJlcS5wYXJhbXM7XG4gICAgICAgICAgICBcbiAgICAgICAgICAgIC8vIFNhZmVseSBkZXN0cnVjdHVyZSBmcm9tIHJlcS5ib2R5LCBoYW5kbGluZyBjYXNlcyB3aGVyZSBpdCBtaWdodCBiZSB1bmRlZmluZWQgKFBvbGthIGJlaGF2aW9yKVxuICAgICAgICAgICAgY29uc3QgeyBjdXN0b21UZW1wbGF0ZUNvbnRlbnQsIG1vY2tEYXRhIH0gPSByZXEuYm9keSB8fCB7fTtcblxuICAgICAgICAgICAgaWYgKCF0aGlzLnNlc3Npb25zLmhhcyhzZXNzaW9uSWQpKSB7XG4gICAgICAgICAgICAgICAgc2VuZChyZXMsIDQwNCwge1xuICAgICAgICAgICAgICAgICAgICBzdWNjZXNzOiBmYWxzZSxcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZTogJ1Nlc3Npb24gbm90IGZvdW5kJ1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uc3Qgc2Vzc2lvbiA9IHRoaXMuc2Vzc2lvbnMuZ2V0KHNlc3Npb25JZCk7XG4gICAgICAgICAgICB0aGlzLnVwZGF0ZVNlc3Npb25BY3Rpdml0eShzZXNzaW9uSWQpO1xuXG4gICAgICAgICAgICAvLyBTYXZlIHRoZSBjdXN0b20gdGVtcGxhdGUgY29udGVudCBpZiBwcm92aWRlZFxuICAgICAgICAgICAgaWYgKGN1c3RvbVRlbXBsYXRlQ29udGVudCAmJiByZXEuYm9keS50ZW1wbGF0ZVBhdGgpIHtcbiAgICAgICAgICAgICAgICBjb25zdCB0ZW1wbGF0ZVBhdGggPSBwYXRoLmpvaW4oc2Vzc2lvbi50ZW1wbGF0ZURpciwgcmVxLmJvZHkudGVtcGxhdGVQYXRoKTtcbiAgICAgICAgICAgICAgICBhd2FpdCBmcy53cml0ZUZpbGUodGVtcGxhdGVQYXRoLCBjdXN0b21UZW1wbGF0ZUNvbnRlbnQsICd1dGY4Jyk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIEdlbmVyYXRlIGRvY3VtZW50YXRpb24gZm9yIHRoaXMgc2Vzc2lvblxuICAgICAgICAgICAgdGhpcy5nZW5lcmF0ZURvY3VtZW50YXRpb24oc2Vzc2lvbklkLCBmYWxzZSk7IC8vIE5vIGRlYm91bmNlIGZvciBtYW51YWwgZ2VuZXJhdGlvblxuXG4gICAgICAgICAgICBzZW5kKHJlcywgMjAwLCB7XG4gICAgICAgICAgICAgICAgc3VjY2VzczogdHJ1ZSxcbiAgICAgICAgICAgICAgICBtZXNzYWdlOiAnRG9jdW1lbnRhdGlvbiBnZW5lcmF0aW9uIHN0YXJ0ZWQnLFxuICAgICAgICAgICAgICAgIHNlc3Npb25JZDogc2Vzc2lvbklkXG4gICAgICAgICAgICB9KTtcblxuICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgbG9nZ2VyLmVycm9yKCdFcnJvciBnZW5lcmF0aW5nIHNlc3Npb24gZG9jdW1lbnRhdGlvbjonLCBlcnJvcik7XG4gICAgICAgICAgICBzZW5kKHJlcywgNTAwLCB7XG4gICAgICAgICAgICAgICAgc3VjY2VzczogZmFsc2UsXG4gICAgICAgICAgICAgICAgbWVzc2FnZTogJ0ZhaWxlZCB0byBnZW5lcmF0ZSBkb2N1bWVudGF0aW9uJyxcbiAgICAgICAgICAgICAgICBlcnJvcjogZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yLm1lc3NhZ2UgOiAnVW5rbm93biBlcnJvcidcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBhc3luYyBnZXRTZXNzaW9uQ29uZmlnKHJlcTogYW55LCByZXM6IFNlcnZlclJlc3BvbnNlKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjb25zdCBzZXNzaW9uSWQgPSByZXEucGFyYW1zLnNlc3Npb25JZDtcbiAgICAgICAgICAgIGNvbnN0IHNlc3Npb24gPSB0aGlzLnNlc3Npb25zLmdldChzZXNzaW9uSWQpO1xuXG4gICAgICAgICAgICBpZiAoIXNlc3Npb24pIHtcbiAgICAgICAgICAgICAgICBzZW5kKHJlcywgNDA0LCB7IHN1Y2Nlc3M6IGZhbHNlLCBtZXNzYWdlOiAnU2Vzc2lvbiBub3QgZm91bmQnIH0pO1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGhpcy51cGRhdGVTZXNzaW9uQWN0aXZpdHkoc2Vzc2lvbklkKTtcblxuICAgICAgICAgICAgLy8gUmV0dXJuIGNvbXBsZXRlIENvbXBvZG9jIGNvbmZpZ3VyYXRpb24gd2l0aCBjdXJyZW50IHZhbHVlcyBvciBkZWZhdWx0c1xuICAgICAgICAgICAgY29uc3QgZnVsbENvbmZpZyA9IHtcbiAgICAgICAgICAgICAgICAvLyBEb2N1bWVudGF0aW9uIE1ldGFkYXRhXG4gICAgICAgICAgICAgICAgbmFtZTogc2Vzc2lvbi5jb25maWc/Lm5hbWUgfHwgJ0FwcGxpY2F0aW9uIGRvY3VtZW50YXRpb24nLFxuXG4gICAgICAgICAgICAgICAgLy8gUGF0aHMgYW5kIE91dHB1dFxuICAgICAgICAgICAgICAgIG91dHB1dDogc2Vzc2lvbi5jb25maWc/Lm91dHB1dCB8fCAnLi9kb2N1bWVudGF0aW9uLycsXG4gICAgICAgICAgICAgICAgdGhlbWU6IHNlc3Npb24uY29uZmlnPy50aGVtZSB8fCAnZ2l0Ym9vaycsXG4gICAgICAgICAgICAgICAgbGFuZ3VhZ2U6IHNlc3Npb24uY29uZmlnPy5sYW5ndWFnZSB8fCAnZW4tVVMnLFxuICAgICAgICAgICAgICAgIGJhc2U6IHNlc3Npb24uY29uZmlnPy5iYXNlIHx8ICcvJyxcblxuICAgICAgICAgICAgICAgIC8vIEFzc2V0cyBhbmQgQ3VzdG9tIFVJXG4gICAgICAgICAgICAgICAgY3VzdG9tRmF2aWNvbjogc2Vzc2lvbi5jb25maWc/LmN1c3RvbUZhdmljb24gfHwgJycsXG4gICAgICAgICAgICAgICAgY3VzdG9tTG9nbzogc2Vzc2lvbi5jb25maWc/LmN1c3RvbUxvZ28gfHwgJycsXG4gICAgICAgICAgICAgICAgYXNzZXRzRm9sZGVyOiBzZXNzaW9uLmNvbmZpZz8uYXNzZXRzRm9sZGVyIHx8ICcnLFxuICAgICAgICAgICAgICAgIGV4dFRoZW1lOiBzZXNzaW9uLmNvbmZpZz8uZXh0VGhlbWUgfHwgJycsXG5cbiAgICAgICAgICAgICAgICAvLyBGZWF0dXJlIFRvZ2dsZXMgLSBEaXNhYmxlIE9wdGlvbnNcbiAgICAgICAgICAgICAgICBkaXNhYmxlU291cmNlQ29kZTogISFzZXNzaW9uLmNvbmZpZz8uZGlzYWJsZVNvdXJjZUNvZGUsXG4gICAgICAgICAgICAgICAgZGlzYWJsZUdyYXBoOiAhIXNlc3Npb24uY29uZmlnPy5kaXNhYmxlR3JhcGgsXG4gICAgICAgICAgICAgICAgZGlzYWJsZUNvdmVyYWdlOiAhIXNlc3Npb24uY29uZmlnPy5kaXNhYmxlQ292ZXJhZ2UsXG4gICAgICAgICAgICAgICAgZGlzYWJsZVByaXZhdGU6ICEhc2Vzc2lvbi5jb25maWc/LmRpc2FibGVQcml2YXRlLFxuICAgICAgICAgICAgICAgIGRpc2FibGVQcm90ZWN0ZWQ6ICEhc2Vzc2lvbi5jb25maWc/LmRpc2FibGVQcm90ZWN0ZWQsXG4gICAgICAgICAgICAgICAgZGlzYWJsZUludGVybmFsOiAhIXNlc3Npb24uY29uZmlnPy5kaXNhYmxlSW50ZXJuYWwsXG4gICAgICAgICAgICAgICAgZGlzYWJsZUxpZmVDeWNsZUhvb2tzOiAhIXNlc3Npb24uY29uZmlnPy5kaXNhYmxlTGlmZUN5Y2xlSG9va3MsXG4gICAgICAgICAgICAgICAgZGlzYWJsZUNvbnN0cnVjdG9yczogISFzZXNzaW9uLmNvbmZpZz8uZGlzYWJsZUNvbnN0cnVjdG9ycyxcbiAgICAgICAgICAgICAgICBkaXNhYmxlUm91dGVzR3JhcGg6ICEhc2Vzc2lvbi5jb25maWc/LmRpc2FibGVSb3V0ZXNHcmFwaCxcbiAgICAgICAgICAgICAgICBkaXNhYmxlU2VhcmNoOiAhIXNlc3Npb24uY29uZmlnPy5kaXNhYmxlU2VhcmNoLFxuICAgICAgICAgICAgICAgIGRpc2FibGVEZXBlbmRlbmNpZXM6ICEhc2Vzc2lvbi5jb25maWc/LmRpc2FibGVEZXBlbmRlbmNpZXMsXG4gICAgICAgICAgICAgICAgZGlzYWJsZVByb3BlcnRpZXM6ICEhc2Vzc2lvbi5jb25maWc/LmRpc2FibGVQcm9wZXJ0aWVzLFxuICAgICAgICAgICAgICAgIGRpc2FibGVEb21UcmVlOiAhIXNlc3Npb24uY29uZmlnPy5kaXNhYmxlRG9tVHJlZSxcbiAgICAgICAgICAgICAgICBkaXNhYmxlVGVtcGxhdGVUYWI6ICEhc2Vzc2lvbi5jb25maWc/LmRpc2FibGVUZW1wbGF0ZVRhYixcbiAgICAgICAgICAgICAgICBkaXNhYmxlU3R5bGVUYWI6ICEhc2Vzc2lvbi5jb25maWc/LmRpc2FibGVTdHlsZVRhYixcbiAgICAgICAgICAgICAgICBkaXNhYmxlTWFpbkdyYXBoOiAhIXNlc3Npb24uY29uZmlnPy5kaXNhYmxlTWFpbkdyYXBoLFxuICAgICAgICAgICAgICAgIGRpc2FibGVGaWxlUGF0aDogISFzZXNzaW9uLmNvbmZpZz8uZGlzYWJsZUZpbGVQYXRoLFxuICAgICAgICAgICAgICAgIGRpc2FibGVPdmVydmlldzogISFzZXNzaW9uLmNvbmZpZz8uZGlzYWJsZU92ZXJ2aWV3LFxuXG4gICAgICAgICAgICAgICAgLy8gVUkgT3B0aW9uc1xuICAgICAgICAgICAgICAgIGhpZGVHZW5lcmF0b3I6ICEhc2Vzc2lvbi5jb25maWc/LmhpZGVHZW5lcmF0b3IsXG4gICAgICAgICAgICAgICAgaGlkZURhcmtNb2RlVG9nZ2xlOiAhIXNlc3Npb24uY29uZmlnPy5oaWRlRGFya01vZGVUb2dnbGUsXG4gICAgICAgICAgICAgICAgbWluaW1hbDogISFzZXNzaW9uLmNvbmZpZz8ubWluaW1hbCxcblxuICAgICAgICAgICAgICAgIC8vIEFkZGl0aW9uYWwgQ29udGVudFxuICAgICAgICAgICAgICAgIGluY2x1ZGVzOiBzZXNzaW9uLmNvbmZpZz8uaW5jbHVkZXMgfHwgJycsXG4gICAgICAgICAgICAgICAgaW5jbHVkZXNOYW1lOiBzZXNzaW9uLmNvbmZpZz8uaW5jbHVkZXNOYW1lIHx8ICdBZGRpdGlvbmFsIGRvY3VtZW50YXRpb24nLFxuXG4gICAgICAgICAgICAgICAgLy8gU2VydmluZyBPcHRpb25zXG4gICAgICAgICAgICAgICAgcG9ydDogc2Vzc2lvbi5jb25maWc/LnBvcnQgfHwgODA4MCxcbiAgICAgICAgICAgICAgICBob3N0bmFtZTogc2Vzc2lvbi5jb25maWc/Lmhvc3RuYW1lIHx8ICcxMjcuMC4wLjEnLFxuICAgICAgICAgICAgICAgIHNlcnZlOiAhIXNlc3Npb24uY29uZmlnPy5zZXJ2ZSxcbiAgICAgICAgICAgICAgICBvcGVuOiAhIXNlc3Npb24uY29uZmlnPy5vcGVuLFxuICAgICAgICAgICAgICAgIHdhdGNoOiAhIXNlc3Npb24uY29uZmlnPy53YXRjaCxcblxuICAgICAgICAgICAgICAgIC8vIEV4cG9ydCBPcHRpb25zXG4gICAgICAgICAgICAgICAgZXhwb3J0Rm9ybWF0OiBzZXNzaW9uLmNvbmZpZz8uZXhwb3J0Rm9ybWF0IHx8ICdodG1sJyxcblxuICAgICAgICAgICAgICAgIC8vIENvdmVyYWdlIE9wdGlvbnNcbiAgICAgICAgICAgICAgICBjb3ZlcmFnZVRlc3Q6ICEhc2Vzc2lvbi5jb25maWc/LmNvdmVyYWdlVGVzdCxcbiAgICAgICAgICAgICAgICBjb3ZlcmFnZVRlc3RUaHJlc2hvbGQ6IHNlc3Npb24uY29uZmlnPy5jb3ZlcmFnZVRlc3RUaHJlc2hvbGQgfHwgNzAsXG4gICAgICAgICAgICAgICAgY292ZXJhZ2VNaW5pbXVtUGVyRmlsZTogc2Vzc2lvbi5jb25maWc/LmNvdmVyYWdlTWluaW11bVBlckZpbGUgfHwgMCxcbiAgICAgICAgICAgICAgICBjb3ZlcmFnZVRlc3RUaHJlc2hvbGRGYWlsOiAhIXNlc3Npb24uY29uZmlnPy5jb3ZlcmFnZVRlc3RUaHJlc2hvbGRGYWlsLFxuICAgICAgICAgICAgICAgIGNvdmVyYWdlVGVzdFNob3dPbmx5RmFpbGVkOiAhIXNlc3Npb24uY29uZmlnPy5jb3ZlcmFnZVRlc3RTaG93T25seUZhaWxlZCxcbiAgICAgICAgICAgICAgICB1bml0VGVzdENvdmVyYWdlOiBzZXNzaW9uLmNvbmZpZz8udW5pdFRlc3RDb3ZlcmFnZSB8fCAnJyxcblxuICAgICAgICAgICAgICAgIC8vIEdvb2dsZSBBbmFseXRpY3NcbiAgICAgICAgICAgICAgICBnYUlEOiBzZXNzaW9uLmNvbmZpZz8uZ2FJRCB8fCAnJyxcbiAgICAgICAgICAgICAgICBnYVNpdGU6IHNlc3Npb24uY29uZmlnPy5nYVNpdGUgfHwgJ2F1dG8nLFxuXG4gICAgICAgICAgICAgICAgLy8gQWR2YW5jZWQgT3B0aW9uc1xuICAgICAgICAgICAgICAgIHNpbGVudDogISFzZXNzaW9uLmNvbmZpZz8uc2lsZW50LFxuICAgICAgICAgICAgICAgIG1heFNlYXJjaFJlc3VsdHM6IHNlc3Npb24uY29uZmlnPy5tYXhTZWFyY2hSZXN1bHRzIHx8IDE1LFxuXG4gICAgICAgICAgICAgICAgLy8gTWVudSBDb25maWd1cmF0aW9uIChhcyBKU09OIHN0cmluZyBmb3IgZWRpdGluZylcbiAgICAgICAgICAgICAgICB0b2dnbGVNZW51SXRlbXM6IEpTT04uc3RyaW5naWZ5KHNlc3Npb24uY29uZmlnPy50b2dnbGVNZW51SXRlbXMgfHwgWydhbGwnXSksXG4gICAgICAgICAgICAgICAgbmF2VGFiQ29uZmlnOiBKU09OLnN0cmluZ2lmeShzZXNzaW9uLmNvbmZpZz8ubmF2VGFiQ29uZmlnIHx8IFtdKVxuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgc2VuZChyZXMsIDIwMCwge1xuICAgICAgICAgICAgICAgIGNvbmZpZzogZnVsbENvbmZpZyxcbiAgICAgICAgICAgICAgICBzdWNjZXNzOiB0cnVlXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgIGxvZ2dlci5lcnJvcignRXJyb3IgZ2V0dGluZyBzZXNzaW9uIGNvbmZpZzonLCBlcnJvcik7XG4gICAgICAgICAgICBzZW5kKHJlcywgNTAwLCB7XG4gICAgICAgICAgICAgICAgc3VjY2VzczogZmFsc2UsXG4gICAgICAgICAgICAgICAgbWVzc2FnZTogJ0ZhaWxlZCB0byBnZXQgY29uZmlnJyxcbiAgICAgICAgICAgICAgICBlcnJvcjogZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yLm1lc3NhZ2UgOiAnVW5rbm93biBlcnJvcidcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBhc3luYyB1cGRhdGVTZXNzaW9uQ29uZmlnKHJlcTogYW55LCByZXM6IFNlcnZlclJlc3BvbnNlKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjb25zdCBzZXNzaW9uSWQgPSByZXEucGFyYW1zLnNlc3Npb25JZDtcbiAgICAgICAgICAgIGNvbnN0IHsgY29uZmlnIH0gPSByZXEuYm9keTtcbiAgICAgICAgICAgIGNvbnN0IHNlc3Npb24gPSB0aGlzLnNlc3Npb25zLmdldChzZXNzaW9uSWQpO1xuXG4gICAgICAgICAgICBpZiAoIXNlc3Npb24pIHtcbiAgICAgICAgICAgICAgICBzZW5kKHJlcywgNDA0LCB7IHN1Y2Nlc3M6IGZhbHNlLCBtZXNzYWdlOiAnU2Vzc2lvbiBub3QgZm91bmQnIH0pO1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGhpcy51cGRhdGVTZXNzaW9uQWN0aXZpdHkoc2Vzc2lvbklkKTtcblxuICAgICAgICAgICAgLy8gVXBkYXRlIHNlc3Npb24gY29uZmlnXG4gICAgICAgICAgICBzZXNzaW9uLmNvbmZpZyA9IHsgLi4uc2Vzc2lvbi5jb25maWcsIC4uLmNvbmZpZyB9O1xuXG4gICAgICAgICAgICAvLyBUcmlnZ2VyIGRlYm91bmNlZCBkb2N1bWVudGF0aW9uIHJlZ2VuZXJhdGlvbiB3aXRoIG5ldyBjb25maWdcbiAgICAgICAgICAgIHRoaXMuZ2VuZXJhdGVEb2N1bWVudGF0aW9uKHNlc3Npb25JZCwgdHJ1ZSk7XG5cbiAgICAgICAgICAgIHNlbmQocmVzLCAyMDAsIHtcbiAgICAgICAgICAgICAgICBzdWNjZXNzOiB0cnVlLFxuICAgICAgICAgICAgICAgIG1lc3NhZ2U6ICdDb25maWd1cmF0aW9uIHVwZGF0ZWQgc3VjY2Vzc2Z1bGx5JyxcbiAgICAgICAgICAgICAgICBjb25maWc6IHNlc3Npb24uY29uZmlnXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgIGxvZ2dlci5lcnJvcignRXJyb3IgdXBkYXRpbmcgc2Vzc2lvbiBjb25maWc6JywgZXJyb3IpO1xuICAgICAgICAgICAgc2VuZChyZXMsIDUwMCwge1xuICAgICAgICAgICAgICAgIHN1Y2Nlc3M6IGZhbHNlLFxuICAgICAgICAgICAgICAgIG1lc3NhZ2U6ICdGYWlsZWQgdG8gdXBkYXRlIGNvbmZpZycsXG4gICAgICAgICAgICAgICAgZXJyb3I6IGVycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvci5tZXNzYWdlIDogJ1Vua25vd24gZXJyb3InXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgc2VydmVTZXNzaW9uRG9jcyhyZXE6IGFueSwgcmVzOiBTZXJ2ZXJSZXNwb25zZSk6IHZvaWQge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgY29uc3Qgc2Vzc2lvbklkID0gcmVxLnBhcmFtcy5zZXNzaW9uSWQ7XG4gICAgICAgICAgICBjb25zdCBzZXNzaW9uID0gdGhpcy5zZXNzaW9ucy5nZXQoc2Vzc2lvbklkKTtcblxuICAgICAgICAgICAgaWYgKCFzZXNzaW9uKSB7XG4gICAgICAgICAgICAgICAgc2VuZChyZXMsIDQwNCwgeyBzdWNjZXNzOiBmYWxzZSwgbWVzc2FnZTogJ1Nlc3Npb24gbm90IGZvdW5kJyB9KTtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHRoaXMudXBkYXRlU2Vzc2lvbkFjdGl2aXR5KHNlc3Npb25JZCk7XG5cbiAgICAgICAgICAgIC8vIFJlbW92ZSB0aGUgc2Vzc2lvbiBwYXJ0IGZyb20gdGhlIFVSTCB0byBnZXQgdGhlIGZpbGUgcGF0aFxuICAgICAgICAgICAgY29uc3QgZmlsZVBhdGggPSByZXEudXJsLnJlcGxhY2UoL15cXC9hcGlcXC9zZXNzaW9uXFwvW15cXC9dK1xcL2RvY3MvLCAnJyk7XG4gICAgICAgICAgICBjb25zdCBmdWxsUGF0aCA9IHBhdGguam9pbihzZXNzaW9uLmRvY3VtZW50YXRpb25EaXIsIGZpbGVQYXRoIHx8ICdpbmRleC5odG1sJyk7XG5cbiAgICAgICAgICAgIGlmIChmcy5leGlzdHNTeW5jKGZ1bGxQYXRoKSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IGNvbnRlbnQgPSBmcy5yZWFkRmlsZVN5bmMoZnVsbFBhdGgpO1xuICAgICAgICAgICAgICAgIGNvbnN0IGV4dCA9IHBhdGguZXh0bmFtZShmdWxsUGF0aCkudG9Mb3dlckNhc2UoKTtcbiAgICAgICAgICAgICAgICBjb25zdCBjb250ZW50VHlwZSA9IGV4dCA9PT0gJy5odG1sJyA/ICd0ZXh0L2h0bWwnIDogXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXh0ID09PSAnLmNzcycgPyAndGV4dC9jc3MnIDpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBleHQgPT09ICcuanMnID8gJ2FwcGxpY2F0aW9uL2phdmFzY3JpcHQnIDpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBleHQgPT09ICcuanNvbicgPyAnYXBwbGljYXRpb24vanNvbicgOlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICd0ZXh0L3BsYWluJztcbiAgICAgICAgICAgICAgICByZXMuc2V0SGVhZGVyKCdDb250ZW50LVR5cGUnLCBjb250ZW50VHlwZSk7XG4gICAgICAgICAgICAgICAgcmVzLmVuZChjb250ZW50KTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcmVzLnN0YXR1c0NvZGUgPSA0MDQ7XG4gICAgICAgICAgICAgICAgcmVzLmVuZCgnRG9jdW1lbnRhdGlvbiBmaWxlIG5vdCBmb3VuZCcpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgbG9nZ2VyLmVycm9yKCdFcnJvciBzZXJ2aW5nIHNlc3Npb24gZG9jczonLCBlcnJvcik7XG4gICAgICAgICAgICByZXMuc3RhdHVzQ29kZSA9IDUwMDtcbiAgICAgICAgICAgIHJlcy5lbmQoJ0Vycm9yIHNlcnZpbmcgZG9jdW1lbnRhdGlvbicpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBhc3luYyBpc1BvcnRBdmFpbGFibGUocG9ydDogbnVtYmVyKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSkgPT4ge1xuICAgICAgICAgICAgY29uc3Qgc2VydmVyID0gaHR0cC5jcmVhdGVTZXJ2ZXIoKTtcbiAgICAgICAgICAgIHNlcnZlci5saXN0ZW4ocG9ydCwgKCkgPT4ge1xuICAgICAgICAgICAgICAgIHNlcnZlci5jbG9zZSgoKSA9PiByZXNvbHZlKHRydWUpKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgc2VydmVyLm9uKCdlcnJvcicsICgpID0+IHJlc29sdmUoZmFsc2UpKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBhc3luYyBmaW5kQXZhaWxhYmxlUG9ydChzdGFydFBvcnQ6IG51bWJlcik6IFByb21pc2U8bnVtYmVyPiB7XG4gICAgICAgIGxldCBwb3J0ID0gc3RhcnRQb3J0O1xuICAgICAgICB3aGlsZSAocG9ydCA8IHN0YXJ0UG9ydCArIDEwMCkgeyAvLyBUcnkgdXAgdG8gMTAwIHBvcnRzIGFib3ZlIHRoZSByZXF1ZXN0ZWQgcG9ydFxuICAgICAgICAgICAgaWYgKGF3YWl0IHRoaXMuaXNQb3J0QXZhaWxhYmxlKHBvcnQpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHBvcnQ7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBwb3J0Kys7XG4gICAgICAgIH1cbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBObyBhdmFpbGFibGUgcG9ydCBmb3VuZCBpbiByYW5nZSAke3N0YXJ0UG9ydH0tJHtzdGFydFBvcnQgKyA5OX1gKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgYXN5bmMgc3RhcnQoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICAvLyBDaGVjayBpZiB0aGUgcmVxdWVzdGVkIHBvcnQgaXMgYXZhaWxhYmxlLCBvdGhlcndpc2UgZmluZCBhbiBhbHRlcm5hdGl2ZVxuICAgICAgICAgICAgaWYgKCEoYXdhaXQgdGhpcy5pc1BvcnRBdmFpbGFibGUodGhpcy5wb3J0KSkpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBvcmlnaW5hbFBvcnQgPSB0aGlzLnBvcnQ7XG4gICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5wb3J0ID0gYXdhaXQgdGhpcy5maW5kQXZhaWxhYmxlUG9ydCh0aGlzLnBvcnQgKyAxKTtcbiAgICAgICAgICAgICAgICAgICAgbG9nZ2VyLndhcm4oYOKaoO+4jyAgUG9ydCAke29yaWdpbmFsUG9ydH0gaXMgaW4gdXNlLiBVc2luZyBwb3J0ICR7dGhpcy5wb3J0fSBpbnN0ZWFkLmApO1xuICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgUG9ydCAke29yaWdpbmFsUG9ydH0gaXMgaW4gdXNlIGFuZCBubyBhbHRlcm5hdGl2ZSBwb3J0IGNvdWxkIGJlIGZvdW5kLiBQbGVhc2Ugc3RvcCB0aGUgcHJvY2VzcyB1c2luZyBwb3J0ICR7b3JpZ2luYWxQb3J0fSBvciBzcGVjaWZ5IGEgZGlmZmVyZW50IHBvcnQuYCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0aGlzLnNlcnZlciA9IHRoaXMuYXBwLmxpc3Rlbih0aGlzLnBvcnQsICgpID0+IHtcbiAgICAgICAgICAgICAgICBsb2dnZXIuaW5mbyhg8J+OqCBUZW1wbGF0ZSBQbGF5Z3JvdW5kIGlzIHJ1bm5pbmcgYXQ6IGh0dHA6Ly9sb2NhbGhvc3Q6JHt0aGlzLnBvcnR9YCk7XG4gICAgICAgICAgICAgICAgbG9nZ2VyLmluZm8oJ/Cfk50gVXNlIHRoaXMgdG9vbCB0byBjdXN0b21pemUgYW5kIHByZXZpZXcgQ29tcG9kb2MgdGVtcGxhdGVzJyk7XG4gICAgICAgICAgICAgICAgbG9nZ2VyLmluZm8oJ/CflKcgRWRpdCB0ZW1wbGF0ZXMgaW4gdGhlIGxlZnQgcGFuZWwgYW5kIHNlZSBsaXZlIHByZXZpZXcgb24gdGhlIHJpZ2h0Jyk7XG4gICAgICAgICAgICAgICAgbG9nZ2VyLmluZm8oJ/Cfkr4gRXhwb3J0IHlvdXIgY3VzdG9taXplZCB0ZW1wbGF0ZXMgd2hlbiByZWFkeScpO1xuICAgICAgICAgICAgICAgIGxvZ2dlci5pbmZvKCcnKTtcbiAgICAgICAgICAgICAgICBsb2dnZXIuaW5mbygnUHJlc3MgQ3RybCtDIHRvIHN0b3AgdGhlIHNlcnZlcicpO1xuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIC8vIEdyYWNlZnVsIHNodXRkb3duXG4gICAgICAgICAgICBwcm9jZXNzLm9uKCdTSUdURVJNJywgdGhpcy5zdG9wLmJpbmQodGhpcykpO1xuICAgICAgICAgICAgcHJvY2Vzcy5vbignU0lHSU5UJywgdGhpcy5zdG9wLmJpbmQodGhpcykpO1xuICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgbG9nZ2VyLmVycm9yKCdGYWlsZWQgdG8gc3RhcnQgVGVtcGxhdGUgUGxheWdyb3VuZDonLCBlcnJvcik7XG4gICAgICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHB1YmxpYyBzdG9wKCk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2U8dm9pZD4oKHJlc29sdmUpID0+IHtcbiAgICAgICAgICAgIC8vIFJlbW92ZSBzaWduYWwgaGFuZGxlcnMgdG8gcHJldmVudCBtZW1vcnkgbGVha3NcbiAgICAgICAgICAgIGZvciAoY29uc3QgW3NpZ25hbCwgaGFuZGxlcl0gb2YgdGhpcy5zaWduYWxIYW5kbGVycy5lbnRyaWVzKCkpIHtcbiAgICAgICAgICAgICAgICBwcm9jZXNzLnJlbW92ZUxpc3RlbmVyKHNpZ25hbCwgaGFuZGxlcik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLnNpZ25hbEhhbmRsZXJzLmNsZWFyKCk7XG5cbiAgICAgICAgICAgIC8vIENsZWFyIGNsZWFudXAgaW50ZXJ2YWxcbiAgICAgICAgICAgIGlmICh0aGlzLmNsZWFudXBJbnRlcnZhbCkge1xuICAgICAgICAgICAgICAgIGNsZWFySW50ZXJ2YWwodGhpcy5jbGVhbnVwSW50ZXJ2YWwpO1xuICAgICAgICAgICAgICAgIHRoaXMuY2xlYW51cEludGVydmFsID0gbnVsbDtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gQ2xlYXIgYWxsIGRlYm91bmNlIHRpbWVyc1xuICAgICAgICAgICAgZm9yIChjb25zdCB0aW1lciBvZiB0aGlzLmRlYm91bmNlVGltZXJzLnZhbHVlcygpKSB7XG4gICAgICAgICAgICAgICAgY2xlYXJUaW1lb3V0KHRpbWVyKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuZGVib3VuY2VUaW1lcnMuY2xlYXIoKTtcblxuICAgICAgICAgICAgLy8gQ2xlYW4gdXAgYWxsIHNlc3Npb25zXG4gICAgICAgICAgICBmb3IgKGNvbnN0IHNlc3Npb25JZCBvZiB0aGlzLnNlc3Npb25zLmtleXMoKSkge1xuICAgICAgICAgICAgICAgIHRoaXMuY2xlYW51cFNlc3Npb24oc2Vzc2lvbklkKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gR2V0IHRoZSBhY3R1YWwgSFRUUCBzZXJ2ZXIgZnJvbSBQb2xrYSBpbnN0YW5jZVxuICAgICAgICAgICAgY29uc3QgaHR0cFNlcnZlciA9IHRoaXMuc2VydmVyPy5zZXJ2ZXI7XG4gICAgICAgICAgICBcbiAgICAgICAgICAgIGlmIChodHRwU2VydmVyICYmIHR5cGVvZiBodHRwU2VydmVyLmNsb3NlID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICAgICAgbGV0IHJlc29sdmVkID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgXG4gICAgICAgICAgICAgICAgaHR0cFNlcnZlci5jbG9zZSgoZXJyb3IpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFyZXNvbHZlZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9nZ2VyLndhcm4oJ0Vycm9yIGNsb3Npbmcgc2VydmVyOicsIGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9nZ2VyLmluZm8oJ1RlbXBsYXRlIFBsYXlncm91bmQgc2VydmVyIHN0b3BwZWQnKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIFxuICAgICAgICAgICAgICAgIC8vIEZvcmNlIGNsb3NlIGFmdGVyIDEgc2Vjb25kIGlmIGl0IGhhc24ndCBjbG9zZWQgbmF0dXJhbGx5XG4gICAgICAgICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmICghcmVzb2x2ZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmVkID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGxvZ2dlci5pbmZvKCdTZXJ2ZXIgY2xvc2UgdGltZW91dCAtIHJlc29sdmluZyBhbnl3YXknKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0sIDEwMDApO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBsb2dnZXIuaW5mbygnTm8gSFRUUCBzZXJ2ZXIgdG8gY2xvc2Ugb3IgY2xvc2UgbWV0aG9kIG5vdCBhdmFpbGFibGUnKTtcbiAgICAgICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIENsZWFuIHVwIHRlbXBvcmFyeSBmaWxlc1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAvLyBUaGUgY2xlYW51cCBsb2dpYyBmb3Igc2Vzc2lvbnMgaXMgbm93IGhhbmRsZWQgYnkgdGhlIGRlYm91bmNlVGltZXJzXG4gICAgICAgICAgICAgICAgLy8gYW5kIHRoZSBzdGFydFNlc3Npb25DbGVhbnVwIGludGVydmFsLlxuICAgICAgICAgICAgICAgIC8vIFdlIGNhbiByZW1vdmUgdGhlIGRpcmVjdCBjbGVhbnVwIG9mIHRlbXBQcm9qZWN0UGF0aCBhbmQgb3JpZ2luYWxUZW1wbGF0ZXNQYXRoXG4gICAgICAgICAgICAgICAgLy8gYXMgdGhleSBhcmUgbm93IG1hbmFnZWQgd2l0aGluIHNlc3Npb25zLlxuICAgICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICBsb2dnZXIud2FybignRmFpbGVkIHRvIGNsZWFuIHVwIHRlbXBvcmFyeSBmaWxlczonLCBlcnJvcik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cbn1cbiJdLCJuYW1lcyI6WyJfX2F3YWl0ZXIiLCJsb2dnZXIiLCJwYXRoIiwiZnMiLCJjcnlwdG8iLCJvcyIsIl9fdmFsdWVzIiwiZXhlY1N5bmMiLCJfX3JlYWQiLCJfX2Fzc2lnbiIsImh0dHAiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLElBQU0sS0FBSyxHQUFHLE9BQU8sQ0FBQyxPQUFPLENBQUM7QUFDOUIsSUFBTSxJQUFJLEdBQUcsT0FBTyxDQUFDLE1BQU0sQ0FBQztBQUN0QixJQUFBLEVBQUEsR0FBdUIsT0FBTyxDQUFDLGFBQWEsQ0FBQyxFQUEzQyxJQUFJLEdBQUEsRUFBQSxDQUFBLElBQUEsRUFBRSxVQUFVLEdBQUEsRUFBQSxDQUFBLFVBQTJCO0FBQ25ELElBQU0sSUFBSSxHQUFHLE9BQU8sQ0FBQyxrQkFBa0IsQ0FBQztBQVF4QyxJQUFNLFFBQVEsR0FBRyxPQUFPLENBQUMsVUFBVSxDQUFDO0FBeUZwQyxJQUFBLHdCQUFBLGtCQUFBLFlBQUE7QUFhSSxJQUFBLFNBQUEsd0JBQUEsQ0FBWSxJQUFhLEVBQUE7QUFSakIsUUFBQSxJQUFBLENBQUEsUUFBUSxHQUFtQyxJQUFJLEdBQUcsRUFBRTtBQUNwRCxRQUFBLElBQUEsQ0FBQSxhQUFhLEdBQXdCLElBQUksR0FBRyxFQUFFO0FBQzlDLFFBQUEsSUFBQSxDQUFBLGNBQWMsR0FBZ0MsSUFBSSxHQUFHLEVBQUU7QUFJ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LENBQUEsR0FBUCxPQUFPLENBQUUsTUFBTSxNQUFBLElBQUEsSUFBQSxHQUFBLEtBQUEsS0FBQSxDQUFBLEdBQUEsS0FBQSxDQUFBLEdBQUEsR0FBQSxDQUFFLElBQUksS0FBSSxLQUFLO0FBQ3BDLHdCQUFBLEtBQUssRUFBRSxDQUFBLENBQUEsR0FBQSxHQUFBLE9BQU8sS0FBQSxJQUFBLElBQVAsT0FBTyxLQUFBLEtBQUEsQ0FBQSxHQUFBLEtBQUEsQ0FBQSxHQUFQLE9BQU8sQ0FBRSxNQUFNLE1BQUEsSUFBQSxJQUFBLEdBQUEsS0FBQSxLQUFBLENBQUEsR0FBQSxLQUFBLENBQUEsR0FBQSxHQUFBLENBQUUsS0FBSyxLQUFJLEtBQUs7O0FBR3RDLHdCQUFBLFlBQVksRUFBRSxDQUFBLENBQUEsR0FBQSxHQUFBLE9BQU8sS0FBQSxJQUFBLElBQVAsT0FBTyxLQUFBLEtBQUEsQ0FBQSxHQUFBLEtBQUEsQ0FBQSxHQUFQLE9BQU8sQ0FBRSxNQUFNLE1BQUEsSUFBQSxJQUFBLEdBQUEsS0FBQSxLQUFBLENBQUEsR0FBQSxLQUFBLENBQUEsR0FBQSxHQUFBLENBQUUsWUFBWSxLQUFJLE1BQU07O0FBR3JELHdCQUFBLFlBQVksRUFBRSxDQUFBLENBQUEsR0FBQSxHQUFBLE9BQU8sS0FBQSxJQUFBLElBQVAsT0FBTyxLQUFBLEtBQUEsQ0FBQSxHQUFBLEtBQUEsQ0FBQSxHQUFQLE9BQU8sQ0FBRSxNQUFNLE1BQUEsSUFBQSxJQUFBLEdBQUEsS0FBQSxLQUFBLENBQUEsR0FBQSxLQUFBLENBQUEsR0FBQSxHQUFBLENBQUUsWUFBWSxLQUFJLEtBQUs7QUFDcEQsd0JBQUEscUJBQXFCLEVBQUUsQ0FBQSxDQUFBLEdBQUEsR0FBQSxPQUFPLEtBQUEsSUFBQSxJQUFQLE9BQU8sS0FBQSxLQUFBLENBQUEsR0FBQSxLQUFBLENBQUEsR0FBUCxPQUFPLENBQUUsTUFBTSxNQUFBLElBQUEsSUFBQSxHQUFBLEtBQUEsS0FBQSxDQUFBLEdBQUEsS0FBQSxDQUFBLEdBQUEsR0FBQSxDQUFFLHFCQUFxQixLQUFJLEVBQUU7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TUFBQSxJQUFBLElBQUEsRUFBQSxLQUFBLEtBQUEsQ0FBQSxHQUFBLEtBQUEsQ0FBQSxHQUFBLEVBQUEsQ0FBRSxNQUFNLEtBQUksa0JBQWtCO3dCQUNwRCxLQUFLLEVBQUUsQ0FBQSxDQUFBLEVBQUEsR0FBQSxPQUFPLENBQUMsTUFBTSxNQUFBLElBQUEsSUFBQSxFQUFBLEtBQUEsS0FBQSxDQUFBLEdBQUEsS0FBQSxDQUFBLEdBQUEsRUFBQSxDQUFFLEtBQUssS0FBSSxTQUFTO3dCQUN6QyxRQUFRLEVBQUUsQ0FBQSxDQUFBLEVBQUEsR0FBQSxPQUFPLENBQUMsTUFBTSxNQUFBLElBQUEsSUFBQSxFQUFBLEtBQUEsS0FBQSxDQUFBLEdBQUEsS0FBQSxDQUFBLEdBQUEsRUFBQSxDQUFFLFFBQVEsS0FBSSxPQUFPO3dCQUM3QyxJQUFJLEVBQUUsQ0FBQSxDQUFBLEVBQUEsR0FBQSxPQUFPLENBQUMsTUFBTSxNQUFBLElBQUEsSUFBQSxFQUFBLEtBQUEsS0FBQSxDQUFBLEdBQUEsS0FBQSxDQUFBLEdBQUEsRUFBQSxDQUFFLElBQUksS0FBSSxHQUFHOzt3QkFHakMsYUFBYSxFQUFFLENBQUEsQ0FBQSxFQUFBLEdBQUEsT0FBTyxDQUFDLE1BQU0sTUFBQSxJQUFBLElBQUEsRUFBQSxLQUFBLEtBQUEsQ0FBQSxHQUFBLEtBQUEsQ0FBQSxHQUFBLEVBQUEsQ0FBRSxhQUFhLEtBQUksRUFBRTt3QkFDbEQsVUFBVSxFQUFFLENBQUEsQ0FBQSxFQUFBLEdBQUEsT0FBTyxDQUFDLE1BQU0sTUFBQSxJQUFBLElBQUEsRUFBQSxLQUFBLEtBQUEsQ0FBQSxHQUFBLEtBQUEsQ0FBQSxHQUFBLEVBQUEsQ0FBRSxVQUFVLEtBQUksRUFBRTt3QkFDNUMsWUFBWSxFQUFFLENBQUEsQ0FBQSxFQUFBLEdBQUEsT0FBTyxDQUFDLE1BQU0sTUFBQSxJQUFBLElBQUEsRUFBQSxLQUFBLEtBQUEsQ0FBQSxHQUFBLEtBQUEsQ0FBQSxHQUFBLEVBQUEsQ0FBRSxZQUFZLEtBQUksRUFBRTt3QkFDaEQsUUFBUSxFQUFFLENBQUEsQ0FB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
|