Files
rspade_system/storage-working/rsx-tmp/babel_cache/c18e9930b0b47704493d6efaa669ebdf_modern.js
root 78553d4edf Fix code quality violations for publish
Remove unused blade settings pages not linked from UI
Convert remaining frontend pages to SPA actions
Convert settings user_settings and general to SPA actions
Convert settings profile pages to SPA actions
Convert contacts and projects add/edit pages to SPA actions
Convert clients add/edit page to SPA action with loading pattern
Refactor component scoped IDs from $id to $sid
Fix jqhtml comment syntax and implement universal error component system
Update all application code to use new unified error system
Remove all backwards compatibility - unified error system complete
Phase 5: Remove old response classes
Phase 3-4: Ajax response handler sends new format, old helpers deprecated
Phase 2: Add client-side unified error foundation
Phase 1: Add server-side unified error foundation
Add unified Ajax error response system with constants

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-21 04:35:01 +00:00

201 lines
24 KiB
JavaScript
Executable File

"use strict";
/**
* Rsx_Form
*
* Form container with validation, submission, and widget value management.
* See rsx_form.jqhtml for full documentation.
*
* JavaScript Responsibilities:
* - Parses and stores initial form data from $data attribute (JSON or object)
* - Discovers and manages child Widget components via vals() getter/setter
* - Handles form submission via Ajax to controller/method endpoints
* - Applies validation errors to fields using Form_Utils
* - Integrates with Rsx_Tabs for tab-aware error handling
* - Provides seed() functionality for debug/testing
* - Manages form state (values, errors) throughout lifecycle
*/
class Rsx_Form extends Component {
on_create() {
this.data.values = {}; // Current form values {name: value}
this.data.errors = {}; // Validation errors {name: error_message}
this.tabs = null; // Reference to Rsx_Tabs component if present
// Parse initial data from $data attribute (e.g., from $data=$client)
let data = this.args.data;
if (typeof data === 'string') {
try {
// Decode HTML entities before parsing JSON
// This handles cases where JSON is passed through Blade {!! !!} syntax
const decoded = $('<textarea>').html(data).text();
data = json_decode(decoded);
} catch (e) {
console.error('Form: Failed to parse data JSON string', e);
data = {};
}
}
if (data && typeof data === 'object') {
this.data.values = data;
}
}
on_ready() {
const that = this;
// Validate that error container exists
if (!this.$sid('error').exists()) {
console.log(this.$.html());
throw new Error('Rsx_Form requires an error container with $id="error". ' + 'Add <div $id="error"></div> to your form template for displaying validation and error messages.');
}
// Set up seed button handler if in debug mode
if (window.rsxapp.debug && this.$sid('seed_btn').exists()) {
that.$sid('seed_btn').on('click', function () {
that.seed();
});
}
// Find child Rsx_Tabs component if present for error handling integration
const tabs_el = this.$.find('.Rsx_Tabs').first();
if (tabs_el.length) {
that.tabs = tabs_el.component();
}
// Automatically wire all submit buttons to call form submit()
this.$.find('button[type="submit"]').each(function () {
$(this).on('click', function (e) {
e.preventDefault();
that.submit();
});
});
// Notify all fields to load their initial values
// This happens in on_ready to ensure all Form_Field children are initialized
this.vals(this.data.values);
// Hide loading spinner and show form content (without re-rendering)
this.$sid('loader').hide();
this.$sid('form_content').show();
}
// Getter or setter for all form values, similar to jquery val
vals(values) {
if (values) {
// Setter
this.$.shallowFind('.Widget').each(function () {
let $widget = $(this);
let component = $widget.component();
if (component && 'val' in component) {
let widget_name = $widget.data('name');
if (widget_name in values) {
component.val(values[widget_name]);
}
}
});
return null;
} else {
// Getter
let data = {};
// Get widget values
this.$.shallowFind('.Widget').each(function () {
let $widget = $(this);
let component = $widget.component();
if (component && 'val' in component) {
let widget_name = $widget.data('name');
data[widget_name] = component.val();
}
});
// Also get regular hidden inputs (non-widget inputs)
this.$.find('input[type="hidden"][name]').each(function () {
let $input = $(this);
let name = $input.attr('name');
if (name) {
data[name] = $input.val();
}
});
return data;
}
}
get_error(name) {
return this.data.errors[name];
}
/**
* Render an error in the form's error container
*
* Handles both field-specific validation errors and generic errors.
* Can be called by external handlers (e.g., modal on_submit) or internally
* by the form's own submit() method.
*
* @param {Error|Object} error - Error object from Ajax call
*/
async render_error(error) {
// Handle validation errors - apply to fields
if (error.type === 'form_error' && error.details) {
await Form_Utils.apply_form_errors(this.$, error.details);
// Notify tabs of validation errors for error badges and auto-switching
if (this.tabs) {
this.tabs.handle_validation_errors(error.details);
}
// Form_Utils handles all rendering (inline errors + unmatched errors alert)
// Don't call Rsx.render_error() to avoid duplicate alerts
return;
}
// For non-form errors (fatal, auth, network, etc.), render in form's error container
Rsx.render_error(error, this.$sid('error'));
}
async submit() {
// Clear any previous errors
Form_Utils.reset_form_errors(this.$);
this.$sid('error').empty();
// Clear tab error badges if tabs are present
if (this.tabs) {
this.tabs.clear_error_badges();
}
// Serialize all field values
let values = this.vals();
// Call submit handler
if (!this.args.controller || !this.args.method) {
console.error('Form: No controller/method provided');
throw new Error('Form configuration error: Missing controller or method');
}
try {
// Build Ajax URL from controller and method
const ajax_url = `/_ajax/${this.args.controller}/${this.args.method}`;
// Call Ajax endpoint - response is directly what PHP returned
const result = await Ajax.call(ajax_url, values);
// Success! Handle result
if (result && result.redirect) {
// Redirect to URL
window.location.href = result.redirect;
} else {
// Success without redirect
console.log('Form submitted successfully', result);
}
} catch (error) {
// Render error (handles both validation and generic errors)
await this.render_error(error);
}
}
async seed() {
const promises = [];
this.$.shallowFind('.Form_Field').each(function () {
let component = $(this).component();
if (component && 'seed' in component) {
promises.push(component.seed());
}
});
await Promise.all(promises);
}
}
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJSc3hfRm9ybSIsIkpxaHRtbF9Db21wb25lbnQiLCJvbl9jcmVhdGUiLCJkYXRhIiwidmFsdWVzIiwiZXJyb3JzIiwidGFicyIsImFyZ3MiLCJkZWNvZGVkIiwiJCIsImh0bWwiLCJ0ZXh0IiwianNvbl9kZWNvZGUiLCJlIiwiY29uc29sZSIsImVycm9yIiwib25fcmVhZHkiLCJ0aGF0IiwiJGlkIiwiZXhpc3RzIiwibG9nIiwiRXJyb3IiLCJ3aW5kb3ciLCJyc3hhcHAiLCJkZWJ1ZyIsIm9uIiwic2VlZCIsInRhYnNfZWwiLCJmaW5kIiwiZmlyc3QiLCJsZW5ndGgiLCJjb21wb25lbnQiLCJlYWNoIiwicHJldmVudERlZmF1bHQiLCJzdWJtaXQiLCJ2YWxzIiwiaGlkZSIsInNob3ciLCJzaGFsbG93RmluZCIsIiR3aWRnZXQiLCJ3aWRnZXRfbmFtZSIsInZhbCIsIiRpbnB1dCIsIm5hbWUiLCJhdHRyIiwiZ2V0X2Vycm9yIiwicmVuZGVyX2Vycm9yIiwidHlwZSIsImRldGFpbHMiLCJGb3JtX1V0aWxzIiwiYXBwbHlfZm9ybV9lcnJvcnMiLCJoYW5kbGVfdmFsaWRhdGlvbl9lcnJvcnMiLCJSc3giLCJyZXNldF9mb3JtX2Vycm9ycyIsImVtcHR5IiwiY2xlYXJfZXJyb3JfYmFkZ2VzIiwiY29udHJvbGxlciIsIm1ldGhvZCIsImFqYXhfdXJsIiwicmVzdWx0IiwiQWpheCIsImNhbGwiLCJyZWRpcmVjdCIsImxvY2F0aW9uIiwiaHJlZiIsInByb21pc2VzIiwicHVzaCIsIlByb21pc2UiLCJhbGwiXSwic291cmNlcyI6WyJyc3gvdGhlbWUvY29tcG9uZW50cy9mb3Jtcy9yc3hfZm9ybS5qcyJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIFJzeF9Gb3JtXG4gKlxuICogRm9ybSBjb250YWluZXIgd2l0aCB2YWxpZGF0aW9uLCBzdWJtaXNzaW9uLCBhbmQgd2lkZ2V0IHZhbHVlIG1hbmFnZW1lbnQuXG4gKiBTZWUgcnN4X2Zvcm0uanFodG1sIGZvciBmdWxsIGRvY3VtZW50YXRpb24uXG4gKlxuICogSmF2YVNjcmlwdCBSZXNwb25zaWJpbGl0aWVzOlxuICogLSBQYXJzZXMgYW5kIHN0b3JlcyBpbml0aWFsIGZvcm0gZGF0YSBmcm9tICRkYXRhIGF0dHJpYnV0ZSAoSlNPTiBvciBvYmplY3QpXG4gKiAtIERpc2NvdmVycyBhbmQgbWFuYWdlcyBjaGlsZCBXaWRnZXQgY29tcG9uZW50cyB2aWEgdmFscygpIGdldHRlci9zZXR0ZXJcbiAqIC0gSGFuZGxlcyBmb3JtIHN1Ym1pc3Npb24gdmlhIEFqYXggdG8gY29udHJvbGxlci9tZXRob2QgZW5kcG9pbnRzXG4gKiAtIEFwcGxpZXMgdmFsaWRhdGlvbiBlcnJvcnMgdG8gZmllbGRzIHVzaW5nIEZvcm1fVXRpbHNcbiAqIC0gSW50ZWdyYXRlcyB3aXRoIFJzeF9UYWJzIGZvciB0YWItYXdhcmUgZXJyb3IgaGFuZGxpbmdcbiAqIC0gUHJvdmlkZXMgc2VlZCgpIGZ1bmN0aW9uYWxpdHkgZm9yIGRlYnVnL3Rlc3RpbmdcbiAqIC0gTWFuYWdlcyBmb3JtIHN0YXRlICh2YWx1ZXMsIGVycm9ycykgdGhyb3VnaG91dCBsaWZlY3ljbGVcbiAqL1xuY2xhc3MgUnN4X0Zvcm0gZXh0ZW5kcyBKcWh0bWxfQ29tcG9uZW50IHtcbiAgICBvbl9jcmVhdGUoKSB7XG4gICAgICAgIHRoaXMuZGF0YS52YWx1ZXMgPSB7fTsgLy8gQ3VycmVudCBmb3JtIHZhbHVlcyB7bmFtZTogdmFsdWV9XG4gICAgICAgIHRoaXMuZGF0YS5lcnJvcnMgPSB7fTsgLy8gVmFsaWRhdGlvbiBlcnJvcnMge25hbWU6IGVycm9yX21lc3NhZ2V9XG4gICAgICAgIHRoaXMudGFicyA9IG51bGw7IC8vIFJlZmVyZW5jZSB0byBSc3hfVGFicyBjb21wb25lbnQgaWYgcHJlc2VudFxuXG4gICAgICAgIC8vIFBhcnNlIGluaXRpYWwgZGF0YSBmcm9tICRkYXRhIGF0dHJpYnV0ZSAoZS5nLiwgZnJvbSAkZGF0YT0kY2xpZW50KVxuICAgICAgICBsZXQgZGF0YSA9IHRoaXMuYXJncy5kYXRhO1xuXG4gICAgICAgIGlmICh0eXBlb2YgZGF0YSA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgLy8gRGVjb2RlIEhUTUwgZW50aXRpZXMgYmVmb3JlIHBhcnNpbmcgSlNPTlxuICAgICAgICAgICAgICAgIC8vIFRoaXMgaGFuZGxlcyBjYXNlcyB3aGVyZSBKU09OIGlzIHBhc3NlZCB0aHJvdWdoIEJsYWRlIHshISAhIX0gc3ludGF4XG4gICAgICAgICAgICAgICAgY29uc3QgZGVjb2RlZCA9ICQoJzx0ZXh0YXJlYT4nKS5odG1sKGRhdGEpLnRleHQoKTtcbiAgICAgICAgICAgICAgICBkYXRhID0ganNvbl9kZWNvZGUoZGVjb2RlZCk7XG4gICAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcignRm9ybTogRmFpbGVkIHRvIHBhcnNlIGRhdGEgSlNPTiBzdHJpbmcnLCBlKTtcbiAgICAgICAgICAgICAgICBkYXRhID0ge307XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoZGF0YSAmJiB0eXBlb2YgZGF0YSA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgICAgIHRoaXMuZGF0YS52YWx1ZXMgPSBkYXRhO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgb25fcmVhZHkoKSB7XG4gICAgICAgIGNvbnN0IHRoYXQgPSB0aGlzO1xuXG4gICAgICAgIC8vIFZhbGlkYXRlIHRoYXQgZXJyb3IgY29udGFpbmVyIGV4aXN0c1xuICAgICAgICBpZiAoIXRoaXMuJGlkKCdlcnJvcicpLmV4aXN0cygpKSB7XG4gICAgICAgICAgICBjb25zb2xlLmxvZyh0aGlzLiQuaHRtbCgpKTtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICAgICAgICAnUnN4X0Zvcm0gcmVxdWlyZXMgYW4gZXJyb3IgY29udGFpbmVyIHdpdGggJGlkPVwiZXJyb3JcIi4gJyArXG4gICAgICAgICAgICAgICAgICAgICdBZGQgPGRpdiAkaWQ9XCJlcnJvclwiPjwvZGl2PiB0byB5b3VyIGZvcm0gdGVtcGxhdGUgZm9yIGRpc3BsYXlpbmcgdmFsaWRhdGlvbiBhbmQgZXJyb3IgbWVzc2FnZXMuJ1xuICAgICAgICAgICAgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFNldCB1cCBzZWVkIGJ1dHRvbiBoYW5kbGVyIGlmIGluIGRlYnVnIG1vZGVcbiAgICAgICAgaWYgKHdpbmRvdy5yc3hhcHAuZGVidWcgJiYgdGhpcy4kaWQoJ3NlZWRfYnRuJykuZXhpc3RzKCkpIHtcbiAgICAgICAgICAgIHRoYXQuJGlkKCdzZWVkX2J0bicpLm9uKCdjbGljaycsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICB0aGF0LnNlZWQoKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gRmluZCBjaGlsZCBSc3hfVGFicyBjb21wb25lbnQgaWYgcHJlc2VudCBmb3IgZXJyb3IgaGFuZGxpbmcgaW50ZWdyYXRpb25cbiAgICAgICAgY29uc3QgdGFic19lbCA9IHRoaXMuJC5maW5kKCcuUnN4X1RhYnMnKS5maXJzdCgpO1xuICAgICAgICBpZiAodGFic19lbC5sZW5ndGgpIHtcbiAgICAgICAgICAgIHRoYXQudGFicyA9IHRhYnNfZWwuY29tcG9uZW50KCk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBBdXRvbWF0aWNhbGx5IHdpcmUgYWxsIHN1Ym1pdCBidXR0b25zIHRvIGNhbGwgZm9ybSBzdWJtaXQoKVxuICAgICAgICB0aGlzLiQuZmluZCgnYnV0dG9uW3R5cGU9XCJzdWJtaXRcIl0nKS5lYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICQodGhpcykub24oJ2NsaWNrJywgZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICAgICAgdGhhdC5zdWJtaXQoKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcblxuICAgICAgICAvLyBOb3RpZnkgYWxsIGZpZWxkcyB0byBsb2FkIHRoZWlyIGluaXRpYWwgdmFsdWVzXG4gICAgICAgIC8vIFRoaXMgaGFwcGVucyBpbiBvbl9yZWFkeSB0byBlbnN1cmUgYWxsIEZvcm1fRmllbGQgY2hpbGRyZW4gYXJlIGluaXRpYWxpemVkXG4gICAgICAgIHRoaXMudmFscyh0aGlzLmRhdGEudmFsdWVzKTtcblxuICAgICAgICAvLyBIaWRlIGxvYWRpbmcgc3Bpbm5lciBhbmQgc2hvdyBmb3JtIGNvbnRlbnQgKHdpdGhvdXQgcmUtcmVuZGVyaW5nKVxuICAgICAgICB0aGlzLiRpZCgnbG9hZGVyJykuaGlkZSgpO1xuICAgICAgICB0aGlzLiRpZCgnZm9ybV9jb250ZW50Jykuc2hvdygpO1xuICAgIH1cblxuICAgIC8vIEdldHRlciBvciBzZXR0ZXIgZm9yIGFsbCBmb3JtIHZhbHVlcywgc2ltaWxhciB0byBqcXVlcnkgdmFsXG4gICAgdmFscyh2YWx1ZXMpIHtcbiAgICAgICAgaWYgKHZhbHVlcykge1xuICAgICAgICAgICAgLy8gU2V0dGVyXG5cbiAgICAgICAgICAgIHRoaXMuJC5zaGFsbG93RmluZCgnLldpZGdldCcpLmVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIGxldCAkd2lkZ2V0ID0gJCh0aGlzKTtcbiAgICAgICAgICAgICAgICBsZXQgY29tcG9uZW50ID0gJHdpZGdldC5jb21wb25lbnQoKTtcbiAgICAgICAgICAgICAgICBpZiAoY29tcG9uZW50ICYmICd2YWwnIGluIGNvbXBvbmVudCkge1xuICAgICAgICAgICAgICAgICAgICBsZXQgd2lkZ2V0X25hbWUgPSAkd2lkZ2V0LmRhdGEoJ25hbWUnKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHdpZGdldF9uYW1lIGluIHZhbHVlcykge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29tcG9uZW50LnZhbCh2YWx1ZXNbd2lkZ2V0X25hbWVdKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIEdldHRlclxuICAgICAgICAgICAgbGV0IGRhdGEgPSB7fTtcblxuICAgICAgICAgICAgLy8gR2V0IHdpZGdldCB2YWx1ZXNcbiAgICAgICAgICAgIHRoaXMuJC5zaGFsbG93RmluZCgnLldpZGdldCcpLmVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIGxldCAkd2lkZ2V0ID0gJCh0aGlzKTtcbiAgICAgICAgICAgICAgICBsZXQgY29tcG9uZW50ID0gJHdpZGdldC5jb21wb25lbnQoKTtcbiAgICAgICAgICAgICAgICBpZiAoY29tcG9uZW50ICYmICd2YWwnIGluIGNvbXBvbmVudCkge1xuICAgICAgICAgICAgICAgICAgICBsZXQgd2lkZ2V0X25hbWUgPSAkd2lkZ2V0LmRhdGEoJ25hbWUnKTtcbiAgICAgICAgICAgICAgICAgICAgZGF0YVt3aWRnZXRfbmFtZV0gPSBjb21wb25lbnQudmFsKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIC8vIEFsc28gZ2V0IHJlZ3VsYXIgaGlkZGVuIGlucHV0cyAobm9uLXdpZGdldCBpbnB1dHMpXG4gICAgICAgICAgICB0aGlzLiQuZmluZCgnaW5wdXRbdHlwZT1cImhpZGRlblwiXVtuYW1lXScpLmVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIGxldCAkaW5wdXQgPSAkKHRoaXMpO1xuICAgICAgICAgICAgICAgIGxldCBuYW1lID0gJGlucHV0LmF0dHIoJ25hbWUnKTtcbiAgICAgICAgICAgICAgICBpZiAobmFtZSkge1xuICAgICAgICAgICAgICAgICAgICBkYXRhW25hbWVdID0gJGlucHV0LnZhbCgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICByZXR1cm4gZGF0YTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGdldF9lcnJvcihuYW1lKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmRhdGEuZXJyb3JzW25hbWVdO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlbmRlciBhbiBlcnJvciBpbiB0aGUgZm9ybSdzIGVycm9yIGNvbnRhaW5lclxuICAgICAqXG4gICAgICogSGFuZGxlcyBib3RoIGZpZWxkLXNwZWNpZmljIHZhbGlkYXRpb24gZXJyb3JzIGFuZCBnZW5lcmljIGVycm9ycy5cbiAgICAgKiBDYW4gYmUgY2FsbGVkIGJ5IGV4dGVybmFsIGhhbmRsZXJzIChlLmcuLCBtb2RhbCBvbl9zdWJtaXQpIG9yIGludGVybmFsbHlcbiAgICAgKiBieSB0aGUgZm9ybSdzIG93biBzdWJtaXQoKSBtZXRob2QuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge0Vycm9yfE9iamVjdH0gZXJyb3IgLSBFcnJvciBvYmplY3QgZnJvbSBBamF4IGNhbGxcbiAgICAgKi9cbiAgICBhc3luYyByZW5kZXJfZXJyb3IoZXJyb3IpIHtcbiAgICAgICAgLy8gSGFuZGxlIHZhbGlkYXRpb24gZXJyb3JzIC0gYXBwbHkgdG8gZmllbGRzXG4gICAgICAgIGlmIChlcnJvci50eXBlID09PSAnZm9ybV9lcnJvcicgJiYgZXJyb3IuZGV0YWlscykge1xuICAgICAgICAgICAgYXdhaXQgRm9ybV9VdGlscy5hcHBseV9mb3JtX2Vycm9ycyh0aGlzLiQsIGVycm9yLmRldGFpbHMpO1xuXG4gICAgICAgICAgICAvLyBOb3RpZnkgdGFicyBvZiB2YWxpZGF0aW9uIGVycm9ycyBmb3IgZXJyb3IgYmFkZ2VzIGFuZCBhdXRvLXN3aXRjaGluZ1xuICAgICAgICAgICAgaWYgKHRoaXMudGFicykge1xuICAgICAgICAgICAgICAgIHRoaXMudGFicy5oYW5kbGVfdmFsaWRhdGlvbl9lcnJvcnMoZXJyb3IuZGV0YWlscyk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIEZvcm1fVXRpbHMgaGFuZGxlcyBhbGwgcmVuZGVyaW5nIChpbmxpbmUgZXJyb3JzICsgdW5tYXRjaGVkIGVycm9ycyBhbGVydClcbiAgICAgICAgICAgIC8vIERvbid0IGNhbGwgUnN4LnJlbmRlcl9lcnJvcigpIHRvIGF2b2lkIGR1cGxpY2F0ZSBhbGVydHNcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIEZvciBub24tZm9ybSBlcnJvcnMgKGZhdGFsLCBhdXRoLCBuZXR3b3JrLCBldGMuKSwgcmVuZGVyIGluIGZvcm0ncyBlcnJvciBjb250YWluZXJcbiAgICAgICAgUnN4LnJlbmRlcl9lcnJvcihlcnJvciwgdGhpcy4kaWQoJ2Vycm9yJykpO1xuICAgIH1cblxuICAgIGFzeW5jIHN1Ym1pdCgpIHtcbiAgICAgICAgLy8gQ2xlYXIgYW55IHByZXZpb3VzIGVycm9yc1xuICAgICAgICBGb3JtX1V0aWxzLnJlc2V0X2Zvcm1fZXJyb3JzKHRoaXMuJCk7XG4gICAgICAgIHRoaXMuJGlkKCdlcnJvcicpLmVtcHR5KCk7XG5cbiAgICAgICAgLy8gQ2xlYXIgdGFiIGVycm9yIGJhZGdlcyBpZiB0YWJzIGFyZSBwcmVzZW50XG4gICAgICAgIGlmICh0aGlzLnRhYnMpIHtcbiAgICAgICAgICAgIHRoaXMudGFicy5jbGVhcl9lcnJvcl9iYWRnZXMoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFNlcmlhbGl6ZSBhbGwgZmllbGQgdmFsdWVzXG4gICAgICAgIGxldCB2YWx1ZXMgPSB0aGlzLnZhbHMoKTtcblxuICAgICAgICAvLyBDYWxsIHN1Ym1pdCBoYW5kbGVyXG4gICAgICAgIGlmICghdGhpcy5hcmdzLmNvbnRyb2xsZXIgfHwgIXRoaXMuYXJncy5tZXRob2QpIHtcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0Zvcm06IE5vIGNvbnRyb2xsZXIvbWV0aG9kIHByb3ZpZGVkJyk7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0Zvcm0gY29uZmlndXJhdGlvbiBlcnJvcjogTWlzc2luZyBjb250cm9sbGVyIG9yIG1ldGhvZCcpO1xuICAgICAgICB9XG5cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIC8vIEJ1aWxkIEFqYXggVVJMIGZyb20gY29udHJvbGxlciBhbmQgbWV0aG9kXG4gICAgICAgICAgICBjb25zdCBhamF4X3VybCA9IGAvX2FqYXgvJHt0aGlzLmFyZ3MuY29udHJvbGxlcn0vJHt0aGlzLmFyZ3MubWV0aG9kfWA7XG5cbiAgICAgICAgICAgIC8vIENhbGwgQWpheCBlbmRwb2ludCAtIHJlc3BvbnNlIGlzIGRpcmVjdGx5IHdoYXQgUEhQIHJldHVybmVkXG4gICAgICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBBamF4LmNhbGwoYWpheF91cmwsIHZhbHVlcyk7XG5cbiAgICAgICAgICAgIC8vIFN1Y2Nlc3MhIEhhbmRsZSByZXN1bHRcbiAgICAgICAgICAgIGlmIChyZXN1bHQgJiYgcmVzdWx0LnJlZGlyZWN0KSB7XG4gICAgICAgICAgICAgICAgLy8gUmVkaXJlY3QgdG8gVVJMXG4gICAgICAgICAgICAgICAgd2luZG93LmxvY2F0aW9uLmhyZWYgPSByZXN1bHQucmVkaXJlY3Q7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIC8vIFN1Y2Nlc3Mgd2l0aG91dCByZWRpcmVjdFxuICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKCdGb3JtIHN1Ym1pdHRlZCBzdWNjZXNzZnVsbHknLCByZXN1bHQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgLy8gUmVuZGVyIGVycm9yIChoYW5kbGVzIGJvdGggdmFsaWRhdGlvbiBhbmQgZ2VuZXJpYyBlcnJvcnMpXG4gICAgICAgICAgICBhd2FpdCB0aGlzLnJlbmRlcl9lcnJvcihlcnJvcik7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBhc3luYyBzZWVkKCkge1xuICAgICAgICBjb25zdCBwcm9taXNlcyA9IFtdO1xuICAgICAgICB0aGlzLiQuc2hhbGxvd0ZpbmQoJy5Gb3JtX0ZpZWxkJykuZWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBsZXQgY29tcG9uZW50ID0gJCh0aGlzKS5jb21wb25lbnQoKTtcbiAgICAgICAgICAgIGlmIChjb21wb25lbnQgJiYgJ3NlZWQnIGluIGNvbXBvbmVudCkge1xuICAgICAgICAgICAgICAgIHByb21pc2VzLnB1c2goY29tcG9uZW50LnNlZWQoKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICBhd2FpdCBQcm9taXNlLmFsbChwcm9taXNlcyk7XG4gICAgfVxufVxuIl0sIm1hcHBpbmdzIjoiOztBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU1BLFFBQVEsU0FBU0MsZ0JBQWdCLENBQUM7RUFDcENDLFNBQVNBLENBQUEsRUFBRztJQUNSLElBQUksQ0FBQ0MsSUFBSSxDQUFDQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUN2QixJQUFJLENBQUNELElBQUksQ0FBQ0UsTUFBTSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDdkIsSUFBSSxDQUFDQyxJQUFJLEdBQUcsSUFBSSxDQUFDLENBQUM7O0lBRWxCO0lBQ0EsSUFBSUgsSUFBSSxHQUFHLElBQUksQ0FBQ0ksSUFBSSxDQUFDSixJQUFJO0lBRXpCLElBQUksT0FBT0EsSUFBSSxLQUFLLFFBQVEsRUFBRTtNQUMxQixJQUFJO1FBQ0E7UUFDQTtRQUNBLE1BQU1LLE9BQU8sR0FBR0MsQ0FBQyxDQUFDLFlBQVksQ0FBQyxDQUFDQyxJQUFJLENBQUNQLElBQUksQ0FBQyxDQUFDUSxJQUFJLENBQUMsQ0FBQztRQUNqRFIsSUFBSSxHQUFHUyxXQUFXLENBQUNKLE9BQU8sQ0FBQztNQUMvQixDQUFDLENBQUMsT0FBT0ssQ0FBQyxFQUFFO1FBQ1JDLE9BQU8sQ0FBQ0MsS0FBSyxD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