Files
rspade_system/storage-broken/rsx-tmp/babel_00c1c8ecac2096cf48fca2aa76715a46.js
root 9ebcc359ae Fix code quality violations and enhance ROUTE-EXISTS-01 rule
Implement JQHTML function cache ID system and fix bundle compilation
Implement underscore prefix for system tables
Fix JS syntax linter to support decorators and grant exception to Task system
SPA: Update planning docs and wishlists with remaining features
SPA: Document Navigation API abandonment and future enhancements
Implement SPA browser integration with History API (Phase 1)
Convert contacts view page to SPA action
Convert clients pages to SPA actions and document conversion procedure
SPA: Merge GET parameters and update documentation
Implement SPA route URL generation in JavaScript and PHP
Implement SPA bootstrap controller architecture
Add SPA routing manual page (rsx:man spa)
Add SPA routing documentation to CLAUDE.md
Phase 4 Complete: Client-side SPA routing implementation
Update get_routes() consumers for unified route structure
Complete SPA Phase 3: PHP-side route type detection and is_spa flag
Restore unified routes structure and Manifest_Query class
Refactor route indexing and add SPA infrastructure
Phase 3 Complete: SPA route registration in manifest
Implement SPA Phase 2: Extract router code and test decorators
Rename Jqhtml_Component to Component and complete SPA foundation setup

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-19 17:48:15 +00:00

343 lines
40 KiB
JavaScript
Executable File

