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>
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.$sid('title').length,
|
|
body: modal_instance.$sid('body').length,
|
|
footer: modal_instance.$sid('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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
|