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>
20457 lines
2.0 MiB
Executable File
20457 lines
2.0 MiB
Executable File
/* === storage/rsx-tmp/bundle_config_Frontend_Bundle.js === */
|
|
window.rsxapp = window.rsxapp || {};
|
|
window.rsxapp.module_paths = {"bootstrap5_src":"rsx\/theme\/vendor\/bootstrap5\/scss"};
|
|
|
|
|
|
/* === storage/rsx-tmp/npm_import_declarations_95a6f602c98037611b640b0b5342830b.js === */
|
|
// NPM Import Declarations for App Bundle
|
|
// Auto-generated to provide NPM modules to app bundle scope
|
|
// Cache key: 95a6f602c98037611b640b0b5342830b
|
|
|
|
const jqhtml = window._rsx_npm.jqhtml;
|
|
if (!jqhtml) {
|
|
throw new Error(
|
|
'RSX Framework Error: NPM module "jqhtml" not found.\n' +
|
|
'Expected window._rsx_npm.jqhtml to be defined by the vendor bundle.'
|
|
);
|
|
}
|
|
|
|
const _Base_Jqhtml_Component = window._rsx_npm._Base_Jqhtml_Component;
|
|
if (!_Base_Jqhtml_Component) {
|
|
throw new Error(
|
|
'RSX Framework Error: NPM module "_Base_Jqhtml_Component" not found.\n' +
|
|
'Expected window._rsx_npm._Base_Jqhtml_Component to be defined by the vendor bundle.'
|
|
);
|
|
}
|
|
|
|
// Clean up NPM container to prevent console access
|
|
delete window._rsx_npm;
|
|
|
|
|
|
/* === app/RSpade/Core/Js/decorator.js (babel) === */
|
|
"use strict";
|
|
|
|
/**
|
|
* Decorator function that marks a function as a decorator implementation.
|
|
*
|
|
* When a function has @decorator in its JSDoc comment, it whitelists that function
|
|
* to be used as a decorator on other methods throughout the codebase.
|
|
*
|
|
* The function itself performs no operation - it simply returns its input unchanged.
|
|
* Its purpose is purely as a marker for the manifest validation system.
|
|
*
|
|
* Usage:
|
|
* // /**
|
|
* // * My custom decorator implementation
|
|
* // * @decorator
|
|
* // *\/
|
|
* function my_custom_decorator(target, key, descriptor) {
|
|
* // Decorator implementation
|
|
* }
|
|
*
|
|
* This allows my_custom_decorator to be used as @my_custom_decorator on static methods.
|
|
*
|
|
* TODO: This is probably no longer necessary? maybe?
|
|
*/
|
|
function decorator(value) {
|
|
return value;
|
|
}
|
|
|
|
|
|
/* === app/RSpade/Core/Js/browser.js (babel) === */
|
|
"use strict";
|
|
|
|
/*
|
|
* Browser and DOM utility functions for the RSpade framework.
|
|
* These functions handle browser detection, viewport utilities, and DOM manipulation.
|
|
*/
|
|
|
|
// ============================================================================
|
|
// BROWSER DETECTION
|
|
// ============================================================================
|
|
|
|
/**
|
|
* Detects if user is on a mobile device or using mobile viewport
|
|
* @returns {boolean} True if mobile device or viewport < 992px
|
|
* @todo Improve user agent detection for all mobile devices
|
|
*/
|
|
function is_mobile() {
|
|
if (/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)) {
|
|
return true;
|
|
} else if ($(window).width() < 992) {
|
|
// 992px = bootstrap 4 col-md-
|
|
return true;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Detects if user is on desktop (not mobile)
|
|
* @returns {boolean} True if not mobile device/viewport
|
|
*/
|
|
function is_desktop() {
|
|
return !is_mobile();
|
|
}
|
|
|
|
/**
|
|
* Detects the user's operating system
|
|
* @returns {string} OS name: 'Mac OS', 'iPhone', 'iPad', 'Windows', 'Android-Phone', 'Android-Tablet', 'Linux', or 'Unknown'
|
|
*/
|
|
function get_os() {
|
|
let user_agent = window.navigator.userAgent,
|
|
platform = window.navigator.platform,
|
|
macos_platforms = ['Macintosh', 'MacIntel', 'MacPPC', 'Mac68K'],
|
|
windows_platforms = ['Win32', 'Win64', 'Windows', 'WinCE'],
|
|
ios_platforms = ['iPhone', 'iPad', 'iPod'],
|
|
os = null;
|
|
let is_mobile_device = is_mobile();
|
|
if (macos_platforms.indexOf(platform) !== -1) {
|
|
os = 'Mac OS';
|
|
} else if (ios_platforms.indexOf(platform) !== -1 && is_mobile_device) {
|
|
os = 'iPhone';
|
|
} else if (ios_platforms.indexOf(platform) !== -1 && !is_mobile_device) {
|
|
os = 'iPad';
|
|
} else if (windows_platforms.indexOf(platform) !== -1) {
|
|
os = 'Windows';
|
|
} else if (/Android/.test(user_agent) && is_mobile_device) {
|
|
os = 'Android-Phone';
|
|
} else if (/Android/.test(user_agent) && !is_mobile_device) {
|
|
os = 'Android-Tablet';
|
|
} else if (!os && /Linux/.test(platform)) {
|
|
os = 'Linux';
|
|
} else {
|
|
os = 'Unknown';
|
|
}
|
|
return os;
|
|
}
|
|
|
|
/**
|
|
* Detects if the user agent is a web crawler/bot
|
|
* @returns {boolean} True if user agent appears to be a bot/crawler
|
|
*/
|
|
function is_crawler() {
|
|
let user_agent = navigator.userAgent;
|
|
let bot_pattern = /bot|spider|crawl|slurp|archiver|ping|search|dig|tracker|monitor|snoopy|yahoo|baidu|msn|ask|teoma|axios/i;
|
|
return bot_pattern.test(user_agent);
|
|
}
|
|
|
|
// ============================================================================
|
|
// DOM SCROLLING UTILITIES
|
|
// ============================================================================
|
|
|
|
/**
|
|
* Scrolls parent container to make target element visible if needed
|
|
* @param {string|HTMLElement|jQuery} target - Target element to scroll into view
|
|
*/
|
|
function scroll_into_view_if_needed(target) {
|
|
const $target = $(target);
|
|
|
|
// Find the closest parent with overflow-y: auto
|
|
const $parent = $target.parent();
|
|
|
|
// Calculate the absolute top position of the target
|
|
const target_top = $target.position().top + $parent.scrollTop();
|
|
const target_height = $target.outerHeight();
|
|
const parent_height = $parent.height();
|
|
const scroll_position = $parent.scrollTop();
|
|
|
|
// Check if the target is out of view
|
|
if (target_top < scroll_position || target_top + target_height > scroll_position + parent_height) {
|
|
Debugger.console_debug('UI', 'Scrolling!', target_top);
|
|
|
|
// Calculate the new scroll position to center the target
|
|
let new_scroll_position = target_top + target_height / 2 - parent_height / 2;
|
|
|
|
// Limit the scroll position between 0 and the maximum scrollable height
|
|
new_scroll_position = Math.max(0, Math.min(new_scroll_position, $parent[0].scrollHeight - parent_height));
|
|
|
|
// Scroll the parent to the new scroll position
|
|
$parent.scrollTop(new_scroll_position);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Scrolls page to make target element visible if needed (with animation)
|
|
* @param {string|HTMLElement|jQuery} target - Target element to scroll into view
|
|
*/
|
|
function scroll_page_into_view_if_needed(target) {
|
|
const $target = $(target);
|
|
|
|
// Calculate the absolute top position of the target relative to the document
|
|
const target_top = $target.offset().top;
|
|
const target_height = $target.outerHeight();
|
|
const window_height = $(window).height();
|
|
const window_scroll_position = $(window).scrollTop();
|
|
|
|
// Check if the target is out of view
|
|
if (target_top < window_scroll_position || target_top + target_height > window_scroll_position + window_height) {
|
|
Debugger.console_debug('UI', 'Scrolling!', target_top);
|
|
|
|
// Calculate the new scroll position to center the target
|
|
const new_scroll_position = target_top + target_height / 2 - window_height / 2;
|
|
|
|
// Animate the scroll to the new position
|
|
$('html, body').animate({
|
|
scrollTop: new_scroll_position
|
|
}, 1000); // duration of the scroll animation in milliseconds
|
|
}
|
|
}
|
|
|
|
// ============================================================================
|
|
// DOM UTILITIES
|
|
// ============================================================================
|
|
|
|
/**
|
|
* Waits for all images on the page to load
|
|
* @param {Function} callback - Function to call when all images are loaded
|
|
*/
|
|
function wait_for_images(callback) {
|
|
const $images = $('img'); // Get all img tags
|
|
const total_images = $images.length;
|
|
let images_loaded = 0;
|
|
if (total_images === 0) {
|
|
callback(); // if there are no images, immediately call the callback
|
|
}
|
|
$images.each(function () {
|
|
const img = new Image();
|
|
img.onload = function () {
|
|
images_loaded++;
|
|
if (images_loaded === total_images) {
|
|
callback(); // call the callback when all images are loaded
|
|
}
|
|
};
|
|
img.onerror = function () {
|
|
images_loaded++;
|
|
if (images_loaded === total_images) {
|
|
callback(); // also call the callback if an image fails to load
|
|
}
|
|
};
|
|
img.src = this.src; // this triggers the loading
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Creates a jQuery element containing a non-breaking space
|
|
* @returns {jQuery} jQuery span element with
|
|
*/
|
|
function $nbsp() {
|
|
return $('<span> </span>');
|
|
}
|
|
|
|
/**
|
|
* Escapes special characters in a jQuery selector
|
|
* @param {string} id - Element ID to escape
|
|
* @returns {string} jQuery selector string with escaped special characters
|
|
* @warning Not safe for security-critical operations
|
|
*/
|
|
function escape_jq_selector(id) {
|
|
return '#' + id.replace(/(:|\.|\[|\]|,|=|@)/g, '\\$1');
|
|
}
|
|
|
|
|
|
/* === app/RSpade/Core/Js/datetime.js (babel) === */
|
|
"use strict";
|
|
|
|
/*
|
|
* Date and time utility functions for the RSpade framework.
|
|
* These functions handle date/time conversions and Unix timestamps.
|
|
*/
|
|
|
|
// ============================================================================
|
|
// DATE/TIME UTILITIES
|
|
// ============================================================================
|
|
|
|
/**
|
|
* Gets the current Unix timestamp (seconds since epoch)
|
|
* @returns {number} Current Unix timestamp in seconds
|
|
* @todo Calculate based on server time at page render
|
|
* @todo Move to a date library
|
|
*/
|
|
function unix_time() {
|
|
return Math.round(new Date().getTime() / 1000);
|
|
}
|
|
|
|
/**
|
|
* Converts a date string to Unix timestamp
|
|
* @param {string} str_date - Date string (Y-m-d H:i:s format)
|
|
* @returns {number} Unix timestamp in seconds
|
|
*/
|
|
function ymdhis_to_unix(str_date) {
|
|
const date = new Date(str_date);
|
|
return date.getTime() / 1000;
|
|
}
|
|
|
|
|
|
/* === app/RSpade/Core/Js/error.js (babel) === */
|
|
"use strict";
|
|
|
|
/*
|
|
* Error handling utility functions for the RSpade framework.
|
|
* These functions handle error creation and debugging utilities.
|
|
*/
|
|
|
|
// ============================================================================
|
|
// ERROR HANDLING
|
|
// ============================================================================
|
|
|
|
/**
|
|
* Creates an error object from a string
|
|
* @param {string|Object} str - Error message or existing error object
|
|
* @param {number} [error_code] - Optional error status code
|
|
* @returns {Object} Error object with error and status properties
|
|
*/
|
|
function error(str, error_code) {
|
|
if (typeof str.error != undef) {
|
|
return str;
|
|
} else {
|
|
if (typeof error_code == undef) {
|
|
return {
|
|
error: str,
|
|
status: null
|
|
};
|
|
} else {
|
|
return {
|
|
error: str,
|
|
status: error_code
|
|
};
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Sanity check failure handler for JavaScript
|
|
*
|
|
* This function should be called when a sanity check fails - i.e., when the code
|
|
* encounters a condition that "shouldn't happen" if everything is working correctly.
|
|
*
|
|
* Unlike PHP, we can't stop JavaScript execution, but we can:
|
|
* 1. Throw an error that will be caught by error handlers
|
|
* 2. Log a clear error to the console
|
|
* 3. Provide stack trace for debugging
|
|
*
|
|
* Use this instead of silently returning or continuing when encountering unexpected conditions.
|
|
*
|
|
* @param {string} message Optional specific message about what shouldn't have happened
|
|
* @throws {Error} Always throws with location and context information
|
|
*/
|
|
function shouldnt_happen() {
|
|
let message = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
|
|
const error = new Error();
|
|
const stack = error.stack || '';
|
|
const stackLines = stack.split('\n');
|
|
|
|
// Get the caller location (skip the Error line and this function)
|
|
let callerInfo = 'unknown location';
|
|
if (stackLines.length > 2) {
|
|
const callerLine = stackLines[2] || stackLines[1] || '';
|
|
// Extract file and line number from stack trace
|
|
const match = callerLine.match(/at\s+.*?\s+\((.*?):(\d+):(\d+)\)/) || callerLine.match(/at\s+(.*?):(\d+):(\d+)/);
|
|
if (match) {
|
|
callerInfo = `${match[1]}:${match[2]}`;
|
|
}
|
|
}
|
|
let errorMessage = `Fatal: shouldnt_happen() was called at ${callerInfo}\n`;
|
|
errorMessage += 'This indicates a sanity check failed - the code is not behaving as expected.\n';
|
|
if (message) {
|
|
errorMessage += `Details: ${message}\n`;
|
|
}
|
|
errorMessage += 'Please thoroughly review the related code to determine why this error occurred.';
|
|
|
|
// Log to console with full visibility
|
|
console.error('='.repeat(80));
|
|
console.error('SANITY CHECK FAILURE');
|
|
console.error('='.repeat(80));
|
|
console.error(errorMessage);
|
|
console.error('Stack trace:', stack);
|
|
console.error('='.repeat(80));
|
|
|
|
// Throw error to stop execution flow
|
|
const fatalError = new Error(errorMessage);
|
|
fatalError.name = 'SanityCheckFailure';
|
|
throw fatalError;
|
|
}
|
|
|
|
|
|
/* === app/RSpade/Core/Js/hash.js (babel) === */
|
|
"use strict";
|
|
|
|
/*
|
|
* Hashing and comparison utility functions for the RSpade framework.
|
|
* These functions handle object hashing and deep comparison.
|
|
*/
|
|
|
|
// ============================================================================
|
|
// HASHING AND COMPARISON
|
|
// ============================================================================
|
|
|
|
/**
|
|
* Generates a unique hash for any value (handles objects, arrays, circular references)
|
|
* @param {*} the_var - Value to hash
|
|
* @param {boolean} [calc_sha1=true] - If true, returns SHA1 hash; if false, returns JSON
|
|
* @param {Array<string>} [ignored_keys=null] - Keys to ignore when hashing objects
|
|
* @returns {string} SHA1 hash or JSON string of the value
|
|
*/
|
|
function hash(the_var) {
|
|
let calc_sha1 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
|
|
let ignored_keys = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
|
|
if (typeof the_var == undef) {
|
|
the_var = '__undefined__';
|
|
}
|
|
if (ignored_keys === null) {
|
|
ignored_keys = ['$'];
|
|
}
|
|
|
|
// Converts value to json, discarding circular references
|
|
let json_stringify_nocirc = function (value) {
|
|
const cache = [];
|
|
return JSON.stringify(value, function (key, v) {
|
|
if (typeof v === 'object' && typeof the_var._cache_key == 'function') {
|
|
return the_var._hash_key();
|
|
} else if (typeof v === 'object' && v !== null) {
|
|
if (cache.indexOf(v) !== -1) {
|
|
// Duplicate reference found, discard key
|
|
return;
|
|
}
|
|
cache.push(v);
|
|
}
|
|
return v;
|
|
});
|
|
};
|
|
|
|
// Turn every property and all its children into a single depth array of values that we can then
|
|
// sort and hash as a whole
|
|
let flat_var = {};
|
|
let _flatten = function (the_var, prefix) {
|
|
let depth = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;
|
|
// If a class object is provided, circular references can make the call stack recursive.
|
|
// For the purposes of how the hash function is called, this should be sufficient.
|
|
if (depth > 10) {
|
|
return;
|
|
}
|
|
|
|
// Does not account for dates i think...
|
|
|
|
if (is_object(the_var) && typeof the_var._cache_key == 'function') {
|
|
// Use _cache_key to hash components
|
|
flat_var[prefix] = the_var._hash_key();
|
|
} else if (is_object(the_var) && typeof Abstract !== 'undefined' && the_var instanceof Abstract) {
|
|
// Stringify all class objects
|
|
flat_var[prefix] = json_stringify_nocirc(the_var);
|
|
} else if (is_object(the_var)) {
|
|
// Iterate other objects
|
|
flat_var[prefix] = {};
|
|
for (let k in the_var) {
|
|
if (the_var.hasOwnProperty(k) && ignored_keys.indexOf(k) == -1) {
|
|
_flatten(the_var[k], prefix + '..' + k, depth + 1);
|
|
}
|
|
}
|
|
} else if (is_array(the_var)) {
|
|
// Iterate arrays
|
|
flat_var[prefix] = [];
|
|
let i = 0;
|
|
foreach(the_var, v => {
|
|
_flatten(v, prefix + '..' + i, depth + 1);
|
|
i++;
|
|
});
|
|
} else if (is_function(the_var)) {
|
|
// nothing
|
|
} else if (!is_numeric(the_var)) {
|
|
flat_var[prefix] = String(the_var);
|
|
} else {
|
|
flat_var[prefix] = the_var;
|
|
}
|
|
};
|
|
_flatten(the_var, '_');
|
|
let sorter = [];
|
|
foreach(flat_var, function (v, k) {
|
|
sorter.push([k, v]);
|
|
});
|
|
sorter.sort(function (a, b) {
|
|
return a[0] > b[0];
|
|
});
|
|
let json = JSON.stringify(sorter);
|
|
if (calc_sha1) {
|
|
let hashed = sha1.sha1(json);
|
|
return hashed;
|
|
} else {
|
|
return json;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Deep comparison of two values (ignores property order and functions)
|
|
* @param {*} a - First value to compare
|
|
* @param {*} b - Second value to compare
|
|
* @returns {boolean} True if values are deeply equal
|
|
*/
|
|
function deep_equal(a, b) {
|
|
return hash(a, false) == hash(b, false);
|
|
}
|
|
|
|
|
|
/* === app/RSpade/Core/Js/Mutex.js (babel) === */
|
|
"use strict";
|
|
|
|
/**
|
|
* Mutex decorator for exclusive method execution
|
|
*
|
|
* Without arguments: Per-instance locking (each object has its own lock per method)
|
|
* @mutex
|
|
* async my_method() { ... }
|
|
*
|
|
* With ID argument: Global locking by ID (all instances share the lock)
|
|
* @mutex('operation_name')
|
|
* async my_method() { ... }
|
|
*
|
|
* @decorator
|
|
* @param {string} [global_id] - Optional global mutex ID for cross-instance locking
|
|
*/
|
|
function mutex(global_id) {
|
|
// Storage (using IIFEs to keep WeakMap/Map in closure scope)
|
|
const instance_mutexes = function () {
|
|
if (!mutex._instance_storage) {
|
|
mutex._instance_storage = new WeakMap();
|
|
}
|
|
return mutex._instance_storage;
|
|
}();
|
|
const global_mutexes = function () {
|
|
if (!mutex._global_storage) {
|
|
mutex._global_storage = new Map();
|
|
}
|
|
return mutex._global_storage;
|
|
}();
|
|
|
|
/**
|
|
* Get or create a mutex for a specific instance and method
|
|
*/
|
|
function get_instance_mutex(instance, method_name) {
|
|
let instance_locks = instance_mutexes.get(instance);
|
|
if (!instance_locks) {
|
|
instance_locks = new Map();
|
|
instance_mutexes.set(instance, instance_locks);
|
|
}
|
|
let lock_state = instance_locks.get(method_name);
|
|
if (!lock_state) {
|
|
lock_state = {
|
|
active: false,
|
|
queue: []
|
|
};
|
|
instance_locks.set(method_name, lock_state);
|
|
}
|
|
return lock_state;
|
|
}
|
|
|
|
/**
|
|
* Get or create a global mutex by ID
|
|
*/
|
|
function get_global_mutex(id) {
|
|
let lock_state = global_mutexes.get(id);
|
|
if (!lock_state) {
|
|
lock_state = {
|
|
active: false,
|
|
queue: []
|
|
};
|
|
global_mutexes.set(id, lock_state);
|
|
}
|
|
return lock_state;
|
|
}
|
|
|
|
/**
|
|
* Execute the next queued operation for a mutex
|
|
*/
|
|
function schedule_next(lock_state) {
|
|
if (lock_state.active || lock_state.queue.length === 0) {
|
|
return;
|
|
}
|
|
const {
|
|
fn,
|
|
resolve,
|
|
reject
|
|
} = lock_state.queue.shift();
|
|
lock_state.active = true;
|
|
Promise.resolve().then(fn).then(resolve, reject).finally(() => {
|
|
lock_state.active = false;
|
|
schedule_next(lock_state);
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Acquire a mutex lock and execute callback
|
|
*/
|
|
function acquire_lock(lock_state, fn) {
|
|
return new Promise((resolve, reject) => {
|
|
lock_state.queue.push({
|
|
fn,
|
|
resolve,
|
|
reject
|
|
});
|
|
schedule_next(lock_state);
|
|
});
|
|
}
|
|
|
|
// If called with an ID argument: @mutex('id')
|
|
if (typeof global_id === 'string') {
|
|
return function (target, key, descriptor) {
|
|
const original_method = descriptor.value;
|
|
if (typeof original_method !== 'function') {
|
|
throw new Error(`@mutex can only be applied to methods (tried to apply to ${key})`);
|
|
}
|
|
descriptor.value = function () {
|
|
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
args[_key] = arguments[_key];
|
|
}
|
|
const lock_state = get_global_mutex(global_id);
|
|
return acquire_lock(lock_state, () => original_method.apply(this, args));
|
|
};
|
|
return descriptor;
|
|
};
|
|
}
|
|
|
|
// If called without arguments: @mutex (target is the first argument)
|
|
const target = global_id; // In this case, first arg is target
|
|
const key = arguments[1];
|
|
const descriptor = arguments[2];
|
|
const original_method = descriptor.value;
|
|
if (typeof original_method !== 'function') {
|
|
throw new Error(`@mutex can only be applied to methods (tried to apply to ${key})`);
|
|
}
|
|
descriptor.value = function () {
|
|
for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
|
|
args[_key2] = arguments[_key2];
|
|
}
|
|
const lock_state = get_instance_mutex(this, key);
|
|
return acquire_lock(lock_state, () => original_method.apply(this, args));
|
|
};
|
|
return descriptor;
|
|
}
|
|
|
|
|
|
/* === app/RSpade/Core/Js/async.js (babel) === */
|
|
"use strict";
|
|
|
|
/*
|
|
* Async utility functions for the RSpade framework.
|
|
* These functions handle asynchronous operations, delays, debouncing, and mutexes.
|
|
*/
|
|
|
|
// ============================================================================
|
|
// ASYNC UTILITIES
|
|
// ============================================================================
|
|
|
|
/**
|
|
* Pauses execution for specified milliseconds
|
|
* @param {number} [milliseconds=0] - Delay in milliseconds (0 uses requestAnimationFrame)
|
|
* @returns {Promise<void>} Promise that resolves after delay
|
|
* @example await sleep(1000); // Wait 1 second
|
|
*/
|
|
function sleep() {
|
|
let milliseconds = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;
|
|
return new Promise(resolve => {
|
|
if (milliseconds == 0 && requestAnimationFrame) {
|
|
requestAnimationFrame(resolve);
|
|
} else {
|
|
setTimeout(resolve, milliseconds);
|
|
}
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Creates a debounced function with exclusivity and promise fan-in
|
|
*
|
|
* This function, when invoked, immediately runs the callback exclusively.
|
|
* For subsequent invocations, it applies a delay before running the callback exclusively again.
|
|
* The delay starts after the current asynchronous operation resolves.
|
|
*
|
|
* If 'delay' is set to 0, the function will only prevent enqueueing multiple executions of the
|
|
* same method more than once, but will still run them immediately in an exclusive sequential manner.
|
|
*
|
|
* The most recent invocation of the function will be the parameters that get passed to the function
|
|
* when it invokes.
|
|
*
|
|
* The function returns a promise that resolves when the next exclusive execution completes.
|
|
*
|
|
* Usage as function:
|
|
* const debouncedFn = debounce(myFunction, 250);
|
|
*
|
|
* Usage as decorator:
|
|
* @debounce(250)
|
|
* myMethod() { ... }
|
|
*
|
|
* @param {function|number} callback_or_delay The callback function OR delay when used as decorator
|
|
* @param {number} delay The delay in milliseconds before subsequent invocations
|
|
* @param {boolean} immediate if true, the first time the action is called, the callback executes immediately
|
|
* @returns {function} A function that when invoked, runs the callback immediately and exclusively,
|
|
*
|
|
* @decorator
|
|
*/
|
|
function debounce(callback_or_delay, delay) {
|
|
let immediate = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
|
|
// Decorator usage: @debounce(250) or @debounce(250, true)
|
|
// First argument is a number (the delay), returns decorator function
|
|
if (typeof callback_or_delay === 'number') {
|
|
const decorator_delay = callback_or_delay;
|
|
const decorator_immediate = delay || false;
|
|
|
|
// TC39 decorator form: receives (value, context)
|
|
return function (value, context) {
|
|
if (context.kind === 'method') {
|
|
return debounce_impl(value, decorator_delay, decorator_immediate);
|
|
}
|
|
};
|
|
}
|
|
|
|
// Function usage: debounce(fn, 250)
|
|
// First argument is a function (the callback)
|
|
const callback = callback_or_delay;
|
|
return debounce_impl(callback, delay, immediate);
|
|
}
|
|
|
|
/**
|
|
* Internal implementation of debounce logic
|
|
* @private
|
|
*/
|
|
function debounce_impl(callback, delay) {
|
|
let immediate = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
|
|
let running = false;
|
|
let queued = false;
|
|
let last_end_time = 0; // timestamp of last completed run
|
|
let timer = null;
|
|
let next_args = [];
|
|
let next_context = null;
|
|
let resolve_queue = [];
|
|
let reject_queue = [];
|
|
const run_function = async () => {
|
|
const these_resolves = resolve_queue;
|
|
const these_rejects = reject_queue;
|
|
const args = next_args;
|
|
const context = next_context;
|
|
resolve_queue = [];
|
|
reject_queue = [];
|
|
next_args = [];
|
|
next_context = null;
|
|
queued = false;
|
|
running = true;
|
|
try {
|
|
const result = await callback.apply(context, args);
|
|
for (const resolve of these_resolves) resolve(result);
|
|
} catch (err) {
|
|
for (const reject of these_rejects) reject(err);
|
|
} finally {
|
|
running = false;
|
|
last_end_time = Date.now();
|
|
if (queued) {
|
|
clearTimeout(timer);
|
|
timer = setTimeout(run_function, Math.max(delay, 0));
|
|
} else {
|
|
timer = null;
|
|
}
|
|
}
|
|
};
|
|
return function () {
|
|
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
args[_key] = arguments[_key];
|
|
}
|
|
next_args = args;
|
|
next_context = this;
|
|
return new Promise((resolve, reject) => {
|
|
resolve_queue.push(resolve);
|
|
reject_queue.push(reject);
|
|
|
|
// Nothing running and nothing scheduled
|
|
if (!running && !timer) {
|
|
const first_call = last_end_time === 0;
|
|
if (immediate && first_call) {
|
|
run_function();
|
|
return;
|
|
}
|
|
const since = first_call ? Infinity : Date.now() - last_end_time;
|
|
if (since >= delay) {
|
|
run_function();
|
|
} else {
|
|
const wait = Math.max(delay - since, 0);
|
|
clearTimeout(timer);
|
|
timer = setTimeout(run_function, wait);
|
|
}
|
|
return;
|
|
}
|
|
|
|
// If we're already running or a timer exists, just mark queued.
|
|
// The finally{} of run_function handles scheduling after full delay.
|
|
queued = true;
|
|
});
|
|
};
|
|
}
|
|
|
|
// ============================================================================
|
|
// READ-WRITE LOCK FUNCTIONS - Delegated to ReadWriteLock class
|
|
// ============================================================================
|
|
|
|
/**
|
|
* Acquire an exclusive write lock by name.
|
|
* Only one writer runs at a time; blocks readers until finished.
|
|
* @param {string} name
|
|
* @param {() => any|Promise<any>} cb
|
|
* @returns {Promise<any>}
|
|
*/
|
|
function rwlock(name, cb) {
|
|
return ReadWriteLock.acquire(name, cb);
|
|
}
|
|
|
|
/**
|
|
* Acquire a shared read lock by name.
|
|
* Multiple readers run in parallel, but readers are blocked by queued/active writers.
|
|
* @param {string} name
|
|
* @param {() => any|Promise<any>} cb
|
|
* @returns {Promise<any>}
|
|
*/
|
|
function rwlock_read(name, cb) {
|
|
return ReadWriteLock.acquire_read(name, cb);
|
|
}
|
|
|
|
/**
|
|
* Forcefully clear all locks and queues for a given name.
|
|
* @param {string} name
|
|
*/
|
|
function rwlock_force_unlock(name) {
|
|
ReadWriteLock.force_unlock(name);
|
|
}
|
|
|
|
/**
|
|
* Inspect lock state for debugging.
|
|
* @param {string} name
|
|
* @returns {{readers:number, writer_active:boolean, reader_q:number, writer_q:number}}
|
|
*/
|
|
function rwlock_pending(name) {
|
|
return ReadWriteLock.pending(name);
|
|
}
|
|
|
|
|
|
/* === app/RSpade/Core/Js/functions.js (babel) === */
|
|
"use strict";
|
|
|
|
/*
|
|
* Core utility functions for the RSpade framework.
|
|
* These functions handle type checking, type conversion, string manipulation,
|
|
* and object/array utilities. They mirror functionality from PHP functions.
|
|
*
|
|
* Other utility functions are organized in:
|
|
* - async.js: Async utilities (sleep, debounce, mutex)
|
|
* - browser.js: Browser/DOM utilities (is_mobile, scroll functions)
|
|
* - datetime.js: Date/time utilities
|
|
* - hash.js: Hashing and comparison
|
|
* - error.js: Error handling
|
|
*/
|
|
|
|
// Todo: test that prod build identifies and removes uncalled functions from the final bundle.
|
|
|
|
// ============================================================================
|
|
// CONSTANTS AND HELPERS
|
|
// ============================================================================
|
|
|
|
// Define commonly used constants
|
|
const undef = 'undefined';
|
|
|
|
/**
|
|
* Iterates over arrays or objects with promise support
|
|
*
|
|
* Works with both synchronous and asynchronous callbacks. If the callback
|
|
* returns promises, they are executed in parallel and this function returns
|
|
* a promise that resolves when all parallel tasks complete.
|
|
*
|
|
* @param {Array|Object} obj - Collection to iterate
|
|
* @param {Function} callback - Function to call for each item (value, key) - can be async
|
|
* @returns {Promise|undefined} Promise if any callbacks return promises, undefined otherwise
|
|
*
|
|
* @example
|
|
* // Synchronous usage
|
|
* foreach([1,2,3], (val) => console.log(val));
|
|
*
|
|
* @example
|
|
* // Asynchronous usage - waits for all to complete
|
|
* await foreach([1,2,3], async (val) => {
|
|
* await fetch('/api/process/' + val);
|
|
* });
|
|
*/
|
|
function foreach(obj, callback) {
|
|
const results = [];
|
|
if (Array.isArray(obj)) {
|
|
obj.forEach((value, index) => {
|
|
results.push(callback(value, index));
|
|
});
|
|
} else if (obj && typeof obj === 'object') {
|
|
for (let key in obj) {
|
|
if (obj.hasOwnProperty(key)) {
|
|
results.push(callback(obj[key], key));
|
|
}
|
|
}
|
|
}
|
|
|
|
// Filter for promises
|
|
const promises = results.filter(result => result && typeof result.then === 'function');
|
|
|
|
// If there are any promises, return Promise.all to wait for all to complete
|
|
if (promises.length > 0) {
|
|
return Promise.all(promises);
|
|
}
|
|
|
|
// No promises returned, so we're done
|
|
return undefined;
|
|
}
|
|
|
|
// ============================================================================
|
|
// TYPE CHECKING FUNCTIONS
|
|
// ============================================================================
|
|
|
|
/**
|
|
* Checks if a value is numeric
|
|
* @param {*} n - Value to check
|
|
* @returns {boolean} True if the value is a finite number
|
|
*/
|
|
function is_numeric(n) {
|
|
return !isNaN(parseFloat(n)) && isFinite(n);
|
|
}
|
|
|
|
/**
|
|
* Checks if a value is a string
|
|
* @param {*} s - Value to check
|
|
* @returns {boolean} True if the value is a string
|
|
*/
|
|
function is_string(s) {
|
|
return typeof s == 'string';
|
|
}
|
|
|
|
/**
|
|
* Checks if a value is an integer
|
|
* @param {*} n - Value to check
|
|
* @returns {boolean} True if the value is an integer
|
|
*/
|
|
function is_integer(n) {
|
|
return Number.isInteger(n);
|
|
}
|
|
|
|
/**
|
|
* Checks if a value is a promise-like object
|
|
* @param {*} obj - Value to check
|
|
* @returns {boolean} True if the value has a then method
|
|
*/
|
|
function is_promise(obj) {
|
|
return typeof obj == 'object' && typeof obj.then == 'function';
|
|
}
|
|
|
|
/**
|
|
* Checks if a value is an array
|
|
* @param {*} obj - Value to check
|
|
* @returns {boolean} True if the value is an array
|
|
*/
|
|
function is_array(obj) {
|
|
return Array.isArray(obj);
|
|
}
|
|
|
|
/**
|
|
* Checks if a value is an object (excludes null)
|
|
* @param {*} obj - Value to check
|
|
* @returns {boolean} True if the value is an object and not null
|
|
*/
|
|
function is_object(obj) {
|
|
return typeof obj === 'object' && obj !== null;
|
|
}
|
|
|
|
/**
|
|
* Checks if a value is a function
|
|
* @param {*} function_to_check - Value to check
|
|
* @returns {boolean} True if the value is a function
|
|
*/
|
|
function is_function(function_to_check) {
|
|
return function_to_check && {}.toString.call(function_to_check) === '[object Function]';
|
|
}
|
|
|
|
/**
|
|
* Checks if a string is a valid email address
|
|
* Uses a practical RFC 5322 compliant regex that matches 99.99% of real-world email addresses
|
|
* @param {string} email - Email address to validate
|
|
* @returns {boolean} True if the string is a valid email address
|
|
*/
|
|
function is_email(email) {
|
|
if (!is_string(email)) {
|
|
return false;
|
|
}
|
|
const regex = /^[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/i;
|
|
return regex.test(email);
|
|
}
|
|
|
|
/**
|
|
* Checks if a value is defined (not undefined)
|
|
* @param {*} value - Value to check
|
|
* @returns {boolean} True if value is not undefined
|
|
*/
|
|
function isset(value) {
|
|
return typeof value != undef;
|
|
}
|
|
|
|
/**
|
|
* Checks if a value is empty (null, undefined, 0, "", empty array/object)
|
|
* @param {*} object - Value to check
|
|
* @returns {boolean} True if the value is considered empty
|
|
*/
|
|
function empty(object) {
|
|
if (typeof object == undef) {
|
|
return true;
|
|
}
|
|
if (object === null) {
|
|
return true;
|
|
}
|
|
if (typeof object == 'string' && object == '') {
|
|
return true;
|
|
}
|
|
if (typeof object == 'number') {
|
|
return object == 0;
|
|
}
|
|
if (Array.isArray(object)) {
|
|
return !object.length;
|
|
}
|
|
if (typeof object == 'function') {
|
|
return false;
|
|
}
|
|
for (let key in object) {
|
|
if (object.hasOwnProperty(key)) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
// ============================================================================
|
|
// TYPE CONVERSION FUNCTIONS
|
|
// ============================================================================
|
|
|
|
/**
|
|
* Converts a value to a floating point number
|
|
* Returns 0 for null, undefined, NaN, or non-numeric values
|
|
* @param {*} val - Value to convert
|
|
* @returns {number} Floating point number
|
|
*/
|
|
function float(val) {
|
|
// Handle null, undefined, empty string
|
|
if (val === null || val === undefined || val === '') {
|
|
return 0.0;
|
|
}
|
|
|
|
// Try to parse the value
|
|
const parsed = parseFloat(val);
|
|
|
|
// Check for NaN and return 0 if parsing failed
|
|
return isNaN(parsed) ? 0.0 : parsed;
|
|
}
|
|
|
|
/**
|
|
* Converts a value to an integer
|
|
* Returns 0 for null, undefined, NaN, or non-numeric values
|
|
* @param {*} val - Value to convert
|
|
* @returns {number} Integer value
|
|
*/
|
|
function int(val) {
|
|
// Handle null, undefined, empty string
|
|
if (val === null || val === undefined || val === '') {
|
|
return 0;
|
|
}
|
|
|
|
// Try to parse the value
|
|
const parsed = parseInt(val, 10);
|
|
|
|
// Check for NaN and return 0 if parsing failed
|
|
return isNaN(parsed) ? 0 : parsed;
|
|
}
|
|
|
|
/**
|
|
* Converts a value to a string
|
|
* Returns empty string for null or undefined
|
|
* @param {*} val - Value to convert
|
|
* @returns {string} String representation
|
|
*/
|
|
function str(val) {
|
|
// Handle null and undefined specially
|
|
if (val === null || val === undefined) {
|
|
return '';
|
|
}
|
|
|
|
// Convert to string
|
|
return String(val);
|
|
}
|
|
|
|
/**
|
|
* Converts numeric strings to numbers, returns all other values unchanged
|
|
* Used when you need to ensure numeric types but don't want to force
|
|
* conversion of non-numeric values (which would become 0)
|
|
* @param {*} val - Value to convert
|
|
* @returns {*} Number if input was numeric string, otherwise unchanged
|
|
*/
|
|
function value_unless_numeric_string_then_numeric_value(val) {
|
|
// If it's already a number, return it
|
|
if (typeof val === 'number') {
|
|
return val;
|
|
}
|
|
|
|
// If it's a string and numeric, convert it
|
|
if (is_string(val) && is_numeric(val)) {
|
|
// Use parseFloat to handle both integers and floats
|
|
return parseFloat(val);
|
|
}
|
|
|
|
// Return everything else unchanged (null, objects, non-numeric strings, etc.)
|
|
return val;
|
|
}
|
|
|
|
// ============================================================================
|
|
// STRING MANIPULATION FUNCTIONS
|
|
// ============================================================================
|
|
|
|
/**
|
|
* Escapes HTML special characters (uses Lodash escape)
|
|
* @param {string} str - String to escape
|
|
* @returns {string} HTML-escaped string
|
|
*/
|
|
function html(str) {
|
|
return _.escape(str);
|
|
}
|
|
|
|
/**
|
|
* Converts newlines to HTML line breaks
|
|
* @param {string} str - String to convert
|
|
* @returns {string} String with newlines replaced by <br />
|
|
*/
|
|
function nl2br(str) {
|
|
if (typeof str === undef || str === null) {
|
|
return '';
|
|
}
|
|
return (str + '').replace(/([^>\r\n]?)(\r\n|\n\r|\r|\n)/g, '$1<br />$2');
|
|
}
|
|
|
|
/**
|
|
* Escapes HTML and converts newlines to <br />
|
|
* @param {string} str - String to process
|
|
* @returns {string} HTML-escaped string with line breaks
|
|
*/
|
|
function htmlbr(str) {
|
|
return nl2br(html(str));
|
|
}
|
|
|
|
/**
|
|
* URL-encodes a string
|
|
* @param {string} str - String to encode
|
|
* @returns {string} URL-encoded string
|
|
*/
|
|
function urlencode(str) {
|
|
return encodeURIComponent(str);
|
|
}
|
|
|
|
/**
|
|
* URL-decodes a string
|
|
* @param {string} str - String to decode
|
|
* @returns {string} URL-decoded string
|
|
*/
|
|
function urldecode(str) {
|
|
return decodeURIComponent(str);
|
|
}
|
|
|
|
/**
|
|
* JSON-encodes a value
|
|
* @param {*} value - Value to encode
|
|
* @returns {string} JSON string
|
|
*/
|
|
function json_encode(value) {
|
|
return JSON.stringify(value);
|
|
}
|
|
|
|
/**
|
|
* JSON-decodes a string
|
|
* @param {string} str - JSON string to decode
|
|
* @returns {*} Decoded value
|
|
*/
|
|
function json_decode(str) {
|
|
return JSON.parse(str);
|
|
}
|
|
|
|
/**
|
|
* Console debug output with channel filtering
|
|
* Alias for Debugger.console_debug
|
|
* @param {string} channel - Debug channel name
|
|
* @param {...*} values - Values to log
|
|
*/
|
|
function console_debug(channel) {
|
|
for (var _len = arguments.length, values = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
|
|
values[_key - 1] = arguments[_key];
|
|
}
|
|
Debugger.console_debug(channel, ...values);
|
|
}
|
|
|
|
/**
|
|
* Replaces all occurrences of a substring in a string
|
|
* @param {string} string - String to search in
|
|
* @param {string} search - Substring to find
|
|
* @param {string} replace - Replacement substring
|
|
* @returns {string} String with all occurrences replaced
|
|
*/
|
|
function replace_all(string, search, replace) {
|
|
if (!is_string(string)) {
|
|
string = string + '';
|
|
}
|
|
return string.split(search).join(replace);
|
|
}
|
|
|
|
/**
|
|
* Capitalizes the first letter of each word
|
|
* @param {string} input - String to capitalize
|
|
* @returns {string} String with first letter of each word capitalized
|
|
*/
|
|
function ucwords(input) {
|
|
return input.split(' ').map(word => word.charAt(0).toUpperCase() + word.slice(1)).join(' ');
|
|
}
|
|
|
|
// ============================================================================
|
|
// OBJECT AND ARRAY UTILITIES
|
|
// ============================================================================
|
|
|
|
/**
|
|
* Counts the number of properties in an object or elements in an array
|
|
* @param {Object|Array} o - Object or array to count
|
|
* @returns {number} Number of own properties/elements
|
|
*/
|
|
function count(o) {
|
|
let c = 0;
|
|
for (const k in o) {
|
|
if (o.hasOwnProperty(k)) {
|
|
++c;
|
|
}
|
|
}
|
|
return c;
|
|
}
|
|
|
|
/**
|
|
* Creates a shallow clone of an object, array, or function
|
|
* @param {*} obj - Value to clone
|
|
* @returns {*} Cloned value
|
|
*/
|
|
function clone(obj) {
|
|
if (typeof Function.prototype.__clone == undef) {
|
|
Function.prototype.__clone = function () {
|
|
//https://stackoverflow.com/questions/1833588/javascript-clone-a-function
|
|
const that = this;
|
|
let temp = function cloned() {
|
|
return that.apply(this, arguments);
|
|
};
|
|
for (let key in this) {
|
|
if (this.hasOwnProperty(key)) {
|
|
temp[key] = this[key];
|
|
}
|
|
}
|
|
return temp;
|
|
};
|
|
}
|
|
if (typeof obj == 'function') {
|
|
return obj.__clone();
|
|
} else if (obj.constructor && obj.constructor == Array) {
|
|
return obj.slice(0);
|
|
} else {
|
|
// https://stackoverflow.com/questions/728360/how-do-i-correctly-clone-a-javascript-object/30042948#30042948
|
|
return Object.assign({}, obj);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Returns the first non-null/undefined value from arguments
|
|
* @param {...*} arguments - Values to check
|
|
* @returns {*} First non-null/undefined value, or null if none found
|
|
*/
|
|
function coalesce() {
|
|
let args = Array.from(arguments);
|
|
let return_val = null;
|
|
args.forEach(function (arg) {
|
|
if (return_val === null && typeof arg != undef && arg !== null) {
|
|
return_val = arg;
|
|
}
|
|
});
|
|
return return_val;
|
|
}
|
|
|
|
/**
|
|
* Converts CSV string to array, trimming each element
|
|
* @param {string} str_csv - CSV string to convert
|
|
* @returns {Array<string>} Array of trimmed values
|
|
* @todo Handle quoted/escaped characters
|
|
*/
|
|
function csv_to_array_trim(str_csv) {
|
|
const parts = str_csv.split(',');
|
|
const ret = [];
|
|
foreach(parts, part => {
|
|
ret.push(part.trim());
|
|
});
|
|
return ret;
|
|
}
|
|
|
|
|
|
/* === rsx/theme/quill/quill_cdn.js (babel) === */
|
|
"use strict";
|
|
|
|
/**
|
|
* Quill Editor - Utility Functions
|
|
*
|
|
* Provides utility functions for working with Quill editor.
|
|
*/
|
|
|
|
/**
|
|
* Ensures Quill is loaded before executing callback
|
|
* @param {Function} callback - Function to call when Quill is ready
|
|
*/
|
|
function quill_ready(callback) {
|
|
if (typeof window.Quill !== 'undefined') {
|
|
callback();
|
|
} else {
|
|
setTimeout(() => quill_ready(callback), 50);
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/app/frontend/clients/edit/save_client.js (babel) === */
|
|
"use strict";
|
|
|
|
/**
|
|
* Save client handler for Form component
|
|
* @param {Object} values - Serialized form values
|
|
* @returns {Promise<Object>} Response {success: bool, errors?: {}, redirect?: string}
|
|
*/
|
|
async function save_client(values) {
|
|
// Check if editing existing client
|
|
const client_id = $('#client-id').val();
|
|
if (client_id) {
|
|
values.id = client_id;
|
|
}
|
|
|
|
// TODO: Collect additional fields not yet in Form component (tags, etc.)
|
|
// For now, just submit the basic fields from the Form component
|
|
|
|
try {
|
|
const response = await Frontend_Clients_Controller.save(values);
|
|
if (response.success) {
|
|
// Redirect to clients list on success
|
|
return {
|
|
success: true,
|
|
redirect: Rsx.Route('Frontend_Clients_Controller', 'index')
|
|
};
|
|
} else {
|
|
// Return validation errors
|
|
return {
|
|
success: false,
|
|
errors: response.errors || {
|
|
_general: response.message || 'An error occurred'
|
|
}
|
|
};
|
|
}
|
|
} catch (error) {
|
|
console.error('Save error:', error);
|
|
return {
|
|
success: false,
|
|
errors: {
|
|
_general: 'An error occurred while saving. Please try again.'
|
|
}
|
|
};
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/app/frontend/contacts/edit/save_contact.js (babel) === */
|
|
"use strict";
|
|
|
|
/**
|
|
* Save contact handler for Form component
|
|
* @param {Object} values - Serialized form values
|
|
* @returns {Promise<Object>} Response {success: bool, errors?: {}, redirect?: string}
|
|
*/
|
|
async function save_contact(values) {
|
|
// Check if editing existing contact
|
|
const contact_id = $('#contact-id').val();
|
|
if (contact_id) {
|
|
values.id = contact_id;
|
|
}
|
|
try {
|
|
const response = await Frontend_Contacts_Controller.save(values);
|
|
if (response.success) {
|
|
// Redirect to contact view or list on success
|
|
return {
|
|
success: true,
|
|
redirect: response.redirect || Rsx.Route('Frontend_Contacts_Controller', 'index')
|
|
};
|
|
} else {
|
|
// Return validation errors
|
|
return {
|
|
success: false,
|
|
errors: response.errors || {
|
|
_general: response.message || 'An error occurred'
|
|
}
|
|
};
|
|
}
|
|
} catch (error) {
|
|
console.error('Save error:', error);
|
|
return {
|
|
success: false,
|
|
errors: {
|
|
_general: 'An error occurred while saving. Please try again.'
|
|
}
|
|
};
|
|
}
|
|
}
|
|
|
|
|
|
/* === app/RSpade/Core/Js/Manifest.js (babel) === */
|
|
"use strict";
|
|
|
|
/**
|
|
* Manifest - JavaScript class registry and metadata system
|
|
*
|
|
* This class maintains a registry of all JavaScript classes in the bundle,
|
|
* tracking their names and inheritance relationships. It provides utilities
|
|
* for working with class hierarchies and calling initialization methods.
|
|
*/
|
|
class Manifest {
|
|
/**
|
|
* Define classes in the manifest (framework internal)
|
|
* @param {Array} items - Array of class definitions [[Class, "ClassName", ParentClass, decorators], ...]
|
|
*/
|
|
static _define(items) {
|
|
// Initialize the classes object if not already defined
|
|
if (typeof Manifest._classes === 'undefined') {
|
|
Manifest._classes = {};
|
|
}
|
|
|
|
// Process each class definition
|
|
items.forEach(item => {
|
|
let class_object = item[0];
|
|
let class_name = item[1];
|
|
let class_extends = item[2] || null;
|
|
let decorators = item[3] || null;
|
|
|
|
// Store the class information (using object to avoid duplicates)
|
|
Manifest._classes[class_name] = {
|
|
class: class_object,
|
|
name: class_name,
|
|
extends: class_extends,
|
|
decorators: decorators // Store compact decorator data
|
|
};
|
|
|
|
// Add metadata to the class object itself
|
|
class_object._name = class_name;
|
|
class_object._extends = class_extends;
|
|
class_object._decorators = decorators;
|
|
});
|
|
|
|
// Build the subclass index after all classes are defined
|
|
Manifest._build_subclass_index();
|
|
}
|
|
|
|
/**
|
|
* Build an index of subclasses for efficient lookups
|
|
* This creates a mapping where each class name points to an array of all its subclasses
|
|
* @private
|
|
*/
|
|
static _build_subclass_index() {
|
|
// Initialize the subclass index
|
|
Manifest._subclass_index = {};
|
|
|
|
// Step through each class and walk up its parent chain
|
|
for (let class_name in Manifest._classes) {
|
|
const classdata = Manifest._classes[class_name];
|
|
let current_class_name = class_name;
|
|
let current_classdata = classdata;
|
|
|
|
// Walk up the parent chain until we reach the root
|
|
while (current_classdata) {
|
|
const extends_name = current_classdata.extends;
|
|
if (extends_name) {
|
|
// Initialize the parent's subclass array if needed
|
|
if (!Manifest._subclass_index[extends_name]) {
|
|
Manifest._subclass_index[extends_name] = [];
|
|
}
|
|
|
|
// Add this class to its parent's subclass list
|
|
if (!Manifest._subclass_index[extends_name].includes(class_name)) {
|
|
Manifest._subclass_index[extends_name].push(class_name);
|
|
}
|
|
|
|
// Move up to the parent's metadata (if it exists in manifest)
|
|
if (Manifest._classes[extends_name]) {
|
|
current_classdata = Manifest._classes[extends_name];
|
|
} else {
|
|
// Parent not in manifest (e.g., native JavaScript class), stop here
|
|
current_classdata = null;
|
|
}
|
|
} else {
|
|
// No parent, we've reached the root
|
|
current_classdata = null;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get all classes that extend a given base class
|
|
* @param {Class|string} base_class - The base class (object or name string) to check for
|
|
* @returns {Array} Array of objects with {class_name, class_object} for classes that extend the base class
|
|
*/
|
|
static get_extending(base_class) {
|
|
if (!Manifest._classes) {
|
|
return [];
|
|
}
|
|
|
|
// Convert string to class object if needed
|
|
let base_class_object = base_class;
|
|
if (typeof base_class === 'string') {
|
|
base_class_object = Manifest.get_class_by_name(base_class);
|
|
if (!base_class_object) {
|
|
throw new Error(`Base class not found: ${base_class}`);
|
|
}
|
|
}
|
|
const classes = [];
|
|
for (let class_name in Manifest._classes) {
|
|
const classdata = Manifest._classes[class_name];
|
|
if (Manifest.js_is_subclass_of(classdata.class, base_class_object)) {
|
|
classes.push({
|
|
class_name: class_name,
|
|
class_object: classdata.class
|
|
});
|
|
}
|
|
}
|
|
|
|
// Sort alphabetically by class name to ensure deterministic behavior and prevent race condition bugs
|
|
classes.sort((a, b) => a.class_name.localeCompare(b.class_name));
|
|
return classes;
|
|
}
|
|
|
|
/**
|
|
* Check if a class is a subclass of another class
|
|
* Matches PHP Manifest::js_is_subclass_of() signature and behavior
|
|
* @param {Class|string} subclass - The child class (object or name) to check
|
|
* @param {Class|string} superclass - The parent class (object or name) to check against
|
|
* @returns {boolean} True if subclass extends superclass (directly or indirectly)
|
|
*/
|
|
static js_is_subclass_of(subclass, superclass) {
|
|
// Convert string names to class objects
|
|
let subclass_object = subclass;
|
|
if (typeof subclass === 'string') {
|
|
subclass_object = Manifest.get_class_by_name(subclass);
|
|
if (!subclass_object) {
|
|
// Can't resolve subclass - return false per spec
|
|
return false;
|
|
}
|
|
}
|
|
let superclass_object = superclass;
|
|
if (typeof superclass === 'string') {
|
|
superclass_object = Manifest.get_class_by_name(superclass);
|
|
if (!superclass_object) {
|
|
// Can't resolve superclass - fail loud per spec
|
|
throw new Error(`Superclass not found in manifest: ${superclass}`);
|
|
}
|
|
}
|
|
|
|
// Classes are not subclasses of themselves
|
|
if (subclass_object === superclass_object) {
|
|
return false;
|
|
}
|
|
|
|
// Walk up the inheritance chain
|
|
let current_class = subclass_object;
|
|
while (current_class) {
|
|
if (current_class === superclass_object) {
|
|
return true;
|
|
}
|
|
// Move up to parent class
|
|
if (current_class._extends) {
|
|
// _extends may be a string or class reference
|
|
if (typeof current_class._extends === 'string') {
|
|
current_class = Manifest.get_class_by_name(current_class._extends);
|
|
} else {
|
|
current_class = current_class._extends;
|
|
}
|
|
} else {
|
|
current_class = null;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Get a class by its name
|
|
* @param {string} class_name - The name of the class
|
|
* @returns {Class|null} The class object or null if not found
|
|
*/
|
|
static get_class_by_name(class_name) {
|
|
if (!Manifest._classes || !Manifest._classes[class_name]) {
|
|
return null;
|
|
}
|
|
return Manifest._classes[class_name].class;
|
|
}
|
|
|
|
/**
|
|
* Get all registered classes
|
|
* @returns {Array} Array of objects with {class_name, class_object, extends}
|
|
*/
|
|
static get_all_classes() {
|
|
if (!Manifest._classes) {
|
|
return [];
|
|
}
|
|
const results = [];
|
|
for (let class_name in Manifest._classes) {
|
|
const classdata = Manifest._classes[class_name];
|
|
results.push({
|
|
class_name: classdata.name,
|
|
class_object: classdata.class,
|
|
extends: classdata.extends
|
|
});
|
|
}
|
|
|
|
// Sort alphabetically by class name to ensure deterministic behavior and prevent race condition bugs
|
|
results.sort((a, b) => a.class_name.localeCompare(b.class_name));
|
|
return results;
|
|
}
|
|
|
|
/**
|
|
* Get the build key from the application configuration
|
|
* @returns {string} The build key or "NOBUILD" if not available
|
|
*/
|
|
static build_key() {
|
|
if (window.rsxapp && window.rsxapp.build_key) {
|
|
return window.rsxapp.build_key;
|
|
}
|
|
return 'NOBUILD';
|
|
}
|
|
|
|
/**
|
|
* Get decorators for a specific class and method
|
|
* @param {string|Class} class_name - The class name or class object
|
|
* @param {string} method_name - The method name
|
|
* @returns {Array|null} Array of decorator objects or null if none found
|
|
*/
|
|
static get_decorators(class_name, method_name) {
|
|
// Convert class object to name if needed
|
|
if (typeof class_name !== 'string') {
|
|
class_name = class_name._name || class_name.name;
|
|
}
|
|
const class_info = Manifest._classes[class_name];
|
|
if (!class_info || !class_info.decorators || !class_info.decorators[method_name]) {
|
|
return null;
|
|
}
|
|
|
|
// Transform compact format to object format
|
|
return Manifest._transform_decorators(class_info.decorators[method_name]);
|
|
}
|
|
|
|
/**
|
|
* Get all methods with decorators for a class
|
|
* @param {string|Class} class_name - The class name or class object
|
|
* @returns {Object} Object with method names as keys and decorator arrays as values
|
|
*/
|
|
static get_all_decorators(class_name) {
|
|
// Convert class object to name if needed
|
|
if (typeof class_name !== 'string') {
|
|
class_name = class_name._name || class_name.name;
|
|
}
|
|
const class_info = Manifest._classes[class_name];
|
|
if (!class_info || !class_info.decorators) {
|
|
return {};
|
|
}
|
|
|
|
// Transform all decorators from compact to object format
|
|
const result = {};
|
|
for (let method_name in class_info.decorators) {
|
|
result[method_name] = Manifest._transform_decorators(class_info.decorators[method_name]);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Transform compact decorator format to object format
|
|
* @param {Array} compact_decorators - Array of [name, [args]] tuples
|
|
* @returns {Array} Array of decorator objects with name and arguments properties
|
|
* @private
|
|
*/
|
|
static _transform_decorators(compact_decorators) {
|
|
if (!Array.isArray(compact_decorators)) {
|
|
return [];
|
|
}
|
|
return compact_decorators.map(decorator => {
|
|
if (Array.isArray(decorator) && decorator.length >= 2) {
|
|
return {
|
|
name: decorator[0],
|
|
arguments: decorator[1] || []
|
|
};
|
|
}
|
|
// Handle malformed decorator data
|
|
return {
|
|
name: 'unknown',
|
|
arguments: []
|
|
};
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Check if a method has a specific decorator
|
|
* @param {string|Class} class_name - The class name or class object
|
|
* @param {string} method_name - The method name
|
|
* @param {string} decorator_name - The decorator name to check for
|
|
* @returns {boolean} True if the method has the decorator
|
|
*/
|
|
static has_decorator(class_name, method_name, decorator_name) {
|
|
const decorators = Manifest.get_decorators(class_name, method_name);
|
|
if (!decorators) {
|
|
return false;
|
|
}
|
|
return decorators.some(d => d.name === decorator_name);
|
|
}
|
|
|
|
/**
|
|
* Get all subclasses of a given class using the pre-built index
|
|
* This is the JavaScript equivalent of PHP's Manifest::js_get_subclasses_of()
|
|
* @param {Class|string} base_class - The base class (object or name string) to get subclasses of
|
|
* @returns {Array<Class>} Array of actual class objects that are subclasses of the base class
|
|
*/
|
|
static js_get_subclasses_of(base_class) {
|
|
// Initialize index if needed
|
|
if (!Manifest._subclass_index) {
|
|
Manifest._build_subclass_index();
|
|
}
|
|
|
|
// Convert class object to name if needed
|
|
let base_class_name = base_class;
|
|
if (typeof base_class !== 'string') {
|
|
base_class_name = base_class._name || base_class.name;
|
|
}
|
|
|
|
// Check if the base class exists
|
|
if (!Manifest._classes[base_class_name]) {
|
|
// Base class not in manifest - return empty array
|
|
return [];
|
|
}
|
|
|
|
// Get subclass names from the index
|
|
const subclass_names = Manifest._subclass_index[base_class_name] || [];
|
|
|
|
// Convert names to actual class objects
|
|
const subclass_objects = [];
|
|
for (let subclass_name of subclass_names) {
|
|
const classdata = Manifest._classes[subclass_name];
|
|
subclass_objects.push(classdata.class);
|
|
}
|
|
|
|
// Sort by class name for deterministic behavior
|
|
subclass_objects.sort((a, b) => {
|
|
const name_a = a._name || a.name;
|
|
const name_b = b._name || b.name;
|
|
return name_a.localeCompare(name_b);
|
|
});
|
|
return subclass_objects;
|
|
}
|
|
}
|
|
|
|
// RSX manifest automatically makes classes global - no manual assignment needed
|
|
|
|
|
|
/* === app/RSpade/Core/Js/Rsx_Behaviors.js (babel) === */
|
|
"use strict";
|
|
|
|
/**
|
|
* Rsx_Behaviors - Core Framework User Experience Enhancements
|
|
*
|
|
* This class provides automatic quality-of-life behaviors that improve the default
|
|
* browser experience for RSX applications. These behaviors are transparent to
|
|
* application developers and run automatically on framework initialization.
|
|
*
|
|
* These behaviors use jQuery event delegation to handle both existing and dynamically
|
|
* added content. They are implemented with low priority to allow application code to
|
|
* override default behaviors when needed.
|
|
*
|
|
* @internal Framework use only - not part of public API
|
|
*/
|
|
class Rsx_Behaviors {
|
|
static _on_framework_core_init() {
|
|
Rsx_Behaviors._init_ignore_invalid_anchor_links();
|
|
Rsx_Behaviors._trim_copied_text();
|
|
}
|
|
|
|
/**
|
|
* - Anchor link handling: Prevents broken "#" links from causing page jumps or URL changes
|
|
* - Ignores "#" (empty hash) to prevent scroll-to-top behavior
|
|
* - Ignores "#placeholder*" links used as route placeholders during development
|
|
* - Validates anchor targets exist before allowing navigation
|
|
* - Preserves normal anchor behavior when targets exist
|
|
*/
|
|
static _init_ignore_invalid_anchor_links() {
|
|
return; // disabled for now - make this into a configurable option
|
|
|
|
// Use event delegation on document to handle all current and future anchor clicks
|
|
// Use mousedown instead of click to run before most application handlers
|
|
$(document).on('mousedown', 'a[href^="#"]', function (e) {
|
|
const $link = $(this);
|
|
const href = $link.attr('href');
|
|
|
|
// Check if another handler has already prevented default
|
|
if (e.isDefaultPrevented()) {
|
|
return;
|
|
}
|
|
|
|
// Allow data-rsx-allow-hash attribute to bypass this behavior
|
|
if ($link.data('rsx-allow-hash')) {
|
|
return;
|
|
}
|
|
|
|
// Handle empty hash - prevent scroll to top
|
|
if (href === '#') {
|
|
e.preventDefault();
|
|
e.stopImmediatePropagation();
|
|
return false;
|
|
}
|
|
|
|
// Handle placeholder links used during development
|
|
if (href.startsWith('#placeholder')) {
|
|
e.preventDefault();
|
|
e.stopImmediatePropagation();
|
|
return false;
|
|
}
|
|
|
|
// For other hash links, check if target exists
|
|
const targetId = href.substring(1);
|
|
if (targetId) {
|
|
// Check for element with matching ID or name attribute
|
|
const targetExists = document.getElementById(targetId) !== null || document.querySelector(`[name="${targetId}"]`) !== null;
|
|
if (!targetExists) {
|
|
// Target doesn't exist - prevent navigation
|
|
e.preventDefault();
|
|
e.stopImmediatePropagation();
|
|
return false;
|
|
}
|
|
// Target exists - allow normal anchor behavior
|
|
}
|
|
});
|
|
}
|
|
|
|
/**
|
|
* - Copy text trimming: Automatically removes leading/trailing whitespace from copied text
|
|
* - Hold Shift to preserve whitespace
|
|
* - Skips trimming in code blocks, textareas, and contenteditable elements
|
|
*/
|
|
static _trim_copied_text() {
|
|
document.addEventListener('copy', function (event) {
|
|
// Don't trim if user is holding Shift (allows copying with whitespace if needed)
|
|
if (event.shiftKey) return;
|
|
let selection = window.getSelection();
|
|
let selected_text = selection.toString();
|
|
|
|
// Don't trim if selection is empty
|
|
if (!selected_text) return;
|
|
|
|
// Don't trim if copying from code blocks, textareas, or content-editable (preserve formatting)
|
|
let container = selection.getRangeAt(0).commonAncestorContainer;
|
|
if (container.nodeType === 3) container = container.parentNode; // Text node to element
|
|
if (container.closest('pre, code, .code-block, textarea, [contenteditable="true"]')) return;
|
|
let trimmed_text = selected_text.trim();
|
|
|
|
// Only modify if there's actually whitespace to trim
|
|
if (trimmed_text !== selected_text && trimmed_text.length > 0) {
|
|
event.preventDefault();
|
|
event.clipboardData.setData('text/plain', trimmed_text);
|
|
console.log('Copy: trimmed whitespace from selection');
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
|
|
/* === app/RSpade/Core/Js/Rsx_Cache.js (babel) === */
|
|
"use strict";
|
|
|
|
// Simple key value cache. Can only store 5000 entries, will reset after 5000 entries.
|
|
|
|
// Todo: keep local cache concept the same, replace global cache concept with the nov 2019 version of
|
|
// session cache. Use a session key & build key to track cache keys so cached values only last until user logs out.
|
|
// review session code to ensure that session key *always* rotates on logout. Make session id a protected value.
|
|
class Rsx_Cache {
|
|
static on_core_define() {
|
|
Core_Cache._caches = {
|
|
global: {},
|
|
instance: {}
|
|
};
|
|
Core_Cache._caches_set = 0;
|
|
}
|
|
|
|
// Alias for get_instance
|
|
static get(key) {
|
|
return Rsx_Cache.get_instance(key);
|
|
}
|
|
|
|
// Returns from the pool of cached data for this 'instance'. An instance
|
|
// in this case is a virtual page load / navigation in the SPA. Call Main.lib.reset() to reset.
|
|
// Returns null on failure
|
|
static get_instance(key) {
|
|
if (Main.debug('no_api_cache')) {
|
|
return null;
|
|
}
|
|
let key_encoded = Rsx_Cache._encodekey(key);
|
|
if (typeof Core_Cache._caches.instance[key_encoded] != undef) {
|
|
return JSON.parse(Core_Cache._caches.instance[key_encoded]);
|
|
}
|
|
return null;
|
|
}
|
|
|
|
// Returns null on failure
|
|
// Returns a cached value from global cache (unique to page load, survives reset())
|
|
static get_global(key) {
|
|
if (Main.debug('no_api_cache')) {
|
|
return null;
|
|
}
|
|
let key_encoded = Rsx_Cache._encodekey(key);
|
|
if (typeof Core_Cache._caches.global[key_encoded] != undef) {
|
|
return JSON.parse(Core_Cache._caches.global[key_encoded]);
|
|
}
|
|
return null;
|
|
}
|
|
|
|
// Sets a value in instance and global cache (not shared between browser tabs)
|
|
static set(key, value) {
|
|
if (Main.debug('no_api_cache')) {
|
|
return;
|
|
}
|
|
if (value === null) {
|
|
return;
|
|
}
|
|
if (value.length > 64 * 1024) {
|
|
Debugger.console_debug('CACHE', 'Warning - not caching large cache entry', key);
|
|
return;
|
|
}
|
|
let key_encoded = Rsx_Cache._encodekey(key);
|
|
Core_Cache._caches.global[key_encoded] = JSON.stringify(value);
|
|
Core_Cache._caches.instance[key_encoded] = JSON.stringify(value);
|
|
|
|
// Debugger.console_debug("CACHE", "Set", key, value);
|
|
|
|
Core_Cache._caches_set++;
|
|
|
|
// Reset cache after 5000 items set
|
|
if (Core_Cache._caches_set > 5000) {
|
|
// Get an accurate count
|
|
Core_Cache._caches_set = count(Core_Cache._caches.global);
|
|
if (Core_Cache._caches_set > 5000) {
|
|
Core_Cache._caches = {
|
|
global: {},
|
|
instance: {}
|
|
};
|
|
Core_Cache._caches_set = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Returns null on failure
|
|
// Returns a cached value from session cache (shared between browser tabs)
|
|
static get_session(key) {
|
|
if (Main.debug('no_api_cache')) {
|
|
return null;
|
|
}
|
|
if (!Rsx_Cache._supportsStorage()) {
|
|
return null;
|
|
}
|
|
let key_encoded = Rsx_Cache._encodekey(key);
|
|
let rs = sessionStorage.getItem(key_encoded);
|
|
if (!empty(rs)) {
|
|
return JSON.parse(rs);
|
|
} else {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
// Sets a value in session cache (shared between browser tabs)
|
|
static set_session(key, value) {
|
|
let _tryagain = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
|
|
if (Main.debug('no_api_cache')) {
|
|
return;
|
|
}
|
|
if (value.length > 64 * 1024) {
|
|
Debugger.console_debug('CACHE', 'Warning - not caching large cache entry', key);
|
|
return;
|
|
}
|
|
if (!Rsx_Cache._supportsStorage()) {
|
|
return null;
|
|
}
|
|
let key_encoded = Rsx_Cache._encodekey(key);
|
|
try {
|
|
sessionStorage.removeItem(key_encoded);
|
|
sessionStorage.setItem(key_encoded, JSON.stringify(value));
|
|
} catch (e) {
|
|
if (Rsx_Cache._isOutOfSpace(e) && sessionStorage.length) {
|
|
sessionStorage.clear();
|
|
if (_tryagain) {
|
|
Core_Cache.set_session(key, value, false);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
static _reset() {
|
|
Core_Cache._caches.instance = {};
|
|
}
|
|
|
|
/**
|
|
* For given key of any type including an object, return a string representing
|
|
* the key that the cached value should be stored as in sessionstorage
|
|
*/
|
|
static _encodekey(key) {
|
|
const prefix = 'cache_';
|
|
|
|
// Session reimplement
|
|
// var prefix = "cache_" + Spa.session().user_id() + "_";
|
|
|
|
if (is_string(key) && key.length < 150 && key.indexOf(' ') == -1) {
|
|
return prefix + Manifest.build_key() + '_' + key;
|
|
} else {
|
|
return prefix + hash([Manifest.build_key(), key]);
|
|
}
|
|
}
|
|
|
|
// Determines if sessionStorage is supported in the browser;
|
|
// result is cached for better performance instead of being run each time.
|
|
// Feature detection is based on how Modernizr does it;
|
|
// it's not straightforward due to FF4 issues.
|
|
// It's not run at parse-time as it takes 200ms in Android.
|
|
// Code from https://github.com/pamelafox/lscache/blob/master/lscache.js, Apache License Pamelafox
|
|
static _supportsStorage() {
|
|
let key = '__cachetest__';
|
|
let value = key;
|
|
if (Rsx_Cache.__supportsStorage !== undefined) {
|
|
return Rsx_Cache.__supportsStorage;
|
|
}
|
|
|
|
// some browsers will throw an error if you try to access local storage (e.g. brave browser)
|
|
// hence check is inside a try/catch
|
|
try {
|
|
if (!sessionStorage) {
|
|
return false;
|
|
}
|
|
} catch (ex) {
|
|
return false;
|
|
}
|
|
try {
|
|
sessionStorage.setItem(key, value);
|
|
sessionStorage.removeItem(key);
|
|
Rsx_Cache.__supportsStorage = true;
|
|
} catch (e) {
|
|
// If we hit the limit, and we don't have an empty sessionStorage then it means we have support
|
|
if (Rsx_Cache._isOutOfSpace(e) && sessionStorage.length) {
|
|
Rsx_Cache.__supportsStorage = true; // just maxed it out and even the set test failed.
|
|
} else {
|
|
Rsx_Cache.__supportsStorage = false;
|
|
}
|
|
}
|
|
return Rsx_Cache.__supportsStorage;
|
|
}
|
|
|
|
// Check to set if the error is us dealing with being out of space
|
|
static _isOutOfSpace(e) {
|
|
return e && (e.name === 'QUOTA_EXCEEDED_ERR' || e.name === 'NS_ERROR_DOM_QUOTA_REACHED' || e.name === 'QuotaExceededError');
|
|
}
|
|
}
|
|
|
|
|
|
/* === app/RSpade/Core/Js/Rsx_Init.js (babel) === */
|
|
"use strict";
|
|
|
|
/**
|
|
* Rsx_Init - Core framework initialization and environment validation
|
|
*/
|
|
class Rsx_Init {
|
|
/**
|
|
* Called via Rsx._rsx_core_boot
|
|
* Initializes the core environment and runs basic sanity checks
|
|
*/
|
|
static _on_framework_core_init() {
|
|
if (!Rsx.is_prod()) {
|
|
Rsx_Init.__environment_checks();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Development environment checks to ensure proper configuration
|
|
*/
|
|
static __environment_checks() {
|
|
// Find all script tags in the DOM
|
|
const scripts = document.getElementsByTagName('script');
|
|
for (let i = 0; i < scripts.length; i++) {
|
|
const script = scripts[i];
|
|
|
|
// Skip inline scripts (no src attribute)
|
|
if (!script.src) {
|
|
continue;
|
|
}
|
|
|
|
// Check if script has defer attribute
|
|
if (!script.defer) {
|
|
const src = script.src || '(inline script)';
|
|
const reason = `All script tags used in an RSpade project must have defer attribute. Found script without defer: ${src}`;
|
|
|
|
// Stop framework boot with reason
|
|
Rsx._rsx_core_boot_stop(reason);
|
|
|
|
// Also log to console for visibility
|
|
console.error(`[RSX BOOT STOPPED] ${reason}`);
|
|
|
|
// Stop checking after first violation
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/* === app/RSpade/Core/Js/Rsx_Js_Model.js (babel) === */
|
|
"use strict";
|
|
|
|
// @FILE-SUBCLASS-01-EXCEPTION
|
|
|
|
/**
|
|
* Base class for JavaScript ORM models
|
|
*
|
|
* Provides core functionality for fetching records from backend PHP models.
|
|
* All model stubs generated by the manifest extend this base class.
|
|
*
|
|
* Example usage:
|
|
* // Fetch single record
|
|
* const user = await User_Model.fetch(123);
|
|
*
|
|
* // Fetch multiple records
|
|
* const users = await User_Model.fetch([1, 2, 3]);
|
|
*
|
|
* // Create instance with data
|
|
* const user = new User_Model({id: 1, name: 'John'});
|
|
*
|
|
* @Instantiatable
|
|
*/
|
|
class Rsx_Js_Model {
|
|
/**
|
|
* Constructor - Initialize model instance with data
|
|
*
|
|
* @param {Object} data - Key-value pairs to populate the model
|
|
*/
|
|
constructor() {
|
|
let data = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
// __MODEL SYSTEM: Enables automatic ORM instantiation when fetching from PHP models.
|
|
// PHP models add "__MODEL": "ClassName" to JSON, JavaScript uses it to create proper instances.
|
|
// This provides typed model objects instead of plain JSON, with methods and type checking.
|
|
|
|
// This constructor filters out the __MODEL marker that was used to identify which class
|
|
// to instantiate, keeping only the actual data properties on the instance.
|
|
const {
|
|
__MODEL,
|
|
...modelData
|
|
} = data;
|
|
Object.assign(this, modelData);
|
|
}
|
|
|
|
/**
|
|
* Fetch record(s) from the backend model
|
|
*
|
|
* This method mirrors the PHP Model::fetch() functionality.
|
|
* The backend model must have a fetch() method with the
|
|
* #[Ajax_Endpoint_Model_Fetch] annotation to be callable.
|
|
*
|
|
* @param {number|Array} id - Single ID or array of IDs to fetch
|
|
* @returns {Promise} - Single model instance, array of instances, or false
|
|
*/
|
|
static async fetch(id) {
|
|
const CurrentClass = this;
|
|
// Get the model class name from the current class
|
|
const modelName = CurrentClass.name;
|
|
const response = await $.ajax({
|
|
url: `/_fetch/${modelName}`,
|
|
method: 'POST',
|
|
data: {
|
|
id: id
|
|
},
|
|
dataType: 'json'
|
|
});
|
|
|
|
// Handle response based on type
|
|
if (response === false) {
|
|
return false;
|
|
}
|
|
|
|
// Use _instantiate_models_recursive to handle ORM instantiation
|
|
// This will automatically detect __MODEL properties and create appropriate instances
|
|
return Rsx_Js_Model._instantiate_models_recursive(response);
|
|
}
|
|
|
|
/**
|
|
* Get the model class name
|
|
* Used internally for API calls
|
|
*
|
|
* @returns {string} The class name
|
|
*/
|
|
static getModelName() {
|
|
const CurrentClass = this;
|
|
return CurrentClass.name;
|
|
}
|
|
|
|
/**
|
|
* Refresh this instance with latest data from server
|
|
*
|
|
* @returns {Promise} Updated instance or false if not found
|
|
*/
|
|
async refresh() {
|
|
const that = this;
|
|
if (!that.id) {
|
|
shouldnt_happen('Cannot refresh model without id property');
|
|
}
|
|
const fresh = await that.constructor.fetch(that.id);
|
|
if (fresh === false) {
|
|
return false;
|
|
}
|
|
|
|
// Update this instance with fresh data
|
|
Object.assign(that, fresh);
|
|
return that;
|
|
}
|
|
|
|
/**
|
|
* Convert model instance to plain object
|
|
* Useful for serialization or sending to APIs
|
|
*
|
|
* @returns {Object} Plain object representation
|
|
*/
|
|
toObject() {
|
|
const that = this;
|
|
const obj = {};
|
|
for (const key in that) {
|
|
if (that.hasOwnProperty(key) && typeof that[key] !== 'function') {
|
|
obj[key] = that[key];
|
|
}
|
|
}
|
|
return obj;
|
|
}
|
|
|
|
/**
|
|
* Convert model instance to JSON string
|
|
*
|
|
* @returns {string} JSON representation
|
|
*/
|
|
toJSON() {
|
|
const that = this;
|
|
return JSON.stringify(that.toObject());
|
|
}
|
|
|
|
/**
|
|
* Recursively instantiate ORM models in response data
|
|
*
|
|
* Looks for objects with __MODEL property and instantiates the appropriate
|
|
* JavaScript model class if it exists in the global scope.
|
|
*
|
|
* @param {*} data - The data to process (can be any type)
|
|
* @returns {*} The data with ORM objects instantiated
|
|
*/
|
|
static _instantiate_models_recursive(data) {
|
|
// __MODEL SYSTEM: Enables automatic ORM instantiation when fetching from PHP models.
|
|
// PHP models add "__MODEL": "ClassName" to JSON, JavaScript uses it to create proper instances.
|
|
// This provides typed model objects instead of plain JSON, with methods and type checking.
|
|
|
|
// This recursive processor scans all API response data looking for __MODEL markers.
|
|
// When found, it attempts to instantiate the appropriate JavaScript model class,
|
|
// converting {__MODEL: "User_Model", id: 1, name: "John"} into new User_Model({...}).
|
|
// Works recursively through arrays and nested objects to handle complex data structures.
|
|
// Handle null/undefined
|
|
if (data === null || data === undefined) {
|
|
return data;
|
|
}
|
|
|
|
// Handle arrays - recursively process each element
|
|
if (Array.isArray(data)) {
|
|
return data.map(item => Rsx_Js_Model._instantiate_models_recursive(item));
|
|
}
|
|
|
|
// Handle objects
|
|
if (typeof data === 'object') {
|
|
// Check if this object has a __MODEL property
|
|
if (data.__MODEL && typeof data.__MODEL === 'string') {
|
|
// Try to find the model class in the global scope
|
|
const ModelClass = window[data.__MODEL];
|
|
|
|
// If the model class exists and extends Rsx_Js_Model, instantiate it
|
|
// Dynamic model resolution requires checking class existence - @JS-DEFENSIVE-01-EXCEPTION
|
|
if (ModelClass && ModelClass.prototype instanceof Rsx_Js_Model) {
|
|
return new ModelClass(data);
|
|
}
|
|
}
|
|
|
|
// Recursively process all object properties
|
|
const result = {};
|
|
for (const key in data) {
|
|
if (data.hasOwnProperty(key)) {
|
|
result[key] = Rsx_Js_Model._instantiate_models_recursive(data[key]);
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
// Return primitive values as-is
|
|
return data;
|
|
}
|
|
}
|
|
|
|
|
|
/* === app/RSpade/Core/Js/Rsx_View_Transitions.js (babel) === */
|
|
"use strict";
|
|
|
|
/**
|
|
* View_Transitions - Smooth page-to-page transitions using View Transitions API
|
|
*
|
|
* Enables cross-document view transitions so the browser doesn't paint the new page
|
|
* until it's ready, creating smooth animations between pages.
|
|
*
|
|
* Falls back gracefully if View Transitions API is not available.
|
|
*/
|
|
class Rsx_View_Transitions {
|
|
/**
|
|
* Called during framework core init phase
|
|
* Checks for View Transitions API support and enables if available
|
|
*/
|
|
static _on_framework_core_init() {
|
|
// Check if View Transitions API is supported
|
|
if (!document.startViewTransition) {
|
|
console_debug('VIEW_TRANSITIONS', 'View Transitions API not supported, skipping');
|
|
return;
|
|
}
|
|
|
|
// Enable cross-document view transitions via CSS
|
|
Rsx_View_Transitions._inject_transition_css();
|
|
}
|
|
|
|
/**
|
|
* Inject CSS to enable cross-document view transitions
|
|
*
|
|
* The @view-transition { navigation: auto; } rule tells the browser to:
|
|
* 1. Capture a snapshot of the current page before navigation
|
|
* 2. Fetch the new page
|
|
* 3. Wait until the new page is fully loaded and painted (document.ready)
|
|
* 4. Animate smoothly between the two states
|
|
*
|
|
* This prevents the white flash during navigation and creates app-like transitions.
|
|
*/
|
|
static _inject_transition_css() {
|
|
const style = document.createElement('style');
|
|
style.textContent = `
|
|
@view-transition {
|
|
navigation: auto;
|
|
}
|
|
|
|
/* Disable animation - instant transition */
|
|
::view-transition-group(*),
|
|
::view-transition-old(*),
|
|
::view-transition-new(*) {
|
|
animation-duration: 0s;
|
|
}
|
|
`;
|
|
document.head.appendChild(style);
|
|
}
|
|
}
|
|
|
|
|
|
/* === app/RSpade/Core/Js/ReadWriteLock.js (babel) === */
|
|
"use strict";
|
|
|
|
var _50ae609e_ReadWriteLock;
|
|
function _50ae609e_assertClassBrand(e, t, n) { if ("function" == typeof e ? e === t : e.has(t)) return arguments.length < 3 ? t : n; throw new TypeError("Private element is not present on this object"); }
|
|
/**
|
|
* ReadWriteLock implementation for RSpade framework
|
|
* Provides exclusive (write) and shared (read) locking mechanisms for asynchronous operations
|
|
*/
|
|
class ReadWriteLock {
|
|
/**
|
|
* Acquire an exclusive mutex lock by name.
|
|
* Only one writer runs at a time; blocks readers until finished.
|
|
* @param {string} name
|
|
* @param {() => any|Promise<any>} cb
|
|
* @returns {Promise<any>}
|
|
*/
|
|
static acquire(name, cb) {
|
|
return new Promise((resolve, reject) => {
|
|
const s = _50ae609e_assertClassBrand(ReadWriteLock, this, _50ae609e_get_lock).call(this, name);
|
|
s.writer_q.push({
|
|
cb,
|
|
resolve,
|
|
reject
|
|
});
|
|
_50ae609e_assertClassBrand(ReadWriteLock, this, _50ae609e_schedule).call(this, name);
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Acquire a shared read lock by name.
|
|
* Multiple readers can run in parallel; blocks when writer is active.
|
|
* @param {string} name
|
|
* @param {() => any|Promise<any>} cb
|
|
* @returns {Promise<any>}
|
|
*/
|
|
static acquire_read(name, cb) {
|
|
return new Promise((resolve, reject) => {
|
|
const s = _50ae609e_assertClassBrand(ReadWriteLock, this, _50ae609e_get_lock).call(this, name);
|
|
if (s.writer_active || s.writer_q.length > 0) {
|
|
s.reader_q.push({
|
|
cb,
|
|
resolve,
|
|
reject
|
|
});
|
|
return _50ae609e_assertClassBrand(ReadWriteLock, this, _50ae609e_schedule).call(this, name);
|
|
}
|
|
s.readers += 1;
|
|
Promise.resolve().then(cb).then(resolve, reject).finally(() => {
|
|
s.readers -= 1;
|
|
if (s.readers === 0) _50ae609e_assertClassBrand(ReadWriteLock, this, _50ae609e_schedule).call(this, name);
|
|
});
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Force-unlock a mutex (use with caution).
|
|
* Completely removes the lock state, potentially breaking waiting operations.
|
|
* @param {string} name
|
|
*/
|
|
static force_unlock(name) {
|
|
_50ae609e_assertClassBrand(ReadWriteLock, this, _locks)._.delete(name);
|
|
}
|
|
|
|
/**
|
|
* Get information about pending operations on a mutex.
|
|
* @param {string} name
|
|
* @returns {{readers: number, writer_active: boolean, reader_q: number, writer_q: number}}
|
|
*/
|
|
static pending(name) {
|
|
const s = _50ae609e_assertClassBrand(ReadWriteLock, this, _locks)._.get(name);
|
|
if (!s) return {
|
|
readers: 0,
|
|
writer_active: false,
|
|
reader_q: 0,
|
|
writer_q: 0
|
|
};
|
|
return {
|
|
readers: s.readers,
|
|
writer_active: s.writer_active,
|
|
reader_q: s.reader_q.length,
|
|
writer_q: s.writer_q.length
|
|
};
|
|
}
|
|
}
|
|
_50ae609e_ReadWriteLock = ReadWriteLock;
|
|
/**
|
|
* Get or create a lock object for a given name
|
|
* @private
|
|
*/
|
|
function _50ae609e_get_lock(name) {
|
|
let s = _50ae609e_assertClassBrand(_50ae609e_ReadWriteLock, this, _locks)._.get(name);
|
|
if (!s) {
|
|
s = {
|
|
readers: 0,
|
|
writer_active: false,
|
|
reader_q: [],
|
|
writer_q: []
|
|
};
|
|
_50ae609e_assertClassBrand(_50ae609e_ReadWriteLock, this, _locks)._.set(name, s);
|
|
}
|
|
return s;
|
|
}
|
|
/**
|
|
* Schedule the next operation for a lock
|
|
* @private
|
|
*/
|
|
function _50ae609e_schedule(name) {
|
|
const s = _50ae609e_assertClassBrand(_50ae609e_ReadWriteLock, this, _50ae609e_get_lock).call(this, name);
|
|
if (s.writer_active || s.readers > 0) return;
|
|
|
|
// run one writer if queued
|
|
if (s.writer_q.length > 0) {
|
|
const {
|
|
cb,
|
|
resolve,
|
|
reject
|
|
} = s.writer_q.shift();
|
|
s.writer_active = true;
|
|
Promise.resolve().then(cb).then(resolve, reject).finally(() => {
|
|
s.writer_active = false;
|
|
_50ae609e_assertClassBrand(_50ae609e_ReadWriteLock, this, _50ae609e_schedule).call(this, name);
|
|
});
|
|
return;
|
|
}
|
|
|
|
// otherwise run all queued readers in parallel
|
|
if (s.reader_q.length > 0) {
|
|
const batch = s.reader_q.splice(0);
|
|
s.readers += batch.length;
|
|
for (const {
|
|
cb,
|
|
resolve,
|
|
reject
|
|
} of batch) {
|
|
Promise.resolve().then(cb).then(resolve, reject).finally(() => {
|
|
s.readers -= 1;
|
|
if (s.readers === 0) _50ae609e_assertClassBrand(_50ae609e_ReadWriteLock, this, _50ae609e_schedule).call(this, name);
|
|
});
|
|
}
|
|
}
|
|
}
|
|
var _locks = {
|
|
_: new Map()
|
|
};
|
|
|
|
|
|
/* === app/RSpade/Core/Js/Form_Utils.js (babel) === */
|
|
"use strict";
|
|
|
|
/**
|
|
* Form utilities for validation and error handling
|
|
*/
|
|
class Form_Utils {
|
|
/**
|
|
* Framework initialization hook to register jQuery plugin
|
|
* Creates $.fn.ajax_submit() for form elements
|
|
* @private
|
|
*/
|
|
static _on_framework_core_define() {
|
|
let params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
$.fn.ajax_submit = function () {
|
|
let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
const $element = $(this);
|
|
if (!$element.is('form')) {
|
|
throw new Error('ajax_submit() can only be called on form elements');
|
|
}
|
|
const url = $element.attr('action');
|
|
if (!url) {
|
|
throw new Error('Form must have an action attribute');
|
|
}
|
|
const {
|
|
controller,
|
|
action
|
|
} = Ajax.ajax_url_to_controller_action(url);
|
|
return Form_Utils.ajax_submit($element, controller, action, options);
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Shows form validation errors
|
|
*
|
|
* REQUIRED HTML STRUCTURE:
|
|
* For inline field errors to display properly, form fields must follow this structure:
|
|
*
|
|
* <div class="form-group">
|
|
* <label class="form-label" for="field-name">Field Label</label>
|
|
* <input class="form-control" id="field-name" name="field-name" type="text">
|
|
* </div>
|
|
*
|
|
* Key requirements:
|
|
* - Wrap each field in a container with class "form-group" (or "form-check" / "input-group")
|
|
* - Input must have a "name" attribute matching the error key
|
|
* - Use "form-control" class on inputs for Bootstrap 5 styling
|
|
*
|
|
* Accepts three formats:
|
|
* - String: Single error shown as alert
|
|
* - Array of strings: Multiple errors shown as bulleted alert
|
|
* - Object: Field names mapped to errors, shown inline (unmatched shown as alert)
|
|
*
|
|
* @param {string} parent_selector - jQuery selector for parent element
|
|
* @param {string|Object|Array} errors - Error messages to display
|
|
* @returns {Promise} Promise that resolves when all animations complete
|
|
*/
|
|
static apply_form_errors(parent_selector, errors) {
|
|
console.error(errors);
|
|
const $parent = $(parent_selector);
|
|
|
|
// Reset the form errors before applying new ones
|
|
Form_Utils.reset_form_errors(parent_selector);
|
|
|
|
// Normalize input to standard format
|
|
const normalized = Form_Utils._normalize_errors(errors);
|
|
return new Promise(resolve => {
|
|
let animations = [];
|
|
if (normalized.type === 'string') {
|
|
// Single error message
|
|
animations = Form_Utils._apply_general_errors($parent, normalized.data);
|
|
} else if (normalized.type === 'array') {
|
|
// Array of error messages
|
|
const deduplicated = Form_Utils._deduplicate_errors(normalized.data);
|
|
animations = Form_Utils._apply_general_errors($parent, deduplicated);
|
|
} else if (normalized.type === 'fields') {
|
|
// Field-specific errors
|
|
const result = Form_Utils._apply_field_errors($parent, normalized.data);
|
|
animations = result.animations;
|
|
|
|
// Count matched fields
|
|
const matched_count = Object.keys(normalized.data).length - Object.keys(result.unmatched).length;
|
|
const unmatched_deduplicated = Form_Utils._deduplicate_errors(result.unmatched);
|
|
const unmatched_count = Object.keys(unmatched_deduplicated).length;
|
|
|
|
// Show summary alert if there are any field errors (matched or unmatched)
|
|
if (matched_count > 0 || unmatched_count > 0) {
|
|
// Build summary message
|
|
let summary_msg = '';
|
|
if (matched_count > 0) {
|
|
summary_msg = matched_count === 1 ? 'Please correct the error highlighted below.' : 'Please correct the errors highlighted below.';
|
|
}
|
|
|
|
// If there are unmatched errors, add them as a bulleted list
|
|
if (unmatched_count > 0) {
|
|
const summary_animations = Form_Utils._apply_combined_error($parent, summary_msg, unmatched_deduplicated);
|
|
animations.push(...summary_animations);
|
|
} else {
|
|
// Just the summary message, no unmatched errors
|
|
const summary_animations = Form_Utils._apply_general_errors($parent, summary_msg);
|
|
animations.push(...summary_animations);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Resolve the promise once all animations are complete
|
|
Promise.all(animations).then(() => {
|
|
// Scroll to error container if it exists
|
|
const $error_container = $parent.find('[data-id="error_container"]').first();
|
|
if ($error_container.length > 0) {
|
|
const container_top = $error_container.offset().top;
|
|
|
|
// Calculate fixed header offset
|
|
const fixed_header_height = Form_Utils._get_fixed_header_height();
|
|
|
|
// Scroll to position error container 20px below any fixed headers
|
|
const target_scroll = container_top - fixed_header_height - 20;
|
|
$('html, body').animate({
|
|
scrollTop: target_scroll
|
|
}, 500);
|
|
}
|
|
resolve();
|
|
});
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Clears form validation errors and resets all form values to defaults
|
|
* @param {string|jQuery} form_selector - jQuery selector or jQuery object for form element
|
|
*/
|
|
static reset(form_selector) {
|
|
const $form = typeof form_selector === 'string' ? $(form_selector) : form_selector;
|
|
Form_Utils.reset_form_errors(form_selector);
|
|
$form.trigger('reset');
|
|
}
|
|
|
|
/**
|
|
* Serializes form data into key-value object
|
|
* Returns all input elements with name attributes as object properties
|
|
* @param {string|jQuery} form_selector - jQuery selector or jQuery object for form element
|
|
* @returns {Object} Form data as key-value pairs
|
|
*/
|
|
static serialize(form_selector) {
|
|
const $form = typeof form_selector === 'string' ? $(form_selector) : form_selector;
|
|
const data = {};
|
|
$form.serializeArray().forEach(item => {
|
|
data[item.name] = item.value;
|
|
});
|
|
return data;
|
|
}
|
|
|
|
/**
|
|
* Submits form to RSX controller action via AJAX
|
|
* @param {string|jQuery} form_selector - jQuery selector or jQuery object for form element
|
|
* @param {string} controller - Controller class name (e.g., 'User_Controller')
|
|
* @param {string} action - Action method name (e.g., 'save_profile')
|
|
* @param {Object} options - Optional configuration {on_success: fn, on_error: fn}
|
|
* @returns {Promise} Promise that resolves with response data
|
|
*/
|
|
static async ajax_submit(form_selector, controller, action) {
|
|
let options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
|
|
const $form = typeof form_selector === 'string' ? $(form_selector) : form_selector;
|
|
const form_data = Form_Utils.serialize($form);
|
|
Form_Utils.reset_form_errors(form_selector);
|
|
try {
|
|
const response = await Ajax.call(controller, action, form_data);
|
|
if (options.on_success) {
|
|
options.on_success(response);
|
|
}
|
|
return response;
|
|
} catch (error) {
|
|
if (error.type === 'form_error' && error.details) {
|
|
await Form_Utils.apply_form_errors(form_selector, error.details);
|
|
} else {
|
|
await Form_Utils.apply_form_errors(form_selector, error.message || 'An error occurred');
|
|
}
|
|
if (options.on_error) {
|
|
options.on_error(error);
|
|
}
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Removes form validation errors
|
|
* @param {string} parent_selector - jQuery selector for parent element
|
|
*/
|
|
static reset_form_errors(parent_selector) {
|
|
const $parent = $(parent_selector);
|
|
|
|
// Remove flash messages
|
|
$('.flash-messages').remove();
|
|
|
|
// Remove alert-danger messages
|
|
$parent.find('.alert-danger').remove();
|
|
|
|
// Remove validation error classes and text from form elements
|
|
$parent.find('.is-invalid').removeClass('is-invalid');
|
|
$parent.find('.invalid-feedback').remove();
|
|
}
|
|
|
|
// ------------------------
|
|
|
|
/**
|
|
* Normalizes error input into standard formats
|
|
* @param {string|Object|Array} errors - Raw error input
|
|
* @returns {Object} Normalized errors as {type: 'string'|'array'|'fields', data: ...}
|
|
* @private
|
|
*/
|
|
static _normalize_errors(errors) {
|
|
// Handle null/undefined
|
|
if (!errors) {
|
|
return {
|
|
type: 'string',
|
|
data: 'An error has occurred'
|
|
};
|
|
}
|
|
|
|
// Handle string
|
|
if (typeof errors === 'string') {
|
|
return {
|
|
type: 'string',
|
|
data: errors
|
|
};
|
|
}
|
|
|
|
// Handle array
|
|
if (Array.isArray(errors)) {
|
|
// Array of strings - general errors
|
|
if (errors.every(e => typeof e === 'string')) {
|
|
return {
|
|
type: 'array',
|
|
data: errors
|
|
};
|
|
}
|
|
// Array with object as first element - extract it
|
|
if (errors.length > 0 && typeof errors[0] === 'object') {
|
|
return Form_Utils._normalize_errors(errors[0]);
|
|
}
|
|
// Empty or mixed array
|
|
return {
|
|
type: 'array',
|
|
data: []
|
|
};
|
|
}
|
|
|
|
// Handle object - check for Laravel response wrapper
|
|
if (typeof errors === 'object') {
|
|
// Unwrap {errors: {...}} or {error: {...}}
|
|
const unwrapped = errors.errors || errors.error;
|
|
if (unwrapped) {
|
|
return Form_Utils._normalize_errors(unwrapped);
|
|
}
|
|
|
|
// Convert Laravel validator format {field: [msg1, msg2]} to {field: msg1}
|
|
const normalized = {};
|
|
for (const field in errors) {
|
|
if (errors.hasOwnProperty(field)) {
|
|
const value = errors[field];
|
|
if (Array.isArray(value) && value.length > 0) {
|
|
normalized[field] = value[0];
|
|
} else if (typeof value === 'string') {
|
|
normalized[field] = value;
|
|
} else {
|
|
normalized[field] = String(value);
|
|
}
|
|
}
|
|
}
|
|
return {
|
|
type: 'fields',
|
|
data: normalized
|
|
};
|
|
}
|
|
|
|
// Final catch-all*
|
|
return {
|
|
type: 'string',
|
|
data: String(errors)
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Removes duplicate error messages from array or object values
|
|
* @param {Array|Object} errors - Errors to deduplicate
|
|
* @returns {Array|Object} Deduplicated errors
|
|
* @private
|
|
*/
|
|
static _deduplicate_errors(errors) {
|
|
if (Array.isArray(errors)) {
|
|
return [...new Set(errors)];
|
|
}
|
|
if (typeof errors === 'object') {
|
|
const seen = new Set();
|
|
const result = {};
|
|
for (const key in errors) {
|
|
const value = errors[key];
|
|
if (!seen.has(value)) {
|
|
seen.add(value);
|
|
result[key] = value;
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
return errors;
|
|
}
|
|
|
|
/**
|
|
* Applies field-specific validation errors to form inputs
|
|
* @param {jQuery} $parent - Parent element containing form
|
|
* @param {Object} field_errors - Object mapping field names to error messages
|
|
* @returns {Object} Object containing {animations: Array, unmatched: Object}
|
|
* @private
|
|
*/
|
|
static _apply_field_errors($parent, field_errors) {
|
|
const animations = [];
|
|
const unmatched = {};
|
|
for (const field_name in field_errors) {
|
|
const error_message = field_errors[field_name];
|
|
const $input = $parent.find(`[name="${field_name}"]`);
|
|
if (!$input.length) {
|
|
unmatched[field_name] = error_message;
|
|
continue;
|
|
}
|
|
const $error = $('<div class="invalid-feedback"></div>').html(error_message);
|
|
const $target = $input.closest('.form-group, .form-check, .input-group');
|
|
if (!$target.length) {
|
|
unmatched[field_name] = error_message;
|
|
continue;
|
|
}
|
|
$input.addClass('is-invalid');
|
|
$error.appendTo($target);
|
|
animations.push($error.hide().fadeIn(300).promise());
|
|
}
|
|
return {
|
|
animations,
|
|
unmatched
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Applies combined error message with summary and unmatched field errors
|
|
* @param {jQuery} $parent - Parent element containing form
|
|
* @param {string} summary_msg - Summary message (e.g., "Please correct the errors below")
|
|
* @param {Object} unmatched_errors - Object of field errors that couldn't be matched to fields
|
|
* @returns {Array} Array of animation promises
|
|
* @private
|
|
*/
|
|
static _apply_combined_error($parent, summary_msg, unmatched_errors) {
|
|
const animations = [];
|
|
const $error_container = $parent.find('[data-id="error_container"]').first();
|
|
const $target = $error_container.length > 0 ? $error_container : $parent;
|
|
|
|
// Create alert with summary message and bulleted list of unmatched errors
|
|
const $alert = $('<div class="alert alert-danger" role="alert"></div>');
|
|
|
|
// Add summary message if provided
|
|
if (summary_msg) {
|
|
$('<p class="mb-2"></p>').text(summary_msg).appendTo($alert);
|
|
}
|
|
|
|
// Add unmatched errors as bulleted list
|
|
if (Object.keys(unmatched_errors).length > 0) {
|
|
const $list = $('<ul class="mb-0"></ul>');
|
|
for (const field_name in unmatched_errors) {
|
|
const error_msg = unmatched_errors[field_name];
|
|
$('<li></li>').html(error_msg).appendTo($list);
|
|
}
|
|
$list.appendTo($alert);
|
|
}
|
|
if ($error_container.length > 0) {
|
|
animations.push($alert.hide().appendTo($target).fadeIn(300).promise());
|
|
} else {
|
|
animations.push($alert.hide().prependTo($target).fadeIn(300).promise());
|
|
}
|
|
return animations;
|
|
}
|
|
|
|
/**
|
|
* Applies general error messages as alert box
|
|
* @param {jQuery} $parent - Parent element to prepend alert to
|
|
* @param {string|Array} messages - Error message(s) to display
|
|
* @returns {Array} Array of animation promises
|
|
* @private
|
|
*/
|
|
static _apply_general_errors($parent, messages) {
|
|
const animations = [];
|
|
|
|
// Look for a specific error container div (e.g., in Rsx_Form component)
|
|
const $error_container = $parent.find('[data-id="error_container"]').first();
|
|
const $target = $error_container.length > 0 ? $error_container : $parent;
|
|
if (typeof messages === 'string') {
|
|
// Single error - simple alert without list
|
|
const $alert = $('<div class="alert alert-danger" role="alert"></div>').text(messages);
|
|
if ($error_container.length > 0) {
|
|
animations.push($alert.hide().appendTo($target).fadeIn(300).promise());
|
|
} else {
|
|
animations.push($alert.hide().prependTo($target).fadeIn(300).promise());
|
|
}
|
|
} else if (Array.isArray(messages) && messages.length > 0) {
|
|
// Multiple errors - bulleted list
|
|
const $alert = $('<div class="alert alert-danger" role="alert"><ul class="mb-0"></ul></div>');
|
|
const $list = $alert.find('ul');
|
|
messages.forEach(msg => {
|
|
const text = (msg + '').trim() || 'An error has occurred';
|
|
$('<li></li>').html(text).appendTo($list);
|
|
});
|
|
if ($error_container.length > 0) {
|
|
animations.push($alert.hide().appendTo($target).fadeIn(300).promise());
|
|
} else {
|
|
animations.push($alert.hide().prependTo($target).fadeIn(300).promise());
|
|
}
|
|
} else if (typeof messages === 'object' && !Array.isArray(messages)) {
|
|
// Object of unmatched field errors - convert to array
|
|
const error_list = Object.values(messages).map(v => String(v).trim()).filter(v => v);
|
|
if (error_list.length > 0) {
|
|
return Form_Utils._apply_general_errors($parent, error_list);
|
|
}
|
|
}
|
|
return animations;
|
|
}
|
|
|
|
/**
|
|
* Calculates the total height of fixed/sticky headers at the top of the page
|
|
* @returns {number} Total height in pixels of fixed top elements
|
|
* @private
|
|
*/
|
|
static _get_fixed_header_height() {
|
|
let total_height = 0;
|
|
|
|
// Find all fixed or sticky positioned elements
|
|
$('*').each(function () {
|
|
const $el = $(this);
|
|
const position = $el.css('position');
|
|
|
|
// Only check fixed or sticky elements
|
|
if (position !== 'fixed' && position !== 'sticky') {
|
|
return;
|
|
}
|
|
|
|
// Check if element is positioned at or near the top
|
|
const top = parseInt($el.css('top')) || 0;
|
|
if (top > 50) {
|
|
return; // Not a top header
|
|
}
|
|
|
|
// Check if element is visible
|
|
if (!$el.is(':visible')) {
|
|
return;
|
|
}
|
|
|
|
// Check if element spans significant width (likely a header/navbar)
|
|
const width = $el.outerWidth();
|
|
const viewport_width = $(window).width();
|
|
if (width < viewport_width * 0.5) {
|
|
return; // Too narrow to be a header
|
|
}
|
|
|
|
// Add this element's height
|
|
total_height += $el.outerHeight();
|
|
});
|
|
return total_height;
|
|
}
|
|
}
|
|
|
|
|
|
/* === app/RSpade/Core/Js/Debugger.js (babel) === */
|
|
"use strict";
|
|
|
|
function _27e0e986_defineProperty(e, r, t) { return (r = _27e0e986_toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
|
|
function _27e0e986_toPropertyKey(t) { var i = _27e0e986_toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
|
|
function _27e0e986_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); }
|
|
/**
|
|
* Debugger class for console_debug and browser error logging
|
|
* Handles batched submission to server when configured
|
|
*/
|
|
class Debugger {
|
|
/**
|
|
* Initialize framework error handling
|
|
* Called during framework initialization
|
|
*/
|
|
static _on_framework_core_init() {
|
|
// Check if browser error logging is enabled
|
|
if (window.rsxapp && window.rsxapp.log_browser_errors) {
|
|
// Register global error handler
|
|
window.addEventListener('error', function (event) {
|
|
Debugger._handle_browser_error({
|
|
message: event.message,
|
|
filename: event.filename,
|
|
lineno: event.lineno,
|
|
colno: event.colno,
|
|
stack: event.error ? event.error.stack : null,
|
|
type: 'error'
|
|
});
|
|
});
|
|
|
|
// Register unhandled promise rejection handler
|
|
window.addEventListener('unhandledrejection', function (event) {
|
|
Debugger._handle_browser_error({
|
|
message: event.reason ? event.reason.message || String(event.reason) : 'Unhandled promise rejection',
|
|
stack: event.reason && event.reason.stack ? event.reason.stack : null,
|
|
type: 'unhandledrejection'
|
|
});
|
|
});
|
|
}
|
|
|
|
// Register ui refresh handler
|
|
Rsx.on('refresh', Debugger.on_refresh);
|
|
}
|
|
|
|
// In dev mode, some ui elements can be automatically applied to assist with development
|
|
static on_refresh() {
|
|
if (!Rsx.is_prod()) {
|
|
// Add an underline 2 px blue to all a tags with href === "#" using jquery
|
|
// Todo: maybe this should be a configurable debug option?
|
|
// $('a[href="#"]').css({
|
|
// 'border-bottom': '2px solid blue',
|
|
// 'text-decoration': 'none'
|
|
// });
|
|
}
|
|
}
|
|
|
|
/**
|
|
* JavaScript implementation of console_debug
|
|
* Mirrors PHP functionality with batching for Laravel log
|
|
*/
|
|
static console_debug(channel) {
|
|
// Check if console_debug is enabled
|
|
if (!window.rsxapp || !window.rsxapp.console_debug || !window.rsxapp.console_debug.enabled) {
|
|
return;
|
|
}
|
|
const config = window.rsxapp.console_debug;
|
|
|
|
// Normalize channel name
|
|
channel = String(channel).toUpperCase().replace(/[\[\]]/g, '');
|
|
|
|
// Apply filtering
|
|
if (config.filter_mode === 'specific') {
|
|
const specific = config.specific_channel;
|
|
if (specific) {
|
|
// Split comma-separated values and normalize
|
|
const channels = specific.split(',').map(c => c.trim().toUpperCase());
|
|
if (!channels.includes(channel)) {
|
|
return;
|
|
}
|
|
}
|
|
} else if (config.filter_mode === 'whitelist') {
|
|
const whitelist = (config.filter_channels || []).map(c => c.toUpperCase());
|
|
if (!whitelist.includes(channel)) {
|
|
return;
|
|
}
|
|
} else if (config.filter_mode === 'blacklist') {
|
|
const blacklist = (config.filter_channels || []).map(c => c.toUpperCase());
|
|
if (blacklist.includes(channel)) {
|
|
return;
|
|
}
|
|
}
|
|
|
|
// Prepare the message
|
|
for (var _len = arguments.length, values = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
|
|
values[_key - 1] = arguments[_key];
|
|
}
|
|
let message = {
|
|
channel: channel,
|
|
values: values,
|
|
timestamp: new Date().toISOString()
|
|
};
|
|
|
|
// Add location if configured
|
|
if (config.include_location || config.include_backtrace) {
|
|
const error = new Error();
|
|
const stack = error.stack || '';
|
|
const stackLines = stack.split('\n');
|
|
if (config.include_location && stackLines.length > 2) {
|
|
// Skip Error line and this function
|
|
const callerLine = stackLines[2] || '';
|
|
const match = callerLine.match(/at\s+.*?\s+\((.*?):(\d+):(\d+)\)/) || callerLine.match(/at\s+(.*?):(\d+):(\d+)/);
|
|
if (match) {
|
|
message.location = `${match[1]}:${match[2]}`;
|
|
}
|
|
}
|
|
if (config.include_backtrace) {
|
|
// Include first 5 stack frames, skipping this function
|
|
message.backtrace = stackLines.slice(2, 7).map(line => line.trim()).filter(line => line);
|
|
}
|
|
}
|
|
|
|
// Output to browser console if enabled
|
|
if (config.outputs && config.outputs.browser) {
|
|
const prefix = config.include_benchmark ? `[${Debugger._get_time_prefix()}] ` : '';
|
|
const channelPrefix = `[${channel}]`;
|
|
|
|
// Use appropriate console method based on channel
|
|
let consoleMethod = 'log';
|
|
if (channel.includes('ERROR')) consoleMethod = 'error';else if (channel.includes('WARN')) consoleMethod = 'warn';else if (channel.includes('INFO')) consoleMethod = 'info';
|
|
console[consoleMethod](prefix + channelPrefix, ...values);
|
|
}
|
|
|
|
// Batch for Laravel log if enabled
|
|
if (config.outputs && config.outputs.laravel_log) {
|
|
Debugger._batch_console_message(message);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Log an error to the server
|
|
* Used manually or by Ajax error handling
|
|
*/
|
|
static log_error(error) {
|
|
// Check if browser error logging is enabled
|
|
if (!window.rsxapp || !window.rsxapp.log_browser_errors) {
|
|
return;
|
|
}
|
|
|
|
// Normalize error format
|
|
let errorData = {};
|
|
if (typeof error === 'string') {
|
|
errorData.message = error;
|
|
errorData.type = 'manual';
|
|
} else if (error instanceof Error) {
|
|
errorData.message = error.message;
|
|
errorData.stack = error.stack;
|
|
errorData.type = 'exception';
|
|
} else if (error && typeof error === 'object') {
|
|
errorData = error;
|
|
if (!errorData.type) {
|
|
errorData.type = 'manual';
|
|
}
|
|
}
|
|
Debugger._handle_browser_error(errorData);
|
|
}
|
|
|
|
/**
|
|
* Internal: Handle browser errors with batching
|
|
*/
|
|
static _handle_browser_error(errorData) {
|
|
// Check limits
|
|
if (Debugger._error_count >= Debugger.MAX_ERRORS_PER_PAGE) {
|
|
return;
|
|
}
|
|
if (Debugger._error_batch_count >= Debugger.MAX_ERROR_BATCHES) {
|
|
return;
|
|
}
|
|
Debugger._error_count++;
|
|
|
|
// Add metadata
|
|
errorData.url = window.location.href;
|
|
errorData.userAgent = navigator.userAgent;
|
|
errorData.timestamp = new Date().toISOString();
|
|
|
|
// Add to batch
|
|
Debugger._error_batch.push(errorData);
|
|
|
|
// Clear existing timer
|
|
if (Debugger._error_timer) {
|
|
clearTimeout(Debugger._error_timer);
|
|
}
|
|
|
|
// Set debounce timer
|
|
Debugger._error_timer = setTimeout(() => {
|
|
Debugger._flush_error_batch();
|
|
}, Debugger.DEBOUNCE_MS);
|
|
}
|
|
|
|
/**
|
|
* Internal: Batch console_debug messages for Laravel log
|
|
*/
|
|
static _batch_console_message(message) {
|
|
Debugger._console_batch.push(message);
|
|
|
|
// Clear existing timer
|
|
if (Debugger._console_timer) {
|
|
clearTimeout(Debugger._console_timer);
|
|
}
|
|
|
|
// Set debounce timer
|
|
Debugger._console_timer = setTimeout(() => {
|
|
Debugger._flush_console_batch();
|
|
}, Debugger.DEBOUNCE_MS);
|
|
}
|
|
|
|
/**
|
|
* Internal: Flush console_debug batch to server
|
|
*/
|
|
static async _flush_console_batch() {
|
|
if (Debugger._console_batch.length === 0) {
|
|
return;
|
|
}
|
|
const messages = Debugger._console_batch;
|
|
Debugger._console_batch = [];
|
|
Debugger._console_timer = null;
|
|
try {
|
|
return Ajax.call(Rsx.Route('Debugger_Controller', 'log_console_messages'), {
|
|
messages: messages
|
|
});
|
|
} catch (error) {
|
|
// Silently fail - don't create error loop
|
|
console.error('Failed to send console_debug messages to server:', error);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Internal: Flush error batch to server
|
|
*/
|
|
static async _flush_error_batch() {
|
|
if (Debugger._error_batch.length === 0) {
|
|
return;
|
|
}
|
|
const errors = Debugger._error_batch;
|
|
Debugger._error_batch = [];
|
|
Debugger._error_timer = null;
|
|
Debugger._error_batch_count++;
|
|
try {
|
|
return Ajax.call(Rsx.Route('Debugger_Controller', 'log_browser_errors'), {
|
|
errors: errors
|
|
});
|
|
} catch (error) {
|
|
// Silently fail - don't create error loop
|
|
console.error('Failed to send browser errors to server:', error);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Internal: Get time prefix for benchmarking
|
|
*/
|
|
static _get_time_prefix() {
|
|
const now = Date.now();
|
|
if (!Debugger._start_time) {
|
|
Debugger._start_time = now;
|
|
}
|
|
const elapsed = now - Debugger._start_time;
|
|
return (elapsed / 1000).toFixed(3) + 's';
|
|
}
|
|
}
|
|
// Batching state for console_debug messages
|
|
_27e0e986_defineProperty(Debugger, "_console_batch", []);
|
|
_27e0e986_defineProperty(Debugger, "_console_timer", null);
|
|
_27e0e986_defineProperty(Debugger, "_console_batch_count", 0);
|
|
// Batching state for error messages
|
|
_27e0e986_defineProperty(Debugger, "_error_batch", []);
|
|
_27e0e986_defineProperty(Debugger, "_error_timer", null);
|
|
_27e0e986_defineProperty(Debugger, "_error_count", 0);
|
|
_27e0e986_defineProperty(Debugger, "_error_batch_count", 0);
|
|
// Constants
|
|
_27e0e986_defineProperty(Debugger, "DEBOUNCE_MS", 2000);
|
|
_27e0e986_defineProperty(Debugger, "MAX_ERRORS_PER_PAGE", 20);
|
|
_27e0e986_defineProperty(Debugger, "MAX_ERROR_BATCHES", 5);
|
|
// Store start time for benchmarking
|
|
_27e0e986_defineProperty(Debugger, "_start_time", null);
|
|
|
|
|
|
/* === app/RSpade/Core/Js/Rsx_Jq_Helpers.js (babel) === */
|
|
"use strict";
|
|
|
|
// @JS-THIS-01-EXCEPTION
|
|
/**
|
|
* jQuery helper extensions for the RSX framework
|
|
* These extensions add utility methods to jQuery's prototype
|
|
* Note: 'this' references in jQuery extensions refer to jQuery objects by design
|
|
*/
|
|
class Rsx_Jq_Helpers {
|
|
/**
|
|
* Initialize jQuery extensions when the framework core is defined
|
|
* This method is called during framework initialization
|
|
*/
|
|
static _on_framework_core_define() {
|
|
// Returns true if jquery selector matched an element
|
|
$.fn.exists = function () {
|
|
return this.length > 0;
|
|
};
|
|
|
|
// Returns true if jquery element is visible
|
|
$.fn.is_visible = function () {
|
|
return this.is(':visible');
|
|
};
|
|
|
|
// Scrolls to the target element, only scrolls up. Todo: Create a version
|
|
// of this that also scrolls only down, or both
|
|
$.fn.scroll_up_to = function () {
|
|
let speed = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;
|
|
if (!this.exists()) {
|
|
// console.warn("Could not find target element to scroll to");
|
|
return;
|
|
}
|
|
if (!this.is_in_dom()) {
|
|
// console.warn("Target element for scroll is not on dom");
|
|
return;
|
|
}
|
|
let e_top = Math.round(this.offset().top);
|
|
let s_top = $('body').scrollTop();
|
|
if (e_top < 0) {
|
|
let target = s_top + e_top;
|
|
$('html, body').animate({
|
|
scrollTop: target
|
|
}, speed);
|
|
}
|
|
};
|
|
|
|
// $().is(":focus") - check if element has focus
|
|
$.expr[':'].focus = function (elem) {
|
|
return elem === document.activeElement && (elem.type || elem.href);
|
|
};
|
|
|
|
// Save native click behavior before override
|
|
$.fn._click_native = $.fn.click;
|
|
|
|
// Override .click() to call preventDefault by default
|
|
// This prevents accidental page navigation/form submission - the correct behavior 95% of the time
|
|
$.fn.click = function (handler) {
|
|
// If no handler provided, trigger click event (jQuery .click() with no args)
|
|
if (typeof handler === 'undefined') {
|
|
return this._click_native();
|
|
}
|
|
|
|
// Attach click handler with automatic preventDefault
|
|
return this.on('click', function (e) {
|
|
// Save original preventDefault
|
|
const original_preventDefault = e.preventDefault.bind(e);
|
|
|
|
// Override preventDefault to show warning when called explicitly
|
|
e.preventDefault = function () {
|
|
console.warn('event.preventDefault() is called automatically by RSpade .click() handlers and can be removed.');
|
|
return original_preventDefault();
|
|
};
|
|
|
|
// Call preventDefault before handler
|
|
original_preventDefault();
|
|
return handler.call(this, e);
|
|
});
|
|
};
|
|
|
|
// Escape hatch: click handler without preventDefault for the 5% case
|
|
$.fn.click_allow_default = function (handler) {
|
|
if (typeof handler === 'undefined') {
|
|
return this._click_native();
|
|
}
|
|
return this._click_native(handler);
|
|
};
|
|
|
|
// Returns true if the jquery element exists in and is attached to the DOM
|
|
$.fn.is_in_dom = function () {
|
|
let $element = this;
|
|
let _ancestor = function (HTMLobj) {
|
|
while (HTMLobj.parentElement) {
|
|
HTMLobj = HTMLobj.parentElement;
|
|
}
|
|
return HTMLobj;
|
|
};
|
|
return _ancestor($element[0]) === document.documentElement;
|
|
};
|
|
|
|
// Returns true if the element is visible in the viewport
|
|
$.fn.is_in_viewport = function () {
|
|
let scrolltop = $(window).scrollTop() > 0 ? $(window).scrollTop() : $('body').scrollTop();
|
|
let $element = this;
|
|
const top_of_element = $element.offset().top;
|
|
const bottom_of_element = $element.offset().top + $element.outerHeight();
|
|
const bottom_of_screen = scrolltop + $(window).innerHeight();
|
|
const top_of_screen = scrolltop;
|
|
if (bottom_of_screen > top_of_element && top_of_screen < bottom_of_element) {
|
|
return true;
|
|
} else {
|
|
return false;
|
|
}
|
|
};
|
|
|
|
// Gets the tagname of a jquery element
|
|
$.fn.tagname = function () {
|
|
return this.prop('tagName').toLowerCase();
|
|
};
|
|
|
|
// Returns true if a href is not same domain
|
|
$.fn.is_external = function () {
|
|
const host = window.location.host;
|
|
const link = $('<a>', {
|
|
href: this.attr('href')
|
|
})[0].hostname;
|
|
return link !== host;
|
|
};
|
|
|
|
// HTML5 form validation wrappers
|
|
$.fn.checkValidity = function () {
|
|
if (this.length === 0) return false;
|
|
return this[0].checkValidity();
|
|
};
|
|
$.fn.reportValidity = function () {
|
|
if (this.length === 0) return false;
|
|
return this[0].reportValidity();
|
|
};
|
|
$.fn.requestSubmit = function () {
|
|
if (this.length === 0) return this;
|
|
this[0].requestSubmit();
|
|
return this;
|
|
};
|
|
|
|
// Find related components by searching up the ancestor tree
|
|
// Like .closest() but searches within ancestors instead of matching them
|
|
$.fn.closest_sibling = function (selector) {
|
|
let $current = this;
|
|
let $parent = $current.parent();
|
|
|
|
// Keep going up the tree until we hit body
|
|
while ($parent.length > 0 && !$parent.is('body')) {
|
|
// Search within this parent for the selector
|
|
let $found = $parent.find(selector);
|
|
if ($found.length > 0) {
|
|
return $found;
|
|
}
|
|
|
|
// Move up one level
|
|
$parent = $parent.parent();
|
|
}
|
|
|
|
// If we reached body, search within body as well
|
|
if ($parent.is('body')) {
|
|
let $found = $parent.find(selector);
|
|
if ($found.length > 0) {
|
|
return $found;
|
|
}
|
|
}
|
|
|
|
// Return empty jQuery object if nothing found
|
|
return $();
|
|
};
|
|
|
|
// Override $.ajax to prevent direct AJAX calls to local server
|
|
// Developers must use the Ajax endpoint pattern: await Controller.method(params)
|
|
const native_ajax = $.ajax;
|
|
$.ajax = function (url, options) {
|
|
// Handle both $.ajax(url, options) and $.ajax(options) signatures
|
|
let settings;
|
|
if (typeof url === 'string') {
|
|
settings = options || {};
|
|
settings.url = url;
|
|
} else {
|
|
settings = url || {};
|
|
}
|
|
|
|
// Check if this is a local request (relative URL or same domain)
|
|
const request_url = settings.url || '';
|
|
const is_relative = !request_url.match(/^https?:\/\//);
|
|
const is_same_domain = request_url.startsWith(window.location.origin);
|
|
const is_local_request = is_relative || is_same_domain;
|
|
|
|
// Allow framework Ajax.call() to function
|
|
if (settings.__local_integration === true) {
|
|
return native_ajax.call(this, settings);
|
|
}
|
|
|
|
// Allow file upload endpoint - requires native $.ajax for FormData support
|
|
const is_file_upload = request_url === '/_upload' || request_url.endsWith('/_upload');
|
|
if (is_file_upload) {
|
|
return native_ajax.call(this, settings);
|
|
}
|
|
|
|
// Block local AJAX requests that don't use the Ajax endpoint pattern
|
|
if (is_local_request) {
|
|
// Try to parse controller and action from URL
|
|
let controller_name = null;
|
|
let action_name = null;
|
|
const url_match = request_url.match(/\/_rsx_api\/([^\/]+)\/([^\/\?]+)/);
|
|
if (url_match) {
|
|
controller_name = url_match[1];
|
|
action_name = url_match[2];
|
|
}
|
|
let error_message = 'AJAX requests to localhost via $.ajax() are prohibited.\n\n';
|
|
if (controller_name && action_name) {
|
|
error_message += `Instead of:\n`;
|
|
error_message += ` $.ajax({url: '${request_url}', ...})\n\n`;
|
|
error_message += `Use:\n`;
|
|
error_message += ` await ${controller_name}.${action_name}(parameters)\n\n`;
|
|
} else {
|
|
error_message += `Use the Ajax endpoint pattern:\n`;
|
|
error_message += ` await Controller_Name.action_name(parameters)\n\n`;
|
|
}
|
|
error_message += `The controller method must have the #[Ajax_Endpoint] attribute.`;
|
|
shouldnt_happen(error_message);
|
|
}
|
|
|
|
// Allow external requests (different domain)
|
|
return native_ajax.call(this, settings);
|
|
};
|
|
}
|
|
}
|
|
|
|
|
|
/* === app/RSpade/Core/Js/Rsx.js (babel) === */
|
|
"use strict";
|
|
|
|
function _e8211f5b_defineProperty(e, r, t) { return (r = _e8211f5b_toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
|
|
function _e8211f5b_toPropertyKey(t) { var i = _e8211f5b_toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
|
|
function _e8211f5b_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); }
|
|
// @ROUTE-EXISTS-01-EXCEPTION - This file contains documentation examples with fictional route names
|
|
|
|
/**
|
|
* Rsx - Core JavaScript Runtime System
|
|
*
|
|
* The Rsx class is the central hub for the RSX JavaScript runtime, providing essential
|
|
* system-level utilities that all other framework components depend on. It serves as the
|
|
* foundation for the client-side framework, handling core operations that must be globally
|
|
* accessible and consistently available.
|
|
*
|
|
* Core Responsibilities:
|
|
* - Event System: Application-wide event bus for framework lifecycle and custom events
|
|
* - Environment Detection: Runtime environment identification (dev/production)
|
|
* - Route Management: Type-safe route generation and URL building
|
|
* - Unique ID Generation: Client-side unique identifier generation
|
|
* - Framework Bootstrap: Multi-phase initialization orchestration
|
|
* - Logging: Centralized logging interface (delegates to console_debug)
|
|
*
|
|
* The Rsx class deliberately keeps its scope limited to core utilities. Advanced features
|
|
* are delegated to specialized classes:
|
|
* - Manifest operations → Manifest class
|
|
* - Caching → Rsx_Cache class
|
|
* - AJAX/API calls → Ajax_* classes
|
|
* - Route proxies → Rsx_Route_Proxy class
|
|
* - Behaviors → Rsx_Behaviors class
|
|
*
|
|
* All methods are static - Rsx is never instantiated. It's available globally from the
|
|
* moment bundles load and remains constant throughout the application lifecycle.
|
|
*
|
|
* Usage Examples:
|
|
* ```javascript
|
|
* // Event system
|
|
* Rsx.on('app_ready', () => console.log('App initialized'));
|
|
* Rsx.trigger('custom_event', {data: 'value'});
|
|
*
|
|
* // Environment detection
|
|
* if (Rsx.is_dev()) { console.log('Development mode'); }
|
|
*
|
|
* // Route generation
|
|
* const url = Rsx.Route('Controller', 'action').url();
|
|
*
|
|
* // Unique IDs
|
|
* const uniqueId = Rsx.uid(); // e.g., "rsx_1234567890_1"
|
|
* ```
|
|
*
|
|
* @static
|
|
* @global
|
|
*/
|
|
class Rsx {
|
|
// Initialize event handlers storage
|
|
static _init_events() {
|
|
if (typeof Rsx._event_handlers === 'undefined') {
|
|
Rsx._event_handlers = {};
|
|
}
|
|
if (typeof Rsx._triggered_events === 'undefined') {
|
|
Rsx._triggered_events = {};
|
|
}
|
|
}
|
|
|
|
// Register an event handler
|
|
static on(event, callback) {
|
|
Rsx._init_events();
|
|
if (typeof callback !== 'function') {
|
|
throw new Error('Callback must be a function');
|
|
}
|
|
if (!Rsx._event_handlers[event]) {
|
|
Rsx._event_handlers[event] = [];
|
|
}
|
|
Rsx._event_handlers[event].push(callback);
|
|
|
|
// If this event was already triggered, call the callback immediately
|
|
if (Rsx._triggered_events[event]) {
|
|
console_debug('RSX_INIT', 'Triggering ' + event + ' for late registered callback');
|
|
callback(Rsx._triggered_events[event]);
|
|
}
|
|
}
|
|
|
|
// Trigger an event with optional data
|
|
static trigger(event) {
|
|
let data = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
Rsx._init_events();
|
|
|
|
// Record that this event was triggered
|
|
Rsx._triggered_events[event] = data;
|
|
if (!Rsx._event_handlers[event]) {
|
|
return;
|
|
}
|
|
console_debug('RSX_INIT', 'Triggering ' + event + ' for ' + Rsx._event_handlers[event].length + ' callbacks');
|
|
|
|
// Call all registered handlers for this event in order
|
|
for (const callback of Rsx._event_handlers[event]) {
|
|
callback(data);
|
|
}
|
|
}
|
|
|
|
// Alias for trigger.refresh(''), should be called after major UI updates to apply such effects as
|
|
// underlining links to unimplemented # routes
|
|
static trigger_refresh() {
|
|
// Use Rsx.on('refresh', callback); to register a callback for refresh
|
|
this.trigger('refresh');
|
|
}
|
|
|
|
// Log to server that an event happened
|
|
static log(type) {
|
|
let message = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'notice';
|
|
Core_Log.log(type, message);
|
|
}
|
|
|
|
// Returns true if the app is being run in dev mode
|
|
// This should affect caching and some debug checks
|
|
static is_dev() {
|
|
return window.rsxapp.debug;
|
|
}
|
|
static is_prod() {
|
|
return !window.rsxapp.debug;
|
|
}
|
|
|
|
// Generates a unique number for the application instance
|
|
static uid() {
|
|
if (typeof Rsx._uid == undef) {
|
|
Rsx._uid = 0;
|
|
}
|
|
return Rsx._uid++;
|
|
}
|
|
|
|
// Storage for route definitions loaded from bundles
|
|
|
|
/**
|
|
* Define routes from bundled data
|
|
* Called by generated JavaScript in bundles
|
|
*/
|
|
static _define_routes(routes) {
|
|
// Merge routes into the global route storage
|
|
for (const class_name in routes) {
|
|
if (!Rsx._routes[class_name]) {
|
|
Rsx._routes[class_name] = {};
|
|
}
|
|
for (const method_name in routes[class_name]) {
|
|
Rsx._routes[class_name][method_name] = routes[class_name][method_name];
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Generate URL for a controller route
|
|
*
|
|
* This method generates URLs for controller actions by looking up route patterns
|
|
* and replacing parameters. It handles both regular routes and Ajax endpoints.
|
|
*
|
|
* If the route is not found in the route definitions, a default pattern is used:
|
|
* `/_/{controller}/{action}` with all parameters appended as query strings.
|
|
*
|
|
* Usage examples:
|
|
* ```javascript
|
|
* // Simple route without parameters (defaults to 'index' action)
|
|
* const url = Rsx.Route('Frontend_Index_Controller');
|
|
* // Returns: /dashboard
|
|
*
|
|
* // Route with explicit action
|
|
* const url = Rsx.Route('Frontend_Index_Controller', 'index');
|
|
* // Returns: /dashboard
|
|
*
|
|
* // Route with integer parameter (sets 'id')
|
|
* const url = Rsx.Route('Frontend_Client_View_Controller', 'view', 123);
|
|
* // Returns: /clients/view/123
|
|
*
|
|
* // Route with named parameters (object)
|
|
* const url = Rsx.Route('Frontend_Client_View_Controller', 'view', {id: 'C001'});
|
|
* // Returns: /clients/view/C001
|
|
*
|
|
* // Route with required and query parameters
|
|
* const url = Rsx.Route('Frontend_Client_View_Controller', 'view', {
|
|
* id: 'C001',
|
|
* tab: 'history'
|
|
* });
|
|
* // Returns: /clients/view/C001?tab=history
|
|
*
|
|
* // Route not found - uses default pattern
|
|
* const url = Rsx.Route('Unimplemented_Controller', 'some_action', {foo: 'bar'});
|
|
* // Returns: /_/Unimplemented_Controller/some_action?foo=bar
|
|
*
|
|
* // Placeholder route
|
|
* const url = Rsx.Route('Future_Controller', '#index');
|
|
* // Returns: #
|
|
* ```
|
|
*
|
|
* @param {string} class_name The controller class name (e.g., 'User_Controller')
|
|
* @param {string} [action_name='index'] The action/method name (defaults to 'index'). Use '#action' for placeholders.
|
|
* @param {number|Object} [params=null] Route parameters. Integer sets 'id', object provides named params.
|
|
* @returns {string} The generated URL
|
|
*/
|
|
static Route(class_name) {
|
|
let action_name = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'index';
|
|
let params = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
|
|
// Normalize params to object
|
|
let params_obj = {};
|
|
if (typeof params === 'number') {
|
|
params_obj = {
|
|
id: params
|
|
};
|
|
} else if (params && typeof params === 'object') {
|
|
params_obj = params;
|
|
} else if (params !== null && params !== undefined) {
|
|
throw new Error('Params must be number, object, or null');
|
|
}
|
|
|
|
// Placeholder route: action starts with # means unimplemented/scaffolding
|
|
if (action_name.startsWith('#')) {
|
|
return '#';
|
|
}
|
|
|
|
// Check if route exists in definitions
|
|
let pattern;
|
|
if (Rsx._routes[class_name] && Rsx._routes[class_name][action_name]) {
|
|
pattern = Rsx._routes[class_name][action_name];
|
|
} else {
|
|
// Route not found - use default pattern /_/{controller}/{action}
|
|
pattern = `/_/${class_name}/${action_name}`;
|
|
}
|
|
|
|
// Generate URL from pattern
|
|
return Rsx._generate_url_from_pattern(pattern, params_obj);
|
|
}
|
|
|
|
/**
|
|
* Generate URL from route pattern by replacing parameters
|
|
*
|
|
* @param {string} pattern The route pattern (e.g., '/users/:id/view')
|
|
* @param {Object} params Parameters to fill into the route
|
|
* @returns {string} The generated URL
|
|
*/
|
|
static _generate_url_from_pattern(pattern, params) {
|
|
// Extract required parameters from the pattern
|
|
const required_params = [];
|
|
const matches = pattern.match(/:([a-zA-Z_][a-zA-Z0-9_]*)/g);
|
|
if (matches) {
|
|
// Remove the : prefix from each match
|
|
for (const match of matches) {
|
|
required_params.push(match.substring(1));
|
|
}
|
|
}
|
|
|
|
// Check for required parameters
|
|
const missing = [];
|
|
for (const required of required_params) {
|
|
if (!(required in params)) {
|
|
missing.push(required);
|
|
}
|
|
}
|
|
if (missing.length > 0) {
|
|
throw new Error(`Required parameters [${missing.join(', ')}] are missing for route ${pattern}`);
|
|
}
|
|
|
|
// Build the URL by replacing parameters
|
|
let url = pattern;
|
|
const used_params = {};
|
|
for (const param_name of required_params) {
|
|
const value = params[param_name];
|
|
// URL encode the value
|
|
const encoded_value = encodeURIComponent(value);
|
|
url = url.replace(':' + param_name, encoded_value);
|
|
used_params[param_name] = true;
|
|
}
|
|
|
|
// Collect any extra parameters for query string
|
|
const query_params = {};
|
|
for (const key in params) {
|
|
if (!used_params[key]) {
|
|
query_params[key] = params[key];
|
|
}
|
|
}
|
|
|
|
// Append query string if there are extra parameters
|
|
if (Object.keys(query_params).length > 0) {
|
|
const query_string = Object.entries(query_params).map(_ref => {
|
|
let [key, value] = _ref;
|
|
return `${encodeURIComponent(key)}=${encodeURIComponent(value)}`;
|
|
}).join('&');
|
|
url += '?' + query_string;
|
|
}
|
|
return url;
|
|
}
|
|
|
|
/**
|
|
* Internal: Call a specific method on all classes that have it
|
|
* Collects promises from return values and waits for all to resolve
|
|
* @param {string} method_name The method name to call on all classes
|
|
* @returns {Promise} Promise that resolves when all method calls complete
|
|
*/
|
|
static async _rsx_call_all_classes(method_name) {
|
|
const all_classes = Manifest.get_all_classes();
|
|
const classes_with_method = [];
|
|
const promise_pile = [];
|
|
for (const class_info of all_classes) {
|
|
const class_object = class_info.class_object;
|
|
const class_name = class_info.class_name;
|
|
|
|
// Check if this class has the method (static methods are on the class itself)
|
|
if (typeof class_object[method_name] === 'function') {
|
|
classes_with_method.push(class_name);
|
|
const return_value = await class_object[method_name]();
|
|
|
|
// Collect promises from return value
|
|
if (return_value instanceof Promise) {
|
|
promise_pile.push(return_value);
|
|
} else if (Array.isArray(return_value)) {
|
|
for (const item of return_value) {
|
|
if (item instanceof Promise) {
|
|
promise_pile.push(item);
|
|
}
|
|
}
|
|
}
|
|
if (Rsx.__stopped) {
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
if (classes_with_method.length > 0) {
|
|
console_debug('RSX_INIT', `${method_name}: ${classes_with_method.length} classes`);
|
|
}
|
|
|
|
// Await all promises before returning
|
|
if (promise_pile.length > 0) {
|
|
console_debug('RSX_INIT', `${method_name}: Awaiting ${promise_pile.length} promises`);
|
|
await Promise.all(promise_pile);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Internal: Execute multi-phase initialization for all registered classes
|
|
* This runs various initialization phases in order to properly set up the application
|
|
* @returns {Promise} Promise that resolves when all initialization phases complete
|
|
*/
|
|
static async _rsx_core_boot() {
|
|
if (Rsx.__booted) {
|
|
console.error('Rsx._rsx_core_boot called more than once');
|
|
return;
|
|
}
|
|
Rsx.__booted = true;
|
|
|
|
// Get all registered classes from the manifest
|
|
const all_classes = Manifest.get_all_classes();
|
|
console_debug('RSX_INIT', `Starting _rsx_core_boot with ${all_classes.length} classes`);
|
|
if (!all_classes || all_classes.length === 0) {
|
|
// No classes to initialize
|
|
shouldnt_happen('No classes registered in js - there should be at least the core framework classes');
|
|
return;
|
|
}
|
|
|
|
// Define initialization phases in order
|
|
const phases = [{
|
|
event: 'framework_core_define',
|
|
method: '_on_framework_core_define'
|
|
}, {
|
|
event: 'framework_modules_define',
|
|
method: '_on_framework_modules_define'
|
|
}, {
|
|
event: 'framework_core_init',
|
|
method: '_on_framework_core_init'
|
|
}, {
|
|
event: 'app_modules_define',
|
|
method: 'on_app_modules_define'
|
|
}, {
|
|
event: 'app_define',
|
|
method: 'on_app_define'
|
|
}, {
|
|
event: 'framework_modules_init',
|
|
method: '_on_framework_modules_init'
|
|
}, {
|
|
event: 'app_modules_init',
|
|
method: 'on_app_modules_init'
|
|
}, {
|
|
event: 'app_init',
|
|
method: 'on_app_init'
|
|
}, {
|
|
event: 'app_ready',
|
|
method: 'on_app_ready'
|
|
}];
|
|
|
|
// Execute each phase in order
|
|
for (const phase of phases) {
|
|
await Rsx._rsx_call_all_classes(phase.method);
|
|
if (Rsx.__stopped) {
|
|
return;
|
|
}
|
|
Rsx.trigger(phase.event);
|
|
}
|
|
|
|
// Ui refresh callbacks
|
|
Rsx.trigger_refresh();
|
|
|
|
// All phases complete
|
|
console_debug('RSX_INIT', 'Initialization complete');
|
|
|
|
// TODO: Find a good wait to wait for all jqhtml components to load, then trigger on_ready and on('ready') emulating the top level last syntax that jqhtml components operateas, but as a standard js class (such as a page class). The biggest question is, how do we efficiently choose only the top level jqhtml components. do we only consider components cretaed directly on blade templates? that seams reasonable...
|
|
|
|
// Trigger _debug_ready event - this is ONLY for tooling like rsx:debug
|
|
// DO NOT use this in application code - use on_app_ready() phase instead
|
|
// This event exists solely for debugging tools that need to run after full initialization
|
|
Rsx.trigger('_debug_ready');
|
|
}
|
|
|
|
/* Calling this stops the boot process. */
|
|
static async _rsx_core_boot_stop(reason) {
|
|
console.error(reason);
|
|
Rsx.__stopped = true;
|
|
}
|
|
|
|
/**
|
|
* Parse URL hash into key-value object
|
|
* Handles format: #key=value&key2=value2
|
|
*
|
|
* @returns {Object} Parsed hash parameters
|
|
*/
|
|
static _parse_hash() {
|
|
const hash = window.location.hash;
|
|
if (!hash || hash === '#') {
|
|
return {};
|
|
}
|
|
|
|
// Remove leading # and parse as query string
|
|
const hash_string = hash.substring(1);
|
|
const params = {};
|
|
const pairs = hash_string.split('&');
|
|
for (const pair of pairs) {
|
|
const [key, value] = pair.split('=');
|
|
if (key) {
|
|
params[decodeURIComponent(key)] = value ? decodeURIComponent(value) : '';
|
|
}
|
|
}
|
|
return params;
|
|
}
|
|
|
|
/**
|
|
* Serialize object into URL hash format
|
|
* Produces format: #key=value&key2=value2
|
|
*
|
|
* @param {Object} params Key-value pairs to encode
|
|
* @returns {string} Encoded hash string (with leading #, or empty string)
|
|
*/
|
|
static _serialize_hash(params) {
|
|
const pairs = [];
|
|
for (const key in params) {
|
|
const value = params[key];
|
|
if (value !== null && value !== undefined && value !== '') {
|
|
pairs.push(`${encodeURIComponent(key)}=${encodeURIComponent(value)}`);
|
|
}
|
|
}
|
|
return pairs.length > 0 ? '#' + pairs.join('&') : '';
|
|
}
|
|
|
|
/**
|
|
* Get all page state from URL hash
|
|
*
|
|
* Usage:
|
|
* ```javascript
|
|
* const state = Rsx.get_all_page_state();
|
|
* // Returns: {dg_page: '2', dg_sort: 'name'}
|
|
* ```
|
|
*
|
|
* @returns {Object} All hash parameters as key-value pairs
|
|
*/
|
|
static get_all_page_state() {
|
|
return Rsx._parse_hash();
|
|
}
|
|
|
|
/**
|
|
* Get single value from URL hash state
|
|
*
|
|
* Usage:
|
|
* ```javascript
|
|
* const page = Rsx.get_page_state('dg_page');
|
|
* // Returns: '2' or null if not set
|
|
* ```
|
|
*
|
|
* @param {string} key The key to retrieve
|
|
* @returns {string|null} The value or null if not found
|
|
*/
|
|
static get_page_state(key) {
|
|
var _state$key;
|
|
const state = Rsx._parse_hash();
|
|
return (_state$key = state[key]) !== null && _state$key !== void 0 ? _state$key : null;
|
|
}
|
|
|
|
/**
|
|
* Set single value in URL hash state (replaces history, doesn't add)
|
|
*
|
|
* Usage:
|
|
* ```javascript
|
|
* Rsx.set_page_state('dg_page', 2);
|
|
* // URL becomes: http://example.com/page#dg_page=2
|
|
*
|
|
* Rsx.set_page_state('dg_page', null); // Remove key
|
|
* ```
|
|
*
|
|
* @param {string} key The key to set
|
|
* @param {string|number|null} value The value (null/empty removes the key)
|
|
*/
|
|
static set_page_state(key, value) {
|
|
const state = Rsx._parse_hash();
|
|
|
|
// Update or remove the key
|
|
if (value === null || value === undefined || value === '') {
|
|
delete state[key];
|
|
} else {
|
|
state[key] = String(value);
|
|
}
|
|
|
|
// Update URL without adding history
|
|
const new_hash = Rsx._serialize_hash(state);
|
|
const url = window.location.pathname + window.location.search + new_hash;
|
|
history.replaceState(null, '', url);
|
|
}
|
|
|
|
/**
|
|
* Set multiple values in URL hash state at once
|
|
*
|
|
* Usage:
|
|
* ```javascript
|
|
* Rsx.set_all_page_state({dg_page: 2, dg_sort: 'name'});
|
|
* // URL becomes: http://example.com/page#dg_page=2&dg_sort=name
|
|
* ```
|
|
*
|
|
* @param {Object} new_state Object with key-value pairs to set
|
|
*/
|
|
static set_all_page_state(new_state) {
|
|
const state = Rsx._parse_hash();
|
|
|
|
// Merge new state
|
|
for (const key in new_state) {
|
|
const value = new_state[key];
|
|
if (value === null || value === undefined || value === '') {
|
|
delete state[key];
|
|
} else {
|
|
state[key] = String(value);
|
|
}
|
|
}
|
|
|
|
// Update URL without adding history
|
|
const new_hash = Rsx._serialize_hash(state);
|
|
const url = window.location.pathname + window.location.search + new_hash;
|
|
history.replaceState(null, '', url);
|
|
}
|
|
|
|
/**
|
|
* Render an error in a DOM element
|
|
*
|
|
* Displays errors from Ajax calls in a standardized format. Handles different
|
|
* error types (fatal, validation, auth, generic) with appropriate formatting.
|
|
*
|
|
* Usage:
|
|
* ```javascript
|
|
* try {
|
|
* const result = await Controller.method();
|
|
* } catch (error) {
|
|
* Rsx.render_error(error, '#error_container');
|
|
* }
|
|
* ```
|
|
*
|
|
* @param {Error|Object} error - Error object from Ajax call
|
|
* @param {jQuery|string} container - jQuery element or selector for error display
|
|
*/
|
|
static render_error(error, container) {
|
|
const $container = $(container);
|
|
if (!$container.exists()) {
|
|
console.error('Rsx.render_error: Container not found', container);
|
|
return;
|
|
}
|
|
|
|
// Clear existing content
|
|
$container.empty();
|
|
let html = '';
|
|
|
|
// Handle different error types
|
|
if (error.type === 'fatal' && error.details) {
|
|
// Fatal PHP error with file/line/error
|
|
const details = error.details;
|
|
const file = details.file || 'Unknown file';
|
|
const line = details.line || '?';
|
|
const message = details.error || error.message || 'Fatal error occurred';
|
|
html = `
|
|
<div class="alert alert-danger" role="alert">
|
|
<h5>Uncaught Fatal Error in ${file}:${line}:</h5>
|
|
<p class="mb-0">${Rsx._escape_html(message)}</p>
|
|
</div>
|
|
`;
|
|
} else if (error.type === 'form_error' && error.details) {
|
|
// Validation errors - show unmatched errors only
|
|
// (matched errors should be handled by Form_Utils.apply_form_errors)
|
|
const errors = error.details;
|
|
const error_list = [];
|
|
for (const field in errors) {
|
|
error_list.push(errors[field]);
|
|
}
|
|
if (error_list.length > 0) {
|
|
html = `
|
|
<div class="alert alert-warning" role="alert">
|
|
<h5>Validation Errors:</h5>
|
|
<ul class="mb-0">
|
|
${error_list.map(err => `<li>${Rsx._escape_html(err)}</li>`).join('')}
|
|
</ul>
|
|
</div>
|
|
`;
|
|
}
|
|
} else if (error.type === 'auth_required' || error.type === 'unauthorized') {
|
|
// Authentication/authorization errors
|
|
const message = error.message || 'Authentication required';
|
|
html = `
|
|
<div class="alert alert-warning" role="alert">
|
|
<p class="mb-0">${Rsx._escape_html(message)}</p>
|
|
</div>
|
|
`;
|
|
} else if (error.type === 'network') {
|
|
// Network errors
|
|
const message = error.message || 'Unable to reach server. Please check your connection.';
|
|
html = `
|
|
<div class="alert alert-danger" role="alert">
|
|
<p class="mb-0">${Rsx._escape_html(message)}</p>
|
|
</div>
|
|
`;
|
|
} else {
|
|
// Generic/unknown error
|
|
const message = error.message || error.toString() || 'An unknown error occurred';
|
|
html = `
|
|
<div class="alert alert-danger" role="alert">
|
|
<p class="mb-0">${Rsx._escape_html(message)}</p>
|
|
</div>
|
|
`;
|
|
}
|
|
$container.html(html);
|
|
}
|
|
|
|
/**
|
|
* Escape HTML to prevent XSS in error messages
|
|
* @private
|
|
*/
|
|
static _escape_html(text) {
|
|
const div = document.createElement('div');
|
|
div.textContent = text;
|
|
return div.innerHTML;
|
|
}
|
|
}
|
|
// Gets set to true to interupt startup sequence
|
|
_e8211f5b_defineProperty(Rsx, "__stopped", false);
|
|
_e8211f5b_defineProperty(Rsx, "_routes", {});
|
|
|
|
|
|
/* === app/RSpade/Core/Js/Ajax.js (babel) === */
|
|
"use strict";
|
|
|
|
// @FILE-SUBCLASS-01-EXCEPTION
|
|
|
|
/**
|
|
* Client-side Ajax class for making API calls to RSX controllers
|
|
*
|
|
* Automatically batches multiple calls into single HTTP requests to reduce network overhead.
|
|
* Batches up to 20 calls or flushes after setTimeout(0) debounce.
|
|
*/
|
|
class Ajax {
|
|
/**
|
|
* Initialize Ajax system
|
|
* Called automatically when class is loaded
|
|
*/
|
|
static _on_framework_core_init() {
|
|
// Queue of pending calls waiting to be batched
|
|
Ajax._pending_calls = {};
|
|
|
|
// Timer for batching flush
|
|
Ajax._flush_timeout = null;
|
|
|
|
// Call counter for generating unique call IDs
|
|
Ajax._call_counter = 0;
|
|
|
|
// Maximum batch size before forcing immediate flush
|
|
Ajax.MAX_BATCH_SIZE = 20;
|
|
|
|
// Debounce time in milliseconds
|
|
Ajax.DEBOUNCE_MS = 0;
|
|
|
|
// Track promises from Ajax calls to detect uncaught rejections
|
|
Ajax._tracked_promises = new WeakSet();
|
|
|
|
// Set up global unhandled rejection handler for Ajax errors
|
|
window.addEventListener('unhandledrejection', async event => {
|
|
// Only handle rejections from Ajax promises
|
|
if (Ajax._tracked_promises.has(event.promise)) {
|
|
event.preventDefault(); // Prevent browser's default "Uncaught (in promise)" error
|
|
|
|
const error = event.reason;
|
|
console.error('Uncaught Ajax error:', error);
|
|
|
|
// Show Modal.error() for uncaught Ajax errors
|
|
if (typeof Modal !== 'undefined' && Modal.error) {
|
|
await Modal.error(error, 'Uncaught Ajax Error');
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Make an AJAX call to an RSX controller action
|
|
*
|
|
* All calls are automatically batched unless window.rsxapp.ajax_disable_batching is true.
|
|
*
|
|
* @param {string|object|function} url - The Ajax URL (e.g., '/_ajax/Controller_Name/action_name') or an object/function with a .path property
|
|
* @param {object} params - Parameters to send to the action
|
|
* @returns {Promise} - Resolves with the return value, rejects with error
|
|
*/
|
|
static async call(url) {
|
|
let params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
// If url is an object or function with a .path property, use that as the URL
|
|
if (url && typeof url === 'object' && url.path) {
|
|
url = url.path;
|
|
} else if (url && typeof url === 'function' && url.path) {
|
|
url = url.path;
|
|
}
|
|
|
|
// Validate url is a non-empty string
|
|
if (typeof url !== 'string' || url.length === 0) {
|
|
throw new Error('Ajax.call() requires a non-empty string URL or an object/function with a .path property');
|
|
}
|
|
|
|
// Extract controller and action from URL
|
|
const {
|
|
controller,
|
|
action
|
|
} = Ajax.ajax_url_to_controller_action(url);
|
|
console.log('Ajax:', controller, action, params);
|
|
|
|
// Check if batching is disabled for debugging
|
|
let promise;
|
|
if (window.rsxapp && window.rsxapp.ajax_disable_batching) {
|
|
promise = Ajax._call_direct(controller, action, params);
|
|
} else {
|
|
promise = Ajax._call_batch(controller, action, params);
|
|
}
|
|
|
|
// Track this promise for unhandled rejection detection
|
|
Ajax._tracked_promises.add(promise);
|
|
return promise;
|
|
}
|
|
|
|
/**
|
|
* Make a batched Ajax call
|
|
* @private
|
|
*/
|
|
static _call_batch(controller, action) {
|
|
let params = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|
console.log('Ajax Batch:', controller, action, params);
|
|
return new Promise((resolve, reject) => {
|
|
// Generate call key for deduplication
|
|
const call_key = Ajax._generate_call_key(controller, action, params);
|
|
|
|
// Check if this exact call is already pending
|
|
if (Ajax._pending_calls[call_key]) {
|
|
const existing_call = Ajax._pending_calls[call_key];
|
|
|
|
// If call already completed (cached), return immediately
|
|
if (existing_call.is_complete) {
|
|
if (existing_call.is_error) {
|
|
reject(existing_call.error);
|
|
} else {
|
|
resolve(existing_call.result);
|
|
}
|
|
return;
|
|
}
|
|
|
|
// Call is pending, add this promise to callbacks
|
|
existing_call.callbacks.push({
|
|
resolve,
|
|
reject
|
|
});
|
|
return;
|
|
}
|
|
|
|
// Create new pending call
|
|
const call_id = Ajax._call_counter++;
|
|
const pending_call = {
|
|
call_id: call_id,
|
|
call_key: call_key,
|
|
controller: controller,
|
|
action: action,
|
|
params: params,
|
|
callbacks: [{
|
|
resolve,
|
|
reject
|
|
}],
|
|
is_complete: false,
|
|
is_error: false,
|
|
result: null,
|
|
error: null
|
|
};
|
|
|
|
// Add to pending queue
|
|
Ajax._pending_calls[call_key] = pending_call;
|
|
|
|
// Count pending calls
|
|
const pending_count = Object.keys(Ajax._pending_calls).filter(key => !Ajax._pending_calls[key].is_complete).length;
|
|
|
|
// If we've hit the batch size limit, flush immediately
|
|
if (pending_count >= Ajax.MAX_BATCH_SIZE) {
|
|
clearTimeout(Ajax._flush_timeout);
|
|
Ajax._flush_timeout = null;
|
|
Ajax._flush_pending_calls();
|
|
} else {
|
|
// Schedule batch flush with debounce
|
|
clearTimeout(Ajax._flush_timeout);
|
|
Ajax._flush_timeout = setTimeout(() => {
|
|
Ajax._flush_pending_calls();
|
|
}, Ajax.DEBOUNCE_MS);
|
|
}
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Make a direct (non-batched) Ajax call
|
|
* @private
|
|
*/
|
|
static async _call_direct(controller, action) {
|
|
let params = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|
// Construct URL from controller and action
|
|
const url = `/_ajax/${controller}/${action}`;
|
|
|
|
// Log the AJAX call using console_debug
|
|
if (typeof Debugger !== 'undefined' && Debugger.console_debug) {
|
|
Debugger.console_debug('AJAX', `Calling ${controller}.${action} (unbatched)`, params);
|
|
}
|
|
return new Promise((resolve, reject) => {
|
|
$.ajax({
|
|
url: url,
|
|
method: 'POST',
|
|
data: params,
|
|
dataType: 'json',
|
|
__local_integration: true,
|
|
// Bypass $.ajax override
|
|
success: response => {
|
|
// Handle console_debug messages
|
|
if (response.console_debug && Array.isArray(response.console_debug)) {
|
|
response.console_debug.forEach(msg => {
|
|
if (!Array.isArray(msg) || msg.length !== 2) {
|
|
throw new Error('Invalid console_debug message format - expected [channel, [arguments]]');
|
|
}
|
|
const [channel, args] = msg;
|
|
console.log(channel, ...args);
|
|
});
|
|
}
|
|
|
|
// Check if the response was successful
|
|
if (response._success === true) {
|
|
// @JS-AJAX-02-EXCEPTION - Unwrap server responses with _ajax_return_value
|
|
const processed_value = Rsx_Js_Model._instantiate_models_recursive(response._ajax_return_value);
|
|
resolve(processed_value);
|
|
} else {
|
|
// Handle error responses
|
|
const error_type = response.error_type || 'unknown_error';
|
|
const reason = response.reason || 'Unknown error occurred';
|
|
const details = response.details || {};
|
|
|
|
// Handle specific error types
|
|
switch (error_type) {
|
|
case 'fatal':
|
|
// Fatal PHP error with full error details
|
|
const fatal_error_data = response.error || {};
|
|
const error_message = fatal_error_data.error || 'Fatal error occurred';
|
|
console.error('Ajax error response from server:', response.error);
|
|
const fatal_error = new Error(error_message);
|
|
fatal_error.type = 'fatal';
|
|
fatal_error.details = response.error;
|
|
|
|
// Log to server if browser error logging is enabled
|
|
Debugger.log_error({
|
|
message: `Ajax Fatal Error: ${error_message}`,
|
|
type: 'ajax_fatal',
|
|
endpoint: url,
|
|
details: response.error
|
|
});
|
|
reject(fatal_error);
|
|
break;
|
|
case 'response_auth_required':
|
|
console.error('The user is no longer authenticated, this is a placeholder for future code which handles this scenario.');
|
|
const auth_error = new Error(reason);
|
|
auth_error.type = 'auth_required';
|
|
auth_error.details = details;
|
|
reject(auth_error);
|
|
break;
|
|
case 'response_unauthorized':
|
|
console.error('The user is unauthorized to perform this action, this is a placeholder for future code which handles this scenario.');
|
|
const unauth_error = new Error(reason);
|
|
unauth_error.type = 'unauthorized';
|
|
unauth_error.details = details;
|
|
reject(unauth_error);
|
|
break;
|
|
case 'response_form_error':
|
|
const form_error = new Error(reason);
|
|
form_error.type = 'form_error';
|
|
form_error.details = details;
|
|
reject(form_error);
|
|
break;
|
|
default:
|
|
const generic_error = new Error(reason);
|
|
generic_error.type = error_type;
|
|
generic_error.details = details;
|
|
reject(generic_error);
|
|
break;
|
|
}
|
|
}
|
|
},
|
|
error: (xhr, status, error) => {
|
|
const error_message = Ajax._extract_error_message(xhr);
|
|
const network_error = new Error(error_message);
|
|
network_error.type = 'network_error';
|
|
network_error.status = xhr.status;
|
|
network_error.statusText = status;
|
|
|
|
// Log server errors (500+) to the server if browser error logging is enabled
|
|
if (xhr.status >= 500) {
|
|
Debugger.log_error({
|
|
message: `Ajax Server Error ${xhr.status}: ${error_message}`,
|
|
type: 'ajax_server_error',
|
|
endpoint: url,
|
|
status: xhr.status,
|
|
statusText: status
|
|
});
|
|
}
|
|
reject(network_error);
|
|
}
|
|
});
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Flush all pending calls by sending batch request
|
|
* @private
|
|
*/
|
|
static async _flush_pending_calls() {
|
|
// Collect all pending calls
|
|
const calls_to_send = [];
|
|
const call_map = {}; // Map call_id to pending_call object
|
|
|
|
for (const call_key in Ajax._pending_calls) {
|
|
const pending_call = Ajax._pending_calls[call_key];
|
|
if (!pending_call.is_complete) {
|
|
calls_to_send.push({
|
|
call_id: pending_call.call_id,
|
|
controller: pending_call.controller,
|
|
action: pending_call.action,
|
|
params: pending_call.params
|
|
});
|
|
call_map[pending_call.call_id] = pending_call;
|
|
}
|
|
}
|
|
|
|
// Nothing to send
|
|
if (calls_to_send.length === 0) {
|
|
return;
|
|
}
|
|
|
|
// Log batch for debugging
|
|
if (typeof Debugger !== 'undefined' && Debugger.console_debug) {
|
|
Debugger.console_debug('AJAX_BATCH', `Sending batch of ${calls_to_send.length} calls`, calls_to_send.map(c => `${c.controller}.${c.action}`));
|
|
}
|
|
try {
|
|
// Send batch request
|
|
const response = await $.ajax({
|
|
url: '/_ajax/_batch',
|
|
method: 'POST',
|
|
data: {
|
|
batch_calls: JSON.stringify(calls_to_send)
|
|
},
|
|
dataType: 'json',
|
|
__local_integration: true // Bypass $.ajax override
|
|
});
|
|
|
|
// Process batch response
|
|
// Response format: { C_0: {success, _ajax_return_value}, C_1: {...}, ... }
|
|
for (const response_key in response) {
|
|
if (!response_key.startsWith('C_')) {
|
|
continue;
|
|
}
|
|
const call_id = parseInt(response_key.substring(2), 10);
|
|
const call_response = response[response_key];
|
|
const pending_call = call_map[call_id];
|
|
if (!pending_call) {
|
|
console.error('Received response for unknown call_id:', call_id);
|
|
continue;
|
|
}
|
|
|
|
// Handle console_debug messages if present
|
|
if (call_response.console_debug && Array.isArray(call_response.console_debug)) {
|
|
call_response.console_debug.forEach(msg => {
|
|
if (!Array.isArray(msg) || msg.length !== 2) {
|
|
throw new Error('Invalid console_debug message format - expected [channel, [arguments]]');
|
|
}
|
|
const [channel, args] = msg;
|
|
console.log(channel, ...args);
|
|
});
|
|
}
|
|
|
|
// Mark call as complete
|
|
pending_call.is_complete = true;
|
|
|
|
// Check if successful
|
|
if (call_response._success === true) {
|
|
// @JS-AJAX-02-EXCEPTION - Batch system unwraps server responses with _ajax_return_value
|
|
const processed_value = Rsx_Js_Model._instantiate_models_recursive(call_response._ajax_return_value);
|
|
pending_call.result = processed_value;
|
|
|
|
// Resolve all callbacks
|
|
pending_call.callbacks.forEach(_ref => {
|
|
let {
|
|
resolve
|
|
} = _ref;
|
|
resolve(processed_value);
|
|
});
|
|
} else {
|
|
// Handle error
|
|
const error_type = call_response.error_type || 'unknown_error';
|
|
let error_message;
|
|
let error_details;
|
|
if (error_type === 'fatal' && call_response.error) {
|
|
// Fatal PHP error with full error details
|
|
const fatal_error_data = call_response.error;
|
|
error_message = fatal_error_data.error || 'Fatal error occurred';
|
|
error_details = call_response.error;
|
|
console.error('Ajax error response from server:', call_response.error);
|
|
} else {
|
|
// Other error types
|
|
error_message = call_response.reason || 'Unknown error occurred';
|
|
error_details = call_response.details || {};
|
|
}
|
|
const error = new Error(error_message);
|
|
error.type = error_type;
|
|
error.details = error_details;
|
|
pending_call.is_error = true;
|
|
pending_call.error = error;
|
|
|
|
// Reject all callbacks
|
|
pending_call.callbacks.forEach(_ref2 => {
|
|
let {
|
|
reject
|
|
} = _ref2;
|
|
reject(error);
|
|
});
|
|
}
|
|
}
|
|
} catch (xhr_error) {
|
|
// Network or server error - reject all pending calls
|
|
const error_message = Ajax._extract_error_message(xhr_error);
|
|
const error = new Error(error_message);
|
|
error.type = 'network_error';
|
|
for (const call_id in call_map) {
|
|
const pending_call = call_map[call_id];
|
|
pending_call.is_complete = true;
|
|
pending_call.is_error = true;
|
|
pending_call.error = error;
|
|
pending_call.callbacks.forEach(_ref3 => {
|
|
let {
|
|
reject
|
|
} = _ref3;
|
|
reject(error);
|
|
});
|
|
}
|
|
console.error('Batch Ajax request failed:', error_message);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Generate a unique key for deduplicating calls
|
|
* @private
|
|
*/
|
|
static _generate_call_key(controller, action, params) {
|
|
// Create a stable string representation of the call
|
|
// Sort params keys for consistent hashing
|
|
const sorted_params = {};
|
|
Object.keys(params).sort().forEach(key => {
|
|
sorted_params[key] = params[key];
|
|
});
|
|
return `${controller}::${action}::${JSON.stringify(sorted_params)}`;
|
|
}
|
|
|
|
/**
|
|
* Extract error message from jQuery XHR object
|
|
* @private
|
|
*/
|
|
static _extract_error_message(xhr) {
|
|
if (xhr.responseJSON && xhr.responseJSON.message) {
|
|
return xhr.responseJSON.message;
|
|
} else if (xhr.responseText) {
|
|
try {
|
|
const response = JSON.parse(xhr.responseText);
|
|
if (response.message) {
|
|
return response.message;
|
|
}
|
|
} catch (e) {
|
|
// Not JSON
|
|
}
|
|
}
|
|
return `${xhr.status}: ${xhr.statusText || 'Unknown error'}`;
|
|
}
|
|
|
|
/**
|
|
* Parses an AJAX URL into controller and action
|
|
* Supports both /_ajax/ and /_/ URL prefixes
|
|
* @param {string|object|function} url - URL in format '/_ajax/Controller_Name/action_name' or '/_/Controller_Name/action_name', or an object/function with a .path property
|
|
* @returns {Object} Object with {controller: string, action: string}
|
|
* @throws {Error} If URL doesn't start with /_ajax or /_ or has invalid structure
|
|
*/
|
|
static ajax_url_to_controller_action(url) {
|
|
// If url is an object or function with a .path property, use that as the URL
|
|
if (url && typeof url === 'object' && url.path) {
|
|
url = url.path;
|
|
} else if (url && typeof url === 'function' && url.path) {
|
|
url = url.path;
|
|
}
|
|
|
|
// Validate url is a string
|
|
if (typeof url !== 'string') {
|
|
throw new Error(`URL must be a string or have a .path property, got: ${typeof url}`);
|
|
}
|
|
if (!url.startsWith('/_ajax') && !url.startsWith('/_/')) {
|
|
throw new Error(`URL must start with /_ajax or /_, got: ${url}`);
|
|
}
|
|
const parts = url.split('/').filter(part => part !== '');
|
|
if (parts.length < 2) {
|
|
throw new Error(`Invalid AJAX URL structure: ${url}`);
|
|
}
|
|
if (parts.length > 3) {
|
|
throw new Error(`AJAX URL has too many segments: ${url}`);
|
|
}
|
|
const controller = parts[1];
|
|
const action = parts[2] || 'index';
|
|
return {
|
|
controller,
|
|
action
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Auto-initialize static properties when class is first loaded
|
|
*/
|
|
static on_core_define() {
|
|
Ajax._on_framework_core_init();
|
|
}
|
|
}
|
|
|
|
|
|
/* === app/RSpade/Integrations/Jqhtml/Component.js (babel) === */
|
|
"use strict";
|
|
|
|
/**
|
|
* Component - Base class for JQHTML components in RSX framework
|
|
*
|
|
* This class wraps the jqhtml.Component from the npm package and provides
|
|
* the standard interface for RSX components following the Upper_Case naming convention.
|
|
*
|
|
* _Base_Jqhtml_Component is imported from npm via Jqhtml_Bundle.
|
|
*
|
|
* @Instantiatable
|
|
*/
|
|
class Component extends _Base_Jqhtml_Component {}
|
|
|
|
// RSX manifest automatically makes classes global - no manual assignment needed
|
|
|
|
|
|
/* === app/RSpade/Integrations/Jqhtml/Jqhtml_Integration.js (babel) === */
|
|
"use strict";
|
|
|
|
/**
|
|
* JQHTML Integration - Automatic component registration and binding
|
|
*
|
|
* This module automatically:
|
|
* 1. Registers component classes that extend Component
|
|
* 2. Binds templates to component classes when names match
|
|
* 3. Enables $(selector).component("Component_Name") syntax
|
|
*/
|
|
class Jqhtml_Integration {
|
|
/**
|
|
* Compiled Jqhtml templates self-register. The developer (the framework in this case) is still
|
|
* responsible for registering es6 component classes with jqhtml. This does so at an early stage
|
|
* of framework init.
|
|
*/
|
|
static _on_framework_modules_define() {
|
|
let jqhtml_components = Manifest.get_extending('Component');
|
|
console_debug('JQHTML_INIT', 'Registering ' + jqhtml_components.length + ' Jqhtml Components');
|
|
for (let component of jqhtml_components) {
|
|
jqhtml.register_component(component.class_name, component.class_object);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Framework modules init phase - Bind components and initialize DOM
|
|
* This runs after templates are registered to bind component classes
|
|
* @param {jQuery} [$scope] Optional scope to search within (defaults to body)
|
|
* @returns {Array<Promise>|undefined} Array of promises for recursive calls, undefined for top-level
|
|
*/
|
|
static _on_framework_modules_init($scope) {
|
|
const is_top_level = !$scope;
|
|
const promises = [];
|
|
const components_needing_init = ($scope || $('body')).find('.Component_Init');
|
|
if (components_needing_init.length > 0) {
|
|
console_debug('JQHTML_INIT', `Initializing ${components_needing_init.length} DOM components`);
|
|
}
|
|
components_needing_init.each(function () {
|
|
const $element = $(this);
|
|
|
|
// Skip if element is no longer attached to the document
|
|
// (may have been removed by a parent component's .empty() call)
|
|
if (!document.contains($element[0])) {
|
|
return;
|
|
}
|
|
|
|
// Check if any parent has Component_Init class - skip nested components
|
|
let parent = $element[0].parentElement;
|
|
while (parent) {
|
|
if (parent.classList.contains('Component_Init')) {
|
|
return; // Skip this element, it's nested
|
|
}
|
|
parent = parent.parentElement;
|
|
}
|
|
const component_name = $element.attr('data-component-init-name');
|
|
|
|
// jQuery's .data() doesn't auto-parse JSON - we need to parse it manually
|
|
let component_args = {};
|
|
const args_string = $element.attr('data-component-args');
|
|
|
|
// Unset component- php side initialization args, it is no longer needed as a compionent attribute
|
|
// Unsetting also prevents undesired access to this code in other parts of the program, prevening an
|
|
// unwanted future dependency on this paradigm
|
|
$element.removeAttr('data-component-init-name');
|
|
$element.removeAttr('data-component-args');
|
|
$element.removeData('component-init-name');
|
|
$element.removeData('component-args');
|
|
if (args_string) {
|
|
try {
|
|
component_args = JSON.parse(args_string);
|
|
} catch (e) {
|
|
console.error(`[JQHTML Integration] Failed to parse component args for ${component_name}:`, e);
|
|
component_args = {};
|
|
}
|
|
}
|
|
if (component_name) {
|
|
// Transform $ prefixed keys to data- attributes
|
|
let component_args_filtered = {};
|
|
for (const [key, value] of Object.entries(component_args)) {
|
|
// if (key.startsWith('$')) {
|
|
// component_args_filtered[key.substring(1)] = value;
|
|
// } else
|
|
if (key.startsWith('data-')) {
|
|
component_args_filtered[key.substring(5)] = value;
|
|
} else {
|
|
component_args_filtered[key] = value;
|
|
}
|
|
}
|
|
try {
|
|
// Store inner HTML as string for nested component processing
|
|
component_args_filtered._inner_html = $element.html();
|
|
$element.empty();
|
|
|
|
// Remove the init class before instantiation to prevent re-initialization
|
|
$element.removeClass('Component_Init');
|
|
|
|
// Create promise for this component's initialization
|
|
const component_promise = new Promise(resolve => {
|
|
// Use jQuery component plugin to create the component
|
|
// Plugin handles element internally, just pass args
|
|
// Get the updated $element from
|
|
let component = $element.component(component_name, component_args_filtered);
|
|
component.on('render', function () {
|
|
// Recursively collect promises from nested components
|
|
|
|
// Getting the updated component here - if the tag name was not div, the element would have been recreated, so we need to get the element set on the component, not from our earlier selector
|
|
|
|
const nested_promises = Jqhtml_Integration._on_framework_modules_init(component.$);
|
|
promises.push(...nested_promises);
|
|
|
|
// Resolve this component's promise
|
|
resolve();
|
|
}).$;
|
|
});
|
|
promises.push(component_promise);
|
|
} catch (error) {
|
|
console.error(`[JQHTML Integration] Failed to initialize component ${component_name}:`, error);
|
|
console.error('Error details:', error.stack || error);
|
|
}
|
|
}
|
|
});
|
|
|
|
// Top-level call: spawn async handler to wait for all promises, then trigger event
|
|
if (is_top_level) {
|
|
(async () => {
|
|
await Promise.all(promises);
|
|
await Rsx._rsx_call_all_classes('on_jqhtml_ready');
|
|
Rsx.trigger('jqhtml_ready');
|
|
})();
|
|
return;
|
|
}
|
|
|
|
// Recursive call: return promises for parent to collect
|
|
return promises;
|
|
}
|
|
|
|
/**
|
|
* Get all registered component names
|
|
* @returns {Array<string>} Array of component names
|
|
*/
|
|
static get_component_names() {
|
|
return jqhtml.get_component_names();
|
|
}
|
|
|
|
/**
|
|
* Check if a component is registered
|
|
* @param {string} name Component name
|
|
* @returns {boolean} True if component is registered
|
|
*/
|
|
static has_component(name) {
|
|
return jqhtml.has_component(name);
|
|
}
|
|
}
|
|
|
|
// RSX manifest automatically makes classes global - no manual assignment needed
|
|
|
|
|
|
/* === rsx/theme/components/datagrid/datagrid_abstract.js (babel) === */
|
|
"use strict";
|
|
|
|
/**
|
|
* DataGrid Component (Phase 1)
|
|
*
|
|
* Due to the more dynamic nature of this component, we are handling load / render lifecycles
|
|
* directly in this class rather than using the on_load lifecycle event
|
|
*
|
|
* **Features**:
|
|
* - Ajax data fetching
|
|
* - Sorting (click headers)
|
|
* - Pagination (next/prev/page select)
|
|
* - Row selection (checkboxes)
|
|
* - CSV export (selected rows, current page)
|
|
* - URL state synchronization
|
|
*
|
|
* **Usage**:
|
|
* ```html
|
|
* <Contacts_DataGrid $api="Frontend_Contacts_Controller" />
|
|
* ```
|
|
*
|
|
* **Required Args**:
|
|
* - `api` - Controller class name with datagrid_fetch() Ajax endpoint
|
|
*
|
|
* **Optional Args**:
|
|
* - `per_page` - Default rows per page (default: 25)
|
|
* - `sort` - Default sort column (default: first column)
|
|
* - `order` - Default sort order (default: 'asc')
|
|
*/
|
|
class DataGrid_Abstract extends Component {
|
|
// Initialize data before first render
|
|
on_create() {
|
|
let that = this;
|
|
|
|
// Initialize data state immediately so template can render
|
|
that.data.rows = [];
|
|
that.data.loading = true;
|
|
that.data.is_empty = false;
|
|
that.data.loaded = false;
|
|
that.data.total_pages = 0;
|
|
}
|
|
|
|
// Calls when datagrid first initialized
|
|
async on_ready() {
|
|
var _that$args$per_page, _that$args$sort, _that$args$order;
|
|
let that = this;
|
|
if (!that.args.data_source) {
|
|
console.error('Datagrid ' + that.component_name() + ' requires args.data_source set to a Ajax_Endpoint object');
|
|
return;
|
|
}
|
|
|
|
// Store defaults for later comparison
|
|
that.data.default_page = 1;
|
|
that.data.default_per_page = (_that$args$per_page = that.args.per_page) !== null && _that$args$per_page !== void 0 ? _that$args$per_page : 15;
|
|
that.data.default_sort = (_that$args$sort = that.args.sort) !== null && _that$args$sort !== void 0 ? _that$args$sort : null;
|
|
that.data.default_order = (_that$args$order = that.args.order) !== null && _that$args$order !== void 0 ? _that$args$order : 'asc';
|
|
that.data.default_filter = '';
|
|
|
|
// Set configured values
|
|
that.data.per_page = that.data.default_per_page;
|
|
|
|
// Initialize state from URL hash if present, otherwise use defaults
|
|
const hash_page = Rsx.get_page_state(that._cid + '_page');
|
|
const hash_sort = Rsx.get_page_state(that._cid + '_sort');
|
|
const hash_order = Rsx.get_page_state(that._cid + '_order');
|
|
const hash_filter = Rsx.get_page_state(that._cid + '_filter');
|
|
that.data.page = hash_page ? int(hash_page) : that.data.default_page;
|
|
that.data.sort = hash_sort || that.data.default_sort;
|
|
that.data.order = hash_order || that.data.default_order;
|
|
that.data.filter = hash_filter || that.data.default_filter;
|
|
that.register_render_callbacks();
|
|
that.register_filter_handlers();
|
|
|
|
// If hash had a filter value, populate the filter input
|
|
if (that.data.filter) {
|
|
const $filter = that.$sid('filter_input');
|
|
if ($filter && $filter.length > 0) {
|
|
$filter.val(that.data.filter);
|
|
}
|
|
}
|
|
|
|
// Measure row height and set fixed tbody height (all in one frame)
|
|
await that.measure_and_set_fixed_height();
|
|
|
|
// Fetch the initial page (respects hash state)
|
|
that.load_page(that.data.page);
|
|
}
|
|
|
|
// Update header only if sort/order changed
|
|
update_header() {
|
|
let that = this;
|
|
|
|
// Track last rendered state
|
|
if (!that._last_header_state) {
|
|
that._last_header_state = {};
|
|
}
|
|
const current = {
|
|
sort: that.data.sort,
|
|
order: that.data.order
|
|
};
|
|
|
|
// Only render if values changed
|
|
if (that._last_header_state.sort !== current.sort || that._last_header_state.order !== current.order) {
|
|
that._last_header_state = current;
|
|
that.id('datagrid_table_header').render();
|
|
}
|
|
}
|
|
|
|
// Update pagination only if values changed
|
|
update_pagination() {
|
|
let that = this;
|
|
|
|
// Track last rendered state
|
|
if (!that._last_pagination_state) {
|
|
that._last_pagination_state = {};
|
|
}
|
|
const current = {
|
|
page: that.data.page,
|
|
per_page: that.data.per_page,
|
|
total: that.data.total,
|
|
total_pages: that.data.total_pages
|
|
};
|
|
|
|
// Only render if values changed
|
|
if (that._last_pagination_state.page !== current.page || that._last_pagination_state.per_page !== current.per_page || that._last_pagination_state.total !== current.total || that._last_pagination_state.total_pages !== current.total_pages) {
|
|
that._last_pagination_state = current;
|
|
that.id('pagination_info').render();
|
|
that.id('pagination_controls').render();
|
|
}
|
|
}
|
|
|
|
// Load data for specified page and re-render data
|
|
async load_page(page) {
|
|
let that = this;
|
|
|
|
// Set loading state
|
|
that.data.loading = true;
|
|
that.data.page = page;
|
|
|
|
// Update UI with requested values (optimistic update)
|
|
that.update_header();
|
|
that.update_pagination();
|
|
|
|
// Only render loading state if no data yet (initial load)
|
|
if (that.data.rows.length === 0) {
|
|
that.id('datagrid_table_body').render();
|
|
}
|
|
const response = await Ajax.call(that.args.data_source, {
|
|
page: page,
|
|
per_page: that.data.per_page,
|
|
sort: that.data.sort,
|
|
order: that.data.order,
|
|
filter: that.data.filter
|
|
});
|
|
|
|
// Update data
|
|
that.data.loading = false;
|
|
that.data.loaded = true;
|
|
that.data.rows = response.records;
|
|
that.data.page = response.page;
|
|
that.data.per_page = response.per_page;
|
|
that.data.total = response.total;
|
|
that.data.total_pages = response.total_pages;
|
|
that.data.sort = response.sort;
|
|
that.data.order = response.order;
|
|
that.data.is_empty = response.records.length === 0;
|
|
|
|
// Persist state to URL hash for bookmarking/sharing
|
|
// Only set values that differ from defaults (null removes the key)
|
|
const state = {};
|
|
state[that._cid + '_page'] = that.data.page !== that.data.default_page ? that.data.page : null;
|
|
state[that._cid + '_sort'] = that.data.sort !== that.data.default_sort ? that.data.sort : null;
|
|
state[that._cid + '_order'] = that.data.order !== that.data.default_order ? that.data.order : null;
|
|
state[that._cid + '_filter'] = that.data.filter !== that.data.default_filter ? that.data.filter : null;
|
|
Rsx.set_all_page_state(state);
|
|
|
|
// Update UI with server response (only renders if changed)
|
|
that.id('datagrid_table_body').render();
|
|
that.update_header();
|
|
that.update_pagination();
|
|
|
|
// Scroll to top of datagrid if it's not currently visible
|
|
that.scroll_to_top_if_needed();
|
|
}
|
|
|
|
// The callbacks in this function fire after each targeted component re-renders
|
|
register_render_callbacks() {
|
|
let that = this;
|
|
|
|
// Attach row click handler - re-runs every time datagrid_table_body renders
|
|
that.id('datagrid_table_body').on('render', function () {
|
|
console.log('DGTB_R');
|
|
// Step 1: Wrap cells in data-href rows with anchor tags
|
|
$(this).find('tr[data-href]').each(function () {
|
|
let $row = $(this);
|
|
let href = $row.attr('data-href');
|
|
$row.find('td').each(function () {
|
|
// let $col = $(this);
|
|
// // Skip if cell already contains interactive elements
|
|
// if ($col.find('a, button, input, select, textarea').length > 0) {
|
|
// return;
|
|
// }
|
|
// // Wrap entire cell contents in an anchor (preserve DOM nodes for component lifecycle)
|
|
// let $anchor = $('<a>', {
|
|
// href: href,
|
|
// class: 'datagrid-row-link'
|
|
// });
|
|
// // Move existing child nodes into anchor (preserves components and their state)
|
|
// $col.contents().appendTo($anchor);
|
|
// // Add anchor to cell
|
|
// $col.append($anchor);
|
|
});
|
|
});
|
|
|
|
// Step 2: Find all cells with single anchor as only child and apply full-width styling
|
|
$(this).find('td').each(function () {
|
|
let $col = $(this);
|
|
let $children = $col.children();
|
|
|
|
// Check if cell contains exactly one direct child that is an anchor
|
|
if ($children.length === 1 && $children.first().is('a')) {
|
|
// Add class to transfer padding from cell to anchor
|
|
$col.addClass('has-full-link');
|
|
}
|
|
// Check if cell contains only text (no child elements)
|
|
else if ($children.length === 0) {
|
|
// Add class to apply vertical padding to text-only cells
|
|
$col.addClass('has-only-text');
|
|
}
|
|
});
|
|
});
|
|
|
|
// Attach sortable header click handler - re-runs every time datagrid_table_header renders
|
|
that.id('datagrid_table_header').on('render', function () {
|
|
// Transform th[data-sortby] elements by wrapping contents in clickable link
|
|
$(this).find('th[data-sortby]').each(function () {
|
|
let $th = $(this);
|
|
let sortby = $th.attr('data-sortby');
|
|
|
|
// TODO: Find out why this on('render') callback is being called twice/on already-processed HTML
|
|
// This unwrap logic shouldn't be necessary - template should render fresh each time
|
|
// For now, unwrap already-wrapped content to prevent double-wrapping
|
|
let $existing_link = $th.find('a.sortable-header');
|
|
let contents;
|
|
if ($existing_link.length > 0) {
|
|
// Unwrap - get the text content without the wrapper and arrows
|
|
contents = $existing_link.clone().find('i.bi').remove().end().html();
|
|
} else {
|
|
contents = $th.html();
|
|
}
|
|
|
|
// Build the arrow icon HTML if this column is currently sorted
|
|
let arrow = '';
|
|
if (that.data.sort === sortby) {
|
|
arrow = that.data.order === 'desc' ? '<i class="bi bi-chevron-up ms-1"></i>' : '<i class="bi bi-chevron-down ms-1"></i>';
|
|
}
|
|
|
|
// Replace contents with wrapped link (fresh wrapper every time)
|
|
$th.html(`<a href="#" class="sortable-header" data-sortby="${sortby}">${contents}${arrow}</a>`);
|
|
});
|
|
|
|
// Attach click handlers to the sortable links we just created
|
|
$(this).find('a.sortable-header[data-sortby]').on('click', function (e) {
|
|
e.preventDefault();
|
|
const sortby = $(this).attr('data-sortby');
|
|
that.sort_by(sortby);
|
|
});
|
|
});
|
|
|
|
// Attach pagination click handler - re-runs every time pagination_controls renders
|
|
that.id('pagination_controls').on('render', function () {
|
|
$(this).find('.page-link').on('click', function (e) {
|
|
e.preventDefault();
|
|
const $link = $(this);
|
|
const page = int($link.attr('data-page'));
|
|
|
|
// Ignore disabled/ellipsis clicks
|
|
if (!page || isNaN(page) || $link.parent().hasClass('disabled')) {
|
|
return;
|
|
}
|
|
|
|
// Load the requested page
|
|
that.load_page(page);
|
|
});
|
|
});
|
|
|
|
// Attach clear filter button handler - re-runs every time datagrid_table_body renders
|
|
that.id('datagrid_table_body').on('render', function () {
|
|
const $clear_btn = that.$sid('clear_filter_btn');
|
|
if ($clear_btn && $clear_btn.length > 0) {
|
|
$clear_btn.on('click', function (e) {
|
|
e.preventDefault();
|
|
that.clear_filter();
|
|
});
|
|
}
|
|
});
|
|
}
|
|
|
|
// Sort by specified column, toggling order if already sorted by that column
|
|
sort_by(column) {
|
|
let that = this;
|
|
|
|
// Toggle order if clicking same column, otherwise default to asc
|
|
if (that.data.sort === column) {
|
|
that.data.order = that.data.order === 'asc' ? 'desc' : 'asc';
|
|
} else {
|
|
that.data.sort = column;
|
|
that.data.order = 'asc';
|
|
}
|
|
|
|
// Reload current page with new sort
|
|
that.id('datagrid_table_header').render();
|
|
that.load_page(that.data.page);
|
|
}
|
|
|
|
// Register filter input handlers
|
|
register_filter_handlers() {
|
|
let that = this;
|
|
|
|
// Find filter input by common identifiers
|
|
let $filter = that.$sid('filter_input');
|
|
if (!$filter || $filter.length === 0) {
|
|
$filter = that.$.find('input[type="search"], input[type="text"].filter-input');
|
|
}
|
|
if ($filter && $filter.length > 0) {
|
|
$filter.on('input keyup', function () {
|
|
const filter_value = $(this).val();
|
|
that.filter_changed(filter_value);
|
|
});
|
|
}
|
|
}
|
|
filter_changed(filter) {
|
|
let that = this;
|
|
that.data.filter = filter;
|
|
that.load_page(1);
|
|
}
|
|
|
|
// Scroll to datagrid top if the top edge is not currently visible in viewport
|
|
scroll_to_top_if_needed() {
|
|
let that = this;
|
|
const $datagrid = that.$;
|
|
const datagridTop = $datagrid.offset().top;
|
|
const scrollTop = $(window).scrollTop();
|
|
|
|
// If datagrid top is above the current viewport, scroll to show it
|
|
if (datagridTop < scrollTop) {
|
|
// If datagrid is within 300px of page top, scroll to 0
|
|
if (datagridTop <= 300) {
|
|
window.scrollTo({
|
|
top: 0,
|
|
behavior: 'instant'
|
|
});
|
|
} else {
|
|
// Scroll to 20px above datagrid
|
|
window.scrollTo({
|
|
top: datagridTop - 20,
|
|
behavior: 'instant'
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
// Measure actual row height and set fixed tbody min-height
|
|
// All happens in one animation frame so user doesn't see it
|
|
async measure_and_set_fixed_height() {
|
|
let that = this;
|
|
|
|
// Wait for next animation frame to ensure DOM is ready
|
|
await sleep(0);
|
|
const $tbody = that.id('datagrid_table_body').$;
|
|
|
|
// Temporarily render a single measurement row
|
|
const $measurement_row = $('<tr>').css('visibility', 'hidden').html('<td>Measuring...</td>');
|
|
$tbody.append($measurement_row);
|
|
|
|
// Measure the row height
|
|
const row_height = $measurement_row.outerHeight();
|
|
|
|
// Remove measurement row
|
|
$measurement_row.remove();
|
|
|
|
// Calculate and set min-height based on per_page
|
|
const min_height = row_height * that.data.per_page;
|
|
$tbody.css('min-height', min_height + 'px');
|
|
|
|
// Store for future reference
|
|
that.data.row_height = row_height;
|
|
that.data.tbody_min_height = min_height;
|
|
}
|
|
|
|
// Clear filter and reset to page 1
|
|
clear_filter() {
|
|
let that = this;
|
|
that.data.filter = '';
|
|
|
|
// Clear the filter input
|
|
const $filter = that.$sid('filter_input');
|
|
if ($filter && $filter.length > 0) {
|
|
$filter.val('');
|
|
}
|
|
|
|
// Reload from page 1
|
|
that.load_page(1);
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Activity_Feed.js (babel) === */
|
|
"use strict";
|
|
|
|
class Activity_Feed extends Component {
|
|
async on_load() {
|
|
if (this.args.data_source) {
|
|
const response = await fetch(this.args.data_source);
|
|
this.data.activities = await response.json();
|
|
} else if (this.args.activities) {
|
|
this.data.activities = this.args.activities;
|
|
}
|
|
}
|
|
on_ready() {
|
|
// Optional: Auto-refresh
|
|
if (this.args.auto_refresh) {
|
|
this.start_auto_refresh();
|
|
}
|
|
}
|
|
start_auto_refresh() {
|
|
const interval = this.args.refresh_interval || 30000; // Default 30 seconds
|
|
|
|
this.refresh_timer = setInterval(() => {
|
|
this.reload_data();
|
|
}, interval);
|
|
}
|
|
stop_auto_refresh() {
|
|
if (this.refresh_timer) {
|
|
clearInterval(this.refresh_timer);
|
|
this.refresh_timer = null;
|
|
}
|
|
}
|
|
async reload_data() {
|
|
if (this.args.data_source) {
|
|
const response = await fetch(this.args.data_source);
|
|
this.data.activities = await response.json();
|
|
this.render();
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Actor_Reference.js (babel) === */
|
|
"use strict";
|
|
|
|
class Actor_Reference extends Component {
|
|
// Pure Bootstrap styling - no JavaScript needed
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Advanced_Search_Panel.js (babel) === */
|
|
"use strict";
|
|
|
|
class Advanced_Search_Panel extends Component {
|
|
on_ready() {
|
|
// Populate dropdowns if provided
|
|
if (this.args.categories) {
|
|
this.$sid('category').set_options(this.args.categories);
|
|
}
|
|
if (this.args.tags) {
|
|
this.$sid('tags').set_options(this.args.tags);
|
|
}
|
|
|
|
// Search button
|
|
this.$sid('search_btn').on('click', e => {
|
|
e.preventDefault();
|
|
this.perform_search();
|
|
});
|
|
|
|
// Reset button
|
|
this.$sid('reset_btn').on('click', e => {
|
|
e.preventDefault();
|
|
this.reset();
|
|
});
|
|
|
|
// Close button
|
|
this.$sid('close_btn').on('click', () => {
|
|
if (this.args.on_close) {
|
|
this.args.on_close();
|
|
} else {
|
|
this.$.hide();
|
|
}
|
|
});
|
|
|
|
// Form submit
|
|
this.$sid('search_form').on('submit', e => {
|
|
e.preventDefault();
|
|
this.perform_search();
|
|
});
|
|
}
|
|
perform_search() {
|
|
const criteria = {
|
|
keywords: this.$sid('keywords').get_value(),
|
|
category: this.$sid('category').get_value(),
|
|
tags: this.$sid('tags').get_value(),
|
|
from_date: this.$sid('from_date').get_value(),
|
|
to_date: this.$sid('to_date').get_value(),
|
|
sort_by: this.$sid('sort_by').val(),
|
|
exact_match: this.$sid('exact_match').is(':checked')
|
|
};
|
|
|
|
// Remove empty values
|
|
Object.keys(criteria).forEach(key => {
|
|
if (!criteria[key] || is_array(criteria[key]) && criteria[key].length === 0) {
|
|
delete criteria[key];
|
|
}
|
|
});
|
|
if (this.args.on_search) {
|
|
this.args.on_search(criteria);
|
|
}
|
|
}
|
|
reset() {
|
|
this.$sid('keywords').set_value('');
|
|
this.$sid('category').set_value('');
|
|
this.$sid('tags').set_value([]);
|
|
this.$sid('from_date').set_value('');
|
|
this.$sid('to_date').set_value('');
|
|
this.$sid('sort_by').val('relevance');
|
|
this.$sid('exact_match').prop('checked', false);
|
|
if (this.args.on_reset) {
|
|
this.args.on_reset();
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Alert_Banner.js (babel) === */
|
|
"use strict";
|
|
|
|
class Alert_Banner extends Component {
|
|
on_ready() {
|
|
// Apply type from args (success, danger, warning, info)
|
|
if (this.args.type) {
|
|
this.$.removeClass('alert-info').addClass(`alert-${this.args.type}`);
|
|
}
|
|
|
|
// Remove dismissible if not needed
|
|
if (this.args.dismissible === false) {
|
|
this.$.removeClass('alert-dismissible');
|
|
this.$.find('.btn-close').remove();
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Avatar.js (babel) === */
|
|
"use strict";
|
|
|
|
class Avatar extends Component {
|
|
on_ready() {
|
|
// Set src from args
|
|
if (this.args.src) {
|
|
this.$.attr('src', this.args.src);
|
|
}
|
|
|
|
// Set size (xs, sm, md, lg, xl)
|
|
const size = this.args.size || 'md';
|
|
const size_map = {
|
|
'xs': '24px',
|
|
'sm': '32px',
|
|
'md': '48px',
|
|
'lg': '64px',
|
|
'xl': '96px'
|
|
};
|
|
this.$.css({
|
|
'width': size_map[size],
|
|
'height': size_map[size],
|
|
'object-fit': 'cover'
|
|
});
|
|
|
|
// Alternative rendering: show initials when no image source provided
|
|
if (!this.args.src && this.args.name) {
|
|
this.show_initials(this.args.name);
|
|
}
|
|
}
|
|
show_initials(name) {
|
|
// Convert img to div with initials
|
|
const initials = name.split(' ').map(n => n[0]).join('').toUpperCase().slice(0, 2);
|
|
const $div = $('<div>').addClass('rounded-circle d-flex align-items-center justify-content-center bg-primary text-white fw-bold').css({
|
|
'width': this.$.css('width'),
|
|
'height': this.$.css('height')
|
|
}).text(initials);
|
|
this.$.replaceWith($div);
|
|
this.$ = $div;
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Blockquote.js (babel) === */
|
|
"use strict";
|
|
|
|
class Blockquote extends Component {
|
|
on_ready() {
|
|
// No special behavior
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Breadcrumbs.js (babel) === */
|
|
"use strict";
|
|
|
|
class Breadcrumbs extends Component {
|
|
// Placeholder component - currently empty in dashboard usage
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Bulk_Action_Bar.js (babel) === */
|
|
"use strict";
|
|
|
|
class Bulk_Action_Bar extends Component {
|
|
on_ready() {
|
|
// Clear selection on close
|
|
this.$sid('close_btn').on('click', () => {
|
|
this.$.hide();
|
|
// Uncheck all boxes
|
|
const $table = this.$.closest('.card').find('table');
|
|
$table.find('input[type="checkbox"]').prop('checked', false);
|
|
});
|
|
}
|
|
set_count(count) {
|
|
this.$.find('.count').text(count);
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Bulk_Selection.js (babel) === */
|
|
"use strict";
|
|
|
|
class Bulk_Selection extends Component {
|
|
on_ready() {
|
|
const $checkbox = this.$sid('checkbox');
|
|
|
|
// Toggle all checkboxes in table body
|
|
$checkbox.on('change', e => {
|
|
const checked = e.target.checked;
|
|
const $table = this.$.closest('table');
|
|
$table.find('tbody input[type="checkbox"]').prop('checked', checked);
|
|
|
|
// Trigger update event
|
|
if (this.args.on_change) {
|
|
this.args.on_change(checked);
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/button_group.js (babel) === */
|
|
"use strict";
|
|
|
|
class Button_Group extends Component {
|
|
// Container for grouped buttons with connected borders
|
|
// Bootstrap btn-group handles all visual grouping
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/button_primary.js (babel) === */
|
|
"use strict";
|
|
|
|
class Button_Primary extends Component {
|
|
// Primary action button - highest visual hierarchy
|
|
// Bootstrap btn-primary provides all styling
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/button_secondary.js (babel) === */
|
|
"use strict";
|
|
|
|
class Button_Secondary extends Component {
|
|
// Secondary action button - lower prominence than primary
|
|
// Bootstrap btn-secondary provides gray color scheme
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/button.js (babel) === */
|
|
"use strict";
|
|
|
|
class Button extends Component {
|
|
// Base button component - no special behavior needed
|
|
// Bootstrap handles all states (hover, active, focus, disabled)
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Calendar_Event.js (babel) === */
|
|
"use strict";
|
|
|
|
class Calendar_Event extends Component {
|
|
on_ready() {
|
|
if (this.args.on_click) {
|
|
this.$.on('click', () => {
|
|
this.args.on_click(this.args);
|
|
});
|
|
}
|
|
|
|
// Hover effect
|
|
this.$.on('mouseenter', () => {
|
|
this.$.addClass('shadow-sm');
|
|
});
|
|
this.$.on('mouseleave', () => {
|
|
this.$.removeClass('shadow-sm');
|
|
});
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Calendar_Grid.js (babel) === */
|
|
"use strict";
|
|
|
|
class Calendar_Grid extends Component {
|
|
on_ready() {
|
|
this.current_date = new Date();
|
|
this.render_calendar();
|
|
this.$sid('prev_btn').on('click', () => {
|
|
this.current_date.setMonth(this.current_date.getMonth() - 1);
|
|
this.render_calendar();
|
|
});
|
|
this.$sid('next_btn').on('click', () => {
|
|
this.current_date.setMonth(this.current_date.getMonth() + 1);
|
|
this.render_calendar();
|
|
});
|
|
this.$sid('today_btn').on('click', () => {
|
|
this.current_date = new Date();
|
|
this.render_calendar();
|
|
});
|
|
}
|
|
render_calendar() {
|
|
const year = this.current_date.getFullYear();
|
|
const month = this.current_date.getMonth();
|
|
|
|
// Update title
|
|
const month_names = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
|
|
this.$sid('month_title').text(`${month_names[month]} ${year}`);
|
|
|
|
// Get first day of month and total days
|
|
const first_day = new Date(year, month, 1).getDay();
|
|
const days_in_month = new Date(year, month + 1, 0).getDate();
|
|
const $tbody = this.$sid('calendar_body');
|
|
$tbody.empty();
|
|
let day = 1;
|
|
let $tr = null;
|
|
|
|
// Build calendar grid
|
|
for (let i = 0; i < 6; i++) {
|
|
$tr = $('<tr>');
|
|
for (let j = 0; j < 7; j++) {
|
|
const $td = $('<td>').css({
|
|
'height': '100px',
|
|
'vertical-align': 'top',
|
|
'padding': '8px'
|
|
});
|
|
if (i === 0 && j < first_day) {
|
|
// Empty cell before month starts
|
|
$td.addClass('bg-light');
|
|
} else if (day > days_in_month) {
|
|
// Empty cell after month ends
|
|
$td.addClass('bg-light');
|
|
} else {
|
|
// Day cell
|
|
const $day_num = $('<div>').addClass('fw-bold mb-2').text(day);
|
|
|
|
// Highlight today
|
|
const today = new Date();
|
|
if (day === today.getDate() && month === today.getMonth() && year === today.getFullYear()) {
|
|
$day_num.addClass('text-primary');
|
|
$td.addClass('border-primary');
|
|
}
|
|
$td.append($day_num);
|
|
|
|
// Add events for this day if provided
|
|
if (this.args.events) {
|
|
const events = this.get_events_for_date(year, month, day);
|
|
events.forEach(event => {
|
|
const $event = $('<div>').addClass('badge bg-primary text-truncate w-100 mb-1 text-start').css('cursor', 'pointer').text(event.title);
|
|
$event.on('click', () => {
|
|
if (this.args.on_event_click) {
|
|
this.args.on_event_click(event);
|
|
}
|
|
});
|
|
$td.append($event);
|
|
});
|
|
}
|
|
$td.attr('data-date', `${year}-${str(month + 1).padStart(2, '0')}-${str(day).padStart(2, '0')}`);
|
|
$td.css('cursor', 'pointer');
|
|
$td.on('click', e => {
|
|
if (this.args.on_date_click && !$(e.target).hasClass('badge')) {
|
|
this.args.on_date_click($td.attr('data-date'));
|
|
}
|
|
});
|
|
day++;
|
|
}
|
|
$tr.append($td);
|
|
}
|
|
$tbody.append($tr);
|
|
if (day > days_in_month) break;
|
|
}
|
|
}
|
|
get_events_for_date(year, month, day) {
|
|
if (!this.args.events) return [];
|
|
const date_str = `${year}-${str(month + 1).padStart(2, '0')}-${str(day).padStart(2, '0')}`;
|
|
return this.args.events.filter(event => {
|
|
return event.date === date_str;
|
|
});
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Card.js (babel) === */
|
|
"use strict";
|
|
|
|
/**
|
|
* Card - Bootstrap 5 Content Container Component
|
|
*
|
|
* Purpose: Primary content container using Bootstrap .card class
|
|
* Design: Pure Bootstrap - border-0 with shadow for modern Volt aesthetic
|
|
*/
|
|
class Card extends Component {
|
|
// Card is a pure container component - no lifecycle methods needed
|
|
// All styling comes from Bootstrap classes: card, border-0, shadow
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Chart_Component.js (babel) === */
|
|
"use strict";
|
|
|
|
class Chart_Component extends Component {
|
|
// Placeholder component - no functionality yet
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Checkbox.js (babel) === */
|
|
"use strict";
|
|
|
|
/**
|
|
* Checkbox - Bootstrap 5 Checkbox Input Component
|
|
*
|
|
* Purpose: Single checkbox for yes/no, true/false selections
|
|
* Design: Bootstrap .form-check-input styling
|
|
* Wrapper: Typically used within <div class="form-check"> for proper layout
|
|
*/
|
|
class Checkbox extends Component {
|
|
on_ready() {
|
|
// Set checked state if provided
|
|
if (this.args.checked) {
|
|
this.$.prop('checked', true);
|
|
}
|
|
|
|
// Set value if provided
|
|
if (this.args.value) {
|
|
this.$.val(this.args.value);
|
|
}
|
|
|
|
// Add custom classes if provided
|
|
if (this.args.class) {
|
|
this.$.addClass(this.args.class);
|
|
}
|
|
|
|
// Set disabled state if provided
|
|
if (this.args.disabled) {
|
|
this.$.prop('disabled', true);
|
|
}
|
|
|
|
// Set required attribute if provided
|
|
if (this.args.required) {
|
|
this.$.prop('required', true);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Code_Block.js (babel) === */
|
|
"use strict";
|
|
|
|
class Code_Block extends Component {
|
|
on_ready() {
|
|
// No special behavior (syntax highlighting could be added later)
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Column_Visibility_Toggle.js (babel) === */
|
|
"use strict";
|
|
|
|
class Column_Visibility_Toggle extends Component {
|
|
on_ready() {
|
|
// Build column checkboxes
|
|
if (this.args.columns) {
|
|
this.build_menu(this.args.columns);
|
|
}
|
|
}
|
|
build_menu(columns) {
|
|
const $menu = this.$sid('menu');
|
|
$menu.empty();
|
|
columns.forEach((column, index) => {
|
|
const $li = $('<li>');
|
|
const $label = $('<label>').addClass('dropdown-item');
|
|
const $checkbox = $('<input>').addClass('form-check-input me-2').attr('type', 'checkbox').prop('checked', column.visible !== false).attr('data-column-index', index);
|
|
$label.append($checkbox).append(column.label || column.name);
|
|
$li.append($label);
|
|
$menu.append($li);
|
|
$checkbox.on('change', e => {
|
|
this.toggle_column(index, e.target.checked);
|
|
});
|
|
});
|
|
}
|
|
toggle_column(index, visible) {
|
|
if (this.args.on_toggle) {
|
|
this.args.on_toggle(index, visible);
|
|
}
|
|
|
|
// Find table and toggle column visibility
|
|
const $table = this.args.table ? $(this.args.table) : this.$.closest('.card').find('table');
|
|
const selector = `th:nth-child(${index + 1}), td:nth-child(${index + 1})`;
|
|
if (visible) {
|
|
$table.find(selector).show();
|
|
} else {
|
|
$table.find(selector).hide();
|
|
}
|
|
}
|
|
set_columns(columns) {
|
|
this.build_menu(columns);
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Comment_Thread.js (babel) === */
|
|
"use strict";
|
|
|
|
class Comment_Thread extends Component {
|
|
async on_load() {
|
|
if (this.args.data_source) {
|
|
const response = await fetch(this.args.data_source);
|
|
this.data.comments = await response.json();
|
|
} else if (this.args.comments) {
|
|
this.data.comments = this.args.comments;
|
|
}
|
|
}
|
|
on_ready() {
|
|
// Submit new comment
|
|
this.$sid('submit_btn').on('click', () => {
|
|
this.submit_comment();
|
|
});
|
|
|
|
// Reply buttons
|
|
this.$.find('.reply-btn').on('click', e => {
|
|
const $comment = $(e.target).closest('[data-comment-id]');
|
|
const comment_id = $comment.attr('data-comment-id');
|
|
this.show_reply_form(comment_id);
|
|
});
|
|
|
|
// Edit buttons
|
|
this.$.find('.edit-btn').on('click', e => {
|
|
const $comment = $(e.target).closest('[data-comment-id]');
|
|
const comment_id = $comment.attr('data-comment-id');
|
|
this.edit_comment(comment_id);
|
|
});
|
|
|
|
// Delete buttons
|
|
this.$.find('.delete-btn').on('click', e => {
|
|
const $comment = $(e.target).closest('[data-comment-id]');
|
|
const comment_id = $comment.attr('data-comment-id');
|
|
this.delete_comment(comment_id);
|
|
});
|
|
}
|
|
async submit_comment() {
|
|
const text = this.$sid('comment_input').val().trim();
|
|
if (!text) return;
|
|
if (this.args.on_submit) {
|
|
const result = await this.args.on_submit(text);
|
|
if (result) {
|
|
this.$sid('comment_input').val('');
|
|
await this.reload_data();
|
|
}
|
|
}
|
|
}
|
|
show_reply_form(comment_id) {
|
|
// TODO: Implement reply form UI
|
|
console.log('Reply to comment:', comment_id);
|
|
}
|
|
edit_comment(comment_id) {
|
|
if (this.args.on_edit) {
|
|
this.args.on_edit(comment_id);
|
|
}
|
|
}
|
|
async delete_comment(comment_id) {
|
|
if (!confirm('Delete this comment?')) return;
|
|
if (this.args.on_delete) {
|
|
const result = await this.args.on_delete(comment_id);
|
|
if (result) {
|
|
await this.reload_data();
|
|
}
|
|
}
|
|
}
|
|
async reload_data() {
|
|
if (this.args.data_source) {
|
|
const response = await fetch(this.args.data_source);
|
|
this.data.comments = await response.json();
|
|
this.render();
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Date_Picker.js (babel) === */
|
|
"use strict";
|
|
|
|
class Date_Picker extends Component {
|
|
on_ready() {
|
|
const $input = this.$sid('input');
|
|
if (this.args.value) {
|
|
$input.val(this.args.value);
|
|
}
|
|
if (this.args.name) {
|
|
$input.attr('name', this.args.name);
|
|
}
|
|
if (this.args.min) {
|
|
$input.attr('min', this.args.min);
|
|
}
|
|
if (this.args.max) {
|
|
$input.attr('max', this.args.max);
|
|
}
|
|
if (this.args.disabled) {
|
|
$input.prop('disabled', true);
|
|
}
|
|
if (this.args.readonly) {
|
|
$input.prop('readonly', true);
|
|
}
|
|
if (this.args.required) {
|
|
$input.prop('required', true);
|
|
}
|
|
if (this.args.on_change) {
|
|
$input.on('change', e => {
|
|
this.args.on_change(e.target.value);
|
|
});
|
|
}
|
|
}
|
|
get_value() {
|
|
return this.$sid('input').val();
|
|
}
|
|
set_value(value) {
|
|
this.$sid('input').val(value);
|
|
}
|
|
focus() {
|
|
this.$sid('input').focus();
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Dropdown_Menu.js (babel) === */
|
|
"use strict";
|
|
|
|
class Dropdown_Menu extends Component {
|
|
on_ready() {
|
|
// Wrap bare text children in <li><a> structure
|
|
const $menu = this.$sid('menu');
|
|
$menu.children().each(function () {
|
|
const $child = $(this);
|
|
if ($child.prop('tagName') !== 'LI') {
|
|
const text = $child.text();
|
|
const href = $child.attr('href') || '#';
|
|
const $li = $('<li>').append($('<a>').addClass('dropdown-item').attr('href', href).text(text));
|
|
$child.replaceWith($li);
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Empty_State.js (babel) === */
|
|
"use strict";
|
|
|
|
class Empty_State extends Component {
|
|
on_ready() {
|
|
// No special behavior
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Export_Button.js (babel) === */
|
|
"use strict";
|
|
|
|
class Export_Button extends Component {
|
|
on_ready() {
|
|
const that = this;
|
|
this.$.find('[data-format]').on('click', e => {
|
|
e.preventDefault();
|
|
const format = $(e.currentTarget).attr('data-format');
|
|
that.export_data(format);
|
|
});
|
|
}
|
|
async export_data(format) {
|
|
if (this.args.on_export) {
|
|
// Custom export handler
|
|
this.args.on_export(format);
|
|
} else if (this.args.data) {
|
|
// Auto-export provided data
|
|
this.auto_export(format, this.args.data);
|
|
} else if (this.args.export_url) {
|
|
// Fetch export from URL
|
|
const url = `${this.args.export_url}?format=${format}`;
|
|
window.location.href = url;
|
|
}
|
|
}
|
|
auto_export(format, data) {
|
|
if (format === 'csv') {
|
|
this.export_csv(data);
|
|
} else if (format === 'json') {
|
|
this.export_json(data);
|
|
} else {
|
|
console.warn('Auto-export only supports CSV and JSON. Implement custom handler for other formats.');
|
|
}
|
|
}
|
|
export_csv(data) {
|
|
if (data.length === 0) return;
|
|
|
|
// Generate CSV
|
|
const headers = Object.keys(data[0]);
|
|
let csv = headers.join(',') + '\n';
|
|
data.forEach(row => {
|
|
const values = headers.map(header => {
|
|
const value = row[header] || '';
|
|
return `"${str(value).replace(/"/g, '""')}"`;
|
|
});
|
|
csv += values.join(',') + '\n';
|
|
});
|
|
|
|
// Download
|
|
const blob = new Blob([csv], {
|
|
type: 'text/csv'
|
|
});
|
|
const url = window.URL.createObjectURL(blob);
|
|
const $a = $('<a>');
|
|
$a.attr('href', url);
|
|
$a.attr('download', `export_${Date.now()}.csv`);
|
|
$a[0].click();
|
|
window.URL.revokeObjectURL(url);
|
|
}
|
|
export_json(data) {
|
|
const json = json_encode(data);
|
|
const blob = new Blob([json], {
|
|
type: 'application/json'
|
|
});
|
|
const url = window.URL.createObjectURL(blob);
|
|
const $a = $('<a>');
|
|
$a.attr('href', url);
|
|
$a.attr('download', `export_${Date.now()}.json`);
|
|
$a[0].click();
|
|
window.URL.revokeObjectURL(url);
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/File_Upload.js (babel) === */
|
|
"use strict";
|
|
|
|
class File_Upload extends Component {
|
|
on_ready() {
|
|
const $input = this.$sid('file_input');
|
|
const $drop_zone = this.$sid('drop_zone');
|
|
if (this.args.accept) {
|
|
$input.attr('accept', this.args.accept);
|
|
}
|
|
if (this.args.multiple) {
|
|
$input.attr('multiple', true);
|
|
}
|
|
|
|
// Click to upload
|
|
$drop_zone.on('click', () => {
|
|
$input.click();
|
|
});
|
|
|
|
// File selected
|
|
$input.on('change', e => {
|
|
const files = e.target.files;
|
|
if (files.length > 0) {
|
|
this.handle_files(files);
|
|
}
|
|
});
|
|
|
|
// Drag and drop
|
|
$drop_zone.on('dragover', e => {
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
$drop_zone.addClass('border-primary bg-light');
|
|
});
|
|
$drop_zone.on('dragleave', e => {
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
$drop_zone.removeClass('border-primary bg-light');
|
|
});
|
|
$drop_zone.on('drop', e => {
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
$drop_zone.removeClass('border-primary bg-light');
|
|
const files = e.originalEvent.dataTransfer.files;
|
|
if (files.length > 0) {
|
|
this.handle_files(files);
|
|
}
|
|
});
|
|
|
|
// Remove button
|
|
this.$sid('remove_btn').on('click', e => {
|
|
e.stopPropagation();
|
|
this.clear();
|
|
});
|
|
}
|
|
handle_files(files) {
|
|
const file = files[0]; // Single file for now
|
|
|
|
// Validate file size
|
|
if (this.args.max_size_bytes && file.size > this.args.max_size_bytes) {
|
|
alert(`File is too large. Max size is ${this.format_size(this.args.max_size_bytes)}`);
|
|
return;
|
|
}
|
|
this.selected_file = file;
|
|
|
|
// Show file info
|
|
this.$sid('placeholder').hide();
|
|
this.$sid('file_info').show();
|
|
this.$sid('file_name').text(file.name);
|
|
this.$sid('file_size').text(this.format_size(file.size));
|
|
|
|
// Auto-upload if endpoint provided
|
|
if (this.args.upload_url) {
|
|
this.upload();
|
|
}
|
|
|
|
// Trigger callback
|
|
if (this.args.on_select) {
|
|
this.args.on_select(file);
|
|
}
|
|
}
|
|
async upload() {
|
|
if (!this.selected_file || !this.args.upload_url) return;
|
|
|
|
// Show progress
|
|
this.$sid('file_info').hide();
|
|
this.$sid('progress').show();
|
|
const form_data = new FormData();
|
|
form_data.append('file', this.selected_file);
|
|
try {
|
|
const response = await fetch(this.args.upload_url, {
|
|
method: 'POST',
|
|
body: form_data
|
|
});
|
|
const result = await response.json();
|
|
|
|
// Hide progress
|
|
this.$sid('progress').hide();
|
|
this.$sid('file_info').show();
|
|
if (this.args.on_upload) {
|
|
this.args.on_upload(result);
|
|
}
|
|
} catch (error) {
|
|
alert('Upload failed: ' + error.message);
|
|
this.$sid('progress').hide();
|
|
this.$sid('placeholder').show();
|
|
}
|
|
}
|
|
clear() {
|
|
this.selected_file = null;
|
|
this.$sid('file_input').val('');
|
|
this.$sid('file_info').hide();
|
|
this.$sid('progress').hide();
|
|
this.$sid('placeholder').show();
|
|
if (this.args.on_clear) {
|
|
this.args.on_clear();
|
|
}
|
|
}
|
|
get_file() {
|
|
return this.selected_file;
|
|
}
|
|
format_size(bytes) {
|
|
if (bytes < 1024) return bytes + ' B';
|
|
if (bytes < 1024 * 1024) return (bytes / 1024).toFixed(1) + ' KB';
|
|
return (bytes / (1024 * 1024)).toFixed(1) + ' MB';
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Filter_Bar.js (babel) === */
|
|
"use strict";
|
|
|
|
class Filter_Bar extends Component {
|
|
on_ready() {
|
|
this.active_filters = {};
|
|
|
|
// Populate status options if provided
|
|
if (this.args.status_options) {
|
|
const $status = this.$sid('status');
|
|
this.args.status_options.forEach(opt => {
|
|
$status.append($('<option>').val(opt.value).text(opt.label));
|
|
});
|
|
}
|
|
|
|
// Date range change handler
|
|
this.$sid('date_range').on('change', e => {
|
|
if (e.target.value === 'custom') {
|
|
this.$sid('custom_dates').show();
|
|
this.$sid('custom_dates_end').show();
|
|
} else {
|
|
this.$sid('custom_dates').hide();
|
|
this.$sid('custom_dates_end').hide();
|
|
}
|
|
});
|
|
|
|
// Search with debounce
|
|
let search_timeout;
|
|
this.$sid('search').$.find('input').on('input', e => {
|
|
clearTimeout(search_timeout);
|
|
search_timeout = setTimeout(() => {
|
|
this.add_filter('search', e.target.value);
|
|
}, 500);
|
|
});
|
|
|
|
// Apply button
|
|
this.$sid('apply_btn').on('click', () => {
|
|
this.apply_filters();
|
|
});
|
|
|
|
// Clear button
|
|
this.$sid('clear_btn').on('click', () => {
|
|
this.clear_filters();
|
|
});
|
|
}
|
|
add_filter(key, value) {
|
|
if (value) {
|
|
this.active_filters[key] = value;
|
|
} else {
|
|
delete this.active_filters[key];
|
|
}
|
|
this.update_filter_display();
|
|
}
|
|
apply_filters() {
|
|
// Collect all filter values
|
|
const search = this.$sid('search').get_value();
|
|
const status = this.$sid('status').val();
|
|
const date_range = this.$sid('date_range').val();
|
|
this.active_filters = {};
|
|
if (search) this.active_filters.search = search;
|
|
if (status) this.active_filters.status = status;
|
|
if (date_range) this.active_filters.date_range = date_range;
|
|
if (date_range === 'custom') {
|
|
const start_date = this.$sid('start_date').get_value();
|
|
const end_date = this.$sid('end_date').get_value();
|
|
if (start_date) this.active_filters.start_date = start_date;
|
|
if (end_date) this.active_filters.end_date = end_date;
|
|
}
|
|
this.update_filter_display();
|
|
if (this.args.on_apply) {
|
|
this.args.on_apply(this.active_filters);
|
|
}
|
|
}
|
|
clear_filters() {
|
|
this.active_filters = {};
|
|
this.$sid('search').set_value('');
|
|
this.$sid('status').val('');
|
|
this.$sid('date_range').val('');
|
|
this.$sid('custom_dates').hide();
|
|
this.$sid('custom_dates_end').hide();
|
|
this.update_filter_display();
|
|
if (this.args.on_clear) {
|
|
this.args.on_clear();
|
|
}
|
|
}
|
|
update_filter_display() {
|
|
const count = Object.keys(this.active_filters).length;
|
|
const $container = this.$sid('active_filters');
|
|
const $tags = this.$sid('filter_tags');
|
|
if (count === 0) {
|
|
$container.hide();
|
|
return;
|
|
}
|
|
$container.show();
|
|
$tags.empty();
|
|
for (let key in this.active_filters) {
|
|
const $tag = $('<span>').addClass('badge bg-primary me-1');
|
|
$tag.text(`${key}: ${this.active_filters[key]}`);
|
|
const $remove = $('<i>').addClass('bi bi-x-circle ms-1').css('cursor', 'pointer');
|
|
$remove.on('click', () => {
|
|
delete this.active_filters[key];
|
|
this.update_filter_display();
|
|
this.apply_filters();
|
|
});
|
|
$tag.append($remove);
|
|
$tags.append($tag);
|
|
}
|
|
}
|
|
get_filters() {
|
|
return this.active_filters;
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/form_actions_component.js (babel) === */
|
|
"use strict";
|
|
|
|
/**
|
|
* Form_Actions_Component - JQHTML Component
|
|
*
|
|
* Lifecycle methods are called in this order:
|
|
* 1. on_create() - Quick UI setup, runs bottom-up through component tree
|
|
* 2. on_load() - Fetch data from APIs (parallel execution, no DOM modifications)
|
|
* 3. on_ready() - Component fully initialized, runs bottom-up through component tree
|
|
*/
|
|
class Form_Actions_Component extends Component {
|
|
/**
|
|
* Called after render, quick UI setup (bottom-up)
|
|
* Use for: Initial state, event bindings, showing loading indicators
|
|
*/
|
|
async on_create() {
|
|
// Example: this.$sid('loading').show();
|
|
// Example: this.$.addClass('initializing');
|
|
}
|
|
|
|
/**
|
|
* Fetch data from APIs (parallel, NO DOM modifications)
|
|
* Use for: Loading data from server, fetching configurations
|
|
* WARNING: Do NOT modify DOM here - only load data
|
|
*/
|
|
async on_load() {
|
|
// Example: this.data.users = await Users_Controller.get_users_api();
|
|
// Example: this.data.config = await this.load_config();
|
|
// WARNING: Do NOT modify DOM here - only load data
|
|
}
|
|
|
|
/**
|
|
* Component fully initialized (bottom-up)
|
|
* Use for: Final UI setup, hiding loading indicators, starting animations
|
|
*/
|
|
async on_ready() {
|
|
// Example: this.$sid('loading').hide();
|
|
// Example: this.setup_event_listeners();
|
|
}
|
|
|
|
/**
|
|
* Click handler for the hello button
|
|
* Referenced in template via @click=this.on_click_hello
|
|
*/
|
|
on_click_hello() {
|
|
this.$sid('inner_html').hide();
|
|
this.$sid('hello_world').show();
|
|
}
|
|
|
|
// For more information: php artisan rsx:man jqhtml
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Form_Field_Group.js (babel) === */
|
|
"use strict";
|
|
|
|
class Form_Field_Group extends Component {
|
|
on_ready() {
|
|
// Optional: Add collapsible functionality
|
|
if (this.args.collapsible) {
|
|
this.make_collapsible();
|
|
}
|
|
}
|
|
make_collapsible() {
|
|
const $header = this.$.find('.card-header');
|
|
const $body = this.$.find('.card-body');
|
|
const collapse_id = 'collapse_' + Math.random().toString(36).substr(2, 9);
|
|
$body.attr('id', collapse_id).addClass('collapse show');
|
|
const $toggle = $('<button>').attr('type', 'button').addClass('btn btn-link btn-sm float-end text-decoration-none').attr('data-bs-toggle', 'collapse').attr('data-bs-target', '#' + collapse_id).html('<i class="bi bi-chevron-up"></i>');
|
|
$header.find('h5').append($toggle);
|
|
$body.on('show.bs.collapse', () => {
|
|
$toggle.html('<i class="bi bi-chevron-up"></i>');
|
|
});
|
|
$body.on('hide.bs.collapse', () => {
|
|
$toggle.html('<i class="bi bi-chevron-down"></i>');
|
|
});
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/form_group_component.js (babel) === */
|
|
"use strict";
|
|
|
|
/**
|
|
* Form_Group_Component - JQHTML Component
|
|
*
|
|
* Lifecycle methods are called in this order:
|
|
* 1. on_create() - Quick UI setup, runs bottom-up through component tree
|
|
* 2. on_load() - Fetch data from APIs (parallel execution, no DOM modifications)
|
|
* 3. on_ready() - Component fully initialized, runs bottom-up through component tree
|
|
*/
|
|
class Form_Group_Component extends Component {
|
|
/**
|
|
* Called after render, quick UI setup (bottom-up)
|
|
* Use for: Initial state, event bindings, showing loading indicators
|
|
*/
|
|
on_create() {
|
|
// Apply responsive column classes
|
|
const col_class = this.args.col_class || 'col-12 col-md-6 col-xl-4';
|
|
this.$.addClass(col_class + ' mb-3');
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/form_row_component.js (babel) === */
|
|
"use strict";
|
|
|
|
/**
|
|
* Form_Row_Component - JQHTML Component
|
|
*
|
|
* Lifecycle methods are called in this order:
|
|
* 1. on_create() - Quick UI setup, runs bottom-up through component tree
|
|
* 2. on_load() - Fetch data from APIs (parallel execution, no DOM modifications)
|
|
* 3. on_ready() - Component fully initialized, runs bottom-up through component tree
|
|
*/
|
|
class Form_Row_Component extends Component {
|
|
/**
|
|
* Called after render, quick UI setup (bottom-up)
|
|
* Use for: Initial state, event bindings, showing loading indicators
|
|
*/
|
|
async on_create() {
|
|
// Example: this.$sid('loading').show();
|
|
// Example: this.$.addClass('initializing');
|
|
}
|
|
|
|
/**
|
|
* Fetch data from APIs (parallel, NO DOM modifications)
|
|
* Use for: Loading data from server, fetching configurations
|
|
* WARNING: Do NOT modify DOM here - only load data
|
|
*/
|
|
async on_load() {
|
|
// Example: this.data.users = await Users_Controller.get_users_api();
|
|
// Example: this.data.config = await this.load_config();
|
|
// WARNING: Do NOT modify DOM here - only load data
|
|
}
|
|
|
|
/**
|
|
* Component fully initialized (bottom-up)
|
|
* Use for: Final UI setup, hiding loading indicators, starting animations
|
|
*/
|
|
async on_ready() {
|
|
// Example: this.$sid('loading').hide();
|
|
// Example: this.setup_event_listeners();
|
|
}
|
|
|
|
/**
|
|
* Click handler for the hello button
|
|
* Referenced in template via @click=this.on_click_hello
|
|
*/
|
|
on_click_hello() {
|
|
this.$sid('inner_html').hide();
|
|
this.$sid('hello_world').show();
|
|
}
|
|
|
|
// For more information: php artisan rsx:man jqhtml
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Form_Validation_Message.js (babel) === */
|
|
"use strict";
|
|
|
|
/**
|
|
* Form_Validation_Message - Bootstrap 5 Validation Feedback Component
|
|
*
|
|
* Purpose: Display validation feedback messages (success/error) below form inputs
|
|
* Design: Bootstrap .invalid-feedback (default) or .valid-feedback styling
|
|
* Visibility: Only shows when sibling input has .is-valid or .is-invalid class
|
|
*/
|
|
class Form_Validation_Message extends Component {
|
|
on_ready() {
|
|
// Add custom classes if provided (e.g., switching to valid-feedback)
|
|
if (this.args.class) {
|
|
// Replace default invalid-feedback with provided class
|
|
this.$.removeClass('invalid-feedback');
|
|
this.$.addClass(this.args.class);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Gantt_Chart.js (babel) === */
|
|
"use strict";
|
|
|
|
class Gantt_Chart extends Component {
|
|
async on_load() {
|
|
if (this.args.data_source) {
|
|
const response = await fetch(this.args.data_source);
|
|
const data = await response.json();
|
|
this.data.tasks = data.tasks;
|
|
this.data.months = data.months;
|
|
} else if (this.args.tasks) {
|
|
this.data.tasks = this.args.tasks;
|
|
this.data.months = this.args.months || this.generate_months();
|
|
}
|
|
}
|
|
generate_months() {
|
|
const months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
|
|
return months;
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/icon_button.js (babel) === */
|
|
"use strict";
|
|
|
|
class Icon_Button extends Component {
|
|
on_ready() {
|
|
// Add aria-label for accessibility (icon-only buttons need labels)
|
|
if (this.args.label) {
|
|
this.$.attr('aria-label', this.args.label);
|
|
}
|
|
|
|
// Add title for tooltip on hover
|
|
if (this.args.title) {
|
|
this.$.attr('title', this.args.title);
|
|
}
|
|
|
|
// Support custom button classes (btn-primary, btn-danger, etc.)
|
|
if (this.args.class) {
|
|
this.$.addClass(this.args.class);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Icon_With_Label.js (babel) === */
|
|
"use strict";
|
|
|
|
class Icon_With_Label extends Component {
|
|
on_ready() {
|
|
// No special behavior
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Icon_With_Text.js (babel) === */
|
|
"use strict";
|
|
|
|
class Icon_With_Text extends Component {
|
|
// Pure Bootstrap styling - no JavaScript needed
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/icon.js (babel) === */
|
|
"use strict";
|
|
|
|
class Icon extends Component {
|
|
// SVG icon container with size variants
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Info_Box.js (babel) === */
|
|
"use strict";
|
|
|
|
class Info_Box extends Component {
|
|
on_ready() {
|
|
// Apply color from args
|
|
if (this.args.color) {
|
|
this.$.removeClass('border-primary').addClass(`border-${this.args.color}`);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Inline_Edit_Field.js (babel) === */
|
|
"use strict";
|
|
|
|
class Inline_Edit_Field extends Component {
|
|
on_ready() {
|
|
this.current_value = this.args.value || '';
|
|
|
|
// Enter edit mode
|
|
this.$sid('display_mode').on('click', () => {
|
|
this.enter_edit_mode();
|
|
});
|
|
|
|
// Save
|
|
this.$sid('save_btn').on('click', () => {
|
|
this.save();
|
|
});
|
|
|
|
// Cancel
|
|
this.$sid('cancel_btn').on('click', () => {
|
|
this.cancel();
|
|
});
|
|
|
|
// Save on Enter, cancel on Escape
|
|
this.$sid('input').on('keydown', e => {
|
|
if (e.key === 'Enter') {
|
|
e.preventDefault();
|
|
this.save();
|
|
} else if (e.key === 'Escape') {
|
|
e.preventDefault();
|
|
this.cancel();
|
|
}
|
|
});
|
|
}
|
|
enter_edit_mode() {
|
|
const $input = this.$sid('input');
|
|
$input.val(this.current_value);
|
|
this.$sid('display_mode').hide();
|
|
this.$sid('edit_mode').show();
|
|
$input.focus();
|
|
$input.select();
|
|
}
|
|
exit_edit_mode() {
|
|
this.$sid('edit_mode').hide();
|
|
this.$sid('display_mode').show();
|
|
}
|
|
save() {
|
|
const new_value = this.$sid('input').val();
|
|
if (new_value === this.current_value) {
|
|
this.exit_edit_mode();
|
|
return;
|
|
}
|
|
|
|
// Trigger callback
|
|
if (this.args.on_save) {
|
|
const result = this.args.on_save(new_value, this.current_value);
|
|
|
|
// If callback returns false, don't save
|
|
if (result === false) {
|
|
return;
|
|
}
|
|
|
|
// If callback returns a promise, wait for it
|
|
if (result && typeof result.then === 'function') {
|
|
this.show_saving();
|
|
result.then(() => {
|
|
this.current_value = new_value;
|
|
this.update_display();
|
|
this.exit_edit_mode();
|
|
}).catch(() => {
|
|
this.exit_edit_mode();
|
|
});
|
|
return;
|
|
}
|
|
}
|
|
this.current_value = new_value;
|
|
this.update_display();
|
|
this.exit_edit_mode();
|
|
}
|
|
cancel() {
|
|
this.exit_edit_mode();
|
|
}
|
|
update_display() {
|
|
const display = this.current_value || this.args.placeholder || 'Click to edit';
|
|
this.$sid('value_display').text(display);
|
|
}
|
|
show_saving() {
|
|
this.$sid('save_btn').prop('disabled', true).html('<span class="spinner-border spinner-border-sm"></span>');
|
|
this.$sid('cancel_btn').prop('disabled', true);
|
|
}
|
|
get_value() {
|
|
return this.current_value;
|
|
}
|
|
set_value(value) {
|
|
this.current_value = value;
|
|
this.update_display();
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Input_With_Icon.js (babel) === */
|
|
"use strict";
|
|
|
|
class Input_With_Icon extends Component {
|
|
on_ready() {
|
|
const $input = this.$sid('input');
|
|
if (this.args.value) {
|
|
$input.val(this.args.value);
|
|
}
|
|
if (this.args.name) {
|
|
$input.attr('name', this.args.name);
|
|
}
|
|
if (this.args.disabled) {
|
|
$input.prop('disabled', true);
|
|
}
|
|
if (this.args.readonly) {
|
|
$input.prop('readonly', true);
|
|
}
|
|
if (this.args.on_change) {
|
|
$input.on('change', e => {
|
|
this.args.on_change(e.target.value);
|
|
});
|
|
}
|
|
if (this.args.on_input) {
|
|
$input.on('input', e => {
|
|
this.args.on_input(e.target.value);
|
|
});
|
|
}
|
|
}
|
|
get_value() {
|
|
return this.$sid('input').val();
|
|
}
|
|
set_value(value) {
|
|
this.$sid('input').val(value);
|
|
}
|
|
focus() {
|
|
this.$sid('input').focus();
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Input_With_Validation.js (babel) === */
|
|
"use strict";
|
|
|
|
class Input_With_Validation extends Component {
|
|
on_ready() {
|
|
const $input = this.$sid('input');
|
|
if (this.args.value) {
|
|
$input.val(this.args.value);
|
|
}
|
|
if (this.args.name) {
|
|
$input.attr('name', this.args.name);
|
|
}
|
|
if (this.args.required) {
|
|
$input.prop('required', true);
|
|
}
|
|
if (this.args.disabled) {
|
|
$input.prop('disabled', true);
|
|
}
|
|
if (this.args.readonly) {
|
|
$input.prop('readonly', true);
|
|
}
|
|
|
|
// Real-time validation
|
|
if (this.args.validate) {
|
|
$input.on('blur', () => {
|
|
this.validate();
|
|
});
|
|
$input.on('input', () => {
|
|
if (this.$.hasClass('was-validated')) {
|
|
this.validate();
|
|
}
|
|
});
|
|
}
|
|
if (this.args.on_change) {
|
|
$input.on('change', e => {
|
|
this.args.on_change(e.target.value);
|
|
});
|
|
}
|
|
}
|
|
validate() {
|
|
const value = this.$sid('input').val();
|
|
const $input = this.$sid('input');
|
|
this.$.addClass('was-validated');
|
|
|
|
// Run validation function
|
|
if (this.args.validate) {
|
|
const result = this.args.validate(value);
|
|
if (result === true || result === null || result === undefined) {
|
|
this.set_valid();
|
|
return true;
|
|
} else {
|
|
this.set_error(result);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
// Basic required check
|
|
if (this.args.required && !value) {
|
|
this.set_error('This field is required');
|
|
return false;
|
|
}
|
|
this.set_valid();
|
|
return true;
|
|
}
|
|
set_error(message) {
|
|
const $input = this.$sid('input');
|
|
const $error = this.$sid('error');
|
|
$input.removeClass('is-valid').addClass('is-invalid');
|
|
$error.text(message).css('display', 'block');
|
|
this.$sid('success').css('display', 'none');
|
|
}
|
|
set_valid(message) {
|
|
const $input = this.$sid('input');
|
|
const $success = this.$sid('success');
|
|
$input.removeClass('is-invalid').addClass('is-valid');
|
|
this.$sid('error').css('display', 'none');
|
|
if (message) {
|
|
$success.text(message).css('display', 'block');
|
|
} else {
|
|
$success.css('display', 'none');
|
|
}
|
|
}
|
|
clear_validation() {
|
|
const $input = this.$sid('input');
|
|
$input.removeClass('is-valid is-invalid');
|
|
this.$sid('error').css('display', 'none');
|
|
this.$sid('success').css('display', 'none');
|
|
this.$.removeClass('was-validated');
|
|
}
|
|
get_value() {
|
|
return this.$sid('input').val();
|
|
}
|
|
set_value(value) {
|
|
this.$sid('input').val(value);
|
|
if (this.$.hasClass('was-validated')) {
|
|
this.validate();
|
|
}
|
|
}
|
|
focus() {
|
|
this.$sid('input').focus();
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Input.js (babel) === */
|
|
"use strict";
|
|
|
|
/**
|
|
* Input - Bootstrap 5 Text Input Component
|
|
*
|
|
* Purpose: Single-line text input field for user data entry
|
|
* Design: Bootstrap .form-control styling
|
|
* Types: text, email, password, number, tel, url, date, etc.
|
|
*/
|
|
class Input extends Component {
|
|
on_ready() {
|
|
// Set type attribute if provided
|
|
if (this.args.type) {
|
|
this.$.attr('type', this.args.type);
|
|
}
|
|
|
|
// Set placeholder if provided
|
|
if (this.args.placeholder) {
|
|
this.$.attr('placeholder', this.args.placeholder);
|
|
}
|
|
|
|
// Set value if provided
|
|
if (this.args.value) {
|
|
this.$.val(this.args.value);
|
|
}
|
|
|
|
// Add custom classes if provided
|
|
if (this.args.class) {
|
|
this.$.addClass(this.args.class);
|
|
}
|
|
|
|
// Set disabled state if provided
|
|
if (this.args.disabled) {
|
|
this.$.prop('disabled', true);
|
|
}
|
|
|
|
// Set required attribute if provided
|
|
if (this.args.required) {
|
|
this.$.prop('required', true);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Kanban_Board.js (babel) === */
|
|
"use strict";
|
|
|
|
class Kanban_Board extends Component {
|
|
async on_load() {
|
|
if (this.args.data_source) {
|
|
const response = await fetch(this.args.data_source);
|
|
this.data.columns = await response.json();
|
|
} else if (this.args.columns) {
|
|
this.data.columns = this.args.columns;
|
|
}
|
|
}
|
|
on_ready() {
|
|
// Drag and drop functionality
|
|
this.setup_drag_and_drop();
|
|
}
|
|
setup_drag_and_drop() {
|
|
let dragged_card = null;
|
|
|
|
// Make cards draggable
|
|
this.$.find('[data-card-id]').each(function () {
|
|
const $card = $(this);
|
|
$card.on('dragstart', function (e) {
|
|
dragged_card = this;
|
|
$(this).css('opacity', '0.5');
|
|
});
|
|
$card.on('dragend', function (e) {
|
|
$(this).css('opacity', '1');
|
|
});
|
|
});
|
|
|
|
// Make columns droppable
|
|
this.$.find('[data-column-cards]').each(function () {
|
|
const $column = $(this);
|
|
$column.on('dragover', function (e) {
|
|
e.preventDefault();
|
|
$column.addClass('bg-light');
|
|
});
|
|
$column.on('dragleave', function (e) {
|
|
$column.removeClass('bg-light');
|
|
});
|
|
$column.on('drop', function (e) {
|
|
e.preventDefault();
|
|
$column.removeClass('bg-light');
|
|
if (dragged_card) {
|
|
$column.append(dragged_card);
|
|
|
|
// Trigger callback
|
|
if (this.args.on_move) {
|
|
const card_id = $(dragged_card).attr('data-card-id');
|
|
const column_id = $column.attr('data-column-cards');
|
|
this.args.on_move(card_id, column_id);
|
|
}
|
|
}
|
|
}.bind(this));
|
|
}.bind(this));
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/link.js (babel) === */
|
|
"use strict";
|
|
|
|
class Link extends Component {
|
|
on_ready() {
|
|
// Support $href attribute for dynamic URLs
|
|
if (this.args.href) {
|
|
this.$.attr('href', this.args.href);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/List.js (babel) === */
|
|
"use strict";
|
|
|
|
class List extends Component {
|
|
on_ready() {
|
|
// Add list-group-item class to each direct child
|
|
this.$.children().each(function () {
|
|
const $element = $(this);
|
|
$element.addClass('list-group-item');
|
|
});
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Loading_Skeleton.js (babel) === */
|
|
"use strict";
|
|
|
|
class Loading_Skeleton extends Component {
|
|
on_ready() {
|
|
// Apply lines from args
|
|
if (this.args.lines) {
|
|
this.$.empty();
|
|
for (let i = 0; i < this.args.lines; i++) {
|
|
const width = 12 - i * 2;
|
|
const $span = $('<span>').addClass(`placeholder col-${Math.max(width, 6)}`);
|
|
this.$.append($span);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Metric_Card.js (babel) === */
|
|
"use strict";
|
|
|
|
class Metric_Card extends Component {
|
|
// Pure container - children already styled
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Mobile_Header.js (babel) === */
|
|
"use strict";
|
|
|
|
class Mobile_Header extends Component {
|
|
on_ready() {
|
|
// No special behavior
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Modal_Dialog.js (babel) === */
|
|
"use strict";
|
|
|
|
class Modal_Dialog extends Component {
|
|
on_ready() {
|
|
// Initialize Bootstrap modal
|
|
this.modal = new bootstrap.Modal(this.$[0]);
|
|
}
|
|
show() {
|
|
this.modal.show();
|
|
}
|
|
hide() {
|
|
this.modal.hide();
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Multi_Select.js (babel) === */
|
|
"use strict";
|
|
|
|
class Multi_Select extends Component {
|
|
on_ready() {
|
|
this.selected_values = this.args.value || [];
|
|
this.all_options = this.args.options || [];
|
|
if (this.all_options.length > 0) {
|
|
this.render_options(this.all_options);
|
|
}
|
|
|
|
// Search functionality
|
|
const $search = this.$sid('search');
|
|
$search.on('input', e => {
|
|
this.filter_options(e.target.value);
|
|
});
|
|
|
|
// Prevent dropdown close when clicking inside
|
|
this.$sid('menu').on('click', e => {
|
|
e.stopPropagation();
|
|
});
|
|
|
|
// Clear/Select all buttons
|
|
this.$sid('clear_all').on('click', () => {
|
|
this.clear_all();
|
|
});
|
|
this.$sid('select_all').on('click', () => {
|
|
this.select_all();
|
|
});
|
|
|
|
// Update display
|
|
this.update_display();
|
|
}
|
|
render_options(options) {
|
|
const $container = this.$sid('options');
|
|
$container.empty();
|
|
if (options.length === 0) {
|
|
$container.append($('<div>').addClass('px-3 py-2 text-muted').text('No options found'));
|
|
return;
|
|
}
|
|
options.forEach(option => {
|
|
const $label = $('<label>').addClass('dropdown-item mb-0');
|
|
const $checkbox = $('<input>').attr('type', 'checkbox').addClass('form-check-input me-2').attr('data-value', option.value).prop('checked', this.selected_values.includes(option.value));
|
|
$checkbox.on('change', e => {
|
|
this.toggle_option(option.value, e.target.checked);
|
|
});
|
|
$label.append($checkbox).append(option.label);
|
|
$container.append($label);
|
|
});
|
|
}
|
|
filter_options(query) {
|
|
const filtered = this.all_options.filter(opt => opt.label.toLowerCase().includes(query.toLowerCase()));
|
|
this.render_options(filtered);
|
|
}
|
|
toggle_option(value, checked) {
|
|
if (checked) {
|
|
if (!this.selected_values.includes(value)) {
|
|
this.selected_values.push(value);
|
|
}
|
|
} else {
|
|
this.selected_values = this.selected_values.filter(v => v !== value);
|
|
}
|
|
this.update_display();
|
|
if (this.args.on_change) {
|
|
this.args.on_change(this.selected_values);
|
|
}
|
|
}
|
|
update_display() {
|
|
const count = this.selected_values.length;
|
|
const $text = this.$sid('selected_text');
|
|
if (count === 0) {
|
|
$text.text(this.args.placeholder || 'Select options');
|
|
} else if (count === 1) {
|
|
const option = this.all_options.find(opt => opt.value === this.selected_values[0]);
|
|
$text.text(option ? option.label : '1 selected');
|
|
} else {
|
|
$text.text(`${count} selected`);
|
|
}
|
|
}
|
|
clear_all() {
|
|
this.selected_values = [];
|
|
this.$sid('options').find('input[type="checkbox"]').prop('checked', false);
|
|
this.update_display();
|
|
if (this.args.on_change) {
|
|
this.args.on_change(this.selected_values);
|
|
}
|
|
}
|
|
select_all() {
|
|
this.selected_values = this.all_options.map(opt => opt.value);
|
|
this.$sid('options').find('input[type="checkbox"]').prop('checked', true);
|
|
this.update_display();
|
|
if (this.args.on_change) {
|
|
this.args.on_change(this.selected_values);
|
|
}
|
|
}
|
|
get_value() {
|
|
return this.selected_values;
|
|
}
|
|
set_value(values) {
|
|
this.selected_values = values;
|
|
this.$sid('options').find('input[type="checkbox"]').each((i, el) => {
|
|
const $el = $(el);
|
|
$el.prop('checked', values.includes($el.attr('data-value')));
|
|
});
|
|
this.update_display();
|
|
}
|
|
set_options(options) {
|
|
this.all_options = options;
|
|
this.render_options(options);
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Notification_Badge.js (babel) === */
|
|
"use strict";
|
|
|
|
class Notification_Badge extends Component {
|
|
on_ready() {
|
|
const $count = this.$sid('count');
|
|
// Update count dynamically
|
|
if (this.args.count === 0 || this.args.count === '0') {
|
|
$count.hide();
|
|
}
|
|
}
|
|
set_count(count) {
|
|
const $count = this.$sid('count');
|
|
$count.text(count);
|
|
if (count > 0) {
|
|
$count.show();
|
|
} else {
|
|
$count.hide();
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Notification_Dropdown.js (babel) === */
|
|
"use strict";
|
|
|
|
class Notification_Dropdown extends Component {
|
|
on_ready() {
|
|
// No special behavior
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Overdue_Indicator.js (babel) === */
|
|
"use strict";
|
|
|
|
class Overdue_Indicator extends Component {
|
|
// Pure Bootstrap styling - no JavaScript needed
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Page_Header.js (babel) === */
|
|
"use strict";
|
|
|
|
/**
|
|
* Page_Header - Bootstrap 5 Page Action Bar Component
|
|
*
|
|
* Purpose: Top section of page containing title, breadcrumbs, and actions
|
|
* Design: Flexbox layout using Bootstrap utility classes
|
|
* Layout: Title/breadcrumbs on left, actions/buttons on right
|
|
*/
|
|
class Page_Header extends Component {
|
|
// Page_Header is a pure container component - no lifecycle methods needed
|
|
// All layout from Bootstrap utilities: d-flex, justify-content-between, align-items-center, py-4
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/page_section.js (babel) === */
|
|
"use strict";
|
|
|
|
class Page_Section extends Component {
|
|
// Content section with spacing - no special behavior needed
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/page.js (babel) === */
|
|
"use strict";
|
|
|
|
class Page extends Component {
|
|
// Semantic page container - no special behavior needed
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Popover.js (babel) === */
|
|
"use strict";
|
|
|
|
class Popover extends Component {
|
|
on_ready() {
|
|
// Set popover content from args
|
|
if (this.args.title) {
|
|
this.$.attr('data-bs-title', this.args.title);
|
|
}
|
|
if (this.args.content) {
|
|
this.$.attr('data-bs-content', this.args.content);
|
|
}
|
|
|
|
// Set trigger (hover, click, focus)
|
|
this.$.attr('data-bs-trigger', this.args.trigger || 'click');
|
|
|
|
// Initialize Bootstrap popover
|
|
new bootstrap.Popover(this.$[0]);
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Progress_Bar.js (babel) === */
|
|
"use strict";
|
|
|
|
class Progress_Bar extends Component {
|
|
on_ready() {
|
|
const $bar = this.$sid('bar');
|
|
|
|
// Apply color from args
|
|
if (this.args.color) {
|
|
$bar.addClass(`bg-${this.args.color}`);
|
|
}
|
|
|
|
// Show value text if requested
|
|
if (this.args.show_value) {
|
|
$bar.text(`${this.args.value || 0}%`);
|
|
}
|
|
}
|
|
set_value(value) {
|
|
const $bar = this.$sid('bar');
|
|
$bar.css('width', `${value}%`).attr('aria-valuenow', value);
|
|
if (this.args.show_value) {
|
|
$bar.text(`${value}%`);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Radio_Button.js (babel) === */
|
|
"use strict";
|
|
|
|
/**
|
|
* Radio_Button - Bootstrap 5 Radio Input Component
|
|
*
|
|
* Purpose: Radio button for mutually exclusive selections within a group
|
|
* Design: Bootstrap .form-check-input styling with circular shape
|
|
* CRITICAL: All radios in same group must have same "name" attribute
|
|
* Wrapper: Typically used within <div class="form-check"> and <fieldset>
|
|
*/
|
|
class Radio_Button extends Component {
|
|
on_ready() {
|
|
// Set name attribute (CRITICAL for grouping)
|
|
if (this.args.name) {
|
|
this.$.attr('name', this.args.name);
|
|
}
|
|
|
|
// Set checked state if provided
|
|
if (this.args.checked) {
|
|
this.$.prop('checked', true);
|
|
}
|
|
|
|
// Set value if provided
|
|
if (this.args.value) {
|
|
this.$.val(this.args.value);
|
|
}
|
|
|
|
// Add custom classes if provided
|
|
if (this.args.class) {
|
|
this.$.addClass(this.args.class);
|
|
}
|
|
|
|
// Set disabled state if provided
|
|
if (this.args.disabled) {
|
|
this.$.prop('disabled', true);
|
|
}
|
|
|
|
// Set required attribute if provided
|
|
if (this.args.required) {
|
|
this.$.prop('required', true);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Rich_Text_Editor.js (babel) === */
|
|
"use strict";
|
|
|
|
class Rich_Text_Editor extends Component {
|
|
on_ready() {
|
|
const $editor = this.$sid('editor');
|
|
|
|
// Toolbar button handlers
|
|
this.$sid('toolbar').find('[data-command]').on('click', e => {
|
|
e.preventDefault();
|
|
const command = $(e.currentTarget).attr('data-command');
|
|
if (command === 'createLink') {
|
|
const url = prompt('Enter URL:');
|
|
if (url) {
|
|
document.execCommand(command, false, url);
|
|
}
|
|
} else {
|
|
document.execCommand(command, false, null);
|
|
}
|
|
$editor.focus();
|
|
});
|
|
|
|
// Track changes
|
|
$editor.on('input', () => {
|
|
if (this.args.on_change) {
|
|
this.args.on_change(this.get_value());
|
|
}
|
|
});
|
|
|
|
// Prevent default behavior on paste (optional - can be customized)
|
|
$editor.on('paste', e => {
|
|
if (this.args.plain_text_paste) {
|
|
e.preventDefault();
|
|
const text = e.originalEvent.clipboardData.getData('text/plain');
|
|
document.execCommand('insertText', false, text);
|
|
}
|
|
});
|
|
}
|
|
get_value() {
|
|
return this.$sid('editor').html();
|
|
}
|
|
get_text() {
|
|
return this.$sid('editor').text();
|
|
}
|
|
set_value(html) {
|
|
this.$sid('editor').html(html);
|
|
}
|
|
clear() {
|
|
this.$sid('editor').empty();
|
|
}
|
|
focus() {
|
|
this.$sid('editor').focus();
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Row_Action_Menu.js (babel) === */
|
|
"use strict";
|
|
|
|
class Row_Action_Menu extends Component {
|
|
on_ready() {
|
|
// Wrap children in dropdown structure
|
|
const $menu = this.$sid('menu');
|
|
$menu.children().each(function () {
|
|
const $child = $(this);
|
|
if ($child.prop('tagName') !== 'LI') {
|
|
if ($child.prop('tagName') === 'HR') {
|
|
const $li = $('<li>').append($('<hr>').addClass('dropdown-divider'));
|
|
$child.replaceWith($li);
|
|
} else {
|
|
$child.addClass('dropdown-item');
|
|
const $li = $('<li>');
|
|
$child.wrap($li);
|
|
}
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Sample_Datagrid_Component.js (babel) === */
|
|
"use strict";
|
|
|
|
/**
|
|
* Sample_Datagrid_Component
|
|
*
|
|
* Full-featured data table with:
|
|
* - Row selection (checkboxes)
|
|
* - Pagination
|
|
* - Row actions (view, edit, delete)
|
|
* - Loading states with placeholders
|
|
* - Empty states
|
|
*
|
|
* Usage:
|
|
* <Sample_Datagrid_Component
|
|
* $title="Client List"
|
|
* $entity_name="clients"
|
|
* $selectable=true
|
|
* $pagination=true
|
|
* $allow_delete=true
|
|
* $view_url="/clients/{id}"
|
|
* $edit_url="/clients/{id}/edit"
|
|
* $api_url="/api/clients"
|
|
* $columns=columns_definition
|
|
* />
|
|
*/
|
|
class Sample_Datagrid_Component extends Component {
|
|
async on_load() {
|
|
const that = this;
|
|
// If API URL provided, fetch data
|
|
if (that.args.api_url) {
|
|
const response = await fetch(that.args.api_url);
|
|
that.data = await response.json();
|
|
} else {
|
|
// Generate sample data for demonstration
|
|
that.data = that.generate_sample_data();
|
|
}
|
|
}
|
|
on_ready() {
|
|
const that = this;
|
|
// Select all checkbox
|
|
if (that.args.selectable) {
|
|
that.$sid('select_all').on('change', e => {
|
|
const checked = e.target.checked;
|
|
that.$.find('tbody input[type="checkbox"]').prop('checked', checked);
|
|
that.update_selection_count();
|
|
});
|
|
|
|
// Individual row checkboxes
|
|
that.$.find('tbody input[type="checkbox"]').on('change', () => {
|
|
that.update_selection_count();
|
|
});
|
|
}
|
|
|
|
// Delete buttons
|
|
if (that.args.allow_delete) {
|
|
that.$.find('button[data-id]').on('click', e => {
|
|
const $button = $(e.currentTarget);
|
|
const id = $button.data('id');
|
|
that.confirm_delete(id);
|
|
});
|
|
}
|
|
|
|
// Pagination
|
|
if (that.args.pagination !== false) {
|
|
that.$sid('prev_page').on('click', e => {
|
|
e.preventDefault();
|
|
that.go_to_page(that.data.pagination.current_page - 1);
|
|
});
|
|
that.$sid('next_page').on('click', e => {
|
|
e.preventDefault();
|
|
that.go_to_page(that.data.pagination.current_page + 1);
|
|
});
|
|
that.$.find('.page-link[data-page]').on('click', e => {
|
|
e.preventDefault();
|
|
const $link = $(e.currentTarget);
|
|
const page = int($link.data('page'));
|
|
that.go_to_page(page);
|
|
});
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Update UI to show how many rows are selected
|
|
*/
|
|
update_selection_count() {
|
|
const that = this;
|
|
const selected = that.$.find('tbody input[type="checkbox"]:checked').length;
|
|
if (selected > 0) {
|
|
// Could show a banner: "3 items selected"
|
|
console.log(`${selected} items selected`);
|
|
|
|
// Fire event for parent components to listen to
|
|
that.$.trigger('selection:changed', {
|
|
count: selected
|
|
});
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get array of selected IDs
|
|
*/
|
|
get_selected_ids() {
|
|
const that = this;
|
|
const ids = [];
|
|
that.$.find('tbody input[type="checkbox"]:checked').each((i, checkbox) => {
|
|
const $checkbox = $(checkbox);
|
|
const id = $checkbox.data('id');
|
|
if (id) ids.push(id);
|
|
});
|
|
return ids;
|
|
}
|
|
|
|
/**
|
|
* Clear all selections
|
|
*/
|
|
clear_selection() {
|
|
const that = this;
|
|
that.$.find('input[type="checkbox"]').prop('checked', false);
|
|
that.update_selection_count();
|
|
}
|
|
|
|
/**
|
|
* Confirm deletion of a row
|
|
*/
|
|
confirm_delete(id) {
|
|
const that = this;
|
|
// In a real app, show a Bootstrap modal
|
|
if (confirm('Are you sure you want to delete this item?')) {
|
|
that.delete_row(id);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Delete a row (would typically make API call)
|
|
*/
|
|
async delete_row(id) {
|
|
const that = this;
|
|
try {
|
|
// Make API call
|
|
// await fetch(`${that.args.api_url}/${id}`, { method: 'DELETE' });
|
|
|
|
// Remove row from data
|
|
that.data.rows = that.data.rows.filter(row => row.id !== id);
|
|
|
|
// Re-render component
|
|
that.refresh();
|
|
|
|
// Show success message
|
|
console.log(`Deleted item ${id}`);
|
|
} catch (error) {
|
|
console.error('Delete failed:', error);
|
|
alert('Failed to delete item');
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Navigate to a specific page
|
|
*/
|
|
async go_to_page(page) {
|
|
const that = this;
|
|
if (page < 1 || page > that.data.pagination.total_pages) {
|
|
return;
|
|
}
|
|
|
|
// Show loading state
|
|
that.$.find('tbody').css('opacity', '0.5');
|
|
try {
|
|
// Fetch new page
|
|
const url = `${that.args.api_url}?page=${page}`;
|
|
const response = await fetch(url);
|
|
that.data = await response.json();
|
|
|
|
// Re-render
|
|
that.refresh();
|
|
} catch (error) {
|
|
console.error('Pagination failed:', error);
|
|
that.$.find('tbody').css('opacity', '1');
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Refresh the table (reload data and re-render)
|
|
*/
|
|
async reload_data() {
|
|
const that = this;
|
|
that.data = {}; // Clear data to show loading state
|
|
that.refresh();
|
|
await that.on_load();
|
|
that.refresh();
|
|
}
|
|
|
|
/**
|
|
* Generate sample data for demonstration purposes
|
|
*/
|
|
generate_sample_data() {
|
|
const that = this;
|
|
const statuses = [{
|
|
label: 'Active',
|
|
color: 'success'
|
|
}, {
|
|
label: 'Pending',
|
|
color: 'warning'
|
|
}, {
|
|
label: 'Inactive',
|
|
color: 'secondary'
|
|
}, {
|
|
label: 'Suspended',
|
|
color: 'danger'
|
|
}];
|
|
const first_names = ['John', 'Sarah', 'Michael', 'Emily', 'David', 'Lisa', 'Robert', 'Jennifer', 'William', 'Amanda'];
|
|
const last_names = ['Smith', 'Johnson', 'Brown', 'Garcia', 'Martinez', 'Lee', 'Anderson', 'Thompson', 'White', 'Davis'];
|
|
const companies = ['Acme Corp', 'Tech Solutions', 'Global Enterprises', 'Innovation Labs', 'Digital Systems', 'Cloud Services', 'Smart Industries', 'Future Networks', 'Prime Consulting', 'Elite Partners'];
|
|
const rows = [];
|
|
const count = that.args.showing || 10;
|
|
for (let i = 0; i < count; i++) {
|
|
const first_name = first_names[Math.floor(Math.random() * first_names.length)];
|
|
const last_name = last_names[Math.floor(Math.random() * last_names.length)];
|
|
const company = companies[Math.floor(Math.random() * companies.length)];
|
|
const status = statuses[Math.floor(Math.random() * statuses.length)];
|
|
rows.push({
|
|
id: `C${str(i + 1).padStart(3, '0')}`,
|
|
name: `${first_name} ${last_name}`,
|
|
company: company,
|
|
email: `${first_name.toLowerCase()}.${last_name.toLowerCase()}@${company.toLowerCase().replace(/\s+/g, '')}.com`,
|
|
phone: `(555) ${str(Math.floor(Math.random() * 900) + 100)}-${str(Math.floor(Math.random() * 9000) + 1000)}`,
|
|
status: status.label,
|
|
status_color: status.color,
|
|
created: that.random_date()
|
|
});
|
|
}
|
|
return {
|
|
rows: rows,
|
|
pagination: {
|
|
current_page: 1,
|
|
total_pages: Math.ceil((that.args.total || 100) / count),
|
|
from: 1,
|
|
to: count,
|
|
total: that.args.total || 100,
|
|
pages: [1, 2, 3, '...', Math.ceil((that.args.total || 100) / count)]
|
|
}
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Generate random date for sample data
|
|
*/
|
|
random_date() {
|
|
const months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
|
|
const month = months[Math.floor(Math.random() * 12)];
|
|
const day = Math.floor(Math.random() * 28) + 1;
|
|
return `${month} ${str(day).padStart(2, '0')}, 2024`;
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Search_Bar.js (babel) === */
|
|
"use strict";
|
|
|
|
class Search_Bar extends Component {
|
|
on_ready() {
|
|
// Bind search event
|
|
const $input = this.$sid('input');
|
|
$input.on('input', e => {
|
|
if (this.args.on_search) {
|
|
this.args.on_search(e.target.value);
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Searchable_Select.js (babel) === */
|
|
"use strict";
|
|
|
|
class Searchable_Select extends Component {
|
|
on_ready() {
|
|
this.selected_value = this.args.value || null;
|
|
this.all_options = this.args.options || [];
|
|
if (this.all_options.length > 0) {
|
|
this.render_options(this.all_options);
|
|
}
|
|
|
|
// Search functionality
|
|
const $search = this.$sid('search');
|
|
$search.on('input', e => {
|
|
this.filter_options(e.target.value);
|
|
});
|
|
|
|
// Prevent dropdown close when clicking search input
|
|
$search.on('click', e => {
|
|
e.stopPropagation();
|
|
});
|
|
|
|
// Update selected text if initial value provided
|
|
if (this.selected_value) {
|
|
const selected_option = this.all_options.find(opt => opt.value == this.selected_value);
|
|
if (selected_option) {
|
|
this.$sid('selected_text').text(selected_option.label);
|
|
}
|
|
}
|
|
}
|
|
render_options(options) {
|
|
const $container = this.$sid('options');
|
|
$container.empty();
|
|
if (options.length === 0) {
|
|
$container.append($('<div>').addClass('px-3 py-2 text-muted').text('No options found'));
|
|
return;
|
|
}
|
|
options.forEach(option => {
|
|
const $item = $('<a>').addClass('dropdown-item').attr('href', '#').text(option.label).attr('data-value', option.value);
|
|
if (option.value == this.selected_value) {
|
|
$item.addClass('active');
|
|
}
|
|
$item.on('click', e => {
|
|
e.preventDefault();
|
|
this.select_option(option);
|
|
});
|
|
$container.append($item);
|
|
});
|
|
}
|
|
filter_options(query) {
|
|
const filtered = this.all_options.filter(opt => opt.label.toLowerCase().includes(query.toLowerCase()));
|
|
this.render_options(filtered);
|
|
}
|
|
select_option(option) {
|
|
this.selected_value = option.value;
|
|
this.$sid('selected_text').text(option.label);
|
|
|
|
// Update active state
|
|
this.$sid('options').find('.dropdown-item').removeClass('active');
|
|
this.$sid('options').find(`[data-value="${option.value}"]`).addClass('active');
|
|
|
|
// Close dropdown
|
|
const dropdown = bootstrap.Dropdown.getInstance(this.$sid('button')[0]);
|
|
if (dropdown) {
|
|
dropdown.hide();
|
|
}
|
|
|
|
// Clear search
|
|
this.$sid('search').val('');
|
|
this.render_options(this.all_options);
|
|
|
|
// Trigger callback
|
|
if (this.args.on_change) {
|
|
this.args.on_change(option.value, option);
|
|
}
|
|
}
|
|
get_value() {
|
|
return this.selected_value;
|
|
}
|
|
set_value(value) {
|
|
this.selected_value = value;
|
|
const option = this.all_options.find(opt => opt.value == value);
|
|
if (option) {
|
|
this.$sid('selected_text').text(option.label);
|
|
this.$sid('options').find('.dropdown-item').removeClass('active');
|
|
this.$sid('options').find(`[data-value="${value}"]`).addClass('active');
|
|
}
|
|
}
|
|
set_options(options) {
|
|
this.all_options = options;
|
|
this.render_options(options);
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Select_Dropdown.js (babel) === */
|
|
"use strict";
|
|
|
|
/**
|
|
* Select_Dropdown - Bootstrap 5 Dropdown Selection Component
|
|
*
|
|
* Purpose: Dropdown menu for selecting one option from a list
|
|
* Design: Bootstrap .form-select styling with dropdown arrow
|
|
* Content: Contains <option> elements
|
|
*/
|
|
class Select_Dropdown extends Component {
|
|
on_ready() {
|
|
// Set value if provided
|
|
if (this.args.value) {
|
|
this.$.val(this.args.value);
|
|
}
|
|
|
|
// Add custom classes if provided
|
|
if (this.args.class) {
|
|
this.$.addClass(this.args.class);
|
|
}
|
|
|
|
// Set disabled state if provided
|
|
if (this.args.disabled) {
|
|
this.$.prop('disabled', true);
|
|
}
|
|
|
|
// Set required attribute if provided
|
|
if (this.args.required) {
|
|
this.$.prop('required', true);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Sidebar_Nav.js (babel) === */
|
|
"use strict";
|
|
|
|
class Sidebar_Nav extends Component {
|
|
on_ready() {
|
|
// Auto-wrap children in nav structure if needed
|
|
const $nav_items = this.$sid('nav_items');
|
|
$nav_items.children().each(function () {
|
|
const $child = $(this);
|
|
if ($child.prop('tagName') !== 'LI') {
|
|
const $li = $('<li>').addClass('nav-item');
|
|
$child.addClass('nav-link');
|
|
$child.wrap($li);
|
|
}
|
|
});
|
|
|
|
// Set active state based on current URL
|
|
const current_path = window.location.pathname;
|
|
$nav_items.find('a.nav-link').each(function () {
|
|
const $link = $(this);
|
|
if ($link.attr('href') === current_path) {
|
|
$link.addClass('active');
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Sortable_Column_Header.js (babel) === */
|
|
"use strict";
|
|
|
|
class Sortable_Column_Header extends Component {
|
|
on_ready() {
|
|
// Click to toggle sort
|
|
this.$.on('click', () => {
|
|
this.toggle_sort();
|
|
});
|
|
|
|
// Set initial sort state
|
|
if (this.args.sort) {
|
|
this.set_sort(this.args.sort); // 'asc' or 'desc'
|
|
}
|
|
}
|
|
toggle_sort() {
|
|
const current = this.$.attr('data-sort') || 'none';
|
|
const next = current === 'none' ? 'asc' : current === 'asc' ? 'desc' : 'asc';
|
|
this.set_sort(next);
|
|
|
|
// Call callback if provided
|
|
if (this.args.on_sort) {
|
|
this.args.on_sort(this.args.column, next);
|
|
}
|
|
}
|
|
set_sort(direction) {
|
|
this.$.attr('data-sort', direction);
|
|
const $icon = this.$sid('sort_icon');
|
|
if (direction === 'asc') {
|
|
$icon.html('<i class="text-primary">↑</i>');
|
|
} else if (direction === 'desc') {
|
|
$icon.html('<i class="text-primary">↓</i>');
|
|
} else {
|
|
$icon.html('<i class="text-muted">⇅</i>');
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Spinner.js (babel) === */
|
|
"use strict";
|
|
|
|
class Spinner extends Component {
|
|
on_ready() {
|
|
// Apply size (sm)
|
|
if (this.args.size === 'sm') {
|
|
this.$.addClass('spinner-border-sm');
|
|
}
|
|
|
|
// Apply color
|
|
if (this.args.color) {
|
|
this.$.addClass(`text-${this.args.color}`);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Stat_Card.js (babel) === */
|
|
"use strict";
|
|
|
|
class Stat_Card extends Component {
|
|
on_ready() {
|
|
// No special behavior
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Status_Badge.js (babel) === */
|
|
"use strict";
|
|
|
|
class Status_Badge extends Component {
|
|
on_ready() {
|
|
// Apply color based on content or args
|
|
const status = this.args.status || this.$.text().trim().toLowerCase();
|
|
|
|
// Default color mappings
|
|
const color_map = {
|
|
'active': 'bg-success',
|
|
'pending': 'bg-warning',
|
|
'completed': 'bg-primary',
|
|
'cancelled': 'bg-danger',
|
|
'draft': 'bg-secondary',
|
|
'archived': 'bg-dark'
|
|
};
|
|
const bg_class = this.args.bg_class || color_map[status] || 'bg-secondary';
|
|
this.$.addClass(bg_class);
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Tab_Content.js (babel) === */
|
|
"use strict";
|
|
|
|
class Tab_Content extends Component {
|
|
on_ready() {
|
|
// Ensure children have tab-pane class
|
|
this.$.children().each(function () {
|
|
const $child = $(this);
|
|
$child.addClass('tab-pane fade');
|
|
|
|
// Set first pane as active if none active
|
|
if ($child.parent().find('.tab-pane.active').length === 0 && $child.index() === 0) {
|
|
$child.addClass('show active');
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Table_Pagination.js (babel) === */
|
|
"use strict";
|
|
|
|
class Table_Pagination extends Component {
|
|
on_ready() {
|
|
// Generate pagination if pages provided via args
|
|
if (this.args.current_page && this.args.total_pages) {
|
|
this.generate_pagination(this.args.current_page, this.args.total_pages);
|
|
}
|
|
}
|
|
generate_pagination(current, total) {
|
|
const $pagination = this.$sid('pagination');
|
|
$pagination.empty();
|
|
|
|
// Previous button
|
|
const $prev = $('<li>').addClass('page-item' + (current === 1 ? ' disabled' : ''));
|
|
$prev.append($('<a>').addClass('page-link').attr('href', '#').text('Previous'));
|
|
$pagination.append($prev);
|
|
|
|
// Page numbers (show 5 pages max)
|
|
let start = Math.max(1, current - 2);
|
|
let end = Math.min(total, current + 2);
|
|
for (let i = start; i <= end; i++) {
|
|
const $li = $('<li>').addClass('page-item' + (i === current ? ' active' : ''));
|
|
$li.append($('<a>').addClass('page-link').attr('href', '#').text(i));
|
|
$pagination.append($li);
|
|
}
|
|
|
|
// Next button
|
|
const $next = $('<li>').addClass('page-item' + (current === total ? ' disabled' : ''));
|
|
$next.append($('<a>').addClass('page-link').attr('href', '#').text('Next'));
|
|
$pagination.append($next);
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Table.js (babel) === */
|
|
"use strict";
|
|
|
|
class Table extends Component {
|
|
on_ready() {
|
|
// Apply variant from args
|
|
if (this.args.variant) {
|
|
this.$.addClass(`table-${this.args.variant}`); // striped, bordered, borderless
|
|
}
|
|
|
|
// Apply size
|
|
if (this.args.size === 'sm') {
|
|
this.$.addClass('table-sm');
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Tabs.js (babel) === */
|
|
"use strict";
|
|
|
|
class Tabs extends Component {
|
|
on_ready() {
|
|
// Wrap children in nav-item structure
|
|
this.$.children().each(function () {
|
|
const $child = $(this);
|
|
if ($child.prop('tagName') !== 'LI') {
|
|
const $li = $('<li>').addClass('nav-item');
|
|
$child.addClass('nav-link');
|
|
$child.wrap($li);
|
|
}
|
|
});
|
|
|
|
// Set first tab as active if none active
|
|
if (this.$.find('.nav-link.active').length === 0) {
|
|
this.$.find('.nav-link').first().addClass('active');
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Tag_Group.js (babel) === */
|
|
"use strict";
|
|
|
|
class Tag_Group extends Component {
|
|
on_ready() {
|
|
// No special behavior needed
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Tag.js (babel) === */
|
|
"use strict";
|
|
|
|
class Tag extends Component {
|
|
on_ready() {
|
|
// Apply color from args
|
|
if (this.args.color) {
|
|
this.$.removeClass('bg-secondary').addClass(`bg-${this.args.color}`);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/text_display.js (babel) === */
|
|
"use strict";
|
|
|
|
class Text_Display extends Component {
|
|
// Generic text display - inherits Bootstrap typography
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Textarea.js (babel) === */
|
|
"use strict";
|
|
|
|
/**
|
|
* Textarea - Bootstrap 5 Multi-line Text Input Component
|
|
*
|
|
* Purpose: Multi-line text input for longer content like descriptions, comments, notes
|
|
* Design: Bootstrap .form-control styling (same as Input)
|
|
*/
|
|
class Textarea extends Component {
|
|
on_ready() {
|
|
// Set rows if provided
|
|
if (this.args.rows) {
|
|
this.$.attr('rows', this.args.rows);
|
|
}
|
|
|
|
// Set placeholder if provided
|
|
if (this.args.placeholder) {
|
|
this.$.attr('placeholder', this.args.placeholder);
|
|
}
|
|
|
|
// Set value if provided (overrides content())
|
|
if (this.args.value) {
|
|
this.$.val(this.args.value);
|
|
}
|
|
|
|
// Add custom classes if provided
|
|
if (this.args.class) {
|
|
this.$.addClass(this.args.class);
|
|
}
|
|
|
|
// Set disabled state if provided
|
|
if (this.args.disabled) {
|
|
this.$.prop('disabled', true);
|
|
}
|
|
|
|
// Set required attribute if provided
|
|
if (this.args.required) {
|
|
this.$.prop('required', true);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Three_Column_Layout.js (babel) === */
|
|
"use strict";
|
|
|
|
class Three_Column_Layout extends Component {
|
|
on_ready() {
|
|
// Wrap each direct child in responsive column classes
|
|
this.$.children().each(function () {
|
|
const $element = $(this);
|
|
$element.addClass('col-12 col-md-6 col-xl-4 mb-4');
|
|
});
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Time_Picker.js (babel) === */
|
|
"use strict";
|
|
|
|
class Time_Picker extends Component {
|
|
on_ready() {
|
|
const $input = this.$sid('input');
|
|
if (this.args.value) {
|
|
$input.val(this.args.value);
|
|
}
|
|
if (this.args.name) {
|
|
$input.attr('name', this.args.name);
|
|
}
|
|
if (this.args.min) {
|
|
$input.attr('min', this.args.min);
|
|
}
|
|
if (this.args.max) {
|
|
$input.attr('max', this.args.max);
|
|
}
|
|
if (this.args.step) {
|
|
$input.attr('step', this.args.step);
|
|
}
|
|
if (this.args.disabled) {
|
|
$input.prop('disabled', true);
|
|
}
|
|
if (this.args.readonly) {
|
|
$input.prop('readonly', true);
|
|
}
|
|
if (this.args.required) {
|
|
$input.prop('required', true);
|
|
}
|
|
if (this.args.on_change) {
|
|
$input.on('change', e => {
|
|
this.args.on_change(e.target.value);
|
|
});
|
|
}
|
|
}
|
|
get_value() {
|
|
return this.$sid('input').val();
|
|
}
|
|
set_value(value) {
|
|
this.$sid('input').val(value);
|
|
}
|
|
focus() {
|
|
this.$sid('input').focus();
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Timeline.js (babel) === */
|
|
"use strict";
|
|
|
|
class Timeline extends Component {
|
|
// Pure Bootstrap flexbox - no JavaScript needed
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Timestamp_Display.js (babel) === */
|
|
"use strict";
|
|
|
|
class Timestamp_Display extends Component {
|
|
// Pure Bootstrap styling - no JavaScript needed
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Tooltip.js (babel) === */
|
|
"use strict";
|
|
|
|
class Tooltip extends Component {
|
|
on_ready() {
|
|
// Set tooltip text from args
|
|
if (this.args.text) {
|
|
this.$.attr('data-bs-title', this.args.text);
|
|
}
|
|
|
|
// Set placement
|
|
if (this.args.placement) {
|
|
this.$.attr('data-bs-placement', this.args.placement);
|
|
}
|
|
|
|
// Initialize Bootstrap tooltip
|
|
new bootstrap.Tooltip(this.$[0]);
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Top_Nav.js (babel) === */
|
|
"use strict";
|
|
|
|
class Top_Nav extends Component {
|
|
on_ready() {
|
|
// Wrap children in nav structure
|
|
const $nav = this.$sid('nav_items');
|
|
$nav.children().each(function () {
|
|
const $child = $(this);
|
|
if ($child.prop('tagName') !== 'LI') {
|
|
const $li = $('<li>').addClass('nav-item');
|
|
$child.addClass('nav-link');
|
|
$child.wrap($li);
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Trend_Indicator.js (babel) === */
|
|
"use strict";
|
|
|
|
class Trend_Indicator extends Component {
|
|
on_ready() {
|
|
const text = this.$.text().trim();
|
|
const is_positive = text.startsWith('+');
|
|
const is_negative = text.startsWith('-');
|
|
if (is_positive) {
|
|
this.$.addClass('text-success fw-bold');
|
|
} else if (is_negative) {
|
|
this.$.addClass('text-danger fw-bold');
|
|
} else {
|
|
this.$.addClass('text-muted fw-bold');
|
|
}
|
|
this.$.addClass('d-block mt-1');
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/Two_Column_Layout.js (babel) === */
|
|
"use strict";
|
|
|
|
class Two_Column_Layout extends Component {
|
|
on_ready() {
|
|
// Wrap each direct child in responsive column classes
|
|
this.$.children().each(function () {
|
|
const $element = $(this);
|
|
$element.addClass('col-12 col-lg-6 mb-4');
|
|
});
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/_archived/unfinished/User_Avatar_Dropdown.js (babel) === */
|
|
"use strict";
|
|
|
|
class User_Avatar_Dropdown extends Component {
|
|
on_ready() {
|
|
// Ensure proper dropdown item structure
|
|
const $menu = this.$sid('menu');
|
|
$menu.children().each(function () {
|
|
const $child = $(this);
|
|
if ($child.prop('tagName') !== 'LI') {
|
|
const $li = $('<li>');
|
|
if ($child.prop('tagName') === 'HR') {
|
|
$li.append($('<hr>').addClass('dropdown-divider'));
|
|
$child.replaceWith($li);
|
|
} else {
|
|
$child.addClass('dropdown-item');
|
|
$child.wrap($li);
|
|
}
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/modal/modal_abstract.js (babel) === */
|
|
"use strict";
|
|
|
|
/**
|
|
* Modal_Abstract - Base class for modal orchestration classes
|
|
*
|
|
* **Philosophy**:
|
|
* Modal classes are orchestration layers that manage the lifecycle of showing
|
|
* a modal, collecting user input, and returning results. They do NOT contain
|
|
* form validation or business logic - that belongs in jqhtml components and
|
|
* controller endpoints.
|
|
*
|
|
* **Purpose**:
|
|
* - Provides a common base class for type identification
|
|
* - Enforces file naming conventions (modal classes end with _Modal)
|
|
* - Documents the modal class pattern
|
|
* - Enables framework-level features (future: discovery, validation)
|
|
*
|
|
* **Responsibilities of Modal Classes**:
|
|
* - Invoke Modal.form() / Modal.show() / Modal.confirm() with appropriate configuration
|
|
* - Handle modal lifecycle (show, submit, cancel, errors)
|
|
* - Return Promise that resolves with data or false
|
|
* - Encapsulate modal-specific UI logic
|
|
*
|
|
* **Contract**:
|
|
* All modal classes extending Modal_Abstract must implement:
|
|
* - `static async show(params)`: Primary entry point, returns Promise
|
|
*
|
|
* **Return Values**:
|
|
* - Success: Resolve with data object (e.g., created user record)
|
|
* - Cancel/Close: Resolve with false
|
|
* - Error: Show error in modal, keep open, don't resolve until user acts
|
|
*
|
|
* **Integration**:
|
|
* Modal classes use Modal.js static API (Modal.form(), Modal.show(), etc.)
|
|
* as building blocks. Form validation handled by Rsx_Form and Form_Utils.
|
|
* Page JS orchestrates modal flow but doesn't contain modal UI logic.
|
|
*
|
|
* **Pattern Examples**:
|
|
*
|
|
* Simple form modal:
|
|
* ```
|
|
* class Add_User_Modal extends Modal_Abstract {
|
|
* static async show() {
|
|
* const result = await Modal.form({
|
|
* title: 'Add User',
|
|
* component: 'Add_User_Modal_Form',
|
|
* on_submit: async (form) => {
|
|
* try {
|
|
* const values = form.vals();
|
|
* const result = await Controller.add_user(values);
|
|
* return result; // Close modal, return data
|
|
* } catch (error) {
|
|
* await form.render_error(error);
|
|
* return false; // Keep modal open
|
|
* }
|
|
* },
|
|
* });
|
|
* return result || false;
|
|
* }
|
|
* }
|
|
* ```
|
|
*
|
|
* Custom content modal:
|
|
* ```
|
|
* class Confirm_Delete_Modal extends Modal_Abstract {
|
|
* static async show({item_name}) {
|
|
* return await Modal.confirm(
|
|
* 'Confirm Delete',
|
|
* `Are you sure you want to delete ${item_name}?`
|
|
* );
|
|
* }
|
|
* }
|
|
* ```
|
|
*
|
|
* Modal with backend call:
|
|
* ```
|
|
* class Send_Invite_Modal extends Modal_Abstract {
|
|
* static async show(user_id) {
|
|
* const result = await Controller.send_invite({user_id});
|
|
* if (result.invite_url) {
|
|
* await Modal.alert('Invite Sent', result.invite_url);
|
|
* }
|
|
* return result;
|
|
* }
|
|
* }
|
|
* ```
|
|
*
|
|
* **Usage Pattern**:
|
|
* ```
|
|
* // Page JS orchestrates flow, modals handle UI
|
|
* const user = await Add_User_Modal.show();
|
|
* if (user) {
|
|
* $('.Users_DataGrid').component().reload();
|
|
* await Send_User_Invite_Modal.show(user.id);
|
|
* }
|
|
* ```
|
|
*
|
|
* **Best Practices**:
|
|
* - Keep modal classes focused: one modal = one class
|
|
* - Page JS orchestrates sequence, modal classes handle individual modals
|
|
* - Modal classes don't call each other directly
|
|
* - Modal classes don't update UI (grids, lists) - page JS does that
|
|
* - Use descriptive names ending in _Modal (Add_User_Modal, Send_Invite_Modal)
|
|
* - Place feature-specific modals in feature directory
|
|
* - Place reusable modals in theme/components/modal/
|
|
*
|
|
* **When to Use Modal Classes**:
|
|
* - Multi-step forms
|
|
* - Forms with complex validation
|
|
* - Modals called from multiple places
|
|
* - Modals with backend interactions
|
|
*
|
|
* **When NOT to Use Modal Classes**:
|
|
* - Simple alerts: `await Modal.alert('Saved!')`
|
|
* - Simple confirmations: `if (await Modal.confirm('Delete?')) {...}`
|
|
* - One-off prompts: `const name = await Modal.prompt('Enter name:')`
|
|
*/
|
|
class Modal_Abstract {
|
|
// This class provides structure and documentation for modal patterns.
|
|
// Concrete modal classes extend this and implement static show() method.
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/modal/rsx_modal.js (babel) === */
|
|
"use strict";
|
|
|
|
/**
|
|
* Rsx_Modal Component
|
|
*
|
|
* Instance of a modal dialog. Handles lifecycle, sizing, and user interaction.
|
|
* Typically created and managed by the Modal static API class.
|
|
*/
|
|
class Rsx_Modal extends Component {
|
|
on_create() {
|
|
this.data.title = '';
|
|
this.data.body_content = null;
|
|
this.data.buttons = [];
|
|
this.data.closable = true;
|
|
this.data.max_width = 800;
|
|
this.data.close_on_submit = true;
|
|
this.data.is_visible = false;
|
|
this.data.result_promise = null;
|
|
this.data.resolve_fn = null;
|
|
|
|
// Store reference to bootstrap modal instance
|
|
this._bs_modal = null;
|
|
this._resize_handler = null;
|
|
}
|
|
on_ready() {
|
|
const that = this;
|
|
|
|
// Set up close button handler
|
|
this.$sid('close_btn').on('click', function (e) {
|
|
e.preventDefault();
|
|
if (that.data.closable) {
|
|
that.close(false);
|
|
}
|
|
});
|
|
|
|
// Set up backdrop click handler
|
|
this.$sid('backdrop').on('click', function (e) {
|
|
if (that.data.closable && e.target === this) {
|
|
that.close(false);
|
|
}
|
|
});
|
|
|
|
// Set up ESC key handler
|
|
$(document).on('keydown.rsx_modal_' + this._cid, function (e) {
|
|
if (e.key === 'Escape' && that.data.closable && that.data.is_visible) {
|
|
that.close(false);
|
|
}
|
|
});
|
|
|
|
// Set up resize handler
|
|
this._resize_handler = debounce(() => {
|
|
if (that.data.is_visible) {
|
|
that._apply_sizing();
|
|
}
|
|
}, 100);
|
|
$(window).on('resize.rsx_modal_' + this._cid, this._resize_handler);
|
|
}
|
|
|
|
/**
|
|
* Configure and show the modal
|
|
* @param {Object} options - Modal options (title, body, buttons, etc.)
|
|
* @param {Object} internal_options - Internal options (skip_backdrop, animate)
|
|
*/
|
|
async show(options) {
|
|
let internal_options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
const that = this;
|
|
const skip_backdrop = internal_options.skip_backdrop || false;
|
|
const should_animate = internal_options.animate || false;
|
|
console.log('[Rsx_Modal] show() called with options:', options);
|
|
|
|
// Store options
|
|
this.data.title = options.title || '';
|
|
this.data.closable = options.closable !== undefined ? options.closable : true;
|
|
this.data.max_width = options.max_width || 800;
|
|
this.data.close_on_submit = options.close_on_submit !== undefined ? options.close_on_submit : true;
|
|
this.data.buttons = options.buttons || [];
|
|
this.data.skip_backdrop = skip_backdrop;
|
|
this.data.icon = options.icon || null;
|
|
console.log('[Rsx_Modal] Setting title to:', this.data.title);
|
|
console.log('[Rsx_Modal] Title element:', this.$sid('title'));
|
|
|
|
// Set title
|
|
this.$sid('title').text(this.data.title);
|
|
|
|
// Show/hide close button based on closable
|
|
if (this.data.closable) {
|
|
this.$sid('close_btn').show();
|
|
} else {
|
|
this.$sid('close_btn').hide();
|
|
}
|
|
|
|
// Set body content (with optional icon)
|
|
this._set_body_content(options.body, this.data.icon);
|
|
|
|
// Set buttons
|
|
this._set_buttons();
|
|
|
|
// Create promise that will resolve when modal closes
|
|
const result_promise = new Promise(resolve => {
|
|
that.data.resolve_fn = resolve;
|
|
});
|
|
|
|
// Show modal and backdrop
|
|
this.data.is_visible = true;
|
|
|
|
// Append to body so it's on top (don't append backdrop if using shared)
|
|
if (!skip_backdrop) {
|
|
$('body').append(this.$sid('backdrop'));
|
|
}
|
|
$('body').append(this.$);
|
|
|
|
// Apply sizing before showing
|
|
this._apply_sizing();
|
|
|
|
// Fade in modal (and backdrop if not using shared)
|
|
await this._fade_in(should_animate);
|
|
|
|
// Auto-focus first input element
|
|
this._focus_first_input();
|
|
return result_promise;
|
|
}
|
|
|
|
/**
|
|
* Set body content with optional icon
|
|
*/
|
|
_set_body_content(body, icon) {
|
|
const $body = this.$sid('body');
|
|
$body.empty();
|
|
|
|
// If icon provided, add it
|
|
if (icon) {
|
|
const $icon = $(`<i class="bi bi-${icon} modal-icon"></i>`);
|
|
$body.append($icon);
|
|
$body.addClass('has-icon');
|
|
} else {
|
|
$body.removeClass('has-icon');
|
|
}
|
|
|
|
// Get or create body content wrapper
|
|
let $content = this.$sid('body_content');
|
|
if (!$content.exists()) {
|
|
$content = $('<div class="modal-body-content"></div>');
|
|
$body.append($content);
|
|
}
|
|
if (typeof body === 'string') {
|
|
// Text content - escape and convert newlines
|
|
const escaped = $('<div>').text(body).html().replace(/\n/g, '<br>');
|
|
$content.html(escaped);
|
|
} else if (body instanceof jQuery) {
|
|
// jQuery element
|
|
$content.append(body);
|
|
} else if (body && typeof body === 'object') {
|
|
// Assume it's a jqhtml component instance
|
|
$content.append(body.$);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Set buttons in footer
|
|
*/
|
|
_set_buttons() {
|
|
const that = this;
|
|
const $footer = this.$sid('footer');
|
|
$footer.empty();
|
|
if (this.data.buttons.length === 0) {
|
|
$footer.hide();
|
|
return;
|
|
}
|
|
$footer.show();
|
|
for (let button_def of this.data.buttons) {
|
|
const $button = $('<button>').attr('type', 'button').addClass('btn').addClass(button_def.class || 'btn-secondary').text(button_def.label || 'Button');
|
|
$button.on('click', async function () {
|
|
let result = button_def.value;
|
|
let had_callback = false;
|
|
|
|
// If button has a callback, call it and use return value as result
|
|
if (button_def.callback && typeof button_def.callback === 'function') {
|
|
had_callback = true;
|
|
result = await button_def.callback();
|
|
}
|
|
|
|
// If callback returned false, keep modal open (but not if just button value is false)
|
|
if (result === false && had_callback) {
|
|
return;
|
|
}
|
|
|
|
// Close modal with result
|
|
that.close(result);
|
|
});
|
|
$footer.append($button);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Calculate and apply responsive sizing
|
|
*/
|
|
_apply_sizing() {
|
|
const viewport_width = $(window).width();
|
|
const viewport_height = $(window).height();
|
|
const is_mobile = viewport_width < 768;
|
|
|
|
// Calculate max width based on viewport
|
|
let max_width = this.data.max_width;
|
|
const viewport_limit = is_mobile ? viewport_width * 0.9 : viewport_width * 0.8;
|
|
max_width = Math.min(max_width, viewport_limit);
|
|
|
|
// Try to constrain to 60% width for better proportions on desktop
|
|
if (!is_mobile) {
|
|
const preferred_width = viewport_width * 0.6;
|
|
if (preferred_width < max_width) {
|
|
max_width = preferred_width;
|
|
}
|
|
}
|
|
|
|
// Apply width
|
|
this.$sid('dialog').css('max-width', max_width + 'px');
|
|
|
|
// Check if content exceeds 80% height
|
|
const content_height = this.$sid('dialog').outerHeight();
|
|
const max_height = viewport_height * 0.8;
|
|
if (content_height > max_height) {
|
|
// Enable scrolling
|
|
this.$sid('dialog').css('max-height', max_height + 'px');
|
|
this.$sid('body').css({
|
|
'overflow-y': 'auto',
|
|
'max-height': max_height - 150 + 'px' // Account for header/footer
|
|
});
|
|
} else {
|
|
// Reset scrolling
|
|
this.$sid('dialog').css('max-height', '');
|
|
this.$sid('body').css({
|
|
'overflow-y': '',
|
|
'max-height': ''
|
|
});
|
|
}
|
|
|
|
// Mobile edge spacing
|
|
if (is_mobile) {
|
|
this.$sid('dialog').css('margin', '5%');
|
|
} else {
|
|
this.$sid('dialog').css('margin', '0');
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Show animation (instant or with fly-in)
|
|
* @param {boolean} animate - Whether to animate the modal entrance
|
|
*/
|
|
async _fade_in() {
|
|
let animate = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
|
|
if (animate) {
|
|
// Initial state: modal positioned above final position
|
|
this.$.css('display', 'flex').css('opacity', '0');
|
|
this.$sid('modal').css({
|
|
'transform': 'translate(0, -50px)',
|
|
'opacity': '0'
|
|
});
|
|
this.$sid('backdrop').css('display', 'block').addClass('show');
|
|
|
|
// Force reflow
|
|
this.$sid('modal')[0].offsetHeight;
|
|
|
|
// Trigger animation
|
|
this.$sid('modal').addClass('show').css({
|
|
'transform': 'translate(0, 0)',
|
|
'opacity': '1'
|
|
});
|
|
this.$.css('opacity', '1');
|
|
|
|
// Wait for animation to complete
|
|
await new Promise(resolve => setTimeout(resolve, 150));
|
|
} else {
|
|
// Disable transitions temporarily for instant display
|
|
this.$sid('dialog').css('transition', 'none');
|
|
|
|
// Show modal and backdrop instantly
|
|
this.$.css('display', 'flex').css('opacity', '1');
|
|
this.$sid('modal').addClass('show').css('opacity', '1');
|
|
this.$sid('backdrop').css('display', 'block').addClass('show');
|
|
|
|
// Force reflow to apply the no-transition state
|
|
this.$sid('dialog')[0].offsetHeight;
|
|
|
|
// Re-enable transitions for future animations
|
|
this.$sid('dialog').css('transition', '');
|
|
}
|
|
return Promise.resolve();
|
|
}
|
|
|
|
/**
|
|
* Focus the first input element in the modal
|
|
*/
|
|
_focus_first_input() {
|
|
// Find first input/textarea/select in modal body
|
|
const $first_input = this.$sid('body').find('input:not([type="hidden"]), textarea, select').first();
|
|
if ($first_input.exists()) {
|
|
requestAnimationFrame(() => {
|
|
$first_input.focus();
|
|
// Select text if it's an input with existing value
|
|
if ($first_input.is('input[type="text"], input[type="email"]') && $first_input.val()) {
|
|
$first_input.select();
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Close the modal instantly
|
|
*/
|
|
async close(result) {
|
|
const that = this;
|
|
|
|
// Mark as not visible
|
|
this.data.is_visible = false;
|
|
|
|
// Remove event listeners
|
|
$(document).off('keydown.rsx_modal_' + this._cid);
|
|
$(window).off('resize.rsx_modal_' + this._cid);
|
|
|
|
// Hide instantly (no fade out)
|
|
this.$.hide();
|
|
this.$sid('backdrop').hide();
|
|
|
|
// Remove from DOM
|
|
this.$.remove();
|
|
this.$sid('backdrop').remove();
|
|
|
|
// Resolve promise
|
|
if (this.data.resolve_fn) {
|
|
this.data.resolve_fn(result);
|
|
this.data.resolve_fn = null;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Apply validation errors to form fields in modal body
|
|
*/
|
|
apply_errors(errors) {
|
|
// Use Form_Utils to apply errors to elements within modal body
|
|
Form_Utils.apply_form_errors(this.$sid('body'), errors);
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/modal/Modal.js (babel) === */
|
|
"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);
|
|
|
|
|
|
/* === rsx/theme/components/page_elements/breadcrumb_item.js (babel) === */
|
|
"use strict";
|
|
|
|
class Breadcrumb_Item extends Component {
|
|
on_create() {
|
|
// Read href from HTML attribute if present
|
|
const href = this.$.attr('href');
|
|
if (href) {
|
|
this.args.href = href;
|
|
}
|
|
|
|
// Read active from HTML attribute if present
|
|
const active = this.$.attr('active');
|
|
if (active !== undefined) {
|
|
this.args.active = true;
|
|
this.$.addClass('active');
|
|
this.$.attr('aria-current', 'page');
|
|
this.$.removeAttr('active'); // Remove the attribute after reading
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/page_elements/client_label_link.js (babel) === */
|
|
"use strict";
|
|
|
|
class Client_Label_Link extends Component {
|
|
on_create() {
|
|
this.data.loading = true;
|
|
this.data.client = null;
|
|
|
|
// Convert client_id to number if it's a numeric string
|
|
if (this.args.client_id) {
|
|
this.args.client_id = value_unless_numeric_string_then_numeric_value(this.args.client_id);
|
|
}
|
|
}
|
|
async on_load() {
|
|
// Load client data if we have an ID
|
|
if (this.args.client_id) {
|
|
try {
|
|
this.data.client = await Frontend_Contacts_Controller.get_client({
|
|
client_id: this.args.client_id
|
|
});
|
|
this.data.loading = false;
|
|
} catch (error) {
|
|
console.error('Failed to load client:', error);
|
|
this.data.loading = false;
|
|
}
|
|
} else {
|
|
this.data.loading = false;
|
|
}
|
|
}
|
|
on_render() {
|
|
// Set href dynamically after each render
|
|
if (this.args.client_id) {
|
|
const href = Rsx.Route('Frontend_Clients_Controller', 'view', this.args.client_id);
|
|
this.$.attr('href', href);
|
|
} else {
|
|
this.$.attr('href', '#');
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get or set the client_id
|
|
* @param {number} [client_id] - If provided, sets the client_id and reloads
|
|
* @returns {number} Current client_id when called as getter
|
|
*/
|
|
val(client_id) {
|
|
if (arguments.length === 0) {
|
|
// Getter
|
|
return this.args.client_id;
|
|
} else {
|
|
// Setter - update client_id and reload
|
|
this.args.client_id = value_unless_numeric_string_then_numeric_value(client_id);
|
|
this.data.loading = true;
|
|
this.data.client = null;
|
|
|
|
// Reload client data and re-render (on_render will update href)
|
|
this.on_load().then(() => {
|
|
this.render();
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/page_elements/client_label.js (babel) === */
|
|
"use strict";
|
|
|
|
class Client_Label extends Component {
|
|
on_create() {
|
|
this.data.loading = true;
|
|
this.data.client = null;
|
|
|
|
// Convert client_id to number if it's a numeric string
|
|
if (this.args.client_id) {
|
|
this.args.client_id = value_unless_numeric_string_then_numeric_value(this.args.client_id);
|
|
}
|
|
}
|
|
async on_load() {
|
|
// Load client data if we have an ID
|
|
if (this.args.client_id) {
|
|
try {
|
|
this.data.client = await Frontend_Contacts_Controller.get_client({
|
|
client_id: this.args.client_id
|
|
});
|
|
this.data.loading = false;
|
|
} catch (error) {
|
|
console.error('Failed to load client:', error);
|
|
this.data.loading = false;
|
|
}
|
|
} else {
|
|
this.data.loading = false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get or set the client_id
|
|
* @param {number} [client_id] - If provided, sets the client_id and reloads
|
|
* @returns {number} Current client_id when called as getter
|
|
*/
|
|
val(client_id) {
|
|
if (arguments.length === 0) {
|
|
// Getter
|
|
return this.args.client_id;
|
|
} else {
|
|
// Setter - update client_id and reload
|
|
this.args.client_id = value_unless_numeric_string_then_numeric_value(client_id);
|
|
this.data.loading = true;
|
|
this.data.client = null;
|
|
|
|
// Reload client data and re-render (on_render will update href)
|
|
this.on_load().then(() => {
|
|
this.render();
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/inputs/form_input_abstract.js (babel) === */
|
|
"use strict";
|
|
|
|
/**
|
|
* Form_Input_Abstract - Base class for all form input widgets
|
|
*
|
|
* Defines the interface that all form widgets must implement.
|
|
* This ensures consistency across all input types (text, select, wysiwyg, etc.)
|
|
*
|
|
* REQUIRED METHODS (must be implemented by subclasses):
|
|
* - val() - Get current value (no arguments)
|
|
* - val(value) - Set value (one argument)
|
|
* - seed() - Fills the widget with random test data (optional)
|
|
*
|
|
* All widgets must:
|
|
* - Have .Widget CSS class
|
|
* - Have data-name attribute set by Form_Field
|
|
*/
|
|
class Form_Input_Abstract extends Component {
|
|
/**
|
|
* val() - Get or set the current value
|
|
* Subclasses MUST implement this method
|
|
*
|
|
* @param {*} [value] - If provided, sets the value. If omitted, returns the value.
|
|
* @returns {*} The current value when called as getter
|
|
*/
|
|
val(value) {
|
|
if (arguments.length === 0) {
|
|
// Getter
|
|
throw new Error(`${this.constructor.name} must implement val() getter`);
|
|
} else {
|
|
// Setter
|
|
throw new Error(`${this.constructor.name} must implement val(value) setter`);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Seed - Fill with random test data (optional)
|
|
* Subclasses MAY implement this method
|
|
*/
|
|
async seed() {
|
|
// Optional - widgets can override if they support seeding
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/inputs/text_input.js (babel) === */
|
|
"use strict";
|
|
|
|
class Text_Input extends Form_Input_Abstract {
|
|
on_create() {
|
|
this.data.value = '';
|
|
}
|
|
|
|
/**
|
|
* val() - Get or set the input value
|
|
* @param {string} [value] - If provided, sets the value
|
|
* @returns {string} The current value when called as getter
|
|
*/
|
|
val(value) {
|
|
if (arguments.length === 0) {
|
|
// Getter
|
|
return this.$sid('input').val();
|
|
} else {
|
|
// Setter
|
|
this.data.value = value || '';
|
|
if (this.$sid('input').exists()) {
|
|
this.$sid('input').val(this.data.value);
|
|
}
|
|
}
|
|
}
|
|
async seed() {
|
|
if (this.args.seeder) {
|
|
// TODO: Implement Rsx_Random_Values endpoint
|
|
// let value = await Rsx_Random_Values[this.args.seeder]();
|
|
// For now, just use placeholder text
|
|
let value = 'Test ' + (this.args.seeder || 'Value');
|
|
this.val(value);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/inputs/checkbox_input.js (babel) === */
|
|
"use strict";
|
|
|
|
class Checkbox_Input extends Form_Input_Abstract {
|
|
on_create() {
|
|
this.data.checked = false;
|
|
this.checked_value = this.args.checked_value || '1';
|
|
this.unchecked_value = this.args.unchecked_value || '0';
|
|
}
|
|
on_ready() {
|
|
// Connect label clicks to checkbox
|
|
const $input = this.$sid('input');
|
|
const $label = this.$sid('label');
|
|
if ($label.exists()) {
|
|
const input_id = $input.attr('id');
|
|
$label.attr('for', input_id);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* val() - Get or set the checkbox state
|
|
* @param {string|boolean} [value] - If provided, sets the checked state
|
|
* @returns {string} The checked_value or unchecked_value when called as getter
|
|
*/
|
|
val(value) {
|
|
if (arguments.length === 0) {
|
|
// Getter
|
|
const is_checked = this.$sid('input').prop('checked');
|
|
return is_checked ? this.checked_value : this.unchecked_value;
|
|
} else {
|
|
// Setter - accepts boolean, checked_value, or unchecked_value
|
|
let should_check = false;
|
|
if (typeof value === 'boolean') {
|
|
should_check = value;
|
|
} else if (value === this.checked_value || value === '1' || value === 1 || value === true) {
|
|
should_check = true;
|
|
}
|
|
this.data.checked = should_check;
|
|
if (this.$sid('input').exists()) {
|
|
this.$sid('input').prop('checked', should_check);
|
|
}
|
|
}
|
|
}
|
|
async seed() {
|
|
// Randomly check or uncheck
|
|
this.val(Math.random() > 0.5);
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/inputs/wysiwyg_input.js (babel) === */
|
|
"use strict";
|
|
|
|
/**
|
|
* Wysiwyg_Input - WYSIWYG editor widget using Quill
|
|
*
|
|
* Implements the form widget interface:
|
|
* - val() - Get/set HTML content
|
|
* - seed() - Fills with random content
|
|
*/
|
|
class Wysiwyg_Input extends Form_Input_Abstract {
|
|
on_create() {
|
|
this.quill = null;
|
|
}
|
|
on_ready() {
|
|
// Wait for Quill to be loaded, then initialize
|
|
const that = this;
|
|
quill_ready(function () {
|
|
that._initialize_quill();
|
|
});
|
|
}
|
|
_initialize_quill() {
|
|
// Initialize Quill editor
|
|
this.quill = new Quill(this.$sid('editor')[0], {
|
|
theme: 'snow',
|
|
placeholder: this.args.placeholder || 'Enter text...',
|
|
modules: {
|
|
toolbar: [[{
|
|
'header': [1, 2, 3, false]
|
|
}], ['bold', 'italic', 'underline', 'strike'], ['blockquote', 'code-block'], [{
|
|
'list': 'ordered'
|
|
}, {
|
|
'list': 'bullet'
|
|
}], [{
|
|
'indent': '-1'
|
|
}, {
|
|
'indent': '+1'
|
|
}], ['link', 'image'], ['clean']]
|
|
}
|
|
});
|
|
|
|
// Update hidden input on text change
|
|
const that = this;
|
|
this.quill.on('text-change', function () {
|
|
that.$sid('hidden_input').val(that.quill.root.innerHTML);
|
|
});
|
|
}
|
|
|
|
/**
|
|
* val() - Get or set HTML content
|
|
* @param {string} [value] - If provided, sets the HTML content
|
|
* @returns {string} The HTML content when called as getter
|
|
*/
|
|
val(value) {
|
|
if (arguments.length === 0) {
|
|
// Getter
|
|
if (!this.quill) return '';
|
|
return this.quill.root.innerHTML;
|
|
} else {
|
|
// Setter
|
|
if (!this.quill) {
|
|
// Quill not ready yet, wait and try again
|
|
const that = this;
|
|
setTimeout(() => that.val(value), 100);
|
|
return;
|
|
}
|
|
if (value) {
|
|
this.quill.root.innerHTML = value;
|
|
this.$sid('hidden_input').val(value);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Seed - Fill with random content for testing
|
|
*/
|
|
async seed() {
|
|
if (!this.quill) return;
|
|
const sample_content = `
|
|
<h2>Sample Heading</h2>
|
|
<p>This is a sample paragraph with <strong>bold text</strong> and <em>italic text</em>.</p>
|
|
<ul>
|
|
<li>First bullet point</li>
|
|
<li>Second bullet point</li>
|
|
<li>Third bullet point</li>
|
|
</ul>
|
|
<p>Another paragraph with <a href="#">a sample link</a>.</p>
|
|
`;
|
|
this.val(sample_content);
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/inputs/select_input.js (babel) === */
|
|
"use strict";
|
|
|
|
class Select_Input extends Form_Input_Abstract {
|
|
on_create() {
|
|
this.data.value = '';
|
|
|
|
// Parse options if passed as JSON string
|
|
if (typeof this.args.options === 'string') {
|
|
try {
|
|
// Decode HTML entities before parsing JSON
|
|
// This handles cases where JSON is passed through Blade {!! !!} syntax
|
|
const decoded = $('<textarea>').html(this.args.options).text();
|
|
this.args.options = json_decode(decoded);
|
|
} catch (e) {
|
|
console.error('Failed to parse options JSON:', e);
|
|
this.args.options = [];
|
|
}
|
|
}
|
|
|
|
// Convert object options to array format
|
|
if (this.args.options && typeof this.args.options === 'object' && !is_array(this.args.options)) {
|
|
this.args.options = Object.entries(this.args.options).map(_ref => {
|
|
let [value, label] = _ref;
|
|
return {
|
|
value,
|
|
label
|
|
};
|
|
});
|
|
}
|
|
}
|
|
on_ready() {
|
|
// Initialize Tom Select
|
|
let config = {
|
|
placeholder: this.args.placeholder || '',
|
|
allowEmptyOption: true,
|
|
create: false,
|
|
maxOptions: null,
|
|
// Show all options (default is 50)
|
|
plugins: ['dropdown_input'],
|
|
// Enable search in dropdown
|
|
onInitialize: function () {
|
|
// Keep Bootstrap form-select class
|
|
this.control.classList.add('form-select');
|
|
}
|
|
};
|
|
this.tom_select = new TomSelect(this.$sid('input').get(0), config);
|
|
|
|
// Set initial value if provided
|
|
if (this.data.value) {
|
|
this.tom_select.setValue(this.data.value, true);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* val() - Get or set the selected value
|
|
* @param {string} [value] - If provided, sets the value
|
|
* @returns {string} The current value when called as getter
|
|
*/
|
|
val(value) {
|
|
if (arguments.length === 0) {
|
|
// Getter
|
|
if (this.tom_select) {
|
|
return this.tom_select.getValue();
|
|
}
|
|
return this.$sid('input').val();
|
|
} else {
|
|
// Setter
|
|
this.data.value = value || '';
|
|
if (this.tom_select) {
|
|
this.tom_select.setValue(this.data.value, true);
|
|
} else if (this.$sid('input').exists()) {
|
|
this.$sid('input').val(this.data.value);
|
|
}
|
|
}
|
|
}
|
|
async seed() {
|
|
if (this.args.seeder) {
|
|
// TODO: Implement Rsx_Random_Values endpoint
|
|
let value = 'Test ' + (this.args.seeder || 'Value');
|
|
this.val(value);
|
|
} else if (this.args.options && this.args.options.length > 0) {
|
|
// Select random option
|
|
let random_index = Math.floor(Math.random() * this.args.options.length);
|
|
let random_opt = this.args.options[random_index];
|
|
let random_value = typeof random_opt === 'object' ? random_opt.value : random_opt;
|
|
this.val(random_value);
|
|
}
|
|
}
|
|
on_destroy() {
|
|
// Clean up Tom Select instance
|
|
if (this.tom_select) {
|
|
this.tom_select.destroy();
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/inputs/ajax_select_input.js (babel) === */
|
|
"use strict";
|
|
|
|
class Ajax_Select_Input extends Select_Input {
|
|
on_create() {
|
|
// Initialize empty select values array
|
|
this.data.select_values = [];
|
|
|
|
// Store for value set before initialization completes
|
|
this._pending_value = null;
|
|
|
|
// Call parent to do basic setup
|
|
super.on_create();
|
|
}
|
|
async on_load() {
|
|
// Load options from Ajax endpoint if provided
|
|
if (this.args.data) {
|
|
try {
|
|
const response = await fetch(this.args.data);
|
|
if (!response.ok) {
|
|
throw new Error(`HTTP error! status: ${response.status}`);
|
|
}
|
|
const data = await response.json();
|
|
this.data.select_values = data;
|
|
} catch (error) {
|
|
console.error('Failed to load select options:', error);
|
|
this.data.select_values = [];
|
|
}
|
|
}
|
|
}
|
|
on_ready() {
|
|
// Call parent to initialize Tom Select
|
|
super.on_ready();
|
|
|
|
// If a value was set before initialization, apply it now
|
|
if (this._pending_value !== null) {
|
|
if (this.tom_select) {
|
|
this.tom_select.setValue(this._pending_value, true);
|
|
} else if (this.$sid('input').exists()) {
|
|
this.$sid('input').val(this._pending_value);
|
|
}
|
|
this.data.value = this._pending_value;
|
|
this._pending_value = null;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* val() - Get or set the selected value
|
|
* Handles calls before Tom Select initialization completes
|
|
* @param {string} [value] - If provided, sets the value
|
|
* @returns {string} The current value when called as getter
|
|
*/
|
|
val(value) {
|
|
if (arguments.length === 0) {
|
|
// Getter
|
|
if (this.tom_select) {
|
|
// Initialized - get from Tom Select
|
|
return this.tom_select.getValue();
|
|
} else if (this._pending_value !== null) {
|
|
// Not yet initialized - return pending value
|
|
return this._pending_value;
|
|
} else if (this.data.value) {
|
|
// Return data value
|
|
return this.data.value;
|
|
}
|
|
return '';
|
|
} else {
|
|
// Setter
|
|
if (this.tom_select) {
|
|
// Initialized - set via Tom Select
|
|
this.data.value = value || '';
|
|
this.tom_select.setValue(this.data.value, true);
|
|
} else {
|
|
// Not yet initialized - store for later
|
|
this._pending_value = value || '';
|
|
this.data.value = value || '';
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/inputs/currency_input.js (babel) === */
|
|
"use strict";
|
|
|
|
/**
|
|
* Currency_Input
|
|
*
|
|
* Extends Text_Input to provide automatic currency formatting.
|
|
*
|
|
* Features:
|
|
* - Adds thousands separators (commas) every 3 digits
|
|
* - Optional currency symbol prefix (default: hidden)
|
|
* - Optional decimal support (default: disabled)
|
|
* - Smart backspace over formatting characters
|
|
* - No mid-string formatting (waits for blur)
|
|
*
|
|
* Arguments:
|
|
* - $allow_decimals - Allow 2 decimal places (default: false)
|
|
* - $show_symbol - Show currency symbol (default: false)
|
|
* - $currency_symbol - Currency symbol to use (default: "$")
|
|
*
|
|
* Usage:
|
|
* <Currency_Input />
|
|
* <Currency_Input $show_symbol=true />
|
|
* <Currency_Input $allow_decimals=true />
|
|
* <Currency_Input $show_symbol=true $allow_decimals=true $currency_symbol="€" />
|
|
*
|
|
* Behavior:
|
|
* - Type "1234567" -> displays "1,234,567", val() returns "1234567"
|
|
* - Type "1234567.89" (with decimals) -> displays "1,234,567.89", val() returns "1234567.89"
|
|
* - With symbol: displays "$1,234,567", val() still returns "1234567"
|
|
*/
|
|
class Currency_Input extends Text_Input {
|
|
on_create() {
|
|
super.on_create();
|
|
|
|
// Set defaults for options
|
|
if (this.args.allow_decimals === undefined) {
|
|
this.args.allow_decimals = false;
|
|
}
|
|
if (this.args.show_symbol === undefined) {
|
|
this.args.show_symbol = false;
|
|
}
|
|
if (this.args.currency_symbol === undefined) {
|
|
this.args.currency_symbol = '$';
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Format currency with commas and optional symbol
|
|
* @param {string} value - Numeric value (may include decimal)
|
|
* @returns {string} Formatted currency string
|
|
*/
|
|
_format_currency(value) {
|
|
if (!value) {
|
|
return '';
|
|
}
|
|
|
|
// Split into integer and decimal parts
|
|
let parts = value.split('.');
|
|
let integer_part = parts[0];
|
|
let decimal_part = parts[1];
|
|
|
|
// Add commas to integer part
|
|
integer_part = integer_part.replace(/\B(?=(\d{3})+(?!\d))/g, ',');
|
|
|
|
// Reconstruct with decimal if allowed
|
|
let formatted = integer_part;
|
|
if (this.args.allow_decimals && decimal_part !== undefined) {
|
|
// Limit to 2 decimal places
|
|
decimal_part = decimal_part.substr(0, 2);
|
|
formatted += '.' + decimal_part;
|
|
}
|
|
|
|
// Add currency symbol if enabled
|
|
if (this.args.show_symbol) {
|
|
formatted = this.args.currency_symbol + formatted;
|
|
}
|
|
return formatted;
|
|
}
|
|
|
|
/**
|
|
* Extract numeric value from formatted string
|
|
* @param {string} formatted - Formatted currency string
|
|
* @returns {string} Clean numeric value (digits and decimal only)
|
|
*/
|
|
_get_numeric_value(formatted) {
|
|
if (!formatted) {
|
|
return '';
|
|
}
|
|
|
|
// Remove currency symbol and commas
|
|
let cleaned = formatted.replace(/[^0-9.]/g, '');
|
|
|
|
// Ensure only one decimal point
|
|
const decimal_count = (cleaned.match(/\./g) || []).length;
|
|
if (decimal_count > 1) {
|
|
// Keep only first decimal point
|
|
const first_decimal = cleaned.indexOf('.');
|
|
cleaned = cleaned.substr(0, first_decimal + 1) + cleaned.substr(first_decimal + 1).replace(/\./g, '');
|
|
}
|
|
return cleaned;
|
|
}
|
|
|
|
/**
|
|
* val() - Get or set the currency value
|
|
* Getter returns numeric string (no commas, no symbol)
|
|
* Setter accepts anything and formats with commas/symbol
|
|
* @param {string} [value]
|
|
* @returns {string}
|
|
*/
|
|
val(value) {
|
|
if (arguments.length === 0) {
|
|
// Getter - return numeric value only
|
|
const raw = this.$sid('input').val();
|
|
return this._get_numeric_value(raw);
|
|
} else {
|
|
// Setter - format and display
|
|
if (!value) {
|
|
this.data.value = '';
|
|
if (this.$sid('input').exists()) {
|
|
this.$sid('input').val('');
|
|
}
|
|
return;
|
|
}
|
|
|
|
// Clean the input value
|
|
const numeric = this._get_numeric_value(str(value));
|
|
const formatted = this._format_currency(numeric);
|
|
this.data.value = formatted;
|
|
if (this.$sid('input').exists()) {
|
|
this.$sid('input').val(formatted);
|
|
}
|
|
}
|
|
}
|
|
on_ready() {
|
|
super.on_ready();
|
|
const $input = this.$sid('input');
|
|
|
|
// Handle keydown to intercept backspace at end of string
|
|
$input.on('keydown', e => {
|
|
const raw = $input.val();
|
|
|
|
// Only handle backspace key
|
|
if (e.key !== 'Backspace') {
|
|
return;
|
|
}
|
|
const input_element = $input[0];
|
|
const cursor_pos = input_element.selectionStart;
|
|
const cursor_end = input_element.selectionEnd;
|
|
const value_length = raw.length;
|
|
|
|
// Only handle if cursor is at the end and no selection
|
|
if (cursor_pos === value_length && cursor_pos === cursor_end) {
|
|
// Check if character before cursor is non-numeric
|
|
if (cursor_pos > 0) {
|
|
const char_before = raw.charAt(cursor_pos - 1);
|
|
if (!/[0-9]/.test(char_before)) {
|
|
// Character before cursor is not a digit
|
|
// Delete the last digit instead
|
|
e.preventDefault();
|
|
const numeric = this._get_numeric_value(raw);
|
|
if (numeric.length > 0) {
|
|
// Remove last character from numeric value
|
|
const new_numeric = numeric.substr(0, numeric.length - 1);
|
|
const formatted = this._format_currency(new_numeric);
|
|
$input.val(formatted);
|
|
|
|
// Place cursor at end
|
|
setTimeout(() => {
|
|
const new_length = $input.val().length;
|
|
input_element.setSelectionRange(new_length, new_length);
|
|
}, 0);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
});
|
|
|
|
// Handle input event for live formatting
|
|
$input.on('input', () => {
|
|
const raw = $input.val();
|
|
const input_element = $input[0];
|
|
const cursor_pos = input_element.selectionStart;
|
|
const value_length = raw.length;
|
|
|
|
// Only apply live formatting if cursor is at the end
|
|
if (cursor_pos === value_length) {
|
|
// Extract numeric value
|
|
let numeric = this._get_numeric_value(raw);
|
|
|
|
// Limit decimal places to 2 if decimals allowed
|
|
if (this.args.allow_decimals) {
|
|
const parts = numeric.split('.');
|
|
if (parts[1] && parts[1].length > 2) {
|
|
numeric = parts[0] + '.' + parts[1].substr(0, 2);
|
|
}
|
|
}
|
|
|
|
// Format the numeric value
|
|
const formatted = this._format_currency(numeric);
|
|
$input.val(formatted);
|
|
} else {
|
|
// Cursor is not at end - user is editing in the middle
|
|
// Don't format, just clean invalid characters
|
|
const numeric = this._get_numeric_value(raw);
|
|
|
|
// Only update if we removed invalid characters
|
|
if (this._format_currency(numeric) !== raw) {
|
|
// Preserve just the numeric characters
|
|
const symbol_offset = this.args.show_symbol ? this.args.currency_symbol.length : 0;
|
|
const cleaned = (this.args.show_symbol ? this.args.currency_symbol : '') + numeric;
|
|
if (cleaned !== raw) {
|
|
$input.val(cleaned);
|
|
// Restore cursor position (approximately)
|
|
const new_cursor = Math.min(cursor_pos, cleaned.length);
|
|
input_element.setSelectionRange(new_cursor, new_cursor);
|
|
}
|
|
}
|
|
}
|
|
});
|
|
|
|
// Handle blur to reformat when done editing
|
|
$input.on('blur', () => {
|
|
const raw = $input.val();
|
|
if (!raw) {
|
|
return;
|
|
}
|
|
|
|
// Reformat the entire value on blur
|
|
const numeric = this._get_numeric_value(raw);
|
|
const formatted = this._format_currency(numeric);
|
|
$input.val(formatted);
|
|
});
|
|
|
|
// Handle focus to select all for easy replacement
|
|
$input.on('focus', () => {
|
|
setTimeout(() => {
|
|
$input[0].select();
|
|
}, 0);
|
|
});
|
|
|
|
// Initialize formatting if there's a value
|
|
const initial_value = $input.val();
|
|
if (initial_value) {
|
|
this.val(initial_value);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/inputs/phone_text_input.js (babel) === */
|
|
"use strict";
|
|
|
|
/**
|
|
* Phone_Text_Input
|
|
*
|
|
* Extends Text_Input to provide automatic phone number formatting.
|
|
*
|
|
* Features:
|
|
* - US Mode (default): Formats as (XXX) XXX-XXXX on every keystroke
|
|
* - International Mode: Triggered by starting with '+', disables formatting
|
|
* - val() getter returns formatted string as displayed
|
|
* - val() setter accepts any format and displays appropriately
|
|
*
|
|
* Usage:
|
|
* <Phone_Text_Input $placeholder="Phone number" />
|
|
*
|
|
* Behavior:
|
|
* - Type "5551234567" -> displays "(555) 123-4567", val() returns "(555) 123-4567"
|
|
* - Type "+44 20 7123 4567" -> displays as typed, val() returns "+44 20 7123 4567"
|
|
* - Leading "1" is stripped: "15551234567" -> "(555) 123-4567"
|
|
*/
|
|
class Phone_Text_Input extends Text_Input {
|
|
on_create() {
|
|
super.on_create();
|
|
this._is_international = false;
|
|
}
|
|
|
|
/**
|
|
* Check if input is in international mode (starts with +)
|
|
* @param {string} value
|
|
* @returns {boolean}
|
|
*/
|
|
_check_international_mode(value) {
|
|
return value && str(value).charAt(0) === '+';
|
|
}
|
|
|
|
/**
|
|
* Format US phone number as (XXX) XXX-XXXX
|
|
* @param {string} digits - Clean numeric string (should be 10 digits or less after processing)
|
|
* @returns {string} Formatted phone number
|
|
*/
|
|
_format_us_phone(digits) {
|
|
// Format based on length (assumes digits are already cleaned and limited to 10)
|
|
if (digits.length >= 6) {
|
|
// (XXX) XXX-XXXX
|
|
return '(' + digits.substr(0, 3) + ') ' + digits.substr(3, 3) + '-' + digits.substr(6);
|
|
} else if (digits.length >= 3) {
|
|
// (XXX) XXX
|
|
return '(' + digits.substr(0, 3) + ') ' + digits.substr(3);
|
|
} else if (digits.length > 0) {
|
|
// (XX
|
|
return '(' + digits;
|
|
}
|
|
return digits;
|
|
}
|
|
|
|
/**
|
|
* val() - Get or set the phone number
|
|
* Getter returns formatted value as displayed (with parens, dashes, etc)
|
|
* Setter accepts anything and formats appropriately
|
|
* @param {string} [value]
|
|
* @returns {string}
|
|
*/
|
|
val(value) {
|
|
if (arguments.length === 0) {
|
|
// Getter - return the formatted value as displayed
|
|
return this.$sid('input').val() || '';
|
|
} else {
|
|
// Setter - format and display
|
|
if (!value) {
|
|
this.data.value = '';
|
|
if (this.$sid('input').exists()) {
|
|
this.$sid('input').val('');
|
|
}
|
|
return;
|
|
}
|
|
const str_value = str(value);
|
|
if (this._check_international_mode(str_value)) {
|
|
// International mode - no formatting
|
|
this.data.value = str_value;
|
|
if (this.$sid('input').exists()) {
|
|
this.$sid('input').val(str_value);
|
|
}
|
|
} else {
|
|
// US mode - clean digits and format
|
|
const digits = str_value.replace(/[^0-9]/g, '');
|
|
|
|
// Determine which digits to format
|
|
let digits_to_format;
|
|
if (digits.length === 11 && digits.charAt(0) === '1' && /[2-9]/.test(digits.charAt(1))) {
|
|
// Strip US country code
|
|
digits_to_format = digits.substr(1);
|
|
} else if (digits.length > 10) {
|
|
// Take first 10
|
|
digits_to_format = digits.substr(0, 10);
|
|
} else {
|
|
// Use as-is
|
|
digits_to_format = digits;
|
|
}
|
|
const formatted = this._format_us_phone(digits_to_format);
|
|
this.data.value = formatted;
|
|
if (this.$sid('input').exists()) {
|
|
this.$sid('input').val(formatted);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
on_ready() {
|
|
super.on_ready();
|
|
const $input = this.$sid('input');
|
|
let _last_cursor_position = null;
|
|
|
|
// Handle keydown to intercept backspace at end of string
|
|
$input.on('keydown', e => {
|
|
const raw = $input.val();
|
|
|
|
// Skip if international mode
|
|
if (this._check_international_mode(raw)) {
|
|
return;
|
|
}
|
|
|
|
// Only handle backspace key
|
|
if (e.key !== 'Backspace') {
|
|
return;
|
|
}
|
|
const input_element = $input[0];
|
|
const cursor_pos = input_element.selectionStart;
|
|
const cursor_end = input_element.selectionEnd;
|
|
const value_length = raw.length;
|
|
|
|
// Only handle if cursor is at the end and no selection
|
|
if (cursor_pos === value_length && cursor_pos === cursor_end) {
|
|
// Check if character before cursor is non-numeric
|
|
if (cursor_pos > 0) {
|
|
const char_before = raw.charAt(cursor_pos - 1);
|
|
if (!/[0-9]/.test(char_before)) {
|
|
// Character before cursor is not a digit
|
|
// Delete the last digit instead
|
|
e.preventDefault();
|
|
const digits = raw.replace(/[^0-9]/g, '');
|
|
if (digits.length > 0) {
|
|
const new_digits = digits.substr(0, digits.length - 1);
|
|
const formatted = this._format_us_phone(new_digits);
|
|
$input.val(formatted);
|
|
|
|
// Place cursor at end
|
|
setTimeout(() => {
|
|
const new_length = $input.val().length;
|
|
input_element.setSelectionRange(new_length, new_length);
|
|
}, 0);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
});
|
|
|
|
// Handle input event for live formatting
|
|
$input.on('input', () => {
|
|
const raw = $input.val();
|
|
if (this._check_international_mode(raw)) {
|
|
// International mode - allow anything
|
|
this._is_international = true;
|
|
// No formatting, no restrictions
|
|
return;
|
|
}
|
|
|
|
// US mode
|
|
this._is_international = false;
|
|
const input_element = $input[0];
|
|
const cursor_pos = input_element.selectionStart;
|
|
const value_length = raw.length;
|
|
|
|
// Only apply live formatting if cursor is at the end
|
|
if (cursor_pos === value_length) {
|
|
// Remove any non-digit, non-formatting characters
|
|
const cleaned = raw.replace(/[^0-9\s\-()]/g, '');
|
|
const digits = cleaned.replace(/[^0-9]/g, '');
|
|
|
|
// Determine which digits to format
|
|
let digits_to_format;
|
|
if (digits.length === 11 && digits.charAt(0) === '1' && /[2-9]/.test(digits.charAt(1))) {
|
|
// Exactly 11 digits starting with "1" followed by valid area code digit (2-9)
|
|
// This is a US country code - strip the leading 1
|
|
digits_to_format = digits.substr(1);
|
|
} else if (digits.length > 10) {
|
|
// More than 10 digits - just take the first 10 and ignore the rest
|
|
digits_to_format = digits.substr(0, 10);
|
|
} else {
|
|
// 10 or fewer digits - use as-is
|
|
digits_to_format = digits;
|
|
}
|
|
|
|
// Format the digits
|
|
const formatted = this._format_us_phone(digits_to_format);
|
|
$input.val(formatted);
|
|
} else {
|
|
// Cursor is not at end - user is editing in the middle
|
|
// Don't format, just clean invalid characters
|
|
const cleaned = raw.replace(/[^0-9\s\-()]/g, '');
|
|
if (cleaned !== raw) {
|
|
$input.val(cleaned);
|
|
// Restore cursor position
|
|
input_element.setSelectionRange(cursor_pos, cursor_pos);
|
|
}
|
|
}
|
|
});
|
|
|
|
// Handle blur to reformat when done editing
|
|
$input.on('blur', () => {
|
|
const raw = $input.val();
|
|
|
|
// Skip if international mode or empty
|
|
if (this._check_international_mode(raw) || !raw) {
|
|
return;
|
|
}
|
|
|
|
// Reformat the entire value on blur
|
|
const digits = raw.replace(/[^0-9]/g, '');
|
|
|
|
// Determine which digits to format
|
|
let digits_to_format;
|
|
if (digits.length === 11 && digits.charAt(0) === '1' && /[2-9]/.test(digits.charAt(1))) {
|
|
// Exactly 11 digits starting with "1" followed by valid area code digit (2-9)
|
|
// This is a US country code - strip the leading 1
|
|
digits_to_format = digits.substr(1);
|
|
} else if (digits.length > 10) {
|
|
// More than 10 digits - just take the first 10
|
|
digits_to_format = digits.substr(0, 10);
|
|
} else {
|
|
// 10 or fewer digits - use as-is
|
|
digits_to_format = digits;
|
|
}
|
|
const formatted = this._format_us_phone(digits_to_format);
|
|
$input.val(formatted);
|
|
});
|
|
|
|
// Initialize formatting if there's a value
|
|
const initial_value = $input.val();
|
|
if (initial_value) {
|
|
this.val(initial_value);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/inputs/state_select_input.js (babel) === */
|
|
"use strict";
|
|
|
|
class State_Select_Input extends Ajax_Select_Input {
|
|
async on_load() {
|
|
// Initialize country code from args or default to US
|
|
if (!this.data.country_code) {
|
|
this.data.country_code = this.args.country_code || 'US';
|
|
}
|
|
|
|
// Load states via Ajax endpoint if country code is set
|
|
if (this.data.country_code) {
|
|
this.data.select_values = await Rsx_Reference_Data_Controller.states({
|
|
country: this.data.country_code
|
|
});
|
|
|
|
// If no states returned, add N/A option
|
|
if (!this.data.select_values || this.data.select_values.length === 0) {
|
|
this.data.select_values = [{
|
|
value: 'N/A',
|
|
label: 'N/A'
|
|
}];
|
|
}
|
|
} else {
|
|
this.data.select_values = [];
|
|
}
|
|
}
|
|
on_create() {
|
|
// Set default placeholder if not provided
|
|
if (!this.args.placeholder) {
|
|
this.args.placeholder = 'Select State...';
|
|
}
|
|
|
|
// Initialize country code in data
|
|
this.data.country_code = this.args.country_code || '';
|
|
|
|
// Cache for selected state per country code
|
|
this._state_cache = {};
|
|
|
|
// Call parent to initialize Ajax_Select_Input
|
|
super.on_create();
|
|
}
|
|
on_ready() {
|
|
// Call parent to initialize Tom Select
|
|
super.on_ready();
|
|
|
|
// Check if this is N/A case (no states for country)
|
|
const is_na = this.data.select_values.length === 1 && this.data.select_values[0].value === 'N/A';
|
|
|
|
// Disable if no country code or N/A case
|
|
if ((!this.data.country_code || is_na) && this.tom_select) {
|
|
this.tom_select.disable();
|
|
}
|
|
|
|
// Set value to N/A if that's the only option
|
|
if (is_na) {
|
|
this.val('N/A');
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Set country code and reload state list
|
|
* @param {string} country_code - ISO country code (e.g., 'US', 'CA')
|
|
*/
|
|
async set_country_code(country_code) {
|
|
// Cache the current value for the current country before switching
|
|
const current_country = this.data.country_code;
|
|
const current_value = this.val();
|
|
if (current_country && current_value && current_value !== 'N/A') {
|
|
this._state_cache[current_country] = current_value;
|
|
}
|
|
|
|
// Update country code
|
|
this.data.country_code = country_code;
|
|
|
|
// Disable the selector while loading
|
|
if (this.tom_select) {
|
|
this.tom_select.disable();
|
|
}
|
|
|
|
// Load new state list
|
|
try {
|
|
this.data.select_values = await Rsx_Reference_Data_Controller.states({
|
|
country: country_code
|
|
});
|
|
|
|
// Race condition check: verify country hasn't changed during the request
|
|
if (this.data.country_code !== country_code) {
|
|
// Country changed while request was in flight - ignore this response
|
|
return;
|
|
}
|
|
|
|
// If no states returned, add N/A option
|
|
if (!this.data.select_values || this.data.select_values.length === 0) {
|
|
this.data.select_values = [{
|
|
value: 'N/A',
|
|
label: 'N/A'
|
|
}];
|
|
}
|
|
|
|
// Re-render the widget with new states
|
|
this.redraw();
|
|
|
|
// Re-initialize Tom Select after redraw
|
|
if (this.tom_select) {
|
|
this.tom_select.destroy();
|
|
}
|
|
|
|
// Re-run on_ready to set up Tom Select again
|
|
this.on_ready();
|
|
|
|
// Check if this is N/A case
|
|
const is_na = this.data.select_values.length === 1 && this.data.select_values[0].value === 'N/A';
|
|
if (is_na) {
|
|
// Set to N/A and keep disabled
|
|
this.val('N/A');
|
|
if (this.tom_select) {
|
|
this.tom_select.disable();
|
|
}
|
|
} else {
|
|
// Try to restore cached value for this country
|
|
const cached_value = this._state_cache[country_code];
|
|
if (cached_value) {
|
|
const value_exists = this.data.select_values.some(opt => (typeof opt === 'object' ? opt.value : opt) === cached_value);
|
|
if (value_exists) {
|
|
this.val(cached_value);
|
|
} else {
|
|
this.val(''); // Clear if cached value not in new list
|
|
}
|
|
} else {
|
|
this.val(''); // No cached value - leave empty
|
|
}
|
|
|
|
// Enable the widget now that we have a country with states
|
|
if (this.tom_select) {
|
|
this.tom_select.enable();
|
|
}
|
|
}
|
|
} catch (error) {
|
|
console.error('Failed to load states for country:', country_code, error);
|
|
this.data.select_values = [];
|
|
|
|
// Re-enable even on error
|
|
if (this.tom_select) {
|
|
this.tom_select.enable();
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Override val() to update cache when user manually selects a state
|
|
*/
|
|
val(value) {
|
|
if (arguments.length === 0) {
|
|
// Getter - use parent implementation
|
|
return super.val();
|
|
} else {
|
|
// Setter - update cache and call parent
|
|
if (this.data.country_code && value && value !== 'N/A') {
|
|
this._state_cache[this.data.country_code] = value;
|
|
}
|
|
return super.val(value);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/inputs/country_select_input.js (babel) === */
|
|
"use strict";
|
|
|
|
class Country_Select_Input extends Ajax_Select_Input {
|
|
async on_load() {
|
|
// Load countries via Ajax endpoint if data not provided
|
|
if (!this.args.data) {
|
|
this.data.select_values = await Rsx_Reference_Data_Controller.countries();
|
|
} else {
|
|
// Use parent on_load for custom data endpoints
|
|
await super.on_load();
|
|
}
|
|
|
|
// Reorder select_values to put default country first in the list
|
|
if (this.args.default_country && this.data.select_values && is_array(this.data.select_values)) {
|
|
const default_country_code = this.args.default_country;
|
|
|
|
// Find the default country in the array
|
|
const default_country_index = this.data.select_values.findIndex(opt => (typeof opt === 'object' ? opt.value : opt) === default_country_code);
|
|
if (default_country_index !== -1) {
|
|
// Remove it from its current position
|
|
const [default_country] = this.data.select_values.splice(default_country_index, 1);
|
|
|
|
// Add it to the beginning
|
|
this.data.select_values.unshift(default_country);
|
|
}
|
|
}
|
|
}
|
|
on_create() {
|
|
// Set default placeholder if not provided
|
|
if (!this.args.placeholder) {
|
|
this.args.placeholder = 'Select Country...';
|
|
}
|
|
|
|
// Call parent to initialize Ajax_Select_Input
|
|
super.on_create();
|
|
|
|
// Handle default country value
|
|
if (this.args.default_country && !this.data.value) {
|
|
this.data.value = this.args.default_country;
|
|
}
|
|
}
|
|
on_ready() {
|
|
// Call parent to initialize Tom Select
|
|
super.on_ready();
|
|
|
|
// Update state selector with initial/default country
|
|
this._update_state_selector();
|
|
|
|
// Listen for country changes and update state selector
|
|
if (this.tom_select) {
|
|
this.tom_select.on('change', () => {
|
|
this._update_state_selector();
|
|
});
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Find State_Select_Input sibling and update its country code
|
|
* @private
|
|
*/
|
|
_update_state_selector() {
|
|
const current_country = this.val();
|
|
|
|
// Find State_Select_Input component using closest_sibling
|
|
const state_component = this.$.closest_sibling('.State_Select_Input').component();
|
|
if (state_component && typeof state_component.set_country_code === 'function') {
|
|
state_component.set_country_code(current_country);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/inputs/profile_photo_input.js (babel) === */
|
|
"use strict";
|
|
|
|
/**
|
|
* Profile_Photo_Input
|
|
*
|
|
* Profile photo upload widget with thumbnail display and upload handling.
|
|
* See profile_photo_input.jqhtml for full documentation.
|
|
*
|
|
* JavaScript Responsibilities:
|
|
* - Handle file selection and upload
|
|
* - Update thumbnail on successful upload
|
|
* - Manage loading state with spinner
|
|
* - Provide val() getter/setter for attachment key
|
|
* - Handle remove button functionality
|
|
*/
|
|
class Profile_Photo_Input extends Form_Input_Abstract {
|
|
on_create() {
|
|
// Initialize data
|
|
this.data.attachment_key = '';
|
|
this.data.thumbnail_url = '';
|
|
}
|
|
on_render() {
|
|
// Handle upload button click - trigger hidden file input
|
|
this.$sid('upload_btn').on('click', () => {
|
|
this.$sid('file_input').click();
|
|
});
|
|
|
|
// Handle file selection
|
|
this.$sid('file_input').on('change', () => {
|
|
const file = this.$sid('file_input')[0].files[0];
|
|
if (!file) return;
|
|
this.upload_photo(file);
|
|
});
|
|
|
|
// Handle remove button
|
|
if (this.args.show_remove) {
|
|
this.$sid('remove_btn').on('click', () => {
|
|
this.remove_photo();
|
|
});
|
|
}
|
|
}
|
|
|
|
/**
|
|
* val() - Get or set the attachment key
|
|
* @param {string} [key] - If provided, sets the attachment key and updates thumbnail
|
|
* @returns {string} The current attachment key when called as getter
|
|
*/
|
|
val(key) {
|
|
if (arguments.length === 0) {
|
|
// Getter - return attachment key
|
|
return this.data.attachment_key || '';
|
|
} else {
|
|
// Setter - set attachment key and update thumbnail
|
|
this.data.attachment_key = key || '';
|
|
if (this.data.attachment_key) {
|
|
// Generate thumbnail URL from attachment key
|
|
const width = this.args.width || 96;
|
|
const height = this.args.height || 96;
|
|
this.data.thumbnail_url = `/_thumbnail/${this.data.attachment_key}/cover/${width}/${height}`;
|
|
} else {
|
|
// No key - clear thumbnail
|
|
this.data.thumbnail_url = '';
|
|
}
|
|
console.log('Rerender');
|
|
// Re-render to switch between icon and image
|
|
this.render();
|
|
}
|
|
}
|
|
upload_photo(file) {
|
|
// Validate file size
|
|
const max_size = (this.args.max_size || 2) * 1024 * 1024; // Convert MB to bytes
|
|
if (file.size > max_size) {
|
|
alert(`File size must be less than ${this.args.max_size || 2}MB`);
|
|
this.$sid('file_input').val(''); // Clear selection
|
|
return;
|
|
}
|
|
|
|
// Show spinner, dim image
|
|
this.$sid('spinner').removeClass('d-none');
|
|
this.$sid('photo').css('opacity', '0.3');
|
|
|
|
// Create FormData for file upload
|
|
const form_data = new FormData();
|
|
form_data.append('file', file);
|
|
form_data.append('site_id', '1'); // TODO: Get from session/config
|
|
// Do NOT set fileable_type/fileable_category - file uploads unattached
|
|
// The parent form will assign it via attach_to() on save
|
|
|
|
// Upload file via AJAX
|
|
$.ajax({
|
|
url: '/_upload',
|
|
type: 'POST',
|
|
data: form_data,
|
|
processData: false,
|
|
contentType: false,
|
|
success: response => {
|
|
console.log('Profile photo upload successful:', response);
|
|
|
|
// Update attachment key (this will also update thumbnail)
|
|
this.val(response.attachment.key);
|
|
|
|
// Hide spinner, restore opacity
|
|
this.$sid('spinner').addClass('d-none');
|
|
this.$sid('photo').css('opacity', '1');
|
|
|
|
// Clear file input for future uploads
|
|
this.$sid('file_input').val('');
|
|
|
|
// Trigger change event for form tracking
|
|
this.$.trigger('change');
|
|
},
|
|
error: (xhr, status, error) => {
|
|
var _xhr$responseJSON;
|
|
console.error('Profile photo upload failed:', error);
|
|
console.error('Response:', xhr.responseJSON);
|
|
|
|
// Hide spinner, restore opacity
|
|
this.$sid('spinner').addClass('d-none');
|
|
this.$sid('photo').css('opacity', '1');
|
|
|
|
// Clear file input
|
|
this.$sid('file_input').val('');
|
|
|
|
// Show error to user
|
|
alert('Upload failed: ' + (((_xhr$responseJSON = xhr.responseJSON) === null || _xhr$responseJSON === void 0 ? void 0 : _xhr$responseJSON.error) || error));
|
|
}
|
|
});
|
|
}
|
|
update_photo() {
|
|
// <% if (this.args.show_remove && this.data.attachment_key) { %>
|
|
}
|
|
remove_photo() {
|
|
// Clear attachment key (sets to placeholder)
|
|
this.val('');
|
|
|
|
// Trigger change event for form tracking
|
|
this.$.trigger('change');
|
|
}
|
|
async seed() {
|
|
// For testing - set a placeholder key
|
|
// In production, this would use actual test data
|
|
this.val('');
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/forms/rsx_tabs.js (babel) === */
|
|
"use strict";
|
|
|
|
/**
|
|
* Rsx_Tabs
|
|
*
|
|
* Tab container component with form-aware error handling integration.
|
|
* See rsx_tabs.jqhtml for full documentation.
|
|
*
|
|
* JavaScript Responsibilities:
|
|
* - Builds tab navigation dynamically from registered Rsx_Tab children
|
|
* - Manages tab activation and switching behavior
|
|
* - Persists active tab to URL hash for bookmarking
|
|
* - Integrates with form validation to show error badges on tabs
|
|
* - Auto-switches to first tab with errors on validation failure
|
|
* - Provides API for parent forms to report validation errors
|
|
*/
|
|
class Rsx_Tabs extends Component {
|
|
on_create() {
|
|
this.tabs = []; // Registered Rsx_Tab components
|
|
this.active_tab_id = null;
|
|
this.form = null;
|
|
}
|
|
on_ready() {
|
|
// Find parent form if it exists
|
|
this.form = this.closest('.Rsx_Form');
|
|
|
|
// Build tab navigation from registered tabs
|
|
this._build_nav();
|
|
|
|
// Restore active tab from URL hash or activate first tab
|
|
const hash = window.location.hash;
|
|
if (hash) {
|
|
const tab_id = hash.substring(1);
|
|
this.activate_tab(tab_id);
|
|
} else if (this.tabs.length > 0) {
|
|
this.activate_tab(this.tabs[0].args.id);
|
|
}
|
|
|
|
// Persist active tab to URL hash
|
|
const that = this;
|
|
this.$sid('nav').on('click', 'a[data-bs-toggle="tab"]', function (e) {
|
|
const tab_id = $(e.currentTarget).data('tab-id');
|
|
window.location.hash = '#' + tab_id;
|
|
});
|
|
}
|
|
register_tab(tab_component) {
|
|
this.tabs.push(tab_component);
|
|
}
|
|
_build_nav() {
|
|
const $nav = this.$sid('nav');
|
|
$nav.empty();
|
|
for (let i = 0; i < this.tabs.length; i++) {
|
|
const tab = this.tabs[i];
|
|
const is_active = i === 0 ? 'active' : '';
|
|
const $li = $(`
|
|
<li class="nav-item" role="presentation">
|
|
<a class="nav-link ${is_active}"
|
|
data-bs-toggle="tab"
|
|
href="#${tab.args.id}"
|
|
data-tab-id="${tab.args.id}"
|
|
aria-selected="${i === 0 ? 'true' : 'false'}"
|
|
role="tab">
|
|
${tab.args.icon ? `<i class="${tab.args.icon}"></i> ` : ''}
|
|
${tab.args.label}
|
|
<span class="badge bg-danger ms-2" style="display: none;" data-error-badge="${tab.args.id}">0</span>
|
|
</a>
|
|
</li>
|
|
`);
|
|
$nav.append($li);
|
|
}
|
|
}
|
|
activate_tab(tab_id) {
|
|
// Find the tab
|
|
const tab = this.tabs.find(t => t.args.id === tab_id);
|
|
if (!tab) return;
|
|
|
|
// Remove active show from all tab panes
|
|
for (let t of this.tabs) {
|
|
t.$.removeClass('active show');
|
|
}
|
|
|
|
// Add active show to the selected tab pane
|
|
tab.$.addClass('active show');
|
|
|
|
// Update Bootstrap tab navigation
|
|
this.$sid('nav').find('a[data-bs-toggle="tab"]').removeClass('active').attr('aria-selected', 'false');
|
|
this.$sid('nav').find('a[data-tab-id="' + tab_id + '"]').addClass('active').attr('aria-selected', 'true');
|
|
this.active_tab_id = tab_id;
|
|
}
|
|
handle_validation_errors(errors) {
|
|
// Count errors per tab
|
|
const tab_errors = {};
|
|
for (let tab of this.tabs) {
|
|
const error_count = tab.count_errors(errors);
|
|
tab_errors[tab.args.id] = error_count;
|
|
|
|
// Update badge
|
|
const $badge = this.$sid('nav').find(`[data-error-badge="${tab.args.id}"]`);
|
|
if (error_count > 0) {
|
|
$badge.text(error_count).show();
|
|
} else {
|
|
$badge.hide();
|
|
}
|
|
}
|
|
|
|
// Find first tab with errors
|
|
const first_errored_tab = this.tabs.find(t => tab_errors[t.args.id] > 0);
|
|
|
|
// Switch to first errored tab if not currently on an errored tab
|
|
if (first_errored_tab && tab_errors[this.active_tab_id] === 0) {
|
|
this.activate_tab(first_errored_tab.args.id);
|
|
}
|
|
}
|
|
clear_error_badges() {
|
|
this.$sid('nav').find('[data-error-badge]').hide();
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/forms/rsx_tab.js (babel) === */
|
|
"use strict";
|
|
|
|
/**
|
|
* Rsx_Tab
|
|
*
|
|
* Individual tab pane component that works with Rsx_Tabs for form validation.
|
|
* See rsx_tab.jqhtml for full documentation.
|
|
*
|
|
* JavaScript Responsibilities:
|
|
* - Auto-registers with parent Rsx_Tabs component on creation
|
|
* - Sets tab pane ID attribute from $id argument
|
|
* - Discovers and tracks child Form_Field components
|
|
* - Counts validation errors within this tab's fields
|
|
* - Provides error count to parent for badge display
|
|
*/
|
|
class Rsx_Tab extends Component {
|
|
on_create() {
|
|
let that = this;
|
|
|
|
// Set the tab ID dynamically from args
|
|
if (that.args.id) {
|
|
that.$.attr('id', that.args.id);
|
|
}
|
|
|
|
// Find parent Rsx_Tabs and register
|
|
that.tabs_container = that.closest('.Rsx_Tabs');
|
|
if (that.tabs_container) {
|
|
that.tabs_container.register_tab(that);
|
|
}
|
|
|
|
// Store reference to all Form_Field components within this tab
|
|
that.fields = [];
|
|
}
|
|
on_ready() {
|
|
let that = this;
|
|
|
|
// Find all Form_Field components within this tab
|
|
that.$.find('.Form_Field').each((index, element) => {
|
|
const field_component = $(element).component();
|
|
if (field_component) {
|
|
that.fields.push(field_component);
|
|
}
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Count validation errors in Form_Field components within this tab
|
|
* @param {Object} errors - Error object from form validation {field_name: error_message}
|
|
* @returns {number} Count of errors in this tab
|
|
*/
|
|
count_errors(errors) {
|
|
let that = this;
|
|
let count = 0;
|
|
for (let field of that.fields) {
|
|
if (errors[field.args.name]) {
|
|
count++;
|
|
}
|
|
}
|
|
return count;
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/forms/rsx_form.js (babel) === */
|
|
"use strict";
|
|
|
|
/**
|
|
* Rsx_Form
|
|
*
|
|
* Form container with validation, submission, and widget value management.
|
|
* See rsx_form.jqhtml for full documentation.
|
|
*
|
|
* JavaScript Responsibilities:
|
|
* - Parses and stores initial form data from $data attribute (JSON or object)
|
|
* - Discovers and manages child Widget components via vals() getter/setter
|
|
* - Handles form submission via Ajax to controller/method endpoints
|
|
* - Applies validation errors to fields using Form_Utils
|
|
* - Integrates with Rsx_Tabs for tab-aware error handling
|
|
* - Provides seed() functionality for debug/testing
|
|
* - Manages form state (values, errors) throughout lifecycle
|
|
*/
|
|
class Rsx_Form extends Component {
|
|
on_create() {
|
|
this.data.values = {}; // Current form values {name: value}
|
|
this.data.errors = {}; // Validation errors {name: error_message}
|
|
this.tabs = null; // Reference to Rsx_Tabs component if present
|
|
|
|
// Parse initial data from $data attribute (e.g., from $data=$client)
|
|
let data = this.args.data;
|
|
if (typeof data === 'string') {
|
|
try {
|
|
// Decode HTML entities before parsing JSON
|
|
// This handles cases where JSON is passed through Blade {!! !!} syntax
|
|
const decoded = $('<textarea>').html(data).text();
|
|
data = json_decode(decoded);
|
|
} catch (e) {
|
|
console.error('Form: Failed to parse data JSON string', e);
|
|
data = {};
|
|
}
|
|
}
|
|
if (data && typeof data === 'object') {
|
|
this.data.values = data;
|
|
}
|
|
}
|
|
on_ready() {
|
|
const that = this;
|
|
|
|
// Validate that error container exists
|
|
if (!this.$sid('error').exists()) {
|
|
console.log(this.$.html());
|
|
throw new Error('Rsx_Form requires an error container with $id="error". ' + 'Add <div $id="error"></div> to your form template for displaying validation and error messages.');
|
|
}
|
|
|
|
// Set up seed button handler if in debug mode
|
|
if (window.rsxapp.debug && this.$sid('seed_btn').exists()) {
|
|
that.$sid('seed_btn').on('click', function () {
|
|
that.seed();
|
|
});
|
|
}
|
|
|
|
// Find child Rsx_Tabs component if present for error handling integration
|
|
const tabs_el = this.$.find('.Rsx_Tabs').first();
|
|
if (tabs_el.length) {
|
|
that.tabs = tabs_el.component();
|
|
}
|
|
|
|
// Automatically wire all submit buttons to call form submit()
|
|
this.$.find('button[type="submit"]').each(function () {
|
|
$(this).on('click', function (e) {
|
|
e.preventDefault();
|
|
that.submit();
|
|
});
|
|
});
|
|
|
|
// Notify all fields to load their initial values
|
|
// This happens in on_ready to ensure all Form_Field children are initialized
|
|
this.vals(this.data.values);
|
|
|
|
// Hide loading spinner and show form content (without re-rendering)
|
|
this.$sid('loader').hide();
|
|
this.$sid('form_content').show();
|
|
}
|
|
|
|
// Getter or setter for all form values, similar to jquery val
|
|
vals(values) {
|
|
if (values) {
|
|
// Setter
|
|
|
|
this.$.shallowFind('.Widget').each(function () {
|
|
let $widget = $(this);
|
|
let component = $widget.component();
|
|
if (component && 'val' in component) {
|
|
let widget_name = $widget.data('name');
|
|
if (widget_name in values) {
|
|
component.val(values[widget_name]);
|
|
}
|
|
}
|
|
});
|
|
return null;
|
|
} else {
|
|
// Getter
|
|
let data = {};
|
|
|
|
// Get widget values
|
|
this.$.shallowFind('.Widget').each(function () {
|
|
let $widget = $(this);
|
|
let component = $widget.component();
|
|
if (component && 'val' in component) {
|
|
let widget_name = $widget.data('name');
|
|
data[widget_name] = component.val();
|
|
}
|
|
});
|
|
|
|
// Also get regular hidden inputs (non-widget inputs)
|
|
this.$.find('input[type="hidden"][name]').each(function () {
|
|
let $input = $(this);
|
|
let name = $input.attr('name');
|
|
if (name) {
|
|
data[name] = $input.val();
|
|
}
|
|
});
|
|
return data;
|
|
}
|
|
}
|
|
get_error(name) {
|
|
return this.data.errors[name];
|
|
}
|
|
|
|
/**
|
|
* Render an error in the form's error container
|
|
*
|
|
* Handles both field-specific validation errors and generic errors.
|
|
* Can be called by external handlers (e.g., modal on_submit) or internally
|
|
* by the form's own submit() method.
|
|
*
|
|
* @param {Error|Object} error - Error object from Ajax call
|
|
*/
|
|
async render_error(error) {
|
|
// Handle validation errors - apply to fields
|
|
if (error.type === 'form_error' && error.details) {
|
|
await Form_Utils.apply_form_errors(this.$, error.details);
|
|
|
|
// Notify tabs of validation errors for error badges and auto-switching
|
|
if (this.tabs) {
|
|
this.tabs.handle_validation_errors(error.details);
|
|
}
|
|
|
|
// Form_Utils handles all rendering (inline errors + unmatched errors alert)
|
|
// Don't call Rsx.render_error() to avoid duplicate alerts
|
|
return;
|
|
}
|
|
|
|
// For non-form errors (fatal, auth, network, etc.), render in form's error container
|
|
Rsx.render_error(error, this.$sid('error'));
|
|
}
|
|
async submit() {
|
|
// Clear any previous errors
|
|
Form_Utils.reset_form_errors(this.$);
|
|
this.$sid('error').empty();
|
|
|
|
// Clear tab error badges if tabs are present
|
|
if (this.tabs) {
|
|
this.tabs.clear_error_badges();
|
|
}
|
|
|
|
// Serialize all field values
|
|
let values = this.vals();
|
|
|
|
// Call submit handler
|
|
if (!this.args.controller || !this.args.method) {
|
|
console.error('Form: No controller/method provided');
|
|
throw new Error('Form configuration error: Missing controller or method');
|
|
}
|
|
try {
|
|
// Build Ajax URL from controller and method
|
|
const ajax_url = `/_ajax/${this.args.controller}/${this.args.method}`;
|
|
|
|
// Call Ajax endpoint - response is directly what PHP returned
|
|
const result = await Ajax.call(ajax_url, values);
|
|
|
|
// Success! Handle result
|
|
if (result && result.redirect) {
|
|
// Redirect to URL
|
|
window.location.href = result.redirect;
|
|
} else {
|
|
// Success without redirect
|
|
console.log('Form submitted successfully', result);
|
|
}
|
|
} catch (error) {
|
|
// Render error (handles both validation and generic errors)
|
|
await this.render_error(error);
|
|
}
|
|
}
|
|
async seed() {
|
|
const promises = [];
|
|
this.$.shallowFind('.Form_Field').each(function () {
|
|
let component = $(this).component();
|
|
if (component && 'seed' in component) {
|
|
promises.push(component.seed());
|
|
}
|
|
});
|
|
await Promise.all(promises);
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/forms/pin_verification_form.js (babel) === */
|
|
"use strict";
|
|
|
|
/**
|
|
* Pin_Verification_Form
|
|
*
|
|
* Specialized 6-digit PIN entry form with auto-navigation between inputs.
|
|
* See pin_verification_form.jqhtml for full documentation.
|
|
*
|
|
* JavaScript Responsibilities:
|
|
* - Auto-advances to next input when digit is entered
|
|
* - Smart backspace: clears current box and moves to previous
|
|
* - Paste support: distributes pasted digits across all 6 inputs
|
|
* - Arrow key navigation between inputs
|
|
* - Numeric-only input validation
|
|
* - Select-all on focus for easy digit replacement
|
|
* - Validates all 6 digits entered before allowing submission
|
|
* - Provides val() getter/setter for programmatic PIN access
|
|
*/
|
|
class Pin_Verification_Form extends Rsx_Form {
|
|
on_create() {
|
|
super.on_create();
|
|
this.pin_length = 6;
|
|
}
|
|
|
|
/**
|
|
* Get or set the PIN value
|
|
* @param {string} [value] - If provided, sets the PIN (distributes across inputs)
|
|
* @returns {string} Current PIN value when called as getter
|
|
*/
|
|
val(value) {
|
|
if (arguments.length === 0) {
|
|
// Getter - collect all digits
|
|
let pin = '';
|
|
for (let i = 0; i < this.pin_length; i++) {
|
|
pin += this.$sid(`digit_${i}`).val() || '';
|
|
}
|
|
return pin;
|
|
} else {
|
|
// Setter - distribute digits across inputs
|
|
const digits = str(value || '').replace(/[^0-9]/g, '');
|
|
for (let i = 0; i < this.pin_length; i++) {
|
|
this.$sid(`digit_${i}`).val(digits[i] || '');
|
|
}
|
|
// Focus first empty input or last input
|
|
const first_empty = this._find_first_empty_index();
|
|
if (first_empty !== -1) {
|
|
this.$sid(`digit_${first_empty}`)[0].focus();
|
|
} else {
|
|
this.$sid(`digit_${this.pin_length - 1}`)[0].focus();
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Find the first empty input index
|
|
* @returns {number} Index of first empty input, or -1 if all filled
|
|
*/
|
|
_find_first_empty_index() {
|
|
for (let i = 0; i < this.pin_length; i++) {
|
|
if (!this.$sid(`digit_${i}`).val()) {
|
|
return i;
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
/**
|
|
* Move focus to specific input index
|
|
* @param {number} index
|
|
*/
|
|
_focus_input(index) {
|
|
if (index >= 0 && index < this.pin_length) {
|
|
const $input = this.$sid(`digit_${index}`);
|
|
if ($input.exists()) {
|
|
$input[0].focus();
|
|
// Select the content if there is any
|
|
$input[0].select();
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Handle paste event - distribute digits across inputs
|
|
* @param {ClipboardEvent} e
|
|
* @param {number} start_index
|
|
*/
|
|
_handle_paste(e, start_index) {
|
|
e.preventDefault();
|
|
|
|
// Get pasted data
|
|
const paste = (e.originalEvent || e).clipboardData.getData('text');
|
|
const digits = paste.replace(/[^0-9]/g, '');
|
|
if (!digits) {
|
|
return;
|
|
}
|
|
|
|
// Distribute digits starting from current input
|
|
for (let i = 0; i < digits.length && start_index + i < this.pin_length; i++) {
|
|
this.$sid(`digit_${start_index + i}`).val(digits[i]);
|
|
}
|
|
|
|
// Focus next empty input or last input
|
|
const next_index = Math.min(start_index + digits.length, this.pin_length - 1);
|
|
this._focus_input(next_index);
|
|
}
|
|
on_ready() {
|
|
super.on_ready();
|
|
const that = this;
|
|
|
|
// Set up event handlers for each input
|
|
for (let i = 0; i < this.pin_length; i++) {
|
|
const $input = this.$sid(`digit_${i}`);
|
|
const index = i;
|
|
|
|
// Handle input event - auto-advance
|
|
$input.on('input', function (e) {
|
|
const value = $(this).val();
|
|
|
|
// Only allow numeric input
|
|
const numeric = value.replace(/[^0-9]/g, '');
|
|
if (numeric !== value) {
|
|
$(this).val(numeric);
|
|
}
|
|
|
|
// If multiple digits were entered (paste), distribute them
|
|
if (numeric.length > 1) {
|
|
that._handle_paste({
|
|
preventDefault: () => {},
|
|
originalEvent: {
|
|
clipboardData: {
|
|
getData: () => numeric
|
|
}
|
|
}
|
|
}, index);
|
|
return;
|
|
}
|
|
|
|
// Auto-advance to next input if digit was entered
|
|
if (numeric.length === 1 && index < that.pin_length - 1) {
|
|
that._focus_input(index + 1);
|
|
}
|
|
});
|
|
|
|
// Handle keydown for backspace
|
|
$input.on('keydown', function (e) {
|
|
// Backspace key
|
|
if (e.key === 'Backspace') {
|
|
const current_value = $(this).val();
|
|
|
|
// If current input is empty, move to previous and clear it
|
|
if (!current_value && index > 0) {
|
|
e.preventDefault();
|
|
that.$sid(`digit_${index - 1}`).val('');
|
|
that._focus_input(index - 1);
|
|
}
|
|
// If current input has value, it will be cleared by default behavior
|
|
// and we stay on current input
|
|
}
|
|
|
|
// Arrow left
|
|
if (e.key === 'ArrowLeft' && index > 0) {
|
|
e.preventDefault();
|
|
that._focus_input(index - 1);
|
|
}
|
|
|
|
// Arrow right
|
|
if (e.key === 'ArrowRight' && index < that.pin_length - 1) {
|
|
e.preventDefault();
|
|
that._focus_input(index + 1);
|
|
}
|
|
});
|
|
|
|
// Handle paste event
|
|
$input.on('paste', function (e) {
|
|
that._handle_paste(e, index);
|
|
});
|
|
|
|
// Select all on focus for easy replacement
|
|
$input.on('focus', function () {
|
|
$(this)[0].select();
|
|
});
|
|
}
|
|
|
|
// Focus first input on load
|
|
this._focus_input(0);
|
|
}
|
|
|
|
/**
|
|
* Override submit to validate PIN is complete
|
|
*/
|
|
async submit() {
|
|
const pin = this.val();
|
|
|
|
// Clear previous errors
|
|
this.$sid('error_container').hide().empty();
|
|
|
|
// Validate PIN is 6 digits
|
|
if (pin.length !== this.pin_length) {
|
|
this.$sid('error_container').text('Please enter all 6 digits').show();
|
|
|
|
// Mark inputs as invalid
|
|
for (let i = 0; i < this.pin_length; i++) {
|
|
if (!this.$sid(`digit_${i}`).val()) {
|
|
this.$sid(`digit_${i}`).addClass('is-invalid');
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
|
|
// Remove invalid class from all inputs
|
|
for (let i = 0; i < this.pin_length; i++) {
|
|
this.$sid(`digit_${i}`).removeClass('is-invalid');
|
|
}
|
|
|
|
// Call parent submit (which will use controller/method if provided)
|
|
await super.submit();
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/forms/form_field_abstract.js (babel) === */
|
|
"use strict";
|
|
|
|
/**
|
|
* Form_Field_Abstract
|
|
*
|
|
* Abstract base class for form field wrappers. Provides core functionality without visual formatting.
|
|
* See form_field_abstract.jqhtml for full documentation.
|
|
*
|
|
* JavaScript Responsibilities:
|
|
* - Discovers and configures child Widget component
|
|
* - Sets data-name attribute on widget for form value collection
|
|
* - Sets name attribute on native inputs for Form_Utils compatibility
|
|
* - Wires label 'for' attribute to input element ID for accessibility (if label exists)
|
|
* - Provides seed() support for debug/testing data
|
|
* - Bridges between form validation state and child widget
|
|
*/
|
|
class Form_Field_Abstract extends Component {
|
|
on_create() {
|
|
// Find parent form for error display
|
|
this.form = this.closest('.Rsx_Form');
|
|
if (!this.form) {
|
|
shouldnt_happen('Form_Field_Abstract must be inside a Rsx_Form component');
|
|
}
|
|
}
|
|
on_ready() {
|
|
// Find child widget and set its data-name attribute
|
|
let $widget = this.$.find('.Widget').first();
|
|
if (!$widget.exists()) {
|
|
shouldnt_happen(`Form_Field_Abstract "${this.args.name}" has no .Widget child. Every Form_Field must contain exactly one widget (Text_Input, Wysiwyg_Input, etc.)`);
|
|
}
|
|
|
|
// Set data-name on the widget so Rsx_Form can collect values
|
|
$widget.attr('data-name', this.args.name);
|
|
let $input = this.$.find('input, select, textarea').first();
|
|
if ($input.exists()) {
|
|
// Also set name attribute on native inputs for Form_Utils compatibility
|
|
// Todo: clever way to deal with this for non standard input elements
|
|
$input.attr('name', this.args.name);
|
|
|
|
// Set the for field to the element if label exists (for child classes)
|
|
// Todo: clever way to deal with this for non standard input elements
|
|
let $label = this.$sid('form_label');
|
|
if ($label.exists()) {
|
|
$label.attr('for', $input.attr('id'));
|
|
}
|
|
}
|
|
}
|
|
get_error() {
|
|
return this.form.get_error(this.args.name);
|
|
}
|
|
has_error() {
|
|
return !!this.get_error();
|
|
}
|
|
async seed() {
|
|
if (!this.args.seeder) {
|
|
return;
|
|
}
|
|
|
|
// Find child widget
|
|
let $widget = this.$.find('.Widget').first();
|
|
if (!$widget.exists()) {
|
|
return;
|
|
}
|
|
let widget_component = $widget.component();
|
|
if (!widget_component || !widget_component.val) {
|
|
return;
|
|
}
|
|
|
|
// Call the seeder endpoint (Ajax route reference like form $action)
|
|
try {
|
|
let value = await Ajax.call(this.args.seeder, {});
|
|
widget_component.val(value);
|
|
} catch (error) {
|
|
console.error(`Seeder error for ${this.args.name}:`, error);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/forms/form_field.js (babel) === */
|
|
"use strict";
|
|
|
|
/**
|
|
* Form_Field
|
|
*
|
|
* Form field wrapper that adds labels, help text, and required indicators.
|
|
* See form_field.jqhtml for full documentation.
|
|
*
|
|
* Extends Form_Field_Abstract to inherit all core functionality.
|
|
* This class exists primarily for template inheritance and any future
|
|
* formatted-field-specific behavior.
|
|
*/
|
|
class Form_Field extends Form_Field_Abstract {
|
|
// All functionality inherited from Form_Field_Abstract
|
|
// This class provides the formatted visual wrapper via its template
|
|
}
|
|
|
|
|
|
/* === rsx/theme/components/forms/form_hidden_field.js (babel) === */
|
|
"use strict";
|
|
|
|
/**
|
|
* Form_Hidden_Field - Hidden input field component
|
|
*
|
|
* Extends Form_Field_Abstract but IS the input element itself (using tag="input" type="hidden").
|
|
* See form_hidden_field.jqhtml for full documentation.
|
|
*
|
|
* JavaScript Responsibilities:
|
|
* - Sets value attribute dynamically in on_create()
|
|
* - Overrides on_ready() to handle that this.$ IS both the widget and the input
|
|
* - Provides val() method for getting/setting the hidden value
|
|
*/
|
|
class Form_Hidden_Field extends Form_Field_Abstract {
|
|
on_create() {
|
|
// Call parent to set up form reference
|
|
super.on_create();
|
|
|
|
// Set initial value attribute (can't be done in Define tag)
|
|
this.$.attr('value', '');
|
|
}
|
|
on_ready() {
|
|
// Override parent on_ready() because this.$ IS the widget and the input
|
|
// Set data-name on this.$ (which is the input element)
|
|
this.$.attr('data-name', this.args.name);
|
|
|
|
// Set name attribute on this.$ for Form_Utils compatibility
|
|
this.$.attr('name', this.args.name);
|
|
}
|
|
|
|
/**
|
|
* val() - Get or set the hidden input value
|
|
* @param {string} [value] - If provided, sets the value
|
|
* @returns {string} The current value when called as getter
|
|
*/
|
|
val(value) {
|
|
if (arguments.length === 0) {
|
|
// Getter - this.$ is the input element itself
|
|
return this.$.val();
|
|
} else {
|
|
// Setter - update the input value directly (this.$ is the input)
|
|
this.$.val(value || '');
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/app/frontend/dashboard/frontend_dashboard.js (babel) === */
|
|
"use strict";
|
|
|
|
class Frontend_Dashboard {
|
|
static init() {
|
|
if (!$(".Frontend_Dashboard").exists()) return;
|
|
|
|
// Initialize your component here
|
|
console.log('Frontend_Dashboard initialized');
|
|
|
|
// Example: Handle button clicks
|
|
$('.btn-action').on('click', function () {
|
|
// Handle action
|
|
});
|
|
|
|
// Example: Initialize tooltips
|
|
$('[data-bs-toggle="tooltip"]').tooltip();
|
|
}
|
|
static on_app_ready() {
|
|
Frontend_Dashboard.init();
|
|
}
|
|
|
|
// static on_jqhtml_ready() {
|
|
// // Called after all JQHTML components have loaded and rendered
|
|
// // Use this if you need to interact with JQHTML components
|
|
// // Otherwise, use on_app_ready() for most initialization
|
|
// }
|
|
}
|
|
|
|
|
|
/* === rsx/app/frontend/clients/index/clients_datagrid.js (babel) === */
|
|
"use strict";
|
|
|
|
/**
|
|
* Clients_DataGrid Component
|
|
*
|
|
* Concrete implementation for clients datagrid.
|
|
* All functionality is in DataGrid_Abstract.
|
|
*/
|
|
class Clients_DataGrid extends DataGrid_Abstract {
|
|
// All behavior inherited from DataGrid_Abstract
|
|
}
|
|
|
|
|
|
/* === rsx/app/frontend/clients/edit/frontend_clients_edit.js (babel) === */
|
|
"use strict";
|
|
|
|
class Frontend_Clients_Edit {
|
|
static init() {
|
|
if (!$('.Frontend_Clients_Edit').exists()) return;
|
|
|
|
// Handle dynamic tag addition
|
|
$('#add-tag').on('click', function () {
|
|
const tag_html = `
|
|
<div class="input-group mb-2">
|
|
<input type="text" class="form-control" name="tags[]" placeholder="e.g., VIP, Enterprise, Strategic Partner">
|
|
<button class="btn btn-danger remove-tag" type="button">
|
|
<i class="bi bi-trash"></i>
|
|
</button>
|
|
</div>
|
|
`;
|
|
$('#tags-container').append(tag_html);
|
|
});
|
|
|
|
// Handle tag removal
|
|
$(document).on('click', '.remove-tag', function (e) {
|
|
const $button = $(e.currentTarget);
|
|
// Only remove if more than one tag field exists
|
|
if ($('#tags-container .input-group').length > 1) {
|
|
$button.closest('.input-group').remove();
|
|
} else {
|
|
// Clear the value of the last remaining field
|
|
$button.closest('.input-group').find('input').val('');
|
|
}
|
|
});
|
|
}
|
|
static on_app_ready() {
|
|
Frontend_Clients_Edit.init();
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/app/frontend/clients/view/frontend_clients_view.js (babel) === */
|
|
"use strict";
|
|
|
|
class Frontend_Clients_View {
|
|
static init() {
|
|
if (!$(".Frontend_Clients_View").exists()) return;
|
|
console_debug('CLIENT', 'Frontend_Clients_View initialized');
|
|
|
|
// Handle delete button
|
|
$('#delete-client-btn').on('click', async function () {
|
|
const $element = $(this);
|
|
const client_id = $element.data('client-id');
|
|
const confirmed = await Modal.confirm('Delete Client', 'Are you sure you want to delete this client?\n\nThis action can be undone by restoring the client.', 'Delete', 'Cancel');
|
|
if (confirmed) {
|
|
const result = await Frontend_Clients_Controller.delete({
|
|
id: client_id
|
|
});
|
|
if (result.success) {
|
|
// Reload the page to show deleted status
|
|
location.reload();
|
|
} else {
|
|
alert(result.message || 'Failed to delete client');
|
|
}
|
|
}
|
|
});
|
|
|
|
// Handle restore button
|
|
$('#restore-client-btn').on('click', async function () {
|
|
const $element = $(this);
|
|
const client_id = $element.data('client-id');
|
|
const confirmed = await Modal.confirm('Restore Client', 'Are you sure you want to restore this client?', 'Restore', 'Cancel');
|
|
if (confirmed) {
|
|
const result = await Frontend_Clients_Controller.restore({
|
|
id: client_id
|
|
});
|
|
if (result.success) {
|
|
// Reload the page to show restored status
|
|
location.reload();
|
|
} else {
|
|
alert(result.message || 'Failed to restore client');
|
|
}
|
|
}
|
|
});
|
|
}
|
|
static on_app_ready() {
|
|
Frontend_Clients_View.init();
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/app/frontend/clients/frontend_clients.js (babel) === */
|
|
"use strict";
|
|
|
|
class Frontend_Clients {
|
|
static init() {
|
|
if (!$('.Frontend_Clients').exists()) return;
|
|
|
|
// Initialize your component here
|
|
console.log('Frontend_Clients initialized');
|
|
}
|
|
static on_app_ready() {
|
|
Frontend_Clients.init();
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/app/frontend/settings/team/frontend_settings_team.js (babel) === */
|
|
"use strict";
|
|
|
|
class Frontend_Settings_Team {
|
|
static init() {
|
|
if (!$(".Frontend_Settings_Team").exists()) return;
|
|
|
|
// Initialize your component here
|
|
console.log('Frontend_Settings_Team initialized');
|
|
|
|
// Example: Handle button clicks
|
|
$('.btn-action').on('click', function () {
|
|
// Handle action
|
|
});
|
|
|
|
// Example: Initialize tooltips
|
|
$('[data-bs-toggle="tooltip"]').tooltip();
|
|
}
|
|
static on_app_ready() {
|
|
Frontend_Settings_Team.init();
|
|
}
|
|
|
|
// static on_jqhtml_ready() {
|
|
// // Called after all JQHTML components have loaded and rendered
|
|
// // Use this if you need to interact with JQHTML components
|
|
// // Otherwise, use on_app_ready() for most initialization
|
|
// }
|
|
}
|
|
|
|
|
|
/* === rsx/app/frontend/settings/notifications/frontend_settings_notifications.js (babel) === */
|
|
"use strict";
|
|
|
|
class Frontend_Settings_Notifications {
|
|
static init() {
|
|
if (!$(".Frontend_Settings_Notifications").exists()) return;
|
|
|
|
// Initialize your component here
|
|
console.log('Frontend_Settings_Notifications initialized');
|
|
|
|
// Example: Handle button clicks
|
|
$('.btn-action').on('click', function () {
|
|
// Handle action
|
|
});
|
|
|
|
// Example: Initialize tooltips
|
|
$('[data-bs-toggle="tooltip"]').tooltip();
|
|
}
|
|
static on_app_ready() {
|
|
Frontend_Settings_Notifications.init();
|
|
}
|
|
|
|
// static on_jqhtml_ready() {
|
|
// // Called after all JQHTML components have loaded and rendered
|
|
// // Use this if you need to interact with JQHTML components
|
|
// // Otherwise, use on_app_ready() for most initialization
|
|
// }
|
|
}
|
|
|
|
|
|
/* === rsx/app/frontend/settings/billing/frontend_settings_billing.js (babel) === */
|
|
"use strict";
|
|
|
|
class Frontend_Settings_Billing {
|
|
static init() {
|
|
if (!$(".Frontend_Settings_Billing").exists()) return;
|
|
|
|
// Initialize your component here
|
|
console.log('Frontend_Settings_Billing initialized');
|
|
|
|
// Example: Handle button clicks
|
|
$('.btn-action').on('click', function () {
|
|
// Handle action
|
|
});
|
|
|
|
// Example: Initialize tooltips
|
|
$('[data-bs-toggle="tooltip"]').tooltip();
|
|
}
|
|
static on_app_ready() {
|
|
Frontend_Settings_Billing.init();
|
|
}
|
|
|
|
// static on_jqhtml_ready() {
|
|
// // Called after all JQHTML components have loaded and rendered
|
|
// // Use this if you need to interact with JQHTML components
|
|
// // Otherwise, use on_app_ready() for most initialization
|
|
// }
|
|
}
|
|
|
|
|
|
/* === rsx/app/frontend/settings/import/frontend_settings_import.js (babel) === */
|
|
"use strict";
|
|
|
|
class Frontend_Settings_Import {
|
|
static init() {
|
|
if (!$(".Frontend_Settings_Import").exists()) return;
|
|
|
|
// Initialize your component here
|
|
console.log('Frontend_Settings_Import initialized');
|
|
|
|
// Example: Handle button clicks
|
|
$('.btn-action').on('click', function () {
|
|
// Handle action
|
|
});
|
|
|
|
// Example: Initialize tooltips
|
|
$('[data-bs-toggle="tooltip"]').tooltip();
|
|
}
|
|
static on_app_ready() {
|
|
Frontend_Settings_Import.init();
|
|
}
|
|
|
|
// static on_jqhtml_ready() {
|
|
// // Called after all JQHTML components have loaded and rendered
|
|
// // Use this if you need to interact with JQHTML components
|
|
// // Otherwise, use on_app_ready() for most initialization
|
|
// }
|
|
}
|
|
|
|
|
|
/* === rsx/app/frontend/settings/api/frontend_settings_api.js (babel) === */
|
|
"use strict";
|
|
|
|
class Frontend_Settings_Api {
|
|
static init() {
|
|
if (!$(".Frontend_Settings_Api").exists()) return;
|
|
|
|
// Initialize your component here
|
|
console.log('Frontend_Settings_Api initialized');
|
|
|
|
// Example: Handle button clicks
|
|
$('.btn-action').on('click', function () {
|
|
// Handle action
|
|
});
|
|
|
|
// Example: Initialize tooltips
|
|
$('[data-bs-toggle="tooltip"]').tooltip();
|
|
}
|
|
static on_app_ready() {
|
|
Frontend_Settings_Api.init();
|
|
}
|
|
|
|
// static on_jqhtml_ready() {
|
|
// // Called after all JQHTML components have loaded and rendered
|
|
// // Use this if you need to interact with JQHTML components
|
|
// // Otherwise, use on_app_ready() for most initialization
|
|
// }
|
|
}
|
|
|
|
|
|
/* === rsx/app/frontend/settings/templates/frontend_settings_templates.js (babel) === */
|
|
"use strict";
|
|
|
|
class Frontend_Settings_Templates {
|
|
static init() {
|
|
if (!$(".Frontend_Settings_Templates").exists()) return;
|
|
|
|
// Initialize your component here
|
|
console.log('Frontend_Settings_Templates initialized');
|
|
|
|
// Example: Handle button clicks
|
|
$('.btn-action').on('click', function () {
|
|
// Handle action
|
|
});
|
|
|
|
// Example: Initialize tooltips
|
|
$('[data-bs-toggle="tooltip"]').tooltip();
|
|
}
|
|
static on_app_ready() {
|
|
Frontend_Settings_Templates.init();
|
|
}
|
|
|
|
// static on_jqhtml_ready() {
|
|
// // Called after all JQHTML components have loaded and rendered
|
|
// // Use this if you need to interact with JQHTML components
|
|
// // Otherwise, use on_app_ready() for most initialization
|
|
// }
|
|
}
|
|
|
|
|
|
/* === rsx/app/frontend/settings/audit/frontend_settings_audit.js (babel) === */
|
|
"use strict";
|
|
|
|
class Frontend_Settings_Audit {
|
|
static init() {
|
|
if (!$(".Frontend_Settings_Audit").exists()) return;
|
|
|
|
// Initialize your component here
|
|
console.log('Frontend_Settings_Audit initialized');
|
|
|
|
// Example: Handle button clicks
|
|
$('.btn-action').on('click', function () {
|
|
// Handle action
|
|
});
|
|
|
|
// Example: Initialize tooltips
|
|
$('[data-bs-toggle="tooltip"]').tooltip();
|
|
}
|
|
static on_app_ready() {
|
|
Frontend_Settings_Audit.init();
|
|
}
|
|
|
|
// static on_jqhtml_ready() {
|
|
// // Called after all JQHTML components have loaded and rendered
|
|
// // Use this if you need to interact with JQHTML components
|
|
// // Otherwise, use on_app_ready() for most initialization
|
|
// }
|
|
}
|
|
|
|
|
|
/* === rsx/app/frontend/settings/profile_display/frontend_settings_profile_display.js (babel) === */
|
|
"use strict";
|
|
|
|
class Frontend_Settings_Profile_Display {
|
|
static init() {
|
|
if (!$(".Frontend_Settings_Profile_Display").exists()) return;
|
|
|
|
// Initialize your component here
|
|
console.log('Frontend_Settings_Profile_Display initialized');
|
|
|
|
// Example: Handle button clicks
|
|
$('.btn-action').on('click', function () {
|
|
// Handle action
|
|
});
|
|
|
|
// Example: Initialize tooltips
|
|
$('[data-bs-toggle="tooltip"]').tooltip();
|
|
}
|
|
static on_app_ready() {
|
|
Frontend_Settings_Profile_Display.init();
|
|
}
|
|
|
|
// static on_jqhtml_ready() {
|
|
// // Called after all JQHTML components have loaded and rendered
|
|
// // Use this if you need to interact with JQHTML components
|
|
// // Otherwise, use on_app_ready() for most initialization
|
|
// }
|
|
}
|
|
|
|
|
|
/* === rsx/app/frontend/settings/user_settings/frontend_settings_user_settings.js (babel) === */
|
|
"use strict";
|
|
|
|
class Frontend_Settings_User_Settings {
|
|
static init() {
|
|
if (!$(".Frontend_Settings_User_Settings").exists()) return;
|
|
|
|
// Initialize your component here
|
|
console.log('Frontend_Settings_User_Settings initialized');
|
|
|
|
// Example: Handle button clicks
|
|
$('.btn-action').on('click', function () {
|
|
// Handle action
|
|
});
|
|
|
|
// Example: Initialize tooltips
|
|
$('[data-bs-toggle="tooltip"]').tooltip();
|
|
}
|
|
static on_app_ready() {
|
|
Frontend_Settings_User_Settings.init();
|
|
}
|
|
|
|
// static on_jqhtml_ready() {
|
|
// // Called after all JQHTML components have loaded and rendered
|
|
// // Use this if you need to interact with JQHTML components
|
|
// // Otherwise, use on_app_ready() for most initialization
|
|
// }
|
|
}
|
|
|
|
|
|
/* === rsx/app/frontend/settings/password_security/frontend_settings_password_security.js (babel) === */
|
|
"use strict";
|
|
|
|
class Frontend_Settings_Password_Security {
|
|
static init() {
|
|
if (!$(".Frontend_Settings_Password_Security").exists()) return;
|
|
|
|
// Initialize your component here
|
|
console.log('Frontend_Settings_Password_Security initialized');
|
|
|
|
// Example: Handle button clicks
|
|
$('.btn-action').on('click', function () {
|
|
// Handle action
|
|
});
|
|
|
|
// Example: Initialize tooltips
|
|
$('[data-bs-toggle="tooltip"]').tooltip();
|
|
}
|
|
static on_app_ready() {
|
|
Frontend_Settings_Password_Security.init();
|
|
}
|
|
|
|
// static on_jqhtml_ready() {
|
|
// // Called after all JQHTML components have loaded and rendered
|
|
// // Use this if you need to interact with JQHTML components
|
|
// // Otherwise, use on_app_ready() for most initialization
|
|
// }
|
|
}
|
|
|
|
|
|
/* === rsx/app/frontend/settings/api_keys/frontend_settings_api_keys.js (babel) === */
|
|
"use strict";
|
|
|
|
class Frontend_Settings_Api_Keys {
|
|
static init() {
|
|
if (!$(".Frontend_Settings_Api_Keys").exists()) return;
|
|
|
|
// Initialize your component here
|
|
console.log('Frontend_Settings_Api_Keys initialized');
|
|
|
|
// Example: Handle button clicks
|
|
$('.btn-action').on('click', function () {
|
|
// Handle action
|
|
});
|
|
|
|
// Example: Initialize tooltips
|
|
$('[data-bs-toggle="tooltip"]').tooltip();
|
|
}
|
|
static on_app_ready() {
|
|
Frontend_Settings_Api_Keys.init();
|
|
}
|
|
|
|
// static on_jqhtml_ready() {
|
|
// // Called after all JQHTML components have loaded and rendered
|
|
// // Use this if you need to interact with JQHTML components
|
|
// // Otherwise, use on_app_ready() for most initialization
|
|
// }
|
|
}
|
|
|
|
|
|
/* === rsx/app/frontend/settings/user_management/users_datagrid.js (babel) === */
|
|
"use strict";
|
|
|
|
/**
|
|
* Users_DataGrid Component
|
|
*
|
|
* Concrete implementation for clients datagrid.
|
|
* All functionality is in DataGrid_Abstract.
|
|
*/
|
|
class Users_DataGrid extends DataGrid_Abstract {
|
|
// All behavior inherited from DataGrid_Abstract
|
|
}
|
|
|
|
|
|
/* === rsx/app/frontend/settings/user_management/add_user_form.js (babel) === */
|
|
"use strict";
|
|
|
|
/**
|
|
* Add_User_Form
|
|
*
|
|
* Modal form component for inviting users to the current site.
|
|
* See add_user_form.jqhtml for full documentation.
|
|
*
|
|
* JavaScript Responsibilities:
|
|
* - Implements vals() method for form data extraction
|
|
* - Provides default role_id (Member = 3)
|
|
*/
|
|
class Add_User_Form extends Component {
|
|
/**
|
|
* Get or set form values
|
|
* @param {Object} [values] - If provided, populates form with these values
|
|
* @returns {Object|null} - Form values if getting, null if setting
|
|
*/
|
|
// vals(values) {
|
|
// const form = this.$.find('form');
|
|
// if (values) {
|
|
// // Setter - populate form
|
|
// form.find('[name="email"]').val(values.email || '');
|
|
// form.find('[name="first_name"]').val(values.first_name || '');
|
|
// form.find('[name="last_name"]').val(values.last_name || '');
|
|
// form.find('[name="role_id"]').val(values.role_id || 3); // Default to Member
|
|
// form.find('[name="phone"]').val(values.phone || '');
|
|
// return null;
|
|
// } else {
|
|
// // Getter - extract form values
|
|
// return {
|
|
// email: form.find('[name="email"]').val(),
|
|
// first_name: form.find('[name="first_name"]').val(),
|
|
// last_name: form.find('[name="last_name"]').val(),
|
|
// role_id: parseInt(form.find('[name="role_id"]').val()) || 3,
|
|
// phone: form.find('[name="phone"]').val()
|
|
// };
|
|
// }
|
|
// }
|
|
}
|
|
|
|
|
|
/* === rsx/app/frontend/settings/user_management/add_user_modal.js (babel) === */
|
|
"use strict";
|
|
|
|
/**
|
|
* Add_User_Modal - Modal for adding/inviting new users to site
|
|
*
|
|
* Displays form to collect user information and create pending invitation.
|
|
* Uses Add_User_Modal_Form component for UI and validation.
|
|
*
|
|
* Returns created user record on success, false on cancel.
|
|
*/
|
|
class Add_User_Modal extends Modal_Abstract {
|
|
/**
|
|
* Show add user modal
|
|
*
|
|
* @returns {Promise<Object|false>} User record on success, false on cancel
|
|
*/
|
|
static async show() {
|
|
const result = await Modal.form({
|
|
title: 'Add User',
|
|
component: 'Add_User_Modal_Form',
|
|
on_submit: async form => {
|
|
try {
|
|
const values = form.vals();
|
|
const result = await Frontend_Settings_User_Management_Controller.add_user(values);
|
|
return result; // Close modal, return user data
|
|
} catch (error) {
|
|
// Render error (form handles both validation and generic errors)
|
|
await form.render_error(error);
|
|
return false; // Keep modal open
|
|
}
|
|
}
|
|
});
|
|
return result || false;
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/app/frontend/settings/user_management/send_user_invite_modal.js (babel) === */
|
|
"use strict";
|
|
|
|
/**
|
|
* Send_User_Invite_Modal - Modal for sending/resending user invitations
|
|
*
|
|
* Handles both initial invitation sending (after user creation) and resending
|
|
* expired/pending invitations. Calls backend endpoint to generate new invite
|
|
* code and displays URL for testing (until email system implemented).
|
|
*
|
|
* Returns invite data on success, false on error.
|
|
*/
|
|
class Send_User_Invite_Modal extends Modal_Abstract {
|
|
/**
|
|
* Show send invite modal and trigger backend invite
|
|
*
|
|
* @param {number} user_id - User ID to send invite to
|
|
* @returns {Promise<Object|false>} Invite data on success, false on error
|
|
*/
|
|
static async show(user_id) {
|
|
try {
|
|
// Call backend to send/resend invite
|
|
const result = await Frontend_Settings_User_Management_Controller.send_invite({
|
|
user_id
|
|
});
|
|
|
|
// Show invite URL for testing (until email system implemented)
|
|
if (result.invite_url) {
|
|
await Modal.alert('User Invited Successfully', `Invitation sent!\n\nTest invitation URL:\n${result.invite_url}`);
|
|
}
|
|
return result;
|
|
} catch (error) {
|
|
// Show error to user
|
|
await Modal.error(error, 'Failed to Send Invitation');
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/app/frontend/settings/user_management/frontend_settings_user_management.js (babel) === */
|
|
"use strict";
|
|
|
|
class Frontend_Settings_User_Management {
|
|
static init() {
|
|
if (!$('.Frontend_Settings_User_Management').exists()) return;
|
|
|
|
// Handle Add User button click
|
|
$('#btn_add_user').on('click', async function () {
|
|
await Frontend_Settings_User_Management.handle_add_user();
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Add user workflow: show add modal, refresh grid, show invite modal
|
|
*/
|
|
static async handle_add_user() {
|
|
// Show add user modal
|
|
const user = await Add_User_Modal.show();
|
|
if (user) {
|
|
// Refresh the user list
|
|
$('.Users_DataGrid').component().reload();
|
|
|
|
// Show send invite modal
|
|
await Send_User_Invite_Modal.show(user.id);
|
|
}
|
|
}
|
|
static on_app_ready() {
|
|
Frontend_Settings_User_Management.init();
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/app/frontend/settings/user_management/edit_user_modal.js (babel) === */
|
|
"use strict";
|
|
|
|
/**
|
|
* Edit_User_Modal - Modal for editing existing user information
|
|
*
|
|
* Displays form to update user profile information.
|
|
* Uses Edit_User_Modal_Form component for UI and validation.
|
|
*
|
|
* Returns updated user record on success, false on cancel.
|
|
*/
|
|
class Edit_User_Modal extends Modal_Abstract {
|
|
/**
|
|
* Show edit user modal
|
|
*
|
|
* @param {number} user_id - ID of user to edit
|
|
* @returns {Promise<Object|false>} Updated user record on success, false on cancel
|
|
*/
|
|
static async show(user_id) {
|
|
// Load user data for editing
|
|
let user_data;
|
|
try {
|
|
user_data = await Frontend_Settings_User_Management_Controller.get_user_for_edit({
|
|
user_id
|
|
});
|
|
} catch (error) {
|
|
await Modal.error(error, 'Failed to Load User');
|
|
return false;
|
|
}
|
|
const result = await Modal.form({
|
|
title: 'Edit User',
|
|
component: 'Edit_User_Modal_Form',
|
|
component_args: {
|
|
data: user_data
|
|
},
|
|
on_submit: async form => {
|
|
try {
|
|
const values = form.vals();
|
|
const result = await Frontend_Settings_User_Management_Controller.save_user(values);
|
|
return result; // Close modal, return user data
|
|
} catch (error) {
|
|
// Render error (form handles both validation and generic errors)
|
|
await form.render_error(error);
|
|
return false; // Keep modal open
|
|
}
|
|
}
|
|
});
|
|
return result || false;
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/app/frontend/settings/user_management/frontend_settings_user_management_view.js (babel) === */
|
|
"use strict";
|
|
|
|
class Frontend_Settings_User_Management_View {
|
|
static init() {
|
|
if (!$('.Frontend_Settings_User_Management_View').exists()) return;
|
|
|
|
// Handle Edit User button click
|
|
$('#btn_edit_user').on('click', async function () {
|
|
await Frontend_Settings_User_Management_View.handle_edit_user();
|
|
});
|
|
|
|
// Handle Resend Invite button click
|
|
$('#btn_resend_invite').on('click', async function () {
|
|
await Frontend_Settings_User_Management_View.handle_resend_invite();
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Edit user workflow: show edit modal, refresh page on save
|
|
*/
|
|
static async handle_edit_user() {
|
|
var _window$rsxapp$page_d;
|
|
// Get user ID from page data
|
|
const user_id = (_window$rsxapp$page_d = window.rsxapp.page_data) === null || _window$rsxapp$page_d === void 0 ? void 0 : _window$rsxapp$page_d.user_id;
|
|
if (!user_id) {
|
|
await Modal.error('User ID not found');
|
|
return;
|
|
}
|
|
|
|
// Show edit user modal
|
|
const result = await Edit_User_Modal.show(user_id);
|
|
if (result) {
|
|
// Refresh page to show updated user information
|
|
location.reload();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Resend invite workflow: call send invite modal
|
|
*/
|
|
static async handle_resend_invite() {
|
|
var _window$rsxapp$page_d2;
|
|
// Get user ID from page data
|
|
const user_id = (_window$rsxapp$page_d2 = window.rsxapp.page_data) === null || _window$rsxapp$page_d2 === void 0 ? void 0 : _window$rsxapp$page_d2.user_id;
|
|
if (!user_id) {
|
|
await Modal.error('User ID not found');
|
|
return;
|
|
}
|
|
|
|
// Show send invite modal
|
|
const result = await Send_User_Invite_Modal.show(user_id);
|
|
if (result) {
|
|
// Refresh page to show updated invite status
|
|
location.reload();
|
|
}
|
|
}
|
|
static on_app_ready() {
|
|
Frontend_Settings_User_Management_View.init();
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/app/frontend/settings/site_settings/frontend_settings_site_settings.js (babel) === */
|
|
"use strict";
|
|
|
|
class Frontend_Settings_Site_Settings {
|
|
static init() {
|
|
if (!$(".Frontend_Settings_Site_Settings").exists()) return;
|
|
|
|
// Initialize your component here
|
|
console.log('Frontend_Settings_Site_Settings initialized');
|
|
|
|
// Example: Handle button clicks
|
|
$('.btn-action').on('click', function () {
|
|
// Handle action
|
|
});
|
|
|
|
// Example: Initialize tooltips
|
|
$('[data-bs-toggle="tooltip"]').tooltip();
|
|
}
|
|
static on_app_ready() {
|
|
Frontend_Settings_Site_Settings.init();
|
|
}
|
|
|
|
// static on_jqhtml_ready() {
|
|
// // Called after all JQHTML components have loaded and rendered
|
|
// // Use this if you need to interact with JQHTML components
|
|
// // Otherwise, use on_app_ready() for most initialization
|
|
// }
|
|
}
|
|
|
|
|
|
/* === rsx/app/frontend/settings/frontend_settings.js (babel) === */
|
|
"use strict";
|
|
|
|
/**
|
|
* Settings Page JavaScript
|
|
*/
|
|
class Frontend_Settings {
|
|
/**
|
|
* Initialize the settings page
|
|
*/
|
|
static on_app_ready() {
|
|
// Only initialize if we're on the settings page
|
|
if (!$(".Frontend_Settings").exists()) {
|
|
return;
|
|
}
|
|
Debugger.console_debug("JS_INIT", "Settings page initialized");
|
|
|
|
// Handle sidebar navigation
|
|
$('.sidebar .nav-link').on('click', function (e) {
|
|
const $link = $(this);
|
|
if ($link.attr('href') === '#') {
|
|
e.preventDefault();
|
|
// Remove active from all links
|
|
$('.sidebar .nav-link').removeClass('active');
|
|
// Add active to clicked
|
|
$link.addClass('active');
|
|
const section = $link.text().trim();
|
|
Debugger.console_debug("UI", "Settings section clicked:", section);
|
|
}
|
|
});
|
|
|
|
// Handle form submissions
|
|
$('form').on('submit', function (e) {
|
|
e.preventDefault();
|
|
const $form = $(this);
|
|
const formData = $form.serialize();
|
|
Debugger.console_debug("FORM", "Settings form submitted", formData);
|
|
|
|
// Show success message (mock)
|
|
const $alert = $('<div class="alert alert-success alert-dismissible fade show" role="alert">').html('Settings saved successfully! <button type="button" class="btn-close" data-bs-dismiss="alert"></button>');
|
|
$form.closest('.card-body').prepend($alert);
|
|
|
|
// Auto-dismiss after 3 seconds
|
|
// setTimeout(() => {
|
|
// $alert.fadeOut(() => $alert.remove());
|
|
// }, 3000);
|
|
});
|
|
|
|
// Quick action buttons
|
|
$('.card-body .btn-primary').on('click', function () {
|
|
const $button = $(this);
|
|
const action = $button.text().trim();
|
|
Debugger.console_debug("UI", "Quick action:", action);
|
|
|
|
// Simulate action
|
|
const originalText = $button.html();
|
|
$button.html('<span class="spinner-border spinner-border-sm me-1"></span> Processing...');
|
|
$button.prop('disabled', true);
|
|
setTimeout(() => {
|
|
$button.html(originalText);
|
|
$button.prop('disabled', false);
|
|
}, 1500);
|
|
});
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/app/frontend/contacts/index/contacts_datagrid.js (babel) === */
|
|
"use strict";
|
|
|
|
/**
|
|
* Contacts_DataGrid Component
|
|
*
|
|
* Concrete implementation for contacts datagrid.
|
|
* All functionality is in DataGrid_Abstract.
|
|
*/
|
|
class Contacts_DataGrid extends DataGrid_Abstract {
|
|
// All behavior inherited from DataGrid_Abstract
|
|
}
|
|
|
|
|
|
/* === rsx/app/frontend/contacts/_data_table_qq/Data_Table.js (babel) === */
|
|
"use strict";
|
|
|
|
class Data_Table extends Component {
|
|
on_render() {
|
|
// Hide until data loads to prevent visual glitches
|
|
if (Object.keys(this.data).length === 0) {
|
|
this.$sid('footer').css('opacity', '0');
|
|
}
|
|
}
|
|
async on_load() {
|
|
// If data_source provided, fetch data
|
|
if (this.args.data_source) {
|
|
this.data = await this.fetch_data();
|
|
} else if (this.args.columns && this.args.rows) {
|
|
// Use provided static data
|
|
this.data = {
|
|
columns: this.args.columns,
|
|
rows: this.args.rows,
|
|
total: this.args.rows.length,
|
|
start: 1,
|
|
end: this.args.rows.length,
|
|
current_page: 1,
|
|
total_pages: 1
|
|
};
|
|
}
|
|
}
|
|
on_ready() {
|
|
// Show footer after render
|
|
this.$sid('footer').css('opacity', '1');
|
|
|
|
// Build column headers with sorting
|
|
if (this.data.columns) {
|
|
this.build_headers(this.data.columns);
|
|
}
|
|
|
|
// Setup search if enabled
|
|
if (this.args.searchable) {
|
|
this.setup_search();
|
|
}
|
|
|
|
// Setup column visibility toggle if enabled
|
|
if (this.args.column_toggle) {
|
|
this.setup_column_toggle();
|
|
}
|
|
|
|
// Setup bulk actions
|
|
if (this.args.bulk_actions) {
|
|
this.setup_bulk_actions();
|
|
}
|
|
|
|
// Attach row checkbox listeners
|
|
this.$.find('.row-checkbox').on('change', () => {
|
|
this.update_bulk_selection();
|
|
});
|
|
|
|
// Setup pagination click handlers
|
|
const $pagination = this.$sid('pagination');
|
|
$pagination.$.find('.page-link').on('click', e => {
|
|
e.preventDefault();
|
|
const page_text = $(e.target).text();
|
|
if (page_text === 'Previous') {
|
|
this.load_page(this.data.current_page - 1);
|
|
} else if (page_text === 'Next') {
|
|
this.load_page(this.data.current_page + 1);
|
|
} else {
|
|
const page = int(page_text);
|
|
if (!isNaN(page)) {
|
|
this.load_page(page);
|
|
}
|
|
}
|
|
});
|
|
}
|
|
build_headers(columns) {
|
|
const $header_row = this.$sid('header_row');
|
|
|
|
// Skip first cell if bulk actions (already has Bulk_Selection)
|
|
const offset = this.args.bulk_actions ? 1 : 0;
|
|
columns.forEach((col, index) => {
|
|
const $th = $('<th>');
|
|
if (col.sortable !== false) {
|
|
// Create sortable column header
|
|
const $sortable = $('<div>').addClass('Sortable_Column_Header').attr({
|
|
'data-column': col.field,
|
|
'data-sort': 'none'
|
|
});
|
|
const $text = $('<span>').text(col.label || col.field);
|
|
const $icon = $('<span>').attr('data-id', 'sort_icon').html('<i class="text-muted">⇅</i>');
|
|
$sortable.append($text).append(' ').append($icon);
|
|
$sortable.css('cursor', 'pointer');
|
|
$sortable.on('click', () => {
|
|
this.handle_sort(col.field);
|
|
});
|
|
$th.append($sortable);
|
|
} else {
|
|
$th.text(col.label || col.field);
|
|
}
|
|
if (col.width) {
|
|
$th.css('width', col.width);
|
|
}
|
|
$header_row.append($th);
|
|
});
|
|
|
|
// Add actions column header if row_actions enabled
|
|
if (this.args.row_actions) {
|
|
const $th = $('<th>').text('Actions').css('width', '100px');
|
|
$header_row.append($th);
|
|
}
|
|
}
|
|
setup_search() {
|
|
const $container = this.$sid('search_container');
|
|
const $search = $('<input>').attr({
|
|
type: 'search',
|
|
placeholder: 'Search...',
|
|
class: 'form-control form-control-sm'
|
|
}).css('width', '200px');
|
|
$container.append($search);
|
|
let timeout;
|
|
$search.on('input', e => {
|
|
clearTimeout(timeout);
|
|
timeout = setTimeout(() => {
|
|
this.search_query = e.target.value;
|
|
this.reload_data();
|
|
}, 300);
|
|
});
|
|
}
|
|
setup_column_toggle() {
|
|
const $container = this.$sid('column_toggle_container');
|
|
const $toggle = $('<div>').addClass('Column_Visibility_Toggle');
|
|
$container.append($toggle);
|
|
|
|
// Initialize component manually
|
|
const toggle_component = $toggle.component();
|
|
if (toggle_component) {
|
|
toggle_component.args.columns = this.data.columns;
|
|
toggle_component.args.table = this.$sid('table').$;
|
|
toggle_component.build_menu(this.data.columns);
|
|
}
|
|
}
|
|
setup_bulk_actions() {
|
|
const $bulk_selection = this.$sid('bulk_selection');
|
|
$bulk_selection.$.find('input[type="checkbox"]').on('change', e => {
|
|
const checked = e.target.checked;
|
|
this.$.find('.row-checkbox').prop('checked', checked);
|
|
this.update_bulk_selection();
|
|
});
|
|
}
|
|
update_bulk_selection() {
|
|
const checked = this.$.find('.row-checkbox:checked').length;
|
|
const $bulk_bar = this.$sid('bulk_bar');
|
|
if (checked > 0) {
|
|
$bulk_bar.$.show();
|
|
$bulk_bar.set_count(checked);
|
|
} else {
|
|
$bulk_bar.$.hide();
|
|
}
|
|
}
|
|
async handle_sort(field) {
|
|
// Toggle sort direction
|
|
const current = this.sort_field === field ? this.sort_direction : 'none';
|
|
this.sort_direction = current === 'none' ? 'asc' : current === 'asc' ? 'desc' : 'asc';
|
|
this.sort_field = field;
|
|
|
|
// Update sort icon
|
|
this.$sid('header_row').find('[data-column]').each(function () {
|
|
const $sortable = $(this);
|
|
const col = $sortable.attr('data-column');
|
|
const $icon = $sortable.find('[data-id="sort_icon"]');
|
|
if (col === field) {
|
|
$sortable.attr('data-sort', this.sort_direction);
|
|
if (this.sort_direction === 'asc') {
|
|
$icon.html('<i class="text-primary">↑</i>');
|
|
} else if (this.sort_direction === 'desc') {
|
|
$icon.html('<i class="text-primary">↓</i>');
|
|
} else {
|
|
$icon.html('<i class="text-muted">⇅</i>');
|
|
}
|
|
} else {
|
|
$sortable.attr('data-sort', 'none');
|
|
$icon.html('<i class="text-muted">⇅</i>');
|
|
}
|
|
}.bind(this));
|
|
await this.reload_data();
|
|
}
|
|
async load_page(page) {
|
|
if (page < 1 || page > this.data.total_pages) return;
|
|
this.current_page = page;
|
|
await this.reload_data();
|
|
}
|
|
async fetch_data() {
|
|
const params = {
|
|
page: this.current_page || 1,
|
|
per_page: this.args.per_page || 20,
|
|
sort_field: this.sort_field,
|
|
sort_direction: this.sort_direction,
|
|
search: this.search_query
|
|
};
|
|
|
|
// Call data source (can be URL or function)
|
|
if (typeof this.args.data_source === 'function') {
|
|
return await this.args.data_source(params);
|
|
} else {
|
|
const url = new URL(this.args.data_source, window.location.origin);
|
|
Object.keys(params).forEach(key => {
|
|
if (params[key]) url.searchParams.append(key, params[key]);
|
|
});
|
|
const response = await fetch(url);
|
|
return await response.json();
|
|
}
|
|
}
|
|
get_selected_ids() {
|
|
const ids = [];
|
|
this.$.find('.row-checkbox:checked').each(function () {
|
|
ids.push($(this).val());
|
|
});
|
|
return ids;
|
|
}
|
|
async reload_data() {
|
|
// Show loading state
|
|
const $tbody = this.$sid('tbody');
|
|
$tbody.html(`
|
|
<tr>
|
|
<td colspan="100" class="text-center py-5">
|
|
<div class="spinner-border spinner-border-sm" role="status">
|
|
<span class="visually-hidden">Loading...</span>
|
|
</div>
|
|
<div class="mt-2 text-muted">Loading data...</div>
|
|
</td>
|
|
</tr>
|
|
`);
|
|
|
|
// Fetch new data
|
|
this.data = await this.fetch_data();
|
|
|
|
// Re-render entire component
|
|
this.render();
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/app/frontend/contacts/edit/form/client_selector_input.js (babel) === */
|
|
"use strict";
|
|
|
|
class Client_Selector_Input extends Ajax_Select_Input {
|
|
async on_load() {
|
|
// Load clients via Ajax endpoint if data not provided
|
|
if (!this.args.data) {
|
|
this.data.select_values = await Frontend_Contacts_Controller.get_clients();
|
|
} else {
|
|
// Use parent on_load for custom data endpoints
|
|
await super.on_load();
|
|
}
|
|
}
|
|
on_create() {
|
|
// Set default placeholder if not provided
|
|
if (!this.args.placeholder) {
|
|
this.args.placeholder = 'Select Client...';
|
|
}
|
|
|
|
// Call parent to initialize Ajax_Select_Input
|
|
super.on_create();
|
|
}
|
|
on_ready() {
|
|
// Call parent to initialize Tom Select
|
|
super.on_ready();
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/app/frontend/contacts/edit/frontend_contacts_edit.js (babel) === */
|
|
"use strict";
|
|
|
|
class Frontend_Contacts_Edit {
|
|
static init() {
|
|
// No initialization needed - submit button automatically wired by Rsx_Form
|
|
}
|
|
static on_app_ready() {
|
|
Frontend_Contacts_Edit.init();
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/app/frontend/contacts/view/frontend_contacts_view.js (babel) === */
|
|
"use strict";
|
|
|
|
class Frontend_Contacts_View {
|
|
static init() {
|
|
if (!$('.Frontend_Contacts_View').exists()) return;
|
|
|
|
// Initialize your component here
|
|
console.log('Frontend_Contacts_View initialized');
|
|
|
|
// Example: Handle button clicks
|
|
$('.btn-action').on('click', function () {
|
|
// Handle action
|
|
});
|
|
|
|
// Example: Initialize tooltips
|
|
$('[data-bs-toggle="tooltip"]').tooltip();
|
|
}
|
|
static on_app_ready() {
|
|
Frontend_Contacts_View.init();
|
|
}
|
|
|
|
// static on_jqhtml_ready() {
|
|
// // Called after all JQHTML components have loaded and rendered
|
|
// // Use this if you need to interact with JQHTML components
|
|
// // Otherwise, use on_app_ready() for most initialization
|
|
// }
|
|
}
|
|
|
|
|
|
/* === rsx/app/frontend/contacts/frontend_contacts.js (babel) === */
|
|
"use strict";
|
|
|
|
class Frontend_Contacts {
|
|
static init() {
|
|
if (!$('.Frontend_Contacts').exists()) return;
|
|
|
|
// Initialize your component here
|
|
console.log('Frontend_Contacts initialized');
|
|
|
|
// // Example: Handle button clicks
|
|
// $('.btn-action').on('click', function() {
|
|
// // Handle action
|
|
// });
|
|
|
|
// // Example: Initialize tooltips
|
|
// $('[data-bs-toggle="tooltip"]').tooltip();
|
|
}
|
|
static on_app_ready() {
|
|
Frontend_Contacts.init();
|
|
}
|
|
|
|
// static on_jqhtml_ready() {
|
|
// // Called after all JQHTML components have loaded and rendered
|
|
// // Use this if you need to interact with JQHTML components
|
|
// // Otherwise, use on_app_ready() for most initialization
|
|
// }
|
|
}
|
|
|
|
|
|
/* === rsx/app/frontend/projects/index/projects_datagrid.js (babel) === */
|
|
"use strict";
|
|
|
|
/**
|
|
* Projects_DataGrid Component
|
|
*
|
|
* Concrete implementation for projects datagrid.
|
|
* All functionality is in DataGrid_Abstract.
|
|
*/
|
|
class Projects_DataGrid extends DataGrid_Abstract {
|
|
// All behavior inherited from DataGrid_Abstract
|
|
}
|
|
|
|
|
|
/* === rsx/app/frontend/projects/edit/frontend_projects_edit.js (babel) === */
|
|
"use strict";
|
|
|
|
class Frontend_Projects_Edit {
|
|
static init() {
|
|
// No initialization needed - submit button automatically wired by Rsx_Form
|
|
}
|
|
static on_app_ready() {
|
|
Frontend_Projects_Edit.init();
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/app/frontend/projects/frontend_projects_list.js (babel) === */
|
|
"use strict";
|
|
|
|
class Frontend_Projects_List {
|
|
static init() {
|
|
if (!$(".Frontend_Projects_List").exists()) return;
|
|
|
|
// Initialize your component here
|
|
console.log('Frontend_Projects_List initialized');
|
|
|
|
// Example: Handle button clicks
|
|
$('.btn-action').on('click', function () {
|
|
// Handle action
|
|
});
|
|
|
|
// Example: Initialize tooltips
|
|
$('[data-bs-toggle="tooltip"]').tooltip();
|
|
}
|
|
static on_app_ready() {
|
|
Frontend_Projects_List.init();
|
|
}
|
|
|
|
// static on_jqhtml_ready() {
|
|
// // Called after all JQHTML components have loaded and rendered
|
|
// // Use this if you need to interact with JQHTML components
|
|
// // Otherwise, use on_app_ready() for most initialization
|
|
// }
|
|
}
|
|
|
|
|
|
/* === rsx/app/frontend/projects/frontend_projects_view.js (babel) === */
|
|
"use strict";
|
|
|
|
class Frontend_Projects_View {
|
|
static init() {
|
|
if (!$(".Frontend_Projects_View").exists()) return;
|
|
|
|
// Initialize your component here
|
|
console.log('Frontend_Projects_View initialized');
|
|
|
|
// Example: Handle button clicks
|
|
$('.btn-action').on('click', function () {
|
|
// Handle action
|
|
});
|
|
|
|
// Example: Initialize tooltips
|
|
$('[data-bs-toggle="tooltip"]').tooltip();
|
|
}
|
|
static on_app_ready() {
|
|
Frontend_Projects_View.init();
|
|
}
|
|
|
|
// static on_jqhtml_ready() {
|
|
// // Called after all JQHTML components have loaded and rendered
|
|
// // Use this if you need to interact with JQHTML components
|
|
// // Otherwise, use on_app_ready() for most initialization
|
|
// }
|
|
}
|
|
|
|
|
|
/* === rsx/app/frontend/projects/frontend_projects_add.js (babel) === */
|
|
"use strict";
|
|
|
|
class Frontend_Projects_Add {
|
|
static init() {
|
|
if (!$(".Frontend_Projects_Add").exists()) return;
|
|
|
|
// Initialize your component here
|
|
console.log('Frontend_Projects_Add initialized');
|
|
|
|
// Example: Handle button clicks
|
|
$('.btn-action').on('click', function () {
|
|
// Handle action
|
|
});
|
|
|
|
// Example: Initialize tooltips
|
|
$('[data-bs-toggle="tooltip"]').tooltip();
|
|
}
|
|
static on_app_ready() {
|
|
Frontend_Projects_Add.init();
|
|
}
|
|
|
|
// static on_jqhtml_ready() {
|
|
// // Called after all JQHTML components have loaded and rendered
|
|
// // Use this if you need to interact with JQHTML components
|
|
// // Otherwise, use on_app_ready() for most initialization
|
|
// }
|
|
}
|
|
|
|
|
|
/* === rsx/app/frontend/projects/frontend_projects.js (babel) === */
|
|
"use strict";
|
|
|
|
class Frontend_Projects {
|
|
static init() {
|
|
if (!$(".Frontend_Projects").exists()) return;
|
|
|
|
// Initialize your component here
|
|
console.log('Frontend_Projects initialized');
|
|
}
|
|
static on_app_ready() {
|
|
Frontend_Projects.init();
|
|
}
|
|
}
|
|
|
|
|
|
/* === rsx/app/frontend/tasks/frontend_tasks.js (babel) === */
|
|
"use strict";
|
|
|
|
class Frontend_Tasks {
|
|
static init() {
|
|
if (!$(".Frontend_Tasks").exists()) return;
|
|
|
|
// Initialize your component here
|
|
console.log('Frontend_Tasks initialized');
|
|
|
|
// Example: Handle button clicks
|
|
$('.btn-action').on('click', function () {
|
|
// Handle action
|
|
});
|
|
|
|
// Example: Initialize tooltips
|
|
$('[data-bs-toggle="tooltip"]').tooltip();
|
|
}
|
|
static on_app_ready() {
|
|
Frontend_Tasks.init();
|
|
}
|
|
|
|
// static on_jqhtml_ready() {
|
|
// // Called after all JQHTML components have loaded and rendered
|
|
// // Use this if you need to interact with JQHTML components
|
|
// // Otherwise, use on_app_ready() for most initialization
|
|
// }
|
|
}
|
|
|
|
|
|
/* === rsx/app/frontend/tasks/frontend_tasks_view.js (babel) === */
|
|
"use strict";
|
|
|
|
class Frontend_Tasks_View {
|
|
static init() {
|
|
if (!$(".Frontend_Tasks_View").exists()) return;
|
|
|
|
// Initialize your component here
|
|
console.log('Frontend_Tasks_View initialized');
|
|
|
|
// Example: Handle button clicks
|
|
$('.btn-action').on('click', function () {
|
|
// Handle action
|
|
});
|
|
|
|
// Example: Initialize tooltips
|
|
$('[data-bs-toggle="tooltip"]').tooltip();
|
|
}
|
|
static on_app_ready() {
|
|
Frontend_Tasks_View.init();
|
|
}
|
|
|
|
// static on_jqhtml_ready() {
|
|
// // Called after all JQHTML components have loaded and rendered
|
|
// // Use this if you need to interact with JQHTML components
|
|
// // Otherwise, use on_app_ready() for most initialization
|
|
// }
|
|
}
|
|
|
|
|
|
/* === rsx/app/frontend/tasks/frontend_tasks_add.js (babel) === */
|
|
"use strict";
|
|
|
|
class Frontend_Tasks_Add {
|
|
static init() {
|
|
if (!$(".Frontend_Tasks_Add").exists()) return;
|
|
|
|
// Initialize your component here
|
|
console.log('Frontend_Tasks_Add initialized');
|
|
|
|
// Example: Handle button clicks
|
|
$('.btn-action').on('click', function () {
|
|
// Handle action
|
|
});
|
|
|
|
// Example: Initialize tooltips
|
|
$('[data-bs-toggle="tooltip"]').tooltip();
|
|
}
|
|
static on_app_ready() {
|
|
Frontend_Tasks_Add.init();
|
|
}
|
|
|
|
// static on_jqhtml_ready() {
|
|
// // Called after all JQHTML components have loaded and rendered
|
|
// // Use this if you need to interact with JQHTML components
|
|
// // Otherwise, use on_app_ready() for most initialization
|
|
// }
|
|
}
|
|
|
|
|
|
/* === rsx/app/frontend/calendar/frontend_calendar.js (babel) === */
|
|
"use strict";
|
|
|
|
class Frontend_Calendar {
|
|
static init() {
|
|
if (!$(".Frontend_Calendar").exists()) return;
|
|
|
|
// Initialize your component here
|
|
console.log('Frontend_Calendar initialized');
|
|
|
|
// Example: Handle button clicks
|
|
$('.btn-action').on('click', function () {
|
|
// Handle action
|
|
});
|
|
|
|
// Example: Initialize tooltips
|
|
$('[data-bs-toggle="tooltip"]').tooltip();
|
|
}
|
|
static on_app_ready() {
|
|
Frontend_Calendar.init();
|
|
}
|
|
|
|
// static on_jqhtml_ready() {
|
|
// // Called after all JQHTML components have loaded and rendered
|
|
// // Use this if you need to interact with JQHTML components
|
|
// // Otherwise, use on_app_ready() for most initialization
|
|
// }
|
|
}
|
|
|
|
|
|
/* === rsx/app/frontend/calendar/frontend_calendar_event.js (babel) === */
|
|
"use strict";
|
|
|
|
class Frontend_Calendar_Event {
|
|
static init() {
|
|
if (!$(".Frontend_Calendar_Event").exists()) return;
|
|
|
|
// Initialize your component here
|
|
console.log('Frontend_Calendar_Event initialized');
|
|
|
|
// Example: Handle button clicks
|
|
$('.btn-action').on('click', function () {
|
|
// Handle action
|
|
});
|
|
|
|
// Example: Initialize tooltips
|
|
$('[data-bs-toggle="tooltip"]').tooltip();
|
|
}
|
|
static on_app_ready() {
|
|
Frontend_Calendar_Event.init();
|
|
}
|
|
|
|
// static on_jqhtml_ready() {
|
|
// // Called after all JQHTML components have loaded and rendered
|
|
// // Use this if you need to interact with JQHTML components
|
|
// // Otherwise, use on_app_ready() for most initialization
|
|
// }
|
|
}
|
|
|
|
|
|
/* === rsx/app/frontend/invoices/frontend_invoices.js (babel) === */
|
|
"use strict";
|
|
|
|
class Frontend_Invoices {
|
|
static init() {
|
|
if (!$(".Frontend_Invoices").exists()) return;
|
|
|
|
// Initialize your component here
|
|
console.log('Frontend_Invoices initialized');
|
|
|
|
// Example: Handle button clicks
|
|
$('.btn-action').on('click', function () {
|
|
// Handle action
|
|
});
|
|
|
|
// Example: Initialize tooltips
|
|
$('[data-bs-toggle="tooltip"]').tooltip();
|
|
}
|
|
static on_app_ready() {
|
|
Frontend_Invoices.init();
|
|
}
|
|
|
|
// static on_jqhtml_ready() {
|
|
// // Called after all JQHTML components have loaded and rendered
|
|
// // Use this if you need to interact with JQHTML components
|
|
// // Otherwise, use on_app_ready() for most initialization
|
|
// }
|
|
}
|
|
|
|
|
|
/* === rsx/app/frontend/invoices/frontend_invoices_view.js (babel) === */
|
|
"use strict";
|
|
|
|
class Frontend_Invoices_View {
|
|
static init() {
|
|
if (!$(".Frontend_Invoices_View").exists()) return;
|
|
|
|
// Initialize your component here
|
|
console.log('Frontend_Invoices_View initialized');
|
|
|
|
// Example: Handle button clicks
|
|
$('.btn-action').on('click', function () {
|
|
// Handle action
|
|
});
|
|
|
|
// Example: Initialize tooltips
|
|
$('[data-bs-toggle="tooltip"]').tooltip();
|
|
}
|
|
static on_app_ready() {
|
|
Frontend_Invoices_View.init();
|
|
}
|
|
|
|
// static on_jqhtml_ready() {
|
|
// // Called after all JQHTML components have loaded and rendered
|
|
// // Use this if you need to interact with JQHTML components
|
|
// // Otherwise, use on_app_ready() for most initialization
|
|
// }
|
|
}
|
|
|
|
|
|
/* === rsx/app/frontend/invoices/frontend_invoices_add.js (babel) === */
|
|
"use strict";
|
|
|
|
function _72eab514_defineProperty(e, r, t) { return (r = _72eab514_toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
|
|
function _72eab514_toPropertyKey(t) { var i = _72eab514_toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
|
|
function _72eab514_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); }
|
|
/**
|
|
* Frontend_Invoices_Add Component
|
|
*
|
|
* Handles dynamic line items and invoice calculations
|
|
*/
|
|
class Frontend_Invoices_Add {
|
|
static async on_app_ready() {
|
|
if (!$(".Frontend_Invoices_Add").exists()) return;
|
|
|
|
// Add line item button
|
|
$('#addLineItem').on('click', () => {
|
|
Frontend_Invoices_Add.add_line_item();
|
|
});
|
|
|
|
// Initial calculation
|
|
Frontend_Invoices_Add.calculate_totals();
|
|
|
|
// Attach event handlers to existing line items
|
|
Frontend_Invoices_Add.attach_line_item_handlers();
|
|
|
|
// Tax rate change
|
|
$('#tax_rate').on('input', () => {
|
|
Frontend_Invoices_Add.calculate_totals();
|
|
});
|
|
}
|
|
static attach_line_item_handlers() {
|
|
// Quantity and rate changes
|
|
$('.item-quantity, .item-rate').off('input').on('input', function () {
|
|
Frontend_Invoices_Add.update_line_item_amount($(this).closest('tr'));
|
|
Frontend_Invoices_Add.calculate_totals();
|
|
});
|
|
|
|
// Remove item buttons
|
|
$('.remove-item').off('click').on('click', function () {
|
|
const $row = $(this).closest('tr');
|
|
if ($('#lineItemsBody tr').length > 1) {
|
|
$row.remove();
|
|
Frontend_Invoices_Add.calculate_totals();
|
|
} else {
|
|
alert('Invoice must have at least one line item');
|
|
}
|
|
});
|
|
}
|
|
static add_line_item() {
|
|
const index = Frontend_Invoices_Add.line_item_count++;
|
|
const $row = $(`
|
|
<tr class="line-item">
|
|
<td>
|
|
<input type="text" class="form-control form-control-sm" name="items[${index}][description]"
|
|
placeholder="Item description" required>
|
|
</td>
|
|
<td>
|
|
<input type="number" class="form-control form-control-sm text-end item-quantity"
|
|
name="items[${index}][quantity]" value="1" min="0" step="0.01" required>
|
|
</td>
|
|
<td>
|
|
<div class="input-group input-group-sm">
|
|
<span class="input-group-text">$</span>
|
|
<input type="number" class="form-control text-end item-rate"
|
|
name="items[${index}][rate]" value="0.00" min="0" step="0.01" required>
|
|
</div>
|
|
</td>
|
|
<td class="text-end">
|
|
<div class="fw-bold item-amount">$0.00</div>
|
|
</td>
|
|
<td class="text-center">
|
|
<button type="button" class="btn btn-sm btn-danger remove-item">
|
|
<i class="bi bi-trash"></i>
|
|
</button>
|
|
</td>
|
|
</tr>
|
|
`);
|
|
$('#lineItemsBody').append($row);
|
|
Frontend_Invoices_Add.attach_line_item_handlers();
|
|
}
|
|
static update_line_item_amount(row) {
|
|
const quantity = float(row.find('.item-quantity').val()) || 0;
|
|
const rate = float(row.find('.item-rate').val()) || 0;
|
|
const amount = quantity * rate;
|
|
row.find('.item-amount').text(`$${amount.toFixed(2)}`);
|
|
}
|
|
static calculate_totals() {
|
|
let subtotal = 0;
|
|
|
|
// Calculate subtotal from all line items
|
|
$('#lineItemsBody tr').each(function () {
|
|
const quantity = float($(this).find('.item-quantity').val()) || 0;
|
|
const rate = float($(this).find('.item-rate').val()) || 0;
|
|
subtotal += quantity * rate;
|
|
});
|
|
|
|
// Calculate tax
|
|
const tax_rate = float($('#tax_rate').val()) || 0;
|
|
const tax_amount = subtotal * (tax_rate / 100);
|
|
const total = subtotal + tax_amount;
|
|
|
|
// Update displays
|
|
$('#subtotalDisplay').text(`$${subtotal.toFixed(2)}`);
|
|
$('#taxDisplay').text(`$${tax_amount.toFixed(2)}`);
|
|
$('#totalDisplay').text(`$${total.toFixed(2)}`);
|
|
}
|
|
}
|
|
_72eab514_defineProperty(Frontend_Invoices_Add, "line_item_count", 1);
|
|
|
|
|
|
/* === rsx/app/frontend/reports/frontend_reports.js (babel) === */
|
|
"use strict";
|
|
|
|
class Frontend_Reports {
|
|
static init() {
|
|
if (!$(".Frontend_Reports").exists()) return;
|
|
|
|
// Initialize your component here
|
|
console.log('Frontend_Reports initialized');
|
|
|
|
// Example: Handle button clicks
|
|
$('.btn-action').on('click', function () {
|
|
// Handle action
|
|
});
|
|
|
|
// Example: Initialize tooltips
|
|
$('[data-bs-toggle="tooltip"]').tooltip();
|
|
}
|
|
static on_app_ready() {
|
|
Frontend_Reports.init();
|
|
}
|
|
|
|
// static on_jqhtml_ready() {
|
|
// // Called after all JQHTML components have loaded and rendered
|
|
// // Use this if you need to interact with JQHTML components
|
|
// // Otherwise, use on_app_ready() for most initialization
|
|
// }
|
|
}
|
|
|
|
|
|
/* === rsx/app/frontend/reports/frontend_reports_revenue.js (babel) === */
|
|
"use strict";
|
|
|
|
class Frontend_Reports_Revenue {
|
|
static init() {
|
|
if (!$(".Frontend_Reports_Revenue").exists()) return;
|
|
|
|
// Initialize your component here
|
|
console.log('Frontend_Reports_Revenue initialized');
|
|
|
|
// Example: Handle button clicks
|
|
$('.btn-action').on('click', function () {
|
|
// Handle action
|
|
});
|
|
|
|
// Example: Initialize tooltips
|
|
$('[data-bs-toggle="tooltip"]').tooltip();
|
|
}
|
|
static on_app_ready() {
|
|
Frontend_Reports_Revenue.init();
|
|
}
|
|
|
|
// static on_jqhtml_ready() {
|
|
// // Called after all JQHTML components have loaded and rendered
|
|
// // Use this if you need to interact with JQHTML components
|
|
// // Otherwise, use on_app_ready() for most initialization
|
|
// }
|
|
}
|
|
|
|
|
|
/* === rsx/app/frontend/reports/frontend_reports_clients.js (babel) === */
|
|
"use strict";
|
|
|
|
class Frontend_Reports_Clients {
|
|
static init() {
|
|
if (!$(".Frontend_Reports_Clients").exists()) return;
|
|
|
|
// Initialize your component here
|
|
console.log('Frontend_Reports_Clients initialized');
|
|
|
|
// Example: Handle button clicks
|
|
$('.btn-action').on('click', function () {
|
|
// Handle action
|
|
});
|
|
|
|
// Example: Initialize tooltips
|
|
$('[data-bs-toggle="tooltip"]').tooltip();
|
|
}
|
|
static on_app_ready() {
|
|
Frontend_Reports_Clients.init();
|
|
}
|
|
|
|
// static on_jqhtml_ready() {
|
|
// // Called after all JQHTML components have loaded and rendered
|
|
// // Use this if you need to interact with JQHTML components
|
|
// // Otherwise, use on_app_ready() for most initialization
|
|
// }
|
|
}
|
|
|
|
|
|
/* === rsx/app/frontend/reports/frontend_reports_projects.js (babel) === */
|
|
"use strict";
|
|
|
|
class Frontend_Reports_Projects {
|
|
static init() {
|
|
if (!$(".Frontend_Reports_Projects").exists()) return;
|
|
|
|
// Initialize your component here
|
|
console.log('Frontend_Reports_Projects initialized');
|
|
|
|
// Example: Handle button clicks
|
|
$('.btn-action').on('click', function () {
|
|
// Handle action
|
|
});
|
|
|
|
// Example: Initialize tooltips
|
|
$('[data-bs-toggle="tooltip"]').tooltip();
|
|
}
|
|
static on_app_ready() {
|
|
Frontend_Reports_Projects.init();
|
|
}
|
|
|
|
// static on_jqhtml_ready() {
|
|
// // Called after all JQHTML components have loaded and rendered
|
|
// // Use this if you need to interact with JQHTML components
|
|
// // Otherwise, use on_app_ready() for most initialization
|
|
// }
|
|
}
|
|
|
|
|
|
/* === rsx/app/frontend/reports/frontend_reports_time.js (babel) === */
|
|
"use strict";
|
|
|
|
class Frontend_Reports_Time {
|
|
static init() {
|
|
if (!$(".Frontend_Reports_Time").exists()) return;
|
|
|
|
// Initialize your component here
|
|
console.log('Frontend_Reports_Time initialized');
|
|
|
|
// Example: Handle button clicks
|
|
$('.btn-action').on('click', function () {
|
|
// Handle action
|
|
});
|
|
|
|
// Example: Initialize tooltips
|
|
$('[data-bs-toggle="tooltip"]').tooltip();
|
|
}
|
|
static on_app_ready() {
|
|
Frontend_Reports_Time.init();
|
|
}
|
|
|
|
// static on_jqhtml_ready() {
|
|
// // Called after all JQHTML components have loaded and rendered
|
|
// // Use this if you need to interact with JQHTML components
|
|
// // Otherwise, use on_app_ready() for most initialization
|
|
// }
|
|
}
|
|
|
|
|
|
/* === rsx/app/frontend/account/frontend_account.js (babel) === */
|
|
"use strict";
|
|
|
|
/**
|
|
* JavaScript for Frontend_Account view
|
|
*/
|
|
class Frontend_Account {
|
|
/**
|
|
* Initialize the view when app is ready
|
|
* This method is automatically called by RSX framework
|
|
* No manual registration is required
|
|
*/
|
|
static on_app_ready() {
|
|
// Check if we're on this specific page
|
|
if (!$(".Frontend_Account").exists()) return;
|
|
|
|
// View-specific initialization
|
|
console.log('Frontend_Account initialized');
|
|
}
|
|
}
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_4c789804a2735328.js === */
|
|
/* Compiled from: rsx/theme/components/datagrid/datagrid_abstract.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_DataGrid_Abstract = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'DataGrid_Abstract',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "card DataGrid"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_output.push(" ");
|
|
_output.push({comp: ["Card_Header", {}, function(Card_Header) { let _output = [];
|
|
_output.push(" "); (() => { const result = content('DG_Card_Header');; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })();
|
|
_output.push(" "); return [_output, this]; }.bind(this)]});
|
|
|
|
_output.push({tag: ["div", {"class": "card-body p-0"}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "table-responsive"}, false]});
|
|
_output.push(" ");_output.push({tag: ["table", {"class": "table table-hover mb-0"}, false]});
|
|
_output.push(" "); _output.push({comp: ["Redrawable", {"id": "datagrid_table_header" + ":" + this._cid, "data-id": "datagrid_table_header", "_tag": "thead"}, function(Redrawable) { let _output = [];
|
|
_output.push(" "); (() => { const result = content('DG_Table_Header');; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })();
|
|
_output.push(" "); return [_output, this]; }.bind(this)]});
|
|
_output.push({comp: ["Redrawable", {"id": "datagrid_table_body" + ":" + this._cid, "data-id": "datagrid_table_body", "class": ((this.data.loading && this.data.rows.length === 0) ? 'is-loading' : (this.data.is_empty ? 'is-empty' : '')), "_tag": "tbody"}, function(Redrawable) { let _output = [];
|
|
_output.push(" "); if (this.data.loading && this.data.rows.length === 0) {
|
|
_output.push({tag: ["tr", {"class": "loading-row"}, false]}); _output.push(" "); _output.push({tag: ["td", {"colspan": "999", "class": "text-center py-5"}, false]}); _output.push(" "); _output.push({tag: ["div", {"class": "spinner-border text-primary mb-3", "role": "status"}, false]}); _output.push(" "); _output.push({tag: ["span", {"class": "visually-hidden"}, false]}); _output.push("Loading..."); _output.push("</span>"); _output.push(" "); _output.push("</div>"); _output.push({tag: ["p", {"class": "text-muted"}, false]}); _output.push("Loading..."); _output.push("</p>"); _output.push(" "); _output.push("</td>"); _output.push("</tr>");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} else if (this.data.is_empty) {
|
|
_output.push({tag: ["tr", {"class": "empty-row"}, false]}); _output.push(" "); _output.push({tag: ["td", {"colspan": "999", "class": "text-center py-5"}, false]}); _output.push(" "); _output.push({tag: ["i", {"class": "bi bi-inbox", "style": "font-size: 3rem; color: #6c757d;"}, false]}); _output.push("</i>"); _output.push(" "); if (this.data.filter) { _output.push({tag: ["p", {"class": "text-muted mt-3"}, false]}); _output.push("No results found for \""); (() => { const result = this.data.filter ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("\""); _output.push("</p>"); _output.push(" "); _output.push({tag: ["button", {"id": "clear_filter_btn" + ":" + this._cid, "data-id": "clear_filter_btn", "class": "btn btn-sm btn-secondary mt-2"}, false]}); _output.push("Clear Filter"); _output.push("</button>"); _output.push(" "); } else { _output.push({tag: ["p", {"class": "text-muted mt-3"}, false]}); _output.push("No results found"); _output.push("</p>"); _output.push(" "); } _output.push("</td>"); _output.push("</tr>");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} else {
|
|
for(let row of this.data.rows) {
|
|
(() => { const result = content('row', row);; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })();
|
|
_output.push(" "); }
|
|
}
|
|
return [_output, this]; }.bind(this)]});
|
|
_output.push("</table>");
|
|
_output.push("</div>");
|
|
_output.push("</div>");
|
|
|
|
_output.push({comp: ["Card_Footer", {}, function(Card_Footer) { let _output = [];
|
|
_output.push(" "); _output.push({tag: ["div", {"class": "d-flex gap-2 align-items-center"}, false]}); _output.push(" "); _output.push({tag: ["div", {"class": "dropdown"}, false]}); _output.push(" "); _output.push({tag: ["button", {"class": "btn btn-secondary btn-sm dropdown-toggle", "type": "button", "data-bs-toggle": "dropdown"}, false]}); _output.push(" "); _output.push(" Actions "); _output.push("</button>"); _output.push(" "); _output.push({tag: ["ul", {"class": "dropdown-menu"}, false]}); _output.push(" "); _output.push({tag: ["li", {}, false]}); _output.push({tag: ["a", {"class": "dropdown-item", "href": "#"}, false]}); _output.push("Export Selected"); _output.push("</a>"); _output.push("</li>"); _output.push(" "); _output.push({tag: ["li", {}, false]}); _output.push({tag: ["a", {"class": "dropdown-item", "href": "#"}, false]}); _output.push("Delete Selected"); _output.push("</a>"); _output.push("</li>"); _output.push(" "); _output.push({tag: ["li", {}, false]}); _output.push(" "); _output.push({tag: ["hr", {"class": "dropdown-divider"}, true]}); _output.push(" "); _output.push("</li>"); _output.push({tag: ["li", {}, false]}); _output.push({tag: ["a", {"class": "dropdown-item", "href": "#"}, false]}); _output.push("Mark as Active"); _output.push("</a>"); _output.push("</li>"); _output.push(" "); _output.push("</ul>"); _output.push("</div>"); _output.push({comp: ["Pagination_Info", {"id": "pagination_info" + ":" + this._cid, "data-id": "pagination_info"}, function(Pagination_Info) {
|
|
const _output = [];
|
|
_output.push(" "); if (this.data.total && this.data.page && this.data.per_page) { /* empty line */
|
|
const start = ((this.data.page - 1) * this.data.per_page) + 1;
|
|
const end = Math.min(this.data.page * this.data.per_page, this.data.total); _output.push(" Showing "); (() => { const result = start ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push(" to "); (() => { const result = end ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push(" of "); (() => { const result = this.data.total ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push(" entries "); } _output.push(" ");
|
|
return [_output, this];
|
|
}.bind(this)]}); _output.push("</div>");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_output.push({comp: ["Pagination_Controls", {"id": "pagination_controls" + ":" + this._cid, "data-id": "pagination_controls"}, function(Pagination_Controls) {
|
|
const _output = [];
|
|
_output.push(" "); if (this.data.total_pages && this.data.total_pages > 1) { /* empty line */
|
|
const currentPage = this.data.page || 1;
|
|
const totalPages = this.data.total_pages;
|
|
const maxVisible = 7; // Maximum page numbers to show
|
|
/* empty line */
|
|
// Calculate page range to display
|
|
let startPage, endPage;
|
|
/* empty line */
|
|
if (totalPages <= maxVisible) {
|
|
// Show all pages if total is less than max
|
|
startPage = 1;
|
|
endPage = totalPages;
|
|
} else {
|
|
// Calculate range with current page near center
|
|
const maxPagesBeforeCurrentPage = Math.floor(maxVisible / 2);
|
|
const maxPagesAfterCurrentPage = Math.ceil(maxVisible / 2) - 1;
|
|
/* empty line */
|
|
if (currentPage <= maxPagesBeforeCurrentPage) {
|
|
// Near the start
|
|
startPage = 1;
|
|
endPage = maxVisible;
|
|
} else if (currentPage + maxPagesAfterCurrentPage >= totalPages) {
|
|
// Near the end
|
|
startPage = totalPages - maxVisible + 1;
|
|
endPage = totalPages;
|
|
} else {
|
|
// In the middle
|
|
startPage = currentPage - maxPagesBeforeCurrentPage;
|
|
endPage = currentPage + maxPagesAfterCurrentPage;
|
|
}
|
|
}
|
|
/* empty line */
|
|
// Generate page numbers array
|
|
const pages = [];
|
|
for (let i = startPage; i <= endPage; i++) {
|
|
pages.push(i);
|
|
}
|
|
/* empty line */
|
|
const showStartEllipsis = startPage > 1;
|
|
const showEndEllipsis = endPage < totalPages; _output.push({tag: ["li", {"class": "page-item" + (currentPage === 1 ? 'disabled' : '')}, false]}); _output.push(" "); _output.push({tag: ["a", {"class": "page-link", "href": "#", "data-page": (currentPage - 1), "tabindex": (currentPage === 1 ? '-1' : '0')}, false]}); _output.push(" "); _output.push(" Previous "); _output.push("</a>"); _output.push(" "); _output.push("</li>"); if (showStartEllipsis) { _output.push({tag: ["li", {"class": "page-item"}, false]}); _output.push(" "); _output.push({tag: ["a", {"class": "page-link", "href": "#", "data-page": "1"}, false]}); _output.push("1"); _output.push("</a>"); _output.push(" "); _output.push("</li>"); _output.push({tag: ["li", {"class": "page-item disabled"}, false]}); _output.push(" "); _output.push({tag: ["span", {"class": "page-link"}, false]}); _output.push("..."); _output.push("</span>"); _output.push(" "); _output.push("</li>"); } for (let pageNum of pages) { console.log("Loop check", pageNum, currentPage); _output.push({tag: ["li", {"class": "page-item" + (pageNum === currentPage ? 'active' : '')}, false]}); _output.push(" "); _output.push({tag: ["a", {"class": "page-link", "href": "#", "data-page": (pageNum)}, false]}); _output.push(" "); (() => { const result = pageNum ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push(" "); _output.push("</a>"); _output.push("</li>"); } if (showEndEllipsis) { _output.push({tag: ["li", {"class": "page-item disabled"}, false]}); _output.push(" "); _output.push({tag: ["span", {"class": "page-link"}, false]}); _output.push("..."); _output.push("</span>"); _output.push(" "); _output.push("</li>"); _output.push({tag: ["li", {"class": "page-item"}, false]}); _output.push(" "); _output.push({tag: ["a", {"class": "page-link", "href": "#", "data-page": (totalPages)}, false]}); (() => { const result = totalPages ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</a>"); _output.push(" "); _output.push("</li>"); } _output.push({tag: ["li", {"class": "page-item" + (currentPage === totalPages ? 'disabled' : '')}, false]}); _output.push(" "); _output.push({tag: ["a", {"class": "page-link", "href": "#", "data-page": (currentPage + 1)}, false]}); _output.push(" "); _output.push(" Next "); _output.push("</a>"); _output.push(" "); _output.push("</li>"); }
|
|
return [_output, this];
|
|
}.bind(this)]});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return [_output, this]; }.bind(this)]});
|
|
|
|
return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_DataGrid_Abstract);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_cafa46b601e1b05d.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/action_button_delete.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Action_Button_Delete = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Action_Button_Delete',
|
|
tag: 'button',
|
|
defaultAttributes: {"type": "button", "class": "btn btn-danger", "title": "Delete"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-trash"}, false]}); _output.push("</i>");
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Action_Button_Delete);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_39f39e3b268dbe32.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/action_button_edit.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Action_Button_Edit = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Action_Button_Edit',
|
|
tag: 'a',
|
|
defaultAttributes: {"class": "btn btn-secondary", "title": "Edit"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-pencil"}, false]}); _output.push("</i>");
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Action_Button_Edit);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_40cbd9b14342dbca.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/action_button_view.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Action_Button_View = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Action_Button_View',
|
|
tag: 'a',
|
|
defaultAttributes: {"class": "btn btn-primary", "title": "View"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-eye"}, false]}); _output.push("</i>");
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Action_Button_View);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_c4cd6b6689b37222.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/activity_feed.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Activity_Feed = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Activity_Feed',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "list-group list-group-flush"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" "); if (Object.keys(this.data).length === 0) {
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "text-center py-4"}, false]});
|
|
_output.push(" "); _output.push({comp: ["Spinner", {}]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "mt-2 text-muted small"}, false]}); _output.push("Loading activity..."); _output.push("</div>");
|
|
_output.push(" "); _output.push("</div>");
|
|
} else if (this.data.activities && this.data.activities.length === 0) {
|
|
_output.push(" "); _output.push({comp: ["Empty_State", {"data-icon": "activity", "data-title": "No activity yet", "data-message": "Activity will appear here"}]});
|
|
|
|
|
|
|
|
|
|
_output.push(" "); } else {
|
|
_output.push(" "); for (let activity of this.data.activities || []) {
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "list-group-item d-flex gap-3 py-3"}, false]});
|
|
_output.push(" "); if (activity.avatar) {
|
|
_output.push(" "); _output.push({comp: ["Avatar", {"data-src": activity.avatar, "data-size": "sm"}]});
|
|
_output.push(" "); } else {
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "rounded-circle bg-primary text-white d-flex align-items-center justify-content-center", "style": "width: 32px; height: 32px; flex-shrink: 0;"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-" + (activity.icon || 'activity')}, false]}); _output.push("</i>");
|
|
_output.push(" "); _output.push("</div>");
|
|
}
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "flex-grow-1"}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "d-flex justify-content-between align-items-start"}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["strong", {}, false]}); (() => { const result = activity.user_name ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</strong>");
|
|
_output.push(" ");_output.push({tag: ["span", {"class": "text-muted"}, false]}); (() => { const result = activity.action ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</span>");
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push({tag: ["small", {"class": "text-muted"}, false]}); (() => { const result = activity.time_ago ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</small>");
|
|
_output.push(" "); _output.push("</div>");
|
|
if (activity.description) {
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "text-muted small mt-1"}, false]}); (() => { const result = activity.description ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</div>");
|
|
_output.push(" "); }
|
|
_output.push(" "); if (activity.metadata) {
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "mt-2"}, false]});
|
|
_output.push(" "); for (let key in activity.metadata) {
|
|
_output.push(" ");_output.push({tag: ["span", {"class": "badge bg-light text-dark me-1"}, false]});
|
|
_output.push(" "); (() => { const result = key ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push(": "); (() => { const result = activity.metadata[key] ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })();
|
|
_output.push(" "); _output.push("</span>");
|
|
}
|
|
_output.push(" "); _output.push("</div>");
|
|
}
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push("</div>");
|
|
}
|
|
_output.push(" "); }
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Activity_Feed);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_16e12ed0cd36683b.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/actor_reference.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Actor_Reference = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Actor_Reference',
|
|
tag: 'small',
|
|
defaultAttributes: {"class": "text-muted d-block mt-1"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Actor_Reference);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_94c8ee6c8ba68a1d.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/advanced_search_panel.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Advanced_Search_Panel = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Advanced_Search_Panel',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "card"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "card-header d-flex justify-content-between align-items-center"}, false]});
|
|
_output.push(" ");_output.push({tag: ["h5", {"class": "mb-0"}, false]}); _output.push("Advanced Search"); _output.push("</h5>");
|
|
_output.push(" ");_output.push({tag: ["button", {"type": "button", "class": "btn-close", "id": "close_btn" + ":" + this._cid, "data-id": "close_btn"}, false]}); _output.push("</button>");
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push({tag: ["div", {"class": "card-body"}, false]});
|
|
_output.push(" ");_output.push({tag: ["form", {"id": "search_form" + ":" + this._cid, "data-id": "search_form"}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "row g-3"}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "col-12"}, false]});
|
|
_output.push(" "); _output.push({comp: ["Input_With_Validation", {"data-label": "Keywords", "data-placeholder": "Search keywords...", "data-name": "keywords", "id": "keywords" + ":" + this._cid, "data-id": "keywords"}]});
|
|
|
|
|
|
|
|
|
|
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push({tag: ["div", {"class": "col-md-6"}, false]});
|
|
_output.push(" "); _output.push({comp: ["Searchable_Select", {"data-label": "Category", "data-placeholder": "Select category", "id": "category" + ":" + this._cid, "data-id": "category"}]});
|
|
|
|
|
|
|
|
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push({tag: ["div", {"class": "col-md-6"}, false]});
|
|
_output.push(" "); _output.push({comp: ["Multi_Select", {"data-label": "Tags", "data-placeholder": "Select tags", "id": "tags" + ":" + this._cid, "data-id": "tags"}]});
|
|
|
|
|
|
|
|
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push({tag: ["div", {"class": "col-md-6"}, false]});
|
|
_output.push(" "); _output.push({comp: ["Date_Picker", {"data-label": "From Date", "id": "from_date" + ":" + this._cid, "data-id": "from_date"}]});
|
|
|
|
|
|
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push({tag: ["div", {"class": "col-md-6"}, false]});
|
|
_output.push(" "); _output.push({comp: ["Date_Picker", {"data-label": "To Date", "id": "to_date" + ":" + this._cid, "data-id": "to_date"}]});
|
|
|
|
|
|
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push({tag: ["div", {"class": "col-12"}, false]});
|
|
_output.push(" ");_output.push({tag: ["label", {"class": "form-label"}, false]}); _output.push("Sort By"); _output.push("</label>");
|
|
_output.push(" ");_output.push({tag: ["select", {"class": "form-select", "id": "sort_by" + ":" + this._cid, "data-id": "sort_by"}, false]});
|
|
_output.push(" ");_output.push({tag: ["option", {"value": "relevance"}, false]}); _output.push("Relevance"); _output.push("</option>");
|
|
_output.push(" ");_output.push({tag: ["option", {"value": "date"}, false]}); _output.push("Date"); _output.push("</option>");
|
|
_output.push(" ");_output.push({tag: ["option", {"value": "title"}, false]}); _output.push("Title"); _output.push("</option>");
|
|
_output.push(" "); _output.push("</select>");
|
|
_output.push("</div>");
|
|
_output.push({tag: ["div", {"class": "col-12"}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "form-check"}, false]});
|
|
_output.push(" ");_output.push({tag: ["input", {"class": "form-check-input", "type": "checkbox", "id": "exact_match" + ":" + this._cid, "data-id": "exact_match"}, true]}); _output.push("</input>");
|
|
_output.push(" ");_output.push({tag: ["label", {"class": "form-check-label"}, false]});
|
|
_output.push(" "); _output.push(" Exact match only "); _output.push("</label>");
|
|
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push("</div>");
|
|
_output.push("</div>");
|
|
_output.push("</form>");
|
|
_output.push("</div>");
|
|
_output.push({tag: ["div", {"class": "card-footer d-flex justify-content-between"}, false]});
|
|
_output.push(" "); _output.push({comp: ["Button_Secondary", {"id": "reset_btn" + ":" + this._cid, "data-id": "reset_btn"}, function(Button_Secondary) { let _output = []; _output.push("Reset"); return [_output, this]; }.bind(this)]});
|
|
_output.push(" "); _output.push({comp: ["Button_Primary", {"id": "search_btn" + ":" + this._cid, "data-id": "search_btn"}, function(Button_Primary) { let _output = []; _output.push("Search"); return [_output, this]; }.bind(this)]});
|
|
_output.push(" "); _output.push("</div>");
|
|
return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Advanced_Search_Panel);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_9785d1ab0167c4c2.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/alert_banner.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Alert_Banner = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Alert_Banner',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "alert alert-info alert-dismissible fade show", "role": "alert"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" ");_output.push({tag: ["button", {"type": "button", "class": "btn-close", "data-bs-dismiss": "alert", "aria-label": "Close"}, false]}); _output.push("</button>");
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Alert_Banner);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_23f6ef44135b0ff4.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/avatar.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Avatar = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Avatar',
|
|
tag: 'img',
|
|
defaultAttributes: {"class": "rounded-circle", "alt": "User avatar"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Avatar);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_9b93da3b449e709a.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/blockquote.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Blockquote = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Blockquote',
|
|
tag: 'blockquote',
|
|
defaultAttributes: {"class": "blockquote"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Blockquote);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_8962f68b97d8e8f3.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/breadcrumbs.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Breadcrumbs = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Breadcrumbs',
|
|
tag: 'nav',
|
|
defaultAttributes: {"aria-label": "breadcrumb"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" ");_output.push({tag: ["ol", {"class": "breadcrumb mb-0"}, false]});
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); _output.push("</ol>");
|
|
return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Breadcrumbs);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_afe144bdfa61d3cd.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/bulk_action_bar.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Bulk_Action_Bar = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Bulk_Action_Bar',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "alert alert-primary d-flex justify-content-between align-items-center mb-3", "role": "alert"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" ");_output.push({tag: ["div", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["strong", {"class": "count"}, false]}); _output.push("0"); _output.push("</strong>"); _output.push(" items selected "); _output.push("</div>");
|
|
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "d-flex gap-2"}, false]});
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" ");_output.push({tag: ["button", {"type": "button", "class": "btn-close", "id": "close_btn" + ":" + this._cid, "data-id": "close_btn", "aria-label": "Close"}, false]}); _output.push("</button>");
|
|
_output.push(" "); _output.push("</div>");
|
|
return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Bulk_Action_Bar);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_e544f4c81faee9c9.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/bulk_selection.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Bulk_Selection = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Bulk_Selection',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "form-check"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" ");_output.push({tag: ["input", {"class": "form-check-input", "type": "checkbox", "id": "checkbox" + ":" + this._cid, "data-id": "checkbox", "aria-label": "Select all"}, true]}); _output.push("</input>");
|
|
|
|
|
|
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Bulk_Selection);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_2f4eef67eee9d66a.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/button_group.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Button_Group = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Button_Group',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "btn-group", "role": "group"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Button_Group);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_b239d09fd9e8122f.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/button_primary.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Button_Primary = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Button_Primary',
|
|
tag: 'button',
|
|
defaultAttributes: {"class": "btn btn-primary", "type": "button"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Button_Primary);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_3ad6fdf2a551145b.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/button_secondary.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Button_Secondary = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Button_Secondary',
|
|
tag: 'button',
|
|
defaultAttributes: {"class": "btn btn-secondary", "type": "button"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Button_Secondary);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_bcfe3c72ddaa89e1.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/button.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Button = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Button',
|
|
tag: 'button',
|
|
defaultAttributes: {"class": "btn", "type": "button"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Button);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_90dcdfb9bcaea588.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/calendar_event.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Calendar_Event = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Calendar_Event',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "card mb-2", "style": "cursor: pointer;"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "card-body p-2"}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "d-flex align-items-start gap-2"}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "bg-" + (this.args.color || 'primary') + "rounded", "style": "width: 4px; height: 100%; min-height: 40px;"}, false]}); _output.push("</div>");
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "flex-grow-1"}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "fw-bold small"}, false]}); (() => { const result = this.args.title ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</div>");
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "text-muted small"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-clock me-1"}, false]}); _output.push("</i>");
|
|
_output.push(" "); (() => { const result = this.args.time ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })();
|
|
_output.push(" "); _output.push("</div>");
|
|
if (this.args.location) {
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "text-muted small"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-geo-alt me-1"}, false]}); _output.push("</i>");
|
|
_output.push(" "); (() => { const result = this.args.location ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })();
|
|
_output.push(" "); _output.push("</div>");
|
|
}
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push("</div>");
|
|
_output.push("</div>");
|
|
return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Calendar_Event);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_21cc4349a5469d96.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/calendar_grid.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Calendar_Grid = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Calendar_Grid',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "card"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "card-header d-flex justify-content-between align-items-center"}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "btn-group btn-group-sm"}, false]});
|
|
_output.push(" ");_output.push({tag: ["button", {"type": "button", "class": "btn btn-secondary", "id": "prev_btn" + ":" + this._cid, "data-id": "prev_btn"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-chevron-left"}, false]}); _output.push("</i>");
|
|
_output.push(" "); _output.push("</button>");
|
|
_output.push({tag: ["button", {"type": "button", "class": "btn btn-secondary", "id": "today_btn" + ":" + this._cid, "data-id": "today_btn"}, false]}); _output.push("Today"); _output.push("</button>");
|
|
_output.push(" ");_output.push({tag: ["button", {"type": "button", "class": "btn btn-secondary", "id": "next_btn" + ":" + this._cid, "data-id": "next_btn"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-chevron-right"}, false]}); _output.push("</i>");
|
|
_output.push(" "); _output.push("</button>");
|
|
_output.push("</div>");
|
|
_output.push({tag: ["h5", {"class": "mb-0", "id": "month_title" + ":" + this._cid, "data-id": "month_title"}, false]}); _output.push("</h5>");
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "btn-group btn-group-sm"}, false]});
|
|
_output.push(" ");_output.push({tag: ["button", {"type": "button", "class": "btn btn-secondary", "data-view": "month"}, false]}); _output.push("Month"); _output.push("</button>");
|
|
_output.push(" ");_output.push({tag: ["button", {"type": "button", "class": "btn btn-secondary", "data-view": "week"}, false]}); _output.push("Week"); _output.push("</button>");
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push("</div>");
|
|
_output.push({tag: ["div", {"class": "card-body p-0"}, false]});
|
|
_output.push(" ");_output.push({tag: ["table", {"class": "table table-bordered mb-0"}, false]});
|
|
_output.push(" ");_output.push({tag: ["thead", {"class": "table-light"}, false]});
|
|
_output.push(" ");_output.push({tag: ["tr", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["th", {"class": "text-center"}, false]}); _output.push("Sun"); _output.push("</th>");
|
|
_output.push(" ");_output.push({tag: ["th", {"class": "text-center"}, false]}); _output.push("Mon"); _output.push("</th>");
|
|
_output.push(" ");_output.push({tag: ["th", {"class": "text-center"}, false]}); _output.push("Tue"); _output.push("</th>");
|
|
_output.push(" ");_output.push({tag: ["th", {"class": "text-center"}, false]}); _output.push("Wed"); _output.push("</th>");
|
|
_output.push(" ");_output.push({tag: ["th", {"class": "text-center"}, false]}); _output.push("Thu"); _output.push("</th>");
|
|
_output.push(" ");_output.push({tag: ["th", {"class": "text-center"}, false]}); _output.push("Fri"); _output.push("</th>");
|
|
_output.push(" ");_output.push({tag: ["th", {"class": "text-center"}, false]}); _output.push("Sat"); _output.push("</th>");
|
|
_output.push(" "); _output.push("</tr>");
|
|
_output.push("</thead>");
|
|
_output.push({tag: ["tbody", {"id": "calendar_body" + ":" + this._cid, "data-id": "calendar_body"}, false]});
|
|
_output.push(" "); _output.push("<!-- Generated via JavaScript -->");
|
|
_output.push(" "); _output.push("</tbody>");
|
|
_output.push("</table>");
|
|
_output.push("</div>");
|
|
return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Calendar_Grid);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_c7f2613cd27ca298.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/card_footer.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Card_Footer = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Card_Footer',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "card-footer bg-light"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "d-flex justify-content-between align-items-center"}, false]});
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); _output.push("</div>");
|
|
return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Card_Footer);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_ebb90bbbba9ffc1b.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/card_header.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Card_Header = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Card_Header',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "card-header bg-light"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "d-flex justify-content-between align-items-center"}, false]});
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); _output.push("</div>");
|
|
return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Card_Header);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_046c6fa8cf01a4ee.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/card_title.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Card_Title = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Card_Title',
|
|
tag: 'h5',
|
|
defaultAttributes: {"class": "mb-0"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" ");
|
|
(() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" ");
|
|
return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Card_Title);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_fd9575173d3ff436.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/card.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Card = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Card',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "card"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" ");
|
|
_output.push({tag: ["div", {"class": "card-body"}, false]});
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); _output.push("</div>");
|
|
|
|
return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Card);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_bb17642e22644b05.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/chart_component.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Chart_Component = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Chart_Component',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "chart-placeholder bg-light rounded d-flex align-items-center justify-content-center"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "text-center text-muted p-5"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-graph-up fs-1 d-block mb-2"}, false]}); _output.push("</i>");
|
|
_output.push(" ");_output.push({tag: ["p", {"class": "mb-0"}, false]}); _output.push("Chart Component"); _output.push("</p>");
|
|
_output.push(" ");_output.push({tag: ["small", {}, false]}); _output.push("Placeholder for future chart integration"); _output.push("</small>");
|
|
_output.push(" "); _output.push("</div>");
|
|
return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Chart_Component);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_c5c07318a6a9c3fb.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/checkbox.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Checkbox = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Checkbox',
|
|
tag: 'input',
|
|
defaultAttributes: {"type": "checkbox", "class": "form-check-input"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Checkbox);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_91cd4a0023337040.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/code_block.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Code_Block = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Code_Block',
|
|
tag: 'pre',
|
|
defaultAttributes: {"class": "p-3 bg-dark text-light rounded"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" ");_output.push({tag: ["code", {}, false]}); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })(); _output.push("</code>");
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Code_Block);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_915ef00c65975793.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/column_visibility_toggle.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Column_Visibility_Toggle = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Column_Visibility_Toggle',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "dropdown"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" ");_output.push({tag: ["button", {"class": "btn btn-secondary btn-sm dropdown-toggle", "type": "button", "data-bs-toggle": "dropdown", "aria-expanded": "false"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-columns"}, false]}); _output.push("</i>"); _output.push(" Columns "); _output.push("</button>");
|
|
|
|
_output.push(" ");_output.push({tag: ["ul", {"class": "dropdown-menu dropdown-menu-end", "id": "menu" + ":" + this._cid, "data-id": "menu"}, false]});
|
|
_output.push(" "); _output.push("<!-- Dynamically populated via JavaScript -->");
|
|
_output.push(" "); _output.push("</ul>");
|
|
return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Column_Visibility_Toggle);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_b3e6a83d01905036.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/comment_thread.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Comment_Thread = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Comment_Thread',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "card"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "card-header d-flex justify-content-between align-items-center"}, false]});
|
|
_output.push(" ");_output.push({tag: ["h5", {"class": "mb-0"}, false]}); _output.push("Comments (");_output.push({tag: ["span", {"id": "comment_count" + ":" + this._cid, "data-id": "comment_count"}, false]}); (() => { const result = (this.data.comments || []).length ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</span>"); _output.push(")"); _output.push("</h5>");
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push({tag: ["div", {"class": "card-body"}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"id": "comments" + ":" + this._cid, "data-id": "comments"}, false]});
|
|
_output.push(" "); if (Object.keys(this.data).length === 0) {
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "text-center py-4"}, false]});
|
|
_output.push(" "); _output.push({comp: ["Spinner", {}]});
|
|
_output.push(" "); _output.push("</div>");
|
|
} else if (this.data.comments && this.data.comments.length === 0) {
|
|
_output.push(" "); _output.push({comp: ["Empty_State", {"data-icon": "chat-left-text", "data-title": "No comments yet", "data-message": "Be the first to comment"}]});
|
|
|
|
|
|
|
|
|
|
_output.push(" "); } else {
|
|
_output.push(" "); for (let comment of this.data.comments || []) {
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "d-flex gap-3 mb-4", "data-comment-id": (comment.id)}, false]});
|
|
_output.push(" "); _output.push({comp: ["Avatar", {"data-src": comment.avatar, "data-name": comment.user_name, "data-size": "sm"}]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "flex-grow-1"}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "bg-light rounded p-3"}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "d-flex justify-content-between align-items-start mb-2"}, false]});
|
|
_output.push(" ");_output.push({tag: ["strong", {}, false]}); (() => { const result = comment.user_name ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</strong>");
|
|
_output.push(" ");_output.push({tag: ["small", {"class": "text-muted"}, false]}); (() => { const result = comment.time_ago ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</small>");
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push({tag: ["div", {}, false]}); (() => { const result = comment.text ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</div>");
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push({tag: ["div", {"class": "mt-2"}, false]});
|
|
_output.push(" ");_output.push({tag: ["button", {"class": "btn btn-link btn-sm p-0 me-3 reply-btn"}, false]}); _output.push("Reply"); _output.push("</button>");
|
|
_output.push(" "); if (comment.can_edit) {
|
|
_output.push(" ");_output.push({tag: ["button", {"class": "btn btn-link btn-sm p-0 me-3 edit-btn"}, false]}); _output.push("Edit"); _output.push("</button>");
|
|
_output.push(" "); }
|
|
_output.push(" "); if (comment.can_delete) {
|
|
_output.push(" ");_output.push({tag: ["button", {"class": "btn btn-link btn-sm p-0 text-danger delete-btn"}, false]}); _output.push("Delete"); _output.push("</button>");
|
|
_output.push(" "); }
|
|
_output.push(" "); _output.push("</div>");
|
|
if (comment.replies && comment.replies.length > 0) {
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "ms-4 mt-3"}, false]});
|
|
_output.push(" "); for (let reply of comment.replies) {
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "d-flex gap-3 mb-3", "data-comment-id": (reply.id)}, false]});
|
|
_output.push(" "); _output.push({comp: ["Avatar", {"data-src": reply.avatar, "data-name": reply.user_name, "data-size": "xs"}]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "flex-grow-1"}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "bg-light rounded p-2"}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "d-flex justify-content-between align-items-start mb-1"}, false]});
|
|
_output.push(" ");_output.push({tag: ["strong", {"class": "small"}, false]}); (() => { const result = reply.user_name ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</strong>");
|
|
_output.push(" ");_output.push({tag: ["small", {"class": "text-muted"}, false]}); (() => { const result = reply.time_ago ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</small>");
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push({tag: ["div", {"class": "small"}, false]}); (() => { const result = reply.text ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</div>");
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push("</div>");
|
|
_output.push("</div>");
|
|
}
|
|
_output.push(" "); _output.push("</div>");
|
|
}
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push("</div>");
|
|
}
|
|
_output.push(" "); }
|
|
_output.push(" "); _output.push("</div>");
|
|
|
|
_output.push("<!-- New comment form -->");
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "mt-4 pt-4 border-top", "id": "new_comment_form" + ":" + this._cid, "data-id": "new_comment_form"}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "d-flex gap-3"}, false]});
|
|
_output.push(" "); _output.push({comp: ["Avatar", {"data-src": this.args.current_user_avatar, "data-name": this.args.current_user_name, "data-size": "sm"}]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "flex-grow-1"}, false]});
|
|
_output.push(" ");_output.push({tag: ["textarea", {"class": "form-control mb-2", "rows": "3", "placeholder": "Write a comment...", "id": "comment_input" + ":" + this._cid, "data-id": "comment_input"}, false]}); _output.push("</textarea>");
|
|
_output.push(" "); _output.push({comp: ["Button_Primary", {"id": "submit_btn" + ":" + this._cid, "data-id": "submit_btn"}, function(Button_Primary) { let _output = []; _output.push("Post Comment"); return [_output, this]; }.bind(this)]});
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push("</div>");
|
|
_output.push("</div>");
|
|
_output.push("</div>");
|
|
return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Comment_Thread);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_8e90648b1e516e10.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/contact_actions.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Contact_Actions = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Contact_Actions',
|
|
tag: 'td',
|
|
defaultAttributes: {},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" ");
|
|
_output.push({tag: ["div", {"class": "btn-group btn-group-sm"}, false]});
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); _output.push("</div>");
|
|
|
|
return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Contact_Actions);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_7f748fe97d884387.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/contact_row.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Contact_Row = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Contact_Row',
|
|
tag: 'tr',
|
|
defaultAttributes: {},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Contact_Row);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_522acc1e0535a8e0.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/contacts_data_table.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Contacts_Data_Table = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Contacts_Data_Table',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "card-body p-0"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "table-responsive"}, false]});
|
|
_output.push(" ");_output.push({tag: ["table", {"class": "table table-hover mb-0"}, false]});
|
|
_output.push(" ");_output.push({tag: ["thead", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["tr", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["th", {"style": "width: 40px;"}, false]});_output.push({tag: ["input", {"class": "form-check-input", "type": "checkbox"}, true]}); _output.push("</input>"); _output.push("</th>");
|
|
_output.push(" ");_output.push({tag: ["th", {}, false]}); _output.push("ID"); _output.push("</th>");
|
|
_output.push(" ");_output.push({tag: ["th", {}, false]}); _output.push("Name"); _output.push("</th>");
|
|
_output.push(" ");_output.push({tag: ["th", {}, false]}); _output.push("Email"); _output.push("</th>");
|
|
_output.push(" ");_output.push({tag: ["th", {}, false]}); _output.push("Phone"); _output.push("</th>");
|
|
_output.push(" ");_output.push({tag: ["th", {}, false]}); _output.push("Company"); _output.push("</th>");
|
|
_output.push(" ");_output.push({tag: ["th", {}, false]}); _output.push("Role"); _output.push("</th>");
|
|
_output.push(" ");_output.push({tag: ["th", {}, false]}); _output.push("Status"); _output.push("</th>");
|
|
_output.push(" ");_output.push({tag: ["th", {}, false]}); _output.push("Created"); _output.push("</th>");
|
|
_output.push(" ");_output.push({tag: ["th", {"style": "width: 100px;"}, false]}); _output.push("Actions"); _output.push("</th>");
|
|
_output.push(" "); _output.push("</tr>");
|
|
_output.push("</thead>");
|
|
_output.push({tag: ["tbody", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["tr", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});_output.push({tag: ["input", {"class": "form-check-input", "type": "checkbox"}, true]}); _output.push("</input>"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});_output.push({tag: ["a", {"href": (Rsx.Route('Frontend_Contacts_View_Controller'))}, false]}); _output.push("#CT001"); _output.push("</a>"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});_output.push({tag: ["a", {"href": (Rsx.Route('Frontend_Contacts_View_Controller'))}, false]}); _output.push("Jane Smith"); _output.push("</a>"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});_output.push({tag: ["a", {"href": (Rsx.Route('Frontend_Contacts_View_Controller'))}, false]}); _output.push("jane@acme.com"); _output.push("</a>"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("(555) 123-4567"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("Acme Corporation"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("CEO"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});_output.push({tag: ["span", {"class": "badge bg-success"}, false]}); _output.push("Active"); _output.push("</span>"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("Jan 15, 2024"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "btn-group btn-group-sm"}, false]});
|
|
_output.push(" ");_output.push({tag: ["a", {"class": "btn btn-primary", "href": (Rsx.Route('Frontend_Contacts_View_Controller')), "title": "View"}, false]});_output.push({tag: ["i", {"class": "bi bi-eye"}, false]}); _output.push("</i>"); _output.push("</a>");
|
|
_output.push(" ");_output.push({tag: ["a", {"class": "btn btn-secondary", "href": "#", "title": "Edit"}, false]});_output.push({tag: ["i", {"class": "bi bi-pencil"}, false]}); _output.push("</i>"); _output.push("</a>");
|
|
_output.push(" ");_output.push({tag: ["button", {"class": "btn btn-danger", "type": "button", "title": "Delete"}, false]});_output.push({tag: ["i", {"class": "bi bi-trash"}, false]}); _output.push("</i>"); _output.push("</button>");
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push("</td>");
|
|
_output.push("</tr>");
|
|
_output.push({tag: ["tr", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});_output.push({tag: ["input", {"class": "form-check-input", "type": "checkbox"}, true]}); _output.push("</input>"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("#CT002"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("Bob Johnson"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("bob@techsolutions.io"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("(555) 234-5678"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("Tech Solutions Inc"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("CTO"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});_output.push({tag: ["span", {"class": "badge bg-success"}, false]}); _output.push("Active"); _output.push("</span>"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("Jan 18, 2024"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "btn-group btn-group-sm"}, false]});
|
|
_output.push(" ");_output.push({tag: ["a", {"class": "btn btn-primary", "href": (Rsx.Route('Frontend_Contacts_View_Controller')), "title": "View"}, false]});_output.push({tag: ["i", {"class": "bi bi-eye"}, false]}); _output.push("</i>"); _output.push("</a>");
|
|
_output.push(" ");_output.push({tag: ["a", {"class": "btn btn-secondary", "href": "#", "title": "Edit"}, false]});_output.push({tag: ["i", {"class": "bi bi-pencil"}, false]}); _output.push("</i>"); _output.push("</a>");
|
|
_output.push(" ");_output.push({tag: ["button", {"class": "btn btn-danger", "type": "button", "title": "Delete"}, false]});_output.push({tag: ["i", {"class": "bi bi-trash"}, false]}); _output.push("</i>"); _output.push("</button>");
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push("</td>");
|
|
_output.push("</tr>");
|
|
_output.push({tag: ["tr", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});_output.push({tag: ["input", {"class": "form-check-input", "type": "checkbox"}, true]}); _output.push("</input>"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("#CT003"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("Sarah Wilson"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("sarah@globalent.com"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("(555) 345-6789"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("Global Enterprises"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("Project Manager"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});_output.push({tag: ["span", {"class": "badge bg-warning"}, false]}); _output.push("Pending"); _output.push("</span>"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("Feb 02, 2024"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "btn-group btn-group-sm"}, false]});
|
|
_output.push(" ");_output.push({tag: ["a", {"class": "btn btn-primary", "href": (Rsx.Route('Frontend_Contacts_View_Controller')), "title": "View"}, false]});_output.push({tag: ["i", {"class": "bi bi-eye"}, false]}); _output.push("</i>"); _output.push("</a>");
|
|
_output.push(" ");_output.push({tag: ["a", {"class": "btn btn-secondary", "href": "#", "title": "Edit"}, false]});_output.push({tag: ["i", {"class": "bi bi-pencil"}, false]}); _output.push("</i>"); _output.push("</a>");
|
|
_output.push(" ");_output.push({tag: ["button", {"class": "btn btn-danger", "type": "button", "title": "Delete"}, false]});_output.push({tag: ["i", {"class": "bi bi-trash"}, false]}); _output.push("</i>"); _output.push("</button>");
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push("</td>");
|
|
_output.push("</tr>");
|
|
_output.push({tag: ["tr", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});_output.push({tag: ["input", {"class": "form-check-input", "type": "checkbox"}, true]}); _output.push("</input>"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("#CT004"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("Michael Brown"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("mbrown@innovation.co"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("(555) 456-7890"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("StartUp Innovations"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("Developer"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});_output.push({tag: ["span", {"class": "badge bg-success"}, false]}); _output.push("Active"); _output.push("</span>"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("Feb 10, 2024"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "btn-group btn-group-sm"}, false]});
|
|
_output.push(" ");_output.push({tag: ["a", {"class": "btn btn-primary", "href": (Rsx.Route('Frontend_Contacts_View_Controller')), "title": "View"}, false]});_output.push({tag: ["i", {"class": "bi bi-eye"}, false]}); _output.push("</i>"); _output.push("</a>");
|
|
_output.push(" ");_output.push({tag: ["a", {"class": "btn btn-secondary", "href": "#", "title": "Edit"}, false]});_output.push({tag: ["i", {"class": "bi bi-pencil"}, false]}); _output.push("</i>"); _output.push("</a>");
|
|
_output.push(" ");_output.push({tag: ["button", {"class": "btn btn-danger", "type": "button", "title": "Delete"}, false]});_output.push({tag: ["i", {"class": "bi bi-trash"}, false]}); _output.push("</i>"); _output.push("</button>");
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push("</td>");
|
|
_output.push("</tr>");
|
|
_output.push({tag: ["tr", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});_output.push({tag: ["input", {"class": "form-check-input", "type": "checkbox"}, true]}); _output.push("</input>"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("#CT005"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("Emily Davis"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("emily@wilson.com"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("(555) 567-8901"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("Wilson & Associates"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("Marketing Director"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});_output.push({tag: ["span", {"class": "badge bg-danger"}, false]}); _output.push("Suspended"); _output.push("</span>"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("Feb 15, 2024"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "btn-group btn-group-sm"}, false]});
|
|
_output.push(" ");_output.push({tag: ["a", {"class": "btn btn-primary", "href": (Rsx.Route('Frontend_Contacts_View_Controller')), "title": "View"}, false]});_output.push({tag: ["i", {"class": "bi bi-eye"}, false]}); _output.push("</i>"); _output.push("</a>");
|
|
_output.push(" ");_output.push({tag: ["a", {"class": "btn btn-secondary", "href": "#", "title": "Edit"}, false]});_output.push({tag: ["i", {"class": "bi bi-pencil"}, false]}); _output.push("</i>"); _output.push("</a>");
|
|
_output.push(" ");_output.push({tag: ["button", {"class": "btn btn-danger", "type": "button", "title": "Delete"}, false]});_output.push({tag: ["i", {"class": "bi bi-trash"}, false]}); _output.push("</i>"); _output.push("</button>");
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push("</td>");
|
|
_output.push("</tr>");
|
|
_output.push({tag: ["tr", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});_output.push({tag: ["input", {"class": "form-check-input", "type": "checkbox"}, true]}); _output.push("</input>"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("#CT006"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("David Martinez"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("david@dmppro.com"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("(555) 678-9012"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("Digital Marketing Pro"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("Sales Manager"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});_output.push({tag: ["span", {"class": "badge bg-success"}, false]}); _output.push("Active"); _output.push("</span>"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("Mar 01, 2024"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "btn-group btn-group-sm"}, false]});
|
|
_output.push(" ");_output.push({tag: ["a", {"class": "btn btn-primary", "href": (Rsx.Route('Frontend_Contacts_View_Controller')), "title": "View"}, false]});_output.push({tag: ["i", {"class": "bi bi-eye"}, false]}); _output.push("</i>"); _output.push("</a>");
|
|
_output.push(" ");_output.push({tag: ["a", {"class": "btn btn-secondary", "href": "#", "title": "Edit"}, false]});_output.push({tag: ["i", {"class": "bi bi-pencil"}, false]}); _output.push("</i>"); _output.push("</a>");
|
|
_output.push(" ");_output.push({tag: ["button", {"class": "btn btn-danger", "type": "button", "title": "Delete"}, false]});_output.push({tag: ["i", {"class": "bi bi-trash"}, false]}); _output.push("</i>"); _output.push("</button>");
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push("</td>");
|
|
_output.push("</tr>");
|
|
_output.push({tag: ["tr", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});_output.push({tag: ["input", {"class": "form-check-input", "type": "checkbox"}, true]}); _output.push("</input>"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("#CT007"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("Jennifer Anderson"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("jennifer@andersonind.net"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("(555) 789-0123"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("Anderson Industries"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("CFO"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});_output.push({tag: ["span", {"class": "badge bg-success"}, false]}); _output.push("Active"); _output.push("</span>"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("Mar 05, 2024"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "btn-group btn-group-sm"}, false]});
|
|
_output.push(" ");_output.push({tag: ["a", {"class": "btn btn-primary", "href": (Rsx.Route('Frontend_Contacts_View_Controller')), "title": "View"}, false]});_output.push({tag: ["i", {"class": "bi bi-eye"}, false]}); _output.push("</i>"); _output.push("</a>");
|
|
_output.push(" ");_output.push({tag: ["a", {"class": "btn btn-secondary", "href": "#", "title": "Edit"}, false]});_output.push({tag: ["i", {"class": "bi bi-pencil"}, false]}); _output.push("</i>"); _output.push("</a>");
|
|
_output.push(" ");_output.push({tag: ["button", {"class": "btn btn-danger", "type": "button", "title": "Delete"}, false]});_output.push({tag: ["i", {"class": "bi bi-trash"}, false]}); _output.push("</i>"); _output.push("</button>");
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push("</td>");
|
|
_output.push("</tr>");
|
|
_output.push({tag: ["tr", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});_output.push({tag: ["input", {"class": "form-check-input", "type": "checkbox"}, true]}); _output.push("</input>"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("#CT008"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("Robert Thompson"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("robert@creativestudios.com"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("(555) 890-1234"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("Creative Studios LLC"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("Art Director"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});_output.push({tag: ["span", {"class": "badge bg-warning"}, false]}); _output.push("Pending"); _output.push("</span>"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("Mar 12, 2024"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "btn-group btn-group-sm"}, false]});
|
|
_output.push(" ");_output.push({tag: ["a", {"class": "btn btn-primary", "href": (Rsx.Route('Frontend_Contacts_View_Controller')), "title": "View"}, false]});_output.push({tag: ["i", {"class": "bi bi-eye"}, false]}); _output.push("</i>"); _output.push("</a>");
|
|
_output.push(" ");_output.push({tag: ["a", {"class": "btn btn-secondary", "href": "#", "title": "Edit"}, false]});_output.push({tag: ["i", {"class": "bi bi-pencil"}, false]}); _output.push("</i>"); _output.push("</a>");
|
|
_output.push(" ");_output.push({tag: ["button", {"class": "btn btn-danger", "type": "button", "title": "Delete"}, false]});_output.push({tag: ["i", {"class": "bi bi-trash"}, false]}); _output.push("</i>"); _output.push("</button>");
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push("</td>");
|
|
_output.push("</tr>");
|
|
_output.push({tag: ["tr", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});_output.push({tag: ["input", {"class": "form-check-input", "type": "checkbox"}, true]}); _output.push("</input>"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("#CT009"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("Lisa Garcia"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("lisa@garciaconsult.com"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("(555) 901-2345"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("Garcia Consulting"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("Consultant"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});_output.push({tag: ["span", {"class": "badge bg-success"}, false]}); _output.push("Active"); _output.push("</span>"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("Mar 18, 2024"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "btn-group btn-group-sm"}, false]});
|
|
_output.push(" ");_output.push({tag: ["a", {"class": "btn btn-primary", "href": (Rsx.Route('Frontend_Contacts_View_Controller')), "title": "View"}, false]});_output.push({tag: ["i", {"class": "bi bi-eye"}, false]}); _output.push("</i>"); _output.push("</a>");
|
|
_output.push(" ");_output.push({tag: ["a", {"class": "btn btn-secondary", "href": "#", "title": "Edit"}, false]});_output.push({tag: ["i", {"class": "bi bi-pencil"}, false]}); _output.push("</i>"); _output.push("</a>");
|
|
_output.push(" ");_output.push({tag: ["button", {"class": "btn btn-danger", "type": "button", "title": "Delete"}, false]});_output.push({tag: ["i", {"class": "bi bi-trash"}, false]}); _output.push("</i>"); _output.push("</button>");
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push("</td>");
|
|
_output.push("</tr>");
|
|
_output.push({tag: ["tr", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});_output.push({tag: ["input", {"class": "form-check-input", "type": "checkbox"}, true]}); _output.push("</input>"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("#CT010"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("Christopher White"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("chris@whitepartners.org"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("(555) 012-3456"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("White & Partners"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("Partner"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});_output.push({tag: ["span", {"class": "badge bg-success"}, false]}); _output.push("Active"); _output.push("</span>"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("Mar 22, 2024"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "btn-group btn-group-sm"}, false]});
|
|
_output.push(" ");_output.push({tag: ["a", {"class": "btn btn-primary", "href": (Rsx.Route('Frontend_Contacts_View_Controller')), "title": "View"}, false]});_output.push({tag: ["i", {"class": "bi bi-eye"}, false]}); _output.push("</i>"); _output.push("</a>");
|
|
_output.push(" ");_output.push({tag: ["a", {"class": "btn btn-secondary", "href": "#", "title": "Edit"}, false]});_output.push({tag: ["i", {"class": "bi bi-pencil"}, false]}); _output.push("</i>"); _output.push("</a>");
|
|
_output.push(" ");_output.push({tag: ["button", {"class": "btn btn-danger", "type": "button", "title": "Delete"}, false]});_output.push({tag: ["i", {"class": "bi bi-trash"}, false]}); _output.push("</i>"); _output.push("</button>");
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push("</td>");
|
|
_output.push("</tr>");
|
|
_output.push("</tbody>");
|
|
_output.push("</table>");
|
|
_output.push("</div>");
|
|
return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Contacts_Data_Table);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_11caea8e6e7fc2d3.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/contacts_list_card.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Contacts_List_Card = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Contacts_List_Card',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "card"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" ");
|
|
(() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" ");
|
|
return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Contacts_List_Card);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_2b0dad9b2a4c6834.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/date_picker.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Date_Picker = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Date_Picker',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "mb-3"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" "); if (this.args.label) {
|
|
_output.push(" ");_output.push({tag: ["label", {"class": "form-label"}, false]}); (() => { const result = this.args.label ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</label>");
|
|
_output.push(" "); }
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "input-group"}, false]});
|
|
_output.push(" ");_output.push({tag: ["span", {"class": "input-group-text"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-calendar"}, false]}); _output.push("</i>");
|
|
_output.push(" "); _output.push("</span>");
|
|
_output.push({tag: ["input", {"type": "date", "class": "form-control", "placeholder": (this.args.placeholder || ''), "id": "input" + ":" + this._cid, "data-id": "input"}, true]}); _output.push("</input>");
|
|
|
|
|
|
|
|
|
|
|
|
_output.push(" "); _output.push("</div>");
|
|
if (this.args.help) {
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "form-text"}, false]}); (() => { const result = this.args.help ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</div>");
|
|
_output.push(" "); }
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Date_Picker);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_865ebd1e323b6278.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/dropdown_menu.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Dropdown_Menu = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Dropdown_Menu',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "dropdown"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" ");_output.push({tag: ["button", {"class": "btn btn-secondary dropdown-toggle", "type": "button", "data-bs-toggle": "dropdown", "aria-expanded": "false", "id": "toggle" + ":" + this._cid, "data-id": "toggle"}, false]});
|
|
|
|
|
|
|
|
|
|
_output.push(" "); (() => { const result = this.args.label || 'Menu' ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })();
|
|
_output.push(" "); _output.push("</button>");
|
|
_output.push({tag: ["ul", {"class": "dropdown-menu", "aria-labelledby": "toggle", "id": "menu" + ":" + this._cid, "data-id": "menu"}, false]});
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); _output.push("</ul>");
|
|
return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Dropdown_Menu);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_c4180645ca8fee3a.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/empty_state.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Empty_State = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Empty_State',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "text-center py-5"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "mb-3 text-muted", "style": "font-size: 3rem;"}, false]});
|
|
_output.push(" "); _output.push({comp: ["Icon", {"data-name": this.args.icon || 'inbox'}]});
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push({tag: ["h5", {"class": "text-muted"}, false]}); (() => { const result = this.args.title || 'No items found' ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</h5>");
|
|
_output.push(" ");_output.push({tag: ["p", {"class": "text-muted"}, false]}); (() => { const result = this.args.message || 'Get started by creating a new item.' ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</p>");
|
|
_output.push(" "); if (this.args.action_label) {
|
|
_output.push(" "); _output.push({comp: ["Button_Primary", {}, function(Button_Primary) { let _output = []; (() => { const result = this.args.action_label ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); return [_output, this]; }.bind(this)]});
|
|
_output.push(" "); }
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Empty_State);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_92f90b187b0143cf.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/export_button.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Export_Button = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Export_Button',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "dropdown"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" ");_output.push({tag: ["button", {"class": "btn btn-" + (this.args.variant || 'primary') + "dropdown-toggle", "type": "button", "data-bs-toggle": "dropdown", "aria-expanded": "false"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-download"}, false]}); _output.push("</i>");
|
|
_output.push(" "); (() => { const result = this.args.label || 'Export' ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })();
|
|
_output.push(" "); _output.push("</button>");
|
|
_output.push({tag: ["ul", {"class": "dropdown-menu"}, false]});
|
|
_output.push(" ");_output.push({tag: ["li", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["a", {"class": "dropdown-item", "href": "#", "data-format": "csv"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-filetype-csv me-2"}, false]}); _output.push("</i>");
|
|
_output.push(" "); _output.push(" Export as CSV "); _output.push("</a>");
|
|
|
|
_output.push(" "); _output.push("</li>");
|
|
_output.push({tag: ["li", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["a", {"class": "dropdown-item", "href": "#", "data-format": "excel"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-filetype-xlsx me-2"}, false]}); _output.push("</i>");
|
|
_output.push(" "); _output.push(" Export as Excel "); _output.push("</a>");
|
|
|
|
_output.push(" "); _output.push("</li>");
|
|
_output.push({tag: ["li", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["a", {"class": "dropdown-item", "href": "#", "data-format": "pdf"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-filetype-pdf me-2"}, false]}); _output.push("</i>");
|
|
_output.push(" "); _output.push(" Export as PDF "); _output.push("</a>");
|
|
|
|
_output.push(" "); _output.push("</li>");
|
|
_output.push({tag: ["li", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["a", {"class": "dropdown-item", "href": "#", "data-format": "json"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-filetype-json me-2"}, false]}); _output.push("</i>");
|
|
_output.push(" "); _output.push(" Export as JSON "); _output.push("</a>");
|
|
|
|
_output.push(" "); _output.push("</li>");
|
|
_output.push("</ul>");
|
|
return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Export_Button);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_9a5639b57b894f70.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/file_upload.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_File_Upload = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'File_Upload',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "mb-3"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" "); if (this.args.label) {
|
|
_output.push(" ");_output.push({tag: ["label", {"class": "form-label"}, false]}); (() => { const result = this.args.label ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</label>");
|
|
_output.push(" "); }
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "border rounded p-4 text-center", "id": "drop_zone" + ":" + this._cid, "data-id": "drop_zone", "style": "cursor: pointer; transition: all 0.2s;"}, false]});
|
|
_output.push(" ");_output.push({tag: ["input", {"type": "file", "class": "d-none", "id": "file_input" + ":" + this._cid, "data-id": "file_input"}, true]}); _output.push("</input>");
|
|
_output.push(" ");_output.push({tag: ["div", {"id": "placeholder" + ":" + this._cid, "data-id": "placeholder"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-cloud-upload fs-1 text-muted"}, false]}); _output.push("</i>");
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "mt-2"}, false]});
|
|
_output.push(" ");_output.push({tag: ["span", {"class": "text-primary"}, false]}); _output.push("Click to upload"); _output.push("</span>"); _output.push(" or drag and drop "); _output.push("</div>");
|
|
|
|
_output.push(" "); if (this.args.accept) {
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "text-muted small mt-1"}, false]}); (() => { const result = this.args.accept ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</div>");
|
|
_output.push(" "); }
|
|
_output.push(" "); if (this.args.max_size) {
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "text-muted small"}, false]}); _output.push("Max size: "); (() => { const result = this.args.max_size ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</div>");
|
|
_output.push(" "); }
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push({tag: ["div", {"id": "file_info" + ":" + this._cid, "data-id": "file_info", "style": "display: none;"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-file-earmark fs-1 text-success"}, false]}); _output.push("</i>");
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "mt-2", "id": "file_name" + ":" + this._cid, "data-id": "file_name"}, false]}); _output.push("</div>");
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "text-muted small", "id": "file_size" + ":" + this._cid, "data-id": "file_size"}, false]}); _output.push("</div>");
|
|
_output.push(" "); _output.push({comp: ["Button_Secondary", {"id": "remove_btn" + ":" + this._cid, "data-id": "remove_btn", "class": "mt-2"}, function(Button_Secondary) { let _output = []; _output.push("Remove"); return [_output, this]; }.bind(this)]});
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push({tag: ["div", {"id": "progress" + ":" + this._cid, "data-id": "progress", "style": "display: none;"}, false]});
|
|
_output.push(" "); _output.push({comp: ["Progress_Bar", {"id": "progress_bar" + ":" + this._cid, "data-id": "progress_bar"}]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "text-muted small mt-2"}, false]}); _output.push("Uploading..."); _output.push("</div>");
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push("</div>");
|
|
if (this.args.help) {
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "form-text"}, false]}); (() => { const result = this.args.help ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</div>");
|
|
_output.push(" "); }
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_File_Upload);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_e8b264b6e5dbbf91.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/filter_bar.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Filter_Bar = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Filter_Bar',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "card mb-3"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "card-body"}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "row g-3 align-items-end"}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "col-auto"}, false]});
|
|
_output.push(" ");_output.push({tag: ["label", {"class": "form-label small text-muted mb-1"}, false]}); _output.push("Search"); _output.push("</label>");
|
|
_output.push(" "); _output.push({comp: ["Input_With_Icon", {"data-icon": "search", "data-placeholder": "Search...", "id": "search" + ":" + this._cid, "data-id": "search"}]});
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push({tag: ["div", {"class": "col-auto"}, false]});
|
|
_output.push(" ");_output.push({tag: ["label", {"class": "form-label small text-muted mb-1"}, false]}); _output.push("Status"); _output.push("</label>");
|
|
_output.push(" ");_output.push({tag: ["select", {"class": "form-select", "id": "status" + ":" + this._cid, "data-id": "status"}, false]});
|
|
_output.push(" ");_output.push({tag: ["option", {"value": ""}, false]}); _output.push("All"); _output.push("</option>");
|
|
_output.push(" "); _output.push("</select>");
|
|
_output.push("</div>");
|
|
_output.push({tag: ["div", {"class": "col-auto"}, false]});
|
|
_output.push(" ");_output.push({tag: ["label", {"class": "form-label small text-muted mb-1"}, false]}); _output.push("Date Range"); _output.push("</label>");
|
|
_output.push(" ");_output.push({tag: ["select", {"class": "form-select", "id": "date_range" + ":" + this._cid, "data-id": "date_range"}, false]});
|
|
_output.push(" ");_output.push({tag: ["option", {"value": ""}, false]}); _output.push("All Time"); _output.push("</option>");
|
|
_output.push(" ");_output.push({tag: ["option", {"value": "today"}, false]}); _output.push("Today"); _output.push("</option>");
|
|
_output.push(" ");_output.push({tag: ["option", {"value": "week"}, false]}); _output.push("This Week"); _output.push("</option>");
|
|
_output.push(" ");_output.push({tag: ["option", {"value": "month"}, false]}); _output.push("This Month"); _output.push("</option>");
|
|
_output.push(" ");_output.push({tag: ["option", {"value": "custom"}, false]}); _output.push("Custom Range"); _output.push("</option>");
|
|
_output.push(" "); _output.push("</select>");
|
|
_output.push("</div>");
|
|
_output.push({tag: ["div", {"class": "col-auto", "id": "custom_dates" + ":" + this._cid, "data-id": "custom_dates", "style": "display: none;"}, false]});
|
|
_output.push(" "); _output.push({comp: ["Date_Picker", {"id": "start_date" + ":" + this._cid, "data-id": "start_date"}]});
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push({tag: ["div", {"class": "col-auto", "id": "custom_dates_end" + ":" + this._cid, "data-id": "custom_dates_end", "style": "display: none;"}, false]});
|
|
_output.push(" "); _output.push({comp: ["Date_Picker", {"id": "end_date" + ":" + this._cid, "data-id": "end_date"}]});
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push({tag: ["div", {"class": "col-auto ms-auto"}, false]});
|
|
_output.push(" "); _output.push({comp: ["Button_Secondary", {"id": "clear_btn" + ":" + this._cid, "data-id": "clear_btn"}, function(Button_Secondary) { let _output = []; _output.push("Clear Filters"); return [_output, this]; }.bind(this)]});
|
|
_output.push(" "); _output.push({comp: ["Button_Primary", {"id": "apply_btn" + ":" + this._cid, "data-id": "apply_btn", "class": "ms-2"}, function(Button_Primary) { let _output = []; _output.push("Apply"); return [_output, this]; }.bind(this)]});
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push("</div>");
|
|
_output.push({tag: ["div", {"class": "mt-3", "id": "active_filters" + ":" + this._cid, "data-id": "active_filters", "style": "display: none;"}, false]});
|
|
_output.push(" ");_output.push({tag: ["small", {"class": "text-muted me-2"}, false]}); _output.push("Active filters:"); _output.push("</small>");
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "d-inline-block", "id": "filter_tags" + ":" + this._cid, "data-id": "filter_tags"}, false]}); _output.push("</div>");
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push("</div>");
|
|
return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Filter_Bar);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_86bdf5e6b735bb21.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/form_actions_component.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Form_Actions_Component = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Form_Actions_Component',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "mt-3"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" "); if (this.args.cancel_url) {
|
|
_output.push(" ");_output.push({tag: ["a", {"href": (this.args.cancel_url), "class": "btn btn-secondary"}, false]}); (() => { const result = this.args.cancel_text || 'Cancel' ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</a>");
|
|
_output.push(" "); }
|
|
_output.push(" ");_output.push({tag: ["button", {"class": "btn btn-primary", "type": "submit"}, false]}); (() => { const result = this.args.submit_text || 'Save' ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</button>");
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Form_Actions_Component);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_c125b86d10e97419.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/form_field_group.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Form_Field_Group = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Form_Field_Group',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "card mb-3"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "card-header"}, false]});
|
|
_output.push(" ");_output.push({tag: ["h5", {"class": "mb-0"}, false]}); (() => { const result = this.args.title || 'Form Section' ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</h5>");
|
|
_output.push(" "); if (this.args.description) {
|
|
_output.push(" ");_output.push({tag: ["small", {"class": "text-muted"}, false]}); (() => { const result = this.args.description ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</small>");
|
|
_output.push(" "); }
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push({tag: ["div", {"class": "card-body"}, false]});
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); _output.push("</div>");
|
|
return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Form_Field_Group);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_1e85106de52ce305.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/form_group_component.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Form_Group_Component = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Form_Group_Component',
|
|
tag: 'div',
|
|
defaultAttributes: {},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" ");_output.push({tag: ["div", {}, false]});
|
|
_output.push(" "); if (this.args.label) {
|
|
_output.push(" ");_output.push({tag: ["label", {"for": (this.args.id)}, false]}); (() => { const result = this.args.label ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</label>");
|
|
_output.push(" "); }
|
|
_output.push(" "); if (this.args.type === 'select') {
|
|
_output.push(" "); if (this.args.required) {
|
|
_output.push(" ");_output.push({tag: ["select", {"class": "form-select", "id": "[object Object]", "required": "true"}, false]});
|
|
_output.push(" "); if (this.args.placeholder) {
|
|
_output.push(" ");_output.push({tag: ["option", {"value": ""}, false]}); (() => { const result = this.args.placeholder ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</option>");
|
|
_output.push(" "); }
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); _output.push("</select>");
|
|
} else {
|
|
_output.push(" ");_output.push({tag: ["select", {"class": "form-select", "id": "[object Object]"}, false]});
|
|
_output.push(" "); if (this.args.placeholder) {
|
|
_output.push(" ");_output.push({tag: ["option", {"value": ""}, false]}); (() => { const result = this.args.placeholder ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</option>");
|
|
_output.push(" "); }
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); _output.push("</select>");
|
|
}
|
|
_output.push(" "); } else if (this.args.type === 'textarea') {
|
|
_output.push(" "); if (this.args.required) {
|
|
_output.push(" ");_output.push({tag: ["textarea", {"class": "form-control", "id": "[object Object]", "rows": (this.args.rows || 4), "placeholder": (this.args.placeholder || ''), "required": "true"}, false]}); _output.push("</textarea>");
|
|
_output.push(" "); } else {
|
|
_output.push(" ");_output.push({tag: ["textarea", {"class": "form-control", "id": "[object Object]", "rows": (this.args.rows || 4), "placeholder": (this.args.placeholder || '')}, false]}); _output.push("</textarea>");
|
|
_output.push(" "); }
|
|
_output.push(" "); } else {
|
|
_output.push(" "); if (this.args.required) {
|
|
_output.push(" ");_output.push({tag: ["input", {"class": "form-control", "id": "[object Object]", "type": (this.args.type || 'text'), "placeholder": (this.args.placeholder || ''), "required": "true"}, true]}); _output.push("</input>");
|
|
_output.push(" "); } else {
|
|
_output.push(" ");_output.push({tag: ["input", {"class": "form-control", "id": "[object Object]", "type": (this.args.type || 'text'), "placeholder": (this.args.placeholder || '')}, true]}); _output.push("</input>");
|
|
_output.push(" "); }
|
|
_output.push(" "); }
|
|
_output.push(" "); _output.push("</div>");
|
|
return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Form_Group_Component);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_72937efe895dac3c.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/form_row_component.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Form_Row_Component = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Form_Row_Component',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "row"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Form_Row_Component);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_9f9f86aba7786134.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/form_validation_message.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Form_Validation_Message = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Form_Validation_Message',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "invalid-feedback"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Form_Validation_Message);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_2246bd22f8e9add5.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/gantt_chart.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Gantt_Chart = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Gantt_Chart',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "card"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "card-header"}, false]});
|
|
_output.push(" ");_output.push({tag: ["h5", {"class": "mb-0"}, false]}); (() => { const result = this.args.title || 'Project Timeline' ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</h5>");
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push({tag: ["div", {"class": "card-body p-0"}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "table-responsive"}, false]});
|
|
_output.push(" ");_output.push({tag: ["table", {"class": "table table-bordered mb-0", "style": "table-layout: fixed;"}, false]});
|
|
_output.push(" ");_output.push({tag: ["thead", {"class": "table-light"}, false]});
|
|
_output.push(" ");_output.push({tag: ["tr", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["th", {"style": "width: 200px;"}, false]}); _output.push("Task"); _output.push("</th>");
|
|
_output.push(" "); for (let month of this.data.months || []) {
|
|
_output.push(" ");_output.push({tag: ["th", {"class": "text-center small"}, false]}); (() => { const result = month ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</th>");
|
|
_output.push(" "); }
|
|
_output.push(" "); _output.push("</tr>");
|
|
_output.push("</thead>");
|
|
_output.push({tag: ["tbody", {}, false]});
|
|
_output.push(" "); if (Object.keys(this.data).length === 0) {
|
|
_output.push(" ");_output.push({tag: ["tr", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["td", {"colspan": "100", "class": "text-center py-5"}, false]});
|
|
_output.push(" "); _output.push({comp: ["Spinner", {}]});
|
|
_output.push(" "); _output.push("</td>");
|
|
_output.push("</tr>");
|
|
} else {
|
|
_output.push(" "); for (let task of this.data.tasks || []) {
|
|
_output.push(" ");_output.push({tag: ["tr", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["td", {"class": "align-middle"}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "fw-bold"}, false]}); (() => { const result = task.name ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</div>");
|
|
_output.push(" "); if (task.assignee) {
|
|
_output.push(" ");_output.push({tag: ["small", {"class": "text-muted"}, false]}); (() => { const result = task.assignee ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</small>");
|
|
_output.push(" "); }
|
|
_output.push(" "); _output.push("</td>");
|
|
for (let i = 0; i < (this.data.months || []).length; i++) {
|
|
_output.push(" ");_output.push({tag: ["td", {"class": "p-1 align-middle"}, false]});
|
|
_output.push(" "); if (task.start_month <= i && task.end_month >= i) {
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "bg-" + (task.color || 'primary') + "rounded p-2 text-white small text-center"}, false]});
|
|
_output.push(" "); (() => { const result = task.start_month === i ? task.name : '' ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })();
|
|
_output.push(" "); _output.push("</div>");
|
|
}
|
|
_output.push(" "); _output.push("</td>");
|
|
}
|
|
_output.push(" "); _output.push("</tr>");
|
|
}
|
|
_output.push(" "); }
|
|
_output.push(" "); _output.push("</tbody>");
|
|
_output.push("</table>");
|
|
_output.push("</div>");
|
|
_output.push("</div>");
|
|
return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Gantt_Chart);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_bd1cce1a76e13af1.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/icon_button.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Icon_Button = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Icon_Button',
|
|
tag: 'button',
|
|
defaultAttributes: {"class": "btn btn-secondary", "type": "button"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Icon_Button);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_31b59dfa6b448fb1.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/icon_with_label.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Icon_With_Label = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Icon_With_Label',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "d-inline-flex align-items-center gap-2"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" "); _output.push({comp: ["Icon", {"data-name": this.args.icon}]});
|
|
_output.push(" ");_output.push({tag: ["span", {}, false]}); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })(); _output.push("</span>");
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Icon_With_Label);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_0dec1f395fabb9f3.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/icon_with_text.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Icon_With_Text = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Icon_With_Text',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "d-flex align-items-center py-2"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-circle-fill me-2 text-primary", "style": "font-size: 0.5rem;"}, false]}); _output.push("</i>");
|
|
_output.push(" ");_output.push({tag: ["span", {"class": "flex-grow-1"}, false]}); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })(); _output.push("</span>");
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Icon_With_Text);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_cbefc50830c7e1b7.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/icon.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Icon = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Icon',
|
|
tag: 'svg',
|
|
defaultAttributes: {"class": "icon icon-xs", "fill": "currentColor", "viewBox": "0 0 24 24", "xmlns": "http://www.w3.org/2000/svg"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Icon);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_f277ab5240123d0d.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/info_box.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Info_Box = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Info_Box',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "p-3 mb-3 bg-light border-start border-primary border-4"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Info_Box);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_c6771957d17edc03.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/inline_edit_field.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Inline_Edit_Field = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Inline_Edit_Field',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "d-flex align-items-center gap-2"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" ");_output.push({tag: ["div", {"id": "display_mode" + ":" + this._cid, "data-id": "display_mode", "style": "cursor: pointer;"}, false]});
|
|
_output.push(" ");_output.push({tag: ["span", {"id": "value_display" + ":" + this._cid, "data-id": "value_display"}, false]}); (() => { const result = this.args.value || this.args.placeholder || 'Click to edit' ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</span>");
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-pencil text-muted ms-2"}, false]}); _output.push("</i>");
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push({tag: ["div", {"id": "edit_mode" + ":" + this._cid, "data-id": "edit_mode", "style": "display: none;"}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "input-group input-group-sm"}, false]});
|
|
_output.push(" ");_output.push({tag: ["input", {"type": "text", "class": "form-control", "id": "input" + ":" + this._cid, "data-id": "input"}, true]}); _output.push("</input>");
|
|
_output.push(" ");_output.push({tag: ["button", {"class": "btn btn-success", "type": "button", "id": "save_btn" + ":" + this._cid, "data-id": "save_btn", "title": "Save"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-check-lg"}, false]}); _output.push("</i>");
|
|
_output.push(" "); _output.push("</button>");
|
|
_output.push({tag: ["button", {"class": "btn btn-secondary", "type": "button", "id": "cancel_btn" + ":" + this._cid, "data-id": "cancel_btn", "title": "Cancel"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-x-lg"}, false]}); _output.push("</i>");
|
|
_output.push(" "); _output.push("</button>");
|
|
_output.push("</div>");
|
|
_output.push("</div>");
|
|
return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Inline_Edit_Field);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_27017433acf49ce1.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/input_with_icon.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Input_With_Icon = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Input_With_Icon',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "input-group"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" "); if (this.args.icon_position !== 'end') {
|
|
_output.push(" ");_output.push({tag: ["span", {"class": "input-group-text"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-" + (this.args.icon || 'search')}, false]}); _output.push("</i>");
|
|
_output.push(" "); _output.push("</span>");
|
|
}
|
|
_output.push(" ");_output.push({tag: ["input", {"type": (this.args.type || 'text'), "class": "form-control", "placeholder": (this.args.placeholder || ''), "id": "input" + ":" + this._cid, "data-id": "input"}, true]}); _output.push("</input>");
|
|
|
|
|
|
|
|
|
|
|
|
_output.push(" "); if (this.args.icon_position === 'end') {
|
|
_output.push(" ");_output.push({tag: ["span", {"class": "input-group-text"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-" + (this.args.icon || 'search')}, false]}); _output.push("</i>");
|
|
_output.push(" "); _output.push("</span>");
|
|
}
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Input_With_Icon);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_8f20f47d36d9f4f1.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/input_with_validation.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Input_With_Validation = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Input_With_Validation',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "mb-3"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" "); if (this.args.label) {
|
|
_output.push(" ");_output.push({tag: ["label", {"class": "form-label", "id": "label" + ":" + this._cid, "data-id": "label"}, false]});
|
|
_output.push(" "); (() => { const result = this.args.label ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })();
|
|
_output.push(" "); if (this.args.required) {_output.push({tag: ["span", {"class": "text-danger"}, false]}); _output.push("*"); _output.push("</span>"); }
|
|
_output.push(" "); _output.push("</label>");
|
|
}
|
|
_output.push(" ");_output.push({tag: ["input", {"type": (this.args.type || 'text'), "class": "form-control", "placeholder": (this.args.placeholder || ''), "id": "input" + ":" + this._cid, "data-id": "input"}, true]}); _output.push("</input>");
|
|
|
|
|
|
|
|
|
|
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "invalid-feedback", "id": "error" + ":" + this._cid, "data-id": "error"}, false]}); _output.push("</div>");
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "valid-feedback", "id": "success" + ":" + this._cid, "data-id": "success"}, false]}); _output.push("</div>");
|
|
_output.push(" "); if (this.args.help) {
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "form-text"}, false]}); (() => { const result = this.args.help ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</div>");
|
|
_output.push(" "); }
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Input_With_Validation);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_f2c3b3f07b2cfc23.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/input.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Input = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Input',
|
|
tag: 'input',
|
|
defaultAttributes: {"type": "text", "class": "form-control"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Input);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_3cd257bb9dd3ef15.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/kanban_board.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Kanban_Board = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Kanban_Board',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "d-flex gap-3", "style": "overflow-x: auto;"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" "); if (Object.keys(this.data).length === 0) {
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "w-100 text-center py-5"}, false]});
|
|
_output.push(" "); _output.push({comp: ["Spinner", {}]});
|
|
_output.push(" "); _output.push("</div>");
|
|
} else {
|
|
_output.push(" "); for (let column of this.data.columns || []) {
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "card", "style": "min-width: 300px; max-width: 300px;", "data-column-id": (column.id)}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "card-header bg-light"}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "d-flex justify-content-between align-items-center"}, false]});
|
|
_output.push(" ");_output.push({tag: ["h6", {"class": "mb-0"}, false]}); (() => { const result = column.title ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</h6>");
|
|
_output.push(" ");_output.push({tag: ["span", {"class": "badge bg-secondary"}, false]}); (() => { const result = column.cards.length ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</span>");
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push("</div>");
|
|
_output.push({tag: ["div", {"class": "card-body p-2", "style": "min-height: 400px; max-height: 600px; overflow-y: auto;", "data-column-cards": (column.id)}, false]});
|
|
_output.push(" "); for (let card of column.cards) {
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "card mb-2", "draggable": "true", "data-card-id": (card.id)}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "card-body p-3"}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "fw-bold mb-2"}, false]}); (() => { const result = card.title ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</div>");
|
|
_output.push(" "); if (card.description) {
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "text-muted small mb-2"}, false]}); (() => { const result = card.description ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</div>");
|
|
_output.push(" "); }
|
|
_output.push(" "); if (card.tags && card.tags.length > 0) {
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "mb-2"}, false]});
|
|
_output.push(" "); for (let tag of card.tags) {
|
|
_output.push(" ");_output.push({tag: ["span", {"class": "badge bg-light text-dark me-1"}, false]}); (() => { const result = tag ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</span>");
|
|
_output.push(" "); }
|
|
_output.push(" "); _output.push("</div>");
|
|
}
|
|
_output.push(" "); if (card.assignee) {
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "d-flex align-items-center gap-2"}, false]});
|
|
_output.push(" "); _output.push({comp: ["Avatar", {"data-name": card.assignee, "data-size": "xs"}]});
|
|
_output.push(" ");_output.push({tag: ["small", {"class": "text-muted"}, false]}); (() => { const result = card.assignee ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</small>");
|
|
_output.push(" "); _output.push("</div>");
|
|
}
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push("</div>");
|
|
}
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push("</div>");
|
|
}
|
|
_output.push(" "); }
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Kanban_Board);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_66091e157d531d0d.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/link.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Link = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Link',
|
|
tag: 'a',
|
|
defaultAttributes: {"href": "#"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Link);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_5cb3cbf116fa5289.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/list.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_List = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'List',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "list-group list-group-flush"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_List);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_ee1dd5e5562b7d50.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/loading_skeleton.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Loading_Skeleton = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Loading_Skeleton',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "placeholder-glow"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" ");_output.push({tag: ["span", {"class": "placeholder col-12"}, false]}); _output.push("</span>");
|
|
_output.push(" ");_output.push({tag: ["span", {"class": "placeholder col-10"}, false]}); _output.push("</span>");
|
|
_output.push(" ");_output.push({tag: ["span", {"class": "placeholder col-8"}, false]}); _output.push("</span>");
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Loading_Skeleton);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_a0cf37c460ea7ee3.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/metric_card.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Metric_Card = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Metric_Card',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "card h-100"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" ");
|
|
_output.push({tag: ["div", {"class": "card-body p-4"}, false]});
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); _output.push("</div>");
|
|
|
|
return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Metric_Card);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_5300a706b2d27d65.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/mobile_header.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Mobile_Header = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Mobile_Header',
|
|
tag: 'header',
|
|
defaultAttributes: {"class": "navbar navbar-light bg-light d-lg-none"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "container-fluid"}, false]});
|
|
_output.push(" ");_output.push({tag: ["button", {"class": "navbar-toggler", "type": "button", "data-bs-toggle": "offcanvas", "data-bs-target": "#mobileSidebar", "aria-controls": "mobileSidebar"}, false]});
|
|
|
|
|
|
|
|
|
|
_output.push(" ");_output.push({tag: ["span", {"class": "navbar-toggler-icon"}, false]}); _output.push("</span>");
|
|
_output.push(" "); _output.push("</button>");
|
|
_output.push({tag: ["span", {"class": "navbar-brand mb-0 h1"}, false]}); _output.push("PSM"); _output.push("</span>");
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "d-flex align-items-center gap-2"}, false]});
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push("</div>");
|
|
return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Mobile_Header);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_8e635c235d2a1b12.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/modal_dialog.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Modal_Dialog = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Modal_Dialog',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "modal fade", "tabindex": "-1", "aria-hidden": "true"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "modal-dialog"}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "modal-content"}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "modal-header"}, false]});
|
|
_output.push(" ");_output.push({tag: ["h5", {"class": "modal-title", "id": "title" + ":" + this._cid, "data-id": "title"}, false]}); (() => { const result = this.args.title || 'Modal' ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</h5>");
|
|
_output.push(" ");_output.push({tag: ["button", {"type": "button", "class": "btn-close", "data-bs-dismiss": "modal", "aria-label": "Close"}, false]}); _output.push("</button>");
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push({tag: ["div", {"class": "modal-body", "id": "body" + ":" + this._cid, "data-id": "body"}, false]});
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push({tag: ["div", {"class": "modal-footer", "id": "footer" + ":" + this._cid, "data-id": "footer"}, false]});
|
|
_output.push(" "); _output.push({comp: ["Button_Secondary", {"data-bs-dismiss": "modal"}, function(Button_Secondary) { let _output = []; _output.push("Close"); return [_output, this]; }.bind(this)]});
|
|
_output.push(" "); _output.push({comp: ["Button_Primary", {"id": "confirm" + ":" + this._cid, "data-id": "confirm"}, function(Button_Primary) { let _output = []; _output.push("Confirm"); return [_output, this]; }.bind(this)]});
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push("</div>");
|
|
_output.push("</div>");
|
|
return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Modal_Dialog);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_7095e51c2533c441.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/multi_select.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Multi_Select = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Multi_Select',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "dropdown"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" "); if (this.args.label) {
|
|
_output.push(" ");_output.push({tag: ["label", {"class": "form-label"}, false]}); (() => { const result = this.args.label ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</label>");
|
|
_output.push(" "); }
|
|
_output.push(" ");_output.push({tag: ["button", {"class": "btn btn-secondary dropdown-toggle w-100 text-start", "type": "button", "data-bs-toggle": "dropdown", "aria-expanded": "false", "id": "button" + ":" + this._cid, "data-id": "button"}, false]});
|
|
_output.push(" ");_output.push({tag: ["span", {"id": "selected_text" + ":" + this._cid, "data-id": "selected_text"}, false]}); (() => { const result = this.args.placeholder || 'Select options' ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</span>");
|
|
_output.push(" "); _output.push("</button>");
|
|
_output.push({tag: ["div", {"class": "dropdown-menu w-100", "id": "menu" + ":" + this._cid, "data-id": "menu"}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "px-3 py-2"}, false]});
|
|
_output.push(" ");_output.push({tag: ["input", {"type": "search", "class": "form-control form-control-sm", "placeholder": "Search...", "id": "search" + ":" + this._cid, "data-id": "search"}, true]}); _output.push("</input>");
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push({tag: ["div", {"class": "dropdown-divider"}, false]}); _output.push("</div>");
|
|
_output.push(" ");_output.push({tag: ["div", {"id": "options" + ":" + this._cid, "data-id": "options", "style": "max-height: 250px; overflow-y: auto;"}, false]});
|
|
_output.push(" "); _output.push("<!-- Options populated via JavaScript -->");
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push({tag: ["div", {"class": "dropdown-divider"}, false]}); _output.push("</div>");
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "px-3 py-2 d-flex justify-content-between"}, false]});
|
|
_output.push(" ");_output.push({tag: ["button", {"type": "button", "class": "btn btn-link btn-sm p-0", "id": "clear_all" + ":" + this._cid, "data-id": "clear_all"}, false]}); _output.push("Clear All"); _output.push("</button>");
|
|
_output.push(" ");_output.push({tag: ["button", {"type": "button", "class": "btn btn-link btn-sm p-0", "id": "select_all" + ":" + this._cid, "data-id": "select_all"}, false]}); _output.push("Select All"); _output.push("</button>");
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push("</div>");
|
|
return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Multi_Select);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_b3fc253174c86570.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/notification_badge.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Notification_Badge = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Notification_Badge',
|
|
tag: 'span',
|
|
defaultAttributes: {"class": "position-relative"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" ");_output.push({tag: ["span", {"class": "position-absolute top-0 start-100 translate-middle badge rounded-pill bg-danger", "id": "count" + ":" + this._cid, "data-id": "count", "style": ((this.args.count > 0 ? '' : 'display: none;'))}, false]});
|
|
|
|
|
|
_output.push(" "); (() => { const result = this.args.count || 0 ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })();
|
|
_output.push(" "); _output.push("</span>");
|
|
return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Notification_Badge);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_5f169cc80d559d94.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/notification_dropdown.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Notification_Dropdown = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Notification_Dropdown',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "dropdown"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" ");_output.push({tag: ["button", {"class": "btn btn-link position-relative", "type": "button", "data-bs-toggle": "dropdown", "aria-expanded": "false"}, false]});
|
|
|
|
|
|
|
|
_output.push(" "); _output.push({comp: ["Icon", {"data-name": "bell"}]});
|
|
_output.push(" "); if (this.args.unread_count > 0) {
|
|
_output.push(" ");_output.push({tag: ["span", {"class": "position-absolute top-0 start-100 translate-middle badge rounded-pill bg-danger"}, false]});
|
|
_output.push(" "); (() => { const result = this.args.unread_count ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })();
|
|
_output.push(" "); _output.push("</span>");
|
|
}
|
|
_output.push(" "); _output.push("</button>");
|
|
_output.push({tag: ["div", {"class": "dropdown-menu dropdown-menu-end", "style": "width: 320px;"}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "dropdown-header d-flex justify-content-between align-items-center"}, false]});
|
|
_output.push(" ");_output.push({tag: ["span", {"class": "fw-bold"}, false]}); _output.push("Notifications"); _output.push("</span>");
|
|
_output.push(" ");_output.push({tag: ["a", {"href": "#", "class": "small"}, false]}); _output.push("Mark all read"); _output.push("</a>");
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push({tag: ["div", {"class": "dropdown-divider"}, false]}); _output.push("</div>");
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "overflow-auto", "style": "max-height: 400px;"}, false]});
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push("</div>");
|
|
return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Notification_Dropdown);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_fca9bd701278cdf2.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/overdue_indicator.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Overdue_Indicator = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Overdue_Indicator',
|
|
tag: 'span',
|
|
defaultAttributes: {"class": "badge bg-warning text-dark d-block mt-1"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Overdue_Indicator);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_98f2e35a4e8f98a6.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/page_header_left.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Page_Header_Left = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Page_Header_Left',
|
|
tag: 'div',
|
|
defaultAttributes: {},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" ");_output.push({tag: ["div", {}, false]});
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); _output.push("</div>");
|
|
return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Page_Header_Left);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_3f3348e80138bd83.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/page_header_right.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Page_Header_Right = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Page_Header_Right',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "d-flex gap-2"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Page_Header_Right);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_0a3eab3f332207ff.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/page_header.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Page_Header = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Page_Header',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "d-flex justify-content-between align-items-center mb-4"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Page_Header);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_2b286f1f39207482.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/page_section.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Page_Section = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Page_Section',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "mb-4"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Page_Section);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_d6cf7c9e16e8f541.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/page_subtitle.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Page_Subtitle = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Page_Subtitle',
|
|
tag: 'p',
|
|
defaultAttributes: {"class": "text-muted mb-0"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Page_Subtitle);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_0ab20aacac832674.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/page_title.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Page_Title = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Page_Title',
|
|
tag: 'h1',
|
|
defaultAttributes: {"class": "h2 mb-1"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Page_Title);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_fcfe2eadb09b8b45.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/page.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Page = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Page',
|
|
tag: 'div',
|
|
defaultAttributes: {},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Page);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_31fd149cfb317d39.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/pagination_controls.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Pagination_Controls = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Pagination_Controls',
|
|
tag: 'nav',
|
|
defaultAttributes: {"aria-label": "Table pagination"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" ");_output.push({tag: ["ul", {"class": "pagination pagination-sm mb-0"}, false]});
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); _output.push("</ul>");
|
|
return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Pagination_Controls);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_e6ee289a952c7453.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/pagination_info.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Pagination_Info = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Pagination_Info',
|
|
tag: 'div',
|
|
defaultAttributes: {},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" ");_output.push({tag: ["div", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["small", {"class": "text-muted"}, false]}); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })(); _output.push("</small>");
|
|
_output.push(" "); _output.push("</div>");
|
|
return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Pagination_Info);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_75460b9999183e3a.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/popover.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Popover = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Popover',
|
|
tag: 'button',
|
|
defaultAttributes: {"type": "button", "class": "btn btn-secondary", "data-bs-toggle": "popover"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" "); (() => { const result = this.args.label || 'Info' ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })();
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Popover);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_c31885d0846c31e6.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/progress_bar.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Progress_Bar = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Progress_Bar',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "progress"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "progress-bar", "role": "progressbar", "style": "width:" + (this.args.value || 0) + "%", "aria-valuenow": (this.args.value || 0), "aria-valuemin": "0", "aria-valuemax": "100", "id": "bar" + ":" + this._cid, "data-id": "bar"}, false]});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_output.push(" "); _output.push("</div>");
|
|
return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Progress_Bar);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_090d679f00c495b6.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/radio_button.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Radio_Button = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Radio_Button',
|
|
tag: 'input',
|
|
defaultAttributes: {"type": "radio", "class": "form-check-input"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Radio_Button);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_b0b4f93e436d5119.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/record_count_display.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Record_Count_Display = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Record_Count_Display',
|
|
tag: 'small',
|
|
defaultAttributes: {"class": "text-muted"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Record_Count_Display);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_c55ba0e3e36e44d5.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/rich_text_editor.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Rich_Text_Editor = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Rich_Text_Editor',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "mb-3"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" "); if (this.args.label) {
|
|
_output.push(" ");_output.push({tag: ["label", {"class": "form-label"}, false]}); (() => { const result = this.args.label ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</label>");
|
|
_output.push(" "); }
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "border rounded"}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "border-bottom bg-light p-2", "id": "toolbar" + ":" + this._cid, "data-id": "toolbar"}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "btn-group btn-group-sm me-2", "role": "group"}, false]});
|
|
_output.push(" ");_output.push({tag: ["button", {"type": "button", "class": "btn btn-secondary", "data-command": "bold", "title": "Bold"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-type-bold"}, false]}); _output.push("</i>");
|
|
_output.push(" "); _output.push("</button>");
|
|
_output.push({tag: ["button", {"type": "button", "class": "btn btn-secondary", "data-command": "italic", "title": "Italic"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-type-italic"}, false]}); _output.push("</i>");
|
|
_output.push(" "); _output.push("</button>");
|
|
_output.push({tag: ["button", {"type": "button", "class": "btn btn-secondary", "data-command": "underline", "title": "Underline"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-type-underline"}, false]}); _output.push("</i>");
|
|
_output.push(" "); _output.push("</button>");
|
|
_output.push("</div>");
|
|
_output.push({tag: ["div", {"class": "btn-group btn-group-sm me-2", "role": "group"}, false]});
|
|
_output.push(" ");_output.push({tag: ["button", {"type": "button", "class": "btn btn-secondary", "data-command": "insertUnorderedList", "title": "Bullet List"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-list-ul"}, false]}); _output.push("</i>");
|
|
_output.push(" "); _output.push("</button>");
|
|
_output.push({tag: ["button", {"type": "button", "class": "btn btn-secondary", "data-command": "insertOrderedList", "title": "Numbered List"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-list-ol"}, false]}); _output.push("</i>");
|
|
_output.push(" "); _output.push("</button>");
|
|
_output.push("</div>");
|
|
_output.push({tag: ["div", {"class": "btn-group btn-group-sm me-2", "role": "group"}, false]});
|
|
_output.push(" ");_output.push({tag: ["button", {"type": "button", "class": "btn btn-secondary", "data-command": "justifyLeft", "title": "Align Left"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-text-left"}, false]}); _output.push("</i>");
|
|
_output.push(" "); _output.push("</button>");
|
|
_output.push({tag: ["button", {"type": "button", "class": "btn btn-secondary", "data-command": "justifyCenter", "title": "Align Center"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-text-center"}, false]}); _output.push("</i>");
|
|
_output.push(" "); _output.push("</button>");
|
|
_output.push({tag: ["button", {"type": "button", "class": "btn btn-secondary", "data-command": "justifyRight", "title": "Align Right"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-text-right"}, false]}); _output.push("</i>");
|
|
_output.push(" "); _output.push("</button>");
|
|
_output.push("</div>");
|
|
_output.push({tag: ["div", {"class": "btn-group btn-group-sm", "role": "group"}, false]});
|
|
_output.push(" ");_output.push({tag: ["button", {"type": "button", "class": "btn btn-secondary", "data-command": "createLink", "title": "Insert Link"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-link"}, false]}); _output.push("</i>");
|
|
_output.push(" "); _output.push("</button>");
|
|
_output.push({tag: ["button", {"type": "button", "class": "btn btn-secondary", "data-command": "unlink", "title": "Remove Link"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-link-45deg"}, false]}); _output.push("</i>");
|
|
_output.push(" "); _output.push("</button>");
|
|
_output.push("</div>");
|
|
_output.push("</div>");
|
|
_output.push({tag: ["div", {"contenteditable": "true", "class": "p-3", "style": "min-height: 200px; max-height: 400px; overflow-y: auto;", "id": "editor" + ":" + this._cid, "data-id": "editor"}, false]});
|
|
|
|
|
|
|
|
|
|
(() => { const result = this.args.value || '' ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</div>");
|
|
_output.push(" "); _output.push("</div>");
|
|
if (this.args.help) {
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "form-text"}, false]}); (() => { const result = this.args.help ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</div>");
|
|
_output.push(" "); }
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Rich_Text_Editor);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_15b2ff9a7d6c41ca.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/row_action_menu.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Row_Action_Menu = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Row_Action_Menu',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "dropdown"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" ");_output.push({tag: ["button", {"class": "btn btn-sm btn-link text-muted dropdown-toggle", "type": "button", "data-bs-toggle": "dropdown", "aria-expanded": "false"}, false]});
|
|
|
|
|
|
|
|
_output.push(" "); _output.push(" ⋮ "); _output.push("</button>");
|
|
|
|
_output.push(" ");_output.push({tag: ["ul", {"class": "dropdown-menu dropdown-menu-end", "id": "menu" + ":" + this._cid, "data-id": "menu"}, false]});
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); _output.push("</ul>");
|
|
return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Row_Action_Menu);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_f1b2503da86c7b29.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/Sample_Datagrid_Component.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Sample_Datagrid_Component = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Sample_Datagrid_Component',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "card"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_output.push(" ");
|
|
_output.push({tag: ["div", {"class": "card-header bg-light"}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "d-flex justify-content-between align-items-center"}, false]});
|
|
_output.push(" ");_output.push({tag: ["h5", {"class": "mb-0"}, false]}); (() => { const result = this.args.title || 'Data Table' ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</h5>");
|
|
_output.push(" ");_output.push({tag: ["small", {"class": "text-muted"}, false]});
|
|
_output.push(" "); _output.push(" Showing "); (() => { const result = this.args.showing || 10 ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push(" of "); (() => { const result = this.args.total || 100 ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push(" "); (() => { const result = this.args.entity_name || 'items' ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })();
|
|
_output.push(" "); _output.push("</small>");
|
|
_output.push("</div>");
|
|
_output.push("</div>");
|
|
|
|
|
|
_output.push({tag: ["div", {"class": "card-body p-0"}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "table-responsive"}, false]});
|
|
_output.push(" ");_output.push({tag: ["table", {"class": "table table-hover mb-0"}, false]});
|
|
_output.push(" ");
|
|
_output.push({tag: ["thead", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["tr", {}, false]});
|
|
_output.push(" "); if (this.args.selectable) {
|
|
_output.push(" ");_output.push({tag: ["th", {"style": "width: 40px;"}, false]});
|
|
_output.push(" ");_output.push({tag: ["input", {"type": "checkbox", "class": "form-check-input", "id": "select_all" + ":" + this._cid, "data-id": "select_all"}, true]}); _output.push("</input>");
|
|
_output.push(" "); _output.push("</th>");
|
|
}
|
|
_output.push(" ");
|
|
|
|
if (this.args.columns && this.args.columns.length > 0) {
|
|
_output.push(" "); for (let column of this.args.columns) {
|
|
_output.push(" ");_output.push({tag: ["th", {"style": ((column.width ? 'width: '+column.width : ''))}, false]});
|
|
_output.push(" "); (() => { const result = column.label ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })();
|
|
_output.push(" "); _output.push("</th>");
|
|
}
|
|
_output.push(" "); } else {
|
|
_output.push(" ");
|
|
_output.push({tag: ["th", {}, false]}); _output.push("ID"); _output.push("</th>");
|
|
_output.push(" ");_output.push({tag: ["th", {}, false]}); _output.push("Name"); _output.push("</th>");
|
|
_output.push(" ");_output.push({tag: ["th", {}, false]}); _output.push("Company"); _output.push("</th>");
|
|
_output.push(" ");_output.push({tag: ["th", {}, false]}); _output.push("Email"); _output.push("</th>");
|
|
_output.push(" ");_output.push({tag: ["th", {}, false]}); _output.push("Phone"); _output.push("</th>");
|
|
_output.push(" ");_output.push({tag: ["th", {}, false]}); _output.push("Status"); _output.push("</th>");
|
|
_output.push(" ");_output.push({tag: ["th", {}, false]}); _output.push("Created"); _output.push("</th>");
|
|
_output.push(" ");_output.push({tag: ["th", {"style": "width: 100px;"}, false]}); _output.push("Actions"); _output.push("</th>");
|
|
_output.push(" "); }
|
|
_output.push(" "); _output.push("</tr>");
|
|
_output.push("</thead>");
|
|
|
|
|
|
_output.push({tag: ["tbody", {}, false]});
|
|
_output.push(" ");
|
|
if (Object.keys(this.data).length === 0) {
|
|
_output.push(" ");
|
|
for (let i = 0; i < (this.args.placeholder_rows || 10); i++) {
|
|
_output.push(" ");_output.push({tag: ["tr", {}, false]});
|
|
_output.push(" "); if (this.args.selectable) {
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});_output.push({tag: ["input", {"type": "checkbox", "class": "form-check-input", "disabled": "true"}, true]}); _output.push("</input>"); _output.push("</td>");
|
|
_output.push(" "); }
|
|
_output.push(" "); for (let j = 0; j < (this.args.columns ? this.args.columns.length : 8); j++) {
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "placeholder-glow"}, false]});
|
|
_output.push(" ");_output.push({tag: ["span", {"class": "placeholder col-" + (Math.floor(Math.random() * 8) + 4)}, false]}); _output.push("</span>");
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push("</td>");
|
|
}
|
|
_output.push(" "); _output.push("</tr>");
|
|
}
|
|
_output.push(" "); } else if (this.data.rows && this.data.rows.length > 0) {
|
|
_output.push(" ");
|
|
for (let row of this.data.rows) {
|
|
_output.push(" ");_output.push({tag: ["tr", {}, false]});
|
|
_output.push(" "); if (this.args.selectable) {
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});_output.push({tag: ["input", {"type": "checkbox", "class": "form-check-input", "id": row.id + ":" + this._cid, "data-id": row.id}, true]}); _output.push("</input>"); _output.push("</td>");
|
|
_output.push(" "); }
|
|
_output.push(" ");
|
|
|
|
if (this.args.columns) {
|
|
_output.push(" "); for (let column of this.args.columns) {
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});
|
|
_output.push(" "); if (column.type === 'badge') {
|
|
_output.push(" ");
|
|
_output.push({tag: ["span", {"class": "badge bg-" + (row[column.field + '_color'] || 'secondary')}, false]});
|
|
_output.push(" "); (() => { const result = row[column.field] ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })();
|
|
_output.push(" "); _output.push("</span>");
|
|
} else if (column.type === 'actions') {
|
|
_output.push(" ");
|
|
_output.push({tag: ["div", {"class": "btn-group btn-group-sm"}, false]});
|
|
_output.push(" "); if (this.args.view_url) {
|
|
_output.push(" ");_output.push({tag: ["a", {"href": (this.args.view_url.replace('{id}', row.id)), "class": "btn btn-primary", "title": "View"}, false]});
|
|
|
|
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-eye"}, false]}); _output.push("</i>");
|
|
_output.push(" "); _output.push("</a>");
|
|
}
|
|
_output.push(" "); if (this.args.edit_url) {
|
|
_output.push(" ");_output.push({tag: ["a", {"href": (this.args.edit_url.replace('{id}', row.id)), "class": "btn btn-secondary", "title": "Edit"}, false]});
|
|
|
|
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-pencil"}, false]}); _output.push("</i>");
|
|
_output.push(" "); _output.push("</a>");
|
|
}
|
|
_output.push(" "); if (this.args.allow_delete) {
|
|
_output.push(" ");_output.push({tag: ["button", {"class": "btn btn-danger", "id": "delete_button" + ":" + this._cid, "data-id": "delete_button", "title": "Delete"}, false]});
|
|
|
|
|
|
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-trash"}, false]}); _output.push("</i>");
|
|
_output.push(" "); _output.push("</button>");
|
|
}
|
|
_output.push(" "); _output.push("</div>");
|
|
} else {
|
|
_output.push(" ");
|
|
(() => { const result = row[column.field] ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })();
|
|
_output.push(" "); }
|
|
_output.push(" "); _output.push("</td>");
|
|
}
|
|
_output.push(" "); } else {
|
|
_output.push(" ");
|
|
_output.push({tag: ["td", {}, false]}); (() => { const result = row.id ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); (() => { const result = row.name ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); (() => { const result = row.company ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); (() => { const result = row.email ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); (() => { const result = row.phone ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["span", {"class": "badge bg-" + (row.status_color || 'success')}, false]});
|
|
_output.push(" "); (() => { const result = row.status ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })();
|
|
_output.push(" "); _output.push("</span>");
|
|
_output.push("</td>");
|
|
_output.push({tag: ["td", {}, false]}); (() => { const result = row.created ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "btn-group btn-group-sm"}, false]});
|
|
_output.push(" ");_output.push({tag: ["button", {"class": "btn btn-primary", "title": "View"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-eye"}, false]}); _output.push("</i>");
|
|
_output.push(" "); _output.push("</button>");
|
|
_output.push({tag: ["button", {"class": "btn btn-secondary", "title": "Edit"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-pencil"}, false]}); _output.push("</i>");
|
|
_output.push(" "); _output.push("</button>");
|
|
_output.push({tag: ["button", {"class": "btn btn-danger", "title": "Delete"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-trash"}, false]}); _output.push("</i>");
|
|
_output.push(" "); _output.push("</button>");
|
|
_output.push("</div>");
|
|
_output.push("</td>");
|
|
}
|
|
_output.push(" "); _output.push("</tr>");
|
|
}
|
|
_output.push(" "); } else {
|
|
_output.push(" ");
|
|
_output.push({tag: ["tr", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["td", {"colspan": ((this.args.selectable ? 1 : 0) + (this.args.columns ? this.args.columns.length : 8)), "class": "text-center text-muted py-5"}, false]});
|
|
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-inbox fs-1 d-block mb-2"}, false]}); _output.push("</i>");
|
|
_output.push(" "); _output.push(" No "); (() => { const result = this.args.entity_name || 'items' ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push(" found "); _output.push("</td>");
|
|
|
|
_output.push(" "); _output.push("</tr>");
|
|
}
|
|
_output.push(" "); _output.push("</tbody>");
|
|
_output.push("</table>");
|
|
_output.push("</div>");
|
|
_output.push("</div>");
|
|
|
|
|
|
if (this.args.pagination !== false && Object.keys(this.data).length > 0) {
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "card-footer bg-light"}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "d-flex justify-content-between align-items-center"}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["small", {"class": "text-muted"}, false]});
|
|
_output.push(" "); _output.push(" Showing "); (() => { const result = this.data.pagination?.from || 1 ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push(" to "); (() => { const result = this.data.pagination?.to || 10 ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })();
|
|
_output.push(" "); _output.push(" of "); (() => { const result = this.data.pagination?.total || 100 ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push(" entries "); _output.push("</small>");
|
|
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push({tag: ["nav", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["ul", {"class": "pagination pagination-sm mb-0"}, false]});
|
|
_output.push(" ");
|
|
_output.push({tag: ["li", {"class": "page-item" + (this.data.pagination?.current_page === 1 ? 'disabled' : '')}, false]});
|
|
_output.push(" ");_output.push({tag: ["a", {"class": "page-link", "href": "#", "tabindex": "-1", "id": "prev_page" + ":" + this._cid, "data-id": "prev_page"}, false]}); _output.push("Previous"); _output.push("</a>");
|
|
_output.push(" "); _output.push("</li>");
|
|
|
|
|
|
if (this.data.pagination?.pages) {
|
|
_output.push(" "); for (let page of this.data.pagination.pages) {
|
|
_output.push(" "); if (page === '...') {
|
|
_output.push(" ");_output.push({tag: ["li", {"class": "page-item disabled"}, false]});_output.push({tag: ["a", {"class": "page-link", "href": "#"}, false]}); _output.push("..."); _output.push("</a>"); _output.push("</li>");
|
|
_output.push(" "); } else {
|
|
_output.push(" ");_output.push({tag: ["li", {"class": "page-item" + (page === this.data.pagination.current_page ? 'active' : '')}, false]});
|
|
_output.push(" ");_output.push({tag: ["a", {"class": "page-link", "href": "#", "data-page": (page)}, false]}); (() => { const result = page ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</a>");
|
|
_output.push(" "); _output.push("</li>");
|
|
}
|
|
_output.push(" "); }
|
|
_output.push(" "); } else {
|
|
_output.push(" ");
|
|
for (let i = 1; i <= 5; i++) {
|
|
_output.push(" ");_output.push({tag: ["li", {"class": "page-item" + (i === 1 ? 'active' : '')}, false]});
|
|
_output.push(" ");_output.push({tag: ["a", {"class": "page-link", "href": "#", "data-page": (i)}, false]}); (() => { const result = i ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</a>");
|
|
_output.push(" "); _output.push("</li>");
|
|
}
|
|
_output.push(" "); }
|
|
_output.push(" ");
|
|
|
|
_output.push({tag: ["li", {"class": "page-item" + (this.data.pagination?.current_page === this.data.pagination?.total_pages ? 'disabled' : '')}, false]});
|
|
_output.push(" ");_output.push({tag: ["a", {"class": "page-link", "href": "#", "id": "next_page" + ":" + this._cid, "data-id": "next_page"}, false]}); _output.push("Next"); _output.push("</a>");
|
|
_output.push(" "); _output.push("</li>");
|
|
_output.push("</ul>");
|
|
_output.push("</nav>");
|
|
_output.push("</div>");
|
|
_output.push("</div>");
|
|
}
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Sample_Datagrid_Component);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_9a27aa4290bb1e22.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/search_bar.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Search_Bar = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Search_Bar',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "input-group"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" ");_output.push({tag: ["span", {"class": "input-group-text"}, false]});
|
|
_output.push(" "); _output.push({comp: ["Icon", {"data-name": "search"}]});
|
|
_output.push(" "); _output.push("</span>");
|
|
_output.push({tag: ["input", {"type": "search", "class": "form-control", "placeholder": (this.args.placeholder || 'Search...'), "id": "input" + ":" + this._cid, "data-id": "input"}, true]}); _output.push("</input>");
|
|
|
|
|
|
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Search_Bar);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_82fa1779b5d52f06.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/search_button.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Search_Button = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Search_Button',
|
|
tag: 'button',
|
|
defaultAttributes: {"type": "button", "class": "btn btn-secondary"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-search"}, false]}); _output.push("</i>");
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Search_Button);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_90ce087c10b29f3c.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/search_input.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Search_Input = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Search_Input',
|
|
tag: 'input',
|
|
defaultAttributes: {"type": "search", "class": "form-control", "placeholder": "Search contacts...", "style": "width: 250px;"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Search_Input);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_87133ebd4afe5e36.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/searchable_select.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Searchable_Select = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Searchable_Select',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "dropdown"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" "); if (this.args.label) {
|
|
_output.push(" ");_output.push({tag: ["label", {"class": "form-label"}, false]}); (() => { const result = this.args.label ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</label>");
|
|
_output.push(" "); }
|
|
_output.push(" ");_output.push({tag: ["button", {"class": "btn btn-secondary dropdown-toggle w-100 text-start", "type": "button", "data-bs-toggle": "dropdown", "aria-expanded": "false", "id": "button" + ":" + this._cid, "data-id": "button"}, false]});
|
|
_output.push(" ");_output.push({tag: ["span", {"id": "selected_text" + ":" + this._cid, "data-id": "selected_text"}, false]}); (() => { const result = this.args.placeholder || 'Select an option' ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</span>");
|
|
_output.push(" "); _output.push("</button>");
|
|
_output.push({tag: ["div", {"class": "dropdown-menu w-100", "id": "menu" + ":" + this._cid, "data-id": "menu"}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "px-3 py-2"}, false]});
|
|
_output.push(" ");_output.push({tag: ["input", {"type": "search", "class": "form-control form-control-sm", "placeholder": "Search...", "id": "search" + ":" + this._cid, "data-id": "search"}, true]}); _output.push("</input>");
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push({tag: ["div", {"class": "dropdown-divider"}, false]}); _output.push("</div>");
|
|
_output.push(" ");_output.push({tag: ["div", {"id": "options" + ":" + this._cid, "data-id": "options", "style": "max-height: 250px; overflow-y: auto;"}, false]});
|
|
_output.push(" "); _output.push("<!-- Options populated via JavaScript -->");
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push("</div>");
|
|
return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Searchable_Select);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_aacf254b7210322b.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/select_dropdown.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Select_Dropdown = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Select_Dropdown',
|
|
tag: 'select',
|
|
defaultAttributes: {"class": "form-select"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Select_Dropdown);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_146e3e3c9db514f9.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/sidebar_nav.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Sidebar_Nav = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Sidebar_Nav',
|
|
tag: 'nav',
|
|
defaultAttributes: {"class": "d-flex flex-column p-3 bg-light", "style": "width: 250px; min-height: 100vh;"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" ");_output.push({tag: ["a", {"href": "/", "class": "d-flex align-items-center mb-3 text-decoration-none"}, false]});
|
|
_output.push(" ");_output.push({tag: ["span", {"class": "fs-4 fw-bold"}, false]}); _output.push("PSM"); _output.push("</span>");
|
|
_output.push(" "); _output.push("</a>");
|
|
_output.push({tag: ["hr", {}, true]}); _output.push("</hr>");
|
|
_output.push(" ");_output.push({tag: ["ul", {"class": "nav nav-pills flex-column mb-auto", "id": "nav_items" + ":" + this._cid, "data-id": "nav_items"}, false]});
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); _output.push("</ul>");
|
|
return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Sidebar_Nav);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_dc81d680341fe1d9.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/simple_table_test.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Simple_Table_Test = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Simple_Table_Test',
|
|
tag: 'div',
|
|
defaultAttributes: {},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" ");_output.push({tag: ["table", {"class": "table"}, false]});
|
|
_output.push(" ");_output.push({tag: ["tr", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("Test"); _output.push("</td>");
|
|
_output.push(" "); _output.push("</tr>");
|
|
_output.push("</table>");
|
|
return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Simple_Table_Test);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_875974d23c25e5e2.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/sortable_column_header.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Sortable_Column_Header = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Sortable_Column_Header',
|
|
tag: 'th',
|
|
defaultAttributes: {"class": "user-select-none", "style": "cursor: pointer;"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "d-flex align-items-center justify-content-between"}, false]});
|
|
_output.push(" ");_output.push({tag: ["span", {}, false]}); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })(); _output.push("</span>");
|
|
_output.push(" ");_output.push({tag: ["span", {"class": "ms-2", "id": "sort_icon" + ":" + this._cid, "data-id": "sort_icon"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "text-muted"}, false]}); _output.push("⇅"); _output.push("</i>");
|
|
_output.push(" "); _output.push("</span>");
|
|
_output.push("</div>");
|
|
return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Sortable_Column_Header);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_5724e547fb5ecdca.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/spinner.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Spinner = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Spinner',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "spinner-border", "role": "status"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" ");_output.push({tag: ["span", {"class": "visually-hidden"}, false]}); _output.push("Loading..."); _output.push("</span>");
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Spinner);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_d7e6ffd2a74afdea.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/stat_card.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Stat_Card = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Stat_Card',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "card text-center border-0 shadow-sm"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "card-body"}, false]});
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); _output.push("</div>");
|
|
return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Stat_Card);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_5c147c4272fcbdfc.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/status_badge.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Status_Badge = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Status_Badge',
|
|
tag: 'span',
|
|
defaultAttributes: {"class": "badge"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Status_Badge);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_8d3bc06fac256488.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/tab_content.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Tab_Content = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Tab_Content',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "tab-content mt-3"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Tab_Content);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_f657f12a0aa25bb7.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/table_body.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Table_Body = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Table_Body',
|
|
tag: 'tbody',
|
|
defaultAttributes: {},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Table_Body);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_f586647b2517ead3.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/table_headers.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Table_Headers = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Table_Headers',
|
|
tag: 'thead',
|
|
defaultAttributes: {},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" ");_output.push({tag: ["tr", {}, false]});
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); _output.push("</tr>");
|
|
return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Table_Headers);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_18d1bbdb5a50465a.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/table_pagination.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Table_Pagination = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Table_Pagination',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "d-flex justify-content-between align-items-center mt-3"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "text-muted small", "id": "info" + ":" + this._cid, "data-id": "info"}, false]});
|
|
_output.push(" "); _output.push(" Showing "); (() => { const result = this.args.start || 1 ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push(" to "); (() => { const result = this.args.end || 10 ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push(" of "); (() => { const result = this.args.total || 0 ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push(" entries "); _output.push("</div>");
|
|
|
|
_output.push(" ");_output.push({tag: ["nav", {"aria-label": "Table pagination"}, false]});
|
|
_output.push(" ");_output.push({tag: ["ul", {"class": "pagination mb-0", "id": "pagination" + ":" + this._cid, "data-id": "pagination"}, false]});
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); _output.push("</ul>");
|
|
_output.push("</nav>");
|
|
return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Table_Pagination);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_383242ee22658bf0.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/table.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Table = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Table',
|
|
tag: 'table',
|
|
defaultAttributes: {"class": "table table-hover"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Table);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_ed2ddbf29c859aa9.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/tabs.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Tabs = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Tabs',
|
|
tag: 'ul',
|
|
defaultAttributes: {"class": "nav nav-tabs"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Tabs);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_4150fd75011321be.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/tag_group.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Tag_Group = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Tag_Group',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "d-flex flex-wrap gap-1"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Tag_Group);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_a5dbed84a331830f.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/tag.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Tag = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Tag',
|
|
tag: 'span',
|
|
defaultAttributes: {"class": "badge rounded-pill bg-secondary me-1"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Tag);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_58a09a623e844c61.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/text_display.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Text_Display = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Text_Display',
|
|
tag: 'span',
|
|
defaultAttributes: {},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Text_Display);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_4ca4caa4aa2ac28a.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/textarea.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Textarea = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Textarea',
|
|
tag: 'textarea',
|
|
defaultAttributes: {"class": "form-control", "rows": "4"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Textarea);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_cfb5cfb28a80dd74.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/three_column_layout.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Three_Column_Layout = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Three_Column_Layout',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "row"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Three_Column_Layout);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_aa4c1ba17a301e31.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/time_picker.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Time_Picker = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Time_Picker',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "mb-3"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" "); if (this.args.label) {
|
|
_output.push(" ");_output.push({tag: ["label", {"class": "form-label"}, false]}); (() => { const result = this.args.label ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</label>");
|
|
_output.push(" "); }
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "input-group"}, false]});
|
|
_output.push(" ");_output.push({tag: ["span", {"class": "input-group-text"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-clock"}, false]}); _output.push("</i>");
|
|
_output.push(" "); _output.push("</span>");
|
|
_output.push({tag: ["input", {"type": "time", "class": "form-control", "placeholder": (this.args.placeholder || ''), "id": "input" + ":" + this._cid, "data-id": "input"}, true]}); _output.push("</input>");
|
|
|
|
|
|
|
|
|
|
|
|
_output.push(" "); _output.push("</div>");
|
|
if (this.args.help) {
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "form-text"}, false]}); (() => { const result = this.args.help ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</div>");
|
|
_output.push(" "); }
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Time_Picker);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_2031023f9f1c01f1.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/timeline.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Timeline = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Timeline',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "d-flex flex-column gap-3"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Timeline);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_12433da901e62b43.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/timestamp_display.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Timestamp_Display = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Timestamp_Display',
|
|
tag: 'small',
|
|
defaultAttributes: {"class": "text-muted d-block"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Timestamp_Display);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_98934efba78289b0.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/tooltip.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Tooltip = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Tooltip',
|
|
tag: 'span',
|
|
defaultAttributes: {"data-bs-toggle": "tooltip", "data-bs-placement": "top"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Tooltip);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_517d4f18a4791725.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/top_nav.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Top_Nav = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Top_Nav',
|
|
tag: 'nav',
|
|
defaultAttributes: {"class": "navbar navbar-expand-lg navbar-light bg-light"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "container-fluid"}, false]});
|
|
_output.push(" ");_output.push({tag: ["a", {"class": "navbar-brand", "href": "/"}, false]}); _output.push("PSM"); _output.push("</a>");
|
|
_output.push(" ");_output.push({tag: ["button", {"class": "navbar-toggler", "type": "button", "data-bs-toggle": "collapse", "data-bs-target": "#navbarNav", "aria-controls": "navbarNav", "aria-expanded": "false", "aria-label": "Toggle navigation"}, false]});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_output.push(" ");_output.push({tag: ["span", {"class": "navbar-toggler-icon"}, false]}); _output.push("</span>");
|
|
_output.push(" "); _output.push("</button>");
|
|
_output.push({tag: ["div", {"class": "collapse navbar-collapse", "id": "navbarNav"}, false]});
|
|
_output.push(" ");_output.push({tag: ["ul", {"class": "navbar-nav ms-auto", "id": "nav_items" + ":" + this._cid, "data-id": "nav_items"}, false]});
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); _output.push("</ul>");
|
|
_output.push("</div>");
|
|
_output.push("</div>");
|
|
return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Top_Nav);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_16475a3ae7842075.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/trend_indicator.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Trend_Indicator = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Trend_Indicator',
|
|
tag: 'span',
|
|
defaultAttributes: {},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Trend_Indicator);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_0e49800ae2b20a04.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/two_column_layout.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Two_Column_Layout = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Two_Column_Layout',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "row"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Two_Column_Layout);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_09b2f3fdf425ee42.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/user_avatar_dropdown.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_User_Avatar_Dropdown = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'User_Avatar_Dropdown',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "dropdown"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" ");_output.push({tag: ["button", {"class": "btn btn-link dropdown-toggle p-0 border-0", "type": "button", "data-bs-toggle": "dropdown", "aria-expanded": "false", "id": "toggle" + ":" + this._cid, "data-id": "toggle"}, false]});
|
|
|
|
|
|
|
|
|
|
_output.push(" "); _output.push({comp: ["Avatar", {"data-src": this.args.avatar_src, "data-name": this.args.user_name, "data-size": "sm"}]});
|
|
_output.push(" "); _output.push("</button>");
|
|
_output.push({tag: ["ul", {"class": "dropdown-menu dropdown-menu-end", "id": "menu" + ":" + this._cid, "data-id": "menu"}, false]});
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); _output.push("</ul>");
|
|
return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_User_Avatar_Dropdown);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_b75b5b5352e01ff2.js === */
|
|
/* Compiled from: rsx/theme/components/_archived/unfinished/users_data_table.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Users_Data_Table = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Users_Data_Table',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "card-body p-0"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "table-responsive"}, false]});
|
|
_output.push(" ");_output.push({tag: ["table", {"class": "table table-hover mb-0"}, false]});
|
|
_output.push(" ");_output.push({tag: ["thead", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["tr", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["th", {"style": "width: 40px;"}, false]});
|
|
_output.push(" ");_output.push({tag: ["input", {"type": "checkbox", "class": "form-check-input", "id": "select-all"}, true]}); _output.push("</input>");
|
|
_output.push(" "); _output.push("</th>");
|
|
_output.push({tag: ["th", {}, false]}); _output.push("ID"); _output.push("</th>");
|
|
_output.push(" ");_output.push({tag: ["th", {}, false]}); _output.push("Name"); _output.push("</th>");
|
|
_output.push(" ");_output.push({tag: ["th", {}, false]}); _output.push("Email"); _output.push("</th>");
|
|
_output.push(" ");_output.push({tag: ["th", {}, false]}); _output.push("Role"); _output.push("</th>");
|
|
_output.push(" ");_output.push({tag: ["th", {}, false]}); _output.push("Department"); _output.push("</th>");
|
|
_output.push(" ");_output.push({tag: ["th", {}, false]}); _output.push("Status"); _output.push("</th>");
|
|
_output.push(" ");_output.push({tag: ["th", {}, false]}); _output.push("Last Login"); _output.push("</th>");
|
|
_output.push(" ");_output.push({tag: ["th", {}, false]}); _output.push("Joined"); _output.push("</th>");
|
|
_output.push(" ");_output.push({tag: ["th", {"style": "width: 100px;"}, false]}); _output.push("Actions"); _output.push("</th>");
|
|
_output.push(" "); _output.push("</tr>");
|
|
_output.push("</thead>");
|
|
_output.push({tag: ["tbody", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["tr", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});_output.push({tag: ["input", {"type": "checkbox", "class": "form-check-input user-select"}, true]}); _output.push("</input>"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("#U001"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "d-flex align-items-center"}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "avatar-sm me-2"}, false]});
|
|
_output.push(" ");_output.push({tag: ["span", {"class": "avatar-initials"}, false]}); _output.push("JD"); _output.push("</span>");
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push(" John Doe "); _output.push("</div>");
|
|
|
|
_output.push(" "); _output.push("</td>");
|
|
_output.push({tag: ["td", {}, false]}); _output.push("john.doe@example.com"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});_output.push({tag: ["span", {"class": "badge bg-danger"}, false]}); _output.push("Admin"); _output.push("</span>"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("Engineering"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});_output.push({tag: ["span", {"class": "badge bg-success"}, false]}); _output.push("Active"); _output.push("</span>"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("2 hours ago"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("Jan 15, 2023"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "btn-group btn-group-sm"}, false]});
|
|
_output.push(" ");_output.push({tag: ["button", {"class": "btn btn-primary", "title": "View Profile"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-eye"}, false]}); _output.push("</i>");
|
|
_output.push(" "); _output.push("</button>");
|
|
_output.push({tag: ["button", {"class": "btn btn-secondary", "title": "Edit"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-pencil"}, false]}); _output.push("</i>");
|
|
_output.push(" "); _output.push("</button>");
|
|
_output.push({tag: ["button", {"class": "btn btn-danger", "title": "Suspend"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-ban"}, false]}); _output.push("</i>");
|
|
_output.push(" "); _output.push("</button>");
|
|
_output.push("</div>");
|
|
_output.push("</td>");
|
|
_output.push("</tr>");
|
|
_output.push({tag: ["tr", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});_output.push({tag: ["input", {"type": "checkbox", "class": "form-check-input user-select"}, true]}); _output.push("</input>"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("#U002"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "d-flex align-items-center"}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "avatar-sm me-2"}, false]});
|
|
_output.push(" ");_output.push({tag: ["span", {"class": "avatar-initials"}, false]}); _output.push("JS"); _output.push("</span>");
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push(" Jane Smith "); _output.push("</div>");
|
|
|
|
_output.push(" "); _output.push("</td>");
|
|
_output.push({tag: ["td", {}, false]}); _output.push("jane.smith@example.com"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});_output.push({tag: ["span", {"class": "badge bg-primary"}, false]}); _output.push("Manager"); _output.push("</span>"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("Marketing"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});_output.push({tag: ["span", {"class": "badge bg-success"}, false]}); _output.push("Active"); _output.push("</span>"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("1 day ago"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("Feb 20, 2023"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "btn-group btn-group-sm"}, false]});
|
|
_output.push(" ");_output.push({tag: ["button", {"class": "btn btn-primary", "title": "View Profile"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-eye"}, false]}); _output.push("</i>");
|
|
_output.push(" "); _output.push("</button>");
|
|
_output.push({tag: ["button", {"class": "btn btn-secondary", "title": "Edit"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-pencil"}, false]}); _output.push("</i>");
|
|
_output.push(" "); _output.push("</button>");
|
|
_output.push({tag: ["button", {"class": "btn btn-danger", "title": "Suspend"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-ban"}, false]}); _output.push("</i>");
|
|
_output.push(" "); _output.push("</button>");
|
|
_output.push("</div>");
|
|
_output.push("</td>");
|
|
_output.push("</tr>");
|
|
_output.push({tag: ["tr", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});_output.push({tag: ["input", {"type": "checkbox", "class": "form-check-input user-select"}, true]}); _output.push("</input>"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("#U003"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "d-flex align-items-center"}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "avatar-sm me-2"}, false]});
|
|
_output.push(" ");_output.push({tag: ["span", {"class": "avatar-initials"}, false]}); _output.push("MB"); _output.push("</span>");
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push(" Mike Brown "); _output.push("</div>");
|
|
|
|
_output.push(" "); _output.push("</td>");
|
|
_output.push({tag: ["td", {}, false]}); _output.push("mike.brown@example.com"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});_output.push({tag: ["span", {"class": "badge bg-secondary"}, false]}); _output.push("User"); _output.push("</span>"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("Sales"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});_output.push({tag: ["span", {"class": "badge bg-warning"}, false]}); _output.push("Inactive"); _output.push("</span>"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("5 days ago"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("Mar 10, 2023"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "btn-group btn-group-sm"}, false]});
|
|
_output.push(" ");_output.push({tag: ["button", {"class": "btn btn-primary", "title": "View Profile"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-eye"}, false]}); _output.push("</i>");
|
|
_output.push(" "); _output.push("</button>");
|
|
_output.push({tag: ["button", {"class": "btn btn-secondary", "title": "Edit"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-pencil"}, false]}); _output.push("</i>");
|
|
_output.push(" "); _output.push("</button>");
|
|
_output.push({tag: ["button", {"class": "btn btn-success", "title": "Activate"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-check-circle"}, false]}); _output.push("</i>");
|
|
_output.push(" "); _output.push("</button>");
|
|
_output.push("</div>");
|
|
_output.push("</td>");
|
|
_output.push("</tr>");
|
|
_output.push({tag: ["tr", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});_output.push({tag: ["input", {"type": "checkbox", "class": "form-check-input user-select"}, true]}); _output.push("</input>"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("#U004"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "d-flex align-items-center"}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "avatar-sm me-2"}, false]});
|
|
_output.push(" ");_output.push({tag: ["span", {"class": "avatar-initials"}, false]}); _output.push("SW"); _output.push("</span>");
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push(" Sarah Wilson "); _output.push("</div>");
|
|
|
|
_output.push(" "); _output.push("</td>");
|
|
_output.push({tag: ["td", {}, false]}); _output.push("sarah.wilson@example.com"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});_output.push({tag: ["span", {"class": "badge bg-primary"}, false]}); _output.push("Manager"); _output.push("</span>"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("HR"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});_output.push({tag: ["span", {"class": "badge bg-success"}, false]}); _output.push("Active"); _output.push("</span>"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("3 hours ago"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("Apr 05, 2023"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "btn-group btn-group-sm"}, false]});
|
|
_output.push(" ");_output.push({tag: ["button", {"class": "btn btn-primary", "title": "View Profile"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-eye"}, false]}); _output.push("</i>");
|
|
_output.push(" "); _output.push("</button>");
|
|
_output.push({tag: ["button", {"class": "btn btn-secondary", "title": "Edit"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-pencil"}, false]}); _output.push("</i>");
|
|
_output.push(" "); _output.push("</button>");
|
|
_output.push({tag: ["button", {"class": "btn btn-danger", "title": "Suspend"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-ban"}, false]}); _output.push("</i>");
|
|
_output.push(" "); _output.push("</button>");
|
|
_output.push("</div>");
|
|
_output.push("</td>");
|
|
_output.push("</tr>");
|
|
_output.push({tag: ["tr", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});_output.push({tag: ["input", {"type": "checkbox", "class": "form-check-input user-select"}, true]}); _output.push("</input>"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("#U005"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "d-flex align-items-center"}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "avatar-sm me-2"}, false]});
|
|
_output.push(" ");_output.push({tag: ["span", {"class": "avatar-initials"}, false]}); _output.push("TJ"); _output.push("</span>");
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push(" Tom Johnson "); _output.push("</div>");
|
|
|
|
_output.push(" "); _output.push("</td>");
|
|
_output.push({tag: ["td", {}, false]}); _output.push("tom.j@example.com"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});_output.push({tag: ["span", {"class": "badge bg-secondary"}, false]}); _output.push("User"); _output.push("</span>"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("Support"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});_output.push({tag: ["span", {"class": "badge bg-danger"}, false]}); _output.push("Suspended"); _output.push("</span>"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("2 weeks ago"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("May 12, 2023"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "btn-group btn-group-sm"}, false]});
|
|
_output.push(" ");_output.push({tag: ["button", {"class": "btn btn-primary", "title": "View Profile"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-eye"}, false]}); _output.push("</i>");
|
|
_output.push(" "); _output.push("</button>");
|
|
_output.push({tag: ["button", {"class": "btn btn-secondary", "title": "Edit"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-pencil"}, false]}); _output.push("</i>");
|
|
_output.push(" "); _output.push("</button>");
|
|
_output.push({tag: ["button", {"class": "btn btn-success", "title": "Reactivate"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-arrow-clockwise"}, false]}); _output.push("</i>");
|
|
_output.push(" "); _output.push("</button>");
|
|
_output.push("</div>");
|
|
_output.push("</td>");
|
|
_output.push("</tr>");
|
|
_output.push({tag: ["tr", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});_output.push({tag: ["input", {"type": "checkbox", "class": "form-check-input user-select"}, true]}); _output.push("</input>"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("#U006"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "d-flex align-items-center"}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "avatar-sm me-2"}, false]});
|
|
_output.push(" ");_output.push({tag: ["span", {"class": "avatar-initials"}, false]}); _output.push("ED"); _output.push("</span>");
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push(" Emily Davis "); _output.push("</div>");
|
|
|
|
_output.push(" "); _output.push("</td>");
|
|
_output.push({tag: ["td", {}, false]}); _output.push("emily.d@example.com"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});_output.push({tag: ["span", {"class": "badge bg-danger"}, false]}); _output.push("Admin"); _output.push("</span>"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("IT"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});_output.push({tag: ["span", {"class": "badge bg-success"}, false]}); _output.push("Active"); _output.push("</span>"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("Just now"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("Jun 01, 2023"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "btn-group btn-group-sm"}, false]});
|
|
_output.push(" ");_output.push({tag: ["button", {"class": "btn btn-primary", "title": "View Profile"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-eye"}, false]}); _output.push("</i>");
|
|
_output.push(" "); _output.push("</button>");
|
|
_output.push({tag: ["button", {"class": "btn btn-secondary", "title": "Edit"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-pencil"}, false]}); _output.push("</i>");
|
|
_output.push(" "); _output.push("</button>");
|
|
_output.push({tag: ["button", {"class": "btn btn-danger", "title": "Suspend"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-ban"}, false]}); _output.push("</i>");
|
|
_output.push(" "); _output.push("</button>");
|
|
_output.push("</div>");
|
|
_output.push("</td>");
|
|
_output.push("</tr>");
|
|
_output.push({tag: ["tr", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});_output.push({tag: ["input", {"type": "checkbox", "class": "form-check-input user-select"}, true]}); _output.push("</input>"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("#U007"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "d-flex align-items-center"}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "avatar-sm me-2"}, false]});
|
|
_output.push(" ");_output.push({tag: ["span", {"class": "avatar-initials"}, false]}); _output.push("CG"); _output.push("</span>");
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push(" Chris Garcia "); _output.push("</div>");
|
|
|
|
_output.push(" "); _output.push("</td>");
|
|
_output.push({tag: ["td", {}, false]}); _output.push("chris.g@example.com"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});_output.push({tag: ["span", {"class": "badge bg-secondary"}, false]}); _output.push("User"); _output.push("</span>"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("Finance"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});_output.push({tag: ["span", {"class": "badge bg-success"}, false]}); _output.push("Active"); _output.push("</span>"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("6 hours ago"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("Jul 15, 2023"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "btn-group btn-group-sm"}, false]});
|
|
_output.push(" ");_output.push({tag: ["button", {"class": "btn btn-primary", "title": "View Profile"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-eye"}, false]}); _output.push("</i>");
|
|
_output.push(" "); _output.push("</button>");
|
|
_output.push({tag: ["button", {"class": "btn btn-secondary", "title": "Edit"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-pencil"}, false]}); _output.push("</i>");
|
|
_output.push(" "); _output.push("</button>");
|
|
_output.push({tag: ["button", {"class": "btn btn-danger", "title": "Suspend"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-ban"}, false]}); _output.push("</i>");
|
|
_output.push(" "); _output.push("</button>");
|
|
_output.push("</div>");
|
|
_output.push("</td>");
|
|
_output.push("</tr>");
|
|
_output.push({tag: ["tr", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});_output.push({tag: ["input", {"type": "checkbox", "class": "form-check-input user-select"}, true]}); _output.push("</input>"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("#U008"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "d-flex align-items-center"}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "avatar-sm me-2"}, false]});
|
|
_output.push(" ");_output.push({tag: ["span", {"class": "avatar-initials"}, false]}); _output.push("AM"); _output.push("</span>");
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push(" Ashley Martinez "); _output.push("</div>");
|
|
|
|
_output.push(" "); _output.push("</td>");
|
|
_output.push({tag: ["td", {}, false]}); _output.push("ashley.m@example.com"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});_output.push({tag: ["span", {"class": "badge bg-primary"}, false]}); _output.push("Manager"); _output.push("</span>"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("Operations"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});_output.push({tag: ["span", {"class": "badge bg-success"}, false]}); _output.push("Active"); _output.push("</span>"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("12 hours ago"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("Aug 20, 2023"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "btn-group btn-group-sm"}, false]});
|
|
_output.push(" ");_output.push({tag: ["button", {"class": "btn btn-primary", "title": "View Profile"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-eye"}, false]}); _output.push("</i>");
|
|
_output.push(" "); _output.push("</button>");
|
|
_output.push({tag: ["button", {"class": "btn btn-secondary", "title": "Edit"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-pencil"}, false]}); _output.push("</i>");
|
|
_output.push(" "); _output.push("</button>");
|
|
_output.push({tag: ["button", {"class": "btn btn-danger", "title": "Suspend"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-ban"}, false]}); _output.push("</i>");
|
|
_output.push(" "); _output.push("</button>");
|
|
_output.push("</div>");
|
|
_output.push("</td>");
|
|
_output.push("</tr>");
|
|
_output.push({tag: ["tr", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});_output.push({tag: ["input", {"type": "checkbox", "class": "form-check-input user-select"}, true]}); _output.push("</input>"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("#U009"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "d-flex align-items-center"}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "avatar-sm me-2"}, false]});
|
|
_output.push(" ");_output.push({tag: ["span", {"class": "avatar-initials"}, false]}); _output.push("KL"); _output.push("</span>");
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push(" Kevin Lee "); _output.push("</div>");
|
|
|
|
_output.push(" "); _output.push("</td>");
|
|
_output.push({tag: ["td", {}, false]}); _output.push("kevin.lee@example.com"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});_output.push({tag: ["span", {"class": "badge bg-secondary"}, false]}); _output.push("User"); _output.push("</span>"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("Design"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});_output.push({tag: ["span", {"class": "badge bg-success"}, false]}); _output.push("Active"); _output.push("</span>"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("1 day ago"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("Sep 10, 2023"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "btn-group btn-group-sm"}, false]});
|
|
_output.push(" ");_output.push({tag: ["button", {"class": "btn btn-primary", "title": "View Profile"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-eye"}, false]}); _output.push("</i>");
|
|
_output.push(" "); _output.push("</button>");
|
|
_output.push({tag: ["button", {"class": "btn btn-secondary", "title": "Edit"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-pencil"}, false]}); _output.push("</i>");
|
|
_output.push(" "); _output.push("</button>");
|
|
_output.push({tag: ["button", {"class": "btn btn-danger", "title": "Suspend"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-ban"}, false]}); _output.push("</i>");
|
|
_output.push(" "); _output.push("</button>");
|
|
_output.push("</div>");
|
|
_output.push("</td>");
|
|
_output.push("</tr>");
|
|
_output.push({tag: ["tr", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});_output.push({tag: ["input", {"type": "checkbox", "class": "form-check-input user-select"}, true]}); _output.push("</input>"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("#U010"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "d-flex align-items-center"}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "avatar-sm me-2"}, false]});
|
|
_output.push(" ");_output.push({tag: ["span", {"class": "avatar-initials"}, false]}); _output.push("RW"); _output.push("</span>");
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push(" Rachel White "); _output.push("</div>");
|
|
|
|
_output.push(" "); _output.push("</td>");
|
|
_output.push({tag: ["td", {}, false]}); _output.push("rachel.w@example.com"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});_output.push({tag: ["span", {"class": "badge bg-secondary"}, false]}); _output.push("User"); _output.push("</span>"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("Legal"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});_output.push({tag: ["span", {"class": "badge bg-warning"}, false]}); _output.push("Inactive"); _output.push("</span>"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("1 week ago"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]}); _output.push("Oct 05, 2023"); _output.push("</td>");
|
|
_output.push(" ");_output.push({tag: ["td", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "btn-group btn-group-sm"}, false]});
|
|
_output.push(" ");_output.push({tag: ["button", {"class": "btn btn-primary", "title": "View Profile"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-eye"}, false]}); _output.push("</i>");
|
|
_output.push(" "); _output.push("</button>");
|
|
_output.push({tag: ["button", {"class": "btn btn-secondary", "title": "Edit"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-pencil"}, false]}); _output.push("</i>");
|
|
_output.push(" "); _output.push("</button>");
|
|
_output.push({tag: ["button", {"class": "btn btn-success", "title": "Activate"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-check-circle"}, false]}); _output.push("</i>");
|
|
_output.push(" "); _output.push("</button>");
|
|
_output.push("</div>");
|
|
_output.push("</td>");
|
|
_output.push("</tr>");
|
|
_output.push("</tbody>");
|
|
_output.push("</table>");
|
|
_output.push("</div>");
|
|
return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Users_Data_Table);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_4e0b9dea1b172d56.js === */
|
|
/* Compiled from: rsx/theme/components/modal/rsx_modal.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Rsx_Modal = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Rsx_Modal',
|
|
tag: 'div',
|
|
defaultAttributes: {},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "modal fade rsx-modal", "tabindex": "-1", "id": "modal" + ":" + this._cid, "data-id": "modal"}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "modal-dialog", "id": "dialog" + ":" + this._cid, "data-id": "dialog"}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "modal-content"}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "modal-header", "id": "header" + ":" + this._cid, "data-id": "header"}, false]});
|
|
_output.push(" ");_output.push({tag: ["h5", {"class": "modal-title", "id": "title" + ":" + this._cid, "data-id": "title"}, false]}); _output.push("</h5>");
|
|
_output.push(" ");_output.push({tag: ["button", {"type": "button", "class": "btn-close", "id": "close_btn" + ":" + this._cid, "data-id": "close_btn", "data-bs-dismiss": "modal", "aria-label": "Close"}, false]}); _output.push("</button>");
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push({tag: ["div", {"class": "modal-body", "id": "body" + ":" + this._cid, "data-id": "body"}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "modal-body-content", "id": "body_content" + ":" + this._cid, "data-id": "body_content"}, false]});
|
|
_output.push(" "); _output.push("<!-- Dynamic content inserted here -->");
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push("</div>");
|
|
_output.push({tag: ["div", {"class": "modal-footer", "id": "footer" + ":" + this._cid, "data-id": "footer"}, false]});
|
|
_output.push(" "); _output.push("<!-- Dynamic buttons inserted here -->");
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push("</div>");
|
|
_output.push("</div>");
|
|
_output.push("</div>");
|
|
_output.push({tag: ["div", {"class": "modal-backdrop fade", "id": "backdrop" + ":" + this._cid, "data-id": "backdrop"}, false]}); _output.push("</div>");
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Rsx_Modal);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_7217e9c37c215bd8.js === */
|
|
/* Compiled from: rsx/theme/components/page_elements/breadcrumb.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Breadcrumb = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Breadcrumb',
|
|
tag: 'nav',
|
|
defaultAttributes: {"aria-label": "breadcrumb"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_output.push(" ");_output.push({tag: ["ol", {"class": "breadcrumb bg-transparent p-0 mb-0"}, false]});
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); _output.push("</ol>");
|
|
return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Breadcrumb);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_0437ab9d2970dd17.js === */
|
|
/* Compiled from: rsx/theme/components/page_elements/breadcrumb_item.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Breadcrumb_Item = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Breadcrumb_Item',
|
|
tag: 'li',
|
|
defaultAttributes: {"class": "breadcrumb-item"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_output.push(" "); if (this.args.active) {
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); } else if (this.args.href) {
|
|
_output.push(" ");_output.push({tag: ["a", {"href": (this.args.href)}, false]}); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })(); _output.push("</a>");
|
|
_output.push(" "); } else {
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); }
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Breadcrumb_Item);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_796750a84323e25c.js === */
|
|
/* Compiled from: rsx/theme/components/page_elements/client_label.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Client_Label = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Client_Label',
|
|
tag: 'span',
|
|
defaultAttributes: {"class": "Widget"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_output.push(" ");
|
|
_output.push({tag: ["i", {"class": "bi bi-building"}, false]}); _output.push("</i>");
|
|
_output.push(" "); if (this.data.loading) {
|
|
_output.push(" "); (() => { const result = this.args.placeholder || '------' ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })();
|
|
_output.push(" "); } else if (this.data.client) {
|
|
_output.push(" "); (() => { const result = this.data.client.name ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push(" cadfdsa ");
|
|
} else {
|
|
_output.push(" ");_output.push({tag: ["span", {"class": "text-muted"}, false]}); _output.push("Unknown Client"); _output.push("</span>");
|
|
_output.push(" "); }
|
|
_output.push(" ");
|
|
return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Client_Label);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_84a4678f9228ae19.js === */
|
|
/* Compiled from: rsx/theme/components/page_elements/client_label_link.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Client_Label_Link = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Client_Label_Link',
|
|
tag: 'a',
|
|
defaultAttributes: {"class": "Widget"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_output.push(" ");
|
|
_output.push({tag: ["i", {"class": "bi bi-building"}, false]}); _output.push("</i>");
|
|
_output.push(" "); if (this.data.loading) {
|
|
_output.push(" "); (() => { const result = this.args.placeholder || '------' ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })();
|
|
_output.push(" "); } else if (this.data.client) {
|
|
_output.push(" "); (() => { const result = this.data.client.name ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })();
|
|
_output.push(" "); } else {
|
|
_output.push(" ");_output.push({tag: ["span", {"class": "text-muted"}, false]}); _output.push("Unknown Client"); _output.push("</span>");
|
|
_output.push(" "); }
|
|
_output.push(" ");
|
|
return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Client_Label_Link);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_1f6b5c0a2361546e.js === */
|
|
/* Compiled from: rsx/theme/components/inputs/text_input.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Text_Input = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Text_Input',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "Widget"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_output.push(" "); if (this.args.type === 'textarea') {
|
|
_output.push(" ");_output.push({rawtag: ["textarea", Object.assign({}, {"id": "input" + ":" + this._cid, "data-id": "input", "class": "form-control", "rows": (this.args.rows || 3), "placeholder": (this.args.placeholder || '')}, ((this.args.disabled)) ? {"disabled": "true"} : {}), "undefined"]});
|
|
|
|
|
|
|
|
|
|
_output.push(" "); } else if (this.args.prefix || this.args.suffix) {
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "input-group"}, false]});
|
|
_output.push(" "); if (this.args.prefix) {
|
|
_output.push(" ");_output.push({tag: ["span", {"class": "input-group-text"}, false]}); (() => { const result = this.args.prefix ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</span>");
|
|
_output.push(" "); }
|
|
_output.push(" ");_output.push({tag: ["input", Object.assign({}, Object.assign({}, Object.assign({}, Object.assign({}, {"id": "input" + ":" + this._cid, "data-id": "input", "type": (this.args.type || 'text'), "class": "form-control", "value": (this.data.value), "placeholder": (this.args.placeholder || '')}, ((this.args.min !== undefined)) ? {"min": (this.args.min)} : {}), ((this.args.max !== undefined)) ? {"max": (this.args.max)} : {}), ((this.args.maxlength)) ? {"maxlength": (this.args.maxlength)} : {}), ((this.args.disabled)) ? {"disabled": "true"} : {}), true]}); _output.push("</input>");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_output.push(" "); if (this.args.suffix) {
|
|
_output.push(" ");_output.push({tag: ["span", {"class": "input-group-text"}, false]}); (() => { const result = this.args.suffix ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</span>");
|
|
_output.push(" "); }
|
|
_output.push(" "); _output.push("</div>");
|
|
} else {
|
|
_output.push(" ");_output.push({tag: ["input", Object.assign({}, Object.assign({}, Object.assign({}, Object.assign({}, {"id": "input" + ":" + this._cid, "data-id": "input", "type": (this.args.type || 'text'), "class": "form-control", "value": (this.data.value), "placeholder": (this.args.placeholder || '')}, ((this.args.min !== undefined)) ? {"min": (this.args.min)} : {}), ((this.args.max !== undefined)) ? {"max": (this.args.max)} : {}), ((this.args.maxlength)) ? {"maxlength": (this.args.maxlength)} : {}), ((this.args.disabled)) ? {"disabled": "true"} : {}), true]}); _output.push("</input>");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_output.push(" "); }
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Text_Input);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_59c189b4fa652b8e.js === */
|
|
/* Compiled from: rsx/theme/components/inputs/select_input.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Select_Input = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Select_Input',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "Widget"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_output.push(" ");_output.push({tag: ["select", Object.assign({}, {"id": "input" + ":" + this._cid, "data-id": "input"}, ((this.args.disabled)) ? {"disabled": "true"} : {}), false]});
|
|
_output.push(" "); if (this.args.placeholder) {
|
|
_output.push(" ");_output.push({tag: ["option", {"value": ""}, false]}); (() => { const result = this.args.placeholder ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</option>");
|
|
_output.push(" "); }
|
|
_output.push(" "); if (this.args.options) {
|
|
_output.push(" "); for (let opt of this.args.options) {
|
|
_output.push(" "); if (typeof opt === 'object') {
|
|
_output.push(" ");_output.push({tag: ["option", Object.assign({}, {"value": (opt.value)}, ((this.data.value == opt.value)) ? {"selected": "true"} : {}), false]}); (() => { const result = opt.label ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</option>");
|
|
_output.push(" "); } else {
|
|
_output.push(" ");_output.push({tag: ["option", Object.assign({}, {"value": (opt)}, ((this.data.value == opt)) ? {"selected": "true"} : {}), false]}); (() => { const result = opt ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</option>");
|
|
_output.push(" "); }
|
|
_output.push(" "); }
|
|
_output.push(" "); }
|
|
_output.push(" "); _output.push("</select>");
|
|
return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Select_Input);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_3a30a5c5dfa4f0b9.js === */
|
|
/* Compiled from: rsx/theme/components/inputs/ajax_select_input.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Ajax_Select_Input = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Ajax_Select_Input',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "Widget"},
|
|
extends: 'Select_Input',
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_output.push(" ");_output.push({tag: ["select", Object.assign({}, {"id": "input" + ":" + this._cid, "data-id": "input"}, ((this.args.disabled)) ? {"disabled": "true"} : {}), false]});
|
|
_output.push(" "); if (!this.data.select_values || this.data.select_values.length === 0) {
|
|
_output.push(" ");_output.push({tag: ["option", {"value": ""}, false]}); (() => { const result = this.args.placeholder || 'Please wait...' ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</option>");
|
|
_output.push(" "); } else {
|
|
_output.push(" "); if (this.args.placeholder) {
|
|
_output.push(" ");_output.push({tag: ["option", {"value": ""}, false]}); (() => { const result = this.args.placeholder ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</option>");
|
|
_output.push(" "); }
|
|
_output.push(" "); for (let opt of this.data.select_values) {
|
|
_output.push(" "); if (typeof opt === 'object') {
|
|
_output.push(" ");_output.push({tag: ["option", Object.assign({}, {"value": (opt.value)}, ((this.data.value == opt.value)) ? {"selected": "true"} : {}), false]}); (() => { const result = opt.label ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</option>");
|
|
_output.push(" "); } else {
|
|
_output.push(" ");_output.push({tag: ["option", Object.assign({}, {"value": (opt)}, ((this.data.value == opt)) ? {"selected": "true"} : {}), false]}); (() => { const result = opt ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</option>");
|
|
_output.push(" "); }
|
|
_output.push(" "); }
|
|
_output.push(" "); }
|
|
_output.push(" "); _output.push("</select>");
|
|
return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Ajax_Select_Input);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_d3f44e3bcb81a874.js === */
|
|
/* Compiled from: rsx/theme/components/inputs/checkbox_input.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Checkbox_Input = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Checkbox_Input',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "Widget"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "form-check"}, false]});
|
|
_output.push(" ");_output.push({tag: ["input", Object.assign({}, Object.assign({}, {"id": "input" + ":" + this._cid, "data-id": "input", "class": "form-check-input", "type": "checkbox"}, ((this.data.checked)) ? {"checked": "true"} : {}), ((this.args.disabled)) ? {"disabled": "true"} : {}), true]}); _output.push("</input>");
|
|
_output.push(" "); if (this.args.label) {
|
|
_output.push(" ");_output.push({tag: ["label", {"id": "label" + ":" + this._cid, "data-id": "label", "class": "form-check-label"}, false]});
|
|
_output.push(" "); (() => { const result = this.args.label ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })();
|
|
_output.push(" "); _output.push("</label>");
|
|
}
|
|
_output.push(" "); _output.push("</div>");
|
|
return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Checkbox_Input);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_77d25c093236508a.js === */
|
|
/* Compiled from: rsx/theme/components/inputs/wysiwyg_input.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Wysiwyg_Input = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Wysiwyg_Input',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "Widget"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_output.push(" ");_output.push({tag: ["div", {"id": "editor" + ":" + this._cid, "data-id": "editor", "style": "min-height: 200px; background: white;"}, false]}); _output.push("</div>");
|
|
_output.push(" ");_output.push({tag: ["input", {"type": "hidden", "id": "hidden_input" + ":" + this._cid, "data-id": "hidden_input"}, true]}); _output.push("</input>");
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Wysiwyg_Input);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_23e1143d0e1cd60c.js === */
|
|
/* Compiled from: rsx/theme/components/inputs/country_select_input.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Country_Select_Input = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Country_Select_Input',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "Widget"},
|
|
extends: 'Ajax_Select_Input',
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_output.push(" ");_output.push({tag: ["select", Object.assign({}, {"id": "input" + ":" + this._cid, "data-id": "input"}, ((this.args.disabled)) ? {"disabled": "true"} : {}), false]});
|
|
_output.push(" "); if (!this.data.select_values || this.data.select_values.length === 0) {
|
|
_output.push(" ");_output.push({tag: ["option", {"value": ""}, false]}); (() => { const result = this.args.placeholder || 'Please wait...' ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</option>");
|
|
_output.push(" "); } else {
|
|
_output.push(" "); if (this.args.placeholder) {
|
|
_output.push(" ");_output.push({tag: ["option", {"value": ""}, false]}); (() => { const result = this.args.placeholder ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</option>");
|
|
_output.push(" "); }
|
|
_output.push(" "); for (let opt of this.data.select_values) {
|
|
_output.push(" "); if (typeof opt === 'object') {
|
|
_output.push(" ");_output.push({tag: ["option", Object.assign({}, {"value": (opt.value)}, ((this.data.value == opt.value)) ? {"selected": "true"} : {}), false]}); (() => { const result = opt.label ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</option>");
|
|
_output.push(" "); } else {
|
|
_output.push(" ");_output.push({tag: ["option", Object.assign({}, {"value": (opt)}, ((this.data.value == opt)) ? {"selected": "true"} : {}), false]}); (() => { const result = opt ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</option>");
|
|
_output.push(" "); }
|
|
_output.push(" "); }
|
|
_output.push(" "); }
|
|
_output.push(" "); _output.push("</select>");
|
|
return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Country_Select_Input);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_717fc745d391ec0b.js === */
|
|
/* Compiled from: rsx/theme/components/inputs/state_select_input.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_State_Select_Input = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'State_Select_Input',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "Widget"},
|
|
extends: 'Ajax_Select_Input',
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_output.push(" ");_output.push({tag: ["select", Object.assign({}, {"id": "input" + ":" + this._cid, "data-id": "input"}, ((this.args.disabled || !this.data.country_code)) ? {"disabled": "true"} : {}), false]});
|
|
_output.push(" "); if (!this.data.select_values || this.data.select_values.length === 0) {
|
|
_output.push(" ");_output.push({tag: ["option", {"value": ""}, false]}); (() => { const result = this.args.placeholder || 'Select State...' ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</option>");
|
|
_output.push(" "); } else {
|
|
_output.push(" "); if (this.args.placeholder) {
|
|
_output.push(" ");_output.push({tag: ["option", {"value": ""}, false]}); (() => { const result = this.args.placeholder ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</option>");
|
|
_output.push(" "); }
|
|
_output.push(" "); for (let opt of this.data.select_values) {
|
|
_output.push(" "); if (typeof opt === 'object') {
|
|
_output.push(" ");_output.push({tag: ["option", Object.assign({}, {"value": (opt.value)}, ((this.data.value == opt.value)) ? {"selected": "true"} : {}), false]}); (() => { const result = opt.label ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</option>");
|
|
_output.push(" "); } else {
|
|
_output.push(" ");_output.push({tag: ["option", Object.assign({}, {"value": (opt)}, ((this.data.value == opt)) ? {"selected": "true"} : {}), false]}); (() => { const result = opt ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</option>");
|
|
_output.push(" "); }
|
|
_output.push(" "); }
|
|
_output.push(" "); }
|
|
_output.push(" "); _output.push("</select>");
|
|
return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_State_Select_Input);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_1bc3e8b1a237bb35.js === */
|
|
/* Compiled from: rsx/theme/components/inputs/profile_photo_input.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Profile_Photo_Input = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Profile_Photo_Input',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "Widget"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_output.push(" ");
|
|
_output.push({tag: ["div", {"class": "d-flex align-items-center"}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "position-relative"}, false]});
|
|
_output.push(" "); if (this.data.thumbnail_url) {
|
|
_output.push(" ");_output.push({tag: ["img", {"id": "photo" + ":" + this._cid, "data-id": "photo", "src": (this.data.thumbnail_url), "class": "rounded-circle me-3", "alt": "Profile Photo", "width": (this.args.width || 96), "height": (this.args.height || 96), "style": "opacity: 1;"}, true]}); _output.push("</img>");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_output.push(" "); } else {
|
|
_output.push(" ");_output.push({tag: ["div", {"id": "photo" + ":" + this._cid, "data-id": "photo", "class": "user-profile-icon me-3", "style": "width:" + (this.args.width || 96) + "px; height:" + (this.args.height || 96) + "px; display: flex; align-items: center; justify-content: center;"}, false]});
|
|
_output.push(" ");_output.push({tag: ["i", {"class": "bi bi-person-circle", "style": "font-size:" + (Math.round((this.args.width || 96) * 0.75)) + "px;"}, false]}); _output.push("</i>");
|
|
_output.push(" "); _output.push("</div>");
|
|
}
|
|
_output.push(" ");_output.push({tag: ["div", {"id": "spinner" + ":" + this._cid, "data-id": "spinner", "class": "position-absolute top-50 start-50 translate-middle d-none"}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "spinner-border text-primary", "role": "status"}, false]});
|
|
_output.push(" ");_output.push({tag: ["span", {"class": "visually-hidden"}, false]}); _output.push("Uploading..."); _output.push("</span>");
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push("</div>");
|
|
_output.push("</div>");
|
|
_output.push({tag: ["div", {}, false]});
|
|
_output.push(" ");_output.push({tag: ["input", {"type": "file", "id": "file_input" + ":" + this._cid, "data-id": "file_input", "class": "d-none", "accept": (this.args.accept || 'image/jpeg,image/png,image/gif')}, true]}); _output.push("</input>");
|
|
_output.push(" ");_output.push({tag: ["button", {"type": "button", "id": "upload_btn" + ":" + this._cid, "data-id": "upload_btn", "class": "btn btn-sm btn-primary me-2"}, false]}); _output.push("Upload New Photo"); _output.push("</button>");
|
|
_output.push(" "); if (this.args.show_remove && this.data.attachment_key) {
|
|
_output.push(" ");_output.push({tag: ["button", {"type": "button", "id": "remove_btn" + ":" + this._cid, "data-id": "remove_btn", "class": "btn btn-sm btn-danger"}, false]}); _output.push("Remove"); _output.push("</button>");
|
|
_output.push(" "); }
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "form-text mt-2"}, false]}); _output.push("JPG, PNG or GIF. Max size "); (() => { const result = this.args.max_size || 2 ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("MB."); _output.push("</div>");
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push("</div>");
|
|
|
|
return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Profile_Photo_Input);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_7e9b52d659877f0d.js === */
|
|
/* Compiled from: rsx/theme/components/forms/rsx_tabs.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Rsx_Tabs = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Rsx_Tabs',
|
|
tag: 'div',
|
|
defaultAttributes: {},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_output.push(" "); _output.push("<!-- Tab Navigation -->");
|
|
_output.push(" ");_output.push({tag: ["ul", {"class": "nav nav-tabs", "role": "tablist", "id": "nav" + ":" + this._cid, "data-id": "nav"}, false]});
|
|
_output.push(" "); _output.push("<!-- Tab headers will be rendered by Rsx_Tab components -->");
|
|
_output.push(" "); _output.push("</ul>");
|
|
|
|
_output.push("<!-- Tab Content Container -->");
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "tab-content mt-4", "id": "content" + ":" + this._cid, "data-id": "content"}, false]});
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); _output.push("</div>");
|
|
return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Rsx_Tabs);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_948e2845fa2cff99.js === */
|
|
/* Compiled from: rsx/theme/components/forms/rsx_tab.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Rsx_Tab = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Rsx_Tab',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "tab-pane fade", "role": "tabpanel"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Rsx_Tab);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_dbf52270a0259e5e.js === */
|
|
/* Compiled from: rsx/theme/components/forms/rsx_form.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Rsx_Form = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Rsx_Form',
|
|
tag: 'form',
|
|
defaultAttributes: {},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_output.push(" ");
|
|
_output.push({tag: ["div", {"id": "loader" + ":" + this._cid, "data-id": "loader", "class": "text-center py-5"}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "spinner-border text-primary mb-3", "role": "status"}, false]});
|
|
_output.push(" ");_output.push({tag: ["span", {"class": "visually-hidden"}, false]}); _output.push("Loading..."); _output.push("</span>");
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push({tag: ["p", {"class": "text-muted"}, false]}); _output.push("Loading form..."); _output.push("</p>");
|
|
_output.push(" "); _output.push("</div>");
|
|
|
|
_output.push({tag: ["div", {"id": "form_content" + ":" + this._cid, "data-id": "form_content", "style": "display: none;"}, false]});
|
|
_output.push(" "); if (window.rsxapp.debug) {
|
|
_output.push(" ");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
_output.push(" ");
|
|
_output.push({tag: ["div", {"id": "error" + ":" + this._cid, "data-id": "error"}, false]}); _output.push("</div>");
|
|
_output.push(" ");
|
|
(() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); _output.push("</div>");
|
|
|
|
return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Rsx_Form);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_24af8013a9dcda8c.js === */
|
|
/* Compiled from: rsx/theme/components/forms/form_field_abstract.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Form_Field_Abstract = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Form_Field_Abstract',
|
|
tag: 'div',
|
|
defaultAttributes: {},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Form_Field_Abstract);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_10786dec1aed77bb.js === */
|
|
/* Compiled from: rsx/theme/components/forms/form_field.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Form_Field = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Form_Field',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "form-group mb-3"},
|
|
extends: 'Form_Field_Abstract',
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_output.push(" ");
|
|
if (this.args.label) {
|
|
_output.push(" ");_output.push({tag: ["label", {"class": "form-label", "id": "form_label" + ":" + this._cid, "data-id": "form_label"}, false]});
|
|
_output.push(" "); (() => { const result = this.args.label ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(result); } })();
|
|
_output.push(" "); if (this.args.required) {
|
|
_output.push(" ");_output.push({tag: ["span", {"class": "text-danger"}, false]}); _output.push("*"); _output.push("</span>");
|
|
_output.push(" "); }
|
|
_output.push(" "); _output.push("</label>");
|
|
}
|
|
_output.push(" ");
|
|
_output.push({tag: ["div", {"class": (this.has_error() ? 'is-invalid' : '')}, false]});
|
|
_output.push(" "); (() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })();
|
|
_output.push(" "); _output.push("</div>");
|
|
|
|
if (this.has_error()) {
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "invalid-feedback d-block"}, false]});
|
|
_output.push(" "); (() => { const result = this.get_error() ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })();
|
|
_output.push(" "); _output.push("</div>");
|
|
}
|
|
_output.push(" ");
|
|
if (this.args.help) {
|
|
_output.push(" ");_output.push({tag: ["small", {"class": "form-text text-muted d-block mt-1"}, false]});
|
|
_output.push(" "); (() => { const result = this.args.help ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })();
|
|
_output.push(" "); _output.push("</small>");
|
|
}
|
|
_output.push(" ");
|
|
return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Form_Field);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_df8486e42e28be4f.js === */
|
|
/* Compiled from: rsx/theme/components/forms/form_hidden_field.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Form_Hidden_Field = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Form_Hidden_Field',
|
|
tag: 'input',
|
|
defaultAttributes: {"type": "hidden", "class": "Widget"},
|
|
extends: 'Form_Field_Abstract',
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Form_Hidden_Field);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_5e1e2e4a50922d32.js === */
|
|
/* Compiled from: rsx/theme/components/forms/pin_verification_form.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Pin_Verification_Form = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Pin_Verification_Form',
|
|
tag: 'div',
|
|
defaultAttributes: {},
|
|
extends: 'Rsx_Form',
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "pin-verification-form"}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "pin-inputs d-flex justify-content-center gap-2 mb-3"}, false]});
|
|
_output.push(" ");_output.push({tag: ["input", {"id": "digit_0" + ":" + this._cid, "data-id": "digit_0", "type": "text", "class": "form-control pin-input text-center", "maxlength": "1", "inputmode": "numeric", "pattern": "[0-9]", "autocomplete": "off", "data-index": "0"}, true]}); _output.push("</input>");
|
|
_output.push(" ");_output.push({tag: ["input", {"id": "digit_1" + ":" + this._cid, "data-id": "digit_1", "type": "text", "class": "form-control pin-input text-center", "maxlength": "1", "inputmode": "numeric", "pattern": "[0-9]", "autocomplete": "off", "data-index": "1"}, true]}); _output.push("</input>");
|
|
_output.push(" ");_output.push({tag: ["input", {"id": "digit_2" + ":" + this._cid, "data-id": "digit_2", "type": "text", "class": "form-control pin-input text-center", "maxlength": "1", "inputmode": "numeric", "pattern": "[0-9]", "autocomplete": "off", "data-index": "2"}, true]}); _output.push("</input>");
|
|
_output.push(" ");_output.push({tag: ["input", {"id": "digit_3" + ":" + this._cid, "data-id": "digit_3", "type": "text", "class": "form-control pin-input text-center", "maxlength": "1", "inputmode": "numeric", "pattern": "[0-9]", "autocomplete": "off", "data-index": "3"}, true]}); _output.push("</input>");
|
|
_output.push(" ");_output.push({tag: ["input", {"id": "digit_4" + ":" + this._cid, "data-id": "digit_4", "type": "text", "class": "form-control pin-input text-center", "maxlength": "1", "inputmode": "numeric", "pattern": "[0-9]", "autocomplete": "off", "data-index": "4"}, true]}); _output.push("</input>");
|
|
_output.push(" ");_output.push({tag: ["input", {"id": "digit_5" + ":" + this._cid, "data-id": "digit_5", "type": "text", "class": "form-control pin-input text-center", "maxlength": "1", "inputmode": "numeric", "pattern": "[0-9]", "autocomplete": "off", "data-index": "5"}, true]}); _output.push("</input>");
|
|
_output.push(" "); _output.push("</div>");
|
|
|
|
_output.push({tag: ["div", {"id": "error_container" + ":" + this._cid, "data-id": "error_container", "class": "alert alert-danger", "style": "display: none;"}, false]}); _output.push("</div>");
|
|
_output.push(" ");
|
|
_output.push({tag: ["div", {"class": "text-center text-muted small"}, false]});
|
|
_output.push(" "); _output.push(" Enter the 6-digit PIN code "); _output.push("</div>");
|
|
|
|
_output.push(" "); _output.push("</div>");
|
|
return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Pin_Verification_Form);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_0624c3489faf8bba.js === */
|
|
/* Compiled from: rsx/app/frontend/clients/index/clients_datagrid.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Clients_DataGrid = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Clients_DataGrid',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "card DataGrid"},
|
|
defineArgs: {"data_source": Frontend_Clients_Controller.datagrid_fetch, "sort": "id", "order": "desc", "per_page": "15"},
|
|
extends: 'DataGrid_Abstract',
|
|
render: function render(data, args, content, jqhtml) { return [{_slots: {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
DG_Card_Header: function(DG_Card_Header) { const _output = [];
|
|
_output.push(" "); _output.push({comp: ["Card_Title", {}, function(Card_Title) {
|
|
const _output = [];
|
|
_output.push("Client List");
|
|
return [_output, this];
|
|
}.bind(this)]});
|
|
_output.push(" "); _output.push({comp: ["Card_Header_Right", {}, function(Card_Header_Right) {
|
|
const _output = [];
|
|
_output.push(" "); _output.push({comp: ["Search_Input", {"id": "filter_input" + ":" + this._cid, "data-id": "filter_input"}]}); _output.push(" "); _output.push({tag: ["button", {"class": "btn btn-secondary btn-sm"}, false]}); _output.push("Filter"); _output.push("</button>"); _output.push(" ");
|
|
return [_output, this];
|
|
}.bind(this)]});
|
|
|
|
|
|
|
|
return [_output, this]; }.bind(this),
|
|
|
|
DG_Table_Header: function(DG_Table_Header) { const _output = [];
|
|
_output.push({tag: ["tr", {}, false]}); _output.push(" "); _output.push({tag: ["th", {"style": "width: 40px;"}, false]}); _output.push(" "); _output.push({tag: ["input", {"class": "form-check-input", "type": "checkbox", "id": "select_all" + ":" + this._cid, "data-id": "select_all"}, true]}); _output.push(" "); _output.push("</th>"); _output.push({tag: ["th", {"data-sortby": "id"}, false]}); _output.push("ID"); _output.push("</th>"); _output.push(" "); _output.push({tag: ["th", {"data-sortby": "name"}, false]}); _output.push("Company Name"); _output.push("</th>"); _output.push(" "); _output.push({tag: ["th", {"data-sortby": "city"}, false]}); _output.push("Location"); _output.push("</th>"); _output.push(" "); _output.push({tag: ["th", {}, false]}); _output.push("Phone"); _output.push("</th>"); _output.push(" "); _output.push({tag: ["th", {}, false]}); _output.push("Website"); _output.push("</th>"); _output.push(" "); _output.push({tag: ["th", {"data-sortby": "priority"}, false]}); _output.push("Priority"); _output.push("</th>"); _output.push(" "); _output.push({tag: ["th", {"data-sortby": "created_at"}, false]}); _output.push("Created"); _output.push("</th>"); _output.push(" "); _output.push({tag: ["th", {"style": "width: 120px;"}, false]}); _output.push("Actions"); _output.push("</th>"); _output.push(" "); _output.push("</tr>");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return [_output, this]; }.bind(this),
|
|
|
|
row: function(row) { const _output = [];
|
|
_output.push({tag: ["tr", {"data-href": Rsx.Route('Frontend_Clients_Controller','view',row.id)}, false]}); _output.push(" "); _output.push({tag: ["td", {}, false]}); _output.push(" "); _output.push({tag: ["input", {"class": "form-check-input row-checkbox", "type": "checkbox", "value": (row.id)}, true]}); _output.push(" "); _output.push("</td>"); _output.push({tag: ["td", {}, false]}); _output.push(" "); _output.push(" #CL"); (() => { const result = String(row.id).padStart(3, '0') ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push(" "); _output.push("</td>"); _output.push({tag: ["td", {}, false]}); _output.push(" "); (() => { const result = row.name ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push(" "); _output.push("</td>"); _output.push({tag: ["td", {}, false]}); _output.push(" "); if (row.city && row.state) { (() => { const result = row.city ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push(", "); (() => { const result = row.state ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push(" "); } else if (row.city) { (() => { const result = row.city ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push(" "); } else if (row.state) { (() => { const result = row.state ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push(" "); } else { _output.push(" - "); } _output.push(" "); _output.push("</td>"); _output.push({tag: ["td", {}, false]}); (() => { const result = row.phone || '-' ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</td>"); _output.push(" "); _output.push({tag: ["td", {}, false]}); _output.push(" "); if (row.website) { _output.push({tag: ["a", {"href": (row.website), "target": "_blank", "class": "text-decoration-none"}, false]}); _output.push(" "); _output.push({tag: ["i", {"class": "bi bi-link-45deg"}, false]}); _output.push("</i>"); _output.push(" "); _output.push("</a>"); } else { _output.push(" - "); } _output.push(" "); _output.push("</td>"); _output.push({tag: ["td", {}, false]}); _output.push(" "); if (row.priority === 4) { _output.push({tag: ["span", {"class": "badge bg-danger"}, false]}); _output.push("Urgent"); _output.push("</span>"); _output.push(" "); } else if (row.priority === 3) { _output.push({tag: ["span", {"class": "badge bg-warning"}, false]}); _output.push("High"); _output.push("</span>"); _output.push(" "); } else if (row.priority === 2) { _output.push({tag: ["span", {"class": "badge bg-primary"}, false]}); _output.push("Medium"); _output.push("</span>"); _output.push(" "); } else { _output.push({tag: ["span", {"class": "badge bg-secondary"}, false]}); _output.push("Low"); _output.push("</span>"); _output.push(" "); } _output.push("</td>"); _output.push({tag: ["td", {}, false]}); (() => { const result = new Date(row.created_at).toLocaleDateString() ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</td>"); _output.push(" "); _output.push({tag: ["td", {}, false]}); _output.push(" "); _output.push({tag: ["div", {"class": "btn-group btn-group-sm"}, false]}); _output.push(" "); _output.push({tag: ["a", {"class": "btn btn-outline-primary", "href": "/clients/view/" + (row.id), "title": "View"}, false]}); _output.push(" "); _output.push({tag: ["i", {"class": "bi bi-eye"}, false]}); _output.push("</i>"); _output.push(" "); _output.push("</a>"); _output.push({tag: ["a", {"class": "btn btn-outline-secondary", "href": "#", "title": "Edit"}, false]}); _output.push(" "); _output.push({tag: ["i", {"class": "bi bi-pencil"}, false]}); _output.push("</i>"); _output.push(" "); _output.push("</a>"); _output.push({tag: ["button", {"class": "btn btn-outline-danger", "type": "button", "title": "Delete"}, false]}); _output.push(" "); _output.push({tag: ["i", {"class": "bi bi-trash"}, false]}); _output.push("</i>"); _output.push(" "); _output.push("</button>"); _output.push("</div>"); _output.push("</td>"); _output.push("</tr>");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return [_output, this]; }.bind(this) }}, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Clients_DataGrid);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_a0ed24b2f2a26a2c.js === */
|
|
/* Compiled from: rsx/app/frontend/settings/user_management/add_user_modal_form.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Add_User_Modal_Form = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Add_User_Modal_Form',
|
|
tag: 'div',
|
|
defaultAttributes: {},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_output.push(" ");
|
|
_output.push({comp: ["Rsx_Form", {"data-controller": "Frontend_Settings_User_Management_Controller", "data-method": "add_user"}, function(Rsx_Form) { let _output = [];
|
|
_output.push(" ");
|
|
_output.push({tag: ["div", {"class": "mb-3"}, false]}); _output.push(" "); _output.push({comp: ["Form_Field", {"data-name": "email", "data-label": "Email Address", "data-required": true}, function(Form_Field) {
|
|
const _output = [];
|
|
_output.push(" "); _output.push({comp: ["Text_Input", {"data-type": "email", "data-placeholder": "user@example.com", "data-autofocus": true}]}); _output.push(" ");
|
|
return [_output, this];
|
|
}.bind(this)]}); _output.push("</div>");
|
|
|
|
|
|
|
|
|
|
|
|
_output.push({tag: ["div", {"class": "row"}, false]}); _output.push(" "); _output.push({tag: ["div", {"class": "col-md-6 mb-3"}, false]}); _output.push(" "); _output.push({comp: ["Form_Field", {"data-name": "first_name", "data-label": "First Name", "data-required": true}, function(Form_Field) {
|
|
const _output = [];
|
|
_output.push(" "); _output.push({comp: ["Text_Input", {}]}); _output.push(" ");
|
|
return [_output, this];
|
|
}.bind(this)]}); _output.push("</div>"); _output.push({tag: ["div", {"class": "col-md-6 mb-3"}, false]}); _output.push(" "); _output.push({comp: ["Form_Field", {"data-name": "last_name", "data-label": "Last Name", "data-required": true}, function(Form_Field) {
|
|
const _output = [];
|
|
_output.push(" "); _output.push({comp: ["Text_Input", {}]}); _output.push(" ");
|
|
return [_output, this];
|
|
}.bind(this)]}); _output.push("</div>"); _output.push("</div>");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_output.push({tag: ["div", {"class": "mb-3"}, false]}); _output.push(" "); _output.push({comp: ["Form_Field", {"data-name": "role_id", "data-label": "Role", "data-required": true}, function(Form_Field) {
|
|
const _output = [];
|
|
_output.push(" "); _output.push({comp: ["Select_Input", {"data-options": (JSON.stringify([ {value: 3, label: 'Member'}, {value: 2, label: 'Admin'}, {value: 1, label: 'Owner'}, {value: 4, label: 'Viewer'} ]))}]}); _output.push(" ");
|
|
return [_output, this];
|
|
}.bind(this)]}); _output.push("</div>");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_output.push({tag: ["div", {"class": "mb-3"}, false]}); _output.push(" "); _output.push({comp: ["Form_Field", {"data-name": "phone", "data-label": "Phone Number"}, function(Form_Field) {
|
|
const _output = [];
|
|
_output.push(" "); _output.push({comp: ["Phone_Text_Input", {"data-placeholder": "(555) 123-4567"}]}); _output.push(" ");
|
|
return [_output, this];
|
|
}.bind(this)]}); _output.push("</div>");
|
|
|
|
|
|
|
|
|
|
|
|
return [_output, this]; }.bind(this)]});
|
|
|
|
return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Add_User_Modal_Form);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_b1ddcd786055dd48.js === */
|
|
/* Compiled from: rsx/app/frontend/settings/user_management/users_datagrid.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Users_DataGrid = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Users_DataGrid',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "card DataGrid"},
|
|
defineArgs: {"data_source": Frontend_Settings_User_Management_Controller.datagrid_fetch, "sort": "id", "order": "desc", "per_page": "15"},
|
|
extends: 'DataGrid_Abstract',
|
|
render: function render(data, args, content, jqhtml) { return [{_slots: {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
DG_Card_Header: function(DG_Card_Header) { const _output = [];
|
|
_output.push(" "); _output.push({comp: ["Card_Title", {}, function(Card_Title) {
|
|
const _output = [];
|
|
_output.push("User List");
|
|
return [_output, this];
|
|
}.bind(this)]});
|
|
_output.push(" "); _output.push({comp: ["Card_Header_Right", {}, function(Card_Header_Right) {
|
|
const _output = [];
|
|
_output.push(" "); _output.push({comp: ["Search_Input", {"id": "filter_input" + ":" + this._cid, "data-id": "filter_input"}]}); _output.push(" "); _output.push({tag: ["button", {"class": "btn btn-secondary btn-sm"}, false]}); _output.push("Filter"); _output.push("</button>"); _output.push(" ");
|
|
return [_output, this];
|
|
}.bind(this)]});
|
|
|
|
|
|
|
|
return [_output, this]; }.bind(this),
|
|
|
|
DG_Table_Header: function(DG_Table_Header) { const _output = [];
|
|
_output.push({tag: ["tr", {}, false]}); _output.push(" "); _output.push({tag: ["th", {"style": "width: 40px;"}, false]}); _output.push(" "); _output.push({tag: ["input", {"class": "form-check-input", "type": "checkbox", "id": "select_all" + ":" + this._cid, "data-id": "select_all"}, true]}); _output.push(" "); _output.push("</th>"); _output.push({tag: ["th", {"data-sortby": "id"}, false]}); _output.push("ID"); _output.push("</th>"); _output.push(" "); _output.push({tag: ["th", {"data-sortby": "first_name"}, false]}); _output.push("Name"); _output.push("</th>"); _output.push(" "); _output.push({tag: ["th", {"data-sortby": "email"}, false]}); _output.push("Email"); _output.push("</th>"); _output.push(" "); _output.push({tag: ["th", {}, false]}); _output.push("Status"); _output.push("</th>"); _output.push(" "); _output.push({tag: ["th", {}, false]}); _output.push("Phone"); _output.push("</th>"); _output.push(" "); _output.push({tag: ["th", {"data-sortby": "user_role_id"}, false]}); _output.push("Role"); _output.push("</th>"); _output.push(" "); _output.push({tag: ["th", {"data-sortby": "created_at"}, false]}); _output.push("Created"); _output.push("</th>"); _output.push(" "); _output.push({tag: ["th", {"style": "width: 120px;"}, false]}); _output.push("Actions"); _output.push("</th>"); _output.push(" "); _output.push("</tr>");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return [_output, this]; }.bind(this),
|
|
|
|
row: function(row) { const _output = [];
|
|
_output.push({tag: ["tr", {"data-href": (Rsx.Route('Frontend_Settings_User_Management_Controller', 'view', row.id))}, false]}); _output.push(" "); _output.push({tag: ["td", {}, false]}); _output.push(" "); _output.push({tag: ["input", {"class": "form-check-input row-checkbox", "type": "checkbox", "value": (row.id)}, true]}); _output.push(" "); _output.push("</td>"); _output.push({tag: ["td", {}, false]}); _output.push(" "); _output.push(" #U"); (() => { const result = String(row.id).padStart(3, '0') ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push(" "); _output.push("</td>"); _output.push({tag: ["td", {}, false]}); _output.push(" "); if (row.first_name || row.last_name) { (() => { const result = row.first_name ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push(" "); (() => { const result = row.last_name ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push(" "); } else { _output.push({tag: ["em", {"class": "text-muted"}, false]}); _output.push("No name set"); _output.push("</em>"); _output.push(" "); } _output.push("</td>"); _output.push({tag: ["td", {}, false]}); _output.push(" "); (() => { const result = row.email ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push(" "); _output.push("</td>"); _output.push({tag: ["td", {}, false]}); _output.push(" "); if (row.invitation_status === 'accepted') { _output.push({tag: ["span", {"class": "badge bg-success"}, false]}); _output.push("Active"); _output.push("</span>"); _output.push(" "); } else if (row.invitation_status === 'expired') { _output.push({tag: ["span", {"class": "badge bg-danger"}, false]}); _output.push("Expired"); _output.push("</span>"); _output.push(" "); } else { _output.push({tag: ["span", {"class": "badge bg-warning"}, false]}); _output.push("Invited"); _output.push("</span>"); _output.push(" "); } _output.push("</td>"); _output.push({tag: ["td", {}, false]}); (() => { const result = row.phone || '-' ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</td>"); _output.push(" "); _output.push({tag: ["td", {}, false]}); _output.push(" "); if (row.user_role_id_label) { _output.push({tag: ["span", {"class": "badge bg-primary"}, false]}); (() => { const result = row.user_role_id_label ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</span>"); _output.push(" "); } else { _output.push({tag: ["span", {"class": "badge bg-secondary"}, false]}); _output.push("User"); _output.push("</span>"); _output.push(" "); } _output.push("</td>"); _output.push({tag: ["td", {}, false]}); (() => { const result = new Date(row.created_at).toLocaleDateString() ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</td>"); _output.push(" "); _output.push({tag: ["td", {}, false]}); _output.push(" "); _output.push({tag: ["div", {"class": "btn-group btn-group-sm"}, false]}); _output.push(" "); _output.push({tag: ["a", {"class": "btn btn-outline-primary", "href": (Rsx.Route('Frontend_Settings_User_Management_Controller', 'view', row.id)), "title": "View"}, false]}); _output.push(" "); _output.push({tag: ["i", {"class": "bi bi-eye"}, false]}); _output.push("</i>"); _output.push(" "); _output.push("</a>"); _output.push({tag: ["a", {"class": "btn btn-outline-secondary", "href": "#", "title": "Edit"}, false]}); _output.push(" "); _output.push({tag: ["i", {"class": "bi bi-pencil"}, false]}); _output.push("</i>"); _output.push(" "); _output.push("</a>"); _output.push({tag: ["button", {"class": "btn btn-outline-danger", "type": "button", "title": "Delete"}, false]}); _output.push(" "); _output.push({tag: ["i", {"class": "bi bi-trash"}, false]}); _output.push("</i>"); _output.push(" "); _output.push("</button>"); _output.push("</div>"); _output.push("</td>"); _output.push("</tr>");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return [_output, this]; }.bind(this) }}, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Users_DataGrid);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_999138a7ad9fb892.js === */
|
|
/* Compiled from: rsx/app/frontend/settings/user_management/edit_user_modal_form.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Edit_User_Modal_Form = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Edit_User_Modal_Form',
|
|
tag: 'div',
|
|
defaultAttributes: {},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_output.push(" ");
|
|
_output.push({comp: ["Rsx_Form", {"data-controller": "Frontend_Settings_User_Management_Controller", "data-method": "save_user", "data-data": (JSON.stringify(this.args.data))}, function(Rsx_Form) { let _output = [];
|
|
_output.push(" ");
|
|
_output.push({comp: ["Form_Hidden_Field", {"data-name": "id"}]});
|
|
_output.push(" ");
|
|
_output.push({tag: ["div", {"class": "mb-3"}, false]}); _output.push(" "); _output.push({comp: ["Form_Field", {"data-name": "email", "data-label": "Email Address", "data-required": true}, function(Form_Field) {
|
|
const _output = [];
|
|
_output.push(" "); _output.push({comp: ["Text_Input", {"data-type": "email", "data-placeholder": "user@example.com", "data-autofocus": true}]}); _output.push(" ");
|
|
return [_output, this];
|
|
}.bind(this)]}); _output.push("</div>");
|
|
|
|
|
|
|
|
|
|
|
|
_output.push({tag: ["div", {"class": "row"}, false]}); _output.push(" "); _output.push({tag: ["div", {"class": "col-md-6 mb-3"}, false]}); _output.push(" "); _output.push({comp: ["Form_Field", {"data-name": "first_name", "data-label": "First Name", "data-required": true}, function(Form_Field) {
|
|
const _output = [];
|
|
_output.push(" "); _output.push({comp: ["Text_Input", {}]}); _output.push(" ");
|
|
return [_output, this];
|
|
}.bind(this)]}); _output.push("</div>"); _output.push({tag: ["div", {"class": "col-md-6 mb-3"}, false]}); _output.push(" "); _output.push({comp: ["Form_Field", {"data-name": "last_name", "data-label": "Last Name", "data-required": true}, function(Form_Field) {
|
|
const _output = [];
|
|
_output.push(" "); _output.push({comp: ["Text_Input", {}]}); _output.push(" ");
|
|
return [_output, this];
|
|
}.bind(this)]}); _output.push("</div>"); _output.push("</div>");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_output.push({tag: ["div", {"class": "mb-3"}, false]}); _output.push(" "); _output.push({comp: ["Form_Field", {"data-name": "role_id", "data-label": "Role", "data-required": true}, function(Form_Field) {
|
|
const _output = [];
|
|
_output.push(" "); _output.push({comp: ["Select_Input", {"data-options": (JSON.stringify([ {value: 3, label: 'Member'}, {value: 2, label: 'Admin'}, {value: 1, label: 'Owner'}, {value: 4, label: 'Viewer'} ]))}]}); _output.push(" ");
|
|
return [_output, this];
|
|
}.bind(this)]}); _output.push("</div>");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_output.push({tag: ["div", {"class": "mb-3"}, false]}); _output.push(" "); _output.push({comp: ["Form_Field", {"data-name": "phone", "data-label": "Phone Number"}, function(Form_Field) {
|
|
const _output = [];
|
|
_output.push(" "); _output.push({comp: ["Phone_Text_Input", {"data-placeholder": "(555) 123-4567"}]}); _output.push(" ");
|
|
return [_output, this];
|
|
}.bind(this)]}); _output.push("</div>");
|
|
|
|
|
|
|
|
|
|
|
|
return [_output, this]; }.bind(this)]});
|
|
|
|
return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Edit_User_Modal_Form);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_2db45a178bfdaa95.js === */
|
|
/* Compiled from: rsx/app/frontend/contacts/index/contacts_datagrid.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Contacts_DataGrid = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Contacts_DataGrid',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "card DataGrid"},
|
|
defineArgs: {"data_source": Frontend_Contacts_Controller.datagrid_fetch, "sort": "id", "order": "desc", "per_page": "15"},
|
|
extends: 'DataGrid_Abstract',
|
|
render: function render(data, args, content, jqhtml) { return [{_slots: {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
DG_Card_Header: function(DG_Card_Header) { const _output = [];
|
|
_output.push(" "); _output.push({comp: ["Card_Title", {}, function(Card_Title) {
|
|
const _output = [];
|
|
_output.push("Contact List");
|
|
return [_output, this];
|
|
}.bind(this)]});
|
|
_output.push(" "); _output.push({comp: ["Card_Header_Right", {}, function(Card_Header_Right) {
|
|
const _output = [];
|
|
_output.push(" "); _output.push({comp: ["Search_Input", {"id": "filter_input" + ":" + this._cid, "data-id": "filter_input"}]}); _output.push(" "); _output.push({tag: ["button", {"class": "btn btn-secondary btn-sm"}, false]}); _output.push("Filter"); _output.push("</button>"); _output.push(" ");
|
|
return [_output, this];
|
|
}.bind(this)]});
|
|
|
|
|
|
|
|
return [_output, this]; }.bind(this),
|
|
|
|
DG_Table_Header: function(DG_Table_Header) { const _output = [];
|
|
_output.push({tag: ["tr", {}, false]}); _output.push(" "); _output.push({tag: ["th", {"style": "width: 40px;"}, false]}); _output.push(" "); _output.push({tag: ["input", {"class": "form-check-input", "type": "checkbox", "id": "select_all" + ":" + this._cid, "data-id": "select_all"}, true]}); _output.push(" "); _output.push("</th>"); _output.push({tag: ["th", {"data-sortby": "id"}, false]}); _output.push("ID"); _output.push("</th>"); _output.push(" "); _output.push({tag: ["th", {"data-sortby": "first_name"}, false]}); _output.push("Name"); _output.push("</th>"); _output.push(" "); _output.push({tag: ["th", {"data-sortby": "email"}, false]}); _output.push("Email"); _output.push("</th>"); _output.push(" "); _output.push({tag: ["th", {}, false]}); _output.push("Phone"); _output.push("</th>"); _output.push(" "); _output.push({tag: ["th", {}, false]}); _output.push("Company"); _output.push("</th>"); _output.push(" "); _output.push({tag: ["th", {}, false]}); _output.push("Role"); _output.push("</th>"); _output.push(" "); _output.push({tag: ["th", {"data-sortby": "priority"}, false]}); _output.push("Priority"); _output.push("</th>"); _output.push(" "); _output.push({tag: ["th", {"data-sortby": "created_at"}, false]}); _output.push("Created"); _output.push("</th>"); _output.push(" "); _output.push({tag: ["th", {"style": "width: 120px;"}, false]}); _output.push("Actions"); _output.push("</th>"); _output.push(" "); _output.push("</tr>");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return [_output, this]; }.bind(this),
|
|
|
|
row: function(row) { const _output = [];
|
|
|
|
_output.push({tag: ["tr", {"data-href": Rsx.Route('Frontend_Contacts_Controller','view',row.id)}, false]}); _output.push(" "); _output.push({tag: ["td", {}, false]}); _output.push(" "); _output.push({tag: ["input", {"class": "form-check-input row-checkbox", "type": "checkbox", "value": (row.id)}, true]}); _output.push(" "); _output.push("</td>"); _output.push({tag: ["td", {}, false]}); _output.push(" "); _output.push(" #CT"); (() => { const result = String(row.id).padStart(3, '0') ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push(" "); _output.push("</td>"); _output.push({tag: ["td", {}, false]}); _output.push(" "); (() => { const result = row.first_name ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push(" "); (() => { const result = row.last_name ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push(" "); _output.push("</td>"); _output.push({tag: ["td", {}, false]}); _output.push(" "); (() => { const result = row.email ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push(" "); _output.push("</td>"); _output.push({tag: ["td", {}, false]}); (() => { const result = row.phone_work || '-' ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</td>"); _output.push(" "); _output.push({tag: ["td", {}, false]}); _output.push(" "); if (row.client_id) { _output.push({comp: ["Client_Label", {"data-client_id": row.client_id}]}); _output.push(" "); } else { _output.push(" - "); } _output.push(" "); _output.push("</td>"); _output.push({tag: ["td", {}, false]}); _output.push("-"); _output.push("</td>"); _output.push(" "); _output.push({tag: ["td", {}, false]}); _output.push(" "); if (row.priority === 4) { _output.push({tag: ["span", {"class": "badge bg-danger"}, false]}); _output.push("Urgent"); _output.push("</span>"); _output.push(" "); } else if (row.priority === 3) { _output.push({tag: ["span", {"class": "badge bg-warning"}, false]}); _output.push("High"); _output.push("</span>"); _output.push(" "); } else if (row.priority === 2) { _output.push({tag: ["span", {"class": "badge bg-primary"}, false]}); _output.push("Medium"); _output.push("</span>"); _output.push(" "); } else { _output.push({tag: ["span", {"class": "badge bg-secondary"}, false]}); _output.push("Low"); _output.push("</span>"); _output.push(" "); } _output.push("</td>"); _output.push({tag: ["td", {}, false]}); (() => { const result = new Date(row.created_at).toLocaleDateString() ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</td>"); _output.push(" "); _output.push({tag: ["td", {}, false]}); _output.push(" "); _output.push({tag: ["div", {"class": "btn-group btn-group-sm"}, false]}); _output.push(" "); _output.push({tag: ["a", {"class": "btn btn-outline-primary", "href": "/contacts/view/" + (row.id), "title": "View"}, false]}); _output.push(" "); _output.push({tag: ["i", {"class": "bi bi-eye"}, false]}); _output.push("</i>"); _output.push(" "); _output.push("</a>"); _output.push({tag: ["a", {"class": "btn btn-outline-secondary", "href": "#", "title": "Edit"}, false]}); _output.push(" "); _output.push({tag: ["i", {"class": "bi bi-pencil"}, false]}); _output.push("</i>"); _output.push(" "); _output.push("</a>"); _output.push({tag: ["button", {"class": "btn btn-outline-danger", "type": "button", "title": "Delete"}, false]}); _output.push(" "); _output.push({tag: ["i", {"class": "bi bi-trash"}, false]}); _output.push("</i>"); _output.push(" "); _output.push("</button>"); _output.push("</div>"); _output.push("</td>"); _output.push("</tr>");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return [_output, this]; }.bind(this) }}, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Contacts_DataGrid);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_e2d87387fe13db9a.js === */
|
|
/* Compiled from: rsx/app/frontend/contacts/_data_table_qq/data_table.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Data_Table = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Data_Table',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "card"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
_output.push(" ");
|
|
_output.push({tag: ["div", {"class": "card-header d-flex justify-content-between align-items-center"}, false]});
|
|
_output.push(" ");_output.push({tag: ["h5", {"class": "mb-0"}, false]}); (() => { const result = this.args.title || 'Data Table' ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</h5>");
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "d-flex gap-2"}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"id": "search_container" + ":" + this._cid, "data-id": "search_container"}, false]}); _output.push("</div>");
|
|
_output.push(" ");_output.push({tag: ["div", {"id": "filter_container" + ":" + this._cid, "data-id": "filter_container"}, false]}); _output.push("</div>");
|
|
_output.push(" ");_output.push({tag: ["div", {"id": "column_toggle_container" + ":" + this._cid, "data-id": "column_toggle_container"}, false]}); _output.push("</div>");
|
|
_output.push(" "); _output.push("</div>");
|
|
_output.push("</div>");
|
|
|
|
_output.push({comp: ["Bulk_Action_Bar", {"id": "bulk_bar" + ":" + this._cid, "data-id": "bulk_bar", "style": "display: none;"}, function(Bulk_Action_Bar) { let _output = [];
|
|
_output.push(" "); _output.push({comp: ["Button_Danger", {"id": "bulk_delete" + ":" + this._cid, "data-id": "bulk_delete"}, function(Button_Danger) {
|
|
const _output = [];
|
|
_output.push("Delete Selected");
|
|
return [_output, this];
|
|
}.bind(this)]});
|
|
_output.push(" "); _output.push({comp: ["Button_Secondary", {"id": "bulk_export" + ":" + this._cid, "data-id": "bulk_export"}, function(Button_Secondary) {
|
|
const _output = [];
|
|
_output.push("Export Selected");
|
|
return [_output, this];
|
|
}.bind(this)]});
|
|
_output.push(" "); return [_output, this]; }.bind(this)]});
|
|
|
|
_output.push({tag: ["div", {"class": "card-body p-0"}, false]});
|
|
_output.push(" ");_output.push({tag: ["div", {"class": "table-responsive"}, false]});
|
|
_output.push(" "); _output.push({comp: ["Table", {"id": "table" + ":" + this._cid, "data-id": "table"}, function(Table) { let _output = [];
|
|
_output.push(" "); _output.push({tag: ["thead", {}, false]}); _output.push(" "); _output.push({tag: ["tr", {"id": "header_row" + ":" + this._cid, "data-id": "header_row"}, false]}); _output.push(" "); if (this.args.bulk_actions) { _output.push({tag: ["th", {"style": "width: 40px;"}, false]}); _output.push(" "); _output.push({comp: ["Bulk_Selection", {"id": "bulk_selection" + ":" + this._cid, "data-id": "bulk_selection"}]}); _output.push(" "); _output.push("</th>"); } _output.push("<!-- Column headers dynamically generated -->"); _output.push(" "); _output.push("</tr>"); _output.push("</thead>");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_output.push({tag: ["tbody", {"id": "tbody" + ":" + this._cid, "data-id": "tbody"}, false]}); _output.push(" "); if (Object.keys(this.data).length === 0) { _output.push({tag: ["tr", {}, false]}); _output.push(" "); _output.push({tag: ["td", {"colspan": "100", "class": "text-center py-5"}, false]}); _output.push(" "); _output.push({comp: ["Spinner", {}]}); _output.push(" "); _output.push({tag: ["div", {"class": "mt-2 text-muted"}, false]}); _output.push("Loading data..."); _output.push("</div>"); _output.push(" "); _output.push("</td>"); _output.push("</tr>"); } else if (this.data.rows && this.data.rows.length === 0) { _output.push({tag: ["tr", {}, false]}); _output.push(" "); _output.push({tag: ["td", {"colspan": "100"}, false]}); _output.push(" "); _output.push({comp: ["Empty_State", {"data-icon": "inbox", "data-title": "No data available", "data-message": "There are no records to display"}]}); _output.push(" "); _output.push("</td>"); _output.push("</tr>"); } else { for (let row of this.data.rows || []) { _output.push({tag: ["tr", {"id": row.id + ":" + this._cid, "data-id": row.id}, false]}); _output.push(" "); if (this.args.bulk_actions) { _output.push({tag: ["td", {}, false]}); _output.push(" "); _output.push({tag: ["input", {"type": "checkbox", "class": "form-check-input row-checkbox", "value": (row.id)}, true]}); _output.push(" "); _output.push("</td>"); } for (let col of this.data.columns || []) { _output.push({tag: ["td", {}, false]}); (() => { const result = row[col.field] ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</td>"); _output.push(" "); } if (this.args.row_actions) { _output.push({tag: ["td", {}, false]}); _output.push(" "); _output.push({comp: ["Row_Action_Menu", {"id": "row_actions_" + row.id + ":" + this._cid, "data-id": "row_actions_" + row.id}, function(Row_Action_Menu) {
|
|
const _output = [];
|
|
_output.push(" "); (() => { const result = this.args.row_actions(row) ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push(" ");
|
|
return [_output, this];
|
|
}.bind(this)]}); _output.push("</td>"); } _output.push("</tr>"); } } _output.push("</tbody>");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return [_output, this]; }.bind(this)]});
|
|
_output.push("</div>");
|
|
_output.push("</div>");
|
|
|
|
_output.push({tag: ["div", {"class": "card-footer", "id": "footer" + ":" + this._cid, "data-id": "footer"}, false]});
|
|
_output.push(" "); _output.push({comp: ["Table_Pagination", {"id": "pagination" + ":" + this._cid, "data-id": "pagination", "data-start": this.data.start, "data-end": this.data.end, "data-total": this.data.total, "data-current_page": this.data.current_page, "data-total_pages": this.data.total_pages}]});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_output.push(" "); _output.push("</div>");
|
|
|
|
return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Data_Table);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_af2c362f250eb18b.js === */
|
|
/* Compiled from: rsx/app/frontend/contacts/_new_elements/Card_Header_Right.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Card_Header_Right = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Card_Header_Right',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "d-flex gap-2"},
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
|
|
(() => { if (this.args._inner_html) { _output.push(this.args._inner_html); } else if (typeof content === 'function') { const [contentInstructions] = content.call(this); _output.push(['_content', contentInstructions]); } })(); _output.push(" "); return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Card_Header_Right);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_ae868a09468038cb.js === */
|
|
/* Compiled from: rsx/app/frontend/contacts/edit/form/client_selector_input.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Client_Selector_Input = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Client_Selector_Input',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "Widget"},
|
|
extends: 'Ajax_Select_Input',
|
|
render: function render(data, args, content, jqhtml) { let _output = []; const _cid = this._cid; const that = this;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_output.push(" ");_output.push({tag: ["select", Object.assign({}, {"id": "input" + ":" + this._cid, "data-id": "input"}, ((this.args.disabled)) ? {"disabled": "true"} : {}), false]});
|
|
_output.push(" "); if (!this.data.select_values || this.data.select_values.length === 0) {
|
|
_output.push(" ");_output.push({tag: ["option", {"value": ""}, false]}); (() => { const result = this.args.placeholder || 'Please wait...' ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</option>");
|
|
_output.push(" "); } else {
|
|
_output.push(" "); if (this.args.placeholder) {
|
|
_output.push(" ");_output.push({tag: ["option", {"value": ""}, false]}); (() => { const result = this.args.placeholder ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</option>");
|
|
_output.push(" "); }
|
|
_output.push(" "); for (let opt of this.data.select_values) {
|
|
_output.push(" "); if (typeof opt === 'object') {
|
|
_output.push(" ");_output.push({tag: ["option", Object.assign({}, {"value": (opt.value)}, ((this.data.value == opt.value)) ? {"selected": "true"} : {}), false]}); (() => { const result = opt.label ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</option>");
|
|
_output.push(" "); } else {
|
|
_output.push(" ");_output.push({tag: ["option", Object.assign({}, {"value": (opt)}, ((this.data.value == opt)) ? {"selected": "true"} : {}), false]}); (() => { const result = opt ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</option>");
|
|
_output.push(" "); }
|
|
_output.push(" "); }
|
|
_output.push(" "); }
|
|
_output.push(" "); _output.push("</select>");
|
|
return [_output, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Client_Selector_Input);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/jqhtml_54d7ab6b9e7b33ca.js === */
|
|
/* Compiled from: rsx/app/frontend/projects/index/projects_datagrid.jqhtml */ (function() {
|
|
'use strict';
|
|
|
|
const template_Projects_DataGrid = {
|
|
_jqhtml_version: '2.2.185',
|
|
name: 'Projects_DataGrid',
|
|
tag: 'div',
|
|
defaultAttributes: {"class": "card DataGrid"},
|
|
defineArgs: {"data_source": Frontend_Projects_Controller.datagrid_fetch, "sort": "created_at", "per_page": "15"},
|
|
extends: 'DataGrid_Abstract',
|
|
render: function render(data, args, content, jqhtml) { return [{_slots: {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
DG_Card_Header: function(DG_Card_Header) { const _output = [];
|
|
_output.push(" "); _output.push({comp: ["Card_Title", {}, function(Card_Title) {
|
|
const _output = [];
|
|
_output.push("Project List");
|
|
return [_output, this];
|
|
}.bind(this)]});
|
|
_output.push(" "); _output.push({comp: ["Card_Header_Right", {}, function(Card_Header_Right) {
|
|
const _output = [];
|
|
_output.push(" "); _output.push({comp: ["Search_Input", {"id": "filter_input" + ":" + this._cid, "data-id": "filter_input"}]}); _output.push(" "); _output.push({tag: ["button", {"class": "btn btn-secondary btn-sm"}, false]}); _output.push("Filter"); _output.push("</button>"); _output.push(" ");
|
|
return [_output, this];
|
|
}.bind(this)]});
|
|
|
|
|
|
|
|
return [_output, this]; }.bind(this),
|
|
|
|
DG_Table_Header: function(DG_Table_Header) { const _output = [];
|
|
_output.push({tag: ["tr", {}, false]}); _output.push(" "); _output.push({tag: ["th", {"style": "width: 40px;"}, false]}); _output.push(" "); _output.push({tag: ["input", {"class": "form-check-input", "type": "checkbox", "id": "select_all" + ":" + this._cid, "data-id": "select_all"}, true]}); _output.push(" "); _output.push("</th>"); _output.push({tag: ["th", {"data-sortby": "id"}, false]}); _output.push("ID"); _output.push("</th>"); _output.push(" "); _output.push({tag: ["th", {"data-sortby": "name"}, false]}); _output.push("Project Name"); _output.push("</th>"); _output.push(" "); _output.push({tag: ["th", {"data-sortby": "client_id"}, false]}); _output.push("Client"); _output.push("</th>"); _output.push(" "); _output.push({tag: ["th", {"data-sortby": "status"}, false]}); _output.push("Status"); _output.push("</th>"); _output.push(" "); _output.push({tag: ["th", {"data-sortby": "priority"}, false]}); _output.push("Priority"); _output.push("</th>"); _output.push(" "); _output.push({tag: ["th", {"data-sortby": "start_date"}, false]}); _output.push("Start Date"); _output.push("</th>"); _output.push(" "); _output.push({tag: ["th", {"data-sortby": "due_date"}, false]}); _output.push("Due Date"); _output.push("</th>"); _output.push(" "); _output.push({tag: ["th", {"data-sortby": "created_at"}, false]}); _output.push("Created"); _output.push("</th>"); _output.push(" "); _output.push({tag: ["th", {"style": "width: 120px;"}, false]}); _output.push("Actions"); _output.push("</th>"); _output.push(" "); _output.push("</tr>");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return [_output, this]; }.bind(this),
|
|
|
|
row: function(row) { const _output = [];
|
|
_output.push({tag: ["tr", {"data-href": Rsx.Route('Frontend_Projects_Controller','view',row.id)}, false]}); _output.push(" "); _output.push({tag: ["td", {}, false]}); _output.push(" "); _output.push({tag: ["input", {"class": "form-check-input row-checkbox", "type": "checkbox", "value": (row.id)}, true]}); _output.push(" "); _output.push("</td>"); _output.push({tag: ["td", {}, false]}); _output.push(" "); _output.push(" #PR"); (() => { const result = String(row.id).padStart(3, '0') ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push(" "); _output.push("</td>"); _output.push({tag: ["td", {}, false]}); _output.push(" "); (() => { const result = row.name ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push(" "); _output.push("</td>"); _output.push({tag: ["td", {}, false]}); _output.push(" "); if (row.client) { (() => { const result = row.client.name ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push(" "); } else { _output.push(" - "); } _output.push(" "); _output.push("</td>"); _output.push({tag: ["td", {}, false]}); _output.push(" "); if (row.status === 1) { _output.push({tag: ["span", {"class": "badge bg-info"}, false]}); _output.push("Planning"); _output.push("</span>"); _output.push(" "); } else if (row.status === 2) { _output.push({tag: ["span", {"class": "badge bg-success"}, false]}); _output.push("Active"); _output.push("</span>"); _output.push(" "); } else if (row.status === 3) { _output.push({tag: ["span", {"class": "badge bg-warning"}, false]}); _output.push("On Hold"); _output.push("</span>"); _output.push(" "); } else if (row.status === 4) { _output.push({tag: ["span", {"class": "badge bg-primary"}, false]}); _output.push("Completed"); _output.push("</span>"); _output.push(" "); } else if (row.status === 5) { _output.push({tag: ["span", {"class": "badge bg-secondary"}, false]}); _output.push("Cancelled"); _output.push("</span>"); _output.push(" "); } _output.push("</td>"); _output.push({tag: ["td", {}, false]}); _output.push(" "); if (row.priority === 4) { _output.push({tag: ["span", {"class": "badge bg-danger"}, false]}); _output.push("Urgent"); _output.push("</span>"); _output.push(" "); } else if (row.priority === 3) { _output.push({tag: ["span", {"class": "badge bg-warning"}, false]}); _output.push("High"); _output.push("</span>"); _output.push(" "); } else if (row.priority === 2) { _output.push({tag: ["span", {"class": "badge bg-primary"}, false]}); _output.push("Medium"); _output.push("</span>"); _output.push(" "); } else { _output.push({tag: ["span", {"class": "badge bg-secondary"}, false]}); _output.push("Low"); _output.push("</span>"); _output.push(" "); } _output.push("</td>"); _output.push({tag: ["td", {}, false]}); (() => { const result = row.start_date ? new Date(row.start_date).toLocaleDateString() : '-' ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</td>"); _output.push(" "); _output.push({tag: ["td", {}, false]}); (() => { const result = row.due_date ? new Date(row.due_date).toLocaleDateString() : '-' ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</td>"); _output.push(" "); _output.push({tag: ["td", {}, false]}); (() => { const result = new Date(row.created_at).toLocaleDateString() ; if (Array.isArray(result)) { if (result.length === 2 && Array.isArray(result[0])) { _output.push(...result[0]); } else { _output.push(...result); } } else { _output.push(jqhtml.escape_html(result)); } })(); _output.push("</td>"); _output.push(" "); _output.push({tag: ["td", {}, false]}); _output.push(" "); _output.push({tag: ["div", {"class": "btn-group btn-group-sm"}, false]}); _output.push(" "); _output.push({tag: ["a", {"class": "btn btn-outline-primary", "href": (Rsx.Route('Frontend_Projects_Controller', 'view', row.id)), "title": "View"}, false]}); _output.push(" "); _output.push({tag: ["i", {"class": "bi bi-eye"}, false]}); _output.push("</i>"); _output.push(" "); _output.push("</a>"); _output.push({tag: ["a", {"class": "btn btn-outline-secondary", "href": "#", "title": "Edit"}, false]}); _output.push(" "); _output.push({tag: ["i", {"class": "bi bi-pencil"}, false]}); _output.push("</i>"); _output.push(" "); _output.push("</a>"); _output.push({tag: ["button", {"class": "btn btn-outline-danger", "type": "button", "title": "Delete"}, false]}); _output.push(" "); _output.push({tag: ["i", {"class": "bi bi-trash"}, false]}); _output.push("</i>"); _output.push(" "); _output.push("</button>"); _output.push("</div>"); _output.push("</td>"); _output.push("</tr>");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return [_output, this]; }.bind(this) }}, this]; },
|
|
dependencies: []
|
|
};
|
|
|
|
// Self-register with jqhtml runtime
|
|
// Must use window.jqhtml since we're in bundle scope
|
|
if (!window.jqhtml) {
|
|
throw new Error('FATAL: window.jqhtml is not defined. The jqhtml runtime must be loaded before registering templates.');
|
|
}
|
|
|
|
// Auto-register following standard jqhtml pattern
|
|
window.jqhtml.register_template(template_Projects_DataGrid);
|
|
})();
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/bundle_Frontend_Bundle_8f0d6431.js === */
|
|
// JavaScript Manifest - Generated by BundleCompiler
|
|
// Registers all classes in this bundle for runtime introspection
|
|
Manifest._define([
|
|
[Manifest, "Manifest", null],
|
|
[Rsx_Behaviors, "Rsx_Behaviors", null],
|
|
[Rsx_Cache, "Rsx_Cache", null],
|
|
[Rsx_Init, "Rsx_Init", null],
|
|
[Rsx_Js_Model, "Rsx_Js_Model", null],
|
|
[Rsx_View_Transitions, "Rsx_View_Transitions", null],
|
|
[ReadWriteLock, "ReadWriteLock", null],
|
|
[Form_Utils, "Form_Utils", null],
|
|
[Debugger, "Debugger", null],
|
|
[Rsx_Jq_Helpers, "Rsx_Jq_Helpers", null],
|
|
[Rsx, "Rsx", null],
|
|
[Ajax, "Ajax", null],
|
|
[Component, "Component", _Base_Jqhtml_Component],
|
|
[Jqhtml_Integration, "Jqhtml_Integration", null],
|
|
[DataGrid_Abstract, "DataGrid_Abstract", Component],
|
|
[Activity_Feed, "Activity_Feed", Component],
|
|
[Actor_Reference, "Actor_Reference", Component],
|
|
[Advanced_Search_Panel, "Advanced_Search_Panel", Component],
|
|
[Alert_Banner, "Alert_Banner", Component],
|
|
[Avatar, "Avatar", Component],
|
|
[Blockquote, "Blockquote", Component],
|
|
[Breadcrumbs, "Breadcrumbs", Component],
|
|
[Bulk_Action_Bar, "Bulk_Action_Bar", Component],
|
|
[Bulk_Selection, "Bulk_Selection", Component],
|
|
[Button_Group, "Button_Group", Component],
|
|
[Button_Primary, "Button_Primary", Component],
|
|
[Button_Secondary, "Button_Secondary", Component],
|
|
[Button, "Button", Component],
|
|
[Calendar_Event, "Calendar_Event", Component],
|
|
[Calendar_Grid, "Calendar_Grid", Component],
|
|
[Card, "Card", Component],
|
|
[Chart_Component, "Chart_Component", Component],
|
|
[Checkbox, "Checkbox", Component],
|
|
[Code_Block, "Code_Block", Component],
|
|
[Column_Visibility_Toggle, "Column_Visibility_Toggle", Component],
|
|
[Comment_Thread, "Comment_Thread", Component],
|
|
[Date_Picker, "Date_Picker", Component],
|
|
[Dropdown_Menu, "Dropdown_Menu", Component],
|
|
[Empty_State, "Empty_State", Component],
|
|
[Export_Button, "Export_Button", Component],
|
|
[File_Upload, "File_Upload", Component],
|
|
[Filter_Bar, "Filter_Bar", Component],
|
|
[Form_Actions_Component, "Form_Actions_Component", Component],
|
|
[Form_Field_Group, "Form_Field_Group", Component],
|
|
[Form_Group_Component, "Form_Group_Component", Component],
|
|
[Form_Row_Component, "Form_Row_Component", Component],
|
|
[Form_Validation_Message, "Form_Validation_Message", Component],
|
|
[Gantt_Chart, "Gantt_Chart", Component],
|
|
[Icon_Button, "Icon_Button", Component],
|
|
[Icon_With_Label, "Icon_With_Label", Component],
|
|
[Icon_With_Text, "Icon_With_Text", Component],
|
|
[Icon, "Icon", Component],
|
|
[Info_Box, "Info_Box", Component],
|
|
[Inline_Edit_Field, "Inline_Edit_Field", Component],
|
|
[Input_With_Icon, "Input_With_Icon", Component],
|
|
[Input_With_Validation, "Input_With_Validation", Component],
|
|
[Input, "Input", Component],
|
|
[Kanban_Board, "Kanban_Board", Component],
|
|
[Link, "Link", Component],
|
|
[List, "List", Component],
|
|
[Loading_Skeleton, "Loading_Skeleton", Component],
|
|
[Metric_Card, "Metric_Card", Component],
|
|
[Mobile_Header, "Mobile_Header", Component],
|
|
[Modal_Dialog, "Modal_Dialog", Component],
|
|
[Multi_Select, "Multi_Select", Component],
|
|
[Notification_Badge, "Notification_Badge", Component],
|
|
[Notification_Dropdown, "Notification_Dropdown", Component],
|
|
[Overdue_Indicator, "Overdue_Indicator", Component],
|
|
[Page_Header, "Page_Header", Component],
|
|
[Page_Section, "Page_Section", Component],
|
|
[Page, "Page", Component],
|
|
[Popover, "Popover", Component],
|
|
[Progress_Bar, "Progress_Bar", Component],
|
|
[Radio_Button, "Radio_Button", Component],
|
|
[Rich_Text_Editor, "Rich_Text_Editor", Component],
|
|
[Row_Action_Menu, "Row_Action_Menu", Component],
|
|
[Sample_Datagrid_Component, "Sample_Datagrid_Component", Component],
|
|
[Search_Bar, "Search_Bar", Component],
|
|
[Searchable_Select, "Searchable_Select", Component],
|
|
[Select_Dropdown, "Select_Dropdown", Component],
|
|
[Sidebar_Nav, "Sidebar_Nav", Component],
|
|
[Sortable_Column_Header, "Sortable_Column_Header", Component],
|
|
[Spinner, "Spinner", Component],
|
|
[Stat_Card, "Stat_Card", Component],
|
|
[Status_Badge, "Status_Badge", Component],
|
|
[Tab_Content, "Tab_Content", Component],
|
|
[Table_Pagination, "Table_Pagination", Component],
|
|
[Table, "Table", Component],
|
|
[Tabs, "Tabs", Component],
|
|
[Tag_Group, "Tag_Group", Component],
|
|
[Tag, "Tag", Component],
|
|
[Text_Display, "Text_Display", Component],
|
|
[Textarea, "Textarea", Component],
|
|
[Three_Column_Layout, "Three_Column_Layout", Component],
|
|
[Time_Picker, "Time_Picker", Component],
|
|
[Timeline, "Timeline", Component],
|
|
[Timestamp_Display, "Timestamp_Display", Component],
|
|
[Tooltip, "Tooltip", Component],
|
|
[Top_Nav, "Top_Nav", Component],
|
|
[Trend_Indicator, "Trend_Indicator", Component],
|
|
[Two_Column_Layout, "Two_Column_Layout", Component],
|
|
[User_Avatar_Dropdown, "User_Avatar_Dropdown", Component],
|
|
[Modal_Abstract, "Modal_Abstract", null],
|
|
[Rsx_Modal, "Rsx_Modal", Component],
|
|
[Modal, "Modal", null],
|
|
[Breadcrumb_Item, "Breadcrumb_Item", Component],
|
|
[Client_Label_Link, "Client_Label_Link", Component],
|
|
[Client_Label, "Client_Label", Component],
|
|
[Form_Input_Abstract, "Form_Input_Abstract", Component],
|
|
[Text_Input, "Text_Input", Form_Input_Abstract],
|
|
[Checkbox_Input, "Checkbox_Input", Form_Input_Abstract],
|
|
[Wysiwyg_Input, "Wysiwyg_Input", Form_Input_Abstract],
|
|
[Select_Input, "Select_Input", Form_Input_Abstract],
|
|
[Ajax_Select_Input, "Ajax_Select_Input", Select_Input],
|
|
[Currency_Input, "Currency_Input", Text_Input],
|
|
[Phone_Text_Input, "Phone_Text_Input", Text_Input],
|
|
[State_Select_Input, "State_Select_Input", Ajax_Select_Input],
|
|
[Country_Select_Input, "Country_Select_Input", Ajax_Select_Input],
|
|
[Profile_Photo_Input, "Profile_Photo_Input", Form_Input_Abstract],
|
|
[Rsx_Tabs, "Rsx_Tabs", Component],
|
|
[Rsx_Tab, "Rsx_Tab", Component],
|
|
[Rsx_Form, "Rsx_Form", Component],
|
|
[Pin_Verification_Form, "Pin_Verification_Form", Rsx_Form],
|
|
[Form_Field_Abstract, "Form_Field_Abstract", Component],
|
|
[Form_Field, "Form_Field", Form_Field_Abstract],
|
|
[Form_Hidden_Field, "Form_Hidden_Field", Form_Field_Abstract],
|
|
[Frontend_Dashboard, "Frontend_Dashboard", null],
|
|
[Clients_DataGrid, "Clients_DataGrid", DataGrid_Abstract],
|
|
[Frontend_Clients_Edit, "Frontend_Clients_Edit", null],
|
|
[Frontend_Clients_View, "Frontend_Clients_View", null],
|
|
[Frontend_Clients, "Frontend_Clients", null],
|
|
[Frontend_Settings_Team, "Frontend_Settings_Team", null],
|
|
[Frontend_Settings_Notifications, "Frontend_Settings_Notifications", null],
|
|
[Frontend_Settings_Billing, "Frontend_Settings_Billing", null],
|
|
[Frontend_Settings_Import, "Frontend_Settings_Import", null],
|
|
[Frontend_Settings_Api, "Frontend_Settings_Api", null],
|
|
[Frontend_Settings_Templates, "Frontend_Settings_Templates", null],
|
|
[Frontend_Settings_Audit, "Frontend_Settings_Audit", null],
|
|
[Frontend_Settings_Profile_Display, "Frontend_Settings_Profile_Display", null],
|
|
[Frontend_Settings_User_Settings, "Frontend_Settings_User_Settings", null],
|
|
[Frontend_Settings_Password_Security, "Frontend_Settings_Password_Security", null],
|
|
[Frontend_Settings_Api_Keys, "Frontend_Settings_Api_Keys", null],
|
|
[Users_DataGrid, "Users_DataGrid", DataGrid_Abstract],
|
|
[Add_User_Form, "Add_User_Form", Component],
|
|
[Add_User_Modal, "Add_User_Modal", Modal_Abstract],
|
|
[Send_User_Invite_Modal, "Send_User_Invite_Modal", Modal_Abstract],
|
|
[Frontend_Settings_User_Management, "Frontend_Settings_User_Management", null],
|
|
[Edit_User_Modal, "Edit_User_Modal", Modal_Abstract],
|
|
[Frontend_Settings_User_Management_View, "Frontend_Settings_User_Management_View", null],
|
|
[Frontend_Settings_Site_Settings, "Frontend_Settings_Site_Settings", null],
|
|
[Frontend_Settings, "Frontend_Settings", null],
|
|
[Contacts_DataGrid, "Contacts_DataGrid", DataGrid_Abstract],
|
|
[Data_Table, "Data_Table", Component],
|
|
[Client_Selector_Input, "Client_Selector_Input", Ajax_Select_Input],
|
|
[Frontend_Contacts_Edit, "Frontend_Contacts_Edit", null],
|
|
[Frontend_Contacts_View, "Frontend_Contacts_View", null],
|
|
[Frontend_Contacts, "Frontend_Contacts", null],
|
|
[Projects_DataGrid, "Projects_DataGrid", DataGrid_Abstract],
|
|
[Frontend_Projects_Edit, "Frontend_Projects_Edit", null],
|
|
[Frontend_Projects_List, "Frontend_Projects_List", null],
|
|
[Frontend_Projects_View, "Frontend_Projects_View", null],
|
|
[Frontend_Projects_Add, "Frontend_Projects_Add", null],
|
|
[Frontend_Projects, "Frontend_Projects", null],
|
|
[Frontend_Tasks, "Frontend_Tasks", null],
|
|
[Frontend_Tasks_View, "Frontend_Tasks_View", null],
|
|
[Frontend_Tasks_Add, "Frontend_Tasks_Add", null],
|
|
[Frontend_Calendar, "Frontend_Calendar", null],
|
|
[Frontend_Calendar_Event, "Frontend_Calendar_Event", null],
|
|
[Frontend_Invoices, "Frontend_Invoices", null],
|
|
[Frontend_Invoices_View, "Frontend_Invoices_View", null],
|
|
[Frontend_Invoices_Add, "Frontend_Invoices_Add", null],
|
|
[Frontend_Reports, "Frontend_Reports", null],
|
|
[Frontend_Reports_Revenue, "Frontend_Reports_Revenue", null],
|
|
[Frontend_Reports_Clients, "Frontend_Reports_Clients", null],
|
|
[Frontend_Reports_Projects, "Frontend_Reports_Projects", null],
|
|
[Frontend_Reports_Time, "Frontend_Reports_Time", null],
|
|
[Frontend_Account, "Frontend_Account", null]
|
|
]);
|
|
|
|
|
|
|
|
/* === storage/rsx-tmp/bundle_Frontend_Bundle_bedffa98.js === */
|
|
// RSX Route Definitions - Generated by BundleCompiler
|
|
// Provides route patterns for type-safe URL generation
|
|
Rsx._define_routes({
|
|
"Frontend_Dashboard_Controller": {
|
|
"index": "/dashboard"
|
|
},
|
|
"Frontend_Clients_Controller": {
|
|
"index": "/clients",
|
|
"view": "/clients/view/:id",
|
|
"add": "/clients/add",
|
|
"edit": "/clients/edit/:id"
|
|
},
|
|
"Frontend_Settings_Team_Controller": {
|
|
"index": "/frontend/settings/team"
|
|
},
|
|
"Frontend_Settings_Notifications_Controller": {
|
|
"index": "/frontend/settings/notifications"
|
|
},
|
|
"Frontend_Settings_Billing_Controller": {
|
|
"index": "/frontend/settings/billing"
|
|
},
|
|
"Frontend_Settings_Import_Controller": {
|
|
"index": "/frontend/settings/import"
|
|
},
|
|
"Frontend_Settings_Api_Controller": {
|
|
"index": "/frontend/settings/api"
|
|
},
|
|
"Frontend_Settings_Templates_Controller": {
|
|
"index": "/frontend/settings/templates"
|
|
},
|
|
"Frontend_Settings_Audit_Controller": {
|
|
"index": "/frontend/settings/audit"
|
|
},
|
|
"Frontend_Settings_Account_Controller": {
|
|
"index": "/frontend/settings/account"
|
|
},
|
|
"Frontend_Settings_General_Controller": {
|
|
"index": "/frontend/settings/general"
|
|
},
|
|
"Frontend_Settings_Profile_Controller": {
|
|
"index": "/frontend/settings/profile"
|
|
},
|
|
"Frontend_Settings_Profile_Display_Controller": {
|
|
"index": "/frontend/settings/profile_display"
|
|
},
|
|
"Frontend_Settings_Profile_Edit_Controller": {
|
|
"index": "/frontend/settings/profile_edit"
|
|
},
|
|
"Frontend_Settings_User_Settings_Controller": {
|
|
"index": "/frontend/settings/user_settings"
|
|
},
|
|
"Frontend_Settings_Password_Security_Controller": {
|
|
"index": "/frontend/settings/password_security"
|
|
},
|
|
"Frontend_Settings_Api_Keys_Controller": {
|
|
"index": "/frontend/settings/api_keys"
|
|
},
|
|
"Frontend_Settings_User_Management_Controller": {
|
|
"index": "/frontend/settings/user_management",
|
|
"view": "/frontend/settings/user_management/:id"
|
|
},
|
|
"Frontend_Settings_Site_Settings_Controller": {
|
|
"index": "/frontend/settings/site_settings"
|
|
},
|
|
"Frontend_Contacts_Controller": {
|
|
"index": "/contacts",
|
|
"view": "/contacts/view/:id",
|
|
"add": "/contacts/add",
|
|
"edit": "/contacts/edit/:id"
|
|
},
|
|
"Frontend_Projects_Controller": {
|
|
"index": "/projects",
|
|
"view": "/projects/view/:id",
|
|
"add": "/projects/add",
|
|
"edit": "/projects/edit/:id"
|
|
},
|
|
"Frontend_Tasks_Controller": {
|
|
"index": "/tasks"
|
|
},
|
|
"Frontend_Tasks_View_Controller": {
|
|
"index": "/tasks/view"
|
|
},
|
|
"Frontend_Tasks_Add_Controller": {
|
|
"index": "/tasks/add"
|
|
},
|
|
"Frontend_Calendar_Controller": {
|
|
"index": "/calendar"
|
|
},
|
|
"Frontend_Calendar_Event_Controller": {
|
|
"index": "/calendar/event"
|
|
},
|
|
"Frontend_Invoices_Controller": {
|
|
"index": "/invoices"
|
|
},
|
|
"Frontend_Invoices_View_Controller": {
|
|
"index": "/invoices/view"
|
|
},
|
|
"Frontend_Invoices_Add_Controller": {
|
|
"index": "/invoices/add"
|
|
},
|
|
"Frontend_Reports_Clients_Controller": {
|
|
"index": "/reports/clients"
|
|
},
|
|
"Frontend_Reports_Controller": {
|
|
"index": "/reports"
|
|
},
|
|
"Frontend_Reports_Projects_Controller": {
|
|
"index": "/reports/projects"
|
|
},
|
|
"Frontend_Reports_Revenue_Controller": {
|
|
"index": "/reports/revenue"
|
|
},
|
|
"Frontend_Reports_Time_Controller": {
|
|
"index": "/reports/time"
|
|
},
|
|
"Frontend_Account_Controller": {
|
|
"index": "/frontend/account"
|
|
}
|
|
});
|
|
|
|
|
|
/* === storage/rsx-tmp/bundle_Frontend_Bundle_e83e43d3.js === */
|
|
$(document).ready(async function() {
|
|
try {
|
|
console_debug('RSX_INIT', 'Document ready, starting Rsx._rsx_core_boot');
|
|
await Rsx._rsx_core_boot();
|
|
console_debug('RSX_INIT', 'Initialization complete');
|
|
} catch (error) {
|
|
console.error('[RSX_INIT] Initialization failed:', error);
|
|
console.error('[RSX_INIT] Stack:', error.stack);
|
|
throw error;
|
|
}
|
|
});
|
|
|
|
|
|
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInN0b3JhZ2UvcnN4LXRtcC9idW5kbGVfY29uZmlnX0Zyb250ZW5kX0J1bmRsZS5qcyIsInN0b3JhZ2UvcnN4LXRtcC9ucG1faW1wb3J0X2RlY2xhcmF0aW9uc185NWE2ZjYwMmM5ODAzNzYxMWI2NDBiMGI1MzQyODMwYi5qcyIsImFwcC9SU3BhZGUvQ29yZS9Kcy9kZWNvcmF0b3IuanMiLCJhcHAvUlNwYWRlL0NvcmUvSnMvYnJvd3Nlci5qcyIsImFwcC9SU3BhZGUvQ29yZS9Kcy9kYXRldGltZS5qcyIsImFwcC9SU3BhZGUvQ29yZS9Kcy9lcnJvci5qcyIsImFwcC9SU3BhZGUvQ29yZS9Kcy9oYXNoLmpzIiwiYXBwL1JTcGFkZS9Db3JlL0pzL011dGV4LmpzIiwiYXBwL1JTcGFkZS9Db3JlL0pzL2FzeW5jLmpzIiwiYXBwL1JTcGFkZS9Db3JlL0pzL2Z1bmN0aW9ucy5qcyIsInJzeC90aGVtZS9xdWlsbC9xdWlsbF9jZG4uanMiLCJyc3gvYXBwL2Zyb250ZW5kL2NsaWVudHMvZWRpdC9zYXZlX2NsaWVudC5qcyIsInJzeC9hcHAvZnJvbnRlbmQvY29udGFjdHMvZWRpdC9zYXZlX2NvbnRhY3QuanMiLCJhcHAvUlNwYWRlL0NvcmUvSnMvTWFuaWZlc3QuanMiLCJhcHAvUlNwYWRlL0NvcmUvSnMvUnN4X0JlaGF2aW9ycy5qcyIsImFwcC9SU3BhZGUvQ29yZS9Kcy9Sc3hfQ2FjaGUuanMiLCJhcHAvUlNwYWRlL0NvcmUvSnMvUnN4X0luaXQuanMiLCJhcHAvUlNwYWRlL0NvcmUvSnMvUnN4X0pzX01vZGVsLmpzIiwiYXBwL1JTcGFkZS9Db3JlL0pzL1JzeF9WaWV3X1RyYW5zaXRpb25zLmpzIiwiYXBwL1JTcGFkZS9Db3JlL0pzL1JlYWRXcml0ZUxvY2suanMiLCJhcHAvUlNwYWRlL0NvcmUvSnMvRm9ybV9VdGlscy5qcyIsImFwcC9SU3BhZGUvQ29yZS9Kcy9EZWJ1Z2dlci5qcyIsImFwcC9SU3BhZGUvQ29yZS9Kcy9Sc3hfSnFfSGVscGVycy5qcyIsImFwcC9SU3BhZGUvQ29yZS9Kcy9Sc3guanMiLCJhcHAvUlNwYWRlL0NvcmUvSnMvQWpheC5qcyIsImFwcC9SU3BhZGUvSW50ZWdyYXRpb25zL0pxaHRtbC9KcWh0bWxfQ29tcG9uZW50LmpzIiwiYXBwL1JTcGFkZS9JbnRlZ3JhdGlvbnMvSnFodG1sL0pxaHRtbF9JbnRlZ3JhdGlvbi5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL2RhdGFncmlkL2RhdGFncmlkX2Fic3RyYWN0LmpzIiwicnN4L3RoZW1lL2NvbXBvbmVudHMvX2FyY2hpdmVkL3VuZmluaXNoZWQvQWN0aXZpdHlfRmVlZC5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL19hcmNoaXZlZC91bmZpbmlzaGVkL0FjdG9yX1JlZmVyZW5jZS5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL19hcmNoaXZlZC91bmZpbmlzaGVkL0FkdmFuY2VkX1NlYXJjaF9QYW5lbC5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL19hcmNoaXZlZC91bmZpbmlzaGVkL0FsZXJ0X0Jhbm5lci5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL19hcmNoaXZlZC91bmZpbmlzaGVkL0F2YXRhci5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL19hcmNoaXZlZC91bmZpbmlzaGVkL0Jsb2NrcXVvdGUuanMiLCJyc3gvdGhlbWUvY29tcG9uZW50cy9fYXJjaGl2ZWQvdW5maW5pc2hlZC9CcmVhZGNydW1icy5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL19hcmNoaXZlZC91bmZpbmlzaGVkL0J1bGtfQWN0aW9uX0Jhci5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL19hcmNoaXZlZC91bmZpbmlzaGVkL0J1bGtfU2VsZWN0aW9uLmpzIiwicnN4L3RoZW1lL2NvbXBvbmVudHMvX2FyY2hpdmVkL3VuZmluaXNoZWQvYnV0dG9uX2dyb3VwLmpzIiwicnN4L3RoZW1lL2NvbXBvbmVudHMvX2FyY2hpdmVkL3VuZmluaXNoZWQvYnV0dG9uX3ByaW1hcnkuanMiLCJyc3gvdGhlbWUvY29tcG9uZW50cy9fYXJjaGl2ZWQvdW5maW5pc2hlZC9idXR0b25fc2Vjb25kYXJ5LmpzIiwicnN4L3RoZW1lL2NvbXBvbmVudHMvX2FyY2hpdmVkL3VuZmluaXNoZWQvYnV0dG9uLmpzIiwicnN4L3RoZW1lL2NvbXBvbmVudHMvX2FyY2hpdmVkL3VuZmluaXNoZWQvQ2FsZW5kYXJfRXZlbnQuanMiLCJyc3gvdGhlbWUvY29tcG9uZW50cy9fYXJjaGl2ZWQvdW5maW5pc2hlZC9DYWxlbmRhcl9HcmlkLmpzIiwicnN4L3RoZW1lL2NvbXBvbmVudHMvX2FyY2hpdmVkL3VuZmluaXNoZWQvQ2FyZC5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL19hcmNoaXZlZC91bmZpbmlzaGVkL0NoYXJ0X0NvbXBvbmVudC5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL19hcmNoaXZlZC91bmZpbmlzaGVkL0NoZWNrYm94LmpzIiwicnN4L3RoZW1lL2NvbXBvbmVudHMvX2FyY2hpdmVkL3VuZmluaXNoZWQvQ29kZV9CbG9jay5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL19hcmNoaXZlZC91bmZpbmlzaGVkL0NvbHVtbl9WaXNpYmlsaXR5X1RvZ2dsZS5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL19hcmNoaXZlZC91bmZpbmlzaGVkL0NvbW1lbnRfVGhyZWFkLmpzIiwicnN4L3RoZW1lL2NvbXBvbmVudHMvX2FyY2hpdmVkL3VuZmluaXNoZWQvRGF0ZV9QaWNrZXIuanMiLCJyc3gvdGhlbWUvY29tcG9uZW50cy9fYXJjaGl2ZWQvdW5maW5pc2hlZC9Ecm9wZG93bl9NZW51LmpzIiwicnN4L3RoZW1lL2NvbXBvbmVudHMvX2FyY2hpdmVkL3VuZmluaXNoZWQvRW1wdHlfU3RhdGUuanMiLCJyc3gvdGhlbWUvY29tcG9uZW50cy9fYXJjaGl2ZWQvdW5maW5pc2hlZC9FeHBvcnRfQnV0dG9uLmpzIiwicnN4L3RoZW1lL2NvbXBvbmVudHMvX2FyY2hpdmVkL3VuZmluaXNoZWQvRmlsZV9VcGxvYWQuanMiLCJyc3gvdGhlbWUvY29tcG9uZW50cy9fYXJjaGl2ZWQvdW5maW5pc2hlZC9GaWx0ZXJfQmFyLmpzIiwicnN4L3RoZW1lL2NvbXBvbmVudHMvX2FyY2hpdmVkL3VuZmluaXNoZWQvZm9ybV9hY3Rpb25zX2NvbXBvbmVudC5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL19hcmNoaXZlZC91bmZpbmlzaGVkL0Zvcm1fRmllbGRfR3JvdXAuanMiLCJyc3gvdGhlbWUvY29tcG9uZW50cy9fYXJjaGl2ZWQvdW5maW5pc2hlZC9mb3JtX2dyb3VwX2NvbXBvbmVudC5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL19hcmNoaXZlZC91bmZpbmlzaGVkL2Zvcm1fcm93X2NvbXBvbmVudC5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL19hcmNoaXZlZC91bmZpbmlzaGVkL0Zvcm1fVmFsaWRhdGlvbl9NZXNzYWdlLmpzIiwicnN4L3RoZW1lL2NvbXBvbmVudHMvX2FyY2hpdmVkL3VuZmluaXNoZWQvR2FudHRfQ2hhcnQuanMiLCJyc3gvdGhlbWUvY29tcG9uZW50cy9fYXJjaGl2ZWQvdW5maW5pc2hlZC9pY29uX2J1dHRvbi5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL19hcmNoaXZlZC91bmZpbmlzaGVkL0ljb25fV2l0aF9MYWJlbC5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL19hcmNoaXZlZC91bmZpbmlzaGVkL0ljb25fV2l0aF9UZXh0LmpzIiwicnN4L3RoZW1lL2NvbXBvbmVudHMvX2FyY2hpdmVkL3VuZmluaXNoZWQvaWNvbi5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL19hcmNoaXZlZC91bmZpbmlzaGVkL0luZm9fQm94LmpzIiwicnN4L3RoZW1lL2NvbXBvbmVudHMvX2FyY2hpdmVkL3VuZmluaXNoZWQvSW5saW5lX0VkaXRfRmllbGQuanMiLCJyc3gvdGhlbWUvY29tcG9uZW50cy9fYXJjaGl2ZWQvdW5maW5pc2hlZC9JbnB1dF9XaXRoX0ljb24uanMiLCJyc3gvdGhlbWUvY29tcG9uZW50cy9fYXJjaGl2ZWQvdW5maW5pc2hlZC9JbnB1dF9XaXRoX1ZhbGlkYXRpb24uanMiLCJyc3gvdGhlbWUvY29tcG9uZW50cy9fYXJjaGl2ZWQvdW5maW5pc2hlZC9JbnB1dC5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL19hcmNoaXZlZC91bmZpbmlzaGVkL0thbmJhbl9Cb2FyZC5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL19hcmNoaXZlZC91bmZpbmlzaGVkL2xpbmsuanMiLCJyc3gvdGhlbWUvY29tcG9uZW50cy9fYXJjaGl2ZWQvdW5maW5pc2hlZC9MaXN0LmpzIiwicnN4L3RoZW1lL2NvbXBvbmVudHMvX2FyY2hpdmVkL3VuZmluaXNoZWQvTG9hZGluZ19Ta2VsZXRvbi5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL19hcmNoaXZlZC91bmZpbmlzaGVkL01ldHJpY19DYXJkLmpzIiwicnN4L3RoZW1lL2NvbXBvbmVudHMvX2FyY2hpdmVkL3VuZmluaXNoZWQvTW9iaWxlX0hlYWRlci5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL19hcmNoaXZlZC91bmZpbmlzaGVkL01vZGFsX0RpYWxvZy5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL19hcmNoaXZlZC91bmZpbmlzaGVkL011bHRpX1NlbGVjdC5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL19hcmNoaXZlZC91bmZpbmlzaGVkL05vdGlmaWNhdGlvbl9CYWRnZS5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL19hcmNoaXZlZC91bmZpbmlzaGVkL05vdGlmaWNhdGlvbl9Ecm9wZG93bi5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL19hcmNoaXZlZC91bmZpbmlzaGVkL092ZXJkdWVfSW5kaWNhdG9yLmpzIiwicnN4L3RoZW1lL2NvbXBvbmVudHMvX2FyY2hpdmVkL3VuZmluaXNoZWQvUGFnZV9IZWFkZXIuanMiLCJyc3gvdGhlbWUvY29tcG9uZW50cy9fYXJjaGl2ZWQvdW5maW5pc2hlZC9wYWdlX3NlY3Rpb24uanMiLCJyc3gvdGhlbWUvY29tcG9uZW50cy9fYXJjaGl2ZWQvdW5maW5pc2hlZC9wYWdlLmpzIiwicnN4L3RoZW1lL2NvbXBvbmVudHMvX2FyY2hpdmVkL3VuZmluaXNoZWQvUG9wb3Zlci5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL19hcmNoaXZlZC91bmZpbmlzaGVkL1Byb2dyZXNzX0Jhci5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL19hcmNoaXZlZC91bmZpbmlzaGVkL1JhZGlvX0J1dHRvbi5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL19hcmNoaXZlZC91bmZpbmlzaGVkL1JpY2hfVGV4dF9FZGl0b3IuanMiLCJyc3gvdGhlbWUvY29tcG9uZW50cy9fYXJjaGl2ZWQvdW5maW5pc2hlZC9Sb3dfQWN0aW9uX01lbnUuanMiLCJyc3gvdGhlbWUvY29tcG9uZW50cy9fYXJjaGl2ZWQvdW5maW5pc2hlZC9TYW1wbGVfRGF0YWdyaWRfQ29tcG9uZW50LmpzIiwicnN4L3RoZW1lL2NvbXBvbmVudHMvX2FyY2hpdmVkL3VuZmluaXNoZWQvU2VhcmNoX0Jhci5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL19hcmNoaXZlZC91bmZpbmlzaGVkL1NlYXJjaGFibGVfU2VsZWN0LmpzIiwicnN4L3RoZW1lL2NvbXBvbmVudHMvX2FyY2hpdmVkL3VuZmluaXNoZWQvU2VsZWN0X0Ryb3Bkb3duLmpzIiwicnN4L3RoZW1lL2NvbXBvbmVudHMvX2FyY2hpdmVkL3VuZmluaXNoZWQvU2lkZWJhcl9OYXYuanMiLCJyc3gvdGhlbWUvY29tcG9uZW50cy9fYXJjaGl2ZWQvdW5maW5pc2hlZC9Tb3J0YWJsZV9Db2x1bW5fSGVhZGVyLmpzIiwicnN4L3RoZW1lL2NvbXBvbmVudHMvX2FyY2hpdmVkL3VuZmluaXNoZWQvU3Bpbm5lci5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL19hcmNoaXZlZC91bmZpbmlzaGVkL1N0YXRfQ2FyZC5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL19hcmNoaXZlZC91bmZpbmlzaGVkL1N0YXR1c19CYWRnZS5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL19hcmNoaXZlZC91bmZpbmlzaGVkL1RhYl9Db250ZW50LmpzIiwicnN4L3RoZW1lL2NvbXBvbmVudHMvX2FyY2hpdmVkL3VuZmluaXNoZWQvVGFibGVfUGFnaW5hdGlvbi5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL19hcmNoaXZlZC91bmZpbmlzaGVkL1RhYmxlLmpzIiwicnN4L3RoZW1lL2NvbXBvbmVudHMvX2FyY2hpdmVkL3VuZmluaXNoZWQvVGFicy5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL19hcmNoaXZlZC91bmZpbmlzaGVkL1RhZ19Hcm91cC5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL19hcmNoaXZlZC91bmZpbmlzaGVkL1RhZy5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL19hcmNoaXZlZC91bmZpbmlzaGVkL3RleHRfZGlzcGxheS5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL19hcmNoaXZlZC91bmZpbmlzaGVkL1RleHRhcmVhLmpzIiwicnN4L3RoZW1lL2NvbXBvbmVudHMvX2FyY2hpdmVkL3VuZmluaXNoZWQvVGhyZWVfQ29sdW1uX0xheW91dC5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL19hcmNoaXZlZC91bmZpbmlzaGVkL1RpbWVfUGlja2VyLmpzIiwicnN4L3RoZW1lL2NvbXBvbmVudHMvX2FyY2hpdmVkL3VuZmluaXNoZWQvVGltZWxpbmUuanMiLCJyc3gvdGhlbWUvY29tcG9uZW50cy9fYXJjaGl2ZWQvdW5maW5pc2hlZC9UaW1lc3RhbXBfRGlzcGxheS5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL19hcmNoaXZlZC91bmZpbmlzaGVkL1Rvb2x0aXAuanMiLCJyc3gvdGhlbWUvY29tcG9uZW50cy9fYXJjaGl2ZWQvdW5maW5pc2hlZC9Ub3BfTmF2LmpzIiwicnN4L3RoZW1lL2NvbXBvbmVudHMvX2FyY2hpdmVkL3VuZmluaXNoZWQvVHJlbmRfSW5kaWNhdG9yLmpzIiwicnN4L3RoZW1lL2NvbXBvbmVudHMvX2FyY2hpdmVkL3VuZmluaXNoZWQvVHdvX0NvbHVtbl9MYXlvdXQuanMiLCJyc3gvdGhlbWUvY29tcG9uZW50cy9fYXJjaGl2ZWQvdW5maW5pc2hlZC9Vc2VyX0F2YXRhcl9Ecm9wZG93bi5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL21vZGFsL21vZGFsX2Fic3RyYWN0LmpzIiwicnN4L3RoZW1lL2NvbXBvbmVudHMvbW9kYWwvcnN4X21vZGFsLmpzIiwicnN4L3RoZW1lL2NvbXBvbmVudHMvbW9kYWwvTW9kYWwuanMiLCJyc3gvdGhlbWUvY29tcG9uZW50cy9wYWdlX2VsZW1lbnRzL2JyZWFkY3J1bWJfaXRlbS5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL3BhZ2VfZWxlbWVudHMvY2xpZW50X2xhYmVsX2xpbmsuanMiLCJyc3gvdGhlbWUvY29tcG9uZW50cy9wYWdlX2VsZW1lbnRzL2NsaWVudF9sYWJlbC5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL2lucHV0cy9mb3JtX2lucHV0X2Fic3RyYWN0LmpzIiwicnN4L3RoZW1lL2NvbXBvbmVudHMvaW5wdXRzL3RleHRfaW5wdXQuanMiLCJyc3gvdGhlbWUvY29tcG9uZW50cy9pbnB1dHMvY2hlY2tib3hfaW5wdXQuanMiLCJyc3gvdGhlbWUvY29tcG9uZW50cy9pbnB1dHMvd3lzaXd5Z19pbnB1dC5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL2lucHV0cy9zZWxlY3RfaW5wdXQuanMiLCJyc3gvdGhlbWUvY29tcG9uZW50cy9pbnB1dHMvYWpheF9zZWxlY3RfaW5wdXQuanMiLCJyc3gvdGhlbWUvY29tcG9uZW50cy9pbnB1dHMvY3VycmVuY3lfaW5wdXQuanMiLCJyc3gvdGhlbWUvY29tcG9uZW50cy9pbnB1dHMvcGhvbmVfdGV4dF9pbnB1dC5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL2lucHV0cy9zdGF0ZV9zZWxlY3RfaW5wdXQuanMiLCJyc3gvdGhlbWUvY29tcG9uZW50cy9pbnB1dHMvY291bnRyeV9zZWxlY3RfaW5wdXQuanMiLCJyc3gvdGhlbWUvY29tcG9uZW50cy9pbnB1dHMvcHJvZmlsZV9waG90b19pbnB1dC5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL2Zvcm1zL3JzeF90YWJzLmpzIiwicnN4L3RoZW1lL2NvbXBvbmVudHMvZm9ybXMvcnN4X3RhYi5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL2Zvcm1zL3JzeF9mb3JtLmpzIiwicnN4L3RoZW1lL2NvbXBvbmVudHMvZm9ybXMvcGluX3ZlcmlmaWNhdGlvbl9mb3JtLmpzIiwicnN4L3RoZW1lL2NvbXBvbmVudHMvZm9ybXMvZm9ybV9maWVsZF9hYnN0cmFjdC5qcyIsInJzeC90aGVtZS9jb21wb25lbnRzL2Zvcm1zL2Zvcm1fZmllbGQuanMiLCJyc3gvdGhlbWUvY29tcG9uZW50cy9mb3Jtcy9mb3JtX2hpZGRlbl9maWVsZC5qcyIsInJzeC9hcHAvZnJvbnRlbmQvZGFzaGJvYXJkL2Zyb250ZW5kX2Rhc2hib2FyZC5qcyIsInJzeC9hcHAvZnJvbnRlbmQvY2xpZW50cy9pbmRleC9jbGllbnRzX2RhdGFncmlkLmpzIiwicnN4L2FwcC9mcm9udGVuZC9jbGllbnRzL2VkaXQvZnJvbnRlbmRfY2xpZW50c19lZGl0LmpzIiwicnN4L2FwcC9mcm9udGVuZC9jbGllbnRzL3ZpZXcvZnJvbnRlbmRfY2xpZW50c192aWV3LmpzIiwicnN4L2FwcC9mcm9udGVuZC9jbGllbnRzL2Zyb250ZW5kX2NsaWVudHMuanMiLCJyc3gvYXBwL2Zyb250ZW5kL3NldHRpbmdzL3RlYW0vZnJvbnRlbmRfc2V0dGluZ3NfdGVhbS5qcyIsInJzeC9hcHAvZnJvbnRlbmQvc2V0dGluZ3Mvbm90aWZpY2F0aW9ucy9mcm9udGVuZF9zZXR0aW5nc19ub3RpZmljYXRpb25zLmpzIiwicnN4L2FwcC9mcm9udGVuZC9zZXR0aW5ncy9iaWxsaW5nL2Zyb250ZW5kX3NldHRpbmdzX2JpbGxpbmcuanMiLCJyc3gvYXBwL2Zyb250ZW5kL3NldHRpbmdzL2ltcG9ydC9mcm9udGVuZF9zZXR0aW5nc19pbXBvcnQuanMiLCJyc3gvYXBwL2Zyb250ZW5kL3NldHRpbmdzL2FwaS9mcm9udGVuZF9zZXR0aW5nc19hcGkuanMiLCJyc3gvYXBwL2Zyb250ZW5kL3NldHRpbmdzL3RlbXBsYXRlcy9mcm9udGVuZF9zZXR0aW5nc190ZW1wbGF0ZXMuanMiLCJyc3gvYXBwL2Zyb250ZW5kL3NldHRpbmdzL2F1ZGl0L2Zyb250ZW5kX3NldHRpbmdzX2F1ZGl0LmpzIiwicnN4L2FwcC9mcm9udGVuZC9zZXR0aW5ncy9wcm9maWxlX2Rpc3BsYXkvZnJvbnRlbmRfc2V0dGluZ3NfcHJvZmlsZV9kaXNwbGF5LmpzIiwicnN4L2FwcC9mcm9udGVuZC9zZXR0aW5ncy91c2VyX3NldHRpbmdzL2Zyb250ZW5kX3NldHRpbmdzX3VzZXJfc2V0dGluZ3MuanMiLCJyc3gvYXBwL2Zyb250ZW5kL3NldHRpbmdzL3Bhc3N3b3JkX3NlY3VyaXR5L2Zyb250ZW5kX3NldHRpbmdzX3Bhc3N3b3JkX3NlY3VyaXR5LmpzIiwicnN4L2FwcC9mcm9udGVuZC9zZXR0aW5ncy9hcGlfa2V5cy9mcm9udGVuZF9zZXR0aW5nc19hcGlfa2V5cy5qcyIsInJzeC9hcHAvZnJvbnRlbmQvc2V0dGluZ3MvdXNlcl9tYW5hZ2VtZW50L3VzZXJzX2RhdGFncmlkLmpzIiwicnN4L2FwcC9mcm9udGVuZC9zZXR0aW5ncy91c2VyX21hbmFnZW1lbnQvYWRkX3VzZXJfZm9ybS5qcyIsInJzeC9hcHAvZnJvbnRlbmQvc2V0dGluZ3MvdXNlcl9tYW5hZ2VtZW50L2FkZF91c2VyX21vZGFsLmpzIiwicnN4L2FwcC9mcm9udGVuZC9zZXR0aW5ncy91c2VyX21hbmFnZW1lbnQvc2VuZF91c2VyX2ludml0ZV9tb2RhbC5qcyIsInJzeC9hcHAvZnJvbnRlbmQvc2V0dGluZ3MvdXNlcl9tYW5hZ2VtZW50L2Zyb250ZW5kX3NldHRpbmdzX3VzZXJfbWFuYWdlbWVudC5qcyIsInJzeC9hcHAvZnJvbnRlbmQvc2V0dGluZ3MvdXNlcl9tYW5hZ2VtZW50L2VkaXRfdXNlcl9tb2RhbC5qcyIsInJzeC9hcHAvZnJvbnRlbmQvc2V0dGluZ3MvdXNlcl9tYW5hZ2VtZW50L2Zyb250ZW5kX3NldHRpbmdzX3VzZXJfbWFuYWdlbWVudF92aWV3LmpzIiwicnN4L2FwcC9mcm9udGVuZC9zZXR0aW5ncy9zaXRlX3NldHRpbmdzL2Zyb250ZW5kX3NldHRpbmdzX3NpdGVfc2V0dGluZ3MuanMiLCJyc3gvYXBwL2Zyb250ZW5kL3NldHRpbmdzL2Zyb250ZW5kX3NldHRpbmdzLmpzIiwicnN4L2FwcC9mcm9udGVuZC9jb250YWN0cy9pbmRleC9jb250YWN0c19kYXRhZ3JpZC5qcyIsInJzeC9hcHAvZnJvbnRlbmQvY29udGFjdHMvX2RhdGFfdGFibGVfcXEvRGF0YV9UYWJsZS5qcyIsInJzeC9hcHAvZnJvbnRlbmQvY29udGFjdHMvZWRpdC9mb3JtL2NsaWVudF9zZWxlY3Rvcl9pbnB1dC5qcyIsInJzeC9hcHAvZnJvbnRlbmQvY29udGFjdHMvZWRpdC9mcm9udGVuZF9jb250YWN0c19lZGl0LmpzIiwicnN4L2FwcC9mcm9udGVuZC9jb250YWN0cy92aWV3L2Zyb250ZW5kX2NvbnRhY3RzX3ZpZXcuanMiLCJyc3gvYXBwL2Zyb250ZW5kL2NvbnRhY3RzL2Zyb250ZW5kX2NvbnRhY3RzLmpzIiwicnN4L2FwcC9mcm9udGVuZC9wcm9qZWN0cy9pbmRleC9wcm9qZWN0c19kYXRhZ3JpZC5qcyIsInJzeC9hcHAvZnJvbnRlbmQvcHJvamVjdHMvZWRpdC9mcm9udGVuZF9wcm9qZWN0c19lZGl0LmpzIiwicnN4L2FwcC9mcm9udGVuZC9wcm9qZWN0cy9mcm9udGVuZF9wcm9qZWN0c19saXN0LmpzIiwicnN4L2FwcC9mcm9udGVuZC9wcm9qZWN0cy9mcm9udGVuZF9wcm9qZWN0c192aWV3LmpzIiwicnN4L2FwcC9mcm9udGVuZC9wcm9qZWN0cy9mcm9udGVuZF9wcm9qZWN0c19hZGQuanMiLCJyc3gvYXBwL2Zyb250ZW5kL3Byb2plY3RzL2Zyb250ZW5kX3Byb2plY3RzLmpzIiwicnN4L2FwcC9mcm9udGVuZC90YXNrcy9mcm9udGVuZF90YXNrcy5qcyIsInJzeC9hcHAvZnJvbnRlbmQvdGFza3MvZnJvbnRlbmRfdGFza3Nfdmlldy5qcyIsInJzeC9hcHAvZnJvbnRlbmQvdGFza3MvZnJvbnRlbmRfdGFza3NfYWRkLmpzIiwicnN4L2FwcC9mcm9udGVuZC9jYWxlbmRhci9mcm9udGVuZF9jYWxlbmRhci5qcyIsInJzeC9hcHAvZnJvbnRlbmQvY2FsZW5kYXIvZnJvbnRlbmRfY2FsZW5kYXJfZXZlbnQuanMiLCJyc3gvYXBwL2Zyb250ZW5kL2ludm9pY2VzL2Zyb250ZW5kX2ludm9pY2VzLmpzIiwicnN4L2FwcC9mcm9udGVuZC9pbnZvaWNlcy9mcm9udGVuZF9pbnZvaWNlc192aWV3LmpzIiwicnN4L2FwcC9mcm9udGVuZC9pbnZvaWNlcy9mcm9udGVuZF9pbnZvaWNlc19hZGQuanMiLCJyc3gvYXBwL2Zyb250ZW5kL3JlcG9ydHMvZnJvbnRlbmRfcmVwb3J0cy5qcyIsInJzeC9hcHAvZnJvbnRlbmQvcmVwb3J0cy9mcm9udGVuZF9yZXBvcnRzX3JldmVudWUuanMiLCJyc3gvYXBwL2Zyb250ZW5kL3JlcG9ydHMvZnJvbnRlbmRfcmVwb3J0c19jbGllbnRzLmpzIiwicnN4L2FwcC9mcm9udGVuZC9yZXBvcnRzL2Zyb250ZW5kX3JlcG9ydHNfcHJvamVjdHMuanMiLCJyc3gvYXBwL2Zyb250ZW5kL3JlcG9ydHMvZnJvbnRlbmRfcmVwb3J0c190aW1lLmpzIiwicnN4L2FwcC9mcm9udGVuZC9hY2NvdW50L2Zyb250ZW5kX2FjY291bnQuanMiLCJkYXRhZ3JpZF9hYnN0cmFjdC5qcWh0bWwiLCJhY3Rpb25fYnV0dG9uX2RlbGV0ZS5qcWh0bWwiLCJhY3Rpb25fYnV0dG9uX2VkaXQuanFodG1sIiwiYWN0aW9uX2J1dHRvbl92aWV3LmpxaHRtbCIsImFjdGl2aXR5X2ZlZWQuanFodG1sIiwiYWN0b3JfcmVmZXJlbmNlLmpxaHRtbCIsImFkdmFuY2VkX3NlYXJjaF9wYW5lbC5qcWh0bWwiLCJhbGVydF9iYW5uZXIuanFodG1sIiwiYXZhdGFyLmpxaHRtbCIsImJsb2NrcXVvdGUuanFodG1sIiwiYnJlYWRjcnVtYnMuanFodG1sIiwiYnVsa19hY3Rpb25fYmFyLmpxaHRtbCIsImJ1bGtfc2VsZWN0aW9uLmpxaHRtbCIsImJ1dHRvbl9ncm91cC5qcWh0bWwiLCJidXR0b25fcHJpbWFyeS5qcWh0bWwiLCJidXR0b25fc2Vjb25kYXJ5LmpxaHRtbCIsImJ1dHRvbi5qcWh0bWwiLCJjYWxlbmRhcl9ldmVudC5qcWh0bWwiLCJjYWxlbmRhcl9ncmlkLmpxaHRtbCIsImNhcmRfZm9vdGVyLmpxaHRtbCIsImNhcmRfaGVhZGVyLmpxaHRtbCIsImNhcmRfdGl0bGUuanFodG1sIiwiY2FyZC5qcWh0bWwiLCJjaGFydF9jb21wb25lbnQuanFodG1sIiwiY2hlY2tib3guanFodG1sIiwiY29kZV9ibG9jay5qcWh0bWwiLCJjb2x1bW5fdmlzaWJpbGl0eV90b2dnbGUuanFodG1sIiwiY29tbWVudF90aHJlYWQuanFodG1sIiwiY29udGFjdF9hY3Rpb25zLmpxaHRtbCIsImNvbnRhY3Rfcm93LmpxaHRtbCIsImNvbnRhY3RzX2RhdGFfdGFibGUuanFodG1sIiwiY29udGFjdHNfbGlzdF9jYXJkLmpxaHRtbCIsImRhdGVfcGlja2VyLmpxaHRtbCIsImRyb3Bkb3duX21lbnUuanFodG1sIiwiZW1wdHlfc3RhdGUuanFodG1sIiwiZXhwb3J0X2J1dHRvbi5qcWh0bWwiLCJmaWxlX3VwbG9hZC5qcWh0bWwiLCJmaWx0ZXJfYmFyLmpxaHRtbCIsImZvcm1fYWN0aW9uc19jb21wb25lbnQuanFodG1sIiwiZm9ybV9maWVsZF9ncm91cC5qcWh0bWwiLCJmb3JtX2dyb3VwX2NvbXBvbmVudC5qcWh0bWwiLCJmb3JtX3Jvd19jb21wb25lbnQuanFodG1sIiwiZm9ybV92YWxpZGF0aW9uX21lc3NhZ2UuanFodG1sIiwiZ2FudHRfY2hhcnQuanFodG1sIiwiaWNvbl9idXR0b24uanFodG1sIiwiaWNvbl93aXRoX2xhYmVsLmpxaHRtbCIsImljb25fd2l0aF90ZXh0LmpxaHRtbCIsImljb24uanFodG1sIiwiaW5mb19ib3guanFodG1sIiwiaW5saW5lX2VkaXRfZmllbGQuanFodG1sIiwiaW5wdXRfd2l0aF9pY29uLmpxaHRtbCIsImlucHV0X3dpdGhfdmFsaWRhdGlvbi5qcWh0bWwiLCJpbnB1dC5qcWh0bWwiLCJrYW5iYW5fYm9hcmQuanFodG1sIiwibGluay5qcWh0bWwiLCJsaXN0LmpxaHRtbCIsImxvYWRpbmdfc2tlbGV0b24uanFodG1sIiwibWV0cmljX2NhcmQuanFodG1sIiwibW9iaWxlX2hlYWRlci5qcWh0bWwiLCJtb2RhbF9kaWFsb2cuanFodG1sIiwibXVsdGlfc2VsZWN0LmpxaHRtbCIsIm5vdGlmaWNhdGlvbl9iYWRnZS5qcWh0bWwiLCJub3RpZmljYXRpb25fZHJvcGRvd24uanFodG1sIiwib3ZlcmR1ZV9pbmRpY2F0b3IuanFodG1sIiwicGFnZV9oZWFkZXJfbGVmdC5qcWh0bWwiLCJwYWdlX2hlYWRlcl9yaWdodC5qcWh0bWwiLCJwYWdlX2hlYWRlci5qcWh0bWwiLCJwYWdlX3NlY3Rpb24uanFodG1sIiwicGFnZV9zdWJ0aXRsZS5qcWh0bWwiLCJwYWdlX3RpdGxlLmpxaHRtbCIsInBhZ2UuanFodG1sIiwicGFnaW5hdGlvbl9jb250cm9scy5qcWh0bWwiLCJwYWdpbmF0aW9uX2luZm8uanFodG1sIiwicG9wb3Zlci5qcWh0bWwiLCJwcm9ncmVzc19iYXIuanFodG1sIiwicmFkaW9fYnV0dG9uLmpxaHRtbCIsInJlY29yZF9jb3VudF9kaXNwbGF5LmpxaHRtbCIsInJpY2hfdGV4dF9lZGl0b3IuanFodG1sIiwicm93X2FjdGlvbl9tZW51LmpxaHRtbCIsIlNhbXBsZV9EYXRhZ3JpZF9Db21wb25lbnQuanFodG1sIiwic2VhcmNoX2Jhci5qcWh0bWwiLCJzZWFyY2hfYnV0dG9uLmpxaHRtbCIsInNlYXJjaF9pbnB1dC5qcWh0bWwiLCJzZWFyY2hhYmxlX3NlbGVjdC5qcWh0bWwiLCJzZWxlY3RfZHJvcGRvd24uanFodG1sIiwic2lkZWJhcl9uYXYuanFodG1sIiwic2ltcGxlX3RhYmxlX3Rlc3QuanFodG1sIiwic29ydGFibGVfY29sdW1uX2hlYWRlci5qcWh0bWwiLCJzcGlubmVyLmpxaHRtbCIsInN0YXRfY2FyZC5qcWh0bWwiLCJzdGF0dXNfYmFkZ2UuanFodG1sIiwidGFiX2NvbnRlbnQuanFodG1sIiwidGFibGVfYm9keS5qcWh0bWwiLCJ0YWJsZV9oZWFkZXJzLmpxaHRtbCIsInRhYmxlX3BhZ2luYXRpb24uanFodG1sIiwidGFibGUuanFodG1sIiwidGFicy5qcWh0bWwiLCJ0YWdfZ3JvdXAuanFodG1sIiwidGFnLmpxaHRtbCIsInRleHRfZGlzcGxheS5qcWh0bWwiLCJ0ZXh0YXJlYS5qcWh0bWwiLCJ0aHJlZV9jb2x1bW5fbGF5b3V0LmpxaHRtbCIsInRpbWVfcGlja2VyLmpxaHRtbCIsInRpbWVsaW5lLmpxaHRtbCIsInRpbWVzdGFtcF9kaXNwbGF5LmpxaHRtbCIsInRvb2x0aXAuanFodG1sIiwidG9wX25hdi5qcWh0bWwiLCJ0cmVuZF9pbmRpY2F0b3IuanFodG1sIiwidHdvX2NvbHVtbl9sYXlvdXQuanFodG1sIiwidXNlcl9hdmF0YXJfZHJvcGRvd24uanFodG1sIiwidXNlcnNfZGF0YV90YWJsZS5qcWh0bWwiLCJyc3hfbW9kYWwuanFodG1sIiwiYnJlYWRjcnVtYi5qcWh0bWwiLCJicmVhZGNydW1iX2l0ZW0uanFodG1sIiwiY2xpZW50X2xhYmVsLmpxaHRtbCIsImNsaWVudF9sYWJlbF9saW5rLmpxaHRtbCIsInRleHRfaW5wdXQuanFodG1sIiwic2VsZWN0X2lucHV0LmpxaHRtbCIsImFqYXhfc2VsZWN0X2lucHV0LmpxaHRtbCIsImNoZWNrYm94X2lucHV0LmpxaHRtbCIsInd5c2l3eWdfaW5wdXQuanFodG1sIiwiY291bnRyeV9zZWxlY3RfaW5wdXQuanFodG1sIiwic3RhdGVfc2VsZWN0X2lucHV0LmpxaHRtbCIsInByb2ZpbGVfcGhvdG9faW5wdXQuanFodG1sIiwicnN4X3RhYnMuanFodG1sIiwicnN4X3RhYi5qcWh0bWwiLCJyc3hfZm9ybS5qcWh0bWwiLCJmb3JtX2ZpZWxkX2Fic3RyYWN0LmpxaHRtbCIsImZvcm1fZmllbGQuanFodG1sIiwiZm9ybV9oaWRkZW5fZmllbGQuanFodG1sIiwicGluX3ZlcmlmaWNhdGlvbl9mb3JtLmpxaHRtbCIsImNsaWVudHNfZGF0YWdyaWQuanFodG1sIiwiYWRkX3VzZXJfbW9kYWxfZm9ybS5qcWh0bWwiLCJ1c2Vyc19kYXRhZ3JpZC5qcWh0bWwiLCJlZGl0X3VzZXJfbW9kYWxfZm9ybS5qcWh0bWwiLCJjb250YWN0c19kYXRhZ3JpZC5qcWh0bWwiLCJkYXRhX3RhYmxlLmpxaHRtbCIsIkNhcmRfSGVhZGVyX1JpZ2h0LmpxaHRtbCIsImNsaWVudF9zZWxlY3Rvcl9pbnB1dC5qcWh0bWwiLCJwcm9qZWN0c19kYXRhZ3JpZC5qcWh0bWwiLCJzdG9yYWdlL3JzeC10bXAvYnVuZGxlX0Zyb250ZW5kX0J1bmRsZV84ZjBkNjQzMS5qcyIsInN0b3JhZ2UvcnN4LXRtcC9idW5kbGVfRnJvbnRlbmRfQnVuZGxlX2JlZGZmYTk4LmpzIiwic3RvcmFnZS9yc3gtdG1wL2J1bmRsZV9Gcm9udGVuZF9CdW5kbGVfZTgzZTQzZDMuanMiXSwibmFtZXMiOlsiZGVjb3JhdG9yIiwidmFsdWUiLCJpc19tb2JpbGUiLCJ0ZXN0IiwibmF2aWdhdG9yIiwidXNlckFnZW50IiwiJCIsIndpbmRvdyIsIndpZHRoIiwiaXNfZGVza3RvcCIsImdldF9vcyIsInVzZXJfYWdlbnQiLCJwbGF0Zm9ybSIsIm1hY29zX3BsYXRmb3JtcyIsIndpbmRvd3NfcGxhdGZvcm1zIiwiaW9zX3BsYXRmb3JtcyIsIm9zIiwiaXNfbW9iaWxlX2RldmljZSIsImluZGV4T2YiLCJpc19jcmF3bGVyIiwiYm90X3BhdHRlcm4iLCJzY3JvbGxfaW50b192aWV3X2lmX25lZWRlZCIsInRhcmdldCIsIiR0YXJnZXQiLCIkcGFyZW50IiwicGFyZW50IiwidGFyZ2V0X3RvcCIsInBvc2l0aW9uIiwidG9wIiwic2Nyb2xsVG9wIiwidGFyZ2V0X2hlaWdodCIsIm91dGVySGVpZ2h0IiwicGFyZW50X2hlaWdodCIsImhlaWdodCIsInNjcm9sbF9wb3NpdGlvbiIsIkRlYnVnZ2VyIiwiY29uc29sZV9kZWJ1ZyIsIm5ld19zY3JvbGxfcG9zaXRpb24iLCJNYXRoIiwibWF4IiwibWluIiwic2Nyb2xsSGVpZ2h0Iiwic2Nyb2xsX3BhZ2VfaW50b192aWV3X2lmX25lZWRlZCIsIm9mZnNldCIsIndpbmRvd19oZWlnaHQiLCJ3aW5kb3dfc2Nyb2xsX3Bvc2l0aW9uIiwiYW5pbWF0ZSIsIndhaXRfZm9yX2ltYWdlcyIsImNhbGxiYWNrIiwiJGltYWdlcyIsInRvdGFsX2ltYWdlcyIsImxlbmd0aCIsImltYWdlc19sb2FkZWQiLCJlYWNoIiwiaW1nIiwiSW1hZ2UiLCJvbmxvYWQiLCJvbmVycm9yIiwic3JjIiwiJG5ic3AiLCJlc2NhcGVfanFfc2VsZWN0b3IiLCJpZCIsInJlcGxhY2UiLCJ1bml4X3RpbWUiLCJyb3VuZCIsIkRhdGUiLCJnZXRUaW1lIiwieW1kaGlzX3RvX3VuaXgiLCJzdHJfZGF0ZSIsImRhdGUiLCJlcnJvciIsInN0ciIsImVycm9yX2NvZGUiLCJ1bmRlZiIsInN0YXR1cyIsInNob3VsZG50X2hhcHBlbiIsIm1lc3NhZ2UiLCJhcmd1bWVudHMiLCJ1bmRlZmluZWQiLCJFcnJvciIsInN0YWNrIiwic3RhY2tMaW5lcyIsInNwbGl0IiwiY2FsbGVySW5mbyIsImNhbGxlckxpbmUiLCJtYXRjaCIsImVycm9yTWVzc2FnZSIsImNvbnNvbGUiLCJyZXBlYXQiLCJmYXRhbEVycm9yIiwibmFtZSIsImhhc2giLCJ0aGVfdmFyIiwiY2FsY19zaGExIiwiaWdub3JlZF9rZXlzIiwianNvbl9zdHJpbmdpZnlfbm9jaXJjIiwiY2FjaGUiLCJKU09OIiwic3RyaW5naWZ5Iiwia2V5IiwidiIsIl9jYWNoZV9rZXkiLCJfaGFzaF9rZXkiLCJwdXNoIiwiZmxhdF92YXIiLCJfZmxhdHRlbiIsInByZWZpeCIsImRlcHRoIiwiaXNfb2JqZWN0IiwiQWJzdHJhY3QiLCJrIiwiaGFzT3duUHJvcGVydHkiLCJpc19hcnJheSIsImkiLCJmb3JlYWNoIiwiaXNfZnVuY3Rpb24iLCJpc19udW1lcmljIiwiU3RyaW5nIiwic29ydGVyIiwic29ydCIsImEiLCJiIiwianNvbiIsImhhc2hlZCIsInNoYTEiLCJkZWVwX2VxdWFsIiwibXV0ZXgiLCJnbG9iYWxfaWQiLCJpbnN0YW5jZV9tdXRleGVzIiwiX2luc3RhbmNlX3N0b3JhZ2UiLCJXZWFrTWFwIiwiZ2xvYmFsX211dGV4ZXMiLCJfZ2xvYmFsX3N0b3JhZ2UiLCJNYXAiLCJnZXRfaW5zdGFuY2VfbXV0ZXgiLCJpbnN0YW5jZSIsIm1ldGhvZF9uYW1lIiwiaW5zdGFuY2VfbG9ja3MiLCJnZXQiLCJzZXQiLCJsb2NrX3N0YXRlIiwiYWN0aXZlIiwicXVldWUiLCJnZXRfZ2xvYmFsX211dGV4Iiwic2NoZWR1bGVfbmV4dCIsImZuIiwicmVzb2x2ZSIsInJlamVjdCIsInNoaWZ0IiwiUHJvbWlzZSIsInRoZW4iLCJmaW5hbGx5IiwiYWNxdWlyZV9sb2NrIiwiZGVzY3JpcHRvciIsIm9yaWdpbmFsX21ldGhvZCIsIl9sZW4iLCJhcmdzIiwiQXJyYXkiLCJfa2V5IiwiYXBwbHkiLCJfbGVuMiIsIl9rZXkyIiwic2xlZXAiLCJtaWxsaXNlY29uZHMiLCJyZXF1ZXN0QW5pbWF0aW9uRnJhbWUiLCJzZXRUaW1lb3V0IiwiZGVib3VuY2UiLCJjYWxsYmFja19vcl9kZWxheSIsImRlbGF5IiwiaW1tZWRpYXRlIiwiZGVjb3JhdG9yX2RlbGF5IiwiZGVjb3JhdG9yX2ltbWVkaWF0ZSIsImNvbnRleHQiLCJraW5kIiwiZGVib3VuY2VfaW1wbCIsInJ1bm5pbmciLCJxdWV1ZWQiLCJsYXN0X2VuZF90aW1lIiwidGltZXIiLCJuZXh0X2FyZ3MiLCJuZXh0X2NvbnRleHQiLCJyZXNvbHZlX3F1ZXVlIiwicmVqZWN0X3F1ZXVlIiwicnVuX2Z1bmN0aW9uIiwidGhlc2VfcmVzb2x2ZXMiLCJ0aGVzZV9yZWplY3RzIiwicmVzdWx0IiwiZXJyIiwibm93IiwiY2xlYXJUaW1lb3V0IiwiZmlyc3RfY2FsbCIsInNpbmNlIiwiSW5maW5pdHkiLCJ3YWl0Iiwicndsb2NrIiwiY2IiLCJSZWFkV3JpdGVMb2NrIiwiYWNxdWlyZSIsInJ3bG9ja19yZWFkIiwiYWNxdWlyZV9yZWFkIiwicndsb2NrX2ZvcmNlX3VubG9jayIsImZvcmNlX3VubG9jayIsInJ3bG9ja19wZW5kaW5nIiwicGVuZGluZyIsIm9iaiIsInJlc3VsdHMiLCJpc0FycmF5IiwiZm9yRWFjaCIsImluZGV4IiwicHJvbWlzZXMiLCJmaWx0ZXIiLCJhbGwiLCJuIiwiaXNOYU4iLCJwYXJzZUZsb2F0IiwiaXNGaW5pdGUiLCJpc19zdHJpbmciLCJzIiwiaXNfaW50ZWdlciIsIk51bWJlciIsImlzSW50ZWdlciIsImlzX3Byb21pc2UiLCJmdW5jdGlvbl90b19jaGVjayIsInRvU3RyaW5nIiwiY2FsbCIsImlzX2VtYWlsIiwiZW1haWwiLCJyZWdleCIsImlzc2V0IiwiZW1wdHkiLCJvYmplY3QiLCJmbG9hdCIsInZhbCIsInBhcnNlZCIsImludCIsInBhcnNlSW50IiwidmFsdWVfdW5sZXNzX251bWVyaWNfc3RyaW5nX3RoZW5fbnVtZXJpY192YWx1ZSIsImh0bWwiLCJfIiwiZXNjYXBlIiwibmwyYnIiLCJodG1sYnIiLCJ1cmxlbmNvZGUiLCJlbmNvZGVVUklDb21wb25lbnQiLCJ1cmxkZWNvZGUiLCJkZWNvZGVVUklDb21wb25lbnQiLCJqc29uX2VuY29kZSIsImpzb25fZGVjb2RlIiwicGFyc2UiLCJjaGFubmVsIiwidmFsdWVzIiwicmVwbGFjZV9hbGwiLCJzdHJpbmciLCJzZWFyY2giLCJqb2luIiwidWN3b3JkcyIsImlucHV0IiwibWFwIiwid29yZCIsImNoYXJBdCIsInRvVXBwZXJDYXNlIiwic2xpY2UiLCJjb3VudCIsIm8iLCJjIiwiY2xvbmUiLCJGdW5jdGlvbiIsInByb3RvdHlwZSIsIl9fY2xvbmUiLCJ0aGF0IiwidGVtcCIsImNsb25lZCIsImNvbnN0cnVjdG9yIiwiT2JqZWN0IiwiYXNzaWduIiwiY29hbGVzY2UiLCJmcm9tIiwicmV0dXJuX3ZhbCIsImFyZyIsImNzdl90b19hcnJheV90cmltIiwic3RyX2NzdiIsInBhcnRzIiwicmV0IiwicGFydCIsInRyaW0iLCJxdWlsbF9yZWFkeSIsIlF1aWxsIiwic2F2ZV9jbGllbnQiLCJjbGllbnRfaWQiLCJyZXNwb25zZSIsIkZyb250ZW5kX0NsaWVudHNfQ29udHJvbGxlciIsInNhdmUiLCJzdWNjZXNzIiwicmVkaXJlY3QiLCJSc3giLCJSb3V0ZSIsImVycm9ycyIsIl9nZW5lcmFsIiwic2F2ZV9jb250YWN0IiwiY29udGFjdF9pZCIsIkZyb250ZW5kX0NvbnRhY3RzX0NvbnRyb2xsZXIiLCJNYW5pZmVzdCIsIl9kZWZpbmUiLCJpdGVtcyIsIl9jbGFzc2VzIiwiaXRlbSIsImNsYXNzX29iamVjdCIsImNsYXNzX25hbWUiLCJjbGFzc19leHRlbmRzIiwiZGVjb3JhdG9ycyIsImNsYXNzIiwiZXh0ZW5kcyIsIl9uYW1lIiwiX2V4dGVuZHMiLCJfZGVjb3JhdG9ycyIsIl9idWlsZF9zdWJjbGFzc19pbmRleCIsIl9zdWJjbGFzc19pbmRleCIsImNsYXNzZGF0YSIsImN1cnJlbnRfY2xhc3NfbmFtZSIsImN1cnJlbnRfY2xhc3NkYXRhIiwiZXh0ZW5kc19uYW1lIiwiaW5jbHVkZXMiLCJnZXRfZXh0ZW5kaW5nIiwiYmFzZV9jbGFzcyIsImJhc2VfY2xhc3Nfb2JqZWN0IiwiZ2V0X2NsYXNzX2J5X25hbWUiLCJjbGFzc2VzIiwianNfaXNfc3ViY2xhc3Nfb2YiLCJsb2NhbGVDb21wYXJlIiwic3ViY2xhc3MiLCJzdXBlcmNsYXNzIiwic3ViY2xhc3Nfb2JqZWN0Iiwic3VwZXJjbGFzc19vYmplY3QiLCJjdXJyZW50X2NsYXNzIiwiZ2V0X2FsbF9jbGFzc2VzIiwiYnVpbGRfa2V5IiwicnN4YXBwIiwiZ2V0X2RlY29yYXRvcnMiLCJjbGFzc19pbmZvIiwiX3RyYW5zZm9ybV9kZWNvcmF0b3JzIiwiZ2V0X2FsbF9kZWNvcmF0b3JzIiwiY29tcGFjdF9kZWNvcmF0b3JzIiwiaGFzX2RlY29yYXRvciIsImRlY29yYXRvcl9uYW1lIiwic29tZSIsImQiLCJqc19nZXRfc3ViY2xhc3Nlc19vZiIsImJhc2VfY2xhc3NfbmFtZSIsInN1YmNsYXNzX25hbWVzIiwic3ViY2xhc3Nfb2JqZWN0cyIsInN1YmNsYXNzX25hbWUiLCJuYW1lX2EiLCJuYW1lX2IiLCJSc3hfQmVoYXZpb3JzIiwiX29uX2ZyYW1ld29ya19jb3JlX2luaXQiLCJfaW5pdF9pZ25vcmVfaW52YWxpZF9hbmNob3JfbGlua3MiLCJfdHJpbV9jb3BpZWRfdGV4dCIsImRvY3VtZW50Iiwib24iLCJlIiwiJGxpbmsiLCJocmVmIiwiYXR0ciIsImlzRGVmYXVsdFByZXZlbnRlZCIsImRhdGEiLCJwcmV2ZW50RGVmYXVsdCIsInN0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbiIsInN0YXJ0c1dpdGgiLCJ0YXJnZXRJZCIsInN1YnN0cmluZyIsInRhcmdldEV4aXN0cyIsImdldEVsZW1lbnRCeUlkIiwicXVlcnlTZWxlY3RvciIsImFkZEV2ZW50TGlzdGVuZXIiLCJldmVudCIsInNoaWZ0S2V5Iiwic2VsZWN0aW9uIiwiZ2V0U2VsZWN0aW9uIiwic2VsZWN0ZWRfdGV4dCIsImNvbnRhaW5lciIsImdldFJhbmdlQXQiLCJjb21tb25BbmNlc3RvckNvbnRhaW5lciIsIm5vZGVUeXBlIiwicGFyZW50Tm9kZSIsImNsb3Nlc3QiLCJ0cmltbWVkX3RleHQiLCJjbGlwYm9hcmREYXRhIiwic2V0RGF0YSIsImxvZyIsIlJzeF9DYWNoZSIsIm9uX2NvcmVfZGVmaW5lIiwiQ29yZV9DYWNoZSIsIl9jYWNoZXMiLCJnbG9iYWwiLCJfY2FjaGVzX3NldCIsImdldF9pbnN0YW5jZSIsIk1haW4iLCJkZWJ1ZyIsImtleV9lbmNvZGVkIiwiX2VuY29kZWtleSIsImdldF9nbG9iYWwiLCJnZXRfc2Vzc2lvbiIsIl9zdXBwb3J0c1N0b3JhZ2UiLCJycyIsInNlc3Npb25TdG9yYWdlIiwiZ2V0SXRlbSIsInNldF9zZXNzaW9uIiwiX3RyeWFnYWluIiwicmVtb3ZlSXRlbSIsInNldEl0ZW0iLCJfaXNPdXRPZlNwYWNlIiwiY2xlYXIiLCJfcmVzZXQiLCJfX3N1cHBvcnRzU3RvcmFnZSIsImV4IiwiUnN4X0luaXQiLCJpc19wcm9kIiwiX19lbnZpcm9ubWVudF9jaGVja3MiLCJzY3JpcHRzIiwiZ2V0RWxlbWVudHNCeVRhZ05hbWUiLCJzY3JpcHQiLCJkZWZlciIsInJlYXNvbiIsIl9yc3hfY29yZV9ib290X3N0b3AiLCJSc3hfSnNfTW9kZWwiLCJfX01PREVMIiwibW9kZWxEYXRhIiwiZmV0Y2giLCJDdXJyZW50Q2xhc3MiLCJtb2RlbE5hbWUiLCJhamF4IiwidXJsIiwibWV0aG9kIiwiZGF0YVR5cGUiLCJfaW5zdGFudGlhdGVfbW9kZWxzX3JlY3Vyc2l2ZSIsImdldE1vZGVsTmFtZSIsInJlZnJlc2giLCJmcmVzaCIsInRvT2JqZWN0IiwidG9KU09OIiwiTW9kZWxDbGFzcyIsIlJzeF9WaWV3X1RyYW5zaXRpb25zIiwic3RhcnRWaWV3VHJhbnNpdGlvbiIsIl9pbmplY3RfdHJhbnNpdGlvbl9jc3MiLCJzdHlsZSIsImNyZWF0ZUVsZW1lbnQiLCJ0ZXh0Q29udGVudCIsImhlYWQiLCJhcHBlbmRDaGlsZCIsIl81MGFlNjA5ZV9hc3NlcnRDbGFzc0JyYW5kIiwiXzUwYWU2MDllX2dldF9sb2NrIiwid3JpdGVyX3EiLCJfNTBhZTYwOWVfc2NoZWR1bGUiLCJ3cml0ZXJfYWN0aXZlIiwicmVhZGVyX3EiLCJyZWFkZXJzIiwiX2xvY2tzIiwiZGVsZXRlIiwiXzUwYWU2MDllX1JlYWRXcml0ZUxvY2siLCJiYXRjaCIsInNwbGljZSIsIkZvcm1fVXRpbHMiLCJfb25fZnJhbWV3b3JrX2NvcmVfZGVmaW5lIiwicGFyYW1zIiwiYWpheF9zdWJtaXQiLCJvcHRpb25zIiwiJGVsZW1lbnQiLCJpcyIsImNvbnRyb2xsZXIiLCJhY3Rpb24iLCJBamF4IiwiYWpheF91cmxfdG9fY29udHJvbGxlcl9hY3Rpb24iLCJhcHBseV9mb3JtX2Vycm9ycyIsInBhcmVudF9zZWxlY3RvciIsInJlc2V0X2Zvcm1fZXJyb3JzIiwibm9ybWFsaXplZCIsIl9ub3JtYWxpemVfZXJyb3JzIiwiYW5pbWF0aW9ucyIsInR5cGUiLCJfYXBwbHlfZ2VuZXJhbF9lcnJvcnMiLCJkZWR1cGxpY2F0ZWQiLCJfZGVkdXBsaWNhdGVfZXJyb3JzIiwiX2FwcGx5X2ZpZWxkX2Vycm9ycyIsIm1hdGNoZWRfY291bnQiLCJrZXlzIiwidW5tYXRjaGVkIiwidW5tYXRjaGVkX2RlZHVwbGljYXRlZCIsInVubWF0Y2hlZF9jb3VudCIsInN1bW1hcnlfbXNnIiwic3VtbWFyeV9hbmltYXRpb25zIiwiX2FwcGx5X2NvbWJpbmVkX2Vycm9yIiwiJGVycm9yX2NvbnRhaW5lciIsImZpbmQiLCJmaXJzdCIsImNvbnRhaW5lcl90b3AiLCJmaXhlZF9oZWFkZXJfaGVpZ2h0IiwiX2dldF9maXhlZF9oZWFkZXJfaGVpZ2h0IiwidGFyZ2V0X3Njcm9sbCIsInJlc2V0IiwiZm9ybV9zZWxlY3RvciIsIiRmb3JtIiwidHJpZ2dlciIsInNlcmlhbGl6ZSIsInNlcmlhbGl6ZUFycmF5IiwiZm9ybV9kYXRhIiwib25fc3VjY2VzcyIsImRldGFpbHMiLCJvbl9lcnJvciIsInJlbW92ZSIsInJlbW92ZUNsYXNzIiwiZXZlcnkiLCJ1bndyYXBwZWQiLCJmaWVsZCIsIlNldCIsInNlZW4iLCJoYXMiLCJhZGQiLCJmaWVsZF9lcnJvcnMiLCJmaWVsZF9uYW1lIiwiZXJyb3JfbWVzc2FnZSIsIiRpbnB1dCIsIiRlcnJvciIsImFkZENsYXNzIiwiYXBwZW5kVG8iLCJoaWRlIiwiZmFkZUluIiwicHJvbWlzZSIsInVubWF0Y2hlZF9lcnJvcnMiLCIkYWxlcnQiLCJ0ZXh0IiwiJGxpc3QiLCJlcnJvcl9tc2ciLCJwcmVwZW5kVG8iLCJtZXNzYWdlcyIsIm1zZyIsImVycm9yX2xpc3QiLCJ0b3RhbF9oZWlnaHQiLCIkZWwiLCJjc3MiLCJvdXRlcldpZHRoIiwidmlld3BvcnRfd2lkdGgiLCJsb2dfYnJvd3Nlcl9lcnJvcnMiLCJfaGFuZGxlX2Jyb3dzZXJfZXJyb3IiLCJmaWxlbmFtZSIsImxpbmVubyIsImNvbG5vIiwib25fcmVmcmVzaCIsImVuYWJsZWQiLCJjb25maWciLCJmaWx0ZXJfbW9kZSIsInNwZWNpZmljIiwic3BlY2lmaWNfY2hhbm5lbCIsImNoYW5uZWxzIiwid2hpdGVsaXN0IiwiZmlsdGVyX2NoYW5uZWxzIiwiYmxhY2tsaXN0IiwidGltZXN0YW1wIiwidG9JU09TdHJpbmciLCJpbmNsdWRlX2xvY2F0aW9uIiwiaW5jbHVkZV9iYWNrdHJhY2UiLCJsb2NhdGlvbiIsImJhY2t0cmFjZSIsImxpbmUiLCJvdXRwdXRzIiwiYnJvd3NlciIsImluY2x1ZGVfYmVuY2htYXJrIiwiX2dldF90aW1lX3ByZWZpeCIsImNoYW5uZWxQcmVmaXgiLCJjb25zb2xlTWV0aG9kIiwibGFyYXZlbF9sb2ciLCJfYmF0Y2hfY29uc29sZV9tZXNzYWdlIiwibG9nX2Vycm9yIiwiZXJyb3JEYXRhIiwiX2Vycm9yX2NvdW50IiwiTUFYX0VSUk9SU19QRVJfUEFHRSIsIl9lcnJvcl9iYXRjaF9jb3VudCIsIk1BWF9FUlJPUl9CQVRDSEVTIiwiX2Vycm9yX2JhdGNoIiwiX2Vycm9yX3RpbWVyIiwiX2ZsdXNoX2Vycm9yX2JhdGNoIiwiREVCT1VOQ0VfTVMiLCJfY29uc29sZV9iYXRjaCIsIl9jb25zb2xlX3RpbWVyIiwiX2ZsdXNoX2NvbnNvbGVfYmF0Y2giLCJfc3RhcnRfdGltZSIsImVsYXBzZWQiLCJ0b0ZpeGVkIiwiXzI3ZTBlOTg2X2RlZmluZVByb3BlcnR5IiwiUnN4X0pxX0hlbHBlcnMiLCJleGlzdHMiLCJpc192aXNpYmxlIiwic2Nyb2xsX3VwX3RvIiwic3BlZWQiLCJpc19pbl9kb20iLCJlX3RvcCIsInNfdG9wIiwiZXhwciIsImZvY3VzIiwiZWxlbSIsImFjdGl2ZUVsZW1lbnQiLCJfY2xpY2tfbmF0aXZlIiwiY2xpY2siLCJoYW5kbGVyIiwib3JpZ2luYWxfcHJldmVudERlZmF1bHQiLCJiaW5kIiwid2FybiIsImNsaWNrX2FsbG93X2RlZmF1bHQiLCJfYW5jZXN0b3IiLCJIVE1Mb2JqIiwicGFyZW50RWxlbWVudCIsImRvY3VtZW50RWxlbWVudCIsImlzX2luX3ZpZXdwb3J0Iiwic2Nyb2xsdG9wIiwidG9wX29mX2VsZW1lbnQiLCJib3R0b21fb2ZfZWxlbWVudCIsImJvdHRvbV9vZl9zY3JlZW4iLCJpbm5lckhlaWdodCIsInRvcF9vZl9zY3JlZW4iLCJ0YWduYW1lIiwicHJvcCIsInRvTG93ZXJDYXNlIiwiaXNfZXh0ZXJuYWwiLCJob3N0IiwibGluayIsImhvc3RuYW1lIiwiY2hlY2tWYWxpZGl0eSIsInJlcG9ydFZhbGlkaXR5IiwicmVxdWVzdFN1Ym1pdCIsImNsb3Nlc3Rfc2libGluZyIsInNlbGVjdG9yIiwiJGN1cnJlbnQiLCIkZm91bmQiLCJuYXRpdmVfYWpheCIsInNldHRpbmdzIiwicmVxdWVzdF91cmwiLCJpc19yZWxhdGl2ZSIsImlzX3NhbWVfZG9tYWluIiwib3JpZ2luIiwiaXNfbG9jYWxfcmVxdWVzdCIsIl9fbG9jYWxfaW50ZWdyYXRpb24iLCJpc19maWxlX3VwbG9hZCIsImVuZHNXaXRoIiwiY29udHJvbGxlcl9uYW1lIiwiYWN0aW9uX25hbWUiLCJ1cmxfbWF0Y2giLCJfaW5pdF9ldmVudHMiLCJfZXZlbnRfaGFuZGxlcnMiLCJfdHJpZ2dlcmVkX2V2ZW50cyIsInRyaWdnZXJfcmVmcmVzaCIsIkNvcmVfTG9nIiwiaXNfZGV2IiwidWlkIiwiX3VpZCIsIl9kZWZpbmVfcm91dGVzIiwicm91dGVzIiwiX3JvdXRlcyIsInBhcmFtc19vYmoiLCJwYXR0ZXJuIiwiX2dlbmVyYXRlX3VybF9mcm9tX3BhdHRlcm4iLCJyZXF1aXJlZF9wYXJhbXMiLCJtYXRjaGVzIiwibWlzc2luZyIsInJlcXVpcmVkIiwidXNlZF9wYXJhbXMiLCJwYXJhbV9uYW1lIiwiZW5jb2RlZF92YWx1ZSIsInF1ZXJ5X3BhcmFtcyIsInF1ZXJ5X3N0cmluZyIsImVudHJpZXMiLCJfcmVmIiwiX3JzeF9jYWxsX2FsbF9jbGFzc2VzIiwiYWxsX2NsYXNzZXMiLCJjbGFzc2VzX3dpdGhfbWV0aG9kIiwicHJvbWlzZV9waWxlIiwicmV0dXJuX3ZhbHVlIiwiX19zdG9wcGVkIiwiX3JzeF9jb3JlX2Jvb3QiLCJfX2Jvb3RlZCIsInBoYXNlcyIsInBoYXNlIiwiX3BhcnNlX2hhc2giLCJoYXNoX3N0cmluZyIsInBhaXJzIiwicGFpciIsIl9zZXJpYWxpemVfaGFzaCIsImdldF9hbGxfcGFnZV9zdGF0ZSIsImdldF9wYWdlX3N0YXRlIiwiX3N0YXRlJGtleSIsInN0YXRlIiwic2V0X3BhZ2Vfc3RhdGUiLCJuZXdfaGFzaCIsInBhdGhuYW1lIiwiaGlzdG9yeSIsInJlcGxhY2VTdGF0ZSIsInNldF9hbGxfcGFnZV9zdGF0ZSIsIm5ld19zdGF0ZSIsInJlbmRlcl9lcnJvciIsIiRjb250YWluZXIiLCJmaWxlIiwiX2VzY2FwZV9odG1sIiwiZGl2IiwiaW5uZXJIVE1MIiwiX2U4MjExZjViX2RlZmluZVByb3BlcnR5IiwiX3BlbmRpbmdfY2FsbHMiLCJfZmx1c2hfdGltZW91dCIsIl9jYWxsX2NvdW50ZXIiLCJNQVhfQkFUQ0hfU0laRSIsIl90cmFja2VkX3Byb21pc2VzIiwiV2Vha1NldCIsIk1vZGFsIiwicGF0aCIsImFqYXhfZGlzYWJsZV9iYXRjaGluZyIsIl9jYWxsX2RpcmVjdCIsIl9jYWxsX2JhdGNoIiwiY2FsbF9rZXkiLCJfZ2VuZXJhdGVfY2FsbF9rZXkiLCJleGlzdGluZ19jYWxsIiwiaXNfY29tcGxldGUiLCJpc19lcnJvciIsImNhbGxiYWNrcyIsImNhbGxfaWQiLCJwZW5kaW5nX2NhbGwiLCJwZW5kaW5nX2NvdW50IiwiX2ZsdXNoX3BlbmRpbmdfY2FsbHMiLCJfc3VjY2VzcyIsInByb2Nlc3NlZF92YWx1ZSIsIl9hamF4X3JldHVybl92YWx1ZSIsImVycm9yX3R5cGUiLCJmYXRhbF9lcnJvcl9kYXRhIiwiZmF0YWxfZXJyb3IiLCJlbmRwb2ludCIsImF1dGhfZXJyb3IiLCJ1bmF1dGhfZXJyb3IiLCJmb3JtX2Vycm9yIiwiZ2VuZXJpY19lcnJvciIsInhociIsIl9leHRyYWN0X2Vycm9yX21lc3NhZ2UiLCJuZXR3b3JrX2Vycm9yIiwic3RhdHVzVGV4dCIsImNhbGxzX3RvX3NlbmQiLCJjYWxsX21hcCIsImJhdGNoX2NhbGxzIiwicmVzcG9uc2Vfa2V5IiwiY2FsbF9yZXNwb25zZSIsImVycm9yX2RldGFpbHMiLCJfcmVmMiIsInhocl9lcnJvciIsIl9yZWYzIiwic29ydGVkX3BhcmFtcyIsInJlc3BvbnNlSlNPTiIsInJlc3BvbnNlVGV4dCIsIkpxaHRtbF9Db21wb25lbnQiLCJfQmFzZV9KcWh0bWxfQ29tcG9uZW50IiwiSnFodG1sX0ludGVncmF0aW9uIiwiX29uX2ZyYW1ld29ya19tb2R1bGVzX2RlZmluZSIsImpxaHRtbF9jb21wb25lbnRzIiwiY29tcG9uZW50IiwianFodG1sIiwicmVnaXN0ZXJfY29tcG9uZW50IiwiX29uX2ZyYW1ld29ya19tb2R1bGVzX2luaXQiLCIkc2NvcGUiLCJpc190b3BfbGV2ZWwiLCJjb21wb25lbnRzX25lZWRpbmdfaW5pdCIsImNvbnRhaW5zIiwiY2xhc3NMaXN0IiwiY29tcG9uZW50X25hbWUiLCJjb21wb25lbnRfYXJncyIsImFyZ3Nfc3RyaW5nIiwicmVtb3ZlQXR0ciIsInJlbW92ZURhdGEiLCJjb21wb25lbnRfYXJnc19maWx0ZXJlZCIsIl9pbm5lcl9odG1sIiwiY29tcG9uZW50X3Byb21pc2UiLCJuZXN0ZWRfcHJvbWlzZXMiLCJnZXRfY29tcG9uZW50X25hbWVzIiwiaGFzX2NvbXBvbmVudCIsIkRhdGFHcmlkX0Fic3RyYWN0Iiwib25fY3JlYXRlIiwicm93cyIsImxvYWRpbmciLCJpc19lbXB0eSIsImxvYWRlZCIsInRvdGFsX3BhZ2VzIiwib25fcmVhZHkiLCJfdGhhdCRhcmdzJHBlcl9wYWdlIiwiX3RoYXQkYXJncyRzb3J0IiwiX3RoYXQkYXJncyRvcmRlciIsImRhdGFfc291cmNlIiwiZGVmYXVsdF9wYWdlIiwiZGVmYXVsdF9wZXJfcGFnZSIsInBlcl9wYWdlIiwiZGVmYXVsdF9zb3J0IiwiZGVmYXVsdF9vcmRlciIsIm9yZGVyIiwiZGVmYXVsdF9maWx0ZXIiLCJoYXNoX3BhZ2UiLCJfY2lkIiwiaGFzaF9zb3J0IiwiaGFzaF9vcmRlciIsImhhc2hfZmlsdGVyIiwicGFnZSIsInJlZ2lzdGVyX3JlbmRlcl9jYWxsYmFja3MiLCJyZWdpc3Rlcl9maWx0ZXJfaGFuZGxlcnMiLCIkZmlsdGVyIiwiJGlkIiwibWVhc3VyZV9hbmRfc2V0X2ZpeGVkX2hlaWdodCIsImxvYWRfcGFnZSIsInVwZGF0ZV9oZWFkZXIiLCJfbGFzdF9oZWFkZXJfc3RhdGUiLCJjdXJyZW50IiwicmVuZGVyIiwidXBkYXRlX3BhZ2luYXRpb24iLCJfbGFzdF9wYWdpbmF0aW9uX3N0YXRlIiwidG90YWwiLCJyZWNvcmRzIiwic2Nyb2xsX3RvX3RvcF9pZl9uZWVkZWQiLCIkcm93IiwiJGNvbCIsIiRjaGlsZHJlbiIsImNoaWxkcmVuIiwiJHRoIiwic29ydGJ5IiwiJGV4aXN0aW5nX2xpbmsiLCJjb250ZW50cyIsImVuZCIsImFycm93Iiwic29ydF9ieSIsImhhc0NsYXNzIiwiJGNsZWFyX2J0biIsImNsZWFyX2ZpbHRlciIsImNvbHVtbiIsImZpbHRlcl92YWx1ZSIsImZpbHRlcl9jaGFuZ2VkIiwiJGRhdGFncmlkIiwiZGF0YWdyaWRUb3AiLCJzY3JvbGxUbyIsImJlaGF2aW9yIiwiJHRib2R5IiwiJG1lYXN1cmVtZW50X3JvdyIsImFwcGVuZCIsInJvd19oZWlnaHQiLCJtaW5faGVpZ2h0IiwidGJvZHlfbWluX2hlaWdodCIsIkFjdGl2aXR5X0ZlZWQiLCJvbl9sb2FkIiwiYWN0aXZpdGllcyIsImF1dG9fcmVmcmVzaCIsInN0YXJ0X2F1dG9fcmVmcmVzaCIsImludGVydmFsIiwicmVmcmVzaF9pbnRlcnZhbCIsInJlZnJlc2hfdGltZXIiLCJzZXRJbnRlcnZhbCIsInJlbG9hZF9kYXRhIiwic3RvcF9hdXRvX3JlZnJlc2giLCJjbGVhckludGVydmFsIiwiQWN0b3JfUmVmZXJlbmNlIiwiQWR2YW5jZWRfU2VhcmNoX1BhbmVsIiwiY2F0ZWdvcmllcyIsInNldF9vcHRpb25zIiwidGFncyIsInBlcmZvcm1fc2VhcmNoIiwib25fY2xvc2UiLCJjcml0ZXJpYSIsImtleXdvcmRzIiwiZ2V0X3ZhbHVlIiwiY2F0ZWdvcnkiLCJmcm9tX2RhdGUiLCJ0b19kYXRlIiwiZXhhY3RfbWF0Y2giLCJvbl9zZWFyY2giLCJzZXRfdmFsdWUiLCJvbl9yZXNldCIsIkFsZXJ0X0Jhbm5lciIsImRpc21pc3NpYmxlIiwiQXZhdGFyIiwic2l6ZSIsInNpemVfbWFwIiwic2hvd19pbml0aWFscyIsImluaXRpYWxzIiwiJGRpdiIsInJlcGxhY2VXaXRoIiwiQmxvY2txdW90ZSIsIkJyZWFkY3J1bWJzIiwiQnVsa19BY3Rpb25fQmFyIiwiJHRhYmxlIiwic2V0X2NvdW50IiwiQnVsa19TZWxlY3Rpb24iLCIkY2hlY2tib3giLCJjaGVja2VkIiwib25fY2hhbmdlIiwiQnV0dG9uX0dyb3VwIiwiQnV0dG9uX1ByaW1hcnkiLCJCdXR0b25fU2Vjb25kYXJ5IiwiQnV0dG9uIiwiQ2FsZW5kYXJfRXZlbnQiLCJvbl9jbGljayIsIkNhbGVuZGFyX0dyaWQiLCJjdXJyZW50X2RhdGUiLCJyZW5kZXJfY2FsZW5kYXIiLCJzZXRNb250aCIsImdldE1vbnRoIiwieWVhciIsImdldEZ1bGxZZWFyIiwibW9udGgiLCJtb250aF9uYW1lcyIsImZpcnN0X2RheSIsImdldERheSIsImRheXNfaW5fbW9udGgiLCJnZXREYXRlIiwiZGF5IiwiJHRyIiwiaiIsIiR0ZCIsIiRkYXlfbnVtIiwidG9kYXkiLCJldmVudHMiLCJnZXRfZXZlbnRzX2Zvcl9kYXRlIiwiJGV2ZW50IiwidGl0bGUiLCJvbl9ldmVudF9jbGljayIsInBhZFN0YXJ0Iiwib25fZGF0ZV9jbGljayIsImRhdGVfc3RyIiwiQ2FyZCIsIkNoYXJ0X0NvbXBvbmVudCIsIkNoZWNrYm94IiwiZGlzYWJsZWQiLCJDb2RlX0Jsb2NrIiwiQ29sdW1uX1Zpc2liaWxpdHlfVG9nZ2xlIiwiY29sdW1ucyIsImJ1aWxkX21lbnUiLCIkbWVudSIsIiRsaSIsIiRsYWJlbCIsInZpc2libGUiLCJsYWJlbCIsInRvZ2dsZV9jb2x1bW4iLCJvbl90b2dnbGUiLCJ0YWJsZSIsInNob3ciLCJzZXRfY29sdW1ucyIsIkNvbW1lbnRfVGhyZWFkIiwiY29tbWVudHMiLCJzdWJtaXRfY29tbWVudCIsIiRjb21tZW50IiwiY29tbWVudF9pZCIsInNob3dfcmVwbHlfZm9ybSIsImVkaXRfY29tbWVudCIsImRlbGV0ZV9jb21tZW50Iiwib25fc3VibWl0Iiwib25fZWRpdCIsImNvbmZpcm0iLCJvbl9kZWxldGUiLCJEYXRlX1BpY2tlciIsInJlYWRvbmx5IiwiRHJvcGRvd25fTWVudSIsIiRjaGlsZCIsIkVtcHR5X1N0YXRlIiwiRXhwb3J0X0J1dHRvbiIsImZvcm1hdCIsImN1cnJlbnRUYXJnZXQiLCJleHBvcnRfZGF0YSIsIm9uX2V4cG9ydCIsImF1dG9fZXhwb3J0IiwiZXhwb3J0X3VybCIsImV4cG9ydF9jc3YiLCJleHBvcnRfanNvbiIsImhlYWRlcnMiLCJjc3YiLCJyb3ciLCJoZWFkZXIiLCJibG9iIiwiQmxvYiIsIlVSTCIsImNyZWF0ZU9iamVjdFVSTCIsIiRhIiwicmV2b2tlT2JqZWN0VVJMIiwiRmlsZV9VcGxvYWQiLCIkZHJvcF96b25lIiwiYWNjZXB0IiwibXVsdGlwbGUiLCJmaWxlcyIsImhhbmRsZV9maWxlcyIsInN0b3BQcm9wYWdhdGlvbiIsIm9yaWdpbmFsRXZlbnQiLCJkYXRhVHJhbnNmZXIiLCJtYXhfc2l6ZV9ieXRlcyIsImFsZXJ0IiwiZm9ybWF0X3NpemUiLCJzZWxlY3RlZF9maWxlIiwidXBsb2FkX3VybCIsInVwbG9hZCIsIm9uX3NlbGVjdCIsIkZvcm1EYXRhIiwiYm9keSIsIm9uX3VwbG9hZCIsIm9uX2NsZWFyIiwiZ2V0X2ZpbGUiLCJieXRlcyIsIkZpbHRlcl9CYXIiLCJhY3RpdmVfZmlsdGVycyIsInN0YXR1c19vcHRpb25zIiwiJHN0YXR1cyIsIm9wdCIsInNlYXJjaF90aW1lb3V0IiwiYWRkX2ZpbHRlciIsImFwcGx5X2ZpbHRlcnMiLCJjbGVhcl9maWx0ZXJzIiwidXBkYXRlX2ZpbHRlcl9kaXNwbGF5IiwiZGF0ZV9yYW5nZSIsInN0YXJ0X2RhdGUiLCJlbmRfZGF0ZSIsIm9uX2FwcGx5IiwiJHRhZ3MiLCIkdGFnIiwiJHJlbW92ZSIsImdldF9maWx0ZXJzIiwiRm9ybV9BY3Rpb25zX0NvbXBvbmVudCIsIm9uX2NsaWNrX2hlbGxvIiwiRm9ybV9GaWVsZF9Hcm91cCIsImNvbGxhcHNpYmxlIiwibWFrZV9jb2xsYXBzaWJsZSIsIiRoZWFkZXIiLCIkYm9keSIsImNvbGxhcHNlX2lkIiwicmFuZG9tIiwic3Vic3RyIiwiJHRvZ2dsZSIsIkZvcm1fR3JvdXBfQ29tcG9uZW50IiwiY29sX2NsYXNzIiwiRm9ybV9Sb3dfQ29tcG9uZW50IiwiRm9ybV9WYWxpZGF0aW9uX01lc3NhZ2UiLCJHYW50dF9DaGFydCIsInRhc2tzIiwibW9udGhzIiwiZ2VuZXJhdGVfbW9udGhzIiwiSWNvbl9CdXR0b24iLCJJY29uX1dpdGhfTGFiZWwiLCJJY29uX1dpdGhfVGV4dCIsIkljb24iLCJJbmZvX0JveCIsImNvbG9yIiwiSW5saW5lX0VkaXRfRmllbGQiLCJjdXJyZW50X3ZhbHVlIiwiZW50ZXJfZWRpdF9tb2RlIiwiY2FuY2VsIiwic2VsZWN0IiwiZXhpdF9lZGl0X21vZGUiLCJuZXdfdmFsdWUiLCJvbl9zYXZlIiwic2hvd19zYXZpbmciLCJ1cGRhdGVfZGlzcGxheSIsImNhdGNoIiwiZGlzcGxheSIsInBsYWNlaG9sZGVyIiwiSW5wdXRfV2l0aF9JY29uIiwib25faW5wdXQiLCJJbnB1dF9XaXRoX1ZhbGlkYXRpb24iLCJ2YWxpZGF0ZSIsInNldF92YWxpZCIsInNldF9lcnJvciIsIiRzdWNjZXNzIiwiY2xlYXJfdmFsaWRhdGlvbiIsIklucHV0IiwiS2FuYmFuX0JvYXJkIiwic2V0dXBfZHJhZ19hbmRfZHJvcCIsImRyYWdnZWRfY2FyZCIsIiRjYXJkIiwiJGNvbHVtbiIsIm9uX21vdmUiLCJjYXJkX2lkIiwiY29sdW1uX2lkIiwiTGluayIsIkxpc3QiLCJMb2FkaW5nX1NrZWxldG9uIiwibGluZXMiLCIkc3BhbiIsIk1ldHJpY19DYXJkIiwiTW9iaWxlX0hlYWRlciIsIk1vZGFsX0RpYWxvZyIsIm1vZGFsIiwiYm9vdHN0cmFwIiwiTXVsdGlfU2VsZWN0Iiwic2VsZWN0ZWRfdmFsdWVzIiwiYWxsX29wdGlvbnMiLCJyZW5kZXJfb3B0aW9ucyIsIiRzZWFyY2giLCJmaWx0ZXJfb3B0aW9ucyIsImNsZWFyX2FsbCIsInNlbGVjdF9hbGwiLCJvcHRpb24iLCJ0b2dnbGVfb3B0aW9uIiwicXVlcnkiLCJmaWx0ZXJlZCIsIiR0ZXh0IiwiZWwiLCJOb3RpZmljYXRpb25fQmFkZ2UiLCIkY291bnQiLCJOb3RpZmljYXRpb25fRHJvcGRvd24iLCJPdmVyZHVlX0luZGljYXRvciIsIlBhZ2VfSGVhZGVyIiwiUGFnZV9TZWN0aW9uIiwiUGFnZSIsIlBvcG92ZXIiLCJjb250ZW50IiwiUHJvZ3Jlc3NfQmFyIiwiJGJhciIsInNob3dfdmFsdWUiLCJSYWRpb19CdXR0b24iLCJSaWNoX1RleHRfRWRpdG9yIiwiJGVkaXRvciIsImNvbW1hbmQiLCJwcm9tcHQiLCJleGVjQ29tbWFuZCIsInBsYWluX3RleHRfcGFzdGUiLCJnZXREYXRhIiwiZ2V0X3RleHQiLCJSb3dfQWN0aW9uX01lbnUiLCJ3cmFwIiwiU2FtcGxlX0RhdGFncmlkX0NvbXBvbmVudCIsImFwaV91cmwiLCJnZW5lcmF0ZV9zYW1wbGVfZGF0YSIsInNlbGVjdGFibGUiLCJ1cGRhdGVfc2VsZWN0aW9uX2NvdW50IiwiYWxsb3dfZGVsZXRlIiwiJGJ1dHRvbiIsImNvbmZpcm1fZGVsZXRlIiwicGFnaW5hdGlvbiIsImdvX3RvX3BhZ2UiLCJjdXJyZW50X3BhZ2UiLCJzZWxlY3RlZCIsImdldF9zZWxlY3RlZF9pZHMiLCJpZHMiLCJjaGVja2JveCIsImNsZWFyX3NlbGVjdGlvbiIsImRlbGV0ZV9yb3ciLCJzdGF0dXNlcyIsImZpcnN0X25hbWVzIiwibGFzdF9uYW1lcyIsImNvbXBhbmllcyIsInNob3dpbmciLCJmaXJzdF9uYW1lIiwiZmxvb3IiLCJsYXN0X25hbWUiLCJjb21wYW55IiwicGhvbmUiLCJzdGF0dXNfY29sb3IiLCJjcmVhdGVkIiwicmFuZG9tX2RhdGUiLCJjZWlsIiwidG8iLCJwYWdlcyIsIlNlYXJjaF9CYXIiLCJTZWFyY2hhYmxlX1NlbGVjdCIsInNlbGVjdGVkX3ZhbHVlIiwic2VsZWN0ZWRfb3B0aW9uIiwiJGl0ZW0iLCJzZWxlY3Rfb3B0aW9uIiwiZHJvcGRvd24iLCJEcm9wZG93biIsImdldEluc3RhbmNlIiwiU2VsZWN0X0Ryb3Bkb3duIiwiU2lkZWJhcl9OYXYiLCIkbmF2X2l0ZW1zIiwiY3VycmVudF9wYXRoIiwiU29ydGFibGVfQ29sdW1uX0hlYWRlciIsInRvZ2dsZV9zb3J0Iiwic2V0X3NvcnQiLCJuZXh0Iiwib25fc29ydCIsImRpcmVjdGlvbiIsIiRpY29uIiwiU3Bpbm5lciIsIlN0YXRfQ2FyZCIsIlN0YXR1c19CYWRnZSIsImNvbG9yX21hcCIsImJnX2NsYXNzIiwiVGFiX0NvbnRlbnQiLCJUYWJsZV9QYWdpbmF0aW9uIiwiZ2VuZXJhdGVfcGFnaW5hdGlvbiIsIiRwYWdpbmF0aW9uIiwiJHByZXYiLCJzdGFydCIsIiRuZXh0IiwiVGFibGUiLCJ2YXJpYW50IiwiVGFicyIsIlRhZ19Hcm91cCIsIlRhZyIsIlRleHRfRGlzcGxheSIsIlRleHRhcmVhIiwiVGhyZWVfQ29sdW1uX0xheW91dCIsIlRpbWVfUGlja2VyIiwic3RlcCIsIlRpbWVsaW5lIiwiVGltZXN0YW1wX0Rpc3BsYXkiLCJUb29sdGlwIiwicGxhY2VtZW50IiwiVG9wX05hdiIsIiRuYXYiLCJUcmVuZF9JbmRpY2F0b3IiLCJpc19wb3NpdGl2ZSIsImlzX25lZ2F0aXZlIiwiVHdvX0NvbHVtbl9MYXlvdXQiLCJVc2VyX0F2YXRhcl9Ecm9wZG93biIsIk1vZGFsX0Fic3RyYWN0IiwiUnN4X01vZGFsIiwiYm9keV9jb250ZW50IiwiYnV0dG9ucyIsImNsb3NhYmxlIiwibWF4X3dpZHRoIiwiY2xvc2Vfb25fc3VibWl0IiwicmVzdWx0X3Byb21pc2UiLCJyZXNvbHZlX2ZuIiwiX2JzX21vZGFsIiwiX3Jlc2l6ZV9oYW5kbGVyIiwiY2xvc2UiLCJfYXBwbHlfc2l6aW5nIiwiaW50ZXJuYWxfb3B0aW9ucyIsInNraXBfYmFja2Ryb3AiLCJzaG91bGRfYW5pbWF0ZSIsImljb24iLCJfc2V0X2JvZHlfY29udGVudCIsIl9zZXRfYnV0dG9ucyIsIl9mYWRlX2luIiwiX2ZvY3VzX2ZpcnN0X2lucHV0IiwiJGNvbnRlbnQiLCJlc2NhcGVkIiwialF1ZXJ5IiwiJGZvb3RlciIsImJ1dHRvbl9kZWYiLCJoYWRfY2FsbGJhY2siLCJ2aWV3cG9ydF9oZWlnaHQiLCJ2aWV3cG9ydF9saW1pdCIsInByZWZlcnJlZF93aWR0aCIsImNvbnRlbnRfaGVpZ2h0IiwibWF4X2hlaWdodCIsIm9mZnNldEhlaWdodCIsIiRmaXJzdF9pbnB1dCIsIm9mZiIsImFwcGx5X2Vycm9ycyIsIl9pbml0IiwiX2luaXRpYWxpemVkIiwiX2JhY2tkcm9wIiwiX2dldF9zY3JvbGxiYXJfd2lkdGgiLCIkb3V0ZXIiLCJ2aXNpYmlsaXR5Iiwib3ZlcmZsb3ciLCJ3aWR0aF93aXRoX3Njcm9sbGJhciIsIm9mZnNldFdpZHRoIiwiJGlubmVyIiwid2lkdGhfd2l0aG91dF9zY3JvbGxiYXIiLCJfbG9ja19ib2R5X3Njcm9sbCIsIl91bmxvY2tfdGltZW91dCIsIl9vcmlnaW5hbF9ib2R5X292ZXJmbG93IiwiX29yaWdpbmFsX2JvZHlfcGFkZGluZyIsImhhc19zY3JvbGxiYXIiLCJzY3JvbGxiYXJfd2lkdGgiLCJjdXJyZW50X3BhZGRpbmciLCJfdW5sb2NrX2JvZHlfc2Nyb2xsIiwiX2N1cnJlbnQiLCJfcXVldWUiLCJfc2hvd19iYWNrZHJvcCIsIl9oaWRlX2JhY2tkcm9wIiwiX2NyZWF0ZV9tb2RhbCIsIiRtb2RhbF9lbGVtZW50IiwibW9kYWxfaW5zdGFuY2UiLCJmb290ZXIiLCJfc2hvd19tb2RhbCIsIl9wcm9jZXNzX3F1ZXVlIiwiYmFja2Ryb3BfdmlzaWJsZSIsInRpbWVfc2luY2VfbGFzdF9jbG9zZSIsIl9sYXN0X2Nsb3NlX3RpbWVzdGFtcCIsImlzX29wZW4iLCJnZXRfY3VycmVudCIsInRpdGxlX29yX2JvZHkiLCJidXR0b25fbGFiZWwiLCJkZWZhdWx0IiwiY29uZmlybV9sYWJlbCIsImNhbmNlbF9sYWJlbCIsImRlZmF1bHRfdmFsdWUiLCJtdWx0aWxpbmUiLCJkZWZhdWx0cyIsImZpbmFsX29wdGlvbnMiLCJmb3JtIiwic3VibWl0X2xhYmVsIiwiJGNvbXBvbmVudF9jb250YWluZXIiLCJjb21wb25lbnRfaW5zdGFuY2UiLCJ2YWxzIiwic3VibWl0IiwidW5jbG9zYWJsZSIsImN1c3RvbSIsImVycm9yX21lc3NhZ2VzIiwicmVvcGVuX3dpdGhfZXJyb3JzIiwiX2QxZjVhM2NiX2RlZmluZVByb3BlcnR5IiwiQnJlYWRjcnVtYl9JdGVtIiwiQ2xpZW50X0xhYmVsX0xpbmsiLCJjbGllbnQiLCJnZXRfY2xpZW50Iiwib25fcmVuZGVyIiwiQ2xpZW50X0xhYmVsIiwiRm9ybV9JbnB1dF9BYnN0cmFjdCIsInNlZWQiLCJUZXh0X0lucHV0Iiwic2VlZGVyIiwiQ2hlY2tib3hfSW5wdXQiLCJjaGVja2VkX3ZhbHVlIiwidW5jaGVja2VkX3ZhbHVlIiwiaW5wdXRfaWQiLCJpc19jaGVja2VkIiwic2hvdWxkX2NoZWNrIiwiV3lzaXd5Z19JbnB1dCIsInF1aWxsIiwiX2luaXRpYWxpemVfcXVpbGwiLCJ0aGVtZSIsIm1vZHVsZXMiLCJ0b29sYmFyIiwicm9vdCIsInNhbXBsZV9jb250ZW50IiwiU2VsZWN0X0lucHV0IiwiZGVjb2RlZCIsImFsbG93RW1wdHlPcHRpb24iLCJjcmVhdGUiLCJtYXhPcHRpb25zIiwicGx1Z2lucyIsIm9uSW5pdGlhbGl6ZSIsImNvbnRyb2wiLCJ0b21fc2VsZWN0IiwiVG9tU2VsZWN0Iiwic2V0VmFsdWUiLCJnZXRWYWx1ZSIsInJhbmRvbV9pbmRleCIsInJhbmRvbV9vcHQiLCJyYW5kb21fdmFsdWUiLCJvbl9kZXN0cm95IiwiZGVzdHJveSIsIkFqYXhfU2VsZWN0X0lucHV0Iiwic2VsZWN0X3ZhbHVlcyIsIl9wZW5kaW5nX3ZhbHVlIiwib2siLCJDdXJyZW5jeV9JbnB1dCIsImFsbG93X2RlY2ltYWxzIiwic2hvd19zeW1ib2wiLCJjdXJyZW5jeV9zeW1ib2wiLCJfZm9ybWF0X2N1cnJlbmN5IiwiaW50ZWdlcl9wYXJ0IiwiZGVjaW1hbF9wYXJ0IiwiZm9ybWF0dGVkIiwiX2dldF9udW1lcmljX3ZhbHVlIiwiY2xlYW5lZCIsImRlY2ltYWxfY291bnQiLCJmaXJzdF9kZWNpbWFsIiwicmF3IiwibnVtZXJpYyIsImlucHV0X2VsZW1lbnQiLCJjdXJzb3JfcG9zIiwic2VsZWN0aW9uU3RhcnQiLCJjdXJzb3JfZW5kIiwic2VsZWN0aW9uRW5kIiwidmFsdWVfbGVuZ3RoIiwiY2hhcl9iZWZvcmUiLCJuZXdfbnVtZXJpYyIsIm5ld19sZW5ndGgiLCJzZXRTZWxlY3Rpb25SYW5nZSIsInN5bWJvbF9vZmZzZXQiLCJuZXdfY3Vyc29yIiwiaW5pdGlhbF92YWx1ZSIsIlBob25lX1RleHRfSW5wdXQiLCJfaXNfaW50ZXJuYXRpb25hbCIsIl9jaGVja19pbnRlcm5hdGlvbmFsX21vZGUiLCJfZm9ybWF0X3VzX3Bob25lIiwiZGlnaXRzIiwic3RyX3ZhbHVlIiwiZGlnaXRzX3RvX2Zvcm1hdCIsIl9sYXN0X2N1cnNvcl9wb3NpdGlvbiIsIm5ld19kaWdpdHMiLCJTdGF0ZV9TZWxlY3RfSW5wdXQiLCJjb3VudHJ5X2NvZGUiLCJSc3hfUmVmZXJlbmNlX0RhdGFfQ29udHJvbGxlciIsInN0YXRlcyIsImNvdW50cnkiLCJfc3RhdGVfY2FjaGUiLCJpc19uYSIsImRpc2FibGUiLCJzZXRfY291bnRyeV9jb2RlIiwiY3VycmVudF9jb3VudHJ5IiwicmVkcmF3IiwiY2FjaGVkX3ZhbHVlIiwidmFsdWVfZXhpc3RzIiwiZW5hYmxlIiwiQ291bnRyeV9TZWxlY3RfSW5wdXQiLCJjb3VudHJpZXMiLCJkZWZhdWx0X2NvdW50cnkiLCJkZWZhdWx0X2NvdW50cnlfY29kZSIsImRlZmF1bHRfY291bnRyeV9pbmRleCIsImZpbmRJbmRleCIsInVuc2hpZnQiLCJfdXBkYXRlX3N0YXRlX3NlbGVjdG9yIiwic3RhdGVfY29tcG9uZW50IiwiUHJvZmlsZV9QaG90b19JbnB1dCIsImF0dGFjaG1lbnRfa2V5IiwidGh1bWJuYWlsX3VybCIsInVwbG9hZF9waG90byIsInNob3dfcmVtb3ZlIiwicmVtb3ZlX3Bob3RvIiwibWF4X3NpemUiLCJwcm9jZXNzRGF0YSIsImNvbnRlbnRUeXBlIiwiYXR0YWNobWVudCIsIl94aHIkcmVzcG9uc2VKU09OIiwidXBkYXRlX3Bob3RvIiwiUnN4X1RhYnMiLCJ0YWJzIiwiYWN0aXZlX3RhYl9pZCIsIl9idWlsZF9uYXYiLCJ0YWJfaWQiLCJhY3RpdmF0ZV90YWIiLCJyZWdpc3Rlcl90YWIiLCJ0YWJfY29tcG9uZW50IiwidGFiIiwiaXNfYWN0aXZlIiwidCIsImhhbmRsZV92YWxpZGF0aW9uX2Vycm9ycyIsInRhYl9lcnJvcnMiLCJlcnJvcl9jb3VudCIsImNvdW50X2Vycm9ycyIsIiRiYWRnZSIsImZpcnN0X2Vycm9yZWRfdGFiIiwiY2xlYXJfZXJyb3JfYmFkZ2VzIiwiUnN4X1RhYiIsInRhYnNfY29udGFpbmVyIiwiZmllbGRzIiwiZWxlbWVudCIsImZpZWxkX2NvbXBvbmVudCIsIlJzeF9Gb3JtIiwidGFic19lbCIsInNoYWxsb3dGaW5kIiwiJHdpZGdldCIsIndpZGdldF9uYW1lIiwiZ2V0X2Vycm9yIiwiYWpheF91cmwiLCJQaW5fVmVyaWZpY2F0aW9uX0Zvcm0iLCJwaW5fbGVuZ3RoIiwicGluIiwiZmlyc3RfZW1wdHkiLCJfZmluZF9maXJzdF9lbXB0eV9pbmRleCIsIl9mb2N1c19pbnB1dCIsIl9oYW5kbGVfcGFzdGUiLCJzdGFydF9pbmRleCIsInBhc3RlIiwibmV4dF9pbmRleCIsIkZvcm1fRmllbGRfQWJzdHJhY3QiLCJoYXNfZXJyb3IiLCJ3aWRnZXRfY29tcG9uZW50IiwiRm9ybV9GaWVsZCIsIkZvcm1fSGlkZGVuX0ZpZWxkIiwiRnJvbnRlbmRfRGFzaGJvYXJkIiwiaW5pdCIsInRvb2x0aXAiLCJvbl9hcHBfcmVhZHkiLCJDbGllbnRzX0RhdGFHcmlkIiwiRnJvbnRlbmRfQ2xpZW50c19FZGl0IiwidGFnX2h0bWwiLCJGcm9udGVuZF9DbGllbnRzX1ZpZXciLCJjb25maXJtZWQiLCJyZWxvYWQiLCJyZXN0b3JlIiwiRnJvbnRlbmRfQ2xpZW50cyIsIkZyb250ZW5kX1NldHRpbmdzX1RlYW0iLCJGcm9udGVuZF9TZXR0aW5nc19Ob3RpZmljYXRpb25zIiwiRnJvbnRlbmRfU2V0dGluZ3NfQmlsbGluZyIsIkZyb250ZW5kX1NldHRpbmdzX0ltcG9ydCIsIkZyb250ZW5kX1NldHRpbmdzX0FwaSIsIkZyb250ZW5kX1NldHRpbmdzX1RlbXBsYXRlcyIsIkZyb250ZW5kX1NldHRpbmdzX0F1ZGl0IiwiRnJvbnRlbmRfU2V0dGluZ3NfUHJvZmlsZV9EaXNwbGF5IiwiRnJvbnRlbmRfU2V0dGluZ3NfVXNlcl9TZXR0aW5ncyIsIkZyb250ZW5kX1NldHRpbmdzX1Bhc3N3b3JkX1NlY3VyaXR5IiwiRnJvbnRlbmRfU2V0dGluZ3NfQXBpX0tleXMiLCJVc2Vyc19EYXRhR3JpZCIsIkFkZF9Vc2VyX0Zvcm0iLCJBZGRfVXNlcl9Nb2RhbCIsIkZyb250ZW5kX1NldHRpbmdzX1VzZXJfTWFuYWdlbWVudF9Db250cm9sbGVyIiwiYWRkX3VzZXIiLCJTZW5kX1VzZXJfSW52aXRlX01vZGFsIiwidXNlcl9pZCIsInNlbmRfaW52aXRlIiwiaW52aXRlX3VybCIsIkZyb250ZW5kX1NldHRpbmdzX1VzZXJfTWFuYWdlbWVudCIsImhhbmRsZV9hZGRfdXNlciIsInVzZXIiLCJFZGl0X1VzZXJfTW9kYWwiLCJ1c2VyX2RhdGEiLCJnZXRfdXNlcl9mb3JfZWRpdCIsInNhdmVfdXNlciIsIkZyb250ZW5kX1NldHRpbmdzX1VzZXJfTWFuYWdlbWVudF9WaWV3IiwiaGFuZGxlX2VkaXRfdXNlciIsImhhbmRsZV9yZXNlbmRfaW52aXRlIiwiX3dpbmRvdyRyc3hhcHAkcGFnZV9kIiwicGFnZV9kYXRhIiwiX3dpbmRvdyRyc3hhcHAkcGFnZV9kMiIsIkZyb250ZW5kX1NldHRpbmdzX1NpdGVfU2V0dGluZ3MiLCJGcm9udGVuZF9TZXR0aW5ncyIsInNlY3Rpb24iLCJmb3JtRGF0YSIsInByZXBlbmQiLCJvcmlnaW5hbFRleHQiLCJDb250YWN0c19EYXRhR3JpZCIsIkRhdGFfVGFibGUiLCJmZXRjaF9kYXRhIiwiYnVpbGRfaGVhZGVycyIsInNlYXJjaGFibGUiLCJzZXR1cF9zZWFyY2giLCJjb2x1bW5fdG9nZ2xlIiwic2V0dXBfY29sdW1uX3RvZ2dsZSIsImJ1bGtfYWN0aW9ucyIsInNldHVwX2J1bGtfYWN0aW9ucyIsInVwZGF0ZV9idWxrX3NlbGVjdGlvbiIsInBhZ2VfdGV4dCIsIiRoZWFkZXJfcm93IiwiY29sIiwic29ydGFibGUiLCIkc29ydGFibGUiLCJoYW5kbGVfc29ydCIsInJvd19hY3Rpb25zIiwidGltZW91dCIsInNlYXJjaF9xdWVyeSIsInRvZ2dsZV9jb21wb25lbnQiLCIkYnVsa19zZWxlY3Rpb24iLCIkYnVsa19iYXIiLCJzb3J0X2ZpZWxkIiwic29ydF9kaXJlY3Rpb24iLCJzZWFyY2hQYXJhbXMiLCJDbGllbnRfU2VsZWN0b3JfSW5wdXQiLCJnZXRfY2xpZW50cyIsIkZyb250ZW5kX0NvbnRhY3RzX0VkaXQiLCJGcm9udGVuZF9Db250YWN0c19WaWV3IiwiRnJvbnRlbmRfQ29udGFjdHMiLCJQcm9qZWN0c19EYXRhR3JpZCIsIkZyb250ZW5kX1Byb2plY3RzX0VkaXQiLCJGcm9udGVuZF9Qcm9qZWN0c19MaXN0IiwiRnJvbnRlbmRfUHJvamVjdHNfVmlldyIsIkZyb250ZW5kX1Byb2plY3RzX0FkZCIsIkZyb250ZW5kX1Byb2plY3RzIiwiRnJvbnRlbmRfVGFza3MiLCJGcm9udGVuZF9UYXNrc19WaWV3IiwiRnJvbnRlbmRfVGFza3NfQWRkIiwiRnJvbnRlbmRfQ2FsZW5kYXIiLCJGcm9udGVuZF9DYWxlbmRhcl9FdmVudCIsIkZyb250ZW5kX0ludm9pY2VzIiwiRnJvbnRlbmRfSW52b2ljZXNfVmlldyIsIkZyb250ZW5kX0ludm9pY2VzX0FkZCIsImFkZF9saW5lX2l0ZW0iLCJjYWxjdWxhdGVfdG90YWxzIiwiYXR0YWNoX2xpbmVfaXRlbV9oYW5kbGVycyIsInVwZGF0ZV9saW5lX2l0ZW1fYW1vdW50IiwibGluZV9pdGVtX2NvdW50IiwicXVhbnRpdHkiLCJyYXRlIiwiYW1vdW50Iiwic3VidG90YWwiLCJ0YXhfcmF0ZSIsInRheF9hbW91bnQiLCJfNzJlYWI1MTRfZGVmaW5lUHJvcGVydHkiLCJGcm9udGVuZF9SZXBvcnRzIiwiRnJvbnRlbmRfUmVwb3J0c19SZXZlbnVlIiwiRnJvbnRlbmRfUmVwb3J0c19DbGllbnRzIiwiRnJvbnRlbmRfUmVwb3J0c19Qcm9qZWN0cyIsIkZyb250ZW5kX1JlcG9ydHNfVGltZSIsIkZyb250ZW5kX0FjY291bnQiXSwibWFwcGluZ3MiOiI7QUFBQTtBQUNBOzs7O0FDREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7OztBQ3JCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVNBLFNBQVNBLENBQUNDLEtBQUssRUFBRTtFQUN0QixPQUFPQSxLQUFLO0FBQ2hCOzs7Ozs7QUN4QkE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTQyxTQUFTQSxDQUFBLEVBQUc7RUFDakIsSUFBSSxnRUFBZ0UsQ0FBQ0MsSUFBSSxDQUFDQyxTQUFTLENB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O0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDMUtBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7OztBQ0hBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7OztBQ0hBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7OztBQ0hBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUMvQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDSEE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDbEVBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDSkE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7OztBQ0ZBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7OztBQ0hBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUNMQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUNUQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUNOQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUNIQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUNIQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUNIQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUNIQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDcEJBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7OztBQ3BDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDTEE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7OztBQ0xBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUNKQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7OztBQ1BBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDUEE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7OztBQ0ZBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7OztBQ0hBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUNSQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7OztBQ3pFQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7OztBQ1BBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7OztBQ0hBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDMU1BO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUNMQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7OztBQ25CQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUNaQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7OztBQ1ZBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUNoQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDakNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDeENBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7OztBQ05BO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUNYQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUNwQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDSEE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDSEE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDaERBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7OztBQ0hBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDSkE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUNKQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUNIQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUNIQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDakJBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7OztBQ2xCQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7OztBQ25CQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDRkE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUMzQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDSEE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDSEE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7OztBQ0xBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDUEE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDZkE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7OztBQ2pCQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7OztBQ3RCQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDUkE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7OztBQ3ZCQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUNIQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDTEE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDSEE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDSEE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDSEE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDSEE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDSEE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDSEE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7OztBQ0xBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUNMQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUNIQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7OztBQ1ZBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUNGQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUNIQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDeERBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUNYQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDdk5BO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7OztBQ1RBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7OztBQ0hBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUNGQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDakJBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7OztBQ0hBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7OztBQ1RBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDUEE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7OztBQ1JBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7OztBQ0hBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUNMQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUNIQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUNIQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUNIQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDTEE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUNWQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUNIQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUNIQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUNIQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUNIQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUNIQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUNIQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUNIQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7OztBQ25CQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUNIQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUNIQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUNIQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7OztBQ25CQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUNIQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUNIQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUNaQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7OztBQzlVQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7OztBQ2xDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUNsQkE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDckJBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUN0QkE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUN4QkE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDNURBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7OztBQzlCQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7OztBQ3ZDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUN4QkE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUNoQkE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDbkNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDcENBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDdERBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUNoQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUM1QkE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7OztBQ3hDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7OztBQ2xCQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDM0NBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDbEJBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUMzQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUM5RkE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDNURBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUN2RkE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7Ozs7QUM5REE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDMUZBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDcEZBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7OztBQ0pBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTs7OztBQ2hDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBOzs7O0FDbEdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUNyTEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQ3RIQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEciLCJmaWxlIjoiYnVuZGxlX291dHB1dF9Gcm9udGVuZF9CdW5kbGUuanMiLCJzb3VyY2VzQ29udGVudCI6WyJ3aW5kb3cucnN4YXBwID0gd2luZG93LnJzeGFwcCB8fCB7fTtcbndpbmRvdy5yc3hhcHAubW9kdWxlX3BhdGhzID0ge1wiYm9vdHN0cmFwNV9zcmNcIjpcInJzeFxcL3RoZW1lXFwvdmVuZG9yXFwvYm9vdHN0cmFwNVxcL3Njc3NcIn07XG4iLCIvLyBOUE0gSW1wb3J0IERlY2xhcmF0aW9ucyBmb3IgQXBwIEJ1bmRsZVxuLy8gQXV0by1nZW5lcmF0ZWQgdG8gcHJvdmlkZSBOUE0gbW9kdWxlcyB0byBhcHAgYnVuZGxlIHNjb3BlXG4vLyBDYWNoZSBrZXk6IDk1YTZmNjAyYzk4MDM3NjExYjY0MGIwYjUzNDI4MzBiXG5cbmNvbnN0IGpxaHRtbCA9IHdpbmRvdy5fcnN4X25wbS5qcWh0bWw7XG5pZiAoIWpxaHRtbCkge1xuICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgJ1JTWCBGcmFtZXdvcmsgRXJyb3I6IE5QTSBtb2R1bGUgXCJqcWh0bWxcIiBub3QgZm91bmQuXFxuJyArXG4gICAgICAgICdFeHBlY3RlZCB3aW5kb3cuX3JzeF9ucG0uanFodG1sIHRvIGJlIGRlZmluZWQgYnkgdGhlIHZlbmRvciBidW5kbGUuJ1xuICAgICk7XG59XG5cbmNvbnN0IF9CYXNlX0pxaHRtbF9Db21wb25lbnQgPSB3aW5kb3cuX3JzeF9ucG0uX0Jhc2VfSnFodG1sX0NvbXBvbmVudDtcbmlmICghX0Jhc2VfSnFodG1sX0NvbXBvbmVudCkge1xuICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgJ1JTWCBGcmFtZXdvcmsgRXJyb3I6IE5QTSBtb2R1bGUgXCJfQmFzZV9KcWh0bWxfQ29tcG9uZW50XCIgbm90IGZvdW5kLlxcbicgK1xuICAgICAgICAnRXhwZWN0ZWQgd2luZG93Ll9yc3hfbnBtLl9CYXNlX0pxaHRtbF9Db21wb25lbnQgdG8gYmUgZGVmaW5lZCBieSB0aGUgdmVuZG9yIGJ1bmRsZS4nXG4gICAgKTtcbn1cblxuLy8gQ2xlYW4gdXAgTlBNIGNvbnRhaW5lciB0byBwcmV2ZW50IGNvbnNvbGUgYWNjZXNzXG5kZWxldGUgd2luZG93Ll9yc3hfbnBtO1xuIiwiLyoqXG4gKiBEZWNvcmF0b3IgZnVuY3Rpb24gdGhhdCBtYXJrcyBhIGZ1bmN0aW9uIGFzIGEgZGVjb3JhdG9yIGltcGxlbWVudGF0aW9uLlxuICpcbiAqIFdoZW4gYSBmdW5jdGlvbiBoYXMgQGRlY29yYXRvciBpbiBpdHMgSlNEb2MgY29tbWVudCwgaXQgd2hpdGVsaXN0cyB0aGF0IGZ1bmN0aW9uXG4gKiB0byBiZSB1c2VkIGFzIGEgZGVjb3JhdG9yIG9uIG90aGVyIG1ldGhvZHMgdGhyb3VnaG91dCB0aGUgY29kZWJhc2UuXG4gKlxuICogVGhlIGZ1bmN0aW9uIGl0c2VsZiBwZXJmb3JtcyBubyBvcGVyYXRpb24gLSBpdCBzaW1wbHkgcmV0dXJucyBpdHMgaW5wdXQgdW5jaGFuZ2VkLlxuICogSXRzIHB1cnBvc2UgaXMgcHVyZWx5IGFzIGEgbWFya2VyIGZvciB0aGUgbWFuaWZlc3QgdmFsaWRhdGlvbiBzeXN0ZW0uXG4gKlxuICogVXNhZ2U6XG4gKiAgIC8vIC8qKlxuICogICAvLyAgKiBNeSBjdXN0b20gZGVjb3JhdG9yIGltcGxlbWVudGF0aW9uXG4gKiAgIC8vICAqIEBkZWNvcmF0b3JcbiAqICAgLy8gICpcXC9cbiAqICAgZnVuY3Rpb24gbXlfY3VzdG9tX2RlY29yYXRvcih0YXJnZXQsIGtleSwgZGVzY3JpcHRvcikge1xuICogICAgICAgLy8gRGVjb3JhdG9yIGltcGxlbWVudGF0aW9uXG4gKiAgIH1cbiAqXG4gKiBUaGlzIGFsbG93cyBteV9jdXN0b21fZGVjb3JhdG9yIHRvIGJlIHVzZWQgYXMgQG15X2N1c3RvbV9kZWNvcmF0b3Igb24gc3RhdGljIG1ldGhvZHMuXG4gKlxuICogVE9ETzogVGhpcyBpcyBwcm9iYWJseSBubyBsb25nZXIgbmVjZXNzYXJ5PyBtYXliZT9cbiAqL1xuZnVuY3Rpb24gZGVjb3JhdG9yKHZhbHVlKSB7XG4gICAgcmV0dXJuIHZhbHVlO1xufVxuIiwiLypcbiAqIEJyb3dzZXIgYW5kIERPTSB1dGlsaXR5IGZ1bmN0aW9ucyBmb3IgdGhlIFJTcGFkZSBmcmFtZXdvcmsuXG4gKiBUaGVzZSBmdW5jdGlvbnMgaGFuZGxlIGJyb3dzZXIgZGV0ZWN0aW9uLCB2aWV3cG9ydCB1dGlsaXRpZXMsIGFuZCBET00gbWFuaXB1bGF0aW9uLlxuICovXG5cbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbi8vIEJST1dTRVIgREVURUNUSU9OXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbi8qKlxuICogRGV0ZWN0cyBpZiB1c2VyIGlzIG9uIGEgbW9iaWxlIGRldmljZSBvciB1c2luZyBtb2JpbGUgdmlld3BvcnRcbiAqIEByZXR1cm5zIHtib29sZWFufSBUcnVlIGlmIG1vYmlsZSBkZXZpY2Ugb3Igdmlld3BvcnQgPCA5OTJweFxuICogQHRvZG8gSW1wcm92ZSB1c2VyIGFnZW50IGRldGVjdGlvbiBmb3IgYWxsIG1vYmlsZSBkZXZpY2VzXG4gKi9cbmZ1bmN0aW9uIGlzX21vYmlsZSgpIHtcbiAgICBpZiAoL0FuZHJvaWR8d2ViT1N8aVBob25lfGlQYWR8aVBvZHxCbGFja0JlcnJ5fElFTW9iaWxlfE9wZXJhIE1pbmkvaS50ZXN0KG5hdmlnYXRvci51c2VyQWdlbnQpKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH0gZWxzZSBpZiAoJCh3aW5kb3cpLndpZHRoKCkgPCA5OTIpIHtcbiAgICAgICAgLy8gOTkycHggPSBib290c3RyYXAgNCBjb2wtbWQtXG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG59XG5cbi8qKlxuICogRGV0ZWN0cyBpZiB1c2VyIGlzIG9uIGRlc2t0b3AgKG5vdCBtb2JpbGUpXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gVHJ1ZSBpZiBub3QgbW9iaWxlIGRldmljZS92aWV3cG9ydFxuICovXG5mdW5jdGlvbiBpc19kZXNrdG9wKCkge1xuICAgIHJldHVybiAhaXNfbW9iaWxlKCk7XG59XG5cbi8qKlxuICogRGV0ZWN0cyB0aGUgdXNlcidzIG9wZXJhdGluZyBzeXN0ZW1cbiAqIEByZXR1cm5zIHtzdHJpbmd9IE9TIG5hbWU6ICdNYWMgT1MnLCAnaVBob25lJywgJ2lQYWQnLCAnV2luZG93cycsICdBbmRyb2lkLVBob25lJywgJ0FuZHJvaWQtVGFibGV0JywgJ0xpbnV4Jywgb3IgJ1Vua25vd24nXG4gKi9cbmZ1bmN0aW9uIGdldF9vcygpIHtcbiAgICBsZXQgdXNlcl9hZ2VudCA9IHdpbmRvdy5uYXZpZ2F0b3IudXNlckFnZW50LFxuICAgICAgICBwbGF0Zm9ybSA9IHdpbmRvdy5uYXZpZ2F0b3IucGxhdGZvcm0sXG4gICAgICAgIG1hY29zX3BsYXRmb3JtcyA9IFsnTWFjaW50b3NoJywgJ01hY0ludGVsJywgJ01hY1BQQycsICdNYWM2OEsnXSxcbiAgICAgICAgd2luZG93c19wbGF0Zm9ybXMgPSBbJ1dpbjMyJywgJ1dpbjY0JywgJ1dpbmRvd3MnLCAnV2luQ0UnXSxcbiAgICAgICAgaW9zX3BsYXRmb3JtcyA9IFsnaVBob25lJywgJ2lQYWQnLCAnaVBvZCddLFxuICAgICAgICBvcyA9IG51bGw7XG5cbiAgICBsZXQgaXNfbW9iaWxlX2RldmljZSA9IGlzX21vYmlsZSgpO1xuXG4gICAgaWYgKG1hY29zX3BsYXRmb3Jtcy5pbmRleE9mKHBsYXRmb3JtKSAhPT0gLTEpIHtcbiAgICAgICAgb3MgPSAnTWFjIE9TJztcbiAgICB9IGVsc2UgaWYgKGlvc19wbGF0Zm9ybXMuaW5kZXhPZihwbGF0Zm9ybSkgIT09IC0xICYmIGlzX21vYmlsZV9kZXZpY2UpIHtcbiAgICAgICAgb3MgPSAnaVBob25lJztcbiAgICB9IGVsc2UgaWYgKGlvc19wbGF0Zm9ybXMuaW5kZXhPZihwbGF0Zm9ybSkgIT09IC0xICYmICFpc19tb2JpbGVfZGV2aWNlKSB7XG4gICAgICAgIG9zID0gJ2lQYWQnO1xuICAgIH0gZWxzZSBpZiAod2luZG93c19wbGF0Zm9ybXMuaW5kZXhPZihwbGF0Zm9ybSkgIT09IC0xKSB7XG4gICAgICAgIG9zID0gJ1dpbmRvd3MnO1xuICAgIH0gZWxzZSBpZiAoL0FuZHJvaWQvLnRlc3QodXNlcl9hZ2VudCkgJiYgaXNfbW9iaWxlX2RldmljZSkge1xuICAgICAgICBvcyA9ICdBbmRyb2lkLVBob25lJztcbiAgICB9IGVsc2UgaWYgKC9BbmRyb2lkLy50ZXN0KHVzZXJfYWdlbnQpICYmICFpc19tb2JpbGVfZGV2aWNlKSB7XG4gICAgICAgIG9zID0gJ0FuZHJvaWQtVGFibGV0JztcbiAgICB9IGVsc2UgaWYgKCFvcyAmJiAvTGludXgvLnRlc3QocGxhdGZvcm0pKSB7XG4gICAgICAgIG9zID0gJ0xpbnV4JztcbiAgICB9IGVsc2Uge1xuICAgICAgICBvcyA9ICdVbmtub3duJztcbiAgICB9XG5cbiAgICByZXR1cm4gb3M7XG59XG5cbi8qKlxuICogRGV0ZWN0cyBpZiB0aGUgdXNlciBhZ2VudCBpcyBhIHdlYiBjcmF3bGVyL2JvdFxuICogQHJldHVybnMge2Jvb2xlYW59IFRydWUgaWYgdXNlciBhZ2VudCBhcHBlYXJzIHRvIGJlIGEgYm90L2NyYXdsZXJcbiAqL1xuZnVuY3Rpb24gaXNfY3Jhd2xlcigpIHtcbiAgICBsZXQgdXNlcl9hZ2VudCA9IG5hdmlnYXRvci51c2VyQWdlbnQ7XG4gICAgbGV0IGJvdF9wYXR0ZXJuID0gL2JvdHxzcGlkZXJ8Y3Jhd2x8c2x1cnB8YXJjaGl2ZXJ8cGluZ3xzZWFyY2h8ZGlnfHRyYWNrZXJ8bW9uaXRvcnxzbm9vcHl8eWFob298YmFpZHV8bXNufGFza3x0ZW9tYXxheGlvcy9pO1xuXG4gICAgcmV0dXJuIGJvdF9wYXR0ZXJuLnRlc3QodXNlcl9hZ2VudCk7XG59XG5cbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbi8vIERPTSBTQ1JPTExJTkcgVVRJTElUSUVTXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbi8qKlxuICogU2Nyb2xscyBwYXJlbnQgY29udGFpbmVyIHRvIG1ha2UgdGFyZ2V0IGVsZW1lbnQgdmlzaWJsZSBpZiBuZWVkZWRcbiAqIEBwYXJhbSB7c3RyaW5nfEhUTUxFbGVtZW50fGpRdWVyeX0gdGFyZ2V0IC0gVGFyZ2V0IGVsZW1lbnQgdG8gc2Nyb2xsIGludG8gdmlld1xuICovXG5mdW5jdGlvbiBzY3JvbGxfaW50b192aWV3X2lmX25lZWRlZCh0YXJnZXQpIHtcbiAgICBjb25zdCAkdGFyZ2V0ID0gJCh0YXJnZXQpO1xuXG4gICAgLy8gRmluZCB0aGUgY2xvc2VzdCBwYXJlbnQgd2l0aCBvdmVyZmxvdy15OiBhdXRvXG4gICAgY29uc3QgJHBhcmVudCA9ICR0YXJnZXQucGFyZW50KCk7XG5cbiAgICAvLyBDYWxjdWxhdGUgdGhlIGFic29sdXRlIHRvcCBwb3NpdGlvbiBvZiB0aGUgdGFyZ2V0XG4gICAgY29uc3QgdGFyZ2V0X3RvcCA9ICR0YXJnZXQucG9zaXRpb24oKS50b3AgKyAkcGFyZW50LnNjcm9sbFRvcCgpO1xuXG4gICAgY29uc3QgdGFyZ2V0X2hlaWdodCA9ICR0YXJnZXQub3V0ZXJIZWlnaHQoKTtcbiAgICBjb25zdCBwYXJlbnRfaGVpZ2h0ID0gJHBhcmVudC5oZWlnaHQoKTtcbiAgICBjb25zdCBzY3JvbGxfcG9zaXRpb24gPSAkcGFyZW50LnNjcm9sbFRvcCgpO1xuXG4gICAgLy8gQ2hlY2sgaWYgdGhlIHRhcmdldCBpcyBvdXQgb2Ygdmlld1xuICAgIGlmICh0YXJnZXRfdG9wIDwgc2Nyb2xsX3Bvc2l0aW9uIHx8IHRhcmdldF90b3AgKyB0YXJnZXRfaGVpZ2h0ID4gc2Nyb2xsX3Bvc2l0aW9uICsgcGFyZW50X2hlaWdodCkge1xuICAgICAgICBEZWJ1Z2dlci5jb25zb2xlX2RlYnVnKCdVSScsICdTY3JvbGxpbmchJywgdGFyZ2V0X3RvcCk7XG5cbiAgICAgICAgLy8gQ2FsY3VsYXRlIHRoZSBuZXcgc2Nyb2xsIHBvc2l0aW9uIHRvIGNlbnRlciB0aGUgdGFyZ2V0XG4gICAgICAgIGxldCBuZXdfc2Nyb2xsX3Bvc2l0aW9uID0gdGFyZ2V0X3RvcCArIHRhcmdldF9oZWlnaHQgLyAyIC0gcGFyZW50X2hlaWdodCAvIDI7XG5cbiAgICAgICAgLy8gTGltaXQgdGhlIHNjcm9sbCBwb3NpdGlvbiBiZXR3ZWVuIDAgYW5kIHRoZSBtYXhpbXVtIHNjcm9sbGFibGUgaGVpZ2h0XG4gICAgICAgIG5ld19zY3JvbGxfcG9zaXRpb24gPSBNYXRoLm1heCgwLCBNYXRoLm1pbihuZXdfc2Nyb2xsX3Bvc2l0aW9uLCAkcGFyZW50WzBdLnNjcm9sbEhlaWdodCAtIHBhcmVudF9oZWlnaHQpKTtcblxuICAgICAgICAvLyBTY3JvbGwgdGhlIHBhcmVudCB0byB0aGUgbmV3IHNjcm9sbCBwb3NpdGlvblxuICAgICAgICAkcGFyZW50LnNjcm9sbFRvcChuZXdfc2Nyb2xsX3Bvc2l0aW9uKTtcbiAgICB9XG59XG5cbi8qKlxuICogU2Nyb2xscyBwYWdlIHRvIG1ha2UgdGFyZ2V0IGVsZW1lbnQgdmlzaWJsZSBpZiBuZWVkZWQgKHdpdGggYW5pbWF0aW9uKVxuICogQHBhcmFtIHtzdHJpbmd8SFRNTEVsZW1lbnR8alF1ZXJ5fSB0YXJnZXQgLSBUYXJnZXQgZWxlbWVudCB0byBzY3JvbGwgaW50byB2aWV3XG4gKi9cbmZ1bmN0aW9uIHNjcm9sbF9wYWdlX2ludG9fdmlld19pZl9uZWVkZWQodGFyZ2V0KSB7XG4gICAgY29uc3QgJHRhcmdldCA9ICQodGFyZ2V0KTtcblxuICAgIC8vIENhbGN1bGF0ZSB0aGUgYWJzb2x1dGUgdG9wIHBvc2l0aW9uIG9mIHRoZSB0YXJnZXQgcmVsYXRpdmUgdG8gdGhlIGRvY3VtZW50XG4gICAgY29uc3QgdGFyZ2V0X3RvcCA9ICR0YXJnZXQub2Zmc2V0KCkudG9wO1xuXG4gICAgY29uc3QgdGFyZ2V0X2hlaWdodCA9ICR0YXJnZXQub3V0ZXJIZWlnaHQoKTtcbiAgICBjb25zdCB3aW5kb3dfaGVpZ2h0ID0gJCh3aW5kb3cpLmhlaWdodCgpO1xuICAgIGNvbnN0IHdpbmRvd19zY3JvbGxfcG9zaXRpb24gPSAkKHdpbmRvdykuc2Nyb2xsVG9wKCk7XG5cbiAgICAvLyBDaGVjayBpZiB0aGUgdGFyZ2V0IGlzIG91dCBvZiB2aWV3XG4gICAgaWYgKHRhcmdldF90b3AgPCB3aW5kb3dfc2Nyb2xsX3Bvc2l0aW9uIHx8IHRhcmdldF90b3AgKyB0YXJnZXRfaGVpZ2h0ID4gd2luZG93X3Njcm9sbF9wb3NpdGlvbiArIHdpbmRvd19oZWlnaHQpIHtcbiAgICAgICAgRGVidWdnZXIuY29uc29sZV9kZWJ1ZygnVUknLCAnU2Nyb2xsaW5nIScsIHRhcmdldF90b3ApO1xuXG4gICAgICAgIC8vIENhbGN1bGF0ZSB0aGUgbmV3IHNjcm9sbCBwb3NpdGlvbiB0byBjZW50ZXIgdGhlIHRhcmdldFxuICAgICAgICBjb25zdCBuZXdfc2Nyb2xsX3Bvc2l0aW9uID0gdGFyZ2V0X3RvcCArIHRhcmdldF9oZWlnaHQgLyAyIC0gd2luZG93X2hlaWdodCAvIDI7XG5cbiAgICAgICAgLy8gQW5pbWF0ZSB0aGUgc2Nyb2xsIHRvIHRoZSBuZXcgcG9zaXRpb25cbiAgICAgICAgJCgnaHRtbCwgYm9keScpLmFuaW1hdGUoXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgc2Nyb2xsVG9wOiBuZXdfc2Nyb2xsX3Bvc2l0aW9uLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIDEwMDBcbiAgICAgICAgKTsgLy8gZHVyYXRpb24gb2YgdGhlIHNjcm9sbCBhbmltYXRpb24gaW4gbWlsbGlzZWNvbmRzXG4gICAgfVxufVxuXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4vLyBET00gVVRJTElUSUVTXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbi8qKlxuICogV2FpdHMgZm9yIGFsbCBpbWFnZXMgb24gdGhlIHBhZ2UgdG8gbG9hZFxuICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2sgLSBGdW5jdGlvbiB0byBjYWxsIHdoZW4gYWxsIGltYWdlcyBhcmUgbG9hZGVkXG4gKi9cbmZ1bmN0aW9uIHdhaXRfZm9yX2ltYWdlcyhjYWxsYmFjaykge1xuICAgIGNvbnN0ICRpbWFnZXMgPSAkKCdpbWcnKTsgLy8gR2V0IGFsbCBpbWcgdGFnc1xuICAgIGNvbnN0IHRvdGFsX2ltYWdlcyA9ICRpbWFnZXMubGVuZ3RoO1xuICAgIGxldCBpbWFnZXNfbG9hZGVkID0gMDtcblxuICAgIGlmICh0b3RhbF9pbWFnZXMgPT09IDApIHtcbiAgICAgICAgY2FsbGJhY2soKTsgLy8gaWYgdGhlcmUgYXJlIG5vIGltYWdlcywgaW1tZWRpYXRlbHkgY2FsbCB0aGUgY2FsbGJhY2tcbiAgICB9XG5cbiAgICAkaW1hZ2VzLmVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgICBjb25zdCBpbWcgPSBuZXcgSW1hZ2UoKTtcbiAgICAgICAgaW1nLm9ubG9hZCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGltYWdlc19sb2FkZWQrKztcbiAgICAgICAgICAgIGlmIChpbWFnZXNfbG9hZGVkID09PSB0b3RhbF9pbWFnZXMpIHtcbiAgICAgICAgICAgICAgICBjYWxsYmFjaygpOyAvLyBjYWxsIHRoZSBjYWxsYmFjayB3aGVuIGFsbCBpbWFnZXMgYXJlIGxvYWRlZFxuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICBpbWcub25lcnJvciA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGltYWdlc19sb2FkZWQrKztcbiAgICAgICAgICAgIGlmIChpbWFnZXNfbG9hZGVkID09PSB0b3RhbF9pbWFnZXMpIHtcbiAgICAgICAgICAgICAgICBjYWxsYmFjaygpOyAvLyBhbHNvIGNhbGwgdGhlIGNhbGxiYWNrIGlmIGFuIGltYWdlIGZhaWxzIHRvIGxvYWRcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgaW1nLnNyYyA9IHRoaXMuc3JjOyAvLyB0aGlzIHRyaWdnZXJzIHRoZSBsb2FkaW5nXG4gICAgfSk7XG59XG5cbi8qKlxuICogQ3JlYXRlcyBhIGpRdWVyeSBlbGVtZW50IGNvbnRhaW5pbmcgYSBub24tYnJlYWtpbmcgc3BhY2VcbiAqIEByZXR1cm5zIHtqUXVlcnl9IGpRdWVyeSBzcGFuIGVsZW1lbnQgd2l0aCAmbmJzcDtcbiAqL1xuZnVuY3Rpb24gJG5ic3AoKSB7XG4gICAgcmV0dXJuICQoJzxzcGFuPiZuYnNwOzwvc3Bhbj4nKTtcbn1cblxuLyoqXG4gKiBFc2NhcGVzIHNwZWNpYWwgY2hhcmFjdGVycyBpbiBhIGpRdWVyeSBzZWxlY3RvclxuICogQHBhcmFtIHtzdHJpbmd9IGlkIC0gRWxlbWVudCBJRCB0byBlc2NhcGVcbiAqIEByZXR1cm5zIHtzdHJpbmd9IGpRdWVyeSBzZWxlY3RvciBzdHJpbmcgd2l0aCBlc2NhcGVkIHNwZWNpYWwgY2hhcmFjdGVyc1xuICogQHdhcm5pbmcgTm90IHNhZmUgZm9yIHNlY3VyaXR5LWNyaXRpY2FsIG9wZXJhdGlvbnNcbiAqL1xuZnVuY3Rpb24gZXNjYXBlX2pxX3NlbGVjdG9yKGlkKSB7XG4gICAgcmV0dXJuICcjJyArIGlkLnJlcGxhY2UoLyg6fFxcLnxcXFt8XFxdfCx8PXxAKS9nLCAnXFxcXCQxJyk7XG59IiwiLypcbiAqIERhdGUgYW5kIHRpbWUgdXRpbGl0eSBmdW5jdGlvbnMgZm9yIHRoZSBSU3BhZGUgZnJhbWV3b3JrLlxuICogVGhlc2UgZnVuY3Rpb25zIGhhbmRsZSBkYXRlL3RpbWUgY29udmVyc2lvbnMgYW5kIFVuaXggdGltZXN0YW1wcy5cbiAqL1xuXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4vLyBEQVRFL1RJTUUgVVRJTElUSUVTXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbi8qKlxuICogR2V0cyB0aGUgY3VycmVudCBVbml4IHRpbWVzdGFtcCAoc2Vjb25kcyBzaW5jZSBlcG9jaClcbiAqIEByZXR1cm5zIHtudW1iZXJ9IEN1cnJlbnQgVW5peCB0aW1lc3RhbXAgaW4gc2Vjb25kc1xuICogQHRvZG8gQ2FsY3VsYXRlIGJhc2VkIG9uIHNlcnZlciB0aW1lIGF0IHBhZ2UgcmVuZGVyXG4gKiBAdG9kbyBNb3ZlIHRvIGEgZGF0ZSBsaWJyYXJ5XG4gKi9cbmZ1bmN0aW9uIHVuaXhfdGltZSgpIHtcbiAgICByZXR1cm4gTWF0aC5yb3VuZChuZXcgRGF0ZSgpLmdldFRpbWUoKSAvIDEwMDApO1xufVxuXG4vKipcbiAqIENvbnZlcnRzIGEgZGF0ZSBzdHJpbmcgdG8gVW5peCB0aW1lc3RhbXBcbiAqIEBwYXJhbSB7c3RyaW5nfSBzdHJfZGF0ZSAtIERhdGUgc3RyaW5nIChZLW0tZCBIOmk6cyBmb3JtYXQpXG4gKiBAcmV0dXJucyB7bnVtYmVyfSBVbml4IHRpbWVzdGFtcCBpbiBzZWNvbmRzXG4gKi9cbmZ1bmN0aW9uIHltZGhpc190b191bml4KHN0cl9kYXRlKSB7XG4gICAgY29uc3QgZGF0ZSA9IG5ldyBEYXRlKHN0cl9kYXRlKTtcbiAgICByZXR1cm4gZGF0ZS5nZXRUaW1lKCkgLyAxMDAwO1xufSIsIi8qXG4gKiBFcnJvciBoYW5kbGluZyB1dGlsaXR5IGZ1bmN0aW9ucyBmb3IgdGhlIFJTcGFkZSBmcmFtZXdvcmsuXG4gKiBUaGVzZSBmdW5jdGlvbnMgaGFuZGxlIGVycm9yIGNyZWF0aW9uIGFuZCBkZWJ1Z2dpbmcgdXRpbGl0aWVzLlxuICovXG5cbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbi8vIEVSUk9SIEhBTkRMSU5HXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbi8qKlxuICogQ3JlYXRlcyBhbiBlcnJvciBvYmplY3QgZnJvbSBhIHN0cmluZ1xuICogQHBhcmFtIHtzdHJpbmd8T2JqZWN0fSBzdHIgLSBFcnJvciBtZXNzYWdlIG9yIGV4aXN0aW5nIGVycm9yIG9iamVjdFxuICogQHBhcmFtIHtudW1iZXJ9IFtlcnJvcl9jb2RlXSAtIE9wdGlvbmFsIGVycm9yIHN0YXR1cyBjb2RlXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBFcnJvciBvYmplY3Qgd2l0aCBlcnJvciBhbmQgc3RhdHVzIHByb3BlcnRpZXNcbiAqL1xuZnVuY3Rpb24gZXJyb3Ioc3RyLCBlcnJvcl9jb2RlKSB7XG4gICAgaWYgKHR5cGVvZiBzdHIuZXJyb3IgIT0gdW5kZWYpIHtcbiAgICAgICAgcmV0dXJuIHN0cjtcbiAgICB9IGVsc2Uge1xuICAgICAgICBpZiAodHlwZW9mIGVycm9yX2NvZGUgPT0gdW5kZWYpIHtcbiAgICAgICAgICAgIHJldHVybiB7IGVycm9yOiBzdHIsIHN0YXR1czogbnVsbCB9O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIHsgZXJyb3I6IHN0ciwgc3RhdHVzOiBlcnJvcl9jb2RlIH07XG4gICAgICAgIH1cbiAgICB9XG59XG5cbi8qKlxuICogU2FuaXR5IGNoZWNrIGZhaWx1cmUgaGFuZGxlciBmb3IgSmF2YVNjcmlwdFxuICpcbiAqIFRoaXMgZnVuY3Rpb24gc2hvdWxkIGJlIGNhbGxlZCB3aGVuIGEgc2FuaXR5IGNoZWNrIGZhaWxzIC0gaS5lLiwgd2hlbiB0aGUgY29kZVxuICogZW5jb3VudGVycyBhIGNvbmRpdGlvbiB0aGF0IFwic2hvdWxkbid0IGhhcHBlblwiIGlmIGV2ZXJ5dGhpbmcgaXMgd29ya2luZyBjb3JyZWN0bHkuXG4gKlxuICogVW5saWtlIFBIUCwgd2UgY2FuJ3Qgc3RvcCBKYXZhU2NyaXB0IGV4ZWN1dGlvbiwgYnV0IHdlIGNhbjpcbiAqIDEuIFRocm93IGFuIGVycm9yIHRoYXQgd2lsbCBiZSBjYXVnaHQgYnkgZXJyb3IgaGFuZGxlcnNcbiAqIDIuIExvZyBhIGNsZWFyIGVycm9yIHRvIHRoZSBjb25zb2xlXG4gKiAzLiBQcm92aWRlIHN0YWNrIHRyYWNlIGZvciBkZWJ1Z2dpbmdcbiAqXG4gKiBVc2UgdGhpcyBpbnN0ZWFkIG9mIHNpbGVudGx5IHJldHVybmluZyBvciBjb250aW51aW5nIHdoZW4gZW5jb3VudGVyaW5nIHVuZXhwZWN0ZWQgY29uZGl0aW9ucy5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gbWVzc2FnZSBPcHRpb25hbCBzcGVjaWZpYyBtZXNzYWdlIGFib3V0IHdoYXQgc2hvdWxkbid0IGhhdmUgaGFwcGVuZWRcbiAqIEB0aHJvd3Mge0Vycm9yfSBBbHdheXMgdGhyb3dzIHdpdGggbG9jYXRpb24gYW5kIGNvbnRleHQgaW5mb3JtYXRpb25cbiAqL1xuZnVuY3Rpb24gc2hvdWxkbnRfaGFwcGVuKG1lc3NhZ2UgPSBudWxsKSB7XG4gICAgY29uc3QgZXJyb3IgPSBuZXcgRXJyb3IoKTtcbiAgICBjb25zdCBzdGFjayA9IGVycm9yLnN0YWNrIHx8ICcnO1xuICAgIGNvbnN0IHN0YWNrTGluZXMgPSBzdGFjay5zcGxpdCgnXFxuJyk7XG5cbiAgICAvLyBHZXQgdGhlIGNhbGxlciBsb2NhdGlvbiAoc2tpcCB0aGUgRXJyb3IgbGluZSBhbmQgdGhpcyBmdW5jdGlvbilcbiAgICBsZXQgY2FsbGVySW5mbyA9ICd1bmtub3duIGxvY2F0aW9uJztcbiAgICBpZiAoc3RhY2tMaW5lcy5sZW5ndGggPiAyKSB7XG4gICAgICAgIGNvbnN0IGNhbGxlckxpbmUgPSBzdGFja0xpbmVzWzJdIHx8IHN0YWNrTGluZXNbMV0gfHwgJyc7XG4gICAgICAgIC8vIEV4dHJhY3QgZmlsZSBhbmQgbGluZSBudW1iZXIgZnJvbSBzdGFjayB0cmFjZVxuICAgICAgICBjb25zdCBtYXRjaCA9IGNhbGxlckxpbmUubWF0Y2goL2F0XFxzKy4qP1xccytcXCgoLio/KTooXFxkKyk6KFxcZCspXFwpLykgfHwgY2FsbGVyTGluZS5tYXRjaCgvYXRcXHMrKC4qPyk6KFxcZCspOihcXGQrKS8pO1xuICAgICAgICBpZiAobWF0Y2gpIHtcbiAgICAgICAgICAgIGNhbGxlckluZm8gPSBgJHttYXRjaFsxXX06JHttYXRjaFsyXX1gO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgbGV0IGVycm9yTWVzc2FnZSA9IGBGYXRhbDogc2hvdWxkbnRfaGFwcGVuKCkgd2FzIGNhbGxlZCBhdCAke2NhbGxlckluZm99XFxuYDtcbiAgICBlcnJvck1lc3NhZ2UgKz0gJ1RoaXMgaW5kaWNhdGVzIGEgc2FuaXR5IGNoZWNrIGZhaWxlZCAtIHRoZSBjb2RlIGlzIG5vdCBiZWhhdmluZyBhcyBleHBlY3RlZC5cXG4nO1xuXG4gICAgaWYgKG1lc3NhZ2UpIHtcbiAgICAgICAgZXJyb3JNZXNzYWdlICs9IGBEZXRhaWxzOiAke21lc3NhZ2V9XFxuYDtcbiAgICB9XG5cbiAgICBlcnJvck1lc3NhZ2UgKz0gJ1BsZWFzZSB0aG9yb3VnaGx5IHJldmlldyB0aGUgcmVsYXRlZCBjb2RlIHRvIGRldGVybWluZSB3aHkgdGhpcyBlcnJvciBvY2N1cnJlZC4nO1xuXG4gICAgLy8gTG9nIHRvIGNvbnNvbGUgd2l0aCBmdWxsIHZpc2liaWxpdHlcbiAgICBjb25zb2xlLmVycm9yKCc9Jy5yZXBlYXQoODApKTtcbiAgICBjb25zb2xlLmVycm9yKCdTQU5JVFkgQ0hFQ0sgRkFJTFVSRScpO1xuICAgIGNvbnNvbGUuZXJyb3IoJz0nLnJlcGVhdCg4MCkpO1xuICAgIGNvbnNvbGUuZXJyb3IoZXJyb3JNZXNzYWdlKTtcbiAgICBjb25zb2xlLmVycm9yKCdTdGFjayB0cmFjZTonLCBzdGFjayk7XG4gICAgY29uc29sZS5lcnJvcignPScucmVwZWF0KDgwKSk7XG5cbiAgICAvLyBUaHJvdyBlcnJvciB0byBzdG9wIGV4ZWN1dGlvbiBmbG93XG4gICAgY29uc3QgZmF0YWxFcnJvciA9IG5ldyBFcnJvcihlcnJvck1lc3NhZ2UpO1xuICAgIGZhdGFsRXJyb3IubmFtZSA9ICdTYW5pdHlDaGVja0ZhaWx1cmUnO1xuICAgIHRocm93IGZhdGFsRXJyb3I7XG59IiwiLypcbiAqIEhhc2hpbmcgYW5kIGNvbXBhcmlzb24gdXRpbGl0eSBmdW5jdGlvbnMgZm9yIHRoZSBSU3BhZGUgZnJhbWV3b3JrLlxuICogVGhlc2UgZnVuY3Rpb25zIGhhbmRsZSBvYmplY3QgaGFzaGluZyBhbmQgZGVlcCBjb21wYXJpc29uLlxuICovXG5cbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbi8vIEhBU0hJTkcgQU5EIENPTVBBUklTT05cbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuLyoqXG4gKiBHZW5lcmF0ZXMgYSB1bmlxdWUgaGFzaCBmb3IgYW55IHZhbHVlIChoYW5kbGVzIG9iamVjdHMsIGFycmF5cywgY2lyY3VsYXIgcmVmZXJlbmNlcylcbiAqIEBwYXJhbSB7Kn0gdGhlX3ZhciAtIFZhbHVlIHRvIGhhc2hcbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW2NhbGNfc2hhMT10cnVlXSAtIElmIHRydWUsIHJldHVybnMgU0hBMSBoYXNoOyBpZiBmYWxzZSwgcmV0dXJucyBKU09OXG4gKiBAcGFyYW0ge0FycmF5PHN0cmluZz59IFtpZ25vcmVkX2tleXM9bnVsbF0gLSBLZXlzIHRvIGlnbm9yZSB3aGVuIGhhc2hpbmcgb2JqZWN0c1xuICogQHJldHVybnMge3N0cmluZ30gU0hBMSBoYXNoIG9yIEpTT04gc3RyaW5nIG9mIHRoZSB2YWx1ZVxuICovXG5mdW5jdGlvbiBoYXNoKHRoZV92YXIsIGNhbGNfc2hhMSA9IHRydWUsIGlnbm9yZWRfa2V5cyA9IG51bGwpIHtcbiAgICBpZiAodHlwZW9mIHRoZV92YXIgPT0gdW5kZWYpIHtcbiAgICAgICAgdGhlX3ZhciA9ICdfX3VuZGVmaW5lZF9fJztcbiAgICB9XG5cbiAgICBpZiAoaWdub3JlZF9rZXlzID09PSBudWxsKSB7XG4gICAgICAgIGlnbm9yZWRfa2V5cyA9IFsnJCddO1xuICAgIH1cblxuICAgIC8vIENvbnZlcnRzIHZhbHVlIHRvIGpzb24sIGRpc2NhcmRpbmcgY2lyY3VsYXIgcmVmZXJlbmNlc1xuICAgIGxldCBqc29uX3N0cmluZ2lmeV9ub2NpcmMgPSBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgY29uc3QgY2FjaGUgPSBbXTtcbiAgICAgICAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KHZhbHVlLCBmdW5jdGlvbiAoa2V5LCB2KSB7XG4gICAgICAgICAgICBpZiAodHlwZW9mIHYgPT09ICdvYmplY3QnICYmIHR5cGVvZiB0aGVfdmFyLl9jYWNoZV9rZXkgPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGVfdmFyLl9oYXNoX2tleSgpO1xuICAgICAgICAgICAgfSBlbHNlIGlmICh0eXBlb2YgdiA9PT0gJ29iamVjdCcgJiYgdiAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIGlmIChjYWNoZS5pbmRleE9mKHYpICE9PSAtMSkge1xuICAgICAgICAgICAgICAgICAgICAvLyBEdXBsaWNhdGUgcmVmZXJlbmNlIGZvdW5kLCBkaXNjYXJkIGtleVxuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNhY2hlLnB1c2godik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gdjtcbiAgICAgICAgfSk7XG4gICAgfTtcblxuICAgIC8vIFR1cm4gZXZlcnkgcHJvcGVydHkgYW5kIGFsbCBpdHMgY2hpbGRyZW4gaW50byBhIHNpbmdsZSBkZXB0aCBhcnJheSBvZiB2YWx1ZXMgdGhhdCB3ZSBjYW4gdGhlblxuICAgIC8vIHNvcnQgYW5kIGhhc2ggYXMgYSB3aG9sZVxuICAgIGxldCBmbGF0X3ZhciA9IHt9O1xuICAgIGxldCBfZmxhdHRlbiA9IGZ1bmN0aW9uICh0aGVfdmFyLCBwcmVmaXgsIGRlcHRoID0gMCkge1xuICAgICAgICAvLyBJZiBhIGNsYXNzIG9iamVjdCBpcyBwcm92aWRlZCwgY2lyY3VsYXIgcmVmZXJlbmNlcyBjYW4gbWFrZSB0aGUgY2FsbCBzdGFjayByZWN1cnNpdmUuXG4gICAgICAgIC8vIEZvciB0aGUgcHVycG9zZXMgb2YgaG93IHRoZSBoYXNoIGZ1bmN0aW9uIGlzIGNhbGxlZCwgdGhpcyBzaG91bGQgYmUgc3VmZmljaWVudC5cbiAgICAgICAgaWYgKGRlcHRoID4gMTApIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIERvZXMgbm90IGFjY291bnQgZm9yIGRhdGVzIGkgdGhpbmsuLi5cblxuICAgICAgICBpZiAoaXNfb2JqZWN0KHRoZV92YXIpICYmIHR5cGVvZiB0aGVfdmFyLl9jYWNoZV9rZXkgPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgLy8gVXNlIF9jYWNoZV9rZXkgdG8gaGFzaCBjb21wb25lbnRzXG4gICAgICAgICAgICBmbGF0X3ZhcltwcmVmaXhdID0gdGhlX3Zhci5faGFzaF9rZXkoKTtcbiAgICAgICAgfSBlbHNlIGlmIChpc19vYmplY3QodGhlX3ZhcikgJiYgdHlwZW9mIEFic3RyYWN0ICE9PSAndW5kZWZpbmVkJyAmJiB0aGVfdmFyIGluc3RhbmNlb2YgQWJzdHJhY3QpIHtcbiAgICAgICAgICAgIC8vIFN0cmluZ2lmeSBhbGwgY2xhc3Mgb2JqZWN0c1xuICAgICAgICAgICAgZmxhdF92YXJbcHJlZml4XSA9IGpzb25fc3RyaW5naWZ5X25vY2lyYyh0aGVfdmFyKTtcbiAgICAgICAgfSBlbHNlIGlmIChpc19vYmplY3QodGhlX3ZhcikpIHtcbiAgICAgICAgICAgIC8vIEl0ZXJhdGUgb3RoZXIgb2JqZWN0c1xuICAgICAgICAgICAgZmxhdF92YXJbcHJlZml4XSA9IHt9O1xuICAgICAgICAgICAgZm9yIChsZXQgayBpbiB0aGVfdmFyKSB7XG4gICAgICAgICAgICAgICAgaWYgKHRoZV92YXIuaGFzT3duUHJvcGVydHkoaykgJiYgaWdub3JlZF9rZXlzLmluZGV4T2YoaykgPT0gLTEpIHtcbiAgICAgICAgICAgICAgICAgICAgX2ZsYXR0ZW4odGhlX3ZhcltrXSwgcHJlZml4ICsgJy4uJyArIGssIGRlcHRoICsgMSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2UgaWYgKGlzX2FycmF5KHRoZV92YXIpKSB7XG4gICAgICAgICAgICAvLyBJdGVyYXRlIGFycmF5c1xuICAgICAgICAgICAgZmxhdF92YXJbcHJlZml4XSA9IFtdO1xuICAgICAgICAgICAgbGV0IGkgPSAwO1xuICAgICAgICAgICAgZm9yZWFjaCh0aGVfdmFyLCAodikgPT4ge1xuICAgICAgICAgICAgICAgIF9mbGF0dGVuKHYsIHByZWZpeCArICcuLicgKyBpLCBkZXB0aCArIDEpO1xuICAgICAgICAgICAgICAgIGkrKztcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9IGVsc2UgaWYgKGlzX2Z1bmN0aW9uKHRoZV92YXIpKSB7XG4gICAgICAgICAgICAvLyBub3RoaW5nXG4gICAgICAgIH0gZWxzZSBpZiAoIWlzX251bWVyaWModGhlX3ZhcikpIHtcbiAgICAgICAgICAgIGZsYXRfdmFyW3ByZWZpeF0gPSBTdHJpbmcodGhlX3Zhcik7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBmbGF0X3ZhcltwcmVmaXhdID0gdGhlX3ZhcjtcbiAgICAgICAgfVxuICAgIH07XG5cbiAgICBfZmxhdHRlbih0aGVfdmFyLCAnXycpO1xuXG4gICAgbGV0IHNvcnRlciA9IFtdO1xuXG4gICAgZm9yZWFjaChmbGF0X3ZhciwgZnVuY3Rpb24gKHYsIGspIHtcbiAgICAgICAgc29ydGVyLnB1c2goW2ssIHZdKTtcbiAgICB9KTtcblxuICAgIHNvcnRlci5zb3J0KGZ1bmN0aW9uIChhLCBiKSB7XG4gICAgICAgIHJldHVybiBhWzBdID4gYlswXTtcbiAgICB9KTtcblxuICAgIGxldCBqc29uID0gSlNPTi5zdHJpbmdpZnkoc29ydGVyKTtcblxuICAgIGlmIChjYWxjX3NoYTEpIHtcbiAgICAgICAgbGV0IGhhc2hlZCA9IHNoYTEuc2hhMShqc29uKTtcbiAgICAgICAgcmV0dXJuIGhhc2hlZDtcbiAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4ganNvbjtcbiAgICB9XG59XG5cbi8qKlxuICogRGVlcCBjb21wYXJpc29uIG9mIHR3byB2YWx1ZXMgKGlnbm9yZXMgcHJvcGVydHkgb3JkZXIgYW5kIGZ1bmN0aW9ucylcbiAqIEBwYXJhbSB7Kn0gYSAtIEZpcnN0IHZhbHVlIHRvIGNvbXBhcmVcbiAqIEBwYXJhbSB7Kn0gYiAtIFNlY29uZCB2YWx1ZSB0byBjb21wYXJlXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gVHJ1ZSBpZiB2YWx1ZXMgYXJlIGRlZXBseSBlcXVhbFxuICovXG5mdW5jdGlvbiBkZWVwX2VxdWFsKGEsIGIpIHtcbiAgICByZXR1cm4gaGFzaChhLCBmYWxzZSkgPT0gaGFzaChiLCBmYWxzZSk7XG59IiwiLyoqXG4gKiBNdXRleCBkZWNvcmF0b3IgZm9yIGV4Y2x1c2l2ZSBtZXRob2QgZXhlY3V0aW9uXG4gKlxuICogV2l0aG91dCBhcmd1bWVudHM6IFBlci1pbnN0YW5jZSBsb2NraW5nIChlYWNoIG9iamVjdCBoYXMgaXRzIG93biBsb2NrIHBlciBtZXRob2QpXG4gKiAgIEBtdXRleFxuICogICBhc3luYyBteV9tZXRob2QoKSB7IC4uLiB9XG4gKlxuICogV2l0aCBJRCBhcmd1bWVudDogR2xvYmFsIGxvY2tpbmcgYnkgSUQgKGFsbCBpbnN0YW5jZXMgc2hhcmUgdGhlIGxvY2spXG4gKiAgIEBtdXRleCgnb3BlcmF0aW9uX25hbWUnKVxuICogICBhc3luYyBteV9tZXRob2QoKSB7IC4uLiB9XG4gKlxuICogQGRlY29yYXRvclxuICogQHBhcmFtIHtzdHJpbmd9IFtnbG9iYWxfaWRdIC0gT3B0aW9uYWwgZ2xvYmFsIG11dGV4IElEIGZvciBjcm9zcy1pbnN0YW5jZSBsb2NraW5nXG4gKi9cbmZ1bmN0aW9uIG11dGV4KGdsb2JhbF9pZCkge1xuICAgIC8vIFN0b3JhZ2UgKHVzaW5nIElJRkVzIHRvIGtlZXAgV2Vha01hcC9NYXAgaW4gY2xvc3VyZSBzY29wZSlcbiAgICBjb25zdCBpbnN0YW5jZV9tdXRleGVzID0gKGZ1bmN0aW9uKCkge1xuICAgICAgICBpZiAoIW11dGV4Ll9pbnN0YW5jZV9zdG9yYWdlKSB7XG4gICAgICAgICAgICBtdXRleC5faW5zdGFuY2Vfc3RvcmFnZSA9IG5ldyBXZWFrTWFwKCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG11dGV4Ll9pbnN0YW5jZV9zdG9yYWdlO1xuICAgIH0pKCk7XG5cbiAgICBjb25zdCBnbG9iYWxfbXV0ZXhlcyA9IChmdW5jdGlvbigpIHtcbiAgICAgICAgaWYgKCFtdXRleC5fZ2xvYmFsX3N0b3JhZ2UpIHtcbiAgICAgICAgICAgIG11dGV4Ll9nbG9iYWxfc3RvcmFnZSA9IG5ldyBNYXAoKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbXV0ZXguX2dsb2JhbF9zdG9yYWdlO1xuICAgIH0pKCk7XG5cbiAgICAvKipcbiAgICAgKiBHZXQgb3IgY3JlYXRlIGEgbXV0ZXggZm9yIGEgc3BlY2lmaWMgaW5zdGFuY2UgYW5kIG1ldGhvZFxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGdldF9pbnN0YW5jZV9tdXRleChpbnN0YW5jZSwgbWV0aG9kX25hbWUpIHtcbiAgICAgICAgbGV0IGluc3RhbmNlX2xvY2tzID0gaW5zdGFuY2VfbXV0ZXhlcy5nZXQoaW5zdGFuY2UpO1xuICAgICAgICBpZiAoIWluc3RhbmNlX2xvY2tzKSB7XG4gICAgICAgICAgICBpbnN0YW5jZV9sb2NrcyA9IG5ldyBNYXAoKTtcbiAgICAgICAgICAgIGluc3RhbmNlX211dGV4ZXMuc2V0KGluc3RhbmNlLCBpbnN0YW5jZV9sb2Nrcyk7XG4gICAgICAgIH1cblxuICAgICAgICBsZXQgbG9ja19zdGF0ZSA9IGluc3RhbmNlX2xvY2tzLmdldChtZXRob2RfbmFtZSk7XG4gICAgICAgIGlmICghbG9ja19zdGF0ZSkge1xuICAgICAgICAgICAgbG9ja19zdGF0ZSA9IHsgYWN0aXZlOiBmYWxzZSwgcXVldWU6IFtdIH07XG4gICAgICAgICAgICBpbnN0YW5jZV9sb2Nrcy5zZXQobWV0aG9kX25hbWUsIGxvY2tfc3RhdGUpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGxvY2tfc3RhdGU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0IG9yIGNyZWF0ZSBhIGdsb2JhbCBtdXRleCBieSBJRFxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGdldF9nbG9iYWxfbXV0ZXgoaWQpIHtcbiAgICAgICAgbGV0IGxvY2tfc3RhdGUgPSBnbG9iYWxfbXV0ZXhlcy5nZXQoaWQpO1xuICAgICAgICBpZiAoIWxvY2tfc3RhdGUpIHtcbiAgICAgICAgICAgIGxvY2tfc3RhdGUgPSB7IGFjdGl2ZTogZmFsc2UsIHF1ZXVlOiBbXSB9O1xuICAgICAgICAgICAgZ2xvYmFsX211dGV4ZXMuc2V0KGlkLCBsb2NrX3N0YXRlKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbG9ja19zdGF0ZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBFeGVjdXRlIHRoZSBuZXh0IHF1ZXVlZCBvcGVyYXRpb24gZm9yIGEgbXV0ZXhcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBzY2hlZHVsZV9uZXh0KGxvY2tfc3RhdGUpIHtcbiAgICAgICAgaWYgKGxvY2tfc3RhdGUuYWN0aXZlIHx8IGxvY2tfc3RhdGUucXVldWUubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCB7IGZuLCByZXNvbHZlLCByZWplY3QgfSA9IGxvY2tfc3RhdGUucXVldWUuc2hpZnQoKTtcbiAgICAgICAgbG9ja19zdGF0ZS5hY3RpdmUgPSB0cnVlO1xuXG4gICAgICAgIFByb21pc2UucmVzb2x2ZSgpXG4gICAgICAgICAgICAudGhlbihmbilcbiAgICAgICAgICAgIC50aGVuKHJlc29sdmUsIHJlamVjdClcbiAgICAgICAgICAgIC5maW5hbGx5KCgpID0+IHtcbiAgICAgICAgICAgICAgICBsb2NrX3N0YXRlLmFjdGl2ZSA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIHNjaGVkdWxlX25leHQobG9ja19zdGF0ZSk7XG4gICAgICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBY3F1aXJlIGEgbXV0ZXggbG9jayBhbmQgZXhlY3V0ZSBjYWxsYmFja1xuICAgICAqL1xuICAgIGZ1bmN0aW9uIGFjcXVpcmVfbG9jayhsb2NrX3N0YXRlLCBmbikge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgbG9ja19zdGF0ZS5xdWV1ZS5wdXNoKHsgZm4sIHJlc29sdmUsIHJlamVjdCB9KTtcbiAgICAgICAgICAgIHNjaGVkdWxlX25leHQobG9ja19zdGF0ZSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8vIElmIGNhbGxlZCB3aXRoIGFuIElEIGFyZ3VtZW50OiBAbXV0ZXgoJ2lkJylcbiAgICBpZiAodHlwZW9mIGdsb2JhbF9pZCA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uKHRhcmdldCwga2V5LCBkZXNjcmlwdG9yKSB7XG4gICAgICAgICAgICBjb25zdCBvcmlnaW5hbF9tZXRob2QgPSBkZXNjcmlwdG9yLnZhbHVlO1xuXG4gICAgICAgICAgICBpZiAodHlwZW9mIG9yaWdpbmFsX21ldGhvZCAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgQG11dGV4IGNhbiBvbmx5IGJlIGFwcGxpZWQgdG8gbWV0aG9kcyAodHJpZWQgdG8gYXBwbHkgdG8gJHtrZXl9KWApO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBkZXNjcmlwdG9yLnZhbHVlID0gZnVuY3Rpb24oLi4uYXJncykge1xuICAgICAgICAgICAgICAgIGNvbnN0IGxvY2tfc3RhdGUgPSBnZXRfZ2xvYmFsX211dGV4KGdsb2JhbF9pZCk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGFjcXVpcmVfbG9jayhsb2NrX3N0YXRlLCAoKSA9PiBvcmlnaW5hbF9tZXRob2QuYXBwbHkodGhpcywgYXJncykpO1xuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgcmV0dXJuIGRlc2NyaXB0b3I7XG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgLy8gSWYgY2FsbGVkIHdpdGhvdXQgYXJndW1lbnRzOiBAbXV0ZXggKHRhcmdldCBpcyB0aGUgZmlyc3QgYXJndW1lbnQpXG4gICAgY29uc3QgdGFyZ2V0ID0gZ2xvYmFsX2lkOyAgLy8gSW4gdGhpcyBjYXNlLCBmaXJzdCBhcmcgaXMgdGFyZ2V0XG4gICAgY29uc3Qga2V5ID0gYXJndW1lbnRzWzFdO1xuICAgIGNvbnN0IGRlc2NyaXB0b3IgPSBhcmd1bWVudHNbMl07XG5cbiAgICBjb25zdCBvcmlnaW5hbF9tZXRob2QgPSBkZXNjcmlwdG9yLnZhbHVlO1xuXG4gICAgaWYgKHR5cGVvZiBvcmlnaW5hbF9tZXRob2QgIT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBAbXV0ZXggY2FuIG9ubHkgYmUgYXBwbGllZCB0byBtZXRob2RzICh0cmllZCB0byBhcHBseSB0byAke2tleX0pYCk7XG4gICAgfVxuXG4gICAgZGVzY3JpcHRvci52YWx1ZSA9IGZ1bmN0aW9uKC4uLmFyZ3MpIHtcbiAgICAgICAgY29uc3QgbG9ja19zdGF0ZSA9IGdldF9pbnN0YW5jZV9tdXRleCh0aGlzLCBrZXkpO1xuICAgICAgICByZXR1cm4gYWNxdWlyZV9sb2NrKGxvY2tfc3RhdGUsICgpID0+IG9yaWdpbmFsX21ldGhvZC5hcHBseSh0aGlzLCBhcmdzKSk7XG4gICAgfTtcblxuICAgIHJldHVybiBkZXNjcmlwdG9yO1xufVxuIiwiLypcbiAqIEFzeW5jIHV0aWxpdHkgZnVuY3Rpb25zIGZvciB0aGUgUlNwYWRlIGZyYW1ld29yay5cbiAqIFRoZXNlIGZ1bmN0aW9ucyBoYW5kbGUgYXN5bmNocm9ub3VzIG9wZXJhdGlvbnMsIGRlbGF5cywgZGVib3VuY2luZywgYW5kIG11dGV4ZXMuXG4gKi9cblxuLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuLy8gQVNZTkMgVVRJTElUSUVTXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbi8qKlxuICogUGF1c2VzIGV4ZWN1dGlvbiBmb3Igc3BlY2lmaWVkIG1pbGxpc2Vjb25kc1xuICogQHBhcmFtIHtudW1iZXJ9IFttaWxsaXNlY29uZHM9MF0gLSBEZWxheSBpbiBtaWxsaXNlY29uZHMgKDAgdXNlcyByZXF1ZXN0QW5pbWF0aW9uRnJhbWUpXG4gKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn0gUHJvbWlzZSB0aGF0IHJlc29sdmVzIGFmdGVyIGRlbGF5XG4gKiBAZXhhbXBsZSBhd2FpdCBzbGVlcCgxMDAwKTsgLy8gV2FpdCAxIHNlY29uZFxuICovXG5mdW5jdGlvbiBzbGVlcChtaWxsaXNlY29uZHMgPSAwKSB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PiB7XG4gICAgICAgIGlmIChtaWxsaXNlY29uZHMgPT0gMCAmJiByZXF1ZXN0QW5pbWF0aW9uRnJhbWUpIHtcbiAgICAgICAgICAgIHJlcXVlc3RBbmltYXRpb25GcmFtZShyZXNvbHZlKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHNldFRpbWVvdXQocmVzb2x2ZSwgbWlsbGlzZWNvbmRzKTtcbiAgICAgICAgfVxuICAgIH0pO1xufVxuXG4vKipcbiAqIENyZWF0ZXMgYSBkZWJvdW5jZWQgZnVuY3Rpb24gd2l0aCBleGNsdXNpdml0eSBhbmQgcHJvbWlzZSBmYW4taW5cbiAqXG4gKiBUaGlzIGZ1bmN0aW9uLCB3aGVuIGludm9rZWQsIGltbWVkaWF0ZWx5IHJ1bnMgdGhlIGNhbGxiYWNrIGV4Y2x1c2l2ZWx5LlxuICogRm9yIHN1YnNlcXVlbnQgaW52b2NhdGlvbnMsIGl0IGFwcGxpZXMgYSBkZWxheSBiZWZvcmUgcnVubmluZyB0aGUgY2FsbGJhY2sgZXhjbHVzaXZlbHkgYWdhaW4uXG4gKiBUaGUgZGVsYXkgc3RhcnRzIGFmdGVyIHRoZSBjdXJyZW50IGFzeW5jaHJvbm91cyBvcGVyYXRpb24gcmVzb2x2ZXMuXG4gKlxuICogSWYgJ2RlbGF5JyBpcyBzZXQgdG8gMCwgdGhlIGZ1bmN0aW9uIHdpbGwgb25seSBwcmV2ZW50IGVucXVldWVpbmcgbXVsdGlwbGUgZXhlY3V0aW9ucyBvZiB0aGVcbiAqIHNhbWUgbWV0aG9kIG1vcmUgdGhhbiBvbmNlLCBidXQgd2lsbCBzdGlsbCBydW4gdGhlbSBpbW1lZGlhdGVseSBpbiBhbiBleGNsdXNpdmUgc2VxdWVudGlhbCBtYW5uZXIuXG4gKlxuICogVGhlIG1vc3QgcmVjZW50IGludm9jYXRpb24gb2YgdGhlIGZ1bmN0aW9uIHdpbGwgYmUgdGhlIHBhcmFtZXRlcnMgdGhhdCBnZXQgcGFzc2VkIHRvIHRoZSBmdW5jdGlvblxuICogd2hlbiBpdCBpbnZva2VzLlxuICpcbiAqIFRoZSBmdW5jdGlvbiByZXR1cm5zIGEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHdoZW4gdGhlIG5leHQgZXhjbHVzaXZlIGV4ZWN1dGlvbiBjb21wbGV0ZXMuXG4gKlxuICogVXNhZ2UgYXMgZnVuY3Rpb246XG4gKiAgIGNvbnN0IGRlYm91bmNlZEZuID0gZGVib3VuY2UobXlGdW5jdGlvbiwgMjUwKTtcbiAqXG4gKiBVc2FnZSBhcyBkZWNvcmF0b3I6XG4gKiAgIEBkZWJvdW5jZSgyNTApXG4gKiAgIG15TWV0aG9kKCkgeyAuLi4gfVxuICpcbiAqIEBwYXJhbSB7ZnVuY3Rpb258bnVtYmVyfSBjYWxsYmFja19vcl9kZWxheSBUaGUgY2FsbGJhY2sgZnVuY3Rpb24gT1IgZGVsYXkgd2hlbiB1c2VkIGFzIGRlY29yYXRvclxuICogQHBhcmFtIHtudW1iZXJ9IGRlbGF5IFRoZSBkZWxheSBpbiBtaWxsaXNlY29uZHMgYmVmb3JlIHN1YnNlcXVlbnQgaW52b2NhdGlvbnNcbiAqIEBwYXJhbSB7Ym9vbGVhbn0gaW1tZWRpYXRlIGlmIHRydWUsIHRoZSBmaXJzdCB0aW1lIHRoZSBhY3Rpb24gaXMgY2FsbGVkLCB0aGUgY2FsbGJhY2sgZXhlY3V0ZXMgaW1tZWRpYXRlbHlcbiAqIEByZXR1cm5zIHtmdW5jdGlvbn0gQSBmdW5jdGlvbiB0aGF0IHdoZW4gaW52b2tlZCwgcnVucyB0aGUgY2FsbGJhY2sgaW1tZWRpYXRlbHkgYW5kIGV4Y2x1c2l2ZWx5LFxuICpcbiAqIEBkZWNvcmF0b3JcbiAqL1xuZnVuY3Rpb24gZGVib3VuY2UoY2FsbGJhY2tfb3JfZGVsYXksIGRlbGF5LCBpbW1lZGlhdGUgPSBmYWxzZSkge1xuICAgIC8vIERlY29yYXRvciB1c2FnZTogQGRlYm91bmNlKDI1MCkgb3IgQGRlYm91bmNlKDI1MCwgdHJ1ZSlcbiAgICAvLyBGaXJzdCBhcmd1bWVudCBpcyBhIG51bWJlciAodGhlIGRlbGF5KSwgcmV0dXJucyBkZWNvcmF0b3IgZnVuY3Rpb25cbiAgICBpZiAodHlwZW9mIGNhbGxiYWNrX29yX2RlbGF5ID09PSAnbnVtYmVyJykge1xuICAgICAgICBjb25zdCBkZWNvcmF0b3JfZGVsYXkgPSBjYWxsYmFja19vcl9kZWxheTtcbiAgICAgICAgY29uc3QgZGVjb3JhdG9yX2ltbWVkaWF0ZSA9IGRlbGF5IHx8IGZhbHNlO1xuXG4gICAgICAgIC8vIFRDMzkgZGVjb3JhdG9yIGZvcm06IHJlY2VpdmVzICh2YWx1ZSwgY29udGV4dClcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uICh2YWx1ZSwgY29udGV4dCkge1xuICAgICAgICAgICAgaWYgKGNvbnRleHQua2luZCA9PT0gJ21ldGhvZCcpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZGVib3VuY2VfaW1wbCh2YWx1ZSwgZGVjb3JhdG9yX2RlbGF5LCBkZWNvcmF0b3JfaW1tZWRpYXRlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICAvLyBGdW5jdGlvbiB1c2FnZTogZGVib3VuY2UoZm4sIDI1MClcbiAgICAvLyBGaXJzdCBhcmd1bWVudCBpcyBhIGZ1bmN0aW9uICh0aGUgY2FsbGJhY2spXG4gICAgY29uc3QgY2FsbGJhY2sgPSBjYWxsYmFja19vcl9kZWxheTtcbiAgICByZXR1cm4gZGVib3VuY2VfaW1wbChjYWxsYmFjaywgZGVsYXksIGltbWVkaWF0ZSk7XG59XG5cbi8qKlxuICogSW50ZXJuYWwgaW1wbGVtZW50YXRpb24gb2YgZGVib3VuY2UgbG9naWNcbiAqIEBwcml2YXRlXG4gKi9cbmZ1bmN0aW9uIGRlYm91bmNlX2ltcGwoY2FsbGJhY2ssIGRlbGF5LCBpbW1lZGlhdGUgPSBmYWxzZSkge1xuICAgIGxldCBydW5uaW5nID0gZmFsc2U7XG4gICAgbGV0IHF1ZXVlZCA9IGZhbHNlO1xuICAgIGxldCBsYXN0X2VuZF90aW1lID0gMDsgLy8gdGltZXN0YW1wIG9mIGxhc3QgY29tcGxldGVkIHJ1blxuICAgIGxldCB0aW1lciA9IG51bGw7XG5cbiAgICBsZXQgbmV4dF9hcmdzID0gW107XG4gICAgbGV0IG5leHRfY29udGV4dCA9IG51bGw7XG4gICAgbGV0IHJlc29sdmVfcXVldWUgPSBbXTtcbiAgICBsZXQgcmVqZWN0X3F1ZXVlID0gW107XG5cbiAgICBjb25zdCBydW5fZnVuY3Rpb24gPSBhc3luYyAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHRoZXNlX3Jlc29sdmVzID0gcmVzb2x2ZV9xdWV1ZTtcbiAgICAgICAgY29uc3QgdGhlc2VfcmVqZWN0cyA9IHJlamVjdF9xdWV1ZTtcbiAgICAgICAgY29uc3QgYXJncyA9IG5leHRfYXJncztcbiAgICAgICAgY29uc3QgY29udGV4dCA9IG5leHRfY29udGV4dDtcblxuICAgICAgICByZXNvbHZlX3F1ZXVlID0gW107XG4gICAgICAgIHJlamVjdF9xdWV1ZSA9IFtdO1xuICAgICAgICBuZXh0X2FyZ3MgPSBbXTtcbiAgICAgICAgbmV4dF9jb250ZXh0ID0gbnVsbDtcbiAgICAgICAgcXVldWVkID0gZmFsc2U7XG4gICAgICAgIHJ1bm5pbmcgPSB0cnVlO1xuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBjYWxsYmFjay5hcHBseShjb250ZXh0LCBhcmdzKTtcbiAgICAgICAgICAgIGZvciAoY29uc3QgcmVzb2x2ZSBvZiB0aGVzZV9yZXNvbHZlcykgcmVzb2x2ZShyZXN1bHQpO1xuICAgICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgIGZvciAoY29uc3QgcmVqZWN0IG9mIHRoZXNlX3JlamVjdHMpIHJlamVjdChlcnIpO1xuICAgICAgICB9IGZpbmFsbHkge1xuICAgICAgICAgICAgcnVubmluZyA9IGZhbHNlO1xuICAgICAgICAgICAgbGFzdF9lbmRfdGltZSA9IERhdGUubm93KCk7XG4gICAgICAgICAgICBpZiAocXVldWVkKSB7XG4gICAgICAgICAgICAgICAgY2xlYXJUaW1lb3V0KHRpbWVyKTtcbiAgICAgICAgICAgICAgICB0aW1lciA9IHNldFRpbWVvdXQocnVuX2Z1bmN0aW9uLCBNYXRoLm1heChkZWxheSwgMCkpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aW1lciA9IG51bGw7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgcmV0dXJuIGZ1bmN0aW9uICguLi5hcmdzKSB7XG4gICAgICAgIG5leHRfYXJncyA9IGFyZ3M7XG4gICAgICAgIG5leHRfY29udGV4dCA9IHRoaXM7XG5cbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIHJlc29sdmVfcXVldWUucHVzaChyZXNvbHZlKTtcbiAgICAgICAgICAgIHJlamVjdF9xdWV1ZS5wdXNoKHJlamVjdCk7XG5cbiAgICAgICAgICAgIC8vIE5vdGhpbmcgcnVubmluZyBhbmQgbm90aGluZyBzY2hlZHVsZWRcbiAgICAgICAgICAgIGlmICghcnVubmluZyAmJiAhdGltZXIpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBmaXJzdF9jYWxsID0gbGFzdF9lbmRfdGltZSA9PT0gMDtcblxuICAgICAgICAgICAgICAgIGlmIChpbW1lZGlhdGUgJiYgZmlyc3RfY2FsbCkge1xuICAgICAgICAgICAgICAgICAgICBydW5fZnVuY3Rpb24oKTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGNvbnN0IHNpbmNlID0gZmlyc3RfY2FsbCA/IEluZmluaXR5IDogRGF0ZS5ub3coKSAtIGxhc3RfZW5kX3RpbWU7XG4gICAgICAgICAgICAgICAgaWYgKHNpbmNlID49IGRlbGF5KSB7XG4gICAgICAgICAgICAgICAgICAgIHJ1bl9mdW5jdGlvbigpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHdhaXQgPSBNYXRoLm1heChkZWxheSAtIHNpbmNlLCAwKTtcbiAgICAgICAgICAgICAgICAgICAgY2xlYXJUaW1lb3V0KHRpbWVyKTtcbiAgICAgICAgICAgICAgICAgICAgdGltZXIgPSBzZXRUaW1lb3V0KHJ1bl9mdW5jdGlvbiwgd2FpdCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gSWYgd2UncmUgYWxyZWFkeSBydW5uaW5nIG9yIGEgdGltZXIgZXhpc3RzLCBqdXN0IG1hcmsgcXVldWVkLlxuICAgICAgICAgICAgLy8gVGhlIGZpbmFsbHl7fSBvZiBydW5fZnVuY3Rpb24gaGFuZGxlcyBzY2hlZHVsaW5nIGFmdGVyIGZ1bGwgZGVsYXkuXG4gICAgICAgICAgICBxdWV1ZWQgPSB0cnVlO1xuICAgICAgICB9KTtcbiAgICB9O1xufVxuXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4vLyBSRUFELVdSSVRFIExPQ0sgRlVOQ1RJT05TIC0gRGVsZWdhdGVkIHRvIFJlYWRXcml0ZUxvY2sgY2xhc3Ncbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuLyoqXG4gKiBBY3F1aXJlIGFuIGV4Y2x1c2l2ZSB3cml0ZSBsb2NrIGJ5IG5hbWUuXG4gKiBPbmx5IG9uZSB3cml0ZXIgcnVucyBhdCBhIHRpbWU7IGJsb2NrcyByZWFkZXJzIHVudGlsIGZpbmlzaGVkLlxuICogQHBhcmFtIHtzdHJpbmd9IG5hbWVcbiAqIEBwYXJhbSB7KCkgPT4gYW55fFByb21pc2U8YW55Pn0gY2JcbiAqIEByZXR1cm5zIHtQcm9taXNlPGFueT59XG4gKi9cbmZ1bmN0aW9uIHJ3bG9jayhuYW1lLCBjYikge1xuICAgIHJldHVybiBSZWFkV3JpdGVMb2NrLmFjcXVpcmUobmFtZSwgY2IpO1xufVxuXG4vKipcbiAqIEFjcXVpcmUgYSBzaGFyZWQgcmVhZCBsb2NrIGJ5IG5hbWUuXG4gKiBNdWx0aXBsZSByZWFkZXJzIHJ1biBpbiBwYXJhbGxlbCwgYnV0IHJlYWRlcnMgYXJlIGJsb2NrZWQgYnkgcXVldWVkL2FjdGl2ZSB3cml0ZXJzLlxuICogQHBhcmFtIHtzdHJpbmd9IG5hbWVcbiAqIEBwYXJhbSB7KCkgPT4gYW55fFByb21pc2U8YW55Pn0gY2JcbiAqIEByZXR1cm5zIHtQcm9taXNlPGFueT59XG4gKi9cbmZ1bmN0aW9uIHJ3bG9ja19yZWFkKG5hbWUsIGNiKSB7XG4gICAgcmV0dXJuIFJlYWRXcml0ZUxvY2suYWNxdWlyZV9yZWFkKG5hbWUsIGNiKTtcbn1cblxuLyoqXG4gKiBGb3JjZWZ1bGx5IGNsZWFyIGFsbCBsb2NrcyBhbmQgcXVldWVzIGZvciBhIGdpdmVuIG5hbWUuXG4gKiBAcGFyYW0ge3N0cmluZ30gbmFtZVxuICovXG5mdW5jdGlvbiByd2xvY2tfZm9yY2VfdW5sb2NrKG5hbWUpIHtcbiAgICBSZWFkV3JpdGVMb2NrLmZvcmNlX3VubG9jayhuYW1lKTtcbn1cblxuLyoqXG4gKiBJbnNwZWN0IGxvY2sgc3RhdGUgZm9yIGRlYnVnZ2luZy5cbiAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lXG4gKiBAcmV0dXJucyB7e3JlYWRlcnM6bnVtYmVyLCB3cml0ZXJfYWN0aXZlOmJvb2xlYW4sIHJlYWRlcl9xOm51bWJlciwgd3JpdGVyX3E6bnVtYmVyfX1cbiAqL1xuZnVuY3Rpb24gcndsb2NrX3BlbmRpbmcobmFtZSkge1xuICAgIHJldHVybiBSZWFkV3JpdGVMb2NrLnBlbmRpbmcobmFtZSk7XG59XG4iLCIvKlxuICogQ29yZSB1dGlsaXR5IGZ1bmN0aW9ucyBmb3IgdGhlIFJTcGFkZSBmcmFtZXdvcmsuXG4gKiBUaGVzZSBmdW5jdGlvbnMgaGFuZGxlIHR5cGUgY2hlY2tpbmcsIHR5cGUgY29udmVyc2lvbiwgc3RyaW5nIG1hbmlwdWxhdGlvbixcbiAqIGFuZCBvYmplY3QvYXJyYXkgdXRpbGl0aWVzLiBUaGV5IG1pcnJvciBmdW5jdGlvbmFsaXR5IGZyb20gUEhQIGZ1bmN0aW9ucy5cbiAqXG4gKiBPdGhlciB1dGlsaXR5IGZ1bmN0aW9ucyBhcmUgb3JnYW5pemVkIGluOlxuICogLSBhc3luYy5qczogQXN5bmMgdXRpbGl0aWVzIChzbGVlcCwgZGVib3VuY2UsIG11dGV4KVxuICogLSBicm93c2VyLmpzOiBCcm93c2VyL0RPTSB1dGlsaXRpZXMgKGlzX21vYmlsZSwgc2Nyb2xsIGZ1bmN0aW9ucylcbiAqIC0gZGF0ZXRpbWUuanM6IERhdGUvdGltZSB1dGlsaXRpZXNcbiAqIC0gaGFzaC5qczogSGFzaGluZyBhbmQgY29tcGFyaXNvblxuICogLSBlcnJvci5qczogRXJyb3IgaGFuZGxpbmdcbiAqL1xuXG4vLyBUb2RvOiB0ZXN0IHRoYXQgcHJvZCBidWlsZCBpZGVudGlmaWVzIGFuZCByZW1vdmVzIHVuY2FsbGVkIGZ1bmN0aW9ucyBmcm9tIHRoZSBmaW5hbCBidW5kbGUuXG5cbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbi8vIENPTlNUQU5UUyBBTkQgSEVMUEVSU1xuLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuXG4vLyBEZWZpbmUgY29tbW9ubHkgdXNlZCBjb25zdGFudHNcbmNvbnN0IHVuZGVmID0gJ3VuZGVmaW5lZCc7XG5cbi8qKlxuICogSXRlcmF0ZXMgb3ZlciBhcnJheXMgb3Igb2JqZWN0cyB3aXRoIHByb21pc2Ugc3VwcG9ydFxuICpcbiAqIFdvcmtzIHdpdGggYm90aCBzeW5jaHJvbm91cyBhbmQgYXN5bmNocm9ub3VzIGNhbGxiYWNrcy4gSWYgdGhlIGNhbGxiYWNrXG4gKiByZXR1cm5zIHByb21pc2VzLCB0aGV5IGFyZSBleGVjdXRlZCBpbiBwYXJhbGxlbCBhbmQgdGhpcyBmdW5jdGlvbiByZXR1cm5zXG4gKiBhIHByb21pc2UgdGhhdCByZXNvbHZlcyB3aGVuIGFsbCBwYXJhbGxlbCB0YXNrcyBjb21wbGV0ZS5cbiAqXG4gKiBAcGFyYW0ge0FycmF5fE9iamVjdH0gb2JqIC0gQ29sbGVjdGlvbiB0byBpdGVyYXRlXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFjayAtIEZ1bmN0aW9uIHRvIGNhbGwgZm9yIGVhY2ggaXRlbSAodmFsdWUsIGtleSkgLSBjYW4gYmUgYXN5bmNcbiAqIEByZXR1cm5zIHtQcm9taXNlfHVuZGVmaW5lZH0gUHJvbWlzZSBpZiBhbnkgY2FsbGJhY2tzIHJldHVybiBwcm9taXNlcywgdW5kZWZpbmVkIG90aGVyd2lzZVxuICpcbiAqIEBleGFtcGxlXG4gKiAvLyBTeW5jaHJvbm91cyB1c2FnZVxuICogZm9yZWFjaChbMSwyLDNdLCAodmFsKSA9PiBjb25zb2xlLmxvZyh2YWwpKTtcbiAqXG4gKiBAZXhhbXBsZVxuICogLy8gQXN5bmNocm9ub3VzIHVzYWdlIC0gd2FpdHMgZm9yIGFsbCB0byBjb21wbGV0ZVxuICogYXdhaXQgZm9yZWFjaChbMSwyLDNdLCBhc3luYyAodmFsKSA9PiB7XG4gKiAgICAgYXdhaXQgZmV0Y2goJy9hcGkvcHJvY2Vzcy8nICsgdmFsKTtcbiAqIH0pO1xuICovXG5mdW5jdGlvbiBmb3JlYWNoKG9iaiwgY2FsbGJhY2spIHtcbiAgICBjb25zdCByZXN1bHRzID0gW107XG5cbiAgICBpZiAoQXJyYXkuaXNBcnJheShvYmopKSB7XG4gICAgICAgIG9iai5mb3JFYWNoKCh2YWx1ZSwgaW5kZXgpID0+IHtcbiAgICAgICAgICAgIHJlc3VsdHMucHVzaChjYWxsYmFjayh2YWx1ZSwgaW5kZXgpKTtcbiAgICAgICAgfSk7XG4gICAgfSBlbHNlIGlmIChvYmogJiYgdHlwZW9mIG9iaiA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgZm9yIChsZXQga2V5IGluIG9iaikge1xuICAgICAgICAgICAgaWYgKG9iai5oYXNPd25Qcm9wZXJ0eShrZXkpKSB7XG4gICAgICAgICAgICAgICAgcmVzdWx0cy5wdXNoKGNhbGxiYWNrKG9ialtrZXldLCBrZXkpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8vIEZpbHRlciBmb3IgcHJvbWlzZXNcbiAgICBjb25zdCBwcm9taXNlcyA9IHJlc3VsdHMuZmlsdGVyKChyZXN1bHQpID0+IHJlc3VsdCAmJiB0eXBlb2YgcmVzdWx0LnRoZW4gPT09ICdmdW5jdGlvbicpO1xuXG4gICAgLy8gSWYgdGhlcmUgYXJlIGFueSBwcm9taXNlcywgcmV0dXJuIFByb21pc2UuYWxsIHRvIHdhaXQgZm9yIGFsbCB0byBjb21wbGV0ZVxuICAgIGlmIChwcm9taXNlcy5sZW5ndGggPiAwKSB7XG4gICAgICAgIHJldHVybiBQcm9taXNlLmFsbChwcm9taXNlcyk7XG4gICAgfVxuXG4gICAgLy8gTm8gcHJvbWlzZXMgcmV0dXJuZWQsIHNvIHdlJ3JlIGRvbmVcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xufVxuXG5cbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbi8vIFRZUEUgQ0hFQ0tJTkcgRlVOQ1RJT05TXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbi8qKlxuICogQ2hlY2tzIGlmIGEgdmFsdWUgaXMgbnVtZXJpY1xuICogQHBhcmFtIHsqfSBuIC0gVmFsdWUgdG8gY2hlY2tcbiAqIEByZXR1cm5zIHtib29sZWFufSBUcnVlIGlmIHRoZSB2YWx1ZSBpcyBhIGZpbml0ZSBudW1iZXJcbiAqL1xuZnVuY3Rpb24gaXNfbnVtZXJpYyhuKSB7XG4gICAgcmV0dXJuICFpc05hTihwYXJzZUZsb2F0KG4pKSAmJiBpc0Zpbml0ZShuKTtcbn1cblxuLyoqXG4gKiBDaGVja3MgaWYgYSB2YWx1ZSBpcyBhIHN0cmluZ1xuICogQHBhcmFtIHsqfSBzIC0gVmFsdWUgdG8gY2hlY2tcbiAqIEByZXR1cm5zIHtib29sZWFufSBUcnVlIGlmIHRoZSB2YWx1ZSBpcyBhIHN0cmluZ1xuICovXG5mdW5jdGlvbiBpc19zdHJpbmcocykge1xuICAgIHJldHVybiB0eXBlb2YgcyA9PSAnc3RyaW5nJztcbn1cblxuLyoqXG4gKiBDaGVja3MgaWYgYSB2YWx1ZSBpcyBhbiBpbnRlZ2VyXG4gKiBAcGFyYW0geyp9IG4gLSBWYWx1ZSB0byBjaGVja1xuICogQHJldHVybnMge2Jvb2xlYW59IFRydWUgaWYgdGhlIHZhbHVlIGlzIGFuIGludGVnZXJcbiAqL1xuZnVuY3Rpb24gaXNfaW50ZWdlcihuKSB7XG4gICAgcmV0dXJuIE51bWJlci5pc0ludGVnZXIobik7XG59XG5cbi8qKlxuICogQ2hlY2tzIGlmIGEgdmFsdWUgaXMgYSBwcm9taXNlLWxpa2Ugb2JqZWN0XG4gKiBAcGFyYW0geyp9IG9iaiAtIFZhbHVlIHRvIGNoZWNrXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gVHJ1ZSBpZiB0aGUgdmFsdWUgaGFzIGEgdGhlbiBtZXRob2RcbiAqL1xuZnVuY3Rpb24gaXNfcHJvbWlzZShvYmopIHtcbiAgICByZXR1cm4gdHlwZW9mIG9iaiA9PSAnb2JqZWN0JyAmJiB0eXBlb2Ygb2JqLnRoZW4gPT0gJ2Z1bmN0aW9uJztcbn1cblxuLyoqXG4gKiBDaGVja3MgaWYgYSB2YWx1ZSBpcyBhbiBhcnJheVxuICogQHBhcmFtIHsqfSBvYmogLSBWYWx1ZSB0byBjaGVja1xuICogQHJldHVybnMge2Jvb2xlYW59IFRydWUgaWYgdGhlIHZhbHVlIGlzIGFuIGFycmF5XG4gKi9cbmZ1bmN0aW9uIGlzX2FycmF5KG9iaikge1xuICAgIHJldHVybiBBcnJheS5pc0FycmF5KG9iaik7XG59XG5cbi8qKlxuICogQ2hlY2tzIGlmIGEgdmFsdWUgaXMgYW4gb2JqZWN0IChleGNsdWRlcyBudWxsKVxuICogQHBhcmFtIHsqfSBvYmogLSBWYWx1ZSB0byBjaGVja1xuICogQHJldHVybnMge2Jvb2xlYW59IFRydWUgaWYgdGhlIHZhbHVlIGlzIGFuIG9iamVjdCBhbmQgbm90IG51bGxcbiAqL1xuZnVuY3Rpb24gaXNfb2JqZWN0KG9iaikge1xuICAgIHJldHVybiB0eXBlb2Ygb2JqID09PSAnb2JqZWN0JyAmJiBvYmogIT09IG51bGw7XG59XG5cbi8qKlxuICogQ2hlY2tzIGlmIGEgdmFsdWUgaXMgYSBmdW5jdGlvblxuICogQHBhcmFtIHsqfSBmdW5jdGlvbl90b19jaGVjayAtIFZhbHVlIHRvIGNoZWNrXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gVHJ1ZSBpZiB0aGUgdmFsdWUgaXMgYSBmdW5jdGlvblxuICovXG5mdW5jdGlvbiBpc19mdW5jdGlvbihmdW5jdGlvbl90b19jaGVjaykge1xuICAgIHJldHVybiBmdW5jdGlvbl90b19jaGVjayAmJiB7fS50b1N0cmluZy5jYWxsKGZ1bmN0aW9uX3RvX2NoZWNrKSA9PT0gJ1tvYmplY3QgRnVuY3Rpb25dJztcbn1cblxuLyoqXG4gKiBDaGVja3MgaWYgYSBzdHJpbmcgaXMgYSB2YWxpZCBlbWFpbCBhZGRyZXNzXG4gKiBVc2VzIGEgcHJhY3RpY2FsIFJGQyA1MzIyIGNvbXBsaWFudCByZWdleCB0aGF0IG1hdGNoZXMgOTkuOTklIG9mIHJlYWwtd29ybGQgZW1haWwgYWRkcmVzc2VzXG4gKiBAcGFyYW0ge3N0cmluZ30gZW1haWwgLSBFbWFpbCBhZGRyZXNzIHRvIHZhbGlkYXRlXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gVHJ1ZSBpZiB0aGUgc3RyaW5nIGlzIGEgdmFsaWQgZW1haWwgYWRkcmVzc1xuICovXG5mdW5jdGlvbiBpc19lbWFpbChlbWFpbCkge1xuICAgIGlmICghaXNfc3RyaW5nKGVtYWlsKSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGNvbnN0IHJlZ2V4ID0gL15bYS16MC05ISMkJSYnKisvPT9eX2B7fH1+LV0rKD86XFwuW2EtejAtOSEjJCUmJyorLz0/Xl9ge3x9fi1dKykqQCg/OlthLXowLTldKD86W2EtejAtOS1dKlthLXowLTldKT9cXC4pK1thLXowLTldKD86W2EtejAtOS1dKlthLXowLTldKT8kL2k7XG4gICAgcmV0dXJuIHJlZ2V4LnRlc3QoZW1haWwpO1xufVxuXG4vKipcbiAqIENoZWNrcyBpZiBhIHZhbHVlIGlzIGRlZmluZWQgKG5vdCB1bmRlZmluZWQpXG4gKiBAcGFyYW0geyp9IHZhbHVlIC0gVmFsdWUgdG8gY2hlY2tcbiAqIEByZXR1cm5zIHtib29sZWFufSBUcnVlIGlmIHZhbHVlIGlzIG5vdCB1bmRlZmluZWRcbiAqL1xuZnVuY3Rpb24gaXNzZXQodmFsdWUpIHtcbiAgICByZXR1cm4gdHlwZW9mIHZhbHVlICE9IHVuZGVmO1xufVxuXG4vKipcbiAqIENoZWNrcyBpZiBhIHZhbHVlIGlzIGVtcHR5IChudWxsLCB1bmRlZmluZWQsIDAsIFwiXCIsIGVtcHR5IGFycmF5L29iamVjdClcbiAqIEBwYXJhbSB7Kn0gb2JqZWN0IC0gVmFsdWUgdG8gY2hlY2tcbiAqIEByZXR1cm5zIHtib29sZWFufSBUcnVlIGlmIHRoZSB2YWx1ZSBpcyBjb25zaWRlcmVkIGVtcHR5XG4gKi9cbmZ1bmN0aW9uIGVtcHR5KG9iamVjdCkge1xuICAgIGlmICh0eXBlb2Ygb2JqZWN0ID09IHVuZGVmKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICBpZiAob2JqZWN0ID09PSBudWxsKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICBpZiAodHlwZW9mIG9iamVjdCA9PSAnc3RyaW5nJyAmJiBvYmplY3QgPT0gJycpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIGlmICh0eXBlb2Ygb2JqZWN0ID09ICdudW1iZXInKSB7XG4gICAgICAgIHJldHVybiBvYmplY3QgPT0gMDtcbiAgICB9XG4gICAgaWYgKEFycmF5LmlzQXJyYXkob2JqZWN0KSkge1xuICAgICAgICByZXR1cm4gIW9iamVjdC5sZW5ndGg7XG4gICAgfVxuICAgIGlmICh0eXBlb2Ygb2JqZWN0ID09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBmb3IgKGxldCBrZXkgaW4gb2JqZWN0KSB7XG4gICAgICAgIGlmIChvYmplY3QuaGFzT3duUHJvcGVydHkoa2V5KSkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xufVxuXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4vLyBUWVBFIENPTlZFUlNJT04gRlVOQ1RJT05TXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbi8qKlxuICogQ29udmVydHMgYSB2YWx1ZSB0byBhIGZsb2F0aW5nIHBvaW50IG51bWJlclxuICogUmV0dXJucyAwIGZvciBudWxsLCB1bmRlZmluZWQsIE5hTiwgb3Igbm9uLW51bWVyaWMgdmFsdWVzXG4gKiBAcGFyYW0geyp9IHZhbCAtIFZhbHVlIHRvIGNvbnZlcnRcbiAqIEByZXR1cm5zIHtudW1iZXJ9IEZsb2F0aW5nIHBvaW50IG51bWJlclxuICovXG5mdW5jdGlvbiBmbG9hdCh2YWwpIHtcbiAgICAvLyBIYW5kbGUgbnVsbCwgdW5kZWZpbmVkLCBlbXB0eSBzdHJpbmdcbiAgICBpZiAodmFsID09PSBudWxsIHx8IHZhbCA9PT0gdW5kZWZpbmVkIHx8IHZhbCA9PT0gJycpIHtcbiAgICAgICAgcmV0dXJuIDAuMDtcbiAgICB9XG5cbiAgICAvLyBUcnkgdG8gcGFyc2UgdGhlIHZhbHVlXG4gICAgY29uc3QgcGFyc2VkID0gcGFyc2VGbG9hdCh2YWwpO1xuXG4gICAgLy8gQ2hlY2sgZm9yIE5hTiBhbmQgcmV0dXJuIDAgaWYgcGFyc2luZyBmYWlsZWRcbiAgICByZXR1cm4gaXNOYU4ocGFyc2VkKSA/IDAuMCA6IHBhcnNlZDtcbn1cblxuLyoqXG4gKiBDb252ZXJ0cyBhIHZhbHVlIHRvIGFuIGludGVnZXJcbiAqIFJldHVybnMgMCBmb3IgbnVsbCwgdW5kZWZpbmVkLCBOYU4sIG9yIG5vbi1udW1lcmljIHZhbHVlc1xuICogQHBhcmFtIHsqfSB2YWwgLSBWYWx1ZSB0byBjb252ZXJ0XG4gKiBAcmV0dXJucyB7bnVtYmVyfSBJbnRlZ2VyIHZhbHVlXG4gKi9cbmZ1bmN0aW9uIGludCh2YWwpIHtcbiAgICAvLyBIYW5kbGUgbnVsbCwgdW5kZWZpbmVkLCBlbXB0eSBzdHJpbmdcbiAgICBpZiAodmFsID09PSBudWxsIHx8IHZhbCA9PT0gdW5kZWZpbmVkIHx8IHZhbCA9PT0gJycpIHtcbiAgICAgICAgcmV0dXJuIDA7XG4gICAgfVxuXG4gICAgLy8gVHJ5IHRvIHBhcnNlIHRoZSB2YWx1ZVxuICAgIGNvbnN0IHBhcnNlZCA9IHBhcnNlSW50KHZhbCwgMTApO1xuXG4gICAgLy8gQ2hlY2sgZm9yIE5hTiBhbmQgcmV0dXJuIDAgaWYgcGFyc2luZyBmYWlsZWRcbiAgICByZXR1cm4gaXNOYU4ocGFyc2VkKSA/IDAgOiBwYXJzZWQ7XG59XG5cbi8qKlxuICogQ29udmVydHMgYSB2YWx1ZSB0byBhIHN0cmluZ1xuICogUmV0dXJucyBlbXB0eSBzdHJpbmcgZm9yIG51bGwgb3IgdW5kZWZpbmVkXG4gKiBAcGFyYW0geyp9IHZhbCAtIFZhbHVlIHRvIGNvbnZlcnRcbiAqIEByZXR1cm5zIHtzdHJpbmd9IFN0cmluZyByZXByZXNlbnRhdGlvblxuICovXG5mdW5jdGlvbiBzdHIodmFsKSB7XG4gICAgLy8gSGFuZGxlIG51bGwgYW5kIHVuZGVmaW5lZCBzcGVjaWFsbHlcbiAgICBpZiAodmFsID09PSBudWxsIHx8IHZhbCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJldHVybiAnJztcbiAgICB9XG5cbiAgICAvLyBDb252ZXJ0IHRvIHN0cmluZ1xuICAgIHJldHVybiBTdHJpbmcodmFsKTtcbn1cblxuLyoqXG4gKiBDb252ZXJ0cyBudW1lcmljIHN0cmluZ3MgdG8gbnVtYmVycywgcmV0dXJucyBhbGwgb3RoZXIgdmFsdWVzIHVuY2hhbmdlZFxuICogVXNlZCB3aGVuIHlvdSBuZWVkIHRvIGVuc3VyZSBudW1lcmljIHR5cGVzIGJ1dCBkb24ndCB3YW50IHRvIGZvcmNlXG4gKiBjb252ZXJzaW9uIG9mIG5vbi1udW1lcmljIHZhbHVlcyAod2hpY2ggd291bGQgYmVjb21lIDApXG4gKiBAcGFyYW0geyp9IHZhbCAtIFZhbHVlIHRvIGNvbnZlcnRcbiAqIEByZXR1cm5zIHsqfSBOdW1iZXIgaWYgaW5wdXQgd2FzIG51bWVyaWMgc3RyaW5nLCBvdGhlcndpc2UgdW5jaGFuZ2VkXG4gKi9cbmZ1bmN0aW9uIHZhbHVlX3VubGVzc19udW1lcmljX3N0cmluZ190aGVuX251bWVyaWNfdmFsdWUodmFsKSB7XG4gICAgLy8gSWYgaXQncyBhbHJlYWR5IGEgbnVtYmVyLCByZXR1cm4gaXRcbiAgICBpZiAodHlwZW9mIHZhbCA9PT0gJ251bWJlcicpIHtcbiAgICAgICAgcmV0dXJuIHZhbDtcbiAgICB9XG5cbiAgICAvLyBJZiBpdCdzIGEgc3RyaW5nIGFuZCBudW1lcmljLCBjb252ZXJ0IGl0XG4gICAgaWYgKGlzX3N0cmluZyh2YWwpICYmIGlzX251bWVyaWModmFsKSkge1xuICAgICAgICAvLyBVc2UgcGFyc2VGbG9hdCB0byBoYW5kbGUgYm90aCBpbnRlZ2VycyBhbmQgZmxvYXRzXG4gICAgICAgIHJldHVybiBwYXJzZUZsb2F0KHZhbCk7XG4gICAgfVxuXG4gICAgLy8gUmV0dXJuIGV2ZXJ5dGhpbmcgZWxzZSB1bmNoYW5nZWQgKG51bGwsIG9iamVjdHMsIG5vbi1udW1lcmljIHN0cmluZ3MsIGV0Yy4pXG4gICAgcmV0dXJuIHZhbDtcbn1cblxuLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuLy8gU1RSSU5HIE1BTklQVUxBVElPTiBGVU5DVElPTlNcbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuLyoqXG4gKiBFc2NhcGVzIEhUTUwgc3BlY2lhbCBjaGFyYWN0ZXJzICh1c2VzIExvZGFzaCBlc2NhcGUpXG4gKiBAcGFyYW0ge3N0cmluZ30gc3RyIC0gU3RyaW5nIHRvIGVzY2FwZVxuICogQHJldHVybnMge3N0cmluZ30gSFRNTC1lc2NhcGVkIHN0cmluZ1xuICovXG5mdW5jdGlvbiBodG1sKHN0cikge1xuICAgIHJldHVybiBfLmVzY2FwZShzdHIpO1xufVxuXG4vKipcbiAqIENvbnZlcnRzIG5ld2xpbmVzIHRvIEhUTUwgbGluZSBicmVha3NcbiAqIEBwYXJhbSB7c3RyaW5nfSBzdHIgLSBTdHJpbmcgdG8gY29udmVydFxuICogQHJldHVybnMge3N0cmluZ30gU3RyaW5nIHdpdGggbmV3bGluZXMgcmVwbGFjZWQgYnkgPGJyIC8+XG4gKi9cbmZ1bmN0aW9uIG5sMmJyKHN0cikge1xuICAgIGlmICh0eXBlb2Ygc3RyID09PSB1bmRlZiB8fCBzdHIgPT09IG51bGwpIHtcbiAgICAgICAgcmV0dXJuICcnO1xuICAgIH1cbiAgICByZXR1cm4gKHN0ciArICcnKS5yZXBsYWNlKC8oW14+XFxyXFxuXT8pKFxcclxcbnxcXG5cXHJ8XFxyfFxcbikvZywgJyQxPGJyIC8+JDInKTtcbn1cblxuLyoqXG4gKiBFc2NhcGVzIEhUTUwgYW5kIGNvbnZlcnRzIG5ld2xpbmVzIHRvIDxiciAvPlxuICogQHBhcmFtIHtzdHJpbmd9IHN0ciAtIFN0cmluZyB0byBwcm9jZXNzXG4gKiBAcmV0dXJucyB7c3RyaW5nfSBIVE1MLWVzY2FwZWQgc3RyaW5nIHdpdGggbGluZSBicmVha3NcbiAqL1xuZnVuY3Rpb24gaHRtbGJyKHN0cikge1xuICAgIHJldHVybiBubDJicihodG1sKHN0cikpO1xufVxuXG4vKipcbiAqIFVSTC1lbmNvZGVzIGEgc3RyaW5nXG4gKiBAcGFyYW0ge3N0cmluZ30gc3RyIC0gU3RyaW5nIHRvIGVuY29kZVxuICogQHJldHVybnMge3N0cmluZ30gVVJMLWVuY29kZWQgc3RyaW5nXG4gKi9cbmZ1bmN0aW9uIHVybGVuY29kZShzdHIpIHtcbiAgICByZXR1cm4gZW5jb2RlVVJJQ29tcG9uZW50KHN0cik7XG59XG5cbi8qKlxuICogVVJMLWRlY29kZXMgYSBzdHJpbmdcbiAqIEBwYXJhbSB7c3RyaW5nfSBzdHIgLSBTdHJpbmcgdG8gZGVjb2RlXG4gKiBAcmV0dXJucyB7c3RyaW5nfSBVUkwtZGVjb2RlZCBzdHJpbmdcbiAqL1xuZnVuY3Rpb24gdXJsZGVjb2RlKHN0cikge1xuICAgIHJldHVybiBkZWNvZGVVUklDb21wb25lbnQoc3RyKTtcbn1cblxuLyoqXG4gKiBKU09OLWVuY29kZXMgYSB2YWx1ZVxuICogQHBhcmFtIHsqfSB2YWx1ZSAtIFZhbHVlIHRvIGVuY29kZVxuICogQHJldHVybnMge3N0cmluZ30gSlNPTiBzdHJpbmdcbiAqL1xuZnVuY3Rpb24ganNvbl9lbmNvZGUodmFsdWUpIHtcbiAgICByZXR1cm4gSlNPTi5zdHJpbmdpZnkodmFsdWUpO1xufVxuXG4vKipcbiAqIEpTT04tZGVjb2RlcyBhIHN0cmluZ1xuICogQHBhcmFtIHtzdHJpbmd9IHN0ciAtIEpTT04gc3RyaW5nIHRvIGRlY29kZVxuICogQHJldHVybnMgeyp9IERlY29kZWQgdmFsdWVcbiAqL1xuZnVuY3Rpb24ganNvbl9kZWNvZGUoc3RyKSB7XG4gICAgcmV0dXJuIEpTT04ucGFyc2Uoc3RyKTtcbn1cblxuLyoqXG4gKiBDb25zb2xlIGRlYnVnIG91dHB1dCB3aXRoIGNoYW5uZWwgZmlsdGVyaW5nXG4gKiBBbGlhcyBmb3IgRGVidWdnZXIuY29uc29sZV9kZWJ1Z1xuICogQHBhcmFtIHtzdHJpbmd9IGNoYW5uZWwgLSBEZWJ1ZyBjaGFubmVsIG5hbWVcbiAqIEBwYXJhbSB7Li4uKn0gdmFsdWVzIC0gVmFsdWVzIHRvIGxvZ1xuICovXG5mdW5jdGlvbiBjb25zb2xlX2RlYnVnKGNoYW5uZWwsIC4uLnZhbHVlcykge1xuICAgIERlYnVnZ2VyLmNvbnNvbGVfZGVidWcoY2hhbm5lbCwgLi4udmFsdWVzKTtcbn1cblxuLyoqXG4gKiBSZXBsYWNlcyBhbGwgb2NjdXJyZW5jZXMgb2YgYSBzdWJzdHJpbmcgaW4gYSBzdHJpbmdcbiAqIEBwYXJhbSB7c3RyaW5nfSBzdHJpbmcgLSBTdHJpbmcgdG8gc2VhcmNoIGluXG4gKiBAcGFyYW0ge3N0cmluZ30gc2VhcmNoIC0gU3Vic3RyaW5nIHRvIGZpbmRcbiAqIEBwYXJhbSB7c3RyaW5nfSByZXBsYWNlIC0gUmVwbGFjZW1lbnQgc3Vic3RyaW5nXG4gKiBAcmV0dXJucyB7c3RyaW5nfSBTdHJpbmcgd2l0aCBhbGwgb2NjdXJyZW5jZXMgcmVwbGFjZWRcbiAqL1xuZnVuY3Rpb24gcmVwbGFjZV9hbGwoc3RyaW5nLCBzZWFyY2gsIHJlcGxhY2UpIHtcbiAgICBpZiAoIWlzX3N0cmluZyhzdHJpbmcpKSB7XG4gICAgICAgIHN0cmluZyA9IHN0cmluZyArICcnO1xuICAgIH1cbiAgICByZXR1cm4gc3RyaW5nLnNwbGl0KHNlYXJjaCkuam9pbihyZXBsYWNlKTtcbn1cblxuLyoqXG4gKiBDYXBpdGFsaXplcyB0aGUgZmlyc3QgbGV0dGVyIG9mIGVhY2ggd29yZFxuICogQHBhcmFtIHtzdHJpbmd9IGlucHV0IC0gU3RyaW5nIHRvIGNhcGl0YWxpemVcbiAqIEByZXR1cm5zIHtzdHJpbmd9IFN0cmluZyB3aXRoIGZpcnN0IGxldHRlciBvZiBlYWNoIHdvcmQgY2FwaXRhbGl6ZWRcbiAqL1xuZnVuY3Rpb24gdWN3b3JkcyhpbnB1dCkge1xuICAgIHJldHVybiBpbnB1dFxuICAgICAgICAuc3BsaXQoJyAnKVxuICAgICAgICAubWFwKCh3b3JkKSA9PiB3b3JkLmNoYXJBdCgwKS50b1VwcGVyQ2FzZSgpICsgd29yZC5zbGljZSgxKSlcbiAgICAgICAgLmpvaW4oJyAnKTtcbn1cblxuLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuLy8gT0JKRUNUIEFORCBBUlJBWSBVVElMSVRJRVNcbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuLyoqXG4gKiBDb3VudHMgdGhlIG51bWJlciBvZiBwcm9wZXJ0aWVzIGluIGFuIG9iamVjdCBvciBlbGVtZW50cyBpbiBhbiBhcnJheVxuICogQHBhcmFtIHtPYmplY3R8QXJyYXl9IG8gLSBPYmplY3Qgb3IgYXJyYXkgdG8gY291bnRcbiAqIEByZXR1cm5zIHtudW1iZXJ9IE51bWJlciBvZiBvd24gcHJvcGVydGllcy9lbGVtZW50c1xuICovXG5mdW5jdGlvbiBjb3VudChvKSB7XG4gICAgbGV0IGMgPSAwO1xuICAgIGZvciAoY29uc3QgayBpbiBvKSB7XG4gICAgICAgIGlmIChvLmhhc093blByb3BlcnR5KGspKSB7XG4gICAgICAgICAgICArK2M7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGM7XG59XG5cbi8qKlxuICogQ3JlYXRlcyBhIHNoYWxsb3cgY2xvbmUgb2YgYW4gb2JqZWN0LCBhcnJheSwgb3IgZnVuY3Rpb25cbiAqIEBwYXJhbSB7Kn0gb2JqIC0gVmFsdWUgdG8gY2xvbmVcbiAqIEByZXR1cm5zIHsqfSBDbG9uZWQgdmFsdWVcbiAqL1xuZnVuY3Rpb24gY2xvbmUob2JqKSB7XG4gICAgaWYgKHR5cGVvZiBGdW5jdGlvbi5wcm90b3R5cGUuX19jbG9uZSA9PSB1bmRlZikge1xuICAgICAgICBGdW5jdGlvbi5wcm90b3R5cGUuX19jbG9uZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIC8vaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvMTgzMzU4OC9qYXZhc2NyaXB0LWNsb25lLWEtZnVuY3Rpb25cbiAgICAgICAgICAgIGNvbnN0IHRoYXQgPSB0aGlzO1xuICAgICAgICAgICAgbGV0IHRlbXAgPSBmdW5jdGlvbiBjbG9uZWQoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoYXQuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBmb3IgKGxldCBrZXkgaW4gdGhpcykge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLmhhc093blByb3BlcnR5KGtleSkpIHtcbiAgICAgICAgICAgICAgICAgICAgdGVtcFtrZXldID0gdGhpc1trZXldO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB0ZW1wO1xuICAgICAgICB9O1xuICAgIH1cblxuICAgIGlmICh0eXBlb2Ygb2JqID09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgcmV0dXJuIG9iai5fX2Nsb25lKCk7XG4gICAgfSBlbHNlIGlmIChvYmouY29uc3RydWN0b3IgJiYgb2JqLmNvbnN0cnVjdG9yID09IEFycmF5KSB7XG4gICAgICAgIHJldHVybiBvYmouc2xpY2UoMCk7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgLy8gaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvNzI4MzYwL2hvdy1kby1pLWNvcnJlY3RseS1jbG9uZS1hLWphdmFzY3JpcHQtb2JqZWN0LzMwMDQyOTQ4IzMwMDQyOTQ4XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKHt9LCBvYmopO1xuICAgIH1cbn1cblxuLyoqXG4gKiBSZXR1cm5zIHRoZSBmaXJzdCBub24tbnVsbC91bmRlZmluZWQgdmFsdWUgZnJvbSBhcmd1bWVudHNcbiAqIEBwYXJhbSB7Li4uKn0gYXJndW1lbnRzIC0gVmFsdWVzIHRvIGNoZWNrXG4gKiBAcmV0dXJucyB7Kn0gRmlyc3Qgbm9uLW51bGwvdW5kZWZpbmVkIHZhbHVlLCBvciBudWxsIGlmIG5vbmUgZm91bmRcbiAqL1xuZnVuY3Rpb24gY29hbGVzY2UoKSB7XG4gICAgbGV0IGFyZ3MgPSBBcnJheS5mcm9tKGFyZ3VtZW50cyk7XG4gICAgbGV0IHJldHVybl92YWwgPSBudWxsO1xuICAgIGFyZ3MuZm9yRWFjaChmdW5jdGlvbiAoYXJnKSB7XG4gICAgICAgIGlmIChyZXR1cm5fdmFsID09PSBudWxsICYmIHR5cGVvZiBhcmcgIT0gdW5kZWYgJiYgYXJnICE9PSBudWxsKSB7XG4gICAgICAgICAgICByZXR1cm5fdmFsID0gYXJnO1xuICAgICAgICB9XG4gICAgfSk7XG4gICAgcmV0dXJuIHJldHVybl92YWw7XG59XG5cbi8qKlxuICogQ29udmVydHMgQ1NWIHN0cmluZyB0byBhcnJheSwgdHJpbW1pbmcgZWFjaCBlbGVtZW50XG4gKiBAcGFyYW0ge3N0cmluZ30gc3RyX2NzdiAtIENTViBzdHJpbmcgdG8gY29udmVydFxuICogQHJldHVybnMge0FycmF5PHN0cmluZz59IEFycmF5IG9mIHRyaW1tZWQgdmFsdWVzXG4gKiBAdG9kbyBIYW5kbGUgcXVvdGVkL2VzY2FwZWQgY2hhcmFjdGVyc1xuICovXG5mdW5jdGlvbiBjc3ZfdG9fYXJyYXlfdHJpbShzdHJfY3N2KSB7XG4gICAgY29uc3QgcGFydHMgPSBzdHJfY3N2LnNwbGl0KCcsJyk7XG4gICAgY29uc3QgcmV0ID0gW107XG4gICAgZm9yZWFjaChwYXJ0cywgKHBhcnQpID0+IHtcbiAgICAgICAgcmV0LnB1c2gocGFydC50cmltKCkpO1xuICAgIH0pO1xuICAgIHJldHVybiByZXQ7XG59XG4iLCIvKipcbiAqIFF1aWxsIEVkaXRvciAtIFV0aWxpdHkgRnVuY3Rpb25zXG4gKlxuICogUHJvdmlkZXMgdXRpbGl0eSBmdW5jdGlvbnMgZm9yIHdvcmtpbmcgd2l0aCBRdWlsbCBlZGl0b3IuXG4gKi9cblxuLyoqXG4gKiBFbnN1cmVzIFF1aWxsIGlzIGxvYWRlZCBiZWZvcmUgZXhlY3V0aW5nIGNhbGxiYWNrXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFjayAtIEZ1bmN0aW9uIHRvIGNhbGwgd2hlbiBRdWlsbCBpcyByZWFkeVxuICovXG5mdW5jdGlvbiBxdWlsbF9yZWFkeShjYWxsYmFjaykge1xuICAgIGlmICh0eXBlb2Ygd2luZG93LlF1aWxsICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICBjYWxsYmFjaygpO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHNldFRpbWVvdXQoKCkgPT4gcXVpbGxfcmVhZHkoY2FsbGJhY2spLCA1MCk7XG4gICAgfVxufVxuIiwiLyoqXG4gKiBTYXZlIGNsaWVudCBoYW5kbGVyIGZvciBGb3JtIGNvbXBvbmVudFxuICogQHBhcmFtIHtPYmplY3R9IHZhbHVlcyAtIFNlcmlhbGl6ZWQgZm9ybSB2YWx1ZXNcbiAqIEByZXR1cm5zIHtQcm9taXNlPE9iamVjdD59IFJlc3BvbnNlIHtzdWNjZXNzOiBib29sLCBlcnJvcnM/OiB7fSwgcmVkaXJlY3Q/OiBzdHJpbmd9XG4gKi9cbmFzeW5jIGZ1bmN0aW9uIHNhdmVfY2xpZW50KHZhbHVlcykge1xuICAgIC8vIENoZWNrIGlmIGVkaXRpbmcgZXhpc3RpbmcgY2xpZW50XG4gICAgY29uc3QgY2xpZW50X2lkID0gJCgnI2NsaWVudC1pZCcpLnZhbCgpO1xuICAgIGlmIChjbGllbnRfaWQpIHtcbiAgICAgICAgdmFsdWVzLmlkID0gY2xpZW50X2lkO1xuICAgIH1cblxuICAgIC8vIFRPRE86IENvbGxlY3QgYWRkaXRpb25hbCBmaWVsZHMgbm90IHlldCBpbiBGb3JtIGNvbXBvbmVudCAodGFncywgZXRjLilcbiAgICAvLyBGb3Igbm93LCBqdXN0IHN1Ym1pdCB0aGUgYmFzaWMgZmllbGRzIGZyb20gdGhlIEZvcm0gY29tcG9uZW50XG5cbiAgICB0cnkge1xuICAgICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IEZyb250ZW5kX0NsaWVudHNfQ29udHJvbGxlci5zYXZlKHZhbHVlcyk7XG5cbiAgICAgICAgaWYgKHJlc3BvbnNlLnN1Y2Nlc3MpIHtcbiAgICAgICAgICAgIC8vIFJlZGlyZWN0IHRvIGNsaWVudHMgbGlzdCBvbiBzdWNjZXNzXG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIHN1Y2Nlc3M6IHRydWUsXG4gICAgICAgICAgICAgICAgcmVkaXJlY3Q6IFJzeC5Sb3V0ZSgnRnJvbnRlbmRfQ2xpZW50c19Db250cm9sbGVyJywgJ2luZGV4JylcbiAgICAgICAgICAgIH07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBSZXR1cm4gdmFsaWRhdGlvbiBlcnJvcnNcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgc3VjY2VzczogZmFsc2UsXG4gICAgICAgICAgICAgICAgZXJyb3JzOiByZXNwb25zZS5lcnJvcnMgfHwge19nZW5lcmFsOiByZXNwb25zZS5tZXNzYWdlIHx8ICdBbiBlcnJvciBvY2N1cnJlZCd9XG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgY29uc29sZS5lcnJvcignU2F2ZSBlcnJvcjonLCBlcnJvcik7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBzdWNjZXNzOiBmYWxzZSxcbiAgICAgICAgICAgIGVycm9yczoge19nZW5lcmFsOiAnQW4gZXJyb3Igb2NjdXJyZWQgd2hpbGUgc2F2aW5nLiBQbGVhc2UgdHJ5IGFnYWluLid9XG4gICAgICAgIH07XG4gICAgfVxufVxuIiwiLyoqXG4gKiBTYXZlIGNvbnRhY3QgaGFuZGxlciBmb3IgRm9ybSBjb21wb25lbnRcbiAqIEBwYXJhbSB7T2JqZWN0fSB2YWx1ZXMgLSBTZXJpYWxpemVkIGZvcm0gdmFsdWVzXG4gKiBAcmV0dXJucyB7UHJvbWlzZTxPYmplY3Q+fSBSZXNwb25zZSB7c3VjY2VzczogYm9vbCwgZXJyb3JzPzoge30sIHJlZGlyZWN0Pzogc3RyaW5nfVxuICovXG5hc3luYyBmdW5jdGlvbiBzYXZlX2NvbnRhY3QodmFsdWVzKSB7XG4gICAgLy8gQ2hlY2sgaWYgZWRpdGluZyBleGlzdGluZyBjb250YWN0XG4gICAgY29uc3QgY29udGFjdF9pZCA9ICQoJyNjb250YWN0LWlkJykudmFsKCk7XG4gICAgaWYgKGNvbnRhY3RfaWQpIHtcbiAgICAgICAgdmFsdWVzLmlkID0gY29udGFjdF9pZDtcbiAgICB9XG5cbiAgICB0cnkge1xuICAgICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IEZyb250ZW5kX0NvbnRhY3RzX0NvbnRyb2xsZXIuc2F2ZSh2YWx1ZXMpO1xuXG4gICAgICAgIGlmIChyZXNwb25zZS5zdWNjZXNzKSB7XG4gICAgICAgICAgICAvLyBSZWRpcmVjdCB0byBjb250YWN0IHZpZXcgb3IgbGlzdCBvbiBzdWNjZXNzXG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIHN1Y2Nlc3M6IHRydWUsXG4gICAgICAgICAgICAgICAgcmVkaXJlY3Q6IHJlc3BvbnNlLnJlZGlyZWN0IHx8IFJzeC5Sb3V0ZSgnRnJvbnRlbmRfQ29udGFjdHNfQ29udHJvbGxlcicsICdpbmRleCcpXG4gICAgICAgICAgICB9O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gUmV0dXJuIHZhbGlkYXRpb24gZXJyb3JzXG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIHN1Y2Nlc3M6IGZhbHNlLFxuICAgICAgICAgICAgICAgIGVycm9yczogcmVzcG9uc2UuZXJyb3JzIHx8IHtfZ2VuZXJhbDogcmVzcG9uc2UubWVzc2FnZSB8fCAnQW4gZXJyb3Igb2NjdXJyZWQnfVxuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoJ1NhdmUgZXJyb3I6JywgZXJyb3IpO1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgc3VjY2VzczogZmFsc2UsXG4gICAgICAgICAgICBlcnJvcnM6IHtfZ2VuZXJhbDogJ0FuIGVycm9yIG9jY3VycmVkIHdoaWxlIHNhdmluZy4gUGxlYXNlIHRyeSBhZ2Fpbi4nfVxuICAgICAgICB9O1xuICAgIH1cbn1cbiIsIi8qKlxuICogTWFuaWZlc3QgLSBKYXZhU2NyaXB0IGNsYXNzIHJlZ2lzdHJ5IGFuZCBtZXRhZGF0YSBzeXN0ZW1cbiAqXG4gKiBUaGlzIGNsYXNzIG1haW50YWlucyBhIHJlZ2lzdHJ5IG9mIGFsbCBKYXZhU2NyaXB0IGNsYXNzZXMgaW4gdGhlIGJ1bmRsZSxcbiAqIHRyYWNraW5nIHRoZWlyIG5hbWVzIGFuZCBpbmhlcml0YW5jZSByZWxhdGlvbnNoaXBzLiBJdCBwcm92aWRlcyB1dGlsaXRpZXNcbiAqIGZvciB3b3JraW5nIHdpdGggY2xhc3MgaGllcmFyY2hpZXMgYW5kIGNhbGxpbmcgaW5pdGlhbGl6YXRpb24gbWV0aG9kcy5cbiAqL1xuY2xhc3MgTWFuaWZlc3Qge1xuICAgIC8qKlxuICAgICAqIERlZmluZSBjbGFzc2VzIGluIHRoZSBtYW5pZmVzdCAoZnJhbWV3b3JrIGludGVybmFsKVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGl0ZW1zIC0gQXJyYXkgb2YgY2xhc3MgZGVmaW5pdGlvbnMgW1tDbGFzcywgXCJDbGFzc05hbWVcIiwgUGFyZW50Q2xhc3MsIGRlY29yYXRvcnNdLCAuLi5dXG4gICAgICovXG4gICAgc3RhdGljIF9kZWZpbmUoaXRlbXMpIHtcbiAgICAgICAgLy8gSW5pdGlhbGl6ZSB0aGUgY2xhc3NlcyBvYmplY3QgaWYgbm90IGFscmVhZHkgZGVmaW5lZFxuICAgICAgICBpZiAodHlwZW9mIE1hbmlmZXN0Ll9jbGFzc2VzID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgTWFuaWZlc3QuX2NsYXNzZXMgPSB7fTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFByb2Nlc3MgZWFjaCBjbGFzcyBkZWZpbml0aW9uXG4gICAgICAgIGl0ZW1zLmZvckVhY2goKGl0ZW0pID0+IHtcbiAgICAgICAgICAgIGxldCBjbGFzc19vYmplY3QgPSBpdGVtWzBdO1xuICAgICAgICAgICAgbGV0IGNsYXNzX25hbWUgPSBpdGVtWzFdO1xuICAgICAgICAgICAgbGV0IGNsYXNzX2V4dGVuZHMgPSBpdGVtWzJdIHx8IG51bGw7XG4gICAgICAgICAgICBsZXQgZGVjb3JhdG9ycyA9IGl0ZW1bM10gfHwgbnVsbDtcblxuICAgICAgICAgICAgLy8gU3RvcmUgdGhlIGNsYXNzIGluZm9ybWF0aW9uICh1c2luZyBvYmplY3QgdG8gYXZvaWQgZHVwbGljYXRlcylcbiAgICAgICAgICAgIE1hbmlmZXN0Ll9jbGFzc2VzW2NsYXNzX25hbWVdID0ge1xuICAgICAgICAgICAgICAgIGNsYXNzOiBjbGFzc19vYmplY3QsXG4gICAgICAgICAgICAgICAgbmFtZTogY2xhc3NfbmFtZSxcbiAgICAgICAgICAgICAgICBleHRlbmRzOiBjbGFzc19leHRlbmRzLFxuICAgICAgICAgICAgICAgIGRlY29yYXRvcnM6IGRlY29yYXRvcnMsICAvLyBTdG9yZSBjb21wYWN0IGRlY29yYXRvciBkYXRhXG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAvLyBBZGQgbWV0YWRhdGEgdG8gdGhlIGNsYXNzIG9iamVjdCBpdHNlbGZcbiAgICAgICAgICAgIGNsYXNzX29iamVjdC5fbmFtZSA9IGNsYXNzX25hbWU7XG4gICAgICAgICAgICBjbGFzc19vYmplY3QuX2V4dGVuZHMgPSBjbGFzc19leHRlbmRzO1xuICAgICAgICAgICAgY2xhc3Nfb2JqZWN0Ll9kZWNvcmF0b3JzID0gZGVjb3JhdG9ycztcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gQnVpbGQgdGhlIHN1YmNsYXNzIGluZGV4IGFmdGVyIGFsbCBjbGFzc2VzIGFyZSBkZWZpbmVkXG4gICAgICAgIE1hbmlmZXN0Ll9idWlsZF9zdWJjbGFzc19pbmRleCgpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEJ1aWxkIGFuIGluZGV4IG9mIHN1YmNsYXNzZXMgZm9yIGVmZmljaWVudCBsb29rdXBzXG4gICAgICogVGhpcyBjcmVhdGVzIGEgbWFwcGluZyB3aGVyZSBlYWNoIGNsYXNzIG5hbWUgcG9pbnRzIHRvIGFuIGFycmF5IG9mIGFsbCBpdHMgc3ViY2xhc3Nlc1xuICAgICAqIEBwcml2YXRlXG4gICAgICovXG4gICAgc3RhdGljIF9idWlsZF9zdWJjbGFzc19pbmRleCgpIHtcbiAgICAgICAgLy8gSW5pdGlhbGl6ZSB0aGUgc3ViY2xhc3MgaW5kZXhcbiAgICAgICAgTWFuaWZlc3QuX3N1YmNsYXNzX2luZGV4ID0ge307XG5cbiAgICAgICAgLy8gU3RlcCB0aHJvdWdoIGVhY2ggY2xhc3MgYW5kIHdhbGsgdXAgaXRzIHBhcmVudCBjaGFpblxuICAgICAgICBmb3IgKGxldCBjbGFzc19uYW1lIGluIE1hbmlmZXN0Ll9jbGFzc2VzKSB7XG4gICAgICAgICAgICBjb25zdCBjbGFzc2RhdGEgPSBNYW5pZmVzdC5fY2xhc3Nlc1tjbGFzc19uYW1lXTtcbiAgICAgICAgICAgIGxldCBjdXJyZW50X2NsYXNzX25hbWUgPSBjbGFzc19uYW1lO1xuICAgICAgICAgICAgbGV0IGN1cnJlbnRfY2xhc3NkYXRhID0gY2xhc3NkYXRhO1xuXG4gICAgICAgICAgICAvLyBXYWxrIHVwIHRoZSBwYXJlbnQgY2hhaW4gdW50aWwgd2UgcmVhY2ggdGhlIHJvb3RcbiAgICAgICAgICAgIHdoaWxlIChjdXJyZW50X2NsYXNzZGF0YSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IGV4dGVuZHNfbmFtZSA9IGN1cnJlbnRfY2xhc3NkYXRhLmV4dGVuZHM7XG5cbiAgICAgICAgICAgICAgICBpZiAoZXh0ZW5kc19uYW1lKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIEluaXRpYWxpemUgdGhlIHBhcmVudCdzIHN1YmNsYXNzIGFycmF5IGlmIG5lZWRlZFxuICAgICAgICAgICAgICAgICAgICBpZiAoIU1hbmlmZXN0Ll9zdWJjbGFzc19pbmRleFtleHRlbmRzX25hbWVdKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBNYW5pZmVzdC5fc3ViY2xhc3NfaW5kZXhbZXh0ZW5kc19uYW1lXSA9IFtdO1xuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgLy8gQWRkIHRoaXMgY2xhc3MgdG8gaXRzIHBhcmVudCdzIHN1YmNsYXNzIGxpc3RcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFNYW5pZmVzdC5fc3ViY2xhc3NfaW5kZXhbZXh0ZW5kc19uYW1lXS5pbmNsdWRlcyhjbGFzc19uYW1lKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgTWFuaWZlc3QuX3N1YmNsYXNzX2luZGV4W2V4dGVuZHNfbmFtZV0ucHVzaChjbGFzc19uYW1lKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIC8vIE1vdmUgdXAgdG8gdGhlIHBhcmVudCdzIG1ldGFkYXRhIChpZiBpdCBleGlzdHMgaW4gbWFuaWZlc3QpXG4gICAgICAgICAgICAgICAgICAgIGlmIChNYW5pZmVzdC5fY2xhc3Nlc1tleHRlbmRzX25hbWVdKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjdXJyZW50X2NsYXNzZGF0YSA9IE1hbmlmZXN0Ll9jbGFzc2VzW2V4dGVuZHNfbmFtZV07XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBQYXJlbnQgbm90IGluIG1hbmlmZXN0IChlLmcuLCBuYXRpdmUgSmF2YVNjcmlwdCBjbGFzcyksIHN0b3AgaGVyZVxuICAgICAgICAgICAgICAgICAgICAgICAgY3VycmVudF9jbGFzc2RhdGEgPSBudWxsO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gTm8gcGFyZW50LCB3ZSd2ZSByZWFjaGVkIHRoZSByb290XG4gICAgICAgICAgICAgICAgICAgIGN1cnJlbnRfY2xhc3NkYXRhID0gbnVsbDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXQgYWxsIGNsYXNzZXMgdGhhdCBleHRlbmQgYSBnaXZlbiBiYXNlIGNsYXNzXG4gICAgICogQHBhcmFtIHtDbGFzc3xzdHJpbmd9IGJhc2VfY2xhc3MgLSBUaGUgYmFzZSBjbGFzcyAob2JqZWN0IG9yIG5hbWUgc3RyaW5nKSB0byBjaGVjayBmb3JcbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IEFycmF5IG9mIG9iamVjdHMgd2l0aCB7Y2xhc3NfbmFtZSwgY2xhc3Nfb2JqZWN0fSBmb3IgY2xhc3NlcyB0aGF0IGV4dGVuZCB0aGUgYmFzZSBjbGFzc1xuICAgICAqL1xuICAgIHN0YXRpYyBnZXRfZXh0ZW5kaW5nKGJhc2VfY2xhc3MpIHtcbiAgICAgICAgaWYgKCFNYW5pZmVzdC5fY2xhc3Nlcykge1xuICAgICAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gQ29udmVydCBzdHJpbmcgdG8gY2xhc3Mgb2JqZWN0IGlmIG5lZWRlZFxuICAgICAgICBsZXQgYmFzZV9jbGFzc19vYmplY3QgPSBiYXNlX2NsYXNzO1xuICAgICAgICBpZiAodHlwZW9mIGJhc2VfY2xhc3MgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICBiYXNlX2NsYXNzX29iamVjdCA9IE1hbmlmZXN0LmdldF9jbGFzc19ieV9uYW1lKGJhc2VfY2xhc3MpO1xuICAgICAgICAgICAgaWYgKCFiYXNlX2NsYXNzX29iamVjdCkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgQmFzZSBjbGFzcyBub3QgZm91bmQ6ICR7YmFzZV9jbGFzc31gKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGNsYXNzZXMgPSBbXTtcblxuICAgICAgICBmb3IgKGxldCBjbGFzc19uYW1lIGluIE1hbmlmZXN0Ll9jbGFzc2VzKSB7XG4gICAgICAgICAgICBjb25zdCBjbGFzc2RhdGEgPSBNYW5pZmVzdC5fY2xhc3Nlc1tjbGFzc19uYW1lXTtcbiAgICAgICAgICAgIGlmIChNYW5pZmVzdC5qc19pc19zdWJjbGFzc19vZihjbGFzc2RhdGEuY2xhc3MsIGJhc2VfY2xhc3Nfb2JqZWN0KSkge1xuICAgICAgICAgICAgICAgIGNsYXNzZXMucHVzaCh7XG4gICAgICAgICAgICAgICAgICAgIGNsYXNzX25hbWU6IGNsYXNzX25hbWUsXG4gICAgICAgICAgICAgICAgICAgIGNsYXNzX29iamVjdDogY2xhc3NkYXRhLmNsYXNzLFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gU29ydCBhbHBoYWJldGljYWxseSBieSBjbGFzcyBuYW1lIHRvIGVuc3VyZSBkZXRlcm1pbmlzdGljIGJlaGF2aW9yIGFuZCBwcmV2ZW50IHJhY2UgY29uZGl0aW9uIGJ1Z3NcbiAgICAgICAgY2xhc3Nlcy5zb3J0KChhLCBiKSA9PiBhLmNsYXNzX25hbWUubG9jYWxlQ29tcGFyZShiLmNsYXNzX25hbWUpKTtcblxuICAgICAgICByZXR1cm4gY2xhc3NlcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVjayBpZiBhIGNsYXNzIGlzIGEgc3ViY2xhc3Mgb2YgYW5vdGhlciBjbGFzc1xuICAgICAqIE1hdGNoZXMgUEhQIE1hbmlmZXN0Ojpqc19pc19zdWJjbGFzc19vZigpIHNpZ25hdHVyZSBhbmQgYmVoYXZpb3JcbiAgICAgKiBAcGFyYW0ge0NsYXNzfHN0cmluZ30gc3ViY2xhc3MgLSBUaGUgY2hpbGQgY2xhc3MgKG9iamVjdCBvciBuYW1lKSB0byBjaGVja1xuICAgICAqIEBwYXJhbSB7Q2xhc3N8c3RyaW5nfSBzdXBlcmNsYXNzIC0gVGhlIHBhcmVudCBjbGFzcyAob2JqZWN0IG9yIG5hbWUpIHRvIGNoZWNrIGFnYWluc3RcbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gVHJ1ZSBpZiBzdWJjbGFzcyBleHRlbmRzIHN1cGVyY2xhc3MgKGRpcmVjdGx5IG9yIGluZGlyZWN0bHkpXG4gICAgICovXG4gICAgc3RhdGljIGpzX2lzX3N1YmNsYXNzX29mKHN1YmNsYXNzLCBzdXBlcmNsYXNzKSB7XG4gICAgICAgIC8vIENvbnZlcnQgc3RyaW5nIG5hbWVzIHRvIGNsYXNzIG9iamVjdHNcbiAgICAgICAgbGV0IHN1YmNsYXNzX29iamVjdCA9IHN1YmNsYXNzO1xuICAgICAgICBpZiAodHlwZW9mIHN1YmNsYXNzID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgc3ViY2xhc3Nfb2JqZWN0ID0gTWFuaWZlc3QuZ2V0X2NsYXNzX2J5X25hbWUoc3ViY2xhc3MpO1xuICAgICAgICAgICAgaWYgKCFzdWJjbGFzc19vYmplY3QpIHtcbiAgICAgICAgICAgICAgICAvLyBDYW4ndCByZXNvbHZlIHN1YmNsYXNzIC0gcmV0dXJuIGZhbHNlIHBlciBzcGVjXG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgbGV0IHN1cGVyY2xhc3Nfb2JqZWN0ID0gc3VwZXJjbGFzcztcbiAgICAgICAgaWYgKHR5cGVvZiBzdXBlcmNsYXNzID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgc3VwZXJjbGFzc19vYmplY3QgPSBNYW5pZmVzdC5nZXRfY2xhc3NfYnlfbmFtZShzdXBlcmNsYXNzKTtcbiAgICAgICAgICAgIGlmICghc3VwZXJjbGFzc19vYmplY3QpIHtcbiAgICAgICAgICAgICAgICAvLyBDYW4ndCByZXNvbHZlIHN1cGVyY2xhc3MgLSBmYWlsIGxvdWQgcGVyIHNwZWNcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFN1cGVyY2xhc3Mgbm90IGZvdW5kIGluIG1hbmlmZXN0OiAke3N1cGVyY2xhc3N9YCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyBDbGFzc2VzIGFyZSBub3Qgc3ViY2xhc3NlcyBvZiB0aGVtc2VsdmVzXG4gICAgICAgIGlmIChzdWJjbGFzc19vYmplY3QgPT09IHN1cGVyY2xhc3Nfb2JqZWN0KSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBXYWxrIHVwIHRoZSBpbmhlcml0YW5jZSBjaGFpblxuICAgICAgICBsZXQgY3VycmVudF9jbGFzcyA9IHN1YmNsYXNzX29iamVjdDtcbiAgICAgICAgd2hpbGUgKGN1cnJlbnRfY2xhc3MpIHtcbiAgICAgICAgICAgIGlmIChjdXJyZW50X2NsYXNzID09PSBzdXBlcmNsYXNzX29iamVjdCkge1xuICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gTW92ZSB1cCB0byBwYXJlbnQgY2xhc3NcbiAgICAgICAgICAgIGlmIChjdXJyZW50X2NsYXNzLl9leHRlbmRzKSB7XG4gICAgICAgICAgICAgICAgLy8gX2V4dGVuZHMgbWF5IGJlIGEgc3RyaW5nIG9yIGNsYXNzIHJlZmVyZW5jZVxuICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgY3VycmVudF9jbGFzcy5fZXh0ZW5kcyA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgICAgICAgICAgY3VycmVudF9jbGFzcyA9IE1hbmlmZXN0LmdldF9jbGFzc19ieV9uYW1lKGN1cnJlbnRfY2xhc3MuX2V4dGVuZHMpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGN1cnJlbnRfY2xhc3MgPSBjdXJyZW50X2NsYXNzLl9leHRlbmRzO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgY3VycmVudF9jbGFzcyA9IG51bGw7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0IGEgY2xhc3MgYnkgaXRzIG5hbWVcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gY2xhc3NfbmFtZSAtIFRoZSBuYW1lIG9mIHRoZSBjbGFzc1xuICAgICAqIEByZXR1cm5zIHtDbGFzc3xudWxsfSBUaGUgY2xhc3Mgb2JqZWN0IG9yIG51bGwgaWYgbm90IGZvdW5kXG4gICAgICovXG4gICAgc3RhdGljIGdldF9jbGFzc19ieV9uYW1lKGNsYXNzX25hbWUpIHtcbiAgICAgICAgaWYgKCFNYW5pZmVzdC5fY2xhc3NlcyB8fCAhTWFuaWZlc3QuX2NsYXNzZXNbY2xhc3NfbmFtZV0pIHtcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIE1hbmlmZXN0Ll9jbGFzc2VzW2NsYXNzX25hbWVdLmNsYXNzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldCBhbGwgcmVnaXN0ZXJlZCBjbGFzc2VzXG4gICAgICogQHJldHVybnMge0FycmF5fSBBcnJheSBvZiBvYmplY3RzIHdpdGgge2NsYXNzX25hbWUsIGNsYXNzX29iamVjdCwgZXh0ZW5kc31cbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0X2FsbF9jbGFzc2VzKCkge1xuICAgICAgICBpZiAoIU1hbmlmZXN0Ll9jbGFzc2VzKSB7XG4gICAgICAgICAgICByZXR1cm4gW107XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCByZXN1bHRzID0gW107XG4gICAgICAgIGZvciAobGV0IGNsYXNzX25hbWUgaW4gTWFuaWZlc3QuX2NsYXNzZXMpIHtcbiAgICAgICAgICAgIGNvbnN0IGNsYXNzZGF0YSA9IE1hbmlmZXN0Ll9jbGFzc2VzW2NsYXNzX25hbWVdO1xuICAgICAgICAgICAgcmVzdWx0cy5wdXNoKHtcbiAgICAgICAgICAgICAgICBjbGFzc19uYW1lOiBjbGFzc2RhdGEubmFtZSxcbiAgICAgICAgICAgICAgICBjbGFzc19vYmplY3Q6IGNsYXNzZGF0YS5jbGFzcyxcbiAgICAgICAgICAgICAgICBleHRlbmRzOiBjbGFzc2RhdGEuZXh0ZW5kcyxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gU29ydCBhbHBoYWJldGljYWxseSBieSBjbGFzcyBuYW1lIHRvIGVuc3VyZSBkZXRlcm1pbmlzdGljIGJlaGF2aW9yIGFuZCBwcmV2ZW50IHJhY2UgY29uZGl0aW9uIGJ1Z3NcbiAgICAgICAgcmVzdWx0cy5zb3J0KChhLCBiKSA9PiBhLmNsYXNzX25hbWUubG9jYWxlQ29tcGFyZShiLmNsYXNzX25hbWUpKTtcblxuICAgICAgICByZXR1cm4gcmVzdWx0cztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIGJ1aWxkIGtleSBmcm9tIHRoZSBhcHBsaWNhdGlvbiBjb25maWd1cmF0aW9uXG4gICAgICogQHJldHVybnMge3N0cmluZ30gVGhlIGJ1aWxkIGtleSBvciBcIk5PQlVJTERcIiBpZiBub3QgYXZhaWxhYmxlXG4gICAgICovXG4gICAgc3RhdGljIGJ1aWxkX2tleSgpIHtcbiAgICAgICAgaWYgKHdpbmRvdy5yc3hhcHAgJiYgd2luZG93LnJzeGFwcC5idWlsZF9rZXkpIHtcbiAgICAgICAgICAgIHJldHVybiB3aW5kb3cucnN4YXBwLmJ1aWxkX2tleTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gJ05PQlVJTEQnO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldCBkZWNvcmF0b3JzIGZvciBhIHNwZWNpZmljIGNsYXNzIGFuZCBtZXRob2RcbiAgICAgKiBAcGFyYW0ge3N0cmluZ3xDbGFzc30gY2xhc3NfbmFtZSAtIFRoZSBjbGFzcyBuYW1lIG9yIGNsYXNzIG9iamVjdFxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBtZXRob2RfbmFtZSAtIFRoZSBtZXRob2QgbmFtZVxuICAgICAqIEByZXR1cm5zIHtBcnJheXxudWxsfSBBcnJheSBvZiBkZWNvcmF0b3Igb2JqZWN0cyBvciBudWxsIGlmIG5vbmUgZm91bmRcbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0X2RlY29yYXRvcnMoY2xhc3NfbmFtZSwgbWV0aG9kX25hbWUpIHtcbiAgICAgICAgLy8gQ29udmVydCBjbGFzcyBvYmplY3QgdG8gbmFtZSBpZiBuZWVkZWRcbiAgICAgICAgaWYgKHR5cGVvZiBjbGFzc19uYW1lICE9PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgY2xhc3NfbmFtZSA9IGNsYXNzX25hbWUuX25hbWUgfHwgY2xhc3NfbmFtZS5uYW1lO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgY2xhc3NfaW5mbyA9IE1hbmlmZXN0Ll9jbGFzc2VzW2NsYXNzX25hbWVdO1xuICAgICAgICBpZiAoIWNsYXNzX2luZm8gfHwgIWNsYXNzX2luZm8uZGVjb3JhdG9ycyB8fCAhY2xhc3NfaW5mby5kZWNvcmF0b3JzW21ldGhvZF9uYW1lXSkge1xuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBUcmFuc2Zvcm0gY29tcGFjdCBmb3JtYXQgdG8gb2JqZWN0IGZvcm1hdFxuICAgICAgICByZXR1cm4gTWFuaWZlc3QuX3RyYW5zZm9ybV9kZWNvcmF0b3JzKGNsYXNzX2luZm8uZGVjb3JhdG9yc1ttZXRob2RfbmFtZV0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldCBhbGwgbWV0aG9kcyB3aXRoIGRlY29yYXRvcnMgZm9yIGEgY2xhc3NcbiAgICAgKiBAcGFyYW0ge3N0cmluZ3xDbGFzc30gY2xhc3NfbmFtZSAtIFRoZSBjbGFzcyBuYW1lIG9yIGNsYXNzIG9iamVjdFxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IE9iamVjdCB3aXRoIG1ldGhvZCBuYW1lcyBhcyBrZXlzIGFuZCBkZWNvcmF0b3IgYXJyYXlzIGFzIHZhbHVlc1xuICAgICAqL1xuICAgIHN0YXRpYyBnZXRfYWxsX2RlY29yYXRvcnMoY2xhc3NfbmFtZSkge1xuICAgICAgICAvLyBDb252ZXJ0IGNsYXNzIG9iamVjdCB0byBuYW1lIGlmIG5lZWRlZFxuICAgICAgICBpZiAodHlwZW9mIGNsYXNzX25hbWUgIT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICBjbGFzc19uYW1lID0gY2xhc3NfbmFtZS5fbmFtZSB8fCBjbGFzc19uYW1lLm5hbWU7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBjbGFzc19pbmZvID0gTWFuaWZlc3QuX2NsYXNzZXNbY2xhc3NfbmFtZV07XG4gICAgICAgIGlmICghY2xhc3NfaW5mbyB8fCAhY2xhc3NfaW5mby5kZWNvcmF0b3JzKSB7XG4gICAgICAgICAgICByZXR1cm4ge307XG4gICAgICAgIH1cblxuICAgICAgICAvLyBUcmFuc2Zvcm0gYWxsIGRlY29yYXRvcnMgZnJvbSBjb21wYWN0IHRvIG9iamVjdCBmb3JtYXRcbiAgICAgICAgY29uc3QgcmVzdWx0ID0ge307XG4gICAgICAgIGZvciAobGV0IG1ldGhvZF9uYW1lIGluIGNsYXNzX2luZm8uZGVjb3JhdG9ycykge1xuICAgICAgICAgICAgcmVzdWx0W21ldGhvZF9uYW1lXSA9IE1hbmlmZXN0Ll90cmFuc2Zvcm1fZGVjb3JhdG9ycyhjbGFzc19pbmZvLmRlY29yYXRvcnNbbWV0aG9kX25hbWVdKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRyYW5zZm9ybSBjb21wYWN0IGRlY29yYXRvciBmb3JtYXQgdG8gb2JqZWN0IGZvcm1hdFxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGNvbXBhY3RfZGVjb3JhdG9ycyAtIEFycmF5IG9mIFtuYW1lLCBbYXJnc11dIHR1cGxlc1xuICAgICAqIEByZXR1cm5zIHtBcnJheX0gQXJyYXkgb2YgZGVjb3JhdG9yIG9iamVjdHMgd2l0aCBuYW1lIGFuZCBhcmd1bWVudHMgcHJvcGVydGllc1xuICAgICAqIEBwcml2YXRlXG4gICAgICovXG4gICAgc3RhdGljIF90cmFuc2Zvcm1fZGVjb3JhdG9ycyhjb21wYWN0X2RlY29yYXRvcnMpIHtcbiAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KGNvbXBhY3RfZGVjb3JhdG9ycykpIHtcbiAgICAgICAgICAgIHJldHVybiBbXTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBjb21wYWN0X2RlY29yYXRvcnMubWFwKGRlY29yYXRvciA9PiB7XG4gICAgICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShkZWNvcmF0b3IpICYmIGRlY29yYXRvci5sZW5ndGggPj0gMikge1xuICAgICAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgICAgIG5hbWU6IGRlY29yYXRvclswXSxcbiAgICAgICAgICAgICAgICAgICAgYXJndW1lbnRzOiBkZWNvcmF0b3JbMV0gfHwgW11cbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gSGFuZGxlIG1hbGZvcm1lZCBkZWNvcmF0b3IgZGF0YVxuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICBuYW1lOiAndW5rbm93bicsXG4gICAgICAgICAgICAgICAgYXJndW1lbnRzOiBbXVxuICAgICAgICAgICAgfTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2sgaWYgYSBtZXRob2QgaGFzIGEgc3BlY2lmaWMgZGVjb3JhdG9yXG4gICAgICogQHBhcmFtIHtzdHJpbmd8Q2xhc3N9IGNsYXNzX25hbWUgLSBUaGUgY2xhc3MgbmFtZSBvciBjbGFzcyBvYmplY3RcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gbWV0aG9kX25hbWUgLSBUaGUgbWV0aG9kIG5hbWVcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gZGVjb3JhdG9yX25hbWUgLSBUaGUgZGVjb3JhdG9yIG5hbWUgdG8gY2hlY2sgZm9yXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IFRydWUgaWYgdGhlIG1ldGhvZCBoYXMgdGhlIGRlY29yYXRvclxuICAgICAqL1xuICAgIHN0YXRpYyBoYXNfZGVjb3JhdG9yKGNsYXNzX25hbWUsIG1ldGhvZF9uYW1lLCBkZWNvcmF0b3JfbmFtZSkge1xuICAgICAgICBjb25zdCBkZWNvcmF0b3JzID0gTWFuaWZlc3QuZ2V0X2RlY29yYXRvcnMoY2xhc3NfbmFtZSwgbWV0aG9kX25hbWUpO1xuICAgICAgICBpZiAoIWRlY29yYXRvcnMpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBkZWNvcmF0b3JzLnNvbWUoZCA9PiBkLm5hbWUgPT09IGRlY29yYXRvcl9uYW1lKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXQgYWxsIHN1YmNsYXNzZXMgb2YgYSBnaXZlbiBjbGFzcyB1c2luZyB0aGUgcHJlLWJ1aWx0IGluZGV4XG4gICAgICogVGhpcyBpcyB0aGUgSmF2YVNjcmlwdCBlcXVpdmFsZW50IG9mIFBIUCdzIE1hbmlmZXN0Ojpqc19nZXRfc3ViY2xhc3Nlc19vZigpXG4gICAgICogQHBhcmFtIHtDbGFzc3xzdHJpbmd9IGJhc2VfY2xhc3MgLSBUaGUgYmFzZSBjbGFzcyAob2JqZWN0IG9yIG5hbWUgc3RyaW5nKSB0byBnZXQgc3ViY2xhc3NlcyBvZlxuICAgICAqIEByZXR1cm5zIHtBcnJheTxDbGFzcz59IEFycmF5IG9mIGFjdHVhbCBjbGFzcyBvYmplY3RzIHRoYXQgYXJlIHN1YmNsYXNzZXMgb2YgdGhlIGJhc2UgY2xhc3NcbiAgICAgKi9cbiAgICBzdGF0aWMganNfZ2V0X3N1YmNsYXNzZXNfb2YoYmFzZV9jbGFzcykge1xuICAgICAgICAvLyBJbml0aWFsaXplIGluZGV4IGlmIG5lZWRlZFxuICAgICAgICBpZiAoIU1hbmlmZXN0Ll9zdWJjbGFzc19pbmRleCkge1xuICAgICAgICAgICAgTWFuaWZlc3QuX2J1aWxkX3N1YmNsYXNzX2luZGV4KCk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBDb252ZXJ0IGNsYXNzIG9iamVjdCB0byBuYW1lIGlmIG5lZWRlZFxuICAgICAgICBsZXQgYmFzZV9jbGFzc19uYW1lID0gYmFzZV9jbGFzcztcbiAgICAgICAgaWYgKHR5cGVvZiBiYXNlX2NsYXNzICE9PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgYmFzZV9jbGFzc19uYW1lID0gYmFzZV9jbGFzcy5fbmFtZSB8fCBiYXNlX2NsYXNzLm5hbWU7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBDaGVjayBpZiB0aGUgYmFzZSBjbGFzcyBleGlzdHNcbiAgICAgICAgaWYgKCFNYW5pZmVzdC5fY2xhc3Nlc1tiYXNlX2NsYXNzX25hbWVdKSB7XG4gICAgICAgICAgICAvLyBCYXNlIGNsYXNzIG5vdCBpbiBtYW5pZmVzdCAtIHJldHVybiBlbXB0eSBhcnJheVxuICAgICAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gR2V0IHN1YmNsYXNzIG5hbWVzIGZyb20gdGhlIGluZGV4XG4gICAgICAgIGNvbnN0IHN1YmNsYXNzX25hbWVzID0gTWFuaWZlc3QuX3N1YmNsYXNzX2luZGV4W2Jhc2VfY2xhc3NfbmFtZV0gfHwgW107XG5cbiAgICAgICAgLy8gQ29udmVydCBuYW1lcyB0byBhY3R1YWwgY2xhc3Mgb2JqZWN0c1xuICAgICAgICBjb25zdCBzdWJjbGFzc19vYmplY3RzID0gW107XG4gICAgICAgIGZvciAobGV0IHN1YmNsYXNzX25hbWUgb2Ygc3ViY2xhc3NfbmFtZXMpIHtcbiAgICAgICAgICAgIGNvbnN0IGNsYXNzZGF0YSA9IE1hbmlmZXN0Ll9jbGFzc2VzW3N1YmNsYXNzX25hbWVdO1xuICAgICAgICAgICAgc3ViY2xhc3Nfb2JqZWN0cy5wdXNoKGNsYXNzZGF0YS5jbGFzcyk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBTb3J0IGJ5IGNsYXNzIG5hbWUgZm9yIGRldGVybWluaXN0aWMgYmVoYXZpb3JcbiAgICAgICAgc3ViY2xhc3Nfb2JqZWN0cy5zb3J0KChhLCBiKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBuYW1lX2EgPSBhLl9uYW1lIHx8IGEubmFtZTtcbiAgICAgICAgICAgIGNvbnN0IG5hbWVfYiA9IGIuX25hbWUgfHwgYi5uYW1lO1xuICAgICAgICAgICAgcmV0dXJuIG5hbWVfYS5sb2NhbGVDb21wYXJlKG5hbWVfYik7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHJldHVybiBzdWJjbGFzc19vYmplY3RzO1xuICAgIH1cbn1cblxuLy8gUlNYIG1hbmlmZXN0IGF1dG9tYXRpY2FsbHkgbWFrZXMgY2xhc3NlcyBnbG9iYWwgLSBubyBtYW51YWwgYXNzaWdubWVudCBuZWVkZWRcbiIsIi8qKlxuICogUnN4X0JlaGF2aW9ycyAtIENvcmUgRnJhbWV3b3JrIFVzZXIgRXhwZXJpZW5jZSBFbmhhbmNlbWVudHNcbiAqXG4gKiBUaGlzIGNsYXNzIHByb3ZpZGVzIGF1dG9tYXRpYyBxdWFsaXR5LW9mLWxpZmUgYmVoYXZpb3JzIHRoYXQgaW1wcm92ZSB0aGUgZGVmYXVsdFxuICogYnJvd3NlciBleHBlcmllbmNlIGZvciBSU1ggYXBwbGljYXRpb25zLiBUaGVzZSBiZWhhdmlvcnMgYXJlIHRyYW5zcGFyZW50IHRvXG4gKiBhcHBsaWNhdGlvbiBkZXZlbG9wZXJzIGFuZCBydW4gYXV0b21hdGljYWxseSBvbiBmcmFtZXdvcmsgaW5pdGlhbGl6YXRpb24uXG4gKlxuICogVGhlc2UgYmVoYXZpb3JzIHVzZSBqUXVlcnkgZXZlbnQgZGVsZWdhdGlvbiB0byBoYW5kbGUgYm90aCBleGlzdGluZyBhbmQgZHluYW1pY2FsbHlcbiAqIGFkZGVkIGNvbnRlbnQuIFRoZXkgYXJlIGltcGxlbWVudGVkIHdpdGggbG93IHByaW9yaXR5IHRvIGFsbG93IGFwcGxpY2F0aW9uIGNvZGUgdG9cbiAqIG92ZXJyaWRlIGRlZmF1bHQgYmVoYXZpb3JzIHdoZW4gbmVlZGVkLlxuICpcbiAqIEBpbnRlcm5hbCBGcmFtZXdvcmsgdXNlIG9ubHkgLSBub3QgcGFydCBvZiBwdWJsaWMgQVBJXG4gKi9cbmNsYXNzIFJzeF9CZWhhdmlvcnMge1xuICAgIHN0YXRpYyBfb25fZnJhbWV3b3JrX2NvcmVfaW5pdCgpIHtcbiAgICAgICAgUnN4X0JlaGF2aW9ycy5faW5pdF9pZ25vcmVfaW52YWxpZF9hbmNob3JfbGlua3MoKTtcbiAgICAgICAgUnN4X0JlaGF2aW9ycy5fdHJpbV9jb3BpZWRfdGV4dCgpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIC0gQW5jaG9yIGxpbmsgaGFuZGxpbmc6IFByZXZlbnRzIGJyb2tlbiBcIiNcIiBsaW5rcyBmcm9tIGNhdXNpbmcgcGFnZSBqdW1wcyBvciBVUkwgY2hhbmdlc1xuICAgICAqIC0gSWdub3JlcyBcIiNcIiAoZW1wdHkgaGFzaCkgdG8gcHJldmVudCBzY3JvbGwtdG8tdG9wIGJlaGF2aW9yXG4gICAgICogLSBJZ25vcmVzIFwiI3BsYWNlaG9sZGVyKlwiIGxpbmtzIHVzZWQgYXMgcm91dGUgcGxhY2Vob2xkZXJzIGR1cmluZyBkZXZlbG9wbWVudFxuICAgICAqIC0gVmFsaWRhdGVzIGFuY2hvciB0YXJnZXRzIGV4aXN0IGJlZm9yZSBhbGxvd2luZyBuYXZpZ2F0aW9uXG4gICAgICogLSBQcmVzZXJ2ZXMgbm9ybWFsIGFuY2hvciBiZWhhdmlvciB3aGVuIHRhcmdldHMgZXhpc3RcbiAgICAgKi9cbiAgICBzdGF0aWMgX2luaXRfaWdub3JlX2ludmFsaWRfYW5jaG9yX2xpbmtzKCkge1xuICAgICAgICByZXR1cm47IC8vIGRpc2FibGVkIGZvciBub3cgLSBtYWtlIHRoaXMgaW50byBhIGNvbmZpZ3VyYWJsZSBvcHRpb25cblxuICAgICAgICAvLyBVc2UgZXZlbnQgZGVsZWdhdGlvbiBvbiBkb2N1bWVudCB0byBoYW5kbGUgYWxsIGN1cnJlbnQgYW5kIGZ1dHVyZSBhbmNob3IgY2xpY2tzXG4gICAgICAgIC8vIFVzZSBtb3VzZWRvd24gaW5zdGVhZCBvZiBjbGljayB0byBydW4gYmVmb3JlIG1vc3QgYXBwbGljYXRpb24gaGFuZGxlcnNcbiAgICAgICAgJChkb2N1bWVudCkub24oJ21vdXNlZG93bicsICdhW2hyZWZePVwiI1wiXScsIGZ1bmN0aW9uIChlKSB7XG4gICAgICAgICAgICBjb25zdCAkbGluayA9ICQodGhpcyk7XG4gICAgICAgICAgICBjb25zdCBocmVmID0gJGxpbmsuYXR0cignaHJlZicpO1xuXG4gICAgICAgICAgICAvLyBDaGVjayBpZiBhbm90aGVyIGhhbmRsZXIgaGFzIGFscmVhZHkgcHJldmVudGVkIGRlZmF1bHRcbiAgICAgICAgICAgIGlmIChlLmlzRGVmYXVsdFByZXZlbnRlZCgpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBBbGxvdyBkYXRhLXJzeC1hbGxvdy1oYXNoIGF0dHJpYnV0ZSB0byBieXBhc3MgdGhpcyBiZWhhdmlvclxuICAgICAgICAgICAgaWYgKCRsaW5rLmRhdGEoJ3JzeC1hbGxvdy1oYXNoJykpIHtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIEhhbmRsZSBlbXB0eSBoYXNoIC0gcHJldmVudCBzY3JvbGwgdG8gdG9wXG4gICAgICAgICAgICBpZiAoaHJlZiA9PT0gJyMnKSB7XG4gICAgICAgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgICAgICAgIGUuc3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uKCk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBIYW5kbGUgcGxhY2Vob2xkZXIgbGlua3MgdXNlZCBkdXJpbmcgZGV2ZWxvcG1lbnRcbiAgICAgICAgICAgIGlmIChocmVmLnN0YXJ0c1dpdGgoJyNwbGFjZWhvbGRlcicpKSB7XG4gICAgICAgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgICAgICAgIGUuc3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uKCk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBGb3Igb3RoZXIgaGFzaCBsaW5rcywgY2hlY2sgaWYgdGFyZ2V0IGV4aXN0c1xuICAgICAgICAgICAgY29uc3QgdGFyZ2V0SWQgPSBocmVmLnN1YnN0cmluZygxKTtcbiAgICAgICAgICAgIGlmICh0YXJnZXRJZCkge1xuICAgICAgICAgICAgICAgIC8vIENoZWNrIGZvciBlbGVtZW50IHdpdGggbWF0Y2hpbmcgSUQgb3IgbmFtZSBhdHRyaWJ1dGVcbiAgICAgICAgICAgICAgICBjb25zdCB0YXJnZXRFeGlzdHMgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCh0YXJnZXRJZCkgIT09IG51bGwgfHwgZG9jdW1lbnQucXVlcnlTZWxlY3RvcihgW25hbWU9XCIke3RhcmdldElkfVwiXWApICE9PSBudWxsO1xuXG4gICAgICAgICAgICAgICAgaWYgKCF0YXJnZXRFeGlzdHMpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gVGFyZ2V0IGRvZXNuJ3QgZXhpc3QgLSBwcmV2ZW50IG5hdmlnYXRpb25cbiAgICAgICAgICAgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgICAgICAgICAgICBlLnN0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbigpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIC8vIFRhcmdldCBleGlzdHMgLSBhbGxvdyBub3JtYWwgYW5jaG9yIGJlaGF2aW9yXG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIC0gQ29weSB0ZXh0IHRyaW1taW5nOiBBdXRvbWF0aWNhbGx5IHJlbW92ZXMgbGVhZGluZy90cmFpbGluZyB3aGl0ZXNwYWNlIGZyb20gY29waWVkIHRleHRcbiAgICAgKiAtIEhvbGQgU2hpZnQgdG8gcHJlc2VydmUgd2hpdGVzcGFjZVxuICAgICAqIC0gU2tpcHMgdHJpbW1pbmcgaW4gY29kZSBibG9ja3MsIHRleHRhcmVhcywgYW5kIGNvbnRlbnRlZGl0YWJsZSBlbGVtZW50c1xuICAgICAqL1xuICAgIHN0YXRpYyBfdHJpbV9jb3BpZWRfdGV4dCgpIHtcbiAgICAgICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignY29weScsIGZ1bmN0aW9uIChldmVudCkge1xuICAgICAgICAgICAgLy8gRG9uJ3QgdHJpbSBpZiB1c2VyIGlzIGhvbGRpbmcgU2hpZnQgKGFsbG93cyBjb3B5aW5nIHdpdGggd2hpdGVzcGFjZSBpZiBuZWVkZWQpXG4gICAgICAgICAgICBpZiAoZXZlbnQuc2hpZnRLZXkpIHJldHVybjtcblxuICAgICAgICAgICAgbGV0IHNlbGVjdGlvbiA9IHdpbmRvdy5nZXRTZWxlY3Rpb24oKTtcbiAgICAgICAgICAgIGxldCBzZWxlY3RlZF90ZXh0ID0gc2VsZWN0aW9uLnRvU3RyaW5nKCk7XG5cbiAgICAgICAgICAgIC8vIERvbid0IHRyaW0gaWYgc2VsZWN0aW9uIGlzIGVtcHR5XG4gICAgICAgICAgICBpZiAoIXNlbGVjdGVkX3RleHQpIHJldHVybjtcblxuICAgICAgICAgICAgLy8gRG9uJ3QgdHJpbSBpZiBjb3B5aW5nIGZyb20gY29kZSBibG9ja3MsIHRleHRhcmVhcywgb3IgY29udGVudC1lZGl0YWJsZSAocHJlc2VydmUgZm9ybWF0dGluZylcbiAgICAgICAgICAgIGxldCBjb250YWluZXIgPSBzZWxlY3Rpb24uZ2V0UmFuZ2VBdCgwKS5jb21tb25BbmNlc3RvckNvbnRhaW5lcjtcbiAgICAgICAgICAgIGlmIChjb250YWluZXIubm9kZVR5cGUgPT09IDMpIGNvbnRhaW5lciA9IGNvbnRhaW5lci5wYXJlbnROb2RlOyAvLyBUZXh0IG5vZGUgdG8gZWxlbWVudFxuICAgICAgICAgICAgaWYgKGNvbnRhaW5lci5jbG9zZXN0KCdwcmUsIGNvZGUsIC5jb2RlLWJsb2NrLCB0ZXh0YXJlYSwgW2NvbnRlbnRlZGl0YWJsZT1cInRydWVcIl0nKSkgcmV0dXJuO1xuXG4gICAgICAgICAgICBsZXQgdHJpbW1lZF90ZXh0ID0gc2VsZWN0ZWRfdGV4dC50cmltKCk7XG5cbiAgICAgICAgICAgIC8vIE9ubHkgbW9kaWZ5IGlmIHRoZXJlJ3MgYWN0dWFsbHkgd2hpdGVzcGFjZSB0byB0cmltXG4gICAgICAgICAgICBpZiAodHJpbW1lZF90ZXh0ICE9PSBzZWxlY3RlZF90ZXh0ICYmIHRyaW1tZWRfdGV4dC5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICAgICAgICBldmVudC5jbGlwYm9hcmREYXRhLnNldERhdGEoJ3RleHQvcGxhaW4nLCB0cmltbWVkX3RleHQpO1xuICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKCdDb3B5OiB0cmltbWVkIHdoaXRlc3BhY2UgZnJvbSBzZWxlY3Rpb24nKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxufVxuIiwiLy8gU2ltcGxlIGtleSB2YWx1ZSBjYWNoZS4gIENhbiBvbmx5IHN0b3JlIDUwMDAgZW50cmllcywgd2lsbCByZXNldCBhZnRlciA1MDAwIGVudHJpZXMuXG5cbi8vIFRvZG86IGtlZXAgbG9jYWwgY2FjaGUgY29uY2VwdCB0aGUgc2FtZSwgcmVwbGFjZSBnbG9iYWwgY2FjaGUgY29uY2VwdCB3aXRoIHRoZSBub3YgMjAxOSB2ZXJzaW9uIG9mXG4vLyBzZXNzaW9uIGNhY2hlLiAgVXNlIGEgc2Vzc2lvbiBrZXkgJiBidWlsZCBrZXkgdG8gdHJhY2sgY2FjaGUga2V5cyBzbyBjYWNoZWQgdmFsdWVzIG9ubHkgbGFzdCB1bnRpbCB1c2VyIGxvZ3Mgb3V0LlxuLy8gcmV2aWV3IHNlc3Npb24gY29kZSB0byBlbnN1cmUgdGhhdCBzZXNzaW9uIGtleSAqYWx3YXlzKiByb3RhdGVzIG9uIGxvZ291dC4gIE1ha2Ugc2Vzc2lvbiBpZCBhIHByb3RlY3RlZCB2YWx1ZS5cbmNsYXNzIFJzeF9DYWNoZSB7XG4gICAgc3RhdGljIG9uX2NvcmVfZGVmaW5lKCkge1xuICAgICAgICBDb3JlX0NhY2hlLl9jYWNoZXMgPSB7XG4gICAgICAgICAgICBnbG9iYWw6IHt9LFxuICAgICAgICAgICAgaW5zdGFuY2U6IHt9LFxuICAgICAgICB9O1xuXG4gICAgICAgIENvcmVfQ2FjaGUuX2NhY2hlc19zZXQgPSAwO1xuICAgIH1cblxuICAgIC8vIEFsaWFzIGZvciBnZXRfaW5zdGFuY2VcbiAgICBzdGF0aWMgZ2V0KGtleSkge1xuICAgICAgICByZXR1cm4gUnN4X0NhY2hlLmdldF9pbnN0YW5jZShrZXkpO1xuICAgIH1cblxuICAgIC8vIFJldHVybnMgZnJvbSB0aGUgcG9vbCBvZiBjYWNoZWQgZGF0YSBmb3IgdGhpcyAnaW5zdGFuY2UnLiAgQW4gaW5zdGFuY2VcbiAgICAvLyBpbiB0aGlzIGNhc2UgaXMgYSB2aXJ0dWFsIHBhZ2UgbG9hZCAvIG5hdmlnYXRpb24gaW4gdGhlIFNQQS4gIENhbGwgTWFpbi5saWIucmVzZXQoKSB0byByZXNldC5cbiAgICAvLyBSZXR1cm5zIG51bGwgb24gZmFpbHVyZVxuICAgIHN0YXRpYyBnZXRfaW5zdGFuY2Uoa2V5KSB7XG4gICAgICAgIGlmIChNYWluLmRlYnVnKCdub19hcGlfY2FjaGUnKSkge1xuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cblxuICAgICAgICBsZXQga2V5X2VuY29kZWQgPSBSc3hfQ2FjaGUuX2VuY29kZWtleShrZXkpO1xuXG4gICAgICAgIGlmICh0eXBlb2YgQ29yZV9DYWNoZS5fY2FjaGVzLmluc3RhbmNlW2tleV9lbmNvZGVkXSAhPSB1bmRlZikge1xuICAgICAgICAgICAgcmV0dXJuIEpTT04ucGFyc2UoQ29yZV9DYWNoZS5fY2FjaGVzLmluc3RhbmNlW2tleV9lbmNvZGVkXSk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICAvLyBSZXR1cm5zIG51bGwgb24gZmFpbHVyZVxuICAgIC8vIFJldHVybnMgYSBjYWNoZWQgdmFsdWUgZnJvbSBnbG9iYWwgY2FjaGUgKHVuaXF1ZSB0byBwYWdlIGxvYWQsIHN1cnZpdmVzIHJlc2V0KCkpXG4gICAgc3RhdGljIGdldF9nbG9iYWwoa2V5KSB7XG4gICAgICAgIGlmIChNYWluLmRlYnVnKCdub19hcGlfY2FjaGUnKSkge1xuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cblxuICAgICAgICBsZXQga2V5X2VuY29kZWQgPSBSc3hfQ2FjaGUuX2VuY29kZWtleShrZXkpO1xuXG4gICAgICAgIGlmICh0eXBlb2YgQ29yZV9DYWNoZS5fY2FjaGVzLmdsb2JhbFtrZXlfZW5jb2RlZF0gIT0gdW5kZWYpIHtcbiAgICAgICAgICAgIHJldHVybiBKU09OLnBhcnNlKENvcmVfQ2FjaGUuX2NhY2hlcy5nbG9iYWxba2V5X2VuY29kZWRdKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIC8vIFNldHMgYSB2YWx1ZSBpbiBpbnN0YW5jZSBhbmQgZ2xvYmFsIGNhY2hlIChub3Qgc2hhcmVkIGJldHdlZW4gYnJvd3NlciB0YWJzKVxuICAgIHN0YXRpYyBzZXQoa2V5LCB2YWx1ZSkge1xuICAgICAgICBpZiAoTWFpbi5kZWJ1Zygnbm9fYXBpX2NhY2hlJykpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh2YWx1ZSA9PT0gbnVsbCkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHZhbHVlLmxlbmd0aCA+IDY0ICogMTAyNCkge1xuICAgICAgICAgICAgRGVidWdnZXIuY29uc29sZV9kZWJ1ZygnQ0FDSEUnLCAnV2FybmluZyAtIG5vdCBjYWNoaW5nIGxhcmdlIGNhY2hlIGVudHJ5Jywga2V5KTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGxldCBrZXlfZW5jb2RlZCA9IFJzeF9DYWNoZS5fZW5jb2Rla2V5KGtleSk7XG5cbiAgICAgICAgQ29yZV9DYWNoZS5fY2FjaGVzLmdsb2JhbFtrZXlfZW5jb2RlZF0gPSBKU09OLnN0cmluZ2lmeSh2YWx1ZSk7XG4gICAgICAgIENvcmVfQ2FjaGUuX2NhY2hlcy5pbnN0YW5jZVtrZXlfZW5jb2RlZF0gPSBKU09OLnN0cmluZ2lmeSh2YWx1ZSk7XG5cbiAgICAgICAgLy8gRGVidWdnZXIuY29uc29sZV9kZWJ1ZyhcIkNBQ0hFXCIsIFwiU2V0XCIsIGtleSwgdmFsdWUpO1xuXG4gICAgICAgIENvcmVfQ2FjaGUuX2NhY2hlc19zZXQrKztcblxuICAgICAgICAvLyBSZXNldCBjYWNoZSBhZnRlciA1MDAwIGl0ZW1zIHNldFxuICAgICAgICBpZiAoQ29yZV9DYWNoZS5fY2FjaGVzX3NldCA+IDUwMDApIHtcbiAgICAgICAgICAgIC8vIEdldCBhbiBhY2N1cmF0ZSBjb3VudFxuICAgICAgICAgICAgQ29yZV9DYWNoZS5fY2FjaGVzX3NldCA9IGNvdW50KENvcmVfQ2FjaGUuX2NhY2hlcy5nbG9iYWwpO1xuXG4gICAgICAgICAgICBpZiAoQ29yZV9DYWNoZS5fY2FjaGVzX3NldCA+IDUwMDApIHtcbiAgICAgICAgICAgICAgICBDb3JlX0NhY2hlLl9jYWNoZXMgPSB7XG4gICAgICAgICAgICAgICAgICAgIGdsb2JhbDoge30sXG4gICAgICAgICAgICAgICAgICAgIGluc3RhbmNlOiB7fSxcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIENvcmVfQ2FjaGUuX2NhY2hlc19zZXQgPSAwO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgLy8gUmV0dXJucyBudWxsIG9uIGZhaWx1cmVcbiAgICAvLyBSZXR1cm5zIGEgY2FjaGVkIHZhbHVlIGZyb20gc2Vzc2lvbiBjYWNoZSAoc2hhcmVkIGJldHdlZW4gYnJvd3NlciB0YWJzKVxuICAgIHN0YXRpYyBnZXRfc2Vzc2lvbihrZXkpIHtcbiAgICAgICAgaWYgKE1haW4uZGVidWcoJ25vX2FwaV9jYWNoZScpKSB7XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghUnN4X0NhY2hlLl9zdXBwb3J0c1N0b3JhZ2UoKSkge1xuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cblxuICAgICAgICBsZXQga2V5X2VuY29kZWQgPSBSc3hfQ2FjaGUuX2VuY29kZWtleShrZXkpO1xuXG4gICAgICAgIGxldCBycyA9IHNlc3Npb25TdG9yYWdlLmdldEl0ZW0oa2V5X2VuY29kZWQpO1xuXG4gICAgICAgIGlmICghZW1wdHkocnMpKSB7XG4gICAgICAgICAgICByZXR1cm4gSlNPTi5wYXJzZShycyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8vIFNldHMgYSB2YWx1ZSBpbiBzZXNzaW9uIGNhY2hlIChzaGFyZWQgYmV0d2VlbiBicm93c2VyIHRhYnMpXG4gICAgc3RhdGljIHNldF9zZXNzaW9uKGtleSwgdmFsdWUsIF90cnlhZ2FpbiA9IHRydWUpIHtcbiAgICAgICAgaWYgKE1haW4uZGVidWcoJ25vX2FwaV9jYWNoZScpKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodmFsdWUubGVuZ3RoID4gNjQgKiAxMDI0KSB7XG4gICAgICAgICAgICBEZWJ1Z2dlci5jb25zb2xlX2RlYnVnKCdDQUNIRScsICdXYXJuaW5nIC0gbm90IGNhY2hpbmcgbGFyZ2UgY2FjaGUgZW50cnknLCBrZXkpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCFSc3hfQ2FjaGUuX3N1cHBvcnRzU3RvcmFnZSgpKSB7XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuXG4gICAgICAgIGxldCBrZXlfZW5jb2RlZCA9IFJzeF9DYWNoZS5fZW5jb2Rla2V5KGtleSk7XG5cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHNlc3Npb25TdG9yYWdlLnJlbW92ZUl0ZW0oa2V5X2VuY29kZWQpO1xuICAgICAgICAgICAgc2Vzc2lvblN0b3JhZ2Uuc2V0SXRlbShrZXlfZW5jb2RlZCwgSlNPTi5zdHJpbmdpZnkodmFsdWUpKTtcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgaWYgKFJzeF9DYWNoZS5faXNPdXRPZlNwYWNlKGUpICYmIHNlc3Npb25TdG9yYWdlLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIHNlc3Npb25TdG9yYWdlLmNsZWFyKCk7XG4gICAgICAgICAgICAgICAgaWYgKF90cnlhZ2Fpbikge1xuICAgICAgICAgICAgICAgICAgICBDb3JlX0NhY2hlLnNldF9zZXNzaW9uKGtleSwgdmFsdWUsIGZhbHNlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBzdGF0aWMgX3Jlc2V0KCkge1xuICAgICAgICBDb3JlX0NhY2hlLl9jYWNoZXMuaW5zdGFuY2UgPSB7fTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBGb3IgZ2l2ZW4ga2V5IG9mIGFueSB0eXBlIGluY2x1ZGluZyBhbiBvYmplY3QsIHJldHVybiBhIHN0cmluZyByZXByZXNlbnRpbmdcbiAgICAgKiB0aGUga2V5IHRoYXQgdGhlIGNhY2hlZCB2YWx1ZSBzaG91bGQgYmUgc3RvcmVkIGFzIGluIHNlc3Npb25zdG9yYWdlXG4gICAgICovXG4gICAgc3RhdGljIF9lbmNvZGVrZXkoa2V5KSB7XG4gICAgICAgIGNvbnN0IHByZWZpeCA9ICdjYWNoZV8nO1xuXG4gICAgICAgIC8vIFNlc3Npb24gcmVpbXBsZW1lbnRcbiAgICAgICAgLy8gdmFyIHByZWZpeCA9IFwiY2FjaGVfXCIgKyBTcGEuc2Vzc2lvbigpLnVzZXJfaWQoKSArIFwiX1wiO1xuXG4gICAgICAgIGlmIChpc19zdHJpbmcoa2V5KSAmJiBrZXkubGVuZ3RoIDwgMTUwICYmIGtleS5pbmRleE9mKCcgJykgPT0gLTEpIHtcbiAgICAgICAgICAgIHJldHVybiBwcmVmaXggKyBNYW5pZmVzdC5idWlsZF9rZXkoKSArICdfJyArIGtleTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBwcmVmaXggKyBoYXNoKFtNYW5pZmVzdC5idWlsZF9rZXkoKSwga2V5XSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBEZXRlcm1pbmVzIGlmIHNlc3Npb25TdG9yYWdlIGlzIHN1cHBvcnRlZCBpbiB0aGUgYnJvd3NlcjtcbiAgICAvLyByZXN1bHQgaXMgY2FjaGVkIGZvciBiZXR0ZXIgcGVyZm9ybWFuY2UgaW5zdGVhZCBvZiBiZWluZyBydW4gZWFjaCB0aW1lLlxuICAgIC8vIEZlYXR1cmUgZGV0ZWN0aW9uIGlzIGJhc2VkIG9uIGhvdyBNb2Rlcm5penIgZG9lcyBpdDtcbiAgICAvLyBpdCdzIG5vdCBzdHJhaWdodGZvcndhcmQgZHVlIHRvIEZGNCBpc3N1ZXMuXG4gICAgLy8gSXQncyBub3QgcnVuIGF0IHBhcnNlLXRpbWUgYXMgaXQgdGFrZXMgMjAwbXMgaW4gQW5kcm9pZC5cbiAgICAvLyBDb2RlIGZyb20gaHR0cHM6Ly9naXRodWIuY29tL3BhbWVsYWZveC9sc2NhY2hlL2Jsb2IvbWFzdGVyL2xzY2FjaGUuanMsIEFwYWNoZSBMaWNlbnNlIFBhbWVsYWZveFxuICAgIHN0YXRpYyBfc3VwcG9ydHNTdG9yYWdlKCkge1xuICAgICAgICBsZXQga2V5ID0gJ19fY2FjaGV0ZXN0X18nO1xuICAgICAgICBsZXQgdmFsdWUgPSBrZXk7XG5cbiAgICAgICAgaWYgKFJzeF9DYWNoZS5fX3N1cHBvcnRzU3RvcmFnZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICByZXR1cm4gUnN4X0NhY2hlLl9fc3VwcG9ydHNTdG9yYWdlO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gc29tZSBicm93c2VycyB3aWxsIHRocm93IGFuIGVycm9yIGlmIHlvdSB0cnkgdG8gYWNjZXNzIGxvY2FsIHN0b3JhZ2UgKGUuZy4gYnJhdmUgYnJvd3NlcilcbiAgICAgICAgLy8gaGVuY2UgY2hlY2sgaXMgaW5zaWRlIGEgdHJ5L2NhdGNoXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBpZiAoIXNlc3Npb25TdG9yYWdlKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGNhdGNoIChleCkge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG5cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHNlc3Npb25TdG9yYWdlLnNldEl0ZW0oa2V5LCB2YWx1ZSk7XG4gICAgICAgICAgICBzZXNzaW9uU3RvcmFnZS5yZW1vdmVJdGVtKGtleSk7XG4gICAgICAgICAgICBSc3hfQ2FjaGUuX19zdXBwb3J0c1N0b3JhZ2UgPSB0cnVlO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAvLyBJZiB3ZSBoaXQgdGhlIGxpbWl0LCBhbmQgd2UgZG9uJ3QgaGF2ZSBhbiBlbXB0eSBzZXNzaW9uU3RvcmFnZSB0aGVuIGl0IG1lYW5zIHdlIGhhdmUgc3VwcG9ydFxuICAgICAgICAgICAgaWYgKFJzeF9DYWNoZS5faXNPdXRPZlNwYWNlKGUpICYmIHNlc3Npb25TdG9yYWdlLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIFJzeF9DYWNoZS5fX3N1cHBvcnRzU3RvcmFnZSA9IHRydWU7IC8vIGp1c3QgbWF4ZWQgaXQgb3V0IGFuZCBldmVuIHRoZSBzZXQgdGVzdCBmYWlsZWQuXG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIFJzeF9DYWNoZS5fX3N1cHBvcnRzU3RvcmFnZSA9IGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIFJzeF9DYWNoZS5fX3N1cHBvcnRzU3RvcmFnZTtcbiAgICB9XG5cbiAgICAvLyBDaGVjayB0byBzZXQgaWYgdGhlIGVycm9yIGlzIHVzIGRlYWxpbmcgd2l0aCBiZWluZyBvdXQgb2Ygc3BhY2VcbiAgICBzdGF0aWMgX2lzT3V0T2ZTcGFjZShlKSB7XG4gICAgICAgIHJldHVybiBlICYmIChlLm5hbWUgPT09ICdRVU9UQV9FWENFRURFRF9FUlInIHx8IGUubmFtZSA9PT0gJ05TX0VSUk9SX0RPTV9RVU9UQV9SRUFDSEVEJyB8fCBlLm5hbWUgPT09ICdRdW90YUV4Y2VlZGVkRXJyb3InKTtcbiAgICB9XG59XG4iLCIvKipcbiAqIFJzeF9Jbml0IC0gQ29yZSBmcmFtZXdvcmsgaW5pdGlhbGl6YXRpb24gYW5kIGVudmlyb25tZW50IHZhbGlkYXRpb25cbiAqL1xuY2xhc3MgUnN4X0luaXQge1xuICAgIC8qKlxuICAgICAqIENhbGxlZCB2aWEgUnN4Ll9yc3hfY29yZV9ib290XG4gICAgICogSW5pdGlhbGl6ZXMgdGhlIGNvcmUgZW52aXJvbm1lbnQgYW5kIHJ1bnMgYmFzaWMgc2FuaXR5IGNoZWNrc1xuICAgICAqL1xuICAgIHN0YXRpYyBfb25fZnJhbWV3b3JrX2NvcmVfaW5pdCgpIHtcbiAgICAgICAgaWYgKCFSc3guaXNfcHJvZCgpKSB7XG4gICAgICAgICAgICBSc3hfSW5pdC5fX2Vudmlyb25tZW50X2NoZWNrcygpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRGV2ZWxvcG1lbnQgZW52aXJvbm1lbnQgY2hlY2tzIHRvIGVuc3VyZSBwcm9wZXIgY29uZmlndXJhdGlvblxuICAgICAqL1xuICAgIHN0YXRpYyBfX2Vudmlyb25tZW50X2NoZWNrcygpIHtcbiAgICAgICAgLy8gRmluZCBhbGwgc2NyaXB0IHRhZ3MgaW4gdGhlIERPTVxuICAgICAgICBjb25zdCBzY3JpcHRzID0gZG9jdW1lbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoJ3NjcmlwdCcpO1xuXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc2NyaXB0cy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgY29uc3Qgc2NyaXB0ID0gc2NyaXB0c1tpXTtcblxuICAgICAgICAgICAgLy8gU2tpcCBpbmxpbmUgc2NyaXB0cyAobm8gc3JjIGF0dHJpYnV0ZSlcbiAgICAgICAgICAgIGlmICghc2NyaXB0LnNyYykge1xuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBDaGVjayBpZiBzY3JpcHQgaGFzIGRlZmVyIGF0dHJpYnV0ZVxuICAgICAgICAgICAgaWYgKCFzY3JpcHQuZGVmZXIpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBzcmMgPSBzY3JpcHQuc3JjIHx8ICcoaW5saW5lIHNjcmlwdCknO1xuICAgICAgICAgICAgICAgIGNvbnN0IHJlYXNvbiA9IGBBbGwgc2NyaXB0IHRhZ3MgdXNlZCBpbiBhbiBSU3BhZGUgcHJvamVjdCBtdXN0IGhhdmUgZGVmZXIgYXR0cmlidXRlLiBGb3VuZCBzY3JpcHQgd2l0aG91dCBkZWZlcjogJHtzcmN9YDtcblxuICAgICAgICAgICAgICAgIC8vIFN0b3AgZnJhbWV3b3JrIGJvb3Qgd2l0aCByZWFzb25cbiAgICAgICAgICAgICAgICBSc3guX3JzeF9jb3JlX2Jvb3Rfc3RvcChyZWFzb24pO1xuXG4gICAgICAgICAgICAgICAgLy8gQWxzbyBsb2cgdG8gY29uc29sZSBmb3IgdmlzaWJpbGl0eVxuICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoYFtSU1ggQk9PVCBTVE9QUEVEXSAke3JlYXNvbn1gKTtcblxuICAgICAgICAgICAgICAgIC8vIFN0b3AgY2hlY2tpbmcgYWZ0ZXIgZmlyc3QgdmlvbGF0aW9uXG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxufSIsIi8vIEBGSUxFLVNVQkNMQVNTLTAxLUVYQ0VQVElPTlxuXG4vKipcbiAqIEJhc2UgY2xhc3MgZm9yIEphdmFTY3JpcHQgT1JNIG1vZGVsc1xuICpcbiAqIFByb3ZpZGVzIGNvcmUgZnVuY3Rpb25hbGl0eSBmb3IgZmV0Y2hpbmcgcmVjb3JkcyBmcm9tIGJhY2tlbmQgUEhQIG1vZGVscy5cbiAqIEFsbCBtb2RlbCBzdHVicyBnZW5lcmF0ZWQgYnkgdGhlIG1hbmlmZXN0IGV4dGVuZCB0aGlzIGJhc2UgY2xhc3MuXG4gKlxuICogRXhhbXBsZSB1c2FnZTpcbiAqICAgLy8gRmV0Y2ggc2luZ2xlIHJlY29yZFxuICogICBjb25zdCB1c2VyID0gYXdhaXQgVXNlcl9Nb2RlbC5mZXRjaCgxMjMpO1xuICpcbiAqICAgLy8gRmV0Y2ggbXVsdGlwbGUgcmVjb3Jkc1xuICogICBjb25zdCB1c2VycyA9IGF3YWl0IFVzZXJfTW9kZWwuZmV0Y2goWzEsIDIsIDNdKTtcbiAqXG4gKiAgIC8vIENyZWF0ZSBpbnN0YW5jZSB3aXRoIGRhdGFcbiAqICAgY29uc3QgdXNlciA9IG5ldyBVc2VyX01vZGVsKHtpZDogMSwgbmFtZTogJ0pvaG4nfSk7XG4gKlxuICogIEBJbnN0YW50aWF0YWJsZVxuICovXG5jbGFzcyBSc3hfSnNfTW9kZWwge1xuICAgIC8qKlxuICAgICAqIENvbnN0cnVjdG9yIC0gSW5pdGlhbGl6ZSBtb2RlbCBpbnN0YW5jZSB3aXRoIGRhdGFcbiAgICAgKlxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBkYXRhIC0gS2V5LXZhbHVlIHBhaXJzIHRvIHBvcHVsYXRlIHRoZSBtb2RlbFxuICAgICAqL1xuICAgIGNvbnN0cnVjdG9yKGRhdGEgPSB7fSkge1xuICAgICAgICAvLyBfX01PREVMIFNZU1RFTTogRW5hYmxlcyBhdXRvbWF0aWMgT1JNIGluc3RhbnRpYXRpb24gd2hlbiBmZXRjaGluZyBmcm9tIFBIUCBtb2RlbHMuXG4gICAgICAgIC8vIFBIUCBtb2RlbHMgYWRkIFwiX19NT0RFTFwiOiBcIkNsYXNzTmFtZVwiIHRvIEpTT04sIEphdmFTY3JpcHQgdXNlcyBpdCB0byBjcmVhdGUgcHJvcGVyIGluc3RhbmNlcy5cbiAgICAgICAgLy8gVGhpcyBwcm92aWRlcyB0eXBlZCBtb2RlbCBvYmplY3RzIGluc3RlYWQgb2YgcGxhaW4gSlNPTiwgd2l0aCBtZXRob2RzIGFuZCB0eXBlIGNoZWNraW5nLlxuXG4gICAgICAgIC8vIFRoaXMgY29uc3RydWN0b3IgZmlsdGVycyBvdXQgdGhlIF9fTU9ERUwgbWFya2VyIHRoYXQgd2FzIHVzZWQgdG8gaWRlbnRpZnkgd2hpY2ggY2xhc3NcbiAgICAgICAgLy8gdG8gaW5zdGFudGlhdGUsIGtlZXBpbmcgb25seSB0aGUgYWN0dWFsIGRhdGEgcHJvcGVydGllcyBvbiB0aGUgaW5zdGFuY2UuXG4gICAgICAgIGNvbnN0IHsgX19NT0RFTCwgLi4ubW9kZWxEYXRhIH0gPSBkYXRhO1xuICAgICAgICBPYmplY3QuYXNzaWduKHRoaXMsIG1vZGVsRGF0YSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRmV0Y2ggcmVjb3JkKHMpIGZyb20gdGhlIGJhY2tlbmQgbW9kZWxcbiAgICAgKlxuICAgICAqIFRoaXMgbWV0aG9kIG1pcnJvcnMgdGhlIFBIUCBNb2RlbDo6ZmV0Y2goKSBmdW5jdGlvbmFsaXR5LlxuICAgICAqIFRoZSBiYWNrZW5kIG1vZGVsIG11c3QgaGF2ZSBhIGZldGNoKCkgbWV0aG9kIHdpdGggdGhlXG4gICAgICogI1tBamF4X0VuZHBvaW50X01vZGVsX0ZldGNoXSBhbm5vdGF0aW9uIHRvIGJlIGNhbGxhYmxlLlxuICAgICAqXG4gICAgICogQHBhcmFtIHtudW1iZXJ8QXJyYXl9IGlkIC0gU2luZ2xlIElEIG9yIGFycmF5IG9mIElEcyB0byBmZXRjaFxuICAgICAqIEByZXR1cm5zIHtQcm9taXNlfSAtIFNpbmdsZSBtb2RlbCBpbnN0YW5jZSwgYXJyYXkgb2YgaW5zdGFuY2VzLCBvciBmYWxzZVxuICAgICAqL1xuICAgIHN0YXRpYyBhc3luYyBmZXRjaChpZCkge1xuICAgICAgICBjb25zdCBDdXJyZW50Q2xhc3MgPSB0aGlzO1xuICAgICAgICAvLyBHZXQgdGhlIG1vZGVsIGNsYXNzIG5hbWUgZnJvbSB0aGUgY3VycmVudCBjbGFzc1xuICAgICAgICBjb25zdCBtb2RlbE5hbWUgPSBDdXJyZW50Q2xhc3MubmFtZTtcblxuICAgICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0ICQuYWpheCh7XG4gICAgICAgICAgICB1cmw6IGAvX2ZldGNoLyR7bW9kZWxOYW1lfWAsXG4gICAgICAgICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgICAgICAgIGRhdGE6IHsgaWQ6IGlkIH0sXG4gICAgICAgICAgICBkYXRhVHlwZTogJ2pzb24nLFxuICAgICAgICB9KTtcblxuICAgICAgICAvLyBIYW5kbGUgcmVzcG9uc2UgYmFzZWQgb24gdHlwZVxuICAgICAgICBpZiAocmVzcG9uc2UgPT09IGZhbHNlKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBVc2UgX2luc3RhbnRpYXRlX21vZGVsc19yZWN1cnNpdmUgdG8gaGFuZGxlIE9STSBpbnN0YW50aWF0aW9uXG4gICAgICAgIC8vIFRoaXMgd2lsbCBhdXRvbWF0aWNhbGx5IGRldGVjdCBfX01PREVMIHByb3BlcnRpZXMgYW5kIGNyZWF0ZSBhcHByb3ByaWF0ZSBpbnN0YW5jZXNcbiAgICAgICAgcmV0dXJuIFJzeF9Kc19Nb2RlbC5faW5zdGFudGlhdGVfbW9kZWxzX3JlY3Vyc2l2ZShyZXNwb25zZSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0IHRoZSBtb2RlbCBjbGFzcyBuYW1lXG4gICAgICogVXNlZCBpbnRlcm5hbGx5IGZvciBBUEkgY2FsbHNcbiAgICAgKlxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFRoZSBjbGFzcyBuYW1lXG4gICAgICovXG4gICAgc3RhdGljIGdldE1vZGVsTmFtZSgpIHtcbiAgICAgICAgY29uc3QgQ3VycmVudENsYXNzID0gdGhpcztcbiAgICAgICAgcmV0dXJuIEN1cnJlbnRDbGFzcy5uYW1lO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlZnJlc2ggdGhpcyBpbnN0YW5jZSB3aXRoIGxhdGVzdCBkYXRhIGZyb20gc2VydmVyXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyB7UHJvbWlzZX0gVXBkYXRlZCBpbnN0YW5jZSBvciBmYWxzZSBpZiBub3QgZm91bmRcbiAgICAgKi9cbiAgICBhc3luYyByZWZyZXNoKCkge1xuICAgICAgICBjb25zdCB0aGF0ID0gdGhpcztcbiAgICAgICAgaWYgKCF0aGF0LmlkKSB7XG4gICAgICAgICAgICBzaG91bGRudF9oYXBwZW4oJ0Nhbm5vdCByZWZyZXNoIG1vZGVsIHdpdGhvdXQgaWQgcHJvcGVydHknKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGZyZXNoID0gYXdhaXQgdGhhdC5jb25zdHJ1Y3Rvci5mZXRjaCh0aGF0LmlkKTtcblxuICAgICAgICBpZiAoZnJlc2ggPT09IGZhbHNlKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBVcGRhdGUgdGhpcyBpbnN0YW5jZSB3aXRoIGZyZXNoIGRhdGFcbiAgICAgICAgT2JqZWN0LmFzc2lnbih0aGF0LCBmcmVzaCk7XG4gICAgICAgIHJldHVybiB0aGF0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENvbnZlcnQgbW9kZWwgaW5zdGFuY2UgdG8gcGxhaW4gb2JqZWN0XG4gICAgICogVXNlZnVsIGZvciBzZXJpYWxpemF0aW9uIG9yIHNlbmRpbmcgdG8gQVBJc1xuICAgICAqXG4gICAgICogQHJldHVybnMge09iamVjdH0gUGxhaW4gb2JqZWN0IHJlcHJlc2VudGF0aW9uXG4gICAgICovXG4gICAgdG9PYmplY3QoKSB7XG4gICAgICAgIGNvbnN0IHRoYXQgPSB0aGlzO1xuICAgICAgICBjb25zdCBvYmogPSB7fTtcbiAgICAgICAgZm9yIChjb25zdCBrZXkgaW4gdGhhdCkge1xuICAgICAgICAgICAgaWYgKHRoYXQuaGFzT3duUHJvcGVydHkoa2V5KSAmJiB0eXBlb2YgdGhhdFtrZXldICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICAgICAgb2JqW2tleV0gPSB0aGF0W2tleV07XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG9iajtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDb252ZXJ0IG1vZGVsIGluc3RhbmNlIHRvIEpTT04gc3RyaW5nXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBKU09OIHJlcHJlc2VudGF0aW9uXG4gICAgICovXG4gICAgdG9KU09OKCkge1xuICAgICAgICBjb25zdCB0aGF0ID0gdGhpcztcbiAgICAgICAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KHRoYXQudG9PYmplY3QoKSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmVjdXJzaXZlbHkgaW5zdGFudGlhdGUgT1JNIG1vZGVscyBpbiByZXNwb25zZSBkYXRhXG4gICAgICpcbiAgICAgKiBMb29rcyBmb3Igb2JqZWN0cyB3aXRoIF9fTU9ERUwgcHJvcGVydHkgYW5kIGluc3RhbnRpYXRlcyB0aGUgYXBwcm9wcmlhdGVcbiAgICAgKiBKYXZhU2NyaXB0IG1vZGVsIGNsYXNzIGlmIGl0IGV4aXN0cyBpbiB0aGUgZ2xvYmFsIHNjb3BlLlxuICAgICAqXG4gICAgICogQHBhcmFtIHsqfSBkYXRhIC0gVGhlIGRhdGEgdG8gcHJvY2VzcyAoY2FuIGJlIGFueSB0eXBlKVxuICAgICAqIEByZXR1cm5zIHsqfSBUaGUgZGF0YSB3aXRoIE9STSBvYmplY3RzIGluc3RhbnRpYXRlZFxuICAgICAqL1xuICAgIHN0YXRpYyBfaW5zdGFudGlhdGVfbW9kZWxzX3JlY3Vyc2l2ZShkYXRhKSB7XG4gICAgICAgIC8vIF9fTU9ERUwgU1lTVEVNOiBFbmFibGVzIGF1dG9tYXRpYyBPUk0gaW5zdGFudGlhdGlvbiB3aGVuIGZldGNoaW5nIGZyb20gUEhQIG1vZGVscy5cbiAgICAgICAgLy8gUEhQIG1vZGVscyBhZGQgXCJfX01PREVMXCI6IFwiQ2xhc3NOYW1lXCIgdG8gSlNPTiwgSmF2YVNjcmlwdCB1c2VzIGl0IHRvIGNyZWF0ZSBwcm9wZXIgaW5zdGFuY2VzLlxuICAgICAgICAvLyBUaGlzIHByb3ZpZGVzIHR5cGVkIG1vZGVsIG9iamVjdHMgaW5zdGVhZCBvZiBwbGFpbiBKU09OLCB3aXRoIG1ldGhvZHMgYW5kIHR5cGUgY2hlY2tpbmcuXG5cbiAgICAgICAgLy8gVGhpcyByZWN1cnNpdmUgcHJvY2Vzc29yIHNjYW5zIGFsbCBBUEkgcmVzcG9uc2UgZGF0YSBsb29raW5nIGZvciBfX01PREVMIG1hcmtlcnMuXG4gICAgICAgIC8vIFdoZW4gZm91bmQsIGl0IGF0dGVtcHRzIHRvIGluc3RhbnRpYXRlIHRoZSBhcHByb3ByaWF0ZSBKYXZhU2NyaXB0IG1vZGVsIGNsYXNzLFxuICAgICAgICAvLyBjb252ZXJ0aW5nIHtfX01PREVMOiBcIlVzZXJfTW9kZWxcIiwgaWQ6IDEsIG5hbWU6IFwiSm9oblwifSBpbnRvIG5ldyBVc2VyX01vZGVsKHsuLi59KS5cbiAgICAgICAgLy8gV29ya3MgcmVjdXJzaXZlbHkgdGhyb3VnaCBhcnJheXMgYW5kIG5lc3RlZCBvYmplY3RzIHRvIGhhbmRsZSBjb21wbGV4IGRhdGEgc3RydWN0dXJlcy5cbiAgICAgICAgLy8gSGFuZGxlIG51bGwvdW5kZWZpbmVkXG4gICAgICAgIGlmIChkYXRhID09PSBudWxsIHx8IGRhdGEgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcmV0dXJuIGRhdGE7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBIYW5kbGUgYXJyYXlzIC0gcmVjdXJzaXZlbHkgcHJvY2VzcyBlYWNoIGVsZW1lbnRcbiAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkoZGF0YSkpIHtcbiAgICAgICAgICAgIHJldHVybiBkYXRhLm1hcCgoaXRlbSkgPT4gUnN4X0pzX01vZGVsLl9pbnN0YW50aWF0ZV9tb2RlbHNfcmVjdXJzaXZlKGl0ZW0pKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIEhhbmRsZSBvYmplY3RzXG4gICAgICAgIGlmICh0eXBlb2YgZGF0YSA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgICAgIC8vIENoZWNrIGlmIHRoaXMgb2JqZWN0IGhhcyBhIF9fTU9ERUwgcHJvcGVydHlcbiAgICAgICAgICAgIGlmIChkYXRhLl9fTU9ERUwgJiYgdHlwZW9mIGRhdGEuX19NT0RFTCA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgICAgICAvLyBUcnkgdG8gZmluZCB0aGUgbW9kZWwgY2xhc3MgaW4gdGhlIGdsb2JhbCBzY29wZVxuICAgICAgICAgICAgICAgIGNvbnN0IE1vZGVsQ2xhc3MgPSB3aW5kb3dbZGF0YS5fX01PREVMXTtcblxuICAgICAgICAgICAgICAgIC8vIElmIHRoZSBtb2RlbCBjbGFzcyBleGlzdHMgYW5kIGV4dGVuZHMgUnN4X0pzX01vZGVsLCBpbnN0YW50aWF0ZSBpdFxuICAgICAgICAgICAgICAgIC8vIER5bmFtaWMgbW9kZWwgcmVzb2x1dGlvbiByZXF1aXJlcyBjaGVja2luZyBjbGFzcyBleGlzdGVuY2UgLSBASlMtREVGRU5TSVZFLTAxLUVYQ0VQVElPTlxuICAgICAgICAgICAgICAgIGlmIChNb2RlbENsYXNzICYmIE1vZGVsQ2xhc3MucHJvdG90eXBlIGluc3RhbmNlb2YgUnN4X0pzX01vZGVsKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXcgTW9kZWxDbGFzcyhkYXRhKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIFJlY3Vyc2l2ZWx5IHByb2Nlc3MgYWxsIG9iamVjdCBwcm9wZXJ0aWVzXG4gICAgICAgICAgICBjb25zdCByZXN1bHQgPSB7fTtcbiAgICAgICAgICAgIGZvciAoY29uc3Qga2V5IGluIGRhdGEpIHtcbiAgICAgICAgICAgICAgICBpZiAoZGF0YS5oYXNPd25Qcm9wZXJ0eShrZXkpKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlc3VsdFtrZXldID0gUnN4X0pzX01vZGVsLl9pbnN0YW50aWF0ZV9tb2RlbHNfcmVjdXJzaXZlKGRhdGFba2V5XSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFJldHVybiBwcmltaXRpdmUgdmFsdWVzIGFzLWlzXG4gICAgICAgIHJldHVybiBkYXRhO1xuICAgIH1cbn1cbiIsIi8qKlxuICogVmlld19UcmFuc2l0aW9ucyAtIFNtb290aCBwYWdlLXRvLXBhZ2UgdHJhbnNpdGlvbnMgdXNpbmcgVmlldyBUcmFuc2l0aW9ucyBBUElcbiAqXG4gKiBFbmFibGVzIGNyb3NzLWRvY3VtZW50IHZpZXcgdHJhbnNpdGlvbnMgc28gdGhlIGJyb3dzZXIgZG9lc24ndCBwYWludCB0aGUgbmV3IHBhZ2VcbiAqIHVudGlsIGl0J3MgcmVhZHksIGNyZWF0aW5nIHNtb290aCBhbmltYXRpb25zIGJldHdlZW4gcGFnZXMuXG4gKlxuICogRmFsbHMgYmFjayBncmFjZWZ1bGx5IGlmIFZpZXcgVHJhbnNpdGlvbnMgQVBJIGlzIG5vdCBhdmFpbGFibGUuXG4gKi9cbmNsYXNzIFJzeF9WaWV3X1RyYW5zaXRpb25zIHtcbiAgICAvKipcbiAgICAgKiBDYWxsZWQgZHVyaW5nIGZyYW1ld29yayBjb3JlIGluaXQgcGhhc2VcbiAgICAgKiBDaGVja3MgZm9yIFZpZXcgVHJhbnNpdGlvbnMgQVBJIHN1cHBvcnQgYW5kIGVuYWJsZXMgaWYgYXZhaWxhYmxlXG4gICAgICovXG4gICAgc3RhdGljIF9vbl9mcmFtZXdvcmtfY29yZV9pbml0KCkge1xuICAgICAgICAvLyBDaGVjayBpZiBWaWV3IFRyYW5zaXRpb25zIEFQSSBpcyBzdXBwb3J0ZWRcbiAgICAgICAgaWYgKCFkb2N1bWVudC5zdGFydFZpZXdUcmFuc2l0aW9uKSB7XG4gICAgICAgICAgICBjb25zb2xlX2RlYnVnKCdWSUVXX1RSQU5TSVRJT05TJywgJ1ZpZXcgVHJhbnNpdGlvbnMgQVBJIG5vdCBzdXBwb3J0ZWQsIHNraXBwaW5nJyk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICAvLyBFbmFibGUgY3Jvc3MtZG9jdW1lbnQgdmlldyB0cmFuc2l0aW9ucyB2aWEgQ1NTXG4gICAgICAgIFJzeF9WaWV3X1RyYW5zaXRpb25zLl9pbmplY3RfdHJhbnNpdGlvbl9jc3MoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBJbmplY3QgQ1NTIHRvIGVuYWJsZSBjcm9zcy1kb2N1bWVudCB2aWV3IHRyYW5zaXRpb25zXG4gICAgICpcbiAgICAgKiBUaGUgQHZpZXctdHJhbnNpdGlvbiB7IG5hdmlnYXRpb246IGF1dG87IH0gcnVsZSB0ZWxscyB0aGUgYnJvd3NlciB0bzpcbiAgICAgKiAxLiBDYXB0dXJlIGEgc25hcHNob3Qgb2YgdGhlIGN1cnJlbnQgcGFnZSBiZWZvcmUgbmF2aWdhdGlvblxuICAgICAqIDIuIEZldGNoIHRoZSBuZXcgcGFnZVxuICAgICAqIDMuIFdhaXQgdW50aWwgdGhlIG5ldyBwYWdlIGlzIGZ1bGx5IGxvYWRlZCBhbmQgcGFpbnRlZCAoZG9jdW1lbnQucmVhZHkpXG4gICAgICogNC4gQW5pbWF0ZSBzbW9vdGhseSBiZXR3ZWVuIHRoZSB0d28gc3RhdGVzXG4gICAgICpcbiAgICAgKiBUaGlzIHByZXZlbnRzIHRoZSB3aGl0ZSBmbGFzaCBkdXJpbmcgbmF2aWdhdGlvbiBhbmQgY3JlYXRlcyBhcHAtbGlrZSB0cmFuc2l0aW9ucy5cbiAgICAgKi9cbiAgICBzdGF0aWMgX2luamVjdF90cmFuc2l0aW9uX2NzcygpIHtcbiAgICAgICAgY29uc3Qgc3R5bGUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzdHlsZScpO1xuXG4gICAgICAgIHN0eWxlLnRleHRDb250ZW50ID0gYFxuICAgICAgICAgICAgQHZpZXctdHJhbnNpdGlvbiB7XG4gICAgICAgICAgICAgICAgbmF2aWdhdGlvbjogYXV0bztcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLyogRGlzYWJsZSBhbmltYXRpb24gLSBpbnN0YW50IHRyYW5zaXRpb24gKi9cbiAgICAgICAgICAgIDo6dmlldy10cmFuc2l0aW9uLWdyb3VwKCopLFxuICAgICAgICAgICAgOjp2aWV3LXRyYW5zaXRpb24tb2xkKCopLFxuICAgICAgICAgICAgOjp2aWV3LXRyYW5zaXRpb24tbmV3KCopIHtcbiAgICAgICAgICAgICAgICBhbmltYXRpb24tZHVyYXRpb246IDBzO1xuICAgICAgICAgICAgfVxuICAgICAgICBgO1xuXG4gICAgICAgIGRvY3VtZW50LmhlYWQuYXBwZW5kQ2hpbGQoc3R5bGUpO1xuICAgIH1cbn1cbiIsIi8qKlxuICogUmVhZFdyaXRlTG9jayBpbXBsZW1lbnRhdGlvbiBmb3IgUlNwYWRlIGZyYW1ld29ya1xuICogUHJvdmlkZXMgZXhjbHVzaXZlICh3cml0ZSkgYW5kIHNoYXJlZCAocmVhZCkgbG9ja2luZyBtZWNoYW5pc21zIGZvciBhc3luY2hyb25vdXMgb3BlcmF0aW9uc1xuICovXG5jbGFzcyBSZWFkV3JpdGVMb2NrIHtcbiAgICBzdGF0aWMgI2xvY2tzID0gbmV3IE1hcCgpO1xuXG4gICAgLyoqXG4gICAgICogR2V0IG9yIGNyZWF0ZSBhIGxvY2sgb2JqZWN0IGZvciBhIGdpdmVuIG5hbWVcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuICAgIHN0YXRpYyAjZ2V0X2xvY2sobmFtZSkge1xuICAgICAgICBsZXQgcyA9IHRoaXMuI2xvY2tzLmdldChuYW1lKTtcbiAgICAgICAgaWYgKCFzKSB7XG4gICAgICAgICAgICBzID0geyByZWFkZXJzOiAwLCB3cml0ZXJfYWN0aXZlOiBmYWxzZSwgcmVhZGVyX3E6IFtdLCB3cml0ZXJfcTogW10gfTtcbiAgICAgICAgICAgIHRoaXMuI2xvY2tzLnNldChuYW1lLCBzKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTY2hlZHVsZSB0aGUgbmV4dCBvcGVyYXRpb24gZm9yIGEgbG9ja1xuICAgICAqIEBwcml2YXRlXG4gICAgICovXG4gICAgc3RhdGljICNzY2hlZHVsZShuYW1lKSB7XG4gICAgICAgIGNvbnN0IHMgPSB0aGlzLiNnZXRfbG9jayhuYW1lKTtcbiAgICAgICAgaWYgKHMud3JpdGVyX2FjdGl2ZSB8fCBzLnJlYWRlcnMgPiAwKSByZXR1cm47XG5cbiAgICAgICAgLy8gcnVuIG9uZSB3cml0ZXIgaWYgcXVldWVkXG4gICAgICAgIGlmIChzLndyaXRlcl9xLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIGNvbnN0IHsgY2IsIHJlc29sdmUsIHJlamVjdCB9ID0gcy53cml0ZXJfcS5zaGlmdCgpO1xuICAgICAgICAgICAgcy53cml0ZXJfYWN0aXZlID0gdHJ1ZTtcbiAgICAgICAgICAgIFByb21pc2UucmVzb2x2ZSgpXG4gICAgICAgICAgICAgICAgLnRoZW4oY2IpXG4gICAgICAgICAgICAgICAgLnRoZW4ocmVzb2x2ZSwgcmVqZWN0KVxuICAgICAgICAgICAgICAgIC5maW5hbGx5KCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgcy53cml0ZXJfYWN0aXZlID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuI3NjaGVkdWxlKG5hbWUpO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gb3RoZXJ3aXNlIHJ1biBhbGwgcXVldWVkIHJlYWRlcnMgaW4gcGFyYWxsZWxcbiAgICAgICAgaWYgKHMucmVhZGVyX3EubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgY29uc3QgYmF0Y2ggPSBzLnJlYWRlcl9xLnNwbGljZSgwKTtcbiAgICAgICAgICAgIHMucmVhZGVycyArPSBiYXRjaC5sZW5ndGg7XG4gICAgICAgICAgICBmb3IgKGNvbnN0IHsgY2IsIHJlc29sdmUsIHJlamVjdCB9IG9mIGJhdGNoKSB7XG4gICAgICAgICAgICAgICAgUHJvbWlzZS5yZXNvbHZlKClcbiAgICAgICAgICAgICAgICAgICAgLnRoZW4oY2IpXG4gICAgICAgICAgICAgICAgICAgIC50aGVuKHJlc29sdmUsIHJlamVjdClcbiAgICAgICAgICAgICAgICAgICAgLmZpbmFsbHkoKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgcy5yZWFkZXJzIC09IDE7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAocy5yZWFkZXJzID09PSAwKSB0aGlzLiNzY2hlZHVsZShuYW1lKTtcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBY3F1aXJlIGFuIGV4Y2x1c2l2ZSBtdXRleCBsb2NrIGJ5IG5hbWUuXG4gICAgICogT25seSBvbmUgd3JpdGVyIHJ1bnMgYXQgYSB0aW1lOyBibG9ja3MgcmVhZGVycyB1bnRpbCBmaW5pc2hlZC5cbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gbmFtZVxuICAgICAqIEBwYXJhbSB7KCkgPT4gYW55fFByb21pc2U8YW55Pn0gY2JcbiAgICAgKiBAcmV0dXJucyB7UHJvbWlzZTxhbnk+fVxuICAgICAqL1xuICAgIHN0YXRpYyBhY3F1aXJlKG5hbWUsIGNiKSB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICBjb25zdCBzID0gdGhpcy4jZ2V0X2xvY2sobmFtZSk7XG4gICAgICAgICAgICBzLndyaXRlcl9xLnB1c2goeyBjYiwgcmVzb2x2ZSwgcmVqZWN0IH0pO1xuICAgICAgICAgICAgdGhpcy4jc2NoZWR1bGUobmFtZSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEFjcXVpcmUgYSBzaGFyZWQgcmVhZCBsb2NrIGJ5IG5hbWUuXG4gICAgICogTXVsdGlwbGUgcmVhZGVycyBjYW4gcnVuIGluIHBhcmFsbGVsOyBibG9ja3Mgd2hlbiB3cml0ZXIgaXMgYWN0aXZlLlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lXG4gICAgICogQHBhcmFtIHsoKSA9PiBhbnl8UHJvbWlzZTxhbnk+fSBjYlxuICAgICAqIEByZXR1cm5zIHtQcm9taXNlPGFueT59XG4gICAgICovXG4gICAgc3RhdGljIGFjcXVpcmVfcmVhZChuYW1lLCBjYikge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgcyA9IHRoaXMuI2dldF9sb2NrKG5hbWUpO1xuICAgICAgICAgICAgaWYgKHMud3JpdGVyX2FjdGl2ZSB8fCBzLndyaXRlcl9xLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICBzLnJlYWRlcl9xLnB1c2goeyBjYiwgcmVzb2x2ZSwgcmVqZWN0IH0pO1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLiNzY2hlZHVsZShuYW1lKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHMucmVhZGVycyArPSAxO1xuICAgICAgICAgICAgUHJvbWlzZS5yZXNvbHZlKClcbiAgICAgICAgICAgICAgICAudGhlbihjYilcbiAgICAgICAgICAgICAgICAudGhlbihyZXNvbHZlLCByZWplY3QpXG4gICAgICAgICAgICAgICAgLmZpbmFsbHkoKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBzLnJlYWRlcnMgLT0gMTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHMucmVhZGVycyA9PT0gMCkgdGhpcy4jc2NoZWR1bGUobmFtZSk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEZvcmNlLXVubG9jayBhIG11dGV4ICh1c2Ugd2l0aCBjYXV0aW9uKS5cbiAgICAgKiBDb21wbGV0ZWx5IHJlbW92ZXMgdGhlIGxvY2sgc3RhdGUsIHBvdGVudGlhbGx5IGJyZWFraW5nIHdhaXRpbmcgb3BlcmF0aW9ucy5cbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gbmFtZVxuICAgICAqL1xuICAgIHN0YXRpYyBmb3JjZV91bmxvY2sobmFtZSkge1xuICAgICAgICB0aGlzLiNsb2Nrcy5kZWxldGUobmFtZSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0IGluZm9ybWF0aW9uIGFib3V0IHBlbmRpbmcgb3BlcmF0aW9ucyBvbiBhIG11dGV4LlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lXG4gICAgICogQHJldHVybnMge3tyZWFkZXJzOiBudW1iZXIsIHdyaXRlcl9hY3RpdmU6IGJvb2xlYW4sIHJlYWRlcl9xOiBudW1iZXIsIHdyaXRlcl9xOiBudW1iZXJ9fVxuICAgICAqL1xuICAgIHN0YXRpYyBwZW5kaW5nKG5hbWUpIHtcbiAgICAgICAgY29uc3QgcyA9IHRoaXMuI2xvY2tzLmdldChuYW1lKTtcbiAgICAgICAgaWYgKCFzKSByZXR1cm4geyByZWFkZXJzOiAwLCB3cml0ZXJfYWN0aXZlOiBmYWxzZSwgcmVhZGVyX3E6IDAsIHdyaXRlcl9xOiAwIH07XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICByZWFkZXJzOiBzLnJlYWRlcnMsXG4gICAgICAgICAgICB3cml0ZXJfYWN0aXZlOiBzLndyaXRlcl9hY3RpdmUsXG4gICAgICAgICAgICByZWFkZXJfcTogcy5yZWFkZXJfcS5sZW5ndGgsXG4gICAgICAgICAgICB3cml0ZXJfcTogcy53cml0ZXJfcS5sZW5ndGhcbiAgICAgICAgfTtcbiAgICB9XG59IiwiLyoqXG4gKiBGb3JtIHV0aWxpdGllcyBmb3IgdmFsaWRhdGlvbiBhbmQgZXJyb3IgaGFuZGxpbmdcbiAqL1xuY2xhc3MgRm9ybV9VdGlscyB7XG4gICAgLyoqXG4gICAgICogRnJhbWV3b3JrIGluaXRpYWxpemF0aW9uIGhvb2sgdG8gcmVnaXN0ZXIgalF1ZXJ5IHBsdWdpblxuICAgICAqIENyZWF0ZXMgJC5mbi5hamF4X3N1Ym1pdCgpIGZvciBmb3JtIGVsZW1lbnRzXG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cbiAgICBzdGF0aWMgX29uX2ZyYW1ld29ya19jb3JlX2RlZmluZShwYXJhbXMgPSB7fSkge1xuICAgICAgICAkLmZuLmFqYXhfc3VibWl0ID0gZnVuY3Rpb24ob3B0aW9ucyA9IHt9KSB7XG4gICAgICAgICAgICBjb25zdCAkZWxlbWVudCA9ICQodGhpcyk7XG5cbiAgICAgICAgICAgIGlmICghJGVsZW1lbnQuaXMoJ2Zvcm0nKSkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignYWpheF9zdWJtaXQoKSBjYW4gb25seSBiZSBjYWxsZWQgb24gZm9ybSBlbGVtZW50cycpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjb25zdCB1cmwgPSAkZWxlbWVudC5hdHRyKCdhY3Rpb24nKTtcbiAgICAgICAgICAgIGlmICghdXJsKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdGb3JtIG11c3QgaGF2ZSBhbiBhY3Rpb24gYXR0cmlidXRlJyk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbnN0IHsgY29udHJvbGxlciwgYWN0aW9uIH0gPSBBamF4LmFqYXhfdXJsX3RvX2NvbnRyb2xsZXJfYWN0aW9uKHVybCk7XG5cbiAgICAgICAgICAgIHJldHVybiBGb3JtX1V0aWxzLmFqYXhfc3VibWl0KCRlbGVtZW50LCBjb250cm9sbGVyLCBhY3Rpb24sIG9wdGlvbnMpO1xuICAgICAgICB9O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNob3dzIGZvcm0gdmFsaWRhdGlvbiBlcnJvcnNcbiAgICAgKlxuICAgICAqIFJFUVVJUkVEIEhUTUwgU1RSVUNUVVJFOlxuICAgICAqIEZvciBpbmxpbmUgZmllbGQgZXJyb3JzIHRvIGRpc3BsYXkgcHJvcGVybHksIGZvcm0gZmllbGRzIG11c3QgZm9sbG93IHRoaXMgc3RydWN0dXJlOlxuICAgICAqXG4gICAgICogPGRpdiBjbGFzcz1cImZvcm0tZ3JvdXBcIj5cbiAgICAgKiAgIDxsYWJlbCBjbGFzcz1cImZvcm0tbGFiZWxcIiBmb3I9XCJmaWVsZC1uYW1lXCI+RmllbGQgTGFiZWw8L2xhYmVsPlxuICAgICAqICAgPGlucHV0IGNsYXNzPVwiZm9ybS1jb250cm9sXCIgaWQ9XCJmaWVsZC1uYW1lXCIgbmFtZT1cImZpZWxkLW5hbWVcIiB0eXBlPVwidGV4dFwiPlxuICAgICAqIDwvZGl2PlxuICAgICAqXG4gICAgICogS2V5IHJlcXVpcmVtZW50czpcbiAgICAgKiAtIFdyYXAgZWFjaCBmaWVsZCBpbiBhIGNvbnRhaW5lciB3aXRoIGNsYXNzIFwiZm9ybS1ncm91cFwiIChvciBcImZvcm0tY2hlY2tcIiAvIFwiaW5wdXQtZ3JvdXBcIilcbiAgICAgKiAtIElucHV0IG11c3QgaGF2ZSBhIFwibmFtZVwiIGF0dHJpYnV0ZSBtYXRjaGluZyB0aGUgZXJyb3Iga2V5XG4gICAgICogLSBVc2UgXCJmb3JtLWNvbnRyb2xcIiBjbGFzcyBvbiBpbnB1dHMgZm9yIEJvb3RzdHJhcCA1IHN0eWxpbmdcbiAgICAgKlxuICAgICAqIEFjY2VwdHMgdGhyZWUgZm9ybWF0czpcbiAgICAgKiAtIFN0cmluZzogU2luZ2xlIGVycm9yIHNob3duIGFzIGFsZXJ0XG4gICAgICogLSBBcnJheSBvZiBzdHJpbmdzOiBNdWx0aXBsZSBlcnJvcnMgc2hvd24gYXMgYnVsbGV0ZWQgYWxlcnRcbiAgICAgKiAtIE9iamVjdDogRmllbGQgbmFtZXMgbWFwcGVkIHRvIGVycm9ycywgc2hvd24gaW5saW5lICh1bm1hdGNoZWQgc2hvd24gYXMgYWxlcnQpXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gcGFyZW50X3NlbGVjdG9yIC0galF1ZXJ5IHNlbGVjdG9yIGZvciBwYXJlbnQgZWxlbWVudFxuICAgICAqIEBwYXJhbSB7c3RyaW5nfE9iamVjdHxBcnJheX0gZXJyb3JzIC0gRXJyb3IgbWVzc2FnZXMgdG8gZGlzcGxheVxuICAgICAqIEByZXR1cm5zIHtQcm9taXNlfSBQcm9taXNlIHRoYXQgcmVzb2x2ZXMgd2hlbiBhbGwgYW5pbWF0aW9ucyBjb21wbGV0ZVxuICAgICAqL1xuICAgIHN0YXRpYyBhcHBseV9mb3JtX2Vycm9ycyhwYXJlbnRfc2VsZWN0b3IsIGVycm9ycykge1xuICAgICAgICBjb25zb2xlLmVycm9yKGVycm9ycyk7XG5cbiAgICAgICAgY29uc3QgJHBhcmVudCA9ICQocGFyZW50X3NlbGVjdG9yKTtcblxuICAgICAgICAvLyBSZXNldCB0aGUgZm9ybSBlcnJvcnMgYmVmb3JlIGFwcGx5aW5nIG5ldyBvbmVzXG4gICAgICAgIEZvcm1fVXRpbHMucmVzZXRfZm9ybV9lcnJvcnMocGFyZW50X3NlbGVjdG9yKTtcblxuICAgICAgICAvLyBOb3JtYWxpemUgaW5wdXQgdG8gc3RhbmRhcmQgZm9ybWF0XG4gICAgICAgIGNvbnN0IG5vcm1hbGl6ZWQgPSBGb3JtX1V0aWxzLl9ub3JtYWxpemVfZXJyb3JzKGVycm9ycyk7XG5cbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PiB7XG4gICAgICAgICAgICBsZXQgYW5pbWF0aW9ucyA9IFtdO1xuXG4gICAgICAgICAgICBpZiAobm9ybWFsaXplZC50eXBlID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgICAgIC8vIFNpbmdsZSBlcnJvciBtZXNzYWdlXG4gICAgICAgICAgICAgICAgYW5pbWF0aW9ucyA9IEZvcm1fVXRpbHMuX2FwcGx5X2dlbmVyYWxfZXJyb3JzKCRwYXJlbnQsIG5vcm1hbGl6ZWQuZGF0YSk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKG5vcm1hbGl6ZWQudHlwZSA9PT0gJ2FycmF5Jykge1xuICAgICAgICAgICAgICAgIC8vIEFycmF5IG9mIGVycm9yIG1lc3NhZ2VzXG4gICAgICAgICAgICAgICAgY29uc3QgZGVkdXBsaWNhdGVkID0gRm9ybV9VdGlscy5fZGVkdXBsaWNhdGVfZXJyb3JzKG5vcm1hbGl6ZWQuZGF0YSk7XG4gICAgICAgICAgICAgICAgYW5pbWF0aW9ucyA9IEZvcm1fVXRpbHMuX2FwcGx5X2dlbmVyYWxfZXJyb3JzKCRwYXJlbnQsIGRlZHVwbGljYXRlZCk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKG5vcm1hbGl6ZWQudHlwZSA9PT0gJ2ZpZWxkcycpIHtcbiAgICAgICAgICAgICAgICAvLyBGaWVsZC1zcGVjaWZpYyBlcnJvcnNcbiAgICAgICAgICAgICAgICBjb25zdCByZXN1bHQgPSBGb3JtX1V0aWxzLl9hcHBseV9maWVsZF9lcnJvcnMoJHBhcmVudCwgbm9ybWFsaXplZC5kYXRhKTtcbiAgICAgICAgICAgICAgICBhbmltYXRpb25zID0gcmVzdWx0LmFuaW1hdGlvbnM7XG5cbiAgICAgICAgICAgICAgICAvLyBDb3VudCBtYXRjaGVkIGZpZWxkc1xuICAgICAgICAgICAgICAgIGNvbnN0IG1hdGNoZWRfY291bnQgPSBPYmplY3Qua2V5cyhub3JtYWxpemVkLmRhdGEpLmxlbmd0aCAtIE9iamVjdC5rZXlzKHJlc3VsdC51bm1hdGNoZWQpLmxlbmd0aDtcbiAgICAgICAgICAgICAgICBjb25zdCB1bm1hdGNoZWRfZGVkdXBsaWNhdGVkID0gRm9ybV9VdGlscy5fZGVkdXBsaWNhdGVfZXJyb3JzKHJlc3VsdC51bm1hdGNoZWQpO1xuICAgICAgICAgICAgICAgIGNvbnN0IHVubWF0Y2hlZF9jb3VudCA9IE9iamVjdC5rZXlzKHVubWF0Y2hlZF9kZWR1cGxpY2F0ZWQpLmxlbmd0aDtcblxuICAgICAgICAgICAgICAgIC8vIFNob3cgc3VtbWFyeSBhbGVydCBpZiB0aGVyZSBhcmUgYW55IGZpZWxkIGVycm9ycyAobWF0Y2hlZCBvciB1bm1hdGNoZWQpXG4gICAgICAgICAgICAgICAgaWYgKG1hdGNoZWRfY291bnQgPiAwIHx8IHVubWF0Y2hlZF9jb3VudCA+IDApIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gQnVpbGQgc3VtbWFyeSBtZXNzYWdlXG4gICAgICAgICAgICAgICAgICAgIGxldCBzdW1tYXJ5X21zZyA9ICcnO1xuICAgICAgICAgICAgICAgICAgICBpZiAobWF0Y2hlZF9jb3VudCA+IDApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHN1bW1hcnlfbXNnID0gbWF0Y2hlZF9jb3VudCA9PT0gMVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gJ1BsZWFzZSBjb3JyZWN0IHRoZSBlcnJvciBoaWdobGlnaHRlZCBiZWxvdy4nXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgOiAnUGxlYXNlIGNvcnJlY3QgdGhlIGVycm9ycyBoaWdobGlnaHRlZCBiZWxvdy4nO1xuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgLy8gSWYgdGhlcmUgYXJlIHVubWF0Y2hlZCBlcnJvcnMsIGFkZCB0aGVtIGFzIGEgYnVsbGV0ZWQgbGlzdFxuICAgICAgICAgICAgICAgICAgICBpZiAodW5tYXRjaGVkX2NvdW50ID4gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3VtbWFyeV9hbmltYXRpb25zID0gRm9ybV9VdGlscy5fYXBwbHlfY29tYmluZWRfZXJyb3IoJHBhcmVudCwgc3VtbWFyeV9tc2csIHVubWF0Y2hlZF9kZWR1cGxpY2F0ZWQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgYW5pbWF0aW9ucy5wdXNoKC4uLnN1bW1hcnlfYW5pbWF0aW9ucyk7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBKdXN0IHRoZSBzdW1tYXJ5IG1lc3NhZ2UsIG5vIHVubWF0Y2hlZCBlcnJvcnNcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN1bW1hcnlfYW5pbWF0aW9ucyA9IEZvcm1fVXRpbHMuX2FwcGx5X2dlbmVyYWxfZXJyb3JzKCRwYXJlbnQsIHN1bW1hcnlfbXNnKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGFuaW1hdGlvbnMucHVzaCguLi5zdW1tYXJ5X2FuaW1hdGlvbnMpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBSZXNvbHZlIHRoZSBwcm9taXNlIG9uY2UgYWxsIGFuaW1hdGlvbnMgYXJlIGNvbXBsZXRlXG4gICAgICAgICAgICBQcm9taXNlLmFsbChhbmltYXRpb25zKS50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgICAvLyBTY3JvbGwgdG8gZXJyb3IgY29udGFpbmVyIGlmIGl0IGV4aXN0c1xuICAgICAgICAgICAgICAgIGNvbnN0ICRlcnJvcl9jb250YWluZXIgPSAkcGFyZW50LmZpbmQoJ1tkYXRhLWlkPVwiZXJyb3JfY29udGFpbmVyXCJdJykuZmlyc3QoKTtcbiAgICAgICAgICAgICAgICBpZiAoJGVycm9yX2NvbnRhaW5lci5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGNvbnRhaW5lcl90b3AgPSAkZXJyb3JfY29udGFpbmVyLm9mZnNldCgpLnRvcDtcblxuICAgICAgICAgICAgICAgICAgICAvLyBDYWxjdWxhdGUgZml4ZWQgaGVhZGVyIG9mZnNldFxuICAgICAgICAgICAgICAgICAgICBjb25zdCBmaXhlZF9oZWFkZXJfaGVpZ2h0ID0gRm9ybV9VdGlscy5fZ2V0X2ZpeGVkX2hlYWRlcl9oZWlnaHQoKTtcblxuICAgICAgICAgICAgICAgICAgICAvLyBTY3JvbGwgdG8gcG9zaXRpb24gZXJyb3IgY29udGFpbmVyIDIwcHggYmVsb3cgYW55IGZpeGVkIGhlYWRlcnNcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgdGFyZ2V0X3Njcm9sbCA9IGNvbnRhaW5lcl90b3AgLSBmaXhlZF9oZWFkZXJfaGVpZ2h0IC0gMjA7XG4gICAgICAgICAgICAgICAgICAgICQoJ2h0bWwsIGJvZHknKS5hbmltYXRlKHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHNjcm9sbFRvcDogdGFyZ2V0X3Njcm9sbFxuICAgICAgICAgICAgICAgICAgICB9LCA1MDApO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDbGVhcnMgZm9ybSB2YWxpZGF0aW9uIGVycm9ycyBhbmQgcmVzZXRzIGFsbCBmb3JtIHZhbHVlcyB0byBkZWZhdWx0c1xuICAgICAqIEBwYXJhbSB7c3RyaW5nfGpRdWVyeX0gZm9ybV9zZWxlY3RvciAtIGpRdWVyeSBzZWxlY3RvciBvciBqUXVlcnkgb2JqZWN0IGZvciBmb3JtIGVsZW1lbnRcbiAgICAgKi9cbiAgICBzdGF0aWMgcmVzZXQoZm9ybV9zZWxlY3Rvcikge1xuICAgICAgICBjb25zdCAkZm9ybSA9IHR5cGVvZiBmb3JtX3NlbGVjdG9yID09PSAnc3RyaW5nJyA/ICQoZm9ybV9zZWxlY3RvcikgOiBmb3JtX3NlbGVjdG9yO1xuXG4gICAgICAgIEZvcm1fVXRpbHMucmVzZXRfZm9ybV9lcnJvcnMoZm9ybV9zZWxlY3Rvcik7XG4gICAgICAgICRmb3JtLnRyaWdnZXIoJ3Jlc2V0Jyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2VyaWFsaXplcyBmb3JtIGRhdGEgaW50byBrZXktdmFsdWUgb2JqZWN0XG4gICAgICogUmV0dXJucyBhbGwgaW5wdXQgZWxlbWVudHMgd2l0aCBuYW1lIGF0dHJpYnV0ZXMgYXMgb2JqZWN0IHByb3BlcnRpZXNcbiAgICAgKiBAcGFyYW0ge3N0cmluZ3xqUXVlcnl9IGZvcm1fc2VsZWN0b3IgLSBqUXVlcnkgc2VsZWN0b3Igb3IgalF1ZXJ5IG9iamVjdCBmb3IgZm9ybSBlbGVtZW50XG4gICAgICogQHJldHVybnMge09iamVjdH0gRm9ybSBkYXRhIGFzIGtleS12YWx1ZSBwYWlyc1xuICAgICAqL1xuICAgIHN0YXRpYyBzZXJpYWxpemUoZm9ybV9zZWxlY3Rvcikge1xuICAgICAgICBjb25zdCAkZm9ybSA9IHR5cGVvZiBmb3JtX3NlbGVjdG9yID09PSAnc3RyaW5nJyA/ICQoZm9ybV9zZWxlY3RvcikgOiBmb3JtX3NlbGVjdG9yO1xuICAgICAgICBjb25zdCBkYXRhID0ge307XG5cbiAgICAgICAgJGZvcm0uc2VyaWFsaXplQXJyYXkoKS5mb3JFYWNoKChpdGVtKSA9PiB7XG4gICAgICAgICAgICBkYXRhW2l0ZW0ubmFtZV0gPSBpdGVtLnZhbHVlO1xuICAgICAgICB9KTtcblxuICAgICAgICByZXR1cm4gZGF0YTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTdWJtaXRzIGZvcm0gdG8gUlNYIGNvbnRyb2xsZXIgYWN0aW9uIHZpYSBBSkFYXG4gICAgICogQHBhcmFtIHtzdHJpbmd8alF1ZXJ5fSBmb3JtX3NlbGVjdG9yIC0galF1ZXJ5IHNlbGVjdG9yIG9yIGpRdWVyeSBvYmplY3QgZm9yIGZvcm0gZWxlbWVudFxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBjb250cm9sbGVyIC0gQ29udHJvbGxlciBjbGFzcyBuYW1lIChlLmcuLCAnVXNlcl9Db250cm9sbGVyJylcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gYWN0aW9uIC0gQWN0aW9uIG1ldGhvZCBuYW1lIChlLmcuLCAnc2F2ZV9wcm9maWxlJylcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb3B0aW9ucyAtIE9wdGlvbmFsIGNvbmZpZ3VyYXRpb24ge29uX3N1Y2Nlc3M6IGZuLCBvbl9lcnJvcjogZm59XG4gICAgICogQHJldHVybnMge1Byb21pc2V9IFByb21pc2UgdGhhdCByZXNvbHZlcyB3aXRoIHJlc3BvbnNlIGRhdGFcbiAgICAgKi9cbiAgICBzdGF0aWMgYXN5bmMgYWpheF9zdWJtaXQoZm9ybV9zZWxlY3RvciwgY29udHJvbGxlciwgYWN0aW9uLCBvcHRpb25zID0ge30pIHtcbiAgICAgICAgY29uc3QgJGZvcm0gPSB0eXBlb2YgZm9ybV9zZWxlY3RvciA9PT0gJ3N0cmluZycgPyAkKGZvcm1fc2VsZWN0b3IpIDogZm9ybV9zZWxlY3RvcjtcbiAgICAgICAgY29uc3QgZm9ybV9kYXRhID0gRm9ybV9VdGlscy5zZXJpYWxpemUoJGZvcm0pO1xuXG4gICAgICAgIEZvcm1fVXRpbHMucmVzZXRfZm9ybV9lcnJvcnMoZm9ybV9zZWxlY3Rvcik7XG5cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgQWpheC5jYWxsKGNvbnRyb2xsZXIsIGFjdGlvbiwgZm9ybV9kYXRhKTtcblxuICAgICAgICAgICAgaWYgKG9wdGlvbnMub25fc3VjY2Vzcykge1xuICAgICAgICAgICAgICAgIG9wdGlvbnMub25fc3VjY2VzcyhyZXNwb25zZSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiByZXNwb25zZTtcbiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgIGlmIChlcnJvci50eXBlID09PSAnZm9ybV9lcnJvcicgJiYgZXJyb3IuZGV0YWlscykge1xuICAgICAgICAgICAgICAgIGF3YWl0IEZvcm1fVXRpbHMuYXBwbHlfZm9ybV9lcnJvcnMoZm9ybV9zZWxlY3RvciwgZXJyb3IuZGV0YWlscyk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGF3YWl0IEZvcm1fVXRpbHMuYXBwbHlfZm9ybV9lcnJvcnMoZm9ybV9zZWxlY3RvciwgZXJyb3IubWVzc2FnZSB8fCAnQW4gZXJyb3Igb2NjdXJyZWQnKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKG9wdGlvbnMub25fZXJyb3IpIHtcbiAgICAgICAgICAgICAgICBvcHRpb25zLm9uX2Vycm9yKGVycm9yKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZW1vdmVzIGZvcm0gdmFsaWRhdGlvbiBlcnJvcnNcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gcGFyZW50X3NlbGVjdG9yIC0galF1ZXJ5IHNlbGVjdG9yIGZvciBwYXJlbnQgZWxlbWVudFxuICAgICAqL1xuICAgIHN0YXRpYyByZXNldF9mb3JtX2Vycm9ycyhwYXJlbnRfc2VsZWN0b3IpIHtcbiAgICAgICAgY29uc3QgJHBhcmVudCA9ICQocGFyZW50X3NlbGVjdG9yKTtcblxuICAgICAgICAvLyBSZW1vdmUgZmxhc2ggbWVzc2FnZXNcbiAgICAgICAgJCgnLmZsYXNoLW1lc3NhZ2VzJykucmVtb3ZlKCk7XG5cbiAgICAgICAgLy8gUmVtb3ZlIGFsZXJ0LWRhbmdlciBtZXNzYWdlc1xuICAgICAgICAkcGFyZW50LmZpbmQoJy5hbGVydC1kYW5nZXInKS5yZW1vdmUoKTtcblxuICAgICAgICAvLyBSZW1vdmUgdmFsaWRhdGlvbiBlcnJvciBjbGFzc2VzIGFuZCB0ZXh0IGZyb20gZm9ybSBlbGVtZW50c1xuICAgICAgICAkcGFyZW50LmZpbmQoJy5pcy1pbnZhbGlkJykucmVtb3ZlQ2xhc3MoJ2lzLWludmFsaWQnKTtcbiAgICAgICAgJHBhcmVudC5maW5kKCcuaW52YWxpZC1mZWVkYmFjaycpLnJlbW92ZSgpO1xuICAgIH1cblxuICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG4gICAgLyoqXG4gICAgICogTm9ybWFsaXplcyBlcnJvciBpbnB1dCBpbnRvIHN0YW5kYXJkIGZvcm1hdHNcbiAgICAgKiBAcGFyYW0ge3N0cmluZ3xPYmplY3R8QXJyYXl9IGVycm9ycyAtIFJhdyBlcnJvciBpbnB1dFxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IE5vcm1hbGl6ZWQgZXJyb3JzIGFzIHt0eXBlOiAnc3RyaW5nJ3wnYXJyYXknfCdmaWVsZHMnLCBkYXRhOiAuLi59XG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cbiAgICBzdGF0aWMgX25vcm1hbGl6ZV9lcnJvcnMoZXJyb3JzKSB7XG4gICAgICAgIC8vIEhhbmRsZSBudWxsL3VuZGVmaW5lZFxuICAgICAgICBpZiAoIWVycm9ycykge1xuICAgICAgICAgICAgcmV0dXJuIHsgdHlwZTogJ3N0cmluZycsIGRhdGE6ICdBbiBlcnJvciBoYXMgb2NjdXJyZWQnIH07XG4gICAgICAgIH1cblxuICAgICAgICAvLyBIYW5kbGUgc3RyaW5nXG4gICAgICAgIGlmICh0eXBlb2YgZXJyb3JzID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgcmV0dXJuIHsgdHlwZTogJ3N0cmluZycsIGRhdGE6IGVycm9ycyB9O1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gSGFuZGxlIGFycmF5XG4gICAgICAgIGlmIChBcnJheS5pc0FycmF5KGVycm9ycykpIHtcbiAgICAgICAgICAgIC8vIEFycmF5IG9mIHN0cmluZ3MgLSBnZW5lcmFsIGVycm9yc1xuICAgICAgICAgICAgaWYgKGVycm9ycy5ldmVyeSgoZSkgPT4gdHlwZW9mIGUgPT09ICdzdHJpbmcnKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiB7IHR5cGU6ICdhcnJheScsIGRhdGE6IGVycm9ycyB9O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gQXJyYXkgd2l0aCBvYmplY3QgYXMgZmlyc3QgZWxlbWVudCAtIGV4dHJhY3QgaXRcbiAgICAgICAgICAgIGlmIChlcnJvcnMubGVuZ3RoID4gMCAmJiB0eXBlb2YgZXJyb3JzWzBdID09PSAnb2JqZWN0Jykge1xuICAgICAgICAgICAgICAgIHJldHVybiBGb3JtX1V0aWxzLl9ub3JtYWxpemVfZXJyb3JzKGVycm9yc1swXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBFbXB0eSBvciBtaXhlZCBhcnJheVxuICAgICAgICAgICAgcmV0dXJuIHsgdHlwZTogJ2FycmF5JywgZGF0YTogW10gfTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIEhhbmRsZSBvYmplY3QgLSBjaGVjayBmb3IgTGFyYXZlbCByZXNwb25zZSB3cmFwcGVyXG4gICAgICAgIGlmICh0eXBlb2YgZXJyb3JzID09PSAnb2JqZWN0Jykge1xuICAgICAgICAgICAgLy8gVW53cmFwIHtlcnJvcnM6IHsuLi59fSBvciB7ZXJyb3I6IHsuLi59fVxuICAgICAgICAgICAgY29uc3QgdW53cmFwcGVkID0gZXJyb3JzLmVycm9ycyB8fCBlcnJvcnMuZXJyb3I7XG4gICAgICAgICAgICBpZiAodW53cmFwcGVkKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIEZvcm1fVXRpbHMuX25vcm1hbGl6ZV9lcnJvcnModW53cmFwcGVkKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gQ29udmVydCBMYXJhdmVsIHZhbGlkYXRvciBmb3JtYXQge2ZpZWxkOiBbbXNnMSwgbXNnMl19IHRvIHtmaWVsZDogbXNnMX1cbiAgICAgICAgICAgIGNvbnN0IG5vcm1hbGl6ZWQgPSB7fTtcbiAgICAgICAgICAgIGZvciAoY29uc3QgZmllbGQgaW4gZXJyb3JzKSB7XG4gICAgICAgICAgICAgICAgaWYgKGVycm9ycy5oYXNPd25Qcm9wZXJ0eShmaWVsZCkpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgdmFsdWUgPSBlcnJvcnNbZmllbGRdO1xuICAgICAgICAgICAgICAgICAgICBpZiAoQXJyYXkuaXNBcnJheSh2YWx1ZSkgJiYgdmFsdWUubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgbm9ybWFsaXplZFtmaWVsZF0gPSB2YWx1ZVswXTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmICh0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBub3JtYWxpemVkW2ZpZWxkXSA9IHZhbHVlO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgbm9ybWFsaXplZFtmaWVsZF0gPSBTdHJpbmcodmFsdWUpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4geyB0eXBlOiAnZmllbGRzJywgZGF0YTogbm9ybWFsaXplZCB9O1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gRmluYWwgY2F0Y2gtYWxsKlxuICAgICAgICByZXR1cm4geyB0eXBlOiAnc3RyaW5nJywgZGF0YTogU3RyaW5nKGVycm9ycykgfTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZW1vdmVzIGR1cGxpY2F0ZSBlcnJvciBtZXNzYWdlcyBmcm9tIGFycmF5IG9yIG9iamVjdCB2YWx1ZXNcbiAgICAgKiBAcGFyYW0ge0FycmF5fE9iamVjdH0gZXJyb3JzIC0gRXJyb3JzIHRvIGRlZHVwbGljYXRlXG4gICAgICogQHJldHVybnMge0FycmF5fE9iamVjdH0gRGVkdXBsaWNhdGVkIGVycm9yc1xuICAgICAqIEBwcml2YXRlXG4gICAgICovXG4gICAgc3RhdGljIF9kZWR1cGxpY2F0ZV9lcnJvcnMoZXJyb3JzKSB7XG4gICAgICAgIGlmIChBcnJheS5pc0FycmF5KGVycm9ycykpIHtcbiAgICAgICAgICAgIHJldHVybiBbLi4ubmV3IFNldChlcnJvcnMpXTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0eXBlb2YgZXJyb3JzID09PSAnb2JqZWN0Jykge1xuICAgICAgICAgICAgY29uc3Qgc2VlbiA9IG5ldyBTZXQoKTtcbiAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IHt9O1xuICAgICAgICAgICAgZm9yIChjb25zdCBrZXkgaW4gZXJyb3JzKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgdmFsdWUgPSBlcnJvcnNba2V5XTtcbiAgICAgICAgICAgICAgICBpZiAoIXNlZW4uaGFzKHZhbHVlKSkge1xuICAgICAgICAgICAgICAgICAgICBzZWVuLmFkZCh2YWx1ZSk7XG4gICAgICAgICAgICAgICAgICAgIHJlc3VsdFtrZXldID0gdmFsdWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBlcnJvcnM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQXBwbGllcyBmaWVsZC1zcGVjaWZpYyB2YWxpZGF0aW9uIGVycm9ycyB0byBmb3JtIGlucHV0c1xuICAgICAqIEBwYXJhbSB7alF1ZXJ5fSAkcGFyZW50IC0gUGFyZW50IGVsZW1lbnQgY29udGFpbmluZyBmb3JtXG4gICAgICogQHBhcmFtIHtPYmplY3R9IGZpZWxkX2Vycm9ycyAtIE9iamVjdCBtYXBwaW5nIGZpZWxkIG5hbWVzIHRvIGVycm9yIG1lc3NhZ2VzXG4gICAgICogQHJldHVybnMge09iamVjdH0gT2JqZWN0IGNvbnRhaW5pbmcge2FuaW1hdGlvbnM6IEFycmF5LCB1bm1hdGNoZWQ6IE9iamVjdH1cbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuICAgIHN0YXRpYyBfYXBwbHlfZmllbGRfZXJyb3JzKCRwYXJlbnQsIGZpZWxkX2Vycm9ycykge1xuICAgICAgICBjb25zdCBhbmltYXRpb25zID0gW107XG4gICAgICAgIGNvbnN0IHVubWF0Y2hlZCA9IHt9O1xuXG4gICAgICAgIGZvciAoY29uc3QgZmllbGRfbmFtZSBpbiBmaWVsZF9lcnJvcnMpIHtcbiAgICAgICAgICAgIGNvbnN0IGVycm9yX21lc3NhZ2UgPSBmaWVsZF9lcnJvcnNbZmllbGRfbmFtZV07XG4gICAgICAgICAgICBjb25zdCAkaW5wdXQgPSAkcGFyZW50LmZpbmQoYFtuYW1lPVwiJHtmaWVsZF9uYW1lfVwiXWApO1xuXG4gICAgICAgICAgICBpZiAoISRpbnB1dC5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICB1bm1hdGNoZWRbZmllbGRfbmFtZV0gPSBlcnJvcl9tZXNzYWdlO1xuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjb25zdCAkZXJyb3IgPSAkKCc8ZGl2IGNsYXNzPVwiaW52YWxpZC1mZWVkYmFja1wiPjwvZGl2PicpLmh0bWwoZXJyb3JfbWVzc2FnZSk7XG4gICAgICAgICAgICBjb25zdCAkdGFyZ2V0ID0gJGlucHV0LmNsb3Nlc3QoJy5mb3JtLWdyb3VwLCAuZm9ybS1jaGVjaywgLmlucHV0LWdyb3VwJyk7XG5cbiAgICAgICAgICAgIGlmICghJHRhcmdldC5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICB1bm1hdGNoZWRbZmllbGRfbmFtZV0gPSBlcnJvcl9tZXNzYWdlO1xuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAkaW5wdXQuYWRkQ2xhc3MoJ2lzLWludmFsaWQnKTtcbiAgICAgICAgICAgICRlcnJvci5hcHBlbmRUbygkdGFyZ2V0KTtcbiAgICAgICAgICAgIGFuaW1hdGlvbnMucHVzaCgkZXJyb3IuaGlkZSgpLmZhZGVJbigzMDApLnByb21pc2UoKSk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4geyBhbmltYXRpb25zLCB1bm1hdGNoZWQgfTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBcHBsaWVzIGNvbWJpbmVkIGVycm9yIG1lc3NhZ2Ugd2l0aCBzdW1tYXJ5IGFuZCB1bm1hdGNoZWQgZmllbGQgZXJyb3JzXG4gICAgICogQHBhcmFtIHtqUXVlcnl9ICRwYXJlbnQgLSBQYXJlbnQgZWxlbWVudCBjb250YWluaW5nIGZvcm1cbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gc3VtbWFyeV9tc2cgLSBTdW1tYXJ5IG1lc3NhZ2UgKGUuZy4sIFwiUGxlYXNlIGNvcnJlY3QgdGhlIGVycm9ycyBiZWxvd1wiKVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSB1bm1hdGNoZWRfZXJyb3JzIC0gT2JqZWN0IG9mIGZpZWxkIGVycm9ycyB0aGF0IGNvdWxkbid0IGJlIG1hdGNoZWQgdG8gZmllbGRzXG4gICAgICogQHJldHVybnMge0FycmF5fSBBcnJheSBvZiBhbmltYXRpb24gcHJvbWlzZXNcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuICAgIHN0YXRpYyBfYXBwbHlfY29tYmluZWRfZXJyb3IoJHBhcmVudCwgc3VtbWFyeV9tc2csIHVubWF0Y2hlZF9lcnJvcnMpIHtcbiAgICAgICAgY29uc3QgYW5pbWF0aW9ucyA9IFtdO1xuICAgICAgICBjb25zdCAkZXJyb3JfY29udGFpbmVyID0gJHBhcmVudC5maW5kKCdbZGF0YS1pZD1cImVycm9yX2NvbnRhaW5lclwiXScpLmZpcnN0KCk7XG4gICAgICAgIGNvbnN0ICR0YXJnZXQgPSAkZXJyb3JfY29udGFpbmVyLmxlbmd0aCA+IDAgPyAkZXJyb3JfY29udGFpbmVyIDogJHBhcmVudDtcblxuICAgICAgICAvLyBDcmVhdGUgYWxlcnQgd2l0aCBzdW1tYXJ5IG1lc3NhZ2UgYW5kIGJ1bGxldGVkIGxpc3Qgb2YgdW5tYXRjaGVkIGVycm9yc1xuICAgICAgICBjb25zdCAkYWxlcnQgPSAkKCc8ZGl2IGNsYXNzPVwiYWxlcnQgYWxlcnQtZGFuZ2VyXCIgcm9sZT1cImFsZXJ0XCI+PC9kaXY+Jyk7XG5cbiAgICAgICAgLy8gQWRkIHN1bW1hcnkgbWVzc2FnZSBpZiBwcm92aWRlZFxuICAgICAgICBpZiAoc3VtbWFyeV9tc2cpIHtcbiAgICAgICAgICAgICQoJzxwIGNsYXNzPVwibWItMlwiPjwvcD4nKS50ZXh0KHN1bW1hcnlfbXNnKS5hcHBlbmRUbygkYWxlcnQpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gQWRkIHVubWF0Y2hlZCBlcnJvcnMgYXMgYnVsbGV0ZWQgbGlzdFxuICAgICAgICBpZiAoT2JqZWN0LmtleXModW5tYXRjaGVkX2Vycm9ycykubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgY29uc3QgJGxpc3QgPSAkKCc8dWwgY2xhc3M9XCJtYi0wXCI+PC91bD4nKTtcbiAgICAgICAgICAgIGZvciAoY29uc3QgZmllbGRfbmFtZSBpbiB1bm1hdGNoZWRfZXJyb3JzKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgZXJyb3JfbXNnID0gdW5tYXRjaGVkX2Vycm9yc1tmaWVsZF9uYW1lXTtcbiAgICAgICAgICAgICAgICAkKCc8bGk+PC9saT4nKS5odG1sKGVycm9yX21zZykuYXBwZW5kVG8oJGxpc3QpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgJGxpc3QuYXBwZW5kVG8oJGFsZXJ0KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICgkZXJyb3JfY29udGFpbmVyLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIGFuaW1hdGlvbnMucHVzaCgkYWxlcnQuaGlkZSgpLmFwcGVuZFRvKCR0YXJnZXQpLmZhZGVJbigzMDApLnByb21pc2UoKSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBhbmltYXRpb25zLnB1c2goJGFsZXJ0LmhpZGUoKS5wcmVwZW5kVG8oJHRhcmdldCkuZmFkZUluKDMwMCkucHJvbWlzZSgpKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBhbmltYXRpb25zO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEFwcGxpZXMgZ2VuZXJhbCBlcnJvciBtZXNzYWdlcyBhcyBhbGVydCBib3hcbiAgICAgKiBAcGFyYW0ge2pRdWVyeX0gJHBhcmVudCAtIFBhcmVudCBlbGVtZW50IHRvIHByZXBlbmQgYWxlcnQgdG9cbiAgICAgKiBAcGFyYW0ge3N0cmluZ3xBcnJheX0gbWVzc2FnZXMgLSBFcnJvciBtZXNzYWdlKHMpIHRvIGRpc3BsYXlcbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IEFycmF5IG9mIGFuaW1hdGlvbiBwcm9taXNlc1xuICAgICAqIEBwcml2YXRlXG4gICAgICovXG4gICAgc3RhdGljIF9hcHBseV9nZW5lcmFsX2Vycm9ycygkcGFyZW50LCBtZXNzYWdlcykge1xuICAgICAgICBjb25zdCBhbmltYXRpb25zID0gW107XG5cbiAgICAgICAgLy8gTG9vayBmb3IgYSBzcGVjaWZpYyBlcnJvciBjb250YWluZXIgZGl2IChlLmcuLCBpbiBSc3hfRm9ybSBjb21wb25lbnQpXG4gICAgICAgIGNvbnN0ICRlcnJvcl9jb250YWluZXIgPSAkcGFyZW50LmZpbmQoJ1tkYXRhLWlkPVwiZXJyb3JfY29udGFpbmVyXCJdJykuZmlyc3QoKTtcbiAgICAgICAgY29uc3QgJHRhcmdldCA9ICRlcnJvcl9jb250YWluZXIubGVuZ3RoID4gMCA/ICRlcnJvcl9jb250YWluZXIgOiAkcGFyZW50O1xuXG4gICAgICAgIGlmICh0eXBlb2YgbWVzc2FnZXMgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICAvLyBTaW5nbGUgZXJyb3IgLSBzaW1wbGUgYWxlcnQgd2l0aG91dCBsaXN0XG4gICAgICAgICAgICBjb25zdCAkYWxlcnQgPSAkKCc8ZGl2IGNsYXNzPVwiYWxlcnQgYWxlcnQtZGFuZ2VyXCIgcm9sZT1cImFsZXJ0XCI+PC9kaXY+JykudGV4dChtZXNzYWdlcyk7XG4gICAgICAgICAgICBpZiAoJGVycm9yX2NvbnRhaW5lci5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgICAgYW5pbWF0aW9ucy5wdXNoKCRhbGVydC5oaWRlKCkuYXBwZW5kVG8oJHRhcmdldCkuZmFkZUluKDMwMCkucHJvbWlzZSgpKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgYW5pbWF0aW9ucy5wdXNoKCRhbGVydC5oaWRlKCkucHJlcGVuZFRvKCR0YXJnZXQpLmZhZGVJbigzMDApLnByb21pc2UoKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSBpZiAoQXJyYXkuaXNBcnJheShtZXNzYWdlcykgJiYgbWVzc2FnZXMubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgLy8gTXVsdGlwbGUgZXJyb3JzIC0gYnVsbGV0ZWQgbGlzdFxuICAgICAgICAgICAgY29uc3QgJGFsZXJ0ID0gJCgnPGRpdiBjbGFzcz1cImFsZXJ0IGFsZXJ0LWRhbmdlclwiIHJvbGU9XCJhbGVydFwiPjx1bCBjbGFzcz1cIm1iLTBcIj48L3VsPjwvZGl2PicpO1xuICAgICAgICAgICAgY29uc3QgJGxpc3QgPSAkYWxlcnQuZmluZCgndWwnKTtcblxuICAgICAgICAgICAgbWVzc2FnZXMuZm9yRWFjaCgobXNnKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgdGV4dCA9IChtc2cgKyAnJykudHJpbSgpIHx8ICdBbiBlcnJvciBoYXMgb2NjdXJyZWQnO1xuICAgICAgICAgICAgICAgICQoJzxsaT48L2xpPicpLmh0bWwodGV4dCkuYXBwZW5kVG8oJGxpc3QpO1xuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIGlmICgkZXJyb3JfY29udGFpbmVyLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICBhbmltYXRpb25zLnB1c2goJGFsZXJ0LmhpZGUoKS5hcHBlbmRUbygkdGFyZ2V0KS5mYWRlSW4oMzAwKS5wcm9taXNlKCkpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBhbmltYXRpb25zLnB1c2goJGFsZXJ0LmhpZGUoKS5wcmVwZW5kVG8oJHRhcmdldCkuZmFkZUluKDMwMCkucHJvbWlzZSgpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmICh0eXBlb2YgbWVzc2FnZXMgPT09ICdvYmplY3QnICYmICFBcnJheS5pc0FycmF5KG1lc3NhZ2VzKSkge1xuICAgICAgICAgICAgLy8gT2JqZWN0IG9mIHVubWF0Y2hlZCBmaWVsZCBlcnJvcnMgLSBjb252ZXJ0IHRvIGFycmF5XG4gICAgICAgICAgICBjb25zdCBlcnJvcl9saXN0ID0gT2JqZWN0LnZhbHVlcyhtZXNzYWdlcylcbiAgICAgICAgICAgICAgICAubWFwKCh2KSA9PiBTdHJpbmcodikudHJpbSgpKVxuICAgICAgICAgICAgICAgIC5maWx0ZXIoKHYpID0+IHYpO1xuICAgICAgICAgICAgaWYgKGVycm9yX2xpc3QubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBGb3JtX1V0aWxzLl9hcHBseV9nZW5lcmFsX2Vycm9ycygkcGFyZW50LCBlcnJvcl9saXN0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBhbmltYXRpb25zO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENhbGN1bGF0ZXMgdGhlIHRvdGFsIGhlaWdodCBvZiBmaXhlZC9zdGlja3kgaGVhZGVycyBhdCB0aGUgdG9wIG9mIHRoZSBwYWdlXG4gICAgICogQHJldHVybnMge251bWJlcn0gVG90YWwgaGVpZ2h0IGluIHBpeGVscyBvZiBmaXhlZCB0b3AgZWxlbWVudHNcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuICAgIHN0YXRpYyBfZ2V0X2ZpeGVkX2hlYWRlcl9oZWlnaHQoKSB7XG4gICAgICAgIGxldCB0b3RhbF9oZWlnaHQgPSAwO1xuXG4gICAgICAgIC8vIEZpbmQgYWxsIGZpeGVkIG9yIHN0aWNreSBwb3NpdGlvbmVkIGVsZW1lbnRzXG4gICAgICAgICQoJyonKS5lYWNoKGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgY29uc3QgJGVsID0gJCh0aGlzKTtcbiAgICAgICAgICAgIGNvbnN0IHBvc2l0aW9uID0gJGVsLmNzcygncG9zaXRpb24nKTtcblxuICAgICAgICAgICAgLy8gT25seSBjaGVjayBmaXhlZCBvciBzdGlja3kgZWxlbWVudHNcbiAgICAgICAgICAgIGlmIChwb3NpdGlvbiAhPT0gJ2ZpeGVkJyAmJiBwb3NpdGlvbiAhPT0gJ3N0aWNreScpIHtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIENoZWNrIGlmIGVsZW1lbnQgaXMgcG9zaXRpb25lZCBhdCBvciBuZWFyIHRoZSB0b3BcbiAgICAgICAgICAgIGNvbnN0IHRvcCA9IHBhcnNlSW50KCRlbC5jc3MoJ3RvcCcpKSB8fCAwO1xuICAgICAgICAgICAgaWYgKHRvcCA+IDUwKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuOyAvLyBOb3QgYSB0b3AgaGVhZGVyXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIENoZWNrIGlmIGVsZW1lbnQgaXMgdmlzaWJsZVxuICAgICAgICAgICAgaWYgKCEkZWwuaXMoJzp2aXNpYmxlJykpIHtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIENoZWNrIGlmIGVsZW1lbnQgc3BhbnMgc2lnbmlmaWNhbnQgd2lkdGggKGxpa2VseSBhIGhlYWRlci9uYXZiYXIpXG4gICAgICAgICAgICBjb25zdCB3aWR0aCA9ICRlbC5vdXRlcldpZHRoKCk7XG4gICAgICAgICAgICBjb25zdCB2aWV3cG9ydF93aWR0aCA9ICQod2luZG93KS53aWR0aCgpO1xuICAgICAgICAgICAgaWYgKHdpZHRoIDwgdmlld3BvcnRfd2lkdGggKiAwLjUpIHtcbiAgICAgICAgICAgICAgICByZXR1cm47IC8vIFRvbyBuYXJyb3cgdG8gYmUgYSBoZWFkZXJcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gQWRkIHRoaXMgZWxlbWVudCdzIGhlaWdodFxuICAgICAgICAgICAgdG90YWxfaGVpZ2h0ICs9ICRlbC5vdXRlckhlaWdodCgpO1xuICAgICAgICB9KTtcblxuICAgICAgICByZXR1cm4gdG90YWxfaGVpZ2h0O1xuICAgIH1cbn1cbiIsIi8qKlxuICogRGVidWdnZXIgY2xhc3MgZm9yIGNvbnNvbGVfZGVidWcgYW5kIGJyb3dzZXIgZXJyb3IgbG9nZ2luZ1xuICogSGFuZGxlcyBiYXRjaGVkIHN1Ym1pc3Npb24gdG8gc2VydmVyIHdoZW4gY29uZmlndXJlZFxuICovXG5jbGFzcyBEZWJ1Z2dlciB7XG4gICAgLy8gQmF0Y2hpbmcgc3RhdGUgZm9yIGNvbnNvbGVfZGVidWcgbWVzc2FnZXNcbiAgICBzdGF0aWMgX2NvbnNvbGVfYmF0Y2ggPSBbXTtcbiAgICBzdGF0aWMgX2NvbnNvbGVfdGltZXIgPSBudWxsO1xuICAgIHN0YXRpYyBfY29uc29sZV9iYXRjaF9jb3VudCA9IDA7XG5cbiAgICAvLyBCYXRjaGluZyBzdGF0ZSBmb3IgZXJyb3IgbWVzc2FnZXNcbiAgICBzdGF0aWMgX2Vycm9yX2JhdGNoID0gW107XG4gICAgc3RhdGljIF9lcnJvcl90aW1lciA9IG51bGw7XG4gICAgc3RhdGljIF9lcnJvcl9jb3VudCA9IDA7XG4gICAgc3RhdGljIF9lcnJvcl9iYXRjaF9jb3VudCA9IDA7XG5cbiAgICAvLyBDb25zdGFudHNcbiAgICBzdGF0aWMgREVCT1VOQ0VfTVMgPSAyMDAwO1xuICAgIHN0YXRpYyBNQVhfRVJST1JTX1BFUl9QQUdFID0gMjA7XG4gICAgc3RhdGljIE1BWF9FUlJPUl9CQVRDSEVTID0gNTtcblxuICAgIC8vIFN0b3JlIHN0YXJ0IHRpbWUgZm9yIGJlbmNobWFya2luZ1xuICAgIHN0YXRpYyBfc3RhcnRfdGltZSA9IG51bGw7XG5cbiAgICAvKipcbiAgICAgKiBJbml0aWFsaXplIGZyYW1ld29yayBlcnJvciBoYW5kbGluZ1xuICAgICAqIENhbGxlZCBkdXJpbmcgZnJhbWV3b3JrIGluaXRpYWxpemF0aW9uXG4gICAgICovXG4gICAgc3RhdGljIF9vbl9mcmFtZXdvcmtfY29yZV9pbml0KCkge1xuICAgICAgICAvLyBDaGVjayBpZiBicm93c2VyIGVycm9yIGxvZ2dpbmcgaXMgZW5hYmxlZFxuICAgICAgICBpZiAod2luZG93LnJzeGFwcCAmJiB3aW5kb3cucnN4YXBwLmxvZ19icm93c2VyX2Vycm9ycykge1xuICAgICAgICAgICAgLy8gUmVnaXN0ZXIgZ2xvYmFsIGVycm9yIGhhbmRsZXJcbiAgICAgICAgICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdlcnJvcicsIGZ1bmN0aW9uIChldmVudCkge1xuICAgICAgICAgICAgICAgIERlYnVnZ2VyLl9oYW5kbGVfYnJvd3Nlcl9lcnJvcih7XG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2U6IGV2ZW50Lm1lc3NhZ2UsXG4gICAgICAgICAgICAgICAgICAgIGZpbGVuYW1lOiBldmVudC5maWxlbmFtZSxcbiAgICAgICAgICAgICAgICAgICAgbGluZW5vOiBldmVudC5saW5lbm8sXG4gICAgICAgICAgICAgICAgICAgIGNvbG5vOiBldmVudC5jb2xubyxcbiAgICAgICAgICAgICAgICAgICAgc3RhY2s6IGV2ZW50LmVycm9yID8gZXZlbnQuZXJyb3Iuc3RhY2sgOiBudWxsLFxuICAgICAgICAgICAgICAgICAgICB0eXBlOiAnZXJyb3InLFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIC8vIFJlZ2lzdGVyIHVuaGFuZGxlZCBwcm9taXNlIHJlamVjdGlvbiBoYW5kbGVyXG4gICAgICAgICAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcigndW5oYW5kbGVkcmVqZWN0aW9uJywgZnVuY3Rpb24gKGV2ZW50KSB7XG4gICAgICAgICAgICAgICAgRGVidWdnZXIuX2hhbmRsZV9icm93c2VyX2Vycm9yKHtcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZTogZXZlbnQucmVhc29uID8gZXZlbnQucmVhc29uLm1lc3NhZ2UgfHwgU3RyaW5nKGV2ZW50LnJlYXNvbikgOiAnVW5oYW5kbGVkIHByb21pc2UgcmVqZWN0aW9uJyxcbiAgICAgICAgICAgICAgICAgICAgc3RhY2s6IGV2ZW50LnJlYXNvbiAmJiBldmVudC5yZWFzb24uc3RhY2sgPyBldmVudC5yZWFzb24uc3RhY2sgOiBudWxsLFxuICAgICAgICAgICAgICAgICAgICB0eXBlOiAndW5oYW5kbGVkcmVqZWN0aW9uJyxcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gUmVnaXN0ZXIgdWkgcmVmcmVzaCBoYW5kbGVyXG4gICAgICAgIFJzeC5vbigncmVmcmVzaCcsIERlYnVnZ2VyLm9uX3JlZnJlc2gpO1xuICAgIH1cblxuICAgIC8vIEluIGRldiBtb2RlLCBzb21lIHVpIGVsZW1lbnRzIGNhbiBiZSBhdXRvbWF0aWNhbGx5IGFwcGxpZWQgdG8gYXNzaXN0IHdpdGggZGV2ZWxvcG1lbnRcbiAgICBzdGF0aWMgb25fcmVmcmVzaCgpIHtcbiAgICAgICAgaWYgKCFSc3guaXNfcHJvZCgpKSB7XG4gICAgICAgICAgICAvLyBBZGQgYW4gdW5kZXJsaW5lIDIgcHggYmx1ZSB0byBhbGwgYSB0YWdzIHdpdGggaHJlZiA9PT0gXCIjXCIgdXNpbmcganF1ZXJ5XG4gICAgICAgICAgICAvLyBUb2RvOiBtYXliZSB0aGlzIHNob3VsZCBiZSBhIGNvbmZpZ3VyYWJsZSBkZWJ1ZyBvcHRpb24/XG4gICAgICAgICAgICAvLyAkKCdhW2hyZWY9XCIjXCJdJykuY3NzKHtcbiAgICAgICAgICAgIC8vICAgICAnYm9yZGVyLWJvdHRvbSc6ICcycHggc29saWQgYmx1ZScsXG4gICAgICAgICAgICAvLyAgICAgJ3RleHQtZGVjb3JhdGlvbic6ICdub25lJ1xuICAgICAgICAgICAgLy8gfSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBKYXZhU2NyaXB0IGltcGxlbWVudGF0aW9uIG9mIGNvbnNvbGVfZGVidWdcbiAgICAgKiBNaXJyb3JzIFBIUCBmdW5jdGlvbmFsaXR5IHdpdGggYmF0Y2hpbmcgZm9yIExhcmF2ZWwgbG9nXG4gICAgICovXG4gICAgc3RhdGljIGNvbnNvbGVfZGVidWcoY2hhbm5lbCwgLi4udmFsdWVzKSB7XG4gICAgICAgIC8vIENoZWNrIGlmIGNvbnNvbGVfZGVidWcgaXMgZW5hYmxlZFxuICAgICAgICBpZiAoIXdpbmRvdy5yc3hhcHAgfHwgIXdpbmRvdy5yc3hhcHAuY29uc29sZV9kZWJ1ZyB8fCAhd2luZG93LnJzeGFwcC5jb25zb2xlX2RlYnVnLmVuYWJsZWQpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGNvbmZpZyA9IHdpbmRvdy5yc3hhcHAuY29uc29sZV9kZWJ1ZztcblxuICAgICAgICAvLyBOb3JtYWxpemUgY2hhbm5lbCBuYW1lXG4gICAgICAgIGNoYW5uZWwgPSBTdHJpbmcoY2hhbm5lbClcbiAgICAgICAgICAgIC50b1VwcGVyQ2FzZSgpXG4gICAgICAgICAgICAucmVwbGFjZSgvW1xcW1xcXV0vZywgJycpO1xuXG4gICAgICAgIC8vIEFwcGx5IGZpbHRlcmluZ1xuICAgICAgICBpZiAoY29uZmlnLmZpbHRlcl9tb2RlID09PSAnc3BlY2lmaWMnKSB7XG4gICAgICAgICAgICBjb25zdCBzcGVjaWZpYyA9IGNvbmZpZy5zcGVjaWZpY19jaGFubmVsO1xuICAgICAgICAgICAgaWYgKHNwZWNpZmljKSB7XG4gICAgICAgICAgICAgICAgLy8gU3BsaXQgY29tbWEtc2VwYXJhdGVkIHZhbHVlcyBhbmQgbm9ybWFsaXplXG4gICAgICAgICAgICAgICAgY29uc3QgY2hhbm5lbHMgPSBzcGVjaWZpYy5zcGxpdCgnLCcpLm1hcCgoYykgPT4gYy50cmltKCkudG9VcHBlckNhc2UoKSk7XG4gICAgICAgICAgICAgICAgaWYgKCFjaGFubmVscy5pbmNsdWRlcyhjaGFubmVsKSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2UgaWYgKGNvbmZpZy5maWx0ZXJfbW9kZSA9PT0gJ3doaXRlbGlzdCcpIHtcbiAgICAgICAgICAgIGNvbnN0IHdoaXRlbGlzdCA9IChjb25maWcuZmlsdGVyX2NoYW5uZWxzIHx8IFtdKS5tYXAoKGMpID0+IGMudG9VcHBlckNhc2UoKSk7XG4gICAgICAgICAgICBpZiAoIXdoaXRlbGlzdC5pbmNsdWRlcyhjaGFubmVsKSkge1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmIChjb25maWcuZmlsdGVyX21vZGUgPT09ICdibGFja2xpc3QnKSB7XG4gICAgICAgICAgICBjb25zdCBibGFja2xpc3QgPSAoY29uZmlnLmZpbHRlcl9jaGFubmVscyB8fCBbXSkubWFwKChjKSA9PiBjLnRvVXBwZXJDYXNlKCkpO1xuICAgICAgICAgICAgaWYgKGJsYWNrbGlzdC5pbmNsdWRlcyhjaGFubmVsKSkge1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFByZXBhcmUgdGhlIG1lc3NhZ2VcbiAgICAgICAgbGV0IG1lc3NhZ2UgPSB7XG4gICAgICAgICAgICBjaGFubmVsOiBjaGFubmVsLFxuICAgICAgICAgICAgdmFsdWVzOiB2YWx1ZXMsXG4gICAgICAgICAgICB0aW1lc3RhbXA6IG5ldyBEYXRlKCkudG9JU09TdHJpbmcoKSxcbiAgICAgICAgfTtcblxuICAgICAgICAvLyBBZGQgbG9jYXRpb24gaWYgY29uZmlndXJlZFxuICAgICAgICBpZiAoY29uZmlnLmluY2x1ZGVfbG9jYXRpb24gfHwgY29uZmlnLmluY2x1ZGVfYmFja3RyYWNlKSB7XG4gICAgICAgICAgICBjb25zdCBlcnJvciA9IG5ldyBFcnJvcigpO1xuICAgICAgICAgICAgY29uc3Qgc3RhY2sgPSBlcnJvci5zdGFjayB8fCAnJztcbiAgICAgICAgICAgIGNvbnN0IHN0YWNrTGluZXMgPSBzdGFjay5zcGxpdCgnXFxuJyk7XG5cbiAgICAgICAgICAgIGlmIChjb25maWcuaW5jbHVkZV9sb2NhdGlvbiAmJiBzdGFja0xpbmVzLmxlbmd0aCA+IDIpIHtcbiAgICAgICAgICAgICAgICAvLyBTa2lwIEVycm9yIGxpbmUgYW5kIHRoaXMgZnVuY3Rpb25cbiAgICAgICAgICAgICAgICBjb25zdCBjYWxsZXJMaW5lID0gc3RhY2tMaW5lc1syXSB8fCAnJztcbiAgICAgICAgICAgICAgICBjb25zdCBtYXRjaCA9IGNhbGxlckxpbmUubWF0Y2goL2F0XFxzKy4qP1xccytcXCgoLio/KTooXFxkKyk6KFxcZCspXFwpLykgfHwgY2FsbGVyTGluZS5tYXRjaCgvYXRcXHMrKC4qPyk6KFxcZCspOihcXGQrKS8pO1xuICAgICAgICAgICAgICAgIGlmIChtYXRjaCkge1xuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlLmxvY2F0aW9uID0gYCR7bWF0Y2hbMV19OiR7bWF0Y2hbMl19YDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChjb25maWcuaW5jbHVkZV9iYWNrdHJhY2UpIHtcbiAgICAgICAgICAgICAgICAvLyBJbmNsdWRlIGZpcnN0IDUgc3RhY2sgZnJhbWVzLCBza2lwcGluZyB0aGlzIGZ1bmN0aW9uXG4gICAgICAgICAgICAgICAgbWVzc2FnZS5iYWNrdHJhY2UgPSBzdGFja0xpbmVzXG4gICAgICAgICAgICAgICAgICAgIC5zbGljZSgyLCA3KVxuICAgICAgICAgICAgICAgICAgICAubWFwKChsaW5lKSA9PiBsaW5lLnRyaW0oKSlcbiAgICAgICAgICAgICAgICAgICAgLmZpbHRlcigobGluZSkgPT4gbGluZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyBPdXRwdXQgdG8gYnJvd3NlciBjb25zb2xlIGlmIGVuYWJsZWRcbiAgICAgICAgaWYgKGNvbmZpZy5vdXRwdXRzICYmIGNvbmZpZy5vdXRwdXRzLmJyb3dzZXIpIHtcbiAgICAgICAgICAgIGNvbnN0IHByZWZpeCA9IGNvbmZpZy5pbmNsdWRlX2JlbmNobWFyayA/IGBbJHtEZWJ1Z2dlci5fZ2V0X3RpbWVfcHJlZml4KCl9XSBgIDogJyc7XG4gICAgICAgICAgICBjb25zdCBjaGFubmVsUHJlZml4ID0gYFske2NoYW5uZWx9XWA7XG5cbiAgICAgICAgICAgIC8vIFVzZSBhcHByb3ByaWF0ZSBjb25zb2xlIG1ldGhvZCBiYXNlZCBvbiBjaGFubmVsXG4gICAgICAgICAgICBsZXQgY29uc29sZU1ldGhvZCA9ICdsb2cnO1xuICAgICAgICAgICAgaWYgKGNoYW5uZWwuaW5jbHVkZXMoJ0VSUk9SJykpIGNvbnNvbGVNZXRob2QgPSAnZXJyb3InO1xuICAgICAgICAgICAgZWxzZSBpZiAoY2hhbm5lbC5pbmNsdWRlcygnV0FSTicpKSBjb25zb2xlTWV0aG9kID0gJ3dhcm4nO1xuICAgICAgICAgICAgZWxzZSBpZiAoY2hhbm5lbC5pbmNsdWRlcygnSU5GTycpKSBjb25zb2xlTWV0aG9kID0gJ2luZm8nO1xuXG4gICAgICAgICAgICBjb25zb2xlW2NvbnNvbGVNZXRob2RdKHByZWZpeCArIGNoYW5uZWxQcmVmaXgsIC4uLnZhbHVlcyk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBCYXRjaCBmb3IgTGFyYXZlbCBsb2cgaWYgZW5hYmxlZFxuICAgICAgICBpZiAoY29uZmlnLm91dHB1dHMgJiYgY29uZmlnLm91dHB1dHMubGFyYXZlbF9sb2cpIHtcbiAgICAgICAgICAgIERlYnVnZ2VyLl9iYXRjaF9jb25zb2xlX21lc3NhZ2UobWVzc2FnZSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBMb2cgYW4gZXJyb3IgdG8gdGhlIHNlcnZlclxuICAgICAqIFVzZWQgbWFudWFsbHkgb3IgYnkgQWpheCBlcnJvciBoYW5kbGluZ1xuICAgICAqL1xuICAgIHN0YXRpYyBsb2dfZXJyb3IoZXJyb3IpIHtcbiAgICAgICAgLy8gQ2hlY2sgaWYgYnJvd3NlciBlcnJvciBsb2dnaW5nIGlzIGVuYWJsZWRcbiAgICAgICAgaWYgKCF3aW5kb3cucnN4YXBwIHx8ICF3aW5kb3cucnN4YXBwLmxvZ19icm93c2VyX2Vycm9ycykge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gTm9ybWFsaXplIGVycm9yIGZvcm1hdFxuICAgICAgICBsZXQgZXJyb3JEYXRhID0ge307XG4gICAgICAgIGlmICh0eXBlb2YgZXJyb3IgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICBlcnJvckRhdGEubWVzc2FnZSA9IGVycm9yO1xuICAgICAgICAgICAgZXJyb3JEYXRhLnR5cGUgPSAnbWFudWFsJztcbiAgICAgICAgfSBlbHNlIGlmIChlcnJvciBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICAgICAgICBlcnJvckRhdGEubWVzc2FnZSA9IGVycm9yLm1lc3NhZ2U7XG4gICAgICAgICAgICBlcnJvckRhdGEuc3RhY2sgPSBlcnJvci5zdGFjaztcbiAgICAgICAgICAgIGVycm9yRGF0YS50eXBlID0gJ2V4Y2VwdGlvbic7XG4gICAgICAgIH0gZWxzZSBpZiAoZXJyb3IgJiYgdHlwZW9mIGVycm9yID09PSAnb2JqZWN0Jykge1xuICAgICAgICAgICAgZXJyb3JEYXRhID0gZXJyb3I7XG4gICAgICAgICAgICBpZiAoIWVycm9yRGF0YS50eXBlKSB7XG4gICAgICAgICAgICAgICAgZXJyb3JEYXRhLnR5cGUgPSAnbWFudWFsJztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIERlYnVnZ2VyLl9oYW5kbGVfYnJvd3Nlcl9lcnJvcihlcnJvckRhdGEpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEludGVybmFsOiBIYW5kbGUgYnJvd3NlciBlcnJvcnMgd2l0aCBiYXRjaGluZ1xuICAgICAqL1xuICAgIHN0YXRpYyBfaGFuZGxlX2Jyb3dzZXJfZXJyb3IoZXJyb3JEYXRhKSB7XG4gICAgICAgIC8vIENoZWNrIGxpbWl0c1xuICAgICAgICBpZiAoRGVidWdnZXIuX2Vycm9yX2NvdW50ID49IERlYnVnZ2VyLk1BWF9FUlJPUlNfUEVSX1BBR0UpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBpZiAoRGVidWdnZXIuX2Vycm9yX2JhdGNoX2NvdW50ID49IERlYnVnZ2VyLk1BWF9FUlJPUl9CQVRDSEVTKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBEZWJ1Z2dlci5fZXJyb3JfY291bnQrKztcblxuICAgICAgICAvLyBBZGQgbWV0YWRhdGFcbiAgICAgICAgZXJyb3JEYXRhLnVybCA9IHdpbmRvdy5sb2NhdGlvbi5ocmVmO1xuICAgICAgICBlcnJvckRhdGEudXNlckFnZW50ID0gbmF2aWdhdG9yLnVzZXJBZ2VudDtcbiAgICAgICAgZXJyb3JEYXRhLnRpbWVzdGFtcCA9IG5ldyBEYXRlKCkudG9JU09TdHJpbmcoKTtcblxuICAgICAgICAvLyBBZGQgdG8gYmF0Y2hcbiAgICAgICAgRGVidWdnZXIuX2Vycm9yX2JhdGNoLnB1c2goZXJyb3JEYXRhKTtcblxuICAgICAgICAvLyBDbGVhciBleGlzdGluZyB0aW1lclxuICAgICAgICBpZiAoRGVidWdnZXIuX2Vycm9yX3RpbWVyKSB7XG4gICAgICAgICAgICBjbGVhclRpbWVvdXQoRGVidWdnZXIuX2Vycm9yX3RpbWVyKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFNldCBkZWJvdW5jZSB0aW1lclxuICAgICAgICBEZWJ1Z2dlci5fZXJyb3JfdGltZXIgPSBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgIERlYnVnZ2VyLl9mbHVzaF9lcnJvcl9iYXRjaCgpO1xuICAgICAgICB9LCBEZWJ1Z2dlci5ERUJPVU5DRV9NUyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogSW50ZXJuYWw6IEJhdGNoIGNvbnNvbGVfZGVidWcgbWVzc2FnZXMgZm9yIExhcmF2ZWwgbG9nXG4gICAgICovXG4gICAgc3RhdGljIF9iYXRjaF9jb25zb2xlX21lc3NhZ2UobWVzc2FnZSkge1xuICAgICAgICBEZWJ1Z2dlci5fY29uc29sZV9iYXRjaC5wdXNoKG1lc3NhZ2UpO1xuXG4gICAgICAgIC8vIENsZWFyIGV4aXN0aW5nIHRpbWVyXG4gICAgICAgIGlmIChEZWJ1Z2dlci5fY29uc29sZV90aW1lcikge1xuICAgICAgICAgICAgY2xlYXJUaW1lb3V0KERlYnVnZ2VyLl9jb25zb2xlX3RpbWVyKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFNldCBkZWJvdW5jZSB0aW1lclxuICAgICAgICBEZWJ1Z2dlci5fY29uc29sZV90aW1lciA9IHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgRGVidWdnZXIuX2ZsdXNoX2NvbnNvbGVfYmF0Y2goKTtcbiAgICAgICAgfSwgRGVidWdnZXIuREVCT1VOQ0VfTVMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEludGVybmFsOiBGbHVzaCBjb25zb2xlX2RlYnVnIGJhdGNoIHRvIHNlcnZlclxuICAgICAqL1xuICAgIHN0YXRpYyBhc3luYyBfZmx1c2hfY29uc29sZV9iYXRjaCgpIHtcbiAgICAgICAgaWYgKERlYnVnZ2VyLl9jb25zb2xlX2JhdGNoLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgbWVzc2FnZXMgPSBEZWJ1Z2dlci5fY29uc29sZV9iYXRjaDtcbiAgICAgICAgRGVidWdnZXIuX2NvbnNvbGVfYmF0Y2ggPSBbXTtcbiAgICAgICAgRGVidWdnZXIuX2NvbnNvbGVfdGltZXIgPSBudWxsO1xuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICByZXR1cm4gQWpheC5jYWxsKFJzeC5Sb3V0ZSgnRGVidWdnZXJfQ29udHJvbGxlcicsICdsb2dfY29uc29sZV9tZXNzYWdlcycpLCB7IG1lc3NhZ2VzOiBtZXNzYWdlcyB9KTtcbiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgIC8vIFNpbGVudGx5IGZhaWwgLSBkb24ndCBjcmVhdGUgZXJyb3IgbG9vcFxuICAgICAgICAgICAgY29uc29sZS5lcnJvcignRmFpbGVkIHRvIHNlbmQgY29uc29sZV9kZWJ1ZyBtZXNzYWdlcyB0byBzZXJ2ZXI6JywgZXJyb3IpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogSW50ZXJuYWw6IEZsdXNoIGVycm9yIGJhdGNoIHRvIHNlcnZlclxuICAgICAqL1xuICAgIHN0YXRpYyBhc3luYyBfZmx1c2hfZXJyb3JfYmF0Y2goKSB7XG4gICAgICAgIGlmIChEZWJ1Z2dlci5fZXJyb3JfYmF0Y2gubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBlcnJvcnMgPSBEZWJ1Z2dlci5fZXJyb3JfYmF0Y2g7XG4gICAgICAgIERlYnVnZ2VyLl9lcnJvcl9iYXRjaCA9IFtdO1xuICAgICAgICBEZWJ1Z2dlci5fZXJyb3JfdGltZXIgPSBudWxsO1xuICAgICAgICBEZWJ1Z2dlci5fZXJyb3JfYmF0Y2hfY291bnQrKztcblxuICAgICAgICB0cnkge1xuICAgICAgICAgICAgcmV0dXJuIEFqYXguY2FsbChSc3guUm91dGUoJ0RlYnVnZ2VyX0NvbnRyb2xsZXInLCAnbG9nX2Jyb3dzZXJfZXJyb3JzJyksIHsgZXJyb3JzOiBlcnJvcnMgfSk7XG4gICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICAvLyBTaWxlbnRseSBmYWlsIC0gZG9uJ3QgY3JlYXRlIGVycm9yIGxvb3BcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0ZhaWxlZCB0byBzZW5kIGJyb3dzZXIgZXJyb3JzIHRvIHNlcnZlcjonLCBlcnJvcik7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBJbnRlcm5hbDogR2V0IHRpbWUgcHJlZml4IGZvciBiZW5jaG1hcmtpbmdcbiAgICAgKi9cbiAgICBzdGF0aWMgX2dldF90aW1lX3ByZWZpeCgpIHtcbiAgICAgICAgY29uc3Qgbm93ID0gRGF0ZS5ub3coKTtcbiAgICAgICAgaWYgKCFEZWJ1Z2dlci5fc3RhcnRfdGltZSkge1xuICAgICAgICAgICAgRGVidWdnZXIuX3N0YXJ0X3RpbWUgPSBub3c7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgZWxhcHNlZCA9IG5vdyAtIERlYnVnZ2VyLl9zdGFydF90aW1lO1xuICAgICAgICByZXR1cm4gKGVsYXBzZWQgLyAxMDAwKS50b0ZpeGVkKDMpICsgJ3MnO1xuICAgIH1cbn1cbiIsIi8vIEBKUy1USElTLTAxLUVYQ0VQVElPTlxuLyoqXG4gKiBqUXVlcnkgaGVscGVyIGV4dGVuc2lvbnMgZm9yIHRoZSBSU1ggZnJhbWV3b3JrXG4gKiBUaGVzZSBleHRlbnNpb25zIGFkZCB1dGlsaXR5IG1ldGhvZHMgdG8galF1ZXJ5J3MgcHJvdG90eXBlXG4gKiBOb3RlOiAndGhpcycgcmVmZXJlbmNlcyBpbiBqUXVlcnkgZXh0ZW5zaW9ucyByZWZlciB0byBqUXVlcnkgb2JqZWN0cyBieSBkZXNpZ25cbiAqL1xuY2xhc3MgUnN4X0pxX0hlbHBlcnMge1xuICAgIC8qKlxuICAgICAqIEluaXRpYWxpemUgalF1ZXJ5IGV4dGVuc2lvbnMgd2hlbiB0aGUgZnJhbWV3b3JrIGNvcmUgaXMgZGVmaW5lZFxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGNhbGxlZCBkdXJpbmcgZnJhbWV3b3JrIGluaXRpYWxpemF0aW9uXG4gICAgICovXG4gICAgc3RhdGljIF9vbl9mcmFtZXdvcmtfY29yZV9kZWZpbmUoKSB7XG4gICAgICAgIC8vIFJldHVybnMgdHJ1ZSBpZiBqcXVlcnkgc2VsZWN0b3IgbWF0Y2hlZCBhbiBlbGVtZW50XG4gICAgICAgICQuZm4uZXhpc3RzID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMubGVuZ3RoID4gMDtcbiAgICAgICAgfTtcblxuICAgICAgICAvLyBSZXR1cm5zIHRydWUgaWYganF1ZXJ5IGVsZW1lbnQgaXMgdmlzaWJsZVxuICAgICAgICAkLmZuLmlzX3Zpc2libGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5pcygnOnZpc2libGUnKTtcbiAgICAgICAgfTtcblxuICAgICAgICAvLyBTY3JvbGxzIHRvIHRoZSB0YXJnZXQgZWxlbWVudCwgb25seSBzY3JvbGxzIHVwLiAgVG9kbzogQ3JlYXRlIGEgdmVyc2lvblxuICAgICAgICAvLyBvZiB0aGlzIHRoYXQgYWxzbyBzY3JvbGxzIG9ubHkgZG93biwgb3IgYm90aFxuICAgICAgICAkLmZuLnNjcm9sbF91cF90byA9IGZ1bmN0aW9uIChzcGVlZCA9IDApIHtcbiAgICAgICAgICAgIGlmICghdGhpcy5leGlzdHMoKSkge1xuICAgICAgICAgICAgICAgIC8vIGNvbnNvbGUud2FybihcIkNvdWxkIG5vdCBmaW5kIHRhcmdldCBlbGVtZW50IHRvIHNjcm9sbCB0b1wiKTtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmICghdGhpcy5pc19pbl9kb20oKSkge1xuICAgICAgICAgICAgICAgIC8vIGNvbnNvbGUud2FybihcIlRhcmdldCBlbGVtZW50IGZvciBzY3JvbGwgaXMgbm90IG9uIGRvbVwiKTtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGxldCBlX3RvcCA9IE1hdGgucm91bmQodGhpcy5vZmZzZXQoKS50b3ApO1xuICAgICAgICAgICAgbGV0IHNfdG9wID0gJCgnYm9keScpLnNjcm9sbFRvcCgpO1xuICAgICAgICAgICAgaWYgKGVfdG9wIDwgMCkge1xuICAgICAgICAgICAgICAgIGxldCB0YXJnZXQgPSBzX3RvcCArIGVfdG9wO1xuICAgICAgICAgICAgICAgICQoJ2h0bWwsIGJvZHknKS5hbmltYXRlKFxuICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzY3JvbGxUb3A6IHRhcmdldCxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgc3BlZWRcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuXG4gICAgICAgIC8vICQoKS5pcyhcIjpmb2N1c1wiKSAtIGNoZWNrIGlmIGVsZW1lbnQgaGFzIGZvY3VzXG4gICAgICAgICQuZXhwclsnOiddLmZvY3VzID0gZnVuY3Rpb24gKGVsZW0pIHtcbiAgICAgICAgICAgIHJldHVybiBlbGVtID09PSBkb2N1bWVudC5hY3RpdmVFbGVtZW50ICYmIChlbGVtLnR5cGUgfHwgZWxlbS5ocmVmKTtcbiAgICAgICAgfTtcblxuICAgICAgICAvLyBTYXZlIG5hdGl2ZSBjbGljayBiZWhhdmlvciBiZWZvcmUgb3ZlcnJpZGVcbiAgICAgICAgJC5mbi5fY2xpY2tfbmF0aXZlID0gJC5mbi5jbGljaztcblxuICAgICAgICAvLyBPdmVycmlkZSAuY2xpY2soKSB0byBjYWxsIHByZXZlbnREZWZhdWx0IGJ5IGRlZmF1bHRcbiAgICAgICAgLy8gVGhpcyBwcmV2ZW50cyBhY2NpZGVudGFsIHBhZ2UgbmF2aWdhdGlvbi9mb3JtIHN1Ym1pc3Npb24gLSB0aGUgY29ycmVjdCBiZWhhdmlvciA5NSUgb2YgdGhlIHRpbWVcbiAgICAgICAgJC5mbi5jbGljayA9IGZ1bmN0aW9uIChoYW5kbGVyKSB7XG4gICAgICAgICAgICAvLyBJZiBubyBoYW5kbGVyIHByb3ZpZGVkLCB0cmlnZ2VyIGNsaWNrIGV2ZW50IChqUXVlcnkgLmNsaWNrKCkgd2l0aCBubyBhcmdzKVxuICAgICAgICAgICAgaWYgKHR5cGVvZiBoYW5kbGVyID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9jbGlja19uYXRpdmUoKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gQXR0YWNoIGNsaWNrIGhhbmRsZXIgd2l0aCBhdXRvbWF0aWMgcHJldmVudERlZmF1bHRcbiAgICAgICAgICAgIHJldHVybiB0aGlzLm9uKCdjbGljaycsIGZ1bmN0aW9uIChlKSB7XG4gICAgICAgICAgICAgICAgLy8gU2F2ZSBvcmlnaW5hbCBwcmV2ZW50RGVmYXVsdFxuICAgICAgICAgICAgICAgIGNvbnN0IG9yaWdpbmFsX3ByZXZlbnREZWZhdWx0ID0gZS5wcmV2ZW50RGVmYXVsdC5iaW5kKGUpO1xuXG4gICAgICAgICAgICAgICAgLy8gT3ZlcnJpZGUgcHJldmVudERlZmF1bHQgdG8gc2hvdyB3YXJuaW5nIHdoZW4gY2FsbGVkIGV4cGxpY2l0bHlcbiAgICAgICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0ID0gZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUud2FybignZXZlbnQucHJldmVudERlZmF1bHQoKSBpcyBjYWxsZWQgYXV0b21hdGljYWxseSBieSBSU3BhZGUgLmNsaWNrKCkgaGFuZGxlcnMgYW5kIGNhbiBiZSByZW1vdmVkLicpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gb3JpZ2luYWxfcHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAgICAgLy8gQ2FsbCBwcmV2ZW50RGVmYXVsdCBiZWZvcmUgaGFuZGxlclxuICAgICAgICAgICAgICAgIG9yaWdpbmFsX3ByZXZlbnREZWZhdWx0KCk7XG5cbiAgICAgICAgICAgICAgICByZXR1cm4gaGFuZGxlci5jYWxsKHRoaXMsIGUpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH07XG5cbiAgICAgICAgLy8gRXNjYXBlIGhhdGNoOiBjbGljayBoYW5kbGVyIHdpdGhvdXQgcHJldmVudERlZmF1bHQgZm9yIHRoZSA1JSBjYXNlXG4gICAgICAgICQuZm4uY2xpY2tfYWxsb3dfZGVmYXVsdCA9IGZ1bmN0aW9uIChoYW5kbGVyKSB7XG4gICAgICAgICAgICBpZiAodHlwZW9mIGhhbmRsZXIgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2NsaWNrX25hdGl2ZSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2NsaWNrX25hdGl2ZShoYW5kbGVyKTtcbiAgICAgICAgfTtcblxuICAgICAgICAvLyBSZXR1cm5zIHRydWUgaWYgdGhlIGpxdWVyeSBlbGVtZW50IGV4aXN0cyBpbiBhbmQgaXMgYXR0YWNoZWQgdG8gdGhlIERPTVxuICAgICAgICAkLmZuLmlzX2luX2RvbSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGxldCAkZWxlbWVudCA9IHRoaXM7XG4gICAgICAgICAgICBsZXQgX2FuY2VzdG9yID0gZnVuY3Rpb24gKEhUTUxvYmopIHtcbiAgICAgICAgICAgICAgICB3aGlsZSAoSFRNTG9iai5wYXJlbnRFbGVtZW50KSB7XG4gICAgICAgICAgICAgICAgICAgIEhUTUxvYmogPSBIVE1Mb2JqLnBhcmVudEVsZW1lbnQ7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiBIVE1Mb2JqO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIHJldHVybiBfYW5jZXN0b3IoJGVsZW1lbnRbMF0pID09PSBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQ7XG4gICAgICAgIH07XG5cbiAgICAgICAgLy8gUmV0dXJucyB0cnVlIGlmIHRoZSBlbGVtZW50IGlzIHZpc2libGUgaW4gdGhlIHZpZXdwb3J0XG4gICAgICAgICQuZm4uaXNfaW5fdmlld3BvcnQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBsZXQgc2Nyb2xsdG9wID0gJCh3aW5kb3cpLnNjcm9sbFRvcCgpID4gMCA/ICQod2luZG93KS5zY3JvbGxUb3AoKSA6ICQoJ2JvZHknKS5zY3JvbGxUb3AoKTtcblxuICAgICAgICAgICAgbGV0ICRlbGVtZW50ID0gdGhpcztcblxuICAgICAgICAgICAgY29uc3QgdG9wX29mX2VsZW1lbnQgPSAkZWxlbWVudC5vZmZzZXQoKS50b3A7XG4gICAgICAgICAgICBjb25zdCBib3R0b21fb2ZfZWxlbWVudCA9ICRlbGVtZW50Lm9mZnNldCgpLnRvcCArICRlbGVtZW50Lm91dGVySGVpZ2h0KCk7XG4gICAgICAgICAgICBjb25zdCBib3R0b21fb2Zfc2NyZWVuID0gc2Nyb2xsdG9wICsgJCh3aW5kb3cpLmlubmVySGVpZ2h0KCk7XG4gICAgICAgICAgICBjb25zdCB0b3Bfb2Zfc2NyZWVuID0gc2Nyb2xsdG9wO1xuXG4gICAgICAgICAgICBpZiAoYm90dG9tX29mX3NjcmVlbiA+IHRvcF9vZl9lbGVtZW50ICYmIHRvcF9vZl9zY3JlZW4gPCBib3R0b21fb2ZfZWxlbWVudCkge1xuICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG5cbiAgICAgICAgLy8gR2V0cyB0aGUgdGFnbmFtZSBvZiBhIGpxdWVyeSBlbGVtZW50XG4gICAgICAgICQuZm4udGFnbmFtZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnByb3AoJ3RhZ05hbWUnKS50b0xvd2VyQ2FzZSgpO1xuICAgICAgICB9O1xuXG4gICAgICAgIC8vIFJldHVybnMgdHJ1ZSBpZiBhIGhyZWYgaXMgbm90IHNhbWUgZG9tYWluXG4gICAgICAgICQuZm4uaXNfZXh0ZXJuYWwgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBjb25zdCBob3N0ID0gd2luZG93LmxvY2F0aW9uLmhvc3Q7XG4gICAgICAgICAgICBjb25zdCBsaW5rID0gJCgnPGE+Jywge1xuICAgICAgICAgICAgICAgIGhyZWY6IHRoaXMuYXR0cignaHJlZicpLFxuICAgICAgICAgICAgfSlbMF0uaG9zdG5hbWU7XG4gICAgICAgICAgICByZXR1cm4gbGluayAhPT0gaG9zdDtcbiAgICAgICAgfTtcblxuICAgICAgICAvLyBIVE1MNSBmb3JtIHZhbGlkYXRpb24gd3JhcHBlcnNcbiAgICAgICAgJC5mbi5jaGVja1ZhbGlkaXR5ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgaWYgKHRoaXMubGVuZ3RoID09PSAwKSByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICByZXR1cm4gdGhpc1swXS5jaGVja1ZhbGlkaXR5KCk7XG4gICAgICAgIH07XG5cbiAgICAgICAgJC5mbi5yZXBvcnRWYWxpZGl0eSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLmxlbmd0aCA9PT0gMCkgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXNbMF0ucmVwb3J0VmFsaWRpdHkoKTtcbiAgICAgICAgfTtcblxuICAgICAgICAkLmZuLnJlcXVlc3RTdWJtaXQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5sZW5ndGggPT09IDApIHJldHVybiB0aGlzO1xuICAgICAgICAgICAgdGhpc1swXS5yZXF1ZXN0U3VibWl0KCk7XG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfTtcblxuICAgICAgICAvLyBGaW5kIHJlbGF0ZWQgY29tcG9uZW50cyBieSBzZWFyY2hpbmcgdXAgdGhlIGFuY2VzdG9yIHRyZWVcbiAgICAgICAgLy8gTGlrZSAuY2xvc2VzdCgpIGJ1dCBzZWFyY2hlcyB3aXRoaW4gYW5jZXN0b3JzIGluc3RlYWQgb2YgbWF0Y2hpbmcgdGhlbVxuICAgICAgICAkLmZuLmNsb3Nlc3Rfc2libGluZyA9IGZ1bmN0aW9uIChzZWxlY3Rvcikge1xuICAgICAgICAgICAgbGV0ICRjdXJyZW50ID0gdGhpcztcbiAgICAgICAgICAgIGxldCAkcGFyZW50ID0gJGN1cnJlbnQucGFyZW50KCk7XG5cbiAgICAgICAgICAgIC8vIEtlZXAgZ29pbmcgdXAgdGhlIHRyZWUgdW50aWwgd2UgaGl0IGJvZHlcbiAgICAgICAgICAgIHdoaWxlICgkcGFyZW50Lmxlbmd0aCA+IDAgJiYgISRwYXJlbnQuaXMoJ2JvZHknKSkge1xuICAgICAgICAgICAgICAgIC8vIFNlYXJjaCB3aXRoaW4gdGhpcyBwYXJlbnQgZm9yIHRoZSBzZWxlY3RvclxuICAgICAgICAgICAgICAgIGxldCAkZm91bmQgPSAkcGFyZW50LmZpbmQoc2VsZWN0b3IpO1xuICAgICAgICAgICAgICAgIGlmICgkZm91bmQubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gJGZvdW5kO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIC8vIE1vdmUgdXAgb25lIGxldmVsXG4gICAgICAgICAgICAgICAgJHBhcmVudCA9ICRwYXJlbnQucGFyZW50KCk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIElmIHdlIHJlYWNoZWQgYm9keSwgc2VhcmNoIHdpdGhpbiBib2R5IGFzIHdlbGxcbiAgICAgICAgICAgIGlmICgkcGFyZW50LmlzKCdib2R5JykpIHtcbiAgICAgICAgICAgICAgICBsZXQgJGZvdW5kID0gJHBhcmVudC5maW5kKHNlbGVjdG9yKTtcbiAgICAgICAgICAgICAgICBpZiAoJGZvdW5kLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuICRmb3VuZDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIFJldHVybiBlbXB0eSBqUXVlcnkgb2JqZWN0IGlmIG5vdGhpbmcgZm91bmRcbiAgICAgICAgICAgIHJldHVybiAkKCk7XG4gICAgICAgIH07XG5cbiAgICAgICAgLy8gT3ZlcnJpZGUgJC5hamF4IHRvIHByZXZlbnQgZGlyZWN0IEFKQVggY2FsbHMgdG8gbG9jYWwgc2VydmVyXG4gICAgICAgIC8vIERldmVsb3BlcnMgbXVzdCB1c2UgdGhlIEFqYXggZW5kcG9pbnQgcGF0dGVybjogYXdhaXQgQ29udHJvbGxlci5tZXRob2QocGFyYW1zKVxuICAgICAgICBjb25zdCBuYXRpdmVfYWpheCA9ICQuYWpheDtcbiAgICAgICAgJC5hamF4ID0gZnVuY3Rpb24gKHVybCwgb3B0aW9ucykge1xuICAgICAgICAgICAgLy8gSGFuZGxlIGJvdGggJC5hamF4KHVybCwgb3B0aW9ucykgYW5kICQuYWpheChvcHRpb25zKSBzaWduYXR1cmVzXG4gICAgICAgICAgICBsZXQgc2V0dGluZ3M7XG4gICAgICAgICAgICBpZiAodHlwZW9mIHVybCA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgICAgICBzZXR0aW5ncyA9IG9wdGlvbnMgfHwge307XG4gICAgICAgICAgICAgICAgc2V0dGluZ3MudXJsID0gdXJsO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBzZXR0aW5ncyA9IHVybCB8fCB7fTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gQ2hlY2sgaWYgdGhpcyBpcyBhIGxvY2FsIHJlcXVlc3QgKHJlbGF0aXZlIFVSTCBvciBzYW1lIGRvbWFpbilcbiAgICAgICAgICAgIGNvbnN0IHJlcXVlc3RfdXJsID0gc2V0dGluZ3MudXJsIHx8ICcnO1xuICAgICAgICAgICAgY29uc3QgaXNfcmVsYXRpdmUgPSAhcmVxdWVzdF91cmwubWF0Y2goL15odHRwcz86XFwvXFwvLyk7XG4gICAgICAgICAgICBjb25zdCBpc19zYW1lX2RvbWFpbiA9IHJlcXVlc3RfdXJsLnN0YXJ0c1dpdGgod2luZG93LmxvY2F0aW9uLm9yaWdpbik7XG4gICAgICAgICAgICBjb25zdCBpc19sb2NhbF9yZXF1ZXN0ID0gaXNfcmVsYXRpdmUgfHwgaXNfc2FtZV9kb21haW47XG5cbiAgICAgICAgICAgIC8vIEFsbG93IGZyYW1ld29yayBBamF4LmNhbGwoKSB0byBmdW5jdGlvblxuICAgICAgICAgICAgaWYgKHNldHRpbmdzLl9fbG9jYWxfaW50ZWdyYXRpb24gPT09IHRydWUpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbmF0aXZlX2FqYXguY2FsbCh0aGlzLCBzZXR0aW5ncyk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIEFsbG93IGZpbGUgdXBsb2FkIGVuZHBvaW50IC0gcmVxdWlyZXMgbmF0aXZlICQuYWpheCBmb3IgRm9ybURhdGEgc3VwcG9ydFxuICAgICAgICAgICAgY29uc3QgaXNfZmlsZV91cGxvYWQgPSByZXF1ZXN0X3VybCA9PT0gJy9fdXBsb2FkJyB8fCByZXF1ZXN0X3VybC5lbmRzV2l0aCgnL191cGxvYWQnKTtcbiAgICAgICAgICAgIGlmIChpc19maWxlX3VwbG9hZCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBuYXRpdmVfYWpheC5jYWxsKHRoaXMsIHNldHRpbmdzKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gQmxvY2sgbG9jYWwgQUpBWCByZXF1ZXN0cyB0aGF0IGRvbid0IHVzZSB0aGUgQWpheCBlbmRwb2ludCBwYXR0ZXJuXG4gICAgICAgICAgICBpZiAoaXNfbG9jYWxfcmVxdWVzdCkge1xuICAgICAgICAgICAgICAgIC8vIFRyeSB0byBwYXJzZSBjb250cm9sbGVyIGFuZCBhY3Rpb24gZnJvbSBVUkxcbiAgICAgICAgICAgICAgICBsZXQgY29udHJvbGxlcl9uYW1lID0gbnVsbDtcbiAgICAgICAgICAgICAgICBsZXQgYWN0aW9uX25hbWUgPSBudWxsO1xuICAgICAgICAgICAgICAgIGNvbnN0IHVybF9tYXRjaCA9IHJlcXVlc3RfdXJsLm1hdGNoKC9cXC9fcnN4X2FwaVxcLyhbXlxcL10rKVxcLyhbXlxcL1xcP10rKS8pO1xuICAgICAgICAgICAgICAgIGlmICh1cmxfbWF0Y2gpIHtcbiAgICAgICAgICAgICAgICAgICAgY29udHJvbGxlcl9uYW1lID0gdXJsX21hdGNoWzFdO1xuICAgICAgICAgICAgICAgICAgICBhY3Rpb25fbmFtZSA9IHVybF9tYXRjaFsyXTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBsZXQgZXJyb3JfbWVzc2FnZSA9ICdBSkFYIHJlcXVlc3RzIHRvIGxvY2FsaG9zdCB2aWEgJC5hamF4KCkgYXJlIHByb2hpYml0ZWQuXFxuXFxuJztcblxuICAgICAgICAgICAgICAgIGlmIChjb250cm9sbGVyX25hbWUgJiYgYWN0aW9uX25hbWUpIHtcbiAgICAgICAgICAgICAgICAgICAgZXJyb3JfbWVzc2FnZSArPSBgSW5zdGVhZCBvZjpcXG5gO1xuICAgICAgICAgICAgICAgICAgICBlcnJvcl9tZXNzYWdlICs9IGAgICQuYWpheCh7dXJsOiAnJHtyZXF1ZXN0X3VybH0nLCAuLi59KVxcblxcbmA7XG4gICAgICAgICAgICAgICAgICAgIGVycm9yX21lc3NhZ2UgKz0gYFVzZTpcXG5gO1xuICAgICAgICAgICAgICAgICAgICBlcnJvcl9tZXNzYWdlICs9IGAgIGF3YWl0ICR7Y29udHJvbGxlcl9uYW1lfS4ke2FjdGlvbl9uYW1lfShwYXJhbWV0ZXJzKVxcblxcbmA7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgZXJyb3JfbWVzc2FnZSArPSBgVXNlIHRoZSBBamF4IGVuZHBvaW50IHBhdHRlcm46XFxuYDtcbiAgICAgICAgICAgICAgICAgICAgZXJyb3JfbWVzc2FnZSArPSBgICBhd2FpdCBDb250cm9sbGVyX05hbWUuYWN0aW9uX25hbWUocGFyYW1ldGVycylcXG5cXG5gO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGVycm9yX21lc3NhZ2UgKz0gYFRoZSBjb250cm9sbGVyIG1ldGhvZCBtdXN0IGhhdmUgdGhlICNbQWpheF9FbmRwb2ludF0gYXR0cmlidXRlLmA7XG5cbiAgICAgICAgICAgICAgICBzaG91bGRudF9oYXBwZW4oZXJyb3JfbWVzc2FnZSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIEFsbG93IGV4dGVybmFsIHJlcXVlc3RzIChkaWZmZXJlbnQgZG9tYWluKVxuICAgICAgICAgICAgcmV0dXJuIG5hdGl2ZV9hamF4LmNhbGwodGhpcywgc2V0dGluZ3MpO1xuICAgICAgICB9O1xuICAgIH1cbn0iLCIvLyBAUk9VVEUtRVhJU1RTLTAxLUVYQ0VQVElPTiAtIFRoaXMgZmlsZSBjb250YWlucyBkb2N1bWVudGF0aW9uIGV4YW1wbGVzIHdpdGggZmljdGlvbmFsIHJvdXRlIG5hbWVzXG5cbi8qKlxuICogUnN4IC0gQ29yZSBKYXZhU2NyaXB0IFJ1bnRpbWUgU3lzdGVtXG4gKlxuICogVGhlIFJzeCBjbGFzcyBpcyB0aGUgY2VudHJhbCBodWIgZm9yIHRoZSBSU1ggSmF2YVNjcmlwdCBydW50aW1lLCBwcm92aWRpbmcgZXNzZW50aWFsXG4gKiBzeXN0ZW0tbGV2ZWwgdXRpbGl0aWVzIHRoYXQgYWxsIG90aGVyIGZyYW1ld29yayBjb21wb25lbnRzIGRlcGVuZCBvbi4gSXQgc2VydmVzIGFzIHRoZVxuICogZm91bmRhdGlvbiBmb3IgdGhlIGNsaWVudC1zaWRlIGZyYW1ld29yaywgaGFuZGxpbmcgY29yZSBvcGVyYXRpb25zIHRoYXQgbXVzdCBiZSBnbG9iYWxseVxuICogYWNjZXNzaWJsZSBhbmQgY29uc2lzdGVudGx5IGF2YWlsYWJsZS5cbiAqXG4gKiBDb3JlIFJlc3BvbnNpYmlsaXRpZXM6XG4gKiAtIEV2ZW50IFN5c3RlbTogQXBwbGljYXRpb24td2lkZSBldmVudCBidXMgZm9yIGZyYW1ld29yayBsaWZlY3ljbGUgYW5kIGN1c3RvbSBldmVudHNcbiAqIC0gRW52aXJvbm1lbnQgRGV0ZWN0aW9uOiBSdW50aW1lIGVudmlyb25tZW50IGlkZW50aWZpY2F0aW9uIChkZXYvcHJvZHVjdGlvbilcbiAqIC0gUm91dGUgTWFuYWdlbWVudDogVHlwZS1zYWZlIHJvdXRlIGdlbmVyYXRpb24gYW5kIFVSTCBidWlsZGluZ1xuICogLSBVbmlxdWUgSUQgR2VuZXJhdGlvbjogQ2xpZW50LXNpZGUgdW5pcXVlIGlkZW50aWZpZXIgZ2VuZXJhdGlvblxuICogLSBGcmFtZXdvcmsgQm9vdHN0cmFwOiBNdWx0aS1waGFzZSBpbml0aWFsaXphdGlvbiBvcmNoZXN0cmF0aW9uXG4gKiAtIExvZ2dpbmc6IENlbnRyYWxpemVkIGxvZ2dpbmcgaW50ZXJmYWNlIChkZWxlZ2F0ZXMgdG8gY29uc29sZV9kZWJ1ZylcbiAqXG4gKiBUaGUgUnN4IGNsYXNzIGRlbGliZXJhdGVseSBrZWVwcyBpdHMgc2NvcGUgbGltaXRlZCB0byBjb3JlIHV0aWxpdGllcy4gQWR2YW5jZWQgZmVhdHVyZXNcbiAqIGFyZSBkZWxlZ2F0ZWQgdG8gc3BlY2lhbGl6ZWQgY2xhc3NlczpcbiAqIC0gTWFuaWZlc3Qgb3BlcmF0aW9ucyDihpIgTWFuaWZlc3QgY2xhc3NcbiAqIC0gQ2FjaGluZyDihpIgUnN4X0NhY2hlIGNsYXNzXG4gKiAtIEFKQVgvQVBJIGNhbGxzIOKGkiBBamF4XyogY2xhc3Nlc1xuICogLSBSb3V0ZSBwcm94aWVzIOKGkiBSc3hfUm91dGVfUHJveHkgY2xhc3NcbiAqIC0gQmVoYXZpb3JzIOKGkiBSc3hfQmVoYXZpb3JzIGNsYXNzXG4gKlxuICogQWxsIG1ldGhvZHMgYXJlIHN0YXRpYyAtIFJzeCBpcyBuZXZlciBpbnN0YW50aWF0ZWQuIEl0J3MgYXZhaWxhYmxlIGdsb2JhbGx5IGZyb20gdGhlXG4gKiBtb21lbnQgYnVuZGxlcyBsb2FkIGFuZCByZW1haW5zIGNvbnN0YW50IHRocm91Z2hvdXQgdGhlIGFwcGxpY2F0aW9uIGxpZmVjeWNsZS5cbiAqXG4gKiBVc2FnZSBFeGFtcGxlczpcbiAqIGBgYGphdmFzY3JpcHRcbiAqIC8vIEV2ZW50IHN5c3RlbVxuICogUnN4Lm9uKCdhcHBfcmVhZHknLCAoKSA9PiBjb25zb2xlLmxvZygnQXBwIGluaXRpYWxpemVkJykpO1xuICogUnN4LnRyaWdnZXIoJ2N1c3RvbV9ldmVudCcsIHtkYXRhOiAndmFsdWUnfSk7XG4gKlxuICogLy8gRW52aXJvbm1lbnQgZGV0ZWN0aW9uXG4gKiBpZiAoUnN4LmlzX2RldigpKSB7IGNvbnNvbGUubG9nKCdEZXZlbG9wbWVudCBtb2RlJyk7IH1cbiAqXG4gKiAvLyBSb3V0ZSBnZW5lcmF0aW9uXG4gKiBjb25zdCB1cmwgPSBSc3guUm91dGUoJ0NvbnRyb2xsZXInLCAnYWN0aW9uJykudXJsKCk7XG4gKlxuICogLy8gVW5pcXVlIElEc1xuICogY29uc3QgdW5pcXVlSWQgPSBSc3gudWlkKCk7IC8vIGUuZy4sIFwicnN4XzEyMzQ1Njc4OTBfMVwiXG4gKiBgYGBcbiAqXG4gKiBAc3RhdGljXG4gKiBAZ2xvYmFsXG4gKi9cbmNsYXNzIFJzeCB7XG4gICAgLy8gR2V0cyBzZXQgdG8gdHJ1ZSB0byBpbnRlcnVwdCBzdGFydHVwIHNlcXVlbmNlXG4gICAgc3RhdGljIF9fc3RvcHBlZCA9IGZhbHNlO1xuXG4gICAgLy8gSW5pdGlhbGl6ZSBldmVudCBoYW5kbGVycyBzdG9yYWdlXG4gICAgc3RhdGljIF9pbml0X2V2ZW50cygpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBSc3guX2V2ZW50X2hhbmRsZXJzID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgUnN4Ll9ldmVudF9oYW5kbGVycyA9IHt9O1xuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlb2YgUnN4Ll90cmlnZ2VyZWRfZXZlbnRzID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgUnN4Ll90cmlnZ2VyZWRfZXZlbnRzID0ge307XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBSZWdpc3RlciBhbiBldmVudCBoYW5kbGVyXG4gICAgc3RhdGljIG9uKGV2ZW50LCBjYWxsYmFjaykge1xuICAgICAgICBSc3guX2luaXRfZXZlbnRzKCk7XG5cbiAgICAgICAgaWYgKHR5cGVvZiBjYWxsYmFjayAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdDYWxsYmFjayBtdXN0IGJlIGEgZnVuY3Rpb24nKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghUnN4Ll9ldmVudF9oYW5kbGVyc1tldmVudF0pIHtcbiAgICAgICAgICAgIFJzeC5fZXZlbnRfaGFuZGxlcnNbZXZlbnRdID0gW107XG4gICAgICAgIH1cblxuICAgICAgICBSc3guX2V2ZW50X2hhbmRsZXJzW2V2ZW50XS5wdXNoKGNhbGxiYWNrKTtcblxuICAgICAgICAvLyBJZiB0aGlzIGV2ZW50IHdhcyBhbHJlYWR5IHRyaWdnZXJlZCwgY2FsbCB0aGUgY2FsbGJhY2sgaW1tZWRpYXRlbHlcbiAgICAgICAgaWYgKFJzeC5fdHJpZ2dlcmVkX2V2ZW50c1tldmVudF0pIHtcbiAgICAgICAgICAgIGNvbnNvbGVfZGVidWcoJ1JTWF9JTklUJywgJ1RyaWdnZXJpbmcgJyArIGV2ZW50ICsgJyBmb3IgbGF0ZSByZWdpc3RlcmVkIGNhbGxiYWNrJyk7XG4gICAgICAgICAgICBjYWxsYmFjayhSc3guX3RyaWdnZXJlZF9ldmVudHNbZXZlbnRdKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8vIFRyaWdnZXIgYW4gZXZlbnQgd2l0aCBvcHRpb25hbCBkYXRhXG4gICAgc3RhdGljIHRyaWdnZXIoZXZlbnQsIGRhdGEgPSB7fSkge1xuICAgICAgICBSc3guX2luaXRfZXZlbnRzKCk7XG5cbiAgICAgICAgLy8gUmVjb3JkIHRoYXQgdGhpcyBldmVudCB3YXMgdHJpZ2dlcmVkXG4gICAgICAgIFJzeC5fdHJpZ2dlcmVkX2V2ZW50c1tldmVudF0gPSBkYXRhO1xuXG4gICAgICAgIGlmICghUnN4Ll9ldmVudF9oYW5kbGVyc1tldmVudF0pIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnNvbGVfZGVidWcoJ1JTWF9JTklUJywgJ1RyaWdnZXJpbmcgJyArIGV2ZW50ICsgJyBmb3IgJyArIFJzeC5fZXZlbnRfaGFuZGxlcnNbZXZlbnRdLmxlbmd0aCArICcgY2FsbGJhY2tzJyk7XG5cbiAgICAgICAgLy8gQ2FsbCBhbGwgcmVnaXN0ZXJlZCBoYW5kbGVycyBmb3IgdGhpcyBldmVudCBpbiBvcmRlclxuICAgICAgICBmb3IgKGNvbnN0IGNhbGxiYWNrIG9mIFJzeC5fZXZlbnRfaGFuZGxlcnNbZXZlbnRdKSB7XG4gICAgICAgICAgICBjYWxsYmFjayhkYXRhKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8vIEFsaWFzIGZvciB0cmlnZ2VyLnJlZnJlc2goJycpLCBzaG91bGQgYmUgY2FsbGVkIGFmdGVyIG1ham9yIFVJIHVwZGF0ZXMgdG8gYXBwbHkgc3VjaCBlZmZlY3RzIGFzXG4gICAgLy8gdW5kZXJsaW5pbmcgbGlua3MgdG8gdW5pbXBsZW1lbnRlZCAjIHJvdXRlc1xuICAgIHN0YXRpYyB0cmlnZ2VyX3JlZnJlc2goKSB7XG4gICAgICAgIC8vIFVzZSBSc3gub24oJ3JlZnJlc2gnLCBjYWxsYmFjayk7IHRvIHJlZ2lzdGVyIGEgY2FsbGJhY2sgZm9yIHJlZnJlc2hcbiAgICAgICAgdGhpcy50cmlnZ2VyKCdyZWZyZXNoJyk7XG4gICAgfVxuXG4gICAgLy8gTG9nIHRvIHNlcnZlciB0aGF0IGFuIGV2ZW50IGhhcHBlbmVkXG4gICAgc3RhdGljIGxvZyh0eXBlLCBtZXNzYWdlID0gJ25vdGljZScpIHtcbiAgICAgICAgQ29yZV9Mb2cubG9nKHR5cGUsIG1lc3NhZ2UpO1xuICAgIH1cblxuICAgIC8vIFJldHVybnMgdHJ1ZSBpZiB0aGUgYXBwIGlzIGJlaW5nIHJ1biBpbiBkZXYgbW9kZVxuICAgIC8vIFRoaXMgc2hvdWxkIGFmZmVjdCBjYWNoaW5nIGFuZCBzb21lIGRlYnVnIGNoZWNrc1xuICAgIHN0YXRpYyBpc19kZXYoKSB7XG4gICAgICAgIHJldHVybiB3aW5kb3cucnN4YXBwLmRlYnVnO1xuICAgIH1cblxuICAgIHN0YXRpYyBpc19wcm9kKCkge1xuICAgICAgICByZXR1cm4gIXdpbmRvdy5yc3hhcHAuZGVidWc7XG4gICAgfVxuXG4gICAgLy8gR2VuZXJhdGVzIGEgdW5pcXVlIG51bWJlciBmb3IgdGhlIGFwcGxpY2F0aW9uIGluc3RhbmNlXG4gICAgc3RhdGljIHVpZCgpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBSc3guX3VpZCA9PSB1bmRlZikge1xuICAgICAgICAgICAgUnN4Ll91aWQgPSAwO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBSc3guX3VpZCsrO1xuICAgIH1cblxuICAgIC8vIFN0b3JhZ2UgZm9yIHJvdXRlIGRlZmluaXRpb25zIGxvYWRlZCBmcm9tIGJ1bmRsZXNcbiAgICBzdGF0aWMgX3JvdXRlcyA9IHt9O1xuXG4gICAgLyoqXG4gICAgICogRGVmaW5lIHJvdXRlcyBmcm9tIGJ1bmRsZWQgZGF0YVxuICAgICAqIENhbGxlZCBieSBnZW5lcmF0ZWQgSmF2YVNjcmlwdCBpbiBidW5kbGVzXG4gICAgICovXG4gICAgc3RhdGljIF9kZWZpbmVfcm91dGVzKHJvdXRlcykge1xuICAgICAgICAvLyBNZXJnZSByb3V0ZXMgaW50byB0aGUgZ2xvYmFsIHJvdXRlIHN0b3JhZ2VcbiAgICAgICAgZm9yIChjb25zdCBjbGFzc19uYW1lIGluIHJvdXRlcykge1xuICAgICAgICAgICAgaWYgKCFSc3guX3JvdXRlc1tjbGFzc19uYW1lXSkge1xuICAgICAgICAgICAgICAgIFJzeC5fcm91dGVzW2NsYXNzX25hbWVdID0ge307XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBmb3IgKGNvbnN0IG1ldGhvZF9uYW1lIGluIHJvdXRlc1tjbGFzc19uYW1lXSkge1xuICAgICAgICAgICAgICAgIFJzeC5fcm91dGVzW2NsYXNzX25hbWVdW21ldGhvZF9uYW1lXSA9IHJvdXRlc1tjbGFzc19uYW1lXVttZXRob2RfbmFtZV07XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZW5lcmF0ZSBVUkwgZm9yIGEgY29udHJvbGxlciByb3V0ZVxuICAgICAqXG4gICAgICogVGhpcyBtZXRob2QgZ2VuZXJhdGVzIFVSTHMgZm9yIGNvbnRyb2xsZXIgYWN0aW9ucyBieSBsb29raW5nIHVwIHJvdXRlIHBhdHRlcm5zXG4gICAgICogYW5kIHJlcGxhY2luZyBwYXJhbWV0ZXJzLiBJdCBoYW5kbGVzIGJvdGggcmVndWxhciByb3V0ZXMgYW5kIEFqYXggZW5kcG9pbnRzLlxuICAgICAqXG4gICAgICogSWYgdGhlIHJvdXRlIGlzIG5vdCBmb3VuZCBpbiB0aGUgcm91dGUgZGVmaW5pdGlvbnMsIGEgZGVmYXVsdCBwYXR0ZXJuIGlzIHVzZWQ6XG4gICAgICogYC9fL3tjb250cm9sbGVyfS97YWN0aW9ufWAgd2l0aCBhbGwgcGFyYW1ldGVycyBhcHBlbmRlZCBhcyBxdWVyeSBzdHJpbmdzLlxuICAgICAqXG4gICAgICogVXNhZ2UgZXhhbXBsZXM6XG4gICAgICogYGBgamF2YXNjcmlwdFxuICAgICAqIC8vIFNpbXBsZSByb3V0ZSB3aXRob3V0IHBhcmFtZXRlcnMgKGRlZmF1bHRzIHRvICdpbmRleCcgYWN0aW9uKVxuICAgICAqIGNvbnN0IHVybCA9IFJzeC5Sb3V0ZSgnRnJvbnRlbmRfSW5kZXhfQ29udHJvbGxlcicpO1xuICAgICAqIC8vIFJldHVybnM6IC9kYXNoYm9hcmRcbiAgICAgKlxuICAgICAqIC8vIFJvdXRlIHdpdGggZXhwbGljaXQgYWN0aW9uXG4gICAgICogY29uc3QgdXJsID0gUnN4LlJvdXRlKCdGcm9udGVuZF9JbmRleF9Db250cm9sbGVyJywgJ2luZGV4Jyk7XG4gICAgICogLy8gUmV0dXJuczogL2Rhc2hib2FyZFxuICAgICAqXG4gICAgICogLy8gUm91dGUgd2l0aCBpbnRlZ2VyIHBhcmFtZXRlciAoc2V0cyAnaWQnKVxuICAgICAqIGNvbnN0IHVybCA9IFJzeC5Sb3V0ZSgnRnJvbnRlbmRfQ2xpZW50X1ZpZXdfQ29udHJvbGxlcicsICd2aWV3JywgMTIzKTtcbiAgICAgKiAvLyBSZXR1cm5zOiAvY2xpZW50cy92aWV3LzEyM1xuICAgICAqXG4gICAgICogLy8gUm91dGUgd2l0aCBuYW1lZCBwYXJhbWV0ZXJzIChvYmplY3QpXG4gICAgICogY29uc3QgdXJsID0gUnN4LlJvdXRlKCdGcm9udGVuZF9DbGllbnRfVmlld19Db250cm9sbGVyJywgJ3ZpZXcnLCB7aWQ6ICdDMDAxJ30pO1xuICAgICAqIC8vIFJldHVybnM6IC9jbGllbnRzL3ZpZXcvQzAwMVxuICAgICAqXG4gICAgICogLy8gUm91dGUgd2l0aCByZXF1aXJlZCBhbmQgcXVlcnkgcGFyYW1ldGVyc1xuICAgICAqIGNvbnN0IHVybCA9IFJzeC5Sb3V0ZSgnRnJvbnRlbmRfQ2xpZW50X1ZpZXdfQ29udHJvbGxlcicsICd2aWV3Jywge1xuICAgICAqICAgICBpZDogJ0MwMDEnLFxuICAgICAqICAgICB0YWI6ICdoaXN0b3J5J1xuICAgICAqIH0pO1xuICAgICAqIC8vIFJldHVybnM6IC9jbGllbnRzL3ZpZXcvQzAwMT90YWI9aGlzdG9yeVxuICAgICAqXG4gICAgICogLy8gUm91dGUgbm90IGZvdW5kIC0gdXNlcyBkZWZhdWx0IHBhdHRlcm5cbiAgICAgKiBjb25zdCB1cmwgPSBSc3guUm91dGUoJ1VuaW1wbGVtZW50ZWRfQ29udHJvbGxlcicsICdzb21lX2FjdGlvbicsIHtmb286ICdiYXInfSk7XG4gICAgICogLy8gUmV0dXJuczogL18vVW5pbXBsZW1lbnRlZF9Db250cm9sbGVyL3NvbWVfYWN0aW9uP2Zvbz1iYXJcbiAgICAgKlxuICAgICAqIC8vIFBsYWNlaG9sZGVyIHJvdXRlXG4gICAgICogY29uc3QgdXJsID0gUnN4LlJvdXRlKCdGdXR1cmVfQ29udHJvbGxlcicsICcjaW5kZXgnKTtcbiAgICAgKiAvLyBSZXR1cm5zOiAjXG4gICAgICogYGBgXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gY2xhc3NfbmFtZSBUaGUgY29udHJvbGxlciBjbGFzcyBuYW1lIChlLmcuLCAnVXNlcl9Db250cm9sbGVyJylcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW2FjdGlvbl9uYW1lPSdpbmRleCddIFRoZSBhY3Rpb24vbWV0aG9kIG5hbWUgKGRlZmF1bHRzIHRvICdpbmRleCcpLiBVc2UgJyNhY3Rpb24nIGZvciBwbGFjZWhvbGRlcnMuXG4gICAgICogQHBhcmFtIHtudW1iZXJ8T2JqZWN0fSBbcGFyYW1zPW51bGxdIFJvdXRlIHBhcmFtZXRlcnMuIEludGVnZXIgc2V0cyAnaWQnLCBvYmplY3QgcHJvdmlkZXMgbmFtZWQgcGFyYW1zLlxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFRoZSBnZW5lcmF0ZWQgVVJMXG4gICAgICovXG4gICAgc3RhdGljIFJvdXRlKGNsYXNzX25hbWUsIGFjdGlvbl9uYW1lID0gJ2luZGV4JywgcGFyYW1zID0gbnVsbCkge1xuICAgICAgICAvLyBOb3JtYWxpemUgcGFyYW1zIHRvIG9iamVjdFxuICAgICAgICBsZXQgcGFyYW1zX29iaiA9IHt9O1xuICAgICAgICBpZiAodHlwZW9mIHBhcmFtcyA9PT0gJ251bWJlcicpIHtcbiAgICAgICAgICAgIHBhcmFtc19vYmogPSB7IGlkOiBwYXJhbXMgfTtcbiAgICAgICAgfSBlbHNlIGlmIChwYXJhbXMgJiYgdHlwZW9mIHBhcmFtcyA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgICAgIHBhcmFtc19vYmogPSBwYXJhbXM7XG4gICAgICAgIH0gZWxzZSBpZiAocGFyYW1zICE9PSBudWxsICYmIHBhcmFtcyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1BhcmFtcyBtdXN0IGJlIG51bWJlciwgb2JqZWN0LCBvciBudWxsJyk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBQbGFjZWhvbGRlciByb3V0ZTogYWN0aW9uIHN0YXJ0cyB3aXRoICMgbWVhbnMgdW5pbXBsZW1lbnRlZC9zY2FmZm9sZGluZ1xuICAgICAgICBpZiAoYWN0aW9uX25hbWUuc3RhcnRzV2l0aCgnIycpKSB7XG4gICAgICAgICAgICByZXR1cm4gJyMnO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gQ2hlY2sgaWYgcm91dGUgZXhpc3RzIGluIGRlZmluaXRpb25zXG4gICAgICAgIGxldCBwYXR0ZXJuO1xuICAgICAgICBpZiAoUnN4Ll9yb3V0ZXNbY2xhc3NfbmFtZV0gJiYgUnN4Ll9yb3V0ZXNbY2xhc3NfbmFtZV1bYWN0aW9uX25hbWVdKSB7XG4gICAgICAgICAgICBwYXR0ZXJuID0gUnN4Ll9yb3V0ZXNbY2xhc3NfbmFtZV1bYWN0aW9uX25hbWVdO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gUm91dGUgbm90IGZvdW5kIC0gdXNlIGRlZmF1bHQgcGF0dGVybiAvXy97Y29udHJvbGxlcn0ve2FjdGlvbn1cbiAgICAgICAgICAgIHBhdHRlcm4gPSBgL18vJHtjbGFzc19uYW1lfS8ke2FjdGlvbl9uYW1lfWA7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBHZW5lcmF0ZSBVUkwgZnJvbSBwYXR0ZXJuXG4gICAgICAgIHJldHVybiBSc3guX2dlbmVyYXRlX3VybF9mcm9tX3BhdHRlcm4ocGF0dGVybiwgcGFyYW1zX29iaik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2VuZXJhdGUgVVJMIGZyb20gcm91dGUgcGF0dGVybiBieSByZXBsYWNpbmcgcGFyYW1ldGVyc1xuICAgICAqXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHBhdHRlcm4gVGhlIHJvdXRlIHBhdHRlcm4gKGUuZy4sICcvdXNlcnMvOmlkL3ZpZXcnKVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBwYXJhbXMgUGFyYW1ldGVycyB0byBmaWxsIGludG8gdGhlIHJvdXRlXG4gICAgICogQHJldHVybnMge3N0cmluZ30gVGhlIGdlbmVyYXRlZCBVUkxcbiAgICAgKi9cbiAgICBzdGF0aWMgX2dlbmVyYXRlX3VybF9mcm9tX3BhdHRlcm4ocGF0dGVybiwgcGFyYW1zKSB7XG4gICAgICAgIC8vIEV4dHJhY3QgcmVxdWlyZWQgcGFyYW1ldGVycyBmcm9tIHRoZSBwYXR0ZXJuXG4gICAgICAgIGNvbnN0IHJlcXVpcmVkX3BhcmFtcyA9IFtdO1xuICAgICAgICBjb25zdCBtYXRjaGVzID0gcGF0dGVybi5tYXRjaCgvOihbYS16QS1aX11bYS16QS1aMC05X10qKS9nKTtcbiAgICAgICAgaWYgKG1hdGNoZXMpIHtcbiAgICAgICAgICAgIC8vIFJlbW92ZSB0aGUgOiBwcmVmaXggZnJvbSBlYWNoIG1hdGNoXG4gICAgICAgICAgICBmb3IgKGNvbnN0IG1hdGNoIG9mIG1hdGNoZXMpIHtcbiAgICAgICAgICAgICAgICByZXF1aXJlZF9wYXJhbXMucHVzaChtYXRjaC5zdWJzdHJpbmcoMSkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gQ2hlY2sgZm9yIHJlcXVpcmVkIHBhcmFtZXRlcnNcbiAgICAgICAgY29uc3QgbWlzc2luZyA9IFtdO1xuICAgICAgICBmb3IgKGNvbnN0IHJlcXVpcmVkIG9mIHJlcXVpcmVkX3BhcmFtcykge1xuICAgICAgICAgICAgaWYgKCEocmVxdWlyZWQgaW4gcGFyYW1zKSkge1xuICAgICAgICAgICAgICAgIG1pc3NpbmcucHVzaChyZXF1aXJlZCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAobWlzc2luZy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFJlcXVpcmVkIHBhcmFtZXRlcnMgWyR7bWlzc2luZy5qb2luKCcsICcpfV0gYXJlIG1pc3NpbmcgZm9yIHJvdXRlICR7cGF0dGVybn1gKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIEJ1aWxkIHRoZSBVUkwgYnkgcmVwbGFjaW5nIHBhcmFtZXRlcnNcbiAgICAgICAgbGV0IHVybCA9IHBhdHRlcm47XG4gICAgICAgIGNvbnN0IHVzZWRfcGFyYW1zID0ge307XG5cbiAgICAgICAgZm9yIChjb25zdCBwYXJhbV9uYW1lIG9mIHJlcXVpcmVkX3BhcmFtcykge1xuICAgICAgICAgICAgY29uc3QgdmFsdWUgPSBwYXJhbXNbcGFyYW1fbmFtZV07XG4gICAgICAgICAgICAvLyBVUkwgZW5jb2RlIHRoZSB2YWx1ZVxuICAgICAgICAgICAgY29uc3QgZW5jb2RlZF92YWx1ZSA9IGVuY29kZVVSSUNvbXBvbmVudCh2YWx1ZSk7XG4gICAgICAgICAgICB1cmwgPSB1cmwucmVwbGFjZSgnOicgKyBwYXJhbV9uYW1lLCBlbmNvZGVkX3ZhbHVlKTtcbiAgICAgICAgICAgIHVzZWRfcGFyYW1zW3BhcmFtX25hbWVdID0gdHJ1ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIENvbGxlY3QgYW55IGV4dHJhIHBhcmFtZXRlcnMgZm9yIHF1ZXJ5IHN0cmluZ1xuICAgICAgICBjb25zdCBxdWVyeV9wYXJhbXMgPSB7fTtcbiAgICAgICAgZm9yIChjb25zdCBrZXkgaW4gcGFyYW1zKSB7XG4gICAgICAgICAgICBpZiAoIXVzZWRfcGFyYW1zW2tleV0pIHtcbiAgICAgICAgICAgICAgICBxdWVyeV9wYXJhbXNba2V5XSA9IHBhcmFtc1trZXldO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gQXBwZW5kIHF1ZXJ5IHN0cmluZyBpZiB0aGVyZSBhcmUgZXh0cmEgcGFyYW1ldGVyc1xuICAgICAgICBpZiAoT2JqZWN0LmtleXMocXVlcnlfcGFyYW1zKS5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICBjb25zdCBxdWVyeV9zdHJpbmcgPSBPYmplY3QuZW50cmllcyhxdWVyeV9wYXJhbXMpXG4gICAgICAgICAgICAgICAgLm1hcCgoW2tleSwgdmFsdWVdKSA9PiBgJHtlbmNvZGVVUklDb21wb25lbnQoa2V5KX09JHtlbmNvZGVVUklDb21wb25lbnQodmFsdWUpfWApXG4gICAgICAgICAgICAgICAgLmpvaW4oJyYnKTtcbiAgICAgICAgICAgIHVybCArPSAnPycgKyBxdWVyeV9zdHJpbmc7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdXJsO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEludGVybmFsOiBDYWxsIGEgc3BlY2lmaWMgbWV0aG9kIG9uIGFsbCBjbGFzc2VzIHRoYXQgaGF2ZSBpdFxuICAgICAqIENvbGxlY3RzIHByb21pc2VzIGZyb20gcmV0dXJuIHZhbHVlcyBhbmQgd2FpdHMgZm9yIGFsbCB0byByZXNvbHZlXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IG1ldGhvZF9uYW1lIFRoZSBtZXRob2QgbmFtZSB0byBjYWxsIG9uIGFsbCBjbGFzc2VzXG4gICAgICogQHJldHVybnMge1Byb21pc2V9IFByb21pc2UgdGhhdCByZXNvbHZlcyB3aGVuIGFsbCBtZXRob2QgY2FsbHMgY29tcGxldGVcbiAgICAgKi9cbiAgICBzdGF0aWMgYXN5bmMgX3JzeF9jYWxsX2FsbF9jbGFzc2VzKG1ldGhvZF9uYW1lKSB7XG4gICAgICAgIGNvbnN0IGFsbF9jbGFzc2VzID0gTWFuaWZlc3QuZ2V0X2FsbF9jbGFzc2VzKCk7XG4gICAgICAgIGNvbnN0IGNsYXNzZXNfd2l0aF9tZXRob2QgPSBbXTtcbiAgICAgICAgY29uc3QgcHJvbWlzZV9waWxlID0gW107XG5cbiAgICAgICAgZm9yIChjb25zdCBjbGFzc19pbmZvIG9mIGFsbF9jbGFzc2VzKSB7XG4gICAgICAgICAgICBjb25zdCBjbGFzc19vYmplY3QgPSBjbGFzc19pbmZvLmNsYXNzX29iamVjdDtcbiAgICAgICAgICAgIGNvbnN0IGNsYXNzX25hbWUgPSBjbGFzc19pbmZvLmNsYXNzX25hbWU7XG5cbiAgICAgICAgICAgIC8vIENoZWNrIGlmIHRoaXMgY2xhc3MgaGFzIHRoZSBtZXRob2QgKHN0YXRpYyBtZXRob2RzIGFyZSBvbiB0aGUgY2xhc3MgaXRzZWxmKVxuICAgICAgICAgICAgaWYgKHR5cGVvZiBjbGFzc19vYmplY3RbbWV0aG9kX25hbWVdID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICAgICAgY2xhc3Nlc193aXRoX21ldGhvZC5wdXNoKGNsYXNzX25hbWUpO1xuICAgICAgICAgICAgICAgIGNvbnN0IHJldHVybl92YWx1ZSA9IGF3YWl0IGNsYXNzX29iamVjdFttZXRob2RfbmFtZV0oKTtcblxuICAgICAgICAgICAgICAgIC8vIENvbGxlY3QgcHJvbWlzZXMgZnJvbSByZXR1cm4gdmFsdWVcbiAgICAgICAgICAgICAgICBpZiAocmV0dXJuX3ZhbHVlIGluc3RhbmNlb2YgUHJvbWlzZSkge1xuICAgICAgICAgICAgICAgICAgICBwcm9taXNlX3BpbGUucHVzaChyZXR1cm5fdmFsdWUpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoQXJyYXkuaXNBcnJheShyZXR1cm5fdmFsdWUpKSB7XG4gICAgICAgICAgICAgICAgICAgIGZvciAoY29uc3QgaXRlbSBvZiByZXR1cm5fdmFsdWUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpdGVtIGluc3RhbmNlb2YgUHJvbWlzZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByb21pc2VfcGlsZS5wdXNoKGl0ZW0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgaWYgKFJzeC5fX3N0b3BwZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChjbGFzc2VzX3dpdGhfbWV0aG9kLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIGNvbnNvbGVfZGVidWcoJ1JTWF9JTklUJywgYCR7bWV0aG9kX25hbWV9OiAke2NsYXNzZXNfd2l0aF9tZXRob2QubGVuZ3RofSBjbGFzc2VzYCk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBBd2FpdCBhbGwgcHJvbWlzZXMgYmVmb3JlIHJldHVybmluZ1xuICAgICAgICBpZiAocHJvbWlzZV9waWxlLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIGNvbnNvbGVfZGVidWcoJ1JTWF9JTklUJywgYCR7bWV0aG9kX25hbWV9OiBBd2FpdGluZyAke3Byb21pc2VfcGlsZS5sZW5ndGh9IHByb21pc2VzYCk7XG4gICAgICAgICAgICBhd2FpdCBQcm9taXNlLmFsbChwcm9taXNlX3BpbGUpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogSW50ZXJuYWw6IEV4ZWN1dGUgbXVsdGktcGhhc2UgaW5pdGlhbGl6YXRpb24gZm9yIGFsbCByZWdpc3RlcmVkIGNsYXNzZXNcbiAgICAgKiBUaGlzIHJ1bnMgdmFyaW91cyBpbml0aWFsaXphdGlvbiBwaGFzZXMgaW4gb3JkZXIgdG8gcHJvcGVybHkgc2V0IHVwIHRoZSBhcHBsaWNhdGlvblxuICAgICAqIEByZXR1cm5zIHtQcm9taXNlfSBQcm9taXNlIHRoYXQgcmVzb2x2ZXMgd2hlbiBhbGwgaW5pdGlhbGl6YXRpb24gcGhhc2VzIGNvbXBsZXRlXG4gICAgICovXG4gICAgc3RhdGljIGFzeW5jIF9yc3hfY29yZV9ib290KCkge1xuICAgICAgICBpZiAoUnN4Ll9fYm9vdGVkKSB7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKCdSc3guX3JzeF9jb3JlX2Jvb3QgY2FsbGVkIG1vcmUgdGhhbiBvbmNlJyk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBSc3guX19ib290ZWQgPSB0cnVlO1xuXG4gICAgICAgIC8vIEdldCBhbGwgcmVnaXN0ZXJlZCBjbGFzc2VzIGZyb20gdGhlIG1hbmlmZXN0XG4gICAgICAgIGNvbnN0IGFsbF9jbGFzc2VzID0gTWFuaWZlc3QuZ2V0X2FsbF9jbGFzc2VzKCk7XG5cbiAgICAgICAgY29uc29sZV9kZWJ1ZygnUlNYX0lOSVQnLCBgU3RhcnRpbmcgX3JzeF9jb3JlX2Jvb3Qgd2l0aCAke2FsbF9jbGFzc2VzLmxlbmd0aH0gY2xhc3Nlc2ApO1xuXG4gICAgICAgIGlmICghYWxsX2NsYXNzZXMgfHwgYWxsX2NsYXNzZXMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAvLyBObyBjbGFzc2VzIHRvIGluaXRpYWxpemVcbiAgICAgICAgICAgIHNob3VsZG50X2hhcHBlbignTm8gY2xhc3NlcyByZWdpc3RlcmVkIGluIGpzIC0gdGhlcmUgc2hvdWxkIGJlIGF0IGxlYXN0IHRoZSBjb3JlIGZyYW1ld29yayBjbGFzc2VzJyk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICAvLyBEZWZpbmUgaW5pdGlhbGl6YXRpb24gcGhhc2VzIGluIG9yZGVyXG4gICAgICAgIGNvbnN0IHBoYXNlcyA9IFtcbiAgICAgICAgICAgIHsgZXZlbnQ6ICdmcmFtZXdvcmtfY29yZV9kZWZpbmUnLCBtZXRob2Q6ICdfb25fZnJhbWV3b3JrX2NvcmVfZGVmaW5lJyB9LFxuICAgICAgICAgICAgeyBldmVudDogJ2ZyYW1ld29ya19tb2R1bGVzX2RlZmluZScsIG1ldGhvZDogJ19vbl9mcmFtZXdvcmtfbW9kdWxlc19kZWZpbmUnIH0sXG4gICAgICAgICAgICB7IGV2ZW50OiAnZnJhbWV3b3JrX2NvcmVfaW5pdCcsIG1ldGhvZDogJ19vbl9mcmFtZXdvcmtfY29yZV9pbml0JyB9LFxuICAgICAgICAgICAgeyBldmVudDogJ2FwcF9tb2R1bGVzX2RlZmluZScsIG1ldGhvZDogJ29uX2FwcF9tb2R1bGVzX2RlZmluZScgfSxcbiAgICAgICAgICAgIHsgZXZlbnQ6ICdhcHBfZGVmaW5lJywgbWV0aG9kOiAnb25fYXBwX2RlZmluZScgfSxcbiAgICAgICAgICAgIHsgZXZlbnQ6ICdmcmFtZXdvcmtfbW9kdWxlc19pbml0JywgbWV0aG9kOiAnX29uX2ZyYW1ld29ya19tb2R1bGVzX2luaXQnIH0sXG4gICAgICAgICAgICB7IGV2ZW50OiAnYXBwX21vZHVsZXNfaW5pdCcsIG1ldGhvZDogJ29uX2FwcF9tb2R1bGVzX2luaXQnIH0sXG4gICAgICAgICAgICB7IGV2ZW50OiAnYXBwX2luaXQnLCBtZXRob2Q6ICdvbl9hcHBfaW5pdCcgfSxcbiAgICAgICAgICAgIHsgZXZlbnQ6ICdhcHBfcmVhZHknLCBtZXRob2Q6ICdvbl9hcHBfcmVhZHknIH0sXG4gICAgICAgIF07XG5cbiAgICAgICAgLy8gRXhlY3V0ZSBlYWNoIHBoYXNlIGluIG9yZGVyXG4gICAgICAgIGZvciAoY29uc3QgcGhhc2Ugb2YgcGhhc2VzKSB7XG4gICAgICAgICAgICBhd2FpdCBSc3guX3JzeF9jYWxsX2FsbF9jbGFzc2VzKHBoYXNlLm1ldGhvZCk7XG5cbiAgICAgICAgICAgIGlmIChSc3guX19zdG9wcGVkKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBSc3gudHJpZ2dlcihwaGFzZS5ldmVudCk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBVaSByZWZyZXNoIGNhbGxiYWNrc1xuICAgICAgICBSc3gudHJpZ2dlcl9yZWZyZXNoKCk7XG5cbiAgICAgICAgLy8gQWxsIHBoYXNlcyBjb21wbGV0ZVxuICAgICAgICBjb25zb2xlX2RlYnVnKCdSU1hfSU5JVCcsICdJbml0aWFsaXphdGlvbiBjb21wbGV0ZScpO1xuXG4gICAgICAgIC8vIFRPRE86IEZpbmQgYSBnb29kIHdhaXQgdG8gd2FpdCBmb3IgYWxsIGpxaHRtbCBjb21wb25lbnRzIHRvIGxvYWQsIHRoZW4gdHJpZ2dlciBvbl9yZWFkeSBhbmQgb24oJ3JlYWR5JykgZW11bGF0aW5nIHRoZSB0b3AgbGV2ZWwgbGFzdCBzeW50YXggdGhhdCBqcWh0bWwgY29tcG9uZW50cyBvcGVyYXRlYXMsIGJ1dCBhcyBhIHN0YW5kYXJkIGpzIGNsYXNzIChzdWNoIGFzIGEgcGFnZSBjbGFzcykuICBUaGUgYmlnZ2VzdCBxdWVzdGlvbiBpcywgaG93IGRvIHdlIGVmZmljaWVudGx5IGNob29zZSBvbmx5IHRoZSB0b3AgbGV2ZWwganFodG1sIGNvbXBvbmVudHMuICBkbyB3ZSBvbmx5IGNvbnNpZGVyIGNvbXBvbmVudHMgY3JldGFlZCBkaXJlY3RseSBvbiBibGFkZSB0ZW1wbGF0ZXM/IHRoYXQgc2VhbXMgcmVhc29uYWJsZS4uLlxuXG4gICAgICAgIC8vIFRyaWdnZXIgX2RlYnVnX3JlYWR5IGV2ZW50IC0gdGhpcyBpcyBPTkxZIGZvciB0b29saW5nIGxpa2UgcnN4OmRlYnVnXG4gICAgICAgIC8vIERPIE5PVCB1c2UgdGhpcyBpbiBhcHBsaWNhdGlvbiBjb2RlIC0gdXNlIG9uX2FwcF9yZWFkeSgpIHBoYXNlIGluc3RlYWRcbiAgICAgICAgLy8gVGhpcyBldmVudCBleGlzdHMgc29sZWx5IGZvciBkZWJ1Z2dpbmcgdG9vbHMgdGhhdCBuZWVkIHRvIHJ1biBhZnRlciBmdWxsIGluaXRpYWxpemF0aW9uXG4gICAgICAgIFJzeC50cmlnZ2VyKCdfZGVidWdfcmVhZHknKTtcbiAgICB9XG5cbiAgICAvKiBDYWxsaW5nIHRoaXMgc3RvcHMgdGhlIGJvb3QgcHJvY2Vzcy4gKi9cbiAgICBzdGF0aWMgYXN5bmMgX3JzeF9jb3JlX2Jvb3Rfc3RvcChyZWFzb24pIHtcbiAgICAgICAgY29uc29sZS5lcnJvcihyZWFzb24pO1xuICAgICAgICBSc3guX19zdG9wcGVkID0gdHJ1ZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBQYXJzZSBVUkwgaGFzaCBpbnRvIGtleS12YWx1ZSBvYmplY3RcbiAgICAgKiBIYW5kbGVzIGZvcm1hdDogI2tleT12YWx1ZSZrZXkyPXZhbHVlMlxuICAgICAqXG4gICAgICogQHJldHVybnMge09iamVjdH0gUGFyc2VkIGhhc2ggcGFyYW1ldGVyc1xuICAgICAqL1xuICAgIHN0YXRpYyBfcGFyc2VfaGFzaCgpIHtcbiAgICAgICAgY29uc3QgaGFzaCA9IHdpbmRvdy5sb2NhdGlvbi5oYXNoO1xuICAgICAgICBpZiAoIWhhc2ggfHwgaGFzaCA9PT0gJyMnKSB7XG4gICAgICAgICAgICByZXR1cm4ge307XG4gICAgICAgIH1cblxuICAgICAgICAvLyBSZW1vdmUgbGVhZGluZyAjIGFuZCBwYXJzZSBhcyBxdWVyeSBzdHJpbmdcbiAgICAgICAgY29uc3QgaGFzaF9zdHJpbmcgPSBoYXNoLnN1YnN0cmluZygxKTtcbiAgICAgICAgY29uc3QgcGFyYW1zID0ge307XG5cbiAgICAgICAgY29uc3QgcGFpcnMgPSBoYXNoX3N0cmluZy5zcGxpdCgnJicpO1xuICAgICAgICBmb3IgKGNvbnN0IHBhaXIgb2YgcGFpcnMpIHtcbiAgICAgICAgICAgIGNvbnN0IFtrZXksIHZhbHVlXSA9IHBhaXIuc3BsaXQoJz0nKTtcbiAgICAgICAgICAgIGlmIChrZXkpIHtcbiAgICAgICAgICAgICAgICBwYXJhbXNbZGVjb2RlVVJJQ29tcG9uZW50KGtleSldID0gdmFsdWUgPyBkZWNvZGVVUklDb21wb25lbnQodmFsdWUpIDogJyc7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gcGFyYW1zO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNlcmlhbGl6ZSBvYmplY3QgaW50byBVUkwgaGFzaCBmb3JtYXRcbiAgICAgKiBQcm9kdWNlcyBmb3JtYXQ6ICNrZXk9dmFsdWUma2V5Mj12YWx1ZTJcbiAgICAgKlxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBwYXJhbXMgS2V5LXZhbHVlIHBhaXJzIHRvIGVuY29kZVxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IEVuY29kZWQgaGFzaCBzdHJpbmcgKHdpdGggbGVhZGluZyAjLCBvciBlbXB0eSBzdHJpbmcpXG4gICAgICovXG4gICAgc3RhdGljIF9zZXJpYWxpemVfaGFzaChwYXJhbXMpIHtcbiAgICAgICAgY29uc3QgcGFpcnMgPSBbXTtcbiAgICAgICAgZm9yIChjb25zdCBrZXkgaW4gcGFyYW1zKSB7XG4gICAgICAgICAgICBjb25zdCB2YWx1ZSA9IHBhcmFtc1trZXldO1xuICAgICAgICAgICAgaWYgKHZhbHVlICE9PSBudWxsICYmIHZhbHVlICE9PSB1bmRlZmluZWQgJiYgdmFsdWUgIT09ICcnKSB7XG4gICAgICAgICAgICAgICAgcGFpcnMucHVzaChgJHtlbmNvZGVVUklDb21wb25lbnQoa2V5KX09JHtlbmNvZGVVUklDb21wb25lbnQodmFsdWUpfWApO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHBhaXJzLmxlbmd0aCA+IDAgPyAnIycgKyBwYWlycy5qb2luKCcmJykgOiAnJztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXQgYWxsIHBhZ2Ugc3RhdGUgZnJvbSBVUkwgaGFzaFxuICAgICAqXG4gICAgICogVXNhZ2U6XG4gICAgICogYGBgamF2YXNjcmlwdFxuICAgICAqIGNvbnN0IHN0YXRlID0gUnN4LmdldF9hbGxfcGFnZV9zdGF0ZSgpO1xuICAgICAqIC8vIFJldHVybnM6IHtkZ19wYWdlOiAnMicsIGRnX3NvcnQ6ICduYW1lJ31cbiAgICAgKiBgYGBcbiAgICAgKlxuICAgICAqIEByZXR1cm5zIHtPYmplY3R9IEFsbCBoYXNoIHBhcmFtZXRlcnMgYXMga2V5LXZhbHVlIHBhaXJzXG4gICAgICovXG4gICAgc3RhdGljIGdldF9hbGxfcGFnZV9zdGF0ZSgpIHtcbiAgICAgICAgcmV0dXJuIFJzeC5fcGFyc2VfaGFzaCgpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldCBzaW5nbGUgdmFsdWUgZnJvbSBVUkwgaGFzaCBzdGF0ZVxuICAgICAqXG4gICAgICogVXNhZ2U6XG4gICAgICogYGBgamF2YXNjcmlwdFxuICAgICAqIGNvbnN0IHBhZ2UgPSBSc3guZ2V0X3BhZ2Vfc3RhdGUoJ2RnX3BhZ2UnKTtcbiAgICAgKiAvLyBSZXR1cm5zOiAnMicgb3IgbnVsbCBpZiBub3Qgc2V0XG4gICAgICogYGBgXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgdG8gcmV0cmlldmVcbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfG51bGx9IFRoZSB2YWx1ZSBvciBudWxsIGlmIG5vdCBmb3VuZFxuICAgICAqL1xuICAgIHN0YXRpYyBnZXRfcGFnZV9zdGF0ZShrZXkpIHtcbiAgICAgICAgY29uc3Qgc3RhdGUgPSBSc3guX3BhcnNlX2hhc2goKTtcbiAgICAgICAgcmV0dXJuIHN0YXRlW2tleV0gPz8gbnVsbDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTZXQgc2luZ2xlIHZhbHVlIGluIFVSTCBoYXNoIHN0YXRlIChyZXBsYWNlcyBoaXN0b3J5LCBkb2Vzbid0IGFkZClcbiAgICAgKlxuICAgICAqIFVzYWdlOlxuICAgICAqIGBgYGphdmFzY3JpcHRcbiAgICAgKiBSc3guc2V0X3BhZ2Vfc3RhdGUoJ2RnX3BhZ2UnLCAyKTtcbiAgICAgKiAvLyBVUkwgYmVjb21lczogaHR0cDovL2V4YW1wbGUuY29tL3BhZ2UjZGdfcGFnZT0yXG4gICAgICpcbiAgICAgKiBSc3guc2V0X3BhZ2Vfc3RhdGUoJ2RnX3BhZ2UnLCBudWxsKTsgLy8gUmVtb3ZlIGtleVxuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IHRvIHNldFxuICAgICAqIEBwYXJhbSB7c3RyaW5nfG51bWJlcnxudWxsfSB2YWx1ZSBUaGUgdmFsdWUgKG51bGwvZW1wdHkgcmVtb3ZlcyB0aGUga2V5KVxuICAgICAqL1xuICAgIHN0YXRpYyBzZXRfcGFnZV9zdGF0ZShrZXksIHZhbHVlKSB7XG4gICAgICAgIGNvbnN0IHN0YXRlID0gUnN4Ll9wYXJzZV9oYXNoKCk7XG5cbiAgICAgICAgLy8gVXBkYXRlIG9yIHJlbW92ZSB0aGUga2V5XG4gICAgICAgIGlmICh2YWx1ZSA9PT0gbnVsbCB8fCB2YWx1ZSA9PT0gdW5kZWZpbmVkIHx8IHZhbHVlID09PSAnJykge1xuICAgICAgICAgICAgZGVsZXRlIHN0YXRlW2tleV07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBzdGF0ZVtrZXldID0gU3RyaW5nKHZhbHVlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFVwZGF0ZSBVUkwgd2l0aG91dCBhZGRpbmcgaGlzdG9yeVxuICAgICAgICBjb25zdCBuZXdfaGFzaCA9IFJzeC5fc2VyaWFsaXplX2hhc2goc3RhdGUpO1xuICAgICAgICBjb25zdCB1cmwgPSB3aW5kb3cubG9jYXRpb24ucGF0aG5hbWUgKyB3aW5kb3cubG9jYXRpb24uc2VhcmNoICsgbmV3X2hhc2g7XG4gICAgICAgIGhpc3RvcnkucmVwbGFjZVN0YXRlKG51bGwsICcnLCB1cmwpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNldCBtdWx0aXBsZSB2YWx1ZXMgaW4gVVJMIGhhc2ggc3RhdGUgYXQgb25jZVxuICAgICAqXG4gICAgICogVXNhZ2U6XG4gICAgICogYGBgamF2YXNjcmlwdFxuICAgICAqIFJzeC5zZXRfYWxsX3BhZ2Vfc3RhdGUoe2RnX3BhZ2U6IDIsIGRnX3NvcnQ6ICduYW1lJ30pO1xuICAgICAqIC8vIFVSTCBiZWNvbWVzOiBodHRwOi8vZXhhbXBsZS5jb20vcGFnZSNkZ19wYWdlPTImZGdfc29ydD1uYW1lXG4gICAgICogYGBgXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gbmV3X3N0YXRlIE9iamVjdCB3aXRoIGtleS12YWx1ZSBwYWlycyB0byBzZXRcbiAgICAgKi9cbiAgICBzdGF0aWMgc2V0X2FsbF9wYWdlX3N0YXRlKG5ld19zdGF0ZSkge1xuICAgICAgICBjb25zdCBzdGF0ZSA9IFJzeC5fcGFyc2VfaGFzaCgpO1xuXG4gICAgICAgIC8vIE1lcmdlIG5ldyBzdGF0ZVxuICAgICAgICBmb3IgKGNvbnN0IGtleSBpbiBuZXdfc3RhdGUpIHtcbiAgICAgICAgICAgIGNvbnN0IHZhbHVlID0gbmV3X3N0YXRlW2tleV07XG4gICAgICAgICAgICBpZiAodmFsdWUgPT09IG51bGwgfHwgdmFsdWUgPT09IHVuZGVmaW5lZCB8fCB2YWx1ZSA9PT0gJycpIHtcbiAgICAgICAgICAgICAgICBkZWxldGUgc3RhdGVba2V5XTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgc3RhdGVba2V5XSA9IFN0cmluZyh2YWx1ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyBVcGRhdGUgVVJMIHdpdGhvdXQgYWRkaW5nIGhpc3RvcnlcbiAgICAgICAgY29uc3QgbmV3X2hhc2ggPSBSc3guX3NlcmlhbGl6ZV9oYXNoKHN0YXRlKTtcbiAgICAgICAgY29uc3QgdXJsID0gd2luZG93LmxvY2F0aW9uLnBhdGhuYW1lICsgd2luZG93LmxvY2F0aW9uLnNlYXJjaCArIG5ld19oYXNoO1xuICAgICAgICBoaXN0b3J5LnJlcGxhY2VTdGF0ZShudWxsLCAnJywgdXJsKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBSZW5kZXIgYW4gZXJyb3IgaW4gYSBET00gZWxlbWVudFxuICAgICAqXG4gICAgICogRGlzcGxheXMgZXJyb3JzIGZyb20gQWpheCBjYWxscyBpbiBhIHN0YW5kYXJkaXplZCBmb3JtYXQuIEhhbmRsZXMgZGlmZmVyZW50XG4gICAgICogZXJyb3IgdHlwZXMgKGZhdGFsLCB2YWxpZGF0aW9uLCBhdXRoLCBnZW5lcmljKSB3aXRoIGFwcHJvcHJpYXRlIGZvcm1hdHRpbmcuXG4gICAgICpcbiAgICAgKiBVc2FnZTpcbiAgICAgKiBgYGBqYXZhc2NyaXB0XG4gICAgICogdHJ5IHtcbiAgICAgKiAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgQ29udHJvbGxlci5tZXRob2QoKTtcbiAgICAgKiB9IGNhdGNoIChlcnJvcikge1xuICAgICAqICAgICBSc3gucmVuZGVyX2Vycm9yKGVycm9yLCAnI2Vycm9yX2NvbnRhaW5lcicpO1xuICAgICAqIH1cbiAgICAgKiBgYGBcbiAgICAgKlxuICAgICAqIEBwYXJhbSB7RXJyb3J8T2JqZWN0fSBlcnJvciAtIEVycm9yIG9iamVjdCBmcm9tIEFqYXggY2FsbFxuICAgICAqIEBwYXJhbSB7alF1ZXJ5fHN0cmluZ30gY29udGFpbmVyIC0galF1ZXJ5IGVsZW1lbnQgb3Igc2VsZWN0b3IgZm9yIGVycm9yIGRpc3BsYXlcbiAgICAgKi9cbiAgICBzdGF0aWMgcmVuZGVyX2Vycm9yKGVycm9yLCBjb250YWluZXIpIHtcbiAgICAgICAgY29uc3QgJGNvbnRhaW5lciA9ICQoY29udGFpbmVyKTtcblxuICAgICAgICBpZiAoISRjb250YWluZXIuZXhpc3RzKCkpIHtcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ1JzeC5yZW5kZXJfZXJyb3I6IENvbnRhaW5lciBub3QgZm91bmQnLCBjb250YWluZXIpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gQ2xlYXIgZXhpc3RpbmcgY29udGVudFxuICAgICAgICAkY29udGFpbmVyLmVtcHR5KCk7XG5cbiAgICAgICAgbGV0IGh0bWwgPSAnJztcblxuICAgICAgICAvLyBIYW5kbGUgZGlmZmVyZW50IGVycm9yIHR5cGVzXG4gICAgICAgIGlmIChlcnJvci50eXBlID09PSAnZmF0YWwnICYmIGVycm9yLmRldGFpbHMpIHtcbiAgICAgICAgICAgIC8vIEZhdGFsIFBIUCBlcnJvciB3aXRoIGZpbGUvbGluZS9lcnJvclxuICAgICAgICAgICAgY29uc3QgZGV0YWlscyA9IGVycm9yLmRldGFpbHM7XG4gICAgICAgICAgICBjb25zdCBmaWxlID0gZGV0YWlscy5maWxlIHx8ICdVbmtub3duIGZpbGUnO1xuICAgICAgICAgICAgY29uc3QgbGluZSA9IGRldGFpbHMubGluZSB8fCAnPyc7XG4gICAgICAgICAgICBjb25zdCBtZXNzYWdlID0gZGV0YWlscy5lcnJvciB8fCBlcnJvci5tZXNzYWdlIHx8ICdGYXRhbCBlcnJvciBvY2N1cnJlZCc7XG5cbiAgICAgICAgICAgIGh0bWwgPSBgXG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImFsZXJ0IGFsZXJ0LWRhbmdlclwiIHJvbGU9XCJhbGVydFwiPlxuICAgICAgICAgICAgICAgICAgICA8aDU+VW5jYXVnaHQgRmF0YWwgRXJyb3IgaW4gJHtmaWxlfToke2xpbmV9OjwvaDU+XG4gICAgICAgICAgICAgICAgICAgIDxwIGNsYXNzPVwibWItMFwiPiR7UnN4Ll9lc2NhcGVfaHRtbChtZXNzYWdlKX08L3A+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICBgO1xuICAgICAgICB9IGVsc2UgaWYgKGVycm9yLnR5cGUgPT09ICdmb3JtX2Vycm9yJyAmJiBlcnJvci5kZXRhaWxzKSB7XG4gICAgICAgICAgICAvLyBWYWxpZGF0aW9uIGVycm9ycyAtIHNob3cgdW5tYXRjaGVkIGVycm9ycyBvbmx5XG4gICAgICAgICAgICAvLyAobWF0Y2hlZCBlcnJvcnMgc2hvdWxkIGJlIGhhbmRsZWQgYnkgRm9ybV9VdGlscy5hcHBseV9mb3JtX2Vycm9ycylcbiAgICAgICAgICAgIGNvbnN0IGVycm9ycyA9IGVycm9yLmRldGFpbHM7XG4gICAgICAgICAgICBjb25zdCBlcnJvcl9saXN0ID0gW107XG5cbiAgICAgICAgICAgIGZvciAoY29uc3QgZmllbGQgaW4gZXJyb3JzKSB7XG4gICAgICAgICAgICAgICAgZXJyb3JfbGlzdC5wdXNoKGVycm9yc1tmaWVsZF0pO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoZXJyb3JfbGlzdC5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgICAgaHRtbCA9IGBcbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImFsZXJ0IGFsZXJ0LXdhcm5pbmdcIiByb2xlPVwiYWxlcnRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxoNT5WYWxpZGF0aW9uIEVycm9yczo8L2g1PlxuICAgICAgICAgICAgICAgICAgICAgICAgPHVsIGNsYXNzPVwibWItMFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICR7ZXJyb3JfbGlzdC5tYXAoZXJyID0+IGA8bGk+JHtSc3guX2VzY2FwZV9odG1sKGVycil9PC9saT5gKS5qb2luKCcnKX1cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvdWw+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIGA7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSBpZiAoZXJyb3IudHlwZSA9PT0gJ2F1dGhfcmVxdWlyZWQnIHx8IGVycm9yLnR5cGUgPT09ICd1bmF1dGhvcml6ZWQnKSB7XG4gICAgICAgICAgICAvLyBBdXRoZW50aWNhdGlvbi9hdXRob3JpemF0aW9uIGVycm9yc1xuICAgICAgICAgICAgY29uc3QgbWVzc2FnZSA9IGVycm9yLm1lc3NhZ2UgfHwgJ0F1dGhlbnRpY2F0aW9uIHJlcXVpcmVkJztcbiAgICAgICAgICAgIGh0bWwgPSBgXG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImFsZXJ0IGFsZXJ0LXdhcm5pbmdcIiByb2xlPVwiYWxlcnRcIj5cbiAgICAgICAgICAgICAgICAgICAgPHAgY2xhc3M9XCJtYi0wXCI+JHtSc3guX2VzY2FwZV9odG1sKG1lc3NhZ2UpfTwvcD5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIGA7XG4gICAgICAgIH0gZWxzZSBpZiAoZXJyb3IudHlwZSA9PT0gJ25ldHdvcmsnKSB7XG4gICAgICAgICAgICAvLyBOZXR3b3JrIGVycm9yc1xuICAgICAgICAgICAgY29uc3QgbWVzc2FnZSA9IGVycm9yLm1lc3NhZ2UgfHwgJ1VuYWJsZSB0byByZWFjaCBzZXJ2ZXIuIFBsZWFzZSBjaGVjayB5b3VyIGNvbm5lY3Rpb24uJztcbiAgICAgICAgICAgIGh0bWwgPSBgXG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImFsZXJ0IGFsZXJ0LWRhbmdlclwiIHJvbGU9XCJhbGVydFwiPlxuICAgICAgICAgICAgICAgICAgICA8cCBjbGFzcz1cIm1iLTBcIj4ke1JzeC5fZXNjYXBlX2h0bWwobWVzc2FnZSl9PC9wPlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgYDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIEdlbmVyaWMvdW5rbm93biBlcnJvclxuICAgICAgICAgICAgY29uc3QgbWVzc2FnZSA9IGVycm9yLm1lc3NhZ2UgfHwgZXJyb3IudG9TdHJpbmcoKSB8fCAnQW4gdW5rbm93biBlcnJvciBvY2N1cnJlZCc7XG4gICAgICAgICAgICBodG1sID0gYFxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJhbGVydCBhbGVydC1kYW5nZXJcIiByb2xlPVwiYWxlcnRcIj5cbiAgICAgICAgICAgICAgICAgICAgPHAgY2xhc3M9XCJtYi0wXCI+JHtSc3guX2VzY2FwZV9odG1sKG1lc3NhZ2UpfTwvcD5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIGA7XG4gICAgICAgIH1cblxuICAgICAgICAkY29udGFpbmVyLmh0bWwoaHRtbCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRXNjYXBlIEhUTUwgdG8gcHJldmVudCBYU1MgaW4gZXJyb3IgbWVzc2FnZXNcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuICAgIHN0YXRpYyBfZXNjYXBlX2h0bWwodGV4dCkge1xuICAgICAgICBjb25zdCBkaXYgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICAgICAgZGl2LnRleHRDb250ZW50ID0gdGV4dDtcbiAgICAgICAgcmV0dXJuIGRpdi5pbm5lckhUTUw7XG4gICAgfVxufVxuIiwiLy8gQEZJTEUtU1VCQ0xBU1MtMDEtRVhDRVBUSU9OXG5cbi8qKlxuICogQ2xpZW50LXNpZGUgQWpheCBjbGFzcyBmb3IgbWFraW5nIEFQSSBjYWxscyB0byBSU1ggY29udHJvbGxlcnNcbiAqXG4gKiBBdXRvbWF0aWNhbGx5IGJhdGNoZXMgbXVsdGlwbGUgY2FsbHMgaW50byBzaW5nbGUgSFRUUCByZXF1ZXN0cyB0byByZWR1Y2UgbmV0d29yayBvdmVyaGVhZC5cbiAqIEJhdGNoZXMgdXAgdG8gMjAgY2FsbHMgb3IgZmx1c2hlcyBhZnRlciBzZXRUaW1lb3V0KDApIGRlYm91bmNlLlxuICovXG5jbGFzcyBBamF4IHtcbiAgICAvKipcbiAgICAgKiBJbml0aWFsaXplIEFqYXggc3lzdGVtXG4gICAgICogQ2FsbGVkIGF1dG9tYXRpY2FsbHkgd2hlbiBjbGFzcyBpcyBsb2FkZWRcbiAgICAgKi9cbiAgICBzdGF0aWMgX29uX2ZyYW1ld29ya19jb3JlX2luaXQoKSB7XG4gICAgICAgIC8vIFF1ZXVlIG9mIHBlbmRpbmcgY2FsbHMgd2FpdGluZyB0byBiZSBiYXRjaGVkXG4gICAgICAgIEFqYXguX3BlbmRpbmdfY2FsbHMgPSB7fTtcblxuICAgICAgICAvLyBUaW1lciBmb3IgYmF0Y2hpbmcgZmx1c2hcbiAgICAgICAgQWpheC5fZmx1c2hfdGltZW91dCA9IG51bGw7XG5cbiAgICAgICAgLy8gQ2FsbCBjb3VudGVyIGZvciBnZW5lcmF0aW5nIHVuaXF1ZSBjYWxsIElEc1xuICAgICAgICBBamF4Ll9jYWxsX2NvdW50ZXIgPSAwO1xuXG4gICAgICAgIC8vIE1heGltdW0gYmF0Y2ggc2l6ZSBiZWZvcmUgZm9yY2luZyBpbW1lZGlhdGUgZmx1c2hcbiAgICAgICAgQWpheC5NQVhfQkFUQ0hfU0laRSA9IDIwO1xuXG4gICAgICAgIC8vIERlYm91bmNlIHRpbWUgaW4gbWlsbGlzZWNvbmRzXG4gICAgICAgIEFqYXguREVCT1VOQ0VfTVMgPSAwO1xuXG4gICAgICAgIC8vIFRyYWNrIHByb21pc2VzIGZyb20gQWpheCBjYWxscyB0byBkZXRlY3QgdW5jYXVnaHQgcmVqZWN0aW9uc1xuICAgICAgICBBamF4Ll90cmFja2VkX3Byb21pc2VzID0gbmV3IFdlYWtTZXQoKTtcblxuICAgICAgICAvLyBTZXQgdXAgZ2xvYmFsIHVuaGFuZGxlZCByZWplY3Rpb24gaGFuZGxlciBmb3IgQWpheCBlcnJvcnNcbiAgICAgICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ3VuaGFuZGxlZHJlamVjdGlvbicsIGFzeW5jIChldmVudCkgPT4ge1xuICAgICAgICAgICAgLy8gT25seSBoYW5kbGUgcmVqZWN0aW9ucyBmcm9tIEFqYXggcHJvbWlzZXNcbiAgICAgICAgICAgIGlmIChBamF4Ll90cmFja2VkX3Byb21pc2VzLmhhcyhldmVudC5wcm9taXNlKSkge1xuICAgICAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7IC8vIFByZXZlbnQgYnJvd3NlcidzIGRlZmF1bHQgXCJVbmNhdWdodCAoaW4gcHJvbWlzZSlcIiBlcnJvclxuXG4gICAgICAgICAgICAgICAgY29uc3QgZXJyb3IgPSBldmVudC5yZWFzb247XG4gICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcignVW5jYXVnaHQgQWpheCBlcnJvcjonLCBlcnJvcik7XG5cbiAgICAgICAgICAgICAgICAvLyBTaG93IE1vZGFsLmVycm9yKCkgZm9yIHVuY2F1Z2h0IEFqYXggZXJyb3JzXG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBNb2RhbCAhPT0gJ3VuZGVmaW5lZCcgJiYgTW9kYWwuZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgYXdhaXQgTW9kYWwuZXJyb3IoZXJyb3IsICdVbmNhdWdodCBBamF4IEVycm9yJyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBNYWtlIGFuIEFKQVggY2FsbCB0byBhbiBSU1ggY29udHJvbGxlciBhY3Rpb25cbiAgICAgKlxuICAgICAqIEFsbCBjYWxscyBhcmUgYXV0b21hdGljYWxseSBiYXRjaGVkIHVubGVzcyB3aW5kb3cucnN4YXBwLmFqYXhfZGlzYWJsZV9iYXRjaGluZyBpcyB0cnVlLlxuICAgICAqXG4gICAgICogQHBhcmFtIHtzdHJpbmd8b2JqZWN0fGZ1bmN0aW9ufSB1cmwgLSBUaGUgQWpheCBVUkwgKGUuZy4sICcvX2FqYXgvQ29udHJvbGxlcl9OYW1lL2FjdGlvbl9uYW1lJykgb3IgYW4gb2JqZWN0L2Z1bmN0aW9uIHdpdGggYSAucGF0aCBwcm9wZXJ0eVxuICAgICAqIEBwYXJhbSB7b2JqZWN0fSBwYXJhbXMgLSBQYXJhbWV0ZXJzIHRvIHNlbmQgdG8gdGhlIGFjdGlvblxuICAgICAqIEByZXR1cm5zIHtQcm9taXNlfSAtIFJlc29sdmVzIHdpdGggdGhlIHJldHVybiB2YWx1ZSwgcmVqZWN0cyB3aXRoIGVycm9yXG4gICAgICovXG4gICAgc3RhdGljIGFzeW5jIGNhbGwodXJsLCBwYXJhbXMgPSB7fSkge1xuICAgICAgICAvLyBJZiB1cmwgaXMgYW4gb2JqZWN0IG9yIGZ1bmN0aW9uIHdpdGggYSAucGF0aCBwcm9wZXJ0eSwgdXNlIHRoYXQgYXMgdGhlIFVSTFxuICAgICAgICBpZiAodXJsICYmIHR5cGVvZiB1cmwgPT09ICdvYmplY3QnICYmIHVybC5wYXRoKSB7XG4gICAgICAgICAgICB1cmwgPSB1cmwucGF0aDtcbiAgICAgICAgfSBlbHNlIGlmICh1cmwgJiYgdHlwZW9mIHVybCA9PT0gJ2Z1bmN0aW9uJyAmJiB1cmwucGF0aCkge1xuICAgICAgICAgICAgdXJsID0gdXJsLnBhdGg7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBWYWxpZGF0ZSB1cmwgaXMgYSBub24tZW1wdHkgc3RyaW5nXG4gICAgICAgIGlmICh0eXBlb2YgdXJsICE9PSAnc3RyaW5nJyB8fCB1cmwubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0FqYXguY2FsbCgpIHJlcXVpcmVzIGEgbm9uLWVtcHR5IHN0cmluZyBVUkwgb3IgYW4gb2JqZWN0L2Z1bmN0aW9uIHdpdGggYSAucGF0aCBwcm9wZXJ0eScpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gRXh0cmFjdCBjb250cm9sbGVyIGFuZCBhY3Rpb24gZnJvbSBVUkxcbiAgICAgICAgY29uc3QgeyBjb250cm9sbGVyLCBhY3Rpb24gfSA9IEFqYXguYWpheF91cmxfdG9fY29udHJvbGxlcl9hY3Rpb24odXJsKTtcblxuICAgICAgICBjb25zb2xlLmxvZygnQWpheDonLCBjb250cm9sbGVyLCBhY3Rpb24sIHBhcmFtcyk7XG5cbiAgICAgICAgLy8gQ2hlY2sgaWYgYmF0Y2hpbmcgaXMgZGlzYWJsZWQgZm9yIGRlYnVnZ2luZ1xuICAgICAgICBsZXQgcHJvbWlzZTtcbiAgICAgICAgaWYgKHdpbmRvdy5yc3hhcHAgJiYgd2luZG93LnJzeGFwcC5hamF4X2Rpc2FibGVfYmF0Y2hpbmcpIHtcbiAgICAgICAgICAgIHByb21pc2UgPSBBamF4Ll9jYWxsX2RpcmVjdChjb250cm9sbGVyLCBhY3Rpb24sIHBhcmFtcyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBwcm9taXNlID0gQWpheC5fY2FsbF9iYXRjaChjb250cm9sbGVyLCBhY3Rpb24sIHBhcmFtcyk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBUcmFjayB0aGlzIHByb21pc2UgZm9yIHVuaGFuZGxlZCByZWplY3Rpb24gZGV0ZWN0aW9uXG4gICAgICAgIEFqYXguX3RyYWNrZWRfcHJvbWlzZXMuYWRkKHByb21pc2UpO1xuXG4gICAgICAgIHJldHVybiBwcm9taXNlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIE1ha2UgYSBiYXRjaGVkIEFqYXggY2FsbFxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG4gICAgc3RhdGljIF9jYWxsX2JhdGNoKGNvbnRyb2xsZXIsIGFjdGlvbiwgcGFyYW1zID0ge30pIHtcbiAgICAgICAgY29uc29sZS5sb2coJ0FqYXggQmF0Y2g6JywgY29udHJvbGxlciwgYWN0aW9uLCBwYXJhbXMpO1xuXG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICAvLyBHZW5lcmF0ZSBjYWxsIGtleSBmb3IgZGVkdXBsaWNhdGlvblxuICAgICAgICAgICAgY29uc3QgY2FsbF9rZXkgPSBBamF4Ll9nZW5lcmF0ZV9jYWxsX2tleShjb250cm9sbGVyLCBhY3Rpb24sIHBhcmFtcyk7XG5cbiAgICAgICAgICAgIC8vIENoZWNrIGlmIHRoaXMgZXhhY3QgY2FsbCBpcyBhbHJlYWR5IHBlbmRpbmdcbiAgICAgICAgICAgIGlmIChBamF4Ll9wZW5kaW5nX2NhbGxzW2NhbGxfa2V5XSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IGV4aXN0aW5nX2NhbGwgPSBBamF4Ll9wZW5kaW5nX2NhbGxzW2NhbGxfa2V5XTtcblxuICAgICAgICAgICAgICAgIC8vIElmIGNhbGwgYWxyZWFkeSBjb21wbGV0ZWQgKGNhY2hlZCksIHJldHVybiBpbW1lZGlhdGVseVxuICAgICAgICAgICAgICAgIGlmIChleGlzdGluZ19jYWxsLmlzX2NvbXBsZXRlKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChleGlzdGluZ19jYWxsLmlzX2Vycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZWplY3QoZXhpc3RpbmdfY2FsbC5lcnJvcik7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKGV4aXN0aW5nX2NhbGwucmVzdWx0KTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgLy8gQ2FsbCBpcyBwZW5kaW5nLCBhZGQgdGhpcyBwcm9taXNlIHRvIGNhbGxiYWNrc1xuICAgICAgICAgICAgICAgIGV4aXN0aW5nX2NhbGwuY2FsbGJhY2tzLnB1c2goeyByZXNvbHZlLCByZWplY3QgfSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBDcmVhdGUgbmV3IHBlbmRpbmcgY2FsbFxuICAgICAgICAgICAgY29uc3QgY2FsbF9pZCA9IEFqYXguX2NhbGxfY291bnRlcisrO1xuICAgICAgICAgICAgY29uc3QgcGVuZGluZ19jYWxsID0ge1xuICAgICAgICAgICAgICAgIGNhbGxfaWQ6IGNhbGxfaWQsXG4gICAgICAgICAgICAgICAgY2FsbF9rZXk6IGNhbGxfa2V5LFxuICAgICAgICAgICAgICAgIGNvbnRyb2xsZXI6IGNvbnRyb2xsZXIsXG4gICAgICAgICAgICAgICAgYWN0aW9uOiBhY3Rpb24sXG4gICAgICAgICAgICAgICAgcGFyYW1zOiBwYXJhbXMsXG4gICAgICAgICAgICAgICAgY2FsbGJhY2tzOiBbeyByZXNvbHZlLCByZWplY3QgfV0sXG4gICAgICAgICAgICAgICAgaXNfY29tcGxldGU6IGZhbHNlLFxuICAgICAgICAgICAgICAgIGlzX2Vycm9yOiBmYWxzZSxcbiAgICAgICAgICAgICAgICByZXN1bHQ6IG51bGwsXG4gICAgICAgICAgICAgICAgZXJyb3I6IG51bGwsXG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAvLyBBZGQgdG8gcGVuZGluZyBxdWV1ZVxuICAgICAgICAgICAgQWpheC5fcGVuZGluZ19jYWxsc1tjYWxsX2tleV0gPSBwZW5kaW5nX2NhbGw7XG5cbiAgICAgICAgICAgIC8vIENvdW50IHBlbmRpbmcgY2FsbHNcbiAgICAgICAgICAgIGNvbnN0IHBlbmRpbmdfY291bnQgPSBPYmplY3Qua2V5cyhBamF4Ll9wZW5kaW5nX2NhbGxzKS5maWx0ZXIoKGtleSkgPT4gIUFqYXguX3BlbmRpbmdfY2FsbHNba2V5XS5pc19jb21wbGV0ZSkubGVuZ3RoO1xuXG4gICAgICAgICAgICAvLyBJZiB3ZSd2ZSBoaXQgdGhlIGJhdGNoIHNpemUgbGltaXQsIGZsdXNoIGltbWVkaWF0ZWx5XG4gICAgICAgICAgICBpZiAocGVuZGluZ19jb3VudCA+PSBBamF4Lk1BWF9CQVRDSF9TSVpFKSB7XG4gICAgICAgICAgICAgICAgY2xlYXJUaW1lb3V0KEFqYXguX2ZsdXNoX3RpbWVvdXQpO1xuICAgICAgICAgICAgICAgIEFqYXguX2ZsdXNoX3RpbWVvdXQgPSBudWxsO1xuICAgICAgICAgICAgICAgIEFqYXguX2ZsdXNoX3BlbmRpbmdfY2FsbHMoKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgLy8gU2NoZWR1bGUgYmF0Y2ggZmx1c2ggd2l0aCBkZWJvdW5jZVxuICAgICAgICAgICAgICAgIGNsZWFyVGltZW91dChBamF4Ll9mbHVzaF90aW1lb3V0KTtcbiAgICAgICAgICAgICAgICBBamF4Ll9mbHVzaF90aW1lb3V0ID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIEFqYXguX2ZsdXNoX3BlbmRpbmdfY2FsbHMoKTtcbiAgICAgICAgICAgICAgICB9LCBBamF4LkRFQk9VTkNFX01TKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogTWFrZSBhIGRpcmVjdCAobm9uLWJhdGNoZWQpIEFqYXggY2FsbFxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG4gICAgc3RhdGljIGFzeW5jIF9jYWxsX2RpcmVjdChjb250cm9sbGVyLCBhY3Rpb24sIHBhcmFtcyA9IHt9KSB7XG4gICAgICAgIC8vIENvbnN0cnVjdCBVUkwgZnJvbSBjb250cm9sbGVyIGFuZCBhY3Rpb25cbiAgICAgICAgY29uc3QgdXJsID0gYC9fYWpheC8ke2NvbnRyb2xsZXJ9LyR7YWN0aW9ufWA7XG5cbiAgICAgICAgLy8gTG9nIHRoZSBBSkFYIGNhbGwgdXNpbmcgY29uc29sZV9kZWJ1Z1xuICAgICAgICBpZiAodHlwZW9mIERlYnVnZ2VyICE9PSAndW5kZWZpbmVkJyAmJiBEZWJ1Z2dlci5jb25zb2xlX2RlYnVnKSB7XG4gICAgICAgICAgICBEZWJ1Z2dlci5jb25zb2xlX2RlYnVnKCdBSkFYJywgYENhbGxpbmcgJHtjb250cm9sbGVyfS4ke2FjdGlvbn0gKHVuYmF0Y2hlZClgLCBwYXJhbXMpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgICQuYWpheCh7XG4gICAgICAgICAgICAgICAgdXJsOiB1cmwsXG4gICAgICAgICAgICAgICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgICAgICAgICAgICAgZGF0YTogcGFyYW1zLFxuICAgICAgICAgICAgICAgIGRhdGFUeXBlOiAnanNvbicsXG4gICAgICAgICAgICAgICAgX19sb2NhbF9pbnRlZ3JhdGlvbjogdHJ1ZSwgLy8gQnlwYXNzICQuYWpheCBvdmVycmlkZVxuICAgICAgICAgICAgICAgIHN1Y2Nlc3M6IChyZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAvLyBIYW5kbGUgY29uc29sZV9kZWJ1ZyBtZXNzYWdlc1xuICAgICAgICAgICAgICAgICAgICBpZiAocmVzcG9uc2UuY29uc29sZV9kZWJ1ZyAmJiBBcnJheS5pc0FycmF5KHJlc3BvbnNlLmNvbnNvbGVfZGVidWcpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXNwb25zZS5jb25zb2xlX2RlYnVnLmZvckVhY2goKG1zZykgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghQXJyYXkuaXNBcnJheShtc2cpIHx8IG1zZy5sZW5ndGggIT09IDIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGNvbnNvbGVfZGVidWcgbWVzc2FnZSBmb3JtYXQgLSBleHBlY3RlZCBbY2hhbm5lbCwgW2FyZ3VtZW50c11dJyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFtjaGFubmVsLCBhcmdzXSA9IG1zZztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhjaGFubmVsLCAuLi5hcmdzKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgLy8gQ2hlY2sgaWYgdGhlIHJlc3BvbnNlIHdhcyBzdWNjZXNzZnVsXG4gICAgICAgICAgICAgICAgICAgIGlmIChyZXNwb25zZS5fc3VjY2VzcyA9PT0gdHJ1ZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gQEpTLUFKQVgtMDItRVhDRVBUSU9OIC0gVW53cmFwIHNlcnZlciByZXNwb25zZXMgd2l0aCBfYWpheF9yZXR1cm5fdmFsdWVcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHByb2Nlc3NlZF92YWx1ZSA9IFJzeF9Kc19Nb2RlbC5faW5zdGFudGlhdGVfbW9kZWxzX3JlY3Vyc2l2ZShyZXNwb25zZS5fYWpheF9yZXR1cm5fdmFsdWUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZShwcm9jZXNzZWRfdmFsdWUpO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gSGFuZGxlIGVycm9yIHJlc3BvbnNlc1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZXJyb3JfdHlwZSA9IHJlc3BvbnNlLmVycm9yX3R5cGUgfHwgJ3Vua25vd25fZXJyb3InO1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgcmVhc29uID0gcmVzcG9uc2UucmVhc29uIHx8ICdVbmtub3duIGVycm9yIG9jY3VycmVkJztcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGRldGFpbHMgPSByZXNwb25zZS5kZXRhaWxzIHx8IHt9O1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBIYW5kbGUgc3BlY2lmaWMgZXJyb3IgdHlwZXNcbiAgICAgICAgICAgICAgICAgICAgICAgIHN3aXRjaCAoZXJyb3JfdHlwZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgJ2ZhdGFsJzpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gRmF0YWwgUEhQIGVycm9yIHdpdGggZnVsbCBlcnJvciBkZXRhaWxzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGZhdGFsX2Vycm9yX2RhdGEgPSByZXNwb25zZS5lcnJvciB8fCB7fTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZXJyb3JfbWVzc2FnZSA9IGZhdGFsX2Vycm9yX2RhdGEuZXJyb3IgfHwgJ0ZhdGFsIGVycm9yIG9jY3VycmVkJztcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKCdBamF4IGVycm9yIHJlc3BvbnNlIGZyb20gc2VydmVyOicsIHJlc3BvbnNlLmVycm9yKTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBmYXRhbF9lcnJvciA9IG5ldyBFcnJvcihlcnJvcl9tZXNzYWdlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmF0YWxfZXJyb3IudHlwZSA9ICdmYXRhbCc7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZhdGFsX2Vycm9yLmRldGFpbHMgPSByZXNwb25zZS5lcnJvcjtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBMb2cgdG8gc2VydmVyIGlmIGJyb3dzZXIgZXJyb3IgbG9nZ2luZyBpcyBlbmFibGVkXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERlYnVnZ2VyLmxvZ19lcnJvcih7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlOiBgQWpheCBGYXRhbCBFcnJvcjogJHtlcnJvcl9tZXNzYWdlfWAsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlOiAnYWpheF9mYXRhbCcsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbmRwb2ludDogdXJsLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGV0YWlsczogcmVzcG9uc2UuZXJyb3IsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChmYXRhbF9lcnJvcik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAncmVzcG9uc2VfYXV0aF9yZXF1aXJlZCc6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnVGhlIHVzZXIgaXMgbm8gbG9uZ2VyIGF1dGhlbnRpY2F0ZWQsIHRoaXMgaXMgYSBwbGFjZWhvbGRlciBmb3IgZnV0dXJlIGNvZGUgd2hpY2ggaGFuZGxlcyB0aGlzIHNjZW5hcmlvLidcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgYXV0aF9lcnJvciA9IG5ldyBFcnJvcihyZWFzb24pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhdXRoX2Vycm9yLnR5cGUgPSAnYXV0aF9yZXF1aXJlZCc7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF1dGhfZXJyb3IuZGV0YWlscyA9IGRldGFpbHM7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChhdXRoX2Vycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlICdyZXNwb25zZV91bmF1dGhvcml6ZWQnOlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ1RoZSB1c2VyIGlzIHVuYXV0aG9yaXplZCB0byBwZXJmb3JtIHRoaXMgYWN0aW9uLCB0aGlzIGlzIGEgcGxhY2Vob2xkZXIgZm9yIGZ1dHVyZSBjb2RlIHdoaWNoIGhhbmRsZXMgdGhpcyBzY2VuYXJpby4nXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHVuYXV0aF9lcnJvciA9IG5ldyBFcnJvcihyZWFzb24pO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bmF1dGhfZXJyb3IudHlwZSA9ICd1bmF1dGhvcml6ZWQnO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bmF1dGhfZXJyb3IuZGV0YWlscyA9IGRldGFpbHM7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdCh1bmF1dGhfZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgJ3Jlc3BvbnNlX2Zvcm1fZXJyb3InOlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBmb3JtX2Vycm9yID0gbmV3IEVycm9yKHJlYXNvbik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvcm1fZXJyb3IudHlwZSA9ICdmb3JtX2Vycm9yJztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9ybV9lcnJvci5kZXRhaWxzID0gZGV0YWlscztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGZvcm1fZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGdlbmVyaWNfZXJyb3IgPSBuZXcgRXJyb3IocmVhc29uKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2VuZXJpY19lcnJvci50eXBlID0gZXJyb3JfdHlwZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2VuZXJpY19lcnJvci5kZXRhaWxzID0gZGV0YWlscztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGdlbmVyaWNfZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgZXJyb3I6ICh4aHIsIHN0YXR1cywgZXJyb3IpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZXJyb3JfbWVzc2FnZSA9IEFqYXguX2V4dHJhY3RfZXJyb3JfbWVzc2FnZSh4aHIpO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBuZXR3b3JrX2Vycm9yID0gbmV3IEVycm9yKGVycm9yX21lc3NhZ2UpO1xuICAgICAgICAgICAgICAgICAgICBuZXR3b3JrX2Vycm9yLnR5cGUgPSAnbmV0d29ya19lcnJvcic7XG4gICAgICAgICAgICAgICAgICAgIG5ldHdvcmtfZXJyb3Iuc3RhdHVzID0geGhyLnN0YXR1cztcbiAgICAgICAgICAgICAgICAgICAgbmV0d29ya19lcnJvci5zdGF0dXNUZXh0ID0gc3RhdHVzO1xuXG4gICAgICAgICAgICAgICAgICAgIC8vIExvZyBzZXJ2ZXIgZXJyb3JzICg1MDArKSB0byB0aGUgc2VydmVyIGlmIGJyb3dzZXIgZXJyb3IgbG9nZ2luZyBpcyBlbmFibGVkXG4gICAgICAgICAgICAgICAgICAgIGlmICh4aHIuc3RhdHVzID49IDUwMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgRGVidWdnZXIubG9nX2Vycm9yKHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlOiBgQWpheCBTZXJ2ZXIgRXJyb3IgJHt4aHIuc3RhdHVzfTogJHtlcnJvcl9tZXNzYWdlfWAsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZTogJ2FqYXhfc2VydmVyX2Vycm9yJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbmRwb2ludDogdXJsLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXR1czogeGhyLnN0YXR1cyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGF0dXNUZXh0OiBzdGF0dXMsXG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIHJlamVjdChuZXR3b3JrX2Vycm9yKTtcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEZsdXNoIGFsbCBwZW5kaW5nIGNhbGxzIGJ5IHNlbmRpbmcgYmF0Y2ggcmVxdWVzdFxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG4gICAgc3RhdGljIGFzeW5jIF9mbHVzaF9wZW5kaW5nX2NhbGxzKCkge1xuICAgICAgICAvLyBDb2xsZWN0IGFsbCBwZW5kaW5nIGNhbGxzXG4gICAgICAgIGNvbnN0IGNhbGxzX3RvX3NlbmQgPSBbXTtcbiAgICAgICAgY29uc3QgY2FsbF9tYXAgPSB7fTsgLy8gTWFwIGNhbGxfaWQgdG8gcGVuZGluZ19jYWxsIG9iamVjdFxuXG4gICAgICAgIGZvciAoY29uc3QgY2FsbF9rZXkgaW4gQWpheC5fcGVuZGluZ19jYWxscykge1xuICAgICAgICAgICAgY29uc3QgcGVuZGluZ19jYWxsID0gQWpheC5fcGVuZGluZ19jYWxsc1tjYWxsX2tleV07XG5cbiAgICAgICAgICAgIGlmICghcGVuZGluZ19jYWxsLmlzX2NvbXBsZXRlKSB7XG4gICAgICAgICAgICAgICAgY2FsbHNfdG9fc2VuZC5wdXNoKHtcbiAgICAgICAgICAgICAgICAgICAgY2FsbF9pZDogcGVuZGluZ19jYWxsLmNhbGxfaWQsXG4gICAgICAgICAgICAgICAgICAgIGNvbnRyb2xsZXI6IHBlbmRpbmdfY2FsbC5jb250cm9sbGVyLFxuICAgICAgICAgICAgICAgICAgICBhY3Rpb246IHBlbmRpbmdfY2FsbC5hY3Rpb24sXG4gICAgICAgICAgICAgICAgICAgIHBhcmFtczogcGVuZGluZ19jYWxsLnBhcmFtcyxcbiAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICAgIGNhbGxfbWFwW3BlbmRpbmdfY2FsbC5jYWxsX2lkXSA9IHBlbmRpbmdfY2FsbDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIC8vIE5vdGhpbmcgdG8gc2VuZFxuICAgICAgICBpZiAoY2FsbHNfdG9fc2VuZC5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIExvZyBiYXRjaCBmb3IgZGVidWdnaW5nXG4gICAgICAgIGlmICh0eXBlb2YgRGVidWdnZXIgIT09ICd1bmRlZmluZWQnICYmIERlYnVnZ2VyLmNvbnNvbGVfZGVidWcpIHtcbiAgICAgICAgICAgIERlYnVnZ2VyLmNvbnNvbGVfZGVidWcoXG4gICAgICAgICAgICAgICAgJ0FKQVhfQkFUQ0gnLFxuICAgICAgICAgICAgICAgIGBTZW5kaW5nIGJhdGNoIG9mICR7Y2FsbHNfdG9fc2VuZC5sZW5ndGh9IGNhbGxzYCxcbiAgICAgICAgICAgICAgICBjYWxsc190b19zZW5kLm1hcCgoYykgPT4gYCR7Yy5jb250cm9sbGVyfS4ke2MuYWN0aW9ufWApXG4gICAgICAgICAgICApO1xuICAgICAgICB9XG5cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIC8vIFNlbmQgYmF0Y2ggcmVxdWVzdFxuICAgICAgICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCAkLmFqYXgoe1xuICAgICAgICAgICAgICAgIHVybDogJy9fYWpheC9fYmF0Y2gnLFxuICAgICAgICAgICAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgICAgICAgICAgIGRhdGE6IHsgYmF0Y2hfY2FsbHM6IEpTT04uc3RyaW5naWZ5KGNhbGxzX3RvX3NlbmQpIH0sXG4gICAgICAgICAgICAgICAgZGF0YVR5cGU6ICdqc29uJyxcbiAgICAgICAgICAgICAgICBfX2xvY2FsX2ludGVncmF0aW9uOiB0cnVlLCAvLyBCeXBhc3MgJC5hamF4IG92ZXJyaWRlXG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgLy8gUHJvY2VzcyBiYXRjaCByZXNwb25zZVxuICAgICAgICAgICAgLy8gUmVzcG9uc2UgZm9ybWF0OiB7IENfMDoge3N1Y2Nlc3MsIF9hamF4X3JldHVybl92YWx1ZX0sIENfMTogey4uLn0sIC4uLiB9XG4gICAgICAgICAgICBmb3IgKGNvbnN0IHJlc3BvbnNlX2tleSBpbiByZXNwb25zZSkge1xuICAgICAgICAgICAgICAgIGlmICghcmVzcG9uc2Vfa2V5LnN0YXJ0c1dpdGgoJ0NfJykpIHtcbiAgICAgICAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgY29uc3QgY2FsbF9pZCA9IHBhcnNlSW50KHJlc3BvbnNlX2tleS5zdWJzdHJpbmcoMiksIDEwKTtcbiAgICAgICAgICAgICAgICBjb25zdCBjYWxsX3Jlc3BvbnNlID0gcmVzcG9uc2VbcmVzcG9uc2Vfa2V5XTtcbiAgICAgICAgICAgICAgICBjb25zdCBwZW5kaW5nX2NhbGwgPSBjYWxsX21hcFtjYWxsX2lkXTtcblxuICAgICAgICAgICAgICAgIGlmICghcGVuZGluZ19jYWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ1JlY2VpdmVkIHJlc3BvbnNlIGZvciB1bmtub3duIGNhbGxfaWQ6JywgY2FsbF9pZCk7XG4gICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIC8vIEhhbmRsZSBjb25zb2xlX2RlYnVnIG1lc3NhZ2VzIGlmIHByZXNlbnRcbiAgICAgICAgICAgICAgICBpZiAoY2FsbF9yZXNwb25zZS5jb25zb2xlX2RlYnVnICYmIEFycmF5LmlzQXJyYXkoY2FsbF9yZXNwb25zZS5jb25zb2xlX2RlYnVnKSkge1xuICAgICAgICAgICAgICAgICAgICBjYWxsX3Jlc3BvbnNlLmNvbnNvbGVfZGVidWcuZm9yRWFjaCgobXNnKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkobXNnKSB8fCBtc2cubGVuZ3RoICE9PSAyKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGNvbnNvbGVfZGVidWcgbWVzc2FnZSBmb3JtYXQgLSBleHBlY3RlZCBbY2hhbm5lbCwgW2FyZ3VtZW50c11dJyk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBbY2hhbm5lbCwgYXJnc10gPSBtc2c7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhjaGFubmVsLCAuLi5hcmdzKTtcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgLy8gTWFyayBjYWxsIGFzIGNvbXBsZXRlXG4gICAgICAgICAgICAgICAgcGVuZGluZ19jYWxsLmlzX2NvbXBsZXRlID0gdHJ1ZTtcblxuICAgICAgICAgICAgICAgIC8vIENoZWNrIGlmIHN1Y2Nlc3NmdWxcbiAgICAgICAgICAgICAgICBpZiAoY2FsbF9yZXNwb25zZS5fc3VjY2VzcyA9PT0gdHJ1ZSkge1xuICAgICAgICAgICAgICAgICAgICAvLyBASlMtQUpBWC0wMi1FWENFUFRJT04gLSBCYXRjaCBzeXN0ZW0gdW53cmFwcyBzZXJ2ZXIgcmVzcG9uc2VzIHdpdGggX2FqYXhfcmV0dXJuX3ZhbHVlXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHByb2Nlc3NlZF92YWx1ZSA9IFJzeF9Kc19Nb2RlbC5faW5zdGFudGlhdGVfbW9kZWxzX3JlY3Vyc2l2ZShjYWxsX3Jlc3BvbnNlLl9hamF4X3JldHVybl92YWx1ZSk7XG4gICAgICAgICAgICAgICAgICAgIHBlbmRpbmdfY2FsbC5yZXN1bHQgPSBwcm9jZXNzZWRfdmFsdWU7XG5cbiAgICAgICAgICAgICAgICAgICAgLy8gUmVzb2x2ZSBhbGwgY2FsbGJhY2tzXG4gICAgICAgICAgICAgICAgICAgIHBlbmRpbmdfY2FsbC5jYWxsYmFja3MuZm9yRWFjaCgoeyByZXNvbHZlIH0pID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUocHJvY2Vzc2VkX3ZhbHVlKTtcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gSGFuZGxlIGVycm9yXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGVycm9yX3R5cGUgPSBjYWxsX3Jlc3BvbnNlLmVycm9yX3R5cGUgfHwgJ3Vua25vd25fZXJyb3InO1xuICAgICAgICAgICAgICAgICAgICBsZXQgZXJyb3JfbWVzc2FnZTtcbiAgICAgICAgICAgICAgICAgICAgbGV0IGVycm9yX2RldGFpbHM7XG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yX3R5cGUgPT09ICdmYXRhbCcgJiYgY2FsbF9yZXNwb25zZS5lcnJvcikge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gRmF0YWwgUEhQIGVycm9yIHdpdGggZnVsbCBlcnJvciBkZXRhaWxzXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBmYXRhbF9lcnJvcl9kYXRhID0gY2FsbF9yZXNwb25zZS5lcnJvcjtcbiAgICAgICAgICAgICAgICAgICAgICAgIGVycm9yX21lc3NhZ2UgPSBmYXRhbF9lcnJvcl9kYXRhLmVycm9yIHx8ICdGYXRhbCBlcnJvciBvY2N1cnJlZCc7XG4gICAgICAgICAgICAgICAgICAgICAgICBlcnJvcl9kZXRhaWxzID0gY2FsbF9yZXNwb25zZS5lcnJvcjtcblxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcignQWpheCBlcnJvciByZXNwb25zZSBmcm9tIHNlcnZlcjonLCBjYWxsX3Jlc3BvbnNlLmVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIE90aGVyIGVycm9yIHR5cGVzXG4gICAgICAgICAgICAgICAgICAgICAgICBlcnJvcl9tZXNzYWdlID0gY2FsbF9yZXNwb25zZS5yZWFzb24gfHwgJ1Vua25vd24gZXJyb3Igb2NjdXJyZWQnO1xuICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JfZGV0YWlscyA9IGNhbGxfcmVzcG9uc2UuZGV0YWlscyB8fCB7fTtcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGVycm9yID0gbmV3IEVycm9yKGVycm9yX21lc3NhZ2UpO1xuICAgICAgICAgICAgICAgICAgICBlcnJvci50eXBlID0gZXJyb3JfdHlwZTtcbiAgICAgICAgICAgICAgICAgICAgZXJyb3IuZGV0YWlscyA9IGVycm9yX2RldGFpbHM7XG5cbiAgICAgICAgICAgICAgICAgICAgcGVuZGluZ19jYWxsLmlzX2Vycm9yID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgcGVuZGluZ19jYWxsLmVycm9yID0gZXJyb3I7XG5cbiAgICAgICAgICAgICAgICAgICAgLy8gUmVqZWN0IGFsbCBjYWxsYmFja3NcbiAgICAgICAgICAgICAgICAgICAgcGVuZGluZ19jYWxsLmNhbGxiYWNrcy5mb3JFYWNoKCh7IHJlamVjdCB9KSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gY2F0Y2ggKHhocl9lcnJvcikge1xuICAgICAgICAgICAgLy8gTmV0d29yayBvciBzZXJ2ZXIgZXJyb3IgLSByZWplY3QgYWxsIHBlbmRpbmcgY2FsbHNcbiAgICAgICAgICAgIGNvbnN0IGVycm9yX21lc3NhZ2UgPSBBamF4Ll9leHRyYWN0X2Vycm9yX21lc3NhZ2UoeGhyX2Vycm9yKTtcbiAgICAgICAgICAgIGNvbnN0IGVycm9yID0gbmV3IEVycm9yKGVycm9yX21lc3NhZ2UpO1xuICAgICAgICAgICAgZXJyb3IudHlwZSA9ICduZXR3b3JrX2Vycm9yJztcblxuICAgICAgICAgICAgZm9yIChjb25zdCBjYWxsX2lkIGluIGNhbGxfbWFwKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgcGVuZGluZ19jYWxsID0gY2FsbF9tYXBbY2FsbF9pZF07XG4gICAgICAgICAgICAgICAgcGVuZGluZ19jYWxsLmlzX2NvbXBsZXRlID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICBwZW5kaW5nX2NhbGwuaXNfZXJyb3IgPSB0cnVlO1xuICAgICAgICAgICAgICAgIHBlbmRpbmdfY2FsbC5lcnJvciA9IGVycm9yO1xuXG4gICAgICAgICAgICAgICAgcGVuZGluZ19jYWxsLmNhbGxiYWNrcy5mb3JFYWNoKCh7IHJlamVjdCB9KSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0JhdGNoIEFqYXggcmVxdWVzdCBmYWlsZWQ6JywgZXJyb3JfbWVzc2FnZSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZW5lcmF0ZSBhIHVuaXF1ZSBrZXkgZm9yIGRlZHVwbGljYXRpbmcgY2FsbHNcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuICAgIHN0YXRpYyBfZ2VuZXJhdGVfY2FsbF9rZXkoY29udHJvbGxlciwgYWN0aW9uLCBwYXJhbXMpIHtcbiAgICAgICAgLy8gQ3JlYXRlIGEgc3RhYmxlIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgY2FsbFxuICAgICAgICAvLyBTb3J0IHBhcmFtcyBrZXlzIGZvciBjb25zaXN0ZW50IGhhc2hpbmdcbiAgICAgICAgY29uc3Qgc29ydGVkX3BhcmFtcyA9IHt9O1xuICAgICAgICBPYmplY3Qua2V5cyhwYXJhbXMpXG4gICAgICAgICAgICAuc29ydCgpXG4gICAgICAgICAgICAuZm9yRWFjaCgoa2V5KSA9PiB7XG4gICAgICAgICAgICAgICAgc29ydGVkX3BhcmFtc1trZXldID0gcGFyYW1zW2tleV07XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICByZXR1cm4gYCR7Y29udHJvbGxlcn06OiR7YWN0aW9ufTo6JHtKU09OLnN0cmluZ2lmeShzb3J0ZWRfcGFyYW1zKX1gO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEV4dHJhY3QgZXJyb3IgbWVzc2FnZSBmcm9tIGpRdWVyeSBYSFIgb2JqZWN0XG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cbiAgICBzdGF0aWMgX2V4dHJhY3RfZXJyb3JfbWVzc2FnZSh4aHIpIHtcbiAgICAgICAgaWYgKHhoci5yZXNwb25zZUpTT04gJiYgeGhyLnJlc3BvbnNlSlNPTi5tZXNzYWdlKSB7XG4gICAgICAgICAgICByZXR1cm4geGhyLnJlc3BvbnNlSlNPTi5tZXNzYWdlO1xuICAgICAgICB9IGVsc2UgaWYgKHhoci5yZXNwb25zZVRleHQpIHtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgY29uc3QgcmVzcG9uc2UgPSBKU09OLnBhcnNlKHhoci5yZXNwb25zZVRleHQpO1xuICAgICAgICAgICAgICAgIGlmIChyZXNwb25zZS5tZXNzYWdlKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiByZXNwb25zZS5tZXNzYWdlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgICAvLyBOb3QgSlNPTlxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGAke3hoci5zdGF0dXN9OiAke3hoci5zdGF0dXNUZXh0IHx8ICdVbmtub3duIGVycm9yJ31gO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFBhcnNlcyBhbiBBSkFYIFVSTCBpbnRvIGNvbnRyb2xsZXIgYW5kIGFjdGlvblxuICAgICAqIFN1cHBvcnRzIGJvdGggL19hamF4LyBhbmQgL18vIFVSTCBwcmVmaXhlc1xuICAgICAqIEBwYXJhbSB7c3RyaW5nfG9iamVjdHxmdW5jdGlvbn0gdXJsIC0gVVJMIGluIGZvcm1hdCAnL19hamF4L0NvbnRyb2xsZXJfTmFtZS9hY3Rpb25fbmFtZScgb3IgJy9fL0NvbnRyb2xsZXJfTmFtZS9hY3Rpb25fbmFtZScsIG9yIGFuIG9iamVjdC9mdW5jdGlvbiB3aXRoIGEgLnBhdGggcHJvcGVydHlcbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSBPYmplY3Qgd2l0aCB7Y29udHJvbGxlcjogc3RyaW5nLCBhY3Rpb246IHN0cmluZ31cbiAgICAgKiBAdGhyb3dzIHtFcnJvcn0gSWYgVVJMIGRvZXNuJ3Qgc3RhcnQgd2l0aCAvX2FqYXggb3IgL18gb3IgaGFzIGludmFsaWQgc3RydWN0dXJlXG4gICAgICovXG4gICAgc3RhdGljIGFqYXhfdXJsX3RvX2NvbnRyb2xsZXJfYWN0aW9uKHVybCkge1xuICAgICAgICAvLyBJZiB1cmwgaXMgYW4gb2JqZWN0IG9yIGZ1bmN0aW9uIHdpdGggYSAucGF0aCBwcm9wZXJ0eSwgdXNlIHRoYXQgYXMgdGhlIFVSTFxuICAgICAgICBpZiAodXJsICYmIHR5cGVvZiB1cmwgPT09ICdvYmplY3QnICYmIHVybC5wYXRoKSB7XG4gICAgICAgICAgICB1cmwgPSB1cmwucGF0aDtcbiAgICAgICAgfSBlbHNlIGlmICh1cmwgJiYgdHlwZW9mIHVybCA9PT0gJ2Z1bmN0aW9uJyAmJiB1cmwucGF0aCkge1xuICAgICAgICAgICAgdXJsID0gdXJsLnBhdGg7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBWYWxpZGF0ZSB1cmwgaXMgYSBzdHJpbmdcbiAgICAgICAgaWYgKHR5cGVvZiB1cmwgIT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFVSTCBtdXN0IGJlIGEgc3RyaW5nIG9yIGhhdmUgYSAucGF0aCBwcm9wZXJ0eSwgZ290OiAke3R5cGVvZiB1cmx9YCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIXVybC5zdGFydHNXaXRoKCcvX2FqYXgnKSAmJiAhdXJsLnN0YXJ0c1dpdGgoJy9fLycpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFVSTCBtdXN0IHN0YXJ0IHdpdGggL19hamF4IG9yIC9fLCBnb3Q6ICR7dXJsfWApO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgcGFydHMgPSB1cmwuc3BsaXQoJy8nKS5maWx0ZXIoKHBhcnQpID0+IHBhcnQgIT09ICcnKTtcblxuICAgICAgICBpZiAocGFydHMubGVuZ3RoIDwgMikge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBJbnZhbGlkIEFKQVggVVJMIHN0cnVjdHVyZTogJHt1cmx9YCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAocGFydHMubGVuZ3RoID4gMykge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBBSkFYIFVSTCBoYXMgdG9vIG1hbnkgc2VnbWVudHM6ICR7dXJsfWApO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgY29udHJvbGxlciA9IHBhcnRzWzFdO1xuICAgICAgICBjb25zdCBhY3Rpb24gPSBwYXJ0c1syXSB8fCAnaW5kZXgnO1xuXG4gICAgICAgIHJldHVybiB7IGNvbnRyb2xsZXIsIGFjdGlvbiB9O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEF1dG8taW5pdGlhbGl6ZSBzdGF0aWMgcHJvcGVydGllcyB3aGVuIGNsYXNzIGlzIGZpcnN0IGxvYWRlZFxuICAgICAqL1xuICAgIHN0YXRpYyBvbl9jb3JlX2RlZmluZSgpIHtcbiAgICAgICAgQWpheC5fb25fZnJhbWV3b3JrX2NvcmVfaW5pdCgpO1xuICAgIH1cbn1cbiIsIi8qKlxuICogSnFodG1sX0NvbXBvbmVudCAtIEJhc2UgY2xhc3MgZm9yIEpRSFRNTCBjb21wb25lbnRzIGluIFJTWCBmcmFtZXdvcmtcbiAqXG4gKiBUaGlzIGNsYXNzIHdyYXBzIHRoZSBqcWh0bWwuQ29tcG9uZW50IGZyb20gdGhlIG5wbSBwYWNrYWdlIGFuZCBwcm92aWRlc1xuICogdGhlIHN0YW5kYXJkIGludGVyZmFjZSBmb3IgUlNYIGNvbXBvbmVudHMgZm9sbG93aW5nIHRoZSBVcHBlcl9DYXNlIG5hbWluZyBjb252ZW50aW9uLlxuICpcbiAqIF9CYXNlX0pxaHRtbF9Db21wb25lbnQgaXMgaW1wb3J0ZWQgZnJvbSBucG0gdmlhIEpxaHRtbF9CdW5kbGUuXG4gKlxuICogQEluc3RhbnRpYXRhYmxlXG4gKi9cbmNsYXNzIEpxaHRtbF9Db21wb25lbnQgZXh0ZW5kcyBfQmFzZV9KcWh0bWxfQ29tcG9uZW50IHt9XG5cbi8vIFJTWCBtYW5pZmVzdCBhdXRvbWF0aWNhbGx5IG1ha2VzIGNsYXNzZXMgZ2xvYmFsIC0gbm8gbWFudWFsIGFzc2lnbm1lbnQgbmVlZGVkXG4iLCIvKipcbiAqIEpRSFRNTCBJbnRlZ3JhdGlvbiAtIEF1dG9tYXRpYyBjb21wb25lbnQgcmVnaXN0cmF0aW9uIGFuZCBiaW5kaW5nXG4gKlxuICogVGhpcyBtb2R1bGUgYXV0b21hdGljYWxseTpcbiAqIDEuIFJlZ2lzdGVycyBjb21wb25lbnQgY2xhc3NlcyB0aGF0IGV4dGVuZCBKcWh0bWxfQ29tcG9uZW50XG4gKiAyLiBCaW5kcyB0ZW1wbGF0ZXMgdG8gY29tcG9uZW50IGNsYXNzZXMgd2hlbiBuYW1lcyBtYXRjaFxuICogMy4gRW5hYmxlcyAkKHNlbGVjdG9yKS5jb21wb25lbnQoXCJDb21wb25lbnRfTmFtZVwiKSBzeW50YXhcbiAqL1xuY2xhc3MgSnFodG1sX0ludGVncmF0aW9uIHtcbiAgICAvKipcbiAgICAgKiBDb21waWxlZCBKcWh0bWwgdGVtcGxhdGVzIHNlbGYtcmVnaXN0ZXIuICBUaGUgZGV2ZWxvcGVyICh0aGUgZnJhbWV3b3JrIGluIHRoaXMgY2FzZSkgaXMgc3RpbGxcbiAgICAgKiByZXNwb25zaWJsZSBmb3IgcmVnaXN0ZXJpbmcgZXM2IGNvbXBvbmVudCBjbGFzc2VzIHdpdGgganFodG1sLiAgVGhpcyBkb2VzIHNvIGF0IGFuIGVhcmx5IHN0YWdlXG4gICAgICogb2YgZnJhbWV3b3JrIGluaXQuXG4gICAgICovXG4gICAgc3RhdGljIF9vbl9mcmFtZXdvcmtfbW9kdWxlc19kZWZpbmUoKSB7XG4gICAgICAgIGxldCBqcWh0bWxfY29tcG9uZW50cyA9IE1hbmlmZXN0LmdldF9leHRlbmRpbmcoJ0pxaHRtbF9Db21wb25lbnQnKTtcblxuICAgICAgICBjb25zb2xlX2RlYnVnKCdKUUhUTUxfSU5JVCcsICdSZWdpc3RlcmluZyAnICsganFodG1sX2NvbXBvbmVudHMubGVuZ3RoICsgJyBKcWh0bWwgQ29tcG9uZW50cycpO1xuXG4gICAgICAgIGZvciAobGV0IGNvbXBvbmVudCBvZiBqcWh0bWxfY29tcG9uZW50cykge1xuICAgICAgICAgICAganFodG1sLnJlZ2lzdGVyX2NvbXBvbmVudChjb21wb25lbnQuY2xhc3NfbmFtZSwgY29tcG9uZW50LmNsYXNzX29iamVjdCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBGcmFtZXdvcmsgbW9kdWxlcyBpbml0IHBoYXNlIC0gQmluZCBjb21wb25lbnRzIGFuZCBpbml0aWFsaXplIERPTVxuICAgICAqIFRoaXMgcnVucyBhZnRlciB0ZW1wbGF0ZXMgYXJlIHJlZ2lzdGVyZWQgdG8gYmluZCBjb21wb25lbnQgY2xhc3Nlc1xuICAgICAqIEBwYXJhbSB7alF1ZXJ5fSBbJHNjb3BlXSBPcHRpb25hbCBzY29wZSB0byBzZWFyY2ggd2l0aGluIChkZWZhdWx0cyB0byBib2R5KVxuICAgICAqIEByZXR1cm5zIHtBcnJheTxQcm9taXNlPnx1bmRlZmluZWR9IEFycmF5IG9mIHByb21pc2VzIGZvciByZWN1cnNpdmUgY2FsbHMsIHVuZGVmaW5lZCBmb3IgdG9wLWxldmVsXG4gICAgICovXG4gICAgc3RhdGljIF9vbl9mcmFtZXdvcmtfbW9kdWxlc19pbml0KCRzY29wZSkge1xuICAgICAgICBjb25zdCBpc190b3BfbGV2ZWwgPSAhJHNjb3BlO1xuICAgICAgICBjb25zdCBwcm9taXNlcyA9IFtdO1xuICAgICAgICBjb25zdCBjb21wb25lbnRzX25lZWRpbmdfaW5pdCA9ICgkc2NvcGUgfHwgJCgnYm9keScpKS5maW5kKCcuSnFodG1sX0NvbXBvbmVudF9Jbml0Jyk7XG4gICAgICAgIGlmIChjb21wb25lbnRzX25lZWRpbmdfaW5pdC5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICBjb25zb2xlX2RlYnVnKCdKUUhUTUxfSU5JVCcsIGBJbml0aWFsaXppbmcgJHtjb21wb25lbnRzX25lZWRpbmdfaW5pdC5sZW5ndGh9IERPTSBjb21wb25lbnRzYCk7XG4gICAgICAgIH1cblxuICAgICAgICBjb21wb25lbnRzX25lZWRpbmdfaW5pdC5lYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGNvbnN0ICRlbGVtZW50ID0gJCh0aGlzKTtcblxuICAgICAgICAgICAgLy8gU2tpcCBpZiBlbGVtZW50IGlzIG5vIGxvbmdlciBhdHRhY2hlZCB0byB0aGUgZG9jdW1lbnRcbiAgICAgICAgICAgIC8vIChtYXkgaGF2ZSBiZWVuIHJlbW92ZWQgYnkgYSBwYXJlbnQgY29tcG9uZW50J3MgLmVtcHR5KCkgY2FsbClcbiAgICAgICAgICAgIGlmICghZG9jdW1lbnQuY29udGFpbnMoJGVsZW1lbnRbMF0pKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBDaGVjayBpZiBhbnkgcGFyZW50IGhhcyBKcWh0bWxfQ29tcG9uZW50X0luaXQgY2xhc3MgLSBza2lwIG5lc3RlZCBjb21wb25lbnRzXG4gICAgICAgICAgICBsZXQgcGFyZW50ID0gJGVsZW1lbnRbMF0ucGFyZW50RWxlbWVudDtcbiAgICAgICAgICAgIHdoaWxlIChwYXJlbnQpIHtcbiAgICAgICAgICAgICAgICBpZiAocGFyZW50LmNsYXNzTGlzdC5jb250YWlucygnSnFodG1sX0NvbXBvbmVudF9Jbml0JykpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuOyAvLyBTa2lwIHRoaXMgZWxlbWVudCwgaXQncyBuZXN0ZWRcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcGFyZW50ID0gcGFyZW50LnBhcmVudEVsZW1lbnQ7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbnN0IGNvbXBvbmVudF9uYW1lID0gJGVsZW1lbnQuYXR0cignZGF0YS1jb21wb25lbnQtaW5pdC1uYW1lJyk7XG5cbiAgICAgICAgICAgIC8vIGpRdWVyeSdzIC5kYXRhKCkgZG9lc24ndCBhdXRvLXBhcnNlIEpTT04gLSB3ZSBuZWVkIHRvIHBhcnNlIGl0IG1hbnVhbGx5XG4gICAgICAgICAgICBsZXQgY29tcG9uZW50X2FyZ3MgPSB7fTtcbiAgICAgICAgICAgIGNvbnN0IGFyZ3Nfc3RyaW5nID0gJGVsZW1lbnQuYXR0cignZGF0YS1jb21wb25lbnQtYXJncycpO1xuXG4gICAgICAgICAgICAvLyBVbnNldCBjb21wb25lbnQtIHBocCBzaWRlIGluaXRpYWxpemF0aW9uIGFyZ3MsIGl0IGlzIG5vIGxvbmdlciBuZWVkZWQgYXMgYSBjb21waW9uZW50IGF0dHJpYnV0ZVxuICAgICAgICAgICAgLy8gVW5zZXR0aW5nIGFsc28gcHJldmVudHMgdW5kZXNpcmVkIGFjY2VzcyB0byB0aGlzIGNvZGUgaW4gb3RoZXIgcGFydHMgb2YgdGhlIHByb2dyYW0sIHByZXZlbmluZyBhblxuICAgICAgICAgICAgLy8gdW53YW50ZWQgZnV0dXJlIGRlcGVuZGVuY3kgb24gdGhpcyBwYXJhZGlnbVxuICAgICAgICAgICAgJGVsZW1lbnQucmVtb3ZlQXR0cignZGF0YS1jb21wb25lbnQtaW5pdC1uYW1lJyk7XG4gICAgICAgICAgICAkZWxlbWVudC5yZW1vdmVBdHRyKCdkYXRhLWNvbXBvbmVudC1hcmdzJyk7XG4gICAgICAgICAgICAkZWxlbWVudC5yZW1vdmVEYXRhKCdjb21wb25lbnQtaW5pdC1uYW1lJyk7XG4gICAgICAgICAgICAkZWxlbWVudC5yZW1vdmVEYXRhKCdjb21wb25lbnQtYXJncycpO1xuXG4gICAgICAgICAgICBpZiAoYXJnc19zdHJpbmcpIHtcbiAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICBjb21wb25lbnRfYXJncyA9IEpTT04ucGFyc2UoYXJnc19zdHJpbmcpO1xuICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihgW0pRSFRNTCBJbnRlZ3JhdGlvbl0gRmFpbGVkIHRvIHBhcnNlIGNvbXBvbmVudCBhcmdzIGZvciAke2NvbXBvbmVudF9uYW1lfTpgLCBlKTtcbiAgICAgICAgICAgICAgICAgICAgY29tcG9uZW50X2FyZ3MgPSB7fTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChjb21wb25lbnRfbmFtZSkge1xuICAgICAgICAgICAgICAgIC8vIFRyYW5zZm9ybSAkIHByZWZpeGVkIGtleXMgdG8gZGF0YS0gYXR0cmlidXRlc1xuICAgICAgICAgICAgICAgIGxldCBjb21wb25lbnRfYXJnc19maWx0ZXJlZCA9IHt9O1xuICAgICAgICAgICAgICAgIGZvciAoY29uc3QgW2tleSwgdmFsdWVdIG9mIE9iamVjdC5lbnRyaWVzKGNvbXBvbmVudF9hcmdzKSkge1xuICAgICAgICAgICAgICAgICAgICAvLyBpZiAoa2V5LnN0YXJ0c1dpdGgoJyQnKSkge1xuICAgICAgICAgICAgICAgICAgICAvLyBjb21wb25lbnRfYXJnc19maWx0ZXJlZFtrZXkuc3Vic3RyaW5nKDEpXSA9IHZhbHVlO1xuICAgICAgICAgICAgICAgICAgICAvLyB9IGVsc2VcbiAgICAgICAgICAgICAgICAgICAgaWYgKGtleS5zdGFydHNXaXRoKCdkYXRhLScpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb21wb25lbnRfYXJnc19maWx0ZXJlZFtrZXkuc3Vic3RyaW5nKDUpXSA9IHZhbHVlO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29tcG9uZW50X2FyZ3NfZmlsdGVyZWRba2V5XSA9IHZhbHVlO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgLy8gU3RvcmUgaW5uZXIgSFRNTCBhcyBzdHJpbmcgZm9yIG5lc3RlZCBjb21wb25lbnQgcHJvY2Vzc2luZ1xuICAgICAgICAgICAgICAgICAgICBjb21wb25lbnRfYXJnc19maWx0ZXJlZC5faW5uZXJfaHRtbCA9ICRlbGVtZW50Lmh0bWwoKTtcbiAgICAgICAgICAgICAgICAgICAgJGVsZW1lbnQuZW1wdHkoKTtcblxuICAgICAgICAgICAgICAgICAgICAvLyBSZW1vdmUgdGhlIGluaXQgY2xhc3MgYmVmb3JlIGluc3RhbnRpYXRpb24gdG8gcHJldmVudCByZS1pbml0aWFsaXphdGlvblxuICAgICAgICAgICAgICAgICAgICAkZWxlbWVudC5yZW1vdmVDbGFzcygnSnFodG1sX0NvbXBvbmVudF9Jbml0Jyk7XG5cbiAgICAgICAgICAgICAgICAgICAgLy8gQ3JlYXRlIHByb21pc2UgZm9yIHRoaXMgY29tcG9uZW50J3MgaW5pdGlhbGl6YXRpb25cbiAgICAgICAgICAgICAgICAgICAgY29uc3QgY29tcG9uZW50X3Byb21pc2UgPSBuZXcgUHJvbWlzZSgocmVzb2x2ZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gVXNlIGpRdWVyeSBjb21wb25lbnQgcGx1Z2luIHRvIGNyZWF0ZSB0aGUgY29tcG9uZW50XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBQbHVnaW4gaGFuZGxlcyBlbGVtZW50IGludGVybmFsbHksIGp1c3QgcGFzcyBhcmdzXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBHZXQgdGhlIHVwZGF0ZWQgJGVsZW1lbnQgZnJvbVxuICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGNvbXBvbmVudCA9ICRlbGVtZW50LmNvbXBvbmVudChjb21wb25lbnRfbmFtZSwgY29tcG9uZW50X2FyZ3NfZmlsdGVyZWQpO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBjb21wb25lbnQub24oJ3JlbmRlcicsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBSZWN1cnNpdmVseSBjb2xsZWN0IHByb21pc2VzIGZyb20gbmVzdGVkIGNvbXBvbmVudHNcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEdldHRpbmcgdGhlIHVwZGF0ZWQgY29tcG9uZW50IGhlcmUgLSBpZiB0aGUgdGFnIG5hbWUgd2FzIG5vdCBkaXYsIHRoZSBlbGVtZW50IHdvdWxkIGhhdmUgYmVlbiByZWNyZWF0ZWQsIHNvIHdlIG5lZWQgdG8gZ2V0IHRoZSBlbGVtZW50IHNldCBvbiB0aGUgY29tcG9uZW50LCBub3QgZnJvbSBvdXIgZWFybGllciBzZWxlY3RvclxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbmVzdGVkX3Byb21pc2VzID0gSnFodG1sX0ludGVncmF0aW9uLl9vbl9mcmFtZXdvcmtfbW9kdWxlc19pbml0KGNvbXBvbmVudC4kKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcm9taXNlcy5wdXNoKC4uLm5lc3RlZF9wcm9taXNlcyk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBSZXNvbHZlIHRoaXMgY29tcG9uZW50J3MgcHJvbWlzZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pLiQ7XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICAgICAgIHByb21pc2VzLnB1c2goY29tcG9uZW50X3Byb21pc2UpO1xuICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoYFtKUUhUTUwgSW50ZWdyYXRpb25dIEZhaWxlZCB0byBpbml0aWFsaXplIGNvbXBvbmVudCAke2NvbXBvbmVudF9uYW1lfTpgLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIGRldGFpbHM6JywgZXJyb3Iuc3RhY2sgfHwgZXJyb3IpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gVG9wLWxldmVsIGNhbGw6IHNwYXduIGFzeW5jIGhhbmRsZXIgdG8gd2FpdCBmb3IgYWxsIHByb21pc2VzLCB0aGVuIHRyaWdnZXIgZXZlbnRcbiAgICAgICAgaWYgKGlzX3RvcF9sZXZlbCkge1xuICAgICAgICAgICAgKGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgICAgICBhd2FpdCBQcm9taXNlLmFsbChwcm9taXNlcyk7XG4gICAgICAgICAgICAgICAgYXdhaXQgUnN4Ll9yc3hfY2FsbF9hbGxfY2xhc3Nlcygnb25fanFodG1sX3JlYWR5Jyk7XG4gICAgICAgICAgICAgICAgUnN4LnRyaWdnZXIoJ2pxaHRtbF9yZWFkeScpO1xuICAgICAgICAgICAgfSkoKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFJlY3Vyc2l2ZSBjYWxsOiByZXR1cm4gcHJvbWlzZXMgZm9yIHBhcmVudCB0byBjb2xsZWN0XG4gICAgICAgIHJldHVybiBwcm9taXNlcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXQgYWxsIHJlZ2lzdGVyZWQgY29tcG9uZW50IG5hbWVzXG4gICAgICogQHJldHVybnMge0FycmF5PHN0cmluZz59IEFycmF5IG9mIGNvbXBvbmVudCBuYW1lc1xuICAgICAqL1xuICAgIHN0YXRpYyBnZXRfY29tcG9uZW50X25hbWVzKCkge1xuICAgICAgICByZXR1cm4ganFodG1sLmdldF9jb21wb25lbnRfbmFtZXMoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVjayBpZiBhIGNvbXBvbmVudCBpcyByZWdpc3RlcmVkXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IG5hbWUgQ29tcG9uZW50IG5hbWVcbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gVHJ1ZSBpZiBjb21wb25lbnQgaXMgcmVnaXN0ZXJlZFxuICAgICAqL1xuICAgIHN0YXRpYyBoYXNfY29tcG9uZW50KG5hbWUpIHtcbiAgICAgICAgcmV0dXJuIGpxaHRtbC5oYXNfY29tcG9uZW50KG5hbWUpO1xuICAgIH1cbn1cblxuLy8gUlNYIG1hbmlmZXN0IGF1dG9tYXRpY2FsbHkgbWFrZXMgY2xhc3NlcyBnbG9iYWwgLSBubyBtYW51YWwgYXNzaWdubWVudCBuZWVkZWRcbiIsIi8qKlxuICogRGF0YUdyaWQgQ29tcG9uZW50IChQaGFzZSAxKVxuICpcbiAqIER1ZSB0byB0aGUgbW9yZSBkeW5hbWljIG5hdHVyZSBvZiB0aGlzIGNvbXBvbmVudCwgd2UgYXJlIGhhbmRsaW5nIGxvYWQgLyByZW5kZXIgbGlmZWN5Y2xlc1xuICogZGlyZWN0bHkgaW4gdGhpcyBjbGFzcyByYXRoZXIgdGhhbiB1c2luZyB0aGUgb25fbG9hZCBsaWZlY3ljbGUgZXZlbnRcbiAqXG4gKiAqKkZlYXR1cmVzKio6XG4gKiAtIEFqYXggZGF0YSBmZXRjaGluZ1xuICogLSBTb3J0aW5nIChjbGljayBoZWFkZXJzKVxuICogLSBQYWdpbmF0aW9uIChuZXh0L3ByZXYvcGFnZSBzZWxlY3QpXG4gKiAtIFJvdyBzZWxlY3Rpb24gKGNoZWNrYm94ZXMpXG4gKiAtIENTViBleHBvcnQgKHNlbGVjdGVkIHJvd3MsIGN1cnJlbnQgcGFnZSlcbiAqIC0gVVJMIHN0YXRlIHN5bmNocm9uaXphdGlvblxuICpcbiAqICoqVXNhZ2UqKjpcbiAqIGBgYGh0bWxcbiAqIDxDb250YWN0c19EYXRhR3JpZCAkYXBpPVwiRnJvbnRlbmRfQ29udGFjdHNfQ29udHJvbGxlclwiIC8+XG4gKiBgYGBcbiAqXG4gKiAqKlJlcXVpcmVkIEFyZ3MqKjpcbiAqIC0gYGFwaWAgLSBDb250cm9sbGVyIGNsYXNzIG5hbWUgd2l0aCBkYXRhZ3JpZF9mZXRjaCgpIEFqYXggZW5kcG9pbnRcbiAqXG4gKiAqKk9wdGlvbmFsIEFyZ3MqKjpcbiAqIC0gYHBlcl9wYWdlYCAtIERlZmF1bHQgcm93cyBwZXIgcGFnZSAoZGVmYXVsdDogMjUpXG4gKiAtIGBzb3J0YCAtIERlZmF1bHQgc29ydCBjb2x1bW4gKGRlZmF1bHQ6IGZpcnN0IGNvbHVtbilcbiAqIC0gYG9yZGVyYCAtIERlZmF1bHQgc29ydCBvcmRlciAoZGVmYXVsdDogJ2FzYycpXG4gKi9cbmNsYXNzIERhdGFHcmlkX0Fic3RyYWN0IGV4dGVuZHMgSnFodG1sX0NvbXBvbmVudCB7XG4gICAgLy8gSW5pdGlhbGl6ZSBkYXRhIGJlZm9yZSBmaXJzdCByZW5kZXJcbiAgICBvbl9jcmVhdGUoKSB7XG4gICAgICAgIGxldCB0aGF0ID0gdGhpcztcblxuICAgICAgICAvLyBJbml0aWFsaXplIGRhdGEgc3RhdGUgaW1tZWRpYXRlbHkgc28gdGVtcGxhdGUgY2FuIHJlbmRlclxuICAgICAgICB0aGF0LmRhdGEucm93cyA9IFtdO1xuICAgICAgICB0aGF0LmRhdGEubG9hZGluZyA9IHRydWU7XG4gICAgICAgIHRoYXQuZGF0YS5pc19lbXB0eSA9IGZhbHNlO1xuICAgICAgICB0aGF0LmRhdGEubG9hZGVkID0gZmFsc2U7XG4gICAgICAgIHRoYXQuZGF0YS50b3RhbF9wYWdlcyA9IDA7XG4gICAgfVxuXG4gICAgLy8gQ2FsbHMgd2hlbiBkYXRhZ3JpZCBmaXJzdCBpbml0aWFsaXplZFxuICAgIGFzeW5jIG9uX3JlYWR5KCkge1xuICAgICAgICBsZXQgdGhhdCA9IHRoaXM7XG5cbiAgICAgICAgaWYgKCF0aGF0LmFyZ3MuZGF0YV9zb3VyY2UpIHtcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0RhdGFncmlkICcgKyB0aGF0LmNvbXBvbmVudF9uYW1lKCkgKyAnIHJlcXVpcmVzIGFyZ3MuZGF0YV9zb3VyY2Ugc2V0IHRvIGEgQWpheF9FbmRwb2ludCBvYmplY3QnKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFN0b3JlIGRlZmF1bHRzIGZvciBsYXRlciBjb21wYXJpc29uXG4gICAgICAgIHRoYXQuZGF0YS5kZWZhdWx0X3BhZ2UgPSAxO1xuICAgICAgICB0aGF0LmRhdGEuZGVmYXVsdF9wZXJfcGFnZSA9IHRoYXQuYXJncy5wZXJfcGFnZSA/PyAxNTtcbiAgICAgICAgdGhhdC5kYXRhLmRlZmF1bHRfc29ydCA9IHRoYXQuYXJncy5zb3J0ID8/IG51bGw7XG4gICAgICAgIHRoYXQuZGF0YS5kZWZhdWx0X29yZGVyID0gdGhhdC5hcmdzLm9yZGVyID8/ICdhc2MnO1xuICAgICAgICB0aGF0LmRhdGEuZGVmYXVsdF9maWx0ZXIgPSAnJztcblxuICAgICAgICAvLyBTZXQgY29uZmlndXJlZCB2YWx1ZXNcbiAgICAgICAgdGhhdC5kYXRhLnBlcl9wYWdlID0gdGhhdC5kYXRhLmRlZmF1bHRfcGVyX3BhZ2U7XG5cbiAgICAgICAgLy8gSW5pdGlhbGl6ZSBzdGF0ZSBmcm9tIFVSTCBoYXNoIGlmIHByZXNlbnQsIG90aGVyd2lzZSB1c2UgZGVmYXVsdHNcbiAgICAgICAgY29uc3QgaGFzaF9wYWdlID0gUnN4LmdldF9wYWdlX3N0YXRlKHRoYXQuX2NpZCArICdfcGFnZScpO1xuICAgICAgICBjb25zdCBoYXNoX3NvcnQgPSBSc3guZ2V0X3BhZ2Vfc3RhdGUodGhhdC5fY2lkICsgJ19zb3J0Jyk7XG4gICAgICAgIGNvbnN0IGhhc2hfb3JkZXIgPSBSc3guZ2V0X3BhZ2Vfc3RhdGUodGhhdC5fY2lkICsgJ19vcmRlcicpO1xuICAgICAgICBjb25zdCBoYXNoX2ZpbHRlciA9IFJzeC5nZXRfcGFnZV9zdGF0ZSh0aGF0Ll9jaWQgKyAnX2ZpbHRlcicpO1xuXG4gICAgICAgIHRoYXQuZGF0YS5wYWdlID0gaGFzaF9wYWdlID8gaW50KGhhc2hfcGFnZSkgOiB0aGF0LmRhdGEuZGVmYXVsdF9wYWdlO1xuICAgICAgICB0aGF0LmRhdGEuc29ydCA9IGhhc2hfc29ydCB8fCB0aGF0LmRhdGEuZGVmYXVsdF9zb3J0O1xuICAgICAgICB0aGF0LmRhdGEub3JkZXIgPSBoYXNoX29yZGVyIHx8IHRoYXQuZGF0YS5kZWZhdWx0X29yZGVyO1xuICAgICAgICB0aGF0LmRhdGEuZmlsdGVyID0gaGFzaF9maWx0ZXIgfHwgdGhhdC5kYXRhLmRlZmF1bHRfZmlsdGVyO1xuXG4gICAgICAgIHRoYXQucmVnaXN0ZXJfcmVuZGVyX2NhbGxiYWNrcygpO1xuICAgICAgICB0aGF0LnJlZ2lzdGVyX2ZpbHRlcl9oYW5kbGVycygpO1xuXG4gICAgICAgIC8vIElmIGhhc2ggaGFkIGEgZmlsdGVyIHZhbHVlLCBwb3B1bGF0ZSB0aGUgZmlsdGVyIGlucHV0XG4gICAgICAgIGlmICh0aGF0LmRhdGEuZmlsdGVyKSB7XG4gICAgICAgICAgICBjb25zdCAkZmlsdGVyID0gdGhhdC4kaWQoJ2ZpbHRlcl9pbnB1dCcpO1xuICAgICAgICAgICAgaWYgKCRmaWx0ZXIgJiYgJGZpbHRlci5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgICAgJGZpbHRlci52YWwodGhhdC5kYXRhLmZpbHRlcik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyBNZWFzdXJlIHJvdyBoZWlnaHQgYW5kIHNldCBmaXhlZCB0Ym9keSBoZWlnaHQgKGFsbCBpbiBvbmUgZnJhbWUpXG4gICAgICAgIGF3YWl0IHRoYXQubWVhc3VyZV9hbmRfc2V0X2ZpeGVkX2hlaWdodCgpO1xuXG4gICAgICAgIC8vIEZldGNoIHRoZSBpbml0aWFsIHBhZ2UgKHJlc3BlY3RzIGhhc2ggc3RhdGUpXG4gICAgICAgIHRoYXQubG9hZF9wYWdlKHRoYXQuZGF0YS5wYWdlKTtcbiAgICB9XG5cbiAgICAvLyBVcGRhdGUgaGVhZGVyIG9ubHkgaWYgc29ydC9vcmRlciBjaGFuZ2VkXG4gICAgdXBkYXRlX2hlYWRlcigpIHtcbiAgICAgICAgbGV0IHRoYXQgPSB0aGlzO1xuXG4gICAgICAgIC8vIFRyYWNrIGxhc3QgcmVuZGVyZWQgc3RhdGVcbiAgICAgICAgaWYgKCF0aGF0Ll9sYXN0X2hlYWRlcl9zdGF0ZSkge1xuICAgICAgICAgICAgdGhhdC5fbGFzdF9oZWFkZXJfc3RhdGUgPSB7fTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGN1cnJlbnQgPSB7XG4gICAgICAgICAgICBzb3J0OiB0aGF0LmRhdGEuc29ydCxcbiAgICAgICAgICAgIG9yZGVyOiB0aGF0LmRhdGEub3JkZXIsXG4gICAgICAgIH07XG5cbiAgICAgICAgLy8gT25seSByZW5kZXIgaWYgdmFsdWVzIGNoYW5nZWRcbiAgICAgICAgaWYgKHRoYXQuX2xhc3RfaGVhZGVyX3N0YXRlLnNvcnQgIT09IGN1cnJlbnQuc29ydCB8fCB0aGF0Ll9sYXN0X2hlYWRlcl9zdGF0ZS5vcmRlciAhPT0gY3VycmVudC5vcmRlcikge1xuICAgICAgICAgICAgdGhhdC5fbGFzdF9oZWFkZXJfc3RhdGUgPSBjdXJyZW50O1xuICAgICAgICAgICAgdGhhdC5pZCgnZGF0YWdyaWRfdGFibGVfaGVhZGVyJykucmVuZGVyKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBVcGRhdGUgcGFnaW5hdGlvbiBvbmx5IGlmIHZhbHVlcyBjaGFuZ2VkXG4gICAgdXBkYXRlX3BhZ2luYXRpb24oKSB7XG4gICAgICAgIGxldCB0aGF0ID0gdGhpcztcblxuICAgICAgICAvLyBUcmFjayBsYXN0IHJlbmRlcmVkIHN0YXRlXG4gICAgICAgIGlmICghdGhhdC5fbGFzdF9wYWdpbmF0aW9uX3N0YXRlKSB7XG4gICAgICAgICAgICB0aGF0Ll9sYXN0X3BhZ2luYXRpb25fc3RhdGUgPSB7fTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGN1cnJlbnQgPSB7XG4gICAgICAgICAgICBwYWdlOiB0aGF0LmRhdGEucGFnZSxcbiAgICAgICAgICAgIHBlcl9wYWdlOiB0aGF0LmRhdGEucGVyX3BhZ2UsXG4gICAgICAgICAgICB0b3RhbDogdGhhdC5kYXRhLnRvdGFsLFxuICAgICAgICAgICAgdG90YWxfcGFnZXM6IHRoYXQuZGF0YS50b3RhbF9wYWdlcyxcbiAgICAgICAgfTtcblxuICAgICAgICAvLyBPbmx5IHJlbmRlciBpZiB2YWx1ZXMgY2hhbmdlZFxuICAgICAgICBpZiAoXG4gICAgICAgICAgICB0aGF0Ll9sYXN0X3BhZ2luYXRpb25fc3RhdGUucGFnZSAhPT0gY3VycmVudC5wYWdlIHx8XG4gICAgICAgICAgICB0aGF0Ll9sYXN0X3BhZ2luYXRpb25fc3RhdGUucGVyX3BhZ2UgIT09IGN1cnJlbnQucGVyX3BhZ2UgfHxcbiAgICAgICAgICAgIHRoYXQuX2xhc3RfcGFnaW5hdGlvbl9zdGF0ZS50b3RhbCAhPT0gY3VycmVudC50b3RhbCB8fFxuICAgICAgICAgICAgdGhhdC5fbGFzdF9wYWdpbmF0aW9uX3N0YXRlLnRvdGFsX3BhZ2VzICE9PSBjdXJyZW50LnRvdGFsX3BhZ2VzXG4gICAgICAgICkge1xuICAgICAgICAgICAgdGhhdC5fbGFzdF9wYWdpbmF0aW9uX3N0YXRlID0gY3VycmVudDtcbiAgICAgICAgICAgIHRoYXQuaWQoJ3BhZ2luYXRpb25faW5mbycpLnJlbmRlcigpO1xuICAgICAgICAgICAgdGhhdC5pZCgncGFnaW5hdGlvbl9jb250cm9scycpLnJlbmRlcigpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLy8gTG9hZCBkYXRhIGZvciBzcGVjaWZpZWQgcGFnZSBhbmQgcmUtcmVuZGVyIGRhdGFcbiAgICBhc3luYyBsb2FkX3BhZ2UocGFnZSkge1xuICAgICAgICBsZXQgdGhhdCA9IHRoaXM7XG5cbiAgICAgICAgLy8gU2V0IGxvYWRpbmcgc3RhdGVcbiAgICAgICAgdGhhdC5kYXRhLmxvYWRpbmcgPSB0cnVlO1xuICAgICAgICB0aGF0LmRhdGEucGFnZSA9IHBhZ2U7XG5cbiAgICAgICAgLy8gVXBkYXRlIFVJIHdpdGggcmVxdWVzdGVkIHZhbHVlcyAob3B0aW1pc3RpYyB1cGRhdGUpXG4gICAgICAgIHRoYXQudXBkYXRlX2hlYWRlcigpO1xuICAgICAgICB0aGF0LnVwZGF0ZV9wYWdpbmF0aW9uKCk7XG5cbiAgICAgICAgLy8gT25seSByZW5kZXIgbG9hZGluZyBzdGF0ZSBpZiBubyBkYXRhIHlldCAoaW5pdGlhbCBsb2FkKVxuICAgICAgICBpZiAodGhhdC5kYXRhLnJvd3MubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICB0aGF0LmlkKCdkYXRhZ3JpZF90YWJsZV9ib2R5JykucmVuZGVyKCk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IEFqYXguY2FsbCh0aGF0LmFyZ3MuZGF0YV9zb3VyY2UsIHtcbiAgICAgICAgICAgIHBhZ2U6IHBhZ2UsXG4gICAgICAgICAgICBwZXJfcGFnZTogdGhhdC5kYXRhLnBlcl9wYWdlLFxuICAgICAgICAgICAgc29ydDogdGhhdC5kYXRhLnNvcnQsXG4gICAgICAgICAgICBvcmRlcjogdGhhdC5kYXRhLm9yZGVyLFxuICAgICAgICAgICAgZmlsdGVyOiB0aGF0LmRhdGEuZmlsdGVyLFxuICAgICAgICB9KTtcblxuICAgICAgICAvLyBVcGRhdGUgZGF0YVxuICAgICAgICB0aGF0LmRhdGEubG9hZGluZyA9IGZhbHNlO1xuICAgICAgICB0aGF0LmRhdGEubG9hZGVkID0gdHJ1ZTtcbiAgICAgICAgdGhhdC5kYXRhLnJvd3MgPSByZXNwb25zZS5yZWNvcmRzO1xuICAgICAgICB0aGF0LmRhdGEucGFnZSA9IHJlc3BvbnNlLnBhZ2U7XG4gICAgICAgIHRoYXQuZGF0YS5wZXJfcGFnZSA9IHJlc3BvbnNlLnBlcl9wYWdlO1xuICAgICAgICB0aGF0LmRhdGEudG90YWwgPSByZXNwb25zZS50b3RhbDtcbiAgICAgICAgdGhhdC5kYXRhLnRvdGFsX3BhZ2VzID0gcmVzcG9uc2UudG90YWxfcGFnZXM7XG4gICAgICAgIHRoYXQuZGF0YS5zb3J0ID0gcmVzcG9uc2Uuc29ydDtcbiAgICAgICAgdGhhdC5kYXRhLm9yZGVyID0gcmVzcG9uc2Uub3JkZXI7XG4gICAgICAgIHRoYXQuZGF0YS5pc19lbXB0eSA9IHJlc3BvbnNlLnJlY29yZHMubGVuZ3RoID09PSAwO1xuXG4gICAgICAgIC8vIFBlcnNpc3Qgc3RhdGUgdG8gVVJMIGhhc2ggZm9yIGJvb2ttYXJraW5nL3NoYXJpbmdcbiAgICAgICAgLy8gT25seSBzZXQgdmFsdWVzIHRoYXQgZGlmZmVyIGZyb20gZGVmYXVsdHMgKG51bGwgcmVtb3ZlcyB0aGUga2V5KVxuICAgICAgICBjb25zdCBzdGF0ZSA9IHt9O1xuICAgICAgICBzdGF0ZVt0aGF0Ll9jaWQgKyAnX3BhZ2UnXSA9IHRoYXQuZGF0YS5wYWdlICE9PSB0aGF0LmRhdGEuZGVmYXVsdF9wYWdlID8gdGhhdC5kYXRhLnBhZ2UgOiBudWxsO1xuICAgICAgICBzdGF0ZVt0aGF0Ll9jaWQgKyAnX3NvcnQnXSA9IHRoYXQuZGF0YS5zb3J0ICE9PSB0aGF0LmRhdGEuZGVmYXVsdF9zb3J0ID8gdGhhdC5kYXRhLnNvcnQgOiBudWxsO1xuICAgICAgICBzdGF0ZVt0aGF0Ll9jaWQgKyAnX29yZGVyJ10gPSB0aGF0LmRhdGEub3JkZXIgIT09IHRoYXQuZGF0YS5kZWZhdWx0X29yZGVyID8gdGhhdC5kYXRhLm9yZGVyIDogbnVsbDtcbiAgICAgICAgc3RhdGVbdGhhdC5fY2lkICsgJ19maWx0ZXInXSA9IHRoYXQuZGF0YS5maWx0ZXIgIT09IHRoYXQuZGF0YS5kZWZhdWx0X2ZpbHRlciA/IHRoYXQuZGF0YS5maWx0ZXIgOiBudWxsO1xuXG4gICAgICAgIFJzeC5zZXRfYWxsX3BhZ2Vfc3RhdGUoc3RhdGUpO1xuXG4gICAgICAgIC8vIFVwZGF0ZSBVSSB3aXRoIHNlcnZlciByZXNwb25zZSAob25seSByZW5kZXJzIGlmIGNoYW5nZWQpXG4gICAgICAgIHRoYXQuaWQoJ2RhdGFncmlkX3RhYmxlX2JvZHknKS5yZW5kZXIoKTtcbiAgICAgICAgdGhhdC51cGRhdGVfaGVhZGVyKCk7XG4gICAgICAgIHRoYXQudXBkYXRlX3BhZ2luYXRpb24oKTtcblxuICAgICAgICAvLyBTY3JvbGwgdG8gdG9wIG9mIGRhdGFncmlkIGlmIGl0J3Mgbm90IGN1cnJlbnRseSB2aXNpYmxlXG4gICAgICAgIHRoYXQuc2Nyb2xsX3RvX3RvcF9pZl9uZWVkZWQoKTtcbiAgICB9XG5cbiAgICAvLyBUaGUgY2FsbGJhY2tzIGluIHRoaXMgZnVuY3Rpb24gZmlyZSBhZnRlciBlYWNoIHRhcmdldGVkIGNvbXBvbmVudCByZS1yZW5kZXJzXG4gICAgcmVnaXN0ZXJfcmVuZGVyX2NhbGxiYWNrcygpIHtcbiAgICAgICAgbGV0IHRoYXQgPSB0aGlzO1xuXG4gICAgICAgIC8vIEF0dGFjaCByb3cgY2xpY2sgaGFuZGxlciAtIHJlLXJ1bnMgZXZlcnkgdGltZSBkYXRhZ3JpZF90YWJsZV9ib2R5IHJlbmRlcnNcbiAgICAgICAgdGhhdC5pZCgnZGF0YWdyaWRfdGFibGVfYm9keScpLm9uKCdyZW5kZXInLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBjb25zb2xlLmxvZygnREdUQl9SJyk7XG4gICAgICAgICAgICAvLyBTdGVwIDE6IFdyYXAgY2VsbHMgaW4gZGF0YS1ocmVmIHJvd3Mgd2l0aCBhbmNob3IgdGFnc1xuICAgICAgICAgICAgJCh0aGlzKVxuICAgICAgICAgICAgICAgIC5maW5kKCd0cltkYXRhLWhyZWZdJylcbiAgICAgICAgICAgICAgICAuZWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAgIGxldCAkcm93ID0gJCh0aGlzKTtcbiAgICAgICAgICAgICAgICAgICAgbGV0IGhyZWYgPSAkcm93LmF0dHIoJ2RhdGEtaHJlZicpO1xuXG4gICAgICAgICAgICAgICAgICAgICRyb3cuZmluZCgndGQnKS5lYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGxldCAkY29sID0gJCh0aGlzKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIC8vIFNraXAgaWYgY2VsbCBhbHJlYWR5IGNvbnRhaW5zIGludGVyYWN0aXZlIGVsZW1lbnRzXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBpZiAoJGNvbC5maW5kKCdhLCBidXR0b24sIGlucHV0LCBzZWxlY3QsIHRleHRhcmVhJykubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIC8vIFdyYXAgZW50aXJlIGNlbGwgY29udGVudHMgaW4gYW4gYW5jaG9yIChwcmVzZXJ2ZSBET00gbm9kZXMgZm9yIGNvbXBvbmVudCBsaWZlY3ljbGUpXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBsZXQgJGFuY2hvciA9ICQoJzxhPicsIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vICAgICBocmVmOiBocmVmLFxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gICAgIGNsYXNzOiAnZGF0YWdyaWQtcm93LWxpbmsnXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyB9KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIC8vIE1vdmUgZXhpc3RpbmcgY2hpbGQgbm9kZXMgaW50byBhbmNob3IgKHByZXNlcnZlcyBjb21wb25lbnRzIGFuZCB0aGVpciBzdGF0ZSlcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vICRjb2wuY29udGVudHMoKS5hcHBlbmRUbygkYW5jaG9yKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIC8vIEFkZCBhbmNob3IgdG8gY2VsbFxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gJGNvbC5hcHBlbmQoJGFuY2hvcik7XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAvLyBTdGVwIDI6IEZpbmQgYWxsIGNlbGxzIHdpdGggc2luZ2xlIGFuY2hvciBhcyBvbmx5IGNoaWxkIGFuZCBhcHBseSBmdWxsLXdpZHRoIHN0eWxpbmdcbiAgICAgICAgICAgICQodGhpcylcbiAgICAgICAgICAgICAgICAuZmluZCgndGQnKVxuICAgICAgICAgICAgICAgIC5lYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgbGV0ICRjb2wgPSAkKHRoaXMpO1xuICAgICAgICAgICAgICAgICAgICBsZXQgJGNoaWxkcmVuID0gJGNvbC5jaGlsZHJlbigpO1xuXG4gICAgICAgICAgICAgICAgICAgIC8vIENoZWNrIGlmIGNlbGwgY29udGFpbnMgZXhhY3RseSBvbmUgZGlyZWN0IGNoaWxkIHRoYXQgaXMgYW4gYW5jaG9yXG4gICAgICAgICAgICAgICAgICAgIGlmICgkY2hpbGRyZW4ubGVuZ3RoID09PSAxICYmICRjaGlsZHJlbi5maXJzdCgpLmlzKCdhJykpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIEFkZCBjbGFzcyB0byB0cmFuc2ZlciBwYWRkaW5nIGZyb20gY2VsbCB0byBhbmNob3JcbiAgICAgICAgICAgICAgICAgICAgICAgICRjb2wuYWRkQ2xhc3MoJ2hhcy1mdWxsLWxpbmsnKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAvLyBDaGVjayBpZiBjZWxsIGNvbnRhaW5zIG9ubHkgdGV4dCAobm8gY2hpbGQgZWxlbWVudHMpXG4gICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKCRjaGlsZHJlbi5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIEFkZCBjbGFzcyB0byBhcHBseSB2ZXJ0aWNhbCBwYWRkaW5nIHRvIHRleHQtb25seSBjZWxsc1xuICAgICAgICAgICAgICAgICAgICAgICAgJGNvbC5hZGRDbGFzcygnaGFzLW9ubHktdGV4dCcpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIEF0dGFjaCBzb3J0YWJsZSBoZWFkZXIgY2xpY2sgaGFuZGxlciAtIHJlLXJ1bnMgZXZlcnkgdGltZSBkYXRhZ3JpZF90YWJsZV9oZWFkZXIgcmVuZGVyc1xuICAgICAgICB0aGF0LmlkKCdkYXRhZ3JpZF90YWJsZV9oZWFkZXInKS5vbigncmVuZGVyJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgLy8gVHJhbnNmb3JtIHRoW2RhdGEtc29ydGJ5XSBlbGVtZW50cyBieSB3cmFwcGluZyBjb250ZW50cyBpbiBjbGlja2FibGUgbGlua1xuICAgICAgICAgICAgJCh0aGlzKVxuICAgICAgICAgICAgICAgIC5maW5kKCd0aFtkYXRhLXNvcnRieV0nKVxuICAgICAgICAgICAgICAgIC5lYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgbGV0ICR0aCA9ICQodGhpcyk7XG4gICAgICAgICAgICAgICAgICAgIGxldCBzb3J0YnkgPSAkdGguYXR0cignZGF0YS1zb3J0YnknKTtcblxuICAgICAgICAgICAgICAgICAgICAvLyBUT0RPOiBGaW5kIG91dCB3aHkgdGhpcyBvbigncmVuZGVyJykgY2FsbGJhY2sgaXMgYmVpbmcgY2FsbGVkIHR3aWNlL29uIGFscmVhZHktcHJvY2Vzc2VkIEhUTUxcbiAgICAgICAgICAgICAgICAgICAgLy8gVGhpcyB1bndyYXAgbG9naWMgc2hvdWxkbid0IGJlIG5lY2Vzc2FyeSAtIHRlbXBsYXRlIHNob3VsZCByZW5kZXIgZnJlc2ggZWFjaCB0aW1lXG4gICAgICAgICAgICAgICAgICAgIC8vIEZvciBub3csIHVud3JhcCBhbHJlYWR5LXdyYXBwZWQgY29udGVudCB0byBwcmV2ZW50IGRvdWJsZS13cmFwcGluZ1xuICAgICAgICAgICAgICAgICAgICBsZXQgJGV4aXN0aW5nX2xpbmsgPSAkdGguZmluZCgnYS5zb3J0YWJsZS1oZWFkZXInKTtcbiAgICAgICAgICAgICAgICAgICAgbGV0IGNvbnRlbnRzO1xuICAgICAgICAgICAgICAgICAgICBpZiAoJGV4aXN0aW5nX2xpbmsubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gVW53cmFwIC0gZ2V0IHRoZSB0ZXh0IGNvbnRlbnQgd2l0aG91dCB0aGUgd3JhcHBlciBhbmQgYXJyb3dzXG4gICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50cyA9ICRleGlzdGluZ19saW5rLmNsb25lKCkuZmluZCgnaS5iaScpLnJlbW92ZSgpLmVuZCgpLmh0bWwoKTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnRzID0gJHRoLmh0bWwoKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIC8vIEJ1aWxkIHRoZSBhcnJvdyBpY29uIEhUTUwgaWYgdGhpcyBjb2x1bW4gaXMgY3VycmVudGx5IHNvcnRlZFxuICAgICAgICAgICAgICAgICAgICBsZXQgYXJyb3cgPSAnJztcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoYXQuZGF0YS5zb3J0ID09PSBzb3J0YnkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGFycm93ID1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGF0LmRhdGEub3JkZXIgPT09ICdkZXNjJ1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA/ICc8aSBjbGFzcz1cImJpIGJpLWNoZXZyb24tdXAgbXMtMVwiPjwvaT4nXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogJzxpIGNsYXNzPVwiYmkgYmktY2hldnJvbi1kb3duIG1zLTFcIj48L2k+JztcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIC8vIFJlcGxhY2UgY29udGVudHMgd2l0aCB3cmFwcGVkIGxpbmsgKGZyZXNoIHdyYXBwZXIgZXZlcnkgdGltZSlcbiAgICAgICAgICAgICAgICAgICAgJHRoLmh0bWwoYDxhIGhyZWY9XCIjXCIgY2xhc3M9XCJzb3J0YWJsZS1oZWFkZXJcIiBkYXRhLXNvcnRieT1cIiR7c29ydGJ5fVwiPiR7Y29udGVudHN9JHthcnJvd308L2E+YCk7XG4gICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIC8vIEF0dGFjaCBjbGljayBoYW5kbGVycyB0byB0aGUgc29ydGFibGUgbGlua3Mgd2UganVzdCBjcmVhdGVkXG4gICAgICAgICAgICAkKHRoaXMpXG4gICAgICAgICAgICAgICAgLmZpbmQoJ2Euc29ydGFibGUtaGVhZGVyW2RhdGEtc29ydGJ5XScpXG4gICAgICAgICAgICAgICAgLm9uKCdjbGljaycsIGZ1bmN0aW9uIChlKSB7XG4gICAgICAgICAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc29ydGJ5ID0gJCh0aGlzKS5hdHRyKCdkYXRhLXNvcnRieScpO1xuICAgICAgICAgICAgICAgICAgICB0aGF0LnNvcnRfYnkoc29ydGJ5KTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gQXR0YWNoIHBhZ2luYXRpb24gY2xpY2sgaGFuZGxlciAtIHJlLXJ1bnMgZXZlcnkgdGltZSBwYWdpbmF0aW9uX2NvbnRyb2xzIHJlbmRlcnNcbiAgICAgICAgdGhhdC5pZCgncGFnaW5hdGlvbl9jb250cm9scycpLm9uKCdyZW5kZXInLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAkKHRoaXMpXG4gICAgICAgICAgICAgICAgLmZpbmQoJy5wYWdlLWxpbmsnKVxuICAgICAgICAgICAgICAgIC5vbignY2xpY2snLCBmdW5jdGlvbiAoZSkge1xuICAgICAgICAgICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG5cbiAgICAgICAgICAgICAgICAgICAgY29uc3QgJGxpbmsgPSAkKHRoaXMpO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBwYWdlID0gaW50KCRsaW5rLmF0dHIoJ2RhdGEtcGFnZScpKTtcblxuICAgICAgICAgICAgICAgICAgICAvLyBJZ25vcmUgZGlzYWJsZWQvZWxsaXBzaXMgY2xpY2tzXG4gICAgICAgICAgICAgICAgICAgIGlmICghcGFnZSB8fCBpc05hTihwYWdlKSB8fCAkbGluay5wYXJlbnQoKS5oYXNDbGFzcygnZGlzYWJsZWQnKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgLy8gTG9hZCB0aGUgcmVxdWVzdGVkIHBhZ2VcbiAgICAgICAgICAgICAgICAgICAgdGhhdC5sb2FkX3BhZ2UocGFnZSk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIEF0dGFjaCBjbGVhciBmaWx0ZXIgYnV0dG9uIGhhbmRsZXIgLSByZS1ydW5zIGV2ZXJ5IHRpbWUgZGF0YWdyaWRfdGFibGVfYm9keSByZW5kZXJzXG4gICAgICAgIHRoYXQuaWQoJ2RhdGFncmlkX3RhYmxlX2JvZHknKS5vbigncmVuZGVyJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgY29uc3QgJGNsZWFyX2J0biA9IHRoYXQuJGlkKCdjbGVhcl9maWx0ZXJfYnRuJyk7XG4gICAgICAgICAgICBpZiAoJGNsZWFyX2J0biAmJiAkY2xlYXJfYnRuLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICAkY2xlYXJfYnRuLm9uKCdjbGljaycsIGZ1bmN0aW9uIChlKSB7XG4gICAgICAgICAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICAgICAgICAgICAgdGhhdC5jbGVhcl9maWx0ZXIoKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLy8gU29ydCBieSBzcGVjaWZpZWQgY29sdW1uLCB0b2dnbGluZyBvcmRlciBpZiBhbHJlYWR5IHNvcnRlZCBieSB0aGF0IGNvbHVtblxuICAgIHNvcnRfYnkoY29sdW1uKSB7XG4gICAgICAgIGxldCB0aGF0ID0gdGhpcztcblxuICAgICAgICAvLyBUb2dnbGUgb3JkZXIgaWYgY2xpY2tpbmcgc2FtZSBjb2x1bW4sIG90aGVyd2lzZSBkZWZhdWx0IHRvIGFzY1xuICAgICAgICBpZiAodGhhdC5kYXRhLnNvcnQgPT09IGNvbHVtbikge1xuICAgICAgICAgICAgdGhhdC5kYXRhLm9yZGVyID0gdGhhdC5kYXRhLm9yZGVyID09PSAnYXNjJyA/ICdkZXNjJyA6ICdhc2MnO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhhdC5kYXRhLnNvcnQgPSBjb2x1bW47XG4gICAgICAgICAgICB0aGF0LmRhdGEub3JkZXIgPSAnYXNjJztcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFJlbG9hZCBjdXJyZW50IHBhZ2Ugd2l0aCBuZXcgc29ydFxuICAgICAgICB0aGF0LmlkKCdkYXRhZ3JpZF90YWJsZV9oZWFkZXInKS5yZW5kZXIoKTtcbiAgICAgICAgdGhhdC5sb2FkX3BhZ2UodGhhdC5kYXRhLnBhZ2UpO1xuICAgIH1cblxuICAgIC8vIFJlZ2lzdGVyIGZpbHRlciBpbnB1dCBoYW5kbGVyc1xuICAgIHJlZ2lzdGVyX2ZpbHRlcl9oYW5kbGVycygpIHtcbiAgICAgICAgbGV0IHRoYXQgPSB0aGlzO1xuXG4gICAgICAgIC8vIEZpbmQgZmlsdGVyIGlucHV0IGJ5IGNvbW1vbiBpZGVudGlmaWVyc1xuICAgICAgICBsZXQgJGZpbHRlciA9IHRoYXQuJGlkKCdmaWx0ZXJfaW5wdXQnKTtcbiAgICAgICAgaWYgKCEkZmlsdGVyIHx8ICRmaWx0ZXIubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAkZmlsdGVyID0gdGhhdC4kLmZpbmQoJ2lucHV0W3R5cGU9XCJzZWFyY2hcIl0sIGlucHV0W3R5cGU9XCJ0ZXh0XCJdLmZpbHRlci1pbnB1dCcpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCRmaWx0ZXIgJiYgJGZpbHRlci5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAkZmlsdGVyLm9uKCdpbnB1dCBrZXl1cCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBmaWx0ZXJfdmFsdWUgPSAkKHRoaXMpLnZhbCgpO1xuICAgICAgICAgICAgICAgIHRoYXQuZmlsdGVyX2NoYW5nZWQoZmlsdGVyX3ZhbHVlKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgZmlsdGVyX2NoYW5nZWQoZmlsdGVyKSB7XG4gICAgICAgIGxldCB0aGF0ID0gdGhpcztcblxuICAgICAgICB0aGF0LmRhdGEuZmlsdGVyID0gZmlsdGVyO1xuICAgICAgICB0aGF0LmxvYWRfcGFnZSgxKTtcbiAgICB9XG5cbiAgICAvLyBTY3JvbGwgdG8gZGF0YWdyaWQgdG9wIGlmIHRoZSB0b3AgZWRnZSBpcyBub3QgY3VycmVudGx5IHZpc2libGUgaW4gdmlld3BvcnRcbiAgICBzY3JvbGxfdG9fdG9wX2lmX25lZWRlZCgpIHtcbiAgICAgICAgbGV0IHRoYXQgPSB0aGlzO1xuXG4gICAgICAgIGNvbnN0ICRkYXRhZ3JpZCA9IHRoYXQuJDtcbiAgICAgICAgY29uc3QgZGF0YWdyaWRUb3AgPSAkZGF0YWdyaWQub2Zmc2V0KCkudG9wO1xuICAgICAgICBjb25zdCBzY3JvbGxUb3AgPSAkKHdpbmRvdykuc2Nyb2xsVG9wKCk7XG5cbiAgICAgICAgLy8gSWYgZGF0YWdyaWQgdG9wIGlzIGFib3ZlIHRoZSBjdXJyZW50IHZpZXdwb3J0LCBzY3JvbGwgdG8gc2hvdyBpdFxuICAgICAgICBpZiAoZGF0YWdyaWRUb3AgPCBzY3JvbGxUb3ApIHtcbiAgICAgICAgICAgIC8vIElmIGRhdGFncmlkIGlzIHdpdGhpbiAzMDBweCBvZiBwYWdlIHRvcCwgc2Nyb2xsIHRvIDBcbiAgICAgICAgICAgIGlmIChkYXRhZ3JpZFRvcCA8PSAzMDApIHtcbiAgICAgICAgICAgICAgICB3aW5kb3cuc2Nyb2xsVG8oeyB0b3A6IDAsIGJlaGF2aW9yOiAnaW5zdGFudCcgfSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIC8vIFNjcm9sbCB0byAyMHB4IGFib3ZlIGRhdGFncmlkXG4gICAgICAgICAgICAgICAgd2luZG93LnNjcm9sbFRvKHsgdG9wOiBkYXRhZ3JpZFRvcCAtIDIwLCBiZWhhdmlvcjogJ2luc3RhbnQnIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgLy8gTWVhc3VyZSBhY3R1YWwgcm93IGhlaWdodCBhbmQgc2V0IGZpeGVkIHRib2R5IG1pbi1oZWlnaHRcbiAgICAvLyBBbGwgaGFwcGVucyBpbiBvbmUgYW5pbWF0aW9uIGZyYW1lIHNvIHVzZXIgZG9lc24ndCBzZWUgaXRcbiAgICBhc3luYyBtZWFzdXJlX2FuZF9zZXRfZml4ZWRfaGVpZ2h0KCkge1xuICAgICAgICBsZXQgdGhhdCA9IHRoaXM7XG5cbiAgICAgICAgLy8gV2FpdCBmb3IgbmV4dCBhbmltYXRpb24gZnJhbWUgdG8gZW5zdXJlIERPTSBpcyByZWFkeVxuICAgICAgICBhd2FpdCBzbGVlcCgwKTtcblxuICAgICAgICBjb25zdCAkdGJvZHkgPSB0aGF0LmlkKCdkYXRhZ3JpZF90YWJsZV9ib2R5JykuJDtcblxuICAgICAgICAvLyBUZW1wb3JhcmlseSByZW5kZXIgYSBzaW5nbGUgbWVhc3VyZW1lbnQgcm93XG4gICAgICAgIGNvbnN0ICRtZWFzdXJlbWVudF9yb3cgPSAkKCc8dHI+JykuY3NzKCd2aXNpYmlsaXR5JywgJ2hpZGRlbicpLmh0bWwoJzx0ZD5NZWFzdXJpbmcuLi48L3RkPicpO1xuICAgICAgICAkdGJvZHkuYXBwZW5kKCRtZWFzdXJlbWVudF9yb3cpO1xuXG4gICAgICAgIC8vIE1lYXN1cmUgdGhlIHJvdyBoZWlnaHRcbiAgICAgICAgY29uc3Qgcm93X2hlaWdodCA9ICRtZWFzdXJlbWVudF9yb3cub3V0ZXJIZWlnaHQoKTtcblxuICAgICAgICAvLyBSZW1vdmUgbWVhc3VyZW1lbnQgcm93XG4gICAgICAgICRtZWFzdXJlbWVudF9yb3cucmVtb3ZlKCk7XG5cbiAgICAgICAgLy8gQ2FsY3VsYXRlIGFuZCBzZXQgbWluLWhlaWdodCBiYXNlZCBvbiBwZXJfcGFnZVxuICAgICAgICBjb25zdCBtaW5faGVpZ2h0ID0gcm93X2hlaWdodCAqIHRoYXQuZGF0YS5wZXJfcGFnZTtcbiAgICAgICAgJHRib2R5LmNzcygnbWluLWhlaWdodCcsIG1pbl9oZWlnaHQgKyAncHgnKTtcblxuICAgICAgICAvLyBTdG9yZSBmb3IgZnV0dXJlIHJlZmVyZW5jZVxuICAgICAgICB0aGF0LmRhdGEucm93X2hlaWdodCA9IHJvd19oZWlnaHQ7XG4gICAgICAgIHRoYXQuZGF0YS50Ym9keV9taW5faGVpZ2h0ID0gbWluX2hlaWdodDtcbiAgICB9XG5cbiAgICAvLyBDbGVhciBmaWx0ZXIgYW5kIHJlc2V0IHRvIHBhZ2UgMVxuICAgIGNsZWFyX2ZpbHRlcigpIHtcbiAgICAgICAgbGV0IHRoYXQgPSB0aGlzO1xuXG4gICAgICAgIHRoYXQuZGF0YS5maWx0ZXIgPSAnJztcblxuICAgICAgICAvLyBDbGVhciB0aGUgZmlsdGVyIGlucHV0XG4gICAgICAgIGNvbnN0ICRmaWx0ZXIgPSB0aGF0LiRpZCgnZmlsdGVyX2lucHV0Jyk7XG4gICAgICAgIGlmICgkZmlsdGVyICYmICRmaWx0ZXIubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgJGZpbHRlci52YWwoJycpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gUmVsb2FkIGZyb20gcGFnZSAxXG4gICAgICAgIHRoYXQubG9hZF9wYWdlKDEpO1xuICAgIH1cbn1cbiIsImNsYXNzIEFjdGl2aXR5X0ZlZWQgZXh0ZW5kcyBKcWh0bWxfQ29tcG9uZW50IHtcbiAgICBhc3luYyBvbl9sb2FkKCkge1xuICAgICAgICBpZiAodGhpcy5hcmdzLmRhdGFfc291cmNlKSB7XG4gICAgICAgICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKHRoaXMuYXJncy5kYXRhX3NvdXJjZSk7XG4gICAgICAgICAgICB0aGlzLmRhdGEuYWN0aXZpdGllcyA9IGF3YWl0IHJlc3BvbnNlLmpzb24oKTtcbiAgICAgICAgfSBlbHNlIGlmICh0aGlzLmFyZ3MuYWN0aXZpdGllcykge1xuICAgICAgICAgICAgdGhpcy5kYXRhLmFjdGl2aXRpZXMgPSB0aGlzLmFyZ3MuYWN0aXZpdGllcztcbiAgICAgICAgfVxuICAgIH1cblxuICAgIG9uX3JlYWR5KCkge1xuICAgICAgICAvLyBPcHRpb25hbDogQXV0by1yZWZyZXNoXG4gICAgICAgIGlmICh0aGlzLmFyZ3MuYXV0b19yZWZyZXNoKSB7XG4gICAgICAgICAgICB0aGlzLnN0YXJ0X2F1dG9fcmVmcmVzaCgpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgc3RhcnRfYXV0b19yZWZyZXNoKCkge1xuICAgICAgICBjb25zdCBpbnRlcnZhbCA9IHRoaXMuYXJncy5yZWZyZXNoX2ludGVydmFsIHx8IDMwMDAwOyAvLyBEZWZhdWx0IDMwIHNlY29uZHNcblxuICAgICAgICB0aGlzLnJlZnJlc2hfdGltZXIgPSBzZXRJbnRlcnZhbCgoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLnJlbG9hZF9kYXRhKCk7XG4gICAgICAgIH0sIGludGVydmFsKTtcbiAgICB9XG5cbiAgICBzdG9wX2F1dG9fcmVmcmVzaCgpIHtcbiAgICAgICAgaWYgKHRoaXMucmVmcmVzaF90aW1lcikge1xuICAgICAgICAgICAgY2xlYXJJbnRlcnZhbCh0aGlzLnJlZnJlc2hfdGltZXIpO1xuICAgICAgICAgICAgdGhpcy5yZWZyZXNoX3RpbWVyID0gbnVsbDtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGFzeW5jIHJlbG9hZF9kYXRhKCkge1xuICAgICAgICBpZiAodGhpcy5hcmdzLmRhdGFfc291cmNlKSB7XG4gICAgICAgICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKHRoaXMuYXJncy5kYXRhX3NvdXJjZSk7XG4gICAgICAgICAgICB0aGlzLmRhdGEuYWN0aXZpdGllcyA9IGF3YWl0IHJlc3BvbnNlLmpzb24oKTtcbiAgICAgICAgICAgIHRoaXMucmVuZGVyKCk7XG4gICAgICAgIH1cbiAgICB9XG59XG4iLCJjbGFzcyBBY3Rvcl9SZWZlcmVuY2UgZXh0ZW5kcyBKcWh0bWxfQ29tcG9uZW50IHtcbiAgICAvLyBQdXJlIEJvb3RzdHJhcCBzdHlsaW5nIC0gbm8gSmF2YVNjcmlwdCBuZWVkZWRcbn1cbiIsImNsYXNzIEFkdmFuY2VkX1NlYXJjaF9QYW5lbCBleHRlbmRzIEpxaHRtbF9Db21wb25lbnQge1xuICAgIG9uX3JlYWR5KCkge1xuICAgICAgICAvLyBQb3B1bGF0ZSBkcm9wZG93bnMgaWYgcHJvdmlkZWRcbiAgICAgICAgaWYgKHRoaXMuYXJncy5jYXRlZ29yaWVzKSB7XG4gICAgICAgICAgICB0aGlzLiRpZCgnY2F0ZWdvcnknKS5zZXRfb3B0aW9ucyh0aGlzLmFyZ3MuY2F0ZWdvcmllcyk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5hcmdzLnRhZ3MpIHtcbiAgICAgICAgICAgIHRoaXMuJGlkKCd0YWdzJykuc2V0X29wdGlvbnModGhpcy5hcmdzLnRhZ3MpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gU2VhcmNoIGJ1dHRvblxuICAgICAgICB0aGlzLiRpZCgnc2VhcmNoX2J0bicpLm9uKCdjbGljaycsIChlKSA9PiB7XG4gICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICB0aGlzLnBlcmZvcm1fc2VhcmNoKCk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIFJlc2V0IGJ1dHRvblxuICAgICAgICB0aGlzLiRpZCgncmVzZXRfYnRuJykub24oJ2NsaWNrJywgKGUpID0+IHtcbiAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICAgIHRoaXMucmVzZXQoKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gQ2xvc2UgYnV0dG9uXG4gICAgICAgIHRoaXMuJGlkKCdjbG9zZV9idG4nKS5vbignY2xpY2snLCAoKSA9PiB7XG4gICAgICAgICAgICBpZiAodGhpcy5hcmdzLm9uX2Nsb3NlKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5hcmdzLm9uX2Nsb3NlKCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMuJC5oaWRlKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIEZvcm0gc3VibWl0XG4gICAgICAgIHRoaXMuJGlkKCdzZWFyY2hfZm9ybScpLm9uKCdzdWJtaXQnLCAoZSkgPT4ge1xuICAgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgICAgdGhpcy5wZXJmb3JtX3NlYXJjaCgpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwZXJmb3JtX3NlYXJjaCgpIHtcbiAgICAgICAgY29uc3QgY3JpdGVyaWEgPSB7XG4gICAgICAgICAgICBrZXl3b3JkczogdGhpcy4kaWQoJ2tleXdvcmRzJykuZ2V0X3ZhbHVlKCksXG4gICAgICAgICAgICBjYXRlZ29yeTogdGhpcy4kaWQoJ2NhdGVnb3J5JykuZ2V0X3ZhbHVlKCksXG4gICAgICAgICAgICB0YWdzOiB0aGlzLiRpZCgndGFncycpLmdldF92YWx1ZSgpLFxuICAgICAgICAgICAgZnJvbV9kYXRlOiB0aGlzLiRpZCgnZnJvbV9kYXRlJykuZ2V0X3ZhbHVlKCksXG4gICAgICAgICAgICB0b19kYXRlOiB0aGlzLiRpZCgndG9fZGF0ZScpLmdldF92YWx1ZSgpLFxuICAgICAgICAgICAgc29ydF9ieTogdGhpcy4kaWQoJ3NvcnRfYnknKS52YWwoKSxcbiAgICAgICAgICAgIGV4YWN0X21hdGNoOiB0aGlzLiRpZCgnZXhhY3RfbWF0Y2gnKS5pcygnOmNoZWNrZWQnKVxuICAgICAgICB9O1xuXG4gICAgICAgIC8vIFJlbW92ZSBlbXB0eSB2YWx1ZXNcbiAgICAgICAgT2JqZWN0LmtleXMoY3JpdGVyaWEpLmZvckVhY2goa2V5ID0+IHtcbiAgICAgICAgICAgIGlmICghY3JpdGVyaWFba2V5XSB8fCAoaXNfYXJyYXkoY3JpdGVyaWFba2V5XSkgJiYgY3JpdGVyaWFba2V5XS5sZW5ndGggPT09IDApKSB7XG4gICAgICAgICAgICAgICAgZGVsZXRlIGNyaXRlcmlhW2tleV07XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGlmICh0aGlzLmFyZ3Mub25fc2VhcmNoKSB7XG4gICAgICAgICAgICB0aGlzLmFyZ3Mub25fc2VhcmNoKGNyaXRlcmlhKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHJlc2V0KCkge1xuICAgICAgICB0aGlzLiRpZCgna2V5d29yZHMnKS5zZXRfdmFsdWUoJycpO1xuICAgICAgICB0aGlzLiRpZCgnY2F0ZWdvcnknKS5zZXRfdmFsdWUoJycpO1xuICAgICAgICB0aGlzLiRpZCgndGFncycpLnNldF92YWx1ZShbXSk7XG4gICAgICAgIHRoaXMuJGlkKCdmcm9tX2RhdGUnKS5zZXRfdmFsdWUoJycpO1xuICAgICAgICB0aGlzLiRpZCgndG9fZGF0ZScpLnNldF92YWx1ZSgnJyk7XG4gICAgICAgIHRoaXMuJGlkKCdzb3J0X2J5JykudmFsKCdyZWxldmFuY2UnKTtcbiAgICAgICAgdGhpcy4kaWQoJ2V4YWN0X21hdGNoJykucHJvcCgnY2hlY2tlZCcsIGZhbHNlKTtcblxuICAgICAgICBpZiAodGhpcy5hcmdzLm9uX3Jlc2V0KSB7XG4gICAgICAgICAgICB0aGlzLmFyZ3Mub25fcmVzZXQoKTtcbiAgICAgICAgfVxuICAgIH1cbn1cbiIsImNsYXNzIEFsZXJ0X0Jhbm5lciBleHRlbmRzIEpxaHRtbF9Db21wb25lbnQge1xuICAgIG9uX3JlYWR5KCkge1xuICAgICAgICAvLyBBcHBseSB0eXBlIGZyb20gYXJncyAoc3VjY2VzcywgZGFuZ2VyLCB3YXJuaW5nLCBpbmZvKVxuICAgICAgICBpZiAodGhpcy5hcmdzLnR5cGUpIHtcbiAgICAgICAgICAgIHRoaXMuJC5yZW1vdmVDbGFzcygnYWxlcnQtaW5mbycpLmFkZENsYXNzKGBhbGVydC0ke3RoaXMuYXJncy50eXBlfWApO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gUmVtb3ZlIGRpc21pc3NpYmxlIGlmIG5vdCBuZWVkZWRcbiAgICAgICAgaWYgKHRoaXMuYXJncy5kaXNtaXNzaWJsZSA9PT0gZmFsc2UpIHtcbiAgICAgICAgICAgIHRoaXMuJC5yZW1vdmVDbGFzcygnYWxlcnQtZGlzbWlzc2libGUnKTtcbiAgICAgICAgICAgIHRoaXMuJC5maW5kKCcuYnRuLWNsb3NlJykucmVtb3ZlKCk7XG4gICAgICAgIH1cbiAgICB9XG59XG4iLCJjbGFzcyBBdmF0YXIgZXh0ZW5kcyBKcWh0bWxfQ29tcG9uZW50IHtcbiAgICBvbl9yZWFkeSgpIHtcbiAgICAgICAgLy8gU2V0IHNyYyBmcm9tIGFyZ3NcbiAgICAgICAgaWYgKHRoaXMuYXJncy5zcmMpIHtcbiAgICAgICAgICAgIHRoaXMuJC5hdHRyKCdzcmMnLCB0aGlzLmFyZ3Muc3JjKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFNldCBzaXplICh4cywgc20sIG1kLCBsZywgeGwpXG4gICAgICAgIGNvbnN0IHNpemUgPSB0aGlzLmFyZ3Muc2l6ZSB8fCAnbWQnO1xuICAgICAgICBjb25zdCBzaXplX21hcCA9IHtcbiAgICAgICAgICAgICd4cyc6ICcyNHB4JyxcbiAgICAgICAgICAgICdzbSc6ICczMnB4JyxcbiAgICAgICAgICAgICdtZCc6ICc0OHB4JyxcbiAgICAgICAgICAgICdsZyc6ICc2NHB4JyxcbiAgICAgICAgICAgICd4bCc6ICc5NnB4J1xuICAgICAgICB9O1xuXG4gICAgICAgIHRoaXMuJC5jc3Moe1xuICAgICAgICAgICAgJ3dpZHRoJzogc2l6ZV9tYXBbc2l6ZV0sXG4gICAgICAgICAgICAnaGVpZ2h0Jzogc2l6ZV9tYXBbc2l6ZV0sXG4gICAgICAgICAgICAnb2JqZWN0LWZpdCc6ICdjb3ZlcidcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gQWx0ZXJuYXRpdmUgcmVuZGVyaW5nOiBzaG93IGluaXRpYWxzIHdoZW4gbm8gaW1hZ2Ugc291cmNlIHByb3ZpZGVkXG4gICAgICAgIGlmICghdGhpcy5hcmdzLnNyYyAmJiB0aGlzLmFyZ3MubmFtZSkge1xuICAgICAgICAgICAgdGhpcy5zaG93X2luaXRpYWxzKHRoaXMuYXJncy5uYW1lKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHNob3dfaW5pdGlhbHMobmFtZSkge1xuICAgICAgICAvLyBDb252ZXJ0IGltZyB0byBkaXYgd2l0aCBpbml0aWFsc1xuICAgICAgICBjb25zdCBpbml0aWFscyA9IG5hbWUuc3BsaXQoJyAnKS5tYXAobiA9PiBuWzBdKS5qb2luKCcnKS50b1VwcGVyQ2FzZSgpLnNsaWNlKDAsIDIpO1xuICAgICAgICBjb25zdCAkZGl2ID0gJCgnPGRpdj4nKVxuICAgICAgICAgICAgLmFkZENsYXNzKCdyb3VuZGVkLWNpcmNsZSBkLWZsZXggYWxpZ24taXRlbXMtY2VudGVyIGp1c3RpZnktY29udGVudC1jZW50ZXIgYmctcHJpbWFyeSB0ZXh0LXdoaXRlIGZ3LWJvbGQnKVxuICAgICAgICAgICAgLmNzcyh7XG4gICAgICAgICAgICAgICAgJ3dpZHRoJzogdGhpcy4kLmNzcygnd2lkdGgnKSxcbiAgICAgICAgICAgICAgICAnaGVpZ2h0JzogdGhpcy4kLmNzcygnaGVpZ2h0JylcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAudGV4dChpbml0aWFscyk7XG5cbiAgICAgICAgdGhpcy4kLnJlcGxhY2VXaXRoKCRkaXYpO1xuICAgICAgICB0aGlzLiQgPSAkZGl2O1xuICAgIH1cbn1cbiIsImNsYXNzIEJsb2NrcXVvdGUgZXh0ZW5kcyBKcWh0bWxfQ29tcG9uZW50IHtcbiAgICBvbl9yZWFkeSgpIHtcbiAgICAgICAgLy8gTm8gc3BlY2lhbCBiZWhhdmlvclxuICAgIH1cbn1cbiIsImNsYXNzIEJyZWFkY3J1bWJzIGV4dGVuZHMgSnFodG1sX0NvbXBvbmVudCB7XG4gICAgLy8gUGxhY2Vob2xkZXIgY29tcG9uZW50IC0gY3VycmVudGx5IGVtcHR5IGluIGRhc2hib2FyZCB1c2FnZVxufVxuIiwiY2xhc3MgQnVsa19BY3Rpb25fQmFyIGV4dGVuZHMgSnFodG1sX0NvbXBvbmVudCB7XG4gICAgb25fcmVhZHkoKSB7XG4gICAgICAgIC8vIENsZWFyIHNlbGVjdGlvbiBvbiBjbG9zZVxuICAgICAgICB0aGlzLiRpZCgnY2xvc2VfYnRuJykub24oJ2NsaWNrJywgKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy4kLmhpZGUoKTtcbiAgICAgICAgICAgIC8vIFVuY2hlY2sgYWxsIGJveGVzXG4gICAgICAgICAgICBjb25zdCAkdGFibGUgPSB0aGlzLiQuY2xvc2VzdCgnLmNhcmQnKS5maW5kKCd0YWJsZScpO1xuICAgICAgICAgICAgJHRhYmxlLmZpbmQoJ2lucHV0W3R5cGU9XCJjaGVja2JveFwiXScpLnByb3AoJ2NoZWNrZWQnLCBmYWxzZSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHNldF9jb3VudChjb3VudCkge1xuICAgICAgICB0aGlzLiQuZmluZCgnLmNvdW50JykudGV4dChjb3VudCk7XG4gICAgfVxufVxuIiwiY2xhc3MgQnVsa19TZWxlY3Rpb24gZXh0ZW5kcyBKcWh0bWxfQ29tcG9uZW50IHtcbiAgICBvbl9yZWFkeSgpIHtcbiAgICAgICAgY29uc3QgJGNoZWNrYm94ID0gdGhpcy4kaWQoJ2NoZWNrYm94Jyk7XG5cbiAgICAgICAgLy8gVG9nZ2xlIGFsbCBjaGVja2JveGVzIGluIHRhYmxlIGJvZHlcbiAgICAgICAgJGNoZWNrYm94Lm9uKCdjaGFuZ2UnLCAoZSkgPT4ge1xuICAgICAgICAgICAgY29uc3QgY2hlY2tlZCA9IGUudGFyZ2V0LmNoZWNrZWQ7XG4gICAgICAgICAgICBjb25zdCAkdGFibGUgPSB0aGlzLiQuY2xvc2VzdCgndGFibGUnKTtcbiAgICAgICAgICAgICR0YWJsZS5maW5kKCd0Ym9keSBpbnB1dFt0eXBlPVwiY2hlY2tib3hcIl0nKS5wcm9wKCdjaGVja2VkJywgY2hlY2tlZCk7XG5cbiAgICAgICAgICAgIC8vIFRyaWdnZXIgdXBkYXRlIGV2ZW50XG4gICAgICAgICAgICBpZiAodGhpcy5hcmdzLm9uX2NoYW5nZSkge1xuICAgICAgICAgICAgICAgIHRoaXMuYXJncy5vbl9jaGFuZ2UoY2hlY2tlZCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cbn1cbiIsImNsYXNzIEJ1dHRvbl9Hcm91cCBleHRlbmRzIEpxaHRtbF9Db21wb25lbnQge1xuICAgIC8vIENvbnRhaW5lciBmb3IgZ3JvdXBlZCBidXR0b25zIHdpdGggY29ubmVjdGVkIGJvcmRlcnNcbiAgICAvLyBCb290c3RyYXAgYnRuLWdyb3VwIGhhbmRsZXMgYWxsIHZpc3VhbCBncm91cGluZ1xufVxuIiwiY2xhc3MgQnV0dG9uX1ByaW1hcnkgZXh0ZW5kcyBKcWh0bWxfQ29tcG9uZW50IHtcbiAgICAvLyBQcmltYXJ5IGFjdGlvbiBidXR0b24gLSBoaWdoZXN0IHZpc3VhbCBoaWVyYXJjaHlcbiAgICAvLyBCb290c3RyYXAgYnRuLXByaW1hcnkgcHJvdmlkZXMgYWxsIHN0eWxpbmdcbn1cbiIsImNsYXNzIEJ1dHRvbl9TZWNvbmRhcnkgZXh0ZW5kcyBKcWh0bWxfQ29tcG9uZW50IHtcbiAgICAvLyBTZWNvbmRhcnkgYWN0aW9uIGJ1dHRvbiAtIGxvd2VyIHByb21pbmVuY2UgdGhhbiBwcmltYXJ5XG4gICAgLy8gQm9vdHN0cmFwIGJ0bi1zZWNvbmRhcnkgcHJvdmlkZXMgZ3JheSBjb2xvciBzY2hlbWVcbn1cbiIsImNsYXNzIEJ1dHRvbiBleHRlbmRzIEpxaHRtbF9Db21wb25lbnQge1xuICAgIC8vIEJhc2UgYnV0dG9uIGNvbXBvbmVudCAtIG5vIHNwZWNpYWwgYmVoYXZpb3IgbmVlZGVkXG4gICAgLy8gQm9vdHN0cmFwIGhhbmRsZXMgYWxsIHN0YXRlcyAoaG92ZXIsIGFjdGl2ZSwgZm9jdXMsIGRpc2FibGVkKVxufVxuIiwiY2xhc3MgQ2FsZW5kYXJfRXZlbnQgZXh0ZW5kcyBKcWh0bWxfQ29tcG9uZW50IHtcbiAgICBvbl9yZWFkeSgpIHtcbiAgICAgICAgaWYgKHRoaXMuYXJncy5vbl9jbGljaykge1xuICAgICAgICAgICAgdGhpcy4kLm9uKCdjbGljaycsICgpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmFyZ3Mub25fY2xpY2sodGhpcy5hcmdzKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gSG92ZXIgZWZmZWN0XG4gICAgICAgIHRoaXMuJC5vbignbW91c2VlbnRlcicsICgpID0+IHtcbiAgICAgICAgICAgIHRoaXMuJC5hZGRDbGFzcygnc2hhZG93LXNtJyk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHRoaXMuJC5vbignbW91c2VsZWF2ZScsICgpID0+IHtcbiAgICAgICAgICAgIHRoaXMuJC5yZW1vdmVDbGFzcygnc2hhZG93LXNtJyk7XG4gICAgICAgIH0pO1xuICAgIH1cbn1cbiIsImNsYXNzIENhbGVuZGFyX0dyaWQgZXh0ZW5kcyBKcWh0bWxfQ29tcG9uZW50IHtcbiAgICBvbl9yZWFkeSgpIHtcbiAgICAgICAgdGhpcy5jdXJyZW50X2RhdGUgPSBuZXcgRGF0ZSgpO1xuICAgICAgICB0aGlzLnJlbmRlcl9jYWxlbmRhcigpO1xuXG4gICAgICAgIHRoaXMuJGlkKCdwcmV2X2J0bicpLm9uKCdjbGljaycsICgpID0+IHtcbiAgICAgICAgICAgIHRoaXMuY3VycmVudF9kYXRlLnNldE1vbnRoKHRoaXMuY3VycmVudF9kYXRlLmdldE1vbnRoKCkgLSAxKTtcbiAgICAgICAgICAgIHRoaXMucmVuZGVyX2NhbGVuZGFyKCk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHRoaXMuJGlkKCduZXh0X2J0bicpLm9uKCdjbGljaycsICgpID0+IHtcbiAgICAgICAgICAgIHRoaXMuY3VycmVudF9kYXRlLnNldE1vbnRoKHRoaXMuY3VycmVudF9kYXRlLmdldE1vbnRoKCkgKyAxKTtcbiAgICAgICAgICAgIHRoaXMucmVuZGVyX2NhbGVuZGFyKCk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHRoaXMuJGlkKCd0b2RheV9idG4nKS5vbignY2xpY2snLCAoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmN1cnJlbnRfZGF0ZSA9IG5ldyBEYXRlKCk7XG4gICAgICAgICAgICB0aGlzLnJlbmRlcl9jYWxlbmRhcigpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICByZW5kZXJfY2FsZW5kYXIoKSB7XG4gICAgICAgIGNvbnN0IHllYXIgPSB0aGlzLmN1cnJlbnRfZGF0ZS5nZXRGdWxsWWVhcigpO1xuICAgICAgICBjb25zdCBtb250aCA9IHRoaXMuY3VycmVudF9kYXRlLmdldE1vbnRoKCk7XG5cbiAgICAgICAgLy8gVXBkYXRlIHRpdGxlXG4gICAgICAgIGNvbnN0IG1vbnRoX25hbWVzID0gWydKYW51YXJ5JywgJ0ZlYnJ1YXJ5JywgJ01hcmNoJywgJ0FwcmlsJywgJ01heScsICdKdW5lJyxcbiAgICAgICAgICAgICdKdWx5JywgJ0F1Z3VzdCcsICdTZXB0ZW1iZXInLCAnT2N0b2JlcicsICdOb3ZlbWJlcicsICdEZWNlbWJlciddO1xuICAgICAgICB0aGlzLiRpZCgnbW9udGhfdGl0bGUnKS50ZXh0KGAke21vbnRoX25hbWVzW21vbnRoXX0gJHt5ZWFyfWApO1xuXG4gICAgICAgIC8vIEdldCBmaXJzdCBkYXkgb2YgbW9udGggYW5kIHRvdGFsIGRheXNcbiAgICAgICAgY29uc3QgZmlyc3RfZGF5ID0gbmV3IERhdGUoeWVhciwgbW9udGgsIDEpLmdldERheSgpO1xuICAgICAgICBjb25zdCBkYXlzX2luX21vbnRoID0gbmV3IERhdGUoeWVhciwgbW9udGggKyAxLCAwKS5nZXREYXRlKCk7XG5cbiAgICAgICAgY29uc3QgJHRib2R5ID0gdGhpcy4kaWQoJ2NhbGVuZGFyX2JvZHknKTtcbiAgICAgICAgJHRib2R5LmVtcHR5KCk7XG5cbiAgICAgICAgbGV0IGRheSA9IDE7XG4gICAgICAgIGxldCAkdHIgPSBudWxsO1xuXG4gICAgICAgIC8vIEJ1aWxkIGNhbGVuZGFyIGdyaWRcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCA2OyBpKyspIHtcbiAgICAgICAgICAgICR0ciA9ICQoJzx0cj4nKTtcblxuICAgICAgICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCA3OyBqKyspIHtcbiAgICAgICAgICAgICAgICBjb25zdCAkdGQgPSAkKCc8dGQ+JykuY3NzKHtcbiAgICAgICAgICAgICAgICAgICAgJ2hlaWdodCc6ICcxMDBweCcsXG4gICAgICAgICAgICAgICAgICAgICd2ZXJ0aWNhbC1hbGlnbic6ICd0b3AnLFxuICAgICAgICAgICAgICAgICAgICAncGFkZGluZyc6ICc4cHgnXG4gICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgICBpZiAoaSA9PT0gMCAmJiBqIDwgZmlyc3RfZGF5KSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIEVtcHR5IGNlbGwgYmVmb3JlIG1vbnRoIHN0YXJ0c1xuICAgICAgICAgICAgICAgICAgICAkdGQuYWRkQ2xhc3MoJ2JnLWxpZ2h0Jyk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChkYXkgPiBkYXlzX2luX21vbnRoKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIEVtcHR5IGNlbGwgYWZ0ZXIgbW9udGggZW5kc1xuICAgICAgICAgICAgICAgICAgICAkdGQuYWRkQ2xhc3MoJ2JnLWxpZ2h0Jyk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gRGF5IGNlbGxcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgJGRheV9udW0gPSAkKCc8ZGl2PicpLmFkZENsYXNzKCdmdy1ib2xkIG1iLTInKS50ZXh0KGRheSk7XG5cbiAgICAgICAgICAgICAgICAgICAgLy8gSGlnaGxpZ2h0IHRvZGF5XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHRvZGF5ID0gbmV3IERhdGUoKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGRheSA9PT0gdG9kYXkuZ2V0RGF0ZSgpICYmIG1vbnRoID09PSB0b2RheS5nZXRNb250aCgpICYmIHllYXIgPT09IHRvZGF5LmdldEZ1bGxZZWFyKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICRkYXlfbnVtLmFkZENsYXNzKCd0ZXh0LXByaW1hcnknKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICR0ZC5hZGRDbGFzcygnYm9yZGVyLXByaW1hcnknKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICR0ZC5hcHBlbmQoJGRheV9udW0pO1xuXG4gICAgICAgICAgICAgICAgICAgIC8vIEFkZCBldmVudHMgZm9yIHRoaXMgZGF5IGlmIHByb3ZpZGVkXG4gICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLmFyZ3MuZXZlbnRzKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBldmVudHMgPSB0aGlzLmdldF9ldmVudHNfZm9yX2RhdGUoeWVhciwgbW9udGgsIGRheSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBldmVudHMuZm9yRWFjaChldmVudCA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgJGV2ZW50ID0gJCgnPGRpdj4nKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuYWRkQ2xhc3MoJ2JhZGdlIGJnLXByaW1hcnkgdGV4dC10cnVuY2F0ZSB3LTEwMCBtYi0xIHRleHQtc3RhcnQnKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuY3NzKCdjdXJzb3InLCAncG9pbnRlcicpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC50ZXh0KGV2ZW50LnRpdGxlKTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICRldmVudC5vbignY2xpY2snLCAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLmFyZ3Mub25fZXZlbnRfY2xpY2spIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuYXJncy5vbl9ldmVudF9jbGljayhldmVudCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICR0ZC5hcHBlbmQoJGV2ZW50KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgJHRkLmF0dHIoJ2RhdGEtZGF0ZScsIGAke3llYXJ9LSR7c3RyKG1vbnRoICsgMSkucGFkU3RhcnQoMiwgJzAnKX0tJHtzdHIoZGF5KS5wYWRTdGFydCgyLCAnMCcpfWApO1xuICAgICAgICAgICAgICAgICAgICAkdGQuY3NzKCdjdXJzb3InLCAncG9pbnRlcicpO1xuXG4gICAgICAgICAgICAgICAgICAgICR0ZC5vbignY2xpY2snLCAoZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuYXJncy5vbl9kYXRlX2NsaWNrICYmICEkKGUudGFyZ2V0KS5oYXNDbGFzcygnYmFkZ2UnKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuYXJncy5vbl9kYXRlX2NsaWNrKCR0ZC5hdHRyKCdkYXRhLWRhdGUnKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICAgICAgIGRheSsrO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICR0ci5hcHBlbmQoJHRkKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgJHRib2R5LmFwcGVuZCgkdHIpO1xuXG4gICAgICAgICAgICBpZiAoZGF5ID4gZGF5c19pbl9tb250aCkgYnJlYWs7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBnZXRfZXZlbnRzX2Zvcl9kYXRlKHllYXIsIG1vbnRoLCBkYXkpIHtcbiAgICAgICAgaWYgKCF0aGlzLmFyZ3MuZXZlbnRzKSByZXR1cm4gW107XG5cbiAgICAgICAgY29uc3QgZGF0ZV9zdHIgPSBgJHt5ZWFyfS0ke3N0cihtb250aCArIDEpLnBhZFN0YXJ0KDIsICcwJyl9LSR7c3RyKGRheSkucGFkU3RhcnQoMiwgJzAnKX1gO1xuXG4gICAgICAgIHJldHVybiB0aGlzLmFyZ3MuZXZlbnRzLmZpbHRlcihldmVudCA9PiB7XG4gICAgICAgICAgICByZXR1cm4gZXZlbnQuZGF0ZSA9PT0gZGF0ZV9zdHI7XG4gICAgICAgIH0pO1xuICAgIH1cbn1cbiIsIi8qKlxuICogQ2FyZCAtIEJvb3RzdHJhcCA1IENvbnRlbnQgQ29udGFpbmVyIENvbXBvbmVudFxuICpcbiAqIFB1cnBvc2U6IFByaW1hcnkgY29udGVudCBjb250YWluZXIgdXNpbmcgQm9vdHN0cmFwIC5jYXJkIGNsYXNzXG4gKiBEZXNpZ246IFB1cmUgQm9vdHN0cmFwIC0gYm9yZGVyLTAgd2l0aCBzaGFkb3cgZm9yIG1vZGVybiBWb2x0IGFlc3RoZXRpY1xuICovXG5jbGFzcyBDYXJkIGV4dGVuZHMgSnFodG1sX0NvbXBvbmVudCB7XG4gICAgLy8gQ2FyZCBpcyBhIHB1cmUgY29udGFpbmVyIGNvbXBvbmVudCAtIG5vIGxpZmVjeWNsZSBtZXRob2RzIG5lZWRlZFxuICAgIC8vIEFsbCBzdHlsaW5nIGNvbWVzIGZyb20gQm9vdHN0cmFwIGNsYXNzZXM6IGNhcmQsIGJvcmRlci0wLCBzaGFkb3dcbn1cbiIsImNsYXNzIENoYXJ0X0NvbXBvbmVudCBleHRlbmRzIEpxaHRtbF9Db21wb25lbnQge1xuICAgIC8vIFBsYWNlaG9sZGVyIGNvbXBvbmVudCAtIG5vIGZ1bmN0aW9uYWxpdHkgeWV0XG59XG4iLCIvKipcbiAqIENoZWNrYm94IC0gQm9vdHN0cmFwIDUgQ2hlY2tib3ggSW5wdXQgQ29tcG9uZW50XG4gKlxuICogUHVycG9zZTogU2luZ2xlIGNoZWNrYm94IGZvciB5ZXMvbm8sIHRydWUvZmFsc2Ugc2VsZWN0aW9uc1xuICogRGVzaWduOiBCb290c3RyYXAgLmZvcm0tY2hlY2staW5wdXQgc3R5bGluZ1xuICogV3JhcHBlcjogVHlwaWNhbGx5IHVzZWQgd2l0aGluIDxkaXYgY2xhc3M9XCJmb3JtLWNoZWNrXCI+IGZvciBwcm9wZXIgbGF5b3V0XG4gKi9cbmNsYXNzIENoZWNrYm94IGV4dGVuZHMgSnFodG1sX0NvbXBvbmVudCB7XG4gICAgb25fcmVhZHkoKSB7XG4gICAgICAgIC8vIFNldCBjaGVja2VkIHN0YXRlIGlmIHByb3ZpZGVkXG4gICAgICAgIGlmICh0aGlzLmFyZ3MuY2hlY2tlZCkge1xuICAgICAgICAgICAgdGhpcy4kLnByb3AoJ2NoZWNrZWQnLCB0cnVlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFNldCB2YWx1ZSBpZiBwcm92aWRlZFxuICAgICAgICBpZiAodGhpcy5hcmdzLnZhbHVlKSB7XG4gICAgICAgICAgICB0aGlzLiQudmFsKHRoaXMuYXJncy52YWx1ZSk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBBZGQgY3VzdG9tIGNsYXNzZXMgaWYgcHJvdmlkZWRcbiAgICAgICAgaWYgKHRoaXMuYXJncy5jbGFzcykge1xuICAgICAgICAgICAgdGhpcy4kLmFkZENsYXNzKHRoaXMuYXJncy5jbGFzcyk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBTZXQgZGlzYWJsZWQgc3RhdGUgaWYgcHJvdmlkZWRcbiAgICAgICAgaWYgKHRoaXMuYXJncy5kaXNhYmxlZCkge1xuICAgICAgICAgICAgdGhpcy4kLnByb3AoJ2Rpc2FibGVkJywgdHJ1ZSk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBTZXQgcmVxdWlyZWQgYXR0cmlidXRlIGlmIHByb3ZpZGVkXG4gICAgICAgIGlmICh0aGlzLmFyZ3MucmVxdWlyZWQpIHtcbiAgICAgICAgICAgIHRoaXMuJC5wcm9wKCdyZXF1aXJlZCcsIHRydWUpO1xuICAgICAgICB9XG4gICAgfVxufVxuIiwiY2xhc3MgQ29kZV9CbG9jayBleHRlbmRzIEpxaHRtbF9Db21wb25lbnQge1xuICAgIG9uX3JlYWR5KCkge1xuICAgICAgICAvLyBObyBzcGVjaWFsIGJlaGF2aW9yIChzeW50YXggaGlnaGxpZ2h0aW5nIGNvdWxkIGJlIGFkZGVkIGxhdGVyKVxuICAgIH1cbn1cbiIsImNsYXNzIENvbHVtbl9WaXNpYmlsaXR5X1RvZ2dsZSBleHRlbmRzIEpxaHRtbF9Db21wb25lbnQge1xuICAgIG9uX3JlYWR5KCkge1xuICAgICAgICAvLyBCdWlsZCBjb2x1bW4gY2hlY2tib3hlc1xuICAgICAgICBpZiAodGhpcy5hcmdzLmNvbHVtbnMpIHtcbiAgICAgICAgICAgIHRoaXMuYnVpbGRfbWVudSh0aGlzLmFyZ3MuY29sdW1ucyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBidWlsZF9tZW51KGNvbHVtbnMpIHtcbiAgICAgICAgY29uc3QgJG1lbnUgPSB0aGlzLiRpZCgnbWVudScpO1xuICAgICAgICAkbWVudS5lbXB0eSgpO1xuXG4gICAgICAgIGNvbHVtbnMuZm9yRWFjaCgoY29sdW1uLCBpbmRleCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgJGxpID0gJCgnPGxpPicpO1xuICAgICAgICAgICAgY29uc3QgJGxhYmVsID0gJCgnPGxhYmVsPicpLmFkZENsYXNzKCdkcm9wZG93bi1pdGVtJyk7XG4gICAgICAgICAgICBjb25zdCAkY2hlY2tib3ggPSAkKCc8aW5wdXQ+JylcbiAgICAgICAgICAgICAgICAuYWRkQ2xhc3MoJ2Zvcm0tY2hlY2staW5wdXQgbWUtMicpXG4gICAgICAgICAgICAgICAgLmF0dHIoJ3R5cGUnLCAnY2hlY2tib3gnKVxuICAgICAgICAgICAgICAgIC5wcm9wKCdjaGVja2VkJywgY29sdW1uLnZpc2libGUgIT09IGZhbHNlKVxuICAgICAgICAgICAgICAgIC5hdHRyKCdkYXRhLWNvbHVtbi1pbmRleCcsIGluZGV4KTtcblxuICAgICAgICAgICAgJGxhYmVsLmFwcGVuZCgkY2hlY2tib3gpLmFwcGVuZChjb2x1bW4ubGFiZWwgfHwgY29sdW1uLm5hbWUpO1xuICAgICAgICAgICAgJGxpLmFwcGVuZCgkbGFiZWwpO1xuICAgICAgICAgICAgJG1lbnUuYXBwZW5kKCRsaSk7XG5cbiAgICAgICAgICAgICRjaGVja2JveC5vbignY2hhbmdlJywgKGUpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLnRvZ2dsZV9jb2x1bW4oaW5kZXgsIGUudGFyZ2V0LmNoZWNrZWQpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHRvZ2dsZV9jb2x1bW4oaW5kZXgsIHZpc2libGUpIHtcbiAgICAgICAgaWYgKHRoaXMuYXJncy5vbl90b2dnbGUpIHtcbiAgICAgICAgICAgIHRoaXMuYXJncy5vbl90b2dnbGUoaW5kZXgsIHZpc2libGUpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gRmluZCB0YWJsZSBhbmQgdG9nZ2xlIGNvbHVtbiB2aXNpYmlsaXR5XG4gICAgICAgIGNvbnN0ICR0YWJsZSA9IHRoaXMuYXJncy50YWJsZSA/ICQodGhpcy5hcmdzLnRhYmxlKSA6IHRoaXMuJC5jbG9zZXN0KCcuY2FyZCcpLmZpbmQoJ3RhYmxlJyk7XG4gICAgICAgIGNvbnN0IHNlbGVjdG9yID0gYHRoOm50aC1jaGlsZCgke2luZGV4ICsgMX0pLCB0ZDpudGgtY2hpbGQoJHtpbmRleCArIDF9KWA7XG5cbiAgICAgICAgaWYgKHZpc2libGUpIHtcbiAgICAgICAgICAgICR0YWJsZS5maW5kKHNlbGVjdG9yKS5zaG93KCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAkdGFibGUuZmluZChzZWxlY3RvcikuaGlkZSgpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgc2V0X2NvbHVtbnMoY29sdW1ucykge1xuICAgICAgICB0aGlzLmJ1aWxkX21lbnUoY29sdW1ucyk7XG4gICAgfVxufVxuIiwiY2xhc3MgQ29tbWVudF9UaHJlYWQgZXh0ZW5kcyBKcWh0bWxfQ29tcG9uZW50IHtcbiAgICBhc3luYyBvbl9sb2FkKCkge1xuICAgICAgICBpZiAodGhpcy5hcmdzLmRhdGFfc291cmNlKSB7XG4gICAgICAgICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKHRoaXMuYXJncy5kYXRhX3NvdXJjZSk7XG4gICAgICAgICAgICB0aGlzLmRhdGEuY29tbWVudHMgPSBhd2FpdCByZXNwb25zZS5qc29uKCk7XG4gICAgICAgIH0gZWxzZSBpZiAodGhpcy5hcmdzLmNvbW1lbnRzKSB7XG4gICAgICAgICAgICB0aGlzLmRhdGEuY29tbWVudHMgPSB0aGlzLmFyZ3MuY29tbWVudHM7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBvbl9yZWFkeSgpIHtcbiAgICAgICAgLy8gU3VibWl0IG5ldyBjb21tZW50XG4gICAgICAgIHRoaXMuJGlkKCdzdWJtaXRfYnRuJykub24oJ2NsaWNrJywgKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5zdWJtaXRfY29tbWVudCgpO1xuICAgICAgICB9KTtcblxuICAgICAgICAvLyBSZXBseSBidXR0b25zXG4gICAgICAgIHRoaXMuJC5maW5kKCcucmVwbHktYnRuJykub24oJ2NsaWNrJywgKGUpID0+IHtcbiAgICAgICAgICAgIGNvbnN0ICRjb21tZW50ID0gJChlLnRhcmdldCkuY2xvc2VzdCgnW2RhdGEtY29tbWVudC1pZF0nKTtcbiAgICAgICAgICAgIGNvbnN0IGNvbW1lbnRfaWQgPSAkY29tbWVudC5hdHRyKCdkYXRhLWNvbW1lbnQtaWQnKTtcbiAgICAgICAgICAgIHRoaXMuc2hvd19yZXBseV9mb3JtKGNvbW1lbnRfaWQpO1xuICAgICAgICB9KTtcblxuICAgICAgICAvLyBFZGl0IGJ1dHRvbnNcbiAgICAgICAgdGhpcy4kLmZpbmQoJy5lZGl0LWJ0bicpLm9uKCdjbGljaycsIChlKSA9PiB7XG4gICAgICAgICAgICBjb25zdCAkY29tbWVudCA9ICQoZS50YXJnZXQpLmNsb3Nlc3QoJ1tkYXRhLWNvbW1lbnQtaWRdJyk7XG4gICAgICAgICAgICBjb25zdCBjb21tZW50X2lkID0gJGNvbW1lbnQuYXR0cignZGF0YS1jb21tZW50LWlkJyk7XG4gICAgICAgICAgICB0aGlzLmVkaXRfY29tbWVudChjb21tZW50X2lkKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gRGVsZXRlIGJ1dHRvbnNcbiAgICAgICAgdGhpcy4kLmZpbmQoJy5kZWxldGUtYnRuJykub24oJ2NsaWNrJywgKGUpID0+IHtcbiAgICAgICAgICAgIGNvbnN0ICRjb21tZW50ID0gJChlLnRhcmdldCkuY2xvc2VzdCgnW2RhdGEtY29tbWVudC1pZF0nKTtcbiAgICAgICAgICAgIGNvbnN0IGNvbW1lbnRfaWQgPSAkY29tbWVudC5hdHRyKCdkYXRhLWNvbW1lbnQtaWQnKTtcbiAgICAgICAgICAgIHRoaXMuZGVsZXRlX2NvbW1lbnQoY29tbWVudF9pZCk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIGFzeW5jIHN1Ym1pdF9jb21tZW50KCkge1xuICAgICAgICBjb25zdCB0ZXh0ID0gdGhpcy4kaWQoJ2NvbW1lbnRfaW5wdXQnKS52YWwoKS50cmltKCk7XG4gICAgICAgIGlmICghdGV4dCkgcmV0dXJuO1xuXG4gICAgICAgIGlmICh0aGlzLmFyZ3Mub25fc3VibWl0KSB7XG4gICAgICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB0aGlzLmFyZ3Mub25fc3VibWl0KHRleHQpO1xuICAgICAgICAgICAgaWYgKHJlc3VsdCkge1xuICAgICAgICAgICAgICAgIHRoaXMuJGlkKCdjb21tZW50X2lucHV0JykudmFsKCcnKTtcbiAgICAgICAgICAgICAgICBhd2FpdCB0aGlzLnJlbG9hZF9kYXRhKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBzaG93X3JlcGx5X2Zvcm0oY29tbWVudF9pZCkge1xuICAgICAgICAvLyBUT0RPOiBJbXBsZW1lbnQgcmVwbHkgZm9ybSBVSVxuICAgICAgICBjb25zb2xlLmxvZygnUmVwbHkgdG8gY29tbWVudDonLCBjb21tZW50X2lkKTtcbiAgICB9XG5cbiAgICBlZGl0X2NvbW1lbnQoY29tbWVudF9pZCkge1xuICAgICAgICBpZiAodGhpcy5hcmdzLm9uX2VkaXQpIHtcbiAgICAgICAgICAgIHRoaXMuYXJncy5vbl9lZGl0KGNvbW1lbnRfaWQpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgYXN5bmMgZGVsZXRlX2NvbW1lbnQoY29tbWVudF9pZCkge1xuICAgICAgICBpZiAoIWNvbmZpcm0oJ0RlbGV0ZSB0aGlzIGNvbW1lbnQ/JykpIHJldHVybjtcblxuICAgICAgICBpZiAodGhpcy5hcmdzLm9uX2RlbGV0ZSkge1xuICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgdGhpcy5hcmdzLm9uX2RlbGV0ZShjb21tZW50X2lkKTtcbiAgICAgICAgICAgIGlmIChyZXN1bHQpIHtcbiAgICAgICAgICAgICAgICBhd2FpdCB0aGlzLnJlbG9hZF9kYXRhKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBhc3luYyByZWxvYWRfZGF0YSgpIHtcbiAgICAgICAgaWYgKHRoaXMuYXJncy5kYXRhX3NvdXJjZSkge1xuICAgICAgICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBmZXRjaCh0aGlzLmFyZ3MuZGF0YV9zb3VyY2UpO1xuICAgICAgICAgICAgdGhpcy5kYXRhLmNvbW1lbnRzID0gYXdhaXQgcmVzcG9uc2UuanNvbigpO1xuICAgICAgICAgICAgdGhpcy5yZW5kZXIoKTtcbiAgICAgICAgfVxuICAgIH1cbn1cbiIsImNsYXNzIERhdGVfUGlja2VyIGV4dGVuZHMgSnFodG1sX0NvbXBvbmVudCB7XG4gICAgb25fcmVhZHkoKSB7XG4gICAgICAgIGNvbnN0ICRpbnB1dCA9IHRoaXMuJGlkKCdpbnB1dCcpO1xuXG4gICAgICAgIGlmICh0aGlzLmFyZ3MudmFsdWUpIHtcbiAgICAgICAgICAgICRpbnB1dC52YWwodGhpcy5hcmdzLnZhbHVlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLmFyZ3MubmFtZSkge1xuICAgICAgICAgICAgJGlucHV0LmF0dHIoJ25hbWUnLCB0aGlzLmFyZ3MubmFtZSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5hcmdzLm1pbikge1xuICAgICAgICAgICAgJGlucHV0LmF0dHIoJ21pbicsIHRoaXMuYXJncy5taW4pO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMuYXJncy5tYXgpIHtcbiAgICAgICAgICAgICRpbnB1dC5hdHRyKCdtYXgnLCB0aGlzLmFyZ3MubWF4KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLmFyZ3MuZGlzYWJsZWQpIHtcbiAgICAgICAgICAgICRpbnB1dC5wcm9wKCdkaXNhYmxlZCcsIHRydWUpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMuYXJncy5yZWFkb25seSkge1xuICAgICAgICAgICAgJGlucHV0LnByb3AoJ3JlYWRvbmx5JywgdHJ1ZSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5hcmdzLnJlcXVpcmVkKSB7XG4gICAgICAgICAgICAkaW5wdXQucHJvcCgncmVxdWlyZWQnLCB0cnVlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLmFyZ3Mub25fY2hhbmdlKSB7XG4gICAgICAgICAgICAkaW5wdXQub24oJ2NoYW5nZScsIChlKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5hcmdzLm9uX2NoYW5nZShlLnRhcmdldC52YWx1ZSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGdldF92YWx1ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuJGlkKCdpbnB1dCcpLnZhbCgpO1xuICAgIH1cblxuICAgIHNldF92YWx1ZSh2YWx1ZSkge1xuICAgICAgICB0aGlzLiRpZCgnaW5wdXQnKS52YWwodmFsdWUpO1xuICAgIH1cblxuICAgIGZvY3VzKCkge1xuICAgICAgICB0aGlzLiRpZCgnaW5wdXQnKS5mb2N1cygpO1xuICAgIH1cbn1cbiIsImNsYXNzIERyb3Bkb3duX01lbnUgZXh0ZW5kcyBKcWh0bWxfQ29tcG9uZW50IHtcbiAgICBvbl9yZWFkeSgpIHtcbiAgICAgICAgLy8gV3JhcCBiYXJlIHRleHQgY2hpbGRyZW4gaW4gPGxpPjxhPiBzdHJ1Y3R1cmVcbiAgICAgICAgY29uc3QgJG1lbnUgPSB0aGlzLiRpZCgnbWVudScpO1xuICAgICAgICAkbWVudS5jaGlsZHJlbigpLmVhY2goZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICBjb25zdCAkY2hpbGQgPSAkKHRoaXMpO1xuICAgICAgICAgICAgaWYgKCRjaGlsZC5wcm9wKCd0YWdOYW1lJykgIT09ICdMSScpIHtcbiAgICAgICAgICAgICAgICBjb25zdCB0ZXh0ID0gJGNoaWxkLnRleHQoKTtcbiAgICAgICAgICAgICAgICBjb25zdCBocmVmID0gJGNoaWxkLmF0dHIoJ2hyZWYnKSB8fCAnIyc7XG4gICAgICAgICAgICAgICAgY29uc3QgJGxpID0gJCgnPGxpPicpLmFwcGVuZChcbiAgICAgICAgICAgICAgICAgICAgJCgnPGE+JykuYWRkQ2xhc3MoJ2Ryb3Bkb3duLWl0ZW0nKS5hdHRyKCdocmVmJywgaHJlZikudGV4dCh0ZXh0KVxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgJGNoaWxkLnJlcGxhY2VXaXRoKCRsaSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cbn1cbiIsImNsYXNzIEVtcHR5X1N0YXRlIGV4dGVuZHMgSnFodG1sX0NvbXBvbmVudCB7XG4gICAgb25fcmVhZHkoKSB7XG4gICAgICAgIC8vIE5vIHNwZWNpYWwgYmVoYXZpb3JcbiAgICB9XG59XG4iLCJjbGFzcyBFeHBvcnRfQnV0dG9uIGV4dGVuZHMgSnFodG1sX0NvbXBvbmVudCB7XG4gICAgb25fcmVhZHkoKSB7XG4gICAgICAgIGNvbnN0IHRoYXQgPSB0aGlzO1xuICAgICAgICB0aGlzLiQuZmluZCgnW2RhdGEtZm9ybWF0XScpLm9uKCdjbGljaycsIChlKSA9PiB7XG4gICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICBjb25zdCBmb3JtYXQgPSAkKGUuY3VycmVudFRhcmdldCkuYXR0cignZGF0YS1mb3JtYXQnKTtcbiAgICAgICAgICAgIHRoYXQuZXhwb3J0X2RhdGEoZm9ybWF0KTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgYXN5bmMgZXhwb3J0X2RhdGEoZm9ybWF0KSB7XG4gICAgICAgIGlmICh0aGlzLmFyZ3Mub25fZXhwb3J0KSB7XG4gICAgICAgICAgICAvLyBDdXN0b20gZXhwb3J0IGhhbmRsZXJcbiAgICAgICAgICAgIHRoaXMuYXJncy5vbl9leHBvcnQoZm9ybWF0KTtcbiAgICAgICAgfSBlbHNlIGlmICh0aGlzLmFyZ3MuZGF0YSkge1xuICAgICAgICAgICAgLy8gQXV0by1leHBvcnQgcHJvdmlkZWQgZGF0YVxuICAgICAgICAgICAgdGhpcy5hdXRvX2V4cG9ydChmb3JtYXQsIHRoaXMuYXJncy5kYXRhKTtcbiAgICAgICAgfSBlbHNlIGlmICh0aGlzLmFyZ3MuZXhwb3J0X3VybCkge1xuICAgICAgICAgICAgLy8gRmV0Y2ggZXhwb3J0IGZyb20gVVJMXG4gICAgICAgICAgICBjb25zdCB1cmwgPSBgJHt0aGlzLmFyZ3MuZXhwb3J0X3VybH0/Zm9ybWF0PSR7Zm9ybWF0fWA7XG4gICAgICAgICAgICB3aW5kb3cubG9jYXRpb24uaHJlZiA9IHVybDtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGF1dG9fZXhwb3J0KGZvcm1hdCwgZGF0YSkge1xuICAgICAgICBpZiAoZm9ybWF0ID09PSAnY3N2Jykge1xuICAgICAgICAgICAgdGhpcy5leHBvcnRfY3N2KGRhdGEpO1xuICAgICAgICB9IGVsc2UgaWYgKGZvcm1hdCA9PT0gJ2pzb24nKSB7XG4gICAgICAgICAgICB0aGlzLmV4cG9ydF9qc29uKGRhdGEpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29uc29sZS53YXJuKCdBdXRvLWV4cG9ydCBvbmx5IHN1cHBvcnRzIENTViBhbmQgSlNPTi4gSW1wbGVtZW50IGN1c3RvbSBoYW5kbGVyIGZvciBvdGhlciBmb3JtYXRzLicpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgZXhwb3J0X2NzdihkYXRhKSB7XG4gICAgICAgIGlmIChkYXRhLmxlbmd0aCA9PT0gMCkgcmV0dXJuO1xuXG4gICAgICAgIC8vIEdlbmVyYXRlIENTVlxuICAgICAgICBjb25zdCBoZWFkZXJzID0gT2JqZWN0LmtleXMoZGF0YVswXSk7XG4gICAgICAgIGxldCBjc3YgPSBoZWFkZXJzLmpvaW4oJywnKSArICdcXG4nO1xuXG4gICAgICAgIGRhdGEuZm9yRWFjaChyb3cgPT4ge1xuICAgICAgICAgICAgY29uc3QgdmFsdWVzID0gaGVhZGVycy5tYXAoaGVhZGVyID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCB2YWx1ZSA9IHJvd1toZWFkZXJdIHx8ICcnO1xuICAgICAgICAgICAgICAgIHJldHVybiBgXCIke3N0cih2YWx1ZSkucmVwbGFjZSgvXCIvZywgJ1wiXCInKX1cImA7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGNzdiArPSB2YWx1ZXMuam9pbignLCcpICsgJ1xcbic7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIERvd25sb2FkXG4gICAgICAgIGNvbnN0IGJsb2IgPSBuZXcgQmxvYihbY3N2XSwgeyB0eXBlOiAndGV4dC9jc3YnIH0pO1xuICAgICAgICBjb25zdCB1cmwgPSB3aW5kb3cuVVJMLmNyZWF0ZU9iamVjdFVSTChibG9iKTtcbiAgICAgICAgY29uc3QgJGEgPSAkKCc8YT4nKTtcbiAgICAgICAgJGEuYXR0cignaHJlZicsIHVybCk7XG4gICAgICAgICRhLmF0dHIoJ2Rvd25sb2FkJywgYGV4cG9ydF8ke0RhdGUubm93KCl9LmNzdmApO1xuICAgICAgICAkYVswXS5jbGljaygpO1xuICAgICAgICB3aW5kb3cuVVJMLnJldm9rZU9iamVjdFVSTCh1cmwpO1xuICAgIH1cblxuICAgIGV4cG9ydF9qc29uKGRhdGEpIHtcbiAgICAgICAgY29uc3QganNvbiA9IGpzb25fZW5jb2RlKGRhdGEpO1xuICAgICAgICBjb25zdCBibG9iID0gbmV3IEJsb2IoW2pzb25dLCB7IHR5cGU6ICdhcHBsaWNhdGlvbi9qc29uJyB9KTtcbiAgICAgICAgY29uc3QgdXJsID0gd2luZG93LlVSTC5jcmVhdGVPYmplY3RVUkwoYmxvYik7XG4gICAgICAgIGNvbnN0ICRhID0gJCgnPGE+Jyk7XG4gICAgICAgICRhLmF0dHIoJ2hyZWYnLCB1cmwpO1xuICAgICAgICAkYS5hdHRyKCdkb3dubG9hZCcsIGBleHBvcnRfJHtEYXRlLm5vdygpfS5qc29uYCk7XG4gICAgICAgICRhWzBdLmNsaWNrKCk7XG4gICAgICAgIHdpbmRvdy5VUkwucmV2b2tlT2JqZWN0VVJMKHVybCk7XG4gICAgfVxufVxuIiwiY2xhc3MgRmlsZV9VcGxvYWQgZXh0ZW5kcyBKcWh0bWxfQ29tcG9uZW50IHtcbiAgICBvbl9yZWFkeSgpIHtcbiAgICAgICAgY29uc3QgJGlucHV0ID0gdGhpcy4kaWQoJ2ZpbGVfaW5wdXQnKTtcbiAgICAgICAgY29uc3QgJGRyb3Bfem9uZSA9IHRoaXMuJGlkKCdkcm9wX3pvbmUnKTtcblxuICAgICAgICBpZiAodGhpcy5hcmdzLmFjY2VwdCkge1xuICAgICAgICAgICAgJGlucHV0LmF0dHIoJ2FjY2VwdCcsIHRoaXMuYXJncy5hY2NlcHQpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMuYXJncy5tdWx0aXBsZSkge1xuICAgICAgICAgICAgJGlucHV0LmF0dHIoJ211bHRpcGxlJywgdHJ1ZSk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBDbGljayB0byB1cGxvYWRcbiAgICAgICAgJGRyb3Bfem9uZS5vbignY2xpY2snLCAoKSA9PiB7XG4gICAgICAgICAgICAkaW5wdXQuY2xpY2soKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gRmlsZSBzZWxlY3RlZFxuICAgICAgICAkaW5wdXQub24oJ2NoYW5nZScsIChlKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBmaWxlcyA9IGUudGFyZ2V0LmZpbGVzO1xuICAgICAgICAgICAgaWYgKGZpbGVzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICB0aGlzLmhhbmRsZV9maWxlcyhmaWxlcyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIERyYWcgYW5kIGRyb3BcbiAgICAgICAgJGRyb3Bfem9uZS5vbignZHJhZ292ZXInLCAoZSkgPT4ge1xuICAgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgICAgICAgICRkcm9wX3pvbmUuYWRkQ2xhc3MoJ2JvcmRlci1wcmltYXJ5IGJnLWxpZ2h0Jyk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgICRkcm9wX3pvbmUub24oJ2RyYWdsZWF2ZScsIChlKSA9PiB7XG4gICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgICAgICAgJGRyb3Bfem9uZS5yZW1vdmVDbGFzcygnYm9yZGVyLXByaW1hcnkgYmctbGlnaHQnKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgJGRyb3Bfem9uZS5vbignZHJvcCcsIChlKSA9PiB7XG4gICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgICAgICAgJGRyb3Bfem9uZS5yZW1vdmVDbGFzcygnYm9yZGVyLXByaW1hcnkgYmctbGlnaHQnKTtcblxuICAgICAgICAgICAgY29uc3QgZmlsZXMgPSBlLm9yaWdpbmFsRXZlbnQuZGF0YVRyYW5zZmVyLmZpbGVzO1xuICAgICAgICAgICAgaWYgKGZpbGVzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICB0aGlzLmhhbmRsZV9maWxlcyhmaWxlcyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIFJlbW92ZSBidXR0b25cbiAgICAgICAgdGhpcy4kaWQoJ3JlbW92ZV9idG4nKS5vbignY2xpY2snLCAoZSkgPT4ge1xuICAgICAgICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgICAgICAgIHRoaXMuY2xlYXIoKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgaGFuZGxlX2ZpbGVzKGZpbGVzKSB7XG4gICAgICAgIGNvbnN0IGZpbGUgPSBmaWxlc1swXTsgLy8gU2luZ2xlIGZpbGUgZm9yIG5vd1xuXG4gICAgICAgIC8vIFZhbGlkYXRlIGZpbGUgc2l6ZVxuICAgICAgICBpZiAodGhpcy5hcmdzLm1heF9zaXplX2J5dGVzICYmIGZpbGUuc2l6ZSA+IHRoaXMuYXJncy5tYXhfc2l6ZV9ieXRlcykge1xuICAgICAgICAgICAgYWxlcnQoYEZpbGUgaXMgdG9vIGxhcmdlLiBNYXggc2l6ZSBpcyAke3RoaXMuZm9ybWF0X3NpemUodGhpcy5hcmdzLm1heF9zaXplX2J5dGVzKX1gKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuc2VsZWN0ZWRfZmlsZSA9IGZpbGU7XG5cbiAgICAgICAgLy8gU2hvdyBmaWxlIGluZm9cbiAgICAgICAgdGhpcy4kaWQoJ3BsYWNlaG9sZGVyJykuaGlkZSgpO1xuICAgICAgICB0aGlzLiRpZCgnZmlsZV9pbmZvJykuc2hvdygpO1xuICAgICAgICB0aGlzLiRpZCgnZmlsZV9uYW1lJykudGV4dChmaWxlLm5hbWUpO1xuICAgICAgICB0aGlzLiRpZCgnZmlsZV9zaXplJykudGV4dCh0aGlzLmZvcm1hdF9zaXplKGZpbGUuc2l6ZSkpO1xuXG4gICAgICAgIC8vIEF1dG8tdXBsb2FkIGlmIGVuZHBvaW50IHByb3ZpZGVkXG4gICAgICAgIGlmICh0aGlzLmFyZ3MudXBsb2FkX3VybCkge1xuICAgICAgICAgICAgdGhpcy51cGxvYWQoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFRyaWdnZXIgY2FsbGJhY2tcbiAgICAgICAgaWYgKHRoaXMuYXJncy5vbl9zZWxlY3QpIHtcbiAgICAgICAgICAgIHRoaXMuYXJncy5vbl9zZWxlY3QoZmlsZSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBhc3luYyB1cGxvYWQoKSB7XG4gICAgICAgIGlmICghdGhpcy5zZWxlY3RlZF9maWxlIHx8ICF0aGlzLmFyZ3MudXBsb2FkX3VybCkgcmV0dXJuO1xuXG4gICAgICAgIC8vIFNob3cgcHJvZ3Jlc3NcbiAgICAgICAgdGhpcy4kaWQoJ2ZpbGVfaW5mbycpLmhpZGUoKTtcbiAgICAgICAgdGhpcy4kaWQoJ3Byb2dyZXNzJykuc2hvdygpO1xuXG4gICAgICAgIGNvbnN0IGZvcm1fZGF0YSA9IG5ldyBGb3JtRGF0YSgpO1xuICAgICAgICBmb3JtX2RhdGEuYXBwZW5kKCdmaWxlJywgdGhpcy5zZWxlY3RlZF9maWxlKTtcblxuICAgICAgICB0cnkge1xuICAgICAgICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBmZXRjaCh0aGlzLmFyZ3MudXBsb2FkX3VybCwge1xuICAgICAgICAgICAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgICAgICAgICAgIGJvZHk6IGZvcm1fZGF0YVxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHJlc3BvbnNlLmpzb24oKTtcblxuICAgICAgICAgICAgLy8gSGlkZSBwcm9ncmVzc1xuICAgICAgICAgICAgdGhpcy4kaWQoJ3Byb2dyZXNzJykuaGlkZSgpO1xuICAgICAgICAgICAgdGhpcy4kaWQoJ2ZpbGVfaW5mbycpLnNob3coKTtcblxuICAgICAgICAgICAgaWYgKHRoaXMuYXJncy5vbl91cGxvYWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmFyZ3Mub25fdXBsb2FkKHJlc3VsdCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICBhbGVydCgnVXBsb2FkIGZhaWxlZDogJyArIGVycm9yLm1lc3NhZ2UpO1xuICAgICAgICAgICAgdGhpcy4kaWQoJ3Byb2dyZXNzJykuaGlkZSgpO1xuICAgICAgICAgICAgdGhpcy4kaWQoJ3BsYWNlaG9sZGVyJykuc2hvdygpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgY2xlYXIoKSB7XG4gICAgICAgIHRoaXMuc2VsZWN0ZWRfZmlsZSA9IG51bGw7XG4gICAgICAgIHRoaXMuJGlkKCdmaWxlX2lucHV0JykudmFsKCcnKTtcbiAgICAgICAgdGhpcy4kaWQoJ2ZpbGVfaW5mbycpLmhpZGUoKTtcbiAgICAgICAgdGhpcy4kaWQoJ3Byb2dyZXNzJykuaGlkZSgpO1xuICAgICAgICB0aGlzLiRpZCgncGxhY2Vob2xkZXInKS5zaG93KCk7XG5cbiAgICAgICAgaWYgKHRoaXMuYXJncy5vbl9jbGVhcikge1xuICAgICAgICAgICAgdGhpcy5hcmdzLm9uX2NsZWFyKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBnZXRfZmlsZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuc2VsZWN0ZWRfZmlsZTtcbiAgICB9XG5cbiAgICBmb3JtYXRfc2l6ZShieXRlcykge1xuICAgICAgICBpZiAoYnl0ZXMgPCAxMDI0KSByZXR1cm4gYnl0ZXMgKyAnIEInO1xuICAgICAgICBpZiAoYnl0ZXMgPCAxMDI0ICogMTAyNCkgcmV0dXJuIChieXRlcyAvIDEwMjQpLnRvRml4ZWQoMSkgKyAnIEtCJztcbiAgICAgICAgcmV0dXJuIChieXRlcyAvICgxMDI0ICogMTAyNCkpLnRvRml4ZWQoMSkgKyAnIE1CJztcbiAgICB9XG59XG4iLCJjbGFzcyBGaWx0ZXJfQmFyIGV4dGVuZHMgSnFodG1sX0NvbXBvbmVudCB7XG4gICAgb25fcmVhZHkoKSB7XG4gICAgICAgIHRoaXMuYWN0aXZlX2ZpbHRlcnMgPSB7fTtcblxuICAgICAgICAvLyBQb3B1bGF0ZSBzdGF0dXMgb3B0aW9ucyBpZiBwcm92aWRlZFxuICAgICAgICBpZiAodGhpcy5hcmdzLnN0YXR1c19vcHRpb25zKSB7XG4gICAgICAgICAgICBjb25zdCAkc3RhdHVzID0gdGhpcy4kaWQoJ3N0YXR1cycpO1xuICAgICAgICAgICAgdGhpcy5hcmdzLnN0YXR1c19vcHRpb25zLmZvckVhY2gob3B0ID0+IHtcbiAgICAgICAgICAgICAgICAkc3RhdHVzLmFwcGVuZCgkKCc8b3B0aW9uPicpLnZhbChvcHQudmFsdWUpLnRleHQob3B0LmxhYmVsKSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIERhdGUgcmFuZ2UgY2hhbmdlIGhhbmRsZXJcbiAgICAgICAgdGhpcy4kaWQoJ2RhdGVfcmFuZ2UnKS5vbignY2hhbmdlJywgKGUpID0+IHtcbiAgICAgICAgICAgIGlmIChlLnRhcmdldC52YWx1ZSA9PT0gJ2N1c3RvbScpIHtcbiAgICAgICAgICAgICAgICB0aGlzLiRpZCgnY3VzdG9tX2RhdGVzJykuc2hvdygpO1xuICAgICAgICAgICAgICAgIHRoaXMuJGlkKCdjdXN0b21fZGF0ZXNfZW5kJykuc2hvdygpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLiRpZCgnY3VzdG9tX2RhdGVzJykuaGlkZSgpO1xuICAgICAgICAgICAgICAgIHRoaXMuJGlkKCdjdXN0b21fZGF0ZXNfZW5kJykuaGlkZSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgICAgICAvLyBTZWFyY2ggd2l0aCBkZWJvdW5jZVxuICAgICAgICBsZXQgc2VhcmNoX3RpbWVvdXQ7XG4gICAgICAgIHRoaXMuJGlkKCdzZWFyY2gnKS4kLmZpbmQoJ2lucHV0Jykub24oJ2lucHV0JywgKGUpID0+IHtcbiAgICAgICAgICAgIGNsZWFyVGltZW91dChzZWFyY2hfdGltZW91dCk7XG4gICAgICAgICAgICBzZWFyY2hfdGltZW91dCA9IHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuYWRkX2ZpbHRlcignc2VhcmNoJywgZS50YXJnZXQudmFsdWUpO1xuICAgICAgICAgICAgfSwgNTAwKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gQXBwbHkgYnV0dG9uXG4gICAgICAgIHRoaXMuJGlkKCdhcHBseV9idG4nKS5vbignY2xpY2snLCAoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmFwcGx5X2ZpbHRlcnMoKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gQ2xlYXIgYnV0dG9uXG4gICAgICAgIHRoaXMuJGlkKCdjbGVhcl9idG4nKS5vbignY2xpY2snLCAoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmNsZWFyX2ZpbHRlcnMoKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgYWRkX2ZpbHRlcihrZXksIHZhbHVlKSB7XG4gICAgICAgIGlmICh2YWx1ZSkge1xuICAgICAgICAgICAgdGhpcy5hY3RpdmVfZmlsdGVyc1trZXldID0gdmFsdWU7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBkZWxldGUgdGhpcy5hY3RpdmVfZmlsdGVyc1trZXldO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMudXBkYXRlX2ZpbHRlcl9kaXNwbGF5KCk7XG4gICAgfVxuXG4gICAgYXBwbHlfZmlsdGVycygpIHtcbiAgICAgICAgLy8gQ29sbGVjdCBhbGwgZmlsdGVyIHZhbHVlc1xuICAgICAgICBjb25zdCBzZWFyY2ggPSB0aGlzLiRpZCgnc2VhcmNoJykuZ2V0X3ZhbHVlKCk7XG4gICAgICAgIGNvbnN0IHN0YXR1cyA9IHRoaXMuJGlkKCdzdGF0dXMnKS52YWwoKTtcbiAgICAgICAgY29uc3QgZGF0ZV9yYW5nZSA9IHRoaXMuJGlkKCdkYXRlX3JhbmdlJykudmFsKCk7XG5cbiAgICAgICAgdGhpcy5hY3RpdmVfZmlsdGVycyA9IHt9O1xuXG4gICAgICAgIGlmIChzZWFyY2gpIHRoaXMuYWN0aXZlX2ZpbHRlcnMuc2VhcmNoID0gc2VhcmNoO1xuICAgICAgICBpZiAoc3RhdHVzKSB0aGlzLmFjdGl2ZV9maWx0ZXJzLnN0YXR1cyA9IHN0YXR1cztcbiAgICAgICAgaWYgKGRhdGVfcmFuZ2UpIHRoaXMuYWN0aXZlX2ZpbHRlcnMuZGF0ZV9yYW5nZSA9IGRhdGVfcmFuZ2U7XG5cbiAgICAgICAgaWYgKGRhdGVfcmFuZ2UgPT09ICdjdXN0b20nKSB7XG4gICAgICAgICAgICBjb25zdCBzdGFydF9kYXRlID0gdGhpcy4kaWQoJ3N0YXJ0X2RhdGUnKS5nZXRfdmFsdWUoKTtcbiAgICAgICAgICAgIGNvbnN0IGVuZF9kYXRlID0gdGhpcy4kaWQoJ2VuZF9kYXRlJykuZ2V0X3ZhbHVlKCk7XG4gICAgICAgICAgICBpZiAoc3RhcnRfZGF0ZSkgdGhpcy5hY3RpdmVfZmlsdGVycy5zdGFydF9kYXRlID0gc3RhcnRfZGF0ZTtcbiAgICAgICAgICAgIGlmIChlbmRfZGF0ZSkgdGhpcy5hY3RpdmVfZmlsdGVycy5lbmRfZGF0ZSA9IGVuZF9kYXRlO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy51cGRhdGVfZmlsdGVyX2Rpc3BsYXkoKTtcblxuICAgICAgICBpZiAodGhpcy5hcmdzLm9uX2FwcGx5KSB7XG4gICAgICAgICAgICB0aGlzLmFyZ3Mub25fYXBwbHkodGhpcy5hY3RpdmVfZmlsdGVycyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBjbGVhcl9maWx0ZXJzKCkge1xuICAgICAgICB0aGlzLmFjdGl2ZV9maWx0ZXJzID0ge307XG5cbiAgICAgICAgdGhpcy4kaWQoJ3NlYXJjaCcpLnNldF92YWx1ZSgnJyk7XG4gICAgICAgIHRoaXMuJGlkKCdzdGF0dXMnKS52YWwoJycpO1xuICAgICAgICB0aGlzLiRpZCgnZGF0ZV9yYW5nZScpLnZhbCgnJyk7XG4gICAgICAgIHRoaXMuJGlkKCdjdXN0b21fZGF0ZXMnKS5oaWRlKCk7XG4gICAgICAgIHRoaXMuJGlkKCdjdXN0b21fZGF0ZXNfZW5kJykuaGlkZSgpO1xuXG4gICAgICAgIHRoaXMudXBkYXRlX2ZpbHRlcl9kaXNwbGF5KCk7XG5cbiAgICAgICAgaWYgKHRoaXMuYXJncy5vbl9jbGVhcikge1xuICAgICAgICAgICAgdGhpcy5hcmdzLm9uX2NsZWFyKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICB1cGRhdGVfZmlsdGVyX2Rpc3BsYXkoKSB7XG4gICAgICAgIGNvbnN0IGNvdW50ID0gT2JqZWN0LmtleXModGhpcy5hY3RpdmVfZmlsdGVycykubGVuZ3RoO1xuICAgICAgICBjb25zdCAkY29udGFpbmVyID0gdGhpcy4kaWQoJ2FjdGl2ZV9maWx0ZXJzJyk7XG4gICAgICAgIGNvbnN0ICR0YWdzID0gdGhpcy4kaWQoJ2ZpbHRlcl90YWdzJyk7XG5cbiAgICAgICAgaWYgKGNvdW50ID09PSAwKSB7XG4gICAgICAgICAgICAkY29udGFpbmVyLmhpZGUoKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgICRjb250YWluZXIuc2hvdygpO1xuICAgICAgICAkdGFncy5lbXB0eSgpO1xuXG4gICAgICAgIGZvciAobGV0IGtleSBpbiB0aGlzLmFjdGl2ZV9maWx0ZXJzKSB7XG4gICAgICAgICAgICBjb25zdCAkdGFnID0gJCgnPHNwYW4+JykuYWRkQ2xhc3MoJ2JhZGdlIGJnLXByaW1hcnkgbWUtMScpO1xuICAgICAgICAgICAgJHRhZy50ZXh0KGAke2tleX06ICR7dGhpcy5hY3RpdmVfZmlsdGVyc1trZXldfWApO1xuXG4gICAgICAgICAgICBjb25zdCAkcmVtb3ZlID0gJCgnPGk+JykuYWRkQ2xhc3MoJ2JpIGJpLXgtY2lyY2xlIG1zLTEnKS5jc3MoJ2N1cnNvcicsICdwb2ludGVyJyk7XG4gICAgICAgICAgICAkcmVtb3ZlLm9uKCdjbGljaycsICgpID0+IHtcbiAgICAgICAgICAgICAgICBkZWxldGUgdGhpcy5hY3RpdmVfZmlsdGVyc1trZXldO1xuICAgICAgICAgICAgICAgIHRoaXMudXBkYXRlX2ZpbHRlcl9kaXNwbGF5KCk7XG4gICAgICAgICAgICAgICAgdGhpcy5hcHBseV9maWx0ZXJzKCk7XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgJHRhZy5hcHBlbmQoJHJlbW92ZSk7XG4gICAgICAgICAgICAkdGFncy5hcHBlbmQoJHRhZyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBnZXRfZmlsdGVycygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuYWN0aXZlX2ZpbHRlcnM7XG4gICAgfVxufVxuIiwiLyoqXG4gKiBGb3JtX0FjdGlvbnNfQ29tcG9uZW50IC0gSlFIVE1MIENvbXBvbmVudFxuICpcbiAqIExpZmVjeWNsZSBtZXRob2RzIGFyZSBjYWxsZWQgaW4gdGhpcyBvcmRlcjpcbiAqIDEuIG9uX2NyZWF0ZSgpIC0gUXVpY2sgVUkgc2V0dXAsIHJ1bnMgYm90dG9tLXVwIHRocm91Z2ggY29tcG9uZW50IHRyZWVcbiAqIDIuIG9uX2xvYWQoKSAtIEZldGNoIGRhdGEgZnJvbSBBUElzIChwYXJhbGxlbCBleGVjdXRpb24sIG5vIERPTSBtb2RpZmljYXRpb25zKVxuICogMy4gb25fcmVhZHkoKSAtIENvbXBvbmVudCBmdWxseSBpbml0aWFsaXplZCwgcnVucyBib3R0b20tdXAgdGhyb3VnaCBjb21wb25lbnQgdHJlZVxuICovXG5jbGFzcyBGb3JtX0FjdGlvbnNfQ29tcG9uZW50IGV4dGVuZHMgSnFodG1sX0NvbXBvbmVudCB7XG4gICAgLyoqXG4gICAgICogQ2FsbGVkIGFmdGVyIHJlbmRlciwgcXVpY2sgVUkgc2V0dXAgKGJvdHRvbS11cClcbiAgICAgKiBVc2UgZm9yOiBJbml0aWFsIHN0YXRlLCBldmVudCBiaW5kaW5ncywgc2hvd2luZyBsb2FkaW5nIGluZGljYXRvcnNcbiAgICAgKi9cbiAgICBhc3luYyBvbl9jcmVhdGUoKSB7XG4gICAgICAgIC8vIEV4YW1wbGU6IHRoaXMuJGlkKCdsb2FkaW5nJykuc2hvdygpO1xuICAgICAgICAvLyBFeGFtcGxlOiB0aGlzLiQuYWRkQ2xhc3MoJ2luaXRpYWxpemluZycpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEZldGNoIGRhdGEgZnJvbSBBUElzIChwYXJhbGxlbCwgTk8gRE9NIG1vZGlmaWNhdGlvbnMpXG4gICAgICogVXNlIGZvcjogTG9hZGluZyBkYXRhIGZyb20gc2VydmVyLCBmZXRjaGluZyBjb25maWd1cmF0aW9uc1xuICAgICAqIFdBUk5JTkc6IERvIE5PVCBtb2RpZnkgRE9NIGhlcmUgLSBvbmx5IGxvYWQgZGF0YVxuICAgICAqL1xuICAgIGFzeW5jIG9uX2xvYWQoKSB7XG4gICAgICAgIC8vIEV4YW1wbGU6IHRoaXMuZGF0YS51c2VycyA9IGF3YWl0IFVzZXJzX0NvbnRyb2xsZXIuZ2V0X3VzZXJzX2FwaSgpO1xuICAgICAgICAvLyBFeGFtcGxlOiB0aGlzLmRhdGEuY29uZmlnID0gYXdhaXQgdGhpcy5sb2FkX2NvbmZpZygpO1xuICAgICAgICAvLyBXQVJOSU5HOiBEbyBOT1QgbW9kaWZ5IERPTSBoZXJlIC0gb25seSBsb2FkIGRhdGFcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDb21wb25lbnQgZnVsbHkgaW5pdGlhbGl6ZWQgKGJvdHRvbS11cClcbiAgICAgKiBVc2UgZm9yOiBGaW5hbCBVSSBzZXR1cCwgaGlkaW5nIGxvYWRpbmcgaW5kaWNhdG9ycywgc3RhcnRpbmcgYW5pbWF0aW9uc1xuICAgICAqL1xuICAgIGFzeW5jIG9uX3JlYWR5KCkge1xuICAgICAgICAvLyBFeGFtcGxlOiB0aGlzLiRpZCgnbG9hZGluZycpLmhpZGUoKTtcbiAgICAgICAgLy8gRXhhbXBsZTogdGhpcy5zZXR1cF9ldmVudF9saXN0ZW5lcnMoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDbGljayBoYW5kbGVyIGZvciB0aGUgaGVsbG8gYnV0dG9uXG4gICAgICogUmVmZXJlbmNlZCBpbiB0ZW1wbGF0ZSB2aWEgQGNsaWNrPXRoaXMub25fY2xpY2tfaGVsbG9cbiAgICAgKi9cbiAgICBvbl9jbGlja19oZWxsbygpIHtcbiAgICAgICAgdGhpcy4kaWQoJ2lubmVyX2h0bWwnKS5oaWRlKCk7XG4gICAgICAgIHRoaXMuJGlkKCdoZWxsb193b3JsZCcpLnNob3coKTtcbiAgICB9XG5cbiAgICAvLyBGb3IgbW9yZSBpbmZvcm1hdGlvbjogcGhwIGFydGlzYW4gcnN4Om1hbiBqcWh0bWxcbn0iLCJjbGFzcyBGb3JtX0ZpZWxkX0dyb3VwIGV4dGVuZHMgSnFodG1sX0NvbXBvbmVudCB7XG4gICAgb25fcmVhZHkoKSB7XG4gICAgICAgIC8vIE9wdGlvbmFsOiBBZGQgY29sbGFwc2libGUgZnVuY3Rpb25hbGl0eVxuICAgICAgICBpZiAodGhpcy5hcmdzLmNvbGxhcHNpYmxlKSB7XG4gICAgICAgICAgICB0aGlzLm1ha2VfY29sbGFwc2libGUoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIG1ha2VfY29sbGFwc2libGUoKSB7XG4gICAgICAgIGNvbnN0ICRoZWFkZXIgPSB0aGlzLiQuZmluZCgnLmNhcmQtaGVhZGVyJyk7XG4gICAgICAgIGNvbnN0ICRib2R5ID0gdGhpcy4kLmZpbmQoJy5jYXJkLWJvZHknKTtcbiAgICAgICAgY29uc3QgY29sbGFwc2VfaWQgPSAnY29sbGFwc2VfJyArIE1hdGgucmFuZG9tKCkudG9TdHJpbmcoMzYpLnN1YnN0cigyLCA5KTtcblxuICAgICAgICAkYm9keS5hdHRyKCdpZCcsIGNvbGxhcHNlX2lkKS5hZGRDbGFzcygnY29sbGFwc2Ugc2hvdycpO1xuXG4gICAgICAgIGNvbnN0ICR0b2dnbGUgPSAkKCc8YnV0dG9uPicpXG4gICAgICAgICAgICAuYXR0cigndHlwZScsICdidXR0b24nKVxuICAgICAgICAgICAgLmFkZENsYXNzKCdidG4gYnRuLWxpbmsgYnRuLXNtIGZsb2F0LWVuZCB0ZXh0LWRlY29yYXRpb24tbm9uZScpXG4gICAgICAgICAgICAuYXR0cignZGF0YS1icy10b2dnbGUnLCAnY29sbGFwc2UnKVxuICAgICAgICAgICAgLmF0dHIoJ2RhdGEtYnMtdGFyZ2V0JywgJyMnICsgY29sbGFwc2VfaWQpXG4gICAgICAgICAgICAuaHRtbCgnPGkgY2xhc3M9XCJiaSBiaS1jaGV2cm9uLXVwXCI+PC9pPicpO1xuXG4gICAgICAgICRoZWFkZXIuZmluZCgnaDUnKS5hcHBlbmQoJHRvZ2dsZSk7XG5cbiAgICAgICAgJGJvZHkub24oJ3Nob3cuYnMuY29sbGFwc2UnLCAoKSA9PiB7XG4gICAgICAgICAgICAkdG9nZ2xlLmh0bWwoJzxpIGNsYXNzPVwiYmkgYmktY2hldnJvbi11cFwiPjwvaT4nKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgJGJvZHkub24oJ2hpZGUuYnMuY29sbGFwc2UnLCAoKSA9PiB7XG4gICAgICAgICAgICAkdG9nZ2xlLmh0bWwoJzxpIGNsYXNzPVwiYmkgYmktY2hldnJvbi1kb3duXCI+PC9pPicpO1xuICAgICAgICB9KTtcbiAgICB9XG59XG4iLCIvKipcbiAqIEZvcm1fR3JvdXBfQ29tcG9uZW50IC0gSlFIVE1MIENvbXBvbmVudFxuICpcbiAqIExpZmVjeWNsZSBtZXRob2RzIGFyZSBjYWxsZWQgaW4gdGhpcyBvcmRlcjpcbiAqIDEuIG9uX2NyZWF0ZSgpIC0gUXVpY2sgVUkgc2V0dXAsIHJ1bnMgYm90dG9tLXVwIHRocm91Z2ggY29tcG9uZW50IHRyZWVcbiAqIDIuIG9uX2xvYWQoKSAtIEZldGNoIGRhdGEgZnJvbSBBUElzIChwYXJhbGxlbCBleGVjdXRpb24sIG5vIERPTSBtb2RpZmljYXRpb25zKVxuICogMy4gb25fcmVhZHkoKSAtIENvbXBvbmVudCBmdWxseSBpbml0aWFsaXplZCwgcnVucyBib3R0b20tdXAgdGhyb3VnaCBjb21wb25lbnQgdHJlZVxuICovXG5jbGFzcyBGb3JtX0dyb3VwX0NvbXBvbmVudCBleHRlbmRzIEpxaHRtbF9Db21wb25lbnQge1xuICAgIC8qKlxuICAgICAqIENhbGxlZCBhZnRlciByZW5kZXIsIHF1aWNrIFVJIHNldHVwIChib3R0b20tdXApXG4gICAgICogVXNlIGZvcjogSW5pdGlhbCBzdGF0ZSwgZXZlbnQgYmluZGluZ3MsIHNob3dpbmcgbG9hZGluZyBpbmRpY2F0b3JzXG4gICAgICovXG4gICAgb25fY3JlYXRlKCkge1xuICAgICAgICAvLyBBcHBseSByZXNwb25zaXZlIGNvbHVtbiBjbGFzc2VzXG4gICAgICAgIGNvbnN0IGNvbF9jbGFzcyA9IHRoaXMuYXJncy5jb2xfY2xhc3MgfHwgJ2NvbC0xMiBjb2wtbWQtNiBjb2wteGwtNCc7XG4gICAgICAgIHRoaXMuJC5hZGRDbGFzcyhjb2xfY2xhc3MgKyAnIG1iLTMnKTtcbiAgICB9XG59XG4iLCIvKipcbiAqIEZvcm1fUm93X0NvbXBvbmVudCAtIEpRSFRNTCBDb21wb25lbnRcbiAqXG4gKiBMaWZlY3ljbGUgbWV0aG9kcyBhcmUgY2FsbGVkIGluIHRoaXMgb3JkZXI6XG4gKiAxLiBvbl9jcmVhdGUoKSAtIFF1aWNrIFVJIHNldHVwLCBydW5zIGJvdHRvbS11cCB0aHJvdWdoIGNvbXBvbmVudCB0cmVlXG4gKiAyLiBvbl9sb2FkKCkgLSBGZXRjaCBkYXRhIGZyb20gQVBJcyAocGFyYWxsZWwgZXhlY3V0aW9uLCBubyBET00gbW9kaWZpY2F0aW9ucylcbiAqIDMuIG9uX3JlYWR5KCkgLSBDb21wb25lbnQgZnVsbHkgaW5pdGlhbGl6ZWQsIHJ1bnMgYm90dG9tLXVwIHRocm91Z2ggY29tcG9uZW50IHRyZWVcbiAqL1xuY2xhc3MgRm9ybV9Sb3dfQ29tcG9uZW50IGV4dGVuZHMgSnFodG1sX0NvbXBvbmVudCB7XG4gICAgLyoqXG4gICAgICogQ2FsbGVkIGFmdGVyIHJlbmRlciwgcXVpY2sgVUkgc2V0dXAgKGJvdHRvbS11cClcbiAgICAgKiBVc2UgZm9yOiBJbml0aWFsIHN0YXRlLCBldmVudCBiaW5kaW5ncywgc2hvd2luZyBsb2FkaW5nIGluZGljYXRvcnNcbiAgICAgKi9cbiAgICBhc3luYyBvbl9jcmVhdGUoKSB7XG4gICAgICAgIC8vIEV4YW1wbGU6IHRoaXMuJGlkKCdsb2FkaW5nJykuc2hvdygpO1xuICAgICAgICAvLyBFeGFtcGxlOiB0aGlzLiQuYWRkQ2xhc3MoJ2luaXRpYWxpemluZycpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEZldGNoIGRhdGEgZnJvbSBBUElzIChwYXJhbGxlbCwgTk8gRE9NIG1vZGlmaWNhdGlvbnMpXG4gICAgICogVXNlIGZvcjogTG9hZGluZyBkYXRhIGZyb20gc2VydmVyLCBmZXRjaGluZyBjb25maWd1cmF0aW9uc1xuICAgICAqIFdBUk5JTkc6IERvIE5PVCBtb2RpZnkgRE9NIGhlcmUgLSBvbmx5IGxvYWQgZGF0YVxuICAgICAqL1xuICAgIGFzeW5jIG9uX2xvYWQoKSB7XG4gICAgICAgIC8vIEV4YW1wbGU6IHRoaXMuZGF0YS51c2VycyA9IGF3YWl0IFVzZXJzX0NvbnRyb2xsZXIuZ2V0X3VzZXJzX2FwaSgpO1xuICAgICAgICAvLyBFeGFtcGxlOiB0aGlzLmRhdGEuY29uZmlnID0gYXdhaXQgdGhpcy5sb2FkX2NvbmZpZygpO1xuICAgICAgICAvLyBXQVJOSU5HOiBEbyBOT1QgbW9kaWZ5IERPTSBoZXJlIC0gb25seSBsb2FkIGRhdGFcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDb21wb25lbnQgZnVsbHkgaW5pdGlhbGl6ZWQgKGJvdHRvbS11cClcbiAgICAgKiBVc2UgZm9yOiBGaW5hbCBVSSBzZXR1cCwgaGlkaW5nIGxvYWRpbmcgaW5kaWNhdG9ycywgc3RhcnRpbmcgYW5pbWF0aW9uc1xuICAgICAqL1xuICAgIGFzeW5jIG9uX3JlYWR5KCkge1xuICAgICAgICAvLyBFeGFtcGxlOiB0aGlzLiRpZCgnbG9hZGluZycpLmhpZGUoKTtcbiAgICAgICAgLy8gRXhhbXBsZTogdGhpcy5zZXR1cF9ldmVudF9saXN0ZW5lcnMoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDbGljayBoYW5kbGVyIGZvciB0aGUgaGVsbG8gYnV0dG9uXG4gICAgICogUmVmZXJlbmNlZCBpbiB0ZW1wbGF0ZSB2aWEgQGNsaWNrPXRoaXMub25fY2xpY2tfaGVsbG9cbiAgICAgKi9cbiAgICBvbl9jbGlja19oZWxsbygpIHtcbiAgICAgICAgdGhpcy4kaWQoJ2lubmVyX2h0bWwnKS5oaWRlKCk7XG4gICAgICAgIHRoaXMuJGlkKCdoZWxsb193b3JsZCcpLnNob3coKTtcbiAgICB9XG5cbiAgICAvLyBGb3IgbW9yZSBpbmZvcm1hdGlvbjogcGhwIGFydGlzYW4gcnN4Om1hbiBqcWh0bWxcbn0iLCIvKipcbiAqIEZvcm1fVmFsaWRhdGlvbl9NZXNzYWdlIC0gQm9vdHN0cmFwIDUgVmFsaWRhdGlvbiBGZWVkYmFjayBDb21wb25lbnRcbiAqXG4gKiBQdXJwb3NlOiBEaXNwbGF5IHZhbGlkYXRpb24gZmVlZGJhY2sgbWVzc2FnZXMgKHN1Y2Nlc3MvZXJyb3IpIGJlbG93IGZvcm0gaW5wdXRzXG4gKiBEZXNpZ246IEJvb3RzdHJhcCAuaW52YWxpZC1mZWVkYmFjayAoZGVmYXVsdCkgb3IgLnZhbGlkLWZlZWRiYWNrIHN0eWxpbmdcbiAqIFZpc2liaWxpdHk6IE9ubHkgc2hvd3Mgd2hlbiBzaWJsaW5nIGlucHV0IGhhcyAuaXMtdmFsaWQgb3IgLmlzLWludmFsaWQgY2xhc3NcbiAqL1xuY2xhc3MgRm9ybV9WYWxpZGF0aW9uX01lc3NhZ2UgZXh0ZW5kcyBKcWh0bWxfQ29tcG9uZW50IHtcbiAgICBvbl9yZWFkeSgpIHtcbiAgICAgICAgLy8gQWRkIGN1c3RvbSBjbGFzc2VzIGlmIHByb3ZpZGVkIChlLmcuLCBzd2l0Y2hpbmcgdG8gdmFsaWQtZmVlZGJhY2spXG4gICAgICAgIGlmICh0aGlzLmFyZ3MuY2xhc3MpIHtcbiAgICAgICAgICAgIC8vIFJlcGxhY2UgZGVmYXVsdCBpbnZhbGlkLWZlZWRiYWNrIHdpdGggcHJvdmlkZWQgY2xhc3NcbiAgICAgICAgICAgIHRoaXMuJC5yZW1vdmVDbGFzcygnaW52YWxpZC1mZWVkYmFjaycpO1xuICAgICAgICAgICAgdGhpcy4kLmFkZENsYXNzKHRoaXMuYXJncy5jbGFzcyk7XG4gICAgICAgIH1cbiAgICB9XG59XG4iLCJjbGFzcyBHYW50dF9DaGFydCBleHRlbmRzIEpxaHRtbF9Db21wb25lbnQge1xuICAgIGFzeW5jIG9uX2xvYWQoKSB7XG4gICAgICAgIGlmICh0aGlzLmFyZ3MuZGF0YV9zb3VyY2UpIHtcbiAgICAgICAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2godGhpcy5hcmdzLmRhdGFfc291cmNlKTtcbiAgICAgICAgICAgIGNvbnN0IGRhdGEgPSBhd2FpdCByZXNwb25zZS5qc29uKCk7XG4gICAgICAgICAgICB0aGlzLmRhdGEudGFza3MgPSBkYXRhLnRhc2tzO1xuICAgICAgICAgICAgdGhpcy5kYXRhLm1vbnRocyA9IGRhdGEubW9udGhzO1xuICAgICAgICB9IGVsc2UgaWYgKHRoaXMuYXJncy50YXNrcykge1xuICAgICAgICAgICAgdGhpcy5kYXRhLnRhc2tzID0gdGhpcy5hcmdzLnRhc2tzO1xuICAgICAgICAgICAgdGhpcy5kYXRhLm1vbnRocyA9IHRoaXMuYXJncy5tb250aHMgfHwgdGhpcy5nZW5lcmF0ZV9tb250aHMoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGdlbmVyYXRlX21vbnRocygpIHtcbiAgICAgICAgY29uc3QgbW9udGhzID0gWydKYW4nLCAnRmViJywgJ01hcicsICdBcHInLCAnTWF5JywgJ0p1bicsICdKdWwnLCAnQXVnJywgJ1NlcCcsICdPY3QnLCAnTm92JywgJ0RlYyddO1xuICAgICAgICByZXR1cm4gbW9udGhzO1xuICAgIH1cbn1cbiIsImNsYXNzIEljb25fQnV0dG9uIGV4dGVuZHMgSnFodG1sX0NvbXBvbmVudCB7XG4gICAgb25fcmVhZHkoKSB7XG4gICAgICAgIC8vIEFkZCBhcmlhLWxhYmVsIGZvciBhY2Nlc3NpYmlsaXR5IChpY29uLW9ubHkgYnV0dG9ucyBuZWVkIGxhYmVscylcbiAgICAgICAgaWYgKHRoaXMuYXJncy5sYWJlbCkge1xuICAgICAgICAgICAgdGhpcy4kLmF0dHIoJ2FyaWEtbGFiZWwnLCB0aGlzLmFyZ3MubGFiZWwpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gQWRkIHRpdGxlIGZvciB0b29sdGlwIG9uIGhvdmVyXG4gICAgICAgIGlmICh0aGlzLmFyZ3MudGl0bGUpIHtcbiAgICAgICAgICAgIHRoaXMuJC5hdHRyKCd0aXRsZScsIHRoaXMuYXJncy50aXRsZSk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBTdXBwb3J0IGN1c3RvbSBidXR0b24gY2xhc3NlcyAoYnRuLXByaW1hcnksIGJ0bi1kYW5nZXIsIGV0Yy4pXG4gICAgICAgIGlmICh0aGlzLmFyZ3MuY2xhc3MpIHtcbiAgICAgICAgICAgIHRoaXMuJC5hZGRDbGFzcyh0aGlzLmFyZ3MuY2xhc3MpO1xuICAgICAgICB9XG4gICAgfVxufVxuIiwiY2xhc3MgSWNvbl9XaXRoX0xhYmVsIGV4dGVuZHMgSnFodG1sX0NvbXBvbmVudCB7XG4gICAgb25fcmVhZHkoKSB7XG4gICAgICAgIC8vIE5vIHNwZWNpYWwgYmVoYXZpb3JcbiAgICB9XG59XG4iLCJjbGFzcyBJY29uX1dpdGhfVGV4dCBleHRlbmRzIEpxaHRtbF9Db21wb25lbnQge1xuICAgIC8vIFB1cmUgQm9vdHN0cmFwIHN0eWxpbmcgLSBubyBKYXZhU2NyaXB0IG5lZWRlZFxufVxuIiwiY2xhc3MgSWNvbiBleHRlbmRzIEpxaHRtbF9Db21wb25lbnQge1xuICAgIC8vIFNWRyBpY29uIGNvbnRhaW5lciB3aXRoIHNpemUgdmFyaWFudHNcbn1cbiIsImNsYXNzIEluZm9fQm94IGV4dGVuZHMgSnFodG1sX0NvbXBvbmVudCB7XG4gICAgb25fcmVhZHkoKSB7XG4gICAgICAgIC8vIEFwcGx5IGNvbG9yIGZyb20gYXJnc1xuICAgICAgICBpZiAodGhpcy5hcmdzLmNvbG9yKSB7XG4gICAgICAgICAgICB0aGlzLiQucmVtb3ZlQ2xhc3MoJ2JvcmRlci1wcmltYXJ5JykuYWRkQ2xhc3MoYGJvcmRlci0ke3RoaXMuYXJncy5jb2xvcn1gKTtcbiAgICAgICAgfVxuICAgIH1cbn1cbiIsImNsYXNzIElubGluZV9FZGl0X0ZpZWxkIGV4dGVuZHMgSnFodG1sX0NvbXBvbmVudCB7XG4gICAgb25fcmVhZHkoKSB7XG4gICAgICAgIHRoaXMuY3VycmVudF92YWx1ZSA9IHRoaXMuYXJncy52YWx1ZSB8fCAnJztcblxuICAgICAgICAvLyBFbnRlciBlZGl0IG1vZGVcbiAgICAgICAgdGhpcy4kaWQoJ2Rpc3BsYXlfbW9kZScpLm9uKCdjbGljaycsICgpID0+IHtcbiAgICAgICAgICAgIHRoaXMuZW50ZXJfZWRpdF9tb2RlKCk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIFNhdmVcbiAgICAgICAgdGhpcy4kaWQoJ3NhdmVfYnRuJykub24oJ2NsaWNrJywgKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5zYXZlKCk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIENhbmNlbFxuICAgICAgICB0aGlzLiRpZCgnY2FuY2VsX2J0bicpLm9uKCdjbGljaycsICgpID0+IHtcbiAgICAgICAgICAgIHRoaXMuY2FuY2VsKCk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIFNhdmUgb24gRW50ZXIsIGNhbmNlbCBvbiBFc2NhcGVcbiAgICAgICAgdGhpcy4kaWQoJ2lucHV0Jykub24oJ2tleWRvd24nLCAoZSkgPT4ge1xuICAgICAgICAgICAgaWYgKGUua2V5ID09PSAnRW50ZXInKSB7XG4gICAgICAgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgICAgICAgIHRoaXMuc2F2ZSgpO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChlLmtleSA9PT0gJ0VzY2FwZScpIHtcbiAgICAgICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICAgICAgdGhpcy5jYW5jZWwoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgZW50ZXJfZWRpdF9tb2RlKCkge1xuICAgICAgICBjb25zdCAkaW5wdXQgPSB0aGlzLiRpZCgnaW5wdXQnKTtcbiAgICAgICAgJGlucHV0LnZhbCh0aGlzLmN1cnJlbnRfdmFsdWUpO1xuXG4gICAgICAgIHRoaXMuJGlkKCdkaXNwbGF5X21vZGUnKS5oaWRlKCk7XG4gICAgICAgIHRoaXMuJGlkKCdlZGl0X21vZGUnKS5zaG93KCk7XG5cbiAgICAgICAgJGlucHV0LmZvY3VzKCk7XG4gICAgICAgICRpbnB1dC5zZWxlY3QoKTtcbiAgICB9XG5cbiAgICBleGl0X2VkaXRfbW9kZSgpIHtcbiAgICAgICAgdGhpcy4kaWQoJ2VkaXRfbW9kZScpLmhpZGUoKTtcbiAgICAgICAgdGhpcy4kaWQoJ2Rpc3BsYXlfbW9kZScpLnNob3coKTtcbiAgICB9XG5cbiAgICBzYXZlKCkge1xuICAgICAgICBjb25zdCBuZXdfdmFsdWUgPSB0aGlzLiRpZCgnaW5wdXQnKS52YWwoKTtcblxuICAgICAgICBpZiAobmV3X3ZhbHVlID09PSB0aGlzLmN1cnJlbnRfdmFsdWUpIHtcbiAgICAgICAgICAgIHRoaXMuZXhpdF9lZGl0X21vZGUoKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFRyaWdnZXIgY2FsbGJhY2tcbiAgICAgICAgaWYgKHRoaXMuYXJncy5vbl9zYXZlKSB7XG4gICAgICAgICAgICBjb25zdCByZXN1bHQgPSB0aGlzLmFyZ3Mub25fc2F2ZShuZXdfdmFsdWUsIHRoaXMuY3VycmVudF92YWx1ZSk7XG5cbiAgICAgICAgICAgIC8vIElmIGNhbGxiYWNrIHJldHVybnMgZmFsc2UsIGRvbid0IHNhdmVcbiAgICAgICAgICAgIGlmIChyZXN1bHQgPT09IGZhbHNlKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBJZiBjYWxsYmFjayByZXR1cm5zIGEgcHJvbWlzZSwgd2FpdCBmb3IgaXRcbiAgICAgICAgICAgIGlmIChyZXN1bHQgJiYgdHlwZW9mIHJlc3VsdC50aGVuID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zaG93X3NhdmluZygpO1xuICAgICAgICAgICAgICAgIHJlc3VsdC50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5jdXJyZW50X3ZhbHVlID0gbmV3X3ZhbHVlO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnVwZGF0ZV9kaXNwbGF5KCk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZXhpdF9lZGl0X21vZGUoKTtcbiAgICAgICAgICAgICAgICB9KS5jYXRjaCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZXhpdF9lZGl0X21vZGUoKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmN1cnJlbnRfdmFsdWUgPSBuZXdfdmFsdWU7XG4gICAgICAgIHRoaXMudXBkYXRlX2Rpc3BsYXkoKTtcbiAgICAgICAgdGhpcy5leGl0X2VkaXRfbW9kZSgpO1xuICAgIH1cblxuICAgIGNhbmNlbCgpIHtcbiAgICAgICAgdGhpcy5leGl0X2VkaXRfbW9kZSgpO1xuICAgIH1cblxuICAgIHVwZGF0ZV9kaXNwbGF5KCkge1xuICAgICAgICBjb25zdCBkaXNwbGF5ID0gdGhpcy5jdXJyZW50X3ZhbHVlIHx8IHRoaXMuYXJncy5wbGFjZWhvbGRlciB8fCAnQ2xpY2sgdG8gZWRpdCc7XG4gICAgICAgIHRoaXMuJGlkKCd2YWx1ZV9kaXNwbGF5JykudGV4dChkaXNwbGF5KTtcbiAgICB9XG5cbiAgICBzaG93X3NhdmluZygpIHtcbiAgICAgICAgdGhpcy4kaWQoJ3NhdmVfYnRuJykucHJvcCgnZGlzYWJsZWQnLCB0cnVlKS5odG1sKCc8c3BhbiBjbGFzcz1cInNwaW5uZXItYm9yZGVyIHNwaW5uZXItYm9yZGVyLXNtXCI+PC9zcGFuPicpO1xuICAgICAgICB0aGlzLiRpZCgnY2FuY2VsX2J0bicpLnByb3AoJ2Rpc2FibGVkJywgdHJ1ZSk7XG4gICAgfVxuXG4gICAgZ2V0X3ZhbHVlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5jdXJyZW50X3ZhbHVlO1xuICAgIH1cblxuICAgIHNldF92YWx1ZSh2YWx1ZSkge1xuICAgICAgICB0aGlzLmN1cnJlbnRfdmFsdWUgPSB2YWx1ZTtcbiAgICAgICAgdGhpcy51cGRhdGVfZGlzcGxheSgpO1xuICAgIH1cbn1cbiIsImNsYXNzIElucHV0X1dpdGhfSWNvbiBleHRlbmRzIEpxaHRtbF9Db21wb25lbnQge1xuICAgIG9uX3JlYWR5KCkge1xuICAgICAgICBjb25zdCAkaW5wdXQgPSB0aGlzLiRpZCgnaW5wdXQnKTtcblxuICAgICAgICBpZiAodGhpcy5hcmdzLnZhbHVlKSB7XG4gICAgICAgICAgICAkaW5wdXQudmFsKHRoaXMuYXJncy52YWx1ZSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5hcmdzLm5hbWUpIHtcbiAgICAgICAgICAgICRpbnB1dC5hdHRyKCduYW1lJywgdGhpcy5hcmdzLm5hbWUpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMuYXJncy5kaXNhYmxlZCkge1xuICAgICAgICAgICAgJGlucHV0LnByb3AoJ2Rpc2FibGVkJywgdHJ1ZSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5hcmdzLnJlYWRvbmx5KSB7XG4gICAgICAgICAgICAkaW5wdXQucHJvcCgncmVhZG9ubHknLCB0cnVlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLmFyZ3Mub25fY2hhbmdlKSB7XG4gICAgICAgICAgICAkaW5wdXQub24oJ2NoYW5nZScsIChlKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5hcmdzLm9uX2NoYW5nZShlLnRhcmdldC52YWx1ZSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLmFyZ3Mub25faW5wdXQpIHtcbiAgICAgICAgICAgICRpbnB1dC5vbignaW5wdXQnLCAoZSkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuYXJncy5vbl9pbnB1dChlLnRhcmdldC52YWx1ZSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGdldF92YWx1ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuJGlkKCdpbnB1dCcpLnZhbCgpO1xuICAgIH1cblxuICAgIHNldF92YWx1ZSh2YWx1ZSkge1xuICAgICAgICB0aGlzLiRpZCgnaW5wdXQnKS52YWwodmFsdWUpO1xuICAgIH1cblxuICAgIGZvY3VzKCkge1xuICAgICAgICB0aGlzLiRpZCgnaW5wdXQnKS5mb2N1cygpO1xuICAgIH1cbn1cbiIsImNsYXNzIElucHV0X1dpdGhfVmFsaWRhdGlvbiBleHRlbmRzIEpxaHRtbF9Db21wb25lbnQge1xuICAgIG9uX3JlYWR5KCkge1xuICAgICAgICBjb25zdCAkaW5wdXQgPSB0aGlzLiRpZCgnaW5wdXQnKTtcblxuICAgICAgICBpZiAodGhpcy5hcmdzLnZhbHVlKSB7XG4gICAgICAgICAgICAkaW5wdXQudmFsKHRoaXMuYXJncy52YWx1ZSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5hcmdzLm5hbWUpIHtcbiAgICAgICAgICAgICRpbnB1dC5hdHRyKCduYW1lJywgdGhpcy5hcmdzLm5hbWUpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMuYXJncy5yZXF1aXJlZCkge1xuICAgICAgICAgICAgJGlucHV0LnByb3AoJ3JlcXVpcmVkJywgdHJ1ZSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5hcmdzLmRpc2FibGVkKSB7XG4gICAgICAgICAgICAkaW5wdXQucHJvcCgnZGlzYWJsZWQnLCB0cnVlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLmFyZ3MucmVhZG9ubHkpIHtcbiAgICAgICAgICAgICRpbnB1dC5wcm9wKCdyZWFkb25seScsIHRydWUpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gUmVhbC10aW1lIHZhbGlkYXRpb25cbiAgICAgICAgaWYgKHRoaXMuYXJncy52YWxpZGF0ZSkge1xuICAgICAgICAgICAgJGlucHV0Lm9uKCdibHVyJywgKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMudmFsaWRhdGUoKTtcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAkaW5wdXQub24oJ2lucHV0JywgKCkgPT4ge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLiQuaGFzQ2xhc3MoJ3dhcy12YWxpZGF0ZWQnKSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnZhbGlkYXRlKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5hcmdzLm9uX2NoYW5nZSkge1xuICAgICAgICAgICAgJGlucHV0Lm9uKCdjaGFuZ2UnLCAoZSkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuYXJncy5vbl9jaGFuZ2UoZS50YXJnZXQudmFsdWUpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICB2YWxpZGF0ZSgpIHtcbiAgICAgICAgY29uc3QgdmFsdWUgPSB0aGlzLiRpZCgnaW5wdXQnKS52YWwoKTtcbiAgICAgICAgY29uc3QgJGlucHV0ID0gdGhpcy4kaWQoJ2lucHV0Jyk7XG5cbiAgICAgICAgdGhpcy4kLmFkZENsYXNzKCd3YXMtdmFsaWRhdGVkJyk7XG5cbiAgICAgICAgLy8gUnVuIHZhbGlkYXRpb24gZnVuY3Rpb25cbiAgICAgICAgaWYgKHRoaXMuYXJncy52YWxpZGF0ZSkge1xuICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gdGhpcy5hcmdzLnZhbGlkYXRlKHZhbHVlKTtcblxuICAgICAgICAgICAgaWYgKHJlc3VsdCA9PT0gdHJ1ZSB8fCByZXN1bHQgPT09IG51bGwgfHwgcmVzdWx0ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnNldF92YWxpZCgpO1xuICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLnNldF9lcnJvcihyZXN1bHQpO1xuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIC8vIEJhc2ljIHJlcXVpcmVkIGNoZWNrXG4gICAgICAgIGlmICh0aGlzLmFyZ3MucmVxdWlyZWQgJiYgIXZhbHVlKSB7XG4gICAgICAgICAgICB0aGlzLnNldF9lcnJvcignVGhpcyBmaWVsZCBpcyByZXF1aXJlZCcpO1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5zZXRfdmFsaWQoKTtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgc2V0X2Vycm9yKG1lc3NhZ2UpIHtcbiAgICAgICAgY29uc3QgJGlucHV0ID0gdGhpcy4kaWQoJ2lucHV0Jyk7XG4gICAgICAgIGNvbnN0ICRlcnJvciA9IHRoaXMuJGlkKCdlcnJvcicpO1xuXG4gICAgICAgICRpbnB1dC5yZW1vdmVDbGFzcygnaXMtdmFsaWQnKS5hZGRDbGFzcygnaXMtaW52YWxpZCcpO1xuICAgICAgICAkZXJyb3IudGV4dChtZXNzYWdlKS5jc3MoJ2Rpc3BsYXknLCAnYmxvY2snKTtcbiAgICAgICAgdGhpcy4kaWQoJ3N1Y2Nlc3MnKS5jc3MoJ2Rpc3BsYXknLCAnbm9uZScpO1xuICAgIH1cblxuICAgIHNldF92YWxpZChtZXNzYWdlKSB7XG4gICAgICAgIGNvbnN0ICRpbnB1dCA9IHRoaXMuJGlkKCdpbnB1dCcpO1xuICAgICAgICBjb25zdCAkc3VjY2VzcyA9IHRoaXMuJGlkKCdzdWNjZXNzJyk7XG5cbiAgICAgICAgJGlucHV0LnJlbW92ZUNsYXNzKCdpcy1pbnZhbGlkJykuYWRkQ2xhc3MoJ2lzLXZhbGlkJyk7XG4gICAgICAgIHRoaXMuJGlkKCdlcnJvcicpLmNzcygnZGlzcGxheScsICdub25lJyk7XG5cbiAgICAgICAgaWYgKG1lc3NhZ2UpIHtcbiAgICAgICAgICAgICRzdWNjZXNzLnRleHQobWVzc2FnZSkuY3NzKCdkaXNwbGF5JywgJ2Jsb2NrJyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAkc3VjY2Vzcy5jc3MoJ2Rpc3BsYXknLCAnbm9uZScpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgY2xlYXJfdmFsaWRhdGlvbigpIHtcbiAgICAgICAgY29uc3QgJGlucHV0ID0gdGhpcy4kaWQoJ2lucHV0Jyk7XG4gICAgICAgICRpbnB1dC5yZW1vdmVDbGFzcygnaXMtdmFsaWQgaXMtaW52YWxpZCcpO1xuICAgICAgICB0aGlzLiRpZCgnZXJyb3InKS5jc3MoJ2Rpc3BsYXknLCAnbm9uZScpO1xuICAgICAgICB0aGlzLiRpZCgnc3VjY2VzcycpLmNzcygnZGlzcGxheScsICdub25lJyk7XG4gICAgICAgIHRoaXMuJC5yZW1vdmVDbGFzcygnd2FzLXZhbGlkYXRlZCcpO1xuICAgIH1cblxuICAgIGdldF92YWx1ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuJGlkKCdpbnB1dCcpLnZhbCgpO1xuICAgIH1cblxuICAgIHNldF92YWx1ZSh2YWx1ZSkge1xuICAgICAgICB0aGlzLiRpZCgnaW5wdXQnKS52YWwodmFsdWUpO1xuICAgICAgICBpZiAodGhpcy4kLmhhc0NsYXNzKCd3YXMtdmFsaWRhdGVkJykpIHtcbiAgICAgICAgICAgIHRoaXMudmFsaWRhdGUoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZvY3VzKCkge1xuICAgICAgICB0aGlzLiRpZCgnaW5wdXQnKS5mb2N1cygpO1xuICAgIH1cbn1cbiIsIi8qKlxuICogSW5wdXQgLSBCb290c3RyYXAgNSBUZXh0IElucHV0IENvbXBvbmVudFxuICpcbiAqIFB1cnBvc2U6IFNpbmdsZS1saW5lIHRleHQgaW5wdXQgZmllbGQgZm9yIHVzZXIgZGF0YSBlbnRyeVxuICogRGVzaWduOiBCb290c3RyYXAgLmZvcm0tY29udHJvbCBzdHlsaW5nXG4gKiBUeXBlczogdGV4dCwgZW1haWwsIHBhc3N3b3JkLCBudW1iZXIsIHRlbCwgdXJsLCBkYXRlLCBldGMuXG4gKi9cbmNsYXNzIElucHV0IGV4dGVuZHMgSnFodG1sX0NvbXBvbmVudCB7XG4gICAgb25fcmVhZHkoKSB7XG4gICAgICAgIC8vIFNldCB0eXBlIGF0dHJpYnV0ZSBpZiBwcm92aWRlZFxuICAgICAgICBpZiAodGhpcy5hcmdzLnR5cGUpIHtcbiAgICAgICAgICAgIHRoaXMuJC5hdHRyKCd0eXBlJywgdGhpcy5hcmdzLnR5cGUpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gU2V0IHBsYWNlaG9sZGVyIGlmIHByb3ZpZGVkXG4gICAgICAgIGlmICh0aGlzLmFyZ3MucGxhY2Vob2xkZXIpIHtcbiAgICAgICAgICAgIHRoaXMuJC5hdHRyKCdwbGFjZWhvbGRlcicsIHRoaXMuYXJncy5wbGFjZWhvbGRlcik7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBTZXQgdmFsdWUgaWYgcHJvdmlkZWRcbiAgICAgICAgaWYgKHRoaXMuYXJncy52YWx1ZSkge1xuICAgICAgICAgICAgdGhpcy4kLnZhbCh0aGlzLmFyZ3MudmFsdWUpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gQWRkIGN1c3RvbSBjbGFzc2VzIGlmIHByb3ZpZGVkXG4gICAgICAgIGlmICh0aGlzLmFyZ3MuY2xhc3MpIHtcbiAgICAgICAgICAgIHRoaXMuJC5hZGRDbGFzcyh0aGlzLmFyZ3MuY2xhc3MpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gU2V0IGRpc2FibGVkIHN0YXRlIGlmIHByb3ZpZGVkXG4gICAgICAgIGlmICh0aGlzLmFyZ3MuZGlzYWJsZWQpIHtcbiAgICAgICAgICAgIHRoaXMuJC5wcm9wKCdkaXNhYmxlZCcsIHRydWUpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gU2V0IHJlcXVpcmVkIGF0dHJpYnV0ZSBpZiBwcm92aWRlZFxuICAgICAgICBpZiAodGhpcy5hcmdzLnJlcXVpcmVkKSB7XG4gICAgICAgICAgICB0aGlzLiQucHJvcCgncmVxdWlyZWQnLCB0cnVlKTtcbiAgICAgICAgfVxuICAgIH1cbn1cbiIsImNsYXNzIEthbmJhbl9Cb2FyZCBleHRlbmRzIEpxaHRtbF9Db21wb25lbnQge1xuICAgIGFzeW5jIG9uX2xvYWQoKSB7XG4gICAgICAgIGlmICh0aGlzLmFyZ3MuZGF0YV9zb3VyY2UpIHtcbiAgICAgICAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2godGhpcy5hcmdzLmRhdGFfc291cmNlKTtcbiAgICAgICAgICAgIHRoaXMuZGF0YS5jb2x1bW5zID0gYXdhaXQgcmVzcG9uc2UuanNvbigpO1xuICAgICAgICB9IGVsc2UgaWYgKHRoaXMuYXJncy5jb2x1bW5zKSB7XG4gICAgICAgICAgICB0aGlzLmRhdGEuY29sdW1ucyA9IHRoaXMuYXJncy5jb2x1bW5zO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgb25fcmVhZHkoKSB7XG4gICAgICAgIC8vIERyYWcgYW5kIGRyb3AgZnVuY3Rpb25hbGl0eVxuICAgICAgICB0aGlzLnNldHVwX2RyYWdfYW5kX2Ryb3AoKTtcbiAgICB9XG5cbiAgICBzZXR1cF9kcmFnX2FuZF9kcm9wKCkge1xuICAgICAgICBsZXQgZHJhZ2dlZF9jYXJkID0gbnVsbDtcblxuICAgICAgICAvLyBNYWtlIGNhcmRzIGRyYWdnYWJsZVxuICAgICAgICB0aGlzLiQuZmluZCgnW2RhdGEtY2FyZC1pZF0nKS5lYWNoKGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgY29uc3QgJGNhcmQgPSAkKHRoaXMpO1xuXG4gICAgICAgICAgICAkY2FyZC5vbignZHJhZ3N0YXJ0JywgZnVuY3Rpb24oZSkge1xuICAgICAgICAgICAgICAgIGRyYWdnZWRfY2FyZCA9IHRoaXM7XG4gICAgICAgICAgICAgICAgJCh0aGlzKS5jc3MoJ29wYWNpdHknLCAnMC41Jyk7XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgJGNhcmQub24oJ2RyYWdlbmQnLCBmdW5jdGlvbihlKSB7XG4gICAgICAgICAgICAgICAgJCh0aGlzKS5jc3MoJ29wYWNpdHknLCAnMScpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIE1ha2UgY29sdW1ucyBkcm9wcGFibGVcbiAgICAgICAgdGhpcy4kLmZpbmQoJ1tkYXRhLWNvbHVtbi1jYXJkc10nKS5lYWNoKGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgY29uc3QgJGNvbHVtbiA9ICQodGhpcyk7XG5cbiAgICAgICAgICAgICRjb2x1bW4ub24oJ2RyYWdvdmVyJywgZnVuY3Rpb24oZSkge1xuICAgICAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICAgICAgICAkY29sdW1uLmFkZENsYXNzKCdiZy1saWdodCcpO1xuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICRjb2x1bW4ub24oJ2RyYWdsZWF2ZScsIGZ1bmN0aW9uKGUpIHtcbiAgICAgICAgICAgICAgICAkY29sdW1uLnJlbW92ZUNsYXNzKCdiZy1saWdodCcpO1xuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICRjb2x1bW4ub24oJ2Ryb3AnLCBmdW5jdGlvbihlKSB7XG4gICAgICAgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgICAgICAgICRjb2x1bW4ucmVtb3ZlQ2xhc3MoJ2JnLWxpZ2h0Jyk7XG5cbiAgICAgICAgICAgICAgICBpZiAoZHJhZ2dlZF9jYXJkKSB7XG4gICAgICAgICAgICAgICAgICAgICRjb2x1bW4uYXBwZW5kKGRyYWdnZWRfY2FyZCk7XG5cbiAgICAgICAgICAgICAgICAgICAgLy8gVHJpZ2dlciBjYWxsYmFja1xuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5hcmdzLm9uX21vdmUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNhcmRfaWQgPSAkKGRyYWdnZWRfY2FyZCkuYXR0cignZGF0YS1jYXJkLWlkJyk7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjb2x1bW5faWQgPSAkY29sdW1uLmF0dHIoJ2RhdGEtY29sdW1uLWNhcmRzJyk7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmFyZ3Mub25fbW92ZShjYXJkX2lkLCBjb2x1bW5faWQpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfS5iaW5kKHRoaXMpKTtcbiAgICAgICAgfS5iaW5kKHRoaXMpKTtcbiAgICB9XG59XG4iLCJjbGFzcyBMaW5rIGV4dGVuZHMgSnFodG1sX0NvbXBvbmVudCB7XG4gICAgb25fcmVhZHkoKSB7XG4gICAgICAgIC8vIFN1cHBvcnQgJGhyZWYgYXR0cmlidXRlIGZvciBkeW5hbWljIFVSTHNcbiAgICAgICAgaWYgKHRoaXMuYXJncy5ocmVmKSB7XG4gICAgICAgICAgICB0aGlzLiQuYXR0cignaHJlZicsIHRoaXMuYXJncy5ocmVmKTtcbiAgICAgICAgfVxuICAgIH1cbn1cbiIsImNsYXNzIExpc3QgZXh0ZW5kcyBKcWh0bWxfQ29tcG9uZW50IHtcbiAgICBvbl9yZWFkeSgpIHtcbiAgICAgICAgLy8gQWRkIGxpc3QtZ3JvdXAtaXRlbSBjbGFzcyB0byBlYWNoIGRpcmVjdCBjaGlsZFxuICAgICAgICB0aGlzLiQuY2hpbGRyZW4oKS5lYWNoKGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgY29uc3QgJGVsZW1lbnQgPSAkKHRoaXMpO1xuICAgICAgICAgICAgJGVsZW1lbnQuYWRkQ2xhc3MoJ2xpc3QtZ3JvdXAtaXRlbScpO1xuICAgICAgICB9KTtcbiAgICB9XG59XG4iLCJjbGFzcyBMb2FkaW5nX1NrZWxldG9uIGV4dGVuZHMgSnFodG1sX0NvbXBvbmVudCB7XG4gICAgb25fcmVhZHkoKSB7XG4gICAgICAgIC8vIEFwcGx5IGxpbmVzIGZyb20gYXJnc1xuICAgICAgICBpZiAodGhpcy5hcmdzLmxpbmVzKSB7XG4gICAgICAgICAgICB0aGlzLiQuZW1wdHkoKTtcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5hcmdzLmxpbmVzOyBpKyspIHtcbiAgICAgICAgICAgICAgICBjb25zdCB3aWR0aCA9IDEyIC0gKGkgKiAyKTtcbiAgICAgICAgICAgICAgICBjb25zdCAkc3BhbiA9ICQoJzxzcGFuPicpLmFkZENsYXNzKGBwbGFjZWhvbGRlciBjb2wtJHtNYXRoLm1heCh3aWR0aCwgNil9YCk7XG4gICAgICAgICAgICAgICAgdGhpcy4kLmFwcGVuZCgkc3Bhbik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG59XG4iLCJjbGFzcyBNZXRyaWNfQ2FyZCBleHRlbmRzIEpxaHRtbF9Db21wb25lbnQge1xuICAgIC8vIFB1cmUgY29udGFpbmVyIC0gY2hpbGRyZW4gYWxyZWFkeSBzdHlsZWRcbn1cbiIsImNsYXNzIE1vYmlsZV9IZWFkZXIgZXh0ZW5kcyBKcWh0bWxfQ29tcG9uZW50IHtcbiAgICBvbl9yZWFkeSgpIHtcbiAgICAgICAgLy8gTm8gc3BlY2lhbCBiZWhhdmlvclxuICAgIH1cbn1cbiIsImNsYXNzIE1vZGFsX0RpYWxvZyBleHRlbmRzIEpxaHRtbF9Db21wb25lbnQge1xuICAgIG9uX3JlYWR5KCkge1xuICAgICAgICAvLyBJbml0aWFsaXplIEJvb3RzdHJhcCBtb2RhbFxuICAgICAgICB0aGlzLm1vZGFsID0gbmV3IGJvb3RzdHJhcC5Nb2RhbCh0aGlzLiRbMF0pO1xuICAgIH1cblxuICAgIHNob3coKSB7XG4gICAgICAgIHRoaXMubW9kYWwuc2hvdygpO1xuICAgIH1cblxuICAgIGhpZGUoKSB7XG4gICAgICAgIHRoaXMubW9kYWwuaGlkZSgpO1xuICAgIH1cbn1cbiIsImNsYXNzIE11bHRpX1NlbGVjdCBleHRlbmRzIEpxaHRtbF9Db21wb25lbnQge1xuICAgIG9uX3JlYWR5KCkge1xuICAgICAgICB0aGlzLnNlbGVjdGVkX3ZhbHVlcyA9IHRoaXMuYXJncy52YWx1ZSB8fCBbXTtcbiAgICAgICAgdGhpcy5hbGxfb3B0aW9ucyA9IHRoaXMuYXJncy5vcHRpb25zIHx8IFtdO1xuXG4gICAgICAgIGlmICh0aGlzLmFsbF9vcHRpb25zLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIHRoaXMucmVuZGVyX29wdGlvbnModGhpcy5hbGxfb3B0aW9ucyk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBTZWFyY2ggZnVuY3Rpb25hbGl0eVxuICAgICAgICBjb25zdCAkc2VhcmNoID0gdGhpcy4kaWQoJ3NlYXJjaCcpO1xuICAgICAgICAkc2VhcmNoLm9uKCdpbnB1dCcsIChlKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmZpbHRlcl9vcHRpb25zKGUudGFyZ2V0LnZhbHVlKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gUHJldmVudCBkcm9wZG93biBjbG9zZSB3aGVuIGNsaWNraW5nIGluc2lkZVxuICAgICAgICB0aGlzLiRpZCgnbWVudScpLm9uKCdjbGljaycsIChlKSA9PiB7XG4gICAgICAgICAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgICB9KTtcblxuICAgICAgICAvLyBDbGVhci9TZWxlY3QgYWxsIGJ1dHRvbnNcbiAgICAgICAgdGhpcy4kaWQoJ2NsZWFyX2FsbCcpLm9uKCdjbGljaycsICgpID0+IHtcbiAgICAgICAgICAgIHRoaXMuY2xlYXJfYWxsKCk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHRoaXMuJGlkKCdzZWxlY3RfYWxsJykub24oJ2NsaWNrJywgKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5zZWxlY3RfYWxsKCk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIFVwZGF0ZSBkaXNwbGF5XG4gICAgICAgIHRoaXMudXBkYXRlX2Rpc3BsYXkoKTtcbiAgICB9XG5cbiAgICByZW5kZXJfb3B0aW9ucyhvcHRpb25zKSB7XG4gICAgICAgIGNvbnN0ICRjb250YWluZXIgPSB0aGlzLiRpZCgnb3B0aW9ucycpO1xuICAgICAgICAkY29udGFpbmVyLmVtcHR5KCk7XG5cbiAgICAgICAgaWYgKG9wdGlvbnMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAkY29udGFpbmVyLmFwcGVuZCgkKCc8ZGl2PicpLmFkZENsYXNzKCdweC0zIHB5LTIgdGV4dC1tdXRlZCcpLnRleHQoJ05vIG9wdGlvbnMgZm91bmQnKSk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBvcHRpb25zLmZvckVhY2gob3B0aW9uID0+IHtcbiAgICAgICAgICAgIGNvbnN0ICRsYWJlbCA9ICQoJzxsYWJlbD4nKS5hZGRDbGFzcygnZHJvcGRvd24taXRlbSBtYi0wJyk7XG4gICAgICAgICAgICBjb25zdCAkY2hlY2tib3ggPSAkKCc8aW5wdXQ+JylcbiAgICAgICAgICAgICAgICAuYXR0cigndHlwZScsICdjaGVja2JveCcpXG4gICAgICAgICAgICAgICAgLmFkZENsYXNzKCdmb3JtLWNoZWNrLWlucHV0IG1lLTInKVxuICAgICAgICAgICAgICAgIC5hdHRyKCdkYXRhLXZhbHVlJywgb3B0aW9uLnZhbHVlKVxuICAgICAgICAgICAgICAgIC5wcm9wKCdjaGVja2VkJywgdGhpcy5zZWxlY3RlZF92YWx1ZXMuaW5jbHVkZXMob3B0aW9uLnZhbHVlKSk7XG5cbiAgICAgICAgICAgICRjaGVja2JveC5vbignY2hhbmdlJywgKGUpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLnRvZ2dsZV9vcHRpb24ob3B0aW9uLnZhbHVlLCBlLnRhcmdldC5jaGVja2VkKTtcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAkbGFiZWwuYXBwZW5kKCRjaGVja2JveCkuYXBwZW5kKG9wdGlvbi5sYWJlbCk7XG4gICAgICAgICAgICAkY29udGFpbmVyLmFwcGVuZCgkbGFiZWwpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBmaWx0ZXJfb3B0aW9ucyhxdWVyeSkge1xuICAgICAgICBjb25zdCBmaWx0ZXJlZCA9IHRoaXMuYWxsX29wdGlvbnMuZmlsdGVyKG9wdCA9PlxuICAgICAgICAgICAgb3B0LmxhYmVsLnRvTG93ZXJDYXNlKCkuaW5jbHVkZXMocXVlcnkudG9Mb3dlckNhc2UoKSlcbiAgICAgICAgKTtcbiAgICAgICAgdGhpcy5yZW5kZXJfb3B0aW9ucyhmaWx0ZXJlZCk7XG4gICAgfVxuXG4gICAgdG9nZ2xlX29wdGlvbih2YWx1ZSwgY2hlY2tlZCkge1xuICAgICAgICBpZiAoY2hlY2tlZCkge1xuICAgICAgICAgICAgaWYgKCF0aGlzLnNlbGVjdGVkX3ZhbHVlcy5pbmNsdWRlcyh2YWx1ZSkpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnNlbGVjdGVkX3ZhbHVlcy5wdXNoKHZhbHVlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuc2VsZWN0ZWRfdmFsdWVzID0gdGhpcy5zZWxlY3RlZF92YWx1ZXMuZmlsdGVyKHYgPT4gdiAhPT0gdmFsdWUpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy51cGRhdGVfZGlzcGxheSgpO1xuXG4gICAgICAgIGlmICh0aGlzLmFyZ3Mub25fY2hhbmdlKSB7XG4gICAgICAgICAgICB0aGlzLmFyZ3Mub25fY2hhbmdlKHRoaXMuc2VsZWN0ZWRfdmFsdWVzKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHVwZGF0ZV9kaXNwbGF5KCkge1xuICAgICAgICBjb25zdCBjb3VudCA9IHRoaXMuc2VsZWN0ZWRfdmFsdWVzLmxlbmd0aDtcbiAgICAgICAgY29uc3QgJHRleHQgPSB0aGlzLiRpZCgnc2VsZWN0ZWRfdGV4dCcpO1xuXG4gICAgICAgIGlmIChjb3VudCA9PT0gMCkge1xuICAgICAgICAgICAgJHRleHQudGV4dCh0aGlzLmFyZ3MucGxhY2Vob2xkZXIgfHwgJ1NlbGVjdCBvcHRpb25zJyk7XG4gICAgICAgIH0gZWxzZSBpZiAoY291bnQgPT09IDEpIHtcbiAgICAgICAgICAgIGNvbnN0IG9wdGlvbiA9IHRoaXMuYWxsX29wdGlvbnMuZmluZChvcHQgPT4gb3B0LnZhbHVlID09PSB0aGlzLnNlbGVjdGVkX3ZhbHVlc1swXSk7XG4gICAgICAgICAgICAkdGV4dC50ZXh0KG9wdGlvbiA/IG9wdGlvbi5sYWJlbCA6ICcxIHNlbGVjdGVkJyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAkdGV4dC50ZXh0KGAke2NvdW50fSBzZWxlY3RlZGApO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgY2xlYXJfYWxsKCkge1xuICAgICAgICB0aGlzLnNlbGVjdGVkX3ZhbHVlcyA9IFtdO1xuICAgICAgICB0aGlzLiRpZCgnb3B0aW9ucycpLmZpbmQoJ2lucHV0W3R5cGU9XCJjaGVja2JveFwiXScpLnByb3AoJ2NoZWNrZWQnLCBmYWxzZSk7XG4gICAgICAgIHRoaXMudXBkYXRlX2Rpc3BsYXkoKTtcblxuICAgICAgICBpZiAodGhpcy5hcmdzLm9uX2NoYW5nZSkge1xuICAgICAgICAgICAgdGhpcy5hcmdzLm9uX2NoYW5nZSh0aGlzLnNlbGVjdGVkX3ZhbHVlcyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBzZWxlY3RfYWxsKCkge1xuICAgICAgICB0aGlzLnNlbGVjdGVkX3ZhbHVlcyA9IHRoaXMuYWxsX29wdGlvbnMubWFwKG9wdCA9PiBvcHQudmFsdWUpO1xuICAgICAgICB0aGlzLiRpZCgnb3B0aW9ucycpLmZpbmQoJ2lucHV0W3R5cGU9XCJjaGVja2JveFwiXScpLnByb3AoJ2NoZWNrZWQnLCB0cnVlKTtcbiAgICAgICAgdGhpcy51cGRhdGVfZGlzcGxheSgpO1xuXG4gICAgICAgIGlmICh0aGlzLmFyZ3Mub25fY2hhbmdlKSB7XG4gICAgICAgICAgICB0aGlzLmFyZ3Mub25fY2hhbmdlKHRoaXMuc2VsZWN0ZWRfdmFsdWVzKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGdldF92YWx1ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuc2VsZWN0ZWRfdmFsdWVzO1xuICAgIH1cblxuICAgIHNldF92YWx1ZSh2YWx1ZXMpIHtcbiAgICAgICAgdGhpcy5zZWxlY3RlZF92YWx1ZXMgPSB2YWx1ZXM7XG4gICAgICAgIHRoaXMuJGlkKCdvcHRpb25zJykuZmluZCgnaW5wdXRbdHlwZT1cImNoZWNrYm94XCJdJykuZWFjaCgoaSwgZWwpID0+IHtcbiAgICAgICAgICAgIGNvbnN0ICRlbCA9ICQoZWwpO1xuICAgICAgICAgICAgJGVsLnByb3AoJ2NoZWNrZWQnLCB2YWx1ZXMuaW5jbHVkZXMoJGVsLmF0dHIoJ2RhdGEtdmFsdWUnKSkpO1xuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy51cGRhdGVfZGlzcGxheSgpO1xuICAgIH1cblxuICAgIHNldF9vcHRpb25zKG9wdGlvbnMpIHtcbiAgICAgICAgdGhpcy5hbGxfb3B0aW9ucyA9IG9wdGlvbnM7XG4gICAgICAgIHRoaXMucmVuZGVyX29wdGlvbnMob3B0aW9ucyk7XG4gICAgfVxufVxuIiwiY2xhc3MgTm90aWZpY2F0aW9uX0JhZGdlIGV4dGVuZHMgSnFodG1sX0NvbXBvbmVudCB7XG4gICAgb25fcmVhZHkoKSB7XG4gICAgICAgIGNvbnN0ICRjb3VudCA9IHRoaXMuJGlkKCdjb3VudCcpO1xuICAgICAgICAvLyBVcGRhdGUgY291bnQgZHluYW1pY2FsbHlcbiAgICAgICAgaWYgKHRoaXMuYXJncy5jb3VudCA9PT0gMCB8fCB0aGlzLmFyZ3MuY291bnQgPT09ICcwJykge1xuICAgICAgICAgICAgJGNvdW50LmhpZGUoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHNldF9jb3VudChjb3VudCkge1xuICAgICAgICBjb25zdCAkY291bnQgPSB0aGlzLiRpZCgnY291bnQnKTtcbiAgICAgICAgJGNvdW50LnRleHQoY291bnQpO1xuICAgICAgICBpZiAoY291bnQgPiAwKSB7XG4gICAgICAgICAgICAkY291bnQuc2hvdygpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgJGNvdW50LmhpZGUoKTtcbiAgICAgICAgfVxuICAgIH1cbn1cbiIsImNsYXNzIE5vdGlmaWNhdGlvbl9Ecm9wZG93biBleHRlbmRzIEpxaHRtbF9Db21wb25lbnQge1xuICAgIG9uX3JlYWR5KCkge1xuICAgICAgICAvLyBObyBzcGVjaWFsIGJlaGF2aW9yXG4gICAgfVxufVxuIiwiY2xhc3MgT3ZlcmR1ZV9JbmRpY2F0b3IgZXh0ZW5kcyBKcWh0bWxfQ29tcG9uZW50IHtcbiAgICAvLyBQdXJlIEJvb3RzdHJhcCBzdHlsaW5nIC0gbm8gSmF2YVNjcmlwdCBuZWVkZWRcbn1cbiIsIi8qKlxuICogUGFnZV9IZWFkZXIgLSBCb290c3RyYXAgNSBQYWdlIEFjdGlvbiBCYXIgQ29tcG9uZW50XG4gKlxuICogUHVycG9zZTogVG9wIHNlY3Rpb24gb2YgcGFnZSBjb250YWluaW5nIHRpdGxlLCBicmVhZGNydW1icywgYW5kIGFjdGlvbnNcbiAqIERlc2lnbjogRmxleGJveCBsYXlvdXQgdXNpbmcgQm9vdHN0cmFwIHV0aWxpdHkgY2xhc3Nlc1xuICogTGF5b3V0OiBUaXRsZS9icmVhZGNydW1icyBvbiBsZWZ0LCBhY3Rpb25zL2J1dHRvbnMgb24gcmlnaHRcbiAqL1xuY2xhc3MgUGFnZV9IZWFkZXIgZXh0ZW5kcyBKcWh0bWxfQ29tcG9uZW50IHtcbiAgICAvLyBQYWdlX0hlYWRlciBpcyBhIHB1cmUgY29udGFpbmVyIGNvbXBvbmVudCAtIG5vIGxpZmVjeWNsZSBtZXRob2RzIG5lZWRlZFxuICAgIC8vIEFsbCBsYXlvdXQgZnJvbSBCb290c3RyYXAgdXRpbGl0aWVzOiBkLWZsZXgsIGp1c3RpZnktY29udGVudC1iZXR3ZWVuLCBhbGlnbi1pdGVtcy1jZW50ZXIsIHB5LTRcbn1cbiIsImNsYXNzIFBhZ2VfU2VjdGlvbiBleHRlbmRzIEpxaHRtbF9Db21wb25lbnQge1xuICAgIC8vIENvbnRlbnQgc2VjdGlvbiB3aXRoIHNwYWNpbmcgLSBubyBzcGVjaWFsIGJlaGF2aW9yIG5lZWRlZFxufVxuIiwiY2xhc3MgUGFnZSBleHRlbmRzIEpxaHRtbF9Db21wb25lbnQge1xuICAgIC8vIFNlbWFudGljIHBhZ2UgY29udGFpbmVyIC0gbm8gc3BlY2lhbCBiZWhhdmlvciBuZWVkZWRcbn1cbiIsImNsYXNzIFBvcG92ZXIgZXh0ZW5kcyBKcWh0bWxfQ29tcG9uZW50IHtcbiAgICBvbl9yZWFkeSgpIHtcbiAgICAgICAgLy8gU2V0IHBvcG92ZXIgY29udGVudCBmcm9tIGFyZ3NcbiAgICAgICAgaWYgKHRoaXMuYXJncy50aXRsZSkge1xuICAgICAgICAgICAgdGhpcy4kLmF0dHIoJ2RhdGEtYnMtdGl0bGUnLCB0aGlzLmFyZ3MudGl0bGUpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMuYXJncy5jb250ZW50KSB7XG4gICAgICAgICAgICB0aGlzLiQuYXR0cignZGF0YS1icy1jb250ZW50JywgdGhpcy5hcmdzLmNvbnRlbnQpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gU2V0IHRyaWdnZXIgKGhvdmVyLCBjbGljaywgZm9jdXMpXG4gICAgICAgIHRoaXMuJC5hdHRyKCdkYXRhLWJzLXRyaWdnZXInLCB0aGlzLmFyZ3MudHJpZ2dlciB8fCAnY2xpY2snKTtcblxuICAgICAgICAvLyBJbml0aWFsaXplIEJvb3RzdHJhcCBwb3BvdmVyXG4gICAgICAgIG5ldyBib290c3RyYXAuUG9wb3Zlcih0aGlzLiRbMF0pO1xuICAgIH1cbn1cbiIsImNsYXNzIFByb2dyZXNzX0JhciBleHRlbmRzIEpxaHRtbF9Db21wb25lbnQge1xuICAgIG9uX3JlYWR5KCkge1xuICAgICAgICBjb25zdCAkYmFyID0gdGhpcy4kaWQoJ2JhcicpO1xuXG4gICAgICAgIC8vIEFwcGx5IGNvbG9yIGZyb20gYXJnc1xuICAgICAgICBpZiAodGhpcy5hcmdzLmNvbG9yKSB7XG4gICAgICAgICAgICAkYmFyLmFkZENsYXNzKGBiZy0ke3RoaXMuYXJncy5jb2xvcn1gKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFNob3cgdmFsdWUgdGV4dCBpZiByZXF1ZXN0ZWRcbiAgICAgICAgaWYgKHRoaXMuYXJncy5zaG93X3ZhbHVlKSB7XG4gICAgICAgICAgICAkYmFyLnRleHQoYCR7dGhpcy5hcmdzLnZhbHVlIHx8IDB9JWApO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgc2V0X3ZhbHVlKHZhbHVlKSB7XG4gICAgICAgIGNvbnN0ICRiYXIgPSB0aGlzLiRpZCgnYmFyJyk7XG4gICAgICAgICRiYXIuY3NzKCd3aWR0aCcsIGAke3ZhbHVlfSVgKS5hdHRyKCdhcmlhLXZhbHVlbm93JywgdmFsdWUpO1xuICAgICAgICBpZiAodGhpcy5hcmdzLnNob3dfdmFsdWUpIHtcbiAgICAgICAgICAgICRiYXIudGV4dChgJHt2YWx1ZX0lYCk7XG4gICAgICAgIH1cbiAgICB9XG59XG4iLCIvKipcbiAqIFJhZGlvX0J1dHRvbiAtIEJvb3RzdHJhcCA1IFJhZGlvIElucHV0IENvbXBvbmVudFxuICpcbiAqIFB1cnBvc2U6IFJhZGlvIGJ1dHRvbiBmb3IgbXV0dWFsbHkgZXhjbHVzaXZlIHNlbGVjdGlvbnMgd2l0aGluIGEgZ3JvdXBcbiAqIERlc2lnbjogQm9vdHN0cmFwIC5mb3JtLWNoZWNrLWlucHV0IHN0eWxpbmcgd2l0aCBjaXJjdWxhciBzaGFwZVxuICogQ1JJVElDQUw6IEFsbCByYWRpb3MgaW4gc2FtZSBncm91cCBtdXN0IGhhdmUgc2FtZSBcIm5hbWVcIiBhdHRyaWJ1dGVcbiAqIFdyYXBwZXI6IFR5cGljYWxseSB1c2VkIHdpdGhpbiA8ZGl2IGNsYXNzPVwiZm9ybS1jaGVja1wiPiBhbmQgPGZpZWxkc2V0PlxuICovXG5jbGFzcyBSYWRpb19CdXR0b24gZXh0ZW5kcyBKcWh0bWxfQ29tcG9uZW50IHtcbiAgICBvbl9yZWFkeSgpIHtcbiAgICAgICAgLy8gU2V0IG5hbWUgYXR0cmlidXRlIChDUklUSUNBTCBmb3IgZ3JvdXBpbmcpXG4gICAgICAgIGlmICh0aGlzLmFyZ3MubmFtZSkge1xuICAgICAgICAgICAgdGhpcy4kLmF0dHIoJ25hbWUnLCB0aGlzLmFyZ3MubmFtZSk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBTZXQgY2hlY2tlZCBzdGF0ZSBpZiBwcm92aWRlZFxuICAgICAgICBpZiAodGhpcy5hcmdzLmNoZWNrZWQpIHtcbiAgICAgICAgICAgIHRoaXMuJC5wcm9wKCdjaGVja2VkJywgdHJ1ZSk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBTZXQgdmFsdWUgaWYgcHJvdmlkZWRcbiAgICAgICAgaWYgKHRoaXMuYXJncy52YWx1ZSkge1xuICAgICAgICAgICAgdGhpcy4kLnZhbCh0aGlzLmFyZ3MudmFsdWUpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gQWRkIGN1c3RvbSBjbGFzc2VzIGlmIHByb3ZpZGVkXG4gICAgICAgIGlmICh0aGlzLmFyZ3MuY2xhc3MpIHtcbiAgICAgICAgICAgIHRoaXMuJC5hZGRDbGFzcyh0aGlzLmFyZ3MuY2xhc3MpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gU2V0IGRpc2FibGVkIHN0YXRlIGlmIHByb3ZpZGVkXG4gICAgICAgIGlmICh0aGlzLmFyZ3MuZGlzYWJsZWQpIHtcbiAgICAgICAgICAgIHRoaXMuJC5wcm9wKCdkaXNhYmxlZCcsIHRydWUpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gU2V0IHJlcXVpcmVkIGF0dHJpYnV0ZSBpZiBwcm92aWRlZFxuICAgICAgICBpZiAodGhpcy5hcmdzLnJlcXVpcmVkKSB7XG4gICAgICAgICAgICB0aGlzLiQucHJvcCgncmVxdWlyZWQnLCB0cnVlKTtcbiAgICAgICAgfVxuICAgIH1cbn1cbiIsImNsYXNzIFJpY2hfVGV4dF9FZGl0b3IgZXh0ZW5kcyBKcWh0bWxfQ29tcG9uZW50IHtcbiAgICBvbl9yZWFkeSgpIHtcbiAgICAgICAgY29uc3QgJGVkaXRvciA9IHRoaXMuJGlkKCdlZGl0b3InKTtcblxuICAgICAgICAvLyBUb29sYmFyIGJ1dHRvbiBoYW5kbGVyc1xuICAgICAgICB0aGlzLiRpZCgndG9vbGJhcicpLmZpbmQoJ1tkYXRhLWNvbW1hbmRdJykub24oJ2NsaWNrJywgKGUpID0+IHtcbiAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICAgIGNvbnN0IGNvbW1hbmQgPSAkKGUuY3VycmVudFRhcmdldCkuYXR0cignZGF0YS1jb21tYW5kJyk7XG5cbiAgICAgICAgICAgIGlmIChjb21tYW5kID09PSAnY3JlYXRlTGluaycpIHtcbiAgICAgICAgICAgICAgICBjb25zdCB1cmwgPSBwcm9tcHQoJ0VudGVyIFVSTDonKTtcbiAgICAgICAgICAgICAgICBpZiAodXJsKSB7XG4gICAgICAgICAgICAgICAgICAgIGRvY3VtZW50LmV4ZWNDb21tYW5kKGNvbW1hbmQsIGZhbHNlLCB1cmwpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgZG9jdW1lbnQuZXhlY0NvbW1hbmQoY29tbWFuZCwgZmFsc2UsIG51bGwpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAkZWRpdG9yLmZvY3VzKCk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIFRyYWNrIGNoYW5nZXNcbiAgICAgICAgJGVkaXRvci5vbignaW5wdXQnLCAoKSA9PiB7XG4gICAgICAgICAgICBpZiAodGhpcy5hcmdzLm9uX2NoYW5nZSkge1xuICAgICAgICAgICAgICAgIHRoaXMuYXJncy5vbl9jaGFuZ2UodGhpcy5nZXRfdmFsdWUoKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIFByZXZlbnQgZGVmYXVsdCBiZWhhdmlvciBvbiBwYXN0ZSAob3B0aW9uYWwgLSBjYW4gYmUgY3VzdG9taXplZClcbiAgICAgICAgJGVkaXRvci5vbigncGFzdGUnLCAoZSkgPT4ge1xuICAgICAgICAgICAgaWYgKHRoaXMuYXJncy5wbGFpbl90ZXh0X3Bhc3RlKSB7XG4gICAgICAgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgICAgICAgIGNvbnN0IHRleHQgPSBlLm9yaWdpbmFsRXZlbnQuY2xpcGJvYXJkRGF0YS5nZXREYXRhKCd0ZXh0L3BsYWluJyk7XG4gICAgICAgICAgICAgICAgZG9jdW1lbnQuZXhlY0NvbW1hbmQoJ2luc2VydFRleHQnLCBmYWxzZSwgdGV4dCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIGdldF92YWx1ZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuJGlkKCdlZGl0b3InKS5odG1sKCk7XG4gICAgfVxuXG4gICAgZ2V0X3RleHQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLiRpZCgnZWRpdG9yJykudGV4dCgpO1xuICAgIH1cblxuICAgIHNldF92YWx1ZShodG1sKSB7XG4gICAgICAgIHRoaXMuJGlkKCdlZGl0b3InKS5odG1sKGh0bWwpO1xuICAgIH1cblxuICAgIGNsZWFyKCkge1xuICAgICAgICB0aGlzLiRpZCgnZWRpdG9yJykuZW1wdHkoKTtcbiAgICB9XG5cbiAgICBmb2N1cygpIHtcbiAgICAgICAgdGhpcy4kaWQoJ2VkaXRvcicpLmZvY3VzKCk7XG4gICAgfVxufVxuIiwiY2xhc3MgUm93X0FjdGlvbl9NZW51IGV4dGVuZHMgSnFodG1sX0NvbXBvbmVudCB7XG4gICAgb25fcmVhZHkoKSB7XG4gICAgICAgIC8vIFdyYXAgY2hpbGRyZW4gaW4gZHJvcGRvd24gc3RydWN0dXJlXG4gICAgICAgIGNvbnN0ICRtZW51ID0gdGhpcy4kaWQoJ21lbnUnKTtcbiAgICAgICAgJG1lbnUuY2hpbGRyZW4oKS5lYWNoKGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgY29uc3QgJGNoaWxkID0gJCh0aGlzKTtcbiAgICAgICAgICAgIGlmICgkY2hpbGQucHJvcCgndGFnTmFtZScpICE9PSAnTEknKSB7XG4gICAgICAgICAgICAgICAgaWYgKCRjaGlsZC5wcm9wKCd0YWdOYW1lJykgPT09ICdIUicpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgJGxpID0gJCgnPGxpPicpLmFwcGVuZCgkKCc8aHI+JykuYWRkQ2xhc3MoJ2Ryb3Bkb3duLWRpdmlkZXInKSk7XG4gICAgICAgICAgICAgICAgICAgICRjaGlsZC5yZXBsYWNlV2l0aCgkbGkpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICRjaGlsZC5hZGRDbGFzcygnZHJvcGRvd24taXRlbScpO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCAkbGkgPSAkKCc8bGk+Jyk7XG4gICAgICAgICAgICAgICAgICAgICRjaGlsZC53cmFwKCRsaSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG59XG4iLCIvKipcbiAqIFNhbXBsZV9EYXRhZ3JpZF9Db21wb25lbnRcbiAqXG4gKiBGdWxsLWZlYXR1cmVkIGRhdGEgdGFibGUgd2l0aDpcbiAqIC0gUm93IHNlbGVjdGlvbiAoY2hlY2tib3hlcylcbiAqIC0gUGFnaW5hdGlvblxuICogLSBSb3cgYWN0aW9ucyAodmlldywgZWRpdCwgZGVsZXRlKVxuICogLSBMb2FkaW5nIHN0YXRlcyB3aXRoIHBsYWNlaG9sZGVyc1xuICogLSBFbXB0eSBzdGF0ZXNcbiAqXG4gKiBVc2FnZTpcbiAqIDxTYW1wbGVfRGF0YWdyaWRfQ29tcG9uZW50XG4gKiAgICR0aXRsZT1cIkNsaWVudCBMaXN0XCJcbiAqICAgJGVudGl0eV9uYW1lPVwiY2xpZW50c1wiXG4gKiAgICRzZWxlY3RhYmxlPXRydWVcbiAqICAgJHBhZ2luYXRpb249dHJ1ZVxuICogICAkYWxsb3dfZGVsZXRlPXRydWVcbiAqICAgJHZpZXdfdXJsPVwiL2NsaWVudHMve2lkfVwiXG4gKiAgICRlZGl0X3VybD1cIi9jbGllbnRzL3tpZH0vZWRpdFwiXG4gKiAgICRhcGlfdXJsPVwiL2FwaS9jbGllbnRzXCJcbiAqICAgJGNvbHVtbnM9Y29sdW1uc19kZWZpbml0aW9uXG4gKiAvPlxuICovXG5jbGFzcyBTYW1wbGVfRGF0YWdyaWRfQ29tcG9uZW50IGV4dGVuZHMgSnFodG1sX0NvbXBvbmVudCB7XG5cbiAgYXN5bmMgb25fbG9hZCgpIHtcbiAgICBjb25zdCB0aGF0ID0gdGhpcztcbiAgICAvLyBJZiBBUEkgVVJMIHByb3ZpZGVkLCBmZXRjaCBkYXRhXG4gICAgaWYgKHRoYXQuYXJncy5hcGlfdXJsKSB7XG4gICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKHRoYXQuYXJncy5hcGlfdXJsKTtcbiAgICAgIHRoYXQuZGF0YSA9IGF3YWl0IHJlc3BvbnNlLmpzb24oKTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gR2VuZXJhdGUgc2FtcGxlIGRhdGEgZm9yIGRlbW9uc3RyYXRpb25cbiAgICAgIHRoYXQuZGF0YSA9IHRoYXQuZ2VuZXJhdGVfc2FtcGxlX2RhdGEoKTtcbiAgICB9XG4gIH1cblxuICBvbl9yZWFkeSgpIHtcbiAgICBjb25zdCB0aGF0ID0gdGhpcztcbiAgICAvLyBTZWxlY3QgYWxsIGNoZWNrYm94XG4gICAgaWYgKHRoYXQuYXJncy5zZWxlY3RhYmxlKSB7XG4gICAgICB0aGF0LiRpZCgnc2VsZWN0X2FsbCcpLm9uKCdjaGFuZ2UnLCAoZSkgPT4ge1xuICAgICAgICBjb25zdCBjaGVja2VkID0gZS50YXJnZXQuY2hlY2tlZDtcbiAgICAgICAgdGhhdC4kLmZpbmQoJ3Rib2R5IGlucHV0W3R5cGU9XCJjaGVja2JveFwiXScpLnByb3AoJ2NoZWNrZWQnLCBjaGVja2VkKTtcbiAgICAgICAgdGhhdC51cGRhdGVfc2VsZWN0aW9uX2NvdW50KCk7XG4gICAgICB9KTtcblxuICAgICAgLy8gSW5kaXZpZHVhbCByb3cgY2hlY2tib3hlc1xuICAgICAgdGhhdC4kLmZpbmQoJ3Rib2R5IGlucHV0W3R5cGU9XCJjaGVja2JveFwiXScpLm9uKCdjaGFuZ2UnLCAoKSA9PiB7XG4gICAgICAgIHRoYXQudXBkYXRlX3NlbGVjdGlvbl9jb3VudCgpO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLy8gRGVsZXRlIGJ1dHRvbnNcbiAgICBpZiAodGhhdC5hcmdzLmFsbG93X2RlbGV0ZSkge1xuICAgICAgdGhhdC4kLmZpbmQoJ2J1dHRvbltkYXRhLWlkXScpLm9uKCdjbGljaycsIChlKSA9PiB7XG4gICAgICAgIGNvbnN0ICRidXR0b24gPSAkKGUuY3VycmVudFRhcmdldCk7XG4gICAgICAgIGNvbnN0IGlkID0gJGJ1dHRvbi5kYXRhKCdpZCcpO1xuICAgICAgICB0aGF0LmNvbmZpcm1fZGVsZXRlKGlkKTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIC8vIFBhZ2luYXRpb25cbiAgICBpZiAodGhhdC5hcmdzLnBhZ2luYXRpb24gIT09IGZhbHNlKSB7XG4gICAgICB0aGF0LiRpZCgncHJldl9wYWdlJykub24oJ2NsaWNrJywgKGUpID0+IHtcbiAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICB0aGF0LmdvX3RvX3BhZ2UodGhhdC5kYXRhLnBhZ2luYXRpb24uY3VycmVudF9wYWdlIC0gMSk7XG4gICAgICB9KTtcblxuICAgICAgdGhhdC4kaWQoJ25leHRfcGFnZScpLm9uKCdjbGljaycsIChlKSA9PiB7XG4gICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgdGhhdC5nb190b19wYWdlKHRoYXQuZGF0YS5wYWdpbmF0aW9uLmN1cnJlbnRfcGFnZSArIDEpO1xuICAgICAgfSk7XG5cbiAgICAgIHRoYXQuJC5maW5kKCcucGFnZS1saW5rW2RhdGEtcGFnZV0nKS5vbignY2xpY2snLCAoZSkgPT4ge1xuICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgIGNvbnN0ICRsaW5rID0gJChlLmN1cnJlbnRUYXJnZXQpO1xuICAgICAgICBjb25zdCBwYWdlID0gaW50KCRsaW5rLmRhdGEoJ3BhZ2UnKSk7XG4gICAgICAgIHRoYXQuZ29fdG9fcGFnZShwYWdlKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBVcGRhdGUgVUkgdG8gc2hvdyBob3cgbWFueSByb3dzIGFyZSBzZWxlY3RlZFxuICAgKi9cbiAgdXBkYXRlX3NlbGVjdGlvbl9jb3VudCgpIHtcbiAgICBjb25zdCB0aGF0ID0gdGhpcztcbiAgICBjb25zdCBzZWxlY3RlZCA9IHRoYXQuJC5maW5kKCd0Ym9keSBpbnB1dFt0eXBlPVwiY2hlY2tib3hcIl06Y2hlY2tlZCcpLmxlbmd0aDtcblxuICAgIGlmIChzZWxlY3RlZCA+IDApIHtcbiAgICAgIC8vIENvdWxkIHNob3cgYSBiYW5uZXI6IFwiMyBpdGVtcyBzZWxlY3RlZFwiXG4gICAgICBjb25zb2xlLmxvZyhgJHtzZWxlY3RlZH0gaXRlbXMgc2VsZWN0ZWRgKTtcblxuICAgICAgLy8gRmlyZSBldmVudCBmb3IgcGFyZW50IGNvbXBvbmVudHMgdG8gbGlzdGVuIHRvXG4gICAgICB0aGF0LiQudHJpZ2dlcignc2VsZWN0aW9uOmNoYW5nZWQnLCB7IGNvdW50OiBzZWxlY3RlZCB9KTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogR2V0IGFycmF5IG9mIHNlbGVjdGVkIElEc1xuICAgKi9cbiAgZ2V0X3NlbGVjdGVkX2lkcygpIHtcbiAgICBjb25zdCB0aGF0ID0gdGhpcztcbiAgICBjb25zdCBpZHMgPSBbXTtcbiAgICB0aGF0LiQuZmluZCgndGJvZHkgaW5wdXRbdHlwZT1cImNoZWNrYm94XCJdOmNoZWNrZWQnKS5lYWNoKChpLCBjaGVja2JveCkgPT4ge1xuICAgICAgY29uc3QgJGNoZWNrYm94ID0gJChjaGVja2JveCk7XG4gICAgICBjb25zdCBpZCA9ICRjaGVja2JveC5kYXRhKCdpZCcpO1xuICAgICAgaWYgKGlkKSBpZHMucHVzaChpZCk7XG4gICAgfSk7XG4gICAgcmV0dXJuIGlkcztcbiAgfVxuXG4gIC8qKlxuICAgKiBDbGVhciBhbGwgc2VsZWN0aW9uc1xuICAgKi9cbiAgY2xlYXJfc2VsZWN0aW9uKCkge1xuICAgIGNvbnN0IHRoYXQgPSB0aGlzO1xuICAgIHRoYXQuJC5maW5kKCdpbnB1dFt0eXBlPVwiY2hlY2tib3hcIl0nKS5wcm9wKCdjaGVja2VkJywgZmFsc2UpO1xuICAgIHRoYXQudXBkYXRlX3NlbGVjdGlvbl9jb3VudCgpO1xuICB9XG5cbiAgLyoqXG4gICAqIENvbmZpcm0gZGVsZXRpb24gb2YgYSByb3dcbiAgICovXG4gIGNvbmZpcm1fZGVsZXRlKGlkKSB7XG4gICAgY29uc3QgdGhhdCA9IHRoaXM7XG4gICAgLy8gSW4gYSByZWFsIGFwcCwgc2hvdyBhIEJvb3RzdHJhcCBtb2RhbFxuICAgIGlmIChjb25maXJtKCdBcmUgeW91IHN1cmUgeW91IHdhbnQgdG8gZGVsZXRlIHRoaXMgaXRlbT8nKSkge1xuICAgICAgdGhhdC5kZWxldGVfcm93KGlkKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogRGVsZXRlIGEgcm93ICh3b3VsZCB0eXBpY2FsbHkgbWFrZSBBUEkgY2FsbClcbiAgICovXG4gIGFzeW5jIGRlbGV0ZV9yb3coaWQpIHtcbiAgICBjb25zdCB0aGF0ID0gdGhpcztcbiAgICB0cnkge1xuICAgICAgLy8gTWFrZSBBUEkgY2FsbFxuICAgICAgLy8gYXdhaXQgZmV0Y2goYCR7dGhhdC5hcmdzLmFwaV91cmx9LyR7aWR9YCwgeyBtZXRob2Q6ICdERUxFVEUnIH0pO1xuXG4gICAgICAvLyBSZW1vdmUgcm93IGZyb20gZGF0YVxuICAgICAgdGhhdC5kYXRhLnJvd3MgPSB0aGF0LmRhdGEucm93cy5maWx0ZXIocm93ID0+IHJvdy5pZCAhPT0gaWQpO1xuXG4gICAgICAvLyBSZS1yZW5kZXIgY29tcG9uZW50XG4gICAgICB0aGF0LnJlZnJlc2goKTtcblxuICAgICAgLy8gU2hvdyBzdWNjZXNzIG1lc3NhZ2VcbiAgICAgIGNvbnNvbGUubG9nKGBEZWxldGVkIGl0ZW0gJHtpZH1gKTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgY29uc29sZS5lcnJvcignRGVsZXRlIGZhaWxlZDonLCBlcnJvcik7XG4gICAgICBhbGVydCgnRmFpbGVkIHRvIGRlbGV0ZSBpdGVtJyk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIE5hdmlnYXRlIHRvIGEgc3BlY2lmaWMgcGFnZVxuICAgKi9cbiAgYXN5bmMgZ29fdG9fcGFnZShwYWdlKSB7XG4gICAgY29uc3QgdGhhdCA9IHRoaXM7XG4gICAgaWYgKHBhZ2UgPCAxIHx8IHBhZ2UgPiB0aGF0LmRhdGEucGFnaW5hdGlvbi50b3RhbF9wYWdlcykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIFNob3cgbG9hZGluZyBzdGF0ZVxuICAgIHRoYXQuJC5maW5kKCd0Ym9keScpLmNzcygnb3BhY2l0eScsICcwLjUnKTtcblxuICAgIHRyeSB7XG4gICAgICAvLyBGZXRjaCBuZXcgcGFnZVxuICAgICAgY29uc3QgdXJsID0gYCR7dGhhdC5hcmdzLmFwaV91cmx9P3BhZ2U9JHtwYWdlfWA7XG4gICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKHVybCk7XG4gICAgICB0aGF0LmRhdGEgPSBhd2FpdCByZXNwb25zZS5qc29uKCk7XG5cbiAgICAgIC8vIFJlLXJlbmRlclxuICAgICAgdGhhdC5yZWZyZXNoKCk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoJ1BhZ2luYXRpb24gZmFpbGVkOicsIGVycm9yKTtcbiAgICAgIHRoYXQuJC5maW5kKCd0Ym9keScpLmNzcygnb3BhY2l0eScsICcxJyk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJlZnJlc2ggdGhlIHRhYmxlIChyZWxvYWQgZGF0YSBhbmQgcmUtcmVuZGVyKVxuICAgKi9cbiAgYXN5bmMgcmVsb2FkX2RhdGEoKSB7XG4gICAgY29uc3QgdGhhdCA9IHRoaXM7XG4gICAgdGhhdC5kYXRhID0ge307IC8vIENsZWFyIGRhdGEgdG8gc2hvdyBsb2FkaW5nIHN0YXRlXG4gICAgdGhhdC5yZWZyZXNoKCk7XG5cbiAgICBhd2FpdCB0aGF0Lm9uX2xvYWQoKTtcbiAgICB0aGF0LnJlZnJlc2goKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZW5lcmF0ZSBzYW1wbGUgZGF0YSBmb3IgZGVtb25zdHJhdGlvbiBwdXJwb3Nlc1xuICAgKi9cbiAgZ2VuZXJhdGVfc2FtcGxlX2RhdGEoKSB7XG4gICAgY29uc3QgdGhhdCA9IHRoaXM7XG4gICAgY29uc3Qgc3RhdHVzZXMgPSBbXG4gICAgICB7IGxhYmVsOiAnQWN0aXZlJywgY29sb3I6ICdzdWNjZXNzJyB9LFxuICAgICAgeyBsYWJlbDogJ1BlbmRpbmcnLCBjb2xvcjogJ3dhcm5pbmcnIH0sXG4gICAgICB7IGxhYmVsOiAnSW5hY3RpdmUnLCBjb2xvcjogJ3NlY29uZGFyeScgfSxcbiAgICAgIHsgbGFiZWw6ICdTdXNwZW5kZWQnLCBjb2xvcjogJ2RhbmdlcicgfVxuICAgIF07XG5cbiAgICBjb25zdCBmaXJzdF9uYW1lcyA9IFsnSm9obicsICdTYXJhaCcsICdNaWNoYWVsJywgJ0VtaWx5JywgJ0RhdmlkJywgJ0xpc2EnLCAnUm9iZXJ0JywgJ0plbm5pZmVyJywgJ1dpbGxpYW0nLCAnQW1hbmRhJ107XG4gICAgY29uc3QgbGFzdF9uYW1lcyA9IFsnU21pdGgnLCAnSm9obnNvbicsICdCcm93bicsICdHYXJjaWEnLCAnTWFydGluZXonLCAnTGVlJywgJ0FuZGVyc29uJywgJ1Rob21wc29uJywgJ1doaXRlJywgJ0RhdmlzJ107XG4gICAgY29uc3QgY29tcGFuaWVzID0gWydBY21lIENvcnAnLCAnVGVjaCBTb2x1dGlvbnMnLCAnR2xvYmFsIEVudGVycHJpc2VzJywgJ0lubm92YXRpb24gTGFicycsICdEaWdpdGFsIFN5c3RlbXMnLCAnQ2xvdWQgU2VydmljZXMnLCAnU21hcnQgSW5kdXN0cmllcycsICdGdXR1cmUgTmV0d29ya3MnLCAnUHJpbWUgQ29uc3VsdGluZycsICdFbGl0ZSBQYXJ0bmVycyddO1xuXG4gICAgY29uc3Qgcm93cyA9IFtdO1xuICAgIGNvbnN0IGNvdW50ID0gdGhhdC5hcmdzLnNob3dpbmcgfHwgMTA7XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGNvdW50OyBpKyspIHtcbiAgICAgIGNvbnN0IGZpcnN0X25hbWUgPSBmaXJzdF9uYW1lc1tNYXRoLmZsb29yKE1hdGgucmFuZG9tKCkgKiBmaXJzdF9uYW1lcy5sZW5ndGgpXTtcbiAgICAgIGNvbnN0IGxhc3RfbmFtZSA9IGxhc3RfbmFtZXNbTWF0aC5mbG9vcihNYXRoLnJhbmRvbSgpICogbGFzdF9uYW1lcy5sZW5ndGgpXTtcbiAgICAgIGNvbnN0IGNvbXBhbnkgPSBjb21wYW5pZXNbTWF0aC5mbG9vcihNYXRoLnJhbmRvbSgpICogY29tcGFuaWVzLmxlbmd0aCldO1xuICAgICAgY29uc3Qgc3RhdHVzID0gc3RhdHVzZXNbTWF0aC5mbG9vcihNYXRoLnJhbmRvbSgpICogc3RhdHVzZXMubGVuZ3RoKV07XG5cbiAgICAgIHJvd3MucHVzaCh7XG4gICAgICAgIGlkOiBgQyR7c3RyKGkgKyAxKS5wYWRTdGFydCgzLCAnMCcpfWAsXG4gICAgICAgIG5hbWU6IGAke2ZpcnN0X25hbWV9ICR7bGFzdF9uYW1lfWAsXG4gICAgICAgIGNvbXBhbnk6IGNvbXBhbnksXG4gICAgICAgIGVtYWlsOiBgJHtmaXJzdF9uYW1lLnRvTG93ZXJDYXNlKCl9LiR7bGFzdF9uYW1lLnRvTG93ZXJDYXNlKCl9QCR7Y29tcGFueS50b0xvd2VyQ2FzZSgpLnJlcGxhY2UoL1xccysvZywgJycpfS5jb21gLFxuICAgICAgICBwaG9uZTogYCg1NTUpICR7c3RyKE1hdGguZmxvb3IoTWF0aC5yYW5kb20oKSAqIDkwMCkgKyAxMDApfS0ke3N0cihNYXRoLmZsb29yKE1hdGgucmFuZG9tKCkgKiA5MDAwKSArIDEwMDApfWAsXG4gICAgICAgIHN0YXR1czogc3RhdHVzLmxhYmVsLFxuICAgICAgICBzdGF0dXNfY29sb3I6IHN0YXR1cy5jb2xvcixcbiAgICAgICAgY3JlYXRlZDogdGhhdC5yYW5kb21fZGF0ZSgpXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgcm93czogcm93cyxcbiAgICAgIHBhZ2luYXRpb246IHtcbiAgICAgICAgY3VycmVudF9wYWdlOiAxLFxuICAgICAgICB0b3RhbF9wYWdlczogTWF0aC5jZWlsKCh0aGF0LmFyZ3MudG90YWwgfHwgMTAwKSAvIGNvdW50KSxcbiAgICAgICAgZnJvbTogMSxcbiAgICAgICAgdG86IGNvdW50LFxuICAgICAgICB0b3RhbDogdGhhdC5hcmdzLnRvdGFsIHx8IDEwMCxcbiAgICAgICAgcGFnZXM6IFsxLCAyLCAzLCAnLi4uJywgTWF0aC5jZWlsKCh0aGF0LmFyZ3MudG90YWwgfHwgMTAwKSAvIGNvdW50KV1cbiAgICAgIH1cbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIEdlbmVyYXRlIHJhbmRvbSBkYXRlIGZvciBzYW1wbGUgZGF0YVxuICAgKi9cbiAgcmFuZG9tX2RhdGUoKSB7XG4gICAgY29uc3QgbW9udGhzID0gWydKYW4nLCAnRmViJywgJ01hcicsICdBcHInLCAnTWF5JywgJ0p1bicsICdKdWwnLCAnQXVnJywgJ1NlcCcsICdPY3QnLCAnTm92JywgJ0RlYyddO1xuICAgIGNvbnN0IG1vbnRoID0gbW9udGhzW01hdGguZmxvb3IoTWF0aC5yYW5kb20oKSAqIDEyKV07XG4gICAgY29uc3QgZGF5ID0gTWF0aC5mbG9vcihNYXRoLnJhbmRvbSgpICogMjgpICsgMTtcbiAgICByZXR1cm4gYCR7bW9udGh9ICR7c3RyKGRheSkucGFkU3RhcnQoMiwgJzAnKX0sIDIwMjRgO1xuICB9XG59XG4iLCJjbGFzcyBTZWFyY2hfQmFyIGV4dGVuZHMgSnFodG1sX0NvbXBvbmVudCB7XG4gICAgb25fcmVhZHkoKSB7XG4gICAgICAgIC8vIEJpbmQgc2VhcmNoIGV2ZW50XG4gICAgICAgIGNvbnN0ICRpbnB1dCA9IHRoaXMuJGlkKCdpbnB1dCcpO1xuICAgICAgICAkaW5wdXQub24oJ2lucHV0JywgKGUpID0+IHtcbiAgICAgICAgICAgIGlmICh0aGlzLmFyZ3Mub25fc2VhcmNoKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5hcmdzLm9uX3NlYXJjaChlLnRhcmdldC52YWx1ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cbn1cbiIsImNsYXNzIFNlYXJjaGFibGVfU2VsZWN0IGV4dGVuZHMgSnFodG1sX0NvbXBvbmVudCB7XG4gICAgb25fcmVhZHkoKSB7XG4gICAgICAgIHRoaXMuc2VsZWN0ZWRfdmFsdWUgPSB0aGlzLmFyZ3MudmFsdWUgfHwgbnVsbDtcbiAgICAgICAgdGhpcy5hbGxfb3B0aW9ucyA9IHRoaXMuYXJncy5vcHRpb25zIHx8IFtdO1xuXG4gICAgICAgIGlmICh0aGlzLmFsbF9vcHRpb25zLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIHRoaXMucmVuZGVyX29wdGlvbnModGhpcy5hbGxfb3B0aW9ucyk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBTZWFyY2ggZnVuY3Rpb25hbGl0eVxuICAgICAgICBjb25zdCAkc2VhcmNoID0gdGhpcy4kaWQoJ3NlYXJjaCcpO1xuICAgICAgICAkc2VhcmNoLm9uKCdpbnB1dCcsIChlKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmZpbHRlcl9vcHRpb25zKGUudGFyZ2V0LnZhbHVlKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gUHJldmVudCBkcm9wZG93biBjbG9zZSB3aGVuIGNsaWNraW5nIHNlYXJjaCBpbnB1dFxuICAgICAgICAkc2VhcmNoLm9uKCdjbGljaycsIChlKSA9PiB7XG4gICAgICAgICAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgICB9KTtcblxuICAgICAgICAvLyBVcGRhdGUgc2VsZWN0ZWQgdGV4dCBpZiBpbml0aWFsIHZhbHVlIHByb3ZpZGVkXG4gICAgICAgIGlmICh0aGlzLnNlbGVjdGVkX3ZhbHVlKSB7XG4gICAgICAgICAgICBjb25zdCBzZWxlY3RlZF9vcHRpb24gPSB0aGlzLmFsbF9vcHRpb25zLmZpbmQob3B0ID0+IG9wdC52YWx1ZSA9PSB0aGlzLnNlbGVjdGVkX3ZhbHVlKTtcbiAgICAgICAgICAgIGlmIChzZWxlY3RlZF9vcHRpb24pIHtcbiAgICAgICAgICAgICAgICB0aGlzLiRpZCgnc2VsZWN0ZWRfdGV4dCcpLnRleHQoc2VsZWN0ZWRfb3B0aW9uLmxhYmVsKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIHJlbmRlcl9vcHRpb25zKG9wdGlvbnMpIHtcbiAgICAgICAgY29uc3QgJGNvbnRhaW5lciA9IHRoaXMuJGlkKCdvcHRpb25zJyk7XG4gICAgICAgICRjb250YWluZXIuZW1wdHkoKTtcblxuICAgICAgICBpZiAob3B0aW9ucy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgICRjb250YWluZXIuYXBwZW5kKCQoJzxkaXY+JykuYWRkQ2xhc3MoJ3B4LTMgcHktMiB0ZXh0LW11dGVkJykudGV4dCgnTm8gb3B0aW9ucyBmb3VuZCcpKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIG9wdGlvbnMuZm9yRWFjaChvcHRpb24gPT4ge1xuICAgICAgICAgICAgY29uc3QgJGl0ZW0gPSAkKCc8YT4nKVxuICAgICAgICAgICAgICAgIC5hZGRDbGFzcygnZHJvcGRvd24taXRlbScpXG4gICAgICAgICAgICAgICAgLmF0dHIoJ2hyZWYnLCAnIycpXG4gICAgICAgICAgICAgICAgLnRleHQob3B0aW9uLmxhYmVsKVxuICAgICAgICAgICAgICAgIC5hdHRyKCdkYXRhLXZhbHVlJywgb3B0aW9uLnZhbHVlKTtcblxuICAgICAgICAgICAgaWYgKG9wdGlvbi52YWx1ZSA9PSB0aGlzLnNlbGVjdGVkX3ZhbHVlKSB7XG4gICAgICAgICAgICAgICAgJGl0ZW0uYWRkQ2xhc3MoJ2FjdGl2ZScpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAkaXRlbS5vbignY2xpY2snLCAoZSkgPT4ge1xuICAgICAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICAgICAgICB0aGlzLnNlbGVjdF9vcHRpb24ob3B0aW9uKTtcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAkY29udGFpbmVyLmFwcGVuZCgkaXRlbSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIGZpbHRlcl9vcHRpb25zKHF1ZXJ5KSB7XG4gICAgICAgIGNvbnN0IGZpbHRlcmVkID0gdGhpcy5hbGxfb3B0aW9ucy5maWx0ZXIob3B0ID0+XG4gICAgICAgICAgICBvcHQubGFiZWwudG9Mb3dlckNhc2UoKS5pbmNsdWRlcyhxdWVyeS50b0xvd2VyQ2FzZSgpKVxuICAgICAgICApO1xuICAgICAgICB0aGlzLnJlbmRlcl9vcHRpb25zKGZpbHRlcmVkKTtcbiAgICB9XG5cbiAgICBzZWxlY3Rfb3B0aW9uKG9wdGlvbikge1xuICAgICAgICB0aGlzLnNlbGVjdGVkX3ZhbHVlID0gb3B0aW9uLnZhbHVlO1xuICAgICAgICB0aGlzLiRpZCgnc2VsZWN0ZWRfdGV4dCcpLnRleHQob3B0aW9uLmxhYmVsKTtcblxuICAgICAgICAvLyBVcGRhdGUgYWN0aXZlIHN0YXRlXG4gICAgICAgIHRoaXMuJGlkKCdvcHRpb25zJykuZmluZCgnLmRyb3Bkb3duLWl0ZW0nKS5yZW1vdmVDbGFzcygnYWN0aXZlJyk7XG4gICAgICAgIHRoaXMuJGlkKCdvcHRpb25zJykuZmluZChgW2RhdGEtdmFsdWU9XCIke29wdGlvbi52YWx1ZX1cIl1gKS5hZGRDbGFzcygnYWN0aXZlJyk7XG5cbiAgICAgICAgLy8gQ2xvc2UgZHJvcGRvd25cbiAgICAgICAgY29uc3QgZHJvcGRvd24gPSBib290c3RyYXAuRHJvcGRvd24uZ2V0SW5zdGFuY2UodGhpcy4kaWQoJ2J1dHRvbicpWzBdKTtcbiAgICAgICAgaWYgKGRyb3Bkb3duKSB7XG4gICAgICAgICAgICBkcm9wZG93bi5oaWRlKCk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBDbGVhciBzZWFyY2hcbiAgICAgICAgdGhpcy4kaWQoJ3NlYXJjaCcpLnZhbCgnJyk7XG4gICAgICAgIHRoaXMucmVuZGVyX29wdGlvbnModGhpcy5hbGxfb3B0aW9ucyk7XG5cbiAgICAgICAgLy8gVHJpZ2dlciBjYWxsYmFja1xuICAgICAgICBpZiAodGhpcy5hcmdzLm9uX2NoYW5nZSkge1xuICAgICAgICAgICAgdGhpcy5hcmdzLm9uX2NoYW5nZShvcHRpb24udmFsdWUsIG9wdGlvbik7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBnZXRfdmFsdWUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnNlbGVjdGVkX3ZhbHVlO1xuICAgIH1cblxuICAgIHNldF92YWx1ZSh2YWx1ZSkge1xuICAgICAgICB0aGlzLnNlbGVjdGVkX3ZhbHVlID0gdmFsdWU7XG4gICAgICAgIGNvbnN0IG9wdGlvbiA9IHRoaXMuYWxsX29wdGlvbnMuZmluZChvcHQgPT4gb3B0LnZhbHVlID09IHZhbHVlKTtcbiAgICAgICAgaWYgKG9wdGlvbikge1xuICAgICAgICAgICAgdGhpcy4kaWQoJ3NlbGVjdGVkX3RleHQnKS50ZXh0KG9wdGlvbi5sYWJlbCk7XG4gICAgICAgICAgICB0aGlzLiRpZCgnb3B0aW9ucycpLmZpbmQoJy5kcm9wZG93bi1pdGVtJykucmVtb3ZlQ2xhc3MoJ2FjdGl2ZScpO1xuICAgICAgICAgICAgdGhpcy4kaWQoJ29wdGlvbnMnKS5maW5kKGBbZGF0YS12YWx1ZT1cIiR7dmFsdWV9XCJdYCkuYWRkQ2xhc3MoJ2FjdGl2ZScpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgc2V0X29wdGlvbnMob3B0aW9ucykge1xuICAgICAgICB0aGlzLmFsbF9vcHRpb25zID0gb3B0aW9ucztcbiAgICAgICAgdGhpcy5yZW5kZXJfb3B0aW9ucyhvcHRpb25zKTtcbiAgICB9XG59XG4iLCIvKipcbiAqIFNlbGVjdF9Ecm9wZG93biAtIEJvb3RzdHJhcCA1IERyb3Bkb3duIFNlbGVjdGlvbiBDb21wb25lbnRcbiAqXG4gKiBQdXJwb3NlOiBEcm9wZG93biBtZW51IGZvciBzZWxlY3Rpbmcgb25lIG9wdGlvbiBmcm9tIGEgbGlzdFxuICogRGVzaWduOiBCb290c3RyYXAgLmZvcm0tc2VsZWN0IHN0eWxpbmcgd2l0aCBkcm9wZG93biBhcnJvd1xuICogQ29udGVudDogQ29udGFpbnMgPG9wdGlvbj4gZWxlbWVudHNcbiAqL1xuY2xhc3MgU2VsZWN0X0Ryb3Bkb3duIGV4dGVuZHMgSnFodG1sX0NvbXBvbmVudCB7XG4gICAgb25fcmVhZHkoKSB7XG4gICAgICAgIC8vIFNldCB2YWx1ZSBpZiBwcm92aWRlZFxuICAgICAgICBpZiAodGhpcy5hcmdzLnZhbHVlKSB7XG4gICAgICAgICAgICB0aGlzLiQudmFsKHRoaXMuYXJncy52YWx1ZSk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBBZGQgY3VzdG9tIGNsYXNzZXMgaWYgcHJvdmlkZWRcbiAgICAgICAgaWYgKHRoaXMuYXJncy5jbGFzcykge1xuICAgICAgICAgICAgdGhpcy4kLmFkZENsYXNzKHRoaXMuYXJncy5jbGFzcyk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBTZXQgZGlzYWJsZWQgc3RhdGUgaWYgcHJvdmlkZWRcbiAgICAgICAgaWYgKHRoaXMuYXJncy5kaXNhYmxlZCkge1xuICAgICAgICAgICAgdGhpcy4kLnByb3AoJ2Rpc2FibGVkJywgdHJ1ZSk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBTZXQgcmVxdWlyZWQgYXR0cmlidXRlIGlmIHByb3ZpZGVkXG4gICAgICAgIGlmICh0aGlzLmFyZ3MucmVxdWlyZWQpIHtcbiAgICAgICAgICAgIHRoaXMuJC5wcm9wKCdyZXF1aXJlZCcsIHRydWUpO1xuICAgICAgICB9XG4gICAgfVxufVxuIiwiY2xhc3MgU2lkZWJhcl9OYXYgZXh0ZW5kcyBKcWh0bWxfQ29tcG9uZW50IHtcbiAgICBvbl9yZWFkeSgpIHtcbiAgICAgICAgLy8gQXV0by13cmFwIGNoaWxkcmVuIGluIG5hdiBzdHJ1Y3R1cmUgaWYgbmVlZGVkXG4gICAgICAgIGNvbnN0ICRuYXZfaXRlbXMgPSB0aGlzLiRpZCgnbmF2X2l0ZW1zJyk7XG4gICAgICAgICRuYXZfaXRlbXMuY2hpbGRyZW4oKS5lYWNoKGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgY29uc3QgJGNoaWxkID0gJCh0aGlzKTtcbiAgICAgICAgICAgIGlmICgkY2hpbGQucHJvcCgndGFnTmFtZScpICE9PSAnTEknKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgJGxpID0gJCgnPGxpPicpLmFkZENsYXNzKCduYXYtaXRlbScpO1xuICAgICAgICAgICAgICAgICRjaGlsZC5hZGRDbGFzcygnbmF2LWxpbmsnKTtcbiAgICAgICAgICAgICAgICAkY2hpbGQud3JhcCgkbGkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgICAgICAvLyBTZXQgYWN0aXZlIHN0YXRlIGJhc2VkIG9uIGN1cnJlbnQgVVJMXG4gICAgICAgIGNvbnN0IGN1cnJlbnRfcGF0aCA9IHdpbmRvdy5sb2NhdGlvbi5wYXRobmFtZTtcbiAgICAgICAgJG5hdl9pdGVtcy5maW5kKCdhLm5hdi1saW5rJykuZWFjaChmdW5jdGlvbigpIHtcbiAgICAgICAgICAgIGNvbnN0ICRsaW5rID0gJCh0aGlzKTtcbiAgICAgICAgICAgIGlmICgkbGluay5hdHRyKCdocmVmJykgPT09IGN1cnJlbnRfcGF0aCkge1xuICAgICAgICAgICAgICAgICRsaW5rLmFkZENsYXNzKCdhY3RpdmUnKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxufVxuIiwiY2xhc3MgU29ydGFibGVfQ29sdW1uX0hlYWRlciBleHRlbmRzIEpxaHRtbF9Db21wb25lbnQge1xuICAgIG9uX3JlYWR5KCkge1xuICAgICAgICAvLyBDbGljayB0byB0b2dnbGUgc29ydFxuICAgICAgICB0aGlzLiQub24oJ2NsaWNrJywgKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy50b2dnbGVfc29ydCgpO1xuICAgICAgICB9KTtcblxuICAgICAgICAvLyBTZXQgaW5pdGlhbCBzb3J0IHN0YXRlXG4gICAgICAgIGlmICh0aGlzLmFyZ3Muc29ydCkge1xuICAgICAgICAgICAgdGhpcy5zZXRfc29ydCh0aGlzLmFyZ3Muc29ydCk7IC8vICdhc2MnIG9yICdkZXNjJ1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgdG9nZ2xlX3NvcnQoKSB7XG4gICAgICAgIGNvbnN0IGN1cnJlbnQgPSB0aGlzLiQuYXR0cignZGF0YS1zb3J0JykgfHwgJ25vbmUnO1xuICAgICAgICBjb25zdCBuZXh0ID0gY3VycmVudCA9PT0gJ25vbmUnID8gJ2FzYycgOiBjdXJyZW50ID09PSAnYXNjJyA/ICdkZXNjJyA6ICdhc2MnO1xuICAgICAgICB0aGlzLnNldF9zb3J0KG5leHQpO1xuXG4gICAgICAgIC8vIENhbGwgY2FsbGJhY2sgaWYgcHJvdmlkZWRcbiAgICAgICAgaWYgKHRoaXMuYXJncy5vbl9zb3J0KSB7XG4gICAgICAgICAgICB0aGlzLmFyZ3Mub25fc29ydCh0aGlzLmFyZ3MuY29sdW1uLCBuZXh0KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHNldF9zb3J0KGRpcmVjdGlvbikge1xuICAgICAgICB0aGlzLiQuYXR0cignZGF0YS1zb3J0JywgZGlyZWN0aW9uKTtcbiAgICAgICAgY29uc3QgJGljb24gPSB0aGlzLiRpZCgnc29ydF9pY29uJyk7XG5cbiAgICAgICAgaWYgKGRpcmVjdGlvbiA9PT0gJ2FzYycpIHtcbiAgICAgICAgICAgICRpY29uLmh0bWwoJzxpIGNsYXNzPVwidGV4dC1wcmltYXJ5XCI+4oaRPC9pPicpO1xuICAgICAgICB9IGVsc2UgaWYgKGRpcmVjdGlvbiA9PT0gJ2Rlc2MnKSB7XG4gICAgICAgICAgICAkaWNvbi5odG1sKCc8aSBjbGFzcz1cInRleHQtcHJpbWFyeVwiPuKGkzwvaT4nKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICRpY29uLmh0bWwoJzxpIGNsYXNzPVwidGV4dC1tdXRlZFwiPuKHhTwvaT4nKTtcbiAgICAgICAgfVxuICAgIH1cbn1cbiIsImNsYXNzIFNwaW5uZXIgZXh0ZW5kcyBKcWh0bWxfQ29tcG9uZW50IHtcbiAgICBvbl9yZWFkeSgpIHtcbiAgICAgICAgLy8gQXBwbHkgc2l6ZSAoc20pXG4gICAgICAgIGlmICh0aGlzLmFyZ3Muc2l6ZSA9PT0gJ3NtJykge1xuICAgICAgICAgICAgdGhpcy4kLmFkZENsYXNzKCdzcGlubmVyLWJvcmRlci1zbScpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gQXBwbHkgY29sb3JcbiAgICAgICAgaWYgKHRoaXMuYXJncy5jb2xvcikge1xuICAgICAgICAgICAgdGhpcy4kLmFkZENsYXNzKGB0ZXh0LSR7dGhpcy5hcmdzLmNvbG9yfWApO1xuICAgICAgICB9XG4gICAgfVxufVxuIiwiY2xhc3MgU3RhdF9DYXJkIGV4dGVuZHMgSnFodG1sX0NvbXBvbmVudCB7XG4gICAgb25fcmVhZHkoKSB7XG4gICAgICAgIC8vIE5vIHNwZWNpYWwgYmVoYXZpb3JcbiAgICB9XG59XG4iLCJjbGFzcyBTdGF0dXNfQmFkZ2UgZXh0ZW5kcyBKcWh0bWxfQ29tcG9uZW50IHtcbiAgICBvbl9yZWFkeSgpIHtcbiAgICAgICAgLy8gQXBwbHkgY29sb3IgYmFzZWQgb24gY29udGVudCBvciBhcmdzXG4gICAgICAgIGNvbnN0IHN0YXR1cyA9IHRoaXMuYXJncy5zdGF0dXMgfHwgdGhpcy4kLnRleHQoKS50cmltKCkudG9Mb3dlckNhc2UoKTtcblxuICAgICAgICAvLyBEZWZhdWx0IGNvbG9yIG1hcHBpbmdzXG4gICAgICAgIGNvbnN0IGNvbG9yX21hcCA9IHtcbiAgICAgICAgICAgICdhY3RpdmUnOiAnYmctc3VjY2VzcycsXG4gICAgICAgICAgICAncGVuZGluZyc6ICdiZy13YXJuaW5nJyxcbiAgICAgICAgICAgICdjb21wbGV0ZWQnOiAnYmctcHJpbWFyeScsXG4gICAgICAgICAgICAnY2FuY2VsbGVkJzogJ2JnLWRhbmdlcicsXG4gICAgICAgICAgICAnZHJhZnQnOiAnYmctc2Vjb25kYXJ5JyxcbiAgICAgICAgICAgICdhcmNoaXZlZCc6ICdiZy1kYXJrJ1xuICAgICAgICB9O1xuXG4gICAgICAgIGNvbnN0IGJnX2NsYXNzID0gdGhpcy5hcmdzLmJnX2NsYXNzIHx8IGNvbG9yX21hcFtzdGF0dXNdIHx8ICdiZy1zZWNvbmRhcnknO1xuICAgICAgICB0aGlzLiQuYWRkQ2xhc3MoYmdfY2xhc3MpO1xuICAgIH1cbn1cbiIsImNsYXNzIFRhYl9Db250ZW50IGV4dGVuZHMgSnFodG1sX0NvbXBvbmVudCB7XG4gICAgb25fcmVhZHkoKSB7XG4gICAgICAgIC8vIEVuc3VyZSBjaGlsZHJlbiBoYXZlIHRhYi1wYW5lIGNsYXNzXG4gICAgICAgIHRoaXMuJC5jaGlsZHJlbigpLmVhY2goZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICBjb25zdCAkY2hpbGQgPSAkKHRoaXMpO1xuICAgICAgICAgICAgJGNoaWxkLmFkZENsYXNzKCd0YWItcGFuZSBmYWRlJyk7XG5cbiAgICAgICAgICAgIC8vIFNldCBmaXJzdCBwYW5lIGFzIGFjdGl2ZSBpZiBub25lIGFjdGl2ZVxuICAgICAgICAgICAgaWYgKCRjaGlsZC5wYXJlbnQoKS5maW5kKCcudGFiLXBhbmUuYWN0aXZlJykubGVuZ3RoID09PSAwICYmICRjaGlsZC5pbmRleCgpID09PSAwKSB7XG4gICAgICAgICAgICAgICAgJGNoaWxkLmFkZENsYXNzKCdzaG93IGFjdGl2ZScpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG59XG4iLCJjbGFzcyBUYWJsZV9QYWdpbmF0aW9uIGV4dGVuZHMgSnFodG1sX0NvbXBvbmVudCB7XG4gICAgb25fcmVhZHkoKSB7XG4gICAgICAgIC8vIEdlbmVyYXRlIHBhZ2luYXRpb24gaWYgcGFnZXMgcHJvdmlkZWQgdmlhIGFyZ3NcbiAgICAgICAgaWYgKHRoaXMuYXJncy5jdXJyZW50X3BhZ2UgJiYgdGhpcy5hcmdzLnRvdGFsX3BhZ2VzKSB7XG4gICAgICAgICAgICB0aGlzLmdlbmVyYXRlX3BhZ2luYXRpb24odGhpcy5hcmdzLmN1cnJlbnRfcGFnZSwgdGhpcy5hcmdzLnRvdGFsX3BhZ2VzKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGdlbmVyYXRlX3BhZ2luYXRpb24oY3VycmVudCwgdG90YWwpIHtcbiAgICAgICAgY29uc3QgJHBhZ2luYXRpb24gPSB0aGlzLiRpZCgncGFnaW5hdGlvbicpO1xuICAgICAgICAkcGFnaW5hdGlvbi5lbXB0eSgpO1xuXG4gICAgICAgIC8vIFByZXZpb3VzIGJ1dHRvblxuICAgICAgICBjb25zdCAkcHJldiA9ICQoJzxsaT4nKS5hZGRDbGFzcygncGFnZS1pdGVtJyArIChjdXJyZW50ID09PSAxID8gJyBkaXNhYmxlZCcgOiAnJykpO1xuICAgICAgICAkcHJldi5hcHBlbmQoJCgnPGE+JykuYWRkQ2xhc3MoJ3BhZ2UtbGluaycpLmF0dHIoJ2hyZWYnLCAnIycpLnRleHQoJ1ByZXZpb3VzJykpO1xuICAgICAgICAkcGFnaW5hdGlvbi5hcHBlbmQoJHByZXYpO1xuXG4gICAgICAgIC8vIFBhZ2UgbnVtYmVycyAoc2hvdyA1IHBhZ2VzIG1heClcbiAgICAgICAgbGV0IHN0YXJ0ID0gTWF0aC5tYXgoMSwgY3VycmVudCAtIDIpO1xuICAgICAgICBsZXQgZW5kID0gTWF0aC5taW4odG90YWwsIGN1cnJlbnQgKyAyKTtcblxuICAgICAgICBmb3IgKGxldCBpID0gc3RhcnQ7IGkgPD0gZW5kOyBpKyspIHtcbiAgICAgICAgICAgIGNvbnN0ICRsaSA9ICQoJzxsaT4nKS5hZGRDbGFzcygncGFnZS1pdGVtJyArIChpID09PSBjdXJyZW50ID8gJyBhY3RpdmUnIDogJycpKTtcbiAgICAgICAgICAgICRsaS5hcHBlbmQoJCgnPGE+JykuYWRkQ2xhc3MoJ3BhZ2UtbGluaycpLmF0dHIoJ2hyZWYnLCAnIycpLnRleHQoaSkpO1xuICAgICAgICAgICAgJHBhZ2luYXRpb24uYXBwZW5kKCRsaSk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBOZXh0IGJ1dHRvblxuICAgICAgICBjb25zdCAkbmV4dCA9ICQoJzxsaT4nKS5hZGRDbGFzcygncGFnZS1pdGVtJyArIChjdXJyZW50ID09PSB0b3RhbCA/ICcgZGlzYWJsZWQnIDogJycpKTtcbiAgICAgICAgJG5leHQuYXBwZW5kKCQoJzxhPicpLmFkZENsYXNzKCdwYWdlLWxpbmsnKS5hdHRyKCdocmVmJywgJyMnKS50ZXh0KCdOZXh0JykpO1xuICAgICAgICAkcGFnaW5hdGlvbi5hcHBlbmQoJG5leHQpO1xuICAgIH1cbn1cbiIsImNsYXNzIFRhYmxlIGV4dGVuZHMgSnFodG1sX0NvbXBvbmVudCB7XG4gICAgb25fcmVhZHkoKSB7XG4gICAgICAgIC8vIEFwcGx5IHZhcmlhbnQgZnJvbSBhcmdzXG4gICAgICAgIGlmICh0aGlzLmFyZ3MudmFyaWFudCkge1xuICAgICAgICAgICAgdGhpcy4kLmFkZENsYXNzKGB0YWJsZS0ke3RoaXMuYXJncy52YXJpYW50fWApOyAvLyBzdHJpcGVkLCBib3JkZXJlZCwgYm9yZGVybGVzc1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gQXBwbHkgc2l6ZVxuICAgICAgICBpZiAodGhpcy5hcmdzLnNpemUgPT09ICdzbScpIHtcbiAgICAgICAgICAgIHRoaXMuJC5hZGRDbGFzcygndGFibGUtc20nKTtcbiAgICAgICAgfVxuICAgIH1cbn1cbiIsImNsYXNzIFRhYnMgZXh0ZW5kcyBKcWh0bWxfQ29tcG9uZW50IHtcbiAgICBvbl9yZWFkeSgpIHtcbiAgICAgICAgLy8gV3JhcCBjaGlsZHJlbiBpbiBuYXYtaXRlbSBzdHJ1Y3R1cmVcbiAgICAgICAgdGhpcy4kLmNoaWxkcmVuKCkuZWFjaChmdW5jdGlvbigpIHtcbiAgICAgICAgICAgIGNvbnN0ICRjaGlsZCA9ICQodGhpcyk7XG4gICAgICAgICAgICBpZiAoJGNoaWxkLnByb3AoJ3RhZ05hbWUnKSAhPT0gJ0xJJykge1xuICAgICAgICAgICAgICAgIGNvbnN0ICRsaSA9ICQoJzxsaT4nKS5hZGRDbGFzcygnbmF2LWl0ZW0nKTtcbiAgICAgICAgICAgICAgICAkY2hpbGQuYWRkQ2xhc3MoJ25hdi1saW5rJyk7XG4gICAgICAgICAgICAgICAgJGNoaWxkLndyYXAoJGxpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gU2V0IGZpcnN0IHRhYiBhcyBhY3RpdmUgaWYgbm9uZSBhY3RpdmVcbiAgICAgICAgaWYgKHRoaXMuJC5maW5kKCcubmF2LWxpbmsuYWN0aXZlJykubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICB0aGlzLiQuZmluZCgnLm5hdi1saW5rJykuZmlyc3QoKS5hZGRDbGFzcygnYWN0aXZlJyk7XG4gICAgICAgIH1cbiAgICB9XG59XG4iLCJjbGFzcyBUYWdfR3JvdXAgZXh0ZW5kcyBKcWh0bWxfQ29tcG9uZW50IHtcbiAgICBvbl9yZWFkeSgpIHtcbiAgICAgICAgLy8gTm8gc3BlY2lhbCBiZWhhdmlvciBuZWVkZWRcbiAgICB9XG59XG4iLCJjbGFzcyBUYWcgZXh0ZW5kcyBKcWh0bWxfQ29tcG9uZW50IHtcbiAgICBvbl9yZWFkeSgpIHtcbiAgICAgICAgLy8gQXBwbHkgY29sb3IgZnJvbSBhcmdzXG4gICAgICAgIGlmICh0aGlzLmFyZ3MuY29sb3IpIHtcbiAgICAgICAgICAgIHRoaXMuJC5yZW1vdmVDbGFzcygnYmctc2Vjb25kYXJ5JykuYWRkQ2xhc3MoYGJnLSR7dGhpcy5hcmdzLmNvbG9yfWApO1xuICAgICAgICB9XG4gICAgfVxufVxuIiwiY2xhc3MgVGV4dF9EaXNwbGF5IGV4dGVuZHMgSnFodG1sX0NvbXBvbmVudCB7XG4gICAgLy8gR2VuZXJpYyB0ZXh0IGRpc3BsYXkgLSBpbmhlcml0cyBCb290c3RyYXAgdHlwb2dyYXBoeVxufVxuIiwiLyoqXG4gKiBUZXh0YXJlYSAtIEJvb3RzdHJhcCA1IE11bHRpLWxpbmUgVGV4dCBJbnB1dCBDb21wb25lbnRcbiAqXG4gKiBQdXJwb3NlOiBNdWx0aS1saW5lIHRleHQgaW5wdXQgZm9yIGxvbmdlciBjb250ZW50IGxpa2UgZGVzY3JpcHRpb25zLCBjb21tZW50cywgbm90ZXNcbiAqIERlc2lnbjogQm9vdHN0cmFwIC5mb3JtLWNvbnRyb2wgc3R5bGluZyAoc2FtZSBhcyBJbnB1dClcbiAqL1xuY2xhc3MgVGV4dGFyZWEgZXh0ZW5kcyBKcWh0bWxfQ29tcG9uZW50IHtcbiAgICBvbl9yZWFkeSgpIHtcbiAgICAgICAgLy8gU2V0IHJvd3MgaWYgcHJvdmlkZWRcbiAgICAgICAgaWYgKHRoaXMuYXJncy5yb3dzKSB7XG4gICAgICAgICAgICB0aGlzLiQuYXR0cigncm93cycsIHRoaXMuYXJncy5yb3dzKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFNldCBwbGFjZWhvbGRlciBpZiBwcm92aWRlZFxuICAgICAgICBpZiAodGhpcy5hcmdzLnBsYWNlaG9sZGVyKSB7XG4gICAgICAgICAgICB0aGlzLiQuYXR0cigncGxhY2Vob2xkZXInLCB0aGlzLmFyZ3MucGxhY2Vob2xkZXIpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gU2V0IHZhbHVlIGlmIHByb3ZpZGVkIChvdmVycmlkZXMgY29udGVudCgpKVxuICAgICAgICBpZiAodGhpcy5hcmdzLnZhbHVlKSB7XG4gICAgICAgICAgICB0aGlzLiQudmFsKHRoaXMuYXJncy52YWx1ZSk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBBZGQgY3VzdG9tIGNsYXNzZXMgaWYgcHJvdmlkZWRcbiAgICAgICAgaWYgKHRoaXMuYXJncy5jbGFzcykge1xuICAgICAgICAgICAgdGhpcy4kLmFkZENsYXNzKHRoaXMuYXJncy5jbGFzcyk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBTZXQgZGlzYWJsZWQgc3RhdGUgaWYgcHJvdmlkZWRcbiAgICAgICAgaWYgKHRoaXMuYXJncy5kaXNhYmxlZCkge1xuICAgICAgICAgICAgdGhpcy4kLnByb3AoJ2Rpc2FibGVkJywgdHJ1ZSk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBTZXQgcmVxdWlyZWQgYXR0cmlidXRlIGlmIHByb3ZpZGVkXG4gICAgICAgIGlmICh0aGlzLmFyZ3MucmVxdWlyZWQpIHtcbiAgICAgICAgICAgIHRoaXMuJC5wcm9wKCdyZXF1aXJlZCcsIHRydWUpO1xuICAgICAgICB9XG4gICAgfVxufVxuIiwiY2xhc3MgVGhyZWVfQ29sdW1uX0xheW91dCBleHRlbmRzIEpxaHRtbF9Db21wb25lbnQge1xuICAgIG9uX3JlYWR5KCkge1xuICAgICAgICAvLyBXcmFwIGVhY2ggZGlyZWN0IGNoaWxkIGluIHJlc3BvbnNpdmUgY29sdW1uIGNsYXNzZXNcbiAgICAgICAgdGhpcy4kLmNoaWxkcmVuKCkuZWFjaChmdW5jdGlvbigpIHtcbiAgICAgICAgICAgIGNvbnN0ICRlbGVtZW50ID0gJCh0aGlzKTtcbiAgICAgICAgICAgICRlbGVtZW50LmFkZENsYXNzKCdjb2wtMTIgY29sLW1kLTYgY29sLXhsLTQgbWItNCcpO1xuICAgICAgICB9KTtcbiAgICB9XG59XG4iLCJjbGFzcyBUaW1lX1BpY2tlciBleHRlbmRzIEpxaHRtbF9Db21wb25lbnQge1xuICAgIG9uX3JlYWR5KCkge1xuICAgICAgICBjb25zdCAkaW5wdXQgPSB0aGlzLiRpZCgnaW5wdXQnKTtcblxuICAgICAgICBpZiAodGhpcy5hcmdzLnZhbHVlKSB7XG4gICAgICAgICAgICAkaW5wdXQudmFsKHRoaXMuYXJncy52YWx1ZSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5hcmdzLm5hbWUpIHtcbiAgICAgICAgICAgICRpbnB1dC5hdHRyKCduYW1lJywgdGhpcy5hcmdzLm5hbWUpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMuYXJncy5taW4pIHtcbiAgICAgICAgICAgICRpbnB1dC5hdHRyKCdtaW4nLCB0aGlzLmFyZ3MubWluKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLmFyZ3MubWF4KSB7XG4gICAgICAgICAgICAkaW5wdXQuYXR0cignbWF4JywgdGhpcy5hcmdzLm1heCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5hcmdzLnN0ZXApIHtcbiAgICAgICAgICAgICRpbnB1dC5hdHRyKCdzdGVwJywgdGhpcy5hcmdzLnN0ZXApO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMuYXJncy5kaXNhYmxlZCkge1xuICAgICAgICAgICAgJGlucHV0LnByb3AoJ2Rpc2FibGVkJywgdHJ1ZSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5hcmdzLnJlYWRvbmx5KSB7XG4gICAgICAgICAgICAkaW5wdXQucHJvcCgncmVhZG9ubHknLCB0cnVlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLmFyZ3MucmVxdWlyZWQpIHtcbiAgICAgICAgICAgICRpbnB1dC5wcm9wKCdyZXF1aXJlZCcsIHRydWUpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMuYXJncy5vbl9jaGFuZ2UpIHtcbiAgICAgICAgICAgICRpbnB1dC5vbignY2hhbmdlJywgKGUpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmFyZ3Mub25fY2hhbmdlKGUudGFyZ2V0LnZhbHVlKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgZ2V0X3ZhbHVlKCkge1xuICAgICAgICByZXR1cm4gdGhpcy4kaWQoJ2lucHV0JykudmFsKCk7XG4gICAgfVxuXG4gICAgc2V0X3ZhbHVlKHZhbHVlKSB7XG4gICAgICAgIHRoaXMuJGlkKCdpbnB1dCcpLnZhbCh2YWx1ZSk7XG4gICAgfVxuXG4gICAgZm9jdXMoKSB7XG4gICAgICAgIHRoaXMuJGlkKCdpbnB1dCcpLmZvY3VzKCk7XG4gICAgfVxufVxuIiwiY2xhc3MgVGltZWxpbmUgZXh0ZW5kcyBKcWh0bWxfQ29tcG9uZW50IHtcbiAgICAvLyBQdXJlIEJvb3RzdHJhcCBmbGV4Ym94IC0gbm8gSmF2YVNjcmlwdCBuZWVkZWRcbn1cbiIsImNsYXNzIFRpbWVzdGFtcF9EaXNwbGF5IGV4dGVuZHMgSnFodG1sX0NvbXBvbmVudCB7XG4gICAgLy8gUHVyZSBCb290c3RyYXAgc3R5bGluZyAtIG5vIEphdmFTY3JpcHQgbmVlZGVkXG59XG4iLCJjbGFzcyBUb29sdGlwIGV4dGVuZHMgSnFodG1sX0NvbXBvbmVudCB7XG4gICAgb25fcmVhZHkoKSB7XG4gICAgICAgIC8vIFNldCB0b29sdGlwIHRleHQgZnJvbSBhcmdzXG4gICAgICAgIGlmICh0aGlzLmFyZ3MudGV4dCkge1xuICAgICAgICAgICAgdGhpcy4kLmF0dHIoJ2RhdGEtYnMtdGl0bGUnLCB0aGlzLmFyZ3MudGV4dCk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBTZXQgcGxhY2VtZW50XG4gICAgICAgIGlmICh0aGlzLmFyZ3MucGxhY2VtZW50KSB7XG4gICAgICAgICAgICB0aGlzLiQuYXR0cignZGF0YS1icy1wbGFjZW1lbnQnLCB0aGlzLmFyZ3MucGxhY2VtZW50KTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIEluaXRpYWxpemUgQm9vdHN0cmFwIHRvb2x0aXBcbiAgICAgICAgbmV3IGJvb3RzdHJhcC5Ub29sdGlwKHRoaXMuJFswXSk7XG4gICAgfVxufVxuIiwiY2xhc3MgVG9wX05hdiBleHRlbmRzIEpxaHRtbF9Db21wb25lbnQge1xuICAgIG9uX3JlYWR5KCkge1xuICAgICAgICAvLyBXcmFwIGNoaWxkcmVuIGluIG5hdiBzdHJ1Y3R1cmVcbiAgICAgICAgY29uc3QgJG5hdiA9IHRoaXMuJGlkKCduYXZfaXRlbXMnKTtcbiAgICAgICAgJG5hdi5jaGlsZHJlbigpLmVhY2goZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICBjb25zdCAkY2hpbGQgPSAkKHRoaXMpO1xuICAgICAgICAgICAgaWYgKCRjaGlsZC5wcm9wKCd0YWdOYW1lJykgIT09ICdMSScpIHtcbiAgICAgICAgICAgICAgICBjb25zdCAkbGkgPSAkKCc8bGk+JykuYWRkQ2xhc3MoJ25hdi1pdGVtJyk7XG4gICAgICAgICAgICAgICAgJGNoaWxkLmFkZENsYXNzKCduYXYtbGluaycpO1xuICAgICAgICAgICAgICAgICRjaGlsZC53cmFwKCRsaSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cbn1cbiIsImNsYXNzIFRyZW5kX0luZGljYXRvciBleHRlbmRzIEpxaHRtbF9Db21wb25lbnQge1xuICAgIG9uX3JlYWR5KCkge1xuICAgICAgICBjb25zdCB0ZXh0ID0gdGhpcy4kLnRleHQoKS50cmltKCk7XG4gICAgICAgIGNvbnN0IGlzX3Bvc2l0aXZlID0gdGV4dC5zdGFydHNXaXRoKCcrJyk7XG4gICAgICAgIGNvbnN0IGlzX25lZ2F0aXZlID0gdGV4dC5zdGFydHNXaXRoKCctJyk7XG5cbiAgICAgICAgaWYgKGlzX3Bvc2l0aXZlKSB7XG4gICAgICAgICAgICB0aGlzLiQuYWRkQ2xhc3MoJ3RleHQtc3VjY2VzcyBmdy1ib2xkJyk7XG4gICAgICAgIH0gZWxzZSBpZiAoaXNfbmVnYXRpdmUpIHtcbiAgICAgICAgICAgIHRoaXMuJC5hZGRDbGFzcygndGV4dC1kYW5nZXIgZnctYm9sZCcpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy4kLmFkZENsYXNzKCd0ZXh0LW11dGVkIGZ3LWJvbGQnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuJC5hZGRDbGFzcygnZC1ibG9jayBtdC0xJyk7XG4gICAgfVxufVxuIiwiY2xhc3MgVHdvX0NvbHVtbl9MYXlvdXQgZXh0ZW5kcyBKcWh0bWxfQ29tcG9uZW50IHtcbiAgICBvbl9yZWFkeSgpIHtcbiAgICAgICAgLy8gV3JhcCBlYWNoIGRpcmVjdCBjaGlsZCBpbiByZXNwb25zaXZlIGNvbHVtbiBjbGFzc2VzXG4gICAgICAgIHRoaXMuJC5jaGlsZHJlbigpLmVhY2goZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICBjb25zdCAkZWxlbWVudCA9ICQodGhpcyk7XG4gICAgICAgICAgICAkZWxlbWVudC5hZGRDbGFzcygnY29sLTEyIGNvbC1sZy02IG1iLTQnKTtcbiAgICAgICAgfSk7XG4gICAgfVxufVxuIiwiY2xhc3MgVXNlcl9BdmF0YXJfRHJvcGRvd24gZXh0ZW5kcyBKcWh0bWxfQ29tcG9uZW50IHtcbiAgICBvbl9yZWFkeSgpIHtcbiAgICAgICAgLy8gRW5zdXJlIHByb3BlciBkcm9wZG93biBpdGVtIHN0cnVjdHVyZVxuICAgICAgICBjb25zdCAkbWVudSA9IHRoaXMuJGlkKCdtZW51Jyk7XG4gICAgICAgICRtZW51LmNoaWxkcmVuKCkuZWFjaChmdW5jdGlvbigpIHtcbiAgICAgICAgICAgIGNvbnN0ICRjaGlsZCA9ICQodGhpcyk7XG4gICAgICAgICAgICBpZiAoJGNoaWxkLnByb3AoJ3RhZ05hbWUnKSAhPT0gJ0xJJykge1xuICAgICAgICAgICAgICAgIGNvbnN0ICRsaSA9ICQoJzxsaT4nKTtcbiAgICAgICAgICAgICAgICBpZiAoJGNoaWxkLnByb3AoJ3RhZ05hbWUnKSA9PT0gJ0hSJykge1xuICAgICAgICAgICAgICAgICAgICAkbGkuYXBwZW5kKCQoJzxocj4nKS5hZGRDbGFzcygnZHJvcGRvd24tZGl2aWRlcicpKTtcbiAgICAgICAgICAgICAgICAgICAgJGNoaWxkLnJlcGxhY2VXaXRoKCRsaSk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgJGNoaWxkLmFkZENsYXNzKCdkcm9wZG93bi1pdGVtJyk7XG4gICAgICAgICAgICAgICAgICAgICRjaGlsZC53cmFwKCRsaSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG59XG4iLCIvKipcbiAqIE1vZGFsX0Fic3RyYWN0IC0gQmFzZSBjbGFzcyBmb3IgbW9kYWwgb3JjaGVzdHJhdGlvbiBjbGFzc2VzXG4gKlxuICogKipQaGlsb3NvcGh5Kio6XG4gKiBNb2RhbCBjbGFzc2VzIGFyZSBvcmNoZXN0cmF0aW9uIGxheWVycyB0aGF0IG1hbmFnZSB0aGUgbGlmZWN5Y2xlIG9mIHNob3dpbmdcbiAqIGEgbW9kYWwsIGNvbGxlY3RpbmcgdXNlciBpbnB1dCwgYW5kIHJldHVybmluZyByZXN1bHRzLiBUaGV5IGRvIE5PVCBjb250YWluXG4gKiBmb3JtIHZhbGlkYXRpb24gb3IgYnVzaW5lc3MgbG9naWMgLSB0aGF0IGJlbG9uZ3MgaW4ganFodG1sIGNvbXBvbmVudHMgYW5kXG4gKiBjb250cm9sbGVyIGVuZHBvaW50cy5cbiAqXG4gKiAqKlB1cnBvc2UqKjpcbiAqIC0gUHJvdmlkZXMgYSBjb21tb24gYmFzZSBjbGFzcyBmb3IgdHlwZSBpZGVudGlmaWNhdGlvblxuICogLSBFbmZvcmNlcyBmaWxlIG5hbWluZyBjb252ZW50aW9ucyAobW9kYWwgY2xhc3NlcyBlbmQgd2l0aCBfTW9kYWwpXG4gKiAtIERvY3VtZW50cyB0aGUgbW9kYWwgY2xhc3MgcGF0dGVyblxuICogLSBFbmFibGVzIGZyYW1ld29yay1sZXZlbCBmZWF0dXJlcyAoZnV0dXJlOiBkaXNjb3ZlcnksIHZhbGlkYXRpb24pXG4gKlxuICogKipSZXNwb25zaWJpbGl0aWVzIG9mIE1vZGFsIENsYXNzZXMqKjpcbiAqIC0gSW52b2tlIE1vZGFsLmZvcm0oKSAvIE1vZGFsLnNob3coKSAvIE1vZGFsLmNvbmZpcm0oKSB3aXRoIGFwcHJvcHJpYXRlIGNvbmZpZ3VyYXRpb25cbiAqIC0gSGFuZGxlIG1vZGFsIGxpZmVjeWNsZSAoc2hvdywgc3VibWl0LCBjYW5jZWwsIGVycm9ycylcbiAqIC0gUmV0dXJuIFByb21pc2UgdGhhdCByZXNvbHZlcyB3aXRoIGRhdGEgb3IgZmFsc2VcbiAqIC0gRW5jYXBzdWxhdGUgbW9kYWwtc3BlY2lmaWMgVUkgbG9naWNcbiAqXG4gKiAqKkNvbnRyYWN0Kio6XG4gKiBBbGwgbW9kYWwgY2xhc3NlcyBleHRlbmRpbmcgTW9kYWxfQWJzdHJhY3QgbXVzdCBpbXBsZW1lbnQ6XG4gKiAtIGBzdGF0aWMgYXN5bmMgc2hvdyhwYXJhbXMpYDogUHJpbWFyeSBlbnRyeSBwb2ludCwgcmV0dXJucyBQcm9taXNlXG4gKlxuICogKipSZXR1cm4gVmFsdWVzKio6XG4gKiAtIFN1Y2Nlc3M6IFJlc29sdmUgd2l0aCBkYXRhIG9iamVjdCAoZS5nLiwgY3JlYXRlZCB1c2VyIHJlY29yZClcbiAqIC0gQ2FuY2VsL0Nsb3NlOiBSZXNvbHZlIHdpdGggZmFsc2VcbiAqIC0gRXJyb3I6IFNob3cgZXJyb3IgaW4gbW9kYWwsIGtlZXAgb3BlbiwgZG9uJ3QgcmVzb2x2ZSB1bnRpbCB1c2VyIGFjdHNcbiAqXG4gKiAqKkludGVncmF0aW9uKio6XG4gKiBNb2RhbCBjbGFzc2VzIHVzZSBNb2RhbC5qcyBzdGF0aWMgQVBJIChNb2RhbC5mb3JtKCksIE1vZGFsLnNob3coKSwgZXRjLilcbiAqIGFzIGJ1aWxkaW5nIGJsb2Nrcy4gRm9ybSB2YWxpZGF0aW9uIGhhbmRsZWQgYnkgUnN4X0Zvcm0gYW5kIEZvcm1fVXRpbHMuXG4gKiBQYWdlIEpTIG9yY2hlc3RyYXRlcyBtb2RhbCBmbG93IGJ1dCBkb2Vzbid0IGNvbnRhaW4gbW9kYWwgVUkgbG9naWMuXG4gKlxuICogKipQYXR0ZXJuIEV4YW1wbGVzKio6XG4gKlxuICogU2ltcGxlIGZvcm0gbW9kYWw6XG4gKiBgYGBcbiAqIGNsYXNzIEFkZF9Vc2VyX01vZGFsIGV4dGVuZHMgTW9kYWxfQWJzdHJhY3Qge1xuICogICAgIHN0YXRpYyBhc3luYyBzaG93KCkge1xuICogICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBNb2RhbC5mb3JtKHtcbiAqICAgICAgICAgICAgIHRpdGxlOiAnQWRkIFVzZXInLFxuICogICAgICAgICAgICAgY29tcG9uZW50OiAnQWRkX1VzZXJfTW9kYWxfRm9ybScsXG4gKiAgICAgICAgICAgICBvbl9zdWJtaXQ6IGFzeW5jIChmb3JtKSA9PiB7XG4gKiAgICAgICAgICAgICAgICAgdHJ5IHtcbiAqICAgICAgICAgICAgICAgICAgICAgY29uc3QgdmFsdWVzID0gZm9ybS52YWxzKCk7XG4gKiAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IENvbnRyb2xsZXIuYWRkX3VzZXIodmFsdWVzKTtcbiAqICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDsgLy8gQ2xvc2UgbW9kYWwsIHJldHVybiBkYXRhXG4gKiAgICAgICAgICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAqICAgICAgICAgICAgICAgICAgICAgYXdhaXQgZm9ybS5yZW5kZXJfZXJyb3IoZXJyb3IpO1xuICogICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7IC8vIEtlZXAgbW9kYWwgb3BlblxuICogICAgICAgICAgICAgICAgIH1cbiAqICAgICAgICAgICAgIH0sXG4gKiAgICAgICAgIH0pO1xuICogICAgICAgICByZXR1cm4gcmVzdWx0IHx8IGZhbHNlO1xuICogICAgIH1cbiAqIH1cbiAqIGBgYFxuICpcbiAqIEN1c3RvbSBjb250ZW50IG1vZGFsOlxuICogYGBgXG4gKiBjbGFzcyBDb25maXJtX0RlbGV0ZV9Nb2RhbCBleHRlbmRzIE1vZGFsX0Fic3RyYWN0IHtcbiAqICAgICBzdGF0aWMgYXN5bmMgc2hvdyh7aXRlbV9uYW1lfSkge1xuICogICAgICAgICByZXR1cm4gYXdhaXQgTW9kYWwuY29uZmlybShcbiAqICAgICAgICAgICAgICdDb25maXJtIERlbGV0ZScsXG4gKiAgICAgICAgICAgICBgQXJlIHlvdSBzdXJlIHlvdSB3YW50IHRvIGRlbGV0ZSAke2l0ZW1fbmFtZX0/YFxuICogICAgICAgICApO1xuICogICAgIH1cbiAqIH1cbiAqIGBgYFxuICpcbiAqIE1vZGFsIHdpdGggYmFja2VuZCBjYWxsOlxuICogYGBgXG4gKiBjbGFzcyBTZW5kX0ludml0ZV9Nb2RhbCBleHRlbmRzIE1vZGFsX0Fic3RyYWN0IHtcbiAqICAgICBzdGF0aWMgYXN5bmMgc2hvdyh1c2VyX2lkKSB7XG4gKiAgICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IENvbnRyb2xsZXIuc2VuZF9pbnZpdGUoe3VzZXJfaWR9KTtcbiAqICAgICAgICAgaWYgKHJlc3VsdC5pbnZpdGVfdXJsKSB7XG4gKiAgICAgICAgICAgICBhd2FpdCBNb2RhbC5hbGVydCgnSW52aXRlIFNlbnQnLCByZXN1bHQuaW52aXRlX3VybCk7XG4gKiAgICAgICAgIH1cbiAqICAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAqICAgICB9XG4gKiB9XG4gKiBgYGBcbiAqXG4gKiAqKlVzYWdlIFBhdHRlcm4qKjpcbiAqIGBgYFxuICogLy8gUGFnZSBKUyBvcmNoZXN0cmF0ZXMgZmxvdywgbW9kYWxzIGhhbmRsZSBVSVxuICogY29uc3QgdXNlciA9IGF3YWl0IEFkZF9Vc2VyX01vZGFsLnNob3coKTtcbiAqIGlmICh1c2VyKSB7XG4gKiAgICAgJCgnLlVzZXJzX0RhdGFHcmlkJykuY29tcG9uZW50KCkucmVsb2FkKCk7XG4gKiAgICAgYXdhaXQgU2VuZF9Vc2VyX0ludml0ZV9Nb2RhbC5zaG93KHVzZXIuaWQpO1xuICogfVxuICogYGBgXG4gKlxuICogKipCZXN0IFByYWN0aWNlcyoqOlxuICogLSBLZWVwIG1vZGFsIGNsYXNzZXMgZm9jdXNlZDogb25lIG1vZGFsID0gb25lIGNsYXNzXG4gKiAtIFBhZ2UgSlMgb3JjaGVzdHJhdGVzIHNlcXVlbmNlLCBtb2RhbCBjbGFzc2VzIGhhbmRsZSBpbmRpdmlkdWFsIG1vZGFsc1xuICogLSBNb2RhbCBjbGFzc2VzIGRvbid0IGNhbGwgZWFjaCBvdGhlciBkaXJlY3RseVxuICogLSBNb2RhbCBjbGFzc2VzIGRvbid0IHVwZGF0ZSBVSSAoZ3JpZHMsIGxpc3RzKSAtIHBhZ2UgSlMgZG9lcyB0aGF0XG4gKiAtIFVzZSBkZXNjcmlwdGl2ZSBuYW1lcyBlbmRpbmcgaW4gX01vZGFsIChBZGRfVXNlcl9Nb2RhbCwgU2VuZF9JbnZpdGVfTW9kYWwpXG4gKiAtIFBsYWNlIGZlYXR1cmUtc3BlY2lmaWMgbW9kYWxzIGluIGZlYXR1cmUgZGlyZWN0b3J5XG4gKiAtIFBsYWNlIHJldXNhYmxlIG1vZGFscyBpbiB0aGVtZS9jb21wb25lbnRzL21vZGFsL1xuICpcbiAqICoqV2hlbiB0byBVc2UgTW9kYWwgQ2xhc3NlcyoqOlxuICogLSBNdWx0aS1zdGVwIGZvcm1zXG4gKiAtIEZvcm1zIHdpdGggY29tcGxleCB2YWxpZGF0aW9uXG4gKiAtIE1vZGFscyBjYWxsZWQgZnJvbSBtdWx0aXBsZSBwbGFjZXNcbiAqIC0gTW9kYWxzIHdpdGggYmFja2VuZCBpbnRlcmFjdGlvbnNcbiAqXG4gKiAqKldoZW4gTk9UIHRvIFVzZSBNb2RhbCBDbGFzc2VzKio6XG4gKiAtIFNpbXBsZSBhbGVydHM6IGBhd2FpdCBNb2RhbC5hbGVydCgnU2F2ZWQhJylgXG4gKiAtIFNpbXBsZSBjb25maXJtYXRpb25zOiBgaWYgKGF3YWl0IE1vZGFsLmNvbmZpcm0oJ0RlbGV0ZT8nKSkgey4uLn1gXG4gKiAtIE9uZS1vZmYgcHJvbXB0czogYGNvbnN0IG5hbWUgPSBhd2FpdCBNb2RhbC5wcm9tcHQoJ0VudGVyIG5hbWU6JylgXG4gKi9cbmNsYXNzIE1vZGFsX0Fic3RyYWN0IHtcbiAgICAvLyBUaGlzIGNsYXNzIHByb3ZpZGVzIHN0cnVjdHVyZSBhbmQgZG9jdW1lbnRhdGlvbiBmb3IgbW9kYWwgcGF0dGVybnMuXG4gICAgLy8gQ29uY3JldGUgbW9kYWwgY2xhc3NlcyBleHRlbmQgdGhpcyBhbmQgaW1wbGVtZW50IHN0YXRpYyBzaG93KCkgbWV0aG9kLlxufVxuIiwiLyoqXG4gKiBSc3hfTW9kYWwgQ29tcG9uZW50XG4gKlxuICogSW5zdGFuY2Ugb2YgYSBtb2RhbCBkaWFsb2cuIEhhbmRsZXMgbGlmZWN5Y2xlLCBzaXppbmcsIGFuZCB1c2VyIGludGVyYWN0aW9uLlxuICogVHlwaWNhbGx5IGNyZWF0ZWQgYW5kIG1hbmFnZWQgYnkgdGhlIE1vZGFsIHN0YXRpYyBBUEkgY2xhc3MuXG4gKi9cbmNsYXNzIFJzeF9Nb2RhbCBleHRlbmRzIEpxaHRtbF9Db21wb25lbnQge1xuICAgIG9uX2NyZWF0ZSgpIHtcbiAgICAgICAgdGhpcy5kYXRhLnRpdGxlID0gJyc7XG4gICAgICAgIHRoaXMuZGF0YS5ib2R5X2NvbnRlbnQgPSBudWxsO1xuICAgICAgICB0aGlzLmRhdGEuYnV0dG9ucyA9IFtdO1xuICAgICAgICB0aGlzLmRhdGEuY2xvc2FibGUgPSB0cnVlO1xuICAgICAgICB0aGlzLmRhdGEubWF4X3dpZHRoID0gODAwO1xuICAgICAgICB0aGlzLmRhdGEuY2xvc2Vfb25fc3VibWl0ID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5kYXRhLmlzX3Zpc2libGUgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5kYXRhLnJlc3VsdF9wcm9taXNlID0gbnVsbDtcbiAgICAgICAgdGhpcy5kYXRhLnJlc29sdmVfZm4gPSBudWxsO1xuXG4gICAgICAgIC8vIFN0b3JlIHJlZmVyZW5jZSB0byBib290c3RyYXAgbW9kYWwgaW5zdGFuY2VcbiAgICAgICAgdGhpcy5fYnNfbW9kYWwgPSBudWxsO1xuICAgICAgICB0aGlzLl9yZXNpemVfaGFuZGxlciA9IG51bGw7XG4gICAgfVxuXG4gICAgb25fcmVhZHkoKSB7XG4gICAgICAgIGNvbnN0IHRoYXQgPSB0aGlzO1xuXG4gICAgICAgIC8vIFNldCB1cCBjbG9zZSBidXR0b24gaGFuZGxlclxuICAgICAgICB0aGlzLiRpZCgnY2xvc2VfYnRuJykub24oJ2NsaWNrJywgZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICAgIGlmICh0aGF0LmRhdGEuY2xvc2FibGUpIHtcbiAgICAgICAgICAgICAgICB0aGF0LmNsb3NlKGZhbHNlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gU2V0IHVwIGJhY2tkcm9wIGNsaWNrIGhhbmRsZXJcbiAgICAgICAgdGhpcy4kaWQoJ2JhY2tkcm9wJykub24oJ2NsaWNrJywgZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgICAgIGlmICh0aGF0LmRhdGEuY2xvc2FibGUgJiYgZS50YXJnZXQgPT09IHRoaXMpIHtcbiAgICAgICAgICAgICAgICB0aGF0LmNsb3NlKGZhbHNlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gU2V0IHVwIEVTQyBrZXkgaGFuZGxlclxuICAgICAgICAkKGRvY3VtZW50KS5vbigna2V5ZG93bi5yc3hfbW9kYWxfJyArIHRoaXMuX2NpZCwgZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgICAgIGlmIChlLmtleSA9PT0gJ0VzY2FwZScgJiYgdGhhdC5kYXRhLmNsb3NhYmxlICYmIHRoYXQuZGF0YS5pc192aXNpYmxlKSB7XG4gICAgICAgICAgICAgICAgdGhhdC5jbG9zZShmYWxzZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIFNldCB1cCByZXNpemUgaGFuZGxlclxuICAgICAgICB0aGlzLl9yZXNpemVfaGFuZGxlciA9IGRlYm91bmNlKCgpID0+IHtcbiAgICAgICAgICAgIGlmICh0aGF0LmRhdGEuaXNfdmlzaWJsZSkge1xuICAgICAgICAgICAgICAgIHRoYXQuX2FwcGx5X3NpemluZygpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9LCAxMDApO1xuXG4gICAgICAgICQod2luZG93KS5vbigncmVzaXplLnJzeF9tb2RhbF8nICsgdGhpcy5fY2lkLCB0aGlzLl9yZXNpemVfaGFuZGxlcik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ29uZmlndXJlIGFuZCBzaG93IHRoZSBtb2RhbFxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zIC0gTW9kYWwgb3B0aW9ucyAodGl0bGUsIGJvZHksIGJ1dHRvbnMsIGV0Yy4pXG4gICAgICogQHBhcmFtIHtPYmplY3R9IGludGVybmFsX29wdGlvbnMgLSBJbnRlcm5hbCBvcHRpb25zIChza2lwX2JhY2tkcm9wLCBhbmltYXRlKVxuICAgICAqL1xuICAgIGFzeW5jIHNob3cob3B0aW9ucywgaW50ZXJuYWxfb3B0aW9ucyA9IHt9KSB7XG4gICAgICAgIGNvbnN0IHRoYXQgPSB0aGlzO1xuICAgICAgICBjb25zdCBza2lwX2JhY2tkcm9wID0gaW50ZXJuYWxfb3B0aW9ucy5za2lwX2JhY2tkcm9wIHx8IGZhbHNlO1xuICAgICAgICBjb25zdCBzaG91bGRfYW5pbWF0ZSA9IGludGVybmFsX29wdGlvbnMuYW5pbWF0ZSB8fCBmYWxzZTtcblxuICAgICAgICBjb25zb2xlLmxvZygnW1JzeF9Nb2RhbF0gc2hvdygpIGNhbGxlZCB3aXRoIG9wdGlvbnM6Jywgb3B0aW9ucyk7XG5cbiAgICAgICAgLy8gU3RvcmUgb3B0aW9uc1xuICAgICAgICB0aGlzLmRhdGEudGl0bGUgPSBvcHRpb25zLnRpdGxlIHx8ICcnO1xuICAgICAgICB0aGlzLmRhdGEuY2xvc2FibGUgPSBvcHRpb25zLmNsb3NhYmxlICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLmNsb3NhYmxlIDogdHJ1ZTtcbiAgICAgICAgdGhpcy5kYXRhLm1heF93aWR0aCA9IG9wdGlvbnMubWF4X3dpZHRoIHx8IDgwMDtcbiAgICAgICAgdGhpcy5kYXRhLmNsb3NlX29uX3N1Ym1pdCA9IG9wdGlvbnMuY2xvc2Vfb25fc3VibWl0ICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLmNsb3NlX29uX3N1Ym1pdCA6IHRydWU7XG4gICAgICAgIHRoaXMuZGF0YS5idXR0b25zID0gb3B0aW9ucy5idXR0b25zIHx8IFtdO1xuICAgICAgICB0aGlzLmRhdGEuc2tpcF9iYWNrZHJvcCA9IHNraXBfYmFja2Ryb3A7XG4gICAgICAgIHRoaXMuZGF0YS5pY29uID0gb3B0aW9ucy5pY29uIHx8IG51bGw7XG5cbiAgICAgICAgY29uc29sZS5sb2coJ1tSc3hfTW9kYWxdIFNldHRpbmcgdGl0bGUgdG86JywgdGhpcy5kYXRhLnRpdGxlKTtcbiAgICAgICAgY29uc29sZS5sb2coJ1tSc3hfTW9kYWxdIFRpdGxlIGVsZW1lbnQ6JywgdGhpcy4kaWQoJ3RpdGxlJykpO1xuXG4gICAgICAgIC8vIFNldCB0aXRsZVxuICAgICAgICB0aGlzLiRpZCgndGl0bGUnKS50ZXh0KHRoaXMuZGF0YS50aXRsZSk7XG5cbiAgICAgICAgLy8gU2hvdy9oaWRlIGNsb3NlIGJ1dHRvbiBiYXNlZCBvbiBjbG9zYWJsZVxuICAgICAgICBpZiAodGhpcy5kYXRhLmNsb3NhYmxlKSB7XG4gICAgICAgICAgICB0aGlzLiRpZCgnY2xvc2VfYnRuJykuc2hvdygpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy4kaWQoJ2Nsb3NlX2J0bicpLmhpZGUoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFNldCBib2R5IGNvbnRlbnQgKHdpdGggb3B0aW9uYWwgaWNvbilcbiAgICAgICAgdGhpcy5fc2V0X2JvZHlfY29udGVudChvcHRpb25zLmJvZHksIHRoaXMuZGF0YS5pY29uKTtcblxuICAgICAgICAvLyBTZXQgYnV0dG9uc1xuICAgICAgICB0aGlzLl9zZXRfYnV0dG9ucygpO1xuXG4gICAgICAgIC8vIENyZWF0ZSBwcm9taXNlIHRoYXQgd2lsbCByZXNvbHZlIHdoZW4gbW9kYWwgY2xvc2VzXG4gICAgICAgIGNvbnN0IHJlc3VsdF9wcm9taXNlID0gbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHtcbiAgICAgICAgICAgIHRoYXQuZGF0YS5yZXNvbHZlX2ZuID0gcmVzb2x2ZTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gU2hvdyBtb2RhbCBhbmQgYmFja2Ryb3BcbiAgICAgICAgdGhpcy5kYXRhLmlzX3Zpc2libGUgPSB0cnVlO1xuXG4gICAgICAgIC8vIEFwcGVuZCB0byBib2R5IHNvIGl0J3Mgb24gdG9wIChkb24ndCBhcHBlbmQgYmFja2Ryb3AgaWYgdXNpbmcgc2hhcmVkKVxuICAgICAgICBpZiAoIXNraXBfYmFja2Ryb3ApIHtcbiAgICAgICAgICAgICQoJ2JvZHknKS5hcHBlbmQodGhpcy4kaWQoJ2JhY2tkcm9wJykpO1xuICAgICAgICB9XG4gICAgICAgICQoJ2JvZHknKS5hcHBlbmQodGhpcy4kKTtcblxuICAgICAgICAvLyBBcHBseSBzaXppbmcgYmVmb3JlIHNob3dpbmdcbiAgICAgICAgdGhpcy5fYXBwbHlfc2l6aW5nKCk7XG5cbiAgICAgICAgLy8gRmFkZSBpbiBtb2RhbCAoYW5kIGJhY2tkcm9wIGlmIG5vdCB1c2luZyBzaGFyZWQpXG4gICAgICAgIGF3YWl0IHRoaXMuX2ZhZGVfaW4oc2hvdWxkX2FuaW1hdGUpO1xuXG4gICAgICAgIC8vIEF1dG8tZm9jdXMgZmlyc3QgaW5wdXQgZWxlbWVudFxuICAgICAgICB0aGlzLl9mb2N1c19maXJzdF9pbnB1dCgpO1xuXG4gICAgICAgIHJldHVybiByZXN1bHRfcHJvbWlzZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTZXQgYm9keSBjb250ZW50IHdpdGggb3B0aW9uYWwgaWNvblxuICAgICAqL1xuICAgIF9zZXRfYm9keV9jb250ZW50KGJvZHksIGljb24pIHtcbiAgICAgICAgY29uc3QgJGJvZHkgPSB0aGlzLiRpZCgnYm9keScpO1xuICAgICAgICAkYm9keS5lbXB0eSgpO1xuXG4gICAgICAgIC8vIElmIGljb24gcHJvdmlkZWQsIGFkZCBpdFxuICAgICAgICBpZiAoaWNvbikge1xuICAgICAgICAgICAgY29uc3QgJGljb24gPSAkKGA8aSBjbGFzcz1cImJpIGJpLSR7aWNvbn0gbW9kYWwtaWNvblwiPjwvaT5gKTtcbiAgICAgICAgICAgICRib2R5LmFwcGVuZCgkaWNvbik7XG4gICAgICAgICAgICAkYm9keS5hZGRDbGFzcygnaGFzLWljb24nKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICRib2R5LnJlbW92ZUNsYXNzKCdoYXMtaWNvbicpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gR2V0IG9yIGNyZWF0ZSBib2R5IGNvbnRlbnQgd3JhcHBlclxuICAgICAgICBsZXQgJGNvbnRlbnQgPSB0aGlzLiRpZCgnYm9keV9jb250ZW50Jyk7XG4gICAgICAgIGlmICghJGNvbnRlbnQuZXhpc3RzKCkpIHtcbiAgICAgICAgICAgICRjb250ZW50ID0gJCgnPGRpdiBjbGFzcz1cIm1vZGFsLWJvZHktY29udGVudFwiPjwvZGl2PicpO1xuICAgICAgICAgICAgJGJvZHkuYXBwZW5kKCRjb250ZW50KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0eXBlb2YgYm9keSA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgIC8vIFRleHQgY29udGVudCAtIGVzY2FwZSBhbmQgY29udmVydCBuZXdsaW5lc1xuICAgICAgICAgICAgY29uc3QgZXNjYXBlZCA9ICQoJzxkaXY+JykudGV4dChib2R5KS5odG1sKCkucmVwbGFjZSgvXFxuL2csICc8YnI+Jyk7XG4gICAgICAgICAgICAkY29udGVudC5odG1sKGVzY2FwZWQpO1xuICAgICAgICB9IGVsc2UgaWYgKGJvZHkgaW5zdGFuY2VvZiBqUXVlcnkpIHtcbiAgICAgICAgICAgIC8vIGpRdWVyeSBlbGVtZW50XG4gICAgICAgICAgICAkY29udGVudC5hcHBlbmQoYm9keSk7XG4gICAgICAgIH0gZWxzZSBpZiAoYm9keSAmJiB0eXBlb2YgYm9keSA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgICAgIC8vIEFzc3VtZSBpdCdzIGEganFodG1sIGNvbXBvbmVudCBpbnN0YW5jZVxuICAgICAgICAgICAgJGNvbnRlbnQuYXBwZW5kKGJvZHkuJCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTZXQgYnV0dG9ucyBpbiBmb290ZXJcbiAgICAgKi9cbiAgICBfc2V0X2J1dHRvbnMoKSB7XG4gICAgICAgIGNvbnN0IHRoYXQgPSB0aGlzO1xuICAgICAgICBjb25zdCAkZm9vdGVyID0gdGhpcy4kaWQoJ2Zvb3RlcicpO1xuICAgICAgICAkZm9vdGVyLmVtcHR5KCk7XG5cbiAgICAgICAgaWYgKHRoaXMuZGF0YS5idXR0b25zLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgJGZvb3Rlci5oaWRlKCk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICAkZm9vdGVyLnNob3coKTtcblxuICAgICAgICBmb3IgKGxldCBidXR0b25fZGVmIG9mIHRoaXMuZGF0YS5idXR0b25zKSB7XG4gICAgICAgICAgICBjb25zdCAkYnV0dG9uID0gJCgnPGJ1dHRvbj4nKVxuICAgICAgICAgICAgICAgIC5hdHRyKCd0eXBlJywgJ2J1dHRvbicpXG4gICAgICAgICAgICAgICAgLmFkZENsYXNzKCdidG4nKVxuICAgICAgICAgICAgICAgIC5hZGRDbGFzcyhidXR0b25fZGVmLmNsYXNzIHx8ICdidG4tc2Vjb25kYXJ5JylcbiAgICAgICAgICAgICAgICAudGV4dChidXR0b25fZGVmLmxhYmVsIHx8ICdCdXR0b24nKTtcblxuICAgICAgICAgICAgJGJ1dHRvbi5vbignY2xpY2snLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgbGV0IHJlc3VsdCA9IGJ1dHRvbl9kZWYudmFsdWU7XG4gICAgICAgICAgICAgICAgbGV0IGhhZF9jYWxsYmFjayA9IGZhbHNlO1xuXG4gICAgICAgICAgICAgICAgLy8gSWYgYnV0dG9uIGhhcyBhIGNhbGxiYWNrLCBjYWxsIGl0IGFuZCB1c2UgcmV0dXJuIHZhbHVlIGFzIHJlc3VsdFxuICAgICAgICAgICAgICAgIGlmIChidXR0b25fZGVmLmNhbGxiYWNrICYmIHR5cGVvZiBidXR0b25fZGVmLmNhbGxiYWNrID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICAgICAgICAgIGhhZF9jYWxsYmFjayA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IGF3YWl0IGJ1dHRvbl9kZWYuY2FsbGJhY2soKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAvLyBJZiBjYWxsYmFjayByZXR1cm5lZCBmYWxzZSwga2VlcCBtb2RhbCBvcGVuIChidXQgbm90IGlmIGp1c3QgYnV0dG9uIHZhbHVlIGlzIGZhbHNlKVxuICAgICAgICAgICAgICAgIGlmIChyZXN1bHQgPT09IGZhbHNlICYmIGhhZF9jYWxsYmFjaykge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgLy8gQ2xvc2UgbW9kYWwgd2l0aCByZXN1bHRcbiAgICAgICAgICAgICAgICB0aGF0LmNsb3NlKHJlc3VsdCk7XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgJGZvb3Rlci5hcHBlbmQoJGJ1dHRvbik7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDYWxjdWxhdGUgYW5kIGFwcGx5IHJlc3BvbnNpdmUgc2l6aW5nXG4gICAgICovXG4gICAgX2FwcGx5X3NpemluZygpIHtcbiAgICAgICAgY29uc3Qgdmlld3BvcnRfd2lkdGggPSAkKHdpbmRvdykud2lkdGgoKTtcbiAgICAgICAgY29uc3Qgdmlld3BvcnRfaGVpZ2h0ID0gJCh3aW5kb3cpLmhlaWdodCgpO1xuICAgICAgICBjb25zdCBpc19tb2JpbGUgPSB2aWV3cG9ydF93aWR0aCA8IDc2ODtcblxuICAgICAgICAvLyBDYWxjdWxhdGUgbWF4IHdpZHRoIGJhc2VkIG9uIHZpZXdwb3J0XG4gICAgICAgIGxldCBtYXhfd2lkdGggPSB0aGlzLmRhdGEubWF4X3dpZHRoO1xuICAgICAgICBjb25zdCB2aWV3cG9ydF9saW1pdCA9IGlzX21vYmlsZSA/IHZpZXdwb3J0X3dpZHRoICogMC45IDogdmlld3BvcnRfd2lkdGggKiAwLjg7XG5cbiAgICAgICAgbWF4X3dpZHRoID0gTWF0aC5taW4obWF4X3dpZHRoLCB2aWV3cG9ydF9saW1pdCk7XG5cbiAgICAgICAgLy8gVHJ5IHRvIGNvbnN0cmFpbiB0byA2MCUgd2lkdGggZm9yIGJldHRlciBwcm9wb3J0aW9ucyBvbiBkZXNrdG9wXG4gICAgICAgIGlmICghaXNfbW9iaWxlKSB7XG4gICAgICAgICAgICBjb25zdCBwcmVmZXJyZWRfd2lkdGggPSB2aWV3cG9ydF93aWR0aCAqIDAuNjtcbiAgICAgICAgICAgIGlmIChwcmVmZXJyZWRfd2lkdGggPCBtYXhfd2lkdGgpIHtcbiAgICAgICAgICAgICAgICBtYXhfd2lkdGggPSBwcmVmZXJyZWRfd2lkdGg7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyBBcHBseSB3aWR0aFxuICAgICAgICB0aGlzLiRpZCgnZGlhbG9nJykuY3NzKCdtYXgtd2lkdGgnLCBtYXhfd2lkdGggKyAncHgnKTtcblxuICAgICAgICAvLyBDaGVjayBpZiBjb250ZW50IGV4Y2VlZHMgODAlIGhlaWdodFxuICAgICAgICBjb25zdCBjb250ZW50X2hlaWdodCA9IHRoaXMuJGlkKCdkaWFsb2cnKS5vdXRlckhlaWdodCgpO1xuICAgICAgICBjb25zdCBtYXhfaGVpZ2h0ID0gdmlld3BvcnRfaGVpZ2h0ICogMC44O1xuXG4gICAgICAgIGlmIChjb250ZW50X2hlaWdodCA+IG1heF9oZWlnaHQpIHtcbiAgICAgICAgICAgIC8vIEVuYWJsZSBzY3JvbGxpbmdcbiAgICAgICAgICAgIHRoaXMuJGlkKCdkaWFsb2cnKS5jc3MoJ21heC1oZWlnaHQnLCBtYXhfaGVpZ2h0ICsgJ3B4Jyk7XG4gICAgICAgICAgICB0aGlzLiRpZCgnYm9keScpLmNzcyh7XG4gICAgICAgICAgICAgICAgJ292ZXJmbG93LXknOiAnYXV0bycsXG4gICAgICAgICAgICAgICAgJ21heC1oZWlnaHQnOiBtYXhfaGVpZ2h0IC0gMTUwICsgJ3B4JywgLy8gQWNjb3VudCBmb3IgaGVhZGVyL2Zvb3RlclxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBSZXNldCBzY3JvbGxpbmdcbiAgICAgICAgICAgIHRoaXMuJGlkKCdkaWFsb2cnKS5jc3MoJ21heC1oZWlnaHQnLCAnJyk7XG4gICAgICAgICAgICB0aGlzLiRpZCgnYm9keScpLmNzcyh7XG4gICAgICAgICAgICAgICAgJ292ZXJmbG93LXknOiAnJyxcbiAgICAgICAgICAgICAgICAnbWF4LWhlaWdodCc6ICcnLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBNb2JpbGUgZWRnZSBzcGFjaW5nXG4gICAgICAgIGlmIChpc19tb2JpbGUpIHtcbiAgICAgICAgICAgIHRoaXMuJGlkKCdkaWFsb2cnKS5jc3MoJ21hcmdpbicsICc1JScpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy4kaWQoJ2RpYWxvZycpLmNzcygnbWFyZ2luJywgJzAnKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNob3cgYW5pbWF0aW9uIChpbnN0YW50IG9yIHdpdGggZmx5LWluKVxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gYW5pbWF0ZSAtIFdoZXRoZXIgdG8gYW5pbWF0ZSB0aGUgbW9kYWwgZW50cmFuY2VcbiAgICAgKi9cbiAgICBhc3luYyBfZmFkZV9pbihhbmltYXRlID0gZmFsc2UpIHtcbiAgICAgICAgaWYgKGFuaW1hdGUpIHtcbiAgICAgICAgICAgIC8vIEluaXRpYWwgc3RhdGU6IG1vZGFsIHBvc2l0aW9uZWQgYWJvdmUgZmluYWwgcG9zaXRpb25cbiAgICAgICAgICAgIHRoaXMuJC5jc3MoJ2Rpc3BsYXknLCAnZmxleCcpLmNzcygnb3BhY2l0eScsICcwJyk7XG4gICAgICAgICAgICB0aGlzLiRpZCgnbW9kYWwnKS5jc3Moe1xuICAgICAgICAgICAgICAgICd0cmFuc2Zvcm0nOiAndHJhbnNsYXRlKDAsIC01MHB4KScsXG4gICAgICAgICAgICAgICAgJ29wYWNpdHknOiAnMCdcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgdGhpcy4kaWQoJ2JhY2tkcm9wJykuY3NzKCdkaXNwbGF5JywgJ2Jsb2NrJykuYWRkQ2xhc3MoJ3Nob3cnKTtcblxuICAgICAgICAgICAgLy8gRm9yY2UgcmVmbG93XG4gICAgICAgICAgICB0aGlzLiRpZCgnbW9kYWwnKVswXS5vZmZzZXRIZWlnaHQ7XG5cbiAgICAgICAgICAgIC8vIFRyaWdnZXIgYW5pbWF0aW9uXG4gICAgICAgICAgICB0aGlzLiRpZCgnbW9kYWwnKS5hZGRDbGFzcygnc2hvdycpLmNzcyh7XG4gICAgICAgICAgICAgICAgJ3RyYW5zZm9ybSc6ICd0cmFuc2xhdGUoMCwgMCknLFxuICAgICAgICAgICAgICAgICdvcGFjaXR5JzogJzEnXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHRoaXMuJC5jc3MoJ29wYWNpdHknLCAnMScpO1xuXG4gICAgICAgICAgICAvLyBXYWl0IGZvciBhbmltYXRpb24gdG8gY29tcGxldGVcbiAgICAgICAgICAgIGF3YWl0IG5ldyBQcm9taXNlKHJlc29sdmUgPT4gc2V0VGltZW91dChyZXNvbHZlLCAxNTApKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIERpc2FibGUgdHJhbnNpdGlvbnMgdGVtcG9yYXJpbHkgZm9yIGluc3RhbnQgZGlzcGxheVxuICAgICAgICAgICAgdGhpcy4kaWQoJ2RpYWxvZycpLmNzcygndHJhbnNpdGlvbicsICdub25lJyk7XG5cbiAgICAgICAgICAgIC8vIFNob3cgbW9kYWwgYW5kIGJhY2tkcm9wIGluc3RhbnRseVxuICAgICAgICAgICAgdGhpcy4kLmNzcygnZGlzcGxheScsICdmbGV4JykuY3NzKCdvcGFjaXR5JywgJzEnKTtcbiAgICAgICAgICAgIHRoaXMuJGlkKCdtb2RhbCcpLmFkZENsYXNzKCdzaG93JykuY3NzKCdvcGFjaXR5JywgJzEnKTtcbiAgICAgICAgICAgIHRoaXMuJGlkKCdiYWNrZHJvcCcpLmNzcygnZGlzcGxheScsICdibG9jaycpLmFkZENsYXNzKCdzaG93Jyk7XG5cbiAgICAgICAgICAgIC8vIEZvcmNlIHJlZmxvdyB0byBhcHBseSB0aGUgbm8tdHJhbnNpdGlvbiBzdGF0ZVxuICAgICAgICAgICAgdGhpcy4kaWQoJ2RpYWxvZycpWzBdLm9mZnNldEhlaWdodDtcblxuICAgICAgICAgICAgLy8gUmUtZW5hYmxlIHRyYW5zaXRpb25zIGZvciBmdXR1cmUgYW5pbWF0aW9uc1xuICAgICAgICAgICAgdGhpcy4kaWQoJ2RpYWxvZycpLmNzcygndHJhbnNpdGlvbicsICcnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBGb2N1cyB0aGUgZmlyc3QgaW5wdXQgZWxlbWVudCBpbiB0aGUgbW9kYWxcbiAgICAgKi9cbiAgICBfZm9jdXNfZmlyc3RfaW5wdXQoKSB7XG4gICAgICAgIC8vIEZpbmQgZmlyc3QgaW5wdXQvdGV4dGFyZWEvc2VsZWN0IGluIG1vZGFsIGJvZHlcbiAgICAgICAgY29uc3QgJGZpcnN0X2lucHV0ID0gdGhpcy4kaWQoJ2JvZHknKS5maW5kKCdpbnB1dDpub3QoW3R5cGU9XCJoaWRkZW5cIl0pLCB0ZXh0YXJlYSwgc2VsZWN0JykuZmlyc3QoKTtcbiAgICAgICAgaWYgKCRmaXJzdF9pbnB1dC5leGlzdHMoKSkge1xuICAgICAgICAgICAgcmVxdWVzdEFuaW1hdGlvbkZyYW1lKCgpID0+IHtcbiAgICAgICAgICAgICAgICAkZmlyc3RfaW5wdXQuZm9jdXMoKTtcbiAgICAgICAgICAgICAgICAvLyBTZWxlY3QgdGV4dCBpZiBpdCdzIGFuIGlucHV0IHdpdGggZXhpc3RpbmcgdmFsdWVcbiAgICAgICAgICAgICAgICBpZiAoJGZpcnN0X2lucHV0LmlzKCdpbnB1dFt0eXBlPVwidGV4dFwiXSwgaW5wdXRbdHlwZT1cImVtYWlsXCJdJykgJiYgJGZpcnN0X2lucHV0LnZhbCgpKSB7XG4gICAgICAgICAgICAgICAgICAgICRmaXJzdF9pbnB1dC5zZWxlY3QoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENsb3NlIHRoZSBtb2RhbCBpbnN0YW50bHlcbiAgICAgKi9cbiAgICBhc3luYyBjbG9zZShyZXN1bHQpIHtcbiAgICAgICAgY29uc3QgdGhhdCA9IHRoaXM7XG5cbiAgICAgICAgLy8gTWFyayBhcyBub3QgdmlzaWJsZVxuICAgICAgICB0aGlzLmRhdGEuaXNfdmlzaWJsZSA9IGZhbHNlO1xuXG4gICAgICAgIC8vIFJlbW92ZSBldmVudCBsaXN0ZW5lcnNcbiAgICAgICAgJChkb2N1bWVudCkub2ZmKCdrZXlkb3duLnJzeF9tb2RhbF8nICsgdGhpcy5fY2lkKTtcbiAgICAgICAgJCh3aW5kb3cpLm9mZigncmVzaXplLnJzeF9tb2RhbF8nICsgdGhpcy5fY2lkKTtcblxuICAgICAgICAvLyBIaWRlIGluc3RhbnRseSAobm8gZmFkZSBvdXQpXG4gICAgICAgIHRoaXMuJC5oaWRlKCk7XG4gICAgICAgIHRoaXMuJGlkKCdiYWNrZHJvcCcpLmhpZGUoKTtcblxuICAgICAgICAvLyBSZW1vdmUgZnJvbSBET01cbiAgICAgICAgdGhpcy4kLnJlbW92ZSgpO1xuICAgICAgICB0aGlzLiRpZCgnYmFja2Ryb3AnKS5yZW1vdmUoKTtcblxuICAgICAgICAvLyBSZXNvbHZlIHByb21pc2VcbiAgICAgICAgaWYgKHRoaXMuZGF0YS5yZXNvbHZlX2ZuKSB7XG4gICAgICAgICAgICB0aGlzLmRhdGEucmVzb2x2ZV9mbihyZXN1bHQpO1xuICAgICAgICAgICAgdGhpcy5kYXRhLnJlc29sdmVfZm4gPSBudWxsO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQXBwbHkgdmFsaWRhdGlvbiBlcnJvcnMgdG8gZm9ybSBmaWVsZHMgaW4gbW9kYWwgYm9keVxuICAgICAqL1xuICAgIGFwcGx5X2Vycm9ycyhlcnJvcnMpIHtcbiAgICAgICAgLy8gVXNlIEZvcm1fVXRpbHMgdG8gYXBwbHkgZXJyb3JzIHRvIGVsZW1lbnRzIHdpdGhpbiBtb2RhbCBib2R5XG4gICAgICAgIEZvcm1fVXRpbHMuYXBwbHlfZm9ybV9lcnJvcnModGhpcy4kaWQoJ2JvZHknKSwgZXJyb3JzKTtcbiAgICB9XG59XG4iLCIvKipcbiAqIE1vZGFsIFN0YXRpYyBBUElcbiAqXG4gKiBQcmltYXJ5IGludGVyZmFjZSBmb3IgZGlzcGxheWluZyBtb2RhbHMgdGhyb3VnaG91dCB0aGUgYXBwbGljYXRpb24uXG4gKiBQcm92aWRlcyBzaW1wbGUgbWV0aG9kcyBmb3IgY29tbW9uIGRpYWxvZ3MgYW5kIGZsZXhpYmxlIG9wdGlvbnMgZm9yIGN1c3RvbSBtb2RhbHMuXG4gKlxuICogVXNhZ2U6XG4gKiAgIGF3YWl0IE1vZGFsLmFsZXJ0KFwiRmlsZSBzYXZlZFwiKVxuICogICBpZiAoYXdhaXQgTW9kYWwuY29uZmlybShcIkRlbGV0ZT9cIikpIHsgLi4uIH1cbiAqICAgbGV0IG5hbWUgPSBhd2FpdCBNb2RhbC5wcm9tcHQoXCJFbnRlciBuYW1lOlwiKVxuICogICBsZXQgcmVzdWx0ID0gYXdhaXQgTW9kYWwuc2hvdyh7IHRpdGxlLCBib2R5LCBidXR0b25zIH0pXG4gKi9cbmNsYXNzIE1vZGFsIHtcbiAgICAvLyBJbnRlcm5hbCBzdGF0ZVxuICAgIHN0YXRpYyBfcXVldWUgPSBbXTtcbiAgICBzdGF0aWMgX2N1cnJlbnQgPSBudWxsO1xuICAgIHN0YXRpYyBfaW5pdGlhbGl6ZWQgPSBmYWxzZTtcbiAgICBzdGF0aWMgX2JhY2tkcm9wID0gbnVsbDtcbiAgICBzdGF0aWMgX29yaWdpbmFsX2JvZHlfb3ZlcmZsb3cgPSBudWxsO1xuICAgIHN0YXRpYyBfb3JpZ2luYWxfYm9keV9wYWRkaW5nID0gbnVsbDtcbiAgICBzdGF0aWMgX3VubG9ja190aW1lb3V0ID0gbnVsbDtcbiAgICBzdGF0aWMgX2xhc3RfY2xvc2VfdGltZXN0YW1wID0gMDtcblxuICAgIC8qKlxuICAgICAqIEluaXRpYWxpemUgZ2xvYmFsIGhhbmRsZXJzIChjYWxsZWQgYXV0b21hdGljYWxseSBvbiBmaXJzdCBtb2RhbClcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuICAgIHN0YXRpYyBfaW5pdCgpIHtcbiAgICAgICAgaWYgKHRoaXMuX2luaXRpYWxpemVkKSByZXR1cm47XG4gICAgICAgIHRoaXMuX2luaXRpYWxpemVkID0gdHJ1ZTtcblxuICAgICAgICAvLyBDcmVhdGUgc2hhcmVkIGJhY2tkcm9wIGVsZW1lbnRcbiAgICAgICAgdGhpcy5fYmFja2Ryb3AgPSAkKCc8ZGl2IGNsYXNzPVwibW9kYWwtYmFja2Ryb3AgZmFkZVwiPjwvZGl2PicpO1xuICAgICAgICAkKCdib2R5JykuYXBwZW5kKHRoaXMuX2JhY2tkcm9wKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDYWxjdWxhdGUgc2Nyb2xsYmFyIHdpZHRoXG4gICAgICogQHByaXZhdGVcbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfVxuICAgICAqL1xuICAgIHN0YXRpYyBfZ2V0X3Njcm9sbGJhcl93aWR0aCgpIHtcbiAgICAgICAgLy8gQ3JlYXRlIHRlbXBvcmFyeSBlbGVtZW50IHRvIG1lYXN1cmUgc2Nyb2xsYmFyIHdpZHRoXG4gICAgICAgIGNvbnN0ICRvdXRlciA9ICQoJzxkaXY+JykuY3NzKHtcbiAgICAgICAgICAgIHZpc2liaWxpdHk6ICdoaWRkZW4nLFxuICAgICAgICAgICAgb3ZlcmZsb3c6ICdzY3JvbGwnLFxuICAgICAgICAgICAgd2lkdGg6ICcxMDBweCcsXG4gICAgICAgICAgICBwb3NpdGlvbjogJ2Fic29sdXRlJyxcbiAgICAgICAgICAgIHRvcDogJy05OTk5cHgnLFxuICAgICAgICB9KTtcbiAgICAgICAgJCgnYm9keScpLmFwcGVuZCgkb3V0ZXIpO1xuXG4gICAgICAgIGNvbnN0IHdpZHRoX3dpdGhfc2Nyb2xsYmFyID0gJG91dGVyWzBdLm9mZnNldFdpZHRoO1xuXG4gICAgICAgIGNvbnN0ICRpbm5lciA9ICQoJzxkaXY+JykuY3NzKCd3aWR0aCcsICcxMDAlJyk7XG4gICAgICAgICRvdXRlci5hcHBlbmQoJGlubmVyKTtcblxuICAgICAgICBjb25zdCB3aWR0aF93aXRob3V0X3Njcm9sbGJhciA9ICRpbm5lclswXS5vZmZzZXRXaWR0aDtcblxuICAgICAgICAkb3V0ZXIucmVtb3ZlKCk7XG5cbiAgICAgICAgcmV0dXJuIHdpZHRoX3dpdGhfc2Nyb2xsYmFyIC0gd2lkdGhfd2l0aG91dF9zY3JvbGxiYXI7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogTG9jayBib2R5IHNjcm9sbCBhbmQgY29tcGVuc2F0ZSBmb3Igc2Nyb2xsYmFyIHdpZHRoXG4gICAgICogT25seSBsb2NrcyBpZiB3ZSBoYXZlbid0IGFscmVhZHkgc2F2ZWQgdGhlIG9yaWdpbmFsIHN0YXRlIChmaXJzdCBtb2RhbCBpbiBjaGFpbilcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuICAgIHN0YXRpYyBfbG9ja19ib2R5X3Njcm9sbCgpIHtcbiAgICAgICAgLy8gQ2FuY2VsIGFueSBwZW5kaW5nIHVubG9jayB0aW1lb3V0XG4gICAgICAgIGlmICh0aGlzLl91bmxvY2tfdGltZW91dCkge1xuICAgICAgICAgICAgY2xlYXJUaW1lb3V0KHRoaXMuX3VubG9ja190aW1lb3V0KTtcbiAgICAgICAgICAgIHRoaXMuX3VubG9ja190aW1lb3V0ID0gbnVsbDtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIE9ubHkgbG9jayBzY3JvbGwgaWYgd2UgaGF2ZW4ndCBhbHJlYWR5IHNhdmVkIHN0YXRlIChmaXJzdCBtb2RhbClcbiAgICAgICAgLy8gVGhpcyBpcyB0aGUgdHJ1ZSBpbmRpY2F0b3IgLSBub3QgYmFja2Ryb3AgdmlzaWJpbGl0eSB3aGljaCBjYW4gYmUgdHJhbnNpdGlvbmFsXG4gICAgICAgIGlmICh0aGlzLl9vcmlnaW5hbF9ib2R5X292ZXJmbG93ID09PSBudWxsKSB7XG4gICAgICAgICAgICBjb25zdCAkYm9keSA9ICQoJ2JvZHknKTtcblxuICAgICAgICAgICAgLy8gU3RvcmUgb3JpZ2luYWwgdmFsdWVzXG4gICAgICAgICAgICB0aGlzLl9vcmlnaW5hbF9ib2R5X292ZXJmbG93ID0gJGJvZHkuY3NzKCdvdmVyZmxvdycpO1xuICAgICAgICAgICAgdGhpcy5fb3JpZ2luYWxfYm9keV9wYWRkaW5nID0gJGJvZHkuY3NzKCdwYWRkaW5nLXJpZ2h0Jyk7XG5cbiAgICAgICAgICAgIC8vIENoZWNrIGlmIGJvZHkgY3VycmVudGx5IGhhcyB2ZXJ0aWNhbCBzY3JvbGxcbiAgICAgICAgICAgIGNvbnN0IGhhc19zY3JvbGxiYXIgPSBkb2N1bWVudC5ib2R5LnNjcm9sbEhlaWdodCA+IHdpbmRvdy5pbm5lckhlaWdodDtcblxuICAgICAgICAgICAgLy8gSWYgdGhlcmUncyBhIHNjcm9sbGJhciwgYWRkIHBhZGRpbmcgdG8gY29tcGVuc2F0ZSBmb3IgaXRzIHJlbW92YWxcbiAgICAgICAgICAgIGlmIChoYXNfc2Nyb2xsYmFyKSB7XG4gICAgICAgICAgICAgICAgY29uc3Qgc2Nyb2xsYmFyX3dpZHRoID0gdGhpcy5fZ2V0X3Njcm9sbGJhcl93aWR0aCgpO1xuICAgICAgICAgICAgICAgIGNvbnN0IGN1cnJlbnRfcGFkZGluZyA9IGludCh0aGlzLl9vcmlnaW5hbF9ib2R5X3BhZGRpbmcpIHx8IDA7XG4gICAgICAgICAgICAgICAgJGJvZHkuY3NzKCdwYWRkaW5nLXJpZ2h0JywgY3VycmVudF9wYWRkaW5nICsgc2Nyb2xsYmFyX3dpZHRoICsgJ3B4Jyk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIExvY2sgc2Nyb2xsXG4gICAgICAgICAgICAkYm9keS5jc3MoJ292ZXJmbG93JywgJ2hpZGRlbicpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVW5sb2NrIGJvZHkgc2Nyb2xsIGFuZCByZXN0b3JlIG9yaWdpbmFsIHN0YXRlXG4gICAgICogVXNlcyBkZWxheWVkIGNoZWNrIHRvIGVuc3VyZSBubyBvdGhlciBtb2RhbHMgYXJlIG9wZW5pbmdcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuICAgIHN0YXRpYyBfdW5sb2NrX2JvZHlfc2Nyb2xsKCkge1xuICAgICAgICAvLyBDbGVhciBhbnkgZXhpc3RpbmcgdGltZW91dFxuICAgICAgICBpZiAodGhpcy5fdW5sb2NrX3RpbWVvdXQpIHtcbiAgICAgICAgICAgIGNsZWFyVGltZW91dCh0aGlzLl91bmxvY2tfdGltZW91dCk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBNaW5pbWFsIGRlbGF5IGJlZm9yZSB1bmxvY2tpbmdcbiAgICAgICAgdGhpcy5fdW5sb2NrX3RpbWVvdXQgPSBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgIC8vIERvdWJsZS1jaGVjayBubyBtb2RhbCBpcyBjdXJyZW50bHkgb3BlbiBhbmQgcXVldWUgaXMgZW1wdHlcbiAgICAgICAgICAgIGlmICghdGhpcy5fY3VycmVudCAmJiB0aGlzLl9xdWV1ZS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgICAgICBjb25zdCAkYm9keSA9ICQoJ2JvZHknKTtcblxuICAgICAgICAgICAgICAgIC8vIFJlc3RvcmUgb3JpZ2luYWwgdmFsdWVzXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuX29yaWdpbmFsX2JvZHlfb3ZlcmZsb3cgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgJGJvZHkuY3NzKCdvdmVyZmxvdycsIHRoaXMuX29yaWdpbmFsX2JvZHlfb3ZlcmZsb3cpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9vcmlnaW5hbF9ib2R5X292ZXJmbG93ID0gbnVsbDtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBpZiAodGhpcy5fb3JpZ2luYWxfYm9keV9wYWRkaW5nICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgICRib2R5LmNzcygncGFkZGluZy1yaWdodCcsIHRoaXMuX29yaWdpbmFsX2JvZHlfcGFkZGluZyk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX29yaWdpbmFsX2JvZHlfcGFkZGluZyA9IG51bGw7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0aGlzLl91bmxvY2tfdGltZW91dCA9IG51bGw7XG4gICAgICAgIH0sIDUwKTsgLy8gTWluaW1hbCBzYWZldHkgYnVmZmVyXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2hvdyB0aGUgc2hhcmVkIGJhY2tkcm9wIChpbnN0YW50IC0gbm8gYW5pbWF0aW9uKVxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG4gICAgc3RhdGljIGFzeW5jIF9zaG93X2JhY2tkcm9wKCkge1xuICAgICAgICBpZiAoIXRoaXMuX2JhY2tkcm9wLmhhc0NsYXNzKCdzaG93JykpIHtcbiAgICAgICAgICAgIC8vIExvY2sgYm9keSBzY3JvbGwgYmVmb3JlIHNob3dpbmcgYmFja2Ryb3BcbiAgICAgICAgICAgIHRoaXMuX2xvY2tfYm9keV9zY3JvbGwoKTtcblxuICAgICAgICAgICAgdGhpcy5fYmFja2Ryb3AuY3NzKCdkaXNwbGF5JywgJ2Jsb2NrJykuYWRkQ2xhc3MoJ3Nob3cnKTtcbiAgICAgICAgICAgIC8vIE5vIGRlbGF5IC0gcmV0dXJuIGltbWVkaWF0ZWx5XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBIaWRlIHRoZSBzaGFyZWQgYmFja2Ryb3AgKGluc3RhbnQgLSBubyBhbmltYXRpb24pXG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cbiAgICBzdGF0aWMgYXN5bmMgX2hpZGVfYmFja2Ryb3AoKSB7XG4gICAgICAgIHRoaXMuX2JhY2tkcm9wLnJlbW92ZUNsYXNzKCdzaG93JykuY3NzKCdkaXNwbGF5JywgJ25vbmUnKTtcblxuICAgICAgICAvLyBVbmxvY2sgYm9keSBzY3JvbGwgYWZ0ZXIgYmFja2Ryb3AgaXMgaGlkZGVuXG4gICAgICAgIHRoaXMuX3VubG9ja19ib2R5X3Njcm9sbCgpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZSBhIG5ldyBSc3hfTW9kYWwgaW5zdGFuY2VcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuICAgIHN0YXRpYyBhc3luYyBfY3JlYXRlX21vZGFsKCkge1xuICAgICAgICAvLyBDcmVhdGUgbW9kYWwgY29tcG9uZW50IHVzaW5nIGpRdWVyeSBwbHVnaW5cbiAgICAgICAgY29uc3QgJG1vZGFsX2VsZW1lbnQgPSAkKCc8ZGl2PicpO1xuXG4gICAgICAgIC8vIENyZWF0ZSBjb21wb25lbnQgaW5zdGFuY2UgZGlyZWN0bHkgKHJldHVybnMgdGhlIGNvbXBvbmVudClcbiAgICAgICAgY29uc3QgbW9kYWxfaW5zdGFuY2UgPSAkbW9kYWxfZWxlbWVudC5jb21wb25lbnQoJ1JzeF9Nb2RhbCcsIHt9KTtcblxuICAgICAgICAvLyBXYWl0IGZvciBjb21wb25lbnQgdG8gYmUgZnVsbHkgcmVhZHkgKERPTSBlbGVtZW50cyBxdWVyeWFibGUpXG4gICAgICAgIGF3YWl0IG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PiB7XG4gICAgICAgICAgICBtb2RhbF9pbnN0YW5jZS5vbigncmVhZHknLCAoKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5sb2coJ1tNb2RhbF0gQ29tcG9uZW50IHJlYWR5LCBlbGVtZW50czonLCB7XG4gICAgICAgICAgICAgICAgICAgIHRpdGxlOiBtb2RhbF9pbnN0YW5jZS4kaWQoJ3RpdGxlJykubGVuZ3RoLFxuICAgICAgICAgICAgICAgICAgICBib2R5OiBtb2RhbF9pbnN0YW5jZS4kaWQoJ2JvZHknKS5sZW5ndGgsXG4gICAgICAgICAgICAgICAgICAgIGZvb3RlcjogbW9kYWxfaW5zdGFuY2UuJGlkKCdmb290ZXInKS5sZW5ndGgsXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHJldHVybiBtb2RhbF9pbnN0YW5jZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTaG93IGEgbW9kYWwgYW5kIG1hbmFnZSBxdWV1ZVxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG4gICAgc3RhdGljIGFzeW5jIF9zaG93X21vZGFsKG9wdGlvbnMpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PiB7XG4gICAgICAgICAgICB0aGlzLl9xdWV1ZS5wdXNoKHsgb3B0aW9ucywgcmVzb2x2ZSB9KTtcblxuICAgICAgICAgICAgLy8gUHJvY2VzcyBxdWV1ZSBpZiBubyBtb2RhbCBjdXJyZW50bHkgc2hvd2luZ1xuICAgICAgICAgICAgaWYgKCF0aGlzLl9jdXJyZW50KSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fcHJvY2Vzc19xdWV1ZSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBQcm9jZXNzIHRoZSBtb2RhbCBxdWV1ZVxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG4gICAgc3RhdGljIGFzeW5jIF9wcm9jZXNzX3F1ZXVlKCkge1xuICAgICAgICBpZiAodGhpcy5fcXVldWUubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICB0aGlzLl9jdXJyZW50ID0gbnVsbDtcbiAgICAgICAgICAgIC8vIEhpZGUgYmFja2Ryb3Agd2hlbiBxdWV1ZSBpcyBlbXB0eVxuICAgICAgICAgICAgYXdhaXQgdGhpcy5faGlkZV9iYWNrZHJvcCgpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgeyBvcHRpb25zLCByZXNvbHZlIH0gPSB0aGlzLl9xdWV1ZS5zaGlmdCgpO1xuXG4gICAgICAgIC8vIEVuc3VyZSBpbml0aWFsaXplZFxuICAgICAgICB0aGlzLl9pbml0KCk7XG5cbiAgICAgICAgLy8gU2hvdyBiYWNrZHJvcCBpZiBub3QgYWxyZWFkeSB2aXNpYmxlIChpbnN0YW50IC0gbm8gZGVsYXkgYmV0d2VlbiBtb2RhbHMpXG4gICAgICAgIGNvbnN0IGJhY2tkcm9wX3Zpc2libGUgPSB0aGlzLl9iYWNrZHJvcC5oYXNDbGFzcygnc2hvdycpO1xuICAgICAgICBpZiAoIWJhY2tkcm9wX3Zpc2libGUpIHtcbiAgICAgICAgICAgIGF3YWl0IHRoaXMuX3Nob3dfYmFja2Ryb3AoKTtcbiAgICAgICAgfVxuICAgICAgICAvLyBObyBkZWxheSBiZXR3ZWVuIHNlcXVlbnRpYWwgbW9kYWxzIC0gaW1tZWRpYXRlIHRyYW5zaXRpb25cblxuICAgICAgICAvLyBDcmVhdGUgbW9kYWwgaW5zdGFuY2VcbiAgICAgICAgY29uc3QgbW9kYWxfaW5zdGFuY2UgPSBhd2FpdCB0aGlzLl9jcmVhdGVfbW9kYWwoKTtcbiAgICAgICAgdGhpcy5fY3VycmVudCA9IG1vZGFsX2luc3RhbmNlO1xuXG4gICAgICAgIC8vIERldGVybWluZSBpZiB3ZSBzaG91bGQgYW5pbWF0ZSBiYXNlZCBvbjpcbiAgICAgICAgLy8gMS4gRGVza3RvcCB2aWV3cG9ydCAoPj0gMTAwMHB4KVxuICAgICAgICAvLyAyLiBNb3JlIHRoYW4gMSBzZWNvbmQgc2luY2UgbGFzdCBtb2RhbCBjbG9zZWRcbiAgICAgICAgY29uc3Qgdmlld3BvcnRfd2lkdGggPSAkKHdpbmRvdykud2lkdGgoKTtcbiAgICAgICAgY29uc3QgaXNfZGVza3RvcCA9IHZpZXdwb3J0X3dpZHRoID49IDEwMDA7XG4gICAgICAgIGNvbnN0IHRpbWVfc2luY2VfbGFzdF9jbG9zZSA9IERhdGUubm93KCkgLSB0aGlzLl9sYXN0X2Nsb3NlX3RpbWVzdGFtcDtcbiAgICAgICAgY29uc3Qgc2hvdWxkX2FuaW1hdGUgPSBpc19kZXNrdG9wICYmIHRpbWVfc2luY2VfbGFzdF9jbG9zZSA+IDEwMDA7XG5cbiAgICAgICAgLy8gU2hvdyBtb2RhbCBhbmQgd2FpdCBmb3IgcmVzdWx0IChtb2RhbCB3b24ndCBjcmVhdGUgaXRzIG93biBiYWNrZHJvcClcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgbW9kYWxfaW5zdGFuY2Uuc2hvdyhvcHRpb25zLCB7IHNraXBfYmFja2Ryb3A6IHRydWUsIGFuaW1hdGU6IHNob3VsZF9hbmltYXRlIH0pO1xuXG4gICAgICAgIC8vIFJlY29yZCBjbG9zZSB0aW1lc3RhbXAgQkVGT1JFIHJlc29sdmluZyAoZW5zdXJlcyBpdCdzIHNldCBiZWZvcmUgbmV4dCBtb2RhbCBjYW4gc3RhcnQpXG4gICAgICAgIHRoaXMuX2xhc3RfY2xvc2VfdGltZXN0YW1wID0gRGF0ZS5ub3coKTtcblxuICAgICAgICAvLyBSZXNvbHZlIHRoZSBwcm9taXNlIHdpdGggdGhlIHJlc3VsdFxuICAgICAgICByZXNvbHZlKHJlc3VsdCk7XG5cbiAgICAgICAgLy8gQ2xlYXIgY3VycmVudCBhbmQgcHJvY2VzcyBuZXh0XG4gICAgICAgIHRoaXMuX2N1cnJlbnQgPSBudWxsO1xuICAgICAgICB0aGlzLl9wcm9jZXNzX3F1ZXVlKCk7XG4gICAgfVxuXG4gICAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAgICAvLyBTdGF0ZSBNYW5hZ2VtZW50IE1ldGhvZHNcbiAgICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuXG4gICAgLyoqXG4gICAgICogQ2hlY2sgaWYgYSBtb2RhbCBpcyBjdXJyZW50bHkgb3BlblxuICAgICAqIEByZXR1cm5zIHtib29sZWFufVxuICAgICAqL1xuICAgIHN0YXRpYyBpc19vcGVuKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fY3VycmVudCAhPT0gbnVsbDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIGN1cnJlbnRseSBvcGVuIG1vZGFsIGluc3RhbmNlXG4gICAgICogQHJldHVybnMge1JzeF9Nb2RhbHxudWxsfVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXRfY3VycmVudCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2N1cnJlbnQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRm9yY2UgY2xvc2UgdGhlIGN1cnJlbnQgbW9kYWxcbiAgICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn1cbiAgICAgKi9cbiAgICBzdGF0aWMgYXN5bmMgY2xvc2UoKSB7XG4gICAgICAgIGlmICh0aGlzLl9jdXJyZW50KSB7XG4gICAgICAgICAgICBhd2FpdCB0aGlzLl9jdXJyZW50LmNsb3NlKGZhbHNlKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEFwcGx5IHZhbGlkYXRpb24gZXJyb3JzIHRvIHRoZSBjdXJyZW50IG1vZGFsXG4gICAgICogQHBhcmFtIHtPYmplY3R9IGVycm9ycyAtIEVycm9yIG9iamVjdCB7ZmllbGQ6IG1lc3NhZ2V9XG4gICAgICovXG4gICAgc3RhdGljIGFwcGx5X2Vycm9ycyhlcnJvcnMpIHtcbiAgICAgICAgaWYgKHRoaXMuX2N1cnJlbnQpIHtcbiAgICAgICAgICAgIHRoaXMuX2N1cnJlbnQuYXBwbHlfZXJyb3JzKGVycm9ycyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICAgIC8vIFNpbXBsZSBEaWFsb2cgTWV0aG9kc1xuICAgIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbiAgICAvKipcbiAgICAgKiBTaG93IGFuIGFsZXJ0IGRpYWxvZ1xuICAgICAqIEBwYXJhbSB7c3RyaW5nfGpRdWVyeX0gdGl0bGVfb3JfYm9keSAtIE1lc3NhZ2UgKGlmIG9ubHkgMSBhcmcpIG9yIFRpdGxlIChpZiAyIGFyZ3MpLiBDYW4gYmUgc3RyaW5nIG9yIGpRdWVyeSBlbGVtZW50LlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfGpRdWVyeX0gYm9keSAtIE1lc3NhZ2UgYm9keSAoaWYgMiBhcmdzKS4gQ2FuIGJlIHN0cmluZyBvciBqUXVlcnkgZWxlbWVudC5cbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gYnV0dG9uX2xhYmVsIC0gQnV0dG9uIHRleHQgKGRlZmF1bHQ6IFwiT0tcIilcbiAgICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn1cbiAgICAgKi9cbiAgICBzdGF0aWMgYXN5bmMgYWxlcnQodGl0bGVfb3JfYm9keSwgYm9keSA9IG51bGwsIGJ1dHRvbl9sYWJlbCA9ICdPSycpIHtcbiAgICAgICAgbGV0IHRpdGxlID0gJ05vdGljZSc7XG4gICAgICAgIGxldCBtZXNzYWdlID0gdGl0bGVfb3JfYm9keTtcblxuICAgICAgICBpZiAoYm9keSAhPT0gbnVsbCkge1xuICAgICAgICAgICAgdGl0bGUgPSB0aXRsZV9vcl9ib2R5O1xuICAgICAgICAgICAgbWVzc2FnZSA9IGJvZHk7XG4gICAgICAgIH1cblxuICAgICAgICBhd2FpdCB0aGlzLl9zaG93X21vZGFsKHtcbiAgICAgICAgICAgIHRpdGxlOiB0aXRsZSxcbiAgICAgICAgICAgIGJvZHk6IG1lc3NhZ2UsXG4gICAgICAgICAgICBidXR0b25zOiBbXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBsYWJlbDogYnV0dG9uX2xhYmVsLFxuICAgICAgICAgICAgICAgICAgICB2YWx1ZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgY2xhc3M6ICdidG4tcHJpbWFyeScsXG4gICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6IHRydWUsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgICBjbG9zYWJsZTogdHJ1ZSxcbiAgICAgICAgICAgIGNsb3NlX29uX3N1Ym1pdDogdHJ1ZSxcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2hvdyBhIGNvbmZpcm1hdGlvbiBkaWFsb2dcbiAgICAgKiBAcGFyYW0ge3N0cmluZ3xqUXVlcnl9IHRpdGxlX29yX2JvZHkgLSBNZXNzYWdlIChpZiAxLTIgYXJncykgb3IgVGl0bGUgKGlmIDMtNCBhcmdzKS4gQ2FuIGJlIHN0cmluZyBvciBqUXVlcnkgZWxlbWVudC5cbiAgICAgKiBAcGFyYW0ge3N0cmluZ3xqUXVlcnl9IGJvZHkgLSBNZXNzYWdlIGJvZHkgKG9wdGlvbmFsKS4gQ2FuIGJlIHN0cmluZyBvciBqUXVlcnkgZWxlbWVudC5cbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gY29uZmlybV9sYWJlbCAtIENvbmZpcm0gYnV0dG9uIHRleHQgKGRlZmF1bHQ6IFwiQ29uZmlybVwiKVxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBjYW5jZWxfbGFiZWwgLSBDYW5jZWwgYnV0dG9uIHRleHQgKGRlZmF1bHQ6IFwiQ2FuY2VsXCIpXG4gICAgICogQHJldHVybnMge1Byb21pc2U8Ym9vbGVhbj59XG4gICAgICovXG4gICAgc3RhdGljIGFzeW5jIGNvbmZpcm0odGl0bGVfb3JfYm9keSwgYm9keSA9IG51bGwsIGNvbmZpcm1fbGFiZWwgPSAnQ29uZmlybScsIGNhbmNlbF9sYWJlbCA9ICdDYW5jZWwnKSB7XG4gICAgICAgIGxldCB0aXRsZSA9ICdDb25maXJtJztcbiAgICAgICAgbGV0IG1lc3NhZ2UgPSB0aXRsZV9vcl9ib2R5O1xuXG4gICAgICAgIGlmIChib2R5ICE9PSBudWxsKSB7XG4gICAgICAgICAgICB0aXRsZSA9IHRpdGxlX29yX2JvZHk7XG4gICAgICAgICAgICBtZXNzYWdlID0gYm9keTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHRoaXMuX3Nob3dfbW9kYWwoe1xuICAgICAgICAgICAgdGl0bGU6IHRpdGxlLFxuICAgICAgICAgICAgYm9keTogbWVzc2FnZSxcbiAgICAgICAgICAgIGJ1dHRvbnM6IFtcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGxhYmVsOiBjYW5jZWxfbGFiZWwsXG4gICAgICAgICAgICAgICAgICAgIHZhbHVlOiBmYWxzZSxcbiAgICAgICAgICAgICAgICAgICAgY2xhc3M6ICdidG4tc2Vjb25kYXJ5JyxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgbGFiZWw6IGNvbmZpcm1fbGFiZWwsXG4gICAgICAgICAgICAgICAgICAgIHZhbHVlOiB0cnVlLFxuICAgICAgICAgICAgICAgICAgICBjbGFzczogJ2J0bi1wcmltYXJ5JyxcbiAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDogdHJ1ZSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICAgIGNsb3NhYmxlOiB0cnVlLFxuICAgICAgICAgICAgY2xvc2Vfb25fc3VibWl0OiB0cnVlLFxuICAgICAgICB9KTtcblxuICAgICAgICByZXR1cm4gcmVzdWx0ID09PSB0cnVlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNob3cgYSBwcm9tcHQgZGlhbG9nIGZvciB0ZXh0IGlucHV0XG4gICAgICogQHBhcmFtIHtzdHJpbmd8alF1ZXJ5fSB0aXRsZV9vcl9ib2R5IC0gTWVzc2FnZSAoaWYgMS0zIGFyZ3MpIG9yIFRpdGxlIChpZiA0IGFyZ3MpLiBDYW4gYmUgc3RyaW5nIG9yIGpRdWVyeSBlbGVtZW50LlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfGpRdWVyeX0gYm9keSAtIE1lc3NhZ2UgYm9keSAob3B0aW9uYWwpLiBDYW4gYmUgc3RyaW5nIG9yIGpRdWVyeSBlbGVtZW50LlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBkZWZhdWx0X3ZhbHVlIC0gRGVmYXVsdCBpbnB1dCB2YWx1ZVxuICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gbXVsdGlsaW5lIC0gU2hvdyB0ZXh0YXJlYSBpbnN0ZWFkIG9mIGlucHV0XG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGVycm9yIC0gT3B0aW9uYWwgZXJyb3IgbWVzc2FnZSB0byBkaXNwbGF5IGFzIHZhbGlkYXRpb24gZmVlZGJhY2tcbiAgICAgKiBAcmV0dXJucyB7UHJvbWlzZTxzdHJpbmd8ZmFsc2U+fVxuICAgICAqL1xuICAgIHN0YXRpYyBhc3luYyBwcm9tcHQodGl0bGVfb3JfYm9keSwgYm9keSA9IG51bGwsIGRlZmF1bHRfdmFsdWUgPSAnJywgbXVsdGlsaW5lID0gZmFsc2UsIGVycm9yID0gbnVsbCkge1xuICAgICAgICBsZXQgdGl0bGUgPSAnSW5wdXQnO1xuICAgICAgICBsZXQgbWVzc2FnZSA9IHRpdGxlX29yX2JvZHk7XG5cbiAgICAgICAgLy8gSGFuZGxlIG92ZXJsb2FkZWQgYXJndW1lbnRzXG4gICAgICAgIGlmICh0eXBlb2YgYm9keSA9PT0gJ3N0cmluZycgJiYgYm9keSAhPT0gJycpIHtcbiAgICAgICAgICAgIHRpdGxlID0gdGl0bGVfb3JfYm9keTtcbiAgICAgICAgICAgIG1lc3NhZ2UgPSBib2R5O1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gQ3JlYXRlIGlucHV0IGVsZW1lbnQgd2l0aCBtaW5pbXVtIHdpZHRoIGNvbnN0cmFpbnRzXG4gICAgICAgIGNvbnN0ICRpbnB1dCA9IG11bHRpbGluZVxuICAgICAgICAgICAgPyAkKCc8dGV4dGFyZWEgY2xhc3M9XCJmb3JtLWNvbnRyb2xcIiByb3dzPVwiNFwiIHN0eWxlPVwibWluLXdpZHRoOiAzMTVweDtcIj48L3RleHRhcmVhPicpXG4gICAgICAgICAgICA6ICQoJzxpbnB1dCB0eXBlPVwidGV4dFwiIGNsYXNzPVwiZm9ybS1jb250cm9sXCIgc3R5bGU9XCJtaW4td2lkdGg6IDI0NXB4O1wiPicpO1xuXG4gICAgICAgICRpbnB1dC52YWwoZGVmYXVsdF92YWx1ZSk7XG5cbiAgICAgICAgLy8gTWFyayBhcyBpbnZhbGlkIGlmIHRoZXJlJ3MgYW4gZXJyb3JcbiAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICAkaW5wdXQuYWRkQ2xhc3MoJ2lzLWludmFsaWQnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIENyZWF0ZSBib2R5IHdpdGggbWVzc2FnZSBhbmQgaW5wdXRcbiAgICAgICAgbGV0ICRib2R5O1xuICAgICAgICBpZiAobWVzc2FnZSBpbnN0YW5jZW9mIGpRdWVyeSkge1xuICAgICAgICAgICAgLy8gSWYgbWVzc2FnZSBpcyBhIGpRdWVyeSBlbGVtZW50LCB1c2UgaXQgYXMgdGhlIGNvbnRhaW5lciBhbmQgYXBwZW5kIGlucHV0XG4gICAgICAgICAgICAkYm9keSA9IG1lc3NhZ2UuYXBwZW5kKCRpbnB1dCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBJZiBtZXNzYWdlIGlzIGEgc3RyaW5nLCBjcmVhdGUgd3JhcHBlciB3aXRoIHRleHQgYW5kIGlucHV0ICgzNnB4IHNwYWNpbmcpXG4gICAgICAgICAgICAkYm9keSA9ICQoJzxkaXYgY2xhc3M9XCJmb3JtLWdyb3VwXCI+JykuYXBwZW5kKCQoJzxkaXYgc3R5bGU9XCJtYXJnaW4tYm90dG9tOiAzNnB4O1wiPicpLnRleHQobWVzc2FnZSkpLmFwcGVuZCgkaW5wdXQpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gQWRkIGVycm9yIG1lc3NhZ2UgaWYgcHJvdmlkZWRcbiAgICAgICAgaWYgKGVycm9yKSB7XG4gICAgICAgICAgICBjb25zdCAkZXJyb3IgPSAkKCc8ZGl2IGNsYXNzPVwiaW52YWxpZC1mZWVkYmFjayBkLWJsb2NrXCI+PC9kaXY+JykudGV4dChlcnJvcik7XG4gICAgICAgICAgICAkYm9keS5hcHBlbmQoJGVycm9yKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHRoaXMuX3Nob3dfbW9kYWwoe1xuICAgICAgICAgICAgdGl0bGU6IHRpdGxlLFxuICAgICAgICAgICAgYm9keTogJGJvZHksXG4gICAgICAgICAgICBidXR0b25zOiBbXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBsYWJlbDogJ0NhbmNlbCcsXG4gICAgICAgICAgICAgICAgICAgIHZhbHVlOiBmYWxzZSxcbiAgICAgICAgICAgICAgICAgICAgY2xhc3M6ICdidG4tc2Vjb25kYXJ5JyxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgbGFiZWw6ICdTdWJtaXQnLFxuICAgICAgICAgICAgICAgICAgICB2YWx1ZTogbnVsbCwgLy8gV2lsbCBiZSByZXBsYWNlZCBieSBjYWxsYmFja1xuICAgICAgICAgICAgICAgICAgICBjbGFzczogJ2J0bi1wcmltYXJ5JyxcbiAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgY2FsbGJhY2s6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAkaW5wdXQudmFsKCk7XG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgICBjbG9zYWJsZTogdHJ1ZSxcbiAgICAgICAgICAgIGNsb3NlX29uX3N1Ym1pdDogdHJ1ZSxcbiAgICAgICAgICAgIG1heF93aWR0aDogNTAwLFxuICAgICAgICB9KTtcblxuICAgICAgICAvLyBGb2N1cyBhbmQgc2VsZWN0IGlucHV0IGFmdGVyIG1vZGFsIHNob3dzXG4gICAgICAgIHJlcXVlc3RBbmltYXRpb25GcmFtZSgoKSA9PiB7XG4gICAgICAgICAgICAkaW5wdXQuZm9jdXMoKTtcbiAgICAgICAgICAgIGlmICghbXVsdGlsaW5lKSB7XG4gICAgICAgICAgICAgICAgJGlucHV0LnNlbGVjdCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNob3cgYW4gZXJyb3IgZGlhbG9nIHdpdGggcmVkIGFsZXJ0IHN0eWxpbmdcbiAgICAgKlxuICAgICAqIENhbiBhcHBlYXIgb3ZlciBvdGhlciBtb2RhbHMgdG8gc2hvdyBjcml0aWNhbCB1bmNhdWdodCBleGNlcHRpb25zLlxuICAgICAqIFVzZWQgcHJpbWFyaWx5IGZvciBBamF4IGVycm9ycyB0aGF0IHdlcmVuJ3QgY2F1Z2h0IGJ5IGFwcGxpY2F0aW9uIGNvZGUuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge3N0cmluZ3xFcnJvcnxPYmplY3R9IGVycm9yIC0gRXJyb3IgbWVzc2FnZSBzdHJpbmcsIEVycm9yIG9iamVjdCwgb3Igc3RydWN0dXJlZCBlcnJvclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSB0aXRsZSAtIE1vZGFsIHRpdGxlIChkZWZhdWx0OiBcIkVycm9yXCIpXG4gICAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59XG4gICAgICovXG4gICAgc3RhdGljIGFzeW5jIGVycm9yKGVycm9yLCB0aXRsZSA9ICdFcnJvcicpIHtcbiAgICAgICAgbGV0IG1lc3NhZ2UgPSAnJztcblxuICAgICAgICAvLyBIYW5kbGUgZGlmZmVyZW50IGVycm9yIHR5cGVzXG4gICAgICAgIGlmICh0eXBlb2YgZXJyb3IgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICBtZXNzYWdlID0gZXJyb3I7XG4gICAgICAgIH0gZWxzZSBpZiAoZXJyb3IgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgICAgICAgbWVzc2FnZSA9IGVycm9yLm1lc3NhZ2UgfHwgZXJyb3IudG9TdHJpbmcoKTtcbiAgICAgICAgfSBlbHNlIGlmIChlcnJvciAmJiBlcnJvci5tZXNzYWdlKSB7XG4gICAgICAgICAgICBtZXNzYWdlID0gZXJyb3IubWVzc2FnZTtcbiAgICAgICAgfSBlbHNlIGlmIChlcnJvciAmJiBlcnJvci5lcnJvcikge1xuICAgICAgICAgICAgLy8gRmF0YWwgZXJyb3Igd2l0aCBkZXRhaWxzXG4gICAgICAgICAgICBjb25zdCBkZXRhaWxzID0gZXJyb3IuZXJyb3I7XG4gICAgICAgICAgICBpZiAoZGV0YWlscy5maWxlICYmIGRldGFpbHMubGluZSkge1xuICAgICAgICAgICAgICAgIG1lc3NhZ2UgPSBgVW5jYXVnaHQgRmF0YWwgRXJyb3IgaW4gJHtkZXRhaWxzLmZpbGV9OiR7ZGV0YWlscy5saW5lfTpcXG5cXG4ke2RldGFpbHMuZXJyb3J9YDtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgbWVzc2FnZSA9IGRldGFpbHMuZXJyb3IgfHwgJ0FuIHVua25vd24gZXJyb3Igb2NjdXJyZWQnO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgbWVzc2FnZSA9ICdBbiB1bmtub3duIGVycm9yIG9jY3VycmVkJztcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIENyZWF0ZSBlcnJvciBib2R5IHdpdGggcmVkIGFsZXJ0IHN0eWxpbmdcbiAgICAgICAgY29uc3QgJGJvZHkgPSAkKCc8ZGl2IGNsYXNzPVwiYWxlcnQgYWxlcnQtZGFuZ2VyIG1iLTBcIiByb2xlPVwiYWxlcnRcIj4nKS5hcHBlbmQoXG4gICAgICAgICAgICAkKCc8cHJlIGNsYXNzPVwibWItMFwiIHN0eWxlPVwid2hpdGUtc3BhY2U6IHByZS13cmFwOyB3b3JkLXdyYXA6IGJyZWFrLXdvcmQ7IGZvbnQtZmFtaWx5OiBtb25vc3BhY2U7IGZvbnQtc2l6ZTogMC45ZW07XCI+JykudGV4dChcbiAgICAgICAgICAgICAgICBtZXNzYWdlXG4gICAgICAgICAgICApXG4gICAgICAgICk7XG5cbiAgICAgICAgYXdhaXQgdGhpcy5fc2hvd19tb2RhbCh7XG4gICAgICAgICAgICB0aXRsZTogdGl0bGUsXG4gICAgICAgICAgICBib2R5OiAkYm9keSxcbiAgICAgICAgICAgIGJ1dHRvbnM6IFtcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGxhYmVsOiAnQ2xvc2UnLFxuICAgICAgICAgICAgICAgICAgICB2YWx1ZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgY2xhc3M6ICdidG4tZGFuZ2VyJyxcbiAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDogdHJ1ZSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICAgIGNsb3NhYmxlOiB0cnVlLFxuICAgICAgICAgICAgY2xvc2Vfb25fc3VibWl0OiB0cnVlLFxuICAgICAgICAgICAgbWF4X3dpZHRoOiA2MDAsXG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gICAgLy8gQ3VzdG9tIE1vZGFsIE1ldGhvZHNcbiAgICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuXG4gICAgLyoqXG4gICAgICogU2hvdyBhIGN1c3RvbSBtb2RhbCB3aXRoIHNwZWNpZmllZCBjb250ZW50IGFuZCBidXR0b25zXG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnNcbiAgICAgKiBAcmV0dXJucyB7UHJvbWlzZTwqPn1cbiAgICAgKi9cbiAgICBzdGF0aWMgYXN5bmMgc2hvdyhvcHRpb25zKSB7XG4gICAgICAgIGNvbnN0IGRlZmF1bHRzID0ge1xuICAgICAgICAgICAgdGl0bGU6ICdNb2RhbCcsXG4gICAgICAgICAgICBib2R5OiAnJyxcbiAgICAgICAgICAgIGJ1dHRvbnM6IFtdLFxuICAgICAgICAgICAgbWF4X3dpZHRoOiA4MDAsXG4gICAgICAgICAgICBjbG9zYWJsZTogdHJ1ZSxcbiAgICAgICAgICAgIGNsb3NlX29uX3N1Ym1pdDogdHJ1ZSxcbiAgICAgICAgfTtcblxuICAgICAgICBjb25zdCBmaW5hbF9vcHRpb25zID0gT2JqZWN0LmFzc2lnbih7fSwgZGVmYXVsdHMsIG9wdGlvbnMpO1xuXG4gICAgICAgIHJldHVybiBhd2FpdCB0aGlzLl9zaG93X21vZGFsKGZpbmFsX29wdGlvbnMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNob3cgYSBtb2RhbCB3aXRoIGEganFodG1sIGZvcm0gY29tcG9uZW50XG4gICAgICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnNcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gb3B0aW9ucy5jb21wb25lbnQgLSBDb21wb25lbnQgY2xhc3MgbmFtZVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zLmNvbXBvbmVudF9hcmdzIC0gQXJndW1lbnRzIHRvIHBhc3MgdG8gY29tcG9uZW50XG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gb3B0aW9ucy5vbl9zdWJtaXQgLSBDYWxsYmFjayBmdW5jdGlvbiBjYWxsZWQgb24gc3VibWl0LiBSZWNlaXZlcyBmb3JtIGNvbXBvbmVudCBpbnN0YW5jZS5cbiAgICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSZXR1cm4gZmFsc2UgdG8ga2VlcCBtb2RhbCBvcGVuLCBvciByZXR1cm4gZGF0YSB0byBjbG9zZSBhbmQgcmVzb2x2ZS5cbiAgICAgKiBAcmV0dXJucyB7UHJvbWlzZTxPYmplY3R8ZmFsc2U+fVxuICAgICAqL1xuICAgIHN0YXRpYyBhc3luYyBmb3JtKG9wdGlvbnMpIHtcbiAgICAgICAgY29uc3QgZGVmYXVsdHMgPSB7XG4gICAgICAgICAgICB0aXRsZTogJ0Zvcm0nLFxuICAgICAgICAgICAgY29tcG9uZW50OiBudWxsLFxuICAgICAgICAgICAgY29tcG9uZW50X2FyZ3M6IHt9LFxuICAgICAgICAgICAgbWF4X3dpZHRoOiA4MDAsXG4gICAgICAgICAgICBjbG9zYWJsZTogdHJ1ZSxcbiAgICAgICAgICAgIHN1Ym1pdF9sYWJlbDogJ1N1Ym1pdCcsXG4gICAgICAgICAgICBjYW5jZWxfbGFiZWw6ICdDYW5jZWwnLFxuICAgICAgICAgICAgb25fc3VibWl0OiBudWxsLFxuICAgICAgICB9O1xuXG4gICAgICAgIGNvbnN0IGZpbmFsX29wdGlvbnMgPSBPYmplY3QuYXNzaWduKHt9LCBkZWZhdWx0cywgb3B0aW9ucyk7XG5cbiAgICAgICAgaWYgKCFmaW5hbF9vcHRpb25zLmNvbXBvbmVudCkge1xuICAgICAgICAgICAgY29uc29sZS5lcnJvcignTW9kYWwuZm9ybSgpIHJlcXVpcmVzIGEgY29tcG9uZW50Jyk7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBDcmVhdGUgY29tcG9uZW50IGluc3RhbmNlXG4gICAgICAgIGxldCAkY29tcG9uZW50X2NvbnRhaW5lciA9ICQoJzxkaXY+Jyk7XG4gICAgICAgIGxldCBjb21wb25lbnRfaW5zdGFuY2UgPSAkY29tcG9uZW50X2NvbnRhaW5lci5jb21wb25lbnQoZmluYWxfb3B0aW9ucy5jb21wb25lbnQsIGZpbmFsX29wdGlvbnMuY29tcG9uZW50X2FyZ3MpO1xuXG4gICAgICAgIC8vIFdhaXQgZm9yIGNvbXBvbmVudCB0byBiZSByZWFkeVxuICAgICAgICBhd2FpdCBuZXcgUHJvbWlzZSgocmVzb2x2ZSkgPT4ge1xuICAgICAgICAgICAgY29tcG9uZW50X2luc3RhbmNlLm9uKCdyZWFkeScsICgpID0+IHJlc29sdmUoKSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIEZpbmQgYSBmb3JtIGluc3RhbmNlIGlmIGNvbXBvbmVudCBpbnN0YW5jZSBkb2VzbnQgaGF2ZSAudmFscygpXG4gICAgICAgIGlmICghY29tcG9uZW50X2luc3RhbmNlLnZhbHMpIHtcbiAgICAgICAgICAgIGxldCAkZm9ybSA9IGNvbXBvbmVudF9pbnN0YW5jZS4kLmZpbmQoJy5Sc3hfRm9ybScpO1xuICAgICAgICAgICAgaWYgKCRmb3JtLmV4aXN0cygpKSB7XG4gICAgICAgICAgICAgICAgY29tcG9uZW50X2luc3RhbmNlID0gJGZvcm0uY29tcG9uZW50KCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyBDcmVhdGUgYnV0dG9uc1xuICAgICAgICBjb25zdCBidXR0b25zID0gW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGxhYmVsOiBmaW5hbF9vcHRpb25zLmNhbmNlbF9sYWJlbCxcbiAgICAgICAgICAgICAgICB2YWx1ZTogZmFsc2UsXG4gICAgICAgICAgICAgICAgY2xhc3M6ICdidG4tc2Vjb25kYXJ5JyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgbGFiZWw6IGZpbmFsX29wdGlvbnMuc3VibWl0X2xhYmVsLFxuICAgICAgICAgICAgICAgIHZhbHVlOiBudWxsLFxuICAgICAgICAgICAgICAgIGNsYXNzOiAnYnRuLXByaW1hcnknLFxuICAgICAgICAgICAgICAgIGRlZmF1bHQ6IHRydWUsXG4gICAgICAgICAgICAgICAgY2FsbGJhY2s6IGFzeW5jIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gSWYgb25fc3VibWl0IGNhbGxiYWNrIHByb3ZpZGVkLCB1c2UgaXRcbiAgICAgICAgICAgICAgICAgICAgaWYgKGZpbmFsX29wdGlvbnMub25fc3VibWl0ICYmIHR5cGVvZiBmaW5hbF9vcHRpb25zLm9uX3N1Ym1pdCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgZmluYWxfb3B0aW9ucy5vbl9zdWJtaXQoY29tcG9uZW50X2luc3RhbmNlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIElmIGNhbGxiYWNrIHJldHVybnMgbnVsbC91bmRlZmluZWQsIGtlZXAgbW9kYWwgb3BlblxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJlc3VsdCA9PT0gbnVsbCB8fCByZXN1bHQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIE90aGVyd2lzZSAoaW5jbHVkaW5nIGZhbHNlKSwgcmV0dXJuIHRoZSByZXN1bHQgdG8gY2xvc2UgbW9kYWxcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAvLyBObyBvbl9zdWJtaXQgY2FsbGJhY2sgLSBnZXQgZm9ybSBkYXRhIGFuZCBjbG9zZSBtb2RhbFxuICAgICAgICAgICAgICAgICAgICBpZiAoY29tcG9uZW50X2luc3RhbmNlLnN1Ym1pdCAmJiB0eXBlb2YgY29tcG9uZW50X2luc3RhbmNlLnN1Ym1pdCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGF3YWl0IGNvbXBvbmVudF9pbnN0YW5jZS5zdWJtaXQoKTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChjb21wb25lbnRfaW5zdGFuY2UudmFscyAmJiB0eXBlb2YgY29tcG9uZW50X2luc3RhbmNlLnZhbHMgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBjb21wb25lbnRfaW5zdGFuY2UudmFscygpO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS53YXJuKCdGb3JtIGNvbXBvbmVudCBoYXMgbm8gc3VibWl0KCkgb3IgdmFscygpIG1ldGhvZCcpO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgXTtcblxuICAgICAgICByZXR1cm4gYXdhaXQgdGhpcy5fc2hvd19tb2RhbCh7XG4gICAgICAgICAgICB0aXRsZTogZmluYWxfb3B0aW9ucy50aXRsZSxcbiAgICAgICAgICAgIGJvZHk6IGNvbXBvbmVudF9pbnN0YW5jZS4kLFxuICAgICAgICAgICAgYnV0dG9uczogYnV0dG9ucyxcbiAgICAgICAgICAgIG1heF93aWR0aDogZmluYWxfb3B0aW9ucy5tYXhfd2lkdGgsXG4gICAgICAgICAgICBjbG9zYWJsZTogZmluYWxfb3B0aW9ucy5jbG9zYWJsZSxcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2hvdyBhbiB1bmNsb3NhYmxlIG1vZGFsXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHRpdGxlX29yX2JvZHlcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gYm9keVxuICAgICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fVxuICAgICAqL1xuICAgIHN0YXRpYyBhc3luYyB1bmNsb3NhYmxlKHRpdGxlX29yX2JvZHksIGJvZHkgPSBudWxsKSB7XG4gICAgICAgIGxldCB0aXRsZSA9ICdQbGVhc2UgV2FpdCc7XG4gICAgICAgIGxldCBtZXNzYWdlID0gdGl0bGVfb3JfYm9keTtcblxuICAgICAgICBpZiAoYm9keSAhPT0gbnVsbCkge1xuICAgICAgICAgICAgdGl0bGUgPSB0aXRsZV9vcl9ib2R5O1xuICAgICAgICAgICAgbWVzc2FnZSA9IGJvZHk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBEb24ndCB3YWl0IGZvciB0aGlzIHByb21pc2UgLSBpdCBuZXZlciByZXNvbHZlcyB1bnRpbCBjbG9zZWQgbWFudWFsbHlcbiAgICAgICAgdGhpcy5fc2hvd19tb2RhbCh7XG4gICAgICAgICAgICB0aXRsZTogdGl0bGUsXG4gICAgICAgICAgICBib2R5OiBtZXNzYWdlLFxuICAgICAgICAgICAgYnV0dG9uczogW10sIC8vIE5vIGJ1dHRvbnNcbiAgICAgICAgICAgIGNsb3NhYmxlOiBmYWxzZSwgLy8gQ2FuJ3QgY2xvc2VcbiAgICAgICAgICAgIGNsb3NlX29uX3N1Ym1pdDogZmFsc2UsXG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIFdhaXQgZm9yIG5leHQgYW5pbWF0aW9uIGZyYW1lIGZvciBtb2RhbCB0byByZW5kZXJcbiAgICAgICAgYXdhaXQgbmV3IFByb21pc2UocmVzb2x2ZSA9PiByZXF1ZXN0QW5pbWF0aW9uRnJhbWUocmVzb2x2ZSkpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNob3cgYSBtb2RhbCB3aXRoIGN1c3RvbSBqUXVlcnkgY29udGVudFxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zXG4gICAgICogQHJldHVybnMge1Byb21pc2U8Kj59XG4gICAgICovXG4gICAgc3RhdGljIGFzeW5jIGN1c3RvbShvcHRpb25zKSB7XG4gICAgICAgIC8vIEFsaWFzIGZvciBzaG93KCkgLSBzYW1lIGZ1bmN0aW9uYWxpdHlcbiAgICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuc2hvdyhvcHRpb25zKTtcbiAgICB9XG5cbiAgICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICAgIC8vIEhlbHBlciBNZXRob2RzXG4gICAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuICAgIC8qKlxuICAgICAqIFNob3cgYW4gZXJyb3IgYWxlcnRcbiAgICAgKiBAcGFyYW0geyp9IGVycm9yc1xuICAgICAqIEBwYXJhbSB7c3RyaW5nfSB0aXRsZVxuICAgICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fVxuICAgICAqL1xuICAgIHN0YXRpYyBhc3luYyBlcnJvcihlcnJvcnMsIHRpdGxlID0gJ0Vycm9yJykge1xuICAgICAgICBsZXQgbWVzc2FnZSA9ICdBbiBlcnJvciBvY2N1cnJlZCc7XG5cbiAgICAgICAgLy8gSGFuZGxlIHZhcmlvdXMgZXJyb3IgZm9ybWF0c1xuICAgICAgICBpZiAodHlwZW9mIGVycm9ycyA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgIG1lc3NhZ2UgPSBlcnJvcnM7XG4gICAgICAgIH0gZWxzZSBpZiAoZXJyb3JzICYmICdyZXNwb25zZUpTT04nIGluIGVycm9ycyAmJiAnbWVzc2FnZScgaW4gZXJyb3JzLnJlc3BvbnNlSlNPTikge1xuICAgICAgICAgICAgbWVzc2FnZSA9IGVycm9ycy5yZXNwb25zZUpTT04ubWVzc2FnZTtcbiAgICAgICAgfSBlbHNlIGlmIChlcnJvcnMgJiYgJ21lc3NhZ2UnIGluIGVycm9ycykge1xuICAgICAgICAgICAgbWVzc2FnZSA9IGVycm9ycy5tZXNzYWdlO1xuICAgICAgICB9IGVsc2UgaWYgKGVycm9ycyAmJiB0eXBlb2YgZXJyb3JzID09PSAnb2JqZWN0Jykge1xuICAgICAgICAgICAgLy8gVHJ5IHRvIGZvcm1hdCBlcnJvciBvYmplY3RcbiAgICAgICAgICAgIGNvbnN0IGVycm9yX21lc3NhZ2VzID0gW107XG4gICAgICAgICAgICBmb3IgKGNvbnN0IGtleSBpbiBlcnJvcnMpIHtcbiAgICAgICAgICAgICAgICBpZiAoaXNfYXJyYXkoZXJyb3JzW2tleV0pKSB7XG4gICAgICAgICAgICAgICAgICAgIGVycm9yX21lc3NhZ2VzLnB1c2goZXJyb3JzW2tleV1bMF0pO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGVycm9yX21lc3NhZ2VzLnB1c2goZXJyb3JzW2tleV0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChlcnJvcl9tZXNzYWdlcy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgICAgbWVzc2FnZSA9IGVycm9yX21lc3NhZ2VzLmpvaW4oJ1xcbicpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgYXdhaXQgdGhpcy5fc2hvd19tb2RhbCh7XG4gICAgICAgICAgICB0aXRsZTogdGl0bGUsXG4gICAgICAgICAgICBib2R5OiBtZXNzYWdlLFxuICAgICAgICAgICAgaWNvbjogJ2V4Y2xhbWF0aW9uLWNpcmNsZScsXG4gICAgICAgICAgICBidXR0b25zOiBbXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBsYWJlbDogJ09LJyxcbiAgICAgICAgICAgICAgICAgICAgdmFsdWU6IHRydWUsXG4gICAgICAgICAgICAgICAgICAgIGNsYXNzOiAnYnRuLWRhbmdlcicsXG4gICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6IHRydWUsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgICBjbG9zYWJsZTogdHJ1ZSxcbiAgICAgICAgICAgIGNsb3NlX29uX3N1Ym1pdDogdHJ1ZSxcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmVvcGVuIGN1cnJlbnQgbW9kYWwgd2l0aCB2YWxpZGF0aW9uIGVycm9yc1xuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBlcnJvcnNcbiAgICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn1cbiAgICAgKi9cbiAgICBzdGF0aWMgYXN5bmMgcmVvcGVuX3dpdGhfZXJyb3JzKGVycm9ycykge1xuICAgICAgICBpZiAodGhpcy5fY3VycmVudCkge1xuICAgICAgICAgICAgLy8gTW9kYWwgaXMgc3RpbGwgb3BlbiwganVzdCBhcHBseSBlcnJvcnNcbiAgICAgICAgICAgIHRoaXMuYXBwbHlfZXJyb3JzKGVycm9ycyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zb2xlLndhcm4oJ05vIG1vZGFsIG9wZW4gdG8gYXBwbHkgZXJyb3JzIHRvJyk7XG4gICAgICAgIH1cbiAgICB9XG59XG4iLCJjbGFzcyBCcmVhZGNydW1iX0l0ZW0gZXh0ZW5kcyBKcWh0bWxfQ29tcG9uZW50IHtcbiAgICBvbl9jcmVhdGUoKSB7XG4gICAgICAgIC8vIFJlYWQgaHJlZiBmcm9tIEhUTUwgYXR0cmlidXRlIGlmIHByZXNlbnRcbiAgICAgICAgY29uc3QgaHJlZiA9IHRoaXMuJC5hdHRyKCdocmVmJyk7XG4gICAgICAgIGlmIChocmVmKSB7XG4gICAgICAgICAgICB0aGlzLmFyZ3MuaHJlZiA9IGhyZWY7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBSZWFkIGFjdGl2ZSBmcm9tIEhUTUwgYXR0cmlidXRlIGlmIHByZXNlbnRcbiAgICAgICAgY29uc3QgYWN0aXZlID0gdGhpcy4kLmF0dHIoJ2FjdGl2ZScpO1xuICAgICAgICBpZiAoYWN0aXZlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHRoaXMuYXJncy5hY3RpdmUgPSB0cnVlO1xuICAgICAgICAgICAgdGhpcy4kLmFkZENsYXNzKCdhY3RpdmUnKTtcbiAgICAgICAgICAgIHRoaXMuJC5hdHRyKCdhcmlhLWN1cnJlbnQnLCAncGFnZScpO1xuICAgICAgICAgICAgdGhpcy4kLnJlbW92ZUF0dHIoJ2FjdGl2ZScpOyAvLyBSZW1vdmUgdGhlIGF0dHJpYnV0ZSBhZnRlciByZWFkaW5nXG4gICAgICAgIH1cbiAgICB9XG59XG4iLCJjbGFzcyBDbGllbnRfTGFiZWxfTGluayBleHRlbmRzIEpxaHRtbF9Db21wb25lbnQge1xuICAgIG9uX2NyZWF0ZSgpIHtcbiAgICAgICAgdGhpcy5kYXRhLmxvYWRpbmcgPSB0cnVlO1xuICAgICAgICB0aGlzLmRhdGEuY2xpZW50ID0gbnVsbDtcblxuICAgICAgICAvLyBDb252ZXJ0IGNsaWVudF9pZCB0byBudW1iZXIgaWYgaXQncyBhIG51bWVyaWMgc3RyaW5nXG4gICAgICAgIGlmICh0aGlzLmFyZ3MuY2xpZW50X2lkKSB7XG4gICAgICAgICAgICB0aGlzLmFyZ3MuY2xpZW50X2lkID0gdmFsdWVfdW5sZXNzX251bWVyaWNfc3RyaW5nX3RoZW5fbnVtZXJpY192YWx1ZSh0aGlzLmFyZ3MuY2xpZW50X2lkKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGFzeW5jIG9uX2xvYWQoKSB7XG4gICAgICAgIC8vIExvYWQgY2xpZW50IGRhdGEgaWYgd2UgaGF2ZSBhbiBJRFxuICAgICAgICBpZiAodGhpcy5hcmdzLmNsaWVudF9pZCkge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICB0aGlzLmRhdGEuY2xpZW50ID0gYXdhaXQgRnJvbnRlbmRfQ29udGFjdHNfQ29udHJvbGxlci5nZXRfY2xpZW50KHtcbiAgICAgICAgICAgICAgICAgICAgY2xpZW50X2lkOiB0aGlzLmFyZ3MuY2xpZW50X2lkLFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIHRoaXMuZGF0YS5sb2FkaW5nID0gZmFsc2U7XG4gICAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0ZhaWxlZCB0byBsb2FkIGNsaWVudDonLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgdGhpcy5kYXRhLmxvYWRpbmcgPSBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuZGF0YS5sb2FkaW5nID0gZmFsc2U7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBvbl9yZW5kZXIoKSB7XG4gICAgICAgIC8vIFNldCBocmVmIGR5bmFtaWNhbGx5IGFmdGVyIGVhY2ggcmVuZGVyXG4gICAgICAgIGlmICh0aGlzLmFyZ3MuY2xpZW50X2lkKSB7XG4gICAgICAgICAgICBjb25zdCBocmVmID0gUnN4LlJvdXRlKCdGcm9udGVuZF9DbGllbnRzX0NvbnRyb2xsZXInLCAndmlldycsIHRoaXMuYXJncy5jbGllbnRfaWQpO1xuICAgICAgICAgICAgdGhpcy4kLmF0dHIoJ2hyZWYnLCBocmVmKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuJC5hdHRyKCdocmVmJywgJyMnKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldCBvciBzZXQgdGhlIGNsaWVudF9pZFxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbY2xpZW50X2lkXSAtIElmIHByb3ZpZGVkLCBzZXRzIHRoZSBjbGllbnRfaWQgYW5kIHJlbG9hZHNcbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBDdXJyZW50IGNsaWVudF9pZCB3aGVuIGNhbGxlZCBhcyBnZXR0ZXJcbiAgICAgKi9cbiAgICB2YWwoY2xpZW50X2lkKSB7XG4gICAgICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAvLyBHZXR0ZXJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmFyZ3MuY2xpZW50X2lkO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gU2V0dGVyIC0gdXBkYXRlIGNsaWVudF9pZCBhbmQgcmVsb2FkXG4gICAgICAgICAgICB0aGlzLmFyZ3MuY2xpZW50X2lkID0gdmFsdWVfdW5sZXNzX251bWVyaWNfc3RyaW5nX3RoZW5fbnVtZXJpY192YWx1ZShjbGllbnRfaWQpO1xuICAgICAgICAgICAgdGhpcy5kYXRhLmxvYWRpbmcgPSB0cnVlO1xuICAgICAgICAgICAgdGhpcy5kYXRhLmNsaWVudCA9IG51bGw7XG5cbiAgICAgICAgICAgIC8vIFJlbG9hZCBjbGllbnQgZGF0YSBhbmQgcmUtcmVuZGVyIChvbl9yZW5kZXIgd2lsbCB1cGRhdGUgaHJlZilcbiAgICAgICAgICAgIHRoaXMub25fbG9hZCgpLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMucmVuZGVyKCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH1cbn1cbiIsImNsYXNzIENsaWVudF9MYWJlbCBleHRlbmRzIEpxaHRtbF9Db21wb25lbnQge1xuICAgIG9uX2NyZWF0ZSgpIHtcbiAgICAgICAgdGhpcy5kYXRhLmxvYWRpbmcgPSB0cnVlO1xuICAgICAgICB0aGlzLmRhdGEuY2xpZW50ID0gbnVsbDtcblxuICAgICAgICAvLyBDb252ZXJ0IGNsaWVudF9pZCB0byBudW1iZXIgaWYgaXQncyBhIG51bWVyaWMgc3RyaW5nXG4gICAgICAgIGlmICh0aGlzLmFyZ3MuY2xpZW50X2lkKSB7XG4gICAgICAgICAgICB0aGlzLmFyZ3MuY2xpZW50X2lkID0gdmFsdWVfdW5sZXNzX251bWVyaWNfc3RyaW5nX3RoZW5fbnVtZXJpY192YWx1ZSh0aGlzLmFyZ3MuY2xpZW50X2lkKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGFzeW5jIG9uX2xvYWQoKSB7XG4gICAgICAgIC8vIExvYWQgY2xpZW50IGRhdGEgaWYgd2UgaGF2ZSBhbiBJRFxuICAgICAgICBpZiAodGhpcy5hcmdzLmNsaWVudF9pZCkge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICB0aGlzLmRhdGEuY2xpZW50ID0gYXdhaXQgRnJvbnRlbmRfQ29udGFjdHNfQ29udHJvbGxlci5nZXRfY2xpZW50KHtcbiAgICAgICAgICAgICAgICAgICAgY2xpZW50X2lkOiB0aGlzLmFyZ3MuY2xpZW50X2lkLFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIHRoaXMuZGF0YS5sb2FkaW5nID0gZmFsc2U7XG4gICAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0ZhaWxlZCB0byBsb2FkIGNsaWVudDonLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgdGhpcy5kYXRhLmxvYWRpbmcgPSBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuZGF0YS5sb2FkaW5nID0gZmFsc2U7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXQgb3Igc2V0IHRoZSBjbGllbnRfaWRcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gW2NsaWVudF9pZF0gLSBJZiBwcm92aWRlZCwgc2V0cyB0aGUgY2xpZW50X2lkIGFuZCByZWxvYWRzXG4gICAgICogQHJldHVybnMge251bWJlcn0gQ3VycmVudCBjbGllbnRfaWQgd2hlbiBjYWxsZWQgYXMgZ2V0dGVyXG4gICAgICovXG4gICAgdmFsKGNsaWVudF9pZCkge1xuICAgICAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgLy8gR2V0dGVyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5hcmdzLmNsaWVudF9pZDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIFNldHRlciAtIHVwZGF0ZSBjbGllbnRfaWQgYW5kIHJlbG9hZFxuICAgICAgICAgICAgdGhpcy5hcmdzLmNsaWVudF9pZCA9IHZhbHVlX3VubGVzc19udW1lcmljX3N0cmluZ190aGVuX251bWVyaWNfdmFsdWUoY2xpZW50X2lkKTtcbiAgICAgICAgICAgIHRoaXMuZGF0YS5sb2FkaW5nID0gdHJ1ZTtcbiAgICAgICAgICAgIHRoaXMuZGF0YS5jbGllbnQgPSBudWxsO1xuXG4gICAgICAgICAgICAvLyBSZWxvYWQgY2xpZW50IGRhdGEgYW5kIHJlLXJlbmRlciAob25fcmVuZGVyIHdpbGwgdXBkYXRlIGhyZWYpXG4gICAgICAgICAgICB0aGlzLm9uX2xvYWQoKS50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLnJlbmRlcigpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG59XG4iLCIvKipcbiAqIEZvcm1fSW5wdXRfQWJzdHJhY3QgLSBCYXNlIGNsYXNzIGZvciBhbGwgZm9ybSBpbnB1dCB3aWRnZXRzXG4gKlxuICogRGVmaW5lcyB0aGUgaW50ZXJmYWNlIHRoYXQgYWxsIGZvcm0gd2lkZ2V0cyBtdXN0IGltcGxlbWVudC5cbiAqIFRoaXMgZW5zdXJlcyBjb25zaXN0ZW5jeSBhY3Jvc3MgYWxsIGlucHV0IHR5cGVzICh0ZXh0LCBzZWxlY3QsIHd5c2l3eWcsIGV0Yy4pXG4gKlxuICogUkVRVUlSRUQgTUVUSE9EUyAobXVzdCBiZSBpbXBsZW1lbnRlZCBieSBzdWJjbGFzc2VzKTpcbiAqIC0gdmFsKCkgLSBHZXQgY3VycmVudCB2YWx1ZSAobm8gYXJndW1lbnRzKVxuICogLSB2YWwodmFsdWUpIC0gU2V0IHZhbHVlIChvbmUgYXJndW1lbnQpXG4gKiAtIHNlZWQoKSAtIEZpbGxzIHRoZSB3aWRnZXQgd2l0aCByYW5kb20gdGVzdCBkYXRhIChvcHRpb25hbClcbiAqXG4gKiBBbGwgd2lkZ2V0cyBtdXN0OlxuICogLSBIYXZlIC5XaWRnZXQgQ1NTIGNsYXNzXG4gKiAtIEhhdmUgZGF0YS1uYW1lIGF0dHJpYnV0ZSBzZXQgYnkgRm9ybV9GaWVsZFxuICovXG5jbGFzcyBGb3JtX0lucHV0X0Fic3RyYWN0IGV4dGVuZHMgSnFodG1sX0NvbXBvbmVudCB7XG4gICAgLyoqXG4gICAgICogdmFsKCkgLSBHZXQgb3Igc2V0IHRoZSBjdXJyZW50IHZhbHVlXG4gICAgICogU3ViY2xhc3NlcyBNVVNUIGltcGxlbWVudCB0aGlzIG1ldGhvZFxuICAgICAqXG4gICAgICogQHBhcmFtIHsqfSBbdmFsdWVdIC0gSWYgcHJvdmlkZWQsIHNldHMgdGhlIHZhbHVlLiBJZiBvbWl0dGVkLCByZXR1cm5zIHRoZSB2YWx1ZS5cbiAgICAgKiBAcmV0dXJucyB7Kn0gVGhlIGN1cnJlbnQgdmFsdWUgd2hlbiBjYWxsZWQgYXMgZ2V0dGVyXG4gICAgICovXG4gICAgdmFsKHZhbHVlKSB7XG4gICAgICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAvLyBHZXR0ZXJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgJHt0aGlzLmNvbnN0cnVjdG9yLm5hbWV9IG11c3QgaW1wbGVtZW50IHZhbCgpIGdldHRlcmApO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gU2V0dGVyXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYCR7dGhpcy5jb25zdHJ1Y3Rvci5uYW1lfSBtdXN0IGltcGxlbWVudCB2YWwodmFsdWUpIHNldHRlcmApO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2VlZCAtIEZpbGwgd2l0aCByYW5kb20gdGVzdCBkYXRhIChvcHRpb25hbClcbiAgICAgKiBTdWJjbGFzc2VzIE1BWSBpbXBsZW1lbnQgdGhpcyBtZXRob2RcbiAgICAgKi9cbiAgICBhc3luYyBzZWVkKCkge1xuICAgICAgICAvLyBPcHRpb25hbCAtIHdpZGdldHMgY2FuIG92ZXJyaWRlIGlmIHRoZXkgc3VwcG9ydCBzZWVkaW5nXG4gICAgfVxufVxuIiwiY2xhc3MgVGV4dF9JbnB1dCBleHRlbmRzIEZvcm1fSW5wdXRfQWJzdHJhY3Qge1xuICAgIG9uX2NyZWF0ZSgpIHtcbiAgICAgICAgdGhpcy5kYXRhLnZhbHVlID0gJyc7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogdmFsKCkgLSBHZXQgb3Igc2V0IHRoZSBpbnB1dCB2YWx1ZVxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbdmFsdWVdIC0gSWYgcHJvdmlkZWQsIHNldHMgdGhlIHZhbHVlXG4gICAgICogQHJldHVybnMge3N0cmluZ30gVGhlIGN1cnJlbnQgdmFsdWUgd2hlbiBjYWxsZWQgYXMgZ2V0dGVyXG4gICAgICovXG4gICAgdmFsKHZhbHVlKSB7XG4gICAgICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAvLyBHZXR0ZXJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLiRpZCgnaW5wdXQnKS52YWwoKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIFNldHRlclxuICAgICAgICAgICAgdGhpcy5kYXRhLnZhbHVlID0gdmFsdWUgfHwgJyc7XG4gICAgICAgICAgICBpZiAodGhpcy4kaWQoJ2lucHV0JykuZXhpc3RzKCkpIHtcbiAgICAgICAgICAgICAgICB0aGlzLiRpZCgnaW5wdXQnKS52YWwodGhpcy5kYXRhLnZhbHVlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIGFzeW5jIHNlZWQoKSB7XG4gICAgICAgIGlmICh0aGlzLmFyZ3Muc2VlZGVyKSB7XG4gICAgICAgICAgICAvLyBUT0RPOiBJbXBsZW1lbnQgUnN4X1JhbmRvbV9WYWx1ZXMgZW5kcG9pbnRcbiAgICAgICAgICAgIC8vIGxldCB2YWx1ZSA9IGF3YWl0IFJzeF9SYW5kb21fVmFsdWVzW3RoaXMuYXJncy5zZWVkZXJdKCk7XG4gICAgICAgICAgICAvLyBGb3Igbm93LCBqdXN0IHVzZSBwbGFjZWhvbGRlciB0ZXh0XG4gICAgICAgICAgICBsZXQgdmFsdWUgPSAnVGVzdCAnICsgKHRoaXMuYXJncy5zZWVkZXIgfHwgJ1ZhbHVlJyk7XG4gICAgICAgICAgICB0aGlzLnZhbCh2YWx1ZSk7XG4gICAgICAgIH1cbiAgICB9XG59XG4iLCJjbGFzcyBDaGVja2JveF9JbnB1dCBleHRlbmRzIEZvcm1fSW5wdXRfQWJzdHJhY3Qge1xuICAgIG9uX2NyZWF0ZSgpIHtcbiAgICAgICAgdGhpcy5kYXRhLmNoZWNrZWQgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5jaGVja2VkX3ZhbHVlID0gdGhpcy5hcmdzLmNoZWNrZWRfdmFsdWUgfHwgJzEnO1xuICAgICAgICB0aGlzLnVuY2hlY2tlZF92YWx1ZSA9IHRoaXMuYXJncy51bmNoZWNrZWRfdmFsdWUgfHwgJzAnO1xuICAgIH1cblxuICAgIG9uX3JlYWR5KCkge1xuICAgICAgICAvLyBDb25uZWN0IGxhYmVsIGNsaWNrcyB0byBjaGVja2JveFxuICAgICAgICBjb25zdCAkaW5wdXQgPSB0aGlzLiRpZCgnaW5wdXQnKTtcbiAgICAgICAgY29uc3QgJGxhYmVsID0gdGhpcy4kaWQoJ2xhYmVsJyk7XG5cbiAgICAgICAgaWYgKCRsYWJlbC5leGlzdHMoKSkge1xuICAgICAgICAgICAgY29uc3QgaW5wdXRfaWQgPSAkaW5wdXQuYXR0cignaWQnKTtcbiAgICAgICAgICAgICRsYWJlbC5hdHRyKCdmb3InLCBpbnB1dF9pZCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiB2YWwoKSAtIEdldCBvciBzZXQgdGhlIGNoZWNrYm94IHN0YXRlXG4gICAgICogQHBhcmFtIHtzdHJpbmd8Ym9vbGVhbn0gW3ZhbHVlXSAtIElmIHByb3ZpZGVkLCBzZXRzIHRoZSBjaGVja2VkIHN0YXRlXG4gICAgICogQHJldHVybnMge3N0cmluZ30gVGhlIGNoZWNrZWRfdmFsdWUgb3IgdW5jaGVja2VkX3ZhbHVlIHdoZW4gY2FsbGVkIGFzIGdldHRlclxuICAgICAqL1xuICAgIHZhbCh2YWx1ZSkge1xuICAgICAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgLy8gR2V0dGVyXG4gICAgICAgICAgICBjb25zdCBpc19jaGVja2VkID0gdGhpcy4kaWQoJ2lucHV0JykucHJvcCgnY2hlY2tlZCcpO1xuICAgICAgICAgICAgcmV0dXJuIGlzX2NoZWNrZWQgPyB0aGlzLmNoZWNrZWRfdmFsdWUgOiB0aGlzLnVuY2hlY2tlZF92YWx1ZTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIFNldHRlciAtIGFjY2VwdHMgYm9vbGVhbiwgY2hlY2tlZF92YWx1ZSwgb3IgdW5jaGVja2VkX3ZhbHVlXG4gICAgICAgICAgICBsZXQgc2hvdWxkX2NoZWNrID0gZmFsc2U7XG5cbiAgICAgICAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdib29sZWFuJykge1xuICAgICAgICAgICAgICAgIHNob3VsZF9jaGVjayA9IHZhbHVlO1xuICAgICAgICAgICAgfSBlbHNlIGlmICh2YWx1ZSA9PT0gdGhpcy5jaGVja2VkX3ZhbHVlIHx8IHZhbHVlID09PSAnMScgfHwgdmFsdWUgPT09IDEgfHwgdmFsdWUgPT09IHRydWUpIHtcbiAgICAgICAgICAgICAgICBzaG91bGRfY2hlY2sgPSB0cnVlO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0aGlzLmRhdGEuY2hlY2tlZCA9IHNob3VsZF9jaGVjaztcbiAgICAgICAgICAgIGlmICh0aGlzLiRpZCgnaW5wdXQnKS5leGlzdHMoKSkge1xuICAgICAgICAgICAgICAgIHRoaXMuJGlkKCdpbnB1dCcpLnByb3AoJ2NoZWNrZWQnLCBzaG91bGRfY2hlY2spO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgYXN5bmMgc2VlZCgpIHtcbiAgICAgICAgLy8gUmFuZG9tbHkgY2hlY2sgb3IgdW5jaGVja1xuICAgICAgICB0aGlzLnZhbChNYXRoLnJhbmRvbSgpID4gMC41KTtcbiAgICB9XG59XG4iLCIvKipcbiAqIFd5c2l3eWdfSW5wdXQgLSBXWVNJV1lHIGVkaXRvciB3aWRnZXQgdXNpbmcgUXVpbGxcbiAqXG4gKiBJbXBsZW1lbnRzIHRoZSBmb3JtIHdpZGdldCBpbnRlcmZhY2U6XG4gKiAtIHZhbCgpIC0gR2V0L3NldCBIVE1MIGNvbnRlbnRcbiAqIC0gc2VlZCgpIC0gRmlsbHMgd2l0aCByYW5kb20gY29udGVudFxuICovXG5jbGFzcyBXeXNpd3lnX0lucHV0IGV4dGVuZHMgRm9ybV9JbnB1dF9BYnN0cmFjdCB7XG4gICAgb25fY3JlYXRlKCkge1xuICAgICAgICB0aGlzLnF1aWxsID0gbnVsbDtcbiAgICB9XG5cbiAgICBvbl9yZWFkeSgpIHtcbiAgICAgICAgLy8gV2FpdCBmb3IgUXVpbGwgdG8gYmUgbG9hZGVkLCB0aGVuIGluaXRpYWxpemVcbiAgICAgICAgY29uc3QgdGhhdCA9IHRoaXM7XG4gICAgICAgIHF1aWxsX3JlYWR5KGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgdGhhdC5faW5pdGlhbGl6ZV9xdWlsbCgpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBfaW5pdGlhbGl6ZV9xdWlsbCgpIHtcbiAgICAgICAgLy8gSW5pdGlhbGl6ZSBRdWlsbCBlZGl0b3JcbiAgICAgICAgdGhpcy5xdWlsbCA9IG5ldyBRdWlsbCh0aGlzLiRpZCgnZWRpdG9yJylbMF0sIHtcbiAgICAgICAgICAgIHRoZW1lOiAnc25vdycsXG4gICAgICAgICAgICBwbGFjZWhvbGRlcjogdGhpcy5hcmdzLnBsYWNlaG9sZGVyIHx8ICdFbnRlciB0ZXh0Li4uJyxcbiAgICAgICAgICAgIG1vZHVsZXM6IHtcbiAgICAgICAgICAgICAgICB0b29sYmFyOiBbXG4gICAgICAgICAgICAgICAgICAgIFt7ICdoZWFkZXInOiBbMSwgMiwgMywgZmFsc2VdIH1dLFxuICAgICAgICAgICAgICAgICAgICBbJ2JvbGQnLCAnaXRhbGljJywgJ3VuZGVybGluZScsICdzdHJpa2UnXSxcbiAgICAgICAgICAgICAgICAgICAgWydibG9ja3F1b3RlJywgJ2NvZGUtYmxvY2snXSxcbiAgICAgICAgICAgICAgICAgICAgW3sgJ2xpc3QnOiAnb3JkZXJlZCd9LCB7ICdsaXN0JzogJ2J1bGxldCcgfV0sXG4gICAgICAgICAgICAgICAgICAgIFt7ICdpbmRlbnQnOiAnLTEnfSwgeyAnaW5kZW50JzogJysxJyB9XSxcbiAgICAgICAgICAgICAgICAgICAgWydsaW5rJywgJ2ltYWdlJ10sXG4gICAgICAgICAgICAgICAgICAgIFsnY2xlYW4nXVxuICAgICAgICAgICAgICAgIF1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gVXBkYXRlIGhpZGRlbiBpbnB1dCBvbiB0ZXh0IGNoYW5nZVxuICAgICAgICBjb25zdCB0aGF0ID0gdGhpcztcbiAgICAgICAgdGhpcy5xdWlsbC5vbigndGV4dC1jaGFuZ2UnLCBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgIHRoYXQuJGlkKCdoaWRkZW5faW5wdXQnKS52YWwodGhhdC5xdWlsbC5yb290LmlubmVySFRNTCk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIHZhbCgpIC0gR2V0IG9yIHNldCBIVE1MIGNvbnRlbnRcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW3ZhbHVlXSAtIElmIHByb3ZpZGVkLCBzZXRzIHRoZSBIVE1MIGNvbnRlbnRcbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBUaGUgSFRNTCBjb250ZW50IHdoZW4gY2FsbGVkIGFzIGdldHRlclxuICAgICAqL1xuICAgIHZhbCh2YWx1ZSkge1xuICAgICAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgLy8gR2V0dGVyXG4gICAgICAgICAgICBpZiAoIXRoaXMucXVpbGwpIHJldHVybiAnJztcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnF1aWxsLnJvb3QuaW5uZXJIVE1MO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gU2V0dGVyXG4gICAgICAgICAgICBpZiAoIXRoaXMucXVpbGwpIHtcbiAgICAgICAgICAgICAgICAvLyBRdWlsbCBub3QgcmVhZHkgeWV0LCB3YWl0IGFuZCB0cnkgYWdhaW5cbiAgICAgICAgICAgICAgICBjb25zdCB0aGF0ID0gdGhpcztcbiAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHRoYXQudmFsKHZhbHVlKSwgMTAwKTtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmICh2YWx1ZSkge1xuICAgICAgICAgICAgICAgIHRoaXMucXVpbGwucm9vdC5pbm5lckhUTUwgPSB2YWx1ZTtcbiAgICAgICAgICAgICAgICB0aGlzLiRpZCgnaGlkZGVuX2lucHV0JykudmFsKHZhbHVlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNlZWQgLSBGaWxsIHdpdGggcmFuZG9tIGNvbnRlbnQgZm9yIHRlc3RpbmdcbiAgICAgKi9cbiAgICBhc3luYyBzZWVkKCkge1xuICAgICAgICBpZiAoIXRoaXMucXVpbGwpIHJldHVybjtcblxuICAgICAgICBjb25zdCBzYW1wbGVfY29udGVudCA9IGBcbiAgICAgICAgICAgIDxoMj5TYW1wbGUgSGVhZGluZzwvaDI+XG4gICAgICAgICAgICA8cD5UaGlzIGlzIGEgc2FtcGxlIHBhcmFncmFwaCB3aXRoIDxzdHJvbmc+Ym9sZCB0ZXh0PC9zdHJvbmc+IGFuZCA8ZW0+aXRhbGljIHRleHQ8L2VtPi48L3A+XG4gICAgICAgICAgICA8dWw+XG4gICAgICAgICAgICAgICAgPGxpPkZpcnN0IGJ1bGxldCBwb2ludDwvbGk+XG4gICAgICAgICAgICAgICAgPGxpPlNlY29uZCBidWxsZXQgcG9pbnQ8L2xpPlxuICAgICAgICAgICAgICAgIDxsaT5UaGlyZCBidWxsZXQgcG9pbnQ8L2xpPlxuICAgICAgICAgICAgPC91bD5cbiAgICAgICAgICAgIDxwPkFub3RoZXIgcGFyYWdyYXBoIHdpdGggPGEgaHJlZj1cIiNcIj5hIHNhbXBsZSBsaW5rPC9hPi48L3A+XG4gICAgICAgIGA7XG5cbiAgICAgICAgdGhpcy52YWwoc2FtcGxlX2NvbnRlbnQpO1xuICAgIH1cbn1cbiIsImNsYXNzIFNlbGVjdF9JbnB1dCBleHRlbmRzIEZvcm1fSW5wdXRfQWJzdHJhY3Qge1xuICAgIG9uX2NyZWF0ZSgpIHtcbiAgICAgICAgdGhpcy5kYXRhLnZhbHVlID0gJyc7XG5cbiAgICAgICAgLy8gUGFyc2Ugb3B0aW9ucyBpZiBwYXNzZWQgYXMgSlNPTiBzdHJpbmdcbiAgICAgICAgaWYgKHR5cGVvZiB0aGlzLmFyZ3Mub3B0aW9ucyA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgLy8gRGVjb2RlIEhUTUwgZW50aXRpZXMgYmVmb3JlIHBhcnNpbmcgSlNPTlxuICAgICAgICAgICAgICAgIC8vIFRoaXMgaGFuZGxlcyBjYXNlcyB3aGVyZSBKU09OIGlzIHBhc3NlZCB0aHJvdWdoIEJsYWRlIHshISAhIX0gc3ludGF4XG4gICAgICAgICAgICAgICAgY29uc3QgZGVjb2RlZCA9ICQoJzx0ZXh0YXJlYT4nKS5odG1sKHRoaXMuYXJncy5vcHRpb25zKS50ZXh0KCk7XG4gICAgICAgICAgICAgICAgdGhpcy5hcmdzLm9wdGlvbnMgPSBqc29uX2RlY29kZShkZWNvZGVkKTtcbiAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKCdGYWlsZWQgdG8gcGFyc2Ugb3B0aW9ucyBKU09OOicsIGUpO1xuICAgICAgICAgICAgICAgIHRoaXMuYXJncy5vcHRpb25zID0gW107XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyBDb252ZXJ0IG9iamVjdCBvcHRpb25zIHRvIGFycmF5IGZvcm1hdFxuICAgICAgICBpZiAodGhpcy5hcmdzLm9wdGlvbnMgJiYgdHlwZW9mIHRoaXMuYXJncy5vcHRpb25zID09PSAnb2JqZWN0JyAmJiAhaXNfYXJyYXkodGhpcy5hcmdzLm9wdGlvbnMpKSB7XG4gICAgICAgICAgICB0aGlzLmFyZ3Mub3B0aW9ucyA9IE9iamVjdC5lbnRyaWVzKHRoaXMuYXJncy5vcHRpb25zKS5tYXAoKFt2YWx1ZSwgbGFiZWxdKSA9PiAoe3ZhbHVlLCBsYWJlbH0pKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIG9uX3JlYWR5KCkge1xuICAgICAgICAvLyBJbml0aWFsaXplIFRvbSBTZWxlY3RcbiAgICAgICAgbGV0IGNvbmZpZyA9IHtcbiAgICAgICAgICAgIHBsYWNlaG9sZGVyOiB0aGlzLmFyZ3MucGxhY2Vob2xkZXIgfHwgJycsXG4gICAgICAgICAgICBhbGxvd0VtcHR5T3B0aW9uOiB0cnVlLFxuICAgICAgICAgICAgY3JlYXRlOiBmYWxzZSxcbiAgICAgICAgICAgIG1heE9wdGlvbnM6IG51bGwsICAvLyBTaG93IGFsbCBvcHRpb25zIChkZWZhdWx0IGlzIDUwKVxuICAgICAgICAgICAgcGx1Z2luczogWydkcm9wZG93bl9pbnB1dCddLCAgLy8gRW5hYmxlIHNlYXJjaCBpbiBkcm9wZG93blxuICAgICAgICAgICAgb25Jbml0aWFsaXplOiBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgICAgICAvLyBLZWVwIEJvb3RzdHJhcCBmb3JtLXNlbGVjdCBjbGFzc1xuICAgICAgICAgICAgICAgIHRoaXMuY29udHJvbC5jbGFzc0xpc3QuYWRkKCdmb3JtLXNlbGVjdCcpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuXG4gICAgICAgIHRoaXMudG9tX3NlbGVjdCA9IG5ldyBUb21TZWxlY3QodGhpcy4kaWQoJ2lucHV0JykuZ2V0KDApLCBjb25maWcpO1xuXG4gICAgICAgIC8vIFNldCBpbml0aWFsIHZhbHVlIGlmIHByb3ZpZGVkXG4gICAgICAgIGlmICh0aGlzLmRhdGEudmFsdWUpIHtcbiAgICAgICAgICAgIHRoaXMudG9tX3NlbGVjdC5zZXRWYWx1ZSh0aGlzLmRhdGEudmFsdWUsIHRydWUpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogdmFsKCkgLSBHZXQgb3Igc2V0IHRoZSBzZWxlY3RlZCB2YWx1ZVxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbdmFsdWVdIC0gSWYgcHJvdmlkZWQsIHNldHMgdGhlIHZhbHVlXG4gICAgICogQHJldHVybnMge3N0cmluZ30gVGhlIGN1cnJlbnQgdmFsdWUgd2hlbiBjYWxsZWQgYXMgZ2V0dGVyXG4gICAgICovXG4gICAgdmFsKHZhbHVlKSB7XG4gICAgICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAvLyBHZXR0ZXJcbiAgICAgICAgICAgIGlmICh0aGlzLnRvbV9zZWxlY3QpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy50b21fc2VsZWN0LmdldFZhbHVlKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gdGhpcy4kaWQoJ2lucHV0JykudmFsKCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBTZXR0ZXJcbiAgICAgICAgICAgIHRoaXMuZGF0YS52YWx1ZSA9IHZhbHVlIHx8ICcnO1xuICAgICAgICAgICAgaWYgKHRoaXMudG9tX3NlbGVjdCkge1xuICAgICAgICAgICAgICAgIHRoaXMudG9tX3NlbGVjdC5zZXRWYWx1ZSh0aGlzLmRhdGEudmFsdWUsIHRydWUpO1xuICAgICAgICAgICAgfSBlbHNlIGlmICh0aGlzLiRpZCgnaW5wdXQnKS5leGlzdHMoKSkge1xuICAgICAgICAgICAgICAgIHRoaXMuJGlkKCdpbnB1dCcpLnZhbCh0aGlzLmRhdGEudmFsdWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgYXN5bmMgc2VlZCgpIHtcbiAgICAgICAgaWYgKHRoaXMuYXJncy5zZWVkZXIpIHtcbiAgICAgICAgICAgIC8vIFRPRE86IEltcGxlbWVudCBSc3hfUmFuZG9tX1ZhbHVlcyBlbmRwb2ludFxuICAgICAgICAgICAgbGV0IHZhbHVlID0gJ1Rlc3QgJyArICh0aGlzLmFyZ3Muc2VlZGVyIHx8ICdWYWx1ZScpO1xuICAgICAgICAgICAgdGhpcy52YWwodmFsdWUpO1xuICAgICAgICB9IGVsc2UgaWYgKHRoaXMuYXJncy5vcHRpb25zICYmIHRoaXMuYXJncy5vcHRpb25zLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIC8vIFNlbGVjdCByYW5kb20gb3B0aW9uXG4gICAgICAgICAgICBsZXQgcmFuZG9tX2luZGV4ID0gTWF0aC5mbG9vcihNYXRoLnJhbmRvbSgpICogdGhpcy5hcmdzLm9wdGlvbnMubGVuZ3RoKTtcbiAgICAgICAgICAgIGxldCByYW5kb21fb3B0ID0gdGhpcy5hcmdzLm9wdGlvbnNbcmFuZG9tX2luZGV4XTtcbiAgICAgICAgICAgIGxldCByYW5kb21fdmFsdWUgPSB0eXBlb2YgcmFuZG9tX29wdCA9PT0gJ29iamVjdCcgPyByYW5kb21fb3B0LnZhbHVlIDogcmFuZG9tX29wdDtcbiAgICAgICAgICAgIHRoaXMudmFsKHJhbmRvbV92YWx1ZSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBvbl9kZXN0cm95KCkge1xuICAgICAgICAvLyBDbGVhbiB1cCBUb20gU2VsZWN0IGluc3RhbmNlXG4gICAgICAgIGlmICh0aGlzLnRvbV9zZWxlY3QpIHtcbiAgICAgICAgICAgIHRoaXMudG9tX3NlbGVjdC5kZXN0cm95KCk7XG4gICAgICAgIH1cbiAgICB9XG59XG4iLCJjbGFzcyBBamF4X1NlbGVjdF9JbnB1dCBleHRlbmRzIFNlbGVjdF9JbnB1dCB7XG4gICAgb25fY3JlYXRlKCkge1xuICAgICAgICAvLyBJbml0aWFsaXplIGVtcHR5IHNlbGVjdCB2YWx1ZXMgYXJyYXlcbiAgICAgICAgdGhpcy5kYXRhLnNlbGVjdF92YWx1ZXMgPSBbXTtcblxuICAgICAgICAvLyBTdG9yZSBmb3IgdmFsdWUgc2V0IGJlZm9yZSBpbml0aWFsaXphdGlvbiBjb21wbGV0ZXNcbiAgICAgICAgdGhpcy5fcGVuZGluZ192YWx1ZSA9IG51bGw7XG5cbiAgICAgICAgLy8gQ2FsbCBwYXJlbnQgdG8gZG8gYmFzaWMgc2V0dXBcbiAgICAgICAgc3VwZXIub25fY3JlYXRlKCk7XG4gICAgfVxuXG4gICAgYXN5bmMgb25fbG9hZCgpIHtcbiAgICAgICAgLy8gTG9hZCBvcHRpb25zIGZyb20gQWpheCBlbmRwb2ludCBpZiBwcm92aWRlZFxuICAgICAgICBpZiAodGhpcy5hcmdzLmRhdGEpIHtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBmZXRjaCh0aGlzLmFyZ3MuZGF0YSk7XG4gICAgICAgICAgICAgICAgaWYgKCFyZXNwb25zZS5vaykge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEhUVFAgZXJyb3IhIHN0YXR1czogJHtyZXNwb25zZS5zdGF0dXN9YCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNvbnN0IGRhdGEgPSBhd2FpdCByZXNwb25zZS5qc29uKCk7XG4gICAgICAgICAgICAgICAgdGhpcy5kYXRhLnNlbGVjdF92YWx1ZXMgPSBkYXRhO1xuICAgICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKCdGYWlsZWQgdG8gbG9hZCBzZWxlY3Qgb3B0aW9uczonLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgdGhpcy5kYXRhLnNlbGVjdF92YWx1ZXMgPSBbXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIG9uX3JlYWR5KCkge1xuICAgICAgICAvLyBDYWxsIHBhcmVudCB0byBpbml0aWFsaXplIFRvbSBTZWxlY3RcbiAgICAgICAgc3VwZXIub25fcmVhZHkoKTtcblxuICAgICAgICAvLyBJZiBhIHZhbHVlIHdhcyBzZXQgYmVmb3JlIGluaXRpYWxpemF0aW9uLCBhcHBseSBpdCBub3dcbiAgICAgICAgaWYgKHRoaXMuX3BlbmRpbmdfdmFsdWUgIT09IG51bGwpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLnRvbV9zZWxlY3QpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnRvbV9zZWxlY3Quc2V0VmFsdWUodGhpcy5fcGVuZGluZ192YWx1ZSwgdHJ1ZSk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHRoaXMuJGlkKCdpbnB1dCcpLmV4aXN0cygpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy4kaWQoJ2lucHV0JykudmFsKHRoaXMuX3BlbmRpbmdfdmFsdWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5kYXRhLnZhbHVlID0gdGhpcy5fcGVuZGluZ192YWx1ZTtcbiAgICAgICAgICAgIHRoaXMuX3BlbmRpbmdfdmFsdWUgPSBudWxsO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogdmFsKCkgLSBHZXQgb3Igc2V0IHRoZSBzZWxlY3RlZCB2YWx1ZVxuICAgICAqIEhhbmRsZXMgY2FsbHMgYmVmb3JlIFRvbSBTZWxlY3QgaW5pdGlhbGl6YXRpb24gY29tcGxldGVzXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFt2YWx1ZV0gLSBJZiBwcm92aWRlZCwgc2V0cyB0aGUgdmFsdWVcbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBUaGUgY3VycmVudCB2YWx1ZSB3aGVuIGNhbGxlZCBhcyBnZXR0ZXJcbiAgICAgKi9cbiAgICB2YWwodmFsdWUpIHtcbiAgICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIC8vIEdldHRlclxuICAgICAgICAgICAgaWYgKHRoaXMudG9tX3NlbGVjdCkge1xuICAgICAgICAgICAgICAgIC8vIEluaXRpYWxpemVkIC0gZ2V0IGZyb20gVG9tIFNlbGVjdFxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLnRvbV9zZWxlY3QuZ2V0VmFsdWUoKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAodGhpcy5fcGVuZGluZ192YWx1ZSAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIC8vIE5vdCB5ZXQgaW5pdGlhbGl6ZWQgLSByZXR1cm4gcGVuZGluZyB2YWx1ZVxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9wZW5kaW5nX3ZhbHVlO1xuICAgICAgICAgICAgfSBlbHNlIGlmICh0aGlzLmRhdGEudmFsdWUpIHtcbiAgICAgICAgICAgICAgICAvLyBSZXR1cm4gZGF0YSB2YWx1ZVxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmRhdGEudmFsdWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gJyc7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBTZXR0ZXJcbiAgICAgICAgICAgIGlmICh0aGlzLnRvbV9zZWxlY3QpIHtcbiAgICAgICAgICAgICAgICAvLyBJbml0aWFsaXplZCAtIHNldCB2aWEgVG9tIFNlbGVjdFxuICAgICAgICAgICAgICAgIHRoaXMuZGF0YS52YWx1ZSA9IHZhbHVlIHx8ICcnO1xuICAgICAgICAgICAgICAgIHRoaXMudG9tX3NlbGVjdC5zZXRWYWx1ZSh0aGlzLmRhdGEudmFsdWUsIHRydWUpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAvLyBOb3QgeWV0IGluaXRpYWxpemVkIC0gc3RvcmUgZm9yIGxhdGVyXG4gICAgICAgICAgICAgICAgdGhpcy5fcGVuZGluZ192YWx1ZSA9IHZhbHVlIHx8ICcnO1xuICAgICAgICAgICAgICAgIHRoaXMuZGF0YS52YWx1ZSA9IHZhbHVlIHx8ICcnO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxufVxuIiwiLyoqXG4gKiBDdXJyZW5jeV9JbnB1dFxuICpcbiAqIEV4dGVuZHMgVGV4dF9JbnB1dCB0byBwcm92aWRlIGF1dG9tYXRpYyBjdXJyZW5jeSBmb3JtYXR0aW5nLlxuICpcbiAqIEZlYXR1cmVzOlxuICogLSBBZGRzIHRob3VzYW5kcyBzZXBhcmF0b3JzIChjb21tYXMpIGV2ZXJ5IDMgZGlnaXRzXG4gKiAtIE9wdGlvbmFsIGN1cnJlbmN5IHN5bWJvbCBwcmVmaXggKGRlZmF1bHQ6IGhpZGRlbilcbiAqIC0gT3B0aW9uYWwgZGVjaW1hbCBzdXBwb3J0IChkZWZhdWx0OiBkaXNhYmxlZClcbiAqIC0gU21hcnQgYmFja3NwYWNlIG92ZXIgZm9ybWF0dGluZyBjaGFyYWN0ZXJzXG4gKiAtIE5vIG1pZC1zdHJpbmcgZm9ybWF0dGluZyAod2FpdHMgZm9yIGJsdXIpXG4gKlxuICogQXJndW1lbnRzOlxuICogLSAkYWxsb3dfZGVjaW1hbHMgLSBBbGxvdyAyIGRlY2ltYWwgcGxhY2VzIChkZWZhdWx0OiBmYWxzZSlcbiAqIC0gJHNob3dfc3ltYm9sIC0gU2hvdyBjdXJyZW5jeSBzeW1ib2wgKGRlZmF1bHQ6IGZhbHNlKVxuICogLSAkY3VycmVuY3lfc3ltYm9sIC0gQ3VycmVuY3kgc3ltYm9sIHRvIHVzZSAoZGVmYXVsdDogXCIkXCIpXG4gKlxuICogVXNhZ2U6XG4gKiAgIDxDdXJyZW5jeV9JbnB1dCAvPlxuICogICA8Q3VycmVuY3lfSW5wdXQgJHNob3dfc3ltYm9sPXRydWUgLz5cbiAqICAgPEN1cnJlbmN5X0lucHV0ICRhbGxvd19kZWNpbWFscz10cnVlIC8+XG4gKiAgIDxDdXJyZW5jeV9JbnB1dCAkc2hvd19zeW1ib2w9dHJ1ZSAkYWxsb3dfZGVjaW1hbHM9dHJ1ZSAkY3VycmVuY3lfc3ltYm9sPVwi4oKsXCIgLz5cbiAqXG4gKiBCZWhhdmlvcjpcbiAqIC0gVHlwZSBcIjEyMzQ1NjdcIiAtPiBkaXNwbGF5cyBcIjEsMjM0LDU2N1wiLCB2YWwoKSByZXR1cm5zIFwiMTIzNDU2N1wiXG4gKiAtIFR5cGUgXCIxMjM0NTY3Ljg5XCIgKHdpdGggZGVjaW1hbHMpIC0+IGRpc3BsYXlzIFwiMSwyMzQsNTY3Ljg5XCIsIHZhbCgpIHJldHVybnMgXCIxMjM0NTY3Ljg5XCJcbiAqIC0gV2l0aCBzeW1ib2w6IGRpc3BsYXlzIFwiJDEsMjM0LDU2N1wiLCB2YWwoKSBzdGlsbCByZXR1cm5zIFwiMTIzNDU2N1wiXG4gKi9cbmNsYXNzIEN1cnJlbmN5X0lucHV0IGV4dGVuZHMgVGV4dF9JbnB1dCB7XG4gICAgb25fY3JlYXRlKCkge1xuICAgICAgICBzdXBlci5vbl9jcmVhdGUoKTtcblxuICAgICAgICAvLyBTZXQgZGVmYXVsdHMgZm9yIG9wdGlvbnNcbiAgICAgICAgaWYgKHRoaXMuYXJncy5hbGxvd19kZWNpbWFscyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICB0aGlzLmFyZ3MuYWxsb3dfZGVjaW1hbHMgPSBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5hcmdzLnNob3dfc3ltYm9sID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHRoaXMuYXJncy5zaG93X3N5bWJvbCA9IGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLmFyZ3MuY3VycmVuY3lfc3ltYm9sID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHRoaXMuYXJncy5jdXJyZW5jeV9zeW1ib2wgPSAnJCc7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBGb3JtYXQgY3VycmVuY3kgd2l0aCBjb21tYXMgYW5kIG9wdGlvbmFsIHN5bWJvbFxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSB2YWx1ZSAtIE51bWVyaWMgdmFsdWUgKG1heSBpbmNsdWRlIGRlY2ltYWwpXG4gICAgICogQHJldHVybnMge3N0cmluZ30gRm9ybWF0dGVkIGN1cnJlbmN5IHN0cmluZ1xuICAgICAqL1xuICAgIF9mb3JtYXRfY3VycmVuY3kodmFsdWUpIHtcbiAgICAgICAgaWYgKCF2YWx1ZSkge1xuICAgICAgICAgICAgcmV0dXJuICcnO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gU3BsaXQgaW50byBpbnRlZ2VyIGFuZCBkZWNpbWFsIHBhcnRzXG4gICAgICAgIGxldCBwYXJ0cyA9IHZhbHVlLnNwbGl0KCcuJyk7XG4gICAgICAgIGxldCBpbnRlZ2VyX3BhcnQgPSBwYXJ0c1swXTtcbiAgICAgICAgbGV0IGRlY2ltYWxfcGFydCA9IHBhcnRzWzFdO1xuXG4gICAgICAgIC8vIEFkZCBjb21tYXMgdG8gaW50ZWdlciBwYXJ0XG4gICAgICAgIGludGVnZXJfcGFydCA9IGludGVnZXJfcGFydC5yZXBsYWNlKC9cXEIoPz0oXFxkezN9KSsoPyFcXGQpKS9nLCAnLCcpO1xuXG4gICAgICAgIC8vIFJlY29uc3RydWN0IHdpdGggZGVjaW1hbCBpZiBhbGxvd2VkXG4gICAgICAgIGxldCBmb3JtYXR0ZWQgPSBpbnRlZ2VyX3BhcnQ7XG4gICAgICAgIGlmICh0aGlzLmFyZ3MuYWxsb3dfZGVjaW1hbHMgJiYgZGVjaW1hbF9wYXJ0ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIC8vIExpbWl0IHRvIDIgZGVjaW1hbCBwbGFjZXNcbiAgICAgICAgICAgIGRlY2ltYWxfcGFydCA9IGRlY2ltYWxfcGFydC5zdWJzdHIoMCwgMik7XG4gICAgICAgICAgICBmb3JtYXR0ZWQgKz0gJy4nICsgZGVjaW1hbF9wYXJ0O1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gQWRkIGN1cnJlbmN5IHN5bWJvbCBpZiBlbmFibGVkXG4gICAgICAgIGlmICh0aGlzLmFyZ3Muc2hvd19zeW1ib2wpIHtcbiAgICAgICAgICAgIGZvcm1hdHRlZCA9IHRoaXMuYXJncy5jdXJyZW5jeV9zeW1ib2wgKyBmb3JtYXR0ZWQ7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gZm9ybWF0dGVkO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEV4dHJhY3QgbnVtZXJpYyB2YWx1ZSBmcm9tIGZvcm1hdHRlZCBzdHJpbmdcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gZm9ybWF0dGVkIC0gRm9ybWF0dGVkIGN1cnJlbmN5IHN0cmluZ1xuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IENsZWFuIG51bWVyaWMgdmFsdWUgKGRpZ2l0cyBhbmQgZGVjaW1hbCBvbmx5KVxuICAgICAqL1xuICAgIF9nZXRfbnVtZXJpY192YWx1ZShmb3JtYXR0ZWQpIHtcbiAgICAgICAgaWYgKCFmb3JtYXR0ZWQpIHtcbiAgICAgICAgICAgIHJldHVybiAnJztcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFJlbW92ZSBjdXJyZW5jeSBzeW1ib2wgYW5kIGNvbW1hc1xuICAgICAgICBsZXQgY2xlYW5lZCA9IGZvcm1hdHRlZC5yZXBsYWNlKC9bXjAtOS5dL2csICcnKTtcblxuICAgICAgICAvLyBFbnN1cmUgb25seSBvbmUgZGVjaW1hbCBwb2ludFxuICAgICAgICBjb25zdCBkZWNpbWFsX2NvdW50ID0gKGNsZWFuZWQubWF0Y2goL1xcLi9nKSB8fCBbXSkubGVuZ3RoO1xuICAgICAgICBpZiAoZGVjaW1hbF9jb3VudCA+IDEpIHtcbiAgICAgICAgICAgIC8vIEtlZXAgb25seSBmaXJzdCBkZWNpbWFsIHBvaW50XG4gICAgICAgICAgICBjb25zdCBmaXJzdF9kZWNpbWFsID0gY2xlYW5lZC5pbmRleE9mKCcuJyk7XG4gICAgICAgICAgICBjbGVhbmVkID0gY2xlYW5lZC5zdWJzdHIoMCwgZmlyc3RfZGVjaW1hbCArIDEpICsgY2xlYW5lZC5zdWJzdHIoZmlyc3RfZGVjaW1hbCArIDEpLnJlcGxhY2UoL1xcLi9nLCAnJyk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gY2xlYW5lZDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiB2YWwoKSAtIEdldCBvciBzZXQgdGhlIGN1cnJlbmN5IHZhbHVlXG4gICAgICogR2V0dGVyIHJldHVybnMgbnVtZXJpYyBzdHJpbmcgKG5vIGNvbW1hcywgbm8gc3ltYm9sKVxuICAgICAqIFNldHRlciBhY2NlcHRzIGFueXRoaW5nIGFuZCBmb3JtYXRzIHdpdGggY29tbWFzL3N5bWJvbFxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbdmFsdWVdXG4gICAgICogQHJldHVybnMge3N0cmluZ31cbiAgICAgKi9cbiAgICB2YWwodmFsdWUpIHtcbiAgICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIC8vIEdldHRlciAtIHJldHVybiBudW1lcmljIHZhbHVlIG9ubHlcbiAgICAgICAgICAgIGNvbnN0IHJhdyA9IHRoaXMuJGlkKCdpbnB1dCcpLnZhbCgpO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2dldF9udW1lcmljX3ZhbHVlKHJhdyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBTZXR0ZXIgLSBmb3JtYXQgYW5kIGRpc3BsYXlcbiAgICAgICAgICAgIGlmICghdmFsdWUpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmRhdGEudmFsdWUgPSAnJztcbiAgICAgICAgICAgICAgICBpZiAodGhpcy4kaWQoJ2lucHV0JykuZXhpc3RzKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy4kaWQoJ2lucHV0JykudmFsKCcnKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBDbGVhbiB0aGUgaW5wdXQgdmFsdWVcbiAgICAgICAgICAgIGNvbnN0IG51bWVyaWMgPSB0aGlzLl9nZXRfbnVtZXJpY192YWx1ZShzdHIodmFsdWUpKTtcbiAgICAgICAgICAgIGNvbnN0IGZvcm1hdHRlZCA9IHRoaXMuX2Zvcm1hdF9jdXJyZW5jeShudW1lcmljKTtcblxuICAgICAgICAgICAgdGhpcy5kYXRhLnZhbHVlID0gZm9ybWF0dGVkO1xuICAgICAgICAgICAgaWYgKHRoaXMuJGlkKCdpbnB1dCcpLmV4aXN0cygpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy4kaWQoJ2lucHV0JykudmFsKGZvcm1hdHRlZCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBvbl9yZWFkeSgpIHtcbiAgICAgICAgc3VwZXIub25fcmVhZHkoKTtcblxuICAgICAgICBjb25zdCAkaW5wdXQgPSB0aGlzLiRpZCgnaW5wdXQnKTtcblxuICAgICAgICAvLyBIYW5kbGUga2V5ZG93biB0byBpbnRlcmNlcHQgYmFja3NwYWNlIGF0IGVuZCBvZiBzdHJpbmdcbiAgICAgICAgJGlucHV0Lm9uKCdrZXlkb3duJywgKGUpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHJhdyA9ICRpbnB1dC52YWwoKTtcblxuICAgICAgICAgICAgLy8gT25seSBoYW5kbGUgYmFja3NwYWNlIGtleVxuICAgICAgICAgICAgaWYgKGUua2V5ICE9PSAnQmFja3NwYWNlJykge1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uc3QgaW5wdXRfZWxlbWVudCA9ICRpbnB1dFswXTtcbiAgICAgICAgICAgIGNvbnN0IGN1cnNvcl9wb3MgPSBpbnB1dF9lbGVtZW50LnNlbGVjdGlvblN0YXJ0O1xuICAgICAgICAgICAgY29uc3QgY3Vyc29yX2VuZCA9IGlucHV0X2VsZW1lbnQuc2VsZWN0aW9uRW5kO1xuICAgICAgICAgICAgY29uc3QgdmFsdWVfbGVuZ3RoID0gcmF3Lmxlbmd0aDtcblxuICAgICAgICAgICAgLy8gT25seSBoYW5kbGUgaWYgY3Vyc29yIGlzIGF0IHRoZSBlbmQgYW5kIG5vIHNlbGVjdGlvblxuICAgICAgICAgICAgaWYgKGN1cnNvcl9wb3MgPT09IHZhbHVlX2xlbmd0aCAmJiBjdXJzb3JfcG9zID09PSBjdXJzb3JfZW5kKSB7XG4gICAgICAgICAgICAgICAgLy8gQ2hlY2sgaWYgY2hhcmFjdGVyIGJlZm9yZSBjdXJzb3IgaXMgbm9uLW51bWVyaWNcbiAgICAgICAgICAgICAgICBpZiAoY3Vyc29yX3BvcyA+IDApIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhcl9iZWZvcmUgPSByYXcuY2hhckF0KGN1cnNvcl9wb3MgLSAxKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCEvWzAtOV0vLnRlc3QoY2hhcl9iZWZvcmUpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBDaGFyYWN0ZXIgYmVmb3JlIGN1cnNvciBpcyBub3QgYSBkaWdpdFxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gRGVsZXRlIHRoZSBsYXN0IGRpZ2l0IGluc3RlYWRcbiAgICAgICAgICAgICAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbnVtZXJpYyA9IHRoaXMuX2dldF9udW1lcmljX3ZhbHVlKHJhdyk7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAobnVtZXJpYy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gUmVtb3ZlIGxhc3QgY2hhcmFjdGVyIGZyb20gbnVtZXJpYyB2YWx1ZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG5ld19udW1lcmljID0gbnVtZXJpYy5zdWJzdHIoMCwgbnVtZXJpYy5sZW5ndGggLSAxKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBmb3JtYXR0ZWQgPSB0aGlzLl9mb3JtYXRfY3VycmVuY3kobmV3X251bWVyaWMpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICRpbnB1dC52YWwoZm9ybWF0dGVkKTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFBsYWNlIGN1cnNvciBhdCBlbmRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbmV3X2xlbmd0aCA9ICRpbnB1dC52YWwoKS5sZW5ndGg7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlucHV0X2VsZW1lbnQuc2V0U2VsZWN0aW9uUmFuZ2UobmV3X2xlbmd0aCwgbmV3X2xlbmd0aCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSwgMCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIEhhbmRsZSBpbnB1dCBldmVudCBmb3IgbGl2ZSBmb3JtYXR0aW5nXG4gICAgICAgICRpbnB1dC5vbignaW5wdXQnLCAoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCByYXcgPSAkaW5wdXQudmFsKCk7XG4gICAgICAgICAgICBjb25zdCBpbnB1dF9lbGVtZW50ID0gJGlucHV0WzBdO1xuICAgICAgICAgICAgY29uc3QgY3Vyc29yX3BvcyA9IGlucHV0X2VsZW1lbnQuc2VsZWN0aW9uU3RhcnQ7XG4gICAgICAgICAgICBjb25zdCB2YWx1ZV9sZW5ndGggPSByYXcubGVuZ3RoO1xuXG4gICAgICAgICAgICAvLyBPbmx5IGFwcGx5IGxpdmUgZm9ybWF0dGluZyBpZiBjdXJzb3IgaXMgYXQgdGhlIGVuZFxuICAgICAgICAgICAgaWYgKGN1cnNvcl9wb3MgPT09IHZhbHVlX2xlbmd0aCkge1xuICAgICAgICAgICAgICAgIC8vIEV4dHJhY3QgbnVtZXJpYyB2YWx1ZVxuICAgICAgICAgICAgICAgIGxldCBudW1lcmljID0gdGhpcy5fZ2V0X251bWVyaWNfdmFsdWUocmF3KTtcblxuICAgICAgICAgICAgICAgIC8vIExpbWl0IGRlY2ltYWwgcGxhY2VzIHRvIDIgaWYgZGVjaW1hbHMgYWxsb3dlZFxuICAgICAgICAgICAgICAgIGlmICh0aGlzLmFyZ3MuYWxsb3dfZGVjaW1hbHMpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcGFydHMgPSBudW1lcmljLnNwbGl0KCcuJyk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChwYXJ0c1sxXSAmJiBwYXJ0c1sxXS5sZW5ndGggPiAyKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBudW1lcmljID0gcGFydHNbMF0gKyAnLicgKyBwYXJ0c1sxXS5zdWJzdHIoMCwgMik7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAvLyBGb3JtYXQgdGhlIG51bWVyaWMgdmFsdWVcbiAgICAgICAgICAgICAgICBjb25zdCBmb3JtYXR0ZWQgPSB0aGlzLl9mb3JtYXRfY3VycmVuY3kobnVtZXJpYyk7XG4gICAgICAgICAgICAgICAgJGlucHV0LnZhbChmb3JtYXR0ZWQpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAvLyBDdXJzb3IgaXMgbm90IGF0IGVuZCAtIHVzZXIgaXMgZWRpdGluZyBpbiB0aGUgbWlkZGxlXG4gICAgICAgICAgICAgICAgLy8gRG9uJ3QgZm9ybWF0LCBqdXN0IGNsZWFuIGludmFsaWQgY2hhcmFjdGVyc1xuICAgICAgICAgICAgICAgIGNvbnN0IG51bWVyaWMgPSB0aGlzLl9nZXRfbnVtZXJpY192YWx1ZShyYXcpO1xuXG4gICAgICAgICAgICAgICAgLy8gT25seSB1cGRhdGUgaWYgd2UgcmVtb3ZlZCBpbnZhbGlkIGNoYXJhY3RlcnNcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5fZm9ybWF0X2N1cnJlbmN5KG51bWVyaWMpICE9PSByYXcpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gUHJlc2VydmUganVzdCB0aGUgbnVtZXJpYyBjaGFyYWN0ZXJzXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHN5bWJvbF9vZmZzZXQgPSB0aGlzLmFyZ3Muc2hvd19zeW1ib2wgPyB0aGlzLmFyZ3MuY3VycmVuY3lfc3ltYm9sLmxlbmd0aCA6IDA7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGNsZWFuZWQgPSAodGhpcy5hcmdzLnNob3dfc3ltYm9sID8gdGhpcy5hcmdzLmN1cnJlbmN5X3N5bWJvbCA6ICcnKSArIG51bWVyaWM7XG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKGNsZWFuZWQgIT09IHJhdykge1xuICAgICAgICAgICAgICAgICAgICAgICAgJGlucHV0LnZhbChjbGVhbmVkKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIFJlc3RvcmUgY3Vyc29yIHBvc2l0aW9uIChhcHByb3hpbWF0ZWx5KVxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbmV3X2N1cnNvciA9IE1hdGgubWluKGN1cnNvcl9wb3MsIGNsZWFuZWQubGVuZ3RoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlucHV0X2VsZW1lbnQuc2V0U2VsZWN0aW9uUmFuZ2UobmV3X2N1cnNvciwgbmV3X2N1cnNvcik7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIEhhbmRsZSBibHVyIHRvIHJlZm9ybWF0IHdoZW4gZG9uZSBlZGl0aW5nXG4gICAgICAgICRpbnB1dC5vbignYmx1cicsICgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHJhdyA9ICRpbnB1dC52YWwoKTtcblxuICAgICAgICAgICAgaWYgKCFyYXcpIHtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIFJlZm9ybWF0IHRoZSBlbnRpcmUgdmFsdWUgb24gYmx1clxuICAgICAgICAgICAgY29uc3QgbnVtZXJpYyA9IHRoaXMuX2dldF9udW1lcmljX3ZhbHVlKHJhdyk7XG4gICAgICAgICAgICBjb25zdCBmb3JtYXR0ZWQgPSB0aGlzLl9mb3JtYXRfY3VycmVuY3kobnVtZXJpYyk7XG4gICAgICAgICAgICAkaW5wdXQudmFsKGZvcm1hdHRlZCk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIEhhbmRsZSBmb2N1cyB0byBzZWxlY3QgYWxsIGZvciBlYXN5IHJlcGxhY2VtZW50XG4gICAgICAgICRpbnB1dC5vbignZm9jdXMnLCAoKSA9PiB7XG4gICAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgICAgICAkaW5wdXRbMF0uc2VsZWN0KCk7XG4gICAgICAgICAgICB9LCAwKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gSW5pdGlhbGl6ZSBmb3JtYXR0aW5nIGlmIHRoZXJlJ3MgYSB2YWx1ZVxuICAgICAgICBjb25zdCBpbml0aWFsX3ZhbHVlID0gJGlucHV0LnZhbCgpO1xuICAgICAgICBpZiAoaW5pdGlhbF92YWx1ZSkge1xuICAgICAgICAgICAgdGhpcy52YWwoaW5pdGlhbF92YWx1ZSk7XG4gICAgICAgIH1cbiAgICB9XG59XG4iLCIvKipcbiAqIFBob25lX1RleHRfSW5wdXRcbiAqXG4gKiBFeHRlbmRzIFRleHRfSW5wdXQgdG8gcHJvdmlkZSBhdXRvbWF0aWMgcGhvbmUgbnVtYmVyIGZvcm1hdHRpbmcuXG4gKlxuICogRmVhdHVyZXM6XG4gKiAtIFVTIE1vZGUgKGRlZmF1bHQpOiBGb3JtYXRzIGFzIChYWFgpIFhYWC1YWFhYIG9uIGV2ZXJ5IGtleXN0cm9rZVxuICogLSBJbnRlcm5hdGlvbmFsIE1vZGU6IFRyaWdnZXJlZCBieSBzdGFydGluZyB3aXRoICcrJywgZGlzYWJsZXMgZm9ybWF0dGluZ1xuICogLSB2YWwoKSBnZXR0ZXIgcmV0dXJucyBmb3JtYXR0ZWQgc3RyaW5nIGFzIGRpc3BsYXllZFxuICogLSB2YWwoKSBzZXR0ZXIgYWNjZXB0cyBhbnkgZm9ybWF0IGFuZCBkaXNwbGF5cyBhcHByb3ByaWF0ZWx5XG4gKlxuICogVXNhZ2U6XG4gKiAgIDxQaG9uZV9UZXh0X0lucHV0ICRwbGFjZWhvbGRlcj1cIlBob25lIG51bWJlclwiIC8+XG4gKlxuICogQmVoYXZpb3I6XG4gKiAtIFR5cGUgXCI1NTUxMjM0NTY3XCIgLT4gZGlzcGxheXMgXCIoNTU1KSAxMjMtNDU2N1wiLCB2YWwoKSByZXR1cm5zIFwiKDU1NSkgMTIzLTQ1NjdcIlxuICogLSBUeXBlIFwiKzQ0IDIwIDcxMjMgNDU2N1wiIC0+IGRpc3BsYXlzIGFzIHR5cGVkLCB2YWwoKSByZXR1cm5zIFwiKzQ0IDIwIDcxMjMgNDU2N1wiXG4gKiAtIExlYWRpbmcgXCIxXCIgaXMgc3RyaXBwZWQ6IFwiMTU1NTEyMzQ1NjdcIiAtPiBcIig1NTUpIDEyMy00NTY3XCJcbiAqL1xuY2xhc3MgUGhvbmVfVGV4dF9JbnB1dCBleHRlbmRzIFRleHRfSW5wdXQge1xuICAgIG9uX2NyZWF0ZSgpIHtcbiAgICAgICAgc3VwZXIub25fY3JlYXRlKCk7XG4gICAgICAgIHRoaXMuX2lzX2ludGVybmF0aW9uYWwgPSBmYWxzZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDaGVjayBpZiBpbnB1dCBpcyBpbiBpbnRlcm5hdGlvbmFsIG1vZGUgKHN0YXJ0cyB3aXRoICspXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHZhbHVlXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59XG4gICAgICovXG4gICAgX2NoZWNrX2ludGVybmF0aW9uYWxfbW9kZSh2YWx1ZSkge1xuICAgICAgICByZXR1cm4gdmFsdWUgJiYgc3RyKHZhbHVlKS5jaGFyQXQoMCkgPT09ICcrJztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBGb3JtYXQgVVMgcGhvbmUgbnVtYmVyIGFzIChYWFgpIFhYWC1YWFhYXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGRpZ2l0cyAtIENsZWFuIG51bWVyaWMgc3RyaW5nIChzaG91bGQgYmUgMTAgZGlnaXRzIG9yIGxlc3MgYWZ0ZXIgcHJvY2Vzc2luZylcbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBGb3JtYXR0ZWQgcGhvbmUgbnVtYmVyXG4gICAgICovXG4gICAgX2Zvcm1hdF91c19waG9uZShkaWdpdHMpIHtcbiAgICAgICAgLy8gRm9ybWF0IGJhc2VkIG9uIGxlbmd0aCAoYXNzdW1lcyBkaWdpdHMgYXJlIGFscmVhZHkgY2xlYW5lZCBhbmQgbGltaXRlZCB0byAxMClcbiAgICAgICAgaWYgKGRpZ2l0cy5sZW5ndGggPj0gNikge1xuICAgICAgICAgICAgLy8gKFhYWCkgWFhYLVhYWFhcbiAgICAgICAgICAgIHJldHVybiAnKCcgKyBkaWdpdHMuc3Vic3RyKDAsIDMpICsgJykgJyArIGRpZ2l0cy5zdWJzdHIoMywgMykgKyAnLScgKyBkaWdpdHMuc3Vic3RyKDYpO1xuICAgICAgICB9IGVsc2UgaWYgKGRpZ2l0cy5sZW5ndGggPj0gMykge1xuICAgICAgICAgICAgLy8gKFhYWCkgWFhYXG4gICAgICAgICAgICByZXR1cm4gJygnICsgZGlnaXRzLnN1YnN0cigwLCAzKSArICcpICcgKyBkaWdpdHMuc3Vic3RyKDMpO1xuICAgICAgICB9IGVsc2UgaWYgKGRpZ2l0cy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAvLyAoWFhcbiAgICAgICAgICAgIHJldHVybiAnKCcgKyBkaWdpdHM7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gZGlnaXRzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIHZhbCgpIC0gR2V0IG9yIHNldCB0aGUgcGhvbmUgbnVtYmVyXG4gICAgICogR2V0dGVyIHJldHVybnMgZm9ybWF0dGVkIHZhbHVlIGFzIGRpc3BsYXllZCAod2l0aCBwYXJlbnMsIGRhc2hlcywgZXRjKVxuICAgICAqIFNldHRlciBhY2NlcHRzIGFueXRoaW5nIGFuZCBmb3JtYXRzIGFwcHJvcHJpYXRlbHlcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW3ZhbHVlXVxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9XG4gICAgICovXG4gICAgdmFsKHZhbHVlKSB7XG4gICAgICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAvLyBHZXR0ZXIgLSByZXR1cm4gdGhlIGZvcm1hdHRlZCB2YWx1ZSBhcyBkaXNwbGF5ZWRcbiAgICAgICAgICAgIHJldHVybiB0aGlzLiRpZCgnaW5wdXQnKS52YWwoKSB8fCAnJztcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIFNldHRlciAtIGZvcm1hdCBhbmQgZGlzcGxheVxuICAgICAgICAgICAgaWYgKCF2YWx1ZSkge1xuICAgICAgICAgICAgICAgIHRoaXMuZGF0YS52YWx1ZSA9ICcnO1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLiRpZCgnaW5wdXQnKS5leGlzdHMoKSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLiRpZCgnaW5wdXQnKS52YWwoJycpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbnN0IHN0cl92YWx1ZSA9IHN0cih2YWx1ZSk7XG5cbiAgICAgICAgICAgIGlmICh0aGlzLl9jaGVja19pbnRlcm5hdGlvbmFsX21vZGUoc3RyX3ZhbHVlKSkge1xuICAgICAgICAgICAgICAgIC8vIEludGVybmF0aW9uYWwgbW9kZSAtIG5vIGZvcm1hdHRpbmdcbiAgICAgICAgICAgICAgICB0aGlzLmRhdGEudmFsdWUgPSBzdHJfdmFsdWU7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuJGlkKCdpbnB1dCcpLmV4aXN0cygpKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuJGlkKCdpbnB1dCcpLnZhbChzdHJfdmFsdWUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgLy8gVVMgbW9kZSAtIGNsZWFuIGRpZ2l0cyBhbmQgZm9ybWF0XG4gICAgICAgICAgICAgICAgY29uc3QgZGlnaXRzID0gc3RyX3ZhbHVlLnJlcGxhY2UoL1teMC05XS9nLCAnJyk7XG5cbiAgICAgICAgICAgICAgICAvLyBEZXRlcm1pbmUgd2hpY2ggZGlnaXRzIHRvIGZvcm1hdFxuICAgICAgICAgICAgICAgIGxldCBkaWdpdHNfdG9fZm9ybWF0O1xuICAgICAgICAgICAgICAgIGlmIChkaWdpdHMubGVuZ3RoID09PSAxMSAmJiBkaWdpdHMuY2hhckF0KDApID09PSAnMScgJiYgL1syLTldLy50ZXN0KGRpZ2l0cy5jaGFyQXQoMSkpKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIFN0cmlwIFVTIGNvdW50cnkgY29kZVxuICAgICAgICAgICAgICAgICAgICBkaWdpdHNfdG9fZm9ybWF0ID0gZGlnaXRzLnN1YnN0cigxKTtcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGRpZ2l0cy5sZW5ndGggPiAxMCkge1xuICAgICAgICAgICAgICAgICAgICAvLyBUYWtlIGZpcnN0IDEwXG4gICAgICAgICAgICAgICAgICAgIGRpZ2l0c190b19mb3JtYXQgPSBkaWdpdHMuc3Vic3RyKDAsIDEwKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAvLyBVc2UgYXMtaXNcbiAgICAgICAgICAgICAgICAgICAgZGlnaXRzX3RvX2Zvcm1hdCA9IGRpZ2l0cztcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBjb25zdCBmb3JtYXR0ZWQgPSB0aGlzLl9mb3JtYXRfdXNfcGhvbmUoZGlnaXRzX3RvX2Zvcm1hdCk7XG4gICAgICAgICAgICAgICAgdGhpcy5kYXRhLnZhbHVlID0gZm9ybWF0dGVkO1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLiRpZCgnaW5wdXQnKS5leGlzdHMoKSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLiRpZCgnaW5wdXQnKS52YWwoZm9ybWF0dGVkKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBvbl9yZWFkeSgpIHtcbiAgICAgICAgc3VwZXIub25fcmVhZHkoKTtcblxuICAgICAgICBjb25zdCAkaW5wdXQgPSB0aGlzLiRpZCgnaW5wdXQnKTtcbiAgICAgICAgbGV0IF9sYXN0X2N1cnNvcl9wb3NpdGlvbiA9IG51bGw7XG5cbiAgICAgICAgLy8gSGFuZGxlIGtleWRvd24gdG8gaW50ZXJjZXB0IGJhY2tzcGFjZSBhdCBlbmQgb2Ygc3RyaW5nXG4gICAgICAgICRpbnB1dC5vbigna2V5ZG93bicsIChlKSA9PiB7XG4gICAgICAgICAgICBjb25zdCByYXcgPSAkaW5wdXQudmFsKCk7XG5cbiAgICAgICAgICAgIC8vIFNraXAgaWYgaW50ZXJuYXRpb25hbCBtb2RlXG4gICAgICAgICAgICBpZiAodGhpcy5fY2hlY2tfaW50ZXJuYXRpb25hbF9tb2RlKHJhdykpIHtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIE9ubHkgaGFuZGxlIGJhY2tzcGFjZSBrZXlcbiAgICAgICAgICAgIGlmIChlLmtleSAhPT0gJ0JhY2tzcGFjZScpIHtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbnN0IGlucHV0X2VsZW1lbnQgPSAkaW5wdXRbMF07XG4gICAgICAgICAgICBjb25zdCBjdXJzb3JfcG9zID0gaW5wdXRfZWxlbWVudC5zZWxlY3Rpb25TdGFydDtcbiAgICAgICAgICAgIGNvbnN0IGN1cnNvcl9lbmQgPSBpbnB1dF9lbGVtZW50LnNlbGVjdGlvbkVuZDtcbiAgICAgICAgICAgIGNvbnN0IHZhbHVlX2xlbmd0aCA9IHJhdy5sZW5ndGg7XG5cbiAgICAgICAgICAgIC8vIE9ubHkgaGFuZGxlIGlmIGN1cnNvciBpcyBhdCB0aGUgZW5kIGFuZCBubyBzZWxlY3Rpb25cbiAgICAgICAgICAgIGlmIChjdXJzb3JfcG9zID09PSB2YWx1ZV9sZW5ndGggJiYgY3Vyc29yX3BvcyA9PT0gY3Vyc29yX2VuZCkge1xuICAgICAgICAgICAgICAgIC8vIENoZWNrIGlmIGNoYXJhY3RlciBiZWZvcmUgY3Vyc29yIGlzIG5vbi1udW1lcmljXG4gICAgICAgICAgICAgICAgaWYgKGN1cnNvcl9wb3MgPiAwKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXJfYmVmb3JlID0gcmF3LmNoYXJBdChjdXJzb3JfcG9zIC0gMSk7XG4gICAgICAgICAgICAgICAgICAgIGlmICghL1swLTldLy50ZXN0KGNoYXJfYmVmb3JlKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gQ2hhcmFjdGVyIGJlZm9yZSBjdXJzb3IgaXMgbm90IGEgZGlnaXRcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIERlbGV0ZSB0aGUgbGFzdCBkaWdpdCBpbnN0ZWFkXG4gICAgICAgICAgICAgICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGRpZ2l0cyA9IHJhdy5yZXBsYWNlKC9bXjAtOV0vZywgJycpO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGRpZ2l0cy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbmV3X2RpZ2l0cyA9IGRpZ2l0cy5zdWJzdHIoMCwgZGlnaXRzLmxlbmd0aCAtIDEpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGZvcm1hdHRlZCA9IHRoaXMuX2Zvcm1hdF91c19waG9uZShuZXdfZGlnaXRzKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkaW5wdXQudmFsKGZvcm1hdHRlZCk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBQbGFjZSBjdXJzb3IgYXQgZW5kXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG5ld19sZW5ndGggPSAkaW5wdXQudmFsKCkubGVuZ3RoO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnB1dF9lbGVtZW50LnNldFNlbGVjdGlvblJhbmdlKG5ld19sZW5ndGgsIG5ld19sZW5ndGgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sIDApO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgICAgICAvLyBIYW5kbGUgaW5wdXQgZXZlbnQgZm9yIGxpdmUgZm9ybWF0dGluZ1xuICAgICAgICAkaW5wdXQub24oJ2lucHV0JywgKCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgcmF3ID0gJGlucHV0LnZhbCgpO1xuXG4gICAgICAgICAgICBpZiAodGhpcy5fY2hlY2tfaW50ZXJuYXRpb25hbF9tb2RlKHJhdykpIHtcbiAgICAgICAgICAgICAgICAvLyBJbnRlcm5hdGlvbmFsIG1vZGUgLSBhbGxvdyBhbnl0aGluZ1xuICAgICAgICAgICAgICAgIHRoaXMuX2lzX2ludGVybmF0aW9uYWwgPSB0cnVlO1xuICAgICAgICAgICAgICAgIC8vIE5vIGZvcm1hdHRpbmcsIG5vIHJlc3RyaWN0aW9uc1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gVVMgbW9kZVxuICAgICAgICAgICAgdGhpcy5faXNfaW50ZXJuYXRpb25hbCA9IGZhbHNlO1xuXG4gICAgICAgICAgICBjb25zdCBpbnB1dF9lbGVtZW50ID0gJGlucHV0WzBdO1xuICAgICAgICAgICAgY29uc3QgY3Vyc29yX3BvcyA9IGlucHV0X2VsZW1lbnQuc2VsZWN0aW9uU3RhcnQ7XG4gICAgICAgICAgICBjb25zdCB2YWx1ZV9sZW5ndGggPSByYXcubGVuZ3RoO1xuXG4gICAgICAgICAgICAvLyBPbmx5IGFwcGx5IGxpdmUgZm9ybWF0dGluZyBpZiBjdXJzb3IgaXMgYXQgdGhlIGVuZFxuICAgICAgICAgICAgaWYgKGN1cnNvcl9wb3MgPT09IHZhbHVlX2xlbmd0aCkge1xuICAgICAgICAgICAgICAgIC8vIFJlbW92ZSBhbnkgbm9uLWRpZ2l0LCBub24tZm9ybWF0dGluZyBjaGFyYWN0ZXJzXG4gICAgICAgICAgICAgICAgY29uc3QgY2xlYW5lZCA9IHJhdy5yZXBsYWNlKC9bXjAtOVxcc1xcLSgpXS9nLCAnJyk7XG4gICAgICAgICAgICAgICAgY29uc3QgZGlnaXRzID0gY2xlYW5lZC5yZXBsYWNlKC9bXjAtOV0vZywgJycpO1xuXG4gICAgICAgICAgICAgICAgLy8gRGV0ZXJtaW5lIHdoaWNoIGRpZ2l0cyB0byBmb3JtYXRcbiAgICAgICAgICAgICAgICBsZXQgZGlnaXRzX3RvX2Zvcm1hdDtcblxuICAgICAgICAgICAgICAgIGlmIChkaWdpdHMubGVuZ3RoID09PSAxMSAmJiBkaWdpdHMuY2hhckF0KDApID09PSAnMScgJiYgL1syLTldLy50ZXN0KGRpZ2l0cy5jaGFyQXQoMSkpKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIEV4YWN0bHkgMTEgZGlnaXRzIHN0YXJ0aW5nIHdpdGggXCIxXCIgZm9sbG93ZWQgYnkgdmFsaWQgYXJlYSBjb2RlIGRpZ2l0ICgyLTkpXG4gICAgICAgICAgICAgICAgICAgIC8vIFRoaXMgaXMgYSBVUyBjb3VudHJ5IGNvZGUgLSBzdHJpcCB0aGUgbGVhZGluZyAxXG4gICAgICAgICAgICAgICAgICAgIGRpZ2l0c190b19mb3JtYXQgPSBkaWdpdHMuc3Vic3RyKDEpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoZGlnaXRzLmxlbmd0aCA+IDEwKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIE1vcmUgdGhhbiAxMCBkaWdpdHMgLSBqdXN0IHRha2UgdGhlIGZpcnN0IDEwIGFuZCBpZ25vcmUgdGhlIHJlc3RcbiAgICAgICAgICAgICAgICAgICAgZGlnaXRzX3RvX2Zvcm1hdCA9IGRpZ2l0cy5zdWJzdHIoMCwgMTApO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIDEwIG9yIGZld2VyIGRpZ2l0cyAtIHVzZSBhcy1pc1xuICAgICAgICAgICAgICAgICAgICBkaWdpdHNfdG9fZm9ybWF0ID0gZGlnaXRzO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIC8vIEZvcm1hdCB0aGUgZGlnaXRzXG4gICAgICAgICAgICAgICAgY29uc3QgZm9ybWF0dGVkID0gdGhpcy5fZm9ybWF0X3VzX3Bob25lKGRpZ2l0c190b19mb3JtYXQpO1xuICAgICAgICAgICAgICAgICRpbnB1dC52YWwoZm9ybWF0dGVkKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgLy8gQ3Vyc29yIGlzIG5vdCBhdCBlbmQgLSB1c2VyIGlzIGVkaXRpbmcgaW4gdGhlIG1pZGRsZVxuICAgICAgICAgICAgICAgIC8vIERvbid0IGZvcm1hdCwganVzdCBjbGVhbiBpbnZhbGlkIGNoYXJhY3RlcnNcbiAgICAgICAgICAgICAgICBjb25zdCBjbGVhbmVkID0gcmF3LnJlcGxhY2UoL1teMC05XFxzXFwtKCldL2csICcnKTtcbiAgICAgICAgICAgICAgICBpZiAoY2xlYW5lZCAhPT0gcmF3KSB7XG4gICAgICAgICAgICAgICAgICAgICRpbnB1dC52YWwoY2xlYW5lZCk7XG4gICAgICAgICAgICAgICAgICAgIC8vIFJlc3RvcmUgY3Vyc29yIHBvc2l0aW9uXG4gICAgICAgICAgICAgICAgICAgIGlucHV0X2VsZW1lbnQuc2V0U2VsZWN0aW9uUmFuZ2UoY3Vyc29yX3BvcywgY3Vyc29yX3Bvcyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgICAgICAvLyBIYW5kbGUgYmx1ciB0byByZWZvcm1hdCB3aGVuIGRvbmUgZWRpdGluZ1xuICAgICAgICAkaW5wdXQub24oJ2JsdXInLCAoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCByYXcgPSAkaW5wdXQudmFsKCk7XG5cbiAgICAgICAgICAgIC8vIFNraXAgaWYgaW50ZXJuYXRpb25hbCBtb2RlIG9yIGVtcHR5XG4gICAgICAgICAgICBpZiAodGhpcy5fY2hlY2tfaW50ZXJuYXRpb25hbF9tb2RlKHJhdykgfHwgIXJhdykge1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gUmVmb3JtYXQgdGhlIGVudGlyZSB2YWx1ZSBvbiBibHVyXG4gICAgICAgICAgICBjb25zdCBkaWdpdHMgPSByYXcucmVwbGFjZSgvW14wLTldL2csICcnKTtcblxuICAgICAgICAgICAgLy8gRGV0ZXJtaW5lIHdoaWNoIGRpZ2l0cyB0byBmb3JtYXRcbiAgICAgICAgICAgIGxldCBkaWdpdHNfdG9fZm9ybWF0O1xuXG4gICAgICAgICAgICBpZiAoZGlnaXRzLmxlbmd0aCA9PT0gMTEgJiYgZGlnaXRzLmNoYXJBdCgwKSA9PT0gJzEnICYmIC9bMi05XS8udGVzdChkaWdpdHMuY2hhckF0KDEpKSkge1xuICAgICAgICAgICAgICAgIC8vIEV4YWN0bHkgMTEgZGlnaXRzIHN0YXJ0aW5nIHdpdGggXCIxXCIgZm9sbG93ZWQgYnkgdmFsaWQgYXJlYSBjb2RlIGRpZ2l0ICgyLTkpXG4gICAgICAgICAgICAgICAgLy8gVGhpcyBpcyBhIFVTIGNvdW50cnkgY29kZSAtIHN0cmlwIHRoZSBsZWFkaW5nIDFcbiAgICAgICAgICAgICAgICBkaWdpdHNfdG9fZm9ybWF0ID0gZGlnaXRzLnN1YnN0cigxKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoZGlnaXRzLmxlbmd0aCA+IDEwKSB7XG4gICAgICAgICAgICAgICAgLy8gTW9yZSB0aGFuIDEwIGRpZ2l0cyAtIGp1c3QgdGFrZSB0aGUgZmlyc3QgMTBcbiAgICAgICAgICAgICAgICBkaWdpdHNfdG9fZm9ybWF0ID0gZGlnaXRzLnN1YnN0cigwLCAxMCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIC8vIDEwIG9yIGZld2VyIGRpZ2l0cyAtIHVzZSBhcy1pc1xuICAgICAgICAgICAgICAgIGRpZ2l0c190b19mb3JtYXQgPSBkaWdpdHM7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbnN0IGZvcm1hdHRlZCA9IHRoaXMuX2Zvcm1hdF91c19waG9uZShkaWdpdHNfdG9fZm9ybWF0KTtcbiAgICAgICAgICAgICRpbnB1dC52YWwoZm9ybWF0dGVkKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gSW5pdGlhbGl6ZSBmb3JtYXR0aW5nIGlmIHRoZXJlJ3MgYSB2YWx1ZVxuICAgICAgICBjb25zdCBpbml0aWFsX3ZhbHVlID0gJGlucHV0LnZhbCgpO1xuICAgICAgICBpZiAoaW5pdGlhbF92YWx1ZSkge1xuICAgICAgICAgICAgdGhpcy52YWwoaW5pdGlhbF92YWx1ZSk7XG4gICAgICAgIH1cbiAgICB9XG59XG4iLCJjbGFzcyBTdGF0ZV9TZWxlY3RfSW5wdXQgZXh0ZW5kcyBBamF4X1NlbGVjdF9JbnB1dCB7XG4gICAgYXN5bmMgb25fbG9hZCgpIHtcbiAgICAgICAgLy8gSW5pdGlhbGl6ZSBjb3VudHJ5IGNvZGUgZnJvbSBhcmdzIG9yIGRlZmF1bHQgdG8gVVNcbiAgICAgICAgaWYgKCF0aGlzLmRhdGEuY291bnRyeV9jb2RlKSB7XG4gICAgICAgICAgICB0aGlzLmRhdGEuY291bnRyeV9jb2RlID0gdGhpcy5hcmdzLmNvdW50cnlfY29kZSB8fCAnVVMnO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gTG9hZCBzdGF0ZXMgdmlhIEFqYXggZW5kcG9pbnQgaWYgY291bnRyeSBjb2RlIGlzIHNldFxuICAgICAgICBpZiAodGhpcy5kYXRhLmNvdW50cnlfY29kZSkge1xuICAgICAgICAgICAgdGhpcy5kYXRhLnNlbGVjdF92YWx1ZXMgPSBhd2FpdCBSc3hfUmVmZXJlbmNlX0RhdGFfQ29udHJvbGxlci5zdGF0ZXMoeyBjb3VudHJ5OiB0aGlzLmRhdGEuY291bnRyeV9jb2RlIH0pO1xuXG4gICAgICAgICAgICAvLyBJZiBubyBzdGF0ZXMgcmV0dXJuZWQsIGFkZCBOL0Egb3B0aW9uXG4gICAgICAgICAgICBpZiAoIXRoaXMuZGF0YS5zZWxlY3RfdmFsdWVzIHx8IHRoaXMuZGF0YS5zZWxlY3RfdmFsdWVzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgICAgIHRoaXMuZGF0YS5zZWxlY3RfdmFsdWVzID0gW3sgdmFsdWU6ICdOL0EnLCBsYWJlbDogJ04vQScgfV07XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmRhdGEuc2VsZWN0X3ZhbHVlcyA9IFtdO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgb25fY3JlYXRlKCkge1xuICAgICAgICAvLyBTZXQgZGVmYXVsdCBwbGFjZWhvbGRlciBpZiBub3QgcHJvdmlkZWRcbiAgICAgICAgaWYgKCF0aGlzLmFyZ3MucGxhY2Vob2xkZXIpIHtcbiAgICAgICAgICAgIHRoaXMuYXJncy5wbGFjZWhvbGRlciA9ICdTZWxlY3QgU3RhdGUuLi4nO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gSW5pdGlhbGl6ZSBjb3VudHJ5IGNvZGUgaW4gZGF0YVxuICAgICAgICB0aGlzLmRhdGEuY291bnRyeV9jb2RlID0gdGhpcy5hcmdzLmNvdW50cnlfY29kZSB8fCAnJztcblxuICAgICAgICAvLyBDYWNoZSBmb3Igc2VsZWN0ZWQgc3RhdGUgcGVyIGNvdW50cnkgY29kZVxuICAgICAgICB0aGlzLl9zdGF0ZV9jYWNoZSA9IHt9O1xuXG4gICAgICAgIC8vIENhbGwgcGFyZW50IHRvIGluaXRpYWxpemUgQWpheF9TZWxlY3RfSW5wdXRcbiAgICAgICAgc3VwZXIub25fY3JlYXRlKCk7XG4gICAgfVxuXG4gICAgb25fcmVhZHkoKSB7XG4gICAgICAgIC8vIENhbGwgcGFyZW50IHRvIGluaXRpYWxpemUgVG9tIFNlbGVjdFxuICAgICAgICBzdXBlci5vbl9yZWFkeSgpO1xuXG4gICAgICAgIC8vIENoZWNrIGlmIHRoaXMgaXMgTi9BIGNhc2UgKG5vIHN0YXRlcyBmb3IgY291bnRyeSlcbiAgICAgICAgY29uc3QgaXNfbmEgPSB0aGlzLmRhdGEuc2VsZWN0X3ZhbHVlcy5sZW5ndGggPT09IDEgJiYgdGhpcy5kYXRhLnNlbGVjdF92YWx1ZXNbMF0udmFsdWUgPT09ICdOL0EnO1xuXG4gICAgICAgIC8vIERpc2FibGUgaWYgbm8gY291bnRyeSBjb2RlIG9yIE4vQSBjYXNlXG4gICAgICAgIGlmICgoIXRoaXMuZGF0YS5jb3VudHJ5X2NvZGUgfHwgaXNfbmEpICYmIHRoaXMudG9tX3NlbGVjdCkge1xuICAgICAgICAgICAgdGhpcy50b21fc2VsZWN0LmRpc2FibGUoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFNldCB2YWx1ZSB0byBOL0EgaWYgdGhhdCdzIHRoZSBvbmx5IG9wdGlvblxuICAgICAgICBpZiAoaXNfbmEpIHtcbiAgICAgICAgICAgIHRoaXMudmFsKCdOL0EnKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNldCBjb3VudHJ5IGNvZGUgYW5kIHJlbG9hZCBzdGF0ZSBsaXN0XG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGNvdW50cnlfY29kZSAtIElTTyBjb3VudHJ5IGNvZGUgKGUuZy4sICdVUycsICdDQScpXG4gICAgICovXG4gICAgYXN5bmMgc2V0X2NvdW50cnlfY29kZShjb3VudHJ5X2NvZGUpIHtcbiAgICAgICAgLy8gQ2FjaGUgdGhlIGN1cnJlbnQgdmFsdWUgZm9yIHRoZSBjdXJyZW50IGNvdW50cnkgYmVmb3JlIHN3aXRjaGluZ1xuICAgICAgICBjb25zdCBjdXJyZW50X2NvdW50cnkgPSB0aGlzLmRhdGEuY291bnRyeV9jb2RlO1xuICAgICAgICBjb25zdCBjdXJyZW50X3ZhbHVlID0gdGhpcy52YWwoKTtcbiAgICAgICAgaWYgKGN1cnJlbnRfY291bnRyeSAmJiBjdXJyZW50X3ZhbHVlICYmIGN1cnJlbnRfdmFsdWUgIT09ICdOL0EnKSB7XG4gICAgICAgICAgICB0aGlzLl9zdGF0ZV9jYWNoZVtjdXJyZW50X2NvdW50cnldID0gY3VycmVudF92YWx1ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFVwZGF0ZSBjb3VudHJ5IGNvZGVcbiAgICAgICAgdGhpcy5kYXRhLmNvdW50cnlfY29kZSA9IGNvdW50cnlfY29kZTtcblxuICAgICAgICAvLyBEaXNhYmxlIHRoZSBzZWxlY3RvciB3aGlsZSBsb2FkaW5nXG4gICAgICAgIGlmICh0aGlzLnRvbV9zZWxlY3QpIHtcbiAgICAgICAgICAgIHRoaXMudG9tX3NlbGVjdC5kaXNhYmxlKCk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBMb2FkIG5ldyBzdGF0ZSBsaXN0XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICB0aGlzLmRhdGEuc2VsZWN0X3ZhbHVlcyA9IGF3YWl0IFJzeF9SZWZlcmVuY2VfRGF0YV9Db250cm9sbGVyLnN0YXRlcyh7IGNvdW50cnk6IGNvdW50cnlfY29kZSB9KTtcblxuICAgICAgICAgICAgLy8gUmFjZSBjb25kaXRpb24gY2hlY2s6IHZlcmlmeSBjb3VudHJ5IGhhc24ndCBjaGFuZ2VkIGR1cmluZyB0aGUgcmVxdWVzdFxuICAgICAgICAgICAgaWYgKHRoaXMuZGF0YS5jb3VudHJ5X2NvZGUgIT09IGNvdW50cnlfY29kZSkge1xuICAgICAgICAgICAgICAgIC8vIENvdW50cnkgY2hhbmdlZCB3aGlsZSByZXF1ZXN0IHdhcyBpbiBmbGlnaHQgLSBpZ25vcmUgdGhpcyByZXNwb25zZVxuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gSWYgbm8gc3RhdGVzIHJldHVybmVkLCBhZGQgTi9BIG9wdGlvblxuICAgICAgICAgICAgaWYgKCF0aGlzLmRhdGEuc2VsZWN0X3ZhbHVlcyB8fCB0aGlzLmRhdGEuc2VsZWN0X3ZhbHVlcy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgICAgICB0aGlzLmRhdGEuc2VsZWN0X3ZhbHVlcyA9IFt7IHZhbHVlOiAnTi9BJywgbGFiZWw6ICdOL0EnIH1dO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBSZS1yZW5kZXIgdGhlIHdpZGdldCB3aXRoIG5ldyBzdGF0ZXNcbiAgICAgICAgICAgIHRoaXMucmVkcmF3KCk7XG5cbiAgICAgICAgICAgIC8vIFJlLWluaXRpYWxpemUgVG9tIFNlbGVjdCBhZnRlciByZWRyYXdcbiAgICAgICAgICAgIGlmICh0aGlzLnRvbV9zZWxlY3QpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnRvbV9zZWxlY3QuZGVzdHJveSgpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBSZS1ydW4gb25fcmVhZHkgdG8gc2V0IHVwIFRvbSBTZWxlY3QgYWdhaW5cbiAgICAgICAgICAgIHRoaXMub25fcmVhZHkoKTtcblxuICAgICAgICAgICAgLy8gQ2hlY2sgaWYgdGhpcyBpcyBOL0EgY2FzZVxuICAgICAgICAgICAgY29uc3QgaXNfbmEgPSB0aGlzLmRhdGEuc2VsZWN0X3ZhbHVlcy5sZW5ndGggPT09IDEgJiYgdGhpcy5kYXRhLnNlbGVjdF92YWx1ZXNbMF0udmFsdWUgPT09ICdOL0EnO1xuXG4gICAgICAgICAgICBpZiAoaXNfbmEpIHtcbiAgICAgICAgICAgICAgICAvLyBTZXQgdG8gTi9BIGFuZCBrZWVwIGRpc2FibGVkXG4gICAgICAgICAgICAgICAgdGhpcy52YWwoJ04vQScpO1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLnRvbV9zZWxlY3QpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy50b21fc2VsZWN0LmRpc2FibGUoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIC8vIFRyeSB0byByZXN0b3JlIGNhY2hlZCB2YWx1ZSBmb3IgdGhpcyBjb3VudHJ5XG4gICAgICAgICAgICAgICAgY29uc3QgY2FjaGVkX3ZhbHVlID0gdGhpcy5fc3RhdGVfY2FjaGVbY291bnRyeV9jb2RlXTtcblxuICAgICAgICAgICAgICAgIGlmIChjYWNoZWRfdmFsdWUpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgdmFsdWVfZXhpc3RzID0gdGhpcy5kYXRhLnNlbGVjdF92YWx1ZXMuc29tZSgob3B0KSA9PiAodHlwZW9mIG9wdCA9PT0gJ29iamVjdCcgPyBvcHQudmFsdWUgOiBvcHQpID09PSBjYWNoZWRfdmFsdWUpO1xuXG4gICAgICAgICAgICAgICAgICAgIGlmICh2YWx1ZV9leGlzdHMpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMudmFsKGNhY2hlZF92YWx1ZSk7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnZhbCgnJyk7IC8vIENsZWFyIGlmIGNhY2hlZCB2YWx1ZSBub3QgaW4gbmV3IGxpc3RcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMudmFsKCcnKTsgLy8gTm8gY2FjaGVkIHZhbHVlIC0gbGVhdmUgZW1wdHlcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAvLyBFbmFibGUgdGhlIHdpZGdldCBub3cgdGhhdCB3ZSBoYXZlIGEgY291bnRyeSB3aXRoIHN0YXRlc1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLnRvbV9zZWxlY3QpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy50b21fc2VsZWN0LmVuYWJsZSgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0ZhaWxlZCB0byBsb2FkIHN0YXRlcyBmb3IgY291bnRyeTonLCBjb3VudHJ5X2NvZGUsIGVycm9yKTtcbiAgICAgICAgICAgIHRoaXMuZGF0YS5zZWxlY3RfdmFsdWVzID0gW107XG5cbiAgICAgICAgICAgIC8vIFJlLWVuYWJsZSBldmVuIG9uIGVycm9yXG4gICAgICAgICAgICBpZiAodGhpcy50b21fc2VsZWN0KSB7XG4gICAgICAgICAgICAgICAgdGhpcy50b21fc2VsZWN0LmVuYWJsZSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogT3ZlcnJpZGUgdmFsKCkgdG8gdXBkYXRlIGNhY2hlIHdoZW4gdXNlciBtYW51YWxseSBzZWxlY3RzIGEgc3RhdGVcbiAgICAgKi9cbiAgICB2YWwodmFsdWUpIHtcbiAgICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIC8vIEdldHRlciAtIHVzZSBwYXJlbnQgaW1wbGVtZW50YXRpb25cbiAgICAgICAgICAgIHJldHVybiBzdXBlci52YWwoKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIFNldHRlciAtIHVwZGF0ZSBjYWNoZSBhbmQgY2FsbCBwYXJlbnRcbiAgICAgICAgICAgIGlmICh0aGlzLmRhdGEuY291bnRyeV9jb2RlICYmIHZhbHVlICYmIHZhbHVlICE9PSAnTi9BJykge1xuICAgICAgICAgICAgICAgIHRoaXMuX3N0YXRlX2NhY2hlW3RoaXMuZGF0YS5jb3VudHJ5X2NvZGVdID0gdmFsdWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gc3VwZXIudmFsKHZhbHVlKTtcbiAgICAgICAgfVxuICAgIH1cbn1cbiIsImNsYXNzIENvdW50cnlfU2VsZWN0X0lucHV0IGV4dGVuZHMgQWpheF9TZWxlY3RfSW5wdXQge1xuICAgIGFzeW5jIG9uX2xvYWQoKSB7XG4gICAgICAgIC8vIExvYWQgY291bnRyaWVzIHZpYSBBamF4IGVuZHBvaW50IGlmIGRhdGEgbm90IHByb3ZpZGVkXG4gICAgICAgIGlmICghdGhpcy5hcmdzLmRhdGEpIHtcbiAgICAgICAgICAgIHRoaXMuZGF0YS5zZWxlY3RfdmFsdWVzID0gYXdhaXQgUnN4X1JlZmVyZW5jZV9EYXRhX0NvbnRyb2xsZXIuY291bnRyaWVzKCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBVc2UgcGFyZW50IG9uX2xvYWQgZm9yIGN1c3RvbSBkYXRhIGVuZHBvaW50c1xuICAgICAgICAgICAgYXdhaXQgc3VwZXIub25fbG9hZCgpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gUmVvcmRlciBzZWxlY3RfdmFsdWVzIHRvIHB1dCBkZWZhdWx0IGNvdW50cnkgZmlyc3QgaW4gdGhlIGxpc3RcbiAgICAgICAgaWYgKHRoaXMuYXJncy5kZWZhdWx0X2NvdW50cnkgJiYgdGhpcy5kYXRhLnNlbGVjdF92YWx1ZXMgJiYgaXNfYXJyYXkodGhpcy5kYXRhLnNlbGVjdF92YWx1ZXMpKSB7XG4gICAgICAgICAgICBjb25zdCBkZWZhdWx0X2NvdW50cnlfY29kZSA9IHRoaXMuYXJncy5kZWZhdWx0X2NvdW50cnk7XG5cbiAgICAgICAgICAgIC8vIEZpbmQgdGhlIGRlZmF1bHQgY291bnRyeSBpbiB0aGUgYXJyYXlcbiAgICAgICAgICAgIGNvbnN0IGRlZmF1bHRfY291bnRyeV9pbmRleCA9IHRoaXMuZGF0YS5zZWxlY3RfdmFsdWVzLmZpbmRJbmRleChcbiAgICAgICAgICAgICAgICBvcHQgPT4gKHR5cGVvZiBvcHQgPT09ICdvYmplY3QnID8gb3B0LnZhbHVlIDogb3B0KSA9PT0gZGVmYXVsdF9jb3VudHJ5X2NvZGVcbiAgICAgICAgICAgICk7XG5cbiAgICAgICAgICAgIGlmIChkZWZhdWx0X2NvdW50cnlfaW5kZXggIT09IC0xKSB7XG4gICAgICAgICAgICAgICAgLy8gUmVtb3ZlIGl0IGZyb20gaXRzIGN1cnJlbnQgcG9zaXRpb25cbiAgICAgICAgICAgICAgICBjb25zdCBbZGVmYXVsdF9jb3VudHJ5XSA9IHRoaXMuZGF0YS5zZWxlY3RfdmFsdWVzLnNwbGljZShkZWZhdWx0X2NvdW50cnlfaW5kZXgsIDEpO1xuXG4gICAgICAgICAgICAgICAgLy8gQWRkIGl0IHRvIHRoZSBiZWdpbm5pbmdcbiAgICAgICAgICAgICAgICB0aGlzLmRhdGEuc2VsZWN0X3ZhbHVlcy51bnNoaWZ0KGRlZmF1bHRfY291bnRyeSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBvbl9jcmVhdGUoKSB7XG4gICAgICAgIC8vIFNldCBkZWZhdWx0IHBsYWNlaG9sZGVyIGlmIG5vdCBwcm92aWRlZFxuICAgICAgICBpZiAoIXRoaXMuYXJncy5wbGFjZWhvbGRlcikge1xuICAgICAgICAgICAgdGhpcy5hcmdzLnBsYWNlaG9sZGVyID0gJ1NlbGVjdCBDb3VudHJ5Li4uJztcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIENhbGwgcGFyZW50IHRvIGluaXRpYWxpemUgQWpheF9TZWxlY3RfSW5wdXRcbiAgICAgICAgc3VwZXIub25fY3JlYXRlKCk7XG5cbiAgICAgICAgLy8gSGFuZGxlIGRlZmF1bHQgY291bnRyeSB2YWx1ZVxuICAgICAgICBpZiAodGhpcy5hcmdzLmRlZmF1bHRfY291bnRyeSAmJiAhdGhpcy5kYXRhLnZhbHVlKSB7XG4gICAgICAgICAgICB0aGlzLmRhdGEudmFsdWUgPSB0aGlzLmFyZ3MuZGVmYXVsdF9jb3VudHJ5O1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgb25fcmVhZHkoKSB7XG4gICAgICAgIC8vIENhbGwgcGFyZW50IHRvIGluaXRpYWxpemUgVG9tIFNlbGVjdFxuICAgICAgICBzdXBlci5vbl9yZWFkeSgpO1xuXG4gICAgICAgIC8vIFVwZGF0ZSBzdGF0ZSBzZWxlY3RvciB3aXRoIGluaXRpYWwvZGVmYXVsdCBjb3VudHJ5XG4gICAgICAgIHRoaXMuX3VwZGF0ZV9zdGF0ZV9zZWxlY3RvcigpO1xuXG4gICAgICAgIC8vIExpc3RlbiBmb3IgY291bnRyeSBjaGFuZ2VzIGFuZCB1cGRhdGUgc3RhdGUgc2VsZWN0b3JcbiAgICAgICAgaWYgKHRoaXMudG9tX3NlbGVjdCkge1xuICAgICAgICAgICAgdGhpcy50b21fc2VsZWN0Lm9uKCdjaGFuZ2UnLCAoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5fdXBkYXRlX3N0YXRlX3NlbGVjdG9yKCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEZpbmQgU3RhdGVfU2VsZWN0X0lucHV0IHNpYmxpbmcgYW5kIHVwZGF0ZSBpdHMgY291bnRyeSBjb2RlXG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cbiAgICBfdXBkYXRlX3N0YXRlX3NlbGVjdG9yKCkge1xuICAgICAgICBjb25zdCBjdXJyZW50X2NvdW50cnkgPSB0aGlzLnZhbCgpO1xuXG4gICAgICAgIC8vIEZpbmQgU3RhdGVfU2VsZWN0X0lucHV0IGNvbXBvbmVudCB1c2luZyBjbG9zZXN0X3NpYmxpbmdcbiAgICAgICAgY29uc3Qgc3RhdGVfY29tcG9uZW50ID0gdGhpcy4kLmNsb3Nlc3Rfc2libGluZygnLlN0YXRlX1NlbGVjdF9JbnB1dCcpLmNvbXBvbmVudCgpO1xuXG4gICAgICAgIGlmIChzdGF0ZV9jb21wb25lbnQgJiYgdHlwZW9mIHN0YXRlX2NvbXBvbmVudC5zZXRfY291bnRyeV9jb2RlID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICBzdGF0ZV9jb21wb25lbnQuc2V0X2NvdW50cnlfY29kZShjdXJyZW50X2NvdW50cnkpO1xuICAgICAgICB9XG4gICAgfVxufVxuIiwiLyoqXG4gKiBQcm9maWxlX1Bob3RvX0lucHV0XG4gKlxuICogUHJvZmlsZSBwaG90byB1cGxvYWQgd2lkZ2V0IHdpdGggdGh1bWJuYWlsIGRpc3BsYXkgYW5kIHVwbG9hZCBoYW5kbGluZy5cbiAqIFNlZSBwcm9maWxlX3Bob3RvX2lucHV0LmpxaHRtbCBmb3IgZnVsbCBkb2N1bWVudGF0aW9uLlxuICpcbiAqIEphdmFTY3JpcHQgUmVzcG9uc2liaWxpdGllczpcbiAqIC0gSGFuZGxlIGZpbGUgc2VsZWN0aW9uIGFuZCB1cGxvYWRcbiAqIC0gVXBkYXRlIHRodW1ibmFpbCBvbiBzdWNjZXNzZnVsIHVwbG9hZFxuICogLSBNYW5hZ2UgbG9hZGluZyBzdGF0ZSB3aXRoIHNwaW5uZXJcbiAqIC0gUHJvdmlkZSB2YWwoKSBnZXR0ZXIvc2V0dGVyIGZvciBhdHRhY2htZW50IGtleVxuICogLSBIYW5kbGUgcmVtb3ZlIGJ1dHRvbiBmdW5jdGlvbmFsaXR5XG4gKi9cbmNsYXNzIFByb2ZpbGVfUGhvdG9fSW5wdXQgZXh0ZW5kcyBGb3JtX0lucHV0X0Fic3RyYWN0IHtcbiAgICBvbl9jcmVhdGUoKSB7XG4gICAgICAgIC8vIEluaXRpYWxpemUgZGF0YVxuICAgICAgICB0aGlzLmRhdGEuYXR0YWNobWVudF9rZXkgPSAnJztcbiAgICAgICAgdGhpcy5kYXRhLnRodW1ibmFpbF91cmwgPSAnJztcbiAgICB9XG5cbiAgICBvbl9yZW5kZXIoKSB7XG4gICAgICAgIC8vIEhhbmRsZSB1cGxvYWQgYnV0dG9uIGNsaWNrIC0gdHJpZ2dlciBoaWRkZW4gZmlsZSBpbnB1dFxuICAgICAgICB0aGlzLiRpZCgndXBsb2FkX2J0bicpLm9uKCdjbGljaycsICgpID0+IHtcbiAgICAgICAgICAgIHRoaXMuJGlkKCdmaWxlX2lucHV0JykuY2xpY2soKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gSGFuZGxlIGZpbGUgc2VsZWN0aW9uXG4gICAgICAgIHRoaXMuJGlkKCdmaWxlX2lucHV0Jykub24oJ2NoYW5nZScsICgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGZpbGUgPSB0aGlzLiRpZCgnZmlsZV9pbnB1dCcpWzBdLmZpbGVzWzBdO1xuICAgICAgICAgICAgaWYgKCFmaWxlKSByZXR1cm47XG5cbiAgICAgICAgICAgIHRoaXMudXBsb2FkX3Bob3RvKGZpbGUpO1xuICAgICAgICB9KTtcblxuICAgICAgICAvLyBIYW5kbGUgcmVtb3ZlIGJ1dHRvblxuICAgICAgICBpZiAodGhpcy5hcmdzLnNob3dfcmVtb3ZlKSB7XG4gICAgICAgICAgICB0aGlzLiRpZCgncmVtb3ZlX2J0bicpLm9uKCdjbGljaycsICgpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLnJlbW92ZV9waG90bygpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiB2YWwoKSAtIEdldCBvciBzZXQgdGhlIGF0dGFjaG1lbnQga2V5XG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFtrZXldIC0gSWYgcHJvdmlkZWQsIHNldHMgdGhlIGF0dGFjaG1lbnQga2V5IGFuZCB1cGRhdGVzIHRodW1ibmFpbFxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFRoZSBjdXJyZW50IGF0dGFjaG1lbnQga2V5IHdoZW4gY2FsbGVkIGFzIGdldHRlclxuICAgICAqL1xuICAgIHZhbChrZXkpIHtcbiAgICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIC8vIEdldHRlciAtIHJldHVybiBhdHRhY2htZW50IGtleVxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuZGF0YS5hdHRhY2htZW50X2tleSB8fCAnJztcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIFNldHRlciAtIHNldCBhdHRhY2htZW50IGtleSBhbmQgdXBkYXRlIHRodW1ibmFpbFxuICAgICAgICAgICAgdGhpcy5kYXRhLmF0dGFjaG1lbnRfa2V5ID0ga2V5IHx8ICcnO1xuXG4gICAgICAgICAgICBpZiAodGhpcy5kYXRhLmF0dGFjaG1lbnRfa2V5KSB7XG4gICAgICAgICAgICAgICAgLy8gR2VuZXJhdGUgdGh1bWJuYWlsIFVSTCBmcm9tIGF0dGFjaG1lbnQga2V5XG4gICAgICAgICAgICAgICAgY29uc3Qgd2lkdGggPSB0aGlzLmFyZ3Mud2lkdGggfHwgOTY7XG4gICAgICAgICAgICAgICAgY29uc3QgaGVpZ2h0ID0gdGhpcy5hcmdzLmhlaWdodCB8fCA5NjtcbiAgICAgICAgICAgICAgICB0aGlzLmRhdGEudGh1bWJuYWlsX3VybCA9IGAvX3RodW1ibmFpbC8ke3RoaXMuZGF0YS5hdHRhY2htZW50X2tleX0vY292ZXIvJHt3aWR0aH0vJHtoZWlnaHR9YDtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgLy8gTm8ga2V5IC0gY2xlYXIgdGh1bWJuYWlsXG4gICAgICAgICAgICAgICAgdGhpcy5kYXRhLnRodW1ibmFpbF91cmwgPSAnJztcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uc29sZS5sb2coJ1JlcmVuZGVyJyk7XG4gICAgICAgICAgICAvLyBSZS1yZW5kZXIgdG8gc3dpdGNoIGJldHdlZW4gaWNvbiBhbmQgaW1hZ2VcbiAgICAgICAgICAgIHRoaXMucmVuZGVyKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICB1cGxvYWRfcGhvdG8oZmlsZSkge1xuICAgICAgICAvLyBWYWxpZGF0ZSBmaWxlIHNpemVcbiAgICAgICAgY29uc3QgbWF4X3NpemUgPSAodGhpcy5hcmdzLm1heF9zaXplIHx8IDIpICogMTAyNCAqIDEwMjQ7IC8vIENvbnZlcnQgTUIgdG8gYnl0ZXNcbiAgICAgICAgaWYgKGZpbGUuc2l6ZSA+IG1heF9zaXplKSB7XG4gICAgICAgICAgICBhbGVydChgRmlsZSBzaXplIG11c3QgYmUgbGVzcyB0aGFuICR7dGhpcy5hcmdzLm1heF9zaXplIHx8IDJ9TUJgKTtcbiAgICAgICAgICAgIHRoaXMuJGlkKCdmaWxlX2lucHV0JykudmFsKCcnKTsgLy8gQ2xlYXIgc2VsZWN0aW9uXG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICAvLyBTaG93IHNwaW5uZXIsIGRpbSBpbWFnZVxuICAgICAgICB0aGlzLiRpZCgnc3Bpbm5lcicpLnJlbW92ZUNsYXNzKCdkLW5vbmUnKTtcbiAgICAgICAgdGhpcy4kaWQoJ3Bob3RvJykuY3NzKCdvcGFjaXR5JywgJzAuMycpO1xuXG4gICAgICAgIC8vIENyZWF0ZSBGb3JtRGF0YSBmb3IgZmlsZSB1cGxvYWRcbiAgICAgICAgY29uc3QgZm9ybV9kYXRhID0gbmV3IEZvcm1EYXRhKCk7XG4gICAgICAgIGZvcm1fZGF0YS5hcHBlbmQoJ2ZpbGUnLCBmaWxlKTtcbiAgICAgICAgZm9ybV9kYXRhLmFwcGVuZCgnc2l0ZV9pZCcsICcxJyk7IC8vIFRPRE86IEdldCBmcm9tIHNlc3Npb24vY29uZmlnXG4gICAgICAgIC8vIERvIE5PVCBzZXQgZmlsZWFibGVfdHlwZS9maWxlYWJsZV9jYXRlZ29yeSAtIGZpbGUgdXBsb2FkcyB1bmF0dGFjaGVkXG4gICAgICAgIC8vIFRoZSBwYXJlbnQgZm9ybSB3aWxsIGFzc2lnbiBpdCB2aWEgYXR0YWNoX3RvKCkgb24gc2F2ZVxuXG4gICAgICAgIC8vIFVwbG9hZCBmaWxlIHZpYSBBSkFYXG4gICAgICAgICQuYWpheCh7XG4gICAgICAgICAgICB1cmw6ICcvX3VwbG9hZCcsXG4gICAgICAgICAgICB0eXBlOiAnUE9TVCcsXG4gICAgICAgICAgICBkYXRhOiBmb3JtX2RhdGEsXG4gICAgICAgICAgICBwcm9jZXNzRGF0YTogZmFsc2UsXG4gICAgICAgICAgICBjb250ZW50VHlwZTogZmFsc2UsXG4gICAgICAgICAgICBzdWNjZXNzOiAocmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZygnUHJvZmlsZSBwaG90byB1cGxvYWQgc3VjY2Vzc2Z1bDonLCByZXNwb25zZSk7XG5cbiAgICAgICAgICAgICAgICAvLyBVcGRhdGUgYXR0YWNobWVudCBrZXkgKHRoaXMgd2lsbCBhbHNvIHVwZGF0ZSB0aHVtYm5haWwpXG4gICAgICAgICAgICAgICAgdGhpcy52YWwocmVzcG9uc2UuYXR0YWNobWVudC5rZXkpO1xuXG4gICAgICAgICAgICAgICAgLy8gSGlkZSBzcGlubmVyLCByZXN0b3JlIG9wYWNpdHlcbiAgICAgICAgICAgICAgICB0aGlzLiRpZCgnc3Bpbm5lcicpLmFkZENsYXNzKCdkLW5vbmUnKTtcbiAgICAgICAgICAgICAgICB0aGlzLiRpZCgncGhvdG8nKS5jc3MoJ29wYWNpdHknLCAnMScpO1xuXG4gICAgICAgICAgICAgICAgLy8gQ2xlYXIgZmlsZSBpbnB1dCBmb3IgZnV0dXJlIHVwbG9hZHNcbiAgICAgICAgICAgICAgICB0aGlzLiRpZCgnZmlsZV9pbnB1dCcpLnZhbCgnJyk7XG5cbiAgICAgICAgICAgICAgICAvLyBUcmlnZ2VyIGNoYW5nZSBldmVudCBmb3IgZm9ybSB0cmFja2luZ1xuICAgICAgICAgICAgICAgIHRoaXMuJC50cmlnZ2VyKCdjaGFuZ2UnKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBlcnJvcjogKHhociwgc3RhdHVzLCBlcnJvcikgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ1Byb2ZpbGUgcGhvdG8gdXBsb2FkIGZhaWxlZDonLCBlcnJvcik7XG4gICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcignUmVzcG9uc2U6JywgeGhyLnJlc3BvbnNlSlNPTik7XG5cbiAgICAgICAgICAgICAgICAvLyBIaWRlIHNwaW5uZXIsIHJlc3RvcmUgb3BhY2l0eVxuICAgICAgICAgICAgICAgIHRoaXMuJGlkKCdzcGlubmVyJykuYWRkQ2xhc3MoJ2Qtbm9uZScpO1xuICAgICAgICAgICAgICAgIHRoaXMuJGlkKCdwaG90bycpLmNzcygnb3BhY2l0eScsICcxJyk7XG5cbiAgICAgICAgICAgICAgICAvLyBDbGVhciBmaWxlIGlucHV0XG4gICAgICAgICAgICAgICAgdGhpcy4kaWQoJ2ZpbGVfaW5wdXQnKS52YWwoJycpO1xuXG4gICAgICAgICAgICAgICAgLy8gU2hvdyBlcnJvciB0byB1c2VyXG4gICAgICAgICAgICAgICAgYWxlcnQoJ1VwbG9hZCBmYWlsZWQ6ICcgKyAoeGhyLnJlc3BvbnNlSlNPTj8uZXJyb3IgfHwgZXJyb3IpKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHVwZGF0ZV9waG90bygpIHtcbiAgICAgICAgLy8gPCUgaWYgKHRoaXMuYXJncy5zaG93X3JlbW92ZSAmJiB0aGlzLmRhdGEuYXR0YWNobWVudF9rZXkpIHsgJT5cbiAgICB9XG5cbiAgICByZW1vdmVfcGhvdG8oKSB7XG4gICAgICAgIC8vIENsZWFyIGF0dGFjaG1lbnQga2V5IChzZXRzIHRvIHBsYWNlaG9sZGVyKVxuICAgICAgICB0aGlzLnZhbCgnJyk7XG5cbiAgICAgICAgLy8gVHJpZ2dlciBjaGFuZ2UgZXZlbnQgZm9yIGZvcm0gdHJhY2tpbmdcbiAgICAgICAgdGhpcy4kLnRyaWdnZXIoJ2NoYW5nZScpO1xuICAgIH1cblxuICAgIGFzeW5jIHNlZWQoKSB7XG4gICAgICAgIC8vIEZvciB0ZXN0aW5nIC0gc2V0IGEgcGxhY2Vob2xkZXIga2V5XG4gICAgICAgIC8vIEluIHByb2R1Y3Rpb24sIHRoaXMgd291bGQgdXNlIGFjdHVhbCB0ZXN0IGRhdGFcbiAgICAgICAgdGhpcy52YWwoJycpO1xuICAgIH1cbn1cbiIsIi8qKlxuICogUnN4X1RhYnNcbiAqXG4gKiBUYWIgY29udGFpbmVyIGNvbXBvbmVudCB3aXRoIGZvcm0tYXdhcmUgZXJyb3IgaGFuZGxpbmcgaW50ZWdyYXRpb24uXG4gKiBTZWUgcnN4X3RhYnMuanFodG1sIGZvciBmdWxsIGRvY3VtZW50YXRpb24uXG4gKlxuICogSmF2YVNjcmlwdCBSZXNwb25zaWJpbGl0aWVzOlxuICogLSBCdWlsZHMgdGFiIG5hdmlnYXRpb24gZHluYW1pY2FsbHkgZnJvbSByZWdpc3RlcmVkIFJzeF9UYWIgY2hpbGRyZW5cbiAqIC0gTWFuYWdlcyB0YWIgYWN0aXZhdGlvbiBhbmQgc3dpdGNoaW5nIGJlaGF2aW9yXG4gKiAtIFBlcnNpc3RzIGFjdGl2ZSB0YWIgdG8gVVJMIGhhc2ggZm9yIGJvb2ttYXJraW5nXG4gKiAtIEludGVncmF0ZXMgd2l0aCBmb3JtIHZhbGlkYXRpb24gdG8gc2hvdyBlcnJvciBiYWRnZXMgb24gdGFic1xuICogLSBBdXRvLXN3aXRjaGVzIHRvIGZpcnN0IHRhYiB3aXRoIGVycm9ycyBvbiB2YWxpZGF0aW9uIGZhaWx1cmVcbiAqIC0gUHJvdmlkZXMgQVBJIGZvciBwYXJlbnQgZm9ybXMgdG8gcmVwb3J0IHZhbGlkYXRpb24gZXJyb3JzXG4gKi9cbmNsYXNzIFJzeF9UYWJzIGV4dGVuZHMgSnFodG1sX0NvbXBvbmVudCB7XG4gICAgb25fY3JlYXRlKCkge1xuICAgICAgICB0aGlzLnRhYnMgPSBbXTsgLy8gUmVnaXN0ZXJlZCBSc3hfVGFiIGNvbXBvbmVudHNcbiAgICAgICAgdGhpcy5hY3RpdmVfdGFiX2lkID0gbnVsbDtcbiAgICAgICAgdGhpcy5mb3JtID0gbnVsbDtcbiAgICB9XG5cbiAgICBvbl9yZWFkeSgpIHtcbiAgICAgICAgLy8gRmluZCBwYXJlbnQgZm9ybSBpZiBpdCBleGlzdHNcbiAgICAgICAgdGhpcy5mb3JtID0gdGhpcy5jbG9zZXN0KCcuUnN4X0Zvcm0nKTtcblxuICAgICAgICAvLyBCdWlsZCB0YWIgbmF2aWdhdGlvbiBmcm9tIHJlZ2lzdGVyZWQgdGFic1xuICAgICAgICB0aGlzLl9idWlsZF9uYXYoKTtcblxuICAgICAgICAvLyBSZXN0b3JlIGFjdGl2ZSB0YWIgZnJvbSBVUkwgaGFzaCBvciBhY3RpdmF0ZSBmaXJzdCB0YWJcbiAgICAgICAgY29uc3QgaGFzaCA9IHdpbmRvdy5sb2NhdGlvbi5oYXNoO1xuICAgICAgICBpZiAoaGFzaCkge1xuICAgICAgICAgICAgY29uc3QgdGFiX2lkID0gaGFzaC5zdWJzdHJpbmcoMSk7XG4gICAgICAgICAgICB0aGlzLmFjdGl2YXRlX3RhYih0YWJfaWQpO1xuICAgICAgICB9IGVsc2UgaWYgKHRoaXMudGFicy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICB0aGlzLmFjdGl2YXRlX3RhYih0aGlzLnRhYnNbMF0uYXJncy5pZCk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBQZXJzaXN0IGFjdGl2ZSB0YWIgdG8gVVJMIGhhc2hcbiAgICAgICAgY29uc3QgdGhhdCA9IHRoaXM7XG4gICAgICAgIHRoaXMuJGlkKCduYXYnKS5vbignY2xpY2snLCAnYVtkYXRhLWJzLXRvZ2dsZT1cInRhYlwiXScsIGZ1bmN0aW9uIChlKSB7XG4gICAgICAgICAgICBjb25zdCB0YWJfaWQgPSAkKGUuY3VycmVudFRhcmdldCkuZGF0YSgndGFiLWlkJyk7XG4gICAgICAgICAgICB3aW5kb3cubG9jYXRpb24uaGFzaCA9ICcjJyArIHRhYl9pZDtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgcmVnaXN0ZXJfdGFiKHRhYl9jb21wb25lbnQpIHtcbiAgICAgICAgdGhpcy50YWJzLnB1c2godGFiX2NvbXBvbmVudCk7XG4gICAgfVxuXG4gICAgX2J1aWxkX25hdigpIHtcbiAgICAgICAgY29uc3QgJG5hdiA9IHRoaXMuJGlkKCduYXYnKTtcbiAgICAgICAgJG5hdi5lbXB0eSgpO1xuXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy50YWJzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBjb25zdCB0YWIgPSB0aGlzLnRhYnNbaV07XG4gICAgICAgICAgICBjb25zdCBpc19hY3RpdmUgPSBpID09PSAwID8gJ2FjdGl2ZScgOiAnJztcblxuICAgICAgICAgICAgY29uc3QgJGxpID0gJChgXG4gICAgICAgICAgICAgICAgPGxpIGNsYXNzPVwibmF2LWl0ZW1cIiByb2xlPVwicHJlc2VudGF0aW9uXCI+XG4gICAgICAgICAgICAgICAgICAgIDxhIGNsYXNzPVwibmF2LWxpbmsgJHtpc19hY3RpdmV9XCJcbiAgICAgICAgICAgICAgICAgICAgICAgZGF0YS1icy10b2dnbGU9XCJ0YWJcIlxuICAgICAgICAgICAgICAgICAgICAgICBocmVmPVwiIyR7dGFiLmFyZ3MuaWR9XCJcbiAgICAgICAgICAgICAgICAgICAgICAgZGF0YS10YWItaWQ9XCIke3RhYi5hcmdzLmlkfVwiXG4gICAgICAgICAgICAgICAgICAgICAgIGFyaWEtc2VsZWN0ZWQ9XCIke2kgPT09IDAgPyAndHJ1ZScgOiAnZmFsc2UnfVwiXG4gICAgICAgICAgICAgICAgICAgICAgIHJvbGU9XCJ0YWJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICR7dGFiLmFyZ3MuaWNvbiA/IGA8aSBjbGFzcz1cIiR7dGFiLmFyZ3MuaWNvbn1cIj48L2k+IGAgOiAnJ31cbiAgICAgICAgICAgICAgICAgICAgICAgICR7dGFiLmFyZ3MubGFiZWx9XG4gICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImJhZGdlIGJnLWRhbmdlciBtcy0yXCIgc3R5bGU9XCJkaXNwbGF5OiBub25lO1wiIGRhdGEtZXJyb3ItYmFkZ2U9XCIke3RhYi5hcmdzLmlkfVwiPjA8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgIDwvYT5cbiAgICAgICAgICAgICAgICA8L2xpPlxuICAgICAgICAgICAgYCk7XG5cbiAgICAgICAgICAgICRuYXYuYXBwZW5kKCRsaSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBhY3RpdmF0ZV90YWIodGFiX2lkKSB7XG4gICAgICAgIC8vIEZpbmQgdGhlIHRhYlxuICAgICAgICBjb25zdCB0YWIgPSB0aGlzLnRhYnMuZmluZCgodCkgPT4gdC5hcmdzLmlkID09PSB0YWJfaWQpO1xuICAgICAgICBpZiAoIXRhYikgcmV0dXJuO1xuXG4gICAgICAgIC8vIFJlbW92ZSBhY3RpdmUgc2hvdyBmcm9tIGFsbCB0YWIgcGFuZXNcbiAgICAgICAgZm9yIChsZXQgdCBvZiB0aGlzLnRhYnMpIHtcbiAgICAgICAgICAgIHQuJC5yZW1vdmVDbGFzcygnYWN0aXZlIHNob3cnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIEFkZCBhY3RpdmUgc2hvdyB0byB0aGUgc2VsZWN0ZWQgdGFiIHBhbmVcbiAgICAgICAgdGFiLiQuYWRkQ2xhc3MoJ2FjdGl2ZSBzaG93Jyk7XG5cbiAgICAgICAgLy8gVXBkYXRlIEJvb3RzdHJhcCB0YWIgbmF2aWdhdGlvblxuICAgICAgICB0aGlzLiRpZCgnbmF2JykuZmluZCgnYVtkYXRhLWJzLXRvZ2dsZT1cInRhYlwiXScpLnJlbW92ZUNsYXNzKCdhY3RpdmUnKS5hdHRyKCdhcmlhLXNlbGVjdGVkJywgJ2ZhbHNlJyk7XG4gICAgICAgIHRoaXMuJGlkKCduYXYnKVxuICAgICAgICAgICAgLmZpbmQoJ2FbZGF0YS10YWItaWQ9XCInICsgdGFiX2lkICsgJ1wiXScpXG4gICAgICAgICAgICAuYWRkQ2xhc3MoJ2FjdGl2ZScpXG4gICAgICAgICAgICAuYXR0cignYXJpYS1zZWxlY3RlZCcsICd0cnVlJyk7XG5cbiAgICAgICAgdGhpcy5hY3RpdmVfdGFiX2lkID0gdGFiX2lkO1xuICAgIH1cblxuICAgIGhhbmRsZV92YWxpZGF0aW9uX2Vycm9ycyhlcnJvcnMpIHtcbiAgICAgICAgLy8gQ291bnQgZXJyb3JzIHBlciB0YWJcbiAgICAgICAgY29uc3QgdGFiX2Vycm9ycyA9IHt9O1xuXG4gICAgICAgIGZvciAobGV0IHRhYiBvZiB0aGlzLnRhYnMpIHtcbiAgICAgICAgICAgIGNvbnN0IGVycm9yX2NvdW50ID0gdGFiLmNvdW50X2Vycm9ycyhlcnJvcnMpO1xuICAgICAgICAgICAgdGFiX2Vycm9yc1t0YWIuYXJncy5pZF0gPSBlcnJvcl9jb3VudDtcblxuICAgICAgICAgICAgLy8gVXBkYXRlIGJhZGdlXG4gICAgICAgICAgICBjb25zdCAkYmFkZ2UgPSB0aGlzLiRpZCgnbmF2JykuZmluZChgW2RhdGEtZXJyb3ItYmFkZ2U9XCIke3RhYi5hcmdzLmlkfVwiXWApO1xuICAgICAgICAgICAgaWYgKGVycm9yX2NvdW50ID4gMCkge1xuICAgICAgICAgICAgICAgICRiYWRnZS50ZXh0KGVycm9yX2NvdW50KS5zaG93KCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICRiYWRnZS5oaWRlKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyBGaW5kIGZpcnN0IHRhYiB3aXRoIGVycm9yc1xuICAgICAgICBjb25zdCBmaXJzdF9lcnJvcmVkX3RhYiA9IHRoaXMudGFicy5maW5kKCh0KSA9PiB0YWJfZXJyb3JzW3QuYXJncy5pZF0gPiAwKTtcblxuICAgICAgICAvLyBTd2l0Y2ggdG8gZmlyc3QgZXJyb3JlZCB0YWIgaWYgbm90IGN1cnJlbnRseSBvbiBhbiBlcnJvcmVkIHRhYlxuICAgICAgICBpZiAoZmlyc3RfZXJyb3JlZF90YWIgJiYgdGFiX2Vycm9yc1t0aGlzLmFjdGl2ZV90YWJfaWRdID09PSAwKSB7XG4gICAgICAgICAgICB0aGlzLmFjdGl2YXRlX3RhYihmaXJzdF9lcnJvcmVkX3RhYi5hcmdzLmlkKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGNsZWFyX2Vycm9yX2JhZGdlcygpIHtcbiAgICAgICAgdGhpcy4kaWQoJ25hdicpLmZpbmQoJ1tkYXRhLWVycm9yLWJhZGdlXScpLmhpZGUoKTtcbiAgICB9XG59XG4iLCIvKipcbiAqIFJzeF9UYWJcbiAqXG4gKiBJbmRpdmlkdWFsIHRhYiBwYW5lIGNvbXBvbmVudCB0aGF0IHdvcmtzIHdpdGggUnN4X1RhYnMgZm9yIGZvcm0gdmFsaWRhdGlvbi5cbiAqIFNlZSByc3hfdGFiLmpxaHRtbCBmb3IgZnVsbCBkb2N1bWVudGF0aW9uLlxuICpcbiAqIEphdmFTY3JpcHQgUmVzcG9uc2liaWxpdGllczpcbiAqIC0gQXV0by1yZWdpc3RlcnMgd2l0aCBwYXJlbnQgUnN4X1RhYnMgY29tcG9uZW50IG9uIGNyZWF0aW9uXG4gKiAtIFNldHMgdGFiIHBhbmUgSUQgYXR0cmlidXRlIGZyb20gJGlkIGFyZ3VtZW50XG4gKiAtIERpc2NvdmVycyBhbmQgdHJhY2tzIGNoaWxkIEZvcm1fRmllbGQgY29tcG9uZW50c1xuICogLSBDb3VudHMgdmFsaWRhdGlvbiBlcnJvcnMgd2l0aGluIHRoaXMgdGFiJ3MgZmllbGRzXG4gKiAtIFByb3ZpZGVzIGVycm9yIGNvdW50IHRvIHBhcmVudCBmb3IgYmFkZ2UgZGlzcGxheVxuICovXG5jbGFzcyBSc3hfVGFiIGV4dGVuZHMgSnFodG1sX0NvbXBvbmVudCB7XG4gICAgb25fY3JlYXRlKCkge1xuICAgICAgICBsZXQgdGhhdCA9IHRoaXM7XG5cbiAgICAgICAgLy8gU2V0IHRoZSB0YWIgSUQgZHluYW1pY2FsbHkgZnJvbSBhcmdzXG4gICAgICAgIGlmICh0aGF0LmFyZ3MuaWQpIHtcbiAgICAgICAgICAgIHRoYXQuJC5hdHRyKCdpZCcsIHRoYXQuYXJncy5pZCk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBGaW5kIHBhcmVudCBSc3hfVGFicyBhbmQgcmVnaXN0ZXJcbiAgICAgICAgdGhhdC50YWJzX2NvbnRhaW5lciA9IHRoYXQuY2xvc2VzdCgnLlJzeF9UYWJzJyk7XG4gICAgICAgIGlmICh0aGF0LnRhYnNfY29udGFpbmVyKSB7XG4gICAgICAgICAgICB0aGF0LnRhYnNfY29udGFpbmVyLnJlZ2lzdGVyX3RhYih0aGF0KTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFN0b3JlIHJlZmVyZW5jZSB0byBhbGwgRm9ybV9GaWVsZCBjb21wb25lbnRzIHdpdGhpbiB0aGlzIHRhYlxuICAgICAgICB0aGF0LmZpZWxkcyA9IFtdO1xuICAgIH1cblxuICAgIG9uX3JlYWR5KCkge1xuICAgICAgICBsZXQgdGhhdCA9IHRoaXM7XG5cbiAgICAgICAgLy8gRmluZCBhbGwgRm9ybV9GaWVsZCBjb21wb25lbnRzIHdpdGhpbiB0aGlzIHRhYlxuICAgICAgICB0aGF0LiQuZmluZCgnLkZvcm1fRmllbGQnKS5lYWNoKChpbmRleCwgZWxlbWVudCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgZmllbGRfY29tcG9uZW50ID0gJChlbGVtZW50KS5jb21wb25lbnQoKTtcbiAgICAgICAgICAgIGlmIChmaWVsZF9jb21wb25lbnQpIHtcbiAgICAgICAgICAgICAgICB0aGF0LmZpZWxkcy5wdXNoKGZpZWxkX2NvbXBvbmVudCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENvdW50IHZhbGlkYXRpb24gZXJyb3JzIGluIEZvcm1fRmllbGQgY29tcG9uZW50cyB3aXRoaW4gdGhpcyB0YWJcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gZXJyb3JzIC0gRXJyb3Igb2JqZWN0IGZyb20gZm9ybSB2YWxpZGF0aW9uIHtmaWVsZF9uYW1lOiBlcnJvcl9tZXNzYWdlfVxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IENvdW50IG9mIGVycm9ycyBpbiB0aGlzIHRhYlxuICAgICAqL1xuICAgIGNvdW50X2Vycm9ycyhlcnJvcnMpIHtcbiAgICAgICAgbGV0IHRoYXQgPSB0aGlzO1xuICAgICAgICBsZXQgY291bnQgPSAwO1xuXG4gICAgICAgIGZvciAobGV0IGZpZWxkIG9mIHRoYXQuZmllbGRzKSB7XG4gICAgICAgICAgICBpZiAoZXJyb3JzW2ZpZWxkLmFyZ3MubmFtZV0pIHtcbiAgICAgICAgICAgICAgICBjb3VudCsrO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGNvdW50O1xuICAgIH1cbn1cbiIsIi8qKlxuICogUnN4X0Zvcm1cbiAqXG4gKiBGb3JtIGNvbnRhaW5lciB3aXRoIHZhbGlkYXRpb24sIHN1Ym1pc3Npb24sIGFuZCB3aWRnZXQgdmFsdWUgbWFuYWdlbWVudC5cbiAqIFNlZSByc3hfZm9ybS5qcWh0bWwgZm9yIGZ1bGwgZG9jdW1lbnRhdGlvbi5cbiAqXG4gKiBKYXZhU2NyaXB0IFJlc3BvbnNpYmlsaXRpZXM6XG4gKiAtIFBhcnNlcyBhbmQgc3RvcmVzIGluaXRpYWwgZm9ybSBkYXRhIGZyb20gJGRhdGEgYXR0cmlidXRlIChKU09OIG9yIG9iamVjdClcbiAqIC0gRGlzY292ZXJzIGFuZCBtYW5hZ2VzIGNoaWxkIFdpZGdldCBjb21wb25lbnRzIHZpYSB2YWxzKCkgZ2V0dGVyL3NldHRlclxuICogLSBIYW5kbGVzIGZvcm0gc3VibWlzc2lvbiB2aWEgQWpheCB0byBjb250cm9sbGVyL21ldGhvZCBlbmRwb2ludHNcbiAqIC0gQXBwbGllcyB2YWxpZGF0aW9uIGVycm9ycyB0byBmaWVsZHMgdXNpbmcgRm9ybV9VdGlsc1xuICogLSBJbnRlZ3JhdGVzIHdpdGggUnN4X1RhYnMgZm9yIHRhYi1hd2FyZSBlcnJvciBoYW5kbGluZ1xuICogLSBQcm92aWRlcyBzZWVkKCkgZnVuY3Rpb25hbGl0eSBmb3IgZGVidWcvdGVzdGluZ1xuICogLSBNYW5hZ2VzIGZvcm0gc3RhdGUgKHZhbHVlcywgZXJyb3JzKSB0aHJvdWdob3V0IGxpZmVjeWNsZVxuICovXG5jbGFzcyBSc3hfRm9ybSBleHRlbmRzIEpxaHRtbF9Db21wb25lbnQge1xuICAgIG9uX2NyZWF0ZSgpIHtcbiAgICAgICAgdGhpcy5kYXRhLnZhbHVlcyA9IHt9OyAvLyBDdXJyZW50IGZvcm0gdmFsdWVzIHtuYW1lOiB2YWx1ZX1cbiAgICAgICAgdGhpcy5kYXRhLmVycm9ycyA9IHt9OyAvLyBWYWxpZGF0aW9uIGVycm9ycyB7bmFtZTogZXJyb3JfbWVzc2FnZX1cbiAgICAgICAgdGhpcy50YWJzID0gbnVsbDsgLy8gUmVmZXJlbmNlIHRvIFJzeF9UYWJzIGNvbXBvbmVudCBpZiBwcmVzZW50XG5cbiAgICAgICAgLy8gUGFyc2UgaW5pdGlhbCBkYXRhIGZyb20gJGRhdGEgYXR0cmlidXRlIChlLmcuLCBmcm9tICRkYXRhPSRjbGllbnQpXG4gICAgICAgIGxldCBkYXRhID0gdGhpcy5hcmdzLmRhdGE7XG5cbiAgICAgICAgaWYgKHR5cGVvZiBkYXRhID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAvLyBEZWNvZGUgSFRNTCBlbnRpdGllcyBiZWZvcmUgcGFyc2luZyBKU09OXG4gICAgICAgICAgICAgICAgLy8gVGhpcyBoYW5kbGVzIGNhc2VzIHdoZXJlIEpTT04gaXMgcGFzc2VkIHRocm91Z2ggQmxhZGUgeyEhICEhfSBzeW50YXhcbiAgICAgICAgICAgICAgICBjb25zdCBkZWNvZGVkID0gJCgnPHRleHRhcmVhPicpLmh0bWwoZGF0YSkudGV4dCgpO1xuICAgICAgICAgICAgICAgIGRhdGEgPSBqc29uX2RlY29kZShkZWNvZGVkKTtcbiAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKCdGb3JtOiBGYWlsZWQgdG8gcGFyc2UgZGF0YSBKU09OIHN0cmluZycsIGUpO1xuICAgICAgICAgICAgICAgIGRhdGEgPSB7fTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChkYXRhICYmIHR5cGVvZiBkYXRhID09PSAnb2JqZWN0Jykge1xuICAgICAgICAgICAgdGhpcy5kYXRhLnZhbHVlcyA9IGRhdGE7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBvbl9yZWFkeSgpIHtcbiAgICAgICAgY29uc3QgdGhhdCA9IHRoaXM7XG5cbiAgICAgICAgLy8gVmFsaWRhdGUgdGhhdCBlcnJvciBjb250YWluZXIgZXhpc3RzXG4gICAgICAgIGlmICghdGhpcy4kaWQoJ2Vycm9yJykuZXhpc3RzKCkpIHtcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKHRoaXMuJC5odG1sKCkpO1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgICAgICAgICdSc3hfRm9ybSByZXF1aXJlcyBhbiBlcnJvciBjb250YWluZXIgd2l0aCAkaWQ9XCJlcnJvclwiLiAnICtcbiAgICAgICAgICAgICAgICAgICAgJ0FkZCA8ZGl2ICRpZD1cImVycm9yXCI+PC9kaXY+IHRvIHlvdXIgZm9ybSB0ZW1wbGF0ZSBmb3IgZGlzcGxheWluZyB2YWxpZGF0aW9uIGFuZCBlcnJvciBtZXNzYWdlcy4nXG4gICAgICAgICAgICApO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gU2V0IHVwIHNlZWQgYnV0dG9uIGhhbmRsZXIgaWYgaW4gZGVidWcgbW9kZVxuICAgICAgICBpZiAod2luZG93LnJzeGFwcC5kZWJ1ZyAmJiB0aGlzLiRpZCgnc2VlZF9idG4nKS5leGlzdHMoKSkge1xuICAgICAgICAgICAgdGhhdC4kaWQoJ3NlZWRfYnRuJykub24oJ2NsaWNrJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHRoYXQuc2VlZCgpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBGaW5kIGNoaWxkIFJzeF9UYWJzIGNvbXBvbmVudCBpZiBwcmVzZW50IGZvciBlcnJvciBoYW5kbGluZyBpbnRlZ3JhdGlvblxuICAgICAgICBjb25zdCB0YWJzX2VsID0gdGhpcy4kLmZpbmQoJy5Sc3hfVGFicycpLmZpcnN0KCk7XG4gICAgICAgIGlmICh0YWJzX2VsLmxlbmd0aCkge1xuICAgICAgICAgICAgdGhhdC50YWJzID0gdGFic19lbC5jb21wb25lbnQoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIEF1dG9tYXRpY2FsbHkgd2lyZSBhbGwgc3VibWl0IGJ1dHRvbnMgdG8gY2FsbCBmb3JtIHN1Ym1pdCgpXG4gICAgICAgIHRoaXMuJC5maW5kKCdidXR0b25bdHlwZT1cInN1Ym1pdFwiXScpLmVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgJCh0aGlzKS5vbignY2xpY2snLCBmdW5jdGlvbiAoZSkge1xuICAgICAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICAgICAgICB0aGF0LnN1Ym1pdCgpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIE5vdGlmeSBhbGwgZmllbGRzIHRvIGxvYWQgdGhlaXIgaW5pdGlhbCB2YWx1ZXNcbiAgICAgICAgLy8gVGhpcyBoYXBwZW5zIGluIG9uX3JlYWR5IHRvIGVuc3VyZSBhbGwgRm9ybV9GaWVsZCBjaGlsZHJlbiBhcmUgaW5pdGlhbGl6ZWRcbiAgICAgICAgdGhpcy52YWxzKHRoaXMuZGF0YS52YWx1ZXMpO1xuXG4gICAgICAgIC8vIEhpZGUgbG9hZGluZyBzcGlubmVyIGFuZCBzaG93IGZvcm0gY29udGVudCAod2l0aG91dCByZS1yZW5kZXJpbmcpXG4gICAgICAgIHRoaXMuJGlkKCdsb2FkZXInKS5oaWRlKCk7XG4gICAgICAgIHRoaXMuJGlkKCdmb3JtX2NvbnRlbnQnKS5zaG93KCk7XG4gICAgfVxuXG4gICAgLy8gR2V0dGVyIG9yIHNldHRlciBmb3IgYWxsIGZvcm0gdmFsdWVzLCBzaW1pbGFyIHRvIGpxdWVyeSB2YWxcbiAgICB2YWxzKHZhbHVlcykge1xuICAgICAgICBpZiAodmFsdWVzKSB7XG4gICAgICAgICAgICAvLyBTZXR0ZXJcblxuICAgICAgICAgICAgdGhpcy4kLnNoYWxsb3dGaW5kKCcuV2lkZ2V0JykuZWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgbGV0ICR3aWRnZXQgPSAkKHRoaXMpO1xuICAgICAgICAgICAgICAgIGxldCBjb21wb25lbnQgPSAkd2lkZ2V0LmNvbXBvbmVudCgpO1xuICAgICAgICAgICAgICAgIGlmIChjb21wb25lbnQgJiYgJ3ZhbCcgaW4gY29tcG9uZW50KSB7XG4gICAgICAgICAgICAgICAgICAgIGxldCB3aWRnZXRfbmFtZSA9ICR3aWRnZXQuZGF0YSgnbmFtZScpO1xuICAgICAgICAgICAgICAgICAgICBpZiAod2lkZ2V0X25hbWUgaW4gdmFsdWVzKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb21wb25lbnQudmFsKHZhbHVlc1t3aWRnZXRfbmFtZV0pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gR2V0dGVyXG4gICAgICAgICAgICBsZXQgZGF0YSA9IHt9O1xuXG4gICAgICAgICAgICAvLyBHZXQgd2lkZ2V0IHZhbHVlc1xuICAgICAgICAgICAgdGhpcy4kLnNoYWxsb3dGaW5kKCcuV2lkZ2V0JykuZWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgbGV0ICR3aWRnZXQgPSAkKHRoaXMpO1xuICAgICAgICAgICAgICAgIGxldCBjb21wb25lbnQgPSAkd2lkZ2V0LmNvbXBvbmVudCgpO1xuICAgICAgICAgICAgICAgIGlmIChjb21wb25lbnQgJiYgJ3ZhbCcgaW4gY29tcG9uZW50KSB7XG4gICAgICAgICAgICAgICAgICAgIGxldCB3aWRnZXRfbmFtZSA9ICR3aWRnZXQuZGF0YSgnbmFtZScpO1xuICAgICAgICAgICAgICAgICAgICBkYXRhW3dpZGdldF9uYW1lXSA9IGNvbXBvbmVudC52YWwoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgLy8gQWxzbyBnZXQgcmVndWxhciBoaWRkZW4gaW5wdXRzIChub24td2lkZ2V0IGlucHV0cylcbiAgICAgICAgICAgIHRoaXMuJC5maW5kKCdpbnB1dFt0eXBlPVwiaGlkZGVuXCJdW25hbWVdJykuZWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgbGV0ICRpbnB1dCA9ICQodGhpcyk7XG4gICAgICAgICAgICAgICAgbGV0IG5hbWUgPSAkaW5wdXQuYXR0cignbmFtZScpO1xuICAgICAgICAgICAgICAgIGlmIChuYW1lKSB7XG4gICAgICAgICAgICAgICAgICAgIGRhdGFbbmFtZV0gPSAkaW5wdXQudmFsKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIHJldHVybiBkYXRhO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgZ2V0X2Vycm9yKG5hbWUpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZGF0YS5lcnJvcnNbbmFtZV07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmVuZGVyIGFuIGVycm9yIGluIHRoZSBmb3JtJ3MgZXJyb3IgY29udGFpbmVyXG4gICAgICpcbiAgICAgKiBIYW5kbGVzIGJvdGggZmllbGQtc3BlY2lmaWMgdmFsaWRhdGlvbiBlcnJvcnMgYW5kIGdlbmVyaWMgZXJyb3JzLlxuICAgICAqIENhbiBiZSBjYWxsZWQgYnkgZXh0ZXJuYWwgaGFuZGxlcnMgKGUuZy4sIG1vZGFsIG9uX3N1Ym1pdCkgb3IgaW50ZXJuYWxseVxuICAgICAqIGJ5IHRoZSBmb3JtJ3Mgb3duIHN1Ym1pdCgpIG1ldGhvZC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7RXJyb3J8T2JqZWN0fSBlcnJvciAtIEVycm9yIG9iamVjdCBmcm9tIEFqYXggY2FsbFxuICAgICAqL1xuICAgIGFzeW5jIHJlbmRlcl9lcnJvcihlcnJvcikge1xuICAgICAgICAvLyBIYW5kbGUgdmFsaWRhdGlvbiBlcnJvcnMgLSBhcHBseSB0byBmaWVsZHNcbiAgICAgICAgaWYgKGVycm9yLnR5cGUgPT09ICdmb3JtX2Vycm9yJyAmJiBlcnJvci5kZXRhaWxzKSB7XG4gICAgICAgICAgICBhd2FpdCBGb3JtX1V0aWxzLmFwcGx5X2Zvcm1fZXJyb3JzKHRoaXMuJCwgZXJyb3IuZGV0YWlscyk7XG5cbiAgICAgICAgICAgIC8vIE5vdGlmeSB0YWJzIG9mIHZhbGlkYXRpb24gZXJyb3JzIGZvciBlcnJvciBiYWRnZXMgYW5kIGF1dG8tc3dpdGNoaW5nXG4gICAgICAgICAgICBpZiAodGhpcy50YWJzKSB7XG4gICAgICAgICAgICAgICAgdGhpcy50YWJzLmhhbmRsZV92YWxpZGF0aW9uX2Vycm9ycyhlcnJvci5kZXRhaWxzKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gRm9ybV9VdGlscyBoYW5kbGVzIGFsbCByZW5kZXJpbmcgKGlubGluZSBlcnJvcnMgKyB1bm1hdGNoZWQgZXJyb3JzIGFsZXJ0KVxuICAgICAgICAgICAgLy8gRG9uJ3QgY2FsbCBSc3gucmVuZGVyX2Vycm9yKCkgdG8gYXZvaWQgZHVwbGljYXRlIGFsZXJ0c1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gRm9yIG5vbi1mb3JtIGVycm9ycyAoZmF0YWwsIGF1dGgsIG5ldHdvcmssIGV0Yy4pLCByZW5kZXIgaW4gZm9ybSdzIGVycm9yIGNvbnRhaW5lclxuICAgICAgICBSc3gucmVuZGVyX2Vycm9yKGVycm9yLCB0aGlzLiRpZCgnZXJyb3InKSk7XG4gICAgfVxuXG4gICAgYXN5bmMgc3VibWl0KCkge1xuICAgICAgICAvLyBDbGVhciBhbnkgcHJldmlvdXMgZXJyb3JzXG4gICAgICAgIEZvcm1fVXRpbHMucmVzZXRfZm9ybV9lcnJvcnModGhpcy4kKTtcbiAgICAgICAgdGhpcy4kaWQoJ2Vycm9yJykuZW1wdHkoKTtcblxuICAgICAgICAvLyBDbGVhciB0YWIgZXJyb3IgYmFkZ2VzIGlmIHRhYnMgYXJlIHByZXNlbnRcbiAgICAgICAgaWYgKHRoaXMudGFicykge1xuICAgICAgICAgICAgdGhpcy50YWJzLmNsZWFyX2Vycm9yX2JhZGdlcygpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gU2VyaWFsaXplIGFsbCBmaWVsZCB2YWx1ZXNcbiAgICAgICAgbGV0IHZhbHVlcyA9IHRoaXMudmFscygpO1xuXG4gICAgICAgIC8vIENhbGwgc3VibWl0IGhhbmRsZXJcbiAgICAgICAgaWYgKCF0aGlzLmFyZ3MuY29udHJvbGxlciB8fCAhdGhpcy5hcmdzLm1ldGhvZCkge1xuICAgICAgICAgICAgY29uc29sZS5lcnJvcignRm9ybTogTm8gY29udHJvbGxlci9tZXRob2QgcHJvdmlkZWQnKTtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignRm9ybSBjb25maWd1cmF0aW9uIGVycm9yOiBNaXNzaW5nIGNvbnRyb2xsZXIgb3IgbWV0aG9kJyk7XG4gICAgICAgIH1cblxuICAgICAgICB0cnkge1xuICAgICAgICAgICAgLy8gQnVpbGQgQWpheCBVUkwgZnJvbSBjb250cm9sbGVyIGFuZCBtZXRob2RcbiAgICAgICAgICAgIGNvbnN0IGFqYXhfdXJsID0gYC9fYWpheC8ke3RoaXMuYXJncy5jb250cm9sbGVyfS8ke3RoaXMuYXJncy5tZXRob2R9YDtcblxuICAgICAgICAgICAgLy8gQ2FsbCBBamF4IGVuZHBvaW50IC0gcmVzcG9uc2UgaXMgZGlyZWN0bHkgd2hhdCBQSFAgcmV0dXJuZWRcbiAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IEFqYXguY2FsbChhamF4X3VybCwgdmFsdWVzKTtcblxuICAgICAgICAgICAgLy8gU3VjY2VzcyEgSGFuZGxlIHJlc3VsdFxuICAgICAgICAgICAgaWYgKHJlc3VsdCAmJiByZXN1bHQucmVkaXJlY3QpIHtcbiAgICAgICAgICAgICAgICAvLyBSZWRpcmVjdCB0byBVUkxcbiAgICAgICAgICAgICAgICB3aW5kb3cubG9jYXRpb24uaHJlZiA9IHJlc3VsdC5yZWRpcmVjdDtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgLy8gU3VjY2VzcyB3aXRob3V0IHJlZGlyZWN0XG4gICAgICAgICAgICAgICAgY29uc29sZS5sb2coJ0Zvcm0gc3VibWl0dGVkIHN1Y2Nlc3NmdWxseScsIHJlc3VsdCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICAvLyBSZW5kZXIgZXJyb3IgKGhhbmRsZXMgYm90aCB2YWxpZGF0aW9uIGFuZCBnZW5lcmljIGVycm9ycylcbiAgICAgICAgICAgIGF3YWl0IHRoaXMucmVuZGVyX2Vycm9yKGVycm9yKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGFzeW5jIHNlZWQoKSB7XG4gICAgICAgIGNvbnN0IHByb21pc2VzID0gW107XG4gICAgICAgIHRoaXMuJC5zaGFsbG93RmluZCgnLkZvcm1fRmllbGQnKS5lYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGxldCBjb21wb25lbnQgPSAkKHRoaXMpLmNvbXBvbmVudCgpO1xuICAgICAgICAgICAgaWYgKGNvbXBvbmVudCAmJiAnc2VlZCcgaW4gY29tcG9uZW50KSB7XG4gICAgICAgICAgICAgICAgcHJvbWlzZXMucHVzaChjb21wb25lbnQuc2VlZCgpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIGF3YWl0IFByb21pc2UuYWxsKHByb21pc2VzKTtcbiAgICB9XG59XG4iLCIvKipcbiAqIFBpbl9WZXJpZmljYXRpb25fRm9ybVxuICpcbiAqIFNwZWNpYWxpemVkIDYtZGlnaXQgUElOIGVudHJ5IGZvcm0gd2l0aCBhdXRvLW5hdmlnYXRpb24gYmV0d2VlbiBpbnB1dHMuXG4gKiBTZWUgcGluX3ZlcmlmaWNhdGlvbl9mb3JtLmpxaHRtbCBmb3IgZnVsbCBkb2N1bWVudGF0aW9uLlxuICpcbiAqIEphdmFTY3JpcHQgUmVzcG9uc2liaWxpdGllczpcbiAqIC0gQXV0by1hZHZhbmNlcyB0byBuZXh0IGlucHV0IHdoZW4gZGlnaXQgaXMgZW50ZXJlZFxuICogLSBTbWFydCBiYWNrc3BhY2U6IGNsZWFycyBjdXJyZW50IGJveCBhbmQgbW92ZXMgdG8gcHJldmlvdXNcbiAqIC0gUGFzdGUgc3VwcG9ydDogZGlzdHJpYnV0ZXMgcGFzdGVkIGRpZ2l0cyBhY3Jvc3MgYWxsIDYgaW5wdXRzXG4gKiAtIEFycm93IGtleSBuYXZpZ2F0aW9uIGJldHdlZW4gaW5wdXRzXG4gKiAtIE51bWVyaWMtb25seSBpbnB1dCB2YWxpZGF0aW9uXG4gKiAtIFNlbGVjdC1hbGwgb24gZm9jdXMgZm9yIGVhc3kgZGlnaXQgcmVwbGFjZW1lbnRcbiAqIC0gVmFsaWRhdGVzIGFsbCA2IGRpZ2l0cyBlbnRlcmVkIGJlZm9yZSBhbGxvd2luZyBzdWJtaXNzaW9uXG4gKiAtIFByb3ZpZGVzIHZhbCgpIGdldHRlci9zZXR0ZXIgZm9yIHByb2dyYW1tYXRpYyBQSU4gYWNjZXNzXG4gKi9cbmNsYXNzIFBpbl9WZXJpZmljYXRpb25fRm9ybSBleHRlbmRzIFJzeF9Gb3JtIHtcbiAgICBvbl9jcmVhdGUoKSB7XG4gICAgICAgIHN1cGVyLm9uX2NyZWF0ZSgpO1xuICAgICAgICB0aGlzLnBpbl9sZW5ndGggPSA2O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldCBvciBzZXQgdGhlIFBJTiB2YWx1ZVxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbdmFsdWVdIC0gSWYgcHJvdmlkZWQsIHNldHMgdGhlIFBJTiAoZGlzdHJpYnV0ZXMgYWNyb3NzIGlucHV0cylcbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBDdXJyZW50IFBJTiB2YWx1ZSB3aGVuIGNhbGxlZCBhcyBnZXR0ZXJcbiAgICAgKi9cbiAgICB2YWwodmFsdWUpIHtcbiAgICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIC8vIEdldHRlciAtIGNvbGxlY3QgYWxsIGRpZ2l0c1xuICAgICAgICAgICAgbGV0IHBpbiA9ICcnO1xuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLnBpbl9sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgIHBpbiArPSB0aGlzLiRpZChgZGlnaXRfJHtpfWApLnZhbCgpIHx8ICcnO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHBpbjtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIFNldHRlciAtIGRpc3RyaWJ1dGUgZGlnaXRzIGFjcm9zcyBpbnB1dHNcbiAgICAgICAgICAgIGNvbnN0IGRpZ2l0cyA9IHN0cih2YWx1ZSB8fCAnJykucmVwbGFjZSgvW14wLTldL2csICcnKTtcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5waW5fbGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICB0aGlzLiRpZChgZGlnaXRfJHtpfWApLnZhbChkaWdpdHNbaV0gfHwgJycpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8gRm9jdXMgZmlyc3QgZW1wdHkgaW5wdXQgb3IgbGFzdCBpbnB1dFxuICAgICAgICAgICAgY29uc3QgZmlyc3RfZW1wdHkgPSB0aGlzLl9maW5kX2ZpcnN0X2VtcHR5X2luZGV4KCk7XG4gICAgICAgICAgICBpZiAoZmlyc3RfZW1wdHkgIT09IC0xKSB7XG4gICAgICAgICAgICAgICAgdGhpcy4kaWQoYGRpZ2l0XyR7Zmlyc3RfZW1wdHl9YClbMF0uZm9jdXMoKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy4kaWQoYGRpZ2l0XyR7dGhpcy5waW5fbGVuZ3RoIC0gMX1gKVswXS5mb2N1cygpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRmluZCB0aGUgZmlyc3QgZW1wdHkgaW5wdXQgaW5kZXhcbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBJbmRleCBvZiBmaXJzdCBlbXB0eSBpbnB1dCwgb3IgLTEgaWYgYWxsIGZpbGxlZFxuICAgICAqL1xuICAgIF9maW5kX2ZpcnN0X2VtcHR5X2luZGV4KCkge1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMucGluX2xlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBpZiAoIXRoaXMuJGlkKGBkaWdpdF8ke2l9YCkudmFsKCkpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gaTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gLTE7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogTW92ZSBmb2N1cyB0byBzcGVjaWZpYyBpbnB1dCBpbmRleFxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBpbmRleFxuICAgICAqL1xuICAgIF9mb2N1c19pbnB1dChpbmRleCkge1xuICAgICAgICBpZiAoaW5kZXggPj0gMCAmJiBpbmRleCA8IHRoaXMucGluX2xlbmd0aCkge1xuICAgICAgICAgICAgY29uc3QgJGlucHV0ID0gdGhpcy4kaWQoYGRpZ2l0XyR7aW5kZXh9YCk7XG4gICAgICAgICAgICBpZiAoJGlucHV0LmV4aXN0cygpKSB7XG4gICAgICAgICAgICAgICAgJGlucHV0WzBdLmZvY3VzKCk7XG4gICAgICAgICAgICAgICAgLy8gU2VsZWN0IHRoZSBjb250ZW50IGlmIHRoZXJlIGlzIGFueVxuICAgICAgICAgICAgICAgICRpbnB1dFswXS5zZWxlY3QoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEhhbmRsZSBwYXN0ZSBldmVudCAtIGRpc3RyaWJ1dGUgZGlnaXRzIGFjcm9zcyBpbnB1dHNcbiAgICAgKiBAcGFyYW0ge0NsaXBib2FyZEV2ZW50fSBlXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IHN0YXJ0X2luZGV4XG4gICAgICovXG4gICAgX2hhbmRsZV9wYXN0ZShlLCBzdGFydF9pbmRleCkge1xuICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG5cbiAgICAgICAgLy8gR2V0IHBhc3RlZCBkYXRhXG4gICAgICAgIGNvbnN0IHBhc3RlID0gKGUub3JpZ2luYWxFdmVudCB8fCBlKS5jbGlwYm9hcmREYXRhLmdldERhdGEoJ3RleHQnKTtcbiAgICAgICAgY29uc3QgZGlnaXRzID0gcGFzdGUucmVwbGFjZSgvW14wLTldL2csICcnKTtcblxuICAgICAgICBpZiAoIWRpZ2l0cykge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gRGlzdHJpYnV0ZSBkaWdpdHMgc3RhcnRpbmcgZnJvbSBjdXJyZW50IGlucHV0XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZGlnaXRzLmxlbmd0aCAmJiAoc3RhcnRfaW5kZXggKyBpKSA8IHRoaXMucGluX2xlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICB0aGlzLiRpZChgZGlnaXRfJHtzdGFydF9pbmRleCArIGl9YCkudmFsKGRpZ2l0c1tpXSk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBGb2N1cyBuZXh0IGVtcHR5IGlucHV0IG9yIGxhc3QgaW5wdXRcbiAgICAgICAgY29uc3QgbmV4dF9pbmRleCA9IE1hdGgubWluKHN0YXJ0X2luZGV4ICsgZGlnaXRzLmxlbmd0aCwgdGhpcy5waW5fbGVuZ3RoIC0gMSk7XG4gICAgICAgIHRoaXMuX2ZvY3VzX2lucHV0KG5leHRfaW5kZXgpO1xuICAgIH1cblxuICAgIG9uX3JlYWR5KCkge1xuICAgICAgICBzdXBlci5vbl9yZWFkeSgpO1xuXG4gICAgICAgIGNvbnN0IHRoYXQgPSB0aGlzO1xuXG4gICAgICAgIC8vIFNldCB1cCBldmVudCBoYW5kbGVycyBmb3IgZWFjaCBpbnB1dFxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMucGluX2xlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBjb25zdCAkaW5wdXQgPSB0aGlzLiRpZChgZGlnaXRfJHtpfWApO1xuICAgICAgICAgICAgY29uc3QgaW5kZXggPSBpO1xuXG4gICAgICAgICAgICAvLyBIYW5kbGUgaW5wdXQgZXZlbnQgLSBhdXRvLWFkdmFuY2VcbiAgICAgICAgICAgICRpbnB1dC5vbignaW5wdXQnLCBmdW5jdGlvbihlKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgdmFsdWUgPSAkKHRoaXMpLnZhbCgpO1xuXG4gICAgICAgICAgICAgICAgLy8gT25seSBhbGxvdyBudW1lcmljIGlucHV0XG4gICAgICAgICAgICAgICAgY29uc3QgbnVtZXJpYyA9IHZhbHVlLnJlcGxhY2UoL1teMC05XS9nLCAnJyk7XG4gICAgICAgICAgICAgICAgaWYgKG51bWVyaWMgIT09IHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgICAgICQodGhpcykudmFsKG51bWVyaWMpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIC8vIElmIG11bHRpcGxlIGRpZ2l0cyB3ZXJlIGVudGVyZWQgKHBhc3RlKSwgZGlzdHJpYnV0ZSB0aGVtXG4gICAgICAgICAgICAgICAgaWYgKG51bWVyaWMubGVuZ3RoID4gMSkge1xuICAgICAgICAgICAgICAgICAgICB0aGF0Ll9oYW5kbGVfcGFzdGUoe1xuICAgICAgICAgICAgICAgICAgICAgICAgcHJldmVudERlZmF1bHQ6ICgpID0+IHt9LFxuICAgICAgICAgICAgICAgICAgICAgICAgb3JpZ2luYWxFdmVudDoge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsaXBib2FyZERhdGE6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2V0RGF0YTogKCkgPT4gbnVtZXJpY1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSwgaW5kZXgpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgLy8gQXV0by1hZHZhbmNlIHRvIG5leHQgaW5wdXQgaWYgZGlnaXQgd2FzIGVudGVyZWRcbiAgICAgICAgICAgICAgICBpZiAobnVtZXJpYy5sZW5ndGggPT09IDEgJiYgaW5kZXggPCB0aGF0LnBpbl9sZW5ndGggLSAxKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoYXQuX2ZvY3VzX2lucHV0KGluZGV4ICsgMSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIC8vIEhhbmRsZSBrZXlkb3duIGZvciBiYWNrc3BhY2VcbiAgICAgICAgICAgICRpbnB1dC5vbigna2V5ZG93bicsIGZ1bmN0aW9uKGUpIHtcbiAgICAgICAgICAgICAgICAvLyBCYWNrc3BhY2Uga2V5XG4gICAgICAgICAgICAgICAgaWYgKGUua2V5ID09PSAnQmFja3NwYWNlJykge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBjdXJyZW50X3ZhbHVlID0gJCh0aGlzKS52YWwoKTtcblxuICAgICAgICAgICAgICAgICAgICAvLyBJZiBjdXJyZW50IGlucHV0IGlzIGVtcHR5LCBtb3ZlIHRvIHByZXZpb3VzIGFuZCBjbGVhciBpdFxuICAgICAgICAgICAgICAgICAgICBpZiAoIWN1cnJlbnRfdmFsdWUgJiYgaW5kZXggPiAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGF0LiRpZChgZGlnaXRfJHtpbmRleCAtIDF9YCkudmFsKCcnKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoYXQuX2ZvY3VzX2lucHV0KGluZGV4IC0gMSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgLy8gSWYgY3VycmVudCBpbnB1dCBoYXMgdmFsdWUsIGl0IHdpbGwgYmUgY2xlYXJlZCBieSBkZWZhdWx0IGJlaGF2aW9yXG4gICAgICAgICAgICAgICAgICAgIC8vIGFuZCB3ZSBzdGF5IG9uIGN1cnJlbnQgaW5wdXRcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAvLyBBcnJvdyBsZWZ0XG4gICAgICAgICAgICAgICAgaWYgKGUua2V5ID09PSAnQXJyb3dMZWZ0JyAmJiBpbmRleCA+IDApIHtcbiAgICAgICAgICAgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgICAgICAgICAgICB0aGF0Ll9mb2N1c19pbnB1dChpbmRleCAtIDEpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIC8vIEFycm93IHJpZ2h0XG4gICAgICAgICAgICAgICAgaWYgKGUua2V5ID09PSAnQXJyb3dSaWdodCcgJiYgaW5kZXggPCB0aGF0LnBpbl9sZW5ndGggLSAxKSB7XG4gICAgICAgICAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICAgICAgICAgICAgdGhhdC5fZm9jdXNfaW5wdXQoaW5kZXggKyAxKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgLy8gSGFuZGxlIHBhc3RlIGV2ZW50XG4gICAgICAgICAgICAkaW5wdXQub24oJ3Bhc3RlJywgZnVuY3Rpb24oZSkge1xuICAgICAgICAgICAgICAgIHRoYXQuX2hhbmRsZV9wYXN0ZShlLCBpbmRleCk7XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgLy8gU2VsZWN0IGFsbCBvbiBmb2N1cyBmb3IgZWFzeSByZXBsYWNlbWVudFxuICAgICAgICAgICAgJGlucHV0Lm9uKCdmb2N1cycsIGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgICAgICQodGhpcylbMF0uc2VsZWN0KCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIEZvY3VzIGZpcnN0IGlucHV0IG9uIGxvYWRcbiAgICAgICAgdGhpcy5fZm9jdXNfaW5wdXQoMCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogT3ZlcnJpZGUgc3VibWl0IHRvIHZhbGlkYXRlIFBJTiBpcyBjb21wbGV0ZVxuICAgICAqL1xuICAgIGFzeW5jIHN1Ym1pdCgpIHtcbiAgICAgICAgY29uc3QgcGluID0gdGhpcy52YWwoKTtcblxuICAgICAgICAvLyBDbGVhciBwcmV2aW91cyBlcnJvcnNcbiAgICAgICAgdGhpcy4kaWQoJ2Vycm9yX2NvbnRhaW5lcicpLmhpZGUoKS5lbXB0eSgpO1xuXG4gICAgICAgIC8vIFZhbGlkYXRlIFBJTiBpcyA2IGRpZ2l0c1xuICAgICAgICBpZiAocGluLmxlbmd0aCAhPT0gdGhpcy5waW5fbGVuZ3RoKSB7XG4gICAgICAgICAgICB0aGlzLiRpZCgnZXJyb3JfY29udGFpbmVyJylcbiAgICAgICAgICAgICAgICAudGV4dCgnUGxlYXNlIGVudGVyIGFsbCA2IGRpZ2l0cycpXG4gICAgICAgICAgICAgICAgLnNob3coKTtcblxuICAgICAgICAgICAgLy8gTWFyayBpbnB1dHMgYXMgaW52YWxpZFxuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLnBpbl9sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgIGlmICghdGhpcy4kaWQoYGRpZ2l0XyR7aX1gKS52YWwoKSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLiRpZChgZGlnaXRfJHtpfWApLmFkZENsYXNzKCdpcy1pbnZhbGlkJyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICAvLyBSZW1vdmUgaW52YWxpZCBjbGFzcyBmcm9tIGFsbCBpbnB1dHNcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLnBpbl9sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgdGhpcy4kaWQoYGRpZ2l0XyR7aX1gKS5yZW1vdmVDbGFzcygnaXMtaW52YWxpZCcpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gQ2FsbCBwYXJlbnQgc3VibWl0ICh3aGljaCB3aWxsIHVzZSBjb250cm9sbGVyL21ldGhvZCBpZiBwcm92aWRlZClcbiAgICAgICAgYXdhaXQgc3VwZXIuc3VibWl0KCk7XG4gICAgfVxufVxuIiwiLyoqXG4gKiBGb3JtX0ZpZWxkX0Fic3RyYWN0XG4gKlxuICogQWJzdHJhY3QgYmFzZSBjbGFzcyBmb3IgZm9ybSBmaWVsZCB3cmFwcGVycy4gUHJvdmlkZXMgY29yZSBmdW5jdGlvbmFsaXR5IHdpdGhvdXQgdmlzdWFsIGZvcm1hdHRpbmcuXG4gKiBTZWUgZm9ybV9maWVsZF9hYnN0cmFjdC5qcWh0bWwgZm9yIGZ1bGwgZG9jdW1lbnRhdGlvbi5cbiAqXG4gKiBKYXZhU2NyaXB0IFJlc3BvbnNpYmlsaXRpZXM6XG4gKiAtIERpc2NvdmVycyBhbmQgY29uZmlndXJlcyBjaGlsZCBXaWRnZXQgY29tcG9uZW50XG4gKiAtIFNldHMgZGF0YS1uYW1lIGF0dHJpYnV0ZSBvbiB3aWRnZXQgZm9yIGZvcm0gdmFsdWUgY29sbGVjdGlvblxuICogLSBTZXRzIG5hbWUgYXR0cmlidXRlIG9uIG5hdGl2ZSBpbnB1dHMgZm9yIEZvcm1fVXRpbHMgY29tcGF0aWJpbGl0eVxuICogLSBXaXJlcyBsYWJlbCAnZm9yJyBhdHRyaWJ1dGUgdG8gaW5wdXQgZWxlbWVudCBJRCBmb3IgYWNjZXNzaWJpbGl0eSAoaWYgbGFiZWwgZXhpc3RzKVxuICogLSBQcm92aWRlcyBzZWVkKCkgc3VwcG9ydCBmb3IgZGVidWcvdGVzdGluZyBkYXRhXG4gKiAtIEJyaWRnZXMgYmV0d2VlbiBmb3JtIHZhbGlkYXRpb24gc3RhdGUgYW5kIGNoaWxkIHdpZGdldFxuICovXG5jbGFzcyBGb3JtX0ZpZWxkX0Fic3RyYWN0IGV4dGVuZHMgSnFodG1sX0NvbXBvbmVudCB7XG4gICAgb25fY3JlYXRlKCkge1xuICAgICAgICAvLyBGaW5kIHBhcmVudCBmb3JtIGZvciBlcnJvciBkaXNwbGF5XG4gICAgICAgIHRoaXMuZm9ybSA9IHRoaXMuY2xvc2VzdCgnLlJzeF9Gb3JtJyk7XG4gICAgICAgIGlmICghdGhpcy5mb3JtKSB7XG4gICAgICAgICAgICBzaG91bGRudF9oYXBwZW4oJ0Zvcm1fRmllbGRfQWJzdHJhY3QgbXVzdCBiZSBpbnNpZGUgYSBSc3hfRm9ybSBjb21wb25lbnQnKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIG9uX3JlYWR5KCkge1xuICAgICAgICAvLyBGaW5kIGNoaWxkIHdpZGdldCBhbmQgc2V0IGl0cyBkYXRhLW5hbWUgYXR0cmlidXRlXG4gICAgICAgIGxldCAkd2lkZ2V0ID0gdGhpcy4kLmZpbmQoJy5XaWRnZXQnKS5maXJzdCgpO1xuXG4gICAgICAgIGlmICghJHdpZGdldC5leGlzdHMoKSkge1xuICAgICAgICAgICAgc2hvdWxkbnRfaGFwcGVuKFxuICAgICAgICAgICAgICAgIGBGb3JtX0ZpZWxkX0Fic3RyYWN0IFwiJHt0aGlzLmFyZ3MubmFtZX1cIiBoYXMgbm8gLldpZGdldCBjaGlsZC4gRXZlcnkgRm9ybV9GaWVsZCBtdXN0IGNvbnRhaW4gZXhhY3RseSBvbmUgd2lkZ2V0IChUZXh0X0lucHV0LCBXeXNpd3lnX0lucHV0LCBldGMuKWBcbiAgICAgICAgICAgICk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBTZXQgZGF0YS1uYW1lIG9uIHRoZSB3aWRnZXQgc28gUnN4X0Zvcm0gY2FuIGNvbGxlY3QgdmFsdWVzXG4gICAgICAgICR3aWRnZXQuYXR0cignZGF0YS1uYW1lJywgdGhpcy5hcmdzLm5hbWUpO1xuXG4gICAgICAgIGxldCAkaW5wdXQgPSB0aGlzLiQuZmluZCgnaW5wdXQsIHNlbGVjdCwgdGV4dGFyZWEnKS5maXJzdCgpO1xuICAgICAgICBpZiAoJGlucHV0LmV4aXN0cygpKSB7XG4gICAgICAgICAgICAvLyBBbHNvIHNldCBuYW1lIGF0dHJpYnV0ZSBvbiBuYXRpdmUgaW5wdXRzIGZvciBGb3JtX1V0aWxzIGNvbXBhdGliaWxpdHlcbiAgICAgICAgICAgIC8vIFRvZG86IGNsZXZlciB3YXkgdG8gZGVhbCB3aXRoIHRoaXMgZm9yIG5vbiBzdGFuZGFyZCBpbnB1dCBlbGVtZW50c1xuICAgICAgICAgICAgJGlucHV0LmF0dHIoJ25hbWUnLCB0aGlzLmFyZ3MubmFtZSk7XG5cbiAgICAgICAgICAgIC8vIFNldCB0aGUgZm9yIGZpZWxkIHRvIHRoZSBlbGVtZW50IGlmIGxhYmVsIGV4aXN0cyAoZm9yIGNoaWxkIGNsYXNzZXMpXG4gICAgICAgICAgICAvLyBUb2RvOiBjbGV2ZXIgd2F5IHRvIGRlYWwgd2l0aCB0aGlzIGZvciBub24gc3RhbmRhcmQgaW5wdXQgZWxlbWVudHNcbiAgICAgICAgICAgIGxldCAkbGFiZWwgPSB0aGlzLiRpZCgnZm9ybV9sYWJlbCcpO1xuICAgICAgICAgICAgaWYgKCRsYWJlbC5leGlzdHMoKSkge1xuICAgICAgICAgICAgICAgICRsYWJlbC5hdHRyKCdmb3InLCAkaW5wdXQuYXR0cignaWQnKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBnZXRfZXJyb3IoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmZvcm0uZ2V0X2Vycm9yKHRoaXMuYXJncy5uYW1lKTtcbiAgICB9XG5cbiAgICBoYXNfZXJyb3IoKSB7XG4gICAgICAgIHJldHVybiAhIXRoaXMuZ2V0X2Vycm9yKCk7XG4gICAgfVxuXG4gICAgYXN5bmMgc2VlZCgpIHtcbiAgICAgICAgaWYgKCF0aGlzLmFyZ3Muc2VlZGVyKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICAvLyBGaW5kIGNoaWxkIHdpZGdldFxuICAgICAgICBsZXQgJHdpZGdldCA9IHRoaXMuJC5maW5kKCcuV2lkZ2V0JykuZmlyc3QoKTtcbiAgICAgICAgaWYgKCEkd2lkZ2V0LmV4aXN0cygpKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBsZXQgd2lkZ2V0X2NvbXBvbmVudCA9ICR3aWRnZXQuY29tcG9uZW50KCk7XG4gICAgICAgIGlmICghd2lkZ2V0X2NvbXBvbmVudCB8fCAhd2lkZ2V0X2NvbXBvbmVudC52YWwpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIENhbGwgdGhlIHNlZWRlciBlbmRwb2ludCAoQWpheCByb3V0ZSByZWZlcmVuY2UgbGlrZSBmb3JtICRhY3Rpb24pXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBsZXQgdmFsdWUgPSBhd2FpdCBBamF4LmNhbGwodGhpcy5hcmdzLnNlZWRlciwge30pO1xuICAgICAgICAgICAgd2lkZ2V0X2NvbXBvbmVudC52YWwodmFsdWUpO1xuICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgY29uc29sZS5lcnJvcihgU2VlZGVyIGVycm9yIGZvciAke3RoaXMuYXJncy5uYW1lfTpgLCBlcnJvcik7XG4gICAgICAgIH1cbiAgICB9XG59XG4iLCIvKipcbiAqIEZvcm1fRmllbGRcbiAqXG4gKiBGb3JtIGZpZWxkIHdyYXBwZXIgdGhhdCBhZGRzIGxhYmVscywgaGVscCB0ZXh0LCBhbmQgcmVxdWlyZWQgaW5kaWNhdG9ycy5cbiAqIFNlZSBmb3JtX2ZpZWxkLmpxaHRtbCBmb3IgZnVsbCBkb2N1bWVudGF0aW9uLlxuICpcbiAqIEV4dGVuZHMgRm9ybV9GaWVsZF9BYnN0cmFjdCB0byBpbmhlcml0IGFsbCBjb3JlIGZ1bmN0aW9uYWxpdHkuXG4gKiBUaGlzIGNsYXNzIGV4aXN0cyBwcmltYXJpbHkgZm9yIHRlbXBsYXRlIGluaGVyaXRhbmNlIGFuZCBhbnkgZnV0dXJlXG4gKiBmb3JtYXR0ZWQtZmllbGQtc3BlY2lmaWMgYmVoYXZpb3IuXG4gKi9cbmNsYXNzIEZvcm1fRmllbGQgZXh0ZW5kcyBGb3JtX0ZpZWxkX0Fic3RyYWN0IHtcbiAgICAvLyBBbGwgZnVuY3Rpb25hbGl0eSBpbmhlcml0ZWQgZnJvbSBGb3JtX0ZpZWxkX0Fic3RyYWN0XG4gICAgLy8gVGhpcyBjbGFzcyBwcm92aWRlcyB0aGUgZm9ybWF0dGVkIHZpc3VhbCB3cmFwcGVyIHZpYSBpdHMgdGVtcGxhdGVcbn1cbiIsIi8qKlxuICogRm9ybV9IaWRkZW5fRmllbGQgLSBIaWRkZW4gaW5wdXQgZmllbGQgY29tcG9uZW50XG4gKlxuICogRXh0ZW5kcyBGb3JtX0ZpZWxkX0Fic3RyYWN0IGJ1dCBJUyB0aGUgaW5wdXQgZWxlbWVudCBpdHNlbGYgKHVzaW5nIHRhZz1cImlucHV0XCIgdHlwZT1cImhpZGRlblwiKS5cbiAqIFNlZSBmb3JtX2hpZGRlbl9maWVsZC5qcWh0bWwgZm9yIGZ1bGwgZG9jdW1lbnRhdGlvbi5cbiAqXG4gKiBKYXZhU2NyaXB0IFJlc3BvbnNpYmlsaXRpZXM6XG4gKiAtIFNldHMgdmFsdWUgYXR0cmlidXRlIGR5bmFtaWNhbGx5IGluIG9uX2NyZWF0ZSgpXG4gKiAtIE92ZXJyaWRlcyBvbl9yZWFkeSgpIHRvIGhhbmRsZSB0aGF0IHRoaXMuJCBJUyBib3RoIHRoZSB3aWRnZXQgYW5kIHRoZSBpbnB1dFxuICogLSBQcm92aWRlcyB2YWwoKSBtZXRob2QgZm9yIGdldHRpbmcvc2V0dGluZyB0aGUgaGlkZGVuIHZhbHVlXG4gKi9cbmNsYXNzIEZvcm1fSGlkZGVuX0ZpZWxkIGV4dGVuZHMgRm9ybV9GaWVsZF9BYnN0cmFjdCB7XG4gICAgb25fY3JlYXRlKCkge1xuICAgICAgICAvLyBDYWxsIHBhcmVudCB0byBzZXQgdXAgZm9ybSByZWZlcmVuY2VcbiAgICAgICAgc3VwZXIub25fY3JlYXRlKCk7XG5cbiAgICAgICAgLy8gU2V0IGluaXRpYWwgdmFsdWUgYXR0cmlidXRlIChjYW4ndCBiZSBkb25lIGluIERlZmluZSB0YWcpXG4gICAgICAgIHRoaXMuJC5hdHRyKCd2YWx1ZScsICcnKTtcbiAgICB9XG5cbiAgICBvbl9yZWFkeSgpIHtcbiAgICAgICAgLy8gT3ZlcnJpZGUgcGFyZW50IG9uX3JlYWR5KCkgYmVjYXVzZSB0aGlzLiQgSVMgdGhlIHdpZGdldCBhbmQgdGhlIGlucHV0XG4gICAgICAgIC8vIFNldCBkYXRhLW5hbWUgb24gdGhpcy4kICh3aGljaCBpcyB0aGUgaW5wdXQgZWxlbWVudClcbiAgICAgICAgdGhpcy4kLmF0dHIoJ2RhdGEtbmFtZScsIHRoaXMuYXJncy5uYW1lKTtcblxuICAgICAgICAvLyBTZXQgbmFtZSBhdHRyaWJ1dGUgb24gdGhpcy4kIGZvciBGb3JtX1V0aWxzIGNvbXBhdGliaWxpdHlcbiAgICAgICAgdGhpcy4kLmF0dHIoJ25hbWUnLCB0aGlzLmFyZ3MubmFtZSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogdmFsKCkgLSBHZXQgb3Igc2V0IHRoZSBoaWRkZW4gaW5wdXQgdmFsdWVcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gW3ZhbHVlXSAtIElmIHByb3ZpZGVkLCBzZXRzIHRoZSB2YWx1ZVxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFRoZSBjdXJyZW50IHZhbHVlIHdoZW4gY2FsbGVkIGFzIGdldHRlclxuICAgICAqL1xuICAgIHZhbCh2YWx1ZSkge1xuICAgICAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgLy8gR2V0dGVyIC0gdGhpcy4kIGlzIHRoZSBpbnB1dCBlbGVtZW50IGl0c2VsZlxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuJC52YWwoKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIFNldHRlciAtIHVwZGF0ZSB0aGUgaW5wdXQgdmFsdWUgZGlyZWN0bHkgKHRoaXMuJCBpcyB0aGUgaW5wdXQpXG4gICAgICAgICAgICB0aGlzLiQudmFsKHZhbHVlIHx8ICcnKTtcbiAgICAgICAgfVxuICAgIH1cbn1cbiIsImNsYXNzIEZyb250ZW5kX0Rhc2hib2FyZCB7XG4gICAgc3RhdGljIGluaXQoKSB7XG4gICAgICAgIGlmICghJChcIi5Gcm9udGVuZF9EYXNoYm9hcmRcIikuZXhpc3RzKCkpIHJldHVybjtcblxuICAgICAgICAvLyBJbml0aWFsaXplIHlvdXIgY29tcG9uZW50IGhlcmVcbiAgICAgICAgY29uc29sZS5sb2coJ0Zyb250ZW5kX0Rhc2hib2FyZCBpbml0aWFsaXplZCcpO1xuXG4gICAgICAgIC8vIEV4YW1wbGU6IEhhbmRsZSBidXR0b24gY2xpY2tzXG4gICAgICAgICQoJy5idG4tYWN0aW9uJykub24oJ2NsaWNrJywgZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICAvLyBIYW5kbGUgYWN0aW9uXG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIEV4YW1wbGU6IEluaXRpYWxpemUgdG9vbHRpcHNcbiAgICAgICAgJCgnW2RhdGEtYnMtdG9nZ2xlPVwidG9vbHRpcFwiXScpLnRvb2x0aXAoKTtcbiAgICB9XG5cbiAgICBzdGF0aWMgb25fYXBwX3JlYWR5KCkge1xuICAgICAgICBGcm9udGVuZF9EYXNoYm9hcmQuaW5pdCgpO1xuICAgIH1cblxuICAgIC8vIHN0YXRpYyBvbl9qcWh0bWxfcmVhZHkoKSB7XG4gICAgLy8gICAgIC8vIENhbGxlZCBhZnRlciBhbGwgSlFIVE1MIGNvbXBvbmVudHMgaGF2ZSBsb2FkZWQgYW5kIHJlbmRlcmVkXG4gICAgLy8gICAgIC8vIFVzZSB0aGlzIGlmIHlvdSBuZWVkIHRvIGludGVyYWN0IHdpdGggSlFIVE1MIGNvbXBvbmVudHNcbiAgICAvLyAgICAgLy8gT3RoZXJ3aXNlLCB1c2Ugb25fYXBwX3JlYWR5KCkgZm9yIG1vc3QgaW5pdGlhbGl6YXRpb25cbiAgICAvLyB9XG59IiwiLyoqXG4gKiBDbGllbnRzX0RhdGFHcmlkIENvbXBvbmVudFxuICpcbiAqIENvbmNyZXRlIGltcGxlbWVudGF0aW9uIGZvciBjbGllbnRzIGRhdGFncmlkLlxuICogQWxsIGZ1bmN0aW9uYWxpdHkgaXMgaW4gRGF0YUdyaWRfQWJzdHJhY3QuXG4gKi9cbmNsYXNzIENsaWVudHNfRGF0YUdyaWQgZXh0ZW5kcyBEYXRhR3JpZF9BYnN0cmFjdCB7XG4gICAgLy8gQWxsIGJlaGF2aW9yIGluaGVyaXRlZCBmcm9tIERhdGFHcmlkX0Fic3RyYWN0XG59XG4iLCJjbGFzcyBGcm9udGVuZF9DbGllbnRzX0VkaXQge1xuICAgIHN0YXRpYyBpbml0KCkge1xuICAgICAgICBpZiAoISQoJy5Gcm9udGVuZF9DbGllbnRzX0VkaXQnKS5leGlzdHMoKSkgcmV0dXJuO1xuXG4gICAgICAgIC8vIEhhbmRsZSBkeW5hbWljIHRhZyBhZGRpdGlvblxuICAgICAgICAkKCcjYWRkLXRhZycpLm9uKCdjbGljaycsIGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgY29uc3QgdGFnX2h0bWwgPSBgXG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImlucHV0LWdyb3VwIG1iLTJcIj5cbiAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJ0ZXh0XCIgY2xhc3M9XCJmb3JtLWNvbnRyb2xcIiBuYW1lPVwidGFnc1tdXCIgcGxhY2Vob2xkZXI9XCJlLmcuLCBWSVAsIEVudGVycHJpc2UsIFN0cmF0ZWdpYyBQYXJ0bmVyXCI+XG4gICAgICAgICAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJidG4gYnRuLWRhbmdlciByZW1vdmUtdGFnXCIgdHlwZT1cImJ1dHRvblwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGkgY2xhc3M9XCJiaSBiaS10cmFzaFwiPjwvaT5cbiAgICAgICAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICBgO1xuICAgICAgICAgICAgJCgnI3RhZ3MtY29udGFpbmVyJykuYXBwZW5kKHRhZ19odG1sKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gSGFuZGxlIHRhZyByZW1vdmFsXG4gICAgICAgICQoZG9jdW1lbnQpLm9uKCdjbGljaycsICcucmVtb3ZlLXRhZycsIGZ1bmN0aW9uKGUpIHtcbiAgICAgICAgICAgIGNvbnN0ICRidXR0b24gPSAkKGUuY3VycmVudFRhcmdldCk7XG4gICAgICAgICAgICAvLyBPbmx5IHJlbW92ZSBpZiBtb3JlIHRoYW4gb25lIHRhZyBmaWVsZCBleGlzdHNcbiAgICAgICAgICAgIGlmICgkKCcjdGFncy1jb250YWluZXIgLmlucHV0LWdyb3VwJykubGVuZ3RoID4gMSkge1xuICAgICAgICAgICAgICAgICRidXR0b24uY2xvc2VzdCgnLmlucHV0LWdyb3VwJykucmVtb3ZlKCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIC8vIENsZWFyIHRoZSB2YWx1ZSBvZiB0aGUgbGFzdCByZW1haW5pbmcgZmllbGRcbiAgICAgICAgICAgICAgICAkYnV0dG9uLmNsb3Nlc3QoJy5pbnB1dC1ncm91cCcpLmZpbmQoJ2lucHV0JykudmFsKCcnKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgc3RhdGljIG9uX2FwcF9yZWFkeSgpIHtcbiAgICAgICAgRnJvbnRlbmRfQ2xpZW50c19FZGl0LmluaXQoKTtcbiAgICB9XG59XG4iLCJjbGFzcyBGcm9udGVuZF9DbGllbnRzX1ZpZXcge1xuICAgIHN0YXRpYyBpbml0KCkge1xuICAgICAgICBpZiAoISQoXCIuRnJvbnRlbmRfQ2xpZW50c19WaWV3XCIpLmV4aXN0cygpKSByZXR1cm47XG5cbiAgICAgICAgY29uc29sZV9kZWJ1ZygnQ0xJRU5UJywgJ0Zyb250ZW5kX0NsaWVudHNfVmlldyBpbml0aWFsaXplZCcpO1xuXG4gICAgICAgIC8vIEhhbmRsZSBkZWxldGUgYnV0dG9uXG4gICAgICAgICQoJyNkZWxldGUtY2xpZW50LWJ0bicpLm9uKCdjbGljaycsIGFzeW5jIGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgY29uc3QgJGVsZW1lbnQgPSAkKHRoaXMpO1xuICAgICAgICAgICAgY29uc3QgY2xpZW50X2lkID0gJGVsZW1lbnQuZGF0YSgnY2xpZW50LWlkJyk7XG5cbiAgICAgICAgICAgIGNvbnN0IGNvbmZpcm1lZCA9IGF3YWl0IE1vZGFsLmNvbmZpcm0oXG4gICAgICAgICAgICAgICAgJ0RlbGV0ZSBDbGllbnQnLFxuICAgICAgICAgICAgICAgICdBcmUgeW91IHN1cmUgeW91IHdhbnQgdG8gZGVsZXRlIHRoaXMgY2xpZW50P1xcblxcblRoaXMgYWN0aW9uIGNhbiBiZSB1bmRvbmUgYnkgcmVzdG9yaW5nIHRoZSBjbGllbnQuJyxcbiAgICAgICAgICAgICAgICAnRGVsZXRlJyxcbiAgICAgICAgICAgICAgICAnQ2FuY2VsJ1xuICAgICAgICAgICAgKTtcblxuICAgICAgICAgICAgaWYgKGNvbmZpcm1lZCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IEZyb250ZW5kX0NsaWVudHNfQ29udHJvbGxlci5kZWxldGUoeyBpZDogY2xpZW50X2lkIH0pO1xuXG4gICAgICAgICAgICAgICAgaWYgKHJlc3VsdC5zdWNjZXNzKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIFJlbG9hZCB0aGUgcGFnZSB0byBzaG93IGRlbGV0ZWQgc3RhdHVzXG4gICAgICAgICAgICAgICAgICAgIGxvY2F0aW9uLnJlbG9hZCgpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGFsZXJ0KHJlc3VsdC5tZXNzYWdlIHx8ICdGYWlsZWQgdG8gZGVsZXRlIGNsaWVudCcpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gSGFuZGxlIHJlc3RvcmUgYnV0dG9uXG4gICAgICAgICQoJyNyZXN0b3JlLWNsaWVudC1idG4nKS5vbignY2xpY2snLCBhc3luYyBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgIGNvbnN0ICRlbGVtZW50ID0gJCh0aGlzKTtcbiAgICAgICAgICAgIGNvbnN0IGNsaWVudF9pZCA9ICRlbGVtZW50LmRhdGEoJ2NsaWVudC1pZCcpO1xuXG4gICAgICAgICAgICBjb25zdCBjb25maXJtZWQgPSBhd2FpdCBNb2RhbC5jb25maXJtKFxuICAgICAgICAgICAgICAgICdSZXN0b3JlIENsaWVudCcsXG4gICAgICAgICAgICAgICAgJ0FyZSB5b3Ugc3VyZSB5b3Ugd2FudCB0byByZXN0b3JlIHRoaXMgY2xpZW50PycsXG4gICAgICAgICAgICAgICAgJ1Jlc3RvcmUnLFxuICAgICAgICAgICAgICAgICdDYW5jZWwnXG4gICAgICAgICAgICApO1xuXG4gICAgICAgICAgICBpZiAoY29uZmlybWVkKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgRnJvbnRlbmRfQ2xpZW50c19Db250cm9sbGVyLnJlc3RvcmUoeyBpZDogY2xpZW50X2lkIH0pO1xuXG4gICAgICAgICAgICAgICAgaWYgKHJlc3VsdC5zdWNjZXNzKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIFJlbG9hZCB0aGUgcGFnZSB0byBzaG93IHJlc3RvcmVkIHN0YXR1c1xuICAgICAgICAgICAgICAgICAgICBsb2NhdGlvbi5yZWxvYWQoKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBhbGVydChyZXN1bHQubWVzc2FnZSB8fCAnRmFpbGVkIHRvIHJlc3RvcmUgY2xpZW50Jyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBzdGF0aWMgb25fYXBwX3JlYWR5KCkge1xuICAgICAgICBGcm9udGVuZF9DbGllbnRzX1ZpZXcuaW5pdCgpO1xuICAgIH1cbn1cbiIsImNsYXNzIEZyb250ZW5kX0NsaWVudHMge1xuICAgIHN0YXRpYyBpbml0KCkge1xuICAgICAgICBpZiAoISQoJy5Gcm9udGVuZF9DbGllbnRzJykuZXhpc3RzKCkpIHJldHVybjtcblxuICAgICAgICAvLyBJbml0aWFsaXplIHlvdXIgY29tcG9uZW50IGhlcmVcbiAgICAgICAgY29uc29sZS5sb2coJ0Zyb250ZW5kX0NsaWVudHMgaW5pdGlhbGl6ZWQnKTtcbiAgICB9XG5cbiAgICBzdGF0aWMgb25fYXBwX3JlYWR5KCkge1xuICAgICAgICBGcm9udGVuZF9DbGllbnRzLmluaXQoKTtcbiAgICB9XG59XG4iLCJjbGFzcyBGcm9udGVuZF9TZXR0aW5nc19UZWFtIHtcbiAgICBzdGF0aWMgaW5pdCgpIHtcbiAgICAgICAgaWYgKCEkKFwiLkZyb250ZW5kX1NldHRpbmdzX1RlYW1cIikuZXhpc3RzKCkpIHJldHVybjtcblxuICAgICAgICAvLyBJbml0aWFsaXplIHlvdXIgY29tcG9uZW50IGhlcmVcbiAgICAgICAgY29uc29sZS5sb2coJ0Zyb250ZW5kX1NldHRpbmdzX1RlYW0gaW5pdGlhbGl6ZWQnKTtcblxuICAgICAgICAvLyBFeGFtcGxlOiBIYW5kbGUgYnV0dG9uIGNsaWNrc1xuICAgICAgICAkKCcuYnRuLWFjdGlvbicpLm9uKCdjbGljaycsIGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgLy8gSGFuZGxlIGFjdGlvblxuICAgICAgICB9KTtcblxuICAgICAgICAvLyBFeGFtcGxlOiBJbml0aWFsaXplIHRvb2x0aXBzXG4gICAgICAgICQoJ1tkYXRhLWJzLXRvZ2dsZT1cInRvb2x0aXBcIl0nKS50b29sdGlwKCk7XG4gICAgfVxuXG4gICAgc3RhdGljIG9uX2FwcF9yZWFkeSgpIHtcbiAgICAgICAgRnJvbnRlbmRfU2V0dGluZ3NfVGVhbS5pbml0KCk7XG4gICAgfVxuXG4gICAgLy8gc3RhdGljIG9uX2pxaHRtbF9yZWFkeSgpIHtcbiAgICAvLyAgICAgLy8gQ2FsbGVkIGFmdGVyIGFsbCBKUUhUTUwgY29tcG9uZW50cyBoYXZlIGxvYWRlZCBhbmQgcmVuZGVyZWRcbiAgICAvLyAgICAgLy8gVXNlIHRoaXMgaWYgeW91IG5lZWQgdG8gaW50ZXJhY3Qgd2l0aCBKUUhUTUwgY29tcG9uZW50c1xuICAgIC8vICAgICAvLyBPdGhlcndpc2UsIHVzZSBvbl9hcHBfcmVhZHkoKSBmb3IgbW9zdCBpbml0aWFsaXphdGlvblxuICAgIC8vIH1cbn0iLCJjbGFzcyBGcm9udGVuZF9TZXR0aW5nc19Ob3RpZmljYXRpb25zIHtcbiAgICBzdGF0aWMgaW5pdCgpIHtcbiAgICAgICAgaWYgKCEkKFwiLkZyb250ZW5kX1NldHRpbmdzX05vdGlmaWNhdGlvbnNcIikuZXhpc3RzKCkpIHJldHVybjtcblxuICAgICAgICAvLyBJbml0aWFsaXplIHlvdXIgY29tcG9uZW50IGhlcmVcbiAgICAgICAgY29uc29sZS5sb2coJ0Zyb250ZW5kX1NldHRpbmdzX05vdGlmaWNhdGlvbnMgaW5pdGlhbGl6ZWQnKTtcblxuICAgICAgICAvLyBFeGFtcGxlOiBIYW5kbGUgYnV0dG9uIGNsaWNrc1xuICAgICAgICAkKCcuYnRuLWFjdGlvbicpLm9uKCdjbGljaycsIGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgLy8gSGFuZGxlIGFjdGlvblxuICAgICAgICB9KTtcblxuICAgICAgICAvLyBFeGFtcGxlOiBJbml0aWFsaXplIHRvb2x0aXBzXG4gICAgICAgICQoJ1tkYXRhLWJzLXRvZ2dsZT1cInRvb2x0aXBcIl0nKS50b29sdGlwKCk7XG4gICAgfVxuXG4gICAgc3RhdGljIG9uX2FwcF9yZWFkeSgpIHtcbiAgICAgICAgRnJvbnRlbmRfU2V0dGluZ3NfTm90aWZpY2F0aW9ucy5pbml0KCk7XG4gICAgfVxuXG4gICAgLy8gc3RhdGljIG9uX2pxaHRtbF9yZWFkeSgpIHtcbiAgICAvLyAgICAgLy8gQ2FsbGVkIGFmdGVyIGFsbCBKUUhUTUwgY29tcG9uZW50cyBoYXZlIGxvYWRlZCBhbmQgcmVuZGVyZWRcbiAgICAvLyAgICAgLy8gVXNlIHRoaXMgaWYgeW91IG5lZWQgdG8gaW50ZXJhY3Qgd2l0aCBKUUhUTUwgY29tcG9uZW50c1xuICAgIC8vICAgICAvLyBPdGhlcndpc2UsIHVzZSBvbl9hcHBfcmVhZHkoKSBmb3IgbW9zdCBpbml0aWFsaXphdGlvblxuICAgIC8vIH1cbn0iLCJjbGFzcyBGcm9udGVuZF9TZXR0aW5nc19CaWxsaW5nIHtcbiAgICBzdGF0aWMgaW5pdCgpIHtcbiAgICAgICAgaWYgKCEkKFwiLkZyb250ZW5kX1NldHRpbmdzX0JpbGxpbmdcIikuZXhpc3RzKCkpIHJldHVybjtcblxuICAgICAgICAvLyBJbml0aWFsaXplIHlvdXIgY29tcG9uZW50IGhlcmVcbiAgICAgICAgY29uc29sZS5sb2coJ0Zyb250ZW5kX1NldHRpbmdzX0JpbGxpbmcgaW5pdGlhbGl6ZWQnKTtcblxuICAgICAgICAvLyBFeGFtcGxlOiBIYW5kbGUgYnV0dG9uIGNsaWNrc1xuICAgICAgICAkKCcuYnRuLWFjdGlvbicpLm9uKCdjbGljaycsIGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgLy8gSGFuZGxlIGFjdGlvblxuICAgICAgICB9KTtcblxuICAgICAgICAvLyBFeGFtcGxlOiBJbml0aWFsaXplIHRvb2x0aXBzXG4gICAgICAgICQoJ1tkYXRhLWJzLXRvZ2dsZT1cInRvb2x0aXBcIl0nKS50b29sdGlwKCk7XG4gICAgfVxuXG4gICAgc3RhdGljIG9uX2FwcF9yZWFkeSgpIHtcbiAgICAgICAgRnJvbnRlbmRfU2V0dGluZ3NfQmlsbGluZy5pbml0KCk7XG4gICAgfVxuXG4gICAgLy8gc3RhdGljIG9uX2pxaHRtbF9yZWFkeSgpIHtcbiAgICAvLyAgICAgLy8gQ2FsbGVkIGFmdGVyIGFsbCBKUUhUTUwgY29tcG9uZW50cyBoYXZlIGxvYWRlZCBhbmQgcmVuZGVyZWRcbiAgICAvLyAgICAgLy8gVXNlIHRoaXMgaWYgeW91IG5lZWQgdG8gaW50ZXJhY3Qgd2l0aCBKUUhUTUwgY29tcG9uZW50c1xuICAgIC8vICAgICAvLyBPdGhlcndpc2UsIHVzZSBvbl9hcHBfcmVhZHkoKSBmb3IgbW9zdCBpbml0aWFsaXphdGlvblxuICAgIC8vIH1cbn0iLCJjbGFzcyBGcm9udGVuZF9TZXR0aW5nc19JbXBvcnQge1xuICAgIHN0YXRpYyBpbml0KCkge1xuICAgICAgICBpZiAoISQoXCIuRnJvbnRlbmRfU2V0dGluZ3NfSW1wb3J0XCIpLmV4aXN0cygpKSByZXR1cm47XG5cbiAgICAgICAgLy8gSW5pdGlhbGl6ZSB5b3VyIGNvbXBvbmVudCBoZXJlXG4gICAgICAgIGNvbnNvbGUubG9nKCdGcm9udGVuZF9TZXR0aW5nc19JbXBvcnQgaW5pdGlhbGl6ZWQnKTtcblxuICAgICAgICAvLyBFeGFtcGxlOiBIYW5kbGUgYnV0dG9uIGNsaWNrc1xuICAgICAgICAkKCcuYnRuLWFjdGlvbicpLm9uKCdjbGljaycsIGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgLy8gSGFuZGxlIGFjdGlvblxuICAgICAgICB9KTtcblxuICAgICAgICAvLyBFeGFtcGxlOiBJbml0aWFsaXplIHRvb2x0aXBzXG4gICAgICAgICQoJ1tkYXRhLWJzLXRvZ2dsZT1cInRvb2x0aXBcIl0nKS50b29sdGlwKCk7XG4gICAgfVxuXG4gICAgc3RhdGljIG9uX2FwcF9yZWFkeSgpIHtcbiAgICAgICAgRnJvbnRlbmRfU2V0dGluZ3NfSW1wb3J0LmluaXQoKTtcbiAgICB9XG5cbiAgICAvLyBzdGF0aWMgb25fanFodG1sX3JlYWR5KCkge1xuICAgIC8vICAgICAvLyBDYWxsZWQgYWZ0ZXIgYWxsIEpRSFRNTCBjb21wb25lbnRzIGhhdmUgbG9hZGVkIGFuZCByZW5kZXJlZFxuICAgIC8vICAgICAvLyBVc2UgdGhpcyBpZiB5b3UgbmVlZCB0byBpbnRlcmFjdCB3aXRoIEpRSFRNTCBjb21wb25lbnRzXG4gICAgLy8gICAgIC8vIE90aGVyd2lzZSwgdXNlIG9uX2FwcF9yZWFkeSgpIGZvciBtb3N0IGluaXRpYWxpemF0aW9uXG4gICAgLy8gfVxufSIsImNsYXNzIEZyb250ZW5kX1NldHRpbmdzX0FwaSB7XG4gICAgc3RhdGljIGluaXQoKSB7XG4gICAgICAgIGlmICghJChcIi5Gcm9udGVuZF9TZXR0aW5nc19BcGlcIikuZXhpc3RzKCkpIHJldHVybjtcblxuICAgICAgICAvLyBJbml0aWFsaXplIHlvdXIgY29tcG9uZW50IGhlcmVcbiAgICAgICAgY29uc29sZS5sb2coJ0Zyb250ZW5kX1NldHRpbmdzX0FwaSBpbml0aWFsaXplZCcpO1xuXG4gICAgICAgIC8vIEV4YW1wbGU6IEhhbmRsZSBidXR0b24gY2xpY2tzXG4gICAgICAgICQoJy5idG4tYWN0aW9uJykub24oJ2NsaWNrJywgZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICAvLyBIYW5kbGUgYWN0aW9uXG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIEV4YW1wbGU6IEluaXRpYWxpemUgdG9vbHRpcHNcbiAgICAgICAgJCgnW2RhdGEtYnMtdG9nZ2xlPVwidG9vbHRpcFwiXScpLnRvb2x0aXAoKTtcbiAgICB9XG5cbiAgICBzdGF0aWMgb25fYXBwX3JlYWR5KCkge1xuICAgICAgICBGcm9udGVuZF9TZXR0aW5nc19BcGkuaW5pdCgpO1xuICAgIH1cblxuICAgIC8vIHN0YXRpYyBvbl9qcWh0bWxfcmVhZHkoKSB7XG4gICAgLy8gICAgIC8vIENhbGxlZCBhZnRlciBhbGwgSlFIVE1MIGNvbXBvbmVudHMgaGF2ZSBsb2FkZWQgYW5kIHJlbmRlcmVkXG4gICAgLy8gICAgIC8vIFVzZSB0aGlzIGlmIHlvdSBuZWVkIHRvIGludGVyYWN0IHdpdGggSlFIVE1MIGNvbXBvbmVudHNcbiAgICAvLyAgICAgLy8gT3RoZXJ3aXNlLCB1c2Ugb25fYXBwX3JlYWR5KCkgZm9yIG1vc3QgaW5pdGlhbGl6YXRpb25cbiAgICAvLyB9XG59IiwiY2xhc3MgRnJvbnRlbmRfU2V0dGluZ3NfVGVtcGxhdGVzIHtcbiAgICBzdGF0aWMgaW5pdCgpIHtcbiAgICAgICAgaWYgKCEkKFwiLkZyb250ZW5kX1NldHRpbmdzX1RlbXBsYXRlc1wiKS5leGlzdHMoKSkgcmV0dXJuO1xuXG4gICAgICAgIC8vIEluaXRpYWxpemUgeW91ciBjb21wb25lbnQgaGVyZVxuICAgICAgICBjb25zb2xlLmxvZygnRnJvbnRlbmRfU2V0dGluZ3NfVGVtcGxhdGVzIGluaXRpYWxpemVkJyk7XG5cbiAgICAgICAgLy8gRXhhbXBsZTogSGFuZGxlIGJ1dHRvbiBjbGlja3NcbiAgICAgICAgJCgnLmJ0bi1hY3Rpb24nKS5vbignY2xpY2snLCBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgIC8vIEhhbmRsZSBhY3Rpb25cbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gRXhhbXBsZTogSW5pdGlhbGl6ZSB0b29sdGlwc1xuICAgICAgICAkKCdbZGF0YS1icy10b2dnbGU9XCJ0b29sdGlwXCJdJykudG9vbHRpcCgpO1xuICAgIH1cblxuICAgIHN0YXRpYyBvbl9hcHBfcmVhZHkoKSB7XG4gICAgICAgIEZyb250ZW5kX1NldHRpbmdzX1RlbXBsYXRlcy5pbml0KCk7XG4gICAgfVxuXG4gICAgLy8gc3RhdGljIG9uX2pxaHRtbF9yZWFkeSgpIHtcbiAgICAvLyAgICAgLy8gQ2FsbGVkIGFmdGVyIGFsbCBKUUhUTUwgY29tcG9uZW50cyBoYXZlIGxvYWRlZCBhbmQgcmVuZGVyZWRcbiAgICAvLyAgICAgLy8gVXNlIHRoaXMgaWYgeW91IG5lZWQgdG8gaW50ZXJhY3Qgd2l0aCBKUUhUTUwgY29tcG9uZW50c1xuICAgIC8vICAgICAvLyBPdGhlcndpc2UsIHVzZSBvbl9hcHBfcmVhZHkoKSBmb3IgbW9zdCBpbml0aWFsaXphdGlvblxuICAgIC8vIH1cbn0iLCJjbGFzcyBGcm9udGVuZF9TZXR0aW5nc19BdWRpdCB7XG4gICAgc3RhdGljIGluaXQoKSB7XG4gICAgICAgIGlmICghJChcIi5Gcm9udGVuZF9TZXR0aW5nc19BdWRpdFwiKS5leGlzdHMoKSkgcmV0dXJuO1xuXG4gICAgICAgIC8vIEluaXRpYWxpemUgeW91ciBjb21wb25lbnQgaGVyZVxuICAgICAgICBjb25zb2xlLmxvZygnRnJvbnRlbmRfU2V0dGluZ3NfQXVkaXQgaW5pdGlhbGl6ZWQnKTtcblxuICAgICAgICAvLyBFeGFtcGxlOiBIYW5kbGUgYnV0dG9uIGNsaWNrc1xuICAgICAgICAkKCcuYnRuLWFjdGlvbicpLm9uKCdjbGljaycsIGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgLy8gSGFuZGxlIGFjdGlvblxuICAgICAgICB9KTtcblxuICAgICAgICAvLyBFeGFtcGxlOiBJbml0aWFsaXplIHRvb2x0aXBzXG4gICAgICAgICQoJ1tkYXRhLWJzLXRvZ2dsZT1cInRvb2x0aXBcIl0nKS50b29sdGlwKCk7XG4gICAgfVxuXG4gICAgc3RhdGljIG9uX2FwcF9yZWFkeSgpIHtcbiAgICAgICAgRnJvbnRlbmRfU2V0dGluZ3NfQXVkaXQuaW5pdCgpO1xuICAgIH1cblxuICAgIC8vIHN0YXRpYyBvbl9qcWh0bWxfcmVhZHkoKSB7XG4gICAgLy8gICAgIC8vIENhbGxlZCBhZnRlciBhbGwgSlFIVE1MIGNvbXBvbmVudHMgaGF2ZSBsb2FkZWQgYW5kIHJlbmRlcmVkXG4gICAgLy8gICAgIC8vIFVzZSB0aGlzIGlmIHlvdSBuZWVkIHRvIGludGVyYWN0IHdpdGggSlFIVE1MIGNvbXBvbmVudHNcbiAgICAvLyAgICAgLy8gT3RoZXJ3aXNlLCB1c2Ugb25fYXBwX3JlYWR5KCkgZm9yIG1vc3QgaW5pdGlhbGl6YXRpb25cbiAgICAvLyB9XG59IiwiY2xhc3MgRnJvbnRlbmRfU2V0dGluZ3NfUHJvZmlsZV9EaXNwbGF5IHtcbiAgICBzdGF0aWMgaW5pdCgpIHtcbiAgICAgICAgaWYgKCEkKFwiLkZyb250ZW5kX1NldHRpbmdzX1Byb2ZpbGVfRGlzcGxheVwiKS5leGlzdHMoKSkgcmV0dXJuO1xuXG4gICAgICAgIC8vIEluaXRpYWxpemUgeW91ciBjb21wb25lbnQgaGVyZVxuICAgICAgICBjb25zb2xlLmxvZygnRnJvbnRlbmRfU2V0dGluZ3NfUHJvZmlsZV9EaXNwbGF5IGluaXRpYWxpemVkJyk7XG5cbiAgICAgICAgLy8gRXhhbXBsZTogSGFuZGxlIGJ1dHRvbiBjbGlja3NcbiAgICAgICAgJCgnLmJ0bi1hY3Rpb24nKS5vbignY2xpY2snLCBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgIC8vIEhhbmRsZSBhY3Rpb25cbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gRXhhbXBsZTogSW5pdGlhbGl6ZSB0b29sdGlwc1xuICAgICAgICAkKCdbZGF0YS1icy10b2dnbGU9XCJ0b29sdGlwXCJdJykudG9vbHRpcCgpO1xuICAgIH1cblxuICAgIHN0YXRpYyBvbl9hcHBfcmVhZHkoKSB7XG4gICAgICAgIEZyb250ZW5kX1NldHRpbmdzX1Byb2ZpbGVfRGlzcGxheS5pbml0KCk7XG4gICAgfVxuXG4gICAgLy8gc3RhdGljIG9uX2pxaHRtbF9yZWFkeSgpIHtcbiAgICAvLyAgICAgLy8gQ2FsbGVkIGFmdGVyIGFsbCBKUUhUTUwgY29tcG9uZW50cyBoYXZlIGxvYWRlZCBhbmQgcmVuZGVyZWRcbiAgICAvLyAgICAgLy8gVXNlIHRoaXMgaWYgeW91IG5lZWQgdG8gaW50ZXJhY3Qgd2l0aCBKUUhUTUwgY29tcG9uZW50c1xuICAgIC8vICAgICAvLyBPdGhlcndpc2UsIHVzZSBvbl9hcHBfcmVhZHkoKSBmb3IgbW9zdCBpbml0aWFsaXphdGlvblxuICAgIC8vIH1cbn0iLCJjbGFzcyBGcm9udGVuZF9TZXR0aW5nc19Vc2VyX1NldHRpbmdzIHtcbiAgICBzdGF0aWMgaW5pdCgpIHtcbiAgICAgICAgaWYgKCEkKFwiLkZyb250ZW5kX1NldHRpbmdzX1VzZXJfU2V0dGluZ3NcIikuZXhpc3RzKCkpIHJldHVybjtcblxuICAgICAgICAvLyBJbml0aWFsaXplIHlvdXIgY29tcG9uZW50IGhlcmVcbiAgICAgICAgY29uc29sZS5sb2coJ0Zyb250ZW5kX1NldHRpbmdzX1VzZXJfU2V0dGluZ3MgaW5pdGlhbGl6ZWQnKTtcblxuICAgICAgICAvLyBFeGFtcGxlOiBIYW5kbGUgYnV0dG9uIGNsaWNrc1xuICAgICAgICAkKCcuYnRuLWFjdGlvbicpLm9uKCdjbGljaycsIGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgLy8gSGFuZGxlIGFjdGlvblxuICAgICAgICB9KTtcblxuICAgICAgICAvLyBFeGFtcGxlOiBJbml0aWFsaXplIHRvb2x0aXBzXG4gICAgICAgICQoJ1tkYXRhLWJzLXRvZ2dsZT1cInRvb2x0aXBcIl0nKS50b29sdGlwKCk7XG4gICAgfVxuXG4gICAgc3RhdGljIG9uX2FwcF9yZWFkeSgpIHtcbiAgICAgICAgRnJvbnRlbmRfU2V0dGluZ3NfVXNlcl9TZXR0aW5ncy5pbml0KCk7XG4gICAgfVxuXG4gICAgLy8gc3RhdGljIG9uX2pxaHRtbF9yZWFkeSgpIHtcbiAgICAvLyAgICAgLy8gQ2FsbGVkIGFmdGVyIGFsbCBKUUhUTUwgY29tcG9uZW50cyBoYXZlIGxvYWRlZCBhbmQgcmVuZGVyZWRcbiAgICAvLyAgICAgLy8gVXNlIHRoaXMgaWYgeW91IG5lZWQgdG8gaW50ZXJhY3Qgd2l0aCBKUUhUTUwgY29tcG9uZW50c1xuICAgIC8vICAgICAvLyBPdGhlcndpc2UsIHVzZSBvbl9hcHBfcmVhZHkoKSBmb3IgbW9zdCBpbml0aWFsaXphdGlvblxuICAgIC8vIH1cbn0iLCJjbGFzcyBGcm9udGVuZF9TZXR0aW5nc19QYXNzd29yZF9TZWN1cml0eSB7XG4gICAgc3RhdGljIGluaXQoKSB7XG4gICAgICAgIGlmICghJChcIi5Gcm9udGVuZF9TZXR0aW5nc19QYXNzd29yZF9TZWN1cml0eVwiKS5leGlzdHMoKSkgcmV0dXJuO1xuXG4gICAgICAgIC8vIEluaXRpYWxpemUgeW91ciBjb21wb25lbnQgaGVyZVxuICAgICAgICBjb25zb2xlLmxvZygnRnJvbnRlbmRfU2V0dGluZ3NfUGFzc3dvcmRfU2VjdXJpdHkgaW5pdGlhbGl6ZWQnKTtcblxuICAgICAgICAvLyBFeGFtcGxlOiBIYW5kbGUgYnV0dG9uIGNsaWNrc1xuICAgICAgICAkKCcuYnRuLWFjdGlvbicpLm9uKCdjbGljaycsIGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgLy8gSGFuZGxlIGFjdGlvblxuICAgICAgICB9KTtcblxuICAgICAgICAvLyBFeGFtcGxlOiBJbml0aWFsaXplIHRvb2x0aXBzXG4gICAgICAgICQoJ1tkYXRhLWJzLXRvZ2dsZT1cInRvb2x0aXBcIl0nKS50b29sdGlwKCk7XG4gICAgfVxuXG4gICAgc3RhdGljIG9uX2FwcF9yZWFkeSgpIHtcbiAgICAgICAgRnJvbnRlbmRfU2V0dGluZ3NfUGFzc3dvcmRfU2VjdXJpdHkuaW5pdCgpO1xuICAgIH1cblxuICAgIC8vIHN0YXRpYyBvbl9qcWh0bWxfcmVhZHkoKSB7XG4gICAgLy8gICAgIC8vIENhbGxlZCBhZnRlciBhbGwgSlFIVE1MIGNvbXBvbmVudHMgaGF2ZSBsb2FkZWQgYW5kIHJlbmRlcmVkXG4gICAgLy8gICAgIC8vIFVzZSB0aGlzIGlmIHlvdSBuZWVkIHRvIGludGVyYWN0IHdpdGggSlFIVE1MIGNvbXBvbmVudHNcbiAgICAvLyAgICAgLy8gT3RoZXJ3aXNlLCB1c2Ugb25fYXBwX3JlYWR5KCkgZm9yIG1vc3QgaW5pdGlhbGl6YXRpb25cbiAgICAvLyB9XG59IiwiY2xhc3MgRnJvbnRlbmRfU2V0dGluZ3NfQXBpX0tleXMge1xuICAgIHN0YXRpYyBpbml0KCkge1xuICAgICAgICBpZiAoISQoXCIuRnJvbnRlbmRfU2V0dGluZ3NfQXBpX0tleXNcIikuZXhpc3RzKCkpIHJldHVybjtcblxuICAgICAgICAvLyBJbml0aWFsaXplIHlvdXIgY29tcG9uZW50IGhlcmVcbiAgICAgICAgY29uc29sZS5sb2coJ0Zyb250ZW5kX1NldHRpbmdzX0FwaV9LZXlzIGluaXRpYWxpemVkJyk7XG5cbiAgICAgICAgLy8gRXhhbXBsZTogSGFuZGxlIGJ1dHRvbiBjbGlja3NcbiAgICAgICAgJCgnLmJ0bi1hY3Rpb24nKS5vbignY2xpY2snLCBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgIC8vIEhhbmRsZSBhY3Rpb25cbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gRXhhbXBsZTogSW5pdGlhbGl6ZSB0b29sdGlwc1xuICAgICAgICAkKCdbZGF0YS1icy10b2dnbGU9XCJ0b29sdGlwXCJdJykudG9vbHRpcCgpO1xuICAgIH1cblxuICAgIHN0YXRpYyBvbl9hcHBfcmVhZHkoKSB7XG4gICAgICAgIEZyb250ZW5kX1NldHRpbmdzX0FwaV9LZXlzLmluaXQoKTtcbiAgICB9XG5cbiAgICAvLyBzdGF0aWMgb25fanFodG1sX3JlYWR5KCkge1xuICAgIC8vICAgICAvLyBDYWxsZWQgYWZ0ZXIgYWxsIEpRSFRNTCBjb21wb25lbnRzIGhhdmUgbG9hZGVkIGFuZCByZW5kZXJlZFxuICAgIC8vICAgICAvLyBVc2UgdGhpcyBpZiB5b3UgbmVlZCB0byBpbnRlcmFjdCB3aXRoIEpRSFRNTCBjb21wb25lbnRzXG4gICAgLy8gICAgIC8vIE90aGVyd2lzZSwgdXNlIG9uX2FwcF9yZWFkeSgpIGZvciBtb3N0IGluaXRpYWxpemF0aW9uXG4gICAgLy8gfVxufSIsIi8qKlxyXG4gKiBVc2Vyc19EYXRhR3JpZCBDb21wb25lbnRcclxuICpcclxuICogQ29uY3JldGUgaW1wbGVtZW50YXRpb24gZm9yIGNsaWVudHMgZGF0YWdyaWQuXHJcbiAqIEFsbCBmdW5jdGlvbmFsaXR5IGlzIGluIERhdGFHcmlkX0Fic3RyYWN0LlxyXG4gKi9cclxuY2xhc3MgVXNlcnNfRGF0YUdyaWQgZXh0ZW5kcyBEYXRhR3JpZF9BYnN0cmFjdCB7XHJcbiAgICAvLyBBbGwgYmVoYXZpb3IgaW5oZXJpdGVkIGZyb20gRGF0YUdyaWRfQWJzdHJhY3RcclxufVxyXG4iLCIvKipcbiAqIEFkZF9Vc2VyX0Zvcm1cbiAqXG4gKiBNb2RhbCBmb3JtIGNvbXBvbmVudCBmb3IgaW52aXRpbmcgdXNlcnMgdG8gdGhlIGN1cnJlbnQgc2l0ZS5cbiAqIFNlZSBhZGRfdXNlcl9mb3JtLmpxaHRtbCBmb3IgZnVsbCBkb2N1bWVudGF0aW9uLlxuICpcbiAqIEphdmFTY3JpcHQgUmVzcG9uc2liaWxpdGllczpcbiAqIC0gSW1wbGVtZW50cyB2YWxzKCkgbWV0aG9kIGZvciBmb3JtIGRhdGEgZXh0cmFjdGlvblxuICogLSBQcm92aWRlcyBkZWZhdWx0IHJvbGVfaWQgKE1lbWJlciA9IDMpXG4gKi9cbmNsYXNzIEFkZF9Vc2VyX0Zvcm0gZXh0ZW5kcyBKcWh0bWxfQ29tcG9uZW50IHtcbiAgICAvKipcbiAgICAgKiBHZXQgb3Igc2V0IGZvcm0gdmFsdWVzXG4gICAgICogQHBhcmFtIHtPYmplY3R9IFt2YWx1ZXNdIC0gSWYgcHJvdmlkZWQsIHBvcHVsYXRlcyBmb3JtIHdpdGggdGhlc2UgdmFsdWVzXG4gICAgICogQHJldHVybnMge09iamVjdHxudWxsfSAtIEZvcm0gdmFsdWVzIGlmIGdldHRpbmcsIG51bGwgaWYgc2V0dGluZ1xuICAgICAqL1xuICAgIC8vIHZhbHModmFsdWVzKSB7XG4gICAgLy8gICAgIGNvbnN0IGZvcm0gPSB0aGlzLiQuZmluZCgnZm9ybScpO1xuICAgIC8vICAgICBpZiAodmFsdWVzKSB7XG4gICAgLy8gICAgICAgICAvLyBTZXR0ZXIgLSBwb3B1bGF0ZSBmb3JtXG4gICAgLy8gICAgICAgICBmb3JtLmZpbmQoJ1tuYW1lPVwiZW1haWxcIl0nKS52YWwodmFsdWVzLmVtYWlsIHx8ICcnKTtcbiAgICAvLyAgICAgICAgIGZvcm0uZmluZCgnW25hbWU9XCJmaXJzdF9uYW1lXCJdJykudmFsKHZhbHVlcy5maXJzdF9uYW1lIHx8ICcnKTtcbiAgICAvLyAgICAgICAgIGZvcm0uZmluZCgnW25hbWU9XCJsYXN0X25hbWVcIl0nKS52YWwodmFsdWVzLmxhc3RfbmFtZSB8fCAnJyk7XG4gICAgLy8gICAgICAgICBmb3JtLmZpbmQoJ1tuYW1lPVwicm9sZV9pZFwiXScpLnZhbCh2YWx1ZXMucm9sZV9pZCB8fCAzKTsgLy8gRGVmYXVsdCB0byBNZW1iZXJcbiAgICAvLyAgICAgICAgIGZvcm0uZmluZCgnW25hbWU9XCJwaG9uZVwiXScpLnZhbCh2YWx1ZXMucGhvbmUgfHwgJycpO1xuICAgIC8vICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgLy8gICAgIH0gZWxzZSB7XG4gICAgLy8gICAgICAgICAvLyBHZXR0ZXIgLSBleHRyYWN0IGZvcm0gdmFsdWVzXG4gICAgLy8gICAgICAgICByZXR1cm4ge1xuICAgIC8vICAgICAgICAgICAgIGVtYWlsOiBmb3JtLmZpbmQoJ1tuYW1lPVwiZW1haWxcIl0nKS52YWwoKSxcbiAgICAvLyAgICAgICAgICAgICBmaXJzdF9uYW1lOiBmb3JtLmZpbmQoJ1tuYW1lPVwiZmlyc3RfbmFtZVwiXScpLnZhbCgpLFxuICAgIC8vICAgICAgICAgICAgIGxhc3RfbmFtZTogZm9ybS5maW5kKCdbbmFtZT1cImxhc3RfbmFtZVwiXScpLnZhbCgpLFxuICAgIC8vICAgICAgICAgICAgIHJvbGVfaWQ6IHBhcnNlSW50KGZvcm0uZmluZCgnW25hbWU9XCJyb2xlX2lkXCJdJykudmFsKCkpIHx8IDMsXG4gICAgLy8gICAgICAgICAgICAgcGhvbmU6IGZvcm0uZmluZCgnW25hbWU9XCJwaG9uZVwiXScpLnZhbCgpXG4gICAgLy8gICAgICAgICB9O1xuICAgIC8vICAgICB9XG4gICAgLy8gfVxufVxuIiwiLyoqXG4gKiBBZGRfVXNlcl9Nb2RhbCAtIE1vZGFsIGZvciBhZGRpbmcvaW52aXRpbmcgbmV3IHVzZXJzIHRvIHNpdGVcbiAqXG4gKiBEaXNwbGF5cyBmb3JtIHRvIGNvbGxlY3QgdXNlciBpbmZvcm1hdGlvbiBhbmQgY3JlYXRlIHBlbmRpbmcgaW52aXRhdGlvbi5cbiAqIFVzZXMgQWRkX1VzZXJfTW9kYWxfRm9ybSBjb21wb25lbnQgZm9yIFVJIGFuZCB2YWxpZGF0aW9uLlxuICpcbiAqIFJldHVybnMgY3JlYXRlZCB1c2VyIHJlY29yZCBvbiBzdWNjZXNzLCBmYWxzZSBvbiBjYW5jZWwuXG4gKi9cbmNsYXNzIEFkZF9Vc2VyX01vZGFsIGV4dGVuZHMgTW9kYWxfQWJzdHJhY3Qge1xuICAgIC8qKlxuICAgICAqIFNob3cgYWRkIHVzZXIgbW9kYWxcbiAgICAgKlxuICAgICAqIEByZXR1cm5zIHtQcm9taXNlPE9iamVjdHxmYWxzZT59IFVzZXIgcmVjb3JkIG9uIHN1Y2Nlc3MsIGZhbHNlIG9uIGNhbmNlbFxuICAgICAqL1xuICAgIHN0YXRpYyBhc3luYyBzaG93KCkge1xuICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBNb2RhbC5mb3JtKHtcbiAgICAgICAgICAgIHRpdGxlOiAnQWRkIFVzZXInLFxuICAgICAgICAgICAgY29tcG9uZW50OiAnQWRkX1VzZXJfTW9kYWxfRm9ybScsXG4gICAgICAgICAgICBvbl9zdWJtaXQ6IGFzeW5jIChmb3JtKSA9PiB7XG4gICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgdmFsdWVzID0gZm9ybS52YWxzKCk7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IEZyb250ZW5kX1NldHRpbmdzX1VzZXJfTWFuYWdlbWVudF9Db250cm9sbGVyLmFkZF91c2VyKHZhbHVlcyk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQ7IC8vIENsb3NlIG1vZGFsLCByZXR1cm4gdXNlciBkYXRhXG4gICAgICAgICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gUmVuZGVyIGVycm9yIChmb3JtIGhhbmRsZXMgYm90aCB2YWxpZGF0aW9uIGFuZCBnZW5lcmljIGVycm9ycylcbiAgICAgICAgICAgICAgICAgICAgYXdhaXQgZm9ybS5yZW5kZXJfZXJyb3IoZXJyb3IpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7IC8vIEtlZXAgbW9kYWwgb3BlblxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuXG4gICAgICAgIHJldHVybiByZXN1bHQgfHwgZmFsc2U7XG4gICAgfVxufVxuIiwiLyoqXG4gKiBTZW5kX1VzZXJfSW52aXRlX01vZGFsIC0gTW9kYWwgZm9yIHNlbmRpbmcvcmVzZW5kaW5nIHVzZXIgaW52aXRhdGlvbnNcbiAqXG4gKiBIYW5kbGVzIGJvdGggaW5pdGlhbCBpbnZpdGF0aW9uIHNlbmRpbmcgKGFmdGVyIHVzZXIgY3JlYXRpb24pIGFuZCByZXNlbmRpbmdcbiAqIGV4cGlyZWQvcGVuZGluZyBpbnZpdGF0aW9ucy4gQ2FsbHMgYmFja2VuZCBlbmRwb2ludCB0byBnZW5lcmF0ZSBuZXcgaW52aXRlXG4gKiBjb2RlIGFuZCBkaXNwbGF5cyBVUkwgZm9yIHRlc3RpbmcgKHVudGlsIGVtYWlsIHN5c3RlbSBpbXBsZW1lbnRlZCkuXG4gKlxuICogUmV0dXJucyBpbnZpdGUgZGF0YSBvbiBzdWNjZXNzLCBmYWxzZSBvbiBlcnJvci5cbiAqL1xuY2xhc3MgU2VuZF9Vc2VyX0ludml0ZV9Nb2RhbCBleHRlbmRzIE1vZGFsX0Fic3RyYWN0IHtcbiAgICAvKipcbiAgICAgKiBTaG93IHNlbmQgaW52aXRlIG1vZGFsIGFuZCB0cmlnZ2VyIGJhY2tlbmQgaW52aXRlXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gdXNlcl9pZCAtIFVzZXIgSUQgdG8gc2VuZCBpbnZpdGUgdG9cbiAgICAgKiBAcmV0dXJucyB7UHJvbWlzZTxPYmplY3R8ZmFsc2U+fSBJbnZpdGUgZGF0YSBvbiBzdWNjZXNzLCBmYWxzZSBvbiBlcnJvclxuICAgICAqL1xuICAgIHN0YXRpYyBhc3luYyBzaG93KHVzZXJfaWQpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIC8vIENhbGwgYmFja2VuZCB0byBzZW5kL3Jlc2VuZCBpbnZpdGVcbiAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IEZyb250ZW5kX1NldHRpbmdzX1VzZXJfTWFuYWdlbWVudF9Db250cm9sbGVyLnNlbmRfaW52aXRlKHt1c2VyX2lkfSk7XG5cbiAgICAgICAgICAgIC8vIFNob3cgaW52aXRlIFVSTCBmb3IgdGVzdGluZyAodW50aWwgZW1haWwgc3lzdGVtIGltcGxlbWVudGVkKVxuICAgICAgICAgICAgaWYgKHJlc3VsdC5pbnZpdGVfdXJsKSB7XG4gICAgICAgICAgICAgICAgYXdhaXQgTW9kYWwuYWxlcnQoXG4gICAgICAgICAgICAgICAgICAgICdVc2VyIEludml0ZWQgU3VjY2Vzc2Z1bGx5JyxcbiAgICAgICAgICAgICAgICAgICAgYEludml0YXRpb24gc2VudCFcXG5cXG5UZXN0IGludml0YXRpb24gVVJMOlxcbiR7cmVzdWx0Lmludml0ZV91cmx9YFxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICAvLyBTaG93IGVycm9yIHRvIHVzZXJcbiAgICAgICAgICAgIGF3YWl0IE1vZGFsLmVycm9yKGVycm9yLCAnRmFpbGVkIHRvIFNlbmQgSW52aXRhdGlvbicpO1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgfVxufVxuIiwiY2xhc3MgRnJvbnRlbmRfU2V0dGluZ3NfVXNlcl9NYW5hZ2VtZW50IHtcbiAgICBzdGF0aWMgaW5pdCgpIHtcbiAgICAgICAgaWYgKCEkKCcuRnJvbnRlbmRfU2V0dGluZ3NfVXNlcl9NYW5hZ2VtZW50JykuZXhpc3RzKCkpIHJldHVybjtcblxuICAgICAgICAvLyBIYW5kbGUgQWRkIFVzZXIgYnV0dG9uIGNsaWNrXG4gICAgICAgICQoJyNidG5fYWRkX3VzZXInKS5vbignY2xpY2snLCBhc3luYyBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBhd2FpdCBGcm9udGVuZF9TZXR0aW5nc19Vc2VyX01hbmFnZW1lbnQuaGFuZGxlX2FkZF91c2VyKCk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEFkZCB1c2VyIHdvcmtmbG93OiBzaG93IGFkZCBtb2RhbCwgcmVmcmVzaCBncmlkLCBzaG93IGludml0ZSBtb2RhbFxuICAgICAqL1xuICAgIHN0YXRpYyBhc3luYyBoYW5kbGVfYWRkX3VzZXIoKSB7XG4gICAgICAgIC8vIFNob3cgYWRkIHVzZXIgbW9kYWxcbiAgICAgICAgY29uc3QgdXNlciA9IGF3YWl0IEFkZF9Vc2VyX01vZGFsLnNob3coKTtcblxuICAgICAgICBpZiAodXNlcikge1xuICAgICAgICAgICAgLy8gUmVmcmVzaCB0aGUgdXNlciBsaXN0XG4gICAgICAgICAgICAkKCcuVXNlcnNfRGF0YUdyaWQnKS5jb21wb25lbnQoKS5yZWxvYWQoKTtcblxuICAgICAgICAgICAgLy8gU2hvdyBzZW5kIGludml0ZSBtb2RhbFxuICAgICAgICAgICAgYXdhaXQgU2VuZF9Vc2VyX0ludml0ZV9Nb2RhbC5zaG93KHVzZXIuaWQpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgc3RhdGljIG9uX2FwcF9yZWFkeSgpIHtcbiAgICAgICAgRnJvbnRlbmRfU2V0dGluZ3NfVXNlcl9NYW5hZ2VtZW50LmluaXQoKTtcbiAgICB9XG59XG4iLCIvKipcbiAqIEVkaXRfVXNlcl9Nb2RhbCAtIE1vZGFsIGZvciBlZGl0aW5nIGV4aXN0aW5nIHVzZXIgaW5mb3JtYXRpb25cbiAqXG4gKiBEaXNwbGF5cyBmb3JtIHRvIHVwZGF0ZSB1c2VyIHByb2ZpbGUgaW5mb3JtYXRpb24uXG4gKiBVc2VzIEVkaXRfVXNlcl9Nb2RhbF9Gb3JtIGNvbXBvbmVudCBmb3IgVUkgYW5kIHZhbGlkYXRpb24uXG4gKlxuICogUmV0dXJucyB1cGRhdGVkIHVzZXIgcmVjb3JkIG9uIHN1Y2Nlc3MsIGZhbHNlIG9uIGNhbmNlbC5cbiAqL1xuY2xhc3MgRWRpdF9Vc2VyX01vZGFsIGV4dGVuZHMgTW9kYWxfQWJzdHJhY3Qge1xuICAgIC8qKlxuICAgICAqIFNob3cgZWRpdCB1c2VyIG1vZGFsXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gdXNlcl9pZCAtIElEIG9mIHVzZXIgdG8gZWRpdFxuICAgICAqIEByZXR1cm5zIHtQcm9taXNlPE9iamVjdHxmYWxzZT59IFVwZGF0ZWQgdXNlciByZWNvcmQgb24gc3VjY2VzcywgZmFsc2Ugb24gY2FuY2VsXG4gICAgICovXG4gICAgc3RhdGljIGFzeW5jIHNob3codXNlcl9pZCkge1xuICAgICAgICAvLyBMb2FkIHVzZXIgZGF0YSBmb3IgZWRpdGluZ1xuICAgICAgICBsZXQgdXNlcl9kYXRhO1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgdXNlcl9kYXRhID0gYXdhaXQgRnJvbnRlbmRfU2V0dGluZ3NfVXNlcl9NYW5hZ2VtZW50X0NvbnRyb2xsZXIuZ2V0X3VzZXJfZm9yX2VkaXQoe3VzZXJfaWR9KTtcbiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgIGF3YWl0IE1vZGFsLmVycm9yKGVycm9yLCAnRmFpbGVkIHRvIExvYWQgVXNlcicpO1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgTW9kYWwuZm9ybSh7XG4gICAgICAgICAgICB0aXRsZTogJ0VkaXQgVXNlcicsXG4gICAgICAgICAgICBjb21wb25lbnQ6ICdFZGl0X1VzZXJfTW9kYWxfRm9ybScsXG4gICAgICAgICAgICBjb21wb25lbnRfYXJnczoge2RhdGE6IHVzZXJfZGF0YX0sXG4gICAgICAgICAgICBvbl9zdWJtaXQ6IGFzeW5jIChmb3JtKSA9PiB7XG4gICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgdmFsdWVzID0gZm9ybS52YWxzKCk7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IEZyb250ZW5kX1NldHRpbmdzX1VzZXJfTWFuYWdlbWVudF9Db250cm9sbGVyLnNhdmVfdXNlcih2YWx1ZXMpO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0OyAvLyBDbG9zZSBtb2RhbCwgcmV0dXJuIHVzZXIgZGF0YVxuICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIFJlbmRlciBlcnJvciAoZm9ybSBoYW5kbGVzIGJvdGggdmFsaWRhdGlvbiBhbmQgZ2VuZXJpYyBlcnJvcnMpXG4gICAgICAgICAgICAgICAgICAgIGF3YWl0IGZvcm0ucmVuZGVyX2Vycm9yKGVycm9yKTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOyAvLyBLZWVwIG1vZGFsIG9wZW5cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9LFxuICAgICAgICB9KTtcblxuICAgICAgICByZXR1cm4gcmVzdWx0IHx8IGZhbHNlO1xuICAgIH1cbn1cbiIsImNsYXNzIEZyb250ZW5kX1NldHRpbmdzX1VzZXJfTWFuYWdlbWVudF9WaWV3IHtcbiAgICBzdGF0aWMgaW5pdCgpIHtcbiAgICAgICAgaWYgKCEkKCcuRnJvbnRlbmRfU2V0dGluZ3NfVXNlcl9NYW5hZ2VtZW50X1ZpZXcnKS5leGlzdHMoKSkgcmV0dXJuO1xuXG4gICAgICAgIC8vIEhhbmRsZSBFZGl0IFVzZXIgYnV0dG9uIGNsaWNrXG4gICAgICAgICQoJyNidG5fZWRpdF91c2VyJykub24oJ2NsaWNrJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgYXdhaXQgRnJvbnRlbmRfU2V0dGluZ3NfVXNlcl9NYW5hZ2VtZW50X1ZpZXcuaGFuZGxlX2VkaXRfdXNlcigpO1xuICAgICAgICB9KTtcblxuICAgICAgICAvLyBIYW5kbGUgUmVzZW5kIEludml0ZSBidXR0b24gY2xpY2tcbiAgICAgICAgJCgnI2J0bl9yZXNlbmRfaW52aXRlJykub24oJ2NsaWNrJywgYXN5bmMgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgYXdhaXQgRnJvbnRlbmRfU2V0dGluZ3NfVXNlcl9NYW5hZ2VtZW50X1ZpZXcuaGFuZGxlX3Jlc2VuZF9pbnZpdGUoKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRWRpdCB1c2VyIHdvcmtmbG93OiBzaG93IGVkaXQgbW9kYWwsIHJlZnJlc2ggcGFnZSBvbiBzYXZlXG4gICAgICovXG4gICAgc3RhdGljIGFzeW5jIGhhbmRsZV9lZGl0X3VzZXIoKSB7XG4gICAgICAgIC8vIEdldCB1c2VyIElEIGZyb20gcGFnZSBkYXRhXG4gICAgICAgIGNvbnN0IHVzZXJfaWQgPSB3aW5kb3cucnN4YXBwLnBhZ2VfZGF0YT8udXNlcl9pZDtcblxuICAgICAgICBpZiAoIXVzZXJfaWQpIHtcbiAgICAgICAgICAgIGF3YWl0IE1vZGFsLmVycm9yKCdVc2VyIElEIG5vdCBmb3VuZCcpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gU2hvdyBlZGl0IHVzZXIgbW9kYWxcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgRWRpdF9Vc2VyX01vZGFsLnNob3codXNlcl9pZCk7XG5cbiAgICAgICAgaWYgKHJlc3VsdCkge1xuICAgICAgICAgICAgLy8gUmVmcmVzaCBwYWdlIHRvIHNob3cgdXBkYXRlZCB1c2VyIGluZm9ybWF0aW9uXG4gICAgICAgICAgICBsb2NhdGlvbi5yZWxvYWQoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlc2VuZCBpbnZpdGUgd29ya2Zsb3c6IGNhbGwgc2VuZCBpbnZpdGUgbW9kYWxcbiAgICAgKi9cbiAgICBzdGF0aWMgYXN5bmMgaGFuZGxlX3Jlc2VuZF9pbnZpdGUoKSB7XG4gICAgICAgIC8vIEdldCB1c2VyIElEIGZyb20gcGFnZSBkYXRhXG4gICAgICAgIGNvbnN0IHVzZXJfaWQgPSB3aW5kb3cucnN4YXBwLnBhZ2VfZGF0YT8udXNlcl9pZDtcblxuICAgICAgICBpZiAoIXVzZXJfaWQpIHtcbiAgICAgICAgICAgIGF3YWl0IE1vZGFsLmVycm9yKCdVc2VyIElEIG5vdCBmb3VuZCcpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gU2hvdyBzZW5kIGludml0ZSBtb2RhbFxuICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBTZW5kX1VzZXJfSW52aXRlX01vZGFsLnNob3codXNlcl9pZCk7XG5cbiAgICAgICAgaWYgKHJlc3VsdCkge1xuICAgICAgICAgICAgLy8gUmVmcmVzaCBwYWdlIHRvIHNob3cgdXBkYXRlZCBpbnZpdGUgc3RhdHVzXG4gICAgICAgICAgICBsb2NhdGlvbi5yZWxvYWQoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHN0YXRpYyBvbl9hcHBfcmVhZHkoKSB7XG4gICAgICAgIEZyb250ZW5kX1NldHRpbmdzX1VzZXJfTWFuYWdlbWVudF9WaWV3LmluaXQoKTtcbiAgICB9XG59XG4iLCJjbGFzcyBGcm9udGVuZF9TZXR0aW5nc19TaXRlX1NldHRpbmdzIHtcbiAgICBzdGF0aWMgaW5pdCgpIHtcbiAgICAgICAgaWYgKCEkKFwiLkZyb250ZW5kX1NldHRpbmdzX1NpdGVfU2V0dGluZ3NcIikuZXhpc3RzKCkpIHJldHVybjtcblxuICAgICAgICAvLyBJbml0aWFsaXplIHlvdXIgY29tcG9uZW50IGhlcmVcbiAgICAgICAgY29uc29sZS5sb2coJ0Zyb250ZW5kX1NldHRpbmdzX1NpdGVfU2V0dGluZ3MgaW5pdGlhbGl6ZWQnKTtcblxuICAgICAgICAvLyBFeGFtcGxlOiBIYW5kbGUgYnV0dG9uIGNsaWNrc1xuICAgICAgICAkKCcuYnRuLWFjdGlvbicpLm9uKCdjbGljaycsIGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgLy8gSGFuZGxlIGFjdGlvblxuICAgICAgICB9KTtcblxuICAgICAgICAvLyBFeGFtcGxlOiBJbml0aWFsaXplIHRvb2x0aXBzXG4gICAgICAgICQoJ1tkYXRhLWJzLXRvZ2dsZT1cInRvb2x0aXBcIl0nKS50b29sdGlwKCk7XG4gICAgfVxuXG4gICAgc3RhdGljIG9uX2FwcF9yZWFkeSgpIHtcbiAgICAgICAgRnJvbnRlbmRfU2V0dGluZ3NfU2l0ZV9TZXR0aW5ncy5pbml0KCk7XG4gICAgfVxuXG4gICAgLy8gc3RhdGljIG9uX2pxaHRtbF9yZWFkeSgpIHtcbiAgICAvLyAgICAgLy8gQ2FsbGVkIGFmdGVyIGFsbCBKUUhUTUwgY29tcG9uZW50cyBoYXZlIGxvYWRlZCBhbmQgcmVuZGVyZWRcbiAgICAvLyAgICAgLy8gVXNlIHRoaXMgaWYgeW91IG5lZWQgdG8gaW50ZXJhY3Qgd2l0aCBKUUhUTUwgY29tcG9uZW50c1xuICAgIC8vICAgICAvLyBPdGhlcndpc2UsIHVzZSBvbl9hcHBfcmVhZHkoKSBmb3IgbW9zdCBpbml0aWFsaXphdGlvblxuICAgIC8vIH1cbn0iLCIvKipcbiAqIFNldHRpbmdzIFBhZ2UgSmF2YVNjcmlwdFxuICovXG5jbGFzcyBGcm9udGVuZF9TZXR0aW5ncyB7XG4gICAgLyoqXG4gICAgICogSW5pdGlhbGl6ZSB0aGUgc2V0dGluZ3MgcGFnZVxuICAgICAqL1xuICAgIHN0YXRpYyBvbl9hcHBfcmVhZHkoKSB7XG4gICAgICAgIC8vIE9ubHkgaW5pdGlhbGl6ZSBpZiB3ZSdyZSBvbiB0aGUgc2V0dGluZ3MgcGFnZVxuICAgICAgICBpZiAoISQoXCIuRnJvbnRlbmRfU2V0dGluZ3NcIikuZXhpc3RzKCkpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIERlYnVnZ2VyLmNvbnNvbGVfZGVidWcoXCJKU19JTklUXCIsIFwiU2V0dGluZ3MgcGFnZSBpbml0aWFsaXplZFwiKTtcblxuICAgICAgICAvLyBIYW5kbGUgc2lkZWJhciBuYXZpZ2F0aW9uXG4gICAgICAgICQoJy5zaWRlYmFyIC5uYXYtbGluaycpLm9uKCdjbGljaycsIGZ1bmN0aW9uKGUpIHtcbiAgICAgICAgICAgIGNvbnN0ICRsaW5rID0gJCh0aGlzKTtcbiAgICAgICAgICAgIGlmICgkbGluay5hdHRyKCdocmVmJykgPT09ICcjJykge1xuICAgICAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICAgICAgICAvLyBSZW1vdmUgYWN0aXZlIGZyb20gYWxsIGxpbmtzXG4gICAgICAgICAgICAgICAgJCgnLnNpZGViYXIgLm5hdi1saW5rJykucmVtb3ZlQ2xhc3MoJ2FjdGl2ZScpO1xuICAgICAgICAgICAgICAgIC8vIEFkZCBhY3RpdmUgdG8gY2xpY2tlZFxuICAgICAgICAgICAgICAgICRsaW5rLmFkZENsYXNzKCdhY3RpdmUnKTtcblxuICAgICAgICAgICAgICAgIGNvbnN0IHNlY3Rpb24gPSAkbGluay50ZXh0KCkudHJpbSgpO1xuICAgICAgICAgICAgICAgIERlYnVnZ2VyLmNvbnNvbGVfZGVidWcoXCJVSVwiLCBcIlNldHRpbmdzIHNlY3Rpb24gY2xpY2tlZDpcIiwgc2VjdGlvbik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIEhhbmRsZSBmb3JtIHN1Ym1pc3Npb25zXG4gICAgICAgICQoJ2Zvcm0nKS5vbignc3VibWl0JywgZnVuY3Rpb24oZSkge1xuICAgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgICAgY29uc3QgJGZvcm0gPSAkKHRoaXMpO1xuICAgICAgICAgICAgY29uc3QgZm9ybURhdGEgPSAkZm9ybS5zZXJpYWxpemUoKTtcbiAgICAgICAgICAgIERlYnVnZ2VyLmNvbnNvbGVfZGVidWcoXCJGT1JNXCIsIFwiU2V0dGluZ3MgZm9ybSBzdWJtaXR0ZWRcIiwgZm9ybURhdGEpO1xuXG4gICAgICAgICAgICAvLyBTaG93IHN1Y2Nlc3MgbWVzc2FnZSAobW9jaylcbiAgICAgICAgICAgIGNvbnN0ICRhbGVydCA9ICQoJzxkaXYgY2xhc3M9XCJhbGVydCBhbGVydC1zdWNjZXNzIGFsZXJ0LWRpc21pc3NpYmxlIGZhZGUgc2hvd1wiIHJvbGU9XCJhbGVydFwiPicpXG4gICAgICAgICAgICAgICAgLmh0bWwoJ1NldHRpbmdzIHNhdmVkIHN1Y2Nlc3NmdWxseSEgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJidG4tY2xvc2VcIiBkYXRhLWJzLWRpc21pc3M9XCJhbGVydFwiPjwvYnV0dG9uPicpO1xuXG4gICAgICAgICAgICAkZm9ybS5jbG9zZXN0KCcuY2FyZC1ib2R5JykucHJlcGVuZCgkYWxlcnQpO1xuXG4gICAgICAgICAgICAvLyBBdXRvLWRpc21pc3MgYWZ0ZXIgMyBzZWNvbmRzXG4gICAgICAgICAgICAvLyBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgIC8vICAgICAkYWxlcnQuZmFkZU91dCgoKSA9PiAkYWxlcnQucmVtb3ZlKCkpO1xuICAgICAgICAgICAgLy8gfSwgMzAwMCk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIFF1aWNrIGFjdGlvbiBidXR0b25zXG4gICAgICAgICQoJy5jYXJkLWJvZHkgLmJ0bi1wcmltYXJ5Jykub24oJ2NsaWNrJywgZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICBjb25zdCAkYnV0dG9uID0gJCh0aGlzKTtcbiAgICAgICAgICAgIGNvbnN0IGFjdGlvbiA9ICRidXR0b24udGV4dCgpLnRyaW0oKTtcbiAgICAgICAgICAgIERlYnVnZ2VyLmNvbnNvbGVfZGVidWcoXCJVSVwiLCBcIlF1aWNrIGFjdGlvbjpcIiwgYWN0aW9uKTtcblxuICAgICAgICAgICAgLy8gU2ltdWxhdGUgYWN0aW9uXG4gICAgICAgICAgICBjb25zdCBvcmlnaW5hbFRleHQgPSAkYnV0dG9uLmh0bWwoKTtcbiAgICAgICAgICAgICRidXR0b24uaHRtbCgnPHNwYW4gY2xhc3M9XCJzcGlubmVyLWJvcmRlciBzcGlubmVyLWJvcmRlci1zbSBtZS0xXCI+PC9zcGFuPiBQcm9jZXNzaW5nLi4uJyk7XG4gICAgICAgICAgICAkYnV0dG9uLnByb3AoJ2Rpc2FibGVkJywgdHJ1ZSk7XG5cbiAgICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgICAgICRidXR0b24uaHRtbChvcmlnaW5hbFRleHQpO1xuICAgICAgICAgICAgICAgICRidXR0b24ucHJvcCgnZGlzYWJsZWQnLCBmYWxzZSk7XG4gICAgICAgICAgICB9LCAxNTAwKTtcbiAgICAgICAgfSk7XG4gICAgfVxufSIsIi8qKlxuICogQ29udGFjdHNfRGF0YUdyaWQgQ29tcG9uZW50XG4gKlxuICogQ29uY3JldGUgaW1wbGVtZW50YXRpb24gZm9yIGNvbnRhY3RzIGRhdGFncmlkLlxuICogQWxsIGZ1bmN0aW9uYWxpdHkgaXMgaW4gRGF0YUdyaWRfQWJzdHJhY3QuXG4gKi9cbmNsYXNzIENvbnRhY3RzX0RhdGFHcmlkIGV4dGVuZHMgRGF0YUdyaWRfQWJzdHJhY3Qge1xuICAgIC8vIEFsbCBiZWhhdmlvciBpbmhlcml0ZWQgZnJvbSBEYXRhR3JpZF9BYnN0cmFjdFxufVxuIiwiY2xhc3MgRGF0YV9UYWJsZSBleHRlbmRzIEpxaHRtbF9Db21wb25lbnQge1xuICAgIG9uX3JlbmRlcigpIHtcbiAgICAgICAgLy8gSGlkZSB1bnRpbCBkYXRhIGxvYWRzIHRvIHByZXZlbnQgdmlzdWFsIGdsaXRjaGVzXG4gICAgICAgIGlmIChPYmplY3Qua2V5cyh0aGlzLmRhdGEpLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgdGhpcy4kaWQoJ2Zvb3RlcicpLmNzcygnb3BhY2l0eScsICcwJyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBhc3luYyBvbl9sb2FkKCkge1xuICAgICAgICAvLyBJZiBkYXRhX3NvdXJjZSBwcm92aWRlZCwgZmV0Y2ggZGF0YVxuICAgICAgICBpZiAodGhpcy5hcmdzLmRhdGFfc291cmNlKSB7XG4gICAgICAgICAgICB0aGlzLmRhdGEgPSBhd2FpdCB0aGlzLmZldGNoX2RhdGEoKTtcbiAgICAgICAgfSBlbHNlIGlmICh0aGlzLmFyZ3MuY29sdW1ucyAmJiB0aGlzLmFyZ3Mucm93cykge1xuICAgICAgICAgICAgLy8gVXNlIHByb3ZpZGVkIHN0YXRpYyBkYXRhXG4gICAgICAgICAgICB0aGlzLmRhdGEgPSB7XG4gICAgICAgICAgICAgICAgY29sdW1uczogdGhpcy5hcmdzLmNvbHVtbnMsXG4gICAgICAgICAgICAgICAgcm93czogdGhpcy5hcmdzLnJvd3MsXG4gICAgICAgICAgICAgICAgdG90YWw6IHRoaXMuYXJncy5yb3dzLmxlbmd0aCxcbiAgICAgICAgICAgICAgICBzdGFydDogMSxcbiAgICAgICAgICAgICAgICBlbmQ6IHRoaXMuYXJncy5yb3dzLmxlbmd0aCxcbiAgICAgICAgICAgICAgICBjdXJyZW50X3BhZ2U6IDEsXG4gICAgICAgICAgICAgICAgdG90YWxfcGFnZXM6IDEsXG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgb25fcmVhZHkoKSB7XG4gICAgICAgIC8vIFNob3cgZm9vdGVyIGFmdGVyIHJlbmRlclxuICAgICAgICB0aGlzLiRpZCgnZm9vdGVyJykuY3NzKCdvcGFjaXR5JywgJzEnKTtcblxuICAgICAgICAvLyBCdWlsZCBjb2x1bW4gaGVhZGVycyB3aXRoIHNvcnRpbmdcbiAgICAgICAgaWYgKHRoaXMuZGF0YS5jb2x1bW5zKSB7XG4gICAgICAgICAgICB0aGlzLmJ1aWxkX2hlYWRlcnModGhpcy5kYXRhLmNvbHVtbnMpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gU2V0dXAgc2VhcmNoIGlmIGVuYWJsZWRcbiAgICAgICAgaWYgKHRoaXMuYXJncy5zZWFyY2hhYmxlKSB7XG4gICAgICAgICAgICB0aGlzLnNldHVwX3NlYXJjaCgpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gU2V0dXAgY29sdW1uIHZpc2liaWxpdHkgdG9nZ2xlIGlmIGVuYWJsZWRcbiAgICAgICAgaWYgKHRoaXMuYXJncy5jb2x1bW5fdG9nZ2xlKSB7XG4gICAgICAgICAgICB0aGlzLnNldHVwX2NvbHVtbl90b2dnbGUoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFNldHVwIGJ1bGsgYWN0aW9uc1xuICAgICAgICBpZiAodGhpcy5hcmdzLmJ1bGtfYWN0aW9ucykge1xuICAgICAgICAgICAgdGhpcy5zZXR1cF9idWxrX2FjdGlvbnMoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIEF0dGFjaCByb3cgY2hlY2tib3ggbGlzdGVuZXJzXG4gICAgICAgIHRoaXMuJC5maW5kKCcucm93LWNoZWNrYm94Jykub24oJ2NoYW5nZScsICgpID0+IHtcbiAgICAgICAgICAgIHRoaXMudXBkYXRlX2J1bGtfc2VsZWN0aW9uKCk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIFNldHVwIHBhZ2luYXRpb24gY2xpY2sgaGFuZGxlcnNcbiAgICAgICAgY29uc3QgJHBhZ2luYXRpb24gPSB0aGlzLiRpZCgncGFnaW5hdGlvbicpO1xuICAgICAgICAkcGFnaW5hdGlvbi4kLmZpbmQoJy5wYWdlLWxpbmsnKS5vbignY2xpY2snLCAoZSkgPT4ge1xuICAgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgICAgY29uc3QgcGFnZV90ZXh0ID0gJChlLnRhcmdldCkudGV4dCgpO1xuICAgICAgICAgICAgaWYgKHBhZ2VfdGV4dCA9PT0gJ1ByZXZpb3VzJykge1xuICAgICAgICAgICAgICAgIHRoaXMubG9hZF9wYWdlKHRoaXMuZGF0YS5jdXJyZW50X3BhZ2UgLSAxKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAocGFnZV90ZXh0ID09PSAnTmV4dCcpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmxvYWRfcGFnZSh0aGlzLmRhdGEuY3VycmVudF9wYWdlICsgMSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvbnN0IHBhZ2UgPSBpbnQocGFnZV90ZXh0KTtcbiAgICAgICAgICAgICAgICBpZiAoIWlzTmFOKHBhZ2UpKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMubG9hZF9wYWdlKHBhZ2UpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgYnVpbGRfaGVhZGVycyhjb2x1bW5zKSB7XG4gICAgICAgIGNvbnN0ICRoZWFkZXJfcm93ID0gdGhpcy4kaWQoJ2hlYWRlcl9yb3cnKTtcblxuICAgICAgICAvLyBTa2lwIGZpcnN0IGNlbGwgaWYgYnVsayBhY3Rpb25zIChhbHJlYWR5IGhhcyBCdWxrX1NlbGVjdGlvbilcbiAgICAgICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5hcmdzLmJ1bGtfYWN0aW9ucyA/IDEgOiAwO1xuXG4gICAgICAgIGNvbHVtbnMuZm9yRWFjaCgoY29sLCBpbmRleCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgJHRoID0gJCgnPHRoPicpO1xuXG4gICAgICAgICAgICBpZiAoY29sLnNvcnRhYmxlICE9PSBmYWxzZSkge1xuICAgICAgICAgICAgICAgIC8vIENyZWF0ZSBzb3J0YWJsZSBjb2x1bW4gaGVhZGVyXG4gICAgICAgICAgICAgICAgY29uc3QgJHNvcnRhYmxlID0gJCgnPGRpdj4nKS5hZGRDbGFzcygnU29ydGFibGVfQ29sdW1uX0hlYWRlcicpLmF0dHIoe1xuICAgICAgICAgICAgICAgICAgICAnZGF0YS1jb2x1bW4nOiBjb2wuZmllbGQsXG4gICAgICAgICAgICAgICAgICAgICdkYXRhLXNvcnQnOiAnbm9uZScsXG4gICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgICBjb25zdCAkdGV4dCA9ICQoJzxzcGFuPicpLnRleHQoY29sLmxhYmVsIHx8IGNvbC5maWVsZCk7XG4gICAgICAgICAgICAgICAgY29uc3QgJGljb24gPSAkKCc8c3Bhbj4nKS5hdHRyKCdkYXRhLWlkJywgJ3NvcnRfaWNvbicpLmh0bWwoJzxpIGNsYXNzPVwidGV4dC1tdXRlZFwiPuKHhTwvaT4nKTtcblxuICAgICAgICAgICAgICAgICRzb3J0YWJsZS5hcHBlbmQoJHRleHQpLmFwcGVuZCgnICcpLmFwcGVuZCgkaWNvbik7XG4gICAgICAgICAgICAgICAgJHNvcnRhYmxlLmNzcygnY3Vyc29yJywgJ3BvaW50ZXInKTtcblxuICAgICAgICAgICAgICAgICRzb3J0YWJsZS5vbignY2xpY2snLCAoKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuaGFuZGxlX3NvcnQoY29sLmZpZWxkKTtcbiAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICAgICR0aC5hcHBlbmQoJHNvcnRhYmxlKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgJHRoLnRleHQoY29sLmxhYmVsIHx8IGNvbC5maWVsZCk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChjb2wud2lkdGgpIHtcbiAgICAgICAgICAgICAgICAkdGguY3NzKCd3aWR0aCcsIGNvbC53aWR0aCk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICRoZWFkZXJfcm93LmFwcGVuZCgkdGgpO1xuICAgICAgICB9KTtcblxuICAgICAgICAvLyBBZGQgYWN0aW9ucyBjb2x1bW4gaGVhZGVyIGlmIHJvd19hY3Rpb25zIGVuYWJsZWRcbiAgICAgICAgaWYgKHRoaXMuYXJncy5yb3dfYWN0aW9ucykge1xuICAgICAgICAgICAgY29uc3QgJHRoID0gJCgnPHRoPicpLnRleHQoJ0FjdGlvbnMnKS5jc3MoJ3dpZHRoJywgJzEwMHB4Jyk7XG4gICAgICAgICAgICAkaGVhZGVyX3Jvdy5hcHBlbmQoJHRoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHNldHVwX3NlYXJjaCgpIHtcbiAgICAgICAgY29uc3QgJGNvbnRhaW5lciA9IHRoaXMuJGlkKCdzZWFyY2hfY29udGFpbmVyJyk7XG4gICAgICAgIGNvbnN0ICRzZWFyY2ggPSAkKCc8aW5wdXQ+JylcbiAgICAgICAgICAgIC5hdHRyKHtcbiAgICAgICAgICAgICAgICB0eXBlOiAnc2VhcmNoJyxcbiAgICAgICAgICAgICAgICBwbGFjZWhvbGRlcjogJ1NlYXJjaC4uLicsXG4gICAgICAgICAgICAgICAgY2xhc3M6ICdmb3JtLWNvbnRyb2wgZm9ybS1jb250cm9sLXNtJyxcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAuY3NzKCd3aWR0aCcsICcyMDBweCcpO1xuXG4gICAgICAgICRjb250YWluZXIuYXBwZW5kKCRzZWFyY2gpO1xuXG4gICAgICAgIGxldCB0aW1lb3V0O1xuICAgICAgICAkc2VhcmNoLm9uKCdpbnB1dCcsIChlKSA9PiB7XG4gICAgICAgICAgICBjbGVhclRpbWVvdXQodGltZW91dCk7XG4gICAgICAgICAgICB0aW1lb3V0ID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5zZWFyY2hfcXVlcnkgPSBlLnRhcmdldC52YWx1ZTtcbiAgICAgICAgICAgICAgICB0aGlzLnJlbG9hZF9kYXRhKCk7XG4gICAgICAgICAgICB9LCAzMDApO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBzZXR1cF9jb2x1bW5fdG9nZ2xlKCkge1xuICAgICAgICBjb25zdCAkY29udGFpbmVyID0gdGhpcy4kaWQoJ2NvbHVtbl90b2dnbGVfY29udGFpbmVyJyk7XG4gICAgICAgIGNvbnN0ICR0b2dnbGUgPSAkKCc8ZGl2PicpLmFkZENsYXNzKCdDb2x1bW5fVmlzaWJpbGl0eV9Ub2dnbGUnKTtcbiAgICAgICAgJGNvbnRhaW5lci5hcHBlbmQoJHRvZ2dsZSk7XG5cbiAgICAgICAgLy8gSW5pdGlhbGl6ZSBjb21wb25lbnQgbWFudWFsbHlcbiAgICAgICAgY29uc3QgdG9nZ2xlX2NvbXBvbmVudCA9ICR0b2dnbGUuY29tcG9uZW50KCk7XG4gICAgICAgIGlmICh0b2dnbGVfY29tcG9uZW50KSB7XG4gICAgICAgICAgICB0b2dnbGVfY29tcG9uZW50LmFyZ3MuY29sdW1ucyA9IHRoaXMuZGF0YS5jb2x1bW5zO1xuICAgICAgICAgICAgdG9nZ2xlX2NvbXBvbmVudC5hcmdzLnRhYmxlID0gdGhpcy4kaWQoJ3RhYmxlJykuJDtcbiAgICAgICAgICAgIHRvZ2dsZV9jb21wb25lbnQuYnVpbGRfbWVudSh0aGlzLmRhdGEuY29sdW1ucyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBzZXR1cF9idWxrX2FjdGlvbnMoKSB7XG4gICAgICAgIGNvbnN0ICRidWxrX3NlbGVjdGlvbiA9IHRoaXMuJGlkKCdidWxrX3NlbGVjdGlvbicpO1xuICAgICAgICAkYnVsa19zZWxlY3Rpb24uJC5maW5kKCdpbnB1dFt0eXBlPVwiY2hlY2tib3hcIl0nKS5vbignY2hhbmdlJywgKGUpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGNoZWNrZWQgPSBlLnRhcmdldC5jaGVja2VkO1xuICAgICAgICAgICAgdGhpcy4kLmZpbmQoJy5yb3ctY2hlY2tib3gnKS5wcm9wKCdjaGVja2VkJywgY2hlY2tlZCk7XG4gICAgICAgICAgICB0aGlzLnVwZGF0ZV9idWxrX3NlbGVjdGlvbigpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICB1cGRhdGVfYnVsa19zZWxlY3Rpb24oKSB7XG4gICAgICAgIGNvbnN0IGNoZWNrZWQgPSB0aGlzLiQuZmluZCgnLnJvdy1jaGVja2JveDpjaGVja2VkJykubGVuZ3RoO1xuICAgICAgICBjb25zdCAkYnVsa19iYXIgPSB0aGlzLiRpZCgnYnVsa19iYXInKTtcblxuICAgICAgICBpZiAoY2hlY2tlZCA+IDApIHtcbiAgICAgICAgICAgICRidWxrX2Jhci4kLnNob3coKTtcbiAgICAgICAgICAgICRidWxrX2Jhci5zZXRfY291bnQoY2hlY2tlZCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAkYnVsa19iYXIuJC5oaWRlKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBhc3luYyBoYW5kbGVfc29ydChmaWVsZCkge1xuICAgICAgICAvLyBUb2dnbGUgc29ydCBkaXJlY3Rpb25cbiAgICAgICAgY29uc3QgY3VycmVudCA9IHRoaXMuc29ydF9maWVsZCA9PT0gZmllbGQgPyB0aGlzLnNvcnRfZGlyZWN0aW9uIDogJ25vbmUnO1xuICAgICAgICB0aGlzLnNvcnRfZGlyZWN0aW9uID0gY3VycmVudCA9PT0gJ25vbmUnID8gJ2FzYycgOiBjdXJyZW50ID09PSAnYXNjJyA/ICdkZXNjJyA6ICdhc2MnO1xuICAgICAgICB0aGlzLnNvcnRfZmllbGQgPSBmaWVsZDtcblxuICAgICAgICAvLyBVcGRhdGUgc29ydCBpY29uXG4gICAgICAgIHRoaXMuJGlkKCdoZWFkZXJfcm93JylcbiAgICAgICAgICAgIC5maW5kKCdbZGF0YS1jb2x1bW5dJylcbiAgICAgICAgICAgIC5lYWNoKFxuICAgICAgICAgICAgICAgIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgJHNvcnRhYmxlID0gJCh0aGlzKTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgY29sID0gJHNvcnRhYmxlLmF0dHIoJ2RhdGEtY29sdW1uJyk7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0ICRpY29uID0gJHNvcnRhYmxlLmZpbmQoJ1tkYXRhLWlkPVwic29ydF9pY29uXCJdJyk7XG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKGNvbCA9PT0gZmllbGQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICRzb3J0YWJsZS5hdHRyKCdkYXRhLXNvcnQnLCB0aGlzLnNvcnRfZGlyZWN0aW9uKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLnNvcnRfZGlyZWN0aW9uID09PSAnYXNjJykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICRpY29uLmh0bWwoJzxpIGNsYXNzPVwidGV4dC1wcmltYXJ5XCI+4oaRPC9pPicpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmICh0aGlzLnNvcnRfZGlyZWN0aW9uID09PSAnZGVzYycpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkaWNvbi5odG1sKCc8aSBjbGFzcz1cInRleHQtcHJpbWFyeVwiPuKGkzwvaT4nKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgJGljb24uaHRtbCgnPGkgY2xhc3M9XCJ0ZXh0LW11dGVkXCI+4oeFPC9pPicpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgJHNvcnRhYmxlLmF0dHIoJ2RhdGEtc29ydCcsICdub25lJyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAkaWNvbi5odG1sKCc8aSBjbGFzcz1cInRleHQtbXV0ZWRcIj7ih4U8L2k+Jyk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9LmJpbmQodGhpcylcbiAgICAgICAgICAgICk7XG5cbiAgICAgICAgYXdhaXQgdGhpcy5yZWxvYWRfZGF0YSgpO1xuICAgIH1cblxuICAgIGFzeW5jIGxvYWRfcGFnZShwYWdlKSB7XG4gICAgICAgIGlmIChwYWdlIDwgMSB8fCBwYWdlID4gdGhpcy5kYXRhLnRvdGFsX3BhZ2VzKSByZXR1cm47XG4gICAgICAgIHRoaXMuY3VycmVudF9wYWdlID0gcGFnZTtcbiAgICAgICAgYXdhaXQgdGhpcy5yZWxvYWRfZGF0YSgpO1xuICAgIH1cblxuICAgIGFzeW5jIGZldGNoX2RhdGEoKSB7XG4gICAgICAgIGNvbnN0IHBhcmFtcyA9IHtcbiAgICAgICAgICAgIHBhZ2U6IHRoaXMuY3VycmVudF9wYWdlIHx8IDEsXG4gICAgICAgICAgICBwZXJfcGFnZTogdGhpcy5hcmdzLnBlcl9wYWdlIHx8IDIwLFxuICAgICAgICAgICAgc29ydF9maWVsZDogdGhpcy5zb3J0X2ZpZWxkLFxuICAgICAgICAgICAgc29ydF9kaXJlY3Rpb246IHRoaXMuc29ydF9kaXJlY3Rpb24sXG4gICAgICAgICAgICBzZWFyY2g6IHRoaXMuc2VhcmNoX3F1ZXJ5LFxuICAgICAgICB9O1xuXG4gICAgICAgIC8vIENhbGwgZGF0YSBzb3VyY2UgKGNhbiBiZSBVUkwgb3IgZnVuY3Rpb24pXG4gICAgICAgIGlmICh0eXBlb2YgdGhpcy5hcmdzLmRhdGFfc291cmNlID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICByZXR1cm4gYXdhaXQgdGhpcy5hcmdzLmRhdGFfc291cmNlKHBhcmFtcyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zdCB1cmwgPSBuZXcgVVJMKHRoaXMuYXJncy5kYXRhX3NvdXJjZSwgd2luZG93LmxvY2F0aW9uLm9yaWdpbik7XG4gICAgICAgICAgICBPYmplY3Qua2V5cyhwYXJhbXMpLmZvckVhY2goKGtleSkgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChwYXJhbXNba2V5XSkgdXJsLnNlYXJjaFBhcmFtcy5hcHBlbmQoa2V5LCBwYXJhbXNba2V5XSk7XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBmZXRjaCh1cmwpO1xuICAgICAgICAgICAgcmV0dXJuIGF3YWl0IHJlc3BvbnNlLmpzb24oKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGdldF9zZWxlY3RlZF9pZHMoKSB7XG4gICAgICAgIGNvbnN0IGlkcyA9IFtdO1xuICAgICAgICB0aGlzLiQuZmluZCgnLnJvdy1jaGVja2JveDpjaGVja2VkJykuZWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBpZHMucHVzaCgkKHRoaXMpLnZhbCgpKTtcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiBpZHM7XG4gICAgfVxuXG4gICAgYXN5bmMgcmVsb2FkX2RhdGEoKSB7XG4gICAgICAgIC8vIFNob3cgbG9hZGluZyBzdGF0ZVxuICAgICAgICBjb25zdCAkdGJvZHkgPSB0aGlzLiRpZCgndGJvZHknKTtcbiAgICAgICAgJHRib2R5Lmh0bWwoYFxuICAgICAgICAgICAgPHRyPlxuICAgICAgICAgICAgICAgIDx0ZCBjb2xzcGFuPVwiMTAwXCIgY2xhc3M9XCJ0ZXh0LWNlbnRlciBweS01XCI+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzcGlubmVyLWJvcmRlciBzcGlubmVyLWJvcmRlci1zbVwiIHJvbGU9XCJzdGF0dXNcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwidmlzdWFsbHktaGlkZGVuXCI+TG9hZGluZy4uLjwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtdC0yIHRleHQtbXV0ZWRcIj5Mb2FkaW5nIGRhdGEuLi48L2Rpdj5cbiAgICAgICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgPC90cj5cbiAgICAgICAgYCk7XG5cbiAgICAgICAgLy8gRmV0Y2ggbmV3IGRhdGFcbiAgICAgICAgdGhpcy5kYXRhID0gYXdhaXQgdGhpcy5mZXRjaF9kYXRhKCk7XG5cbiAgICAgICAgLy8gUmUtcmVuZGVyIGVudGlyZSBjb21wb25lbnRcbiAgICAgICAgdGhpcy5yZW5kZXIoKTtcbiAgICB9XG59XG4iLCJjbGFzcyBDbGllbnRfU2VsZWN0b3JfSW5wdXQgZXh0ZW5kcyBBamF4X1NlbGVjdF9JbnB1dCB7XG4gICAgYXN5bmMgb25fbG9hZCgpIHtcbiAgICAgICAgLy8gTG9hZCBjbGllbnRzIHZpYSBBamF4IGVuZHBvaW50IGlmIGRhdGEgbm90IHByb3ZpZGVkXG4gICAgICAgIGlmICghdGhpcy5hcmdzLmRhdGEpIHtcbiAgICAgICAgICAgIHRoaXMuZGF0YS5zZWxlY3RfdmFsdWVzID0gYXdhaXQgRnJvbnRlbmRfQ29udGFjdHNfQ29udHJvbGxlci5nZXRfY2xpZW50cygpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gVXNlIHBhcmVudCBvbl9sb2FkIGZvciBjdXN0b20gZGF0YSBlbmRwb2ludHNcbiAgICAgICAgICAgIGF3YWl0IHN1cGVyLm9uX2xvYWQoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIG9uX2NyZWF0ZSgpIHtcbiAgICAgICAgLy8gU2V0IGRlZmF1bHQgcGxhY2Vob2xkZXIgaWYgbm90IHByb3ZpZGVkXG4gICAgICAgIGlmICghdGhpcy5hcmdzLnBsYWNlaG9sZGVyKSB7XG4gICAgICAgICAgICB0aGlzLmFyZ3MucGxhY2Vob2xkZXIgPSAnU2VsZWN0IENsaWVudC4uLic7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBDYWxsIHBhcmVudCB0byBpbml0aWFsaXplIEFqYXhfU2VsZWN0X0lucHV0XG4gICAgICAgIHN1cGVyLm9uX2NyZWF0ZSgpO1xuICAgIH1cblxuICAgIG9uX3JlYWR5KCkge1xuICAgICAgICAvLyBDYWxsIHBhcmVudCB0byBpbml0aWFsaXplIFRvbSBTZWxlY3RcbiAgICAgICAgc3VwZXIub25fcmVhZHkoKTtcbiAgICB9XG59XG4iLCJjbGFzcyBGcm9udGVuZF9Db250YWN0c19FZGl0IHtcbiAgICBzdGF0aWMgaW5pdCgpIHtcbiAgICAgICAgLy8gTm8gaW5pdGlhbGl6YXRpb24gbmVlZGVkIC0gc3VibWl0IGJ1dHRvbiBhdXRvbWF0aWNhbGx5IHdpcmVkIGJ5IFJzeF9Gb3JtXG4gICAgfVxuXG4gICAgc3RhdGljIG9uX2FwcF9yZWFkeSgpIHtcbiAgICAgICAgRnJvbnRlbmRfQ29udGFjdHNfRWRpdC5pbml0KCk7XG4gICAgfVxufVxuIiwiY2xhc3MgRnJvbnRlbmRfQ29udGFjdHNfVmlldyB7XG4gICAgc3RhdGljIGluaXQoKSB7XG4gICAgICAgIGlmICghJCgnLkZyb250ZW5kX0NvbnRhY3RzX1ZpZXcnKS5leGlzdHMoKSkgcmV0dXJuO1xuXG4gICAgICAgIC8vIEluaXRpYWxpemUgeW91ciBjb21wb25lbnQgaGVyZVxuICAgICAgICBjb25zb2xlLmxvZygnRnJvbnRlbmRfQ29udGFjdHNfVmlldyBpbml0aWFsaXplZCcpO1xuXG4gICAgICAgIC8vIEV4YW1wbGU6IEhhbmRsZSBidXR0b24gY2xpY2tzXG4gICAgICAgICQoJy5idG4tYWN0aW9uJykub24oJ2NsaWNrJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgLy8gSGFuZGxlIGFjdGlvblxuICAgICAgICB9KTtcblxuICAgICAgICAvLyBFeGFtcGxlOiBJbml0aWFsaXplIHRvb2x0aXBzXG4gICAgICAgICQoJ1tkYXRhLWJzLXRvZ2dsZT1cInRvb2x0aXBcIl0nKS50b29sdGlwKCk7XG4gICAgfVxuXG4gICAgc3RhdGljIG9uX2FwcF9yZWFkeSgpIHtcbiAgICAgICAgRnJvbnRlbmRfQ29udGFjdHNfVmlldy5pbml0KCk7XG4gICAgfVxuXG4gICAgLy8gc3RhdGljIG9uX2pxaHRtbF9yZWFkeSgpIHtcbiAgICAvLyAgICAgLy8gQ2FsbGVkIGFmdGVyIGFsbCBKUUhUTUwgY29tcG9uZW50cyBoYXZlIGxvYWRlZCBhbmQgcmVuZGVyZWRcbiAgICAvLyAgICAgLy8gVXNlIHRoaXMgaWYgeW91IG5lZWQgdG8gaW50ZXJhY3Qgd2l0aCBKUUhUTUwgY29tcG9uZW50c1xuICAgIC8vICAgICAvLyBPdGhlcndpc2UsIHVzZSBvbl9hcHBfcmVhZHkoKSBmb3IgbW9zdCBpbml0aWFsaXphdGlvblxuICAgIC8vIH1cbn1cbiIsImNsYXNzIEZyb250ZW5kX0NvbnRhY3RzIHtcbiAgICBzdGF0aWMgaW5pdCgpIHtcbiAgICAgICAgaWYgKCEkKCcuRnJvbnRlbmRfQ29udGFjdHMnKS5leGlzdHMoKSkgcmV0dXJuO1xuXG4gICAgICAgIC8vIEluaXRpYWxpemUgeW91ciBjb21wb25lbnQgaGVyZVxuICAgICAgICBjb25zb2xlLmxvZygnRnJvbnRlbmRfQ29udGFjdHMgaW5pdGlhbGl6ZWQnKTtcblxuICAgICAgICAvLyAvLyBFeGFtcGxlOiBIYW5kbGUgYnV0dG9uIGNsaWNrc1xuICAgICAgICAvLyAkKCcuYnRuLWFjdGlvbicpLm9uKCdjbGljaycsIGZ1bmN0aW9uKCkge1xuICAgICAgICAvLyAgICAgLy8gSGFuZGxlIGFjdGlvblxuICAgICAgICAvLyB9KTtcblxuICAgICAgICAvLyAvLyBFeGFtcGxlOiBJbml0aWFsaXplIHRvb2x0aXBzXG4gICAgICAgIC8vICQoJ1tkYXRhLWJzLXRvZ2dsZT1cInRvb2x0aXBcIl0nKS50b29sdGlwKCk7XG4gICAgfVxuXG4gICAgc3RhdGljIG9uX2FwcF9yZWFkeSgpIHtcbiAgICAgICAgRnJvbnRlbmRfQ29udGFjdHMuaW5pdCgpO1xuICAgIH1cblxuICAgIC8vIHN0YXRpYyBvbl9qcWh0bWxfcmVhZHkoKSB7XG4gICAgLy8gICAgIC8vIENhbGxlZCBhZnRlciBhbGwgSlFIVE1MIGNvbXBvbmVudHMgaGF2ZSBsb2FkZWQgYW5kIHJlbmRlcmVkXG4gICAgLy8gICAgIC8vIFVzZSB0aGlzIGlmIHlvdSBuZWVkIHRvIGludGVyYWN0IHdpdGggSlFIVE1MIGNvbXBvbmVudHNcbiAgICAvLyAgICAgLy8gT3RoZXJ3aXNlLCB1c2Ugb25fYXBwX3JlYWR5KCkgZm9yIG1vc3QgaW5pdGlhbGl6YXRpb25cbiAgICAvLyB9XG59XG4iLCIvKipcbiAqIFByb2plY3RzX0RhdGFHcmlkIENvbXBvbmVudFxuICpcbiAqIENvbmNyZXRlIGltcGxlbWVudGF0aW9uIGZvciBwcm9qZWN0cyBkYXRhZ3JpZC5cbiAqIEFsbCBmdW5jdGlvbmFsaXR5IGlzIGluIERhdGFHcmlkX0Fic3RyYWN0LlxuICovXG5jbGFzcyBQcm9qZWN0c19EYXRhR3JpZCBleHRlbmRzIERhdGFHcmlkX0Fic3RyYWN0IHtcbiAgICAvLyBBbGwgYmVoYXZpb3IgaW5oZXJpdGVkIGZyb20gRGF0YUdyaWRfQWJzdHJhY3Rcbn1cbiIsImNsYXNzIEZyb250ZW5kX1Byb2plY3RzX0VkaXQge1xuICAgIHN0YXRpYyBpbml0KCkge1xuICAgICAgICAvLyBObyBpbml0aWFsaXphdGlvbiBuZWVkZWQgLSBzdWJtaXQgYnV0dG9uIGF1dG9tYXRpY2FsbHkgd2lyZWQgYnkgUnN4X0Zvcm1cbiAgICB9XG5cbiAgICBzdGF0aWMgb25fYXBwX3JlYWR5KCkge1xuICAgICAgICBGcm9udGVuZF9Qcm9qZWN0c19FZGl0LmluaXQoKTtcbiAgICB9XG59XG4iLCJjbGFzcyBGcm9udGVuZF9Qcm9qZWN0c19MaXN0IHtcbiAgICBzdGF0aWMgaW5pdCgpIHtcbiAgICAgICAgaWYgKCEkKFwiLkZyb250ZW5kX1Byb2plY3RzX0xpc3RcIikuZXhpc3RzKCkpIHJldHVybjtcblxuICAgICAgICAvLyBJbml0aWFsaXplIHlvdXIgY29tcG9uZW50IGhlcmVcbiAgICAgICAgY29uc29sZS5sb2coJ0Zyb250ZW5kX1Byb2plY3RzX0xpc3QgaW5pdGlhbGl6ZWQnKTtcblxuICAgICAgICAvLyBFeGFtcGxlOiBIYW5kbGUgYnV0dG9uIGNsaWNrc1xuICAgICAgICAkKCcuYnRuLWFjdGlvbicpLm9uKCdjbGljaycsIGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgLy8gSGFuZGxlIGFjdGlvblxuICAgICAgICB9KTtcblxuICAgICAgICAvLyBFeGFtcGxlOiBJbml0aWFsaXplIHRvb2x0aXBzXG4gICAgICAgICQoJ1tkYXRhLWJzLXRvZ2dsZT1cInRvb2x0aXBcIl0nKS50b29sdGlwKCk7XG4gICAgfVxuXG4gICAgc3RhdGljIG9uX2FwcF9yZWFkeSgpIHtcbiAgICAgICAgRnJvbnRlbmRfUHJvamVjdHNfTGlzdC5pbml0KCk7XG4gICAgfVxuXG4gICAgLy8gc3RhdGljIG9uX2pxaHRtbF9yZWFkeSgpIHtcbiAgICAvLyAgICAgLy8gQ2FsbGVkIGFmdGVyIGFsbCBKUUhUTUwgY29tcG9uZW50cyBoYXZlIGxvYWRlZCBhbmQgcmVuZGVyZWRcbiAgICAvLyAgICAgLy8gVXNlIHRoaXMgaWYgeW91IG5lZWQgdG8gaW50ZXJhY3Qgd2l0aCBKUUhUTUwgY29tcG9uZW50c1xuICAgIC8vICAgICAvLyBPdGhlcndpc2UsIHVzZSBvbl9hcHBfcmVhZHkoKSBmb3IgbW9zdCBpbml0aWFsaXphdGlvblxuICAgIC8vIH1cbn0iLCJjbGFzcyBGcm9udGVuZF9Qcm9qZWN0c19WaWV3IHtcbiAgICBzdGF0aWMgaW5pdCgpIHtcbiAgICAgICAgaWYgKCEkKFwiLkZyb250ZW5kX1Byb2plY3RzX1ZpZXdcIikuZXhpc3RzKCkpIHJldHVybjtcblxuICAgICAgICAvLyBJbml0aWFsaXplIHlvdXIgY29tcG9uZW50IGhlcmVcbiAgICAgICAgY29uc29sZS5sb2coJ0Zyb250ZW5kX1Byb2plY3RzX1ZpZXcgaW5pdGlhbGl6ZWQnKTtcblxuICAgICAgICAvLyBFeGFtcGxlOiBIYW5kbGUgYnV0dG9uIGNsaWNrc1xuICAgICAgICAkKCcuYnRuLWFjdGlvbicpLm9uKCdjbGljaycsIGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgLy8gSGFuZGxlIGFjdGlvblxuICAgICAgICB9KTtcblxuICAgICAgICAvLyBFeGFtcGxlOiBJbml0aWFsaXplIHRvb2x0aXBzXG4gICAgICAgICQoJ1tkYXRhLWJzLXRvZ2dsZT1cInRvb2x0aXBcIl0nKS50b29sdGlwKCk7XG4gICAgfVxuXG4gICAgc3RhdGljIG9uX2FwcF9yZWFkeSgpIHtcbiAgICAgICAgRnJvbnRlbmRfUHJvamVjdHNfVmlldy5pbml0KCk7XG4gICAgfVxuXG4gICAgLy8gc3RhdGljIG9uX2pxaHRtbF9yZWFkeSgpIHtcbiAgICAvLyAgICAgLy8gQ2FsbGVkIGFmdGVyIGFsbCBKUUhUTUwgY29tcG9uZW50cyBoYXZlIGxvYWRlZCBhbmQgcmVuZGVyZWRcbiAgICAvLyAgICAgLy8gVXNlIHRoaXMgaWYgeW91IG5lZWQgdG8gaW50ZXJhY3Qgd2l0aCBKUUhUTUwgY29tcG9uZW50c1xuICAgIC8vICAgICAvLyBPdGhlcndpc2UsIHVzZSBvbl9hcHBfcmVhZHkoKSBmb3IgbW9zdCBpbml0aWFsaXphdGlvblxuICAgIC8vIH1cbn0iLCJjbGFzcyBGcm9udGVuZF9Qcm9qZWN0c19BZGQge1xuICAgIHN0YXRpYyBpbml0KCkge1xuICAgICAgICBpZiAoISQoXCIuRnJvbnRlbmRfUHJvamVjdHNfQWRkXCIpLmV4aXN0cygpKSByZXR1cm47XG5cbiAgICAgICAgLy8gSW5pdGlhbGl6ZSB5b3VyIGNvbXBvbmVudCBoZXJlXG4gICAgICAgIGNvbnNvbGUubG9nKCdGcm9udGVuZF9Qcm9qZWN0c19BZGQgaW5pdGlhbGl6ZWQnKTtcblxuICAgICAgICAvLyBFeGFtcGxlOiBIYW5kbGUgYnV0dG9uIGNsaWNrc1xuICAgICAgICAkKCcuYnRuLWFjdGlvbicpLm9uKCdjbGljaycsIGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgLy8gSGFuZGxlIGFjdGlvblxuICAgICAgICB9KTtcblxuICAgICAgICAvLyBFeGFtcGxlOiBJbml0aWFsaXplIHRvb2x0aXBzXG4gICAgICAgICQoJ1tkYXRhLWJzLXRvZ2dsZT1cInRvb2x0aXBcIl0nKS50b29sdGlwKCk7XG4gICAgfVxuXG4gICAgc3RhdGljIG9uX2FwcF9yZWFkeSgpIHtcbiAgICAgICAgRnJvbnRlbmRfUHJvamVjdHNfQWRkLmluaXQoKTtcbiAgICB9XG5cbiAgICAvLyBzdGF0aWMgb25fanFodG1sX3JlYWR5KCkge1xuICAgIC8vICAgICAvLyBDYWxsZWQgYWZ0ZXIgYWxsIEpRSFRNTCBjb21wb25lbnRzIGhhdmUgbG9hZGVkIGFuZCByZW5kZXJlZFxuICAgIC8vICAgICAvLyBVc2UgdGhpcyBpZiB5b3UgbmVlZCB0byBpbnRlcmFjdCB3aXRoIEpRSFRNTCBjb21wb25lbnRzXG4gICAgLy8gICAgIC8vIE90aGVyd2lzZSwgdXNlIG9uX2FwcF9yZWFkeSgpIGZvciBtb3N0IGluaXRpYWxpemF0aW9uXG4gICAgLy8gfVxufSIsImNsYXNzIEZyb250ZW5kX1Byb2plY3RzIHtcbiAgICBzdGF0aWMgaW5pdCgpIHtcbiAgICAgICAgaWYgKCEkKFwiLkZyb250ZW5kX1Byb2plY3RzXCIpLmV4aXN0cygpKSByZXR1cm47XG5cbiAgICAgICAgLy8gSW5pdGlhbGl6ZSB5b3VyIGNvbXBvbmVudCBoZXJlXG4gICAgICAgIGNvbnNvbGUubG9nKCdGcm9udGVuZF9Qcm9qZWN0cyBpbml0aWFsaXplZCcpO1xuICAgIH1cblxuICAgIHN0YXRpYyBvbl9hcHBfcmVhZHkoKSB7XG4gICAgICAgIEZyb250ZW5kX1Byb2plY3RzLmluaXQoKTtcbiAgICB9XG59IiwiY2xhc3MgRnJvbnRlbmRfVGFza3Mge1xuICAgIHN0YXRpYyBpbml0KCkge1xuICAgICAgICBpZiAoISQoXCIuRnJvbnRlbmRfVGFza3NcIikuZXhpc3RzKCkpIHJldHVybjtcblxuICAgICAgICAvLyBJbml0aWFsaXplIHlvdXIgY29tcG9uZW50IGhlcmVcbiAgICAgICAgY29uc29sZS5sb2coJ0Zyb250ZW5kX1Rhc2tzIGluaXRpYWxpemVkJyk7XG5cbiAgICAgICAgLy8gRXhhbXBsZTogSGFuZGxlIGJ1dHRvbiBjbGlja3NcbiAgICAgICAgJCgnLmJ0bi1hY3Rpb24nKS5vbignY2xpY2snLCBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgIC8vIEhhbmRsZSBhY3Rpb25cbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gRXhhbXBsZTogSW5pdGlhbGl6ZSB0b29sdGlwc1xuICAgICAgICAkKCdbZGF0YS1icy10b2dnbGU9XCJ0b29sdGlwXCJdJykudG9vbHRpcCgpO1xuICAgIH1cblxuICAgIHN0YXRpYyBvbl9hcHBfcmVhZHkoKSB7XG4gICAgICAgIEZyb250ZW5kX1Rhc2tzLmluaXQoKTtcbiAgICB9XG5cbiAgICAvLyBzdGF0aWMgb25fanFodG1sX3JlYWR5KCkge1xuICAgIC8vICAgICAvLyBDYWxsZWQgYWZ0ZXIgYWxsIEpRSFRNTCBjb21wb25lbnRzIGhhdmUgbG9hZGVkIGFuZCByZW5kZXJlZFxuICAgIC8vICAgICAvLyBVc2UgdGhpcyBpZiB5b3UgbmVlZCB0byBpbnRlcmFjdCB3aXRoIEpRSFRNTCBjb21wb25lbnRzXG4gICAgLy8gICAgIC8vIE90aGVyd2lzZSwgdXNlIG9uX2FwcF9yZWFkeSgpIGZvciBtb3N0IGluaXRpYWxpemF0aW9uXG4gICAgLy8gfVxufSIsImNsYXNzIEZyb250ZW5kX1Rhc2tzX1ZpZXcge1xuICAgIHN0YXRpYyBpbml0KCkge1xuICAgICAgICBpZiAoISQoXCIuRnJvbnRlbmRfVGFza3NfVmlld1wiKS5leGlzdHMoKSkgcmV0dXJuO1xuXG4gICAgICAgIC8vIEluaXRpYWxpemUgeW91ciBjb21wb25lbnQgaGVyZVxuICAgICAgICBjb25zb2xlLmxvZygnRnJvbnRlbmRfVGFza3NfVmlldyBpbml0aWFsaXplZCcpO1xuXG4gICAgICAgIC8vIEV4YW1wbGU6IEhhbmRsZSBidXR0b24gY2xpY2tzXG4gICAgICAgICQoJy5idG4tYWN0aW9uJykub24oJ2NsaWNrJywgZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICAvLyBIYW5kbGUgYWN0aW9uXG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIEV4YW1wbGU6IEluaXRpYWxpemUgdG9vbHRpcHNcbiAgICAgICAgJCgnW2RhdGEtYnMtdG9nZ2xlPVwidG9vbHRpcFwiXScpLnRvb2x0aXAoKTtcbiAgICB9XG5cbiAgICBzdGF0aWMgb25fYXBwX3JlYWR5KCkge1xuICAgICAgICBGcm9udGVuZF9UYXNrc19WaWV3LmluaXQoKTtcbiAgICB9XG5cbiAgICAvLyBzdGF0aWMgb25fanFodG1sX3JlYWR5KCkge1xuICAgIC8vICAgICAvLyBDYWxsZWQgYWZ0ZXIgYWxsIEpRSFRNTCBjb21wb25lbnRzIGhhdmUgbG9hZGVkIGFuZCByZW5kZXJlZFxuICAgIC8vICAgICAvLyBVc2UgdGhpcyBpZiB5b3UgbmVlZCB0byBpbnRlcmFjdCB3aXRoIEpRSFRNTCBjb21wb25lbnRzXG4gICAgLy8gICAgIC8vIE90aGVyd2lzZSwgdXNlIG9uX2FwcF9yZWFkeSgpIGZvciBtb3N0IGluaXRpYWxpemF0aW9uXG4gICAgLy8gfVxufSIsImNsYXNzIEZyb250ZW5kX1Rhc2tzX0FkZCB7XG4gICAgc3RhdGljIGluaXQoKSB7XG4gICAgICAgIGlmICghJChcIi5Gcm9udGVuZF9UYXNrc19BZGRcIikuZXhpc3RzKCkpIHJldHVybjtcblxuICAgICAgICAvLyBJbml0aWFsaXplIHlvdXIgY29tcG9uZW50IGhlcmVcbiAgICAgICAgY29uc29sZS5sb2coJ0Zyb250ZW5kX1Rhc2tzX0FkZCBpbml0aWFsaXplZCcpO1xuXG4gICAgICAgIC8vIEV4YW1wbGU6IEhhbmRsZSBidXR0b24gY2xpY2tzXG4gICAgICAgICQoJy5idG4tYWN0aW9uJykub24oJ2NsaWNrJywgZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICAvLyBIYW5kbGUgYWN0aW9uXG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIEV4YW1wbGU6IEluaXRpYWxpemUgdG9vbHRpcHNcbiAgICAgICAgJCgnW2RhdGEtYnMtdG9nZ2xlPVwidG9vbHRpcFwiXScpLnRvb2x0aXAoKTtcbiAgICB9XG5cbiAgICBzdGF0aWMgb25fYXBwX3JlYWR5KCkge1xuICAgICAgICBGcm9udGVuZF9UYXNrc19BZGQuaW5pdCgpO1xuICAgIH1cblxuICAgIC8vIHN0YXRpYyBvbl9qcWh0bWxfcmVhZHkoKSB7XG4gICAgLy8gICAgIC8vIENhbGxlZCBhZnRlciBhbGwgSlFIVE1MIGNvbXBvbmVudHMgaGF2ZSBsb2FkZWQgYW5kIHJlbmRlcmVkXG4gICAgLy8gICAgIC8vIFVzZSB0aGlzIGlmIHlvdSBuZWVkIHRvIGludGVyYWN0IHdpdGggSlFIVE1MIGNvbXBvbmVudHNcbiAgICAvLyAgICAgLy8gT3RoZXJ3aXNlLCB1c2Ugb25fYXBwX3JlYWR5KCkgZm9yIG1vc3QgaW5pdGlhbGl6YXRpb25cbiAgICAvLyB9XG59IiwiY2xhc3MgRnJvbnRlbmRfQ2FsZW5kYXIge1xuICAgIHN0YXRpYyBpbml0KCkge1xuICAgICAgICBpZiAoISQoXCIuRnJvbnRlbmRfQ2FsZW5kYXJcIikuZXhpc3RzKCkpIHJldHVybjtcblxuICAgICAgICAvLyBJbml0aWFsaXplIHlvdXIgY29tcG9uZW50IGhlcmVcbiAgICAgICAgY29uc29sZS5sb2coJ0Zyb250ZW5kX0NhbGVuZGFyIGluaXRpYWxpemVkJyk7XG5cbiAgICAgICAgLy8gRXhhbXBsZTogSGFuZGxlIGJ1dHRvbiBjbGlja3NcbiAgICAgICAgJCgnLmJ0bi1hY3Rpb24nKS5vbignY2xpY2snLCBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgIC8vIEhhbmRsZSBhY3Rpb25cbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gRXhhbXBsZTogSW5pdGlhbGl6ZSB0b29sdGlwc1xuICAgICAgICAkKCdbZGF0YS1icy10b2dnbGU9XCJ0b29sdGlwXCJdJykudG9vbHRpcCgpO1xuICAgIH1cblxuICAgIHN0YXRpYyBvbl9hcHBfcmVhZHkoKSB7XG4gICAgICAgIEZyb250ZW5kX0NhbGVuZGFyLmluaXQoKTtcbiAgICB9XG5cbiAgICAvLyBzdGF0aWMgb25fanFodG1sX3JlYWR5KCkge1xuICAgIC8vICAgICAvLyBDYWxsZWQgYWZ0ZXIgYWxsIEpRSFRNTCBjb21wb25lbnRzIGhhdmUgbG9hZGVkIGFuZCByZW5kZXJlZFxuICAgIC8vICAgICAvLyBVc2UgdGhpcyBpZiB5b3UgbmVlZCB0byBpbnRlcmFjdCB3aXRoIEpRSFRNTCBjb21wb25lbnRzXG4gICAgLy8gICAgIC8vIE90aGVyd2lzZSwgdXNlIG9uX2FwcF9yZWFkeSgpIGZvciBtb3N0IGluaXRpYWxpemF0aW9uXG4gICAgLy8gfVxufSIsImNsYXNzIEZyb250ZW5kX0NhbGVuZGFyX0V2ZW50IHtcbiAgICBzdGF0aWMgaW5pdCgpIHtcbiAgICAgICAgaWYgKCEkKFwiLkZyb250ZW5kX0NhbGVuZGFyX0V2ZW50XCIpLmV4aXN0cygpKSByZXR1cm47XG5cbiAgICAgICAgLy8gSW5pdGlhbGl6ZSB5b3VyIGNvbXBvbmVudCBoZXJlXG4gICAgICAgIGNvbnNvbGUubG9nKCdGcm9udGVuZF9DYWxlbmRhcl9FdmVudCBpbml0aWFsaXplZCcpO1xuXG4gICAgICAgIC8vIEV4YW1wbGU6IEhhbmRsZSBidXR0b24gY2xpY2tzXG4gICAgICAgICQoJy5idG4tYWN0aW9uJykub24oJ2NsaWNrJywgZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICAvLyBIYW5kbGUgYWN0aW9uXG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIEV4YW1wbGU6IEluaXRpYWxpemUgdG9vbHRpcHNcbiAgICAgICAgJCgnW2RhdGEtYnMtdG9nZ2xlPVwidG9vbHRpcFwiXScpLnRvb2x0aXAoKTtcbiAgICB9XG5cbiAgICBzdGF0aWMgb25fYXBwX3JlYWR5KCkge1xuICAgICAgICBGcm9udGVuZF9DYWxlbmRhcl9FdmVudC5pbml0KCk7XG4gICAgfVxuXG4gICAgLy8gc3RhdGljIG9uX2pxaHRtbF9yZWFkeSgpIHtcbiAgICAvLyAgICAgLy8gQ2FsbGVkIGFmdGVyIGFsbCBKUUhUTUwgY29tcG9uZW50cyBoYXZlIGxvYWRlZCBhbmQgcmVuZGVyZWRcbiAgICAvLyAgICAgLy8gVXNlIHRoaXMgaWYgeW91IG5lZWQgdG8gaW50ZXJhY3Qgd2l0aCBKUUhUTUwgY29tcG9uZW50c1xuICAgIC8vICAgICAvLyBPdGhlcndpc2UsIHVzZSBvbl9hcHBfcmVhZHkoKSBmb3IgbW9zdCBpbml0aWFsaXphdGlvblxuICAgIC8vIH1cbn0iLCJjbGFzcyBGcm9udGVuZF9JbnZvaWNlcyB7XG4gICAgc3RhdGljIGluaXQoKSB7XG4gICAgICAgIGlmICghJChcIi5Gcm9udGVuZF9JbnZvaWNlc1wiKS5leGlzdHMoKSkgcmV0dXJuO1xuXG4gICAgICAgIC8vIEluaXRpYWxpemUgeW91ciBjb21wb25lbnQgaGVyZVxuICAgICAgICBjb25zb2xlLmxvZygnRnJvbnRlbmRfSW52b2ljZXMgaW5pdGlhbGl6ZWQnKTtcblxuICAgICAgICAvLyBFeGFtcGxlOiBIYW5kbGUgYnV0dG9uIGNsaWNrc1xuICAgICAgICAkKCcuYnRuLWFjdGlvbicpLm9uKCdjbGljaycsIGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgLy8gSGFuZGxlIGFjdGlvblxuICAgICAgICB9KTtcblxuICAgICAgICAvLyBFeGFtcGxlOiBJbml0aWFsaXplIHRvb2x0aXBzXG4gICAgICAgICQoJ1tkYXRhLWJzLXRvZ2dsZT1cInRvb2x0aXBcIl0nKS50b29sdGlwKCk7XG4gICAgfVxuXG4gICAgc3RhdGljIG9uX2FwcF9yZWFkeSgpIHtcbiAgICAgICAgRnJvbnRlbmRfSW52b2ljZXMuaW5pdCgpO1xuICAgIH1cblxuICAgIC8vIHN0YXRpYyBvbl9qcWh0bWxfcmVhZHkoKSB7XG4gICAgLy8gICAgIC8vIENhbGxlZCBhZnRlciBhbGwgSlFIVE1MIGNvbXBvbmVudHMgaGF2ZSBsb2FkZWQgYW5kIHJlbmRlcmVkXG4gICAgLy8gICAgIC8vIFVzZSB0aGlzIGlmIHlvdSBuZWVkIHRvIGludGVyYWN0IHdpdGggSlFIVE1MIGNvbXBvbmVudHNcbiAgICAvLyAgICAgLy8gT3RoZXJ3aXNlLCB1c2Ugb25fYXBwX3JlYWR5KCkgZm9yIG1vc3QgaW5pdGlhbGl6YXRpb25cbiAgICAvLyB9XG59IiwiY2xhc3MgRnJvbnRlbmRfSW52b2ljZXNfVmlldyB7XG4gICAgc3RhdGljIGluaXQoKSB7XG4gICAgICAgIGlmICghJChcIi5Gcm9udGVuZF9JbnZvaWNlc19WaWV3XCIpLmV4aXN0cygpKSByZXR1cm47XG5cbiAgICAgICAgLy8gSW5pdGlhbGl6ZSB5b3VyIGNvbXBvbmVudCBoZXJlXG4gICAgICAgIGNvbnNvbGUubG9nKCdGcm9udGVuZF9JbnZvaWNlc19WaWV3IGluaXRpYWxpemVkJyk7XG5cbiAgICAgICAgLy8gRXhhbXBsZTogSGFuZGxlIGJ1dHRvbiBjbGlja3NcbiAgICAgICAgJCgnLmJ0bi1hY3Rpb24nKS5vbignY2xpY2snLCBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgIC8vIEhhbmRsZSBhY3Rpb25cbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gRXhhbXBsZTogSW5pdGlhbGl6ZSB0b29sdGlwc1xuICAgICAgICAkKCdbZGF0YS1icy10b2dnbGU9XCJ0b29sdGlwXCJdJykudG9vbHRpcCgpO1xuICAgIH1cblxuICAgIHN0YXRpYyBvbl9hcHBfcmVhZHkoKSB7XG4gICAgICAgIEZyb250ZW5kX0ludm9pY2VzX1ZpZXcuaW5pdCgpO1xuICAgIH1cblxuICAgIC8vIHN0YXRpYyBvbl9qcWh0bWxfcmVhZHkoKSB7XG4gICAgLy8gICAgIC8vIENhbGxlZCBhZnRlciBhbGwgSlFIVE1MIGNvbXBvbmVudHMgaGF2ZSBsb2FkZWQgYW5kIHJlbmRlcmVkXG4gICAgLy8gICAgIC8vIFVzZSB0aGlzIGlmIHlvdSBuZWVkIHRvIGludGVyYWN0IHdpdGggSlFIVE1MIGNvbXBvbmVudHNcbiAgICAvLyAgICAgLy8gT3RoZXJ3aXNlLCB1c2Ugb25fYXBwX3JlYWR5KCkgZm9yIG1vc3QgaW5pdGlhbGl6YXRpb25cbiAgICAvLyB9XG59IiwiLyoqXG4gKiBGcm9udGVuZF9JbnZvaWNlc19BZGQgQ29tcG9uZW50XG4gKlxuICogSGFuZGxlcyBkeW5hbWljIGxpbmUgaXRlbXMgYW5kIGludm9pY2UgY2FsY3VsYXRpb25zXG4gKi9cbmNsYXNzIEZyb250ZW5kX0ludm9pY2VzX0FkZCB7XG4gICAgc3RhdGljIGxpbmVfaXRlbV9jb3VudCA9IDE7XG5cbiAgICBzdGF0aWMgYXN5bmMgb25fYXBwX3JlYWR5KCkge1xuICAgICAgICBpZiAoISQoXCIuRnJvbnRlbmRfSW52b2ljZXNfQWRkXCIpLmV4aXN0cygpKSByZXR1cm47XG5cbiAgICAgICAgLy8gQWRkIGxpbmUgaXRlbSBidXR0b25cbiAgICAgICAgJCgnI2FkZExpbmVJdGVtJykub24oJ2NsaWNrJywgKCkgPT4ge1xuICAgICAgICAgICAgRnJvbnRlbmRfSW52b2ljZXNfQWRkLmFkZF9saW5lX2l0ZW0oKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gSW5pdGlhbCBjYWxjdWxhdGlvblxuICAgICAgICBGcm9udGVuZF9JbnZvaWNlc19BZGQuY2FsY3VsYXRlX3RvdGFscygpO1xuXG4gICAgICAgIC8vIEF0dGFjaCBldmVudCBoYW5kbGVycyB0byBleGlzdGluZyBsaW5lIGl0ZW1zXG4gICAgICAgIEZyb250ZW5kX0ludm9pY2VzX0FkZC5hdHRhY2hfbGluZV9pdGVtX2hhbmRsZXJzKCk7XG5cbiAgICAgICAgLy8gVGF4IHJhdGUgY2hhbmdlXG4gICAgICAgICQoJyN0YXhfcmF0ZScpLm9uKCdpbnB1dCcsICgpID0+IHtcbiAgICAgICAgICAgIEZyb250ZW5kX0ludm9pY2VzX0FkZC5jYWxjdWxhdGVfdG90YWxzKCk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHN0YXRpYyBhdHRhY2hfbGluZV9pdGVtX2hhbmRsZXJzKCkge1xuICAgICAgICAvLyBRdWFudGl0eSBhbmQgcmF0ZSBjaGFuZ2VzXG4gICAgICAgICQoJy5pdGVtLXF1YW50aXR5LCAuaXRlbS1yYXRlJykub2ZmKCdpbnB1dCcpLm9uKCdpbnB1dCcsIGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgRnJvbnRlbmRfSW52b2ljZXNfQWRkLnVwZGF0ZV9saW5lX2l0ZW1fYW1vdW50KCQodGhpcykuY2xvc2VzdCgndHInKSk7XG4gICAgICAgICAgICBGcm9udGVuZF9JbnZvaWNlc19BZGQuY2FsY3VsYXRlX3RvdGFscygpO1xuICAgICAgICB9KTtcblxuICAgICAgICAvLyBSZW1vdmUgaXRlbSBidXR0b25zXG4gICAgICAgICQoJy5yZW1vdmUtaXRlbScpLm9mZignY2xpY2snKS5vbignY2xpY2snLCBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgIGNvbnN0ICRyb3cgPSAkKHRoaXMpLmNsb3Nlc3QoJ3RyJyk7XG4gICAgICAgICAgICBpZiAoJCgnI2xpbmVJdGVtc0JvZHkgdHInKS5sZW5ndGggPiAxKSB7XG4gICAgICAgICAgICAgICAgJHJvdy5yZW1vdmUoKTtcbiAgICAgICAgICAgICAgICBGcm9udGVuZF9JbnZvaWNlc19BZGQuY2FsY3VsYXRlX3RvdGFscygpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBhbGVydCgnSW52b2ljZSBtdXN0IGhhdmUgYXQgbGVhc3Qgb25lIGxpbmUgaXRlbScpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBzdGF0aWMgYWRkX2xpbmVfaXRlbSgpIHtcbiAgICAgICAgY29uc3QgaW5kZXggPSBGcm9udGVuZF9JbnZvaWNlc19BZGQubGluZV9pdGVtX2NvdW50Kys7XG4gICAgICAgIGNvbnN0ICRyb3cgPSAkKGBcbiAgICAgICAgICAgIDx0ciBjbGFzcz1cImxpbmUtaXRlbVwiPlxuICAgICAgICAgICAgICAgIDx0ZD5cbiAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJ0ZXh0XCIgY2xhc3M9XCJmb3JtLWNvbnRyb2wgZm9ybS1jb250cm9sLXNtXCIgbmFtZT1cIml0ZW1zWyR7aW5kZXh9XVtkZXNjcmlwdGlvbl1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgcGxhY2Vob2xkZXI9XCJJdGVtIGRlc2NyaXB0aW9uXCIgcmVxdWlyZWQ+XG4gICAgICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgICAgICA8dGQ+XG4gICAgICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwibnVtYmVyXCIgY2xhc3M9XCJmb3JtLWNvbnRyb2wgZm9ybS1jb250cm9sLXNtIHRleHQtZW5kIGl0ZW0tcXVhbnRpdHlcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZT1cIml0ZW1zWyR7aW5kZXh9XVtxdWFudGl0eV1cIiB2YWx1ZT1cIjFcIiBtaW49XCIwXCIgc3RlcD1cIjAuMDFcIiByZXF1aXJlZD5cbiAgICAgICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgICAgIDx0ZD5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImlucHV0LWdyb3VwIGlucHV0LWdyb3VwLXNtXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImlucHV0LWdyb3VwLXRleHRcIj4kPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJudW1iZXJcIiBjbGFzcz1cImZvcm0tY29udHJvbCB0ZXh0LWVuZCBpdGVtLXJhdGVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWU9XCJpdGVtc1ske2luZGV4fV1bcmF0ZV1cIiB2YWx1ZT1cIjAuMDBcIiBtaW49XCIwXCIgc3RlcD1cIjAuMDFcIiByZXF1aXJlZD5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgICAgICA8dGQgY2xhc3M9XCJ0ZXh0LWVuZFwiPlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZnctYm9sZCBpdGVtLWFtb3VudFwiPiQwLjAwPC9kaXY+XG4gICAgICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgICAgICA8dGQgY2xhc3M9XCJ0ZXh0LWNlbnRlclwiPlxuICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cImJ0biBidG4tc20gYnRuLWRhbmdlciByZW1vdmUtaXRlbVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGkgY2xhc3M9XCJiaSBiaS10cmFzaFwiPjwvaT5cbiAgICAgICAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgIDwvdHI+XG4gICAgICAgIGApO1xuXG4gICAgICAgICQoJyNsaW5lSXRlbXNCb2R5JykuYXBwZW5kKCRyb3cpO1xuICAgICAgICBGcm9udGVuZF9JbnZvaWNlc19BZGQuYXR0YWNoX2xpbmVfaXRlbV9oYW5kbGVycygpO1xuICAgIH1cblxuICAgIHN0YXRpYyB1cGRhdGVfbGluZV9pdGVtX2Ftb3VudChyb3cpIHtcbiAgICAgICAgY29uc3QgcXVhbnRpdHkgPSBmbG9hdChyb3cuZmluZCgnLml0ZW0tcXVhbnRpdHknKS52YWwoKSkgfHwgMDtcbiAgICAgICAgY29uc3QgcmF0ZSA9IGZsb2F0KHJvdy5maW5kKCcuaXRlbS1yYXRlJykudmFsKCkpIHx8IDA7XG4gICAgICAgIGNvbnN0IGFtb3VudCA9IHF1YW50aXR5ICogcmF0ZTtcblxuICAgICAgICByb3cuZmluZCgnLml0ZW0tYW1vdW50JykudGV4dChgJCR7YW1vdW50LnRvRml4ZWQoMil9YCk7XG4gICAgfVxuXG4gICAgc3RhdGljIGNhbGN1bGF0ZV90b3RhbHMoKSB7XG4gICAgICAgIGxldCBzdWJ0b3RhbCA9IDA7XG5cbiAgICAgICAgLy8gQ2FsY3VsYXRlIHN1YnRvdGFsIGZyb20gYWxsIGxpbmUgaXRlbXNcbiAgICAgICAgJCgnI2xpbmVJdGVtc0JvZHkgdHInKS5lYWNoKGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgY29uc3QgcXVhbnRpdHkgPSBmbG9hdCgkKHRoaXMpLmZpbmQoJy5pdGVtLXF1YW50aXR5JykudmFsKCkpIHx8IDA7XG4gICAgICAgICAgICBjb25zdCByYXRlID0gZmxvYXQoJCh0aGlzKS5maW5kKCcuaXRlbS1yYXRlJykudmFsKCkpIHx8IDA7XG4gICAgICAgICAgICBzdWJ0b3RhbCArPSBxdWFudGl0eSAqIHJhdGU7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIENhbGN1bGF0ZSB0YXhcbiAgICAgICAgY29uc3QgdGF4X3JhdGUgPSBmbG9hdCgkKCcjdGF4X3JhdGUnKS52YWwoKSkgfHwgMDtcbiAgICAgICAgY29uc3QgdGF4X2Ftb3VudCA9IHN1YnRvdGFsICogKHRheF9yYXRlIC8gMTAwKTtcbiAgICAgICAgY29uc3QgdG90YWwgPSBzdWJ0b3RhbCArIHRheF9hbW91bnQ7XG5cbiAgICAgICAgLy8gVXBkYXRlIGRpc3BsYXlzXG4gICAgICAgICQoJyNzdWJ0b3RhbERpc3BsYXknKS50ZXh0KGAkJHtzdWJ0b3RhbC50b0ZpeGVkKDIpfWApO1xuICAgICAgICAkKCcjdGF4RGlzcGxheScpLnRleHQoYCQke3RheF9hbW91bnQudG9GaXhlZCgyKX1gKTtcbiAgICAgICAgJCgnI3RvdGFsRGlzcGxheScpLnRleHQoYCQke3RvdGFsLnRvRml4ZWQoMil9YCk7XG4gICAgfVxufVxuIiwiY2xhc3MgRnJvbnRlbmRfUmVwb3J0cyB7XG4gICAgc3RhdGljIGluaXQoKSB7XG4gICAgICAgIGlmICghJChcIi5Gcm9udGVuZF9SZXBvcnRzXCIpLmV4aXN0cygpKSByZXR1cm47XG5cbiAgICAgICAgLy8gSW5pdGlhbGl6ZSB5b3VyIGNvbXBvbmVudCBoZXJlXG4gICAgICAgIGNvbnNvbGUubG9nKCdGcm9udGVuZF9SZXBvcnRzIGluaXRpYWxpemVkJyk7XG5cbiAgICAgICAgLy8gRXhhbXBsZTogSGFuZGxlIGJ1dHRvbiBjbGlja3NcbiAgICAgICAgJCgnLmJ0bi1hY3Rpb24nKS5vbignY2xpY2snLCBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgIC8vIEhhbmRsZSBhY3Rpb25cbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gRXhhbXBsZTogSW5pdGlhbGl6ZSB0b29sdGlwc1xuICAgICAgICAkKCdbZGF0YS1icy10b2dnbGU9XCJ0b29sdGlwXCJdJykudG9vbHRpcCgpO1xuICAgIH1cblxuICAgIHN0YXRpYyBvbl9hcHBfcmVhZHkoKSB7XG4gICAgICAgIEZyb250ZW5kX1JlcG9ydHMuaW5pdCgpO1xuICAgIH1cblxuICAgIC8vIHN0YXRpYyBvbl9qcWh0bWxfcmVhZHkoKSB7XG4gICAgLy8gICAgIC8vIENhbGxlZCBhZnRlciBhbGwgSlFIVE1MIGNvbXBvbmVudHMgaGF2ZSBsb2FkZWQgYW5kIHJlbmRlcmVkXG4gICAgLy8gICAgIC8vIFVzZSB0aGlzIGlmIHlvdSBuZWVkIHRvIGludGVyYWN0IHdpdGggSlFIVE1MIGNvbXBvbmVudHNcbiAgICAvLyAgICAgLy8gT3RoZXJ3aXNlLCB1c2Ugb25fYXBwX3JlYWR5KCkgZm9yIG1vc3QgaW5pdGlhbGl6YXRpb25cbiAgICAvLyB9XG59IiwiY2xhc3MgRnJvbnRlbmRfUmVwb3J0c19SZXZlbnVlIHtcbiAgICBzdGF0aWMgaW5pdCgpIHtcbiAgICAgICAgaWYgKCEkKFwiLkZyb250ZW5kX1JlcG9ydHNfUmV2ZW51ZVwiKS5leGlzdHMoKSkgcmV0dXJuO1xuXG4gICAgICAgIC8vIEluaXRpYWxpemUgeW91ciBjb21wb25lbnQgaGVyZVxuICAgICAgICBjb25zb2xlLmxvZygnRnJvbnRlbmRfUmVwb3J0c19SZXZlbnVlIGluaXRpYWxpemVkJyk7XG5cbiAgICAgICAgLy8gRXhhbXBsZTogSGFuZGxlIGJ1dHRvbiBjbGlja3NcbiAgICAgICAgJCgnLmJ0bi1hY3Rpb24nKS5vbignY2xpY2snLCBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgIC8vIEhhbmRsZSBhY3Rpb25cbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gRXhhbXBsZTogSW5pdGlhbGl6ZSB0b29sdGlwc1xuICAgICAgICAkKCdbZGF0YS1icy10b2dnbGU9XCJ0b29sdGlwXCJdJykudG9vbHRpcCgpO1xuICAgIH1cblxuICAgIHN0YXRpYyBvbl9hcHBfcmVhZHkoKSB7XG4gICAgICAgIEZyb250ZW5kX1JlcG9ydHNfUmV2ZW51ZS5pbml0KCk7XG4gICAgfVxuXG4gICAgLy8gc3RhdGljIG9uX2pxaHRtbF9yZWFkeSgpIHtcbiAgICAvLyAgICAgLy8gQ2FsbGVkIGFmdGVyIGFsbCBKUUhUTUwgY29tcG9uZW50cyBoYXZlIGxvYWRlZCBhbmQgcmVuZGVyZWRcbiAgICAvLyAgICAgLy8gVXNlIHRoaXMgaWYgeW91IG5lZWQgdG8gaW50ZXJhY3Qgd2l0aCBKUUhUTUwgY29tcG9uZW50c1xuICAgIC8vICAgICAvLyBPdGhlcndpc2UsIHVzZSBvbl9hcHBfcmVhZHkoKSBmb3IgbW9zdCBpbml0aWFsaXphdGlvblxuICAgIC8vIH1cbn0iLCJjbGFzcyBGcm9udGVuZF9SZXBvcnRzX0NsaWVudHMge1xuICAgIHN0YXRpYyBpbml0KCkge1xuICAgICAgICBpZiAoISQoXCIuRnJvbnRlbmRfUmVwb3J0c19DbGllbnRzXCIpLmV4aXN0cygpKSByZXR1cm47XG5cbiAgICAgICAgLy8gSW5pdGlhbGl6ZSB5b3VyIGNvbXBvbmVudCBoZXJlXG4gICAgICAgIGNvbnNvbGUubG9nKCdGcm9udGVuZF9SZXBvcnRzX0NsaWVudHMgaW5pdGlhbGl6ZWQnKTtcblxuICAgICAgICAvLyBFeGFtcGxlOiBIYW5kbGUgYnV0dG9uIGNsaWNrc1xuICAgICAgICAkKCcuYnRuLWFjdGlvbicpLm9uKCdjbGljaycsIGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgLy8gSGFuZGxlIGFjdGlvblxuICAgICAgICB9KTtcblxuICAgICAgICAvLyBFeGFtcGxlOiBJbml0aWFsaXplIHRvb2x0aXBzXG4gICAgICAgICQoJ1tkYXRhLWJzLXRvZ2dsZT1cInRvb2x0aXBcIl0nKS50b29sdGlwKCk7XG4gICAgfVxuXG4gICAgc3RhdGljIG9uX2FwcF9yZWFkeSgpIHtcbiAgICAgICAgRnJvbnRlbmRfUmVwb3J0c19DbGllbnRzLmluaXQoKTtcbiAgICB9XG5cbiAgICAvLyBzdGF0aWMgb25fanFodG1sX3JlYWR5KCkge1xuICAgIC8vICAgICAvLyBDYWxsZWQgYWZ0ZXIgYWxsIEpRSFRNTCBjb21wb25lbnRzIGhhdmUgbG9hZGVkIGFuZCByZW5kZXJlZFxuICAgIC8vICAgICAvLyBVc2UgdGhpcyBpZiB5b3UgbmVlZCB0byBpbnRlcmFjdCB3aXRoIEpRSFRNTCBjb21wb25lbnRzXG4gICAgLy8gICAgIC8vIE90aGVyd2lzZSwgdXNlIG9uX2FwcF9yZWFkeSgpIGZvciBtb3N0IGluaXRpYWxpemF0aW9uXG4gICAgLy8gfVxufSIsImNsYXNzIEZyb250ZW5kX1JlcG9ydHNfUHJvamVjdHMge1xuICAgIHN0YXRpYyBpbml0KCkge1xuICAgICAgICBpZiAoISQoXCIuRnJvbnRlbmRfUmVwb3J0c19Qcm9qZWN0c1wiKS5leGlzdHMoKSkgcmV0dXJuO1xuXG4gICAgICAgIC8vIEluaXRpYWxpemUgeW91ciBjb21wb25lbnQgaGVyZVxuICAgICAgICBjb25zb2xlLmxvZygnRnJvbnRlbmRfUmVwb3J0c19Qcm9qZWN0cyBpbml0aWFsaXplZCcpO1xuXG4gICAgICAgIC8vIEV4YW1wbGU6IEhhbmRsZSBidXR0b24gY2xpY2tzXG4gICAgICAgICQoJy5idG4tYWN0aW9uJykub24oJ2NsaWNrJywgZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICAvLyBIYW5kbGUgYWN0aW9uXG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIEV4YW1wbGU6IEluaXRpYWxpemUgdG9vbHRpcHNcbiAgICAgICAgJCgnW2RhdGEtYnMtdG9nZ2xlPVwidG9vbHRpcFwiXScpLnRvb2x0aXAoKTtcbiAgICB9XG5cbiAgICBzdGF0aWMgb25fYXBwX3JlYWR5KCkge1xuICAgICAgICBGcm9udGVuZF9SZXBvcnRzX1Byb2plY3RzLmluaXQoKTtcbiAgICB9XG5cbiAgICAvLyBzdGF0aWMgb25fanFodG1sX3JlYWR5KCkge1xuICAgIC8vICAgICAvLyBDYWxsZWQgYWZ0ZXIgYWxsIEpRSFRNTCBjb21wb25lbnRzIGhhdmUgbG9hZGVkIGFuZCByZW5kZXJlZFxuICAgIC8vICAgICAvLyBVc2UgdGhpcyBpZiB5b3UgbmVlZCB0byBpbnRlcmFjdCB3aXRoIEpRSFRNTCBjb21wb25lbnRzXG4gICAgLy8gICAgIC8vIE90aGVyd2lzZSwgdXNlIG9uX2FwcF9yZWFkeSgpIGZvciBtb3N0IGluaXRpYWxpemF0aW9uXG4gICAgLy8gfVxufSIsImNsYXNzIEZyb250ZW5kX1JlcG9ydHNfVGltZSB7XG4gICAgc3RhdGljIGluaXQoKSB7XG4gICAgICAgIGlmICghJChcIi5Gcm9udGVuZF9SZXBvcnRzX1RpbWVcIikuZXhpc3RzKCkpIHJldHVybjtcblxuICAgICAgICAvLyBJbml0aWFsaXplIHlvdXIgY29tcG9uZW50IGhlcmVcbiAgICAgICAgY29uc29sZS5sb2coJ0Zyb250ZW5kX1JlcG9ydHNfVGltZSBpbml0aWFsaXplZCcpO1xuXG4gICAgICAgIC8vIEV4YW1wbGU6IEhhbmRsZSBidXR0b24gY2xpY2tzXG4gICAgICAgICQoJy5idG4tYWN0aW9uJykub24oJ2NsaWNrJywgZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICAvLyBIYW5kbGUgYWN0aW9uXG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIEV4YW1wbGU6IEluaXRpYWxpemUgdG9vbHRpcHNcbiAgICAgICAgJCgnW2RhdGEtYnMtdG9nZ2xlPVwidG9vbHRpcFwiXScpLnRvb2x0aXAoKTtcbiAgICB9XG5cbiAgICBzdGF0aWMgb25fYXBwX3JlYWR5KCkge1xuICAgICAgICBGcm9udGVuZF9SZXBvcnRzX1RpbWUuaW5pdCgpO1xuICAgIH1cblxuICAgIC8vIHN0YXRpYyBvbl9qcWh0bWxfcmVhZHkoKSB7XG4gICAgLy8gICAgIC8vIENhbGxlZCBhZnRlciBhbGwgSlFIVE1MIGNvbXBvbmVudHMgaGF2ZSBsb2FkZWQgYW5kIHJlbmRlcmVkXG4gICAgLy8gICAgIC8vIFVzZSB0aGlzIGlmIHlvdSBuZWVkIHRvIGludGVyYWN0IHdpdGggSlFIVE1MIGNvbXBvbmVudHNcbiAgICAvLyAgICAgLy8gT3RoZXJ3aXNlLCB1c2Ugb25fYXBwX3JlYWR5KCkgZm9yIG1vc3QgaW5pdGlhbGl6YXRpb25cbiAgICAvLyB9XG59IiwiLyoqXG4gKiBKYXZhU2NyaXB0IGZvciBGcm9udGVuZF9BY2NvdW50IHZpZXdcbiAqL1xuY2xhc3MgRnJvbnRlbmRfQWNjb3VudCB7XG4gICAgLyoqXG4gICAgICogSW5pdGlhbGl6ZSB0aGUgdmlldyB3aGVuIGFwcCBpcyByZWFkeVxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGF1dG9tYXRpY2FsbHkgY2FsbGVkIGJ5IFJTWCBmcmFtZXdvcmtcbiAgICAgKiBObyBtYW51YWwgcmVnaXN0cmF0aW9uIGlzIHJlcXVpcmVkXG4gICAgICovXG4gICAgc3RhdGljIG9uX2FwcF9yZWFkeSgpIHtcbiAgICAgICAgLy8gQ2hlY2sgaWYgd2UncmUgb24gdGhpcyBzcGVjaWZpYyBwYWdlXG4gICAgICAgIGlmICghJChcIi5Gcm9udGVuZF9BY2NvdW50XCIpLmV4aXN0cygpKSByZXR1cm47XG5cbiAgICAgICAgLy8gVmlldy1zcGVjaWZpYyBpbml0aWFsaXphdGlvblxuICAgICAgICBjb25zb2xlLmxvZygnRnJvbnRlbmRfQWNjb3VudCBpbml0aWFsaXplZCcpO1xuICAgIH1cbn0iLCI8IS0tXG5Db250YWN0c19EYXRhR3JpZFxuXG5DdXN0b20gZGF0YWdyaWQgZm9yIGNvbnRhY3RzIHdpdGggc3BlY2lhbGl6ZWQgcm93IHJlbmRlcmluZy5cbldyYXBzIGJhc2UgRGF0YUdyaWQgY29tcG9uZW50LlxuXG5BUkdVTUVOVFM6XG4gICAgJGFwaSAtIEFQSSBjb250cm9sbGVyIGNsYXNzXG4tLT5cbjxEZWZpbmU6RGF0YUdyaWRfQWJzdHJhY3QgY2xhc3M9XCJjYXJkIERhdGFHcmlkXCI+XG5cbiAgICA8Q2FyZF9IZWFkZXI+XG4gICAgICAgIDwlPSBjb250ZW50KCdER19DYXJkX0hlYWRlcicpOyAlPlxuICAgIDwvQ2FyZF9IZWFkZXI+XG5cbiAgICA8ZGl2IGNsYXNzPVwiY2FyZC1ib2R5IHAtMFwiPlxuICAgICAgICA8ZGl2IGNsYXNzPVwidGFibGUtcmVzcG9uc2l2ZVwiPlxuICAgICAgICAgICAgPHRhYmxlIGNsYXNzPVwidGFibGUgdGFibGUtaG92ZXIgbWItMFwiPlxuICAgICAgICAgICAgICAgIDx0aGVhZCAkcmVkcmF3YWJsZSAkaWQ9XCJkYXRhZ3JpZF90YWJsZV9oZWFkZXJcIj5cbiAgICAgICAgICAgICAgICAgICAgPCU9IGNvbnRlbnQoJ0RHX1RhYmxlX0hlYWRlcicpOyAlPlxuICAgICAgICAgICAgICAgIDwvdGhlYWQ+XG4gICAgICAgICAgICAgICAgPHRib2R5ICRyZWRyYXdhYmxlICRpZD1cImRhdGFncmlkX3RhYmxlX2JvZHlcIiBjbGFzcz1cIjwlPSAodGhpcy5kYXRhLmxvYWRpbmcgJiYgdGhpcy5kYXRhLnJvd3MubGVuZ3RoID09PSAwKSA/ICdpcy1sb2FkaW5nJyA6ICh0aGlzLmRhdGEuaXNfZW1wdHkgPyAnaXMtZW1wdHknIDogJycpICU+XCI+XG4gICAgICAgICAgICAgICAgICAgIDwlIGlmICh0aGlzLmRhdGEubG9hZGluZyAmJiB0aGlzLmRhdGEucm93cy5sZW5ndGggPT09IDApIHsgJT5cbiAgICAgICAgICAgICAgICAgICAgICAgIDx0ciBjbGFzcz1cImxvYWRpbmctcm93XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRkIGNvbHNwYW49XCI5OTlcIiBjbGFzcz1cInRleHQtY2VudGVyIHB5LTVcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNwaW5uZXItYm9yZGVyIHRleHQtcHJpbWFyeSBtYi0zXCIgcm9sZT1cInN0YXR1c1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJ2aXN1YWxseS1oaWRkZW5cIj5Mb2FkaW5nLi4uPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHAgY2xhc3M9XCJ0ZXh0LW11dGVkXCI+TG9hZGluZy4uLjwvcD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC90cj5cbiAgICAgICAgICAgICAgICAgICAgPCUgfSBlbHNlIGlmICh0aGlzLmRhdGEuaXNfZW1wdHkpIHsgJT5cbiAgICAgICAgICAgICAgICAgICAgICAgIDx0ciBjbGFzcz1cImVtcHR5LXJvd1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0ZCBjb2xzcGFuPVwiOTk5XCIgY2xhc3M9XCJ0ZXh0LWNlbnRlciBweS01XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpIGNsYXNzPVwiYmkgYmktaW5ib3hcIiBzdHlsZT1cImZvbnQtc2l6ZTogM3JlbTsgY29sb3I6ICM2Yzc1N2Q7XCI+PC9pPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8JSBpZiAodGhpcy5kYXRhLmZpbHRlcikgeyAlPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHAgY2xhc3M9XCJ0ZXh0LW11dGVkIG10LTNcIj5ObyByZXN1bHRzIGZvdW5kIGZvciBcIjwlPSB0aGlzLmRhdGEuZmlsdGVyICU+XCI8L3A+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uICRpZD1cImNsZWFyX2ZpbHRlcl9idG5cIiBjbGFzcz1cImJ0biBidG4tc20gYnRuLXNlY29uZGFyeSBtdC0yXCI+Q2xlYXIgRmlsdGVyPC9idXR0b24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwlIH0gZWxzZSB7ICU+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cCBjbGFzcz1cInRleHQtbXV0ZWQgbXQtM1wiPk5vIHJlc3VsdHMgZm91bmQ8L3A+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwlIH0gJT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC90cj5cbiAgICAgICAgICAgICAgICAgICAgPCUgfSBlbHNlIHsgJT5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwlIGZvcihsZXQgcm93IG9mIHRoaXMuZGF0YS5yb3dzKSB7ICU+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPCU9IGNvbnRlbnQoJ3JvdycsIHJvdyk7ICU+XG4gICAgICAgICAgICAgICAgICAgICAgICA8JSB9ICU+XG4gICAgICAgICAgICAgICAgICAgIDwlIH0gJT5cbiAgICAgICAgICAgICAgICA8L3Rib2R5PlxuICAgICAgICAgICAgPC90YWJsZT5cbiAgICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG5cbiAgICA8Q2FyZF9Gb290ZXI+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJkLWZsZXggZ2FwLTIgYWxpZ24taXRlbXMtY2VudGVyXCI+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZHJvcGRvd25cIj5cbiAgICAgICAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwiYnRuIGJ0bi1zZWNvbmRhcnkgYnRuLXNtIGRyb3Bkb3duLXRvZ2dsZVwiIHR5cGU9XCJidXR0b25cIiBkYXRhLWJzLXRvZ2dsZT1cImRyb3Bkb3duXCI+XG4gICAgICAgICAgICAgICAgICAgIEFjdGlvbnNcbiAgICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICA8dWwgY2xhc3M9XCJkcm9wZG93bi1tZW51XCI+XG4gICAgICAgICAgICAgICAgICAgIDxsaT48YSBjbGFzcz1cImRyb3Bkb3duLWl0ZW1cIiBocmVmPVwiI1wiPkV4cG9ydCBTZWxlY3RlZDwvYT48L2xpPlxuICAgICAgICAgICAgICAgICAgICA8bGk+PGEgY2xhc3M9XCJkcm9wZG93bi1pdGVtXCIgaHJlZj1cIiNcIj5EZWxldGUgU2VsZWN0ZWQ8L2E+PC9saT5cbiAgICAgICAgICAgICAgICAgICAgPGxpPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGhyIGNsYXNzPVwiZHJvcGRvd24tZGl2aWRlclwiPlxuICAgICAgICAgICAgICAgICAgICA8L2xpPlxuICAgICAgICAgICAgICAgICAgICA8bGk+PGEgY2xhc3M9XCJkcm9wZG93bi1pdGVtXCIgaHJlZj1cIiNcIj5NYXJrIGFzIEFjdGl2ZTwvYT48L2xpPlxuICAgICAgICAgICAgICAgIDwvdWw+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDxQYWdpbmF0aW9uX0luZm8gJGlkPVwicGFnaW5hdGlvbl9pbmZvXCI+XG4gICAgICAgICAgICAgICAgPCUgaWYgKHRoaXMuZGF0YS50b3RhbCAmJiB0aGlzLmRhdGEucGFnZSAmJiB0aGlzLmRhdGEucGVyX3BhZ2UpIHsgJT5cbiAgICAgICAgICAgICAgICAgICAgPCVcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHN0YXJ0ID0gKCh0aGlzLmRhdGEucGFnZSAtIDEpICogdGhpcy5kYXRhLnBlcl9wYWdlKSArIDE7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBlbmQgPSBNYXRoLm1pbih0aGlzLmRhdGEucGFnZSAqIHRoaXMuZGF0YS5wZXJfcGFnZSwgdGhpcy5kYXRhLnRvdGFsKTtcbiAgICAgICAgICAgICAgICAgICAgJT5cbiAgICAgICAgICAgICAgICAgICAgU2hvd2luZyA8JT0gc3RhcnQgJT4gdG8gPCU9IGVuZCAlPiBvZiA8JT0gdGhpcy5kYXRhLnRvdGFsICU+IGVudHJpZXNcbiAgICAgICAgICAgICAgICA8JSB9ICU+XG4gICAgICAgICAgICA8L1BhZ2luYXRpb25fSW5mbz5cbiAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgPFBhZ2luYXRpb25fQ29udHJvbHMgJGlkPVwicGFnaW5hdGlvbl9jb250cm9sc1wiPlxuICAgICAgICAgICAgPCUgaWYgKHRoaXMuZGF0YS50b3RhbF9wYWdlcyAmJiB0aGlzLmRhdGEudG90YWxfcGFnZXMgPiAxKSB7ICU+XG4gICAgICAgICAgICAgICAgPCVcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgY3VycmVudFBhZ2UgPSB0aGlzLmRhdGEucGFnZSB8fCAxO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCB0b3RhbFBhZ2VzID0gdGhpcy5kYXRhLnRvdGFsX3BhZ2VzO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBtYXhWaXNpYmxlID0gNzsgLy8gTWF4aW11bSBwYWdlIG51bWJlcnMgdG8gc2hvd1xuXG4gICAgICAgICAgICAgICAgICAgIC8vIENhbGN1bGF0ZSBwYWdlIHJhbmdlIHRvIGRpc3BsYXlcbiAgICAgICAgICAgICAgICAgICAgbGV0IHN0YXJ0UGFnZSwgZW5kUGFnZTtcblxuICAgICAgICAgICAgICAgICAgICBpZiAodG90YWxQYWdlcyA8PSBtYXhWaXNpYmxlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBTaG93IGFsbCBwYWdlcyBpZiB0b3RhbCBpcyBsZXNzIHRoYW4gbWF4XG4gICAgICAgICAgICAgICAgICAgICAgICBzdGFydFBhZ2UgPSAxO1xuICAgICAgICAgICAgICAgICAgICAgICAgZW5kUGFnZSA9IHRvdGFsUGFnZXM7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBDYWxjdWxhdGUgcmFuZ2Ugd2l0aCBjdXJyZW50IHBhZ2UgbmVhciBjZW50ZXJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG1heFBhZ2VzQmVmb3JlQ3VycmVudFBhZ2UgPSBNYXRoLmZsb29yKG1heFZpc2libGUgLyAyKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG1heFBhZ2VzQWZ0ZXJDdXJyZW50UGFnZSA9IE1hdGguY2VpbChtYXhWaXNpYmxlIC8gMikgLSAxO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoY3VycmVudFBhZ2UgPD0gbWF4UGFnZXNCZWZvcmVDdXJyZW50UGFnZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE5lYXIgdGhlIHN0YXJ0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhcnRQYWdlID0gMTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbmRQYWdlID0gbWF4VmlzaWJsZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoY3VycmVudFBhZ2UgKyBtYXhQYWdlc0FmdGVyQ3VycmVudFBhZ2UgPj0gdG90YWxQYWdlcykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE5lYXIgdGhlIGVuZFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXJ0UGFnZSA9IHRvdGFsUGFnZXMgLSBtYXhWaXNpYmxlICsgMTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbmRQYWdlID0gdG90YWxQYWdlcztcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gSW4gdGhlIG1pZGRsZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXJ0UGFnZSA9IGN1cnJlbnRQYWdlIC0gbWF4UGFnZXNCZWZvcmVDdXJyZW50UGFnZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbmRQYWdlID0gY3VycmVudFBhZ2UgKyBtYXhQYWdlc0FmdGVyQ3VycmVudFBhZ2U7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAvLyBHZW5lcmF0ZSBwYWdlIG51bWJlcnMgYXJyYXlcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcGFnZXMgPSBbXTtcbiAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IHN0YXJ0UGFnZTsgaSA8PSBlbmRQYWdlOyBpKyspIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHBhZ2VzLnB1c2goaSk7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICBjb25zdCBzaG93U3RhcnRFbGxpcHNpcyA9IHN0YXJ0UGFnZSA+IDE7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHNob3dFbmRFbGxpcHNpcyA9IGVuZFBhZ2UgPCB0b3RhbFBhZ2VzO1xuICAgICAgICAgICAgICAgICU+XG5cbiAgICAgICAgICAgICAgICA8JS0tIFByZXZpb3VzIGJ1dHRvbiAtLSU+XG4gICAgICAgICAgICAgICAgPGxpIGNsYXNzPVwicGFnZS1pdGVtIDwlPSBjdXJyZW50UGFnZSA9PT0gMSA/ICdkaXNhYmxlZCcgOiAnJyAlPlwiPlxuICAgICAgICAgICAgICAgICAgICA8YSBjbGFzcz1cInBhZ2UtbGlua1wiIGhyZWY9XCIjXCIgZGF0YS1wYWdlPVwiPCU9IGN1cnJlbnRQYWdlIC0gMSAlPlwiIHRhYmluZGV4PVwiPCU9IGN1cnJlbnRQYWdlID09PSAxID8gJy0xJyA6ICcwJyAlPlwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgUHJldmlvdXNcbiAgICAgICAgICAgICAgICAgICAgPC9hPlxuICAgICAgICAgICAgICAgIDwvbGk+XG5cbiAgICAgICAgICAgICAgICA8JS0tIEZpcnN0IHBhZ2UgKyBlbGxpcHNpcyAtLSU+XG4gICAgICAgICAgICAgICAgPCUgaWYgKHNob3dTdGFydEVsbGlwc2lzKSB7ICU+XG4gICAgICAgICAgICAgICAgICAgIDxsaSBjbGFzcz1cInBhZ2UtaXRlbVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGEgY2xhc3M9XCJwYWdlLWxpbmtcIiBocmVmPVwiI1wiIGRhdGEtcGFnZT1cIjFcIj4xPC9hPlxuICAgICAgICAgICAgICAgICAgICA8L2xpPlxuICAgICAgICAgICAgICAgICAgICA8bGkgY2xhc3M9XCJwYWdlLWl0ZW0gZGlzYWJsZWRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwicGFnZS1saW5rXCI+Li4uPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICA8L2xpPlxuICAgICAgICAgICAgICAgIDwlIH0gJT5cblxuICAgICAgICAgICAgICAgIDwlLS0gUGFnZSBudW1iZXJzIC0tJT5cbiAgICAgICAgICAgICAgICA8JSBmb3IgKGxldCBwYWdlTnVtIG9mIHBhZ2VzKSB7ICU+XG4gICAgICAgICAgICAgICAgICAgIDwlIGNvbnNvbGUubG9nKFwiTG9vcCBjaGVja1wiLCBwYWdlTnVtLCBjdXJyZW50UGFnZSk7ICU+XG4gICAgICAgICAgICAgICAgICAgIDxsaSBjbGFzcz1cInBhZ2UtaXRlbSA8JT0gcGFnZU51bSA9PT0gY3VycmVudFBhZ2UgPyAnYWN0aXZlJyA6ICcnICU+XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8YSBjbGFzcz1cInBhZ2UtbGlua1wiIGhyZWY9XCIjXCIgZGF0YS1wYWdlPVwiPCU9IHBhZ2VOdW0gJT5cIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8JT0gcGFnZU51bSAlPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9hPlxuICAgICAgICAgICAgICAgICAgICA8L2xpPlxuICAgICAgICAgICAgICAgIDwlIH0gJT5cblxuICAgICAgICAgICAgICAgIDwlLS0gRWxsaXBzaXMgKyBsYXN0IHBhZ2UgLS0lPlxuICAgICAgICAgICAgICAgIDwlIGlmIChzaG93RW5kRWxsaXBzaXMpIHsgJT5cbiAgICAgICAgICAgICAgICAgICAgPGxpIGNsYXNzPVwicGFnZS1pdGVtIGRpc2FibGVkXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInBhZ2UtbGlua1wiPi4uLjwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgPC9saT5cbiAgICAgICAgICAgICAgICAgICAgPGxpIGNsYXNzPVwicGFnZS1pdGVtXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8YSBjbGFzcz1cInBhZ2UtbGlua1wiIGhyZWY9XCIjXCIgZGF0YS1wYWdlPVwiPCU9IHRvdGFsUGFnZXMgJT5cIj48JT0gdG90YWxQYWdlcyAlPjwvYT5cbiAgICAgICAgICAgICAgICAgICAgPC9saT5cbiAgICAgICAgICAgICAgICA8JSB9ICU+XG5cbiAgICAgICAgICAgICAgICA8JS0tIE5leHQgYnV0dG9uIC0tJT5cbiAgICAgICAgICAgICAgICA8bGkgY2xhc3M9XCJwYWdlLWl0ZW0gPCU9IGN1cnJlbnRQYWdlID09PSB0b3RhbFBhZ2VzID8gJ2Rpc2FibGVkJyA6ICcnICU+XCI+XG4gICAgICAgICAgICAgICAgICAgIDxhIGNsYXNzPVwicGFnZS1saW5rXCIgaHJlZj1cIiNcIiBkYXRhLXBhZ2U9XCI8JT0gY3VycmVudFBhZ2UgKyAxICU+XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICBOZXh0XG4gICAgICAgICAgICAgICAgICAgIDwvYT5cbiAgICAgICAgICAgICAgICA8L2xpPlxuICAgICAgICAgICAgPCUgfSAlPlxuICAgICAgICA8L1BhZ2luYXRpb25fQ29udHJvbHM+XG4gICAgPC9DYXJkX0Zvb3Rlcj5cblxuPC9EZWZpbmU6RGF0YUdyaWRfQWJzdHJhY3Q+IiwiPERlZmluZTpBY3Rpb25fQnV0dG9uX0RlbGV0ZSB0YWc9XCJidXR0b25cIiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJidG4gYnRuLWRhbmdlclwiIHRpdGxlPVwiRGVsZXRlXCI+XG4gIDxpIGNsYXNzPVwiYmkgYmktdHJhc2hcIj48L2k+XG48L0RlZmluZTpBY3Rpb25fQnV0dG9uX0RlbGV0ZT5cbiIsIjxEZWZpbmU6QWN0aW9uX0J1dHRvbl9FZGl0IHRhZz1cImFcIiBjbGFzcz1cImJ0biBidG4tc2Vjb25kYXJ5XCIgdGl0bGU9XCJFZGl0XCI+XG4gIDxpIGNsYXNzPVwiYmkgYmktcGVuY2lsXCI+PC9pPlxuPC9EZWZpbmU6QWN0aW9uX0J1dHRvbl9FZGl0PlxuIiwiPERlZmluZTpBY3Rpb25fQnV0dG9uX1ZpZXcgdGFnPVwiYVwiIGNsYXNzPVwiYnRuIGJ0bi1wcmltYXJ5XCIgdGl0bGU9XCJWaWV3XCI+XG4gIDxpIGNsYXNzPVwiYmkgYmktZXllXCI+PC9pPlxuPC9EZWZpbmU6QWN0aW9uX0J1dHRvbl9WaWV3PlxuIiwiPERlZmluZTpBY3Rpdml0eV9GZWVkIGNsYXNzPVwibGlzdC1ncm91cCBsaXN0LWdyb3VwLWZsdXNoXCI+XG4gIDwlIGlmIChPYmplY3Qua2V5cyh0aGlzLmRhdGEpLmxlbmd0aCA9PT0gMCkgeyAlPlxuICAgIDxkaXYgY2xhc3M9XCJ0ZXh0LWNlbnRlciBweS00XCI+XG4gICAgICA8U3Bpbm5lciAvPlxuICAgICAgPGRpdiBjbGFzcz1cIm10LTIgdGV4dC1tdXRlZCBzbWFsbFwiPkxvYWRpbmcgYWN0aXZpdHkuLi48L2Rpdj5cbiAgICA8L2Rpdj5cbiAgPCUgfSBlbHNlIGlmICh0aGlzLmRhdGEuYWN0aXZpdGllcyAmJiB0aGlzLmRhdGEuYWN0aXZpdGllcy5sZW5ndGggPT09IDApIHsgJT5cbiAgICA8RW1wdHlfU3RhdGVcbiAgICAgICRpY29uPVwiYWN0aXZpdHlcIlxuICAgICAgJHRpdGxlPVwiTm8gYWN0aXZpdHkgeWV0XCJcbiAgICAgICRtZXNzYWdlPVwiQWN0aXZpdHkgd2lsbCBhcHBlYXIgaGVyZVwiXG4gICAgLz5cbiAgPCUgfSBlbHNlIHsgJT5cbiAgICA8JSBmb3IgKGxldCBhY3Rpdml0eSBvZiB0aGlzLmRhdGEuYWN0aXZpdGllcyB8fCBbXSkgeyAlPlxuICAgICAgPGRpdiBjbGFzcz1cImxpc3QtZ3JvdXAtaXRlbSBkLWZsZXggZ2FwLTMgcHktM1wiPlxuICAgICAgICA8JSBpZiAoYWN0aXZpdHkuYXZhdGFyKSB7ICU+XG4gICAgICAgICAgPEF2YXRhciAkc3JjPWFjdGl2aXR5LmF2YXRhciAkc2l6ZT1cInNtXCIgLz5cbiAgICAgICAgPCUgfSBlbHNlIHsgJT5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwicm91bmRlZC1jaXJjbGUgYmctcHJpbWFyeSB0ZXh0LXdoaXRlIGQtZmxleCBhbGlnbi1pdGVtcy1jZW50ZXIganVzdGlmeS1jb250ZW50LWNlbnRlclwiIHN0eWxlPVwid2lkdGg6IDMycHg7IGhlaWdodDogMzJweDsgZmxleC1zaHJpbms6IDA7XCI+XG4gICAgICAgICAgICA8aSBjbGFzcz1cImJpIGJpLTwlPSBhY3Rpdml0eS5pY29uIHx8ICdhY3Rpdml0eScgJT5cIj48L2k+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwlIH0gJT5cbiAgICAgICAgPGRpdiBjbGFzcz1cImZsZXgtZ3Jvdy0xXCI+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cImQtZmxleCBqdXN0aWZ5LWNvbnRlbnQtYmV0d2VlbiBhbGlnbi1pdGVtcy1zdGFydFwiPlxuICAgICAgICAgICAgPGRpdj5cbiAgICAgICAgICAgICAgPHN0cm9uZz48JT0gYWN0aXZpdHkudXNlcl9uYW1lICU+PC9zdHJvbmc+XG4gICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwidGV4dC1tdXRlZFwiPjwlPSBhY3Rpdml0eS5hY3Rpb24gJT48L3NwYW4+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDxzbWFsbCBjbGFzcz1cInRleHQtbXV0ZWRcIj48JT0gYWN0aXZpdHkudGltZV9hZ28gJT48L3NtYWxsPlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwlIGlmIChhY3Rpdml0eS5kZXNjcmlwdGlvbikgeyAlPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cInRleHQtbXV0ZWQgc21hbGwgbXQtMVwiPjwlPSBhY3Rpdml0eS5kZXNjcmlwdGlvbiAlPjwvZGl2PlxuICAgICAgICAgIDwlIH0gJT5cbiAgICAgICAgICA8JSBpZiAoYWN0aXZpdHkubWV0YWRhdGEpIHsgJT5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtdC0yXCI+XG4gICAgICAgICAgICAgIDwlIGZvciAobGV0IGtleSBpbiBhY3Rpdml0eS5tZXRhZGF0YSkgeyAlPlxuICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiYmFkZ2UgYmctbGlnaHQgdGV4dC1kYXJrIG1lLTFcIj5cbiAgICAgICAgICAgICAgICAgIDwlPSBrZXkgJT46IDwlPSBhY3Rpdml0eS5tZXRhZGF0YVtrZXldICU+XG4gICAgICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgICAgICA8JSB9ICU+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8JSB9ICU+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG4gICAgPCUgfSAlPlxuICA8JSB9ICU+XG48L0RlZmluZTpBY3Rpdml0eV9GZWVkPlxuIiwiPERlZmluZTpBY3Rvcl9SZWZlcmVuY2UgdGFnPVwic21hbGxcIiBjbGFzcz1cInRleHQtbXV0ZWQgZC1ibG9jayBtdC0xXCI+XG4gIDwlPSBjb250ZW50KCkgJT5cbjwvRGVmaW5lOkFjdG9yX1JlZmVyZW5jZT5cbiIsIjxEZWZpbmU6QWR2YW5jZWRfU2VhcmNoX1BhbmVsIGNsYXNzPVwiY2FyZFwiPlxuICA8ZGl2IGNsYXNzPVwiY2FyZC1oZWFkZXIgZC1mbGV4IGp1c3RpZnktY29udGVudC1iZXR3ZWVuIGFsaWduLWl0ZW1zLWNlbnRlclwiPlxuICAgIDxoNSBjbGFzcz1cIm1iLTBcIj5BZHZhbmNlZCBTZWFyY2g8L2g1PlxuICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwiYnRuLWNsb3NlXCIgJGlkPVwiY2xvc2VfYnRuXCI+PC9idXR0b24+XG4gIDwvZGl2PlxuICA8ZGl2IGNsYXNzPVwiY2FyZC1ib2R5XCI+XG4gICAgPGZvcm0gJGlkPVwic2VhcmNoX2Zvcm1cIj5cbiAgICAgIDxkaXYgY2xhc3M9XCJyb3cgZy0zXCI+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJjb2wtMTJcIj5cbiAgICAgICAgICA8SW5wdXRfV2l0aF9WYWxpZGF0aW9uXG4gICAgICAgICAgICAkbGFiZWw9XCJLZXl3b3Jkc1wiXG4gICAgICAgICAgICAkcGxhY2Vob2xkZXI9XCJTZWFyY2gga2V5d29yZHMuLi5cIlxuICAgICAgICAgICAgJG5hbWU9XCJrZXl3b3Jkc1wiXG4gICAgICAgICAgICAkaWQ9XCJrZXl3b3Jkc1wiXG4gICAgICAgICAgLz5cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJjb2wtbWQtNlwiPlxuICAgICAgICAgIDxTZWFyY2hhYmxlX1NlbGVjdFxuICAgICAgICAgICAgJGxhYmVsPVwiQ2F0ZWdvcnlcIlxuICAgICAgICAgICAgJHBsYWNlaG9sZGVyPVwiU2VsZWN0IGNhdGVnb3J5XCJcbiAgICAgICAgICAgICRpZD1cImNhdGVnb3J5XCJcbiAgICAgICAgICAvPlxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgPGRpdiBjbGFzcz1cImNvbC1tZC02XCI+XG4gICAgICAgICAgPE11bHRpX1NlbGVjdFxuICAgICAgICAgICAgJGxhYmVsPVwiVGFnc1wiXG4gICAgICAgICAgICAkcGxhY2Vob2xkZXI9XCJTZWxlY3QgdGFnc1wiXG4gICAgICAgICAgICAkaWQ9XCJ0YWdzXCJcbiAgICAgICAgICAvPlxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgPGRpdiBjbGFzcz1cImNvbC1tZC02XCI+XG4gICAgICAgICAgPERhdGVfUGlja2VyXG4gICAgICAgICAgICAkbGFiZWw9XCJGcm9tIERhdGVcIlxuICAgICAgICAgICAgJGlkPVwiZnJvbV9kYXRlXCJcbiAgICAgICAgICAvPlxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgPGRpdiBjbGFzcz1cImNvbC1tZC02XCI+XG4gICAgICAgICAgPERhdGVfUGlja2VyXG4gICAgICAgICAgICAkbGFiZWw9XCJUbyBEYXRlXCJcbiAgICAgICAgICAgICRpZD1cInRvX2RhdGVcIlxuICAgICAgICAgIC8+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICA8ZGl2IGNsYXNzPVwiY29sLTEyXCI+XG4gICAgICAgICAgPGxhYmVsIGNsYXNzPVwiZm9ybS1sYWJlbFwiPlNvcnQgQnk8L2xhYmVsPlxuICAgICAgICAgIDxzZWxlY3QgY2xhc3M9XCJmb3JtLXNlbGVjdFwiICRpZD1cInNvcnRfYnlcIj5cbiAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCJyZWxldmFuY2VcIj5SZWxldmFuY2U8L29wdGlvbj5cbiAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCJkYXRlXCI+RGF0ZTwvb3B0aW9uPlxuICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT1cInRpdGxlXCI+VGl0bGU8L29wdGlvbj5cbiAgICAgICAgICA8L3NlbGVjdD5cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJjb2wtMTJcIj5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwiZm9ybS1jaGVja1wiPlxuICAgICAgICAgICAgPGlucHV0IGNsYXNzPVwiZm9ybS1jaGVjay1pbnB1dFwiIHR5cGU9XCJjaGVja2JveFwiICRpZD1cImV4YWN0X21hdGNoXCI+XG4gICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJmb3JtLWNoZWNrLWxhYmVsXCI+XG4gICAgICAgICAgICAgIEV4YWN0IG1hdGNoIG9ubHlcbiAgICAgICAgICAgIDwvbGFiZWw+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG4gICAgPC9mb3JtPlxuICA8L2Rpdj5cbiAgPGRpdiBjbGFzcz1cImNhcmQtZm9vdGVyIGQtZmxleCBqdXN0aWZ5LWNvbnRlbnQtYmV0d2VlblwiPlxuICAgIDxCdXR0b25fU2Vjb25kYXJ5ICRpZD1cInJlc2V0X2J0blwiPlJlc2V0PC9CdXR0b25fU2Vjb25kYXJ5PlxuICAgIDxCdXR0b25fUHJpbWFyeSAkaWQ9XCJzZWFyY2hfYnRuXCI+U2VhcmNoPC9CdXR0b25fUHJpbWFyeT5cbiAgPC9kaXY+XG48L0RlZmluZTpBZHZhbmNlZF9TZWFyY2hfUGFuZWw+XG4iLCI8RGVmaW5lOkFsZXJ0X0Jhbm5lciBjbGFzcz1cImFsZXJ0IGFsZXJ0LWluZm8gYWxlcnQtZGlzbWlzc2libGUgZmFkZSBzaG93XCIgcm9sZT1cImFsZXJ0XCI+XG4gIDwlPSBjb250ZW50KCkgJT5cbiAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJidG4tY2xvc2VcIiBkYXRhLWJzLWRpc21pc3M9XCJhbGVydFwiIGFyaWEtbGFiZWw9XCJDbG9zZVwiPjwvYnV0dG9uPlxuPC9EZWZpbmU6QWxlcnRfQmFubmVyPlxuIiwiPERlZmluZTpBdmF0YXIgdGFnPVwiaW1nXCIgY2xhc3M9XCJyb3VuZGVkLWNpcmNsZVwiIGFsdD1cIlVzZXIgYXZhdGFyXCI+XG48L0RlZmluZTpBdmF0YXI+XG4iLCI8RGVmaW5lOkJsb2NrcXVvdGUgdGFnPVwiYmxvY2txdW90ZVwiIGNsYXNzPVwiYmxvY2txdW90ZVwiPlxuICA8JT0gY29udGVudCgpICU+XG48L0RlZmluZTpCbG9ja3F1b3RlPlxuIiwiPERlZmluZTpCcmVhZGNydW1icyB0YWc9XCJuYXZcIiBhcmlhLWxhYmVsPVwiYnJlYWRjcnVtYlwiPlxuICA8b2wgY2xhc3M9XCJicmVhZGNydW1iIG1iLTBcIj5cbiAgICA8JT0gY29udGVudCgpICU+XG4gIDwvb2w+XG48L0RlZmluZTpCcmVhZGNydW1icz5cbiIsIjxEZWZpbmU6QnVsa19BY3Rpb25fQmFyIGNsYXNzPVwiYWxlcnQgYWxlcnQtcHJpbWFyeSBkLWZsZXgganVzdGlmeS1jb250ZW50LWJldHdlZW4gYWxpZ24taXRlbXMtY2VudGVyIG1iLTNcIiByb2xlPVwiYWxlcnRcIj5cbiAgPGRpdj5cbiAgICA8c3Ryb25nIGNsYXNzPVwiY291bnRcIj4wPC9zdHJvbmc+IGl0ZW1zIHNlbGVjdGVkXG4gIDwvZGl2PlxuICA8ZGl2IGNsYXNzPVwiZC1mbGV4IGdhcC0yXCI+XG4gICAgPCU9IGNvbnRlbnQoKSAlPlxuICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwiYnRuLWNsb3NlXCIgJGlkPVwiY2xvc2VfYnRuXCIgYXJpYS1sYWJlbD1cIkNsb3NlXCI+PC9idXR0b24+XG4gIDwvZGl2PlxuPC9EZWZpbmU6QnVsa19BY3Rpb25fQmFyPlxuIiwiPERlZmluZTpCdWxrX1NlbGVjdGlvbiBjbGFzcz1cImZvcm0tY2hlY2tcIj5cbiAgPGlucHV0IGNsYXNzPVwiZm9ybS1jaGVjay1pbnB1dFwiXG4gICAgICAgICB0eXBlPVwiY2hlY2tib3hcIlxuICAgICAgICAgJGlkPVwiY2hlY2tib3hcIlxuICAgICAgICAgYXJpYS1sYWJlbD1cIlNlbGVjdCBhbGxcIiAvPlxuPC9EZWZpbmU6QnVsa19TZWxlY3Rpb24+XG4iLCI8RGVmaW5lOkJ1dHRvbl9Hcm91cCBjbGFzcz1cImJ0bi1ncm91cFwiIHJvbGU9XCJncm91cFwiPlxuICA8JT0gY29udGVudCgpICU+XG48L0RlZmluZTpCdXR0b25fR3JvdXA+XG4iLCI8RGVmaW5lOkJ1dHRvbl9QcmltYXJ5IHRhZz1cImJ1dHRvblwiIGNsYXNzPVwiYnRuIGJ0bi1wcmltYXJ5XCIgdHlwZT1cImJ1dHRvblwiPlxuICA8JT0gY29udGVudCgpICU+XG48L0RlZmluZTpCdXR0b25fUHJpbWFyeT5cbiIsIjxEZWZpbmU6QnV0dG9uX1NlY29uZGFyeSB0YWc9XCJidXR0b25cIiBjbGFzcz1cImJ0biBidG4tc2Vjb25kYXJ5XCIgdHlwZT1cImJ1dHRvblwiPlxuICA8JT0gY29udGVudCgpICU+XG48L0RlZmluZTpCdXR0b25fU2Vjb25kYXJ5PlxuIiwiPERlZmluZTpCdXR0b24gdGFnPVwiYnV0dG9uXCIgY2xhc3M9XCJidG5cIiB0eXBlPVwiYnV0dG9uXCI+XG4gIDwlPSBjb250ZW50KCkgJT5cbjwvRGVmaW5lOkJ1dHRvbj5cbiIsIjxEZWZpbmU6Q2FsZW5kYXJfRXZlbnQgY2xhc3M9XCJjYXJkIG1iLTJcIiBzdHlsZT1cImN1cnNvcjogcG9pbnRlcjtcIj5cbiAgPGRpdiBjbGFzcz1cImNhcmQtYm9keSBwLTJcIj5cbiAgICA8ZGl2IGNsYXNzPVwiZC1mbGV4IGFsaWduLWl0ZW1zLXN0YXJ0IGdhcC0yXCI+XG4gICAgICA8ZGl2IGNsYXNzPVwiYmctPCU9IHRoaXMuYXJncy5jb2xvciB8fCAncHJpbWFyeScgJT4gcm91bmRlZFwiIHN0eWxlPVwid2lkdGg6IDRweDsgaGVpZ2h0OiAxMDAlOyBtaW4taGVpZ2h0OiA0MHB4O1wiPjwvZGl2PlxuICAgICAgPGRpdiBjbGFzcz1cImZsZXgtZ3Jvdy0xXCI+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJmdy1ib2xkIHNtYWxsXCI+PCU9IHRoaXMuYXJncy50aXRsZSAlPjwvZGl2PlxuICAgICAgICA8ZGl2IGNsYXNzPVwidGV4dC1tdXRlZCBzbWFsbFwiPlxuICAgICAgICAgIDxpIGNsYXNzPVwiYmkgYmktY2xvY2sgbWUtMVwiPjwvaT5cbiAgICAgICAgICA8JT0gdGhpcy5hcmdzLnRpbWUgJT5cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIDwlIGlmICh0aGlzLmFyZ3MubG9jYXRpb24pIHsgJT5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwidGV4dC1tdXRlZCBzbWFsbFwiPlxuICAgICAgICAgICAgPGkgY2xhc3M9XCJiaSBiaS1nZW8tYWx0IG1lLTFcIj48L2k+XG4gICAgICAgICAgICA8JT0gdGhpcy5hcmdzLmxvY2F0aW9uICU+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwlIH0gJT5cbiAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuICA8L2Rpdj5cbjwvRGVmaW5lOkNhbGVuZGFyX0V2ZW50PlxuIiwiPERlZmluZTpDYWxlbmRhcl9HcmlkIGNsYXNzPVwiY2FyZFwiPlxuICA8ZGl2IGNsYXNzPVwiY2FyZC1oZWFkZXIgZC1mbGV4IGp1c3RpZnktY29udGVudC1iZXR3ZWVuIGFsaWduLWl0ZW1zLWNlbnRlclwiPlxuICAgIDxkaXYgY2xhc3M9XCJidG4tZ3JvdXAgYnRuLWdyb3VwLXNtXCI+XG4gICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cImJ0biBidG4tc2Vjb25kYXJ5XCIgJGlkPVwicHJldl9idG5cIj5cbiAgICAgICAgPGkgY2xhc3M9XCJiaSBiaS1jaGV2cm9uLWxlZnRcIj48L2k+XG4gICAgICA8L2J1dHRvbj5cbiAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwiYnRuIGJ0bi1zZWNvbmRhcnlcIiAkaWQ9XCJ0b2RheV9idG5cIj5Ub2RheTwvYnV0dG9uPlxuICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJidG4gYnRuLXNlY29uZGFyeVwiICRpZD1cIm5leHRfYnRuXCI+XG4gICAgICAgIDxpIGNsYXNzPVwiYmkgYmktY2hldnJvbi1yaWdodFwiPjwvaT5cbiAgICAgIDwvYnV0dG9uPlxuICAgIDwvZGl2PlxuICAgIDxoNSBjbGFzcz1cIm1iLTBcIiAkaWQ9XCJtb250aF90aXRsZVwiPjwvaDU+XG4gICAgPGRpdiBjbGFzcz1cImJ0bi1ncm91cCBidG4tZ3JvdXAtc21cIj5cbiAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwiYnRuIGJ0bi1zZWNvbmRhcnlcIiBkYXRhLXZpZXc9XCJtb250aFwiPk1vbnRoPC9idXR0b24+XG4gICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cImJ0biBidG4tc2Vjb25kYXJ5XCIgZGF0YS12aWV3PVwid2Vla1wiPldlZWs8L2J1dHRvbj5cbiAgICA8L2Rpdj5cbiAgPC9kaXY+XG4gIDxkaXYgY2xhc3M9XCJjYXJkLWJvZHkgcC0wXCI+XG4gICAgPHRhYmxlIGNsYXNzPVwidGFibGUgdGFibGUtYm9yZGVyZWQgbWItMFwiPlxuICAgICAgPHRoZWFkIGNsYXNzPVwidGFibGUtbGlnaHRcIj5cbiAgICAgICAgPHRyPlxuICAgICAgICAgIDx0aCBjbGFzcz1cInRleHQtY2VudGVyXCI+U3VuPC90aD5cbiAgICAgICAgICA8dGggY2xhc3M9XCJ0ZXh0LWNlbnRlclwiPk1vbjwvdGg+XG4gICAgICAgICAgPHRoIGNsYXNzPVwidGV4dC1jZW50ZXJcIj5UdWU8L3RoPlxuICAgICAgICAgIDx0aCBjbGFzcz1cInRleHQtY2VudGVyXCI+V2VkPC90aD5cbiAgICAgICAgICA8dGggY2xhc3M9XCJ0ZXh0LWNlbnRlclwiPlRodTwvdGg+XG4gICAgICAgICAgPHRoIGNsYXNzPVwidGV4dC1jZW50ZXJcIj5Gcmk8L3RoPlxuICAgICAgICAgIDx0aCBjbGFzcz1cInRleHQtY2VudGVyXCI+U2F0PC90aD5cbiAgICAgICAgPC90cj5cbiAgICAgIDwvdGhlYWQ+XG4gICAgICA8dGJvZHkgJGlkPVwiY2FsZW5kYXJfYm9keVwiPlxuICAgICAgICA8IS0tIEdlbmVyYXRlZCB2aWEgSmF2YVNjcmlwdCAtLT5cbiAgICAgIDwvdGJvZHk+XG4gICAgPC90YWJsZT5cbiAgPC9kaXY+XG48L0RlZmluZTpDYWxlbmRhcl9HcmlkPlxuIiwiPERlZmluZTpDYXJkX0Zvb3RlciBjbGFzcz1cImNhcmQtZm9vdGVyIGJnLWxpZ2h0XCI+XG4gIDxkaXYgY2xhc3M9XCJkLWZsZXgganVzdGlmeS1jb250ZW50LWJldHdlZW4gYWxpZ24taXRlbXMtY2VudGVyXCI+XG4gICAgPCU9IGNvbnRlbnQoKSAlPlxuICA8L2Rpdj5cbjwvRGVmaW5lOkNhcmRfRm9vdGVyPlxuIiwiPERlZmluZTpDYXJkX0hlYWRlciBjbGFzcz1cImNhcmQtaGVhZGVyIGJnLWxpZ2h0XCI+XG4gIDxkaXYgY2xhc3M9XCJkLWZsZXgganVzdGlmeS1jb250ZW50LWJldHdlZW4gYWxpZ24taXRlbXMtY2VudGVyXCI+XG4gICAgPCU9IGNvbnRlbnQoKSAlPlxuICA8L2Rpdj5cbjwvRGVmaW5lOkNhcmRfSGVhZGVyPlxuIiwiPERlZmluZTpDYXJkX1RpdGxlIHRhZz1cImg1XCIgY2xhc3M9XCJtYi0wXCI+XG5cbiAgICA8JT0gY29udGVudCgpICU+XG5cbjwvRGVmaW5lOkNhcmRfVGl0bGU+IiwiPERlZmluZTpDYXJkIGNsYXNzPVwiY2FyZFwiPlxuXG4gICAgPGRpdiBjbGFzcz1cImNhcmQtYm9keVwiPlxuICAgICAgICA8JT0gY29udGVudCgpICU+XG4gICAgPC9kaXY+XG5cbjwvRGVmaW5lOkNhcmQ+XG4iLCI8RGVmaW5lOkNoYXJ0X0NvbXBvbmVudCBjbGFzcz1cImNoYXJ0LXBsYWNlaG9sZGVyIGJnLWxpZ2h0IHJvdW5kZWQgZC1mbGV4IGFsaWduLWl0ZW1zLWNlbnRlciBqdXN0aWZ5LWNvbnRlbnQtY2VudGVyXCI+XG4gIDxkaXYgY2xhc3M9XCJ0ZXh0LWNlbnRlciB0ZXh0LW11dGVkIHAtNVwiPlxuICAgIDxpIGNsYXNzPVwiYmkgYmktZ3JhcGgtdXAgZnMtMSBkLWJsb2NrIG1iLTJcIj48L2k+XG4gICAgPHAgY2xhc3M9XCJtYi0wXCI+Q2hhcnQgQ29tcG9uZW50PC9wPlxuICAgIDxzbWFsbD5QbGFjZWhvbGRlciBmb3IgZnV0dXJlIGNoYXJ0IGludGVncmF0aW9uPC9zbWFsbD5cbiAgPC9kaXY+XG48L0RlZmluZTpDaGFydF9Db21wb25lbnQ+XG4iLCI8RGVmaW5lOkNoZWNrYm94IHRhZz1cImlucHV0XCIgdHlwZT1cImNoZWNrYm94XCIgY2xhc3M9XCJmb3JtLWNoZWNrLWlucHV0XCI+XG48L0RlZmluZTpDaGVja2JveD5cbiIsIjxEZWZpbmU6Q29kZV9CbG9jayB0YWc9XCJwcmVcIiBjbGFzcz1cInAtMyBiZy1kYXJrIHRleHQtbGlnaHQgcm91bmRlZFwiPlxuICA8Y29kZT48JT0gY29udGVudCgpICU+PC9jb2RlPlxuPC9EZWZpbmU6Q29kZV9CbG9jaz5cbiIsIjxEZWZpbmU6Q29sdW1uX1Zpc2liaWxpdHlfVG9nZ2xlIGNsYXNzPVwiZHJvcGRvd25cIj5cbiAgPGJ1dHRvbiBjbGFzcz1cImJ0biBidG4tc2Vjb25kYXJ5IGJ0bi1zbSBkcm9wZG93bi10b2dnbGVcIiB0eXBlPVwiYnV0dG9uXCIgZGF0YS1icy10b2dnbGU9XCJkcm9wZG93blwiIGFyaWEtZXhwYW5kZWQ9XCJmYWxzZVwiPlxuICAgIDxpIGNsYXNzPVwiYmkgYmktY29sdW1uc1wiPjwvaT4gQ29sdW1uc1xuICA8L2J1dHRvbj5cbiAgPHVsIGNsYXNzPVwiZHJvcGRvd24tbWVudSBkcm9wZG93bi1tZW51LWVuZFwiICRpZD1cIm1lbnVcIj5cbiAgICA8IS0tIER5bmFtaWNhbGx5IHBvcHVsYXRlZCB2aWEgSmF2YVNjcmlwdCAtLT5cbiAgPC91bD5cbjwvRGVmaW5lOkNvbHVtbl9WaXNpYmlsaXR5X1RvZ2dsZT5cbiIsIjxEZWZpbmU6Q29tbWVudF9UaHJlYWQgY2xhc3M9XCJjYXJkXCI+XG4gIDxkaXYgY2xhc3M9XCJjYXJkLWhlYWRlciBkLWZsZXgganVzdGlmeS1jb250ZW50LWJldHdlZW4gYWxpZ24taXRlbXMtY2VudGVyXCI+XG4gICAgPGg1IGNsYXNzPVwibWItMFwiPkNvbW1lbnRzICg8c3BhbiAkaWQ9XCJjb21tZW50X2NvdW50XCI+PCU9ICh0aGlzLmRhdGEuY29tbWVudHMgfHwgW10pLmxlbmd0aCAlPjwvc3Bhbj4pPC9oNT5cbiAgPC9kaXY+XG4gIDxkaXYgY2xhc3M9XCJjYXJkLWJvZHlcIj5cbiAgICA8ZGl2ICRpZD1cImNvbW1lbnRzXCI+XG4gICAgICA8JSBpZiAoT2JqZWN0LmtleXModGhpcy5kYXRhKS5sZW5ndGggPT09IDApIHsgJT5cbiAgICAgICAgPGRpdiBjbGFzcz1cInRleHQtY2VudGVyIHB5LTRcIj5cbiAgICAgICAgICA8U3Bpbm5lciAvPlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwlIH0gZWxzZSBpZiAodGhpcy5kYXRhLmNvbW1lbnRzICYmIHRoaXMuZGF0YS5jb21tZW50cy5sZW5ndGggPT09IDApIHsgJT5cbiAgICAgICAgPEVtcHR5X1N0YXRlXG4gICAgICAgICAgJGljb249XCJjaGF0LWxlZnQtdGV4dFwiXG4gICAgICAgICAgJHRpdGxlPVwiTm8gY29tbWVudHMgeWV0XCJcbiAgICAgICAgICAkbWVzc2FnZT1cIkJlIHRoZSBmaXJzdCB0byBjb21tZW50XCJcbiAgICAgICAgLz5cbiAgICAgIDwlIH0gZWxzZSB7ICU+XG4gICAgICAgIDwlIGZvciAobGV0IGNvbW1lbnQgb2YgdGhpcy5kYXRhLmNvbW1lbnRzIHx8IFtdKSB7ICU+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cImQtZmxleCBnYXAtMyBtYi00XCIgZGF0YS1jb21tZW50LWlkPVwiPCU9IGNvbW1lbnQuaWQgJT5cIj5cbiAgICAgICAgICAgIDxBdmF0YXIgJHNyYz1jb21tZW50LmF2YXRhciAkbmFtZT1jb21tZW50LnVzZXJfbmFtZSAkc2l6ZT1cInNtXCIgLz5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4LWdyb3ctMVwiPlxuICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiYmctbGlnaHQgcm91bmRlZCBwLTNcIj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZC1mbGV4IGp1c3RpZnktY29udGVudC1iZXR3ZWVuIGFsaWduLWl0ZW1zLXN0YXJ0IG1iLTJcIj5cbiAgICAgICAgICAgICAgICAgIDxzdHJvbmc+PCU9IGNvbW1lbnQudXNlcl9uYW1lICU+PC9zdHJvbmc+XG4gICAgICAgICAgICAgICAgICA8c21hbGwgY2xhc3M9XCJ0ZXh0LW11dGVkXCI+PCU9IGNvbW1lbnQudGltZV9hZ28gJT48L3NtYWxsPlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDxkaXY+PCU9IGNvbW1lbnQudGV4dCAlPjwvZGl2PlxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm10LTJcIj5cbiAgICAgICAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwiYnRuIGJ0bi1saW5rIGJ0bi1zbSBwLTAgbWUtMyByZXBseS1idG5cIj5SZXBseTwvYnV0dG9uPlxuICAgICAgICAgICAgICAgIDwlIGlmIChjb21tZW50LmNhbl9lZGl0KSB7ICU+XG4gICAgICAgICAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwiYnRuIGJ0bi1saW5rIGJ0bi1zbSBwLTAgbWUtMyBlZGl0LWJ0blwiPkVkaXQ8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICA8JSB9ICU+XG4gICAgICAgICAgICAgICAgPCUgaWYgKGNvbW1lbnQuY2FuX2RlbGV0ZSkgeyAlPlxuICAgICAgICAgICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cImJ0biBidG4tbGluayBidG4tc20gcC0wIHRleHQtZGFuZ2VyIGRlbGV0ZS1idG5cIj5EZWxldGU8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICA8JSB9ICU+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICA8JSBpZiAoY29tbWVudC5yZXBsaWVzICYmIGNvbW1lbnQucmVwbGllcy5sZW5ndGggPiAwKSB7ICU+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1zLTQgbXQtM1wiPlxuICAgICAgICAgICAgICAgICAgPCUgZm9yIChsZXQgcmVwbHkgb2YgY29tbWVudC5yZXBsaWVzKSB7ICU+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkLWZsZXggZ2FwLTMgbWItM1wiIGRhdGEtY29tbWVudC1pZD1cIjwlPSByZXBseS5pZCAlPlwiPlxuICAgICAgICAgICAgICAgICAgICAgIDxBdmF0YXIgJHNyYz1yZXBseS5hdmF0YXIgJG5hbWU9cmVwbHkudXNlcl9uYW1lICRzaXplPVwieHNcIiAvPlxuICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbGV4LWdyb3ctMVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImJnLWxpZ2h0IHJvdW5kZWQgcC0yXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkLWZsZXgganVzdGlmeS1jb250ZW50LWJldHdlZW4gYWxpZ24taXRlbXMtc3RhcnQgbWItMVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzdHJvbmcgY2xhc3M9XCJzbWFsbFwiPjwlPSByZXBseS51c2VyX25hbWUgJT48L3N0cm9uZz5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c21hbGwgY2xhc3M9XCJ0ZXh0LW11dGVkXCI+PCU9IHJlcGx5LnRpbWVfYWdvICU+PC9zbWFsbD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzbWFsbFwiPjwlPSByZXBseS50ZXh0ICU+PC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICA8JSB9ICU+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgIDwlIH0gJT5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8JSB9ICU+XG4gICAgICA8JSB9ICU+XG4gICAgPC9kaXY+XG5cbiAgICA8IS0tIE5ldyBjb21tZW50IGZvcm0gLS0+XG4gICAgPGRpdiBjbGFzcz1cIm10LTQgcHQtNCBib3JkZXItdG9wXCIgJGlkPVwibmV3X2NvbW1lbnRfZm9ybVwiPlxuICAgICAgPGRpdiBjbGFzcz1cImQtZmxleCBnYXAtM1wiPlxuICAgICAgICA8QXZhdGFyICRzcmM9dGhpcy5hcmdzLmN1cnJlbnRfdXNlcl9hdmF0YXIgJG5hbWU9dGhpcy5hcmdzLmN1cnJlbnRfdXNlcl9uYW1lICRzaXplPVwic21cIiAvPlxuICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleC1ncm93LTFcIj5cbiAgICAgICAgICA8dGV4dGFyZWEgY2xhc3M9XCJmb3JtLWNvbnRyb2wgbWItMlwiIHJvd3M9XCIzXCIgcGxhY2Vob2xkZXI9XCJXcml0ZSBhIGNvbW1lbnQuLi5cIiAkaWQ9XCJjb21tZW50X2lucHV0XCI+PC90ZXh0YXJlYT5cbiAgICAgICAgICA8QnV0dG9uX1ByaW1hcnkgJGlkPVwic3VibWl0X2J0blwiPlBvc3QgQ29tbWVudDwvQnV0dG9uX1ByaW1hcnk+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG4gIDwvZGl2PlxuPC9EZWZpbmU6Q29tbWVudF9UaHJlYWQ+XG4iLCI8RGVmaW5lOkNvbnRhY3RfQWN0aW9ucyB0YWc9XCJ0ZFwiPlxuXG4gICAgPGRpdiBjbGFzcz1cImJ0bi1ncm91cCBidG4tZ3JvdXAtc21cIj5cbiAgICAgICAgPCU9IGNvbnRlbnQoKSAlPlxuICAgIDwvZGl2PlxuXG48L0RlZmluZTpDb250YWN0X0FjdGlvbnM+XG4iLCI8RGVmaW5lOkNvbnRhY3RfUm93IHRhZz1cInRyXCI+XG4gIDwlPSBjb250ZW50KCkgJT5cbjwvRGVmaW5lOkNvbnRhY3RfUm93PlxuIiwiPERlZmluZTpDb250YWN0c19EYXRhX1RhYmxlIHRhZz1cImRpdlwiIGNsYXNzPVwiY2FyZC1ib2R5IHAtMFwiPlxuICA8ZGl2IGNsYXNzPVwidGFibGUtcmVzcG9uc2l2ZVwiPlxuICAgIDx0YWJsZSBjbGFzcz1cInRhYmxlIHRhYmxlLWhvdmVyIG1iLTBcIj5cbiAgICAgIDx0aGVhZD5cbiAgICAgICAgPHRyPlxuICAgICAgICAgIDx0aCBzdHlsZT1cIndpZHRoOiA0MHB4O1wiPjxpbnB1dCBjbGFzcz1cImZvcm0tY2hlY2staW5wdXRcIiB0eXBlPVwiY2hlY2tib3hcIiAvPjwvdGg+XG4gICAgICAgICAgPHRoPklEPC90aD5cbiAgICAgICAgICA8dGg+TmFtZTwvdGg+XG4gICAgICAgICAgPHRoPkVtYWlsPC90aD5cbiAgICAgICAgICA8dGg+UGhvbmU8L3RoPlxuICAgICAgICAgIDx0aD5Db21wYW55PC90aD5cbiAgICAgICAgICA8dGg+Um9sZTwvdGg+XG4gICAgICAgICAgPHRoPlN0YXR1czwvdGg+XG4gICAgICAgICAgPHRoPkNyZWF0ZWQ8L3RoPlxuICAgICAgICAgIDx0aCBzdHlsZT1cIndpZHRoOiAxMDBweDtcIj5BY3Rpb25zPC90aD5cbiAgICAgICAgPC90cj5cbiAgICAgIDwvdGhlYWQ+XG4gICAgICA8dGJvZHk+XG4gICAgICAgIDx0cj5cbiAgICAgICAgICA8dGQ+PGlucHV0IGNsYXNzPVwiZm9ybS1jaGVjay1pbnB1dFwiIHR5cGU9XCJjaGVja2JveFwiIC8+PC90ZD5cbiAgICAgICAgICA8dGQ+PGEgaHJlZj1cIjwlPSBSc3guUm91dGUoJ0Zyb250ZW5kX0NvbnRhY3RzX1ZpZXdfQ29udHJvbGxlcicpICU+XCI+I0NUMDAxPC9hPjwvdGQ+XG4gICAgICAgICAgPHRkPjxhIGhyZWY9XCI8JT0gUnN4LlJvdXRlKCdGcm9udGVuZF9Db250YWN0c19WaWV3X0NvbnRyb2xsZXInKSAlPlwiPkphbmUgU21pdGg8L2E+PC90ZD5cbiAgICAgICAgICA8dGQ+PGEgaHJlZj1cIjwlPSBSc3guUm91dGUoJ0Zyb250ZW5kX0NvbnRhY3RzX1ZpZXdfQ29udHJvbGxlcicpICU+XCI+amFuZUBhY21lLmNvbTwvYT48L3RkPlxuICAgICAgICAgIDx0ZD4oNTU1KSAxMjMtNDU2NzwvdGQ+XG4gICAgICAgICAgPHRkPkFjbWUgQ29ycG9yYXRpb248L3RkPlxuICAgICAgICAgIDx0ZD5DRU88L3RkPlxuICAgICAgICAgIDx0ZD48c3BhbiBjbGFzcz1cImJhZGdlIGJnLXN1Y2Nlc3NcIj5BY3RpdmU8L3NwYW4+PC90ZD5cbiAgICAgICAgICA8dGQ+SmFuIDE1LCAyMDI0PC90ZD5cbiAgICAgICAgICA8dGQ+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiYnRuLWdyb3VwIGJ0bi1ncm91cC1zbVwiPlxuICAgICAgICAgICAgICA8YSBjbGFzcz1cImJ0biBidG4tcHJpbWFyeVwiIGhyZWY9XCI8JT0gUnN4LlJvdXRlKCdGcm9udGVuZF9Db250YWN0c19WaWV3X0NvbnRyb2xsZXInKSAlPlwiIHRpdGxlPVwiVmlld1wiPjxpIGNsYXNzPVwiYmkgYmktZXllXCI+PC9pPjwvYT5cbiAgICAgICAgICAgICAgPGEgY2xhc3M9XCJidG4gYnRuLXNlY29uZGFyeVwiIGhyZWY9XCIjXCIgdGl0bGU9XCJFZGl0XCI+PGkgY2xhc3M9XCJiaSBiaS1wZW5jaWxcIj48L2k+PC9hPlxuICAgICAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwiYnRuIGJ0bi1kYW5nZXJcIiB0eXBlPVwiYnV0dG9uXCIgdGl0bGU9XCJEZWxldGVcIj48aSBjbGFzcz1cImJpIGJpLXRyYXNoXCI+PC9pPjwvYnV0dG9uPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC90ZD5cbiAgICAgICAgPC90cj5cbiAgICAgICAgPHRyPlxuICAgICAgICAgIDx0ZD48aW5wdXQgY2xhc3M9XCJmb3JtLWNoZWNrLWlucHV0XCIgdHlwZT1cImNoZWNrYm94XCIgLz48L3RkPlxuICAgICAgICAgIDx0ZD4jQ1QwMDI8L3RkPlxuICAgICAgICAgIDx0ZD5Cb2IgSm9obnNvbjwvdGQ+XG4gICAgICAgICAgPHRkPmJvYkB0ZWNoc29sdXRpb25zLmlvPC90ZD5cbiAgICAgICAgICA8dGQ+KDU1NSkgMjM0LTU2Nzg8L3RkPlxuICAgICAgICAgIDx0ZD5UZWNoIFNvbHV0aW9ucyBJbmM8L3RkPlxuICAgICAgICAgIDx0ZD5DVE88L3RkPlxuICAgICAgICAgIDx0ZD48c3BhbiBjbGFzcz1cImJhZGdlIGJnLXN1Y2Nlc3NcIj5BY3RpdmU8L3NwYW4+PC90ZD5cbiAgICAgICAgICA8dGQ+SmFuIDE4LCAyMDI0PC90ZD5cbiAgICAgICAgICA8dGQ+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiYnRuLWdyb3VwIGJ0bi1ncm91cC1zbVwiPlxuICAgICAgICAgICAgICA8YSBjbGFzcz1cImJ0biBidG4tcHJpbWFyeVwiIGhyZWY9XCI8JT0gUnN4LlJvdXRlKCdGcm9udGVuZF9Db250YWN0c19WaWV3X0NvbnRyb2xsZXInKSAlPlwiIHRpdGxlPVwiVmlld1wiPjxpIGNsYXNzPVwiYmkgYmktZXllXCI+PC9pPjwvYT5cbiAgICAgICAgICAgICAgPGEgY2xhc3M9XCJidG4gYnRuLXNlY29uZGFyeVwiIGhyZWY9XCIjXCIgdGl0bGU9XCJFZGl0XCI+PGkgY2xhc3M9XCJiaSBiaS1wZW5jaWxcIj48L2k+PC9hPlxuICAgICAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwiYnRuIGJ0bi1kYW5nZXJcIiB0eXBlPVwiYnV0dG9uXCIgdGl0bGU9XCJEZWxldGVcIj48aSBjbGFzcz1cImJpIGJpLXRyYXNoXCI+PC9pPjwvYnV0dG9uPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC90ZD5cbiAgICAgICAgPC90cj5cbiAgICAgICAgPHRyPlxuICAgICAgICAgIDx0ZD48aW5wdXQgY2xhc3M9XCJmb3JtLWNoZWNrLWlucHV0XCIgdHlwZT1cImNoZWNrYm94XCIgLz48L3RkPlxuICAgICAgICAgIDx0ZD4jQ1QwMDM8L3RkPlxuICAgICAgICAgIDx0ZD5TYXJhaCBXaWxzb248L3RkPlxuICAgICAgICAgIDx0ZD5zYXJhaEBnbG9iYWxlbnQuY29tPC90ZD5cbiAgICAgICAgICA8dGQ+KDU1NSkgMzQ1LTY3ODk8L3RkPlxuICAgICAgICAgIDx0ZD5HbG9iYWwgRW50ZXJwcmlzZXM8L3RkPlxuICAgICAgICAgIDx0ZD5Qcm9qZWN0IE1hbmFnZXI8L3RkPlxuICAgICAgICAgIDx0ZD48c3BhbiBjbGFzcz1cImJhZGdlIGJnLXdhcm5pbmdcIj5QZW5kaW5nPC9zcGFuPjwvdGQ+XG4gICAgICAgICAgPHRkPkZlYiAwMiwgMjAyNDwvdGQ+XG4gICAgICAgICAgPHRkPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImJ0bi1ncm91cCBidG4tZ3JvdXAtc21cIj5cbiAgICAgICAgICAgICAgPGEgY2xhc3M9XCJidG4gYnRuLXByaW1hcnlcIiBocmVmPVwiPCU9IFJzeC5Sb3V0ZSgnRnJvbnRlbmRfQ29udGFjdHNfVmlld19Db250cm9sbGVyJykgJT5cIiB0aXRsZT1cIlZpZXdcIj48aSBjbGFzcz1cImJpIGJpLWV5ZVwiPjwvaT48L2E+XG4gICAgICAgICAgICAgIDxhIGNsYXNzPVwiYnRuIGJ0bi1zZWNvbmRhcnlcIiBocmVmPVwiI1wiIHRpdGxlPVwiRWRpdFwiPjxpIGNsYXNzPVwiYmkgYmktcGVuY2lsXCI+PC9pPjwvYT5cbiAgICAgICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cImJ0biBidG4tZGFuZ2VyXCIgdHlwZT1cImJ1dHRvblwiIHRpdGxlPVwiRGVsZXRlXCI+PGkgY2xhc3M9XCJiaSBiaS10cmFzaFwiPjwvaT48L2J1dHRvbj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwvdGQ+XG4gICAgICAgIDwvdHI+XG4gICAgICAgIDx0cj5cbiAgICAgICAgICA8dGQ+PGlucHV0IGNsYXNzPVwiZm9ybS1jaGVjay1pbnB1dFwiIHR5cGU9XCJjaGVja2JveFwiIC8+PC90ZD5cbiAgICAgICAgICA8dGQ+I0NUMDA0PC90ZD5cbiAgICAgICAgICA8dGQ+TWljaGFlbCBCcm93bjwvdGQ+XG4gICAgICAgICAgPHRkPm1icm93bkBpbm5vdmF0aW9uLmNvPC90ZD5cbiAgICAgICAgICA8dGQ+KDU1NSkgNDU2LTc4OTA8L3RkPlxuICAgICAgICAgIDx0ZD5TdGFydFVwIElubm92YXRpb25zPC90ZD5cbiAgICAgICAgICA8dGQ+RGV2ZWxvcGVyPC90ZD5cbiAgICAgICAgICA8dGQ+PHNwYW4gY2xhc3M9XCJiYWRnZSBiZy1zdWNjZXNzXCI+QWN0aXZlPC9zcGFuPjwvdGQ+XG4gICAgICAgICAgPHRkPkZlYiAxMCwgMjAyNDwvdGQ+XG4gICAgICAgICAgPHRkPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImJ0bi1ncm91cCBidG4tZ3JvdXAtc21cIj5cbiAgICAgICAgICAgICAgPGEgY2xhc3M9XCJidG4gYnRuLXByaW1hcnlcIiBocmVmPVwiPCU9IFJzeC5Sb3V0ZSgnRnJvbnRlbmRfQ29udGFjdHNfVmlld19Db250cm9sbGVyJykgJT5cIiB0aXRsZT1cIlZpZXdcIj48aSBjbGFzcz1cImJpIGJpLWV5ZVwiPjwvaT48L2E+XG4gICAgICAgICAgICAgIDxhIGNsYXNzPVwiYnRuIGJ0bi1zZWNvbmRhcnlcIiBocmVmPVwiI1wiIHRpdGxlPVwiRWRpdFwiPjxpIGNsYXNzPVwiYmkgYmktcGVuY2lsXCI+PC9pPjwvYT5cbiAgICAgICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cImJ0biBidG4tZGFuZ2VyXCIgdHlwZT1cImJ1dHRvblwiIHRpdGxlPVwiRGVsZXRlXCI+PGkgY2xhc3M9XCJiaSBiaS10cmFzaFwiPjwvaT48L2J1dHRvbj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwvdGQ+XG4gICAgICAgIDwvdHI+XG4gICAgICAgIDx0cj5cbiAgICAgICAgICA8dGQ+PGlucHV0IGNsYXNzPVwiZm9ybS1jaGVjay1pbnB1dFwiIHR5cGU9XCJjaGVja2JveFwiIC8+PC90ZD5cbiAgICAgICAgICA8dGQ+I0NUMDA1PC90ZD5cbiAgICAgICAgICA8dGQ+RW1pbHkgRGF2aXM8L3RkPlxuICAgICAgICAgIDx0ZD5lbWlseUB3aWxzb24uY29tPC90ZD5cbiAgICAgICAgICA8dGQ+KDU1NSkgNTY3LTg5MDE8L3RkPlxuICAgICAgICAgIDx0ZD5XaWxzb24gJiBBc3NvY2lhdGVzPC90ZD5cbiAgICAgICAgICA8dGQ+TWFya2V0aW5nIERpcmVjdG9yPC90ZD5cbiAgICAgICAgICA8dGQ+PHNwYW4gY2xhc3M9XCJiYWRnZSBiZy1kYW5nZXJcIj5TdXNwZW5kZWQ8L3NwYW4+PC90ZD5cbiAgICAgICAgICA8dGQ+RmViIDE1LCAyMDI0PC90ZD5cbiAgICAgICAgICA8dGQ+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiYnRuLWdyb3VwIGJ0bi1ncm91cC1zbVwiPlxuICAgICAgICAgICAgICA8YSBjbGFzcz1cImJ0biBidG4tcHJpbWFyeVwiIGhyZWY9XCI8JT0gUnN4LlJvdXRlKCdGcm9udGVuZF9Db250YWN0c19WaWV3X0NvbnRyb2xsZXInKSAlPlwiIHRpdGxlPVwiVmlld1wiPjxpIGNsYXNzPVwiYmkgYmktZXllXCI+PC9pPjwvYT5cbiAgICAgICAgICAgICAgPGEgY2xhc3M9XCJidG4gYnRuLXNlY29uZGFyeVwiIGhyZWY9XCIjXCIgdGl0bGU9XCJFZGl0XCI+PGkgY2xhc3M9XCJiaSBiaS1wZW5jaWxcIj48L2k+PC9hPlxuICAgICAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwiYnRuIGJ0bi1kYW5nZXJcIiB0eXBlPVwiYnV0dG9uXCIgdGl0bGU9XCJEZWxldGVcIj48aSBjbGFzcz1cImJpIGJpLXRyYXNoXCI+PC9pPjwvYnV0dG9uPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC90ZD5cbiAgICAgICAgPC90cj5cbiAgICAgICAgPHRyPlxuICAgICAgICAgIDx0ZD48aW5wdXQgY2xhc3M9XCJmb3JtLWNoZWNrLWlucHV0XCIgdHlwZT1cImNoZWNrYm94XCIgLz48L3RkPlxuICAgICAgICAgIDx0ZD4jQ1QwMDY8L3RkPlxuICAgICAgICAgIDx0ZD5EYXZpZCBNYXJ0aW5lejwvdGQ+XG4gICAgICAgICAgPHRkPmRhdmlkQGRtcHByby5jb208L3RkPlxuICAgICAgICAgIDx0ZD4oNTU1KSA2NzgtOTAxMjwvdGQ+XG4gICAgICAgICAgPHRkPkRpZ2l0YWwgTWFya2V0aW5nIFBybzwvdGQ+XG4gICAgICAgICAgPHRkPlNhbGVzIE1hbmFnZXI8L3RkPlxuICAgICAgICAgIDx0ZD48c3BhbiBjbGFzcz1cImJhZGdlIGJnLXN1Y2Nlc3NcIj5BY3RpdmU8L3NwYW4+PC90ZD5cbiAgICAgICAgICA8dGQ+TWFyIDAxLCAyMDI0PC90ZD5cbiAgICAgICAgICA8dGQ+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiYnRuLWdyb3VwIGJ0bi1ncm91cC1zbVwiPlxuICAgICAgICAgICAgICA8YSBjbGFzcz1cImJ0biBidG4tcHJpbWFyeVwiIGhyZWY9XCI8JT0gUnN4LlJvdXRlKCdGcm9udGVuZF9Db250YWN0c19WaWV3X0NvbnRyb2xsZXInKSAlPlwiIHRpdGxlPVwiVmlld1wiPjxpIGNsYXNzPVwiYmkgYmktZXllXCI+PC9pPjwvYT5cbiAgICAgICAgICAgICAgPGEgY2xhc3M9XCJidG4gYnRuLXNlY29uZGFyeVwiIGhyZWY9XCIjXCIgdGl0bGU9XCJFZGl0XCI+PGkgY2xhc3M9XCJiaSBiaS1wZW5jaWxcIj48L2k+PC9hPlxuICAgICAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwiYnRuIGJ0bi1kYW5nZXJcIiB0eXBlPVwiYnV0dG9uXCIgdGl0bGU9XCJEZWxldGVcIj48aSBjbGFzcz1cImJpIGJpLXRyYXNoXCI+PC9pPjwvYnV0dG9uPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC90ZD5cbiAgICAgICAgPC90cj5cbiAgICAgICAgPHRyPlxuICAgICAgICAgIDx0ZD48aW5wdXQgY2xhc3M9XCJmb3JtLWNoZWNrLWlucHV0XCIgdHlwZT1cImNoZWNrYm94XCIgLz48L3RkPlxuICAgICAgICAgIDx0ZD4jQ1QwMDc8L3RkPlxuICAgICAgICAgIDx0ZD5KZW5uaWZlciBBbmRlcnNvbjwvdGQ+XG4gICAgICAgICAgPHRkPmplbm5pZmVyQGFuZGVyc29uaW5kLm5ldDwvdGQ+XG4gICAgICAgICAgPHRkPig1NTUpIDc4OS0wMTIzPC90ZD5cbiAgICAgICAgICA8dGQ+QW5kZXJzb24gSW5kdXN0cmllczwvdGQ+XG4gICAgICAgICAgPHRkPkNGTzwvdGQ+XG4gICAgICAgICAgPHRkPjxzcGFuIGNsYXNzPVwiYmFkZ2UgYmctc3VjY2Vzc1wiPkFjdGl2ZTwvc3Bhbj48L3RkPlxuICAgICAgICAgIDx0ZD5NYXIgMDUsIDIwMjQ8L3RkPlxuICAgICAgICAgIDx0ZD5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJidG4tZ3JvdXAgYnRuLWdyb3VwLXNtXCI+XG4gICAgICAgICAgICAgIDxhIGNsYXNzPVwiYnRuIGJ0bi1wcmltYXJ5XCIgaHJlZj1cIjwlPSBSc3guUm91dGUoJ0Zyb250ZW5kX0NvbnRhY3RzX1ZpZXdfQ29udHJvbGxlcicpICU+XCIgdGl0bGU9XCJWaWV3XCI+PGkgY2xhc3M9XCJiaSBiaS1leWVcIj48L2k+PC9hPlxuICAgICAgICAgICAgICA8YSBjbGFzcz1cImJ0biBidG4tc2Vjb25kYXJ5XCIgaHJlZj1cIiNcIiB0aXRsZT1cIkVkaXRcIj48aSBjbGFzcz1cImJpIGJpLXBlbmNpbFwiPjwvaT48L2E+XG4gICAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJidG4gYnRuLWRhbmdlclwiIHR5cGU9XCJidXR0b25cIiB0aXRsZT1cIkRlbGV0ZVwiPjxpIGNsYXNzPVwiYmkgYmktdHJhc2hcIj48L2k+PC9idXR0b24+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L3RkPlxuICAgICAgICA8L3RyPlxuICAgICAgICA8dHI+XG4gICAgICAgICAgPHRkPjxpbnB1dCBjbGFzcz1cImZvcm0tY2hlY2staW5wdXRcIiB0eXBlPVwiY2hlY2tib3hcIiAvPjwvdGQ+XG4gICAgICAgICAgPHRkPiNDVDAwODwvdGQ+XG4gICAgICAgICAgPHRkPlJvYmVydCBUaG9tcHNvbjwvdGQ+XG4gICAgICAgICAgPHRkPnJvYmVydEBjcmVhdGl2ZXN0dWRpb3MuY29tPC90ZD5cbiAgICAgICAgICA8dGQ+KDU1NSkgODkwLTEyMzQ8L3RkPlxuICAgICAgICAgIDx0ZD5DcmVhdGl2ZSBTdHVkaW9zIExMQzwvdGQ+XG4gICAgICAgICAgPHRkPkFydCBEaXJlY3RvcjwvdGQ+XG4gICAgICAgICAgPHRkPjxzcGFuIGNsYXNzPVwiYmFkZ2UgYmctd2FybmluZ1wiPlBlbmRpbmc8L3NwYW4+PC90ZD5cbiAgICAgICAgICA8dGQ+TWFyIDEyLCAyMDI0PC90ZD5cbiAgICAgICAgICA8dGQ+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiYnRuLWdyb3VwIGJ0bi1ncm91cC1zbVwiPlxuICAgICAgICAgICAgICA8YSBjbGFzcz1cImJ0biBidG4tcHJpbWFyeVwiIGhyZWY9XCI8JT0gUnN4LlJvdXRlKCdGcm9udGVuZF9Db250YWN0c19WaWV3X0NvbnRyb2xsZXInKSAlPlwiIHRpdGxlPVwiVmlld1wiPjxpIGNsYXNzPVwiYmkgYmktZXllXCI+PC9pPjwvYT5cbiAgICAgICAgICAgICAgPGEgY2xhc3M9XCJidG4gYnRuLXNlY29uZGFyeVwiIGhyZWY9XCIjXCIgdGl0bGU9XCJFZGl0XCI+PGkgY2xhc3M9XCJiaSBiaS1wZW5jaWxcIj48L2k+PC9hPlxuICAgICAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwiYnRuIGJ0bi1kYW5nZXJcIiB0eXBlPVwiYnV0dG9uXCIgdGl0bGU9XCJEZWxldGVcIj48aSBjbGFzcz1cImJpIGJpLXRyYXNoXCI+PC9pPjwvYnV0dG9uPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC90ZD5cbiAgICAgICAgPC90cj5cbiAgICAgICAgPHRyPlxuICAgICAgICAgIDx0ZD48aW5wdXQgY2xhc3M9XCJmb3JtLWNoZWNrLWlucHV0XCIgdHlwZT1cImNoZWNrYm94XCIgLz48L3RkPlxuICAgICAgICAgIDx0ZD4jQ1QwMDk8L3RkPlxuICAgICAgICAgIDx0ZD5MaXNhIEdhcmNpYTwvdGQ+XG4gICAgICAgICAgPHRkPmxpc2FAZ2FyY2lhY29uc3VsdC5jb208L3RkPlxuICAgICAgICAgIDx0ZD4oNTU1KSA5MDEtMjM0NTwvdGQ+XG4gICAgICAgICAgPHRkPkdhcmNpYSBDb25zdWx0aW5nPC90ZD5cbiAgICAgICAgICA8dGQ+Q29uc3VsdGFudDwvdGQ+XG4gICAgICAgICAgPHRkPjxzcGFuIGNsYXNzPVwiYmFkZ2UgYmctc3VjY2Vzc1wiPkFjdGl2ZTwvc3Bhbj48L3RkPlxuICAgICAgICAgIDx0ZD5NYXIgMTgsIDIwMjQ8L3RkPlxuICAgICAgICAgIDx0ZD5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJidG4tZ3JvdXAgYnRuLWdyb3VwLXNtXCI+XG4gICAgICAgICAgICAgIDxhIGNsYXNzPVwiYnRuIGJ0bi1wcmltYXJ5XCIgaHJlZj1cIjwlPSBSc3guUm91dGUoJ0Zyb250ZW5kX0NvbnRhY3RzX1ZpZXdfQ29udHJvbGxlcicpICU+XCIgdGl0bGU9XCJWaWV3XCI+PGkgY2xhc3M9XCJiaSBiaS1leWVcIj48L2k+PC9hPlxuICAgICAgICAgICAgICA8YSBjbGFzcz1cImJ0biBidG4tc2Vjb25kYXJ5XCIgaHJlZj1cIiNcIiB0aXRsZT1cIkVkaXRcIj48aSBjbGFzcz1cImJpIGJpLXBlbmNpbFwiPjwvaT48L2E+XG4gICAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJidG4gYnRuLWRhbmdlclwiIHR5cGU9XCJidXR0b25cIiB0aXRsZT1cIkRlbGV0ZVwiPjxpIGNsYXNzPVwiYmkgYmktdHJhc2hcIj48L2k+PC9idXR0b24+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L3RkPlxuICAgICAgICA8L3RyPlxuICAgICAgICA8dHI+XG4gICAgICAgICAgPHRkPjxpbnB1dCBjbGFzcz1cImZvcm0tY2hlY2staW5wdXRcIiB0eXBlPVwiY2hlY2tib3hcIiAvPjwvdGQ+XG4gICAgICAgICAgPHRkPiNDVDAxMDwvdGQ+XG4gICAgICAgICAgPHRkPkNocmlzdG9waGVyIFdoaXRlPC90ZD5cbiAgICAgICAgICA8dGQ+Y2hyaXNAd2hpdGVwYXJ0bmVycy5vcmc8L3RkPlxuICAgICAgICAgIDx0ZD4oNTU1KSAwMTItMzQ1NjwvdGQ+XG4gICAgICAgICAgPHRkPldoaXRlICYgUGFydG5lcnM8L3RkPlxuICAgICAgICAgIDx0ZD5QYXJ0bmVyPC90ZD5cbiAgICAgICAgICA8dGQ+PHNwYW4gY2xhc3M9XCJiYWRnZSBiZy1zdWNjZXNzXCI+QWN0aXZlPC9zcGFuPjwvdGQ+XG4gICAgICAgICAgPHRkPk1hciAyMiwgMjAyNDwvdGQ+XG4gICAgICAgICAgPHRkPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImJ0bi1ncm91cCBidG4tZ3JvdXAtc21cIj5cbiAgICAgICAgICAgICAgPGEgY2xhc3M9XCJidG4gYnRuLXByaW1hcnlcIiBocmVmPVwiPCU9IFJzeC5Sb3V0ZSgnRnJvbnRlbmRfQ29udGFjdHNfVmlld19Db250cm9sbGVyJykgJT5cIiB0aXRsZT1cIlZpZXdcIj48aSBjbGFzcz1cImJpIGJpLWV5ZVwiPjwvaT48L2E+XG4gICAgICAgICAgICAgIDxhIGNsYXNzPVwiYnRuIGJ0bi1zZWNvbmRhcnlcIiBocmVmPVwiI1wiIHRpdGxlPVwiRWRpdFwiPjxpIGNsYXNzPVwiYmkgYmktcGVuY2lsXCI+PC9pPjwvYT5cbiAgICAgICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cImJ0biBidG4tZGFuZ2VyXCIgdHlwZT1cImJ1dHRvblwiIHRpdGxlPVwiRGVsZXRlXCI+PGkgY2xhc3M9XCJiaSBiaS10cmFzaFwiPjwvaT48L2J1dHRvbj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwvdGQ+XG4gICAgICAgIDwvdHI+XG4gICAgICA8L3Rib2R5PlxuICAgIDwvdGFibGU+XG4gIDwvZGl2PlxuPC9EZWZpbmU6Q29udGFjdHNfRGF0YV9UYWJsZT5cbiIsIjxEZWZpbmU6Q29udGFjdHNfTGlzdF9DYXJkIHRhZz1cImRpdlwiIGNsYXNzPVwiY2FyZFwiPlxuXG4gICAgPCU9IGNvbnRlbnQoKSAlPlxuXG48L0RlZmluZTpDb250YWN0c19MaXN0X0NhcmQ+XG4iLCI8RGVmaW5lOkRhdGVfUGlja2VyIGNsYXNzPVwibWItM1wiPlxuICA8JSBpZiAodGhpcy5hcmdzLmxhYmVsKSB7ICU+XG4gICAgPGxhYmVsIGNsYXNzPVwiZm9ybS1sYWJlbFwiPjwlPSB0aGlzLmFyZ3MubGFiZWwgJT48L2xhYmVsPlxuICA8JSB9ICU+XG4gIDxkaXYgY2xhc3M9XCJpbnB1dC1ncm91cFwiPlxuICAgIDxzcGFuIGNsYXNzPVwiaW5wdXQtZ3JvdXAtdGV4dFwiPlxuICAgICAgPGkgY2xhc3M9XCJiaSBiaS1jYWxlbmRhclwiPjwvaT5cbiAgICA8L3NwYW4+XG4gICAgPGlucHV0XG4gICAgICB0eXBlPVwiZGF0ZVwiXG4gICAgICBjbGFzcz1cImZvcm0tY29udHJvbFwiXG4gICAgICBwbGFjZWhvbGRlcj1cIjwlPSB0aGlzLmFyZ3MucGxhY2Vob2xkZXIgfHwgJycgJT5cIlxuICAgICAgJGlkPVwiaW5wdXRcIlxuICAgIC8+XG4gIDwvZGl2PlxuICA8JSBpZiAodGhpcy5hcmdzLmhlbHApIHsgJT5cbiAgICA8ZGl2IGNsYXNzPVwiZm9ybS10ZXh0XCI+PCU9IHRoaXMuYXJncy5oZWxwICU+PC9kaXY+XG4gIDwlIH0gJT5cbjwvRGVmaW5lOkRhdGVfUGlja2VyPlxuIiwiPERlZmluZTpEcm9wZG93bl9NZW51IGNsYXNzPVwiZHJvcGRvd25cIj5cbiAgPGJ1dHRvbiBjbGFzcz1cImJ0biBidG4tc2Vjb25kYXJ5IGRyb3Bkb3duLXRvZ2dsZVwiXG4gICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgZGF0YS1icy10b2dnbGU9XCJkcm9wZG93blwiXG4gICAgICAgICAgYXJpYS1leHBhbmRlZD1cImZhbHNlXCJcbiAgICAgICAgICAkaWQ9XCJ0b2dnbGVcIj5cbiAgICA8JT0gdGhpcy5hcmdzLmxhYmVsIHx8ICdNZW51JyAlPlxuICA8L2J1dHRvbj5cbiAgPHVsIGNsYXNzPVwiZHJvcGRvd24tbWVudVwiIGFyaWEtbGFiZWxsZWRieT1cInRvZ2dsZVwiICRpZD1cIm1lbnVcIj5cbiAgICA8JT0gY29udGVudCgpICU+XG4gIDwvdWw+XG48L0RlZmluZTpEcm9wZG93bl9NZW51PlxuIiwiPERlZmluZTpFbXB0eV9TdGF0ZSBjbGFzcz1cInRleHQtY2VudGVyIHB5LTVcIj5cbiAgPGRpdiBjbGFzcz1cIm1iLTMgdGV4dC1tdXRlZFwiIHN0eWxlPVwiZm9udC1zaXplOiAzcmVtO1wiPlxuICAgIDxJY29uICRuYW1lPSh0aGlzLmFyZ3MuaWNvbiB8fCAnaW5ib3gnKSAvPlxuICA8L2Rpdj5cbiAgPGg1IGNsYXNzPVwidGV4dC1tdXRlZFwiPjwlPSB0aGlzLmFyZ3MudGl0bGUgfHwgJ05vIGl0ZW1zIGZvdW5kJyAlPjwvaDU+XG4gIDxwIGNsYXNzPVwidGV4dC1tdXRlZFwiPjwlPSB0aGlzLmFyZ3MubWVzc2FnZSB8fCAnR2V0IHN0YXJ0ZWQgYnkgY3JlYXRpbmcgYSBuZXcgaXRlbS4nICU+PC9wPlxuICA8JSBpZiAodGhpcy5hcmdzLmFjdGlvbl9sYWJlbCkgeyAlPlxuICAgIDxCdXR0b25fUHJpbWFyeT48JT0gdGhpcy5hcmdzLmFjdGlvbl9sYWJlbCAlPjwvQnV0dG9uX1ByaW1hcnk+XG4gIDwlIH0gJT5cbjwvRGVmaW5lOkVtcHR5X1N0YXRlPlxuIiwiPERlZmluZTpFeHBvcnRfQnV0dG9uIGNsYXNzPVwiZHJvcGRvd25cIj5cbiAgPGJ1dHRvbiBjbGFzcz1cImJ0biBidG4tPCU9IHRoaXMuYXJncy52YXJpYW50IHx8ICdwcmltYXJ5JyAlPiBkcm9wZG93bi10b2dnbGVcIiB0eXBlPVwiYnV0dG9uXCIgZGF0YS1icy10b2dnbGU9XCJkcm9wZG93blwiIGFyaWEtZXhwYW5kZWQ9XCJmYWxzZVwiPlxuICAgIDxpIGNsYXNzPVwiYmkgYmktZG93bmxvYWRcIj48L2k+XG4gICAgPCU9IHRoaXMuYXJncy5sYWJlbCB8fCAnRXhwb3J0JyAlPlxuICA8L2J1dHRvbj5cbiAgPHVsIGNsYXNzPVwiZHJvcGRvd24tbWVudVwiPlxuICAgIDxsaT5cbiAgICAgIDxhIGNsYXNzPVwiZHJvcGRvd24taXRlbVwiIGhyZWY9XCIjXCIgZGF0YS1mb3JtYXQ9XCJjc3ZcIj5cbiAgICAgICAgPGkgY2xhc3M9XCJiaSBiaS1maWxldHlwZS1jc3YgbWUtMlwiPjwvaT5cbiAgICAgICAgRXhwb3J0IGFzIENTVlxuICAgICAgPC9hPlxuICAgIDwvbGk+XG4gICAgPGxpPlxuICAgICAgPGEgY2xhc3M9XCJkcm9wZG93bi1pdGVtXCIgaHJlZj1cIiNcIiBkYXRhLWZvcm1hdD1cImV4Y2VsXCI+XG4gICAgICAgIDxpIGNsYXNzPVwiYmkgYmktZmlsZXR5cGUteGxzeCBtZS0yXCI+PC9pPlxuICAgICAgICBFeHBvcnQgYXMgRXhjZWxcbiAgICAgIDwvYT5cbiAgICA8L2xpPlxuICAgIDxsaT5cbiAgICAgIDxhIGNsYXNzPVwiZHJvcGRvd24taXRlbVwiIGhyZWY9XCIjXCIgZGF0YS1mb3JtYXQ9XCJwZGZcIj5cbiAgICAgICAgPGkgY2xhc3M9XCJiaSBiaS1maWxldHlwZS1wZGYgbWUtMlwiPjwvaT5cbiAgICAgICAgRXhwb3J0IGFzIFBERlxuICAgICAgPC9hPlxuICAgIDwvbGk+XG4gICAgPGxpPlxuICAgICAgPGEgY2xhc3M9XCJkcm9wZG93bi1pdGVtXCIgaHJlZj1cIiNcIiBkYXRhLWZvcm1hdD1cImpzb25cIj5cbiAgICAgICAgPGkgY2xhc3M9XCJiaSBiaS1maWxldHlwZS1qc29uIG1lLTJcIj48L2k+XG4gICAgICAgIEV4cG9ydCBhcyBKU09OXG4gICAgICA8L2E+XG4gICAgPC9saT5cbiAgPC91bD5cbjwvRGVmaW5lOkV4cG9ydF9CdXR0b24+XG4iLCI8RGVmaW5lOkZpbGVfVXBsb2FkIGNsYXNzPVwibWItM1wiPlxuICA8JSBpZiAodGhpcy5hcmdzLmxhYmVsKSB7ICU+XG4gICAgPGxhYmVsIGNsYXNzPVwiZm9ybS1sYWJlbFwiPjwlPSB0aGlzLmFyZ3MubGFiZWwgJT48L2xhYmVsPlxuICA8JSB9ICU+XG4gIDxkaXYgY2xhc3M9XCJib3JkZXIgcm91bmRlZCBwLTQgdGV4dC1jZW50ZXJcIiAkaWQ9XCJkcm9wX3pvbmVcIiBzdHlsZT1cImN1cnNvcjogcG9pbnRlcjsgdHJhbnNpdGlvbjogYWxsIDAuMnM7XCI+XG4gICAgPGlucHV0IHR5cGU9XCJmaWxlXCIgY2xhc3M9XCJkLW5vbmVcIiAkaWQ9XCJmaWxlX2lucHV0XCIgLz5cbiAgICA8ZGl2ICRpZD1cInBsYWNlaG9sZGVyXCI+XG4gICAgICA8aSBjbGFzcz1cImJpIGJpLWNsb3VkLXVwbG9hZCBmcy0xIHRleHQtbXV0ZWRcIj48L2k+XG4gICAgICA8ZGl2IGNsYXNzPVwibXQtMlwiPlxuICAgICAgICA8c3BhbiBjbGFzcz1cInRleHQtcHJpbWFyeVwiPkNsaWNrIHRvIHVwbG9hZDwvc3Bhbj4gb3IgZHJhZyBhbmQgZHJvcFxuICAgICAgPC9kaXY+XG4gICAgICA8JSBpZiAodGhpcy5hcmdzLmFjY2VwdCkgeyAlPlxuICAgICAgICA8ZGl2IGNsYXNzPVwidGV4dC1tdXRlZCBzbWFsbCBtdC0xXCI+PCU9IHRoaXMuYXJncy5hY2NlcHQgJT48L2Rpdj5cbiAgICAgIDwlIH0gJT5cbiAgICAgIDwlIGlmICh0aGlzLmFyZ3MubWF4X3NpemUpIHsgJT5cbiAgICAgICAgPGRpdiBjbGFzcz1cInRleHQtbXV0ZWQgc21hbGxcIj5NYXggc2l6ZTogPCU9IHRoaXMuYXJncy5tYXhfc2l6ZSAlPjwvZGl2PlxuICAgICAgPCUgfSAlPlxuICAgIDwvZGl2PlxuICAgIDxkaXYgJGlkPVwiZmlsZV9pbmZvXCIgc3R5bGU9XCJkaXNwbGF5OiBub25lO1wiPlxuICAgICAgPGkgY2xhc3M9XCJiaSBiaS1maWxlLWVhcm1hcmsgZnMtMSB0ZXh0LXN1Y2Nlc3NcIj48L2k+XG4gICAgICA8ZGl2IGNsYXNzPVwibXQtMlwiICRpZD1cImZpbGVfbmFtZVwiPjwvZGl2PlxuICAgICAgPGRpdiBjbGFzcz1cInRleHQtbXV0ZWQgc21hbGxcIiAkaWQ9XCJmaWxlX3NpemVcIj48L2Rpdj5cbiAgICAgIDxCdXR0b25fU2Vjb25kYXJ5ICRpZD1cInJlbW92ZV9idG5cIiBjbGFzcz1cIm10LTJcIj5SZW1vdmU8L0J1dHRvbl9TZWNvbmRhcnk+XG4gICAgPC9kaXY+XG4gICAgPGRpdiAkaWQ9XCJwcm9ncmVzc1wiIHN0eWxlPVwiZGlzcGxheTogbm9uZTtcIj5cbiAgICAgIDxQcm9ncmVzc19CYXIgJGlkPVwicHJvZ3Jlc3NfYmFyXCIgLz5cbiAgICAgIDxkaXYgY2xhc3M9XCJ0ZXh0LW11dGVkIHNtYWxsIG10LTJcIj5VcGxvYWRpbmcuLi48L2Rpdj5cbiAgICA8L2Rpdj5cbiAgPC9kaXY+XG4gIDwlIGlmICh0aGlzLmFyZ3MuaGVscCkgeyAlPlxuICAgIDxkaXYgY2xhc3M9XCJmb3JtLXRleHRcIj48JT0gdGhpcy5hcmdzLmhlbHAgJT48L2Rpdj5cbiAgPCUgfSAlPlxuPC9EZWZpbmU6RmlsZV9VcGxvYWQ+XG4iLCI8RGVmaW5lOkZpbHRlcl9CYXIgY2xhc3M9XCJjYXJkIG1iLTNcIj5cbiAgPGRpdiBjbGFzcz1cImNhcmQtYm9keVwiPlxuICAgIDxkaXYgY2xhc3M9XCJyb3cgZy0zIGFsaWduLWl0ZW1zLWVuZFwiPlxuICAgICAgPGRpdiBjbGFzcz1cImNvbC1hdXRvXCI+XG4gICAgICAgIDxsYWJlbCBjbGFzcz1cImZvcm0tbGFiZWwgc21hbGwgdGV4dC1tdXRlZCBtYi0xXCI+U2VhcmNoPC9sYWJlbD5cbiAgICAgICAgPElucHV0X1dpdGhfSWNvbiAkaWNvbj1cInNlYXJjaFwiICRwbGFjZWhvbGRlcj1cIlNlYXJjaC4uLlwiICRpZD1cInNlYXJjaFwiIC8+XG4gICAgICA8L2Rpdj5cbiAgICAgIDxkaXYgY2xhc3M9XCJjb2wtYXV0b1wiPlxuICAgICAgICA8bGFiZWwgY2xhc3M9XCJmb3JtLWxhYmVsIHNtYWxsIHRleHQtbXV0ZWQgbWItMVwiPlN0YXR1czwvbGFiZWw+XG4gICAgICAgIDxzZWxlY3QgY2xhc3M9XCJmb3JtLXNlbGVjdFwiICRpZD1cInN0YXR1c1wiPlxuICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCJcIj5BbGw8L29wdGlvbj5cbiAgICAgICAgPC9zZWxlY3Q+XG4gICAgICA8L2Rpdj5cbiAgICAgIDxkaXYgY2xhc3M9XCJjb2wtYXV0b1wiPlxuICAgICAgICA8bGFiZWwgY2xhc3M9XCJmb3JtLWxhYmVsIHNtYWxsIHRleHQtbXV0ZWQgbWItMVwiPkRhdGUgUmFuZ2U8L2xhYmVsPlxuICAgICAgICA8c2VsZWN0IGNsYXNzPVwiZm9ybS1zZWxlY3RcIiAkaWQ9XCJkYXRlX3JhbmdlXCI+XG4gICAgICAgICAgPG9wdGlvbiB2YWx1ZT1cIlwiPkFsbCBUaW1lPC9vcHRpb24+XG4gICAgICAgICAgPG9wdGlvbiB2YWx1ZT1cInRvZGF5XCI+VG9kYXk8L29wdGlvbj5cbiAgICAgICAgICA8b3B0aW9uIHZhbHVlPVwid2Vla1wiPlRoaXMgV2Vlazwvb3B0aW9uPlxuICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCJtb250aFwiPlRoaXMgTW9udGg8L29wdGlvbj5cbiAgICAgICAgICA8b3B0aW9uIHZhbHVlPVwiY3VzdG9tXCI+Q3VzdG9tIFJhbmdlPC9vcHRpb24+XG4gICAgICAgIDwvc2VsZWN0PlxuICAgICAgPC9kaXY+XG4gICAgICA8ZGl2IGNsYXNzPVwiY29sLWF1dG9cIiAkaWQ9XCJjdXN0b21fZGF0ZXNcIiBzdHlsZT1cImRpc3BsYXk6IG5vbmU7XCI+XG4gICAgICAgIDxEYXRlX1BpY2tlciAkaWQ9XCJzdGFydF9kYXRlXCIgLz5cbiAgICAgIDwvZGl2PlxuICAgICAgPGRpdiBjbGFzcz1cImNvbC1hdXRvXCIgJGlkPVwiY3VzdG9tX2RhdGVzX2VuZFwiIHN0eWxlPVwiZGlzcGxheTogbm9uZTtcIj5cbiAgICAgICAgPERhdGVfUGlja2VyICRpZD1cImVuZF9kYXRlXCIgLz5cbiAgICAgIDwvZGl2PlxuICAgICAgPGRpdiBjbGFzcz1cImNvbC1hdXRvIG1zLWF1dG9cIj5cbiAgICAgICAgPEJ1dHRvbl9TZWNvbmRhcnkgJGlkPVwiY2xlYXJfYnRuXCI+Q2xlYXIgRmlsdGVyczwvQnV0dG9uX1NlY29uZGFyeT5cbiAgICAgICAgPEJ1dHRvbl9QcmltYXJ5ICRpZD1cImFwcGx5X2J0blwiIGNsYXNzPVwibXMtMlwiPkFwcGx5PC9CdXR0b25fUHJpbWFyeT5cbiAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuICAgIDxkaXYgY2xhc3M9XCJtdC0zXCIgJGlkPVwiYWN0aXZlX2ZpbHRlcnNcIiBzdHlsZT1cImRpc3BsYXk6IG5vbmU7XCI+XG4gICAgICA8c21hbGwgY2xhc3M9XCJ0ZXh0LW11dGVkIG1lLTJcIj5BY3RpdmUgZmlsdGVyczo8L3NtYWxsPlxuICAgICAgPGRpdiBjbGFzcz1cImQtaW5saW5lLWJsb2NrXCIgJGlkPVwiZmlsdGVyX3RhZ3NcIj48L2Rpdj5cbiAgICA8L2Rpdj5cbiAgPC9kaXY+XG48L0RlZmluZTpGaWx0ZXJfQmFyPlxuIiwiPERlZmluZTpGb3JtX0FjdGlvbnNfQ29tcG9uZW50IHRhZz1cImRpdlwiIGNsYXNzPVwibXQtM1wiPlxuICA8JSBpZiAodGhpcy5hcmdzLmNhbmNlbF91cmwpIHsgJT5cbiAgICA8YSBocmVmPVwiPCU9IHRoaXMuYXJncy5jYW5jZWxfdXJsICU+XCIgY2xhc3M9XCJidG4gYnRuLXNlY29uZGFyeVwiPjwlPSB0aGlzLmFyZ3MuY2FuY2VsX3RleHQgfHwgJ0NhbmNlbCcgJT48L2E+XG4gIDwlIH0gJT5cbiAgPGJ1dHRvbiBjbGFzcz1cImJ0biBidG4tcHJpbWFyeVwiIHR5cGU9XCJzdWJtaXRcIj48JT0gdGhpcy5hcmdzLnN1Ym1pdF90ZXh0IHx8ICdTYXZlJyAlPjwvYnV0dG9uPlxuPC9EZWZpbmU6Rm9ybV9BY3Rpb25zX0NvbXBvbmVudD5cbiIsIjxEZWZpbmU6Rm9ybV9GaWVsZF9Hcm91cCBjbGFzcz1cImNhcmQgbWItM1wiPlxuICA8ZGl2IGNsYXNzPVwiY2FyZC1oZWFkZXJcIj5cbiAgICA8aDUgY2xhc3M9XCJtYi0wXCI+PCU9IHRoaXMuYXJncy50aXRsZSB8fCAnRm9ybSBTZWN0aW9uJyAlPjwvaDU+XG4gICAgPCUgaWYgKHRoaXMuYXJncy5kZXNjcmlwdGlvbikgeyAlPlxuICAgICAgPHNtYWxsIGNsYXNzPVwidGV4dC1tdXRlZFwiPjwlPSB0aGlzLmFyZ3MuZGVzY3JpcHRpb24gJT48L3NtYWxsPlxuICAgIDwlIH0gJT5cbiAgPC9kaXY+XG4gIDxkaXYgY2xhc3M9XCJjYXJkLWJvZHlcIj5cbiAgICA8JT0gY29udGVudCgpICU+XG4gIDwvZGl2PlxuPC9EZWZpbmU6Rm9ybV9GaWVsZF9Hcm91cD5cbiIsIjxEZWZpbmU6Rm9ybV9Hcm91cF9Db21wb25lbnQgdGFnPVwiZGl2XCI+XG4gIDxkaXY+XG4gICAgPCUgaWYgKHRoaXMuYXJncy5sYWJlbCkgeyAlPlxuICAgICAgPGxhYmVsIGZvcj1cIjwlPSB0aGlzLmFyZ3MuaWQgJT5cIj48JT0gdGhpcy5hcmdzLmxhYmVsICU+PC9sYWJlbD5cbiAgICA8JSB9ICU+XG4gICAgPCUgaWYgKHRoaXMuYXJncy50eXBlID09PSAnc2VsZWN0JykgeyAlPlxuICAgICAgPCUgaWYgKHRoaXMuYXJncy5yZXF1aXJlZCkgeyAlPlxuICAgICAgICA8c2VsZWN0IGNsYXNzPVwiZm9ybS1zZWxlY3RcIiBpZD1cIjwlPSB0aGlzLmFyZ3MuaWQgJT5cIiByZXF1aXJlZD5cbiAgICAgICAgICA8JSBpZiAodGhpcy5hcmdzLnBsYWNlaG9sZGVyKSB7ICU+XG4gICAgICAgICAgICA8b3B0aW9uIHZhbHVlPVwiXCI+PCU9IHRoaXMuYXJncy5wbGFjZWhvbGRlciAlPjwvb3B0aW9uPlxuICAgICAgICAgIDwlIH0gJT5cbiAgICAgICAgICA8JT0gY29udGVudCgpICU+XG4gICAgICAgIDwvc2VsZWN0PlxuICAgICAgPCUgfSBlbHNlIHsgJT5cbiAgICAgICAgPHNlbGVjdCBjbGFzcz1cImZvcm0tc2VsZWN0XCIgaWQ9XCI8JT0gdGhpcy5hcmdzLmlkICU+XCI+XG4gICAgICAgICAgPCUgaWYgKHRoaXMuYXJncy5wbGFjZWhvbGRlcikgeyAlPlxuICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT1cIlwiPjwlPSB0aGlzLmFyZ3MucGxhY2Vob2xkZXIgJT48L29wdGlvbj5cbiAgICAgICAgICA8JSB9ICU+XG4gICAgICAgICAgPCU9IGNvbnRlbnQoKSAlPlxuICAgICAgICA8L3NlbGVjdD5cbiAgICAgIDwlIH0gJT5cbiAgICA8JSB9IGVsc2UgaWYgKHRoaXMuYXJncy50eXBlID09PSAndGV4dGFyZWEnKSB7ICU+XG4gICAgICA8JSBpZiAodGhpcy5hcmdzLnJlcXVpcmVkKSB7ICU+XG4gICAgICAgIDx0ZXh0YXJlYSBjbGFzcz1cImZvcm0tY29udHJvbFwiIGlkPVwiPCU9IHRoaXMuYXJncy5pZCAlPlwiIHJvd3M9XCI8JT0gdGhpcy5hcmdzLnJvd3MgfHwgNCAlPlwiIHBsYWNlaG9sZGVyPVwiPCU9IHRoaXMuYXJncy5wbGFjZWhvbGRlciB8fCAnJyAlPlwiIHJlcXVpcmVkPjwvdGV4dGFyZWE+XG4gICAgICA8JSB9IGVsc2UgeyAlPlxuICAgICAgICA8dGV4dGFyZWEgY2xhc3M9XCJmb3JtLWNvbnRyb2xcIiBpZD1cIjwlPSB0aGlzLmFyZ3MuaWQgJT5cIiByb3dzPVwiPCU9IHRoaXMuYXJncy5yb3dzIHx8IDQgJT5cIiBwbGFjZWhvbGRlcj1cIjwlPSB0aGlzLmFyZ3MucGxhY2Vob2xkZXIgfHwgJycgJT5cIj48L3RleHRhcmVhPlxuICAgICAgPCUgfSAlPlxuICAgIDwlIH0gZWxzZSB7ICU+XG4gICAgICA8JSBpZiAodGhpcy5hcmdzLnJlcXVpcmVkKSB7ICU+XG4gICAgICAgIDxpbnB1dCBjbGFzcz1cImZvcm0tY29udHJvbFwiIGlkPVwiPCU9IHRoaXMuYXJncy5pZCAlPlwiIHR5cGU9XCI8JT0gdGhpcy5hcmdzLnR5cGUgfHwgJ3RleHQnICU+XCIgcGxhY2Vob2xkZXI9XCI8JT0gdGhpcy5hcmdzLnBsYWNlaG9sZGVyIHx8ICcnICU+XCIgcmVxdWlyZWQ+XG4gICAgICA8JSB9IGVsc2UgeyAlPlxuICAgICAgICA8aW5wdXQgY2xhc3M9XCJmb3JtLWNvbnRyb2xcIiBpZD1cIjwlPSB0aGlzLmFyZ3MuaWQgJT5cIiB0eXBlPVwiPCU9IHRoaXMuYXJncy50eXBlIHx8ICd0ZXh0JyAlPlwiIHBsYWNlaG9sZGVyPVwiPCU9IHRoaXMuYXJncy5wbGFjZWhvbGRlciB8fCAnJyAlPlwiPlxuICAgICAgPCUgfSAlPlxuICAgIDwlIH0gJT5cbiAgPC9kaXY+XG48L0RlZmluZTpGb3JtX0dyb3VwX0NvbXBvbmVudD5cbiIsIjxEZWZpbmU6Rm9ybV9Sb3dfQ29tcG9uZW50IHRhZz1cImRpdlwiIGNsYXNzPVwicm93XCI+XG4gIDwlPSBjb250ZW50KCkgJT5cbjwvRGVmaW5lOkZvcm1fUm93X0NvbXBvbmVudD5cbiIsIjxEZWZpbmU6Rm9ybV9WYWxpZGF0aW9uX01lc3NhZ2UgY2xhc3M9XCJpbnZhbGlkLWZlZWRiYWNrXCI+XG4gIDwlPSBjb250ZW50KCkgJT5cbjwvRGVmaW5lOkZvcm1fVmFsaWRhdGlvbl9NZXNzYWdlPlxuIiwiPERlZmluZTpHYW50dF9DaGFydCBjbGFzcz1cImNhcmRcIj5cbiAgPGRpdiBjbGFzcz1cImNhcmQtaGVhZGVyXCI+XG4gICAgPGg1IGNsYXNzPVwibWItMFwiPjwlPSB0aGlzLmFyZ3MudGl0bGUgfHwgJ1Byb2plY3QgVGltZWxpbmUnICU+PC9oNT5cbiAgPC9kaXY+XG4gIDxkaXYgY2xhc3M9XCJjYXJkLWJvZHkgcC0wXCI+XG4gICAgPGRpdiBjbGFzcz1cInRhYmxlLXJlc3BvbnNpdmVcIj5cbiAgICAgIDx0YWJsZSBjbGFzcz1cInRhYmxlIHRhYmxlLWJvcmRlcmVkIG1iLTBcIiBzdHlsZT1cInRhYmxlLWxheW91dDogZml4ZWQ7XCI+XG4gICAgICAgIDx0aGVhZCBjbGFzcz1cInRhYmxlLWxpZ2h0XCI+XG4gICAgICAgICAgPHRyPlxuICAgICAgICAgICAgPHRoIHN0eWxlPVwid2lkdGg6IDIwMHB4O1wiPlRhc2s8L3RoPlxuICAgICAgICAgICAgPCUgZm9yIChsZXQgbW9udGggb2YgdGhpcy5kYXRhLm1vbnRocyB8fCBbXSkgeyAlPlxuICAgICAgICAgICAgICA8dGggY2xhc3M9XCJ0ZXh0LWNlbnRlciBzbWFsbFwiPjwlPSBtb250aCAlPjwvdGg+XG4gICAgICAgICAgICA8JSB9ICU+XG4gICAgICAgICAgPC90cj5cbiAgICAgICAgPC90aGVhZD5cbiAgICAgICAgPHRib2R5PlxuICAgICAgICAgIDwlIGlmIChPYmplY3Qua2V5cyh0aGlzLmRhdGEpLmxlbmd0aCA9PT0gMCkgeyAlPlxuICAgICAgICAgICAgPHRyPlxuICAgICAgICAgICAgICA8dGQgY29sc3Bhbj1cIjEwMFwiIGNsYXNzPVwidGV4dC1jZW50ZXIgcHktNVwiPlxuICAgICAgICAgICAgICAgIDxTcGlubmVyIC8+XG4gICAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICA8L3RyPlxuICAgICAgICAgIDwlIH0gZWxzZSB7ICU+XG4gICAgICAgICAgICA8JSBmb3IgKGxldCB0YXNrIG9mIHRoaXMuZGF0YS50YXNrcyB8fCBbXSkgeyAlPlxuICAgICAgICAgICAgICA8dHI+XG4gICAgICAgICAgICAgICAgPHRkIGNsYXNzPVwiYWxpZ24tbWlkZGxlXCI+XG4gICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZnctYm9sZFwiPjwlPSB0YXNrLm5hbWUgJT48L2Rpdj5cbiAgICAgICAgICAgICAgICAgIDwlIGlmICh0YXNrLmFzc2lnbmVlKSB7ICU+XG4gICAgICAgICAgICAgICAgICAgIDxzbWFsbCBjbGFzcz1cInRleHQtbXV0ZWRcIj48JT0gdGFzay5hc3NpZ25lZSAlPjwvc21hbGw+XG4gICAgICAgICAgICAgICAgICA8JSB9ICU+XG4gICAgICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgICAgICA8JSBmb3IgKGxldCBpID0gMDsgaSA8ICh0aGlzLmRhdGEubW9udGhzIHx8IFtdKS5sZW5ndGg7IGkrKykgeyAlPlxuICAgICAgICAgICAgICAgICAgPHRkIGNsYXNzPVwicC0xIGFsaWduLW1pZGRsZVwiPlxuICAgICAgICAgICAgICAgICAgICA8JSBpZiAodGFzay5zdGFydF9tb250aCA8PSBpICYmIHRhc2suZW5kX21vbnRoID49IGkpIHsgJT5cbiAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiYmctPCU9IHRhc2suY29sb3IgfHwgJ3ByaW1hcnknICU+IHJvdW5kZWQgcC0yIHRleHQtd2hpdGUgc21hbGwgdGV4dC1jZW50ZXJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwlPSB0YXNrLnN0YXJ0X21vbnRoID09PSBpID8gdGFzay5uYW1lIDogJycgJT5cbiAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPCUgfSAlPlxuICAgICAgICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgICAgICA8JSB9ICU+XG4gICAgICAgICAgICAgIDwvdHI+XG4gICAgICAgICAgICA8JSB9ICU+XG4gICAgICAgICAgPCUgfSAlPlxuICAgICAgICA8L3Rib2R5PlxuICAgICAgPC90YWJsZT5cbiAgICA8L2Rpdj5cbiAgPC9kaXY+XG48L0RlZmluZTpHYW50dF9DaGFydD5cbiIsIjxEZWZpbmU6SWNvbl9CdXR0b24gdGFnPVwiYnV0dG9uXCIgY2xhc3M9XCJidG4gYnRuLXNlY29uZGFyeVwiIHR5cGU9XCJidXR0b25cIj5cbiAgPCU9IGNvbnRlbnQoKSAlPlxuPC9EZWZpbmU6SWNvbl9CdXR0b24+XG4iLCI8RGVmaW5lOkljb25fV2l0aF9MYWJlbCBjbGFzcz1cImQtaW5saW5lLWZsZXggYWxpZ24taXRlbXMtY2VudGVyIGdhcC0yXCI+XG4gIDxJY29uICRuYW1lPSh0aGlzLmFyZ3MuaWNvbikgLz5cbiAgPHNwYW4+PCU9IGNvbnRlbnQoKSAlPjwvc3Bhbj5cbjwvRGVmaW5lOkljb25fV2l0aF9MYWJlbD5cbiIsIjxEZWZpbmU6SWNvbl9XaXRoX1RleHQgY2xhc3M9XCJkLWZsZXggYWxpZ24taXRlbXMtY2VudGVyIHB5LTJcIj5cbiAgPGkgY2xhc3M9XCJiaSBiaS1jaXJjbGUtZmlsbCBtZS0yIHRleHQtcHJpbWFyeVwiIHN0eWxlPVwiZm9udC1zaXplOiAwLjVyZW07XCI+PC9pPlxuICA8c3BhbiBjbGFzcz1cImZsZXgtZ3Jvdy0xXCI+PCU9IGNvbnRlbnQoKSAlPjwvc3Bhbj5cbjwvRGVmaW5lOkljb25fV2l0aF9UZXh0PlxuIiwiPERlZmluZTpJY29uIHRhZz1cInN2Z1wiIGNsYXNzPVwiaWNvbiBpY29uLXhzXCIgZmlsbD1cImN1cnJlbnRDb2xvclwiIHZpZXdCb3g9XCIwIDAgMjQgMjRcIiB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCI+XG4gIDwlPSBjb250ZW50KCkgJT5cbjwvRGVmaW5lOkljb24+XG4iLCI8RGVmaW5lOkluZm9fQm94IGNsYXNzPVwicC0zIG1iLTMgYmctbGlnaHQgYm9yZGVyLXN0YXJ0IGJvcmRlci1wcmltYXJ5IGJvcmRlci00XCI+XG4gIDwlPSBjb250ZW50KCkgJT5cbjwvRGVmaW5lOkluZm9fQm94PlxuIiwiPERlZmluZTpJbmxpbmVfRWRpdF9GaWVsZCBjbGFzcz1cImQtZmxleCBhbGlnbi1pdGVtcy1jZW50ZXIgZ2FwLTJcIj5cbiAgPGRpdiAkaWQ9XCJkaXNwbGF5X21vZGVcIiBzdHlsZT1cImN1cnNvcjogcG9pbnRlcjtcIj5cbiAgICA8c3BhbiAkaWQ9XCJ2YWx1ZV9kaXNwbGF5XCI+PCU9IHRoaXMuYXJncy52YWx1ZSB8fCB0aGlzLmFyZ3MucGxhY2Vob2xkZXIgfHwgJ0NsaWNrIHRvIGVkaXQnICU+PC9zcGFuPlxuICAgIDxpIGNsYXNzPVwiYmkgYmktcGVuY2lsIHRleHQtbXV0ZWQgbXMtMlwiPjwvaT5cbiAgPC9kaXY+XG4gIDxkaXYgJGlkPVwiZWRpdF9tb2RlXCIgc3R5bGU9XCJkaXNwbGF5OiBub25lO1wiPlxuICAgIDxkaXYgY2xhc3M9XCJpbnB1dC1ncm91cCBpbnB1dC1ncm91cC1zbVwiPlxuICAgICAgPGlucHV0IHR5cGU9XCJ0ZXh0XCIgY2xhc3M9XCJmb3JtLWNvbnRyb2xcIiAkaWQ9XCJpbnB1dFwiIC8+XG4gICAgICA8YnV0dG9uIGNsYXNzPVwiYnRuIGJ0bi1zdWNjZXNzXCIgdHlwZT1cImJ1dHRvblwiICRpZD1cInNhdmVfYnRuXCIgdGl0bGU9XCJTYXZlXCI+XG4gICAgICAgIDxpIGNsYXNzPVwiYmkgYmktY2hlY2stbGdcIj48L2k+XG4gICAgICA8L2J1dHRvbj5cbiAgICAgIDxidXR0b24gY2xhc3M9XCJidG4gYnRuLXNlY29uZGFyeVwiIHR5cGU9XCJidXR0b25cIiAkaWQ9XCJjYW5jZWxfYnRuXCIgdGl0bGU9XCJDYW5jZWxcIj5cbiAgICAgICAgPGkgY2xhc3M9XCJiaSBiaS14LWxnXCI+PC9pPlxuICAgICAgPC9idXR0b24+XG4gICAgPC9kaXY+XG4gIDwvZGl2PlxuPC9EZWZpbmU6SW5saW5lX0VkaXRfRmllbGQ+XG4iLCI8RGVmaW5lOklucHV0X1dpdGhfSWNvbiBjbGFzcz1cImlucHV0LWdyb3VwXCI+XG4gIDwlIGlmICh0aGlzLmFyZ3MuaWNvbl9wb3NpdGlvbiAhPT0gJ2VuZCcpIHsgJT5cbiAgICA8c3BhbiBjbGFzcz1cImlucHV0LWdyb3VwLXRleHRcIj5cbiAgICAgIDxpIGNsYXNzPVwiYmkgYmktPCU9IHRoaXMuYXJncy5pY29uIHx8ICdzZWFyY2gnICU+XCI+PC9pPlxuICAgIDwvc3Bhbj5cbiAgPCUgfSAlPlxuICA8aW5wdXRcbiAgICB0eXBlPVwiPCU9IHRoaXMuYXJncy50eXBlIHx8ICd0ZXh0JyAlPlwiXG4gICAgY2xhc3M9XCJmb3JtLWNvbnRyb2xcIlxuICAgIHBsYWNlaG9sZGVyPVwiPCU9IHRoaXMuYXJncy5wbGFjZWhvbGRlciB8fCAnJyAlPlwiXG4gICAgJGlkPVwiaW5wdXRcIlxuICAvPlxuICA8JSBpZiAodGhpcy5hcmdzLmljb25fcG9zaXRpb24gPT09ICdlbmQnKSB7ICU+XG4gICAgPHNwYW4gY2xhc3M9XCJpbnB1dC1ncm91cC10ZXh0XCI+XG4gICAgICA8aSBjbGFzcz1cImJpIGJpLTwlPSB0aGlzLmFyZ3MuaWNvbiB8fCAnc2VhcmNoJyAlPlwiPjwvaT5cbiAgICA8L3NwYW4+XG4gIDwlIH0gJT5cbjwvRGVmaW5lOklucHV0X1dpdGhfSWNvbj5cbiIsIjxEZWZpbmU6SW5wdXRfV2l0aF9WYWxpZGF0aW9uIGNsYXNzPVwibWItM1wiPlxuICA8JSBpZiAodGhpcy5hcmdzLmxhYmVsKSB7ICU+XG4gICAgPGxhYmVsIGNsYXNzPVwiZm9ybS1sYWJlbFwiICRpZD1cImxhYmVsXCI+XG4gICAgICA8JT0gdGhpcy5hcmdzLmxhYmVsICU+XG4gICAgICA8JSBpZiAodGhpcy5hcmdzLnJlcXVpcmVkKSB7ICU+PHNwYW4gY2xhc3M9XCJ0ZXh0LWRhbmdlclwiPio8L3NwYW4+PCUgfSAlPlxuICAgIDwvbGFiZWw+XG4gIDwlIH0gJT5cbiAgPGlucHV0XG4gICAgdHlwZT1cIjwlPSB0aGlzLmFyZ3MudHlwZSB8fCAndGV4dCcgJT5cIlxuICAgIGNsYXNzPVwiZm9ybS1jb250cm9sXCJcbiAgICBwbGFjZWhvbGRlcj1cIjwlPSB0aGlzLmFyZ3MucGxhY2Vob2xkZXIgfHwgJycgJT5cIlxuICAgICRpZD1cImlucHV0XCJcbiAgLz5cbiAgPGRpdiBjbGFzcz1cImludmFsaWQtZmVlZGJhY2tcIiAkaWQ9XCJlcnJvclwiPjwvZGl2PlxuICA8ZGl2IGNsYXNzPVwidmFsaWQtZmVlZGJhY2tcIiAkaWQ9XCJzdWNjZXNzXCI+PC9kaXY+XG4gIDwlIGlmICh0aGlzLmFyZ3MuaGVscCkgeyAlPlxuICAgIDxkaXYgY2xhc3M9XCJmb3JtLXRleHRcIj48JT0gdGhpcy5hcmdzLmhlbHAgJT48L2Rpdj5cbiAgPCUgfSAlPlxuPC9EZWZpbmU6SW5wdXRfV2l0aF9WYWxpZGF0aW9uPlxuIiwiPERlZmluZTpJbnB1dCB0YWc9XCJpbnB1dFwiIHR5cGU9XCJ0ZXh0XCIgY2xhc3M9XCJmb3JtLWNvbnRyb2xcIj5cbjwvRGVmaW5lOklucHV0PlxuIiwiPERlZmluZTpLYW5iYW5fQm9hcmQgY2xhc3M9XCJkLWZsZXggZ2FwLTNcIiBzdHlsZT1cIm92ZXJmbG93LXg6IGF1dG87XCI+XG4gIDwlIGlmIChPYmplY3Qua2V5cyh0aGlzLmRhdGEpLmxlbmd0aCA9PT0gMCkgeyAlPlxuICAgIDxkaXYgY2xhc3M9XCJ3LTEwMCB0ZXh0LWNlbnRlciBweS01XCI+XG4gICAgICA8U3Bpbm5lciAvPlxuICAgIDwvZGl2PlxuICA8JSB9IGVsc2UgeyAlPlxuICAgIDwlIGZvciAobGV0IGNvbHVtbiBvZiB0aGlzLmRhdGEuY29sdW1ucyB8fCBbXSkgeyAlPlxuICAgICAgPGRpdiBjbGFzcz1cImNhcmRcIiBzdHlsZT1cIm1pbi13aWR0aDogMzAwcHg7IG1heC13aWR0aDogMzAwcHg7XCIgZGF0YS1jb2x1bW4taWQ9XCI8JT0gY29sdW1uLmlkICU+XCI+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJjYXJkLWhlYWRlciBiZy1saWdodFwiPlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJkLWZsZXgganVzdGlmeS1jb250ZW50LWJldHdlZW4gYWxpZ24taXRlbXMtY2VudGVyXCI+XG4gICAgICAgICAgICA8aDYgY2xhc3M9XCJtYi0wXCI+PCU9IGNvbHVtbi50aXRsZSAlPjwvaDY+XG4gICAgICAgICAgICA8c3BhbiBjbGFzcz1cImJhZGdlIGJnLXNlY29uZGFyeVwiPjwlPSBjb2x1bW4uY2FyZHMubGVuZ3RoICU+PC9zcGFuPlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgPGRpdiBjbGFzcz1cImNhcmQtYm9keSBwLTJcIiBzdHlsZT1cIm1pbi1oZWlnaHQ6IDQwMHB4OyBtYXgtaGVpZ2h0OiA2MDBweDsgb3ZlcmZsb3cteTogYXV0bztcIiBkYXRhLWNvbHVtbi1jYXJkcz1cIjwlPSBjb2x1bW4uaWQgJT5cIj5cbiAgICAgICAgICA8JSBmb3IgKGxldCBjYXJkIG9mIGNvbHVtbi5jYXJkcykgeyAlPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNhcmQgbWItMlwiIGRyYWdnYWJsZT1cInRydWVcIiBkYXRhLWNhcmQtaWQ9XCI8JT0gY2FyZC5pZCAlPlwiPlxuICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY2FyZC1ib2R5IHAtM1wiPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmdy1ib2xkIG1iLTJcIj48JT0gY2FyZC50aXRsZSAlPjwvZGl2PlxuICAgICAgICAgICAgICAgIDwlIGlmIChjYXJkLmRlc2NyaXB0aW9uKSB7ICU+XG4gICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidGV4dC1tdXRlZCBzbWFsbCBtYi0yXCI+PCU9IGNhcmQuZGVzY3JpcHRpb24gJT48L2Rpdj5cbiAgICAgICAgICAgICAgICA8JSB9ICU+XG4gICAgICAgICAgICAgICAgPCUgaWYgKGNhcmQudGFncyAmJiBjYXJkLnRhZ3MubGVuZ3RoID4gMCkgeyAlPlxuICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1iLTJcIj5cbiAgICAgICAgICAgICAgICAgICAgPCUgZm9yIChsZXQgdGFnIG9mIGNhcmQudGFncykgeyAlPlxuICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiYmFkZ2UgYmctbGlnaHQgdGV4dC1kYXJrIG1lLTFcIj48JT0gdGFnICU+PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICA8JSB9ICU+XG4gICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8JSB9ICU+XG4gICAgICAgICAgICAgICAgPCUgaWYgKGNhcmQuYXNzaWduZWUpIHsgJT5cbiAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkLWZsZXggYWxpZ24taXRlbXMtY2VudGVyIGdhcC0yXCI+XG4gICAgICAgICAgICAgICAgICAgIDxBdmF0YXIgJG5hbWU9Y2FyZC5hc3NpZ25lZSAkc2l6ZT1cInhzXCIgLz5cbiAgICAgICAgICAgICAgICAgICAgPHNtYWxsIGNsYXNzPVwidGV4dC1tdXRlZFwiPjwlPSBjYXJkLmFzc2lnbmVlICU+PC9zbWFsbD5cbiAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDwlIH0gJT5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8JSB9ICU+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG4gICAgPCUgfSAlPlxuICA8JSB9ICU+XG48L0RlZmluZTpLYW5iYW5fQm9hcmQ+XG4iLCI8RGVmaW5lOkxpbmsgdGFnPVwiYVwiIGhyZWY9XCIjXCI+XG4gIDwlPSBjb250ZW50KCkgJT5cbjwvRGVmaW5lOkxpbms+XG4iLCI8RGVmaW5lOkxpc3QgY2xhc3M9XCJsaXN0LWdyb3VwIGxpc3QtZ3JvdXAtZmx1c2hcIj5cbiAgPCU9IGNvbnRlbnQoKSAlPlxuPC9EZWZpbmU6TGlzdD5cbiIsIjxEZWZpbmU6TG9hZGluZ19Ta2VsZXRvbiBjbGFzcz1cInBsYWNlaG9sZGVyLWdsb3dcIj5cbiAgPHNwYW4gY2xhc3M9XCJwbGFjZWhvbGRlciBjb2wtMTJcIj48L3NwYW4+XG4gIDxzcGFuIGNsYXNzPVwicGxhY2Vob2xkZXIgY29sLTEwXCI+PC9zcGFuPlxuICA8c3BhbiBjbGFzcz1cInBsYWNlaG9sZGVyIGNvbC04XCI+PC9zcGFuPlxuPC9EZWZpbmU6TG9hZGluZ19Ta2VsZXRvbj5cbiIsIjxEZWZpbmU6TWV0cmljX0NhcmQgY2xhc3M9XCJjYXJkICBoLTEwMFwiPlxuXG4gICAgPGRpdiBjbGFzcz1cImNhcmQtYm9keSBwLTRcIj5cbiAgICAgICAgPCU9IGNvbnRlbnQoKSAlPlxuICAgIDwvZGl2PlxuXG48L0RlZmluZTpNZXRyaWNfQ2FyZD5cbiIsIjxEZWZpbmU6TW9iaWxlX0hlYWRlciB0YWc9XCJoZWFkZXJcIiBjbGFzcz1cIm5hdmJhciBuYXZiYXItbGlnaHQgYmctbGlnaHQgZC1sZy1ub25lXCI+XG4gIDxkaXYgY2xhc3M9XCJjb250YWluZXItZmx1aWRcIj5cbiAgICA8YnV0dG9uIGNsYXNzPVwibmF2YmFyLXRvZ2dsZXJcIlxuICAgICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgICBkYXRhLWJzLXRvZ2dsZT1cIm9mZmNhbnZhc1wiXG4gICAgICAgICAgICBkYXRhLWJzLXRhcmdldD1cIiNtb2JpbGVTaWRlYmFyXCJcbiAgICAgICAgICAgIGFyaWEtY29udHJvbHM9XCJtb2JpbGVTaWRlYmFyXCI+XG4gICAgICA8c3BhbiBjbGFzcz1cIm5hdmJhci10b2dnbGVyLWljb25cIj48L3NwYW4+XG4gICAgPC9idXR0b24+XG4gICAgPHNwYW4gY2xhc3M9XCJuYXZiYXItYnJhbmQgbWItMCBoMVwiPlBTTTwvc3Bhbj5cbiAgICA8ZGl2IGNsYXNzPVwiZC1mbGV4IGFsaWduLWl0ZW1zLWNlbnRlciBnYXAtMlwiPlxuICAgICAgPCU9IGNvbnRlbnQoKSAlPlxuICAgIDwvZGl2PlxuICA8L2Rpdj5cbjwvRGVmaW5lOk1vYmlsZV9IZWFkZXI+XG4iLCI8RGVmaW5lOk1vZGFsX0RpYWxvZyBjbGFzcz1cIm1vZGFsIGZhZGVcIiB0YWJpbmRleD1cIi0xXCIgYXJpYS1oaWRkZW49XCJ0cnVlXCI+XG4gIDxkaXYgY2xhc3M9XCJtb2RhbC1kaWFsb2dcIj5cbiAgICA8ZGl2IGNsYXNzPVwibW9kYWwtY29udGVudFwiPlxuICAgICAgPGRpdiBjbGFzcz1cIm1vZGFsLWhlYWRlclwiPlxuICAgICAgICA8aDUgY2xhc3M9XCJtb2RhbC10aXRsZVwiICRpZD1cInRpdGxlXCI+PCU9IHRoaXMuYXJncy50aXRsZSB8fCAnTW9kYWwnICU+PC9oNT5cbiAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJidG4tY2xvc2VcIiBkYXRhLWJzLWRpc21pc3M9XCJtb2RhbFwiIGFyaWEtbGFiZWw9XCJDbG9zZVwiPjwvYnV0dG9uPlxuICAgICAgPC9kaXY+XG4gICAgICA8ZGl2IGNsYXNzPVwibW9kYWwtYm9keVwiICRpZD1cImJvZHlcIj5cbiAgICAgICAgPCU9IGNvbnRlbnQoKSAlPlxuICAgICAgPC9kaXY+XG4gICAgICA8ZGl2IGNsYXNzPVwibW9kYWwtZm9vdGVyXCIgJGlkPVwiZm9vdGVyXCI+XG4gICAgICAgIDxCdXR0b25fU2Vjb25kYXJ5IGRhdGEtYnMtZGlzbWlzcz1cIm1vZGFsXCI+Q2xvc2U8L0J1dHRvbl9TZWNvbmRhcnk+XG4gICAgICAgIDxCdXR0b25fUHJpbWFyeSAkaWQ9XCJjb25maXJtXCI+Q29uZmlybTwvQnV0dG9uX1ByaW1hcnk+XG4gICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbiAgPC9kaXY+XG48L0RlZmluZTpNb2RhbF9EaWFsb2c+XG4iLCI8RGVmaW5lOk11bHRpX1NlbGVjdCBjbGFzcz1cImRyb3Bkb3duXCI+XG4gIDwlIGlmICh0aGlzLmFyZ3MubGFiZWwpIHsgJT5cbiAgICA8bGFiZWwgY2xhc3M9XCJmb3JtLWxhYmVsXCI+PCU9IHRoaXMuYXJncy5sYWJlbCAlPjwvbGFiZWw+XG4gIDwlIH0gJT5cbiAgPGJ1dHRvbiBjbGFzcz1cImJ0biBidG4tc2Vjb25kYXJ5IGRyb3Bkb3duLXRvZ2dsZSB3LTEwMCB0ZXh0LXN0YXJ0XCIgdHlwZT1cImJ1dHRvblwiIGRhdGEtYnMtdG9nZ2xlPVwiZHJvcGRvd25cIiBhcmlhLWV4cGFuZGVkPVwiZmFsc2VcIiAkaWQ9XCJidXR0b25cIj5cbiAgICA8c3BhbiAkaWQ9XCJzZWxlY3RlZF90ZXh0XCI+PCU9IHRoaXMuYXJncy5wbGFjZWhvbGRlciB8fCAnU2VsZWN0IG9wdGlvbnMnICU+PC9zcGFuPlxuICA8L2J1dHRvbj5cbiAgPGRpdiBjbGFzcz1cImRyb3Bkb3duLW1lbnUgdy0xMDBcIiAkaWQ9XCJtZW51XCI+XG4gICAgPGRpdiBjbGFzcz1cInB4LTMgcHktMlwiPlxuICAgICAgPGlucHV0IHR5cGU9XCJzZWFyY2hcIiBjbGFzcz1cImZvcm0tY29udHJvbCBmb3JtLWNvbnRyb2wtc21cIiBwbGFjZWhvbGRlcj1cIlNlYXJjaC4uLlwiICRpZD1cInNlYXJjaFwiPlxuICAgIDwvZGl2PlxuICAgIDxkaXYgY2xhc3M9XCJkcm9wZG93bi1kaXZpZGVyXCI+PC9kaXY+XG4gICAgPGRpdiAkaWQ9XCJvcHRpb25zXCIgc3R5bGU9XCJtYXgtaGVpZ2h0OiAyNTBweDsgb3ZlcmZsb3cteTogYXV0bztcIj5cbiAgICAgIDwhLS0gT3B0aW9ucyBwb3B1bGF0ZWQgdmlhIEphdmFTY3JpcHQgLS0+XG4gICAgPC9kaXY+XG4gICAgPGRpdiBjbGFzcz1cImRyb3Bkb3duLWRpdmlkZXJcIj48L2Rpdj5cbiAgICA8ZGl2IGNsYXNzPVwicHgtMyBweS0yIGQtZmxleCBqdXN0aWZ5LWNvbnRlbnQtYmV0d2VlblwiPlxuICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJidG4gYnRuLWxpbmsgYnRuLXNtIHAtMFwiICRpZD1cImNsZWFyX2FsbFwiPkNsZWFyIEFsbDwvYnV0dG9uPlxuICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJidG4gYnRuLWxpbmsgYnRuLXNtIHAtMFwiICRpZD1cInNlbGVjdF9hbGxcIj5TZWxlY3QgQWxsPC9idXR0b24+XG4gICAgPC9kaXY+XG4gIDwvZGl2PlxuPC9EZWZpbmU6TXVsdGlfU2VsZWN0PlxuIiwiPERlZmluZTpOb3RpZmljYXRpb25fQmFkZ2UgdGFnPVwic3BhblwiIGNsYXNzPVwicG9zaXRpb24tcmVsYXRpdmVcIj5cbiAgPCU9IGNvbnRlbnQoKSAlPlxuICA8c3BhbiBjbGFzcz1cInBvc2l0aW9uLWFic29sdXRlIHRvcC0wIHN0YXJ0LTEwMCB0cmFuc2xhdGUtbWlkZGxlIGJhZGdlIHJvdW5kZWQtcGlsbCBiZy1kYW5nZXJcIlxuICAgICAgICAkaWQ9XCJjb3VudFwiXG4gICAgICAgIHN0eWxlPVwiPCU9ICh0aGlzLmFyZ3MuY291bnQgPiAwID8gJycgOiAnZGlzcGxheTogbm9uZTsnKSAlPlwiPlxuICAgIDwlPSB0aGlzLmFyZ3MuY291bnQgfHwgMCAlPlxuICA8L3NwYW4+XG48L0RlZmluZTpOb3RpZmljYXRpb25fQmFkZ2U+XG4iLCI8RGVmaW5lOk5vdGlmaWNhdGlvbl9Ecm9wZG93biBjbGFzcz1cImRyb3Bkb3duXCI+XG4gIDxidXR0b24gY2xhc3M9XCJidG4gYnRuLWxpbmsgcG9zaXRpb24tcmVsYXRpdmVcIlxuICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgIGRhdGEtYnMtdG9nZ2xlPVwiZHJvcGRvd25cIlxuICAgICAgICAgIGFyaWEtZXhwYW5kZWQ9XCJmYWxzZVwiPlxuICAgIDxJY29uICRuYW1lPVwiYmVsbFwiIC8+XG4gICAgPCUgaWYgKHRoaXMuYXJncy51bnJlYWRfY291bnQgPiAwKSB7ICU+XG4gICAgICA8c3BhbiBjbGFzcz1cInBvc2l0aW9uLWFic29sdXRlIHRvcC0wIHN0YXJ0LTEwMCB0cmFuc2xhdGUtbWlkZGxlIGJhZGdlIHJvdW5kZWQtcGlsbCBiZy1kYW5nZXJcIj5cbiAgICAgICAgPCU9IHRoaXMuYXJncy51bnJlYWRfY291bnQgJT5cbiAgICAgIDwvc3Bhbj5cbiAgICA8JSB9ICU+XG4gIDwvYnV0dG9uPlxuICA8ZGl2IGNsYXNzPVwiZHJvcGRvd24tbWVudSBkcm9wZG93bi1tZW51LWVuZFwiIHN0eWxlPVwid2lkdGg6IDMyMHB4O1wiPlxuICAgIDxkaXYgY2xhc3M9XCJkcm9wZG93bi1oZWFkZXIgZC1mbGV4IGp1c3RpZnktY29udGVudC1iZXR3ZWVuIGFsaWduLWl0ZW1zLWNlbnRlclwiPlxuICAgICAgPHNwYW4gY2xhc3M9XCJmdy1ib2xkXCI+Tm90aWZpY2F0aW9uczwvc3Bhbj5cbiAgICAgIDxhIGhyZWY9XCIjXCIgY2xhc3M9XCJzbWFsbFwiPk1hcmsgYWxsIHJlYWQ8L2E+XG4gICAgPC9kaXY+XG4gICAgPGRpdiBjbGFzcz1cImRyb3Bkb3duLWRpdmlkZXJcIj48L2Rpdj5cbiAgICA8ZGl2IGNsYXNzPVwib3ZlcmZsb3ctYXV0b1wiIHN0eWxlPVwibWF4LWhlaWdodDogNDAwcHg7XCI+XG4gICAgICA8JT0gY29udGVudCgpICU+XG4gICAgPC9kaXY+XG4gIDwvZGl2PlxuPC9EZWZpbmU6Tm90aWZpY2F0aW9uX0Ryb3Bkb3duPlxuIiwiPERlZmluZTpPdmVyZHVlX0luZGljYXRvciB0YWc9XCJzcGFuXCIgY2xhc3M9XCJiYWRnZSBiZy13YXJuaW5nIHRleHQtZGFyayBkLWJsb2NrIG10LTFcIj5cbiAgPCU9IGNvbnRlbnQoKSAlPlxuPC9EZWZpbmU6T3ZlcmR1ZV9JbmRpY2F0b3I+XG4iLCI8RGVmaW5lOlBhZ2VfSGVhZGVyX0xlZnQ+XG4gIDxkaXY+XG4gICAgPCU9IGNvbnRlbnQoKSAlPlxuICA8L2Rpdj5cbjwvRGVmaW5lOlBhZ2VfSGVhZGVyX0xlZnQ+XG4iLCI8RGVmaW5lOlBhZ2VfSGVhZGVyX1JpZ2h0IGNsYXNzPVwiZC1mbGV4IGdhcC0yXCI+XG4gIDwlPSBjb250ZW50KCkgJT5cbjwvRGVmaW5lOlBhZ2VfSGVhZGVyX1JpZ2h0PlxuIiwiPERlZmluZTpQYWdlX0hlYWRlciBjbGFzcz1cImQtZmxleCBqdXN0aWZ5LWNvbnRlbnQtYmV0d2VlbiBhbGlnbi1pdGVtcy1jZW50ZXIgbWItNFwiPlxuICA8JT0gY29udGVudCgpICU+XG48L0RlZmluZTpQYWdlX0hlYWRlcj5cbiIsIjxEZWZpbmU6UGFnZV9TZWN0aW9uIGNsYXNzPVwibWItNFwiPlxuICA8JT0gY29udGVudCgpICU+XG48L0RlZmluZTpQYWdlX1NlY3Rpb24+XG4iLCI8RGVmaW5lOlBhZ2VfU3VidGl0bGUgdGFnPVwicFwiIGNsYXNzPVwidGV4dC1tdXRlZCBtYi0wXCI+XG4gIDwlPSBjb250ZW50KCkgJT5cbjwvRGVmaW5lOlBhZ2VfU3VidGl0bGU+XG4iLCI8RGVmaW5lOlBhZ2VfVGl0bGUgdGFnPVwiaDFcIiBjbGFzcz1cImgyIG1iLTFcIj5cbiAgPCU9IGNvbnRlbnQoKSAlPlxuPC9EZWZpbmU6UGFnZV9UaXRsZT5cbiIsIjxEZWZpbmU6UGFnZT5cbiAgPCU9IGNvbnRlbnQoKSAlPlxuPC9EZWZpbmU6UGFnZT5cbiIsIjxEZWZpbmU6UGFnaW5hdGlvbl9Db250cm9scyB0YWc9XCJuYXZcIiBhcmlhLWxhYmVsPVwiVGFibGUgcGFnaW5hdGlvblwiPlxuICA8dWwgY2xhc3M9XCJwYWdpbmF0aW9uIHBhZ2luYXRpb24tc20gbWItMFwiPlxuICAgIDwlPSBjb250ZW50KCkgJT5cbiAgPC91bD5cbjwvRGVmaW5lOlBhZ2luYXRpb25fQ29udHJvbHM+XG4iLCI8RGVmaW5lOlBhZ2luYXRpb25fSW5mbz5cbiAgPGRpdj5cbiAgICA8c21hbGwgY2xhc3M9XCJ0ZXh0LW11dGVkXCI+PCU9IGNvbnRlbnQoKSAlPjwvc21hbGw+XG4gIDwvZGl2PlxuPC9EZWZpbmU6UGFnaW5hdGlvbl9JbmZvPlxuIiwiPERlZmluZTpQb3BvdmVyIHRhZz1cImJ1dHRvblwiIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cImJ0biBidG4tc2Vjb25kYXJ5XCIgZGF0YS1icy10b2dnbGU9XCJwb3BvdmVyXCI+XG4gIDwlPSB0aGlzLmFyZ3MubGFiZWwgfHwgJ0luZm8nICU+XG48L0RlZmluZTpQb3BvdmVyPlxuIiwiPERlZmluZTpQcm9ncmVzc19CYXIgY2xhc3M9XCJwcm9ncmVzc1wiPlxuICA8ZGl2IGNsYXNzPVwicHJvZ3Jlc3MtYmFyXCJcbiAgICAgICByb2xlPVwicHJvZ3Jlc3NiYXJcIlxuICAgICAgIHN0eWxlPVwid2lkdGg6IDwlPSB0aGlzLmFyZ3MudmFsdWUgfHwgMCAlPiVcIlxuICAgICAgIGFyaWEtdmFsdWVub3c9XCI8JT0gdGhpcy5hcmdzLnZhbHVlIHx8IDAgJT5cIlxuICAgICAgIGFyaWEtdmFsdWVtaW49XCIwXCJcbiAgICAgICBhcmlhLXZhbHVlbWF4PVwiMTAwXCJcbiAgICAgICAkaWQ9XCJiYXJcIj5cbiAgPC9kaXY+XG48L0RlZmluZTpQcm9ncmVzc19CYXI+XG4iLCI8RGVmaW5lOlJhZGlvX0J1dHRvbiB0YWc9XCJpbnB1dFwiIHR5cGU9XCJyYWRpb1wiIGNsYXNzPVwiZm9ybS1jaGVjay1pbnB1dFwiPlxuPC9EZWZpbmU6UmFkaW9fQnV0dG9uPlxuIiwiPERlZmluZTpSZWNvcmRfQ291bnRfRGlzcGxheSB0YWc9XCJzbWFsbFwiIGNsYXNzPVwidGV4dC1tdXRlZFwiPlxuICA8JT0gY29udGVudCgpICU+XG48L0RlZmluZTpSZWNvcmRfQ291bnRfRGlzcGxheT5cbiIsIjxEZWZpbmU6UmljaF9UZXh0X0VkaXRvciBjbGFzcz1cIm1iLTNcIj5cbiAgPCUgaWYgKHRoaXMuYXJncy5sYWJlbCkgeyAlPlxuICAgIDxsYWJlbCBjbGFzcz1cImZvcm0tbGFiZWxcIj48JT0gdGhpcy5hcmdzLmxhYmVsICU+PC9sYWJlbD5cbiAgPCUgfSAlPlxuICA8ZGl2IGNsYXNzPVwiYm9yZGVyIHJvdW5kZWRcIj5cbiAgICA8ZGl2IGNsYXNzPVwiYm9yZGVyLWJvdHRvbSBiZy1saWdodCBwLTJcIiAkaWQ9XCJ0b29sYmFyXCI+XG4gICAgICA8ZGl2IGNsYXNzPVwiYnRuLWdyb3VwIGJ0bi1ncm91cC1zbSBtZS0yXCIgcm9sZT1cImdyb3VwXCI+XG4gICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwiYnRuIGJ0bi1zZWNvbmRhcnlcIiBkYXRhLWNvbW1hbmQ9XCJib2xkXCIgdGl0bGU9XCJCb2xkXCI+XG4gICAgICAgICAgPGkgY2xhc3M9XCJiaSBiaS10eXBlLWJvbGRcIj48L2k+XG4gICAgICAgIDwvYnV0dG9uPlxuICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cImJ0biBidG4tc2Vjb25kYXJ5XCIgZGF0YS1jb21tYW5kPVwiaXRhbGljXCIgdGl0bGU9XCJJdGFsaWNcIj5cbiAgICAgICAgICA8aSBjbGFzcz1cImJpIGJpLXR5cGUtaXRhbGljXCI+PC9pPlxuICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJidG4gYnRuLXNlY29uZGFyeVwiIGRhdGEtY29tbWFuZD1cInVuZGVybGluZVwiIHRpdGxlPVwiVW5kZXJsaW5lXCI+XG4gICAgICAgICAgPGkgY2xhc3M9XCJiaSBiaS10eXBlLXVuZGVybGluZVwiPjwvaT5cbiAgICAgICAgPC9idXR0b24+XG4gICAgICA8L2Rpdj5cbiAgICAgIDxkaXYgY2xhc3M9XCJidG4tZ3JvdXAgYnRuLWdyb3VwLXNtIG1lLTJcIiByb2xlPVwiZ3JvdXBcIj5cbiAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJidG4gYnRuLXNlY29uZGFyeVwiIGRhdGEtY29tbWFuZD1cImluc2VydFVub3JkZXJlZExpc3RcIiB0aXRsZT1cIkJ1bGxldCBMaXN0XCI+XG4gICAgICAgICAgPGkgY2xhc3M9XCJiaSBiaS1saXN0LXVsXCI+PC9pPlxuICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJidG4gYnRuLXNlY29uZGFyeVwiIGRhdGEtY29tbWFuZD1cImluc2VydE9yZGVyZWRMaXN0XCIgdGl0bGU9XCJOdW1iZXJlZCBMaXN0XCI+XG4gICAgICAgICAgPGkgY2xhc3M9XCJiaSBiaS1saXN0LW9sXCI+PC9pPlxuICAgICAgICA8L2J1dHRvbj5cbiAgICAgIDwvZGl2PlxuICAgICAgPGRpdiBjbGFzcz1cImJ0bi1ncm91cCBidG4tZ3JvdXAtc20gbWUtMlwiIHJvbGU9XCJncm91cFwiPlxuICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cImJ0biBidG4tc2Vjb25kYXJ5XCIgZGF0YS1jb21tYW5kPVwianVzdGlmeUxlZnRcIiB0aXRsZT1cIkFsaWduIExlZnRcIj5cbiAgICAgICAgICA8aSBjbGFzcz1cImJpIGJpLXRleHQtbGVmdFwiPjwvaT5cbiAgICAgICAgPC9idXR0b24+XG4gICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwiYnRuIGJ0bi1zZWNvbmRhcnlcIiBkYXRhLWNvbW1hbmQ9XCJqdXN0aWZ5Q2VudGVyXCIgdGl0bGU9XCJBbGlnbiBDZW50ZXJcIj5cbiAgICAgICAgICA8aSBjbGFzcz1cImJpIGJpLXRleHQtY2VudGVyXCI+PC9pPlxuICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJidG4gYnRuLXNlY29uZGFyeVwiIGRhdGEtY29tbWFuZD1cImp1c3RpZnlSaWdodFwiIHRpdGxlPVwiQWxpZ24gUmlnaHRcIj5cbiAgICAgICAgICA8aSBjbGFzcz1cImJpIGJpLXRleHQtcmlnaHRcIj48L2k+XG4gICAgICAgIDwvYnV0dG9uPlxuICAgICAgPC9kaXY+XG4gICAgICA8ZGl2IGNsYXNzPVwiYnRuLWdyb3VwIGJ0bi1ncm91cC1zbVwiIHJvbGU9XCJncm91cFwiPlxuICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cImJ0biBidG4tc2Vjb25kYXJ5XCIgZGF0YS1jb21tYW5kPVwiY3JlYXRlTGlua1wiIHRpdGxlPVwiSW5zZXJ0IExpbmtcIj5cbiAgICAgICAgICA8aSBjbGFzcz1cImJpIGJpLWxpbmtcIj48L2k+XG4gICAgICAgIDwvYnV0dG9uPlxuICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cImJ0biBidG4tc2Vjb25kYXJ5XCIgZGF0YS1jb21tYW5kPVwidW5saW5rXCIgdGl0bGU9XCJSZW1vdmUgTGlua1wiPlxuICAgICAgICAgIDxpIGNsYXNzPVwiYmkgYmktbGluay00NWRlZ1wiPjwvaT5cbiAgICAgICAgPC9idXR0b24+XG4gICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbiAgICA8ZGl2XG4gICAgICBjb250ZW50ZWRpdGFibGU9XCJ0cnVlXCJcbiAgICAgIGNsYXNzPVwicC0zXCJcbiAgICAgIHN0eWxlPVwibWluLWhlaWdodDogMjAwcHg7IG1heC1oZWlnaHQ6IDQwMHB4OyBvdmVyZmxvdy15OiBhdXRvO1wiXG4gICAgICAkaWQ9XCJlZGl0b3JcIlxuICAgID48JT0gdGhpcy5hcmdzLnZhbHVlIHx8ICcnICU+PC9kaXY+XG4gIDwvZGl2PlxuICA8JSBpZiAodGhpcy5hcmdzLmhlbHApIHsgJT5cbiAgICA8ZGl2IGNsYXNzPVwiZm9ybS10ZXh0XCI+PCU9IHRoaXMuYXJncy5oZWxwICU+PC9kaXY+XG4gIDwlIH0gJT5cbjwvRGVmaW5lOlJpY2hfVGV4dF9FZGl0b3I+XG4iLCI8RGVmaW5lOlJvd19BY3Rpb25fTWVudSBjbGFzcz1cImRyb3Bkb3duXCI+XG4gIDxidXR0b24gY2xhc3M9XCJidG4gYnRuLXNtIGJ0bi1saW5rIHRleHQtbXV0ZWQgZHJvcGRvd24tdG9nZ2xlXCJcbiAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICBkYXRhLWJzLXRvZ2dsZT1cImRyb3Bkb3duXCJcbiAgICAgICAgICBhcmlhLWV4cGFuZGVkPVwiZmFsc2VcIj5cbiAgICDii65cbiAgPC9idXR0b24+XG4gIDx1bCBjbGFzcz1cImRyb3Bkb3duLW1lbnUgZHJvcGRvd24tbWVudS1lbmRcIiAkaWQ9XCJtZW51XCI+XG4gICAgPCU9IGNvbnRlbnQoKSAlPlxuICA8L3VsPlxuPC9EZWZpbmU6Um93X0FjdGlvbl9NZW51PlxuIiwiPCUtLVxuICBTYW1wbGUgRGF0YWdyaWQgQ29tcG9uZW50XG4gIERlbW9uc3RyYXRlcyBhIGZ1bGwtZmVhdHVyZWQgZGF0YSB0YWJsZSB3aXRoOlxuICAtIFNlbGVjdGFibGUgcm93c1xuICAtIENvbHVtbiBoZWFkZXJzXG4gIC0gQWN0aW9uIGJ1dHRvbnNcbiAgLSBQYWdpbmF0aW9uXG4gIC0gU3RhdHVzIGJhZGdlc1xuICAtIFVzaW5nIGxvb3BzIHRvIGF2b2lkIHJlcGV0aXRpb25cbi0tJT5cblxuPERlZmluZTpTYW1wbGVfRGF0YWdyaWRfQ29tcG9uZW50IGNsYXNzPVwiY2FyZFwiPlxuICA8JS0tIENhcmQgSGVhZGVyIHdpdGggVGl0bGUgYW5kIENvdW50IC0tJT5cbiAgPGRpdiBjbGFzcz1cImNhcmQtaGVhZGVyIGJnLWxpZ2h0XCI+XG4gICAgPGRpdiBjbGFzcz1cImQtZmxleCBqdXN0aWZ5LWNvbnRlbnQtYmV0d2VlbiBhbGlnbi1pdGVtcy1jZW50ZXJcIj5cbiAgICAgIDxoNSBjbGFzcz1cIm1iLTBcIj48JT0gdGhpcy5hcmdzLnRpdGxlIHx8ICdEYXRhIFRhYmxlJyAlPjwvaDU+XG4gICAgICA8c21hbGwgY2xhc3M9XCJ0ZXh0LW11dGVkXCI+XG4gICAgICAgIFNob3dpbmcgPCU9IHRoaXMuYXJncy5zaG93aW5nIHx8IDEwICU+IG9mIDwlPSB0aGlzLmFyZ3MudG90YWwgfHwgMTAwICU+IDwlPSB0aGlzLmFyZ3MuZW50aXR5X25hbWUgfHwgJ2l0ZW1zJyAlPlxuICAgICAgPC9zbWFsbD5cbiAgICA8L2Rpdj5cbiAgPC9kaXY+XG5cbiAgPCUtLSBUYWJsZSAtLSU+XG4gIDxkaXYgY2xhc3M9XCJjYXJkLWJvZHkgcC0wXCI+XG4gICAgPGRpdiBjbGFzcz1cInRhYmxlLXJlc3BvbnNpdmVcIj5cbiAgICAgIDx0YWJsZSBjbGFzcz1cInRhYmxlIHRhYmxlLWhvdmVyIG1iLTBcIj5cbiAgICAgICAgPCUtLSBUYWJsZSBIZWFkZXIgLS0lPlxuICAgICAgICA8dGhlYWQ+XG4gICAgICAgICAgPHRyPlxuICAgICAgICAgICAgPCUgaWYgKHRoaXMuYXJncy5zZWxlY3RhYmxlKTogJT5cbiAgICAgICAgICAgICAgPHRoIHN0eWxlPVwid2lkdGg6IDQwcHg7XCI+XG4gICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9XCJjaGVja2JveFwiIGNsYXNzPVwiZm9ybS1jaGVjay1pbnB1dFwiICRpZD1cInNlbGVjdF9hbGxcIiAvPlxuICAgICAgICAgICAgICA8L3RoPlxuICAgICAgICAgICAgPCUgZW5kaWY7ICU+XG5cbiAgICAgICAgICAgIDwlLS0gQ29sdW1uIEhlYWRlcnMgKGZyb20gYXJncy5jb2x1bW5zIGFycmF5KSAtLSU+XG4gICAgICAgICAgICA8JSBpZiAodGhpcy5hcmdzLmNvbHVtbnMgJiYgdGhpcy5hcmdzLmNvbHVtbnMubGVuZ3RoID4gMCkgeyAlPlxuICAgICAgICAgICAgICA8JSBmb3IgKGxldCBjb2x1bW4gb2YgdGhpcy5hcmdzLmNvbHVtbnMpIHsgJT5cbiAgICAgICAgICAgICAgICA8dGggc3R5bGU9XCI8JT0gKGNvbHVtbi53aWR0aCA/ICd3aWR0aDogJytjb2x1bW4ud2lkdGggOiAnJykgJT5cIj5cbiAgICAgICAgICAgICAgICAgIDwlPSBjb2x1bW4ubGFiZWwgJT5cbiAgICAgICAgICAgICAgICA8L3RoPlxuICAgICAgICAgICAgICA8JSB9ICU+XG4gICAgICAgICAgICA8JSB9IGVsc2UgeyAlPlxuICAgICAgICAgICAgICA8JS0tIERlZmF1bHQgY29sdW1ucyBpZiBub25lIHNwZWNpZmllZCAtLSU+XG4gICAgICAgICAgICAgIDx0aD5JRDwvdGg+XG4gICAgICAgICAgICAgIDx0aD5OYW1lPC90aD5cbiAgICAgICAgICAgICAgPHRoPkNvbXBhbnk8L3RoPlxuICAgICAgICAgICAgICA8dGg+RW1haWw8L3RoPlxuICAgICAgICAgICAgICA8dGg+UGhvbmU8L3RoPlxuICAgICAgICAgICAgICA8dGg+U3RhdHVzPC90aD5cbiAgICAgICAgICAgICAgPHRoPkNyZWF0ZWQ8L3RoPlxuICAgICAgICAgICAgICA8dGggc3R5bGU9XCJ3aWR0aDogMTAwcHg7XCI+QWN0aW9uczwvdGg+XG4gICAgICAgICAgICA8JSB9ICU+XG4gICAgICAgICAgPC90cj5cbiAgICAgICAgPC90aGVhZD5cblxuICAgICAgICA8JS0tIFRhYmxlIEJvZHkgLS0lPlxuICAgICAgICA8dGJvZHk+XG4gICAgICAgICAgPCUtLSBDaGVjayBpZiB3ZSBoYXZlIHJlYWwgZGF0YSBsb2FkZWQgLS0lPlxuICAgICAgICAgIDwlIGlmIChPYmplY3Qua2V5cyh0aGlzLmRhdGEpLmxlbmd0aCA9PT0gMCkgeyAlPlxuICAgICAgICAgICAgPCUtLSBMb2FkaW5nIHN0YXRlIC0gZ2VuZXJhdGUgcGxhY2Vob2xkZXIgcm93cyAtLSU+XG4gICAgICAgICAgICA8JSBmb3IgKGxldCBpID0gMDsgaSA8ICh0aGlzLmFyZ3MucGxhY2Vob2xkZXJfcm93cyB8fCAxMCk7IGkrKykgeyAlPlxuICAgICAgICAgICAgICA8dHI+XG4gICAgICAgICAgICAgICAgPCUgaWYgKHRoaXMuYXJncy5zZWxlY3RhYmxlKSB7ICU+XG4gICAgICAgICAgICAgICAgICA8dGQ+PGlucHV0IHR5cGU9XCJjaGVja2JveFwiIGNsYXNzPVwiZm9ybS1jaGVjay1pbnB1dFwiIGRpc2FibGVkIC8+PC90ZD5cbiAgICAgICAgICAgICAgICA8JSB9ICU+XG4gICAgICAgICAgICAgICAgPCUgZm9yIChsZXQgaiA9IDA7IGogPCAodGhpcy5hcmdzLmNvbHVtbnMgPyB0aGlzLmFyZ3MuY29sdW1ucy5sZW5ndGggOiA4KTsgaisrKSB7ICU+XG4gICAgICAgICAgICAgICAgICA8dGQ+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJwbGFjZWhvbGRlci1nbG93XCI+XG4gICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJwbGFjZWhvbGRlciBjb2wtPCU9IE1hdGguZmxvb3IoTWF0aC5yYW5kb20oKSAqIDgpICsgNCAlPlwiPjwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgICAgIDwlIH0gJT5cbiAgICAgICAgICAgICAgPC90cj5cbiAgICAgICAgICAgIDwlIH0gJT5cbiAgICAgICAgICA8JSB9IGVsc2UgaWYgKHRoaXMuZGF0YS5yb3dzICYmIHRoaXMuZGF0YS5yb3dzLmxlbmd0aCA+IDApIHsgJT5cbiAgICAgICAgICAgIDwlLS0gUmVhbCBkYXRhIHJvd3MgLS0lPlxuICAgICAgICAgICAgPCUgZm9yIChsZXQgcm93IG9mIHRoaXMuZGF0YS5yb3dzKSB7ICU+XG4gICAgICAgICAgICAgIDx0cj5cbiAgICAgICAgICAgICAgICA8JSBpZiAodGhpcy5hcmdzLnNlbGVjdGFibGUpIHsgJT5cbiAgICAgICAgICAgICAgICAgIDx0ZD48aW5wdXQgdHlwZT1cImNoZWNrYm94XCIgY2xhc3M9XCJmb3JtLWNoZWNrLWlucHV0XCIgZGF0YS1pZD1cIjwlPSByb3cuaWQgJT5cIiAvPjwvdGQ+XG4gICAgICAgICAgICAgICAgPCUgfSAlPlxuXG4gICAgICAgICAgICAgICAgPCUtLSBSZW5kZXIgY2VsbHMgYmFzZWQgb24gY29sdW1ucyBkZWZpbml0aW9uIC0tJT5cbiAgICAgICAgICAgICAgICA8JSBpZiAodGhpcy5hcmdzLmNvbHVtbnMpIHsgJT5cbiAgICAgICAgICAgICAgICAgIDwlIGZvciAobGV0IGNvbHVtbiBvZiB0aGlzLmFyZ3MuY29sdW1ucykgeyAlPlxuICAgICAgICAgICAgICAgICAgICA8dGQ+XG4gICAgICAgICAgICAgICAgICAgICAgPCUgaWYgKGNvbHVtbi50eXBlID09PSAnYmFkZ2UnKSB7ICU+XG4gICAgICAgICAgICAgICAgICAgICAgICA8JS0tIFJlbmRlciBhcyBiYWRnZSAtLSU+XG4gICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImJhZGdlIGJnLTwlPSByb3dbY29sdW1uLmZpZWxkICsgJ19jb2xvciddIHx8ICdzZWNvbmRhcnknICU+XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDwlPSByb3dbY29sdW1uLmZpZWxkXSAlPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgIDwlIH0gZWxzZSBpZiAoY29sdW1uLnR5cGUgPT09ICdhY3Rpb25zJykgeyAlPlxuICAgICAgICAgICAgICAgICAgICAgICAgPCUtLSBBY3Rpb24gYnV0dG9ucyAtLSU+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiYnRuLWdyb3VwIGJ0bi1ncm91cC1zbVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICA8JSBpZiAodGhpcy5hcmdzLnZpZXdfdXJsKSB7ICU+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGEgaHJlZj1cIjwlPSB0aGlzLmFyZ3Mudmlld191cmwucmVwbGFjZSgne2lkfScsIHJvdy5pZCkgJT5cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiYnRuIGJ0bi1wcmltYXJ5XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aXRsZT1cIlZpZXdcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpIGNsYXNzPVwiYmkgYmktZXllXCI+PC9pPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvYT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPCUgfSAlPlxuICAgICAgICAgICAgICAgICAgICAgICAgICA8JSBpZiAodGhpcy5hcmdzLmVkaXRfdXJsKSB7ICU+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGEgaHJlZj1cIjwlPSB0aGlzLmFyZ3MuZWRpdF91cmwucmVwbGFjZSgne2lkfScsIHJvdy5pZCkgJT5cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiYnRuIGJ0bi1zZWNvbmRhcnlcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRpdGxlPVwiRWRpdFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGkgY2xhc3M9XCJiaSBiaS1wZW5jaWxcIj48L2k+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9hPlxuICAgICAgICAgICAgICAgICAgICAgICAgICA8JSB9ICU+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDwlIGlmICh0aGlzLmFyZ3MuYWxsb3dfZGVsZXRlKSB7ICU+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cImJ0biBidG4tZGFuZ2VyXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEtaWQ9XCI8JT0gcm93LmlkICU+XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICRpZD1cImRlbGV0ZV9idXR0b25cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGl0bGU9XCJEZWxldGVcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpIGNsYXNzPVwiYmkgYmktdHJhc2hcIj48L2k+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDwlIH0gJT5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgIDwlIH0gZWxzZSB7ICU+XG4gICAgICAgICAgICAgICAgICAgICAgICA8JS0tIFJlZ3VsYXIgdGV4dCBjZWxsIC0tJT5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwlPSByb3dbY29sdW1uLmZpZWxkXSAlPlxuICAgICAgICAgICAgICAgICAgICAgIDwlIH0gJT5cbiAgICAgICAgICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgICAgICAgIDwlIH0gJT5cbiAgICAgICAgICAgICAgICA8JSB9IGVsc2UgeyAlPlxuICAgICAgICAgICAgICAgICAgPCUtLSBEZWZhdWx0IGNlbGwgcmVuZGVyaW5nIHdpdGhvdXQgY29sdW1uIGRlZmluaXRpb25zIC0tJT5cbiAgICAgICAgICAgICAgICAgIDx0ZD48JT0gcm93LmlkICU+PC90ZD5cbiAgICAgICAgICAgICAgICAgIDx0ZD48JT0gcm93Lm5hbWUgJT48L3RkPlxuICAgICAgICAgICAgICAgICAgPHRkPjwlPSByb3cuY29tcGFueSAlPjwvdGQ+XG4gICAgICAgICAgICAgICAgICA8dGQ+PCU9IHJvdy5lbWFpbCAlPjwvdGQ+XG4gICAgICAgICAgICAgICAgICA8dGQ+PCU9IHJvdy5waG9uZSAlPjwvdGQ+XG4gICAgICAgICAgICAgICAgICA8dGQ+XG4gICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiYmFkZ2UgYmctPCU9IHJvdy5zdGF0dXNfY29sb3IgfHwgJ3N1Y2Nlc3MnICU+XCI+XG4gICAgICAgICAgICAgICAgICAgICAgPCU9IHJvdy5zdGF0dXMgJT5cbiAgICAgICAgICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgICAgICAgIDx0ZD48JT0gcm93LmNyZWF0ZWQgJT48L3RkPlxuICAgICAgICAgICAgICAgICAgPHRkPlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiYnRuLWdyb3VwIGJ0bi1ncm91cC1zbVwiPlxuICAgICAgICAgICAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJidG4gYnRuLXByaW1hcnlcIiB0aXRsZT1cIlZpZXdcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxpIGNsYXNzPVwiYmkgYmktZXllXCI+PC9pPlxuICAgICAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJidG4gYnRuLXNlY29uZGFyeVwiIHRpdGxlPVwiRWRpdFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGkgY2xhc3M9XCJiaSBiaS1wZW5jaWxcIj48L2k+XG4gICAgICAgICAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cImJ0biBidG4tZGFuZ2VyXCIgdGl0bGU9XCJEZWxldGVcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxpIGNsYXNzPVwiYmkgYmktdHJhc2hcIj48L2k+XG4gICAgICAgICAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgICAgICA8JSB9ICU+XG4gICAgICAgICAgICAgIDwvdHI+XG4gICAgICAgICAgICA8JSB9ICU+XG4gICAgICAgICAgPCUgfSBlbHNlIHsgJT5cbiAgICAgICAgICAgIDwlLS0gRW1wdHkgc3RhdGUgLS0lPlxuICAgICAgICAgICAgPHRyPlxuICAgICAgICAgICAgICA8dGQgY29sc3Bhbj1cIjwlPSAodGhpcy5hcmdzLnNlbGVjdGFibGUgPyAxIDogMCkgKyAodGhpcy5hcmdzLmNvbHVtbnMgPyB0aGlzLmFyZ3MuY29sdW1ucy5sZW5ndGggOiA4KSAlPlwiXG4gICAgICAgICAgICAgICAgICBjbGFzcz1cInRleHQtY2VudGVyIHRleHQtbXV0ZWQgcHktNVwiPlxuICAgICAgICAgICAgICAgIDxpIGNsYXNzPVwiYmkgYmktaW5ib3ggZnMtMSBkLWJsb2NrIG1iLTJcIj48L2k+XG4gICAgICAgICAgICAgICAgTm8gPCU9IHRoaXMuYXJncy5lbnRpdHlfbmFtZSB8fCAnaXRlbXMnICU+IGZvdW5kXG4gICAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICA8L3RyPlxuICAgICAgICAgIDwlIH0gJT5cbiAgICAgICAgPC90Ym9keT5cbiAgICAgIDwvdGFibGU+XG4gICAgPC9kaXY+XG4gIDwvZGl2PlxuXG4gIDwlLS0gUGFnaW5hdGlvbiBGb290ZXIgLS0lPlxuICA8JSBpZiAodGhpcy5hcmdzLnBhZ2luYXRpb24gIT09IGZhbHNlICYmIE9iamVjdC5rZXlzKHRoaXMuZGF0YSkubGVuZ3RoID4gMCkgeyAlPlxuICAgIDxkaXYgY2xhc3M9XCJjYXJkLWZvb3RlciBiZy1saWdodFwiPlxuICAgICAgPGRpdiBjbGFzcz1cImQtZmxleCBqdXN0aWZ5LWNvbnRlbnQtYmV0d2VlbiBhbGlnbi1pdGVtcy1jZW50ZXJcIj5cbiAgICAgICAgPGRpdj5cbiAgICAgICAgICA8c21hbGwgY2xhc3M9XCJ0ZXh0LW11dGVkXCI+XG4gICAgICAgICAgICBTaG93aW5nIDwlPSB0aGlzLmRhdGEucGFnaW5hdGlvbj8uZnJvbSB8fCAxICU+IHRvIDwlPSB0aGlzLmRhdGEucGFnaW5hdGlvbj8udG8gfHwgMTAgJT5cbiAgICAgICAgICAgIG9mIDwlPSB0aGlzLmRhdGEucGFnaW5hdGlvbj8udG90YWwgfHwgMTAwICU+IGVudHJpZXNcbiAgICAgICAgICA8L3NtYWxsPlxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgPG5hdj5cbiAgICAgICAgICA8dWwgY2xhc3M9XCJwYWdpbmF0aW9uIHBhZ2luYXRpb24tc20gbWItMFwiPlxuICAgICAgICAgICAgPCUtLSBQcmV2aW91cyBCdXR0b24gLS0lPlxuICAgICAgICAgICAgPGxpIGNsYXNzPVwicGFnZS1pdGVtIDwlPSB0aGlzLmRhdGEucGFnaW5hdGlvbj8uY3VycmVudF9wYWdlID09PSAxID8gJ2Rpc2FibGVkJyA6ICcnICU+XCI+XG4gICAgICAgICAgICAgIDxhIGNsYXNzPVwicGFnZS1saW5rXCIgaHJlZj1cIiNcIiB0YWJpbmRleD1cIi0xXCIgJGlkPVwicHJldl9wYWdlXCI+UHJldmlvdXM8L2E+XG4gICAgICAgICAgICA8L2xpPlxuXG4gICAgICAgICAgICA8JS0tIFBhZ2UgTnVtYmVycyAtLSU+XG4gICAgICAgICAgICA8JSBpZiAodGhpcy5kYXRhLnBhZ2luYXRpb24/LnBhZ2VzKSB7ICU+XG4gICAgICAgICAgICAgIDwlIGZvciAobGV0IHBhZ2Ugb2YgdGhpcy5kYXRhLnBhZ2luYXRpb24ucGFnZXMpIHsgJT5cbiAgICAgICAgICAgICAgICA8JSBpZiAocGFnZSA9PT0gJy4uLicpIHsgJT5cbiAgICAgICAgICAgICAgICAgIDxsaSBjbGFzcz1cInBhZ2UtaXRlbSBkaXNhYmxlZFwiPjxhIGNsYXNzPVwicGFnZS1saW5rXCIgaHJlZj1cIiNcIj4uLi48L2E+PC9saT5cbiAgICAgICAgICAgICAgICA8JSB9IGVsc2UgeyAlPlxuICAgICAgICAgICAgICAgICAgPGxpIGNsYXNzPVwicGFnZS1pdGVtIDwlPSBwYWdlID09PSB0aGlzLmRhdGEucGFnaW5hdGlvbi5jdXJyZW50X3BhZ2UgPyAnYWN0aXZlJyA6ICcnICU+XCI+XG4gICAgICAgICAgICAgICAgICAgIDxhIGNsYXNzPVwicGFnZS1saW5rXCIgaHJlZj1cIiNcIiBkYXRhLXBhZ2U9XCI8JT0gcGFnZSAlPlwiPjwlPSBwYWdlICU+PC9hPlxuICAgICAgICAgICAgICAgICAgPC9saT5cbiAgICAgICAgICAgICAgICA8JSB9ICU+XG4gICAgICAgICAgICAgIDwlIH0gJT5cbiAgICAgICAgICAgIDwlIH0gZWxzZSB7ICU+XG4gICAgICAgICAgICAgIDwlLS0gR2VuZXJhdGUgNSBwYWdlIGJ1dHRvbnMgaWYgcGFnaW5hdGlvbiBkYXRhIG5vdCBmdWxseSBsb2FkZWQgLS0lPlxuICAgICAgICAgICAgICA8JSBmb3IgKGxldCBpID0gMTsgaSA8PSA1OyBpKyspIHsgJT5cbiAgICAgICAgICAgICAgICA8bGkgY2xhc3M9XCJwYWdlLWl0ZW0gPCU9IGkgPT09IDEgPyAnYWN0aXZlJyA6ICcnICU+XCI+XG4gICAgICAgICAgICAgICAgICA8YSBjbGFzcz1cInBhZ2UtbGlua1wiIGhyZWY9XCIjXCIgZGF0YS1wYWdlPVwiPCU9IGkgJT5cIj48JT0gaSAlPjwvYT5cbiAgICAgICAgICAgICAgICA8L2xpPlxuICAgICAgICAgICAgICA8JSB9ICU+XG4gICAgICAgICAgICA8JSB9ICU+XG5cbiAgICAgICAgICAgIDwlLS0gTmV4dCBCdXR0b24gLS0lPlxuICAgICAgICAgICAgPGxpIGNsYXNzPVwicGFnZS1pdGVtIDwlPSB0aGlzLmRhdGEucGFnaW5hdGlvbj8uY3VycmVudF9wYWdlID09PSB0aGlzLmRhdGEucGFnaW5hdGlvbj8udG90YWxfcGFnZXMgPyAnZGlzYWJsZWQnIDogJycgJT5cIj5cbiAgICAgICAgICAgICAgPGEgY2xhc3M9XCJwYWdlLWxpbmtcIiBocmVmPVwiI1wiICRpZD1cIm5leHRfcGFnZVwiPk5leHQ8L2E+XG4gICAgICAgICAgICA8L2xpPlxuICAgICAgICAgIDwvdWw+XG4gICAgICAgIDwvbmF2PlxuICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG4gIDwlIH0gJT5cbjwvRGVmaW5lOlNhbXBsZV9EYXRhZ3JpZF9Db21wb25lbnQ+XG4iLCI8RGVmaW5lOlNlYXJjaF9CYXIgY2xhc3M9XCJpbnB1dC1ncm91cFwiPlxuICA8c3BhbiBjbGFzcz1cImlucHV0LWdyb3VwLXRleHRcIj5cbiAgICA8SWNvbiAkbmFtZT1cInNlYXJjaFwiIC8+XG4gIDwvc3Bhbj5cbiAgPGlucHV0IHR5cGU9XCJzZWFyY2hcIlxuICAgICAgICAgY2xhc3M9XCJmb3JtLWNvbnRyb2xcIlxuICAgICAgICAgcGxhY2Vob2xkZXI9XCI8JT0gdGhpcy5hcmdzLnBsYWNlaG9sZGVyIHx8ICdTZWFyY2guLi4nICU+XCJcbiAgICAgICAgICRpZD1cImlucHV0XCIgLz5cbjwvRGVmaW5lOlNlYXJjaF9CYXI+XG4iLCI8RGVmaW5lOlNlYXJjaF9CdXR0b24gdGFnPVwiYnV0dG9uXCIgdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwiYnRuIGJ0bi1zZWNvbmRhcnlcIj5cbiAgPGkgY2xhc3M9XCJiaSBiaS1zZWFyY2hcIj48L2k+XG48L0RlZmluZTpTZWFyY2hfQnV0dG9uPlxuIiwiPERlZmluZTpTZWFyY2hfSW5wdXQgdGFnPVwiaW5wdXRcIiB0eXBlPVwic2VhcmNoXCIgY2xhc3M9XCJmb3JtLWNvbnRyb2xcIiBwbGFjZWhvbGRlcj1cIlNlYXJjaCBjb250YWN0cy4uLlwiIHN0eWxlPVwid2lkdGg6IDI1MHB4O1wiPlxuPC9EZWZpbmU6U2VhcmNoX0lucHV0PlxuIiwiPERlZmluZTpTZWFyY2hhYmxlX1NlbGVjdCBjbGFzcz1cImRyb3Bkb3duXCI+XG4gIDwlIGlmICh0aGlzLmFyZ3MubGFiZWwpIHsgJT5cbiAgICA8bGFiZWwgY2xhc3M9XCJmb3JtLWxhYmVsXCI+PCU9IHRoaXMuYXJncy5sYWJlbCAlPjwvbGFiZWw+XG4gIDwlIH0gJT5cbiAgPGJ1dHRvbiBjbGFzcz1cImJ0biBidG4tc2Vjb25kYXJ5IGRyb3Bkb3duLXRvZ2dsZSB3LTEwMCB0ZXh0LXN0YXJ0XCIgdHlwZT1cImJ1dHRvblwiIGRhdGEtYnMtdG9nZ2xlPVwiZHJvcGRvd25cIiBhcmlhLWV4cGFuZGVkPVwiZmFsc2VcIiAkaWQ9XCJidXR0b25cIj5cbiAgICA8c3BhbiAkaWQ9XCJzZWxlY3RlZF90ZXh0XCI+PCU9IHRoaXMuYXJncy5wbGFjZWhvbGRlciB8fCAnU2VsZWN0IGFuIG9wdGlvbicgJT48L3NwYW4+XG4gIDwvYnV0dG9uPlxuICA8ZGl2IGNsYXNzPVwiZHJvcGRvd24tbWVudSB3LTEwMFwiICRpZD1cIm1lbnVcIj5cbiAgICA8ZGl2IGNsYXNzPVwicHgtMyBweS0yXCI+XG4gICAgICA8aW5wdXQgdHlwZT1cInNlYXJjaFwiIGNsYXNzPVwiZm9ybS1jb250cm9sIGZvcm0tY29udHJvbC1zbVwiIHBsYWNlaG9sZGVyPVwiU2VhcmNoLi4uXCIgJGlkPVwic2VhcmNoXCI+XG4gICAgPC9kaXY+XG4gICAgPGRpdiBjbGFzcz1cImRyb3Bkb3duLWRpdmlkZXJcIj48L2Rpdj5cbiAgICA8ZGl2ICRpZD1cIm9wdGlvbnNcIiBzdHlsZT1cIm1heC1oZWlnaHQ6IDI1MHB4OyBvdmVyZmxvdy15OiBhdXRvO1wiPlxuICAgICAgPCEtLSBPcHRpb25zIHBvcHVsYXRlZCB2aWEgSmF2YVNjcmlwdCAtLT5cbiAgICA8L2Rpdj5cbiAgPC9kaXY+XG48L0RlZmluZTpTZWFyY2hhYmxlX1NlbGVjdD5cbiIsIjxEZWZpbmU6U2VsZWN0X0Ryb3Bkb3duIHRhZz1cInNlbGVjdFwiIGNsYXNzPVwiZm9ybS1zZWxlY3RcIj5cbiAgPCU9IGNvbnRlbnQoKSAlPlxuPC9EZWZpbmU6U2VsZWN0X0Ryb3Bkb3duPlxuIiwiPERlZmluZTpTaWRlYmFyX05hdiB0YWc9XCJuYXZcIiBjbGFzcz1cImQtZmxleCBmbGV4LWNvbHVtbiBwLTMgYmctbGlnaHRcIiBzdHlsZT1cIndpZHRoOiAyNTBweDsgbWluLWhlaWdodDogMTAwdmg7XCI+XG4gIDxhIGhyZWY9XCIvXCIgY2xhc3M9XCJkLWZsZXggYWxpZ24taXRlbXMtY2VudGVyIG1iLTMgdGV4dC1kZWNvcmF0aW9uLW5vbmVcIj5cbiAgICA8c3BhbiBjbGFzcz1cImZzLTQgZnctYm9sZFwiPlBTTTwvc3Bhbj5cbiAgPC9hPlxuICA8aHIgLz5cbiAgPHVsIGNsYXNzPVwibmF2IG5hdi1waWxscyBmbGV4LWNvbHVtbiBtYi1hdXRvXCIgJGlkPVwibmF2X2l0ZW1zXCI+XG4gICAgPCU9IGNvbnRlbnQoKSAlPlxuICA8L3VsPlxuPC9EZWZpbmU6U2lkZWJhcl9OYXY+XG4iLCI8RGVmaW5lOlNpbXBsZV9UYWJsZV9UZXN0PlxuICA8dGFibGUgY2xhc3M9XCJ0YWJsZVwiPlxuICAgIDx0cj5cbiAgICAgIDx0ZD5UZXN0PC90ZD5cbiAgICA8L3RyPlxuICA8L3RhYmxlPlxuPC9EZWZpbmU6U2ltcGxlX1RhYmxlX1Rlc3Q+XG4iLCI8RGVmaW5lOlNvcnRhYmxlX0NvbHVtbl9IZWFkZXIgdGFnPVwidGhcIiBjbGFzcz1cInVzZXItc2VsZWN0LW5vbmVcIiBzdHlsZT1cImN1cnNvcjogcG9pbnRlcjtcIj5cbiAgPGRpdiBjbGFzcz1cImQtZmxleCBhbGlnbi1pdGVtcy1jZW50ZXIganVzdGlmeS1jb250ZW50LWJldHdlZW5cIj5cbiAgICA8c3Bhbj48JT0gY29udGVudCgpICU+PC9zcGFuPlxuICAgIDxzcGFuIGNsYXNzPVwibXMtMlwiICRpZD1cInNvcnRfaWNvblwiPlxuICAgICAgPGkgY2xhc3M9XCJ0ZXh0LW11dGVkXCI+4oeFPC9pPlxuICAgIDwvc3Bhbj5cbiAgPC9kaXY+XG48L0RlZmluZTpTb3J0YWJsZV9Db2x1bW5fSGVhZGVyPlxuIiwiPERlZmluZTpTcGlubmVyIGNsYXNzPVwic3Bpbm5lci1ib3JkZXJcIiByb2xlPVwic3RhdHVzXCI+XG4gIDxzcGFuIGNsYXNzPVwidmlzdWFsbHktaGlkZGVuXCI+TG9hZGluZy4uLjwvc3Bhbj5cbjwvRGVmaW5lOlNwaW5uZXI+XG4iLCI8RGVmaW5lOlN0YXRfQ2FyZCBjbGFzcz1cImNhcmQgdGV4dC1jZW50ZXIgYm9yZGVyLTAgc2hhZG93LXNtXCI+XG4gIDxkaXYgY2xhc3M9XCJjYXJkLWJvZHlcIj5cbiAgICA8JT0gY29udGVudCgpICU+XG4gIDwvZGl2PlxuPC9EZWZpbmU6U3RhdF9DYXJkPlxuIiwiPERlZmluZTpTdGF0dXNfQmFkZ2UgdGFnPVwic3BhblwiIGNsYXNzPVwiYmFkZ2VcIj5cbiAgPCU9IGNvbnRlbnQoKSAlPlxuPC9EZWZpbmU6U3RhdHVzX0JhZGdlPlxuIiwiPERlZmluZTpUYWJfQ29udGVudCBjbGFzcz1cInRhYi1jb250ZW50IG10LTNcIj5cbiAgPCU9IGNvbnRlbnQoKSAlPlxuPC9EZWZpbmU6VGFiX0NvbnRlbnQ+XG4iLCI8RGVmaW5lOlRhYmxlX0JvZHkgdGFnPVwidGJvZHlcIj5cbiAgPCU9IGNvbnRlbnQoKSAlPlxuPC9EZWZpbmU6VGFibGVfQm9keT5cbiIsIjxEZWZpbmU6VGFibGVfSGVhZGVycyB0YWc9XCJ0aGVhZFwiPlxuICA8dHI+XG4gICAgPCU9IGNvbnRlbnQoKSAlPlxuICA8L3RyPlxuPC9EZWZpbmU6VGFibGVfSGVhZGVycz5cbiIsIjxEZWZpbmU6VGFibGVfUGFnaW5hdGlvbiBjbGFzcz1cImQtZmxleCBqdXN0aWZ5LWNvbnRlbnQtYmV0d2VlbiBhbGlnbi1pdGVtcy1jZW50ZXIgbXQtM1wiPlxuICA8ZGl2IGNsYXNzPVwidGV4dC1tdXRlZCBzbWFsbFwiICRpZD1cImluZm9cIj5cbiAgICBTaG93aW5nIDwlPSB0aGlzLmFyZ3Muc3RhcnQgfHwgMSAlPiB0byA8JT0gdGhpcy5hcmdzLmVuZCB8fCAxMCAlPiBvZiA8JT0gdGhpcy5hcmdzLnRvdGFsIHx8IDAgJT4gZW50cmllc1xuICA8L2Rpdj5cbiAgPG5hdiBhcmlhLWxhYmVsPVwiVGFibGUgcGFnaW5hdGlvblwiPlxuICAgIDx1bCBjbGFzcz1cInBhZ2luYXRpb24gbWItMFwiICRpZD1cInBhZ2luYXRpb25cIj5cbiAgICAgIDwlPSBjb250ZW50KCkgJT5cbiAgICA8L3VsPlxuICA8L25hdj5cbjwvRGVmaW5lOlRhYmxlX1BhZ2luYXRpb24+XG4iLCI8RGVmaW5lOlRhYmxlIHRhZz1cInRhYmxlXCIgY2xhc3M9XCJ0YWJsZSB0YWJsZS1ob3ZlclwiPlxuICA8JT0gY29udGVudCgpICU+XG48L0RlZmluZTpUYWJsZT5cbiIsIjxEZWZpbmU6VGFicyB0YWc9XCJ1bFwiIGNsYXNzPVwibmF2IG5hdi10YWJzXCI+XG4gIDwlPSBjb250ZW50KCkgJT5cbjwvRGVmaW5lOlRhYnM+XG4iLCI8RGVmaW5lOlRhZ19Hcm91cCBjbGFzcz1cImQtZmxleCBmbGV4LXdyYXAgZ2FwLTFcIj5cbiAgPCU9IGNvbnRlbnQoKSAlPlxuPC9EZWZpbmU6VGFnX0dyb3VwPlxuIiwiPERlZmluZTpUYWcgdGFnPVwic3BhblwiIGNsYXNzPVwiYmFkZ2Ugcm91bmRlZC1waWxsIGJnLXNlY29uZGFyeSBtZS0xXCI+XG4gIDwlPSBjb250ZW50KCkgJT5cbjwvRGVmaW5lOlRhZz5cbiIsIjxEZWZpbmU6VGV4dF9EaXNwbGF5IHRhZz1cInNwYW5cIj5cbiAgPCU9IGNvbnRlbnQoKSAlPlxuPC9EZWZpbmU6VGV4dF9EaXNwbGF5PlxuIiwiPERlZmluZTpUZXh0YXJlYSB0YWc9XCJ0ZXh0YXJlYVwiIGNsYXNzPVwiZm9ybS1jb250cm9sXCIgcm93cz1cIjRcIj5cbiAgPCU9IGNvbnRlbnQoKSAlPlxuPC9EZWZpbmU6VGV4dGFyZWE+XG4iLCI8RGVmaW5lOlRocmVlX0NvbHVtbl9MYXlvdXQgY2xhc3M9XCJyb3dcIj5cbiAgPCU9IGNvbnRlbnQoKSAlPlxuPC9EZWZpbmU6VGhyZWVfQ29sdW1uX0xheW91dD5cbiIsIjxEZWZpbmU6VGltZV9QaWNrZXIgY2xhc3M9XCJtYi0zXCI+XG4gIDwlIGlmICh0aGlzLmFyZ3MubGFiZWwpIHsgJT5cbiAgICA8bGFiZWwgY2xhc3M9XCJmb3JtLWxhYmVsXCI+PCU9IHRoaXMuYXJncy5sYWJlbCAlPjwvbGFiZWw+XG4gIDwlIH0gJT5cbiAgPGRpdiBjbGFzcz1cImlucHV0LWdyb3VwXCI+XG4gICAgPHNwYW4gY2xhc3M9XCJpbnB1dC1ncm91cC10ZXh0XCI+XG4gICAgICA8aSBjbGFzcz1cImJpIGJpLWNsb2NrXCI+PC9pPlxuICAgIDwvc3Bhbj5cbiAgICA8aW5wdXRcbiAgICAgIHR5cGU9XCJ0aW1lXCJcbiAgICAgIGNsYXNzPVwiZm9ybS1jb250cm9sXCJcbiAgICAgIHBsYWNlaG9sZGVyPVwiPCU9IHRoaXMuYXJncy5wbGFjZWhvbGRlciB8fCAnJyAlPlwiXG4gICAgICAkaWQ9XCJpbnB1dFwiXG4gICAgLz5cbiAgPC9kaXY+XG4gIDwlIGlmICh0aGlzLmFyZ3MuaGVscCkgeyAlPlxuICAgIDxkaXYgY2xhc3M9XCJmb3JtLXRleHRcIj48JT0gdGhpcy5hcmdzLmhlbHAgJT48L2Rpdj5cbiAgPCUgfSAlPlxuPC9EZWZpbmU6VGltZV9QaWNrZXI+XG4iLCI8RGVmaW5lOlRpbWVsaW5lIGNsYXNzPVwiZC1mbGV4IGZsZXgtY29sdW1uIGdhcC0zXCI+XG4gIDwlPSBjb250ZW50KCkgJT5cbjwvRGVmaW5lOlRpbWVsaW5lPlxuIiwiPERlZmluZTpUaW1lc3RhbXBfRGlzcGxheSB0YWc9XCJzbWFsbFwiIGNsYXNzPVwidGV4dC1tdXRlZCBkLWJsb2NrXCI+XG4gIDwlPSBjb250ZW50KCkgJT5cbjwvRGVmaW5lOlRpbWVzdGFtcF9EaXNwbGF5PlxuIiwiPERlZmluZTpUb29sdGlwIHRhZz1cInNwYW5cIiBkYXRhLWJzLXRvZ2dsZT1cInRvb2x0aXBcIiBkYXRhLWJzLXBsYWNlbWVudD1cInRvcFwiPlxuICA8JT0gY29udGVudCgpICU+XG48L0RlZmluZTpUb29sdGlwPlxuIiwiPERlZmluZTpUb3BfTmF2IHRhZz1cIm5hdlwiIGNsYXNzPVwibmF2YmFyIG5hdmJhci1leHBhbmQtbGcgbmF2YmFyLWxpZ2h0IGJnLWxpZ2h0XCI+XG4gIDxkaXYgY2xhc3M9XCJjb250YWluZXItZmx1aWRcIj5cbiAgICA8YSBjbGFzcz1cIm5hdmJhci1icmFuZFwiIGhyZWY9XCIvXCI+UFNNPC9hPlxuICAgIDxidXR0b24gY2xhc3M9XCJuYXZiYXItdG9nZ2xlclwiXG4gICAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgIGRhdGEtYnMtdG9nZ2xlPVwiY29sbGFwc2VcIlxuICAgICAgICAgICAgZGF0YS1icy10YXJnZXQ9XCIjbmF2YmFyTmF2XCJcbiAgICAgICAgICAgIGFyaWEtY29udHJvbHM9XCJuYXZiYXJOYXZcIlxuICAgICAgICAgICAgYXJpYS1leHBhbmRlZD1cImZhbHNlXCJcbiAgICAgICAgICAgIGFyaWEtbGFiZWw9XCJUb2dnbGUgbmF2aWdhdGlvblwiPlxuICAgICAgPHNwYW4gY2xhc3M9XCJuYXZiYXItdG9nZ2xlci1pY29uXCI+PC9zcGFuPlxuICAgIDwvYnV0dG9uPlxuICAgIDxkaXYgY2xhc3M9XCJjb2xsYXBzZSBuYXZiYXItY29sbGFwc2VcIiBpZD1cIm5hdmJhck5hdlwiPlxuICAgICAgPHVsIGNsYXNzPVwibmF2YmFyLW5hdiBtcy1hdXRvXCIgJGlkPVwibmF2X2l0ZW1zXCI+XG4gICAgICAgIDwlPSBjb250ZW50KCkgJT5cbiAgICAgIDwvdWw+XG4gICAgPC9kaXY+XG4gIDwvZGl2PlxuPC9EZWZpbmU6VG9wX05hdj5cbiIsIjxEZWZpbmU6VHJlbmRfSW5kaWNhdG9yIHRhZz1cInNwYW5cIj5cbiAgPCU9IGNvbnRlbnQoKSAlPlxuPC9EZWZpbmU6VHJlbmRfSW5kaWNhdG9yPlxuIiwiPERlZmluZTpUd29fQ29sdW1uX0xheW91dCBjbGFzcz1cInJvd1wiPlxuICA8JT0gY29udGVudCgpICU+XG48L0RlZmluZTpUd29fQ29sdW1uX0xheW91dD5cbiIsIjxEZWZpbmU6VXNlcl9BdmF0YXJfRHJvcGRvd24gY2xhc3M9XCJkcm9wZG93blwiPlxuICA8YnV0dG9uIGNsYXNzPVwiYnRuIGJ0bi1saW5rIGRyb3Bkb3duLXRvZ2dsZSBwLTAgYm9yZGVyLTBcIlxuICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgIGRhdGEtYnMtdG9nZ2xlPVwiZHJvcGRvd25cIlxuICAgICAgICAgIGFyaWEtZXhwYW5kZWQ9XCJmYWxzZVwiXG4gICAgICAgICAgJGlkPVwidG9nZ2xlXCI+XG4gICAgPEF2YXRhciAkc3JjPSh0aGlzLmFyZ3MuYXZhdGFyX3NyYykgJG5hbWU9KHRoaXMuYXJncy51c2VyX25hbWUpICRzaXplPVwic21cIiAvPlxuICA8L2J1dHRvbj5cbiAgPHVsIGNsYXNzPVwiZHJvcGRvd24tbWVudSBkcm9wZG93bi1tZW51LWVuZFwiICRpZD1cIm1lbnVcIj5cbiAgICA8JT0gY29udGVudCgpICU+XG4gIDwvdWw+XG48L0RlZmluZTpVc2VyX0F2YXRhcl9Ecm9wZG93bj5cbiIsIjxEZWZpbmU6VXNlcnNfRGF0YV9UYWJsZSB0YWc9XCJkaXZcIiBjbGFzcz1cImNhcmQtYm9keSBwLTBcIj5cbiAgPGRpdiBjbGFzcz1cInRhYmxlLXJlc3BvbnNpdmVcIj5cbiAgICA8dGFibGUgY2xhc3M9XCJ0YWJsZSB0YWJsZS1ob3ZlciBtYi0wXCI+XG4gICAgICA8dGhlYWQ+XG4gICAgICAgIDx0cj5cbiAgICAgICAgICA8dGggc3R5bGU9XCJ3aWR0aDogNDBweDtcIj5cbiAgICAgICAgICAgIDxpbnB1dCB0eXBlPVwiY2hlY2tib3hcIiBjbGFzcz1cImZvcm0tY2hlY2staW5wdXRcIiBpZD1cInNlbGVjdC1hbGxcIj5cbiAgICAgICAgICA8L3RoPlxuICAgICAgICAgIDx0aD5JRDwvdGg+XG4gICAgICAgICAgPHRoPk5hbWU8L3RoPlxuICAgICAgICAgIDx0aD5FbWFpbDwvdGg+XG4gICAgICAgICAgPHRoPlJvbGU8L3RoPlxuICAgICAgICAgIDx0aD5EZXBhcnRtZW50PC90aD5cbiAgICAgICAgICA8dGg+U3RhdHVzPC90aD5cbiAgICAgICAgICA8dGg+TGFzdCBMb2dpbjwvdGg+XG4gICAgICAgICAgPHRoPkpvaW5lZDwvdGg+XG4gICAgICAgICAgPHRoIHN0eWxlPVwid2lkdGg6IDEwMHB4O1wiPkFjdGlvbnM8L3RoPlxuICAgICAgICA8L3RyPlxuICAgICAgPC90aGVhZD5cbiAgICAgIDx0Ym9keT5cbiAgICAgICAgPHRyPlxuICAgICAgICAgIDx0ZD48aW5wdXQgdHlwZT1cImNoZWNrYm94XCIgY2xhc3M9XCJmb3JtLWNoZWNrLWlucHV0IHVzZXItc2VsZWN0XCI+PC90ZD5cbiAgICAgICAgICA8dGQ+I1UwMDE8L3RkPlxuICAgICAgICAgIDx0ZD5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkLWZsZXggYWxpZ24taXRlbXMtY2VudGVyXCI+XG4gICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJhdmF0YXItc20gbWUtMlwiPlxuICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiYXZhdGFyLWluaXRpYWxzXCI+SkQ8L3NwYW4+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICBKb2huIERvZVxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC90ZD5cbiAgICAgICAgICA8dGQ+am9obi5kb2VAZXhhbXBsZS5jb208L3RkPlxuICAgICAgICAgIDx0ZD48c3BhbiBjbGFzcz1cImJhZGdlIGJnLWRhbmdlclwiPkFkbWluPC9zcGFuPjwvdGQ+XG4gICAgICAgICAgPHRkPkVuZ2luZWVyaW5nPC90ZD5cbiAgICAgICAgICA8dGQ+PHNwYW4gY2xhc3M9XCJiYWRnZSBiZy1zdWNjZXNzXCI+QWN0aXZlPC9zcGFuPjwvdGQ+XG4gICAgICAgICAgPHRkPjIgaG91cnMgYWdvPC90ZD5cbiAgICAgICAgICA8dGQ+SmFuIDE1LCAyMDIzPC90ZD5cbiAgICAgICAgICA8dGQ+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiYnRuLWdyb3VwIGJ0bi1ncm91cC1zbVwiPlxuICAgICAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwiYnRuIGJ0bi1wcmltYXJ5XCIgdGl0bGU9XCJWaWV3IFByb2ZpbGVcIj5cbiAgICAgICAgICAgICAgICA8aSBjbGFzcz1cImJpIGJpLWV5ZVwiPjwvaT5cbiAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJidG4gYnRuLXNlY29uZGFyeVwiIHRpdGxlPVwiRWRpdFwiPlxuICAgICAgICAgICAgICAgIDxpIGNsYXNzPVwiYmkgYmktcGVuY2lsXCI+PC9pPlxuICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cImJ0biBidG4tZGFuZ2VyXCIgdGl0bGU9XCJTdXNwZW5kXCI+XG4gICAgICAgICAgICAgICAgPGkgY2xhc3M9XCJiaSBiaS1iYW5cIj48L2k+XG4gICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC90ZD5cbiAgICAgICAgPC90cj5cbiAgICAgICAgPHRyPlxuICAgICAgICAgIDx0ZD48aW5wdXQgdHlwZT1cImNoZWNrYm94XCIgY2xhc3M9XCJmb3JtLWNoZWNrLWlucHV0IHVzZXItc2VsZWN0XCI+PC90ZD5cbiAgICAgICAgICA8dGQ+I1UwMDI8L3RkPlxuICAgICAgICAgIDx0ZD5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkLWZsZXggYWxpZ24taXRlbXMtY2VudGVyXCI+XG4gICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJhdmF0YXItc20gbWUtMlwiPlxuICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiYXZhdGFyLWluaXRpYWxzXCI+SlM8L3NwYW4+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICBKYW5lIFNtaXRoXG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L3RkPlxuICAgICAgICAgIDx0ZD5qYW5lLnNtaXRoQGV4YW1wbGUuY29tPC90ZD5cbiAgICAgICAgICA8dGQ+PHNwYW4gY2xhc3M9XCJiYWRnZSBiZy1wcmltYXJ5XCI+TWFuYWdlcjwvc3Bhbj48L3RkPlxuICAgICAgICAgIDx0ZD5NYXJrZXRpbmc8L3RkPlxuICAgICAgICAgIDx0ZD48c3BhbiBjbGFzcz1cImJhZGdlIGJnLXN1Y2Nlc3NcIj5BY3RpdmU8L3NwYW4+PC90ZD5cbiAgICAgICAgICA8dGQ+MSBkYXkgYWdvPC90ZD5cbiAgICAgICAgICA8dGQ+RmViIDIwLCAyMDIzPC90ZD5cbiAgICAgICAgICA8dGQ+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiYnRuLWdyb3VwIGJ0bi1ncm91cC1zbVwiPlxuICAgICAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwiYnRuIGJ0bi1wcmltYXJ5XCIgdGl0bGU9XCJWaWV3IFByb2ZpbGVcIj5cbiAgICAgICAgICAgICAgICA8aSBjbGFzcz1cImJpIGJpLWV5ZVwiPjwvaT5cbiAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJidG4gYnRuLXNlY29uZGFyeVwiIHRpdGxlPVwiRWRpdFwiPlxuICAgICAgICAgICAgICAgIDxpIGNsYXNzPVwiYmkgYmktcGVuY2lsXCI+PC9pPlxuICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cImJ0biBidG4tZGFuZ2VyXCIgdGl0bGU9XCJTdXNwZW5kXCI+XG4gICAgICAgICAgICAgICAgPGkgY2xhc3M9XCJiaSBiaS1iYW5cIj48L2k+XG4gICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC90ZD5cbiAgICAgICAgPC90cj5cbiAgICAgICAgPHRyPlxuICAgICAgICAgIDx0ZD48aW5wdXQgdHlwZT1cImNoZWNrYm94XCIgY2xhc3M9XCJmb3JtLWNoZWNrLWlucHV0IHVzZXItc2VsZWN0XCI+PC90ZD5cbiAgICAgICAgICA8dGQ+I1UwMDM8L3RkPlxuICAgICAgICAgIDx0ZD5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkLWZsZXggYWxpZ24taXRlbXMtY2VudGVyXCI+XG4gICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJhdmF0YXItc20gbWUtMlwiPlxuICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiYXZhdGFyLWluaXRpYWxzXCI+TUI8L3NwYW4+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICBNaWtlIEJyb3duXG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L3RkPlxuICAgICAgICAgIDx0ZD5taWtlLmJyb3duQGV4YW1wbGUuY29tPC90ZD5cbiAgICAgICAgICA8dGQ+PHNwYW4gY2xhc3M9XCJiYWRnZSBiZy1zZWNvbmRhcnlcIj5Vc2VyPC9zcGFuPjwvdGQ+XG4gICAgICAgICAgPHRkPlNhbGVzPC90ZD5cbiAgICAgICAgICA8dGQ+PHNwYW4gY2xhc3M9XCJiYWRnZSBiZy13YXJuaW5nXCI+SW5hY3RpdmU8L3NwYW4+PC90ZD5cbiAgICAgICAgICA8dGQ+NSBkYXlzIGFnbzwvdGQ+XG4gICAgICAgICAgPHRkPk1hciAxMCwgMjAyMzwvdGQ+XG4gICAgICAgICAgPHRkPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImJ0bi1ncm91cCBidG4tZ3JvdXAtc21cIj5cbiAgICAgICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cImJ0biBidG4tcHJpbWFyeVwiIHRpdGxlPVwiVmlldyBQcm9maWxlXCI+XG4gICAgICAgICAgICAgICAgPGkgY2xhc3M9XCJiaSBiaS1leWVcIj48L2k+XG4gICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwiYnRuIGJ0bi1zZWNvbmRhcnlcIiB0aXRsZT1cIkVkaXRcIj5cbiAgICAgICAgICAgICAgICA8aSBjbGFzcz1cImJpIGJpLXBlbmNpbFwiPjwvaT5cbiAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJidG4gYnRuLXN1Y2Nlc3NcIiB0aXRsZT1cIkFjdGl2YXRlXCI+XG4gICAgICAgICAgICAgICAgPGkgY2xhc3M9XCJiaSBiaS1jaGVjay1jaXJjbGVcIj48L2k+XG4gICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC90ZD5cbiAgICAgICAgPC90cj5cbiAgICAgICAgPHRyPlxuICAgICAgICAgIDx0ZD48aW5wdXQgdHlwZT1cImNoZWNrYm94XCIgY2xhc3M9XCJmb3JtLWNoZWNrLWlucHV0IHVzZXItc2VsZWN0XCI+PC90ZD5cbiAgICAgICAgICA8dGQ+I1UwMDQ8L3RkPlxuICAgICAgICAgIDx0ZD5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkLWZsZXggYWxpZ24taXRlbXMtY2VudGVyXCI+XG4gICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJhdmF0YXItc20gbWUtMlwiPlxuICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiYXZhdGFyLWluaXRpYWxzXCI+U1c8L3NwYW4+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICBTYXJhaCBXaWxzb25cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgPHRkPnNhcmFoLndpbHNvbkBleGFtcGxlLmNvbTwvdGQ+XG4gICAgICAgICAgPHRkPjxzcGFuIGNsYXNzPVwiYmFkZ2UgYmctcHJpbWFyeVwiPk1hbmFnZXI8L3NwYW4+PC90ZD5cbiAgICAgICAgICA8dGQ+SFI8L3RkPlxuICAgICAgICAgIDx0ZD48c3BhbiBjbGFzcz1cImJhZGdlIGJnLXN1Y2Nlc3NcIj5BY3RpdmU8L3NwYW4+PC90ZD5cbiAgICAgICAgICA8dGQ+MyBob3VycyBhZ288L3RkPlxuICAgICAgICAgIDx0ZD5BcHIgMDUsIDIwMjM8L3RkPlxuICAgICAgICAgIDx0ZD5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJidG4tZ3JvdXAgYnRuLWdyb3VwLXNtXCI+XG4gICAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJidG4gYnRuLXByaW1hcnlcIiB0aXRsZT1cIlZpZXcgUHJvZmlsZVwiPlxuICAgICAgICAgICAgICAgIDxpIGNsYXNzPVwiYmkgYmktZXllXCI+PC9pPlxuICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cImJ0biBidG4tc2Vjb25kYXJ5XCIgdGl0bGU9XCJFZGl0XCI+XG4gICAgICAgICAgICAgICAgPGkgY2xhc3M9XCJiaSBiaS1wZW5jaWxcIj48L2k+XG4gICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwiYnRuIGJ0bi1kYW5nZXJcIiB0aXRsZT1cIlN1c3BlbmRcIj5cbiAgICAgICAgICAgICAgICA8aSBjbGFzcz1cImJpIGJpLWJhblwiPjwvaT5cbiAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L3RkPlxuICAgICAgICA8L3RyPlxuICAgICAgICA8dHI+XG4gICAgICAgICAgPHRkPjxpbnB1dCB0eXBlPVwiY2hlY2tib3hcIiBjbGFzcz1cImZvcm0tY2hlY2staW5wdXQgdXNlci1zZWxlY3RcIj48L3RkPlxuICAgICAgICAgIDx0ZD4jVTAwNTwvdGQ+XG4gICAgICAgICAgPHRkPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImQtZmxleCBhbGlnbi1pdGVtcy1jZW50ZXJcIj5cbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImF2YXRhci1zbSBtZS0yXCI+XG4gICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJhdmF0YXItaW5pdGlhbHNcIj5USjwvc3Bhbj5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgIFRvbSBKb2huc29uXG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L3RkPlxuICAgICAgICAgIDx0ZD50b20uakBleGFtcGxlLmNvbTwvdGQ+XG4gICAgICAgICAgPHRkPjxzcGFuIGNsYXNzPVwiYmFkZ2UgYmctc2Vjb25kYXJ5XCI+VXNlcjwvc3Bhbj48L3RkPlxuICAgICAgICAgIDx0ZD5TdXBwb3J0PC90ZD5cbiAgICAgICAgICA8dGQ+PHNwYW4gY2xhc3M9XCJiYWRnZSBiZy1kYW5nZXJcIj5TdXNwZW5kZWQ8L3NwYW4+PC90ZD5cbiAgICAgICAgICA8dGQ+MiB3ZWVrcyBhZ288L3RkPlxuICAgICAgICAgIDx0ZD5NYXkgMTIsIDIwMjM8L3RkPlxuICAgICAgICAgIDx0ZD5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJidG4tZ3JvdXAgYnRuLWdyb3VwLXNtXCI+XG4gICAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJidG4gYnRuLXByaW1hcnlcIiB0aXRsZT1cIlZpZXcgUHJvZmlsZVwiPlxuICAgICAgICAgICAgICAgIDxpIGNsYXNzPVwiYmkgYmktZXllXCI+PC9pPlxuICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cImJ0biBidG4tc2Vjb25kYXJ5XCIgdGl0bGU9XCJFZGl0XCI+XG4gICAgICAgICAgICAgICAgPGkgY2xhc3M9XCJiaSBiaS1wZW5jaWxcIj48L2k+XG4gICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwiYnRuIGJ0bi1zdWNjZXNzXCIgdGl0bGU9XCJSZWFjdGl2YXRlXCI+XG4gICAgICAgICAgICAgICAgPGkgY2xhc3M9XCJiaSBiaS1hcnJvdy1jbG9ja3dpc2VcIj48L2k+XG4gICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC90ZD5cbiAgICAgICAgPC90cj5cbiAgICAgICAgPHRyPlxuICAgICAgICAgIDx0ZD48aW5wdXQgdHlwZT1cImNoZWNrYm94XCIgY2xhc3M9XCJmb3JtLWNoZWNrLWlucHV0IHVzZXItc2VsZWN0XCI+PC90ZD5cbiAgICAgICAgICA8dGQ+I1UwMDY8L3RkPlxuICAgICAgICAgIDx0ZD5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkLWZsZXggYWxpZ24taXRlbXMtY2VudGVyXCI+XG4gICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJhdmF0YXItc20gbWUtMlwiPlxuICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiYXZhdGFyLWluaXRpYWxzXCI+RUQ8L3NwYW4+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICBFbWlseSBEYXZpc1xuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC90ZD5cbiAgICAgICAgICA8dGQ+ZW1pbHkuZEBleGFtcGxlLmNvbTwvdGQ+XG4gICAgICAgICAgPHRkPjxzcGFuIGNsYXNzPVwiYmFkZ2UgYmctZGFuZ2VyXCI+QWRtaW48L3NwYW4+PC90ZD5cbiAgICAgICAgICA8dGQ+SVQ8L3RkPlxuICAgICAgICAgIDx0ZD48c3BhbiBjbGFzcz1cImJhZGdlIGJnLXN1Y2Nlc3NcIj5BY3RpdmU8L3NwYW4+PC90ZD5cbiAgICAgICAgICA8dGQ+SnVzdCBub3c8L3RkPlxuICAgICAgICAgIDx0ZD5KdW4gMDEsIDIwMjM8L3RkPlxuICAgICAgICAgIDx0ZD5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJidG4tZ3JvdXAgYnRuLWdyb3VwLXNtXCI+XG4gICAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJidG4gYnRuLXByaW1hcnlcIiB0aXRsZT1cIlZpZXcgUHJvZmlsZVwiPlxuICAgICAgICAgICAgICAgIDxpIGNsYXNzPVwiYmkgYmktZXllXCI+PC9pPlxuICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cImJ0biBidG4tc2Vjb25kYXJ5XCIgdGl0bGU9XCJFZGl0XCI+XG4gICAgICAgICAgICAgICAgPGkgY2xhc3M9XCJiaSBiaS1wZW5jaWxcIj48L2k+XG4gICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwiYnRuIGJ0bi1kYW5nZXJcIiB0aXRsZT1cIlN1c3BlbmRcIj5cbiAgICAgICAgICAgICAgICA8aSBjbGFzcz1cImJpIGJpLWJhblwiPjwvaT5cbiAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L3RkPlxuICAgICAgICA8L3RyPlxuICAgICAgICA8dHI+XG4gICAgICAgICAgPHRkPjxpbnB1dCB0eXBlPVwiY2hlY2tib3hcIiBjbGFzcz1cImZvcm0tY2hlY2staW5wdXQgdXNlci1zZWxlY3RcIj48L3RkPlxuICAgICAgICAgIDx0ZD4jVTAwNzwvdGQ+XG4gICAgICAgICAgPHRkPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImQtZmxleCBhbGlnbi1pdGVtcy1jZW50ZXJcIj5cbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImF2YXRhci1zbSBtZS0yXCI+XG4gICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJhdmF0YXItaW5pdGlhbHNcIj5DRzwvc3Bhbj5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgIENocmlzIEdhcmNpYVxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC90ZD5cbiAgICAgICAgICA8dGQ+Y2hyaXMuZ0BleGFtcGxlLmNvbTwvdGQ+XG4gICAgICAgICAgPHRkPjxzcGFuIGNsYXNzPVwiYmFkZ2UgYmctc2Vjb25kYXJ5XCI+VXNlcjwvc3Bhbj48L3RkPlxuICAgICAgICAgIDx0ZD5GaW5hbmNlPC90ZD5cbiAgICAgICAgICA8dGQ+PHNwYW4gY2xhc3M9XCJiYWRnZSBiZy1zdWNjZXNzXCI+QWN0aXZlPC9zcGFuPjwvdGQ+XG4gICAgICAgICAgPHRkPjYgaG91cnMgYWdvPC90ZD5cbiAgICAgICAgICA8dGQ+SnVsIDE1LCAyMDIzPC90ZD5cbiAgICAgICAgICA8dGQ+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiYnRuLWdyb3VwIGJ0bi1ncm91cC1zbVwiPlxuICAgICAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwiYnRuIGJ0bi1wcmltYXJ5XCIgdGl0bGU9XCJWaWV3IFByb2ZpbGVcIj5cbiAgICAgICAgICAgICAgICA8aSBjbGFzcz1cImJpIGJpLWV5ZVwiPjwvaT5cbiAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJidG4gYnRuLXNlY29uZGFyeVwiIHRpdGxlPVwiRWRpdFwiPlxuICAgICAgICAgICAgICAgIDxpIGNsYXNzPVwiYmkgYmktcGVuY2lsXCI+PC9pPlxuICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cImJ0biBidG4tZGFuZ2VyXCIgdGl0bGU9XCJTdXNwZW5kXCI+XG4gICAgICAgICAgICAgICAgPGkgY2xhc3M9XCJiaSBiaS1iYW5cIj48L2k+XG4gICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC90ZD5cbiAgICAgICAgPC90cj5cbiAgICAgICAgPHRyPlxuICAgICAgICAgIDx0ZD48aW5wdXQgdHlwZT1cImNoZWNrYm94XCIgY2xhc3M9XCJmb3JtLWNoZWNrLWlucHV0IHVzZXItc2VsZWN0XCI+PC90ZD5cbiAgICAgICAgICA8dGQ+I1UwMDg8L3RkPlxuICAgICAgICAgIDx0ZD5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJkLWZsZXggYWxpZ24taXRlbXMtY2VudGVyXCI+XG4gICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJhdmF0YXItc20gbWUtMlwiPlxuICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiYXZhdGFyLWluaXRpYWxzXCI+QU08L3NwYW4+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICBBc2hsZXkgTWFydGluZXpcbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgPHRkPmFzaGxleS5tQGV4YW1wbGUuY29tPC90ZD5cbiAgICAgICAgICA8dGQ+PHNwYW4gY2xhc3M9XCJiYWRnZSBiZy1wcmltYXJ5XCI+TWFuYWdlcjwvc3Bhbj48L3RkPlxuICAgICAgICAgIDx0ZD5PcGVyYXRpb25zPC90ZD5cbiAgICAgICAgICA8dGQ+PHNwYW4gY2xhc3M9XCJiYWRnZSBiZy1zdWNjZXNzXCI+QWN0aXZlPC9zcGFuPjwvdGQ+XG4gICAgICAgICAgPHRkPjEyIGhvdXJzIGFnbzwvdGQ+XG4gICAgICAgICAgPHRkPkF1ZyAyMCwgMjAyMzwvdGQ+XG4gICAgICAgICAgPHRkPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImJ0bi1ncm91cCBidG4tZ3JvdXAtc21cIj5cbiAgICAgICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cImJ0biBidG4tcHJpbWFyeVwiIHRpdGxlPVwiVmlldyBQcm9maWxlXCI+XG4gICAgICAgICAgICAgICAgPGkgY2xhc3M9XCJiaSBiaS1leWVcIj48L2k+XG4gICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwiYnRuIGJ0bi1zZWNvbmRhcnlcIiB0aXRsZT1cIkVkaXRcIj5cbiAgICAgICAgICAgICAgICA8aSBjbGFzcz1cImJpIGJpLXBlbmNpbFwiPjwvaT5cbiAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJidG4gYnRuLWRhbmdlclwiIHRpdGxlPVwiU3VzcGVuZFwiPlxuICAgICAgICAgICAgICAgIDxpIGNsYXNzPVwiYmkgYmktYmFuXCI+PC9pPlxuICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwvdGQ+XG4gICAgICAgIDwvdHI+XG4gICAgICAgIDx0cj5cbiAgICAgICAgICA8dGQ+PGlucHV0IHR5cGU9XCJjaGVja2JveFwiIGNsYXNzPVwiZm9ybS1jaGVjay1pbnB1dCB1c2VyLXNlbGVjdFwiPjwvdGQ+XG4gICAgICAgICAgPHRkPiNVMDA5PC90ZD5cbiAgICAgICAgICA8dGQ+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZC1mbGV4IGFsaWduLWl0ZW1zLWNlbnRlclwiPlxuICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiYXZhdGFyLXNtIG1lLTJcIj5cbiAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImF2YXRhci1pbml0aWFsc1wiPktMPC9zcGFuPlxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgS2V2aW4gTGVlXG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L3RkPlxuICAgICAgICAgIDx0ZD5rZXZpbi5sZWVAZXhhbXBsZS5jb208L3RkPlxuICAgICAgICAgIDx0ZD48c3BhbiBjbGFzcz1cImJhZGdlIGJnLXNlY29uZGFyeVwiPlVzZXI8L3NwYW4+PC90ZD5cbiAgICAgICAgICA8dGQ+RGVzaWduPC90ZD5cbiAgICAgICAgICA8dGQ+PHNwYW4gY2xhc3M9XCJiYWRnZSBiZy1zdWNjZXNzXCI+QWN0aXZlPC9zcGFuPjwvdGQ+XG4gICAgICAgICAgPHRkPjEgZGF5IGFnbzwvdGQ+XG4gICAgICAgICAgPHRkPlNlcCAxMCwgMjAyMzwvdGQ+XG4gICAgICAgICAgPHRkPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImJ0bi1ncm91cCBidG4tZ3JvdXAtc21cIj5cbiAgICAgICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cImJ0biBidG4tcHJpbWFyeVwiIHRpdGxlPVwiVmlldyBQcm9maWxlXCI+XG4gICAgICAgICAgICAgICAgPGkgY2xhc3M9XCJiaSBiaS1leWVcIj48L2k+XG4gICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwiYnRuIGJ0bi1zZWNvbmRhcnlcIiB0aXRsZT1cIkVkaXRcIj5cbiAgICAgICAgICAgICAgICA8aSBjbGFzcz1cImJpIGJpLXBlbmNpbFwiPjwvaT5cbiAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJidG4gYnRuLWRhbmdlclwiIHRpdGxlPVwiU3VzcGVuZFwiPlxuICAgICAgICAgICAgICAgIDxpIGNsYXNzPVwiYmkgYmktYmFuXCI+PC9pPlxuICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwvdGQ+XG4gICAgICAgIDwvdHI+XG4gICAgICAgIDx0cj5cbiAgICAgICAgICA8dGQ+PGlucHV0IHR5cGU9XCJjaGVja2JveFwiIGNsYXNzPVwiZm9ybS1jaGVjay1pbnB1dCB1c2VyLXNlbGVjdFwiPjwvdGQ+XG4gICAgICAgICAgPHRkPiNVMDEwPC90ZD5cbiAgICAgICAgICA8dGQ+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZC1mbGV4IGFsaWduLWl0ZW1zLWNlbnRlclwiPlxuICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiYXZhdGFyLXNtIG1lLTJcIj5cbiAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImF2YXRhci1pbml0aWFsc1wiPlJXPC9zcGFuPlxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgUmFjaGVsIFdoaXRlXG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L3RkPlxuICAgICAgICAgIDx0ZD5yYWNoZWwud0BleGFtcGxlLmNvbTwvdGQ+XG4gICAgICAgICAgPHRkPjxzcGFuIGNsYXNzPVwiYmFkZ2UgYmctc2Vjb25kYXJ5XCI+VXNlcjwvc3Bhbj48L3RkPlxuICAgICAgICAgIDx0ZD5MZWdhbDwvdGQ+XG4gICAgICAgICAgPHRkPjxzcGFuIGNsYXNzPVwiYmFkZ2UgYmctd2FybmluZ1wiPkluYWN0aXZlPC9zcGFuPjwvdGQ+XG4gICAgICAgICAgPHRkPjEgd2VlayBhZ288L3RkPlxuICAgICAgICAgIDx0ZD5PY3QgMDUsIDIwMjM8L3RkPlxuICAgICAgICAgIDx0ZD5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJidG4tZ3JvdXAgYnRuLWdyb3VwLXNtXCI+XG4gICAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJidG4gYnRuLXByaW1hcnlcIiB0aXRsZT1cIlZpZXcgUHJvZmlsZVwiPlxuICAgICAgICAgICAgICAgIDxpIGNsYXNzPVwiYmkgYmktZXllXCI+PC9pPlxuICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cImJ0biBidG4tc2Vjb25kYXJ5XCIgdGl0bGU9XCJFZGl0XCI+XG4gICAgICAgICAgICAgICAgPGkgY2xhc3M9XCJiaSBiaS1wZW5jaWxcIj48L2k+XG4gICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwiYnRuIGJ0bi1zdWNjZXNzXCIgdGl0bGU9XCJBY3RpdmF0ZVwiPlxuICAgICAgICAgICAgICAgIDxpIGNsYXNzPVwiYmkgYmktY2hlY2stY2lyY2xlXCI+PC9pPlxuICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwvdGQ+XG4gICAgICAgIDwvdHI+XG4gICAgICA8L3Rib2R5PlxuICAgIDwvdGFibGU+XG4gIDwvZGl2PlxuPC9EZWZpbmU6VXNlcnNfRGF0YV9UYWJsZT5cbiIsIjwhLS1cblJzeF9Nb2RhbCBDb21wb25lbnRcblxuQmFzZSBtb2RhbCBjb21wb25lbnQgZm9yIGRpc3BsYXlpbmcgZGlhbG9ncywgZm9ybXMsIGFuZCBjdXN0b20gY29udGVudC5cblVzZXMgQm9vdHN0cmFwIDUgbW9kYWwgYXMgZm91bmRhdGlvbiB3aXRoIGN1c3RvbSBzaXppbmcgYW5kIGJlaGF2aW9yLlxuXG5BcmdzOlxuLSAkdGl0bGU6IE1vZGFsIHRpdGxlIHRleHRcbi0gJGNsb3NhYmxlOiBBbGxvdyBFU0MvYmFja2Ryb3AvWCB0byBjbG9zZSAoZGVmYXVsdDogdHJ1ZSlcbi0gJG1heF93aWR0aDogTWF4aW11bSB3aWR0aCBpbiBwaXhlbHMgKGRlZmF1bHQ6IDgwMClcblxuVGhlIG1vZGFsIGJvZHkgYW5kIGZvb3RlciBhcmUgcG9wdWxhdGVkIGR5bmFtaWNhbGx5IHZpYSB0aGUgTW9kYWwuanMgQVBJLlxuLS0+XG48RGVmaW5lOlJzeF9Nb2RhbD5cbiAgICA8ZGl2IGNsYXNzPVwibW9kYWwgZmFkZSByc3gtbW9kYWxcIiB0YWJpbmRleD1cIi0xXCIgJGlkPVwibW9kYWxcIj5cbiAgICAgICAgPGRpdiBjbGFzcz1cIm1vZGFsLWRpYWxvZ1wiICRpZD1cImRpYWxvZ1wiPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1vZGFsLWNvbnRlbnRcIj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibW9kYWwtaGVhZGVyXCIgJGlkPVwiaGVhZGVyXCI+XG4gICAgICAgICAgICAgICAgICAgIDxoNSBjbGFzcz1cIm1vZGFsLXRpdGxlXCIgJGlkPVwidGl0bGVcIj48L2g1PlxuICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cImJ0bi1jbG9zZVwiICRpZD1cImNsb3NlX2J0blwiIGRhdGEtYnMtZGlzbWlzcz1cIm1vZGFsXCIgYXJpYS1sYWJlbD1cIkNsb3NlXCI+PC9idXR0b24+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1vZGFsLWJvZHlcIiAkaWQ9XCJib2R5XCI+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtb2RhbC1ib2R5LWNvbnRlbnRcIiAkaWQ9XCJib2R5X2NvbnRlbnRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwhLS0gRHluYW1pYyBjb250ZW50IGluc2VydGVkIGhlcmUgLS0+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtb2RhbC1mb290ZXJcIiAkaWQ9XCJmb290ZXJcIj5cbiAgICAgICAgICAgICAgICAgICAgPCEtLSBEeW5hbWljIGJ1dHRvbnMgaW5zZXJ0ZWQgaGVyZSAtLT5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbiAgICA8ZGl2IGNsYXNzPVwibW9kYWwtYmFja2Ryb3AgZmFkZVwiICRpZD1cImJhY2tkcm9wXCI+PC9kaXY+XG48L0RlZmluZTpSc3hfTW9kYWw+XG4iLCI8IS0tXG5CcmVhZGNydW1iXG5cbkJyZWFkY3J1bWIgbmF2aWdhdGlvbiBjb21wb25lbnQgZm9sbG93aW5nIEJvb3RzdHJhcCA1IHN0eWxpbmcuXG5Vc2VzIHRyYW5zcGFyZW50IGJhY2tncm91bmQgYW5kIG5vIHBhZGRpbmcgZm9yIGNsZWFuIGludGVncmF0aW9uIHdpdGggUGFnZV9IZWFkZXIuXG5cblVzYWdlOlxuPEJyZWFkY3J1bWI+XG4gIDxCcmVhZGNydW1iX0l0ZW0gaHJlZj1cIjwlPSBSc3guUm91dGUoJ0Zyb250ZW5kX0Rhc2hib2FyZF9Db250cm9sbGVyJykgJT5cIj5EYXNoYm9hcmQ8L0JyZWFkY3J1bWJfSXRlbT5cbiAgPEJyZWFkY3J1bWJfSXRlbSBocmVmPVwiPCU9IFJzeC5Sb3V0ZSgnRnJvbnRlbmRfQ2xpZW50c19Db250cm9sbGVyJykgJT5cIj5DbGllbnRzPC9CcmVhZGNydW1iX0l0ZW0+XG4gIDxCcmVhZGNydW1iX0l0ZW0gYWN0aXZlPlZpZXc8L0JyZWFkY3J1bWJfSXRlbT5cbjwvQnJlYWRjcnVtYj5cbi0tPlxuPERlZmluZTpCcmVhZGNydW1iIHRhZz1cIm5hdlwiIGFyaWEtbGFiZWw9XCJicmVhZGNydW1iXCI+XG4gIDxvbCBjbGFzcz1cImJyZWFkY3J1bWIgYmctdHJhbnNwYXJlbnQgcC0wIG1iLTBcIj5cbiAgICA8JT0gY29udGVudCgpICU+XG4gIDwvb2w+XG48L0RlZmluZTpCcmVhZGNydW1iPlxuIiwiPCEtLVxuQnJlYWRjcnVtYl9JdGVtXG5cbkluZGl2aWR1YWwgYnJlYWRjcnVtYiBpdGVtLiBDYW4gYmUgYSBsaW5rIG9yIGFjdGl2ZSAoY3VycmVudCBwYWdlKS5cblxuJGhyZWYgLSBPcHRpb25hbCBsaW5rIFVSTC4gSWYgb21pdHRlZCwgcmVuZGVycyBhcyBwbGFpbiB0ZXh0LlxuJGFjdGl2ZSAtIEJvb2xlYW4uIElmIHRydWUsIHJlbmRlcnMgYXMgYWN0aXZlIGl0ZW0gKGN1cnJlbnQgcGFnZSkuXG5cblVzYWdlOlxuPEJyZWFkY3J1bWJfSXRlbSBocmVmPVwiPCU9IFJzeC5Sb3V0ZSgnRnJvbnRlbmRfRGFzaGJvYXJkX0NvbnRyb2xsZXInKSAlPlwiPkRhc2hib2FyZDwvQnJlYWRjcnVtYl9JdGVtPlxuPEJyZWFkY3J1bWJfSXRlbSBhY3RpdmU+Q3VycmVudCBQYWdlPC9CcmVhZGNydW1iX0l0ZW0+XG4tLT5cbjxEZWZpbmU6QnJlYWRjcnVtYl9JdGVtIHRhZz1cImxpXCIgY2xhc3M9XCJicmVhZGNydW1iLWl0ZW1cIj5cbiAgPCUgaWYgKHRoaXMuYXJncy5hY3RpdmUpIHsgJT5cbiAgICA8JT0gY29udGVudCgpICU+XG4gIDwlIH0gZWxzZSBpZiAodGhpcy5hcmdzLmhyZWYpIHsgJT5cbiAgICA8YSBocmVmPVwiPCU9IHRoaXMuYXJncy5ocmVmICU+XCI+PCU9IGNvbnRlbnQoKSAlPjwvYT5cbiAgPCUgfSBlbHNlIHsgJT5cbiAgICA8JT0gY29udGVudCgpICU+XG4gIDwlIH0gJT5cbjwvRGVmaW5lOkJyZWFkY3J1bWJfSXRlbT5cbiIsIjwhLS1cbkRpc3BsYXlzIGEgY2xpZW50IG5hbWUuXG5Mb2FkcyBjbGllbnQgZGF0YSB2aWEgQWpheCBhbmQgc2hvd3MgdGhlIG5hbWUgb25jZSBsb2FkZWQuXG5cbiRjbGllbnRfaWQgLSBDbGllbnQgSUQgdG8gZGlzcGxheVxuJHBsYWNlaG9sZGVyIC0gVGV4dCB0byBzaG93IHdoaWxlIGxvYWRpbmcgKGRlZmF1bHQ6IFwiLS0tLS0tXCIpXG5cbldpZGdldCBpbnRlcmZhY2U6XG4tIHZhbCgpIC0gR2V0IGN1cnJlbnQgY2xpZW50X2lkXG4tIHZhbChpZCkgLSBTZXQgbmV3IGNsaWVudF9pZCBhbmQgcmVsb2FkXG4tLT5cbjxEZWZpbmU6Q2xpZW50X0xhYmVsIHRhZz1cInNwYW5cIiBjbGFzcz1cIldpZGdldFwiPlxuXG4gICAgPGkgY2xhc3M9XCJiaSBiaS1idWlsZGluZ1wiPjwvaT5cbiAgICA8JSBpZiAodGhpcy5kYXRhLmxvYWRpbmcpIHsgJT5cbiAgICAgICAgPCU9IHRoaXMuYXJncy5wbGFjZWhvbGRlciB8fCAnLS0tLS0tJyAlPlxuICAgIDwlIH0gZWxzZSBpZiAodGhpcy5kYXRhLmNsaWVudCkgeyAlPlxuICAgICAgICA8JT0gdGhpcy5kYXRhLmNsaWVudC5uYW1lICU+IGNhZGZkc2FcbiAgICA8JSB9IGVsc2UgeyAlPlxuICAgICAgICA8c3BhbiBjbGFzcz1cInRleHQtbXV0ZWRcIj5Vbmtub3duIENsaWVudDwvc3Bhbj5cbiAgICA8JSB9ICU+XG5cbjwvRGVmaW5lOkNsaWVudF9MYWJlbD4iLCI8IS0tXG5DbGllbnRfTGFiZWxfTGlua1xuXG5EaXNwbGF5cyBhIGNsaWNrYWJsZSBjbGllbnQgbmFtZSB0aGF0IGxpbmtzIHRvIHRoZSBjbGllbnQgdmlldyBwYWdlLlxuTG9hZHMgY2xpZW50IGRhdGEgdmlhIEFqYXggYW5kIHNob3dzIHRoZSBuYW1lIG9uY2UgbG9hZGVkLlxuXG4kY2xpZW50X2lkIC0gQ2xpZW50IElEIHRvIGRpc3BsYXlcbiRwbGFjZWhvbGRlciAtIFRleHQgdG8gc2hvdyB3aGlsZSBsb2FkaW5nIChkZWZhdWx0OiBcIi0tLS0tLVwiKVxuXG5XaWRnZXQgaW50ZXJmYWNlOlxuLSB2YWwoKSAtIEdldCBjdXJyZW50IGNsaWVudF9pZFxuLSB2YWwoaWQpIC0gU2V0IG5ldyBjbGllbnRfaWQgYW5kIHJlbG9hZFxuLS0+XG48RGVmaW5lOkNsaWVudF9MYWJlbF9MaW5rIHRhZz1cImFcIiBjbGFzcz1cIldpZGdldFwiPlxuXG4gICAgPGkgY2xhc3M9XCJiaSBiaS1idWlsZGluZ1wiPjwvaT5cbiAgICA8JSBpZiAodGhpcy5kYXRhLmxvYWRpbmcpIHsgJT5cbiAgICAgICAgPCU9IHRoaXMuYXJncy5wbGFjZWhvbGRlciB8fCAnLS0tLS0tJyAlPlxuICAgIDwlIH0gZWxzZSBpZiAodGhpcy5kYXRhLmNsaWVudCkgeyAlPlxuICAgICAgICA8JT0gdGhpcy5kYXRhLmNsaWVudC5uYW1lICU+XG4gICAgPCUgfSBlbHNlIHsgJT5cbiAgICAgICAgPHNwYW4gY2xhc3M9XCJ0ZXh0LW11dGVkXCI+VW5rbm93biBDbGllbnQ8L3NwYW4+XG4gICAgPCUgfSAlPlxuXG48L0RlZmluZTpDbGllbnRfTGFiZWxfTGluaz4iLCI8IS0tXG5UZXh0X0lucHV0XG5cbkJhc2ljIHRleHQgaW5wdXQgd2lkZ2V0LiBTdXBwb3J0cyB2YXJpb3VzIGlucHV0IHR5cGVzICh0ZXh0LCBlbWFpbCwgdXJsLCB0ZWwsIG51bWJlciwgdGV4dGFyZWEpLlxuXG4kdHlwZSAtIElucHV0IHR5cGUgKGRlZmF1bHQ6IHRleHQpLiBVc2UgXCJ0ZXh0YXJlYVwiIGZvciBtdWx0aWxpbmUgdGV4dC5cbiRyb3dzIC0gTnVtYmVyIG9mIHJvd3MgZm9yIHRleHRhcmVhIChkZWZhdWx0OiAzKVxuJHBsYWNlaG9sZGVyIC0gUGxhY2Vob2xkZXIgdGV4dFxuJHByZWZpeCAtIFRleHQgdG8gcHJlcGVuZCBiZWZvcmUgaW5wdXQgKGNyZWF0ZXMgaW5wdXQtZ3JvdXApXG4kc3VmZml4IC0gVGV4dCB0byBhcHBlbmQgYWZ0ZXIgaW5wdXQgKGNyZWF0ZXMgaW5wdXQtZ3JvdXApXG4kbWluIC0gTWluaW11bSB2YWx1ZSBmb3IgbnVtYmVyIGlucHV0c1xuJG1heCAtIE1heGltdW0gdmFsdWUgZm9yIG51bWJlciBpbnB1dHNcbiRtYXhsZW5ndGggLSBNYXhpbXVtIGxlbmd0aCBmb3IgdGV4dCBpbnB1dHNcbiRkaXNhYmxlZCAtIEJvb2xlYW4gdG8gZGlzYWJsZSB0aGUgaW5wdXQgKHN0aWxsIHJldHVybnMgdmFsdWUgdmlhIHZhbCgpKVxuJHNlZWRlciAtIFNlZWRlciBmdW5jdGlvbiBuYW1lIChlLmcuLCBcImZpcnN0X25hbWVcIiBjYWxscyBSc3hfUmFuZG9tX1ZhbHVlcy5maXJzdF9uYW1lKCkpXG5cblVzYWdlOlxuPFRleHRfSW5wdXQgJHR5cGU9XCJlbWFpbFwiICRwbGFjZWhvbGRlcj1cInVzZXJAZXhhbXBsZS5jb21cIiAvPlxuPFRleHRfSW5wdXQgJHR5cGU9XCJ1cmxcIiAkcGxhY2Vob2xkZXI9XCJodHRwczovL2V4YW1wbGUuY29tXCIgLz5cbjxUZXh0X0lucHV0ICR0eXBlPVwidGV4dGFyZWFcIiAkcm93cz01IC8+XG48VGV4dF9JbnB1dCAkcHJlZml4PVwiQFwiICRwbGFjZWhvbGRlcj1cInVzZXJuYW1lXCIgLz5cbjxUZXh0X0lucHV0ICRzZWVkZXI9XCJjb21wYW55X25hbWVcIiAvPlxuLS0+XG48RGVmaW5lOlRleHRfSW5wdXQgY2xhc3M9XCJXaWRnZXRcIj5cbiAgICA8JSBpZiAodGhpcy5hcmdzLnR5cGUgPT09ICd0ZXh0YXJlYScpIHsgJT5cbiAgICAgICAgPHRleHRhcmVhICRpZD1cImlucHV0XCJcbiAgICAgICAgICAgICAgICAgIGNsYXNzPVwiZm9ybS1jb250cm9sXCJcbiAgICAgICAgICAgICAgICAgIHJvd3M9XCI8JT0gdGhpcy5hcmdzLnJvd3MgfHwgMyAlPlwiXG4gICAgICAgICAgICAgICAgICBwbGFjZWhvbGRlcj1cIjwlPSB0aGlzLmFyZ3MucGxhY2Vob2xkZXIgfHwgJycgJT5cIlxuICAgICAgICAgICAgICAgICAgPCUgaWYgKHRoaXMuYXJncy5kaXNhYmxlZCkgeyAlPmRpc2FibGVkPCUgfSAlPj48JT0gdGhpcy5kYXRhLnZhbHVlICU+PC90ZXh0YXJlYT5cbiAgICA8JSB9IGVsc2UgaWYgKHRoaXMuYXJncy5wcmVmaXggfHwgdGhpcy5hcmdzLnN1ZmZpeCkgeyAlPlxuICAgICAgICA8ZGl2IGNsYXNzPVwiaW5wdXQtZ3JvdXBcIj5cbiAgICAgICAgICAgIDwlIGlmICh0aGlzLmFyZ3MucHJlZml4KSB7ICU+XG4gICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJpbnB1dC1ncm91cC10ZXh0XCI+PCU9IHRoaXMuYXJncy5wcmVmaXggJT48L3NwYW4+XG4gICAgICAgICAgICA8JSB9ICU+XG4gICAgICAgICAgICA8aW5wdXQgJGlkPVwiaW5wdXRcIlxuICAgICAgICAgICAgICAgICAgIHR5cGU9XCI8JT0gdGhpcy5hcmdzLnR5cGUgfHwgJ3RleHQnICU+XCJcbiAgICAgICAgICAgICAgICAgICBjbGFzcz1cImZvcm0tY29udHJvbFwiXG4gICAgICAgICAgICAgICAgICAgdmFsdWU9XCI8JT0gdGhpcy5kYXRhLnZhbHVlICU+XCJcbiAgICAgICAgICAgICAgICAgICBwbGFjZWhvbGRlcj1cIjwlPSB0aGlzLmFyZ3MucGxhY2Vob2xkZXIgfHwgJycgJT5cIlxuICAgICAgICAgICAgICAgICAgIDwlIGlmICh0aGlzLmFyZ3MubWluICE9PSB1bmRlZmluZWQpIHsgJT5taW49XCI8JT0gdGhpcy5hcmdzLm1pbiAlPlwiPCUgfSAlPlxuICAgICAgICAgICAgICAgICAgIDwlIGlmICh0aGlzLmFyZ3MubWF4ICE9PSB1bmRlZmluZWQpIHsgJT5tYXg9XCI8JT0gdGhpcy5hcmdzLm1heCAlPlwiPCUgfSAlPlxuICAgICAgICAgICAgICAgICAgIDwlIGlmICh0aGlzLmFyZ3MubWF4bGVuZ3RoKSB7ICU+bWF4bGVuZ3RoPVwiPCU9IHRoaXMuYXJncy5tYXhsZW5ndGggJT5cIjwlIH0gJT5cbiAgICAgICAgICAgICAgICAgICA8JSBpZiAodGhpcy5hcmdzLmRpc2FibGVkKSB7ICU+ZGlzYWJsZWQ8JSB9ICU+IC8+XG4gICAgICAgICAgICA8JSBpZiAodGhpcy5hcmdzLnN1ZmZpeCkgeyAlPlxuICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiaW5wdXQtZ3JvdXAtdGV4dFwiPjwlPSB0aGlzLmFyZ3Muc3VmZml4ICU+PC9zcGFuPlxuICAgICAgICAgICAgPCUgfSAlPlxuICAgICAgICA8L2Rpdj5cbiAgICA8JSB9IGVsc2UgeyAlPlxuICAgICAgICA8aW5wdXQgJGlkPVwiaW5wdXRcIlxuICAgICAgICAgICAgICAgdHlwZT1cIjwlPSB0aGlzLmFyZ3MudHlwZSB8fCAndGV4dCcgJT5cIlxuICAgICAgICAgICAgICAgY2xhc3M9XCJmb3JtLWNvbnRyb2xcIlxuICAgICAgICAgICAgICAgdmFsdWU9XCI8JT0gdGhpcy5kYXRhLnZhbHVlICU+XCJcbiAgICAgICAgICAgICAgIHBsYWNlaG9sZGVyPVwiPCU9IHRoaXMuYXJncy5wbGFjZWhvbGRlciB8fCAnJyAlPlwiXG4gICAgICAgICAgICAgICA8JSBpZiAodGhpcy5hcmdzLm1pbiAhPT0gdW5kZWZpbmVkKSB7ICU+bWluPVwiPCU9IHRoaXMuYXJncy5taW4gJT5cIjwlIH0gJT5cbiAgICAgICAgICAgICAgIDwlIGlmICh0aGlzLmFyZ3MubWF4ICE9PSB1bmRlZmluZWQpIHsgJT5tYXg9XCI8JT0gdGhpcy5hcmdzLm1heCAlPlwiPCUgfSAlPlxuICAgICAgICAgICAgICAgPCUgaWYgKHRoaXMuYXJncy5tYXhsZW5ndGgpIHsgJT5tYXhsZW5ndGg9XCI8JT0gdGhpcy5hcmdzLm1heGxlbmd0aCAlPlwiPCUgfSAlPlxuICAgICAgICAgICAgICAgPCUgaWYgKHRoaXMuYXJncy5kaXNhYmxlZCkgeyAlPmRpc2FibGVkPCUgfSAlPiAvPlxuICAgIDwlIH0gJT5cbjwvRGVmaW5lOlRleHRfSW5wdXQ+XG4iLCI8IS0tXG5TZWxlY3RfSW5wdXRcblxuRHJvcGRvd24gc2VsZWN0IHdpZGdldCBmb3IgZm9ybXMuXG5cbiRvcHRpb25zIC0gQXJyYXkgb2Ygb3B0aW9uczogW3t2YWx1ZTogJ3ZhbCcsIGxhYmVsOiAnTGFiZWwnfSwgLi4uXSBvciBzaW1wbGUgYXJyYXkgWyd2YWwxJywgJ3ZhbDInXVxuJHBsYWNlaG9sZGVyIC0gUGxhY2Vob2xkZXIgb3B0aW9uIHRleHQgKGNyZWF0ZXMgZW1wdHkgb3B0aW9uIGF0IHRvcClcbiRkaXNhYmxlZCAtIEJvb2xlYW4gdG8gZGlzYWJsZSB0aGUgc2VsZWN0IChzdGlsbCByZXR1cm5zIHZhbHVlIHZpYSB2YWwoKSlcbiRzZWVkZXIgLSBTZWVkZXIgZnVuY3Rpb24gbmFtZSBmb3IgdGVzdCBkYXRhXG5cbldpZGdldCBpbnRlcmZhY2U6XG4tIHZhbCgpIC0gR2V0L3NldCBzZWxlY3RlZCB2YWx1ZVxuLSBzZWVkKCkgLSBGaWxscyB3aXRoIHJhbmRvbSB2YWx1ZVxuLS0+XG48RGVmaW5lOlNlbGVjdF9JbnB1dCBjbGFzcz1cIldpZGdldFwiPlxuICAgIDxzZWxlY3QgJGlkPVwiaW5wdXRcIiA8JSBpZiAodGhpcy5hcmdzLmRpc2FibGVkKSB7ICU+ZGlzYWJsZWQ8JSB9ICU+PlxuICAgICAgICA8JSBpZiAodGhpcy5hcmdzLnBsYWNlaG9sZGVyKSB7ICU+XG4gICAgICAgICAgICA8b3B0aW9uIHZhbHVlPVwiXCI+PCU9IHRoaXMuYXJncy5wbGFjZWhvbGRlciAlPjwvb3B0aW9uPlxuICAgICAgICA8JSB9ICU+XG4gICAgICAgIDwlIGlmICh0aGlzLmFyZ3Mub3B0aW9ucykgeyAlPlxuICAgICAgICAgICAgPCUgZm9yIChsZXQgb3B0IG9mIHRoaXMuYXJncy5vcHRpb25zKSB7ICU+XG4gICAgICAgICAgICAgICAgPCUgaWYgKHR5cGVvZiBvcHQgPT09ICdvYmplY3QnKSB7ICU+XG4gICAgICAgICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCI8JT0gb3B0LnZhbHVlICU+XCIgPCUgaWYgKHRoaXMuZGF0YS52YWx1ZSA9PSBvcHQudmFsdWUpIHsgJT5zZWxlY3RlZDwlIH0gJT4+PCU9IG9wdC5sYWJlbCAlPjwvb3B0aW9uPlxuICAgICAgICAgICAgICAgIDwlIH0gZWxzZSB7ICU+XG4gICAgICAgICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCI8JT0gb3B0ICU+XCIgPCUgaWYgKHRoaXMuZGF0YS52YWx1ZSA9PSBvcHQpIHsgJT5zZWxlY3RlZDwlIH0gJT4+PCU9IG9wdCAlPjwvb3B0aW9uPlxuICAgICAgICAgICAgICAgIDwlIH0gJT5cbiAgICAgICAgICAgIDwlIH0gJT5cbiAgICAgICAgPCUgfSAlPlxuICAgIDwvc2VsZWN0PlxuPC9EZWZpbmU6U2VsZWN0X0lucHV0PlxuIiwiPCEtLVxuQWpheF9TZWxlY3RfSW5wdXRcblxuRHJvcGRvd24gc2VsZWN0IHdpZGdldCB0aGF0IGxvYWRzIG9wdGlvbnMgdmlhIEFqYXguXG5FeHRlbmRzIFNlbGVjdF9JbnB1dCB3aXRoIEFqYXggZGF0YSBsb2FkaW5nIGNhcGFiaWxpdHkuXG5cbiRkYXRhIC0gQWpheCBlbmRwb2ludCBVUkwgdGhhdCByZXR1cm5zIGFycmF5IG9mIG9wdGlvbnNcbiRwbGFjZWhvbGRlciAtIFBsYWNlaG9sZGVyIG9wdGlvbiB0ZXh0IChkZWZhdWx0OiBcIlBsZWFzZSB3YWl0Li4uXCIpXG4kZGlzYWJsZWQgLSBCb29sZWFuIHRvIGRpc2FibGUgdGhlIHNlbGVjdFxuJHNlZWRlciAtIFNlZWRlciBmdW5jdGlvbiBuYW1lIGZvciB0ZXN0IGRhdGFcblxuV2lkZ2V0IGludGVyZmFjZTpcbi0gdmFsKCkgLSBHZXQvc2V0IHNlbGVjdGVkIHZhbHVlIChoYW5kbGVzIHByZS1pbml0aWFsaXphdGlvbiBjYWxscylcbi0gc2VlZCgpIC0gRmlsbHMgd2l0aCByYW5kb20gdmFsdWVcblxuRmVhdHVyZXM6XG4tIExvYWRzIG9wdGlvbnMgYXN5bmNocm9ub3VzbHkgZnJvbSBlbmRwb2ludCBkdXJpbmcgb25fbG9hZCgpXG4tIFNob3dzIFwiUGxlYXNlIHdhaXQuLi5cIiB3aGlsZSBsb2FkaW5nXG4tIEhhbmRsZXMgdmFsKCkgY2FsbHMgYmVmb3JlIGluaXRpYWxpemF0aW9uIGNvbXBsZXRlc1xuLSBSZS1yZW5kZXJzIHdpdGggYWN0dWFsIG9wdGlvbnMgb25jZSBsb2FkZWRcbi0tPlxuPERlZmluZTpBamF4X1NlbGVjdF9JbnB1dCBleHRlbmRzPVwiU2VsZWN0X0lucHV0XCIgY2xhc3M9XCJXaWRnZXRcIj5cbiAgICA8c2VsZWN0ICRpZD1cImlucHV0XCIgPCUgaWYgKHRoaXMuYXJncy5kaXNhYmxlZCkgeyAlPmRpc2FibGVkPCUgfSAlPj5cbiAgICAgICAgPCUgaWYgKCF0aGlzLmRhdGEuc2VsZWN0X3ZhbHVlcyB8fCB0aGlzLmRhdGEuc2VsZWN0X3ZhbHVlcy5sZW5ndGggPT09IDApIHsgJT5cbiAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCJcIj48JT0gdGhpcy5hcmdzLnBsYWNlaG9sZGVyIHx8ICdQbGVhc2Ugd2FpdC4uLicgJT48L29wdGlvbj5cbiAgICAgICAgPCUgfSBlbHNlIHsgJT5cbiAgICAgICAgICAgIDwlIGlmICh0aGlzLmFyZ3MucGxhY2Vob2xkZXIpIHsgJT5cbiAgICAgICAgICAgICAgICA8b3B0aW9uIHZhbHVlPVwiXCI+PCU9IHRoaXMuYXJncy5wbGFjZWhvbGRlciAlPjwvb3B0aW9uPlxuICAgICAgICAgICAgPCUgfSAlPlxuICAgICAgICAgICAgPCUgZm9yIChsZXQgb3B0IG9mIHRoaXMuZGF0YS5zZWxlY3RfdmFsdWVzKSB7ICU+XG4gICAgICAgICAgICAgICAgPCUgaWYgKHR5cGVvZiBvcHQgPT09ICdvYmplY3QnKSB7ICU+XG4gICAgICAgICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCI8JT0gb3B0LnZhbHVlICU+XCIgPCUgaWYgKHRoaXMuZGF0YS52YWx1ZSA9PSBvcHQudmFsdWUpIHsgJT5zZWxlY3RlZDwlIH0gJT4+PCU9IG9wdC5sYWJlbCAlPjwvb3B0aW9uPlxuICAgICAgICAgICAgICAgIDwlIH0gZWxzZSB7ICU+XG4gICAgICAgICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCI8JT0gb3B0ICU+XCIgPCUgaWYgKHRoaXMuZGF0YS52YWx1ZSA9PSBvcHQpIHsgJT5zZWxlY3RlZDwlIH0gJT4+PCU9IG9wdCAlPjwvb3B0aW9uPlxuICAgICAgICAgICAgICAgIDwlIH0gJT5cbiAgICAgICAgICAgIDwlIH0gJT5cbiAgICAgICAgPCUgfSAlPlxuICAgIDwvc2VsZWN0PlxuPC9EZWZpbmU6QWpheF9TZWxlY3RfSW5wdXQ+XG4iLCI8IS0tXG5DaGVja2JveF9JbnB1dFxuXG5DaGVja2JveCB3aWRnZXQgZm9yIGZvcm1zLlxuXG4kbGFiZWwgLSBMYWJlbCB0ZXh0IHRvIGRpc3BsYXkgbmV4dCB0byBjaGVja2JveFxuJGNoZWNrZWRfdmFsdWUgLSBWYWx1ZSB3aGVuIGNoZWNrZWQgKGRlZmF1bHQ6IFwiMVwiKVxuJHVuY2hlY2tlZF92YWx1ZSAtIFZhbHVlIHdoZW4gdW5jaGVja2VkIChkZWZhdWx0OiBcIjBcIilcbiRkaXNhYmxlZCAtIEJvb2xlYW4gdG8gZGlzYWJsZSB0aGUgY2hlY2tib3ggKHN0aWxsIHJldHVybnMgdmFsdWUgdmlhIHZhbCgpKVxuXG5XaWRnZXQgaW50ZXJmYWNlOlxuLSB2YWwoKSAtIEdldC9zZXQgY2hlY2tlZCBzdGF0ZSAocmV0dXJucyBjaGVja2VkX3ZhbHVlIG9yIHVuY2hlY2tlZF92YWx1ZSlcbi0gc2VlZCgpIC0gUmFuZG9tbHkgY2hlY2tzL3VuY2hlY2tzXG4tLT5cbjxEZWZpbmU6Q2hlY2tib3hfSW5wdXQgY2xhc3M9XCJXaWRnZXRcIj5cbiAgICA8ZGl2IGNsYXNzPVwiZm9ybS1jaGVja1wiPlxuICAgICAgICA8aW5wdXQgJGlkPVwiaW5wdXRcIiBjbGFzcz1cImZvcm0tY2hlY2staW5wdXRcIiB0eXBlPVwiY2hlY2tib3hcIiA8JSBpZiAodGhpcy5kYXRhLmNoZWNrZWQpIHsgJT5jaGVja2VkPCUgfSAlPiA8JSBpZiAodGhpcy5hcmdzLmRpc2FibGVkKSB7ICU+ZGlzYWJsZWQ8JSB9ICU+PlxuICAgICAgICA8JSBpZiAodGhpcy5hcmdzLmxhYmVsKSB7ICU+XG4gICAgICAgICAgICA8bGFiZWwgJGlkPVwibGFiZWxcIiBjbGFzcz1cImZvcm0tY2hlY2stbGFiZWxcIj5cbiAgICAgICAgICAgICAgICA8JT0gdGhpcy5hcmdzLmxhYmVsICU+XG4gICAgICAgICAgICA8L2xhYmVsPlxuICAgICAgICA8JSB9ICU+XG4gICAgPC9kaXY+XG48L0RlZmluZTpDaGVja2JveF9JbnB1dD5cbiIsIjwhLS1cbld5c2l3eWdfSW5wdXRcblxuV1lTSVdZRyBlZGl0b3Igd2lkZ2V0IGZvciBmb3JtcyB1c2luZyBRdWlsbC5cblxuJHBsYWNlaG9sZGVyIC0gUGxhY2Vob2xkZXIgdGV4dFxuJHNlZWRlciAtIFNlZWRlciBmdW5jdGlvbiBuYW1lIGZvciB0ZXN0IGRhdGFcblxuV2lkZ2V0IGludGVyZmFjZTpcbi0gdmFsKCkgLSBHZXQvc2V0IEhUTUwgY29udGVudFxuLSBzZWVkKCkgLSBGaWxscyB3aXRoIHJhbmRvbSBjb250ZW50XG4tLT5cbjxEZWZpbmU6V3lzaXd5Z19JbnB1dCBjbGFzcz1cIldpZGdldFwiPlxuICAgIDxkaXYgJGlkPVwiZWRpdG9yXCIgc3R5bGU9XCJtaW4taGVpZ2h0OiAyMDBweDsgYmFja2dyb3VuZDogd2hpdGU7XCI+PC9kaXY+XG4gICAgPGlucHV0IHR5cGU9XCJoaWRkZW5cIiAkaWQ9XCJoaWRkZW5faW5wdXRcIiAvPlxuPC9EZWZpbmU6V3lzaXd5Z19JbnB1dD5cbiIsIjwhLS1cbkNvdW50cnlfU2VsZWN0X0lucHV0XG5cblNwZWNpYWxpemVkIHNlbGVjdCBmb3IgY291bnRyeSBkcm9wZG93bnMgd2l0aCBkZWZhdWx0IGNvdW50cnkgc3VwcG9ydC5cbkV4dGVuZHMgQWpheF9TZWxlY3RfSW5wdXQgd2l0aCBjb3VudHJ5LXNwZWNpZmljIGJlaGF2aW9yLlxuXG4kZGF0YSAtIEFqYXggZW5kcG9pbnQgZm9yIGNvdW50cnkgZGF0YSAob3B0aW9uYWwsIGRlZmF1bHRzIHRvIFJzeF9SZWZlcmVuY2VfRGF0YV9Db250cm9sbGVyLmNvdW50cmllcygpKVxuJHBsYWNlaG9sZGVyIC0gUGxhY2Vob2xkZXIgdGV4dCAoZGVmYXVsdDogXCJTZWxlY3QgQ291bnRyeS4uLlwiKVxuJGRlZmF1bHRfY291bnRyeSAtIERlZmF1bHQgY291bnRyeSBjb2RlIChlLmcuIFwiVVNcIikgdG8gcHJlLXNlbGVjdCBhbmQgbW92ZSB0byB0b3BcbiRkaXNhYmxlZCAtIEJvb2xlYW4gdG8gZGlzYWJsZSB0aGUgc2VsZWN0XG5cbkZlYXR1cmVzOlxuLSBMb2FkcyBjb3VudHJ5IGxpc3QgdmlhIEFqYXggYXV0b21hdGljYWxseVxuLSBQcmUtc2VsZWN0cyBkZWZhdWx0IGNvdW50cnkgaWYgbm8gdmFsdWUgc2V0XG4tIE1vdmVzIGRlZmF1bHQgY291bnRyeSB0byB0b3Agb2YgbGlzdFxuLSBJbmhlcml0cyBhbGwgQWpheF9TZWxlY3RfSW5wdXQgYmVoYXZpb3IgKFRvbSBTZWxlY3QsIHNlYXJjaCwgbG9hZGluZyBzdGF0ZXMsIGV0Yy4pXG4tLT5cbjxEZWZpbmU6Q291bnRyeV9TZWxlY3RfSW5wdXQgZXh0ZW5kcz1cIkFqYXhfU2VsZWN0X0lucHV0XCIgY2xhc3M9XCJXaWRnZXRcIj5cbiAgICA8c2VsZWN0ICRpZD1cImlucHV0XCIgPCUgaWYgKHRoaXMuYXJncy5kaXNhYmxlZCkgeyAlPmRpc2FibGVkPCUgfSAlPj5cbiAgICAgICAgPCUgaWYgKCF0aGlzLmRhdGEuc2VsZWN0X3ZhbHVlcyB8fCB0aGlzLmRhdGEuc2VsZWN0X3ZhbHVlcy5sZW5ndGggPT09IDApIHsgJT5cbiAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCJcIj48JT0gdGhpcy5hcmdzLnBsYWNlaG9sZGVyIHx8ICdQbGVhc2Ugd2FpdC4uLicgJT48L29wdGlvbj5cbiAgICAgICAgPCUgfSBlbHNlIHsgJT5cbiAgICAgICAgICAgIDwlIGlmICh0aGlzLmFyZ3MucGxhY2Vob2xkZXIpIHsgJT5cbiAgICAgICAgICAgICAgICA8b3B0aW9uIHZhbHVlPVwiXCI+PCU9IHRoaXMuYXJncy5wbGFjZWhvbGRlciAlPjwvb3B0aW9uPlxuICAgICAgICAgICAgPCUgfSAlPlxuICAgICAgICAgICAgPCUgZm9yIChsZXQgb3B0IG9mIHRoaXMuZGF0YS5zZWxlY3RfdmFsdWVzKSB7ICU+XG4gICAgICAgICAgICAgICAgPCUgaWYgKHR5cGVvZiBvcHQgPT09ICdvYmplY3QnKSB7ICU+XG4gICAgICAgICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCI8JT0gb3B0LnZhbHVlICU+XCIgPCUgaWYgKHRoaXMuZGF0YS52YWx1ZSA9PSBvcHQudmFsdWUpIHsgJT5zZWxlY3RlZDwlIH0gJT4+PCU9IG9wdC5sYWJlbCAlPjwvb3B0aW9uPlxuICAgICAgICAgICAgICAgIDwlIH0gZWxzZSB7ICU+XG4gICAgICAgICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCI8JT0gb3B0ICU+XCIgPCUgaWYgKHRoaXMuZGF0YS52YWx1ZSA9PSBvcHQpIHsgJT5zZWxlY3RlZDwlIH0gJT4+PCU9IG9wdCAlPjwvb3B0aW9uPlxuICAgICAgICAgICAgICAgIDwlIH0gJT5cbiAgICAgICAgICAgIDwlIH0gJT5cbiAgICAgICAgPCUgfSAlPlxuICAgIDwvc2VsZWN0PlxuPC9EZWZpbmU6Q291bnRyeV9TZWxlY3RfSW5wdXQ+XG4iLCI8IS0tXG5TdGF0ZV9TZWxlY3RfSW5wdXRcblxuU3BlY2lhbGl6ZWQgc2VsZWN0IGZvciBzdGF0ZS9wcm92aW5jZS9yZWdpb24gZHJvcGRvd25zIHdpdGggY291bnRyeS1zcGVjaWZpYyBsaXN0cy5cbkV4dGVuZHMgQWpheF9TZWxlY3RfSW5wdXQgd2l0aCBzdGF0ZS1zcGVjaWZpYyBiZWhhdmlvci5cblxuJGRhdGEgLSBBamF4IGVuZHBvaW50IGZvciBzdGF0ZSBkYXRhIChvcHRpb25hbCwgZGVmYXVsdHMgdG8gUnN4X1JlZmVyZW5jZV9EYXRhX0NvbnRyb2xsZXIuc3RhdGVzKCkpXG4kcGxhY2Vob2xkZXIgLSBQbGFjZWhvbGRlciB0ZXh0IChkZWZhdWx0OiBcIlNlbGVjdCBTdGF0ZS4uLlwiKVxuJGNvdW50cnlfY29kZSAtIEluaXRpYWwgY291bnRyeSBjb2RlIChlLmcuIFwiVVNcIikgdG8gbG9hZCBzdGF0ZXMgZm9yXG4kZGlzYWJsZWQgLSBCb29sZWFuIHRvIGRpc2FibGUgdGhlIHNlbGVjdFxuXG5GZWF0dXJlczpcbi0gTG9hZHMgc3RhdGUgbGlzdCB2aWEgQWpheCBiYXNlZCBvbiBjb3VudHJ5IGNvZGVcbi0gc2V0X2NvdW50cnlfY29kZShjb2RlKSBtZXRob2QgdG8gY2hhbmdlIGNvdW50cnkgYW5kIHJlbG9hZCBzdGF0ZXNcbi0gUmVtYWlucyBkaXNhYmxlZCB1bnRpbCBjb3VudHJ5IGNvZGUgaXMgc2V0XG4tIFJldGFpbnMgdmFsdWUgc2V0IHZpYSB2YWwoKSB1bnRpbCBzdGF0ZXMgbG9hZFxuLSBJbmhlcml0cyBhbGwgQWpheF9TZWxlY3RfSW5wdXQgYmVoYXZpb3IgKFRvbSBTZWxlY3QsIHNlYXJjaCwgbG9hZGluZyBzdGF0ZXMsIGV0Yy4pXG4tLT5cbjxEZWZpbmU6U3RhdGVfU2VsZWN0X0lucHV0IGV4dGVuZHM9XCJBamF4X1NlbGVjdF9JbnB1dFwiIGNsYXNzPVwiV2lkZ2V0XCI+XG4gICAgPHNlbGVjdCAkaWQ9XCJpbnB1dFwiIDwlIGlmICh0aGlzLmFyZ3MuZGlzYWJsZWQgfHwgIXRoaXMuZGF0YS5jb3VudHJ5X2NvZGUpIHsgJT5kaXNhYmxlZDwlIH0gJT4+XG4gICAgICAgIDwlIGlmICghdGhpcy5kYXRhLnNlbGVjdF92YWx1ZXMgfHwgdGhpcy5kYXRhLnNlbGVjdF92YWx1ZXMubGVuZ3RoID09PSAwKSB7ICU+XG4gICAgICAgICAgICA8b3B0aW9uIHZhbHVlPVwiXCI+PCU9IHRoaXMuYXJncy5wbGFjZWhvbGRlciB8fCAnU2VsZWN0IFN0YXRlLi4uJyAlPjwvb3B0aW9uPlxuICAgICAgICA8JSB9IGVsc2UgeyAlPlxuICAgICAgICAgICAgPCUgaWYgKHRoaXMuYXJncy5wbGFjZWhvbGRlcikgeyAlPlxuICAgICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCJcIj48JT0gdGhpcy5hcmdzLnBsYWNlaG9sZGVyICU+PC9vcHRpb24+XG4gICAgICAgICAgICA8JSB9ICU+XG4gICAgICAgICAgICA8JSBmb3IgKGxldCBvcHQgb2YgdGhpcy5kYXRhLnNlbGVjdF92YWx1ZXMpIHsgJT5cbiAgICAgICAgICAgICAgICA8JSBpZiAodHlwZW9mIG9wdCA9PT0gJ29iamVjdCcpIHsgJT5cbiAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT1cIjwlPSBvcHQudmFsdWUgJT5cIiA8JSBpZiAodGhpcy5kYXRhLnZhbHVlID09IG9wdC52YWx1ZSkgeyAlPnNlbGVjdGVkPCUgfSAlPj48JT0gb3B0LmxhYmVsICU+PC9vcHRpb24+XG4gICAgICAgICAgICAgICAgPCUgfSBlbHNlIHsgJT5cbiAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT1cIjwlPSBvcHQgJT5cIiA8JSBpZiAodGhpcy5kYXRhLnZhbHVlID09IG9wdCkgeyAlPnNlbGVjdGVkPCUgfSAlPj48JT0gb3B0ICU+PC9vcHRpb24+XG4gICAgICAgICAgICAgICAgPCUgfSAlPlxuICAgICAgICAgICAgPCUgfSAlPlxuICAgICAgICA8JSB9ICU+XG4gICAgPC9zZWxlY3Q+XG48L0RlZmluZTpTdGF0ZV9TZWxlY3RfSW5wdXQ+XG4iLCI8IS0tXG5Qcm9maWxlX1Bob3RvX0lucHV0XG5cblByb2ZpbGUgcGhvdG8gdXBsb2FkIHdpZGdldCB0aGF0IGRpc3BsYXlzIGEgdGh1bWJuYWlsIGFuZCBwcm92aWRlcyB1cGxvYWQgZnVuY3Rpb25hbGl0eS5cblxuJHdpZHRoIC0gVGh1bWJuYWlsIHdpZHRoIGluIHBpeGVscyAoZGVmYXVsdDogOTYpXG4kaGVpZ2h0IC0gVGh1bWJuYWlsIGhlaWdodCBpbiBwaXhlbHMgKGRlZmF1bHQ6IDk2KVxuJGFjY2VwdCAtIEZpbGUgdHlwZXMgdG8gYWNjZXB0IChkZWZhdWx0OiBpbWFnZS9qcGVnLGltYWdlL3BuZyxpbWFnZS9naWYpXG4kbWF4X3NpemUgLSBNYXhpbXVtIGZpbGUgc2l6ZSBpbiBNQiAoZGVmYXVsdDogMilcbiRwbGFjZWhvbGRlciAtIFBsYWNlaG9sZGVyIGltYWdlIFVSTCB3aGVuIG5vIHBob3RvIGlzIHNldFxuJHNob3dfcmVtb3ZlIC0gU2hvdyByZW1vdmUgYnV0dG9uIChkZWZhdWx0OiBmYWxzZSlcblxuVGhlIHdpZGdldCB2YWx1ZSAodmlhIHZhbCgpIGdldHRlci9zZXR0ZXIpIGlzIHRoZSBhdHRhY2htZW50IGtleS5cblxuVXNhZ2U6XG48Rm9ybV9GaWVsZCAkbmFtZT1cInByb2ZpbGVfcGhvdG9cIiAkbGFiZWw9XCJQcm9maWxlIFBob3RvXCI+XG4gICAgPFByb2ZpbGVfUGhvdG9fSW5wdXQgLz5cbjwvRm9ybV9GaWVsZD5cblxuPFByb2ZpbGVfUGhvdG9fSW5wdXQgJHdpZHRoPTEyOCAkaGVpZ2h0PTEyOCAkc2hvd19yZW1vdmU9dHJ1ZSAvPlxuLS0+XG48RGVmaW5lOlByb2ZpbGVfUGhvdG9fSW5wdXQgY2xhc3M9XCJXaWRnZXRcIj5cblxuICAgIDxkaXYgY2xhc3M9XCJkLWZsZXggYWxpZ24taXRlbXMtY2VudGVyXCI+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJwb3NpdGlvbi1yZWxhdGl2ZVwiPlxuICAgICAgICAgICAgPCUgaWYgKHRoaXMuZGF0YS50aHVtYm5haWxfdXJsKSB7ICU+XG4gICAgICAgICAgICAgICAgPGltZyAkaWQ9XCJwaG90b1wiXG4gICAgICAgICAgICAgICAgICAgIHNyYz1cIjwlPSB0aGlzLmRhdGEudGh1bWJuYWlsX3VybCAlPlwiXG4gICAgICAgICAgICAgICAgICAgIGNsYXNzPVwicm91bmRlZC1jaXJjbGUgbWUtM1wiXG4gICAgICAgICAgICAgICAgICAgIGFsdD1cIlByb2ZpbGUgUGhvdG9cIlxuICAgICAgICAgICAgICAgICAgICB3aWR0aD1cIjwlPSB0aGlzLmFyZ3Mud2lkdGggfHwgOTYgJT5cIlxuICAgICAgICAgICAgICAgICAgICBoZWlnaHQ9XCI8JT0gdGhpcy5hcmdzLmhlaWdodCB8fCA5NiAlPlwiXG4gICAgICAgICAgICAgICAgc3R5bGU9XCJvcGFjaXR5OiAxO1wiPlxuICAgICAgICAgICAgPCUgfSBlbHNlIHsgJT5cbiAgICAgICAgICAgICAgICA8ZGl2ICRpZD1cInBob3RvXCIgY2xhc3M9XCJ1c2VyLXByb2ZpbGUtaWNvbiBtZS0zXCIgc3R5bGU9XCJ3aWR0aDogPCU9IHRoaXMuYXJncy53aWR0aCB8fCA5NiAlPnB4OyBoZWlnaHQ6IDwlPSB0aGlzLmFyZ3MuaGVpZ2h0IHx8IDk2ICU+cHg7IGRpc3BsYXk6IGZsZXg7IGFsaWduLWl0ZW1zOiBjZW50ZXI7IGp1c3RpZnktY29udGVudDogY2VudGVyO1wiPlxuICAgICAgICAgICAgICAgICAgICA8aSBjbGFzcz1cImJpIGJpLXBlcnNvbi1jaXJjbGVcIiBzdHlsZT1cImZvbnQtc2l6ZTogPCU9IE1hdGgucm91bmQoKHRoaXMuYXJncy53aWR0aCB8fCA5NikgKiAwLjc1KSAlPnB4O1wiPjwvaT5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwlIH0gJT5cbiAgICAgICAgICAgIDxkaXYgJGlkPVwic3Bpbm5lclwiIGNsYXNzPVwicG9zaXRpb24tYWJzb2x1dGUgdG9wLTUwIHN0YXJ0LTUwIHRyYW5zbGF0ZS1taWRkbGUgZC1ub25lXCI+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNwaW5uZXItYm9yZGVyIHRleHQtcHJpbWFyeVwiIHJvbGU9XCJzdGF0dXNcIj5cbiAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJ2aXN1YWxseS1oaWRkZW5cIj5VcGxvYWRpbmcuLi48L3NwYW4+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIDxkaXY+XG4gICAgICAgICAgICA8aW5wdXQgdHlwZT1cImZpbGVcIiAkaWQ9XCJmaWxlX2lucHV0XCIgY2xhc3M9XCJkLW5vbmVcIiBhY2NlcHQ9XCI8JT0gdGhpcy5hcmdzLmFjY2VwdCB8fCAnaW1hZ2UvanBlZyxpbWFnZS9wbmcsaW1hZ2UvZ2lmJyAlPlwiPlxuICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgJGlkPVwidXBsb2FkX2J0blwiIGNsYXNzPVwiYnRuIGJ0bi1zbSBidG4tcHJpbWFyeSBtZS0yXCI+VXBsb2FkIE5ldyBQaG90bzwvYnV0dG9uPlxuICAgICAgICAgICAgPCUgaWYgKHRoaXMuYXJncy5zaG93X3JlbW92ZSAmJiB0aGlzLmRhdGEuYXR0YWNobWVudF9rZXkpIHsgJT5cbiAgICAgICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiAkaWQ9XCJyZW1vdmVfYnRuXCIgY2xhc3M9XCJidG4gYnRuLXNtIGJ0bi1kYW5nZXJcIj5SZW1vdmU8L2J1dHRvbj5cbiAgICAgICAgICAgIDwlIH0gJT5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmb3JtLXRleHQgbXQtMlwiPkpQRywgUE5HIG9yIEdJRi4gTWF4IHNpemUgPCU9IHRoaXMuYXJncy5tYXhfc2l6ZSB8fCAyICU+TUIuPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuXG48L0RlZmluZTpQcm9maWxlX1Bob3RvX0lucHV0PiIsIjwhLS1cblJzeF9UYWJzXG5cbkZvcm0tYXdhcmUgdGFiIGNvbnRhaW5lciB0aGF0IG1hbmFnZXMgdGFiIG5hdmlnYXRpb24gYW5kIGVycm9yIHN0YXRlcy5cblxuRmVhdHVyZXM6XG4tIEF1dG9tYXRpY2FsbHkgZGV0ZWN0cyBlcnJvcnMgaW4gY2hpbGQgUnN4X1RhYiBjb21wb25lbnRzXG4tIFN3aXRjaGVzIHRvIGZpcnN0IHRhYiB3aXRoIGVycm9ycyBvbiB2YWxpZGF0aW9uIGZhaWx1cmVcbi0gU2hvd3MgZXJyb3IgYmFkZ2VzIG9uIHRhYiBsYWJlbHNcbi0gUGVyc2lzdHMgYWN0aXZlIHRhYiB0byBVUkwgaGFzaFxuXG5Vc2FnZTpcbjxSc3hfVGFicz5cbiAgICA8UnN4X1RhYiAkaWQ9XCJiYXNpYy1pbmZvXCIgJGxhYmVsPVwiQmFzaWMgSW5mb3JtYXRpb25cIiAkaWNvbj1cImJpLWJ1aWxkaW5nXCI+XG4gICAgICAgIDxGb3JtX0ZpZWxkICRuYW1lPVwibmFtZVwiPi4uLjwvRm9ybV9GaWVsZD5cbiAgICA8L1JzeF9UYWI+XG4gICAgPFJzeF9UYWIgJGlkPVwiYWRkcmVzc1wiICRsYWJlbD1cIkFkZHJlc3NcIiAkaWNvbj1cImJpLWdlby1hbHRcIj5cbiAgICAgICAgPEZvcm1fRmllbGQgJG5hbWU9XCJzdHJlZXRcIj4uLi48L0Zvcm1fRmllbGQ+XG4gICAgPC9Sc3hfVGFiPlxuPC9Sc3hfVGFicz5cbi0tPlxuPERlZmluZTpSc3hfVGFicz5cbiAgICA8IS0tIFRhYiBOYXZpZ2F0aW9uIC0tPlxuICAgIDx1bCBjbGFzcz1cIm5hdiBuYXYtdGFic1wiIHJvbGU9XCJ0YWJsaXN0XCIgJGlkPVwibmF2XCI+XG4gICAgICAgIDwhLS0gVGFiIGhlYWRlcnMgd2lsbCBiZSByZW5kZXJlZCBieSBSc3hfVGFiIGNvbXBvbmVudHMgLS0+XG4gICAgPC91bD5cblxuICAgIDwhLS0gVGFiIENvbnRlbnQgQ29udGFpbmVyIC0tPlxuICAgIDxkaXYgY2xhc3M9XCJ0YWItY29udGVudCBtdC00XCIgJGlkPVwiY29udGVudFwiPlxuICAgICAgICA8JT0gY29udGVudCgpICU+XG4gICAgPC9kaXY+XG48L0RlZmluZTpSc3hfVGFicz5cbiIsIjwhLS1cblJzeF9UYWJcblxuSW5kaXZpZHVhbCB0YWIgY29tcG9uZW50IHRoYXQgaW50ZWdyYXRlcyB3aXRoIFJzeF9UYWJzIGZvciBmb3JtLWF3YXJlIGVycm9yIGhhbmRsaW5nLlxuXG4kaWQgLSBUYWIgaWRlbnRpZmllciAodXNlZCBmb3IgVVJMIGhhc2ggYW5kIHRhcmdldGluZylcbiRsYWJlbCAtIFRhYiBsYWJlbCB0ZXh0XG4kaWNvbiAtIE9wdGlvbmFsIEJvb3RzdHJhcCBpY29uIGNsYXNzIChlLmcuLCBcImJpLWJ1aWxkaW5nXCIpXG5cbkZlYXR1cmVzOlxuLSBBdXRvbWF0aWNhbGx5IHJlZ2lzdGVycyB3aXRoIHBhcmVudCBSc3hfVGFicyBjb21wb25lbnRcbi0gQ291bnRzIHZhbGlkYXRpb24gZXJyb3JzIGluIGNoaWxkIEZvcm1fRmllbGQgY29tcG9uZW50c1xuLSBSZW5kZXJzIGFzIEJvb3RzdHJhcCB0YWIgcGFuZVxuLSBXb3JrcyBpbmRlcGVuZGVudGx5IG9yIHdpdGhpbiBSc3hfVGFicyBjb250YWluZXJcblxuVXNhZ2U6XG48UnN4X1RhYnM+XG4gICAgPFJzeF9UYWIgJGlkPVwiYmFzaWMtaW5mb1wiICRsYWJlbD1cIkJhc2ljIEluZm9ybWF0aW9uXCIgJGljb249XCJiaS1idWlsZGluZ1wiPlxuICAgICAgICA8Rm9ybV9GaWVsZCAkbmFtZT1cIm5hbWVcIj4uLi48L0Zvcm1fRmllbGQ+XG4gICAgPC9Sc3hfVGFiPlxuICAgIDxSc3hfVGFiICRpZD1cImFkZHJlc3NcIiAkbGFiZWw9XCJBZGRyZXNzXCIgJGljb249XCJiaS1nZW8tYWx0XCI+XG4gICAgICAgIDxGb3JtX0ZpZWxkICRuYW1lPVwic3RyZWV0XCI+Li4uPC9Gb3JtX0ZpZWxkPlxuICAgIDwvUnN4X1RhYj5cbjwvUnN4X1RhYnM+XG4tLT5cbjxEZWZpbmU6UnN4X1RhYiBjbGFzcz1cInRhYi1wYW5lIGZhZGVcIiByb2xlPVwidGFicGFuZWxcIj5cbiAgICA8JT0gY29udGVudCgpICU+XG48L0RlZmluZTpSc3hfVGFiPlxuIiwiPCEtLVxuUnN4X0Zvcm1cblxuTWFpbiBmb3JtIGNvbnRhaW5lciB0aGF0IG1hbmFnZXMgd2lkZ2V0IGRpc2NvdmVyeSwgdmFsdWUgY29sbGVjdGlvbiwgYW5kIHN1Ym1pc3Npb24uXG5cbiRkYXRhIC0gT2JqZWN0IHdpdGggaW5pdGlhbCBmb3JtIHZhbHVlcyAoZm9yIGVkaXQgbW9kZSlcbiRhY3Rpb24gLSBBamF4IFVSTCBvciBjb250cm9sbGVyIG1ldGhvZCByZWZlcmVuY2UgKGUuZy4sIEZyb250ZW5kX0NsaWVudHNfQ29udHJvbGxlci5zYXZlKVxuXG5Vc2FnZTpcbjxSc3hfRm9ybSAkZGF0YT0kY2xpZW50ICRhY3Rpb249RnJvbnRlbmRfQ2xpZW50c19Db250cm9sbGVyLnNhdmU+XG4gICAgPEZvcm1fRmllbGQgJG5hbWU9XCJuYW1lXCIgJGxhYmVsPVwiQ29tcGFueSBOYW1lXCI+XG4gICAgICAgIDxUZXh0X0lucHV0IC8+XG4gICAgPC9Gb3JtX0ZpZWxkPlxuPC9Sc3hfRm9ybT5cbi0tPlxuPERlZmluZTpSc3hfRm9ybSB0YWc9XCJmb3JtXCI+XG5cbiAgICA8ZGl2ICRpZD1cImxvYWRlclwiIGNsYXNzPVwidGV4dC1jZW50ZXIgcHktNVwiPlxuICAgICAgICA8ZGl2IGNsYXNzPVwic3Bpbm5lci1ib3JkZXIgdGV4dC1wcmltYXJ5IG1iLTNcIiByb2xlPVwic3RhdHVzXCI+XG4gICAgICAgICAgICA8c3BhbiBjbGFzcz1cInZpc3VhbGx5LWhpZGRlblwiPkxvYWRpbmcuLi48L3NwYW4+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICA8cCBjbGFzcz1cInRleHQtbXV0ZWRcIj5Mb2FkaW5nIGZvcm0uLi48L3A+XG4gICAgPC9kaXY+XG5cbiAgICA8ZGl2ICRpZD1cImZvcm1fY29udGVudFwiIHN0eWxlPVwiZGlzcGxheTogbm9uZTtcIj5cbiAgICAgICAgPCUgaWYgKHdpbmRvdy5yc3hhcHAuZGVidWcpIHsgJT5cbiAgICAgICAgICAgIDwlLS0gPGRpdiBjbGFzcz1cIm1iLTNcIj5cbiAgICAgICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJidG4gYnRuLXNtIGJ0bi1zZWNvbmRhcnlcIlxuICAgICAgICAgICAgICAgICAgICAgICAgJGlkPVwic2VlZF9idG5cIj5cbiAgICAgICAgICAgICAgICAgICAgPGkgY2xhc3M9XCJiaSBiaS1zaHVmZmxlXCI+PC9pPiBGaWxsIFRlc3QgRGF0YVxuICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgPC9kaXY+IC0tJT5cbiAgICAgICAgPCUgfSAlPlxuXG4gICAgICAgIDxkaXYgJGlkPVwiZXJyb3JcIj48L2Rpdj5cblxuICAgICAgICA8JT0gY29udGVudCgpICU+XG4gICAgPC9kaXY+XG5cbjwvRGVmaW5lOlJzeF9Gb3JtPiIsIjwhLS1cbkZvcm1fRmllbGRfQWJzdHJhY3RcblxuQWJzdHJhY3QgYmFzZSBjb21wb25lbnQgZm9yIGZvcm0gZmllbGQgd3JhcHBlcnMuIFByb3ZpZGVzIGNvcmUgZnVuY3Rpb25hbGl0eSB3aXRob3V0IHZpc3VhbCBmb3JtYXR0aW5nLlxuRXh0ZW5kIHRoaXMgdG8gY3JlYXRlIGN1c3RvbSBmb3JtIGZpZWxkIHdyYXBwZXJzIHdpdGggZGlmZmVyZW50IHZpc3VhbCBzdHlsZXMuXG5cbiRuYW1lIC0gRmllbGQgbmFtZSAocmVxdWlyZWQpIC0gdXNlZCBmb3IgZm9ybSBzZXJpYWxpemF0aW9uIGFuZCBlcnJvciBkaXNwbGF5XG4kbGFiZWwgLSBMYWJlbCB0ZXh0IChvcHRpb25hbCkgLSBhdmFpbGFibGUgZm9yIGNoaWxkIGNsYXNzZXMgdG8gZGlzcGxheVxuJHJlcXVpcmVkIC0gQm9vbGVhbiAob3B0aW9uYWwpIC0gYXZhaWxhYmxlIGZvciBjaGlsZCBjbGFzc2VzIHRvIGluZGljYXRlIHJlcXVpcmVkIGZpZWxkc1xuJGhlbHAgLSBIZWxwIHRleHQgKG9wdGlvbmFsKSAtIGF2YWlsYWJsZSBmb3IgY2hpbGQgY2xhc3NlcyB0byBkaXNwbGF5XG5cbkNoaWxkIGNvbnRlbnQgaXMgdGhlIGZvcm0gd2lkZ2V0IChUZXh0X0lucHV0LCBTZWxlY3RfSW5wdXQsIGV0Yy4pXG5cbk5vdGU6IFRoaXMgaXMgYW4gYWJzdHJhY3QgY29tcG9uZW50LiBVc2UgRm9ybV9GaWVsZCBmb3Igc3RhbmRhcmQgZm9ybWF0dGVkIGZpZWxkcyxcbm9yIGV4dGVuZCB0aGlzIHRvIGNyZWF0ZSBjdXN0b20gZmllbGQgd3JhcHBlcnMuXG4tLT5cbjxEZWZpbmU6Rm9ybV9GaWVsZF9BYnN0cmFjdD5cbiAgICA8JT0gY29udGVudCgpICU+XG48L0RlZmluZTpGb3JtX0ZpZWxkX0Fic3RyYWN0PiIsIjwhLS1cbkZvcm1fRmllbGRcblxuV3JhcHBlciBjb21wb25lbnQgdGhhdCBwcm92aWRlcyBjb25zaXN0ZW50IGxhYmVsLCBoZWxwIHRleHQsIGFuZCBlcnJvciBkaXNwbGF5IGZvciBmb3JtIHdpZGdldHMuXG5cbiRuYW1lIC0gRmllbGQgbmFtZSAocmVxdWlyZWQpIC0gdXNlZCBmb3IgZm9ybSBzZXJpYWxpemF0aW9uIGFuZCBlcnJvciBkaXNwbGF5XG4kbGFiZWwgLSBMYWJlbCB0ZXh0IHRvIGRpc3BsYXkgYWJvdmUgdGhlIGZpZWxkXG4kcmVxdWlyZWQgLSBCb29sZWFuIC0gaWYgdHJ1ZSwgc2hvd3MgcmVkIGFzdGVyaXNrIG5leHQgdG8gbGFiZWxcbiRoZWxwIC0gSGVscCB0ZXh0IHRvIGRpc3BsYXkgYmVsb3cgdGhlIGZpZWxkXG5cblVzYWdlOlxuPEZvcm1fRmllbGQgJG5hbWU9XCJlbWFpbFwiICRsYWJlbD1cIkVtYWlsIEFkZHJlc3NcIiAkcmVxdWlyZWQ9dHJ1ZSAkaGVscD1cIldlJ2xsIG5ldmVyIHNoYXJlIHlvdXIgZW1haWxcIj5cbiAgICA8VGV4dF9JbnB1dCAkcGxhY2Vob2xkZXI9XCJ1c2VyQGV4YW1wbGUuY29tXCIgLz5cbjwvRm9ybV9GaWVsZD5cbi0tPlxuPERlZmluZTpGb3JtX0ZpZWxkIGV4dGVuZHM9XCJGb3JtX0ZpZWxkX0Fic3RyYWN0XCIgdGFnPVwiZGl2XCIgY2xhc3M9XCJmb3JtLWdyb3VwIG1iLTNcIj5cblxuICAgIDwlIGlmICh0aGlzLmFyZ3MubGFiZWwpIHsgJT5cbiAgICAgICAgPGxhYmVsIGNsYXNzPVwiZm9ybS1sYWJlbFwiICRpZD1cImZvcm1fbGFiZWxcIj5cbiAgICAgICAgICAgIDwlIT0gdGhpcy5hcmdzLmxhYmVsICU+XG4gICAgICAgICAgICA8JSBpZiAodGhpcy5hcmdzLnJlcXVpcmVkKSB7ICU+XG4gICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJ0ZXh0LWRhbmdlclwiPio8L3NwYW4+XG4gICAgICAgICAgICA8JSB9ICU+XG4gICAgICAgIDwvbGFiZWw+XG4gICAgPCUgfSAlPlxuXG4gICAgPGRpdiBjbGFzcz1cIjwlPSB0aGlzLmhhc19lcnJvcigpID8gJ2lzLWludmFsaWQnIDogJycgJT5cIj5cbiAgICAgICAgPCU9IGNvbnRlbnQoKSAlPlxuICAgIDwvZGl2PlxuXG4gICAgPCUgaWYgKHRoaXMuaGFzX2Vycm9yKCkpIHsgJT5cbiAgICAgICAgPGRpdiBjbGFzcz1cImludmFsaWQtZmVlZGJhY2sgZC1ibG9ja1wiPlxuICAgICAgICAgICAgPCU9IHRoaXMuZ2V0X2Vycm9yKCkgJT5cbiAgICAgICAgPC9kaXY+XG4gICAgPCUgfSAlPlxuXG4gICAgPCUgaWYgKHRoaXMuYXJncy5oZWxwKSB7ICU+XG4gICAgICAgIDxzbWFsbCBjbGFzcz1cImZvcm0tdGV4dCB0ZXh0LW11dGVkIGQtYmxvY2sgbXQtMVwiPlxuICAgICAgICAgICAgPCU9IHRoaXMuYXJncy5oZWxwICU+XG4gICAgICAgIDwvc21hbGw+XG4gICAgPCUgfSAlPlxuXG48L0RlZmluZTpGb3JtX0ZpZWxkPlxuIiwiPCEtLVxuRm9ybV9IaWRkZW5fRmllbGRcblxuSGlkZGVuIGlucHV0IGZpZWxkIGNvbXBvbmVudC4gVW5saWtlIG90aGVyIEZvcm1fRmllbGRfKiBjb21wb25lbnRzLCB0aGlzIGNvbXBvbmVudFxuSVMgYm90aCB0aGUgZmllbGQgd3JhcHBlciBBTkQgdGhlIGhpZGRlbiBpbnB1dCBpdHNlbGYuXG5cbiRuYW1lIC0gRmllbGQgbmFtZSAocmVxdWlyZWQpIC0gdXNlZCBmb3IgZm9ybSBzZXJpYWxpemF0aW9uXG5cblVzYWdlOlxuPEZvcm1fSGlkZGVuX0ZpZWxkICRuYW1lPVwiaWRcIiAvPlxuXG5SZXBsYWNlcyB0aGUgcGF0dGVybjpcbjxGb3JtX0ZpZWxkX0Fic3RyYWN0ICRuYW1lPVwiaWRcIj5cbiAgPEhpZGRlbl9JbnB1dCAvPlxuPC9Gb3JtX0ZpZWxkX0Fic3RyYWN0PlxuLS0+XG48RGVmaW5lOkZvcm1fSGlkZGVuX0ZpZWxkIGV4dGVuZHM9XCJGb3JtX0ZpZWxkX0Fic3RyYWN0XCIgdGFnPVwiaW5wdXRcIiB0eXBlPVwiaGlkZGVuXCIgY2xhc3M9XCJXaWRnZXRcIj5cbjwvRGVmaW5lOkZvcm1fSGlkZGVuX0ZpZWxkPlxuIiwiPCEtLVxuUGluX1ZlcmlmaWNhdGlvbl9Gb3JtXG5cbjYtZGlnaXQgUElOIGVudHJ5IGZvcm0gd2l0aCBhdXRvbWF0aWMgbmF2aWdhdGlvbiBiZXR3ZWVuIGJveGVzLlxuXG5GZWF0dXJlczpcbi0gQXV0by1hZHZhbmNlIHRvIG5leHQgYm94IHdoZW4gZGlnaXQgaXMgZW50ZXJlZFxuLSBCYWNrc3BhY2UgY2xlYXJzIGN1cnJlbnQgYm94IGFuZCBtb3ZlcyB0byBwcmV2aW91c1xuLSBQYXN0ZSBzdXBwb3J0OiBkaXN0cmlidXRlcyBkaWdpdHMgYWNyb3NzIGJveGVzXG4tIFZhbGlkYXRlcyBudW1lcmljIGlucHV0IG9ubHlcblxuVXNhZ2UgaW4gbW9kYWw6XG5jb25zdCByZXN1bHQgPSBhd2FpdCBNb2RhbC5mb3JtKHtcbiAgICB0aXRsZTogXCJFbnRlciBQSU5cIixcbiAgICBjb21wb25lbnQ6IFwiUGluX1ZlcmlmaWNhdGlvbl9Gb3JtXCIsXG4gICAgb25fc3VibWl0OiBhc3luYyAoZm9ybSkgPT4ge1xuICAgICAgICBjb25zdCBwaW4gPSBmb3JtLnZhbCgpO1xuICAgICAgICBpZiAocGluLmxlbmd0aCAhPT0gNikge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlOyAvLyBLZWVwIG1vZGFsIG9wZW5cbiAgICAgICAgfVxuICAgICAgICAvLyBWZXJpZnkgUElOLi4uXG4gICAgICAgIHJldHVybiB7IHN1Y2Nlc3M6IHRydWUsIHBpbjogcGluIH07XG4gICAgfVxufSk7XG4tLT5cbjxEZWZpbmU6UGluX1ZlcmlmaWNhdGlvbl9Gb3JtIGV4dGVuZHM9XCJSc3hfRm9ybVwiPlxuICAgIDxkaXYgY2xhc3M9XCJwaW4tdmVyaWZpY2F0aW9uLWZvcm1cIj5cbiAgICAgICAgPGRpdiBjbGFzcz1cInBpbi1pbnB1dHMgZC1mbGV4IGp1c3RpZnktY29udGVudC1jZW50ZXIgZ2FwLTIgbWItM1wiPlxuICAgICAgICAgICAgPGlucHV0ICRpZD1cImRpZ2l0XzBcIiB0eXBlPVwidGV4dFwiIGNsYXNzPVwiZm9ybS1jb250cm9sIHBpbi1pbnB1dCB0ZXh0LWNlbnRlclwiIG1heGxlbmd0aD1cIjFcIiBpbnB1dG1vZGU9XCJudW1lcmljXCIgcGF0dGVybj1cIlswLTldXCIgYXV0b2NvbXBsZXRlPVwib2ZmXCIgZGF0YS1pbmRleD1cIjBcIiAvPlxuICAgICAgICAgICAgPGlucHV0ICRpZD1cImRpZ2l0XzFcIiB0eXBlPVwidGV4dFwiIGNsYXNzPVwiZm9ybS1jb250cm9sIHBpbi1pbnB1dCB0ZXh0LWNlbnRlclwiIG1heGxlbmd0aD1cIjFcIiBpbnB1dG1vZGU9XCJudW1lcmljXCIgcGF0dGVybj1cIlswLTldXCIgYXV0b2NvbXBsZXRlPVwib2ZmXCIgZGF0YS1pbmRleD1cIjFcIiAvPlxuICAgICAgICAgICAgPGlucHV0ICRpZD1cImRpZ2l0XzJcIiB0eXBlPVwidGV4dFwiIGNsYXNzPVwiZm9ybS1jb250cm9sIHBpbi1pbnB1dCB0ZXh0LWNlbnRlclwiIG1heGxlbmd0aD1cIjFcIiBpbnB1dG1vZGU9XCJudW1lcmljXCIgcGF0dGVybj1cIlswLTldXCIgYXV0b2NvbXBsZXRlPVwib2ZmXCIgZGF0YS1pbmRleD1cIjJcIiAvPlxuICAgICAgICAgICAgPGlucHV0ICRpZD1cImRpZ2l0XzNcIiB0eXBlPVwidGV4dFwiIGNsYXNzPVwiZm9ybS1jb250cm9sIHBpbi1pbnB1dCB0ZXh0LWNlbnRlclwiIG1heGxlbmd0aD1cIjFcIiBpbnB1dG1vZGU9XCJudW1lcmljXCIgcGF0dGVybj1cIlswLTldXCIgYXV0b2NvbXBsZXRlPVwib2ZmXCIgZGF0YS1pbmRleD1cIjNcIiAvPlxuICAgICAgICAgICAgPGlucHV0ICRpZD1cImRpZ2l0XzRcIiB0eXBlPVwidGV4dFwiIGNsYXNzPVwiZm9ybS1jb250cm9sIHBpbi1pbnB1dCB0ZXh0LWNlbnRlclwiIG1heGxlbmd0aD1cIjFcIiBpbnB1dG1vZGU9XCJudW1lcmljXCIgcGF0dGVybj1cIlswLTldXCIgYXV0b2NvbXBsZXRlPVwib2ZmXCIgZGF0YS1pbmRleD1cIjRcIiAvPlxuICAgICAgICAgICAgPGlucHV0ICRpZD1cImRpZ2l0XzVcIiB0eXBlPVwidGV4dFwiIGNsYXNzPVwiZm9ybS1jb250cm9sIHBpbi1pbnB1dCB0ZXh0LWNlbnRlclwiIG1heGxlbmd0aD1cIjFcIiBpbnB1dG1vZGU9XCJudW1lcmljXCIgcGF0dGVybj1cIlswLTldXCIgYXV0b2NvbXBsZXRlPVwib2ZmXCIgZGF0YS1pbmRleD1cIjVcIiAvPlxuICAgICAgICA8L2Rpdj5cblxuICAgICAgICA8ZGl2ICRpZD1cImVycm9yX2NvbnRhaW5lclwiIGRhdGEtaWQ9XCJlcnJvcl9jb250YWluZXJcIiBjbGFzcz1cImFsZXJ0IGFsZXJ0LWRhbmdlclwiIHN0eWxlPVwiZGlzcGxheTogbm9uZTtcIj48L2Rpdj5cblxuICAgICAgICA8ZGl2IGNsYXNzPVwidGV4dC1jZW50ZXIgdGV4dC1tdXRlZCBzbWFsbFwiPlxuICAgICAgICAgICAgRW50ZXIgdGhlIDYtZGlnaXQgUElOIGNvZGVcbiAgICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG48L0RlZmluZTpQaW5fVmVyaWZpY2F0aW9uX0Zvcm0+XG4iLCI8JS0tIEV4dGVuZHMgRGF0YWdyaWRfQWJzdHJhY3QgLS0lPlxuXG48RGVmaW5lOkNsaWVudHNfRGF0YUdyaWRcbiAgICBleHRlbmRzPVwiRGF0YUdyaWRfQWJzdHJhY3RcIlxuICAgICRkYXRhX3NvdXJjZT1Gcm9udGVuZF9DbGllbnRzX0NvbnRyb2xsZXIuZGF0YWdyaWRfZmV0Y2hcbiAgICAkc29ydD1cImlkXCJcbiAgICAkb3JkZXI9XCJkZXNjXCJcbiAgICAkcGVyX3BhZ2U9MTVcbiAgICBjbGFzcz1cImNhcmQgRGF0YUdyaWRcIj5cblxuICAgIDwjREdfQ2FyZF9IZWFkZXI+XG4gICAgICAgIDxDYXJkX1RpdGxlPkNsaWVudCBMaXN0PC9DYXJkX1RpdGxlPlxuICAgICAgICA8Q2FyZF9IZWFkZXJfUmlnaHQ+XG4gICAgICAgICAgICA8U2VhcmNoX0lucHV0ICRpZD1cImZpbHRlcl9pbnB1dFwiIC8+XG4gICAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwiYnRuIGJ0bi1zZWNvbmRhcnkgYnRuLXNtXCI+RmlsdGVyPC9idXR0b24+XG4gICAgICAgIDwvQ2FyZF9IZWFkZXJfUmlnaHQ+XG4gICAgPC8jREdfQ2FyZF9IZWFkZXI+XG5cbiAgICA8I0RHX1RhYmxlX0hlYWRlcj5cbiAgICAgICAgPHRyPlxuICAgICAgICAgICAgPHRoIHN0eWxlPVwid2lkdGg6IDQwcHg7XCI+XG4gICAgICAgICAgICAgICAgPGlucHV0IGNsYXNzPVwiZm9ybS1jaGVjay1pbnB1dFwiIHR5cGU9XCJjaGVja2JveFwiICRpZD1cInNlbGVjdF9hbGxcIiAvPlxuICAgICAgICAgICAgPC90aD5cbiAgICAgICAgICAgIDx0aCAkc29ydGJ5PVwiaWRcIj5JRDwvdGg+XG4gICAgICAgICAgICA8dGggJHNvcnRieT1cIm5hbWVcIj5Db21wYW55IE5hbWU8L3RoPlxuICAgICAgICAgICAgPHRoICRzb3J0Ynk9XCJjaXR5XCI+TG9jYXRpb248L3RoPlxuICAgICAgICAgICAgPHRoPlBob25lPC90aD5cbiAgICAgICAgICAgIDx0aD5XZWJzaXRlPC90aD5cbiAgICAgICAgICAgIDx0aCAkc29ydGJ5PVwicHJpb3JpdHlcIj5Qcmlvcml0eTwvdGg+XG4gICAgICAgICAgICA8dGggJHNvcnRieT1cImNyZWF0ZWRfYXRcIj5DcmVhdGVkPC90aD5cbiAgICAgICAgICAgIDx0aCBzdHlsZT1cIndpZHRoOiAxMjBweDtcIj5BY3Rpb25zPC90aD5cbiAgICAgICAgPC90cj5cbiAgICA8LyNER19UYWJsZV9IZWFkZXI+XG5cbiAgICA8I3Jvdz5cbiAgICAgICAgPHRyICRocmVmPVJzeC5Sb3V0ZSgnRnJvbnRlbmRfQ2xpZW50c19Db250cm9sbGVyJywndmlldycscm93LmlkKT5cbiAgICAgICAgICAgIDx0ZD5cbiAgICAgICAgICAgICAgICA8aW5wdXQgY2xhc3M9XCJmb3JtLWNoZWNrLWlucHV0IHJvdy1jaGVja2JveFwiIHR5cGU9XCJjaGVja2JveFwiIHZhbHVlPVwiPCU9IHJvdy5pZCAlPlwiIC8+XG4gICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgPHRkPlxuICAgICAgICAgICAgICAgICNDTDwlPSBTdHJpbmcocm93LmlkKS5wYWRTdGFydCgzLCAnMCcpICU+XG4gICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgPHRkPlxuICAgICAgICAgICAgICAgIDwlPSByb3cubmFtZSAlPlxuICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgIDx0ZD5cbiAgICAgICAgICAgICAgICA8JSBpZiAocm93LmNpdHkgJiYgcm93LnN0YXRlKSB7ICU+XG4gICAgICAgICAgICAgICAgICAgIDwlPSByb3cuY2l0eSAlPiwgPCU9IHJvdy5zdGF0ZSAlPlxuICAgICAgICAgICAgICAgIDwlIH0gZWxzZSBpZiAocm93LmNpdHkpIHsgJT5cbiAgICAgICAgICAgICAgICAgICAgPCU9IHJvdy5jaXR5ICU+XG4gICAgICAgICAgICAgICAgPCUgfSBlbHNlIGlmIChyb3cuc3RhdGUpIHsgJT5cbiAgICAgICAgICAgICAgICAgICAgPCU9IHJvdy5zdGF0ZSAlPlxuICAgICAgICAgICAgICAgIDwlIH0gZWxzZSB7ICU+XG4gICAgICAgICAgICAgICAgICAgIC1cbiAgICAgICAgICAgICAgICA8JSB9ICU+XG4gICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgPHRkPjwlPSByb3cucGhvbmUgfHwgJy0nICU+PC90ZD5cbiAgICAgICAgICAgIDx0ZD5cbiAgICAgICAgICAgICAgICA8JSBpZiAocm93LndlYnNpdGUpIHsgJT5cbiAgICAgICAgICAgICAgICAgICAgPGEgaHJlZj1cIjwlPSByb3cud2Vic2l0ZSAlPlwiIHRhcmdldD1cIl9ibGFua1wiIGNsYXNzPVwidGV4dC1kZWNvcmF0aW9uLW5vbmVcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxpIGNsYXNzPVwiYmkgYmktbGluay00NWRlZ1wiPjwvaT5cbiAgICAgICAgICAgICAgICAgICAgPC9hPlxuICAgICAgICAgICAgICAgIDwlIH0gZWxzZSB7ICU+XG4gICAgICAgICAgICAgICAgICAgIC1cbiAgICAgICAgICAgICAgICA8JSB9ICU+XG4gICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgPHRkPlxuICAgICAgICAgICAgICAgIDwlIGlmIChyb3cucHJpb3JpdHkgPT09IDQpIHsgJT5cbiAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJiYWRnZSBiZy1kYW5nZXJcIj5VcmdlbnQ8L3NwYW4+XG4gICAgICAgICAgICAgICAgPCUgfSBlbHNlIGlmIChyb3cucHJpb3JpdHkgPT09IDMpIHsgJT5cbiAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJiYWRnZSBiZy13YXJuaW5nXCI+SGlnaDwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8JSB9IGVsc2UgaWYgKHJvdy5wcmlvcml0eSA9PT0gMikgeyAlPlxuICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImJhZGdlIGJnLXByaW1hcnlcIj5NZWRpdW08L3NwYW4+XG4gICAgICAgICAgICAgICAgPCUgfSBlbHNlIHsgJT5cbiAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJiYWRnZSBiZy1zZWNvbmRhcnlcIj5Mb3c8L3NwYW4+XG4gICAgICAgICAgICAgICAgPCUgfSAlPlxuICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgIDx0ZD48JT0gbmV3IERhdGUocm93LmNyZWF0ZWRfYXQpLnRvTG9jYWxlRGF0ZVN0cmluZygpICU+PC90ZD5cbiAgICAgICAgICAgIDx0ZD5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiYnRuLWdyb3VwIGJ0bi1ncm91cC1zbVwiPlxuICAgICAgICAgICAgICAgICAgICA8YSBjbGFzcz1cImJ0biBidG4tb3V0bGluZS1wcmltYXJ5XCIgaHJlZj1cIi9jbGllbnRzL3ZpZXcvPCU9IHJvdy5pZCAlPlwiIHRpdGxlPVwiVmlld1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGkgY2xhc3M9XCJiaSBiaS1leWVcIj48L2k+XG4gICAgICAgICAgICAgICAgICAgIDwvYT5cbiAgICAgICAgICAgICAgICAgICAgPGEgY2xhc3M9XCJidG4gYnRuLW91dGxpbmUtc2Vjb25kYXJ5XCIgaHJlZj1cIiNcIiB0aXRsZT1cIkVkaXRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxpIGNsYXNzPVwiYmkgYmktcGVuY2lsXCI+PC9pPlxuICAgICAgICAgICAgICAgICAgICA8L2E+XG4gICAgICAgICAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJidG4gYnRuLW91dGxpbmUtZGFuZ2VyXCIgdHlwZT1cImJ1dHRvblwiIHRpdGxlPVwiRGVsZXRlXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8aSBjbGFzcz1cImJpIGJpLXRyYXNoXCI+PC9pPlxuICAgICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgIDwvdHI+XG4gICAgPC8jcm93PlxuXG48L0RlZmluZTpDbGllbnRzX0RhdGFHcmlkPiIsIjwhLS1cbkFkZF9Vc2VyX01vZGFsX0Zvcm0gLSBNb2RhbCBmb3JtIGZvciBpbnZpdGluZyB1c2VycyB0byBzaXRlXG5cbkFsbG93cyBhZG1pbnMgdG8gaW52aXRlIHVzZXJzIGJ5IGVtYWlsLiBDcmVhdGVzIGEgcGVuZGluZyBpbnZpdGF0aW9uIHJlY29yZFxud2l0aCBhbiBpbnZpdGVfY29kZSB0aGF0IGV4cGlyZXMgYWZ0ZXIgY29uZmlndXJlZCBkYXlzLiBVc2VyIHJlY2VpdmVzIGludml0YXRpb25cblVSTCB0byBhY2NlcHQgYW5kIGNyZWF0ZSB0aGVpciBhY2NvdW50LlxuXG5GaWVsZHM6XG4tIGVtYWlsIChyZXF1aXJlZCk6IFVzZXIncyBlbWFpbCBhZGRyZXNzIGZvciBpbnZpdGF0aW9uXG4tIGZpcnN0X25hbWUgKHJlcXVpcmVkKTogVXNlcidzIGZpcnN0IG5hbWVcbi0gbGFzdF9uYW1lIChyZXF1aXJlZCk6IFVzZXIncyBsYXN0IG5hbWVcbi0gcm9sZV9pZCAocmVxdWlyZWQpOiBVc2VyJ3Mgcm9sZSAoT3duZXIvQWRtaW4vTWVtYmVyL1ZpZXdlcilcbi0gcGhvbmUgKG9wdGlvbmFsKTogVXNlcidzIHBob25lIG51bWJlclxuXG5Gb3JtIGZvbGxvd3MgUnN4X0Zvcm0gcGF0dGVybiB3aXRoIEZvcm1fRmllbGQgKyBpbnB1dCBjb21wb25lbnRzLlxuVmFsaWRhdGlvbiBoYW5kbGVkIHNlcnZlci1zaWRlLCBlcnJvcnMgZGlzcGxheWVkIHZpYSBGb3JtX1V0aWxzLlxuLS0+XG5cbjxEZWZpbmU6QWRkX1VzZXJfTW9kYWxfRm9ybT5cblxuICA8UnN4X0Zvcm0gJGNvbnRyb2xsZXI9XCJGcm9udGVuZF9TZXR0aW5nc19Vc2VyX01hbmFnZW1lbnRfQ29udHJvbGxlclwiICRtZXRob2Q9XCJhZGRfdXNlclwiPlxuXG4gICAgPGRpdiBjbGFzcz1cIm1iLTNcIj5cbiAgICAgIDxGb3JtX0ZpZWxkICRuYW1lPVwiZW1haWxcIiAkbGFiZWw9XCJFbWFpbCBBZGRyZXNzXCIgJHJlcXVpcmVkPXRydWU+XG4gICAgICAgIDxUZXh0X0lucHV0ICR0eXBlPVwiZW1haWxcIiAkcGxhY2Vob2xkZXI9XCJ1c2VyQGV4YW1wbGUuY29tXCIgJGF1dG9mb2N1cz10cnVlIC8+XG4gICAgICA8L0Zvcm1fRmllbGQ+XG4gICAgPC9kaXY+XG5cbiAgICA8ZGl2IGNsYXNzPVwicm93XCI+XG4gICAgICA8ZGl2IGNsYXNzPVwiY29sLW1kLTYgbWItM1wiPlxuICAgICAgICA8Rm9ybV9GaWVsZCAkbmFtZT1cImZpcnN0X25hbWVcIiAkbGFiZWw9XCJGaXJzdCBOYW1lXCIgJHJlcXVpcmVkPXRydWU+XG4gICAgICAgICAgPFRleHRfSW5wdXQgLz5cbiAgICAgICAgPC9Gb3JtX0ZpZWxkPlxuICAgICAgPC9kaXY+XG4gICAgICA8ZGl2IGNsYXNzPVwiY29sLW1kLTYgbWItM1wiPlxuICAgICAgICA8Rm9ybV9GaWVsZCAkbmFtZT1cImxhc3RfbmFtZVwiICRsYWJlbD1cIkxhc3QgTmFtZVwiICRyZXF1aXJlZD10cnVlPlxuICAgICAgICAgIDxUZXh0X0lucHV0IC8+XG4gICAgICAgIDwvRm9ybV9GaWVsZD5cbiAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuXG4gICAgPGRpdiBjbGFzcz1cIm1iLTNcIj5cbiAgICAgIDxGb3JtX0ZpZWxkICRuYW1lPVwicm9sZV9pZFwiICRsYWJlbD1cIlJvbGVcIiAkcmVxdWlyZWQ9dHJ1ZT5cbiAgICAgICAgPFNlbGVjdF9JbnB1dCAkb3B0aW9ucz1cIjwlPSBKU09OLnN0cmluZ2lmeShbXG4gICAgICAgICAge3ZhbHVlOiAzLCBsYWJlbDogJ01lbWJlcid9LFxuICAgICAgICAgIHt2YWx1ZTogMiwgbGFiZWw6ICdBZG1pbid9LFxuICAgICAgICAgIHt2YWx1ZTogMSwgbGFiZWw6ICdPd25lcid9LFxuICAgICAgICAgIHt2YWx1ZTogNCwgbGFiZWw6ICdWaWV3ZXInfVxuICAgICAgICBdKSAlPlwiIC8+XG4gICAgICA8L0Zvcm1fRmllbGQ+XG4gICAgPC9kaXY+XG5cbiAgICA8ZGl2IGNsYXNzPVwibWItM1wiPlxuICAgICAgPEZvcm1fRmllbGQgJG5hbWU9XCJwaG9uZVwiICRsYWJlbD1cIlBob25lIE51bWJlclwiPlxuICAgICAgICA8UGhvbmVfVGV4dF9JbnB1dCAkcGxhY2Vob2xkZXI9XCIoNTU1KSAxMjMtNDU2N1wiIC8+XG4gICAgICA8L0Zvcm1fRmllbGQ+XG4gICAgPC9kaXY+XG5cbiAgPC9Sc3hfRm9ybT5cblxuPC9EZWZpbmU6QWRkX1VzZXJfTW9kYWxfRm9ybT4iLCI8JS0tIFVzZXIgTWFuYWdlbWVudCBEYXRhR3JpZCBDb21wb25lbnQgLS0lPlxuXG48RGVmaW5lOlVzZXJzX0RhdGFHcmlkXG4gICAgZXh0ZW5kcz1cIkRhdGFHcmlkX0Fic3RyYWN0XCJcbiAgICAkZGF0YV9zb3VyY2U9RnJvbnRlbmRfU2V0dGluZ3NfVXNlcl9NYW5hZ2VtZW50X0NvbnRyb2xsZXIuZGF0YWdyaWRfZmV0Y2hcbiAgICAkc29ydD1cImlkXCJcbiAgICAkb3JkZXI9XCJkZXNjXCJcbiAgICAkcGVyX3BhZ2U9MTVcbiAgICBjbGFzcz1cImNhcmQgRGF0YUdyaWRcIj5cblxuICAgIDwjREdfQ2FyZF9IZWFkZXI+XG4gICAgICAgIDxDYXJkX1RpdGxlPlVzZXIgTGlzdDwvQ2FyZF9UaXRsZT5cbiAgICAgICAgPENhcmRfSGVhZGVyX1JpZ2h0PlxuICAgICAgICAgICAgPFNlYXJjaF9JbnB1dCAkaWQ9XCJmaWx0ZXJfaW5wdXRcIiAvPlxuICAgICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cImJ0biBidG4tc2Vjb25kYXJ5IGJ0bi1zbVwiPkZpbHRlcjwvYnV0dG9uPlxuICAgICAgICA8L0NhcmRfSGVhZGVyX1JpZ2h0PlxuICAgIDwvI0RHX0NhcmRfSGVhZGVyPlxuXG4gICAgPCNER19UYWJsZV9IZWFkZXI+XG4gICAgICAgIDx0cj5cbiAgICAgICAgICAgIDx0aCBzdHlsZT1cIndpZHRoOiA0MHB4O1wiPlxuICAgICAgICAgICAgICAgIDxpbnB1dCBjbGFzcz1cImZvcm0tY2hlY2staW5wdXRcIiB0eXBlPVwiY2hlY2tib3hcIiAkaWQ9XCJzZWxlY3RfYWxsXCI+XG4gICAgICAgICAgICA8L3RoPlxuICAgICAgICAgICAgPHRoICRzb3J0Ynk9XCJpZFwiPklEPC90aD5cbiAgICAgICAgICAgIDx0aCAkc29ydGJ5PVwiZmlyc3RfbmFtZVwiPk5hbWU8L3RoPlxuICAgICAgICAgICAgPHRoICRzb3J0Ynk9XCJlbWFpbFwiPkVtYWlsPC90aD5cbiAgICAgICAgICAgIDx0aD5TdGF0dXM8L3RoPlxuICAgICAgICAgICAgPHRoPlBob25lPC90aD5cbiAgICAgICAgICAgIDx0aCAkc29ydGJ5PVwidXNlcl9yb2xlX2lkXCI+Um9sZTwvdGg+XG4gICAgICAgICAgICA8dGggJHNvcnRieT1cImNyZWF0ZWRfYXRcIj5DcmVhdGVkPC90aD5cbiAgICAgICAgICAgIDx0aCBzdHlsZT1cIndpZHRoOiAxMjBweDtcIj5BY3Rpb25zPC90aD5cbiAgICAgICAgPC90cj5cbiAgICA8LyNER19UYWJsZV9IZWFkZXI+XG5cbiAgICA8I3Jvdz5cbiAgICAgICAgPHRyIGRhdGEtaHJlZj1cIjwlPSBSc3guUm91dGUoJ0Zyb250ZW5kX1NldHRpbmdzX1VzZXJfTWFuYWdlbWVudF9Db250cm9sbGVyJywgJ3ZpZXcnLCByb3cuaWQpICU+XCI+XG4gICAgICAgICAgICA8dGQ+XG4gICAgICAgICAgICAgICAgPGlucHV0IGNsYXNzPVwiZm9ybS1jaGVjay1pbnB1dCByb3ctY2hlY2tib3hcIiB0eXBlPVwiY2hlY2tib3hcIiB2YWx1ZT1cIjwlPSByb3cuaWQgJT5cIj5cbiAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICA8dGQ+XG4gICAgICAgICAgICAgICAgI1U8JT0gU3RyaW5nKHJvdy5pZCkucGFkU3RhcnQoMywgJzAnKSAlPlxuICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgIDx0ZD5cbiAgICAgICAgICAgICAgICA8JSBpZiAocm93LmZpcnN0X25hbWUgfHwgcm93Lmxhc3RfbmFtZSkgeyAlPlxuICAgICAgICAgICAgICAgICAgICA8JT0gcm93LmZpcnN0X25hbWUgJT4gPCU9IHJvdy5sYXN0X25hbWUgJT5cbiAgICAgICAgICAgICAgICA8JSB9IGVsc2UgeyAlPlxuICAgICAgICAgICAgICAgICAgICA8ZW0gY2xhc3M9XCJ0ZXh0LW11dGVkXCI+Tm8gbmFtZSBzZXQ8L2VtPlxuICAgICAgICAgICAgICAgIDwlIH0gJT5cbiAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICA8dGQ+XG4gICAgICAgICAgICAgICAgPCU9IHJvdy5lbWFpbCAlPlxuICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgIDx0ZD5cbiAgICAgICAgICAgICAgICA8JSBpZiAocm93Lmludml0YXRpb25fc3RhdHVzID09PSAnYWNjZXB0ZWQnKSB7ICU+XG4gICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiYmFkZ2UgYmctc3VjY2Vzc1wiPkFjdGl2ZTwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8JSB9IGVsc2UgaWYgKHJvdy5pbnZpdGF0aW9uX3N0YXR1cyA9PT0gJ2V4cGlyZWQnKSB7ICU+XG4gICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiYmFkZ2UgYmctZGFuZ2VyXCI+RXhwaXJlZDwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8JSB9IGVsc2UgeyAlPlxuICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImJhZGdlIGJnLXdhcm5pbmdcIj5JbnZpdGVkPC9zcGFuPlxuICAgICAgICAgICAgICAgIDwlIH0gJT5cbiAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICA8dGQ+PCU9IHJvdy5waG9uZSB8fCAnLScgJT48L3RkPlxuICAgICAgICAgICAgPHRkPlxuICAgICAgICAgICAgICAgIDwlIGlmIChyb3cudXNlcl9yb2xlX2lkX2xhYmVsKSB7ICU+XG4gICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiYmFkZ2UgYmctcHJpbWFyeVwiPjwlPSByb3cudXNlcl9yb2xlX2lkX2xhYmVsICU+PC9zcGFuPlxuICAgICAgICAgICAgICAgIDwlIH0gZWxzZSB7ICU+XG4gICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiYmFkZ2UgYmctc2Vjb25kYXJ5XCI+VXNlcjwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8JSB9ICU+XG4gICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgPHRkPjwlPSBuZXcgRGF0ZShyb3cuY3JlYXRlZF9hdCkudG9Mb2NhbGVEYXRlU3RyaW5nKCkgJT48L3RkPlxuICAgICAgICAgICAgPHRkPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJidG4tZ3JvdXAgYnRuLWdyb3VwLXNtXCI+XG4gICAgICAgICAgICAgICAgICAgIDxhIGNsYXNzPVwiYnRuIGJ0bi1vdXRsaW5lLXByaW1hcnlcIiBocmVmPVwiPCU9IFJzeC5Sb3V0ZSgnRnJvbnRlbmRfU2V0dGluZ3NfVXNlcl9NYW5hZ2VtZW50X0NvbnRyb2xsZXInLCAndmlldycsIHJvdy5pZCkgJT5cIiB0aXRsZT1cIlZpZXdcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxpIGNsYXNzPVwiYmkgYmktZXllXCI+PC9pPlxuICAgICAgICAgICAgICAgICAgICA8L2E+XG4gICAgICAgICAgICAgICAgICAgIDxhIGNsYXNzPVwiYnRuIGJ0bi1vdXRsaW5lLXNlY29uZGFyeVwiIGhyZWY9XCIjXCIgdGl0bGU9XCJFZGl0XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8aSBjbGFzcz1cImJpIGJpLXBlbmNpbFwiPjwvaT5cbiAgICAgICAgICAgICAgICAgICAgPC9hPlxuICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwiYnRuIGJ0bi1vdXRsaW5lLWRhbmdlclwiIHR5cGU9XCJidXR0b25cIiB0aXRsZT1cIkRlbGV0ZVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGkgY2xhc3M9XCJiaSBiaS10cmFzaFwiPjwvaT5cbiAgICAgICAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L3RkPlxuICAgICAgICA8L3RyPlxuICAgIDwvI3Jvdz5cblxuPC9EZWZpbmU6VXNlcnNfRGF0YUdyaWQ+XG4iLCI8IS0tXG5FZGl0X1VzZXJfTW9kYWxfRm9ybSAtIE1vZGFsIGZvcm0gZm9yIGVkaXRpbmcgdXNlciBpbmZvcm1hdGlvblxuXG5BbGxvd3MgYWRtaW5zIHRvIHVwZGF0ZSB1c2VyIHByb2ZpbGUgaW5mb3JtYXRpb24gZm9yIGV4aXN0aW5nIHVzZXJzLlxuXG5GaWVsZHM6XG4tIGlkIChoaWRkZW4pOiBVc2VyIElEXG4tIGVtYWlsIChyZXF1aXJlZCk6IFVzZXIncyBlbWFpbCBhZGRyZXNzXG4tIGZpcnN0X25hbWUgKHJlcXVpcmVkKTogVXNlcidzIGZpcnN0IG5hbWVcbi0gbGFzdF9uYW1lIChyZXF1aXJlZCk6IFVzZXIncyBsYXN0IG5hbWVcbi0gcm9sZV9pZCAocmVxdWlyZWQpOiBVc2VyJ3Mgcm9sZSAoT3duZXIvQWRtaW4vTWVtYmVyL1ZpZXdlcilcbi0gcGhvbmUgKG9wdGlvbmFsKTogVXNlcidzIHBob25lIG51bWJlclxuXG5Gb3JtIGZvbGxvd3MgUnN4X0Zvcm0gcGF0dGVybiB3aXRoIEZvcm1fRmllbGQgKyBpbnB1dCBjb21wb25lbnRzLlxuVmFsaWRhdGlvbiBoYW5kbGVkIHNlcnZlci1zaWRlLCBlcnJvcnMgZGlzcGxheWVkIHZpYSBGb3JtX1V0aWxzLlxuLS0+XG5cbjxEZWZpbmU6RWRpdF9Vc2VyX01vZGFsX0Zvcm0+XG5cbiAgPFJzeF9Gb3JtICRjb250cm9sbGVyPVwiRnJvbnRlbmRfU2V0dGluZ3NfVXNlcl9NYW5hZ2VtZW50X0NvbnRyb2xsZXJcIiAkbWV0aG9kPVwic2F2ZV91c2VyXCIgJGRhdGE9XCI8JT0gSlNPTi5zdHJpbmdpZnkodGhpcy5hcmdzLmRhdGEpICU+XCI+XG5cbiAgICA8Rm9ybV9IaWRkZW5fRmllbGQgJG5hbWU9XCJpZFwiIC8+XG5cbiAgICA8ZGl2IGNsYXNzPVwibWItM1wiPlxuICAgICAgPEZvcm1fRmllbGQgJG5hbWU9XCJlbWFpbFwiICRsYWJlbD1cIkVtYWlsIEFkZHJlc3NcIiAkcmVxdWlyZWQ9dHJ1ZT5cbiAgICAgICAgPFRleHRfSW5wdXQgJHR5cGU9XCJlbWFpbFwiICRwbGFjZWhvbGRlcj1cInVzZXJAZXhhbXBsZS5jb21cIiAkYXV0b2ZvY3VzPXRydWUgLz5cbiAgICAgIDwvRm9ybV9GaWVsZD5cbiAgICA8L2Rpdj5cblxuICAgIDxkaXYgY2xhc3M9XCJyb3dcIj5cbiAgICAgIDxkaXYgY2xhc3M9XCJjb2wtbWQtNiBtYi0zXCI+XG4gICAgICAgIDxGb3JtX0ZpZWxkICRuYW1lPVwiZmlyc3RfbmFtZVwiICRsYWJlbD1cIkZpcnN0IE5hbWVcIiAkcmVxdWlyZWQ9dHJ1ZT5cbiAgICAgICAgICA8VGV4dF9JbnB1dCAvPlxuICAgICAgICA8L0Zvcm1fRmllbGQ+XG4gICAgICA8L2Rpdj5cbiAgICAgIDxkaXYgY2xhc3M9XCJjb2wtbWQtNiBtYi0zXCI+XG4gICAgICAgIDxGb3JtX0ZpZWxkICRuYW1lPVwibGFzdF9uYW1lXCIgJGxhYmVsPVwiTGFzdCBOYW1lXCIgJHJlcXVpcmVkPXRydWU+XG4gICAgICAgICAgPFRleHRfSW5wdXQgLz5cbiAgICAgICAgPC9Gb3JtX0ZpZWxkPlxuICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG5cbiAgICA8ZGl2IGNsYXNzPVwibWItM1wiPlxuICAgICAgPEZvcm1fRmllbGQgJG5hbWU9XCJyb2xlX2lkXCIgJGxhYmVsPVwiUm9sZVwiICRyZXF1aXJlZD10cnVlPlxuICAgICAgICA8U2VsZWN0X0lucHV0ICRvcHRpb25zPVwiPCU9IEpTT04uc3RyaW5naWZ5KFtcbiAgICAgICAgICB7dmFsdWU6IDMsIGxhYmVsOiAnTWVtYmVyJ30sXG4gICAgICAgICAge3ZhbHVlOiAyLCBsYWJlbDogJ0FkbWluJ30sXG4gICAgICAgICAge3ZhbHVlOiAxLCBsYWJlbDogJ093bmVyJ30sXG4gICAgICAgICAge3ZhbHVlOiA0LCBsYWJlbDogJ1ZpZXdlcid9XG4gICAgICAgIF0pICU+XCIgLz5cbiAgICAgIDwvRm9ybV9GaWVsZD5cbiAgICA8L2Rpdj5cblxuICAgIDxkaXYgY2xhc3M9XCJtYi0zXCI+XG4gICAgICA8Rm9ybV9GaWVsZCAkbmFtZT1cInBob25lXCIgJGxhYmVsPVwiUGhvbmUgTnVtYmVyXCI+XG4gICAgICAgIDxQaG9uZV9UZXh0X0lucHV0ICRwbGFjZWhvbGRlcj1cIig1NTUpIDEyMy00NTY3XCIgLz5cbiAgICAgIDwvRm9ybV9GaWVsZD5cbiAgICA8L2Rpdj5cblxuICA8L1JzeF9Gb3JtPlxuXG48L0RlZmluZTpFZGl0X1VzZXJfTW9kYWxfRm9ybT5cbiIsIjwlLS0gRXh0ZW5kcyBEYXRhZ3JpZF9BYnN0cmFjdCAtLSU+XG5cbjwlLS0gV2UgYXJlIGhlcmU6IHNlZWluZyBpZiAkZGF0YV9zb3VyY2Ugd2lsbCB3b3JrLjogLS0lPlxuYGBcbjxEZWZpbmU6Q29udGFjdHNfRGF0YUdyaWRcbiAgICBleHRlbmRzPVwiRGF0YUdyaWRfQWJzdHJhY3RcIlxuICAgICRkYXRhX3NvdXJjZT1Gcm9udGVuZF9Db250YWN0c19Db250cm9sbGVyLmRhdGFncmlkX2ZldGNoXG4gICAgJHNvcnQ9XCJpZFwiXG4gICAgJG9yZGVyPVwiZGVzY1wiXG4gICAgJHBlcl9wYWdlPTE1XG4gICAgY2xhc3M9XCJjYXJkIERhdGFHcmlkXCI+XG5cbiAgICA8I0RHX0NhcmRfSGVhZGVyPlxuICAgICAgICA8Q2FyZF9UaXRsZT5Db250YWN0IExpc3Q8L0NhcmRfVGl0bGU+XG4gICAgICAgIDxDYXJkX0hlYWRlcl9SaWdodD5cbiAgICAgICAgICAgIDxTZWFyY2hfSW5wdXQgJGlkPVwiZmlsdGVyX2lucHV0XCIgLz5cbiAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJidG4gYnRuLXNlY29uZGFyeSBidG4tc21cIj5GaWx0ZXI8L2J1dHRvbj5cbiAgICAgICAgPC9DYXJkX0hlYWRlcl9SaWdodD5cbiAgICA8LyNER19DYXJkX0hlYWRlcj5cblxuICAgIDwjREdfVGFibGVfSGVhZGVyPlxuICAgICAgICA8dHI+XG4gICAgICAgICAgICA8dGggc3R5bGU9XCJ3aWR0aDogNDBweDtcIj5cbiAgICAgICAgICAgICAgICA8aW5wdXQgY2xhc3M9XCJmb3JtLWNoZWNrLWlucHV0XCIgdHlwZT1cImNoZWNrYm94XCIgJGlkPVwic2VsZWN0X2FsbFwiIC8+XG4gICAgICAgICAgICA8L3RoPlxuICAgICAgICAgICAgPHRoICRzb3J0Ynk9XCJpZFwiPklEPC90aD5cbiAgICAgICAgICAgIDx0aCAkc29ydGJ5PVwiZmlyc3RfbmFtZVwiPk5hbWU8L3RoPlxuICAgICAgICAgICAgPHRoICRzb3J0Ynk9XCJlbWFpbFwiPkVtYWlsPC90aD5cbiAgICAgICAgICAgIDx0aD5QaG9uZTwvdGg+XG4gICAgICAgICAgICA8dGg+Q29tcGFueTwvdGg+XG4gICAgICAgICAgICA8dGg+Um9sZTwvdGg+XG4gICAgICAgICAgICA8dGggJHNvcnRieT1cInByaW9yaXR5XCI+UHJpb3JpdHk8L3RoPlxuICAgICAgICAgICAgPHRoICRzb3J0Ynk9XCJjcmVhdGVkX2F0XCI+Q3JlYXRlZDwvdGg+XG4gICAgICAgICAgICA8dGggc3R5bGU9XCJ3aWR0aDogMTIwcHg7XCI+QWN0aW9uczwvdGg+XG4gICAgICAgIDwvdHI+XG4gICAgPC8jREdfVGFibGVfSGVhZGVyPlxuXG4gICAgPCNyb3c+XG4gICAgICAgIDwlLS0gPCUgY29uc29sZS5sb2coXCJJIGFtIGEgcm93XCIsIHJvdyk7ICU+IC0tJT5cbiAgICAgICAgPHRyICRocmVmPVJzeC5Sb3V0ZSgnRnJvbnRlbmRfQ29udGFjdHNfQ29udHJvbGxlcicsJ3ZpZXcnLHJvdy5pZCk+XG4gICAgICAgICAgICA8JS0tIDx0cj4gLS0lPlxuICAgICAgICAgICAgPHRkPlxuICAgICAgICAgICAgICAgIDxpbnB1dCBjbGFzcz1cImZvcm0tY2hlY2staW5wdXQgcm93LWNoZWNrYm94XCIgdHlwZT1cImNoZWNrYm94XCIgdmFsdWU9XCI8JT0gcm93LmlkICU+XCIgLz5cbiAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICA8dGQ+XG4gICAgICAgICAgICAgICAgI0NUPCU9IFN0cmluZyhyb3cuaWQpLnBhZFN0YXJ0KDMsICcwJykgJT5cbiAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICA8dGQ+XG4gICAgICAgICAgICAgICAgPCU9IHJvdy5maXJzdF9uYW1lICU+IDwlPSByb3cubGFzdF9uYW1lICU+XG4gICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgPHRkPlxuICAgICAgICAgICAgICAgIDwlPSByb3cuZW1haWwgJT5cbiAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICA8dGQ+PCU9IHJvdy5waG9uZV93b3JrIHx8ICctJyAlPjwvdGQ+XG4gICAgICAgICAgICA8dGQ+XG4gICAgICAgICAgICAgICAgPCUgaWYgKHJvdy5jbGllbnRfaWQpIHsgJT5cbiAgICAgICAgICAgICAgICAgICAgPENsaWVudF9MYWJlbCAkY2xpZW50X2lkPXJvdy5jbGllbnRfaWQgLz5cbiAgICAgICAgICAgICAgICA8JSB9IGVsc2UgeyAlPlxuICAgICAgICAgICAgICAgICAgICAtXG4gICAgICAgICAgICAgICAgPCUgfSAlPlxuICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgIDx0ZD4tPC90ZD5cbiAgICAgICAgICAgIDx0ZD5cbiAgICAgICAgICAgICAgICA8JSBpZiAocm93LnByaW9yaXR5ID09PSA0KSB7ICU+XG4gICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiYmFkZ2UgYmctZGFuZ2VyXCI+VXJnZW50PC9zcGFuPlxuICAgICAgICAgICAgICAgIDwlIH0gZWxzZSBpZiAocm93LnByaW9yaXR5ID09PSAzKSB7ICU+XG4gICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiYmFkZ2UgYmctd2FybmluZ1wiPkhpZ2g8L3NwYW4+XG4gICAgICAgICAgICAgICAgPCUgfSBlbHNlIGlmIChyb3cucHJpb3JpdHkgPT09IDIpIHsgJT5cbiAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJiYWRnZSBiZy1wcmltYXJ5XCI+TWVkaXVtPC9zcGFuPlxuICAgICAgICAgICAgICAgIDwlIH0gZWxzZSB7ICU+XG4gICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiYmFkZ2UgYmctc2Vjb25kYXJ5XCI+TG93PC9zcGFuPlxuICAgICAgICAgICAgICAgIDwlIH0gJT5cbiAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICA8dGQ+PCU9IG5ldyBEYXRlKHJvdy5jcmVhdGVkX2F0KS50b0xvY2FsZURhdGVTdHJpbmcoKSAlPjwvdGQ+XG4gICAgICAgICAgICA8dGQ+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImJ0bi1ncm91cCBidG4tZ3JvdXAtc21cIj5cbiAgICAgICAgICAgICAgICAgICAgPGEgY2xhc3M9XCJidG4gYnRuLW91dGxpbmUtcHJpbWFyeVwiIGhyZWY9XCIvY29udGFjdHMvdmlldy88JT0gcm93LmlkICU+XCIgdGl0bGU9XCJWaWV3XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8aSBjbGFzcz1cImJpIGJpLWV5ZVwiPjwvaT5cbiAgICAgICAgICAgICAgICAgICAgPC9hPlxuICAgICAgICAgICAgICAgICAgICA8YSBjbGFzcz1cImJ0biBidG4tb3V0bGluZS1zZWNvbmRhcnlcIiBocmVmPVwiI1wiIHRpdGxlPVwiRWRpdFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGkgY2xhc3M9XCJiaSBiaS1wZW5jaWxcIj48L2k+XG4gICAgICAgICAgICAgICAgICAgIDwvYT5cbiAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cImJ0biBidG4tb3V0bGluZS1kYW5nZXJcIiB0eXBlPVwiYnV0dG9uXCIgdGl0bGU9XCJEZWxldGVcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxpIGNsYXNzPVwiYmkgYmktdHJhc2hcIj48L2k+XG4gICAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgPC90cj5cbiAgICA8LyNyb3c+XG5cbjwvRGVmaW5lOkNvbnRhY3RzX0RhdGFHcmlkPiIsIjxEZWZpbmU6RGF0YV9UYWJsZSBjbGFzcz1cImNhcmRcIj5cblxuICA8ZGl2IGNsYXNzPVwiY2FyZC1oZWFkZXIgZC1mbGV4IGp1c3RpZnktY29udGVudC1iZXR3ZWVuIGFsaWduLWl0ZW1zLWNlbnRlclwiPlxuICAgIDxoNSBjbGFzcz1cIm1iLTBcIj48JT0gdGhpcy5hcmdzLnRpdGxlIHx8ICdEYXRhIFRhYmxlJyAlPjwvaDU+XG4gICAgPGRpdiBjbGFzcz1cImQtZmxleCBnYXAtMlwiPlxuICAgICAgPGRpdiAkaWQ9XCJzZWFyY2hfY29udGFpbmVyXCI+PC9kaXY+XG4gICAgICA8ZGl2ICRpZD1cImZpbHRlcl9jb250YWluZXJcIj48L2Rpdj5cbiAgICAgIDxkaXYgJGlkPVwiY29sdW1uX3RvZ2dsZV9jb250YWluZXJcIj48L2Rpdj5cbiAgICA8L2Rpdj5cbiAgPC9kaXY+XG5cbiAgPEJ1bGtfQWN0aW9uX0JhciAkaWQ9XCJidWxrX2JhclwiIHN0eWxlPVwiZGlzcGxheTogbm9uZTtcIj5cbiAgICA8QnV0dG9uX0RhbmdlciAkaWQ9XCJidWxrX2RlbGV0ZVwiPkRlbGV0ZSBTZWxlY3RlZDwvQnV0dG9uX0Rhbmdlcj5cbiAgICA8QnV0dG9uX1NlY29uZGFyeSAkaWQ9XCJidWxrX2V4cG9ydFwiPkV4cG9ydCBTZWxlY3RlZDwvQnV0dG9uX1NlY29uZGFyeT5cbiAgPC9CdWxrX0FjdGlvbl9CYXI+XG5cbiAgPGRpdiBjbGFzcz1cImNhcmQtYm9keSBwLTBcIj5cbiAgICA8ZGl2IGNsYXNzPVwidGFibGUtcmVzcG9uc2l2ZVwiPlxuICAgICAgPFRhYmxlICRpZD1cInRhYmxlXCI+XG4gICAgICAgIDx0aGVhZD5cbiAgICAgICAgICA8dHIgJGlkPVwiaGVhZGVyX3Jvd1wiPlxuICAgICAgICAgICAgPCUgaWYgKHRoaXMuYXJncy5idWxrX2FjdGlvbnMpIHsgJT5cbiAgICAgICAgICAgICAgPHRoIHN0eWxlPVwid2lkdGg6IDQwcHg7XCI+XG4gICAgICAgICAgICAgICAgPEJ1bGtfU2VsZWN0aW9uICRpZD1cImJ1bGtfc2VsZWN0aW9uXCIgLz5cbiAgICAgICAgICAgICAgPC90aD5cbiAgICAgICAgICAgIDwlIH0gJT5cbiAgICAgICAgICAgIDwhLS0gQ29sdW1uIGhlYWRlcnMgZHluYW1pY2FsbHkgZ2VuZXJhdGVkIC0tPlxuICAgICAgICAgIDwvdHI+XG4gICAgICAgIDwvdGhlYWQ+XG4gICAgICAgIDx0Ym9keSAkaWQ9XCJ0Ym9keVwiPlxuICAgICAgICAgIDwlIGlmIChPYmplY3Qua2V5cyh0aGlzLmRhdGEpLmxlbmd0aCA9PT0gMCkgeyAlPlxuICAgICAgICAgICAgPHRyPlxuICAgICAgICAgICAgICA8dGQgY29sc3Bhbj1cIjEwMFwiIGNsYXNzPVwidGV4dC1jZW50ZXIgcHktNVwiPlxuICAgICAgICAgICAgICAgIDxTcGlubmVyIC8+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm10LTIgdGV4dC1tdXRlZFwiPkxvYWRpbmcgZGF0YS4uLjwvZGl2PlxuICAgICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgPC90cj5cbiAgICAgICAgICA8JSB9IGVsc2UgaWYgKHRoaXMuZGF0YS5yb3dzICYmIHRoaXMuZGF0YS5yb3dzLmxlbmd0aCA9PT0gMCkgeyAlPlxuICAgICAgICAgICAgPHRyPlxuICAgICAgICAgICAgICA8dGQgY29sc3Bhbj1cIjEwMFwiPlxuICAgICAgICAgICAgICAgIDxFbXB0eV9TdGF0ZVxuICAgICAgICAgICAgICAgICAgJGljb249XCJpbmJveFwiXG4gICAgICAgICAgICAgICAgICAkdGl0bGU9XCJObyBkYXRhIGF2YWlsYWJsZVwiXG4gICAgICAgICAgICAgICAgICAkbWVzc2FnZT1cIlRoZXJlIGFyZSBubyByZWNvcmRzIHRvIGRpc3BsYXlcIlxuICAgICAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgIDwvdHI+XG4gICAgICAgICAgPCUgfSBlbHNlIHsgJT5cbiAgICAgICAgICAgIDwlIGZvciAobGV0IHJvdyBvZiB0aGlzLmRhdGEucm93cyB8fCBbXSkgeyAlPlxuICAgICAgICAgICAgICA8dHIgZGF0YS1pZD1cIjwlPSByb3cuaWQgJT5cIj5cbiAgICAgICAgICAgICAgICA8JSBpZiAodGhpcy5hcmdzLmJ1bGtfYWN0aW9ucykgeyAlPlxuICAgICAgICAgICAgICAgICAgPHRkPlxuICAgICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cImNoZWNrYm94XCIgY2xhc3M9XCJmb3JtLWNoZWNrLWlucHV0IHJvdy1jaGVja2JveFwiIHZhbHVlPVwiPCU9IHJvdy5pZCAlPlwiPlxuICAgICAgICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgICAgICA8JSB9ICU+XG4gICAgICAgICAgICAgICAgPCUgZm9yIChsZXQgY29sIG9mIHRoaXMuZGF0YS5jb2x1bW5zIHx8IFtdKSB7ICU+XG4gICAgICAgICAgICAgICAgICA8dGQ+PCU9IHJvd1tjb2wuZmllbGRdICU+PC90ZD5cbiAgICAgICAgICAgICAgICA8JSB9ICU+XG4gICAgICAgICAgICAgICAgPCUgaWYgKHRoaXMuYXJncy5yb3dfYWN0aW9ucykgeyAlPlxuICAgICAgICAgICAgICAgICAgPHRkPlxuICAgICAgICAgICAgICAgICAgICA8Um93X0FjdGlvbl9NZW51ICRpZD1cInJvd19hY3Rpb25zXzwlPSByb3cuaWQgJT5cIj5cbiAgICAgICAgICAgICAgICAgICAgICA8JT0gdGhpcy5hcmdzLnJvd19hY3Rpb25zKHJvdykgJT5cbiAgICAgICAgICAgICAgICAgICAgPC9Sb3dfQWN0aW9uX01lbnU+XG4gICAgICAgICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgICAgIDwlIH0gJT5cbiAgICAgICAgICAgICAgPC90cj5cbiAgICAgICAgICAgIDwlIH0gJT5cbiAgICAgICAgICA8JSB9ICU+XG4gICAgICAgIDwvdGJvZHk+XG4gICAgICA8L1RhYmxlPlxuICAgIDwvZGl2PlxuICA8L2Rpdj5cblxuICA8ZGl2IGNsYXNzPVwiY2FyZC1mb290ZXJcIiAkaWQ9XCJmb290ZXJcIj5cbiAgICA8VGFibGVfUGFnaW5hdGlvblxuICAgICAgJGlkPVwicGFnaW5hdGlvblwiXG4gICAgICAkc3RhcnQ9dGhpcy5kYXRhLnN0YXJ0XG4gICAgICAkZW5kPXRoaXMuZGF0YS5lbmRcbiAgICAgICR0b3RhbD10aGlzLmRhdGEudG90YWxcbiAgICAgICRjdXJyZW50X3BhZ2U9dGhpcy5kYXRhLmN1cnJlbnRfcGFnZVxuICAgICAgJHRvdGFsX3BhZ2VzPXRoaXMuZGF0YS50b3RhbF9wYWdlc1xuICAgICAgLz5cbiAgPC9kaXY+XG5cbjwvRGVmaW5lOkRhdGFfVGFibGU+IiwiPERlZmluZTpDYXJkX0hlYWRlcl9SaWdodCBjbGFzcz1cImQtZmxleCBnYXAtMlwiPlxyXG5cclxuICA8JT0gY29udGVudCgpICU+XHJcblxyXG48L0RlZmluZTpDYXJkX0hlYWRlcl9SaWdodD4iLCI8IS0tXG5DbGllbnRfU2VsZWN0b3JfSW5wdXRcblxuU3BlY2lhbGl6ZWQgc2VsZWN0IGZvciBjbGllbnQgZHJvcGRvd25zIHdpdGggQWpheCBsb2FkaW5nLlxuRXh0ZW5kcyBBamF4X1NlbGVjdF9JbnB1dCB3aXRoIGNsaWVudC1zcGVjaWZpYyBiZWhhdmlvci5cblxuJGRhdGEgLSBBamF4IGVuZHBvaW50IGZvciBjbGllbnQgZGF0YSAob3B0aW9uYWwsIGRlZmF1bHRzIHRvIEZyb250ZW5kX0NvbnRhY3RzX0NvbnRyb2xsZXIuZ2V0X2NsaWVudHMoKSlcbiRwbGFjZWhvbGRlciAtIFBsYWNlaG9sZGVyIHRleHQgKGRlZmF1bHQ6IFwiU2VsZWN0IENsaWVudC4uLlwiKVxuJGRpc2FibGVkIC0gQm9vbGVhbiB0byBkaXNhYmxlIHRoZSBzZWxlY3RcblxuRmVhdHVyZXM6XG4tIExvYWRzIGNsaWVudCBsaXN0IHZpYSBBamF4IGF1dG9tYXRpY2FsbHlcbi0gSW5oZXJpdHMgYWxsIEFqYXhfU2VsZWN0X0lucHV0IGJlaGF2aW9yIChUb20gU2VsZWN0LCBzZWFyY2gsIGxvYWRpbmcgc3RhdGVzLCBldGMuKVxuLS0+XG48RGVmaW5lOkNsaWVudF9TZWxlY3Rvcl9JbnB1dCBleHRlbmRzPVwiQWpheF9TZWxlY3RfSW5wdXRcIiBjbGFzcz1cIldpZGdldFwiPlxuICAgIDxzZWxlY3QgJGlkPVwiaW5wdXRcIiA8JSBpZiAodGhpcy5hcmdzLmRpc2FibGVkKSB7ICU+ZGlzYWJsZWQ8JSB9ICU+PlxuICAgICAgICA8JSBpZiAoIXRoaXMuZGF0YS5zZWxlY3RfdmFsdWVzIHx8IHRoaXMuZGF0YS5zZWxlY3RfdmFsdWVzLmxlbmd0aCA9PT0gMCkgeyAlPlxuICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT1cIlwiPjwlPSB0aGlzLmFyZ3MucGxhY2Vob2xkZXIgfHwgJ1BsZWFzZSB3YWl0Li4uJyAlPjwvb3B0aW9uPlxuICAgICAgICA8JSB9IGVsc2UgeyAlPlxuICAgICAgICAgICAgPCUgaWYgKHRoaXMuYXJncy5wbGFjZWhvbGRlcikgeyAlPlxuICAgICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCJcIj48JT0gdGhpcy5hcmdzLnBsYWNlaG9sZGVyICU+PC9vcHRpb24+XG4gICAgICAgICAgICA8JSB9ICU+XG4gICAgICAgICAgICA8JSBmb3IgKGxldCBvcHQgb2YgdGhpcy5kYXRhLnNlbGVjdF92YWx1ZXMpIHsgJT5cbiAgICAgICAgICAgICAgICA8JSBpZiAodHlwZW9mIG9wdCA9PT0gJ29iamVjdCcpIHsgJT5cbiAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT1cIjwlPSBvcHQudmFsdWUgJT5cIiA8JSBpZiAodGhpcy5kYXRhLnZhbHVlID09IG9wdC52YWx1ZSkgeyAlPnNlbGVjdGVkPCUgfSAlPj48JT0gb3B0LmxhYmVsICU+PC9vcHRpb24+XG4gICAgICAgICAgICAgICAgPCUgfSBlbHNlIHsgJT5cbiAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT1cIjwlPSBvcHQgJT5cIiA8JSBpZiAodGhpcy5kYXRhLnZhbHVlID09IG9wdCkgeyAlPnNlbGVjdGVkPCUgfSAlPj48JT0gb3B0ICU+PC9vcHRpb24+XG4gICAgICAgICAgICAgICAgPCUgfSAlPlxuICAgICAgICAgICAgPCUgfSAlPlxuICAgICAgICA8JSB9ICU+XG4gICAgPC9zZWxlY3Q+XG48L0RlZmluZTpDbGllbnRfU2VsZWN0b3JfSW5wdXQ+XG4iLCI8JS0tIEV4dGVuZHMgRGF0YWdyaWRfQWJzdHJhY3QgLS0lPlxuXG48RGVmaW5lOlByb2plY3RzX0RhdGFHcmlkXG4gICAgZXh0ZW5kcz1cIkRhdGFHcmlkX0Fic3RyYWN0XCJcbiAgICAkZGF0YV9zb3VyY2U9RnJvbnRlbmRfUHJvamVjdHNfQ29udHJvbGxlci5kYXRhZ3JpZF9mZXRjaFxuICAgICRzb3J0PVwiY3JlYXRlZF9hdFwiXG4gICAgJHBlcl9wYWdlPTE1XG4gICAgY2xhc3M9XCJjYXJkIERhdGFHcmlkXCI+XG5cbiAgICA8I0RHX0NhcmRfSGVhZGVyPlxuICAgICAgICA8Q2FyZF9UaXRsZT5Qcm9qZWN0IExpc3Q8L0NhcmRfVGl0bGU+XG4gICAgICAgIDxDYXJkX0hlYWRlcl9SaWdodD5cbiAgICAgICAgICAgIDxTZWFyY2hfSW5wdXQgJGlkPVwiZmlsdGVyX2lucHV0XCIgLz5cbiAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJidG4gYnRuLXNlY29uZGFyeSBidG4tc21cIj5GaWx0ZXI8L2J1dHRvbj5cbiAgICAgICAgPC9DYXJkX0hlYWRlcl9SaWdodD5cbiAgICA8LyNER19DYXJkX0hlYWRlcj5cblxuICAgIDwjREdfVGFibGVfSGVhZGVyPlxuICAgICAgICA8dHI+XG4gICAgICAgICAgICA8dGggc3R5bGU9XCJ3aWR0aDogNDBweDtcIj5cbiAgICAgICAgICAgICAgICA8aW5wdXQgY2xhc3M9XCJmb3JtLWNoZWNrLWlucHV0XCIgdHlwZT1cImNoZWNrYm94XCIgJGlkPVwic2VsZWN0X2FsbFwiIC8+XG4gICAgICAgICAgICA8L3RoPlxuICAgICAgICAgICAgPHRoICRzb3J0Ynk9XCJpZFwiPklEPC90aD5cbiAgICAgICAgICAgIDx0aCAkc29ydGJ5PVwibmFtZVwiPlByb2plY3QgTmFtZTwvdGg+XG4gICAgICAgICAgICA8dGggJHNvcnRieT1cImNsaWVudF9pZFwiPkNsaWVudDwvdGg+XG4gICAgICAgICAgICA8dGggJHNvcnRieT1cInN0YXR1c1wiPlN0YXR1czwvdGg+XG4gICAgICAgICAgICA8dGggJHNvcnRieT1cInByaW9yaXR5XCI+UHJpb3JpdHk8L3RoPlxuICAgICAgICAgICAgPHRoICRzb3J0Ynk9XCJzdGFydF9kYXRlXCI+U3RhcnQgRGF0ZTwvdGg+XG4gICAgICAgICAgICA8dGggJHNvcnRieT1cImR1ZV9kYXRlXCI+RHVlIERhdGU8L3RoPlxuICAgICAgICAgICAgPHRoICRzb3J0Ynk9XCJjcmVhdGVkX2F0XCI+Q3JlYXRlZDwvdGg+XG4gICAgICAgICAgICA8dGggc3R5bGU9XCJ3aWR0aDogMTIwcHg7XCI+QWN0aW9uczwvdGg+XG4gICAgICAgIDwvdHI+XG4gICAgPC8jREdfVGFibGVfSGVhZGVyPlxuXG4gICAgPCNyb3c+XG4gICAgICAgIDx0ciAkaHJlZj1Sc3guUm91dGUoJ0Zyb250ZW5kX1Byb2plY3RzX0NvbnRyb2xsZXInLCd2aWV3Jyxyb3cuaWQpPlxuICAgICAgICAgICAgPHRkPlxuICAgICAgICAgICAgICAgIDxpbnB1dCBjbGFzcz1cImZvcm0tY2hlY2staW5wdXQgcm93LWNoZWNrYm94XCIgdHlwZT1cImNoZWNrYm94XCIgdmFsdWU9XCI8JT0gcm93LmlkICU+XCIgLz5cbiAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICA8dGQ+XG4gICAgICAgICAgICAgICAgI1BSPCU9IFN0cmluZyhyb3cuaWQpLnBhZFN0YXJ0KDMsICcwJykgJT5cbiAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICA8dGQ+XG4gICAgICAgICAgICAgICAgPCU9IHJvdy5uYW1lICU+XG4gICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgPHRkPlxuICAgICAgICAgICAgICAgIDwlIGlmIChyb3cuY2xpZW50KSB7ICU+XG4gICAgICAgICAgICAgICAgICAgIDwlPSByb3cuY2xpZW50Lm5hbWUgJT5cbiAgICAgICAgICAgICAgICA8JSB9IGVsc2UgeyAlPlxuICAgICAgICAgICAgICAgICAgICAtXG4gICAgICAgICAgICAgICAgPCUgfSAlPlxuICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgIDx0ZD5cbiAgICAgICAgICAgICAgICA8JSBpZiAocm93LnN0YXR1cyA9PT0gMSkgeyAlPlxuICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImJhZGdlIGJnLWluZm9cIj5QbGFubmluZzwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8JSB9IGVsc2UgaWYgKHJvdy5zdGF0dXMgPT09IDIpIHsgJT5cbiAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJiYWRnZSBiZy1zdWNjZXNzXCI+QWN0aXZlPC9zcGFuPlxuICAgICAgICAgICAgICAgIDwlIH0gZWxzZSBpZiAocm93LnN0YXR1cyA9PT0gMykgeyAlPlxuICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImJhZGdlIGJnLXdhcm5pbmdcIj5PbiBIb2xkPC9zcGFuPlxuICAgICAgICAgICAgICAgIDwlIH0gZWxzZSBpZiAocm93LnN0YXR1cyA9PT0gNCkgeyAlPlxuICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImJhZGdlIGJnLXByaW1hcnlcIj5Db21wbGV0ZWQ8L3NwYW4+XG4gICAgICAgICAgICAgICAgPCUgfSBlbHNlIGlmIChyb3cuc3RhdHVzID09PSA1KSB7ICU+XG4gICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiYmFkZ2UgYmctc2Vjb25kYXJ5XCI+Q2FuY2VsbGVkPC9zcGFuPlxuICAgICAgICAgICAgICAgIDwlIH0gJT5cbiAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICA8dGQ+XG4gICAgICAgICAgICAgICAgPCUgaWYgKHJvdy5wcmlvcml0eSA9PT0gNCkgeyAlPlxuICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImJhZGdlIGJnLWRhbmdlclwiPlVyZ2VudDwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8JSB9IGVsc2UgaWYgKHJvdy5wcmlvcml0eSA9PT0gMykgeyAlPlxuICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImJhZGdlIGJnLXdhcm5pbmdcIj5IaWdoPC9zcGFuPlxuICAgICAgICAgICAgICAgIDwlIH0gZWxzZSBpZiAocm93LnByaW9yaXR5ID09PSAyKSB7ICU+XG4gICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiYmFkZ2UgYmctcHJpbWFyeVwiPk1lZGl1bTwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8JSB9IGVsc2UgeyAlPlxuICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImJhZGdlIGJnLXNlY29uZGFyeVwiPkxvdzwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8JSB9ICU+XG4gICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgPHRkPjwlPSByb3cuc3RhcnRfZGF0ZSA/IG5ldyBEYXRlKHJvdy5zdGFydF9kYXRlKS50b0xvY2FsZURhdGVTdHJpbmcoKSA6ICctJyAlPjwvdGQ+XG4gICAgICAgICAgICA8dGQ+PCU9IHJvdy5kdWVfZGF0ZSA/IG5ldyBEYXRlKHJvdy5kdWVfZGF0ZSkudG9Mb2NhbGVEYXRlU3RyaW5nKCkgOiAnLScgJT48L3RkPlxuICAgICAgICAgICAgPHRkPjwlPSBuZXcgRGF0ZShyb3cuY3JlYXRlZF9hdCkudG9Mb2NhbGVEYXRlU3RyaW5nKCkgJT48L3RkPlxuICAgICAgICAgICAgPHRkPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJidG4tZ3JvdXAgYnRuLWdyb3VwLXNtXCI+XG4gICAgICAgICAgICAgICAgICAgIDxhIGNsYXNzPVwiYnRuIGJ0bi1vdXRsaW5lLXByaW1hcnlcIiBocmVmPVwiPCU9IFJzeC5Sb3V0ZSgnRnJvbnRlbmRfUHJvamVjdHNfQ29udHJvbGxlcicsICd2aWV3Jywgcm93LmlkKSAlPlwiIHRpdGxlPVwiVmlld1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGkgY2xhc3M9XCJiaSBiaS1leWVcIj48L2k+XG4gICAgICAgICAgICAgICAgICAgIDwvYT5cbiAgICAgICAgICAgICAgICAgICAgPGEgY2xhc3M9XCJidG4gYnRuLW91dGxpbmUtc2Vjb25kYXJ5XCIgaHJlZj1cIiNcIiB0aXRsZT1cIkVkaXRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxpIGNsYXNzPVwiYmkgYmktcGVuY2lsXCI+PC9pPlxuICAgICAgICAgICAgICAgICAgICA8L2E+XG4gICAgICAgICAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJidG4gYnRuLW91dGxpbmUtZGFuZ2VyXCIgdHlwZT1cImJ1dHRvblwiIHRpdGxlPVwiRGVsZXRlXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8aSBjbGFzcz1cImJpIGJpLXRyYXNoXCI+PC9pPlxuICAgICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgIDwvdHI+XG4gICAgPC8jcm93PlxuXG48L0RlZmluZTpQcm9qZWN0c19EYXRhR3JpZD5cbiIsIi8vIEphdmFTY3JpcHQgTWFuaWZlc3QgLSBHZW5lcmF0ZWQgYnkgQnVuZGxlQ29tcGlsZXJcbi8vIFJlZ2lzdGVycyBhbGwgY2xhc3NlcyBpbiB0aGlzIGJ1bmRsZSBmb3IgcnVudGltZSBpbnRyb3NwZWN0aW9uXG5NYW5pZmVzdC5fZGVmaW5lKFtcbiAgICBbTWFuaWZlc3QsIFwiTWFuaWZlc3RcIiwgbnVsbF0sXG4gICAgW1JzeF9CZWhhdmlvcnMsIFwiUnN4X0JlaGF2aW9yc1wiLCBudWxsXSxcbiAgICBbUnN4X0NhY2hlLCBcIlJzeF9DYWNoZVwiLCBudWxsXSxcbiAgICBbUnN4X0luaXQsIFwiUnN4X0luaXRcIiwgbnVsbF0sXG4gICAgW1JzeF9Kc19Nb2RlbCwgXCJSc3hfSnNfTW9kZWxcIiwgbnVsbF0sXG4gICAgW1JzeF9WaWV3X1RyYW5zaXRpb25zLCBcIlJzeF9WaWV3X1RyYW5zaXRpb25zXCIsIG51bGxdLFxuICAgIFtSZWFkV3JpdGVMb2NrLCBcIlJlYWRXcml0ZUxvY2tcIiwgbnVsbF0sXG4gICAgW0Zvcm1fVXRpbHMsIFwiRm9ybV9VdGlsc1wiLCBudWxsXSxcbiAgICBbRGVidWdnZXIsIFwiRGVidWdnZXJcIiwgbnVsbF0sXG4gICAgW1JzeF9KcV9IZWxwZXJzLCBcIlJzeF9KcV9IZWxwZXJzXCIsIG51bGxdLFxuICAgIFtSc3gsIFwiUnN4XCIsIG51bGxdLFxuICAgIFtBamF4LCBcIkFqYXhcIiwgbnVsbF0sXG4gICAgW0pxaHRtbF9Db21wb25lbnQsIFwiSnFodG1sX0NvbXBvbmVudFwiLCBfQmFzZV9KcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbSnFodG1sX0ludGVncmF0aW9uLCBcIkpxaHRtbF9JbnRlZ3JhdGlvblwiLCBudWxsXSxcbiAgICBbRGF0YUdyaWRfQWJzdHJhY3QsIFwiRGF0YUdyaWRfQWJzdHJhY3RcIiwgSnFodG1sX0NvbXBvbmVudF0sXG4gICAgW0FjdGl2aXR5X0ZlZWQsIFwiQWN0aXZpdHlfRmVlZFwiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbQWN0b3JfUmVmZXJlbmNlLCBcIkFjdG9yX1JlZmVyZW5jZVwiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbQWR2YW5jZWRfU2VhcmNoX1BhbmVsLCBcIkFkdmFuY2VkX1NlYXJjaF9QYW5lbFwiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbQWxlcnRfQmFubmVyLCBcIkFsZXJ0X0Jhbm5lclwiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbQXZhdGFyLCBcIkF2YXRhclwiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbQmxvY2txdW90ZSwgXCJCbG9ja3F1b3RlXCIsIEpxaHRtbF9Db21wb25lbnRdLFxuICAgIFtCcmVhZGNydW1icywgXCJCcmVhZGNydW1ic1wiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbQnVsa19BY3Rpb25fQmFyLCBcIkJ1bGtfQWN0aW9uX0JhclwiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbQnVsa19TZWxlY3Rpb24sIFwiQnVsa19TZWxlY3Rpb25cIiwgSnFodG1sX0NvbXBvbmVudF0sXG4gICAgW0J1dHRvbl9Hcm91cCwgXCJCdXR0b25fR3JvdXBcIiwgSnFodG1sX0NvbXBvbmVudF0sXG4gICAgW0J1dHRvbl9QcmltYXJ5LCBcIkJ1dHRvbl9QcmltYXJ5XCIsIEpxaHRtbF9Db21wb25lbnRdLFxuICAgIFtCdXR0b25fU2Vjb25kYXJ5LCBcIkJ1dHRvbl9TZWNvbmRhcnlcIiwgSnFodG1sX0NvbXBvbmVudF0sXG4gICAgW0J1dHRvbiwgXCJCdXR0b25cIiwgSnFodG1sX0NvbXBvbmVudF0sXG4gICAgW0NhbGVuZGFyX0V2ZW50LCBcIkNhbGVuZGFyX0V2ZW50XCIsIEpxaHRtbF9Db21wb25lbnRdLFxuICAgIFtDYWxlbmRhcl9HcmlkLCBcIkNhbGVuZGFyX0dyaWRcIiwgSnFodG1sX0NvbXBvbmVudF0sXG4gICAgW0NhcmQsIFwiQ2FyZFwiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbQ2hhcnRfQ29tcG9uZW50LCBcIkNoYXJ0X0NvbXBvbmVudFwiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbQ2hlY2tib3gsIFwiQ2hlY2tib3hcIiwgSnFodG1sX0NvbXBvbmVudF0sXG4gICAgW0NvZGVfQmxvY2ssIFwiQ29kZV9CbG9ja1wiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbQ29sdW1uX1Zpc2liaWxpdHlfVG9nZ2xlLCBcIkNvbHVtbl9WaXNpYmlsaXR5X1RvZ2dsZVwiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbQ29tbWVudF9UaHJlYWQsIFwiQ29tbWVudF9UaHJlYWRcIiwgSnFodG1sX0NvbXBvbmVudF0sXG4gICAgW0RhdGVfUGlja2VyLCBcIkRhdGVfUGlja2VyXCIsIEpxaHRtbF9Db21wb25lbnRdLFxuICAgIFtEcm9wZG93bl9NZW51LCBcIkRyb3Bkb3duX01lbnVcIiwgSnFodG1sX0NvbXBvbmVudF0sXG4gICAgW0VtcHR5X1N0YXRlLCBcIkVtcHR5X1N0YXRlXCIsIEpxaHRtbF9Db21wb25lbnRdLFxuICAgIFtFeHBvcnRfQnV0dG9uLCBcIkV4cG9ydF9CdXR0b25cIiwgSnFodG1sX0NvbXBvbmVudF0sXG4gICAgW0ZpbGVfVXBsb2FkLCBcIkZpbGVfVXBsb2FkXCIsIEpxaHRtbF9Db21wb25lbnRdLFxuICAgIFtGaWx0ZXJfQmFyLCBcIkZpbHRlcl9CYXJcIiwgSnFodG1sX0NvbXBvbmVudF0sXG4gICAgW0Zvcm1fQWN0aW9uc19Db21wb25lbnQsIFwiRm9ybV9BY3Rpb25zX0NvbXBvbmVudFwiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbRm9ybV9GaWVsZF9Hcm91cCwgXCJGb3JtX0ZpZWxkX0dyb3VwXCIsIEpxaHRtbF9Db21wb25lbnRdLFxuICAgIFtGb3JtX0dyb3VwX0NvbXBvbmVudCwgXCJGb3JtX0dyb3VwX0NvbXBvbmVudFwiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbRm9ybV9Sb3dfQ29tcG9uZW50LCBcIkZvcm1fUm93X0NvbXBvbmVudFwiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbRm9ybV9WYWxpZGF0aW9uX01lc3NhZ2UsIFwiRm9ybV9WYWxpZGF0aW9uX01lc3NhZ2VcIiwgSnFodG1sX0NvbXBvbmVudF0sXG4gICAgW0dhbnR0X0NoYXJ0LCBcIkdhbnR0X0NoYXJ0XCIsIEpxaHRtbF9Db21wb25lbnRdLFxuICAgIFtJY29uX0J1dHRvbiwgXCJJY29uX0J1dHRvblwiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbSWNvbl9XaXRoX0xhYmVsLCBcIkljb25fV2l0aF9MYWJlbFwiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbSWNvbl9XaXRoX1RleHQsIFwiSWNvbl9XaXRoX1RleHRcIiwgSnFodG1sX0NvbXBvbmVudF0sXG4gICAgW0ljb24sIFwiSWNvblwiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbSW5mb19Cb3gsIFwiSW5mb19Cb3hcIiwgSnFodG1sX0NvbXBvbmVudF0sXG4gICAgW0lubGluZV9FZGl0X0ZpZWxkLCBcIklubGluZV9FZGl0X0ZpZWxkXCIsIEpxaHRtbF9Db21wb25lbnRdLFxuICAgIFtJbnB1dF9XaXRoX0ljb24sIFwiSW5wdXRfV2l0aF9JY29uXCIsIEpxaHRtbF9Db21wb25lbnRdLFxuICAgIFtJbnB1dF9XaXRoX1ZhbGlkYXRpb24sIFwiSW5wdXRfV2l0aF9WYWxpZGF0aW9uXCIsIEpxaHRtbF9Db21wb25lbnRdLFxuICAgIFtJbnB1dCwgXCJJbnB1dFwiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbS2FuYmFuX0JvYXJkLCBcIkthbmJhbl9Cb2FyZFwiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbTGluaywgXCJMaW5rXCIsIEpxaHRtbF9Db21wb25lbnRdLFxuICAgIFtMaXN0LCBcIkxpc3RcIiwgSnFodG1sX0NvbXBvbmVudF0sXG4gICAgW0xvYWRpbmdfU2tlbGV0b24sIFwiTG9hZGluZ19Ta2VsZXRvblwiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbTWV0cmljX0NhcmQsIFwiTWV0cmljX0NhcmRcIiwgSnFodG1sX0NvbXBvbmVudF0sXG4gICAgW01vYmlsZV9IZWFkZXIsIFwiTW9iaWxlX0hlYWRlclwiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbTW9kYWxfRGlhbG9nLCBcIk1vZGFsX0RpYWxvZ1wiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbTXVsdGlfU2VsZWN0LCBcIk11bHRpX1NlbGVjdFwiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbTm90aWZpY2F0aW9uX0JhZGdlLCBcIk5vdGlmaWNhdGlvbl9CYWRnZVwiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbTm90aWZpY2F0aW9uX0Ryb3Bkb3duLCBcIk5vdGlmaWNhdGlvbl9Ecm9wZG93blwiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbT3ZlcmR1ZV9JbmRpY2F0b3IsIFwiT3ZlcmR1ZV9JbmRpY2F0b3JcIiwgSnFodG1sX0NvbXBvbmVudF0sXG4gICAgW1BhZ2VfSGVhZGVyLCBcIlBhZ2VfSGVhZGVyXCIsIEpxaHRtbF9Db21wb25lbnRdLFxuICAgIFtQYWdlX1NlY3Rpb24sIFwiUGFnZV9TZWN0aW9uXCIsIEpxaHRtbF9Db21wb25lbnRdLFxuICAgIFtQYWdlLCBcIlBhZ2VcIiwgSnFodG1sX0NvbXBvbmVudF0sXG4gICAgW1BvcG92ZXIsIFwiUG9wb3ZlclwiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbUHJvZ3Jlc3NfQmFyLCBcIlByb2dyZXNzX0JhclwiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbUmFkaW9fQnV0dG9uLCBcIlJhZGlvX0J1dHRvblwiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbUmljaF9UZXh0X0VkaXRvciwgXCJSaWNoX1RleHRfRWRpdG9yXCIsIEpxaHRtbF9Db21wb25lbnRdLFxuICAgIFtSb3dfQWN0aW9uX01lbnUsIFwiUm93X0FjdGlvbl9NZW51XCIsIEpxaHRtbF9Db21wb25lbnRdLFxuICAgIFtTYW1wbGVfRGF0YWdyaWRfQ29tcG9uZW50LCBcIlNhbXBsZV9EYXRhZ3JpZF9Db21wb25lbnRcIiwgSnFodG1sX0NvbXBvbmVudF0sXG4gICAgW1NlYXJjaF9CYXIsIFwiU2VhcmNoX0JhclwiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbU2VhcmNoYWJsZV9TZWxlY3QsIFwiU2VhcmNoYWJsZV9TZWxlY3RcIiwgSnFodG1sX0NvbXBvbmVudF0sXG4gICAgW1NlbGVjdF9Ecm9wZG93biwgXCJTZWxlY3RfRHJvcGRvd25cIiwgSnFodG1sX0NvbXBvbmVudF0sXG4gICAgW1NpZGViYXJfTmF2LCBcIlNpZGViYXJfTmF2XCIsIEpxaHRtbF9Db21wb25lbnRdLFxuICAgIFtTb3J0YWJsZV9Db2x1bW5fSGVhZGVyLCBcIlNvcnRhYmxlX0NvbHVtbl9IZWFkZXJcIiwgSnFodG1sX0NvbXBvbmVudF0sXG4gICAgW1NwaW5uZXIsIFwiU3Bpbm5lclwiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbU3RhdF9DYXJkLCBcIlN0YXRfQ2FyZFwiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbU3RhdHVzX0JhZGdlLCBcIlN0YXR1c19CYWRnZVwiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbVGFiX0NvbnRlbnQsIFwiVGFiX0NvbnRlbnRcIiwgSnFodG1sX0NvbXBvbmVudF0sXG4gICAgW1RhYmxlX1BhZ2luYXRpb24sIFwiVGFibGVfUGFnaW5hdGlvblwiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbVGFibGUsIFwiVGFibGVcIiwgSnFodG1sX0NvbXBvbmVudF0sXG4gICAgW1RhYnMsIFwiVGFic1wiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbVGFnX0dyb3VwLCBcIlRhZ19Hcm91cFwiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbVGFnLCBcIlRhZ1wiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbVGV4dF9EaXNwbGF5LCBcIlRleHRfRGlzcGxheVwiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbVGV4dGFyZWEsIFwiVGV4dGFyZWFcIiwgSnFodG1sX0NvbXBvbmVudF0sXG4gICAgW1RocmVlX0NvbHVtbl9MYXlvdXQsIFwiVGhyZWVfQ29sdW1uX0xheW91dFwiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbVGltZV9QaWNrZXIsIFwiVGltZV9QaWNrZXJcIiwgSnFodG1sX0NvbXBvbmVudF0sXG4gICAgW1RpbWVsaW5lLCBcIlRpbWVsaW5lXCIsIEpxaHRtbF9Db21wb25lbnRdLFxuICAgIFtUaW1lc3RhbXBfRGlzcGxheSwgXCJUaW1lc3RhbXBfRGlzcGxheVwiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbVG9vbHRpcCwgXCJUb29sdGlwXCIsIEpxaHRtbF9Db21wb25lbnRdLFxuICAgIFtUb3BfTmF2LCBcIlRvcF9OYXZcIiwgSnFodG1sX0NvbXBvbmVudF0sXG4gICAgW1RyZW5kX0luZGljYXRvciwgXCJUcmVuZF9JbmRpY2F0b3JcIiwgSnFodG1sX0NvbXBvbmVudF0sXG4gICAgW1R3b19Db2x1bW5fTGF5b3V0LCBcIlR3b19Db2x1bW5fTGF5b3V0XCIsIEpxaHRtbF9Db21wb25lbnRdLFxuICAgIFtVc2VyX0F2YXRhcl9Ecm9wZG93biwgXCJVc2VyX0F2YXRhcl9Ecm9wZG93blwiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbTW9kYWxfQWJzdHJhY3QsIFwiTW9kYWxfQWJzdHJhY3RcIiwgbnVsbF0sXG4gICAgW1JzeF9Nb2RhbCwgXCJSc3hfTW9kYWxcIiwgSnFodG1sX0NvbXBvbmVudF0sXG4gICAgW01vZGFsLCBcIk1vZGFsXCIsIG51bGxdLFxuICAgIFtCcmVhZGNydW1iX0l0ZW0sIFwiQnJlYWRjcnVtYl9JdGVtXCIsIEpxaHRtbF9Db21wb25lbnRdLFxuICAgIFtDbGllbnRfTGFiZWxfTGluaywgXCJDbGllbnRfTGFiZWxfTGlua1wiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbQ2xpZW50X0xhYmVsLCBcIkNsaWVudF9MYWJlbFwiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbRm9ybV9JbnB1dF9BYnN0cmFjdCwgXCJGb3JtX0lucHV0X0Fic3RyYWN0XCIsIEpxaHRtbF9Db21wb25lbnRdLFxuICAgIFtUZXh0X0lucHV0LCBcIlRleHRfSW5wdXRcIiwgRm9ybV9JbnB1dF9BYnN0cmFjdF0sXG4gICAgW0NoZWNrYm94X0lucHV0LCBcIkNoZWNrYm94X0lucHV0XCIsIEZvcm1fSW5wdXRfQWJzdHJhY3RdLFxuICAgIFtXeXNpd3lnX0lucHV0LCBcIld5c2l3eWdfSW5wdXRcIiwgRm9ybV9JbnB1dF9BYnN0cmFjdF0sXG4gICAgW1NlbGVjdF9JbnB1dCwgXCJTZWxlY3RfSW5wdXRcIiwgRm9ybV9JbnB1dF9BYnN0cmFjdF0sXG4gICAgW0FqYXhfU2VsZWN0X0lucHV0LCBcIkFqYXhfU2VsZWN0X0lucHV0XCIsIFNlbGVjdF9JbnB1dF0sXG4gICAgW0N1cnJlbmN5X0lucHV0LCBcIkN1cnJlbmN5X0lucHV0XCIsIFRleHRfSW5wdXRdLFxuICAgIFtQaG9uZV9UZXh0X0lucHV0LCBcIlBob25lX1RleHRfSW5wdXRcIiwgVGV4dF9JbnB1dF0sXG4gICAgW1N0YXRlX1NlbGVjdF9JbnB1dCwgXCJTdGF0ZV9TZWxlY3RfSW5wdXRcIiwgQWpheF9TZWxlY3RfSW5wdXRdLFxuICAgIFtDb3VudHJ5X1NlbGVjdF9JbnB1dCwgXCJDb3VudHJ5X1NlbGVjdF9JbnB1dFwiLCBBamF4X1NlbGVjdF9JbnB1dF0sXG4gICAgW1Byb2ZpbGVfUGhvdG9fSW5wdXQsIFwiUHJvZmlsZV9QaG90b19JbnB1dFwiLCBGb3JtX0lucHV0X0Fic3RyYWN0XSxcbiAgICBbUnN4X1RhYnMsIFwiUnN4X1RhYnNcIiwgSnFodG1sX0NvbXBvbmVudF0sXG4gICAgW1JzeF9UYWIsIFwiUnN4X1RhYlwiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbUnN4X0Zvcm0sIFwiUnN4X0Zvcm1cIiwgSnFodG1sX0NvbXBvbmVudF0sXG4gICAgW1Bpbl9WZXJpZmljYXRpb25fRm9ybSwgXCJQaW5fVmVyaWZpY2F0aW9uX0Zvcm1cIiwgUnN4X0Zvcm1dLFxuICAgIFtGb3JtX0ZpZWxkX0Fic3RyYWN0LCBcIkZvcm1fRmllbGRfQWJzdHJhY3RcIiwgSnFodG1sX0NvbXBvbmVudF0sXG4gICAgW0Zvcm1fRmllbGQsIFwiRm9ybV9GaWVsZFwiLCBGb3JtX0ZpZWxkX0Fic3RyYWN0XSxcbiAgICBbRm9ybV9IaWRkZW5fRmllbGQsIFwiRm9ybV9IaWRkZW5fRmllbGRcIiwgRm9ybV9GaWVsZF9BYnN0cmFjdF0sXG4gICAgW0Zyb250ZW5kX0Rhc2hib2FyZCwgXCJGcm9udGVuZF9EYXNoYm9hcmRcIiwgbnVsbF0sXG4gICAgW0NsaWVudHNfRGF0YUdyaWQsIFwiQ2xpZW50c19EYXRhR3JpZFwiLCBEYXRhR3JpZF9BYnN0cmFjdF0sXG4gICAgW0Zyb250ZW5kX0NsaWVudHNfRWRpdCwgXCJGcm9udGVuZF9DbGllbnRzX0VkaXRcIiwgbnVsbF0sXG4gICAgW0Zyb250ZW5kX0NsaWVudHNfVmlldywgXCJGcm9udGVuZF9DbGllbnRzX1ZpZXdcIiwgbnVsbF0sXG4gICAgW0Zyb250ZW5kX0NsaWVudHMsIFwiRnJvbnRlbmRfQ2xpZW50c1wiLCBudWxsXSxcbiAgICBbRnJvbnRlbmRfU2V0dGluZ3NfVGVhbSwgXCJGcm9udGVuZF9TZXR0aW5nc19UZWFtXCIsIG51bGxdLFxuICAgIFtGcm9udGVuZF9TZXR0aW5nc19Ob3RpZmljYXRpb25zLCBcIkZyb250ZW5kX1NldHRpbmdzX05vdGlmaWNhdGlvbnNcIiwgbnVsbF0sXG4gICAgW0Zyb250ZW5kX1NldHRpbmdzX0JpbGxpbmcsIFwiRnJvbnRlbmRfU2V0dGluZ3NfQmlsbGluZ1wiLCBudWxsXSxcbiAgICBbRnJvbnRlbmRfU2V0dGluZ3NfSW1wb3J0LCBcIkZyb250ZW5kX1NldHRpbmdzX0ltcG9ydFwiLCBudWxsXSxcbiAgICBbRnJvbnRlbmRfU2V0dGluZ3NfQXBpLCBcIkZyb250ZW5kX1NldHRpbmdzX0FwaVwiLCBudWxsXSxcbiAgICBbRnJvbnRlbmRfU2V0dGluZ3NfVGVtcGxhdGVzLCBcIkZyb250ZW5kX1NldHRpbmdzX1RlbXBsYXRlc1wiLCBudWxsXSxcbiAgICBbRnJvbnRlbmRfU2V0dGluZ3NfQXVkaXQsIFwiRnJvbnRlbmRfU2V0dGluZ3NfQXVkaXRcIiwgbnVsbF0sXG4gICAgW0Zyb250ZW5kX1NldHRpbmdzX1Byb2ZpbGVfRGlzcGxheSwgXCJGcm9udGVuZF9TZXR0aW5nc19Qcm9maWxlX0Rpc3BsYXlcIiwgbnVsbF0sXG4gICAgW0Zyb250ZW5kX1NldHRpbmdzX1VzZXJfU2V0dGluZ3MsIFwiRnJvbnRlbmRfU2V0dGluZ3NfVXNlcl9TZXR0aW5nc1wiLCBudWxsXSxcbiAgICBbRnJvbnRlbmRfU2V0dGluZ3NfUGFzc3dvcmRfU2VjdXJpdHksIFwiRnJvbnRlbmRfU2V0dGluZ3NfUGFzc3dvcmRfU2VjdXJpdHlcIiwgbnVsbF0sXG4gICAgW0Zyb250ZW5kX1NldHRpbmdzX0FwaV9LZXlzLCBcIkZyb250ZW5kX1NldHRpbmdzX0FwaV9LZXlzXCIsIG51bGxdLFxuICAgIFtVc2Vyc19EYXRhR3JpZCwgXCJVc2Vyc19EYXRhR3JpZFwiLCBEYXRhR3JpZF9BYnN0cmFjdF0sXG4gICAgW0FkZF9Vc2VyX0Zvcm0sIFwiQWRkX1VzZXJfRm9ybVwiLCBKcWh0bWxfQ29tcG9uZW50XSxcbiAgICBbQWRkX1VzZXJfTW9kYWwsIFwiQWRkX1VzZXJfTW9kYWxcIiwgTW9kYWxfQWJzdHJhY3RdLFxuICAgIFtTZW5kX1VzZXJfSW52aXRlX01vZGFsLCBcIlNlbmRfVXNlcl9JbnZpdGVfTW9kYWxcIiwgTW9kYWxfQWJzdHJhY3RdLFxuICAgIFtGcm9udGVuZF9TZXR0aW5nc19Vc2VyX01hbmFnZW1lbnQsIFwiRnJvbnRlbmRfU2V0dGluZ3NfVXNlcl9NYW5hZ2VtZW50XCIsIG51bGxdLFxuICAgIFtFZGl0X1VzZXJfTW9kYWwsIFwiRWRpdF9Vc2VyX01vZGFsXCIsIE1vZGFsX0Fic3RyYWN0XSxcbiAgICBbRnJvbnRlbmRfU2V0dGluZ3NfVXNlcl9NYW5hZ2VtZW50X1ZpZXcsIFwiRnJvbnRlbmRfU2V0dGluZ3NfVXNlcl9NYW5hZ2VtZW50X1ZpZXdcIiwgbnVsbF0sXG4gICAgW0Zyb250ZW5kX1NldHRpbmdzX1NpdGVfU2V0dGluZ3MsIFwiRnJvbnRlbmRfU2V0dGluZ3NfU2l0ZV9TZXR0aW5nc1wiLCBudWxsXSxcbiAgICBbRnJvbnRlbmRfU2V0dGluZ3MsIFwiRnJvbnRlbmRfU2V0dGluZ3NcIiwgbnVsbF0sXG4gICAgW0NvbnRhY3RzX0RhdGFHcmlkLCBcIkNvbnRhY3RzX0RhdGFHcmlkXCIsIERhdGFHcmlkX0Fic3RyYWN0XSxcbiAgICBbRGF0YV9UYWJsZSwgXCJEYXRhX1RhYmxlXCIsIEpxaHRtbF9Db21wb25lbnRdLFxuICAgIFtDbGllbnRfU2VsZWN0b3JfSW5wdXQsIFwiQ2xpZW50X1NlbGVjdG9yX0lucHV0XCIsIEFqYXhfU2VsZWN0X0lucHV0XSxcbiAgICBbRnJvbnRlbmRfQ29udGFjdHNfRWRpdCwgXCJGcm9udGVuZF9Db250YWN0c19FZGl0XCIsIG51bGxdLFxuICAgIFtGcm9udGVuZF9Db250YWN0c19WaWV3LCBcIkZyb250ZW5kX0NvbnRhY3RzX1ZpZXdcIiwgbnVsbF0sXG4gICAgW0Zyb250ZW5kX0NvbnRhY3RzLCBcIkZyb250ZW5kX0NvbnRhY3RzXCIsIG51bGxdLFxuICAgIFtQcm9qZWN0c19EYXRhR3JpZCwgXCJQcm9qZWN0c19EYXRhR3JpZFwiLCBEYXRhR3JpZF9BYnN0cmFjdF0sXG4gICAgW0Zyb250ZW5kX1Byb2plY3RzX0VkaXQsIFwiRnJvbnRlbmRfUHJvamVjdHNfRWRpdFwiLCBudWxsXSxcbiAgICBbRnJvbnRlbmRfUHJvamVjdHNfTGlzdCwgXCJGcm9udGVuZF9Qcm9qZWN0c19MaXN0XCIsIG51bGxdLFxuICAgIFtGcm9udGVuZF9Qcm9qZWN0c19WaWV3LCBcIkZyb250ZW5kX1Byb2plY3RzX1ZpZXdcIiwgbnVsbF0sXG4gICAgW0Zyb250ZW5kX1Byb2plY3RzX0FkZCwgXCJGcm9udGVuZF9Qcm9qZWN0c19BZGRcIiwgbnVsbF0sXG4gICAgW0Zyb250ZW5kX1Byb2plY3RzLCBcIkZyb250ZW5kX1Byb2plY3RzXCIsIG51bGxdLFxuICAgIFtGcm9udGVuZF9UYXNrcywgXCJGcm9udGVuZF9UYXNrc1wiLCBudWxsXSxcbiAgICBbRnJvbnRlbmRfVGFza3NfVmlldywgXCJGcm9udGVuZF9UYXNrc19WaWV3XCIsIG51bGxdLFxuICAgIFtGcm9udGVuZF9UYXNrc19BZGQsIFwiRnJvbnRlbmRfVGFza3NfQWRkXCIsIG51bGxdLFxuICAgIFtGcm9udGVuZF9DYWxlbmRhciwgXCJGcm9udGVuZF9DYWxlbmRhclwiLCBudWxsXSxcbiAgICBbRnJvbnRlbmRfQ2FsZW5kYXJfRXZlbnQsIFwiRnJvbnRlbmRfQ2FsZW5kYXJfRXZlbnRcIiwgbnVsbF0sXG4gICAgW0Zyb250ZW5kX0ludm9pY2VzLCBcIkZyb250ZW5kX0ludm9pY2VzXCIsIG51bGxdLFxuICAgIFtGcm9udGVuZF9JbnZvaWNlc19WaWV3LCBcIkZyb250ZW5kX0ludm9pY2VzX1ZpZXdcIiwgbnVsbF0sXG4gICAgW0Zyb250ZW5kX0ludm9pY2VzX0FkZCwgXCJGcm9udGVuZF9JbnZvaWNlc19BZGRcIiwgbnVsbF0sXG4gICAgW0Zyb250ZW5kX1JlcG9ydHMsIFwiRnJvbnRlbmRfUmVwb3J0c1wiLCBudWxsXSxcbiAgICBbRnJvbnRlbmRfUmVwb3J0c19SZXZlbnVlLCBcIkZyb250ZW5kX1JlcG9ydHNfUmV2ZW51ZVwiLCBudWxsXSxcbiAgICBbRnJvbnRlbmRfUmVwb3J0c19DbGllbnRzLCBcIkZyb250ZW5kX1JlcG9ydHNfQ2xpZW50c1wiLCBudWxsXSxcbiAgICBbRnJvbnRlbmRfUmVwb3J0c19Qcm9qZWN0cywgXCJGcm9udGVuZF9SZXBvcnRzX1Byb2plY3RzXCIsIG51bGxdLFxuICAgIFtGcm9udGVuZF9SZXBvcnRzX1RpbWUsIFwiRnJvbnRlbmRfUmVwb3J0c19UaW1lXCIsIG51bGxdLFxuICAgIFtGcm9udGVuZF9BY2NvdW50LCBcIkZyb250ZW5kX0FjY291bnRcIiwgbnVsbF1cbl0pO1xuXG4iLCIvLyBSU1ggUm91dGUgRGVmaW5pdGlvbnMgLSBHZW5lcmF0ZWQgYnkgQnVuZGxlQ29tcGlsZXJcbi8vIFByb3ZpZGVzIHJvdXRlIHBhdHRlcm5zIGZvciB0eXBlLXNhZmUgVVJMIGdlbmVyYXRpb25cblJzeC5fZGVmaW5lX3JvdXRlcyh7XG4gICAgXCJGcm9udGVuZF9EYXNoYm9hcmRfQ29udHJvbGxlclwiOiB7XG4gICAgICAgIFwiaW5kZXhcIjogXCIvZGFzaGJvYXJkXCJcbiAgICB9LFxuICAgIFwiRnJvbnRlbmRfQ2xpZW50c19Db250cm9sbGVyXCI6IHtcbiAgICAgICAgXCJpbmRleFwiOiBcIi9jbGllbnRzXCIsXG4gICAgICAgIFwidmlld1wiOiBcIi9jbGllbnRzL3ZpZXcvOmlkXCIsXG4gICAgICAgIFwiYWRkXCI6IFwiL2NsaWVudHMvYWRkXCIsXG4gICAgICAgIFwiZWRpdFwiOiBcIi9jbGllbnRzL2VkaXQvOmlkXCJcbiAgICB9LFxuICAgIFwiRnJvbnRlbmRfU2V0dGluZ3NfVGVhbV9Db250cm9sbGVyXCI6IHtcbiAgICAgICAgXCJpbmRleFwiOiBcIi9mcm9udGVuZC9zZXR0aW5ncy90ZWFtXCJcbiAgICB9LFxuICAgIFwiRnJvbnRlbmRfU2V0dGluZ3NfTm90aWZpY2F0aW9uc19Db250cm9sbGVyXCI6IHtcbiAgICAgICAgXCJpbmRleFwiOiBcIi9mcm9udGVuZC9zZXR0aW5ncy9ub3RpZmljYXRpb25zXCJcbiAgICB9LFxuICAgIFwiRnJvbnRlbmRfU2V0dGluZ3NfQmlsbGluZ19Db250cm9sbGVyXCI6IHtcbiAgICAgICAgXCJpbmRleFwiOiBcIi9mcm9udGVuZC9zZXR0aW5ncy9iaWxsaW5nXCJcbiAgICB9LFxuICAgIFwiRnJvbnRlbmRfU2V0dGluZ3NfSW1wb3J0X0NvbnRyb2xsZXJcIjoge1xuICAgICAgICBcImluZGV4XCI6IFwiL2Zyb250ZW5kL3NldHRpbmdzL2ltcG9ydFwiXG4gICAgfSxcbiAgICBcIkZyb250ZW5kX1NldHRpbmdzX0FwaV9Db250cm9sbGVyXCI6IHtcbiAgICAgICAgXCJpbmRleFwiOiBcIi9mcm9udGVuZC9zZXR0aW5ncy9hcGlcIlxuICAgIH0sXG4gICAgXCJGcm9udGVuZF9TZXR0aW5nc19UZW1wbGF0ZXNfQ29udHJvbGxlclwiOiB7XG4gICAgICAgIFwiaW5kZXhcIjogXCIvZnJvbnRlbmQvc2V0dGluZ3MvdGVtcGxhdGVzXCJcbiAgICB9LFxuICAgIFwiRnJvbnRlbmRfU2V0dGluZ3NfQXVkaXRfQ29udHJvbGxlclwiOiB7XG4gICAgICAgIFwiaW5kZXhcIjogXCIvZnJvbnRlbmQvc2V0dGluZ3MvYXVkaXRcIlxuICAgIH0sXG4gICAgXCJGcm9udGVuZF9TZXR0aW5nc19BY2NvdW50X0NvbnRyb2xsZXJcIjoge1xuICAgICAgICBcImluZGV4XCI6IFwiL2Zyb250ZW5kL3NldHRpbmdzL2FjY291bnRcIlxuICAgIH0sXG4gICAgXCJGcm9udGVuZF9TZXR0aW5nc19HZW5lcmFsX0NvbnRyb2xsZXJcIjoge1xuICAgICAgICBcImluZGV4XCI6IFwiL2Zyb250ZW5kL3NldHRpbmdzL2dlbmVyYWxcIlxuICAgIH0sXG4gICAgXCJGcm9udGVuZF9TZXR0aW5nc19Qcm9maWxlX0NvbnRyb2xsZXJcIjoge1xuICAgICAgICBcImluZGV4XCI6IFwiL2Zyb250ZW5kL3NldHRpbmdzL3Byb2ZpbGVcIlxuICAgIH0sXG4gICAgXCJGcm9udGVuZF9TZXR0aW5nc19Qcm9maWxlX0Rpc3BsYXlfQ29udHJvbGxlclwiOiB7XG4gICAgICAgIFwiaW5kZXhcIjogXCIvZnJvbnRlbmQvc2V0dGluZ3MvcHJvZmlsZV9kaXNwbGF5XCJcbiAgICB9LFxuICAgIFwiRnJvbnRlbmRfU2V0dGluZ3NfUHJvZmlsZV9FZGl0X0NvbnRyb2xsZXJcIjoge1xuICAgICAgICBcImluZGV4XCI6IFwiL2Zyb250ZW5kL3NldHRpbmdzL3Byb2ZpbGVfZWRpdFwiXG4gICAgfSxcbiAgICBcIkZyb250ZW5kX1NldHRpbmdzX1VzZXJfU2V0dGluZ3NfQ29udHJvbGxlclwiOiB7XG4gICAgICAgIFwiaW5kZXhcIjogXCIvZnJvbnRlbmQvc2V0dGluZ3MvdXNlcl9zZXR0aW5nc1wiXG4gICAgfSxcbiAgICBcIkZyb250ZW5kX1NldHRpbmdzX1Bhc3N3b3JkX1NlY3VyaXR5X0NvbnRyb2xsZXJcIjoge1xuICAgICAgICBcImluZGV4XCI6IFwiL2Zyb250ZW5kL3NldHRpbmdzL3Bhc3N3b3JkX3NlY3VyaXR5XCJcbiAgICB9LFxuICAgIFwiRnJvbnRlbmRfU2V0dGluZ3NfQXBpX0tleXNfQ29udHJvbGxlclwiOiB7XG4gICAgICAgIFwiaW5kZXhcIjogXCIvZnJvbnRlbmQvc2V0dGluZ3MvYXBpX2tleXNcIlxuICAgIH0sXG4gICAgXCJGcm9udGVuZF9TZXR0aW5nc19Vc2VyX01hbmFnZW1lbnRfQ29udHJvbGxlclwiOiB7XG4gICAgICAgIFwiaW5kZXhcIjogXCIvZnJvbnRlbmQvc2V0dGluZ3MvdXNlcl9tYW5hZ2VtZW50XCIsXG4gICAgICAgIFwidmlld1wiOiBcIi9mcm9udGVuZC9zZXR0aW5ncy91c2VyX21hbmFnZW1lbnQvOmlkXCJcbiAgICB9LFxuICAgIFwiRnJvbnRlbmRfU2V0dGluZ3NfU2l0ZV9TZXR0aW5nc19Db250cm9sbGVyXCI6IHtcbiAgICAgICAgXCJpbmRleFwiOiBcIi9mcm9udGVuZC9zZXR0aW5ncy9zaXRlX3NldHRpbmdzXCJcbiAgICB9LFxuICAgIFwiRnJvbnRlbmRfQ29udGFjdHNfQ29udHJvbGxlclwiOiB7XG4gICAgICAgIFwiaW5kZXhcIjogXCIvY29udGFjdHNcIixcbiAgICAgICAgXCJ2aWV3XCI6IFwiL2NvbnRhY3RzL3ZpZXcvOmlkXCIsXG4gICAgICAgIFwiYWRkXCI6IFwiL2NvbnRhY3RzL2FkZFwiLFxuICAgICAgICBcImVkaXRcIjogXCIvY29udGFjdHMvZWRpdC86aWRcIlxuICAgIH0sXG4gICAgXCJGcm9udGVuZF9Qcm9qZWN0c19Db250cm9sbGVyXCI6IHtcbiAgICAgICAgXCJpbmRleFwiOiBcIi9wcm9qZWN0c1wiLFxuICAgICAgICBcInZpZXdcIjogXCIvcHJvamVjdHMvdmlldy86aWRcIixcbiAgICAgICAgXCJhZGRcIjogXCIvcHJvamVjdHMvYWRkXCIsXG4gICAgICAgIFwiZWRpdFwiOiBcIi9wcm9qZWN0cy9lZGl0LzppZFwiXG4gICAgfSxcbiAgICBcIkZyb250ZW5kX1Rhc2tzX0NvbnRyb2xsZXJcIjoge1xuICAgICAgICBcImluZGV4XCI6IFwiL3Rhc2tzXCJcbiAgICB9LFxuICAgIFwiRnJvbnRlbmRfVGFza3NfVmlld19Db250cm9sbGVyXCI6IHtcbiAgICAgICAgXCJpbmRleFwiOiBcIi90YXNrcy92aWV3XCJcbiAgICB9LFxuICAgIFwiRnJvbnRlbmRfVGFza3NfQWRkX0NvbnRyb2xsZXJcIjoge1xuICAgICAgICBcImluZGV4XCI6IFwiL3Rhc2tzL2FkZFwiXG4gICAgfSxcbiAgICBcIkZyb250ZW5kX0NhbGVuZGFyX0NvbnRyb2xsZXJcIjoge1xuICAgICAgICBcImluZGV4XCI6IFwiL2NhbGVuZGFyXCJcbiAgICB9LFxuICAgIFwiRnJvbnRlbmRfQ2FsZW5kYXJfRXZlbnRfQ29udHJvbGxlclwiOiB7XG4gICAgICAgIFwiaW5kZXhcIjogXCIvY2FsZW5kYXIvZXZlbnRcIlxuICAgIH0sXG4gICAgXCJGcm9udGVuZF9JbnZvaWNlc19Db250cm9sbGVyXCI6IHtcbiAgICAgICAgXCJpbmRleFwiOiBcIi9pbnZvaWNlc1wiXG4gICAgfSxcbiAgICBcIkZyb250ZW5kX0ludm9pY2VzX1ZpZXdfQ29udHJvbGxlclwiOiB7XG4gICAgICAgIFwiaW5kZXhcIjogXCIvaW52b2ljZXMvdmlld1wiXG4gICAgfSxcbiAgICBcIkZyb250ZW5kX0ludm9pY2VzX0FkZF9Db250cm9sbGVyXCI6IHtcbiAgICAgICAgXCJpbmRleFwiOiBcIi9pbnZvaWNlcy9hZGRcIlxuICAgIH0sXG4gICAgXCJGcm9udGVuZF9SZXBvcnRzX0NsaWVudHNfQ29udHJvbGxlclwiOiB7XG4gICAgICAgIFwiaW5kZXhcIjogXCIvcmVwb3J0cy9jbGllbnRzXCJcbiAgICB9LFxuICAgIFwiRnJvbnRlbmRfUmVwb3J0c19Db250cm9sbGVyXCI6IHtcbiAgICAgICAgXCJpbmRleFwiOiBcIi9yZXBvcnRzXCJcbiAgICB9LFxuICAgIFwiRnJvbnRlbmRfUmVwb3J0c19Qcm9qZWN0c19Db250cm9sbGVyXCI6IHtcbiAgICAgICAgXCJpbmRleFwiOiBcIi9yZXBvcnRzL3Byb2plY3RzXCJcbiAgICB9LFxuICAgIFwiRnJvbnRlbmRfUmVwb3J0c19SZXZlbnVlX0NvbnRyb2xsZXJcIjoge1xuICAgICAgICBcImluZGV4XCI6IFwiL3JlcG9ydHMvcmV2ZW51ZVwiXG4gICAgfSxcbiAgICBcIkZyb250ZW5kX1JlcG9ydHNfVGltZV9Db250cm9sbGVyXCI6IHtcbiAgICAgICAgXCJpbmRleFwiOiBcIi9yZXBvcnRzL3RpbWVcIlxuICAgIH0sXG4gICAgXCJGcm9udGVuZF9BY2NvdW50X0NvbnRyb2xsZXJcIjoge1xuICAgICAgICBcImluZGV4XCI6IFwiL2Zyb250ZW5kL2FjY291bnRcIlxuICAgIH1cbn0pO1xuIiwiJChkb2N1bWVudCkucmVhZHkoYXN5bmMgZnVuY3Rpb24oKSB7XG50cnkge1xuY29uc29sZV9kZWJ1ZygnUlNYX0lOSVQnLCAnRG9jdW1lbnQgcmVhZHksIHN0YXJ0aW5nIFJzeC5fcnN4X2NvcmVfYm9vdCcpO1xuYXdhaXQgUnN4Ll9yc3hfY29yZV9ib290KCk7XG5jb25zb2xlX2RlYnVnKCdSU1hfSU5JVCcsICdJbml0aWFsaXphdGlvbiBjb21wbGV0ZScpO1xufSBjYXRjaCAoZXJyb3IpIHtcbmNvbnNvbGUuZXJyb3IoJ1tSU1hfSU5JVF0gSW5pdGlhbGl6YXRpb24gZmFpbGVkOicsIGVycm9yKTtcbmNvbnNvbGUuZXJyb3IoJ1tSU1hfSU5JVF0gU3RhY2s6JywgZXJyb3Iuc3RhY2spO1xudGhyb3cgZXJyb3I7XG59XG59KTsiXSwic291cmNlUm9vdCI6IiJ9
|