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>
704 lines
76 KiB
JavaScript
Executable File
704 lines
76 KiB
JavaScript
Executable File
"use strict";
|
|
|
|
function _d1f5a3cb_defineProperty(e, r, t) { return (r = _d1f5a3cb_toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
|
|
function _d1f5a3cb_toPropertyKey(t) { var i = _d1f5a3cb_toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
|
|
function _d1f5a3cb_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); }
|
|
/**
|
|
* Modal Static API
|
|
*
|
|
* Primary interface for displaying modals throughout the application.
|
|
* Provides simple methods for common dialogs and flexible options for custom modals.
|
|
*
|
|
* Usage:
|
|
* await Modal.alert("File saved")
|
|
* if (await Modal.confirm("Delete?")) { ... }
|
|
* let name = await Modal.prompt("Enter name:")
|
|
* let result = await Modal.show({ title, body, buttons })
|
|
*/
|
|
class Modal {
|
|
/**
|
|
* Initialize global handlers (called automatically on first modal)
|
|
* @private
|
|
*/
|
|
static _init() {
|
|
if (this._initialized) return;
|
|
this._initialized = true;
|
|
|
|
// Create shared backdrop element
|
|
this._backdrop = $('<div class="modal-backdrop fade"></div>');
|
|
$('body').append(this._backdrop);
|
|
}
|
|
|
|
/**
|
|
* Calculate scrollbar width
|
|
* @private
|
|
* @returns {number}
|
|
*/
|
|
static _get_scrollbar_width() {
|
|
// Create temporary element to measure scrollbar width
|
|
const $outer = $('<div>').css({
|
|
visibility: 'hidden',
|
|
overflow: 'scroll',
|
|
width: '100px',
|
|
position: 'absolute',
|
|
top: '-9999px'
|
|
});
|
|
$('body').append($outer);
|
|
const width_with_scrollbar = $outer[0].offsetWidth;
|
|
const $inner = $('<div>').css('width', '100%');
|
|
$outer.append($inner);
|
|
const width_without_scrollbar = $inner[0].offsetWidth;
|
|
$outer.remove();
|
|
return width_with_scrollbar - width_without_scrollbar;
|
|
}
|
|
|
|
/**
|
|
* Lock body scroll and compensate for scrollbar width
|
|
* Only locks if we haven't already saved the original state (first modal in chain)
|
|
* @private
|
|
*/
|
|
static _lock_body_scroll() {
|
|
// Cancel any pending unlock timeout
|
|
if (this._unlock_timeout) {
|
|
clearTimeout(this._unlock_timeout);
|
|
this._unlock_timeout = null;
|
|
}
|
|
|
|
// Only lock scroll if we haven't already saved state (first modal)
|
|
// This is the true indicator - not backdrop visibility which can be transitional
|
|
if (this._original_body_overflow === null) {
|
|
const $body = $('body');
|
|
|
|
// Store original values
|
|
this._original_body_overflow = $body.css('overflow');
|
|
this._original_body_padding = $body.css('padding-right');
|
|
|
|
// Check if body currently has vertical scroll
|
|
const has_scrollbar = document.body.scrollHeight > window.innerHeight;
|
|
|
|
// If there's a scrollbar, add padding to compensate for its removal
|
|
if (has_scrollbar) {
|
|
const scrollbar_width = this._get_scrollbar_width();
|
|
const current_padding = int(this._original_body_padding) || 0;
|
|
$body.css('padding-right', current_padding + scrollbar_width + 'px');
|
|
}
|
|
|
|
// Lock scroll
|
|
$body.css('overflow', 'hidden');
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Unlock body scroll and restore original state
|
|
* Uses delayed check to ensure no other modals are opening
|
|
* @private
|
|
*/
|
|
static _unlock_body_scroll() {
|
|
// Clear any existing timeout
|
|
if (this._unlock_timeout) {
|
|
clearTimeout(this._unlock_timeout);
|
|
}
|
|
|
|
// Minimal delay before unlocking
|
|
this._unlock_timeout = setTimeout(() => {
|
|
// Double-check no modal is currently open and queue is empty
|
|
if (!this._current && this._queue.length === 0) {
|
|
const $body = $('body');
|
|
|
|
// Restore original values
|
|
if (this._original_body_overflow !== null) {
|
|
$body.css('overflow', this._original_body_overflow);
|
|
this._original_body_overflow = null;
|
|
}
|
|
if (this._original_body_padding !== null) {
|
|
$body.css('padding-right', this._original_body_padding);
|
|
this._original_body_padding = null;
|
|
}
|
|
}
|
|
this._unlock_timeout = null;
|
|
}, 50); // Minimal safety buffer
|
|
}
|
|
|
|
/**
|
|
* Show the shared backdrop (instant - no animation)
|
|
* @private
|
|
*/
|
|
static async _show_backdrop() {
|
|
if (!this._backdrop.hasClass('show')) {
|
|
// Lock body scroll before showing backdrop
|
|
this._lock_body_scroll();
|
|
this._backdrop.css('display', 'block').addClass('show');
|
|
// No delay - return immediately
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Hide the shared backdrop (instant - no animation)
|
|
* @private
|
|
*/
|
|
static async _hide_backdrop() {
|
|
this._backdrop.removeClass('show').css('display', 'none');
|
|
|
|
// Unlock body scroll after backdrop is hidden
|
|
this._unlock_body_scroll();
|
|
}
|
|
|
|
/**
|
|
* Create a new Rsx_Modal instance
|
|
* @private
|
|
*/
|
|
static async _create_modal() {
|
|
// Create modal component using jQuery plugin
|
|
const $modal_element = $('<div>');
|
|
|
|
// Create component instance directly (returns the component)
|
|
const modal_instance = $modal_element.component('Rsx_Modal', {});
|
|
|
|
// Wait for component to be fully ready (DOM elements queryable)
|
|
await new Promise(resolve => {
|
|
modal_instance.on('ready', () => {
|
|
console.log('[Modal] Component ready, elements:', {
|
|
title: modal_instance.$id('title').length,
|
|
body: modal_instance.$id('body').length,
|
|
footer: modal_instance.$id('footer').length
|
|
});
|
|
resolve();
|
|
});
|
|
});
|
|
return modal_instance;
|
|
}
|
|
|
|
/**
|
|
* Show a modal and manage queue
|
|
* @private
|
|
*/
|
|
static async _show_modal(options) {
|
|
return new Promise(resolve => {
|
|
this._queue.push({
|
|
options,
|
|
resolve
|
|
});
|
|
|
|
// Process queue if no modal currently showing
|
|
if (!this._current) {
|
|
this._process_queue();
|
|
}
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Process the modal queue
|
|
* @private
|
|
*/
|
|
static async _process_queue() {
|
|
if (this._queue.length === 0) {
|
|
this._current = null;
|
|
// Hide backdrop when queue is empty
|
|
await this._hide_backdrop();
|
|
return;
|
|
}
|
|
const {
|
|
options,
|
|
resolve
|
|
} = this._queue.shift();
|
|
|
|
// Ensure initialized
|
|
this._init();
|
|
|
|
// Show backdrop if not already visible (instant - no delay between modals)
|
|
const backdrop_visible = this._backdrop.hasClass('show');
|
|
if (!backdrop_visible) {
|
|
await this._show_backdrop();
|
|
}
|
|
// No delay between sequential modals - immediate transition
|
|
|
|
// Create modal instance
|
|
const modal_instance = await this._create_modal();
|
|
this._current = modal_instance;
|
|
|
|
// Determine if we should animate based on:
|
|
// 1. Desktop viewport (>= 1000px)
|
|
// 2. More than 1 second since last modal closed
|
|
const viewport_width = $(window).width();
|
|
const is_desktop = viewport_width >= 1000;
|
|
const time_since_last_close = Date.now() - this._last_close_timestamp;
|
|
const should_animate = is_desktop && time_since_last_close > 1000;
|
|
|
|
// Show modal and wait for result (modal won't create its own backdrop)
|
|
const result = await modal_instance.show(options, {
|
|
skip_backdrop: true,
|
|
animate: should_animate
|
|
});
|
|
|
|
// Record close timestamp BEFORE resolving (ensures it's set before next modal can start)
|
|
this._last_close_timestamp = Date.now();
|
|
|
|
// Resolve the promise with the result
|
|
resolve(result);
|
|
|
|
// Clear current and process next
|
|
this._current = null;
|
|
this._process_queue();
|
|
}
|
|
|
|
// ================================================================================
|
|
// State Management Methods
|
|
// ================================================================================
|
|
|
|
/**
|
|
* Check if a modal is currently open
|
|
* @returns {boolean}
|
|
*/
|
|
static is_open() {
|
|
return this._current !== null;
|
|
}
|
|
|
|
/**
|
|
* Get the currently open modal instance
|
|
* @returns {Rsx_Modal|null}
|
|
*/
|
|
static get_current() {
|
|
return this._current;
|
|
}
|
|
|
|
/**
|
|
* Force close the current modal
|
|
* @returns {Promise<void>}
|
|
*/
|
|
static async close() {
|
|
if (this._current) {
|
|
await this._current.close(false);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Apply validation errors to the current modal
|
|
* @param {Object} errors - Error object {field: message}
|
|
*/
|
|
static apply_errors(errors) {
|
|
if (this._current) {
|
|
this._current.apply_errors(errors);
|
|
}
|
|
}
|
|
|
|
// ================================================================================
|
|
// Simple Dialog Methods
|
|
// ================================================================================
|
|
|
|
/**
|
|
* Show an alert dialog
|
|
* @param {string|jQuery} title_or_body - Message (if only 1 arg) or Title (if 2 args). Can be string or jQuery element.
|
|
* @param {string|jQuery} body - Message body (if 2 args). Can be string or jQuery element.
|
|
* @param {string} button_label - Button text (default: "OK")
|
|
* @returns {Promise<void>}
|
|
*/
|
|
static async alert(title_or_body) {
|
|
let body = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
|
|
let button_label = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'OK';
|
|
let title = 'Notice';
|
|
let message = title_or_body;
|
|
if (body !== null) {
|
|
title = title_or_body;
|
|
message = body;
|
|
}
|
|
await this._show_modal({
|
|
title: title,
|
|
body: message,
|
|
buttons: [{
|
|
label: button_label,
|
|
value: true,
|
|
class: 'btn-primary',
|
|
default: true
|
|
}],
|
|
closable: true,
|
|
close_on_submit: true
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Show a confirmation dialog
|
|
* @param {string|jQuery} title_or_body - Message (if 1-2 args) or Title (if 3-4 args). Can be string or jQuery element.
|
|
* @param {string|jQuery} body - Message body (optional). Can be string or jQuery element.
|
|
* @param {string} confirm_label - Confirm button text (default: "Confirm")
|
|
* @param {string} cancel_label - Cancel button text (default: "Cancel")
|
|
* @returns {Promise<boolean>}
|
|
*/
|
|
static async confirm(title_or_body) {
|
|
let body = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
|
|
let confirm_label = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'Confirm';
|
|
let cancel_label = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 'Cancel';
|
|
let title = 'Confirm';
|
|
let message = title_or_body;
|
|
if (body !== null) {
|
|
title = title_or_body;
|
|
message = body;
|
|
}
|
|
const result = await this._show_modal({
|
|
title: title,
|
|
body: message,
|
|
buttons: [{
|
|
label: cancel_label,
|
|
value: false,
|
|
class: 'btn-secondary'
|
|
}, {
|
|
label: confirm_label,
|
|
value: true,
|
|
class: 'btn-primary',
|
|
default: true
|
|
}],
|
|
closable: true,
|
|
close_on_submit: true
|
|
});
|
|
return result === true;
|
|
}
|
|
|
|
/**
|
|
* Show a prompt dialog for text input
|
|
* @param {string|jQuery} title_or_body - Message (if 1-3 args) or Title (if 4 args). Can be string or jQuery element.
|
|
* @param {string|jQuery} body - Message body (optional). Can be string or jQuery element.
|
|
* @param {string} default_value - Default input value
|
|
* @param {boolean} multiline - Show textarea instead of input
|
|
* @param {string} error - Optional error message to display as validation feedback
|
|
* @returns {Promise<string|false>}
|
|
*/
|
|
static async prompt(title_or_body) {
|
|
let body = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
|
|
let default_value = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : '';
|
|
let multiline = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
|
|
let error = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : null;
|
|
let title = 'Input';
|
|
let message = title_or_body;
|
|
|
|
// Handle overloaded arguments
|
|
if (typeof body === 'string' && body !== '') {
|
|
title = title_or_body;
|
|
message = body;
|
|
}
|
|
|
|
// Create input element with minimum width constraints
|
|
const $input = multiline ? $('<textarea class="form-control" rows="4" style="min-width: 315px;"></textarea>') : $('<input type="text" class="form-control" style="min-width: 245px;">');
|
|
$input.val(default_value);
|
|
|
|
// Mark as invalid if there's an error
|
|
if (error) {
|
|
$input.addClass('is-invalid');
|
|
}
|
|
|
|
// Create body with message and input
|
|
let $body;
|
|
if (message instanceof jQuery) {
|
|
// If message is a jQuery element, use it as the container and append input
|
|
$body = message.append($input);
|
|
} else {
|
|
// If message is a string, create wrapper with text and input (36px spacing)
|
|
$body = $('<div class="form-group">').append($('<div style="margin-bottom: 36px;">').text(message)).append($input);
|
|
}
|
|
|
|
// Add error message if provided
|
|
if (error) {
|
|
const $error = $('<div class="invalid-feedback d-block"></div>').text(error);
|
|
$body.append($error);
|
|
}
|
|
const result = await this._show_modal({
|
|
title: title,
|
|
body: $body,
|
|
buttons: [{
|
|
label: 'Cancel',
|
|
value: false,
|
|
class: 'btn-secondary'
|
|
}, {
|
|
label: 'Submit',
|
|
value: null,
|
|
// Will be replaced by callback
|
|
class: 'btn-primary',
|
|
default: true,
|
|
callback: function () {
|
|
return $input.val();
|
|
}
|
|
}],
|
|
closable: true,
|
|
close_on_submit: true,
|
|
max_width: 500
|
|
});
|
|
|
|
// Focus and select input after modal shows
|
|
requestAnimationFrame(() => {
|
|
$input.focus();
|
|
if (!multiline) {
|
|
$input.select();
|
|
}
|
|
});
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Show an error dialog with red alert styling
|
|
*
|
|
* Can appear over other modals to show critical uncaught exceptions.
|
|
* Used primarily for Ajax errors that weren't caught by application code.
|
|
*
|
|
* @param {string|Error|Object} error - Error message string, Error object, or structured error
|
|
* @param {string} title - Modal title (default: "Error")
|
|
* @returns {Promise<void>}
|
|
*/
|
|
static async error(error) {
|
|
let title = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'Error';
|
|
let message = '';
|
|
|
|
// Handle different error types
|
|
if (typeof error === 'string') {
|
|
message = error;
|
|
} else if (error instanceof Error) {
|
|
message = error.message || error.toString();
|
|
} else if (error && error.message) {
|
|
message = error.message;
|
|
} else if (error && error.error) {
|
|
// Fatal error with details
|
|
const details = error.error;
|
|
if (details.file && details.line) {
|
|
message = `Uncaught Fatal Error in ${details.file}:${details.line}:\n\n${details.error}`;
|
|
} else {
|
|
message = details.error || 'An unknown error occurred';
|
|
}
|
|
} else {
|
|
message = 'An unknown error occurred';
|
|
}
|
|
|
|
// Create error body with red alert styling
|
|
const $body = $('<div class="alert alert-danger mb-0" role="alert">').append($('<pre class="mb-0" style="white-space: pre-wrap; word-wrap: break-word; font-family: monospace; font-size: 0.9em;">').text(message));
|
|
await this._show_modal({
|
|
title: title,
|
|
body: $body,
|
|
buttons: [{
|
|
label: 'Close',
|
|
value: true,
|
|
class: 'btn-danger',
|
|
default: true
|
|
}],
|
|
closable: true,
|
|
close_on_submit: true,
|
|
max_width: 600
|
|
});
|
|
}
|
|
|
|
// ================================================================================
|
|
// Custom Modal Methods
|
|
// ================================================================================
|
|
|
|
/**
|
|
* Show a custom modal with specified content and buttons
|
|
* @param {Object} options
|
|
* @returns {Promise<*>}
|
|
*/
|
|
static async show(options) {
|
|
const defaults = {
|
|
title: 'Modal',
|
|
body: '',
|
|
buttons: [],
|
|
max_width: 800,
|
|
closable: true,
|
|
close_on_submit: true
|
|
};
|
|
const final_options = Object.assign({}, defaults, options);
|
|
return await this._show_modal(final_options);
|
|
}
|
|
|
|
/**
|
|
* Show a modal with a jqhtml form component
|
|
* @param {Object} options
|
|
* @param {string} options.component - Component class name
|
|
* @param {Object} options.component_args - Arguments to pass to component
|
|
* @param {Function} options.on_submit - Callback function called on submit. Receives form component instance.
|
|
* Return false to keep modal open, or return data to close and resolve.
|
|
* @returns {Promise<Object|false>}
|
|
*/
|
|
static async form(options) {
|
|
const defaults = {
|
|
title: 'Form',
|
|
component: null,
|
|
component_args: {},
|
|
max_width: 800,
|
|
closable: true,
|
|
submit_label: 'Submit',
|
|
cancel_label: 'Cancel',
|
|
on_submit: null
|
|
};
|
|
const final_options = Object.assign({}, defaults, options);
|
|
if (!final_options.component) {
|
|
console.error('Modal.form() requires a component');
|
|
return false;
|
|
}
|
|
|
|
// Create component instance
|
|
let $component_container = $('<div>');
|
|
let component_instance = $component_container.component(final_options.component, final_options.component_args);
|
|
|
|
// Wait for component to be ready
|
|
await new Promise(resolve => {
|
|
component_instance.on('ready', () => resolve());
|
|
});
|
|
|
|
// Find a form instance if component instance doesnt have .vals()
|
|
if (!component_instance.vals) {
|
|
let $form = component_instance.$.find('.Rsx_Form');
|
|
if ($form.exists()) {
|
|
component_instance = $form.component();
|
|
}
|
|
}
|
|
|
|
// Create buttons
|
|
const buttons = [{
|
|
label: final_options.cancel_label,
|
|
value: false,
|
|
class: 'btn-secondary'
|
|
}, {
|
|
label: final_options.submit_label,
|
|
value: null,
|
|
class: 'btn-primary',
|
|
default: true,
|
|
callback: async function () {
|
|
// If on_submit callback provided, use it
|
|
if (final_options.on_submit && typeof final_options.on_submit === 'function') {
|
|
const result = await final_options.on_submit(component_instance);
|
|
// If callback returns null/undefined, keep modal open
|
|
if (result === null || result === undefined) {
|
|
return false;
|
|
}
|
|
// Otherwise (including false), return the result to close modal
|
|
return result;
|
|
}
|
|
|
|
// No on_submit callback - get form data and close modal
|
|
if (component_instance.submit && typeof component_instance.submit === 'function') {
|
|
return await component_instance.submit();
|
|
} else if (component_instance.vals && typeof component_instance.vals === 'function') {
|
|
return component_instance.vals();
|
|
} else {
|
|
console.warn('Form component has no submit() or vals() method');
|
|
return true;
|
|
}
|
|
}
|
|
}];
|
|
return await this._show_modal({
|
|
title: final_options.title,
|
|
body: component_instance.$,
|
|
buttons: buttons,
|
|
max_width: final_options.max_width,
|
|
closable: final_options.closable
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Show an unclosable modal
|
|
* @param {string} title_or_body
|
|
* @param {string} body
|
|
* @returns {Promise<void>}
|
|
*/
|
|
static async unclosable(title_or_body) {
|
|
let body = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
|
|
let title = 'Please Wait';
|
|
let message = title_or_body;
|
|
if (body !== null) {
|
|
title = title_or_body;
|
|
message = body;
|
|
}
|
|
|
|
// Don't wait for this promise - it never resolves until closed manually
|
|
this._show_modal({
|
|
title: title,
|
|
body: message,
|
|
buttons: [],
|
|
// No buttons
|
|
closable: false,
|
|
// Can't close
|
|
close_on_submit: false
|
|
});
|
|
|
|
// Wait for next animation frame for modal to render
|
|
await new Promise(resolve => requestAnimationFrame(resolve));
|
|
}
|
|
|
|
/**
|
|
* Show a modal with custom jQuery content
|
|
* @param {Object} options
|
|
* @returns {Promise<*>}
|
|
*/
|
|
static async custom(options) {
|
|
// Alias for show() - same functionality
|
|
return await this.show(options);
|
|
}
|
|
|
|
// ================================================================================
|
|
// Helper Methods
|
|
// ================================================================================
|
|
|
|
/**
|
|
* Show an error alert
|
|
* @param {*} errors
|
|
* @param {string} title
|
|
* @returns {Promise<void>}
|
|
*/
|
|
static async error(errors) {
|
|
let title = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'Error';
|
|
let message = 'An error occurred';
|
|
|
|
// Handle various error formats
|
|
if (typeof errors === 'string') {
|
|
message = errors;
|
|
} else if (errors && 'responseJSON' in errors && 'message' in errors.responseJSON) {
|
|
message = errors.responseJSON.message;
|
|
} else if (errors && 'message' in errors) {
|
|
message = errors.message;
|
|
} else if (errors && typeof errors === 'object') {
|
|
// Try to format error object
|
|
const error_messages = [];
|
|
for (const key in errors) {
|
|
if (is_array(errors[key])) {
|
|
error_messages.push(errors[key][0]);
|
|
} else {
|
|
error_messages.push(errors[key]);
|
|
}
|
|
}
|
|
if (error_messages.length > 0) {
|
|
message = error_messages.join('\n');
|
|
}
|
|
}
|
|
await this._show_modal({
|
|
title: title,
|
|
body: message,
|
|
icon: 'exclamation-circle',
|
|
buttons: [{
|
|
label: 'OK',
|
|
value: true,
|
|
class: 'btn-danger',
|
|
default: true
|
|
}],
|
|
closable: true,
|
|
close_on_submit: true
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Reopen current modal with validation errors
|
|
* @param {Object} errors
|
|
* @returns {Promise<void>}
|
|
*/
|
|
static async reopen_with_errors(errors) {
|
|
if (this._current) {
|
|
// Modal is still open, just apply errors
|
|
this.apply_errors(errors);
|
|
} else {
|
|
console.warn('No modal open to apply errors to');
|
|
}
|
|
}
|
|
}
|
|
// Internal state
|
|
_d1f5a3cb_defineProperty(Modal, "_queue", []);
|
|
_d1f5a3cb_defineProperty(Modal, "_current", null);
|
|
_d1f5a3cb_defineProperty(Modal, "_initialized", false);
|
|
_d1f5a3cb_defineProperty(Modal, "_backdrop", null);
|
|
_d1f5a3cb_defineProperty(Modal, "_original_body_overflow", null);
|
|
_d1f5a3cb_defineProperty(Modal, "_original_body_padding", null);
|
|
_d1f5a3cb_defineProperty(Modal, "_unlock_timeout", null);
|
|
_d1f5a3cb_defineProperty(Modal, "_last_close_timestamp", 0);
|
|
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJNb2RhbCIsIl9pbml0IiwiX2luaXRpYWxpemVkIiwiX2JhY2tkcm9wIiwiJCIsImFwcGVuZCIsIl9nZXRfc2Nyb2xsYmFyX3dpZHRoIiwiJG91dGVyIiwiY3NzIiwidmlzaWJpbGl0eSIsIm92ZXJmbG93Iiwid2lkdGgiLCJwb3NpdGlvbiIsInRvcCIsIndpZHRoX3dpdGhfc2Nyb2xsYmFyIiwib2Zmc2V0V2lkdGgiLCIkaW5uZXIiLCJ3aWR0aF93aXRob3V0X3Njcm9sbGJhciIsInJlbW92ZSIsIl9sb2NrX2JvZHlfc2Nyb2xsIiwiX3VubG9ja190aW1lb3V0IiwiY2xlYXJUaW1lb3V0IiwiX29yaWdpbmFsX2JvZHlfb3ZlcmZsb3ciLCIkYm9keSIsIl9vcmlnaW5hbF9ib2R5X3BhZGRpbmciLCJoYXNfc2Nyb2xsYmFyIiwiZG9jdW1lbnQiLCJib2R5Iiwic2Nyb2xsSGVpZ2h0Iiwid2luZG93IiwiaW5uZXJIZWlnaHQiLCJzY3JvbGxiYXJfd2lkdGgiLCJjdXJyZW50X3BhZGRpbmciLCJpbnQiLCJfdW5sb2NrX2JvZHlfc2Nyb2xsIiwic2V0VGltZW91dCIsIl9jdXJyZW50IiwiX3F1ZXVlIiwibGVuZ3RoIiwiX3Nob3dfYmFja2Ryb3AiLCJoYXNDbGFzcyIsImFkZENsYXNzIiwiX2hpZGVfYmFja2Ryb3AiLCJyZW1vdmVDbGFzcyIsIl9jcmVhdGVfbW9kYWwiLCIkbW9kYWxfZWxlbWVudCIsIm1vZGFsX2luc3RhbmNlIiwiY29tcG9uZW50IiwiUHJvbWlzZSIsInJlc29sdmUiLCJvbiIsImNvbnNvbGUiLCJsb2ciLCJ0aXRsZSIsIiRpZCIsImZvb3RlciIsIl9zaG93X21vZGFsIiwib3B0aW9ucyIsInB1c2giLCJfcHJvY2Vzc19xdWV1ZSIsInNoaWZ0IiwiYmFja2Ryb3BfdmlzaWJsZSIsInZpZXdwb3J0X3dpZHRoIiwiaXNfZGVza3RvcCIsInRpbWVfc2luY2VfbGFzdF9jbG9zZSIsIkRhdGUiLCJub3ciLCJfbGFzdF9jbG9zZV90aW1lc3RhbXAiLCJzaG91bGRfYW5pbWF0ZSIsInJlc3VsdCIsInNob3ciLCJza2lwX2JhY2tkcm9wIiwiYW5pbWF0ZSIsImlzX29wZW4iLCJnZXRfY3VycmVudCIsImNsb3NlIiwiYXBwbHlfZXJyb3JzIiwiZXJyb3JzIiwiYWxlcnQiLCJ0aXRsZV9vcl9ib2R5IiwiYXJndW1lbnRzIiwidW5kZWZpbmVkIiwiYnV0dG9uX2xhYmVsIiwibWVzc2FnZSIsImJ1dHRvbnMiLCJsYWJlbCIsInZhbHVlIiwiY2xhc3MiLCJkZWZhdWx0IiwiY2xvc2FibGUiLCJjbG9zZV9vbl9zdWJtaXQiLCJjb25maXJtIiwiY29uZmlybV9sYWJlbCIsImNhbmNlbF9sYWJlbCIsInByb21wdCIsImRlZmF1bHRfdmFsdWUiLCJtdWx0aWxpbmUiLCJlcnJvciIsIiRpbnB1dCIsInZhbCIsImpRdWVyeSIsInRleHQiLCIkZXJyb3IiLCJjYWxsYmFjayIsIm1heF93aWR0aCIsInJlcXVlc3RBbmltYXRpb25GcmFtZSIsImZvY3VzIiwic2VsZWN0IiwiRXJyb3IiLCJ0b1N0cmluZyIsImRldGFpbHMiLCJmaWxlIiwibGluZSIsImRlZmF1bHRzIiwiZmluYWxfb3B0aW9ucyIsIk9iamVjdCIsImFzc2lnbiIsImZvcm0iLCJjb21wb25lbnRfYXJncyIsInN1Ym1pdF9sYWJlbCIsIm9uX3N1Ym1pdCIsIiRjb21wb25lbnRfY29udGFpbmVyIiwiY29tcG9uZW50X2luc3RhbmNlIiwidmFscyIsIiRmb3JtIiwiZmluZCIsImV4aXN0cyIsInN1Ym1pdCIsIndhcm4iLCJ1bmNsb3NhYmxlIiwiY3VzdG9tIiwicmVzcG9uc2VKU09OIiwiZXJyb3JfbWVzc2FnZXMiLCJrZXkiLCJpc19hcnJheSIsImpvaW4iLCJpY29uIiwicmVvcGVuX3dpdGhfZXJyb3JzIiwiX2QxZjVhM2NiX2RlZmluZVByb3BlcnR5Il0sInNvdXJjZXMiOlsicnN4L3RoZW1lL2NvbXBvbmVudHMvbW9kYWwvTW9kYWwuanMiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBNb2RhbCBTdGF0aWMgQVBJXG4gKlxuICogUHJpbWFyeSBpbnRlcmZhY2UgZm9yIGRpc3BsYXlpbmcgbW9kYWxzIHRocm91Z2hvdXQgdGhlIGFwcGxpY2F0aW9uLlxuICogUHJvdmlkZXMgc2ltcGxlIG1ldGhvZHMgZm9yIGNvbW1vbiBkaWFsb2dzIGFuZCBmbGV4aWJsZSBvcHRpb25zIGZvciBjdXN0b20gbW9kYWxzLlxuICpcbiAqIFVzYWdlOlxuICogICBhd2FpdCBNb2RhbC5hbGVydChcIkZpbGUgc2F2ZWRcIilcbiAqICAgaWYgKGF3YWl0IE1vZGFsLmNvbmZpcm0oXCJEZWxldGU/XCIpKSB7IC4uLiB9XG4gKiAgIGxldCBuYW1lID0gYXdhaXQgTW9kYWwucHJvbXB0KFwiRW50ZXIgbmFtZTpcIilcbiAqICAgbGV0IHJlc3VsdCA9IGF3YWl0IE1vZGFsLnNob3coeyB0aXRsZSwgYm9keSwgYnV0dG9ucyB9KVxuICovXG5jbGFzcyBNb2RhbCB7XG4gICAgLy8gSW50ZXJuYWwgc3RhdGVcbiAgICBzdGF0aWMgX3F1ZXVlID0gW107XG4gICAgc3RhdGljIF9jdXJyZW50ID0gbnVsbDtcbiAgICBzdGF0aWMgX2luaXRpYWxpemVkID0gZmFsc2U7XG4gICAgc3RhdGljIF9iYWNrZHJvcCA9IG51bGw7XG4gICAgc3RhdGljIF9vcmlnaW5hbF9ib2R5X292ZXJmbG93ID0gbnVsbDtcbiAgICBzdGF0aWMgX29yaWdpbmFsX2JvZHlfcGFkZGluZyA9IG51bGw7XG4gICAgc3RhdGljIF91bmxvY2tfdGltZW91dCA9IG51bGw7XG4gICAgc3RhdGljIF9sYXN0X2Nsb3NlX3RpbWVzdGFtcCA9IDA7XG5cbiAgICAvKipcbiAgICAgKiBJbml0aWFsaXplIGdsb2JhbCBoYW5kbGVycyAoY2FsbGVkIGF1dG9tYXRpY2FsbHkgb24gZmlyc3QgbW9kYWwpXG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cbiAgICBzdGF0aWMgX2luaXQoKSB7XG4gICAgICAgIGlmICh0aGlzLl9pbml0aWFsaXplZCkgcmV0dXJuO1xuICAgICAgICB0aGlzLl9pbml0aWFsaXplZCA9IHRydWU7XG5cbiAgICAgICAgLy8gQ3JlYXRlIHNoYXJlZCBiYWNrZHJvcCBlbGVtZW50XG4gICAgICAgIHRoaXMuX2JhY2tkcm9wID0gJCgnPGRpdiBjbGFzcz1cIm1vZGFsLWJhY2tkcm9wIGZhZGVcIj48L2Rpdj4nKTtcbiAgICAgICAgJCgnYm9keScpLmFwcGVuZCh0aGlzLl9iYWNrZHJvcCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2FsY3VsYXRlIHNjcm9sbGJhciB3aWR0aFxuICAgICAqIEBwcml2YXRlXG4gICAgICogQHJldHVybnMge251bWJlcn1cbiAgICAgKi9cbiAgICBzdGF0aWMgX2dldF9zY3JvbGxiYXJfd2lkdGgoKSB7XG4gICAgICAgIC8vIENyZWF0ZSB0ZW1wb3JhcnkgZWxlbWVudCB0byBtZWFzdXJlIHNjcm9sbGJhciB3aWR0aFxuICAgICAgICBjb25zdCAkb3V0ZXIgPSAkKCc8ZGl2PicpLmNzcyh7XG4gICAgICAgICAgICB2aXNpYmlsaXR5OiAnaGlkZGVuJyxcbiAgICAgICAgICAgIG92ZXJmbG93OiAnc2Nyb2xsJyxcbiAgICAgICAgICAgIHdpZHRoOiAnMTAwcHgnLFxuICAgICAgICAgICAgcG9zaXRpb246ICdhYnNvbHV0ZScsXG4gICAgICAgICAgICB0b3A6ICctOTk5OXB4JyxcbiAgICAgICAgfSk7XG4gICAgICAgICQoJ2JvZHknKS5hcHBlbmQoJG91dGVyKTtcblxuICAgICAgICBjb25zdCB3aWR0aF93aXRoX3Njcm9sbGJhciA9ICRvdXRlclswXS5vZmZzZXRXaWR0aDtcblxuICAgICAgICBjb25zdCAkaW5uZXIgPSAkKCc8ZGl2PicpLmNzcygnd2lkdGgnLCAnMTAwJScpO1xuICAgICAgICAkb3V0ZXIuYXBwZW5kKCRpbm5lcik7XG5cbiAgICAgICAgY29uc3Qgd2lkdGhfd2l0aG91dF9zY3JvbGxiYXIgPSAkaW5uZXJbMF0ub2Zmc2V0V2lkdGg7XG5cbiAgICAgICAgJG91dGVyLnJlbW92ZSgpO1xuXG4gICAgICAgIHJldHVybiB3aWR0aF93aXRoX3Njcm9sbGJhciAtIHdpZHRoX3dpdGhvdXRfc2Nyb2xsYmFyO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIExvY2sgYm9keSBzY3JvbGwgYW5kIGNvbXBlbnNhdGUgZm9yIHNjcm9sbGJhciB3aWR0aFxuICAgICAqIE9ubHkgbG9ja3MgaWYgd2UgaGF2ZW4ndCBhbHJlYWR5IHNhdmVkIHRoZSBvcmlnaW5hbCBzdGF0ZSAoZmlyc3QgbW9kYWwgaW4gY2hhaW4pXG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cbiAgICBzdGF0aWMgX2xvY2tfYm9keV9zY3JvbGwoKSB7XG4gICAgICAgIC8vIENhbmNlbCBhbnkgcGVuZGluZyB1bmxvY2sgdGltZW91dFxuICAgICAgICBpZiAodGhpcy5fdW5sb2NrX3RpbWVvdXQpIHtcbiAgICAgICAgICAgIGNsZWFyVGltZW91dCh0aGlzLl91bmxvY2tfdGltZW91dCk7XG4gICAgICAgICAgICB0aGlzLl91bmxvY2tfdGltZW91dCA9IG51bGw7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBPbmx5IGxvY2sgc2Nyb2xsIGlmIHdlIGhhdmVuJ3QgYWxyZWFkeSBzYXZlZCBzdGF0ZSAoZmlyc3QgbW9kYWwpXG4gICAgICAgIC8vIFRoaXMgaXMgdGhlIHRydWUgaW5kaWNhdG9yIC0gbm90IGJhY2tkcm9wIHZpc2liaWxpdHkgd2hpY2ggY2FuIGJlIHRyYW5zaXRpb25hbFxuICAgICAgICBpZiAodGhpcy5fb3JpZ2luYWxfYm9keV9vdmVyZmxvdyA9PT0gbnVsbCkge1xuICAgICAgICAgICAgY29uc3QgJGJvZHkgPSAkKCdib2R5Jyk7XG5cbiAgICAgICAgICAgIC8vIFN0b3JlIG9yaWdpbmFsIHZhbHVlc1xuICAgICAgICAgICAgdGhpcy5fb3JpZ2luYWxfYm9keV9vdmVyZmxvdyA9ICRib2R5LmNzcygnb3ZlcmZsb3cnKTtcbiAgICAgICAgICAgIHRoaXMuX29yaWdpbmFsX2JvZHlfcGFkZGluZyA9ICRib2R5LmNzcygncGFkZGluZy1yaWdodCcpO1xuXG4gICAgICAgICAgICAvLyBDaGVjayBpZiBib2R5IGN1cnJlbnRseSBoYXMgdmVydGljYWwgc2Nyb2xsXG4gICAgICAgICAgICBjb25zdCBoYXNfc2Nyb2xsYmFyID0gZG9jdW1lbnQuYm9keS5zY3JvbGxIZWlnaHQgPiB3aW5kb3cuaW5uZXJIZWlnaHQ7XG5cbiAgICAgICAgICAgIC8vIElmIHRoZXJlJ3MgYSBzY3JvbGxiYXIsIGFkZCBwYWRkaW5nIHRvIGNvbXBlbnNhdGUgZm9yIGl0cyByZW1vdmFsXG4gICAgICAgICAgICBpZiAoaGFzX3Njcm9sbGJhcikge1xuICAgICAgICAgICAgICAgIGNvbnN0IHNjcm9sbGJhcl93aWR0aCA9IHRoaXMuX2dldF9zY3JvbGxiYXJfd2lkdGgoKTtcbiAgICAgICAgICAgICAgICBjb25zdCBjdXJyZW50X3BhZGRpbmcgPSBpbnQodGhpcy5fb3JpZ2luYWxfYm9keV9wYWRkaW5nKSB8fCAwO1xuICAgICAgICAgICAgICAgICRib2R5LmNzcygncGFkZGluZy1yaWdodCcsIGN1cnJlbnRfcGFkZGluZyArIHNjcm9sbGJhcl93aWR0aCArICdweCcpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBMb2NrIHNjcm9sbFxuICAgICAgICAgICAgJGJvZHkuY3NzKCdvdmVyZmxvdycsICdoaWRkZW4nKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFVubG9jayBib2R5IHNjcm9sbCBhbmQgcmVzdG9yZSBvcmlnaW5hbCBzdGF0ZVxuICAgICAqIFVzZXMgZGVsYXllZCBjaGVjayB0byBlbnN1cmUgbm8gb3RoZXIgbW9kYWxzIGFyZSBvcGVuaW5nXG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cbiAgICBzdGF0aWMgX3VubG9ja19ib2R5X3Njcm9sbCgpIHtcbiAgICAgICAgLy8gQ2xlYXIgYW55IGV4aXN0aW5nIHRpbWVvdXRcbiAgICAgICAgaWYgKHRoaXMuX3VubG9ja190aW1lb3V0KSB7XG4gICAgICAgICAgICBjbGVhclRpbWVvdXQodGhpcy5fdW5sb2NrX3RpbWVvdXQpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gTWluaW1hbCBkZWxheSBiZWZvcmUgdW5sb2NraW5nXG4gICAgICAgIHRoaXMuX3VubG9ja190aW1lb3V0ID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICAvLyBEb3VibGUtY2hlY2sgbm8gbW9kYWwgaXMgY3VycmVudGx5IG9wZW4gYW5kIHF1ZXVlIGlzIGVtcHR5XG4gICAgICAgICAgICBpZiAoIXRoaXMuX2N1cnJlbnQgJiYgdGhpcy5fcXVldWUubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgJGJvZHkgPSAkKCdib2R5Jyk7XG5cbiAgICAgICAgICAgICAgICAvLyBSZXN0b3JlIG9yaWdpbmFsIHZhbHVlc1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLl9vcmlnaW5hbF9ib2R5X292ZXJmbG93ICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgICRib2R5LmNzcygnb3ZlcmZsb3cnLCB0aGlzLl9vcmlnaW5hbF9ib2R5X292ZXJmbG93KTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fb3JpZ2luYWxfYm9keV9vdmVyZmxvdyA9IG51bGw7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuX29yaWdpbmFsX2JvZHlfcGFkZGluZyAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICAkYm9keS5jc3MoJ3BhZGRpbmctcmlnaHQnLCB0aGlzLl9vcmlnaW5hbF9ib2R5X3BhZGRpbmcpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9vcmlnaW5hbF9ib2R5X3BhZGRpbmcgPSBudWxsO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGhpcy5fdW5sb2NrX3RpbWVvdXQgPSBudWxsO1xuICAgICAgICB9LCA1MCk7IC8vIE1pbmltYWwgc2FmZXR5IGJ1ZmZlclxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNob3cgdGhlIHNoYXJlZCBiYWNrZHJvcCAoaW5zdGFudCAtIG5vIGFuaW1hdGlvbilcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuICAgIHN0YXRpYyBhc3luYyBfc2hvd19iYWNrZHJvcCgpIHtcbiAgICAgICAgaWYgKCF0aGlzLl9iYWNrZHJvcC5oYXNDbGFzcygnc2hvdycpKSB7XG4gICAgICAgICAgICAvLyBMb2NrIGJvZHkgc2Nyb2xsIGJlZm9yZSBzaG93aW5nIGJhY2tkcm9wXG4gICAgICAgICAgICB0aGlzLl9sb2NrX2JvZHlfc2Nyb2xsKCk7XG5cbiAgICAgICAgICAgIHRoaXMuX2JhY2tkcm9wLmNzcygnZGlzcGxheScsICdibG9jaycpLmFkZENsYXNzKCdzaG93Jyk7XG4gICAgICAgICAgICAvLyBObyBkZWxheSAtIHJldHVybiBpbW1lZGlhdGVseVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogSGlkZSB0aGUgc2hhcmVkIGJhY2tkcm9wIChpbnN0YW50IC0gbm8gYW5pbWF0aW9uKVxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG4gICAgc3RhdGljIGFzeW5jIF9oaWRlX2JhY2tkcm9wKCkge1xuICAgICAgICB0aGlzLl9iYWNrZHJvcC5yZW1vdmVDbGFzcygnc2hvdycpLmNzcygnZGlzcGxheScsICdub25lJyk7XG5cbiAgICAgICAgLy8gVW5sb2NrIGJvZHkgc2Nyb2xsIGFmdGVyIGJhY2tkcm9wIGlzIGhpZGRlblxuICAgICAgICB0aGlzLl91bmxvY2tfYm9keV9zY3JvbGwoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGUgYSBuZXcgUnN4X01vZGFsIGluc3RhbmNlXG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cbiAgICBzdGF0aWMgYXN5bmMgX2NyZWF0ZV9tb2RhbCgpIHtcbiAgICAgICAgLy8gQ3JlYXRlIG1vZGFsIGNvbXBvbmVudCB1c2luZyBqUXVlcnkgcGx1Z2luXG4gICAgICAgIGNvbnN0ICRtb2RhbF9lbGVtZW50ID0gJCgnPGRpdj4nKTtcblxuICAgICAgICAvLyBDcmVhdGUgY29tcG9uZW50IGluc3RhbmNlIGRpcmVjdGx5IChyZXR1cm5zIHRoZSBjb21wb25lbnQpXG4gICAgICAgIGNvbnN0IG1vZGFsX2luc3RhbmNlID0gJG1vZGFsX2VsZW1lbnQuY29tcG9uZW50KCdSc3hfTW9kYWwnLCB7fSk7XG5cbiAgICAgICAgLy8gV2FpdCBmb3IgY29tcG9uZW50IHRvIGJlIGZ1bGx5IHJlYWR5IChET00gZWxlbWVudHMgcXVlcnlhYmxlKVxuICAgICAgICBhd2FpdCBuZXcgUHJvbWlzZSgocmVzb2x2ZSkgPT4ge1xuICAgICAgICAgICAgbW9kYWxfaW5zdGFuY2Uub24oJ3JlYWR5JywgKCkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKCdbTW9kYWxdIENvbXBvbmVudCByZWFkeSwgZWxlbWVudHM6Jywge1xuICAgICAgICAgICAgICAgICAgICB0aXRsZTogbW9kYWxfaW5zdGFuY2UuJGlkKCd0aXRsZScpLmxlbmd0aCxcbiAgICAgICAgICAgICAgICAgICAgYm9keTogbW9kYWxfaW5zdGFuY2UuJGlkKCdib2R5JykubGVuZ3RoLFxuICAgICAgICAgICAgICAgICAgICBmb290ZXI6IG1vZGFsX2luc3RhbmNlLiRpZCgnZm9vdGVyJykubGVuZ3RoLFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcblxuICAgICAgICByZXR1cm4gbW9kYWxfaW5zdGFuY2U7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2hvdyBhIG1vZGFsIGFuZCBtYW5hZ2UgcXVldWVcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuICAgIHN0YXRpYyBhc3luYyBfc2hvd19tb2RhbChvcHRpb25zKSB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSkgPT4ge1xuICAgICAgICAgICAgdGhpcy5fcXVldWUucHVzaCh7IG9wdGlvbnMsIHJlc29sdmUgfSk7XG5cbiAgICAgICAgICAgIC8vIFByb2Nlc3MgcXVldWUgaWYgbm8gbW9kYWwgY3VycmVudGx5IHNob3dpbmdcbiAgICAgICAgICAgIGlmICghdGhpcy5fY3VycmVudCkge1xuICAgICAgICAgICAgICAgIHRoaXMuX3Byb2Nlc3NfcXVldWUoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUHJvY2VzcyB0aGUgbW9kYWwgcXVldWVcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuICAgIHN0YXRpYyBhc3luYyBfcHJvY2Vzc19xdWV1ZSgpIHtcbiAgICAgICAgaWYgKHRoaXMuX3F1ZXVlLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgdGhpcy5fY3VycmVudCA9IG51bGw7XG4gICAgICAgICAgICAvLyBIaWRlIGJhY2tkcm9wIHdoZW4gcXVldWUgaXMgZW1wdHlcbiAgICAgICAgICAgIGF3YWl0IHRoaXMuX2hpZGVfYmFja2Ryb3AoKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHsgb3B0aW9ucywgcmVzb2x2ZSB9ID0gdGhpcy5fcXVldWUuc2hpZnQoKTtcblxuICAgICAgICAvLyBFbnN1cmUgaW5pdGlhbGl6ZWRcbiAgICAgICAgdGhpcy5faW5pdCgpO1xuXG4gICAgICAgIC8vIFNob3cgYmFja2Ryb3AgaWYgbm90IGFscmVhZHkgdmlzaWJsZSAoaW5zdGFudCAtIG5vIGRlbGF5IGJldHdlZW4gbW9kYWxzKVxuICAgICAgICBjb25zdCBiYWNrZHJvcF92aXNpYmxlID0gdGhpcy5fYmFja2Ryb3AuaGFzQ2xhc3MoJ3Nob3cnKTtcbiAgICAgICAgaWYgKCFiYWNrZHJvcF92aXNpYmxlKSB7XG4gICAgICAgICAgICBhd2FpdCB0aGlzLl9zaG93X2JhY2tkcm9wKCk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gTm8gZGVsYXkgYmV0d2VlbiBzZXF1ZW50aWFsIG1vZGFscyAtIGltbWVkaWF0ZSB0cmFuc2l0aW9uXG5cbiAgICAgICAgLy8gQ3JlYXRlIG1vZGFsIGluc3RhbmNlXG4gICAgICAgIGNvbnN0IG1vZGFsX2luc3RhbmNlID0gYXdhaXQgdGhpcy5fY3JlYXRlX21vZGFsKCk7XG4gICAgICAgIHRoaXMuX2N1cnJlbnQgPSBtb2RhbF9pbnN0YW5jZTtcblxuICAgICAgICAvLyBEZXRlcm1pbmUgaWYgd2Ugc2hvdWxkIGFuaW1hdGUgYmFzZWQgb246XG4gICAgICAgIC8vIDEuIERlc2t0b3Agdmlld3BvcnQgKD49IDEwMDBweClcbiAgICAgICAgLy8gMi4gTW9yZSB0aGFuIDEgc2Vjb25kIHNpbmNlIGxhc3QgbW9kYWwgY2xvc2VkXG4gICAgICAgIGNvbnN0IHZpZXdwb3J0X3dpZHRoID0gJCh3aW5kb3cpLndpZHRoKCk7XG4gICAgICAgIGNvbnN0IGlzX2Rlc2t0b3AgPSB2aWV3cG9ydF93aWR0aCA+PSAxMDAwO1xuICAgICAgICBjb25zdCB0aW1lX3NpbmNlX2xhc3RfY2xvc2UgPSBEYXRlLm5vdygpIC0gdGhpcy5fbGFzdF9jbG9zZV90aW1lc3RhbXA7XG4gICAgICAgIGNvbnN0IHNob3VsZF9hbmltYXRlID0gaXNfZGVza3RvcCAmJiB0aW1lX3NpbmNlX2xhc3RfY2xvc2UgPiAxMDAwO1xuXG4gICAgICAgIC8vIFNob3cgbW9kYWwgYW5kIHdhaXQgZm9yIHJlc3VsdCAobW9kYWwgd29uJ3QgY3JlYXRlIGl0cyBvd24gYmFja2Ryb3ApXG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IG1vZGFsX2luc3RhbmNlLnNob3cob3B0aW9ucywgeyBza2lwX2JhY2tkcm9wOiB0cnVlLCBhbmltYXRlOiBzaG91bGRfYW5pbWF0ZSB9KTtcblxuICAgICAgICAvLyBSZWNvcmQgY2xvc2UgdGltZXN0YW1wIEJFRk9SRSByZXNvbHZpbmcgKGVuc3VyZXMgaXQncyBzZXQgYmVmb3JlIG5leHQgbW9kYWwgY2FuIHN0YXJ0KVxuICAgICAgICB0aGlzLl9sYXN0X2Nsb3NlX3RpbWVzdGFtcCA9IERhdGUubm93KCk7XG5cbiAgICAgICAgLy8gUmVzb2x2ZSB0aGUgcHJvbWlzZSB3aXRoIHRoZSByZXN1bHRcbiAgICAgICAgcmVzb2x2ZShyZXN1bHQpO1xuXG4gICAgICAgIC8vIENsZWFyIGN1cnJlbnQgYW5kIHByb2Nlc3MgbmV4dFxuICAgICAgICB0aGlzLl9jdXJyZW50ID0gbnVsbDtcbiAgICAgICAgdGhpcy5fcHJvY2Vzc19xdWV1ZSgpO1xuICAgIH1cblxuICAgIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gICAgLy8gU3RhdGUgTWFuYWdlbWVudCBNZXRob2RzXG4gICAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuICAgIC8qKlxuICAgICAqIENoZWNrIGlmIGEgbW9kYWwgaXMgY3VycmVudGx5IG9wZW5cbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn1cbiAgICAgKi9cbiAgICBzdGF0aWMgaXNfb3BlbigpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2N1cnJlbnQgIT09IG51bGw7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBjdXJyZW50bHkgb3BlbiBtb2RhbCBpbnN0YW5jZVxuICAgICAqIEByZXR1cm5zIHtSc3hfTW9kYWx8bnVsbH1cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0X2N1cnJlbnQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9jdXJyZW50O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEZvcmNlIGNsb3NlIHRoZSBjdXJyZW50IG1vZGFsXG4gICAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59XG4gICAgICovXG4gICAgc3RhdGljIGFzeW5jIGNsb3NlKCkge1xuICAgICAgICBpZiAodGhpcy5fY3VycmVudCkge1xuICAgICAgICAgICAgYXdhaXQgdGhpcy5fY3VycmVudC5jbG9zZShmYWxzZSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBcHBseSB2YWxpZGF0aW9uIGVycm9ycyB0byB0aGUgY3VycmVudCBtb2RhbFxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBlcnJvcnMgLSBFcnJvciBvYmplY3Qge2ZpZWxkOiBtZXNzYWdlfVxuICAgICAqL1xuICAgIHN0YXRpYyBhcHBseV9lcnJvcnMoZXJyb3JzKSB7XG4gICAgICAgIGlmICh0aGlzLl9jdXJyZW50KSB7XG4gICAgICAgICAgICB0aGlzLl9jdXJyZW50LmFwcGx5X2Vycm9ycyhlcnJvcnMpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAgICAvLyBTaW1wbGUgRGlhbG9nIE1ldGhvZHNcbiAgICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuXG4gICAgLyoqXG4gICAgICogU2hvdyBhbiBhbGVydCBkaWFsb2dcbiAgICAgKiBAcGFyYW0ge3N0cmluZ3xqUXVlcnl9IHRpdGxlX29yX2JvZHkgLSBNZXNzYWdlIChpZiBvbmx5IDEgYXJnKSBvciBUaXRsZSAoaWYgMiBhcmdzKS4gQ2FuIGJlIHN0cmluZyBvciBqUXVlcnkgZWxlbWVudC5cbiAgICAgKiBAcGFyYW0ge3N0cmluZ3xqUXVlcnl9IGJvZHkgLSBNZXNzYWdlIGJvZHkgKGlmIDIgYXJncykuIENhbiBiZSBzdHJpbmcgb3IgalF1ZXJ5IGVsZW1lbnQuXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGJ1dHRvbl9sYWJlbCAtIEJ1dHRvbiB0ZXh0IChkZWZhdWx0OiBcIk9LXCIpXG4gICAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59XG4gICAgICovXG4gICAgc3RhdGljIGFzeW5jIGFsZXJ0KHRpdGxlX29yX2JvZHksIGJvZHkgPSBudWxsLCBidXR0b25fbGFiZWwgPSAnT0snKSB7XG4gICAgICAgIGxldCB0aXRsZSA9ICdOb3RpY2UnO1xuICAgICAgICBsZXQgbWVzc2FnZSA9IHRpdGxlX29yX2JvZHk7XG5cbiAgICAgICAgaWYgKGJvZHkgIT09IG51bGwpIHtcbiAgICAgICAgICAgIHRpdGxlID0gdGl0bGVfb3JfYm9keTtcbiAgICAgICAgICAgIG1lc3NhZ2UgPSBib2R5O1xuICAgICAgICB9XG5cbiAgICAgICAgYXdhaXQgdGhpcy5fc2hvd19tb2RhbCh7XG4gICAgICAgICAgICB0aXRsZTogdGl0bGUsXG4gICAgICAgICAgICBib2R5OiBtZXNzYWdlLFxuICAgICAgICAgICAgYnV0dG9uczogW1xuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgbGFiZWw6IGJ1dHRvbl9sYWJlbCxcbiAgICAgICAgICAgICAgICAgICAgdmFsdWU6IHRydWUsXG4gICAgICAgICAgICAgICAgICAgIGNsYXNzOiAnYnRuLXByaW1hcnknLFxuICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OiB0cnVlLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBdLFxuICAgICAgICAgICAgY2xvc2FibGU6IHRydWUsXG4gICAgICAgICAgICBjbG9zZV9vbl9zdWJtaXQ6IHRydWUsXG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNob3cgYSBjb25maXJtYXRpb24gZGlhbG9nXG4gICAgICogQHBhcmFtIHtzdHJpbmd8alF1ZXJ5fSB0aXRsZV9vcl9ib2R5IC0gTWVzc2FnZSAoaWYgMS0yIGFyZ3MpIG9yIFRpdGxlIChpZiAzLTQgYXJncykuIENhbiBiZSBzdHJpbmcgb3IgalF1ZXJ5IGVsZW1lbnQuXG4gICAgICogQHBhcmFtIHtzdHJpbmd8alF1ZXJ5fSBib2R5IC0gTWVzc2FnZSBib2R5IChvcHRpb25hbCkuIENhbiBiZSBzdHJpbmcgb3IgalF1ZXJ5IGVsZW1lbnQuXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGNvbmZpcm1fbGFiZWwgLSBDb25maXJtIGJ1dHRvbiB0ZXh0IChkZWZhdWx0OiBcIkNvbmZpcm1cIilcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gY2FuY2VsX2xhYmVsIC0gQ2FuY2VsIGJ1dHRvbiB0ZXh0IChkZWZhdWx0OiBcIkNhbmNlbFwiKVxuICAgICAqIEByZXR1cm5zIHtQcm9taXNlPGJvb2xlYW4+fVxuICAgICAqL1xuICAgIHN0YXRpYyBhc3luYyBjb25maXJtKHRpdGxlX29yX2JvZHksIGJvZHkgPSBudWxsLCBjb25maXJtX2xhYmVsID0gJ0NvbmZpcm0nLCBjYW5jZWxfbGFiZWwgPSAnQ2FuY2VsJykge1xuICAgICAgICBsZXQgdGl0bGUgPSAnQ29uZmlybSc7XG4gICAgICAgIGxldCBtZXNzYWdlID0gdGl0bGVfb3JfYm9keTtcblxuICAgICAgICBpZiAoYm9keSAhPT0gbnVsbCkge1xuICAgICAgICAgICAgdGl0bGUgPSB0aXRsZV9vcl9ib2R5O1xuICAgICAgICAgICAgbWVzc2FnZSA9IGJvZHk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB0aGlzLl9zaG93X21vZGFsKHtcbiAgICAgICAgICAgIHRpdGxlOiB0aXRsZSxcbiAgICAgICAgICAgIGJvZHk6IG1lc3NhZ2UsXG4gICAgICAgICAgICBidXR0b25zOiBbXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBsYWJlbDogY2FuY2VsX2xhYmVsLFxuICAgICAgICAgICAgICAgICAgICB2YWx1ZTogZmFsc2UsXG4gICAgICAgICAgICAgICAgICAgIGNsYXNzOiAnYnRuLXNlY29uZGFyeScsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGxhYmVsOiBjb25maXJtX2xhYmVsLFxuICAgICAgICAgICAgICAgICAgICB2YWx1ZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgY2xhc3M6ICdidG4tcHJpbWFyeScsXG4gICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6IHRydWUsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgICBjbG9zYWJsZTogdHJ1ZSxcbiAgICAgICAgICAgIGNsb3NlX29uX3N1Ym1pdDogdHJ1ZSxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgcmV0dXJuIHJlc3VsdCA9PT0gdHJ1ZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTaG93IGEgcHJvbXB0IGRpYWxvZyBmb3IgdGV4dCBpbnB1dFxuICAgICAqIEBwYXJhbSB7c3RyaW5nfGpRdWVyeX0gdGl0bGVfb3JfYm9keSAtIE1lc3NhZ2UgKGlmIDEtMyBhcmdzKSBvciBUaXRsZSAoaWYgNCBhcmdzKS4gQ2FuIGJlIHN0cmluZyBvciBqUXVlcnkgZWxlbWVudC5cbiAgICAgKiBAcGFyYW0ge3N0cmluZ3xqUXVlcnl9IGJvZHkgLSBNZXNzYWdlIGJvZHkgKG9wdGlvbmFsKS4gQ2FuIGJlIHN0cmluZyBvciBqUXVlcnkgZWxlbWVudC5cbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gZGVmYXVsdF92YWx1ZSAtIERlZmF1bHQgaW5wdXQgdmFsdWVcbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IG11bHRpbGluZSAtIFNob3cgdGV4dGFyZWEgaW5zdGVhZCBvZiBpbnB1dFxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBlcnJvciAtIE9wdGlvbmFsIGVycm9yIG1lc3NhZ2UgdG8gZGlzcGxheSBhcyB2YWxpZGF0aW9uIGZlZWRiYWNrXG4gICAgICogQHJldHVybnMge1Byb21pc2U8c3RyaW5nfGZhbHNlPn1cbiAgICAgKi9cbiAgICBzdGF0aWMgYXN5bmMgcHJvbXB0KHRpdGxlX29yX2JvZHksIGJvZHkgPSBudWxsLCBkZWZhdWx0X3ZhbHVlID0gJycsIG11bHRpbGluZSA9IGZhbHNlLCBlcnJvciA9IG51bGwpIHtcbiAgICAgICAgbGV0IHRpdGxlID0gJ0lucHV0JztcbiAgICAgICAgbGV0IG1lc3NhZ2UgPSB0aXRsZV9vcl9ib2R5O1xuXG4gICAgICAgIC8vIEhhbmRsZSBvdmVybG9hZGVkIGFyZ3VtZW50c1xuICAgICAgICBpZiAodHlwZW9mIGJvZHkgPT09ICdzdHJpbmcnICYmIGJvZHkgIT09ICcnKSB7XG4gICAgICAgICAgICB0aXRsZSA9IHRpdGxlX29yX2JvZHk7XG4gICAgICAgICAgICBtZXNzYWdlID0gYm9keTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIENyZWF0ZSBpbnB1dCBlbGVtZW50IHdpdGggbWluaW11bSB3aWR0aCBjb25zdHJhaW50c1xuICAgICAgICBjb25zdCAkaW5wdXQgPSBtdWx0aWxpbmVcbiAgICAgICAgICAgID8gJCgnPHRleHRhcmVhIGNsYXNzPVwiZm9ybS1jb250cm9sXCIgcm93cz1cIjRcIiBzdHlsZT1cIm1pbi13aWR0aDogMzE1cHg7XCI+PC90ZXh0YXJlYT4nKVxuICAgICAgICAgICAgOiAkKCc8aW5wdXQgdHlwZT1cInRleHRcIiBjbGFzcz1cImZvcm0tY29udHJvbFwiIHN0eWxlPVwibWluLXdpZHRoOiAyNDVweDtcIj4nKTtcblxuICAgICAgICAkaW5wdXQudmFsKGRlZmF1bHRfdmFsdWUpO1xuXG4gICAgICAgIC8vIE1hcmsgYXMgaW52YWxpZCBpZiB0aGVyZSdzIGFuIGVycm9yXG4gICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgJGlucHV0LmFkZENsYXNzKCdpcy1pbnZhbGlkJyk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBDcmVhdGUgYm9keSB3aXRoIG1lc3NhZ2UgYW5kIGlucHV0XG4gICAgICAgIGxldCAkYm9keTtcbiAgICAgICAgaWYgKG1lc3NhZ2UgaW5zdGFuY2VvZiBqUXVlcnkpIHtcbiAgICAgICAgICAgIC8vIElmIG1lc3NhZ2UgaXMgYSBqUXVlcnkgZWxlbWVudCwgdXNlIGl0IGFzIHRoZSBjb250YWluZXIgYW5kIGFwcGVuZCBpbnB1dFxuICAgICAgICAgICAgJGJvZHkgPSBtZXNzYWdlLmFwcGVuZCgkaW5wdXQpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gSWYgbWVzc2FnZSBpcyBhIHN0cmluZywgY3JlYXRlIHdyYXBwZXIgd2l0aCB0ZXh0IGFuZCBpbnB1dCAoMzZweCBzcGFjaW5nKVxuICAgICAgICAgICAgJGJvZHkgPSAkKCc8ZGl2IGNsYXNzPVwiZm9ybS1ncm91cFwiPicpLmFwcGVuZCgkKCc8ZGl2IHN0eWxlPVwibWFyZ2luLWJvdHRvbTogMzZweDtcIj4nKS50ZXh0KG1lc3NhZ2UpKS5hcHBlbmQoJGlucHV0KTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIEFkZCBlcnJvciBtZXNzYWdlIGlmIHByb3ZpZGVkXG4gICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgY29uc3QgJGVycm9yID0gJCgnPGRpdiBjbGFzcz1cImludmFsaWQtZmVlZGJhY2sgZC1ibG9ja1wiPjwvZGl2PicpLnRleHQoZXJyb3IpO1xuICAgICAgICAgICAgJGJvZHkuYXBwZW5kKCRlcnJvcik7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB0aGlzLl9zaG93X21vZGFsKHtcbiAgICAgICAgICAgIHRpdGxlOiB0aXRsZSxcbiAgICAgICAgICAgIGJvZHk6ICRib2R5LFxuICAgICAgICAgICAgYnV0dG9uczogW1xuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgbGFiZWw6ICdDYW5jZWwnLFxuICAgICAgICAgICAgICAgICAgICB2YWx1ZTogZmFsc2UsXG4gICAgICAgICAgICAgICAgICAgIGNsYXNzOiAnYnRuLXNlY29uZGFyeScsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGxhYmVsOiAnU3VibWl0JyxcbiAgICAgICAgICAgICAgICAgICAgdmFsdWU6IG51bGwsIC8vIFdpbGwgYmUgcmVwbGFjZWQgYnkgY2FsbGJhY2tcbiAgICAgICAgICAgICAgICAgICAgY2xhc3M6ICdidG4tcHJpbWFyeScsXG4gICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6IHRydWUsXG4gICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gJGlucHV0LnZhbCgpO1xuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBdLFxuICAgICAgICAgICAgY2xvc2FibGU6IHRydWUsXG4gICAgICAgICAgICBjbG9zZV9vbl9zdWJtaXQ6IHRydWUsXG4gICAgICAgICAgICBtYXhfd2lkdGg6IDUwMCxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gRm9jdXMgYW5kIHNlbGVjdCBpbnB1dCBhZnRlciBtb2RhbCBzaG93c1xuICAgICAgICByZXF1ZXN0QW5pbWF0aW9uRnJhbWUoKCkgPT4ge1xuICAgICAgICAgICAgJGlucHV0LmZvY3VzKCk7XG4gICAgICAgICAgICBpZiAoIW11bHRpbGluZSkge1xuICAgICAgICAgICAgICAgICRpbnB1dC5zZWxlY3QoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG5cbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTaG93IGFuIGVycm9yIGRpYWxvZyB3aXRoIHJlZCBhbGVydCBzdHlsaW5nXG4gICAgICpcbiAgICAgKiBDYW4gYXBwZWFyIG92ZXIgb3RoZXIgbW9kYWxzIHRvIHNob3cgY3JpdGljYWwgdW5jYXVnaHQgZXhjZXB0aW9ucy5cbiAgICAgKiBVc2VkIHByaW1hcmlseSBmb3IgQWpheCBlcnJvcnMgdGhhdCB3ZXJlbid0IGNhdWdodCBieSBhcHBsaWNhdGlvbiBjb2RlLlxuICAgICAqXG4gICAgICogQHBhcmFtIHtzdHJpbmd8RXJyb3J8T2JqZWN0fSBlcnJvciAtIEVycm9yIG1lc3NhZ2Ugc3RyaW5nLCBFcnJvciBvYmplY3QsIG9yIHN0cnVjdHVyZWQgZXJyb3JcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gdGl0bGUgLSBNb2RhbCB0aXRsZSAoZGVmYXVsdDogXCJFcnJvclwiKVxuICAgICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fVxuICAgICAqL1xuICAgIHN0YXRpYyBhc3luYyBlcnJvcihlcnJvciwgdGl0bGUgPSAnRXJyb3InKSB7XG4gICAgICAgIGxldCBtZXNzYWdlID0gJyc7XG5cbiAgICAgICAgLy8gSGFuZGxlIGRpZmZlcmVudCBlcnJvciB0eXBlc1xuICAgICAgICBpZiAodHlwZW9mIGVycm9yID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgbWVzc2FnZSA9IGVycm9yO1xuICAgICAgICB9IGVsc2UgaWYgKGVycm9yIGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgICAgICAgIG1lc3NhZ2UgPSBlcnJvci5tZXNzYWdlIHx8IGVycm9yLnRvU3RyaW5nKCk7XG4gICAgICAgIH0gZWxzZSBpZiAoZXJyb3IgJiYgZXJyb3IubWVzc2FnZSkge1xuICAgICAgICAgICAgbWVzc2FnZSA9IGVycm9yLm1lc3NhZ2U7XG4gICAgICAgIH0gZWxzZSBpZiAoZXJyb3IgJiYgZXJyb3IuZXJyb3IpIHtcbiAgICAgICAgICAgIC8vIEZhdGFsIGVycm9yIHdpdGggZGV0YWlsc1xuICAgICAgICAgICAgY29uc3QgZGV0YWlscyA9IGVycm9yLmVycm9yO1xuICAgICAgICAgICAgaWYgKGRldGFpbHMuZmlsZSAmJiBkZXRhaWxzLmxpbmUpIHtcbiAgICAgICAgICAgICAgICBtZXNzYWdlID0gYFVuY2F1Z2h0IEZhdGFsIEVycm9yIGluICR7ZGV0YWlscy5maWxlfToke2RldGFpbHMubGluZX06XFxuXFxuJHtkZXRhaWxzLmVycm9yfWA7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIG1lc3NhZ2UgPSBkZXRhaWxzLmVycm9yIHx8ICdBbiB1bmtub3duIGVycm9yIG9jY3VycmVkJztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIG1lc3NhZ2UgPSAnQW4gdW5rbm93biBlcnJvciBvY2N1cnJlZCc7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBDcmVhdGUgZXJyb3IgYm9keSB3aXRoIHJlZCBhbGVydCBzdHlsaW5nXG4gICAgICAgIGNvbnN0ICRib2R5ID0gJCgnPGRpdiBjbGFzcz1cImFsZXJ0IGFsZXJ0LWRhbmdlciBtYi0wXCIgcm9sZT1cImFsZXJ0XCI+JykuYXBwZW5kKFxuICAgICAgICAgICAgJCgnPHByZSBjbGFzcz1cIm1iLTBcIiBzdHlsZT1cIndoaXRlLXNwYWNlOiBwcmUtd3JhcDsgd29yZC13cmFwOiBicmVhay13b3JkOyBmb250LWZhbWlseTogbW9ub3NwYWNlOyBmb250LXNpemU6IDAuOWVtO1wiPicpLnRleHQoXG4gICAgICAgICAgICAgICAgbWVzc2FnZVxuICAgICAgICAgICAgKVxuICAgICAgICApO1xuXG4gICAgICAgIGF3YWl0IHRoaXMuX3Nob3dfbW9kYWwoe1xuICAgICAgICAgICAgdGl0bGU6IHRpdGxlLFxuICAgICAgICAgICAgYm9keTogJGJvZHksXG4gICAgICAgICAgICBidXR0b25zOiBbXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBsYWJlbDogJ0Nsb3NlJyxcbiAgICAgICAgICAgICAgICAgICAgdmFsdWU6IHRydWUsXG4gICAgICAgICAgICAgICAgICAgIGNsYXNzOiAnYnRuLWRhbmdlcicsXG4gICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6IHRydWUsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgICBjbG9zYWJsZTogdHJ1ZSxcbiAgICAgICAgICAgIGNsb3NlX29uX3N1Ym1pdDogdHJ1ZSxcbiAgICAgICAgICAgIG1heF93aWR0aDogNjAwLFxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICAgIC8vIEN1c3RvbSBNb2RhbCBNZXRob2RzXG4gICAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuICAgIC8qKlxuICAgICAqIFNob3cgYSBjdXN0b20gbW9kYWwgd2l0aCBzcGVjaWZpZWQgY29udGVudCBhbmQgYnV0dG9uc1xuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zXG4gICAgICogQHJldHVybnMge1Byb21pc2U8Kj59XG4gICAgICovXG4gICAgc3RhdGljIGFzeW5jIHNob3cob3B0aW9ucykge1xuICAgICAgICBjb25zdCBkZWZhdWx0cyA9IHtcbiAgICAgICAgICAgIHRpdGxlOiAnTW9kYWwnLFxuICAgICAgICAgICAgYm9keTogJycsXG4gICAgICAgICAgICBidXR0b25zOiBbXSxcbiAgICAgICAgICAgIG1heF93aWR0aDogODAwLFxuICAgICAgICAgICAgY2xvc2FibGU6IHRydWUsXG4gICAgICAgICAgICBjbG9zZV9vbl9zdWJtaXQ6IHRydWUsXG4gICAgICAgIH07XG5cbiAgICAgICAgY29uc3QgZmluYWxfb3B0aW9ucyA9IE9iamVjdC5hc3NpZ24oe30sIGRlZmF1bHRzLCBvcHRpb25zKTtcblxuICAgICAgICByZXR1cm4gYXdhaXQgdGhpcy5fc2hvd19tb2RhbChmaW5hbF9vcHRpb25zKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTaG93IGEgbW9kYWwgd2l0aCBhIGpxaHRtbCBmb3JtIGNvbXBvbmVudFxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IG9wdGlvbnMuY29tcG9uZW50IC0gQ29tcG9uZW50IGNsYXNzIG5hbWVcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb3B0aW9ucy5jb21wb25lbnRfYXJncyAtIEFyZ3VtZW50cyB0byBwYXNzIHRvIGNvbXBvbmVudFxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IG9wdGlvbnMub25fc3VibWl0IC0gQ2FsbGJhY2sgZnVuY3Rpb24gY2FsbGVkIG9uIHN1Ym1pdC4gUmVjZWl2ZXMgZm9ybSBjb21wb25lbnQgaW5zdGFuY2UuXG4gICAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUmV0dXJuIGZhbHNlIHRvIGtlZXAgbW9kYWwgb3Blbiwgb3IgcmV0dXJuIGRhdGEgdG8gY2xvc2UgYW5kIHJlc29sdmUuXG4gICAgICogQHJldHVybnMge1Byb21pc2U8T2JqZWN0fGZhbHNlPn1cbiAgICAgKi9cbiAgICBzdGF0aWMgYXN5bmMgZm9ybShvcHRpb25zKSB7XG4gICAgICAgIGNvbnN0IGRlZmF1bHRzID0ge1xuICAgICAgICAgICAgdGl0bGU6ICdGb3JtJyxcbiAgICAgICAgICAgIGNvbXBvbmVudDogbnVsbCxcbiAgICAgICAgICAgIGNvbXBvbmVudF9hcmdzOiB7fSxcbiAgICAgICAgICAgIG1heF93aWR0aDogODAwLFxuICAgICAgICAgICAgY2xvc2FibGU6IHRydWUsXG4gICAgICAgICAgICBzdWJtaXRfbGFiZWw6ICdTdWJtaXQnLFxuICAgICAgICAgICAgY2FuY2VsX2xhYmVsOiAnQ2FuY2VsJyxcbiAgICAgICAgICAgIG9uX3N1Ym1pdDogbnVsbCxcbiAgICAgICAgfTtcblxuICAgICAgICBjb25zdCBmaW5hbF9vcHRpb25zID0gT2JqZWN0LmFzc2lnbih7fSwgZGVmYXVsdHMsIG9wdGlvbnMpO1xuXG4gICAgICAgIGlmICghZmluYWxfb3B0aW9ucy5jb21wb25lbnQpIHtcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ01vZGFsLmZvcm0oKSByZXF1aXJlcyBhIGNvbXBvbmVudCcpO1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gQ3JlYXRlIGNvbXBvbmVudCBpbnN0YW5jZVxuICAgICAgICBsZXQgJGNvbXBvbmVudF9jb250YWluZXIgPSAkKCc8ZGl2PicpO1xuICAgICAgICBsZXQgY29tcG9uZW50X2luc3RhbmNlID0gJGNvbXBvbmVudF9jb250YWluZXIuY29tcG9uZW50KGZpbmFsX29wdGlvbnMuY29tcG9uZW50LCBmaW5hbF9vcHRpb25zLmNvbXBvbmVudF9hcmdzKTtcblxuICAgICAgICAvLyBXYWl0IGZvciBjb21wb25lbnQgdG8gYmUgcmVhZHlcbiAgICAgICAgYXdhaXQgbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHtcbiAgICAgICAgICAgIGNvbXBvbmVudF9pbnN0YW5jZS5vbigncmVhZHknLCAoKSA9PiByZXNvbHZlKCkpO1xuICAgICAgICB9KTtcblxuICAgICAgICAvLyBGaW5kIGEgZm9ybSBpbnN0YW5jZSBpZiBjb21wb25lbnQgaW5zdGFuY2UgZG9lc250IGhhdmUgLnZhbHMoKVxuICAgICAgICBpZiAoIWNvbXBvbmVudF9pbnN0YW5jZS52YWxzKSB7XG4gICAgICAgICAgICBsZXQgJGZvcm0gPSBjb21wb25lbnRfaW5zdGFuY2UuJC5maW5kKCcuUnN4X0Zvcm0nKTtcbiAgICAgICAgICAgIGlmICgkZm9ybS5leGlzdHMoKSkge1xuICAgICAgICAgICAgICAgIGNvbXBvbmVudF9pbnN0YW5jZSA9ICRmb3JtLmNvbXBvbmVudCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gQ3JlYXRlIGJ1dHRvbnNcbiAgICAgICAgY29uc3QgYnV0dG9ucyA9IFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBsYWJlbDogZmluYWxfb3B0aW9ucy5jYW5jZWxfbGFiZWwsXG4gICAgICAgICAgICAgICAgdmFsdWU6IGZhbHNlLFxuICAgICAgICAgICAgICAgIGNsYXNzOiAnYnRuLXNlY29uZGFyeScsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGxhYmVsOiBmaW5hbF9vcHRpb25zLnN1Ym1pdF9sYWJlbCxcbiAgICAgICAgICAgICAgICB2YWx1ZTogbnVsbCxcbiAgICAgICAgICAgICAgICBjbGFzczogJ2J0bi1wcmltYXJ5JyxcbiAgICAgICAgICAgICAgICBkZWZhdWx0OiB0cnVlLFxuICAgICAgICAgICAgICAgIGNhbGxiYWNrOiBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIElmIG9uX3N1Ym1pdCBjYWxsYmFjayBwcm92aWRlZCwgdXNlIGl0XG4gICAgICAgICAgICAgICAgICAgIGlmIChmaW5hbF9vcHRpb25zLm9uX3N1Ym1pdCAmJiB0eXBlb2YgZmluYWxfb3B0aW9ucy5vbl9zdWJtaXQgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGZpbmFsX29wdGlvbnMub25fc3VibWl0KGNvbXBvbmVudF9pbnN0YW5jZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBJZiBjYWxsYmFjayByZXR1cm5zIG51bGwvdW5kZWZpbmVkLCBrZWVwIG1vZGFsIG9wZW5cbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyZXN1bHQgPT09IG51bGwgfHwgcmVzdWx0ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBPdGhlcndpc2UgKGluY2x1ZGluZyBmYWxzZSksIHJldHVybiB0aGUgcmVzdWx0IHRvIGNsb3NlIG1vZGFsXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgLy8gTm8gb25fc3VibWl0IGNhbGxiYWNrIC0gZ2V0IGZvcm0gZGF0YSBhbmQgY2xvc2UgbW9kYWxcbiAgICAgICAgICAgICAgICAgICAgaWYgKGNvbXBvbmVudF9pbnN0YW5jZS5zdWJtaXQgJiYgdHlwZW9mIGNvbXBvbmVudF9pbnN0YW5jZS5zdWJtaXQgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBhd2FpdCBjb21wb25lbnRfaW5zdGFuY2Uuc3VibWl0KCk7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoY29tcG9uZW50X2luc3RhbmNlLnZhbHMgJiYgdHlwZW9mIGNvbXBvbmVudF9pbnN0YW5jZS52YWxzID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gY29tcG9uZW50X2luc3RhbmNlLnZhbHMoKTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUud2FybignRm9ybSBjb21wb25lbnQgaGFzIG5vIHN1Ym1pdCgpIG9yIHZhbHMoKSBtZXRob2QnKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgIF07XG5cbiAgICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuX3Nob3dfbW9kYWwoe1xuICAgICAgICAgICAgdGl0bGU6IGZpbmFsX29wdGlvbnMudGl0bGUsXG4gICAgICAgICAgICBib2R5OiBjb21wb25lbnRfaW5zdGFuY2UuJCxcbiAgICAgICAgICAgIGJ1dHRvbnM6IGJ1dHRvbnMsXG4gICAgICAgICAgICBtYXhfd2lkdGg6IGZpbmFsX29wdGlvbnMubWF4X3dpZHRoLFxuICAgICAgICAgICAgY2xvc2FibGU6IGZpbmFsX29wdGlvbnMuY2xvc2FibGUsXG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNob3cgYW4gdW5jbG9zYWJsZSBtb2RhbFxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSB0aXRsZV9vcl9ib2R5XG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGJvZHlcbiAgICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn1cbiAgICAgKi9cbiAgICBzdGF0aWMgYXN5bmMgdW5jbG9zYWJsZSh0aXRsZV9vcl9ib2R5LCBib2R5ID0gbnVsbCkge1xuICAgICAgICBsZXQgdGl0bGUgPSAnUGxlYXNlIFdhaXQnO1xuICAgICAgICBsZXQgbWVzc2FnZSA9IHRpdGxlX29yX2JvZHk7XG5cbiAgICAgICAgaWYgKGJvZHkgIT09IG51bGwpIHtcbiAgICAgICAgICAgIHRpdGxlID0gdGl0bGVfb3JfYm9keTtcbiAgICAgICAgICAgIG1lc3NhZ2UgPSBib2R5O1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gRG9uJ3Qgd2FpdCBmb3IgdGhpcyBwcm9taXNlIC0gaXQgbmV2ZXIgcmVzb2x2ZXMgdW50aWwgY2xvc2VkIG1hbnVhbGx5XG4gICAgICAgIHRoaXMuX3Nob3dfbW9kYWwoe1xuICAgICAgICAgICAgdGl0bGU6IHRpdGxlLFxuICAgICAgICAgICAgYm9keTogbWVzc2FnZSxcbiAgICAgICAgICAgIGJ1dHRvbnM6IFtdLCAvLyBObyBidXR0b25zXG4gICAgICAgICAgICBjbG9zYWJsZTogZmFsc2UsIC8vIENhbid0IGNsb3NlXG4gICAgICAgICAgICBjbG9zZV9vbl9zdWJtaXQ6IGZhbHNlLFxuICAgICAgICB9KTtcblxuICAgICAgICAvLyBXYWl0IGZvciBuZXh0IGFuaW1hdGlvbiBmcmFtZSBmb3IgbW9kYWwgdG8gcmVuZGVyXG4gICAgICAgIGF3YWl0IG5ldyBQcm9taXNlKHJlc29sdmUgPT4gcmVxdWVzdEFuaW1hdGlvbkZyYW1lKHJlc29sdmUpKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTaG93IGEgbW9kYWwgd2l0aCBjdXN0b20galF1ZXJ5IGNvbnRlbnRcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb3B0aW9uc1xuICAgICAqIEByZXR1cm5zIHtQcm9taXNlPCo+fVxuICAgICAqL1xuICAgIHN0YXRpYyBhc3luYyBjdXN0b20ob3B0aW9ucykge1xuICAgICAgICAvLyBBbGlhcyBmb3Igc2hvdygpIC0gc2FtZSBmdW5jdGlvbmFsaXR5XG4gICAgICAgIHJldHVybiBhd2FpdCB0aGlzLnNob3cob3B0aW9ucyk7XG4gICAgfVxuXG4gICAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAgICAvLyBIZWxwZXIgTWV0aG9kc1xuICAgIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbiAgICAvKipcbiAgICAgKiBTaG93IGFuIGVycm9yIGFsZXJ0XG4gICAgICogQHBhcmFtIHsqfSBlcnJvcnNcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gdGl0bGVcbiAgICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn1cbiAgICAgKi9cbiAgICBzdGF0aWMgYXN5bmMgZXJyb3IoZXJyb3JzLCB0aXRsZSA9ICdFcnJvcicpIHtcbiAgICAgICAgbGV0IG1lc3NhZ2UgPSAnQW4gZXJyb3Igb2NjdXJyZWQnO1xuXG4gICAgICAgIC8vIEhhbmRsZSB2YXJpb3VzIGVycm9yIGZvcm1hdHNcbiAgICAgICAgaWYgKHR5cGVvZiBlcnJvcnMgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICBtZXNzYWdlID0gZXJyb3JzO1xuICAgICAgICB9IGVsc2UgaWYgKGVycm9ycyAmJiAncmVzcG9uc2VKU09OJyBpbiBlcnJvcnMgJiYgJ21lc3NhZ2UnIGluIGVycm9ycy5yZXNwb25zZUpTT04pIHtcbiAgICAgICAgICAgIG1lc3NhZ2UgPSBlcnJvcnMucmVzcG9uc2VKU09OLm1lc3NhZ2U7XG4gICAgICAgIH0gZWxzZSBpZiAoZXJyb3JzICYmICdtZXNzYWdlJyBpbiBlcnJvcnMpIHtcbiAgICAgICAgICAgIG1lc3NhZ2UgPSBlcnJvcnMubWVzc2FnZTtcbiAgICAgICAgfSBlbHNlIGlmIChlcnJvcnMgJiYgdHlwZW9mIGVycm9ycyA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgICAgIC8vIFRyeSB0byBmb3JtYXQgZXJyb3Igb2JqZWN0XG4gICAgICAgICAgICBjb25zdCBlcnJvcl9tZXNzYWdlcyA9IFtdO1xuICAgICAgICAgICAgZm9yIChjb25zdCBrZXkgaW4gZXJyb3JzKSB7XG4gICAgICAgICAgICAgICAgaWYgKGlzX2FycmF5KGVycm9yc1trZXldKSkge1xuICAgICAgICAgICAgICAgICAgICBlcnJvcl9tZXNzYWdlcy5wdXNoKGVycm9yc1trZXldWzBdKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBlcnJvcl9tZXNzYWdlcy5wdXNoKGVycm9yc1trZXldKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoZXJyb3JfbWVzc2FnZXMubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgIG1lc3NhZ2UgPSBlcnJvcl9tZXNzYWdlcy5qb2luKCdcXG4nKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGF3YWl0IHRoaXMuX3Nob3dfbW9kYWwoe1xuICAgICAgICAgICAgdGl0bGU6IHRpdGxlLFxuICAgICAgICAgICAgYm9keTogbWVzc2FnZSxcbiAgICAgICAgICAgIGljb246ICdleGNsYW1hdGlvbi1jaXJjbGUnLFxuICAgICAgICAgICAgYnV0dG9uczogW1xuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgbGFiZWw6ICdPSycsXG4gICAgICAgICAgICAgICAgICAgIHZhbHVlOiB0cnVlLFxuICAgICAgICAgICAgICAgICAgICBjbGFzczogJ2J0bi1kYW5nZXInLFxuICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OiB0cnVlLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBdLFxuICAgICAgICAgICAgY2xvc2FibGU6IHRydWUsXG4gICAgICAgICAgICBjbG9zZV9vbl9zdWJtaXQ6IHRydWUsXG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlb3BlbiBjdXJyZW50IG1vZGFsIHdpdGggdmFsaWRhdGlvbiBlcnJvcnNcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gZXJyb3JzXG4gICAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59XG4gICAgICovXG4gICAgc3RhdGljIGFzeW5jIHJlb3Blbl93aXRoX2Vycm9ycyhlcnJvcnMpIHtcbiAgICAgICAgaWYgKHRoaXMuX2N1cnJlbnQpIHtcbiAgICAgICAgICAgIC8vIE1vZGFsIGlzIHN0aWxsIG9wZW4sIGp1c3QgYXBwbHkgZXJyb3JzXG4gICAgICAgICAgICB0aGlzLmFwcGx5X2Vycm9ycyhlcnJvcnMpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29uc29sZS53YXJuKCdObyBtb2RhbCBvcGVuIHRvIGFwcGx5IGVycm9ycyB0bycpO1xuICAgICAgICB9XG4gICAgfVxufVxuIl0sIm1hcHBpbmdzIjoiOzs7OztBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU1BLEtBQUssQ0FBQztFQVdSO0FBQ0o7QUFDQTtBQUNBO0VBQ0ksT0FBT0MsS0FBS0EsQ0FBQSxFQUFHO0lBQ1gsSUFBSSxJQUFJLENBQUNDLFlBQVksRUFBRTtJQUN2QixJQUFJLENBQUNBLFlBQVksR0FBRyxJQUFJOztJQUV4QjtJQUNBLElBQUksQ0FBQ0MsU0FBUyxHQUFHQyxDQUFDLENBQUMseUNBQXlDLENBQUM7SUFDN0RBLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQ0MsTUFBTSxDQUFDLElBQUksQ0FBQ0YsU0FBUyxDQUFDO0VBQ3BDOztFQUVBO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7RUFDSSxPQUFP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
|