Standardize settings file naming and relocate documentation files Fix code quality violations from rsx:check Reorganize user_management directory into logical subdirectories Move Quill Bundle to core and align with Tom Select pattern Simplify Site Settings page to focus on core site information Complete Phase 5: Multi-tenant authentication with login flow and site selection Add route query parameter rule and synchronize filename validation logic Fix critical bug in UpdateNpmCommand causing missing JavaScript stubs Implement filename convention rule and resolve VS Code auto-rename conflict Implement js-sanitizer RPC server to eliminate 900+ Node.js process spawns Implement RPC server architecture for JavaScript parsing WIP: Add RPC server infrastructure for JS parsing (partial implementation) Update jqhtml terminology from destroy to stop, fix datagrid DOM preservation Add JQHTML-CLASS-01 rule and fix redundant class names Improve code quality rules and resolve violations Remove legacy fatal error format in favor of unified 'fatal' error type Filter internal keys from window.rsxapp output Update button styling and comprehensive form/modal documentation Add conditional fly-in animation for modals Fix non-deterministic bundle compilation 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
283 lines
34 KiB
JavaScript
Executable File
283 lines
34 KiB
JavaScript
Executable File
"use strict";
|
|
|
|
function _27e0e986_defineProperty(e, r, t) { return (r = _27e0e986_toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
|
|
function _27e0e986_toPropertyKey(t) { var i = _27e0e986_toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
|
|
function _27e0e986_toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
|
/**
|
|
* Debugger class for console_debug and browser error logging
|
|
* Handles batched submission to server when configured
|
|
*/
|
|
class Debugger {
|
|
/**
|
|
* Initialize framework error handling
|
|
* Called during framework initialization
|
|
*/
|
|
static _on_framework_core_init() {
|
|
// Check if browser error logging is enabled
|
|
if (window.rsxapp && window.rsxapp.log_browser_errors) {
|
|
// Register global error handler
|
|
window.addEventListener('error', function (event) {
|
|
Debugger._handle_browser_error({
|
|
message: event.message,
|
|
filename: event.filename,
|
|
lineno: event.lineno,
|
|
colno: event.colno,
|
|
stack: event.error ? event.error.stack : null,
|
|
type: 'error'
|
|
});
|
|
});
|
|
|
|
// Register unhandled promise rejection handler
|
|
window.addEventListener('unhandledrejection', function (event) {
|
|
Debugger._handle_browser_error({
|
|
message: event.reason ? event.reason.message || String(event.reason) : 'Unhandled promise rejection',
|
|
stack: event.reason && event.reason.stack ? event.reason.stack : null,
|
|
type: 'unhandledrejection'
|
|
});
|
|
});
|
|
}
|
|
|
|
// Register ui refresh handler
|
|
Rsx.on('refresh', Debugger.on_refresh);
|
|
}
|
|
|
|
// In dev mode, some ui elements can be automatically applied to assist with development
|
|
static on_refresh() {
|
|
if (!Rsx.is_prod()) {
|
|
// Add an underline 2 px blue to all a tags with href === "#" using jquery
|
|
// Todo: maybe this should be a configurable debug option?
|
|
// $('a[href="#"]').css({
|
|
// 'border-bottom': '2px solid blue',
|
|
// 'text-decoration': 'none'
|
|
// });
|
|
}
|
|
}
|
|
|
|
/**
|
|
* JavaScript implementation of console_debug
|
|
* Mirrors PHP functionality with batching for Laravel log
|
|
*/
|
|
static console_debug(channel) {
|
|
// Check if console_debug is enabled
|
|
if (!window.rsxapp || !window.rsxapp.console_debug || !window.rsxapp.console_debug.enabled) {
|
|
return;
|
|
}
|
|
const config = window.rsxapp.console_debug;
|
|
|
|
// Normalize channel name
|
|
channel = String(channel).toUpperCase().replace(/[\[\]]/g, '');
|
|
|
|
// Apply filtering
|
|
if (config.filter_mode === 'specific') {
|
|
const specific = config.specific_channel;
|
|
if (specific) {
|
|
// Split comma-separated values and normalize
|
|
const channels = specific.split(',').map(c => c.trim().toUpperCase());
|
|
if (!channels.includes(channel)) {
|
|
return;
|
|
}
|
|
}
|
|
} else if (config.filter_mode === 'whitelist') {
|
|
const whitelist = (config.filter_channels || []).map(c => c.toUpperCase());
|
|
if (!whitelist.includes(channel)) {
|
|
return;
|
|
}
|
|
} else if (config.filter_mode === 'blacklist') {
|
|
const blacklist = (config.filter_channels || []).map(c => c.toUpperCase());
|
|
if (blacklist.includes(channel)) {
|
|
return;
|
|
}
|
|
}
|
|
|
|
// Prepare the message
|
|
for (var _len = arguments.length, values = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
|
|
values[_key - 1] = arguments[_key];
|
|
}
|
|
let message = {
|
|
channel: channel,
|
|
values: values,
|
|
timestamp: new Date().toISOString()
|
|
};
|
|
|
|
// Add location if configured
|
|
if (config.include_location || config.include_backtrace) {
|
|
const error = new Error();
|
|
const stack = error.stack || '';
|
|
const stackLines = stack.split('\n');
|
|
if (config.include_location && stackLines.length > 2) {
|
|
// Skip Error line and this function
|
|
const callerLine = stackLines[2] || '';
|
|
const match = callerLine.match(/at\s+.*?\s+\((.*?):(\d+):(\d+)\)/) || callerLine.match(/at\s+(.*?):(\d+):(\d+)/);
|
|
if (match) {
|
|
message.location = `${match[1]}:${match[2]}`;
|
|
}
|
|
}
|
|
if (config.include_backtrace) {
|
|
// Include first 5 stack frames, skipping this function
|
|
message.backtrace = stackLines.slice(2, 7).map(line => line.trim()).filter(line => line);
|
|
}
|
|
}
|
|
|
|
// Output to browser console if enabled
|
|
if (config.outputs && config.outputs.browser) {
|
|
const prefix = config.include_benchmark ? `[${Debugger._get_time_prefix()}] ` : '';
|
|
const channelPrefix = `[${channel}]`;
|
|
|
|
// Use appropriate console method based on channel
|
|
let consoleMethod = 'log';
|
|
if (channel.includes('ERROR')) consoleMethod = 'error';else if (channel.includes('WARN')) consoleMethod = 'warn';else if (channel.includes('INFO')) consoleMethod = 'info';
|
|
console[consoleMethod](prefix + channelPrefix, ...values);
|
|
}
|
|
|
|
// Batch for Laravel log if enabled
|
|
if (config.outputs && config.outputs.laravel_log) {
|
|
Debugger._batch_console_message(message);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Log an error to the server
|
|
* Used manually or by Ajax error handling
|
|
*/
|
|
static log_error(error) {
|
|
// Check if browser error logging is enabled
|
|
if (!window.rsxapp || !window.rsxapp.log_browser_errors) {
|
|
return;
|
|
}
|
|
|
|
// Normalize error format
|
|
let errorData = {};
|
|
if (typeof error === 'string') {
|
|
errorData.message = error;
|
|
errorData.type = 'manual';
|
|
} else if (error instanceof Error) {
|
|
errorData.message = error.message;
|
|
errorData.stack = error.stack;
|
|
errorData.type = 'exception';
|
|
} else if (error && typeof error === 'object') {
|
|
errorData = error;
|
|
if (!errorData.type) {
|
|
errorData.type = 'manual';
|
|
}
|
|
}
|
|
Debugger._handle_browser_error(errorData);
|
|
}
|
|
|
|
/**
|
|
* Internal: Handle browser errors with batching
|
|
*/
|
|
static _handle_browser_error(errorData) {
|
|
// Check limits
|
|
if (Debugger._error_count >= Debugger.MAX_ERRORS_PER_PAGE) {
|
|
return;
|
|
}
|
|
if (Debugger._error_batch_count >= Debugger.MAX_ERROR_BATCHES) {
|
|
return;
|
|
}
|
|
Debugger._error_count++;
|
|
|
|
// Add metadata
|
|
errorData.url = window.location.href;
|
|
errorData.userAgent = navigator.userAgent;
|
|
errorData.timestamp = new Date().toISOString();
|
|
|
|
// Add to batch
|
|
Debugger._error_batch.push(errorData);
|
|
|
|
// Clear existing timer
|
|
if (Debugger._error_timer) {
|
|
clearTimeout(Debugger._error_timer);
|
|
}
|
|
|
|
// Set debounce timer
|
|
Debugger._error_timer = setTimeout(() => {
|
|
Debugger._flush_error_batch();
|
|
}, Debugger.DEBOUNCE_MS);
|
|
}
|
|
|
|
/**
|
|
* Internal: Batch console_debug messages for Laravel log
|
|
*/
|
|
static _batch_console_message(message) {
|
|
Debugger._console_batch.push(message);
|
|
|
|
// Clear existing timer
|
|
if (Debugger._console_timer) {
|
|
clearTimeout(Debugger._console_timer);
|
|
}
|
|
|
|
// Set debounce timer
|
|
Debugger._console_timer = setTimeout(() => {
|
|
Debugger._flush_console_batch();
|
|
}, Debugger.DEBOUNCE_MS);
|
|
}
|
|
|
|
/**
|
|
* Internal: Flush console_debug batch to server
|
|
*/
|
|
static async _flush_console_batch() {
|
|
if (Debugger._console_batch.length === 0) {
|
|
return;
|
|
}
|
|
const messages = Debugger._console_batch;
|
|
Debugger._console_batch = [];
|
|
Debugger._console_timer = null;
|
|
try {
|
|
return Ajax.call(Rsx.Route('Debugger_Controller', 'log_console_messages'), {
|
|
messages: messages
|
|
});
|
|
} catch (error) {
|
|
// Silently fail - don't create error loop
|
|
console.error('Failed to send console_debug messages to server:', error);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Internal: Flush error batch to server
|
|
*/
|
|
static async _flush_error_batch() {
|
|
if (Debugger._error_batch.length === 0) {
|
|
return;
|
|
}
|
|
const errors = Debugger._error_batch;
|
|
Debugger._error_batch = [];
|
|
Debugger._error_timer = null;
|
|
Debugger._error_batch_count++;
|
|
try {
|
|
return Ajax.call(Rsx.Route('Debugger_Controller', 'log_browser_errors'), {
|
|
errors: errors
|
|
});
|
|
} catch (error) {
|
|
// Silently fail - don't create error loop
|
|
console.error('Failed to send browser errors to server:', error);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Internal: Get time prefix for benchmarking
|
|
*/
|
|
static _get_time_prefix() {
|
|
const now = Date.now();
|
|
if (!Debugger._start_time) {
|
|
Debugger._start_time = now;
|
|
}
|
|
const elapsed = now - Debugger._start_time;
|
|
return (elapsed / 1000).toFixed(3) + 's';
|
|
}
|
|
}
|
|
// Batching state for console_debug messages
|
|
_27e0e986_defineProperty(Debugger, "_console_batch", []);
|
|
_27e0e986_defineProperty(Debugger, "_console_timer", null);
|
|
_27e0e986_defineProperty(Debugger, "_console_batch_count", 0);
|
|
// Batching state for error messages
|
|
_27e0e986_defineProperty(Debugger, "_error_batch", []);
|
|
_27e0e986_defineProperty(Debugger, "_error_timer", null);
|
|
_27e0e986_defineProperty(Debugger, "_error_count", 0);
|
|
_27e0e986_defineProperty(Debugger, "_error_batch_count", 0);
|
|
// Constants
|
|
_27e0e986_defineProperty(Debugger, "DEBOUNCE_MS", 2000);
|
|
_27e0e986_defineProperty(Debugger, "MAX_ERRORS_PER_PAGE", 20);
|
|
_27e0e986_defineProperty(Debugger, "MAX_ERROR_BATCHES", 5);
|
|
// Store start time for benchmarking
|
|
_27e0e986_defineProperty(Debugger, "_start_time", null);
|
|
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJEZWJ1Z2dlciIsIl9vbl9mcmFtZXdvcmtfY29yZV9pbml0Iiwid2luZG93IiwicnN4YXBwIiwibG9nX2Jyb3dzZXJfZXJyb3JzIiwiYWRkRXZlbnRMaXN0ZW5lciIsImV2ZW50IiwiX2hhbmRsZV9icm93c2VyX2Vycm9yIiwibWVzc2FnZSIsImZpbGVuYW1lIiwibGluZW5vIiwiY29sbm8iLCJzdGFjayIsImVycm9yIiwidHlwZSIsInJlYXNvbiIsIlN0cmluZyIsIlJzeCIsIm9uIiwib25fcmVmcmVzaCIsImlzX3Byb2QiLCJjb25zb2xlX2RlYnVnIiwiY2hhbm5lbCIsImVuYWJsZWQiLCJjb25maWciLCJ0b1VwcGVyQ2FzZSIsInJlcGxhY2UiLCJmaWx0ZXJfbW9kZSIsInNwZWNpZmljIiwic3BlY2lmaWNfY2hhbm5lbCIsImNoYW5uZWxzIiwic3BsaXQiLCJtYXAiLCJjIiwidHJpbSIsImluY2x1ZGVzIiwid2hpdGVsaXN0IiwiZmlsdGVyX2NoYW5uZWxzIiwiYmxhY2tsaXN0IiwiX2xlbiIsImFyZ3VtZW50cyIsImxlbmd0aCIsInZhbHVlcyIsIkFycmF5IiwiX2tleSIsInRpbWVzdGFtcCIsIkRhdGUiLCJ0b0lTT1N0cmluZyIsImluY2x1ZGVfbG9jYXRpb24iLCJpbmNsdWRlX2JhY2t0cmFjZSIsIkVycm9yIiwic3RhY2tMaW5lcyIsImNhbGxlckxpbmUiLCJtYXRjaCIsImxvY2F0aW9uIiwiYmFja3RyYWNlIiwic2xpY2UiLCJsaW5lIiwiZmlsdGVyIiwib3V0cHV0cyIsImJyb3dzZXIiLCJwcmVmaXgiLCJpbmNsdWRlX2JlbmNobWFyayIsIl9nZXRfdGltZV9wcmVmaXgiLCJjaGFubmVsUHJlZml4IiwiY29uc29sZU1ldGhvZCIsImNvbnNvbGUiLCJsYXJhdmVsX2xvZyIsIl9iYXRjaF9jb25zb2xlX21lc3NhZ2UiLCJsb2dfZXJyb3IiLCJlcnJvckRhdGEiLCJfZXJyb3JfY291bnQiLCJNQVhfRVJST1JTX1BFUl9QQUdFIiwiX2Vycm9yX2JhdGNoX2NvdW50IiwiTUFYX0VSUk9SX0JBVENIRVMiLCJ1cmwiLCJocmVmIiwidXNlckFnZW50IiwibmF2aWdhdG9yIiwiX2Vycm9yX2JhdGNoIiwicHVzaCIsIl9lcnJvcl90aW1lciIsImNsZWFyVGltZW91dCIsInNldFRpbWVvdXQiLCJfZmx1c2hfZXJyb3JfYmF0Y2giLCJERUJPVU5DRV9NUyIsIl9jb25zb2xlX2JhdGNoIiwiX2NvbnNvbGVfdGltZXIiLCJfZmx1c2hfY29uc29sZV9iYXRjaCIsIm1lc3NhZ2VzIiwiQWpheCIsImNhbGwiLCJSb3V0ZSIsImVycm9ycyIsIm5vdyIsIl9zdGFydF90aW1lIiwiZWxhcHNlZCIsInRvRml4ZWQiLCJfMjdlMGU5ODZfZGVmaW5lUHJvcGVydHkiXSwic291cmNlcyI6WyJhcHAvUlNwYWRlL0NvcmUvSnMvRGVidWdnZXIuanMiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBEZWJ1Z2dlciBjbGFzcyBmb3IgY29uc29sZV9kZWJ1ZyBhbmQgYnJvd3NlciBlcnJvciBsb2dnaW5nXG4gKiBIYW5kbGVzIGJhdGNoZWQgc3VibWlzc2lvbiB0byBzZXJ2ZXIgd2hlbiBjb25maWd1cmVkXG4gKi9cbmNsYXNzIERlYnVnZ2VyIHtcbiAgICAvLyBCYXRjaGluZyBzdGF0ZSBmb3IgY29uc29sZV9kZWJ1ZyBtZXNzYWdlc1xuICAgIHN0YXRpYyBfY29uc29sZV9iYXRjaCA9IFtdO1xuICAgIHN0YXRpYyBfY29uc29sZV90aW1lciA9IG51bGw7XG4gICAgc3RhdGljIF9jb25zb2xlX2JhdGNoX2NvdW50ID0gMDtcblxuICAgIC8vIEJhdGNoaW5nIHN0YXRlIGZvciBlcnJvciBtZXNzYWdlc1xuICAgIHN0YXRpYyBfZXJyb3JfYmF0Y2ggPSBbXTtcbiAgICBzdGF0aWMgX2Vycm9yX3RpbWVyID0gbnVsbDtcbiAgICBzdGF0aWMgX2Vycm9yX2NvdW50ID0gMDtcbiAgICBzdGF0aWMgX2Vycm9yX2JhdGNoX2NvdW50ID0gMDtcblxuICAgIC8vIENvbnN0YW50c1xuICAgIHN0YXRpYyBERUJPVU5DRV9NUyA9IDIwMDA7XG4gICAgc3RhdGljIE1BWF9FUlJPUlNfUEVSX1BBR0UgPSAyMDtcbiAgICBzdGF0aWMgTUFYX0VSUk9SX0JBVENIRVMgPSA1O1xuXG4gICAgLy8gU3RvcmUgc3RhcnQgdGltZSBmb3IgYmVuY2htYXJraW5nXG4gICAgc3RhdGljIF9zdGFydF90aW1lID0gbnVsbDtcblxuICAgIC8qKlxuICAgICAqIEluaXRpYWxpemUgZnJhbWV3b3JrIGVycm9yIGhhbmRsaW5nXG4gICAgICogQ2FsbGVkIGR1cmluZyBmcmFtZXdvcmsgaW5pdGlhbGl6YXRpb25cbiAgICAgKi9cbiAgICBzdGF0aWMgX29uX2ZyYW1ld29ya19jb3JlX2luaXQoKSB7XG4gICAgICAgIC8vIENoZWNrIGlmIGJyb3dzZXIgZXJyb3IgbG9nZ2luZyBpcyBlbmFibGVkXG4gICAgICAgIGlmICh3aW5kb3cucnN4YXBwICYmIHdpbmRvdy5yc3hhcHAubG9nX2Jyb3dzZXJfZXJyb3JzKSB7XG4gICAgICAgICAgICAvLyBSZWdpc3RlciBnbG9iYWwgZXJyb3IgaGFuZGxlclxuICAgICAgICAgICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ2Vycm9yJywgZnVuY3Rpb24gKGV2ZW50KSB7XG4gICAgICAgICAgICAgICAgRGVidWdnZXIuX2hhbmRsZV9icm93c2VyX2Vycm9yKHtcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZTogZXZlbnQubWVzc2FnZSxcbiAgICAgICAgICAgICAgICAgICAgZmlsZW5hbWU6IGV2ZW50LmZpbGVuYW1lLFxuICAgICAgICAgICAgICAgICAgICBsaW5lbm86IGV2ZW50LmxpbmVubyxcbiAgICAgICAgICAgICAgICAgICAgY29sbm86IGV2ZW50LmNvbG5vLFxuICAgICAgICAgICAgICAgICAgICBzdGFjazogZXZlbnQuZXJyb3IgPyBldmVudC5lcnJvci5zdGFjayA6IG51bGwsXG4gICAgICAgICAgICAgICAgICAgIHR5cGU6ICdlcnJvcicsXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgLy8gUmVnaXN0ZXIgdW5oYW5kbGVkIHByb21pc2UgcmVqZWN0aW9uIGhhbmRsZXJcbiAgICAgICAgICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCd1bmhhbmRsZWRyZWplY3Rpb24nLCBmdW5jdGlvbiAoZXZlbnQpIHtcbiAgICAgICAgICAgICAgICBEZWJ1Z2dlci5faGFuZGxlX2Jyb3dzZXJfZXJyb3Ioe1xuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlOiBldmVudC5yZWFzb24gPyBldmVudC5yZWFzb24ubWVzc2FnZSB8fCBTdHJpbmcoZXZlbnQucmVhc29uKSA6ICdVbmhhbmRsZWQgcHJvbWlzZSByZWplY3Rpb24nLFxuICAgICAgICAgICAgICAgICAgICBzdGFjazogZXZlbnQucmVhc29uICYmIGV2ZW50LnJlYXNvbi5zdGFjayA/IGV2ZW50LnJlYXNvbi5zdGFjayA6IG51bGwsXG4gICAgICAgICAgICAgICAgICAgIHR5cGU6ICd1bmhhbmRsZWRyZWplY3Rpb24nLFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBSZWdpc3RlciB1aSByZWZyZXNoIGhhbmRsZXJcbiAgICAgICAgUnN4Lm9uKCdyZWZyZXNoJywgRGVidWdnZXIub25fcmVmcmVzaCk7XG4gICAgfVxuXG4gICAgLy8gSW4gZGV2IG1vZGUsIHNvbWUgdWkgZWxlbWVudHMgY2FuIGJlIGF1dG9tYXRpY2FsbHkgYXBwbGllZCB0byBhc3Npc3Qgd2l0aCBkZXZlbG9wbWVudFxuICAgIHN0YXRpYyBvbl9yZWZyZXNoKCkge1xuICAgICAgICBpZiAoIVJzeC5pc19wcm9kKCkpIHtcbiAgICAgICAgICAgIC8vIEFkZCBhbiB1bmRlcmxpbmUgMiBweCBibHVlIHRvIGFsbCBhIHRhZ3Mgd2l0aCBocmVmID09PSBcIiNcIiB1c2luZyBqcXVlcnlcbiAgICAgICAgICAgIC8vIFRvZG86IG1heWJlIHRoaXMgc2hvdWxkIGJlIGEgY29uZmlndXJhYmxlIGRlYnVnIG9wdGlvbj9cbiAgICAgICAgICAgIC8vICQoJ2FbaHJlZj1cIiNcIl0nKS5jc3Moe1xuICAgICAgICAgICAgLy8gICAgICdib3JkZXItYm90dG9tJzogJzJweCBzb2xpZCBibHVlJyxcbiAgICAgICAgICAgIC8vICAgICAndGV4dC1kZWNvcmF0aW9uJzogJ25vbmUnXG4gICAgICAgICAgICAvLyB9KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEphdmFTY3JpcHQgaW1wbGVtZW50YXRpb24gb2YgY29uc29sZV9kZWJ1Z1xuICAgICAqIE1pcnJvcnMgUEhQIGZ1bmN0aW9uYWxpdHkgd2l0aCBiYXRjaGluZyBmb3IgTGFyYXZlbCBsb2dcbiAgICAgKi9cbiAgICBzdGF0aWMgY29uc29sZV9kZWJ1ZyhjaGFubmVsLCAuLi52YWx1ZXMpIHtcbiAgICAgICAgLy8gQ2hlY2sgaWYgY29uc29sZV9kZWJ1ZyBpcyBlbmFibGVkXG4gICAgICAgIGlmICghd2luZG93LnJzeGFwcCB8fCAhd2luZG93LnJzeGFwcC5jb25zb2xlX2RlYnVnIHx8ICF3aW5kb3cucnN4YXBwLmNvbnNvbGVfZGVidWcuZW5hYmxlZCkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgY29uZmlnID0gd2luZG93LnJzeGFwcC5jb25zb2xlX2RlYnVnO1xuXG4gICAgICAgIC8vIE5vcm1hbGl6ZSBjaGFubmVsIG5hbWVcbiAgICAgICAgY2hhbm5lbCA9IFN0cmluZyhjaGFubmVsKVxuICAgICAgICAgICAgLnRvVXBwZXJDYXNlKClcbiAgICAgICAgICAgIC5yZXBsYWNlKC9bXFxbXFxdXS9nLCAnJyk7XG5cbiAgICAgICAgLy8gQXBwbHkgZmlsdGVyaW5nXG4gICAgICAgIGlmIChjb25maWcuZmlsdGVyX21vZGUgPT09ICdzcGVjaWZpYycpIHtcbiAgICAgICAgICAgIGNvbnN0IHNwZWNpZmljID0gY29uZmlnLnNwZWNpZmljX2NoYW5uZWw7XG4gICAgICAgICAgICBpZiAoc3BlY2lmaWMpIHtcbiAgICAgICAgICAgICAgICAvLyBTcGxpdCBjb21tYS1zZXBhcmF0ZWQgdmFsdWVzIGFuZCBub3JtYWxpemVcbiAgICAgICAgICAgICAgICBjb25zdCBjaGFubmVscyA9IHNwZWNpZmljLnNwbGl0KCcsJykubWFwKChjKSA9PiBjLnRyaW0oKS50b1VwcGVyQ2FzZSgpKTtcbiAgICAgICAgICAgICAgICBpZiAoIWNoYW5uZWxzLmluY2x1ZGVzKGNoYW5uZWwpKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSBpZiAoY29uZmlnLmZpbHRlcl9tb2RlID09PSAnd2hpdGVsaXN0Jykge1xuICAgICAgICAgICAgY29uc3Qgd2hpdGVsaXN0ID0gKGNvbmZpZy5maWx0ZXJfY2hhbm5lbHMgfHwgW10pLm1hcCgoYykgPT4gYy50b1VwcGVyQ2FzZSgpKTtcbiAgICAgICAgICAgIGlmICghd2hpdGVsaXN0LmluY2x1ZGVzKGNoYW5uZWwpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2UgaWYgKGNvbmZpZy5maWx0ZXJfbW9kZSA9PT0gJ2JsYWNrbGlzdCcpIHtcbiAgICAgICAgICAgIGNvbnN0IGJsYWNrbGlzdCA9IChjb25maWcuZmlsdGVyX2NoYW5uZWxzIHx8IFtdKS5tYXAoKGMpID0+IGMudG9VcHBlckNhc2UoKSk7XG4gICAgICAgICAgICBpZiAoYmxhY2tsaXN0LmluY2x1ZGVzKGNoYW5uZWwpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gUHJlcGFyZSB0aGUgbWVzc2FnZVxuICAgICAgICBsZXQgbWVzc2FnZSA9IHtcbiAgICAgICAgICAgIGNoYW5uZWw6IGNoYW5uZWwsXG4gICAgICAgICAgICB2YWx1ZXM6IHZhbHVlcyxcbiAgICAgICAgICAgIHRpbWVzdGFtcDogbmV3IERhdGUoKS50b0lTT1N0cmluZygpLFxuICAgICAgICB9O1xuXG4gICAgICAgIC8vIEFkZCBsb2NhdGlvbiBpZiBjb25maWd1cmVkXG4gICAgICAgIGlmIChjb25maWcuaW5jbHVkZV9sb2NhdGlvbiB8fCBjb25maWcuaW5jbHVkZV9iYWNrdHJhY2UpIHtcbiAgICAgICAgICAgIGNvbnN0IGVycm9yID0gbmV3IEVycm9yKCk7XG4gICAgICAgICAgICBjb25zdCBzdGFjayA9IGVycm9yLnN0YWNrIHx8ICcnO1xuICAgICAgICAgICAgY29uc3Qgc3RhY2tMaW5lcyA9IHN0YWNrLnNwbGl0KCdcXG4nKTtcblxuICAgICAgICAgICAgaWYgKGNvbmZpZy5pbmNsdWRlX2xvY2F0aW9uICYmIHN0YWNrTGluZXMubGVuZ3RoID4gMikge1xuICAgICAgICAgICAgICAgIC8vIFNraXAgRXJyb3IgbGluZSBhbmQgdGhpcyBmdW5jdGlvblxuICAgICAgICAgICAgICAgIGNvbnN0IGNhbGxlckxpbmUgPSBzdGFja0xpbmVzWzJdIHx8ICcnO1xuICAgICAgICAgICAgICAgIGNvbnN0IG1hdGNoID0gY2FsbGVyTGluZS5tYXRjaCgvYXRcXHMrLio/XFxzK1xcKCguKj8pOihcXGQrKTooXFxkKylcXCkvKSB8fCBjYWxsZXJMaW5lLm1hdGNoKC9hdFxccysoLio/KTooXFxkKyk6KFxcZCspLyk7XG4gICAgICAgICAgICAgICAgaWYgKG1hdGNoKSB7XG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UubG9jYXRpb24gPSBgJHttYXRjaFsxXX06JHttYXRjaFsyXX1gO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKGNvbmZpZy5pbmNsdWRlX2JhY2t0cmFjZSkge1xuICAgICAgICAgICAgICAgIC8vIEluY2x1ZGUgZmlyc3QgNSBzdGFjayBmcmFtZXMsIHNraXBwaW5nIHRoaXMgZnVuY3Rpb25cbiAgICAgICAgICAgICAgICBtZXNzYWdlLmJhY2t0cmFjZSA9IHN0YWNrTGluZXNcbiAgICAgICAgICAgICAgICAgICAgLnNsaWNlKDIsIDcpXG4gICAgICAgICAgICAgICAgICAgIC5tYXAoKGxpbmUpID0+IGxpbmUudHJpbSgpKVxuICAgICAgICAgICAgICAgICAgICAuZmlsdGVyKChsaW5lKSA9PiBsaW5lKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIC8vIE91dHB1dCB0byBicm93c2VyIGNvbnNvbGUgaWYgZW5hYmxlZFxuICAgICAgICBpZiAoY29uZmlnLm91dHB1dHMgJiYgY29uZmlnLm91dHB1dHMuYnJvd3Nlcikge1xuICAgICAgICAgICAgY29uc3QgcHJlZml4ID0gY29uZmlnLmluY2x1ZGVfYmVuY2htYXJrID8gYFske0RlYnVnZ2VyLl9nZXRfdGltZV9wcmVmaXgoKX1dIGAgOiAnJztcbiAgICAgICAgICAgIGNvbnN0IGNoYW5uZWxQcmVmaXggPSBgWyR7Y2hhbm5lbH1dYDtcblxuICAgICAgICAgICAgLy8gVXNlIGFwcHJvcHJpYXRlIGNvbnNvbGUgbWV0aG9kIGJhc2VkIG9uIGNoYW5uZWxcbiAgICAgICAgICAgIGxldCBjb25zb2xlTWV0aG9kID0gJ2xvZyc7XG4gICAgICAgICAgICBpZiAoY2hhbm5lbC5pbmNsdWRlcygnRVJST1InKSkgY29uc29sZU1ldGhvZCA9ICdlcnJvcic7XG4gICAgICAgICAgICBlbHNlIGlmIChjaGFubmVsLmluY2x1ZGVzKCdXQVJOJykpIGNvbnNvbGVNZXRob2QgPSAnd2Fybic7XG4gICAgICAgICAgICBlbHNlIGlmIChjaGFubmVsLmluY2x1ZGVzKCdJTkZPJykpIGNvbnNvbGVNZXRob2QgPSAnaW5mbyc7XG5cbiAgICAgICAgICAgIGNvbnNvbGVbY29uc29sZU1ldGhvZF0ocHJlZml4ICsgY2hhbm5lbFByZWZpeCwgLi4udmFsdWVzKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIEJhdGNoIGZvciBMYXJhdmVsIGxvZyBpZiBlbmFibGVkXG4gICAgICAgIGlmIChjb25maWcub3V0cHV0cyAmJiBjb25maWcub3V0cHV0cy5sYXJhdmVsX2xvZykge1xuICAgICAgICAgICAgRGVidWdnZXIuX2JhdGNoX2NvbnNvbGVfbWVzc2FnZShtZXNzYWdlKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIExvZyBhbiBlcnJvciB0byB0aGUgc2VydmVyXG4gICAgICogVXNlZCBtYW51YWxseSBvciBieSBBamF4IGVycm9yIGhhbmRsaW5nXG4gICAgICovXG4gICAgc3RhdGljIGxvZ19lcnJvcihlcnJvcikge1xuICAgICAgICAvLyBDaGVjayBpZiBicm93c2VyIGVycm9yIGxvZ2dpbmcgaXMgZW5hYmxlZFxuICAgICAgICBpZiAoIXdpbmRvdy5yc3hhcHAgfHwgIXdpbmRvdy5yc3hhcHAubG9nX2Jyb3dzZXJfZXJyb3JzKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICAvLyBOb3JtYWxpemUgZXJyb3IgZm9ybWF0XG4gICAgICAgIGxldCBlcnJvckRhdGEgPSB7fTtcbiAgICAgICAgaWYgKHR5cGVvZiBlcnJvciA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgIGVycm9yRGF0YS5tZXNzYWdlID0gZXJyb3I7XG4gICAgICAgICAgICBlcnJvckRhdGEudHlwZSA9ICdtYW51YWwnO1xuICAgICAgICB9IGVsc2UgaWYgKGVycm9yIGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgICAgICAgIGVycm9yRGF0YS5tZXNzYWdlID0gZXJyb3IubWVzc2FnZTtcbiAgICAgICAgICAgIGVycm9yRGF0YS5zdGFjayA9IGVycm9yLnN0YWNrO1xuICAgICAgICAgICAgZXJyb3JEYXRhLnR5cGUgPSAnZXhjZXB0aW9uJztcbiAgICAgICAgfSBlbHNlIGlmIChlcnJvciAmJiB0eXBlb2YgZXJyb3IgPT09ICdvYmplY3QnKSB7XG4gICAgICAgICAgICBlcnJvckRhdGEgPSBlcnJvcjtcbiAgICAgICAgICAgIGlmICghZXJyb3JEYXRhLnR5cGUpIHtcbiAgICAgICAgICAgICAgICBlcnJvckRhdGEudHlwZSA9ICdtYW51YWwnO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgRGVidWdnZXIuX2hhbmRsZV9icm93c2VyX2Vycm9yKGVycm9yRGF0YSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogSW50ZXJuYWw6IEhhbmRsZSBicm93c2VyIGVycm9ycyB3aXRoIGJhdGNoaW5nXG4gICAgICovXG4gICAgc3RhdGljIF9oYW5kbGVfYnJvd3Nlcl9lcnJvcihlcnJvckRhdGEpIHtcbiAgICAgICAgLy8gQ2hlY2sgbGltaXRzXG4gICAgICAgIGlmIChEZWJ1Z2dlci5fZXJyb3JfY291bnQgPj0gRGVidWdnZXIuTUFYX0VSUk9SU19QRVJfUEFHRSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGlmIChEZWJ1Z2dlci5fZXJyb3JfYmF0Y2hfY291bnQgPj0gRGVidWdnZXIuTUFYX0VSUk9SX0JBVENIRVMpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIERlYnVnZ2VyLl9lcnJvcl9jb3VudCsrO1xuXG4gICAgICAgIC8vIEFkZCBtZXRhZGF0YVxuICAgICAgICBlcnJvckRhdGEudXJsID0gd2luZG93LmxvY2F0aW9uLmhyZWY7XG4gICAgICAgIGVycm9yRGF0YS51c2VyQWdlbnQgPSBuYXZpZ2F0b3IudXNlckFnZW50O1xuICAgICAgICBlcnJvckRhdGEudGltZXN0YW1wID0gbmV3IERhdGUoKS50b0lTT1N0cmluZygpO1xuXG4gICAgICAgIC8vIEFkZCB0byBiYXRjaFxuICAgICAgICBEZWJ1Z2dlci5fZXJyb3JfYmF0Y2gucHVzaChlcnJvckRhdGEpO1xuXG4gICAgICAgIC8vIENsZWFyIGV4aXN0aW5nIHRpbWVyXG4gICAgICAgIGlmIChEZWJ1Z2dlci5fZXJyb3JfdGltZXIpIHtcbiAgICAgICAgICAgIGNsZWFyVGltZW91dChEZWJ1Z2dlci5fZXJyb3JfdGltZXIpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gU2V0IGRlYm91bmNlIHRpbWVyXG4gICAgICAgIERlYnVnZ2VyLl9lcnJvcl90aW1lciA9IHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgRGVidWdnZXIuX2ZsdXNoX2Vycm9yX2JhdGNoKCk7XG4gICAgICAgIH0sIERlYnVnZ2VyLkRFQk9VTkNFX01TKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBJbnRlcm5hbDogQmF0Y2ggY29uc29sZV9kZWJ1ZyBtZXNzYWdlcyBmb3IgTGFyYXZlbCBsb2dcbiAgICAgKi9cbiAgICBzdGF0aWMgX2JhdGNoX2NvbnNvbGVfbWVzc2FnZShtZXNzYWdlKSB7XG4gICAgICAgIERlYnVnZ2VyLl9jb25zb2xlX2JhdGNoLnB1c2gobWVzc2FnZSk7XG5cbiAgICAgICAgLy8gQ2xlYXIgZXhpc3RpbmcgdGltZXJcbiAgICAgICAgaWYgKERlYnVnZ2VyLl9jb25zb2xlX3RpbWVyKSB7XG4gICAgICAgICAgICBjbGVhclRpbWVvdXQoRGVidWdnZXIuX2NvbnNvbGVfdGltZXIpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gU2V0IGRlYm91bmNlIHRpbWVyXG4gICAgICAgIERlYnVnZ2VyLl9jb25zb2xlX3RpbWVyID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICBEZWJ1Z2dlci5fZmx1c2hfY29uc29sZV9iYXRjaCgpO1xuICAgICAgICB9LCBEZWJ1Z2dlci5ERUJPVU5DRV9NUyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogSW50ZXJuYWw6IEZsdXNoIGNvbnNvbGVfZGVidWcgYmF0Y2ggdG8gc2VydmVyXG4gICAgICovXG4gICAgc3RhdGljIGFzeW5jIF9mbHVzaF9jb25zb2xlX2JhdGNoKCkge1xuICAgICAgICBpZiAoRGVidWdnZXIuX2NvbnNvbGVfYmF0Y2gubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBtZXNzYWdlcyA9IERlYnVnZ2VyLl9jb25zb2xlX2JhdGNoO1xuICAgICAgICBEZWJ1Z2dlci5fY29uc29sZV9iYXRjaCA9IFtdO1xuICAgICAgICBEZWJ1Z2dlci5fY29uc29sZV90aW1lciA9IG51bGw7XG5cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHJldHVybiBBamF4LmNhbGwoUnN4LlJvdXRlKCdEZWJ1Z2dlcl9Db250cm9sbGVyJywgJ2xvZ19jb25zb2xlX21lc3NhZ2VzJyksIHsgbWVzc2FnZXM6IG1lc3NhZ2VzIH0pO1xuICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgLy8gU2lsZW50bHkgZmFpbCAtIGRvbid0IGNyZWF0ZSBlcnJvciBsb29wXG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKCdGYWlsZWQgdG8gc2VuZCBjb25zb2xlX2RlYnVnIG1lc3NhZ2VzIHRvIHNlcnZlcjonLCBlcnJvcik7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBJbnRlcm5hbDogRmx1c2ggZXJyb3IgYmF0Y2ggdG8gc2VydmVyXG4gICAgICovXG4gICAgc3RhdGljIGFzeW5jIF9mbHVzaF9lcnJvcl9iYXRjaCgpIHtcbiAgICAgICAgaWYgKERlYnVnZ2VyLl9lcnJvcl9iYXRjaC5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGVycm9ycyA9IERlYnVnZ2VyLl9lcnJvcl9iYXRjaDtcbiAgICAgICAgRGVidWdnZXIuX2Vycm9yX2JhdGNoID0gW107XG4gICAgICAgIERlYnVnZ2VyLl9lcnJvcl90aW1lciA9IG51bGw7XG4gICAgICAgIERlYnVnZ2VyLl9lcnJvcl9iYXRjaF9jb3VudCsrO1xuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICByZXR1cm4gQWpheC5jYWxsKFJzeC5Sb3V0ZSgnRGVidWdnZXJfQ29udHJvbGxlcicsICdsb2dfYnJvd3Nlcl9lcnJvcnMnKSwgeyBlcnJvcnM6IGVycm9ycyB9KTtcbiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgIC8vIFNpbGVudGx5IGZhaWwgLSBkb24ndCBjcmVhdGUgZXJyb3IgbG9vcFxuICAgICAgICAgICAgY29uc29sZS5lcnJvcignRmFpbGVkIHRvIHNlbmQgYnJvd3NlciBlcnJvcnMgdG8gc2VydmVyOicsIGVycm9yKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEludGVybmFsOiBHZXQgdGltZSBwcmVmaXggZm9yIGJlbmNobWFya2luZ1xuICAgICAqL1xuICAgIHN0YXRpYyBfZ2V0X3RpbWVfcHJlZml4KCkge1xuICAgICAgICBjb25zdCBub3cgPSBEYXRlLm5vdygpO1xuICAgICAgICBpZiAoIURlYnVnZ2VyLl9zdGFydF90aW1lKSB7XG4gICAgICAgICAgICBEZWJ1Z2dlci5fc3RhcnRfdGltZSA9IG5vdztcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBlbGFwc2VkID0gbm93IC0gRGVidWdnZXIuX3N0YXJ0X3RpbWU7XG4gICAgICAgIHJldHVybiAoZWxhcHNlZCAvIDEwMDApLnRvRml4ZWQoMykgKyAncyc7XG4gICAgfVxufVxuIl0sIm1hcHBpbmdzIjoiOzs7OztBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTUEsUUFBUSxDQUFDO0VBb0JYO0FBQ0o7QUFDQTtBQUNBO0VBQ0ksT0FBT0MsdUJBQXVCQSxDQUFBLEVBQUc7SUFDN0I7SUFDQSxJQUFJQyxNQUFNLENBQUNDLE1BQU0sSUFBSUQsTUFBTSxDQUFDQyxNQUFNLENBQUNDLGtCQUFrQixFQUFFO01BQ25EO01BQ0FGLE1BQU0sQ0FBQ0csZ0JBQWdCLENBQUMsT0FBTyxFQUFFLFVBQVVDLEtBQUssRUFBRTtRQUM5Q04sUUFBUSxDQUFDTyxxQkFBcUIsQ0FBQztVQUMzQkMsT0FBTyxFQUFFRixLQUFLLENBQUNFLE9BQU87VUFDdEJDLFFBQVEsRUFBRUgsS0FBSyxDQUFDRyxRQUFRO1VB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
|