"use strict";
/**
* Rsx_Modal Component
*
* Instance of a modal dialog. Handles lifecycle, sizing, and user interaction.
* Typically created and managed by the Modal static API class.
*/
class Rsx_Modal extends Component {
on_create() {
this.data.title = '';
this.data.body_content = null;
this.data.buttons = [];
this.data.closable = true;
this.data.max_width = 800;
this.data.close_on_submit = true;
this.data.is_visible = false;
this.data.result_promise = null;
this.data.resolve_fn = null;
// Store reference to bootstrap modal instance
this._bs_modal = null;
this._resize_handler = null;
}
on_ready() {
const that = this;
// Set up close button handler
this.$id('close_btn').on('click', function (e) {
e.preventDefault();
if (that.data.closable) {
that.close(false);
}
});
// Set up backdrop click handler
this.$id('backdrop').on('click', function (e) {
if (that.data.closable && e.target === this) {
that.close(false);
}
});
// Set up ESC key handler
$(document).on('keydown.rsx_modal_' + this._cid, function (e) {
if (e.key === 'Escape' && that.data.closable && that.data.is_visible) {
that.close(false);
}
});
// Set up resize handler
this._resize_handler = debounce(() => {
if (that.data.is_visible) {
that._apply_sizing();
}
}, 100);
$(window).on('resize.rsx_modal_' + this._cid, this._resize_handler);
}
/**
* Configure and show the modal
* @param {Object} options - Modal options (title, body, buttons, etc.)
* @param {Object} internal_options - Internal options (skip_backdrop, animate)
*/
async show(options) {
let internal_options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
const that = this;
const skip_backdrop = internal_options.skip_backdrop || false;
const should_animate = internal_options.animate || false;
console.log('[Rsx_Modal] show() called with options:', options);
// Store options
this.data.title = options.title || '';
this.data.closable = options.closable !== undefined ? options.closable : true;
this.data.max_width = options.max_width || 800;
this.data.close_on_submit = options.close_on_submit !== undefined ? options.close_on_submit : true;
this.data.buttons = options.buttons || [];
this.data.skip_backdrop = skip_backdrop;
this.data.icon = options.icon || null;
console.log('[Rsx_Modal] Setting title to:', this.data.title);
console.log('[Rsx_Modal] Title element:', this.$id('title'));
// Set title
this.$id('title').text(this.data.title);
// Show/hide close button based on closable
if (this.data.closable) {
this.$id('close_btn').show();
} else {
this.$id('close_btn').hide();
}
// Set body content (with optional icon)
this._set_body_content(options.body, this.data.icon);
// Set buttons
this._set_buttons();
// Create promise that will resolve when modal closes
const result_promise = new Promise(resolve => {
that.data.resolve_fn = resolve;
});
// Show modal and backdrop
this.data.is_visible = true;
// Append to body so it's on top (don't append backdrop if using shared)
if (!skip_backdrop) {
$('body').append(this.$id('backdrop'));
}
$('body').append(this.$);
// Apply sizing before showing
this._apply_sizing();
// Fade in modal (and backdrop if not using shared)
await this._fade_in(should_animate);
// Auto-focus first input element
this._focus_first_input();
return result_promise;
}
/**
* Set body content with optional icon
*/
_set_body_content(body, icon) {
const $body = this.$id('body');
$body.empty();
// If icon provided, add it
if (icon) {
const $icon = $(`<i class="bi bi-${icon} modal-icon"></i>`);
$body.append($icon);
$body.addClass('has-icon');
} else {
$body.removeClass('has-icon');
}
// Get or create body content wrapper
let $content = this.$id('body_content');
if (!$content.exists()) {
$content = $('<div class="modal-body-content"></div>');
$body.append($content);
}
if (typeof body === 'string') {
// Text content - escape and convert newlines
const escaped = $('<div>').text(body).html().replace(/\n/g, '<br>');
$content.html(escaped);
} else if (body instanceof jQuery) {
// jQuery element
$content.append(body);
} else if (body && typeof body === 'object') {
// Assume it's a jqhtml component instance
$content.append(body.$);
}
}
/**
* Set buttons in footer
*/
_set_buttons() {
const that = this;
const $footer = this.$id('footer');
$footer.empty();
if (this.data.buttons.length === 0) {
$footer.hide();
return;
}
$footer.show();
for (let button_def of this.data.buttons) {
const $button = $('<button>').attr('type', 'button').addClass('btn').addClass(button_def.class || 'btn-secondary').text(button_def.label || 'Button');
$button.on('click', async function () {
let result = button_def.value;
let had_callback = false;
// If button has a callback, call it and use return value as result
if (button_def.callback && typeof button_def.callback === 'function') {
had_callback = true;
result = await button_def.callback();
}
// If callback returned false, keep modal open (but not if just button value is false)
if (result === false && had_callback) {
return;
}
// Close modal with result
that.close(result);
});
$footer.append($button);
}
}
/**
* Calculate and apply responsive sizing
*/
_apply_sizing() {
const viewport_width = $(window).width();
const viewport_height = $(window).height();
const is_mobile = viewport_width < 768;
// Calculate max width based on viewport
let max_width = this.data.max_width;
const viewport_limit = is_mobile ? viewport_width * 0.9 : viewport_width * 0.8;
max_width = Math.min(max_width, viewport_limit);
// Try to constrain to 60% width for better proportions on desktop
if (!is_mobile) {
const preferred_width = viewport_width * 0.6;
if (preferred_width < max_width) {
max_width = preferred_width;
}
}
// Apply width
this.$id('dialog').css('max-width', max_width + 'px');
// Check if content exceeds 80% height
const content_height = this.$id('dialog').outerHeight();
const max_height = viewport_height * 0.8;
if (content_height > max_height) {
// Enable scrolling
this.$id('dialog').css('max-height', max_height + 'px');
this.$id('body').css({
'overflow-y': 'auto',
'max-height': max_height - 150 + 'px' // Account for header/footer
});
} else {
// Reset scrolling
this.$id('dialog').css('max-height', '');
this.$id('body').css({
'overflow-y': '',
'max-height': ''
});
}
// Mobile edge spacing
if (is_mobile) {
this.$id('dialog').css('margin', '5%');
} else {
this.$id('dialog').css('margin', '0');
}
}
/**
* Show animation (instant or with fly-in)
* @param {boolean} animate - Whether to animate the modal entrance
*/
async _fade_in() {
let animate = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
if (animate) {
// Initial state: modal positioned above final position
this.$.css('display', 'flex').css('opacity', '0');
this.$id('modal').css({
'transform': 'translate(0, -50px)',
'opacity': '0'
});
this.$id('backdrop').css('display', 'block').addClass('show');
// Force reflow
this.$id('modal')[0].offsetHeight;
// Trigger animation
this.$id('modal').addClass('show').css({
'transform': 'translate(0, 0)',
'opacity': '1'
});
this.$.css('opacity', '1');
// Wait for animation to complete
await new Promise(resolve => setTimeout(resolve, 150));
} else {
// Disable transitions temporarily for instant display
this.$id('dialog').css('transition', 'none');
// Show modal and backdrop instantly
this.$.css('display', 'flex').css('opacity', '1');
this.$id('modal').addClass('show').css('opacity', '1');
this.$id('backdrop').css('display', 'block').addClass('show');
// Force reflow to apply the no-transition state
this.$id('dialog')[0].offsetHeight;
// Re-enable transitions for future animations
this.$id('dialog').css('transition', '');
}
return Promise.resolve();
}
/**
* Focus the first input element in the modal
*/
_focus_first_input() {
// Find first input/textarea/select in modal body
const $first_input = this.$id('body').find('input:not([type="hidden"]), textarea, select').first();
if ($first_input.exists()) {
requestAnimationFrame(() => {
$first_input.focus();
// Select text if it's an input with existing value
if ($first_input.is('input[type="text"], input[type="email"]') && $first_input.val()) {
$first_input.select();
}
});
}
}
/**
* Close the modal instantly
*/
async close(result) {
const that = this;
// Mark as not visible
this.data.is_visible = false;
// Remove event listeners
$(document).off('keydown.rsx_modal_' + this._cid);
$(window).off('resize.rsx_modal_' + this._cid);
// Hide instantly (no fade out)
this.$.hide();
this.$id('backdrop').hide();
// Remove from DOM
this.$.remove();
this.$id('backdrop').remove();
// Resolve promise
if (this.data.resolve_fn) {
this.data.resolve_fn(result);
this.data.resolve_fn = null;
}
}
/**
* Apply validation errors to form fields in modal body
*/
apply_errors(errors) {
// Use Form_Utils to apply errors to elements within modal body
Form_Utils.apply_form_errors(this.$id('body'), errors);
}
}
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJSc3hfTW9kYWwiLCJKcWh0bWxfQ29tcG9uZW50Iiwib25fY3JlYXRlIiwiZGF0YSIsInRpdGxlIiwiYm9keV9jb250ZW50IiwiYnV0dG9ucyIsImNsb3NhYmxlIiwibWF4X3dpZHRoIiwiY2xvc2Vfb25fc3VibWl0IiwiaXNfdmlzaWJsZSIsInJlc3VsdF9wcm9taXNlIiwicmVzb2x2ZV9mbiIsIl9ic19tb2RhbCIsIl9yZXNpemVfaGFuZGxlciIsIm9uX3JlYWR5IiwidGhhdCIsIiRpZCIsIm9uIiwiZSIsInByZXZlbnREZWZhdWx0IiwiY2xvc2UiLCJ0YXJnZXQiLCIkIiwiZG9jdW1lbnQiLCJfY2lkIiwia2V5IiwiZGVib3VuY2UiLCJfYXBwbHlfc2l6aW5nIiwid2luZG93Iiwic2hvdyIsIm9wdGlvbnMiLCJpbnRlcm5hbF9vcHRpb25zIiwiYXJndW1lbnRzIiwibGVuZ3RoIiwidW5kZWZpbmVkIiwic2tpcF9iYWNrZHJvcCIsInNob3VsZF9hbmltYXRlIiwiYW5pbWF0ZSIsImNvbnNvbGUiLCJsb2ciLCJpY29uIiwidGV4dCIsImhpZGUiLCJfc2V0X2JvZHlfY29udGVudCIsImJvZHkiLCJfc2V0X2J1dHRvbnMiLCJQcm9taXNlIiwicmVzb2x2ZSIsImFwcGVuZCIsIl9mYWRlX2luIiwiX2ZvY3VzX2ZpcnN0X2lucHV0IiwiJGJvZHkiLCJlbXB0eSIsIiRpY29uIiwiYWRkQ2xhc3MiLCJyZW1vdmVDbGFzcyIsIiRjb250ZW50IiwiZXhpc3RzIiwiZXNjYXBlZCIsImh0bWwiLCJyZXBsYWNlIiwialF1ZXJ5IiwiJGZvb3RlciIsImJ1dHRvbl9kZWYiLCIkYnV0dG9uIiwiYXR0ciIsImNsYXNzIiwibGFiZWwiLCJyZXN1bHQiLCJ2YWx1ZSIsImhhZF9jYWxsYmFjayIsImNhbGxiYWNrIiwidmlld3BvcnRfd2lkdGgiLCJ3aWR0aCIsInZpZXdwb3J0X2hlaWdodCIsImhlaWdodCIsImlzX21vYmlsZSIsInZpZXdwb3J0X2xpbWl0IiwiTWF0aCIsIm1pbiIsInByZWZlcnJlZF93aWR0aCIsImNzcyIsImNvbnRlbnRfaGVpZ2h0Iiwib3V0ZXJIZWlnaHQiLCJtYXhfaGVpZ2h0Iiwib2Zmc2V0SGVpZ2h0Iiwic2V0VGltZW91dCIsIiRmaXJzdF9pbnB1dCIsImZpbmQiLCJmaXJzdCIsInJlcXVlc3RBbmltYXRpb25GcmFtZSIsImZvY3VzIiwiaXMiLCJ2YWwiLCJzZWxlY3QiLCJvZmYiLCJyZW1vdmUiLCJhcHBseV9lcnJvcnMiLCJlcnJvcnMiLCJGb3JtX1V0aWxzIiwiYXBwbHlfZm9ybV9lcnJvcnMiXSwic291cmNlcyI6WyJyc3gvdGhlbWUvY29tcG9uZW50cy9tb2RhbC9yc3hfbW9kYWwuanMiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBSc3hfTW9kYWwgQ29tcG9uZW50XG4gKlxuICogSW5zdGFuY2Ugb2YgYSBtb2RhbCBkaWFsb2cuIEhhbmRsZXMgbGlmZWN5Y2xlLCBzaXppbmcsIGFuZCB1c2VyIGludGVyYWN0aW9uLlxuICogVHlwaWNhbGx5IGNyZWF0ZWQgYW5kIG1hbmFnZWQgYnkgdGhlIE1vZGFsIHN0YXRpYyBBUEkgY2xhc3MuXG4gKi9cbmNsYXNzIFJzeF9Nb2RhbCBleHRlbmRzIEpxaHRtbF9Db21wb25lbnQge1xuICAgIG9uX2NyZWF0ZSgpIHtcbiAgICAgICAgdGhpcy5kYXRhLnRpdGxlID0gJyc7XG4gICAgICAgIHRoaXMuZGF0YS5ib2R5X2NvbnRlbnQgPSBudWxsO1xuICAgICAgICB0aGlzLmRhdGEuYnV0dG9ucyA9IFtdO1xuICAgICAgICB0aGlzLmRhdGEuY2xvc2FibGUgPSB0cnVlO1xuICAgICAgICB0aGlzLmRhdGEubWF4X3dpZHRoID0gODAwO1xuICAgICAgICB0aGlzLmRhdGEuY2xvc2Vfb25fc3VibWl0ID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5kYXRhLmlzX3Zpc2libGUgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5kYXRhLnJlc3VsdF9wcm9taXNlID0gbnVsbDtcbiAgICAgICAgdGhpcy5kYXRhLnJlc29sdmVfZm4gPSBudWxsO1xuXG4gICAgICAgIC8vIFN0b3JlIHJlZmVyZW5jZSB0byBib290c3RyYXAgbW9kYWwgaW5zdGFuY2VcbiAgICAgICAgdGhpcy5fYnNfbW9kYWwgPSBudWxsO1xuICAgICAgICB0aGlzLl9yZXNpemVfaGFuZGxlciA9IG51bGw7XG4gICAgfVxuXG4gICAgb25fcmVhZHkoKSB7XG4gICAgICAgIGNvbnN0IHRoYXQgPSB0aGlzO1xuXG4gICAgICAgIC8vIFNldCB1cCBjbG9zZSBidXR0b24gaGFuZGxlclxuICAgICAgICB0aGlzLiRpZCgnY2xvc2VfYnRuJykub24oJ2NsaWNrJywgZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICAgIGlmICh0aGF0LmRhdGEuY2xvc2FibGUpIHtcbiAgICAgICAgICAgICAgICB0aGF0LmNsb3NlKGZhbHNlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gU2V0IHVwIGJhY2tkcm9wIGNsaWNrIGhhbmRsZXJcbiAgICAgICAgdGhpcy4kaWQoJ2JhY2tkcm9wJykub24oJ2NsaWNrJywgZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgICAgIGlmICh0aGF0LmRhdGEuY2xvc2FibGUgJiYgZS50YXJnZXQgPT09IHRoaXMpIHtcbiAgICAgICAgICAgICAgICB0aGF0LmNsb3NlKGZhbHNlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gU2V0IHVwIEVTQyBrZXkgaGFuZGxlclxuICAgICAgICAkKGRvY3VtZW50KS5vbigna2V5ZG93bi5yc3hfbW9kYWxfJyArIHRoaXMuX2NpZCwgZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgICAgIGlmIChlLmtleSA9PT0gJ0VzY2FwZScgJiYgdGhhdC5kYXRhLmNsb3NhYmxlICYmIHRoYXQuZGF0YS5pc192aXNpYmxlKSB7XG4gICAgICAgICAgICAgICAgdGhhdC5jbG9zZShmYWxzZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIFNldCB1cCByZXNpemUgaGFuZGxlclxuICAgICAgICB0aGlzLl9yZXNpemVfaGFuZGxlciA9IGRlYm91bmNlKCgpID0+IHtcbiAgICAgICAgICAgIGlmICh0aGF0LmRhdGEuaXNfdmlzaWJsZSkge1xuICAgICAgICAgICAgICAgIHRoYXQuX2FwcGx5X3NpemluZygpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9LCAxMDApO1xuXG4gICAgICAgICQod2luZG93KS5vbigncmVzaXplLnJzeF9tb2RhbF8nICsgdGhpcy5fY2lkLCB0aGlzLl9yZXNpemVfaGFuZGxlcik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ29uZmlndXJlIGFuZCBzaG93IHRoZSBtb2RhbFxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zIC0gTW9kYWwgb3B0aW9ucyAodGl0bGUsIGJvZHksIGJ1dHRvbnMsIGV0Yy4pXG4gICAgICogQHBhcmFtIHtPYmplY3R9IGludGVybmFsX29wdGlvbnMgLSBJbnRlcm5hbCBvcHRpb25zIChza2lwX2JhY2tkcm9wLCBhbmltYXRlKVxuICAgICAqL1xuICAgIGFzeW5jIHNob3cob3B0aW9ucywgaW50ZXJuYWxfb3B0aW9ucyA9IHt9KSB7XG4gICAgICAgIGNvbnN0IHRoYXQgPSB0aGlzO1xuICAgICAgICBjb25zdCBza2lwX2JhY2tkcm9wID0gaW50ZXJuYWxfb3B0aW9ucy5za2lwX2JhY2tkcm9wIHx8IGZhbHNlO1xuICAgICAgICBjb25zdCBzaG91bGRfYW5pbWF0ZSA9IGludGVybmFsX29wdGlvbnMuYW5pbWF0ZSB8fCBmYWxzZTtcblxuICAgICAgICBjb25zb2xlLmxvZygnW1JzeF9Nb2RhbF0gc2hvdygpIGNhbGxlZCB3aXRoIG9wdGlvbnM6Jywgb3B0aW9ucyk7XG5cbiAgICAgICAgLy8gU3RvcmUgb3B0aW9uc1xuICAgICAgICB0aGlzLmRhdGEudGl0bGUgPSBvcHRpb25zLnRpdGxlIHx8ICcnO1xuICAgICAgICB0aGlzLmRhdGEuY2xvc2FibGUgPSBvcHRpb25zLmNsb3NhYmxlICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLmNsb3NhYmxlIDogdHJ1ZTtcbiAgICAgICAgdGhpcy5kYXRhLm1heF93aWR0aCA9IG9wdGlvbnMubWF4X3dpZHRoIHx8IDgwMDtcbiAgICAgICAgdGhpcy5kYXRhLmNsb3NlX29uX3N1Ym1pdCA9IG9wdGlvbnMuY2xvc2Vfb25fc3VibWl0ICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLmNsb3NlX29uX3N1Ym1pdCA6IHRydWU7XG4gICAgICAgIHRoaXMuZGF0YS5idXR0b25zID0gb3B0aW9ucy5idXR0b25zIHx8IFtdO1xuICAgICAgICB0aGlzLmRhdGEuc2tpcF9iYWNrZHJvcCA9IHNraXBfYmFja2Ryb3A7XG4gICAgICAgIHRoaXMuZGF0YS5pY29uID0gb3B0aW9ucy5pY29uIHx8IG51bGw7XG5cbiAgICAgICAgY29uc29sZS5sb2coJ1tSc3hfTW9kYWxdIFNldHRpbmcgdGl0bGUgdG86JywgdGhpcy5kYXRhLnRpdGxlKTtcbiAgICAgICAgY29uc29sZS5sb2coJ1tSc3hfTW9kYWxdIFRpdGxlIGVsZW1lbnQ6JywgdGhpcy4kaWQoJ3RpdGxlJykpO1xuXG4gICAgICAgIC8vIFNldCB0aXRsZVxuICAgICAgICB0aGlzLiRpZCgndGl0bGUnKS50ZXh0KHRoaXMuZGF0YS50aXRsZSk7XG5cbiAgICAgICAgLy8gU2hvdy9oaWRlIGNsb3NlIGJ1dHRvbiBiYXNlZCBvbiBjbG9zYWJsZVxuICAgICAgICBpZiAodGhpcy5kYXRhLmNsb3NhYmxlKSB7XG4gICAgICAgICAgICB0aGlzLiRpZCgnY2xvc2VfYnRuJykuc2hvdygpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy4kaWQoJ2Nsb3NlX2J0bicpLmhpZGUoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFNldCBib2R5IGNvbnRlbnQgKHdpdGggb3B0aW9uYWwgaWNvbilcbiAgICAgICAgdGhpcy5fc2V0X2JvZHlfY29udGVudChvcHRpb25zLmJvZHksIHRoaXMuZGF0YS5pY29uKTtcblxuICAgICAgICAvLyBTZXQgYnV0dG9uc1xuICAgICAgICB0aGlzLl9zZXRfYnV0dG9ucygpO1xuXG4gICAgICAgIC8vIENyZWF0ZSBwcm9taXNlIHRoYXQgd2lsbCByZXNvbHZlIHdoZW4gbW9kYWwgY2xvc2VzXG4gICAgICAgIGNvbnN0IHJlc3VsdF9wcm9taXNlID0gbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHtcbiAgICAgICAgICAgIHRoYXQuZGF0YS5yZXNvbHZlX2ZuID0gcmVzb2x2ZTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gU2hvdyBtb2RhbCBhbmQgYmFja2Ryb3BcbiAgICAgICAgdGhpcy5kYXRhLmlzX3Zpc2libGUgPSB0cnVlO1xuXG4gICAgICAgIC8vIEFwcGVuZCB0byBib2R5IHNvIGl0J3Mgb24gdG9wIChkb24ndCBhcHBlbmQgYmFja2Ryb3AgaWYgdXNpbmcgc2hhcmVkKVxuICAgICAgICBpZiAoIXNraXBfYmFja2Ryb3ApIHtcbiAgICAgICAgICAgICQoJ2JvZHknKS5hcHBlbmQodGhpcy4kaWQoJ2JhY2tkcm9wJykpO1xuICAgICAgICB9XG4gICAgICAgICQoJ2JvZHknKS5hcHBlbmQodGhpcy4kKTtcblxuICAgICAgICAvLyBBcHBseSBzaXppbmcgYmVmb3JlIHNob3dpbmdcbiAgICAgICAgdGhpcy5fYXBwbHlfc2l6aW5nKCk7XG5cbiAgICAgICAgLy8gRmFkZSBpbiBtb2RhbCAoYW5kIGJhY2tkcm9wIGlmIG5vdCB1c2luZyBzaGFyZWQpXG4gICAgICAgIGF3YWl0IHRoaXMuX2ZhZGVfaW4oc2hvdWxkX2FuaW1hdGUpO1xuXG4gICAgICAgIC8vIEF1dG8tZm9jdXMgZmlyc3QgaW5wdXQgZWxlbWVudFxuICAgICAgICB0aGlzLl9mb2N1c19maXJzdF9pbnB1dCgpO1xuXG4gICAgICAgIHJldHVybiByZXN1bHRfcHJvbWlzZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTZXQgYm9keSBjb250ZW50IHdpdGggb3B0aW9uYWwgaWNvblxuICAgICAqL1xuICAgIF9zZXRfYm9keV9jb250ZW50KGJvZHksIGljb24pIHtcbiAgICAgICAgY29uc3QgJGJvZHkgPSB0aGlzLiRpZCgnYm9keScpO1xuICAgICAgICAkYm9keS5lbXB0eSgpO1xuXG4gICAgICAgIC8vIElmIGljb24gcHJvdmlkZWQsIGFkZCBpdFxuICAgICAgICBpZiAoaWNvbikge1xuICAgICAgICAgICAgY29uc3QgJGljb24gPSAkKGA8aSBjbGFzcz1cImJpIGJpLSR7aWNvbn0gbW9kYWwtaWNvblwiPjwvaT5gKTtcbiAgICAgICAgICAgICRib2R5LmFwcGVuZCgkaWNvbik7XG4gICAgICAgICAgICAkYm9keS5hZGRDbGFzcygnaGFzLWljb24nKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICRib2R5LnJlbW92ZUNsYXNzKCdoYXMtaWNvbicpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gR2V0IG9yIGNyZWF0ZSBib2R5IGNvbnRlbnQgd3JhcHBlclxuICAgICAgICBsZXQgJGNvbnRlbnQgPSB0aGlzLiRpZCgnYm9keV9jb250ZW50Jyk7XG4gICAgICAgIGlmICghJGNvbnRlbnQuZXhpc3RzKCkpIHtcbiAgICAgICAgICAgICRjb250ZW50ID0gJCgnPGRpdiBjbGFzcz1cIm1vZGFsLWJvZHktY29udGVudFwiPjwvZGl2PicpO1xuICAgICAgICAgICAgJGJvZHkuYXBwZW5kKCRjb250ZW50KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0eXBlb2YgYm9keSA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgIC8vIFRleHQgY29udGVudCAtIGVzY2FwZSBhbmQgY29udmVydCBuZXdsaW5lc1xuICAgICAgICAgICAgY29uc3QgZXNjYXBlZCA9ICQoJzxkaXY+JykudGV4dChib2R5KS5odG1sKCkucmVwbGFjZSgvXFxuL2csICc8YnI+Jyk7XG4gICAgICAgICAgICAkY29udGVudC5odG1sKGVzY2FwZWQpO1xuICAgICAgICB9IGVsc2UgaWYgKGJvZHkgaW5zdGFuY2VvZiBqUXVlcnkpIHtcbiAgICAgICAgICAgIC8vIGpRdWVyeSBlbGVtZW50XG4gICAgICAgICAgICAkY29udGVudC5hcHBlbmQoYm9keSk7XG4gICAgICAgIH0gZWxzZSBpZiAoYm9keSAmJiB0eXBlb2YgYm9keSA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgICAgIC8vIEFzc3VtZSBpdCdzIGEganFodG1sIGNvbXBvbmVudCBpbnN0YW5jZVxuICAgICAgICAgICAgJGNvbnRlbnQuYXBwZW5kKGJvZHkuJCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTZXQgYnV0dG9ucyBpbiBmb290ZXJcbiAgICAgKi9cbiAgICBfc2V0X2J1dHRvbnMoKSB7XG4gICAgICAgIGNvbnN0IHRoYXQgPSB0aGlzO1xuICAgICAgICBjb25zdCAkZm9vdGVyID0gdGhpcy4kaWQoJ2Zvb3RlcicpO1xuICAgICAgICAkZm9vdGVyLmVtcHR5KCk7XG5cbiAgICAgICAgaWYgKHRoaXMuZGF0YS5idXR0b25zLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgJGZvb3Rlci5oaWRlKCk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICAkZm9vdGVyLnNob3coKTtcblxuICAgICAgICBmb3IgKGxldCBidXR0b25fZGVmIG9mIHRoaXMuZGF0YS5idXR0b25zKSB7XG4gICAgICAgICAgICBjb25zdCAkYnV0dG9uID0gJCgnPGJ1dHRvbj4nKVxuICAgICAgICAgICAgICAgIC5hdHRyKCd0eXBlJywgJ2J1dHRvbicpXG4gICAgICAgICAgICAgICAgLmFkZENsYXNzKCdidG4nKVxuICAgICAgICAgICAgICAgIC5hZGRDbGFzcyhidXR0b25fZGVmLmNsYXNzIHx8ICdidG4tc2Vjb25kYXJ5JylcbiAgICAgICAgICAgICAgICAudGV4dChidXR0b25fZGVmLmxhYmVsIHx8ICdCdXR0b24nKTtcblxuICAgICAgICAgICAgJGJ1dHRvbi5vbignY2xpY2snLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgbGV0IHJlc3VsdCA9IGJ1dHRvbl9kZWYudmFsdWU7XG4gICAgICAgICAgICAgICAgbGV0IGhhZF9jYWxsYmFjayA9IGZhbHNlO1xuXG4gICAgICAgICAgICAgICAgLy8gSWYgYnV0dG9uIGhhcyBhIGNhbGxiYWNrLCBjYWxsIGl0IGFuZCB1c2UgcmV0dXJuIHZhbHVlIGFzIHJlc3VsdFxuICAgICAgICAgICAgICAgIGlmIChidXR0b25fZGVmLmNhbGxiYWNrICYmIHR5cGVvZiBidXR0b25fZGVmLmNhbGxiYWNrID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICAgICAgICAgIGhhZF9jYWxsYmFjayA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IGF3YWl0IGJ1dHRvbl9kZWYuY2FsbGJhY2soKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAvLyBJZiBjYWxsYmFjayByZXR1cm5lZCBmYWxzZSwga2VlcCBtb2RhbCBvcGVuIChidXQgbm90IGlmIGp1c3QgYnV0dG9uIHZhbHVlIGlzIGZhbHNlKVxuICAgICAgICAgICAgICAgIGlmIChyZXN1bHQgPT09IGZhbHNlICYmIGhhZF9jYWxsYmFjaykge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgLy8gQ2xvc2UgbW9kYWwgd2l0aCByZXN1bHRcbiAgICAgICAgICAgICAgICB0aGF0LmNsb3NlKHJlc3VsdCk7XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgJGZvb3Rlci5hcHBlbmQoJGJ1dHRvbik7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDYWxjdWxhdGUgYW5kIGFwcGx5IHJlc3BvbnNpdmUgc2l6aW5nXG4gICAgICovXG4gICAgX2FwcGx5X3NpemluZygpIHtcbiAgICAgICAgY29uc3Qgdmlld3BvcnRfd2lkdGggPSAkKHdpbmRvdykud2lkdGgoKTtcbiAgICAgICAgY29uc3Qgdmlld3BvcnRfaGVpZ2h0ID0gJCh3aW5kb3cpLmhlaWdodCgpO1xuICAgICAgICBjb25zdCBpc19tb2JpbGUgPSB2aWV3cG9ydF93aWR0aCA8IDc2ODtcblxuICAgICAgICAvLyBDYWxjdWxhdGUgbWF4IHdpZHRoIGJhc2VkIG9uIHZpZXdwb3J0XG4gICAgICAgIGxldCBtYXhfd2lkdGggPSB0aGlzLmRhdGEubWF4X3dpZHRoO1xuICAgICAgICBjb25zdCB2aWV3cG9ydF9saW1pdCA9IGlzX21vYmlsZSA/IHZpZXdwb3J0X3dpZHRoICogMC45IDogdmlld3BvcnRfd2lkdGggKiAwLjg7XG5cbiAgICAgICAgbWF4X3dpZHRoID0gTWF0aC5taW4obWF4X3dpZHRoLCB2aWV3cG9ydF9saW1pdCk7XG5cbiAgICAgICAgLy8gVHJ5IHRvIGNvbnN0cmFpbiB0byA2MCUgd2lkdGggZm9yIGJldHRlciBwcm9wb3J0aW9ucyBvbiBkZXNrdG9wXG4gICAgICAgIGlmICghaXNfbW9iaWxlKSB7XG4gICAgICAgICAgICBjb25zdCBwcmVmZXJyZWRfd2lkdGggPSB2aWV3cG9ydF93aWR0aCAqIDAuNjtcbiAgICAgICAgICAgIGlmIChwcmVmZXJyZWRfd2lkdGggPCBtYXhfd2lkdGgpIHtcbiAgICAgICAgICAgICAgICBtYXhfd2lkdGggPSBwcmVmZXJyZWRfd2lkdGg7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyBBcHBseSB3aWR0aFxuICAgICAgICB0aGlzLiRpZCgnZGlhbG9nJykuY3NzKCdtYXgtd2lkdGgnLCBtYXhfd2lkdGggKyAncHgnKTtcblxuICAgICAgICAvLyBDaGVjayBpZiBjb250ZW50IGV4Y2VlZHMgODAlIGhlaWdodFxuICAgICAgICBjb25zdCBjb250ZW50X2hlaWdodCA9IHRoaXMuJGlkKCdkaWFsb2cnKS5vdXRlckhlaWdodCgpO1xuICAgICAgICBjb25zdCBtYXhfaGVpZ2h0ID0gdmlld3BvcnRfaGVpZ2h0ICogMC44O1xuXG4gICAgICAgIGlmIChjb250ZW50X2hlaWdodCA+IG1heF9oZWlnaHQpIHtcbiAgICAgICAgICAgIC8vIEVuYWJsZSBzY3JvbGxpbmdcbiAgICAgICAgICAgIHRoaXMuJGlkKCdkaWFsb2cnKS5jc3MoJ21heC1oZWlnaHQnLCBtYXhfaGVpZ2h0ICsgJ3B4Jyk7XG4gICAgICAgICAgICB0aGlzLiRpZCgnYm9keScpLmNzcyh7XG4gICAgICAgICAgICAgICAgJ292ZXJmbG93LXknOiAnYXV0bycsXG4gICAgICAgICAgICAgICAgJ21heC1oZWlnaHQnOiBtYXhfaGVpZ2h0IC0gMTUwICsgJ3B4JywgLy8gQWNjb3VudCBmb3IgaGVhZGVyL2Zvb3RlclxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBSZXNldCBzY3JvbGxpbmdcbiAgICAgICAgICAgIHRoaXMuJGlkKCdkaWFsb2cnKS5jc3MoJ21heC1oZWlnaHQnLCAnJyk7XG4gICAgICAgICAgICB0aGlzLiRpZCgnYm9keScpLmNzcyh7XG4gICAgICAgICAgICAgICAgJ292ZXJmbG93LXknOiAnJyxcbiAgICAgICAgICAgICAgICAnbWF4LWhlaWdodCc6ICcnLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBNb2JpbGUgZWRnZSBzcGFjaW5nXG4gICAgICAgIGlmIChpc19tb2JpbGUpIHtcbiAgICAgICAgICAgIHRoaXMuJGlkKCdkaWFsb2cnKS5jc3MoJ21hcmdpbicsICc1JScpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy4kaWQoJ2RpYWxvZycpLmNzcygnbWFyZ2luJywgJzAnKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNob3cgYW5pbWF0aW9uIChpbnN0YW50IG9yIHdpdGggZmx5LWluKVxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gYW5pbWF0ZSAtIFdoZXRoZXIgdG8gYW5pbWF0ZSB0aGUgbW9kYWwgZW50cmFuY2VcbiAgICAgKi9cbiAgICBhc3luYyBfZmFkZV9pbihhbmltYXRlID0gZmFsc2UpIHtcbiAgICAgICAgaWYgKGFuaW1hdGUpIHtcbiAgICAgICAgICAgIC8vIEluaXRpYWwgc3RhdGU6IG1vZGFsIHBvc2l0aW9uZWQgYWJvdmUgZmluYWwgcG9zaXRpb25cbiAgICAgICAgICAgIHRoaXMuJC5jc3MoJ2Rpc3BsYXknLCAnZmxleCcpLmNzcygnb3BhY2l0eScsICcwJyk7XG4gICAgICAgICAgICB0aGlzLiRpZCgnbW9kYWwnKS5jc3Moe1xuICAgICAgICAgICAgICAgICd0cmFuc2Zvcm0nOiAndHJhbnNsYXRlKDAsIC01MHB4KScsXG4gICAgICAgICAgICAgICAgJ29wYWNpdHknOiAnMCdcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgdGhpcy4kaWQoJ2JhY2tkcm9wJykuY3NzKCdkaXNwbGF5JywgJ2Jsb2NrJykuYWRkQ2xhc3MoJ3Nob3cnKTtcblxuICAgICAgICAgICAgLy8gRm9yY2UgcmVmbG93XG4gICAgICAgICAgICB0aGlzLiRpZCgnbW9kYWwnKVswXS5vZmZzZXRIZWlnaHQ7XG5cbiAgICAgICAgICAgIC8vIFRyaWdnZXIgYW5pbWF0aW9uXG4gICAgICAgICAgICB0aGlzLiRpZCgnbW9kYWwnKS5hZGRDbGFzcygnc2hvdycpLmNzcyh7XG4gICAgICAgICAgICAgICAgJ3RyYW5zZm9ybSc6ICd0cmFuc2xhdGUoMCwgMCknLFxuICAgICAgICAgICAgICAgICdvcGFjaXR5JzogJzEnXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHRoaXMuJC5jc3MoJ29wYWNpdHknLCAnMScpO1xuXG4gICAgICAgICAgICAvLyBXYWl0IGZvciBhbmltYXRpb24gdG8gY29tcGxldGVcbiAgICAgICAgICAgIGF3YWl0IG5ldyBQcm9taXNlKHJlc29sdmUgPT4gc2V0VGltZW91dChyZXNvbHZlLCAxNTApKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIERpc2FibGUgdHJhbnNpdGlvbnMgdGVtcG9yYXJpbHkgZm9yIGluc3RhbnQgZGlzcGxheVxuICAgICAgICAgICAgdGhpcy4kaWQoJ2RpYWxvZycpLmNzcygndHJhbnNpdGlvbicsICdub25lJyk7XG5cbiAgICAgICAgICAgIC8vIFNob3cgbW9kYWwgYW5kIGJhY2tkcm9wIGluc3RhbnRseVxuICAgICAgICAgICAgdGhpcy4kLmNzcygnZGlzcGxheScsICdmbGV4JykuY3NzKCdvcGFjaXR5JywgJzEnKTtcbiAgICAgICAgICAgIHRoaXMuJGlkKCdtb2RhbCcpLmFkZENsYXNzKCdzaG93JykuY3NzKCdvcGFjaXR5JywgJzEnKTtcbiAgICAgICAgICAgIHRoaXMuJGlkKCdiYWNrZHJvcCcpLmNzcygnZGlzcGxheScsICdibG9jaycpLmFkZENsYXNzKCdzaG93Jyk7XG5cbiAgICAgICAgICAgIC8vIEZvcmNlIHJlZmxvdyB0byBhcHBseSB0aGUgbm8tdHJhbnNpdGlvbiBzdGF0ZVxuICAgICAgICAgICAgdGhpcy4kaWQoJ2RpYWxvZycpWzBdLm9mZnNldEhlaWdodDtcblxuICAgICAgICAgICAgLy8gUmUtZW5hYmxlIHRyYW5zaXRpb25zIGZvciBmdXR1cmUgYW5pbWF0aW9uc1xuICAgICAgICAgICAgdGhpcy4kaWQoJ2RpYWxvZycpLmNzcygndHJhbnNpdGlvbicsICcnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBGb2N1cyB0aGUgZmlyc3QgaW5wdXQgZWxlbWVudCBpbiB0aGUgbW9kYWxcbiAgICAgKi9cbiAgICBfZm9jdXNfZmlyc3RfaW5wdXQoKSB7XG4gICAgICAgIC8vIEZpbmQgZmlyc3QgaW5wdXQvdGV4dGFyZWEvc2VsZWN0IGluIG1vZGFsIGJvZHlcbiAgICAgICAgY29uc3QgJGZpcnN0X2lucHV0ID0gdGhpcy4kaWQoJ2JvZHknKS5maW5kKCdpbnB1dDpub3QoW3R5cGU9XCJoaWRkZW5cIl0pLCB0ZXh0YXJlYSwgc2VsZWN0JykuZmlyc3QoKTtcbiAgICAgICAgaWYgKCRmaXJzdF9pbnB1dC5leGlzdHMoKSkge1xuICAgICAgICAgICAgcmVxdWVzdEFuaW1hdGlvbkZyYW1lKCgpID0+IHtcbiAgICAgICAgICAgICAgICAkZmlyc3RfaW5wdXQuZm9jdXMoKTtcbiAgICAgICAgICAgICAgICAvLyBTZWxlY3QgdGV4dCBpZiBpdCdzIGFuIGlucHV0IHdpdGggZXhpc3RpbmcgdmFsdWVcbiAgICAgICAgICAgICAgICBpZiAoJGZpcnN0X2lucHV0LmlzKCdpbnB1dFt0eXBlPVwidGV4dFwiXSwgaW5wdXRbdHlwZT1cImVtYWlsXCJdJykgJiYgJGZpcnN0X2lucHV0LnZhbCgpKSB7XG4gICAgICAgICAgICAgICAgICAgICRmaXJzdF9pbnB1dC5zZWxlY3QoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENsb3NlIHRoZSBtb2RhbCBpbnN0YW50bHlcbiAgICAgKi9cbiAgICBhc3luYyBjbG9zZShyZXN1bHQpIHtcbiAgICAgICAgY29uc3QgdGhhdCA9IHRoaXM7XG5cbiAgICAgICAgLy8gTWFyayBhcyBub3QgdmlzaWJsZVxuICAgICAgICB0aGlzLmRhdGEuaXNfdmlzaWJsZSA9IGZhbHNlO1xuXG4gICAgICAgIC8vIFJlbW92ZSBldmVudCBsaXN0ZW5lcnNcbiAgICAgICAgJChkb2N1bWVudCkub2ZmKCdrZXlkb3duLnJzeF9tb2RhbF8nICsgdGhpcy5fY2lkKTtcbiAgICAgICAgJCh3aW5kb3cpLm9mZigncmVzaXplLnJzeF9tb2RhbF8nICsgdGhpcy5fY2lkKTtcblxuICAgICAgICAvLyBIaWRlIGluc3RhbnRseSAobm8gZmFkZSBvdXQpXG4gICAgICAgIHRoaXMuJC5oaWRlKCk7XG4gICAgICAgIHRoaXMuJGlkKCdiYWNrZHJvcCcpLmhpZGUoKTtcblxuICAgICAgICAvLyBSZW1vdmUgZnJvbSBET01cbiAgICAgICAgdGhpcy4kLnJlbW92ZSgpO1xuICAgICAgICB0aGlzLiRpZCgnYmFja2Ryb3AnKS5yZW1vdmUoKTtcblxuICAgICAgICAvLyBSZXNvbHZlIHByb21pc2VcbiAgICAgICAgaWYgKHRoaXMuZGF0YS5yZXNvbHZlX2ZuKSB7XG4gICAgICAgICAgICB0aGlzLmRhdGEucmVzb2x2ZV9mbihyZXN1bHQpO1xuICAgICAgICAgICAgdGhpcy5kYXRhLnJlc29sdmVfZm4gPSBudWxsO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQXBwbHkgdmFsaWRhdGlvbiBlcnJvcnMgdG8gZm9ybSBmaWVsZHMgaW4gbW9kYWwgYm9keVxuICAgICAqL1xuICAgIGFwcGx5X2Vycm9ycyhlcnJvcnMpIHtcbiAgICAgICAgLy8gVXNlIEZvcm1fVXRpbHMgdG8gYXBwbHkgZXJyb3JzIHRvIGVsZW1lbnRzIHdpdGhpbiBtb2RhbCBib2R5XG4gICAgICAgIEZvcm1fVXRpbHMuYXBwbHlfZm9ybV9lcnJvcnModGhpcy4kaWQoJ2JvZHknKSwgZXJyb3JzKTtcbiAgICB9XG59XG4iXSwibWFwcGluZ3MiOiI7O0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBTUEsU0FBUyxTQUFTQyxnQkFBZ0IsQ0FBQztFQUNyQ0MsU0FBU0EsQ0FBQSxFQUFHO0lBQ1IsSUFBSSxDQUFDQyxJQUFJLENBQUNDLEtBQUssR0FBRyxFQUFFO0lBQ3BCLElBQUksQ0FBQ0QsSUFBSSxDQUFDRSxZQUFZLEdBQUcsSUFBSTtJQUM3QixJQUFJLENBQUNGLElBQUksQ0FBQ0csT0FBTyxHQUFHLEVBQUU7SUFDdEIsSUFBSSxDQUFDSCxJQUFJLENBQUNJLFFBQVEsR0FBRyxJQUFJO0lBQ3pCLElBQUksQ0FBQ0osSUFBSSxDQUFDSyxTQUFTLEdBQUcsR0FBRztJQUN6QixJQUFJLENBQUNMLElBQUksQ0FBQ00sZUFBZSxHQUFHLElBQUk7SUFDaEMsSUFBSSxDQUFDTixJQUFJLENBQUNPLFVBQVUsR0FBRyxLQUFLO0lBQzVCLElBQUksQ0FBQ1AsSUFBSSxDQUFD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