Files
rspade_system/storage-broken/rsx-tmp/babel_cache/1394fe2f02b002663ff290d59449f6ef_modern.js
root 77b4d10af8 Refactor filename naming system and apply convention-based renames
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>
2025-11-13 19:10:02 +00:00

248 lines
28 KiB
JavaScript
Executable File

"use strict";
/**
* Currency_Input
*
* Extends Text_Input to provide automatic currency formatting.
*
* Features:
* - Adds thousands separators (commas) every 3 digits
* - Optional currency symbol prefix (default: hidden)
* - Optional decimal support (default: disabled)
* - Smart backspace over formatting characters
* - No mid-string formatting (waits for blur)
*
* Arguments:
* - $allow_decimals - Allow 2 decimal places (default: false)
* - $show_symbol - Show currency symbol (default: false)
* - $currency_symbol - Currency symbol to use (default: "$")
*
* Usage:
* <Currency_Input />
* <Currency_Input $show_symbol=true />
* <Currency_Input $allow_decimals=true />
* <Currency_Input $show_symbol=true $allow_decimals=true $currency_symbol="€" />
*
* Behavior:
* - Type "1234567" -> displays "1,234,567", val() returns "1234567"
* - Type "1234567.89" (with decimals) -> displays "1,234,567.89", val() returns "1234567.89"
* - With symbol: displays "$1,234,567", val() still returns "1234567"
*/
class Currency_Input extends Text_Input {
on_create() {
super.on_create();
// Set defaults for options
if (this.args.allow_decimals === undefined) {
this.args.allow_decimals = false;
}
if (this.args.show_symbol === undefined) {
this.args.show_symbol = false;
}
if (this.args.currency_symbol === undefined) {
this.args.currency_symbol = '$';
}
}
/**
* Format currency with commas and optional symbol
* @param {string} value - Numeric value (may include decimal)
* @returns {string} Formatted currency string
*/
_format_currency(value) {
if (!value) {
return '';
}
// Split into integer and decimal parts
let parts = value.split('.');
let integer_part = parts[0];
let decimal_part = parts[1];
// Add commas to integer part
integer_part = integer_part.replace(/\B(?=(\d{3})+(?!\d))/g, ',');
// Reconstruct with decimal if allowed
let formatted = integer_part;
if (this.args.allow_decimals && decimal_part !== undefined) {
// Limit to 2 decimal places
decimal_part = decimal_part.substr(0, 2);
formatted += '.' + decimal_part;
}
// Add currency symbol if enabled
if (this.args.show_symbol) {
formatted = this.args.currency_symbol + formatted;
}
return formatted;
}
/**
* Extract numeric value from formatted string
* @param {string} formatted - Formatted currency string
* @returns {string} Clean numeric value (digits and decimal only)
*/
_get_numeric_value(formatted) {
if (!formatted) {
return '';
}
// Remove currency symbol and commas
let cleaned = formatted.replace(/[^0-9.]/g, '');
// Ensure only one decimal point
const decimal_count = (cleaned.match(/\./g) || []).length;
if (decimal_count > 1) {
// Keep only first decimal point
const first_decimal = cleaned.indexOf('.');
cleaned = cleaned.substr(0, first_decimal + 1) + cleaned.substr(first_decimal + 1).replace(/\./g, '');
}
return cleaned;
}
/**
* val() - Get or set the currency value
* Getter returns numeric string (no commas, no symbol)
* Setter accepts anything and formats with commas/symbol
* @param {string} [value]
* @returns {string}
*/
val(value) {
if (arguments.length === 0) {
// Getter - return numeric value only
const raw = this.$id('input').val();
return this._get_numeric_value(raw);
} else {
// Setter - format and display
if (!value) {
this.data.value = '';
if (this.$id('input').exists()) {
this.$id('input').val('');
}
return;
}
// Clean the input value
const numeric = this._get_numeric_value(str(value));
const formatted = this._format_currency(numeric);
this.data.value = formatted;
if (this.$id('input').exists()) {
this.$id('input').val(formatted);
}
}
}
on_ready() {
super.on_ready();
const $input = this.$id('input');
// Handle keydown to intercept backspace at end of string
$input.on('keydown', e => {
const raw = $input.val();
// Only handle backspace key
if (e.key !== 'Backspace') {
return;
}
const input_element = $input[0];
const cursor_pos = input_element.selectionStart;
const cursor_end = input_element.selectionEnd;
const value_length = raw.length;
// Only handle if cursor is at the end and no selection
if (cursor_pos === value_length && cursor_pos === cursor_end) {
// Check if character before cursor is non-numeric
if (cursor_pos > 0) {
const char_before = raw.charAt(cursor_pos - 1);
if (!/[0-9]/.test(char_before)) {
// Character before cursor is not a digit
// Delete the last digit instead
e.preventDefault();
const numeric = this._get_numeric_value(raw);
if (numeric.length > 0) {
// Remove last character from numeric value
const new_numeric = numeric.substr(0, numeric.length - 1);
const formatted = this._format_currency(new_numeric);
$input.val(formatted);
// Place cursor at end
setTimeout(() => {
const new_length = $input.val().length;
input_element.setSelectionRange(new_length, new_length);
}, 0);
}
}
}
}
});
// Handle input event for live formatting
$input.on('input', () => {
const raw = $input.val();
const input_element = $input[0];
const cursor_pos = input_element.selectionStart;
const value_length = raw.length;
// Only apply live formatting if cursor is at the end
if (cursor_pos === value_length) {
// Extract numeric value
let numeric = this._get_numeric_value(raw);
// Limit decimal places to 2 if decimals allowed
if (this.args.allow_decimals) {
const parts = numeric.split('.');
if (parts[1] && parts[1].length > 2) {
numeric = parts[0] + '.' + parts[1].substr(0, 2);
}
}
// Format the numeric value
const formatted = this._format_currency(numeric);
$input.val(formatted);
} else {
// Cursor is not at end - user is editing in the middle
// Don't format, just clean invalid characters
const numeric = this._get_numeric_value(raw);
// Only update if we removed invalid characters
if (this._format_currency(numeric) !== raw) {
// Preserve just the numeric characters
const symbol_offset = this.args.show_symbol ? this.args.currency_symbol.length : 0;
const cleaned = (this.args.show_symbol ? this.args.currency_symbol : '') + numeric;
if (cleaned !== raw) {
$input.val(cleaned);
// Restore cursor position (approximately)
const new_cursor = Math.min(cursor_pos, cleaned.length);
input_element.setSelectionRange(new_cursor, new_cursor);
}
}
}
});
// Handle blur to reformat when done editing
$input.on('blur', () => {
const raw = $input.val();
if (!raw) {
return;
}
// Reformat the entire value on blur
const numeric = this._get_numeric_value(raw);
const formatted = this._format_currency(numeric);
$input.val(formatted);
});
// Handle focus to select all for easy replacement
$input.on('focus', () => {
setTimeout(() => {
$input[0].select();
}, 0);
});
// Initialize formatting if there's a value
const initial_value = $input.val();
if (initial_value) {
this.val(initial_value);
}
}
}
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJDdXJyZW5jeV9JbnB1dCIsIlRleHRfSW5wdXQiLCJvbl9jcmVhdGUiLCJhcmdzIiwiYWxsb3dfZGVjaW1hbHMiLCJ1bmRlZmluZWQiLCJzaG93X3N5bWJvbCIsImN1cnJlbmN5X3N5bWJvbCIsIl9mb3JtYXRfY3VycmVuY3kiLCJ2YWx1ZSIsInBhcnRzIiwic3BsaXQiLCJpbnRlZ2VyX3BhcnQiLCJkZWNpbWFsX3BhcnQiLCJyZXBsYWNlIiwiZm9ybWF0dGVkIiwic3Vic3RyIiwiX2dldF9udW1lcmljX3ZhbHVlIiwiY2xlYW5lZCIsImRlY2ltYWxfY291bnQiLCJtYXRjaCIsImxlbmd0aCIsImZpcnN0X2RlY2ltYWwiLCJpbmRleE9mIiwidmFsIiwiYXJndW1lbnRzIiwicmF3IiwiJGlkIiwiZGF0YSIsImV4aXN0cyIsIm51bWVyaWMiLCJzdHIiLCJvbl9yZWFkeSIsIiRpbnB1dCIsIm9uIiwiZSIsImtleSIsImlucHV0X2VsZW1lbnQiLCJjdXJzb3JfcG9zIiwic2VsZWN0aW9uU3RhcnQiLCJjdXJzb3JfZW5kIiwic2VsZWN0aW9uRW5kIiwidmFsdWVfbGVuZ3RoIiwiY2hhcl9iZWZvcmUiLCJjaGFyQXQiLCJ0ZXN0IiwicHJldmVudERlZmF1bHQiLCJuZXdfbnVtZXJpYyIsInNldFRpbWVvdXQiLCJuZXdfbGVuZ3RoIiwic2V0U2VsZWN0aW9uUmFuZ2UiLCJzeW1ib2xfb2Zmc2V0IiwibmV3X2N1cnNvciIsIk1hdGgiLCJtaW4iLCJzZWxlY3QiLCJpbml0aWFsX3ZhbHVlIl0sInNvdXJjZXMiOlsicnN4L3RoZW1lL2NvbXBvbmVudHMvaW5wdXRzL2N1cnJlbmN5X2lucHV0LmpzIl0sInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQ3VycmVuY3lfSW5wdXRcbiAqXG4gKiBFeHRlbmRzIFRleHRfSW5wdXQgdG8gcHJvdmlkZSBhdXRvbWF0aWMgY3VycmVuY3kgZm9ybWF0dGluZy5cbiAqXG4gKiBGZWF0dXJlczpcbiAqIC0gQWRkcyB0aG91c2FuZHMgc2VwYXJhdG9ycyAoY29tbWFzKSBldmVyeSAzIGRpZ2l0c1xuICogLSBPcHRpb25hbCBjdXJyZW5jeSBzeW1ib2wgcHJlZml4IChkZWZhdWx0OiBoaWRkZW4pXG4gKiAtIE9wdGlvbmFsIGRlY2ltYWwgc3VwcG9ydCAoZGVmYXVsdDogZGlzYWJsZWQpXG4gKiAtIFNtYXJ0IGJhY2tzcGFjZSBvdmVyIGZvcm1hdHRpbmcgY2hhcmFjdGVyc1xuICogLSBObyBtaWQtc3RyaW5nIGZvcm1hdHRpbmcgKHdhaXRzIGZvciBibHVyKVxuICpcbiAqIEFyZ3VtZW50czpcbiAqIC0gJGFsbG93X2RlY2ltYWxzIC0gQWxsb3cgMiBkZWNpbWFsIHBsYWNlcyAoZGVmYXVsdDogZmFsc2UpXG4gKiAtICRzaG93X3N5bWJvbCAtIFNob3cgY3VycmVuY3kgc3ltYm9sIChkZWZhdWx0OiBmYWxzZSlcbiAqIC0gJGN1cnJlbmN5X3N5bWJvbCAtIEN1cnJlbmN5IHN5bWJvbCB0byB1c2UgKGRlZmF1bHQ6IFwiJFwiKVxuICpcbiAqIFVzYWdlOlxuICogICA8Q3VycmVuY3lfSW5wdXQgLz5cbiAqICAgPEN1cnJlbmN5X0lucHV0ICRzaG93X3N5bWJvbD10cnVlIC8+XG4gKiAgIDxDdXJyZW5jeV9JbnB1dCAkYWxsb3dfZGVjaW1hbHM9dHJ1ZSAvPlxuICogICA8Q3VycmVuY3lfSW5wdXQgJHNob3dfc3ltYm9sPXRydWUgJGFsbG93X2RlY2ltYWxzPXRydWUgJGN1cnJlbmN5X3N5bWJvbD1cIuKCrFwiIC8+XG4gKlxuICogQmVoYXZpb3I6XG4gKiAtIFR5cGUgXCIxMjM0NTY3XCIgLT4gZGlzcGxheXMgXCIxLDIzNCw1NjdcIiwgdmFsKCkgcmV0dXJucyBcIjEyMzQ1NjdcIlxuICogLSBUeXBlIFwiMTIzNDU2Ny44OVwiICh3aXRoIGRlY2ltYWxzKSAtPiBkaXNwbGF5cyBcIjEsMjM0LDU2Ny44OVwiLCB2YWwoKSByZXR1cm5zIFwiMTIzNDU2Ny44OVwiXG4gKiAtIFdpdGggc3ltYm9sOiBkaXNwbGF5cyBcIiQxLDIzNCw1NjdcIiwgdmFsKCkgc3RpbGwgcmV0dXJucyBcIjEyMzQ1NjdcIlxuICovXG5jbGFzcyBDdXJyZW5jeV9JbnB1dCBleHRlbmRzIFRleHRfSW5wdXQge1xuICAgIG9uX2NyZWF0ZSgpIHtcbiAgICAgICAgc3VwZXIub25fY3JlYXRlKCk7XG5cbiAgICAgICAgLy8gU2V0IGRlZmF1bHRzIGZvciBvcHRpb25zXG4gICAgICAgIGlmICh0aGlzLmFyZ3MuYWxsb3dfZGVjaW1hbHMgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgdGhpcy5hcmdzLmFsbG93X2RlY2ltYWxzID0gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuYXJncy5zaG93X3N5bWJvbCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICB0aGlzLmFyZ3Muc2hvd19zeW1ib2wgPSBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5hcmdzLmN1cnJlbmN5X3N5bWJvbCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICB0aGlzLmFyZ3MuY3VycmVuY3lfc3ltYm9sID0gJyQnO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRm9ybWF0IGN1cnJlbmN5IHdpdGggY29tbWFzIGFuZCBvcHRpb25hbCBzeW1ib2xcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gdmFsdWUgLSBOdW1lcmljIHZhbHVlIChtYXkgaW5jbHVkZSBkZWNpbWFsKVxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IEZvcm1hdHRlZCBjdXJyZW5jeSBzdHJpbmdcbiAgICAgKi9cbiAgICBfZm9ybWF0X2N1cnJlbmN5KHZhbHVlKSB7XG4gICAgICAgIGlmICghdmFsdWUpIHtcbiAgICAgICAgICAgIHJldHVybiAnJztcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFNwbGl0IGludG8gaW50ZWdlciBhbmQgZGVjaW1hbCBwYXJ0c1xuICAgICAgICBsZXQgcGFydHMgPSB2YWx1ZS5zcGxpdCgnLicpO1xuICAgICAgICBsZXQgaW50ZWdlcl9wYXJ0ID0gcGFydHNbMF07XG4gICAgICAgIGxldCBkZWNpbWFsX3BhcnQgPSBwYXJ0c1sxXTtcblxuICAgICAgICAvLyBBZGQgY29tbWFzIHRvIGludGVnZXIgcGFydFxuICAgICAgICBpbnRlZ2VyX3BhcnQgPSBpbnRlZ2VyX3BhcnQucmVwbGFjZSgvXFxCKD89KFxcZHszfSkrKD8hXFxkKSkvZywgJywnKTtcblxuICAgICAgICAvLyBSZWNvbnN0cnVjdCB3aXRoIGRlY2ltYWwgaWYgYWxsb3dlZFxuICAgICAgICBsZXQgZm9ybWF0dGVkID0gaW50ZWdlcl9wYXJ0O1xuICAgICAgICBpZiAodGhpcy5hcmdzLmFsbG93X2RlY2ltYWxzICYmIGRlY2ltYWxfcGFydCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAvLyBMaW1pdCB0byAyIGRlY2ltYWwgcGxhY2VzXG4gICAgICAgICAgICBkZWNpbWFsX3BhcnQgPSBkZWNpbWFsX3BhcnQuc3Vic3RyKDAsIDIpO1xuICAgICAgICAgICAgZm9ybWF0dGVkICs9ICcuJyArIGRlY2ltYWxfcGFydDtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIEFkZCBjdXJyZW5jeSBzeW1ib2wgaWYgZW5hYmxlZFxuICAgICAgICBpZiAodGhpcy5hcmdzLnNob3dfc3ltYm9sKSB7XG4gICAgICAgICAgICBmb3JtYXR0ZWQgPSB0aGlzLmFyZ3MuY3VycmVuY3lfc3ltYm9sICsgZm9ybWF0dGVkO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGZvcm1hdHRlZDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBFeHRyYWN0IG51bWVyaWMgdmFsdWUgZnJvbSBmb3JtYXR0ZWQgc3RyaW5nXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGZvcm1hdHRlZCAtIEZvcm1hdHRlZCBjdXJyZW5jeSBzdHJpbmdcbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBDbGVhbiBudW1lcmljIHZhbHVlIChkaWdpdHMgYW5kIGRlY2ltYWwgb25seSlcbiAgICAgKi9cbiAgICBfZ2V0X251bWVyaWNfdmFsdWUoZm9ybWF0dGVkKSB7XG4gICAgICAgIGlmICghZm9ybWF0dGVkKSB7XG4gICAgICAgICAgICByZXR1cm4gJyc7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBSZW1vdmUgY3VycmVuY3kgc3ltYm9sIGFuZCBjb21tYXNcbiAgICAgICAgbGV0IGNsZWFuZWQgPSBmb3JtYXR0ZWQucmVwbGFjZSgvW14wLTkuXS9nLCAnJyk7XG5cbiAgICAgICAgLy8gRW5zdXJlIG9ubHkgb25lIGRlY2ltYWwgcG9pbnRcbiAgICAgICAgY29uc3QgZGVjaW1hbF9jb3VudCA9IChjbGVhbmVkLm1hdGNoKC9cXC4vZykgfHwgW10pLmxlbmd0aDtcbiAgICAgICAgaWYgKGRlY2ltYWxfY291bnQgPiAxKSB7XG4gICAgICAgICAgICAvLyBLZWVwIG9ubHkgZmlyc3QgZGVjaW1hbCBwb2ludFxuICAgICAgICAgICAgY29uc3QgZmlyc3RfZGVjaW1hbCA9IGNsZWFuZWQuaW5kZXhPZignLicpO1xuICAgICAgICAgICAgY2xlYW5lZCA9IGNsZWFuZWQuc3Vic3RyKDAsIGZpcnN0X2RlY2ltYWwgKyAxKSArIGNsZWFuZWQuc3Vic3RyKGZpcnN0X2RlY2ltYWwgKyAxKS5yZXBsYWNlKC9cXC4vZywgJycpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGNsZWFuZWQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogdmFsKCkgLSBHZXQgb3Igc2V0IHRoZSBjdXJyZW5jeSB2YWx1ZVxuICAgICAqIEdldHRlciByZXR1cm5zIG51bWVyaWMgc3RyaW5nIChubyBjb21tYXMsIG5vIHN5bWJvbClcbiAgICAgKiBTZXR0ZXIgYWNjZXB0cyBhbnl0aGluZyBhbmQgZm9ybWF0cyB3aXRoIGNvbW1hcy9zeW1ib2xcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW3ZhbHVlXVxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9XG4gICAgICovXG4gICAgdmFsKHZhbHVlKSB7XG4gICAgICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAvLyBHZXR0ZXIgLSByZXR1cm4gbnVtZXJpYyB2YWx1ZSBvbmx5XG4gICAgICAgICAgICBjb25zdCByYXcgPSB0aGlzLiRpZCgnaW5wdXQnKS52YWwoKTtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9nZXRfbnVtZXJpY192YWx1ZShyYXcpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gU2V0dGVyIC0gZm9ybWF0IGFuZCBkaXNwbGF5XG4gICAgICAgICAgICBpZiAoIXZhbHVlKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5kYXRhLnZhbHVlID0gJyc7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuJGlkKCdpbnB1dCcpLmV4aXN0cygpKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuJGlkKCdpbnB1dCcpLnZhbCgnJyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gQ2xlYW4gdGhlIGlucHV0IHZhbHVlXG4gICAgICAgICAgICBjb25zdCBudW1lcmljID0gdGhpcy5fZ2V0X251bWVyaWNfdmFsdWUoc3RyKHZhbHVlKSk7XG4gICAgICAgICAgICBjb25zdCBmb3JtYXR0ZWQgPSB0aGlzLl9mb3JtYXRfY3VycmVuY3kobnVtZXJpYyk7XG5cbiAgICAgICAgICAgIHRoaXMuZGF0YS52YWx1ZSA9IGZvcm1hdHRlZDtcbiAgICAgICAgICAgIGlmICh0aGlzLiRpZCgnaW5wdXQnKS5leGlzdHMoKSkge1xuICAgICAgICAgICAgICAgIHRoaXMuJGlkKCdpbnB1dCcpLnZhbChmb3JtYXR0ZWQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgb25fcmVhZHkoKSB7XG4gICAgICAgIHN1cGVyLm9uX3JlYWR5KCk7XG5cbiAgICAgICAgY29uc3QgJGlucHV0ID0gdGhpcy4kaWQoJ2lucHV0Jyk7XG5cbiAgICAgICAgLy8gSGFuZGxlIGtleWRvd24gdG8gaW50ZXJjZXB0IGJhY2tzcGFjZSBhdCBlbmQgb2Ygc3RyaW5nXG4gICAgICAgICRpbnB1dC5vbigna2V5ZG93bicsIChlKSA9PiB7XG4gICAgICAgICAgICBjb25zdCByYXcgPSAkaW5wdXQudmFsKCk7XG5cbiAgICAgICAgICAgIC8vIE9ubHkgaGFuZGxlIGJhY2tzcGFjZSBrZXlcbiAgICAgICAgICAgIGlmIChlLmtleSAhPT0gJ0JhY2tzcGFjZScpIHtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbnN0IGlucHV0X2VsZW1lbnQgPSAkaW5wdXRbMF07XG4gICAgICAgICAgICBjb25zdCBjdXJzb3JfcG9zID0gaW5wdXRfZWxlbWVudC5zZWxlY3Rpb25TdGFydDtcbiAgICAgICAgICAgIGNvbnN0IGN1cnNvcl9lbmQgPSBpbnB1dF9lbGVtZW50LnNlbGVjdGlvbkVuZDtcbiAgICAgICAgICAgIGNvbnN0IHZhbHVlX2xlbmd0aCA9IHJhdy5sZW5ndGg7XG5cbiAgICAgICAgICAgIC8vIE9ubHkgaGFuZGxlIGlmIGN1cnNvciBpcyBhdCB0aGUgZW5kIGFuZCBubyBzZWxlY3Rpb25cbiAgICAgICAgICAgIGlmIChjdXJzb3JfcG9zID09PSB2YWx1ZV9sZW5ndGggJiYgY3Vyc29yX3BvcyA9PT0gY3Vyc29yX2VuZCkge1xuICAgICAgICAgICAgICAgIC8vIENoZWNrIGlmIGNoYXJhY3RlciBiZWZvcmUgY3Vyc29yIGlzIG5vbi1udW1lcmljXG4gICAgICAgICAgICAgICAgaWYgKGN1cnNvcl9wb3MgPiAwKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXJfYmVmb3JlID0gcmF3LmNoYXJBdChjdXJzb3JfcG9zIC0gMSk7XG4gICAgICAgICAgICAgICAgICAgIGlmICghL1swLTldLy50ZXN0KGNoYXJfYmVmb3JlKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gQ2hhcmFjdGVyIGJlZm9yZSBjdXJzb3IgaXMgbm90IGEgZGlnaXRcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIERlbGV0ZSB0aGUgbGFzdCBkaWdpdCBpbnN0ZWFkXG4gICAgICAgICAgICAgICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG51bWVyaWMgPSB0aGlzLl9nZXRfbnVtZXJpY192YWx1ZShyYXcpO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG51bWVyaWMubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFJlbW92ZSBsYXN0IGNoYXJhY3RlciBmcm9tIG51bWVyaWMgdmFsdWVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBuZXdfbnVtZXJpYyA9IG51bWVyaWMuc3Vic3RyKDAsIG51bWVyaWMubGVuZ3RoIC0gMSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZm9ybWF0dGVkID0gdGhpcy5fZm9ybWF0X2N1cnJlbmN5KG5ld19udW1lcmljKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkaW5wdXQudmFsKGZvcm1hdHRlZCk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBQbGFjZSBjdXJzb3IgYXQgZW5kXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG5ld19sZW5ndGggPSAkaW5wdXQudmFsKCkubGVuZ3RoO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnB1dF9lbGVtZW50LnNldFNlbGVjdGlvblJhbmdlKG5ld19sZW5ndGgsIG5ld19sZW5ndGgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sIDApO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgICAgICAvLyBIYW5kbGUgaW5wdXQgZXZlbnQgZm9yIGxpdmUgZm9ybWF0dGluZ1xuICAgICAgICAkaW5wdXQub24oJ2lucHV0JywgKCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgcmF3ID0gJGlucHV0LnZhbCgpO1xuICAgICAgICAgICAgY29uc3QgaW5wdXRfZWxlbWVudCA9ICRpbnB1dFswXTtcbiAgICAgICAgICAgIGNvbnN0IGN1cnNvcl9wb3MgPSBpbnB1dF9lbGVtZW50LnNlbGVjdGlvblN0YXJ0O1xuICAgICAgICAgICAgY29uc3QgdmFsdWVfbGVuZ3RoID0gcmF3Lmxlbmd0aDtcblxuICAgICAgICAgICAgLy8gT25seSBhcHBseSBsaXZlIGZvcm1hdHRpbmcgaWYgY3Vyc29yIGlzIGF0IHRoZSBlbmRcbiAgICAgICAgICAgIGlmIChjdXJzb3JfcG9zID09PSB2YWx1ZV9sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICAvLyBFeHRyYWN0IG51bWVyaWMgdmFsdWVcbiAgICAgICAgICAgICAgICBsZXQgbnVtZXJpYyA9IHRoaXMuX2dldF9udW1lcmljX3ZhbHVlKHJhdyk7XG5cbiAgICAgICAgICAgICAgICAvLyBMaW1pdCBkZWNpbWFsIHBsYWNlcyB0byAyIGlmIGRlY2ltYWxzIGFsbG93ZWRcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5hcmdzLmFsbG93X2RlY2ltYWxzKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHBhcnRzID0gbnVtZXJpYy5zcGxpdCgnLicpO1xuICAgICAgICAgICAgICAgICAgICBpZiAocGFydHNbMV0gJiYgcGFydHNbMV0ubGVuZ3RoID4gMikge1xuICAgICAgICAgICAgICAgICAgICAgICAgbnVtZXJpYyA9IHBhcnRzWzBdICsgJy4nICsgcGFydHNbMV0uc3Vic3RyKDAsIDIpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgLy8gRm9ybWF0IHRoZSBudW1lcmljIHZhbHVlXG4gICAgICAgICAgICAgICAgY29uc3QgZm9ybWF0dGVkID0gdGhpcy5fZm9ybWF0X2N1cnJlbmN5KG51bWVyaWMpO1xuICAgICAgICAgICAgICAgICRpbnB1dC52YWwoZm9ybWF0dGVkKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgLy8gQ3Vyc29yIGlzIG5vdCBhdCBlbmQgLSB1c2VyIGlzIGVkaXRpbmcgaW4gdGhlIG1pZGRsZVxuICAgICAgICAgICAgICAgIC8vIERvbid0IGZvcm1hdCwganVzdCBjbGVhbiBpbnZhbGlkIGNoYXJhY3RlcnNcbiAgICAgICAgICAgICAgICBjb25zdCBudW1lcmljID0gdGhpcy5fZ2V0X251bWVyaWNfdmFsdWUocmF3KTtcblxuICAgICAgICAgICAgICAgIC8vIE9ubHkgdXBkYXRlIGlmIHdlIHJlbW92ZWQgaW52YWxpZCBjaGFyYWN0ZXJzXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuX2Zvcm1hdF9jdXJyZW5jeShudW1lcmljKSAhPT0gcmF3KSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIFByZXNlcnZlIGp1c3QgdGhlIG51bWVyaWMgY2hhcmFjdGVyc1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBzeW1ib2xfb2Zmc2V0ID0gdGhpcy5hcmdzLnNob3dfc3ltYm9sID8gdGhpcy5hcmdzLmN1cnJlbmN5X3N5bWJvbC5sZW5ndGggOiAwO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBjbGVhbmVkID0gKHRoaXMuYXJncy5zaG93X3N5bWJvbCA/IHRoaXMuYXJncy5jdXJyZW5jeV9zeW1ib2wgOiAnJykgKyBudW1lcmljO1xuXG4gICAgICAgICAgICAgICAgICAgIGlmIChjbGVhbmVkICE9PSByYXcpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICRpbnB1dC52YWwoY2xlYW5lZCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBSZXN0b3JlIGN1cnNvciBwb3NpdGlvbiAoYXBwcm94aW1hdGVseSlcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG5ld19jdXJzb3IgPSBNYXRoLm1pbihjdXJzb3JfcG9zLCBjbGVhbmVkLmxlbmd0aCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBpbnB1dF9lbGVtZW50LnNldFNlbGVjdGlvblJhbmdlKG5ld19jdXJzb3IsIG5ld19jdXJzb3IpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgICAgICAvLyBIYW5kbGUgYmx1ciB0byByZWZvcm1hdCB3aGVuIGRvbmUgZWRpdGluZ1xuICAgICAgICAkaW5wdXQub24oJ2JsdXInLCAoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCByYXcgPSAkaW5wdXQudmFsKCk7XG5cbiAgICAgICAgICAgIGlmICghcmF3KSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBSZWZvcm1hdCB0aGUgZW50aXJlIHZhbHVlIG9uIGJsdXJcbiAgICAgICAgICAgIGNvbnN0IG51bWVyaWMgPSB0aGlzLl9nZXRfbnVtZXJpY192YWx1ZShyYXcpO1xuICAgICAgICAgICAgY29uc3QgZm9ybWF0dGVkID0gdGhpcy5fZm9ybWF0X2N1cnJlbmN5KG51bWVyaWMpO1xuICAgICAgICAgICAgJGlucHV0LnZhbChmb3JtYXR0ZWQpO1xuICAgICAgICB9KTtcblxuICAgICAgICAvLyBIYW5kbGUgZm9jdXMgdG8gc2VsZWN0IGFsbCBmb3IgZWFzeSByZXBsYWNlbWVudFxuICAgICAgICAkaW5wdXQub24oJ2ZvY3VzJywgKCkgPT4ge1xuICAgICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgJGlucHV0WzBdLnNlbGVjdCgpO1xuICAgICAgICAgICAgfSwgMCk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIEluaXRpYWxpemUgZm9ybWF0dGluZyBpZiB0aGVyZSdzIGEgdmFsdWVcbiAgICAgICAgY29uc3QgaW5pdGlhbF92YWx1ZSA9ICRpbnB1dC52YWwoKTtcbiAgICAgICAgaWYgKGluaXRpYWxfdmFsdWUpIHtcbiAgICAgICAgICAgIHRoaXMudmFsKGluaXRpYWxfdmFsdWUpO1xuICAgICAgICB9XG4gICAgfVxufVxuIl0sIm1hcHBpbmdzIjoiOztBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTUEsY0FBYyxTQUFTQyxVQUFVLENBQUM7RUFDcENDLFNBQVNBLENBQUEsRUFBRztJQUNSLEtBQUssQ0FBQ0EsU0FBUyxDQUFDLENBQUM7O0lBRWpCO0lBQ0EsSUFBSSxJQUFJLENBQUNDLElBQUksQ0FBQ0MsY0FBYyxLQUFLQyxTQUFTLEVBQUU7TUFDeEMsSUFBSSxDQUFDRixJQUFJLENBQUNDLGNBQWMsR0FBRyxLQUFLO0lBQ3BDO0lBQ0EsSUFBSSxJQUFJLENBQUNELElBQUksQ0FBQ0csV0FBVyxLQUFLRCxTQUFTLEVBQUU7TUFDckMsSUFBSSxDQUFDRixJQUFJLENBQUNHLFdBQVcsR0FBRyxLQUFLO0lBQ2pDO0lBQ0EsSUFBSSxJQUFJLENBQUNILElBQUksQ0FBQ0ksZUFBZSxLQUFLRixTQUFTLEVBQUU7TUFDekMsSUFBSSxDQUFDRixJQUFJLENBQUNJLGVBQWUsR0FBRyxHQUFHO0lBQ25DO0VBQ0o7O0VBRUE7QUFDSjtBQUNBO0FBQ0E7QUFDQTtFQUNJQyxnQkFBZ0JBLENBQUNDLEtBQUssRUFBRTtJQUNwQixJQUFJLENBQUNBLEtBQUssRUFBRTtNQUNSLE9BQU8sRUFBRTtJQUNiOztJQUVBO0lBQ0EsSUFBSUMsS0FBSyxHQUFHRCxLQUFLLENBQUNFLEtBQUssQ0FBQyxHQUFHLENBQUM7SUFD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