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>
8302 lines
971 KiB
JavaScript
Executable File
8302 lines
971 KiB
JavaScript
Executable File
/* === storage/rsx-tmp/bundle_config_Dev_Bundle.js === */
|
||
window.rsxapp = window.rsxapp || {};
|
||
window.rsxapp.module_paths = {"bootstrap5_src":"rsx\/theme\/vendor\/bootstrap5\/scss"};
|
||
|
||
|
||
/* === storage/rsx-build/bundles/npm_Dev_Bundle_6459e8ed0f60bda4f121420766012d53.js === */
|
||
(() => {
|
||
// node_modules/@jqhtml/core/dist/index.js
|
||
var LifecycleManager = class _LifecycleManager {
|
||
static get_instance() {
|
||
if (!_LifecycleManager.instance) {
|
||
_LifecycleManager.instance = new _LifecycleManager();
|
||
}
|
||
return _LifecycleManager.instance;
|
||
}
|
||
constructor() {
|
||
this.active_components = /* @__PURE__ */ new Set();
|
||
}
|
||
/**
|
||
* Boot a component - run its full lifecycle
|
||
* Called when component is created
|
||
*/
|
||
async boot_component(component) {
|
||
this.active_components.add(component);
|
||
try {
|
||
await component.create();
|
||
if (component._stopped)
|
||
return;
|
||
component.trigger("create");
|
||
let render_id = component._render();
|
||
if (component._stopped)
|
||
return;
|
||
await component.load();
|
||
if (component._stopped)
|
||
return;
|
||
if (component.should_rerender()) {
|
||
render_id = component._render();
|
||
if (component._stopped)
|
||
return;
|
||
}
|
||
if (component._render_count !== render_id) {
|
||
return;
|
||
}
|
||
await component.ready();
|
||
if (component._stopped)
|
||
return;
|
||
await component.trigger("ready");
|
||
} catch (error) {
|
||
console.error(`Error booting component ${component.component_name()}:`, error);
|
||
throw error;
|
||
}
|
||
}
|
||
/**
|
||
* Unregister a component (called on destroy)
|
||
*/
|
||
unregister_component(component) {
|
||
this.active_components.delete(component);
|
||
}
|
||
/**
|
||
* Wait for all active components to reach ready state
|
||
*/
|
||
async wait_for_ready() {
|
||
const ready_promises = [];
|
||
for (const component of this.active_components) {
|
||
if (component._ready_state < 4) {
|
||
ready_promises.push(new Promise((resolve) => {
|
||
component.on("ready", () => resolve());
|
||
}));
|
||
}
|
||
}
|
||
await Promise.all(ready_promises);
|
||
}
|
||
};
|
||
var component_classes = /* @__PURE__ */ new Map();
|
||
var component_templates = /* @__PURE__ */ new Map();
|
||
var warned_components = /* @__PURE__ */ new Set();
|
||
var DEFAULT_TEMPLATE = {
|
||
name: "Component",
|
||
// Default name
|
||
tag: "div",
|
||
render: function(data, args, content) {
|
||
const _output = [];
|
||
if (args._inner_html) {
|
||
_output.push(args._inner_html);
|
||
return [_output, this];
|
||
}
|
||
if (content && typeof content === "function") {
|
||
const result = content(this);
|
||
if (Array.isArray(result) && result.length === 2) {
|
||
_output.push(...result[0]);
|
||
} else if (typeof result === "string") {
|
||
_output.push(result);
|
||
}
|
||
}
|
||
return [_output, this];
|
||
}
|
||
};
|
||
function register_component(nameOrClass, component_class, template) {
|
||
if (typeof nameOrClass === "string") {
|
||
const name = nameOrClass;
|
||
if (!component_class) {
|
||
throw new Error("Component class is required when registering by name");
|
||
}
|
||
if (!/^[A-Z]/.test(name)) {
|
||
throw new Error(`Component name '${name}' must start with a capital letter. Convention is First_Letter_With_Underscores.`);
|
||
}
|
||
component_classes.set(name, component_class);
|
||
if (template) {
|
||
if (template.name !== name) {
|
||
throw new Error(`Template name '${template.name}' must match component name '${name}'`);
|
||
}
|
||
register_template(template);
|
||
}
|
||
} else {
|
||
const component_class2 = nameOrClass;
|
||
const name = component_class2.name;
|
||
if (!name || name === "Component") {
|
||
throw new Error("Component class must have a name when registering without explicit name");
|
||
}
|
||
component_classes.set(name, component_class2);
|
||
}
|
||
}
|
||
function get_component_class(name) {
|
||
const directClass = component_classes.get(name);
|
||
if (directClass) {
|
||
return directClass;
|
||
}
|
||
const template = component_templates.get(name);
|
||
if (template && template.extends) {
|
||
const visited = /* @__PURE__ */ new Set([name]);
|
||
let currentTemplateName = template.extends;
|
||
while (currentTemplateName && !visited.has(currentTemplateName)) {
|
||
visited.add(currentTemplateName);
|
||
const parentClass = component_classes.get(currentTemplateName);
|
||
if (parentClass) {
|
||
if (window.jqhtml?.debug?.enabled) {
|
||
console.log(`[JQHTML] Component '${name}' using class from parent '${currentTemplateName}' via extends chain`);
|
||
}
|
||
return parentClass;
|
||
}
|
||
const parentTemplate = component_templates.get(currentTemplateName);
|
||
if (parentTemplate && parentTemplate.extends) {
|
||
currentTemplateName = parentTemplate.extends;
|
||
} else {
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
return void 0;
|
||
}
|
||
function register_template(template_def) {
|
||
const name = template_def.name;
|
||
if (!name) {
|
||
throw new Error("Template must have a name property");
|
||
}
|
||
if (!/^[A-Z]/.test(name)) {
|
||
throw new Error(`Template name '${name}' must start with a capital letter. Convention is First_Letter_With_Underscores.`);
|
||
}
|
||
if (component_templates.has(name)) {
|
||
console.warn(`[JQHTML] Template '${name}' already registered, skipping duplicate registration`);
|
||
return false;
|
||
}
|
||
component_templates.set(name, template_def);
|
||
if (window.jqhtml?.debug?.enabled) {
|
||
console.log(`[JQHTML] Successfully registered template: ${name}`);
|
||
}
|
||
const component_class = component_classes.get(name);
|
||
if (component_class) {
|
||
component_class._jqhtml_metadata = {
|
||
tag: template_def.tag,
|
||
defaultAttributes: template_def.defaultAttributes || {}
|
||
};
|
||
}
|
||
return true;
|
||
}
|
||
function get_template(name) {
|
||
const template = component_templates.get(name);
|
||
if (!template) {
|
||
const component_class = component_classes.get(name);
|
||
if (component_class) {
|
||
const inherited_template = get_template_by_class(component_class);
|
||
if (inherited_template !== DEFAULT_TEMPLATE) {
|
||
if (window.jqhtml?.debug?.enabled) {
|
||
console.log(`[JQHTML] Component '${name}' has no template, using template from prototype chain`);
|
||
}
|
||
return inherited_template;
|
||
}
|
||
if (window.jqhtml?.debug?.enabled && !warned_components.has(name)) {
|
||
warned_components.add(name);
|
||
console.log(`[JQHTML] No template found for class: ${name}, using default div template`);
|
||
}
|
||
} else {
|
||
if (name !== "_Jqhtml_Component" && name !== "Redrawable" && !warned_components.has(name)) {
|
||
warned_components.add(name);
|
||
console.warn(`[JQHTML] Creating ${name} with defaults - no template or class defined`);
|
||
}
|
||
}
|
||
if (window.jqhtml?.debug?.verbose) {
|
||
const registered = Array.from(component_templates.keys());
|
||
console.log(`[JQHTML] Looking for template '${name}' in: [${registered.join(", ")}]`);
|
||
}
|
||
return DEFAULT_TEMPLATE;
|
||
}
|
||
return template;
|
||
}
|
||
function get_template_by_class(component_class) {
|
||
if (component_class.template) {
|
||
return component_class.template;
|
||
}
|
||
let currentClass = component_class;
|
||
while (currentClass && currentClass.name !== "Object") {
|
||
let normalizedName = currentClass.name;
|
||
if (normalizedName === "_Jqhtml_Component" || normalizedName === "_Base_Jqhtml_Component") {
|
||
normalizedName = "Component";
|
||
}
|
||
const template = component_templates.get(normalizedName);
|
||
if (template) {
|
||
return template;
|
||
}
|
||
currentClass = Object.getPrototypeOf(currentClass);
|
||
}
|
||
return DEFAULT_TEMPLATE;
|
||
}
|
||
function create_component(name, element, args = {}) {
|
||
const ComponentClass = get_component_class(name) || Component;
|
||
return new ComponentClass(element, args);
|
||
}
|
||
function has_component(name) {
|
||
return component_classes.has(name);
|
||
}
|
||
function get_component_names() {
|
||
return Array.from(component_classes.keys());
|
||
}
|
||
function get_registered_templates() {
|
||
return Array.from(component_templates.keys());
|
||
}
|
||
function list_components() {
|
||
const result = {};
|
||
for (const name of component_classes.keys()) {
|
||
result[name] = {
|
||
has_class: true,
|
||
has_template: component_templates.has(name)
|
||
};
|
||
}
|
||
for (const name of component_templates.keys()) {
|
||
if (!result[name]) {
|
||
result[name] = {
|
||
has_class: false,
|
||
has_template: true
|
||
};
|
||
}
|
||
}
|
||
return result;
|
||
}
|
||
var _cid_increment = "aa";
|
||
function uid() {
|
||
const current = _cid_increment;
|
||
const chars = _cid_increment.split("");
|
||
let carry = true;
|
||
for (let i = chars.length - 1; i >= 0 && carry; i--) {
|
||
const char = chars[i];
|
||
if (char >= "a" && char < "z") {
|
||
chars[i] = String.fromCharCode(char.charCodeAt(0) + 1);
|
||
carry = false;
|
||
} else if (char === "z") {
|
||
chars[i] = "0";
|
||
carry = false;
|
||
} else if (char >= "0" && char < "9") {
|
||
chars[i] = String.fromCharCode(char.charCodeAt(0) + 1);
|
||
carry = false;
|
||
} else if (char === "9") {
|
||
chars[i] = "a";
|
||
carry = true;
|
||
}
|
||
}
|
||
if (carry) {
|
||
chars.unshift("a");
|
||
}
|
||
if (chars[0] >= "0" && chars[0] <= "9") {
|
||
chars[0] = "a";
|
||
chars.unshift("a");
|
||
}
|
||
_cid_increment = chars.join("");
|
||
return current;
|
||
}
|
||
function process_instructions(instructions, target, context, slots) {
|
||
const html = [];
|
||
const tagElements = {};
|
||
const components = {};
|
||
for (const instruction of instructions) {
|
||
process_instruction_to_html(instruction, html, tagElements, components, context, slots);
|
||
}
|
||
target[0].innerHTML = html.join("");
|
||
for (const [tid, tagData] of Object.entries(tagElements)) {
|
||
const el = target[0].querySelector(`[data-tid="${tid}"]`);
|
||
if (el) {
|
||
const element = $(el);
|
||
el.removeAttribute("data-tid");
|
||
apply_attributes(element, tagData.attrs, context);
|
||
}
|
||
}
|
||
for (const [cid, compData] of Object.entries(components)) {
|
||
const el = target[0].querySelector(`[data-cid="${cid}"]`);
|
||
if (el) {
|
||
const element = $(el);
|
||
el.removeAttribute("data-cid");
|
||
initialize_component(element, compData);
|
||
}
|
||
}
|
||
}
|
||
function process_instruction_to_html(instruction, html, tagElements, components, context, slots) {
|
||
if (typeof instruction === "string") {
|
||
html.push(instruction);
|
||
} else if ("tag" in instruction) {
|
||
process_tag_to_html(instruction, html, tagElements, components, context);
|
||
} else if ("comp" in instruction) {
|
||
process_component_to_html(instruction, html, components, context);
|
||
} else if ("slot" in instruction) {
|
||
process_slot_to_html(instruction, html, tagElements, components, context, slots);
|
||
} else if ("rawtag" in instruction) {
|
||
process_rawtag_to_html(instruction, html);
|
||
}
|
||
}
|
||
function process_tag_to_html(instruction, html, tagElements, components, context) {
|
||
const [tagName, attrs, selfClosing] = instruction.tag;
|
||
const needsTracking = Object.keys(attrs).some((key) => key === "$id" || key.startsWith("$") || key.startsWith("@") || key.startsWith("on") || key.startsWith("data-bind-") || key.startsWith("data-on-"));
|
||
html.push(`<${tagName}`);
|
||
let tid = null;
|
||
if (needsTracking) {
|
||
tid = uid();
|
||
html.push(` data-tid="${tid}"`);
|
||
tagElements[tid] = { attrs, context };
|
||
}
|
||
for (const [key, value] of Object.entries(attrs)) {
|
||
if (!key.startsWith("$") && !key.startsWith("on") && !key.startsWith("@") && !key.startsWith("data-bind-") && !key.startsWith("data-on-") && (typeof value === "string" || typeof value === "number")) {
|
||
if (key === "id" && tid) {
|
||
html.push(` id="${value}:${context._cid}"`);
|
||
} else {
|
||
html.push(` ${key}="${value}"`);
|
||
}
|
||
}
|
||
}
|
||
if (selfClosing) {
|
||
html.push(" />");
|
||
} else {
|
||
html.push(">");
|
||
}
|
||
}
|
||
function process_component_to_html(instruction, html, components, context) {
|
||
const [componentName, props, contentFn] = instruction.comp;
|
||
const cid = uid();
|
||
get_component_class(componentName) || Component;
|
||
const template = get_template(componentName);
|
||
const tagName = props._tag || template.tag || "div";
|
||
html.push(`<${tagName} data-cid="${cid}"`);
|
||
if (props["data-id"]) {
|
||
const baseId = props["data-id"];
|
||
html.push(` id="${props["id"]}" data-id="${baseId}"`);
|
||
} else if (props["id"]) {
|
||
html.push(` id="${props["id"]}"`);
|
||
}
|
||
html.push("></" + tagName + ">");
|
||
components[cid] = {
|
||
name: componentName,
|
||
props,
|
||
contentFn,
|
||
context
|
||
};
|
||
}
|
||
function process_slot_to_html(instruction, html, tagElements, components, context, parentSlots) {
|
||
const [slotName] = instruction.slot;
|
||
if (parentSlots && slotName in parentSlots) {
|
||
const parentSlot = parentSlots[slotName];
|
||
const [, slotProps, contentFn] = parentSlot.slot;
|
||
const [content] = contentFn.call(context, slotProps);
|
||
for (const item of content) {
|
||
process_instruction_to_html(item, html, tagElements, components, context);
|
||
}
|
||
} else if (slotName === "default" && instruction.slot[2]) {
|
||
const [, , defaultFn] = instruction.slot;
|
||
const [content] = defaultFn.call(context, {});
|
||
for (const item of content) {
|
||
process_instruction_to_html(item, html, tagElements, components, context);
|
||
}
|
||
}
|
||
}
|
||
function process_rawtag_to_html(instruction, html) {
|
||
const [tagName, attrs, rawContent] = instruction.rawtag;
|
||
html.push(`<${tagName}`);
|
||
for (const [key, value] of Object.entries(attrs)) {
|
||
if (typeof value === "string" || typeof value === "number") {
|
||
const escaped_value = String(value).replace(/"/g, """);
|
||
html.push(` ${key}="${escaped_value}"`);
|
||
} else if (typeof value === "boolean" && value) {
|
||
html.push(` ${key}`);
|
||
}
|
||
}
|
||
html.push(">");
|
||
const escaped_content = rawContent.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
||
html.push(escaped_content);
|
||
html.push(`</${tagName}>`);
|
||
}
|
||
function apply_attributes(element, attrs, context) {
|
||
for (const [key, value] of Object.entries(attrs)) {
|
||
if (key === "$id" || key === "id") {
|
||
continue;
|
||
} else if (key.startsWith("$")) {
|
||
const dataKey = key.substring(1);
|
||
element.data(dataKey, value);
|
||
context.args[dataKey] = value;
|
||
if (typeof value == "string" || typeof value == "number") {
|
||
const attrValue = typeof value === "string" ? value.trim() : value;
|
||
element.attr(`data-${dataKey}`, attrValue);
|
||
}
|
||
} else if (key.startsWith("data-on-")) {
|
||
const eventName = key.substring(8);
|
||
if (typeof value === "function") {
|
||
element.on(eventName, function(e) {
|
||
value.bind(context)(e, element);
|
||
});
|
||
} else {
|
||
console.warn("(JQHTML) Tried to assign a non function to on event handler " + key);
|
||
}
|
||
} else if (key.startsWith("on")) {
|
||
const eventName = key.substring(2);
|
||
if (typeof value === "function") {
|
||
element.on(eventName, function(e) {
|
||
value.bind(context)(e, element);
|
||
});
|
||
} else {
|
||
console.warn("(JQHTML) Tried to assign a non function to on event handler " + key);
|
||
}
|
||
} else if (key.startsWith("data-")) {
|
||
const attrValue = typeof value === "string" ? value.trim() : value;
|
||
element.attr(key, attrValue);
|
||
const dataKey = key.substring(5);
|
||
element.data(dataKey, value);
|
||
context.args[dataKey] = value;
|
||
} else if (key === "class") {
|
||
const existingClasses = element.attr("class");
|
||
if (window.jqhtml?.debug?.enabled) {
|
||
console.log(`[InstructionProcessor] Merging class attribute:`, {
|
||
existing: existingClasses,
|
||
new: value
|
||
});
|
||
}
|
||
if (!existingClasses) {
|
||
const attrValue = typeof value === "string" ? value.trim() : value;
|
||
element.attr("class", attrValue);
|
||
} else {
|
||
const existing = existingClasses.split(/\s+/).filter((c) => c);
|
||
const newClasses = String(value).split(/\s+/).filter((c) => c);
|
||
for (const newClass of newClasses) {
|
||
if (!existing.includes(newClass)) {
|
||
existing.push(newClass);
|
||
}
|
||
}
|
||
element.attr("class", existing.join(" "));
|
||
}
|
||
if (window.jqhtml?.debug?.enabled) {
|
||
console.log(`[InstructionProcessor] Class after merge:`, element.attr("class"));
|
||
}
|
||
} else if (key === "style") {
|
||
const existingStyle = element.attr("style");
|
||
if (!existingStyle) {
|
||
const attrValue = typeof value === "string" ? value.trim() : value;
|
||
element.attr("style", attrValue);
|
||
} else {
|
||
const styleMap = {};
|
||
existingStyle.split(";").forEach((rule) => {
|
||
const [prop, val] = rule.split(":").map((s) => s.trim());
|
||
if (prop && val) {
|
||
styleMap[prop] = val;
|
||
}
|
||
});
|
||
String(value).split(";").forEach((rule) => {
|
||
const [prop, val] = rule.split(":").map((s) => s.trim());
|
||
if (prop && val) {
|
||
styleMap[prop] = val;
|
||
}
|
||
});
|
||
const mergedStyle = Object.entries(styleMap).map(([prop, val]) => `${prop}: ${val}`).join("; ");
|
||
element.attr("style", mergedStyle);
|
||
}
|
||
} else {
|
||
if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
|
||
const attrValue = typeof value === "string" ? value.trim() : String(value);
|
||
element.attr(key, attrValue);
|
||
} else if (typeof value === "object") {
|
||
console.warn(`(JQHTML) Unexpected value for '${key}' on`, element);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
async function initialize_component(element, compData) {
|
||
const { name, props, contentFn, context } = compData;
|
||
const ComponentClass = get_component_class(name) || Component;
|
||
const invocationAttrs = {};
|
||
for (const [key, value] of Object.entries(props)) {
|
||
if (!key.startsWith("_")) {
|
||
invocationAttrs[key] = value;
|
||
}
|
||
}
|
||
if (window.jqhtml?.debug?.enabled) {
|
||
console.log(`[InstructionProcessor] Applying invocation attributes for ${name}:`, invocationAttrs);
|
||
}
|
||
apply_attributes(element, invocationAttrs, context);
|
||
const options = {};
|
||
if (contentFn) {
|
||
options._innerhtml_function = contentFn;
|
||
}
|
||
if (ComponentClass.name !== name) {
|
||
options._component_name = name;
|
||
}
|
||
const instance = new ComponentClass(element, options);
|
||
instance._instantiator = context;
|
||
await instance.boot();
|
||
}
|
||
function extract_slots(instructions) {
|
||
const slots = {};
|
||
for (const instruction of instructions) {
|
||
if (typeof instruction === "object" && "slot" in instruction) {
|
||
const [name] = instruction.slot;
|
||
slots[name] = instruction;
|
||
}
|
||
}
|
||
return slots;
|
||
}
|
||
var performanceMetrics = /* @__PURE__ */ new Map();
|
||
function devWarn(message) {
|
||
if (typeof window !== "undefined" && window.JQHTML_SUPPRESS_WARNINGS) {
|
||
return;
|
||
}
|
||
if (typeof process !== "undefined" && process.env && false) {
|
||
return;
|
||
}
|
||
console.warn(`[JQHTML Dev Warning] ${message}`);
|
||
}
|
||
function getJqhtml$1() {
|
||
if (typeof window !== "undefined" && window.jqhtml) {
|
||
return window.jqhtml;
|
||
}
|
||
if (typeof globalThis !== "undefined" && globalThis.jqhtml) {
|
||
return globalThis.jqhtml;
|
||
}
|
||
throw new Error("FATAL: window.jqhtml is not defined. The JQHTML runtime must be loaded before using debug features. Import and initialize @jqhtml/core before attempting to use debug functionality.");
|
||
}
|
||
function flashComponent(component, eventType) {
|
||
const jqhtml2 = getJqhtml$1();
|
||
if (!jqhtml2?.debug?.flashComponents)
|
||
return;
|
||
const duration = jqhtml2.debug.flashDuration || 500;
|
||
const colors = jqhtml2.debug.flashColors || {};
|
||
const color = colors[eventType] || (eventType === "create" ? "#3498db" : eventType === "render" ? "#27ae60" : "#9b59b6");
|
||
const originalBorder = component.$.css("border");
|
||
component.$.css({
|
||
"border": `2px solid ${color}`,
|
||
"transition": `border ${duration}ms ease-out`
|
||
});
|
||
setTimeout(() => {
|
||
component.$.css("border", originalBorder || "");
|
||
}, duration);
|
||
}
|
||
function logLifecycle(component, phase, status) {
|
||
const jqhtml2 = getJqhtml$1();
|
||
if (!jqhtml2?.debug)
|
||
return;
|
||
const shouldLog = jqhtml2.debug.logFullLifecycle || jqhtml2.debug.logCreationReady && (phase === "create" || phase === "ready");
|
||
if (!shouldLog)
|
||
return;
|
||
const componentName = component.constructor.name;
|
||
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
||
const prefix = `[JQHTML ${timestamp}]`;
|
||
if (status === "start") {
|
||
console.log(`${prefix} ${componentName}#${component._cid} \u2192 ${phase} starting...`);
|
||
if (jqhtml2.debug.profilePerformance) {
|
||
performanceMetrics.set(`${component._cid}_${phase}`, Date.now());
|
||
}
|
||
} else {
|
||
let message = `${prefix} ${componentName}#${component._cid} \u2713 ${phase} complete`;
|
||
if (jqhtml2.debug.profilePerformance) {
|
||
const startTime = performanceMetrics.get(`${component._cid}_${phase}`);
|
||
if (startTime) {
|
||
const duration = Date.now() - startTime;
|
||
message += ` (${duration}ms)`;
|
||
if (phase === "render" && jqhtml2.debug.highlightSlowRenders && duration > jqhtml2.debug.highlightSlowRenders) {
|
||
console.warn(`${prefix} SLOW RENDER: ${componentName}#${component._cid} took ${duration}ms`);
|
||
component.$.css("outline", "2px dashed red");
|
||
}
|
||
}
|
||
}
|
||
console.log(message);
|
||
if (jqhtml2.debug.flashComponents && (phase === "create" || phase === "render" || phase === "ready")) {
|
||
flashComponent(component, phase);
|
||
}
|
||
}
|
||
if (jqhtml2.debug.showComponentTree) {
|
||
updateComponentTree();
|
||
}
|
||
}
|
||
function applyDebugDelay(phase) {
|
||
const jqhtml2 = getJqhtml$1();
|
||
if (!jqhtml2?.debug)
|
||
return;
|
||
let delayMs = 0;
|
||
switch (phase) {
|
||
case "component":
|
||
delayMs = jqhtml2.debug.delayAfterComponent || 0;
|
||
break;
|
||
case "render":
|
||
delayMs = jqhtml2.debug.delayAfterRender || 0;
|
||
break;
|
||
case "rerender":
|
||
delayMs = jqhtml2.debug.delayAfterRerender || 0;
|
||
break;
|
||
}
|
||
if (delayMs > 0) {
|
||
console.log(`[JQHTML Debug] Applying ${delayMs}ms delay after ${phase}`);
|
||
}
|
||
}
|
||
function updateComponentTree() {
|
||
console.log("[JQHTML Tree] Component hierarchy updated");
|
||
}
|
||
var Component = class _Jqhtml_Component {
|
||
constructor(element, args = {}) {
|
||
this.data = {};
|
||
this._ready_state = 0;
|
||
this._instantiator = null;
|
||
this._dom_parent = null;
|
||
this._dom_children = /* @__PURE__ */ new Set();
|
||
this._use_dom_fallback = false;
|
||
this._stopped = false;
|
||
this._booted = false;
|
||
this._data_before_render = null;
|
||
this._lifecycle_callbacks = /* @__PURE__ */ new Map();
|
||
this._lifecycle_states = /* @__PURE__ */ new Set();
|
||
this.__loading = false;
|
||
this._did_first_render = false;
|
||
this._render_count = 0;
|
||
this._cid = this._generate_cid();
|
||
this._lifecycle_manager = LifecycleManager.get_instance();
|
||
if (element) {
|
||
this.$ = $(element);
|
||
} else {
|
||
const div = document.createElement("div");
|
||
this.$ = $(div);
|
||
}
|
||
const dataAttrs = {};
|
||
if (this.$.length > 0) {
|
||
const dataset = this.$[0].dataset || {};
|
||
for (const key in dataset) {
|
||
if (key !== "cid" && key !== "tid" && key !== "componentName" && key !== "readyState") {
|
||
const dataValue = this.$.data(key);
|
||
if (dataValue !== void 0 && dataValue !== dataset[key]) {
|
||
dataAttrs[key] = dataValue;
|
||
} else {
|
||
dataAttrs[key] = dataset[key];
|
||
}
|
||
}
|
||
}
|
||
}
|
||
let template_for_args;
|
||
if (args._component_name) {
|
||
template_for_args = get_template(args._component_name);
|
||
} else {
|
||
template_for_args = get_template_by_class(this.constructor);
|
||
}
|
||
const defineArgs = template_for_args?.defineArgs || {};
|
||
this.args = { ...defineArgs, ...dataAttrs, ...args };
|
||
for (const [key, value] of Object.entries(this.args)) {
|
||
if (key === "cid" || key === "tid" || key === "componentName" || key === "readyState" || key.startsWith("_")) {
|
||
continue;
|
||
}
|
||
if (typeof value === "string" || typeof value === "number") {
|
||
try {
|
||
const currentAttr = this.$.attr(`data-${key}`);
|
||
if (currentAttr != value) {
|
||
this.$.attr(`data-${key}`, String(value));
|
||
}
|
||
} catch (e) {
|
||
}
|
||
}
|
||
}
|
||
this.$.data("_component", this);
|
||
this._apply_css_classes();
|
||
this._apply_default_attributes();
|
||
this._set_attributes();
|
||
this._find_dom_parent();
|
||
this._log_lifecycle("construct", "complete");
|
||
}
|
||
/**
|
||
* Boot - Start the full component lifecycle
|
||
* Called immediately after construction by instruction processor
|
||
*/
|
||
async boot() {
|
||
if (this._booted)
|
||
return;
|
||
this._booted = true;
|
||
await this._lifecycle_manager.boot_component(this);
|
||
}
|
||
// -------------------------------------------------------------------------
|
||
// Lifecycle Methods (called by LifecycleManager)
|
||
// -------------------------------------------------------------------------
|
||
/**
|
||
* Internal render phase - Create DOM structure
|
||
* Called top-down (parent before children) when part of lifecycle
|
||
* This is an internal method - users should call render() instead
|
||
*
|
||
* @param id Optional scoped ID - if provided, delegates to child component's _render()
|
||
* @returns The current _render_count after incrementing (used to detect stale renders)
|
||
* @private
|
||
*/
|
||
_render(id = null) {
|
||
this._render_count++;
|
||
const current_render_id = this._render_count;
|
||
if (this._stopped)
|
||
return current_render_id;
|
||
if (id) {
|
||
const $element = this.$sid(id);
|
||
if ($element.length === 0) {
|
||
throw new Error(`[JQHTML] render("${id}") - no such id.
|
||
Component "${this.component_name()}" has no child element with $id="${id}".`);
|
||
}
|
||
const child = $element.data("_component");
|
||
if (!child) {
|
||
throw new Error(`[JQHTML] render("${id}") - element is not a component or does not have $redrawable attribute set.
|
||
Element with $id="${id}" exists but is not initialized as a component.
|
||
Add $redrawable attribute or make it a proper component.`);
|
||
}
|
||
return child._render();
|
||
}
|
||
if (this.__loading) {
|
||
throw new Error(`[JQHTML] Component "${this.component_name()}" attempted to call render() during on_load().
|
||
on_load() should ONLY modify this.data. DOM updates happen automatically after on_load() completes.
|
||
|
||
Fix: Remove the this.render() call from on_load().
|
||
The framework will automatically re-render if this.data changes during on_load().`);
|
||
}
|
||
this._log_lifecycle("render", "start");
|
||
if (!$.contains(document.documentElement, this.$[0])) {
|
||
this._use_dom_fallback = true;
|
||
} else {
|
||
this._use_dom_fallback = false;
|
||
}
|
||
if (this._did_first_render) {
|
||
this.$.find(".Component").each(function() {
|
||
const child = $(this).data("_component");
|
||
if (child && !child._stopped) {
|
||
child._stop();
|
||
}
|
||
});
|
||
this.$[0].innerHTML = "";
|
||
} else {
|
||
this._did_first_render = true;
|
||
}
|
||
this.$.removeClass("_Component_Stopped");
|
||
if (this._data_before_render === null) {
|
||
this._data_before_render = JSON.stringify(this.data);
|
||
}
|
||
this._dom_children.clear();
|
||
let template_def;
|
||
if (this.args._component_name) {
|
||
template_def = get_template(this.args._component_name);
|
||
} else {
|
||
template_def = get_template_by_class(this.constructor);
|
||
}
|
||
if (template_def && template_def.render) {
|
||
const jqhtml2 = {
|
||
escape_html: (str) => {
|
||
const div = document.createElement("div");
|
||
div.textContent = String(str);
|
||
return div.innerHTML;
|
||
}
|
||
};
|
||
const defaultContent = () => "";
|
||
let [instructions, context] = template_def.render.bind(this)(
|
||
this.data,
|
||
this.args,
|
||
this.args._innerhtml_function || defaultContent,
|
||
// Content function with fallback
|
||
jqhtml2
|
||
// Utilities object
|
||
);
|
||
if (instructions && typeof instructions === "object" && instructions._slots && !Array.isArray(instructions)) {
|
||
const componentName = template_def.name || this.args._component_name || this.constructor.name;
|
||
console.log(`[JQHTML] Slot-only template detected for ${componentName}`);
|
||
let parentTemplate = null;
|
||
let parentTemplateName = null;
|
||
if (template_def.extends) {
|
||
console.log(`[JQHTML] Using explicit extends: ${template_def.extends}`);
|
||
parentTemplate = get_template(template_def.extends);
|
||
parentTemplateName = template_def.extends;
|
||
}
|
||
if (!parentTemplate) {
|
||
let currentClass = Object.getPrototypeOf(this.constructor);
|
||
while (currentClass && currentClass.name !== "Object" && currentClass.name !== "Component") {
|
||
const className = currentClass.name;
|
||
console.log(`[JQHTML] Checking parent: ${className}`);
|
||
try {
|
||
const classTemplate = get_template(className);
|
||
if (classTemplate && classTemplate.name !== "Component") {
|
||
console.log(`[JQHTML] Found parent template: ${className}`);
|
||
parentTemplate = classTemplate;
|
||
parentTemplateName = className;
|
||
break;
|
||
}
|
||
} catch (error) {
|
||
console.warn(`[JQHTML] Error finding parent template ${className}:`, error);
|
||
}
|
||
currentClass = Object.getPrototypeOf(currentClass);
|
||
}
|
||
}
|
||
if (parentTemplate) {
|
||
try {
|
||
const childSlots = instructions._slots;
|
||
const contentFunction = (slotName, data) => {
|
||
if (childSlots[slotName] && typeof childSlots[slotName] === "function") {
|
||
const [slotInstructions, slotContext] = childSlots[slotName](data);
|
||
return [slotInstructions, slotContext];
|
||
}
|
||
return "";
|
||
};
|
||
const [parentInstructions, parentContext] = parentTemplate.render.bind(this)(
|
||
this.data,
|
||
this.args,
|
||
contentFunction,
|
||
// Pass content function that invokes child slots
|
||
jqhtml2
|
||
);
|
||
console.log(`[JQHTML] Parent template invoked successfully`);
|
||
instructions = parentInstructions;
|
||
context = parentContext;
|
||
} catch (error) {
|
||
console.warn(`[JQHTML] Error invoking parent template ${parentTemplateName}:`, error);
|
||
instructions = [];
|
||
}
|
||
} else {
|
||
console.warn(`[JQHTML] No parent template found for ${this.constructor.name}, rendering empty`);
|
||
instructions = [];
|
||
}
|
||
}
|
||
const flattenedInstructions = this._flatten_instructions(instructions);
|
||
process_instructions(flattenedInstructions, this.$, this);
|
||
}
|
||
this._update_debug_attrs();
|
||
this._log_lifecycle("render", "complete");
|
||
const renderResult = this.on_render();
|
||
if (renderResult && typeof renderResult.then === "function") {
|
||
console.warn(`[JQHTML] Component "${this.component_name()}" returned a Promise from on_render(). on_render() must be synchronous code. Remove 'async' from the function declaration.`);
|
||
}
|
||
this.trigger("render");
|
||
const isRerender = this._ready_state >= 3;
|
||
applyDebugDelay(isRerender ? "rerender" : "render");
|
||
return current_render_id;
|
||
}
|
||
/**
|
||
* Public render method - re-renders component and completes lifecycle
|
||
* This is what users should call when they want to update a component.
|
||
*
|
||
* Lifecycle sequence:
|
||
* 1. _render() - Updates DOM synchronously, calls on_render(), fires 'render' event
|
||
* 2. Async continuation (fire and forget):
|
||
* - _wait_for_children_ready() - Waits for all children to reach ready state
|
||
* - on_ready() - Calls user's ready hook
|
||
* - trigger('ready') - Fires ready event
|
||
*
|
||
* Returns immediately after _render() completes - does NOT wait for children
|
||
*/
|
||
render(id = null) {
|
||
if (this._stopped)
|
||
return;
|
||
if (id) {
|
||
const $element = this.$sid(id);
|
||
if ($element.length === 0) {
|
||
throw new Error(`[JQHTML] render("${id}") - no such id.
|
||
Component "${this.component_name()}" has no child element with $id="${id}".`);
|
||
}
|
||
const child = $element.data("_component");
|
||
if (!child) {
|
||
throw new Error(`[JQHTML] render("${id}") - element is not a component or does not have $redrawable attribute set.
|
||
Element with $id="${id}" exists but is not initialized as a component.
|
||
Add $redrawable attribute or make it a proper component.`);
|
||
}
|
||
return child.render();
|
||
}
|
||
const render_id = this._render();
|
||
(async () => {
|
||
await this._wait_for_children_ready();
|
||
if (this._render_count !== render_id) {
|
||
return;
|
||
}
|
||
await this.on_ready();
|
||
await this.trigger("ready");
|
||
})();
|
||
}
|
||
/**
|
||
* Alias for render() - re-renders component with current data
|
||
* Provided for API consistency and clarity
|
||
*/
|
||
redraw(id = null) {
|
||
return this.render(id);
|
||
}
|
||
/**
|
||
* Create phase - Quick setup, prepare UI
|
||
* Called bottom-up (children before parent)
|
||
*/
|
||
async create() {
|
||
if (this._stopped || this._ready_state >= 1)
|
||
return;
|
||
this._log_lifecycle("create", "start");
|
||
const result = this.on_create();
|
||
if (result && typeof result.then === "function") {
|
||
console.warn(`[JQHTML] Component "${this.component_name()}" returned a Promise from on_create(). on_create() must be synchronous code. Remove 'async' from the function declaration.`);
|
||
await result;
|
||
}
|
||
this._ready_state = 1;
|
||
this._update_debug_attrs();
|
||
this._log_lifecycle("create", "complete");
|
||
this.trigger("create");
|
||
}
|
||
/**
|
||
* Load phase - Fetch data from APIs
|
||
* Called bottom-up, fully parallel
|
||
* NO DOM MODIFICATIONS ALLOWED IN THIS PHASE
|
||
*/
|
||
async load() {
|
||
if (this._stopped || this._ready_state >= 2)
|
||
return;
|
||
this._log_lifecycle("load", "start");
|
||
const argsBeforeLoad = JSON.stringify(this.args);
|
||
const propertiesBeforeLoad = new Set(Object.keys(this));
|
||
this.__loading = true;
|
||
try {
|
||
await this.on_load();
|
||
} finally {
|
||
this.__loading = false;
|
||
}
|
||
const argsAfterLoad = JSON.stringify(this.args);
|
||
const propertiesAfterLoad = Object.keys(this);
|
||
if (argsBeforeLoad !== argsAfterLoad) {
|
||
console.error(`[JQHTML] WARNING: Component "${this.component_name()}" modified this.args in on_load().
|
||
on_load() should ONLY modify this.data. The this.args property is read-only.
|
||
|
||
Before: ${argsBeforeLoad}
|
||
After: ${argsAfterLoad}
|
||
|
||
Fix: Move your modifications to this.data instead.`);
|
||
}
|
||
const newProperties = propertiesAfterLoad.filter((prop) => !propertiesBeforeLoad.has(prop) && prop !== "data");
|
||
if (newProperties.length > 0) {
|
||
console.error(`[JQHTML] WARNING: Component "${this.component_name()}" added new properties in on_load().
|
||
on_load() should ONLY modify this.data. New properties detected: ${newProperties.join(", ")}
|
||
|
||
Fix: Store your data in this.data instead:
|
||
\u274C this.${newProperties[0]} = value;
|
||
\u2705 this.data.${newProperties[0]} = value;`);
|
||
}
|
||
this._ready_state = 2;
|
||
this._update_debug_attrs();
|
||
this._log_lifecycle("load", "complete");
|
||
this.trigger("load");
|
||
}
|
||
/**
|
||
* Ready phase - Component fully initialized
|
||
* Called bottom-up (children before parent)
|
||
*/
|
||
async ready() {
|
||
if (this._stopped || this._ready_state >= 4)
|
||
return;
|
||
this._log_lifecycle("ready", "start");
|
||
await this._wait_for_children_ready();
|
||
await this.on_ready();
|
||
this._ready_state = 4;
|
||
this._update_debug_attrs();
|
||
this._log_lifecycle("ready", "complete");
|
||
this.trigger("ready");
|
||
}
|
||
/**
|
||
* Wait for all child components to reach ready state
|
||
* Ensures bottom-up ordering (children ready before parent)
|
||
* @private
|
||
*/
|
||
async _wait_for_children_ready() {
|
||
const children = this._get_dom_children();
|
||
if (children.length === 0) {
|
||
return;
|
||
}
|
||
const ready_promises = [];
|
||
for (const child of children) {
|
||
if (child._ready_state >= 4) {
|
||
continue;
|
||
}
|
||
const ready_promise = new Promise((resolve) => {
|
||
child.on("ready", () => resolve());
|
||
});
|
||
ready_promises.push(ready_promise);
|
||
}
|
||
await Promise.all(ready_promises);
|
||
}
|
||
/**
|
||
* Reinitialize the component - full reset and re-initialization
|
||
* Wipes the innerHTML, resets data to empty, and runs full lifecycle
|
||
*/
|
||
async reinitialize() {
|
||
if (this._stopped)
|
||
return;
|
||
this._log_lifecycle("reinitialize", "start");
|
||
this.$[0].innerHTML = "";
|
||
this.data = {};
|
||
this._ready_state = 0;
|
||
this._data_before_render = null;
|
||
this._dom_children.clear();
|
||
await this._render();
|
||
await this.create();
|
||
await this.load();
|
||
if (this.should_rerender()) {
|
||
await this._render();
|
||
}
|
||
await this.ready();
|
||
this._log_lifecycle("reinitialize", "complete");
|
||
}
|
||
/**
|
||
* Reload component - re-fetch data and re-render
|
||
* Re-runs on_load(), always renders, and calls on_ready()
|
||
*/
|
||
async reload() {
|
||
if (this._stopped)
|
||
return;
|
||
this._log_lifecycle("reload", "start");
|
||
const has_custom_on_load = this.on_load !== _Jqhtml_Component.prototype.on_load;
|
||
if (has_custom_on_load) {
|
||
const argsBeforeLoad = JSON.stringify(this.args);
|
||
const propertiesBeforeLoad = new Set(Object.keys(this));
|
||
this.__loading = true;
|
||
try {
|
||
await this.on_load();
|
||
} finally {
|
||
this.__loading = false;
|
||
}
|
||
const argsAfterLoad = JSON.stringify(this.args);
|
||
const propertiesAfterLoad = Object.keys(this);
|
||
if (argsBeforeLoad !== argsAfterLoad) {
|
||
console.error(`[JQHTML] WARNING: Component "${this.component_name()}" modified this.args in on_load().
|
||
on_load() should ONLY modify this.data. The this.args property is read-only.
|
||
|
||
Before: ${argsBeforeLoad}
|
||
After: ${argsAfterLoad}
|
||
|
||
Fix: Move your modifications to this.data instead.`);
|
||
}
|
||
const newProperties = propertiesAfterLoad.filter((prop) => !propertiesBeforeLoad.has(prop) && prop !== "data");
|
||
if (newProperties.length > 0) {
|
||
console.error(`[JQHTML] WARNING: Component "${this.component_name()}" added new properties in on_load().
|
||
on_load() should ONLY modify this.data. New properties detected: ${newProperties.join(", ")}
|
||
|
||
Fix: Store your data in this.data instead:
|
||
\u274C this.${newProperties[0]} = value;
|
||
\u2705 this.data.${newProperties[0]} = value;`);
|
||
}
|
||
}
|
||
await this.render();
|
||
this._log_lifecycle("reload", "complete");
|
||
}
|
||
/**
|
||
* Destroy the component and cleanup
|
||
* Called automatically by MutationObserver when component is removed from DOM
|
||
* Can also be called manually for explicit cleanup
|
||
*/
|
||
/**
|
||
* Internal stop method - stops just this component (no children)
|
||
* Sets stopped flag, calls lifecycle hooks, but leaves DOM intact
|
||
* @private
|
||
*/
|
||
_stop() {
|
||
if (this._stopped)
|
||
return;
|
||
this._stopped = true;
|
||
const has_custom_destroy = this.on_destroy !== _Jqhtml_Component.prototype.on_destroy;
|
||
const has_destroy_callbacks = this._on_registered("destroy");
|
||
if (!has_custom_destroy && !has_destroy_callbacks) {
|
||
this._lifecycle_manager.unregister_component(this);
|
||
this._ready_state = 99;
|
||
return;
|
||
}
|
||
this._log_lifecycle("destroy", "start");
|
||
this.$.addClass("_Component_Stopped");
|
||
this._lifecycle_manager.unregister_component(this);
|
||
const destroyResult = this.on_destroy();
|
||
if (destroyResult && typeof destroyResult.then === "function") {
|
||
console.warn(`[JQHTML] Component "${this.component_name()}" returned a Promise from on_destroy(). on_destroy() must be synchronous code. Remove 'async' from the function declaration.`);
|
||
}
|
||
this.trigger("destroy");
|
||
this.$.trigger("destroy");
|
||
if (this._dom_parent) {
|
||
this._dom_parent._dom_children.delete(this);
|
||
}
|
||
this._ready_state = 99;
|
||
this._update_debug_attrs();
|
||
this._log_lifecycle("destroy", "complete");
|
||
}
|
||
/**
|
||
* Stop component lifecycle - stops all descendant components then self
|
||
* Leaves DOM intact, just stops lifecycle engine and fires cleanup hooks
|
||
*/
|
||
stop() {
|
||
this.$.find(".Component").each(function() {
|
||
const child = $(this).data("_component");
|
||
if (child && !child._stopped) {
|
||
child._stop();
|
||
}
|
||
});
|
||
this._stop();
|
||
}
|
||
// -------------------------------------------------------------------------
|
||
// Overridable Lifecycle Hooks
|
||
// -------------------------------------------------------------------------
|
||
on_render() {
|
||
}
|
||
on_create() {
|
||
}
|
||
async on_load() {
|
||
}
|
||
async on_ready() {
|
||
}
|
||
on_destroy() {
|
||
}
|
||
/**
|
||
* Should component re-render after load?
|
||
* By default, only re-renders if data has changed
|
||
* Override to control re-rendering behavior
|
||
*/
|
||
should_rerender() {
|
||
const currentDataState = JSON.stringify(this.data);
|
||
const dataChanged = this._data_before_render !== currentDataState;
|
||
if (dataChanged) {
|
||
this._data_before_render = currentDataState;
|
||
}
|
||
return dataChanged;
|
||
}
|
||
// -------------------------------------------------------------------------
|
||
// Public API
|
||
// -------------------------------------------------------------------------
|
||
/**
|
||
* Get component name for debugging
|
||
*/
|
||
component_name() {
|
||
return this.constructor.name;
|
||
}
|
||
/**
|
||
* Emit a jQuery event from component root
|
||
*/
|
||
emit(event_name, data) {
|
||
this._log_debug("emit", event_name, data);
|
||
this.$.trigger(event_name, data);
|
||
}
|
||
/**
|
||
* Register lifecycle event callback
|
||
* Allowed events: 'render', 'create', 'load', 'ready', 'destroy'
|
||
* Callbacks fire after the lifecycle method completes
|
||
* If the event has already occurred, the callback fires immediately AND registers for future occurrences
|
||
*/
|
||
on(event_name, callback) {
|
||
const allowed_events = ["render", "create", "load", "ready", "destroy"];
|
||
if (!allowed_events.includes(event_name)) {
|
||
console.error(`[JQHTML] Component.on() only supports lifecycle events: ${allowed_events.join(", ")}. Received: ${event_name}`);
|
||
return this;
|
||
}
|
||
if (!this._lifecycle_callbacks.has(event_name)) {
|
||
this._lifecycle_callbacks.set(event_name, []);
|
||
}
|
||
this._lifecycle_callbacks.get(event_name).push(callback);
|
||
if (this._lifecycle_states.has(event_name)) {
|
||
try {
|
||
callback(this);
|
||
} catch (error) {
|
||
console.error(`[JQHTML] Error in ${event_name} callback:`, error);
|
||
}
|
||
}
|
||
return this;
|
||
}
|
||
/**
|
||
* Trigger a lifecycle event - fires all registered callbacks
|
||
* Marks event as occurred so future .on() calls fire immediately
|
||
*/
|
||
trigger(event_name) {
|
||
this._lifecycle_states.add(event_name);
|
||
const callbacks = this._lifecycle_callbacks.get(event_name);
|
||
if (callbacks) {
|
||
for (const callback of callbacks) {
|
||
try {
|
||
callback.bind(this)(this);
|
||
} catch (error) {
|
||
console.error(`[JQHTML] Error in ${event_name} callback:`, error);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
/**
|
||
* Check if any callbacks are registered for a given event
|
||
* Used to determine if cleanup logic needs to run
|
||
*/
|
||
_on_registered(event_name) {
|
||
const callbacks = this._lifecycle_callbacks.get(event_name);
|
||
return !!(callbacks && callbacks.length > 0);
|
||
}
|
||
/**
|
||
* Find element by scoped ID
|
||
*
|
||
* Searches for elements with id="local_id:THIS_COMPONENT_CID"
|
||
*
|
||
* Example:
|
||
* Template: <button $id="save_btn">Save</button>
|
||
* Rendered: <button id="save_btn:abc123" data-id="save_btn">Save</button>
|
||
* Access: this.$sid('save_btn') // Returns jQuery element
|
||
*
|
||
* Performance: Uses native document.getElementById() when component is in DOM,
|
||
* falls back to jQuery.find() for components not yet attached to DOM.
|
||
*
|
||
* @param local_id The local ID (without _cid suffix)
|
||
* @returns jQuery element with id="local_id:_cid", or empty jQuery object if not found
|
||
*/
|
||
$id(local_id) {
|
||
const scopedId = `${local_id}:${this._cid}`;
|
||
const el = document.getElementById(scopedId);
|
||
if (el) {
|
||
return $(el);
|
||
}
|
||
return this.$.find(`#${$.escapeSelector(scopedId)}`);
|
||
}
|
||
/**
|
||
* Get component instance by scoped ID
|
||
*
|
||
* Convenience method that finds element by scoped ID and returns the component instance.
|
||
*
|
||
* Example:
|
||
* Template: <User_Card $id="active_user" />
|
||
* Access: const user = this.id('active_user'); // Returns User_Card instance
|
||
* user.data.name // Access component's data
|
||
*
|
||
* @param local_id The local ID (without _cid suffix)
|
||
* @returns Component instance or null if not found or not a component
|
||
*/
|
||
id(local_id) {
|
||
const element = this.$sid(local_id);
|
||
const component = element.data("_component");
|
||
if (!component && element.length > 0) {
|
||
console.warn(`Component ${this.constructor.name} tried to call .id('${local_id}') - ${local_id} exists, however, it is not a component or $redrawable. Did you forget to add $redrawable to the tag?`);
|
||
}
|
||
return component || null;
|
||
}
|
||
/**
|
||
* Get the component that instantiated this component (rendered it in their template)
|
||
* Returns null if component was created programmatically via $().component()
|
||
*/
|
||
instantiator() {
|
||
return this._instantiator;
|
||
}
|
||
/**
|
||
* Find descendant components by CSS selector
|
||
*/
|
||
find(selector) {
|
||
const components = [];
|
||
this.$.find(selector).each((_, el) => {
|
||
const comp = $(el).data("_component");
|
||
if (comp instanceof _Jqhtml_Component) {
|
||
components.push(comp);
|
||
}
|
||
});
|
||
return components;
|
||
}
|
||
/**
|
||
* Find closest ancestor component matching selector
|
||
*/
|
||
closest(selector) {
|
||
let current = this.$.parent();
|
||
while (current.length > 0) {
|
||
if (current.is(selector)) {
|
||
const comp = current.data("_component");
|
||
if (comp instanceof _Jqhtml_Component) {
|
||
return comp;
|
||
}
|
||
}
|
||
current = current.parent();
|
||
}
|
||
return null;
|
||
}
|
||
// -------------------------------------------------------------------------
|
||
// Static Methods
|
||
// -------------------------------------------------------------------------
|
||
/**
|
||
* Get CSS class hierarchy for this component type
|
||
*/
|
||
static get_class_hierarchy() {
|
||
const classes = [];
|
||
let ctor = this;
|
||
while (ctor) {
|
||
if (!ctor.name || typeof ctor.name !== "string") {
|
||
break;
|
||
}
|
||
if (ctor.name !== "Object" && ctor.name !== "") {
|
||
let normalizedName = ctor.name;
|
||
if (normalizedName === "_Jqhtml_Component" || normalizedName === "_Base_Jqhtml_Component") {
|
||
normalizedName = "Component";
|
||
}
|
||
classes.push(normalizedName);
|
||
}
|
||
const nextProto = Object.getPrototypeOf(ctor);
|
||
if (!nextProto || nextProto === Object.prototype || nextProto.constructor === Object) {
|
||
break;
|
||
}
|
||
ctor = nextProto;
|
||
}
|
||
return classes;
|
||
}
|
||
// -------------------------------------------------------------------------
|
||
// Private Implementation
|
||
// -------------------------------------------------------------------------
|
||
_generate_cid() {
|
||
return uid();
|
||
}
|
||
/**
|
||
* Flatten instruction array - converts ['_content', [...]] markers to flat array
|
||
* Recursively flattens nested content from content() calls
|
||
*/
|
||
_flatten_instructions(instructions) {
|
||
const result = [];
|
||
for (const instruction of instructions) {
|
||
if (Array.isArray(instruction) && instruction[0] === "_content" && Array.isArray(instruction[1])) {
|
||
const contentInstructions = this._flatten_instructions(instruction[1]);
|
||
result.push(...contentInstructions);
|
||
} else {
|
||
result.push(instruction);
|
||
}
|
||
}
|
||
return result;
|
||
}
|
||
_apply_css_classes() {
|
||
const hierarchy = this.constructor.get_class_hierarchy();
|
||
const classesToAdd = [...hierarchy];
|
||
if (this.args._component_name && this.args._component_name !== this.constructor.name) {
|
||
classesToAdd.unshift(this.args._component_name);
|
||
}
|
||
const publicClasses = classesToAdd.filter((className) => {
|
||
if (!className || typeof className !== "string") {
|
||
console.warn("[JQHTML] Filtered out invalid class name:", className);
|
||
return false;
|
||
}
|
||
return !className.startsWith("_");
|
||
});
|
||
if (publicClasses.length > 0) {
|
||
this.$.addClass(publicClasses.join(" "));
|
||
}
|
||
}
|
||
_apply_default_attributes() {
|
||
let template;
|
||
if (this.args._component_name) {
|
||
template = get_template(this.args._component_name);
|
||
} else {
|
||
template = get_template_by_class(this.constructor);
|
||
}
|
||
if (template && template.defaultAttributes) {
|
||
const defineAttrs = { ...template.defaultAttributes };
|
||
delete defineAttrs.tag;
|
||
if (window.jqhtml?.debug?.enabled) {
|
||
const componentName = template.name || this.args._component_name || this.constructor.name;
|
||
console.log(`[Component] Applying defaultAttributes for ${componentName}:`, defineAttrs);
|
||
}
|
||
for (const [key, value] of Object.entries(defineAttrs)) {
|
||
if (key === "class") {
|
||
const existingClasses = this.$.attr("class");
|
||
if (existingClasses) {
|
||
const existing = existingClasses.split(/\s+/).filter((c) => c);
|
||
const newClasses = String(value).split(/\s+/).filter((c) => c);
|
||
for (const newClass of newClasses) {
|
||
if (!existing.includes(newClass)) {
|
||
existing.push(newClass);
|
||
}
|
||
}
|
||
this.$.attr("class", existing.join(" "));
|
||
} else {
|
||
this.$.attr("class", value);
|
||
}
|
||
} else if (key === "style") {
|
||
const existingStyle = this.$.attr("style");
|
||
if (existingStyle) {
|
||
const existingRules = /* @__PURE__ */ new Map();
|
||
existingStyle.split(";").forEach((rule) => {
|
||
const [prop, val] = rule.split(":").map((s) => s.trim());
|
||
if (prop && val)
|
||
existingRules.set(prop, val);
|
||
});
|
||
String(value).split(";").forEach((rule) => {
|
||
const [prop, val] = rule.split(":").map((s) => s.trim());
|
||
if (prop && val)
|
||
existingRules.set(prop, val);
|
||
});
|
||
const merged = Array.from(existingRules.entries()).map(([prop, val]) => `${prop}: ${val}`).join("; ");
|
||
this.$.attr("style", merged);
|
||
} else {
|
||
this.$.attr("style", value);
|
||
}
|
||
} else if (key.startsWith("$") || key.startsWith("data-")) {
|
||
const dataKey = key.startsWith("$") ? key.substring(1) : key.startsWith("data-") ? key.substring(5) : key;
|
||
if (!(dataKey in this.args)) {
|
||
this.args[dataKey] = value;
|
||
this.$.data(dataKey, value);
|
||
this.$.attr(key.startsWith("$") ? `data-${dataKey}` : key, String(value));
|
||
}
|
||
} else {
|
||
if (!this.$.attr(key)) {
|
||
this.$.attr(key, value);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
_set_attributes() {
|
||
this.$.attr("data-cid", this._cid);
|
||
if (window.jqhtml?.debug?.verbose) {
|
||
this.$.attr("data-_lifecycle-state", this._ready_state.toString());
|
||
}
|
||
}
|
||
_update_debug_attrs() {
|
||
if (window.jqhtml?.debug?.verbose) {
|
||
this.$.attr("data-_lifecycle-state", this._ready_state.toString());
|
||
}
|
||
}
|
||
_find_dom_parent() {
|
||
let current = this.$.parent();
|
||
while (current.length > 0) {
|
||
const parent = current.data("_component");
|
||
if (parent instanceof _Jqhtml_Component) {
|
||
this._dom_parent = parent;
|
||
parent._dom_children.add(this);
|
||
break;
|
||
}
|
||
current = current.parent();
|
||
}
|
||
}
|
||
/**
|
||
* Get DOM children (components in DOM subtree)
|
||
* Uses fast _dom_children registry when possible, falls back to DOM traversal for off-DOM components
|
||
* @private - Used internally for lifecycle coordination
|
||
*/
|
||
_get_dom_children() {
|
||
if (this._use_dom_fallback) {
|
||
const directChildren = [];
|
||
this.$.find(".Component").each((_, el) => {
|
||
const $el = $(el);
|
||
const comp = $el.data("_component");
|
||
if (comp instanceof _Jqhtml_Component) {
|
||
const closestParent = $el.parent().closest(".Component");
|
||
if (closestParent.length === 0 || closestParent.data("_component") === this) {
|
||
directChildren.push(comp);
|
||
}
|
||
}
|
||
});
|
||
return directChildren;
|
||
}
|
||
const children = Array.from(this._dom_children);
|
||
return children.filter((child) => {
|
||
return $.contains(document.documentElement, child.$[0]);
|
||
});
|
||
}
|
||
_log_lifecycle(phase, status) {
|
||
logLifecycle(this, phase, status);
|
||
if (typeof window !== "undefined" && window.JQHTML_DEBUG) {
|
||
window.JQHTML_DEBUG.log(this.component_name(), phase, status, {
|
||
cid: this._cid,
|
||
ready_state: this._ready_state,
|
||
args: this.args
|
||
});
|
||
}
|
||
}
|
||
_log_debug(action, ...args) {
|
||
if (typeof window !== "undefined" && window.JQHTML_DEBUG) {
|
||
window.JQHTML_DEBUG.log(this.component_name(), "debug", `${action}: ${args.map((a) => JSON.stringify(a)).join(", ")}`);
|
||
}
|
||
}
|
||
};
|
||
async function process_slot_inheritance(component, childSlots) {
|
||
let currentClass = Object.getPrototypeOf(component.constructor);
|
||
console.log(`[JQHTML] Walking prototype chain for ${component.constructor.name}`);
|
||
while (currentClass && currentClass !== Component && currentClass.name !== "Object") {
|
||
const className = currentClass.name;
|
||
console.log(`[JQHTML] Checking parent class: ${className}`);
|
||
if (className === "_Jqhtml_Component" || className === "_Base_Jqhtml_Component") {
|
||
currentClass = Object.getPrototypeOf(currentClass);
|
||
continue;
|
||
}
|
||
try {
|
||
const parentTemplate = get_template(className);
|
||
console.log(`[JQHTML] Template found for ${className}:`, parentTemplate ? parentTemplate.name : "null");
|
||
if (parentTemplate && parentTemplate.name !== "Component") {
|
||
console.log(`[JQHTML] Invoking parent template ${className}`);
|
||
const [parentInstructions, parentContext] = parentTemplate.render.call(
|
||
component,
|
||
component.data,
|
||
component.args,
|
||
childSlots
|
||
// Pass child slots as content parameter
|
||
);
|
||
if (parentInstructions && typeof parentInstructions === "object" && parentInstructions._slots) {
|
||
console.log(`[JQHTML] Parent also slot-only, recursing`);
|
||
return await process_slot_inheritance(component, parentInstructions._slots);
|
||
}
|
||
console.log(`[JQHTML] Parent returned instructions, inheritance complete`);
|
||
return [parentInstructions, parentContext];
|
||
}
|
||
} catch (error) {
|
||
console.warn(`[JQHTML] Error looking up parent template for ${className}:`, error);
|
||
}
|
||
currentClass = Object.getPrototypeOf(currentClass);
|
||
}
|
||
console.warn(`[JQHTML] No parent template found after walking chain`);
|
||
return null;
|
||
}
|
||
async function render_template(component, template_fn) {
|
||
let render_fn = template_fn;
|
||
if (!render_fn) {
|
||
const template_def = get_template_by_class(component.constructor);
|
||
render_fn = template_def.render;
|
||
}
|
||
if (!render_fn) {
|
||
return;
|
||
}
|
||
component.$.empty();
|
||
const defaultContent = () => "";
|
||
let [instructions, context] = render_fn.call(
|
||
component,
|
||
component.data,
|
||
component.args,
|
||
defaultContent
|
||
// Default content function that returns empty string
|
||
);
|
||
if (instructions && typeof instructions === "object" && instructions._slots) {
|
||
console.log(`[JQHTML] Slot-only template detected for ${component.constructor.name}, invoking inheritance`);
|
||
const result = await process_slot_inheritance(component, instructions._slots);
|
||
if (result) {
|
||
console.log(`[JQHTML] Parent template found, using parent instructions`);
|
||
instructions = result[0];
|
||
context = result[1];
|
||
} else {
|
||
console.warn(`[JQHTML] No parent template found for ${component.constructor.name}, rendering empty`);
|
||
instructions = [];
|
||
}
|
||
}
|
||
await process_instructions(instructions, component.$, component);
|
||
await process_bindings(component);
|
||
await attach_event_handlers(component);
|
||
}
|
||
async function process_bindings(component) {
|
||
component.$.find("[data-bind-prop], [data-bind-value], [data-bind-text], [data-bind-html], [data-bind-class], [data-bind-style]").each((_, element) => {
|
||
const el = $(element);
|
||
const attrs = element.attributes;
|
||
for (let i = 0; i < attrs.length; i++) {
|
||
const attr = attrs[i];
|
||
if (attr.name.startsWith("data-bind-")) {
|
||
const binding_type = attr.name.substring(10);
|
||
const expression = attr.value;
|
||
try {
|
||
const value = evaluate_expression(expression, component);
|
||
switch (binding_type) {
|
||
case "prop":
|
||
const prop_name = el.attr("data-bind-prop-name") || "value";
|
||
el.prop(prop_name, value);
|
||
break;
|
||
case "value":
|
||
el.val(value);
|
||
break;
|
||
case "text":
|
||
el.text(value);
|
||
break;
|
||
case "html":
|
||
el.html(value);
|
||
break;
|
||
case "class":
|
||
if (typeof value === "object") {
|
||
Object.entries(value).forEach(([className, enabled]) => {
|
||
el.toggleClass(className, !!enabled);
|
||
});
|
||
} else {
|
||
el.addClass(String(value));
|
||
}
|
||
break;
|
||
case "style":
|
||
if (typeof value === "object") {
|
||
el.css(value);
|
||
} else {
|
||
el.attr("style", String(value));
|
||
}
|
||
break;
|
||
default:
|
||
el.attr(binding_type, value);
|
||
}
|
||
} catch (error) {
|
||
console.error(`Error evaluating binding "${expression}":`, error);
|
||
}
|
||
}
|
||
}
|
||
});
|
||
}
|
||
async function attach_event_handlers(component) {
|
||
component.$.find("[data-on-click], [data-on-change], [data-on-submit], [data-on-keyup], [data-on-keydown], [data-on-focus], [data-on-blur]").each((_, element) => {
|
||
const el = $(element);
|
||
const attrs = element.attributes;
|
||
for (let i = 0; i < attrs.length; i++) {
|
||
const attr = attrs[i];
|
||
if (attr.name.startsWith("data-on-")) {
|
||
const event_name = attr.name.substring(8);
|
||
const handler_expr = attr.value;
|
||
el.removeAttr(attr.name);
|
||
el.on(event_name, function(event) {
|
||
try {
|
||
const handler = evaluate_handler(handler_expr, component);
|
||
if (typeof handler === "function") {
|
||
handler.call(component, event);
|
||
} else {
|
||
evaluate_expression(handler_expr, component, { $event: event });
|
||
}
|
||
} catch (error) {
|
||
console.error(`Error in ${event_name} handler "${handler_expr}":`, error);
|
||
}
|
||
});
|
||
}
|
||
}
|
||
});
|
||
}
|
||
function evaluate_expression(expression, component, locals = {}) {
|
||
const context = {
|
||
// Component properties
|
||
data: component.data,
|
||
args: component.args,
|
||
$: component.$,
|
||
// Component methods
|
||
emit: component.emit.bind(component),
|
||
$id: component.$id.bind(component),
|
||
// Locals (like $event)
|
||
...locals
|
||
};
|
||
const keys = Object.keys(context);
|
||
const values = Object.values(context);
|
||
try {
|
||
const fn = new Function(...keys, `return (${expression})`);
|
||
return fn(...values);
|
||
} catch (error) {
|
||
console.error(`Invalid expression: ${expression}`, error);
|
||
return void 0;
|
||
}
|
||
}
|
||
function evaluate_handler(expression, component) {
|
||
if (expression in component && typeof component[expression] === "function") {
|
||
return component[expression];
|
||
}
|
||
try {
|
||
return new Function("$event", `
|
||
const { data, args, $, emit, $id } = this;
|
||
${expression}
|
||
`).bind(component);
|
||
} catch (error) {
|
||
console.error(`Invalid handler: ${expression}`, error);
|
||
return null;
|
||
}
|
||
}
|
||
function escape_html(str) {
|
||
const div = document.createElement("div");
|
||
div.textContent = str;
|
||
return div.innerHTML;
|
||
}
|
||
function getJQuery() {
|
||
if (typeof window !== "undefined" && window.$) {
|
||
return window.$;
|
||
}
|
||
if (typeof window !== "undefined" && window.jQuery) {
|
||
return window.jQuery;
|
||
}
|
||
throw new Error('FATAL: jQuery is not defined. jQuery must be loaded before using JQHTML. Add <script src="https://code.jquery.com/jquery-3.7.1.min.js"><\/script> before loading JQHTML.');
|
||
}
|
||
function getJqhtml() {
|
||
if (typeof window !== "undefined" && window.jqhtml) {
|
||
return window.jqhtml;
|
||
}
|
||
if (typeof globalThis !== "undefined" && globalThis.jqhtml) {
|
||
return globalThis.jqhtml;
|
||
}
|
||
throw new Error("FATAL: window.jqhtml is not defined. The JQHTML runtime must be loaded before using JQHTML components. Ensure @jqhtml/core is imported and initialized before attempting to use debug features.");
|
||
}
|
||
var DebugOverlay = class _DebugOverlay {
|
||
constructor(options = {}) {
|
||
this.$container = null;
|
||
this.$statusIndicator = null;
|
||
this.$ = getJQuery();
|
||
if (!this.$) {
|
||
throw new Error("jQuery is required for DebugOverlay");
|
||
}
|
||
this.options = {
|
||
position: "bottom",
|
||
theme: "dark",
|
||
compact: false,
|
||
showStatus: true,
|
||
autoHide: false,
|
||
...options
|
||
};
|
||
}
|
||
/**
|
||
* Static method to show debug overlay (singleton pattern)
|
||
*/
|
||
static show(options) {
|
||
if (!_DebugOverlay.instance) {
|
||
_DebugOverlay.instance = new _DebugOverlay(options);
|
||
}
|
||
_DebugOverlay.instance.display();
|
||
return _DebugOverlay.instance;
|
||
}
|
||
/**
|
||
* Static method to hide debug overlay
|
||
*/
|
||
static hide() {
|
||
if (_DebugOverlay.instance) {
|
||
_DebugOverlay.instance.hide();
|
||
}
|
||
}
|
||
/**
|
||
* Static method to toggle debug overlay visibility
|
||
*/
|
||
static toggle() {
|
||
if (_DebugOverlay.instance && _DebugOverlay.instance.$container) {
|
||
if (_DebugOverlay.instance.$container.is(":visible")) {
|
||
_DebugOverlay.hide();
|
||
} else {
|
||
_DebugOverlay.instance.display();
|
||
}
|
||
} else {
|
||
_DebugOverlay.show();
|
||
}
|
||
}
|
||
/**
|
||
* Static method to destroy debug overlay
|
||
*/
|
||
static destroy() {
|
||
if (_DebugOverlay.instance) {
|
||
_DebugOverlay.instance.destroy();
|
||
_DebugOverlay.instance = null;
|
||
}
|
||
}
|
||
/**
|
||
* Display the debug overlay
|
||
*/
|
||
display() {
|
||
if (this.$container) {
|
||
this.$container.show();
|
||
return;
|
||
}
|
||
this.createOverlay();
|
||
if (this.options.showStatus) {
|
||
this.createStatusIndicator();
|
||
}
|
||
}
|
||
/**
|
||
* Hide the debug overlay
|
||
*/
|
||
hide() {
|
||
if (this.$container) {
|
||
this.$container.hide();
|
||
}
|
||
if (this.$statusIndicator) {
|
||
this.$statusIndicator.hide();
|
||
}
|
||
}
|
||
/**
|
||
* Remove the debug overlay completely
|
||
*/
|
||
destroy() {
|
||
if (this.$container) {
|
||
this.$container.remove();
|
||
this.$container = null;
|
||
}
|
||
if (this.$statusIndicator) {
|
||
this.$statusIndicator.remove();
|
||
this.$statusIndicator = null;
|
||
}
|
||
}
|
||
/**
|
||
* Update the status indicator
|
||
*/
|
||
updateStatus(mode) {
|
||
if (!this.$statusIndicator)
|
||
return;
|
||
this.$statusIndicator.text("Debug: " + mode);
|
||
this.$statusIndicator.attr("class", "jqhtml-debug-status" + (mode !== "Off" ? " active" : ""));
|
||
}
|
||
createOverlay() {
|
||
this.addStyles();
|
||
this.$container = this.$("<div>").addClass(`jqhtml-debug-overlay ${this.options.theme} ${this.options.position}`);
|
||
const $content = this.$("<div>").addClass("jqhtml-debug-content");
|
||
const $controls = this.$("<div>").addClass("jqhtml-debug-controls");
|
||
const $title = this.$("<span>").addClass("jqhtml-debug-title").html("<strong>\u{1F41B} JQHTML Debug:</strong>");
|
||
$controls.append($title);
|
||
const buttons = [
|
||
{ text: "Slow Motion + Flash", action: "enableSlowMotionDebug", class: "success" },
|
||
{ text: "Basic Debug", action: "enableBasicDebug", class: "" },
|
||
{ text: "Full Debug", action: "enableFullDebug", class: "" },
|
||
{ text: "Sequential", action: "enableSequentialMode", class: "" },
|
||
{ text: "Clear Debug", action: "clearAllDebug", class: "danger" },
|
||
{ text: "Settings", action: "showDebugInfo", class: "" }
|
||
];
|
||
buttons.forEach((btn) => {
|
||
const $button = this.$("<button>").text(btn.text).addClass("jqhtml-debug-btn" + (btn.class ? ` ${btn.class}` : "")).on("click", () => this.executeAction(btn.action));
|
||
$controls.append($button);
|
||
});
|
||
const $toggleBtn = this.$("<button>").text(this.options.compact ? "\u25BC" : "\u25B2").addClass("jqhtml-debug-toggle").on("click", () => this.toggle());
|
||
$controls.append($toggleBtn);
|
||
$content.append($controls);
|
||
this.$container.append($content);
|
||
this.$("body").append(this.$container);
|
||
}
|
||
createStatusIndicator() {
|
||
this.$statusIndicator = this.$("<div>").addClass("jqhtml-debug-status").text("Debug: Off").css({
|
||
position: "fixed",
|
||
top: "10px",
|
||
right: "10px",
|
||
background: "#2c3e50",
|
||
color: "white",
|
||
padding: "5px 10px",
|
||
borderRadius: "4px",
|
||
fontSize: "0.75rem",
|
||
zIndex: "10001",
|
||
opacity: "0.8",
|
||
fontFamily: "monospace"
|
||
});
|
||
this.$("body").append(this.$statusIndicator);
|
||
}
|
||
addStyles() {
|
||
if (this.$("#jqhtml-debug-styles").length > 0)
|
||
return;
|
||
const $style = this.$("<style>").attr("id", "jqhtml-debug-styles").text('.jqhtml-debug-overlay {position: fixed;left: 0;right: 0;z-index: 10000;font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, monospace;font-size: 0.8rem;box-shadow: 0 2px 10px rgba(0,0,0,0.2);}.jqhtml-debug-overlay.top {top: 0;}.jqhtml-debug-overlay.bottom {bottom: 0;}.jqhtml-debug-overlay.dark {background: #34495e;color: #ecf0f1;}.jqhtml-debug-overlay.light {background: #f8f9fa;color: #333;border-bottom: 1px solid #dee2e6;}.jqhtml-debug-content {padding: 0.5rem 1rem;}.jqhtml-debug-controls {display: flex;flex-wrap: wrap;gap: 8px;align-items: center;}.jqhtml-debug-title {margin-right: 10px;font-weight: bold;}.jqhtml-debug-btn {padding: 4px 8px;border: none;border-radius: 3px;background: #3498db;color: white;cursor: pointer;font-size: 0.75rem;transition: background 0.2s;}.jqhtml-debug-btn:hover {background: #2980b9;}.jqhtml-debug-btn.success {background: #27ae60;}.jqhtml-debug-btn.success:hover {background: #229954;}.jqhtml-debug-btn.danger {background: #e74c3c;}.jqhtml-debug-btn.danger:hover {background: #c0392b;}.jqhtml-debug-toggle {padding: 4px 8px;border: none;border-radius: 3px;background: #7f8c8d;color: white;cursor: pointer;font-size: 0.75rem;margin-left: auto;}.jqhtml-debug-toggle:hover {background: #6c7b7d;}.jqhtml-debug-status.active {background: #27ae60 !important;}@media (max-width: 768px) {.jqhtml-debug-controls {flex-direction: column;align-items: flex-start;}.jqhtml-debug-title {margin-bottom: 5px;}}');
|
||
this.$("head").append($style);
|
||
}
|
||
toggle() {
|
||
this.options.compact = !this.options.compact;
|
||
const $toggleBtn = this.$container.find(".jqhtml-debug-toggle");
|
||
$toggleBtn.text(this.options.compact ? "\u25BC" : "\u25B2");
|
||
const $buttons = this.$container.find(".jqhtml-debug-btn");
|
||
if (this.options.compact) {
|
||
$buttons.hide();
|
||
} else {
|
||
$buttons.show();
|
||
}
|
||
}
|
||
executeAction(action) {
|
||
const jqhtml2 = getJqhtml();
|
||
if (!jqhtml2) {
|
||
console.warn("JQHTML not available - make sure it's loaded and exposed globally");
|
||
return;
|
||
}
|
||
switch (action) {
|
||
case "enableSlowMotionDebug":
|
||
jqhtml2.setDebugSettings({
|
||
logFullLifecycle: true,
|
||
sequentialProcessing: true,
|
||
delayAfterComponent: 150,
|
||
delayAfterRender: 200,
|
||
delayAfterRerender: 250,
|
||
flashComponents: true,
|
||
flashDuration: 800,
|
||
flashColors: {
|
||
create: "#3498db",
|
||
render: "#27ae60",
|
||
ready: "#9b59b6"
|
||
},
|
||
profilePerformance: true,
|
||
highlightSlowRenders: 30,
|
||
logDispatch: true
|
||
});
|
||
this.updateStatus("Slow Motion");
|
||
console.log("\u{1F41B} Slow Motion Debug Mode Enabled");
|
||
break;
|
||
case "enableBasicDebug":
|
||
jqhtml2.enableDebugMode("basic");
|
||
this.updateStatus("Basic");
|
||
console.log("\u{1F41B} Basic Debug Mode Enabled");
|
||
break;
|
||
case "enableFullDebug":
|
||
jqhtml2.enableDebugMode("full");
|
||
this.updateStatus("Full");
|
||
console.log("\u{1F41B} Full Debug Mode Enabled");
|
||
break;
|
||
case "enableSequentialMode":
|
||
jqhtml2.setDebugSettings({
|
||
logCreationReady: true,
|
||
sequentialProcessing: true,
|
||
flashComponents: true,
|
||
profilePerformance: true
|
||
});
|
||
this.updateStatus("Sequential");
|
||
console.log("\u{1F41B} Sequential Processing Mode Enabled");
|
||
break;
|
||
case "clearAllDebug":
|
||
jqhtml2.clearDebugSettings();
|
||
this.updateStatus("Off");
|
||
console.log("\u{1F41B} All Debug Modes Disabled");
|
||
break;
|
||
case "showDebugInfo":
|
||
const settings = JSON.stringify(jqhtml2.debug, null, 2);
|
||
console.log("\u{1F41B} Current Debug Settings:", settings);
|
||
alert("Debug settings logged to console:\n\n" + (Object.keys(jqhtml2.debug).length > 0 ? settings : "No debug settings active"));
|
||
break;
|
||
}
|
||
}
|
||
};
|
||
DebugOverlay.instance = null;
|
||
if (typeof window !== "undefined") {
|
||
const urlParams = new URLSearchParams(window.location.search);
|
||
if (urlParams.get("debug") === "true" || urlParams.get("jqhtml-debug") === "true") {
|
||
document.addEventListener("DOMContentLoaded", () => {
|
||
DebugOverlay.show();
|
||
});
|
||
}
|
||
}
|
||
function init_jquery_plugin(jQuery) {
|
||
if (!jQuery || !jQuery.fn) {
|
||
throw new Error("jQuery is required for JQHTML. Please ensure jQuery is loaded before initializing JQHTML.");
|
||
}
|
||
if (typeof window !== "undefined" && window.$ !== jQuery && !jQuery.__jqhtml_checked) {
|
||
devWarn('jQuery instance appears to be bundled with webpack/modules rather than loaded globally.\nFor best compatibility, it is recommended to:\n1. Include jQuery via <script> tag from a CDN (UMD format)\n2. Configure webpack with: externals: { jquery: "$" }\n3. Remove jquery from package.json dependencies\n\nTo suppress this warning, set: window.JQHTML_SUPPRESS_WARNINGS = true');
|
||
jQuery.__jqhtml_checked = true;
|
||
}
|
||
const _jqhtml_original_jquery = jQuery;
|
||
const JQueryWithComponentSupport = function(selector, context) {
|
||
if (selector && typeof selector === "object" && selector.$ && typeof selector.$id === "function" && typeof selector.id === "function") {
|
||
return selector.$;
|
||
}
|
||
return new _jqhtml_original_jquery(selector, context);
|
||
};
|
||
Object.setPrototypeOf(JQueryWithComponentSupport, _jqhtml_original_jquery);
|
||
for (const key in _jqhtml_original_jquery) {
|
||
if (_jqhtml_original_jquery.hasOwnProperty(key)) {
|
||
JQueryWithComponentSupport[key] = _jqhtml_original_jquery[key];
|
||
}
|
||
}
|
||
JQueryWithComponentSupport.prototype = _jqhtml_original_jquery.prototype;
|
||
JQueryWithComponentSupport.fn = _jqhtml_original_jquery.fn;
|
||
if (typeof window !== "undefined") {
|
||
window.jQuery = JQueryWithComponentSupport;
|
||
window.$ = JQueryWithComponentSupport;
|
||
}
|
||
jQuery = JQueryWithComponentSupport;
|
||
const originalVal = jQuery.fn.val;
|
||
jQuery.fn.val = function(value) {
|
||
if (arguments.length === 0) {
|
||
const firstEl = this.first();
|
||
if (firstEl.length === 0)
|
||
return void 0;
|
||
const component = firstEl.data("_component");
|
||
const tagName = firstEl.prop("tagName");
|
||
if (component && typeof component.val === "function" && tagName !== "INPUT" && tagName !== "TEXTAREA") {
|
||
return component.val();
|
||
}
|
||
return originalVal.call(this);
|
||
} else {
|
||
this.each(function() {
|
||
const $el = jQuery(this);
|
||
const component = $el.data("_component");
|
||
const tagName = $el.prop("tagName");
|
||
if (component && typeof component.val === "function" && tagName !== "INPUT" && tagName !== "TEXTAREA") {
|
||
component.val(value);
|
||
} else {
|
||
originalVal.call($el, value);
|
||
}
|
||
});
|
||
return this;
|
||
}
|
||
};
|
||
jQuery.fn.component = function(componentOrName, args = {}) {
|
||
const element = this.first ? this.first() : this;
|
||
if (!componentOrName) {
|
||
if (element.length === 0) {
|
||
return null;
|
||
}
|
||
const comp = element.data("_component");
|
||
return comp || null;
|
||
}
|
||
const existingComponent = element.data("_component");
|
||
if (existingComponent) {
|
||
return existingComponent;
|
||
}
|
||
let ComponentClass;
|
||
let componentName;
|
||
if (typeof componentOrName === "string") {
|
||
componentName = componentOrName;
|
||
const found = get_component_class(componentOrName);
|
||
args = { ...args, _component_name: componentName };
|
||
if (!found) {
|
||
ComponentClass = Component;
|
||
} else {
|
||
ComponentClass = found;
|
||
}
|
||
} else {
|
||
ComponentClass = componentOrName;
|
||
}
|
||
let targetElement = element;
|
||
if (componentName) {
|
||
const template = get_template(componentName);
|
||
const expectedTag = args._tag || template.tag || "div";
|
||
const currentTag = element.prop("tagName").toLowerCase();
|
||
if (currentTag !== expectedTag.toLowerCase()) {
|
||
if (args._inner_html) {
|
||
const newElement = jQuery(`<${expectedTag}></${expectedTag}>`);
|
||
const oldEl = element[0];
|
||
if (oldEl && oldEl.attributes) {
|
||
for (let i = 0; i < oldEl.attributes.length; i++) {
|
||
const attr = oldEl.attributes[i];
|
||
newElement.attr(attr.name, attr.value);
|
||
}
|
||
}
|
||
newElement.html(element.html());
|
||
element.replaceWith(newElement);
|
||
targetElement = newElement;
|
||
} else {
|
||
console.warn(`[JQHTML] Component '${componentName}' expects tag '<${expectedTag}>' but element is '<${currentTag}>'. Element tag will not be changed. Consider using the correct tag.`);
|
||
}
|
||
}
|
||
}
|
||
const component = new ComponentClass(targetElement, args);
|
||
component.boot();
|
||
applyDebugDelay("component");
|
||
return component;
|
||
};
|
||
const _jqhtml_jquery_overrides = {};
|
||
const dom_insertion_methods = ["append", "prepend", "before", "after", "replaceWith"];
|
||
for (const fnname of dom_insertion_methods) {
|
||
_jqhtml_jquery_overrides[fnname] = jQuery.fn[fnname];
|
||
jQuery.fn[fnname] = function(...args) {
|
||
const resolvedArgs = args.map((arg) => {
|
||
if (arg && typeof arg === "object" && arg instanceof Component) {
|
||
return arg.$;
|
||
}
|
||
return arg;
|
||
});
|
||
const $elements = resolvedArgs.filter((arg) => arg instanceof jQuery);
|
||
const ret = _jqhtml_jquery_overrides[fnname].apply(this, resolvedArgs);
|
||
for (const $e of $elements) {
|
||
if ($e.closest("html").length > 0) {
|
||
$e.find(".Component").addBack(".Component").each(function() {
|
||
const $comp = jQuery(this);
|
||
const component = $comp.data("_component");
|
||
if (component && !component._ready_state) {
|
||
component.boot();
|
||
}
|
||
});
|
||
}
|
||
}
|
||
return ret;
|
||
};
|
||
}
|
||
jQuery.fn.shallowFind = function(selector) {
|
||
const results = [];
|
||
this.each(function() {
|
||
const traverse = (parent) => {
|
||
for (let i = 0; i < parent.children.length; i++) {
|
||
const child = parent.children[i];
|
||
if (jQuery(child).is(selector)) {
|
||
results.push(child);
|
||
} else {
|
||
traverse(child);
|
||
}
|
||
}
|
||
};
|
||
traverse(this);
|
||
});
|
||
return jQuery(results);
|
||
};
|
||
const originalEmpty = jQuery.fn.empty;
|
||
const originalHtml = jQuery.fn.html;
|
||
const originalText = jQuery.fn.text;
|
||
jQuery.fn.empty = function() {
|
||
return this.each(function() {
|
||
jQuery(this).find(".Component").each(function() {
|
||
const component = jQuery(this).data("_component");
|
||
if (component && !component._stopped) {
|
||
component._stop();
|
||
}
|
||
});
|
||
originalEmpty.call(jQuery(this));
|
||
});
|
||
};
|
||
jQuery.fn.html = function(value) {
|
||
if (arguments.length === 0) {
|
||
return originalHtml.call(this);
|
||
}
|
||
return this.each(function() {
|
||
jQuery(this).empty();
|
||
originalHtml.call(jQuery(this), value);
|
||
});
|
||
};
|
||
jQuery.fn.text = function(value) {
|
||
if (arguments.length === 0) {
|
||
return originalText.call(this);
|
||
}
|
||
return this.each(function() {
|
||
jQuery(this).empty();
|
||
originalText.call(jQuery(this), value);
|
||
});
|
||
};
|
||
}
|
||
if (typeof window !== "undefined" && window.jQuery) {
|
||
init_jquery_plugin(window.jQuery);
|
||
}
|
||
var version = "2.2.185";
|
||
var jqhtml = {
|
||
// Core
|
||
Component,
|
||
LifecycleManager,
|
||
// Registry
|
||
register_component,
|
||
get_component_class,
|
||
register_template,
|
||
get_template,
|
||
get_template_by_class,
|
||
create_component,
|
||
has_component,
|
||
get_component_names,
|
||
get_registered_templates,
|
||
list_components,
|
||
// Template system
|
||
process_instructions,
|
||
extract_slots,
|
||
render_template,
|
||
escape_html,
|
||
// Version property - internal
|
||
__version: version,
|
||
// Debug settings
|
||
debug: {
|
||
enabled: false,
|
||
verbose: false
|
||
},
|
||
// Debug helper functions (mainly for internal use but exposed for advanced debugging)
|
||
setDebugSettings(settings) {
|
||
Object.assign(this.debug, settings);
|
||
},
|
||
enableDebugMode(level = "basic") {
|
||
if (level === "basic") {
|
||
this.debug.logCreationReady = true;
|
||
this.debug.logDispatch = true;
|
||
this.debug.flashComponents = true;
|
||
} else {
|
||
this.debug.logFullLifecycle = true;
|
||
this.debug.logDispatchVerbose = true;
|
||
this.debug.flashComponents = true;
|
||
this.debug.profilePerformance = true;
|
||
this.debug.traceDataFlow = true;
|
||
}
|
||
},
|
||
clearDebugSettings() {
|
||
this.debug = {};
|
||
},
|
||
// Debug overlay methods
|
||
showDebugOverlay(options) {
|
||
return DebugOverlay.show(options);
|
||
},
|
||
hideDebugOverlay() {
|
||
return DebugOverlay.hide();
|
||
},
|
||
// Export DebugOverlay class for direct access
|
||
DebugOverlay,
|
||
// Install globals function
|
||
installGlobals() {
|
||
if (typeof window !== "undefined") {
|
||
window.jqhtml = this;
|
||
window.Component = Component;
|
||
window.Jqhtml_LifecycleManager = LifecycleManager;
|
||
}
|
||
},
|
||
// Version display function - shows version of core library and all registered templates
|
||
_version() {
|
||
console.log(`JQHTML Core v${this.__version}`);
|
||
console.log("Registered Templates:");
|
||
const templateNames = get_component_names();
|
||
if (templateNames.length === 0) {
|
||
console.log(" (no templates registered)");
|
||
} else {
|
||
for (const name of templateNames) {
|
||
const template = get_template(name);
|
||
const templateVersion = template ? template._jqhtml_version || "unknown" : "unknown";
|
||
console.log(` - ${name}: v${templateVersion}`);
|
||
}
|
||
}
|
||
return this.__version;
|
||
},
|
||
// Public version function - returns the stamped version number
|
||
version() {
|
||
return version;
|
||
}
|
||
};
|
||
if (typeof window !== "undefined" && !window.jqhtml) {
|
||
window.jqhtml = jqhtml;
|
||
window.Component = Component;
|
||
window.Component = Component;
|
||
window.Jqhtml_LifecycleManager = LifecycleManager;
|
||
if (jqhtml.debug?.enabled) {
|
||
console.log("[JQHTML] Auto-registered window.jqhtml global for template compatibility");
|
||
}
|
||
}
|
||
|
||
// storage/rsx-tmp/npm-compile/entry_6459e8ed0f60bda4f121420766012d53.js
|
||
window._rsx_npm = window._rsx_npm || {};
|
||
window._rsx_npm.jqhtml = jqhtml;
|
||
window._rsx_npm._Base_Jqhtml_Component = Component;
|
||
})();
|
||
|
||
|
||
/* === rsx/theme/vendor/bootstrap5/dist/js/bootstrap.bundle.js (babel) === */
|
||
"use strict";
|
||
|
||
/*!
|
||
* Bootstrap v5.3.3 (https://getbootstrap.com/)
|
||
* Copyright 2011-2024 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
|
||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||
*/
|
||
(function (global, factory) {
|
||
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : typeof define === 'function' && define.amd ? define(factory) : (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.bootstrap = factory());
|
||
})(void 0, function () {
|
||
'use strict';
|
||
|
||
/**
|
||
* --------------------------------------------------------------------------
|
||
* Bootstrap dom/data.js
|
||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||
* --------------------------------------------------------------------------
|
||
*/
|
||
|
||
/**
|
||
* Constants
|
||
*/
|
||
const elementMap = new Map();
|
||
const Data = {
|
||
set(element, key, instance) {
|
||
if (!elementMap.has(element)) {
|
||
elementMap.set(element, new Map());
|
||
}
|
||
const instanceMap = elementMap.get(element);
|
||
|
||
// make it clear we only want one instance per element
|
||
// can be removed later when multiple key/instances are fine to be used
|
||
if (!instanceMap.has(key) && instanceMap.size !== 0) {
|
||
// eslint-disable-next-line no-console
|
||
console.error(`Bootstrap doesn't allow more than one instance per element. Bound instance: ${Array.from(instanceMap.keys())[0]}.`);
|
||
return;
|
||
}
|
||
instanceMap.set(key, instance);
|
||
},
|
||
get(element, key) {
|
||
if (elementMap.has(element)) {
|
||
return elementMap.get(element).get(key) || null;
|
||
}
|
||
return null;
|
||
},
|
||
remove(element, key) {
|
||
if (!elementMap.has(element)) {
|
||
return;
|
||
}
|
||
const instanceMap = elementMap.get(element);
|
||
instanceMap.delete(key);
|
||
|
||
// free up element references if there are no instances left for an element
|
||
if (instanceMap.size === 0) {
|
||
elementMap.delete(element);
|
||
}
|
||
}
|
||
};
|
||
|
||
/**
|
||
* --------------------------------------------------------------------------
|
||
* Bootstrap util/index.js
|
||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||
* --------------------------------------------------------------------------
|
||
*/
|
||
|
||
const MAX_UID = 1000000;
|
||
const MILLISECONDS_MULTIPLIER = 1000;
|
||
const TRANSITION_END = 'transitionend';
|
||
|
||
/**
|
||
* Properly escape IDs selectors to handle weird IDs
|
||
* @param {string} selector
|
||
* @returns {string}
|
||
*/
|
||
const parseSelector = selector => {
|
||
if (selector && window.CSS && window.CSS.escape) {
|
||
// document.querySelector needs escaping to handle IDs (html5+) containing for instance /
|
||
selector = selector.replace(/#([^\s"#']+)/g, (match, id) => `#${CSS.escape(id)}`);
|
||
}
|
||
return selector;
|
||
};
|
||
|
||
// Shout-out Angus Croll (https://goo.gl/pxwQGp)
|
||
const toType = object => {
|
||
if (object === null || object === undefined) {
|
||
return `${object}`;
|
||
}
|
||
return Object.prototype.toString.call(object).match(/\s([a-z]+)/i)[1].toLowerCase();
|
||
};
|
||
|
||
/**
|
||
* Public Util API
|
||
*/
|
||
|
||
const getUID = prefix => {
|
||
do {
|
||
prefix += Math.floor(Math.random() * MAX_UID);
|
||
} while (document.getElementById(prefix));
|
||
return prefix;
|
||
};
|
||
const getTransitionDurationFromElement = element => {
|
||
if (!element) {
|
||
return 0;
|
||
}
|
||
|
||
// Get transition-duration of the element
|
||
let {
|
||
transitionDuration,
|
||
transitionDelay
|
||
} = window.getComputedStyle(element);
|
||
const floatTransitionDuration = Number.parseFloat(transitionDuration);
|
||
const floatTransitionDelay = Number.parseFloat(transitionDelay);
|
||
|
||
// Return 0 if element or transition duration is not found
|
||
if (!floatTransitionDuration && !floatTransitionDelay) {
|
||
return 0;
|
||
}
|
||
|
||
// If multiple durations are defined, take the first
|
||
transitionDuration = transitionDuration.split(',')[0];
|
||
transitionDelay = transitionDelay.split(',')[0];
|
||
return (Number.parseFloat(transitionDuration) + Number.parseFloat(transitionDelay)) * MILLISECONDS_MULTIPLIER;
|
||
};
|
||
const triggerTransitionEnd = element => {
|
||
element.dispatchEvent(new Event(TRANSITION_END));
|
||
};
|
||
const isElement$1 = object => {
|
||
if (!object || typeof object !== 'object') {
|
||
return false;
|
||
}
|
||
if (typeof object.jquery !== 'undefined') {
|
||
object = object[0];
|
||
}
|
||
return typeof object.nodeType !== 'undefined';
|
||
};
|
||
const getElement = object => {
|
||
// it's a jQuery object or a node element
|
||
if (isElement$1(object)) {
|
||
return object.jquery ? object[0] : object;
|
||
}
|
||
if (typeof object === 'string' && object.length > 0) {
|
||
return document.querySelector(parseSelector(object));
|
||
}
|
||
return null;
|
||
};
|
||
const isVisible = element => {
|
||
if (!isElement$1(element) || element.getClientRects().length === 0) {
|
||
return false;
|
||
}
|
||
const elementIsVisible = getComputedStyle(element).getPropertyValue('visibility') === 'visible';
|
||
// Handle `details` element as its content may falsie appear visible when it is closed
|
||
const closedDetails = element.closest('details:not([open])');
|
||
if (!closedDetails) {
|
||
return elementIsVisible;
|
||
}
|
||
if (closedDetails !== element) {
|
||
const summary = element.closest('summary');
|
||
if (summary && summary.parentNode !== closedDetails) {
|
||
return false;
|
||
}
|
||
if (summary === null) {
|
||
return false;
|
||
}
|
||
}
|
||
return elementIsVisible;
|
||
};
|
||
const isDisabled = element => {
|
||
if (!element || element.nodeType !== Node.ELEMENT_NODE) {
|
||
return true;
|
||
}
|
||
if (element.classList.contains('disabled')) {
|
||
return true;
|
||
}
|
||
if (typeof element.disabled !== 'undefined') {
|
||
return element.disabled;
|
||
}
|
||
return element.hasAttribute('disabled') && element.getAttribute('disabled') !== 'false';
|
||
};
|
||
const findShadowRoot = element => {
|
||
if (!document.documentElement.attachShadow) {
|
||
return null;
|
||
}
|
||
|
||
// Can find the shadow root otherwise it'll return the document
|
||
if (typeof element.getRootNode === 'function') {
|
||
const root = element.getRootNode();
|
||
return root instanceof ShadowRoot ? root : null;
|
||
}
|
||
if (element instanceof ShadowRoot) {
|
||
return element;
|
||
}
|
||
|
||
// when we don't find a shadow root
|
||
if (!element.parentNode) {
|
||
return null;
|
||
}
|
||
return findShadowRoot(element.parentNode);
|
||
};
|
||
const noop = () => {};
|
||
|
||
/**
|
||
* Trick to restart an element's animation
|
||
*
|
||
* @param {HTMLElement} element
|
||
* @return void
|
||
*
|
||
* @see https://www.charistheo.io/blog/2021/02/restart-a-css-animation-with-javascript/#restarting-a-css-animation
|
||
*/
|
||
const reflow = element => {
|
||
element.offsetHeight; // eslint-disable-line no-unused-expressions
|
||
};
|
||
const getjQuery = () => {
|
||
if (window.jQuery && !document.body.hasAttribute('data-bs-no-jquery')) {
|
||
return window.jQuery;
|
||
}
|
||
return null;
|
||
};
|
||
const DOMContentLoadedCallbacks = [];
|
||
const onDOMContentLoaded = callback => {
|
||
if (document.readyState === 'loading') {
|
||
// add listener on the first call when the document is in loading state
|
||
if (!DOMContentLoadedCallbacks.length) {
|
||
document.addEventListener('DOMContentLoaded', () => {
|
||
for (const callback of DOMContentLoadedCallbacks) {
|
||
callback();
|
||
}
|
||
});
|
||
}
|
||
DOMContentLoadedCallbacks.push(callback);
|
||
} else {
|
||
callback();
|
||
}
|
||
};
|
||
const isRTL = () => document.documentElement.dir === 'rtl';
|
||
const defineJQueryPlugin = plugin => {
|
||
onDOMContentLoaded(() => {
|
||
const $ = getjQuery();
|
||
/* istanbul ignore if */
|
||
if ($) {
|
||
const name = plugin.NAME;
|
||
const JQUERY_NO_CONFLICT = $.fn[name];
|
||
$.fn[name] = plugin.jQueryInterface;
|
||
$.fn[name].Constructor = plugin;
|
||
$.fn[name].noConflict = () => {
|
||
$.fn[name] = JQUERY_NO_CONFLICT;
|
||
return plugin.jQueryInterface;
|
||
};
|
||
}
|
||
});
|
||
};
|
||
const execute = function (possibleCallback) {
|
||
let args = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
|
||
let defaultValue = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : possibleCallback;
|
||
return typeof possibleCallback === 'function' ? possibleCallback(...args) : defaultValue;
|
||
};
|
||
const executeAfterTransition = function (callback, transitionElement) {
|
||
let waitForTransition = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
|
||
if (!waitForTransition) {
|
||
execute(callback);
|
||
return;
|
||
}
|
||
const durationPadding = 5;
|
||
const emulatedDuration = getTransitionDurationFromElement(transitionElement) + durationPadding;
|
||
let called = false;
|
||
const handler = _ref6 => {
|
||
let {
|
||
target
|
||
} = _ref6;
|
||
if (target !== transitionElement) {
|
||
return;
|
||
}
|
||
called = true;
|
||
transitionElement.removeEventListener(TRANSITION_END, handler);
|
||
execute(callback);
|
||
};
|
||
transitionElement.addEventListener(TRANSITION_END, handler);
|
||
setTimeout(() => {
|
||
if (!called) {
|
||
triggerTransitionEnd(transitionElement);
|
||
}
|
||
}, emulatedDuration);
|
||
};
|
||
|
||
/**
|
||
* Return the previous/next element of a list.
|
||
*
|
||
* @param {array} list The list of elements
|
||
* @param activeElement The active element
|
||
* @param shouldGetNext Choose to get next or previous element
|
||
* @param isCycleAllowed
|
||
* @return {Element|elem} The proper element
|
||
*/
|
||
const getNextActiveElement = (list, activeElement, shouldGetNext, isCycleAllowed) => {
|
||
const listLength = list.length;
|
||
let index = list.indexOf(activeElement);
|
||
|
||
// if the element does not exist in the list return an element
|
||
// depending on the direction and if cycle is allowed
|
||
if (index === -1) {
|
||
return !shouldGetNext && isCycleAllowed ? list[listLength - 1] : list[0];
|
||
}
|
||
index += shouldGetNext ? 1 : -1;
|
||
if (isCycleAllowed) {
|
||
index = (index + listLength) % listLength;
|
||
}
|
||
return list[Math.max(0, Math.min(index, listLength - 1))];
|
||
};
|
||
|
||
/**
|
||
* --------------------------------------------------------------------------
|
||
* Bootstrap dom/event-handler.js
|
||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||
* --------------------------------------------------------------------------
|
||
*/
|
||
|
||
/**
|
||
* Constants
|
||
*/
|
||
|
||
const namespaceRegex = /[^.]*(?=\..*)\.|.*/;
|
||
const stripNameRegex = /\..*/;
|
||
const stripUidRegex = /::\d+$/;
|
||
const eventRegistry = {}; // Events storage
|
||
let uidEvent = 1;
|
||
const customEvents = {
|
||
mouseenter: 'mouseover',
|
||
mouseleave: 'mouseout'
|
||
};
|
||
const nativeEvents = new Set(['click', 'dblclick', 'mouseup', 'mousedown', 'contextmenu', 'mousewheel', 'DOMMouseScroll', 'mouseover', 'mouseout', 'mousemove', 'selectstart', 'selectend', 'keydown', 'keypress', 'keyup', 'orientationchange', 'touchstart', 'touchmove', 'touchend', 'touchcancel', 'pointerdown', 'pointermove', 'pointerup', 'pointerleave', 'pointercancel', 'gesturestart', 'gesturechange', 'gestureend', 'focus', 'blur', 'change', 'reset', 'select', 'submit', 'focusin', 'focusout', 'load', 'unload', 'beforeunload', 'resize', 'move', 'DOMContentLoaded', 'readystatechange', 'error', 'abort', 'scroll']);
|
||
|
||
/**
|
||
* Private methods
|
||
*/
|
||
|
||
function makeEventUid(element, uid) {
|
||
return uid && `${uid}::${uidEvent++}` || element.uidEvent || uidEvent++;
|
||
}
|
||
function getElementEvents(element) {
|
||
const uid = makeEventUid(element);
|
||
element.uidEvent = uid;
|
||
eventRegistry[uid] = eventRegistry[uid] || {};
|
||
return eventRegistry[uid];
|
||
}
|
||
function bootstrapHandler(element, fn) {
|
||
return function handler(event) {
|
||
hydrateObj(event, {
|
||
delegateTarget: element
|
||
});
|
||
if (handler.oneOff) {
|
||
EventHandler.off(element, event.type, fn);
|
||
}
|
||
return fn.apply(element, [event]);
|
||
};
|
||
}
|
||
function bootstrapDelegationHandler(element, selector, fn) {
|
||
return function handler(event) {
|
||
const domElements = element.querySelectorAll(selector);
|
||
for (let {
|
||
target
|
||
} = event; target && target !== this; target = target.parentNode) {
|
||
for (const domElement of domElements) {
|
||
if (domElement !== target) {
|
||
continue;
|
||
}
|
||
hydrateObj(event, {
|
||
delegateTarget: target
|
||
});
|
||
if (handler.oneOff) {
|
||
EventHandler.off(element, event.type, selector, fn);
|
||
}
|
||
return fn.apply(target, [event]);
|
||
}
|
||
}
|
||
};
|
||
}
|
||
function findHandler(events, callable) {
|
||
let delegationSelector = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
|
||
return Object.values(events).find(event => event.callable === callable && event.delegationSelector === delegationSelector);
|
||
}
|
||
function normalizeParameters(originalTypeEvent, handler, delegationFunction) {
|
||
const isDelegated = typeof handler === 'string';
|
||
// TODO: tooltip passes `false` instead of selector, so we need to check
|
||
const callable = isDelegated ? delegationFunction : handler || delegationFunction;
|
||
let typeEvent = getTypeEvent(originalTypeEvent);
|
||
if (!nativeEvents.has(typeEvent)) {
|
||
typeEvent = originalTypeEvent;
|
||
}
|
||
return [isDelegated, callable, typeEvent];
|
||
}
|
||
function addHandler(element, originalTypeEvent, handler, delegationFunction, oneOff) {
|
||
if (typeof originalTypeEvent !== 'string' || !element) {
|
||
return;
|
||
}
|
||
let [isDelegated, callable, typeEvent] = normalizeParameters(originalTypeEvent, handler, delegationFunction);
|
||
|
||
// in case of mouseenter or mouseleave wrap the handler within a function that checks for its DOM position
|
||
// this prevents the handler from being dispatched the same way as mouseover or mouseout does
|
||
if (originalTypeEvent in customEvents) {
|
||
const wrapFunction = fn => {
|
||
return function (event) {
|
||
if (!event.relatedTarget || event.relatedTarget !== event.delegateTarget && !event.delegateTarget.contains(event.relatedTarget)) {
|
||
return fn.call(this, event);
|
||
}
|
||
};
|
||
};
|
||
callable = wrapFunction(callable);
|
||
}
|
||
const events = getElementEvents(element);
|
||
const handlers = events[typeEvent] || (events[typeEvent] = {});
|
||
const previousFunction = findHandler(handlers, callable, isDelegated ? handler : null);
|
||
if (previousFunction) {
|
||
previousFunction.oneOff = previousFunction.oneOff && oneOff;
|
||
return;
|
||
}
|
||
const uid = makeEventUid(callable, originalTypeEvent.replace(namespaceRegex, ''));
|
||
const fn = isDelegated ? bootstrapDelegationHandler(element, handler, callable) : bootstrapHandler(element, callable);
|
||
fn.delegationSelector = isDelegated ? handler : null;
|
||
fn.callable = callable;
|
||
fn.oneOff = oneOff;
|
||
fn.uidEvent = uid;
|
||
handlers[uid] = fn;
|
||
element.addEventListener(typeEvent, fn, isDelegated);
|
||
}
|
||
function removeHandler(element, events, typeEvent, handler, delegationSelector) {
|
||
const fn = findHandler(events[typeEvent], handler, delegationSelector);
|
||
if (!fn) {
|
||
return;
|
||
}
|
||
element.removeEventListener(typeEvent, fn, Boolean(delegationSelector));
|
||
delete events[typeEvent][fn.uidEvent];
|
||
}
|
||
function removeNamespacedHandlers(element, events, typeEvent, namespace) {
|
||
const storeElementEvent = events[typeEvent] || {};
|
||
for (const [handlerKey, event] of Object.entries(storeElementEvent)) {
|
||
if (handlerKey.includes(namespace)) {
|
||
removeHandler(element, events, typeEvent, event.callable, event.delegationSelector);
|
||
}
|
||
}
|
||
}
|
||
function getTypeEvent(event) {
|
||
// allow to get the native events from namespaced events ('click.bs.button' --> 'click')
|
||
event = event.replace(stripNameRegex, '');
|
||
return customEvents[event] || event;
|
||
}
|
||
const EventHandler = {
|
||
on(element, event, handler, delegationFunction) {
|
||
addHandler(element, event, handler, delegationFunction, false);
|
||
},
|
||
one(element, event, handler, delegationFunction) {
|
||
addHandler(element, event, handler, delegationFunction, true);
|
||
},
|
||
off(element, originalTypeEvent, handler, delegationFunction) {
|
||
if (typeof originalTypeEvent !== 'string' || !element) {
|
||
return;
|
||
}
|
||
const [isDelegated, callable, typeEvent] = normalizeParameters(originalTypeEvent, handler, delegationFunction);
|
||
const inNamespace = typeEvent !== originalTypeEvent;
|
||
const events = getElementEvents(element);
|
||
const storeElementEvent = events[typeEvent] || {};
|
||
const isNamespace = originalTypeEvent.startsWith('.');
|
||
if (typeof callable !== 'undefined') {
|
||
// Simplest case: handler is passed, remove that listener ONLY.
|
||
if (!Object.keys(storeElementEvent).length) {
|
||
return;
|
||
}
|
||
removeHandler(element, events, typeEvent, callable, isDelegated ? handler : null);
|
||
return;
|
||
}
|
||
if (isNamespace) {
|
||
for (const elementEvent of Object.keys(events)) {
|
||
removeNamespacedHandlers(element, events, elementEvent, originalTypeEvent.slice(1));
|
||
}
|
||
}
|
||
for (const [keyHandlers, event] of Object.entries(storeElementEvent)) {
|
||
const handlerKey = keyHandlers.replace(stripUidRegex, '');
|
||
if (!inNamespace || originalTypeEvent.includes(handlerKey)) {
|
||
removeHandler(element, events, typeEvent, event.callable, event.delegationSelector);
|
||
}
|
||
}
|
||
},
|
||
trigger(element, event, args) {
|
||
if (typeof event !== 'string' || !element) {
|
||
return null;
|
||
}
|
||
const $ = getjQuery();
|
||
const typeEvent = getTypeEvent(event);
|
||
const inNamespace = event !== typeEvent;
|
||
let jQueryEvent = null;
|
||
let bubbles = true;
|
||
let nativeDispatch = true;
|
||
let defaultPrevented = false;
|
||
if (inNamespace && $) {
|
||
jQueryEvent = $.Event(event, args);
|
||
$(element).trigger(jQueryEvent);
|
||
bubbles = !jQueryEvent.isPropagationStopped();
|
||
nativeDispatch = !jQueryEvent.isImmediatePropagationStopped();
|
||
defaultPrevented = jQueryEvent.isDefaultPrevented();
|
||
}
|
||
const evt = hydrateObj(new Event(event, {
|
||
bubbles,
|
||
cancelable: true
|
||
}), args);
|
||
if (defaultPrevented) {
|
||
evt.preventDefault();
|
||
}
|
||
if (nativeDispatch) {
|
||
element.dispatchEvent(evt);
|
||
}
|
||
if (evt.defaultPrevented && jQueryEvent) {
|
||
jQueryEvent.preventDefault();
|
||
}
|
||
return evt;
|
||
}
|
||
};
|
||
function hydrateObj(obj) {
|
||
let meta = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
||
for (const [key, value] of Object.entries(meta)) {
|
||
try {
|
||
obj[key] = value;
|
||
} catch (_unused) {
|
||
Object.defineProperty(obj, key, {
|
||
configurable: true,
|
||
get() {
|
||
return value;
|
||
}
|
||
});
|
||
}
|
||
}
|
||
return obj;
|
||
}
|
||
|
||
/**
|
||
* --------------------------------------------------------------------------
|
||
* Bootstrap dom/manipulator.js
|
||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||
* --------------------------------------------------------------------------
|
||
*/
|
||
|
||
function normalizeData(value) {
|
||
if (value === 'true') {
|
||
return true;
|
||
}
|
||
if (value === 'false') {
|
||
return false;
|
||
}
|
||
if (value === Number(value).toString()) {
|
||
return Number(value);
|
||
}
|
||
if (value === '' || value === 'null') {
|
||
return null;
|
||
}
|
||
if (typeof value !== 'string') {
|
||
return value;
|
||
}
|
||
try {
|
||
return JSON.parse(decodeURIComponent(value));
|
||
} catch (_unused) {
|
||
return value;
|
||
}
|
||
}
|
||
function normalizeDataKey(key) {
|
||
return key.replace(/[A-Z]/g, chr => `-${chr.toLowerCase()}`);
|
||
}
|
||
const Manipulator = {
|
||
setDataAttribute(element, key, value) {
|
||
element.setAttribute(`data-bs-${normalizeDataKey(key)}`, value);
|
||
},
|
||
removeDataAttribute(element, key) {
|
||
element.removeAttribute(`data-bs-${normalizeDataKey(key)}`);
|
||
},
|
||
getDataAttributes(element) {
|
||
if (!element) {
|
||
return {};
|
||
}
|
||
const attributes = {};
|
||
const bsKeys = Object.keys(element.dataset).filter(key => key.startsWith('bs') && !key.startsWith('bsConfig'));
|
||
for (const key of bsKeys) {
|
||
let pureKey = key.replace(/^bs/, '');
|
||
pureKey = pureKey.charAt(0).toLowerCase() + pureKey.slice(1, pureKey.length);
|
||
attributes[pureKey] = normalizeData(element.dataset[key]);
|
||
}
|
||
return attributes;
|
||
},
|
||
getDataAttribute(element, key) {
|
||
return normalizeData(element.getAttribute(`data-bs-${normalizeDataKey(key)}`));
|
||
}
|
||
};
|
||
|
||
/**
|
||
* --------------------------------------------------------------------------
|
||
* Bootstrap util/config.js
|
||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||
* --------------------------------------------------------------------------
|
||
*/
|
||
|
||
/**
|
||
* Class definition
|
||
*/
|
||
|
||
class Config {
|
||
// Getters
|
||
static get Default() {
|
||
return {};
|
||
}
|
||
static get DefaultType() {
|
||
return {};
|
||
}
|
||
static get NAME() {
|
||
throw new Error('You have to implement the static method "NAME", for each component!');
|
||
}
|
||
_getConfig(config) {
|
||
config = this._mergeConfigObj(config);
|
||
config = this._configAfterMerge(config);
|
||
this._typeCheckConfig(config);
|
||
return config;
|
||
}
|
||
_configAfterMerge(config) {
|
||
return config;
|
||
}
|
||
_mergeConfigObj(config, element) {
|
||
const jsonConfig = isElement$1(element) ? Manipulator.getDataAttribute(element, 'config') : {}; // try to parse
|
||
|
||
return {
|
||
...this.constructor.Default,
|
||
...(typeof jsonConfig === 'object' ? jsonConfig : {}),
|
||
...(isElement$1(element) ? Manipulator.getDataAttributes(element) : {}),
|
||
...(typeof config === 'object' ? config : {})
|
||
};
|
||
}
|
||
_typeCheckConfig(config) {
|
||
let configTypes = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.constructor.DefaultType;
|
||
for (const [property, expectedTypes] of Object.entries(configTypes)) {
|
||
const value = config[property];
|
||
const valueType = isElement$1(value) ? 'element' : toType(value);
|
||
if (!new RegExp(expectedTypes).test(valueType)) {
|
||
throw new TypeError(`${this.constructor.NAME.toUpperCase()}: Option "${property}" provided type "${valueType}" but expected type "${expectedTypes}".`);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* --------------------------------------------------------------------------
|
||
* Bootstrap base-component.js
|
||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||
* --------------------------------------------------------------------------
|
||
*/
|
||
|
||
/**
|
||
* Constants
|
||
*/
|
||
|
||
const VERSION = '5.3.3';
|
||
|
||
/**
|
||
* Class definition
|
||
*/
|
||
|
||
class BaseComponent extends Config {
|
||
constructor(element, config) {
|
||
super();
|
||
element = getElement(element);
|
||
if (!element) {
|
||
return;
|
||
}
|
||
this._element = element;
|
||
this._config = this._getConfig(config);
|
||
Data.set(this._element, this.constructor.DATA_KEY, this);
|
||
}
|
||
|
||
// Public
|
||
dispose() {
|
||
Data.remove(this._element, this.constructor.DATA_KEY);
|
||
EventHandler.off(this._element, this.constructor.EVENT_KEY);
|
||
for (const propertyName of Object.getOwnPropertyNames(this)) {
|
||
this[propertyName] = null;
|
||
}
|
||
}
|
||
_queueCallback(callback, element) {
|
||
let isAnimated = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
|
||
executeAfterTransition(callback, element, isAnimated);
|
||
}
|
||
_getConfig(config) {
|
||
config = this._mergeConfigObj(config, this._element);
|
||
config = this._configAfterMerge(config);
|
||
this._typeCheckConfig(config);
|
||
return config;
|
||
}
|
||
|
||
// Static
|
||
static getInstance(element) {
|
||
return Data.get(getElement(element), this.DATA_KEY);
|
||
}
|
||
static getOrCreateInstance(element) {
|
||
let config = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
||
return this.getInstance(element) || new this(element, typeof config === 'object' ? config : null);
|
||
}
|
||
static get VERSION() {
|
||
return VERSION;
|
||
}
|
||
static get DATA_KEY() {
|
||
return `bs.${this.NAME}`;
|
||
}
|
||
static get EVENT_KEY() {
|
||
return `.${this.DATA_KEY}`;
|
||
}
|
||
static eventName(name) {
|
||
return `${name}${this.EVENT_KEY}`;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* --------------------------------------------------------------------------
|
||
* Bootstrap dom/selector-engine.js
|
||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||
* --------------------------------------------------------------------------
|
||
*/
|
||
|
||
const getSelector = element => {
|
||
let selector = element.getAttribute('data-bs-target');
|
||
if (!selector || selector === '#') {
|
||
let hrefAttribute = element.getAttribute('href');
|
||
|
||
// The only valid content that could double as a selector are IDs or classes,
|
||
// so everything starting with `#` or `.`. If a "real" URL is used as the selector,
|
||
// `document.querySelector` will rightfully complain it is invalid.
|
||
// See https://github.com/twbs/bootstrap/issues/32273
|
||
if (!hrefAttribute || !hrefAttribute.includes('#') && !hrefAttribute.startsWith('.')) {
|
||
return null;
|
||
}
|
||
|
||
// Just in case some CMS puts out a full URL with the anchor appended
|
||
if (hrefAttribute.includes('#') && !hrefAttribute.startsWith('#')) {
|
||
hrefAttribute = `#${hrefAttribute.split('#')[1]}`;
|
||
}
|
||
selector = hrefAttribute && hrefAttribute !== '#' ? hrefAttribute.trim() : null;
|
||
}
|
||
return selector ? selector.split(',').map(sel => parseSelector(sel)).join(',') : null;
|
||
};
|
||
const SelectorEngine = {
|
||
find(selector) {
|
||
let element = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : document.documentElement;
|
||
return [].concat(...Element.prototype.querySelectorAll.call(element, selector));
|
||
},
|
||
findOne(selector) {
|
||
let element = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : document.documentElement;
|
||
return Element.prototype.querySelector.call(element, selector);
|
||
},
|
||
children(element, selector) {
|
||
return [].concat(...element.children).filter(child => child.matches(selector));
|
||
},
|
||
parents(element, selector) {
|
||
const parents = [];
|
||
let ancestor = element.parentNode.closest(selector);
|
||
while (ancestor) {
|
||
parents.push(ancestor);
|
||
ancestor = ancestor.parentNode.closest(selector);
|
||
}
|
||
return parents;
|
||
},
|
||
prev(element, selector) {
|
||
let previous = element.previousElementSibling;
|
||
while (previous) {
|
||
if (previous.matches(selector)) {
|
||
return [previous];
|
||
}
|
||
previous = previous.previousElementSibling;
|
||
}
|
||
return [];
|
||
},
|
||
// TODO: this is now unused; remove later along with prev()
|
||
next(element, selector) {
|
||
let next = element.nextElementSibling;
|
||
while (next) {
|
||
if (next.matches(selector)) {
|
||
return [next];
|
||
}
|
||
next = next.nextElementSibling;
|
||
}
|
||
return [];
|
||
},
|
||
focusableChildren(element) {
|
||
const focusables = ['a', 'button', 'input', 'textarea', 'select', 'details', '[tabindex]', '[contenteditable="true"]'].map(selector => `${selector}:not([tabindex^="-"])`).join(',');
|
||
return this.find(focusables, element).filter(el => !isDisabled(el) && isVisible(el));
|
||
},
|
||
getSelectorFromElement(element) {
|
||
const selector = getSelector(element);
|
||
if (selector) {
|
||
return SelectorEngine.findOne(selector) ? selector : null;
|
||
}
|
||
return null;
|
||
},
|
||
getElementFromSelector(element) {
|
||
const selector = getSelector(element);
|
||
return selector ? SelectorEngine.findOne(selector) : null;
|
||
},
|
||
getMultipleElementsFromSelector(element) {
|
||
const selector = getSelector(element);
|
||
return selector ? SelectorEngine.find(selector) : [];
|
||
}
|
||
};
|
||
|
||
/**
|
||
* --------------------------------------------------------------------------
|
||
* Bootstrap util/component-functions.js
|
||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||
* --------------------------------------------------------------------------
|
||
*/
|
||
|
||
const enableDismissTrigger = function (component) {
|
||
let method = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'hide';
|
||
const clickEvent = `click.dismiss${component.EVENT_KEY}`;
|
||
const name = component.NAME;
|
||
EventHandler.on(document, clickEvent, `[data-bs-dismiss="${name}"]`, function (event) {
|
||
if (['A', 'AREA'].includes(this.tagName)) {
|
||
event.preventDefault();
|
||
}
|
||
if (isDisabled(this)) {
|
||
return;
|
||
}
|
||
const target = SelectorEngine.getElementFromSelector(this) || this.closest(`.${name}`);
|
||
const instance = component.getOrCreateInstance(target);
|
||
|
||
// Method argument is left, for Alert and only, as it doesn't implement the 'hide' method
|
||
instance[method]();
|
||
});
|
||
};
|
||
|
||
/**
|
||
* --------------------------------------------------------------------------
|
||
* Bootstrap alert.js
|
||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||
* --------------------------------------------------------------------------
|
||
*/
|
||
|
||
/**
|
||
* Constants
|
||
*/
|
||
|
||
const NAME$f = 'alert';
|
||
const DATA_KEY$a = 'bs.alert';
|
||
const EVENT_KEY$b = `.${DATA_KEY$a}`;
|
||
const EVENT_CLOSE = `close${EVENT_KEY$b}`;
|
||
const EVENT_CLOSED = `closed${EVENT_KEY$b}`;
|
||
const CLASS_NAME_FADE$5 = 'fade';
|
||
const CLASS_NAME_SHOW$8 = 'show';
|
||
|
||
/**
|
||
* Class definition
|
||
*/
|
||
|
||
class Alert extends BaseComponent {
|
||
// Getters
|
||
static get NAME() {
|
||
return NAME$f;
|
||
}
|
||
|
||
// Public
|
||
close() {
|
||
const closeEvent = EventHandler.trigger(this._element, EVENT_CLOSE);
|
||
if (closeEvent.defaultPrevented) {
|
||
return;
|
||
}
|
||
this._element.classList.remove(CLASS_NAME_SHOW$8);
|
||
const isAnimated = this._element.classList.contains(CLASS_NAME_FADE$5);
|
||
this._queueCallback(() => this._destroyElement(), this._element, isAnimated);
|
||
}
|
||
|
||
// Private
|
||
_destroyElement() {
|
||
this._element.remove();
|
||
EventHandler.trigger(this._element, EVENT_CLOSED);
|
||
this.dispose();
|
||
}
|
||
|
||
// Static
|
||
static jQueryInterface(config) {
|
||
return this.each(function () {
|
||
const data = Alert.getOrCreateInstance(this);
|
||
if (typeof config !== 'string') {
|
||
return;
|
||
}
|
||
if (data[config] === undefined || config.startsWith('_') || config === 'constructor') {
|
||
throw new TypeError(`No method named "${config}"`);
|
||
}
|
||
data[config](this);
|
||
});
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Data API implementation
|
||
*/
|
||
|
||
enableDismissTrigger(Alert, 'close');
|
||
|
||
/**
|
||
* jQuery
|
||
*/
|
||
|
||
defineJQueryPlugin(Alert);
|
||
|
||
/**
|
||
* --------------------------------------------------------------------------
|
||
* Bootstrap button.js
|
||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||
* --------------------------------------------------------------------------
|
||
*/
|
||
|
||
/**
|
||
* Constants
|
||
*/
|
||
|
||
const NAME$e = 'button';
|
||
const DATA_KEY$9 = 'bs.button';
|
||
const EVENT_KEY$a = `.${DATA_KEY$9}`;
|
||
const DATA_API_KEY$6 = '.data-api';
|
||
const CLASS_NAME_ACTIVE$3 = 'active';
|
||
const SELECTOR_DATA_TOGGLE$5 = '[data-bs-toggle="button"]';
|
||
const EVENT_CLICK_DATA_API$6 = `click${EVENT_KEY$a}${DATA_API_KEY$6}`;
|
||
|
||
/**
|
||
* Class definition
|
||
*/
|
||
|
||
class Button extends BaseComponent {
|
||
// Getters
|
||
static get NAME() {
|
||
return NAME$e;
|
||
}
|
||
|
||
// Public
|
||
toggle() {
|
||
// Toggle class and sync the `aria-pressed` attribute with the return value of the `.toggle()` method
|
||
this._element.setAttribute('aria-pressed', this._element.classList.toggle(CLASS_NAME_ACTIVE$3));
|
||
}
|
||
|
||
// Static
|
||
static jQueryInterface(config) {
|
||
return this.each(function () {
|
||
const data = Button.getOrCreateInstance(this);
|
||
if (config === 'toggle') {
|
||
data[config]();
|
||
}
|
||
});
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Data API implementation
|
||
*/
|
||
|
||
EventHandler.on(document, EVENT_CLICK_DATA_API$6, SELECTOR_DATA_TOGGLE$5, event => {
|
||
event.preventDefault();
|
||
const button = event.target.closest(SELECTOR_DATA_TOGGLE$5);
|
||
const data = Button.getOrCreateInstance(button);
|
||
data.toggle();
|
||
});
|
||
|
||
/**
|
||
* jQuery
|
||
*/
|
||
|
||
defineJQueryPlugin(Button);
|
||
|
||
/**
|
||
* --------------------------------------------------------------------------
|
||
* Bootstrap util/swipe.js
|
||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||
* --------------------------------------------------------------------------
|
||
*/
|
||
|
||
/**
|
||
* Constants
|
||
*/
|
||
|
||
const NAME$d = 'swipe';
|
||
const EVENT_KEY$9 = '.bs.swipe';
|
||
const EVENT_TOUCHSTART = `touchstart${EVENT_KEY$9}`;
|
||
const EVENT_TOUCHMOVE = `touchmove${EVENT_KEY$9}`;
|
||
const EVENT_TOUCHEND = `touchend${EVENT_KEY$9}`;
|
||
const EVENT_POINTERDOWN = `pointerdown${EVENT_KEY$9}`;
|
||
const EVENT_POINTERUP = `pointerup${EVENT_KEY$9}`;
|
||
const POINTER_TYPE_TOUCH = 'touch';
|
||
const POINTER_TYPE_PEN = 'pen';
|
||
const CLASS_NAME_POINTER_EVENT = 'pointer-event';
|
||
const SWIPE_THRESHOLD = 40;
|
||
const Default$c = {
|
||
endCallback: null,
|
||
leftCallback: null,
|
||
rightCallback: null
|
||
};
|
||
const DefaultType$c = {
|
||
endCallback: '(function|null)',
|
||
leftCallback: '(function|null)',
|
||
rightCallback: '(function|null)'
|
||
};
|
||
|
||
/**
|
||
* Class definition
|
||
*/
|
||
|
||
class Swipe extends Config {
|
||
constructor(element, config) {
|
||
super();
|
||
this._element = element;
|
||
if (!element || !Swipe.isSupported()) {
|
||
return;
|
||
}
|
||
this._config = this._getConfig(config);
|
||
this._deltaX = 0;
|
||
this._supportPointerEvents = Boolean(window.PointerEvent);
|
||
this._initEvents();
|
||
}
|
||
|
||
// Getters
|
||
static get Default() {
|
||
return Default$c;
|
||
}
|
||
static get DefaultType() {
|
||
return DefaultType$c;
|
||
}
|
||
static get NAME() {
|
||
return NAME$d;
|
||
}
|
||
|
||
// Public
|
||
dispose() {
|
||
EventHandler.off(this._element, EVENT_KEY$9);
|
||
}
|
||
|
||
// Private
|
||
_start(event) {
|
||
if (!this._supportPointerEvents) {
|
||
this._deltaX = event.touches[0].clientX;
|
||
return;
|
||
}
|
||
if (this._eventIsPointerPenTouch(event)) {
|
||
this._deltaX = event.clientX;
|
||
}
|
||
}
|
||
_end(event) {
|
||
if (this._eventIsPointerPenTouch(event)) {
|
||
this._deltaX = event.clientX - this._deltaX;
|
||
}
|
||
this._handleSwipe();
|
||
execute(this._config.endCallback);
|
||
}
|
||
_move(event) {
|
||
this._deltaX = event.touches && event.touches.length > 1 ? 0 : event.touches[0].clientX - this._deltaX;
|
||
}
|
||
_handleSwipe() {
|
||
const absDeltaX = Math.abs(this._deltaX);
|
||
if (absDeltaX <= SWIPE_THRESHOLD) {
|
||
return;
|
||
}
|
||
const direction = absDeltaX / this._deltaX;
|
||
this._deltaX = 0;
|
||
if (!direction) {
|
||
return;
|
||
}
|
||
execute(direction > 0 ? this._config.rightCallback : this._config.leftCallback);
|
||
}
|
||
_initEvents() {
|
||
if (this._supportPointerEvents) {
|
||
EventHandler.on(this._element, EVENT_POINTERDOWN, event => this._start(event));
|
||
EventHandler.on(this._element, EVENT_POINTERUP, event => this._end(event));
|
||
this._element.classList.add(CLASS_NAME_POINTER_EVENT);
|
||
} else {
|
||
EventHandler.on(this._element, EVENT_TOUCHSTART, event => this._start(event));
|
||
EventHandler.on(this._element, EVENT_TOUCHMOVE, event => this._move(event));
|
||
EventHandler.on(this._element, EVENT_TOUCHEND, event => this._end(event));
|
||
}
|
||
}
|
||
_eventIsPointerPenTouch(event) {
|
||
return this._supportPointerEvents && (event.pointerType === POINTER_TYPE_PEN || event.pointerType === POINTER_TYPE_TOUCH);
|
||
}
|
||
|
||
// Static
|
||
static isSupported() {
|
||
return 'ontouchstart' in document.documentElement || navigator.maxTouchPoints > 0;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* --------------------------------------------------------------------------
|
||
* Bootstrap carousel.js
|
||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||
* --------------------------------------------------------------------------
|
||
*/
|
||
|
||
/**
|
||
* Constants
|
||
*/
|
||
|
||
const NAME$c = 'carousel';
|
||
const DATA_KEY$8 = 'bs.carousel';
|
||
const EVENT_KEY$8 = `.${DATA_KEY$8}`;
|
||
const DATA_API_KEY$5 = '.data-api';
|
||
const ARROW_LEFT_KEY$1 = 'ArrowLeft';
|
||
const ARROW_RIGHT_KEY$1 = 'ArrowRight';
|
||
const TOUCHEVENT_COMPAT_WAIT = 500; // Time for mouse compat events to fire after touch
|
||
|
||
const ORDER_NEXT = 'next';
|
||
const ORDER_PREV = 'prev';
|
||
const DIRECTION_LEFT = 'left';
|
||
const DIRECTION_RIGHT = 'right';
|
||
const EVENT_SLIDE = `slide${EVENT_KEY$8}`;
|
||
const EVENT_SLID = `slid${EVENT_KEY$8}`;
|
||
const EVENT_KEYDOWN$1 = `keydown${EVENT_KEY$8}`;
|
||
const EVENT_MOUSEENTER$1 = `mouseenter${EVENT_KEY$8}`;
|
||
const EVENT_MOUSELEAVE$1 = `mouseleave${EVENT_KEY$8}`;
|
||
const EVENT_DRAG_START = `dragstart${EVENT_KEY$8}`;
|
||
const EVENT_LOAD_DATA_API$3 = `load${EVENT_KEY$8}${DATA_API_KEY$5}`;
|
||
const EVENT_CLICK_DATA_API$5 = `click${EVENT_KEY$8}${DATA_API_KEY$5}`;
|
||
const CLASS_NAME_CAROUSEL = 'carousel';
|
||
const CLASS_NAME_ACTIVE$2 = 'active';
|
||
const CLASS_NAME_SLIDE = 'slide';
|
||
const CLASS_NAME_END = 'carousel-item-end';
|
||
const CLASS_NAME_START = 'carousel-item-start';
|
||
const CLASS_NAME_NEXT = 'carousel-item-next';
|
||
const CLASS_NAME_PREV = 'carousel-item-prev';
|
||
const SELECTOR_ACTIVE = '.active';
|
||
const SELECTOR_ITEM = '.carousel-item';
|
||
const SELECTOR_ACTIVE_ITEM = SELECTOR_ACTIVE + SELECTOR_ITEM;
|
||
const SELECTOR_ITEM_IMG = '.carousel-item img';
|
||
const SELECTOR_INDICATORS = '.carousel-indicators';
|
||
const SELECTOR_DATA_SLIDE = '[data-bs-slide], [data-bs-slide-to]';
|
||
const SELECTOR_DATA_RIDE = '[data-bs-ride="carousel"]';
|
||
const KEY_TO_DIRECTION = {
|
||
[ARROW_LEFT_KEY$1]: DIRECTION_RIGHT,
|
||
[ARROW_RIGHT_KEY$1]: DIRECTION_LEFT
|
||
};
|
||
const Default$b = {
|
||
interval: 5000,
|
||
keyboard: true,
|
||
pause: 'hover',
|
||
ride: false,
|
||
touch: true,
|
||
wrap: true
|
||
};
|
||
const DefaultType$b = {
|
||
interval: '(number|boolean)',
|
||
// TODO:v6 remove boolean support
|
||
keyboard: 'boolean',
|
||
pause: '(string|boolean)',
|
||
ride: '(boolean|string)',
|
||
touch: 'boolean',
|
||
wrap: 'boolean'
|
||
};
|
||
|
||
/**
|
||
* Class definition
|
||
*/
|
||
|
||
class Carousel extends BaseComponent {
|
||
constructor(element, config) {
|
||
super(element, config);
|
||
this._interval = null;
|
||
this._activeElement = null;
|
||
this._isSliding = false;
|
||
this.touchTimeout = null;
|
||
this._swipeHelper = null;
|
||
this._indicatorsElement = SelectorEngine.findOne(SELECTOR_INDICATORS, this._element);
|
||
this._addEventListeners();
|
||
if (this._config.ride === CLASS_NAME_CAROUSEL) {
|
||
this.cycle();
|
||
}
|
||
}
|
||
|
||
// Getters
|
||
static get Default() {
|
||
return Default$b;
|
||
}
|
||
static get DefaultType() {
|
||
return DefaultType$b;
|
||
}
|
||
static get NAME() {
|
||
return NAME$c;
|
||
}
|
||
|
||
// Public
|
||
next() {
|
||
this._slide(ORDER_NEXT);
|
||
}
|
||
nextWhenVisible() {
|
||
// FIXME TODO use `document.visibilityState`
|
||
// Don't call next when the page isn't visible
|
||
// or the carousel or its parent isn't visible
|
||
if (!document.hidden && isVisible(this._element)) {
|
||
this.next();
|
||
}
|
||
}
|
||
prev() {
|
||
this._slide(ORDER_PREV);
|
||
}
|
||
pause() {
|
||
if (this._isSliding) {
|
||
triggerTransitionEnd(this._element);
|
||
}
|
||
this._clearInterval();
|
||
}
|
||
cycle() {
|
||
this._clearInterval();
|
||
this._updateInterval();
|
||
this._interval = setInterval(() => this.nextWhenVisible(), this._config.interval);
|
||
}
|
||
_maybeEnableCycle() {
|
||
if (!this._config.ride) {
|
||
return;
|
||
}
|
||
if (this._isSliding) {
|
||
EventHandler.one(this._element, EVENT_SLID, () => this.cycle());
|
||
return;
|
||
}
|
||
this.cycle();
|
||
}
|
||
to(index) {
|
||
const items = this._getItems();
|
||
if (index > items.length - 1 || index < 0) {
|
||
return;
|
||
}
|
||
if (this._isSliding) {
|
||
EventHandler.one(this._element, EVENT_SLID, () => this.to(index));
|
||
return;
|
||
}
|
||
const activeIndex = this._getItemIndex(this._getActive());
|
||
if (activeIndex === index) {
|
||
return;
|
||
}
|
||
const order = index > activeIndex ? ORDER_NEXT : ORDER_PREV;
|
||
this._slide(order, items[index]);
|
||
}
|
||
dispose() {
|
||
if (this._swipeHelper) {
|
||
this._swipeHelper.dispose();
|
||
}
|
||
super.dispose();
|
||
}
|
||
|
||
// Private
|
||
_configAfterMerge(config) {
|
||
config.defaultInterval = config.interval;
|
||
return config;
|
||
}
|
||
_addEventListeners() {
|
||
if (this._config.keyboard) {
|
||
EventHandler.on(this._element, EVENT_KEYDOWN$1, event => this._keydown(event));
|
||
}
|
||
if (this._config.pause === 'hover') {
|
||
EventHandler.on(this._element, EVENT_MOUSEENTER$1, () => this.pause());
|
||
EventHandler.on(this._element, EVENT_MOUSELEAVE$1, () => this._maybeEnableCycle());
|
||
}
|
||
if (this._config.touch && Swipe.isSupported()) {
|
||
this._addTouchEventListeners();
|
||
}
|
||
}
|
||
_addTouchEventListeners() {
|
||
for (const img of SelectorEngine.find(SELECTOR_ITEM_IMG, this._element)) {
|
||
EventHandler.on(img, EVENT_DRAG_START, event => event.preventDefault());
|
||
}
|
||
const endCallBack = () => {
|
||
if (this._config.pause !== 'hover') {
|
||
return;
|
||
}
|
||
|
||
// If it's a touch-enabled device, mouseenter/leave are fired as
|
||
// part of the mouse compatibility events on first tap - the carousel
|
||
// would stop cycling until user tapped out of it;
|
||
// here, we listen for touchend, explicitly pause the carousel
|
||
// (as if it's the second time we tap on it, mouseenter compat event
|
||
// is NOT fired) and after a timeout (to allow for mouse compatibility
|
||
// events to fire) we explicitly restart cycling
|
||
|
||
this.pause();
|
||
if (this.touchTimeout) {
|
||
clearTimeout(this.touchTimeout);
|
||
}
|
||
this.touchTimeout = setTimeout(() => this._maybeEnableCycle(), TOUCHEVENT_COMPAT_WAIT + this._config.interval);
|
||
};
|
||
const swipeConfig = {
|
||
leftCallback: () => this._slide(this._directionToOrder(DIRECTION_LEFT)),
|
||
rightCallback: () => this._slide(this._directionToOrder(DIRECTION_RIGHT)),
|
||
endCallback: endCallBack
|
||
};
|
||
this._swipeHelper = new Swipe(this._element, swipeConfig);
|
||
}
|
||
_keydown(event) {
|
||
if (/input|textarea/i.test(event.target.tagName)) {
|
||
return;
|
||
}
|
||
const direction = KEY_TO_DIRECTION[event.key];
|
||
if (direction) {
|
||
event.preventDefault();
|
||
this._slide(this._directionToOrder(direction));
|
||
}
|
||
}
|
||
_getItemIndex(element) {
|
||
return this._getItems().indexOf(element);
|
||
}
|
||
_setActiveIndicatorElement(index) {
|
||
if (!this._indicatorsElement) {
|
||
return;
|
||
}
|
||
const activeIndicator = SelectorEngine.findOne(SELECTOR_ACTIVE, this._indicatorsElement);
|
||
activeIndicator.classList.remove(CLASS_NAME_ACTIVE$2);
|
||
activeIndicator.removeAttribute('aria-current');
|
||
const newActiveIndicator = SelectorEngine.findOne(`[data-bs-slide-to="${index}"]`, this._indicatorsElement);
|
||
if (newActiveIndicator) {
|
||
newActiveIndicator.classList.add(CLASS_NAME_ACTIVE$2);
|
||
newActiveIndicator.setAttribute('aria-current', 'true');
|
||
}
|
||
}
|
||
_updateInterval() {
|
||
const element = this._activeElement || this._getActive();
|
||
if (!element) {
|
||
return;
|
||
}
|
||
const elementInterval = Number.parseInt(element.getAttribute('data-bs-interval'), 10);
|
||
this._config.interval = elementInterval || this._config.defaultInterval;
|
||
}
|
||
_slide(order) {
|
||
let element = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
|
||
if (this._isSliding) {
|
||
return;
|
||
}
|
||
const activeElement = this._getActive();
|
||
const isNext = order === ORDER_NEXT;
|
||
const nextElement = element || getNextActiveElement(this._getItems(), activeElement, isNext, this._config.wrap);
|
||
if (nextElement === activeElement) {
|
||
return;
|
||
}
|
||
const nextElementIndex = this._getItemIndex(nextElement);
|
||
const triggerEvent = eventName => {
|
||
return EventHandler.trigger(this._element, eventName, {
|
||
relatedTarget: nextElement,
|
||
direction: this._orderToDirection(order),
|
||
from: this._getItemIndex(activeElement),
|
||
to: nextElementIndex
|
||
});
|
||
};
|
||
const slideEvent = triggerEvent(EVENT_SLIDE);
|
||
if (slideEvent.defaultPrevented) {
|
||
return;
|
||
}
|
||
if (!activeElement || !nextElement) {
|
||
// Some weirdness is happening, so we bail
|
||
// TODO: change tests that use empty divs to avoid this check
|
||
return;
|
||
}
|
||
const isCycling = Boolean(this._interval);
|
||
this.pause();
|
||
this._isSliding = true;
|
||
this._setActiveIndicatorElement(nextElementIndex);
|
||
this._activeElement = nextElement;
|
||
const directionalClassName = isNext ? CLASS_NAME_START : CLASS_NAME_END;
|
||
const orderClassName = isNext ? CLASS_NAME_NEXT : CLASS_NAME_PREV;
|
||
nextElement.classList.add(orderClassName);
|
||
reflow(nextElement);
|
||
activeElement.classList.add(directionalClassName);
|
||
nextElement.classList.add(directionalClassName);
|
||
const completeCallBack = () => {
|
||
nextElement.classList.remove(directionalClassName, orderClassName);
|
||
nextElement.classList.add(CLASS_NAME_ACTIVE$2);
|
||
activeElement.classList.remove(CLASS_NAME_ACTIVE$2, orderClassName, directionalClassName);
|
||
this._isSliding = false;
|
||
triggerEvent(EVENT_SLID);
|
||
};
|
||
this._queueCallback(completeCallBack, activeElement, this._isAnimated());
|
||
if (isCycling) {
|
||
this.cycle();
|
||
}
|
||
}
|
||
_isAnimated() {
|
||
return this._element.classList.contains(CLASS_NAME_SLIDE);
|
||
}
|
||
_getActive() {
|
||
return SelectorEngine.findOne(SELECTOR_ACTIVE_ITEM, this._element);
|
||
}
|
||
_getItems() {
|
||
return SelectorEngine.find(SELECTOR_ITEM, this._element);
|
||
}
|
||
_clearInterval() {
|
||
if (this._interval) {
|
||
clearInterval(this._interval);
|
||
this._interval = null;
|
||
}
|
||
}
|
||
_directionToOrder(direction) {
|
||
if (isRTL()) {
|
||
return direction === DIRECTION_LEFT ? ORDER_PREV : ORDER_NEXT;
|
||
}
|
||
return direction === DIRECTION_LEFT ? ORDER_NEXT : ORDER_PREV;
|
||
}
|
||
_orderToDirection(order) {
|
||
if (isRTL()) {
|
||
return order === ORDER_PREV ? DIRECTION_LEFT : DIRECTION_RIGHT;
|
||
}
|
||
return order === ORDER_PREV ? DIRECTION_RIGHT : DIRECTION_LEFT;
|
||
}
|
||
|
||
// Static
|
||
static jQueryInterface(config) {
|
||
return this.each(function () {
|
||
const data = Carousel.getOrCreateInstance(this, config);
|
||
if (typeof config === 'number') {
|
||
data.to(config);
|
||
return;
|
||
}
|
||
if (typeof config === 'string') {
|
||
if (data[config] === undefined || config.startsWith('_') || config === 'constructor') {
|
||
throw new TypeError(`No method named "${config}"`);
|
||
}
|
||
data[config]();
|
||
}
|
||
});
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Data API implementation
|
||
*/
|
||
|
||
EventHandler.on(document, EVENT_CLICK_DATA_API$5, SELECTOR_DATA_SLIDE, function (event) {
|
||
const target = SelectorEngine.getElementFromSelector(this);
|
||
if (!target || !target.classList.contains(CLASS_NAME_CAROUSEL)) {
|
||
return;
|
||
}
|
||
event.preventDefault();
|
||
const carousel = Carousel.getOrCreateInstance(target);
|
||
const slideIndex = this.getAttribute('data-bs-slide-to');
|
||
if (slideIndex) {
|
||
carousel.to(slideIndex);
|
||
carousel._maybeEnableCycle();
|
||
return;
|
||
}
|
||
if (Manipulator.getDataAttribute(this, 'slide') === 'next') {
|
||
carousel.next();
|
||
carousel._maybeEnableCycle();
|
||
return;
|
||
}
|
||
carousel.prev();
|
||
carousel._maybeEnableCycle();
|
||
});
|
||
EventHandler.on(window, EVENT_LOAD_DATA_API$3, () => {
|
||
const carousels = SelectorEngine.find(SELECTOR_DATA_RIDE);
|
||
for (const carousel of carousels) {
|
||
Carousel.getOrCreateInstance(carousel);
|
||
}
|
||
});
|
||
|
||
/**
|
||
* jQuery
|
||
*/
|
||
|
||
defineJQueryPlugin(Carousel);
|
||
|
||
/**
|
||
* --------------------------------------------------------------------------
|
||
* Bootstrap collapse.js
|
||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||
* --------------------------------------------------------------------------
|
||
*/
|
||
|
||
/**
|
||
* Constants
|
||
*/
|
||
|
||
const NAME$b = 'collapse';
|
||
const DATA_KEY$7 = 'bs.collapse';
|
||
const EVENT_KEY$7 = `.${DATA_KEY$7}`;
|
||
const DATA_API_KEY$4 = '.data-api';
|
||
const EVENT_SHOW$6 = `show${EVENT_KEY$7}`;
|
||
const EVENT_SHOWN$6 = `shown${EVENT_KEY$7}`;
|
||
const EVENT_HIDE$6 = `hide${EVENT_KEY$7}`;
|
||
const EVENT_HIDDEN$6 = `hidden${EVENT_KEY$7}`;
|
||
const EVENT_CLICK_DATA_API$4 = `click${EVENT_KEY$7}${DATA_API_KEY$4}`;
|
||
const CLASS_NAME_SHOW$7 = 'show';
|
||
const CLASS_NAME_COLLAPSE = 'collapse';
|
||
const CLASS_NAME_COLLAPSING = 'collapsing';
|
||
const CLASS_NAME_COLLAPSED = 'collapsed';
|
||
const CLASS_NAME_DEEPER_CHILDREN = `:scope .${CLASS_NAME_COLLAPSE} .${CLASS_NAME_COLLAPSE}`;
|
||
const CLASS_NAME_HORIZONTAL = 'collapse-horizontal';
|
||
const WIDTH = 'width';
|
||
const HEIGHT = 'height';
|
||
const SELECTOR_ACTIVES = '.collapse.show, .collapse.collapsing';
|
||
const SELECTOR_DATA_TOGGLE$4 = '[data-bs-toggle="collapse"]';
|
||
const Default$a = {
|
||
parent: null,
|
||
toggle: true
|
||
};
|
||
const DefaultType$a = {
|
||
parent: '(null|element)',
|
||
toggle: 'boolean'
|
||
};
|
||
|
||
/**
|
||
* Class definition
|
||
*/
|
||
|
||
class Collapse extends BaseComponent {
|
||
constructor(element, config) {
|
||
super(element, config);
|
||
this._isTransitioning = false;
|
||
this._triggerArray = [];
|
||
const toggleList = SelectorEngine.find(SELECTOR_DATA_TOGGLE$4);
|
||
for (const elem of toggleList) {
|
||
const selector = SelectorEngine.getSelectorFromElement(elem);
|
||
const filterElement = SelectorEngine.find(selector).filter(foundElement => foundElement === this._element);
|
||
if (selector !== null && filterElement.length) {
|
||
this._triggerArray.push(elem);
|
||
}
|
||
}
|
||
this._initializeChildren();
|
||
if (!this._config.parent) {
|
||
this._addAriaAndCollapsedClass(this._triggerArray, this._isShown());
|
||
}
|
||
if (this._config.toggle) {
|
||
this.toggle();
|
||
}
|
||
}
|
||
|
||
// Getters
|
||
static get Default() {
|
||
return Default$a;
|
||
}
|
||
static get DefaultType() {
|
||
return DefaultType$a;
|
||
}
|
||
static get NAME() {
|
||
return NAME$b;
|
||
}
|
||
|
||
// Public
|
||
toggle() {
|
||
if (this._isShown()) {
|
||
this.hide();
|
||
} else {
|
||
this.show();
|
||
}
|
||
}
|
||
show() {
|
||
if (this._isTransitioning || this._isShown()) {
|
||
return;
|
||
}
|
||
let activeChildren = [];
|
||
|
||
// find active children
|
||
if (this._config.parent) {
|
||
activeChildren = this._getFirstLevelChildren(SELECTOR_ACTIVES).filter(element => element !== this._element).map(element => Collapse.getOrCreateInstance(element, {
|
||
toggle: false
|
||
}));
|
||
}
|
||
if (activeChildren.length && activeChildren[0]._isTransitioning) {
|
||
return;
|
||
}
|
||
const startEvent = EventHandler.trigger(this._element, EVENT_SHOW$6);
|
||
if (startEvent.defaultPrevented) {
|
||
return;
|
||
}
|
||
for (const activeInstance of activeChildren) {
|
||
activeInstance.hide();
|
||
}
|
||
const dimension = this._getDimension();
|
||
this._element.classList.remove(CLASS_NAME_COLLAPSE);
|
||
this._element.classList.add(CLASS_NAME_COLLAPSING);
|
||
this._element.style[dimension] = 0;
|
||
this._addAriaAndCollapsedClass(this._triggerArray, true);
|
||
this._isTransitioning = true;
|
||
const complete = () => {
|
||
this._isTransitioning = false;
|
||
this._element.classList.remove(CLASS_NAME_COLLAPSING);
|
||
this._element.classList.add(CLASS_NAME_COLLAPSE, CLASS_NAME_SHOW$7);
|
||
this._element.style[dimension] = '';
|
||
EventHandler.trigger(this._element, EVENT_SHOWN$6);
|
||
};
|
||
const capitalizedDimension = dimension[0].toUpperCase() + dimension.slice(1);
|
||
const scrollSize = `scroll${capitalizedDimension}`;
|
||
this._queueCallback(complete, this._element, true);
|
||
this._element.style[dimension] = `${this._element[scrollSize]}px`;
|
||
}
|
||
hide() {
|
||
if (this._isTransitioning || !this._isShown()) {
|
||
return;
|
||
}
|
||
const startEvent = EventHandler.trigger(this._element, EVENT_HIDE$6);
|
||
if (startEvent.defaultPrevented) {
|
||
return;
|
||
}
|
||
const dimension = this._getDimension();
|
||
this._element.style[dimension] = `${this._element.getBoundingClientRect()[dimension]}px`;
|
||
reflow(this._element);
|
||
this._element.classList.add(CLASS_NAME_COLLAPSING);
|
||
this._element.classList.remove(CLASS_NAME_COLLAPSE, CLASS_NAME_SHOW$7);
|
||
for (const trigger of this._triggerArray) {
|
||
const element = SelectorEngine.getElementFromSelector(trigger);
|
||
if (element && !this._isShown(element)) {
|
||
this._addAriaAndCollapsedClass([trigger], false);
|
||
}
|
||
}
|
||
this._isTransitioning = true;
|
||
const complete = () => {
|
||
this._isTransitioning = false;
|
||
this._element.classList.remove(CLASS_NAME_COLLAPSING);
|
||
this._element.classList.add(CLASS_NAME_COLLAPSE);
|
||
EventHandler.trigger(this._element, EVENT_HIDDEN$6);
|
||
};
|
||
this._element.style[dimension] = '';
|
||
this._queueCallback(complete, this._element, true);
|
||
}
|
||
_isShown() {
|
||
let element = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this._element;
|
||
return element.classList.contains(CLASS_NAME_SHOW$7);
|
||
}
|
||
|
||
// Private
|
||
_configAfterMerge(config) {
|
||
config.toggle = Boolean(config.toggle); // Coerce string values
|
||
config.parent = getElement(config.parent);
|
||
return config;
|
||
}
|
||
_getDimension() {
|
||
return this._element.classList.contains(CLASS_NAME_HORIZONTAL) ? WIDTH : HEIGHT;
|
||
}
|
||
_initializeChildren() {
|
||
if (!this._config.parent) {
|
||
return;
|
||
}
|
||
const children = this._getFirstLevelChildren(SELECTOR_DATA_TOGGLE$4);
|
||
for (const element of children) {
|
||
const selected = SelectorEngine.getElementFromSelector(element);
|
||
if (selected) {
|
||
this._addAriaAndCollapsedClass([element], this._isShown(selected));
|
||
}
|
||
}
|
||
}
|
||
_getFirstLevelChildren(selector) {
|
||
const children = SelectorEngine.find(CLASS_NAME_DEEPER_CHILDREN, this._config.parent);
|
||
// remove children if greater depth
|
||
return SelectorEngine.find(selector, this._config.parent).filter(element => !children.includes(element));
|
||
}
|
||
_addAriaAndCollapsedClass(triggerArray, isOpen) {
|
||
if (!triggerArray.length) {
|
||
return;
|
||
}
|
||
for (const element of triggerArray) {
|
||
element.classList.toggle(CLASS_NAME_COLLAPSED, !isOpen);
|
||
element.setAttribute('aria-expanded', isOpen);
|
||
}
|
||
}
|
||
|
||
// Static
|
||
static jQueryInterface(config) {
|
||
const _config = {};
|
||
if (typeof config === 'string' && /show|hide/.test(config)) {
|
||
_config.toggle = false;
|
||
}
|
||
return this.each(function () {
|
||
const data = Collapse.getOrCreateInstance(this, _config);
|
||
if (typeof config === 'string') {
|
||
if (typeof data[config] === 'undefined') {
|
||
throw new TypeError(`No method named "${config}"`);
|
||
}
|
||
data[config]();
|
||
}
|
||
});
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Data API implementation
|
||
*/
|
||
|
||
EventHandler.on(document, EVENT_CLICK_DATA_API$4, SELECTOR_DATA_TOGGLE$4, function (event) {
|
||
// preventDefault only for <a> elements (which change the URL) not inside the collapsible element
|
||
if (event.target.tagName === 'A' || event.delegateTarget && event.delegateTarget.tagName === 'A') {
|
||
event.preventDefault();
|
||
}
|
||
for (const element of SelectorEngine.getMultipleElementsFromSelector(this)) {
|
||
Collapse.getOrCreateInstance(element, {
|
||
toggle: false
|
||
}).toggle();
|
||
}
|
||
});
|
||
|
||
/**
|
||
* jQuery
|
||
*/
|
||
|
||
defineJQueryPlugin(Collapse);
|
||
var top = 'top';
|
||
var bottom = 'bottom';
|
||
var right = 'right';
|
||
var left = 'left';
|
||
var auto = 'auto';
|
||
var basePlacements = [top, bottom, right, left];
|
||
var start = 'start';
|
||
var end = 'end';
|
||
var clippingParents = 'clippingParents';
|
||
var viewport = 'viewport';
|
||
var popper = 'popper';
|
||
var reference = 'reference';
|
||
var variationPlacements = /*#__PURE__*/basePlacements.reduce(function (acc, placement) {
|
||
return acc.concat([placement + "-" + start, placement + "-" + end]);
|
||
}, []);
|
||
var placements = /*#__PURE__*/[].concat(basePlacements, [auto]).reduce(function (acc, placement) {
|
||
return acc.concat([placement, placement + "-" + start, placement + "-" + end]);
|
||
}, []); // modifiers that need to read the DOM
|
||
|
||
var beforeRead = 'beforeRead';
|
||
var read = 'read';
|
||
var afterRead = 'afterRead'; // pure-logic modifiers
|
||
|
||
var beforeMain = 'beforeMain';
|
||
var main = 'main';
|
||
var afterMain = 'afterMain'; // modifier with the purpose to write to the DOM (or write into a framework state)
|
||
|
||
var beforeWrite = 'beforeWrite';
|
||
var write = 'write';
|
||
var afterWrite = 'afterWrite';
|
||
var modifierPhases = [beforeRead, read, afterRead, beforeMain, main, afterMain, beforeWrite, write, afterWrite];
|
||
function getNodeName(element) {
|
||
return element ? (element.nodeName || '').toLowerCase() : null;
|
||
}
|
||
function getWindow(node) {
|
||
if (node == null) {
|
||
return window;
|
||
}
|
||
if (node.toString() !== '[object Window]') {
|
||
var ownerDocument = node.ownerDocument;
|
||
return ownerDocument ? ownerDocument.defaultView || window : window;
|
||
}
|
||
return node;
|
||
}
|
||
function isElement(node) {
|
||
var OwnElement = getWindow(node).Element;
|
||
return node instanceof OwnElement || node instanceof Element;
|
||
}
|
||
function isHTMLElement(node) {
|
||
var OwnElement = getWindow(node).HTMLElement;
|
||
return node instanceof OwnElement || node instanceof HTMLElement;
|
||
}
|
||
function isShadowRoot(node) {
|
||
// IE 11 has no ShadowRoot
|
||
if (typeof ShadowRoot === 'undefined') {
|
||
return false;
|
||
}
|
||
var OwnElement = getWindow(node).ShadowRoot;
|
||
return node instanceof OwnElement || node instanceof ShadowRoot;
|
||
}
|
||
|
||
// and applies them to the HTMLElements such as popper and arrow
|
||
|
||
function applyStyles(_ref) {
|
||
var state = _ref.state;
|
||
Object.keys(state.elements).forEach(function (name) {
|
||
var style = state.styles[name] || {};
|
||
var attributes = state.attributes[name] || {};
|
||
var element = state.elements[name]; // arrow is optional + virtual elements
|
||
|
||
if (!isHTMLElement(element) || !getNodeName(element)) {
|
||
return;
|
||
} // Flow doesn't support to extend this property, but it's the most
|
||
// effective way to apply styles to an HTMLElement
|
||
// $FlowFixMe[cannot-write]
|
||
|
||
Object.assign(element.style, style);
|
||
Object.keys(attributes).forEach(function (name) {
|
||
var value = attributes[name];
|
||
if (value === false) {
|
||
element.removeAttribute(name);
|
||
} else {
|
||
element.setAttribute(name, value === true ? '' : value);
|
||
}
|
||
});
|
||
});
|
||
}
|
||
function effect$2(_ref2) {
|
||
var state = _ref2.state;
|
||
var initialStyles = {
|
||
popper: {
|
||
position: state.options.strategy,
|
||
left: '0',
|
||
top: '0',
|
||
margin: '0'
|
||
},
|
||
arrow: {
|
||
position: 'absolute'
|
||
},
|
||
reference: {}
|
||
};
|
||
Object.assign(state.elements.popper.style, initialStyles.popper);
|
||
state.styles = initialStyles;
|
||
if (state.elements.arrow) {
|
||
Object.assign(state.elements.arrow.style, initialStyles.arrow);
|
||
}
|
||
return function () {
|
||
Object.keys(state.elements).forEach(function (name) {
|
||
var element = state.elements[name];
|
||
var attributes = state.attributes[name] || {};
|
||
var styleProperties = Object.keys(state.styles.hasOwnProperty(name) ? state.styles[name] : initialStyles[name]); // Set all values to an empty string to unset them
|
||
|
||
var style = styleProperties.reduce(function (style, property) {
|
||
style[property] = '';
|
||
return style;
|
||
}, {}); // arrow is optional + virtual elements
|
||
|
||
if (!isHTMLElement(element) || !getNodeName(element)) {
|
||
return;
|
||
}
|
||
Object.assign(element.style, style);
|
||
Object.keys(attributes).forEach(function (attribute) {
|
||
element.removeAttribute(attribute);
|
||
});
|
||
});
|
||
};
|
||
} // eslint-disable-next-line import/no-unused-modules
|
||
|
||
const applyStyles$1 = {
|
||
name: 'applyStyles',
|
||
enabled: true,
|
||
phase: 'write',
|
||
fn: applyStyles,
|
||
effect: effect$2,
|
||
requires: ['computeStyles']
|
||
};
|
||
function getBasePlacement(placement) {
|
||
return placement.split('-')[0];
|
||
}
|
||
var max = Math.max;
|
||
var min = Math.min;
|
||
var round = Math.round;
|
||
function getUAString() {
|
||
var uaData = navigator.userAgentData;
|
||
if (uaData != null && uaData.brands && Array.isArray(uaData.brands)) {
|
||
return uaData.brands.map(function (item) {
|
||
return item.brand + "/" + item.version;
|
||
}).join(' ');
|
||
}
|
||
return navigator.userAgent;
|
||
}
|
||
function isLayoutViewport() {
|
||
return !/^((?!chrome|android).)*safari/i.test(getUAString());
|
||
}
|
||
function getBoundingClientRect(element, includeScale, isFixedStrategy) {
|
||
if (includeScale === void 0) {
|
||
includeScale = false;
|
||
}
|
||
if (isFixedStrategy === void 0) {
|
||
isFixedStrategy = false;
|
||
}
|
||
var clientRect = element.getBoundingClientRect();
|
||
var scaleX = 1;
|
||
var scaleY = 1;
|
||
if (includeScale && isHTMLElement(element)) {
|
||
scaleX = element.offsetWidth > 0 ? round(clientRect.width) / element.offsetWidth || 1 : 1;
|
||
scaleY = element.offsetHeight > 0 ? round(clientRect.height) / element.offsetHeight || 1 : 1;
|
||
}
|
||
var _ref = isElement(element) ? getWindow(element) : window,
|
||
visualViewport = _ref.visualViewport;
|
||
var addVisualOffsets = !isLayoutViewport() && isFixedStrategy;
|
||
var x = (clientRect.left + (addVisualOffsets && visualViewport ? visualViewport.offsetLeft : 0)) / scaleX;
|
||
var y = (clientRect.top + (addVisualOffsets && visualViewport ? visualViewport.offsetTop : 0)) / scaleY;
|
||
var width = clientRect.width / scaleX;
|
||
var height = clientRect.height / scaleY;
|
||
return {
|
||
width: width,
|
||
height: height,
|
||
top: y,
|
||
right: x + width,
|
||
bottom: y + height,
|
||
left: x,
|
||
x: x,
|
||
y: y
|
||
};
|
||
}
|
||
|
||
// means it doesn't take into account transforms.
|
||
|
||
function getLayoutRect(element) {
|
||
var clientRect = getBoundingClientRect(element); // Use the clientRect sizes if it's not been transformed.
|
||
// Fixes https://github.com/popperjs/popper-core/issues/1223
|
||
|
||
var width = element.offsetWidth;
|
||
var height = element.offsetHeight;
|
||
if (Math.abs(clientRect.width - width) <= 1) {
|
||
width = clientRect.width;
|
||
}
|
||
if (Math.abs(clientRect.height - height) <= 1) {
|
||
height = clientRect.height;
|
||
}
|
||
return {
|
||
x: element.offsetLeft,
|
||
y: element.offsetTop,
|
||
width: width,
|
||
height: height
|
||
};
|
||
}
|
||
function contains(parent, child) {
|
||
var rootNode = child.getRootNode && child.getRootNode(); // First, attempt with faster native method
|
||
|
||
if (parent.contains(child)) {
|
||
return true;
|
||
} // then fallback to custom implementation with Shadow DOM support
|
||
else if (rootNode && isShadowRoot(rootNode)) {
|
||
var next = child;
|
||
do {
|
||
if (next && parent.isSameNode(next)) {
|
||
return true;
|
||
} // $FlowFixMe[prop-missing]: need a better way to handle this...
|
||
|
||
next = next.parentNode || next.host;
|
||
} while (next);
|
||
} // Give up, the result is false
|
||
|
||
return false;
|
||
}
|
||
function getComputedStyle$1(element) {
|
||
return getWindow(element).getComputedStyle(element);
|
||
}
|
||
function isTableElement(element) {
|
||
return ['table', 'td', 'th'].indexOf(getNodeName(element)) >= 0;
|
||
}
|
||
function getDocumentElement(element) {
|
||
// $FlowFixMe[incompatible-return]: assume body is always available
|
||
return ((isElement(element) ? element.ownerDocument :
|
||
// $FlowFixMe[prop-missing]
|
||
element.document) || window.document).documentElement;
|
||
}
|
||
function getParentNode(element) {
|
||
if (getNodeName(element) === 'html') {
|
||
return element;
|
||
}
|
||
return (
|
||
// this is a quicker (but less type safe) way to save quite some bytes from the bundle
|
||
// $FlowFixMe[incompatible-return]
|
||
// $FlowFixMe[prop-missing]
|
||
element.assignedSlot ||
|
||
// step into the shadow DOM of the parent of a slotted node
|
||
element.parentNode || (
|
||
// DOM Element detected
|
||
isShadowRoot(element) ? element.host : null) ||
|
||
// ShadowRoot detected
|
||
// $FlowFixMe[incompatible-call]: HTMLElement is a Node
|
||
getDocumentElement(element) // fallback
|
||
);
|
||
}
|
||
function getTrueOffsetParent(element) {
|
||
if (!isHTMLElement(element) ||
|
||
// https://github.com/popperjs/popper-core/issues/837
|
||
getComputedStyle$1(element).position === 'fixed') {
|
||
return null;
|
||
}
|
||
return element.offsetParent;
|
||
} // `.offsetParent` reports `null` for fixed elements, while absolute elements
|
||
// return the containing block
|
||
|
||
function getContainingBlock(element) {
|
||
var isFirefox = /firefox/i.test(getUAString());
|
||
var isIE = /Trident/i.test(getUAString());
|
||
if (isIE && isHTMLElement(element)) {
|
||
// In IE 9, 10 and 11 fixed elements containing block is always established by the viewport
|
||
var elementCss = getComputedStyle$1(element);
|
||
if (elementCss.position === 'fixed') {
|
||
return null;
|
||
}
|
||
}
|
||
var currentNode = getParentNode(element);
|
||
if (isShadowRoot(currentNode)) {
|
||
currentNode = currentNode.host;
|
||
}
|
||
while (isHTMLElement(currentNode) && ['html', 'body'].indexOf(getNodeName(currentNode)) < 0) {
|
||
var css = getComputedStyle$1(currentNode); // This is non-exhaustive but covers the most common CSS properties that
|
||
// create a containing block.
|
||
// https://developer.mozilla.org/en-US/docs/Web/CSS/Containing_block#identifying_the_containing_block
|
||
|
||
if (css.transform !== 'none' || css.perspective !== 'none' || css.contain === 'paint' || ['transform', 'perspective'].indexOf(css.willChange) !== -1 || isFirefox && css.willChange === 'filter' || isFirefox && css.filter && css.filter !== 'none') {
|
||
return currentNode;
|
||
} else {
|
||
currentNode = currentNode.parentNode;
|
||
}
|
||
}
|
||
return null;
|
||
} // Gets the closest ancestor positioned element. Handles some edge cases,
|
||
// such as table ancestors and cross browser bugs.
|
||
|
||
function getOffsetParent(element) {
|
||
var window = getWindow(element);
|
||
var offsetParent = getTrueOffsetParent(element);
|
||
while (offsetParent && isTableElement(offsetParent) && getComputedStyle$1(offsetParent).position === 'static') {
|
||
offsetParent = getTrueOffsetParent(offsetParent);
|
||
}
|
||
if (offsetParent && (getNodeName(offsetParent) === 'html' || getNodeName(offsetParent) === 'body' && getComputedStyle$1(offsetParent).position === 'static')) {
|
||
return window;
|
||
}
|
||
return offsetParent || getContainingBlock(element) || window;
|
||
}
|
||
function getMainAxisFromPlacement(placement) {
|
||
return ['top', 'bottom'].indexOf(placement) >= 0 ? 'x' : 'y';
|
||
}
|
||
function within(min$1, value, max$1) {
|
||
return max(min$1, min(value, max$1));
|
||
}
|
||
function withinMaxClamp(min, value, max) {
|
||
var v = within(min, value, max);
|
||
return v > max ? max : v;
|
||
}
|
||
function getFreshSideObject() {
|
||
return {
|
||
top: 0,
|
||
right: 0,
|
||
bottom: 0,
|
||
left: 0
|
||
};
|
||
}
|
||
function mergePaddingObject(paddingObject) {
|
||
return Object.assign({}, getFreshSideObject(), paddingObject);
|
||
}
|
||
function expandToHashMap(value, keys) {
|
||
return keys.reduce(function (hashMap, key) {
|
||
hashMap[key] = value;
|
||
return hashMap;
|
||
}, {});
|
||
}
|
||
var toPaddingObject = function toPaddingObject(padding, state) {
|
||
padding = typeof padding === 'function' ? padding(Object.assign({}, state.rects, {
|
||
placement: state.placement
|
||
})) : padding;
|
||
return mergePaddingObject(typeof padding !== 'number' ? padding : expandToHashMap(padding, basePlacements));
|
||
};
|
||
function arrow(_ref) {
|
||
var _state$modifiersData$;
|
||
var state = _ref.state,
|
||
name = _ref.name,
|
||
options = _ref.options;
|
||
var arrowElement = state.elements.arrow;
|
||
var popperOffsets = state.modifiersData.popperOffsets;
|
||
var basePlacement = getBasePlacement(state.placement);
|
||
var axis = getMainAxisFromPlacement(basePlacement);
|
||
var isVertical = [left, right].indexOf(basePlacement) >= 0;
|
||
var len = isVertical ? 'height' : 'width';
|
||
if (!arrowElement || !popperOffsets) {
|
||
return;
|
||
}
|
||
var paddingObject = toPaddingObject(options.padding, state);
|
||
var arrowRect = getLayoutRect(arrowElement);
|
||
var minProp = axis === 'y' ? top : left;
|
||
var maxProp = axis === 'y' ? bottom : right;
|
||
var endDiff = state.rects.reference[len] + state.rects.reference[axis] - popperOffsets[axis] - state.rects.popper[len];
|
||
var startDiff = popperOffsets[axis] - state.rects.reference[axis];
|
||
var arrowOffsetParent = getOffsetParent(arrowElement);
|
||
var clientSize = arrowOffsetParent ? axis === 'y' ? arrowOffsetParent.clientHeight || 0 : arrowOffsetParent.clientWidth || 0 : 0;
|
||
var centerToReference = endDiff / 2 - startDiff / 2; // Make sure the arrow doesn't overflow the popper if the center point is
|
||
// outside of the popper bounds
|
||
|
||
var min = paddingObject[minProp];
|
||
var max = clientSize - arrowRect[len] - paddingObject[maxProp];
|
||
var center = clientSize / 2 - arrowRect[len] / 2 + centerToReference;
|
||
var offset = within(min, center, max); // Prevents breaking syntax highlighting...
|
||
|
||
var axisProp = axis;
|
||
state.modifiersData[name] = (_state$modifiersData$ = {}, _state$modifiersData$[axisProp] = offset, _state$modifiersData$.centerOffset = offset - center, _state$modifiersData$);
|
||
}
|
||
function effect$1(_ref2) {
|
||
var state = _ref2.state,
|
||
options = _ref2.options;
|
||
var _options$element = options.element,
|
||
arrowElement = _options$element === void 0 ? '[data-popper-arrow]' : _options$element;
|
||
if (arrowElement == null) {
|
||
return;
|
||
} // CSS selector
|
||
|
||
if (typeof arrowElement === 'string') {
|
||
arrowElement = state.elements.popper.querySelector(arrowElement);
|
||
if (!arrowElement) {
|
||
return;
|
||
}
|
||
}
|
||
if (!contains(state.elements.popper, arrowElement)) {
|
||
return;
|
||
}
|
||
state.elements.arrow = arrowElement;
|
||
} // eslint-disable-next-line import/no-unused-modules
|
||
|
||
const arrow$1 = {
|
||
name: 'arrow',
|
||
enabled: true,
|
||
phase: 'main',
|
||
fn: arrow,
|
||
effect: effect$1,
|
||
requires: ['popperOffsets'],
|
||
requiresIfExists: ['preventOverflow']
|
||
};
|
||
function getVariation(placement) {
|
||
return placement.split('-')[1];
|
||
}
|
||
var unsetSides = {
|
||
top: 'auto',
|
||
right: 'auto',
|
||
bottom: 'auto',
|
||
left: 'auto'
|
||
}; // Round the offsets to the nearest suitable subpixel based on the DPR.
|
||
// Zooming can change the DPR, but it seems to report a value that will
|
||
// cleanly divide the values into the appropriate subpixels.
|
||
|
||
function roundOffsetsByDPR(_ref, win) {
|
||
var x = _ref.x,
|
||
y = _ref.y;
|
||
var dpr = win.devicePixelRatio || 1;
|
||
return {
|
||
x: round(x * dpr) / dpr || 0,
|
||
y: round(y * dpr) / dpr || 0
|
||
};
|
||
}
|
||
function mapToStyles(_ref2) {
|
||
var _Object$assign2;
|
||
var popper = _ref2.popper,
|
||
popperRect = _ref2.popperRect,
|
||
placement = _ref2.placement,
|
||
variation = _ref2.variation,
|
||
offsets = _ref2.offsets,
|
||
position = _ref2.position,
|
||
gpuAcceleration = _ref2.gpuAcceleration,
|
||
adaptive = _ref2.adaptive,
|
||
roundOffsets = _ref2.roundOffsets,
|
||
isFixed = _ref2.isFixed;
|
||
var _offsets$x = offsets.x,
|
||
x = _offsets$x === void 0 ? 0 : _offsets$x,
|
||
_offsets$y = offsets.y,
|
||
y = _offsets$y === void 0 ? 0 : _offsets$y;
|
||
var _ref3 = typeof roundOffsets === 'function' ? roundOffsets({
|
||
x: x,
|
||
y: y
|
||
}) : {
|
||
x: x,
|
||
y: y
|
||
};
|
||
x = _ref3.x;
|
||
y = _ref3.y;
|
||
var hasX = offsets.hasOwnProperty('x');
|
||
var hasY = offsets.hasOwnProperty('y');
|
||
var sideX = left;
|
||
var sideY = top;
|
||
var win = window;
|
||
if (adaptive) {
|
||
var offsetParent = getOffsetParent(popper);
|
||
var heightProp = 'clientHeight';
|
||
var widthProp = 'clientWidth';
|
||
if (offsetParent === getWindow(popper)) {
|
||
offsetParent = getDocumentElement(popper);
|
||
if (getComputedStyle$1(offsetParent).position !== 'static' && position === 'absolute') {
|
||
heightProp = 'scrollHeight';
|
||
widthProp = 'scrollWidth';
|
||
}
|
||
} // $FlowFixMe[incompatible-cast]: force type refinement, we compare offsetParent with window above, but Flow doesn't detect it
|
||
|
||
offsetParent = offsetParent;
|
||
if (placement === top || (placement === left || placement === right) && variation === end) {
|
||
sideY = bottom;
|
||
var offsetY = isFixed && offsetParent === win && win.visualViewport ? win.visualViewport.height :
|
||
// $FlowFixMe[prop-missing]
|
||
offsetParent[heightProp];
|
||
y -= offsetY - popperRect.height;
|
||
y *= gpuAcceleration ? 1 : -1;
|
||
}
|
||
if (placement === left || (placement === top || placement === bottom) && variation === end) {
|
||
sideX = right;
|
||
var offsetX = isFixed && offsetParent === win && win.visualViewport ? win.visualViewport.width :
|
||
// $FlowFixMe[prop-missing]
|
||
offsetParent[widthProp];
|
||
x -= offsetX - popperRect.width;
|
||
x *= gpuAcceleration ? 1 : -1;
|
||
}
|
||
}
|
||
var commonStyles = Object.assign({
|
||
position: position
|
||
}, adaptive && unsetSides);
|
||
var _ref4 = roundOffsets === true ? roundOffsetsByDPR({
|
||
x: x,
|
||
y: y
|
||
}, getWindow(popper)) : {
|
||
x: x,
|
||
y: y
|
||
};
|
||
x = _ref4.x;
|
||
y = _ref4.y;
|
||
if (gpuAcceleration) {
|
||
var _Object$assign;
|
||
return Object.assign({}, commonStyles, (_Object$assign = {}, _Object$assign[sideY] = hasY ? '0' : '', _Object$assign[sideX] = hasX ? '0' : '', _Object$assign.transform = (win.devicePixelRatio || 1) <= 1 ? "translate(" + x + "px, " + y + "px)" : "translate3d(" + x + "px, " + y + "px, 0)", _Object$assign));
|
||
}
|
||
return Object.assign({}, commonStyles, (_Object$assign2 = {}, _Object$assign2[sideY] = hasY ? y + "px" : '', _Object$assign2[sideX] = hasX ? x + "px" : '', _Object$assign2.transform = '', _Object$assign2));
|
||
}
|
||
function computeStyles(_ref5) {
|
||
var state = _ref5.state,
|
||
options = _ref5.options;
|
||
var _options$gpuAccelerat = options.gpuAcceleration,
|
||
gpuAcceleration = _options$gpuAccelerat === void 0 ? true : _options$gpuAccelerat,
|
||
_options$adaptive = options.adaptive,
|
||
adaptive = _options$adaptive === void 0 ? true : _options$adaptive,
|
||
_options$roundOffsets = options.roundOffsets,
|
||
roundOffsets = _options$roundOffsets === void 0 ? true : _options$roundOffsets;
|
||
var commonStyles = {
|
||
placement: getBasePlacement(state.placement),
|
||
variation: getVariation(state.placement),
|
||
popper: state.elements.popper,
|
||
popperRect: state.rects.popper,
|
||
gpuAcceleration: gpuAcceleration,
|
||
isFixed: state.options.strategy === 'fixed'
|
||
};
|
||
if (state.modifiersData.popperOffsets != null) {
|
||
state.styles.popper = Object.assign({}, state.styles.popper, mapToStyles(Object.assign({}, commonStyles, {
|
||
offsets: state.modifiersData.popperOffsets,
|
||
position: state.options.strategy,
|
||
adaptive: adaptive,
|
||
roundOffsets: roundOffsets
|
||
})));
|
||
}
|
||
if (state.modifiersData.arrow != null) {
|
||
state.styles.arrow = Object.assign({}, state.styles.arrow, mapToStyles(Object.assign({}, commonStyles, {
|
||
offsets: state.modifiersData.arrow,
|
||
position: 'absolute',
|
||
adaptive: false,
|
||
roundOffsets: roundOffsets
|
||
})));
|
||
}
|
||
state.attributes.popper = Object.assign({}, state.attributes.popper, {
|
||
'data-popper-placement': state.placement
|
||
});
|
||
} // eslint-disable-next-line import/no-unused-modules
|
||
|
||
const computeStyles$1 = {
|
||
name: 'computeStyles',
|
||
enabled: true,
|
||
phase: 'beforeWrite',
|
||
fn: computeStyles,
|
||
data: {}
|
||
};
|
||
var passive = {
|
||
passive: true
|
||
};
|
||
function effect(_ref) {
|
||
var state = _ref.state,
|
||
instance = _ref.instance,
|
||
options = _ref.options;
|
||
var _options$scroll = options.scroll,
|
||
scroll = _options$scroll === void 0 ? true : _options$scroll,
|
||
_options$resize = options.resize,
|
||
resize = _options$resize === void 0 ? true : _options$resize;
|
||
var window = getWindow(state.elements.popper);
|
||
var scrollParents = [].concat(state.scrollParents.reference, state.scrollParents.popper);
|
||
if (scroll) {
|
||
scrollParents.forEach(function (scrollParent) {
|
||
scrollParent.addEventListener('scroll', instance.update, passive);
|
||
});
|
||
}
|
||
if (resize) {
|
||
window.addEventListener('resize', instance.update, passive);
|
||
}
|
||
return function () {
|
||
if (scroll) {
|
||
scrollParents.forEach(function (scrollParent) {
|
||
scrollParent.removeEventListener('scroll', instance.update, passive);
|
||
});
|
||
}
|
||
if (resize) {
|
||
window.removeEventListener('resize', instance.update, passive);
|
||
}
|
||
};
|
||
} // eslint-disable-next-line import/no-unused-modules
|
||
|
||
const eventListeners = {
|
||
name: 'eventListeners',
|
||
enabled: true,
|
||
phase: 'write',
|
||
fn: function fn() {},
|
||
effect: effect,
|
||
data: {}
|
||
};
|
||
var hash$1 = {
|
||
left: 'right',
|
||
right: 'left',
|
||
bottom: 'top',
|
||
top: 'bottom'
|
||
};
|
||
function getOppositePlacement(placement) {
|
||
return placement.replace(/left|right|bottom|top/g, function (matched) {
|
||
return hash$1[matched];
|
||
});
|
||
}
|
||
var hash = {
|
||
start: 'end',
|
||
end: 'start'
|
||
};
|
||
function getOppositeVariationPlacement(placement) {
|
||
return placement.replace(/start|end/g, function (matched) {
|
||
return hash[matched];
|
||
});
|
||
}
|
||
function getWindowScroll(node) {
|
||
var win = getWindow(node);
|
||
var scrollLeft = win.pageXOffset;
|
||
var scrollTop = win.pageYOffset;
|
||
return {
|
||
scrollLeft: scrollLeft,
|
||
scrollTop: scrollTop
|
||
};
|
||
}
|
||
function getWindowScrollBarX(element) {
|
||
// If <html> has a CSS width greater than the viewport, then this will be
|
||
// incorrect for RTL.
|
||
// Popper 1 is broken in this case and never had a bug report so let's assume
|
||
// it's not an issue. I don't think anyone ever specifies width on <html>
|
||
// anyway.
|
||
// Browsers where the left scrollbar doesn't cause an issue report `0` for
|
||
// this (e.g. Edge 2019, IE11, Safari)
|
||
return getBoundingClientRect(getDocumentElement(element)).left + getWindowScroll(element).scrollLeft;
|
||
}
|
||
function getViewportRect(element, strategy) {
|
||
var win = getWindow(element);
|
||
var html = getDocumentElement(element);
|
||
var visualViewport = win.visualViewport;
|
||
var width = html.clientWidth;
|
||
var height = html.clientHeight;
|
||
var x = 0;
|
||
var y = 0;
|
||
if (visualViewport) {
|
||
width = visualViewport.width;
|
||
height = visualViewport.height;
|
||
var layoutViewport = isLayoutViewport();
|
||
if (layoutViewport || !layoutViewport && strategy === 'fixed') {
|
||
x = visualViewport.offsetLeft;
|
||
y = visualViewport.offsetTop;
|
||
}
|
||
}
|
||
return {
|
||
width: width,
|
||
height: height,
|
||
x: x + getWindowScrollBarX(element),
|
||
y: y
|
||
};
|
||
}
|
||
|
||
// of the `<html>` and `<body>` rect bounds if horizontally scrollable
|
||
|
||
function getDocumentRect(element) {
|
||
var _element$ownerDocumen;
|
||
var html = getDocumentElement(element);
|
||
var winScroll = getWindowScroll(element);
|
||
var body = (_element$ownerDocumen = element.ownerDocument) == null ? void 0 : _element$ownerDocumen.body;
|
||
var width = max(html.scrollWidth, html.clientWidth, body ? body.scrollWidth : 0, body ? body.clientWidth : 0);
|
||
var height = max(html.scrollHeight, html.clientHeight, body ? body.scrollHeight : 0, body ? body.clientHeight : 0);
|
||
var x = -winScroll.scrollLeft + getWindowScrollBarX(element);
|
||
var y = -winScroll.scrollTop;
|
||
if (getComputedStyle$1(body || html).direction === 'rtl') {
|
||
x += max(html.clientWidth, body ? body.clientWidth : 0) - width;
|
||
}
|
||
return {
|
||
width: width,
|
||
height: height,
|
||
x: x,
|
||
y: y
|
||
};
|
||
}
|
||
function isScrollParent(element) {
|
||
// Firefox wants us to check `-x` and `-y` variations as well
|
||
var _getComputedStyle = getComputedStyle$1(element),
|
||
overflow = _getComputedStyle.overflow,
|
||
overflowX = _getComputedStyle.overflowX,
|
||
overflowY = _getComputedStyle.overflowY;
|
||
return /auto|scroll|overlay|hidden/.test(overflow + overflowY + overflowX);
|
||
}
|
||
function getScrollParent(node) {
|
||
if (['html', 'body', '#document'].indexOf(getNodeName(node)) >= 0) {
|
||
// $FlowFixMe[incompatible-return]: assume body is always available
|
||
return node.ownerDocument.body;
|
||
}
|
||
if (isHTMLElement(node) && isScrollParent(node)) {
|
||
return node;
|
||
}
|
||
return getScrollParent(getParentNode(node));
|
||
}
|
||
|
||
/*
|
||
given a DOM element, return the list of all scroll parents, up the list of ancesors
|
||
until we get to the top window object. This list is what we attach scroll listeners
|
||
to, because if any of these parent elements scroll, we'll need to re-calculate the
|
||
reference element's position.
|
||
*/
|
||
|
||
function listScrollParents(element, list) {
|
||
var _element$ownerDocumen;
|
||
if (list === void 0) {
|
||
list = [];
|
||
}
|
||
var scrollParent = getScrollParent(element);
|
||
var isBody = scrollParent === ((_element$ownerDocumen = element.ownerDocument) == null ? void 0 : _element$ownerDocumen.body);
|
||
var win = getWindow(scrollParent);
|
||
var target = isBody ? [win].concat(win.visualViewport || [], isScrollParent(scrollParent) ? scrollParent : []) : scrollParent;
|
||
var updatedList = list.concat(target);
|
||
return isBody ? updatedList :
|
||
// $FlowFixMe[incompatible-call]: isBody tells us target will be an HTMLElement here
|
||
updatedList.concat(listScrollParents(getParentNode(target)));
|
||
}
|
||
function rectToClientRect(rect) {
|
||
return Object.assign({}, rect, {
|
||
left: rect.x,
|
||
top: rect.y,
|
||
right: rect.x + rect.width,
|
||
bottom: rect.y + rect.height
|
||
});
|
||
}
|
||
function getInnerBoundingClientRect(element, strategy) {
|
||
var rect = getBoundingClientRect(element, false, strategy === 'fixed');
|
||
rect.top = rect.top + element.clientTop;
|
||
rect.left = rect.left + element.clientLeft;
|
||
rect.bottom = rect.top + element.clientHeight;
|
||
rect.right = rect.left + element.clientWidth;
|
||
rect.width = element.clientWidth;
|
||
rect.height = element.clientHeight;
|
||
rect.x = rect.left;
|
||
rect.y = rect.top;
|
||
return rect;
|
||
}
|
||
function getClientRectFromMixedType(element, clippingParent, strategy) {
|
||
return clippingParent === viewport ? rectToClientRect(getViewportRect(element, strategy)) : isElement(clippingParent) ? getInnerBoundingClientRect(clippingParent, strategy) : rectToClientRect(getDocumentRect(getDocumentElement(element)));
|
||
} // A "clipping parent" is an overflowable container with the characteristic of
|
||
// clipping (or hiding) overflowing elements with a position different from
|
||
// `initial`
|
||
|
||
function getClippingParents(element) {
|
||
var clippingParents = listScrollParents(getParentNode(element));
|
||
var canEscapeClipping = ['absolute', 'fixed'].indexOf(getComputedStyle$1(element).position) >= 0;
|
||
var clipperElement = canEscapeClipping && isHTMLElement(element) ? getOffsetParent(element) : element;
|
||
if (!isElement(clipperElement)) {
|
||
return [];
|
||
} // $FlowFixMe[incompatible-return]: https://github.com/facebook/flow/issues/1414
|
||
|
||
return clippingParents.filter(function (clippingParent) {
|
||
return isElement(clippingParent) && contains(clippingParent, clipperElement) && getNodeName(clippingParent) !== 'body';
|
||
});
|
||
} // Gets the maximum area that the element is visible in due to any number of
|
||
// clipping parents
|
||
|
||
function getClippingRect(element, boundary, rootBoundary, strategy) {
|
||
var mainClippingParents = boundary === 'clippingParents' ? getClippingParents(element) : [].concat(boundary);
|
||
var clippingParents = [].concat(mainClippingParents, [rootBoundary]);
|
||
var firstClippingParent = clippingParents[0];
|
||
var clippingRect = clippingParents.reduce(function (accRect, clippingParent) {
|
||
var rect = getClientRectFromMixedType(element, clippingParent, strategy);
|
||
accRect.top = max(rect.top, accRect.top);
|
||
accRect.right = min(rect.right, accRect.right);
|
||
accRect.bottom = min(rect.bottom, accRect.bottom);
|
||
accRect.left = max(rect.left, accRect.left);
|
||
return accRect;
|
||
}, getClientRectFromMixedType(element, firstClippingParent, strategy));
|
||
clippingRect.width = clippingRect.right - clippingRect.left;
|
||
clippingRect.height = clippingRect.bottom - clippingRect.top;
|
||
clippingRect.x = clippingRect.left;
|
||
clippingRect.y = clippingRect.top;
|
||
return clippingRect;
|
||
}
|
||
function computeOffsets(_ref) {
|
||
var reference = _ref.reference,
|
||
element = _ref.element,
|
||
placement = _ref.placement;
|
||
var basePlacement = placement ? getBasePlacement(placement) : null;
|
||
var variation = placement ? getVariation(placement) : null;
|
||
var commonX = reference.x + reference.width / 2 - element.width / 2;
|
||
var commonY = reference.y + reference.height / 2 - element.height / 2;
|
||
var offsets;
|
||
switch (basePlacement) {
|
||
case top:
|
||
offsets = {
|
||
x: commonX,
|
||
y: reference.y - element.height
|
||
};
|
||
break;
|
||
case bottom:
|
||
offsets = {
|
||
x: commonX,
|
||
y: reference.y + reference.height
|
||
};
|
||
break;
|
||
case right:
|
||
offsets = {
|
||
x: reference.x + reference.width,
|
||
y: commonY
|
||
};
|
||
break;
|
||
case left:
|
||
offsets = {
|
||
x: reference.x - element.width,
|
||
y: commonY
|
||
};
|
||
break;
|
||
default:
|
||
offsets = {
|
||
x: reference.x,
|
||
y: reference.y
|
||
};
|
||
}
|
||
var mainAxis = basePlacement ? getMainAxisFromPlacement(basePlacement) : null;
|
||
if (mainAxis != null) {
|
||
var len = mainAxis === 'y' ? 'height' : 'width';
|
||
switch (variation) {
|
||
case start:
|
||
offsets[mainAxis] = offsets[mainAxis] - (reference[len] / 2 - element[len] / 2);
|
||
break;
|
||
case end:
|
||
offsets[mainAxis] = offsets[mainAxis] + (reference[len] / 2 - element[len] / 2);
|
||
break;
|
||
}
|
||
}
|
||
return offsets;
|
||
}
|
||
function detectOverflow(state, options) {
|
||
if (options === void 0) {
|
||
options = {};
|
||
}
|
||
var _options = options,
|
||
_options$placement = _options.placement,
|
||
placement = _options$placement === void 0 ? state.placement : _options$placement,
|
||
_options$strategy = _options.strategy,
|
||
strategy = _options$strategy === void 0 ? state.strategy : _options$strategy,
|
||
_options$boundary = _options.boundary,
|
||
boundary = _options$boundary === void 0 ? clippingParents : _options$boundary,
|
||
_options$rootBoundary = _options.rootBoundary,
|
||
rootBoundary = _options$rootBoundary === void 0 ? viewport : _options$rootBoundary,
|
||
_options$elementConte = _options.elementContext,
|
||
elementContext = _options$elementConte === void 0 ? popper : _options$elementConte,
|
||
_options$altBoundary = _options.altBoundary,
|
||
altBoundary = _options$altBoundary === void 0 ? false : _options$altBoundary,
|
||
_options$padding = _options.padding,
|
||
padding = _options$padding === void 0 ? 0 : _options$padding;
|
||
var paddingObject = mergePaddingObject(typeof padding !== 'number' ? padding : expandToHashMap(padding, basePlacements));
|
||
var altContext = elementContext === popper ? reference : popper;
|
||
var popperRect = state.rects.popper;
|
||
var element = state.elements[altBoundary ? altContext : elementContext];
|
||
var clippingClientRect = getClippingRect(isElement(element) ? element : element.contextElement || getDocumentElement(state.elements.popper), boundary, rootBoundary, strategy);
|
||
var referenceClientRect = getBoundingClientRect(state.elements.reference);
|
||
var popperOffsets = computeOffsets({
|
||
reference: referenceClientRect,
|
||
element: popperRect,
|
||
strategy: 'absolute',
|
||
placement: placement
|
||
});
|
||
var popperClientRect = rectToClientRect(Object.assign({}, popperRect, popperOffsets));
|
||
var elementClientRect = elementContext === popper ? popperClientRect : referenceClientRect; // positive = overflowing the clipping rect
|
||
// 0 or negative = within the clipping rect
|
||
|
||
var overflowOffsets = {
|
||
top: clippingClientRect.top - elementClientRect.top + paddingObject.top,
|
||
bottom: elementClientRect.bottom - clippingClientRect.bottom + paddingObject.bottom,
|
||
left: clippingClientRect.left - elementClientRect.left + paddingObject.left,
|
||
right: elementClientRect.right - clippingClientRect.right + paddingObject.right
|
||
};
|
||
var offsetData = state.modifiersData.offset; // Offsets can be applied only to the popper element
|
||
|
||
if (elementContext === popper && offsetData) {
|
||
var offset = offsetData[placement];
|
||
Object.keys(overflowOffsets).forEach(function (key) {
|
||
var multiply = [right, bottom].indexOf(key) >= 0 ? 1 : -1;
|
||
var axis = [top, bottom].indexOf(key) >= 0 ? 'y' : 'x';
|
||
overflowOffsets[key] += offset[axis] * multiply;
|
||
});
|
||
}
|
||
return overflowOffsets;
|
||
}
|
||
function computeAutoPlacement(state, options) {
|
||
if (options === void 0) {
|
||
options = {};
|
||
}
|
||
var _options = options,
|
||
placement = _options.placement,
|
||
boundary = _options.boundary,
|
||
rootBoundary = _options.rootBoundary,
|
||
padding = _options.padding,
|
||
flipVariations = _options.flipVariations,
|
||
_options$allowedAutoP = _options.allowedAutoPlacements,
|
||
allowedAutoPlacements = _options$allowedAutoP === void 0 ? placements : _options$allowedAutoP;
|
||
var variation = getVariation(placement);
|
||
var placements$1 = variation ? flipVariations ? variationPlacements : variationPlacements.filter(function (placement) {
|
||
return getVariation(placement) === variation;
|
||
}) : basePlacements;
|
||
var allowedPlacements = placements$1.filter(function (placement) {
|
||
return allowedAutoPlacements.indexOf(placement) >= 0;
|
||
});
|
||
if (allowedPlacements.length === 0) {
|
||
allowedPlacements = placements$1;
|
||
} // $FlowFixMe[incompatible-type]: Flow seems to have problems with two array unions...
|
||
|
||
var overflows = allowedPlacements.reduce(function (acc, placement) {
|
||
acc[placement] = detectOverflow(state, {
|
||
placement: placement,
|
||
boundary: boundary,
|
||
rootBoundary: rootBoundary,
|
||
padding: padding
|
||
})[getBasePlacement(placement)];
|
||
return acc;
|
||
}, {});
|
||
return Object.keys(overflows).sort(function (a, b) {
|
||
return overflows[a] - overflows[b];
|
||
});
|
||
}
|
||
function getExpandedFallbackPlacements(placement) {
|
||
if (getBasePlacement(placement) === auto) {
|
||
return [];
|
||
}
|
||
var oppositePlacement = getOppositePlacement(placement);
|
||
return [getOppositeVariationPlacement(placement), oppositePlacement, getOppositeVariationPlacement(oppositePlacement)];
|
||
}
|
||
function flip(_ref) {
|
||
var state = _ref.state,
|
||
options = _ref.options,
|
||
name = _ref.name;
|
||
if (state.modifiersData[name]._skip) {
|
||
return;
|
||
}
|
||
var _options$mainAxis = options.mainAxis,
|
||
checkMainAxis = _options$mainAxis === void 0 ? true : _options$mainAxis,
|
||
_options$altAxis = options.altAxis,
|
||
checkAltAxis = _options$altAxis === void 0 ? true : _options$altAxis,
|
||
specifiedFallbackPlacements = options.fallbackPlacements,
|
||
padding = options.padding,
|
||
boundary = options.boundary,
|
||
rootBoundary = options.rootBoundary,
|
||
altBoundary = options.altBoundary,
|
||
_options$flipVariatio = options.flipVariations,
|
||
flipVariations = _options$flipVariatio === void 0 ? true : _options$flipVariatio,
|
||
allowedAutoPlacements = options.allowedAutoPlacements;
|
||
var preferredPlacement = state.options.placement;
|
||
var basePlacement = getBasePlacement(preferredPlacement);
|
||
var isBasePlacement = basePlacement === preferredPlacement;
|
||
var fallbackPlacements = specifiedFallbackPlacements || (isBasePlacement || !flipVariations ? [getOppositePlacement(preferredPlacement)] : getExpandedFallbackPlacements(preferredPlacement));
|
||
var placements = [preferredPlacement].concat(fallbackPlacements).reduce(function (acc, placement) {
|
||
return acc.concat(getBasePlacement(placement) === auto ? computeAutoPlacement(state, {
|
||
placement: placement,
|
||
boundary: boundary,
|
||
rootBoundary: rootBoundary,
|
||
padding: padding,
|
||
flipVariations: flipVariations,
|
||
allowedAutoPlacements: allowedAutoPlacements
|
||
}) : placement);
|
||
}, []);
|
||
var referenceRect = state.rects.reference;
|
||
var popperRect = state.rects.popper;
|
||
var checksMap = new Map();
|
||
var makeFallbackChecks = true;
|
||
var firstFittingPlacement = placements[0];
|
||
for (var i = 0; i < placements.length; i++) {
|
||
var placement = placements[i];
|
||
var _basePlacement = getBasePlacement(placement);
|
||
var isStartVariation = getVariation(placement) === start;
|
||
var isVertical = [top, bottom].indexOf(_basePlacement) >= 0;
|
||
var len = isVertical ? 'width' : 'height';
|
||
var overflow = detectOverflow(state, {
|
||
placement: placement,
|
||
boundary: boundary,
|
||
rootBoundary: rootBoundary,
|
||
altBoundary: altBoundary,
|
||
padding: padding
|
||
});
|
||
var mainVariationSide = isVertical ? isStartVariation ? right : left : isStartVariation ? bottom : top;
|
||
if (referenceRect[len] > popperRect[len]) {
|
||
mainVariationSide = getOppositePlacement(mainVariationSide);
|
||
}
|
||
var altVariationSide = getOppositePlacement(mainVariationSide);
|
||
var checks = [];
|
||
if (checkMainAxis) {
|
||
checks.push(overflow[_basePlacement] <= 0);
|
||
}
|
||
if (checkAltAxis) {
|
||
checks.push(overflow[mainVariationSide] <= 0, overflow[altVariationSide] <= 0);
|
||
}
|
||
if (checks.every(function (check) {
|
||
return check;
|
||
})) {
|
||
firstFittingPlacement = placement;
|
||
makeFallbackChecks = false;
|
||
break;
|
||
}
|
||
checksMap.set(placement, checks);
|
||
}
|
||
if (makeFallbackChecks) {
|
||
// `2` may be desired in some cases – research later
|
||
var numberOfChecks = flipVariations ? 3 : 1;
|
||
var _loop = function _loop(_i) {
|
||
var fittingPlacement = placements.find(function (placement) {
|
||
var checks = checksMap.get(placement);
|
||
if (checks) {
|
||
return checks.slice(0, _i).every(function (check) {
|
||
return check;
|
||
});
|
||
}
|
||
});
|
||
if (fittingPlacement) {
|
||
firstFittingPlacement = fittingPlacement;
|
||
return "break";
|
||
}
|
||
};
|
||
for (var _i = numberOfChecks; _i > 0; _i--) {
|
||
var _ret = _loop(_i);
|
||
if (_ret === "break") break;
|
||
}
|
||
}
|
||
if (state.placement !== firstFittingPlacement) {
|
||
state.modifiersData[name]._skip = true;
|
||
state.placement = firstFittingPlacement;
|
||
state.reset = true;
|
||
}
|
||
} // eslint-disable-next-line import/no-unused-modules
|
||
|
||
const flip$1 = {
|
||
name: 'flip',
|
||
enabled: true,
|
||
phase: 'main',
|
||
fn: flip,
|
||
requiresIfExists: ['offset'],
|
||
data: {
|
||
_skip: false
|
||
}
|
||
};
|
||
function getSideOffsets(overflow, rect, preventedOffsets) {
|
||
if (preventedOffsets === void 0) {
|
||
preventedOffsets = {
|
||
x: 0,
|
||
y: 0
|
||
};
|
||
}
|
||
return {
|
||
top: overflow.top - rect.height - preventedOffsets.y,
|
||
right: overflow.right - rect.width + preventedOffsets.x,
|
||
bottom: overflow.bottom - rect.height + preventedOffsets.y,
|
||
left: overflow.left - rect.width - preventedOffsets.x
|
||
};
|
||
}
|
||
function isAnySideFullyClipped(overflow) {
|
||
return [top, right, bottom, left].some(function (side) {
|
||
return overflow[side] >= 0;
|
||
});
|
||
}
|
||
function hide(_ref) {
|
||
var state = _ref.state,
|
||
name = _ref.name;
|
||
var referenceRect = state.rects.reference;
|
||
var popperRect = state.rects.popper;
|
||
var preventedOffsets = state.modifiersData.preventOverflow;
|
||
var referenceOverflow = detectOverflow(state, {
|
||
elementContext: 'reference'
|
||
});
|
||
var popperAltOverflow = detectOverflow(state, {
|
||
altBoundary: true
|
||
});
|
||
var referenceClippingOffsets = getSideOffsets(referenceOverflow, referenceRect);
|
||
var popperEscapeOffsets = getSideOffsets(popperAltOverflow, popperRect, preventedOffsets);
|
||
var isReferenceHidden = isAnySideFullyClipped(referenceClippingOffsets);
|
||
var hasPopperEscaped = isAnySideFullyClipped(popperEscapeOffsets);
|
||
state.modifiersData[name] = {
|
||
referenceClippingOffsets: referenceClippingOffsets,
|
||
popperEscapeOffsets: popperEscapeOffsets,
|
||
isReferenceHidden: isReferenceHidden,
|
||
hasPopperEscaped: hasPopperEscaped
|
||
};
|
||
state.attributes.popper = Object.assign({}, state.attributes.popper, {
|
||
'data-popper-reference-hidden': isReferenceHidden,
|
||
'data-popper-escaped': hasPopperEscaped
|
||
});
|
||
} // eslint-disable-next-line import/no-unused-modules
|
||
|
||
const hide$1 = {
|
||
name: 'hide',
|
||
enabled: true,
|
||
phase: 'main',
|
||
requiresIfExists: ['preventOverflow'],
|
||
fn: hide
|
||
};
|
||
function distanceAndSkiddingToXY(placement, rects, offset) {
|
||
var basePlacement = getBasePlacement(placement);
|
||
var invertDistance = [left, top].indexOf(basePlacement) >= 0 ? -1 : 1;
|
||
var _ref = typeof offset === 'function' ? offset(Object.assign({}, rects, {
|
||
placement: placement
|
||
})) : offset,
|
||
skidding = _ref[0],
|
||
distance = _ref[1];
|
||
skidding = skidding || 0;
|
||
distance = (distance || 0) * invertDistance;
|
||
return [left, right].indexOf(basePlacement) >= 0 ? {
|
||
x: distance,
|
||
y: skidding
|
||
} : {
|
||
x: skidding,
|
||
y: distance
|
||
};
|
||
}
|
||
function offset(_ref2) {
|
||
var state = _ref2.state,
|
||
options = _ref2.options,
|
||
name = _ref2.name;
|
||
var _options$offset = options.offset,
|
||
offset = _options$offset === void 0 ? [0, 0] : _options$offset;
|
||
var data = placements.reduce(function (acc, placement) {
|
||
acc[placement] = distanceAndSkiddingToXY(placement, state.rects, offset);
|
||
return acc;
|
||
}, {});
|
||
var _data$state$placement = data[state.placement],
|
||
x = _data$state$placement.x,
|
||
y = _data$state$placement.y;
|
||
if (state.modifiersData.popperOffsets != null) {
|
||
state.modifiersData.popperOffsets.x += x;
|
||
state.modifiersData.popperOffsets.y += y;
|
||
}
|
||
state.modifiersData[name] = data;
|
||
} // eslint-disable-next-line import/no-unused-modules
|
||
|
||
const offset$1 = {
|
||
name: 'offset',
|
||
enabled: true,
|
||
phase: 'main',
|
||
requires: ['popperOffsets'],
|
||
fn: offset
|
||
};
|
||
function popperOffsets(_ref) {
|
||
var state = _ref.state,
|
||
name = _ref.name;
|
||
// Offsets are the actual position the popper needs to have to be
|
||
// properly positioned near its reference element
|
||
// This is the most basic placement, and will be adjusted by
|
||
// the modifiers in the next step
|
||
state.modifiersData[name] = computeOffsets({
|
||
reference: state.rects.reference,
|
||
element: state.rects.popper,
|
||
strategy: 'absolute',
|
||
placement: state.placement
|
||
});
|
||
} // eslint-disable-next-line import/no-unused-modules
|
||
|
||
const popperOffsets$1 = {
|
||
name: 'popperOffsets',
|
||
enabled: true,
|
||
phase: 'read',
|
||
fn: popperOffsets,
|
||
data: {}
|
||
};
|
||
function getAltAxis(axis) {
|
||
return axis === 'x' ? 'y' : 'x';
|
||
}
|
||
function preventOverflow(_ref) {
|
||
var state = _ref.state,
|
||
options = _ref.options,
|
||
name = _ref.name;
|
||
var _options$mainAxis = options.mainAxis,
|
||
checkMainAxis = _options$mainAxis === void 0 ? true : _options$mainAxis,
|
||
_options$altAxis = options.altAxis,
|
||
checkAltAxis = _options$altAxis === void 0 ? false : _options$altAxis,
|
||
boundary = options.boundary,
|
||
rootBoundary = options.rootBoundary,
|
||
altBoundary = options.altBoundary,
|
||
padding = options.padding,
|
||
_options$tether = options.tether,
|
||
tether = _options$tether === void 0 ? true : _options$tether,
|
||
_options$tetherOffset = options.tetherOffset,
|
||
tetherOffset = _options$tetherOffset === void 0 ? 0 : _options$tetherOffset;
|
||
var overflow = detectOverflow(state, {
|
||
boundary: boundary,
|
||
rootBoundary: rootBoundary,
|
||
padding: padding,
|
||
altBoundary: altBoundary
|
||
});
|
||
var basePlacement = getBasePlacement(state.placement);
|
||
var variation = getVariation(state.placement);
|
||
var isBasePlacement = !variation;
|
||
var mainAxis = getMainAxisFromPlacement(basePlacement);
|
||
var altAxis = getAltAxis(mainAxis);
|
||
var popperOffsets = state.modifiersData.popperOffsets;
|
||
var referenceRect = state.rects.reference;
|
||
var popperRect = state.rects.popper;
|
||
var tetherOffsetValue = typeof tetherOffset === 'function' ? tetherOffset(Object.assign({}, state.rects, {
|
||
placement: state.placement
|
||
})) : tetherOffset;
|
||
var normalizedTetherOffsetValue = typeof tetherOffsetValue === 'number' ? {
|
||
mainAxis: tetherOffsetValue,
|
||
altAxis: tetherOffsetValue
|
||
} : Object.assign({
|
||
mainAxis: 0,
|
||
altAxis: 0
|
||
}, tetherOffsetValue);
|
||
var offsetModifierState = state.modifiersData.offset ? state.modifiersData.offset[state.placement] : null;
|
||
var data = {
|
||
x: 0,
|
||
y: 0
|
||
};
|
||
if (!popperOffsets) {
|
||
return;
|
||
}
|
||
if (checkMainAxis) {
|
||
var _offsetModifierState$;
|
||
var mainSide = mainAxis === 'y' ? top : left;
|
||
var altSide = mainAxis === 'y' ? bottom : right;
|
||
var len = mainAxis === 'y' ? 'height' : 'width';
|
||
var offset = popperOffsets[mainAxis];
|
||
var min$1 = offset + overflow[mainSide];
|
||
var max$1 = offset - overflow[altSide];
|
||
var additive = tether ? -popperRect[len] / 2 : 0;
|
||
var minLen = variation === start ? referenceRect[len] : popperRect[len];
|
||
var maxLen = variation === start ? -popperRect[len] : -referenceRect[len]; // We need to include the arrow in the calculation so the arrow doesn't go
|
||
// outside the reference bounds
|
||
|
||
var arrowElement = state.elements.arrow;
|
||
var arrowRect = tether && arrowElement ? getLayoutRect(arrowElement) : {
|
||
width: 0,
|
||
height: 0
|
||
};
|
||
var arrowPaddingObject = state.modifiersData['arrow#persistent'] ? state.modifiersData['arrow#persistent'].padding : getFreshSideObject();
|
||
var arrowPaddingMin = arrowPaddingObject[mainSide];
|
||
var arrowPaddingMax = arrowPaddingObject[altSide]; // If the reference length is smaller than the arrow length, we don't want
|
||
// to include its full size in the calculation. If the reference is small
|
||
// and near the edge of a boundary, the popper can overflow even if the
|
||
// reference is not overflowing as well (e.g. virtual elements with no
|
||
// width or height)
|
||
|
||
var arrowLen = within(0, referenceRect[len], arrowRect[len]);
|
||
var minOffset = isBasePlacement ? referenceRect[len] / 2 - additive - arrowLen - arrowPaddingMin - normalizedTetherOffsetValue.mainAxis : minLen - arrowLen - arrowPaddingMin - normalizedTetherOffsetValue.mainAxis;
|
||
var maxOffset = isBasePlacement ? -referenceRect[len] / 2 + additive + arrowLen + arrowPaddingMax + normalizedTetherOffsetValue.mainAxis : maxLen + arrowLen + arrowPaddingMax + normalizedTetherOffsetValue.mainAxis;
|
||
var arrowOffsetParent = state.elements.arrow && getOffsetParent(state.elements.arrow);
|
||
var clientOffset = arrowOffsetParent ? mainAxis === 'y' ? arrowOffsetParent.clientTop || 0 : arrowOffsetParent.clientLeft || 0 : 0;
|
||
var offsetModifierValue = (_offsetModifierState$ = offsetModifierState == null ? void 0 : offsetModifierState[mainAxis]) != null ? _offsetModifierState$ : 0;
|
||
var tetherMin = offset + minOffset - offsetModifierValue - clientOffset;
|
||
var tetherMax = offset + maxOffset - offsetModifierValue;
|
||
var preventedOffset = within(tether ? min(min$1, tetherMin) : min$1, offset, tether ? max(max$1, tetherMax) : max$1);
|
||
popperOffsets[mainAxis] = preventedOffset;
|
||
data[mainAxis] = preventedOffset - offset;
|
||
}
|
||
if (checkAltAxis) {
|
||
var _offsetModifierState$2;
|
||
var _mainSide = mainAxis === 'x' ? top : left;
|
||
var _altSide = mainAxis === 'x' ? bottom : right;
|
||
var _offset = popperOffsets[altAxis];
|
||
var _len = altAxis === 'y' ? 'height' : 'width';
|
||
var _min = _offset + overflow[_mainSide];
|
||
var _max = _offset - overflow[_altSide];
|
||
var isOriginSide = [top, left].indexOf(basePlacement) !== -1;
|
||
var _offsetModifierValue = (_offsetModifierState$2 = offsetModifierState == null ? void 0 : offsetModifierState[altAxis]) != null ? _offsetModifierState$2 : 0;
|
||
var _tetherMin = isOriginSide ? _min : _offset - referenceRect[_len] - popperRect[_len] - _offsetModifierValue + normalizedTetherOffsetValue.altAxis;
|
||
var _tetherMax = isOriginSide ? _offset + referenceRect[_len] + popperRect[_len] - _offsetModifierValue - normalizedTetherOffsetValue.altAxis : _max;
|
||
var _preventedOffset = tether && isOriginSide ? withinMaxClamp(_tetherMin, _offset, _tetherMax) : within(tether ? _tetherMin : _min, _offset, tether ? _tetherMax : _max);
|
||
popperOffsets[altAxis] = _preventedOffset;
|
||
data[altAxis] = _preventedOffset - _offset;
|
||
}
|
||
state.modifiersData[name] = data;
|
||
} // eslint-disable-next-line import/no-unused-modules
|
||
|
||
const preventOverflow$1 = {
|
||
name: 'preventOverflow',
|
||
enabled: true,
|
||
phase: 'main',
|
||
fn: preventOverflow,
|
||
requiresIfExists: ['offset']
|
||
};
|
||
function getHTMLElementScroll(element) {
|
||
return {
|
||
scrollLeft: element.scrollLeft,
|
||
scrollTop: element.scrollTop
|
||
};
|
||
}
|
||
function getNodeScroll(node) {
|
||
if (node === getWindow(node) || !isHTMLElement(node)) {
|
||
return getWindowScroll(node);
|
||
} else {
|
||
return getHTMLElementScroll(node);
|
||
}
|
||
}
|
||
function isElementScaled(element) {
|
||
var rect = element.getBoundingClientRect();
|
||
var scaleX = round(rect.width) / element.offsetWidth || 1;
|
||
var scaleY = round(rect.height) / element.offsetHeight || 1;
|
||
return scaleX !== 1 || scaleY !== 1;
|
||
} // Returns the composite rect of an element relative to its offsetParent.
|
||
// Composite means it takes into account transforms as well as layout.
|
||
|
||
function getCompositeRect(elementOrVirtualElement, offsetParent, isFixed) {
|
||
if (isFixed === void 0) {
|
||
isFixed = false;
|
||
}
|
||
var isOffsetParentAnElement = isHTMLElement(offsetParent);
|
||
var offsetParentIsScaled = isHTMLElement(offsetParent) && isElementScaled(offsetParent);
|
||
var documentElement = getDocumentElement(offsetParent);
|
||
var rect = getBoundingClientRect(elementOrVirtualElement, offsetParentIsScaled, isFixed);
|
||
var scroll = {
|
||
scrollLeft: 0,
|
||
scrollTop: 0
|
||
};
|
||
var offsets = {
|
||
x: 0,
|
||
y: 0
|
||
};
|
||
if (isOffsetParentAnElement || !isOffsetParentAnElement && !isFixed) {
|
||
if (getNodeName(offsetParent) !== 'body' ||
|
||
// https://github.com/popperjs/popper-core/issues/1078
|
||
isScrollParent(documentElement)) {
|
||
scroll = getNodeScroll(offsetParent);
|
||
}
|
||
if (isHTMLElement(offsetParent)) {
|
||
offsets = getBoundingClientRect(offsetParent, true);
|
||
offsets.x += offsetParent.clientLeft;
|
||
offsets.y += offsetParent.clientTop;
|
||
} else if (documentElement) {
|
||
offsets.x = getWindowScrollBarX(documentElement);
|
||
}
|
||
}
|
||
return {
|
||
x: rect.left + scroll.scrollLeft - offsets.x,
|
||
y: rect.top + scroll.scrollTop - offsets.y,
|
||
width: rect.width,
|
||
height: rect.height
|
||
};
|
||
}
|
||
function order(modifiers) {
|
||
var map = new Map();
|
||
var visited = new Set();
|
||
var result = [];
|
||
modifiers.forEach(function (modifier) {
|
||
map.set(modifier.name, modifier);
|
||
}); // On visiting object, check for its dependencies and visit them recursively
|
||
|
||
function sort(modifier) {
|
||
visited.add(modifier.name);
|
||
var requires = [].concat(modifier.requires || [], modifier.requiresIfExists || []);
|
||
requires.forEach(function (dep) {
|
||
if (!visited.has(dep)) {
|
||
var depModifier = map.get(dep);
|
||
if (depModifier) {
|
||
sort(depModifier);
|
||
}
|
||
}
|
||
});
|
||
result.push(modifier);
|
||
}
|
||
modifiers.forEach(function (modifier) {
|
||
if (!visited.has(modifier.name)) {
|
||
// check for visited object
|
||
sort(modifier);
|
||
}
|
||
});
|
||
return result;
|
||
}
|
||
function orderModifiers(modifiers) {
|
||
// order based on dependencies
|
||
var orderedModifiers = order(modifiers); // order based on phase
|
||
|
||
return modifierPhases.reduce(function (acc, phase) {
|
||
return acc.concat(orderedModifiers.filter(function (modifier) {
|
||
return modifier.phase === phase;
|
||
}));
|
||
}, []);
|
||
}
|
||
function debounce(fn) {
|
||
var pending;
|
||
return function () {
|
||
if (!pending) {
|
||
pending = new Promise(function (resolve) {
|
||
Promise.resolve().then(function () {
|
||
pending = undefined;
|
||
resolve(fn());
|
||
});
|
||
});
|
||
}
|
||
return pending;
|
||
};
|
||
}
|
||
function mergeByName(modifiers) {
|
||
var merged = modifiers.reduce(function (merged, current) {
|
||
var existing = merged[current.name];
|
||
merged[current.name] = existing ? Object.assign({}, existing, current, {
|
||
options: Object.assign({}, existing.options, current.options),
|
||
data: Object.assign({}, existing.data, current.data)
|
||
}) : current;
|
||
return merged;
|
||
}, {}); // IE11 does not support Object.values
|
||
|
||
return Object.keys(merged).map(function (key) {
|
||
return merged[key];
|
||
});
|
||
}
|
||
var DEFAULT_OPTIONS = {
|
||
placement: 'bottom',
|
||
modifiers: [],
|
||
strategy: 'absolute'
|
||
};
|
||
function areValidElements() {
|
||
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
|
||
args[_key] = arguments[_key];
|
||
}
|
||
return !args.some(function (element) {
|
||
return !(element && typeof element.getBoundingClientRect === 'function');
|
||
});
|
||
}
|
||
function popperGenerator(generatorOptions) {
|
||
if (generatorOptions === void 0) {
|
||
generatorOptions = {};
|
||
}
|
||
var _generatorOptions = generatorOptions,
|
||
_generatorOptions$def = _generatorOptions.defaultModifiers,
|
||
defaultModifiers = _generatorOptions$def === void 0 ? [] : _generatorOptions$def,
|
||
_generatorOptions$def2 = _generatorOptions.defaultOptions,
|
||
defaultOptions = _generatorOptions$def2 === void 0 ? DEFAULT_OPTIONS : _generatorOptions$def2;
|
||
return function createPopper(reference, popper, options) {
|
||
if (options === void 0) {
|
||
options = defaultOptions;
|
||
}
|
||
var state = {
|
||
placement: 'bottom',
|
||
orderedModifiers: [],
|
||
options: Object.assign({}, DEFAULT_OPTIONS, defaultOptions),
|
||
modifiersData: {},
|
||
elements: {
|
||
reference: reference,
|
||
popper: popper
|
||
},
|
||
attributes: {},
|
||
styles: {}
|
||
};
|
||
var effectCleanupFns = [];
|
||
var isDestroyed = false;
|
||
var instance = {
|
||
state: state,
|
||
setOptions: function setOptions(setOptionsAction) {
|
||
var options = typeof setOptionsAction === 'function' ? setOptionsAction(state.options) : setOptionsAction;
|
||
cleanupModifierEffects();
|
||
state.options = Object.assign({}, defaultOptions, state.options, options);
|
||
state.scrollParents = {
|
||
reference: isElement(reference) ? listScrollParents(reference) : reference.contextElement ? listScrollParents(reference.contextElement) : [],
|
||
popper: listScrollParents(popper)
|
||
}; // Orders the modifiers based on their dependencies and `phase`
|
||
// properties
|
||
|
||
var orderedModifiers = orderModifiers(mergeByName([].concat(defaultModifiers, state.options.modifiers))); // Strip out disabled modifiers
|
||
|
||
state.orderedModifiers = orderedModifiers.filter(function (m) {
|
||
return m.enabled;
|
||
});
|
||
runModifierEffects();
|
||
return instance.update();
|
||
},
|
||
// Sync update – it will always be executed, even if not necessary. This
|
||
// is useful for low frequency updates where sync behavior simplifies the
|
||
// logic.
|
||
// For high frequency updates (e.g. `resize` and `scroll` events), always
|
||
// prefer the async Popper#update method
|
||
forceUpdate: function forceUpdate() {
|
||
if (isDestroyed) {
|
||
return;
|
||
}
|
||
var _state$elements = state.elements,
|
||
reference = _state$elements.reference,
|
||
popper = _state$elements.popper; // Don't proceed if `reference` or `popper` are not valid elements
|
||
// anymore
|
||
|
||
if (!areValidElements(reference, popper)) {
|
||
return;
|
||
} // Store the reference and popper rects to be read by modifiers
|
||
|
||
state.rects = {
|
||
reference: getCompositeRect(reference, getOffsetParent(popper), state.options.strategy === 'fixed'),
|
||
popper: getLayoutRect(popper)
|
||
}; // Modifiers have the ability to reset the current update cycle. The
|
||
// most common use case for this is the `flip` modifier changing the
|
||
// placement, which then needs to re-run all the modifiers, because the
|
||
// logic was previously ran for the previous placement and is therefore
|
||
// stale/incorrect
|
||
|
||
state.reset = false;
|
||
state.placement = state.options.placement; // On each update cycle, the `modifiersData` property for each modifier
|
||
// is filled with the initial data specified by the modifier. This means
|
||
// it doesn't persist and is fresh on each update.
|
||
// To ensure persistent data, use `${name}#persistent`
|
||
|
||
state.orderedModifiers.forEach(function (modifier) {
|
||
return state.modifiersData[modifier.name] = Object.assign({}, modifier.data);
|
||
});
|
||
for (var index = 0; index < state.orderedModifiers.length; index++) {
|
||
if (state.reset === true) {
|
||
state.reset = false;
|
||
index = -1;
|
||
continue;
|
||
}
|
||
var _state$orderedModifie = state.orderedModifiers[index],
|
||
fn = _state$orderedModifie.fn,
|
||
_state$orderedModifie2 = _state$orderedModifie.options,
|
||
_options = _state$orderedModifie2 === void 0 ? {} : _state$orderedModifie2,
|
||
name = _state$orderedModifie.name;
|
||
if (typeof fn === 'function') {
|
||
state = fn({
|
||
state: state,
|
||
options: _options,
|
||
name: name,
|
||
instance: instance
|
||
}) || state;
|
||
}
|
||
}
|
||
},
|
||
// Async and optimistically optimized update – it will not be executed if
|
||
// not necessary (debounced to run at most once-per-tick)
|
||
update: debounce(function () {
|
||
return new Promise(function (resolve) {
|
||
instance.forceUpdate();
|
||
resolve(state);
|
||
});
|
||
}),
|
||
destroy: function destroy() {
|
||
cleanupModifierEffects();
|
||
isDestroyed = true;
|
||
}
|
||
};
|
||
if (!areValidElements(reference, popper)) {
|
||
return instance;
|
||
}
|
||
instance.setOptions(options).then(function (state) {
|
||
if (!isDestroyed && options.onFirstUpdate) {
|
||
options.onFirstUpdate(state);
|
||
}
|
||
}); // Modifiers have the ability to execute arbitrary code before the first
|
||
// update cycle runs. They will be executed in the same order as the update
|
||
// cycle. This is useful when a modifier adds some persistent data that
|
||
// other modifiers need to use, but the modifier is run after the dependent
|
||
// one.
|
||
|
||
function runModifierEffects() {
|
||
state.orderedModifiers.forEach(function (_ref) {
|
||
var name = _ref.name,
|
||
_ref$options = _ref.options,
|
||
options = _ref$options === void 0 ? {} : _ref$options,
|
||
effect = _ref.effect;
|
||
if (typeof effect === 'function') {
|
||
var cleanupFn = effect({
|
||
state: state,
|
||
name: name,
|
||
instance: instance,
|
||
options: options
|
||
});
|
||
var noopFn = function noopFn() {};
|
||
effectCleanupFns.push(cleanupFn || noopFn);
|
||
}
|
||
});
|
||
}
|
||
function cleanupModifierEffects() {
|
||
effectCleanupFns.forEach(function (fn) {
|
||
return fn();
|
||
});
|
||
effectCleanupFns = [];
|
||
}
|
||
return instance;
|
||
};
|
||
}
|
||
var createPopper$2 = /*#__PURE__*/popperGenerator(); // eslint-disable-next-line import/no-unused-modules
|
||
|
||
var defaultModifiers$1 = [eventListeners, popperOffsets$1, computeStyles$1, applyStyles$1];
|
||
var createPopper$1 = /*#__PURE__*/popperGenerator({
|
||
defaultModifiers: defaultModifiers$1
|
||
}); // eslint-disable-next-line import/no-unused-modules
|
||
|
||
var defaultModifiers = [eventListeners, popperOffsets$1, computeStyles$1, applyStyles$1, offset$1, flip$1, preventOverflow$1, arrow$1, hide$1];
|
||
var createPopper = /*#__PURE__*/popperGenerator({
|
||
defaultModifiers: defaultModifiers
|
||
}); // eslint-disable-next-line import/no-unused-modules
|
||
|
||
const Popper = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({
|
||
__proto__: null,
|
||
afterMain,
|
||
afterRead,
|
||
afterWrite,
|
||
applyStyles: applyStyles$1,
|
||
arrow: arrow$1,
|
||
auto,
|
||
basePlacements,
|
||
beforeMain,
|
||
beforeRead,
|
||
beforeWrite,
|
||
bottom,
|
||
clippingParents,
|
||
computeStyles: computeStyles$1,
|
||
createPopper,
|
||
createPopperBase: createPopper$2,
|
||
createPopperLite: createPopper$1,
|
||
detectOverflow,
|
||
end,
|
||
eventListeners,
|
||
flip: flip$1,
|
||
hide: hide$1,
|
||
left,
|
||
main,
|
||
modifierPhases,
|
||
offset: offset$1,
|
||
placements,
|
||
popper,
|
||
popperGenerator,
|
||
popperOffsets: popperOffsets$1,
|
||
preventOverflow: preventOverflow$1,
|
||
read,
|
||
reference,
|
||
right,
|
||
start,
|
||
top,
|
||
variationPlacements,
|
||
viewport,
|
||
write
|
||
}, Symbol.toStringTag, {
|
||
value: 'Module'
|
||
}));
|
||
|
||
/**
|
||
* --------------------------------------------------------------------------
|
||
* Bootstrap dropdown.js
|
||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||
* --------------------------------------------------------------------------
|
||
*/
|
||
|
||
/**
|
||
* Constants
|
||
*/
|
||
|
||
const NAME$a = 'dropdown';
|
||
const DATA_KEY$6 = 'bs.dropdown';
|
||
const EVENT_KEY$6 = `.${DATA_KEY$6}`;
|
||
const DATA_API_KEY$3 = '.data-api';
|
||
const ESCAPE_KEY$2 = 'Escape';
|
||
const TAB_KEY$1 = 'Tab';
|
||
const ARROW_UP_KEY$1 = 'ArrowUp';
|
||
const ARROW_DOWN_KEY$1 = 'ArrowDown';
|
||
const RIGHT_MOUSE_BUTTON = 2; // MouseEvent.button value for the secondary button, usually the right button
|
||
|
||
const EVENT_HIDE$5 = `hide${EVENT_KEY$6}`;
|
||
const EVENT_HIDDEN$5 = `hidden${EVENT_KEY$6}`;
|
||
const EVENT_SHOW$5 = `show${EVENT_KEY$6}`;
|
||
const EVENT_SHOWN$5 = `shown${EVENT_KEY$6}`;
|
||
const EVENT_CLICK_DATA_API$3 = `click${EVENT_KEY$6}${DATA_API_KEY$3}`;
|
||
const EVENT_KEYDOWN_DATA_API = `keydown${EVENT_KEY$6}${DATA_API_KEY$3}`;
|
||
const EVENT_KEYUP_DATA_API = `keyup${EVENT_KEY$6}${DATA_API_KEY$3}`;
|
||
const CLASS_NAME_SHOW$6 = 'show';
|
||
const CLASS_NAME_DROPUP = 'dropup';
|
||
const CLASS_NAME_DROPEND = 'dropend';
|
||
const CLASS_NAME_DROPSTART = 'dropstart';
|
||
const CLASS_NAME_DROPUP_CENTER = 'dropup-center';
|
||
const CLASS_NAME_DROPDOWN_CENTER = 'dropdown-center';
|
||
const SELECTOR_DATA_TOGGLE$3 = '[data-bs-toggle="dropdown"]:not(.disabled):not(:disabled)';
|
||
const SELECTOR_DATA_TOGGLE_SHOWN = `${SELECTOR_DATA_TOGGLE$3}.${CLASS_NAME_SHOW$6}`;
|
||
const SELECTOR_MENU = '.dropdown-menu';
|
||
const SELECTOR_NAVBAR = '.navbar';
|
||
const SELECTOR_NAVBAR_NAV = '.navbar-nav';
|
||
const SELECTOR_VISIBLE_ITEMS = '.dropdown-menu .dropdown-item:not(.disabled):not(:disabled)';
|
||
const PLACEMENT_TOP = isRTL() ? 'top-end' : 'top-start';
|
||
const PLACEMENT_TOPEND = isRTL() ? 'top-start' : 'top-end';
|
||
const PLACEMENT_BOTTOM = isRTL() ? 'bottom-end' : 'bottom-start';
|
||
const PLACEMENT_BOTTOMEND = isRTL() ? 'bottom-start' : 'bottom-end';
|
||
const PLACEMENT_RIGHT = isRTL() ? 'left-start' : 'right-start';
|
||
const PLACEMENT_LEFT = isRTL() ? 'right-start' : 'left-start';
|
||
const PLACEMENT_TOPCENTER = 'top';
|
||
const PLACEMENT_BOTTOMCENTER = 'bottom';
|
||
const Default$9 = {
|
||
autoClose: true,
|
||
boundary: 'clippingParents',
|
||
display: 'dynamic',
|
||
offset: [0, 2],
|
||
popperConfig: null,
|
||
reference: 'toggle'
|
||
};
|
||
const DefaultType$9 = {
|
||
autoClose: '(boolean|string)',
|
||
boundary: '(string|element)',
|
||
display: 'string',
|
||
offset: '(array|string|function)',
|
||
popperConfig: '(null|object|function)',
|
||
reference: '(string|element|object)'
|
||
};
|
||
|
||
/**
|
||
* Class definition
|
||
*/
|
||
|
||
class Dropdown extends BaseComponent {
|
||
constructor(element, config) {
|
||
super(element, config);
|
||
this._popper = null;
|
||
this._parent = this._element.parentNode; // dropdown wrapper
|
||
// TODO: v6 revert #37011 & change markup https://getbootstrap.com/docs/5.3/forms/input-group/
|
||
this._menu = SelectorEngine.next(this._element, SELECTOR_MENU)[0] || SelectorEngine.prev(this._element, SELECTOR_MENU)[0] || SelectorEngine.findOne(SELECTOR_MENU, this._parent);
|
||
this._inNavbar = this._detectNavbar();
|
||
}
|
||
|
||
// Getters
|
||
static get Default() {
|
||
return Default$9;
|
||
}
|
||
static get DefaultType() {
|
||
return DefaultType$9;
|
||
}
|
||
static get NAME() {
|
||
return NAME$a;
|
||
}
|
||
|
||
// Public
|
||
toggle() {
|
||
return this._isShown() ? this.hide() : this.show();
|
||
}
|
||
show() {
|
||
if (isDisabled(this._element) || this._isShown()) {
|
||
return;
|
||
}
|
||
const relatedTarget = {
|
||
relatedTarget: this._element
|
||
};
|
||
const showEvent = EventHandler.trigger(this._element, EVENT_SHOW$5, relatedTarget);
|
||
if (showEvent.defaultPrevented) {
|
||
return;
|
||
}
|
||
this._createPopper();
|
||
|
||
// If this is a touch-enabled device we add extra
|
||
// empty mouseover listeners to the body's immediate children;
|
||
// only needed because of broken event delegation on iOS
|
||
// https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html
|
||
if ('ontouchstart' in document.documentElement && !this._parent.closest(SELECTOR_NAVBAR_NAV)) {
|
||
for (const element of [].concat(...document.body.children)) {
|
||
EventHandler.on(element, 'mouseover', noop);
|
||
}
|
||
}
|
||
this._element.focus();
|
||
this._element.setAttribute('aria-expanded', true);
|
||
this._menu.classList.add(CLASS_NAME_SHOW$6);
|
||
this._element.classList.add(CLASS_NAME_SHOW$6);
|
||
EventHandler.trigger(this._element, EVENT_SHOWN$5, relatedTarget);
|
||
}
|
||
hide() {
|
||
if (isDisabled(this._element) || !this._isShown()) {
|
||
return;
|
||
}
|
||
const relatedTarget = {
|
||
relatedTarget: this._element
|
||
};
|
||
this._completeHide(relatedTarget);
|
||
}
|
||
dispose() {
|
||
if (this._popper) {
|
||
this._popper.destroy();
|
||
}
|
||
super.dispose();
|
||
}
|
||
update() {
|
||
this._inNavbar = this._detectNavbar();
|
||
if (this._popper) {
|
||
this._popper.update();
|
||
}
|
||
}
|
||
|
||
// Private
|
||
_completeHide(relatedTarget) {
|
||
const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE$5, relatedTarget);
|
||
if (hideEvent.defaultPrevented) {
|
||
return;
|
||
}
|
||
|
||
// If this is a touch-enabled device we remove the extra
|
||
// empty mouseover listeners we added for iOS support
|
||
if ('ontouchstart' in document.documentElement) {
|
||
for (const element of [].concat(...document.body.children)) {
|
||
EventHandler.off(element, 'mouseover', noop);
|
||
}
|
||
}
|
||
if (this._popper) {
|
||
this._popper.destroy();
|
||
}
|
||
this._menu.classList.remove(CLASS_NAME_SHOW$6);
|
||
this._element.classList.remove(CLASS_NAME_SHOW$6);
|
||
this._element.setAttribute('aria-expanded', 'false');
|
||
Manipulator.removeDataAttribute(this._menu, 'popper');
|
||
EventHandler.trigger(this._element, EVENT_HIDDEN$5, relatedTarget);
|
||
}
|
||
_getConfig(config) {
|
||
config = super._getConfig(config);
|
||
if (typeof config.reference === 'object' && !isElement$1(config.reference) && typeof config.reference.getBoundingClientRect !== 'function') {
|
||
// Popper virtual elements require a getBoundingClientRect method
|
||
throw new TypeError(`${NAME$a.toUpperCase()}: Option "reference" provided type "object" without a required "getBoundingClientRect" method.`);
|
||
}
|
||
return config;
|
||
}
|
||
_createPopper() {
|
||
if (typeof Popper === 'undefined') {
|
||
throw new TypeError('Bootstrap\'s dropdowns require Popper (https://popper.js.org)');
|
||
}
|
||
let referenceElement = this._element;
|
||
if (this._config.reference === 'parent') {
|
||
referenceElement = this._parent;
|
||
} else if (isElement$1(this._config.reference)) {
|
||
referenceElement = getElement(this._config.reference);
|
||
} else if (typeof this._config.reference === 'object') {
|
||
referenceElement = this._config.reference;
|
||
}
|
||
const popperConfig = this._getPopperConfig();
|
||
this._popper = createPopper(referenceElement, this._menu, popperConfig);
|
||
}
|
||
_isShown() {
|
||
return this._menu.classList.contains(CLASS_NAME_SHOW$6);
|
||
}
|
||
_getPlacement() {
|
||
const parentDropdown = this._parent;
|
||
if (parentDropdown.classList.contains(CLASS_NAME_DROPEND)) {
|
||
return PLACEMENT_RIGHT;
|
||
}
|
||
if (parentDropdown.classList.contains(CLASS_NAME_DROPSTART)) {
|
||
return PLACEMENT_LEFT;
|
||
}
|
||
if (parentDropdown.classList.contains(CLASS_NAME_DROPUP_CENTER)) {
|
||
return PLACEMENT_TOPCENTER;
|
||
}
|
||
if (parentDropdown.classList.contains(CLASS_NAME_DROPDOWN_CENTER)) {
|
||
return PLACEMENT_BOTTOMCENTER;
|
||
}
|
||
|
||
// We need to trim the value because custom properties can also include spaces
|
||
const isEnd = getComputedStyle(this._menu).getPropertyValue('--bs-position').trim() === 'end';
|
||
if (parentDropdown.classList.contains(CLASS_NAME_DROPUP)) {
|
||
return isEnd ? PLACEMENT_TOPEND : PLACEMENT_TOP;
|
||
}
|
||
return isEnd ? PLACEMENT_BOTTOMEND : PLACEMENT_BOTTOM;
|
||
}
|
||
_detectNavbar() {
|
||
return this._element.closest(SELECTOR_NAVBAR) !== null;
|
||
}
|
||
_getOffset() {
|
||
const {
|
||
offset
|
||
} = this._config;
|
||
if (typeof offset === 'string') {
|
||
return offset.split(',').map(value => Number.parseInt(value, 10));
|
||
}
|
||
if (typeof offset === 'function') {
|
||
return popperData => offset(popperData, this._element);
|
||
}
|
||
return offset;
|
||
}
|
||
_getPopperConfig() {
|
||
const defaultBsPopperConfig = {
|
||
placement: this._getPlacement(),
|
||
modifiers: [{
|
||
name: 'preventOverflow',
|
||
options: {
|
||
boundary: this._config.boundary
|
||
}
|
||
}, {
|
||
name: 'offset',
|
||
options: {
|
||
offset: this._getOffset()
|
||
}
|
||
}]
|
||
};
|
||
|
||
// Disable Popper if we have a static display or Dropdown is in Navbar
|
||
if (this._inNavbar || this._config.display === 'static') {
|
||
Manipulator.setDataAttribute(this._menu, 'popper', 'static'); // TODO: v6 remove
|
||
defaultBsPopperConfig.modifiers = [{
|
||
name: 'applyStyles',
|
||
enabled: false
|
||
}];
|
||
}
|
||
return {
|
||
...defaultBsPopperConfig,
|
||
...execute(this._config.popperConfig, [defaultBsPopperConfig])
|
||
};
|
||
}
|
||
_selectMenuItem(_ref7) {
|
||
let {
|
||
key,
|
||
target
|
||
} = _ref7;
|
||
const items = SelectorEngine.find(SELECTOR_VISIBLE_ITEMS, this._menu).filter(element => isVisible(element));
|
||
if (!items.length) {
|
||
return;
|
||
}
|
||
|
||
// if target isn't included in items (e.g. when expanding the dropdown)
|
||
// allow cycling to get the last item in case key equals ARROW_UP_KEY
|
||
getNextActiveElement(items, target, key === ARROW_DOWN_KEY$1, !items.includes(target)).focus();
|
||
}
|
||
|
||
// Static
|
||
static jQueryInterface(config) {
|
||
return this.each(function () {
|
||
const data = Dropdown.getOrCreateInstance(this, config);
|
||
if (typeof config !== 'string') {
|
||
return;
|
||
}
|
||
if (typeof data[config] === 'undefined') {
|
||
throw new TypeError(`No method named "${config}"`);
|
||
}
|
||
data[config]();
|
||
});
|
||
}
|
||
static clearMenus(event) {
|
||
if (event.button === RIGHT_MOUSE_BUTTON || event.type === 'keyup' && event.key !== TAB_KEY$1) {
|
||
return;
|
||
}
|
||
const openToggles = SelectorEngine.find(SELECTOR_DATA_TOGGLE_SHOWN);
|
||
for (const toggle of openToggles) {
|
||
const context = Dropdown.getInstance(toggle);
|
||
if (!context || context._config.autoClose === false) {
|
||
continue;
|
||
}
|
||
const composedPath = event.composedPath();
|
||
const isMenuTarget = composedPath.includes(context._menu);
|
||
if (composedPath.includes(context._element) || context._config.autoClose === 'inside' && !isMenuTarget || context._config.autoClose === 'outside' && isMenuTarget) {
|
||
continue;
|
||
}
|
||
|
||
// Tab navigation through the dropdown menu or events from contained inputs shouldn't close the menu
|
||
if (context._menu.contains(event.target) && (event.type === 'keyup' && event.key === TAB_KEY$1 || /input|select|option|textarea|form/i.test(event.target.tagName))) {
|
||
continue;
|
||
}
|
||
const relatedTarget = {
|
||
relatedTarget: context._element
|
||
};
|
||
if (event.type === 'click') {
|
||
relatedTarget.clickEvent = event;
|
||
}
|
||
context._completeHide(relatedTarget);
|
||
}
|
||
}
|
||
static dataApiKeydownHandler(event) {
|
||
// If not an UP | DOWN | ESCAPE key => not a dropdown command
|
||
// If input/textarea && if key is other than ESCAPE => not a dropdown command
|
||
|
||
const isInput = /input|textarea/i.test(event.target.tagName);
|
||
const isEscapeEvent = event.key === ESCAPE_KEY$2;
|
||
const isUpOrDownEvent = [ARROW_UP_KEY$1, ARROW_DOWN_KEY$1].includes(event.key);
|
||
if (!isUpOrDownEvent && !isEscapeEvent) {
|
||
return;
|
||
}
|
||
if (isInput && !isEscapeEvent) {
|
||
return;
|
||
}
|
||
event.preventDefault();
|
||
|
||
// TODO: v6 revert #37011 & change markup https://getbootstrap.com/docs/5.3/forms/input-group/
|
||
const getToggleButton = this.matches(SELECTOR_DATA_TOGGLE$3) ? this : SelectorEngine.prev(this, SELECTOR_DATA_TOGGLE$3)[0] || SelectorEngine.next(this, SELECTOR_DATA_TOGGLE$3)[0] || SelectorEngine.findOne(SELECTOR_DATA_TOGGLE$3, event.delegateTarget.parentNode);
|
||
const instance = Dropdown.getOrCreateInstance(getToggleButton);
|
||
if (isUpOrDownEvent) {
|
||
event.stopPropagation();
|
||
instance.show();
|
||
instance._selectMenuItem(event);
|
||
return;
|
||
}
|
||
if (instance._isShown()) {
|
||
// else is escape and we check if it is shown
|
||
event.stopPropagation();
|
||
instance.hide();
|
||
getToggleButton.focus();
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Data API implementation
|
||
*/
|
||
|
||
EventHandler.on(document, EVENT_KEYDOWN_DATA_API, SELECTOR_DATA_TOGGLE$3, Dropdown.dataApiKeydownHandler);
|
||
EventHandler.on(document, EVENT_KEYDOWN_DATA_API, SELECTOR_MENU, Dropdown.dataApiKeydownHandler);
|
||
EventHandler.on(document, EVENT_CLICK_DATA_API$3, Dropdown.clearMenus);
|
||
EventHandler.on(document, EVENT_KEYUP_DATA_API, Dropdown.clearMenus);
|
||
EventHandler.on(document, EVENT_CLICK_DATA_API$3, SELECTOR_DATA_TOGGLE$3, function (event) {
|
||
event.preventDefault();
|
||
Dropdown.getOrCreateInstance(this).toggle();
|
||
});
|
||
|
||
/**
|
||
* jQuery
|
||
*/
|
||
|
||
defineJQueryPlugin(Dropdown);
|
||
|
||
/**
|
||
* --------------------------------------------------------------------------
|
||
* Bootstrap util/backdrop.js
|
||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||
* --------------------------------------------------------------------------
|
||
*/
|
||
|
||
/**
|
||
* Constants
|
||
*/
|
||
|
||
const NAME$9 = 'backdrop';
|
||
const CLASS_NAME_FADE$4 = 'fade';
|
||
const CLASS_NAME_SHOW$5 = 'show';
|
||
const EVENT_MOUSEDOWN = `mousedown.bs.${NAME$9}`;
|
||
const Default$8 = {
|
||
className: 'modal-backdrop',
|
||
clickCallback: null,
|
||
isAnimated: false,
|
||
isVisible: true,
|
||
// if false, we use the backdrop helper without adding any element to the dom
|
||
rootElement: 'body' // give the choice to place backdrop under different elements
|
||
};
|
||
const DefaultType$8 = {
|
||
className: 'string',
|
||
clickCallback: '(function|null)',
|
||
isAnimated: 'boolean',
|
||
isVisible: 'boolean',
|
||
rootElement: '(element|string)'
|
||
};
|
||
|
||
/**
|
||
* Class definition
|
||
*/
|
||
|
||
class Backdrop extends Config {
|
||
constructor(config) {
|
||
super();
|
||
this._config = this._getConfig(config);
|
||
this._isAppended = false;
|
||
this._element = null;
|
||
}
|
||
|
||
// Getters
|
||
static get Default() {
|
||
return Default$8;
|
||
}
|
||
static get DefaultType() {
|
||
return DefaultType$8;
|
||
}
|
||
static get NAME() {
|
||
return NAME$9;
|
||
}
|
||
|
||
// Public
|
||
show(callback) {
|
||
if (!this._config.isVisible) {
|
||
execute(callback);
|
||
return;
|
||
}
|
||
this._append();
|
||
const element = this._getElement();
|
||
if (this._config.isAnimated) {
|
||
reflow(element);
|
||
}
|
||
element.classList.add(CLASS_NAME_SHOW$5);
|
||
this._emulateAnimation(() => {
|
||
execute(callback);
|
||
});
|
||
}
|
||
hide(callback) {
|
||
if (!this._config.isVisible) {
|
||
execute(callback);
|
||
return;
|
||
}
|
||
this._getElement().classList.remove(CLASS_NAME_SHOW$5);
|
||
this._emulateAnimation(() => {
|
||
this.dispose();
|
||
execute(callback);
|
||
});
|
||
}
|
||
dispose() {
|
||
if (!this._isAppended) {
|
||
return;
|
||
}
|
||
EventHandler.off(this._element, EVENT_MOUSEDOWN);
|
||
this._element.remove();
|
||
this._isAppended = false;
|
||
}
|
||
|
||
// Private
|
||
_getElement() {
|
||
if (!this._element) {
|
||
const backdrop = document.createElement('div');
|
||
backdrop.className = this._config.className;
|
||
if (this._config.isAnimated) {
|
||
backdrop.classList.add(CLASS_NAME_FADE$4);
|
||
}
|
||
this._element = backdrop;
|
||
}
|
||
return this._element;
|
||
}
|
||
_configAfterMerge(config) {
|
||
// use getElement() with the default "body" to get a fresh Element on each instantiation
|
||
config.rootElement = getElement(config.rootElement);
|
||
return config;
|
||
}
|
||
_append() {
|
||
if (this._isAppended) {
|
||
return;
|
||
}
|
||
const element = this._getElement();
|
||
this._config.rootElement.append(element);
|
||
EventHandler.on(element, EVENT_MOUSEDOWN, () => {
|
||
execute(this._config.clickCallback);
|
||
});
|
||
this._isAppended = true;
|
||
}
|
||
_emulateAnimation(callback) {
|
||
executeAfterTransition(callback, this._getElement(), this._config.isAnimated);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* --------------------------------------------------------------------------
|
||
* Bootstrap util/focustrap.js
|
||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||
* --------------------------------------------------------------------------
|
||
*/
|
||
|
||
/**
|
||
* Constants
|
||
*/
|
||
|
||
const NAME$8 = 'focustrap';
|
||
const DATA_KEY$5 = 'bs.focustrap';
|
||
const EVENT_KEY$5 = `.${DATA_KEY$5}`;
|
||
const EVENT_FOCUSIN$2 = `focusin${EVENT_KEY$5}`;
|
||
const EVENT_KEYDOWN_TAB = `keydown.tab${EVENT_KEY$5}`;
|
||
const TAB_KEY = 'Tab';
|
||
const TAB_NAV_FORWARD = 'forward';
|
||
const TAB_NAV_BACKWARD = 'backward';
|
||
const Default$7 = {
|
||
autofocus: true,
|
||
trapElement: null // The element to trap focus inside of
|
||
};
|
||
const DefaultType$7 = {
|
||
autofocus: 'boolean',
|
||
trapElement: 'element'
|
||
};
|
||
|
||
/**
|
||
* Class definition
|
||
*/
|
||
|
||
class FocusTrap extends Config {
|
||
constructor(config) {
|
||
super();
|
||
this._config = this._getConfig(config);
|
||
this._isActive = false;
|
||
this._lastTabNavDirection = null;
|
||
}
|
||
|
||
// Getters
|
||
static get Default() {
|
||
return Default$7;
|
||
}
|
||
static get DefaultType() {
|
||
return DefaultType$7;
|
||
}
|
||
static get NAME() {
|
||
return NAME$8;
|
||
}
|
||
|
||
// Public
|
||
activate() {
|
||
if (this._isActive) {
|
||
return;
|
||
}
|
||
if (this._config.autofocus) {
|
||
this._config.trapElement.focus();
|
||
}
|
||
EventHandler.off(document, EVENT_KEY$5); // guard against infinite focus loop
|
||
EventHandler.on(document, EVENT_FOCUSIN$2, event => this._handleFocusin(event));
|
||
EventHandler.on(document, EVENT_KEYDOWN_TAB, event => this._handleKeydown(event));
|
||
this._isActive = true;
|
||
}
|
||
deactivate() {
|
||
if (!this._isActive) {
|
||
return;
|
||
}
|
||
this._isActive = false;
|
||
EventHandler.off(document, EVENT_KEY$5);
|
||
}
|
||
|
||
// Private
|
||
_handleFocusin(event) {
|
||
const {
|
||
trapElement
|
||
} = this._config;
|
||
if (event.target === document || event.target === trapElement || trapElement.contains(event.target)) {
|
||
return;
|
||
}
|
||
const elements = SelectorEngine.focusableChildren(trapElement);
|
||
if (elements.length === 0) {
|
||
trapElement.focus();
|
||
} else if (this._lastTabNavDirection === TAB_NAV_BACKWARD) {
|
||
elements[elements.length - 1].focus();
|
||
} else {
|
||
elements[0].focus();
|
||
}
|
||
}
|
||
_handleKeydown(event) {
|
||
if (event.key !== TAB_KEY) {
|
||
return;
|
||
}
|
||
this._lastTabNavDirection = event.shiftKey ? TAB_NAV_BACKWARD : TAB_NAV_FORWARD;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* --------------------------------------------------------------------------
|
||
* Bootstrap util/scrollBar.js
|
||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||
* --------------------------------------------------------------------------
|
||
*/
|
||
|
||
/**
|
||
* Constants
|
||
*/
|
||
|
||
const SELECTOR_FIXED_CONTENT = '.fixed-top, .fixed-bottom, .is-fixed, .sticky-top';
|
||
const SELECTOR_STICKY_CONTENT = '.sticky-top';
|
||
const PROPERTY_PADDING = 'padding-right';
|
||
const PROPERTY_MARGIN = 'margin-right';
|
||
|
||
/**
|
||
* Class definition
|
||
*/
|
||
|
||
class ScrollBarHelper {
|
||
constructor() {
|
||
this._element = document.body;
|
||
}
|
||
|
||
// Public
|
||
getWidth() {
|
||
// https://developer.mozilla.org/en-US/docs/Web/API/Window/innerWidth#usage_notes
|
||
const documentWidth = document.documentElement.clientWidth;
|
||
return Math.abs(window.innerWidth - documentWidth);
|
||
}
|
||
hide() {
|
||
const width = this.getWidth();
|
||
this._disableOverFlow();
|
||
// give padding to element to balance the hidden scrollbar width
|
||
this._setElementAttributes(this._element, PROPERTY_PADDING, calculatedValue => calculatedValue + width);
|
||
// trick: We adjust positive paddingRight and negative marginRight to sticky-top elements to keep showing fullwidth
|
||
this._setElementAttributes(SELECTOR_FIXED_CONTENT, PROPERTY_PADDING, calculatedValue => calculatedValue + width);
|
||
this._setElementAttributes(SELECTOR_STICKY_CONTENT, PROPERTY_MARGIN, calculatedValue => calculatedValue - width);
|
||
}
|
||
reset() {
|
||
this._resetElementAttributes(this._element, 'overflow');
|
||
this._resetElementAttributes(this._element, PROPERTY_PADDING);
|
||
this._resetElementAttributes(SELECTOR_FIXED_CONTENT, PROPERTY_PADDING);
|
||
this._resetElementAttributes(SELECTOR_STICKY_CONTENT, PROPERTY_MARGIN);
|
||
}
|
||
isOverflowing() {
|
||
return this.getWidth() > 0;
|
||
}
|
||
|
||
// Private
|
||
_disableOverFlow() {
|
||
this._saveInitialAttribute(this._element, 'overflow');
|
||
this._element.style.overflow = 'hidden';
|
||
}
|
||
_setElementAttributes(selector, styleProperty, callback) {
|
||
const scrollbarWidth = this.getWidth();
|
||
const manipulationCallBack = element => {
|
||
if (element !== this._element && window.innerWidth > element.clientWidth + scrollbarWidth) {
|
||
return;
|
||
}
|
||
this._saveInitialAttribute(element, styleProperty);
|
||
const calculatedValue = window.getComputedStyle(element).getPropertyValue(styleProperty);
|
||
element.style.setProperty(styleProperty, `${callback(Number.parseFloat(calculatedValue))}px`);
|
||
};
|
||
this._applyManipulationCallback(selector, manipulationCallBack);
|
||
}
|
||
_saveInitialAttribute(element, styleProperty) {
|
||
const actualValue = element.style.getPropertyValue(styleProperty);
|
||
if (actualValue) {
|
||
Manipulator.setDataAttribute(element, styleProperty, actualValue);
|
||
}
|
||
}
|
||
_resetElementAttributes(selector, styleProperty) {
|
||
const manipulationCallBack = element => {
|
||
const value = Manipulator.getDataAttribute(element, styleProperty);
|
||
// We only want to remove the property if the value is `null`; the value can also be zero
|
||
if (value === null) {
|
||
element.style.removeProperty(styleProperty);
|
||
return;
|
||
}
|
||
Manipulator.removeDataAttribute(element, styleProperty);
|
||
element.style.setProperty(styleProperty, value);
|
||
};
|
||
this._applyManipulationCallback(selector, manipulationCallBack);
|
||
}
|
||
_applyManipulationCallback(selector, callBack) {
|
||
if (isElement$1(selector)) {
|
||
callBack(selector);
|
||
return;
|
||
}
|
||
for (const sel of SelectorEngine.find(selector, this._element)) {
|
||
callBack(sel);
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* --------------------------------------------------------------------------
|
||
* Bootstrap modal.js
|
||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||
* --------------------------------------------------------------------------
|
||
*/
|
||
|
||
/**
|
||
* Constants
|
||
*/
|
||
|
||
const NAME$7 = 'modal';
|
||
const DATA_KEY$4 = 'bs.modal';
|
||
const EVENT_KEY$4 = `.${DATA_KEY$4}`;
|
||
const DATA_API_KEY$2 = '.data-api';
|
||
const ESCAPE_KEY$1 = 'Escape';
|
||
const EVENT_HIDE$4 = `hide${EVENT_KEY$4}`;
|
||
const EVENT_HIDE_PREVENTED$1 = `hidePrevented${EVENT_KEY$4}`;
|
||
const EVENT_HIDDEN$4 = `hidden${EVENT_KEY$4}`;
|
||
const EVENT_SHOW$4 = `show${EVENT_KEY$4}`;
|
||
const EVENT_SHOWN$4 = `shown${EVENT_KEY$4}`;
|
||
const EVENT_RESIZE$1 = `resize${EVENT_KEY$4}`;
|
||
const EVENT_CLICK_DISMISS = `click.dismiss${EVENT_KEY$4}`;
|
||
const EVENT_MOUSEDOWN_DISMISS = `mousedown.dismiss${EVENT_KEY$4}`;
|
||
const EVENT_KEYDOWN_DISMISS$1 = `keydown.dismiss${EVENT_KEY$4}`;
|
||
const EVENT_CLICK_DATA_API$2 = `click${EVENT_KEY$4}${DATA_API_KEY$2}`;
|
||
const CLASS_NAME_OPEN = 'modal-open';
|
||
const CLASS_NAME_FADE$3 = 'fade';
|
||
const CLASS_NAME_SHOW$4 = 'show';
|
||
const CLASS_NAME_STATIC = 'modal-static';
|
||
const OPEN_SELECTOR$1 = '.modal.show';
|
||
const SELECTOR_DIALOG = '.modal-dialog';
|
||
const SELECTOR_MODAL_BODY = '.modal-body';
|
||
const SELECTOR_DATA_TOGGLE$2 = '[data-bs-toggle="modal"]';
|
||
const Default$6 = {
|
||
backdrop: true,
|
||
focus: true,
|
||
keyboard: true
|
||
};
|
||
const DefaultType$6 = {
|
||
backdrop: '(boolean|string)',
|
||
focus: 'boolean',
|
||
keyboard: 'boolean'
|
||
};
|
||
|
||
/**
|
||
* Class definition
|
||
*/
|
||
|
||
class Modal extends BaseComponent {
|
||
constructor(element, config) {
|
||
super(element, config);
|
||
this._dialog = SelectorEngine.findOne(SELECTOR_DIALOG, this._element);
|
||
this._backdrop = this._initializeBackDrop();
|
||
this._focustrap = this._initializeFocusTrap();
|
||
this._isShown = false;
|
||
this._isTransitioning = false;
|
||
this._scrollBar = new ScrollBarHelper();
|
||
this._addEventListeners();
|
||
}
|
||
|
||
// Getters
|
||
static get Default() {
|
||
return Default$6;
|
||
}
|
||
static get DefaultType() {
|
||
return DefaultType$6;
|
||
}
|
||
static get NAME() {
|
||
return NAME$7;
|
||
}
|
||
|
||
// Public
|
||
toggle(relatedTarget) {
|
||
return this._isShown ? this.hide() : this.show(relatedTarget);
|
||
}
|
||
show(relatedTarget) {
|
||
if (this._isShown || this._isTransitioning) {
|
||
return;
|
||
}
|
||
const showEvent = EventHandler.trigger(this._element, EVENT_SHOW$4, {
|
||
relatedTarget
|
||
});
|
||
if (showEvent.defaultPrevented) {
|
||
return;
|
||
}
|
||
this._isShown = true;
|
||
this._isTransitioning = true;
|
||
this._scrollBar.hide();
|
||
document.body.classList.add(CLASS_NAME_OPEN);
|
||
this._adjustDialog();
|
||
this._backdrop.show(() => this._showElement(relatedTarget));
|
||
}
|
||
hide() {
|
||
if (!this._isShown || this._isTransitioning) {
|
||
return;
|
||
}
|
||
const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE$4);
|
||
if (hideEvent.defaultPrevented) {
|
||
return;
|
||
}
|
||
this._isShown = false;
|
||
this._isTransitioning = true;
|
||
this._focustrap.deactivate();
|
||
this._element.classList.remove(CLASS_NAME_SHOW$4);
|
||
this._queueCallback(() => this._hideModal(), this._element, this._isAnimated());
|
||
}
|
||
dispose() {
|
||
EventHandler.off(window, EVENT_KEY$4);
|
||
EventHandler.off(this._dialog, EVENT_KEY$4);
|
||
this._backdrop.dispose();
|
||
this._focustrap.deactivate();
|
||
super.dispose();
|
||
}
|
||
handleUpdate() {
|
||
this._adjustDialog();
|
||
}
|
||
|
||
// Private
|
||
_initializeBackDrop() {
|
||
return new Backdrop({
|
||
isVisible: Boolean(this._config.backdrop),
|
||
// 'static' option will be translated to true, and booleans will keep their value,
|
||
isAnimated: this._isAnimated()
|
||
});
|
||
}
|
||
_initializeFocusTrap() {
|
||
return new FocusTrap({
|
||
trapElement: this._element
|
||
});
|
||
}
|
||
_showElement(relatedTarget) {
|
||
// try to append dynamic modal
|
||
if (!document.body.contains(this._element)) {
|
||
document.body.append(this._element);
|
||
}
|
||
this._element.style.display = 'block';
|
||
this._element.removeAttribute('aria-hidden');
|
||
this._element.setAttribute('aria-modal', true);
|
||
this._element.setAttribute('role', 'dialog');
|
||
this._element.scrollTop = 0;
|
||
const modalBody = SelectorEngine.findOne(SELECTOR_MODAL_BODY, this._dialog);
|
||
if (modalBody) {
|
||
modalBody.scrollTop = 0;
|
||
}
|
||
reflow(this._element);
|
||
this._element.classList.add(CLASS_NAME_SHOW$4);
|
||
const transitionComplete = () => {
|
||
if (this._config.focus) {
|
||
this._focustrap.activate();
|
||
}
|
||
this._isTransitioning = false;
|
||
EventHandler.trigger(this._element, EVENT_SHOWN$4, {
|
||
relatedTarget
|
||
});
|
||
};
|
||
this._queueCallback(transitionComplete, this._dialog, this._isAnimated());
|
||
}
|
||
_addEventListeners() {
|
||
EventHandler.on(this._element, EVENT_KEYDOWN_DISMISS$1, event => {
|
||
if (event.key !== ESCAPE_KEY$1) {
|
||
return;
|
||
}
|
||
if (this._config.keyboard) {
|
||
this.hide();
|
||
return;
|
||
}
|
||
this._triggerBackdropTransition();
|
||
});
|
||
EventHandler.on(window, EVENT_RESIZE$1, () => {
|
||
if (this._isShown && !this._isTransitioning) {
|
||
this._adjustDialog();
|
||
}
|
||
});
|
||
EventHandler.on(this._element, EVENT_MOUSEDOWN_DISMISS, event => {
|
||
// a bad trick to segregate clicks that may start inside dialog but end outside, and avoid listen to scrollbar clicks
|
||
EventHandler.one(this._element, EVENT_CLICK_DISMISS, event2 => {
|
||
if (this._element !== event.target || this._element !== event2.target) {
|
||
return;
|
||
}
|
||
if (this._config.backdrop === 'static') {
|
||
this._triggerBackdropTransition();
|
||
return;
|
||
}
|
||
if (this._config.backdrop) {
|
||
this.hide();
|
||
}
|
||
});
|
||
});
|
||
}
|
||
_hideModal() {
|
||
this._element.style.display = 'none';
|
||
this._element.setAttribute('aria-hidden', true);
|
||
this._element.removeAttribute('aria-modal');
|
||
this._element.removeAttribute('role');
|
||
this._isTransitioning = false;
|
||
this._backdrop.hide(() => {
|
||
document.body.classList.remove(CLASS_NAME_OPEN);
|
||
this._resetAdjustments();
|
||
this._scrollBar.reset();
|
||
EventHandler.trigger(this._element, EVENT_HIDDEN$4);
|
||
});
|
||
}
|
||
_isAnimated() {
|
||
return this._element.classList.contains(CLASS_NAME_FADE$3);
|
||
}
|
||
_triggerBackdropTransition() {
|
||
const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE_PREVENTED$1);
|
||
if (hideEvent.defaultPrevented) {
|
||
return;
|
||
}
|
||
const isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight;
|
||
const initialOverflowY = this._element.style.overflowY;
|
||
// return if the following background transition hasn't yet completed
|
||
if (initialOverflowY === 'hidden' || this._element.classList.contains(CLASS_NAME_STATIC)) {
|
||
return;
|
||
}
|
||
if (!isModalOverflowing) {
|
||
this._element.style.overflowY = 'hidden';
|
||
}
|
||
this._element.classList.add(CLASS_NAME_STATIC);
|
||
this._queueCallback(() => {
|
||
this._element.classList.remove(CLASS_NAME_STATIC);
|
||
this._queueCallback(() => {
|
||
this._element.style.overflowY = initialOverflowY;
|
||
}, this._dialog);
|
||
}, this._dialog);
|
||
this._element.focus();
|
||
}
|
||
|
||
/**
|
||
* The following methods are used to handle overflowing modals
|
||
*/
|
||
|
||
_adjustDialog() {
|
||
const isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight;
|
||
const scrollbarWidth = this._scrollBar.getWidth();
|
||
const isBodyOverflowing = scrollbarWidth > 0;
|
||
if (isBodyOverflowing && !isModalOverflowing) {
|
||
const property = isRTL() ? 'paddingLeft' : 'paddingRight';
|
||
this._element.style[property] = `${scrollbarWidth}px`;
|
||
}
|
||
if (!isBodyOverflowing && isModalOverflowing) {
|
||
const property = isRTL() ? 'paddingRight' : 'paddingLeft';
|
||
this._element.style[property] = `${scrollbarWidth}px`;
|
||
}
|
||
}
|
||
_resetAdjustments() {
|
||
this._element.style.paddingLeft = '';
|
||
this._element.style.paddingRight = '';
|
||
}
|
||
|
||
// Static
|
||
static jQueryInterface(config, relatedTarget) {
|
||
return this.each(function () {
|
||
const data = Modal.getOrCreateInstance(this, config);
|
||
if (typeof config !== 'string') {
|
||
return;
|
||
}
|
||
if (typeof data[config] === 'undefined') {
|
||
throw new TypeError(`No method named "${config}"`);
|
||
}
|
||
data[config](relatedTarget);
|
||
});
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Data API implementation
|
||
*/
|
||
|
||
EventHandler.on(document, EVENT_CLICK_DATA_API$2, SELECTOR_DATA_TOGGLE$2, function (event) {
|
||
const target = SelectorEngine.getElementFromSelector(this);
|
||
if (['A', 'AREA'].includes(this.tagName)) {
|
||
event.preventDefault();
|
||
}
|
||
EventHandler.one(target, EVENT_SHOW$4, showEvent => {
|
||
if (showEvent.defaultPrevented) {
|
||
// only register focus restorer if modal will actually get shown
|
||
return;
|
||
}
|
||
EventHandler.one(target, EVENT_HIDDEN$4, () => {
|
||
if (isVisible(this)) {
|
||
this.focus();
|
||
}
|
||
});
|
||
});
|
||
|
||
// avoid conflict when clicking modal toggler while another one is open
|
||
const alreadyOpen = SelectorEngine.findOne(OPEN_SELECTOR$1);
|
||
if (alreadyOpen) {
|
||
Modal.getInstance(alreadyOpen).hide();
|
||
}
|
||
const data = Modal.getOrCreateInstance(target);
|
||
data.toggle(this);
|
||
});
|
||
enableDismissTrigger(Modal);
|
||
|
||
/**
|
||
* jQuery
|
||
*/
|
||
|
||
defineJQueryPlugin(Modal);
|
||
|
||
/**
|
||
* --------------------------------------------------------------------------
|
||
* Bootstrap offcanvas.js
|
||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||
* --------------------------------------------------------------------------
|
||
*/
|
||
|
||
/**
|
||
* Constants
|
||
*/
|
||
|
||
const NAME$6 = 'offcanvas';
|
||
const DATA_KEY$3 = 'bs.offcanvas';
|
||
const EVENT_KEY$3 = `.${DATA_KEY$3}`;
|
||
const DATA_API_KEY$1 = '.data-api';
|
||
const EVENT_LOAD_DATA_API$2 = `load${EVENT_KEY$3}${DATA_API_KEY$1}`;
|
||
const ESCAPE_KEY = 'Escape';
|
||
const CLASS_NAME_SHOW$3 = 'show';
|
||
const CLASS_NAME_SHOWING$1 = 'showing';
|
||
const CLASS_NAME_HIDING = 'hiding';
|
||
const CLASS_NAME_BACKDROP = 'offcanvas-backdrop';
|
||
const OPEN_SELECTOR = '.offcanvas.show';
|
||
const EVENT_SHOW$3 = `show${EVENT_KEY$3}`;
|
||
const EVENT_SHOWN$3 = `shown${EVENT_KEY$3}`;
|
||
const EVENT_HIDE$3 = `hide${EVENT_KEY$3}`;
|
||
const EVENT_HIDE_PREVENTED = `hidePrevented${EVENT_KEY$3}`;
|
||
const EVENT_HIDDEN$3 = `hidden${EVENT_KEY$3}`;
|
||
const EVENT_RESIZE = `resize${EVENT_KEY$3}`;
|
||
const EVENT_CLICK_DATA_API$1 = `click${EVENT_KEY$3}${DATA_API_KEY$1}`;
|
||
const EVENT_KEYDOWN_DISMISS = `keydown.dismiss${EVENT_KEY$3}`;
|
||
const SELECTOR_DATA_TOGGLE$1 = '[data-bs-toggle="offcanvas"]';
|
||
const Default$5 = {
|
||
backdrop: true,
|
||
keyboard: true,
|
||
scroll: false
|
||
};
|
||
const DefaultType$5 = {
|
||
backdrop: '(boolean|string)',
|
||
keyboard: 'boolean',
|
||
scroll: 'boolean'
|
||
};
|
||
|
||
/**
|
||
* Class definition
|
||
*/
|
||
|
||
class Offcanvas extends BaseComponent {
|
||
constructor(element, config) {
|
||
super(element, config);
|
||
this._isShown = false;
|
||
this._backdrop = this._initializeBackDrop();
|
||
this._focustrap = this._initializeFocusTrap();
|
||
this._addEventListeners();
|
||
}
|
||
|
||
// Getters
|
||
static get Default() {
|
||
return Default$5;
|
||
}
|
||
static get DefaultType() {
|
||
return DefaultType$5;
|
||
}
|
||
static get NAME() {
|
||
return NAME$6;
|
||
}
|
||
|
||
// Public
|
||
toggle(relatedTarget) {
|
||
return this._isShown ? this.hide() : this.show(relatedTarget);
|
||
}
|
||
show(relatedTarget) {
|
||
if (this._isShown) {
|
||
return;
|
||
}
|
||
const showEvent = EventHandler.trigger(this._element, EVENT_SHOW$3, {
|
||
relatedTarget
|
||
});
|
||
if (showEvent.defaultPrevented) {
|
||
return;
|
||
}
|
||
this._isShown = true;
|
||
this._backdrop.show();
|
||
if (!this._config.scroll) {
|
||
new ScrollBarHelper().hide();
|
||
}
|
||
this._element.setAttribute('aria-modal', true);
|
||
this._element.setAttribute('role', 'dialog');
|
||
this._element.classList.add(CLASS_NAME_SHOWING$1);
|
||
const completeCallBack = () => {
|
||
if (!this._config.scroll || this._config.backdrop) {
|
||
this._focustrap.activate();
|
||
}
|
||
this._element.classList.add(CLASS_NAME_SHOW$3);
|
||
this._element.classList.remove(CLASS_NAME_SHOWING$1);
|
||
EventHandler.trigger(this._element, EVENT_SHOWN$3, {
|
||
relatedTarget
|
||
});
|
||
};
|
||
this._queueCallback(completeCallBack, this._element, true);
|
||
}
|
||
hide() {
|
||
if (!this._isShown) {
|
||
return;
|
||
}
|
||
const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE$3);
|
||
if (hideEvent.defaultPrevented) {
|
||
return;
|
||
}
|
||
this._focustrap.deactivate();
|
||
this._element.blur();
|
||
this._isShown = false;
|
||
this._element.classList.add(CLASS_NAME_HIDING);
|
||
this._backdrop.hide();
|
||
const completeCallback = () => {
|
||
this._element.classList.remove(CLASS_NAME_SHOW$3, CLASS_NAME_HIDING);
|
||
this._element.removeAttribute('aria-modal');
|
||
this._element.removeAttribute('role');
|
||
if (!this._config.scroll) {
|
||
new ScrollBarHelper().reset();
|
||
}
|
||
EventHandler.trigger(this._element, EVENT_HIDDEN$3);
|
||
};
|
||
this._queueCallback(completeCallback, this._element, true);
|
||
}
|
||
dispose() {
|
||
this._backdrop.dispose();
|
||
this._focustrap.deactivate();
|
||
super.dispose();
|
||
}
|
||
|
||
// Private
|
||
_initializeBackDrop() {
|
||
const clickCallback = () => {
|
||
if (this._config.backdrop === 'static') {
|
||
EventHandler.trigger(this._element, EVENT_HIDE_PREVENTED);
|
||
return;
|
||
}
|
||
this.hide();
|
||
};
|
||
|
||
// 'static' option will be translated to true, and booleans will keep their value
|
||
const isVisible = Boolean(this._config.backdrop);
|
||
return new Backdrop({
|
||
className: CLASS_NAME_BACKDROP,
|
||
isVisible,
|
||
isAnimated: true,
|
||
rootElement: this._element.parentNode,
|
||
clickCallback: isVisible ? clickCallback : null
|
||
});
|
||
}
|
||
_initializeFocusTrap() {
|
||
return new FocusTrap({
|
||
trapElement: this._element
|
||
});
|
||
}
|
||
_addEventListeners() {
|
||
EventHandler.on(this._element, EVENT_KEYDOWN_DISMISS, event => {
|
||
if (event.key !== ESCAPE_KEY) {
|
||
return;
|
||
}
|
||
if (this._config.keyboard) {
|
||
this.hide();
|
||
return;
|
||
}
|
||
EventHandler.trigger(this._element, EVENT_HIDE_PREVENTED);
|
||
});
|
||
}
|
||
|
||
// Static
|
||
static jQueryInterface(config) {
|
||
return this.each(function () {
|
||
const data = Offcanvas.getOrCreateInstance(this, config);
|
||
if (typeof config !== 'string') {
|
||
return;
|
||
}
|
||
if (data[config] === undefined || config.startsWith('_') || config === 'constructor') {
|
||
throw new TypeError(`No method named "${config}"`);
|
||
}
|
||
data[config](this);
|
||
});
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Data API implementation
|
||
*/
|
||
|
||
EventHandler.on(document, EVENT_CLICK_DATA_API$1, SELECTOR_DATA_TOGGLE$1, function (event) {
|
||
const target = SelectorEngine.getElementFromSelector(this);
|
||
if (['A', 'AREA'].includes(this.tagName)) {
|
||
event.preventDefault();
|
||
}
|
||
if (isDisabled(this)) {
|
||
return;
|
||
}
|
||
EventHandler.one(target, EVENT_HIDDEN$3, () => {
|
||
// focus on trigger when it is closed
|
||
if (isVisible(this)) {
|
||
this.focus();
|
||
}
|
||
});
|
||
|
||
// avoid conflict when clicking a toggler of an offcanvas, while another is open
|
||
const alreadyOpen = SelectorEngine.findOne(OPEN_SELECTOR);
|
||
if (alreadyOpen && alreadyOpen !== target) {
|
||
Offcanvas.getInstance(alreadyOpen).hide();
|
||
}
|
||
const data = Offcanvas.getOrCreateInstance(target);
|
||
data.toggle(this);
|
||
});
|
||
EventHandler.on(window, EVENT_LOAD_DATA_API$2, () => {
|
||
for (const selector of SelectorEngine.find(OPEN_SELECTOR)) {
|
||
Offcanvas.getOrCreateInstance(selector).show();
|
||
}
|
||
});
|
||
EventHandler.on(window, EVENT_RESIZE, () => {
|
||
for (const element of SelectorEngine.find('[aria-modal][class*=show][class*=offcanvas-]')) {
|
||
if (getComputedStyle(element).position !== 'fixed') {
|
||
Offcanvas.getOrCreateInstance(element).hide();
|
||
}
|
||
}
|
||
});
|
||
enableDismissTrigger(Offcanvas);
|
||
|
||
/**
|
||
* jQuery
|
||
*/
|
||
|
||
defineJQueryPlugin(Offcanvas);
|
||
|
||
/**
|
||
* --------------------------------------------------------------------------
|
||
* Bootstrap util/sanitizer.js
|
||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||
* --------------------------------------------------------------------------
|
||
*/
|
||
|
||
// js-docs-start allow-list
|
||
const ARIA_ATTRIBUTE_PATTERN = /^aria-[\w-]*$/i;
|
||
const DefaultAllowlist = {
|
||
// Global attributes allowed on any supplied element below.
|
||
'*': ['class', 'dir', 'id', 'lang', 'role', ARIA_ATTRIBUTE_PATTERN],
|
||
a: ['target', 'href', 'title', 'rel'],
|
||
area: [],
|
||
b: [],
|
||
br: [],
|
||
col: [],
|
||
code: [],
|
||
dd: [],
|
||
div: [],
|
||
dl: [],
|
||
dt: [],
|
||
em: [],
|
||
hr: [],
|
||
h1: [],
|
||
h2: [],
|
||
h3: [],
|
||
h4: [],
|
||
h5: [],
|
||
h6: [],
|
||
i: [],
|
||
img: ['src', 'srcset', 'alt', 'title', 'width', 'height'],
|
||
li: [],
|
||
ol: [],
|
||
p: [],
|
||
pre: [],
|
||
s: [],
|
||
small: [],
|
||
span: [],
|
||
sub: [],
|
||
sup: [],
|
||
strong: [],
|
||
u: [],
|
||
ul: []
|
||
};
|
||
// js-docs-end allow-list
|
||
|
||
const uriAttributes = new Set(['background', 'cite', 'href', 'itemtype', 'longdesc', 'poster', 'src', 'xlink:href']);
|
||
|
||
/**
|
||
* A pattern that recognizes URLs that are safe wrt. XSS in URL navigation
|
||
* contexts.
|
||
*
|
||
* Shout-out to Angular https://github.com/angular/angular/blob/15.2.8/packages/core/src/sanitization/url_sanitizer.ts#L38
|
||
*/
|
||
// eslint-disable-next-line unicorn/better-regex
|
||
const SAFE_URL_PATTERN = /^(?!javascript:)(?:[a-z0-9+.-]+:|[^&:/?#]*(?:[/?#]|$))/i;
|
||
const allowedAttribute = (attribute, allowedAttributeList) => {
|
||
const attributeName = attribute.nodeName.toLowerCase();
|
||
if (allowedAttributeList.includes(attributeName)) {
|
||
if (uriAttributes.has(attributeName)) {
|
||
return Boolean(SAFE_URL_PATTERN.test(attribute.nodeValue));
|
||
}
|
||
return true;
|
||
}
|
||
|
||
// Check if a regular expression validates the attribute.
|
||
return allowedAttributeList.filter(attributeRegex => attributeRegex instanceof RegExp).some(regex => regex.test(attributeName));
|
||
};
|
||
function sanitizeHtml(unsafeHtml, allowList, sanitizeFunction) {
|
||
if (!unsafeHtml.length) {
|
||
return unsafeHtml;
|
||
}
|
||
if (sanitizeFunction && typeof sanitizeFunction === 'function') {
|
||
return sanitizeFunction(unsafeHtml);
|
||
}
|
||
const domParser = new window.DOMParser();
|
||
const createdDocument = domParser.parseFromString(unsafeHtml, 'text/html');
|
||
const elements = [].concat(...createdDocument.body.querySelectorAll('*'));
|
||
for (const element of elements) {
|
||
const elementName = element.nodeName.toLowerCase();
|
||
if (!Object.keys(allowList).includes(elementName)) {
|
||
element.remove();
|
||
continue;
|
||
}
|
||
const attributeList = [].concat(...element.attributes);
|
||
const allowedAttributes = [].concat(allowList['*'] || [], allowList[elementName] || []);
|
||
for (const attribute of attributeList) {
|
||
if (!allowedAttribute(attribute, allowedAttributes)) {
|
||
element.removeAttribute(attribute.nodeName);
|
||
}
|
||
}
|
||
}
|
||
return createdDocument.body.innerHTML;
|
||
}
|
||
|
||
/**
|
||
* --------------------------------------------------------------------------
|
||
* Bootstrap util/template-factory.js
|
||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||
* --------------------------------------------------------------------------
|
||
*/
|
||
|
||
/**
|
||
* Constants
|
||
*/
|
||
|
||
const NAME$5 = 'TemplateFactory';
|
||
const Default$4 = {
|
||
allowList: DefaultAllowlist,
|
||
content: {},
|
||
// { selector : text , selector2 : text2 , }
|
||
extraClass: '',
|
||
html: false,
|
||
sanitize: true,
|
||
sanitizeFn: null,
|
||
template: '<div></div>'
|
||
};
|
||
const DefaultType$4 = {
|
||
allowList: 'object',
|
||
content: 'object',
|
||
extraClass: '(string|function)',
|
||
html: 'boolean',
|
||
sanitize: 'boolean',
|
||
sanitizeFn: '(null|function)',
|
||
template: 'string'
|
||
};
|
||
const DefaultContentType = {
|
||
entry: '(string|element|function|null)',
|
||
selector: '(string|element)'
|
||
};
|
||
|
||
/**
|
||
* Class definition
|
||
*/
|
||
|
||
class TemplateFactory extends Config {
|
||
constructor(config) {
|
||
super();
|
||
this._config = this._getConfig(config);
|
||
}
|
||
|
||
// Getters
|
||
static get Default() {
|
||
return Default$4;
|
||
}
|
||
static get DefaultType() {
|
||
return DefaultType$4;
|
||
}
|
||
static get NAME() {
|
||
return NAME$5;
|
||
}
|
||
|
||
// Public
|
||
getContent() {
|
||
return Object.values(this._config.content).map(config => this._resolvePossibleFunction(config)).filter(Boolean);
|
||
}
|
||
hasContent() {
|
||
return this.getContent().length > 0;
|
||
}
|
||
changeContent(content) {
|
||
this._checkContent(content);
|
||
this._config.content = {
|
||
...this._config.content,
|
||
...content
|
||
};
|
||
return this;
|
||
}
|
||
toHtml() {
|
||
const templateWrapper = document.createElement('div');
|
||
templateWrapper.innerHTML = this._maybeSanitize(this._config.template);
|
||
for (const [selector, text] of Object.entries(this._config.content)) {
|
||
this._setContent(templateWrapper, text, selector);
|
||
}
|
||
const template = templateWrapper.children[0];
|
||
const extraClass = this._resolvePossibleFunction(this._config.extraClass);
|
||
if (extraClass) {
|
||
template.classList.add(...extraClass.split(' '));
|
||
}
|
||
return template;
|
||
}
|
||
|
||
// Private
|
||
_typeCheckConfig(config) {
|
||
super._typeCheckConfig(config);
|
||
this._checkContent(config.content);
|
||
}
|
||
_checkContent(arg) {
|
||
for (const [selector, content] of Object.entries(arg)) {
|
||
super._typeCheckConfig({
|
||
selector,
|
||
entry: content
|
||
}, DefaultContentType);
|
||
}
|
||
}
|
||
_setContent(template, content, selector) {
|
||
const templateElement = SelectorEngine.findOne(selector, template);
|
||
if (!templateElement) {
|
||
return;
|
||
}
|
||
content = this._resolvePossibleFunction(content);
|
||
if (!content) {
|
||
templateElement.remove();
|
||
return;
|
||
}
|
||
if (isElement$1(content)) {
|
||
this._putElementInTemplate(getElement(content), templateElement);
|
||
return;
|
||
}
|
||
if (this._config.html) {
|
||
templateElement.innerHTML = this._maybeSanitize(content);
|
||
return;
|
||
}
|
||
templateElement.textContent = content;
|
||
}
|
||
_maybeSanitize(arg) {
|
||
return this._config.sanitize ? sanitizeHtml(arg, this._config.allowList, this._config.sanitizeFn) : arg;
|
||
}
|
||
_resolvePossibleFunction(arg) {
|
||
return execute(arg, [this]);
|
||
}
|
||
_putElementInTemplate(element, templateElement) {
|
||
if (this._config.html) {
|
||
templateElement.innerHTML = '';
|
||
templateElement.append(element);
|
||
return;
|
||
}
|
||
templateElement.textContent = element.textContent;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* --------------------------------------------------------------------------
|
||
* Bootstrap tooltip.js
|
||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||
* --------------------------------------------------------------------------
|
||
*/
|
||
|
||
/**
|
||
* Constants
|
||
*/
|
||
|
||
const NAME$4 = 'tooltip';
|
||
const DISALLOWED_ATTRIBUTES = new Set(['sanitize', 'allowList', 'sanitizeFn']);
|
||
const CLASS_NAME_FADE$2 = 'fade';
|
||
const CLASS_NAME_MODAL = 'modal';
|
||
const CLASS_NAME_SHOW$2 = 'show';
|
||
const SELECTOR_TOOLTIP_INNER = '.tooltip-inner';
|
||
const SELECTOR_MODAL = `.${CLASS_NAME_MODAL}`;
|
||
const EVENT_MODAL_HIDE = 'hide.bs.modal';
|
||
const TRIGGER_HOVER = 'hover';
|
||
const TRIGGER_FOCUS = 'focus';
|
||
const TRIGGER_CLICK = 'click';
|
||
const TRIGGER_MANUAL = 'manual';
|
||
const EVENT_HIDE$2 = 'hide';
|
||
const EVENT_HIDDEN$2 = 'hidden';
|
||
const EVENT_SHOW$2 = 'show';
|
||
const EVENT_SHOWN$2 = 'shown';
|
||
const EVENT_INSERTED = 'inserted';
|
||
const EVENT_CLICK$1 = 'click';
|
||
const EVENT_FOCUSIN$1 = 'focusin';
|
||
const EVENT_FOCUSOUT$1 = 'focusout';
|
||
const EVENT_MOUSEENTER = 'mouseenter';
|
||
const EVENT_MOUSELEAVE = 'mouseleave';
|
||
const AttachmentMap = {
|
||
AUTO: 'auto',
|
||
TOP: 'top',
|
||
RIGHT: isRTL() ? 'left' : 'right',
|
||
BOTTOM: 'bottom',
|
||
LEFT: isRTL() ? 'right' : 'left'
|
||
};
|
||
const Default$3 = {
|
||
allowList: DefaultAllowlist,
|
||
animation: true,
|
||
boundary: 'clippingParents',
|
||
container: false,
|
||
customClass: '',
|
||
delay: 0,
|
||
fallbackPlacements: ['top', 'right', 'bottom', 'left'],
|
||
html: false,
|
||
offset: [0, 6],
|
||
placement: 'top',
|
||
popperConfig: null,
|
||
sanitize: true,
|
||
sanitizeFn: null,
|
||
selector: false,
|
||
template: '<div class="tooltip" role="tooltip">' + '<div class="tooltip-arrow"></div>' + '<div class="tooltip-inner"></div>' + '</div>',
|
||
title: '',
|
||
trigger: 'hover focus'
|
||
};
|
||
const DefaultType$3 = {
|
||
allowList: 'object',
|
||
animation: 'boolean',
|
||
boundary: '(string|element)',
|
||
container: '(string|element|boolean)',
|
||
customClass: '(string|function)',
|
||
delay: '(number|object)',
|
||
fallbackPlacements: 'array',
|
||
html: 'boolean',
|
||
offset: '(array|string|function)',
|
||
placement: '(string|function)',
|
||
popperConfig: '(null|object|function)',
|
||
sanitize: 'boolean',
|
||
sanitizeFn: '(null|function)',
|
||
selector: '(string|boolean)',
|
||
template: 'string',
|
||
title: '(string|element|function)',
|
||
trigger: 'string'
|
||
};
|
||
|
||
/**
|
||
* Class definition
|
||
*/
|
||
|
||
class Tooltip extends BaseComponent {
|
||
constructor(element, config) {
|
||
if (typeof Popper === 'undefined') {
|
||
throw new TypeError('Bootstrap\'s tooltips require Popper (https://popper.js.org)');
|
||
}
|
||
super(element, config);
|
||
|
||
// Private
|
||
this._isEnabled = true;
|
||
this._timeout = 0;
|
||
this._isHovered = null;
|
||
this._activeTrigger = {};
|
||
this._popper = null;
|
||
this._templateFactory = null;
|
||
this._newContent = null;
|
||
|
||
// Protected
|
||
this.tip = null;
|
||
this._setListeners();
|
||
if (!this._config.selector) {
|
||
this._fixTitle();
|
||
}
|
||
}
|
||
|
||
// Getters
|
||
static get Default() {
|
||
return Default$3;
|
||
}
|
||
static get DefaultType() {
|
||
return DefaultType$3;
|
||
}
|
||
static get NAME() {
|
||
return NAME$4;
|
||
}
|
||
|
||
// Public
|
||
enable() {
|
||
this._isEnabled = true;
|
||
}
|
||
disable() {
|
||
this._isEnabled = false;
|
||
}
|
||
toggleEnabled() {
|
||
this._isEnabled = !this._isEnabled;
|
||
}
|
||
toggle() {
|
||
if (!this._isEnabled) {
|
||
return;
|
||
}
|
||
this._activeTrigger.click = !this._activeTrigger.click;
|
||
if (this._isShown()) {
|
||
this._leave();
|
||
return;
|
||
}
|
||
this._enter();
|
||
}
|
||
dispose() {
|
||
clearTimeout(this._timeout);
|
||
EventHandler.off(this._element.closest(SELECTOR_MODAL), EVENT_MODAL_HIDE, this._hideModalHandler);
|
||
if (this._element.getAttribute('data-bs-original-title')) {
|
||
this._element.setAttribute('title', this._element.getAttribute('data-bs-original-title'));
|
||
}
|
||
this._disposePopper();
|
||
super.dispose();
|
||
}
|
||
show() {
|
||
if (this._element.style.display === 'none') {
|
||
throw new Error('Please use show on visible elements');
|
||
}
|
||
if (!(this._isWithContent() && this._isEnabled)) {
|
||
return;
|
||
}
|
||
const showEvent = EventHandler.trigger(this._element, this.constructor.eventName(EVENT_SHOW$2));
|
||
const shadowRoot = findShadowRoot(this._element);
|
||
const isInTheDom = (shadowRoot || this._element.ownerDocument.documentElement).contains(this._element);
|
||
if (showEvent.defaultPrevented || !isInTheDom) {
|
||
return;
|
||
}
|
||
|
||
// TODO: v6 remove this or make it optional
|
||
this._disposePopper();
|
||
const tip = this._getTipElement();
|
||
this._element.setAttribute('aria-describedby', tip.getAttribute('id'));
|
||
const {
|
||
container
|
||
} = this._config;
|
||
if (!this._element.ownerDocument.documentElement.contains(this.tip)) {
|
||
container.append(tip);
|
||
EventHandler.trigger(this._element, this.constructor.eventName(EVENT_INSERTED));
|
||
}
|
||
this._popper = this._createPopper(tip);
|
||
tip.classList.add(CLASS_NAME_SHOW$2);
|
||
|
||
// If this is a touch-enabled device we add extra
|
||
// empty mouseover listeners to the body's immediate children;
|
||
// only needed because of broken event delegation on iOS
|
||
// https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html
|
||
if ('ontouchstart' in document.documentElement) {
|
||
for (const element of [].concat(...document.body.children)) {
|
||
EventHandler.on(element, 'mouseover', noop);
|
||
}
|
||
}
|
||
const complete = () => {
|
||
EventHandler.trigger(this._element, this.constructor.eventName(EVENT_SHOWN$2));
|
||
if (this._isHovered === false) {
|
||
this._leave();
|
||
}
|
||
this._isHovered = false;
|
||
};
|
||
this._queueCallback(complete, this.tip, this._isAnimated());
|
||
}
|
||
hide() {
|
||
if (!this._isShown()) {
|
||
return;
|
||
}
|
||
const hideEvent = EventHandler.trigger(this._element, this.constructor.eventName(EVENT_HIDE$2));
|
||
if (hideEvent.defaultPrevented) {
|
||
return;
|
||
}
|
||
const tip = this._getTipElement();
|
||
tip.classList.remove(CLASS_NAME_SHOW$2);
|
||
|
||
// If this is a touch-enabled device we remove the extra
|
||
// empty mouseover listeners we added for iOS support
|
||
if ('ontouchstart' in document.documentElement) {
|
||
for (const element of [].concat(...document.body.children)) {
|
||
EventHandler.off(element, 'mouseover', noop);
|
||
}
|
||
}
|
||
this._activeTrigger[TRIGGER_CLICK] = false;
|
||
this._activeTrigger[TRIGGER_FOCUS] = false;
|
||
this._activeTrigger[TRIGGER_HOVER] = false;
|
||
this._isHovered = null; // it is a trick to support manual triggering
|
||
|
||
const complete = () => {
|
||
if (this._isWithActiveTrigger()) {
|
||
return;
|
||
}
|
||
if (!this._isHovered) {
|
||
this._disposePopper();
|
||
}
|
||
this._element.removeAttribute('aria-describedby');
|
||
EventHandler.trigger(this._element, this.constructor.eventName(EVENT_HIDDEN$2));
|
||
};
|
||
this._queueCallback(complete, this.tip, this._isAnimated());
|
||
}
|
||
update() {
|
||
if (this._popper) {
|
||
this._popper.update();
|
||
}
|
||
}
|
||
|
||
// Protected
|
||
_isWithContent() {
|
||
return Boolean(this._getTitle());
|
||
}
|
||
_getTipElement() {
|
||
if (!this.tip) {
|
||
this.tip = this._createTipElement(this._newContent || this._getContentForTemplate());
|
||
}
|
||
return this.tip;
|
||
}
|
||
_createTipElement(content) {
|
||
const tip = this._getTemplateFactory(content).toHtml();
|
||
|
||
// TODO: remove this check in v6
|
||
if (!tip) {
|
||
return null;
|
||
}
|
||
tip.classList.remove(CLASS_NAME_FADE$2, CLASS_NAME_SHOW$2);
|
||
// TODO: v6 the following can be achieved with CSS only
|
||
tip.classList.add(`bs-${this.constructor.NAME}-auto`);
|
||
const tipId = getUID(this.constructor.NAME).toString();
|
||
tip.setAttribute('id', tipId);
|
||
if (this._isAnimated()) {
|
||
tip.classList.add(CLASS_NAME_FADE$2);
|
||
}
|
||
return tip;
|
||
}
|
||
setContent(content) {
|
||
this._newContent = content;
|
||
if (this._isShown()) {
|
||
this._disposePopper();
|
||
this.show();
|
||
}
|
||
}
|
||
_getTemplateFactory(content) {
|
||
if (this._templateFactory) {
|
||
this._templateFactory.changeContent(content);
|
||
} else {
|
||
this._templateFactory = new TemplateFactory({
|
||
...this._config,
|
||
// the `content` var has to be after `this._config`
|
||
// to override config.content in case of popover
|
||
content,
|
||
extraClass: this._resolvePossibleFunction(this._config.customClass)
|
||
});
|
||
}
|
||
return this._templateFactory;
|
||
}
|
||
_getContentForTemplate() {
|
||
return {
|
||
[SELECTOR_TOOLTIP_INNER]: this._getTitle()
|
||
};
|
||
}
|
||
_getTitle() {
|
||
return this._resolvePossibleFunction(this._config.title) || this._element.getAttribute('data-bs-original-title');
|
||
}
|
||
|
||
// Private
|
||
_initializeOnDelegatedTarget(event) {
|
||
return this.constructor.getOrCreateInstance(event.delegateTarget, this._getDelegateConfig());
|
||
}
|
||
_isAnimated() {
|
||
return this._config.animation || this.tip && this.tip.classList.contains(CLASS_NAME_FADE$2);
|
||
}
|
||
_isShown() {
|
||
return this.tip && this.tip.classList.contains(CLASS_NAME_SHOW$2);
|
||
}
|
||
_createPopper(tip) {
|
||
const placement = execute(this._config.placement, [this, tip, this._element]);
|
||
const attachment = AttachmentMap[placement.toUpperCase()];
|
||
return createPopper(this._element, tip, this._getPopperConfig(attachment));
|
||
}
|
||
_getOffset() {
|
||
const {
|
||
offset
|
||
} = this._config;
|
||
if (typeof offset === 'string') {
|
||
return offset.split(',').map(value => Number.parseInt(value, 10));
|
||
}
|
||
if (typeof offset === 'function') {
|
||
return popperData => offset(popperData, this._element);
|
||
}
|
||
return offset;
|
||
}
|
||
_resolvePossibleFunction(arg) {
|
||
return execute(arg, [this._element]);
|
||
}
|
||
_getPopperConfig(attachment) {
|
||
const defaultBsPopperConfig = {
|
||
placement: attachment,
|
||
modifiers: [{
|
||
name: 'flip',
|
||
options: {
|
||
fallbackPlacements: this._config.fallbackPlacements
|
||
}
|
||
}, {
|
||
name: 'offset',
|
||
options: {
|
||
offset: this._getOffset()
|
||
}
|
||
}, {
|
||
name: 'preventOverflow',
|
||
options: {
|
||
boundary: this._config.boundary
|
||
}
|
||
}, {
|
||
name: 'arrow',
|
||
options: {
|
||
element: `.${this.constructor.NAME}-arrow`
|
||
}
|
||
}, {
|
||
name: 'preSetPlacement',
|
||
enabled: true,
|
||
phase: 'beforeMain',
|
||
fn: data => {
|
||
// Pre-set Popper's placement attribute in order to read the arrow sizes properly.
|
||
// Otherwise, Popper mixes up the width and height dimensions since the initial arrow style is for top placement
|
||
this._getTipElement().setAttribute('data-popper-placement', data.state.placement);
|
||
}
|
||
}]
|
||
};
|
||
return {
|
||
...defaultBsPopperConfig,
|
||
...execute(this._config.popperConfig, [defaultBsPopperConfig])
|
||
};
|
||
}
|
||
_setListeners() {
|
||
const triggers = this._config.trigger.split(' ');
|
||
for (const trigger of triggers) {
|
||
if (trigger === 'click') {
|
||
EventHandler.on(this._element, this.constructor.eventName(EVENT_CLICK$1), this._config.selector, event => {
|
||
const context = this._initializeOnDelegatedTarget(event);
|
||
context.toggle();
|
||
});
|
||
} else if (trigger !== TRIGGER_MANUAL) {
|
||
const eventIn = trigger === TRIGGER_HOVER ? this.constructor.eventName(EVENT_MOUSEENTER) : this.constructor.eventName(EVENT_FOCUSIN$1);
|
||
const eventOut = trigger === TRIGGER_HOVER ? this.constructor.eventName(EVENT_MOUSELEAVE) : this.constructor.eventName(EVENT_FOCUSOUT$1);
|
||
EventHandler.on(this._element, eventIn, this._config.selector, event => {
|
||
const context = this._initializeOnDelegatedTarget(event);
|
||
context._activeTrigger[event.type === 'focusin' ? TRIGGER_FOCUS : TRIGGER_HOVER] = true;
|
||
context._enter();
|
||
});
|
||
EventHandler.on(this._element, eventOut, this._config.selector, event => {
|
||
const context = this._initializeOnDelegatedTarget(event);
|
||
context._activeTrigger[event.type === 'focusout' ? TRIGGER_FOCUS : TRIGGER_HOVER] = context._element.contains(event.relatedTarget);
|
||
context._leave();
|
||
});
|
||
}
|
||
}
|
||
this._hideModalHandler = () => {
|
||
if (this._element) {
|
||
this.hide();
|
||
}
|
||
};
|
||
EventHandler.on(this._element.closest(SELECTOR_MODAL), EVENT_MODAL_HIDE, this._hideModalHandler);
|
||
}
|
||
_fixTitle() {
|
||
const title = this._element.getAttribute('title');
|
||
if (!title) {
|
||
return;
|
||
}
|
||
if (!this._element.getAttribute('aria-label') && !this._element.textContent.trim()) {
|
||
this._element.setAttribute('aria-label', title);
|
||
}
|
||
this._element.setAttribute('data-bs-original-title', title); // DO NOT USE IT. Is only for backwards compatibility
|
||
this._element.removeAttribute('title');
|
||
}
|
||
_enter() {
|
||
if (this._isShown() || this._isHovered) {
|
||
this._isHovered = true;
|
||
return;
|
||
}
|
||
this._isHovered = true;
|
||
this._setTimeout(() => {
|
||
if (this._isHovered) {
|
||
this.show();
|
||
}
|
||
}, this._config.delay.show);
|
||
}
|
||
_leave() {
|
||
if (this._isWithActiveTrigger()) {
|
||
return;
|
||
}
|
||
this._isHovered = false;
|
||
this._setTimeout(() => {
|
||
if (!this._isHovered) {
|
||
this.hide();
|
||
}
|
||
}, this._config.delay.hide);
|
||
}
|
||
_setTimeout(handler, timeout) {
|
||
clearTimeout(this._timeout);
|
||
this._timeout = setTimeout(handler, timeout);
|
||
}
|
||
_isWithActiveTrigger() {
|
||
return Object.values(this._activeTrigger).includes(true);
|
||
}
|
||
_getConfig(config) {
|
||
const dataAttributes = Manipulator.getDataAttributes(this._element);
|
||
for (const dataAttribute of Object.keys(dataAttributes)) {
|
||
if (DISALLOWED_ATTRIBUTES.has(dataAttribute)) {
|
||
delete dataAttributes[dataAttribute];
|
||
}
|
||
}
|
||
config = {
|
||
...dataAttributes,
|
||
...(typeof config === 'object' && config ? config : {})
|
||
};
|
||
config = this._mergeConfigObj(config);
|
||
config = this._configAfterMerge(config);
|
||
this._typeCheckConfig(config);
|
||
return config;
|
||
}
|
||
_configAfterMerge(config) {
|
||
config.container = config.container === false ? document.body : getElement(config.container);
|
||
if (typeof config.delay === 'number') {
|
||
config.delay = {
|
||
show: config.delay,
|
||
hide: config.delay
|
||
};
|
||
}
|
||
if (typeof config.title === 'number') {
|
||
config.title = config.title.toString();
|
||
}
|
||
if (typeof config.content === 'number') {
|
||
config.content = config.content.toString();
|
||
}
|
||
return config;
|
||
}
|
||
_getDelegateConfig() {
|
||
const config = {};
|
||
for (const [key, value] of Object.entries(this._config)) {
|
||
if (this.constructor.Default[key] !== value) {
|
||
config[key] = value;
|
||
}
|
||
}
|
||
config.selector = false;
|
||
config.trigger = 'manual';
|
||
|
||
// In the future can be replaced with:
|
||
// const keysWithDifferentValues = Object.entries(this._config).filter(entry => this.constructor.Default[entry[0]] !== this._config[entry[0]])
|
||
// `Object.fromEntries(keysWithDifferentValues)`
|
||
return config;
|
||
}
|
||
_disposePopper() {
|
||
if (this._popper) {
|
||
this._popper.destroy();
|
||
this._popper = null;
|
||
}
|
||
if (this.tip) {
|
||
this.tip.remove();
|
||
this.tip = null;
|
||
}
|
||
}
|
||
|
||
// Static
|
||
static jQueryInterface(config) {
|
||
return this.each(function () {
|
||
const data = Tooltip.getOrCreateInstance(this, config);
|
||
if (typeof config !== 'string') {
|
||
return;
|
||
}
|
||
if (typeof data[config] === 'undefined') {
|
||
throw new TypeError(`No method named "${config}"`);
|
||
}
|
||
data[config]();
|
||
});
|
||
}
|
||
}
|
||
|
||
/**
|
||
* jQuery
|
||
*/
|
||
|
||
defineJQueryPlugin(Tooltip);
|
||
|
||
/**
|
||
* --------------------------------------------------------------------------
|
||
* Bootstrap popover.js
|
||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||
* --------------------------------------------------------------------------
|
||
*/
|
||
|
||
/**
|
||
* Constants
|
||
*/
|
||
|
||
const NAME$3 = 'popover';
|
||
const SELECTOR_TITLE = '.popover-header';
|
||
const SELECTOR_CONTENT = '.popover-body';
|
||
const Default$2 = {
|
||
...Tooltip.Default,
|
||
content: '',
|
||
offset: [0, 8],
|
||
placement: 'right',
|
||
template: '<div class="popover" role="tooltip">' + '<div class="popover-arrow"></div>' + '<h3 class="popover-header"></h3>' + '<div class="popover-body"></div>' + '</div>',
|
||
trigger: 'click'
|
||
};
|
||
const DefaultType$2 = {
|
||
...Tooltip.DefaultType,
|
||
content: '(null|string|element|function)'
|
||
};
|
||
|
||
/**
|
||
* Class definition
|
||
*/
|
||
|
||
class Popover extends Tooltip {
|
||
// Getters
|
||
static get Default() {
|
||
return Default$2;
|
||
}
|
||
static get DefaultType() {
|
||
return DefaultType$2;
|
||
}
|
||
static get NAME() {
|
||
return NAME$3;
|
||
}
|
||
|
||
// Overrides
|
||
_isWithContent() {
|
||
return this._getTitle() || this._getContent();
|
||
}
|
||
|
||
// Private
|
||
_getContentForTemplate() {
|
||
return {
|
||
[SELECTOR_TITLE]: this._getTitle(),
|
||
[SELECTOR_CONTENT]: this._getContent()
|
||
};
|
||
}
|
||
_getContent() {
|
||
return this._resolvePossibleFunction(this._config.content);
|
||
}
|
||
|
||
// Static
|
||
static jQueryInterface(config) {
|
||
return this.each(function () {
|
||
const data = Popover.getOrCreateInstance(this, config);
|
||
if (typeof config !== 'string') {
|
||
return;
|
||
}
|
||
if (typeof data[config] === 'undefined') {
|
||
throw new TypeError(`No method named "${config}"`);
|
||
}
|
||
data[config]();
|
||
});
|
||
}
|
||
}
|
||
|
||
/**
|
||
* jQuery
|
||
*/
|
||
|
||
defineJQueryPlugin(Popover);
|
||
|
||
/**
|
||
* --------------------------------------------------------------------------
|
||
* Bootstrap scrollspy.js
|
||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||
* --------------------------------------------------------------------------
|
||
*/
|
||
|
||
/**
|
||
* Constants
|
||
*/
|
||
|
||
const NAME$2 = 'scrollspy';
|
||
const DATA_KEY$2 = 'bs.scrollspy';
|
||
const EVENT_KEY$2 = `.${DATA_KEY$2}`;
|
||
const DATA_API_KEY = '.data-api';
|
||
const EVENT_ACTIVATE = `activate${EVENT_KEY$2}`;
|
||
const EVENT_CLICK = `click${EVENT_KEY$2}`;
|
||
const EVENT_LOAD_DATA_API$1 = `load${EVENT_KEY$2}${DATA_API_KEY}`;
|
||
const CLASS_NAME_DROPDOWN_ITEM = 'dropdown-item';
|
||
const CLASS_NAME_ACTIVE$1 = 'active';
|
||
const SELECTOR_DATA_SPY = '[data-bs-spy="scroll"]';
|
||
const SELECTOR_TARGET_LINKS = '[href]';
|
||
const SELECTOR_NAV_LIST_GROUP = '.nav, .list-group';
|
||
const SELECTOR_NAV_LINKS = '.nav-link';
|
||
const SELECTOR_NAV_ITEMS = '.nav-item';
|
||
const SELECTOR_LIST_ITEMS = '.list-group-item';
|
||
const SELECTOR_LINK_ITEMS = `${SELECTOR_NAV_LINKS}, ${SELECTOR_NAV_ITEMS} > ${SELECTOR_NAV_LINKS}, ${SELECTOR_LIST_ITEMS}`;
|
||
const SELECTOR_DROPDOWN = '.dropdown';
|
||
const SELECTOR_DROPDOWN_TOGGLE$1 = '.dropdown-toggle';
|
||
const Default$1 = {
|
||
offset: null,
|
||
// TODO: v6 @deprecated, keep it for backwards compatibility reasons
|
||
rootMargin: '0px 0px -25%',
|
||
smoothScroll: false,
|
||
target: null,
|
||
threshold: [0.1, 0.5, 1]
|
||
};
|
||
const DefaultType$1 = {
|
||
offset: '(number|null)',
|
||
// TODO v6 @deprecated, keep it for backwards compatibility reasons
|
||
rootMargin: 'string',
|
||
smoothScroll: 'boolean',
|
||
target: 'element',
|
||
threshold: 'array'
|
||
};
|
||
|
||
/**
|
||
* Class definition
|
||
*/
|
||
|
||
class ScrollSpy extends BaseComponent {
|
||
constructor(element, config) {
|
||
super(element, config);
|
||
|
||
// this._element is the observablesContainer and config.target the menu links wrapper
|
||
this._targetLinks = new Map();
|
||
this._observableSections = new Map();
|
||
this._rootElement = getComputedStyle(this._element).overflowY === 'visible' ? null : this._element;
|
||
this._activeTarget = null;
|
||
this._observer = null;
|
||
this._previousScrollData = {
|
||
visibleEntryTop: 0,
|
||
parentScrollTop: 0
|
||
};
|
||
this.refresh(); // initialize
|
||
}
|
||
|
||
// Getters
|
||
static get Default() {
|
||
return Default$1;
|
||
}
|
||
static get DefaultType() {
|
||
return DefaultType$1;
|
||
}
|
||
static get NAME() {
|
||
return NAME$2;
|
||
}
|
||
|
||
// Public
|
||
refresh() {
|
||
this._initializeTargetsAndObservables();
|
||
this._maybeEnableSmoothScroll();
|
||
if (this._observer) {
|
||
this._observer.disconnect();
|
||
} else {
|
||
this._observer = this._getNewObserver();
|
||
}
|
||
for (const section of this._observableSections.values()) {
|
||
this._observer.observe(section);
|
||
}
|
||
}
|
||
dispose() {
|
||
this._observer.disconnect();
|
||
super.dispose();
|
||
}
|
||
|
||
// Private
|
||
_configAfterMerge(config) {
|
||
// TODO: on v6 target should be given explicitly & remove the {target: 'ss-target'} case
|
||
config.target = getElement(config.target) || document.body;
|
||
|
||
// TODO: v6 Only for backwards compatibility reasons. Use rootMargin only
|
||
config.rootMargin = config.offset ? `${config.offset}px 0px -30%` : config.rootMargin;
|
||
if (typeof config.threshold === 'string') {
|
||
config.threshold = config.threshold.split(',').map(value => Number.parseFloat(value));
|
||
}
|
||
return config;
|
||
}
|
||
_maybeEnableSmoothScroll() {
|
||
if (!this._config.smoothScroll) {
|
||
return;
|
||
}
|
||
|
||
// unregister any previous listeners
|
||
EventHandler.off(this._config.target, EVENT_CLICK);
|
||
EventHandler.on(this._config.target, EVENT_CLICK, SELECTOR_TARGET_LINKS, event => {
|
||
const observableSection = this._observableSections.get(event.target.hash);
|
||
if (observableSection) {
|
||
event.preventDefault();
|
||
const root = this._rootElement || window;
|
||
const height = observableSection.offsetTop - this._element.offsetTop;
|
||
if (root.scrollTo) {
|
||
root.scrollTo({
|
||
top: height,
|
||
behavior: 'smooth'
|
||
});
|
||
return;
|
||
}
|
||
|
||
// Chrome 60 doesn't support `scrollTo`
|
||
root.scrollTop = height;
|
||
}
|
||
});
|
||
}
|
||
_getNewObserver() {
|
||
const options = {
|
||
root: this._rootElement,
|
||
threshold: this._config.threshold,
|
||
rootMargin: this._config.rootMargin
|
||
};
|
||
return new IntersectionObserver(entries => this._observerCallback(entries), options);
|
||
}
|
||
|
||
// The logic of selection
|
||
_observerCallback(entries) {
|
||
const targetElement = entry => this._targetLinks.get(`#${entry.target.id}`);
|
||
const activate = entry => {
|
||
this._previousScrollData.visibleEntryTop = entry.target.offsetTop;
|
||
this._process(targetElement(entry));
|
||
};
|
||
const parentScrollTop = (this._rootElement || document.documentElement).scrollTop;
|
||
const userScrollsDown = parentScrollTop >= this._previousScrollData.parentScrollTop;
|
||
this._previousScrollData.parentScrollTop = parentScrollTop;
|
||
for (const entry of entries) {
|
||
if (!entry.isIntersecting) {
|
||
this._activeTarget = null;
|
||
this._clearActiveClass(targetElement(entry));
|
||
continue;
|
||
}
|
||
const entryIsLowerThanPrevious = entry.target.offsetTop >= this._previousScrollData.visibleEntryTop;
|
||
// if we are scrolling down, pick the bigger offsetTop
|
||
if (userScrollsDown && entryIsLowerThanPrevious) {
|
||
activate(entry);
|
||
// if parent isn't scrolled, let's keep the first visible item, breaking the iteration
|
||
if (!parentScrollTop) {
|
||
return;
|
||
}
|
||
continue;
|
||
}
|
||
|
||
// if we are scrolling up, pick the smallest offsetTop
|
||
if (!userScrollsDown && !entryIsLowerThanPrevious) {
|
||
activate(entry);
|
||
}
|
||
}
|
||
}
|
||
_initializeTargetsAndObservables() {
|
||
this._targetLinks = new Map();
|
||
this._observableSections = new Map();
|
||
const targetLinks = SelectorEngine.find(SELECTOR_TARGET_LINKS, this._config.target);
|
||
for (const anchor of targetLinks) {
|
||
// ensure that the anchor has an id and is not disabled
|
||
if (!anchor.hash || isDisabled(anchor)) {
|
||
continue;
|
||
}
|
||
const observableSection = SelectorEngine.findOne(decodeURI(anchor.hash), this._element);
|
||
|
||
// ensure that the observableSection exists & is visible
|
||
if (isVisible(observableSection)) {
|
||
this._targetLinks.set(decodeURI(anchor.hash), anchor);
|
||
this._observableSections.set(anchor.hash, observableSection);
|
||
}
|
||
}
|
||
}
|
||
_process(target) {
|
||
if (this._activeTarget === target) {
|
||
return;
|
||
}
|
||
this._clearActiveClass(this._config.target);
|
||
this._activeTarget = target;
|
||
target.classList.add(CLASS_NAME_ACTIVE$1);
|
||
this._activateParents(target);
|
||
EventHandler.trigger(this._element, EVENT_ACTIVATE, {
|
||
relatedTarget: target
|
||
});
|
||
}
|
||
_activateParents(target) {
|
||
// Activate dropdown parents
|
||
if (target.classList.contains(CLASS_NAME_DROPDOWN_ITEM)) {
|
||
SelectorEngine.findOne(SELECTOR_DROPDOWN_TOGGLE$1, target.closest(SELECTOR_DROPDOWN)).classList.add(CLASS_NAME_ACTIVE$1);
|
||
return;
|
||
}
|
||
for (const listGroup of SelectorEngine.parents(target, SELECTOR_NAV_LIST_GROUP)) {
|
||
// Set triggered links parents as active
|
||
// With both <ul> and <nav> markup a parent is the previous sibling of any nav ancestor
|
||
for (const item of SelectorEngine.prev(listGroup, SELECTOR_LINK_ITEMS)) {
|
||
item.classList.add(CLASS_NAME_ACTIVE$1);
|
||
}
|
||
}
|
||
}
|
||
_clearActiveClass(parent) {
|
||
parent.classList.remove(CLASS_NAME_ACTIVE$1);
|
||
const activeNodes = SelectorEngine.find(`${SELECTOR_TARGET_LINKS}.${CLASS_NAME_ACTIVE$1}`, parent);
|
||
for (const node of activeNodes) {
|
||
node.classList.remove(CLASS_NAME_ACTIVE$1);
|
||
}
|
||
}
|
||
|
||
// Static
|
||
static jQueryInterface(config) {
|
||
return this.each(function () {
|
||
const data = ScrollSpy.getOrCreateInstance(this, config);
|
||
if (typeof config !== 'string') {
|
||
return;
|
||
}
|
||
if (data[config] === undefined || config.startsWith('_') || config === 'constructor') {
|
||
throw new TypeError(`No method named "${config}"`);
|
||
}
|
||
data[config]();
|
||
});
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Data API implementation
|
||
*/
|
||
|
||
EventHandler.on(window, EVENT_LOAD_DATA_API$1, () => {
|
||
for (const spy of SelectorEngine.find(SELECTOR_DATA_SPY)) {
|
||
ScrollSpy.getOrCreateInstance(spy);
|
||
}
|
||
});
|
||
|
||
/**
|
||
* jQuery
|
||
*/
|
||
|
||
defineJQueryPlugin(ScrollSpy);
|
||
|
||
/**
|
||
* --------------------------------------------------------------------------
|
||
* Bootstrap tab.js
|
||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||
* --------------------------------------------------------------------------
|
||
*/
|
||
|
||
/**
|
||
* Constants
|
||
*/
|
||
|
||
const NAME$1 = 'tab';
|
||
const DATA_KEY$1 = 'bs.tab';
|
||
const EVENT_KEY$1 = `.${DATA_KEY$1}`;
|
||
const EVENT_HIDE$1 = `hide${EVENT_KEY$1}`;
|
||
const EVENT_HIDDEN$1 = `hidden${EVENT_KEY$1}`;
|
||
const EVENT_SHOW$1 = `show${EVENT_KEY$1}`;
|
||
const EVENT_SHOWN$1 = `shown${EVENT_KEY$1}`;
|
||
const EVENT_CLICK_DATA_API = `click${EVENT_KEY$1}`;
|
||
const EVENT_KEYDOWN = `keydown${EVENT_KEY$1}`;
|
||
const EVENT_LOAD_DATA_API = `load${EVENT_KEY$1}`;
|
||
const ARROW_LEFT_KEY = 'ArrowLeft';
|
||
const ARROW_RIGHT_KEY = 'ArrowRight';
|
||
const ARROW_UP_KEY = 'ArrowUp';
|
||
const ARROW_DOWN_KEY = 'ArrowDown';
|
||
const HOME_KEY = 'Home';
|
||
const END_KEY = 'End';
|
||
const CLASS_NAME_ACTIVE = 'active';
|
||
const CLASS_NAME_FADE$1 = 'fade';
|
||
const CLASS_NAME_SHOW$1 = 'show';
|
||
const CLASS_DROPDOWN = 'dropdown';
|
||
const SELECTOR_DROPDOWN_TOGGLE = '.dropdown-toggle';
|
||
const SELECTOR_DROPDOWN_MENU = '.dropdown-menu';
|
||
const NOT_SELECTOR_DROPDOWN_TOGGLE = `:not(${SELECTOR_DROPDOWN_TOGGLE})`;
|
||
const SELECTOR_TAB_PANEL = '.list-group, .nav, [role="tablist"]';
|
||
const SELECTOR_OUTER = '.nav-item, .list-group-item';
|
||
const SELECTOR_INNER = `.nav-link${NOT_SELECTOR_DROPDOWN_TOGGLE}, .list-group-item${NOT_SELECTOR_DROPDOWN_TOGGLE}, [role="tab"]${NOT_SELECTOR_DROPDOWN_TOGGLE}`;
|
||
const SELECTOR_DATA_TOGGLE = '[data-bs-toggle="tab"], [data-bs-toggle="pill"], [data-bs-toggle="list"]'; // TODO: could only be `tab` in v6
|
||
const SELECTOR_INNER_ELEM = `${SELECTOR_INNER}, ${SELECTOR_DATA_TOGGLE}`;
|
||
const SELECTOR_DATA_TOGGLE_ACTIVE = `.${CLASS_NAME_ACTIVE}[data-bs-toggle="tab"], .${CLASS_NAME_ACTIVE}[data-bs-toggle="pill"], .${CLASS_NAME_ACTIVE}[data-bs-toggle="list"]`;
|
||
|
||
/**
|
||
* Class definition
|
||
*/
|
||
|
||
class Tab extends BaseComponent {
|
||
constructor(element) {
|
||
super(element);
|
||
this._parent = this._element.closest(SELECTOR_TAB_PANEL);
|
||
if (!this._parent) {
|
||
return;
|
||
// TODO: should throw exception in v6
|
||
// throw new TypeError(`${element.outerHTML} has not a valid parent ${SELECTOR_INNER_ELEM}`)
|
||
}
|
||
|
||
// Set up initial aria attributes
|
||
this._setInitialAttributes(this._parent, this._getChildren());
|
||
EventHandler.on(this._element, EVENT_KEYDOWN, event => this._keydown(event));
|
||
}
|
||
|
||
// Getters
|
||
static get NAME() {
|
||
return NAME$1;
|
||
}
|
||
|
||
// Public
|
||
show() {
|
||
// Shows this elem and deactivate the active sibling if exists
|
||
const innerElem = this._element;
|
||
if (this._elemIsActive(innerElem)) {
|
||
return;
|
||
}
|
||
|
||
// Search for active tab on same parent to deactivate it
|
||
const active = this._getActiveElem();
|
||
const hideEvent = active ? EventHandler.trigger(active, EVENT_HIDE$1, {
|
||
relatedTarget: innerElem
|
||
}) : null;
|
||
const showEvent = EventHandler.trigger(innerElem, EVENT_SHOW$1, {
|
||
relatedTarget: active
|
||
});
|
||
if (showEvent.defaultPrevented || hideEvent && hideEvent.defaultPrevented) {
|
||
return;
|
||
}
|
||
this._deactivate(active, innerElem);
|
||
this._activate(innerElem, active);
|
||
}
|
||
|
||
// Private
|
||
_activate(element, relatedElem) {
|
||
if (!element) {
|
||
return;
|
||
}
|
||
element.classList.add(CLASS_NAME_ACTIVE);
|
||
this._activate(SelectorEngine.getElementFromSelector(element)); // Search and activate/show the proper section
|
||
|
||
const complete = () => {
|
||
if (element.getAttribute('role') !== 'tab') {
|
||
element.classList.add(CLASS_NAME_SHOW$1);
|
||
return;
|
||
}
|
||
element.removeAttribute('tabindex');
|
||
element.setAttribute('aria-selected', true);
|
||
this._toggleDropDown(element, true);
|
||
EventHandler.trigger(element, EVENT_SHOWN$1, {
|
||
relatedTarget: relatedElem
|
||
});
|
||
};
|
||
this._queueCallback(complete, element, element.classList.contains(CLASS_NAME_FADE$1));
|
||
}
|
||
_deactivate(element, relatedElem) {
|
||
if (!element) {
|
||
return;
|
||
}
|
||
element.classList.remove(CLASS_NAME_ACTIVE);
|
||
element.blur();
|
||
this._deactivate(SelectorEngine.getElementFromSelector(element)); // Search and deactivate the shown section too
|
||
|
||
const complete = () => {
|
||
if (element.getAttribute('role') !== 'tab') {
|
||
element.classList.remove(CLASS_NAME_SHOW$1);
|
||
return;
|
||
}
|
||
element.setAttribute('aria-selected', false);
|
||
element.setAttribute('tabindex', '-1');
|
||
this._toggleDropDown(element, false);
|
||
EventHandler.trigger(element, EVENT_HIDDEN$1, {
|
||
relatedTarget: relatedElem
|
||
});
|
||
};
|
||
this._queueCallback(complete, element, element.classList.contains(CLASS_NAME_FADE$1));
|
||
}
|
||
_keydown(event) {
|
||
if (![ARROW_LEFT_KEY, ARROW_RIGHT_KEY, ARROW_UP_KEY, ARROW_DOWN_KEY, HOME_KEY, END_KEY].includes(event.key)) {
|
||
return;
|
||
}
|
||
event.stopPropagation(); // stopPropagation/preventDefault both added to support up/down keys without scrolling the page
|
||
event.preventDefault();
|
||
const children = this._getChildren().filter(element => !isDisabled(element));
|
||
let nextActiveElement;
|
||
if ([HOME_KEY, END_KEY].includes(event.key)) {
|
||
nextActiveElement = children[event.key === HOME_KEY ? 0 : children.length - 1];
|
||
} else {
|
||
const isNext = [ARROW_RIGHT_KEY, ARROW_DOWN_KEY].includes(event.key);
|
||
nextActiveElement = getNextActiveElement(children, event.target, isNext, true);
|
||
}
|
||
if (nextActiveElement) {
|
||
nextActiveElement.focus({
|
||
preventScroll: true
|
||
});
|
||
Tab.getOrCreateInstance(nextActiveElement).show();
|
||
}
|
||
}
|
||
_getChildren() {
|
||
// collection of inner elements
|
||
return SelectorEngine.find(SELECTOR_INNER_ELEM, this._parent);
|
||
}
|
||
_getActiveElem() {
|
||
return this._getChildren().find(child => this._elemIsActive(child)) || null;
|
||
}
|
||
_setInitialAttributes(parent, children) {
|
||
this._setAttributeIfNotExists(parent, 'role', 'tablist');
|
||
for (const child of children) {
|
||
this._setInitialAttributesOnChild(child);
|
||
}
|
||
}
|
||
_setInitialAttributesOnChild(child) {
|
||
child = this._getInnerElement(child);
|
||
const isActive = this._elemIsActive(child);
|
||
const outerElem = this._getOuterElement(child);
|
||
child.setAttribute('aria-selected', isActive);
|
||
if (outerElem !== child) {
|
||
this._setAttributeIfNotExists(outerElem, 'role', 'presentation');
|
||
}
|
||
if (!isActive) {
|
||
child.setAttribute('tabindex', '-1');
|
||
}
|
||
this._setAttributeIfNotExists(child, 'role', 'tab');
|
||
|
||
// set attributes to the related panel too
|
||
this._setInitialAttributesOnTargetPanel(child);
|
||
}
|
||
_setInitialAttributesOnTargetPanel(child) {
|
||
const target = SelectorEngine.getElementFromSelector(child);
|
||
if (!target) {
|
||
return;
|
||
}
|
||
this._setAttributeIfNotExists(target, 'role', 'tabpanel');
|
||
if (child.id) {
|
||
this._setAttributeIfNotExists(target, 'aria-labelledby', `${child.id}`);
|
||
}
|
||
}
|
||
_toggleDropDown(element, open) {
|
||
const outerElem = this._getOuterElement(element);
|
||
if (!outerElem.classList.contains(CLASS_DROPDOWN)) {
|
||
return;
|
||
}
|
||
const toggle = (selector, className) => {
|
||
const element = SelectorEngine.findOne(selector, outerElem);
|
||
if (element) {
|
||
element.classList.toggle(className, open);
|
||
}
|
||
};
|
||
toggle(SELECTOR_DROPDOWN_TOGGLE, CLASS_NAME_ACTIVE);
|
||
toggle(SELECTOR_DROPDOWN_MENU, CLASS_NAME_SHOW$1);
|
||
outerElem.setAttribute('aria-expanded', open);
|
||
}
|
||
_setAttributeIfNotExists(element, attribute, value) {
|
||
if (!element.hasAttribute(attribute)) {
|
||
element.setAttribute(attribute, value);
|
||
}
|
||
}
|
||
_elemIsActive(elem) {
|
||
return elem.classList.contains(CLASS_NAME_ACTIVE);
|
||
}
|
||
|
||
// Try to get the inner element (usually the .nav-link)
|
||
_getInnerElement(elem) {
|
||
return elem.matches(SELECTOR_INNER_ELEM) ? elem : SelectorEngine.findOne(SELECTOR_INNER_ELEM, elem);
|
||
}
|
||
|
||
// Try to get the outer element (usually the .nav-item)
|
||
_getOuterElement(elem) {
|
||
return elem.closest(SELECTOR_OUTER) || elem;
|
||
}
|
||
|
||
// Static
|
||
static jQueryInterface(config) {
|
||
return this.each(function () {
|
||
const data = Tab.getOrCreateInstance(this);
|
||
if (typeof config !== 'string') {
|
||
return;
|
||
}
|
||
if (data[config] === undefined || config.startsWith('_') || config === 'constructor') {
|
||
throw new TypeError(`No method named "${config}"`);
|
||
}
|
||
data[config]();
|
||
});
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Data API implementation
|
||
*/
|
||
|
||
EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {
|
||
if (['A', 'AREA'].includes(this.tagName)) {
|
||
event.preventDefault();
|
||
}
|
||
if (isDisabled(this)) {
|
||
return;
|
||
}
|
||
Tab.getOrCreateInstance(this).show();
|
||
});
|
||
|
||
/**
|
||
* Initialize on focus
|
||
*/
|
||
EventHandler.on(window, EVENT_LOAD_DATA_API, () => {
|
||
for (const element of SelectorEngine.find(SELECTOR_DATA_TOGGLE_ACTIVE)) {
|
||
Tab.getOrCreateInstance(element);
|
||
}
|
||
});
|
||
/**
|
||
* jQuery
|
||
*/
|
||
|
||
defineJQueryPlugin(Tab);
|
||
|
||
/**
|
||
* --------------------------------------------------------------------------
|
||
* Bootstrap toast.js
|
||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||
* --------------------------------------------------------------------------
|
||
*/
|
||
|
||
/**
|
||
* Constants
|
||
*/
|
||
|
||
const NAME = 'toast';
|
||
const DATA_KEY = 'bs.toast';
|
||
const EVENT_KEY = `.${DATA_KEY}`;
|
||
const EVENT_MOUSEOVER = `mouseover${EVENT_KEY}`;
|
||
const EVENT_MOUSEOUT = `mouseout${EVENT_KEY}`;
|
||
const EVENT_FOCUSIN = `focusin${EVENT_KEY}`;
|
||
const EVENT_FOCUSOUT = `focusout${EVENT_KEY}`;
|
||
const EVENT_HIDE = `hide${EVENT_KEY}`;
|
||
const EVENT_HIDDEN = `hidden${EVENT_KEY}`;
|
||
const EVENT_SHOW = `show${EVENT_KEY}`;
|
||
const EVENT_SHOWN = `shown${EVENT_KEY}`;
|
||
const CLASS_NAME_FADE = 'fade';
|
||
const CLASS_NAME_HIDE = 'hide'; // @deprecated - kept here only for backwards compatibility
|
||
const CLASS_NAME_SHOW = 'show';
|
||
const CLASS_NAME_SHOWING = 'showing';
|
||
const DefaultType = {
|
||
animation: 'boolean',
|
||
autohide: 'boolean',
|
||
delay: 'number'
|
||
};
|
||
const Default = {
|
||
animation: true,
|
||
autohide: true,
|
||
delay: 5000
|
||
};
|
||
|
||
/**
|
||
* Class definition
|
||
*/
|
||
|
||
class Toast extends BaseComponent {
|
||
constructor(element, config) {
|
||
super(element, config);
|
||
this._timeout = null;
|
||
this._hasMouseInteraction = false;
|
||
this._hasKeyboardInteraction = false;
|
||
this._setListeners();
|
||
}
|
||
|
||
// Getters
|
||
static get Default() {
|
||
return Default;
|
||
}
|
||
static get DefaultType() {
|
||
return DefaultType;
|
||
}
|
||
static get NAME() {
|
||
return NAME;
|
||
}
|
||
|
||
// Public
|
||
show() {
|
||
const showEvent = EventHandler.trigger(this._element, EVENT_SHOW);
|
||
if (showEvent.defaultPrevented) {
|
||
return;
|
||
}
|
||
this._clearTimeout();
|
||
if (this._config.animation) {
|
||
this._element.classList.add(CLASS_NAME_FADE);
|
||
}
|
||
const complete = () => {
|
||
this._element.classList.remove(CLASS_NAME_SHOWING);
|
||
EventHandler.trigger(this._element, EVENT_SHOWN);
|
||
this._maybeScheduleHide();
|
||
};
|
||
this._element.classList.remove(CLASS_NAME_HIDE); // @deprecated
|
||
reflow(this._element);
|
||
this._element.classList.add(CLASS_NAME_SHOW, CLASS_NAME_SHOWING);
|
||
this._queueCallback(complete, this._element, this._config.animation);
|
||
}
|
||
hide() {
|
||
if (!this.isShown()) {
|
||
return;
|
||
}
|
||
const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE);
|
||
if (hideEvent.defaultPrevented) {
|
||
return;
|
||
}
|
||
const complete = () => {
|
||
this._element.classList.add(CLASS_NAME_HIDE); // @deprecated
|
||
this._element.classList.remove(CLASS_NAME_SHOWING, CLASS_NAME_SHOW);
|
||
EventHandler.trigger(this._element, EVENT_HIDDEN);
|
||
};
|
||
this._element.classList.add(CLASS_NAME_SHOWING);
|
||
this._queueCallback(complete, this._element, this._config.animation);
|
||
}
|
||
dispose() {
|
||
this._clearTimeout();
|
||
if (this.isShown()) {
|
||
this._element.classList.remove(CLASS_NAME_SHOW);
|
||
}
|
||
super.dispose();
|
||
}
|
||
isShown() {
|
||
return this._element.classList.contains(CLASS_NAME_SHOW);
|
||
}
|
||
|
||
// Private
|
||
|
||
_maybeScheduleHide() {
|
||
if (!this._config.autohide) {
|
||
return;
|
||
}
|
||
if (this._hasMouseInteraction || this._hasKeyboardInteraction) {
|
||
return;
|
||
}
|
||
this._timeout = setTimeout(() => {
|
||
this.hide();
|
||
}, this._config.delay);
|
||
}
|
||
_onInteraction(event, isInteracting) {
|
||
switch (event.type) {
|
||
case 'mouseover':
|
||
case 'mouseout':
|
||
{
|
||
this._hasMouseInteraction = isInteracting;
|
||
break;
|
||
}
|
||
case 'focusin':
|
||
case 'focusout':
|
||
{
|
||
this._hasKeyboardInteraction = isInteracting;
|
||
break;
|
||
}
|
||
}
|
||
if (isInteracting) {
|
||
this._clearTimeout();
|
||
return;
|
||
}
|
||
const nextElement = event.relatedTarget;
|
||
if (this._element === nextElement || this._element.contains(nextElement)) {
|
||
return;
|
||
}
|
||
this._maybeScheduleHide();
|
||
}
|
||
_setListeners() {
|
||
EventHandler.on(this._element, EVENT_MOUSEOVER, event => this._onInteraction(event, true));
|
||
EventHandler.on(this._element, EVENT_MOUSEOUT, event => this._onInteraction(event, false));
|
||
EventHandler.on(this._element, EVENT_FOCUSIN, event => this._onInteraction(event, true));
|
||
EventHandler.on(this._element, EVENT_FOCUSOUT, event => this._onInteraction(event, false));
|
||
}
|
||
_clearTimeout() {
|
||
clearTimeout(this._timeout);
|
||
this._timeout = null;
|
||
}
|
||
|
||
// Static
|
||
static jQueryInterface(config) {
|
||
return this.each(function () {
|
||
const data = Toast.getOrCreateInstance(this, config);
|
||
if (typeof config === 'string') {
|
||
if (typeof data[config] === 'undefined') {
|
||
throw new TypeError(`No method named "${config}"`);
|
||
}
|
||
data[config](this);
|
||
}
|
||
});
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Data API implementation
|
||
*/
|
||
|
||
enableDismissTrigger(Toast);
|
||
|
||
/**
|
||
* jQuery
|
||
*/
|
||
|
||
defineJQueryPlugin(Toast);
|
||
|
||
/**
|
||
* --------------------------------------------------------------------------
|
||
* Bootstrap index.umd.js
|
||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||
* --------------------------------------------------------------------------
|
||
*/
|
||
|
||
const index_umd = {
|
||
Alert,
|
||
Button,
|
||
Carousel,
|
||
Collapse,
|
||
Dropdown,
|
||
Modal,
|
||
Offcanvas,
|
||
Popover,
|
||
ScrollSpy,
|
||
Tab,
|
||
Toast,
|
||
Tooltip
|
||
};
|
||
return index_umd;
|
||
});
|
||
|
||
|
||
|
||
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInN0b3JhZ2UvcnN4LXRtcC9idW5kbGVfY29uZmlnX0Rldl9CdW5kbGUuanMiLCJzdG9yYWdlL3JzeC1idWlsZC9idW5kbGVzL25wbV9EZXZfQnVuZGxlXzY0NTllOGVkMGY2MGJkYTRmMTIxNDIwNzY2MDEyZDUzLmpzIiwiLi4vLi4vanMvc3JjL2RvbS9kYXRhLmpzIiwiLi4vLi4vanMvc3JjL3V0aWwvaW5kZXguanMiLCIuLi8uLi9qcy9zcmMvZG9tL2V2ZW50LWhhbmRsZXIuanMiLCIuLi8uLi9qcy9zcmMvZG9tL21hbmlwdWxhdG9yLmpzIiwiLi4vLi4vanMvc3JjL3V0aWwvY29uZmlnLmpzIiwiLi4vLi4vanMvc3JjL2Jhc2UtY29tcG9uZW50LmpzIiwiLi4vLi4vanMvc3JjL2RvbS9zZWxlY3Rvci1lbmdpbmUuanMiLCIuLi8uLi9qcy9zcmMvdXRpbC9jb21wb25lbnQtZnVuY3Rpb25zLmpzIiwiLi4vLi4vanMvc3JjL2FsZXJ0LmpzIiwiLi4vLi4vanMvc3JjL2J1dHRvbi5qcyIsIi4uLy4uL2pzL3NyYy91dGlsL3N3aXBlLmpzIiwiLi4vLi4vanMvc3JjL2Nhcm91c2VsLmpzIiwiLi4vLi4vanMvc3JjL2NvbGxhcHNlLmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL0Bwb3BwZXJqcy9jb3JlL2xpYi9lbnVtcy5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvZG9tLXV0aWxzL2dldE5vZGVOYW1lLmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL0Bwb3BwZXJqcy9jb3JlL2xpYi9kb20tdXRpbHMvZ2V0V2luZG93LmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL0Bwb3BwZXJqcy9jb3JlL2xpYi9kb20tdXRpbHMvaW5zdGFuY2VPZi5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvbW9kaWZpZXJzL2FwcGx5U3R5bGVzLmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL0Bwb3BwZXJqcy9jb3JlL2xpYi91dGlscy9nZXRCYXNlUGxhY2VtZW50LmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL0Bwb3BwZXJqcy9jb3JlL2xpYi91dGlscy9tYXRoLmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL0Bwb3BwZXJqcy9jb3JlL2xpYi91dGlscy91c2VyQWdlbnQuanMiLCIuLi8uLi9ub2RlX21vZHVsZXMvQHBvcHBlcmpzL2NvcmUvbGliL2RvbS11dGlscy9pc0xheW91dFZpZXdwb3J0LmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL0Bwb3BwZXJqcy9jb3JlL2xpYi9kb20tdXRpbHMvZ2V0Qm91bmRpbmdDbGllbnRSZWN0LmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL0Bwb3BwZXJqcy9jb3JlL2xpYi9kb20tdXRpbHMvZ2V0TGF5b3V0UmVjdC5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvZG9tLXV0aWxzL2NvbnRhaW5zLmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL0Bwb3BwZXJqcy9jb3JlL2xpYi9kb20tdXRpbHMvZ2V0Q29tcHV0ZWRTdHlsZS5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvZG9tLXV0aWxzL2lzVGFibGVFbGVtZW50LmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL0Bwb3BwZXJqcy9jb3JlL2xpYi9kb20tdXRpbHMvZ2V0RG9jdW1lbnRFbGVtZW50LmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL0Bwb3BwZXJqcy9jb3JlL2xpYi9kb20tdXRpbHMvZ2V0UGFyZW50Tm9kZS5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvZG9tLXV0aWxzL2dldE9mZnNldFBhcmVudC5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvdXRpbHMvZ2V0TWFpbkF4aXNGcm9tUGxhY2VtZW50LmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL0Bwb3BwZXJqcy9jb3JlL2xpYi91dGlscy93aXRoaW4uanMiLCIuLi8uLi9ub2RlX21vZHVsZXMvQHBvcHBlcmpzL2NvcmUvbGliL3V0aWxzL2dldEZyZXNoU2lkZU9iamVjdC5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvdXRpbHMvbWVyZ2VQYWRkaW5nT2JqZWN0LmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL0Bwb3BwZXJqcy9jb3JlL2xpYi91dGlscy9leHBhbmRUb0hhc2hNYXAuanMiLCIuLi8uLi9ub2RlX21vZHVsZXMvQHBvcHBlcmpzL2NvcmUvbGliL21vZGlmaWVycy9hcnJvdy5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvdXRpbHMvZ2V0VmFyaWF0aW9uLmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL0Bwb3BwZXJqcy9jb3JlL2xpYi9tb2RpZmllcnMvY29tcHV0ZVN0eWxlcy5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvbW9kaWZpZXJzL2V2ZW50TGlzdGVuZXJzLmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL0Bwb3BwZXJqcy9jb3JlL2xpYi91dGlscy9nZXRPcHBvc2l0ZVBsYWNlbWVudC5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvdXRpbHMvZ2V0T3Bwb3NpdGVWYXJpYXRpb25QbGFjZW1lbnQuanMiLCIuLi8uLi9ub2RlX21vZHVsZXMvQHBvcHBlcmpzL2NvcmUvbGliL2RvbS11dGlscy9nZXRXaW5kb3dTY3JvbGwuanMiLCIuLi8uLi9ub2RlX21vZHVsZXMvQHBvcHBlcmpzL2NvcmUvbGliL2RvbS11dGlscy9nZXRXaW5kb3dTY3JvbGxCYXJYLmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL0Bwb3BwZXJqcy9jb3JlL2xpYi9kb20tdXRpbHMvZ2V0Vmlld3BvcnRSZWN0LmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL0Bwb3BwZXJqcy9jb3JlL2xpYi9kb20tdXRpbHMvZ2V0RG9jdW1lbnRSZWN0LmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL0Bwb3BwZXJqcy9jb3JlL2xpYi9kb20tdXRpbHMvaXNTY3JvbGxQYXJlbnQuanMiLCIuLi8uLi9ub2RlX21vZHVsZXMvQHBvcHBlcmpzL2NvcmUvbGliL2RvbS11dGlscy9nZXRTY3JvbGxQYXJlbnQuanMiLCIuLi8uLi9ub2RlX21vZHVsZXMvQHBvcHBlcmpzL2NvcmUvbGliL2RvbS11dGlscy9saXN0U2Nyb2xsUGFyZW50cy5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvdXRpbHMvcmVjdFRvQ2xpZW50UmVjdC5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvZG9tLXV0aWxzL2dldENsaXBwaW5nUmVjdC5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvdXRpbHMvY29tcHV0ZU9mZnNldHMuanMiLCIuLi8uLi9ub2RlX21vZHVsZXMvQHBvcHBlcmpzL2NvcmUvbGliL3V0aWxzL2RldGVjdE92ZXJmbG93LmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL0Bwb3BwZXJqcy9jb3JlL2xpYi91dGlscy9jb21wdXRlQXV0b1BsYWNlbWVudC5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvbW9kaWZpZXJzL2ZsaXAuanMiLCIuLi8uLi9ub2RlX21vZHVsZXMvQHBvcHBlcmpzL2NvcmUvbGliL21vZGlmaWVycy9oaWRlLmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL0Bwb3BwZXJqcy9jb3JlL2xpYi9tb2RpZmllcnMvb2Zmc2V0LmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL0Bwb3BwZXJqcy9jb3JlL2xpYi9tb2RpZmllcnMvcG9wcGVyT2Zmc2V0cy5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvdXRpbHMvZ2V0QWx0QXhpcy5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvbW9kaWZpZXJzL3ByZXZlbnRPdmVyZmxvdy5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvZG9tLXV0aWxzL2dldEhUTUxFbGVtZW50U2Nyb2xsLmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL0Bwb3BwZXJqcy9jb3JlL2xpYi9kb20tdXRpbHMvZ2V0Tm9kZVNjcm9sbC5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvZG9tLXV0aWxzL2dldENvbXBvc2l0ZVJlY3QuanMiLCIuLi8uLi9ub2RlX21vZHVsZXMvQHBvcHBlcmpzL2NvcmUvbGliL3V0aWxzL29yZGVyTW9kaWZpZXJzLmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL0Bwb3BwZXJqcy9jb3JlL2xpYi91dGlscy9kZWJvdW5jZS5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvdXRpbHMvbWVyZ2VCeU5hbWUuanMiLCIuLi8uLi9ub2RlX21vZHVsZXMvQHBvcHBlcmpzL2NvcmUvbGliL2NyZWF0ZVBvcHBlci5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvcG9wcGVyLWxpdGUuanMiLCIuLi8uLi9ub2RlX21vZHVsZXMvQHBvcHBlcmpzL2NvcmUvbGliL3BvcHBlci5qcyIsIi4uLy4uL2pzL3NyYy9kcm9wZG93bi5qcyIsIi4uLy4uL2pzL3NyYy91dGlsL2JhY2tkcm9wLmpzIiwiLi4vLi4vanMvc3JjL3V0aWwvZm9jdXN0cmFwLmpzIiwiLi4vLi4vanMvc3JjL3V0aWwvc2Nyb2xsYmFyLmpzIiwiLi4vLi4vanMvc3JjL21vZGFsLmpzIiwiLi4vLi4vanMvc3JjL29mZmNhbnZhcy5qcyIsIi4uLy4uL2pzL3NyYy91dGlsL3Nhbml0aXplci5qcyIsIi4uLy4uL2pzL3NyYy91dGlsL3RlbXBsYXRlLWZhY3RvcnkuanMiLCIuLi8uLi9qcy9zcmMvdG9vbHRpcC5qcyIsIi4uLy4uL2pzL3NyYy9wb3BvdmVyLmpzIiwiLi4vLi4vanMvc3JjL3Njcm9sbHNweS5qcyIsIi4uLy4uL2pzL3NyYy90YWIuanMiLCIuLi8uLi9qcy9zcmMvdG9hc3QuanMiLCIuLi8uLi9qcy9pbmRleC51bWQuanMiXSwibmFtZXMiOlsiZWxlbWVudE1hcCIsIk1hcCIsIkRhdGEiLCJzZXQiLCJlbGVtZW50Iiwia2V5IiwiaW5zdGFuY2UiLCJoYXMiLCJpbnN0YW5jZU1hcCIsImdldCIsInNpemUiLCJjb25zb2xlIiwiZXJyb3IiLCJBcnJheSIsImZyb20iLCJrZXlzIiwicmVtb3ZlIiwiZGVsZXRlIiwiTUFYX1VJRCIsIk1JTExJU0VDT05EU19NVUxUSVBMSUVSIiwiVFJBTlNJVElPTl9FTkQiLCJwYXJzZVNlbGVjdG9yIiwic2VsZWN0b3IiLCJ3aW5kb3ciLCJDU1MiLCJlc2NhcGUiLCJyZXBsYWNlIiwibWF0Y2giLCJpZCIsInRvVHlwZSIsIm9iamVjdCIsInVuZGVmaW5lZCIsIk9iamVjdCIsInByb3RvdHlwZSIsInRvU3RyaW5nIiwiY2FsbCIsInRvTG93ZXJDYXNlIiwiZ2V0VUlEIiwicHJlZml4IiwiTWF0aCIsImZsb29yIiwicmFuZG9tIiwiZG9jdW1lbnQiLCJnZXRFbGVtZW50QnlJZCIsImdldFRyYW5zaXRpb25EdXJhdGlvbkZyb21FbGVtZW50IiwidHJhbnNpdGlvbkR1cmF0aW9uIiwidHJhbnNpdGlvbkRlbGF5IiwiZ2V0Q29tcHV0ZWRTdHlsZSIsImZsb2F0VHJhbnNpdGlvbkR1cmF0aW9uIiwiTnVtYmVyIiwicGFyc2VGbG9hdCIsImZsb2F0VHJhbnNpdGlvbkRlbGF5Iiwic3BsaXQiLCJ0cmlnZ2VyVHJhbnNpdGlvbkVuZCIsImRpc3BhdGNoRXZlbnQiLCJFdmVudCIsImlzRWxlbWVudCQxIiwianF1ZXJ5Iiwibm9kZVR5cGUiLCJnZXRFbGVtZW50IiwibGVuZ3RoIiwicXVlcnlTZWxlY3RvciIsImlzVmlzaWJsZSIsImdldENsaWVudFJlY3RzIiwiZWxlbWVudElzVmlzaWJsZSIsImdldFByb3BlcnR5VmFsdWUiLCJjbG9zZWREZXRhaWxzIiwiY2xvc2VzdCIsInN1bW1hcnkiLCJwYXJlbnROb2RlIiwiaXNEaXNhYmxlZCIsIk5vZGUiLCJFTEVNRU5UX05PREUiLCJjbGFzc0xpc3QiLCJjb250YWlucyIsImRpc2FibGVkIiwiaGFzQXR0cmlidXRlIiwiZ2V0QXR0cmlidXRlIiwiZmluZFNoYWRvd1Jvb3QiLCJkb2N1bWVudEVsZW1lbnQiLCJhdHRhY2hTaGFkb3ciLCJnZXRSb290Tm9kZSIsInJvb3QiLCJTaGFkb3dSb290Iiwibm9vcCIsInJlZmxvdyIsIm9mZnNldEhlaWdodCIsImdldGpRdWVyeSIsImpRdWVyeSIsImJvZHkiLCJET01Db250ZW50TG9hZGVkQ2FsbGJhY2tzIiwib25ET01Db250ZW50TG9hZGVkIiwiY2FsbGJhY2siLCJyZWFkeVN0YXRlIiwiYWRkRXZlbnRMaXN0ZW5lciIsInB1c2giLCJpc1JUTCIsImRpciIsImRlZmluZUpRdWVyeVBsdWdpbiIsInBsdWdpbiIsIiQiLCJuYW1lIiwiTkFNRSIsIkpRVUVSWV9OT19DT05GTElDVCIsImZuIiwialF1ZXJ5SW50ZXJmYWNlIiwiQ29uc3RydWN0b3IiLCJub0NvbmZsaWN0IiwiZXhlY3V0ZSIsInBvc3NpYmxlQ2FsbGJhY2siLCJhcmdzIiwiYXJndW1lbnRzIiwiZGVmYXVsdFZhbHVlIiwiZXhlY3V0ZUFmdGVyVHJhbnNpdGlvbiIsInRyYW5zaXRpb25FbGVtZW50Iiwid2FpdEZvclRyYW5zaXRpb24iLCJkdXJhdGlvblBhZGRpbmciLCJlbXVsYXRlZER1cmF0aW9uIiwiY2FsbGVkIiwiaGFuZGxlciIsIl9yZWY2IiwidGFyZ2V0IiwicmVtb3ZlRXZlbnRMaXN0ZW5lciIsInNldFRpbWVvdXQiLCJnZXROZXh0QWN0aXZlRWxlbWVudCIsImxpc3QiLCJhY3RpdmVFbGVtZW50Iiwic2hvdWxkR2V0TmV4dCIsImlzQ3ljbGVBbGxvd2VkIiwibGlzdExlbmd0aCIsImluZGV4IiwiaW5kZXhPZiIsIm1heCIsIm1pbiIsIm5hbWVzcGFjZVJlZ2V4Iiwic3RyaXBOYW1lUmVnZXgiLCJzdHJpcFVpZFJlZ2V4IiwiZXZlbnRSZWdpc3RyeSIsInVpZEV2ZW50IiwiY3VzdG9tRXZlbnRzIiwibW91c2VlbnRlciIsIm1vdXNlbGVhdmUiLCJuYXRpdmVFdmVudHMiLCJTZXQiLCJtYWtlRXZlbnRVaWQiLCJ1aWQiLCJnZXRFbGVtZW50RXZlbnRzIiwiYm9vdHN0cmFwSGFuZGxlciIsImV2ZW50IiwiaHlkcmF0ZU9iaiIsImRlbGVnYXRlVGFyZ2V0Iiwib25lT2ZmIiwiRXZlbnRIYW5kbGVyIiwib2ZmIiwidHlwZSIsImFwcGx5IiwiYm9vdHN0cmFwRGVsZWdhdGlvbkhhbmRsZXIiLCJkb21FbGVtZW50cyIsInF1ZXJ5U2VsZWN0b3JBbGwiLCJkb21FbGVtZW50IiwiZmluZEhhbmRsZXIiLCJldmVudHMiLCJjYWxsYWJsZSIsImRlbGVnYXRpb25TZWxlY3RvciIsInZhbHVlcyIsImZpbmQiLCJub3JtYWxpemVQYXJhbWV0ZXJzIiwib3JpZ2luYWxUeXBlRXZlbnQiLCJkZWxlZ2F0aW9uRnVuY3Rpb24iLCJpc0RlbGVnYXRlZCIsInR5cGVFdmVudCIsImdldFR5cGVFdmVudCIsImFkZEhhbmRsZXIiLCJ3cmFwRnVuY3Rpb24iLCJyZWxhdGVkVGFyZ2V0IiwiaGFuZGxlcnMiLCJwcmV2aW91c0Z1bmN0aW9uIiwicmVtb3ZlSGFuZGxlciIsIkJvb2xlYW4iLCJyZW1vdmVOYW1lc3BhY2VkSGFuZGxlcnMiLCJuYW1lc3BhY2UiLCJzdG9yZUVsZW1lbnRFdmVudCIsImhhbmRsZXJLZXkiLCJlbnRyaWVzIiwiaW5jbHVkZXMiLCJvbiIsIm9uZSIsImluTmFtZXNwYWNlIiwiaXNOYW1lc3BhY2UiLCJzdGFydHNXaXRoIiwiZWxlbWVudEV2ZW50Iiwic2xpY2UiLCJrZXlIYW5kbGVycyIsInRyaWdnZXIiLCJqUXVlcnlFdmVudCIsImJ1YmJsZXMiLCJuYXRpdmVEaXNwYXRjaCIsImRlZmF1bHRQcmV2ZW50ZWQiLCJpc1Byb3BhZ2F0aW9uU3RvcHBlZCIsImlzSW1tZWRpYXRlUHJvcGFnYXRpb25TdG9wcGVkIiwiaXNEZWZhdWx0UHJldmVudGVkIiwiZXZ0IiwiY2FuY2VsYWJsZSIsInByZXZlbnREZWZhdWx0Iiwib2JqIiwibWV0YSIsInZhbHVlIiwiX3VudXNlZCIsImRlZmluZVByb3BlcnR5IiwiY29uZmlndXJhYmxlIiwibm9ybWFsaXplRGF0YSIsIkpTT04iLCJwYXJzZSIsImRlY29kZVVSSUNvbXBvbmVudCIsIm5vcm1hbGl6ZURhdGFLZXkiLCJjaHIiLCJNYW5pcHVsYXRvciIsInNldERhdGFBdHRyaWJ1dGUiLCJzZXRBdHRyaWJ1dGUiLCJyZW1vdmVEYXRhQXR0cmlidXRlIiwicmVtb3ZlQXR0cmlidXRlIiwiZ2V0RGF0YUF0dHJpYnV0ZXMiLCJhdHRyaWJ1dGVzIiwiYnNLZXlzIiwiZGF0YXNldCIsImZpbHRlciIsInB1cmVLZXkiLCJjaGFyQXQiLCJnZXREYXRhQXR0cmlidXRlIiwiQ29uZmlnIiwiRGVmYXVsdCIsIkRlZmF1bHRUeXBlIiwiRXJyb3IiLCJfZ2V0Q29uZmlnIiwiY29uZmlnIiwiX21lcmdlQ29uZmlnT2JqIiwiX2NvbmZpZ0FmdGVyTWVyZ2UiLCJfdHlwZUNoZWNrQ29uZmlnIiwianNvbkNvbmZpZyIsImNvbnN0cnVjdG9yIiwiY29uZmlnVHlwZXMiLCJwcm9wZXJ0eSIsImV4cGVjdGVkVHlwZXMiLCJ2YWx1ZVR5cGUiLCJSZWdFeHAiLCJ0ZXN0IiwiVHlwZUVycm9yIiwidG9VcHBlckNhc2UiLCJWRVJTSU9OIiwiQmFzZUNvbXBvbmVudCIsIl9lbGVtZW50IiwiX2NvbmZpZyIsIkRBVEFfS0VZIiwiZGlzcG9zZSIsIkVWRU5UX0tFWSIsInByb3BlcnR5TmFtZSIsImdldE93blByb3BlcnR5TmFtZXMiLCJfcXVldWVDYWxsYmFjayIsImlzQW5pbWF0ZWQiLCJnZXRJbnN0YW5jZSIsImdldE9yQ3JlYXRlSW5zdGFuY2UiLCJldmVudE5hbWUiLCJnZXRTZWxlY3RvciIsImhyZWZBdHRyaWJ1dGUiLCJ0cmltIiwibWFwIiwic2VsIiwiam9pbiIsIlNlbGVjdG9yRW5naW5lIiwiY29uY2F0IiwiRWxlbWVudCIsImZpbmRPbmUiLCJjaGlsZHJlbiIsImNoaWxkIiwibWF0Y2hlcyIsInBhcmVudHMiLCJhbmNlc3RvciIsInByZXYiLCJwcmV2aW91cyIsInByZXZpb3VzRWxlbWVudFNpYmxpbmciLCJuZXh0IiwibmV4dEVsZW1lbnRTaWJsaW5nIiwiZm9jdXNhYmxlQ2hpbGRyZW4iLCJmb2N1c2FibGVzIiwiZWwiLCJnZXRTZWxlY3RvckZyb21FbGVtZW50IiwiZ2V0RWxlbWVudEZyb21TZWxlY3RvciIsImdldE11bHRpcGxlRWxlbWVudHNGcm9tU2VsZWN0b3IiLCJlbmFibGVEaXNtaXNzVHJpZ2dlciIsImNvbXBvbmVudCIsIm1ldGhvZCIsImNsaWNrRXZlbnQiLCJ0YWdOYW1lIiwiTkFNRSRmIiwiREFUQV9LRVkkYSIsIkVWRU5UX0tFWSRiIiwiRVZFTlRfQ0xPU0UiLCJFVkVOVF9DTE9TRUQiLCJDTEFTU19OQU1FX0ZBREUkNSIsIkNMQVNTX05BTUVfU0hPVyQ4IiwiQWxlcnQiLCJjbG9zZSIsImNsb3NlRXZlbnQiLCJfZGVzdHJveUVsZW1lbnQiLCJlYWNoIiwiZGF0YSIsIk5BTUUkZSIsIkRBVEFfS0VZJDkiLCJFVkVOVF9LRVkkYSIsIkRBVEFfQVBJX0tFWSQ2IiwiQ0xBU1NfTkFNRV9BQ1RJVkUkMyIsIlNFTEVDVE9SX0RBVEFfVE9HR0xFJDUiLCJFVkVOVF9DTElDS19EQVRBX0FQSSQ2IiwiQnV0dG9uIiwidG9nZ2xlIiwiYnV0dG9uIiwiTkFNRSRkIiwiRVZFTlRfS0VZJDkiLCJFVkVOVF9UT1VDSFNUQVJUIiwiRVZFTlRfVE9VQ0hNT1ZFIiwiRVZFTlRfVE9VQ0hFTkQiLCJFVkVOVF9QT0lOVEVSRE9XTiIsIkVWRU5UX1BPSU5URVJVUCIsIlBPSU5URVJfVFlQRV9UT1VDSCIsIlBPSU5URVJfVFlQRV9QRU4iLCJDTEFTU19OQU1FX1BPSU5URVJfRVZFTlQiLCJTV0lQRV9USFJFU0hPTEQiLCJEZWZhdWx0JGMiLCJlbmRDYWxsYmFjayIsImxlZnRDYWxsYmFjayIsInJpZ2h0Q2FsbGJhY2siLCJEZWZhdWx0VHlwZSRjIiwiU3dpcGUiLCJpc1N1cHBvcnRlZCIsIl9kZWx0YVgiLCJfc3VwcG9ydFBvaW50ZXJFdmVudHMiLCJQb2ludGVyRXZlbnQiLCJfaW5pdEV2ZW50cyIsIl9zdGFydCIsInRvdWNoZXMiLCJjbGllbnRYIiwiX2V2ZW50SXNQb2ludGVyUGVuVG91Y2giLCJfZW5kIiwiX2hhbmRsZVN3aXBlIiwiX21vdmUiLCJhYnNEZWx0YVgiLCJhYnMiLCJkaXJlY3Rpb24iLCJhZGQiLCJwb2ludGVyVHlwZSIsIm5hdmlnYXRvciIsIm1heFRvdWNoUG9pbnRzIiwiTkFNRSRjIiwiREFUQV9LRVkkOCIsIkVWRU5UX0tFWSQ4IiwiREFUQV9BUElfS0VZJDUiLCJBUlJPV19MRUZUX0tFWSQxIiwiQVJST1dfUklHSFRfS0VZJDEiLCJUT1VDSEVWRU5UX0NPTVBBVF9XQUlUIiwiT1JERVJfTkVYVCIsIk9SREVSX1BSRVYiLCJESVJFQ1RJT05fTEVGVCIsIkRJUkVDVElPTl9SSUdIVCIsIkVWRU5UX1NMSURFIiwiRVZFTlRfU0xJRCIsIkVWRU5UX0tFWURPV04kMSIsIkVWRU5UX01PVVNFRU5URVIkMSIsIkVWRU5UX01PVVNFTEVBVkUkMSIsIkVWRU5UX0RSQUdfU1RBUlQiLCJFVkVOVF9MT0FEX0RBVEFfQVBJJDMiLCJFVkVOVF9DTElDS19EQVRBX0FQSSQ1IiwiQ0xBU1NfTkFNRV9DQVJPVVNFTCIsIkNMQVNTX05BTUVfQUNUSVZFJDIiLCJDTEFTU19OQU1FX1NMSURFIiwiQ0xBU1NfTkFNRV9FTkQiLCJDTEFTU19OQU1FX1NUQVJUIiwiQ0xBU1NfTkFNRV9ORVhUIiwiQ0xBU1NfTkFNRV9QUkVWIiwiU0VMRUNUT1JfQUNUSVZFIiwiU0VMRUNUT1JfSVRFTSIsIlNFTEVDVE9SX0FDVElWRV9JVEVNIiwiU0VMRUNUT1JfSVRFTV9JTUciLCJTRUxFQ1RPUl9JTkRJQ0FUT1JTIiwiU0VMRUNUT1JfREFUQV9TTElERSIsIlNFTEVDVE9SX0RBVEFfUklERSIsIktFWV9UT19ESVJFQ1RJT04iLCJEZWZhdWx0JGIiLCJpbnRlcnZhbCIsImtleWJvYXJkIiwicGF1c2UiLCJyaWRlIiwidG91Y2giLCJ3cmFwIiwiRGVmYXVsdFR5cGUkYiIsIkNhcm91c2VsIiwiX2ludGVydmFsIiwiX2FjdGl2ZUVsZW1lbnQiLCJfaXNTbGlkaW5nIiwidG91Y2hUaW1lb3V0IiwiX3N3aXBlSGVscGVyIiwiX2luZGljYXRvcnNFbGVtZW50IiwiX2FkZEV2ZW50TGlzdGVuZXJzIiwiY3ljbGUiLCJfc2xpZGUiLCJuZXh0V2hlblZpc2libGUiLCJoaWRkZW4iLCJfY2xlYXJJbnRlcnZhbCIsIl91cGRhdGVJbnRlcnZhbCIsInNldEludGVydmFsIiwiX21heWJlRW5hYmxlQ3ljbGUiLCJ0byIsIml0ZW1zIiwiX2dldEl0ZW1zIiwiYWN0aXZlSW5kZXgiLCJfZ2V0SXRlbUluZGV4IiwiX2dldEFjdGl2ZSIsIm9yZGVyIiwiZGVmYXVsdEludGVydmFsIiwiX2tleWRvd24iLCJfYWRkVG91Y2hFdmVudExpc3RlbmVycyIsImltZyIsImVuZENhbGxCYWNrIiwiY2xlYXJUaW1lb3V0Iiwic3dpcGVDb25maWciLCJfZGlyZWN0aW9uVG9PcmRlciIsIl9zZXRBY3RpdmVJbmRpY2F0b3JFbGVtZW50IiwiYWN0aXZlSW5kaWNhdG9yIiwibmV3QWN0aXZlSW5kaWNhdG9yIiwiZWxlbWVudEludGVydmFsIiwicGFyc2VJbnQiLCJpc05leHQiLCJuZXh0RWxlbWVudCIsIm5leHRFbGVtZW50SW5kZXgiLCJ0cmlnZ2VyRXZlbnQiLCJfb3JkZXJUb0RpcmVjdGlvbiIsInNsaWRlRXZlbnQiLCJpc0N5Y2xpbmciLCJkaXJlY3Rpb25hbENsYXNzTmFtZSIsIm9yZGVyQ2xhc3NOYW1lIiwiY29tcGxldGVDYWxsQmFjayIsIl9pc0FuaW1hdGVkIiwiY2xlYXJJbnRlcnZhbCIsImNhcm91c2VsIiwic2xpZGVJbmRleCIsImNhcm91c2VscyIsIk5BTUUkYiIsIkRBVEFfS0VZJDciLCJFVkVOVF9LRVkkNyIsIkRBVEFfQVBJX0tFWSQ0IiwiRVZFTlRfU0hPVyQ2IiwiRVZFTlRfU0hPV04kNiIsIkVWRU5UX0hJREUkNiIsIkVWRU5UX0hJRERFTiQ2IiwiRVZFTlRfQ0xJQ0tfREFUQV9BUEkkNCIsIkNMQVNTX05BTUVfU0hPVyQ3IiwiQ0xBU1NfTkFNRV9DT0xMQVBTRSIsIkNMQVNTX05BTUVfQ09MTEFQU0lORyIsIkNMQVNTX05BTUVfQ09MTEFQU0VEIiwiQ0xBU1NfTkFNRV9ERUVQRVJfQ0hJTERSRU4iLCJDTEFTU19OQU1FX0hPUklaT05UQUwiLCJXSURUSCIsIkhFSUdIVCIsIlNFTEVDVE9SX0FDVElWRVMiLCJTRUxFQ1RPUl9EQVRBX1RPR0dMRSQ0IiwiRGVmYXVsdCRhIiwicGFyZW50IiwiRGVmYXVsdFR5cGUkYSIsIkNvbGxhcHNlIiwiX2lzVHJhbnNpdGlvbmluZyIsIl90cmlnZ2VyQXJyYXkiLCJ0b2dnbGVMaXN0IiwiZWxlbSIsImZpbHRlckVsZW1lbnQiLCJmb3VuZEVsZW1lbnQiLCJfaW5pdGlhbGl6ZUNoaWxkcmVuIiwiX2FkZEFyaWFBbmRDb2xsYXBzZWRDbGFzcyIsIl9pc1Nob3duIiwiaGlkZSIsInNob3ciLCJhY3RpdmVDaGlsZHJlbiIsIl9nZXRGaXJzdExldmVsQ2hpbGRyZW4iLCJzdGFydEV2ZW50IiwiYWN0aXZlSW5zdGFuY2UiLCJkaW1lbnNpb24iLCJfZ2V0RGltZW5zaW9uIiwic3R5bGUiLCJjb21wbGV0ZSIsImNhcGl0YWxpemVkRGltZW5zaW9uIiwic2Nyb2xsU2l6ZSIsImdldEJvdW5kaW5nQ2xpZW50UmVjdCIsInNlbGVjdGVkIiwidHJpZ2dlckFycmF5IiwiaXNPcGVuIiwidG9wIiwiYm90dG9tIiwicmlnaHQiLCJsZWZ0IiwiYXV0byIsImJhc2VQbGFjZW1lbnRzIiwic3RhcnQiLCJlbmQiLCJjbGlwcGluZ1BhcmVudHMiLCJ2aWV3cG9ydCIsInBvcHBlciIsInJlZmVyZW5jZSIsInZhcmlhdGlvblBsYWNlbWVudHMiLCJyZWR1Y2UiLCJhY2MiLCJwbGFjZW1lbnQiLCJwbGFjZW1lbnRzIiwiYmVmb3JlUmVhZCIsInJlYWQiLCJhZnRlclJlYWQiLCJiZWZvcmVNYWluIiwibWFpbiIsImFmdGVyTWFpbiIsImJlZm9yZVdyaXRlIiwid3JpdGUiLCJhZnRlcldyaXRlIiwibW9kaWZpZXJQaGFzZXMiLCJnZXROb2RlTmFtZSIsIm5vZGVOYW1lIiwiZ2V0V2luZG93Iiwibm9kZSIsIm93bmVyRG9jdW1lbnQiLCJkZWZhdWx0VmlldyIsImlzRWxlbWVudCIsIk93bkVsZW1lbnQiLCJpc0hUTUxFbGVtZW50IiwiSFRNTEVsZW1lbnQiLCJpc1NoYWRvd1Jvb3QiLCJhcHBseVN0eWxlcyIsIl9yZWYiLCJzdGF0ZSIsImVsZW1lbnRzIiwiZm9yRWFjaCIsInN0eWxlcyIsImFzc2lnbiIsImVmZmVjdCQyIiwiZWZmZWN0IiwiX3JlZjIiLCJpbml0aWFsU3R5bGVzIiwicG9zaXRpb24iLCJvcHRpb25zIiwic3RyYXRlZ3kiLCJtYXJnaW4iLCJhcnJvdyIsInN0eWxlUHJvcGVydGllcyIsImhhc093blByb3BlcnR5IiwiYXR0cmlidXRlIiwiYXBwbHlTdHlsZXMkMSIsImVuYWJsZWQiLCJwaGFzZSIsInJlcXVpcmVzIiwiZ2V0QmFzZVBsYWNlbWVudCIsInJvdW5kIiwiZ2V0VUFTdHJpbmciLCJ1YURhdGEiLCJ1c2VyQWdlbnREYXRhIiwiYnJhbmRzIiwiaXNBcnJheSIsIml0ZW0iLCJicmFuZCIsInZlcnNpb24iLCJ1c2VyQWdlbnQiLCJpc0xheW91dFZpZXdwb3J0IiwiaW5jbHVkZVNjYWxlIiwiaXNGaXhlZFN0cmF0ZWd5IiwiY2xpZW50UmVjdCIsInNjYWxlWCIsInNjYWxlWSIsIm9mZnNldFdpZHRoIiwid2lkdGgiLCJoZWlnaHQiLCJ2aXN1YWxWaWV3cG9ydCIsImFkZFZpc3VhbE9mZnNldHMiLCJ4Iiwib2Zmc2V0TGVmdCIsInkiLCJvZmZzZXRUb3AiLCJnZXRMYXlvdXRSZWN0Iiwicm9vdE5vZGUiLCJpc1NhbWVOb2RlIiwiaG9zdCIsImdldENvbXB1dGVkU3R5bGUkMSIsImlzVGFibGVFbGVtZW50IiwiZ2V0RG9jdW1lbnRFbGVtZW50IiwiZ2V0UGFyZW50Tm9kZSIsImFzc2lnbmVkU2xvdCIsImdldFRydWVPZmZzZXRQYXJlbnQiLCJvZmZzZXRQYXJlbnQiLCJnZXRDb250YWluaW5nQmxvY2siLCJpc0ZpcmVmb3giLCJpc0lFIiwiZWxlbWVudENzcyIsImN1cnJlbnROb2RlIiwiY3NzIiwidHJhbnNmb3JtIiwicGVyc3BlY3RpdmUiLCJjb250YWluIiwid2lsbENoYW5nZSIsImdldE9mZnNldFBhcmVudCIsImdldE1haW5BeGlzRnJvbVBsYWNlbWVudCIsIndpdGhpbiIsIm1pbiQxIiwibWF4JDEiLCJ3aXRoaW5NYXhDbGFtcCIsInYiLCJnZXRGcmVzaFNpZGVPYmplY3QiLCJtZXJnZVBhZGRpbmdPYmplY3QiLCJwYWRkaW5nT2JqZWN0IiwiZXhwYW5kVG9IYXNoTWFwIiwiaGFzaE1hcCIsInRvUGFkZGluZ09iamVjdCIsInBhZGRpbmciLCJyZWN0cyIsIl9zdGF0ZSRtb2RpZmllcnNEYXRhJCIsImFycm93RWxlbWVudCIsInBvcHBlck9mZnNldHMiLCJtb2RpZmllcnNEYXRhIiwiYmFzZVBsYWNlbWVudCIsImF4aXMiLCJpc1ZlcnRpY2FsIiwibGVuIiwiYXJyb3dSZWN0IiwibWluUHJvcCIsIm1heFByb3AiLCJlbmREaWZmIiwic3RhcnREaWZmIiwiYXJyb3dPZmZzZXRQYXJlbnQiLCJjbGllbnRTaXplIiwiY2xpZW50SGVpZ2h0IiwiY2xpZW50V2lkdGgiLCJjZW50ZXJUb1JlZmVyZW5jZSIsImNlbnRlciIsIm9mZnNldCIsImF4aXNQcm9wIiwiY2VudGVyT2Zmc2V0IiwiZWZmZWN0JDEiLCJfb3B0aW9ucyRlbGVtZW50IiwiYXJyb3ckMSIsInJlcXVpcmVzSWZFeGlzdHMiLCJnZXRWYXJpYXRpb24iLCJ1bnNldFNpZGVzIiwicm91bmRPZmZzZXRzQnlEUFIiLCJ3aW4iLCJkcHIiLCJkZXZpY2VQaXhlbFJhdGlvIiwibWFwVG9TdHlsZXMiLCJfT2JqZWN0JGFzc2lnbjIiLCJwb3BwZXJSZWN0IiwidmFyaWF0aW9uIiwib2Zmc2V0cyIsImdwdUFjY2VsZXJhdGlvbiIsImFkYXB0aXZlIiwicm91bmRPZmZzZXRzIiwiaXNGaXhlZCIsIl9vZmZzZXRzJHgiLCJfb2Zmc2V0cyR5IiwiX3JlZjMiLCJoYXNYIiwiaGFzWSIsInNpZGVYIiwic2lkZVkiLCJoZWlnaHRQcm9wIiwid2lkdGhQcm9wIiwib2Zmc2V0WSIsIm9mZnNldFgiLCJjb21tb25TdHlsZXMiLCJfcmVmNCIsIl9PYmplY3QkYXNzaWduIiwiY29tcHV0ZVN0eWxlcyIsIl9yZWY1IiwiX29wdGlvbnMkZ3B1QWNjZWxlcmF0IiwiX29wdGlvbnMkYWRhcHRpdmUiLCJfb3B0aW9ucyRyb3VuZE9mZnNldHMiLCJjb21wdXRlU3R5bGVzJDEiLCJwYXNzaXZlIiwiX29wdGlvbnMkc2Nyb2xsIiwic2Nyb2xsIiwiX29wdGlvbnMkcmVzaXplIiwicmVzaXplIiwic2Nyb2xsUGFyZW50cyIsInNjcm9sbFBhcmVudCIsInVwZGF0ZSIsImV2ZW50TGlzdGVuZXJzIiwiaGFzaCQxIiwiZ2V0T3Bwb3NpdGVQbGFjZW1lbnQiLCJtYXRjaGVkIiwiaGFzaCIsImdldE9wcG9zaXRlVmFyaWF0aW9uUGxhY2VtZW50IiwiZ2V0V2luZG93U2Nyb2xsIiwic2Nyb2xsTGVmdCIsInBhZ2VYT2Zmc2V0Iiwic2Nyb2xsVG9wIiwicGFnZVlPZmZzZXQiLCJnZXRXaW5kb3dTY3JvbGxCYXJYIiwiZ2V0Vmlld3BvcnRSZWN0IiwiaHRtbCIsImxheW91dFZpZXdwb3J0IiwiZ2V0RG9jdW1lbnRSZWN0IiwiX2VsZW1lbnQkb3duZXJEb2N1bWVuIiwid2luU2Nyb2xsIiwic2Nyb2xsV2lkdGgiLCJzY3JvbGxIZWlnaHQiLCJpc1Njcm9sbFBhcmVudCIsIl9nZXRDb21wdXRlZFN0eWxlIiwib3ZlcmZsb3ciLCJvdmVyZmxvd1giLCJvdmVyZmxvd1kiLCJnZXRTY3JvbGxQYXJlbnQiLCJsaXN0U2Nyb2xsUGFyZW50cyIsImlzQm9keSIsInVwZGF0ZWRMaXN0IiwicmVjdFRvQ2xpZW50UmVjdCIsInJlY3QiLCJnZXRJbm5lckJvdW5kaW5nQ2xpZW50UmVjdCIsImNsaWVudFRvcCIsImNsaWVudExlZnQiLCJnZXRDbGllbnRSZWN0RnJvbU1peGVkVHlwZSIsImNsaXBwaW5nUGFyZW50IiwiZ2V0Q2xpcHBpbmdQYXJlbnRzIiwiY2FuRXNjYXBlQ2xpcHBpbmciLCJjbGlwcGVyRWxlbWVudCIsImdldENsaXBwaW5nUmVjdCIsImJvdW5kYXJ5Iiwicm9vdEJvdW5kYXJ5IiwibWFpbkNsaXBwaW5nUGFyZW50cyIsImZpcnN0Q2xpcHBpbmdQYXJlbnQiLCJjbGlwcGluZ1JlY3QiLCJhY2NSZWN0IiwiY29tcHV0ZU9mZnNldHMiLCJjb21tb25YIiwiY29tbW9uWSIsIm1haW5BeGlzIiwiZGV0ZWN0T3ZlcmZsb3ciLCJfb3B0aW9ucyIsIl9vcHRpb25zJHBsYWNlbWVudCIsIl9vcHRpb25zJHN0cmF0ZWd5IiwiX29wdGlvbnMkYm91bmRhcnkiLCJfb3B0aW9ucyRyb290Qm91bmRhcnkiLCJfb3B0aW9ucyRlbGVtZW50Q29udGUiLCJlbGVtZW50Q29udGV4dCIsIl9vcHRpb25zJGFsdEJvdW5kYXJ5IiwiYWx0Qm91bmRhcnkiLCJfb3B0aW9ucyRwYWRkaW5nIiwiYWx0Q29udGV4dCIsImNsaXBwaW5nQ2xpZW50UmVjdCIsImNvbnRleHRFbGVtZW50IiwicmVmZXJlbmNlQ2xpZW50UmVjdCIsInBvcHBlckNsaWVudFJlY3QiLCJlbGVtZW50Q2xpZW50UmVjdCIsIm92ZXJmbG93T2Zmc2V0cyIsIm9mZnNldERhdGEiLCJtdWx0aXBseSIsImNvbXB1dGVBdXRvUGxhY2VtZW50IiwiZmxpcFZhcmlhdGlvbnMiLCJfb3B0aW9ucyRhbGxvd2VkQXV0b1AiLCJhbGxvd2VkQXV0b1BsYWNlbWVudHMiLCJwbGFjZW1lbnRzJDEiLCJhbGxvd2VkUGxhY2VtZW50cyIsIm92ZXJmbG93cyIsInNvcnQiLCJhIiwiYiIsImdldEV4cGFuZGVkRmFsbGJhY2tQbGFjZW1lbnRzIiwib3Bwb3NpdGVQbGFjZW1lbnQiLCJmbGlwIiwiX3NraXAiLCJfb3B0aW9ucyRtYWluQXhpcyIsImNoZWNrTWFpbkF4aXMiLCJfb3B0aW9ucyRhbHRBeGlzIiwiYWx0QXhpcyIsImNoZWNrQWx0QXhpcyIsInNwZWNpZmllZEZhbGxiYWNrUGxhY2VtZW50cyIsImZhbGxiYWNrUGxhY2VtZW50cyIsIl9vcHRpb25zJGZsaXBWYXJpYXRpbyIsInByZWZlcnJlZFBsYWNlbWVudCIsImlzQmFzZVBsYWNlbWVudCIsInJlZmVyZW5jZVJlY3QiLCJjaGVja3NNYXAiLCJtYWtlRmFsbGJhY2tDaGVja3MiLCJmaXJzdEZpdHRpbmdQbGFjZW1lbnQiLCJpIiwiX2Jhc2VQbGFjZW1lbnQiLCJpc1N0YXJ0VmFyaWF0aW9uIiwibWFpblZhcmlhdGlvblNpZGUiLCJhbHRWYXJpYXRpb25TaWRlIiwiY2hlY2tzIiwiZXZlcnkiLCJjaGVjayIsIm51bWJlck9mQ2hlY2tzIiwiX2xvb3AiLCJfaSIsImZpdHRpbmdQbGFjZW1lbnQiLCJfcmV0IiwicmVzZXQiLCJmbGlwJDEiLCJnZXRTaWRlT2Zmc2V0cyIsInByZXZlbnRlZE9mZnNldHMiLCJpc0FueVNpZGVGdWxseUNsaXBwZWQiLCJzb21lIiwic2lkZSIsInByZXZlbnRPdmVyZmxvdyIsInJlZmVyZW5jZU92ZXJmbG93IiwicG9wcGVyQWx0T3ZlcmZsb3ciLCJyZWZlcmVuY2VDbGlwcGluZ09mZnNldHMiLCJwb3BwZXJFc2NhcGVPZmZzZXRzIiwiaXNSZWZlcmVuY2VIaWRkZW4iLCJoYXNQb3BwZXJFc2NhcGVkIiwiaGlkZSQxIiwiZGlzdGFuY2VBbmRTa2lkZGluZ1RvWFkiLCJpbnZlcnREaXN0YW5jZSIsInNraWRkaW5nIiwiZGlzdGFuY2UiLCJfb3B0aW9ucyRvZmZzZXQiLCJfZGF0YSRzdGF0ZSRwbGFjZW1lbnQiLCJvZmZzZXQkMSIsInBvcHBlck9mZnNldHMkMSIsImdldEFsdEF4aXMiLCJfb3B0aW9ucyR0ZXRoZXIiLCJ0ZXRoZXIiLCJfb3B0aW9ucyR0ZXRoZXJPZmZzZXQiLCJ0ZXRoZXJPZmZzZXQiLCJ0ZXRoZXJPZmZzZXRWYWx1ZSIsIm5vcm1hbGl6ZWRUZXRoZXJPZmZzZXRWYWx1ZSIsIm9mZnNldE1vZGlmaWVyU3RhdGUiLCJfb2Zmc2V0TW9kaWZpZXJTdGF0ZSQiLCJtYWluU2lkZSIsImFsdFNpZGUiLCJhZGRpdGl2ZSIsIm1pbkxlbiIsIm1heExlbiIsImFycm93UGFkZGluZ09iamVjdCIsImFycm93UGFkZGluZ01pbiIsImFycm93UGFkZGluZ01heCIsImFycm93TGVuIiwibWluT2Zmc2V0IiwibWF4T2Zmc2V0IiwiY2xpZW50T2Zmc2V0Iiwib2Zmc2V0TW9kaWZpZXJWYWx1ZSIsInRldGhlck1pbiIsInRldGhlck1heCIsInByZXZlbnRlZE9mZnNldCIsIl9vZmZzZXRNb2RpZmllclN0YXRlJDIiLCJfbWFpblNpZGUiLCJfYWx0U2lkZSIsIl9vZmZzZXQiLCJfbGVuIiwiX21pbiIsIl9tYXgiLCJpc09yaWdpblNpZGUiLCJfb2Zmc2V0TW9kaWZpZXJWYWx1ZSIsIl90ZXRoZXJNaW4iLCJfdGV0aGVyTWF4IiwiX3ByZXZlbnRlZE9mZnNldCIsInByZXZlbnRPdmVyZmxvdyQxIiwiZ2V0SFRNTEVsZW1lbnRTY3JvbGwiLCJnZXROb2RlU2Nyb2xsIiwiaXNFbGVtZW50U2NhbGVkIiwiZ2V0Q29tcG9zaXRlUmVjdCIsImVsZW1lbnRPclZpcnR1YWxFbGVtZW50IiwiaXNPZmZzZXRQYXJlbnRBbkVsZW1lbnQiLCJvZmZzZXRQYXJlbnRJc1NjYWxlZCIsIm1vZGlmaWVycyIsInZpc2l0ZWQiLCJyZXN1bHQiLCJtb2RpZmllciIsImRlcCIsImRlcE1vZGlmaWVyIiwib3JkZXJNb2RpZmllcnMiLCJvcmRlcmVkTW9kaWZpZXJzIiwiZGVib3VuY2UiLCJwZW5kaW5nIiwiUHJvbWlzZSIsInJlc29sdmUiLCJ0aGVuIiwibWVyZ2VCeU5hbWUiLCJtZXJnZWQiLCJjdXJyZW50IiwiZXhpc3RpbmciLCJERUZBVUxUX09QVElPTlMiLCJhcmVWYWxpZEVsZW1lbnRzIiwiX2tleSIsInBvcHBlckdlbmVyYXRvciIsImdlbmVyYXRvck9wdGlvbnMiLCJfZ2VuZXJhdG9yT3B0aW9ucyIsIl9nZW5lcmF0b3JPcHRpb25zJGRlZiIsImRlZmF1bHRNb2RpZmllcnMiLCJfZ2VuZXJhdG9yT3B0aW9ucyRkZWYyIiwiZGVmYXVsdE9wdGlvbnMiLCJjcmVhdGVQb3BwZXIiLCJlZmZlY3RDbGVhbnVwRm5zIiwiaXNEZXN0cm95ZWQiLCJzZXRPcHRpb25zIiwic2V0T3B0aW9uc0FjdGlvbiIsImNsZWFudXBNb2RpZmllckVmZmVjdHMiLCJtIiwicnVuTW9kaWZpZXJFZmZlY3RzIiwiZm9yY2VVcGRhdGUiLCJfc3RhdGUkZWxlbWVudHMiLCJfc3RhdGUkb3JkZXJlZE1vZGlmaWUiLCJfc3RhdGUkb3JkZXJlZE1vZGlmaWUyIiwiZGVzdHJveSIsIm9uRmlyc3RVcGRhdGUiLCJfcmVmJG9wdGlvbnMiLCJjbGVhbnVwRm4iLCJub29wRm4iLCJjcmVhdGVQb3BwZXIkMiIsImRlZmF1bHRNb2RpZmllcnMkMSIsImNyZWF0ZVBvcHBlciQxIiwiTkFNRSRhIiwiREFUQV9LRVkkNiIsIkVWRU5UX0tFWSQ2IiwiREFUQV9BUElfS0VZJDMiLCJFU0NBUEVfS0VZJDIiLCJUQUJfS0VZJDEiLCJBUlJPV19VUF9LRVkkMSIsIkFSUk9XX0RPV05fS0VZJDEiLCJSSUdIVF9NT1VTRV9CVVRUT04iLCJFVkVOVF9ISURFJDUiLCJFVkVOVF9ISURERU4kNSIsIkVWRU5UX1NIT1ckNSIsIkVWRU5UX1NIT1dOJDUiLCJFVkVOVF9DTElDS19EQVRBX0FQSSQzIiwiRVZFTlRfS0VZRE9XTl9EQVRBX0FQSSIsIkVWRU5UX0tFWVVQX0RBVEFfQVBJIiwiQ0xBU1NfTkFNRV9TSE9XJDYiLCJDTEFTU19OQU1FX0RST1BVUCIsIkNMQVNTX05BTUVfRFJPUEVORCIsIkNMQVNTX05BTUVfRFJPUFNUQVJUIiwiQ0xBU1NfTkFNRV9EUk9QVVBfQ0VOVEVSIiwiQ0xBU1NfTkFNRV9EUk9QRE9XTl9DRU5URVIiLCJTRUxFQ1RPUl9EQVRBX1RPR0dMRSQzIiwiU0VMRUNUT1JfREFUQV9UT0dHTEVfU0hPV04iLCJTRUxFQ1RPUl9NRU5VIiwiU0VMRUNUT1JfTkFWQkFSIiwiU0VMRUNUT1JfTkFWQkFSX05BViIsIlNFTEVDVE9SX1ZJU0lCTEVfSVRFTVMiLCJQTEFDRU1FTlRfVE9QIiwiUExBQ0VNRU5UX1RPUEVORCIsIlBMQUNFTUVOVF9CT1RUT00iLCJQTEFDRU1FTlRfQk9UVE9NRU5EIiwiUExBQ0VNRU5UX1JJR0hUIiwiUExBQ0VNRU5UX0xFRlQiLCJQTEFDRU1FTlRfVE9QQ0VOVEVSIiwiUExBQ0VNRU5UX0JPVFRPTUNFTlRFUiIsIkRlZmF1bHQkOSIsImF1dG9DbG9zZSIsImRpc3BsYXkiLCJwb3BwZXJDb25maWciLCJEZWZhdWx0VHlwZSQ5IiwiRHJvcGRvd24iLCJfcG9wcGVyIiwiX3BhcmVudCIsIl9tZW51IiwiX2luTmF2YmFyIiwiX2RldGVjdE5hdmJhciIsInNob3dFdmVudCIsIl9jcmVhdGVQb3BwZXIiLCJmb2N1cyIsIl9jb21wbGV0ZUhpZGUiLCJoaWRlRXZlbnQiLCJQb3BwZXIiLCJyZWZlcmVuY2VFbGVtZW50IiwiX2dldFBvcHBlckNvbmZpZyIsIl9nZXRQbGFjZW1lbnQiLCJwYXJlbnREcm9wZG93biIsImlzRW5kIiwiX2dldE9mZnNldCIsInBvcHBlckRhdGEiLCJkZWZhdWx0QnNQb3BwZXJDb25maWciLCJfc2VsZWN0TWVudUl0ZW0iLCJfcmVmNyIsImNsZWFyTWVudXMiLCJvcGVuVG9nZ2xlcyIsImNvbnRleHQiLCJjb21wb3NlZFBhdGgiLCJpc01lbnVUYXJnZXQiLCJkYXRhQXBpS2V5ZG93bkhhbmRsZXIiLCJpc0lucHV0IiwiaXNFc2NhcGVFdmVudCIsImlzVXBPckRvd25FdmVudCIsImdldFRvZ2dsZUJ1dHRvbiIsInN0b3BQcm9wYWdhdGlvbiIsIk5BTUUkOSIsIkNMQVNTX05BTUVfRkFERSQ0IiwiQ0xBU1NfTkFNRV9TSE9XJDUiLCJFVkVOVF9NT1VTRURPV04iLCJEZWZhdWx0JDgiLCJjbGFzc05hbWUiLCJjbGlja0NhbGxiYWNrIiwicm9vdEVsZW1lbnQiLCJEZWZhdWx0VHlwZSQ4IiwiQmFja2Ryb3AiLCJfaXNBcHBlbmRlZCIsIl9hcHBlbmQiLCJfZ2V0RWxlbWVudCIsIl9lbXVsYXRlQW5pbWF0aW9uIiwiYmFja2Ryb3AiLCJjcmVhdGVFbGVtZW50IiwiYXBwZW5kIiwiTkFNRSQ4IiwiREFUQV9LRVkkNSIsIkVWRU5UX0tFWSQ1IiwiRVZFTlRfRk9DVVNJTiQyIiwiRVZFTlRfS0VZRE9XTl9UQUIiLCJUQUJfS0VZIiwiVEFCX05BVl9GT1JXQVJEIiwiVEFCX05BVl9CQUNLV0FSRCIsIkRlZmF1bHQkNyIsImF1dG9mb2N1cyIsInRyYXBFbGVtZW50IiwiRGVmYXVsdFR5cGUkNyIsIkZvY3VzVHJhcCIsIl9pc0FjdGl2ZSIsIl9sYXN0VGFiTmF2RGlyZWN0aW9uIiwiYWN0aXZhdGUiLCJfaGFuZGxlRm9jdXNpbiIsIl9oYW5kbGVLZXlkb3duIiwiZGVhY3RpdmF0ZSIsInNoaWZ0S2V5IiwiU0VMRUNUT1JfRklYRURfQ09OVEVOVCIsIlNFTEVDVE9SX1NUSUNLWV9DT05URU5UIiwiUFJPUEVSVFlfUEFERElORyIsIlBST1BFUlRZX01BUkdJTiIsIlNjcm9sbEJhckhlbHBlciIsImdldFdpZHRoIiwiZG9jdW1lbnRXaWR0aCIsImlubmVyV2lkdGgiLCJfZGlzYWJsZU92ZXJGbG93IiwiX3NldEVsZW1lbnRBdHRyaWJ1dGVzIiwiY2FsY3VsYXRlZFZhbHVlIiwiX3Jlc2V0RWxlbWVudEF0dHJpYnV0ZXMiLCJpc092ZXJmbG93aW5nIiwiX3NhdmVJbml0aWFsQXR0cmlidXRlIiwic3R5bGVQcm9wZXJ0eSIsInNjcm9sbGJhcldpZHRoIiwibWFuaXB1bGF0aW9uQ2FsbEJhY2siLCJzZXRQcm9wZXJ0eSIsIl9hcHBseU1hbmlwdWxhdGlvbkNhbGxiYWNrIiwiYWN0dWFsVmFsdWUiLCJyZW1vdmVQcm9wZXJ0eSIsImNhbGxCYWNrIiwiTkFNRSQ3IiwiREFUQV9LRVkkNCIsIkVWRU5UX0tFWSQ0IiwiREFUQV9BUElfS0VZJDIiLCJFU0NBUEVfS0VZJDEiLCJFVkVOVF9ISURFJDQiLCJFVkVOVF9ISURFX1BSRVZFTlRFRCQxIiwiRVZFTlRfSElEREVOJDQiLCJFVkVOVF9TSE9XJDQiLCJFVkVOVF9TSE9XTiQ0IiwiRVZFTlRfUkVTSVpFJDEiLCJFVkVOVF9DTElDS19ESVNNSVNTIiwiRVZFTlRfTU9VU0VET1dOX0RJU01JU1MiLCJFVkVOVF9LRVlET1dOX0RJU01JU1MkMSIsIkVWRU5UX0NMSUNLX0RBVEFfQVBJJDIiLCJDTEFTU19OQU1FX09QRU4iLCJDTEFTU19OQU1FX0ZBREUkMyIsIkNMQVNTX05BTUVfU0hPVyQ0IiwiQ0xBU1NfTkFNRV9TVEFUSUMiLCJPUEVOX1NFTEVDVE9SJDEiLCJTRUxFQ1RPUl9ESUFMT0ciLCJTRUxFQ1RPUl9NT0RBTF9CT0RZIiwiU0VMRUNUT1JfREFUQV9UT0dHTEUkMiIsIkRlZmF1bHQkNiIsIkRlZmF1bHRUeXBlJDYiLCJNb2RhbCIsIl9kaWFsb2ciLCJfYmFja2Ryb3AiLCJfaW5pdGlhbGl6ZUJhY2tEcm9wIiwiX2ZvY3VzdHJhcCIsIl9pbml0aWFsaXplRm9jdXNUcmFwIiwiX3Njcm9sbEJhciIsIl9hZGp1c3REaWFsb2ciLCJfc2hvd0VsZW1lbnQiLCJfaGlkZU1vZGFsIiwiaGFuZGxlVXBkYXRlIiwibW9kYWxCb2R5IiwidHJhbnNpdGlvbkNvbXBsZXRlIiwiX3RyaWdnZXJCYWNrZHJvcFRyYW5zaXRpb24iLCJldmVudDIiLCJfcmVzZXRBZGp1c3RtZW50cyIsImlzTW9kYWxPdmVyZmxvd2luZyIsImluaXRpYWxPdmVyZmxvd1kiLCJpc0JvZHlPdmVyZmxvd2luZyIsInBhZGRpbmdMZWZ0IiwicGFkZGluZ1JpZ2h0IiwiYWxyZWFkeU9wZW4iLCJOQU1FJDYiLCJEQVRBX0tFWSQzIiwiRVZFTlRfS0VZJDMiLCJEQVRBX0FQSV9LRVkkMSIsIkVWRU5UX0xPQURfREFUQV9BUEkkMiIsIkVTQ0FQRV9LRVkiLCJDTEFTU19OQU1FX1NIT1ckMyIsIkNMQVNTX05BTUVfU0hPV0lORyQxIiwiQ0xBU1NfTkFNRV9ISURJTkciLCJDTEFTU19OQU1FX0JBQ0tEUk9QIiwiT1BFTl9TRUxFQ1RPUiIsIkVWRU5UX1NIT1ckMyIsIkVWRU5UX1NIT1dOJDMiLCJFVkVOVF9ISURFJDMiLCJFVkVOVF9ISURFX1BSRVZFTlRFRCIsIkVWRU5UX0hJRERFTiQzIiwiRVZFTlRfUkVTSVpFIiwiRVZFTlRfQ0xJQ0tfREFUQV9BUEkkMSIsIkVWRU5UX0tFWURPV05fRElTTUlTUyIsIlNFTEVDVE9SX0RBVEFfVE9HR0xFJDEiLCJEZWZhdWx0JDUiLCJEZWZhdWx0VHlwZSQ1IiwiT2ZmY2FudmFzIiwiYmx1ciIsImNvbXBsZXRlQ2FsbGJhY2siLCJBUklBX0FUVFJJQlVURV9QQVRURVJOIiwiRGVmYXVsdEFsbG93bGlzdCIsImFyZWEiLCJiciIsImNvbCIsImNvZGUiLCJkZCIsImRpdiIsImRsIiwiZHQiLCJlbSIsImhyIiwiaDEiLCJoMiIsImgzIiwiaDQiLCJoNSIsImg2IiwibGkiLCJvbCIsInAiLCJwcmUiLCJzIiwic21hbGwiLCJzcGFuIiwic3ViIiwic3VwIiwic3Ryb25nIiwidSIsInVsIiwidXJpQXR0cmlidXRlcyIsIlNBRkVfVVJMX1BBVFRFUk4iLCJhbGxvd2VkQXR0cmlidXRlIiwiYWxsb3dlZEF0dHJpYnV0ZUxpc3QiLCJhdHRyaWJ1dGVOYW1lIiwibm9kZVZhbHVlIiwiYXR0cmlidXRlUmVnZXgiLCJyZWdleCIsInNhbml0aXplSHRtbCIsInVuc2FmZUh0bWwiLCJhbGxvd0xpc3QiLCJzYW5pdGl6ZUZ1bmN0aW9uIiwiZG9tUGFyc2VyIiwiRE9NUGFyc2VyIiwiY3JlYXRlZERvY3VtZW50IiwicGFyc2VGcm9tU3RyaW5nIiwiZWxlbWVudE5hbWUiLCJhdHRyaWJ1dGVMaXN0IiwiYWxsb3dlZEF0dHJpYnV0ZXMiLCJpbm5lckhUTUwiLCJOQU1FJDUiLCJEZWZhdWx0JDQiLCJjb250ZW50IiwiZXh0cmFDbGFzcyIsInNhbml0aXplIiwic2FuaXRpemVGbiIsInRlbXBsYXRlIiwiRGVmYXVsdFR5cGUkNCIsIkRlZmF1bHRDb250ZW50VHlwZSIsImVudHJ5IiwiVGVtcGxhdGVGYWN0b3J5IiwiZ2V0Q29udGVudCIsIl9yZXNvbHZlUG9zc2libGVGdW5jdGlvbiIsImhhc0NvbnRlbnQiLCJjaGFuZ2VDb250ZW50IiwiX2NoZWNrQ29udGVudCIsInRvSHRtbCIsInRlbXBsYXRlV3JhcHBlciIsIl9tYXliZVNhbml0aXplIiwidGV4dCIsIl9zZXRDb250ZW50IiwiYXJnIiwidGVtcGxhdGVFbGVtZW50IiwiX3B1dEVsZW1lbnRJblRlbXBsYXRlIiwidGV4dENvbnRlbnQiLCJOQU1FJDQiLCJESVNBTExPV0VEX0FUVFJJQlVURVMiLCJDTEFTU19OQU1FX0ZBREUkMiIsIkNMQVNTX05BTUVfTU9EQUwiLCJDTEFTU19OQU1FX1NIT1ckMiIsIlNFTEVDVE9SX1RPT0xUSVBfSU5ORVIiLCJTRUxFQ1RPUl9NT0RBTCIsIkVWRU5UX01PREFMX0hJREUiLCJUUklHR0VSX0hPVkVSIiwiVFJJR0dFUl9GT0NVUyIsIlRSSUdHRVJfQ0xJQ0siLCJUUklHR0VSX01BTlVBTCIsIkVWRU5UX0hJREUkMiIsIkVWRU5UX0hJRERFTiQyIiwiRVZFTlRfU0hPVyQyIiwiRVZFTlRfU0hPV04kMiIsIkVWRU5UX0lOU0VSVEVEIiwiRVZFTlRfQ0xJQ0skMSIsIkVWRU5UX0ZPQ1VTSU4kMSIsIkVWRU5UX0ZPQ1VTT1VUJDEiLCJFVkVOVF9NT1VTRUVOVEVSIiwiRVZFTlRfTU9VU0VMRUFWRSIsIkF0dGFjaG1lbnRNYXAiLCJBVVRPIiwiVE9QIiwiUklHSFQiLCJCT1RUT00iLCJMRUZUIiwiRGVmYXVsdCQzIiwiYW5pbWF0aW9uIiwiY29udGFpbmVyIiwiY3VzdG9tQ2xhc3MiLCJkZWxheSIsInRpdGxlIiwiRGVmYXVsdFR5cGUkMyIsIlRvb2x0aXAiLCJfaXNFbmFibGVkIiwiX3RpbWVvdXQiLCJfaXNIb3ZlcmVkIiwiX2FjdGl2ZVRyaWdnZXIiLCJfdGVtcGxhdGVGYWN0b3J5IiwiX25ld0NvbnRlbnQiLCJ0aXAiLCJfc2V0TGlzdGVuZXJzIiwiX2ZpeFRpdGxlIiwiZW5hYmxlIiwiZGlzYWJsZSIsInRvZ2dsZUVuYWJsZWQiLCJjbGljayIsIl9sZWF2ZSIsIl9lbnRlciIsIl9oaWRlTW9kYWxIYW5kbGVyIiwiX2Rpc3Bvc2VQb3BwZXIiLCJfaXNXaXRoQ29udGVudCIsInNoYWRvd1Jvb3QiLCJpc0luVGhlRG9tIiwiX2dldFRpcEVsZW1lbnQiLCJfaXNXaXRoQWN0aXZlVHJpZ2dlciIsIl9nZXRUaXRsZSIsIl9jcmVhdGVUaXBFbGVtZW50IiwiX2dldENvbnRlbnRGb3JUZW1wbGF0ZSIsIl9nZXRUZW1wbGF0ZUZhY3RvcnkiLCJ0aXBJZCIsInNldENvbnRlbnQiLCJfaW5pdGlhbGl6ZU9uRGVsZWdhdGVkVGFyZ2V0IiwiX2dldERlbGVnYXRlQ29uZmlnIiwiYXR0YWNobWVudCIsInRyaWdnZXJzIiwiZXZlbnRJbiIsImV2ZW50T3V0IiwiX3NldFRpbWVvdXQiLCJ0aW1lb3V0IiwiZGF0YUF0dHJpYnV0ZXMiLCJkYXRhQXR0cmlidXRlIiwiTkFNRSQzIiwiU0VMRUNUT1JfVElUTEUiLCJTRUxFQ1RPUl9DT05URU5UIiwiRGVmYXVsdCQyIiwiRGVmYXVsdFR5cGUkMiIsIlBvcG92ZXIiLCJfZ2V0Q29udGVudCIsIk5BTUUkMiIsIkRBVEFfS0VZJDIiLCJFVkVOVF9LRVkkMiIsIkRBVEFfQVBJX0tFWSIsIkVWRU5UX0FDVElWQVRFIiwiRVZFTlRfQ0xJQ0siLCJFVkVOVF9MT0FEX0RBVEFfQVBJJDEiLCJDTEFTU19OQU1FX0RST1BET1dOX0lURU0iLCJDTEFTU19OQU1FX0FDVElWRSQxIiwiU0VMRUNUT1JfREFUQV9TUFkiLCJTRUxFQ1RPUl9UQVJHRVRfTElOS1MiLCJTRUxFQ1RPUl9OQVZfTElTVF9HUk9VUCIsIlNFTEVDVE9SX05BVl9MSU5LUyIsIlNFTEVDVE9SX05BVl9JVEVNUyIsIlNFTEVDVE9SX0xJU1RfSVRFTVMiLCJTRUxFQ1RPUl9MSU5LX0lURU1TIiwiU0VMRUNUT1JfRFJPUERPV04iLCJTRUxFQ1RPUl9EUk9QRE9XTl9UT0dHTEUkMSIsIkRlZmF1bHQkMSIsInJvb3RNYXJnaW4iLCJzbW9vdGhTY3JvbGwiLCJ0aHJlc2hvbGQiLCJEZWZhdWx0VHlwZSQxIiwiU2Nyb2xsU3B5IiwiX3RhcmdldExpbmtzIiwiX29ic2VydmFibGVTZWN0aW9ucyIsIl9yb290RWxlbWVudCIsIl9hY3RpdmVUYXJnZXQiLCJfb2JzZXJ2ZXIiLCJfcHJldmlvdXNTY3JvbGxEYXRhIiwidmlzaWJsZUVudHJ5VG9wIiwicGFyZW50U2Nyb2xsVG9wIiwicmVmcmVzaCIsIl9pbml0aWFsaXplVGFyZ2V0c0FuZE9ic2VydmFibGVzIiwiX21heWJlRW5hYmxlU21vb3RoU2Nyb2xsIiwiZGlzY29ubmVjdCIsIl9nZXROZXdPYnNlcnZlciIsInNlY3Rpb24iLCJvYnNlcnZlIiwib2JzZXJ2YWJsZVNlY3Rpb24iLCJzY3JvbGxUbyIsImJlaGF2aW9yIiwiSW50ZXJzZWN0aW9uT2JzZXJ2ZXIiLCJfb2JzZXJ2ZXJDYWxsYmFjayIsInRhcmdldEVsZW1lbnQiLCJfcHJvY2VzcyIsInVzZXJTY3JvbGxzRG93biIsImlzSW50ZXJzZWN0aW5nIiwiX2NsZWFyQWN0aXZlQ2xhc3MiLCJlbnRyeUlzTG93ZXJUaGFuUHJldmlvdXMiLCJ0YXJnZXRMaW5rcyIsImFuY2hvciIsImRlY29kZVVSSSIsIl9hY3RpdmF0ZVBhcmVudHMiLCJsaXN0R3JvdXAiLCJhY3RpdmVOb2RlcyIsInNweSIsIk5BTUUkMSIsIkRBVEFfS0VZJDEiLCJFVkVOVF9LRVkkMSIsIkVWRU5UX0hJREUkMSIsIkVWRU5UX0hJRERFTiQxIiwiRVZFTlRfU0hPVyQxIiwiRVZFTlRfU0hPV04kMSIsIkVWRU5UX0NMSUNLX0RBVEFfQVBJIiwiRVZFTlRfS0VZRE9XTiIsIkVWRU5UX0xPQURfREFUQV9BUEkiLCJBUlJPV19MRUZUX0tFWSIsIkFSUk9XX1JJR0hUX0tFWSIsIkFSUk9XX1VQX0tFWSIsIkFSUk9XX0RPV05fS0VZIiwiSE9NRV9LRVkiLCJFTkRfS0VZIiwiQ0xBU1NfTkFNRV9BQ1RJVkUiLCJDTEFTU19OQU1FX0ZBREUkMSIsIkNMQVNTX05BTUVfU0hPVyQxIiwiQ0xBU1NfRFJPUERPV04iLCJTRUxFQ1RPUl9EUk9QRE9XTl9UT0dHTEUiLCJTRUxFQ1RPUl9EUk9QRE9XTl9NRU5VIiwiTk9UX1NFTEVDVE9SX0RST1BET1dOX1RPR0dMRSIsIlNFTEVDVE9SX1RBQl9QQU5FTCIsIlNFTEVDVE9SX09VVEVSIiwiU0VMRUNUT1JfSU5ORVIiLCJTRUxFQ1RPUl9EQVRBX1RPR0dMRSIsIlNFTEVDVE9SX0lOTkVSX0VMRU0iLCJTRUxFQ1RPUl9EQVRBX1RPR0dMRV9BQ1RJVkUiLCJUYWIiLCJfc2V0SW5pdGlhbEF0dHJpYnV0ZXMiLCJfZ2V0Q2hpbGRyZW4iLCJpbm5lckVsZW0iLCJfZWxlbUlzQWN0aXZlIiwiYWN0aXZlIiwiX2dldEFjdGl2ZUVsZW0iLCJfZGVhY3RpdmF0ZSIsIl9hY3RpdmF0ZSIsInJlbGF0ZWRFbGVtIiwiX3RvZ2dsZURyb3BEb3duIiwibmV4dEFjdGl2ZUVsZW1lbnQiLCJwcmV2ZW50U2Nyb2xsIiwiX3NldEF0dHJpYnV0ZUlmTm90RXhpc3RzIiwiX3NldEluaXRpYWxBdHRyaWJ1dGVzT25DaGlsZCIsIl9nZXRJbm5lckVsZW1lbnQiLCJpc0FjdGl2ZSIsIm91dGVyRWxlbSIsIl9nZXRPdXRlckVsZW1lbnQiLCJfc2V0SW5pdGlhbEF0dHJpYnV0ZXNPblRhcmdldFBhbmVsIiwib3BlbiIsIkVWRU5UX01PVVNFT1ZFUiIsIkVWRU5UX01PVVNFT1VUIiwiRVZFTlRfRk9DVVNJTiIsIkVWRU5UX0ZPQ1VTT1VUIiwiRVZFTlRfSElERSIsIkVWRU5UX0hJRERFTiIsIkVWRU5UX1NIT1ciLCJFVkVOVF9TSE9XTiIsIkNMQVNTX05BTUVfRkFERSIsIkNMQVNTX05BTUVfSElERSIsIkNMQVNTX05BTUVfU0hPVyIsIkNMQVNTX05BTUVfU0hPV0lORyIsImF1dG9oaWRlIiwiVG9hc3QiLCJfaGFzTW91c2VJbnRlcmFjdGlvbiIsIl9oYXNLZXlib2FyZEludGVyYWN0aW9uIiwiX2NsZWFyVGltZW91dCIsIl9tYXliZVNjaGVkdWxlSGlkZSIsImlzU2hvd24iLCJfb25JbnRlcmFjdGlvbiIsImlzSW50ZXJhY3RpbmciLCJpbmRleF91bWQiXSwibWFwcGluZ3MiOiI7QUFBQTtBQUNBOzs7O0FDREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtB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c0Qsb0JBQW9CLENBQUNnbEMsS0FBSyxDQUFDOztFQUUzQjs7OztFQUlBOXdDLGtCQUFrQixDQUFDOHdDLEtBQUssQ0FBQzs7RUM5TnpCOzs7Ozs7O0VBb0JBLE1BQUFRLFNBQUEsR0FBZTtJQUNiNWtDLEtBQUs7SUFDTGEsTUFBTTtJQUNOaUYsUUFBUTtJQUNSeUUsUUFBUTtJQUNScWUsUUFBUTtJQUNScUgsS0FBSztJQUNMNEMsU0FBUztJQUNUNkosT0FBTztJQUNQeUIsU0FBUztJQUNUK0QsR0FBRztJQUNIa0MsS0FBSztJQUNMdEs7RUFDRixDQUFDIiwiZmlsZSI6ImJ1bmRsZV9vdXRwdXRfRGV2X0J1bmRsZS5qcyIsInNvdXJjZXNDb250ZW50IjpbIndpbmRvdy5yc3hhcHAgPSB3aW5kb3cucnN4YXBwIHx8IHt9O1xud2luZG93LnJzeGFwcC5tb2R1bGVfcGF0aHMgPSB7XCJib290c3RyYXA1X3NyY1wiOlwicnN4XFwvdGhlbWVcXC92ZW5kb3JcXC9ib290c3RyYXA1XFwvc2Nzc1wifTtcbiIsIigoKSA9PiB7XG4gIC8vIG5vZGVfbW9kdWxlcy9AanFodG1sL2NvcmUvZGlzdC9pbmRleC5qc1xuICB2YXIgTGlmZWN5Y2xlTWFuYWdlciA9IGNsYXNzIF9MaWZlY3ljbGVNYW5hZ2VyIHtcbiAgICBzdGF0aWMgZ2V0X2luc3RhbmNlKCkge1xuICAgICAgaWYgKCFfTGlmZWN5Y2xlTWFuYWdlci5pbnN0YW5jZSkge1xuICAgICAgICBfTGlmZWN5Y2xlTWFuYWdlci5pbnN0YW5jZSA9IG5ldyBfTGlmZWN5Y2xlTWFuYWdlcigpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIF9MaWZlY3ljbGVNYW5hZ2VyLmluc3RhbmNlO1xuICAgIH1cbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgIHRoaXMuYWN0aXZlX2NvbXBvbmVudHMgPSAvKiBAX19QVVJFX18gKi8gbmV3IFNldCgpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBCb290IGEgY29tcG9uZW50IC0gcnVuIGl0cyBmdWxsIGxpZmVjeWNsZVxuICAgICAqIENhbGxlZCB3aGVuIGNvbXBvbmVudCBpcyBjcmVhdGVkXG4gICAgICovXG4gICAgYXN5bmMgYm9vdF9jb21wb25lbnQoY29tcG9uZW50KSB7XG4gICAgICB0aGlzLmFjdGl2ZV9jb21wb25lbnRzLmFkZChjb21wb25lbnQpO1xuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgY29tcG9uZW50LmNyZWF0ZSgpO1xuICAgICAgICBpZiAoY29tcG9uZW50Ll9zdG9wcGVkKVxuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgY29tcG9uZW50LnRyaWdnZXIoXCJjcmVhdGVcIik7XG4gICAgICAgIGxldCByZW5kZXJfaWQgPSBjb21wb25lbnQuX3JlbmRlcigpO1xuICAgICAgICBpZiAoY29tcG9uZW50Ll9zdG9wcGVkKVxuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgYXdhaXQgY29tcG9uZW50LmxvYWQoKTtcbiAgICAgICAgaWYgKGNvbXBvbmVudC5fc3RvcHBlZClcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIGlmIChjb21wb25lbnQuc2hvdWxkX3JlcmVuZGVyKCkpIHtcbiAgICAgICAgICByZW5kZXJfaWQgPSBjb21wb25lbnQuX3JlbmRlcigpO1xuICAgICAgICAgIGlmIChjb21wb25lbnQuX3N0b3BwZWQpXG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGNvbXBvbmVudC5fcmVuZGVyX2NvdW50ICE9PSByZW5kZXJfaWQpIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgYXdhaXQgY29tcG9uZW50LnJlYWR5KCk7XG4gICAgICAgIGlmIChjb21wb25lbnQuX3N0b3BwZWQpXG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICBhd2FpdCBjb21wb25lbnQudHJpZ2dlcihcInJlYWR5XCIpO1xuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgY29uc29sZS5lcnJvcihgRXJyb3IgYm9vdGluZyBjb21wb25lbnQgJHtjb21wb25lbnQuY29tcG9uZW50X25hbWUoKX06YCwgZXJyb3IpO1xuICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogVW5yZWdpc3RlciBhIGNvbXBvbmVudCAoY2FsbGVkIG9uIGRlc3Ryb3kpXG4gICAgICovXG4gICAgdW5yZWdpc3Rlcl9jb21wb25lbnQoY29tcG9uZW50KSB7XG4gICAgICB0aGlzLmFjdGl2ZV9jb21wb25lbnRzLmRlbGV0ZShjb21wb25lbnQpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBXYWl0IGZvciBhbGwgYWN0aXZlIGNvbXBvbmVudHMgdG8gcmVhY2ggcmVhZHkgc3RhdGVcbiAgICAgKi9cbiAgICBhc3luYyB3YWl0X2Zvcl9yZWFkeSgpIHtcbiAgICAgIGNvbnN0IHJlYWR5X3Byb21pc2VzID0gW107XG4gICAgICBmb3IgKGNvbnN0IGNvbXBvbmVudCBvZiB0aGlzLmFjdGl2ZV9jb21wb25lbnRzKSB7XG4gICAgICAgIGlmIChjb21wb25lbnQuX3JlYWR5X3N0YXRlIDwgNCkge1xuICAgICAgICAgIHJlYWR5X3Byb21pc2VzLnB1c2gobmV3IFByb21pc2UoKHJlc29sdmUpID0+IHtcbiAgICAgICAgICAgIGNvbXBvbmVudC5vbihcInJlYWR5XCIsICgpID0+IHJlc29sdmUoKSk7XG4gICAgICAgICAgfSkpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBhd2FpdCBQcm9taXNlLmFsbChyZWFkeV9wcm9taXNlcyk7XG4gICAgfVxuICB9O1xuICB2YXIgY29tcG9uZW50X2NsYXNzZXMgPSAvKiBAX19QVVJFX18gKi8gbmV3IE1hcCgpO1xuICB2YXIgY29tcG9uZW50X3RlbXBsYXRlcyA9IC8qIEBfX1BVUkVfXyAqLyBuZXcgTWFwKCk7XG4gIHZhciB3YXJuZWRfY29tcG9uZW50cyA9IC8qIEBfX1BVUkVfXyAqLyBuZXcgU2V0KCk7XG4gIHZhciBERUZBVUxUX1RFTVBMQVRFID0ge1xuICAgIG5hbWU6IFwiSnFodG1sX0NvbXBvbmVudFwiLFxuICAgIC8vIERlZmF1bHQgbmFtZVxuICAgIHRhZzogXCJkaXZcIixcbiAgICByZW5kZXI6IGZ1bmN0aW9uKGRhdGEsIGFyZ3MsIGNvbnRlbnQpIHtcbiAgICAgIGNvbnN0IF9vdXRwdXQgPSBbXTtcbiAgICAgIGlmIChhcmdzLl9pbm5lcl9odG1sKSB7XG4gICAgICAgIF9vdXRwdXQucHVzaChhcmdzLl9pbm5lcl9odG1sKTtcbiAgICAgICAgcmV0dXJuIFtfb3V0cHV0LCB0aGlzXTtcbiAgICAgIH1cbiAgICAgIGlmIChjb250ZW50ICYmIHR5cGVvZiBjb250ZW50ID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gY29udGVudCh0aGlzKTtcbiAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkocmVzdWx0KSAmJiByZXN1bHQubGVuZ3RoID09PSAyKSB7XG4gICAgICAgICAgX291dHB1dC5wdXNoKC4uLnJlc3VsdFswXSk7XG4gICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIHJlc3VsdCA9PT0gXCJzdHJpbmdcIikge1xuICAgICAgICAgIF9vdXRwdXQucHVzaChyZXN1bHQpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gW19vdXRwdXQsIHRoaXNdO1xuICAgIH1cbiAgfTtcbiAgZnVuY3Rpb24gcmVnaXN0ZXJfY29tcG9uZW50KG5hbWVPckNsYXNzLCBjb21wb25lbnRfY2xhc3MsIHRlbXBsYXRlKSB7XG4gICAgaWYgKHR5cGVvZiBuYW1lT3JDbGFzcyA9PT0gXCJzdHJpbmdcIikge1xuICAgICAgY29uc3QgbmFtZSA9IG5hbWVPckNsYXNzO1xuICAgICAgaWYgKCFjb21wb25lbnRfY2xhc3MpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQ29tcG9uZW50IGNsYXNzIGlzIHJlcXVpcmVkIHdoZW4gcmVnaXN0ZXJpbmcgYnkgbmFtZVwiKTtcbiAgICAgIH1cbiAgICAgIGlmICghL15bQS1aXS8udGVzdChuYW1lKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYENvbXBvbmVudCBuYW1lICcke25hbWV9JyBtdXN0IHN0YXJ0IHdpdGggYSBjYXBpdGFsIGxldHRlci4gQ29udmVudGlvbiBpcyBGaXJzdF9MZXR0ZXJfV2l0aF9VbmRlcnNjb3Jlcy5gKTtcbiAgICAgIH1cbiAgICAgIGNvbXBvbmVudF9jbGFzc2VzLnNldChuYW1lLCBjb21wb25lbnRfY2xhc3MpO1xuICAgICAgaWYgKHRlbXBsYXRlKSB7XG4gICAgICAgIGlmICh0ZW1wbGF0ZS5uYW1lICE9PSBuYW1lKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBUZW1wbGF0ZSBuYW1lICcke3RlbXBsYXRlLm5hbWV9JyBtdXN0IG1hdGNoIGNvbXBvbmVudCBuYW1lICcke25hbWV9J2ApO1xuICAgICAgICB9XG4gICAgICAgIHJlZ2lzdGVyX3RlbXBsYXRlKHRlbXBsYXRlKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3QgY29tcG9uZW50X2NsYXNzMiA9IG5hbWVPckNsYXNzO1xuICAgICAgY29uc3QgbmFtZSA9IGNvbXBvbmVudF9jbGFzczIubmFtZTtcbiAgICAgIGlmICghbmFtZSB8fCBuYW1lID09PSBcIkpxaHRtbF9Db21wb25lbnRcIikge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJDb21wb25lbnQgY2xhc3MgbXVzdCBoYXZlIGEgbmFtZSB3aGVuIHJlZ2lzdGVyaW5nIHdpdGhvdXQgZXhwbGljaXQgbmFtZVwiKTtcbiAgICAgIH1cbiAgICAgIGNvbXBvbmVudF9jbGFzc2VzLnNldChuYW1lLCBjb21wb25lbnRfY2xhc3MyKTtcbiAgICB9XG4gIH1cbiAgZnVuY3Rpb24gZ2V0X2NvbXBvbmVudF9jbGFzcyhuYW1lKSB7XG4gICAgY29uc3QgZGlyZWN0Q2xhc3MgPSBjb21wb25lbnRfY2xhc3Nlcy5nZXQobmFtZSk7XG4gICAgaWYgKGRpcmVjdENsYXNzKSB7XG4gICAgICByZXR1cm4gZGlyZWN0Q2xhc3M7XG4gICAgfVxuICAgIGNvbnN0IHRlbXBsYXRlID0gY29tcG9uZW50X3RlbXBsYXRlcy5nZXQobmFtZSk7XG4gICAgaWYgKHRlbXBsYXRlICYmIHRlbXBsYXRlLmV4dGVuZHMpIHtcbiAgICAgIGNvbnN0IHZpc2l0ZWQgPSAvKiBAX19QVVJFX18gKi8gbmV3IFNldChbbmFtZV0pO1xuICAgICAgbGV0IGN1cnJlbnRUZW1wbGF0ZU5hbWUgPSB0ZW1wbGF0ZS5leHRlbmRzO1xuICAgICAgd2hpbGUgKGN1cnJlbnRUZW1wbGF0ZU5hbWUgJiYgIXZpc2l0ZWQuaGFzKGN1cnJlbnRUZW1wbGF0ZU5hbWUpKSB7XG4gICAgICAgIHZpc2l0ZWQuYWRkKGN1cnJlbnRUZW1wbGF0ZU5hbWUpO1xuICAgICAgICBjb25zdCBwYXJlbnRDbGFzcyA9IGNvbXBvbmVudF9jbGFzc2VzLmdldChjdXJyZW50VGVtcGxhdGVOYW1lKTtcbiAgICAgICAgaWYgKHBhcmVudENsYXNzKSB7XG4gICAgICAgICAgaWYgKHdpbmRvdy5qcWh0bWw/LmRlYnVnPy5lbmFibGVkKSB7XG4gICAgICAgICAgICBjb25zb2xlLmxvZyhgW0pRSFRNTF0gQ29tcG9uZW50ICcke25hbWV9JyB1c2luZyBjbGFzcyBmcm9tIHBhcmVudCAnJHtjdXJyZW50VGVtcGxhdGVOYW1lfScgdmlhIGV4dGVuZHMgY2hhaW5gKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIHBhcmVudENsYXNzO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHBhcmVudFRlbXBsYXRlID0gY29tcG9uZW50X3RlbXBsYXRlcy5nZXQoY3VycmVudFRlbXBsYXRlTmFtZSk7XG4gICAgICAgIGlmIChwYXJlbnRUZW1wbGF0ZSAmJiBwYXJlbnRUZW1wbGF0ZS5leHRlbmRzKSB7XG4gICAgICAgICAgY3VycmVudFRlbXBsYXRlTmFtZSA9IHBhcmVudFRlbXBsYXRlLmV4dGVuZHM7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHZvaWQgMDtcbiAgfVxuICBmdW5jdGlvbiByZWdpc3Rlcl90ZW1wbGF0ZSh0ZW1wbGF0ZV9kZWYpIHtcbiAgICBjb25zdCBuYW1lID0gdGVtcGxhdGVfZGVmLm5hbWU7XG4gICAgaWYgKCFuYW1lKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJUZW1wbGF0ZSBtdXN0IGhhdmUgYSBuYW1lIHByb3BlcnR5XCIpO1xuICAgIH1cbiAgICBpZiAoIS9eW0EtWl0vLnRlc3QobmFtZSkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgVGVtcGxhdGUgbmFtZSAnJHtuYW1lfScgbXVzdCBzdGFydCB3aXRoIGEgY2FwaXRhbCBsZXR0ZXIuIENvbnZlbnRpb24gaXMgRmlyc3RfTGV0dGVyX1dpdGhfVW5kZXJzY29yZXMuYCk7XG4gICAgfVxuICAgIGlmIChjb21wb25lbnRfdGVtcGxhdGVzLmhhcyhuYW1lKSkge1xuICAgICAgY29uc29sZS53YXJuKGBbSlFIVE1MXSBUZW1wbGF0ZSAnJHtuYW1lfScgYWxyZWFkeSByZWdpc3RlcmVkLCBza2lwcGluZyBkdXBsaWNhdGUgcmVnaXN0cmF0aW9uYCk7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGNvbXBvbmVudF90ZW1wbGF0ZXMuc2V0KG5hbWUsIHRlbXBsYXRlX2RlZik7XG4gICAgaWYgKHdpbmRvdy5qcWh0bWw/LmRlYnVnPy5lbmFibGVkKSB7XG4gICAgICBjb25zb2xlLmxvZyhgW0pRSFRNTF0gU3VjY2Vzc2Z1bGx5IHJlZ2lzdGVyZWQgdGVtcGxhdGU6ICR7bmFtZX1gKTtcbiAgICB9XG4gICAgY29uc3QgY29tcG9uZW50X2NsYXNzID0gY29tcG9uZW50X2NsYXNzZXMuZ2V0KG5hbWUpO1xuICAgIGlmIChjb21wb25lbnRfY2xhc3MpIHtcbiAgICAgIGNvbXBvbmVudF9jbGFzcy5fanFodG1sX21ldGFkYXRhID0ge1xuICAgICAgICB0YWc6IHRlbXBsYXRlX2RlZi50YWcsXG4gICAgICAgIGRlZmF1bHRBdHRyaWJ1dGVzOiB0ZW1wbGF0ZV9kZWYuZGVmYXVsdEF0dHJpYnV0ZXMgfHwge31cbiAgICAgIH07XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xuICB9XG4gIGZ1bmN0aW9uIGdldF90ZW1wbGF0ZShuYW1lKSB7XG4gICAgY29uc3QgdGVtcGxhdGUgPSBjb21wb25lbnRfdGVtcGxhdGVzLmdldChuYW1lKTtcbiAgICBpZiAoIXRlbXBsYXRlKSB7XG4gICAgICBjb25zdCBjb21wb25lbnRfY2xhc3MgPSBjb21wb25lbnRfY2xhc3Nlcy5nZXQobmFtZSk7XG4gICAgICBpZiAoY29tcG9uZW50X2NsYXNzKSB7XG4gICAgICAgIGNvbnN0IGluaGVyaXRlZF90ZW1wbGF0ZSA9IGdldF90ZW1wbGF0ZV9ieV9jbGFzcyhjb21wb25lbnRfY2xhc3MpO1xuICAgICAgICBpZiAoaW5oZXJpdGVkX3RlbXBsYXRlICE9PSBERUZBVUxUX1RFTVBMQVRFKSB7XG4gICAgICAgICAgaWYgKHdpbmRvdy5qcWh0bWw/LmRlYnVnPy5lbmFibGVkKSB7XG4gICAgICAgICAgICBjb25zb2xlLmxvZyhgW0pRSFRNTF0gQ29tcG9uZW50ICcke25hbWV9JyBoYXMgbm8gdGVtcGxhdGUsIHVzaW5nIHRlbXBsYXRlIGZyb20gcHJvdG90eXBlIGNoYWluYCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiBpbmhlcml0ZWRfdGVtcGxhdGU7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHdpbmRvdy5qcWh0bWw/LmRlYnVnPy5lbmFibGVkICYmICF3YXJuZWRfY29tcG9uZW50cy5oYXMobmFtZSkpIHtcbiAgICAgICAgICB3YXJuZWRfY29tcG9uZW50cy5hZGQobmFtZSk7XG4gICAgICAgICAgY29uc29sZS5sb2coYFtKUUhUTUxdIE5vIHRlbXBsYXRlIGZvdW5kIGZvciBjbGFzczogJHtuYW1lfSwgdXNpbmcgZGVmYXVsdCBkaXYgdGVtcGxhdGVgKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKG5hbWUgIT09IFwiX0pxaHRtbF9Db21wb25lbnRcIiAmJiBuYW1lICE9PSBcIlJlZHJhd2FibGVcIiAmJiAhd2FybmVkX2NvbXBvbmVudHMuaGFzKG5hbWUpKSB7XG4gICAgICAgICAgd2FybmVkX2NvbXBvbmVudHMuYWRkKG5hbWUpO1xuICAgICAgICAgIGNvbnNvbGUud2FybihgW0pRSFRNTF0gQ3JlYXRpbmcgJHtuYW1lfSB3aXRoIGRlZmF1bHRzIC0gbm8gdGVtcGxhdGUgb3IgY2xhc3MgZGVmaW5lZGApO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAod2luZG93LmpxaHRtbD8uZGVidWc/LnZlcmJvc2UpIHtcbiAgICAgICAgY29uc3QgcmVnaXN0ZXJlZCA9IEFycmF5LmZyb20oY29tcG9uZW50X3RlbXBsYXRlcy5rZXlzKCkpO1xuICAgICAgICBjb25zb2xlLmxvZyhgW0pRSFRNTF0gTG9va2luZyBmb3IgdGVtcGxhdGUgJyR7bmFtZX0nIGluOiBbJHtyZWdpc3RlcmVkLmpvaW4oXCIsIFwiKX1dYCk7XG4gICAgICB9XG4gICAgICByZXR1cm4gREVGQVVMVF9URU1QTEFURTtcbiAgICB9XG4gICAgcmV0dXJuIHRlbXBsYXRlO1xuICB9XG4gIGZ1bmN0aW9uIGdldF90ZW1wbGF0ZV9ieV9jbGFzcyhjb21wb25lbnRfY2xhc3MpIHtcbiAgICBpZiAoY29tcG9uZW50X2NsYXNzLnRlbXBsYXRlKSB7XG4gICAgICByZXR1cm4gY29tcG9uZW50X2NsYXNzLnRlbXBsYXRlO1xuICAgIH1cbiAgICBsZXQgY3VycmVudENsYXNzID0gY29tcG9uZW50X2NsYXNzO1xuICAgIHdoaWxlIChjdXJyZW50Q2xhc3MgJiYgY3VycmVudENsYXNzLm5hbWUgIT09IFwiT2JqZWN0XCIpIHtcbiAgICAgIGxldCBub3JtYWxpemVkTmFtZSA9IGN1cnJlbnRDbGFzcy5uYW1lO1xuICAgICAgaWYgKG5vcm1hbGl6ZWROYW1lID09PSBcIl9KcWh0bWxfQ29tcG9uZW50XCIgfHwgbm9ybWFsaXplZE5hbWUgPT09IFwiX0Jhc2VfSnFodG1sX0NvbXBvbmVudFwiKSB7XG4gICAgICAgIG5vcm1hbGl6ZWROYW1lID0gXCJKcWh0bWxfQ29tcG9uZW50XCI7XG4gICAgICB9XG4gICAgICBjb25zdCB0ZW1wbGF0ZSA9IGNvbXBvbmVudF90ZW1wbGF0ZXMuZ2V0KG5vcm1hbGl6ZWROYW1lKTtcbiAgICAgIGlmICh0ZW1wbGF0ZSkge1xuICAgICAgICByZXR1cm4gdGVtcGxhdGU7XG4gICAgICB9XG4gICAgICBjdXJyZW50Q2xhc3MgPSBPYmplY3QuZ2V0UHJvdG90eXBlT2YoY3VycmVudENsYXNzKTtcbiAgICB9XG4gICAgcmV0dXJuIERFRkFVTFRfVEVNUExBVEU7XG4gIH1cbiAgZnVuY3Rpb24gY3JlYXRlX2NvbXBvbmVudChuYW1lLCBlbGVtZW50LCBhcmdzID0ge30pIHtcbiAgICBjb25zdCBDb21wb25lbnRDbGFzcyA9IGdldF9jb21wb25lbnRfY2xhc3MobmFtZSkgfHwgSnFodG1sX0NvbXBvbmVudDtcbiAgICByZXR1cm4gbmV3IENvbXBvbmVudENsYXNzKGVsZW1lbnQsIGFyZ3MpO1xuICB9XG4gIGZ1bmN0aW9uIGhhc19jb21wb25lbnQobmFtZSkge1xuICAgIHJldHVybiBjb21wb25lbnRfY2xhc3Nlcy5oYXMobmFtZSk7XG4gIH1cbiAgZnVuY3Rpb24gZ2V0X2NvbXBvbmVudF9uYW1lcygpIHtcbiAgICByZXR1cm4gQXJyYXkuZnJvbShjb21wb25lbnRfY2xhc3Nlcy5rZXlzKCkpO1xuICB9XG4gIGZ1bmN0aW9uIGdldF9yZWdpc3RlcmVkX3RlbXBsYXRlcygpIHtcbiAgICByZXR1cm4gQXJyYXkuZnJvbShjb21wb25lbnRfdGVtcGxhdGVzLmtleXMoKSk7XG4gIH1cbiAgZnVuY3Rpb24gbGlzdF9jb21wb25lbnRzKCkge1xuICAgIGNvbnN0IHJlc3VsdCA9IHt9O1xuICAgIGZvciAoY29uc3QgbmFtZSBvZiBjb21wb25lbnRfY2xhc3Nlcy5rZXlzKCkpIHtcbiAgICAgIHJlc3VsdFtuYW1lXSA9IHtcbiAgICAgICAgaGFzX2NsYXNzOiB0cnVlLFxuICAgICAgICBoYXNfdGVtcGxhdGU6IGNvbXBvbmVudF90ZW1wbGF0ZXMuaGFzKG5hbWUpXG4gICAgICB9O1xuICAgIH1cbiAgICBmb3IgKGNvbnN0IG5hbWUgb2YgY29tcG9uZW50X3RlbXBsYXRlcy5rZXlzKCkpIHtcbiAgICAgIGlmICghcmVzdWx0W25hbWVdKSB7XG4gICAgICAgIHJlc3VsdFtuYW1lXSA9IHtcbiAgICAgICAgICBoYXNfY2xhc3M6IGZhbHNlLFxuICAgICAgICAgIGhhc190ZW1wbGF0ZTogdHJ1ZVxuICAgICAgICB9O1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG4gIHZhciBfY2lkX2luY3JlbWVudCA9IFwiYWFcIjtcbiAgZnVuY3Rpb24gdWlkKCkge1xuICAgIGNvbnN0IGN1cnJlbnQgPSBfY2lkX2luY3JlbWVudDtcbiAgICBjb25zdCBjaGFycyA9IF9jaWRfaW5jcmVtZW50LnNwbGl0KFwiXCIpO1xuICAgIGxldCBjYXJyeSA9IHRydWU7XG4gICAgZm9yIChsZXQgaSA9IGNoYXJzLmxlbmd0aCAtIDE7IGkgPj0gMCAmJiBjYXJyeTsgaS0tKSB7XG4gICAgICBjb25zdCBjaGFyID0gY2hhcnNbaV07XG4gICAgICBpZiAoY2hhciA+PSBcImFcIiAmJiBjaGFyIDwgXCJ6XCIpIHtcbiAgICAgICAgY2hhcnNbaV0gPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGNoYXIuY2hhckNvZGVBdCgwKSArIDEpO1xuICAgICAgICBjYXJyeSA9IGZhbHNlO1xuICAgICAgfSBlbHNlIGlmIChjaGFyID09PSBcInpcIikge1xuICAgICAgICBjaGFyc1tpXSA9IFwiMFwiO1xuICAgICAgICBjYXJyeSA9IGZhbHNlO1xuICAgICAgfSBlbHNlIGlmIChjaGFyID49IFwiMFwiICYmIGNoYXIgPCBcIjlcIikge1xuICAgICAgICBjaGFyc1tpXSA9IFN0cmluZy5mcm9tQ2hhckNvZGUoY2hhci5jaGFyQ29kZUF0KDApICsgMSk7XG4gICAgICAgIGNhcnJ5ID0gZmFsc2U7XG4gICAgICB9IGVsc2UgaWYgKGNoYXIgPT09IFwiOVwiKSB7XG4gICAgICAgIGNoYXJzW2ldID0gXCJhXCI7XG4gICAgICAgIGNhcnJ5ID0gdHJ1ZTtcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKGNhcnJ5KSB7XG4gICAgICBjaGFycy51bnNoaWZ0KFwiYVwiKTtcbiAgICB9XG4gICAgaWYgKGNoYXJzWzBdID49IFwiMFwiICYmIGNoYXJzWzBdIDw9IFwiOVwiKSB7XG4gICAgICBjaGFyc1swXSA9IFwiYVwiO1xuICAgICAgY2hhcnMudW5zaGlmdChcImFcIik7XG4gICAgfVxuICAgIF9jaWRfaW5jcmVtZW50ID0gY2hhcnMuam9pbihcIlwiKTtcbiAgICByZXR1cm4gY3VycmVudDtcbiAgfVxuICBmdW5jdGlvbiBwcm9jZXNzX2luc3RydWN0aW9ucyhpbnN0cnVjdGlvbnMsIHRhcmdldCwgY29udGV4dCwgc2xvdHMpIHtcbiAgICBjb25zdCBodG1sID0gW107XG4gICAgY29uc3QgdGFnRWxlbWVudHMgPSB7fTtcbiAgICBjb25zdCBjb21wb25lbnRzID0ge307XG4gICAgZm9yIChjb25zdCBpbnN0cnVjdGlvbiBvZiBpbnN0cnVjdGlvbnMpIHtcbiAgICAgIHByb2Nlc3NfaW5zdHJ1Y3Rpb25fdG9faHRtbChpbnN0cnVjdGlvbiwgaHRtbCwgdGFnRWxlbWVudHMsIGNvbXBvbmVudHMsIGNvbnRleHQsIHNsb3RzKTtcbiAgICB9XG4gICAgdGFyZ2V0WzBdLmlubmVySFRNTCA9IGh0bWwuam9pbihcIlwiKTtcbiAgICBmb3IgKGNvbnN0IFt0aWQsIHRhZ0RhdGFdIG9mIE9iamVjdC5lbnRyaWVzKHRhZ0VsZW1lbnRzKSkge1xuICAgICAgY29uc3QgZWwgPSB0YXJnZXRbMF0ucXVlcnlTZWxlY3RvcihgW2RhdGEtdGlkPVwiJHt0aWR9XCJdYCk7XG4gICAgICBpZiAoZWwpIHtcbiAgICAgICAgY29uc3QgZWxlbWVudCA9ICQoZWwpO1xuICAgICAgICBlbC5yZW1vdmVBdHRyaWJ1dGUoXCJkYXRhLXRpZFwiKTtcbiAgICAgICAgYXBwbHlfYXR0cmlidXRlcyhlbGVtZW50LCB0YWdEYXRhLmF0dHJzLCBjb250ZXh0KTtcbiAgICAgIH1cbiAgICB9XG4gICAgZm9yIChjb25zdCBbY2lkLCBjb21wRGF0YV0gb2YgT2JqZWN0LmVudHJpZXMoY29tcG9uZW50cykpIHtcbiAgICAgIGNvbnN0IGVsID0gdGFyZ2V0WzBdLnF1ZXJ5U2VsZWN0b3IoYFtkYXRhLWNpZD1cIiR7Y2lkfVwiXWApO1xuICAgICAgaWYgKGVsKSB7XG4gICAgICAgIGNvbnN0IGVsZW1lbnQgPSAkKGVsKTtcbiAgICAgICAgZWwucmVtb3ZlQXR0cmlidXRlKFwiZGF0YS1jaWRcIik7XG4gICAgICAgIGluaXRpYWxpemVfY29tcG9uZW50KGVsZW1lbnQsIGNvbXBEYXRhKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgZnVuY3Rpb24gcHJvY2Vzc19pbnN0cnVjdGlvbl90b19odG1sKGluc3RydWN0aW9uLCBodG1sLCB0YWdFbGVtZW50cywgY29tcG9uZW50cywgY29udGV4dCwgc2xvdHMpIHtcbiAgICBpZiAodHlwZW9mIGluc3RydWN0aW9uID09PSBcInN0cmluZ1wiKSB7XG4gICAgICBodG1sLnB1c2goaW5zdHJ1Y3Rpb24pO1xuICAgIH0gZWxzZSBpZiAoXCJ0YWdcIiBpbiBpbnN0cnVjdGlvbikge1xuICAgICAgcHJvY2Vzc190YWdfdG9faHRtbChpbnN0cnVjdGlvbiwgaHRtbCwgdGFnRWxlbWVudHMsIGNvbXBvbmVudHMsIGNvbnRleHQpO1xuICAgIH0gZWxzZSBpZiAoXCJjb21wXCIgaW4gaW5zdHJ1Y3Rpb24pIHtcbiAgICAgIHByb2Nlc3NfY29tcG9uZW50X3RvX2h0bWwoaW5zdHJ1Y3Rpb24sIGh0bWwsIGNvbXBvbmVudHMsIGNvbnRleHQpO1xuICAgIH0gZWxzZSBpZiAoXCJzbG90XCIgaW4gaW5zdHJ1Y3Rpb24pIHtcbiAgICAgIHByb2Nlc3Nfc2xvdF90b19odG1sKGluc3RydWN0aW9uLCBodG1sLCB0YWdFbGVtZW50cywgY29tcG9uZW50cywgY29udGV4dCwgc2xvdHMpO1xuICAgIH0gZWxzZSBpZiAoXCJyYXd0YWdcIiBpbiBpbnN0cnVjdGlvbikge1xuICAgICAgcHJvY2Vzc19yYXd0YWdfdG9faHRtbChpbnN0cnVjdGlvbiwgaHRtbCk7XG4gICAgfVxuICB9XG4gIGZ1bmN0aW9uIHByb2Nlc3NfdGFnX3RvX2h0bWwoaW5zdHJ1Y3Rpb24sIGh0bWwsIHRhZ0VsZW1lbnRzLCBjb21wb25lbnRzLCBjb250ZXh0KSB7XG4gICAgY29uc3QgW3RhZ05hbWUsIGF0dHJzLCBzZWxmQ2xvc2luZ10gPSBpbnN0cnVjdGlvbi50YWc7XG4gICAgY29uc3QgbmVlZHNUcmFja2luZyA9IE9iamVjdC5rZXlzKGF0dHJzKS5zb21lKChrZXkpID0+IGtleSA9PT0gXCIkaWRcIiB8fCBrZXkuc3RhcnRzV2l0aChcIiRcIikgfHwga2V5LnN0YXJ0c1dpdGgoXCJAXCIpIHx8IGtleS5zdGFydHNXaXRoKFwib25cIikgfHwga2V5LnN0YXJ0c1dpdGgoXCJkYXRhLWJpbmQtXCIpIHx8IGtleS5zdGFydHNXaXRoKFwiZGF0YS1vbi1cIikpO1xuICAgIGh0bWwucHVzaChgPCR7dGFnTmFtZX1gKTtcbiAgICBsZXQgdGlkID0gbnVsbDtcbiAgICBpZiAobmVlZHNUcmFja2luZykge1xuICAgICAgdGlkID0gdWlkKCk7XG4gICAgICBodG1sLnB1c2goYCBkYXRhLXRpZD1cIiR7dGlkfVwiYCk7XG4gICAgICB0YWdFbGVtZW50c1t0aWRdID0geyBhdHRycywgY29udGV4dCB9O1xuICAgIH1cbiAgICBmb3IgKGNvbnN0IFtrZXksIHZhbHVlXSBvZiBPYmplY3QuZW50cmllcyhhdHRycykpIHtcbiAgICAgIGlmICgha2V5LnN0YXJ0c1dpdGgoXCIkXCIpICYmICFrZXkuc3RhcnRzV2l0aChcIm9uXCIpICYmICFrZXkuc3RhcnRzV2l0aChcIkBcIikgJiYgIWtleS5zdGFydHNXaXRoKFwiZGF0YS1iaW5kLVwiKSAmJiAha2V5LnN0YXJ0c1dpdGgoXCJkYXRhLW9uLVwiKSAmJiAodHlwZW9mIHZhbHVlID09PSBcInN0cmluZ1wiIHx8IHR5cGVvZiB2YWx1ZSA9PT0gXCJudW1iZXJcIikpIHtcbiAgICAgICAgaWYgKGtleSA9PT0gXCJpZFwiICYmIHRpZCkge1xuICAgICAgICAgIGh0bWwucHVzaChgIGlkPVwiJHt2YWx1ZX06JHtjb250ZXh0Ll9jaWR9XCJgKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBodG1sLnB1c2goYCAke2tleX09XCIke3ZhbHVlfVwiYCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKHNlbGZDbG9zaW5nKSB7XG4gICAgICBodG1sLnB1c2goXCIgLz5cIik7XG4gICAgfSBlbHNlIHtcbiAgICAgIGh0bWwucHVzaChcIj5cIik7XG4gICAgfVxuICB9XG4gIGZ1bmN0aW9uIHByb2Nlc3NfY29tcG9uZW50X3RvX2h0bWwoaW5zdHJ1Y3Rpb24sIGh0bWwsIGNvbXBvbmVudHMsIGNvbnRleHQpIHtcbiAgICBjb25zdCBbY29tcG9uZW50TmFtZSwgcHJvcHMsIGNvbnRlbnRGbl0gPSBpbnN0cnVjdGlvbi5jb21wO1xuICAgIGNvbnN0IGNpZCA9IHVpZCgpO1xuICAgIGdldF9jb21wb25lbnRfY2xhc3MoY29tcG9uZW50TmFtZSkgfHwgSnFodG1sX0NvbXBvbmVudDtcbiAgICBjb25zdCB0ZW1wbGF0ZSA9IGdldF90ZW1wbGF0ZShjb21wb25lbnROYW1lKTtcbiAgICBjb25zdCB0YWdOYW1lID0gcHJvcHMuX3RhZyB8fCB0ZW1wbGF0ZS50YWcgfHwgXCJkaXZcIjtcbiAgICBodG1sLnB1c2goYDwke3RhZ05hbWV9IGRhdGEtY2lkPVwiJHtjaWR9XCJgKTtcbiAgICBpZiAocHJvcHNbXCJkYXRhLWlkXCJdKSB7XG4gICAgICBjb25zdCBiYXNlSWQgPSBwcm9wc1tcImRhdGEtaWRcIl07XG4gICAgICBodG1sLnB1c2goYCBpZD1cIiR7cHJvcHNbXCJpZFwiXX1cIiBkYXRhLWlkPVwiJHtiYXNlSWR9XCJgKTtcbiAgICB9IGVsc2UgaWYgKHByb3BzW1wiaWRcIl0pIHtcbiAgICAgIGh0bWwucHVzaChgIGlkPVwiJHtwcm9wc1tcImlkXCJdfVwiYCk7XG4gICAgfVxuICAgIGh0bWwucHVzaChcIj48L1wiICsgdGFnTmFtZSArIFwiPlwiKTtcbiAgICBjb21wb25lbnRzW2NpZF0gPSB7XG4gICAgICBuYW1lOiBjb21wb25lbnROYW1lLFxuICAgICAgcHJvcHMsXG4gICAgICBjb250ZW50Rm4sXG4gICAgICBjb250ZXh0XG4gICAgfTtcbiAgfVxuICBmdW5jdGlvbiBwcm9jZXNzX3Nsb3RfdG9faHRtbChpbnN0cnVjdGlvbiwgaHRtbCwgdGFnRWxlbWVudHMsIGNvbXBvbmVudHMsIGNvbnRleHQsIHBhcmVudFNsb3RzKSB7XG4gICAgY29uc3QgW3Nsb3ROYW1lXSA9IGluc3RydWN0aW9uLnNsb3Q7XG4gICAgaWYgKHBhcmVudFNsb3RzICYmIHNsb3ROYW1lIGluIHBhcmVudFNsb3RzKSB7XG4gICAgICBjb25zdCBwYXJlbnRTbG90ID0gcGFyZW50U2xvdHNbc2xvdE5hbWVdO1xuICAgICAgY29uc3QgWywgc2xvdFByb3BzLCBjb250ZW50Rm5dID0gcGFyZW50U2xvdC5zbG90O1xuICAgICAgY29uc3QgW2NvbnRlbnRdID0gY29udGVudEZuLmNhbGwoY29udGV4dCwgc2xvdFByb3BzKTtcbiAgICAgIGZvciAoY29uc3QgaXRlbSBvZiBjb250ZW50KSB7XG4gICAgICAgIHByb2Nlc3NfaW5zdHJ1Y3Rpb25fdG9faHRtbChpdGVtLCBodG1sLCB0YWdFbGVtZW50cywgY29tcG9uZW50cywgY29udGV4dCk7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChzbG90TmFtZSA9PT0gXCJkZWZhdWx0XCIgJiYgaW5zdHJ1Y3Rpb24uc2xvdFsyXSkge1xuICAgICAgY29uc3QgWywgLCBkZWZhdWx0Rm5dID0gaW5zdHJ1Y3Rpb24uc2xvdDtcbiAgICAgIGNvbnN0IFtjb250ZW50XSA9IGRlZmF1bHRGbi5jYWxsKGNvbnRleHQsIHt9KTtcbiAgICAgIGZvciAoY29uc3QgaXRlbSBvZiBjb250ZW50KSB7XG4gICAgICAgIHByb2Nlc3NfaW5zdHJ1Y3Rpb25fdG9faHRtbChpdGVtLCBodG1sLCB0YWdFbGVtZW50cywgY29tcG9uZW50cywgY29udGV4dCk7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIGZ1bmN0aW9uIHByb2Nlc3NfcmF3dGFnX3RvX2h0bWwoaW5zdHJ1Y3Rpb24sIGh0bWwpIHtcbiAgICBjb25zdCBbdGFnTmFtZSwgYXR0cnMsIHJhd0NvbnRlbnRdID0gaW5zdHJ1Y3Rpb24ucmF3dGFnO1xuICAgIGh0bWwucHVzaChgPCR7dGFnTmFtZX1gKTtcbiAgICBmb3IgKGNvbnN0IFtrZXksIHZhbHVlXSBvZiBPYmplY3QuZW50cmllcyhhdHRycykpIHtcbiAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT09IFwic3RyaW5nXCIgfHwgdHlwZW9mIHZhbHVlID09PSBcIm51bWJlclwiKSB7XG4gICAgICAgIGNvbnN0IGVzY2FwZWRfdmFsdWUgPSBTdHJpbmcodmFsdWUpLnJlcGxhY2UoL1wiL2csIFwiJnF1b3Q7XCIpO1xuICAgICAgICBodG1sLnB1c2goYCAke2tleX09XCIke2VzY2FwZWRfdmFsdWV9XCJgKTtcbiAgICAgIH0gZWxzZSBpZiAodHlwZW9mIHZhbHVlID09PSBcImJvb2xlYW5cIiAmJiB2YWx1ZSkge1xuICAgICAgICBodG1sLnB1c2goYCAke2tleX1gKTtcbiAgICAgIH1cbiAgICB9XG4gICAgaHRtbC5wdXNoKFwiPlwiKTtcbiAgICBjb25zdCBlc2NhcGVkX2NvbnRlbnQgPSByYXdDb250ZW50LnJlcGxhY2UoLyYvZywgXCImYW1wO1wiKS5yZXBsYWNlKC88L2csIFwiJmx0O1wiKS5yZXBsYWNlKC8+L2csIFwiJmd0O1wiKTtcbiAgICBodG1sLnB1c2goZXNjYXBlZF9jb250ZW50KTtcbiAgICBodG1sLnB1c2goYDwvJHt0YWdOYW1lfT5gKTtcbiAgfVxuICBmdW5jdGlvbiBhcHBseV9hdHRyaWJ1dGVzKGVsZW1lbnQsIGF0dHJzLCBjb250ZXh0KSB7XG4gICAgZm9yIChjb25zdCBba2V5LCB2YWx1ZV0gb2YgT2JqZWN0LmVudHJpZXMoYXR0cnMpKSB7XG4gICAgICBpZiAoa2V5ID09PSBcIiRpZFwiIHx8IGtleSA9PT0gXCJpZFwiKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfSBlbHNlIGlmIChrZXkuc3RhcnRzV2l0aChcIiRcIikpIHtcbiAgICAgICAgY29uc3QgZGF0YUtleSA9IGtleS5zdWJzdHJpbmcoMSk7XG4gICAgICAgIGVsZW1lbnQuZGF0YShkYXRhS2V5LCB2YWx1ZSk7XG4gICAgICAgIGNvbnRleHQuYXJnc1tkYXRhS2V5XSA9IHZhbHVlO1xuICAgICAgICBpZiAodHlwZW9mIHZhbHVlID09IFwic3RyaW5nXCIgfHwgdHlwZW9mIHZhbHVlID09IFwibnVtYmVyXCIpIHtcbiAgICAgICAgICBjb25zdCBhdHRyVmFsdWUgPSB0eXBlb2YgdmFsdWUgPT09IFwic3RyaW5nXCIgPyB2YWx1ZS50cmltKCkgOiB2YWx1ZTtcbiAgICAgICAgICBlbGVtZW50LmF0dHIoYGRhdGEtJHtkYXRhS2V5fWAsIGF0dHJWYWx1ZSk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAoa2V5LnN0YXJ0c1dpdGgoXCJkYXRhLW9uLVwiKSkge1xuICAgICAgICBjb25zdCBldmVudE5hbWUgPSBrZXkuc3Vic3RyaW5nKDgpO1xuICAgICAgICBpZiAodHlwZW9mIHZhbHVlID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgICBlbGVtZW50Lm9uKGV2ZW50TmFtZSwgZnVuY3Rpb24oZSkge1xuICAgICAgICAgICAgdmFsdWUuYmluZChjb250ZXh0KShlLCBlbGVtZW50KTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjb25zb2xlLndhcm4oXCIoSlFIVE1MKSBUcmllZCB0byBhc3NpZ24gYSBub24gZnVuY3Rpb24gdG8gb24gZXZlbnQgaGFuZGxlciBcIiArIGtleSk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAoa2V5LnN0YXJ0c1dpdGgoXCJvblwiKSkge1xuICAgICAgICBjb25zdCBldmVudE5hbWUgPSBrZXkuc3Vic3RyaW5nKDIpO1xuICAgICAgICBpZiAodHlwZW9mIHZhbHVlID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgICBlbGVtZW50Lm9uKGV2ZW50TmFtZSwgZnVuY3Rpb24oZSkge1xuICAgICAgICAgICAgdmFsdWUuYmluZChjb250ZXh0KShlLCBlbGVtZW50KTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjb25zb2xlLndhcm4oXCIoSlFIVE1MKSBUcmllZCB0byBhc3NpZ24gYSBub24gZnVuY3Rpb24gdG8gb24gZXZlbnQgaGFuZGxlciBcIiArIGtleSk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAoa2V5LnN0YXJ0c1dpdGgoXCJkYXRhLVwiKSkge1xuICAgICAgICBjb25zdCBhdHRyVmFsdWUgPSB0eXBlb2YgdmFsdWUgPT09IFwic3RyaW5nXCIgPyB2YWx1ZS50cmltKCkgOiB2YWx1ZTtcbiAgICAgICAgZWxlbWVudC5hdHRyKGtleSwgYXR0clZhbHVlKTtcbiAgICAgICAgY29uc3QgZGF0YUtleSA9IGtleS5zdWJzdHJpbmcoNSk7XG4gICAgICAgIGVsZW1lbnQuZGF0YShkYXRhS2V5LCB2YWx1ZSk7XG4gICAgICAgIGNvbnRleHQuYXJnc1tkYXRhS2V5XSA9IHZhbHVlO1xuICAgICAgfSBlbHNlIGlmIChrZXkgPT09IFwiY2xhc3NcIikge1xuICAgICAgICBjb25zdCBleGlzdGluZ0NsYXNzZXMgPSBlbGVtZW50LmF0dHIoXCJjbGFzc1wiKTtcbiAgICAgICAgaWYgKHdpbmRvdy5qcWh0bWw/LmRlYnVnPy5lbmFibGVkKSB7XG4gICAgICAgICAgY29uc29sZS5sb2coYFtJbnN0cnVjdGlvblByb2Nlc3Nvcl0gTWVyZ2luZyBjbGFzcyBhdHRyaWJ1dGU6YCwge1xuICAgICAgICAgICAgZXhpc3Rpbmc6IGV4aXN0aW5nQ2xhc3NlcyxcbiAgICAgICAgICAgIG5ldzogdmFsdWVcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIWV4aXN0aW5nQ2xhc3Nlcykge1xuICAgICAgICAgIGNvbnN0IGF0dHJWYWx1ZSA9IHR5cGVvZiB2YWx1ZSA9PT0gXCJzdHJpbmdcIiA/IHZhbHVlLnRyaW0oKSA6IHZhbHVlO1xuICAgICAgICAgIGVsZW1lbnQuYXR0cihcImNsYXNzXCIsIGF0dHJWYWx1ZSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY29uc3QgZXhpc3RpbmcgPSBleGlzdGluZ0NsYXNzZXMuc3BsaXQoL1xccysvKS5maWx0ZXIoKGMpID0+IGMpO1xuICAgICAgICAgIGNvbnN0IG5ld0NsYXNzZXMgPSBTdHJpbmcodmFsdWUpLnNwbGl0KC9cXHMrLykuZmlsdGVyKChjKSA9PiBjKTtcbiAgICAgICAgICBmb3IgKGNvbnN0IG5ld0NsYXNzIG9mIG5ld0NsYXNzZXMpIHtcbiAgICAgICAgICAgIGlmICghZXhpc3RpbmcuaW5jbHVkZXMobmV3Q2xhc3MpKSB7XG4gICAgICAgICAgICAgIGV4aXN0aW5nLnB1c2gobmV3Q2xhc3MpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBlbGVtZW50LmF0dHIoXCJjbGFzc1wiLCBleGlzdGluZy5qb2luKFwiIFwiKSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHdpbmRvdy5qcWh0bWw/LmRlYnVnPy5lbmFibGVkKSB7XG4gICAgICAgICAgY29uc29sZS5sb2coYFtJbnN0cnVjdGlvblByb2Nlc3Nvcl0gQ2xhc3MgYWZ0ZXIgbWVyZ2U6YCwgZWxlbWVudC5hdHRyKFwiY2xhc3NcIikpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKGtleSA9PT0gXCJzdHlsZVwiKSB7XG4gICAgICAgIGNvbnN0IGV4aXN0aW5nU3R5bGUgPSBlbGVtZW50LmF0dHIoXCJzdHlsZVwiKTtcbiAgICAgICAgaWYgKCFleGlzdGluZ1N0eWxlKSB7XG4gICAgICAgICAgY29uc3QgYXR0clZhbHVlID0gdHlwZW9mIHZhbHVlID09PSBcInN0cmluZ1wiID8gdmFsdWUudHJpbSgpIDogdmFsdWU7XG4gICAgICAgICAgZWxlbWVudC5hdHRyKFwic3R5bGVcIiwgYXR0clZhbHVlKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjb25zdCBzdHlsZU1hcCA9IHt9O1xuICAgICAgICAgIGV4aXN0aW5nU3R5bGUuc3BsaXQoXCI7XCIpLmZvckVhY2goKHJ1bGUpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IFtwcm9wLCB2YWxdID0gcnVsZS5zcGxpdChcIjpcIikubWFwKChzKSA9PiBzLnRyaW0oKSk7XG4gICAgICAgICAgICBpZiAocHJvcCAmJiB2YWwpIHtcbiAgICAgICAgICAgICAgc3R5bGVNYXBbcHJvcF0gPSB2YWw7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSk7XG4gICAgICAgICAgU3RyaW5nKHZhbHVlKS5zcGxpdChcIjtcIikuZm9yRWFjaCgocnVsZSkgPT4ge1xuICAgICAgICAgICAgY29uc3QgW3Byb3AsIHZhbF0gPSBydWxlLnNwbGl0KFwiOlwiKS5tYXAoKHMpID0+IHMudHJpbSgpKTtcbiAgICAgICAgICAgIGlmIChwcm9wICYmIHZhbCkge1xuICAgICAgICAgICAgICBzdHlsZU1hcFtwcm9wXSA9IHZhbDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KTtcbiAgICAgICAgICBjb25zdCBtZXJnZWRTdHlsZSA9IE9iamVjdC5lbnRyaWVzKHN0eWxlTWFwKS5tYXAoKFtwcm9wLCB2YWxdKSA9PiBgJHtwcm9wfTogJHt2YWx9YCkuam9pbihcIjsgXCIpO1xuICAgICAgICAgIGVsZW1lbnQuYXR0cihcInN0eWxlXCIsIG1lcmdlZFN0eWxlKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gXCJzdHJpbmdcIiB8fCB0eXBlb2YgdmFsdWUgPT09IFwibnVtYmVyXCIgfHwgdHlwZW9mIHZhbHVlID09PSBcImJvb2xlYW5cIikge1xuICAgICAgICAgIGNvbnN0IGF0dHJWYWx1ZSA9IHR5cGVvZiB2YWx1ZSA9PT0gXCJzdHJpbmdcIiA/IHZhbHVlLnRyaW0oKSA6IFN0cmluZyh2YWx1ZSk7XG4gICAgICAgICAgZWxlbWVudC5hdHRyKGtleSwgYXR0clZhbHVlKTtcbiAgICAgICAgfSBlbHNlIGlmICh0eXBlb2YgdmFsdWUgPT09IFwib2JqZWN0XCIpIHtcbiAgICAgICAgICBjb25zb2xlLndhcm4oYChKUUhUTUwpIFVuZXhwZWN0ZWQgdmFsdWUgZm9yICcke2tleX0nIG9uYCwgZWxlbWVudCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgYXN5bmMgZnVuY3Rpb24gaW5pdGlhbGl6ZV9jb21wb25lbnQoZWxlbWVudCwgY29tcERhdGEpIHtcbiAgICBjb25zdCB7IG5hbWUsIHByb3BzLCBjb250ZW50Rm4sIGNvbnRleHQgfSA9IGNvbXBEYXRhO1xuICAgIGNvbnN0IENvbXBvbmVudENsYXNzID0gZ2V0X2NvbXBvbmVudF9jbGFzcyhuYW1lKSB8fCBKcWh0bWxfQ29tcG9uZW50O1xuICAgIGNvbnN0IGludm9jYXRpb25BdHRycyA9IHt9O1xuICAgIGZvciAoY29uc3QgW2tleSwgdmFsdWVdIG9mIE9iamVjdC5lbnRyaWVzKHByb3BzKSkge1xuICAgICAgaWYgKCFrZXkuc3RhcnRzV2l0aChcIl9cIikpIHtcbiAgICAgICAgaW52b2NhdGlvbkF0dHJzW2tleV0gPSB2YWx1ZTtcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKHdpbmRvdy5qcWh0bWw/LmRlYnVnPy5lbmFibGVkKSB7XG4gICAgICBjb25zb2xlLmxvZyhgW0luc3RydWN0aW9uUHJvY2Vzc29yXSBBcHBseWluZyBpbnZvY2F0aW9uIGF0dHJpYnV0ZXMgZm9yICR7bmFtZX06YCwgaW52b2NhdGlvbkF0dHJzKTtcbiAgICB9XG4gICAgYXBwbHlfYXR0cmlidXRlcyhlbGVtZW50LCBpbnZvY2F0aW9uQXR0cnMsIGNvbnRleHQpO1xuICAgIGNvbnN0IG9wdGlvbnMgPSB7fTtcbiAgICBpZiAoY29udGVudEZuKSB7XG4gICAgICBvcHRpb25zLl9pbm5lcmh0bWxfZnVuY3Rpb24gPSBjb250ZW50Rm47XG4gICAgfVxuICAgIGlmIChDb21wb25lbnRDbGFzcy5uYW1lICE9PSBuYW1lKSB7XG4gICAgICBvcHRpb25zLl9jb21wb25lbnRfbmFtZSA9IG5hbWU7XG4gICAgfVxuICAgIGNvbnN0IGluc3RhbmNlID0gbmV3IENvbXBvbmVudENsYXNzKGVsZW1lbnQsIG9wdGlvbnMpO1xuICAgIGluc3RhbmNlLl9pbnN0YW50aWF0b3IgPSBjb250ZXh0O1xuICAgIGF3YWl0IGluc3RhbmNlLmJvb3QoKTtcbiAgfVxuICBmdW5jdGlvbiBleHRyYWN0X3Nsb3RzKGluc3RydWN0aW9ucykge1xuICAgIGNvbnN0IHNsb3RzID0ge307XG4gICAgZm9yIChjb25zdCBpbnN0cnVjdGlvbiBvZiBpbnN0cnVjdGlvbnMpIHtcbiAgICAgIGlmICh0eXBlb2YgaW5zdHJ1Y3Rpb24gPT09IFwib2JqZWN0XCIgJiYgXCJzbG90XCIgaW4gaW5zdHJ1Y3Rpb24pIHtcbiAgICAgICAgY29uc3QgW25hbWVdID0gaW5zdHJ1Y3Rpb24uc2xvdDtcbiAgICAgICAgc2xvdHNbbmFtZV0gPSBpbnN0cnVjdGlvbjtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHNsb3RzO1xuICB9XG4gIHZhciBwZXJmb3JtYW5jZU1ldHJpY3MgPSAvKiBAX19QVVJFX18gKi8gbmV3IE1hcCgpO1xuICBmdW5jdGlvbiBkZXZXYXJuKG1lc3NhZ2UpIHtcbiAgICBpZiAodHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiAmJiB3aW5kb3cuSlFIVE1MX1NVUFBSRVNTX1dBUk5JTkdTKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmICh0eXBlb2YgcHJvY2VzcyAhPT0gXCJ1bmRlZmluZWRcIiAmJiBwcm9jZXNzLmVudiAmJiBmYWxzZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zb2xlLndhcm4oYFtKUUhUTUwgRGV2IFdhcm5pbmddICR7bWVzc2FnZX1gKTtcbiAgfVxuICBmdW5jdGlvbiBnZXRKcWh0bWwkMSgpIHtcbiAgICBpZiAodHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiAmJiB3aW5kb3cuanFodG1sKSB7XG4gICAgICByZXR1cm4gd2luZG93LmpxaHRtbDtcbiAgICB9XG4gICAgaWYgKHR5cGVvZiBnbG9iYWxUaGlzICE9PSBcInVuZGVmaW5lZFwiICYmIGdsb2JhbFRoaXMuanFodG1sKSB7XG4gICAgICByZXR1cm4gZ2xvYmFsVGhpcy5qcWh0bWw7XG4gICAgfVxuICAgIHRocm93IG5ldyBFcnJvcihcIkZBVEFMOiB3aW5kb3cuanFodG1sIGlzIG5vdCBkZWZpbmVkLiBUaGUgSlFIVE1MIHJ1bnRpbWUgbXVzdCBiZSBsb2FkZWQgYmVmb3JlIHVzaW5nIGRlYnVnIGZlYXR1cmVzLiBJbXBvcnQgYW5kIGluaXRpYWxpemUgQGpxaHRtbC9jb3JlIGJlZm9yZSBhdHRlbXB0aW5nIHRvIHVzZSBkZWJ1ZyBmdW5jdGlvbmFsaXR5LlwiKTtcbiAgfVxuICBmdW5jdGlvbiBmbGFzaENvbXBvbmVudChjb21wb25lbnQsIGV2ZW50VHlwZSkge1xuICAgIGNvbnN0IGpxaHRtbDIgPSBnZXRKcWh0bWwkMSgpO1xuICAgIGlmICghanFodG1sMj8uZGVidWc/LmZsYXNoQ29tcG9uZW50cylcbiAgICAgIHJldHVybjtcbiAgICBjb25zdCBkdXJhdGlvbiA9IGpxaHRtbDIuZGVidWcuZmxhc2hEdXJhdGlvbiB8fCA1MDA7XG4gICAgY29uc3QgY29sb3JzID0ganFodG1sMi5kZWJ1Zy5mbGFzaENvbG9ycyB8fCB7fTtcbiAgICBjb25zdCBjb2xvciA9IGNvbG9yc1tldmVudFR5cGVdIHx8IChldmVudFR5cGUgPT09IFwiY3JlYXRlXCIgPyBcIiMzNDk4ZGJcIiA6IGV2ZW50VHlwZSA9PT0gXCJyZW5kZXJcIiA/IFwiIzI3YWU2MFwiIDogXCIjOWI1OWI2XCIpO1xuICAgIGNvbnN0IG9yaWdpbmFsQm9yZGVyID0gY29tcG9uZW50LiQuY3NzKFwiYm9yZGVyXCIpO1xuICAgIGNvbXBvbmVudC4kLmNzcyh7XG4gICAgICBcImJvcmRlclwiOiBgMnB4IHNvbGlkICR7Y29sb3J9YCxcbiAgICAgIFwidHJhbnNpdGlvblwiOiBgYm9yZGVyICR7ZHVyYXRpb259bXMgZWFzZS1vdXRgXG4gICAgfSk7XG4gICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICBjb21wb25lbnQuJC5jc3MoXCJib3JkZXJcIiwgb3JpZ2luYWxCb3JkZXIgfHwgXCJcIik7XG4gICAgfSwgZHVyYXRpb24pO1xuICB9XG4gIGZ1bmN0aW9uIGxvZ0xpZmVjeWNsZShjb21wb25lbnQsIHBoYXNlLCBzdGF0dXMpIHtcbiAgICBjb25zdCBqcWh0bWwyID0gZ2V0SnFodG1sJDEoKTtcbiAgICBpZiAoIWpxaHRtbDI/LmRlYnVnKVxuICAgICAgcmV0dXJuO1xuICAgIGNvbnN0IHNob3VsZExvZyA9IGpxaHRtbDIuZGVidWcubG9nRnVsbExpZmVjeWNsZSB8fCBqcWh0bWwyLmRlYnVnLmxvZ0NyZWF0aW9uUmVhZHkgJiYgKHBoYXNlID09PSBcImNyZWF0ZVwiIHx8IHBoYXNlID09PSBcInJlYWR5XCIpO1xuICAgIGlmICghc2hvdWxkTG9nKVxuICAgICAgcmV0dXJuO1xuICAgIGNvbnN0IGNvbXBvbmVudE5hbWUgPSBjb21wb25lbnQuY29uc3RydWN0b3IubmFtZTtcbiAgICBjb25zdCB0aW1lc3RhbXAgPSAoLyogQF9fUFVSRV9fICovIG5ldyBEYXRlKCkpLnRvSVNPU3RyaW5nKCk7XG4gICAgY29uc3QgcHJlZml4ID0gYFtKUUhUTUwgJHt0aW1lc3RhbXB9XWA7XG4gICAgaWYgKHN0YXR1cyA9PT0gXCJzdGFydFwiKSB7XG4gICAgICBjb25zb2xlLmxvZyhgJHtwcmVmaXh9ICR7Y29tcG9uZW50TmFtZX0jJHtjb21wb25lbnQuX2NpZH0gXFx1MjE5MiAke3BoYXNlfSBzdGFydGluZy4uLmApO1xuICAgICAgaWYgKGpxaHRtbDIuZGVidWcucHJvZmlsZVBlcmZvcm1hbmNlKSB7XG4gICAgICAgIHBlcmZvcm1hbmNlTWV0cmljcy5zZXQoYCR7Y29tcG9uZW50Ll9jaWR9XyR7cGhhc2V9YCwgRGF0ZS5ub3coKSk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGxldCBtZXNzYWdlID0gYCR7cHJlZml4fSAke2NvbXBvbmVudE5hbWV9IyR7Y29tcG9uZW50Ll9jaWR9IFxcdTI3MTMgJHtwaGFzZX0gY29tcGxldGVgO1xuICAgICAgaWYgKGpxaHRtbDIuZGVidWcucHJvZmlsZVBlcmZvcm1hbmNlKSB7XG4gICAgICAgIGNvbnN0IHN0YXJ0VGltZSA9IHBlcmZvcm1hbmNlTWV0cmljcy5nZXQoYCR7Y29tcG9uZW50Ll9jaWR9XyR7cGhhc2V9YCk7XG4gICAgICAgIGlmIChzdGFydFRpbWUpIHtcbiAgICAgICAgICBjb25zdCBkdXJhdGlvbiA9IERhdGUubm93KCkgLSBzdGFydFRpbWU7XG4gICAgICAgICAgbWVzc2FnZSArPSBgICgke2R1cmF0aW9ufW1zKWA7XG4gICAgICAgICAgaWYgKHBoYXNlID09PSBcInJlbmRlclwiICYmIGpxaHRtbDIuZGVidWcuaGlnaGxpZ2h0U2xvd1JlbmRlcnMgJiYgZHVyYXRpb24gPiBqcWh0bWwyLmRlYnVnLmhpZ2hsaWdodFNsb3dSZW5kZXJzKSB7XG4gICAgICAgICAgICBjb25zb2xlLndhcm4oYCR7cHJlZml4fSBTTE9XIFJFTkRFUjogJHtjb21wb25lbnROYW1lfSMke2NvbXBvbmVudC5fY2lkfSB0b29rICR7ZHVyYXRpb259bXNgKTtcbiAgICAgICAgICAgIGNvbXBvbmVudC4kLmNzcyhcIm91dGxpbmVcIiwgXCIycHggZGFzaGVkIHJlZFwiKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGNvbnNvbGUubG9nKG1lc3NhZ2UpO1xuICAgICAgaWYgKGpxaHRtbDIuZGVidWcuZmxhc2hDb21wb25lbnRzICYmIChwaGFzZSA9PT0gXCJjcmVhdGVcIiB8fCBwaGFzZSA9PT0gXCJyZW5kZXJcIiB8fCBwaGFzZSA9PT0gXCJyZWFkeVwiKSkge1xuICAgICAgICBmbGFzaENvbXBvbmVudChjb21wb25lbnQsIHBoYXNlKTtcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKGpxaHRtbDIuZGVidWcuc2hvd0NvbXBvbmVudFRyZWUpIHtcbiAgICAgIHVwZGF0ZUNvbXBvbmVudFRyZWUoKTtcbiAgICB9XG4gIH1cbiAgZnVuY3Rpb24gYXBwbHlEZWJ1Z0RlbGF5KHBoYXNlKSB7XG4gICAgY29uc3QganFodG1sMiA9IGdldEpxaHRtbCQxKCk7XG4gICAgaWYgKCFqcWh0bWwyPy5kZWJ1ZylcbiAgICAgIHJldHVybjtcbiAgICBsZXQgZGVsYXlNcyA9IDA7XG4gICAgc3dpdGNoIChwaGFzZSkge1xuICAgICAgY2FzZSBcImNvbXBvbmVudFwiOlxuICAgICAgICBkZWxheU1zID0ganFodG1sMi5kZWJ1Zy5kZWxheUFmdGVyQ29tcG9uZW50IHx8IDA7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBcInJlbmRlclwiOlxuICAgICAgICBkZWxheU1zID0ganFodG1sMi5kZWJ1Zy5kZWxheUFmdGVyUmVuZGVyIHx8IDA7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBcInJlcmVuZGVyXCI6XG4gICAgICAgIGRlbGF5TXMgPSBqcWh0bWwyLmRlYnVnLmRlbGF5QWZ0ZXJSZXJlbmRlciB8fCAwO1xuICAgICAgICBicmVhaztcbiAgICB9XG4gICAgaWYgKGRlbGF5TXMgPiAwKSB7XG4gICAgICBjb25zb2xlLmxvZyhgW0pRSFRNTCBEZWJ1Z10gQXBwbHlpbmcgJHtkZWxheU1zfW1zIGRlbGF5IGFmdGVyICR7cGhhc2V9YCk7XG4gICAgfVxuICB9XG4gIGZ1bmN0aW9uIHVwZGF0ZUNvbXBvbmVudFRyZWUoKSB7XG4gICAgY29uc29sZS5sb2coXCJbSlFIVE1MIFRyZWVdIENvbXBvbmVudCBoaWVyYXJjaHkgdXBkYXRlZFwiKTtcbiAgfVxuICB2YXIgSnFodG1sX0NvbXBvbmVudCA9IGNsYXNzIF9KcWh0bWxfQ29tcG9uZW50IHtcbiAgICBjb25zdHJ1Y3RvcihlbGVtZW50LCBhcmdzID0ge30pIHtcbiAgICAgIHRoaXMuZGF0YSA9IHt9O1xuICAgICAgdGhpcy5fcmVhZHlfc3RhdGUgPSAwO1xuICAgICAgdGhpcy5faW5zdGFudGlhdG9yID0gbnVsbDtcbiAgICAgIHRoaXMuX2RvbV9wYXJlbnQgPSBudWxsO1xuICAgICAgdGhpcy5fZG9tX2NoaWxkcmVuID0gLyogQF9fUFVSRV9fICovIG5ldyBTZXQoKTtcbiAgICAgIHRoaXMuX3VzZV9kb21fZmFsbGJhY2sgPSBmYWxzZTtcbiAgICAgIHRoaXMuX3N0b3BwZWQgPSBmYWxzZTtcbiAgICAgIHRoaXMuX2Jvb3RlZCA9IGZhbHNlO1xuICAgICAgdGhpcy5fZGF0YV9iZWZvcmVfcmVuZGVyID0gbnVsbDtcbiAgICAgIHRoaXMuX2xpZmVjeWNsZV9jYWxsYmFja3MgPSAvKiBAX19QVVJFX18gKi8gbmV3IE1hcCgpO1xuICAgICAgdGhpcy5fbGlmZWN5Y2xlX3N0YXRlcyA9IC8qIEBfX1BVUkVfXyAqLyBuZXcgU2V0KCk7XG4gICAgICB0aGlzLl9fbG9hZGluZyA9IGZhbHNlO1xuICAgICAgdGhpcy5fZGlkX2ZpcnN0X3JlbmRlciA9IGZhbHNlO1xuICAgICAgdGhpcy5fcmVuZGVyX2NvdW50ID0gMDtcbiAgICAgIHRoaXMuX2NpZCA9IHRoaXMuX2dlbmVyYXRlX2NpZCgpO1xuICAgICAgdGhpcy5fbGlmZWN5Y2xlX21hbmFnZXIgPSBMaWZlY3ljbGVNYW5hZ2VyLmdldF9pbnN0YW5jZSgpO1xuICAgICAgaWYgKGVsZW1lbnQpIHtcbiAgICAgICAgdGhpcy4kID0gJChlbGVtZW50KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnN0IGRpdiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIik7XG4gICAgICAgIHRoaXMuJCA9ICQoZGl2KTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGRhdGFBdHRycyA9IHt9O1xuICAgICAgaWYgKHRoaXMuJC5sZW5ndGggPiAwKSB7XG4gICAgICAgIGNvbnN0IGRhdGFzZXQgPSB0aGlzLiRbMF0uZGF0YXNldCB8fCB7fTtcbiAgICAgICAgZm9yIChjb25zdCBrZXkgaW4gZGF0YXNldCkge1xuICAgICAgICAgIGlmIChrZXkgIT09IFwiY2lkXCIgJiYga2V5ICE9PSBcInRpZFwiICYmIGtleSAhPT0gXCJjb21wb25lbnROYW1lXCIgJiYga2V5ICE9PSBcInJlYWR5U3RhdGVcIikge1xuICAgICAgICAgICAgY29uc3QgZGF0YVZhbHVlID0gdGhpcy4kLmRhdGEoa2V5KTtcbiAgICAgICAgICAgIGlmIChkYXRhVmFsdWUgIT09IHZvaWQgMCAmJiBkYXRhVmFsdWUgIT09IGRhdGFzZXRba2V5XSkge1xuICAgICAgICAgICAgICBkYXRhQXR0cnNba2V5XSA9IGRhdGFWYWx1ZTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIGRhdGFBdHRyc1trZXldID0gZGF0YXNldFtrZXldO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgbGV0IHRlbXBsYXRlX2Zvcl9hcmdzO1xuICAgICAgaWYgKGFyZ3MuX2NvbXBvbmVudF9uYW1lKSB7XG4gICAgICAgIHRlbXBsYXRlX2Zvcl9hcmdzID0gZ2V0X3RlbXBsYXRlKGFyZ3MuX2NvbXBvbmVudF9uYW1lKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRlbXBsYXRlX2Zvcl9hcmdzID0gZ2V0X3RlbXBsYXRlX2J5X2NsYXNzKHRoaXMuY29uc3RydWN0b3IpO1xuICAgICAgfVxuICAgICAgY29uc3QgZGVmaW5lQXJncyA9IHRlbXBsYXRlX2Zvcl9hcmdzPy5kZWZpbmVBcmdzIHx8IHt9O1xuICAgICAgdGhpcy5hcmdzID0geyAuLi5kZWZpbmVBcmdzLCAuLi5kYXRhQXR0cnMsIC4uLmFyZ3MgfTtcbiAgICAgIGZvciAoY29uc3QgW2tleSwgdmFsdWVdIG9mIE9iamVjdC5lbnRyaWVzKHRoaXMuYXJncykpIHtcbiAgICAgICAgaWYgKGtleSA9PT0gXCJjaWRcIiB8fCBrZXkgPT09IFwidGlkXCIgfHwga2V5ID09PSBcImNvbXBvbmVudE5hbWVcIiB8fCBrZXkgPT09IFwicmVhZHlTdGF0ZVwiIHx8IGtleS5zdGFydHNXaXRoKFwiX1wiKSkge1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT09IFwic3RyaW5nXCIgfHwgdHlwZW9mIHZhbHVlID09PSBcIm51bWJlclwiKSB7XG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGNvbnN0IGN1cnJlbnRBdHRyID0gdGhpcy4kLmF0dHIoYGRhdGEtJHtrZXl9YCk7XG4gICAgICAgICAgICBpZiAoY3VycmVudEF0dHIgIT0gdmFsdWUpIHtcbiAgICAgICAgICAgICAgdGhpcy4kLmF0dHIoYGRhdGEtJHtrZXl9YCwgU3RyaW5nKHZhbHVlKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgdGhpcy4kLmRhdGEoXCJfY29tcG9uZW50XCIsIHRoaXMpO1xuICAgICAgdGhpcy5fYXBwbHlfY3NzX2NsYXNzZXMoKTtcbiAgICAgIHRoaXMuX2FwcGx5X2RlZmF1bHRfYXR0cmlidXRlcygpO1xuICAgICAgdGhpcy5fc2V0X2F0dHJpYnV0ZXMoKTtcbiAgICAgIHRoaXMuX2ZpbmRfZG9tX3BhcmVudCgpO1xuICAgICAgdGhpcy5fbG9nX2xpZmVjeWNsZShcImNvbnN0cnVjdFwiLCBcImNvbXBsZXRlXCIpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBCb290IC0gU3RhcnQgdGhlIGZ1bGwgY29tcG9uZW50IGxpZmVjeWNsZVxuICAgICAqIENhbGxlZCBpbW1lZGlhdGVseSBhZnRlciBjb25zdHJ1Y3Rpb24gYnkgaW5zdHJ1Y3Rpb24gcHJvY2Vzc29yXG4gICAgICovXG4gICAgYXN5bmMgYm9vdCgpIHtcbiAgICAgIGlmICh0aGlzLl9ib290ZWQpXG4gICAgICAgIHJldHVybjtcbiAgICAgIHRoaXMuX2Jvb3RlZCA9IHRydWU7XG4gICAgICBhd2FpdCB0aGlzLl9saWZlY3ljbGVfbWFuYWdlci5ib290X2NvbXBvbmVudCh0aGlzKTtcbiAgICB9XG4gICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIC8vIExpZmVjeWNsZSBNZXRob2RzIChjYWxsZWQgYnkgTGlmZWN5Y2xlTWFuYWdlcilcbiAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgLyoqXG4gICAgICogSW50ZXJuYWwgcmVuZGVyIHBoYXNlIC0gQ3JlYXRlIERPTSBzdHJ1Y3R1cmVcbiAgICAgKiBDYWxsZWQgdG9wLWRvd24gKHBhcmVudCBiZWZvcmUgY2hpbGRyZW4pIHdoZW4gcGFydCBvZiBsaWZlY3ljbGVcbiAgICAgKiBUaGlzIGlzIGFuIGludGVybmFsIG1ldGhvZCAtIHVzZXJzIHNob3VsZCBjYWxsIHJlbmRlcigpIGluc3RlYWRcbiAgICAgKlxuICAgICAqIEBwYXJhbSBpZCBPcHRpb25hbCBzY29wZWQgSUQgLSBpZiBwcm92aWRlZCwgZGVsZWdhdGVzIHRvIGNoaWxkIGNvbXBvbmVudCdzIF9yZW5kZXIoKVxuICAgICAqIEByZXR1cm5zIFRoZSBjdXJyZW50IF9yZW5kZXJfY291bnQgYWZ0ZXIgaW5jcmVtZW50aW5nICh1c2VkIHRvIGRldGVjdCBzdGFsZSByZW5kZXJzKVxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG4gICAgX3JlbmRlcihpZCA9IG51bGwpIHtcbiAgICAgIHRoaXMuX3JlbmRlcl9jb3VudCsrO1xuICAgICAgY29uc3QgY3VycmVudF9yZW5kZXJfaWQgPSB0aGlzLl9yZW5kZXJfY291bnQ7XG4gICAgICBpZiAodGhpcy5fc3RvcHBlZClcbiAgICAgICAgcmV0dXJuIGN1cnJlbnRfcmVuZGVyX2lkO1xuICAgICAgaWYgKGlkKSB7XG4gICAgICAgIGNvbnN0ICRlbGVtZW50ID0gdGhpcy4kaWQoaWQpO1xuICAgICAgICBpZiAoJGVsZW1lbnQubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBbSlFIVE1MXSByZW5kZXIoXCIke2lkfVwiKSAtIG5vIHN1Y2ggaWQuXG5Db21wb25lbnQgXCIke3RoaXMuY29tcG9uZW50X25hbWUoKX1cIiBoYXMgbm8gY2hpbGQgZWxlbWVudCB3aXRoICRpZD1cIiR7aWR9XCIuYCk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgY2hpbGQgPSAkZWxlbWVudC5kYXRhKFwiX2NvbXBvbmVudFwiKTtcbiAgICAgICAgaWYgKCFjaGlsZCkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgW0pRSFRNTF0gcmVuZGVyKFwiJHtpZH1cIikgLSBlbGVtZW50IGlzIG5vdCBhIGNvbXBvbmVudCBvciBkb2VzIG5vdCBoYXZlICRyZWRyYXdhYmxlIGF0dHJpYnV0ZSBzZXQuXG5FbGVtZW50IHdpdGggJGlkPVwiJHtpZH1cIiBleGlzdHMgYnV0IGlzIG5vdCBpbml0aWFsaXplZCBhcyBhIGNvbXBvbmVudC5cbkFkZCAkcmVkcmF3YWJsZSBhdHRyaWJ1dGUgb3IgbWFrZSBpdCBhIHByb3BlciBjb21wb25lbnQuYCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGNoaWxkLl9yZW5kZXIoKTtcbiAgICAgIH1cbiAgICAgIGlmICh0aGlzLl9fbG9hZGluZykge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFtKUUhUTUxdIENvbXBvbmVudCBcIiR7dGhpcy5jb21wb25lbnRfbmFtZSgpfVwiIGF0dGVtcHRlZCB0byBjYWxsIHJlbmRlcigpIGR1cmluZyBvbl9sb2FkKCkuXG5vbl9sb2FkKCkgc2hvdWxkIE9OTFkgbW9kaWZ5IHRoaXMuZGF0YS4gRE9NIHVwZGF0ZXMgaGFwcGVuIGF1dG9tYXRpY2FsbHkgYWZ0ZXIgb25fbG9hZCgpIGNvbXBsZXRlcy5cblxuRml4OiBSZW1vdmUgdGhlIHRoaXMucmVuZGVyKCkgY2FsbCBmcm9tIG9uX2xvYWQoKS5cblRoZSBmcmFtZXdvcmsgd2lsbCBhdXRvbWF0aWNhbGx5IHJlLXJlbmRlciBpZiB0aGlzLmRhdGEgY2hhbmdlcyBkdXJpbmcgb25fbG9hZCgpLmApO1xuICAgICAgfVxuICAgICAgdGhpcy5fbG9nX2xpZmVjeWNsZShcInJlbmRlclwiLCBcInN0YXJ0XCIpO1xuICAgICAgaWYgKCEkLmNvbnRhaW5zKGRvY3VtZW50LmRvY3VtZW50RWxlbWVudCwgdGhpcy4kWzBdKSkge1xuICAgICAgICB0aGlzLl91c2VfZG9tX2ZhbGxiYWNrID0gdHJ1ZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuX3VzZV9kb21fZmFsbGJhY2sgPSBmYWxzZTtcbiAgICAgIH1cbiAgICAgIGlmICh0aGlzLl9kaWRfZmlyc3RfcmVuZGVyKSB7XG4gICAgICAgIHRoaXMuJC5maW5kKFwiLkpxaHRtbF9Db21wb25lbnRcIikuZWFjaChmdW5jdGlvbigpIHtcbiAgICAgICAgICBjb25zdCBjaGlsZCA9ICQodGhpcykuZGF0YShcIl9jb21wb25lbnRcIik7XG4gICAgICAgICAgaWYgKGNoaWxkICYmICFjaGlsZC5fc3RvcHBlZCkge1xuICAgICAgICAgICAgY2hpbGQuX3N0b3AoKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLiRbMF0uaW5uZXJIVE1MID0gXCJcIjtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuX2RpZF9maXJzdF9yZW5kZXIgPSB0cnVlO1xuICAgICAgfVxuICAgICAgdGhpcy4kLnJlbW92ZUNsYXNzKFwiX0NvbXBvbmVudF9TdG9wcGVkXCIpO1xuICAgICAgaWYgKHRoaXMuX2RhdGFfYmVmb3JlX3JlbmRlciA9PT0gbnVsbCkge1xuICAgICAgICB0aGlzLl9kYXRhX2JlZm9yZV9yZW5kZXIgPSBKU09OLnN0cmluZ2lmeSh0aGlzLmRhdGEpO1xuICAgICAgfVxuICAgICAgdGhpcy5fZG9tX2NoaWxkcmVuLmNsZWFyKCk7XG4gICAgICBsZXQgdGVtcGxhdGVfZGVmO1xuICAgICAgaWYgKHRoaXMuYXJncy5fY29tcG9uZW50X25hbWUpIHtcbiAgICAgICAgdGVtcGxhdGVfZGVmID0gZ2V0X3RlbXBsYXRlKHRoaXMuYXJncy5fY29tcG9uZW50X25hbWUpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGVtcGxhdGVfZGVmID0gZ2V0X3RlbXBsYXRlX2J5X2NsYXNzKHRoaXMuY29uc3RydWN0b3IpO1xuICAgICAgfVxuICAgICAgaWYgKHRlbXBsYXRlX2RlZiAmJiB0ZW1wbGF0ZV9kZWYucmVuZGVyKSB7XG4gICAgICAgIGNvbnN0IGpxaHRtbDIgPSB7XG4gICAgICAgICAgZXNjYXBlX2h0bWw6IChzdHIpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGRpdiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIik7XG4gICAgICAgICAgICBkaXYudGV4dENvbnRlbnQgPSBTdHJpbmcoc3RyKTtcbiAgICAgICAgICAgIHJldHVybiBkaXYuaW5uZXJIVE1MO1xuICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgY29uc3QgZGVmYXVsdENvbnRlbnQgPSAoKSA9PiBcIlwiO1xuICAgICAgICBsZXQgW2luc3RydWN0aW9ucywgY29udGV4dF0gPSB0ZW1wbGF0ZV9kZWYucmVuZGVyLmJpbmQodGhpcykoXG4gICAgICAgICAgdGhpcy5kYXRhLFxuICAgICAgICAgIHRoaXMuYXJncyxcbiAgICAgICAgICB0aGlzLmFyZ3MuX2lubmVyaHRtbF9mdW5jdGlvbiB8fCBkZWZhdWx0Q29udGVudCxcbiAgICAgICAgICAvLyBDb250ZW50IGZ1bmN0aW9uIHdpdGggZmFsbGJhY2tcbiAgICAgICAgICBqcWh0bWwyXG4gICAgICAgICAgLy8gVXRpbGl0aWVzIG9iamVjdFxuICAgICAgICApO1xuICAgICAgICBpZiAoaW5zdHJ1Y3Rpb25zICYmIHR5cGVvZiBpbnN0cnVjdGlvbnMgPT09IFwib2JqZWN0XCIgJiYgaW5zdHJ1Y3Rpb25zLl9zbG90cyAmJiAhQXJyYXkuaXNBcnJheShpbnN0cnVjdGlvbnMpKSB7XG4gICAgICAgICAgY29uc3QgY29tcG9uZW50TmFtZSA9IHRlbXBsYXRlX2RlZi5uYW1lIHx8IHRoaXMuYXJncy5fY29tcG9uZW50X25hbWUgfHwgdGhpcy5jb25zdHJ1Y3Rvci5uYW1lO1xuICAgICAgICAgIGNvbnNvbGUubG9nKGBbSlFIVE1MXSBTbG90LW9ubHkgdGVtcGxhdGUgZGV0ZWN0ZWQgZm9yICR7Y29tcG9uZW50TmFtZX1gKTtcbiAgICAgICAgICBsZXQgcGFyZW50VGVtcGxhdGUgPSBudWxsO1xuICAgICAgICAgIGxldCBwYXJlbnRUZW1wbGF0ZU5hbWUgPSBudWxsO1xuICAgICAgICAgIGlmICh0ZW1wbGF0ZV9kZWYuZXh0ZW5kcykge1xuICAgICAgICAgICAgY29uc29sZS5sb2coYFtKUUhUTUxdICAgVXNpbmcgZXhwbGljaXQgZXh0ZW5kczogJHt0ZW1wbGF0ZV9kZWYuZXh0ZW5kc31gKTtcbiAgICAgICAgICAgIHBhcmVudFRlbXBsYXRlID0gZ2V0X3RlbXBsYXRlKHRlbXBsYXRlX2RlZi5leHRlbmRzKTtcbiAgICAgICAgICAgIHBhcmVudFRlbXBsYXRlTmFtZSA9IHRlbXBsYXRlX2RlZi5leHRlbmRzO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoIXBhcmVudFRlbXBsYXRlKSB7XG4gICAgICAgICAgICBsZXQgY3VycmVudENsYXNzID0gT2JqZWN0LmdldFByb3RvdHlwZU9mKHRoaXMuY29uc3RydWN0b3IpO1xuICAgICAgICAgICAgd2hpbGUgKGN1cnJlbnRDbGFzcyAmJiBjdXJyZW50Q2xhc3MubmFtZSAhPT0gXCJPYmplY3RcIiAmJiBjdXJyZW50Q2xhc3MubmFtZSAhPT0gXCJKcWh0bWxfQ29tcG9uZW50XCIpIHtcbiAgICAgICAgICAgICAgY29uc3QgY2xhc3NOYW1lID0gY3VycmVudENsYXNzLm5hbWU7XG4gICAgICAgICAgICAgIGNvbnNvbGUubG9nKGBbSlFIVE1MXSAgIENoZWNraW5nIHBhcmVudDogJHtjbGFzc05hbWV9YCk7XG4gICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgY29uc3QgY2xhc3NUZW1wbGF0ZSA9IGdldF90ZW1wbGF0ZShjbGFzc05hbWUpO1xuICAgICAgICAgICAgICAgIGlmIChjbGFzc1RlbXBsYXRlICYmIGNsYXNzVGVtcGxhdGUubmFtZSAhPT0gXCJKcWh0bWxfQ29tcG9uZW50XCIpIHtcbiAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKGBbSlFIVE1MXSAgIEZvdW5kIHBhcmVudCB0ZW1wbGF0ZTogJHtjbGFzc05hbWV9YCk7XG4gICAgICAgICAgICAgICAgICBwYXJlbnRUZW1wbGF0ZSA9IGNsYXNzVGVtcGxhdGU7XG4gICAgICAgICAgICAgICAgICBwYXJlbnRUZW1wbGF0ZU5hbWUgPSBjbGFzc05hbWU7XG4gICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgY29uc29sZS53YXJuKGBbSlFIVE1MXSBFcnJvciBmaW5kaW5nIHBhcmVudCB0ZW1wbGF0ZSAke2NsYXNzTmFtZX06YCwgZXJyb3IpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIGN1cnJlbnRDbGFzcyA9IE9iamVjdC5nZXRQcm90b3R5cGVPZihjdXJyZW50Q2xhc3MpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAocGFyZW50VGVtcGxhdGUpIHtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgIGNvbnN0IGNoaWxkU2xvdHMgPSBpbnN0cnVjdGlvbnMuX3Nsb3RzO1xuICAgICAgICAgICAgICBjb25zdCBjb250ZW50RnVuY3Rpb24gPSAoc2xvdE5hbWUsIGRhdGEpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoY2hpbGRTbG90c1tzbG90TmFtZV0gJiYgdHlwZW9mIGNoaWxkU2xvdHNbc2xvdE5hbWVdID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgICAgICAgICAgIGNvbnN0IFtzbG90SW5zdHJ1Y3Rpb25zLCBzbG90Q29udGV4dF0gPSBjaGlsZFNsb3RzW3Nsb3ROYW1lXShkYXRhKTtcbiAgICAgICAgICAgICAgICAgIHJldHVybiBbc2xvdEluc3RydWN0aW9ucywgc2xvdENvbnRleHRdO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gXCJcIjtcbiAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgY29uc3QgW3BhcmVudEluc3RydWN0aW9ucywgcGFyZW50Q29udGV4dF0gPSBwYXJlbnRUZW1wbGF0ZS5yZW5kZXIuYmluZCh0aGlzKShcbiAgICAgICAgICAgICAgICB0aGlzLmRhdGEsXG4gICAgICAgICAgICAgICAgdGhpcy5hcmdzLFxuICAgICAgICAgICAgICAgIGNvbnRlbnRGdW5jdGlvbixcbiAgICAgICAgICAgICAgICAvLyBQYXNzIGNvbnRlbnQgZnVuY3Rpb24gdGhhdCBpbnZva2VzIGNoaWxkIHNsb3RzXG4gICAgICAgICAgICAgICAganFodG1sMlxuICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICBjb25zb2xlLmxvZyhgW0pRSFRNTF0gICBQYXJlbnQgdGVtcGxhdGUgaW52b2tlZCBzdWNjZXNzZnVsbHlgKTtcbiAgICAgICAgICAgICAgaW5zdHJ1Y3Rpb25zID0gcGFyZW50SW5zdHJ1Y3Rpb25zO1xuICAgICAgICAgICAgICBjb250ZXh0ID0gcGFyZW50Q29udGV4dDtcbiAgICAgICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICAgIGNvbnNvbGUud2FybihgW0pRSFRNTF0gRXJyb3IgaW52b2tpbmcgcGFyZW50IHRlbXBsYXRlICR7cGFyZW50VGVtcGxhdGVOYW1lfTpgLCBlcnJvcik7XG4gICAgICAgICAgICAgIGluc3RydWN0aW9ucyA9IFtdO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zb2xlLndhcm4oYFtKUUhUTUxdIE5vIHBhcmVudCB0ZW1wbGF0ZSBmb3VuZCBmb3IgJHt0aGlzLmNvbnN0cnVjdG9yLm5hbWV9LCByZW5kZXJpbmcgZW1wdHlgKTtcbiAgICAgICAgICAgIGluc3RydWN0aW9ucyA9IFtdO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBjb25zdCBmbGF0dGVuZWRJbnN0cnVjdGlvbnMgPSB0aGlzLl9mbGF0dGVuX2luc3RydWN0aW9ucyhpbnN0cnVjdGlvbnMpO1xuICAgICAgICBwcm9jZXNzX2luc3RydWN0aW9ucyhmbGF0dGVuZWRJbnN0cnVjdGlvbnMsIHRoaXMuJCwgdGhpcyk7XG4gICAgICB9XG4gICAgICB0aGlzLl91cGRhdGVfZGVidWdfYXR0cnMoKTtcbiAgICAgIHRoaXMuX2xvZ19saWZlY3ljbGUoXCJyZW5kZXJcIiwgXCJjb21wbGV0ZVwiKTtcbiAgICAgIGNvbnN0IHJlbmRlclJlc3VsdCA9IHRoaXMub25fcmVuZGVyKCk7XG4gICAgICBpZiAocmVuZGVyUmVzdWx0ICYmIHR5cGVvZiByZW5kZXJSZXN1bHQudGhlbiA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgIGNvbnNvbGUud2FybihgW0pRSFRNTF0gQ29tcG9uZW50IFwiJHt0aGlzLmNvbXBvbmVudF9uYW1lKCl9XCIgcmV0dXJuZWQgYSBQcm9taXNlIGZyb20gb25fcmVuZGVyKCkuIG9uX3JlbmRlcigpIG11c3QgYmUgc3luY2hyb25vdXMgY29kZS4gUmVtb3ZlICdhc3luYycgZnJvbSB0aGUgZnVuY3Rpb24gZGVjbGFyYXRpb24uYCk7XG4gICAgICB9XG4gICAgICB0aGlzLnRyaWdnZXIoXCJyZW5kZXJcIik7XG4gICAgICBjb25zdCBpc1JlcmVuZGVyID0gdGhpcy5fcmVhZHlfc3RhdGUgPj0gMztcbiAgICAgIGFwcGx5RGVidWdEZWxheShpc1JlcmVuZGVyID8gXCJyZXJlbmRlclwiIDogXCJyZW5kZXJcIik7XG4gICAgICByZXR1cm4gY3VycmVudF9yZW5kZXJfaWQ7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFB1YmxpYyByZW5kZXIgbWV0aG9kIC0gcmUtcmVuZGVycyBjb21wb25lbnQgYW5kIGNvbXBsZXRlcyBsaWZlY3ljbGVcbiAgICAgKiBUaGlzIGlzIHdoYXQgdXNlcnMgc2hvdWxkIGNhbGwgd2hlbiB0aGV5IHdhbnQgdG8gdXBkYXRlIGEgY29tcG9uZW50LlxuICAgICAqXG4gICAgICogTGlmZWN5Y2xlIHNlcXVlbmNlOlxuICAgICAqIDEuIF9yZW5kZXIoKSAtIFVwZGF0ZXMgRE9NIHN5bmNocm9ub3VzbHksIGNhbGxzIG9uX3JlbmRlcigpLCBmaXJlcyAncmVuZGVyJyBldmVudFxuICAgICAqIDIuIEFzeW5jIGNvbnRpbnVhdGlvbiAoZmlyZSBhbmQgZm9yZ2V0KTpcbiAgICAgKiAgICAtIF93YWl0X2Zvcl9jaGlsZHJlbl9yZWFkeSgpIC0gV2FpdHMgZm9yIGFsbCBjaGlsZHJlbiB0byByZWFjaCByZWFkeSBzdGF0ZVxuICAgICAqICAgIC0gb25fcmVhZHkoKSAtIENhbGxzIHVzZXIncyByZWFkeSBob29rXG4gICAgICogICAgLSB0cmlnZ2VyKCdyZWFkeScpIC0gRmlyZXMgcmVhZHkgZXZlbnRcbiAgICAgKlxuICAgICAqIFJldHVybnMgaW1tZWRpYXRlbHkgYWZ0ZXIgX3JlbmRlcigpIGNvbXBsZXRlcyAtIGRvZXMgTk9UIHdhaXQgZm9yIGNoaWxkcmVuXG4gICAgICovXG4gICAgcmVuZGVyKGlkID0gbnVsbCkge1xuICAgICAgaWYgKHRoaXMuX3N0b3BwZWQpXG4gICAgICAgIHJldHVybjtcbiAgICAgIGlmIChpZCkge1xuICAgICAgICBjb25zdCAkZWxlbWVudCA9IHRoaXMuJGlkKGlkKTtcbiAgICAgICAgaWYgKCRlbGVtZW50Lmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgW0pRSFRNTF0gcmVuZGVyKFwiJHtpZH1cIikgLSBubyBzdWNoIGlkLlxuQ29tcG9uZW50IFwiJHt0aGlzLmNvbXBvbmVudF9uYW1lKCl9XCIgaGFzIG5vIGNoaWxkIGVsZW1lbnQgd2l0aCAkaWQ9XCIke2lkfVwiLmApO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGNoaWxkID0gJGVsZW1lbnQuZGF0YShcIl9jb21wb25lbnRcIik7XG4gICAgICAgIGlmICghY2hpbGQpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFtKUUhUTUxdIHJlbmRlcihcIiR7aWR9XCIpIC0gZWxlbWVudCBpcyBub3QgYSBjb21wb25lbnQgb3IgZG9lcyBub3QgaGF2ZSAkcmVkcmF3YWJsZSBhdHRyaWJ1dGUgc2V0LlxuRWxlbWVudCB3aXRoICRpZD1cIiR7aWR9XCIgZXhpc3RzIGJ1dCBpcyBub3QgaW5pdGlhbGl6ZWQgYXMgYSBjb21wb25lbnQuXG5BZGQgJHJlZHJhd2FibGUgYXR0cmlidXRlIG9yIG1ha2UgaXQgYSBwcm9wZXIgY29tcG9uZW50LmApO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBjaGlsZC5yZW5kZXIoKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHJlbmRlcl9pZCA9IHRoaXMuX3JlbmRlcigpO1xuICAgICAgKGFzeW5jICgpID0+IHtcbiAgICAgICAgYXdhaXQgdGhpcy5fd2FpdF9mb3JfY2hpbGRyZW5fcmVhZHkoKTtcbiAgICAgICAgaWYgKHRoaXMuX3JlbmRlcl9jb3VudCAhPT0gcmVuZGVyX2lkKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGF3YWl0IHRoaXMub25fcmVhZHkoKTtcbiAgICAgICAgYXdhaXQgdGhpcy50cmlnZ2VyKFwicmVhZHlcIik7XG4gICAgICB9KSgpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBBbGlhcyBmb3IgcmVuZGVyKCkgLSByZS1yZW5kZXJzIGNvbXBvbmVudCB3aXRoIGN1cnJlbnQgZGF0YVxuICAgICAqIFByb3ZpZGVkIGZvciBBUEkgY29uc2lzdGVuY3kgYW5kIGNsYXJpdHlcbiAgICAgKi9cbiAgICByZWRyYXcoaWQgPSBudWxsKSB7XG4gICAgICByZXR1cm4gdGhpcy5yZW5kZXIoaWQpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDcmVhdGUgcGhhc2UgLSBRdWljayBzZXR1cCwgcHJlcGFyZSBVSVxuICAgICAqIENhbGxlZCBib3R0b20tdXAgKGNoaWxkcmVuIGJlZm9yZSBwYXJlbnQpXG4gICAgICovXG4gICAgYXN5bmMgY3JlYXRlKCkge1xuICAgICAgaWYgKHRoaXMuX3N0b3BwZWQgfHwgdGhpcy5fcmVhZHlfc3RhdGUgPj0gMSlcbiAgICAgICAgcmV0dXJuO1xuICAgICAgdGhpcy5fbG9nX2xpZmVjeWNsZShcImNyZWF0ZVwiLCBcInN0YXJ0XCIpO1xuICAgICAgY29uc3QgcmVzdWx0ID0gdGhpcy5vbl9jcmVhdGUoKTtcbiAgICAgIGlmIChyZXN1bHQgJiYgdHlwZW9mIHJlc3VsdC50aGVuID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgY29uc29sZS53YXJuKGBbSlFIVE1MXSBDb21wb25lbnQgXCIke3RoaXMuY29tcG9uZW50X25hbWUoKX1cIiByZXR1cm5lZCBhIFByb21pc2UgZnJvbSBvbl9jcmVhdGUoKS4gb25fY3JlYXRlKCkgbXVzdCBiZSBzeW5jaHJvbm91cyBjb2RlLiBSZW1vdmUgJ2FzeW5jJyBmcm9tIHRoZSBmdW5jdGlvbiBkZWNsYXJhdGlvbi5gKTtcbiAgICAgICAgYXdhaXQgcmVzdWx0O1xuICAgICAgfVxuICAgICAgdGhpcy5fcmVhZHlfc3RhdGUgPSAxO1xuICAgICAgdGhpcy5fdXBkYXRlX2RlYnVnX2F0dHJzKCk7XG4gICAgICB0aGlzLl9sb2dfbGlmZWN5Y2xlKFwiY3JlYXRlXCIsIFwiY29tcGxldGVcIik7XG4gICAgICB0aGlzLnRyaWdnZXIoXCJjcmVhdGVcIik7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIExvYWQgcGhhc2UgLSBGZXRjaCBkYXRhIGZyb20gQVBJc1xuICAgICAqIENhbGxlZCBib3R0b20tdXAsIGZ1bGx5IHBhcmFsbGVsXG4gICAgICogTk8gRE9NIE1PRElGSUNBVElPTlMgQUxMT1dFRCBJTiBUSElTIFBIQVNFXG4gICAgICovXG4gICAgYXN5bmMgbG9hZCgpIHtcbiAgICAgIGlmICh0aGlzLl9zdG9wcGVkIHx8IHRoaXMuX3JlYWR5X3N0YXRlID49IDIpXG4gICAgICAgIHJldHVybjtcbiAgICAgIHRoaXMuX2xvZ19saWZlY3ljbGUoXCJsb2FkXCIsIFwic3RhcnRcIik7XG4gICAgICBjb25zdCBhcmdzQmVmb3JlTG9hZCA9IEpTT04uc3RyaW5naWZ5KHRoaXMuYXJncyk7XG4gICAgICBjb25zdCBwcm9wZXJ0aWVzQmVmb3JlTG9hZCA9IG5ldyBTZXQoT2JqZWN0LmtleXModGhpcykpO1xuICAgICAgdGhpcy5fX2xvYWRpbmcgPSB0cnVlO1xuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgdGhpcy5vbl9sb2FkKCk7XG4gICAgICB9IGZpbmFsbHkge1xuICAgICAgICB0aGlzLl9fbG9hZGluZyA9IGZhbHNlO1xuICAgICAgfVxuICAgICAgY29uc3QgYXJnc0FmdGVyTG9hZCA9IEpTT04uc3RyaW5naWZ5KHRoaXMuYXJncyk7XG4gICAgICBjb25zdCBwcm9wZXJ0aWVzQWZ0ZXJMb2FkID0gT2JqZWN0LmtleXModGhpcyk7XG4gICAgICBpZiAoYXJnc0JlZm9yZUxvYWQgIT09IGFyZ3NBZnRlckxvYWQpIHtcbiAgICAgICAgY29uc29sZS5lcnJvcihgW0pRSFRNTF0gV0FSTklORzogQ29tcG9uZW50IFwiJHt0aGlzLmNvbXBvbmVudF9uYW1lKCl9XCIgbW9kaWZpZWQgdGhpcy5hcmdzIGluIG9uX2xvYWQoKS5cbm9uX2xvYWQoKSBzaG91bGQgT05MWSBtb2RpZnkgdGhpcy5kYXRhLiBUaGUgdGhpcy5hcmdzIHByb3BlcnR5IGlzIHJlYWQtb25seS5cblxuQmVmb3JlOiAke2FyZ3NCZWZvcmVMb2FkfVxuQWZ0ZXI6ICAke2FyZ3NBZnRlckxvYWR9XG5cbkZpeDogTW92ZSB5b3VyIG1vZGlmaWNhdGlvbnMgdG8gdGhpcy5kYXRhIGluc3RlYWQuYCk7XG4gICAgICB9XG4gICAgICBjb25zdCBuZXdQcm9wZXJ0aWVzID0gcHJvcGVydGllc0FmdGVyTG9hZC5maWx0ZXIoKHByb3ApID0+ICFwcm9wZXJ0aWVzQmVmb3JlTG9hZC5oYXMocHJvcCkgJiYgcHJvcCAhPT0gXCJkYXRhXCIpO1xuICAgICAgaWYgKG5ld1Byb3BlcnRpZXMubGVuZ3RoID4gMCkge1xuICAgICAgICBjb25zb2xlLmVycm9yKGBbSlFIVE1MXSBXQVJOSU5HOiBDb21wb25lbnQgXCIke3RoaXMuY29tcG9uZW50X25hbWUoKX1cIiBhZGRlZCBuZXcgcHJvcGVydGllcyBpbiBvbl9sb2FkKCkuXG5vbl9sb2FkKCkgc2hvdWxkIE9OTFkgbW9kaWZ5IHRoaXMuZGF0YS4gTmV3IHByb3BlcnRpZXMgZGV0ZWN0ZWQ6ICR7bmV3UHJvcGVydGllcy5qb2luKFwiLCBcIil9XG5cbkZpeDogU3RvcmUgeW91ciBkYXRhIGluIHRoaXMuZGF0YSBpbnN0ZWFkOlxuICBcXHUyNzRDIHRoaXMuJHtuZXdQcm9wZXJ0aWVzWzBdfSA9IHZhbHVlO1xuICBcXHUyNzA1IHRoaXMuZGF0YS4ke25ld1Byb3BlcnRpZXNbMF19ID0gdmFsdWU7YCk7XG4gICAgICB9XG4gICAgICB0aGlzLl9yZWFkeV9zdGF0ZSA9IDI7XG4gICAgICB0aGlzLl91cGRhdGVfZGVidWdfYXR0cnMoKTtcbiAgICAgIHRoaXMuX2xvZ19saWZlY3ljbGUoXCJsb2FkXCIsIFwiY29tcGxldGVcIik7XG4gICAgICB0aGlzLnRyaWdnZXIoXCJsb2FkXCIpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZWFkeSBwaGFzZSAtIENvbXBvbmVudCBmdWxseSBpbml0aWFsaXplZFxuICAgICAqIENhbGxlZCBib3R0b20tdXAgKGNoaWxkcmVuIGJlZm9yZSBwYXJlbnQpXG4gICAgICovXG4gICAgYXN5bmMgcmVhZHkoKSB7XG4gICAgICBpZiAodGhpcy5fc3RvcHBlZCB8fCB0aGlzLl9yZWFkeV9zdGF0ZSA+PSA0KVxuICAgICAgICByZXR1cm47XG4gICAgICB0aGlzLl9sb2dfbGlmZWN5Y2xlKFwicmVhZHlcIiwgXCJzdGFydFwiKTtcbiAgICAgIGF3YWl0IHRoaXMuX3dhaXRfZm9yX2NoaWxkcmVuX3JlYWR5KCk7XG4gICAgICBhd2FpdCB0aGlzLm9uX3JlYWR5KCk7XG4gICAgICB0aGlzLl9yZWFkeV9zdGF0ZSA9IDQ7XG4gICAgICB0aGlzLl91cGRhdGVfZGVidWdfYXR0cnMoKTtcbiAgICAgIHRoaXMuX2xvZ19saWZlY3ljbGUoXCJyZWFkeVwiLCBcImNvbXBsZXRlXCIpO1xuICAgICAgdGhpcy50cmlnZ2VyKFwicmVhZHlcIik7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFdhaXQgZm9yIGFsbCBjaGlsZCBjb21wb25lbnRzIHRvIHJlYWNoIHJlYWR5IHN0YXRlXG4gICAgICogRW5zdXJlcyBib3R0b20tdXAgb3JkZXJpbmcgKGNoaWxkcmVuIHJlYWR5IGJlZm9yZSBwYXJlbnQpXG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cbiAgICBhc3luYyBfd2FpdF9mb3JfY2hpbGRyZW5fcmVhZHkoKSB7XG4gICAgICBjb25zdCBjaGlsZHJlbiA9IHRoaXMuX2dldF9kb21fY2hpbGRyZW4oKTtcbiAgICAgIGlmIChjaGlsZHJlbi5sZW5ndGggPT09IDApIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgY29uc3QgcmVhZHlfcHJvbWlzZXMgPSBbXTtcbiAgICAgIGZvciAoY29uc3QgY2hpbGQgb2YgY2hpbGRyZW4pIHtcbiAgICAgICAgaWYgKGNoaWxkLl9yZWFkeV9zdGF0ZSA+PSA0KSB7XG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgcmVhZHlfcHJvbWlzZSA9IG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PiB7XG4gICAgICAgICAgY2hpbGQub24oXCJyZWFkeVwiLCAoKSA9PiByZXNvbHZlKCkpO1xuICAgICAgICB9KTtcbiAgICAgICAgcmVhZHlfcHJvbWlzZXMucHVzaChyZWFkeV9wcm9taXNlKTtcbiAgICAgIH1cbiAgICAgIGF3YWl0IFByb21pc2UuYWxsKHJlYWR5X3Byb21pc2VzKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmVpbml0aWFsaXplIHRoZSBjb21wb25lbnQgLSBmdWxsIHJlc2V0IGFuZCByZS1pbml0aWFsaXphdGlvblxuICAgICAqIFdpcGVzIHRoZSBpbm5lckhUTUwsIHJlc2V0cyBkYXRhIHRvIGVtcHR5LCBhbmQgcnVucyBmdWxsIGxpZmVjeWNsZVxuICAgICAqL1xuICAgIGFzeW5jIHJlaW5pdGlhbGl6ZSgpIHtcbiAgICAgIGlmICh0aGlzLl9zdG9wcGVkKVxuICAgICAgICByZXR1cm47XG4gICAgICB0aGlzLl9sb2dfbGlmZWN5Y2xlKFwicmVpbml0aWFsaXplXCIsIFwic3RhcnRcIik7XG4gICAgICB0aGlzLiRbMF0uaW5uZXJIVE1MID0gXCJcIjtcbiAgICAgIHRoaXMuZGF0YSA9IHt9O1xuICAgICAgdGhpcy5fcmVhZHlfc3RhdGUgPSAwO1xuICAgICAgdGhpcy5fZGF0YV9iZWZvcmVfcmVuZGVyID0gbnVsbDtcbiAgICAgIHRoaXMuX2RvbV9jaGlsZHJlbi5jbGVhcigpO1xuICAgICAgYXdhaXQgdGhpcy5fcmVuZGVyKCk7XG4gICAgICBhd2FpdCB0aGlzLmNyZWF0ZSgpO1xuICAgICAgYXdhaXQgdGhpcy5sb2FkKCk7XG4gICAgICBpZiAodGhpcy5zaG91bGRfcmVyZW5kZXIoKSkge1xuICAgICAgICBhd2FpdCB0aGlzLl9yZW5kZXIoKTtcbiAgICAgIH1cbiAgICAgIGF3YWl0IHRoaXMucmVhZHkoKTtcbiAgICAgIHRoaXMuX2xvZ19saWZlY3ljbGUoXCJyZWluaXRpYWxpemVcIiwgXCJjb21wbGV0ZVwiKTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogUmVsb2FkIGNvbXBvbmVudCAtIHJlLWZldGNoIGRhdGEgYW5kIHJlLXJlbmRlclxuICAgICAqIFJlLXJ1bnMgb25fbG9hZCgpLCBhbHdheXMgcmVuZGVycywgYW5kIGNhbGxzIG9uX3JlYWR5KClcbiAgICAgKi9cbiAgICBhc3luYyByZWxvYWQoKSB7XG4gICAgICBpZiAodGhpcy5fc3RvcHBlZClcbiAgICAgICAgcmV0dXJuO1xuICAgICAgdGhpcy5fbG9nX2xpZmVjeWNsZShcInJlbG9hZFwiLCBcInN0YXJ0XCIpO1xuICAgICAgY29uc3QgaGFzX2N1c3RvbV9vbl9sb2FkID0gdGhpcy5vbl9sb2FkICE9PSBfSnFodG1sX0NvbXBvbmVudC5wcm90b3R5cGUub25fbG9hZDtcbiAgICAgIGlmIChoYXNfY3VzdG9tX29uX2xvYWQpIHtcbiAgICAgICAgY29uc3QgYXJnc0JlZm9yZUxvYWQgPSBKU09OLnN0cmluZ2lmeSh0aGlzLmFyZ3MpO1xuICAgICAgICBjb25zdCBwcm9wZXJ0aWVzQmVmb3JlTG9hZCA9IG5ldyBTZXQoT2JqZWN0LmtleXModGhpcykpO1xuICAgICAgICB0aGlzLl9fbG9hZGluZyA9IHRydWU7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgYXdhaXQgdGhpcy5vbl9sb2FkKCk7XG4gICAgICAgIH0gZmluYWxseSB7XG4gICAgICAgICAgdGhpcy5fX2xvYWRpbmcgPSBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBhcmdzQWZ0ZXJMb2FkID0gSlNPTi5zdHJpbmdpZnkodGhpcy5hcmdzKTtcbiAgICAgICAgY29uc3QgcHJvcGVydGllc0FmdGVyTG9hZCA9IE9iamVjdC5rZXlzKHRoaXMpO1xuICAgICAgICBpZiAoYXJnc0JlZm9yZUxvYWQgIT09IGFyZ3NBZnRlckxvYWQpIHtcbiAgICAgICAgICBjb25zb2xlLmVycm9yKGBbSlFIVE1MXSBXQVJOSU5HOiBDb21wb25lbnQgXCIke3RoaXMuY29tcG9uZW50X25hbWUoKX1cIiBtb2RpZmllZCB0aGlzLmFyZ3MgaW4gb25fbG9hZCgpLlxub25fbG9hZCgpIHNob3VsZCBPTkxZIG1vZGlmeSB0aGlzLmRhdGEuIFRoZSB0aGlzLmFyZ3MgcHJvcGVydHkgaXMgcmVhZC1vbmx5LlxuXG5CZWZvcmU6ICR7YXJnc0JlZm9yZUxvYWR9XG5BZnRlcjogICR7YXJnc0FmdGVyTG9hZH1cblxuRml4OiBNb3ZlIHlvdXIgbW9kaWZpY2F0aW9ucyB0byB0aGlzLmRhdGEgaW5zdGVhZC5gKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBuZXdQcm9wZXJ0aWVzID0gcHJvcGVydGllc0FmdGVyTG9hZC5maWx0ZXIoKHByb3ApID0+ICFwcm9wZXJ0aWVzQmVmb3JlTG9hZC5oYXMocHJvcCkgJiYgcHJvcCAhPT0gXCJkYXRhXCIpO1xuICAgICAgICBpZiAobmV3UHJvcGVydGllcy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgY29uc29sZS5lcnJvcihgW0pRSFRNTF0gV0FSTklORzogQ29tcG9uZW50IFwiJHt0aGlzLmNvbXBvbmVudF9uYW1lKCl9XCIgYWRkZWQgbmV3IHByb3BlcnRpZXMgaW4gb25fbG9hZCgpLlxub25fbG9hZCgpIHNob3VsZCBPTkxZIG1vZGlmeSB0aGlzLmRhdGEuIE5ldyBwcm9wZXJ0aWVzIGRldGVjdGVkOiAke25ld1Byb3BlcnRpZXMuam9pbihcIiwgXCIpfVxuXG5GaXg6IFN0b3JlIHlvdXIgZGF0YSBpbiB0aGlzLmRhdGEgaW5zdGVhZDpcbiAgXFx1Mjc0QyB0aGlzLiR7bmV3UHJvcGVydGllc1swXX0gPSB2YWx1ZTtcbiAgXFx1MjcwNSB0aGlzLmRhdGEuJHtuZXdQcm9wZXJ0aWVzWzBdfSA9IHZhbHVlO2ApO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBhd2FpdCB0aGlzLnJlbmRlcigpO1xuICAgICAgdGhpcy5fbG9nX2xpZmVjeWNsZShcInJlbG9hZFwiLCBcImNvbXBsZXRlXCIpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBEZXN0cm95IHRoZSBjb21wb25lbnQgYW5kIGNsZWFudXBcbiAgICAgKiBDYWxsZWQgYXV0b21hdGljYWxseSBieSBNdXRhdGlvbk9ic2VydmVyIHdoZW4gY29tcG9uZW50IGlzIHJlbW92ZWQgZnJvbSBET01cbiAgICAgKiBDYW4gYWxzbyBiZSBjYWxsZWQgbWFudWFsbHkgZm9yIGV4cGxpY2l0IGNsZWFudXBcbiAgICAgKi9cbiAgICAvKipcbiAgICAgKiBJbnRlcm5hbCBzdG9wIG1ldGhvZCAtIHN0b3BzIGp1c3QgdGhpcyBjb21wb25lbnQgKG5vIGNoaWxkcmVuKVxuICAgICAqIFNldHMgc3RvcHBlZCBmbGFnLCBjYWxscyBsaWZlY3ljbGUgaG9va3MsIGJ1dCBsZWF2ZXMgRE9NIGludGFjdFxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG4gICAgX3N0b3AoKSB7XG4gICAgICBpZiAodGhpcy5fc3RvcHBlZClcbiAgICAgICAgcmV0dXJuO1xuICAgICAgdGhpcy5fc3RvcHBlZCA9IHRydWU7XG4gICAgICBjb25zdCBoYXNfY3VzdG9tX2Rlc3Ryb3kgPSB0aGlzLm9uX2Rlc3Ryb3kgIT09IF9KcWh0bWxfQ29tcG9uZW50LnByb3RvdHlwZS5vbl9kZXN0cm95O1xuICAgICAgY29uc3QgaGFzX2Rlc3Ryb3lfY2FsbGJhY2tzID0gdGhpcy5fb25fcmVnaXN0ZXJlZChcImRlc3Ryb3lcIik7XG4gICAgICBpZiAoIWhhc19jdXN0b21fZGVzdHJveSAmJiAhaGFzX2Rlc3Ryb3lfY2FsbGJhY2tzKSB7XG4gICAgICAgIHRoaXMuX2xpZmVjeWNsZV9tYW5hZ2VyLnVucmVnaXN0ZXJfY29tcG9uZW50KHRoaXMpO1xuICAgICAgICB0aGlzLl9yZWFkeV9zdGF0ZSA9IDk5O1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICB0aGlzLl9sb2dfbGlmZWN5Y2xlKFwiZGVzdHJveVwiLCBcInN0YXJ0XCIpO1xuICAgICAgdGhpcy4kLmFkZENsYXNzKFwiX0NvbXBvbmVudF9TdG9wcGVkXCIpO1xuICAgICAgdGhpcy5fbGlmZWN5Y2xlX21hbmFnZXIudW5yZWdpc3Rlcl9jb21wb25lbnQodGhpcyk7XG4gICAgICBjb25zdCBkZXN0cm95UmVzdWx0ID0gdGhpcy5vbl9kZXN0cm95KCk7XG4gICAgICBpZiAoZGVzdHJveVJlc3VsdCAmJiB0eXBlb2YgZGVzdHJveVJlc3VsdC50aGVuID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgY29uc29sZS53YXJuKGBbSlFIVE1MXSBDb21wb25lbnQgXCIke3RoaXMuY29tcG9uZW50X25hbWUoKX1cIiByZXR1cm5lZCBhIFByb21pc2UgZnJvbSBvbl9kZXN0cm95KCkuIG9uX2Rlc3Ryb3koKSBtdXN0IGJlIHN5bmNocm9ub3VzIGNvZGUuIFJlbW92ZSAnYXN5bmMnIGZyb20gdGhlIGZ1bmN0aW9uIGRlY2xhcmF0aW9uLmApO1xuICAgICAgfVxuICAgICAgdGhpcy50cmlnZ2VyKFwiZGVzdHJveVwiKTtcbiAgICAgIHRoaXMuJC50cmlnZ2VyKFwiZGVzdHJveVwiKTtcbiAgICAgIGlmICh0aGlzLl9kb21fcGFyZW50KSB7XG4gICAgICAgIHRoaXMuX2RvbV9wYXJlbnQuX2RvbV9jaGlsZHJlbi5kZWxldGUodGhpcyk7XG4gICAgICB9XG4gICAgICB0aGlzLl9yZWFkeV9zdGF0ZSA9IDk5O1xuICAgICAgdGhpcy5fdXBkYXRlX2RlYnVnX2F0dHJzKCk7XG4gICAgICB0aGlzLl9sb2dfbGlmZWN5Y2xlKFwiZGVzdHJveVwiLCBcImNvbXBsZXRlXCIpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBTdG9wIGNvbXBvbmVudCBsaWZlY3ljbGUgLSBzdG9wcyBhbGwgZGVzY2VuZGFudCBjb21wb25lbnRzIHRoZW4gc2VsZlxuICAgICAqIExlYXZlcyBET00gaW50YWN0LCBqdXN0IHN0b3BzIGxpZmVjeWNsZSBlbmdpbmUgYW5kIGZpcmVzIGNsZWFudXAgaG9va3NcbiAgICAgKi9cbiAgICBzdG9wKCkge1xuICAgICAgdGhpcy4kLmZpbmQoXCIuSnFodG1sX0NvbXBvbmVudFwiKS5lYWNoKGZ1bmN0aW9uKCkge1xuICAgICAgICBjb25zdCBjaGlsZCA9ICQodGhpcykuZGF0YShcIl9jb21wb25lbnRcIik7XG4gICAgICAgIGlmIChjaGlsZCAmJiAhY2hpbGQuX3N0b3BwZWQpIHtcbiAgICAgICAgICBjaGlsZC5fc3RvcCgpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIHRoaXMuX3N0b3AoKTtcbiAgICB9XG4gICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIC8vIE92ZXJyaWRhYmxlIExpZmVjeWNsZSBIb29rc1xuICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICBvbl9yZW5kZXIoKSB7XG4gICAgfVxuICAgIG9uX2NyZWF0ZSgpIHtcbiAgICB9XG4gICAgYXN5bmMgb25fbG9hZCgpIHtcbiAgICB9XG4gICAgYXN5bmMgb25fcmVhZHkoKSB7XG4gICAgfVxuICAgIG9uX2Rlc3Ryb3koKSB7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFNob3VsZCBjb21wb25lbnQgcmUtcmVuZGVyIGFmdGVyIGxvYWQ/XG4gICAgICogQnkgZGVmYXVsdCwgb25seSByZS1yZW5kZXJzIGlmIGRhdGEgaGFzIGNoYW5nZWRcbiAgICAgKiBPdmVycmlkZSB0byBjb250cm9sIHJlLXJlbmRlcmluZyBiZWhhdmlvclxuICAgICAqL1xuICAgIHNob3VsZF9yZXJlbmRlcigpIHtcbiAgICAgIGNvbnN0IGN1cnJlbnREYXRhU3RhdGUgPSBKU09OLnN0cmluZ2lmeSh0aGlzLmRhdGEpO1xuICAgICAgY29uc3QgZGF0YUNoYW5nZWQgPSB0aGlzLl9kYXRhX2JlZm9yZV9yZW5kZXIgIT09IGN1cnJlbnREYXRhU3RhdGU7XG4gICAgICBpZiAoZGF0YUNoYW5nZWQpIHtcbiAgICAgICAgdGhpcy5fZGF0YV9iZWZvcmVfcmVuZGVyID0gY3VycmVudERhdGFTdGF0ZTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBkYXRhQ2hhbmdlZDtcbiAgICB9XG4gICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIC8vIFB1YmxpYyBBUElcbiAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgLyoqXG4gICAgICogR2V0IGNvbXBvbmVudCBuYW1lIGZvciBkZWJ1Z2dpbmdcbiAgICAgKi9cbiAgICBjb21wb25lbnRfbmFtZSgpIHtcbiAgICAgIHJldHVybiB0aGlzLmNvbnN0cnVjdG9yLm5hbWU7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEVtaXQgYSBqUXVlcnkgZXZlbnQgZnJvbSBjb21wb25lbnQgcm9vdFxuICAgICAqL1xuICAgIGVtaXQoZXZlbnRfbmFtZSwgZGF0YSkge1xuICAgICAgdGhpcy5fbG9nX2RlYnVnKFwiZW1pdFwiLCBldmVudF9uYW1lLCBkYXRhKTtcbiAgICAgIHRoaXMuJC50cmlnZ2VyKGV2ZW50X25hbWUsIGRhdGEpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZWdpc3RlciBsaWZlY3ljbGUgZXZlbnQgY2FsbGJhY2tcbiAgICAgKiBBbGxvd2VkIGV2ZW50czogJ3JlbmRlcicsICdjcmVhdGUnLCAnbG9hZCcsICdyZWFkeScsICdkZXN0cm95J1xuICAgICAqIENhbGxiYWNrcyBmaXJlIGFmdGVyIHRoZSBsaWZlY3ljbGUgbWV0aG9kIGNvbXBsZXRlc1xuICAgICAqIElmIHRoZSBldmVudCBoYXMgYWxyZWFkeSBvY2N1cnJlZCwgdGhlIGNhbGxiYWNrIGZpcmVzIGltbWVkaWF0ZWx5IEFORCByZWdpc3RlcnMgZm9yIGZ1dHVyZSBvY2N1cnJlbmNlc1xuICAgICAqL1xuICAgIG9uKGV2ZW50X25hbWUsIGNhbGxiYWNrKSB7XG4gICAgICBjb25zdCBhbGxvd2VkX2V2ZW50cyA9IFtcInJlbmRlclwiLCBcImNyZWF0ZVwiLCBcImxvYWRcIiwgXCJyZWFkeVwiLCBcImRlc3Ryb3lcIl07XG4gICAgICBpZiAoIWFsbG93ZWRfZXZlbnRzLmluY2x1ZGVzKGV2ZW50X25hbWUpKSB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoYFtKUUhUTUxdIENvbXBvbmVudC5vbigpIG9ubHkgc3VwcG9ydHMgbGlmZWN5Y2xlIGV2ZW50czogJHthbGxvd2VkX2V2ZW50cy5qb2luKFwiLCBcIil9LiBSZWNlaXZlZDogJHtldmVudF9uYW1lfWApO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgIH1cbiAgICAgIGlmICghdGhpcy5fbGlmZWN5Y2xlX2NhbGxiYWNrcy5oYXMoZXZlbnRfbmFtZSkpIHtcbiAgICAgICAgdGhpcy5fbGlmZWN5Y2xlX2NhbGxiYWNrcy5zZXQoZXZlbnRfbmFtZSwgW10pO1xuICAgICAgfVxuICAgICAgdGhpcy5fbGlmZWN5Y2xlX2NhbGxiYWNrcy5nZXQoZXZlbnRfbmFtZSkucHVzaChjYWxsYmFjayk7XG4gICAgICBpZiAodGhpcy5fbGlmZWN5Y2xlX3N0YXRlcy5oYXMoZXZlbnRfbmFtZSkpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBjYWxsYmFjayh0aGlzKTtcbiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICBjb25zb2xlLmVycm9yKGBbSlFIVE1MXSBFcnJvciBpbiAke2V2ZW50X25hbWV9IGNhbGxiYWNrOmAsIGVycm9yKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFRyaWdnZXIgYSBsaWZlY3ljbGUgZXZlbnQgLSBmaXJlcyBhbGwgcmVnaXN0ZXJlZCBjYWxsYmFja3NcbiAgICAgKiBNYXJrcyBldmVudCBhcyBvY2N1cnJlZCBzbyBmdXR1cmUgLm9uKCkgY2FsbHMgZmlyZSBpbW1lZGlhdGVseVxuICAgICAqL1xuICAgIHRyaWdnZXIoZXZlbnRfbmFtZSkge1xuICAgICAgdGhpcy5fbGlmZWN5Y2xlX3N0YXRlcy5hZGQoZXZlbnRfbmFtZSk7XG4gICAgICBjb25zdCBjYWxsYmFja3MgPSB0aGlzLl9saWZlY3ljbGVfY2FsbGJhY2tzLmdldChldmVudF9uYW1lKTtcbiAgICAgIGlmIChjYWxsYmFja3MpIHtcbiAgICAgICAgZm9yIChjb25zdCBjYWxsYmFjayBvZiBjYWxsYmFja3MpIHtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgY2FsbGJhY2suYmluZCh0aGlzKSh0aGlzKTtcbiAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgY29uc29sZS5lcnJvcihgW0pRSFRNTF0gRXJyb3IgaW4gJHtldmVudF9uYW1lfSBjYWxsYmFjazpgLCBlcnJvcik7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIENoZWNrIGlmIGFueSBjYWxsYmFja3MgYXJlIHJlZ2lzdGVyZWQgZm9yIGEgZ2l2ZW4gZXZlbnRcbiAgICAgKiBVc2VkIHRvIGRldGVybWluZSBpZiBjbGVhbnVwIGxvZ2ljIG5lZWRzIHRvIHJ1blxuICAgICAqL1xuICAgIF9vbl9yZWdpc3RlcmVkKGV2ZW50X25hbWUpIHtcbiAgICAgIGNvbnN0IGNhbGxiYWNrcyA9IHRoaXMuX2xpZmVjeWNsZV9jYWxsYmFja3MuZ2V0KGV2ZW50X25hbWUpO1xuICAgICAgcmV0dXJuICEhKGNhbGxiYWNrcyAmJiBjYWxsYmFja3MubGVuZ3RoID4gMCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEZpbmQgZWxlbWVudCBieSBzY29wZWQgSURcbiAgICAgKlxuICAgICAqIFNlYXJjaGVzIGZvciBlbGVtZW50cyB3aXRoIGlkPVwibG9jYWxfaWQ6VEhJU19DT01QT05FTlRfQ0lEXCJcbiAgICAgKlxuICAgICAqIEV4YW1wbGU6XG4gICAgICogICBUZW1wbGF0ZTogPGJ1dHRvbiAkaWQ9XCJzYXZlX2J0blwiPlNhdmU8L2J1dHRvbj5cbiAgICAgKiAgIFJlbmRlcmVkOiA8YnV0dG9uIGlkPVwic2F2ZV9idG46YWJjMTIzXCIgZGF0YS1pZD1cInNhdmVfYnRuXCI+U2F2ZTwvYnV0dG9uPlxuICAgICAqICAgQWNjZXNzOiAgIHRoaXMuJGlkKCdzYXZlX2J0bicpICAvLyBSZXR1cm5zIGpRdWVyeSBlbGVtZW50XG4gICAgICpcbiAgICAgKiBQZXJmb3JtYW5jZTogVXNlcyBuYXRpdmUgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoKSB3aGVuIGNvbXBvbmVudCBpcyBpbiBET00sXG4gICAgICogZmFsbHMgYmFjayB0byBqUXVlcnkuZmluZCgpIGZvciBjb21wb25lbnRzIG5vdCB5ZXQgYXR0YWNoZWQgdG8gRE9NLlxuICAgICAqXG4gICAgICogQHBhcmFtIGxvY2FsX2lkIFRoZSBsb2NhbCBJRCAod2l0aG91dCBfY2lkIHN1ZmZpeClcbiAgICAgKiBAcmV0dXJucyBqUXVlcnkgZWxlbWVudCB3aXRoIGlkPVwibG9jYWxfaWQ6X2NpZFwiLCBvciBlbXB0eSBqUXVlcnkgb2JqZWN0IGlmIG5vdCBmb3VuZFxuICAgICAqL1xuICAgICRpZChsb2NhbF9pZCkge1xuICAgICAgY29uc3Qgc2NvcGVkSWQgPSBgJHtsb2NhbF9pZH06JHt0aGlzLl9jaWR9YDtcbiAgICAgIGNvbnN0IGVsID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoc2NvcGVkSWQpO1xuICAgICAgaWYgKGVsKSB7XG4gICAgICAgIHJldHVybiAkKGVsKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB0aGlzLiQuZmluZChgIyR7JC5lc2NhcGVTZWxlY3RvcihzY29wZWRJZCl9YCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldCBjb21wb25lbnQgaW5zdGFuY2UgYnkgc2NvcGVkIElEXG4gICAgICpcbiAgICAgKiBDb252ZW5pZW5jZSBtZXRob2QgdGhhdCBmaW5kcyBlbGVtZW50IGJ5IHNjb3BlZCBJRCBhbmQgcmV0dXJucyB0aGUgY29tcG9uZW50IGluc3RhbmNlLlxuICAgICAqXG4gICAgICogRXhhbXBsZTpcbiAgICAgKiAgIFRlbXBsYXRlOiA8VXNlcl9DYXJkICRpZD1cImFjdGl2ZV91c2VyXCIgLz5cbiAgICAgKiAgIEFjY2VzczogICBjb25zdCB1c2VyID0gdGhpcy5pZCgnYWN0aXZlX3VzZXInKTsgIC8vIFJldHVybnMgVXNlcl9DYXJkIGluc3RhbmNlXG4gICAgICogICAgICAgICAgICAgdXNlci5kYXRhLm5hbWUgIC8vIEFjY2VzcyBjb21wb25lbnQncyBkYXRhXG4gICAgICpcbiAgICAgKiBAcGFyYW0gbG9jYWxfaWQgVGhlIGxvY2FsIElEICh3aXRob3V0IF9jaWQgc3VmZml4KVxuICAgICAqIEByZXR1cm5zIENvbXBvbmVudCBpbnN0YW5jZSBvciBudWxsIGlmIG5vdCBmb3VuZCBvciBub3QgYSBjb21wb25lbnRcbiAgICAgKi9cbiAgICBpZChsb2NhbF9pZCkge1xuICAgICAgY29uc3QgZWxlbWVudCA9IHRoaXMuJGlkKGxvY2FsX2lkKTtcbiAgICAgIGNvbnN0IGNvbXBvbmVudCA9IGVsZW1lbnQuZGF0YShcIl9jb21wb25lbnRcIik7XG4gICAgICBpZiAoIWNvbXBvbmVudCAmJiBlbGVtZW50Lmxlbmd0aCA+IDApIHtcbiAgICAgICAgY29uc29sZS53YXJuKGBDb21wb25lbnQgJHt0aGlzLmNvbnN0cnVjdG9yLm5hbWV9IHRyaWVkIHRvIGNhbGwgLmlkKCcke2xvY2FsX2lkfScpIC0gJHtsb2NhbF9pZH0gZXhpc3RzLCBob3dldmVyLCBpdCBpcyBub3QgYSBjb21wb25lbnQgb3IgJHJlZHJhd2FibGUuIERpZCB5b3UgZm9yZ2V0IHRvIGFkZCAkcmVkcmF3YWJsZSB0byB0aGUgdGFnP2ApO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGNvbXBvbmVudCB8fCBudWxsO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBHZXQgdGhlIGNvbXBvbmVudCB0aGF0IGluc3RhbnRpYXRlZCB0aGlzIGNvbXBvbmVudCAocmVuZGVyZWQgaXQgaW4gdGhlaXIgdGVtcGxhdGUpXG4gICAgICogUmV0dXJucyBudWxsIGlmIGNvbXBvbmVudCB3YXMgY3JlYXRlZCBwcm9ncmFtbWF0aWNhbGx5IHZpYSAkKCkuY29tcG9uZW50KClcbiAgICAgKi9cbiAgICBpbnN0YW50aWF0b3IoKSB7XG4gICAgICByZXR1cm4gdGhpcy5faW5zdGFudGlhdG9yO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBGaW5kIGRlc2NlbmRhbnQgY29tcG9uZW50cyBieSBDU1Mgc2VsZWN0b3JcbiAgICAgKi9cbiAgICBmaW5kKHNlbGVjdG9yKSB7XG4gICAgICBjb25zdCBjb21wb25lbnRzID0gW107XG4gICAgICB0aGlzLiQuZmluZChzZWxlY3RvcikuZWFjaCgoXywgZWwpID0+IHtcbiAgICAgICAgY29uc3QgY29tcCA9ICQoZWwpLmRhdGEoXCJfY29tcG9uZW50XCIpO1xuICAgICAgICBpZiAoY29tcCBpbnN0YW5jZW9mIF9KcWh0bWxfQ29tcG9uZW50KSB7XG4gICAgICAgICAgY29tcG9uZW50cy5wdXNoKGNvbXApO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIHJldHVybiBjb21wb25lbnRzO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBGaW5kIGNsb3Nlc3QgYW5jZXN0b3IgY29tcG9uZW50IG1hdGNoaW5nIHNlbGVjdG9yXG4gICAgICovXG4gICAgY2xvc2VzdChzZWxlY3Rvcikge1xuICAgICAgbGV0IGN1cnJlbnQgPSB0aGlzLiQucGFyZW50KCk7XG4gICAgICB3aGlsZSAoY3VycmVudC5sZW5ndGggPiAwKSB7XG4gICAgICAgIGlmIChjdXJyZW50LmlzKHNlbGVjdG9yKSkge1xuICAgICAgICAgIGNvbnN0IGNvbXAgPSBjdXJyZW50LmRhdGEoXCJfY29tcG9uZW50XCIpO1xuICAgICAgICAgIGlmIChjb21wIGluc3RhbmNlb2YgX0pxaHRtbF9Db21wb25lbnQpIHtcbiAgICAgICAgICAgIHJldHVybiBjb21wO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBjdXJyZW50ID0gY3VycmVudC5wYXJlbnQoKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgLy8gU3RhdGljIE1ldGhvZHNcbiAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgLyoqXG4gICAgICogR2V0IENTUyBjbGFzcyBoaWVyYXJjaHkgZm9yIHRoaXMgY29tcG9uZW50IHR5cGVcbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0X2NsYXNzX2hpZXJhcmNoeSgpIHtcbiAgICAgIGNvbnN0IGNsYXNzZXMgPSBbXTtcbiAgICAgIGxldCBjdG9yID0gdGhpcztcbiAgICAgIHdoaWxlIChjdG9yKSB7XG4gICAgICAgIGlmICghY3Rvci5uYW1lIHx8IHR5cGVvZiBjdG9yLm5hbWUgIT09IFwic3RyaW5nXCIpIHtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICBpZiAoY3Rvci5uYW1lICE9PSBcIk9iamVjdFwiICYmIGN0b3IubmFtZSAhPT0gXCJcIikge1xuICAgICAgICAgIGxldCBub3JtYWxpemVkTmFtZSA9IGN0b3IubmFtZTtcbiAgICAgICAgICBpZiAobm9ybWFsaXplZE5hbWUgPT09IFwiX0pxaHRtbF9Db21wb25lbnRcIiB8fCBub3JtYWxpemVkTmFtZSA9PT0gXCJfQmFzZV9KcWh0bWxfQ29tcG9uZW50XCIpIHtcbiAgICAgICAgICAgIG5vcm1hbGl6ZWROYW1lID0gXCJKcWh0bWxfQ29tcG9uZW50XCI7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNsYXNzZXMucHVzaChub3JtYWxpemVkTmFtZSk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgbmV4dFByb3RvID0gT2JqZWN0LmdldFByb3RvdHlwZU9mKGN0b3IpO1xuICAgICAgICBpZiAoIW5leHRQcm90byB8fCBuZXh0UHJvdG8gPT09IE9iamVjdC5wcm90b3R5cGUgfHwgbmV4dFByb3RvLmNvbnN0cnVjdG9yID09PSBPYmplY3QpIHtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICBjdG9yID0gbmV4dFByb3RvO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGNsYXNzZXM7XG4gICAgfVxuICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAvLyBQcml2YXRlIEltcGxlbWVudGF0aW9uXG4gICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIF9nZW5lcmF0ZV9jaWQoKSB7XG4gICAgICByZXR1cm4gdWlkKCk7XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEZsYXR0ZW4gaW5zdHJ1Y3Rpb24gYXJyYXkgLSBjb252ZXJ0cyBbJ19jb250ZW50JywgWy4uLl1dIG1hcmtlcnMgdG8gZmxhdCBhcnJheVxuICAgICAqIFJlY3Vyc2l2ZWx5IGZsYXR0ZW5zIG5lc3RlZCBjb250ZW50IGZyb20gY29udGVudCgpIGNhbGxzXG4gICAgICovXG4gICAgX2ZsYXR0ZW5faW5zdHJ1Y3Rpb25zKGluc3RydWN0aW9ucykge1xuICAgICAgY29uc3QgcmVzdWx0ID0gW107XG4gICAgICBmb3IgKGNvbnN0IGluc3RydWN0aW9uIG9mIGluc3RydWN0aW9ucykge1xuICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShpbnN0cnVjdGlvbikgJiYgaW5zdHJ1Y3Rpb25bMF0gPT09IFwiX2NvbnRlbnRcIiAmJiBBcnJheS5pc0FycmF5KGluc3RydWN0aW9uWzFdKSkge1xuICAgICAgICAgIGNvbnN0IGNvbnRlbnRJbnN0cnVjdGlvbnMgPSB0aGlzLl9mbGF0dGVuX2luc3RydWN0aW9ucyhpbnN0cnVjdGlvblsxXSk7XG4gICAgICAgICAgcmVzdWx0LnB1c2goLi4uY29udGVudEluc3RydWN0aW9ucyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmVzdWx0LnB1c2goaW5zdHJ1Y3Rpb24pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cbiAgICBfYXBwbHlfY3NzX2NsYXNzZXMoKSB7XG4gICAgICBjb25zdCBoaWVyYXJjaHkgPSB0aGlzLmNvbnN0cnVjdG9yLmdldF9jbGFzc19oaWVyYXJjaHkoKTtcbiAgICAgIGNvbnN0IGNsYXNzZXNUb0FkZCA9IFsuLi5oaWVyYXJjaHldO1xuICAgICAgaWYgKHRoaXMuYXJncy5fY29tcG9uZW50X25hbWUgJiYgdGhpcy5hcmdzLl9jb21wb25lbnRfbmFtZSAhPT0gdGhpcy5jb25zdHJ1Y3Rvci5uYW1lKSB7XG4gICAgICAgIGNsYXNzZXNUb0FkZC51bnNoaWZ0KHRoaXMuYXJncy5fY29tcG9uZW50X25hbWUpO1xuICAgICAgfVxuICAgICAgY29uc3QgcHVibGljQ2xhc3NlcyA9IGNsYXNzZXNUb0FkZC5maWx0ZXIoKGNsYXNzTmFtZSkgPT4ge1xuICAgICAgICBpZiAoIWNsYXNzTmFtZSB8fCB0eXBlb2YgY2xhc3NOYW1lICE9PSBcInN0cmluZ1wiKSB7XG4gICAgICAgICAgY29uc29sZS53YXJuKFwiW0pRSFRNTF0gRmlsdGVyZWQgb3V0IGludmFsaWQgY2xhc3MgbmFtZTpcIiwgY2xhc3NOYW1lKTtcbiAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuICFjbGFzc05hbWUuc3RhcnRzV2l0aChcIl9cIik7XG4gICAgICB9KTtcbiAgICAgIGlmIChwdWJsaWNDbGFzc2VzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgdGhpcy4kLmFkZENsYXNzKHB1YmxpY0NsYXNzZXMuam9pbihcIiBcIikpO1xuICAgICAgfVxuICAgIH1cbiAgICBfYXBwbHlfZGVmYXVsdF9hdHRyaWJ1dGVzKCkge1xuICAgICAgbGV0IHRlbXBsYXRlO1xuICAgICAgaWYgKHRoaXMuYXJncy5fY29tcG9uZW50X25hbWUpIHtcbiAgICAgICAgdGVtcGxhdGUgPSBnZXRfdGVtcGxhdGUodGhpcy5hcmdzLl9jb21wb25lbnRfbmFtZSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0ZW1wbGF0ZSA9IGdldF90ZW1wbGF0ZV9ieV9jbGFzcyh0aGlzLmNvbnN0cnVjdG9yKTtcbiAgICAgIH1cbiAgICAgIGlmICh0ZW1wbGF0ZSAmJiB0ZW1wbGF0ZS5kZWZhdWx0QXR0cmlidXRlcykge1xuICAgICAgICBjb25zdCBkZWZpbmVBdHRycyA9IHsgLi4udGVtcGxhdGUuZGVmYXVsdEF0dHJpYnV0ZXMgfTtcbiAgICAgICAgZGVsZXRlIGRlZmluZUF0dHJzLnRhZztcbiAgICAgICAgaWYgKHdpbmRvdy5qcWh0bWw/LmRlYnVnPy5lbmFibGVkKSB7XG4gICAgICAgICAgY29uc3QgY29tcG9uZW50TmFtZSA9IHRlbXBsYXRlLm5hbWUgfHwgdGhpcy5hcmdzLl9jb21wb25lbnRfbmFtZSB8fCB0aGlzLmNvbnN0cnVjdG9yLm5hbWU7XG4gICAgICAgICAgY29uc29sZS5sb2coYFtDb21wb25lbnRdIEFwcGx5aW5nIGRlZmF1bHRBdHRyaWJ1dGVzIGZvciAke2NvbXBvbmVudE5hbWV9OmAsIGRlZmluZUF0dHJzKTtcbiAgICAgICAgfVxuICAgICAgICBmb3IgKGNvbnN0IFtrZXksIHZhbHVlXSBvZiBPYmplY3QuZW50cmllcyhkZWZpbmVBdHRycykpIHtcbiAgICAgICAgICBpZiAoa2V5ID09PSBcImNsYXNzXCIpIHtcbiAgICAgICAgICAgIGNvbnN0IGV4aXN0aW5nQ2xhc3NlcyA9IHRoaXMuJC5hdHRyKFwiY2xhc3NcIik7XG4gICAgICAgICAgICBpZiAoZXhpc3RpbmdDbGFzc2VzKSB7XG4gICAgICAgICAgICAgIGNvbnN0IGV4aXN0aW5nID0gZXhpc3RpbmdDbGFzc2VzLnNwbGl0KC9cXHMrLykuZmlsdGVyKChjKSA9PiBjKTtcbiAgICAgICAgICAgICAgY29uc3QgbmV3Q2xhc3NlcyA9IFN0cmluZyh2YWx1ZSkuc3BsaXQoL1xccysvKS5maWx0ZXIoKGMpID0+IGMpO1xuICAgICAgICAgICAgICBmb3IgKGNvbnN0IG5ld0NsYXNzIG9mIG5ld0NsYXNzZXMpIHtcbiAgICAgICAgICAgICAgICBpZiAoIWV4aXN0aW5nLmluY2x1ZGVzKG5ld0NsYXNzKSkge1xuICAgICAgICAgICAgICAgICAgZXhpc3RpbmcucHVzaChuZXdDbGFzcyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIHRoaXMuJC5hdHRyKFwiY2xhc3NcIiwgZXhpc3Rpbmcuam9pbihcIiBcIikpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgdGhpcy4kLmF0dHIoXCJjbGFzc1wiLCB2YWx1ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBlbHNlIGlmIChrZXkgPT09IFwic3R5bGVcIikge1xuICAgICAgICAgICAgY29uc3QgZXhpc3RpbmdTdHlsZSA9IHRoaXMuJC5hdHRyKFwic3R5bGVcIik7XG4gICAgICAgICAgICBpZiAoZXhpc3RpbmdTdHlsZSkge1xuICAgICAgICAgICAgICBjb25zdCBleGlzdGluZ1J1bGVzID0gLyogQF9fUFVSRV9fICovIG5ldyBNYXAoKTtcbiAgICAgICAgICAgICAgZXhpc3RpbmdTdHlsZS5zcGxpdChcIjtcIikuZm9yRWFjaCgocnVsZSkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IFtwcm9wLCB2YWxdID0gcnVsZS5zcGxpdChcIjpcIikubWFwKChzKSA9PiBzLnRyaW0oKSk7XG4gICAgICAgICAgICAgICAgaWYgKHByb3AgJiYgdmFsKVxuICAgICAgICAgICAgICAgICAgZXhpc3RpbmdSdWxlcy5zZXQocHJvcCwgdmFsKTtcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgIFN0cmluZyh2YWx1ZSkuc3BsaXQoXCI7XCIpLmZvckVhY2goKHJ1bGUpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBbcHJvcCwgdmFsXSA9IHJ1bGUuc3BsaXQoXCI6XCIpLm1hcCgocykgPT4gcy50cmltKCkpO1xuICAgICAgICAgICAgICAgIGlmIChwcm9wICYmIHZhbClcbiAgICAgICAgICAgICAgICAgIGV4aXN0aW5nUnVsZXMuc2V0KHByb3AsIHZhbCk7XG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICBjb25zdCBtZXJnZWQgPSBBcnJheS5mcm9tKGV4aXN0aW5nUnVsZXMuZW50cmllcygpKS5tYXAoKFtwcm9wLCB2YWxdKSA9PiBgJHtwcm9wfTogJHt2YWx9YCkuam9pbihcIjsgXCIpO1xuICAgICAgICAgICAgICB0aGlzLiQuYXR0cihcInN0eWxlXCIsIG1lcmdlZCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICB0aGlzLiQuYXR0cihcInN0eWxlXCIsIHZhbHVlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2UgaWYgKGtleS5zdGFydHNXaXRoKFwiJFwiKSB8fCBrZXkuc3RhcnRzV2l0aChcImRhdGEtXCIpKSB7XG4gICAgICAgICAgICBjb25zdCBkYXRhS2V5ID0ga2V5LnN0YXJ0c1dpdGgoXCIkXCIpID8ga2V5LnN1YnN0cmluZygxKSA6IGtleS5zdGFydHNXaXRoKFwiZGF0YS1cIikgPyBrZXkuc3Vic3RyaW5nKDUpIDoga2V5O1xuICAgICAgICAgICAgaWYgKCEoZGF0YUtleSBpbiB0aGlzLmFyZ3MpKSB7XG4gICAgICAgICAgICAgIHRoaXMuYXJnc1tkYXRhS2V5XSA9IHZhbHVlO1xuICAgICAgICAgICAgICB0aGlzLiQuZGF0YShkYXRhS2V5LCB2YWx1ZSk7XG4gICAgICAgICAgICAgIHRoaXMuJC5hdHRyKGtleS5zdGFydHNXaXRoKFwiJFwiKSA/IGBkYXRhLSR7ZGF0YUtleX1gIDoga2V5LCBTdHJpbmcodmFsdWUpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaWYgKCF0aGlzLiQuYXR0cihrZXkpKSB7XG4gICAgICAgICAgICAgIHRoaXMuJC5hdHRyKGtleSwgdmFsdWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICBfc2V0X2F0dHJpYnV0ZXMoKSB7XG4gICAgICB0aGlzLiQuYXR0cihcImRhdGEtY2lkXCIsIHRoaXMuX2NpZCk7XG4gICAgICBpZiAod2luZG93LmpxaHRtbD8uZGVidWc/LnZlcmJvc2UpIHtcbiAgICAgICAgdGhpcy4kLmF0dHIoXCJkYXRhLV9saWZlY3ljbGUtc3RhdGVcIiwgdGhpcy5fcmVhZHlfc3RhdGUudG9TdHJpbmcoKSk7XG4gICAgICB9XG4gICAgfVxuICAgIF91cGRhdGVfZGVidWdfYXR0cnMoKSB7XG4gICAgICBpZiAod2luZG93LmpxaHRtbD8uZGVidWc/LnZlcmJvc2UpIHtcbiAgICAgICAgdGhpcy4kLmF0dHIoXCJkYXRhLV9saWZlY3ljbGUtc3RhdGVcIiwgdGhpcy5fcmVhZHlfc3RhdGUudG9TdHJpbmcoKSk7XG4gICAgICB9XG4gICAgfVxuICAgIF9maW5kX2RvbV9wYXJlbnQoKSB7XG4gICAgICBsZXQgY3VycmVudCA9IHRoaXMuJC5wYXJlbnQoKTtcbiAgICAgIHdoaWxlIChjdXJyZW50Lmxlbmd0aCA+IDApIHtcbiAgICAgICAgY29uc3QgcGFyZW50ID0gY3VycmVudC5kYXRhKFwiX2NvbXBvbmVudFwiKTtcbiAgICAgICAgaWYgKHBhcmVudCBpbnN0YW5jZW9mIF9KcWh0bWxfQ29tcG9uZW50KSB7XG4gICAgICAgICAgdGhpcy5fZG9tX3BhcmVudCA9IHBhcmVudDtcbiAgICAgICAgICBwYXJlbnQuX2RvbV9jaGlsZHJlbi5hZGQodGhpcyk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgY3VycmVudCA9IGN1cnJlbnQucGFyZW50KCk7XG4gICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEdldCBET00gY2hpbGRyZW4gKGNvbXBvbmVudHMgaW4gRE9NIHN1YnRyZWUpXG4gICAgICogVXNlcyBmYXN0IF9kb21fY2hpbGRyZW4gcmVnaXN0cnkgd2hlbiBwb3NzaWJsZSwgZmFsbHMgYmFjayB0byBET00gdHJhdmVyc2FsIGZvciBvZmYtRE9NIGNvbXBvbmVudHNcbiAgICAgKiBAcHJpdmF0ZSAtIFVzZWQgaW50ZXJuYWxseSBmb3IgbGlmZWN5Y2xlIGNvb3JkaW5hdGlvblxuICAgICAqL1xuICAgIF9nZXRfZG9tX2NoaWxkcmVuKCkge1xuICAgICAgaWYgKHRoaXMuX3VzZV9kb21fZmFsbGJhY2spIHtcbiAgICAgICAgY29uc3QgZGlyZWN0Q2hpbGRyZW4gPSBbXTtcbiAgICAgICAgdGhpcy4kLmZpbmQoXCIuSnFodG1sX0NvbXBvbmVudFwiKS5lYWNoKChfLCBlbCkgPT4ge1xuICAgICAgICAgIGNvbnN0ICRlbCA9ICQoZWwpO1xuICAgICAgICAgIGNvbnN0IGNvbXAgPSAkZWwuZGF0YShcIl9jb21wb25lbnRcIik7XG4gICAgICAgICAgaWYgKGNvbXAgaW5zdGFuY2VvZiBfSnFodG1sX0NvbXBvbmVudCkge1xuICAgICAgICAgICAgY29uc3QgY2xvc2VzdFBhcmVudCA9ICRlbC5wYXJlbnQoKS5jbG9zZXN0KFwiLkpxaHRtbF9Db21wb25lbnRcIik7XG4gICAgICAgICAgICBpZiAoY2xvc2VzdFBhcmVudC5sZW5ndGggPT09IDAgfHwgY2xvc2VzdFBhcmVudC5kYXRhKFwiX2NvbXBvbmVudFwiKSA9PT0gdGhpcykge1xuICAgICAgICAgICAgICBkaXJlY3RDaGlsZHJlbi5wdXNoKGNvbXApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiBkaXJlY3RDaGlsZHJlbjtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGNoaWxkcmVuID0gQXJyYXkuZnJvbSh0aGlzLl9kb21fY2hpbGRyZW4pO1xuICAgICAgcmV0dXJuIGNoaWxkcmVuLmZpbHRlcigoY2hpbGQpID0+IHtcbiAgICAgICAgcmV0dXJuICQuY29udGFpbnMoZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LCBjaGlsZC4kWzBdKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgICBfbG9nX2xpZmVjeWNsZShwaGFzZSwgc3RhdHVzKSB7XG4gICAgICBsb2dMaWZlY3ljbGUodGhpcywgcGhhc2UsIHN0YXR1cyk7XG4gICAgICBpZiAodHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiAmJiB3aW5kb3cuSlFIVE1MX0RFQlVHKSB7XG4gICAgICAgIHdpbmRvdy5KUUhUTUxfREVCVUcubG9nKHRoaXMuY29tcG9uZW50X25hbWUoKSwgcGhhc2UsIHN0YXR1cywge1xuICAgICAgICAgIGNpZDogdGhpcy5fY2lkLFxuICAgICAgICAgIHJlYWR5X3N0YXRlOiB0aGlzLl9yZWFkeV9zdGF0ZSxcbiAgICAgICAgICBhcmdzOiB0aGlzLmFyZ3NcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuICAgIF9sb2dfZGVidWcoYWN0aW9uLCAuLi5hcmdzKSB7XG4gICAgICBpZiAodHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiAmJiB3aW5kb3cuSlFIVE1MX0RFQlVHKSB7XG4gICAgICAgIHdpbmRvdy5KUUhUTUxfREVCVUcubG9nKHRoaXMuY29tcG9uZW50X25hbWUoKSwgXCJkZWJ1Z1wiLCBgJHthY3Rpb259OiAke2FyZ3MubWFwKChhKSA9PiBKU09OLnN0cmluZ2lmeShhKSkuam9pbihcIiwgXCIpfWApO1xuICAgICAgfVxuICAgIH1cbiAgfTtcbiAgYXN5bmMgZnVuY3Rpb24gcHJvY2Vzc19zbG90X2luaGVyaXRhbmNlKGNvbXBvbmVudCwgY2hpbGRTbG90cykge1xuICAgIGxldCBjdXJyZW50Q2xhc3MgPSBPYmplY3QuZ2V0UHJvdG90eXBlT2YoY29tcG9uZW50LmNvbnN0cnVjdG9yKTtcbiAgICBjb25zb2xlLmxvZyhgW0pRSFRNTF0gV2Fsa2luZyBwcm90b3R5cGUgY2hhaW4gZm9yICR7Y29tcG9uZW50LmNvbnN0cnVjdG9yLm5hbWV9YCk7XG4gICAgd2hpbGUgKGN1cnJlbnRDbGFzcyAmJiBjdXJyZW50Q2xhc3MgIT09IEpxaHRtbF9Db21wb25lbnQgJiYgY3VycmVudENsYXNzLm5hbWUgIT09IFwiT2JqZWN0XCIpIHtcbiAgICAgIGNvbnN0IGNsYXNzTmFtZSA9IGN1cnJlbnRDbGFzcy5uYW1lO1xuICAgICAgY29uc29sZS5sb2coYFtKUUhUTUxdICAgQ2hlY2tpbmcgcGFyZW50IGNsYXNzOiAke2NsYXNzTmFtZX1gKTtcbiAgICAgIGlmIChjbGFzc05hbWUgPT09IFwiX0pxaHRtbF9Db21wb25lbnRcIiB8fCBjbGFzc05hbWUgPT09IFwiX0Jhc2VfSnFodG1sX0NvbXBvbmVudFwiKSB7XG4gICAgICAgIGN1cnJlbnRDbGFzcyA9IE9iamVjdC5nZXRQcm90b3R5cGVPZihjdXJyZW50Q2xhc3MpO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHBhcmVudFRlbXBsYXRlID0gZ2V0X3RlbXBsYXRlKGNsYXNzTmFtZSk7XG4gICAgICAgIGNvbnNvbGUubG9nKGBbSlFIVE1MXSAgIFRlbXBsYXRlIGZvdW5kIGZvciAke2NsYXNzTmFtZX06YCwgcGFyZW50VGVtcGxhdGUgPyBwYXJlbnRUZW1wbGF0ZS5uYW1lIDogXCJudWxsXCIpO1xuICAgICAgICBpZiAocGFyZW50VGVtcGxhdGUgJiYgcGFyZW50VGVtcGxhdGUubmFtZSAhPT0gXCJKcWh0bWxfQ29tcG9uZW50XCIpIHtcbiAgICAgICAgICBjb25zb2xlLmxvZyhgW0pRSFRNTF0gICBJbnZva2luZyBwYXJlbnQgdGVtcGxhdGUgJHtjbGFzc05hbWV9YCk7XG4gICAgICAgICAgY29uc3QgW3BhcmVudEluc3RydWN0aW9ucywgcGFyZW50Q29udGV4dF0gPSBwYXJlbnRUZW1wbGF0ZS5yZW5kZXIuY2FsbChcbiAgICAgICAgICAgIGNvbXBvbmVudCxcbiAgICAgICAgICAgIGNvbXBvbmVudC5kYXRhLFxuICAgICAgICAgICAgY29tcG9uZW50LmFyZ3MsXG4gICAgICAgICAgICBjaGlsZFNsb3RzXG4gICAgICAgICAgICAvLyBQYXNzIGNoaWxkIHNsb3RzIGFzIGNvbnRlbnQgcGFyYW1ldGVyXG4gICAgICAgICAgKTtcbiAgICAgICAgICBpZiAocGFyZW50SW5zdHJ1Y3Rpb25zICYmIHR5cGVvZiBwYXJlbnRJbnN0cnVjdGlvbnMgPT09IFwib2JqZWN0XCIgJiYgcGFyZW50SW5zdHJ1Y3Rpb25zLl9zbG90cykge1xuICAgICAgICAgICAgY29uc29sZS5sb2coYFtKUUhUTUxdICAgUGFyZW50IGFsc28gc2xvdC1vbmx5LCByZWN1cnNpbmdgKTtcbiAgICAgICAgICAgIHJldHVybiBhd2FpdCBwcm9jZXNzX3Nsb3RfaW5oZXJpdGFuY2UoY29tcG9uZW50LCBwYXJlbnRJbnN0cnVjdGlvbnMuX3Nsb3RzKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgY29uc29sZS5sb2coYFtKUUhUTUxdICAgUGFyZW50IHJldHVybmVkIGluc3RydWN0aW9ucywgaW5oZXJpdGFuY2UgY29tcGxldGVgKTtcbiAgICAgICAgICByZXR1cm4gW3BhcmVudEluc3RydWN0aW9ucywgcGFyZW50Q29udGV4dF07XG4gICAgICAgIH1cbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIGNvbnNvbGUud2FybihgW0pRSFRNTF0gRXJyb3IgbG9va2luZyB1cCBwYXJlbnQgdGVtcGxhdGUgZm9yICR7Y2xhc3NOYW1lfTpgLCBlcnJvcik7XG4gICAgICB9XG4gICAgICBjdXJyZW50Q2xhc3MgPSBPYmplY3QuZ2V0UHJvdG90eXBlT2YoY3VycmVudENsYXNzKTtcbiAgICB9XG4gICAgY29uc29sZS53YXJuKGBbSlFIVE1MXSBObyBwYXJlbnQgdGVtcGxhdGUgZm91bmQgYWZ0ZXIgd2Fsa2luZyBjaGFpbmApO1xuICAgIHJldHVybiBudWxsO1xuICB9XG4gIGFzeW5jIGZ1bmN0aW9uIHJlbmRlcl90ZW1wbGF0ZShjb21wb25lbnQsIHRlbXBsYXRlX2ZuKSB7XG4gICAgbGV0IHJlbmRlcl9mbiA9IHRlbXBsYXRlX2ZuO1xuICAgIGlmICghcmVuZGVyX2ZuKSB7XG4gICAgICBjb25zdCB0ZW1wbGF0ZV9kZWYgPSBnZXRfdGVtcGxhdGVfYnlfY2xhc3MoY29tcG9uZW50LmNvbnN0cnVjdG9yKTtcbiAgICAgIHJlbmRlcl9mbiA9IHRlbXBsYXRlX2RlZi5yZW5kZXI7XG4gICAgfVxuICAgIGlmICghcmVuZGVyX2ZuKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbXBvbmVudC4kLmVtcHR5KCk7XG4gICAgY29uc3QgZGVmYXVsdENvbnRlbnQgPSAoKSA9PiBcIlwiO1xuICAgIGxldCBbaW5zdHJ1Y3Rpb25zLCBjb250ZXh0XSA9IHJlbmRlcl9mbi5jYWxsKFxuICAgICAgY29tcG9uZW50LFxuICAgICAgY29tcG9uZW50LmRhdGEsXG4gICAgICBjb21wb25lbnQuYXJncyxcbiAgICAgIGRlZmF1bHRDb250ZW50XG4gICAgICAvLyBEZWZhdWx0IGNvbnRlbnQgZnVuY3Rpb24gdGhhdCByZXR1cm5zIGVtcHR5IHN0cmluZ1xuICAgICk7XG4gICAgaWYgKGluc3RydWN0aW9ucyAmJiB0eXBlb2YgaW5zdHJ1Y3Rpb25zID09PSBcIm9iamVjdFwiICYmIGluc3RydWN0aW9ucy5fc2xvdHMpIHtcbiAgICAgIGNvbnNvbGUubG9nKGBbSlFIVE1MXSBTbG90LW9ubHkgdGVtcGxhdGUgZGV0ZWN0ZWQgZm9yICR7Y29tcG9uZW50LmNvbnN0cnVjdG9yLm5hbWV9LCBpbnZva2luZyBpbmhlcml0YW5jZWApO1xuICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgcHJvY2Vzc19zbG90X2luaGVyaXRhbmNlKGNvbXBvbmVudCwgaW5zdHJ1Y3Rpb25zLl9zbG90cyk7XG4gICAgICBpZiAocmVzdWx0KSB7XG4gICAgICAgIGNvbnNvbGUubG9nKGBbSlFIVE1MXSBQYXJlbnQgdGVtcGxhdGUgZm91bmQsIHVzaW5nIHBhcmVudCBpbnN0cnVjdGlvbnNgKTtcbiAgICAgICAgaW5zdHJ1Y3Rpb25zID0gcmVzdWx0WzBdO1xuICAgICAgICBjb250ZXh0ID0gcmVzdWx0WzFdO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc29sZS53YXJuKGBbSlFIVE1MXSBObyBwYXJlbnQgdGVtcGxhdGUgZm91bmQgZm9yICR7Y29tcG9uZW50LmNvbnN0cnVjdG9yLm5hbWV9LCByZW5kZXJpbmcgZW1wdHlgKTtcbiAgICAgICAgaW5zdHJ1Y3Rpb25zID0gW107XG4gICAgICB9XG4gICAgfVxuICAgIGF3YWl0IHByb2Nlc3NfaW5zdHJ1Y3Rpb25zKGluc3RydWN0aW9ucywgY29tcG9uZW50LiQsIGNvbXBvbmVudCk7XG4gICAgYXdhaXQgcHJvY2Vzc19iaW5kaW5ncyhjb21wb25lbnQpO1xuICAgIGF3YWl0IGF0dGFjaF9ldmVudF9oYW5kbGVycyhjb21wb25lbnQpO1xuICB9XG4gIGFzeW5jIGZ1bmN0aW9uIHByb2Nlc3NfYmluZGluZ3MoY29tcG9uZW50KSB7XG4gICAgY29tcG9uZW50LiQuZmluZChcIltkYXRhLWJpbmQtcHJvcF0sIFtkYXRhLWJpbmQtdmFsdWVdLCBbZGF0YS1iaW5kLXRleHRdLCBbZGF0YS1iaW5kLWh0bWxdLCBbZGF0YS1iaW5kLWNsYXNzXSwgW2RhdGEtYmluZC1zdHlsZV1cIikuZWFjaCgoXywgZWxlbWVudCkgPT4ge1xuICAgICAgY29uc3QgZWwgPSAkKGVsZW1lbnQpO1xuICAgICAgY29uc3QgYXR0cnMgPSBlbGVtZW50LmF0dHJpYnV0ZXM7XG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGF0dHJzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGNvbnN0IGF0dHIgPSBhdHRyc1tpXTtcbiAgICAgICAgaWYgKGF0dHIubmFtZS5zdGFydHNXaXRoKFwiZGF0YS1iaW5kLVwiKSkge1xuICAgICAgICAgIGNvbnN0IGJpbmRpbmdfdHlwZSA9IGF0dHIubmFtZS5zdWJzdHJpbmcoMTApO1xuICAgICAgICAgIGNvbnN0IGV4cHJlc3Npb24gPSBhdHRyLnZhbHVlO1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjb25zdCB2YWx1ZSA9IGV2YWx1YXRlX2V4cHJlc3Npb24oZXhwcmVzc2lvbiwgY29tcG9uZW50KTtcbiAgICAgICAgICAgIHN3aXRjaCAoYmluZGluZ190eXBlKSB7XG4gICAgICAgICAgICAgIGNhc2UgXCJwcm9wXCI6XG4gICAgICAgICAgICAgICAgY29uc3QgcHJvcF9uYW1lID0gZWwuYXR0cihcImRhdGEtYmluZC1wcm9wLW5hbWVcIikgfHwgXCJ2YWx1ZVwiO1xuICAgICAgICAgICAgICAgIGVsLnByb3AocHJvcF9uYW1lLCB2YWx1ZSk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgIGNhc2UgXCJ2YWx1ZVwiOlxuICAgICAgICAgICAgICAgIGVsLnZhbCh2YWx1ZSk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgIGNhc2UgXCJ0ZXh0XCI6XG4gICAgICAgICAgICAgICAgZWwudGV4dCh2YWx1ZSk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgIGNhc2UgXCJodG1sXCI6XG4gICAgICAgICAgICAgICAgZWwuaHRtbCh2YWx1ZSk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgIGNhc2UgXCJjbGFzc1wiOlxuICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT09IFwib2JqZWN0XCIpIHtcbiAgICAgICAgICAgICAgICAgIE9iamVjdC5lbnRyaWVzKHZhbHVlKS5mb3JFYWNoKChbY2xhc3NOYW1lLCBlbmFibGVkXSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBlbC50b2dnbGVDbGFzcyhjbGFzc05hbWUsICEhZW5hYmxlZCk7XG4gICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgZWwuYWRkQ2xhc3MoU3RyaW5nKHZhbHVlKSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICBjYXNlIFwic3R5bGVcIjpcbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIHZhbHVlID09PSBcIm9iamVjdFwiKSB7XG4gICAgICAgICAgICAgICAgICBlbC5jc3ModmFsdWUpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICBlbC5hdHRyKFwic3R5bGVcIiwgU3RyaW5nKHZhbHVlKSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgIGVsLmF0dHIoYmluZGluZ190eXBlLCB2YWx1ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoYEVycm9yIGV2YWx1YXRpbmcgYmluZGluZyBcIiR7ZXhwcmVzc2lvbn1cIjpgLCBlcnJvcik7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfSk7XG4gIH1cbiAgYXN5bmMgZnVuY3Rpb24gYXR0YWNoX2V2ZW50X2hhbmRsZXJzKGNvbXBvbmVudCkge1xuICAgIGNvbXBvbmVudC4kLmZpbmQoXCJbZGF0YS1vbi1jbGlja10sIFtkYXRhLW9uLWNoYW5nZV0sIFtkYXRhLW9uLXN1Ym1pdF0sIFtkYXRhLW9uLWtleXVwXSwgW2RhdGEtb24ta2V5ZG93bl0sIFtkYXRhLW9uLWZvY3VzXSwgW2RhdGEtb24tYmx1cl1cIikuZWFjaCgoXywgZWxlbWVudCkgPT4ge1xuICAgICAgY29uc3QgZWwgPSAkKGVsZW1lbnQpO1xuICAgICAgY29uc3QgYXR0cnMgPSBlbGVtZW50LmF0dHJpYnV0ZXM7XG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGF0dHJzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGNvbnN0IGF0dHIgPSBhdHRyc1tpXTtcbiAgICAgICAgaWYgKGF0dHIubmFtZS5zdGFydHNXaXRoKFwiZGF0YS1vbi1cIikpIHtcbiAgICAgICAgICBjb25zdCBldmVudF9uYW1lID0gYXR0ci5uYW1lLnN1YnN0cmluZyg4KTtcbiAgICAgICAgICBjb25zdCBoYW5kbGVyX2V4cHIgPSBhdHRyLnZhbHVlO1xuICAgICAgICAgIGVsLnJlbW92ZUF0dHIoYXR0ci5uYW1lKTtcbiAgICAgICAgICBlbC5vbihldmVudF9uYW1lLCBmdW5jdGlvbihldmVudCkge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgY29uc3QgaGFuZGxlciA9IGV2YWx1YXRlX2hhbmRsZXIoaGFuZGxlcl9leHByLCBjb21wb25lbnQpO1xuICAgICAgICAgICAgICBpZiAodHlwZW9mIGhhbmRsZXIgPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAgICAgICAgIGhhbmRsZXIuY2FsbChjb21wb25lbnQsIGV2ZW50KTtcbiAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBldmFsdWF0ZV9leHByZXNzaW9uKGhhbmRsZXJfZXhwciwgY29tcG9uZW50LCB7ICRldmVudDogZXZlbnQgfSk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoYEVycm9yIGluICR7ZXZlbnRfbmFtZX0gaGFuZGxlciBcIiR7aGFuZGxlcl9leHByfVwiOmAsIGVycm9yKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pO1xuICB9XG4gIGZ1bmN0aW9uIGV2YWx1YXRlX2V4cHJlc3Npb24oZXhwcmVzc2lvbiwgY29tcG9uZW50LCBsb2NhbHMgPSB7fSkge1xuICAgIGNvbnN0IGNvbnRleHQgPSB7XG4gICAgICAvLyBDb21wb25lbnQgcHJvcGVydGllc1xuICAgICAgZGF0YTogY29tcG9uZW50LmRhdGEsXG4gICAgICBhcmdzOiBjb21wb25lbnQuYXJncyxcbiAgICAgICQ6IGNvbXBvbmVudC4kLFxuICAgICAgLy8gQ29tcG9uZW50IG1ldGhvZHNcbiAgICAgIGVtaXQ6IGNvbXBvbmVudC5lbWl0LmJpbmQoY29tcG9uZW50KSxcbiAgICAgICRpZDogY29tcG9uZW50LiRpZC5iaW5kKGNvbXBvbmVudCksXG4gICAgICAvLyBMb2NhbHMgKGxpa2UgJGV2ZW50KVxuICAgICAgLi4ubG9jYWxzXG4gICAgfTtcbiAgICBjb25zdCBrZXlzID0gT2JqZWN0LmtleXMoY29udGV4dCk7XG4gICAgY29uc3QgdmFsdWVzID0gT2JqZWN0LnZhbHVlcyhjb250ZXh0KTtcbiAgICB0cnkge1xuICAgICAgY29uc3QgZm4gPSBuZXcgRnVuY3Rpb24oLi4ua2V5cywgYHJldHVybiAoJHtleHByZXNzaW9ufSlgKTtcbiAgICAgIHJldHVybiBmbiguLi52YWx1ZXMpO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBjb25zb2xlLmVycm9yKGBJbnZhbGlkIGV4cHJlc3Npb246ICR7ZXhwcmVzc2lvbn1gLCBlcnJvcik7XG4gICAgICByZXR1cm4gdm9pZCAwO1xuICAgIH1cbiAgfVxuICBmdW5jdGlvbiBldmFsdWF0ZV9oYW5kbGVyKGV4cHJlc3Npb24sIGNvbXBvbmVudCkge1xuICAgIGlmIChleHByZXNzaW9uIGluIGNvbXBvbmVudCAmJiB0eXBlb2YgY29tcG9uZW50W2V4cHJlc3Npb25dID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgIHJldHVybiBjb21wb25lbnRbZXhwcmVzc2lvbl07XG4gICAgfVxuICAgIHRyeSB7XG4gICAgICByZXR1cm4gbmV3IEZ1bmN0aW9uKFwiJGV2ZW50XCIsIGBcbiAgICAgIGNvbnN0IHsgZGF0YSwgYXJncywgJCwgZW1pdCwgJGlkIH0gPSB0aGlzO1xuICAgICAgJHtleHByZXNzaW9ufVxuICAgIGApLmJpbmQoY29tcG9uZW50KTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgY29uc29sZS5lcnJvcihgSW52YWxpZCBoYW5kbGVyOiAke2V4cHJlc3Npb259YCwgZXJyb3IpO1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICB9XG4gIGZ1bmN0aW9uIGVzY2FwZV9odG1sKHN0cikge1xuICAgIGNvbnN0IGRpdiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIik7XG4gICAgZGl2LnRleHRDb250ZW50ID0gc3RyO1xuICAgIHJldHVybiBkaXYuaW5uZXJIVE1MO1xuICB9XG4gIGZ1bmN0aW9uIGdldEpRdWVyeSgpIHtcbiAgICBpZiAodHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiAmJiB3aW5kb3cuJCkge1xuICAgICAgcmV0dXJuIHdpbmRvdy4kO1xuICAgIH1cbiAgICBpZiAodHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiAmJiB3aW5kb3cualF1ZXJ5KSB7XG4gICAgICByZXR1cm4gd2luZG93LmpRdWVyeTtcbiAgICB9XG4gICAgdGhyb3cgbmV3IEVycm9yKCdGQVRBTDogalF1ZXJ5IGlzIG5vdCBkZWZpbmVkLiBqUXVlcnkgbXVzdCBiZSBsb2FkZWQgYmVmb3JlIHVzaW5nIEpRSFRNTC4gQWRkIDxzY3JpcHQgc3JjPVwiaHR0cHM6Ly9jb2RlLmpxdWVyeS5jb20vanF1ZXJ5LTMuNy4xLm1pbi5qc1wiPjxcXC9zY3JpcHQ+IGJlZm9yZSBsb2FkaW5nIEpRSFRNTC4nKTtcbiAgfVxuICBmdW5jdGlvbiBnZXRKcWh0bWwoKSB7XG4gICAgaWYgKHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgJiYgd2luZG93LmpxaHRtbCkge1xuICAgICAgcmV0dXJuIHdpbmRvdy5qcWh0bWw7XG4gICAgfVxuICAgIGlmICh0eXBlb2YgZ2xvYmFsVGhpcyAhPT0gXCJ1bmRlZmluZWRcIiAmJiBnbG9iYWxUaGlzLmpxaHRtbCkge1xuICAgICAgcmV0dXJuIGdsb2JhbFRoaXMuanFodG1sO1xuICAgIH1cbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJGQVRBTDogd2luZG93LmpxaHRtbCBpcyBub3QgZGVmaW5lZC4gVGhlIEpRSFRNTCBydW50aW1lIG11c3QgYmUgbG9hZGVkIGJlZm9yZSB1c2luZyBKUUhUTUwgY29tcG9uZW50cy4gRW5zdXJlIEBqcWh0bWwvY29yZSBpcyBpbXBvcnRlZCBhbmQgaW5pdGlhbGl6ZWQgYmVmb3JlIGF0dGVtcHRpbmcgdG8gdXNlIGRlYnVnIGZlYXR1cmVzLlwiKTtcbiAgfVxuICB2YXIgRGVidWdPdmVybGF5ID0gY2xhc3MgX0RlYnVnT3ZlcmxheSB7XG4gICAgY29uc3RydWN0b3Iob3B0aW9ucyA9IHt9KSB7XG4gICAgICB0aGlzLiRjb250YWluZXIgPSBudWxsO1xuICAgICAgdGhpcy4kc3RhdHVzSW5kaWNhdG9yID0gbnVsbDtcbiAgICAgIHRoaXMuJCA9IGdldEpRdWVyeSgpO1xuICAgICAgaWYgKCF0aGlzLiQpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwialF1ZXJ5IGlzIHJlcXVpcmVkIGZvciBEZWJ1Z092ZXJsYXlcIik7XG4gICAgICB9XG4gICAgICB0aGlzLm9wdGlvbnMgPSB7XG4gICAgICAgIHBvc2l0aW9uOiBcImJvdHRvbVwiLFxuICAgICAgICB0aGVtZTogXCJkYXJrXCIsXG4gICAgICAgIGNvbXBhY3Q6IGZhbHNlLFxuICAgICAgICBzaG93U3RhdHVzOiB0cnVlLFxuICAgICAgICBhdXRvSGlkZTogZmFsc2UsXG4gICAgICAgIC4uLm9wdGlvbnNcbiAgICAgIH07XG4gICAgfVxuICAgIC8qKlxuICAgICAqIFN0YXRpYyBtZXRob2QgdG8gc2hvdyBkZWJ1ZyBvdmVybGF5IChzaW5nbGV0b24gcGF0dGVybilcbiAgICAgKi9cbiAgICBzdGF0aWMgc2hvdyhvcHRpb25zKSB7XG4gICAgICBpZiAoIV9EZWJ1Z092ZXJsYXkuaW5zdGFuY2UpIHtcbiAgICAgICAgX0RlYnVnT3ZlcmxheS5pbnN0YW5jZSA9IG5ldyBfRGVidWdPdmVybGF5KG9wdGlvbnMpO1xuICAgICAgfVxuICAgICAgX0RlYnVnT3ZlcmxheS5pbnN0YW5jZS5kaXNwbGF5KCk7XG4gICAgICByZXR1cm4gX0RlYnVnT3ZlcmxheS5pbnN0YW5jZTtcbiAgICB9XG4gICAgLyoqXG4gICAgICogU3RhdGljIG1ldGhvZCB0byBoaWRlIGRlYnVnIG92ZXJsYXlcbiAgICAgKi9cbiAgICBzdGF0aWMgaGlkZSgpIHtcbiAgICAgIGlmIChfRGVidWdPdmVybGF5Lmluc3RhbmNlKSB7XG4gICAgICAgIF9EZWJ1Z092ZXJsYXkuaW5zdGFuY2UuaGlkZSgpO1xuICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBTdGF0aWMgbWV0aG9kIHRvIHRvZ2dsZSBkZWJ1ZyBvdmVybGF5IHZpc2liaWxpdHlcbiAgICAgKi9cbiAgICBzdGF0aWMgdG9nZ2xlKCkge1xuICAgICAgaWYgKF9EZWJ1Z092ZXJsYXkuaW5zdGFuY2UgJiYgX0RlYnVnT3ZlcmxheS5pbnN0YW5jZS4kY29udGFpbmVyKSB7XG4gICAgICAgIGlmIChfRGVidWdPdmVybGF5Lmluc3RhbmNlLiRjb250YWluZXIuaXMoXCI6dmlzaWJsZVwiKSkge1xuICAgICAgICAgIF9EZWJ1Z092ZXJsYXkuaGlkZSgpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIF9EZWJ1Z092ZXJsYXkuaW5zdGFuY2UuZGlzcGxheSgpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBfRGVidWdPdmVybGF5LnNob3coKTtcbiAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogU3RhdGljIG1ldGhvZCB0byBkZXN0cm95IGRlYnVnIG92ZXJsYXlcbiAgICAgKi9cbiAgICBzdGF0aWMgZGVzdHJveSgpIHtcbiAgICAgIGlmIChfRGVidWdPdmVybGF5Lmluc3RhbmNlKSB7XG4gICAgICAgIF9EZWJ1Z092ZXJsYXkuaW5zdGFuY2UuZGVzdHJveSgpO1xuICAgICAgICBfRGVidWdPdmVybGF5Lmluc3RhbmNlID0gbnVsbDtcbiAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogRGlzcGxheSB0aGUgZGVidWcgb3ZlcmxheVxuICAgICAqL1xuICAgIGRpc3BsYXkoKSB7XG4gICAgICBpZiAodGhpcy4kY29udGFpbmVyKSB7XG4gICAgICAgIHRoaXMuJGNvbnRhaW5lci5zaG93KCk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIHRoaXMuY3JlYXRlT3ZlcmxheSgpO1xuICAgICAgaWYgKHRoaXMub3B0aW9ucy5zaG93U3RhdHVzKSB7XG4gICAgICAgIHRoaXMuY3JlYXRlU3RhdHVzSW5kaWNhdG9yKCk7XG4gICAgICB9XG4gICAgfVxuICAgIC8qKlxuICAgICAqIEhpZGUgdGhlIGRlYnVnIG92ZXJsYXlcbiAgICAgKi9cbiAgICBoaWRlKCkge1xuICAgICAgaWYgKHRoaXMuJGNvbnRhaW5lcikge1xuICAgICAgICB0aGlzLiRjb250YWluZXIuaGlkZSgpO1xuICAgICAgfVxuICAgICAgaWYgKHRoaXMuJHN0YXR1c0luZGljYXRvcikge1xuICAgICAgICB0aGlzLiRzdGF0dXNJbmRpY2F0b3IuaGlkZSgpO1xuICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBSZW1vdmUgdGhlIGRlYnVnIG92ZXJsYXkgY29tcGxldGVseVxuICAgICAqL1xuICAgIGRlc3Ryb3koKSB7XG4gICAgICBpZiAodGhpcy4kY29udGFpbmVyKSB7XG4gICAgICAgIHRoaXMuJGNvbnRhaW5lci5yZW1vdmUoKTtcbiAgICAgICAgdGhpcy4kY29udGFpbmVyID0gbnVsbDtcbiAgICAgIH1cbiAgICAgIGlmICh0aGlzLiRzdGF0dXNJbmRpY2F0b3IpIHtcbiAgICAgICAgdGhpcy4kc3RhdHVzSW5kaWNhdG9yLnJlbW92ZSgpO1xuICAgICAgICB0aGlzLiRzdGF0dXNJbmRpY2F0b3IgPSBudWxsO1xuICAgICAgfVxuICAgIH1cbiAgICAvKipcbiAgICAgKiBVcGRhdGUgdGhlIHN0YXR1cyBpbmRpY2F0b3JcbiAgICAgKi9cbiAgICB1cGRhdGVTdGF0dXMobW9kZSkge1xuICAgICAgaWYgKCF0aGlzLiRzdGF0dXNJbmRpY2F0b3IpXG4gICAgICAgIHJldHVybjtcbiAgICAgIHRoaXMuJHN0YXR1c0luZGljYXRvci50ZXh0KFwiRGVidWc6IFwiICsgbW9kZSk7XG4gICAgICB0aGlzLiRzdGF0dXNJbmRpY2F0b3IuYXR0cihcImNsYXNzXCIsIFwianFodG1sLWRlYnVnLXN0YXR1c1wiICsgKG1vZGUgIT09IFwiT2ZmXCIgPyBcIiBhY3RpdmVcIiA6IFwiXCIpKTtcbiAgICB9XG4gICAgY3JlYXRlT3ZlcmxheSgpIHtcbiAgICAgIHRoaXMuYWRkU3R5bGVzKCk7XG4gICAgICB0aGlzLiRjb250YWluZXIgPSB0aGlzLiQoXCI8ZGl2PlwiKS5hZGRDbGFzcyhganFodG1sLWRlYnVnLW92ZXJsYXkgJHt0aGlzLm9wdGlvbnMudGhlbWV9ICR7dGhpcy5vcHRpb25zLnBvc2l0aW9ufWApO1xuICAgICAgY29uc3QgJGNvbnRlbnQgPSB0aGlzLiQoXCI8ZGl2PlwiKS5hZGRDbGFzcyhcImpxaHRtbC1kZWJ1Zy1jb250ZW50XCIpO1xuICAgICAgY29uc3QgJGNvbnRyb2xzID0gdGhpcy4kKFwiPGRpdj5cIikuYWRkQ2xhc3MoXCJqcWh0bWwtZGVidWctY29udHJvbHNcIik7XG4gICAgICBjb25zdCAkdGl0bGUgPSB0aGlzLiQoXCI8c3Bhbj5cIikuYWRkQ2xhc3MoXCJqcWh0bWwtZGVidWctdGl0bGVcIikuaHRtbChcIjxzdHJvbmc+XFx1ezFGNDFCfSBKUUhUTUwgRGVidWc6PC9zdHJvbmc+XCIpO1xuICAgICAgJGNvbnRyb2xzLmFwcGVuZCgkdGl0bGUpO1xuICAgICAgY29uc3QgYnV0dG9ucyA9IFtcbiAgICAgICAgeyB0ZXh0OiBcIlNsb3cgTW90aW9uICsgRmxhc2hcIiwgYWN0aW9uOiBcImVuYWJsZVNsb3dNb3Rpb25EZWJ1Z1wiLCBjbGFzczogXCJzdWNjZXNzXCIgfSxcbiAgICAgICAgeyB0ZXh0OiBcIkJhc2ljIERlYnVnXCIsIGFjdGlvbjogXCJlbmFibGVCYXNpY0RlYnVnXCIsIGNsYXNzOiBcIlwiIH0sXG4gICAgICAgIHsgdGV4dDogXCJGdWxsIERlYnVnXCIsIGFjdGlvbjogXCJlbmFibGVGdWxsRGVidWdcIiwgY2xhc3M6IFwiXCIgfSxcbiAgICAgICAgeyB0ZXh0OiBcIlNlcXVlbnRpYWxcIiwgYWN0aW9uOiBcImVuYWJsZVNlcXVlbnRpYWxNb2RlXCIsIGNsYXNzOiBcIlwiIH0sXG4gICAgICAgIHsgdGV4dDogXCJDbGVhciBEZWJ1Z1wiLCBhY3Rpb246IFwiY2xlYXJBbGxEZWJ1Z1wiLCBjbGFzczogXCJkYW5nZXJcIiB9LFxuICAgICAgICB7IHRleHQ6IFwiU2V0dGluZ3NcIiwgYWN0aW9uOiBcInNob3dEZWJ1Z0luZm9cIiwgY2xhc3M6IFwiXCIgfVxuICAgICAgXTtcbiAgICAgIGJ1dHRvbnMuZm9yRWFjaCgoYnRuKSA9PiB7XG4gICAgICAgIGNvbnN0ICRidXR0b24gPSB0aGlzLiQoXCI8YnV0dG9uPlwiKS50ZXh0KGJ0bi50ZXh0KS5hZGRDbGFzcyhcImpxaHRtbC1kZWJ1Zy1idG5cIiArIChidG4uY2xhc3MgPyBgICR7YnRuLmNsYXNzfWAgOiBcIlwiKSkub24oXCJjbGlja1wiLCAoKSA9PiB0aGlzLmV4ZWN1dGVBY3Rpb24oYnRuLmFjdGlvbikpO1xuICAgICAgICAkY29udHJvbHMuYXBwZW5kKCRidXR0b24pO1xuICAgICAgfSk7XG4gICAgICBjb25zdCAkdG9nZ2xlQnRuID0gdGhpcy4kKFwiPGJ1dHRvbj5cIikudGV4dCh0aGlzLm9wdGlvbnMuY29tcGFjdCA/IFwiXFx1MjVCQ1wiIDogXCJcXHUyNUIyXCIpLmFkZENsYXNzKFwianFodG1sLWRlYnVnLXRvZ2dsZVwiKS5vbihcImNsaWNrXCIsICgpID0+IHRoaXMudG9nZ2xlKCkpO1xuICAgICAgJGNvbnRyb2xzLmFwcGVuZCgkdG9nZ2xlQnRuKTtcbiAgICAgICRjb250ZW50LmFwcGVuZCgkY29udHJvbHMpO1xuICAgICAgdGhpcy4kY29udGFpbmVyLmFwcGVuZCgkY29udGVudCk7XG4gICAgICB0aGlzLiQoXCJib2R5XCIpLmFwcGVuZCh0aGlzLiRjb250YWluZXIpO1xuICAgIH1cbiAgICBjcmVhdGVTdGF0dXNJbmRpY2F0b3IoKSB7XG4gICAgICB0aGlzLiRzdGF0dXNJbmRpY2F0b3IgPSB0aGlzLiQoXCI8ZGl2PlwiKS5hZGRDbGFzcyhcImpxaHRtbC1kZWJ1Zy1zdGF0dXNcIikudGV4dChcIkRlYnVnOiBPZmZcIikuY3NzKHtcbiAgICAgICAgcG9zaXRpb246IFwiZml4ZWRcIixcbiAgICAgICAgdG9wOiBcIjEwcHhcIixcbiAgICAgICAgcmlnaHQ6IFwiMTBweFwiLFxuICAgICAgICBiYWNrZ3JvdW5kOiBcIiMyYzNlNTBcIixcbiAgICAgICAgY29sb3I6IFwid2hpdGVcIixcbiAgICAgICAgcGFkZGluZzogXCI1cHggMTBweFwiLFxuICAgICAgICBib3JkZXJSYWRpdXM6IFwiNHB4XCIsXG4gICAgICAgIGZvbnRTaXplOiBcIjAuNzVyZW1cIixcbiAgICAgICAgekluZGV4OiBcIjEwMDAxXCIsXG4gICAgICAgIG9wYWNpdHk6IFwiMC44XCIsXG4gICAgICAgIGZvbnRGYW1pbHk6IFwibW9ub3NwYWNlXCJcbiAgICAgIH0pO1xuICAgICAgdGhpcy4kKFwiYm9keVwiKS5hcHBlbmQodGhpcy4kc3RhdHVzSW5kaWNhdG9yKTtcbiAgICB9XG4gICAgYWRkU3R5bGVzKCkge1xuICAgICAgaWYgKHRoaXMuJChcIiNqcWh0bWwtZGVidWctc3R5bGVzXCIpLmxlbmd0aCA+IDApXG4gICAgICAgIHJldHVybjtcbiAgICAgIGNvbnN0ICRzdHlsZSA9IHRoaXMuJChcIjxzdHlsZT5cIikuYXR0cihcImlkXCIsIFwianFodG1sLWRlYnVnLXN0eWxlc1wiKS50ZXh0KCcuanFodG1sLWRlYnVnLW92ZXJsYXkge3Bvc2l0aW9uOiBmaXhlZDtsZWZ0OiAwO3JpZ2h0OiAwO3otaW5kZXg6IDEwMDAwO2ZvbnQtZmFtaWx5OiAtYXBwbGUtc3lzdGVtLCBCbGlua01hY1N5c3RlbUZvbnQsIFwiU2Vnb2UgVUlcIiwgUm9ib3RvLCBtb25vc3BhY2U7Zm9udC1zaXplOiAwLjhyZW07Ym94LXNoYWRvdzogMCAycHggMTBweCByZ2JhKDAsMCwwLDAuMik7fS5qcWh0bWwtZGVidWctb3ZlcmxheS50b3Age3RvcDogMDt9LmpxaHRtbC1kZWJ1Zy1vdmVybGF5LmJvdHRvbSB7Ym90dG9tOiAwO30uanFodG1sLWRlYnVnLW92ZXJsYXkuZGFyayB7YmFja2dyb3VuZDogIzM0NDk1ZTtjb2xvcjogI2VjZjBmMTt9LmpxaHRtbC1kZWJ1Zy1vdmVybGF5LmxpZ2h0IHtiYWNrZ3JvdW5kOiAjZjhmOWZhO2NvbG9yOiAjMzMzO2JvcmRlci1ib3R0b206IDFweCBzb2xpZCAjZGVlMmU2O30uanFodG1sLWRlYnVnLWNvbnRlbnQge3BhZGRpbmc6IDAuNXJlbSAxcmVtO30uanFodG1sLWRlYnVnLWNvbnRyb2xzIHtkaXNwbGF5OiBmbGV4O2ZsZXgtd3JhcDogd3JhcDtnYXA6IDhweDthbGlnbi1pdGVtczogY2VudGVyO30uanFodG1sLWRlYnVnLXRpdGxlIHttYXJnaW4tcmlnaHQ6IDEwcHg7Zm9udC13ZWlnaHQ6IGJvbGQ7fS5qcWh0bWwtZGVidWctYnRuIHtwYWRkaW5nOiA0cHggOHB4O2JvcmRlcjogbm9uZTtib3JkZXItcmFkaXVzOiAzcHg7YmFja2dyb3VuZDogIzM0OThkYjtjb2xvcjogd2hpdGU7Y3Vyc29yOiBwb2ludGVyO2ZvbnQtc2l6ZTogMC43NXJlbTt0cmFuc2l0aW9uOiBiYWNrZ3JvdW5kIDAuMnM7fS5qcWh0bWwtZGVidWctYnRuOmhvdmVyIHtiYWNrZ3JvdW5kOiAjMjk4MGI5O30uanFodG1sLWRlYnVnLWJ0bi5zdWNjZXNzIHtiYWNrZ3JvdW5kOiAjMjdhZTYwO30uanFodG1sLWRlYnVnLWJ0bi5zdWNjZXNzOmhvdmVyIHtiYWNrZ3JvdW5kOiAjMjI5OTU0O30uanFodG1sLWRlYnVnLWJ0bi5kYW5nZXIge2JhY2tncm91bmQ6ICNlNzRjM2M7fS5qcWh0bWwtZGVidWctYnRuLmRhbmdlcjpob3ZlciB7YmFja2dyb3VuZDogI2MwMzkyYjt9LmpxaHRtbC1kZWJ1Zy10b2dnbGUge3BhZGRpbmc6IDRweCA4cHg7Ym9yZGVyOiBub25lO2JvcmRlci1yYWRpdXM6IDNweDtiYWNrZ3JvdW5kOiAjN2Y4YzhkO2NvbG9yOiB3aGl0ZTtjdXJzb3I6IHBvaW50ZXI7Zm9udC1zaXplOiAwLjc1cmVtO21hcmdpbi1sZWZ0OiBhdXRvO30uanFodG1sLWRlYnVnLXRvZ2dsZTpob3ZlciB7YmFja2dyb3VuZDogIzZjN2I3ZDt9LmpxaHRtbC1kZWJ1Zy1zdGF0dXMuYWN0aXZlIHtiYWNrZ3JvdW5kOiAjMjdhZTYwICFpbXBvcnRhbnQ7fUBtZWRpYSAobWF4LXdpZHRoOiA3NjhweCkgey5qcWh0bWwtZGVidWctY29udHJvbHMge2ZsZXgtZGlyZWN0aW9uOiBjb2x1bW47YWxpZ24taXRlbXM6IGZsZXgtc3RhcnQ7fS5qcWh0bWwtZGVidWctdGl0bGUge21hcmdpbi1ib3R0b206IDVweDt9fScpO1xuICAgICAgdGhpcy4kKFwiaGVhZFwiKS5hcHBlbmQoJHN0eWxlKTtcbiAgICB9XG4gICAgdG9nZ2xlKCkge1xuICAgICAgdGhpcy5vcHRpb25zLmNvbXBhY3QgPSAhdGhpcy5vcHRpb25zLmNvbXBhY3Q7XG4gICAgICBjb25zdCAkdG9nZ2xlQnRuID0gdGhpcy4kY29udGFpbmVyLmZpbmQoXCIuanFodG1sLWRlYnVnLXRvZ2dsZVwiKTtcbiAgICAgICR0b2dnbGVCdG4udGV4dCh0aGlzLm9wdGlvbnMuY29tcGFjdCA/IFwiXFx1MjVCQ1wiIDogXCJcXHUyNUIyXCIpO1xuICAgICAgY29uc3QgJGJ1dHRvbnMgPSB0aGlzLiRjb250YWluZXIuZmluZChcIi5qcWh0bWwtZGVidWctYnRuXCIpO1xuICAgICAgaWYgKHRoaXMub3B0aW9ucy5jb21wYWN0KSB7XG4gICAgICAgICRidXR0b25zLmhpZGUoKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgICRidXR0b25zLnNob3coKTtcbiAgICAgIH1cbiAgICB9XG4gICAgZXhlY3V0ZUFjdGlvbihhY3Rpb24pIHtcbiAgICAgIGNvbnN0IGpxaHRtbDIgPSBnZXRKcWh0bWwoKTtcbiAgICAgIGlmICghanFodG1sMikge1xuICAgICAgICBjb25zb2xlLndhcm4oXCJKUUhUTUwgbm90IGF2YWlsYWJsZSAtIG1ha2Ugc3VyZSBpdCdzIGxvYWRlZCBhbmQgZXhwb3NlZCBnbG9iYWxseVwiKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgc3dpdGNoIChhY3Rpb24pIHtcbiAgICAgICAgY2FzZSBcImVuYWJsZVNsb3dNb3Rpb25EZWJ1Z1wiOlxuICAgICAgICAgIGpxaHRtbDIuc2V0RGVidWdTZXR0aW5ncyh7XG4gICAgICAgICAgICBsb2dGdWxsTGlmZWN5Y2xlOiB0cnVlLFxuICAgICAgICAgICAgc2VxdWVudGlhbFByb2Nlc3Npbmc6IHRydWUsXG4gICAgICAgICAgICBkZWxheUFmdGVyQ29tcG9uZW50OiAxNTAsXG4gICAgICAgICAgICBkZWxheUFmdGVyUmVuZGVyOiAyMDAsXG4gICAgICAgICAgICBkZWxheUFmdGVyUmVyZW5kZXI6IDI1MCxcbiAgICAgICAgICAgIGZsYXNoQ29tcG9uZW50czogdHJ1ZSxcbiAgICAgICAgICAgIGZsYXNoRHVyYXRpb246IDgwMCxcbiAgICAgICAgICAgIGZsYXNoQ29sb3JzOiB7XG4gICAgICAgICAgICAgIGNyZWF0ZTogXCIjMzQ5OGRiXCIsXG4gICAgICAgICAgICAgIHJlbmRlcjogXCIjMjdhZTYwXCIsXG4gICAgICAgICAgICAgIHJlYWR5OiBcIiM5YjU5YjZcIlxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHByb2ZpbGVQZXJmb3JtYW5jZTogdHJ1ZSxcbiAgICAgICAgICAgIGhpZ2hsaWdodFNsb3dSZW5kZXJzOiAzMCxcbiAgICAgICAgICAgIGxvZ0Rpc3BhdGNoOiB0cnVlXG4gICAgICAgICAgfSk7XG4gICAgICAgICAgdGhpcy51cGRhdGVTdGF0dXMoXCJTbG93IE1vdGlvblwiKTtcbiAgICAgICAgICBjb25zb2xlLmxvZyhcIlxcdXsxRjQxQn0gU2xvdyBNb3Rpb24gRGVidWcgTW9kZSBFbmFibGVkXCIpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIFwiZW5hYmxlQmFzaWNEZWJ1Z1wiOlxuICAgICAgICAgIGpxaHRtbDIuZW5hYmxlRGVidWdNb2RlKFwiYmFzaWNcIik7XG4gICAgICAgICAgdGhpcy51cGRhdGVTdGF0dXMoXCJCYXNpY1wiKTtcbiAgICAgICAgICBjb25zb2xlLmxvZyhcIlxcdXsxRjQxQn0gQmFzaWMgRGVidWcgTW9kZSBFbmFibGVkXCIpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIFwiZW5hYmxlRnVsbERlYnVnXCI6XG4gICAgICAgICAganFodG1sMi5lbmFibGVEZWJ1Z01vZGUoXCJmdWxsXCIpO1xuICAgICAgICAgIHRoaXMudXBkYXRlU3RhdHVzKFwiRnVsbFwiKTtcbiAgICAgICAgICBjb25zb2xlLmxvZyhcIlxcdXsxRjQxQn0gRnVsbCBEZWJ1ZyBNb2RlIEVuYWJsZWRcIik7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgXCJlbmFibGVTZXF1ZW50aWFsTW9kZVwiOlxuICAgICAgICAgIGpxaHRtbDIuc2V0RGVidWdTZXR0aW5ncyh7XG4gICAgICAgICAgICBsb2dDcmVhdGlvblJlYWR5OiB0cnVlLFxuICAgICAgICAgICAgc2VxdWVudGlhbFByb2Nlc3Npbmc6IHRydWUsXG4gICAgICAgICAgICBmbGFzaENvbXBvbmVudHM6IHRydWUsXG4gICAgICAgICAgICBwcm9maWxlUGVyZm9ybWFuY2U6IHRydWVcbiAgICAgICAgICB9KTtcbiAgICAgICAgICB0aGlzLnVwZGF0ZVN0YXR1cyhcIlNlcXVlbnRpYWxcIik7XG4gICAgICAgICAgY29uc29sZS5sb2coXCJcXHV7MUY0MUJ9IFNlcXVlbnRpYWwgUHJvY2Vzc2luZyBNb2RlIEVuYWJsZWRcIik7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgXCJjbGVhckFsbERlYnVnXCI6XG4gICAgICAgICAganFodG1sMi5jbGVhckRlYnVnU2V0dGluZ3MoKTtcbiAgICAgICAgICB0aGlzLnVwZGF0ZVN0YXR1cyhcIk9mZlwiKTtcbiAgICAgICAgICBjb25zb2xlLmxvZyhcIlxcdXsxRjQxQn0gQWxsIERlYnVnIE1vZGVzIERpc2FibGVkXCIpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIFwic2hvd0RlYnVnSW5mb1wiOlxuICAgICAgICAgIGNvbnN0IHNldHRpbmdzID0gSlNPTi5zdHJpbmdpZnkoanFodG1sMi5kZWJ1ZywgbnVsbCwgMik7XG4gICAgICAgICAgY29uc29sZS5sb2coXCJcXHV7MUY0MUJ9IEN1cnJlbnQgRGVidWcgU2V0dGluZ3M6XCIsIHNldHRpbmdzKTtcbiAgICAgICAgICBhbGVydChcIkRlYnVnIHNldHRpbmdzIGxvZ2dlZCB0byBjb25zb2xlOlxcblxcblwiICsgKE9iamVjdC5rZXlzKGpxaHRtbDIuZGVidWcpLmxlbmd0aCA+IDAgPyBzZXR0aW5ncyA6IFwiTm8gZGVidWcgc2V0dGluZ3MgYWN0aXZlXCIpKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG4gIH07XG4gIERlYnVnT3ZlcmxheS5pbnN0YW5jZSA9IG51bGw7XG4gIGlmICh0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgY29uc3QgdXJsUGFyYW1zID0gbmV3IFVSTFNlYXJjaFBhcmFtcyh3aW5kb3cubG9jYXRpb24uc2VhcmNoKTtcbiAgICBpZiAodXJsUGFyYW1zLmdldChcImRlYnVnXCIpID09PSBcInRydWVcIiB8fCB1cmxQYXJhbXMuZ2V0KFwianFodG1sLWRlYnVnXCIpID09PSBcInRydWVcIikge1xuICAgICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihcIkRPTUNvbnRlbnRMb2FkZWRcIiwgKCkgPT4ge1xuICAgICAgICBEZWJ1Z092ZXJsYXkuc2hvdygpO1xuICAgICAgfSk7XG4gICAgfVxuICB9XG4gIGZ1bmN0aW9uIGluaXRfanF1ZXJ5X3BsdWdpbihqUXVlcnkpIHtcbiAgICBpZiAoIWpRdWVyeSB8fCAhalF1ZXJ5LmZuKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJqUXVlcnkgaXMgcmVxdWlyZWQgZm9yIEpRSFRNTC4gUGxlYXNlIGVuc3VyZSBqUXVlcnkgaXMgbG9hZGVkIGJlZm9yZSBpbml0aWFsaXppbmcgSlFIVE1MLlwiKTtcbiAgICB9XG4gICAgaWYgKHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgJiYgd2luZG93LiQgIT09IGpRdWVyeSAmJiAhalF1ZXJ5Ll9fanFodG1sX2NoZWNrZWQpIHtcbiAgICAgIGRldldhcm4oJ2pRdWVyeSBpbnN0YW5jZSBhcHBlYXJzIHRvIGJlIGJ1bmRsZWQgd2l0aCB3ZWJwYWNrL21vZHVsZXMgcmF0aGVyIHRoYW4gbG9hZGVkIGdsb2JhbGx5LlxcbkZvciBiZXN0IGNvbXBhdGliaWxpdHksIGl0IGlzIHJlY29tbWVuZGVkIHRvOlxcbjEuIEluY2x1ZGUgalF1ZXJ5IHZpYSA8c2NyaXB0PiB0YWcgZnJvbSBhIENETiAoVU1EIGZvcm1hdClcXG4yLiBDb25maWd1cmUgd2VicGFjayB3aXRoOiBleHRlcm5hbHM6IHsganF1ZXJ5OiBcIiRcIiB9XFxuMy4gUmVtb3ZlIGpxdWVyeSBmcm9tIHBhY2thZ2UuanNvbiBkZXBlbmRlbmNpZXNcXG5cXG5UbyBzdXBwcmVzcyB0aGlzIHdhcm5pbmcsIHNldDogd2luZG93LkpRSFRNTF9TVVBQUkVTU19XQVJOSU5HUyA9IHRydWUnKTtcbiAgICAgIGpRdWVyeS5fX2pxaHRtbF9jaGVja2VkID0gdHJ1ZTtcbiAgICB9XG4gICAgY29uc3QgX2pxaHRtbF9vcmlnaW5hbF9qcXVlcnkgPSBqUXVlcnk7XG4gICAgY29uc3QgSlF1ZXJ5V2l0aENvbXBvbmVudFN1cHBvcnQgPSBmdW5jdGlvbihzZWxlY3RvciwgY29udGV4dCkge1xuICAgICAgaWYgKHNlbGVjdG9yICYmIHR5cGVvZiBzZWxlY3RvciA9PT0gXCJvYmplY3RcIiAmJiBzZWxlY3Rvci4kICYmIHR5cGVvZiBzZWxlY3Rvci4kaWQgPT09IFwiZnVuY3Rpb25cIiAmJiB0eXBlb2Ygc2VsZWN0b3IuaWQgPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICByZXR1cm4gc2VsZWN0b3IuJDtcbiAgICAgIH1cbiAgICAgIHJldHVybiBuZXcgX2pxaHRtbF9vcmlnaW5hbF9qcXVlcnkoc2VsZWN0b3IsIGNvbnRleHQpO1xuICAgIH07XG4gICAgT2JqZWN0LnNldFByb3RvdHlwZU9mKEpRdWVyeVdpdGhDb21wb25lbnRTdXBwb3J0LCBfanFodG1sX29yaWdpbmFsX2pxdWVyeSk7XG4gICAgZm9yIChjb25zdCBrZXkgaW4gX2pxaHRtbF9vcmlnaW5hbF9qcXVlcnkpIHtcbiAgICAgIGlmIChfanFodG1sX29yaWdpbmFsX2pxdWVyeS5oYXNPd25Qcm9wZXJ0eShrZXkpKSB7XG4gICAgICAgIEpRdWVyeVdpdGhDb21wb25lbnRTdXBwb3J0W2tleV0gPSBfanFodG1sX29yaWdpbmFsX2pxdWVyeVtrZXldO1xuICAgICAgfVxuICAgIH1cbiAgICBKUXVlcnlXaXRoQ29tcG9uZW50U3VwcG9ydC5wcm90b3R5cGUgPSBfanFodG1sX29yaWdpbmFsX2pxdWVyeS5wcm90b3R5cGU7XG4gICAgSlF1ZXJ5V2l0aENvbXBvbmVudFN1cHBvcnQuZm4gPSBfanFodG1sX29yaWdpbmFsX2pxdWVyeS5mbjtcbiAgICBpZiAodHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgd2luZG93LmpRdWVyeSA9IEpRdWVyeVdpdGhDb21wb25lbnRTdXBwb3J0O1xuICAgICAgd2luZG93LiQgPSBKUXVlcnlXaXRoQ29tcG9uZW50U3VwcG9ydDtcbiAgICB9XG4gICAgalF1ZXJ5ID0gSlF1ZXJ5V2l0aENvbXBvbmVudFN1cHBvcnQ7XG4gICAgY29uc3Qgb3JpZ2luYWxWYWwgPSBqUXVlcnkuZm4udmFsO1xuICAgIGpRdWVyeS5mbi52YWwgPSBmdW5jdGlvbih2YWx1ZSkge1xuICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgY29uc3QgZmlyc3RFbCA9IHRoaXMuZmlyc3QoKTtcbiAgICAgICAgaWYgKGZpcnN0RWwubGVuZ3RoID09PSAwKVxuICAgICAgICAgIHJldHVybiB2b2lkIDA7XG4gICAgICAgIGNvbnN0IGNvbXBvbmVudCA9IGZpcnN0RWwuZGF0YShcIl9jb21wb25lbnRcIik7XG4gICAgICAgIGNvbnN0IHRhZ05hbWUgPSBmaXJzdEVsLnByb3AoXCJ0YWdOYW1lXCIpO1xuICAgICAgICBpZiAoY29tcG9uZW50ICYmIHR5cGVvZiBjb21wb25lbnQudmFsID09PSBcImZ1bmN0aW9uXCIgJiYgdGFnTmFtZSAhPT0gXCJJTlBVVFwiICYmIHRhZ05hbWUgIT09IFwiVEVYVEFSRUFcIikge1xuICAgICAgICAgIHJldHVybiBjb21wb25lbnQudmFsKCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG9yaWdpbmFsVmFsLmNhbGwodGhpcyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLmVhY2goZnVuY3Rpb24oKSB7XG4gICAgICAgICAgY29uc3QgJGVsID0galF1ZXJ5KHRoaXMpO1xuICAgICAgICAgIGNvbnN0IGNvbXBvbmVudCA9ICRlbC5kYXRhKFwiX2NvbXBvbmVudFwiKTtcbiAgICAgICAgICBjb25zdCB0YWdOYW1lID0gJGVsLnByb3AoXCJ0YWdOYW1lXCIpO1xuICAgICAgICAgIGlmIChjb21wb25lbnQgJiYgdHlwZW9mIGNvbXBvbmVudC52YWwgPT09IFwiZnVuY3Rpb25cIiAmJiB0YWdOYW1lICE9PSBcIklOUFVUXCIgJiYgdGFnTmFtZSAhPT0gXCJURVhUQVJFQVwiKSB7XG4gICAgICAgICAgICBjb21wb25lbnQudmFsKHZhbHVlKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgb3JpZ2luYWxWYWwuY2FsbCgkZWwsIHZhbHVlKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgIH1cbiAgICB9O1xuICAgIGpRdWVyeS5mbi5jb21wb25lbnQgPSBmdW5jdGlvbihjb21wb25lbnRPck5hbWUsIGFyZ3MgPSB7fSkge1xuICAgICAgY29uc3QgZWxlbWVudCA9IHRoaXMuZmlyc3QgPyB0aGlzLmZpcnN0KCkgOiB0aGlzO1xuICAgICAgaWYgKCFjb21wb25lbnRPck5hbWUpIHtcbiAgICAgICAgaWYgKGVsZW1lbnQubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgY29tcCA9IGVsZW1lbnQuZGF0YShcIl9jb21wb25lbnRcIik7XG4gICAgICAgIHJldHVybiBjb21wIHx8IG51bGw7XG4gICAgICB9XG4gICAgICBjb25zdCBleGlzdGluZ0NvbXBvbmVudCA9IGVsZW1lbnQuZGF0YShcIl9jb21wb25lbnRcIik7XG4gICAgICBpZiAoZXhpc3RpbmdDb21wb25lbnQpIHtcbiAgICAgICAgcmV0dXJuIGV4aXN0aW5nQ29tcG9uZW50O1xuICAgICAgfVxuICAgICAgbGV0IENvbXBvbmVudENsYXNzO1xuICAgICAgbGV0IGNvbXBvbmVudE5hbWU7XG4gICAgICBpZiAodHlwZW9mIGNvbXBvbmVudE9yTmFtZSA9PT0gXCJzdHJpbmdcIikge1xuICAgICAgICBjb21wb25lbnROYW1lID0gY29tcG9uZW50T3JOYW1lO1xuICAgICAgICBjb25zdCBmb3VuZCA9IGdldF9jb21wb25lbnRfY2xhc3MoY29tcG9uZW50T3JOYW1lKTtcbiAgICAgICAgYXJncyA9IHsgLi4uYXJncywgX2NvbXBvbmVudF9uYW1lOiBjb21wb25lbnROYW1lIH07XG4gICAgICAgIGlmICghZm91bmQpIHtcbiAgICAgICAgICBDb21wb25lbnRDbGFzcyA9IEpxaHRtbF9Db21wb25lbnQ7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgQ29tcG9uZW50Q2xhc3MgPSBmb3VuZDtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgQ29tcG9uZW50Q2xhc3MgPSBjb21wb25lbnRPck5hbWU7XG4gICAgICB9XG4gICAgICBsZXQgdGFyZ2V0RWxlbWVudCA9IGVsZW1lbnQ7XG4gICAgICBpZiAoY29tcG9uZW50TmFtZSkge1xuICAgICAgICBjb25zdCB0ZW1wbGF0ZSA9IGdldF90ZW1wbGF0ZShjb21wb25lbnROYW1lKTtcbiAgICAgICAgY29uc3QgZXhwZWN0ZWRUYWcgPSBhcmdzLl90YWcgfHwgdGVtcGxhdGUudGFnIHx8IFwiZGl2XCI7XG4gICAgICAgIGNvbnN0IGN1cnJlbnRUYWcgPSBlbGVtZW50LnByb3AoXCJ0YWdOYW1lXCIpLnRvTG93ZXJDYXNlKCk7XG4gICAgICAgIGlmIChjdXJyZW50VGFnICE9PSBleHBlY3RlZFRhZy50b0xvd2VyQ2FzZSgpKSB7XG4gICAgICAgICAgaWYgKGFyZ3MuX2lubmVyX2h0bWwpIHtcbiAgICAgICAgICAgIGNvbnN0IG5ld0VsZW1lbnQgPSBqUXVlcnkoYDwke2V4cGVjdGVkVGFnfT48LyR7ZXhwZWN0ZWRUYWd9PmApO1xuICAgICAgICAgICAgY29uc3Qgb2xkRWwgPSBlbGVtZW50WzBdO1xuICAgICAgICAgICAgaWYgKG9sZEVsICYmIG9sZEVsLmF0dHJpYnV0ZXMpIHtcbiAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBvbGRFbC5hdHRyaWJ1dGVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgYXR0ciA9IG9sZEVsLmF0dHJpYnV0ZXNbaV07XG4gICAgICAgICAgICAgICAgbmV3RWxlbWVudC5hdHRyKGF0dHIubmFtZSwgYXR0ci52YWx1ZSk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIG5ld0VsZW1lbnQuaHRtbChlbGVtZW50Lmh0bWwoKSk7XG4gICAgICAgICAgICBlbGVtZW50LnJlcGxhY2VXaXRoKG5ld0VsZW1lbnQpO1xuICAgICAgICAgICAgdGFyZ2V0RWxlbWVudCA9IG5ld0VsZW1lbnQ7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNvbnNvbGUud2FybihgW0pRSFRNTF0gQ29tcG9uZW50ICcke2NvbXBvbmVudE5hbWV9JyBleHBlY3RzIHRhZyAnPCR7ZXhwZWN0ZWRUYWd9PicgYnV0IGVsZW1lbnQgaXMgJzwke2N1cnJlbnRUYWd9PicuIEVsZW1lbnQgdGFnIHdpbGwgbm90IGJlIGNoYW5nZWQuIENvbnNpZGVyIHVzaW5nIHRoZSBjb3JyZWN0IHRhZy5gKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGNvbnN0IGNvbXBvbmVudCA9IG5ldyBDb21wb25lbnRDbGFzcyh0YXJnZXRFbGVtZW50LCBhcmdzKTtcbiAgICAgIGNvbXBvbmVudC5ib290KCk7XG4gICAgICBhcHBseURlYnVnRGVsYXkoXCJjb21wb25lbnRcIik7XG4gICAgICByZXR1cm4gY29tcG9uZW50O1xuICAgIH07XG4gICAgY29uc3QgX2pxaHRtbF9qcXVlcnlfb3ZlcnJpZGVzID0ge307XG4gICAgY29uc3QgZG9tX2luc2VydGlvbl9tZXRob2RzID0gW1wiYXBwZW5kXCIsIFwicHJlcGVuZFwiLCBcImJlZm9yZVwiLCBcImFmdGVyXCIsIFwicmVwbGFjZVdpdGhcIl07XG4gICAgZm9yIChjb25zdCBmbm5hbWUgb2YgZG9tX2luc2VydGlvbl9tZXRob2RzKSB7XG4gICAgICBfanFodG1sX2pxdWVyeV9vdmVycmlkZXNbZm5uYW1lXSA9IGpRdWVyeS5mbltmbm5hbWVdO1xuICAgICAgalF1ZXJ5LmZuW2ZubmFtZV0gPSBmdW5jdGlvbiguLi5hcmdzKSB7XG4gICAgICAgIGNvbnN0IHJlc29sdmVkQXJncyA9IGFyZ3MubWFwKChhcmcpID0+IHtcbiAgICAgICAgICBpZiAoYXJnICYmIHR5cGVvZiBhcmcgPT09IFwib2JqZWN0XCIgJiYgYXJnIGluc3RhbmNlb2YgSnFodG1sX0NvbXBvbmVudCkge1xuICAgICAgICAgICAgcmV0dXJuIGFyZy4kO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gYXJnO1xuICAgICAgICB9KTtcbiAgICAgICAgY29uc3QgJGVsZW1lbnRzID0gcmVzb2x2ZWRBcmdzLmZpbHRlcigoYXJnKSA9PiBhcmcgaW5zdGFuY2VvZiBqUXVlcnkpO1xuICAgICAgICBjb25zdCByZXQgPSBfanFodG1sX2pxdWVyeV9vdmVycmlkZXNbZm5uYW1lXS5hcHBseSh0aGlzLCByZXNvbHZlZEFyZ3MpO1xuICAgICAgICBmb3IgKGNvbnN0ICRlIG9mICRlbGVtZW50cykge1xuICAgICAgICAgIGlmICgkZS5jbG9zZXN0KFwiaHRtbFwiKS5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAkZS5maW5kKFwiLkpxaHRtbF9Db21wb25lbnRcIikuYWRkQmFjayhcIi5KcWh0bWxfQ29tcG9uZW50XCIpLmVhY2goZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICAgIGNvbnN0ICRjb21wID0galF1ZXJ5KHRoaXMpO1xuICAgICAgICAgICAgICBjb25zdCBjb21wb25lbnQgPSAkY29tcC5kYXRhKFwiX2NvbXBvbmVudFwiKTtcbiAgICAgICAgICAgICAgaWYgKGNvbXBvbmVudCAmJiAhY29tcG9uZW50Ll9yZWFkeV9zdGF0ZSkge1xuICAgICAgICAgICAgICAgIGNvbXBvbmVudC5ib290KCk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmV0O1xuICAgICAgfTtcbiAgICB9XG4gICAgalF1ZXJ5LmZuLnNoYWxsb3dGaW5kID0gZnVuY3Rpb24oc2VsZWN0b3IpIHtcbiAgICAgIGNvbnN0IHJlc3VsdHMgPSBbXTtcbiAgICAgIHRoaXMuZWFjaChmdW5jdGlvbigpIHtcbiAgICAgICAgY29uc3QgdHJhdmVyc2UgPSAocGFyZW50KSA9PiB7XG4gICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBwYXJlbnQuY2hpbGRyZW4ubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGNvbnN0IGNoaWxkID0gcGFyZW50LmNoaWxkcmVuW2ldO1xuICAgICAgICAgICAgaWYgKGpRdWVyeShjaGlsZCkuaXMoc2VsZWN0b3IpKSB7XG4gICAgICAgICAgICAgIHJlc3VsdHMucHVzaChjaGlsZCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICB0cmF2ZXJzZShjaGlsZCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICB0cmF2ZXJzZSh0aGlzKTtcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIGpRdWVyeShyZXN1bHRzKTtcbiAgICB9O1xuICAgIGNvbnN0IG9yaWdpbmFsRW1wdHkgPSBqUXVlcnkuZm4uZW1wdHk7XG4gICAgY29uc3Qgb3JpZ2luYWxIdG1sID0galF1ZXJ5LmZuLmh0bWw7XG4gICAgY29uc3Qgb3JpZ2luYWxUZXh0ID0galF1ZXJ5LmZuLnRleHQ7XG4gICAgalF1ZXJ5LmZuLmVtcHR5ID0gZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gdGhpcy5lYWNoKGZ1bmN0aW9uKCkge1xuICAgICAgICBqUXVlcnkodGhpcykuZmluZChcIi5KcWh0bWxfQ29tcG9uZW50XCIpLmVhY2goZnVuY3Rpb24oKSB7XG4gICAgICAgICAgY29uc3QgY29tcG9uZW50ID0galF1ZXJ5KHRoaXMpLmRhdGEoXCJfY29tcG9uZW50XCIpO1xuICAgICAgICAgIGlmIChjb21wb25lbnQgJiYgIWNvbXBvbmVudC5fc3RvcHBlZCkge1xuICAgICAgICAgICAgY29tcG9uZW50Ll9zdG9wKCk7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgb3JpZ2luYWxFbXB0eS5jYWxsKGpRdWVyeSh0aGlzKSk7XG4gICAgICB9KTtcbiAgICB9O1xuICAgIGpRdWVyeS5mbi5odG1sID0gZnVuY3Rpb24odmFsdWUpIHtcbiAgICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIHJldHVybiBvcmlnaW5hbEh0bWwuY2FsbCh0aGlzKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB0aGlzLmVhY2goZnVuY3Rpb24oKSB7XG4gICAgICAgIGpRdWVyeSh0aGlzKS5lbXB0eSgpO1xuICAgICAgICBvcmlnaW5hbEh0bWwuY2FsbChqUXVlcnkodGhpcyksIHZhbHVlKTtcbiAgICAgIH0pO1xuICAgIH07XG4gICAgalF1ZXJ5LmZuLnRleHQgPSBmdW5jdGlvbih2YWx1ZSkge1xuICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgcmV0dXJuIG9yaWdpbmFsVGV4dC5jYWxsKHRoaXMpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbigpIHtcbiAgICAgICAgalF1ZXJ5KHRoaXMpLmVtcHR5KCk7XG4gICAgICAgIG9yaWdpbmFsVGV4dC5jYWxsKGpRdWVyeSh0aGlzKSwgdmFsdWUpO1xuICAgICAgfSk7XG4gICAgfTtcbiAgfVxuICBpZiAodHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiAmJiB3aW5kb3cualF1ZXJ5KSB7XG4gICAgaW5pdF9qcXVlcnlfcGx1Z2luKHdpbmRvdy5qUXVlcnkpO1xuICB9XG4gIHZhciB2ZXJzaW9uID0gXCIyLjIuMTg1XCI7XG4gIHZhciBqcWh0bWwgPSB7XG4gICAgLy8gQ29yZVxuICAgIEpxaHRtbF9Db21wb25lbnQsXG4gICAgTGlmZWN5Y2xlTWFuYWdlcixcbiAgICAvLyBSZWdpc3RyeVxuICAgIHJlZ2lzdGVyX2NvbXBvbmVudCxcbiAgICBnZXRfY29tcG9uZW50X2NsYXNzLFxuICAgIHJlZ2lzdGVyX3RlbXBsYXRlLFxuICAgIGdldF90ZW1wbGF0ZSxcbiAgICBnZXRfdGVtcGxhdGVfYnlfY2xhc3MsXG4gICAgY3JlYXRlX2NvbXBvbmVudCxcbiAgICBoYXNfY29tcG9uZW50LFxuICAgIGdldF9jb21wb25lbnRfbmFtZXMsXG4gICAgZ2V0X3JlZ2lzdGVyZWRfdGVtcGxhdGVzLFxuICAgIGxpc3RfY29tcG9uZW50cyxcbiAgICAvLyBUZW1wbGF0ZSBzeXN0ZW1cbiAgICBwcm9jZXNzX2luc3RydWN0aW9ucyxcbiAgICBleHRyYWN0X3Nsb3RzLFxuICAgIHJlbmRlcl90ZW1wbGF0ZSxcbiAgICBlc2NhcGVfaHRtbCxcbiAgICAvLyBWZXJzaW9uIHByb3BlcnR5IC0gaW50ZXJuYWxcbiAgICBfX3ZlcnNpb246IHZlcnNpb24sXG4gICAgLy8gRGVidWcgc2V0dGluZ3NcbiAgICBkZWJ1Zzoge1xuICAgICAgZW5hYmxlZDogZmFsc2UsXG4gICAgICB2ZXJib3NlOiBmYWxzZVxuICAgIH0sXG4gICAgLy8gRGVidWcgaGVscGVyIGZ1bmN0aW9ucyAobWFpbmx5IGZvciBpbnRlcm5hbCB1c2UgYnV0IGV4cG9zZWQgZm9yIGFkdmFuY2VkIGRlYnVnZ2luZylcbiAgICBzZXREZWJ1Z1NldHRpbmdzKHNldHRpbmdzKSB7XG4gICAgICBPYmplY3QuYXNzaWduKHRoaXMuZGVidWcsIHNldHRpbmdzKTtcbiAgICB9LFxuICAgIGVuYWJsZURlYnVnTW9kZShsZXZlbCA9IFwiYmFzaWNcIikge1xuICAgICAgaWYgKGxldmVsID09PSBcImJhc2ljXCIpIHtcbiAgICAgICAgdGhpcy5kZWJ1Zy5sb2dDcmVhdGlvblJlYWR5ID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5kZWJ1Zy5sb2dEaXNwYXRjaCA9IHRydWU7XG4gICAgICAgIHRoaXMuZGVidWcuZmxhc2hDb21wb25lbnRzID0gdHJ1ZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuZGVidWcubG9nRnVsbExpZmVjeWNsZSA9IHRydWU7XG4gICAgICAgIHRoaXMuZGVidWcubG9nRGlzcGF0Y2hWZXJib3NlID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5kZWJ1Zy5mbGFzaENvbXBvbmVudHMgPSB0cnVlO1xuICAgICAgICB0aGlzLmRlYnVnLnByb2ZpbGVQZXJmb3JtYW5jZSA9IHRydWU7XG4gICAgICAgIHRoaXMuZGVidWcudHJhY2VEYXRhRmxvdyA9IHRydWU7XG4gICAgICB9XG4gICAgfSxcbiAgICBjbGVhckRlYnVnU2V0dGluZ3MoKSB7XG4gICAgICB0aGlzLmRlYnVnID0ge307XG4gICAgfSxcbiAgICAvLyBEZWJ1ZyBvdmVybGF5IG1ldGhvZHNcbiAgICBzaG93RGVidWdPdmVybGF5KG9wdGlvbnMpIHtcbiAgICAgIHJldHVybiBEZWJ1Z092ZXJsYXkuc2hvdyhvcHRpb25zKTtcbiAgICB9LFxuICAgIGhpZGVEZWJ1Z092ZXJsYXkoKSB7XG4gICAgICByZXR1cm4gRGVidWdPdmVybGF5LmhpZGUoKTtcbiAgICB9LFxuICAgIC8vIEV4cG9ydCBEZWJ1Z092ZXJsYXkgY2xhc3MgZm9yIGRpcmVjdCBhY2Nlc3NcbiAgICBEZWJ1Z092ZXJsYXksXG4gICAgLy8gSW5zdGFsbCBnbG9iYWxzIGZ1bmN0aW9uXG4gICAgaW5zdGFsbEdsb2JhbHMoKSB7XG4gICAgICBpZiAodHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgICB3aW5kb3cuanFodG1sID0gdGhpcztcbiAgICAgICAgd2luZG93LkpxaHRtbF9Db21wb25lbnQgPSBKcWh0bWxfQ29tcG9uZW50O1xuICAgICAgICB3aW5kb3cuSnFodG1sX0xpZmVjeWNsZU1hbmFnZXIgPSBMaWZlY3ljbGVNYW5hZ2VyO1xuICAgICAgfVxuICAgIH0sXG4gICAgLy8gVmVyc2lvbiBkaXNwbGF5IGZ1bmN0aW9uIC0gc2hvd3MgdmVyc2lvbiBvZiBjb3JlIGxpYnJhcnkgYW5kIGFsbCByZWdpc3RlcmVkIHRlbXBsYXRlc1xuICAgIF92ZXJzaW9uKCkge1xuICAgICAgY29uc29sZS5sb2coYEpRSFRNTCBDb3JlIHYke3RoaXMuX192ZXJzaW9ufWApO1xuICAgICAgY29uc29sZS5sb2coXCJSZWdpc3RlcmVkIFRlbXBsYXRlczpcIik7XG4gICAgICBjb25zdCB0ZW1wbGF0ZU5hbWVzID0gZ2V0X2NvbXBvbmVudF9uYW1lcygpO1xuICAgICAgaWYgKHRlbXBsYXRlTmFtZXMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIGNvbnNvbGUubG9nKFwiICAobm8gdGVtcGxhdGVzIHJlZ2lzdGVyZWQpXCIpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZm9yIChjb25zdCBuYW1lIG9mIHRlbXBsYXRlTmFtZXMpIHtcbiAgICAgICAgICBjb25zdCB0ZW1wbGF0ZSA9IGdldF90ZW1wbGF0ZShuYW1lKTtcbiAgICAgICAgICBjb25zdCB0ZW1wbGF0ZVZlcnNpb24gPSB0ZW1wbGF0ZSA/IHRlbXBsYXRlLl9qcWh0bWxfdmVyc2lvbiB8fCBcInVua25vd25cIiA6IFwidW5rbm93blwiO1xuICAgICAgICAgIGNvbnNvbGUubG9nKGAgIC0gJHtuYW1lfTogdiR7dGVtcGxhdGVWZXJzaW9ufWApO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gdGhpcy5fX3ZlcnNpb247XG4gICAgfSxcbiAgICAvLyBQdWJsaWMgdmVyc2lvbiBmdW5jdGlvbiAtIHJldHVybnMgdGhlIHN0YW1wZWQgdmVyc2lvbiBudW1iZXJcbiAgICB2ZXJzaW9uKCkge1xuICAgICAgcmV0dXJuIHZlcnNpb247XG4gICAgfVxuICB9O1xuICBpZiAodHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiAmJiAhd2luZG93LmpxaHRtbCkge1xuICAgIHdpbmRvdy5qcWh0bWwgPSBqcWh0bWw7XG4gICAgd2luZG93LkpxaHRtbF9Db21wb25lbnQgPSBKcWh0bWxfQ29tcG9uZW50O1xuICAgIHdpbmRvdy5Db21wb25lbnQgPSBKcWh0bWxfQ29tcG9uZW50O1xuICAgIHdpbmRvdy5KcWh0bWxfTGlmZWN5Y2xlTWFuYWdlciA9IExpZmVjeWNsZU1hbmFnZXI7XG4gICAgaWYgKGpxaHRtbC5kZWJ1Zz8uZW5hYmxlZCkge1xuICAgICAgY29uc29sZS5sb2coXCJbSlFIVE1MXSBBdXRvLXJlZ2lzdGVyZWQgd2luZG93LmpxaHRtbCBnbG9iYWwgZm9yIHRlbXBsYXRlIGNvbXBhdGliaWxpdHlcIik7XG4gICAgfVxuICB9XG5cbiAgLy8gc3RvcmFnZS9yc3gtdG1wL25wbS1jb21waWxlL2VudHJ5XzY0NTllOGVkMGY2MGJkYTRmMTIxNDIwNzY2MDEyZDUzLmpzXG4gIHdpbmRvdy5fcnN4X25wbSA9IHdpbmRvdy5fcnN4X25wbSB8fCB7fTtcbiAgd2luZG93Ll9yc3hfbnBtLmpxaHRtbCA9IGpxaHRtbDtcbiAgd2luZG93Ll9yc3hfbnBtLl9CYXNlX0pxaHRtbF9Db21wb25lbnQgPSBKcWh0bWxfQ29tcG9uZW50O1xufSkoKTtcbiIsIi8qKlxuICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAqIEJvb3RzdHJhcCBkb20vZGF0YS5qc1xuICogTGljZW5zZWQgdW5kZXIgTUlUIChodHRwczovL2dpdGh1Yi5jb20vdHdicy9ib290c3RyYXAvYmxvYi9tYWluL0xJQ0VOU0UpXG4gKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICovXG5cbi8qKlxuICogQ29uc3RhbnRzXG4gKi9cblxuY29uc3QgZWxlbWVudE1hcCA9IG5ldyBNYXAoKVxuXG5leHBvcnQgZGVmYXVsdCB7XG4gIHNldChlbGVtZW50LCBrZXksIGluc3RhbmNlKSB7XG4gICAgaWYgKCFlbGVtZW50TWFwLmhhcyhlbGVtZW50KSkge1xuICAgICAgZWxlbWVudE1hcC5zZXQoZWxlbWVudCwgbmV3IE1hcCgpKVxuICAgIH1cblxuICAgIGNvbnN0IGluc3RhbmNlTWFwID0gZWxlbWVudE1hcC5nZXQoZWxlbWVudClcblxuICAgIC8vIG1ha2UgaXQgY2xlYXIgd2Ugb25seSB3YW50IG9uZSBpbnN0YW5jZSBwZXIgZWxlbWVudFxuICAgIC8vIGNhbiBiZSByZW1vdmVkIGxhdGVyIHdoZW4gbXVsdGlwbGUga2V5L2luc3RhbmNlcyBhcmUgZmluZSB0byBiZSB1c2VkXG4gICAgaWYgKCFpbnN0YW5jZU1hcC5oYXMoa2V5KSAmJiBpbnN0YW5jZU1hcC5zaXplICE9PSAwKSB7XG4gICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tY29uc29sZVxuICAgICAgY29uc29sZS5lcnJvcihgQm9vdHN0cmFwIGRvZXNuJ3QgYWxsb3cgbW9yZSB0aGFuIG9uZSBpbnN0YW5jZSBwZXIgZWxlbWVudC4gQm91bmQgaW5zdGFuY2U6ICR7QXJyYXkuZnJvbShpbnN0YW5jZU1hcC5rZXlzKCkpWzBdfS5gKVxuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgaW5zdGFuY2VNYXAuc2V0KGtleSwgaW5zdGFuY2UpXG4gIH0sXG5cbiAgZ2V0KGVsZW1lbnQsIGtleSkge1xuICAgIGlmIChlbGVtZW50TWFwLmhhcyhlbGVtZW50KSkge1xuICAgICAgcmV0dXJuIGVsZW1lbnRNYXAuZ2V0KGVsZW1lbnQpLmdldChrZXkpIHx8IG51bGxcbiAgICB9XG5cbiAgICByZXR1cm4gbnVsbFxuICB9LFxuXG4gIHJlbW92ZShlbGVtZW50LCBrZXkpIHtcbiAgICBpZiAoIWVsZW1lbnRNYXAuaGFzKGVsZW1lbnQpKSB7XG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICBjb25zdCBpbnN0YW5jZU1hcCA9IGVsZW1lbnRNYXAuZ2V0KGVsZW1lbnQpXG5cbiAgICBpbnN0YW5jZU1hcC5kZWxldGUoa2V5KVxuXG4gICAgLy8gZnJlZSB1cCBlbGVtZW50IHJlZmVyZW5jZXMgaWYgdGhlcmUgYXJlIG5vIGluc3RhbmNlcyBsZWZ0IGZvciBhbiBlbGVtZW50XG4gICAgaWYgKGluc3RhbmNlTWFwLnNpemUgPT09IDApIHtcbiAgICAgIGVsZW1lbnRNYXAuZGVsZXRlKGVsZW1lbnQpXG4gICAgfVxuICB9XG59XG4iLCIvKipcbiAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gKiBCb290c3RyYXAgdXRpbC9pbmRleC5qc1xuICogTGljZW5zZWQgdW5kZXIgTUlUIChodHRwczovL2dpdGh1Yi5jb20vdHdicy9ib290c3RyYXAvYmxvYi9tYWluL0xJQ0VOU0UpXG4gKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICovXG5cbmNvbnN0IE1BWF9VSUQgPSAxXzAwMF8wMDBcbmNvbnN0IE1JTExJU0VDT05EU19NVUxUSVBMSUVSID0gMTAwMFxuY29uc3QgVFJBTlNJVElPTl9FTkQgPSAndHJhbnNpdGlvbmVuZCdcblxuLyoqXG4gKiBQcm9wZXJseSBlc2NhcGUgSURzIHNlbGVjdG9ycyB0byBoYW5kbGUgd2VpcmQgSURzXG4gKiBAcGFyYW0ge3N0cmluZ30gc2VsZWN0b3JcbiAqIEByZXR1cm5zIHtzdHJpbmd9XG4gKi9cbmNvbnN0IHBhcnNlU2VsZWN0b3IgPSBzZWxlY3RvciA9PiB7XG4gIGlmIChzZWxlY3RvciAmJiB3aW5kb3cuQ1NTICYmIHdpbmRvdy5DU1MuZXNjYXBlKSB7XG4gICAgLy8gZG9jdW1lbnQucXVlcnlTZWxlY3RvciBuZWVkcyBlc2NhcGluZyB0byBoYW5kbGUgSURzIChodG1sNSspIGNvbnRhaW5pbmcgZm9yIGluc3RhbmNlIC9cbiAgICBzZWxlY3RvciA9IHNlbGVjdG9yLnJlcGxhY2UoLyMoW15cXHNcIiMnXSspL2csIChtYXRjaCwgaWQpID0+IGAjJHtDU1MuZXNjYXBlKGlkKX1gKVxuICB9XG5cbiAgcmV0dXJuIHNlbGVjdG9yXG59XG5cbi8vIFNob3V0LW91dCBBbmd1cyBDcm9sbCAoaHR0cHM6Ly9nb28uZ2wvcHh3UUdwKVxuY29uc3QgdG9UeXBlID0gb2JqZWN0ID0+IHtcbiAgaWYgKG9iamVjdCA9PT0gbnVsbCB8fCBvYmplY3QgPT09IHVuZGVmaW5lZCkge1xuICAgIHJldHVybiBgJHtvYmplY3R9YFxuICB9XG5cbiAgcmV0dXJuIE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChvYmplY3QpLm1hdGNoKC9cXHMoW2Etel0rKS9pKVsxXS50b0xvd2VyQ2FzZSgpXG59XG5cbi8qKlxuICogUHVibGljIFV0aWwgQVBJXG4gKi9cblxuY29uc3QgZ2V0VUlEID0gcHJlZml4ID0+IHtcbiAgZG8ge1xuICAgIHByZWZpeCArPSBNYXRoLmZsb29yKE1hdGgucmFuZG9tKCkgKiBNQVhfVUlEKVxuICB9IHdoaWxlIChkb2N1bWVudC5nZXRFbGVtZW50QnlJZChwcmVmaXgpKVxuXG4gIHJldHVybiBwcmVmaXhcbn1cblxuY29uc3QgZ2V0VHJhbnNpdGlvbkR1cmF0aW9uRnJvbUVsZW1lbnQgPSBlbGVtZW50ID0+IHtcbiAgaWYgKCFlbGVtZW50KSB7XG4gICAgcmV0dXJuIDBcbiAgfVxuXG4gIC8vIEdldCB0cmFuc2l0aW9uLWR1cmF0aW9uIG9mIHRoZSBlbGVtZW50XG4gIGxldCB7IHRyYW5zaXRpb25EdXJhdGlvbiwgdHJhbnNpdGlvbkRlbGF5IH0gPSB3aW5kb3cuZ2V0Q29tcHV0ZWRTdHlsZShlbGVtZW50KVxuXG4gIGNvbnN0IGZsb2F0VHJhbnNpdGlvbkR1cmF0aW9uID0gTnVtYmVyLnBhcnNlRmxvYXQodHJhbnNpdGlvbkR1cmF0aW9uKVxuICBjb25zdCBmbG9hdFRyYW5zaXRpb25EZWxheSA9IE51bWJlci5wYXJzZUZsb2F0KHRyYW5zaXRpb25EZWxheSlcblxuICAvLyBSZXR1cm4gMCBpZiBlbGVtZW50IG9yIHRyYW5zaXRpb24gZHVyYXRpb24gaXMgbm90IGZvdW5kXG4gIGlmICghZmxvYXRUcmFuc2l0aW9uRHVyYXRpb24gJiYgIWZsb2F0VHJhbnNpdGlvbkRlbGF5KSB7XG4gICAgcmV0dXJuIDBcbiAgfVxuXG4gIC8vIElmIG11bHRpcGxlIGR1cmF0aW9ucyBhcmUgZGVmaW5lZCwgdGFrZSB0aGUgZmlyc3RcbiAgdHJhbnNpdGlvbkR1cmF0aW9uID0gdHJhbnNpdGlvbkR1cmF0aW9uLnNwbGl0KCcsJylbMF1cbiAgdHJhbnNpdGlvbkRlbGF5ID0gdHJhbnNpdGlvbkRlbGF5LnNwbGl0KCcsJylbMF1cblxuICByZXR1cm4gKE51bWJlci5wYXJzZUZsb2F0KHRyYW5zaXRpb25EdXJhdGlvbikgKyBOdW1iZXIucGFyc2VGbG9hdCh0cmFuc2l0aW9uRGVsYXkpKSAqIE1JTExJU0VDT05EU19NVUxUSVBMSUVSXG59XG5cbmNvbnN0IHRyaWdnZXJUcmFuc2l0aW9uRW5kID0gZWxlbWVudCA9PiB7XG4gIGVsZW1lbnQuZGlzcGF0Y2hFdmVudChuZXcgRXZlbnQoVFJBTlNJVElPTl9FTkQpKVxufVxuXG5jb25zdCBpc0VsZW1lbnQgPSBvYmplY3QgPT4ge1xuICBpZiAoIW9iamVjdCB8fCB0eXBlb2Ygb2JqZWN0ICE9PSAnb2JqZWN0Jykge1xuICAgIHJldHVybiBmYWxzZVxuICB9XG5cbiAgaWYgKHR5cGVvZiBvYmplY3QuanF1ZXJ5ICE9PSAndW5kZWZpbmVkJykge1xuICAgIG9iamVjdCA9IG9iamVjdFswXVxuICB9XG5cbiAgcmV0dXJuIHR5cGVvZiBvYmplY3Qubm9kZVR5cGUgIT09ICd1bmRlZmluZWQnXG59XG5cbmNvbnN0IGdldEVsZW1lbnQgPSBvYmplY3QgPT4ge1xuICAvLyBpdCdzIGEgalF1ZXJ5IG9iamVjdCBvciBhIG5vZGUgZWxlbWVudFxuICBpZiAoaXNFbGVtZW50KG9iamVjdCkpIHtcbiAgICByZXR1cm4gb2JqZWN0LmpxdWVyeSA/IG9iamVjdFswXSA6IG9iamVjdFxuICB9XG5cbiAgaWYgKHR5cGVvZiBvYmplY3QgPT09ICdzdHJpbmcnICYmIG9iamVjdC5sZW5ndGggPiAwKSB7XG4gICAgcmV0dXJuIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IocGFyc2VTZWxlY3RvcihvYmplY3QpKVxuICB9XG5cbiAgcmV0dXJuIG51bGxcbn1cblxuY29uc3QgaXNWaXNpYmxlID0gZWxlbWVudCA9PiB7XG4gIGlmICghaXNFbGVtZW50KGVsZW1lbnQpIHx8IGVsZW1lbnQuZ2V0Q2xpZW50UmVjdHMoKS5sZW5ndGggPT09IDApIHtcbiAgICByZXR1cm4gZmFsc2VcbiAgfVxuXG4gIGNvbnN0IGVsZW1lbnRJc1Zpc2libGUgPSBnZXRDb21wdXRlZFN0eWxlKGVsZW1lbnQpLmdldFByb3BlcnR5VmFsdWUoJ3Zpc2liaWxpdHknKSA9PT0gJ3Zpc2libGUnXG4gIC8vIEhhbmRsZSBgZGV0YWlsc2AgZWxlbWVudCBhcyBpdHMgY29udGVudCBtYXkgZmFsc2llIGFwcGVhciB2aXNpYmxlIHdoZW4gaXQgaXMgY2xvc2VkXG4gIGNvbnN0IGNsb3NlZERldGFpbHMgPSBlbGVtZW50LmNsb3Nlc3QoJ2RldGFpbHM6bm90KFtvcGVuXSknKVxuXG4gIGlmICghY2xvc2VkRGV0YWlscykge1xuICAgIHJldHVybiBlbGVtZW50SXNWaXNpYmxlXG4gIH1cblxuICBpZiAoY2xvc2VkRGV0YWlscyAhPT0gZWxlbWVudCkge1xuICAgIGNvbnN0IHN1bW1hcnkgPSBlbGVtZW50LmNsb3Nlc3QoJ3N1bW1hcnknKVxuICAgIGlmIChzdW1tYXJ5ICYmIHN1bW1hcnkucGFyZW50Tm9kZSAhPT0gY2xvc2VkRGV0YWlscykge1xuICAgICAgcmV0dXJuIGZhbHNlXG4gICAgfVxuXG4gICAgaWYgKHN1bW1hcnkgPT09IG51bGwpIHtcbiAgICAgIHJldHVybiBmYWxzZVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBlbGVtZW50SXNWaXNpYmxlXG59XG5cbmNvbnN0IGlzRGlzYWJsZWQgPSBlbGVtZW50ID0+IHtcbiAgaWYgKCFlbGVtZW50IHx8IGVsZW1lbnQubm9kZVR5cGUgIT09IE5vZGUuRUxFTUVOVF9OT0RFKSB7XG4gICAgcmV0dXJuIHRydWVcbiAgfVxuXG4gIGlmIChlbGVtZW50LmNsYXNzTGlzdC5jb250YWlucygnZGlzYWJsZWQnKSkge1xuICAgIHJldHVybiB0cnVlXG4gIH1cblxuICBpZiAodHlwZW9mIGVsZW1lbnQuZGlzYWJsZWQgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgcmV0dXJuIGVsZW1lbnQuZGlzYWJsZWRcbiAgfVxuXG4gIHJldHVybiBlbGVtZW50Lmhhc0F0dHJpYnV0ZSgnZGlzYWJsZWQnKSAmJiBlbGVtZW50LmdldEF0dHJpYnV0ZSgnZGlzYWJsZWQnKSAhPT0gJ2ZhbHNlJ1xufVxuXG5jb25zdCBmaW5kU2hhZG93Um9vdCA9IGVsZW1lbnQgPT4ge1xuICBpZiAoIWRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5hdHRhY2hTaGFkb3cpIHtcbiAgICByZXR1cm4gbnVsbFxuICB9XG5cbiAgLy8gQ2FuIGZpbmQgdGhlIHNoYWRvdyByb290IG90aGVyd2lzZSBpdCdsbCByZXR1cm4gdGhlIGRvY3VtZW50XG4gIGlmICh0eXBlb2YgZWxlbWVudC5nZXRSb290Tm9kZSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIGNvbnN0IHJvb3QgPSBlbGVtZW50LmdldFJvb3ROb2RlKClcbiAgICByZXR1cm4gcm9vdCBpbnN0YW5jZW9mIFNoYWRvd1Jvb3QgPyByb290IDogbnVsbFxuICB9XG5cbiAgaWYgKGVsZW1lbnQgaW5zdGFuY2VvZiBTaGFkb3dSb290KSB7XG4gICAgcmV0dXJuIGVsZW1lbnRcbiAgfVxuXG4gIC8vIHdoZW4gd2UgZG9uJ3QgZmluZCBhIHNoYWRvdyByb290XG4gIGlmICghZWxlbWVudC5wYXJlbnROb2RlKSB7XG4gICAgcmV0dXJuIG51bGxcbiAgfVxuXG4gIHJldHVybiBmaW5kU2hhZG93Um9vdChlbGVtZW50LnBhcmVudE5vZGUpXG59XG5cbmNvbnN0IG5vb3AgPSAoKSA9PiB7fVxuXG4vKipcbiAqIFRyaWNrIHRvIHJlc3RhcnQgYW4gZWxlbWVudCdzIGFuaW1hdGlvblxuICpcbiAqIEBwYXJhbSB7SFRNTEVsZW1lbnR9IGVsZW1lbnRcbiAqIEByZXR1cm4gdm9pZFxuICpcbiAqIEBzZWUgaHR0cHM6Ly93d3cuY2hhcmlzdGhlby5pby9ibG9nLzIwMjEvMDIvcmVzdGFydC1hLWNzcy1hbmltYXRpb24td2l0aC1qYXZhc2NyaXB0LyNyZXN0YXJ0aW5nLWEtY3NzLWFuaW1hdGlvblxuICovXG5jb25zdCByZWZsb3cgPSBlbGVtZW50ID0+IHtcbiAgZWxlbWVudC5vZmZzZXRIZWlnaHQgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby11bnVzZWQtZXhwcmVzc2lvbnNcbn1cblxuY29uc3QgZ2V0alF1ZXJ5ID0gKCkgPT4ge1xuICBpZiAod2luZG93LmpRdWVyeSAmJiAhZG9jdW1lbnQuYm9keS5oYXNBdHRyaWJ1dGUoJ2RhdGEtYnMtbm8tanF1ZXJ5JykpIHtcbiAgICByZXR1cm4gd2luZG93LmpRdWVyeVxuICB9XG5cbiAgcmV0dXJuIG51bGxcbn1cblxuY29uc3QgRE9NQ29udGVudExvYWRlZENhbGxiYWNrcyA9IFtdXG5cbmNvbnN0IG9uRE9NQ29udGVudExvYWRlZCA9IGNhbGxiYWNrID0+IHtcbiAgaWYgKGRvY3VtZW50LnJlYWR5U3RhdGUgPT09ICdsb2FkaW5nJykge1xuICAgIC8vIGFkZCBsaXN0ZW5lciBvbiB0aGUgZmlyc3QgY2FsbCB3aGVuIHRoZSBkb2N1bWVudCBpcyBpbiBsb2FkaW5nIHN0YXRlXG4gICAgaWYgKCFET01Db250ZW50TG9hZGVkQ2FsbGJhY2tzLmxlbmd0aCkge1xuICAgICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignRE9NQ29udGVudExvYWRlZCcsICgpID0+IHtcbiAgICAgICAgZm9yIChjb25zdCBjYWxsYmFjayBvZiBET01Db250ZW50TG9hZGVkQ2FsbGJhY2tzKSB7XG4gICAgICAgICAgY2FsbGJhY2soKVxuICAgICAgICB9XG4gICAgICB9KVxuICAgIH1cblxuICAgIERPTUNvbnRlbnRMb2FkZWRDYWxsYmFja3MucHVzaChjYWxsYmFjaylcbiAgfSBlbHNlIHtcbiAgICBjYWxsYmFjaygpXG4gIH1cbn1cblxuY29uc3QgaXNSVEwgPSAoKSA9PiBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuZGlyID09PSAncnRsJ1xuXG5jb25zdCBkZWZpbmVKUXVlcnlQbHVnaW4gPSBwbHVnaW4gPT4ge1xuICBvbkRPTUNvbnRlbnRMb2FkZWQoKCkgPT4ge1xuICAgIGNvbnN0ICQgPSBnZXRqUXVlcnkoKVxuICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBpZiAqL1xuICAgIGlmICgkKSB7XG4gICAgICBjb25zdCBuYW1lID0gcGx1Z2luLk5BTUVcbiAgICAgIGNvbnN0IEpRVUVSWV9OT19DT05GTElDVCA9ICQuZm5bbmFtZV1cbiAgICAgICQuZm5bbmFtZV0gPSBwbHVnaW4ualF1ZXJ5SW50ZXJmYWNlXG4gICAgICAkLmZuW25hbWVdLkNvbnN0cnVjdG9yID0gcGx1Z2luXG4gICAgICAkLmZuW25hbWVdLm5vQ29uZmxpY3QgPSAoKSA9PiB7XG4gICAgICAgICQuZm5bbmFtZV0gPSBKUVVFUllfTk9fQ09ORkxJQ1RcbiAgICAgICAgcmV0dXJuIHBsdWdpbi5qUXVlcnlJbnRlcmZhY2VcbiAgICAgIH1cbiAgICB9XG4gIH0pXG59XG5cbmNvbnN0IGV4ZWN1dGUgPSAocG9zc2libGVDYWxsYmFjaywgYXJncyA9IFtdLCBkZWZhdWx0VmFsdWUgPSBwb3NzaWJsZUNhbGxiYWNrKSA9PiB7XG4gIHJldHVybiB0eXBlb2YgcG9zc2libGVDYWxsYmFjayA9PT0gJ2Z1bmN0aW9uJyA/IHBvc3NpYmxlQ2FsbGJhY2soLi4uYXJncykgOiBkZWZhdWx0VmFsdWVcbn1cblxuY29uc3QgZXhlY3V0ZUFmdGVyVHJhbnNpdGlvbiA9IChjYWxsYmFjaywgdHJhbnNpdGlvbkVsZW1lbnQsIHdhaXRGb3JUcmFuc2l0aW9uID0gdHJ1ZSkgPT4ge1xuICBpZiAoIXdhaXRGb3JUcmFuc2l0aW9uKSB7XG4gICAgZXhlY3V0ZShjYWxsYmFjaylcbiAgICByZXR1cm5cbiAgfVxuXG4gIGNvbnN0IGR1cmF0aW9uUGFkZGluZyA9IDVcbiAgY29uc3QgZW11bGF0ZWREdXJhdGlvbiA9IGdldFRyYW5zaXRpb25EdXJhdGlvbkZyb21FbGVtZW50KHRyYW5zaXRpb25FbGVtZW50KSArIGR1cmF0aW9uUGFkZGluZ1xuXG4gIGxldCBjYWxsZWQgPSBmYWxzZVxuXG4gIGNvbnN0IGhhbmRsZXIgPSAoeyB0YXJnZXQgfSkgPT4ge1xuICAgIGlmICh0YXJnZXQgIT09IHRyYW5zaXRpb25FbGVtZW50KSB7XG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICBjYWxsZWQgPSB0cnVlXG4gICAgdHJhbnNpdGlvbkVsZW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcihUUkFOU0lUSU9OX0VORCwgaGFuZGxlcilcbiAgICBleGVjdXRlKGNhbGxiYWNrKVxuICB9XG5cbiAgdHJhbnNpdGlvbkVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihUUkFOU0lUSU9OX0VORCwgaGFuZGxlcilcbiAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgaWYgKCFjYWxsZWQpIHtcbiAgICAgIHRyaWdnZXJUcmFuc2l0aW9uRW5kKHRyYW5zaXRpb25FbGVtZW50KVxuICAgIH1cbiAgfSwgZW11bGF0ZWREdXJhdGlvbilcbn1cblxuLyoqXG4gKiBSZXR1cm4gdGhlIHByZXZpb3VzL25leHQgZWxlbWVudCBvZiBhIGxpc3QuXG4gKlxuICogQHBhcmFtIHthcnJheX0gbGlzdCAgICBUaGUgbGlzdCBvZiBlbGVtZW50c1xuICogQHBhcmFtIGFjdGl2ZUVsZW1lbnQgICBUaGUgYWN0aXZlIGVsZW1lbnRcbiAqIEBwYXJhbSBzaG91bGRHZXROZXh0ICAgQ2hvb3NlIHRvIGdldCBuZXh0IG9yIHByZXZpb3VzIGVsZW1lbnRcbiAqIEBwYXJhbSBpc0N5Y2xlQWxsb3dlZFxuICogQHJldHVybiB7RWxlbWVudHxlbGVtfSBUaGUgcHJvcGVyIGVsZW1lbnRcbiAqL1xuY29uc3QgZ2V0TmV4dEFjdGl2ZUVsZW1lbnQgPSAobGlzdCwgYWN0aXZlRWxlbWVudCwgc2hvdWxkR2V0TmV4dCwgaXNDeWNsZUFsbG93ZWQpID0+IHtcbiAgY29uc3QgbGlzdExlbmd0aCA9IGxpc3QubGVuZ3RoXG4gIGxldCBpbmRleCA9IGxpc3QuaW5kZXhPZihhY3RpdmVFbGVtZW50KVxuXG4gIC8vIGlmIHRoZSBlbGVtZW50IGRvZXMgbm90IGV4aXN0IGluIHRoZSBsaXN0IHJldHVybiBhbiBlbGVtZW50XG4gIC8vIGRlcGVuZGluZyBvbiB0aGUgZGlyZWN0aW9uIGFuZCBpZiBjeWNsZSBpcyBhbGxvd2VkXG4gIGlmIChpbmRleCA9PT0gLTEpIHtcbiAgICByZXR1cm4gIXNob3VsZEdldE5leHQgJiYgaXNDeWNsZUFsbG93ZWQgPyBsaXN0W2xpc3RMZW5ndGggLSAxXSA6IGxpc3RbMF1cbiAgfVxuXG4gIGluZGV4ICs9IHNob3VsZEdldE5leHQgPyAxIDogLTFcblxuICBpZiAoaXNDeWNsZUFsbG93ZWQpIHtcbiAgICBpbmRleCA9IChpbmRleCArIGxpc3RMZW5ndGgpICUgbGlzdExlbmd0aFxuICB9XG5cbiAgcmV0dXJuIGxpc3RbTWF0aC5tYXgoMCwgTWF0aC5taW4oaW5kZXgsIGxpc3RMZW5ndGggLSAxKSldXG59XG5cbmV4cG9ydCB7XG4gIGRlZmluZUpRdWVyeVBsdWdpbixcbiAgZXhlY3V0ZSxcbiAgZXhlY3V0ZUFmdGVyVHJhbnNpdGlvbixcbiAgZmluZFNoYWRvd1Jvb3QsXG4gIGdldEVsZW1lbnQsXG4gIGdldGpRdWVyeSxcbiAgZ2V0TmV4dEFjdGl2ZUVsZW1lbnQsXG4gIGdldFRyYW5zaXRpb25EdXJhdGlvbkZyb21FbGVtZW50LFxuICBnZXRVSUQsXG4gIGlzRGlzYWJsZWQsXG4gIGlzRWxlbWVudCxcbiAgaXNSVEwsXG4gIGlzVmlzaWJsZSxcbiAgbm9vcCxcbiAgb25ET01Db250ZW50TG9hZGVkLFxuICBwYXJzZVNlbGVjdG9yLFxuICByZWZsb3csXG4gIHRyaWdnZXJUcmFuc2l0aW9uRW5kLFxuICB0b1R5cGVcbn1cbiIsIi8qKlxuICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAqIEJvb3RzdHJhcCBkb20vZXZlbnQtaGFuZGxlci5qc1xuICogTGljZW5zZWQgdW5kZXIgTUlUIChodHRwczovL2dpdGh1Yi5jb20vdHdicy9ib290c3RyYXAvYmxvYi9tYWluL0xJQ0VOU0UpXG4gKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICovXG5cbmltcG9ydCB7IGdldGpRdWVyeSB9IGZyb20gJy4uL3V0aWwvaW5kZXguanMnXG5cbi8qKlxuICogQ29uc3RhbnRzXG4gKi9cblxuY29uc3QgbmFtZXNwYWNlUmVnZXggPSAvW14uXSooPz1cXC4uKilcXC58LiovXG5jb25zdCBzdHJpcE5hbWVSZWdleCA9IC9cXC4uKi9cbmNvbnN0IHN0cmlwVWlkUmVnZXggPSAvOjpcXGQrJC9cbmNvbnN0IGV2ZW50UmVnaXN0cnkgPSB7fSAvLyBFdmVudHMgc3RvcmFnZVxubGV0IHVpZEV2ZW50ID0gMVxuY29uc3QgY3VzdG9tRXZlbnRzID0ge1xuICBtb3VzZWVudGVyOiAnbW91c2VvdmVyJyxcbiAgbW91c2VsZWF2ZTogJ21vdXNlb3V0J1xufVxuXG5jb25zdCBuYXRpdmVFdmVudHMgPSBuZXcgU2V0KFtcbiAgJ2NsaWNrJyxcbiAgJ2RibGNsaWNrJyxcbiAgJ21vdXNldXAnLFxuICAnbW91c2Vkb3duJyxcbiAgJ2NvbnRleHRtZW51JyxcbiAgJ21vdXNld2hlZWwnLFxuICAnRE9NTW91c2VTY3JvbGwnLFxuICAnbW91c2VvdmVyJyxcbiAgJ21vdXNlb3V0JyxcbiAgJ21vdXNlbW92ZScsXG4gICdzZWxlY3RzdGFydCcsXG4gICdzZWxlY3RlbmQnLFxuICAna2V5ZG93bicsXG4gICdrZXlwcmVzcycsXG4gICdrZXl1cCcsXG4gICdvcmllbnRhdGlvbmNoYW5nZScsXG4gICd0b3VjaHN0YXJ0JyxcbiAgJ3RvdWNobW92ZScsXG4gICd0b3VjaGVuZCcsXG4gICd0b3VjaGNhbmNlbCcsXG4gICdwb2ludGVyZG93bicsXG4gICdwb2ludGVybW92ZScsXG4gICdwb2ludGVydXAnLFxuICAncG9pbnRlcmxlYXZlJyxcbiAgJ3BvaW50ZXJjYW5jZWwnLFxuICAnZ2VzdHVyZXN0YXJ0JyxcbiAgJ2dlc3R1cmVjaGFuZ2UnLFxuICAnZ2VzdHVyZWVuZCcsXG4gICdmb2N1cycsXG4gICdibHVyJyxcbiAgJ2NoYW5nZScsXG4gICdyZXNldCcsXG4gICdzZWxlY3QnLFxuICAnc3VibWl0JyxcbiAgJ2ZvY3VzaW4nLFxuICAnZm9jdXNvdXQnLFxuICAnbG9hZCcsXG4gICd1bmxvYWQnLFxuICAnYmVmb3JldW5sb2FkJyxcbiAgJ3Jlc2l6ZScsXG4gICdtb3ZlJyxcbiAgJ0RPTUNvbnRlbnRMb2FkZWQnLFxuICAncmVhZHlzdGF0ZWNoYW5nZScsXG4gICdlcnJvcicsXG4gICdhYm9ydCcsXG4gICdzY3JvbGwnXG5dKVxuXG4vKipcbiAqIFByaXZhdGUgbWV0aG9kc1xuICovXG5cbmZ1bmN0aW9uIG1ha2VFdmVudFVpZChlbGVtZW50LCB1aWQpIHtcbiAgcmV0dXJuICh1aWQgJiYgYCR7dWlkfTo6JHt1aWRFdmVudCsrfWApIHx8IGVsZW1lbnQudWlkRXZlbnQgfHwgdWlkRXZlbnQrK1xufVxuXG5mdW5jdGlvbiBnZXRFbGVtZW50RXZlbnRzKGVsZW1lbnQpIHtcbiAgY29uc3QgdWlkID0gbWFrZUV2ZW50VWlkKGVsZW1lbnQpXG5cbiAgZWxlbWVudC51aWRFdmVudCA9IHVpZFxuICBldmVudFJlZ2lzdHJ5W3VpZF0gPSBldmVudFJlZ2lzdHJ5W3VpZF0gfHwge31cblxuICByZXR1cm4gZXZlbnRSZWdpc3RyeVt1aWRdXG59XG5cbmZ1bmN0aW9uIGJvb3RzdHJhcEhhbmRsZXIoZWxlbWVudCwgZm4pIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIGhhbmRsZXIoZXZlbnQpIHtcbiAgICBoeWRyYXRlT2JqKGV2ZW50LCB7IGRlbGVnYXRlVGFyZ2V0OiBlbGVtZW50IH0pXG5cbiAgICBpZiAoaGFuZGxlci5vbmVPZmYpIHtcbiAgICAgIEV2ZW50SGFuZGxlci5vZmYoZWxlbWVudCwgZXZlbnQudHlwZSwgZm4pXG4gICAgfVxuXG4gICAgcmV0dXJuIGZuLmFwcGx5KGVsZW1lbnQsIFtldmVudF0pXG4gIH1cbn1cblxuZnVuY3Rpb24gYm9vdHN0cmFwRGVsZWdhdGlvbkhhbmRsZXIoZWxlbWVudCwgc2VsZWN0b3IsIGZuKSB7XG4gIHJldHVybiBmdW5jdGlvbiBoYW5kbGVyKGV2ZW50KSB7XG4gICAgY29uc3QgZG9tRWxlbWVudHMgPSBlbGVtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoc2VsZWN0b3IpXG5cbiAgICBmb3IgKGxldCB7IHRhcmdldCB9ID0gZXZlbnQ7IHRhcmdldCAmJiB0YXJnZXQgIT09IHRoaXM7IHRhcmdldCA9IHRhcmdldC5wYXJlbnROb2RlKSB7XG4gICAgICBmb3IgKGNvbnN0IGRvbUVsZW1lbnQgb2YgZG9tRWxlbWVudHMpIHtcbiAgICAgICAgaWYgKGRvbUVsZW1lbnQgIT09IHRhcmdldCkge1xuICAgICAgICAgIGNvbnRpbnVlXG4gICAgICAgIH1cblxuICAgICAgICBoeWRyYXRlT2JqKGV2ZW50LCB7IGRlbGVnYXRlVGFyZ2V0OiB0YXJnZXQgfSlcblxuICAgICAgICBpZiAoaGFuZGxlci5vbmVPZmYpIHtcbiAgICAgICAgICBFdmVudEhhbmRsZXIub2ZmKGVsZW1lbnQsIGV2ZW50LnR5cGUsIHNlbGVjdG9yLCBmbilcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBmbi5hcHBseSh0YXJnZXQsIFtldmVudF0pXG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIGZpbmRIYW5kbGVyKGV2ZW50cywgY2FsbGFibGUsIGRlbGVnYXRpb25TZWxlY3RvciA9IG51bGwpIHtcbiAgcmV0dXJuIE9iamVjdC52YWx1ZXMoZXZlbnRzKVxuICAgIC5maW5kKGV2ZW50ID0+IGV2ZW50LmNhbGxhYmxlID09PSBjYWxsYWJsZSAmJiBldmVudC5kZWxlZ2F0aW9uU2VsZWN0b3IgPT09IGRlbGVnYXRpb25TZWxlY3Rvcilcbn1cblxuZnVuY3Rpb24gbm9ybWFsaXplUGFyYW1ldGVycyhvcmlnaW5hbFR5cGVFdmVudCwgaGFuZGxlciwgZGVsZWdhdGlvbkZ1bmN0aW9uKSB7XG4gIGNvbnN0IGlzRGVsZWdhdGVkID0gdHlwZW9mIGhhbmRsZXIgPT09ICdzdHJpbmcnXG4gIC8vIFRPRE86IHRvb2x0aXAgcGFzc2VzIGBmYWxzZWAgaW5zdGVhZCBvZiBzZWxlY3Rvciwgc28gd2UgbmVlZCB0byBjaGVja1xuICBjb25zdCBjYWxsYWJsZSA9IGlzRGVsZWdhdGVkID8gZGVsZWdhdGlvbkZ1bmN0aW9uIDogKGhhbmRsZXIgfHwgZGVsZWdhdGlvbkZ1bmN0aW9uKVxuICBsZXQgdHlwZUV2ZW50ID0gZ2V0VHlwZUV2ZW50KG9yaWdpbmFsVHlwZUV2ZW50KVxuXG4gIGlmICghbmF0aXZlRXZlbnRzLmhhcyh0eXBlRXZlbnQpKSB7XG4gICAgdHlwZUV2ZW50ID0gb3JpZ2luYWxUeXBlRXZlbnRcbiAgfVxuXG4gIHJldHVybiBbaXNEZWxlZ2F0ZWQsIGNhbGxhYmxlLCB0eXBlRXZlbnRdXG59XG5cbmZ1bmN0aW9uIGFkZEhhbmRsZXIoZWxlbWVudCwgb3JpZ2luYWxUeXBlRXZlbnQsIGhhbmRsZXIsIGRlbGVnYXRpb25GdW5jdGlvbiwgb25lT2ZmKSB7XG4gIGlmICh0eXBlb2Ygb3JpZ2luYWxUeXBlRXZlbnQgIT09ICdzdHJpbmcnIHx8ICFlbGVtZW50KSB7XG4gICAgcmV0dXJuXG4gIH1cblxuICBsZXQgW2lzRGVsZWdhdGVkLCBjYWxsYWJsZSwgdHlwZUV2ZW50XSA9IG5vcm1hbGl6ZVBhcmFtZXRlcnMob3JpZ2luYWxUeXBlRXZlbnQsIGhhbmRsZXIsIGRlbGVnYXRpb25GdW5jdGlvbilcblxuICAvLyBpbiBjYXNlIG9mIG1vdXNlZW50ZXIgb3IgbW91c2VsZWF2ZSB3cmFwIHRoZSBoYW5kbGVyIHdpdGhpbiBhIGZ1bmN0aW9uIHRoYXQgY2hlY2tzIGZvciBpdHMgRE9NIHBvc2l0aW9uXG4gIC8vIHRoaXMgcHJldmVudHMgdGhlIGhhbmRsZXIgZnJvbSBiZWluZyBkaXNwYXRjaGVkIHRoZSBzYW1lIHdheSBhcyBtb3VzZW92ZXIgb3IgbW91c2VvdXQgZG9lc1xuICBpZiAob3JpZ2luYWxUeXBlRXZlbnQgaW4gY3VzdG9tRXZlbnRzKSB7XG4gICAgY29uc3Qgd3JhcEZ1bmN0aW9uID0gZm4gPT4ge1xuICAgICAgcmV0dXJuIGZ1bmN0aW9uIChldmVudCkge1xuICAgICAgICBpZiAoIWV2ZW50LnJlbGF0ZWRUYXJnZXQgfHwgKGV2ZW50LnJlbGF0ZWRUYXJnZXQgIT09IGV2ZW50LmRlbGVnYXRlVGFyZ2V0ICYmICFldmVudC5kZWxlZ2F0ZVRhcmdldC5jb250YWlucyhldmVudC5yZWxhdGVkVGFyZ2V0KSkpIHtcbiAgICAgICAgICByZXR1cm4gZm4uY2FsbCh0aGlzLCBldmVudClcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIGNhbGxhYmxlID0gd3JhcEZ1bmN0aW9uKGNhbGxhYmxlKVxuICB9XG5cbiAgY29uc3QgZXZlbnRzID0gZ2V0RWxlbWVudEV2ZW50cyhlbGVtZW50KVxuICBjb25zdCBoYW5kbGVycyA9IGV2ZW50c1t0eXBlRXZlbnRdIHx8IChldmVudHNbdHlwZUV2ZW50XSA9IHt9KVxuICBjb25zdCBwcmV2aW91c0Z1bmN0aW9uID0gZmluZEhhbmRsZXIoaGFuZGxlcnMsIGNhbGxhYmxlLCBpc0RlbGVnYXRlZCA/IGhhbmRsZXIgOiBudWxsKVxuXG4gIGlmIChwcmV2aW91c0Z1bmN0aW9uKSB7XG4gICAgcHJldmlvdXNGdW5jdGlvbi5vbmVPZmYgPSBwcmV2aW91c0Z1bmN0aW9uLm9uZU9mZiAmJiBvbmVPZmZcblxuICAgIHJldHVyblxuICB9XG5cbiAgY29uc3QgdWlkID0gbWFrZUV2ZW50VWlkKGNhbGxhYmxlLCBvcmlnaW5hbFR5cGVFdmVudC5yZXBsYWNlKG5hbWVzcGFjZVJlZ2V4LCAnJykpXG4gIGNvbnN0IGZuID0gaXNEZWxlZ2F0ZWQgP1xuICAgIGJvb3RzdHJhcERlbGVnYXRpb25IYW5kbGVyKGVsZW1lbnQsIGhhbmRsZXIsIGNhbGxhYmxlKSA6XG4gICAgYm9vdHN0cmFwSGFuZGxlcihlbGVtZW50LCBjYWxsYWJsZSlcblxuICBmbi5kZWxlZ2F0aW9uU2VsZWN0b3IgPSBpc0RlbGVnYXRlZCA/IGhhbmRsZXIgOiBudWxsXG4gIGZuLmNhbGxhYmxlID0gY2FsbGFibGVcbiAgZm4ub25lT2ZmID0gb25lT2ZmXG4gIGZuLnVpZEV2ZW50ID0gdWlkXG4gIGhhbmRsZXJzW3VpZF0gPSBmblxuXG4gIGVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcih0eXBlRXZlbnQsIGZuLCBpc0RlbGVnYXRlZClcbn1cblxuZnVuY3Rpb24gcmVtb3ZlSGFuZGxlcihlbGVtZW50LCBldmVudHMsIHR5cGVFdmVudCwgaGFuZGxlciwgZGVsZWdhdGlvblNlbGVjdG9yKSB7XG4gIGNvbnN0IGZuID0gZmluZEhhbmRsZXIoZXZlbnRzW3R5cGVFdmVudF0sIGhhbmRsZXIsIGRlbGVnYXRpb25TZWxlY3RvcilcblxuICBpZiAoIWZuKSB7XG4gICAgcmV0dXJuXG4gIH1cblxuICBlbGVtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIodHlwZUV2ZW50LCBmbiwgQm9vbGVhbihkZWxlZ2F0aW9uU2VsZWN0b3IpKVxuICBkZWxldGUgZXZlbnRzW3R5cGVFdmVudF1bZm4udWlkRXZlbnRdXG59XG5cbmZ1bmN0aW9uIHJlbW92ZU5hbWVzcGFjZWRIYW5kbGVycyhlbGVtZW50LCBldmVudHMsIHR5cGVFdmVudCwgbmFtZXNwYWNlKSB7XG4gIGNvbnN0IHN0b3JlRWxlbWVudEV2ZW50ID0gZXZlbnRzW3R5cGVFdmVudF0gfHwge31cblxuICBmb3IgKGNvbnN0IFtoYW5kbGVyS2V5LCBldmVudF0gb2YgT2JqZWN0LmVudHJpZXMoc3RvcmVFbGVtZW50RXZlbnQpKSB7XG4gICAgaWYgKGhhbmRsZXJLZXkuaW5jbHVkZXMobmFtZXNwYWNlKSkge1xuICAgICAgcmVtb3ZlSGFuZGxlcihlbGVtZW50LCBldmVudHMsIHR5cGVFdmVudCwgZXZlbnQuY2FsbGFibGUsIGV2ZW50LmRlbGVnYXRpb25TZWxlY3RvcilcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gZ2V0VHlwZUV2ZW50KGV2ZW50KSB7XG4gIC8vIGFsbG93IHRvIGdldCB0aGUgbmF0aXZlIGV2ZW50cyBmcm9tIG5hbWVzcGFjZWQgZXZlbnRzICgnY2xpY2suYnMuYnV0dG9uJyAtLT4gJ2NsaWNrJylcbiAgZXZlbnQgPSBldmVudC5yZXBsYWNlKHN0cmlwTmFtZVJlZ2V4LCAnJylcbiAgcmV0dXJuIGN1c3RvbUV2ZW50c1tldmVudF0gfHwgZXZlbnRcbn1cblxuY29uc3QgRXZlbnRIYW5kbGVyID0ge1xuICBvbihlbGVtZW50LCBldmVudCwgaGFuZGxlciwgZGVsZWdhdGlvbkZ1bmN0aW9uKSB7XG4gICAgYWRkSGFuZGxlcihlbGVtZW50LCBldmVudCwgaGFuZGxlciwgZGVsZWdhdGlvbkZ1bmN0aW9uLCBmYWxzZSlcbiAgfSxcblxuICBvbmUoZWxlbWVudCwgZXZlbnQsIGhhbmRsZXIsIGRlbGVnYXRpb25GdW5jdGlvbikge1xuICAgIGFkZEhhbmRsZXIoZWxlbWVudCwgZXZlbnQsIGhhbmRsZXIsIGRlbGVnYXRpb25GdW5jdGlvbiwgdHJ1ZSlcbiAgfSxcblxuICBvZmYoZWxlbWVudCwgb3JpZ2luYWxUeXBlRXZlbnQsIGhhbmRsZXIsIGRlbGVnYXRpb25GdW5jdGlvbikge1xuICAgIGlmICh0eXBlb2Ygb3JpZ2luYWxUeXBlRXZlbnQgIT09ICdzdHJpbmcnIHx8ICFlbGVtZW50KSB7XG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICBjb25zdCBbaXNEZWxlZ2F0ZWQsIGNhbGxhYmxlLCB0eXBlRXZlbnRdID0gbm9ybWFsaXplUGFyYW1ldGVycyhvcmlnaW5hbFR5cGVFdmVudCwgaGFuZGxlciwgZGVsZWdhdGlvbkZ1bmN0aW9uKVxuICAgIGNvbnN0IGluTmFtZXNwYWNlID0gdHlwZUV2ZW50ICE9PSBvcmlnaW5hbFR5cGVFdmVudFxuICAgIGNvbnN0IGV2ZW50cyA9IGdldEVsZW1lbnRFdmVudHMoZWxlbWVudClcbiAgICBjb25zdCBzdG9yZUVsZW1lbnRFdmVudCA9IGV2ZW50c1t0eXBlRXZlbnRdIHx8IHt9XG4gICAgY29uc3QgaXNOYW1lc3BhY2UgPSBvcmlnaW5hbFR5cGVFdmVudC5zdGFydHNXaXRoKCcuJylcblxuICAgIGlmICh0eXBlb2YgY2FsbGFibGUgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAvLyBTaW1wbGVzdCBjYXNlOiBoYW5kbGVyIGlzIHBhc3NlZCwgcmVtb3ZlIHRoYXQgbGlzdGVuZXIgT05MWS5cbiAgICAgIGlmICghT2JqZWN0LmtleXMoc3RvcmVFbGVtZW50RXZlbnQpLmxlbmd0aCkge1xuICAgICAgICByZXR1cm5cbiAgICAgIH1cblxuICAgICAgcmVtb3ZlSGFuZGxlcihlbGVtZW50LCBldmVudHMsIHR5cGVFdmVudCwgY2FsbGFibGUsIGlzRGVsZWdhdGVkID8gaGFuZGxlciA6IG51bGwpXG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICBpZiAoaXNOYW1lc3BhY2UpIHtcbiAgICAgIGZvciAoY29uc3QgZWxlbWVudEV2ZW50IG9mIE9iamVjdC5rZXlzKGV2ZW50cykpIHtcbiAgICAgICAgcmVtb3ZlTmFtZXNwYWNlZEhhbmRsZXJzKGVsZW1lbnQsIGV2ZW50cywgZWxlbWVudEV2ZW50LCBvcmlnaW5hbFR5cGVFdmVudC5zbGljZSgxKSlcbiAgICAgIH1cbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IFtrZXlIYW5kbGVycywgZXZlbnRdIG9mIE9iamVjdC5lbnRyaWVzKHN0b3JlRWxlbWVudEV2ZW50KSkge1xuICAgICAgY29uc3QgaGFuZGxlcktleSA9IGtleUhhbmRsZXJzLnJlcGxhY2Uoc3RyaXBVaWRSZWdleCwgJycpXG5cbiAgICAgIGlmICghaW5OYW1lc3BhY2UgfHwgb3JpZ2luYWxUeXBlRXZlbnQuaW5jbHVkZXMoaGFuZGxlcktleSkpIHtcbiAgICAgICAgcmVtb3ZlSGFuZGxlcihlbGVtZW50LCBldmVudHMsIHR5cGVFdmVudCwgZXZlbnQuY2FsbGFibGUsIGV2ZW50LmRlbGVnYXRpb25TZWxlY3RvcilcbiAgICAgIH1cbiAgICB9XG4gIH0sXG5cbiAgdHJpZ2dlcihlbGVtZW50LCBldmVudCwgYXJncykge1xuICAgIGlmICh0eXBlb2YgZXZlbnQgIT09ICdzdHJpbmcnIHx8ICFlbGVtZW50KSB7XG4gICAgICByZXR1cm4gbnVsbFxuICAgIH1cblxuICAgIGNvbnN0ICQgPSBnZXRqUXVlcnkoKVxuICAgIGNvbnN0IHR5cGVFdmVudCA9IGdldFR5cGVFdmVudChldmVudClcbiAgICBjb25zdCBpbk5hbWVzcGFjZSA9IGV2ZW50ICE9PSB0eXBlRXZlbnRcblxuICAgIGxldCBqUXVlcnlFdmVudCA9IG51bGxcbiAgICBsZXQgYnViYmxlcyA9IHRydWVcbiAgICBsZXQgbmF0aXZlRGlzcGF0Y2ggPSB0cnVlXG4gICAgbGV0IGRlZmF1bHRQcmV2ZW50ZWQgPSBmYWxzZVxuXG4gICAgaWYgKGluTmFtZXNwYWNlICYmICQpIHtcbiAgICAgIGpRdWVyeUV2ZW50ID0gJC5FdmVudChldmVudCwgYXJncylcblxuICAgICAgJChlbGVtZW50KS50cmlnZ2VyKGpRdWVyeUV2ZW50KVxuICAgICAgYnViYmxlcyA9ICFqUXVlcnlFdmVudC5pc1Byb3BhZ2F0aW9uU3RvcHBlZCgpXG4gICAgICBuYXRpdmVEaXNwYXRjaCA9ICFqUXVlcnlFdmVudC5pc0ltbWVkaWF0ZVByb3BhZ2F0aW9uU3RvcHBlZCgpXG4gICAgICBkZWZhdWx0UHJldmVudGVkID0galF1ZXJ5RXZlbnQuaXNEZWZhdWx0UHJldmVudGVkKClcbiAgICB9XG5cbiAgICBjb25zdCBldnQgPSBoeWRyYXRlT2JqKG5ldyBFdmVudChldmVudCwgeyBidWJibGVzLCBjYW5jZWxhYmxlOiB0cnVlIH0pLCBhcmdzKVxuXG4gICAgaWYgKGRlZmF1bHRQcmV2ZW50ZWQpIHtcbiAgICAgIGV2dC5wcmV2ZW50RGVmYXVsdCgpXG4gICAgfVxuXG4gICAgaWYgKG5hdGl2ZURpc3BhdGNoKSB7XG4gICAgICBlbGVtZW50LmRpc3BhdGNoRXZlbnQoZXZ0KVxuICAgIH1cblxuICAgIGlmIChldnQuZGVmYXVsdFByZXZlbnRlZCAmJiBqUXVlcnlFdmVudCkge1xuICAgICAgalF1ZXJ5RXZlbnQucHJldmVudERlZmF1bHQoKVxuICAgIH1cblxuICAgIHJldHVybiBldnRcbiAgfVxufVxuXG5mdW5jdGlvbiBoeWRyYXRlT2JqKG9iaiwgbWV0YSA9IHt9KSB7XG4gIGZvciAoY29uc3QgW2tleSwgdmFsdWVdIG9mIE9iamVjdC5lbnRyaWVzKG1ldGEpKSB7XG4gICAgdHJ5IHtcbiAgICAgIG9ialtrZXldID0gdmFsdWVcbiAgICB9IGNhdGNoIHtcbiAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShvYmosIGtleSwge1xuICAgICAgICBjb25maWd1cmFibGU6IHRydWUsXG4gICAgICAgIGdldCgpIHtcbiAgICAgICAgICByZXR1cm4gdmFsdWVcbiAgICAgICAgfVxuICAgICAgfSlcbiAgICB9XG4gIH1cblxuICByZXR1cm4gb2JqXG59XG5cbmV4cG9ydCBkZWZhdWx0IEV2ZW50SGFuZGxlclxuIiwiLyoqXG4gKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICogQm9vdHN0cmFwIGRvbS9tYW5pcHVsYXRvci5qc1xuICogTGljZW5zZWQgdW5kZXIgTUlUIChodHRwczovL2dpdGh1Yi5jb20vdHdicy9ib290c3RyYXAvYmxvYi9tYWluL0xJQ0VOU0UpXG4gKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICovXG5cbmZ1bmN0aW9uIG5vcm1hbGl6ZURhdGEodmFsdWUpIHtcbiAgaWYgKHZhbHVlID09PSAndHJ1ZScpIHtcbiAgICByZXR1cm4gdHJ1ZVxuICB9XG5cbiAgaWYgKHZhbHVlID09PSAnZmFsc2UnKSB7XG4gICAgcmV0dXJuIGZhbHNlXG4gIH1cblxuICBpZiAodmFsdWUgPT09IE51bWJlcih2YWx1ZSkudG9TdHJpbmcoKSkge1xuICAgIHJldHVybiBOdW1iZXIodmFsdWUpXG4gIH1cblxuICBpZiAodmFsdWUgPT09ICcnIHx8IHZhbHVlID09PSAnbnVsbCcpIHtcbiAgICByZXR1cm4gbnVsbFxuICB9XG5cbiAgaWYgKHR5cGVvZiB2YWx1ZSAhPT0gJ3N0cmluZycpIHtcbiAgICByZXR1cm4gdmFsdWVcbiAgfVxuXG4gIHRyeSB7XG4gICAgcmV0dXJuIEpTT04ucGFyc2UoZGVjb2RlVVJJQ29tcG9uZW50KHZhbHVlKSlcbiAgfSBjYXRjaCB7XG4gICAgcmV0dXJuIHZhbHVlXG4gIH1cbn1cblxuZnVuY3Rpb24gbm9ybWFsaXplRGF0YUtleShrZXkpIHtcbiAgcmV0dXJuIGtleS5yZXBsYWNlKC9bQS1aXS9nLCBjaHIgPT4gYC0ke2Noci50b0xvd2VyQ2FzZSgpfWApXG59XG5cbmNvbnN0IE1hbmlwdWxhdG9yID0ge1xuICBzZXREYXRhQXR0cmlidXRlKGVsZW1lbnQsIGtleSwgdmFsdWUpIHtcbiAgICBlbGVtZW50LnNldEF0dHJpYnV0ZShgZGF0YS1icy0ke25vcm1hbGl6ZURhdGFLZXkoa2V5KX1gLCB2YWx1ZSlcbiAgfSxcblxuICByZW1vdmVEYXRhQXR0cmlidXRlKGVsZW1lbnQsIGtleSkge1xuICAgIGVsZW1lbnQucmVtb3ZlQXR0cmlidXRlKGBkYXRhLWJzLSR7bm9ybWFsaXplRGF0YUtleShrZXkpfWApXG4gIH0sXG5cbiAgZ2V0RGF0YUF0dHJpYnV0ZXMoZWxlbWVudCkge1xuICAgIGlmICghZWxlbWVudCkge1xuICAgICAgcmV0dXJuIHt9XG4gICAgfVxuXG4gICAgY29uc3QgYXR0cmlidXRlcyA9IHt9XG4gICAgY29uc3QgYnNLZXlzID0gT2JqZWN0LmtleXMoZWxlbWVudC5kYXRhc2V0KS5maWx0ZXIoa2V5ID0+IGtleS5zdGFydHNXaXRoKCdicycpICYmICFrZXkuc3RhcnRzV2l0aCgnYnNDb25maWcnKSlcblxuICAgIGZvciAoY29uc3Qga2V5IG9mIGJzS2V5cykge1xuICAgICAgbGV0IHB1cmVLZXkgPSBrZXkucmVwbGFjZSgvXmJzLywgJycpXG4gICAgICBwdXJlS2V5ID0gcHVyZUtleS5jaGFyQXQoMCkudG9Mb3dlckNhc2UoKSArIHB1cmVLZXkuc2xpY2UoMSwgcHVyZUtleS5sZW5ndGgpXG4gICAgICBhdHRyaWJ1dGVzW3B1cmVLZXldID0gbm9ybWFsaXplRGF0YShlbGVtZW50LmRhdGFzZXRba2V5XSlcbiAgICB9XG5cbiAgICByZXR1cm4gYXR0cmlidXRlc1xuICB9LFxuXG4gIGdldERhdGFBdHRyaWJ1dGUoZWxlbWVudCwga2V5KSB7XG4gICAgcmV0dXJuIG5vcm1hbGl6ZURhdGEoZWxlbWVudC5nZXRBdHRyaWJ1dGUoYGRhdGEtYnMtJHtub3JtYWxpemVEYXRhS2V5KGtleSl9YCkpXG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgTWFuaXB1bGF0b3JcbiIsIi8qKlxuICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAqIEJvb3RzdHJhcCB1dGlsL2NvbmZpZy5qc1xuICogTGljZW5zZWQgdW5kZXIgTUlUIChodHRwczovL2dpdGh1Yi5jb20vdHdicy9ib290c3RyYXAvYmxvYi9tYWluL0xJQ0VOU0UpXG4gKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICovXG5cbmltcG9ydCBNYW5pcHVsYXRvciBmcm9tICcuLi9kb20vbWFuaXB1bGF0b3IuanMnXG5pbXBvcnQgeyBpc0VsZW1lbnQsIHRvVHlwZSB9IGZyb20gJy4vaW5kZXguanMnXG5cbi8qKlxuICogQ2xhc3MgZGVmaW5pdGlvblxuICovXG5cbmNsYXNzIENvbmZpZyB7XG4gIC8vIEdldHRlcnNcbiAgc3RhdGljIGdldCBEZWZhdWx0KCkge1xuICAgIHJldHVybiB7fVxuICB9XG5cbiAgc3RhdGljIGdldCBEZWZhdWx0VHlwZSgpIHtcbiAgICByZXR1cm4ge31cbiAgfVxuXG4gIHN0YXRpYyBnZXQgTkFNRSgpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1lvdSBoYXZlIHRvIGltcGxlbWVudCB0aGUgc3RhdGljIG1ldGhvZCBcIk5BTUVcIiwgZm9yIGVhY2ggY29tcG9uZW50IScpXG4gIH1cblxuICBfZ2V0Q29uZmlnKGNvbmZpZykge1xuICAgIGNvbmZpZyA9IHRoaXMuX21lcmdlQ29uZmlnT2JqKGNvbmZpZylcbiAgICBjb25maWcgPSB0aGlzLl9jb25maWdBZnRlck1lcmdlKGNvbmZpZylcbiAgICB0aGlzLl90eXBlQ2hlY2tDb25maWcoY29uZmlnKVxuICAgIHJldHVybiBjb25maWdcbiAgfVxuXG4gIF9jb25maWdBZnRlck1lcmdlKGNvbmZpZykge1xuICAgIHJldHVybiBjb25maWdcbiAgfVxuXG4gIF9tZXJnZUNvbmZpZ09iaihjb25maWcsIGVsZW1lbnQpIHtcbiAgICBjb25zdCBqc29uQ29uZmlnID0gaXNFbGVtZW50KGVsZW1lbnQpID8gTWFuaXB1bGF0b3IuZ2V0RGF0YUF0dHJpYnV0ZShlbGVtZW50LCAnY29uZmlnJykgOiB7fSAvLyB0cnkgdG8gcGFyc2VcblxuICAgIHJldHVybiB7XG4gICAgICAuLi50aGlzLmNvbnN0cnVjdG9yLkRlZmF1bHQsXG4gICAgICAuLi4odHlwZW9mIGpzb25Db25maWcgPT09ICdvYmplY3QnID8ganNvbkNvbmZpZyA6IHt9KSxcbiAgICAgIC4uLihpc0VsZW1lbnQoZWxlbWVudCkgPyBNYW5pcHVsYXRvci5nZXREYXRhQXR0cmlidXRlcyhlbGVtZW50KSA6IHt9KSxcbiAgICAgIC4uLih0eXBlb2YgY29uZmlnID09PSAnb2JqZWN0JyA/IGNvbmZpZyA6IHt9KVxuICAgIH1cbiAgfVxuXG4gIF90eXBlQ2hlY2tDb25maWcoY29uZmlnLCBjb25maWdUeXBlcyA9IHRoaXMuY29uc3RydWN0b3IuRGVmYXVsdFR5cGUpIHtcbiAgICBmb3IgKGNvbnN0IFtwcm9wZXJ0eSwgZXhwZWN0ZWRUeXBlc10gb2YgT2JqZWN0LmVudHJpZXMoY29uZmlnVHlwZXMpKSB7XG4gICAgICBjb25zdCB2YWx1ZSA9IGNvbmZpZ1twcm9wZXJ0eV1cbiAgICAgIGNvbnN0IHZhbHVlVHlwZSA9IGlzRWxlbWVudCh2YWx1ZSkgPyAnZWxlbWVudCcgOiB0b1R5cGUodmFsdWUpXG5cbiAgICAgIGlmICghbmV3IFJlZ0V4cChleHBlY3RlZFR5cGVzKS50ZXN0KHZhbHVlVHlwZSkpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcbiAgICAgICAgICBgJHt0aGlzLmNvbnN0cnVjdG9yLk5BTUUudG9VcHBlckNhc2UoKX06IE9wdGlvbiBcIiR7cHJvcGVydHl9XCIgcHJvdmlkZWQgdHlwZSBcIiR7dmFsdWVUeXBlfVwiIGJ1dCBleHBlY3RlZCB0eXBlIFwiJHtleHBlY3RlZFR5cGVzfVwiLmBcbiAgICAgICAgKVxuICAgICAgfVxuICAgIH1cbiAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBDb25maWdcbiIsIi8qKlxuICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAqIEJvb3RzdHJhcCBiYXNlLWNvbXBvbmVudC5qc1xuICogTGljZW5zZWQgdW5kZXIgTUlUIChodHRwczovL2dpdGh1Yi5jb20vdHdicy9ib290c3RyYXAvYmxvYi9tYWluL0xJQ0VOU0UpXG4gKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICovXG5cbmltcG9ydCBEYXRhIGZyb20gJy4vZG9tL2RhdGEuanMnXG5pbXBvcnQgRXZlbnRIYW5kbGVyIGZyb20gJy4vZG9tL2V2ZW50LWhhbmRsZXIuanMnXG5pbXBvcnQgQ29uZmlnIGZyb20gJy4vdXRpbC9jb25maWcuanMnXG5pbXBvcnQgeyBleGVjdXRlQWZ0ZXJUcmFuc2l0aW9uLCBnZXRFbGVtZW50IH0gZnJvbSAnLi91dGlsL2luZGV4LmpzJ1xuXG4vKipcbiAqIENvbnN0YW50c1xuICovXG5cbmNvbnN0IFZFUlNJT04gPSAnNS4zLjMnXG5cbi8qKlxuICogQ2xhc3MgZGVmaW5pdGlvblxuICovXG5cbmNsYXNzIEJhc2VDb21wb25lbnQgZXh0ZW5kcyBDb25maWcge1xuICBjb25zdHJ1Y3RvcihlbGVtZW50LCBjb25maWcpIHtcbiAgICBzdXBlcigpXG5cbiAgICBlbGVtZW50ID0gZ2V0RWxlbWVudChlbGVtZW50KVxuICAgIGlmICghZWxlbWVudCkge1xuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgdGhpcy5fZWxlbWVudCA9IGVsZW1lbnRcbiAgICB0aGlzLl9jb25maWcgPSB0aGlzLl9nZXRDb25maWcoY29uZmlnKVxuXG4gICAgRGF0YS5zZXQodGhpcy5fZWxlbWVudCwgdGhpcy5jb25zdHJ1Y3Rvci5EQVRBX0tFWSwgdGhpcylcbiAgfVxuXG4gIC8vIFB1YmxpY1xuICBkaXNwb3NlKCkge1xuICAgIERhdGEucmVtb3ZlKHRoaXMuX2VsZW1lbnQsIHRoaXMuY29uc3RydWN0b3IuREFUQV9LRVkpXG4gICAgRXZlbnRIYW5kbGVyLm9mZih0aGlzLl9lbGVtZW50LCB0aGlzLmNvbnN0cnVjdG9yLkVWRU5UX0tFWSlcblxuICAgIGZvciAoY29uc3QgcHJvcGVydHlOYW1lIG9mIE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzKHRoaXMpKSB7XG4gICAgICB0aGlzW3Byb3BlcnR5TmFtZV0gPSBudWxsXG4gICAgfVxuICB9XG5cbiAgX3F1ZXVlQ2FsbGJhY2soY2FsbGJhY2ssIGVsZW1lbnQsIGlzQW5pbWF0ZWQgPSB0cnVlKSB7XG4gICAgZXhlY3V0ZUFmdGVyVHJhbnNpdGlvbihjYWxsYmFjaywgZWxlbWVudCwgaXNBbmltYXRlZClcbiAgfVxuXG4gIF9nZXRDb25maWcoY29uZmlnKSB7XG4gICAgY29uZmlnID0gdGhpcy5fbWVyZ2VDb25maWdPYmooY29uZmlnLCB0aGlzLl9lbGVtZW50KVxuICAgIGNvbmZpZyA9IHRoaXMuX2NvbmZpZ0FmdGVyTWVyZ2UoY29uZmlnKVxuICAgIHRoaXMuX3R5cGVDaGVja0NvbmZpZyhjb25maWcpXG4gICAgcmV0dXJuIGNvbmZpZ1xuICB9XG5cbiAgLy8gU3RhdGljXG4gIHN0YXRpYyBnZXRJbnN0YW5jZShlbGVtZW50KSB7XG4gICAgcmV0dXJuIERhdGEuZ2V0KGdldEVsZW1lbnQoZWxlbWVudCksIHRoaXMuREFUQV9LRVkpXG4gIH1cblxuICBzdGF0aWMgZ2V0T3JDcmVhdGVJbnN0YW5jZShlbGVtZW50LCBjb25maWcgPSB7fSkge1xuICAgIHJldHVybiB0aGlzLmdldEluc3RhbmNlKGVsZW1lbnQpIHx8IG5ldyB0aGlzKGVsZW1lbnQsIHR5cGVvZiBjb25maWcgPT09ICdvYmplY3QnID8gY29uZmlnIDogbnVsbClcbiAgfVxuXG4gIHN0YXRpYyBnZXQgVkVSU0lPTigpIHtcbiAgICByZXR1cm4gVkVSU0lPTlxuICB9XG5cbiAgc3RhdGljIGdldCBEQVRBX0tFWSgpIHtcbiAgICByZXR1cm4gYGJzLiR7dGhpcy5OQU1FfWBcbiAgfVxuXG4gIHN0YXRpYyBnZXQgRVZFTlRfS0VZKCkge1xuICAgIHJldHVybiBgLiR7dGhpcy5EQVRBX0tFWX1gXG4gIH1cblxuICBzdGF0aWMgZXZlbnROYW1lKG5hbWUpIHtcbiAgICByZXR1cm4gYCR7bmFtZX0ke3RoaXMuRVZFTlRfS0VZfWBcbiAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBCYXNlQ29tcG9uZW50XG4iLCIvKipcbiAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gKiBCb290c3RyYXAgZG9tL3NlbGVjdG9yLWVuZ2luZS5qc1xuICogTGljZW5zZWQgdW5kZXIgTUlUIChodHRwczovL2dpdGh1Yi5jb20vdHdicy9ib290c3RyYXAvYmxvYi9tYWluL0xJQ0VOU0UpXG4gKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICovXG5cbmltcG9ydCB7IGlzRGlzYWJsZWQsIGlzVmlzaWJsZSwgcGFyc2VTZWxlY3RvciB9IGZyb20gJy4uL3V0aWwvaW5kZXguanMnXG5cbmNvbnN0IGdldFNlbGVjdG9yID0gZWxlbWVudCA9PiB7XG4gIGxldCBzZWxlY3RvciA9IGVsZW1lbnQuZ2V0QXR0cmlidXRlKCdkYXRhLWJzLXRhcmdldCcpXG5cbiAgaWYgKCFzZWxlY3RvciB8fCBzZWxlY3RvciA9PT0gJyMnKSB7XG4gICAgbGV0IGhyZWZBdHRyaWJ1dGUgPSBlbGVtZW50LmdldEF0dHJpYnV0ZSgnaHJlZicpXG5cbiAgICAvLyBUaGUgb25seSB2YWxpZCBjb250ZW50IHRoYXQgY291bGQgZG91YmxlIGFzIGEgc2VsZWN0b3IgYXJlIElEcyBvciBjbGFzc2VzLFxuICAgIC8vIHNvIGV2ZXJ5dGhpbmcgc3RhcnRpbmcgd2l0aCBgI2Agb3IgYC5gLiBJZiBhIFwicmVhbFwiIFVSTCBpcyB1c2VkIGFzIHRoZSBzZWxlY3RvcixcbiAgICAvLyBgZG9jdW1lbnQucXVlcnlTZWxlY3RvcmAgd2lsbCByaWdodGZ1bGx5IGNvbXBsYWluIGl0IGlzIGludmFsaWQuXG4gICAgLy8gU2VlIGh0dHBzOi8vZ2l0aHViLmNvbS90d2JzL2Jvb3RzdHJhcC9pc3N1ZXMvMzIyNzNcbiAgICBpZiAoIWhyZWZBdHRyaWJ1dGUgfHwgKCFocmVmQXR0cmlidXRlLmluY2x1ZGVzKCcjJykgJiYgIWhyZWZBdHRyaWJ1dGUuc3RhcnRzV2l0aCgnLicpKSkge1xuICAgICAgcmV0dXJuIG51bGxcbiAgICB9XG5cbiAgICAvLyBKdXN0IGluIGNhc2Ugc29tZSBDTVMgcHV0cyBvdXQgYSBmdWxsIFVSTCB3aXRoIHRoZSBhbmNob3IgYXBwZW5kZWRcbiAgICBpZiAoaHJlZkF0dHJpYnV0ZS5pbmNsdWRlcygnIycpICYmICFocmVmQXR0cmlidXRlLnN0YXJ0c1dpdGgoJyMnKSkge1xuICAgICAgaHJlZkF0dHJpYnV0ZSA9IGAjJHtocmVmQXR0cmlidXRlLnNwbGl0KCcjJylbMV19YFxuICAgIH1cblxuICAgIHNlbGVjdG9yID0gaHJlZkF0dHJpYnV0ZSAmJiBocmVmQXR0cmlidXRlICE9PSAnIycgPyBocmVmQXR0cmlidXRlLnRyaW0oKSA6IG51bGxcbiAgfVxuXG4gIHJldHVybiBzZWxlY3RvciA/IHNlbGVjdG9yLnNwbGl0KCcsJykubWFwKHNlbCA9PiBwYXJzZVNlbGVjdG9yKHNlbCkpLmpvaW4oJywnKSA6IG51bGxcbn1cblxuY29uc3QgU2VsZWN0b3JFbmdpbmUgPSB7XG4gIGZpbmQoc2VsZWN0b3IsIGVsZW1lbnQgPSBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQpIHtcbiAgICByZXR1cm4gW10uY29uY2F0KC4uLkVsZW1lbnQucHJvdG90eXBlLnF1ZXJ5U2VsZWN0b3JBbGwuY2FsbChlbGVtZW50LCBzZWxlY3RvcikpXG4gIH0sXG5cbiAgZmluZE9uZShzZWxlY3RvciwgZWxlbWVudCA9IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudCkge1xuICAgIHJldHVybiBFbGVtZW50LnByb3RvdHlwZS5xdWVyeVNlbGVjdG9yLmNhbGwoZWxlbWVudCwgc2VsZWN0b3IpXG4gIH0sXG5cbiAgY2hpbGRyZW4oZWxlbWVudCwgc2VsZWN0b3IpIHtcbiAgICByZXR1cm4gW10uY29uY2F0KC4uLmVsZW1lbnQuY2hpbGRyZW4pLmZpbHRlcihjaGlsZCA9PiBjaGlsZC5tYXRjaGVzKHNlbGVjdG9yKSlcbiAgfSxcblxuICBwYXJlbnRzKGVsZW1lbnQsIHNlbGVjdG9yKSB7XG4gICAgY29uc3QgcGFyZW50cyA9IFtdXG4gICAgbGV0IGFuY2VzdG9yID0gZWxlbWVudC5wYXJlbnROb2RlLmNsb3Nlc3Qoc2VsZWN0b3IpXG5cbiAgICB3aGlsZSAoYW5jZXN0b3IpIHtcbiAgICAgIHBhcmVudHMucHVzaChhbmNlc3RvcilcbiAgICAgIGFuY2VzdG9yID0gYW5jZXN0b3IucGFyZW50Tm9kZS5jbG9zZXN0KHNlbGVjdG9yKVxuICAgIH1cblxuICAgIHJldHVybiBwYXJlbnRzXG4gIH0sXG5cbiAgcHJldihlbGVtZW50LCBzZWxlY3Rvcikge1xuICAgIGxldCBwcmV2aW91cyA9IGVsZW1lbnQucHJldmlvdXNFbGVtZW50U2libGluZ1xuXG4gICAgd2hpbGUgKHByZXZpb3VzKSB7XG4gICAgICBpZiAocHJldmlvdXMubWF0Y2hlcyhzZWxlY3RvcikpIHtcbiAgICAgICAgcmV0dXJuIFtwcmV2aW91c11cbiAgICAgIH1cblxuICAgICAgcHJldmlvdXMgPSBwcmV2aW91cy5wcmV2aW91c0VsZW1lbnRTaWJsaW5nXG4gICAgfVxuXG4gICAgcmV0dXJuIFtdXG4gIH0sXG4gIC8vIFRPRE86IHRoaXMgaXMgbm93IHVudXNlZDsgcmVtb3ZlIGxhdGVyIGFsb25nIHdpdGggcHJldigpXG4gIG5leHQoZWxlbWVudCwgc2VsZWN0b3IpIHtcbiAgICBsZXQgbmV4dCA9IGVsZW1lbnQubmV4dEVsZW1lbnRTaWJsaW5nXG5cbiAgICB3aGlsZSAobmV4dCkge1xuICAgICAgaWYgKG5leHQubWF0Y2hlcyhzZWxlY3RvcikpIHtcbiAgICAgICAgcmV0dXJuIFtuZXh0XVxuICAgICAgfVxuXG4gICAgICBuZXh0ID0gbmV4dC5uZXh0RWxlbWVudFNpYmxpbmdcbiAgICB9XG5cbiAgICByZXR1cm4gW11cbiAgfSxcblxuICBmb2N1c2FibGVDaGlsZHJlbihlbGVtZW50KSB7XG4gICAgY29uc3QgZm9jdXNhYmxlcyA9IFtcbiAgICAgICdhJyxcbiAgICAgICdidXR0b24nLFxuICAgICAgJ2lucHV0JyxcbiAgICAgICd0ZXh0YXJlYScsXG4gICAgICAnc2VsZWN0JyxcbiAgICAgICdkZXRhaWxzJyxcbiAgICAgICdbdGFiaW5kZXhdJyxcbiAgICAgICdbY29udGVudGVkaXRhYmxlPVwidHJ1ZVwiXSdcbiAgICBdLm1hcChzZWxlY3RvciA9PiBgJHtzZWxlY3Rvcn06bm90KFt0YWJpbmRleF49XCItXCJdKWApLmpvaW4oJywnKVxuXG4gICAgcmV0dXJuIHRoaXMuZmluZChmb2N1c2FibGVzLCBlbGVtZW50KS5maWx0ZXIoZWwgPT4gIWlzRGlzYWJsZWQoZWwpICYmIGlzVmlzaWJsZShlbCkpXG4gIH0sXG5cbiAgZ2V0U2VsZWN0b3JGcm9tRWxlbWVudChlbGVtZW50KSB7XG4gICAgY29uc3Qgc2VsZWN0b3IgPSBnZXRTZWxlY3RvcihlbGVtZW50KVxuXG4gICAgaWYgKHNlbGVjdG9yKSB7XG4gICAgICByZXR1cm4gU2VsZWN0b3JFbmdpbmUuZmluZE9uZShzZWxlY3RvcikgPyBzZWxlY3RvciA6IG51bGxcbiAgICB9XG5cbiAgICByZXR1cm4gbnVsbFxuICB9LFxuXG4gIGdldEVsZW1lbnRGcm9tU2VsZWN0b3IoZWxlbWVudCkge1xuICAgIGNvbnN0IHNlbGVjdG9yID0gZ2V0U2VsZWN0b3IoZWxlbWVudClcblxuICAgIHJldHVybiBzZWxlY3RvciA/IFNlbGVjdG9yRW5naW5lLmZpbmRPbmUoc2VsZWN0b3IpIDogbnVsbFxuICB9LFxuXG4gIGdldE11bHRpcGxlRWxlbWVudHNGcm9tU2VsZWN0b3IoZWxlbWVudCkge1xuICAgIGNvbnN0IHNlbGVjdG9yID0gZ2V0U2VsZWN0b3IoZWxlbWVudClcblxuICAgIHJldHVybiBzZWxlY3RvciA/IFNlbGVjdG9yRW5naW5lLmZpbmQoc2VsZWN0b3IpIDogW11cbiAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBTZWxlY3RvckVuZ2luZVxuIiwiLyoqXG4gKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICogQm9vdHN0cmFwIHV0aWwvY29tcG9uZW50LWZ1bmN0aW9ucy5qc1xuICogTGljZW5zZWQgdW5kZXIgTUlUIChodHRwczovL2dpdGh1Yi5jb20vdHdicy9ib290c3RyYXAvYmxvYi9tYWluL0xJQ0VOU0UpXG4gKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICovXG5cbmltcG9ydCBFdmVudEhhbmRsZXIgZnJvbSAnLi4vZG9tL2V2ZW50LWhhbmRsZXIuanMnXG5pbXBvcnQgU2VsZWN0b3JFbmdpbmUgZnJvbSAnLi4vZG9tL3NlbGVjdG9yLWVuZ2luZS5qcydcbmltcG9ydCB7IGlzRGlzYWJsZWQgfSBmcm9tICcuL2luZGV4LmpzJ1xuXG5jb25zdCBlbmFibGVEaXNtaXNzVHJpZ2dlciA9IChjb21wb25lbnQsIG1ldGhvZCA9ICdoaWRlJykgPT4ge1xuICBjb25zdCBjbGlja0V2ZW50ID0gYGNsaWNrLmRpc21pc3Mke2NvbXBvbmVudC5FVkVOVF9LRVl9YFxuICBjb25zdCBuYW1lID0gY29tcG9uZW50Lk5BTUVcblxuICBFdmVudEhhbmRsZXIub24oZG9jdW1lbnQsIGNsaWNrRXZlbnQsIGBbZGF0YS1icy1kaXNtaXNzPVwiJHtuYW1lfVwiXWAsIGZ1bmN0aW9uIChldmVudCkge1xuICAgIGlmIChbJ0EnLCAnQVJFQSddLmluY2x1ZGVzKHRoaXMudGFnTmFtZSkpIHtcbiAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KClcbiAgICB9XG5cbiAgICBpZiAoaXNEaXNhYmxlZCh0aGlzKSkge1xuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgY29uc3QgdGFyZ2V0ID0gU2VsZWN0b3JFbmdpbmUuZ2V0RWxlbWVudEZyb21TZWxlY3Rvcih0aGlzKSB8fCB0aGlzLmNsb3Nlc3QoYC4ke25hbWV9YClcbiAgICBjb25zdCBpbnN0YW5jZSA9IGNvbXBvbmVudC5nZXRPckNyZWF0ZUluc3RhbmNlKHRhcmdldClcblxuICAgIC8vIE1ldGhvZCBhcmd1bWVudCBpcyBsZWZ0LCBmb3IgQWxlcnQgYW5kIG9ubHksIGFzIGl0IGRvZXNuJ3QgaW1wbGVtZW50IHRoZSAnaGlkZScgbWV0aG9kXG4gICAgaW5zdGFuY2VbbWV0aG9kXSgpXG4gIH0pXG59XG5cbmV4cG9ydCB7XG4gIGVuYWJsZURpc21pc3NUcmlnZ2VyXG59XG4iLCIvKipcbiAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gKiBCb290c3RyYXAgYWxlcnQuanNcbiAqIExpY2Vuc2VkIHVuZGVyIE1JVCAoaHR0cHM6Ly9naXRodWIuY29tL3R3YnMvYm9vdHN0cmFwL2Jsb2IvbWFpbi9MSUNFTlNFKVxuICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAqL1xuXG5pbXBvcnQgQmFzZUNvbXBvbmVudCBmcm9tICcuL2Jhc2UtY29tcG9uZW50LmpzJ1xuaW1wb3J0IEV2ZW50SGFuZGxlciBmcm9tICcuL2RvbS9ldmVudC1oYW5kbGVyLmpzJ1xuaW1wb3J0IHsgZW5hYmxlRGlzbWlzc1RyaWdnZXIgfSBmcm9tICcuL3V0aWwvY29tcG9uZW50LWZ1bmN0aW9ucy5qcydcbmltcG9ydCB7IGRlZmluZUpRdWVyeVBsdWdpbiB9IGZyb20gJy4vdXRpbC9pbmRleC5qcydcblxuLyoqXG4gKiBDb25zdGFudHNcbiAqL1xuXG5jb25zdCBOQU1FID0gJ2FsZXJ0J1xuY29uc3QgREFUQV9LRVkgPSAnYnMuYWxlcnQnXG5jb25zdCBFVkVOVF9LRVkgPSBgLiR7REFUQV9LRVl9YFxuXG5jb25zdCBFVkVOVF9DTE9TRSA9IGBjbG9zZSR7RVZFTlRfS0VZfWBcbmNvbnN0IEVWRU5UX0NMT1NFRCA9IGBjbG9zZWQke0VWRU5UX0tFWX1gXG5jb25zdCBDTEFTU19OQU1FX0ZBREUgPSAnZmFkZSdcbmNvbnN0IENMQVNTX05BTUVfU0hPVyA9ICdzaG93J1xuXG4vKipcbiAqIENsYXNzIGRlZmluaXRpb25cbiAqL1xuXG5jbGFzcyBBbGVydCBleHRlbmRzIEJhc2VDb21wb25lbnQge1xuICAvLyBHZXR0ZXJzXG4gIHN0YXRpYyBnZXQgTkFNRSgpIHtcbiAgICByZXR1cm4gTkFNRVxuICB9XG5cbiAgLy8gUHVibGljXG4gIGNsb3NlKCkge1xuICAgIGNvbnN0IGNsb3NlRXZlbnQgPSBFdmVudEhhbmRsZXIudHJpZ2dlcih0aGlzLl9lbGVtZW50LCBFVkVOVF9DTE9TRSlcblxuICAgIGlmIChjbG9zZUV2ZW50LmRlZmF1bHRQcmV2ZW50ZWQpIHtcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIHRoaXMuX2VsZW1lbnQuY2xhc3NMaXN0LnJlbW92ZShDTEFTU19OQU1FX1NIT1cpXG5cbiAgICBjb25zdCBpc0FuaW1hdGVkID0gdGhpcy5fZWxlbWVudC5jbGFzc0xpc3QuY29udGFpbnMoQ0xBU1NfTkFNRV9GQURFKVxuICAgIHRoaXMuX3F1ZXVlQ2FsbGJhY2soKCkgPT4gdGhpcy5fZGVzdHJveUVsZW1lbnQoKSwgdGhpcy5fZWxlbWVudCwgaXNBbmltYXRlZClcbiAgfVxuXG4gIC8vIFByaXZhdGVcbiAgX2Rlc3Ryb3lFbGVtZW50KCkge1xuICAgIHRoaXMuX2VsZW1lbnQucmVtb3ZlKClcbiAgICBFdmVudEhhbmRsZXIudHJpZ2dlcih0aGlzLl9lbGVtZW50LCBFVkVOVF9DTE9TRUQpXG4gICAgdGhpcy5kaXNwb3NlKClcbiAgfVxuXG4gIC8vIFN0YXRpY1xuICBzdGF0aWMgalF1ZXJ5SW50ZXJmYWNlKGNvbmZpZykge1xuICAgIHJldHVybiB0aGlzLmVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgZGF0YSA9IEFsZXJ0LmdldE9yQ3JlYXRlSW5zdGFuY2UodGhpcylcblxuICAgICAgaWYgKHR5cGVvZiBjb25maWcgIT09ICdzdHJpbmcnKSB7XG4gICAgICAgIHJldHVyblxuICAgICAgfVxuXG4gICAgICBpZiAoZGF0YVtjb25maWddID09PSB1bmRlZmluZWQgfHwgY29uZmlnLnN0YXJ0c1dpdGgoJ18nKSB8fCBjb25maWcgPT09ICdjb25zdHJ1Y3RvcicpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihgTm8gbWV0aG9kIG5hbWVkIFwiJHtjb25maWd9XCJgKVxuICAgICAgfVxuXG4gICAgICBkYXRhW2NvbmZpZ10odGhpcylcbiAgICB9KVxuICB9XG59XG5cbi8qKlxuICogRGF0YSBBUEkgaW1wbGVtZW50YXRpb25cbiAqL1xuXG5lbmFibGVEaXNtaXNzVHJpZ2dlcihBbGVydCwgJ2Nsb3NlJylcblxuLyoqXG4gKiBqUXVlcnlcbiAqL1xuXG5kZWZpbmVKUXVlcnlQbHVnaW4oQWxlcnQpXG5cbmV4cG9ydCBkZWZhdWx0IEFsZXJ0XG4iLCIvKipcbiAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gKiBCb290c3RyYXAgYnV0dG9uLmpzXG4gKiBMaWNlbnNlZCB1bmRlciBNSVQgKGh0dHBzOi8vZ2l0aHViLmNvbS90d2JzL2Jvb3RzdHJhcC9ibG9iL21haW4vTElDRU5TRSlcbiAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gKi9cblxuaW1wb3J0IEJhc2VDb21wb25lbnQgZnJvbSAnLi9iYXNlLWNvbXBvbmVudC5qcydcbmltcG9ydCBFdmVudEhhbmRsZXIgZnJvbSAnLi9kb20vZXZlbnQtaGFuZGxlci5qcydcbmltcG9ydCB7IGRlZmluZUpRdWVyeVBsdWdpbiB9IGZyb20gJy4vdXRpbC9pbmRleC5qcydcblxuLyoqXG4gKiBDb25zdGFudHNcbiAqL1xuXG5jb25zdCBOQU1FID0gJ2J1dHRvbidcbmNvbnN0IERBVEFfS0VZID0gJ2JzLmJ1dHRvbidcbmNvbnN0IEVWRU5UX0tFWSA9IGAuJHtEQVRBX0tFWX1gXG5jb25zdCBEQVRBX0FQSV9LRVkgPSAnLmRhdGEtYXBpJ1xuXG5jb25zdCBDTEFTU19OQU1FX0FDVElWRSA9ICdhY3RpdmUnXG5jb25zdCBTRUxFQ1RPUl9EQVRBX1RPR0dMRSA9ICdbZGF0YS1icy10b2dnbGU9XCJidXR0b25cIl0nXG5jb25zdCBFVkVOVF9DTElDS19EQVRBX0FQSSA9IGBjbGljayR7RVZFTlRfS0VZfSR7REFUQV9BUElfS0VZfWBcblxuLyoqXG4gKiBDbGFzcyBkZWZpbml0aW9uXG4gKi9cblxuY2xhc3MgQnV0dG9uIGV4dGVuZHMgQmFzZUNvbXBvbmVudCB7XG4gIC8vIEdldHRlcnNcbiAgc3RhdGljIGdldCBOQU1FKCkge1xuICAgIHJldHVybiBOQU1FXG4gIH1cblxuICAvLyBQdWJsaWNcbiAgdG9nZ2xlKCkge1xuICAgIC8vIFRvZ2dsZSBjbGFzcyBhbmQgc3luYyB0aGUgYGFyaWEtcHJlc3NlZGAgYXR0cmlidXRlIHdpdGggdGhlIHJldHVybiB2YWx1ZSBvZiB0aGUgYC50b2dnbGUoKWAgbWV0aG9kXG4gICAgdGhpcy5fZWxlbWVudC5zZXRBdHRyaWJ1dGUoJ2FyaWEtcHJlc3NlZCcsIHRoaXMuX2VsZW1lbnQuY2xhc3NMaXN0LnRvZ2dsZShDTEFTU19OQU1FX0FDVElWRSkpXG4gIH1cblxuICAvLyBTdGF0aWNcbiAgc3RhdGljIGpRdWVyeUludGVyZmFjZShjb25maWcpIHtcbiAgICByZXR1cm4gdGhpcy5lYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGRhdGEgPSBCdXR0b24uZ2V0T3JDcmVhdGVJbnN0YW5jZSh0aGlzKVxuXG4gICAgICBpZiAoY29uZmlnID09PSAndG9nZ2xlJykge1xuICAgICAgICBkYXRhW2NvbmZpZ10oKVxuICAgICAgfVxuICAgIH0pXG4gIH1cbn1cblxuLyoqXG4gKiBEYXRhIEFQSSBpbXBsZW1lbnRhdGlvblxuICovXG5cbkV2ZW50SGFuZGxlci5vbihkb2N1bWVudCwgRVZFTlRfQ0xJQ0tfREFUQV9BUEksIFNFTEVDVE9SX0RBVEFfVE9HR0xFLCBldmVudCA9PiB7XG4gIGV2ZW50LnByZXZlbnREZWZhdWx0KClcblxuICBjb25zdCBidXR0b24gPSBldmVudC50YXJnZXQuY2xvc2VzdChTRUxFQ1RPUl9EQVRBX1RPR0dMRSlcbiAgY29uc3QgZGF0YSA9IEJ1dHRvbi5nZXRPckNyZWF0ZUluc3RhbmNlKGJ1dHRvbilcblxuICBkYXRhLnRvZ2dsZSgpXG59KVxuXG4vKipcbiAqIGpRdWVyeVxuICovXG5cbmRlZmluZUpRdWVyeVBsdWdpbihCdXR0b24pXG5cbmV4cG9ydCBkZWZhdWx0IEJ1dHRvblxuIiwiLyoqXG4gKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICogQm9vdHN0cmFwIHV0aWwvc3dpcGUuanNcbiAqIExpY2Vuc2VkIHVuZGVyIE1JVCAoaHR0cHM6Ly9naXRodWIuY29tL3R3YnMvYm9vdHN0cmFwL2Jsb2IvbWFpbi9MSUNFTlNFKVxuICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAqL1xuXG5pbXBvcnQgRXZlbnRIYW5kbGVyIGZyb20gJy4uL2RvbS9ldmVudC1oYW5kbGVyLmpzJ1xuaW1wb3J0IENvbmZpZyBmcm9tICcuL2NvbmZpZy5qcydcbmltcG9ydCB7IGV4ZWN1dGUgfSBmcm9tICcuL2luZGV4LmpzJ1xuXG4vKipcbiAqIENvbnN0YW50c1xuICovXG5cbmNvbnN0IE5BTUUgPSAnc3dpcGUnXG5jb25zdCBFVkVOVF9LRVkgPSAnLmJzLnN3aXBlJ1xuY29uc3QgRVZFTlRfVE9VQ0hTVEFSVCA9IGB0b3VjaHN0YXJ0JHtFVkVOVF9LRVl9YFxuY29uc3QgRVZFTlRfVE9VQ0hNT1ZFID0gYHRvdWNobW92ZSR7RVZFTlRfS0VZfWBcbmNvbnN0IEVWRU5UX1RPVUNIRU5EID0gYHRvdWNoZW5kJHtFVkVOVF9LRVl9YFxuY29uc3QgRVZFTlRfUE9JTlRFUkRPV04gPSBgcG9pbnRlcmRvd24ke0VWRU5UX0tFWX1gXG5jb25zdCBFVkVOVF9QT0lOVEVSVVAgPSBgcG9pbnRlcnVwJHtFVkVOVF9LRVl9YFxuY29uc3QgUE9JTlRFUl9UWVBFX1RPVUNIID0gJ3RvdWNoJ1xuY29uc3QgUE9JTlRFUl9UWVBFX1BFTiA9ICdwZW4nXG5jb25zdCBDTEFTU19OQU1FX1BPSU5URVJfRVZFTlQgPSAncG9pbnRlci1ldmVudCdcbmNvbnN0IFNXSVBFX1RIUkVTSE9MRCA9IDQwXG5cbmNvbnN0IERlZmF1bHQgPSB7XG4gIGVuZENhbGxiYWNrOiBudWxsLFxuICBsZWZ0Q2FsbGJhY2s6IG51bGwsXG4gIHJpZ2h0Q2FsbGJhY2s6IG51bGxcbn1cblxuY29uc3QgRGVmYXVsdFR5cGUgPSB7XG4gIGVuZENhbGxiYWNrOiAnKGZ1bmN0aW9ufG51bGwpJyxcbiAgbGVmdENhbGxiYWNrOiAnKGZ1bmN0aW9ufG51bGwpJyxcbiAgcmlnaHRDYWxsYmFjazogJyhmdW5jdGlvbnxudWxsKSdcbn1cblxuLyoqXG4gKiBDbGFzcyBkZWZpbml0aW9uXG4gKi9cblxuY2xhc3MgU3dpcGUgZXh0ZW5kcyBDb25maWcge1xuICBjb25zdHJ1Y3RvcihlbGVtZW50LCBjb25maWcpIHtcbiAgICBzdXBlcigpXG4gICAgdGhpcy5fZWxlbWVudCA9IGVsZW1lbnRcblxuICAgIGlmICghZWxlbWVudCB8fCAhU3dpcGUuaXNTdXBwb3J0ZWQoKSkge1xuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgdGhpcy5fY29uZmlnID0gdGhpcy5fZ2V0Q29uZmlnKGNvbmZpZylcbiAgICB0aGlzLl9kZWx0YVggPSAwXG4gICAgdGhpcy5fc3VwcG9ydFBvaW50ZXJFdmVudHMgPSBCb29sZWFuKHdpbmRvdy5Qb2ludGVyRXZlbnQpXG4gICAgdGhpcy5faW5pdEV2ZW50cygpXG4gIH1cblxuICAvLyBHZXR0ZXJzXG4gIHN0YXRpYyBnZXQgRGVmYXVsdCgpIHtcbiAgICByZXR1cm4gRGVmYXVsdFxuICB9XG5cbiAgc3RhdGljIGdldCBEZWZhdWx0VHlwZSgpIHtcbiAgICByZXR1cm4gRGVmYXVsdFR5cGVcbiAgfVxuXG4gIHN0YXRpYyBnZXQgTkFNRSgpIHtcbiAgICByZXR1cm4gTkFNRVxuICB9XG5cbiAgLy8gUHVibGljXG4gIGRpc3Bvc2UoKSB7XG4gICAgRXZlbnRIYW5kbGVyLm9mZih0aGlzLl9lbGVtZW50LCBFVkVOVF9LRVkpXG4gIH1cblxuICAvLyBQcml2YXRlXG4gIF9zdGFydChldmVudCkge1xuICAgIGlmICghdGhpcy5fc3VwcG9ydFBvaW50ZXJFdmVudHMpIHtcbiAgICAgIHRoaXMuX2RlbHRhWCA9IGV2ZW50LnRvdWNoZXNbMF0uY2xpZW50WFxuXG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICBpZiAodGhpcy5fZXZlbnRJc1BvaW50ZXJQZW5Ub3VjaChldmVudCkpIHtcbiAgICAgIHRoaXMuX2RlbHRhWCA9IGV2ZW50LmNsaWVudFhcbiAgICB9XG4gIH1cblxuICBfZW5kKGV2ZW50KSB7XG4gICAgaWYgKHRoaXMuX2V2ZW50SXNQb2ludGVyUGVuVG91Y2goZXZlbnQpKSB7XG4gICAgICB0aGlzLl9kZWx0YVggPSBldmVudC5jbGllbnRYIC0gdGhpcy5fZGVsdGFYXG4gICAgfVxuXG4gICAgdGhpcy5faGFuZGxlU3dpcGUoKVxuICAgIGV4ZWN1dGUodGhpcy5fY29uZmlnLmVuZENhbGxiYWNrKVxuICB9XG5cbiAgX21vdmUoZXZlbnQpIHtcbiAgICB0aGlzLl9kZWx0YVggPSBldmVudC50b3VjaGVzICYmIGV2ZW50LnRvdWNoZXMubGVuZ3RoID4gMSA/XG4gICAgICAwIDpcbiAgICAgIGV2ZW50LnRvdWNoZXNbMF0uY2xpZW50WCAtIHRoaXMuX2RlbHRhWFxuICB9XG5cbiAgX2hhbmRsZVN3aXBlKCkge1xuICAgIGNvbnN0IGFic0RlbHRhWCA9IE1hdGguYWJzKHRoaXMuX2RlbHRhWClcblxuICAgIGlmIChhYnNEZWx0YVggPD0gU1dJUEVfVEhSRVNIT0xEKSB7XG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICBjb25zdCBkaXJlY3Rpb24gPSBhYnNEZWx0YVggLyB0aGlzLl9kZWx0YVhcblxuICAgIHRoaXMuX2RlbHRhWCA9IDBcblxuICAgIGlmICghZGlyZWN0aW9uKSB7XG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICBleGVjdXRlKGRpcmVjdGlvbiA+IDAgPyB0aGlzLl9jb25maWcucmlnaHRDYWxsYmFjayA6IHRoaXMuX2NvbmZpZy5sZWZ0Q2FsbGJhY2spXG4gIH1cblxuICBfaW5pdEV2ZW50cygpIHtcbiAgICBpZiAodGhpcy5fc3VwcG9ydFBvaW50ZXJFdmVudHMpIHtcbiAgICAgIEV2ZW50SGFuZGxlci5vbih0aGlzLl9lbGVtZW50LCBFVkVOVF9QT0lOVEVSRE9XTiwgZXZlbnQgPT4gdGhpcy5fc3RhcnQoZXZlbnQpKVxuICAgICAgRXZlbnRIYW5kbGVyLm9uKHRoaXMuX2VsZW1lbnQsIEVWRU5UX1BPSU5URVJVUCwgZXZlbnQgPT4gdGhpcy5fZW5kKGV2ZW50KSlcblxuICAgICAgdGhpcy5fZWxlbWVudC5jbGFzc0xpc3QuYWRkKENMQVNTX05BTUVfUE9JTlRFUl9FVkVOVClcbiAgICB9IGVsc2Uge1xuICAgICAgRXZlbnRIYW5kbGVyLm9uKHRoaXMuX2VsZW1lbnQsIEVWRU5UX1RPVUNIU1RBUlQsIGV2ZW50ID0+IHRoaXMuX3N0YXJ0KGV2ZW50KSlcbiAgICAgIEV2ZW50SGFuZGxlci5vbih0aGlzLl9lbGVtZW50LCBFVkVOVF9UT1VDSE1PVkUsIGV2ZW50ID0+IHRoaXMuX21vdmUoZXZlbnQpKVxuICAgICAgRXZlbnRIYW5kbGVyLm9uKHRoaXMuX2VsZW1lbnQsIEVWRU5UX1RPVUNIRU5ELCBldmVudCA9PiB0aGlzLl9lbmQoZXZlbnQpKVxuICAgIH1cbiAgfVxuXG4gIF9ldmVudElzUG9pbnRlclBlblRvdWNoKGV2ZW50KSB7XG4gICAgcmV0dXJuIHRoaXMuX3N1cHBvcnRQb2ludGVyRXZlbnRzICYmIChldmVudC5wb2ludGVyVHlwZSA9PT0gUE9JTlRFUl9UWVBFX1BFTiB8fCBldmVudC5wb2ludGVyVHlwZSA9PT0gUE9JTlRFUl9UWVBFX1RPVUNIKVxuICB9XG5cbiAgLy8gU3RhdGljXG4gIHN0YXRpYyBpc1N1cHBvcnRlZCgpIHtcbiAgICByZXR1cm4gJ29udG91Y2hzdGFydCcgaW4gZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50IHx8IG5hdmlnYXRvci5tYXhUb3VjaFBvaW50cyA+IDBcbiAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBTd2lwZVxuIiwiLyoqXG4gKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICogQm9vdHN0cmFwIGNhcm91c2VsLmpzXG4gKiBMaWNlbnNlZCB1bmRlciBNSVQgKGh0dHBzOi8vZ2l0aHViLmNvbS90d2JzL2Jvb3RzdHJhcC9ibG9iL21haW4vTElDRU5TRSlcbiAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gKi9cblxuaW1wb3J0IEJhc2VDb21wb25lbnQgZnJvbSAnLi9iYXNlLWNvbXBvbmVudC5qcydcbmltcG9ydCBFdmVudEhhbmRsZXIgZnJvbSAnLi9kb20vZXZlbnQtaGFuZGxlci5qcydcbmltcG9ydCBNYW5pcHVsYXRvciBmcm9tICcuL2RvbS9tYW5pcHVsYXRvci5qcydcbmltcG9ydCBTZWxlY3RvckVuZ2luZSBmcm9tICcuL2RvbS9zZWxlY3Rvci1lbmdpbmUuanMnXG5pbXBvcnQge1xuICBkZWZpbmVKUXVlcnlQbHVnaW4sXG4gIGdldE5leHRBY3RpdmVFbGVtZW50LFxuICBpc1JUTCxcbiAgaXNWaXNpYmxlLFxuICByZWZsb3csXG4gIHRyaWdnZXJUcmFuc2l0aW9uRW5kXG59IGZyb20gJy4vdXRpbC9pbmRleC5qcydcbmltcG9ydCBTd2lwZSBmcm9tICcuL3V0aWwvc3dpcGUuanMnXG5cbi8qKlxuICogQ29uc3RhbnRzXG4gKi9cblxuY29uc3QgTkFNRSA9ICdjYXJvdXNlbCdcbmNvbnN0IERBVEFfS0VZID0gJ2JzLmNhcm91c2VsJ1xuY29uc3QgRVZFTlRfS0VZID0gYC4ke0RBVEFfS0VZfWBcbmNvbnN0IERBVEFfQVBJX0tFWSA9ICcuZGF0YS1hcGknXG5cbmNvbnN0IEFSUk9XX0xFRlRfS0VZID0gJ0Fycm93TGVmdCdcbmNvbnN0IEFSUk9XX1JJR0hUX0tFWSA9ICdBcnJvd1JpZ2h0J1xuY29uc3QgVE9VQ0hFVkVOVF9DT01QQVRfV0FJVCA9IDUwMCAvLyBUaW1lIGZvciBtb3VzZSBjb21wYXQgZXZlbnRzIHRvIGZpcmUgYWZ0ZXIgdG91Y2hcblxuY29uc3QgT1JERVJfTkVYVCA9ICduZXh0J1xuY29uc3QgT1JERVJfUFJFViA9ICdwcmV2J1xuY29uc3QgRElSRUNUSU9OX0xFRlQgPSAnbGVmdCdcbmNvbnN0IERJUkVDVElPTl9SSUdIVCA9ICdyaWdodCdcblxuY29uc3QgRVZFTlRfU0xJREUgPSBgc2xpZGUke0VWRU5UX0tFWX1gXG5jb25zdCBFVkVOVF9TTElEID0gYHNsaWQke0VWRU5UX0tFWX1gXG5jb25zdCBFVkVOVF9LRVlET1dOID0gYGtleWRvd24ke0VWRU5UX0tFWX1gXG5jb25zdCBFVkVOVF9NT1VTRUVOVEVSID0gYG1vdXNlZW50ZXIke0VWRU5UX0tFWX1gXG5jb25zdCBFVkVOVF9NT1VTRUxFQVZFID0gYG1vdXNlbGVhdmUke0VWRU5UX0tFWX1gXG5jb25zdCBFVkVOVF9EUkFHX1NUQVJUID0gYGRyYWdzdGFydCR7RVZFTlRfS0VZfWBcbmNvbnN0IEVWRU5UX0xPQURfREFUQV9BUEkgPSBgbG9hZCR7RVZFTlRfS0VZfSR7REFUQV9BUElfS0VZfWBcbmNvbnN0IEVWRU5UX0NMSUNLX0RBVEFfQVBJID0gYGNsaWNrJHtFVkVOVF9LRVl9JHtEQVRBX0FQSV9LRVl9YFxuXG5jb25zdCBDTEFTU19OQU1FX0NBUk9VU0VMID0gJ2Nhcm91c2VsJ1xuY29uc3QgQ0xBU1NfTkFNRV9BQ1RJVkUgPSAnYWN0aXZlJ1xuY29uc3QgQ0xBU1NfTkFNRV9TTElERSA9ICdzbGlkZSdcbmNvbnN0IENMQVNTX05BTUVfRU5EID0gJ2Nhcm91c2VsLWl0ZW0tZW5kJ1xuY29uc3QgQ0xBU1NfTkFNRV9TVEFSVCA9ICdjYXJvdXNlbC1pdGVtLXN0YXJ0J1xuY29uc3QgQ0xBU1NfTkFNRV9ORVhUID0gJ2Nhcm91c2VsLWl0ZW0tbmV4dCdcbmNvbnN0IENMQVNTX05BTUVfUFJFViA9ICdjYXJvdXNlbC1pdGVtLXByZXYnXG5cbmNvbnN0IFNFTEVDVE9SX0FDVElWRSA9ICcuYWN0aXZlJ1xuY29uc3QgU0VMRUNUT1JfSVRFTSA9ICcuY2Fyb3VzZWwtaXRlbSdcbmNvbnN0IFNFTEVDVE9SX0FDVElWRV9JVEVNID0gU0VMRUNUT1JfQUNUSVZFICsgU0VMRUNUT1JfSVRFTVxuY29uc3QgU0VMRUNUT1JfSVRFTV9JTUcgPSAnLmNhcm91c2VsLWl0ZW0gaW1nJ1xuY29uc3QgU0VMRUNUT1JfSU5ESUNBVE9SUyA9ICcuY2Fyb3VzZWwtaW5kaWNhdG9ycydcbmNvbnN0IFNFTEVDVE9SX0RBVEFfU0xJREUgPSAnW2RhdGEtYnMtc2xpZGVdLCBbZGF0YS1icy1zbGlkZS10b10nXG5jb25zdCBTRUxFQ1RPUl9EQVRBX1JJREUgPSAnW2RhdGEtYnMtcmlkZT1cImNhcm91c2VsXCJdJ1xuXG5jb25zdCBLRVlfVE9fRElSRUNUSU9OID0ge1xuICBbQVJST1dfTEVGVF9LRVldOiBESVJFQ1RJT05fUklHSFQsXG4gIFtBUlJPV19SSUdIVF9LRVldOiBESVJFQ1RJT05fTEVGVFxufVxuXG5jb25zdCBEZWZhdWx0ID0ge1xuICBpbnRlcnZhbDogNTAwMCxcbiAga2V5Ym9hcmQ6IHRydWUsXG4gIHBhdXNlOiAnaG92ZXInLFxuICByaWRlOiBmYWxzZSxcbiAgdG91Y2g6IHRydWUsXG4gIHdyYXA6IHRydWVcbn1cblxuY29uc3QgRGVmYXVsdFR5cGUgPSB7XG4gIGludGVydmFsOiAnKG51bWJlcnxib29sZWFuKScsIC8vIFRPRE86djYgcmVtb3ZlIGJvb2xlYW4gc3VwcG9ydFxuICBrZXlib2FyZDogJ2Jvb2xlYW4nLFxuICBwYXVzZTogJyhzdHJpbmd8Ym9vbGVhbiknLFxuICByaWRlOiAnKGJvb2xlYW58c3RyaW5nKScsXG4gIHRvdWNoOiAnYm9vbGVhbicsXG4gIHdyYXA6ICdib29sZWFuJ1xufVxuXG4vKipcbiAqIENsYXNzIGRlZmluaXRpb25cbiAqL1xuXG5jbGFzcyBDYXJvdXNlbCBleHRlbmRzIEJhc2VDb21wb25lbnQge1xuICBjb25zdHJ1Y3RvcihlbGVtZW50LCBjb25maWcpIHtcbiAgICBzdXBlcihlbGVtZW50LCBjb25maWcpXG5cbiAgICB0aGlzLl9pbnRlcnZhbCA9IG51bGxcbiAgICB0aGlzLl9hY3RpdmVFbGVtZW50ID0gbnVsbFxuICAgIHRoaXMuX2lzU2xpZGluZyA9IGZhbHNlXG4gICAgdGhpcy50b3VjaFRpbWVvdXQgPSBudWxsXG4gICAgdGhpcy5fc3dpcGVIZWxwZXIgPSBudWxsXG5cbiAgICB0aGlzLl9pbmRpY2F0b3JzRWxlbWVudCA9IFNlbGVjdG9yRW5naW5lLmZpbmRPbmUoU0VMRUNUT1JfSU5ESUNBVE9SUywgdGhpcy5fZWxlbWVudClcbiAgICB0aGlzLl9hZGRFdmVudExpc3RlbmVycygpXG5cbiAgICBpZiAodGhpcy5fY29uZmlnLnJpZGUgPT09IENMQVNTX05BTUVfQ0FST1VTRUwpIHtcbiAgICAgIHRoaXMuY3ljbGUoKVxuICAgIH1cbiAgfVxuXG4gIC8vIEdldHRlcnNcbiAgc3RhdGljIGdldCBEZWZhdWx0KCkge1xuICAgIHJldHVybiBEZWZhdWx0XG4gIH1cblxuICBzdGF0aWMgZ2V0IERlZmF1bHRUeXBlKCkge1xuICAgIHJldHVybiBEZWZhdWx0VHlwZVxuICB9XG5cbiAgc3RhdGljIGdldCBOQU1FKCkge1xuICAgIHJldHVybiBOQU1FXG4gIH1cblxuICAvLyBQdWJsaWNcbiAgbmV4dCgpIHtcbiAgICB0aGlzLl9zbGlkZShPUkRFUl9ORVhUKVxuICB9XG5cbiAgbmV4dFdoZW5WaXNpYmxlKCkge1xuICAgIC8vIEZJWE1FIFRPRE8gdXNlIGBkb2N1bWVudC52aXNpYmlsaXR5U3RhdGVgXG4gICAgLy8gRG9uJ3QgY2FsbCBuZXh0IHdoZW4gdGhlIHBhZ2UgaXNuJ3QgdmlzaWJsZVxuICAgIC8vIG9yIHRoZSBjYXJvdXNlbCBvciBpdHMgcGFyZW50IGlzbid0IHZpc2libGVcbiAgICBpZiAoIWRvY3VtZW50LmhpZGRlbiAmJiBpc1Zpc2libGUodGhpcy5fZWxlbWVudCkpIHtcbiAgICAgIHRoaXMubmV4dCgpXG4gICAgfVxuICB9XG5cbiAgcHJldigpIHtcbiAgICB0aGlzLl9zbGlkZShPUkRFUl9QUkVWKVxuICB9XG5cbiAgcGF1c2UoKSB7XG4gICAgaWYgKHRoaXMuX2lzU2xpZGluZykge1xuICAgICAgdHJpZ2dlclRyYW5zaXRpb25FbmQodGhpcy5fZWxlbWVudClcbiAgICB9XG5cbiAgICB0aGlzLl9jbGVhckludGVydmFsKClcbiAgfVxuXG4gIGN5Y2xlKCkge1xuICAgIHRoaXMuX2NsZWFySW50ZXJ2YWwoKVxuICAgIHRoaXMuX3VwZGF0ZUludGVydmFsKClcblxuICAgIHRoaXMuX2ludGVydmFsID0gc2V0SW50ZXJ2YWwoKCkgPT4gdGhpcy5uZXh0V2hlblZpc2libGUoKSwgdGhpcy5fY29uZmlnLmludGVydmFsKVxuICB9XG5cbiAgX21heWJlRW5hYmxlQ3ljbGUoKSB7XG4gICAgaWYgKCF0aGlzLl9jb25maWcucmlkZSkge1xuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgaWYgKHRoaXMuX2lzU2xpZGluZykge1xuICAgICAgRXZlbnRIYW5kbGVyLm9uZSh0aGlzLl9lbGVtZW50LCBFVkVOVF9TTElELCAoKSA9PiB0aGlzLmN5Y2xlKCkpXG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICB0aGlzLmN5Y2xlKClcbiAgfVxuXG4gIHRvKGluZGV4KSB7XG4gICAgY29uc3QgaXRlbXMgPSB0aGlzLl9nZXRJdGVtcygpXG4gICAgaWYgKGluZGV4ID4gaXRlbXMubGVuZ3RoIC0gMSB8fCBpbmRleCA8IDApIHtcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIGlmICh0aGlzLl9pc1NsaWRpbmcpIHtcbiAgICAgIEV2ZW50SGFuZGxlci5vbmUodGhpcy5fZWxlbWVudCwgRVZFTlRfU0xJRCwgKCkgPT4gdGhpcy50byhpbmRleCkpXG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICBjb25zdCBhY3RpdmVJbmRleCA9IHRoaXMuX2dldEl0ZW1JbmRleCh0aGlzLl9nZXRBY3RpdmUoKSlcbiAgICBpZiAoYWN0aXZlSW5kZXggPT09IGluZGV4KSB7XG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICBjb25zdCBvcmRlciA9IGluZGV4ID4gYWN0aXZlSW5kZXggPyBPUkRFUl9ORVhUIDogT1JERVJfUFJFVlxuXG4gICAgdGhpcy5fc2xpZGUob3JkZXIsIGl0ZW1zW2luZGV4XSlcbiAgfVxuXG4gIGRpc3Bvc2UoKSB7XG4gICAgaWYgKHRoaXMuX3N3aXBlSGVscGVyKSB7XG4gICAgICB0aGlzLl9zd2lwZUhlbHBlci5kaXNwb3NlKClcbiAgICB9XG5cbiAgICBzdXBlci5kaXNwb3NlKClcbiAgfVxuXG4gIC8vIFByaXZhdGVcbiAgX2NvbmZpZ0FmdGVyTWVyZ2UoY29uZmlnKSB7XG4gICAgY29uZmlnLmRlZmF1bHRJbnRlcnZhbCA9IGNvbmZpZy5pbnRlcnZhbFxuICAgIHJldHVybiBjb25maWdcbiAgfVxuXG4gIF9hZGRFdmVudExpc3RlbmVycygpIHtcbiAgICBpZiAodGhpcy5fY29uZmlnLmtleWJvYXJkKSB7XG4gICAgICBFdmVudEhhbmRsZXIub24odGhpcy5fZWxlbWVudCwgRVZFTlRfS0VZRE9XTiwgZXZlbnQgPT4gdGhpcy5fa2V5ZG93bihldmVudCkpXG4gICAgfVxuXG4gICAgaWYgKHRoaXMuX2NvbmZpZy5wYXVzZSA9PT0gJ2hvdmVyJykge1xuICAgICAgRXZlbnRIYW5kbGVyLm9uKHRoaXMuX2VsZW1lbnQsIEVWRU5UX01PVVNFRU5URVIsICgpID0+IHRoaXMucGF1c2UoKSlcbiAgICAgIEV2ZW50SGFuZGxlci5vbih0aGlzLl9lbGVtZW50LCBFVkVOVF9NT1VTRUxFQVZFLCAoKSA9PiB0aGlzLl9tYXliZUVuYWJsZUN5Y2xlKCkpXG4gICAgfVxuXG4gICAgaWYgKHRoaXMuX2NvbmZpZy50b3VjaCAmJiBTd2lwZS5pc1N1cHBvcnRlZCgpKSB7XG4gICAgICB0aGlzLl9hZGRUb3VjaEV2ZW50TGlzdGVuZXJzKClcbiAgICB9XG4gIH1cblxuICBfYWRkVG91Y2hFdmVudExpc3RlbmVycygpIHtcbiAgICBmb3IgKGNvbnN0IGltZyBvZiBTZWxlY3RvckVuZ2luZS5maW5kKFNFTEVDVE9SX0lURU1fSU1HLCB0aGlzLl9lbGVtZW50KSkge1xuICAgICAgRXZlbnRIYW5kbGVyLm9uKGltZywgRVZFTlRfRFJBR19TVEFSVCwgZXZlbnQgPT4gZXZlbnQucHJldmVudERlZmF1bHQoKSlcbiAgICB9XG5cbiAgICBjb25zdCBlbmRDYWxsQmFjayA9ICgpID0+IHtcbiAgICAgIGlmICh0aGlzLl9jb25maWcucGF1c2UgIT09ICdob3ZlcicpIHtcbiAgICAgICAgcmV0dXJuXG4gICAgICB9XG5cbiAgICAgIC8vIElmIGl0J3MgYSB0b3VjaC1lbmFibGVkIGRldmljZSwgbW91c2VlbnRlci9sZWF2ZSBhcmUgZmlyZWQgYXNcbiAgICAgIC8vIHBhcnQgb2YgdGhlIG1vdXNlIGNvbXBhdGliaWxpdHkgZXZlbnRzIG9uIGZpcnN0IHRhcCAtIHRoZSBjYXJvdXNlbFxuICAgICAgLy8gd291bGQgc3RvcCBjeWNsaW5nIHVudGlsIHVzZXIgdGFwcGVkIG91dCBvZiBpdDtcbiAgICAgIC8vIGhlcmUsIHdlIGxpc3RlbiBmb3IgdG91Y2hlbmQsIGV4cGxpY2l0bHkgcGF1c2UgdGhlIGNhcm91c2VsXG4gICAgICAvLyAoYXMgaWYgaXQncyB0aGUgc2Vjb25kIHRpbWUgd2UgdGFwIG9uIGl0LCBtb3VzZWVudGVyIGNvbXBhdCBldmVudFxuICAgICAgLy8gaXMgTk9UIGZpcmVkKSBhbmQgYWZ0ZXIgYSB0aW1lb3V0ICh0byBhbGxvdyBmb3IgbW91c2UgY29tcGF0aWJpbGl0eVxuICAgICAgLy8gZXZlbnRzIHRvIGZpcmUpIHdlIGV4cGxpY2l0bHkgcmVzdGFydCBjeWNsaW5nXG5cbiAgICAgIHRoaXMucGF1c2UoKVxuICAgICAgaWYgKHRoaXMudG91Y2hUaW1lb3V0KSB7XG4gICAgICAgIGNsZWFyVGltZW91dCh0aGlzLnRvdWNoVGltZW91dClcbiAgICAgIH1cblxuICAgICAgdGhpcy50b3VjaFRpbWVvdXQgPSBzZXRUaW1lb3V0KCgpID0+IHRoaXMuX21heWJlRW5hYmxlQ3ljbGUoKSwgVE9VQ0hFVkVOVF9DT01QQVRfV0FJVCArIHRoaXMuX2NvbmZpZy5pbnRlcnZhbClcbiAgICB9XG5cbiAgICBjb25zdCBzd2lwZUNvbmZpZyA9IHtcbiAgICAgIGxlZnRDYWxsYmFjazogKCkgPT4gdGhpcy5fc2xpZGUodGhpcy5fZGlyZWN0aW9uVG9PcmRlcihESVJFQ1RJT05fTEVGVCkpLFxuICAgICAgcmlnaHRDYWxsYmFjazogKCkgPT4gdGhpcy5fc2xpZGUodGhpcy5fZGlyZWN0aW9uVG9PcmRlcihESVJFQ1RJT05fUklHSFQpKSxcbiAgICAgIGVuZENhbGxiYWNrOiBlbmRDYWxsQmFja1xuICAgIH1cblxuICAgIHRoaXMuX3N3aXBlSGVscGVyID0gbmV3IFN3aXBlKHRoaXMuX2VsZW1lbnQsIHN3aXBlQ29uZmlnKVxuICB9XG5cbiAgX2tleWRvd24oZXZlbnQpIHtcbiAgICBpZiAoL2lucHV0fHRleHRhcmVhL2kudGVzdChldmVudC50YXJnZXQudGFnTmFtZSkpIHtcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIGNvbnN0IGRpcmVjdGlvbiA9IEtFWV9UT19ESVJFQ1RJT05bZXZlbnQua2V5XVxuICAgIGlmIChkaXJlY3Rpb24pIHtcbiAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KClcbiAgICAgIHRoaXMuX3NsaWRlKHRoaXMuX2RpcmVjdGlvblRvT3JkZXIoZGlyZWN0aW9uKSlcbiAgICB9XG4gIH1cblxuICBfZ2V0SXRlbUluZGV4KGVsZW1lbnQpIHtcbiAgICByZXR1cm4gdGhpcy5fZ2V0SXRlbXMoKS5pbmRleE9mKGVsZW1lbnQpXG4gIH1cblxuICBfc2V0QWN0aXZlSW5kaWNhdG9yRWxlbWVudChpbmRleCkge1xuICAgIGlmICghdGhpcy5faW5kaWNhdG9yc0VsZW1lbnQpIHtcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIGNvbnN0IGFjdGl2ZUluZGljYXRvciA9IFNlbGVjdG9yRW5naW5lLmZpbmRPbmUoU0VMRUNUT1JfQUNUSVZFLCB0aGlzLl9pbmRpY2F0b3JzRWxlbWVudClcblxuICAgIGFjdGl2ZUluZGljYXRvci5jbGFzc0xpc3QucmVtb3ZlKENMQVNTX05BTUVfQUNUSVZFKVxuICAgIGFjdGl2ZUluZGljYXRvci5yZW1vdmVBdHRyaWJ1dGUoJ2FyaWEtY3VycmVudCcpXG5cbiAgICBjb25zdCBuZXdBY3RpdmVJbmRpY2F0b3IgPSBTZWxlY3RvckVuZ2luZS5maW5kT25lKGBbZGF0YS1icy1zbGlkZS10bz1cIiR7aW5kZXh9XCJdYCwgdGhpcy5faW5kaWNhdG9yc0VsZW1lbnQpXG5cbiAgICBpZiAobmV3QWN0aXZlSW5kaWNhdG9yKSB7XG4gICAgICBuZXdBY3RpdmVJbmRpY2F0b3IuY2xhc3NMaXN0LmFkZChDTEFTU19OQU1FX0FDVElWRSlcbiAgICAgIG5ld0FjdGl2ZUluZGljYXRvci5zZXRBdHRyaWJ1dGUoJ2FyaWEtY3VycmVudCcsICd0cnVlJylcbiAgICB9XG4gIH1cblxuICBfdXBkYXRlSW50ZXJ2YWwoKSB7XG4gICAgY29uc3QgZWxlbWVudCA9IHRoaXMuX2FjdGl2ZUVsZW1lbnQgfHwgdGhpcy5fZ2V0QWN0aXZlKClcblxuICAgIGlmICghZWxlbWVudCkge1xuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgY29uc3QgZWxlbWVudEludGVydmFsID0gTnVtYmVyLnBhcnNlSW50KGVsZW1lbnQuZ2V0QXR0cmlidXRlKCdkYXRhLWJzLWludGVydmFsJyksIDEwKVxuXG4gICAgdGhpcy5fY29uZmlnLmludGVydmFsID0gZWxlbWVudEludGVydmFsIHx8IHRoaXMuX2NvbmZpZy5kZWZhdWx0SW50ZXJ2YWxcbiAgfVxuXG4gIF9zbGlkZShvcmRlciwgZWxlbWVudCA9IG51bGwpIHtcbiAgICBpZiAodGhpcy5faXNTbGlkaW5nKSB7XG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICBjb25zdCBhY3RpdmVFbGVtZW50ID0gdGhpcy5fZ2V0QWN0aXZlKClcbiAgICBjb25zdCBpc05leHQgPSBvcmRlciA9PT0gT1JERVJfTkVYVFxuICAgIGNvbnN0IG5leHRFbGVtZW50ID0gZWxlbWVudCB8fCBnZXROZXh0QWN0aXZlRWxlbWVudCh0aGlzLl9nZXRJdGVtcygpLCBhY3RpdmVFbGVtZW50LCBpc05leHQsIHRoaXMuX2NvbmZpZy53cmFwKVxuXG4gICAgaWYgKG5leHRFbGVtZW50ID09PSBhY3RpdmVFbGVtZW50KSB7XG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICBjb25zdCBuZXh0RWxlbWVudEluZGV4ID0gdGhpcy5fZ2V0SXRlbUluZGV4KG5leHRFbGVtZW50KVxuXG4gICAgY29uc3QgdHJpZ2dlckV2ZW50ID0gZXZlbnROYW1lID0+IHtcbiAgICAgIHJldHVybiBFdmVudEhhbmRsZXIudHJpZ2dlcih0aGlzLl9lbGVtZW50LCBldmVudE5hbWUsIHtcbiAgICAgICAgcmVsYXRlZFRhcmdldDogbmV4dEVsZW1lbnQsXG4gICAgICAgIGRpcmVjdGlvbjogdGhpcy5fb3JkZXJUb0RpcmVjdGlvbihvcmRlciksXG4gICAgICAgIGZyb206IHRoaXMuX2dldEl0ZW1JbmRleChhY3RpdmVFbGVtZW50KSxcbiAgICAgICAgdG86IG5leHRFbGVtZW50SW5kZXhcbiAgICAgIH0pXG4gICAgfVxuXG4gICAgY29uc3Qgc2xpZGVFdmVudCA9IHRyaWdnZXJFdmVudChFVkVOVF9TTElERSlcblxuICAgIGlmIChzbGlkZUV2ZW50LmRlZmF1bHRQcmV2ZW50ZWQpIHtcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIGlmICghYWN0aXZlRWxlbWVudCB8fCAhbmV4dEVsZW1lbnQpIHtcbiAgICAgIC8vIFNvbWUgd2VpcmRuZXNzIGlzIGhhcHBlbmluZywgc28gd2UgYmFpbFxuICAgICAgLy8gVE9ETzogY2hhbmdlIHRlc3RzIHRoYXQgdXNlIGVtcHR5IGRpdnMgdG8gYXZvaWQgdGhpcyBjaGVja1xuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgY29uc3QgaXNDeWNsaW5nID0gQm9vbGVhbih0aGlzLl9pbnRlcnZhbClcbiAgICB0aGlzLnBhdXNlKClcblxuICAgIHRoaXMuX2lzU2xpZGluZyA9IHRydWVcblxuICAgIHRoaXMuX3NldEFjdGl2ZUluZGljYXRvckVsZW1lbnQobmV4dEVsZW1lbnRJbmRleClcbiAgICB0aGlzLl9hY3RpdmVFbGVtZW50ID0gbmV4dEVsZW1lbnRcblxuICAgIGNvbnN0IGRpcmVjdGlvbmFsQ2xhc3NOYW1lID0gaXNOZXh0ID8gQ0xBU1NfTkFNRV9TVEFSVCA6IENMQVNTX05BTUVfRU5EXG4gICAgY29uc3Qgb3JkZXJDbGFzc05hbWUgPSBpc05leHQgPyBDTEFTU19OQU1FX05FWFQgOiBDTEFTU19OQU1FX1BSRVZcblxuICAgIG5leHRFbGVtZW50LmNsYXNzTGlzdC5hZGQob3JkZXJDbGFzc05hbWUpXG5cbiAgICByZWZsb3cobmV4dEVsZW1lbnQpXG5cbiAgICBhY3RpdmVFbGVtZW50LmNsYXNzTGlzdC5hZGQoZGlyZWN0aW9uYWxDbGFzc05hbWUpXG4gICAgbmV4dEVsZW1lbnQuY2xhc3NMaXN0LmFkZChkaXJlY3Rpb25hbENsYXNzTmFtZSlcblxuICAgIGNvbnN0IGNvbXBsZXRlQ2FsbEJhY2sgPSAoKSA9PiB7XG4gICAgICBuZXh0RWxlbWVudC5jbGFzc0xpc3QucmVtb3ZlKGRpcmVjdGlvbmFsQ2xhc3NOYW1lLCBvcmRlckNsYXNzTmFtZSlcbiAgICAgIG5leHRFbGVtZW50LmNsYXNzTGlzdC5hZGQoQ0xBU1NfTkFNRV9BQ1RJVkUpXG5cbiAgICAgIGFjdGl2ZUVsZW1lbnQuY2xhc3NMaXN0LnJlbW92ZShDTEFTU19OQU1FX0FDVElWRSwgb3JkZXJDbGFzc05hbWUsIGRpcmVjdGlvbmFsQ2xhc3NOYW1lKVxuXG4gICAgICB0aGlzLl9pc1NsaWRpbmcgPSBmYWxzZVxuXG4gICAgICB0cmlnZ2VyRXZlbnQoRVZFTlRfU0xJRClcbiAgICB9XG5cbiAgICB0aGlzLl9xdWV1ZUNhbGxiYWNrKGNvbXBsZXRlQ2FsbEJhY2ssIGFjdGl2ZUVsZW1lbnQsIHRoaXMuX2lzQW5pbWF0ZWQoKSlcblxuICAgIGlmIChpc0N5Y2xpbmcpIHtcbiAgICAgIHRoaXMuY3ljbGUoKVxuICAgIH1cbiAgfVxuXG4gIF9pc0FuaW1hdGVkKCkge1xuICAgIHJldHVybiB0aGlzLl9lbGVtZW50LmNsYXNzTGlzdC5jb250YWlucyhDTEFTU19OQU1FX1NMSURFKVxuICB9XG5cbiAgX2dldEFjdGl2ZSgpIHtcbiAgICByZXR1cm4gU2VsZWN0b3JFbmdpbmUuZmluZE9uZShTRUxFQ1RPUl9BQ1RJVkVfSVRFTSwgdGhpcy5fZWxlbWVudClcbiAgfVxuXG4gIF9nZXRJdGVtcygpIHtcbiAgICByZXR1cm4gU2VsZWN0b3JFbmdpbmUuZmluZChTRUxFQ1RPUl9JVEVNLCB0aGlzLl9lbGVtZW50KVxuICB9XG5cbiAgX2NsZWFySW50ZXJ2YWwoKSB7XG4gICAgaWYgKHRoaXMuX2ludGVydmFsKSB7XG4gICAgICBjbGVhckludGVydmFsKHRoaXMuX2ludGVydmFsKVxuICAgICAgdGhpcy5faW50ZXJ2YWwgPSBudWxsXG4gICAgfVxuICB9XG5cbiAgX2RpcmVjdGlvblRvT3JkZXIoZGlyZWN0aW9uKSB7XG4gICAgaWYgKGlzUlRMKCkpIHtcbiAgICAgIHJldHVybiBkaXJlY3Rpb24gPT09IERJUkVDVElPTl9MRUZUID8gT1JERVJfUFJFViA6IE9SREVSX05FWFRcbiAgICB9XG5cbiAgICByZXR1cm4gZGlyZWN0aW9uID09PSBESVJFQ1RJT05fTEVGVCA/IE9SREVSX05FWFQgOiBPUkRFUl9QUkVWXG4gIH1cblxuICBfb3JkZXJUb0RpcmVjdGlvbihvcmRlcikge1xuICAgIGlmIChpc1JUTCgpKSB7XG4gICAgICByZXR1cm4gb3JkZXIgPT09IE9SREVSX1BSRVYgPyBESVJFQ1RJT05fTEVGVCA6IERJUkVDVElPTl9SSUdIVFxuICAgIH1cblxuICAgIHJldHVybiBvcmRlciA9PT0gT1JERVJfUFJFViA/IERJUkVDVElPTl9SSUdIVCA6IERJUkVDVElPTl9MRUZUXG4gIH1cblxuICAvLyBTdGF0aWNcbiAgc3RhdGljIGpRdWVyeUludGVyZmFjZShjb25maWcpIHtcbiAgICByZXR1cm4gdGhpcy5lYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGRhdGEgPSBDYXJvdXNlbC5nZXRPckNyZWF0ZUluc3RhbmNlKHRoaXMsIGNvbmZpZylcblxuICAgICAgaWYgKHR5cGVvZiBjb25maWcgPT09ICdudW1iZXInKSB7XG4gICAgICAgIGRhdGEudG8oY29uZmlnKVxuICAgICAgICByZXR1cm5cbiAgICAgIH1cblxuICAgICAgaWYgKHR5cGVvZiBjb25maWcgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgIGlmIChkYXRhW2NvbmZpZ10gPT09IHVuZGVmaW5lZCB8fCBjb25maWcuc3RhcnRzV2l0aCgnXycpIHx8IGNvbmZpZyA9PT0gJ2NvbnN0cnVjdG9yJykge1xuICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoYE5vIG1ldGhvZCBuYW1lZCBcIiR7Y29uZmlnfVwiYClcbiAgICAgICAgfVxuXG4gICAgICAgIGRhdGFbY29uZmlnXSgpXG4gICAgICB9XG4gICAgfSlcbiAgfVxufVxuXG4vKipcbiAqIERhdGEgQVBJIGltcGxlbWVudGF0aW9uXG4gKi9cblxuRXZlbnRIYW5kbGVyLm9uKGRvY3VtZW50LCBFVkVOVF9DTElDS19EQVRBX0FQSSwgU0VMRUNUT1JfREFUQV9TTElERSwgZnVuY3Rpb24gKGV2ZW50KSB7XG4gIGNvbnN0IHRhcmdldCA9IFNlbGVjdG9yRW5naW5lLmdldEVsZW1lbnRGcm9tU2VsZWN0b3IodGhpcylcblxuICBpZiAoIXRhcmdldCB8fCAhdGFyZ2V0LmNsYXNzTGlzdC5jb250YWlucyhDTEFTU19OQU1FX0NBUk9VU0VMKSkge1xuICAgIHJldHVyblxuICB9XG5cbiAgZXZlbnQucHJldmVudERlZmF1bHQoKVxuXG4gIGNvbnN0IGNhcm91c2VsID0gQ2Fyb3VzZWwuZ2V0T3JDcmVhdGVJbnN0YW5jZSh0YXJnZXQpXG4gIGNvbnN0IHNsaWRlSW5kZXggPSB0aGlzLmdldEF0dHJpYnV0ZSgnZGF0YS1icy1zbGlkZS10bycpXG5cbiAgaWYgKHNsaWRlSW5kZXgpIHtcbiAgICBjYXJvdXNlbC50byhzbGlkZUluZGV4KVxuICAgIGNhcm91c2VsLl9tYXliZUVuYWJsZUN5Y2xlKClcbiAgICByZXR1cm5cbiAgfVxuXG4gIGlmIChNYW5pcHVsYXRvci5nZXREYXRhQXR0cmlidXRlKHRoaXMsICdzbGlkZScpID09PSAnbmV4dCcpIHtcbiAgICBjYXJvdXNlbC5uZXh0KClcbiAgICBjYXJvdXNlbC5fbWF5YmVFbmFibGVDeWNsZSgpXG4gICAgcmV0dXJuXG4gIH1cblxuICBjYXJvdXNlbC5wcmV2KClcbiAgY2Fyb3VzZWwuX21heWJlRW5hYmxlQ3ljbGUoKVxufSlcblxuRXZlbnRIYW5kbGVyLm9uKHdpbmRvdywgRVZFTlRfTE9BRF9EQVRBX0FQSSwgKCkgPT4ge1xuICBjb25zdCBjYXJvdXNlbHMgPSBTZWxlY3RvckVuZ2luZS5maW5kKFNFTEVDVE9SX0RBVEFfUklERSlcblxuICBmb3IgKGNvbnN0IGNhcm91c2VsIG9mIGNhcm91c2Vscykge1xuICAgIENhcm91c2VsLmdldE9yQ3JlYXRlSW5zdGFuY2UoY2Fyb3VzZWwpXG4gIH1cbn0pXG5cbi8qKlxuICogalF1ZXJ5XG4gKi9cblxuZGVmaW5lSlF1ZXJ5UGx1Z2luKENhcm91c2VsKVxuXG5leHBvcnQgZGVmYXVsdCBDYXJvdXNlbFxuIiwiLyoqXG4gKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICogQm9vdHN0cmFwIGNvbGxhcHNlLmpzXG4gKiBMaWNlbnNlZCB1bmRlciBNSVQgKGh0dHBzOi8vZ2l0aHViLmNvbS90d2JzL2Jvb3RzdHJhcC9ibG9iL21haW4vTElDRU5TRSlcbiAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gKi9cblxuaW1wb3J0IEJhc2VDb21wb25lbnQgZnJvbSAnLi9iYXNlLWNvbXBvbmVudC5qcydcbmltcG9ydCBFdmVudEhhbmRsZXIgZnJvbSAnLi9kb20vZXZlbnQtaGFuZGxlci5qcydcbmltcG9ydCBTZWxlY3RvckVuZ2luZSBmcm9tICcuL2RvbS9zZWxlY3Rvci1lbmdpbmUuanMnXG5pbXBvcnQge1xuICBkZWZpbmVKUXVlcnlQbHVnaW4sXG4gIGdldEVsZW1lbnQsXG4gIHJlZmxvd1xufSBmcm9tICcuL3V0aWwvaW5kZXguanMnXG5cbi8qKlxuICogQ29uc3RhbnRzXG4gKi9cblxuY29uc3QgTkFNRSA9ICdjb2xsYXBzZSdcbmNvbnN0IERBVEFfS0VZID0gJ2JzLmNvbGxhcHNlJ1xuY29uc3QgRVZFTlRfS0VZID0gYC4ke0RBVEFfS0VZfWBcbmNvbnN0IERBVEFfQVBJX0tFWSA9ICcuZGF0YS1hcGknXG5cbmNvbnN0IEVWRU5UX1NIT1cgPSBgc2hvdyR7RVZFTlRfS0VZfWBcbmNvbnN0IEVWRU5UX1NIT1dOID0gYHNob3duJHtFVkVOVF9LRVl9YFxuY29uc3QgRVZFTlRfSElERSA9IGBoaWRlJHtFVkVOVF9LRVl9YFxuY29uc3QgRVZFTlRfSElEREVOID0gYGhpZGRlbiR7RVZFTlRfS0VZfWBcbmNvbnN0IEVWRU5UX0NMSUNLX0RBVEFfQVBJID0gYGNsaWNrJHtFVkVOVF9LRVl9JHtEQVRBX0FQSV9LRVl9YFxuXG5jb25zdCBDTEFTU19OQU1FX1NIT1cgPSAnc2hvdydcbmNvbnN0IENMQVNTX05BTUVfQ09MTEFQU0UgPSAnY29sbGFwc2UnXG5jb25zdCBDTEFTU19OQU1FX0NPTExBUFNJTkcgPSAnY29sbGFwc2luZydcbmNvbnN0IENMQVNTX05BTUVfQ09MTEFQU0VEID0gJ2NvbGxhcHNlZCdcbmNvbnN0IENMQVNTX05BTUVfREVFUEVSX0NISUxEUkVOID0gYDpzY29wZSAuJHtDTEFTU19OQU1FX0NPTExBUFNFfSAuJHtDTEFTU19OQU1FX0NPTExBUFNFfWBcbmNvbnN0IENMQVNTX05BTUVfSE9SSVpPTlRBTCA9ICdjb2xsYXBzZS1ob3Jpem9udGFsJ1xuXG5jb25zdCBXSURUSCA9ICd3aWR0aCdcbmNvbnN0IEhFSUdIVCA9ICdoZWlnaHQnXG5cbmNvbnN0IFNFTEVDVE9SX0FDVElWRVMgPSAnLmNvbGxhcHNlLnNob3csIC5jb2xsYXBzZS5jb2xsYXBzaW5nJ1xuY29uc3QgU0VMRUNUT1JfREFUQV9UT0dHTEUgPSAnW2RhdGEtYnMtdG9nZ2xlPVwiY29sbGFwc2VcIl0nXG5cbmNvbnN0IERlZmF1bHQgPSB7XG4gIHBhcmVudDogbnVsbCxcbiAgdG9nZ2xlOiB0cnVlXG59XG5cbmNvbnN0IERlZmF1bHRUeXBlID0ge1xuICBwYXJlbnQ6ICcobnVsbHxlbGVtZW50KScsXG4gIHRvZ2dsZTogJ2Jvb2xlYW4nXG59XG5cbi8qKlxuICogQ2xhc3MgZGVmaW5pdGlvblxuICovXG5cbmNsYXNzIENvbGxhcHNlIGV4dGVuZHMgQmFzZUNvbXBvbmVudCB7XG4gIGNvbnN0cnVjdG9yKGVsZW1lbnQsIGNvbmZpZykge1xuICAgIHN1cGVyKGVsZW1lbnQsIGNvbmZpZylcblxuICAgIHRoaXMuX2lzVHJhbnNpdGlvbmluZyA9IGZhbHNlXG4gICAgdGhpcy5fdHJpZ2dlckFycmF5ID0gW11cblxuICAgIGNvbnN0IHRvZ2dsZUxpc3QgPSBTZWxlY3RvckVuZ2luZS5maW5kKFNFTEVDVE9SX0RBVEFfVE9HR0xFKVxuXG4gICAgZm9yIChjb25zdCBlbGVtIG9mIHRvZ2dsZUxpc3QpIHtcbiAgICAgIGNvbnN0IHNlbGVjdG9yID0gU2VsZWN0b3JFbmdpbmUuZ2V0U2VsZWN0b3JGcm9tRWxlbWVudChlbGVtKVxuICAgICAgY29uc3QgZmlsdGVyRWxlbWVudCA9IFNlbGVjdG9yRW5naW5lLmZpbmQoc2VsZWN0b3IpXG4gICAgICAgIC5maWx0ZXIoZm91bmRFbGVtZW50ID0+IGZvdW5kRWxlbWVudCA9PT0gdGhpcy5fZWxlbWVudClcblxuICAgICAgaWYgKHNlbGVjdG9yICE9PSBudWxsICYmIGZpbHRlckVsZW1lbnQubGVuZ3RoKSB7XG4gICAgICAgIHRoaXMuX3RyaWdnZXJBcnJheS5wdXNoKGVsZW0pXG4gICAgICB9XG4gICAgfVxuXG4gICAgdGhpcy5faW5pdGlhbGl6ZUNoaWxkcmVuKClcblxuICAgIGlmICghdGhpcy5fY29uZmlnLnBhcmVudCkge1xuICAgICAgdGhpcy5fYWRkQXJpYUFuZENvbGxhcHNlZENsYXNzKHRoaXMuX3RyaWdnZXJBcnJheSwgdGhpcy5faXNTaG93bigpKVxuICAgIH1cblxuICAgIGlmICh0aGlzLl9jb25maWcudG9nZ2xlKSB7XG4gICAgICB0aGlzLnRvZ2dsZSgpXG4gICAgfVxuICB9XG5cbiAgLy8gR2V0dGVyc1xuICBzdGF0aWMgZ2V0IERlZmF1bHQoKSB7XG4gICAgcmV0dXJuIERlZmF1bHRcbiAgfVxuXG4gIHN0YXRpYyBnZXQgRGVmYXVsdFR5cGUoKSB7XG4gICAgcmV0dXJuIERlZmF1bHRUeXBlXG4gIH1cblxuICBzdGF0aWMgZ2V0IE5BTUUoKSB7XG4gICAgcmV0dXJuIE5BTUVcbiAgfVxuXG4gIC8vIFB1YmxpY1xuICB0b2dnbGUoKSB7XG4gICAgaWYgKHRoaXMuX2lzU2hvd24oKSkge1xuICAgICAgdGhpcy5oaWRlKClcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5zaG93KClcbiAgICB9XG4gIH1cblxuICBzaG93KCkge1xuICAgIGlmICh0aGlzLl9pc1RyYW5zaXRpb25pbmcgfHwgdGhpcy5faXNTaG93bigpKSB7XG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICBsZXQgYWN0aXZlQ2hpbGRyZW4gPSBbXVxuXG4gICAgLy8gZmluZCBhY3RpdmUgY2hpbGRyZW5cbiAgICBpZiAodGhpcy5fY29uZmlnLnBhcmVudCkge1xuICAgICAgYWN0aXZlQ2hpbGRyZW4gPSB0aGlzLl9nZXRGaXJzdExldmVsQ2hpbGRyZW4oU0VMRUNUT1JfQUNUSVZFUylcbiAgICAgICAgLmZpbHRlcihlbGVtZW50ID0+IGVsZW1lbnQgIT09IHRoaXMuX2VsZW1lbnQpXG4gICAgICAgIC5tYXAoZWxlbWVudCA9PiBDb2xsYXBzZS5nZXRPckNyZWF0ZUluc3RhbmNlKGVsZW1lbnQsIHsgdG9nZ2xlOiBmYWxzZSB9KSlcbiAgICB9XG5cbiAgICBpZiAoYWN0aXZlQ2hpbGRyZW4ubGVuZ3RoICYmIGFjdGl2ZUNoaWxkcmVuWzBdLl9pc1RyYW5zaXRpb25pbmcpIHtcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIGNvbnN0IHN0YXJ0RXZlbnQgPSBFdmVudEhhbmRsZXIudHJpZ2dlcih0aGlzLl9lbGVtZW50LCBFVkVOVF9TSE9XKVxuICAgIGlmIChzdGFydEV2ZW50LmRlZmF1bHRQcmV2ZW50ZWQpIHtcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIGZvciAoY29uc3QgYWN0aXZlSW5zdGFuY2Ugb2YgYWN0aXZlQ2hpbGRyZW4pIHtcbiAgICAgIGFjdGl2ZUluc3RhbmNlLmhpZGUoKVxuICAgIH1cblxuICAgIGNvbnN0IGRpbWVuc2lvbiA9IHRoaXMuX2dldERpbWVuc2lvbigpXG5cbiAgICB0aGlzLl9lbGVtZW50LmNsYXNzTGlzdC5yZW1vdmUoQ0xBU1NfTkFNRV9DT0xMQVBTRSlcbiAgICB0aGlzLl9lbGVtZW50LmNsYXNzTGlzdC5hZGQoQ0xBU1NfTkFNRV9DT0xMQVBTSU5HKVxuXG4gICAgdGhpcy5fZWxlbWVudC5zdHlsZVtkaW1lbnNpb25dID0gMFxuXG4gICAgdGhpcy5fYWRkQXJpYUFuZENvbGxhcHNlZENsYXNzKHRoaXMuX3RyaWdnZXJBcnJheSwgdHJ1ZSlcbiAgICB0aGlzLl9pc1RyYW5zaXRpb25pbmcgPSB0cnVlXG5cbiAgICBjb25zdCBjb21wbGV0ZSA9ICgpID0+IHtcbiAgICAgIHRoaXMuX2lzVHJhbnNpdGlvbmluZyA9IGZhbHNlXG5cbiAgICAgIHRoaXMuX2VsZW1lbnQuY2xhc3NMaXN0LnJlbW92ZShDTEFTU19OQU1FX0NPTExBUFNJTkcpXG4gICAgICB0aGlzLl9lbGVtZW50LmNsYXNzTGlzdC5hZGQoQ0xBU1NfTkFNRV9DT0xMQVBTRSwgQ0xBU1NfTkFNRV9TSE9XKVxuXG4gICAgICB0aGlzLl9lbGVtZW50LnN0eWxlW2RpbWVuc2lvbl0gPSAnJ1xuXG4gICAgICBFdmVudEhhbmRsZXIudHJpZ2dlcih0aGlzLl9lbGVtZW50LCBFVkVOVF9TSE9XTilcbiAgICB9XG5cbiAgICBjb25zdCBjYXBpdGFsaXplZERpbWVuc2lvbiA9IGRpbWVuc2lvblswXS50b1VwcGVyQ2FzZSgpICsgZGltZW5zaW9uLnNsaWNlKDEpXG4gICAgY29uc3Qgc2Nyb2xsU2l6ZSA9IGBzY3JvbGwke2NhcGl0YWxpemVkRGltZW5zaW9ufWBcblxuICAgIHRoaXMuX3F1ZXVlQ2FsbGJhY2soY29tcGxldGUsIHRoaXMuX2VsZW1lbnQsIHRydWUpXG4gICAgdGhpcy5fZWxlbWVudC5zdHlsZVtkaW1lbnNpb25dID0gYCR7dGhpcy5fZWxlbWVudFtzY3JvbGxTaXplXX1weGBcbiAgfVxuXG4gIGhpZGUoKSB7XG4gICAgaWYgKHRoaXMuX2lzVHJhbnNpdGlvbmluZyB8fCAhdGhpcy5faXNTaG93bigpKSB7XG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICBjb25zdCBzdGFydEV2ZW50ID0gRXZlbnRIYW5kbGVyLnRyaWdnZXIodGhpcy5fZWxlbWVudCwgRVZFTlRfSElERSlcbiAgICBpZiAoc3RhcnRFdmVudC5kZWZhdWx0UHJldmVudGVkKSB7XG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICBjb25zdCBkaW1lbnNpb24gPSB0aGlzLl9nZXREaW1lbnNpb24oKVxuXG4gICAgdGhpcy5fZWxlbWVudC5zdHlsZVtkaW1lbnNpb25dID0gYCR7dGhpcy5fZWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKVtkaW1lbnNpb25dfXB4YFxuXG4gICAgcmVmbG93KHRoaXMuX2VsZW1lbnQpXG5cbiAgICB0aGlzLl9lbGVtZW50LmNsYXNzTGlzdC5hZGQoQ0xBU1NfTkFNRV9DT0xMQVBTSU5HKVxuICAgIHRoaXMuX2VsZW1lbnQuY2xhc3NMaXN0LnJlbW92ZShDTEFTU19OQU1FX0NPTExBUFNFLCBDTEFTU19OQU1FX1NIT1cpXG5cbiAgICBmb3IgKGNvbnN0IHRyaWdnZXIgb2YgdGhpcy5fdHJpZ2dlckFycmF5KSB7XG4gICAgICBjb25zdCBlbGVtZW50ID0gU2VsZWN0b3JFbmdpbmUuZ2V0RWxlbWVudEZyb21TZWxlY3Rvcih0cmlnZ2VyKVxuXG4gICAgICBpZiAoZWxlbWVudCAmJiAhdGhpcy5faXNTaG93bihlbGVtZW50KSkge1xuICAgICAgICB0aGlzLl9hZGRBcmlhQW5kQ29sbGFwc2VkQ2xhc3MoW3RyaWdnZXJdLCBmYWxzZSlcbiAgICAgIH1cbiAgICB9XG5cbiAgICB0aGlzLl9pc1RyYW5zaXRpb25pbmcgPSB0cnVlXG5cbiAgICBjb25zdCBjb21wbGV0ZSA9ICgpID0+IHtcbiAgICAgIHRoaXMuX2lzVHJhbnNpdGlvbmluZyA9IGZhbHNlXG4gICAgICB0aGlzLl9lbGVtZW50LmNsYXNzTGlzdC5yZW1vdmUoQ0xBU1NfTkFNRV9DT0xMQVBTSU5HKVxuICAgICAgdGhpcy5fZWxlbWVudC5jbGFzc0xpc3QuYWRkKENMQVNTX05BTUVfQ09MTEFQU0UpXG4gICAgICBFdmVudEhhbmRsZXIudHJpZ2dlcih0aGlzLl9lbGVtZW50LCBFVkVOVF9ISURERU4pXG4gICAgfVxuXG4gICAgdGhpcy5fZWxlbWVudC5zdHlsZVtkaW1lbnNpb25dID0gJydcblxuICAgIHRoaXMuX3F1ZXVlQ2FsbGJhY2soY29tcGxldGUsIHRoaXMuX2VsZW1lbnQsIHRydWUpXG4gIH1cblxuICBfaXNTaG93bihlbGVtZW50ID0gdGhpcy5fZWxlbWVudCkge1xuICAgIHJldHVybiBlbGVtZW50LmNsYXNzTGlzdC5jb250YWlucyhDTEFTU19OQU1FX1NIT1cpXG4gIH1cblxuICAvLyBQcml2YXRlXG4gIF9jb25maWdBZnRlck1lcmdlKGNvbmZpZykge1xuICAgIGNvbmZpZy50b2dnbGUgPSBCb29sZWFuKGNvbmZpZy50b2dnbGUpIC8vIENvZXJjZSBzdHJpbmcgdmFsdWVzXG4gICAgY29uZmlnLnBhcmVudCA9IGdldEVsZW1lbnQoY29uZmlnLnBhcmVudClcbiAgICByZXR1cm4gY29uZmlnXG4gIH1cblxuICBfZ2V0RGltZW5zaW9uKCkge1xuICAgIHJldHVybiB0aGlzLl9lbGVtZW50LmNsYXNzTGlzdC5jb250YWlucyhDTEFTU19OQU1FX0hPUklaT05UQUwpID8gV0lEVEggOiBIRUlHSFRcbiAgfVxuXG4gIF9pbml0aWFsaXplQ2hpbGRyZW4oKSB7XG4gICAgaWYgKCF0aGlzLl9jb25maWcucGFyZW50KSB7XG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICBjb25zdCBjaGlsZHJlbiA9IHRoaXMuX2dldEZpcnN0TGV2ZWxDaGlsZHJlbihTRUxFQ1RPUl9EQVRBX1RPR0dMRSlcblxuICAgIGZvciAoY29uc3QgZWxlbWVudCBvZiBjaGlsZHJlbikge1xuICAgICAgY29uc3Qgc2VsZWN0ZWQgPSBTZWxlY3RvckVuZ2luZS5nZXRFbGVtZW50RnJvbVNlbGVjdG9yKGVsZW1lbnQpXG5cbiAgICAgIGlmIChzZWxlY3RlZCkge1xuICAgICAgICB0aGlzLl9hZGRBcmlhQW5kQ29sbGFwc2VkQ2xhc3MoW2VsZW1lbnRdLCB0aGlzLl9pc1Nob3duKHNlbGVjdGVkKSlcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBfZ2V0Rmlyc3RMZXZlbENoaWxkcmVuKHNlbGVjdG9yKSB7XG4gICAgY29uc3QgY2hpbGRyZW4gPSBTZWxlY3RvckVuZ2luZS5maW5kKENMQVNTX05BTUVfREVFUEVSX0NISUxEUkVOLCB0aGlzLl9jb25maWcucGFyZW50KVxuICAgIC8vIHJlbW92ZSBjaGlsZHJlbiBpZiBncmVhdGVyIGRlcHRoXG4gICAgcmV0dXJuIFNlbGVjdG9yRW5naW5lLmZpbmQoc2VsZWN0b3IsIHRoaXMuX2NvbmZpZy5wYXJlbnQpLmZpbHRlcihlbGVtZW50ID0+ICFjaGlsZHJlbi5pbmNsdWRlcyhlbGVtZW50KSlcbiAgfVxuXG4gIF9hZGRBcmlhQW5kQ29sbGFwc2VkQ2xhc3ModHJpZ2dlckFycmF5LCBpc09wZW4pIHtcbiAgICBpZiAoIXRyaWdnZXJBcnJheS5sZW5ndGgpIHtcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIGZvciAoY29uc3QgZWxlbWVudCBvZiB0cmlnZ2VyQXJyYXkpIHtcbiAgICAgIGVsZW1lbnQuY2xhc3NMaXN0LnRvZ2dsZShDTEFTU19OQU1FX0NPTExBUFNFRCwgIWlzT3BlbilcbiAgICAgIGVsZW1lbnQuc2V0QXR0cmlidXRlKCdhcmlhLWV4cGFuZGVkJywgaXNPcGVuKVxuICAgIH1cbiAgfVxuXG4gIC8vIFN0YXRpY1xuICBzdGF0aWMgalF1ZXJ5SW50ZXJmYWNlKGNvbmZpZykge1xuICAgIGNvbnN0IF9jb25maWcgPSB7fVxuICAgIGlmICh0eXBlb2YgY29uZmlnID09PSAnc3RyaW5nJyAmJiAvc2hvd3xoaWRlLy50ZXN0KGNvbmZpZykpIHtcbiAgICAgIF9jb25maWcudG9nZ2xlID0gZmFsc2VcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5lYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGRhdGEgPSBDb2xsYXBzZS5nZXRPckNyZWF0ZUluc3RhbmNlKHRoaXMsIF9jb25maWcpXG5cbiAgICAgIGlmICh0eXBlb2YgY29uZmlnID09PSAnc3RyaW5nJykge1xuICAgICAgICBpZiAodHlwZW9mIGRhdGFbY29uZmlnXSA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGBObyBtZXRob2QgbmFtZWQgXCIke2NvbmZpZ31cImApXG4gICAgICAgIH1cblxuICAgICAgICBkYXRhW2NvbmZpZ10oKVxuICAgICAgfVxuICAgIH0pXG4gIH1cbn1cblxuLyoqXG4gKiBEYXRhIEFQSSBpbXBsZW1lbnRhdGlvblxuICovXG5cbkV2ZW50SGFuZGxlci5vbihkb2N1bWVudCwgRVZFTlRfQ0xJQ0tfREFUQV9BUEksIFNFTEVDVE9SX0RBVEFfVE9HR0xFLCBmdW5jdGlvbiAoZXZlbnQpIHtcbiAgLy8gcHJldmVudERlZmF1bHQgb25seSBmb3IgPGE+IGVsZW1lbnRzICh3aGljaCBjaGFuZ2UgdGhlIFVSTCkgbm90IGluc2lkZSB0aGUgY29sbGFwc2libGUgZWxlbWVudFxuICBpZiAoZXZlbnQudGFyZ2V0LnRhZ05hbWUgPT09ICdBJyB8fCAoZXZlbnQuZGVsZWdhdGVUYXJnZXQgJiYgZXZlbnQuZGVsZWdhdGVUYXJnZXQudGFnTmFtZSA9PT0gJ0EnKSkge1xuICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KClcbiAgfVxuXG4gIGZvciAoY29uc3QgZWxlbWVudCBvZiBTZWxlY3RvckVuZ2luZS5nZXRNdWx0aXBsZUVsZW1lbnRzRnJvbVNlbGVjdG9yKHRoaXMpKSB7XG4gICAgQ29sbGFwc2UuZ2V0T3JDcmVhdGVJbnN0YW5jZShlbGVtZW50LCB7IHRvZ2dsZTogZmFsc2UgfSkudG9nZ2xlKClcbiAgfVxufSlcblxuLyoqXG4gKiBqUXVlcnlcbiAqL1xuXG5kZWZpbmVKUXVlcnlQbHVnaW4oQ29sbGFwc2UpXG5cbmV4cG9ydCBkZWZhdWx0IENvbGxhcHNlXG4iLCJleHBvcnQgdmFyIHRvcCA9ICd0b3AnO1xuZXhwb3J0IHZhciBib3R0b20gPSAnYm90dG9tJztcbmV4cG9ydCB2YXIgcmlnaHQgPSAncmlnaHQnO1xuZXhwb3J0IHZhciBsZWZ0ID0gJ2xlZnQnO1xuZXhwb3J0IHZhciBhdXRvID0gJ2F1dG8nO1xuZXhwb3J0IHZhciBiYXNlUGxhY2VtZW50cyA9IFt0b3AsIGJvdHRvbSwgcmlnaHQsIGxlZnRdO1xuZXhwb3J0IHZhciBzdGFydCA9ICdzdGFydCc7XG5leHBvcnQgdmFyIGVuZCA9ICdlbmQnO1xuZXhwb3J0IHZhciBjbGlwcGluZ1BhcmVudHMgPSAnY2xpcHBpbmdQYXJlbnRzJztcbmV4cG9ydCB2YXIgdmlld3BvcnQgPSAndmlld3BvcnQnO1xuZXhwb3J0IHZhciBwb3BwZXIgPSAncG9wcGVyJztcbmV4cG9ydCB2YXIgcmVmZXJlbmNlID0gJ3JlZmVyZW5jZSc7XG5leHBvcnQgdmFyIHZhcmlhdGlvblBsYWNlbWVudHMgPSAvKiNfX1BVUkVfXyovYmFzZVBsYWNlbWVudHMucmVkdWNlKGZ1bmN0aW9uIChhY2MsIHBsYWNlbWVudCkge1xuICByZXR1cm4gYWNjLmNvbmNhdChbcGxhY2VtZW50ICsgXCItXCIgKyBzdGFydCwgcGxhY2VtZW50ICsgXCItXCIgKyBlbmRdKTtcbn0sIFtdKTtcbmV4cG9ydCB2YXIgcGxhY2VtZW50cyA9IC8qI19fUFVSRV9fKi9bXS5jb25jYXQoYmFzZVBsYWNlbWVudHMsIFthdXRvXSkucmVkdWNlKGZ1bmN0aW9uIChhY2MsIHBsYWNlbWVudCkge1xuICByZXR1cm4gYWNjLmNvbmNhdChbcGxhY2VtZW50LCBwbGFjZW1lbnQgKyBcIi1cIiArIHN0YXJ0LCBwbGFjZW1lbnQgKyBcIi1cIiArIGVuZF0pO1xufSwgW10pOyAvLyBtb2RpZmllcnMgdGhhdCBuZWVkIHRvIHJlYWQgdGhlIERPTVxuXG5leHBvcnQgdmFyIGJlZm9yZVJlYWQgPSAnYmVmb3JlUmVhZCc7XG5leHBvcnQgdmFyIHJlYWQgPSAncmVhZCc7XG5leHBvcnQgdmFyIGFmdGVyUmVhZCA9ICdhZnRlclJlYWQnOyAvLyBwdXJlLWxvZ2ljIG1vZGlmaWVyc1xuXG5leHBvcnQgdmFyIGJlZm9yZU1haW4gPSAnYmVmb3JlTWFpbic7XG5leHBvcnQgdmFyIG1haW4gPSAnbWFpbic7XG5leHBvcnQgdmFyIGFmdGVyTWFpbiA9ICdhZnRlck1haW4nOyAvLyBtb2RpZmllciB3aXRoIHRoZSBwdXJwb3NlIHRvIHdyaXRlIHRvIHRoZSBET00gKG9yIHdyaXRlIGludG8gYSBmcmFtZXdvcmsgc3RhdGUpXG5cbmV4cG9ydCB2YXIgYmVmb3JlV3JpdGUgPSAnYmVmb3JlV3JpdGUnO1xuZXhwb3J0IHZhciB3cml0ZSA9ICd3cml0ZSc7XG5leHBvcnQgdmFyIGFmdGVyV3JpdGUgPSAnYWZ0ZXJXcml0ZSc7XG5leHBvcnQgdmFyIG1vZGlmaWVyUGhhc2VzID0gW2JlZm9yZVJlYWQsIHJlYWQsIGFmdGVyUmVhZCwgYmVmb3JlTWFpbiwgbWFpbiwgYWZ0ZXJNYWluLCBiZWZvcmVXcml0ZSwgd3JpdGUsIGFmdGVyV3JpdGVdOyIsImV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGdldE5vZGVOYW1lKGVsZW1lbnQpIHtcbiAgcmV0dXJuIGVsZW1lbnQgPyAoZWxlbWVudC5ub2RlTmFtZSB8fCAnJykudG9Mb3dlckNhc2UoKSA6IG51bGw7XG59IiwiZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gZ2V0V2luZG93KG5vZGUpIHtcbiAgaWYgKG5vZGUgPT0gbnVsbCkge1xuICAgIHJldHVybiB3aW5kb3c7XG4gIH1cblxuICBpZiAobm9kZS50b1N0cmluZygpICE9PSAnW29iamVjdCBXaW5kb3ddJykge1xuICAgIHZhciBvd25lckRvY3VtZW50ID0gbm9kZS5vd25lckRvY3VtZW50O1xuICAgIHJldHVybiBvd25lckRvY3VtZW50ID8gb3duZXJEb2N1bWVudC5kZWZhdWx0VmlldyB8fCB3aW5kb3cgOiB3aW5kb3c7XG4gIH1cblxuICByZXR1cm4gbm9kZTtcbn0iLCJpbXBvcnQgZ2V0V2luZG93IGZyb20gXCIuL2dldFdpbmRvdy5qc1wiO1xuXG5mdW5jdGlvbiBpc0VsZW1lbnQobm9kZSkge1xuICB2YXIgT3duRWxlbWVudCA9IGdldFdpbmRvdyhub2RlKS5FbGVtZW50O1xuICByZXR1cm4gbm9kZSBpbnN0YW5jZW9mIE93bkVsZW1lbnQgfHwgbm9kZSBpbnN0YW5jZW9mIEVsZW1lbnQ7XG59XG5cbmZ1bmN0aW9uIGlzSFRNTEVsZW1lbnQobm9kZSkge1xuICB2YXIgT3duRWxlbWVudCA9IGdldFdpbmRvdyhub2RlKS5IVE1MRWxlbWVudDtcbiAgcmV0dXJuIG5vZGUgaW5zdGFuY2VvZiBPd25FbGVtZW50IHx8IG5vZGUgaW5zdGFuY2VvZiBIVE1MRWxlbWVudDtcbn1cblxuZnVuY3Rpb24gaXNTaGFkb3dSb290KG5vZGUpIHtcbiAgLy8gSUUgMTEgaGFzIG5vIFNoYWRvd1Jvb3RcbiAgaWYgKHR5cGVvZiBTaGFkb3dSb290ID09PSAndW5kZWZpbmVkJykge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHZhciBPd25FbGVtZW50ID0gZ2V0V2luZG93KG5vZGUpLlNoYWRvd1Jvb3Q7XG4gIHJldHVybiBub2RlIGluc3RhbmNlb2YgT3duRWxlbWVudCB8fCBub2RlIGluc3RhbmNlb2YgU2hhZG93Um9vdDtcbn1cblxuZXhwb3J0IHsgaXNFbGVtZW50LCBpc0hUTUxFbGVtZW50LCBpc1NoYWRvd1Jvb3QgfTsiLCJpbXBvcnQgZ2V0Tm9kZU5hbWUgZnJvbSBcIi4uL2RvbS11dGlscy9nZXROb2RlTmFtZS5qc1wiO1xuaW1wb3J0IHsgaXNIVE1MRWxlbWVudCB9IGZyb20gXCIuLi9kb20tdXRpbHMvaW5zdGFuY2VPZi5qc1wiOyAvLyBUaGlzIG1vZGlmaWVyIHRha2VzIHRoZSBzdHlsZXMgcHJlcGFyZWQgYnkgdGhlIGBjb21wdXRlU3R5bGVzYCBtb2RpZmllclxuLy8gYW5kIGFwcGxpZXMgdGhlbSB0byB0aGUgSFRNTEVsZW1lbnRzIHN1Y2ggYXMgcG9wcGVyIGFuZCBhcnJvd1xuXG5mdW5jdGlvbiBhcHBseVN0eWxlcyhfcmVmKSB7XG4gIHZhciBzdGF0ZSA9IF9yZWYuc3RhdGU7XG4gIE9iamVjdC5rZXlzKHN0YXRlLmVsZW1lbnRzKS5mb3JFYWNoKGZ1bmN0aW9uIChuYW1lKSB7XG4gICAgdmFyIHN0eWxlID0gc3RhdGUuc3R5bGVzW25hbWVdIHx8IHt9O1xuICAgIHZhciBhdHRyaWJ1dGVzID0gc3RhdGUuYXR0cmlidXRlc1tuYW1lXSB8fCB7fTtcbiAgICB2YXIgZWxlbWVudCA9IHN0YXRlLmVsZW1lbnRzW25hbWVdOyAvLyBhcnJvdyBpcyBvcHRpb25hbCArIHZpcnR1YWwgZWxlbWVudHNcblxuICAgIGlmICghaXNIVE1MRWxlbWVudChlbGVtZW50KSB8fCAhZ2V0Tm9kZU5hbWUoZWxlbWVudCkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9IC8vIEZsb3cgZG9lc24ndCBzdXBwb3J0IHRvIGV4dGVuZCB0aGlzIHByb3BlcnR5LCBidXQgaXQncyB0aGUgbW9zdFxuICAgIC8vIGVmZmVjdGl2ZSB3YXkgdG8gYXBwbHkgc3R5bGVzIHRvIGFuIEhUTUxFbGVtZW50XG4gICAgLy8gJEZsb3dGaXhNZVtjYW5ub3Qtd3JpdGVdXG5cblxuICAgIE9iamVjdC5hc3NpZ24oZWxlbWVudC5zdHlsZSwgc3R5bGUpO1xuICAgIE9iamVjdC5rZXlzKGF0dHJpYnV0ZXMpLmZvckVhY2goZnVuY3Rpb24gKG5hbWUpIHtcbiAgICAgIHZhciB2YWx1ZSA9IGF0dHJpYnV0ZXNbbmFtZV07XG5cbiAgICAgIGlmICh2YWx1ZSA9PT0gZmFsc2UpIHtcbiAgICAgICAgZWxlbWVudC5yZW1vdmVBdHRyaWJ1dGUobmFtZSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBlbGVtZW50LnNldEF0dHJpYnV0ZShuYW1lLCB2YWx1ZSA9PT0gdHJ1ZSA/ICcnIDogdmFsdWUpO1xuICAgICAgfVxuICAgIH0pO1xuICB9KTtcbn1cblxuZnVuY3Rpb24gZWZmZWN0KF9yZWYyKSB7XG4gIHZhciBzdGF0ZSA9IF9yZWYyLnN0YXRlO1xuICB2YXIgaW5pdGlhbFN0eWxlcyA9IHtcbiAgICBwb3BwZXI6IHtcbiAgICAgIHBvc2l0aW9uOiBzdGF0ZS5vcHRpb25zLnN0cmF0ZWd5LFxuICAgICAgbGVmdDogJzAnLFxuICAgICAgdG9wOiAnMCcsXG4gICAgICBtYXJnaW46ICcwJ1xuICAgIH0sXG4gICAgYXJyb3c6IHtcbiAgICAgIHBvc2l0aW9uOiAnYWJzb2x1dGUnXG4gICAgfSxcbiAgICByZWZlcmVuY2U6IHt9XG4gIH07XG4gIE9iamVjdC5hc3NpZ24oc3RhdGUuZWxlbWVudHMucG9wcGVyLnN0eWxlLCBpbml0aWFsU3R5bGVzLnBvcHBlcik7XG4gIHN0YXRlLnN0eWxlcyA9IGluaXRpYWxTdHlsZXM7XG5cbiAgaWYgKHN0YXRlLmVsZW1lbnRzLmFycm93KSB7XG4gICAgT2JqZWN0LmFzc2lnbihzdGF0ZS5lbGVtZW50cy5hcnJvdy5zdHlsZSwgaW5pdGlhbFN0eWxlcy5hcnJvdyk7XG4gIH1cblxuICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgIE9iamVjdC5rZXlzKHN0YXRlLmVsZW1lbnRzKS5mb3JFYWNoKGZ1bmN0aW9uIChuYW1lKSB7XG4gICAgICB2YXIgZWxlbWVudCA9IHN0YXRlLmVsZW1lbnRzW25hbWVdO1xuICAgICAgdmFyIGF0dHJpYnV0ZXMgPSBzdGF0ZS5hdHRyaWJ1dGVzW25hbWVdIHx8IHt9O1xuICAgICAgdmFyIHN0eWxlUHJvcGVydGllcyA9IE9iamVjdC5rZXlzKHN0YXRlLnN0eWxlcy5oYXNPd25Qcm9wZXJ0eShuYW1lKSA/IHN0YXRlLnN0eWxlc1tuYW1lXSA6IGluaXRpYWxTdHlsZXNbbmFtZV0pOyAvLyBTZXQgYWxsIHZhbHVlcyB0byBhbiBlbXB0eSBzdHJpbmcgdG8gdW5zZXQgdGhlbVxuXG4gICAgICB2YXIgc3R5bGUgPSBzdHlsZVByb3BlcnRpZXMucmVkdWNlKGZ1bmN0aW9uIChzdHlsZSwgcHJvcGVydHkpIHtcbiAgICAgICAgc3R5bGVbcHJvcGVydHldID0gJyc7XG4gICAgICAgIHJldHVybiBzdHlsZTtcbiAgICAgIH0sIHt9KTsgLy8gYXJyb3cgaXMgb3B0aW9uYWwgKyB2aXJ0dWFsIGVsZW1lbnRzXG5cbiAgICAgIGlmICghaXNIVE1MRWxlbWVudChlbGVtZW50KSB8fCAhZ2V0Tm9kZU5hbWUoZWxlbWVudCkpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBPYmplY3QuYXNzaWduKGVsZW1lbnQuc3R5bGUsIHN0eWxlKTtcbiAgICAgIE9iamVjdC5rZXlzKGF0dHJpYnV0ZXMpLmZvckVhY2goZnVuY3Rpb24gKGF0dHJpYnV0ZSkge1xuICAgICAgICBlbGVtZW50LnJlbW92ZUF0dHJpYnV0ZShhdHRyaWJ1dGUpO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH07XG59IC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBpbXBvcnQvbm8tdW51c2VkLW1vZHVsZXNcblxuXG5leHBvcnQgZGVmYXVsdCB7XG4gIG5hbWU6ICdhcHBseVN0eWxlcycsXG4gIGVuYWJsZWQ6IHRydWUsXG4gIHBoYXNlOiAnd3JpdGUnLFxuICBmbjogYXBwbHlTdHlsZXMsXG4gIGVmZmVjdDogZWZmZWN0LFxuICByZXF1aXJlczogWydjb21wdXRlU3R5bGVzJ11cbn07IiwiaW1wb3J0IHsgYXV0byB9IGZyb20gXCIuLi9lbnVtcy5qc1wiO1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gZ2V0QmFzZVBsYWNlbWVudChwbGFjZW1lbnQpIHtcbiAgcmV0dXJuIHBsYWNlbWVudC5zcGxpdCgnLScpWzBdO1xufSIsImV4cG9ydCB2YXIgbWF4ID0gTWF0aC5tYXg7XG5leHBvcnQgdmFyIG1pbiA9IE1hdGgubWluO1xuZXhwb3J0IHZhciByb3VuZCA9IE1hdGgucm91bmQ7IiwiZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gZ2V0VUFTdHJpbmcoKSB7XG4gIHZhciB1YURhdGEgPSBuYXZpZ2F0b3IudXNlckFnZW50RGF0YTtcblxuICBpZiAodWFEYXRhICE9IG51bGwgJiYgdWFEYXRhLmJyYW5kcyAmJiBBcnJheS5pc0FycmF5KHVhRGF0YS5icmFuZHMpKSB7XG4gICAgcmV0dXJuIHVhRGF0YS5icmFuZHMubWFwKGZ1bmN0aW9uIChpdGVtKSB7XG4gICAgICByZXR1cm4gaXRlbS5icmFuZCArIFwiL1wiICsgaXRlbS52ZXJzaW9uO1xuICAgIH0pLmpvaW4oJyAnKTtcbiAgfVxuXG4gIHJldHVybiBuYXZpZ2F0b3IudXNlckFnZW50O1xufSIsImltcG9ydCBnZXRVQVN0cmluZyBmcm9tIFwiLi4vdXRpbHMvdXNlckFnZW50LmpzXCI7XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBpc0xheW91dFZpZXdwb3J0KCkge1xuICByZXR1cm4gIS9eKCg/IWNocm9tZXxhbmRyb2lkKS4pKnNhZmFyaS9pLnRlc3QoZ2V0VUFTdHJpbmcoKSk7XG59IiwiaW1wb3J0IHsgaXNFbGVtZW50LCBpc0hUTUxFbGVtZW50IH0gZnJvbSBcIi4vaW5zdGFuY2VPZi5qc1wiO1xuaW1wb3J0IHsgcm91bmQgfSBmcm9tIFwiLi4vdXRpbHMvbWF0aC5qc1wiO1xuaW1wb3J0IGdldFdpbmRvdyBmcm9tIFwiLi9nZXRXaW5kb3cuanNcIjtcbmltcG9ydCBpc0xheW91dFZpZXdwb3J0IGZyb20gXCIuL2lzTGF5b3V0Vmlld3BvcnQuanNcIjtcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGdldEJvdW5kaW5nQ2xpZW50UmVjdChlbGVtZW50LCBpbmNsdWRlU2NhbGUsIGlzRml4ZWRTdHJhdGVneSkge1xuICBpZiAoaW5jbHVkZVNjYWxlID09PSB2b2lkIDApIHtcbiAgICBpbmNsdWRlU2NhbGUgPSBmYWxzZTtcbiAgfVxuXG4gIGlmIChpc0ZpeGVkU3RyYXRlZ3kgPT09IHZvaWQgMCkge1xuICAgIGlzRml4ZWRTdHJhdGVneSA9IGZhbHNlO1xuICB9XG5cbiAgdmFyIGNsaWVudFJlY3QgPSBlbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICB2YXIgc2NhbGVYID0gMTtcbiAgdmFyIHNjYWxlWSA9IDE7XG5cbiAgaWYgKGluY2x1ZGVTY2FsZSAmJiBpc0hUTUxFbGVtZW50KGVsZW1lbnQpKSB7XG4gICAgc2NhbGVYID0gZWxlbWVudC5vZmZzZXRXaWR0aCA+IDAgPyByb3VuZChjbGllbnRSZWN0LndpZHRoKSAvIGVsZW1lbnQub2Zmc2V0V2lkdGggfHwgMSA6IDE7XG4gICAgc2NhbGVZID0gZWxlbWVudC5vZmZzZXRIZWlnaHQgPiAwID8gcm91bmQoY2xpZW50UmVjdC5oZWlnaHQpIC8gZWxlbWVudC5vZmZzZXRIZWlnaHQgfHwgMSA6IDE7XG4gIH1cblxuICB2YXIgX3JlZiA9IGlzRWxlbWVudChlbGVtZW50KSA/IGdldFdpbmRvdyhlbGVtZW50KSA6IHdpbmRvdyxcbiAgICAgIHZpc3VhbFZpZXdwb3J0ID0gX3JlZi52aXN1YWxWaWV3cG9ydDtcblxuICB2YXIgYWRkVmlzdWFsT2Zmc2V0cyA9ICFpc0xheW91dFZpZXdwb3J0KCkgJiYgaXNGaXhlZFN0cmF0ZWd5O1xuICB2YXIgeCA9IChjbGllbnRSZWN0LmxlZnQgKyAoYWRkVmlzdWFsT2Zmc2V0cyAmJiB2aXN1YWxWaWV3cG9ydCA/IHZpc3VhbFZpZXdwb3J0Lm9mZnNldExlZnQgOiAwKSkgLyBzY2FsZVg7XG4gIHZhciB5ID0gKGNsaWVudFJlY3QudG9wICsgKGFkZFZpc3VhbE9mZnNldHMgJiYgdmlzdWFsVmlld3BvcnQgPyB2aXN1YWxWaWV3cG9ydC5vZmZzZXRUb3AgOiAwKSkgLyBzY2FsZVk7XG4gIHZhciB3aWR0aCA9IGNsaWVudFJlY3Qud2lkdGggLyBzY2FsZVg7XG4gIHZhciBoZWlnaHQgPSBjbGllbnRSZWN0LmhlaWdodCAvIHNjYWxlWTtcbiAgcmV0dXJuIHtcbiAgICB3aWR0aDogd2lkdGgsXG4gICAgaGVpZ2h0OiBoZWlnaHQsXG4gICAgdG9wOiB5LFxuICAgIHJpZ2h0OiB4ICsgd2lkdGgsXG4gICAgYm90dG9tOiB5ICsgaGVpZ2h0LFxuICAgIGxlZnQ6IHgsXG4gICAgeDogeCxcbiAgICB5OiB5XG4gIH07XG59IiwiaW1wb3J0IGdldEJvdW5kaW5nQ2xpZW50UmVjdCBmcm9tIFwiLi9nZXRCb3VuZGluZ0NsaWVudFJlY3QuanNcIjsgLy8gUmV0dXJucyB0aGUgbGF5b3V0IHJlY3Qgb2YgYW4gZWxlbWVudCByZWxhdGl2ZSB0byBpdHMgb2Zmc2V0UGFyZW50LiBMYXlvdXRcbi8vIG1lYW5zIGl0IGRvZXNuJ3QgdGFrZSBpbnRvIGFjY291bnQgdHJhbnNmb3Jtcy5cblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gZ2V0TGF5b3V0UmVjdChlbGVtZW50KSB7XG4gIHZhciBjbGllbnRSZWN0ID0gZ2V0Qm91bmRpbmdDbGllbnRSZWN0KGVsZW1lbnQpOyAvLyBVc2UgdGhlIGNsaWVudFJlY3Qgc2l6ZXMgaWYgaXQncyBub3QgYmVlbiB0cmFuc2Zvcm1lZC5cbiAgLy8gRml4ZXMgaHR0cHM6Ly9naXRodWIuY29tL3BvcHBlcmpzL3BvcHBlci1jb3JlL2lzc3Vlcy8xMjIzXG5cbiAgdmFyIHdpZHRoID0gZWxlbWVudC5vZmZzZXRXaWR0aDtcbiAgdmFyIGhlaWdodCA9IGVsZW1lbnQub2Zmc2V0SGVpZ2h0O1xuXG4gIGlmIChNYXRoLmFicyhjbGllbnRSZWN0LndpZHRoIC0gd2lkdGgpIDw9IDEpIHtcbiAgICB3aWR0aCA9IGNsaWVudFJlY3Qud2lkdGg7XG4gIH1cblxuICBpZiAoTWF0aC5hYnMoY2xpZW50UmVjdC5oZWlnaHQgLSBoZWlnaHQpIDw9IDEpIHtcbiAgICBoZWlnaHQgPSBjbGllbnRSZWN0LmhlaWdodDtcbiAgfVxuXG4gIHJldHVybiB7XG4gICAgeDogZWxlbWVudC5vZmZzZXRMZWZ0LFxuICAgIHk6IGVsZW1lbnQub2Zmc2V0VG9wLFxuICAgIHdpZHRoOiB3aWR0aCxcbiAgICBoZWlnaHQ6IGhlaWdodFxuICB9O1xufSIsImltcG9ydCB7IGlzU2hhZG93Um9vdCB9IGZyb20gXCIuL2luc3RhbmNlT2YuanNcIjtcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGNvbnRhaW5zKHBhcmVudCwgY2hpbGQpIHtcbiAgdmFyIHJvb3ROb2RlID0gY2hpbGQuZ2V0Um9vdE5vZGUgJiYgY2hpbGQuZ2V0Um9vdE5vZGUoKTsgLy8gRmlyc3QsIGF0dGVtcHQgd2l0aCBmYXN0ZXIgbmF0aXZlIG1ldGhvZFxuXG4gIGlmIChwYXJlbnQuY29udGFpbnMoY2hpbGQpKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH0gLy8gdGhlbiBmYWxsYmFjayB0byBjdXN0b20gaW1wbGVtZW50YXRpb24gd2l0aCBTaGFkb3cgRE9NIHN1cHBvcnRcbiAgZWxzZSBpZiAocm9vdE5vZGUgJiYgaXNTaGFkb3dSb290KHJvb3ROb2RlKSkge1xuICAgICAgdmFyIG5leHQgPSBjaGlsZDtcblxuICAgICAgZG8ge1xuICAgICAgICBpZiAobmV4dCAmJiBwYXJlbnQuaXNTYW1lTm9kZShuZXh0KSkge1xuICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9IC8vICRGbG93Rml4TWVbcHJvcC1taXNzaW5nXTogbmVlZCBhIGJldHRlciB3YXkgdG8gaGFuZGxlIHRoaXMuLi5cblxuXG4gICAgICAgIG5leHQgPSBuZXh0LnBhcmVudE5vZGUgfHwgbmV4dC5ob3N0O1xuICAgICAgfSB3aGlsZSAobmV4dCk7XG4gICAgfSAvLyBHaXZlIHVwLCB0aGUgcmVzdWx0IGlzIGZhbHNlXG5cblxuICByZXR1cm4gZmFsc2U7XG59IiwiaW1wb3J0IGdldFdpbmRvdyBmcm9tIFwiLi9nZXRXaW5kb3cuanNcIjtcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGdldENvbXB1dGVkU3R5bGUoZWxlbWVudCkge1xuICByZXR1cm4gZ2V0V2luZG93KGVsZW1lbnQpLmdldENvbXB1dGVkU3R5bGUoZWxlbWVudCk7XG59IiwiaW1wb3J0IGdldE5vZGVOYW1lIGZyb20gXCIuL2dldE5vZGVOYW1lLmpzXCI7XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBpc1RhYmxlRWxlbWVudChlbGVtZW50KSB7XG4gIHJldHVybiBbJ3RhYmxlJywgJ3RkJywgJ3RoJ10uaW5kZXhPZihnZXROb2RlTmFtZShlbGVtZW50KSkgPj0gMDtcbn0iLCJpbXBvcnQgeyBpc0VsZW1lbnQgfSBmcm9tIFwiLi9pbnN0YW5jZU9mLmpzXCI7XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBnZXREb2N1bWVudEVsZW1lbnQoZWxlbWVudCkge1xuICAvLyAkRmxvd0ZpeE1lW2luY29tcGF0aWJsZS1yZXR1cm5dOiBhc3N1bWUgYm9keSBpcyBhbHdheXMgYXZhaWxhYmxlXG4gIHJldHVybiAoKGlzRWxlbWVudChlbGVtZW50KSA/IGVsZW1lbnQub3duZXJEb2N1bWVudCA6IC8vICRGbG93Rml4TWVbcHJvcC1taXNzaW5nXVxuICBlbGVtZW50LmRvY3VtZW50KSB8fCB3aW5kb3cuZG9jdW1lbnQpLmRvY3VtZW50RWxlbWVudDtcbn0iLCJpbXBvcnQgZ2V0Tm9kZU5hbWUgZnJvbSBcIi4vZ2V0Tm9kZU5hbWUuanNcIjtcbmltcG9ydCBnZXREb2N1bWVudEVsZW1lbnQgZnJvbSBcIi4vZ2V0RG9jdW1lbnRFbGVtZW50LmpzXCI7XG5pbXBvcnQgeyBpc1NoYWRvd1Jvb3QgfSBmcm9tIFwiLi9pbnN0YW5jZU9mLmpzXCI7XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBnZXRQYXJlbnROb2RlKGVsZW1lbnQpIHtcbiAgaWYgKGdldE5vZGVOYW1lKGVsZW1lbnQpID09PSAnaHRtbCcpIHtcbiAgICByZXR1cm4gZWxlbWVudDtcbiAgfVxuXG4gIHJldHVybiAoLy8gdGhpcyBpcyBhIHF1aWNrZXIgKGJ1dCBsZXNzIHR5cGUgc2FmZSkgd2F5IHRvIHNhdmUgcXVpdGUgc29tZSBieXRlcyBmcm9tIHRoZSBidW5kbGVcbiAgICAvLyAkRmxvd0ZpeE1lW2luY29tcGF0aWJsZS1yZXR1cm5dXG4gICAgLy8gJEZsb3dGaXhNZVtwcm9wLW1pc3NpbmddXG4gICAgZWxlbWVudC5hc3NpZ25lZFNsb3QgfHwgLy8gc3RlcCBpbnRvIHRoZSBzaGFkb3cgRE9NIG9mIHRoZSBwYXJlbnQgb2YgYSBzbG90dGVkIG5vZGVcbiAgICBlbGVtZW50LnBhcmVudE5vZGUgfHwgKCAvLyBET00gRWxlbWVudCBkZXRlY3RlZFxuICAgIGlzU2hhZG93Um9vdChlbGVtZW50KSA/IGVsZW1lbnQuaG9zdCA6IG51bGwpIHx8IC8vIFNoYWRvd1Jvb3QgZGV0ZWN0ZWRcbiAgICAvLyAkRmxvd0ZpeE1lW2luY29tcGF0aWJsZS1jYWxsXTogSFRNTEVsZW1lbnQgaXMgYSBOb2RlXG4gICAgZ2V0RG9jdW1lbnRFbGVtZW50KGVsZW1lbnQpIC8vIGZhbGxiYWNrXG5cbiAgKTtcbn0iLCJpbXBvcnQgZ2V0V2luZG93IGZyb20gXCIuL2dldFdpbmRvdy5qc1wiO1xuaW1wb3J0IGdldE5vZGVOYW1lIGZyb20gXCIuL2dldE5vZGVOYW1lLmpzXCI7XG5pbXBvcnQgZ2V0Q29tcHV0ZWRTdHlsZSBmcm9tIFwiLi9nZXRDb21wdXRlZFN0eWxlLmpzXCI7XG5pbXBvcnQgeyBpc0hUTUxFbGVtZW50LCBpc1NoYWRvd1Jvb3QgfSBmcm9tIFwiLi9pbnN0YW5jZU9mLmpzXCI7XG5pbXBvcnQgaXNUYWJsZUVsZW1lbnQgZnJvbSBcIi4vaXNUYWJsZUVsZW1lbnQuanNcIjtcbmltcG9ydCBnZXRQYXJlbnROb2RlIGZyb20gXCIuL2dldFBhcmVudE5vZGUuanNcIjtcbmltcG9ydCBnZXRVQVN0cmluZyBmcm9tIFwiLi4vdXRpbHMvdXNlckFnZW50LmpzXCI7XG5cbmZ1bmN0aW9uIGdldFRydWVPZmZzZXRQYXJlbnQoZWxlbWVudCkge1xuICBpZiAoIWlzSFRNTEVsZW1lbnQoZWxlbWVudCkgfHwgLy8gaHR0cHM6Ly9naXRodWIuY29tL3BvcHBlcmpzL3BvcHBlci1jb3JlL2lzc3Vlcy84MzdcbiAgZ2V0Q29tcHV0ZWRTdHlsZShlbGVtZW50KS5wb3NpdGlvbiA9PT0gJ2ZpeGVkJykge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgcmV0dXJuIGVsZW1lbnQub2Zmc2V0UGFyZW50O1xufSAvLyBgLm9mZnNldFBhcmVudGAgcmVwb3J0cyBgbnVsbGAgZm9yIGZpeGVkIGVsZW1lbnRzLCB3aGlsZSBhYnNvbHV0ZSBlbGVtZW50c1xuLy8gcmV0dXJuIHRoZSBjb250YWluaW5nIGJsb2NrXG5cblxuZnVuY3Rpb24gZ2V0Q29udGFpbmluZ0Jsb2NrKGVsZW1lbnQpIHtcbiAgdmFyIGlzRmlyZWZveCA9IC9maXJlZm94L2kudGVzdChnZXRVQVN0cmluZygpKTtcbiAgdmFyIGlzSUUgPSAvVHJpZGVudC9pLnRlc3QoZ2V0VUFTdHJpbmcoKSk7XG5cbiAgaWYgKGlzSUUgJiYgaXNIVE1MRWxlbWVudChlbGVtZW50KSkge1xuICAgIC8vIEluIElFIDksIDEwIGFuZCAxMSBmaXhlZCBlbGVtZW50cyBjb250YWluaW5nIGJsb2NrIGlzIGFsd2F5cyBlc3RhYmxpc2hlZCBieSB0aGUgdmlld3BvcnRcbiAgICB2YXIgZWxlbWVudENzcyA9IGdldENvbXB1dGVkU3R5bGUoZWxlbWVudCk7XG5cbiAgICBpZiAoZWxlbWVudENzcy5wb3NpdGlvbiA9PT0gJ2ZpeGVkJykge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICB9XG5cbiAgdmFyIGN1cnJlbnROb2RlID0gZ2V0UGFyZW50Tm9kZShlbGVtZW50KTtcblxuICBpZiAoaXNTaGFkb3dSb290KGN1cnJlbnROb2RlKSkge1xuICAgIGN1cnJlbnROb2RlID0gY3VycmVudE5vZGUuaG9zdDtcbiAgfVxuXG4gIHdoaWxlIChpc0hUTUxFbGVtZW50KGN1cnJlbnROb2RlKSAmJiBbJ2h0bWwnLCAnYm9keSddLmluZGV4T2YoZ2V0Tm9kZU5hbWUoY3VycmVudE5vZGUpKSA8IDApIHtcbiAgICB2YXIgY3NzID0gZ2V0Q29tcHV0ZWRTdHlsZShjdXJyZW50Tm9kZSk7IC8vIFRoaXMgaXMgbm9uLWV4aGF1c3RpdmUgYnV0IGNvdmVycyB0aGUgbW9zdCBjb21tb24gQ1NTIHByb3BlcnRpZXMgdGhhdFxuICAgIC8vIGNyZWF0ZSBhIGNvbnRhaW5pbmcgYmxvY2suXG4gICAgLy8gaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQ1NTL0NvbnRhaW5pbmdfYmxvY2sjaWRlbnRpZnlpbmdfdGhlX2NvbnRhaW5pbmdfYmxvY2tcblxuICAgIGlmIChjc3MudHJhbnNmb3JtICE9PSAnbm9uZScgfHwgY3NzLnBlcnNwZWN0aXZlICE9PSAnbm9uZScgfHwgY3NzLmNvbnRhaW4gPT09ICdwYWludCcgfHwgWyd0cmFuc2Zvcm0nLCAncGVyc3BlY3RpdmUnXS5pbmRleE9mKGNzcy53aWxsQ2hhbmdlKSAhPT0gLTEgfHwgaXNGaXJlZm94ICYmIGNzcy53aWxsQ2hhbmdlID09PSAnZmlsdGVyJyB8fCBpc0ZpcmVmb3ggJiYgY3NzLmZpbHRlciAmJiBjc3MuZmlsdGVyICE9PSAnbm9uZScpIHtcbiAgICAgIHJldHVybiBjdXJyZW50Tm9kZTtcbiAgICB9IGVsc2Uge1xuICAgICAgY3VycmVudE5vZGUgPSBjdXJyZW50Tm9kZS5wYXJlbnROb2RlO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBudWxsO1xufSAvLyBHZXRzIHRoZSBjbG9zZXN0IGFuY2VzdG9yIHBvc2l0aW9uZWQgZWxlbWVudC4gSGFuZGxlcyBzb21lIGVkZ2UgY2FzZXMsXG4vLyBzdWNoIGFzIHRhYmxlIGFuY2VzdG9ycyBhbmQgY3Jvc3MgYnJvd3NlciBidWdzLlxuXG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGdldE9mZnNldFBhcmVudChlbGVtZW50KSB7XG4gIHZhciB3aW5kb3cgPSBnZXRXaW5kb3coZWxlbWVudCk7XG4gIHZhciBvZmZzZXRQYXJlbnQgPSBnZXRUcnVlT2Zmc2V0UGFyZW50KGVsZW1lbnQpO1xuXG4gIHdoaWxlIChvZmZzZXRQYXJlbnQgJiYgaXNUYWJsZUVsZW1lbnQob2Zmc2V0UGFyZW50KSAmJiBnZXRDb21wdXRlZFN0eWxlKG9mZnNldFBhcmVudCkucG9zaXRpb24gPT09ICdzdGF0aWMnKSB7XG4gICAgb2Zmc2V0UGFyZW50ID0gZ2V0VHJ1ZU9mZnNldFBhcmVudChvZmZzZXRQYXJlbnQpO1xuICB9XG5cbiAgaWYgKG9mZnNldFBhcmVudCAmJiAoZ2V0Tm9kZU5hbWUob2Zmc2V0UGFyZW50KSA9PT0gJ2h0bWwnIHx8IGdldE5vZGVOYW1lKG9mZnNldFBhcmVudCkgPT09ICdib2R5JyAmJiBnZXRDb21wdXRlZFN0eWxlKG9mZnNldFBhcmVudCkucG9zaXRpb24gPT09ICdzdGF0aWMnKSkge1xuICAgIHJldHVybiB3aW5kb3c7XG4gIH1cblxuICByZXR1cm4gb2Zmc2V0UGFyZW50IHx8IGdldENvbnRhaW5pbmdCbG9jayhlbGVtZW50KSB8fCB3aW5kb3c7XG59IiwiZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gZ2V0TWFpbkF4aXNGcm9tUGxhY2VtZW50KHBsYWNlbWVudCkge1xuICByZXR1cm4gWyd0b3AnLCAnYm90dG9tJ10uaW5kZXhPZihwbGFjZW1lbnQpID49IDAgPyAneCcgOiAneSc7XG59IiwiaW1wb3J0IHsgbWF4IGFzIG1hdGhNYXgsIG1pbiBhcyBtYXRoTWluIH0gZnJvbSBcIi4vbWF0aC5qc1wiO1xuZXhwb3J0IGZ1bmN0aW9uIHdpdGhpbihtaW4sIHZhbHVlLCBtYXgpIHtcbiAgcmV0dXJuIG1hdGhNYXgobWluLCBtYXRoTWluKHZhbHVlLCBtYXgpKTtcbn1cbmV4cG9ydCBmdW5jdGlvbiB3aXRoaW5NYXhDbGFtcChtaW4sIHZhbHVlLCBtYXgpIHtcbiAgdmFyIHYgPSB3aXRoaW4obWluLCB2YWx1ZSwgbWF4KTtcbiAgcmV0dXJuIHYgPiBtYXggPyBtYXggOiB2O1xufSIsImV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGdldEZyZXNoU2lkZU9iamVjdCgpIHtcbiAgcmV0dXJuIHtcbiAgICB0b3A6IDAsXG4gICAgcmlnaHQ6IDAsXG4gICAgYm90dG9tOiAwLFxuICAgIGxlZnQ6IDBcbiAgfTtcbn0iLCJpbXBvcnQgZ2V0RnJlc2hTaWRlT2JqZWN0IGZyb20gXCIuL2dldEZyZXNoU2lkZU9iamVjdC5qc1wiO1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gbWVyZ2VQYWRkaW5nT2JqZWN0KHBhZGRpbmdPYmplY3QpIHtcbiAgcmV0dXJuIE9iamVjdC5hc3NpZ24oe30sIGdldEZyZXNoU2lkZU9iamVjdCgpLCBwYWRkaW5nT2JqZWN0KTtcbn0iLCJleHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBleHBhbmRUb0hhc2hNYXAodmFsdWUsIGtleXMpIHtcbiAgcmV0dXJuIGtleXMucmVkdWNlKGZ1bmN0aW9uIChoYXNoTWFwLCBrZXkpIHtcbiAgICBoYXNoTWFwW2tleV0gPSB2YWx1ZTtcbiAgICByZXR1cm4gaGFzaE1hcDtcbiAgfSwge30pO1xufSIsImltcG9ydCBnZXRCYXNlUGxhY2VtZW50IGZyb20gXCIuLi91dGlscy9nZXRCYXNlUGxhY2VtZW50LmpzXCI7XG5pbXBvcnQgZ2V0TGF5b3V0UmVjdCBmcm9tIFwiLi4vZG9tLXV0aWxzL2dldExheW91dFJlY3QuanNcIjtcbmltcG9ydCBjb250YWlucyBmcm9tIFwiLi4vZG9tLXV0aWxzL2NvbnRhaW5zLmpzXCI7XG5pbXBvcnQgZ2V0T2Zmc2V0UGFyZW50IGZyb20gXCIuLi9kb20tdXRpbHMvZ2V0T2Zmc2V0UGFyZW50LmpzXCI7XG5pbXBvcnQgZ2V0TWFpbkF4aXNGcm9tUGxhY2VtZW50IGZyb20gXCIuLi91dGlscy9nZXRNYWluQXhpc0Zyb21QbGFjZW1lbnQuanNcIjtcbmltcG9ydCB7IHdpdGhpbiB9IGZyb20gXCIuLi91dGlscy93aXRoaW4uanNcIjtcbmltcG9ydCBtZXJnZVBhZGRpbmdPYmplY3QgZnJvbSBcIi4uL3V0aWxzL21lcmdlUGFkZGluZ09iamVjdC5qc1wiO1xuaW1wb3J0IGV4cGFuZFRvSGFzaE1hcCBmcm9tIFwiLi4vdXRpbHMvZXhwYW5kVG9IYXNoTWFwLmpzXCI7XG5pbXBvcnQgeyBsZWZ0LCByaWdodCwgYmFzZVBsYWNlbWVudHMsIHRvcCwgYm90dG9tIH0gZnJvbSBcIi4uL2VudW1zLmpzXCI7IC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBpbXBvcnQvbm8tdW51c2VkLW1vZHVsZXNcblxudmFyIHRvUGFkZGluZ09iamVjdCA9IGZ1bmN0aW9uIHRvUGFkZGluZ09iamVjdChwYWRkaW5nLCBzdGF0ZSkge1xuICBwYWRkaW5nID0gdHlwZW9mIHBhZGRpbmcgPT09ICdmdW5jdGlvbicgPyBwYWRkaW5nKE9iamVjdC5hc3NpZ24oe30sIHN0YXRlLnJlY3RzLCB7XG4gICAgcGxhY2VtZW50OiBzdGF0ZS5wbGFjZW1lbnRcbiAgfSkpIDogcGFkZGluZztcbiAgcmV0dXJuIG1lcmdlUGFkZGluZ09iamVjdCh0eXBlb2YgcGFkZGluZyAhPT0gJ251bWJlcicgPyBwYWRkaW5nIDogZXhwYW5kVG9IYXNoTWFwKHBhZGRpbmcsIGJhc2VQbGFjZW1lbnRzKSk7XG59O1xuXG5mdW5jdGlvbiBhcnJvdyhfcmVmKSB7XG4gIHZhciBfc3RhdGUkbW9kaWZpZXJzRGF0YSQ7XG5cbiAgdmFyIHN0YXRlID0gX3JlZi5zdGF0ZSxcbiAgICAgIG5hbWUgPSBfcmVmLm5hbWUsXG4gICAgICBvcHRpb25zID0gX3JlZi5vcHRpb25zO1xuICB2YXIgYXJyb3dFbGVtZW50ID0gc3RhdGUuZWxlbWVudHMuYXJyb3c7XG4gIHZhciBwb3BwZXJPZmZzZXRzID0gc3RhdGUubW9kaWZpZXJzRGF0YS5wb3BwZXJPZmZzZXRzO1xuICB2YXIgYmFzZVBsYWNlbWVudCA9IGdldEJhc2VQbGFjZW1lbnQoc3RhdGUucGxhY2VtZW50KTtcbiAgdmFyIGF4aXMgPSBnZXRNYWluQXhpc0Zyb21QbGFjZW1lbnQoYmFzZVBsYWNlbWVudCk7XG4gIHZhciBpc1ZlcnRpY2FsID0gW2xlZnQsIHJpZ2h0XS5pbmRleE9mKGJhc2VQbGFjZW1lbnQpID49IDA7XG4gIHZhciBsZW4gPSBpc1ZlcnRpY2FsID8gJ2hlaWdodCcgOiAnd2lkdGgnO1xuXG4gIGlmICghYXJyb3dFbGVtZW50IHx8ICFwb3BwZXJPZmZzZXRzKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgdmFyIHBhZGRpbmdPYmplY3QgPSB0b1BhZGRpbmdPYmplY3Qob3B0aW9ucy5wYWRkaW5nLCBzdGF0ZSk7XG4gIHZhciBhcnJvd1JlY3QgPSBnZXRMYXlvdXRSZWN0KGFycm93RWxlbWVudCk7XG4gIHZhciBtaW5Qcm9wID0gYXhpcyA9PT0gJ3knID8gdG9wIDogbGVmdDtcbiAgdmFyIG1heFByb3AgPSBheGlzID09PSAneScgPyBib3R0b20gOiByaWdodDtcbiAgdmFyIGVuZERpZmYgPSBzdGF0ZS5yZWN0cy5yZWZlcmVuY2VbbGVuXSArIHN0YXRlLnJlY3RzLnJlZmVyZW5jZVtheGlzXSAtIHBvcHBlck9mZnNldHNbYXhpc10gLSBzdGF0ZS5yZWN0cy5wb3BwZXJbbGVuXTtcbiAgdmFyIHN0YXJ0RGlmZiA9IHBvcHBlck9mZnNldHNbYXhpc10gLSBzdGF0ZS5yZWN0cy5yZWZlcmVuY2VbYXhpc107XG4gIHZhciBhcnJvd09mZnNldFBhcmVudCA9IGdldE9mZnNldFBhcmVudChhcnJvd0VsZW1lbnQpO1xuICB2YXIgY2xpZW50U2l6ZSA9IGFycm93T2Zmc2V0UGFyZW50ID8gYXhpcyA9PT0gJ3knID8gYXJyb3dPZmZzZXRQYXJlbnQuY2xpZW50SGVpZ2h0IHx8IDAgOiBhcnJvd09mZnNldFBhcmVudC5jbGllbnRXaWR0aCB8fCAwIDogMDtcbiAgdmFyIGNlbnRlclRvUmVmZXJlbmNlID0gZW5kRGlmZiAvIDIgLSBzdGFydERpZmYgLyAyOyAvLyBNYWtlIHN1cmUgdGhlIGFycm93IGRvZXNuJ3Qgb3ZlcmZsb3cgdGhlIHBvcHBlciBpZiB0aGUgY2VudGVyIHBvaW50IGlzXG4gIC8vIG91dHNpZGUgb2YgdGhlIHBvcHBlciBib3VuZHNcblxuICB2YXIgbWluID0gcGFkZGluZ09iamVjdFttaW5Qcm9wXTtcbiAgdmFyIG1heCA9IGNsaWVudFNpemUgLSBhcnJvd1JlY3RbbGVuXSAtIHBhZGRpbmdPYmplY3RbbWF4UHJvcF07XG4gIHZhciBjZW50ZXIgPSBjbGllbnRTaXplIC8gMiAtIGFycm93UmVjdFtsZW5dIC8gMiArIGNlbnRlclRvUmVmZXJlbmNlO1xuICB2YXIgb2Zmc2V0ID0gd2l0aGluKG1pbiwgY2VudGVyLCBtYXgpOyAvLyBQcmV2ZW50cyBicmVha2luZyBzeW50YXggaGlnaGxpZ2h0aW5nLi4uXG5cbiAgdmFyIGF4aXNQcm9wID0gYXhpcztcbiAgc3RhdGUubW9kaWZpZXJzRGF0YVtuYW1lXSA9IChfc3RhdGUkbW9kaWZpZXJzRGF0YSQgPSB7fSwgX3N0YXRlJG1vZGlmaWVyc0RhdGEkW2F4aXNQcm9wXSA9IG9mZnNldCwgX3N0YXRlJG1vZGlmaWVyc0RhdGEkLmNlbnRlck9mZnNldCA9IG9mZnNldCAtIGNlbnRlciwgX3N0YXRlJG1vZGlmaWVyc0RhdGEkKTtcbn1cblxuZnVuY3Rpb24gZWZmZWN0KF9yZWYyKSB7XG4gIHZhciBzdGF0ZSA9IF9yZWYyLnN0YXRlLFxuICAgICAgb3B0aW9ucyA9IF9yZWYyLm9wdGlvbnM7XG4gIHZhciBfb3B0aW9ucyRlbGVtZW50ID0gb3B0aW9ucy5lbGVtZW50LFxuICAgICAgYXJyb3dFbGVtZW50ID0gX29wdGlvbnMkZWxlbWVudCA9PT0gdm9pZCAwID8gJ1tkYXRhLXBvcHBlci1hcnJvd10nIDogX29wdGlvbnMkZWxlbWVudDtcblxuICBpZiAoYXJyb3dFbGVtZW50ID09IG51bGwpIHtcbiAgICByZXR1cm47XG4gIH0gLy8gQ1NTIHNlbGVjdG9yXG5cblxuICBpZiAodHlwZW9mIGFycm93RWxlbWVudCA9PT0gJ3N0cmluZycpIHtcbiAgICBhcnJvd0VsZW1lbnQgPSBzdGF0ZS5lbGVtZW50cy5wb3BwZXIucXVlcnlTZWxlY3RvcihhcnJvd0VsZW1lbnQpO1xuXG4gICAgaWYgKCFhcnJvd0VsZW1lbnQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gIH1cblxuICBpZiAoIWNvbnRhaW5zKHN0YXRlLmVsZW1lbnRzLnBvcHBlciwgYXJyb3dFbGVtZW50KSkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIHN0YXRlLmVsZW1lbnRzLmFycm93ID0gYXJyb3dFbGVtZW50O1xufSAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgaW1wb3J0L25vLXVudXNlZC1tb2R1bGVzXG5cblxuZXhwb3J0IGRlZmF1bHQge1xuICBuYW1lOiAnYXJyb3cnLFxuICBlbmFibGVkOiB0cnVlLFxuICBwaGFzZTogJ21haW4nLFxuICBmbjogYXJyb3csXG4gIGVmZmVjdDogZWZmZWN0LFxuICByZXF1aXJlczogWydwb3BwZXJPZmZzZXRzJ10sXG4gIHJlcXVpcmVzSWZFeGlzdHM6IFsncHJldmVudE92ZXJmbG93J11cbn07IiwiZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gZ2V0VmFyaWF0aW9uKHBsYWNlbWVudCkge1xuICByZXR1cm4gcGxhY2VtZW50LnNwbGl0KCctJylbMV07XG59IiwiaW1wb3J0IHsgdG9wLCBsZWZ0LCByaWdodCwgYm90dG9tLCBlbmQgfSBmcm9tIFwiLi4vZW51bXMuanNcIjtcbmltcG9ydCBnZXRPZmZzZXRQYXJlbnQgZnJvbSBcIi4uL2RvbS11dGlscy9nZXRPZmZzZXRQYXJlbnQuanNcIjtcbmltcG9ydCBnZXRXaW5kb3cgZnJvbSBcIi4uL2RvbS11dGlscy9nZXRXaW5kb3cuanNcIjtcbmltcG9ydCBnZXREb2N1bWVudEVsZW1lbnQgZnJvbSBcIi4uL2RvbS11dGlscy9nZXREb2N1bWVudEVsZW1lbnQuanNcIjtcbmltcG9ydCBnZXRDb21wdXRlZFN0eWxlIGZyb20gXCIuLi9kb20tdXRpbHMvZ2V0Q29tcHV0ZWRTdHlsZS5qc1wiO1xuaW1wb3J0IGdldEJhc2VQbGFjZW1lbnQgZnJvbSBcIi4uL3V0aWxzL2dldEJhc2VQbGFjZW1lbnQuanNcIjtcbmltcG9ydCBnZXRWYXJpYXRpb24gZnJvbSBcIi4uL3V0aWxzL2dldFZhcmlhdGlvbi5qc1wiO1xuaW1wb3J0IHsgcm91bmQgfSBmcm9tIFwiLi4vdXRpbHMvbWF0aC5qc1wiOyAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgaW1wb3J0L25vLXVudXNlZC1tb2R1bGVzXG5cbnZhciB1bnNldFNpZGVzID0ge1xuICB0b3A6ICdhdXRvJyxcbiAgcmlnaHQ6ICdhdXRvJyxcbiAgYm90dG9tOiAnYXV0bycsXG4gIGxlZnQ6ICdhdXRvJ1xufTsgLy8gUm91bmQgdGhlIG9mZnNldHMgdG8gdGhlIG5lYXJlc3Qgc3VpdGFibGUgc3VicGl4ZWwgYmFzZWQgb24gdGhlIERQUi5cbi8vIFpvb21pbmcgY2FuIGNoYW5nZSB0aGUgRFBSLCBidXQgaXQgc2VlbXMgdG8gcmVwb3J0IGEgdmFsdWUgdGhhdCB3aWxsXG4vLyBjbGVhbmx5IGRpdmlkZSB0aGUgdmFsdWVzIGludG8gdGhlIGFwcHJvcHJpYXRlIHN1YnBpeGVscy5cblxuZnVuY3Rpb24gcm91bmRPZmZzZXRzQnlEUFIoX3JlZiwgd2luKSB7XG4gIHZhciB4ID0gX3JlZi54LFxuICAgICAgeSA9IF9yZWYueTtcbiAgdmFyIGRwciA9IHdpbi5kZXZpY2VQaXhlbFJhdGlvIHx8IDE7XG4gIHJldHVybiB7XG4gICAgeDogcm91bmQoeCAqIGRwcikgLyBkcHIgfHwgMCxcbiAgICB5OiByb3VuZCh5ICogZHByKSAvIGRwciB8fCAwXG4gIH07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBtYXBUb1N0eWxlcyhfcmVmMikge1xuICB2YXIgX09iamVjdCRhc3NpZ24yO1xuXG4gIHZhciBwb3BwZXIgPSBfcmVmMi5wb3BwZXIsXG4gICAgICBwb3BwZXJSZWN0ID0gX3JlZjIucG9wcGVyUmVjdCxcbiAgICAgIHBsYWNlbWVudCA9IF9yZWYyLnBsYWNlbWVudCxcbiAgICAgIHZhcmlhdGlvbiA9IF9yZWYyLnZhcmlhdGlvbixcbiAgICAgIG9mZnNldHMgPSBfcmVmMi5vZmZzZXRzLFxuICAgICAgcG9zaXRpb24gPSBfcmVmMi5wb3NpdGlvbixcbiAgICAgIGdwdUFjY2VsZXJhdGlvbiA9IF9yZWYyLmdwdUFjY2VsZXJhdGlvbixcbiAgICAgIGFkYXB0aXZlID0gX3JlZjIuYWRhcHRpdmUsXG4gICAgICByb3VuZE9mZnNldHMgPSBfcmVmMi5yb3VuZE9mZnNldHMsXG4gICAgICBpc0ZpeGVkID0gX3JlZjIuaXNGaXhlZDtcbiAgdmFyIF9vZmZzZXRzJHggPSBvZmZzZXRzLngsXG4gICAgICB4ID0gX29mZnNldHMkeCA9PT0gdm9pZCAwID8gMCA6IF9vZmZzZXRzJHgsXG4gICAgICBfb2Zmc2V0cyR5ID0gb2Zmc2V0cy55LFxuICAgICAgeSA9IF9vZmZzZXRzJHkgPT09IHZvaWQgMCA/IDAgOiBfb2Zmc2V0cyR5O1xuXG4gIHZhciBfcmVmMyA9IHR5cGVvZiByb3VuZE9mZnNldHMgPT09ICdmdW5jdGlvbicgPyByb3VuZE9mZnNldHMoe1xuICAgIHg6IHgsXG4gICAgeTogeVxuICB9KSA6IHtcbiAgICB4OiB4LFxuICAgIHk6IHlcbiAgfTtcblxuICB4ID0gX3JlZjMueDtcbiAgeSA9IF9yZWYzLnk7XG4gIHZhciBoYXNYID0gb2Zmc2V0cy5oYXNPd25Qcm9wZXJ0eSgneCcpO1xuICB2YXIgaGFzWSA9IG9mZnNldHMuaGFzT3duUHJvcGVydHkoJ3knKTtcbiAgdmFyIHNpZGVYID0gbGVmdDtcbiAgdmFyIHNpZGVZID0gdG9wO1xuICB2YXIgd2luID0gd2luZG93O1xuXG4gIGlmIChhZGFwdGl2ZSkge1xuICAgIHZhciBvZmZzZXRQYXJlbnQgPSBnZXRPZmZzZXRQYXJlbnQocG9wcGVyKTtcbiAgICB2YXIgaGVpZ2h0UHJvcCA9ICdjbGllbnRIZWlnaHQnO1xuICAgIHZhciB3aWR0aFByb3AgPSAnY2xpZW50V2lkdGgnO1xuXG4gICAgaWYgKG9mZnNldFBhcmVudCA9PT0gZ2V0V2luZG93KHBvcHBlcikpIHtcbiAgICAgIG9mZnNldFBhcmVudCA9IGdldERvY3VtZW50RWxlbWVudChwb3BwZXIpO1xuXG4gICAgICBpZiAoZ2V0Q29tcHV0ZWRTdHlsZShvZmZzZXRQYXJlbnQpLnBvc2l0aW9uICE9PSAnc3RhdGljJyAmJiBwb3NpdGlvbiA9PT0gJ2Fic29sdXRlJykge1xuICAgICAgICBoZWlnaHRQcm9wID0gJ3Njcm9sbEhlaWdodCc7XG4gICAgICAgIHdpZHRoUHJvcCA9ICdzY3JvbGxXaWR0aCc7XG4gICAgICB9XG4gICAgfSAvLyAkRmxvd0ZpeE1lW2luY29tcGF0aWJsZS1jYXN0XTogZm9yY2UgdHlwZSByZWZpbmVtZW50LCB3ZSBjb21wYXJlIG9mZnNldFBhcmVudCB3aXRoIHdpbmRvdyBhYm92ZSwgYnV0IEZsb3cgZG9lc24ndCBkZXRlY3QgaXRcblxuXG4gICAgb2Zmc2V0UGFyZW50ID0gb2Zmc2V0UGFyZW50O1xuXG4gICAgaWYgKHBsYWNlbWVudCA9PT0gdG9wIHx8IChwbGFjZW1lbnQgPT09IGxlZnQgfHwgcGxhY2VtZW50ID09PSByaWdodCkgJiYgdmFyaWF0aW9uID09PSBlbmQpIHtcbiAgICAgIHNpZGVZID0gYm90dG9tO1xuICAgICAgdmFyIG9mZnNldFkgPSBpc0ZpeGVkICYmIG9mZnNldFBhcmVudCA9PT0gd2luICYmIHdpbi52aXN1YWxWaWV3cG9ydCA/IHdpbi52aXN1YWxWaWV3cG9ydC5oZWlnaHQgOiAvLyAkRmxvd0ZpeE1lW3Byb3AtbWlzc2luZ11cbiAgICAgIG9mZnNldFBhcmVudFtoZWlnaHRQcm9wXTtcbiAgICAgIHkgLT0gb2Zmc2V0WSAtIHBvcHBlclJlY3QuaGVpZ2h0O1xuICAgICAgeSAqPSBncHVBY2NlbGVyYXRpb24gPyAxIDogLTE7XG4gICAgfVxuXG4gICAgaWYgKHBsYWNlbWVudCA9PT0gbGVmdCB8fCAocGxhY2VtZW50ID09PSB0b3AgfHwgcGxhY2VtZW50ID09PSBib3R0b20pICYmIHZhcmlhdGlvbiA9PT0gZW5kKSB7XG4gICAgICBzaWRlWCA9IHJpZ2h0O1xuICAgICAgdmFyIG9mZnNldFggPSBpc0ZpeGVkICYmIG9mZnNldFBhcmVudCA9PT0gd2luICYmIHdpbi52aXN1YWxWaWV3cG9ydCA/IHdpbi52aXN1YWxWaWV3cG9ydC53aWR0aCA6IC8vICRGbG93Rml4TWVbcHJvcC1taXNzaW5nXVxuICAgICAgb2Zmc2V0UGFyZW50W3dpZHRoUHJvcF07XG4gICAgICB4IC09IG9mZnNldFggLSBwb3BwZXJSZWN0LndpZHRoO1xuICAgICAgeCAqPSBncHVBY2NlbGVyYXRpb24gPyAxIDogLTE7XG4gICAgfVxuICB9XG5cbiAgdmFyIGNvbW1vblN0eWxlcyA9IE9iamVjdC5hc3NpZ24oe1xuICAgIHBvc2l0aW9uOiBwb3NpdGlvblxuICB9LCBhZGFwdGl2ZSAmJiB1bnNldFNpZGVzKTtcblxuICB2YXIgX3JlZjQgPSByb3VuZE9mZnNldHMgPT09IHRydWUgPyByb3VuZE9mZnNldHNCeURQUih7XG4gICAgeDogeCxcbiAgICB5OiB5XG4gIH0sIGdldFdpbmRvdyhwb3BwZXIpKSA6IHtcbiAgICB4OiB4LFxuICAgIHk6IHlcbiAgfTtcblxuICB4ID0gX3JlZjQueDtcbiAgeSA9IF9yZWY0Lnk7XG5cbiAgaWYgKGdwdUFjY2VsZXJhdGlvbikge1xuICAgIHZhciBfT2JqZWN0JGFzc2lnbjtcblxuICAgIHJldHVybiBPYmplY3QuYXNzaWduKHt9LCBjb21tb25TdHlsZXMsIChfT2JqZWN0JGFzc2lnbiA9IHt9LCBfT2JqZWN0JGFzc2lnbltzaWRlWV0gPSBoYXNZID8gJzAnIDogJycsIF9PYmplY3QkYXNzaWduW3NpZGVYXSA9IGhhc1ggPyAnMCcgOiAnJywgX09iamVjdCRhc3NpZ24udHJhbnNmb3JtID0gKHdpbi5kZXZpY2VQaXhlbFJhdGlvIHx8IDEpIDw9IDEgPyBcInRyYW5zbGF0ZShcIiArIHggKyBcInB4LCBcIiArIHkgKyBcInB4KVwiIDogXCJ0cmFuc2xhdGUzZChcIiArIHggKyBcInB4LCBcIiArIHkgKyBcInB4LCAwKVwiLCBfT2JqZWN0JGFzc2lnbikpO1xuICB9XG5cbiAgcmV0dXJuIE9iamVjdC5hc3NpZ24oe30sIGNvbW1vblN0eWxlcywgKF9PYmplY3QkYXNzaWduMiA9IHt9LCBfT2JqZWN0JGFzc2lnbjJbc2lkZVldID0gaGFzWSA/IHkgKyBcInB4XCIgOiAnJywgX09iamVjdCRhc3NpZ24yW3NpZGVYXSA9IGhhc1ggPyB4ICsgXCJweFwiIDogJycsIF9PYmplY3QkYXNzaWduMi50cmFuc2Zvcm0gPSAnJywgX09iamVjdCRhc3NpZ24yKSk7XG59XG5cbmZ1bmN0aW9uIGNvbXB1dGVTdHlsZXMoX3JlZjUpIHtcbiAgdmFyIHN0YXRlID0gX3JlZjUuc3RhdGUsXG4gICAgICBvcHRpb25zID0gX3JlZjUub3B0aW9ucztcbiAgdmFyIF9vcHRpb25zJGdwdUFjY2VsZXJhdCA9IG9wdGlvbnMuZ3B1QWNjZWxlcmF0aW9uLFxuICAgICAgZ3B1QWNjZWxlcmF0aW9uID0gX29wdGlvbnMkZ3B1QWNjZWxlcmF0ID09PSB2b2lkIDAgPyB0cnVlIDogX29wdGlvbnMkZ3B1QWNjZWxlcmF0LFxuICAgICAgX29wdGlvbnMkYWRhcHRpdmUgPSBvcHRpb25zLmFkYXB0aXZlLFxuICAgICAgYWRhcHRpdmUgPSBfb3B0aW9ucyRhZGFwdGl2ZSA9PT0gdm9pZCAwID8gdHJ1ZSA6IF9vcHRpb25zJGFkYXB0aXZlLFxuICAgICAgX29wdGlvbnMkcm91bmRPZmZzZXRzID0gb3B0aW9ucy5yb3VuZE9mZnNldHMsXG4gICAgICByb3VuZE9mZnNldHMgPSBfb3B0aW9ucyRyb3VuZE9mZnNldHMgPT09IHZvaWQgMCA/IHRydWUgOiBfb3B0aW9ucyRyb3VuZE9mZnNldHM7XG4gIHZhciBjb21tb25TdHlsZXMgPSB7XG4gICAgcGxhY2VtZW50OiBnZXRCYXNlUGxhY2VtZW50KHN0YXRlLnBsYWNlbWVudCksXG4gICAgdmFyaWF0aW9uOiBnZXRWYXJpYXRpb24oc3RhdGUucGxhY2VtZW50KSxcbiAgICBwb3BwZXI6IHN0YXRlLmVsZW1lbnRzLnBvcHBlcixcbiAgICBwb3BwZXJSZWN0OiBzdGF0ZS5yZWN0cy5wb3BwZXIsXG4gICAgZ3B1QWNjZWxlcmF0aW9uOiBncHVBY2NlbGVyYXRpb24sXG4gICAgaXNGaXhlZDogc3RhdGUub3B0aW9ucy5zdHJhdGVneSA9PT0gJ2ZpeGVkJ1xuICB9O1xuXG4gIGlmIChzdGF0ZS5tb2RpZmllcnNEYXRhLnBvcHBlck9mZnNldHMgIT0gbnVsbCkge1xuICAgIHN0YXRlLnN0eWxlcy5wb3BwZXIgPSBPYmplY3QuYXNzaWduKHt9LCBzdGF0ZS5zdHlsZXMucG9wcGVyLCBtYXBUb1N0eWxlcyhPYmplY3QuYXNzaWduKHt9LCBjb21tb25TdHlsZXMsIHtcbiAgICAgIG9mZnNldHM6IHN0YXRlLm1vZGlmaWVyc0RhdGEucG9wcGVyT2Zmc2V0cyxcbiAgICAgIHBvc2l0aW9uOiBzdGF0ZS5vcHRpb25zLnN0cmF0ZWd5LFxuICAgICAgYWRhcHRpdmU6IGFkYXB0aXZlLFxuICAgICAgcm91bmRPZmZzZXRzOiByb3VuZE9mZnNldHNcbiAgICB9KSkpO1xuICB9XG5cbiAgaWYgKHN0YXRlLm1vZGlmaWVyc0RhdGEuYXJyb3cgIT0gbnVsbCkge1xuICAgIHN0YXRlLnN0eWxlcy5hcnJvdyA9IE9iamVjdC5hc3NpZ24oe30sIHN0YXRlLnN0eWxlcy5hcnJvdywgbWFwVG9TdHlsZXMoT2JqZWN0LmFzc2lnbih7fSwgY29tbW9uU3R5bGVzLCB7XG4gICAgICBvZmZzZXRzOiBzdGF0ZS5tb2RpZmllcnNEYXRhLmFycm93LFxuICAgICAgcG9zaXRpb246ICdhYnNvbHV0ZScsXG4gICAgICBhZGFwdGl2ZTogZmFsc2UsXG4gICAgICByb3VuZE9mZnNldHM6IHJvdW5kT2Zmc2V0c1xuICAgIH0pKSk7XG4gIH1cblxuICBzdGF0ZS5hdHRyaWJ1dGVzLnBvcHBlciA9IE9iamVjdC5hc3NpZ24oe30sIHN0YXRlLmF0dHJpYnV0ZXMucG9wcGVyLCB7XG4gICAgJ2RhdGEtcG9wcGVyLXBsYWNlbWVudCc6IHN0YXRlLnBsYWNlbWVudFxuICB9KTtcbn0gLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGltcG9ydC9uby11bnVzZWQtbW9kdWxlc1xuXG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgbmFtZTogJ2NvbXB1dGVTdHlsZXMnLFxuICBlbmFibGVkOiB0cnVlLFxuICBwaGFzZTogJ2JlZm9yZVdyaXRlJyxcbiAgZm46IGNvbXB1dGVTdHlsZXMsXG4gIGRhdGE6IHt9XG59OyIsImltcG9ydCBnZXRXaW5kb3cgZnJvbSBcIi4uL2RvbS11dGlscy9nZXRXaW5kb3cuanNcIjsgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGltcG9ydC9uby11bnVzZWQtbW9kdWxlc1xuXG52YXIgcGFzc2l2ZSA9IHtcbiAgcGFzc2l2ZTogdHJ1ZVxufTtcblxuZnVuY3Rpb24gZWZmZWN0KF9yZWYpIHtcbiAgdmFyIHN0YXRlID0gX3JlZi5zdGF0ZSxcbiAgICAgIGluc3RhbmNlID0gX3JlZi5pbnN0YW5jZSxcbiAgICAgIG9wdGlvbnMgPSBfcmVmLm9wdGlvbnM7XG4gIHZhciBfb3B0aW9ucyRzY3JvbGwgPSBvcHRpb25zLnNjcm9sbCxcbiAgICAgIHNjcm9sbCA9IF9vcHRpb25zJHNjcm9sbCA9PT0gdm9pZCAwID8gdHJ1ZSA6IF9vcHRpb25zJHNjcm9sbCxcbiAgICAgIF9vcHRpb25zJHJlc2l6ZSA9IG9wdGlvbnMucmVzaXplLFxuICAgICAgcmVzaXplID0gX29wdGlvbnMkcmVzaXplID09PSB2b2lkIDAgPyB0cnVlIDogX29wdGlvbnMkcmVzaXplO1xuICB2YXIgd2luZG93ID0gZ2V0V2luZG93KHN0YXRlLmVsZW1lbnRzLnBvcHBlcik7XG4gIHZhciBzY3JvbGxQYXJlbnRzID0gW10uY29uY2F0KHN0YXRlLnNjcm9sbFBhcmVudHMucmVmZXJlbmNlLCBzdGF0ZS5zY3JvbGxQYXJlbnRzLnBvcHBlcik7XG5cbiAgaWYgKHNjcm9sbCkge1xuICAgIHNjcm9sbFBhcmVudHMuZm9yRWFjaChmdW5jdGlvbiAoc2Nyb2xsUGFyZW50KSB7XG4gICAgICBzY3JvbGxQYXJlbnQuYWRkRXZlbnRMaXN0ZW5lcignc2Nyb2xsJywgaW5zdGFuY2UudXBkYXRlLCBwYXNzaXZlKTtcbiAgICB9KTtcbiAgfVxuXG4gIGlmIChyZXNpemUpIHtcbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcigncmVzaXplJywgaW5zdGFuY2UudXBkYXRlLCBwYXNzaXZlKTtcbiAgfVxuXG4gIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgaWYgKHNjcm9sbCkge1xuICAgICAgc2Nyb2xsUGFyZW50cy5mb3JFYWNoKGZ1bmN0aW9uIChzY3JvbGxQYXJlbnQpIHtcbiAgICAgICAgc2Nyb2xsUGFyZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3Njcm9sbCcsIGluc3RhbmNlLnVwZGF0ZSwgcGFzc2l2ZSk7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBpZiAocmVzaXplKSB7XG4gICAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcigncmVzaXplJywgaW5zdGFuY2UudXBkYXRlLCBwYXNzaXZlKTtcbiAgICB9XG4gIH07XG59IC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBpbXBvcnQvbm8tdW51c2VkLW1vZHVsZXNcblxuXG5leHBvcnQgZGVmYXVsdCB7XG4gIG5hbWU6ICdldmVudExpc3RlbmVycycsXG4gIGVuYWJsZWQ6IHRydWUsXG4gIHBoYXNlOiAnd3JpdGUnLFxuICBmbjogZnVuY3Rpb24gZm4oKSB7fSxcbiAgZWZmZWN0OiBlZmZlY3QsXG4gIGRhdGE6IHt9XG59OyIsInZhciBoYXNoID0ge1xuICBsZWZ0OiAncmlnaHQnLFxuICByaWdodDogJ2xlZnQnLFxuICBib3R0b206ICd0b3AnLFxuICB0b3A6ICdib3R0b20nXG59O1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gZ2V0T3Bwb3NpdGVQbGFjZW1lbnQocGxhY2VtZW50KSB7XG4gIHJldHVybiBwbGFjZW1lbnQucmVwbGFjZSgvbGVmdHxyaWdodHxib3R0b218dG9wL2csIGZ1bmN0aW9uIChtYXRjaGVkKSB7XG4gICAgcmV0dXJuIGhhc2hbbWF0Y2hlZF07XG4gIH0pO1xufSIsInZhciBoYXNoID0ge1xuICBzdGFydDogJ2VuZCcsXG4gIGVuZDogJ3N0YXJ0J1xufTtcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGdldE9wcG9zaXRlVmFyaWF0aW9uUGxhY2VtZW50KHBsYWNlbWVudCkge1xuICByZXR1cm4gcGxhY2VtZW50LnJlcGxhY2UoL3N0YXJ0fGVuZC9nLCBmdW5jdGlvbiAobWF0Y2hlZCkge1xuICAgIHJldHVybiBoYXNoW21hdGNoZWRdO1xuICB9KTtcbn0iLCJpbXBvcnQgZ2V0V2luZG93IGZyb20gXCIuL2dldFdpbmRvdy5qc1wiO1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gZ2V0V2luZG93U2Nyb2xsKG5vZGUpIHtcbiAgdmFyIHdpbiA9IGdldFdpbmRvdyhub2RlKTtcbiAgdmFyIHNjcm9sbExlZnQgPSB3aW4ucGFnZVhPZmZzZXQ7XG4gIHZhciBzY3JvbGxUb3AgPSB3aW4ucGFnZVlPZmZzZXQ7XG4gIHJldHVybiB7XG4gICAgc2Nyb2xsTGVmdDogc2Nyb2xsTGVmdCxcbiAgICBzY3JvbGxUb3A6IHNjcm9sbFRvcFxuICB9O1xufSIsImltcG9ydCBnZXRCb3VuZGluZ0NsaWVudFJlY3QgZnJvbSBcIi4vZ2V0Qm91bmRpbmdDbGllbnRSZWN0LmpzXCI7XG5pbXBvcnQgZ2V0RG9jdW1lbnRFbGVtZW50IGZyb20gXCIuL2dldERvY3VtZW50RWxlbWVudC5qc1wiO1xuaW1wb3J0IGdldFdpbmRvd1Njcm9sbCBmcm9tIFwiLi9nZXRXaW5kb3dTY3JvbGwuanNcIjtcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGdldFdpbmRvd1Njcm9sbEJhclgoZWxlbWVudCkge1xuICAvLyBJZiA8aHRtbD4gaGFzIGEgQ1NTIHdpZHRoIGdyZWF0ZXIgdGhhbiB0aGUgdmlld3BvcnQsIHRoZW4gdGhpcyB3aWxsIGJlXG4gIC8vIGluY29ycmVjdCBmb3IgUlRMLlxuICAvLyBQb3BwZXIgMSBpcyBicm9rZW4gaW4gdGhpcyBjYXNlIGFuZCBuZXZlciBoYWQgYSBidWcgcmVwb3J0IHNvIGxldCdzIGFzc3VtZVxuICAvLyBpdCdzIG5vdCBhbiBpc3N1ZS4gSSBkb24ndCB0aGluayBhbnlvbmUgZXZlciBzcGVjaWZpZXMgd2lkdGggb24gPGh0bWw+XG4gIC8vIGFueXdheS5cbiAgLy8gQnJvd3NlcnMgd2hlcmUgdGhlIGxlZnQgc2Nyb2xsYmFyIGRvZXNuJ3QgY2F1c2UgYW4gaXNzdWUgcmVwb3J0IGAwYCBmb3JcbiAgLy8gdGhpcyAoZS5nLiBFZGdlIDIwMTksIElFMTEsIFNhZmFyaSlcbiAgcmV0dXJuIGdldEJvdW5kaW5nQ2xpZW50UmVjdChnZXREb2N1bWVudEVsZW1lbnQoZWxlbWVudCkpLmxlZnQgKyBnZXRXaW5kb3dTY3JvbGwoZWxlbWVudCkuc2Nyb2xsTGVmdDtcbn0iLCJpbXBvcnQgZ2V0V2luZG93IGZyb20gXCIuL2dldFdpbmRvdy5qc1wiO1xuaW1wb3J0IGdldERvY3VtZW50RWxlbWVudCBmcm9tIFwiLi9nZXREb2N1bWVudEVsZW1lbnQuanNcIjtcbmltcG9ydCBnZXRXaW5kb3dTY3JvbGxCYXJYIGZyb20gXCIuL2dldFdpbmRvd1Njcm9sbEJhclguanNcIjtcbmltcG9ydCBpc0xheW91dFZpZXdwb3J0IGZyb20gXCIuL2lzTGF5b3V0Vmlld3BvcnQuanNcIjtcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGdldFZpZXdwb3J0UmVjdChlbGVtZW50LCBzdHJhdGVneSkge1xuICB2YXIgd2luID0gZ2V0V2luZG93KGVsZW1lbnQpO1xuICB2YXIgaHRtbCA9IGdldERvY3VtZW50RWxlbWVudChlbGVtZW50KTtcbiAgdmFyIHZpc3VhbFZpZXdwb3J0ID0gd2luLnZpc3VhbFZpZXdwb3J0O1xuICB2YXIgd2lkdGggPSBodG1sLmNsaWVudFdpZHRoO1xuICB2YXIgaGVpZ2h0ID0gaHRtbC5jbGllbnRIZWlnaHQ7XG4gIHZhciB4ID0gMDtcbiAgdmFyIHkgPSAwO1xuXG4gIGlmICh2aXN1YWxWaWV3cG9ydCkge1xuICAgIHdpZHRoID0gdmlzdWFsVmlld3BvcnQud2lkdGg7XG4gICAgaGVpZ2h0ID0gdmlzdWFsVmlld3BvcnQuaGVpZ2h0O1xuICAgIHZhciBsYXlvdXRWaWV3cG9ydCA9IGlzTGF5b3V0Vmlld3BvcnQoKTtcblxuICAgIGlmIChsYXlvdXRWaWV3cG9ydCB8fCAhbGF5b3V0Vmlld3BvcnQgJiYgc3RyYXRlZ3kgPT09ICdmaXhlZCcpIHtcbiAgICAgIHggPSB2aXN1YWxWaWV3cG9ydC5vZmZzZXRMZWZ0O1xuICAgICAgeSA9IHZpc3VhbFZpZXdwb3J0Lm9mZnNldFRvcDtcbiAgICB9XG4gIH1cblxuICByZXR1cm4ge1xuICAgIHdpZHRoOiB3aWR0aCxcbiAgICBoZWlnaHQ6IGhlaWdodCxcbiAgICB4OiB4ICsgZ2V0V2luZG93U2Nyb2xsQmFyWChlbGVtZW50KSxcbiAgICB5OiB5XG4gIH07XG59IiwiaW1wb3J0IGdldERvY3VtZW50RWxlbWVudCBmcm9tIFwiLi9nZXREb2N1bWVudEVsZW1lbnQuanNcIjtcbmltcG9ydCBnZXRDb21wdXRlZFN0eWxlIGZyb20gXCIuL2dldENvbXB1dGVkU3R5bGUuanNcIjtcbmltcG9ydCBnZXRXaW5kb3dTY3JvbGxCYXJYIGZyb20gXCIuL2dldFdpbmRvd1Njcm9sbEJhclguanNcIjtcbmltcG9ydCBnZXRXaW5kb3dTY3JvbGwgZnJvbSBcIi4vZ2V0V2luZG93U2Nyb2xsLmpzXCI7XG5pbXBvcnQgeyBtYXggfSBmcm9tIFwiLi4vdXRpbHMvbWF0aC5qc1wiOyAvLyBHZXRzIHRoZSBlbnRpcmUgc2l6ZSBvZiB0aGUgc2Nyb2xsYWJsZSBkb2N1bWVudCBhcmVhLCBldmVuIGV4dGVuZGluZyBvdXRzaWRlXG4vLyBvZiB0aGUgYDxodG1sPmAgYW5kIGA8Ym9keT5gIHJlY3QgYm91bmRzIGlmIGhvcml6b250YWxseSBzY3JvbGxhYmxlXG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGdldERvY3VtZW50UmVjdChlbGVtZW50KSB7XG4gIHZhciBfZWxlbWVudCRvd25lckRvY3VtZW47XG5cbiAgdmFyIGh0bWwgPSBnZXREb2N1bWVudEVsZW1lbnQoZWxlbWVudCk7XG4gIHZhciB3aW5TY3JvbGwgPSBnZXRXaW5kb3dTY3JvbGwoZWxlbWVudCk7XG4gIHZhciBib2R5ID0gKF9lbGVtZW50JG93bmVyRG9jdW1lbiA9IGVsZW1lbnQub3duZXJEb2N1bWVudCkgPT0gbnVsbCA/IHZvaWQgMCA6IF9lbGVtZW50JG93bmVyRG9jdW1lbi5ib2R5O1xuICB2YXIgd2lkdGggPSBtYXgoaHRtbC5zY3JvbGxXaWR0aCwgaHRtbC5jbGllbnRXaWR0aCwgYm9keSA/IGJvZHkuc2Nyb2xsV2lkdGggOiAwLCBib2R5ID8gYm9keS5jbGllbnRXaWR0aCA6IDApO1xuICB2YXIgaGVpZ2h0ID0gbWF4KGh0bWwuc2Nyb2xsSGVpZ2h0LCBodG1sLmNsaWVudEhlaWdodCwgYm9keSA/IGJvZHkuc2Nyb2xsSGVpZ2h0IDogMCwgYm9keSA/IGJvZHkuY2xpZW50SGVpZ2h0IDogMCk7XG4gIHZhciB4ID0gLXdpblNjcm9sbC5zY3JvbGxMZWZ0ICsgZ2V0V2luZG93U2Nyb2xsQmFyWChlbGVtZW50KTtcbiAgdmFyIHkgPSAtd2luU2Nyb2xsLnNjcm9sbFRvcDtcblxuICBpZiAoZ2V0Q29tcHV0ZWRTdHlsZShib2R5IHx8IGh0bWwpLmRpcmVjdGlvbiA9PT0gJ3J0bCcpIHtcbiAgICB4ICs9IG1heChodG1sLmNsaWVudFdpZHRoLCBib2R5ID8gYm9keS5jbGllbnRXaWR0aCA6IDApIC0gd2lkdGg7XG4gIH1cblxuICByZXR1cm4ge1xuICAgIHdpZHRoOiB3aWR0aCxcbiAgICBoZWlnaHQ6IGhlaWdodCxcbiAgICB4OiB4LFxuICAgIHk6IHlcbiAgfTtcbn0iLCJpbXBvcnQgZ2V0Q29tcHV0ZWRTdHlsZSBmcm9tIFwiLi9nZXRDb21wdXRlZFN0eWxlLmpzXCI7XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBpc1Njcm9sbFBhcmVudChlbGVtZW50KSB7XG4gIC8vIEZpcmVmb3ggd2FudHMgdXMgdG8gY2hlY2sgYC14YCBhbmQgYC15YCB2YXJpYXRpb25zIGFzIHdlbGxcbiAgdmFyIF9nZXRDb21wdXRlZFN0eWxlID0gZ2V0Q29tcHV0ZWRTdHlsZShlbGVtZW50KSxcbiAgICAgIG92ZXJmbG93ID0gX2dldENvbXB1dGVkU3R5bGUub3ZlcmZsb3csXG4gICAgICBvdmVyZmxvd1ggPSBfZ2V0Q29tcHV0ZWRTdHlsZS5vdmVyZmxvd1gsXG4gICAgICBvdmVyZmxvd1kgPSBfZ2V0Q29tcHV0ZWRTdHlsZS5vdmVyZmxvd1k7XG5cbiAgcmV0dXJuIC9hdXRvfHNjcm9sbHxvdmVybGF5fGhpZGRlbi8udGVzdChvdmVyZmxvdyArIG92ZXJmbG93WSArIG92ZXJmbG93WCk7XG59IiwiaW1wb3J0IGdldFBhcmVudE5vZGUgZnJvbSBcIi4vZ2V0UGFyZW50Tm9kZS5qc1wiO1xuaW1wb3J0IGlzU2Nyb2xsUGFyZW50IGZyb20gXCIuL2lzU2Nyb2xsUGFyZW50LmpzXCI7XG5pbXBvcnQgZ2V0Tm9kZU5hbWUgZnJvbSBcIi4vZ2V0Tm9kZU5hbWUuanNcIjtcbmltcG9ydCB7IGlzSFRNTEVsZW1lbnQgfSBmcm9tIFwiLi9pbnN0YW5jZU9mLmpzXCI7XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBnZXRTY3JvbGxQYXJlbnQobm9kZSkge1xuICBpZiAoWydodG1sJywgJ2JvZHknLCAnI2RvY3VtZW50J10uaW5kZXhPZihnZXROb2RlTmFtZShub2RlKSkgPj0gMCkge1xuICAgIC8vICRGbG93Rml4TWVbaW5jb21wYXRpYmxlLXJldHVybl06IGFzc3VtZSBib2R5IGlzIGFsd2F5cyBhdmFpbGFibGVcbiAgICByZXR1cm4gbm9kZS5vd25lckRvY3VtZW50LmJvZHk7XG4gIH1cblxuICBpZiAoaXNIVE1MRWxlbWVudChub2RlKSAmJiBpc1Njcm9sbFBhcmVudChub2RlKSkge1xuICAgIHJldHVybiBub2RlO1xuICB9XG5cbiAgcmV0dXJuIGdldFNjcm9sbFBhcmVudChnZXRQYXJlbnROb2RlKG5vZGUpKTtcbn0iLCJpbXBvcnQgZ2V0U2Nyb2xsUGFyZW50IGZyb20gXCIuL2dldFNjcm9sbFBhcmVudC5qc1wiO1xuaW1wb3J0IGdldFBhcmVudE5vZGUgZnJvbSBcIi4vZ2V0UGFyZW50Tm9kZS5qc1wiO1xuaW1wb3J0IGdldFdpbmRvdyBmcm9tIFwiLi9nZXRXaW5kb3cuanNcIjtcbmltcG9ydCBpc1Njcm9sbFBhcmVudCBmcm9tIFwiLi9pc1Njcm9sbFBhcmVudC5qc1wiO1xuLypcbmdpdmVuIGEgRE9NIGVsZW1lbnQsIHJldHVybiB0aGUgbGlzdCBvZiBhbGwgc2Nyb2xsIHBhcmVudHMsIHVwIHRoZSBsaXN0IG9mIGFuY2Vzb3JzXG51bnRpbCB3ZSBnZXQgdG8gdGhlIHRvcCB3aW5kb3cgb2JqZWN0LiBUaGlzIGxpc3QgaXMgd2hhdCB3ZSBhdHRhY2ggc2Nyb2xsIGxpc3RlbmVyc1xudG8sIGJlY2F1c2UgaWYgYW55IG9mIHRoZXNlIHBhcmVudCBlbGVtZW50cyBzY3JvbGwsIHdlJ2xsIG5lZWQgdG8gcmUtY2FsY3VsYXRlIHRoZVxucmVmZXJlbmNlIGVsZW1lbnQncyBwb3NpdGlvbi5cbiovXG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGxpc3RTY3JvbGxQYXJlbnRzKGVsZW1lbnQsIGxpc3QpIHtcbiAgdmFyIF9lbGVtZW50JG93bmVyRG9jdW1lbjtcblxuICBpZiAobGlzdCA9PT0gdm9pZCAwKSB7XG4gICAgbGlzdCA9IFtdO1xuICB9XG5cbiAgdmFyIHNjcm9sbFBhcmVudCA9IGdldFNjcm9sbFBhcmVudChlbGVtZW50KTtcbiAgdmFyIGlzQm9keSA9IHNjcm9sbFBhcmVudCA9PT0gKChfZWxlbWVudCRvd25lckRvY3VtZW4gPSBlbGVtZW50Lm93bmVyRG9jdW1lbnQpID09IG51bGwgPyB2b2lkIDAgOiBfZWxlbWVudCRvd25lckRvY3VtZW4uYm9keSk7XG4gIHZhciB3aW4gPSBnZXRXaW5kb3coc2Nyb2xsUGFyZW50KTtcbiAgdmFyIHRhcmdldCA9IGlzQm9keSA/IFt3aW5dLmNvbmNhdCh3aW4udmlzdWFsVmlld3BvcnQgfHwgW10sIGlzU2Nyb2xsUGFyZW50KHNjcm9sbFBhcmVudCkgPyBzY3JvbGxQYXJlbnQgOiBbXSkgOiBzY3JvbGxQYXJlbnQ7XG4gIHZhciB1cGRhdGVkTGlzdCA9IGxpc3QuY29uY2F0KHRhcmdldCk7XG4gIHJldHVybiBpc0JvZHkgPyB1cGRhdGVkTGlzdCA6IC8vICRGbG93Rml4TWVbaW5jb21wYXRpYmxlLWNhbGxdOiBpc0JvZHkgdGVsbHMgdXMgdGFyZ2V0IHdpbGwgYmUgYW4gSFRNTEVsZW1lbnQgaGVyZVxuICB1cGRhdGVkTGlzdC5jb25jYXQobGlzdFNjcm9sbFBhcmVudHMoZ2V0UGFyZW50Tm9kZSh0YXJnZXQpKSk7XG59IiwiZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gcmVjdFRvQ2xpZW50UmVjdChyZWN0KSB7XG4gIHJldHVybiBPYmplY3QuYXNzaWduKHt9LCByZWN0LCB7XG4gICAgbGVmdDogcmVjdC54LFxuICAgIHRvcDogcmVjdC55LFxuICAgIHJpZ2h0OiByZWN0LnggKyByZWN0LndpZHRoLFxuICAgIGJvdHRvbTogcmVjdC55ICsgcmVjdC5oZWlnaHRcbiAgfSk7XG59IiwiaW1wb3J0IHsgdmlld3BvcnQgfSBmcm9tIFwiLi4vZW51bXMuanNcIjtcbmltcG9ydCBnZXRWaWV3cG9ydFJlY3QgZnJvbSBcIi4vZ2V0Vmlld3BvcnRSZWN0LmpzXCI7XG5pbXBvcnQgZ2V0RG9jdW1lbnRSZWN0IGZyb20gXCIuL2dldERvY3VtZW50UmVjdC5qc1wiO1xuaW1wb3J0IGxpc3RTY3JvbGxQYXJlbnRzIGZyb20gXCIuL2xpc3RTY3JvbGxQYXJlbnRzLmpzXCI7XG5pbXBvcnQgZ2V0T2Zmc2V0UGFyZW50IGZyb20gXCIuL2dldE9mZnNldFBhcmVudC5qc1wiO1xuaW1wb3J0IGdldERvY3VtZW50RWxlbWVudCBmcm9tIFwiLi9nZXREb2N1bWVudEVsZW1lbnQuanNcIjtcbmltcG9ydCBnZXRDb21wdXRlZFN0eWxlIGZyb20gXCIuL2dldENvbXB1dGVkU3R5bGUuanNcIjtcbmltcG9ydCB7IGlzRWxlbWVudCwgaXNIVE1MRWxlbWVudCB9IGZyb20gXCIuL2luc3RhbmNlT2YuanNcIjtcbmltcG9ydCBnZXRCb3VuZGluZ0NsaWVudFJlY3QgZnJvbSBcIi4vZ2V0Qm91bmRpbmdDbGllbnRSZWN0LmpzXCI7XG5pbXBvcnQgZ2V0UGFyZW50Tm9kZSBmcm9tIFwiLi9nZXRQYXJlbnROb2RlLmpzXCI7XG5pbXBvcnQgY29udGFpbnMgZnJvbSBcIi4vY29udGFpbnMuanNcIjtcbmltcG9ydCBnZXROb2RlTmFtZSBmcm9tIFwiLi9nZXROb2RlTmFtZS5qc1wiO1xuaW1wb3J0IHJlY3RUb0NsaWVudFJlY3QgZnJvbSBcIi4uL3V0aWxzL3JlY3RUb0NsaWVudFJlY3QuanNcIjtcbmltcG9ydCB7IG1heCwgbWluIH0gZnJvbSBcIi4uL3V0aWxzL21hdGguanNcIjtcblxuZnVuY3Rpb24gZ2V0SW5uZXJCb3VuZGluZ0NsaWVudFJlY3QoZWxlbWVudCwgc3RyYXRlZ3kpIHtcbiAgdmFyIHJlY3QgPSBnZXRCb3VuZGluZ0NsaWVudFJlY3QoZWxlbWVudCwgZmFsc2UsIHN0cmF0ZWd5ID09PSAnZml4ZWQnKTtcbiAgcmVjdC50b3AgPSByZWN0LnRvcCArIGVsZW1lbnQuY2xpZW50VG9wO1xuICByZWN0LmxlZnQgPSByZWN0LmxlZnQgKyBlbGVtZW50LmNsaWVudExlZnQ7XG4gIHJlY3QuYm90dG9tID0gcmVjdC50b3AgKyBlbGVtZW50LmNsaWVudEhlaWdodDtcbiAgcmVjdC5yaWdodCA9IHJlY3QubGVmdCArIGVsZW1lbnQuY2xpZW50V2lkdGg7XG4gIHJlY3Qud2lkdGggPSBlbGVtZW50LmNsaWVudFdpZHRoO1xuICByZWN0LmhlaWdodCA9IGVsZW1lbnQuY2xpZW50SGVpZ2h0O1xuICByZWN0LnggPSByZWN0LmxlZnQ7XG4gIHJlY3QueSA9IHJlY3QudG9wO1xuICByZXR1cm4gcmVjdDtcbn1cblxuZnVuY3Rpb24gZ2V0Q2xpZW50UmVjdEZyb21NaXhlZFR5cGUoZWxlbWVudCwgY2xpcHBpbmdQYXJlbnQsIHN0cmF0ZWd5KSB7XG4gIHJldHVybiBjbGlwcGluZ1BhcmVudCA9PT0gdmlld3BvcnQgPyByZWN0VG9DbGllbnRSZWN0KGdldFZpZXdwb3J0UmVjdChlbGVtZW50LCBzdHJhdGVneSkpIDogaXNFbGVtZW50KGNsaXBwaW5nUGFyZW50KSA/IGdldElubmVyQm91bmRpbmdDbGllbnRSZWN0KGNsaXBwaW5nUGFyZW50LCBzdHJhdGVneSkgOiByZWN0VG9DbGllbnRSZWN0KGdldERvY3VtZW50UmVjdChnZXREb2N1bWVudEVsZW1lbnQoZWxlbWVudCkpKTtcbn0gLy8gQSBcImNsaXBwaW5nIHBhcmVudFwiIGlzIGFuIG92ZXJmbG93YWJsZSBjb250YWluZXIgd2l0aCB0aGUgY2hhcmFjdGVyaXN0aWMgb2Zcbi8vIGNsaXBwaW5nIChvciBoaWRpbmcpIG92ZXJmbG93aW5nIGVsZW1lbnRzIHdpdGggYSBwb3NpdGlvbiBkaWZmZXJlbnQgZnJvbVxuLy8gYGluaXRpYWxgXG5cblxuZnVuY3Rpb24gZ2V0Q2xpcHBpbmdQYXJlbnRzKGVsZW1lbnQpIHtcbiAgdmFyIGNsaXBwaW5nUGFyZW50cyA9IGxpc3RTY3JvbGxQYXJlbnRzKGdldFBhcmVudE5vZGUoZWxlbWVudCkpO1xuICB2YXIgY2FuRXNjYXBlQ2xpcHBpbmcgPSBbJ2Fic29sdXRlJywgJ2ZpeGVkJ10uaW5kZXhPZihnZXRDb21wdXRlZFN0eWxlKGVsZW1lbnQpLnBvc2l0aW9uKSA+PSAwO1xuICB2YXIgY2xpcHBlckVsZW1lbnQgPSBjYW5Fc2NhcGVDbGlwcGluZyAmJiBpc0hUTUxFbGVtZW50KGVsZW1lbnQpID8gZ2V0T2Zmc2V0UGFyZW50KGVsZW1lbnQpIDogZWxlbWVudDtcblxuICBpZiAoIWlzRWxlbWVudChjbGlwcGVyRWxlbWVudCkpIHtcbiAgICByZXR1cm4gW107XG4gIH0gLy8gJEZsb3dGaXhNZVtpbmNvbXBhdGlibGUtcmV0dXJuXTogaHR0cHM6Ly9naXRodWIuY29tL2ZhY2Vib29rL2Zsb3cvaXNzdWVzLzE0MTRcblxuXG4gIHJldHVybiBjbGlwcGluZ1BhcmVudHMuZmlsdGVyKGZ1bmN0aW9uIChjbGlwcGluZ1BhcmVudCkge1xuICAgIHJldHVybiBpc0VsZW1lbnQoY2xpcHBpbmdQYXJlbnQpICYmIGNvbnRhaW5zKGNsaXBwaW5nUGFyZW50LCBjbGlwcGVyRWxlbWVudCkgJiYgZ2V0Tm9kZU5hbWUoY2xpcHBpbmdQYXJlbnQpICE9PSAnYm9keSc7XG4gIH0pO1xufSAvLyBHZXRzIHRoZSBtYXhpbXVtIGFyZWEgdGhhdCB0aGUgZWxlbWVudCBpcyB2aXNpYmxlIGluIGR1ZSB0byBhbnkgbnVtYmVyIG9mXG4vLyBjbGlwcGluZyBwYXJlbnRzXG5cblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gZ2V0Q2xpcHBpbmdSZWN0KGVsZW1lbnQsIGJvdW5kYXJ5LCByb290Qm91bmRhcnksIHN0cmF0ZWd5KSB7XG4gIHZhciBtYWluQ2xpcHBpbmdQYXJlbnRzID0gYm91bmRhcnkgPT09ICdjbGlwcGluZ1BhcmVudHMnID8gZ2V0Q2xpcHBpbmdQYXJlbnRzKGVsZW1lbnQpIDogW10uY29uY2F0KGJvdW5kYXJ5KTtcbiAgdmFyIGNsaXBwaW5nUGFyZW50cyA9IFtdLmNvbmNhdChtYWluQ2xpcHBpbmdQYXJlbnRzLCBbcm9vdEJvdW5kYXJ5XSk7XG4gIHZhciBmaXJzdENsaXBwaW5nUGFyZW50ID0gY2xpcHBpbmdQYXJlbnRzWzBdO1xuICB2YXIgY2xpcHBpbmdSZWN0ID0gY2xpcHBpbmdQYXJlbnRzLnJlZHVjZShmdW5jdGlvbiAoYWNjUmVjdCwgY2xpcHBpbmdQYXJlbnQpIHtcbiAgICB2YXIgcmVjdCA9IGdldENsaWVudFJlY3RGcm9tTWl4ZWRUeXBlKGVsZW1lbnQsIGNsaXBwaW5nUGFyZW50LCBzdHJhdGVneSk7XG4gICAgYWNjUmVjdC50b3AgPSBtYXgocmVjdC50b3AsIGFjY1JlY3QudG9wKTtcbiAgICBhY2NSZWN0LnJpZ2h0ID0gbWluKHJlY3QucmlnaHQsIGFjY1JlY3QucmlnaHQpO1xuICAgIGFjY1JlY3QuYm90dG9tID0gbWluKHJlY3QuYm90dG9tLCBhY2NSZWN0LmJvdHRvbSk7XG4gICAgYWNjUmVjdC5sZWZ0ID0gbWF4KHJlY3QubGVmdCwgYWNjUmVjdC5sZWZ0KTtcbiAgICByZXR1cm4gYWNjUmVjdDtcbiAgfSwgZ2V0Q2xpZW50UmVjdEZyb21NaXhlZFR5cGUoZWxlbWVudCwgZmlyc3RDbGlwcGluZ1BhcmVudCwgc3RyYXRlZ3kpKTtcbiAgY2xpcHBpbmdSZWN0LndpZHRoID0gY2xpcHBpbmdSZWN0LnJpZ2h0IC0gY2xpcHBpbmdSZWN0LmxlZnQ7XG4gIGNsaXBwaW5nUmVjdC5oZWlnaHQgPSBjbGlwcGluZ1JlY3QuYm90dG9tIC0gY2xpcHBpbmdSZWN0LnRvcDtcbiAgY2xpcHBpbmdSZWN0LnggPSBjbGlwcGluZ1JlY3QubGVmdDtcbiAgY2xpcHBpbmdSZWN0LnkgPSBjbGlwcGluZ1JlY3QudG9wO1xuICByZXR1cm4gY2xpcHBpbmdSZWN0O1xufSIsImltcG9ydCBnZXRCYXNlUGxhY2VtZW50IGZyb20gXCIuL2dldEJhc2VQbGFjZW1lbnQuanNcIjtcbmltcG9ydCBnZXRWYXJpYXRpb24gZnJvbSBcIi4vZ2V0VmFyaWF0aW9uLmpzXCI7XG5pbXBvcnQgZ2V0TWFpbkF4aXNGcm9tUGxhY2VtZW50IGZyb20gXCIuL2dldE1haW5BeGlzRnJvbVBsYWNlbWVudC5qc1wiO1xuaW1wb3J0IHsgdG9wLCByaWdodCwgYm90dG9tLCBsZWZ0LCBzdGFydCwgZW5kIH0gZnJvbSBcIi4uL2VudW1zLmpzXCI7XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBjb21wdXRlT2Zmc2V0cyhfcmVmKSB7XG4gIHZhciByZWZlcmVuY2UgPSBfcmVmLnJlZmVyZW5jZSxcbiAgICAgIGVsZW1lbnQgPSBfcmVmLmVsZW1lbnQsXG4gICAgICBwbGFjZW1lbnQgPSBfcmVmLnBsYWNlbWVudDtcbiAgdmFyIGJhc2VQbGFjZW1lbnQgPSBwbGFjZW1lbnQgPyBnZXRCYXNlUGxhY2VtZW50KHBsYWNlbWVudCkgOiBudWxsO1xuICB2YXIgdmFyaWF0aW9uID0gcGxhY2VtZW50ID8gZ2V0VmFyaWF0aW9uKHBsYWNlbWVudCkgOiBudWxsO1xuICB2YXIgY29tbW9uWCA9IHJlZmVyZW5jZS54ICsgcmVmZXJlbmNlLndpZHRoIC8gMiAtIGVsZW1lbnQud2lkdGggLyAyO1xuICB2YXIgY29tbW9uWSA9IHJlZmVyZW5jZS55ICsgcmVmZXJlbmNlLmhlaWdodCAvIDIgLSBlbGVtZW50LmhlaWdodCAvIDI7XG4gIHZhciBvZmZzZXRzO1xuXG4gIHN3aXRjaCAoYmFzZVBsYWNlbWVudCkge1xuICAgIGNhc2UgdG9wOlxuICAgICAgb2Zmc2V0cyA9IHtcbiAgICAgICAgeDogY29tbW9uWCxcbiAgICAgICAgeTogcmVmZXJlbmNlLnkgLSBlbGVtZW50LmhlaWdodFxuICAgICAgfTtcbiAgICAgIGJyZWFrO1xuXG4gICAgY2FzZSBib3R0b206XG4gICAgICBvZmZzZXRzID0ge1xuICAgICAgICB4OiBjb21tb25YLFxuICAgICAgICB5OiByZWZlcmVuY2UueSArIHJlZmVyZW5jZS5oZWlnaHRcbiAgICAgIH07XG4gICAgICBicmVhaztcblxuICAgIGNhc2UgcmlnaHQ6XG4gICAgICBvZmZzZXRzID0ge1xuICAgICAgICB4OiByZWZlcmVuY2UueCArIHJlZmVyZW5jZS53aWR0aCxcbiAgICAgICAgeTogY29tbW9uWVxuICAgICAgfTtcbiAgICAgIGJyZWFrO1xuXG4gICAgY2FzZSBsZWZ0OlxuICAgICAgb2Zmc2V0cyA9IHtcbiAgICAgICAgeDogcmVmZXJlbmNlLnggLSBlbGVtZW50LndpZHRoLFxuICAgICAgICB5OiBjb21tb25ZXG4gICAgICB9O1xuICAgICAgYnJlYWs7XG5cbiAgICBkZWZhdWx0OlxuICAgICAgb2Zmc2V0cyA9IHtcbiAgICAgICAgeDogcmVmZXJlbmNlLngsXG4gICAgICAgIHk6IHJlZmVyZW5jZS55XG4gICAgICB9O1xuICB9XG5cbiAgdmFyIG1haW5BeGlzID0gYmFzZVBsYWNlbWVudCA/IGdldE1haW5BeGlzRnJvbVBsYWNlbWVudChiYXNlUGxhY2VtZW50KSA6IG51bGw7XG5cbiAgaWYgKG1haW5BeGlzICE9IG51bGwpIHtcbiAgICB2YXIgbGVuID0gbWFpbkF4aXMgPT09ICd5JyA/ICdoZWlnaHQnIDogJ3dpZHRoJztcblxuICAgIHN3aXRjaCAodmFyaWF0aW9uKSB7XG4gICAgICBjYXNlIHN0YXJ0OlxuICAgICAgICBvZmZzZXRzW21haW5BeGlzXSA9IG9mZnNldHNbbWFpbkF4aXNdIC0gKHJlZmVyZW5jZVtsZW5dIC8gMiAtIGVsZW1lbnRbbGVuXSAvIDIpO1xuICAgICAgICBicmVhaztcblxuICAgICAgY2FzZSBlbmQ6XG4gICAgICAgIG9mZnNldHNbbWFpbkF4aXNdID0gb2Zmc2V0c1ttYWluQXhpc10gKyAocmVmZXJlbmNlW2xlbl0gLyAyIC0gZWxlbWVudFtsZW5dIC8gMik7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBkZWZhdWx0OlxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBvZmZzZXRzO1xufSIsImltcG9ydCBnZXRDbGlwcGluZ1JlY3QgZnJvbSBcIi4uL2RvbS11dGlscy9nZXRDbGlwcGluZ1JlY3QuanNcIjtcbmltcG9ydCBnZXREb2N1bWVudEVsZW1lbnQgZnJvbSBcIi4uL2RvbS11dGlscy9nZXREb2N1bWVudEVsZW1lbnQuanNcIjtcbmltcG9ydCBnZXRCb3VuZGluZ0NsaWVudFJlY3QgZnJvbSBcIi4uL2RvbS11dGlscy9nZXRCb3VuZGluZ0NsaWVudFJlY3QuanNcIjtcbmltcG9ydCBjb21wdXRlT2Zmc2V0cyBmcm9tIFwiLi9jb21wdXRlT2Zmc2V0cy5qc1wiO1xuaW1wb3J0IHJlY3RUb0NsaWVudFJlY3QgZnJvbSBcIi4vcmVjdFRvQ2xpZW50UmVjdC5qc1wiO1xuaW1wb3J0IHsgY2xpcHBpbmdQYXJlbnRzLCByZWZlcmVuY2UsIHBvcHBlciwgYm90dG9tLCB0b3AsIHJpZ2h0LCBiYXNlUGxhY2VtZW50cywgdmlld3BvcnQgfSBmcm9tIFwiLi4vZW51bXMuanNcIjtcbmltcG9ydCB7IGlzRWxlbWVudCB9IGZyb20gXCIuLi9kb20tdXRpbHMvaW5zdGFuY2VPZi5qc1wiO1xuaW1wb3J0IG1lcmdlUGFkZGluZ09iamVjdCBmcm9tIFwiLi9tZXJnZVBhZGRpbmdPYmplY3QuanNcIjtcbmltcG9ydCBleHBhbmRUb0hhc2hNYXAgZnJvbSBcIi4vZXhwYW5kVG9IYXNoTWFwLmpzXCI7IC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBpbXBvcnQvbm8tdW51c2VkLW1vZHVsZXNcblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gZGV0ZWN0T3ZlcmZsb3coc3RhdGUsIG9wdGlvbnMpIHtcbiAgaWYgKG9wdGlvbnMgPT09IHZvaWQgMCkge1xuICAgIG9wdGlvbnMgPSB7fTtcbiAgfVxuXG4gIHZhciBfb3B0aW9ucyA9IG9wdGlvbnMsXG4gICAgICBfb3B0aW9ucyRwbGFjZW1lbnQgPSBfb3B0aW9ucy5wbGFjZW1lbnQsXG4gICAgICBwbGFjZW1lbnQgPSBfb3B0aW9ucyRwbGFjZW1lbnQgPT09IHZvaWQgMCA/IHN0YXRlLnBsYWNlbWVudCA6IF9vcHRpb25zJHBsYWNlbWVudCxcbiAgICAgIF9vcHRpb25zJHN0cmF0ZWd5ID0gX29wdGlvbnMuc3RyYXRlZ3ksXG4gICAgICBzdHJhdGVneSA9IF9vcHRpb25zJHN0cmF0ZWd5ID09PSB2b2lkIDAgPyBzdGF0ZS5zdHJhdGVneSA6IF9vcHRpb25zJHN0cmF0ZWd5LFxuICAgICAgX29wdGlvbnMkYm91bmRhcnkgPSBfb3B0aW9ucy5ib3VuZGFyeSxcbiAgICAgIGJvdW5kYXJ5ID0gX29wdGlvbnMkYm91bmRhcnkgPT09IHZvaWQgMCA/IGNsaXBwaW5nUGFyZW50cyA6IF9vcHRpb25zJGJvdW5kYXJ5LFxuICAgICAgX29wdGlvbnMkcm9vdEJvdW5kYXJ5ID0gX29wdGlvbnMucm9vdEJvdW5kYXJ5LFxuICAgICAgcm9vdEJvdW5kYXJ5ID0gX29wdGlvbnMkcm9vdEJvdW5kYXJ5ID09PSB2b2lkIDAgPyB2aWV3cG9ydCA6IF9vcHRpb25zJHJvb3RCb3VuZGFyeSxcbiAgICAgIF9vcHRpb25zJGVsZW1lbnRDb250ZSA9IF9vcHRpb25zLmVsZW1lbnRDb250ZXh0LFxuICAgICAgZWxlbWVudENvbnRleHQgPSBfb3B0aW9ucyRlbGVtZW50Q29udGUgPT09IHZvaWQgMCA/IHBvcHBlciA6IF9vcHRpb25zJGVsZW1lbnRDb250ZSxcbiAgICAgIF9vcHRpb25zJGFsdEJvdW5kYXJ5ID0gX29wdGlvbnMuYWx0Qm91bmRhcnksXG4gICAgICBhbHRCb3VuZGFyeSA9IF9vcHRpb25zJGFsdEJvdW5kYXJ5ID09PSB2b2lkIDAgPyBmYWxzZSA6IF9vcHRpb25zJGFsdEJvdW5kYXJ5LFxuICAgICAgX29wdGlvbnMkcGFkZGluZyA9IF9vcHRpb25zLnBhZGRpbmcsXG4gICAgICBwYWRkaW5nID0gX29wdGlvbnMkcGFkZGluZyA9PT0gdm9pZCAwID8gMCA6IF9vcHRpb25zJHBhZGRpbmc7XG4gIHZhciBwYWRkaW5nT2JqZWN0ID0gbWVyZ2VQYWRkaW5nT2JqZWN0KHR5cGVvZiBwYWRkaW5nICE9PSAnbnVtYmVyJyA/IHBhZGRpbmcgOiBleHBhbmRUb0hhc2hNYXAocGFkZGluZywgYmFzZVBsYWNlbWVudHMpKTtcbiAgdmFyIGFsdENvbnRleHQgPSBlbGVtZW50Q29udGV4dCA9PT0gcG9wcGVyID8gcmVmZXJlbmNlIDogcG9wcGVyO1xuICB2YXIgcG9wcGVyUmVjdCA9IHN0YXRlLnJlY3RzLnBvcHBlcjtcbiAgdmFyIGVsZW1lbnQgPSBzdGF0ZS5lbGVtZW50c1thbHRCb3VuZGFyeSA/IGFsdENvbnRleHQgOiBlbGVtZW50Q29udGV4dF07XG4gIHZhciBjbGlwcGluZ0NsaWVudFJlY3QgPSBnZXRDbGlwcGluZ1JlY3QoaXNFbGVtZW50KGVsZW1lbnQpID8gZWxlbWVudCA6IGVsZW1lbnQuY29udGV4dEVsZW1lbnQgfHwgZ2V0RG9jdW1lbnRFbGVtZW50KHN0YXRlLmVsZW1lbnRzLnBvcHBlciksIGJvdW5kYXJ5LCByb290Qm91bmRhcnksIHN0cmF0ZWd5KTtcbiAgdmFyIHJlZmVyZW5jZUNsaWVudFJlY3QgPSBnZXRCb3VuZGluZ0NsaWVudFJlY3Qoc3RhdGUuZWxlbWVudHMucmVmZXJlbmNlKTtcbiAgdmFyIHBvcHBlck9mZnNldHMgPSBjb21wdXRlT2Zmc2V0cyh7XG4gICAgcmVmZXJlbmNlOiByZWZlcmVuY2VDbGllbnRSZWN0LFxuICAgIGVsZW1lbnQ6IHBvcHBlclJlY3QsXG4gICAgc3RyYXRlZ3k6ICdhYnNvbHV0ZScsXG4gICAgcGxhY2VtZW50OiBwbGFjZW1lbnRcbiAgfSk7XG4gIHZhciBwb3BwZXJDbGllbnRSZWN0ID0gcmVjdFRvQ2xpZW50UmVjdChPYmplY3QuYXNzaWduKHt9LCBwb3BwZXJSZWN0LCBwb3BwZXJPZmZzZXRzKSk7XG4gIHZhciBlbGVtZW50Q2xpZW50UmVjdCA9IGVsZW1lbnRDb250ZXh0ID09PSBwb3BwZXIgPyBwb3BwZXJDbGllbnRSZWN0IDogcmVmZXJlbmNlQ2xpZW50UmVjdDsgLy8gcG9zaXRpdmUgPSBvdmVyZmxvd2luZyB0aGUgY2xpcHBpbmcgcmVjdFxuICAvLyAwIG9yIG5lZ2F0aXZlID0gd2l0aGluIHRoZSBjbGlwcGluZyByZWN0XG5cbiAgdmFyIG92ZXJmbG93T2Zmc2V0cyA9IHtcbiAgICB0b3A6IGNsaXBwaW5nQ2xpZW50UmVjdC50b3AgLSBlbGVtZW50Q2xpZW50UmVjdC50b3AgKyBwYWRkaW5nT2JqZWN0LnRvcCxcbiAgICBib3R0b206IGVsZW1lbnRDbGllbnRSZWN0LmJvdHRvbSAtIGNsaXBwaW5nQ2xpZW50UmVjdC5ib3R0b20gKyBwYWRkaW5nT2JqZWN0LmJvdHRvbSxcbiAgICBsZWZ0OiBjbGlwcGluZ0NsaWVudFJlY3QubGVmdCAtIGVsZW1lbnRDbGllbnRSZWN0LmxlZnQgKyBwYWRkaW5nT2JqZWN0LmxlZnQsXG4gICAgcmlnaHQ6IGVsZW1lbnRDbGllbnRSZWN0LnJpZ2h0IC0gY2xpcHBpbmdDbGllbnRSZWN0LnJpZ2h0ICsgcGFkZGluZ09iamVjdC5yaWdodFxuICB9O1xuICB2YXIgb2Zmc2V0RGF0YSA9IHN0YXRlLm1vZGlmaWVyc0RhdGEub2Zmc2V0OyAvLyBPZmZzZXRzIGNhbiBiZSBhcHBsaWVkIG9ubHkgdG8gdGhlIHBvcHBlciBlbGVtZW50XG5cbiAgaWYgKGVsZW1lbnRDb250ZXh0ID09PSBwb3BwZXIgJiYgb2Zmc2V0RGF0YSkge1xuICAgIHZhciBvZmZzZXQgPSBvZmZzZXREYXRhW3BsYWNlbWVudF07XG4gICAgT2JqZWN0LmtleXMob3ZlcmZsb3dPZmZzZXRzKS5mb3JFYWNoKGZ1bmN0aW9uIChrZXkpIHtcbiAgICAgIHZhciBtdWx0aXBseSA9IFtyaWdodCwgYm90dG9tXS5pbmRleE9mKGtleSkgPj0gMCA/IDEgOiAtMTtcbiAgICAgIHZhciBheGlzID0gW3RvcCwgYm90dG9tXS5pbmRleE9mKGtleSkgPj0gMCA/ICd5JyA6ICd4JztcbiAgICAgIG92ZXJmbG93T2Zmc2V0c1trZXldICs9IG9mZnNldFtheGlzXSAqIG11bHRpcGx5O1xuICAgIH0pO1xuICB9XG5cbiAgcmV0dXJuIG92ZXJmbG93T2Zmc2V0cztcbn0iLCJpbXBvcnQgZ2V0VmFyaWF0aW9uIGZyb20gXCIuL2dldFZhcmlhdGlvbi5qc1wiO1xuaW1wb3J0IHsgdmFyaWF0aW9uUGxhY2VtZW50cywgYmFzZVBsYWNlbWVudHMsIHBsYWNlbWVudHMgYXMgYWxsUGxhY2VtZW50cyB9IGZyb20gXCIuLi9lbnVtcy5qc1wiO1xuaW1wb3J0IGRldGVjdE92ZXJmbG93IGZyb20gXCIuL2RldGVjdE92ZXJmbG93LmpzXCI7XG5pbXBvcnQgZ2V0QmFzZVBsYWNlbWVudCBmcm9tIFwiLi9nZXRCYXNlUGxhY2VtZW50LmpzXCI7XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBjb21wdXRlQXV0b1BsYWNlbWVudChzdGF0ZSwgb3B0aW9ucykge1xuICBpZiAob3B0aW9ucyA9PT0gdm9pZCAwKSB7XG4gICAgb3B0aW9ucyA9IHt9O1xuICB9XG5cbiAgdmFyIF9vcHRpb25zID0gb3B0aW9ucyxcbiAgICAgIHBsYWNlbWVudCA9IF9vcHRpb25zLnBsYWNlbWVudCxcbiAgICAgIGJvdW5kYXJ5ID0gX29wdGlvbnMuYm91bmRhcnksXG4gICAgICByb290Qm91bmRhcnkgPSBfb3B0aW9ucy5yb290Qm91bmRhcnksXG4gICAgICBwYWRkaW5nID0gX29wdGlvbnMucGFkZGluZyxcbiAgICAgIGZsaXBWYXJpYXRpb25zID0gX29wdGlvbnMuZmxpcFZhcmlhdGlvbnMsXG4gICAgICBfb3B0aW9ucyRhbGxvd2VkQXV0b1AgPSBfb3B0aW9ucy5hbGxvd2VkQXV0b1BsYWNlbWVudHMsXG4gICAgICBhbGxvd2VkQXV0b1BsYWNlbWVudHMgPSBfb3B0aW9ucyRhbGxvd2VkQXV0b1AgPT09IHZvaWQgMCA/IGFsbFBsYWNlbWVudHMgOiBfb3B0aW9ucyRhbGxvd2VkQXV0b1A7XG4gIHZhciB2YXJpYXRpb24gPSBnZXRWYXJpYXRpb24ocGxhY2VtZW50KTtcbiAgdmFyIHBsYWNlbWVudHMgPSB2YXJpYXRpb24gPyBmbGlwVmFyaWF0aW9ucyA/IHZhcmlhdGlvblBsYWNlbWVudHMgOiB2YXJpYXRpb25QbGFjZW1lbnRzLmZpbHRlcihmdW5jdGlvbiAocGxhY2VtZW50KSB7XG4gICAgcmV0dXJuIGdldFZhcmlhdGlvbihwbGFjZW1lbnQpID09PSB2YXJpYXRpb247XG4gIH0pIDogYmFzZVBsYWNlbWVudHM7XG4gIHZhciBhbGxvd2VkUGxhY2VtZW50cyA9IHBsYWNlbWVudHMuZmlsdGVyKGZ1bmN0aW9uIChwbGFjZW1lbnQpIHtcbiAgICByZXR1cm4gYWxsb3dlZEF1dG9QbGFjZW1lbnRzLmluZGV4T2YocGxhY2VtZW50KSA+PSAwO1xuICB9KTtcblxuICBpZiAoYWxsb3dlZFBsYWNlbWVudHMubGVuZ3RoID09PSAwKSB7XG4gICAgYWxsb3dlZFBsYWNlbWVudHMgPSBwbGFjZW1lbnRzO1xuICB9IC8vICRGbG93Rml4TWVbaW5jb21wYXRpYmxlLXR5cGVdOiBGbG93IHNlZW1zIHRvIGhhdmUgcHJvYmxlbXMgd2l0aCB0d28gYXJyYXkgdW5pb25zLi4uXG5cblxuICB2YXIgb3ZlcmZsb3dzID0gYWxsb3dlZFBsYWNlbWVudHMucmVkdWNlKGZ1bmN0aW9uIChhY2MsIHBsYWNlbWVudCkge1xuICAgIGFjY1twbGFjZW1lbnRdID0gZGV0ZWN0T3ZlcmZsb3coc3RhdGUsIHtcbiAgICAgIHBsYWNlbWVudDogcGxhY2VtZW50LFxuICAgICAgYm91bmRhcnk6IGJvdW5kYXJ5LFxuICAgICAgcm9vdEJvdW5kYXJ5OiByb290Qm91bmRhcnksXG4gICAgICBwYWRkaW5nOiBwYWRkaW5nXG4gICAgfSlbZ2V0QmFzZVBsYWNlbWVudChwbGFjZW1lbnQpXTtcbiAgICByZXR1cm4gYWNjO1xuICB9LCB7fSk7XG4gIHJldHVybiBPYmplY3Qua2V5cyhvdmVyZmxvd3MpLnNvcnQoZnVuY3Rpb24gKGEsIGIpIHtcbiAgICByZXR1cm4gb3ZlcmZsb3dzW2FdIC0gb3ZlcmZsb3dzW2JdO1xuICB9KTtcbn0iLCJpbXBvcnQgZ2V0T3Bwb3NpdGVQbGFjZW1lbnQgZnJvbSBcIi4uL3V0aWxzL2dldE9wcG9zaXRlUGxhY2VtZW50LmpzXCI7XG5pbXBvcnQgZ2V0QmFzZVBsYWNlbWVudCBmcm9tIFwiLi4vdXRpbHMvZ2V0QmFzZVBsYWNlbWVudC5qc1wiO1xuaW1wb3J0IGdldE9wcG9zaXRlVmFyaWF0aW9uUGxhY2VtZW50IGZyb20gXCIuLi91dGlscy9nZXRPcHBvc2l0ZVZhcmlhdGlvblBsYWNlbWVudC5qc1wiO1xuaW1wb3J0IGRldGVjdE92ZXJmbG93IGZyb20gXCIuLi91dGlscy9kZXRlY3RPdmVyZmxvdy5qc1wiO1xuaW1wb3J0IGNvbXB1dGVBdXRvUGxhY2VtZW50IGZyb20gXCIuLi91dGlscy9jb21wdXRlQXV0b1BsYWNlbWVudC5qc1wiO1xuaW1wb3J0IHsgYm90dG9tLCB0b3AsIHN0YXJ0LCByaWdodCwgbGVmdCwgYXV0byB9IGZyb20gXCIuLi9lbnVtcy5qc1wiO1xuaW1wb3J0IGdldFZhcmlhdGlvbiBmcm9tIFwiLi4vdXRpbHMvZ2V0VmFyaWF0aW9uLmpzXCI7IC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBpbXBvcnQvbm8tdW51c2VkLW1vZHVsZXNcblxuZnVuY3Rpb24gZ2V0RXhwYW5kZWRGYWxsYmFja1BsYWNlbWVudHMocGxhY2VtZW50KSB7XG4gIGlmIChnZXRCYXNlUGxhY2VtZW50KHBsYWNlbWVudCkgPT09IGF1dG8pIHtcbiAgICByZXR1cm4gW107XG4gIH1cblxuICB2YXIgb3Bwb3NpdGVQbGFjZW1lbnQgPSBnZXRPcHBvc2l0ZVBsYWNlbWVudChwbGFjZW1lbnQpO1xuICByZXR1cm4gW2dldE9wcG9zaXRlVmFyaWF0aW9uUGxhY2VtZW50KHBsYWNlbWVudCksIG9wcG9zaXRlUGxhY2VtZW50LCBnZXRPcHBvc2l0ZVZhcmlhdGlvblBsYWNlbWVudChvcHBvc2l0ZVBsYWNlbWVudCldO1xufVxuXG5mdW5jdGlvbiBmbGlwKF9yZWYpIHtcbiAgdmFyIHN0YXRlID0gX3JlZi5zdGF0ZSxcbiAgICAgIG9wdGlvbnMgPSBfcmVmLm9wdGlvbnMsXG4gICAgICBuYW1lID0gX3JlZi5uYW1lO1xuXG4gIGlmIChzdGF0ZS5tb2RpZmllcnNEYXRhW25hbWVdLl9za2lwKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgdmFyIF9vcHRpb25zJG1haW5BeGlzID0gb3B0aW9ucy5tYWluQXhpcyxcbiAgICAgIGNoZWNrTWFpbkF4aXMgPSBfb3B0aW9ucyRtYWluQXhpcyA9PT0gdm9pZCAwID8gdHJ1ZSA6IF9vcHRpb25zJG1haW5BeGlzLFxuICAgICAgX29wdGlvbnMkYWx0QXhpcyA9IG9wdGlvbnMuYWx0QXhpcyxcbiAgICAgIGNoZWNrQWx0QXhpcyA9IF9vcHRpb25zJGFsdEF4aXMgPT09IHZvaWQgMCA/IHRydWUgOiBfb3B0aW9ucyRhbHRBeGlzLFxuICAgICAgc3BlY2lmaWVkRmFsbGJhY2tQbGFjZW1lbnRzID0gb3B0aW9ucy5mYWxsYmFja1BsYWNlbWVudHMsXG4gICAgICBwYWRkaW5nID0gb3B0aW9ucy5wYWRkaW5nLFxuICAgICAgYm91bmRhcnkgPSBvcHRpb25zLmJvdW5kYXJ5LFxuICAgICAgcm9vdEJvdW5kYXJ5ID0gb3B0aW9ucy5yb290Qm91bmRhcnksXG4gICAgICBhbHRCb3VuZGFyeSA9IG9wdGlvbnMuYWx0Qm91bmRhcnksXG4gICAgICBfb3B0aW9ucyRmbGlwVmFyaWF0aW8gPSBvcHRpb25zLmZsaXBWYXJpYXRpb25zLFxuICAgICAgZmxpcFZhcmlhdGlvbnMgPSBfb3B0aW9ucyRmbGlwVmFyaWF0aW8gPT09IHZvaWQgMCA/IHRydWUgOiBfb3B0aW9ucyRmbGlwVmFyaWF0aW8sXG4gICAgICBhbGxvd2VkQXV0b1BsYWNlbWVudHMgPSBvcHRpb25zLmFsbG93ZWRBdXRvUGxhY2VtZW50cztcbiAgdmFyIHByZWZlcnJlZFBsYWNlbWVudCA9IHN0YXRlLm9wdGlvbnMucGxhY2VtZW50O1xuICB2YXIgYmFzZVBsYWNlbWVudCA9IGdldEJhc2VQbGFjZW1lbnQocHJlZmVycmVkUGxhY2VtZW50KTtcbiAgdmFyIGlzQmFzZVBsYWNlbWVudCA9IGJhc2VQbGFjZW1lbnQgPT09IHByZWZlcnJlZFBsYWNlbWVudDtcbiAgdmFyIGZhbGxiYWNrUGxhY2VtZW50cyA9IHNwZWNpZmllZEZhbGxiYWNrUGxhY2VtZW50cyB8fCAoaXNCYXNlUGxhY2VtZW50IHx8ICFmbGlwVmFyaWF0aW9ucyA/IFtnZXRPcHBvc2l0ZVBsYWNlbWVudChwcmVmZXJyZWRQbGFjZW1lbnQpXSA6IGdldEV4cGFuZGVkRmFsbGJhY2tQbGFjZW1lbnRzKHByZWZlcnJlZFBsYWNlbWVudCkpO1xuICB2YXIgcGxhY2VtZW50cyA9IFtwcmVmZXJyZWRQbGFjZW1lbnRdLmNvbmNhdChmYWxsYmFja1BsYWNlbWVudHMpLnJlZHVjZShmdW5jdGlvbiAoYWNjLCBwbGFjZW1lbnQpIHtcbiAgICByZXR1cm4gYWNjLmNvbmNhdChnZXRCYXNlUGxhY2VtZW50KHBsYWNlbWVudCkgPT09IGF1dG8gPyBjb21wdXRlQXV0b1BsYWNlbWVudChzdGF0ZSwge1xuICAgICAgcGxhY2VtZW50OiBwbGFjZW1lbnQsXG4gICAgICBib3VuZGFyeTogYm91bmRhcnksXG4gICAgICByb290Qm91bmRhcnk6IHJvb3RCb3VuZGFyeSxcbiAgICAgIHBhZGRpbmc6IHBhZGRpbmcsXG4gICAgICBmbGlwVmFyaWF0aW9uczogZmxpcFZhcmlhdGlvbnMsXG4gICAgICBhbGxvd2VkQXV0b1BsYWNlbWVudHM6IGFsbG93ZWRBdXRvUGxhY2VtZW50c1xuICAgIH0pIDogcGxhY2VtZW50KTtcbiAgfSwgW10pO1xuICB2YXIgcmVmZXJlbmNlUmVjdCA9IHN0YXRlLnJlY3RzLnJlZmVyZW5jZTtcbiAgdmFyIHBvcHBlclJlY3QgPSBzdGF0ZS5yZWN0cy5wb3BwZXI7XG4gIHZhciBjaGVja3NNYXAgPSBuZXcgTWFwKCk7XG4gIHZhciBtYWtlRmFsbGJhY2tDaGVja3MgPSB0cnVlO1xuICB2YXIgZmlyc3RGaXR0aW5nUGxhY2VtZW50ID0gcGxhY2VtZW50c1swXTtcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IHBsYWNlbWVudHMubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgcGxhY2VtZW50ID0gcGxhY2VtZW50c1tpXTtcblxuICAgIHZhciBfYmFzZVBsYWNlbWVudCA9IGdldEJhc2VQbGFjZW1lbnQocGxhY2VtZW50KTtcblxuICAgIHZhciBpc1N0YXJ0VmFyaWF0aW9uID0gZ2V0VmFyaWF0aW9uKHBsYWNlbWVudCkgPT09IHN0YXJ0O1xuICAgIHZhciBpc1ZlcnRpY2FsID0gW3RvcCwgYm90dG9tXS5pbmRleE9mKF9iYXNlUGxhY2VtZW50KSA+PSAwO1xuICAgIHZhciBsZW4gPSBpc1ZlcnRpY2FsID8gJ3dpZHRoJyA6ICdoZWlnaHQnO1xuICAgIHZhciBvdmVyZmxvdyA9IGRldGVjdE92ZXJmbG93KHN0YXRlLCB7XG4gICAgICBwbGFjZW1lbnQ6IHBsYWNlbWVudCxcbiAgICAgIGJvdW5kYXJ5OiBib3VuZGFyeSxcbiAgICAgIHJvb3RCb3VuZGFyeTogcm9vdEJvdW5kYXJ5LFxuICAgICAgYWx0Qm91bmRhcnk6IGFsdEJvdW5kYXJ5LFxuICAgICAgcGFkZGluZzogcGFkZGluZ1xuICAgIH0pO1xuICAgIHZhciBtYWluVmFyaWF0aW9uU2lkZSA9IGlzVmVydGljYWwgPyBpc1N0YXJ0VmFyaWF0aW9uID8gcmlnaHQgOiBsZWZ0IDogaXNTdGFydFZhcmlhdGlvbiA/IGJvdHRvbSA6IHRvcDtcblxuICAgIGlmIChyZWZlcmVuY2VSZWN0W2xlbl0gPiBwb3BwZXJSZWN0W2xlbl0pIHtcbiAgICAgIG1haW5WYXJpYXRpb25TaWRlID0gZ2V0T3Bwb3NpdGVQbGFjZW1lbnQobWFpblZhcmlhdGlvblNpZGUpO1xuICAgIH1cblxuICAgIHZhciBhbHRWYXJpYXRpb25TaWRlID0gZ2V0T3Bwb3NpdGVQbGFjZW1lbnQobWFpblZhcmlhdGlvblNpZGUpO1xuICAgIHZhciBjaGVja3MgPSBbXTtcblxuICAgIGlmIChjaGVja01haW5BeGlzKSB7XG4gICAgICBjaGVja3MucHVzaChvdmVyZmxvd1tfYmFzZVBsYWNlbWVudF0gPD0gMCk7XG4gICAgfVxuXG4gICAgaWYgKGNoZWNrQWx0QXhpcykge1xuICAgICAgY2hlY2tzLnB1c2gob3ZlcmZsb3dbbWFpblZhcmlhdGlvblNpZGVdIDw9IDAsIG92ZXJmbG93W2FsdFZhcmlhdGlvblNpZGVdIDw9IDApO1xuICAgIH1cblxuICAgIGlmIChjaGVja3MuZXZlcnkoZnVuY3Rpb24gKGNoZWNrKSB7XG4gICAgICByZXR1cm4gY2hlY2s7XG4gICAgfSkpIHtcbiAgICAgIGZpcnN0Rml0dGluZ1BsYWNlbWVudCA9IHBsYWNlbWVudDtcbiAgICAgIG1ha2VGYWxsYmFja0NoZWNrcyA9IGZhbHNlO1xuICAgICAgYnJlYWs7XG4gICAgfVxuXG4gICAgY2hlY2tzTWFwLnNldChwbGFjZW1lbnQsIGNoZWNrcyk7XG4gIH1cblxuICBpZiAobWFrZUZhbGxiYWNrQ2hlY2tzKSB7XG4gICAgLy8gYDJgIG1heSBiZSBkZXNpcmVkIGluIHNvbWUgY2FzZXMg4oCTIHJlc2VhcmNoIGxhdGVyXG4gICAgdmFyIG51bWJlck9mQ2hlY2tzID0gZmxpcFZhcmlhdGlvbnMgPyAzIDogMTtcblxuICAgIHZhciBfbG9vcCA9IGZ1bmN0aW9uIF9sb29wKF9pKSB7XG4gICAgICB2YXIgZml0dGluZ1BsYWNlbWVudCA9IHBsYWNlbWVudHMuZmluZChmdW5jdGlvbiAocGxhY2VtZW50KSB7XG4gICAgICAgIHZhciBjaGVja3MgPSBjaGVja3NNYXAuZ2V0KHBsYWNlbWVudCk7XG5cbiAgICAgICAgaWYgKGNoZWNrcykge1xuICAgICAgICAgIHJldHVybiBjaGVja3Muc2xpY2UoMCwgX2kpLmV2ZXJ5KGZ1bmN0aW9uIChjaGVjaykge1xuICAgICAgICAgICAgcmV0dXJuIGNoZWNrO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgaWYgKGZpdHRpbmdQbGFjZW1lbnQpIHtcbiAgICAgICAgZmlyc3RGaXR0aW5nUGxhY2VtZW50ID0gZml0dGluZ1BsYWNlbWVudDtcbiAgICAgICAgcmV0dXJuIFwiYnJlYWtcIjtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgZm9yICh2YXIgX2kgPSBudW1iZXJPZkNoZWNrczsgX2kgPiAwOyBfaS0tKSB7XG4gICAgICB2YXIgX3JldCA9IF9sb29wKF9pKTtcblxuICAgICAgaWYgKF9yZXQgPT09IFwiYnJlYWtcIikgYnJlYWs7XG4gICAgfVxuICB9XG5cbiAgaWYgKHN0YXRlLnBsYWNlbWVudCAhPT0gZmlyc3RGaXR0aW5nUGxhY2VtZW50KSB7XG4gICAgc3RhdGUubW9kaWZpZXJzRGF0YVtuYW1lXS5fc2tpcCA9IHRydWU7XG4gICAgc3RhdGUucGxhY2VtZW50ID0gZmlyc3RGaXR0aW5nUGxhY2VtZW50O1xuICAgIHN0YXRlLnJlc2V0ID0gdHJ1ZTtcbiAgfVxufSAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgaW1wb3J0L25vLXVudXNlZC1tb2R1bGVzXG5cblxuZXhwb3J0IGRlZmF1bHQge1xuICBuYW1lOiAnZmxpcCcsXG4gIGVuYWJsZWQ6IHRydWUsXG4gIHBoYXNlOiAnbWFpbicsXG4gIGZuOiBmbGlwLFxuICByZXF1aXJlc0lmRXhpc3RzOiBbJ29mZnNldCddLFxuICBkYXRhOiB7XG4gICAgX3NraXA6IGZhbHNlXG4gIH1cbn07IiwiaW1wb3J0IHsgdG9wLCBib3R0b20sIGxlZnQsIHJpZ2h0IH0gZnJvbSBcIi4uL2VudW1zLmpzXCI7XG5pbXBvcnQgZGV0ZWN0T3ZlcmZsb3cgZnJvbSBcIi4uL3V0aWxzL2RldGVjdE92ZXJmbG93LmpzXCI7XG5cbmZ1bmN0aW9uIGdldFNpZGVPZmZzZXRzKG92ZXJmbG93LCByZWN0LCBwcmV2ZW50ZWRPZmZzZXRzKSB7XG4gIGlmIChwcmV2ZW50ZWRPZmZzZXRzID09PSB2b2lkIDApIHtcbiAgICBwcmV2ZW50ZWRPZmZzZXRzID0ge1xuICAgICAgeDogMCxcbiAgICAgIHk6IDBcbiAgICB9O1xuICB9XG5cbiAgcmV0dXJuIHtcbiAgICB0b3A6IG92ZXJmbG93LnRvcCAtIHJlY3QuaGVpZ2h0IC0gcHJldmVudGVkT2Zmc2V0cy55LFxuICAgIHJpZ2h0OiBvdmVyZmxvdy5yaWdodCAtIHJlY3Qud2lkdGggKyBwcmV2ZW50ZWRPZmZzZXRzLngsXG4gICAgYm90dG9tOiBvdmVyZmxvdy5ib3R0b20gLSByZWN0LmhlaWdodCArIHByZXZlbnRlZE9mZnNldHMueSxcbiAgICBsZWZ0OiBvdmVyZmxvdy5sZWZ0IC0gcmVjdC53aWR0aCAtIHByZXZlbnRlZE9mZnNldHMueFxuICB9O1xufVxuXG5mdW5jdGlvbiBpc0FueVNpZGVGdWxseUNsaXBwZWQob3ZlcmZsb3cpIHtcbiAgcmV0dXJuIFt0b3AsIHJpZ2h0LCBib3R0b20sIGxlZnRdLnNvbWUoZnVuY3Rpb24gKHNpZGUpIHtcbiAgICByZXR1cm4gb3ZlcmZsb3dbc2lkZV0gPj0gMDtcbiAgfSk7XG59XG5cbmZ1bmN0aW9uIGhpZGUoX3JlZikge1xuICB2YXIgc3RhdGUgPSBfcmVmLnN0YXRlLFxuICAgICAgbmFtZSA9IF9yZWYubmFtZTtcbiAgdmFyIHJlZmVyZW5jZVJlY3QgPSBzdGF0ZS5yZWN0cy5yZWZlcmVuY2U7XG4gIHZhciBwb3BwZXJSZWN0ID0gc3RhdGUucmVjdHMucG9wcGVyO1xuICB2YXIgcHJldmVudGVkT2Zmc2V0cyA9IHN0YXRlLm1vZGlmaWVyc0RhdGEucHJldmVudE92ZXJmbG93O1xuICB2YXIgcmVmZXJlbmNlT3ZlcmZsb3cgPSBkZXRlY3RPdmVyZmxvdyhzdGF0ZSwge1xuICAgIGVsZW1lbnRDb250ZXh0OiAncmVmZXJlbmNlJ1xuICB9KTtcbiAgdmFyIHBvcHBlckFsdE92ZXJmbG93ID0gZGV0ZWN0T3ZlcmZsb3coc3RhdGUsIHtcbiAgICBhbHRCb3VuZGFyeTogdHJ1ZVxuICB9KTtcbiAgdmFyIHJlZmVyZW5jZUNsaXBwaW5nT2Zmc2V0cyA9IGdldFNpZGVPZmZzZXRzKHJlZmVyZW5jZU92ZXJmbG93LCByZWZlcmVuY2VSZWN0KTtcbiAgdmFyIHBvcHBlckVzY2FwZU9mZnNldHMgPSBnZXRTaWRlT2Zmc2V0cyhwb3BwZXJBbHRPdmVyZmxvdywgcG9wcGVyUmVjdCwgcHJldmVudGVkT2Zmc2V0cyk7XG4gIHZhciBpc1JlZmVyZW5jZUhpZGRlbiA9IGlzQW55U2lkZUZ1bGx5Q2xpcHBlZChyZWZlcmVuY2VDbGlwcGluZ09mZnNldHMpO1xuICB2YXIgaGFzUG9wcGVyRXNjYXBlZCA9IGlzQW55U2lkZUZ1bGx5Q2xpcHBlZChwb3BwZXJFc2NhcGVPZmZzZXRzKTtcbiAgc3RhdGUubW9kaWZpZXJzRGF0YVtuYW1lXSA9IHtcbiAgICByZWZlcmVuY2VDbGlwcGluZ09mZnNldHM6IHJlZmVyZW5jZUNsaXBwaW5nT2Zmc2V0cyxcbiAgICBwb3BwZXJFc2NhcGVPZmZzZXRzOiBwb3BwZXJFc2NhcGVPZmZzZXRzLFxuICAgIGlzUmVmZXJlbmNlSGlkZGVuOiBpc1JlZmVyZW5jZUhpZGRlbixcbiAgICBoYXNQb3BwZXJFc2NhcGVkOiBoYXNQb3BwZXJFc2NhcGVkXG4gIH07XG4gIHN0YXRlLmF0dHJpYnV0ZXMucG9wcGVyID0gT2JqZWN0LmFzc2lnbih7fSwgc3RhdGUuYXR0cmlidXRlcy5wb3BwZXIsIHtcbiAgICAnZGF0YS1wb3BwZXItcmVmZXJlbmNlLWhpZGRlbic6IGlzUmVmZXJlbmNlSGlkZGVuLFxuICAgICdkYXRhLXBvcHBlci1lc2NhcGVkJzogaGFzUG9wcGVyRXNjYXBlZFxuICB9KTtcbn0gLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGltcG9ydC9uby11bnVzZWQtbW9kdWxlc1xuXG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgbmFtZTogJ2hpZGUnLFxuICBlbmFibGVkOiB0cnVlLFxuICBwaGFzZTogJ21haW4nLFxuICByZXF1aXJlc0lmRXhpc3RzOiBbJ3ByZXZlbnRPdmVyZmxvdyddLFxuICBmbjogaGlkZVxufTsiLCJpbXBvcnQgZ2V0QmFzZVBsYWNlbWVudCBmcm9tIFwiLi4vdXRpbHMvZ2V0QmFzZVBsYWNlbWVudC5qc1wiO1xuaW1wb3J0IHsgdG9wLCBsZWZ0LCByaWdodCwgcGxhY2VtZW50cyB9IGZyb20gXCIuLi9lbnVtcy5qc1wiOyAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgaW1wb3J0L25vLXVudXNlZC1tb2R1bGVzXG5cbmV4cG9ydCBmdW5jdGlvbiBkaXN0YW5jZUFuZFNraWRkaW5nVG9YWShwbGFjZW1lbnQsIHJlY3RzLCBvZmZzZXQpIHtcbiAgdmFyIGJhc2VQbGFjZW1lbnQgPSBnZXRCYXNlUGxhY2VtZW50KHBsYWNlbWVudCk7XG4gIHZhciBpbnZlcnREaXN0YW5jZSA9IFtsZWZ0LCB0b3BdLmluZGV4T2YoYmFzZVBsYWNlbWVudCkgPj0gMCA/IC0xIDogMTtcblxuICB2YXIgX3JlZiA9IHR5cGVvZiBvZmZzZXQgPT09ICdmdW5jdGlvbicgPyBvZmZzZXQoT2JqZWN0LmFzc2lnbih7fSwgcmVjdHMsIHtcbiAgICBwbGFjZW1lbnQ6IHBsYWNlbWVudFxuICB9KSkgOiBvZmZzZXQsXG4gICAgICBza2lkZGluZyA9IF9yZWZbMF0sXG4gICAgICBkaXN0YW5jZSA9IF9yZWZbMV07XG5cbiAgc2tpZGRpbmcgPSBza2lkZGluZyB8fCAwO1xuICBkaXN0YW5jZSA9IChkaXN0YW5jZSB8fCAwKSAqIGludmVydERpc3RhbmNlO1xuICByZXR1cm4gW2xlZnQsIHJpZ2h0XS5pbmRleE9mKGJhc2VQbGFjZW1lbnQpID49IDAgPyB7XG4gICAgeDogZGlzdGFuY2UsXG4gICAgeTogc2tpZGRpbmdcbiAgfSA6IHtcbiAgICB4OiBza2lkZGluZyxcbiAgICB5OiBkaXN0YW5jZVxuICB9O1xufVxuXG5mdW5jdGlvbiBvZmZzZXQoX3JlZjIpIHtcbiAgdmFyIHN0YXRlID0gX3JlZjIuc3RhdGUsXG4gICAgICBvcHRpb25zID0gX3JlZjIub3B0aW9ucyxcbiAgICAgIG5hbWUgPSBfcmVmMi5uYW1lO1xuICB2YXIgX29wdGlvbnMkb2Zmc2V0ID0gb3B0aW9ucy5vZmZzZXQsXG4gICAgICBvZmZzZXQgPSBfb3B0aW9ucyRvZmZzZXQgPT09IHZvaWQgMCA/IFswLCAwXSA6IF9vcHRpb25zJG9mZnNldDtcbiAgdmFyIGRhdGEgPSBwbGFjZW1lbnRzLnJlZHVjZShmdW5jdGlvbiAoYWNjLCBwbGFjZW1lbnQpIHtcbiAgICBhY2NbcGxhY2VtZW50XSA9IGRpc3RhbmNlQW5kU2tpZGRpbmdUb1hZKHBsYWNlbWVudCwgc3RhdGUucmVjdHMsIG9mZnNldCk7XG4gICAgcmV0dXJuIGFjYztcbiAgfSwge30pO1xuICB2YXIgX2RhdGEkc3RhdGUkcGxhY2VtZW50ID0gZGF0YVtzdGF0ZS5wbGFjZW1lbnRdLFxuICAgICAgeCA9IF9kYXRhJHN0YXRlJHBsYWNlbWVudC54LFxuICAgICAgeSA9IF9kYXRhJHN0YXRlJHBsYWNlbWVudC55O1xuXG4gIGlmIChzdGF0ZS5tb2RpZmllcnNEYXRhLnBvcHBlck9mZnNldHMgIT0gbnVsbCkge1xuICAgIHN0YXRlLm1vZGlmaWVyc0RhdGEucG9wcGVyT2Zmc2V0cy54ICs9IHg7XG4gICAgc3RhdGUubW9kaWZpZXJzRGF0YS5wb3BwZXJPZmZzZXRzLnkgKz0geTtcbiAgfVxuXG4gIHN0YXRlLm1vZGlmaWVyc0RhdGFbbmFtZV0gPSBkYXRhO1xufSAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgaW1wb3J0L25vLXVudXNlZC1tb2R1bGVzXG5cblxuZXhwb3J0IGRlZmF1bHQge1xuICBuYW1lOiAnb2Zmc2V0JyxcbiAgZW5hYmxlZDogdHJ1ZSxcbiAgcGhhc2U6ICdtYWluJyxcbiAgcmVxdWlyZXM6IFsncG9wcGVyT2Zmc2V0cyddLFxuICBmbjogb2Zmc2V0XG59OyIsImltcG9ydCBjb21wdXRlT2Zmc2V0cyBmcm9tIFwiLi4vdXRpbHMvY29tcHV0ZU9mZnNldHMuanNcIjtcblxuZnVuY3Rpb24gcG9wcGVyT2Zmc2V0cyhfcmVmKSB7XG4gIHZhciBzdGF0ZSA9IF9yZWYuc3RhdGUsXG4gICAgICBuYW1lID0gX3JlZi5uYW1lO1xuICAvLyBPZmZzZXRzIGFyZSB0aGUgYWN0dWFsIHBvc2l0aW9uIHRoZSBwb3BwZXIgbmVlZHMgdG8gaGF2ZSB0byBiZVxuICAvLyBwcm9wZXJseSBwb3NpdGlvbmVkIG5lYXIgaXRzIHJlZmVyZW5jZSBlbGVtZW50XG4gIC8vIFRoaXMgaXMgdGhlIG1vc3QgYmFzaWMgcGxhY2VtZW50LCBhbmQgd2lsbCBiZSBhZGp1c3RlZCBieVxuICAvLyB0aGUgbW9kaWZpZXJzIGluIHRoZSBuZXh0IHN0ZXBcbiAgc3RhdGUubW9kaWZpZXJzRGF0YVtuYW1lXSA9IGNvbXB1dGVPZmZzZXRzKHtcbiAgICByZWZlcmVuY2U6IHN0YXRlLnJlY3RzLnJlZmVyZW5jZSxcbiAgICBlbGVtZW50OiBzdGF0ZS5yZWN0cy5wb3BwZXIsXG4gICAgc3RyYXRlZ3k6ICdhYnNvbHV0ZScsXG4gICAgcGxhY2VtZW50OiBzdGF0ZS5wbGFjZW1lbnRcbiAgfSk7XG59IC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBpbXBvcnQvbm8tdW51c2VkLW1vZHVsZXNcblxuXG5leHBvcnQgZGVmYXVsdCB7XG4gIG5hbWU6ICdwb3BwZXJPZmZzZXRzJyxcbiAgZW5hYmxlZDogdHJ1ZSxcbiAgcGhhc2U6ICdyZWFkJyxcbiAgZm46IHBvcHBlck9mZnNldHMsXG4gIGRhdGE6IHt9XG59OyIsImV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGdldEFsdEF4aXMoYXhpcykge1xuICByZXR1cm4gYXhpcyA9PT0gJ3gnID8gJ3knIDogJ3gnO1xufSIsImltcG9ydCB7IHRvcCwgbGVmdCwgcmlnaHQsIGJvdHRvbSwgc3RhcnQgfSBmcm9tIFwiLi4vZW51bXMuanNcIjtcbmltcG9ydCBnZXRCYXNlUGxhY2VtZW50IGZyb20gXCIuLi91dGlscy9nZXRCYXNlUGxhY2VtZW50LmpzXCI7XG5pbXBvcnQgZ2V0TWFpbkF4aXNGcm9tUGxhY2VtZW50IGZyb20gXCIuLi91dGlscy9nZXRNYWluQXhpc0Zyb21QbGFjZW1lbnQuanNcIjtcbmltcG9ydCBnZXRBbHRBeGlzIGZyb20gXCIuLi91dGlscy9nZXRBbHRBeGlzLmpzXCI7XG5pbXBvcnQgeyB3aXRoaW4sIHdpdGhpbk1heENsYW1wIH0gZnJvbSBcIi4uL3V0aWxzL3dpdGhpbi5qc1wiO1xuaW1wb3J0IGdldExheW91dFJlY3QgZnJvbSBcIi4uL2RvbS11dGlscy9nZXRMYXlvdXRSZWN0LmpzXCI7XG5pbXBvcnQgZ2V0T2Zmc2V0UGFyZW50IGZyb20gXCIuLi9kb20tdXRpbHMvZ2V0T2Zmc2V0UGFyZW50LmpzXCI7XG5pbXBvcnQgZGV0ZWN0T3ZlcmZsb3cgZnJvbSBcIi4uL3V0aWxzL2RldGVjdE92ZXJmbG93LmpzXCI7XG5pbXBvcnQgZ2V0VmFyaWF0aW9uIGZyb20gXCIuLi91dGlscy9nZXRWYXJpYXRpb24uanNcIjtcbmltcG9ydCBnZXRGcmVzaFNpZGVPYmplY3QgZnJvbSBcIi4uL3V0aWxzL2dldEZyZXNoU2lkZU9iamVjdC5qc1wiO1xuaW1wb3J0IHsgbWluIGFzIG1hdGhNaW4sIG1heCBhcyBtYXRoTWF4IH0gZnJvbSBcIi4uL3V0aWxzL21hdGguanNcIjtcblxuZnVuY3Rpb24gcHJldmVudE92ZXJmbG93KF9yZWYpIHtcbiAgdmFyIHN0YXRlID0gX3JlZi5zdGF0ZSxcbiAgICAgIG9wdGlvbnMgPSBfcmVmLm9wdGlvbnMsXG4gICAgICBuYW1lID0gX3JlZi5uYW1lO1xuICB2YXIgX29wdGlvbnMkbWFpbkF4aXMgPSBvcHRpb25zLm1haW5BeGlzLFxuICAgICAgY2hlY2tNYWluQXhpcyA9IF9vcHRpb25zJG1haW5BeGlzID09PSB2b2lkIDAgPyB0cnVlIDogX29wdGlvbnMkbWFpbkF4aXMsXG4gICAgICBfb3B0aW9ucyRhbHRBeGlzID0gb3B0aW9ucy5hbHRBeGlzLFxuICAgICAgY2hlY2tBbHRBeGlzID0gX29wdGlvbnMkYWx0QXhpcyA9PT0gdm9pZCAwID8gZmFsc2UgOiBfb3B0aW9ucyRhbHRBeGlzLFxuICAgICAgYm91bmRhcnkgPSBvcHRpb25zLmJvdW5kYXJ5LFxuICAgICAgcm9vdEJvdW5kYXJ5ID0gb3B0aW9ucy5yb290Qm91bmRhcnksXG4gICAgICBhbHRCb3VuZGFyeSA9IG9wdGlvbnMuYWx0Qm91bmRhcnksXG4gICAgICBwYWRkaW5nID0gb3B0aW9ucy5wYWRkaW5nLFxuICAgICAgX29wdGlvbnMkdGV0aGVyID0gb3B0aW9ucy50ZXRoZXIsXG4gICAgICB0ZXRoZXIgPSBfb3B0aW9ucyR0ZXRoZXIgPT09IHZvaWQgMCA/IHRydWUgOiBfb3B0aW9ucyR0ZXRoZXIsXG4gICAgICBfb3B0aW9ucyR0ZXRoZXJPZmZzZXQgPSBvcHRpb25zLnRldGhlck9mZnNldCxcbiAgICAgIHRldGhlck9mZnNldCA9IF9vcHRpb25zJHRldGhlck9mZnNldCA9PT0gdm9pZCAwID8gMCA6IF9vcHRpb25zJHRldGhlck9mZnNldDtcbiAgdmFyIG92ZXJmbG93ID0gZGV0ZWN0T3ZlcmZsb3coc3RhdGUsIHtcbiAgICBib3VuZGFyeTogYm91bmRhcnksXG4gICAgcm9vdEJvdW5kYXJ5OiByb290Qm91bmRhcnksXG4gICAgcGFkZGluZzogcGFkZGluZyxcbiAgICBhbHRCb3VuZGFyeTogYWx0Qm91bmRhcnlcbiAgfSk7XG4gIHZhciBiYXNlUGxhY2VtZW50ID0gZ2V0QmFzZVBsYWNlbWVudChzdGF0ZS5wbGFjZW1lbnQpO1xuICB2YXIgdmFyaWF0aW9uID0gZ2V0VmFyaWF0aW9uKHN0YXRlLnBsYWNlbWVudCk7XG4gIHZhciBpc0Jhc2VQbGFjZW1lbnQgPSAhdmFyaWF0aW9uO1xuICB2YXIgbWFpbkF4aXMgPSBnZXRNYWluQXhpc0Zyb21QbGFjZW1lbnQoYmFzZVBsYWNlbWVudCk7XG4gIHZhciBhbHRBeGlzID0gZ2V0QWx0QXhpcyhtYWluQXhpcyk7XG4gIHZhciBwb3BwZXJPZmZzZXRzID0gc3RhdGUubW9kaWZpZXJzRGF0YS5wb3BwZXJPZmZzZXRzO1xuICB2YXIgcmVmZXJlbmNlUmVjdCA9IHN0YXRlLnJlY3RzLnJlZmVyZW5jZTtcbiAgdmFyIHBvcHBlclJlY3QgPSBzdGF0ZS5yZWN0cy5wb3BwZXI7XG4gIHZhciB0ZXRoZXJPZmZzZXRWYWx1ZSA9IHR5cGVvZiB0ZXRoZXJPZmZzZXQgPT09ICdmdW5jdGlvbicgPyB0ZXRoZXJPZmZzZXQoT2JqZWN0LmFzc2lnbih7fSwgc3RhdGUucmVjdHMsIHtcbiAgICBwbGFjZW1lbnQ6IHN0YXRlLnBsYWNlbWVudFxuICB9KSkgOiB0ZXRoZXJPZmZzZXQ7XG4gIHZhciBub3JtYWxpemVkVGV0aGVyT2Zmc2V0VmFsdWUgPSB0eXBlb2YgdGV0aGVyT2Zmc2V0VmFsdWUgPT09ICdudW1iZXInID8ge1xuICAgIG1haW5BeGlzOiB0ZXRoZXJPZmZzZXRWYWx1ZSxcbiAgICBhbHRBeGlzOiB0ZXRoZXJPZmZzZXRWYWx1ZVxuICB9IDogT2JqZWN0LmFzc2lnbih7XG4gICAgbWFpbkF4aXM6IDAsXG4gICAgYWx0QXhpczogMFxuICB9LCB0ZXRoZXJPZmZzZXRWYWx1ZSk7XG4gIHZhciBvZmZzZXRNb2RpZmllclN0YXRlID0gc3RhdGUubW9kaWZpZXJzRGF0YS5vZmZzZXQgPyBzdGF0ZS5tb2RpZmllcnNEYXRhLm9mZnNldFtzdGF0ZS5wbGFjZW1lbnRdIDogbnVsbDtcbiAgdmFyIGRhdGEgPSB7XG4gICAgeDogMCxcbiAgICB5OiAwXG4gIH07XG5cbiAgaWYgKCFwb3BwZXJPZmZzZXRzKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgaWYgKGNoZWNrTWFpbkF4aXMpIHtcbiAgICB2YXIgX29mZnNldE1vZGlmaWVyU3RhdGUkO1xuXG4gICAgdmFyIG1haW5TaWRlID0gbWFpbkF4aXMgPT09ICd5JyA/IHRvcCA6IGxlZnQ7XG4gICAgdmFyIGFsdFNpZGUgPSBtYWluQXhpcyA9PT0gJ3knID8gYm90dG9tIDogcmlnaHQ7XG4gICAgdmFyIGxlbiA9IG1haW5BeGlzID09PSAneScgPyAnaGVpZ2h0JyA6ICd3aWR0aCc7XG4gICAgdmFyIG9mZnNldCA9IHBvcHBlck9mZnNldHNbbWFpbkF4aXNdO1xuICAgIHZhciBtaW4gPSBvZmZzZXQgKyBvdmVyZmxvd1ttYWluU2lkZV07XG4gICAgdmFyIG1heCA9IG9mZnNldCAtIG92ZXJmbG93W2FsdFNpZGVdO1xuICAgIHZhciBhZGRpdGl2ZSA9IHRldGhlciA/IC1wb3BwZXJSZWN0W2xlbl0gLyAyIDogMDtcbiAgICB2YXIgbWluTGVuID0gdmFyaWF0aW9uID09PSBzdGFydCA/IHJlZmVyZW5jZVJlY3RbbGVuXSA6IHBvcHBlclJlY3RbbGVuXTtcbiAgICB2YXIgbWF4TGVuID0gdmFyaWF0aW9uID09PSBzdGFydCA/IC1wb3BwZXJSZWN0W2xlbl0gOiAtcmVmZXJlbmNlUmVjdFtsZW5dOyAvLyBXZSBuZWVkIHRvIGluY2x1ZGUgdGhlIGFycm93IGluIHRoZSBjYWxjdWxhdGlvbiBzbyB0aGUgYXJyb3cgZG9lc24ndCBnb1xuICAgIC8vIG91dHNpZGUgdGhlIHJlZmVyZW5jZSBib3VuZHNcblxuICAgIHZhciBhcnJvd0VsZW1lbnQgPSBzdGF0ZS5lbGVtZW50cy5hcnJvdztcbiAgICB2YXIgYXJyb3dSZWN0ID0gdGV0aGVyICYmIGFycm93RWxlbWVudCA/IGdldExheW91dFJlY3QoYXJyb3dFbGVtZW50KSA6IHtcbiAgICAgIHdpZHRoOiAwLFxuICAgICAgaGVpZ2h0OiAwXG4gICAgfTtcbiAgICB2YXIgYXJyb3dQYWRkaW5nT2JqZWN0ID0gc3RhdGUubW9kaWZpZXJzRGF0YVsnYXJyb3cjcGVyc2lzdGVudCddID8gc3RhdGUubW9kaWZpZXJzRGF0YVsnYXJyb3cjcGVyc2lzdGVudCddLnBhZGRpbmcgOiBnZXRGcmVzaFNpZGVPYmplY3QoKTtcbiAgICB2YXIgYXJyb3dQYWRkaW5nTWluID0gYXJyb3dQYWRkaW5nT2JqZWN0W21haW5TaWRlXTtcbiAgICB2YXIgYXJyb3dQYWRkaW5nTWF4ID0gYXJyb3dQYWRkaW5nT2JqZWN0W2FsdFNpZGVdOyAvLyBJZiB0aGUgcmVmZXJlbmNlIGxlbmd0aCBpcyBzbWFsbGVyIHRoYW4gdGhlIGFycm93IGxlbmd0aCwgd2UgZG9uJ3Qgd2FudFxuICAgIC8vIHRvIGluY2x1ZGUgaXRzIGZ1bGwgc2l6ZSBpbiB0aGUgY2FsY3VsYXRpb24uIElmIHRoZSByZWZlcmVuY2UgaXMgc21hbGxcbiAgICAvLyBhbmQgbmVhciB0aGUgZWRnZSBvZiBhIGJvdW5kYXJ5LCB0aGUgcG9wcGVyIGNhbiBvdmVyZmxvdyBldmVuIGlmIHRoZVxuICAgIC8vIHJlZmVyZW5jZSBpcyBub3Qgb3ZlcmZsb3dpbmcgYXMgd2VsbCAoZS5nLiB2aXJ0dWFsIGVsZW1lbnRzIHdpdGggbm9cbiAgICAvLyB3aWR0aCBvciBoZWlnaHQpXG5cbiAgICB2YXIgYXJyb3dMZW4gPSB3aXRoaW4oMCwgcmVmZXJlbmNlUmVjdFtsZW5dLCBhcnJvd1JlY3RbbGVuXSk7XG4gICAgdmFyIG1pbk9mZnNldCA9IGlzQmFzZVBsYWNlbWVudCA/IHJlZmVyZW5jZVJlY3RbbGVuXSAvIDIgLSBhZGRpdGl2ZSAtIGFycm93TGVuIC0gYXJyb3dQYWRkaW5nTWluIC0gbm9ybWFsaXplZFRldGhlck9mZnNldFZhbHVlLm1haW5BeGlzIDogbWluTGVuIC0gYXJyb3dMZW4gLSBhcnJvd1BhZGRpbmdNaW4gLSBub3JtYWxpemVkVGV0aGVyT2Zmc2V0VmFsdWUubWFpbkF4aXM7XG4gICAgdmFyIG1heE9mZnNldCA9IGlzQmFzZVBsYWNlbWVudCA/IC1yZWZlcmVuY2VSZWN0W2xlbl0gLyAyICsgYWRkaXRpdmUgKyBhcnJvd0xlbiArIGFycm93UGFkZGluZ01heCArIG5vcm1hbGl6ZWRUZXRoZXJPZmZzZXRWYWx1ZS5tYWluQXhpcyA6IG1heExlbiArIGFycm93TGVuICsgYXJyb3dQYWRkaW5nTWF4ICsgbm9ybWFsaXplZFRldGhlck9mZnNldFZhbHVlLm1haW5BeGlzO1xuICAgIHZhciBhcnJvd09mZnNldFBhcmVudCA9IHN0YXRlLmVsZW1lbnRzLmFycm93ICYmIGdldE9mZnNldFBhcmVudChzdGF0ZS5lbGVtZW50cy5hcnJvdyk7XG4gICAgdmFyIGNsaWVudE9mZnNldCA9IGFycm93T2Zmc2V0UGFyZW50ID8gbWFpbkF4aXMgPT09ICd5JyA/IGFycm93T2Zmc2V0UGFyZW50LmNsaWVudFRvcCB8fCAwIDogYXJyb3dPZmZzZXRQYXJlbnQuY2xpZW50TGVmdCB8fCAwIDogMDtcbiAgICB2YXIgb2Zmc2V0TW9kaWZpZXJWYWx1ZSA9IChfb2Zmc2V0TW9kaWZpZXJTdGF0ZSQgPSBvZmZzZXRNb2RpZmllclN0YXRlID09IG51bGwgPyB2b2lkIDAgOiBvZmZzZXRNb2RpZmllclN0YXRlW21haW5BeGlzXSkgIT0gbnVsbCA/IF9vZmZzZXRNb2RpZmllclN0YXRlJCA6IDA7XG4gICAgdmFyIHRldGhlck1pbiA9IG9mZnNldCArIG1pbk9mZnNldCAtIG9mZnNldE1vZGlmaWVyVmFsdWUgLSBjbGllbnRPZmZzZXQ7XG4gICAgdmFyIHRldGhlck1heCA9IG9mZnNldCArIG1heE9mZnNldCAtIG9mZnNldE1vZGlmaWVyVmFsdWU7XG4gICAgdmFyIHByZXZlbnRlZE9mZnNldCA9IHdpdGhpbih0ZXRoZXIgPyBtYXRoTWluKG1pbiwgdGV0aGVyTWluKSA6IG1pbiwgb2Zmc2V0LCB0ZXRoZXIgPyBtYXRoTWF4KG1heCwgdGV0aGVyTWF4KSA6IG1heCk7XG4gICAgcG9wcGVyT2Zmc2V0c1ttYWluQXhpc10gPSBwcmV2ZW50ZWRPZmZzZXQ7XG4gICAgZGF0YVttYWluQXhpc10gPSBwcmV2ZW50ZWRPZmZzZXQgLSBvZmZzZXQ7XG4gIH1cblxuICBpZiAoY2hlY2tBbHRBeGlzKSB7XG4gICAgdmFyIF9vZmZzZXRNb2RpZmllclN0YXRlJDI7XG5cbiAgICB2YXIgX21haW5TaWRlID0gbWFpbkF4aXMgPT09ICd4JyA/IHRvcCA6IGxlZnQ7XG5cbiAgICB2YXIgX2FsdFNpZGUgPSBtYWluQXhpcyA9PT0gJ3gnID8gYm90dG9tIDogcmlnaHQ7XG5cbiAgICB2YXIgX29mZnNldCA9IHBvcHBlck9mZnNldHNbYWx0QXhpc107XG5cbiAgICB2YXIgX2xlbiA9IGFsdEF4aXMgPT09ICd5JyA/ICdoZWlnaHQnIDogJ3dpZHRoJztcblxuICAgIHZhciBfbWluID0gX29mZnNldCArIG92ZXJmbG93W19tYWluU2lkZV07XG5cbiAgICB2YXIgX21heCA9IF9vZmZzZXQgLSBvdmVyZmxvd1tfYWx0U2lkZV07XG5cbiAgICB2YXIgaXNPcmlnaW5TaWRlID0gW3RvcCwgbGVmdF0uaW5kZXhPZihiYXNlUGxhY2VtZW50KSAhPT0gLTE7XG5cbiAgICB2YXIgX29mZnNldE1vZGlmaWVyVmFsdWUgPSAoX29mZnNldE1vZGlmaWVyU3RhdGUkMiA9IG9mZnNldE1vZGlmaWVyU3RhdGUgPT0gbnVsbCA/IHZvaWQgMCA6IG9mZnNldE1vZGlmaWVyU3RhdGVbYWx0QXhpc10pICE9IG51bGwgPyBfb2Zmc2V0TW9kaWZpZXJTdGF0ZSQyIDogMDtcblxuICAgIHZhciBfdGV0aGVyTWluID0gaXNPcmlnaW5TaWRlID8gX21pbiA6IF9vZmZzZXQgLSByZWZlcmVuY2VSZWN0W19sZW5dIC0gcG9wcGVyUmVjdFtfbGVuXSAtIF9vZmZzZXRNb2RpZmllclZhbHVlICsgbm9ybWFsaXplZFRldGhlck9mZnNldFZhbHVlLmFsdEF4aXM7XG5cbiAgICB2YXIgX3RldGhlck1heCA9IGlzT3JpZ2luU2lkZSA/IF9vZmZzZXQgKyByZWZlcmVuY2VSZWN0W19sZW5dICsgcG9wcGVyUmVjdFtfbGVuXSAtIF9vZmZzZXRNb2RpZmllclZhbHVlIC0gbm9ybWFsaXplZFRldGhlck9mZnNldFZhbHVlLmFsdEF4aXMgOiBfbWF4O1xuXG4gICAgdmFyIF9wcmV2ZW50ZWRPZmZzZXQgPSB0ZXRoZXIgJiYgaXNPcmlnaW5TaWRlID8gd2l0aGluTWF4Q2xhbXAoX3RldGhlck1pbiwgX29mZnNldCwgX3RldGhlck1heCkgOiB3aXRoaW4odGV0aGVyID8gX3RldGhlck1pbiA6IF9taW4sIF9vZmZzZXQsIHRldGhlciA/IF90ZXRoZXJNYXggOiBfbWF4KTtcblxuICAgIHBvcHBlck9mZnNldHNbYWx0QXhpc10gPSBfcHJldmVudGVkT2Zmc2V0O1xuICAgIGRhdGFbYWx0QXhpc10gPSBfcHJldmVudGVkT2Zmc2V0IC0gX29mZnNldDtcbiAgfVxuXG4gIHN0YXRlLm1vZGlmaWVyc0RhdGFbbmFtZV0gPSBkYXRhO1xufSAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgaW1wb3J0L25vLXVudXNlZC1tb2R1bGVzXG5cblxuZXhwb3J0IGRlZmF1bHQge1xuICBuYW1lOiAncHJldmVudE92ZXJmbG93JyxcbiAgZW5hYmxlZDogdHJ1ZSxcbiAgcGhhc2U6ICdtYWluJyxcbiAgZm46IHByZXZlbnRPdmVyZmxvdyxcbiAgcmVxdWlyZXNJZkV4aXN0czogWydvZmZzZXQnXVxufTsiLCJleHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBnZXRIVE1MRWxlbWVudFNjcm9sbChlbGVtZW50KSB7XG4gIHJldHVybiB7XG4gICAgc2Nyb2xsTGVmdDogZWxlbWVudC5zY3JvbGxMZWZ0LFxuICAgIHNjcm9sbFRvcDogZWxlbWVudC5zY3JvbGxUb3BcbiAgfTtcbn0iLCJpbXBvcnQgZ2V0V2luZG93U2Nyb2xsIGZyb20gXCIuL2dldFdpbmRvd1Njcm9sbC5qc1wiO1xuaW1wb3J0IGdldFdpbmRvdyBmcm9tIFwiLi9nZXRXaW5kb3cuanNcIjtcbmltcG9ydCB7IGlzSFRNTEVsZW1lbnQgfSBmcm9tIFwiLi9pbnN0YW5jZU9mLmpzXCI7XG5pbXBvcnQgZ2V0SFRNTEVsZW1lbnRTY3JvbGwgZnJvbSBcIi4vZ2V0SFRNTEVsZW1lbnRTY3JvbGwuanNcIjtcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGdldE5vZGVTY3JvbGwobm9kZSkge1xuICBpZiAobm9kZSA9PT0gZ2V0V2luZG93KG5vZGUpIHx8ICFpc0hUTUxFbGVtZW50KG5vZGUpKSB7XG4gICAgcmV0dXJuIGdldFdpbmRvd1Njcm9sbChub2RlKTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gZ2V0SFRNTEVsZW1lbnRTY3JvbGwobm9kZSk7XG4gIH1cbn0iLCJpbXBvcnQgZ2V0Qm91bmRpbmdDbGllbnRSZWN0IGZyb20gXCIuL2dldEJvdW5kaW5nQ2xpZW50UmVjdC5qc1wiO1xuaW1wb3J0IGdldE5vZGVTY3JvbGwgZnJvbSBcIi4vZ2V0Tm9kZVNjcm9sbC5qc1wiO1xuaW1wb3J0IGdldE5vZGVOYW1lIGZyb20gXCIuL2dldE5vZGVOYW1lLmpzXCI7XG5pbXBvcnQgeyBpc0hUTUxFbGVtZW50IH0gZnJvbSBcIi4vaW5zdGFuY2VPZi5qc1wiO1xuaW1wb3J0IGdldFdpbmRvd1Njcm9sbEJhclggZnJvbSBcIi4vZ2V0V2luZG93U2Nyb2xsQmFyWC5qc1wiO1xuaW1wb3J0IGdldERvY3VtZW50RWxlbWVudCBmcm9tIFwiLi9nZXREb2N1bWVudEVsZW1lbnQuanNcIjtcbmltcG9ydCBpc1Njcm9sbFBhcmVudCBmcm9tIFwiLi9pc1Njcm9sbFBhcmVudC5qc1wiO1xuaW1wb3J0IHsgcm91bmQgfSBmcm9tIFwiLi4vdXRpbHMvbWF0aC5qc1wiO1xuXG5mdW5jdGlvbiBpc0VsZW1lbnRTY2FsZWQoZWxlbWVudCkge1xuICB2YXIgcmVjdCA9IGVsZW1lbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gIHZhciBzY2FsZVggPSByb3VuZChyZWN0LndpZHRoKSAvIGVsZW1lbnQub2Zmc2V0V2lkdGggfHwgMTtcbiAgdmFyIHNjYWxlWSA9IHJvdW5kKHJlY3QuaGVpZ2h0KSAvIGVsZW1lbnQub2Zmc2V0SGVpZ2h0IHx8IDE7XG4gIHJldHVybiBzY2FsZVggIT09IDEgfHwgc2NhbGVZICE9PSAxO1xufSAvLyBSZXR1cm5zIHRoZSBjb21wb3NpdGUgcmVjdCBvZiBhbiBlbGVtZW50IHJlbGF0aXZlIHRvIGl0cyBvZmZzZXRQYXJlbnQuXG4vLyBDb21wb3NpdGUgbWVhbnMgaXQgdGFrZXMgaW50byBhY2NvdW50IHRyYW5zZm9ybXMgYXMgd2VsbCBhcyBsYXlvdXQuXG5cblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gZ2V0Q29tcG9zaXRlUmVjdChlbGVtZW50T3JWaXJ0dWFsRWxlbWVudCwgb2Zmc2V0UGFyZW50LCBpc0ZpeGVkKSB7XG4gIGlmIChpc0ZpeGVkID09PSB2b2lkIDApIHtcbiAgICBpc0ZpeGVkID0gZmFsc2U7XG4gIH1cblxuICB2YXIgaXNPZmZzZXRQYXJlbnRBbkVsZW1lbnQgPSBpc0hUTUxFbGVtZW50KG9mZnNldFBhcmVudCk7XG4gIHZhciBvZmZzZXRQYXJlbnRJc1NjYWxlZCA9IGlzSFRNTEVsZW1lbnQob2Zmc2V0UGFyZW50KSAmJiBpc0VsZW1lbnRTY2FsZWQob2Zmc2V0UGFyZW50KTtcbiAgdmFyIGRvY3VtZW50RWxlbWVudCA9IGdldERvY3VtZW50RWxlbWVudChvZmZzZXRQYXJlbnQpO1xuICB2YXIgcmVjdCA9IGdldEJvdW5kaW5nQ2xpZW50UmVjdChlbGVtZW50T3JWaXJ0dWFsRWxlbWVudCwgb2Zmc2V0UGFyZW50SXNTY2FsZWQsIGlzRml4ZWQpO1xuICB2YXIgc2Nyb2xsID0ge1xuICAgIHNjcm9sbExlZnQ6IDAsXG4gICAgc2Nyb2xsVG9wOiAwXG4gIH07XG4gIHZhciBvZmZzZXRzID0ge1xuICAgIHg6IDAsXG4gICAgeTogMFxuICB9O1xuXG4gIGlmIChpc09mZnNldFBhcmVudEFuRWxlbWVudCB8fCAhaXNPZmZzZXRQYXJlbnRBbkVsZW1lbnQgJiYgIWlzRml4ZWQpIHtcbiAgICBpZiAoZ2V0Tm9kZU5hbWUob2Zmc2V0UGFyZW50KSAhPT0gJ2JvZHknIHx8IC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9wb3BwZXJqcy9wb3BwZXItY29yZS9pc3N1ZXMvMTA3OFxuICAgIGlzU2Nyb2xsUGFyZW50KGRvY3VtZW50RWxlbWVudCkpIHtcbiAgICAgIHNjcm9sbCA9IGdldE5vZGVTY3JvbGwob2Zmc2V0UGFyZW50KTtcbiAgICB9XG5cbiAgICBpZiAoaXNIVE1MRWxlbWVudChvZmZzZXRQYXJlbnQpKSB7XG4gICAgICBvZmZzZXRzID0gZ2V0Qm91bmRpbmdDbGllbnRSZWN0KG9mZnNldFBhcmVudCwgdHJ1ZSk7XG4gICAgICBvZmZzZXRzLnggKz0gb2Zmc2V0UGFyZW50LmNsaWVudExlZnQ7XG4gICAgICBvZmZzZXRzLnkgKz0gb2Zmc2V0UGFyZW50LmNsaWVudFRvcDtcbiAgICB9IGVsc2UgaWYgKGRvY3VtZW50RWxlbWVudCkge1xuICAgICAgb2Zmc2V0cy54ID0gZ2V0V2luZG93U2Nyb2xsQmFyWChkb2N1bWVudEVsZW1lbnQpO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiB7XG4gICAgeDogcmVjdC5sZWZ0ICsgc2Nyb2xsLnNjcm9sbExlZnQgLSBvZmZzZXRzLngsXG4gICAgeTogcmVjdC50b3AgKyBzY3JvbGwuc2Nyb2xsVG9wIC0gb2Zmc2V0cy55LFxuICAgIHdpZHRoOiByZWN0LndpZHRoLFxuICAgIGhlaWdodDogcmVjdC5oZWlnaHRcbiAgfTtcbn0iLCJpbXBvcnQgeyBtb2RpZmllclBoYXNlcyB9IGZyb20gXCIuLi9lbnVtcy5qc1wiOyAvLyBzb3VyY2U6IGh0dHBzOi8vc3RhY2tvdmVyZmxvdy5jb20vcXVlc3Rpb25zLzQ5ODc1MjU1XG5cbmZ1bmN0aW9uIG9yZGVyKG1vZGlmaWVycykge1xuICB2YXIgbWFwID0gbmV3IE1hcCgpO1xuICB2YXIgdmlzaXRlZCA9IG5ldyBTZXQoKTtcbiAgdmFyIHJlc3VsdCA9IFtdO1xuICBtb2RpZmllcnMuZm9yRWFjaChmdW5jdGlvbiAobW9kaWZpZXIpIHtcbiAgICBtYXAuc2V0KG1vZGlmaWVyLm5hbWUsIG1vZGlmaWVyKTtcbiAgfSk7IC8vIE9uIHZpc2l0aW5nIG9iamVjdCwgY2hlY2sgZm9yIGl0cyBkZXBlbmRlbmNpZXMgYW5kIHZpc2l0IHRoZW0gcmVjdXJzaXZlbHlcblxuICBmdW5jdGlvbiBzb3J0KG1vZGlmaWVyKSB7XG4gICAgdmlzaXRlZC5hZGQobW9kaWZpZXIubmFtZSk7XG4gICAgdmFyIHJlcXVpcmVzID0gW10uY29uY2F0KG1vZGlmaWVyLnJlcXVpcmVzIHx8IFtdLCBtb2RpZmllci5yZXF1aXJlc0lmRXhpc3RzIHx8IFtdKTtcbiAgICByZXF1aXJlcy5mb3JFYWNoKGZ1bmN0aW9uIChkZXApIHtcbiAgICAgIGlmICghdmlzaXRlZC5oYXMoZGVwKSkge1xuICAgICAgICB2YXIgZGVwTW9kaWZpZXIgPSBtYXAuZ2V0KGRlcCk7XG5cbiAgICAgICAgaWYgKGRlcE1vZGlmaWVyKSB7XG4gICAgICAgICAgc29ydChkZXBNb2RpZmllcik7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KTtcbiAgICByZXN1bHQucHVzaChtb2RpZmllcik7XG4gIH1cblxuICBtb2RpZmllcnMuZm9yRWFjaChmdW5jdGlvbiAobW9kaWZpZXIpIHtcbiAgICBpZiAoIXZpc2l0ZWQuaGFzKG1vZGlmaWVyLm5hbWUpKSB7XG4gICAgICAvLyBjaGVjayBmb3IgdmlzaXRlZCBvYmplY3RcbiAgICAgIHNvcnQobW9kaWZpZXIpO1xuICAgIH1cbiAgfSk7XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIG9yZGVyTW9kaWZpZXJzKG1vZGlmaWVycykge1xuICAvLyBvcmRlciBiYXNlZCBvbiBkZXBlbmRlbmNpZXNcbiAgdmFyIG9yZGVyZWRNb2RpZmllcnMgPSBvcmRlcihtb2RpZmllcnMpOyAvLyBvcmRlciBiYXNlZCBvbiBwaGFzZVxuXG4gIHJldHVybiBtb2RpZmllclBoYXNlcy5yZWR1Y2UoZnVuY3Rpb24gKGFjYywgcGhhc2UpIHtcbiAgICByZXR1cm4gYWNjLmNvbmNhdChvcmRlcmVkTW9kaWZpZXJzLmZpbHRlcihmdW5jdGlvbiAobW9kaWZpZXIpIHtcbiAgICAgIHJldHVybiBtb2RpZmllci5waGFzZSA9PT0gcGhhc2U7XG4gICAgfSkpO1xuICB9LCBbXSk7XG59IiwiZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gZGVib3VuY2UoZm4pIHtcbiAgdmFyIHBlbmRpbmc7XG4gIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgaWYgKCFwZW5kaW5nKSB7XG4gICAgICBwZW5kaW5nID0gbmV3IFByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUpIHtcbiAgICAgICAgUHJvbWlzZS5yZXNvbHZlKCkudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgcGVuZGluZyA9IHVuZGVmaW5lZDtcbiAgICAgICAgICByZXNvbHZlKGZuKCkpO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHJldHVybiBwZW5kaW5nO1xuICB9O1xufSIsImV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIG1lcmdlQnlOYW1lKG1vZGlmaWVycykge1xuICB2YXIgbWVyZ2VkID0gbW9kaWZpZXJzLnJlZHVjZShmdW5jdGlvbiAobWVyZ2VkLCBjdXJyZW50KSB7XG4gICAgdmFyIGV4aXN0aW5nID0gbWVyZ2VkW2N1cnJlbnQubmFtZV07XG4gICAgbWVyZ2VkW2N1cnJlbnQubmFtZV0gPSBleGlzdGluZyA/IE9iamVjdC5hc3NpZ24oe30sIGV4aXN0aW5nLCBjdXJyZW50LCB7XG4gICAgICBvcHRpb25zOiBPYmplY3QuYXNzaWduKHt9LCBleGlzdGluZy5vcHRpb25zLCBjdXJyZW50Lm9wdGlvbnMpLFxuICAgICAgZGF0YTogT2JqZWN0LmFzc2lnbih7fSwgZXhpc3RpbmcuZGF0YSwgY3VycmVudC5kYXRhKVxuICAgIH0pIDogY3VycmVudDtcbiAgICByZXR1cm4gbWVyZ2VkO1xuICB9LCB7fSk7IC8vIElFMTEgZG9lcyBub3Qgc3VwcG9ydCBPYmplY3QudmFsdWVzXG5cbiAgcmV0dXJuIE9iamVjdC5rZXlzKG1lcmdlZCkubWFwKGZ1bmN0aW9uIChrZXkpIHtcbiAgICByZXR1cm4gbWVyZ2VkW2tleV07XG4gIH0pO1xufSIsImltcG9ydCBnZXRDb21wb3NpdGVSZWN0IGZyb20gXCIuL2RvbS11dGlscy9nZXRDb21wb3NpdGVSZWN0LmpzXCI7XG5pbXBvcnQgZ2V0TGF5b3V0UmVjdCBmcm9tIFwiLi9kb20tdXRpbHMvZ2V0TGF5b3V0UmVjdC5qc1wiO1xuaW1wb3J0IGxpc3RTY3JvbGxQYXJlbnRzIGZyb20gXCIuL2RvbS11dGlscy9saXN0U2Nyb2xsUGFyZW50cy5qc1wiO1xuaW1wb3J0IGdldE9mZnNldFBhcmVudCBmcm9tIFwiLi9kb20tdXRpbHMvZ2V0T2Zmc2V0UGFyZW50LmpzXCI7XG5pbXBvcnQgb3JkZXJNb2RpZmllcnMgZnJvbSBcIi4vdXRpbHMvb3JkZXJNb2RpZmllcnMuanNcIjtcbmltcG9ydCBkZWJvdW5jZSBmcm9tIFwiLi91dGlscy9kZWJvdW5jZS5qc1wiO1xuaW1wb3J0IG1lcmdlQnlOYW1lIGZyb20gXCIuL3V0aWxzL21lcmdlQnlOYW1lLmpzXCI7XG5pbXBvcnQgZGV0ZWN0T3ZlcmZsb3cgZnJvbSBcIi4vdXRpbHMvZGV0ZWN0T3ZlcmZsb3cuanNcIjtcbmltcG9ydCB7IGlzRWxlbWVudCB9IGZyb20gXCIuL2RvbS11dGlscy9pbnN0YW5jZU9mLmpzXCI7XG52YXIgREVGQVVMVF9PUFRJT05TID0ge1xuICBwbGFjZW1lbnQ6ICdib3R0b20nLFxuICBtb2RpZmllcnM6IFtdLFxuICBzdHJhdGVneTogJ2Fic29sdXRlJ1xufTtcblxuZnVuY3Rpb24gYXJlVmFsaWRFbGVtZW50cygpIHtcbiAgZm9yICh2YXIgX2xlbiA9IGFyZ3VtZW50cy5sZW5ndGgsIGFyZ3MgPSBuZXcgQXJyYXkoX2xlbiksIF9rZXkgPSAwOyBfa2V5IDwgX2xlbjsgX2tleSsrKSB7XG4gICAgYXJnc1tfa2V5XSA9IGFyZ3VtZW50c1tfa2V5XTtcbiAgfVxuXG4gIHJldHVybiAhYXJncy5zb21lKGZ1bmN0aW9uIChlbGVtZW50KSB7XG4gICAgcmV0dXJuICEoZWxlbWVudCAmJiB0eXBlb2YgZWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QgPT09ICdmdW5jdGlvbicpO1xuICB9KTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHBvcHBlckdlbmVyYXRvcihnZW5lcmF0b3JPcHRpb25zKSB7XG4gIGlmIChnZW5lcmF0b3JPcHRpb25zID09PSB2b2lkIDApIHtcbiAgICBnZW5lcmF0b3JPcHRpb25zID0ge307XG4gIH1cblxuICB2YXIgX2dlbmVyYXRvck9wdGlvbnMgPSBnZW5lcmF0b3JPcHRpb25zLFxuICAgICAgX2dlbmVyYXRvck9wdGlvbnMkZGVmID0gX2dlbmVyYXRvck9wdGlvbnMuZGVmYXVsdE1vZGlmaWVycyxcbiAgICAgIGRlZmF1bHRNb2RpZmllcnMgPSBfZ2VuZXJhdG9yT3B0aW9ucyRkZWYgPT09IHZvaWQgMCA/IFtdIDogX2dlbmVyYXRvck9wdGlvbnMkZGVmLFxuICAgICAgX2dlbmVyYXRvck9wdGlvbnMkZGVmMiA9IF9nZW5lcmF0b3JPcHRpb25zLmRlZmF1bHRPcHRpb25zLFxuICAgICAgZGVmYXVsdE9wdGlvbnMgPSBfZ2VuZXJhdG9yT3B0aW9ucyRkZWYyID09PSB2b2lkIDAgPyBERUZBVUxUX09QVElPTlMgOiBfZ2VuZXJhdG9yT3B0aW9ucyRkZWYyO1xuICByZXR1cm4gZnVuY3Rpb24gY3JlYXRlUG9wcGVyKHJlZmVyZW5jZSwgcG9wcGVyLCBvcHRpb25zKSB7XG4gICAgaWYgKG9wdGlvbnMgPT09IHZvaWQgMCkge1xuICAgICAgb3B0aW9ucyA9IGRlZmF1bHRPcHRpb25zO1xuICAgIH1cblxuICAgIHZhciBzdGF0ZSA9IHtcbiAgICAgIHBsYWNlbWVudDogJ2JvdHRvbScsXG4gICAgICBvcmRlcmVkTW9kaWZpZXJzOiBbXSxcbiAgICAgIG9wdGlvbnM6IE9iamVjdC5hc3NpZ24oe30sIERFRkFVTFRfT1BUSU9OUywgZGVmYXVsdE9wdGlvbnMpLFxuICAgICAgbW9kaWZpZXJzRGF0YToge30sXG4gICAgICBlbGVtZW50czoge1xuICAgICAgICByZWZlcmVuY2U6IHJlZmVyZW5jZSxcbiAgICAgICAgcG9wcGVyOiBwb3BwZXJcbiAgICAgIH0sXG4gICAgICBhdHRyaWJ1dGVzOiB7fSxcbiAgICAgIHN0eWxlczoge31cbiAgICB9O1xuICAgIHZhciBlZmZlY3RDbGVhbnVwRm5zID0gW107XG4gICAgdmFyIGlzRGVzdHJveWVkID0gZmFsc2U7XG4gICAgdmFyIGluc3RhbmNlID0ge1xuICAgICAgc3RhdGU6IHN0YXRlLFxuICAgICAgc2V0T3B0aW9uczogZnVuY3Rpb24gc2V0T3B0aW9ucyhzZXRPcHRpb25zQWN0aW9uKSB7XG4gICAgICAgIHZhciBvcHRpb25zID0gdHlwZW9mIHNldE9wdGlvbnNBY3Rpb24gPT09ICdmdW5jdGlvbicgPyBzZXRPcHRpb25zQWN0aW9uKHN0YXRlLm9wdGlvbnMpIDogc2V0T3B0aW9uc0FjdGlvbjtcbiAgICAgICAgY2xlYW51cE1vZGlmaWVyRWZmZWN0cygpO1xuICAgICAgICBzdGF0ZS5vcHRpb25zID0gT2JqZWN0LmFzc2lnbih7fSwgZGVmYXVsdE9wdGlvbnMsIHN0YXRlLm9wdGlvbnMsIG9wdGlvbnMpO1xuICAgICAgICBzdGF0ZS5zY3JvbGxQYXJlbnRzID0ge1xuICAgICAgICAgIHJlZmVyZW5jZTogaXNFbGVtZW50KHJlZmVyZW5jZSkgPyBsaXN0U2Nyb2xsUGFyZW50cyhyZWZlcmVuY2UpIDogcmVmZXJlbmNlLmNvbnRleHRFbGVtZW50ID8gbGlzdFNjcm9sbFBhcmVudHMocmVmZXJlbmNlLmNvbnRleHRFbGVtZW50KSA6IFtdLFxuICAgICAgICAgIHBvcHBlcjogbGlzdFNjcm9sbFBhcmVudHMocG9wcGVyKVxuICAgICAgICB9OyAvLyBPcmRlcnMgdGhlIG1vZGlmaWVycyBiYXNlZCBvbiB0aGVpciBkZXBlbmRlbmNpZXMgYW5kIGBwaGFzZWBcbiAgICAgICAgLy8gcHJvcGVydGllc1xuXG4gICAgICAgIHZhciBvcmRlcmVkTW9kaWZpZXJzID0gb3JkZXJNb2RpZmllcnMobWVyZ2VCeU5hbWUoW10uY29uY2F0KGRlZmF1bHRNb2RpZmllcnMsIHN0YXRlLm9wdGlvbnMubW9kaWZpZXJzKSkpOyAvLyBTdHJpcCBvdXQgZGlzYWJsZWQgbW9kaWZpZXJzXG5cbiAgICAgICAgc3RhdGUub3JkZXJlZE1vZGlmaWVycyA9IG9yZGVyZWRNb2RpZmllcnMuZmlsdGVyKGZ1bmN0aW9uIChtKSB7XG4gICAgICAgICAgcmV0dXJuIG0uZW5hYmxlZDtcbiAgICAgICAgfSk7XG4gICAgICAgIHJ1bk1vZGlmaWVyRWZmZWN0cygpO1xuICAgICAgICByZXR1cm4gaW5zdGFuY2UudXBkYXRlKCk7XG4gICAgICB9LFxuICAgICAgLy8gU3luYyB1cGRhdGUg4oCTIGl0IHdpbGwgYWx3YXlzIGJlIGV4ZWN1dGVkLCBldmVuIGlmIG5vdCBuZWNlc3NhcnkuIFRoaXNcbiAgICAgIC8vIGlzIHVzZWZ1bCBmb3IgbG93IGZyZXF1ZW5jeSB1cGRhdGVzIHdoZXJlIHN5bmMgYmVoYXZpb3Igc2ltcGxpZmllcyB0aGVcbiAgICAgIC8vIGxvZ2ljLlxuICAgICAgLy8gRm9yIGhpZ2ggZnJlcXVlbmN5IHVwZGF0ZXMgKGUuZy4gYHJlc2l6ZWAgYW5kIGBzY3JvbGxgIGV2ZW50cyksIGFsd2F5c1xuICAgICAgLy8gcHJlZmVyIHRoZSBhc3luYyBQb3BwZXIjdXBkYXRlIG1ldGhvZFxuICAgICAgZm9yY2VVcGRhdGU6IGZ1bmN0aW9uIGZvcmNlVXBkYXRlKCkge1xuICAgICAgICBpZiAoaXNEZXN0cm95ZWQpIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgX3N0YXRlJGVsZW1lbnRzID0gc3RhdGUuZWxlbWVudHMsXG4gICAgICAgICAgICByZWZlcmVuY2UgPSBfc3RhdGUkZWxlbWVudHMucmVmZXJlbmNlLFxuICAgICAgICAgICAgcG9wcGVyID0gX3N0YXRlJGVsZW1lbnRzLnBvcHBlcjsgLy8gRG9uJ3QgcHJvY2VlZCBpZiBgcmVmZXJlbmNlYCBvciBgcG9wcGVyYCBhcmUgbm90IHZhbGlkIGVsZW1lbnRzXG4gICAgICAgIC8vIGFueW1vcmVcblxuICAgICAgICBpZiAoIWFyZVZhbGlkRWxlbWVudHMocmVmZXJlbmNlLCBwb3BwZXIpKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9IC8vIFN0b3JlIHRoZSByZWZlcmVuY2UgYW5kIHBvcHBlciByZWN0cyB0byBiZSByZWFkIGJ5IG1vZGlmaWVyc1xuXG5cbiAgICAgICAgc3RhdGUucmVjdHMgPSB7XG4gICAgICAgICAgcmVmZXJlbmNlOiBnZXRDb21wb3NpdGVSZWN0KHJlZmVyZW5jZSwgZ2V0T2Zmc2V0UGFyZW50KHBvcHBlciksIHN0YXRlLm9wdGlvbnMuc3RyYXRlZ3kgPT09ICdmaXhlZCcpLFxuICAgICAgICAgIHBvcHBlcjogZ2V0TGF5b3V0UmVjdChwb3BwZXIpXG4gICAgICAgIH07IC8vIE1vZGlmaWVycyBoYXZlIHRoZSBhYmlsaXR5IHRvIHJlc2V0IHRoZSBjdXJyZW50IHVwZGF0ZSBjeWNsZS4gVGhlXG4gICAgICAgIC8vIG1vc3QgY29tbW9uIHVzZSBjYXNlIGZvciB0aGlzIGlzIHRoZSBgZmxpcGAgbW9kaWZpZXIgY2hhbmdpbmcgdGhlXG4gICAgICAgIC8vIHBsYWNlbWVudCwgd2hpY2ggdGhlbiBuZWVkcyB0byByZS1ydW4gYWxsIHRoZSBtb2RpZmllcnMsIGJlY2F1c2UgdGhlXG4gICAgICAgIC8vIGxvZ2ljIHdhcyBwcmV2aW91c2x5IHJhbiBmb3IgdGhlIHByZXZpb3VzIHBsYWNlbWVudCBhbmQgaXMgdGhlcmVmb3JlXG4gICAgICAgIC8vIHN0YWxlL2luY29ycmVjdFxuXG4gICAgICAgIHN0YXRlLnJlc2V0ID0gZmFsc2U7XG4gICAgICAgIHN0YXRlLnBsYWNlbWVudCA9IHN0YXRlLm9wdGlvbnMucGxhY2VtZW50OyAvLyBPbiBlYWNoIHVwZGF0ZSBjeWNsZSwgdGhlIGBtb2RpZmllcnNEYXRhYCBwcm9wZXJ0eSBmb3IgZWFjaCBtb2RpZmllclxuICAgICAgICAvLyBpcyBmaWxsZWQgd2l0aCB0aGUgaW5pdGlhbCBkYXRhIHNwZWNpZmllZCBieSB0aGUgbW9kaWZpZXIuIFRoaXMgbWVhbnNcbiAgICAgICAgLy8gaXQgZG9lc24ndCBwZXJzaXN0IGFuZCBpcyBmcmVzaCBvbiBlYWNoIHVwZGF0ZS5cbiAgICAgICAgLy8gVG8gZW5zdXJlIHBlcnNpc3RlbnQgZGF0YSwgdXNlIGAke25hbWV9I3BlcnNpc3RlbnRgXG5cbiAgICAgICAgc3RhdGUub3JkZXJlZE1vZGlmaWVycy5mb3JFYWNoKGZ1bmN0aW9uIChtb2RpZmllcikge1xuICAgICAgICAgIHJldHVybiBzdGF0ZS5tb2RpZmllcnNEYXRhW21vZGlmaWVyLm5hbWVdID0gT2JqZWN0LmFzc2lnbih7fSwgbW9kaWZpZXIuZGF0YSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGZvciAodmFyIGluZGV4ID0gMDsgaW5kZXggPCBzdGF0ZS5vcmRlcmVkTW9kaWZpZXJzLmxlbmd0aDsgaW5kZXgrKykge1xuICAgICAgICAgIGlmIChzdGF0ZS5yZXNldCA9PT0gdHJ1ZSkge1xuICAgICAgICAgICAgc3RhdGUucmVzZXQgPSBmYWxzZTtcbiAgICAgICAgICAgIGluZGV4ID0gLTE7XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICB2YXIgX3N0YXRlJG9yZGVyZWRNb2RpZmllID0gc3RhdGUub3JkZXJlZE1vZGlmaWVyc1tpbmRleF0sXG4gICAgICAgICAgICAgIGZuID0gX3N0YXRlJG9yZGVyZWRNb2RpZmllLmZuLFxuICAgICAgICAgICAgICBfc3RhdGUkb3JkZXJlZE1vZGlmaWUyID0gX3N0YXRlJG9yZGVyZWRNb2RpZmllLm9wdGlvbnMsXG4gICAgICAgICAgICAgIF9vcHRpb25zID0gX3N0YXRlJG9yZGVyZWRNb2RpZmllMiA9PT0gdm9pZCAwID8ge30gOiBfc3RhdGUkb3JkZXJlZE1vZGlmaWUyLFxuICAgICAgICAgICAgICBuYW1lID0gX3N0YXRlJG9yZGVyZWRNb2RpZmllLm5hbWU7XG5cbiAgICAgICAgICBpZiAodHlwZW9mIGZuID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICBzdGF0ZSA9IGZuKHtcbiAgICAgICAgICAgICAgc3RhdGU6IHN0YXRlLFxuICAgICAgICAgICAgICBvcHRpb25zOiBfb3B0aW9ucyxcbiAgICAgICAgICAgICAgbmFtZTogbmFtZSxcbiAgICAgICAgICAgICAgaW5zdGFuY2U6IGluc3RhbmNlXG4gICAgICAgICAgICB9KSB8fCBzdGF0ZTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgICAvLyBBc3luYyBhbmQgb3B0aW1pc3RpY2FsbHkgb3B0aW1pemVkIHVwZGF0ZSDigJMgaXQgd2lsbCBub3QgYmUgZXhlY3V0ZWQgaWZcbiAgICAgIC8vIG5vdCBuZWNlc3NhcnkgKGRlYm91bmNlZCB0byBydW4gYXQgbW9zdCBvbmNlLXBlci10aWNrKVxuICAgICAgdXBkYXRlOiBkZWJvdW5jZShmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbiAocmVzb2x2ZSkge1xuICAgICAgICAgIGluc3RhbmNlLmZvcmNlVXBkYXRlKCk7XG4gICAgICAgICAgcmVzb2x2ZShzdGF0ZSk7XG4gICAgICAgIH0pO1xuICAgICAgfSksXG4gICAgICBkZXN0cm95OiBmdW5jdGlvbiBkZXN0cm95KCkge1xuICAgICAgICBjbGVhbnVwTW9kaWZpZXJFZmZlY3RzKCk7XG4gICAgICAgIGlzRGVzdHJveWVkID0gdHJ1ZTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgaWYgKCFhcmVWYWxpZEVsZW1lbnRzKHJlZmVyZW5jZSwgcG9wcGVyKSkge1xuICAgICAgcmV0dXJuIGluc3RhbmNlO1xuICAgIH1cblxuICAgIGluc3RhbmNlLnNldE9wdGlvbnMob3B0aW9ucykudGhlbihmdW5jdGlvbiAoc3RhdGUpIHtcbiAgICAgIGlmICghaXNEZXN0cm95ZWQgJiYgb3B0aW9ucy5vbkZpcnN0VXBkYXRlKSB7XG4gICAgICAgIG9wdGlvbnMub25GaXJzdFVwZGF0ZShzdGF0ZSk7XG4gICAgICB9XG4gICAgfSk7IC8vIE1vZGlmaWVycyBoYXZlIHRoZSBhYmlsaXR5IHRvIGV4ZWN1dGUgYXJiaXRyYXJ5IGNvZGUgYmVmb3JlIHRoZSBmaXJzdFxuICAgIC8vIHVwZGF0ZSBjeWNsZSBydW5zLiBUaGV5IHdpbGwgYmUgZXhlY3V0ZWQgaW4gdGhlIHNhbWUgb3JkZXIgYXMgdGhlIHVwZGF0ZVxuICAgIC8vIGN5Y2xlLiBUaGlzIGlzIHVzZWZ1bCB3aGVuIGEgbW9kaWZpZXIgYWRkcyBzb21lIHBlcnNpc3RlbnQgZGF0YSB0aGF0XG4gICAgLy8gb3RoZXIgbW9kaWZpZXJzIG5lZWQgdG8gdXNlLCBidXQgdGhlIG1vZGlmaWVyIGlzIHJ1biBhZnRlciB0aGUgZGVwZW5kZW50XG4gICAgLy8gb25lLlxuXG4gICAgZnVuY3Rpb24gcnVuTW9kaWZpZXJFZmZlY3RzKCkge1xuICAgICAgc3RhdGUub3JkZXJlZE1vZGlmaWVycy5mb3JFYWNoKGZ1bmN0aW9uIChfcmVmKSB7XG4gICAgICAgIHZhciBuYW1lID0gX3JlZi5uYW1lLFxuICAgICAgICAgICAgX3JlZiRvcHRpb25zID0gX3JlZi5vcHRpb25zLFxuICAgICAgICAgICAgb3B0aW9ucyA9IF9yZWYkb3B0aW9ucyA9PT0gdm9pZCAwID8ge30gOiBfcmVmJG9wdGlvbnMsXG4gICAgICAgICAgICBlZmZlY3QgPSBfcmVmLmVmZmVjdDtcblxuICAgICAgICBpZiAodHlwZW9mIGVmZmVjdCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgIHZhciBjbGVhbnVwRm4gPSBlZmZlY3Qoe1xuICAgICAgICAgICAgc3RhdGU6IHN0YXRlLFxuICAgICAgICAgICAgbmFtZTogbmFtZSxcbiAgICAgICAgICAgIGluc3RhbmNlOiBpbnN0YW5jZSxcbiAgICAgICAgICAgIG9wdGlvbnM6IG9wdGlvbnNcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIHZhciBub29wRm4gPSBmdW5jdGlvbiBub29wRm4oKSB7fTtcblxuICAgICAgICAgIGVmZmVjdENsZWFudXBGbnMucHVzaChjbGVhbnVwRm4gfHwgbm9vcEZuKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gY2xlYW51cE1vZGlmaWVyRWZmZWN0cygpIHtcbiAgICAgIGVmZmVjdENsZWFudXBGbnMuZm9yRWFjaChmdW5jdGlvbiAoZm4pIHtcbiAgICAgICAgcmV0dXJuIGZuKCk7XG4gICAgICB9KTtcbiAgICAgIGVmZmVjdENsZWFudXBGbnMgPSBbXTtcbiAgICB9XG5cbiAgICByZXR1cm4gaW5zdGFuY2U7XG4gIH07XG59XG5leHBvcnQgdmFyIGNyZWF0ZVBvcHBlciA9IC8qI19fUFVSRV9fKi9wb3BwZXJHZW5lcmF0b3IoKTsgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGltcG9ydC9uby11bnVzZWQtbW9kdWxlc1xuXG5leHBvcnQgeyBkZXRlY3RPdmVyZmxvdyB9OyIsImltcG9ydCB7IHBvcHBlckdlbmVyYXRvciwgZGV0ZWN0T3ZlcmZsb3cgfSBmcm9tIFwiLi9jcmVhdGVQb3BwZXIuanNcIjtcbmltcG9ydCBldmVudExpc3RlbmVycyBmcm9tIFwiLi9tb2RpZmllcnMvZXZlbnRMaXN0ZW5lcnMuanNcIjtcbmltcG9ydCBwb3BwZXJPZmZzZXRzIGZyb20gXCIuL21vZGlmaWVycy9wb3BwZXJPZmZzZXRzLmpzXCI7XG5pbXBvcnQgY29tcHV0ZVN0eWxlcyBmcm9tIFwiLi9tb2RpZmllcnMvY29tcHV0ZVN0eWxlcy5qc1wiO1xuaW1wb3J0IGFwcGx5U3R5bGVzIGZyb20gXCIuL21vZGlmaWVycy9hcHBseVN0eWxlcy5qc1wiO1xudmFyIGRlZmF1bHRNb2RpZmllcnMgPSBbZXZlbnRMaXN0ZW5lcnMsIHBvcHBlck9mZnNldHMsIGNvbXB1dGVTdHlsZXMsIGFwcGx5U3R5bGVzXTtcbnZhciBjcmVhdGVQb3BwZXIgPSAvKiNfX1BVUkVfXyovcG9wcGVyR2VuZXJhdG9yKHtcbiAgZGVmYXVsdE1vZGlmaWVyczogZGVmYXVsdE1vZGlmaWVyc1xufSk7IC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBpbXBvcnQvbm8tdW51c2VkLW1vZHVsZXNcblxuZXhwb3J0IHsgY3JlYXRlUG9wcGVyLCBwb3BwZXJHZW5lcmF0b3IsIGRlZmF1bHRNb2RpZmllcnMsIGRldGVjdE92ZXJmbG93IH07IiwiaW1wb3J0IHsgcG9wcGVyR2VuZXJhdG9yLCBkZXRlY3RPdmVyZmxvdyB9IGZyb20gXCIuL2NyZWF0ZVBvcHBlci5qc1wiO1xuaW1wb3J0IGV2ZW50TGlzdGVuZXJzIGZyb20gXCIuL21vZGlmaWVycy9ldmVudExpc3RlbmVycy5qc1wiO1xuaW1wb3J0IHBvcHBlck9mZnNldHMgZnJvbSBcIi4vbW9kaWZpZXJzL3BvcHBlck9mZnNldHMuanNcIjtcbmltcG9ydCBjb21wdXRlU3R5bGVzIGZyb20gXCIuL21vZGlmaWVycy9jb21wdXRlU3R5bGVzLmpzXCI7XG5pbXBvcnQgYXBwbHlTdHlsZXMgZnJvbSBcIi4vbW9kaWZpZXJzL2FwcGx5U3R5bGVzLmpzXCI7XG5pbXBvcnQgb2Zmc2V0IGZyb20gXCIuL21vZGlmaWVycy9vZmZzZXQuanNcIjtcbmltcG9ydCBmbGlwIGZyb20gXCIuL21vZGlmaWVycy9mbGlwLmpzXCI7XG5pbXBvcnQgcHJldmVudE92ZXJmbG93IGZyb20gXCIuL21vZGlmaWVycy9wcmV2ZW50T3ZlcmZsb3cuanNcIjtcbmltcG9ydCBhcnJvdyBmcm9tIFwiLi9tb2RpZmllcnMvYXJyb3cuanNcIjtcbmltcG9ydCBoaWRlIGZyb20gXCIuL21vZGlmaWVycy9oaWRlLmpzXCI7XG52YXIgZGVmYXVsdE1vZGlmaWVycyA9IFtldmVudExpc3RlbmVycywgcG9wcGVyT2Zmc2V0cywgY29tcHV0ZVN0eWxlcywgYXBwbHlTdHlsZXMsIG9mZnNldCwgZmxpcCwgcHJldmVudE92ZXJmbG93LCBhcnJvdywgaGlkZV07XG52YXIgY3JlYXRlUG9wcGVyID0gLyojX19QVVJFX18qL3BvcHBlckdlbmVyYXRvcih7XG4gIGRlZmF1bHRNb2RpZmllcnM6IGRlZmF1bHRNb2RpZmllcnNcbn0pOyAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgaW1wb3J0L25vLXVudXNlZC1tb2R1bGVzXG5cbmV4cG9ydCB7IGNyZWF0ZVBvcHBlciwgcG9wcGVyR2VuZXJhdG9yLCBkZWZhdWx0TW9kaWZpZXJzLCBkZXRlY3RPdmVyZmxvdyB9OyAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgaW1wb3J0L25vLXVudXNlZC1tb2R1bGVzXG5cbmV4cG9ydCB7IGNyZWF0ZVBvcHBlciBhcyBjcmVhdGVQb3BwZXJMaXRlIH0gZnJvbSBcIi4vcG9wcGVyLWxpdGUuanNcIjsgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGltcG9ydC9uby11bnVzZWQtbW9kdWxlc1xuXG5leHBvcnQgKiBmcm9tIFwiLi9tb2RpZmllcnMvaW5kZXguanNcIjsiLCIvKipcbiAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gKiBCb290c3RyYXAgZHJvcGRvd24uanNcbiAqIExpY2Vuc2VkIHVuZGVyIE1JVCAoaHR0cHM6Ly9naXRodWIuY29tL3R3YnMvYm9vdHN0cmFwL2Jsb2IvbWFpbi9MSUNFTlNFKVxuICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAqL1xuXG5pbXBvcnQgKiBhcyBQb3BwZXIgZnJvbSAnQHBvcHBlcmpzL2NvcmUnXG5pbXBvcnQgQmFzZUNvbXBvbmVudCBmcm9tICcuL2Jhc2UtY29tcG9uZW50LmpzJ1xuaW1wb3J0IEV2ZW50SGFuZGxlciBmcm9tICcuL2RvbS9ldmVudC1oYW5kbGVyLmpzJ1xuaW1wb3J0IE1hbmlwdWxhdG9yIGZyb20gJy4vZG9tL21hbmlwdWxhdG9yLmpzJ1xuaW1wb3J0IFNlbGVjdG9yRW5naW5lIGZyb20gJy4vZG9tL3NlbGVjdG9yLWVuZ2luZS5qcydcbmltcG9ydCB7XG4gIGRlZmluZUpRdWVyeVBsdWdpbixcbiAgZXhlY3V0ZSxcbiAgZ2V0RWxlbWVudCxcbiAgZ2V0TmV4dEFjdGl2ZUVsZW1lbnQsXG4gIGlzRGlzYWJsZWQsXG4gIGlzRWxlbWVudCxcbiAgaXNSVEwsXG4gIGlzVmlzaWJsZSxcbiAgbm9vcFxufSBmcm9tICcuL3V0aWwvaW5kZXguanMnXG5cbi8qKlxuICogQ29uc3RhbnRzXG4gKi9cblxuY29uc3QgTkFNRSA9ICdkcm9wZG93bidcbmNvbnN0IERBVEFfS0VZID0gJ2JzLmRyb3Bkb3duJ1xuY29uc3QgRVZFTlRfS0VZID0gYC4ke0RBVEFfS0VZfWBcbmNvbnN0IERBVEFfQVBJX0tFWSA9ICcuZGF0YS1hcGknXG5cbmNvbnN0IEVTQ0FQRV9LRVkgPSAnRXNjYXBlJ1xuY29uc3QgVEFCX0tFWSA9ICdUYWInXG5jb25zdCBBUlJPV19VUF9LRVkgPSAnQXJyb3dVcCdcbmNvbnN0IEFSUk9XX0RPV05fS0VZID0gJ0Fycm93RG93bidcbmNvbnN0IFJJR0hUX01PVVNFX0JVVFRPTiA9IDIgLy8gTW91c2VFdmVudC5idXR0b24gdmFsdWUgZm9yIHRoZSBzZWNvbmRhcnkgYnV0dG9uLCB1c3VhbGx5IHRoZSByaWdodCBidXR0b25cblxuY29uc3QgRVZFTlRfSElERSA9IGBoaWRlJHtFVkVOVF9LRVl9YFxuY29uc3QgRVZFTlRfSElEREVOID0gYGhpZGRlbiR7RVZFTlRfS0VZfWBcbmNvbnN0IEVWRU5UX1NIT1cgPSBgc2hvdyR7RVZFTlRfS0VZfWBcbmNvbnN0IEVWRU5UX1NIT1dOID0gYHNob3duJHtFVkVOVF9LRVl9YFxuY29uc3QgRVZFTlRfQ0xJQ0tfREFUQV9BUEkgPSBgY2xpY2ske0VWRU5UX0tFWX0ke0RBVEFfQVBJX0tFWX1gXG5jb25zdCBFVkVOVF9LRVlET1dOX0RBVEFfQVBJID0gYGtleWRvd24ke0VWRU5UX0tFWX0ke0RBVEFfQVBJX0tFWX1gXG5jb25zdCBFVkVOVF9LRVlVUF9EQVRBX0FQSSA9IGBrZXl1cCR7RVZFTlRfS0VZfSR7REFUQV9BUElfS0VZfWBcblxuY29uc3QgQ0xBU1NfTkFNRV9TSE9XID0gJ3Nob3cnXG5jb25zdCBDTEFTU19OQU1FX0RST1BVUCA9ICdkcm9wdXAnXG5jb25zdCBDTEFTU19OQU1FX0RST1BFTkQgPSAnZHJvcGVuZCdcbmNvbnN0IENMQVNTX05BTUVfRFJPUFNUQVJUID0gJ2Ryb3BzdGFydCdcbmNvbnN0IENMQVNTX05BTUVfRFJPUFVQX0NFTlRFUiA9ICdkcm9wdXAtY2VudGVyJ1xuY29uc3QgQ0xBU1NfTkFNRV9EUk9QRE9XTl9DRU5URVIgPSAnZHJvcGRvd24tY2VudGVyJ1xuXG5jb25zdCBTRUxFQ1RPUl9EQVRBX1RPR0dMRSA9ICdbZGF0YS1icy10b2dnbGU9XCJkcm9wZG93blwiXTpub3QoLmRpc2FibGVkKTpub3QoOmRpc2FibGVkKSdcbmNvbnN0IFNFTEVDVE9SX0RBVEFfVE9HR0xFX1NIT1dOID0gYCR7U0VMRUNUT1JfREFUQV9UT0dHTEV9LiR7Q0xBU1NfTkFNRV9TSE9XfWBcbmNvbnN0IFNFTEVDVE9SX01FTlUgPSAnLmRyb3Bkb3duLW1lbnUnXG5jb25zdCBTRUxFQ1RPUl9OQVZCQVIgPSAnLm5hdmJhcidcbmNvbnN0IFNFTEVDVE9SX05BVkJBUl9OQVYgPSAnLm5hdmJhci1uYXYnXG5jb25zdCBTRUxFQ1RPUl9WSVNJQkxFX0lURU1TID0gJy5kcm9wZG93bi1tZW51IC5kcm9wZG93bi1pdGVtOm5vdCguZGlzYWJsZWQpOm5vdCg6ZGlzYWJsZWQpJ1xuXG5jb25zdCBQTEFDRU1FTlRfVE9QID0gaXNSVEwoKSA/ICd0b3AtZW5kJyA6ICd0b3Atc3RhcnQnXG5jb25zdCBQTEFDRU1FTlRfVE9QRU5EID0gaXNSVEwoKSA/ICd0b3Atc3RhcnQnIDogJ3RvcC1lbmQnXG5jb25zdCBQTEFDRU1FTlRfQk9UVE9NID0gaXNSVEwoKSA/ICdib3R0b20tZW5kJyA6ICdib3R0b20tc3RhcnQnXG5jb25zdCBQTEFDRU1FTlRfQk9UVE9NRU5EID0gaXNSVEwoKSA/ICdib3R0b20tc3RhcnQnIDogJ2JvdHRvbS1lbmQnXG5jb25zdCBQTEFDRU1FTlRfUklHSFQgPSBpc1JUTCgpID8gJ2xlZnQtc3RhcnQnIDogJ3JpZ2h0LXN0YXJ0J1xuY29uc3QgUExBQ0VNRU5UX0xFRlQgPSBpc1JUTCgpID8gJ3JpZ2h0LXN0YXJ0JyA6ICdsZWZ0LXN0YXJ0J1xuY29uc3QgUExBQ0VNRU5UX1RPUENFTlRFUiA9ICd0b3AnXG5jb25zdCBQTEFDRU1FTlRfQk9UVE9NQ0VOVEVSID0gJ2JvdHRvbSdcblxuY29uc3QgRGVmYXVsdCA9IHtcbiAgYXV0b0Nsb3NlOiB0cnVlLFxuICBib3VuZGFyeTogJ2NsaXBwaW5nUGFyZW50cycsXG4gIGRpc3BsYXk6ICdkeW5hbWljJyxcbiAgb2Zmc2V0OiBbMCwgMl0sXG4gIHBvcHBlckNvbmZpZzogbnVsbCxcbiAgcmVmZXJlbmNlOiAndG9nZ2xlJ1xufVxuXG5jb25zdCBEZWZhdWx0VHlwZSA9IHtcbiAgYXV0b0Nsb3NlOiAnKGJvb2xlYW58c3RyaW5nKScsXG4gIGJvdW5kYXJ5OiAnKHN0cmluZ3xlbGVtZW50KScsXG4gIGRpc3BsYXk6ICdzdHJpbmcnLFxuICBvZmZzZXQ6ICcoYXJyYXl8c3RyaW5nfGZ1bmN0aW9uKScsXG4gIHBvcHBlckNvbmZpZzogJyhudWxsfG9iamVjdHxmdW5jdGlvbiknLFxuICByZWZlcmVuY2U6ICcoc3RyaW5nfGVsZW1lbnR8b2JqZWN0KSdcbn1cblxuLyoqXG4gKiBDbGFzcyBkZWZpbml0aW9uXG4gKi9cblxuY2xhc3MgRHJvcGRvd24gZXh0ZW5kcyBCYXNlQ29tcG9uZW50IHtcbiAgY29uc3RydWN0b3IoZWxlbWVudCwgY29uZmlnKSB7XG4gICAgc3VwZXIoZWxlbWVudCwgY29uZmlnKVxuXG4gICAgdGhpcy5fcG9wcGVyID0gbnVsbFxuICAgIHRoaXMuX3BhcmVudCA9IHRoaXMuX2VsZW1lbnQucGFyZW50Tm9kZSAvLyBkcm9wZG93biB3cmFwcGVyXG4gICAgLy8gVE9ETzogdjYgcmV2ZXJ0ICMzNzAxMSAmIGNoYW5nZSBtYXJrdXAgaHR0cHM6Ly9nZXRib290c3RyYXAuY29tL2RvY3MvNS4zL2Zvcm1zL2lucHV0LWdyb3VwL1xuICAgIHRoaXMuX21lbnUgPSBTZWxlY3RvckVuZ2luZS5uZXh0KHRoaXMuX2VsZW1lbnQsIFNFTEVDVE9SX01FTlUpWzBdIHx8XG4gICAgICBTZWxlY3RvckVuZ2luZS5wcmV2KHRoaXMuX2VsZW1lbnQsIFNFTEVDVE9SX01FTlUpWzBdIHx8XG4gICAgICBTZWxlY3RvckVuZ2luZS5maW5kT25lKFNFTEVDVE9SX01FTlUsIHRoaXMuX3BhcmVudClcbiAgICB0aGlzLl9pbk5hdmJhciA9IHRoaXMuX2RldGVjdE5hdmJhcigpXG4gIH1cblxuICAvLyBHZXR0ZXJzXG4gIHN0YXRpYyBnZXQgRGVmYXVsdCgpIHtcbiAgICByZXR1cm4gRGVmYXVsdFxuICB9XG5cbiAgc3RhdGljIGdldCBEZWZhdWx0VHlwZSgpIHtcbiAgICByZXR1cm4gRGVmYXVsdFR5cGVcbiAgfVxuXG4gIHN0YXRpYyBnZXQgTkFNRSgpIHtcbiAgICByZXR1cm4gTkFNRVxuICB9XG5cbiAgLy8gUHVibGljXG4gIHRvZ2dsZSgpIHtcbiAgICByZXR1cm4gdGhpcy5faXNTaG93bigpID8gdGhpcy5oaWRlKCkgOiB0aGlzLnNob3coKVxuICB9XG5cbiAgc2hvdygpIHtcbiAgICBpZiAoaXNEaXNhYmxlZCh0aGlzLl9lbGVtZW50KSB8fCB0aGlzLl9pc1Nob3duKCkpIHtcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIGNvbnN0IHJlbGF0ZWRUYXJnZXQgPSB7XG4gICAgICByZWxhdGVkVGFyZ2V0OiB0aGlzLl9lbGVtZW50XG4gICAgfVxuXG4gICAgY29uc3Qgc2hvd0V2ZW50ID0gRXZlbnRIYW5kbGVyLnRyaWdnZXIodGhpcy5fZWxlbWVudCwgRVZFTlRfU0hPVywgcmVsYXRlZFRhcmdldClcblxuICAgIGlmIChzaG93RXZlbnQuZGVmYXVsdFByZXZlbnRlZCkge1xuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgdGhpcy5fY3JlYXRlUG9wcGVyKClcblxuICAgIC8vIElmIHRoaXMgaXMgYSB0b3VjaC1lbmFibGVkIGRldmljZSB3ZSBhZGQgZXh0cmFcbiAgICAvLyBlbXB0eSBtb3VzZW92ZXIgbGlzdGVuZXJzIHRvIHRoZSBib2R5J3MgaW1tZWRpYXRlIGNoaWxkcmVuO1xuICAgIC8vIG9ubHkgbmVlZGVkIGJlY2F1c2Ugb2YgYnJva2VuIGV2ZW50IGRlbGVnYXRpb24gb24gaU9TXG4gICAgLy8gaHR0cHM6Ly93d3cucXVpcmtzbW9kZS5vcmcvYmxvZy9hcmNoaXZlcy8yMDE0LzAyL21vdXNlX2V2ZW50X2J1Yi5odG1sXG4gICAgaWYgKCdvbnRvdWNoc3RhcnQnIGluIGRvY3VtZW50LmRvY3VtZW50RWxlbWVudCAmJiAhdGhpcy5fcGFyZW50LmNsb3Nlc3QoU0VMRUNUT1JfTkFWQkFSX05BVikpIHtcbiAgICAgIGZvciAoY29uc3QgZWxlbWVudCBvZiBbXS5jb25jYXQoLi4uZG9jdW1lbnQuYm9keS5jaGlsZHJlbikpIHtcbiAgICAgICAgRXZlbnRIYW5kbGVyLm9uKGVsZW1lbnQsICdtb3VzZW92ZXInLCBub29wKVxuICAgICAgfVxuICAgIH1cblxuICAgIHRoaXMuX2VsZW1lbnQuZm9jdXMoKVxuICAgIHRoaXMuX2VsZW1lbnQuc2V0QXR0cmlidXRlKCdhcmlhLWV4cGFuZGVkJywgdHJ1ZSlcblxuICAgIHRoaXMuX21lbnUuY2xhc3NMaXN0LmFkZChDTEFTU19OQU1FX1NIT1cpXG4gICAgdGhpcy5fZWxlbWVudC5jbGFzc0xpc3QuYWRkKENMQVNTX05BTUVfU0hPVylcbiAgICBFdmVudEhhbmRsZXIudHJpZ2dlcih0aGlzLl9lbGVtZW50LCBFVkVOVF9TSE9XTiwgcmVsYXRlZFRhcmdldClcbiAgfVxuXG4gIGhpZGUoKSB7XG4gICAgaWYgKGlzRGlzYWJsZWQodGhpcy5fZWxlbWVudCkgfHwgIXRoaXMuX2lzU2hvd24oKSkge1xuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgY29uc3QgcmVsYXRlZFRhcmdldCA9IHtcbiAgICAgIHJlbGF0ZWRUYXJnZXQ6IHRoaXMuX2VsZW1lbnRcbiAgICB9XG5cbiAgICB0aGlzLl9jb21wbGV0ZUhpZGUocmVsYXRlZFRhcmdldClcbiAgfVxuXG4gIGRpc3Bvc2UoKSB7XG4gICAgaWYgKHRoaXMuX3BvcHBlcikge1xuICAgICAgdGhpcy5fcG9wcGVyLmRlc3Ryb3koKVxuICAgIH1cblxuICAgIHN1cGVyLmRpc3Bvc2UoKVxuICB9XG5cbiAgdXBkYXRlKCkge1xuICAgIHRoaXMuX2luTmF2YmFyID0gdGhpcy5fZGV0ZWN0TmF2YmFyKClcbiAgICBpZiAodGhpcy5fcG9wcGVyKSB7XG4gICAgICB0aGlzLl9wb3BwZXIudXBkYXRlKClcbiAgICB9XG4gIH1cblxuICAvLyBQcml2YXRlXG4gIF9jb21wbGV0ZUhpZGUocmVsYXRlZFRhcmdldCkge1xuICAgIGNvbnN0IGhpZGVFdmVudCA9IEV2ZW50SGFuZGxlci50cmlnZ2VyKHRoaXMuX2VsZW1lbnQsIEVWRU5UX0hJREUsIHJlbGF0ZWRUYXJnZXQpXG4gICAgaWYgKGhpZGVFdmVudC5kZWZhdWx0UHJldmVudGVkKSB7XG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICAvLyBJZiB0aGlzIGlzIGEgdG91Y2gtZW5hYmxlZCBkZXZpY2Ugd2UgcmVtb3ZlIHRoZSBleHRyYVxuICAgIC8vIGVtcHR5IG1vdXNlb3ZlciBsaXN0ZW5lcnMgd2UgYWRkZWQgZm9yIGlPUyBzdXBwb3J0XG4gICAgaWYgKCdvbnRvdWNoc3RhcnQnIGluIGRvY3VtZW50LmRvY3VtZW50RWxlbWVudCkge1xuICAgICAgZm9yIChjb25zdCBlbGVtZW50IG9mIFtdLmNvbmNhdCguLi5kb2N1bWVudC5ib2R5LmNoaWxkcmVuKSkge1xuICAgICAgICBFdmVudEhhbmRsZXIub2ZmKGVsZW1lbnQsICdtb3VzZW92ZXInLCBub29wKVxuICAgICAgfVxuICAgIH1cblxuICAgIGlmICh0aGlzLl9wb3BwZXIpIHtcbiAgICAgIHRoaXMuX3BvcHBlci5kZXN0cm95KClcbiAgICB9XG5cbiAgICB0aGlzLl9tZW51LmNsYXNzTGlzdC5yZW1vdmUoQ0xBU1NfTkFNRV9TSE9XKVxuICAgIHRoaXMuX2VsZW1lbnQuY2xhc3NMaXN0LnJlbW92ZShDTEFTU19OQU1FX1NIT1cpXG4gICAgdGhpcy5fZWxlbWVudC5zZXRBdHRyaWJ1dGUoJ2FyaWEtZXhwYW5kZWQnLCAnZmFsc2UnKVxuICAgIE1hbmlwdWxhdG9yLnJlbW92ZURhdGFBdHRyaWJ1dGUodGhpcy5fbWVudSwgJ3BvcHBlcicpXG4gICAgRXZlbnRIYW5kbGVyLnRyaWdnZXIodGhpcy5fZWxlbWVudCwgRVZFTlRfSElEREVOLCByZWxhdGVkVGFyZ2V0KVxuICB9XG5cbiAgX2dldENvbmZpZyhjb25maWcpIHtcbiAgICBjb25maWcgPSBzdXBlci5fZ2V0Q29uZmlnKGNvbmZpZylcblxuICAgIGlmICh0eXBlb2YgY29uZmlnLnJlZmVyZW5jZSA9PT0gJ29iamVjdCcgJiYgIWlzRWxlbWVudChjb25maWcucmVmZXJlbmNlKSAmJlxuICAgICAgdHlwZW9mIGNvbmZpZy5yZWZlcmVuY2UuZ2V0Qm91bmRpbmdDbGllbnRSZWN0ICE9PSAnZnVuY3Rpb24nXG4gICAgKSB7XG4gICAgICAvLyBQb3BwZXIgdmlydHVhbCBlbGVtZW50cyByZXF1aXJlIGEgZ2V0Qm91bmRpbmdDbGllbnRSZWN0IG1ldGhvZFxuICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihgJHtOQU1FLnRvVXBwZXJDYXNlKCl9OiBPcHRpb24gXCJyZWZlcmVuY2VcIiBwcm92aWRlZCB0eXBlIFwib2JqZWN0XCIgd2l0aG91dCBhIHJlcXVpcmVkIFwiZ2V0Qm91bmRpbmdDbGllbnRSZWN0XCIgbWV0aG9kLmApXG4gICAgfVxuXG4gICAgcmV0dXJuIGNvbmZpZ1xuICB9XG5cbiAgX2NyZWF0ZVBvcHBlcigpIHtcbiAgICBpZiAodHlwZW9mIFBvcHBlciA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0Jvb3RzdHJhcFxcJ3MgZHJvcGRvd25zIHJlcXVpcmUgUG9wcGVyIChodHRwczovL3BvcHBlci5qcy5vcmcpJylcbiAgICB9XG5cbiAgICBsZXQgcmVmZXJlbmNlRWxlbWVudCA9IHRoaXMuX2VsZW1lbnRcblxuICAgIGlmICh0aGlzLl9jb25maWcucmVmZXJlbmNlID09PSAncGFyZW50Jykge1xuICAgICAgcmVmZXJlbmNlRWxlbWVudCA9IHRoaXMuX3BhcmVudFxuICAgIH0gZWxzZSBpZiAoaXNFbGVtZW50KHRoaXMuX2NvbmZpZy5yZWZlcmVuY2UpKSB7XG4gICAgICByZWZlcmVuY2VFbGVtZW50ID0gZ2V0RWxlbWVudCh0aGlzLl9jb25maWcucmVmZXJlbmNlKVxuICAgIH0gZWxzZSBpZiAodHlwZW9mIHRoaXMuX2NvbmZpZy5yZWZlcmVuY2UgPT09ICdvYmplY3QnKSB7XG4gICAgICByZWZlcmVuY2VFbGVtZW50ID0gdGhpcy5fY29uZmlnLnJlZmVyZW5jZVxuICAgIH1cblxuICAgIGNvbnN0IHBvcHBlckNvbmZpZyA9IHRoaXMuX2dldFBvcHBlckNvbmZpZygpXG4gICAgdGhpcy5fcG9wcGVyID0gUG9wcGVyLmNyZWF0ZVBvcHBlcihyZWZlcmVuY2VFbGVtZW50LCB0aGlzLl9tZW51LCBwb3BwZXJDb25maWcpXG4gIH1cblxuICBfaXNTaG93bigpIHtcbiAgICByZXR1cm4gdGhpcy5fbWVudS5jbGFzc0xpc3QuY29udGFpbnMoQ0xBU1NfTkFNRV9TSE9XKVxuICB9XG5cbiAgX2dldFBsYWNlbWVudCgpIHtcbiAgICBjb25zdCBwYXJlbnREcm9wZG93biA9IHRoaXMuX3BhcmVudFxuXG4gICAgaWYgKHBhcmVudERyb3Bkb3duLmNsYXNzTGlzdC5jb250YWlucyhDTEFTU19OQU1FX0RST1BFTkQpKSB7XG4gICAgICByZXR1cm4gUExBQ0VNRU5UX1JJR0hUXG4gICAgfVxuXG4gICAgaWYgKHBhcmVudERyb3Bkb3duLmNsYXNzTGlzdC5jb250YWlucyhDTEFTU19OQU1FX0RST1BTVEFSVCkpIHtcbiAgICAgIHJldHVybiBQTEFDRU1FTlRfTEVGVFxuICAgIH1cblxuICAgIGlmIChwYXJlbnREcm9wZG93bi5jbGFzc0xpc3QuY29udGFpbnMoQ0xBU1NfTkFNRV9EUk9QVVBfQ0VOVEVSKSkge1xuICAgICAgcmV0dXJuIFBMQUNFTUVOVF9UT1BDRU5URVJcbiAgICB9XG5cbiAgICBpZiAocGFyZW50RHJvcGRvd24uY2xhc3NMaXN0LmNvbnRhaW5zKENMQVNTX05BTUVfRFJPUERPV05fQ0VOVEVSKSkge1xuICAgICAgcmV0dXJuIFBMQUNFTUVOVF9CT1RUT01DRU5URVJcbiAgICB9XG5cbiAgICAvLyBXZSBuZWVkIHRvIHRyaW0gdGhlIHZhbHVlIGJlY2F1c2UgY3VzdG9tIHByb3BlcnRpZXMgY2FuIGFsc28gaW5jbHVkZSBzcGFjZXNcbiAgICBjb25zdCBpc0VuZCA9IGdldENvbXB1dGVkU3R5bGUodGhpcy5fbWVudSkuZ2V0UHJvcGVydHlWYWx1ZSgnLS1icy1wb3NpdGlvbicpLnRyaW0oKSA9PT0gJ2VuZCdcblxuICAgIGlmIChwYXJlbnREcm9wZG93bi5jbGFzc0xpc3QuY29udGFpbnMoQ0xBU1NfTkFNRV9EUk9QVVApKSB7XG4gICAgICByZXR1cm4gaXNFbmQgPyBQTEFDRU1FTlRfVE9QRU5EIDogUExBQ0VNRU5UX1RPUFxuICAgIH1cblxuICAgIHJldHVybiBpc0VuZCA/IFBMQUNFTUVOVF9CT1RUT01FTkQgOiBQTEFDRU1FTlRfQk9UVE9NXG4gIH1cblxuICBfZGV0ZWN0TmF2YmFyKCkge1xuICAgIHJldHVybiB0aGlzLl9lbGVtZW50LmNsb3Nlc3QoU0VMRUNUT1JfTkFWQkFSKSAhPT0gbnVsbFxuICB9XG5cbiAgX2dldE9mZnNldCgpIHtcbiAgICBjb25zdCB7IG9mZnNldCB9ID0gdGhpcy5fY29uZmlnXG5cbiAgICBpZiAodHlwZW9mIG9mZnNldCA9PT0gJ3N0cmluZycpIHtcbiAgICAgIHJldHVybiBvZmZzZXQuc3BsaXQoJywnKS5tYXAodmFsdWUgPT4gTnVtYmVyLnBhcnNlSW50KHZhbHVlLCAxMCkpXG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBvZmZzZXQgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIHJldHVybiBwb3BwZXJEYXRhID0+IG9mZnNldChwb3BwZXJEYXRhLCB0aGlzLl9lbGVtZW50KVxuICAgIH1cblxuICAgIHJldHVybiBvZmZzZXRcbiAgfVxuXG4gIF9nZXRQb3BwZXJDb25maWcoKSB7XG4gICAgY29uc3QgZGVmYXVsdEJzUG9wcGVyQ29uZmlnID0ge1xuICAgICAgcGxhY2VtZW50OiB0aGlzLl9nZXRQbGFjZW1lbnQoKSxcbiAgICAgIG1vZGlmaWVyczogW3tcbiAgICAgICAgbmFtZTogJ3ByZXZlbnRPdmVyZmxvdycsXG4gICAgICAgIG9wdGlvbnM6IHtcbiAgICAgICAgICBib3VuZGFyeTogdGhpcy5fY29uZmlnLmJvdW5kYXJ5XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIG5hbWU6ICdvZmZzZXQnLFxuICAgICAgICBvcHRpb25zOiB7XG4gICAgICAgICAgb2Zmc2V0OiB0aGlzLl9nZXRPZmZzZXQoKVxuICAgICAgICB9XG4gICAgICB9XVxuICAgIH1cblxuICAgIC8vIERpc2FibGUgUG9wcGVyIGlmIHdlIGhhdmUgYSBzdGF0aWMgZGlzcGxheSBvciBEcm9wZG93biBpcyBpbiBOYXZiYXJcbiAgICBpZiAodGhpcy5faW5OYXZiYXIgfHwgdGhpcy5fY29uZmlnLmRpc3BsYXkgPT09ICdzdGF0aWMnKSB7XG4gICAgICBNYW5pcHVsYXRvci5zZXREYXRhQXR0cmlidXRlKHRoaXMuX21lbnUsICdwb3BwZXInLCAnc3RhdGljJykgLy8gVE9ETzogdjYgcmVtb3ZlXG4gICAgICBkZWZhdWx0QnNQb3BwZXJDb25maWcubW9kaWZpZXJzID0gW3tcbiAgICAgICAgbmFtZTogJ2FwcGx5U3R5bGVzJyxcbiAgICAgICAgZW5hYmxlZDogZmFsc2VcbiAgICAgIH1dXG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIC4uLmRlZmF1bHRCc1BvcHBlckNvbmZpZyxcbiAgICAgIC4uLmV4ZWN1dGUodGhpcy5fY29uZmlnLnBvcHBlckNvbmZpZywgW2RlZmF1bHRCc1BvcHBlckNvbmZpZ10pXG4gICAgfVxuICB9XG5cbiAgX3NlbGVjdE1lbnVJdGVtKHsga2V5LCB0YXJnZXQgfSkge1xuICAgIGNvbnN0IGl0ZW1zID0gU2VsZWN0b3JFbmdpbmUuZmluZChTRUxFQ1RPUl9WSVNJQkxFX0lURU1TLCB0aGlzLl9tZW51KS5maWx0ZXIoZWxlbWVudCA9PiBpc1Zpc2libGUoZWxlbWVudCkpXG5cbiAgICBpZiAoIWl0ZW1zLmxlbmd0aCkge1xuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgLy8gaWYgdGFyZ2V0IGlzbid0IGluY2x1ZGVkIGluIGl0ZW1zIChlLmcuIHdoZW4gZXhwYW5kaW5nIHRoZSBkcm9wZG93bilcbiAgICAvLyBhbGxvdyBjeWNsaW5nIHRvIGdldCB0aGUgbGFzdCBpdGVtIGluIGNhc2Uga2V5IGVxdWFscyBBUlJPV19VUF9LRVlcbiAgICBnZXROZXh0QWN0aXZlRWxlbWVudChpdGVtcywgdGFyZ2V0LCBrZXkgPT09IEFSUk9XX0RPV05fS0VZLCAhaXRlbXMuaW5jbHVkZXModGFyZ2V0KSkuZm9jdXMoKVxuICB9XG5cbiAgLy8gU3RhdGljXG4gIHN0YXRpYyBqUXVlcnlJbnRlcmZhY2UoY29uZmlnKSB7XG4gICAgcmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBkYXRhID0gRHJvcGRvd24uZ2V0T3JDcmVhdGVJbnN0YW5jZSh0aGlzLCBjb25maWcpXG5cbiAgICAgIGlmICh0eXBlb2YgY29uZmlnICE9PSAnc3RyaW5nJykge1xuICAgICAgICByZXR1cm5cbiAgICAgIH1cblxuICAgICAgaWYgKHR5cGVvZiBkYXRhW2NvbmZpZ10gPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoYE5vIG1ldGhvZCBuYW1lZCBcIiR7Y29uZmlnfVwiYClcbiAgICAgIH1cblxuICAgICAgZGF0YVtjb25maWddKClcbiAgICB9KVxuICB9XG5cbiAgc3RhdGljIGNsZWFyTWVudXMoZXZlbnQpIHtcbiAgICBpZiAoZXZlbnQuYnV0dG9uID09PSBSSUdIVF9NT1VTRV9CVVRUT04gfHwgKGV2ZW50LnR5cGUgPT09ICdrZXl1cCcgJiYgZXZlbnQua2V5ICE9PSBUQUJfS0VZKSkge1xuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgY29uc3Qgb3BlblRvZ2dsZXMgPSBTZWxlY3RvckVuZ2luZS5maW5kKFNFTEVDVE9SX0RBVEFfVE9HR0xFX1NIT1dOKVxuXG4gICAgZm9yIChjb25zdCB0b2dnbGUgb2Ygb3BlblRvZ2dsZXMpIHtcbiAgICAgIGNvbnN0IGNvbnRleHQgPSBEcm9wZG93bi5nZXRJbnN0YW5jZSh0b2dnbGUpXG4gICAgICBpZiAoIWNvbnRleHQgfHwgY29udGV4dC5fY29uZmlnLmF1dG9DbG9zZSA9PT0gZmFsc2UpIHtcbiAgICAgICAgY29udGludWVcbiAgICAgIH1cblxuICAgICAgY29uc3QgY29tcG9zZWRQYXRoID0gZXZlbnQuY29tcG9zZWRQYXRoKClcbiAgICAgIGNvbnN0IGlzTWVudVRhcmdldCA9IGNvbXBvc2VkUGF0aC5pbmNsdWRlcyhjb250ZXh0Ll9tZW51KVxuICAgICAgaWYgKFxuICAgICAgICBjb21wb3NlZFBhdGguaW5jbHVkZXMoY29udGV4dC5fZWxlbWVudCkgfHxcbiAgICAgICAgKGNvbnRleHQuX2NvbmZpZy5hdXRvQ2xvc2UgPT09ICdpbnNpZGUnICYmICFpc01lbnVUYXJnZXQpIHx8XG4gICAgICAgIChjb250ZXh0Ll9jb25maWcuYXV0b0Nsb3NlID09PSAnb3V0c2lkZScgJiYgaXNNZW51VGFyZ2V0KVxuICAgICAgKSB7XG4gICAgICAgIGNvbnRpbnVlXG4gICAgICB9XG5cbiAgICAgIC8vIFRhYiBuYXZpZ2F0aW9uIHRocm91Z2ggdGhlIGRyb3Bkb3duIG1lbnUgb3IgZXZlbnRzIGZyb20gY29udGFpbmVkIGlucHV0cyBzaG91bGRuJ3QgY2xvc2UgdGhlIG1lbnVcbiAgICAgIGlmIChjb250ZXh0Ll9tZW51LmNvbnRhaW5zKGV2ZW50LnRhcmdldCkgJiYgKChldmVudC50eXBlID09PSAna2V5dXAnICYmIGV2ZW50LmtleSA9PT0gVEFCX0tFWSkgfHwgL2lucHV0fHNlbGVjdHxvcHRpb258dGV4dGFyZWF8Zm9ybS9pLnRlc3QoZXZlbnQudGFyZ2V0LnRhZ05hbWUpKSkge1xuICAgICAgICBjb250aW51ZVxuICAgICAgfVxuXG4gICAgICBjb25zdCByZWxhdGVkVGFyZ2V0ID0geyByZWxhdGVkVGFyZ2V0OiBjb250ZXh0Ll9lbGVtZW50IH1cblxuICAgICAgaWYgKGV2ZW50LnR5cGUgPT09ICdjbGljaycpIHtcbiAgICAgICAgcmVsYXRlZFRhcmdldC5jbGlja0V2ZW50ID0gZXZlbnRcbiAgICAgIH1cblxuICAgICAgY29udGV4dC5fY29tcGxldGVIaWRlKHJlbGF0ZWRUYXJnZXQpXG4gICAgfVxuICB9XG5cbiAgc3RhdGljIGRhdGFBcGlLZXlkb3duSGFuZGxlcihldmVudCkge1xuICAgIC8vIElmIG5vdCBhbiBVUCB8IERPV04gfCBFU0NBUEUga2V5ID0+IG5vdCBhIGRyb3Bkb3duIGNvbW1hbmRcbiAgICAvLyBJZiBpbnB1dC90ZXh0YXJlYSAmJiBpZiBrZXkgaXMgb3RoZXIgdGhhbiBFU0NBUEUgPT4gbm90IGEgZHJvcGRvd24gY29tbWFuZFxuXG4gICAgY29uc3QgaXNJbnB1dCA9IC9pbnB1dHx0ZXh0YXJlYS9pLnRlc3QoZXZlbnQudGFyZ2V0LnRhZ05hbWUpXG4gICAgY29uc3QgaXNFc2NhcGVFdmVudCA9IGV2ZW50LmtleSA9PT0gRVNDQVBFX0tFWVxuICAgIGNvbnN0IGlzVXBPckRvd25FdmVudCA9IFtBUlJPV19VUF9LRVksIEFSUk9XX0RPV05fS0VZXS5pbmNsdWRlcyhldmVudC5rZXkpXG5cbiAgICBpZiAoIWlzVXBPckRvd25FdmVudCAmJiAhaXNFc2NhcGVFdmVudCkge1xuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgaWYgKGlzSW5wdXQgJiYgIWlzRXNjYXBlRXZlbnQpIHtcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KClcblxuICAgIC8vIFRPRE86IHY2IHJldmVydCAjMzcwMTEgJiBjaGFuZ2UgbWFya3VwIGh0dHBzOi8vZ2V0Ym9vdHN0cmFwLmNvbS9kb2NzLzUuMy9mb3Jtcy9pbnB1dC1ncm91cC9cbiAgICBjb25zdCBnZXRUb2dnbGVCdXR0b24gPSB0aGlzLm1hdGNoZXMoU0VMRUNUT1JfREFUQV9UT0dHTEUpID9cbiAgICAgIHRoaXMgOlxuICAgICAgKFNlbGVjdG9yRW5naW5lLnByZXYodGhpcywgU0VMRUNUT1JfREFUQV9UT0dHTEUpWzBdIHx8XG4gICAgICAgIFNlbGVjdG9yRW5naW5lLm5leHQodGhpcywgU0VMRUNUT1JfREFUQV9UT0dHTEUpWzBdIHx8XG4gICAgICAgIFNlbGVjdG9yRW5naW5lLmZpbmRPbmUoU0VMRUNUT1JfREFUQV9UT0dHTEUsIGV2ZW50LmRlbGVnYXRlVGFyZ2V0LnBhcmVudE5vZGUpKVxuXG4gICAgY29uc3QgaW5zdGFuY2UgPSBEcm9wZG93bi5nZXRPckNyZWF0ZUluc3RhbmNlKGdldFRvZ2dsZUJ1dHRvbilcblxuICAgIGlmIChpc1VwT3JEb3duRXZlbnQpIHtcbiAgICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpXG4gICAgICBpbnN0YW5jZS5zaG93KClcbiAgICAgIGluc3RhbmNlLl9zZWxlY3RNZW51SXRlbShldmVudClcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIGlmIChpbnN0YW5jZS5faXNTaG93bigpKSB7IC8vIGVsc2UgaXMgZXNjYXBlIGFuZCB3ZSBjaGVjayBpZiBpdCBpcyBzaG93blxuICAgICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKClcbiAgICAgIGluc3RhbmNlLmhpZGUoKVxuICAgICAgZ2V0VG9nZ2xlQnV0dG9uLmZvY3VzKClcbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBEYXRhIEFQSSBpbXBsZW1lbnRhdGlvblxuICovXG5cbkV2ZW50SGFuZGxlci5vbihkb2N1bWVudCwgRVZFTlRfS0VZRE9XTl9EQVRBX0FQSSwgU0VMRUNUT1JfREFUQV9UT0dHTEUsIERyb3Bkb3duLmRhdGFBcGlLZXlkb3duSGFuZGxlcilcbkV2ZW50SGFuZGxlci5vbihkb2N1bWVudCwgRVZFTlRfS0VZRE9XTl9EQVRBX0FQSSwgU0VMRUNUT1JfTUVOVSwgRHJvcGRvd24uZGF0YUFwaUtleWRvd25IYW5kbGVyKVxuRXZlbnRIYW5kbGVyLm9uKGRvY3VtZW50LCBFVkVOVF9DTElDS19EQVRBX0FQSSwgRHJvcGRvd24uY2xlYXJNZW51cylcbkV2ZW50SGFuZGxlci5vbihkb2N1bWVudCwgRVZFTlRfS0VZVVBfREFUQV9BUEksIERyb3Bkb3duLmNsZWFyTWVudXMpXG5FdmVudEhhbmRsZXIub24oZG9jdW1lbnQsIEVWRU5UX0NMSUNLX0RBVEFfQVBJLCBTRUxFQ1RPUl9EQVRBX1RPR0dMRSwgZnVuY3Rpb24gKGV2ZW50KSB7XG4gIGV2ZW50LnByZXZlbnREZWZhdWx0KClcbiAgRHJvcGRvd24uZ2V0T3JDcmVhdGVJbnN0YW5jZSh0aGlzKS50b2dnbGUoKVxufSlcblxuLyoqXG4gKiBqUXVlcnlcbiAqL1xuXG5kZWZpbmVKUXVlcnlQbHVnaW4oRHJvcGRvd24pXG5cbmV4cG9ydCBkZWZhdWx0IERyb3Bkb3duXG4iLCIvKipcbiAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gKiBCb290c3RyYXAgdXRpbC9iYWNrZHJvcC5qc1xuICogTGljZW5zZWQgdW5kZXIgTUlUIChodHRwczovL2dpdGh1Yi5jb20vdHdicy9ib290c3RyYXAvYmxvYi9tYWluL0xJQ0VOU0UpXG4gKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICovXG5cbmltcG9ydCBFdmVudEhhbmRsZXIgZnJvbSAnLi4vZG9tL2V2ZW50LWhhbmRsZXIuanMnXG5pbXBvcnQgQ29uZmlnIGZyb20gJy4vY29uZmlnLmpzJ1xuaW1wb3J0IHtcbiAgZXhlY3V0ZSwgZXhlY3V0ZUFmdGVyVHJhbnNpdGlvbiwgZ2V0RWxlbWVudCwgcmVmbG93XG59IGZyb20gJy4vaW5kZXguanMnXG5cbi8qKlxuICogQ29uc3RhbnRzXG4gKi9cblxuY29uc3QgTkFNRSA9ICdiYWNrZHJvcCdcbmNvbnN0IENMQVNTX05BTUVfRkFERSA9ICdmYWRlJ1xuY29uc3QgQ0xBU1NfTkFNRV9TSE9XID0gJ3Nob3cnXG5jb25zdCBFVkVOVF9NT1VTRURPV04gPSBgbW91c2Vkb3duLmJzLiR7TkFNRX1gXG5cbmNvbnN0IERlZmF1bHQgPSB7XG4gIGNsYXNzTmFtZTogJ21vZGFsLWJhY2tkcm9wJyxcbiAgY2xpY2tDYWxsYmFjazogbnVsbCxcbiAgaXNBbmltYXRlZDogZmFsc2UsXG4gIGlzVmlzaWJsZTogdHJ1ZSwgLy8gaWYgZmFsc2UsIHdlIHVzZSB0aGUgYmFja2Ryb3AgaGVscGVyIHdpdGhvdXQgYWRkaW5nIGFueSBlbGVtZW50IHRvIHRoZSBkb21cbiAgcm9vdEVsZW1lbnQ6ICdib2R5JyAvLyBnaXZlIHRoZSBjaG9pY2UgdG8gcGxhY2UgYmFja2Ryb3AgdW5kZXIgZGlmZmVyZW50IGVsZW1lbnRzXG59XG5cbmNvbnN0IERlZmF1bHRUeXBlID0ge1xuICBjbGFzc05hbWU6ICdzdHJpbmcnLFxuICBjbGlja0NhbGxiYWNrOiAnKGZ1bmN0aW9ufG51bGwpJyxcbiAgaXNBbmltYXRlZDogJ2Jvb2xlYW4nLFxuICBpc1Zpc2libGU6ICdib29sZWFuJyxcbiAgcm9vdEVsZW1lbnQ6ICcoZWxlbWVudHxzdHJpbmcpJ1xufVxuXG4vKipcbiAqIENsYXNzIGRlZmluaXRpb25cbiAqL1xuXG5jbGFzcyBCYWNrZHJvcCBleHRlbmRzIENvbmZpZyB7XG4gIGNvbnN0cnVjdG9yKGNvbmZpZykge1xuICAgIHN1cGVyKClcbiAgICB0aGlzLl9jb25maWcgPSB0aGlzLl9nZXRDb25maWcoY29uZmlnKVxuICAgIHRoaXMuX2lzQXBwZW5kZWQgPSBmYWxzZVxuICAgIHRoaXMuX2VsZW1lbnQgPSBudWxsXG4gIH1cblxuICAvLyBHZXR0ZXJzXG4gIHN0YXRpYyBnZXQgRGVmYXVsdCgpIHtcbiAgICByZXR1cm4gRGVmYXVsdFxuICB9XG5cbiAgc3RhdGljIGdldCBEZWZhdWx0VHlwZSgpIHtcbiAgICByZXR1cm4gRGVmYXVsdFR5cGVcbiAgfVxuXG4gIHN0YXRpYyBnZXQgTkFNRSgpIHtcbiAgICByZXR1cm4gTkFNRVxuICB9XG5cbiAgLy8gUHVibGljXG4gIHNob3coY2FsbGJhY2spIHtcbiAgICBpZiAoIXRoaXMuX2NvbmZpZy5pc1Zpc2libGUpIHtcbiAgICAgIGV4ZWN1dGUoY2FsbGJhY2spXG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICB0aGlzLl9hcHBlbmQoKVxuXG4gICAgY29uc3QgZWxlbWVudCA9IHRoaXMuX2dldEVsZW1lbnQoKVxuICAgIGlmICh0aGlzLl9jb25maWcuaXNBbmltYXRlZCkge1xuICAgICAgcmVmbG93KGVsZW1lbnQpXG4gICAgfVxuXG4gICAgZWxlbWVudC5jbGFzc0xpc3QuYWRkKENMQVNTX05BTUVfU0hPVylcblxuICAgIHRoaXMuX2VtdWxhdGVBbmltYXRpb24oKCkgPT4ge1xuICAgICAgZXhlY3V0ZShjYWxsYmFjaylcbiAgICB9KVxuICB9XG5cbiAgaGlkZShjYWxsYmFjaykge1xuICAgIGlmICghdGhpcy5fY29uZmlnLmlzVmlzaWJsZSkge1xuICAgICAgZXhlY3V0ZShjYWxsYmFjaylcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIHRoaXMuX2dldEVsZW1lbnQoKS5jbGFzc0xpc3QucmVtb3ZlKENMQVNTX05BTUVfU0hPVylcblxuICAgIHRoaXMuX2VtdWxhdGVBbmltYXRpb24oKCkgPT4ge1xuICAgICAgdGhpcy5kaXNwb3NlKClcbiAgICAgIGV4ZWN1dGUoY2FsbGJhY2spXG4gICAgfSlcbiAgfVxuXG4gIGRpc3Bvc2UoKSB7XG4gICAgaWYgKCF0aGlzLl9pc0FwcGVuZGVkKSB7XG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICBFdmVudEhhbmRsZXIub2ZmKHRoaXMuX2VsZW1lbnQsIEVWRU5UX01PVVNFRE9XTilcblxuICAgIHRoaXMuX2VsZW1lbnQucmVtb3ZlKClcbiAgICB0aGlzLl9pc0FwcGVuZGVkID0gZmFsc2VcbiAgfVxuXG4gIC8vIFByaXZhdGVcbiAgX2dldEVsZW1lbnQoKSB7XG4gICAgaWYgKCF0aGlzLl9lbGVtZW50KSB7XG4gICAgICBjb25zdCBiYWNrZHJvcCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpXG4gICAgICBiYWNrZHJvcC5jbGFzc05hbWUgPSB0aGlzLl9jb25maWcuY2xhc3NOYW1lXG4gICAgICBpZiAodGhpcy5fY29uZmlnLmlzQW5pbWF0ZWQpIHtcbiAgICAgICAgYmFja2Ryb3AuY2xhc3NMaXN0LmFkZChDTEFTU19OQU1FX0ZBREUpXG4gICAgICB9XG5cbiAgICAgIHRoaXMuX2VsZW1lbnQgPSBiYWNrZHJvcFxuICAgIH1cblxuICAgIHJldHVybiB0aGlzLl9lbGVtZW50XG4gIH1cblxuICBfY29uZmlnQWZ0ZXJNZXJnZShjb25maWcpIHtcbiAgICAvLyB1c2UgZ2V0RWxlbWVudCgpIHdpdGggdGhlIGRlZmF1bHQgXCJib2R5XCIgdG8gZ2V0IGEgZnJlc2ggRWxlbWVudCBvbiBlYWNoIGluc3RhbnRpYXRpb25cbiAgICBjb25maWcucm9vdEVsZW1lbnQgPSBnZXRFbGVtZW50KGNvbmZpZy5yb290RWxlbWVudClcbiAgICByZXR1cm4gY29uZmlnXG4gIH1cblxuICBfYXBwZW5kKCkge1xuICAgIGlmICh0aGlzLl9pc0FwcGVuZGVkKSB7XG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICBjb25zdCBlbGVtZW50ID0gdGhpcy5fZ2V0RWxlbWVudCgpXG4gICAgdGhpcy5fY29uZmlnLnJvb3RFbGVtZW50LmFwcGVuZChlbGVtZW50KVxuXG4gICAgRXZlbnRIYW5kbGVyLm9uKGVsZW1lbnQsIEVWRU5UX01PVVNFRE9XTiwgKCkgPT4ge1xuICAgICAgZXhlY3V0ZSh0aGlzLl9jb25maWcuY2xpY2tDYWxsYmFjaylcbiAgICB9KVxuXG4gICAgdGhpcy5faXNBcHBlbmRlZCA9IHRydWVcbiAgfVxuXG4gIF9lbXVsYXRlQW5pbWF0aW9uKGNhbGxiYWNrKSB7XG4gICAgZXhlY3V0ZUFmdGVyVHJhbnNpdGlvbihjYWxsYmFjaywgdGhpcy5fZ2V0RWxlbWVudCgpLCB0aGlzLl9jb25maWcuaXNBbmltYXRlZClcbiAgfVxufVxuXG5leHBvcnQgZGVmYXVsdCBCYWNrZHJvcFxuIiwiLyoqXG4gKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICogQm9vdHN0cmFwIHV0aWwvZm9jdXN0cmFwLmpzXG4gKiBMaWNlbnNlZCB1bmRlciBNSVQgKGh0dHBzOi8vZ2l0aHViLmNvbS90d2JzL2Jvb3RzdHJhcC9ibG9iL21haW4vTElDRU5TRSlcbiAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gKi9cblxuaW1wb3J0IEV2ZW50SGFuZGxlciBmcm9tICcuLi9kb20vZXZlbnQtaGFuZGxlci5qcydcbmltcG9ydCBTZWxlY3RvckVuZ2luZSBmcm9tICcuLi9kb20vc2VsZWN0b3ItZW5naW5lLmpzJ1xuaW1wb3J0IENvbmZpZyBmcm9tICcuL2NvbmZpZy5qcydcblxuLyoqXG4gKiBDb25zdGFudHNcbiAqL1xuXG5jb25zdCBOQU1FID0gJ2ZvY3VzdHJhcCdcbmNvbnN0IERBVEFfS0VZID0gJ2JzLmZvY3VzdHJhcCdcbmNvbnN0IEVWRU5UX0tFWSA9IGAuJHtEQVRBX0tFWX1gXG5jb25zdCBFVkVOVF9GT0NVU0lOID0gYGZvY3VzaW4ke0VWRU5UX0tFWX1gXG5jb25zdCBFVkVOVF9LRVlET1dOX1RBQiA9IGBrZXlkb3duLnRhYiR7RVZFTlRfS0VZfWBcblxuY29uc3QgVEFCX0tFWSA9ICdUYWInXG5jb25zdCBUQUJfTkFWX0ZPUldBUkQgPSAnZm9yd2FyZCdcbmNvbnN0IFRBQl9OQVZfQkFDS1dBUkQgPSAnYmFja3dhcmQnXG5cbmNvbnN0IERlZmF1bHQgPSB7XG4gIGF1dG9mb2N1czogdHJ1ZSxcbiAgdHJhcEVsZW1lbnQ6IG51bGwgLy8gVGhlIGVsZW1lbnQgdG8gdHJhcCBmb2N1cyBpbnNpZGUgb2Zcbn1cblxuY29uc3QgRGVmYXVsdFR5cGUgPSB7XG4gIGF1dG9mb2N1czogJ2Jvb2xlYW4nLFxuICB0cmFwRWxlbWVudDogJ2VsZW1lbnQnXG59XG5cbi8qKlxuICogQ2xhc3MgZGVmaW5pdGlvblxuICovXG5cbmNsYXNzIEZvY3VzVHJhcCBleHRlbmRzIENvbmZpZyB7XG4gIGNvbnN0cnVjdG9yKGNvbmZpZykge1xuICAgIHN1cGVyKClcbiAgICB0aGlzLl9jb25maWcgPSB0aGlzLl9nZXRDb25maWcoY29uZmlnKVxuICAgIHRoaXMuX2lzQWN0aXZlID0gZmFsc2VcbiAgICB0aGlzLl9sYXN0VGFiTmF2RGlyZWN0aW9uID0gbnVsbFxuICB9XG5cbiAgLy8gR2V0dGVyc1xuICBzdGF0aWMgZ2V0IERlZmF1bHQoKSB7XG4gICAgcmV0dXJuIERlZmF1bHRcbiAgfVxuXG4gIHN0YXRpYyBnZXQgRGVmYXVsdFR5cGUoKSB7XG4gICAgcmV0dXJuIERlZmF1bHRUeXBlXG4gIH1cblxuICBzdGF0aWMgZ2V0IE5BTUUoKSB7XG4gICAgcmV0dXJuIE5BTUVcbiAgfVxuXG4gIC8vIFB1YmxpY1xuICBhY3RpdmF0ZSgpIHtcbiAgICBpZiAodGhpcy5faXNBY3RpdmUpIHtcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIGlmICh0aGlzLl9jb25maWcuYXV0b2ZvY3VzKSB7XG4gICAgICB0aGlzLl9jb25maWcudHJhcEVsZW1lbnQuZm9jdXMoKVxuICAgIH1cblxuICAgIEV2ZW50SGFuZGxlci5vZmYoZG9jdW1lbnQsIEVWRU5UX0tFWSkgLy8gZ3VhcmQgYWdhaW5zdCBpbmZpbml0ZSBmb2N1cyBsb29wXG4gICAgRXZlbnRIYW5kbGVyLm9uKGRvY3VtZW50LCBFVkVOVF9GT0NVU0lOLCBldmVudCA9PiB0aGlzLl9oYW5kbGVGb2N1c2luKGV2ZW50KSlcbiAgICBFdmVudEhhbmRsZXIub24oZG9jdW1lbnQsIEVWRU5UX0tFWURPV05fVEFCLCBldmVudCA9PiB0aGlzLl9oYW5kbGVLZXlkb3duKGV2ZW50KSlcblxuICAgIHRoaXMuX2lzQWN0aXZlID0gdHJ1ZVxuICB9XG5cbiAgZGVhY3RpdmF0ZSgpIHtcbiAgICBpZiAoIXRoaXMuX2lzQWN0aXZlKSB7XG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICB0aGlzLl9pc0FjdGl2ZSA9IGZhbHNlXG4gICAgRXZlbnRIYW5kbGVyLm9mZihkb2N1bWVudCwgRVZFTlRfS0VZKVxuICB9XG5cbiAgLy8gUHJpdmF0ZVxuICBfaGFuZGxlRm9jdXNpbihldmVudCkge1xuICAgIGNvbnN0IHsgdHJhcEVsZW1lbnQgfSA9IHRoaXMuX2NvbmZpZ1xuXG4gICAgaWYgKGV2ZW50LnRhcmdldCA9PT0gZG9jdW1lbnQgfHwgZXZlbnQudGFyZ2V0ID09PSB0cmFwRWxlbWVudCB8fCB0cmFwRWxlbWVudC5jb250YWlucyhldmVudC50YXJnZXQpKSB7XG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICBjb25zdCBlbGVtZW50cyA9IFNlbGVjdG9yRW5naW5lLmZvY3VzYWJsZUNoaWxkcmVuKHRyYXBFbGVtZW50KVxuXG4gICAgaWYgKGVsZW1lbnRzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgdHJhcEVsZW1lbnQuZm9jdXMoKVxuICAgIH0gZWxzZSBpZiAodGhpcy5fbGFzdFRhYk5hdkRpcmVjdGlvbiA9PT0gVEFCX05BVl9CQUNLV0FSRCkge1xuICAgICAgZWxlbWVudHNbZWxlbWVudHMubGVuZ3RoIC0gMV0uZm9jdXMoKVxuICAgIH0gZWxzZSB7XG4gICAgICBlbGVtZW50c1swXS5mb2N1cygpXG4gICAgfVxuICB9XG5cbiAgX2hhbmRsZUtleWRvd24oZXZlbnQpIHtcbiAgICBpZiAoZXZlbnQua2V5ICE9PSBUQUJfS0VZKSB7XG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICB0aGlzLl9sYXN0VGFiTmF2RGlyZWN0aW9uID0gZXZlbnQuc2hpZnRLZXkgPyBUQUJfTkFWX0JBQ0tXQVJEIDogVEFCX05BVl9GT1JXQVJEXG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgRm9jdXNUcmFwXG4iLCIvKipcbiAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gKiBCb290c3RyYXAgdXRpbC9zY3JvbGxCYXIuanNcbiAqIExpY2Vuc2VkIHVuZGVyIE1JVCAoaHR0cHM6Ly9naXRodWIuY29tL3R3YnMvYm9vdHN0cmFwL2Jsb2IvbWFpbi9MSUNFTlNFKVxuICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAqL1xuXG5pbXBvcnQgTWFuaXB1bGF0b3IgZnJvbSAnLi4vZG9tL21hbmlwdWxhdG9yLmpzJ1xuaW1wb3J0IFNlbGVjdG9yRW5naW5lIGZyb20gJy4uL2RvbS9zZWxlY3Rvci1lbmdpbmUuanMnXG5pbXBvcnQgeyBpc0VsZW1lbnQgfSBmcm9tICcuL2luZGV4LmpzJ1xuXG4vKipcbiAqIENvbnN0YW50c1xuICovXG5cbmNvbnN0IFNFTEVDVE9SX0ZJWEVEX0NPTlRFTlQgPSAnLmZpeGVkLXRvcCwgLmZpeGVkLWJvdHRvbSwgLmlzLWZpeGVkLCAuc3RpY2t5LXRvcCdcbmNvbnN0IFNFTEVDVE9SX1NUSUNLWV9DT05URU5UID0gJy5zdGlja3ktdG9wJ1xuY29uc3QgUFJPUEVSVFlfUEFERElORyA9ICdwYWRkaW5nLXJpZ2h0J1xuY29uc3QgUFJPUEVSVFlfTUFSR0lOID0gJ21hcmdpbi1yaWdodCdcblxuLyoqXG4gKiBDbGFzcyBkZWZpbml0aW9uXG4gKi9cblxuY2xhc3MgU2Nyb2xsQmFySGVscGVyIHtcbiAgY29uc3RydWN0b3IoKSB7XG4gICAgdGhpcy5fZWxlbWVudCA9IGRvY3VtZW50LmJvZHlcbiAgfVxuXG4gIC8vIFB1YmxpY1xuICBnZXRXaWR0aCgpIHtcbiAgICAvLyBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvV2luZG93L2lubmVyV2lkdGgjdXNhZ2Vfbm90ZXNcbiAgICBjb25zdCBkb2N1bWVudFdpZHRoID0gZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmNsaWVudFdpZHRoXG4gICAgcmV0dXJuIE1hdGguYWJzKHdpbmRvdy5pbm5lcldpZHRoIC0gZG9jdW1lbnRXaWR0aClcbiAgfVxuXG4gIGhpZGUoKSB7XG4gICAgY29uc3Qgd2lkdGggPSB0aGlzLmdldFdpZHRoKClcbiAgICB0aGlzLl9kaXNhYmxlT3ZlckZsb3coKVxuICAgIC8vIGdpdmUgcGFkZGluZyB0byBlbGVtZW50IHRvIGJhbGFuY2UgdGhlIGhpZGRlbiBzY3JvbGxiYXIgd2lkdGhcbiAgICB0aGlzLl9zZXRFbGVtZW50QXR0cmlidXRlcyh0aGlzLl9lbGVtZW50LCBQUk9QRVJUWV9QQURESU5HLCBjYWxjdWxhdGVkVmFsdWUgPT4gY2FsY3VsYXRlZFZhbHVlICsgd2lkdGgpXG4gICAgLy8gdHJpY2s6IFdlIGFkanVzdCBwb3NpdGl2ZSBwYWRkaW5nUmlnaHQgYW5kIG5lZ2F0aXZlIG1hcmdpblJpZ2h0IHRvIHN0aWNreS10b3AgZWxlbWVudHMgdG8ga2VlcCBzaG93aW5nIGZ1bGx3aWR0aFxuICAgIHRoaXMuX3NldEVsZW1lbnRBdHRyaWJ1dGVzKFNFTEVDVE9SX0ZJWEVEX0NPTlRFTlQsIFBST1BFUlRZX1BBRERJTkcsIGNhbGN1bGF0ZWRWYWx1ZSA9PiBjYWxjdWxhdGVkVmFsdWUgKyB3aWR0aClcbiAgICB0aGlzLl9zZXRFbGVtZW50QXR0cmlidXRlcyhTRUxFQ1RPUl9TVElDS1lfQ09OVEVOVCwgUFJPUEVSVFlfTUFSR0lOLCBjYWxjdWxhdGVkVmFsdWUgPT4gY2FsY3VsYXRlZFZhbHVlIC0gd2lkdGgpXG4gIH1cblxuICByZXNldCgpIHtcbiAgICB0aGlzLl9yZXNldEVsZW1lbnRBdHRyaWJ1dGVzKHRoaXMuX2VsZW1lbnQsICdvdmVyZmxvdycpXG4gICAgdGhpcy5fcmVzZXRFbGVtZW50QXR0cmlidXRlcyh0aGlzLl9lbGVtZW50LCBQUk9QRVJUWV9QQURESU5HKVxuICAgIHRoaXMuX3Jlc2V0RWxlbWVudEF0dHJpYnV0ZXMoU0VMRUNUT1JfRklYRURfQ09OVEVOVCwgUFJPUEVSVFlfUEFERElORylcbiAgICB0aGlzLl9yZXNldEVsZW1lbnRBdHRyaWJ1dGVzKFNFTEVDVE9SX1NUSUNLWV9DT05URU5ULCBQUk9QRVJUWV9NQVJHSU4pXG4gIH1cblxuICBpc092ZXJmbG93aW5nKCkge1xuICAgIHJldHVybiB0aGlzLmdldFdpZHRoKCkgPiAwXG4gIH1cblxuICAvLyBQcml2YXRlXG4gIF9kaXNhYmxlT3ZlckZsb3coKSB7XG4gICAgdGhpcy5fc2F2ZUluaXRpYWxBdHRyaWJ1dGUodGhpcy5fZWxlbWVudCwgJ292ZXJmbG93JylcbiAgICB0aGlzLl9lbGVtZW50LnN0eWxlLm92ZXJmbG93ID0gJ2hpZGRlbidcbiAgfVxuXG4gIF9zZXRFbGVtZW50QXR0cmlidXRlcyhzZWxlY3Rvciwgc3R5bGVQcm9wZXJ0eSwgY2FsbGJhY2spIHtcbiAgICBjb25zdCBzY3JvbGxiYXJXaWR0aCA9IHRoaXMuZ2V0V2lkdGgoKVxuICAgIGNvbnN0IG1hbmlwdWxhdGlvbkNhbGxCYWNrID0gZWxlbWVudCA9PiB7XG4gICAgICBpZiAoZWxlbWVudCAhPT0gdGhpcy5fZWxlbWVudCAmJiB3aW5kb3cuaW5uZXJXaWR0aCA+IGVsZW1lbnQuY2xpZW50V2lkdGggKyBzY3JvbGxiYXJXaWR0aCkge1xuICAgICAgICByZXR1cm5cbiAgICAgIH1cblxuICAgICAgdGhpcy5fc2F2ZUluaXRpYWxBdHRyaWJ1dGUoZWxlbWVudCwgc3R5bGVQcm9wZXJ0eSlcbiAgICAgIGNvbnN0IGNhbGN1bGF0ZWRWYWx1ZSA9IHdpbmRvdy5nZXRDb21wdXRlZFN0eWxlKGVsZW1lbnQpLmdldFByb3BlcnR5VmFsdWUoc3R5bGVQcm9wZXJ0eSlcbiAgICAgIGVsZW1lbnQuc3R5bGUuc2V0UHJvcGVydHkoc3R5bGVQcm9wZXJ0eSwgYCR7Y2FsbGJhY2soTnVtYmVyLnBhcnNlRmxvYXQoY2FsY3VsYXRlZFZhbHVlKSl9cHhgKVxuICAgIH1cblxuICAgIHRoaXMuX2FwcGx5TWFuaXB1bGF0aW9uQ2FsbGJhY2soc2VsZWN0b3IsIG1hbmlwdWxhdGlvbkNhbGxCYWNrKVxuICB9XG5cbiAgX3NhdmVJbml0aWFsQXR0cmlidXRlKGVsZW1lbnQsIHN0eWxlUHJvcGVydHkpIHtcbiAgICBjb25zdCBhY3R1YWxWYWx1ZSA9IGVsZW1lbnQuc3R5bGUuZ2V0UHJvcGVydHlWYWx1ZShzdHlsZVByb3BlcnR5KVxuICAgIGlmIChhY3R1YWxWYWx1ZSkge1xuICAgICAgTWFuaXB1bGF0b3Iuc2V0RGF0YUF0dHJpYnV0ZShlbGVtZW50LCBzdHlsZVByb3BlcnR5LCBhY3R1YWxWYWx1ZSlcbiAgICB9XG4gIH1cblxuICBfcmVzZXRFbGVtZW50QXR0cmlidXRlcyhzZWxlY3Rvciwgc3R5bGVQcm9wZXJ0eSkge1xuICAgIGNvbnN0IG1hbmlwdWxhdGlvbkNhbGxCYWNrID0gZWxlbWVudCA9PiB7XG4gICAgICBjb25zdCB2YWx1ZSA9IE1hbmlwdWxhdG9yLmdldERhdGFBdHRyaWJ1dGUoZWxlbWVudCwgc3R5bGVQcm9wZXJ0eSlcbiAgICAgIC8vIFdlIG9ubHkgd2FudCB0byByZW1vdmUgdGhlIHByb3BlcnR5IGlmIHRoZSB2YWx1ZSBpcyBgbnVsbGA7IHRoZSB2YWx1ZSBjYW4gYWxzbyBiZSB6ZXJvXG4gICAgICBpZiAodmFsdWUgPT09IG51bGwpIHtcbiAgICAgICAgZWxlbWVudC5zdHlsZS5yZW1vdmVQcm9wZXJ0eShzdHlsZVByb3BlcnR5KVxuICAgICAgICByZXR1cm5cbiAgICAgIH1cblxuICAgICAgTWFuaXB1bGF0b3IucmVtb3ZlRGF0YUF0dHJpYnV0ZShlbGVtZW50LCBzdHlsZVByb3BlcnR5KVxuICAgICAgZWxlbWVudC5zdHlsZS5zZXRQcm9wZXJ0eShzdHlsZVByb3BlcnR5LCB2YWx1ZSlcbiAgICB9XG5cbiAgICB0aGlzLl9hcHBseU1hbmlwdWxhdGlvbkNhbGxiYWNrKHNlbGVjdG9yLCBtYW5pcHVsYXRpb25DYWxsQmFjaylcbiAgfVxuXG4gIF9hcHBseU1hbmlwdWxhdGlvbkNhbGxiYWNrKHNlbGVjdG9yLCBjYWxsQmFjaykge1xuICAgIGlmIChpc0VsZW1lbnQoc2VsZWN0b3IpKSB7XG4gICAgICBjYWxsQmFjayhzZWxlY3RvcilcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIGZvciAoY29uc3Qgc2VsIG9mIFNlbGVjdG9yRW5naW5lLmZpbmQoc2VsZWN0b3IsIHRoaXMuX2VsZW1lbnQpKSB7XG4gICAgICBjYWxsQmFjayhzZWwpXG4gICAgfVxuICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IFNjcm9sbEJhckhlbHBlclxuIiwiLyoqXG4gKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICogQm9vdHN0cmFwIG1vZGFsLmpzXG4gKiBMaWNlbnNlZCB1bmRlciBNSVQgKGh0dHBzOi8vZ2l0aHViLmNvbS90d2JzL2Jvb3RzdHJhcC9ibG9iL21haW4vTElDRU5TRSlcbiAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gKi9cblxuaW1wb3J0IEJhc2VDb21wb25lbnQgZnJvbSAnLi9iYXNlLWNvbXBvbmVudC5qcydcbmltcG9ydCBFdmVudEhhbmRsZXIgZnJvbSAnLi9kb20vZXZlbnQtaGFuZGxlci5qcydcbmltcG9ydCBTZWxlY3RvckVuZ2luZSBmcm9tICcuL2RvbS9zZWxlY3Rvci1lbmdpbmUuanMnXG5pbXBvcnQgQmFja2Ryb3AgZnJvbSAnLi91dGlsL2JhY2tkcm9wLmpzJ1xuaW1wb3J0IHsgZW5hYmxlRGlzbWlzc1RyaWdnZXIgfSBmcm9tICcuL3V0aWwvY29tcG9uZW50LWZ1bmN0aW9ucy5qcydcbmltcG9ydCBGb2N1c1RyYXAgZnJvbSAnLi91dGlsL2ZvY3VzdHJhcC5qcydcbmltcG9ydCB7XG4gIGRlZmluZUpRdWVyeVBsdWdpbiwgaXNSVEwsIGlzVmlzaWJsZSwgcmVmbG93XG59IGZyb20gJy4vdXRpbC9pbmRleC5qcydcbmltcG9ydCBTY3JvbGxCYXJIZWxwZXIgZnJvbSAnLi91dGlsL3Njcm9sbGJhci5qcydcblxuLyoqXG4gKiBDb25zdGFudHNcbiAqL1xuXG5jb25zdCBOQU1FID0gJ21vZGFsJ1xuY29uc3QgREFUQV9LRVkgPSAnYnMubW9kYWwnXG5jb25zdCBFVkVOVF9LRVkgPSBgLiR7REFUQV9LRVl9YFxuY29uc3QgREFUQV9BUElfS0VZID0gJy5kYXRhLWFwaSdcbmNvbnN0IEVTQ0FQRV9LRVkgPSAnRXNjYXBlJ1xuXG5jb25zdCBFVkVOVF9ISURFID0gYGhpZGUke0VWRU5UX0tFWX1gXG5jb25zdCBFVkVOVF9ISURFX1BSRVZFTlRFRCA9IGBoaWRlUHJldmVudGVkJHtFVkVOVF9LRVl9YFxuY29uc3QgRVZFTlRfSElEREVOID0gYGhpZGRlbiR7RVZFTlRfS0VZfWBcbmNvbnN0IEVWRU5UX1NIT1cgPSBgc2hvdyR7RVZFTlRfS0VZfWBcbmNvbnN0IEVWRU5UX1NIT1dOID0gYHNob3duJHtFVkVOVF9LRVl9YFxuY29uc3QgRVZFTlRfUkVTSVpFID0gYHJlc2l6ZSR7RVZFTlRfS0VZfWBcbmNvbnN0IEVWRU5UX0NMSUNLX0RJU01JU1MgPSBgY2xpY2suZGlzbWlzcyR7RVZFTlRfS0VZfWBcbmNvbnN0IEVWRU5UX01PVVNFRE9XTl9ESVNNSVNTID0gYG1vdXNlZG93bi5kaXNtaXNzJHtFVkVOVF9LRVl9YFxuY29uc3QgRVZFTlRfS0VZRE9XTl9ESVNNSVNTID0gYGtleWRvd24uZGlzbWlzcyR7RVZFTlRfS0VZfWBcbmNvbnN0IEVWRU5UX0NMSUNLX0RBVEFfQVBJID0gYGNsaWNrJHtFVkVOVF9LRVl9JHtEQVRBX0FQSV9LRVl9YFxuXG5jb25zdCBDTEFTU19OQU1FX09QRU4gPSAnbW9kYWwtb3BlbidcbmNvbnN0IENMQVNTX05BTUVfRkFERSA9ICdmYWRlJ1xuY29uc3QgQ0xBU1NfTkFNRV9TSE9XID0gJ3Nob3cnXG5jb25zdCBDTEFTU19OQU1FX1NUQVRJQyA9ICdtb2RhbC1zdGF0aWMnXG5cbmNvbnN0IE9QRU5fU0VMRUNUT1IgPSAnLm1vZGFsLnNob3cnXG5jb25zdCBTRUxFQ1RPUl9ESUFMT0cgPSAnLm1vZGFsLWRpYWxvZydcbmNvbnN0IFNFTEVDVE9SX01PREFMX0JPRFkgPSAnLm1vZGFsLWJvZHknXG5jb25zdCBTRUxFQ1RPUl9EQVRBX1RPR0dMRSA9ICdbZGF0YS1icy10b2dnbGU9XCJtb2RhbFwiXSdcblxuY29uc3QgRGVmYXVsdCA9IHtcbiAgYmFja2Ryb3A6IHRydWUsXG4gIGZvY3VzOiB0cnVlLFxuICBrZXlib2FyZDogdHJ1ZVxufVxuXG5jb25zdCBEZWZhdWx0VHlwZSA9IHtcbiAgYmFja2Ryb3A6ICcoYm9vbGVhbnxzdHJpbmcpJyxcbiAgZm9jdXM6ICdib29sZWFuJyxcbiAga2V5Ym9hcmQ6ICdib29sZWFuJ1xufVxuXG4vKipcbiAqIENsYXNzIGRlZmluaXRpb25cbiAqL1xuXG5jbGFzcyBNb2RhbCBleHRlbmRzIEJhc2VDb21wb25lbnQge1xuICBjb25zdHJ1Y3RvcihlbGVtZW50LCBjb25maWcpIHtcbiAgICBzdXBlcihlbGVtZW50LCBjb25maWcpXG5cbiAgICB0aGlzLl9kaWFsb2cgPSBTZWxlY3RvckVuZ2luZS5maW5kT25lKFNFTEVDVE9SX0RJQUxPRywgdGhpcy5fZWxlbWVudClcbiAgICB0aGlzLl9iYWNrZHJvcCA9IHRoaXMuX2luaXRpYWxpemVCYWNrRHJvcCgpXG4gICAgdGhpcy5fZm9jdXN0cmFwID0gdGhpcy5faW5pdGlhbGl6ZUZvY3VzVHJhcCgpXG4gICAgdGhpcy5faXNTaG93biA9IGZhbHNlXG4gICAgdGhpcy5faXNUcmFuc2l0aW9uaW5nID0gZmFsc2VcbiAgICB0aGlzLl9zY3JvbGxCYXIgPSBuZXcgU2Nyb2xsQmFySGVscGVyKClcblxuICAgIHRoaXMuX2FkZEV2ZW50TGlzdGVuZXJzKClcbiAgfVxuXG4gIC8vIEdldHRlcnNcbiAgc3RhdGljIGdldCBEZWZhdWx0KCkge1xuICAgIHJldHVybiBEZWZhdWx0XG4gIH1cblxuICBzdGF0aWMgZ2V0IERlZmF1bHRUeXBlKCkge1xuICAgIHJldHVybiBEZWZhdWx0VHlwZVxuICB9XG5cbiAgc3RhdGljIGdldCBOQU1FKCkge1xuICAgIHJldHVybiBOQU1FXG4gIH1cblxuICAvLyBQdWJsaWNcbiAgdG9nZ2xlKHJlbGF0ZWRUYXJnZXQpIHtcbiAgICByZXR1cm4gdGhpcy5faXNTaG93biA/IHRoaXMuaGlkZSgpIDogdGhpcy5zaG93KHJlbGF0ZWRUYXJnZXQpXG4gIH1cblxuICBzaG93KHJlbGF0ZWRUYXJnZXQpIHtcbiAgICBpZiAodGhpcy5faXNTaG93biB8fCB0aGlzLl9pc1RyYW5zaXRpb25pbmcpIHtcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIGNvbnN0IHNob3dFdmVudCA9IEV2ZW50SGFuZGxlci50cmlnZ2VyKHRoaXMuX2VsZW1lbnQsIEVWRU5UX1NIT1csIHtcbiAgICAgIHJlbGF0ZWRUYXJnZXRcbiAgICB9KVxuXG4gICAgaWYgKHNob3dFdmVudC5kZWZhdWx0UHJldmVudGVkKSB7XG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICB0aGlzLl9pc1Nob3duID0gdHJ1ZVxuICAgIHRoaXMuX2lzVHJhbnNpdGlvbmluZyA9IHRydWVcblxuICAgIHRoaXMuX3Njcm9sbEJhci5oaWRlKClcblxuICAgIGRvY3VtZW50LmJvZHkuY2xhc3NMaXN0LmFkZChDTEFTU19OQU1FX09QRU4pXG5cbiAgICB0aGlzLl9hZGp1c3REaWFsb2coKVxuXG4gICAgdGhpcy5fYmFja2Ryb3Auc2hvdygoKSA9PiB0aGlzLl9zaG93RWxlbWVudChyZWxhdGVkVGFyZ2V0KSlcbiAgfVxuXG4gIGhpZGUoKSB7XG4gICAgaWYgKCF0aGlzLl9pc1Nob3duIHx8IHRoaXMuX2lzVHJhbnNpdGlvbmluZykge1xuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgY29uc3QgaGlkZUV2ZW50ID0gRXZlbnRIYW5kbGVyLnRyaWdnZXIodGhpcy5fZWxlbWVudCwgRVZFTlRfSElERSlcblxuICAgIGlmIChoaWRlRXZlbnQuZGVmYXVsdFByZXZlbnRlZCkge1xuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgdGhpcy5faXNTaG93biA9IGZhbHNlXG4gICAgdGhpcy5faXNUcmFuc2l0aW9uaW5nID0gdHJ1ZVxuICAgIHRoaXMuX2ZvY3VzdHJhcC5kZWFjdGl2YXRlKClcblxuICAgIHRoaXMuX2VsZW1lbnQuY2xhc3NMaXN0LnJlbW92ZShDTEFTU19OQU1FX1NIT1cpXG5cbiAgICB0aGlzLl9xdWV1ZUNhbGxiYWNrKCgpID0+IHRoaXMuX2hpZGVNb2RhbCgpLCB0aGlzLl9lbGVtZW50LCB0aGlzLl9pc0FuaW1hdGVkKCkpXG4gIH1cblxuICBkaXNwb3NlKCkge1xuICAgIEV2ZW50SGFuZGxlci5vZmYod2luZG93LCBFVkVOVF9LRVkpXG4gICAgRXZlbnRIYW5kbGVyLm9mZih0aGlzLl9kaWFsb2csIEVWRU5UX0tFWSlcblxuICAgIHRoaXMuX2JhY2tkcm9wLmRpc3Bvc2UoKVxuICAgIHRoaXMuX2ZvY3VzdHJhcC5kZWFjdGl2YXRlKClcblxuICAgIHN1cGVyLmRpc3Bvc2UoKVxuICB9XG5cbiAgaGFuZGxlVXBkYXRlKCkge1xuICAgIHRoaXMuX2FkanVzdERpYWxvZygpXG4gIH1cblxuICAvLyBQcml2YXRlXG4gIF9pbml0aWFsaXplQmFja0Ryb3AoKSB7XG4gICAgcmV0dXJuIG5ldyBCYWNrZHJvcCh7XG4gICAgICBpc1Zpc2libGU6IEJvb2xlYW4odGhpcy5fY29uZmlnLmJhY2tkcm9wKSwgLy8gJ3N0YXRpYycgb3B0aW9uIHdpbGwgYmUgdHJhbnNsYXRlZCB0byB0cnVlLCBhbmQgYm9vbGVhbnMgd2lsbCBrZWVwIHRoZWlyIHZhbHVlLFxuICAgICAgaXNBbmltYXRlZDogdGhpcy5faXNBbmltYXRlZCgpXG4gICAgfSlcbiAgfVxuXG4gIF9pbml0aWFsaXplRm9jdXNUcmFwKCkge1xuICAgIHJldHVybiBuZXcgRm9jdXNUcmFwKHtcbiAgICAgIHRyYXBFbGVtZW50OiB0aGlzLl9lbGVtZW50XG4gICAgfSlcbiAgfVxuXG4gIF9zaG93RWxlbWVudChyZWxhdGVkVGFyZ2V0KSB7XG4gICAgLy8gdHJ5IHRvIGFwcGVuZCBkeW5hbWljIG1vZGFsXG4gICAgaWYgKCFkb2N1bWVudC5ib2R5LmNvbnRhaW5zKHRoaXMuX2VsZW1lbnQpKSB7XG4gICAgICBkb2N1bWVudC5ib2R5LmFwcGVuZCh0aGlzLl9lbGVtZW50KVxuICAgIH1cblxuICAgIHRoaXMuX2VsZW1lbnQuc3R5bGUuZGlzcGxheSA9ICdibG9jaydcbiAgICB0aGlzLl9lbGVtZW50LnJlbW92ZUF0dHJpYnV0ZSgnYXJpYS1oaWRkZW4nKVxuICAgIHRoaXMuX2VsZW1lbnQuc2V0QXR0cmlidXRlKCdhcmlhLW1vZGFsJywgdHJ1ZSlcbiAgICB0aGlzLl9lbGVtZW50LnNldEF0dHJpYnV0ZSgncm9sZScsICdkaWFsb2cnKVxuICAgIHRoaXMuX2VsZW1lbnQuc2Nyb2xsVG9wID0gMFxuXG4gICAgY29uc3QgbW9kYWxCb2R5ID0gU2VsZWN0b3JFbmdpbmUuZmluZE9uZShTRUxFQ1RPUl9NT0RBTF9CT0RZLCB0aGlzLl9kaWFsb2cpXG4gICAgaWYgKG1vZGFsQm9keSkge1xuICAgICAgbW9kYWxCb2R5LnNjcm9sbFRvcCA9IDBcbiAgICB9XG5cbiAgICByZWZsb3codGhpcy5fZWxlbWVudClcblxuICAgIHRoaXMuX2VsZW1lbnQuY2xhc3NMaXN0LmFkZChDTEFTU19OQU1FX1NIT1cpXG5cbiAgICBjb25zdCB0cmFuc2l0aW9uQ29tcGxldGUgPSAoKSA9PiB7XG4gICAgICBpZiAodGhpcy5fY29uZmlnLmZvY3VzKSB7XG4gICAgICAgIHRoaXMuX2ZvY3VzdHJhcC5hY3RpdmF0ZSgpXG4gICAgICB9XG5cbiAgICAgIHRoaXMuX2lzVHJhbnNpdGlvbmluZyA9IGZhbHNlXG4gICAgICBFdmVudEhhbmRsZXIudHJpZ2dlcih0aGlzLl9lbGVtZW50LCBFVkVOVF9TSE9XTiwge1xuICAgICAgICByZWxhdGVkVGFyZ2V0XG4gICAgICB9KVxuICAgIH1cblxuICAgIHRoaXMuX3F1ZXVlQ2FsbGJhY2sodHJhbnNpdGlvbkNvbXBsZXRlLCB0aGlzLl9kaWFsb2csIHRoaXMuX2lzQW5pbWF0ZWQoKSlcbiAgfVxuXG4gIF9hZGRFdmVudExpc3RlbmVycygpIHtcbiAgICBFdmVudEhhbmRsZXIub24odGhpcy5fZWxlbWVudCwgRVZFTlRfS0VZRE9XTl9ESVNNSVNTLCBldmVudCA9PiB7XG4gICAgICBpZiAoZXZlbnQua2V5ICE9PSBFU0NBUEVfS0VZKSB7XG4gICAgICAgIHJldHVyblxuICAgICAgfVxuXG4gICAgICBpZiAodGhpcy5fY29uZmlnLmtleWJvYXJkKSB7XG4gICAgICAgIHRoaXMuaGlkZSgpXG4gICAgICAgIHJldHVyblxuICAgICAgfVxuXG4gICAgICB0aGlzLl90cmlnZ2VyQmFja2Ryb3BUcmFuc2l0aW9uKClcbiAgICB9KVxuXG4gICAgRXZlbnRIYW5kbGVyLm9uKHdpbmRvdywgRVZFTlRfUkVTSVpFLCAoKSA9PiB7XG4gICAgICBpZiAodGhpcy5faXNTaG93biAmJiAhdGhpcy5faXNUcmFuc2l0aW9uaW5nKSB7XG4gICAgICAgIHRoaXMuX2FkanVzdERpYWxvZygpXG4gICAgICB9XG4gICAgfSlcblxuICAgIEV2ZW50SGFuZGxlci5vbih0aGlzLl9lbGVtZW50LCBFVkVOVF9NT1VTRURPV05fRElTTUlTUywgZXZlbnQgPT4ge1xuICAgICAgLy8gYSBiYWQgdHJpY2sgdG8gc2VncmVnYXRlIGNsaWNrcyB0aGF0IG1heSBzdGFydCBpbnNpZGUgZGlhbG9nIGJ1dCBlbmQgb3V0c2lkZSwgYW5kIGF2b2lkIGxpc3RlbiB0byBzY3JvbGxiYXIgY2xpY2tzXG4gICAgICBFdmVudEhhbmRsZXIub25lKHRoaXMuX2VsZW1lbnQsIEVWRU5UX0NMSUNLX0RJU01JU1MsIGV2ZW50MiA9PiB7XG4gICAgICAgIGlmICh0aGlzLl9lbGVtZW50ICE9PSBldmVudC50YXJnZXQgfHwgdGhpcy5fZWxlbWVudCAhPT0gZXZlbnQyLnRhcmdldCkge1xuICAgICAgICAgIHJldHVyblxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMuX2NvbmZpZy5iYWNrZHJvcCA9PT0gJ3N0YXRpYycpIHtcbiAgICAgICAgICB0aGlzLl90cmlnZ2VyQmFja2Ryb3BUcmFuc2l0aW9uKClcbiAgICAgICAgICByZXR1cm5cbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLl9jb25maWcuYmFja2Ryb3ApIHtcbiAgICAgICAgICB0aGlzLmhpZGUoKVxuICAgICAgICB9XG4gICAgICB9KVxuICAgIH0pXG4gIH1cblxuICBfaGlkZU1vZGFsKCkge1xuICAgIHRoaXMuX2VsZW1lbnQuc3R5bGUuZGlzcGxheSA9ICdub25lJ1xuICAgIHRoaXMuX2VsZW1lbnQuc2V0QXR0cmlidXRlKCdhcmlhLWhpZGRlbicsIHRydWUpXG4gICAgdGhpcy5fZWxlbWVudC5yZW1vdmVBdHRyaWJ1dGUoJ2FyaWEtbW9kYWwnKVxuICAgIHRoaXMuX2VsZW1lbnQucmVtb3ZlQXR0cmlidXRlKCdyb2xlJylcbiAgICB0aGlzLl9pc1RyYW5zaXRpb25pbmcgPSBmYWxzZVxuXG4gICAgdGhpcy5fYmFja2Ryb3AuaGlkZSgoKSA9PiB7XG4gICAgICBkb2N1bWVudC5ib2R5LmNsYXNzTGlzdC5yZW1vdmUoQ0xBU1NfTkFNRV9PUEVOKVxuICAgICAgdGhpcy5fcmVzZXRBZGp1c3RtZW50cygpXG4gICAgICB0aGlzLl9zY3JvbGxCYXIucmVzZXQoKVxuICAgICAgRXZlbnRIYW5kbGVyLnRyaWdnZXIodGhpcy5fZWxlbWVudCwgRVZFTlRfSElEREVOKVxuICAgIH0pXG4gIH1cblxuICBfaXNBbmltYXRlZCgpIHtcbiAgICByZXR1cm4gdGhpcy5fZWxlbWVudC5jbGFzc0xpc3QuY29udGFpbnMoQ0xBU1NfTkFNRV9GQURFKVxuICB9XG5cbiAgX3RyaWdnZXJCYWNrZHJvcFRyYW5zaXRpb24oKSB7XG4gICAgY29uc3QgaGlkZUV2ZW50ID0gRXZlbnRIYW5kbGVyLnRyaWdnZXIodGhpcy5fZWxlbWVudCwgRVZFTlRfSElERV9QUkVWRU5URUQpXG4gICAgaWYgKGhpZGVFdmVudC5kZWZhdWx0UHJldmVudGVkKSB7XG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICBjb25zdCBpc01vZGFsT3ZlcmZsb3dpbmcgPSB0aGlzLl9lbGVtZW50LnNjcm9sbEhlaWdodCA+IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5jbGllbnRIZWlnaHRcbiAgICBjb25zdCBpbml0aWFsT3ZlcmZsb3dZID0gdGhpcy5fZWxlbWVudC5zdHlsZS5vdmVyZmxvd1lcbiAgICAvLyByZXR1cm4gaWYgdGhlIGZvbGxvd2luZyBiYWNrZ3JvdW5kIHRyYW5zaXRpb24gaGFzbid0IHlldCBjb21wbGV0ZWRcbiAgICBpZiAoaW5pdGlhbE92ZXJmbG93WSA9PT0gJ2hpZGRlbicgfHwgdGhpcy5fZWxlbWVudC5jbGFzc0xpc3QuY29udGFpbnMoQ0xBU1NfTkFNRV9TVEFUSUMpKSB7XG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICBpZiAoIWlzTW9kYWxPdmVyZmxvd2luZykge1xuICAgICAgdGhpcy5fZWxlbWVudC5zdHlsZS5vdmVyZmxvd1kgPSAnaGlkZGVuJ1xuICAgIH1cblxuICAgIHRoaXMuX2VsZW1lbnQuY2xhc3NMaXN0LmFkZChDTEFTU19OQU1FX1NUQVRJQylcbiAgICB0aGlzLl9xdWV1ZUNhbGxiYWNrKCgpID0+IHtcbiAgICAgIHRoaXMuX2VsZW1lbnQuY2xhc3NMaXN0LnJlbW92ZShDTEFTU19OQU1FX1NUQVRJQylcbiAgICAgIHRoaXMuX3F1ZXVlQ2FsbGJhY2soKCkgPT4ge1xuICAgICAgICB0aGlzLl9lbGVtZW50LnN0eWxlLm92ZXJmbG93WSA9IGluaXRpYWxPdmVyZmxvd1lcbiAgICAgIH0sIHRoaXMuX2RpYWxvZylcbiAgICB9LCB0aGlzLl9kaWFsb2cpXG5cbiAgICB0aGlzLl9lbGVtZW50LmZvY3VzKClcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGUgZm9sbG93aW5nIG1ldGhvZHMgYXJlIHVzZWQgdG8gaGFuZGxlIG92ZXJmbG93aW5nIG1vZGFsc1xuICAgKi9cblxuICBfYWRqdXN0RGlhbG9nKCkge1xuICAgIGNvbnN0IGlzTW9kYWxPdmVyZmxvd2luZyA9IHRoaXMuX2VsZW1lbnQuc2Nyb2xsSGVpZ2h0ID4gZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmNsaWVudEhlaWdodFxuICAgIGNvbnN0IHNjcm9sbGJhcldpZHRoID0gdGhpcy5fc2Nyb2xsQmFyLmdldFdpZHRoKClcbiAgICBjb25zdCBpc0JvZHlPdmVyZmxvd2luZyA9IHNjcm9sbGJhcldpZHRoID4gMFxuXG4gICAgaWYgKGlzQm9keU92ZXJmbG93aW5nICYmICFpc01vZGFsT3ZlcmZsb3dpbmcpIHtcbiAgICAgIGNvbnN0IHByb3BlcnR5ID0gaXNSVEwoKSA/ICdwYWRkaW5nTGVmdCcgOiAncGFkZGluZ1JpZ2h0J1xuICAgICAgdGhpcy5fZWxlbWVudC5zdHlsZVtwcm9wZXJ0eV0gPSBgJHtzY3JvbGxiYXJXaWR0aH1weGBcbiAgICB9XG5cbiAgICBpZiAoIWlzQm9keU92ZXJmbG93aW5nICYmIGlzTW9kYWxPdmVyZmxvd2luZykge1xuICAgICAgY29uc3QgcHJvcGVydHkgPSBpc1JUTCgpID8gJ3BhZGRpbmdSaWdodCcgOiAncGFkZGluZ0xlZnQnXG4gICAgICB0aGlzLl9lbGVtZW50LnN0eWxlW3Byb3BlcnR5XSA9IGAke3Njcm9sbGJhcldpZHRofXB4YFxuICAgIH1cbiAgfVxuXG4gIF9yZXNldEFkanVzdG1lbnRzKCkge1xuICAgIHRoaXMuX2VsZW1lbnQuc3R5bGUucGFkZGluZ0xlZnQgPSAnJ1xuICAgIHRoaXMuX2VsZW1lbnQuc3R5bGUucGFkZGluZ1JpZ2h0ID0gJydcbiAgfVxuXG4gIC8vIFN0YXRpY1xuICBzdGF0aWMgalF1ZXJ5SW50ZXJmYWNlKGNvbmZpZywgcmVsYXRlZFRhcmdldCkge1xuICAgIHJldHVybiB0aGlzLmVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgZGF0YSA9IE1vZGFsLmdldE9yQ3JlYXRlSW5zdGFuY2UodGhpcywgY29uZmlnKVxuXG4gICAgICBpZiAodHlwZW9mIGNvbmZpZyAhPT0gJ3N0cmluZycpIHtcbiAgICAgICAgcmV0dXJuXG4gICAgICB9XG5cbiAgICAgIGlmICh0eXBlb2YgZGF0YVtjb25maWddID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGBObyBtZXRob2QgbmFtZWQgXCIke2NvbmZpZ31cImApXG4gICAgICB9XG5cbiAgICAgIGRhdGFbY29uZmlnXShyZWxhdGVkVGFyZ2V0KVxuICAgIH0pXG4gIH1cbn1cblxuLyoqXG4gKiBEYXRhIEFQSSBpbXBsZW1lbnRhdGlvblxuICovXG5cbkV2ZW50SGFuZGxlci5vbihkb2N1bWVudCwgRVZFTlRfQ0xJQ0tfREFUQV9BUEksIFNFTEVDVE9SX0RBVEFfVE9HR0xFLCBmdW5jdGlvbiAoZXZlbnQpIHtcbiAgY29uc3QgdGFyZ2V0ID0gU2VsZWN0b3JFbmdpbmUuZ2V0RWxlbWVudEZyb21TZWxlY3Rvcih0aGlzKVxuXG4gIGlmIChbJ0EnLCAnQVJFQSddLmluY2x1ZGVzKHRoaXMudGFnTmFtZSkpIHtcbiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpXG4gIH1cblxuICBFdmVudEhhbmRsZXIub25lKHRhcmdldCwgRVZFTlRfU0hPVywgc2hvd0V2ZW50ID0+IHtcbiAgICBpZiAoc2hvd0V2ZW50LmRlZmF1bHRQcmV2ZW50ZWQpIHtcbiAgICAgIC8vIG9ubHkgcmVnaXN0ZXIgZm9jdXMgcmVzdG9yZXIgaWYgbW9kYWwgd2lsbCBhY3R1YWxseSBnZXQgc2hvd25cbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIEV2ZW50SGFuZGxlci5vbmUodGFyZ2V0LCBFVkVOVF9ISURERU4sICgpID0+IHtcbiAgICAgIGlmIChpc1Zpc2libGUodGhpcykpIHtcbiAgICAgICAgdGhpcy5mb2N1cygpXG4gICAgICB9XG4gICAgfSlcbiAgfSlcblxuICAvLyBhdm9pZCBjb25mbGljdCB3aGVuIGNsaWNraW5nIG1vZGFsIHRvZ2dsZXIgd2hpbGUgYW5vdGhlciBvbmUgaXMgb3BlblxuICBjb25zdCBhbHJlYWR5T3BlbiA9IFNlbGVjdG9yRW5naW5lLmZpbmRPbmUoT1BFTl9TRUxFQ1RPUilcbiAgaWYgKGFscmVhZHlPcGVuKSB7XG4gICAgTW9kYWwuZ2V0SW5zdGFuY2UoYWxyZWFkeU9wZW4pLmhpZGUoKVxuICB9XG5cbiAgY29uc3QgZGF0YSA9IE1vZGFsLmdldE9yQ3JlYXRlSW5zdGFuY2UodGFyZ2V0KVxuXG4gIGRhdGEudG9nZ2xlKHRoaXMpXG59KVxuXG5lbmFibGVEaXNtaXNzVHJpZ2dlcihNb2RhbClcblxuLyoqXG4gKiBqUXVlcnlcbiAqL1xuXG5kZWZpbmVKUXVlcnlQbHVnaW4oTW9kYWwpXG5cbmV4cG9ydCBkZWZhdWx0IE1vZGFsXG4iLCIvKipcbiAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gKiBCb290c3RyYXAgb2ZmY2FudmFzLmpzXG4gKiBMaWNlbnNlZCB1bmRlciBNSVQgKGh0dHBzOi8vZ2l0aHViLmNvbS90d2JzL2Jvb3RzdHJhcC9ibG9iL21haW4vTElDRU5TRSlcbiAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gKi9cblxuaW1wb3J0IEJhc2VDb21wb25lbnQgZnJvbSAnLi9iYXNlLWNvbXBvbmVudC5qcydcbmltcG9ydCBFdmVudEhhbmRsZXIgZnJvbSAnLi9kb20vZXZlbnQtaGFuZGxlci5qcydcbmltcG9ydCBTZWxlY3RvckVuZ2luZSBmcm9tICcuL2RvbS9zZWxlY3Rvci1lbmdpbmUuanMnXG5pbXBvcnQgQmFja2Ryb3AgZnJvbSAnLi91dGlsL2JhY2tkcm9wLmpzJ1xuaW1wb3J0IHsgZW5hYmxlRGlzbWlzc1RyaWdnZXIgfSBmcm9tICcuL3V0aWwvY29tcG9uZW50LWZ1bmN0aW9ucy5qcydcbmltcG9ydCBGb2N1c1RyYXAgZnJvbSAnLi91dGlsL2ZvY3VzdHJhcC5qcydcbmltcG9ydCB7XG4gIGRlZmluZUpRdWVyeVBsdWdpbixcbiAgaXNEaXNhYmxlZCxcbiAgaXNWaXNpYmxlXG59IGZyb20gJy4vdXRpbC9pbmRleC5qcydcbmltcG9ydCBTY3JvbGxCYXJIZWxwZXIgZnJvbSAnLi91dGlsL3Njcm9sbGJhci5qcydcblxuLyoqXG4gKiBDb25zdGFudHNcbiAqL1xuXG5jb25zdCBOQU1FID0gJ29mZmNhbnZhcydcbmNvbnN0IERBVEFfS0VZID0gJ2JzLm9mZmNhbnZhcydcbmNvbnN0IEVWRU5UX0tFWSA9IGAuJHtEQVRBX0tFWX1gXG5jb25zdCBEQVRBX0FQSV9LRVkgPSAnLmRhdGEtYXBpJ1xuY29uc3QgRVZFTlRfTE9BRF9EQVRBX0FQSSA9IGBsb2FkJHtFVkVOVF9LRVl9JHtEQVRBX0FQSV9LRVl9YFxuY29uc3QgRVNDQVBFX0tFWSA9ICdFc2NhcGUnXG5cbmNvbnN0IENMQVNTX05BTUVfU0hPVyA9ICdzaG93J1xuY29uc3QgQ0xBU1NfTkFNRV9TSE9XSU5HID0gJ3Nob3dpbmcnXG5jb25zdCBDTEFTU19OQU1FX0hJRElORyA9ICdoaWRpbmcnXG5jb25zdCBDTEFTU19OQU1FX0JBQ0tEUk9QID0gJ29mZmNhbnZhcy1iYWNrZHJvcCdcbmNvbnN0IE9QRU5fU0VMRUNUT1IgPSAnLm9mZmNhbnZhcy5zaG93J1xuXG5jb25zdCBFVkVOVF9TSE9XID0gYHNob3cke0VWRU5UX0tFWX1gXG5jb25zdCBFVkVOVF9TSE9XTiA9IGBzaG93biR7RVZFTlRfS0VZfWBcbmNvbnN0IEVWRU5UX0hJREUgPSBgaGlkZSR7RVZFTlRfS0VZfWBcbmNvbnN0IEVWRU5UX0hJREVfUFJFVkVOVEVEID0gYGhpZGVQcmV2ZW50ZWQke0VWRU5UX0tFWX1gXG5jb25zdCBFVkVOVF9ISURERU4gPSBgaGlkZGVuJHtFVkVOVF9LRVl9YFxuY29uc3QgRVZFTlRfUkVTSVpFID0gYHJlc2l6ZSR7RVZFTlRfS0VZfWBcbmNvbnN0IEVWRU5UX0NMSUNLX0RBVEFfQVBJID0gYGNsaWNrJHtFVkVOVF9LRVl9JHtEQVRBX0FQSV9LRVl9YFxuY29uc3QgRVZFTlRfS0VZRE9XTl9ESVNNSVNTID0gYGtleWRvd24uZGlzbWlzcyR7RVZFTlRfS0VZfWBcblxuY29uc3QgU0VMRUNUT1JfREFUQV9UT0dHTEUgPSAnW2RhdGEtYnMtdG9nZ2xlPVwib2ZmY2FudmFzXCJdJ1xuXG5jb25zdCBEZWZhdWx0ID0ge1xuICBiYWNrZHJvcDogdHJ1ZSxcbiAga2V5Ym9hcmQ6IHRydWUsXG4gIHNjcm9sbDogZmFsc2Vcbn1cblxuY29uc3QgRGVmYXVsdFR5cGUgPSB7XG4gIGJhY2tkcm9wOiAnKGJvb2xlYW58c3RyaW5nKScsXG4gIGtleWJvYXJkOiAnYm9vbGVhbicsXG4gIHNjcm9sbDogJ2Jvb2xlYW4nXG59XG5cbi8qKlxuICogQ2xhc3MgZGVmaW5pdGlvblxuICovXG5cbmNsYXNzIE9mZmNhbnZhcyBleHRlbmRzIEJhc2VDb21wb25lbnQge1xuICBjb25zdHJ1Y3RvcihlbGVtZW50LCBjb25maWcpIHtcbiAgICBzdXBlcihlbGVtZW50LCBjb25maWcpXG5cbiAgICB0aGlzLl9pc1Nob3duID0gZmFsc2VcbiAgICB0aGlzLl9iYWNrZHJvcCA9IHRoaXMuX2luaXRpYWxpemVCYWNrRHJvcCgpXG4gICAgdGhpcy5fZm9jdXN0cmFwID0gdGhpcy5faW5pdGlhbGl6ZUZvY3VzVHJhcCgpXG4gICAgdGhpcy5fYWRkRXZlbnRMaXN0ZW5lcnMoKVxuICB9XG5cbiAgLy8gR2V0dGVyc1xuICBzdGF0aWMgZ2V0IERlZmF1bHQoKSB7XG4gICAgcmV0dXJuIERlZmF1bHRcbiAgfVxuXG4gIHN0YXRpYyBnZXQgRGVmYXVsdFR5cGUoKSB7XG4gICAgcmV0dXJuIERlZmF1bHRUeXBlXG4gIH1cblxuICBzdGF0aWMgZ2V0IE5BTUUoKSB7XG4gICAgcmV0dXJuIE5BTUVcbiAgfVxuXG4gIC8vIFB1YmxpY1xuICB0b2dnbGUocmVsYXRlZFRhcmdldCkge1xuICAgIHJldHVybiB0aGlzLl9pc1Nob3duID8gdGhpcy5oaWRlKCkgOiB0aGlzLnNob3cocmVsYXRlZFRhcmdldClcbiAgfVxuXG4gIHNob3cocmVsYXRlZFRhcmdldCkge1xuICAgIGlmICh0aGlzLl9pc1Nob3duKSB7XG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICBjb25zdCBzaG93RXZlbnQgPSBFdmVudEhhbmRsZXIudHJpZ2dlcih0aGlzLl9lbGVtZW50LCBFVkVOVF9TSE9XLCB7IHJlbGF0ZWRUYXJnZXQgfSlcblxuICAgIGlmIChzaG93RXZlbnQuZGVmYXVsdFByZXZlbnRlZCkge1xuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgdGhpcy5faXNTaG93biA9IHRydWVcbiAgICB0aGlzLl9iYWNrZHJvcC5zaG93KClcblxuICAgIGlmICghdGhpcy5fY29uZmlnLnNjcm9sbCkge1xuICAgICAgbmV3IFNjcm9sbEJhckhlbHBlcigpLmhpZGUoKVxuICAgIH1cblxuICAgIHRoaXMuX2VsZW1lbnQuc2V0QXR0cmlidXRlKCdhcmlhLW1vZGFsJywgdHJ1ZSlcbiAgICB0aGlzLl9lbGVtZW50LnNldEF0dHJpYnV0ZSgncm9sZScsICdkaWFsb2cnKVxuICAgIHRoaXMuX2VsZW1lbnQuY2xhc3NMaXN0LmFkZChDTEFTU19OQU1FX1NIT1dJTkcpXG5cbiAgICBjb25zdCBjb21wbGV0ZUNhbGxCYWNrID0gKCkgPT4ge1xuICAgICAgaWYgKCF0aGlzLl9jb25maWcuc2Nyb2xsIHx8IHRoaXMuX2NvbmZpZy5iYWNrZHJvcCkge1xuICAgICAgICB0aGlzLl9mb2N1c3RyYXAuYWN0aXZhdGUoKVxuICAgICAgfVxuXG4gICAgICB0aGlzLl9lbGVtZW50LmNsYXNzTGlzdC5hZGQoQ0xBU1NfTkFNRV9TSE9XKVxuICAgICAgdGhpcy5fZWxlbWVudC5jbGFzc0xpc3QucmVtb3ZlKENMQVNTX05BTUVfU0hPV0lORylcbiAgICAgIEV2ZW50SGFuZGxlci50cmlnZ2VyKHRoaXMuX2VsZW1lbnQsIEVWRU5UX1NIT1dOLCB7IHJlbGF0ZWRUYXJnZXQgfSlcbiAgICB9XG5cbiAgICB0aGlzLl9xdWV1ZUNhbGxiYWNrKGNvbXBsZXRlQ2FsbEJhY2ssIHRoaXMuX2VsZW1lbnQsIHRydWUpXG4gIH1cblxuICBoaWRlKCkge1xuICAgIGlmICghdGhpcy5faXNTaG93bikge1xuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgY29uc3QgaGlkZUV2ZW50ID0gRXZlbnRIYW5kbGVyLnRyaWdnZXIodGhpcy5fZWxlbWVudCwgRVZFTlRfSElERSlcblxuICAgIGlmIChoaWRlRXZlbnQuZGVmYXVsdFByZXZlbnRlZCkge1xuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgdGhpcy5fZm9jdXN0cmFwLmRlYWN0aXZhdGUoKVxuICAgIHRoaXMuX2VsZW1lbnQuYmx1cigpXG4gICAgdGhpcy5faXNTaG93biA9IGZhbHNlXG4gICAgdGhpcy5fZWxlbWVudC5jbGFzc0xpc3QuYWRkKENMQVNTX05BTUVfSElESU5HKVxuICAgIHRoaXMuX2JhY2tkcm9wLmhpZGUoKVxuXG4gICAgY29uc3QgY29tcGxldGVDYWxsYmFjayA9ICgpID0+IHtcbiAgICAgIHRoaXMuX2VsZW1lbnQuY2xhc3NMaXN0LnJlbW92ZShDTEFTU19OQU1FX1NIT1csIENMQVNTX05BTUVfSElESU5HKVxuICAgICAgdGhpcy5fZWxlbWVudC5yZW1vdmVBdHRyaWJ1dGUoJ2FyaWEtbW9kYWwnKVxuICAgICAgdGhpcy5fZWxlbWVudC5yZW1vdmVBdHRyaWJ1dGUoJ3JvbGUnKVxuXG4gICAgICBpZiAoIXRoaXMuX2NvbmZpZy5zY3JvbGwpIHtcbiAgICAgICAgbmV3IFNjcm9sbEJhckhlbHBlcigpLnJlc2V0KClcbiAgICAgIH1cblxuICAgICAgRXZlbnRIYW5kbGVyLnRyaWdnZXIodGhpcy5fZWxlbWVudCwgRVZFTlRfSElEREVOKVxuICAgIH1cblxuICAgIHRoaXMuX3F1ZXVlQ2FsbGJhY2soY29tcGxldGVDYWxsYmFjaywgdGhpcy5fZWxlbWVudCwgdHJ1ZSlcbiAgfVxuXG4gIGRpc3Bvc2UoKSB7XG4gICAgdGhpcy5fYmFja2Ryb3AuZGlzcG9zZSgpXG4gICAgdGhpcy5fZm9jdXN0cmFwLmRlYWN0aXZhdGUoKVxuICAgIHN1cGVyLmRpc3Bvc2UoKVxuICB9XG5cbiAgLy8gUHJpdmF0ZVxuICBfaW5pdGlhbGl6ZUJhY2tEcm9wKCkge1xuICAgIGNvbnN0IGNsaWNrQ2FsbGJhY2sgPSAoKSA9PiB7XG4gICAgICBpZiAodGhpcy5fY29uZmlnLmJhY2tkcm9wID09PSAnc3RhdGljJykge1xuICAgICAgICBFdmVudEhhbmRsZXIudHJpZ2dlcih0aGlzLl9lbGVtZW50LCBFVkVOVF9ISURFX1BSRVZFTlRFRClcbiAgICAgICAgcmV0dXJuXG4gICAgICB9XG5cbiAgICAgIHRoaXMuaGlkZSgpXG4gICAgfVxuXG4gICAgLy8gJ3N0YXRpYycgb3B0aW9uIHdpbGwgYmUgdHJhbnNsYXRlZCB0byB0cnVlLCBhbmQgYm9vbGVhbnMgd2lsbCBrZWVwIHRoZWlyIHZhbHVlXG4gICAgY29uc3QgaXNWaXNpYmxlID0gQm9vbGVhbih0aGlzLl9jb25maWcuYmFja2Ryb3ApXG5cbiAgICByZXR1cm4gbmV3IEJhY2tkcm9wKHtcbiAgICAgIGNsYXNzTmFtZTogQ0xBU1NfTkFNRV9CQUNLRFJPUCxcbiAgICAgIGlzVmlzaWJsZSxcbiAgICAgIGlzQW5pbWF0ZWQ6IHRydWUsXG4gICAgICByb290RWxlbWVudDogdGhpcy5fZWxlbWVudC5wYXJlbnROb2RlLFxuICAgICAgY2xpY2tDYWxsYmFjazogaXNWaXNpYmxlID8gY2xpY2tDYWxsYmFjayA6IG51bGxcbiAgICB9KVxuICB9XG5cbiAgX2luaXRpYWxpemVGb2N1c1RyYXAoKSB7XG4gICAgcmV0dXJuIG5ldyBGb2N1c1RyYXAoe1xuICAgICAgdHJhcEVsZW1lbnQ6IHRoaXMuX2VsZW1lbnRcbiAgICB9KVxuICB9XG5cbiAgX2FkZEV2ZW50TGlzdGVuZXJzKCkge1xuICAgIEV2ZW50SGFuZGxlci5vbih0aGlzLl9lbGVtZW50LCBFVkVOVF9LRVlET1dOX0RJU01JU1MsIGV2ZW50ID0+IHtcbiAgICAgIGlmIChldmVudC5rZXkgIT09IEVTQ0FQRV9LRVkpIHtcbiAgICAgICAgcmV0dXJuXG4gICAgICB9XG5cbiAgICAgIGlmICh0aGlzLl9jb25maWcua2V5Ym9hcmQpIHtcbiAgICAgICAgdGhpcy5oaWRlKClcbiAgICAgICAgcmV0dXJuXG4gICAgICB9XG5cbiAgICAgIEV2ZW50SGFuZGxlci50cmlnZ2VyKHRoaXMuX2VsZW1lbnQsIEVWRU5UX0hJREVfUFJFVkVOVEVEKVxuICAgIH0pXG4gIH1cblxuICAvLyBTdGF0aWNcbiAgc3RhdGljIGpRdWVyeUludGVyZmFjZShjb25maWcpIHtcbiAgICByZXR1cm4gdGhpcy5lYWNoKGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGRhdGEgPSBPZmZjYW52YXMuZ2V0T3JDcmVhdGVJbnN0YW5jZSh0aGlzLCBjb25maWcpXG5cbiAgICAgIGlmICh0eXBlb2YgY29uZmlnICE9PSAnc3RyaW5nJykge1xuICAgICAgICByZXR1cm5cbiAgICAgIH1cblxuICAgICAgaWYgKGRhdGFbY29uZmlnXSA9PT0gdW5kZWZpbmVkIHx8IGNvbmZpZy5zdGFydHNXaXRoKCdfJykgfHwgY29uZmlnID09PSAnY29uc3RydWN0b3InKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoYE5vIG1ldGhvZCBuYW1lZCBcIiR7Y29uZmlnfVwiYClcbiAgICAgIH1cblxuICAgICAgZGF0YVtjb25maWddKHRoaXMpXG4gICAgfSlcbiAgfVxufVxuXG4vKipcbiAqIERhdGEgQVBJIGltcGxlbWVudGF0aW9uXG4gKi9cblxuRXZlbnRIYW5kbGVyLm9uKGRvY3VtZW50LCBFVkVOVF9DTElDS19EQVRBX0FQSSwgU0VMRUNUT1JfREFUQV9UT0dHTEUsIGZ1bmN0aW9uIChldmVudCkge1xuICBjb25zdCB0YXJnZXQgPSBTZWxlY3RvckVuZ2luZS5nZXRFbGVtZW50RnJvbVNlbGVjdG9yKHRoaXMpXG5cbiAgaWYgKFsnQScsICdBUkVBJ10uaW5jbHVkZXModGhpcy50YWdOYW1lKSkge1xuICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KClcbiAgfVxuXG4gIGlmIChpc0Rpc2FibGVkKHRoaXMpKSB7XG4gICAgcmV0dXJuXG4gIH1cblxuICBFdmVudEhhbmRsZXIub25lKHRhcmdldCwgRVZFTlRfSElEREVOLCAoKSA9PiB7XG4gICAgLy8gZm9jdXMgb24gdHJpZ2dlciB3aGVuIGl0IGlzIGNsb3NlZFxuICAgIGlmIChpc1Zpc2libGUodGhpcykpIHtcbiAgICAgIHRoaXMuZm9jdXMoKVxuICAgIH1cbiAgfSlcblxuICAvLyBhdm9pZCBjb25mbGljdCB3aGVuIGNsaWNraW5nIGEgdG9nZ2xlciBvZiBhbiBvZmZjYW52YXMsIHdoaWxlIGFub3RoZXIgaXMgb3BlblxuICBjb25zdCBhbHJlYWR5T3BlbiA9IFNlbGVjdG9yRW5naW5lLmZpbmRPbmUoT1BFTl9TRUxFQ1RPUilcbiAgaWYgKGFscmVhZHlPcGVuICYmIGFscmVhZHlPcGVuICE9PSB0YXJnZXQpIHtcbiAgICBPZmZjYW52YXMuZ2V0SW5zdGFuY2UoYWxyZWFkeU9wZW4pLmhpZGUoKVxuICB9XG5cbiAgY29uc3QgZGF0YSA9IE9mZmNhbnZhcy5nZXRPckNyZWF0ZUluc3RhbmNlKHRhcmdldClcbiAgZGF0YS50b2dnbGUodGhpcylcbn0pXG5cbkV2ZW50SGFuZGxlci5vbih3aW5kb3csIEVWRU5UX0xPQURfREFUQV9BUEksICgpID0+IHtcbiAgZm9yIChjb25zdCBzZWxlY3RvciBvZiBTZWxlY3RvckVuZ2luZS5maW5kKE9QRU5fU0VMRUNUT1IpKSB7XG4gICAgT2ZmY2FudmFzLmdldE9yQ3JlYXRlSW5zdGFuY2Uoc2VsZWN0b3IpLnNob3coKVxuICB9XG59KVxuXG5FdmVudEhhbmRsZXIub24od2luZG93LCBFVkVOVF9SRVNJWkUsICgpID0+IHtcbiAgZm9yIChjb25zdCBlbGVtZW50IG9mIFNlbGVjdG9yRW5naW5lLmZpbmQoJ1thcmlhLW1vZGFsXVtjbGFzcyo9c2hvd11bY2xhc3MqPW9mZmNhbnZhcy1dJykpIHtcbiAgICBpZiAoZ2V0Q29tcHV0ZWRTdHlsZShlbGVtZW50KS5wb3NpdGlvbiAhPT0gJ2ZpeGVkJykge1xuICAgICAgT2ZmY2FudmFzLmdldE9yQ3JlYXRlSW5zdGFuY2UoZWxlbWVudCkuaGlkZSgpXG4gICAgfVxuICB9XG59KVxuXG5lbmFibGVEaXNtaXNzVHJpZ2dlcihPZmZjYW52YXMpXG5cbi8qKlxuICogalF1ZXJ5XG4gKi9cblxuZGVmaW5lSlF1ZXJ5UGx1Z2luKE9mZmNhbnZhcylcblxuZXhwb3J0IGRlZmF1bHQgT2ZmY2FudmFzXG4iLCIvKipcbiAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gKiBCb290c3RyYXAgdXRpbC9zYW5pdGl6ZXIuanNcbiAqIExpY2Vuc2VkIHVuZGVyIE1JVCAoaHR0cHM6Ly9naXRodWIuY29tL3R3YnMvYm9vdHN0cmFwL2Jsb2IvbWFpbi9MSUNFTlNFKVxuICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAqL1xuXG4vLyBqcy1kb2NzLXN0YXJ0IGFsbG93LWxpc3RcbmNvbnN0IEFSSUFfQVRUUklCVVRFX1BBVFRFUk4gPSAvXmFyaWEtW1xcdy1dKiQvaVxuXG5leHBvcnQgY29uc3QgRGVmYXVsdEFsbG93bGlzdCA9IHtcbiAgLy8gR2xvYmFsIGF0dHJpYnV0ZXMgYWxsb3dlZCBvbiBhbnkgc3VwcGxpZWQgZWxlbWVudCBiZWxvdy5cbiAgJyonOiBbJ2NsYXNzJywgJ2RpcicsICdpZCcsICdsYW5nJywgJ3JvbGUnLCBBUklBX0FUVFJJQlVURV9QQVRURVJOXSxcbiAgYTogWyd0YXJnZXQnLCAnaHJlZicsICd0aXRsZScsICdyZWwnXSxcbiAgYXJlYTogW10sXG4gIGI6IFtdLFxuICBicjogW10sXG4gIGNvbDogW10sXG4gIGNvZGU6IFtdLFxuICBkZDogW10sXG4gIGRpdjogW10sXG4gIGRsOiBbXSxcbiAgZHQ6IFtdLFxuICBlbTogW10sXG4gIGhyOiBbXSxcbiAgaDE6IFtdLFxuICBoMjogW10sXG4gIGgzOiBbXSxcbiAgaDQ6IFtdLFxuICBoNTogW10sXG4gIGg2OiBbXSxcbiAgaTogW10sXG4gIGltZzogWydzcmMnLCAnc3Jjc2V0JywgJ2FsdCcsICd0aXRsZScsICd3aWR0aCcsICdoZWlnaHQnXSxcbiAgbGk6IFtdLFxuICBvbDogW10sXG4gIHA6IFtdLFxuICBwcmU6IFtdLFxuICBzOiBbXSxcbiAgc21hbGw6IFtdLFxuICBzcGFuOiBbXSxcbiAgc3ViOiBbXSxcbiAgc3VwOiBbXSxcbiAgc3Ryb25nOiBbXSxcbiAgdTogW10sXG4gIHVsOiBbXVxufVxuLy8ganMtZG9jcy1lbmQgYWxsb3ctbGlzdFxuXG5jb25zdCB1cmlBdHRyaWJ1dGVzID0gbmV3IFNldChbXG4gICdiYWNrZ3JvdW5kJyxcbiAgJ2NpdGUnLFxuICAnaHJlZicsXG4gICdpdGVtdHlwZScsXG4gICdsb25nZGVzYycsXG4gICdwb3N0ZXInLFxuICAnc3JjJyxcbiAgJ3hsaW5rOmhyZWYnXG5dKVxuXG4vKipcbiAqIEEgcGF0dGVybiB0aGF0IHJlY29nbml6ZXMgVVJMcyB0aGF0IGFyZSBzYWZlIHdydC4gWFNTIGluIFVSTCBuYXZpZ2F0aW9uXG4gKiBjb250ZXh0cy5cbiAqXG4gKiBTaG91dC1vdXQgdG8gQW5ndWxhciBodHRwczovL2dpdGh1Yi5jb20vYW5ndWxhci9hbmd1bGFyL2Jsb2IvMTUuMi44L3BhY2thZ2VzL2NvcmUvc3JjL3Nhbml0aXphdGlvbi91cmxfc2FuaXRpemVyLnRzI0wzOFxuICovXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgdW5pY29ybi9iZXR0ZXItcmVnZXhcbmNvbnN0IFNBRkVfVVJMX1BBVFRFUk4gPSAvXig/IWphdmFzY3JpcHQ6KSg/OlthLXowLTkrLi1dKzp8W14mOi8/I10qKD86Wy8/I118JCkpL2lcblxuY29uc3QgYWxsb3dlZEF0dHJpYnV0ZSA9IChhdHRyaWJ1dGUsIGFsbG93ZWRBdHRyaWJ1dGVMaXN0KSA9PiB7XG4gIGNvbnN0IGF0dHJpYnV0ZU5hbWUgPSBhdHRyaWJ1dGUubm9kZU5hbWUudG9Mb3dlckNhc2UoKVxuXG4gIGlmIChhbGxvd2VkQXR0cmlidXRlTGlzdC5pbmNsdWRlcyhhdHRyaWJ1dGVOYW1lKSkge1xuICAgIGlmICh1cmlBdHRyaWJ1dGVzLmhhcyhhdHRyaWJ1dGVOYW1lKSkge1xuICAgICAgcmV0dXJuIEJvb2xlYW4oU0FGRV9VUkxfUEFUVEVSTi50ZXN0KGF0dHJpYnV0ZS5ub2RlVmFsdWUpKVxuICAgIH1cblxuICAgIHJldHVybiB0cnVlXG4gIH1cblxuICAvLyBDaGVjayBpZiBhIHJlZ3VsYXIgZXhwcmVzc2lvbiB2YWxpZGF0ZXMgdGhlIGF0dHJpYnV0ZS5cbiAgcmV0dXJuIGFsbG93ZWRBdHRyaWJ1dGVMaXN0LmZpbHRlcihhdHRyaWJ1dGVSZWdleCA9PiBhdHRyaWJ1dGVSZWdleCBpbnN0YW5jZW9mIFJlZ0V4cClcbiAgICAuc29tZShyZWdleCA9PiByZWdleC50ZXN0KGF0dHJpYnV0ZU5hbWUpKVxufVxuXG5leHBvcnQgZnVuY3Rpb24gc2FuaXRpemVIdG1sKHVuc2FmZUh0bWwsIGFsbG93TGlzdCwgc2FuaXRpemVGdW5jdGlvbikge1xuICBpZiAoIXVuc2FmZUh0bWwubGVuZ3RoKSB7XG4gICAgcmV0dXJuIHVuc2FmZUh0bWxcbiAgfVxuXG4gIGlmIChzYW5pdGl6ZUZ1bmN0aW9uICYmIHR5cGVvZiBzYW5pdGl6ZUZ1bmN0aW9uID09PSAnZnVuY3Rpb24nKSB7XG4gICAgcmV0dXJuIHNhbml0aXplRnVuY3Rpb24odW5zYWZlSHRtbClcbiAgfVxuXG4gIGNvbnN0IGRvbVBhcnNlciA9IG5ldyB3aW5kb3cuRE9NUGFyc2VyKClcbiAgY29uc3QgY3JlYXRlZERvY3VtZW50ID0gZG9tUGFyc2VyLnBhcnNlRnJvbVN0cmluZyh1bnNhZmVIdG1sLCAndGV4dC9odG1sJylcbiAgY29uc3QgZWxlbWVudHMgPSBbXS5jb25jYXQoLi4uY3JlYXRlZERvY3VtZW50LmJvZHkucXVlcnlTZWxlY3RvckFsbCgnKicpKVxuXG4gIGZvciAoY29uc3QgZWxlbWVudCBvZiBlbGVtZW50cykge1xuICAgIGNvbnN0IGVsZW1lbnROYW1lID0gZWxlbWVudC5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpXG5cbiAgICBpZiAoIU9iamVjdC5rZXlzKGFsbG93TGlzdCkuaW5jbHVkZXMoZWxlbWVudE5hbWUpKSB7XG4gICAgICBlbGVtZW50LnJlbW92ZSgpXG4gICAgICBjb250aW51ZVxuICAgIH1cblxuICAgIGNvbnN0IGF0dHJpYnV0ZUxpc3QgPSBbXS5jb25jYXQoLi4uZWxlbWVudC5hdHRyaWJ1dGVzKVxuICAgIGNvbnN0IGFsbG93ZWRBdHRyaWJ1dGVzID0gW10uY29uY2F0KGFsbG93TGlzdFsnKiddIHx8IFtdLCBhbGxvd0xpc3RbZWxlbWVudE5hbWVdIHx8IFtdKVxuXG4gICAgZm9yIChjb25zdCBhdHRyaWJ1dGUgb2YgYXR0cmlidXRlTGlzdCkge1xuICAgICAgaWYgKCFhbGxvd2VkQXR0cmlidXRlKGF0dHJpYnV0ZSwgYWxsb3dlZEF0dHJpYnV0ZXMpKSB7XG4gICAgICAgIGVsZW1lbnQucmVtb3ZlQXR0cmlidXRlKGF0dHJpYnV0ZS5ub2RlTmFtZSlcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gY3JlYXRlZERvY3VtZW50LmJvZHkuaW5uZXJIVE1MXG59XG4iLCIvKipcbiAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gKiBCb290c3RyYXAgdXRpbC90ZW1wbGF0ZS1mYWN0b3J5LmpzXG4gKiBMaWNlbnNlZCB1bmRlciBNSVQgKGh0dHBzOi8vZ2l0aHViLmNvbS90d2JzL2Jvb3RzdHJhcC9ibG9iL21haW4vTElDRU5TRSlcbiAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gKi9cblxuaW1wb3J0IFNlbGVjdG9yRW5naW5lIGZyb20gJy4uL2RvbS9zZWxlY3Rvci1lbmdpbmUuanMnXG5pbXBvcnQgQ29uZmlnIGZyb20gJy4vY29uZmlnLmpzJ1xuaW1wb3J0IHsgRGVmYXVsdEFsbG93bGlzdCwgc2FuaXRpemVIdG1sIH0gZnJvbSAnLi9zYW5pdGl6ZXIuanMnXG5pbXBvcnQgeyBleGVjdXRlLCBnZXRFbGVtZW50LCBpc0VsZW1lbnQgfSBmcm9tICcuL2luZGV4LmpzJ1xuXG4vKipcbiAqIENvbnN0YW50c1xuICovXG5cbmNvbnN0IE5BTUUgPSAnVGVtcGxhdGVGYWN0b3J5J1xuXG5jb25zdCBEZWZhdWx0ID0ge1xuICBhbGxvd0xpc3Q6IERlZmF1bHRBbGxvd2xpc3QsXG4gIGNvbnRlbnQ6IHt9LCAvLyB7IHNlbGVjdG9yIDogdGV4dCAsICBzZWxlY3RvcjIgOiB0ZXh0MiAsIH1cbiAgZXh0cmFDbGFzczogJycsXG4gIGh0bWw6IGZhbHNlLFxuICBzYW5pdGl6ZTogdHJ1ZSxcbiAgc2FuaXRpemVGbjogbnVsbCxcbiAgdGVtcGxhdGU6ICc8ZGl2PjwvZGl2Pidcbn1cblxuY29uc3QgRGVmYXVsdFR5cGUgPSB7XG4gIGFsbG93TGlzdDogJ29iamVjdCcsXG4gIGNvbnRlbnQ6ICdvYmplY3QnLFxuICBleHRyYUNsYXNzOiAnKHN0cmluZ3xmdW5jdGlvbiknLFxuICBodG1sOiAnYm9vbGVhbicsXG4gIHNhbml0aXplOiAnYm9vbGVhbicsXG4gIHNhbml0aXplRm46ICcobnVsbHxmdW5jdGlvbiknLFxuICB0ZW1wbGF0ZTogJ3N0cmluZydcbn1cblxuY29uc3QgRGVmYXVsdENvbnRlbnRUeXBlID0ge1xuICBlbnRyeTogJyhzdHJpbmd8ZWxlbWVudHxmdW5jdGlvbnxudWxsKScsXG4gIHNlbGVjdG9yOiAnKHN0cmluZ3xlbGVtZW50KSdcbn1cblxuLyoqXG4gKiBDbGFzcyBkZWZpbml0aW9uXG4gKi9cblxuY2xhc3MgVGVtcGxhdGVGYWN0b3J5IGV4dGVuZHMgQ29uZmlnIHtcbiAgY29uc3RydWN0b3IoY29uZmlnKSB7XG4gICAgc3VwZXIoKVxuICAgIHRoaXMuX2NvbmZpZyA9IHRoaXMuX2dldENvbmZpZyhjb25maWcpXG4gIH1cblxuICAvLyBHZXR0ZXJzXG4gIHN0YXRpYyBnZXQgRGVmYXVsdCgpIHtcbiAgICByZXR1cm4gRGVmYXVsdFxuICB9XG5cbiAgc3RhdGljIGdldCBEZWZhdWx0VHlwZSgpIHtcbiAgICByZXR1cm4gRGVmYXVsdFR5cGVcbiAgfVxuXG4gIHN0YXRpYyBnZXQgTkFNRSgpIHtcbiAgICByZXR1cm4gTkFNRVxuICB9XG5cbiAgLy8gUHVibGljXG4gIGdldENvbnRlbnQoKSB7XG4gICAgcmV0dXJuIE9iamVjdC52YWx1ZXModGhpcy5fY29uZmlnLmNvbnRlbnQpXG4gICAgICAubWFwKGNvbmZpZyA9PiB0aGlzLl9yZXNvbHZlUG9zc2libGVGdW5jdGlvbihjb25maWcpKVxuICAgICAgLmZpbHRlcihCb29sZWFuKVxuICB9XG5cbiAgaGFzQ29udGVudCgpIHtcbiAgICByZXR1cm4gdGhpcy5nZXRDb250ZW50KCkubGVuZ3RoID4gMFxuICB9XG5cbiAgY2hhbmdlQ29udGVudChjb250ZW50KSB7XG4gICAgdGhpcy5fY2hlY2tDb250ZW50KGNvbnRlbnQpXG4gICAgdGhpcy5fY29uZmlnLmNvbnRlbnQgPSB7IC4uLnRoaXMuX2NvbmZpZy5jb250ZW50LCAuLi5jb250ZW50IH1cbiAgICByZXR1cm4gdGhpc1xuICB9XG5cbiAgdG9IdG1sKCkge1xuICAgIGNvbnN0IHRlbXBsYXRlV3JhcHBlciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpXG4gICAgdGVtcGxhdGVXcmFwcGVyLmlubmVySFRNTCA9IHRoaXMuX21heWJlU2FuaXRpemUodGhpcy5fY29uZmlnLnRlbXBsYXRlKVxuXG4gICAgZm9yIChjb25zdCBbc2VsZWN0b3IsIHRleHRdIG9mIE9iamVjdC5lbnRyaWVzKHRoaXMuX2NvbmZpZy5jb250ZW50KSkge1xuICAgICAgdGhpcy5fc2V0Q29udGVudCh0ZW1wbGF0ZVdyYXBwZXIsIHRleHQsIHNlbGVjdG9yKVxuICAgIH1cblxuICAgIGNvbnN0IHRlbXBsYXRlID0gdGVtcGxhdGVXcmFwcGVyLmNoaWxkcmVuWzBdXG4gICAgY29uc3QgZXh0cmFDbGFzcyA9IHRoaXMuX3Jlc29sdmVQb3NzaWJsZUZ1bmN0aW9uKHRoaXMuX2NvbmZpZy5leHRyYUNsYXNzKVxuXG4gICAgaWYgKGV4dHJhQ2xhc3MpIHtcbiAgICAgIHRlbXBsYXRlLmNsYXNzTGlzdC5hZGQoLi4uZXh0cmFDbGFzcy5zcGxpdCgnICcpKVxuICAgIH1cblxuICAgIHJldHVybiB0ZW1wbGF0ZVxuICB9XG5cbiAgLy8gUHJpdmF0ZVxuICBfdHlwZUNoZWNrQ29uZmlnKGNvbmZpZykge1xuICAgIHN1cGVyLl90eXBlQ2hlY2tDb25maWcoY29uZmlnKVxuICAgIHRoaXMuX2NoZWNrQ29udGVudChjb25maWcuY29udGVudClcbiAgfVxuXG4gIF9jaGVja0NvbnRlbnQoYXJnKSB7XG4gICAgZm9yIChjb25zdCBbc2VsZWN0b3IsIGNvbnRlbnRdIG9mIE9iamVjdC5lbnRyaWVzKGFyZykpIHtcbiAgICAgIHN1cGVyLl90eXBlQ2hlY2tDb25maWcoeyBzZWxlY3RvciwgZW50cnk6IGNvbnRlbnQgfSwgRGVmYXVsdENvbnRlbnRUeXBlKVxuICAgIH1cbiAgfVxuXG4gIF9zZXRDb250ZW50KHRlbXBsYXRlLCBjb250ZW50LCBzZWxlY3Rvcikge1xuICAgIGNvbnN0IHRlbXBsYXRlRWxlbWVudCA9IFNlbGVjdG9yRW5naW5lLmZpbmRPbmUoc2VsZWN0b3IsIHRlbXBsYXRlKVxuXG4gICAgaWYgKCF0ZW1wbGF0ZUVsZW1lbnQpIHtcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIGNvbnRlbnQgPSB0aGlzLl9yZXNvbHZlUG9zc2libGVGdW5jdGlvbihjb250ZW50KVxuXG4gICAgaWYgKCFjb250ZW50KSB7XG4gICAgICB0ZW1wbGF0ZUVsZW1lbnQucmVtb3ZlKClcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIGlmIChpc0VsZW1lbnQoY29udGVudCkpIHtcbiAgICAgIHRoaXMuX3B1dEVsZW1lbnRJblRlbXBsYXRlKGdldEVsZW1lbnQoY29udGVudCksIHRlbXBsYXRlRWxlbWVudClcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIGlmICh0aGlzLl9jb25maWcuaHRtbCkge1xuICAgICAgdGVtcGxhdGVFbGVtZW50LmlubmVySFRNTCA9IHRoaXMuX21heWJlU2FuaXRpemUoY29udGVudClcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIHRlbXBsYXRlRWxlbWVudC50ZXh0Q29udGVudCA9IGNvbnRlbnRcbiAgfVxuXG4gIF9tYXliZVNhbml0aXplKGFyZykge1xuICAgIHJldHVybiB0aGlzLl9jb25maWcuc2FuaXRpemUgPyBzYW5pdGl6ZUh0bWwoYXJnLCB0aGlzLl9jb25maWcuYWxsb3dMaXN0LCB0aGlzLl9jb25maWcuc2FuaXRpemVGbikgOiBhcmdcbiAgfVxuXG4gIF9yZXNvbHZlUG9zc2libGVGdW5jdGlvbihhcmcpIHtcbiAgICByZXR1cm4gZXhlY3V0ZShhcmcsIFt0aGlzXSlcbiAgfVxuXG4gIF9wdXRFbGVtZW50SW5UZW1wbGF0ZShlbGVtZW50LCB0ZW1wbGF0ZUVsZW1lbnQpIHtcbiAgICBpZiAodGhpcy5fY29uZmlnLmh0bWwpIHtcbiAgICAgIHRlbXBsYXRlRWxlbWVudC5pbm5lckhUTUwgPSAnJ1xuICAgICAgdGVtcGxhdGVFbGVtZW50LmFwcGVuZChlbGVtZW50KVxuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgdGVtcGxhdGVFbGVtZW50LnRleHRDb250ZW50ID0gZWxlbWVudC50ZXh0Q29udGVudFxuICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IFRlbXBsYXRlRmFjdG9yeVxuIiwiLyoqXG4gKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICogQm9vdHN0cmFwIHRvb2x0aXAuanNcbiAqIExpY2Vuc2VkIHVuZGVyIE1JVCAoaHR0cHM6Ly9naXRodWIuY29tL3R3YnMvYm9vdHN0cmFwL2Jsb2IvbWFpbi9MSUNFTlNFKVxuICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAqL1xuXG5pbXBvcnQgKiBhcyBQb3BwZXIgZnJvbSAnQHBvcHBlcmpzL2NvcmUnXG5pbXBvcnQgQmFzZUNvbXBvbmVudCBmcm9tICcuL2Jhc2UtY29tcG9uZW50LmpzJ1xuaW1wb3J0IEV2ZW50SGFuZGxlciBmcm9tICcuL2RvbS9ldmVudC1oYW5kbGVyLmpzJ1xuaW1wb3J0IE1hbmlwdWxhdG9yIGZyb20gJy4vZG9tL21hbmlwdWxhdG9yLmpzJ1xuaW1wb3J0IHtcbiAgZGVmaW5lSlF1ZXJ5UGx1Z2luLCBleGVjdXRlLCBmaW5kU2hhZG93Um9vdCwgZ2V0RWxlbWVudCwgZ2V0VUlELCBpc1JUTCwgbm9vcFxufSBmcm9tICcuL3V0aWwvaW5kZXguanMnXG5pbXBvcnQgeyBEZWZhdWx0QWxsb3dsaXN0IH0gZnJvbSAnLi91dGlsL3Nhbml0aXplci5qcydcbmltcG9ydCBUZW1wbGF0ZUZhY3RvcnkgZnJvbSAnLi91dGlsL3RlbXBsYXRlLWZhY3RvcnkuanMnXG5cbi8qKlxuICogQ29uc3RhbnRzXG4gKi9cblxuY29uc3QgTkFNRSA9ICd0b29sdGlwJ1xuY29uc3QgRElTQUxMT1dFRF9BVFRSSUJVVEVTID0gbmV3IFNldChbJ3Nhbml0aXplJywgJ2FsbG93TGlzdCcsICdzYW5pdGl6ZUZuJ10pXG5cbmNvbnN0IENMQVNTX05BTUVfRkFERSA9ICdmYWRlJ1xuY29uc3QgQ0xBU1NfTkFNRV9NT0RBTCA9ICdtb2RhbCdcbmNvbnN0IENMQVNTX05BTUVfU0hPVyA9ICdzaG93J1xuXG5jb25zdCBTRUxFQ1RPUl9UT09MVElQX0lOTkVSID0gJy50b29sdGlwLWlubmVyJ1xuY29uc3QgU0VMRUNUT1JfTU9EQUwgPSBgLiR7Q0xBU1NfTkFNRV9NT0RBTH1gXG5cbmNvbnN0IEVWRU5UX01PREFMX0hJREUgPSAnaGlkZS5icy5tb2RhbCdcblxuY29uc3QgVFJJR0dFUl9IT1ZFUiA9ICdob3ZlcidcbmNvbnN0IFRSSUdHRVJfRk9DVVMgPSAnZm9jdXMnXG5jb25zdCBUUklHR0VSX0NMSUNLID0gJ2NsaWNrJ1xuY29uc3QgVFJJR0dFUl9NQU5VQUwgPSAnbWFudWFsJ1xuXG5jb25zdCBFVkVOVF9ISURFID0gJ2hpZGUnXG5jb25zdCBFVkVOVF9ISURERU4gPSAnaGlkZGVuJ1xuY29uc3QgRVZFTlRfU0hPVyA9ICdzaG93J1xuY29uc3QgRVZFTlRfU0hPV04gPSAnc2hvd24nXG5jb25zdCBFVkVOVF9JTlNFUlRFRCA9ICdpbnNlcnRlZCdcbmNvbnN0IEVWRU5UX0NMSUNLID0gJ2NsaWNrJ1xuY29uc3QgRVZFTlRfRk9DVVNJTiA9ICdmb2N1c2luJ1xuY29uc3QgRVZFTlRfRk9DVVNPVVQgPSAnZm9jdXNvdXQnXG5jb25zdCBFVkVOVF9NT1VTRUVOVEVSID0gJ21vdXNlZW50ZXInXG5jb25zdCBFVkVOVF9NT1VTRUxFQVZFID0gJ21vdXNlbGVhdmUnXG5cbmNvbnN0IEF0dGFjaG1lbnRNYXAgPSB7XG4gIEFVVE86ICdhdXRvJyxcbiAgVE9QOiAndG9wJyxcbiAgUklHSFQ6IGlzUlRMKCkgPyAnbGVmdCcgOiAncmlnaHQnLFxuICBCT1RUT006ICdib3R0b20nLFxuICBMRUZUOiBpc1JUTCgpID8gJ3JpZ2h0JyA6ICdsZWZ0J1xufVxuXG5jb25zdCBEZWZhdWx0ID0ge1xuICBhbGxvd0xpc3Q6IERlZmF1bHRBbGxvd2xpc3QsXG4gIGFuaW1hdGlvbjogdHJ1ZSxcbiAgYm91bmRhcnk6ICdjbGlwcGluZ1BhcmVudHMnLFxuICBjb250YWluZXI6IGZhbHNlLFxuICBjdXN0b21DbGFzczogJycsXG4gIGRlbGF5OiAwLFxuICBmYWxsYmFja1BsYWNlbWVudHM6IFsndG9wJywgJ3JpZ2h0JywgJ2JvdHRvbScsICdsZWZ0J10sXG4gIGh0bWw6IGZhbHNlLFxuICBvZmZzZXQ6IFswLCA2XSxcbiAgcGxhY2VtZW50OiAndG9wJyxcbiAgcG9wcGVyQ29uZmlnOiBudWxsLFxuICBzYW5pdGl6ZTogdHJ1ZSxcbiAgc2FuaXRpemVGbjogbnVsbCxcbiAgc2VsZWN0b3I6IGZhbHNlLFxuICB0ZW1wbGF0ZTogJzxkaXYgY2xhc3M9XCJ0b29sdGlwXCIgcm9sZT1cInRvb2x0aXBcIj4nICtcbiAgICAgICAgICAgICc8ZGl2IGNsYXNzPVwidG9vbHRpcC1hcnJvd1wiPjwvZGl2PicgK1xuICAgICAgICAgICAgJzxkaXYgY2xhc3M9XCJ0b29sdGlwLWlubmVyXCI+PC9kaXY+JyArXG4gICAgICAgICAgICAnPC9kaXY+JyxcbiAgdGl0bGU6ICcnLFxuICB0cmlnZ2VyOiAnaG92ZXIgZm9jdXMnXG59XG5cbmNvbnN0IERlZmF1bHRUeXBlID0ge1xuICBhbGxvd0xpc3Q6ICdvYmplY3QnLFxuICBhbmltYXRpb246ICdib29sZWFuJyxcbiAgYm91bmRhcnk6ICcoc3RyaW5nfGVsZW1lbnQpJyxcbiAgY29udGFpbmVyOiAnKHN0cmluZ3xlbGVtZW50fGJvb2xlYW4pJyxcbiAgY3VzdG9tQ2xhc3M6ICcoc3RyaW5nfGZ1bmN0aW9uKScsXG4gIGRlbGF5OiAnKG51bWJlcnxvYmplY3QpJyxcbiAgZmFsbGJhY2tQbGFjZW1lbnRzOiAnYXJyYXknLFxuICBodG1sOiAnYm9vbGVhbicsXG4gIG9mZnNldDogJyhhcnJheXxzdHJpbmd8ZnVuY3Rpb24pJyxcbiAgcGxhY2VtZW50OiAnKHN0cmluZ3xmdW5jdGlvbiknLFxuICBwb3BwZXJDb25maWc6ICcobnVsbHxvYmplY3R8ZnVuY3Rpb24pJyxcbiAgc2FuaXRpemU6ICdib29sZWFuJyxcbiAgc2FuaXRpemVGbjogJyhudWxsfGZ1bmN0aW9uKScsXG4gIHNlbGVjdG9yOiAnKHN0cmluZ3xib29sZWFuKScsXG4gIHRlbXBsYXRlOiAnc3RyaW5nJyxcbiAgdGl0bGU6ICcoc3RyaW5nfGVsZW1lbnR8ZnVuY3Rpb24pJyxcbiAgdHJpZ2dlcjogJ3N0cmluZydcbn1cblxuLyoqXG4gKiBDbGFzcyBkZWZpbml0aW9uXG4gKi9cblxuY2xhc3MgVG9vbHRpcCBleHRlbmRzIEJhc2VDb21wb25lbnQge1xuICBjb25zdHJ1Y3RvcihlbGVtZW50LCBjb25maWcpIHtcbiAgICBpZiAodHlwZW9mIFBvcHBlciA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0Jvb3RzdHJhcFxcJ3MgdG9vbHRpcHMgcmVxdWlyZSBQb3BwZXIgKGh0dHBzOi8vcG9wcGVyLmpzLm9yZyknKVxuICAgIH1cblxuICAgIHN1cGVyKGVsZW1lbnQsIGNvbmZpZylcblxuICAgIC8vIFByaXZhdGVcbiAgICB0aGlzLl9pc0VuYWJsZWQgPSB0cnVlXG4gICAgdGhpcy5fdGltZW91dCA9IDBcbiAgICB0aGlzLl9pc0hvdmVyZWQgPSBudWxsXG4gICAgdGhpcy5fYWN0aXZlVHJpZ2dlciA9IHt9XG4gICAgdGhpcy5fcG9wcGVyID0gbnVsbFxuICAgIHRoaXMuX3RlbXBsYXRlRmFjdG9yeSA9IG51bGxcbiAgICB0aGlzLl9uZXdDb250ZW50ID0gbnVsbFxuXG4gICAgLy8gUHJvdGVjdGVkXG4gICAgdGhpcy50aXAgPSBudWxsXG5cbiAgICB0aGlzLl9zZXRMaXN0ZW5lcnMoKVxuXG4gICAgaWYgKCF0aGlzLl9jb25maWcuc2VsZWN0b3IpIHtcbiAgICAgIHRoaXMuX2ZpeFRpdGxlKClcbiAgICB9XG4gIH1cblxuICAvLyBHZXR0ZXJzXG4gIHN0YXRpYyBnZXQgRGVmYXVsdCgpIHtcbiAgICByZXR1cm4gRGVmYXVsdFxuICB9XG5cbiAgc3RhdGljIGdldCBEZWZhdWx0VHlwZSgpIHtcbiAgICByZXR1cm4gRGVmYXVsdFR5cGVcbiAgfVxuXG4gIHN0YXRpYyBnZXQgTkFNRSgpIHtcbiAgICByZXR1cm4gTkFNRVxuICB9XG5cbiAgLy8gUHVibGljXG4gIGVuYWJsZSgpIHtcbiAgICB0aGlzLl9pc0VuYWJsZWQgPSB0cnVlXG4gIH1cblxuICBkaXNhYmxlKCkge1xuICAgIHRoaXMuX2lzRW5hYmxlZCA9IGZhbHNlXG4gIH1cblxuICB0b2dnbGVFbmFibGVkKCkge1xuICAgIHRoaXMuX2lzRW5hYmxlZCA9ICF0aGlzLl9pc0VuYWJsZWRcbiAgfVxuXG4gIHRvZ2dsZSgpIHtcbiAgICBpZiAoIXRoaXMuX2lzRW5hYmxlZCkge1xuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgdGhpcy5fYWN0aXZlVHJpZ2dlci5jbGljayA9ICF0aGlzLl9hY3RpdmVUcmlnZ2VyLmNsaWNrXG4gICAgaWYgKHRoaXMuX2lzU2hvd24oKSkge1xuICAgICAgdGhpcy5fbGVhdmUoKVxuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgdGhpcy5fZW50ZXIoKVxuICB9XG5cbiAgZGlzcG9zZSgpIHtcbiAgICBjbGVhclRpbWVvdXQodGhpcy5fdGltZW91dClcblxuICAgIEV2ZW50SGFuZGxlci5vZmYodGhpcy5fZWxlbWVudC5jbG9zZXN0KFNFTEVDVE9SX01PREFMKSwgRVZFTlRfTU9EQUxfSElERSwgdGhpcy5faGlkZU1vZGFsSGFuZGxlcilcblxuICAgIGlmICh0aGlzLl9lbGVtZW50LmdldEF0dHJpYnV0ZSgnZGF0YS1icy1vcmlnaW5hbC10aXRsZScpKSB7XG4gICAgICB0aGlzLl9lbGVtZW50LnNldEF0dHJpYnV0ZSgndGl0bGUnLCB0aGlzLl9lbGVtZW50LmdldEF0dHJpYnV0ZSgnZGF0YS1icy1vcmlnaW5hbC10aXRsZScpKVxuICAgIH1cblxuICAgIHRoaXMuX2Rpc3Bvc2VQb3BwZXIoKVxuICAgIHN1cGVyLmRpc3Bvc2UoKVxuICB9XG5cbiAgc2hvdygpIHtcbiAgICBpZiAodGhpcy5fZWxlbWVudC5zdHlsZS5kaXNwbGF5ID09PSAnbm9uZScpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignUGxlYXNlIHVzZSBzaG93IG9uIHZpc2libGUgZWxlbWVudHMnKVxuICAgIH1cblxuICAgIGlmICghKHRoaXMuX2lzV2l0aENvbnRlbnQoKSAmJiB0aGlzLl9pc0VuYWJsZWQpKSB7XG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICBjb25zdCBzaG93RXZlbnQgPSBFdmVudEhhbmRsZXIudHJpZ2dlcih0aGlzLl9lbGVtZW50LCB0aGlzLmNvbnN0cnVjdG9yLmV2ZW50TmFtZShFVkVOVF9TSE9XKSlcbiAgICBjb25zdCBzaGFkb3dSb290ID0gZmluZFNoYWRvd1Jvb3QodGhpcy5fZWxlbWVudClcbiAgICBjb25zdCBpc0luVGhlRG9tID0gKHNoYWRvd1Jvb3QgfHwgdGhpcy5fZWxlbWVudC5vd25lckRvY3VtZW50LmRvY3VtZW50RWxlbWVudCkuY29udGFpbnModGhpcy5fZWxlbWVudClcblxuICAgIGlmIChzaG93RXZlbnQuZGVmYXVsdFByZXZlbnRlZCB8fCAhaXNJblRoZURvbSkge1xuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgLy8gVE9ETzogdjYgcmVtb3ZlIHRoaXMgb3IgbWFrZSBpdCBvcHRpb25hbFxuICAgIHRoaXMuX2Rpc3Bvc2VQb3BwZXIoKVxuXG4gICAgY29uc3QgdGlwID0gdGhpcy5fZ2V0VGlwRWxlbWVudCgpXG5cbiAgICB0aGlzLl9lbGVtZW50LnNldEF0dHJpYnV0ZSgnYXJpYS1kZXNjcmliZWRieScsIHRpcC5nZXRBdHRyaWJ1dGUoJ2lkJykpXG5cbiAgICBjb25zdCB7IGNvbnRhaW5lciB9ID0gdGhpcy5fY29uZmlnXG5cbiAgICBpZiAoIXRoaXMuX2VsZW1lbnQub3duZXJEb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuY29udGFpbnModGhpcy50aXApKSB7XG4gICAgICBjb250YWluZXIuYXBwZW5kKHRpcClcbiAgICAgIEV2ZW50SGFuZGxlci50cmlnZ2VyKHRoaXMuX2VsZW1lbnQsIHRoaXMuY29uc3RydWN0b3IuZXZlbnROYW1lKEVWRU5UX0lOU0VSVEVEKSlcbiAgICB9XG5cbiAgICB0aGlzLl9wb3BwZXIgPSB0aGlzLl9jcmVhdGVQb3BwZXIodGlwKVxuXG4gICAgdGlwLmNsYXNzTGlzdC5hZGQoQ0xBU1NfTkFNRV9TSE9XKVxuXG4gICAgLy8gSWYgdGhpcyBpcyBhIHRvdWNoLWVuYWJsZWQgZGV2aWNlIHdlIGFkZCBleHRyYVxuICAgIC8vIGVtcHR5IG1vdXNlb3ZlciBsaXN0ZW5lcnMgdG8gdGhlIGJvZHkncyBpbW1lZGlhdGUgY2hpbGRyZW47XG4gICAgLy8gb25seSBuZWVkZWQgYmVjYXVzZSBvZiBicm9rZW4gZXZlbnQgZGVsZWdhdGlvbiBvbiBpT1NcbiAgICAvLyBodHRwczovL3d3dy5xdWlya3Ntb2RlLm9yZy9ibG9nL2FyY2hpdmVzLzIwMTQvMDIvbW91c2VfZXZlbnRfYnViLmh0bWxcbiAgICBpZiAoJ29udG91Y2hzdGFydCcgaW4gZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50KSB7XG4gICAgICBmb3IgKGNvbnN0IGVsZW1lbnQgb2YgW10uY29uY2F0KC4uLmRvY3VtZW50LmJvZHkuY2hpbGRyZW4pKSB7XG4gICAgICAgIEV2ZW50SGFuZGxlci5vbihlbGVtZW50LCAnbW91c2VvdmVyJywgbm9vcClcbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCBjb21wbGV0ZSA9ICgpID0+IHtcbiAgICAgIEV2ZW50SGFuZGxlci50cmlnZ2VyKHRoaXMuX2VsZW1lbnQsIHRoaXMuY29uc3RydWN0b3IuZXZlbnROYW1lKEVWRU5UX1NIT1dOKSlcblxuICAgICAgaWYgKHRoaXMuX2lzSG92ZXJlZCA9PT0gZmFsc2UpIHtcbiAgICAgICAgdGhpcy5fbGVhdmUoKVxuICAgICAgfVxuXG4gICAgICB0aGlzLl9pc0hvdmVyZWQgPSBmYWxzZVxuICAgIH1cblxuICAgIHRoaXMuX3F1ZXVlQ2FsbGJhY2soY29tcGxldGUsIHRoaXMudGlwLCB0aGlzLl9pc0FuaW1hdGVkKCkpXG4gIH1cblxuICBoaWRlKCkge1xuICAgIGlmICghdGhpcy5faXNTaG93bigpKSB7XG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICBjb25zdCBoaWRlRXZlbnQgPSBFdmVudEhhbmRsZXIudHJpZ2dlcih0aGlzLl9lbGVtZW50LCB0aGlzLmNvbnN0cnVjdG9yLmV2ZW50TmFtZShFVkVOVF9ISURFKSlcbiAgICBpZiAoaGlkZUV2ZW50LmRlZmF1bHRQcmV2ZW50ZWQpIHtcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIGNvbnN0IHRpcCA9IHRoaXMuX2dldFRpcEVsZW1lbnQoKVxuICAgIHRpcC5jbGFzc0xpc3QucmVtb3ZlKENMQVNTX05BTUVfU0hPVylcblxuICAgIC8vIElmIHRoaXMgaXMgYSB0b3VjaC1lbmFibGVkIGRldmljZSB3ZSByZW1vdmUgdGhlIGV4dHJhXG4gICAgLy8gZW1wdHkgbW91c2VvdmVyIGxpc3RlbmVycyB3ZSBhZGRlZCBmb3IgaU9TIHN1cHBvcnRcbiAgICBpZiAoJ29udG91Y2hzdGFydCcgaW4gZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50KSB7XG4gICAgICBmb3IgKGNvbnN0IGVsZW1lbnQgb2YgW10uY29uY2F0KC4uLmRvY3VtZW50LmJvZHkuY2hpbGRyZW4pKSB7XG4gICAgICAgIEV2ZW50SGFuZGxlci5vZmYoZWxlbWVudCwgJ21vdXNlb3ZlcicsIG5vb3ApXG4gICAgICB9XG4gICAgfVxuXG4gICAgdGhpcy5fYWN0aXZlVHJpZ2dlcltUUklHR0VSX0NMSUNLXSA9IGZhbHNlXG4gICAgdGhpcy5fYWN0aXZlVHJpZ2dlcltUUklHR0VSX0ZPQ1VTXSA9IGZhbHNlXG4gICAgdGhpcy5fYWN0aXZlVHJpZ2dlcltUUklHR0VSX0hPVkVSXSA9IGZhbHNlXG4gICAgdGhpcy5faXNIb3ZlcmVkID0gbnVsbCAvLyBpdCBpcyBhIHRyaWNrIHRvIHN1cHBvcnQgbWFudWFsIHRyaWdnZXJpbmdcblxuICAgIGNvbnN0IGNvbXBsZXRlID0gKCkgPT4ge1xuICAgICAgaWYgKHRoaXMuX2lzV2l0aEFjdGl2ZVRyaWdnZXIoKSkge1xuICAgICAgICByZXR1cm5cbiAgICAgIH1cblxuICAgICAgaWYgKCF0aGlzLl9pc0hvdmVyZWQpIHtcbiAgICAgICAgdGhpcy5fZGlzcG9zZVBvcHBlcigpXG4gICAgICB9XG5cbiAgICAgIHRoaXMuX2VsZW1lbnQucmVtb3ZlQXR0cmlidXRlKCdhcmlhLWRlc2NyaWJlZGJ5JylcbiAgICAgIEV2ZW50SGFuZGxlci50cmlnZ2VyKHRoaXMuX2VsZW1lbnQsIHRoaXMuY29uc3RydWN0b3IuZXZlbnROYW1lKEVWRU5UX0hJRERFTikpXG4gICAgfVxuXG4gICAgdGhpcy5fcXVldWVDYWxsYmFjayhjb21wbGV0ZSwgdGhpcy50aXAsIHRoaXMuX2lzQW5pbWF0ZWQoKSlcbiAgfVxuXG4gIHVwZGF0ZSgpIHtcbiAgICBpZiAodGhpcy5fcG9wcGVyKSB7XG4gICAgICB0aGlzLl9wb3BwZXIudXBkYXRlKClcbiAgICB9XG4gIH1cblxuICAvLyBQcm90ZWN0ZWRcbiAgX2lzV2l0aENvbnRlbnQoKSB7XG4gICAgcmV0dXJuIEJvb2xlYW4odGhpcy5fZ2V0VGl0bGUoKSlcbiAgfVxuXG4gIF9nZXRUaXBFbGVtZW50KCkge1xuICAgIGlmICghdGhpcy50aXApIHtcbiAgICAgIHRoaXMudGlwID0gdGhpcy5fY3JlYXRlVGlwRWxlbWVudCh0aGlzLl9uZXdDb250ZW50IHx8IHRoaXMuX2dldENvbnRlbnRGb3JUZW1wbGF0ZSgpKVxuICAgIH1cblxuICAgIHJldHVybiB0aGlzLnRpcFxuICB9XG5cbiAgX2NyZWF0ZVRpcEVsZW1lbnQoY29udGVudCkge1xuICAgIGNvbnN0IHRpcCA9IHRoaXMuX2dldFRlbXBsYXRlRmFjdG9yeShjb250ZW50KS50b0h0bWwoKVxuXG4gICAgLy8gVE9ETzogcmVtb3ZlIHRoaXMgY2hlY2sgaW4gdjZcbiAgICBpZiAoIXRpcCkge1xuICAgICAgcmV0dXJuIG51bGxcbiAgICB9XG5cbiAgICB0aXAuY2xhc3NMaXN0LnJlbW92ZShDTEFTU19OQU1FX0ZBREUsIENMQVNTX05BTUVfU0hPVylcbiAgICAvLyBUT0RPOiB2NiB0aGUgZm9sbG93aW5nIGNhbiBiZSBhY2hpZXZlZCB3aXRoIENTUyBvbmx5XG4gICAgdGlwLmNsYXNzTGlzdC5hZGQoYGJzLSR7dGhpcy5jb25zdHJ1Y3Rvci5OQU1FfS1hdXRvYClcblxuICAgIGNvbnN0IHRpcElkID0gZ2V0VUlEKHRoaXMuY29uc3RydWN0b3IuTkFNRSkudG9TdHJpbmcoKVxuXG4gICAgdGlwLnNldEF0dHJpYnV0ZSgnaWQnLCB0aXBJZClcblxuICAgIGlmICh0aGlzLl9pc0FuaW1hdGVkKCkpIHtcbiAgICAgIHRpcC5jbGFzc0xpc3QuYWRkKENMQVNTX05BTUVfRkFERSlcbiAgICB9XG5cbiAgICByZXR1cm4gdGlwXG4gIH1cblxuICBzZXRDb250ZW50KGNvbnRlbnQpIHtcbiAgICB0aGlzLl9uZXdDb250ZW50ID0gY29udGVudFxuICAgIGlmICh0aGlzLl9pc1Nob3duKCkpIHtcbiAgICAgIHRoaXMuX2Rpc3Bvc2VQb3BwZXIoKVxuICAgICAgdGhpcy5zaG93KClcbiAgICB9XG4gIH1cblxuICBfZ2V0VGVtcGxhdGVGYWN0b3J5KGNvbnRlbnQpIHtcbiAgICBpZiAodGhpcy5fdGVtcGxhdGVGYWN0b3J5KSB7XG4gICAgICB0aGlzLl90ZW1wbGF0ZUZhY3RvcnkuY2hhbmdlQ29udGVudChjb250ZW50KVxuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLl90ZW1wbGF0ZUZhY3RvcnkgPSBuZXcgVGVtcGxhdGVGYWN0b3J5KHtcbiAgICAgICAgLi4udGhpcy5fY29uZmlnLFxuICAgICAgICAvLyB0aGUgYGNvbnRlbnRgIHZhciBoYXMgdG8gYmUgYWZ0ZXIgYHRoaXMuX2NvbmZpZ2BcbiAgICAgICAgLy8gdG8gb3ZlcnJpZGUgY29uZmlnLmNvbnRlbnQgaW4gY2FzZSBvZiBwb3BvdmVyXG4gICAgICAgIGNvbnRlbnQsXG4gICAgICAgIGV4dHJhQ2xhc3M6IHRoaXMuX3Jlc29sdmVQb3NzaWJsZUZ1bmN0aW9uKHRoaXMuX2NvbmZpZy5jdXN0b21DbGFzcylcbiAgICAgIH0pXG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuX3RlbXBsYXRlRmFjdG9yeVxuICB9XG5cbiAgX2dldENvbnRlbnRGb3JUZW1wbGF0ZSgpIHtcbiAgICByZXR1cm4ge1xuICAgICAgW1NFTEVDVE9SX1RPT0xUSVBfSU5ORVJdOiB0aGlzLl9nZXRUaXRsZSgpXG4gICAgfVxuICB9XG5cbiAgX2dldFRpdGxlKCkge1xuICAgIHJldHVybiB0aGlzLl9yZXNvbHZlUG9zc2libGVGdW5jdGlvbih0aGlzLl9jb25maWcudGl0bGUpIHx8IHRoaXMuX2VsZW1lbnQuZ2V0QXR0cmlidXRlKCdkYXRhLWJzLW9yaWdpbmFsLXRpdGxlJylcbiAgfVxuXG4gIC8vIFByaXZhdGVcbiAgX2luaXRpYWxpemVPbkRlbGVnYXRlZFRhcmdldChldmVudCkge1xuICAgIHJldHVybiB0aGlzLmNvbnN0cnVjdG9yLmdldE9yQ3JlYXRlSW5zdGFuY2UoZXZlbnQuZGVsZWdhdGVUYXJnZXQsIHRoaXMuX2dldERlbGVnYXRlQ29uZmlnKCkpXG4gIH1cblxuICBfaXNBbmltYXRlZCgpIHtcbiAgICByZXR1cm4gdGhpcy5fY29uZmlnLmFuaW1hdGlvbiB8fCAodGhpcy50aXAgJiYgdGhpcy50aXAuY2xhc3NMaXN0LmNvbnRhaW5zKENMQVNTX05BTUVfRkFERSkpXG4gIH1cblxuICBfaXNTaG93bigpIHtcbiAgICByZXR1cm4gdGhpcy50aXAgJiYgdGhpcy50aXAuY2xhc3NMaXN0LmNvbnRhaW5zKENMQVNTX05BTUVfU0hPVylcbiAgfVxuXG4gIF9jcmVhdGVQb3BwZXIodGlwKSB7XG4gICAgY29uc3QgcGxhY2VtZW50ID0gZXhlY3V0ZSh0aGlzLl9jb25maWcucGxhY2VtZW50LCBbdGhpcywgdGlwLCB0aGlzLl9lbGVtZW50XSlcbiAgICBjb25zdCBhdHRhY2htZW50ID0gQXR0YWNobWVudE1hcFtwbGFjZW1lbnQudG9VcHBlckNhc2UoKV1cbiAgICByZXR1cm4gUG9wcGVyLmNyZWF0ZVBvcHBlcih0aGlzLl9lbGVtZW50LCB0aXAsIHRoaXMuX2dldFBvcHBlckNvbmZpZyhhdHRhY2htZW50KSlcbiAgfVxuXG4gIF9nZXRPZmZzZXQoKSB7XG4gICAgY29uc3QgeyBvZmZzZXQgfSA9IHRoaXMuX2NvbmZpZ1xuXG4gICAgaWYgKHR5cGVvZiBvZmZzZXQgPT09ICdzdHJpbmcnKSB7XG4gICAgICByZXR1cm4gb2Zmc2V0LnNwbGl0KCcsJykubWFwKHZhbHVlID0+IE51bWJlci5wYXJzZUludCh2YWx1ZSwgMTApKVxuICAgIH1cblxuICAgIGlmICh0eXBlb2Ygb2Zmc2V0ID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICByZXR1cm4gcG9wcGVyRGF0YSA9PiBvZmZzZXQocG9wcGVyRGF0YSwgdGhpcy5fZWxlbWVudClcbiAgICB9XG5cbiAgICByZXR1cm4gb2Zmc2V0XG4gIH1cblxuICBfcmVzb2x2ZVBvc3NpYmxlRnVuY3Rpb24oYXJnKSB7XG4gICAgcmV0dXJuIGV4ZWN1dGUoYXJnLCBbdGhpcy5fZWxlbWVudF0pXG4gIH1cblxuICBfZ2V0UG9wcGVyQ29uZmlnKGF0dGFjaG1lbnQpIHtcbiAgICBjb25zdCBkZWZhdWx0QnNQb3BwZXJDb25maWcgPSB7XG4gICAgICBwbGFjZW1lbnQ6IGF0dGFjaG1lbnQsXG4gICAgICBtb2RpZmllcnM6IFtcbiAgICAgICAge1xuICAgICAgICAgIG5hbWU6ICdmbGlwJyxcbiAgICAgICAgICBvcHRpb25zOiB7XG4gICAgICAgICAgICBmYWxsYmFja1BsYWNlbWVudHM6IHRoaXMuX2NvbmZpZy5mYWxsYmFja1BsYWNlbWVudHNcbiAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICAgIHtcbiAgICAgICAgICBuYW1lOiAnb2Zmc2V0JyxcbiAgICAgICAgICBvcHRpb25zOiB7XG4gICAgICAgICAgICBvZmZzZXQ6IHRoaXMuX2dldE9mZnNldCgpXG4gICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgbmFtZTogJ3ByZXZlbnRPdmVyZmxvdycsXG4gICAgICAgICAgb3B0aW9uczoge1xuICAgICAgICAgICAgYm91bmRhcnk6IHRoaXMuX2NvbmZpZy5ib3VuZGFyeVxuICAgICAgICAgIH1cbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgIG5hbWU6ICdhcnJvdycsXG4gICAgICAgICAgb3B0aW9uczoge1xuICAgICAgICAgICAgZWxlbWVudDogYC4ke3RoaXMuY29uc3RydWN0b3IuTkFNRX0tYXJyb3dgXG4gICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgbmFtZTogJ3ByZVNldFBsYWNlbWVudCcsXG4gICAgICAgICAgZW5hYmxlZDogdHJ1ZSxcbiAgICAgICAgICBwaGFzZTogJ2JlZm9yZU1haW4nLFxuICAgICAgICAgIGZuOiBkYXRhID0+IHtcbiAgICAgICAgICAgIC8vIFByZS1zZXQgUG9wcGVyJ3MgcGxhY2VtZW50IGF0dHJpYnV0ZSBpbiBvcmRlciB0byByZWFkIHRoZSBhcnJvdyBzaXplcyBwcm9wZXJseS5cbiAgICAgICAgICAgIC8vIE90aGVyd2lzZSwgUG9wcGVyIG1peGVzIHVwIHRoZSB3aWR0aCBhbmQgaGVpZ2h0IGRpbWVuc2lvbnMgc2luY2UgdGhlIGluaXRpYWwgYXJyb3cgc3R5bGUgaXMgZm9yIHRvcCBwbGFjZW1lbnRcbiAgICAgICAgICAgIHRoaXMuX2dldFRpcEVsZW1lbnQoKS5zZXRBdHRyaWJ1dGUoJ2RhdGEtcG9wcGVyLXBsYWNlbWVudCcsIGRhdGEuc3RhdGUucGxhY2VtZW50KVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgXVxuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICAuLi5kZWZhdWx0QnNQb3BwZXJDb25maWcsXG4gICAgICAuLi5leGVjdXRlKHRoaXMuX2NvbmZpZy5wb3BwZXJDb25maWcsIFtkZWZhdWx0QnNQb3BwZXJDb25maWddKVxuICAgIH1cbiAgfVxuXG4gIF9zZXRMaXN0ZW5lcnMoKSB7XG4gICAgY29uc3QgdHJpZ2dlcnMgPSB0aGlzLl9jb25maWcudHJpZ2dlci5zcGxpdCgnICcpXG5cbiAgICBmb3IgKGNvbnN0IHRyaWdnZXIgb2YgdHJpZ2dlcnMpIHtcbiAgICAgIGlmICh0cmlnZ2VyID09PSAnY2xpY2snKSB7XG4gICAgICAgIEV2ZW50SGFuZGxlci5vbih0aGlzLl9lbGVtZW50LCB0aGlzLmNvbnN0cnVjdG9yLmV2ZW50TmFtZShFVkVOVF9DTElDSyksIHRoaXMuX2NvbmZpZy5zZWxlY3RvciwgZXZlbnQgPT4ge1xuICAgICAgICAgIGNvbnN0IGNvbnRleHQgPSB0aGlzLl9pbml0aWFsaXplT25EZWxlZ2F0ZWRUYXJnZXQoZXZlbnQpXG4gICAgICAgICAgY29udGV4dC50b2dnbGUoKVxuICAgICAgICB9KVxuICAgICAgfSBlbHNlIGlmICh0cmlnZ2VyICE9PSBUUklHR0VSX01BTlVBTCkge1xuICAgICAgICBjb25zdCBldmVudEluID0gdHJpZ2dlciA9PT0gVFJJR0dFUl9IT1ZFUiA/XG4gICAgICAgICAgdGhpcy5jb25zdHJ1Y3Rvci5ldmVudE5hbWUoRVZFTlRfTU9VU0VFTlRFUikgOlxuICAgICAgICAgIHRoaXMuY29uc3RydWN0b3IuZXZlbnROYW1lKEVWRU5UX0ZPQ1VTSU4pXG4gICAgICAgIGNvbnN0IGV2ZW50T3V0ID0gdHJpZ2dlciA9PT0gVFJJR0dFUl9IT1ZFUiA/XG4gICAgICAgICAgdGhpcy5jb25zdHJ1Y3Rvci5ldmVudE5hbWUoRVZFTlRfTU9VU0VMRUFWRSkgOlxuICAgICAgICAgIHRoaXMuY29uc3RydWN0b3IuZXZlbnROYW1lKEVWRU5UX0ZPQ1VTT1VUKVxuXG4gICAgICAgIEV2ZW50SGFuZGxlci5vbih0aGlzLl9lbGVtZW50LCBldmVudEluLCB0aGlzLl9jb25maWcuc2VsZWN0b3IsIGV2ZW50ID0+IHtcbiAgICAgICAgICBjb25zdCBjb250ZXh0ID0gdGhpcy5faW5pdGlhbGl6ZU9uRGVsZWdhdGVkVGFyZ2V0KGV2ZW50KVxuICAgICAgICAgIGNvbnRleHQuX2FjdGl2ZVRyaWdnZXJbZXZlbnQudHlwZSA9PT0gJ2ZvY3VzaW4nID8gVFJJR0dFUl9GT0NVUyA6IFRSSUdHRVJfSE9WRVJdID0gdHJ1ZVxuICAgICAgICAgIGNvbnRleHQuX2VudGVyKClcbiAgICAgICAgfSlcbiAgICAgICAgRXZlbnRIYW5kbGVyLm9uKHRoaXMuX2VsZW1lbnQsIGV2ZW50T3V0LCB0aGlzLl9jb25maWcuc2VsZWN0b3IsIGV2ZW50ID0+IHtcbiAgICAgICAgICBjb25zdCBjb250ZXh0ID0gdGhpcy5faW5pdGlhbGl6ZU9uRGVsZWdhdGVkVGFyZ2V0KGV2ZW50KVxuICAgICAgICAgIGNvbnRleHQuX2FjdGl2ZVRyaWdnZXJbZXZlbnQudHlwZSA9PT0gJ2ZvY3Vzb3V0JyA/IFRSSUdHRVJfRk9DVVMgOiBUUklHR0VSX0hPVkVSXSA9XG4gICAgICAgICAgICBjb250ZXh0Ll9lbGVtZW50LmNvbnRhaW5zKGV2ZW50LnJlbGF0ZWRUYXJnZXQpXG5cbiAgICAgICAgICBjb250ZXh0Ll9sZWF2ZSgpXG4gICAgICAgIH0pXG4gICAgICB9XG4gICAgfVxuXG4gICAgdGhpcy5faGlkZU1vZGFsSGFuZGxlciA9ICgpID0+IHtcbiAgICAgIGlmICh0aGlzLl9lbGVtZW50KSB7XG4gICAgICAgIHRoaXMuaGlkZSgpXG4gICAgICB9XG4gICAgfVxuXG4gICAgRXZlbnRIYW5kbGVyLm9uKHRoaXMuX2VsZW1lbnQuY2xvc2VzdChTRUxFQ1RPUl9NT0RBTCksIEVWRU5UX01PREFMX0hJREUsIHRoaXMuX2hpZGVNb2RhbEhhbmRsZXIpXG4gIH1cblxuICBfZml4VGl0bGUoKSB7XG4gICAgY29uc3QgdGl0bGUgPSB0aGlzLl9lbGVtZW50LmdldEF0dHJpYnV0ZSgndGl0bGUnKVxuXG4gICAgaWYgKCF0aXRsZSkge1xuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgaWYgKCF0aGlzLl9lbGVtZW50LmdldEF0dHJpYnV0ZSgnYXJpYS1sYWJlbCcpICYmICF0aGlzLl9lbGVtZW50LnRleHRDb250ZW50LnRyaW0oKSkge1xuICAgICAgdGhpcy5fZWxlbWVudC5zZXRBdHRyaWJ1dGUoJ2FyaWEtbGFiZWwnLCB0aXRsZSlcbiAgICB9XG5cbiAgICB0aGlzLl9lbGVtZW50LnNldEF0dHJpYnV0ZSgnZGF0YS1icy1vcmlnaW5hbC10aXRsZScsIHRpdGxlKSAvLyBETyBOT1QgVVNFIElULiBJcyBvbmx5IGZvciBiYWNrd2FyZHMgY29tcGF0aWJpbGl0eVxuICAgIHRoaXMuX2VsZW1lbnQucmVtb3ZlQXR0cmlidXRlKCd0aXRsZScpXG4gIH1cblxuICBfZW50ZXIoKSB7XG4gICAgaWYgKHRoaXMuX2lzU2hvd24oKSB8fCB0aGlzLl9pc0hvdmVyZWQpIHtcbiAgICAgIHRoaXMuX2lzSG92ZXJlZCA9IHRydWVcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIHRoaXMuX2lzSG92ZXJlZCA9IHRydWVcblxuICAgIHRoaXMuX3NldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgaWYgKHRoaXMuX2lzSG92ZXJlZCkge1xuICAgICAgICB0aGlzLnNob3coKVxuICAgICAgfVxuICAgIH0sIHRoaXMuX2NvbmZpZy5kZWxheS5zaG93KVxuICB9XG5cbiAgX2xlYXZlKCkge1xuICAgIGlmICh0aGlzLl9pc1dpdGhBY3RpdmVUcmlnZ2VyKCkpIHtcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIHRoaXMuX2lzSG92ZXJlZCA9IGZhbHNlXG5cbiAgICB0aGlzLl9zZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIGlmICghdGhpcy5faXNIb3ZlcmVkKSB7XG4gICAgICAgIHRoaXMuaGlkZSgpXG4gICAgICB9XG4gICAgfSwgdGhpcy5fY29uZmlnLmRlbGF5LmhpZGUpXG4gIH1cblxuICBfc2V0VGltZW91dChoYW5kbGVyLCB0aW1lb3V0KSB7XG4gICAgY2xlYXJUaW1lb3V0KHRoaXMuX3RpbWVvdXQpXG4gICAgdGhpcy5fdGltZW91dCA9IHNldFRpbWVvdXQoaGFuZGxlciwgdGltZW91dClcbiAgfVxuXG4gIF9pc1dpdGhBY3RpdmVUcmlnZ2VyKCkge1xuICAgIHJldHVybiBPYmplY3QudmFsdWVzKHRoaXMuX2FjdGl2ZVRyaWdnZXIpLmluY2x1ZGVzKHRydWUpXG4gIH1cblxuICBfZ2V0Q29uZmlnKGNvbmZpZykge1xuICAgIGNvbnN0IGRhdGFBdHRyaWJ1dGVzID0gTWFuaXB1bGF0b3IuZ2V0RGF0YUF0dHJpYnV0ZXModGhpcy5fZWxlbWVudClcblxuICAgIGZvciAoY29uc3QgZGF0YUF0dHJpYnV0ZSBvZiBPYmplY3Qua2V5cyhkYXRhQXR0cmlidXRlcykpIHtcbiAgICAgIGlmIChESVNBTExPV0VEX0FUVFJJQlVURVMuaGFzKGRhdGFBdHRyaWJ1dGUpKSB7XG4gICAgICAgIGRlbGV0ZSBkYXRhQXR0cmlidXRlc1tkYXRhQXR0cmlidXRlXVxuICAgICAgfVxuICAgIH1cblxuICAgIGNvbmZpZyA9IHtcbiAgICAgIC4uLmRhdGFBdHRyaWJ1dGVzLFxuICAgICAgLi4uKHR5cGVvZiBjb25maWcgPT09ICdvYmplY3QnICYmIGNvbmZpZyA/IGNvbmZpZyA6IHt9KVxuICAgIH1cbiAgICBjb25maWcgPSB0aGlzLl9tZXJnZUNvbmZpZ09iaihjb25maWcpXG4gICAgY29uZmlnID0gdGhpcy5fY29uZmlnQWZ0ZXJNZXJnZShjb25maWcpXG4gICAgdGhpcy5fdHlwZUNoZWNrQ29uZmlnKGNvbmZpZylcbiAgICByZXR1cm4gY29uZmlnXG4gIH1cblxuICBfY29uZmlnQWZ0ZXJNZXJnZShjb25maWcpIHtcbiAgICBjb25maWcuY29udGFpbmVyID0gY29uZmlnLmNvbnRhaW5lciA9PT0gZmFsc2UgPyBkb2N1bWVudC5ib2R5IDogZ2V0RWxlbWVudChjb25maWcuY29udGFpbmVyKVxuXG4gICAgaWYgKHR5cGVvZiBjb25maWcuZGVsYXkgPT09ICdudW1iZXInKSB7XG4gICAgICBjb25maWcuZGVsYXkgPSB7XG4gICAgICAgIHNob3c6IGNvbmZpZy5kZWxheSxcbiAgICAgICAgaGlkZTogY29uZmlnLmRlbGF5XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBjb25maWcudGl0bGUgPT09ICdudW1iZXInKSB7XG4gICAgICBjb25maWcudGl0bGUgPSBjb25maWcudGl0bGUudG9TdHJpbmcoKVxuICAgIH1cblxuICAgIGlmICh0eXBlb2YgY29uZmlnLmNvbnRlbnQgPT09ICdudW1iZXInKSB7XG4gICAgICBjb25maWcuY29udGVudCA9IGNvbmZpZy5jb250ZW50LnRvU3RyaW5nKClcbiAgICB9XG5cbiAgICByZXR1cm4gY29uZmlnXG4gIH1cblxuICBfZ2V0RGVsZWdhdGVDb25maWcoKSB7XG4gICAgY29uc3QgY29uZmlnID0ge31cblxuICAgIGZvciAoY29uc3QgW2tleSwgdmFsdWVdIG9mIE9iamVjdC5lbnRyaWVzKHRoaXMuX2NvbmZpZykpIHtcbiAgICAgIGlmICh0aGlzLmNvbnN0cnVjdG9yLkRlZmF1bHRba2V5XSAhPT0gdmFsdWUpIHtcbiAgICAgICAgY29uZmlnW2tleV0gPSB2YWx1ZVxuICAgICAgfVxuICAgIH1cblxuICAgIGNvbmZpZy5zZWxlY3RvciA9IGZhbHNlXG4gICAgY29uZmlnLnRyaWdnZXIgPSAnbWFudWFsJ1xuXG4gICAgLy8gSW4gdGhlIGZ1dHVyZSBjYW4gYmUgcmVwbGFjZWQgd2l0aDpcbiAgICAvLyBjb25zdCBrZXlzV2l0aERpZmZlcmVudFZhbHVlcyA9IE9iamVjdC5lbnRyaWVzKHRoaXMuX2NvbmZpZykuZmlsdGVyKGVudHJ5ID0+IHRoaXMuY29uc3RydWN0b3IuRGVmYXVsdFtlbnRyeVswXV0gIT09IHRoaXMuX2NvbmZpZ1tlbnRyeVswXV0pXG4gICAgLy8gYE9iamVjdC5mcm9tRW50cmllcyhrZXlzV2l0aERpZmZlcmVudFZhbHVlcylgXG4gICAgcmV0dXJuIGNvbmZpZ1xuICB9XG5cbiAgX2Rpc3Bvc2VQb3BwZXIoKSB7XG4gICAgaWYgKHRoaXMuX3BvcHBlcikge1xuICAgICAgdGhpcy5fcG9wcGVyLmRlc3Ryb3koKVxuICAgICAgdGhpcy5fcG9wcGVyID0gbnVsbFxuICAgIH1cblxuICAgIGlmICh0aGlzLnRpcCkge1xuICAgICAgdGhpcy50aXAucmVtb3ZlKClcbiAgICAgIHRoaXMudGlwID0gbnVsbFxuICAgIH1cbiAgfVxuXG4gIC8vIFN0YXRpY1xuICBzdGF0aWMgalF1ZXJ5SW50ZXJmYWNlKGNvbmZpZykge1xuICAgIHJldHVybiB0aGlzLmVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgZGF0YSA9IFRvb2x0aXAuZ2V0T3JDcmVhdGVJbnN0YW5jZSh0aGlzLCBjb25maWcpXG5cbiAgICAgIGlmICh0eXBlb2YgY29uZmlnICE9PSAnc3RyaW5nJykge1xuICAgICAgICByZXR1cm5cbiAgICAgIH1cblxuICAgICAgaWYgKHR5cGVvZiBkYXRhW2NvbmZpZ10gPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoYE5vIG1ldGhvZCBuYW1lZCBcIiR7Y29uZmlnfVwiYClcbiAgICAgIH1cblxuICAgICAgZGF0YVtjb25maWddKClcbiAgICB9KVxuICB9XG59XG5cbi8qKlxuICogalF1ZXJ5XG4gKi9cblxuZGVmaW5lSlF1ZXJ5UGx1Z2luKFRvb2x0aXApXG5cbmV4cG9ydCBkZWZhdWx0IFRvb2x0aXBcbiIsIi8qKlxuICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAqIEJvb3RzdHJhcCBwb3BvdmVyLmpzXG4gKiBMaWNlbnNlZCB1bmRlciBNSVQgKGh0dHBzOi8vZ2l0aHViLmNvbS90d2JzL2Jvb3RzdHJhcC9ibG9iL21haW4vTElDRU5TRSlcbiAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gKi9cblxuaW1wb3J0IFRvb2x0aXAgZnJvbSAnLi90b29sdGlwLmpzJ1xuaW1wb3J0IHsgZGVmaW5lSlF1ZXJ5UGx1Z2luIH0gZnJvbSAnLi91dGlsL2luZGV4LmpzJ1xuXG4vKipcbiAqIENvbnN0YW50c1xuICovXG5cbmNvbnN0IE5BTUUgPSAncG9wb3ZlcidcblxuY29uc3QgU0VMRUNUT1JfVElUTEUgPSAnLnBvcG92ZXItaGVhZGVyJ1xuY29uc3QgU0VMRUNUT1JfQ09OVEVOVCA9ICcucG9wb3Zlci1ib2R5J1xuXG5jb25zdCBEZWZhdWx0ID0ge1xuICAuLi5Ub29sdGlwLkRlZmF1bHQsXG4gIGNvbnRlbnQ6ICcnLFxuICBvZmZzZXQ6IFswLCA4XSxcbiAgcGxhY2VtZW50OiAncmlnaHQnLFxuICB0ZW1wbGF0ZTogJzxkaXYgY2xhc3M9XCJwb3BvdmVyXCIgcm9sZT1cInRvb2x0aXBcIj4nICtcbiAgICAnPGRpdiBjbGFzcz1cInBvcG92ZXItYXJyb3dcIj48L2Rpdj4nICtcbiAgICAnPGgzIGNsYXNzPVwicG9wb3Zlci1oZWFkZXJcIj48L2gzPicgK1xuICAgICc8ZGl2IGNsYXNzPVwicG9wb3Zlci1ib2R5XCI+PC9kaXY+JyArXG4gICAgJzwvZGl2PicsXG4gIHRyaWdnZXI6ICdjbGljaydcbn1cblxuY29uc3QgRGVmYXVsdFR5cGUgPSB7XG4gIC4uLlRvb2x0aXAuRGVmYXVsdFR5cGUsXG4gIGNvbnRlbnQ6ICcobnVsbHxzdHJpbmd8ZWxlbWVudHxmdW5jdGlvbiknXG59XG5cbi8qKlxuICogQ2xhc3MgZGVmaW5pdGlvblxuICovXG5cbmNsYXNzIFBvcG92ZXIgZXh0ZW5kcyBUb29sdGlwIHtcbiAgLy8gR2V0dGVyc1xuICBzdGF0aWMgZ2V0IERlZmF1bHQoKSB7XG4gICAgcmV0dXJuIERlZmF1bHRcbiAgfVxuXG4gIHN0YXRpYyBnZXQgRGVmYXVsdFR5cGUoKSB7XG4gICAgcmV0dXJuIERlZmF1bHRUeXBlXG4gIH1cblxuICBzdGF0aWMgZ2V0IE5BTUUoKSB7XG4gICAgcmV0dXJuIE5BTUVcbiAgfVxuXG4gIC8vIE92ZXJyaWRlc1xuICBfaXNXaXRoQ29udGVudCgpIHtcbiAgICByZXR1cm4gdGhpcy5fZ2V0VGl0bGUoKSB8fCB0aGlzLl9nZXRDb250ZW50KClcbiAgfVxuXG4gIC8vIFByaXZhdGVcbiAgX2dldENvbnRlbnRGb3JUZW1wbGF0ZSgpIHtcbiAgICByZXR1cm4ge1xuICAgICAgW1NFTEVDVE9SX1RJVExFXTogdGhpcy5fZ2V0VGl0bGUoKSxcbiAgICAgIFtTRUxFQ1RPUl9DT05URU5UXTogdGhpcy5fZ2V0Q29udGVudCgpXG4gICAgfVxuICB9XG5cbiAgX2dldENvbnRlbnQoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3Jlc29sdmVQb3NzaWJsZUZ1bmN0aW9uKHRoaXMuX2NvbmZpZy5jb250ZW50KVxuICB9XG5cbiAgLy8gU3RhdGljXG4gIHN0YXRpYyBqUXVlcnlJbnRlcmZhY2UoY29uZmlnKSB7XG4gICAgcmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBkYXRhID0gUG9wb3Zlci5nZXRPckNyZWF0ZUluc3RhbmNlKHRoaXMsIGNvbmZpZylcblxuICAgICAgaWYgKHR5cGVvZiBjb25maWcgIT09ICdzdHJpbmcnKSB7XG4gICAgICAgIHJldHVyblxuICAgICAgfVxuXG4gICAgICBpZiAodHlwZW9mIGRhdGFbY29uZmlnXSA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihgTm8gbWV0aG9kIG5hbWVkIFwiJHtjb25maWd9XCJgKVxuICAgICAgfVxuXG4gICAgICBkYXRhW2NvbmZpZ10oKVxuICAgIH0pXG4gIH1cbn1cblxuLyoqXG4gKiBqUXVlcnlcbiAqL1xuXG5kZWZpbmVKUXVlcnlQbHVnaW4oUG9wb3ZlcilcblxuZXhwb3J0IGRlZmF1bHQgUG9wb3ZlclxuIiwiLyoqXG4gKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICogQm9vdHN0cmFwIHNjcm9sbHNweS5qc1xuICogTGljZW5zZWQgdW5kZXIgTUlUIChodHRwczovL2dpdGh1Yi5jb20vdHdicy9ib290c3RyYXAvYmxvYi9tYWluL0xJQ0VOU0UpXG4gKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICovXG5cbmltcG9ydCBCYXNlQ29tcG9uZW50IGZyb20gJy4vYmFzZS1jb21wb25lbnQuanMnXG5pbXBvcnQgRXZlbnRIYW5kbGVyIGZyb20gJy4vZG9tL2V2ZW50LWhhbmRsZXIuanMnXG5pbXBvcnQgU2VsZWN0b3JFbmdpbmUgZnJvbSAnLi9kb20vc2VsZWN0b3ItZW5naW5lLmpzJ1xuaW1wb3J0IHtcbiAgZGVmaW5lSlF1ZXJ5UGx1Z2luLCBnZXRFbGVtZW50LCBpc0Rpc2FibGVkLCBpc1Zpc2libGVcbn0gZnJvbSAnLi91dGlsL2luZGV4LmpzJ1xuXG4vKipcbiAqIENvbnN0YW50c1xuICovXG5cbmNvbnN0IE5BTUUgPSAnc2Nyb2xsc3B5J1xuY29uc3QgREFUQV9LRVkgPSAnYnMuc2Nyb2xsc3B5J1xuY29uc3QgRVZFTlRfS0VZID0gYC4ke0RBVEFfS0VZfWBcbmNvbnN0IERBVEFfQVBJX0tFWSA9ICcuZGF0YS1hcGknXG5cbmNvbnN0IEVWRU5UX0FDVElWQVRFID0gYGFjdGl2YXRlJHtFVkVOVF9LRVl9YFxuY29uc3QgRVZFTlRfQ0xJQ0sgPSBgY2xpY2ske0VWRU5UX0tFWX1gXG5jb25zdCBFVkVOVF9MT0FEX0RBVEFfQVBJID0gYGxvYWQke0VWRU5UX0tFWX0ke0RBVEFfQVBJX0tFWX1gXG5cbmNvbnN0IENMQVNTX05BTUVfRFJPUERPV05fSVRFTSA9ICdkcm9wZG93bi1pdGVtJ1xuY29uc3QgQ0xBU1NfTkFNRV9BQ1RJVkUgPSAnYWN0aXZlJ1xuXG5jb25zdCBTRUxFQ1RPUl9EQVRBX1NQWSA9ICdbZGF0YS1icy1zcHk9XCJzY3JvbGxcIl0nXG5jb25zdCBTRUxFQ1RPUl9UQVJHRVRfTElOS1MgPSAnW2hyZWZdJ1xuY29uc3QgU0VMRUNUT1JfTkFWX0xJU1RfR1JPVVAgPSAnLm5hdiwgLmxpc3QtZ3JvdXAnXG5jb25zdCBTRUxFQ1RPUl9OQVZfTElOS1MgPSAnLm5hdi1saW5rJ1xuY29uc3QgU0VMRUNUT1JfTkFWX0lURU1TID0gJy5uYXYtaXRlbSdcbmNvbnN0IFNFTEVDVE9SX0xJU1RfSVRFTVMgPSAnLmxpc3QtZ3JvdXAtaXRlbSdcbmNvbnN0IFNFTEVDVE9SX0xJTktfSVRFTVMgPSBgJHtTRUxFQ1RPUl9OQVZfTElOS1N9LCAke1NFTEVDVE9SX05BVl9JVEVNU30gPiAke1NFTEVDVE9SX05BVl9MSU5LU30sICR7U0VMRUNUT1JfTElTVF9JVEVNU31gXG5jb25zdCBTRUxFQ1RPUl9EUk9QRE9XTiA9ICcuZHJvcGRvd24nXG5jb25zdCBTRUxFQ1RPUl9EUk9QRE9XTl9UT0dHTEUgPSAnLmRyb3Bkb3duLXRvZ2dsZSdcblxuY29uc3QgRGVmYXVsdCA9IHtcbiAgb2Zmc2V0OiBudWxsLCAvLyBUT0RPOiB2NiBAZGVwcmVjYXRlZCwga2VlcCBpdCBmb3IgYmFja3dhcmRzIGNvbXBhdGliaWxpdHkgcmVhc29uc1xuICByb290TWFyZ2luOiAnMHB4IDBweCAtMjUlJyxcbiAgc21vb3RoU2Nyb2xsOiBmYWxzZSxcbiAgdGFyZ2V0OiBudWxsLFxuICB0aHJlc2hvbGQ6IFswLjEsIDAuNSwgMV1cbn1cblxuY29uc3QgRGVmYXVsdFR5cGUgPSB7XG4gIG9mZnNldDogJyhudW1iZXJ8bnVsbCknLCAvLyBUT0RPIHY2IEBkZXByZWNhdGVkLCBrZWVwIGl0IGZvciBiYWNrd2FyZHMgY29tcGF0aWJpbGl0eSByZWFzb25zXG4gIHJvb3RNYXJnaW46ICdzdHJpbmcnLFxuICBzbW9vdGhTY3JvbGw6ICdib29sZWFuJyxcbiAgdGFyZ2V0OiAnZWxlbWVudCcsXG4gIHRocmVzaG9sZDogJ2FycmF5J1xufVxuXG4vKipcbiAqIENsYXNzIGRlZmluaXRpb25cbiAqL1xuXG5jbGFzcyBTY3JvbGxTcHkgZXh0ZW5kcyBCYXNlQ29tcG9uZW50IHtcbiAgY29uc3RydWN0b3IoZWxlbWVudCwgY29uZmlnKSB7XG4gICAgc3VwZXIoZWxlbWVudCwgY29uZmlnKVxuXG4gICAgLy8gdGhpcy5fZWxlbWVudCBpcyB0aGUgb2JzZXJ2YWJsZXNDb250YWluZXIgYW5kIGNvbmZpZy50YXJnZXQgdGhlIG1lbnUgbGlua3Mgd3JhcHBlclxuICAgIHRoaXMuX3RhcmdldExpbmtzID0gbmV3IE1hcCgpXG4gICAgdGhpcy5fb2JzZXJ2YWJsZVNlY3Rpb25zID0gbmV3IE1hcCgpXG4gICAgdGhpcy5fcm9vdEVsZW1lbnQgPSBnZXRDb21wdXRlZFN0eWxlKHRoaXMuX2VsZW1lbnQpLm92ZXJmbG93WSA9PT0gJ3Zpc2libGUnID8gbnVsbCA6IHRoaXMuX2VsZW1lbnRcbiAgICB0aGlzLl9hY3RpdmVUYXJnZXQgPSBudWxsXG4gICAgdGhpcy5fb2JzZXJ2ZXIgPSBudWxsXG4gICAgdGhpcy5fcHJldmlvdXNTY3JvbGxEYXRhID0ge1xuICAgICAgdmlzaWJsZUVudHJ5VG9wOiAwLFxuICAgICAgcGFyZW50U2Nyb2xsVG9wOiAwXG4gICAgfVxuICAgIHRoaXMucmVmcmVzaCgpIC8vIGluaXRpYWxpemVcbiAgfVxuXG4gIC8vIEdldHRlcnNcbiAgc3RhdGljIGdldCBEZWZhdWx0KCkge1xuICAgIHJldHVybiBEZWZhdWx0XG4gIH1cblxuICBzdGF0aWMgZ2V0IERlZmF1bHRUeXBlKCkge1xuICAgIHJldHVybiBEZWZhdWx0VHlwZVxuICB9XG5cbiAgc3RhdGljIGdldCBOQU1FKCkge1xuICAgIHJldHVybiBOQU1FXG4gIH1cblxuICAvLyBQdWJsaWNcbiAgcmVmcmVzaCgpIHtcbiAgICB0aGlzLl9pbml0aWFsaXplVGFyZ2V0c0FuZE9ic2VydmFibGVzKClcbiAgICB0aGlzLl9tYXliZUVuYWJsZVNtb290aFNjcm9sbCgpXG5cbiAgICBpZiAodGhpcy5fb2JzZXJ2ZXIpIHtcbiAgICAgIHRoaXMuX29ic2VydmVyLmRpc2Nvbm5lY3QoKVxuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLl9vYnNlcnZlciA9IHRoaXMuX2dldE5ld09ic2VydmVyKClcbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IHNlY3Rpb24gb2YgdGhpcy5fb2JzZXJ2YWJsZVNlY3Rpb25zLnZhbHVlcygpKSB7XG4gICAgICB0aGlzLl9vYnNlcnZlci5vYnNlcnZlKHNlY3Rpb24pXG4gICAgfVxuICB9XG5cbiAgZGlzcG9zZSgpIHtcbiAgICB0aGlzLl9vYnNlcnZlci5kaXNjb25uZWN0KClcbiAgICBzdXBlci5kaXNwb3NlKClcbiAgfVxuXG4gIC8vIFByaXZhdGVcbiAgX2NvbmZpZ0FmdGVyTWVyZ2UoY29uZmlnKSB7XG4gICAgLy8gVE9ETzogb24gdjYgdGFyZ2V0IHNob3VsZCBiZSBnaXZlbiBleHBsaWNpdGx5ICYgcmVtb3ZlIHRoZSB7dGFyZ2V0OiAnc3MtdGFyZ2V0J30gY2FzZVxuICAgIGNvbmZpZy50YXJnZXQgPSBnZXRFbGVtZW50KGNvbmZpZy50YXJnZXQpIHx8IGRvY3VtZW50LmJvZHlcblxuICAgIC8vIFRPRE86IHY2IE9ubHkgZm9yIGJhY2t3YXJkcyBjb21wYXRpYmlsaXR5IHJlYXNvbnMuIFVzZSByb290TWFyZ2luIG9ubHlcbiAgICBjb25maWcucm9vdE1hcmdpbiA9IGNvbmZpZy5vZmZzZXQgPyBgJHtjb25maWcub2Zmc2V0fXB4IDBweCAtMzAlYCA6IGNvbmZpZy5yb290TWFyZ2luXG5cbiAgICBpZiAodHlwZW9mIGNvbmZpZy50aHJlc2hvbGQgPT09ICdzdHJpbmcnKSB7XG4gICAgICBjb25maWcudGhyZXNob2xkID0gY29uZmlnLnRocmVzaG9sZC5zcGxpdCgnLCcpLm1hcCh2YWx1ZSA9PiBOdW1iZXIucGFyc2VGbG9hdCh2YWx1ZSkpXG4gICAgfVxuXG4gICAgcmV0dXJuIGNvbmZpZ1xuICB9XG5cbiAgX21heWJlRW5hYmxlU21vb3RoU2Nyb2xsKCkge1xuICAgIGlmICghdGhpcy5fY29uZmlnLnNtb290aFNjcm9sbCkge1xuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgLy8gdW5yZWdpc3RlciBhbnkgcHJldmlvdXMgbGlzdGVuZXJzXG4gICAgRXZlbnRIYW5kbGVyLm9mZih0aGlzLl9jb25maWcudGFyZ2V0LCBFVkVOVF9DTElDSylcblxuICAgIEV2ZW50SGFuZGxlci5vbih0aGlzLl9jb25maWcudGFyZ2V0LCBFVkVOVF9DTElDSywgU0VMRUNUT1JfVEFSR0VUX0xJTktTLCBldmVudCA9PiB7XG4gICAgICBjb25zdCBvYnNlcnZhYmxlU2VjdGlvbiA9IHRoaXMuX29ic2VydmFibGVTZWN0aW9ucy5nZXQoZXZlbnQudGFyZ2V0Lmhhc2gpXG4gICAgICBpZiAob2JzZXJ2YWJsZVNlY3Rpb24pIHtcbiAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKVxuICAgICAgICBjb25zdCByb290ID0gdGhpcy5fcm9vdEVsZW1lbnQgfHwgd2luZG93XG4gICAgICAgIGNvbnN0IGhlaWdodCA9IG9ic2VydmFibGVTZWN0aW9uLm9mZnNldFRvcCAtIHRoaXMuX2VsZW1lbnQub2Zmc2V0VG9wXG4gICAgICAgIGlmIChyb290LnNjcm9sbFRvKSB7XG4gICAgICAgICAgcm9vdC5zY3JvbGxUbyh7IHRvcDogaGVpZ2h0LCBiZWhhdmlvcjogJ3Ntb290aCcgfSlcbiAgICAgICAgICByZXR1cm5cbiAgICAgICAgfVxuXG4gICAgICAgIC8vIENocm9tZSA2MCBkb2Vzbid0IHN1cHBvcnQgYHNjcm9sbFRvYFxuICAgICAgICByb290LnNjcm9sbFRvcCA9IGhlaWdodFxuICAgICAgfVxuICAgIH0pXG4gIH1cblxuICBfZ2V0TmV3T2JzZXJ2ZXIoKSB7XG4gICAgY29uc3Qgb3B0aW9ucyA9IHtcbiAgICAgIHJvb3Q6IHRoaXMuX3Jvb3RFbGVtZW50LFxuICAgICAgdGhyZXNob2xkOiB0aGlzLl9jb25maWcudGhyZXNob2xkLFxuICAgICAgcm9vdE1hcmdpbjogdGhpcy5fY29uZmlnLnJvb3RNYXJnaW5cbiAgICB9XG5cbiAgICByZXR1cm4gbmV3IEludGVyc2VjdGlvbk9ic2VydmVyKGVudHJpZXMgPT4gdGhpcy5fb2JzZXJ2ZXJDYWxsYmFjayhlbnRyaWVzKSwgb3B0aW9ucylcbiAgfVxuXG4gIC8vIFRoZSBsb2dpYyBvZiBzZWxlY3Rpb25cbiAgX29ic2VydmVyQ2FsbGJhY2soZW50cmllcykge1xuICAgIGNvbnN0IHRhcmdldEVsZW1lbnQgPSBlbnRyeSA9PiB0aGlzLl90YXJnZXRMaW5rcy5nZXQoYCMke2VudHJ5LnRhcmdldC5pZH1gKVxuICAgIGNvbnN0IGFjdGl2YXRlID0gZW50cnkgPT4ge1xuICAgICAgdGhpcy5fcHJldmlvdXNTY3JvbGxEYXRhLnZpc2libGVFbnRyeVRvcCA9IGVudHJ5LnRhcmdldC5vZmZzZXRUb3BcbiAgICAgIHRoaXMuX3Byb2Nlc3ModGFyZ2V0RWxlbWVudChlbnRyeSkpXG4gICAgfVxuXG4gICAgY29uc3QgcGFyZW50U2Nyb2xsVG9wID0gKHRoaXMuX3Jvb3RFbGVtZW50IHx8IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudCkuc2Nyb2xsVG9wXG4gICAgY29uc3QgdXNlclNjcm9sbHNEb3duID0gcGFyZW50U2Nyb2xsVG9wID49IHRoaXMuX3ByZXZpb3VzU2Nyb2xsRGF0YS5wYXJlbnRTY3JvbGxUb3BcbiAgICB0aGlzLl9wcmV2aW91c1Njcm9sbERhdGEucGFyZW50U2Nyb2xsVG9wID0gcGFyZW50U2Nyb2xsVG9wXG5cbiAgICBmb3IgKGNvbnN0IGVudHJ5IG9mIGVudHJpZXMpIHtcbiAgICAgIGlmICghZW50cnkuaXNJbnRlcnNlY3RpbmcpIHtcbiAgICAgICAgdGhpcy5fYWN0aXZlVGFyZ2V0ID0gbnVsbFxuICAgICAgICB0aGlzLl9jbGVhckFjdGl2ZUNsYXNzKHRhcmdldEVsZW1lbnQoZW50cnkpKVxuXG4gICAgICAgIGNvbnRpbnVlXG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGVudHJ5SXNMb3dlclRoYW5QcmV2aW91cyA9IGVudHJ5LnRhcmdldC5vZmZzZXRUb3AgPj0gdGhpcy5fcHJldmlvdXNTY3JvbGxEYXRhLnZpc2libGVFbnRyeVRvcFxuICAgICAgLy8gaWYgd2UgYXJlIHNjcm9sbGluZyBkb3duLCBwaWNrIHRoZSBiaWdnZXIgb2Zmc2V0VG9wXG4gICAgICBpZiAodXNlclNjcm9sbHNEb3duICYmIGVudHJ5SXNMb3dlclRoYW5QcmV2aW91cykge1xuICAgICAgICBhY3RpdmF0ZShlbnRyeSlcbiAgICAgICAgLy8gaWYgcGFyZW50IGlzbid0IHNjcm9sbGVkLCBsZXQncyBrZWVwIHRoZSBmaXJzdCB2aXNpYmxlIGl0ZW0sIGJyZWFraW5nIHRoZSBpdGVyYXRpb25cbiAgICAgICAgaWYgKCFwYXJlbnRTY3JvbGxUb3ApIHtcbiAgICAgICAgICByZXR1cm5cbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnRpbnVlXG4gICAgICB9XG5cbiAgICAgIC8vIGlmIHdlIGFyZSBzY3JvbGxpbmcgdXAsIHBpY2sgdGhlIHNtYWxsZXN0IG9mZnNldFRvcFxuICAgICAgaWYgKCF1c2VyU2Nyb2xsc0Rvd24gJiYgIWVudHJ5SXNMb3dlclRoYW5QcmV2aW91cykge1xuICAgICAgICBhY3RpdmF0ZShlbnRyeSlcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBfaW5pdGlhbGl6ZVRhcmdldHNBbmRPYnNlcnZhYmxlcygpIHtcbiAgICB0aGlzLl90YXJnZXRMaW5rcyA9IG5ldyBNYXAoKVxuICAgIHRoaXMuX29ic2VydmFibGVTZWN0aW9ucyA9IG5ldyBNYXAoKVxuXG4gICAgY29uc3QgdGFyZ2V0TGlua3MgPSBTZWxlY3RvckVuZ2luZS5maW5kKFNFTEVDVE9SX1RBUkdFVF9MSU5LUywgdGhpcy5fY29uZmlnLnRhcmdldClcblxuICAgIGZvciAoY29uc3QgYW5jaG9yIG9mIHRhcmdldExpbmtzKSB7XG4gICAgICAvLyBlbnN1cmUgdGhhdCB0aGUgYW5jaG9yIGhhcyBhbiBpZCBhbmQgaXMgbm90IGRpc2FibGVkXG4gICAgICBpZiAoIWFuY2hvci5oYXNoIHx8IGlzRGlzYWJsZWQoYW5jaG9yKSkge1xuICAgICAgICBjb250aW51ZVxuICAgICAgfVxuXG4gICAgICBjb25zdCBvYnNlcnZhYmxlU2VjdGlvbiA9IFNlbGVjdG9yRW5naW5lLmZpbmRPbmUoZGVjb2RlVVJJKGFuY2hvci5oYXNoKSwgdGhpcy5fZWxlbWVudClcblxuICAgICAgLy8gZW5zdXJlIHRoYXQgdGhlIG9ic2VydmFibGVTZWN0aW9uIGV4aXN0cyAmIGlzIHZpc2libGVcbiAgICAgIGlmIChpc1Zpc2libGUob2JzZXJ2YWJsZVNlY3Rpb24pKSB7XG4gICAgICAgIHRoaXMuX3RhcmdldExpbmtzLnNldChkZWNvZGVVUkkoYW5jaG9yLmhhc2gpLCBhbmNob3IpXG4gICAgICAgIHRoaXMuX29ic2VydmFibGVTZWN0aW9ucy5zZXQoYW5jaG9yLmhhc2gsIG9ic2VydmFibGVTZWN0aW9uKVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIF9wcm9jZXNzKHRhcmdldCkge1xuICAgIGlmICh0aGlzLl9hY3RpdmVUYXJnZXQgPT09IHRhcmdldCkge1xuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgdGhpcy5fY2xlYXJBY3RpdmVDbGFzcyh0aGlzLl9jb25maWcudGFyZ2V0KVxuICAgIHRoaXMuX2FjdGl2ZVRhcmdldCA9IHRhcmdldFxuICAgIHRhcmdldC5jbGFzc0xpc3QuYWRkKENMQVNTX05BTUVfQUNUSVZFKVxuICAgIHRoaXMuX2FjdGl2YXRlUGFyZW50cyh0YXJnZXQpXG5cbiAgICBFdmVudEhhbmRsZXIudHJpZ2dlcih0aGlzLl9lbGVtZW50LCBFVkVOVF9BQ1RJVkFURSwgeyByZWxhdGVkVGFyZ2V0OiB0YXJnZXQgfSlcbiAgfVxuXG4gIF9hY3RpdmF0ZVBhcmVudHModGFyZ2V0KSB7XG4gICAgLy8gQWN0aXZhdGUgZHJvcGRvd24gcGFyZW50c1xuICAgIGlmICh0YXJnZXQuY2xhc3NMaXN0LmNvbnRhaW5zKENMQVNTX05BTUVfRFJPUERPV05fSVRFTSkpIHtcbiAgICAgIFNlbGVjdG9yRW5naW5lLmZpbmRPbmUoU0VMRUNUT1JfRFJPUERPV05fVE9HR0xFLCB0YXJnZXQuY2xvc2VzdChTRUxFQ1RPUl9EUk9QRE9XTikpXG4gICAgICAgIC5jbGFzc0xpc3QuYWRkKENMQVNTX05BTUVfQUNUSVZFKVxuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgZm9yIChjb25zdCBsaXN0R3JvdXAgb2YgU2VsZWN0b3JFbmdpbmUucGFyZW50cyh0YXJnZXQsIFNFTEVDVE9SX05BVl9MSVNUX0dST1VQKSkge1xuICAgICAgLy8gU2V0IHRyaWdnZXJlZCBsaW5rcyBwYXJlbnRzIGFzIGFjdGl2ZVxuICAgICAgLy8gV2l0aCBib3RoIDx1bD4gYW5kIDxuYXY+IG1hcmt1cCBhIHBhcmVudCBpcyB0aGUgcHJldmlvdXMgc2libGluZyBvZiBhbnkgbmF2IGFuY2VzdG9yXG4gICAgICBmb3IgKGNvbnN0IGl0ZW0gb2YgU2VsZWN0b3JFbmdpbmUucHJldihsaXN0R3JvdXAsIFNFTEVDVE9SX0xJTktfSVRFTVMpKSB7XG4gICAgICAgIGl0ZW0uY2xhc3NMaXN0LmFkZChDTEFTU19OQU1FX0FDVElWRSlcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBfY2xlYXJBY3RpdmVDbGFzcyhwYXJlbnQpIHtcbiAgICBwYXJlbnQuY2xhc3NMaXN0LnJlbW92ZShDTEFTU19OQU1FX0FDVElWRSlcblxuICAgIGNvbnN0IGFjdGl2ZU5vZGVzID0gU2VsZWN0b3JFbmdpbmUuZmluZChgJHtTRUxFQ1RPUl9UQVJHRVRfTElOS1N9LiR7Q0xBU1NfTkFNRV9BQ1RJVkV9YCwgcGFyZW50KVxuICAgIGZvciAoY29uc3Qgbm9kZSBvZiBhY3RpdmVOb2Rlcykge1xuICAgICAgbm9kZS5jbGFzc0xpc3QucmVtb3ZlKENMQVNTX05BTUVfQUNUSVZFKVxuICAgIH1cbiAgfVxuXG4gIC8vIFN0YXRpY1xuICBzdGF0aWMgalF1ZXJ5SW50ZXJmYWNlKGNvbmZpZykge1xuICAgIHJldHVybiB0aGlzLmVhY2goZnVuY3Rpb24gKCkge1xuICAgICAgY29uc3QgZGF0YSA9IFNjcm9sbFNweS5nZXRPckNyZWF0ZUluc3RhbmNlKHRoaXMsIGNvbmZpZylcblxuICAgICAgaWYgKHR5cGVvZiBjb25maWcgIT09ICdzdHJpbmcnKSB7XG4gICAgICAgIHJldHVyblxuICAgICAgfVxuXG4gICAgICBpZiAoZGF0YVtjb25maWddID09PSB1bmRlZmluZWQgfHwgY29uZmlnLnN0YXJ0c1dpdGgoJ18nKSB8fCBjb25maWcgPT09ICdjb25zdHJ1Y3RvcicpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihgTm8gbWV0aG9kIG5hbWVkIFwiJHtjb25maWd9XCJgKVxuICAgICAgfVxuXG4gICAgICBkYXRhW2NvbmZpZ10oKVxuICAgIH0pXG4gIH1cbn1cblxuLyoqXG4gKiBEYXRhIEFQSSBpbXBsZW1lbnRhdGlvblxuICovXG5cbkV2ZW50SGFuZGxlci5vbih3aW5kb3csIEVWRU5UX0xPQURfREFUQV9BUEksICgpID0+IHtcbiAgZm9yIChjb25zdCBzcHkgb2YgU2VsZWN0b3JFbmdpbmUuZmluZChTRUxFQ1RPUl9EQVRBX1NQWSkpIHtcbiAgICBTY3JvbGxTcHkuZ2V0T3JDcmVhdGVJbnN0YW5jZShzcHkpXG4gIH1cbn0pXG5cbi8qKlxuICogalF1ZXJ5XG4gKi9cblxuZGVmaW5lSlF1ZXJ5UGx1Z2luKFNjcm9sbFNweSlcblxuZXhwb3J0IGRlZmF1bHQgU2Nyb2xsU3B5XG4iLCIvKipcbiAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gKiBCb290c3RyYXAgdGFiLmpzXG4gKiBMaWNlbnNlZCB1bmRlciBNSVQgKGh0dHBzOi8vZ2l0aHViLmNvbS90d2JzL2Jvb3RzdHJhcC9ibG9iL21haW4vTElDRU5TRSlcbiAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gKi9cblxuaW1wb3J0IEJhc2VDb21wb25lbnQgZnJvbSAnLi9iYXNlLWNvbXBvbmVudC5qcydcbmltcG9ydCBFdmVudEhhbmRsZXIgZnJvbSAnLi9kb20vZXZlbnQtaGFuZGxlci5qcydcbmltcG9ydCBTZWxlY3RvckVuZ2luZSBmcm9tICcuL2RvbS9zZWxlY3Rvci1lbmdpbmUuanMnXG5pbXBvcnQgeyBkZWZpbmVKUXVlcnlQbHVnaW4sIGdldE5leHRBY3RpdmVFbGVtZW50LCBpc0Rpc2FibGVkIH0gZnJvbSAnLi91dGlsL2luZGV4LmpzJ1xuXG4vKipcbiAqIENvbnN0YW50c1xuICovXG5cbmNvbnN0IE5BTUUgPSAndGFiJ1xuY29uc3QgREFUQV9LRVkgPSAnYnMudGFiJ1xuY29uc3QgRVZFTlRfS0VZID0gYC4ke0RBVEFfS0VZfWBcblxuY29uc3QgRVZFTlRfSElERSA9IGBoaWRlJHtFVkVOVF9LRVl9YFxuY29uc3QgRVZFTlRfSElEREVOID0gYGhpZGRlbiR7RVZFTlRfS0VZfWBcbmNvbnN0IEVWRU5UX1NIT1cgPSBgc2hvdyR7RVZFTlRfS0VZfWBcbmNvbnN0IEVWRU5UX1NIT1dOID0gYHNob3duJHtFVkVOVF9LRVl9YFxuY29uc3QgRVZFTlRfQ0xJQ0tfREFUQV9BUEkgPSBgY2xpY2ske0VWRU5UX0tFWX1gXG5jb25zdCBFVkVOVF9LRVlET1dOID0gYGtleWRvd24ke0VWRU5UX0tFWX1gXG5jb25zdCBFVkVOVF9MT0FEX0RBVEFfQVBJID0gYGxvYWQke0VWRU5UX0tFWX1gXG5cbmNvbnN0IEFSUk9XX0xFRlRfS0VZID0gJ0Fycm93TGVmdCdcbmNvbnN0IEFSUk9XX1JJR0hUX0tFWSA9ICdBcnJvd1JpZ2h0J1xuY29uc3QgQVJST1dfVVBfS0VZID0gJ0Fycm93VXAnXG5jb25zdCBBUlJPV19ET1dOX0tFWSA9ICdBcnJvd0Rvd24nXG5jb25zdCBIT01FX0tFWSA9ICdIb21lJ1xuY29uc3QgRU5EX0tFWSA9ICdFbmQnXG5cbmNvbnN0IENMQVNTX05BTUVfQUNUSVZFID0gJ2FjdGl2ZSdcbmNvbnN0IENMQVNTX05BTUVfRkFERSA9ICdmYWRlJ1xuY29uc3QgQ0xBU1NfTkFNRV9TSE9XID0gJ3Nob3cnXG5jb25zdCBDTEFTU19EUk9QRE9XTiA9ICdkcm9wZG93bidcblxuY29uc3QgU0VMRUNUT1JfRFJPUERPV05fVE9HR0xFID0gJy5kcm9wZG93bi10b2dnbGUnXG5jb25zdCBTRUxFQ1RPUl9EUk9QRE9XTl9NRU5VID0gJy5kcm9wZG93bi1tZW51J1xuY29uc3QgTk9UX1NFTEVDVE9SX0RST1BET1dOX1RPR0dMRSA9IGA6bm90KCR7U0VMRUNUT1JfRFJPUERPV05fVE9HR0xFfSlgXG5cbmNvbnN0IFNFTEVDVE9SX1RBQl9QQU5FTCA9ICcubGlzdC1ncm91cCwgLm5hdiwgW3JvbGU9XCJ0YWJsaXN0XCJdJ1xuY29uc3QgU0VMRUNUT1JfT1VURVIgPSAnLm5hdi1pdGVtLCAubGlzdC1ncm91cC1pdGVtJ1xuY29uc3QgU0VMRUNUT1JfSU5ORVIgPSBgLm5hdi1saW5rJHtOT1RfU0VMRUNUT1JfRFJPUERPV05fVE9HR0xFfSwgLmxpc3QtZ3JvdXAtaXRlbSR7Tk9UX1NFTEVDVE9SX0RST1BET1dOX1RPR0dMRX0sIFtyb2xlPVwidGFiXCJdJHtOT1RfU0VMRUNUT1JfRFJPUERPV05fVE9HR0xFfWBcbmNvbnN0IFNFTEVDVE9SX0RBVEFfVE9HR0xFID0gJ1tkYXRhLWJzLXRvZ2dsZT1cInRhYlwiXSwgW2RhdGEtYnMtdG9nZ2xlPVwicGlsbFwiXSwgW2RhdGEtYnMtdG9nZ2xlPVwibGlzdFwiXScgLy8gVE9ETzogY291bGQgb25seSBiZSBgdGFiYCBpbiB2NlxuY29uc3QgU0VMRUNUT1JfSU5ORVJfRUxFTSA9IGAke1NFTEVDVE9SX0lOTkVSfSwgJHtTRUxFQ1RPUl9EQVRBX1RPR0dMRX1gXG5cbmNvbnN0IFNFTEVDVE9SX0RBVEFfVE9HR0xFX0FDVElWRSA9IGAuJHtDTEFTU19OQU1FX0FDVElWRX1bZGF0YS1icy10b2dnbGU9XCJ0YWJcIl0sIC4ke0NMQVNTX05BTUVfQUNUSVZFfVtkYXRhLWJzLXRvZ2dsZT1cInBpbGxcIl0sIC4ke0NMQVNTX05BTUVfQUNUSVZFfVtkYXRhLWJzLXRvZ2dsZT1cImxpc3RcIl1gXG5cbi8qKlxuICogQ2xhc3MgZGVmaW5pdGlvblxuICovXG5cbmNsYXNzIFRhYiBleHRlbmRzIEJhc2VDb21wb25lbnQge1xuICBjb25zdHJ1Y3RvcihlbGVtZW50KSB7XG4gICAgc3VwZXIoZWxlbWVudClcbiAgICB0aGlzLl9wYXJlbnQgPSB0aGlzLl9lbGVtZW50LmNsb3Nlc3QoU0VMRUNUT1JfVEFCX1BBTkVMKVxuXG4gICAgaWYgKCF0aGlzLl9wYXJlbnQpIHtcbiAgICAgIHJldHVyblxuICAgICAgLy8gVE9ETzogc2hvdWxkIHRocm93IGV4Y2VwdGlvbiBpbiB2NlxuICAgICAgLy8gdGhyb3cgbmV3IFR5cGVFcnJvcihgJHtlbGVtZW50Lm91dGVySFRNTH0gaGFzIG5vdCBhIHZhbGlkIHBhcmVudCAke1NFTEVDVE9SX0lOTkVSX0VMRU19YClcbiAgICB9XG5cbiAgICAvLyBTZXQgdXAgaW5pdGlhbCBhcmlhIGF0dHJpYnV0ZXNcbiAgICB0aGlzLl9zZXRJbml0aWFsQXR0cmlidXRlcyh0aGlzLl9wYXJlbnQsIHRoaXMuX2dldENoaWxkcmVuKCkpXG5cbiAgICBFdmVudEhhbmRsZXIub24odGhpcy5fZWxlbWVudCwgRVZFTlRfS0VZRE9XTiwgZXZlbnQgPT4gdGhpcy5fa2V5ZG93bihldmVudCkpXG4gIH1cblxuICAvLyBHZXR0ZXJzXG4gIHN0YXRpYyBnZXQgTkFNRSgpIHtcbiAgICByZXR1cm4gTkFNRVxuICB9XG5cbiAgLy8gUHVibGljXG4gIHNob3coKSB7IC8vIFNob3dzIHRoaXMgZWxlbSBhbmQgZGVhY3RpdmF0ZSB0aGUgYWN0aXZlIHNpYmxpbmcgaWYgZXhpc3RzXG4gICAgY29uc3QgaW5uZXJFbGVtID0gdGhpcy5fZWxlbWVudFxuICAgIGlmICh0aGlzLl9lbGVtSXNBY3RpdmUoaW5uZXJFbGVtKSkge1xuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgLy8gU2VhcmNoIGZvciBhY3RpdmUgdGFiIG9uIHNhbWUgcGFyZW50IHRvIGRlYWN0aXZhdGUgaXRcbiAgICBjb25zdCBhY3RpdmUgPSB0aGlzLl9nZXRBY3RpdmVFbGVtKClcblxuICAgIGNvbnN0IGhpZGVFdmVudCA9IGFjdGl2ZSA/XG4gICAgICBFdmVudEhhbmRsZXIudHJpZ2dlcihhY3RpdmUsIEVWRU5UX0hJREUsIHsgcmVsYXRlZFRhcmdldDogaW5uZXJFbGVtIH0pIDpcbiAgICAgIG51bGxcblxuICAgIGNvbnN0IHNob3dFdmVudCA9IEV2ZW50SGFuZGxlci50cmlnZ2VyKGlubmVyRWxlbSwgRVZFTlRfU0hPVywgeyByZWxhdGVkVGFyZ2V0OiBhY3RpdmUgfSlcblxuICAgIGlmIChzaG93RXZlbnQuZGVmYXVsdFByZXZlbnRlZCB8fCAoaGlkZUV2ZW50ICYmIGhpZGVFdmVudC5kZWZhdWx0UHJldmVudGVkKSkge1xuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgdGhpcy5fZGVhY3RpdmF0ZShhY3RpdmUsIGlubmVyRWxlbSlcbiAgICB0aGlzLl9hY3RpdmF0ZShpbm5lckVsZW0sIGFjdGl2ZSlcbiAgfVxuXG4gIC8vIFByaXZhdGVcbiAgX2FjdGl2YXRlKGVsZW1lbnQsIHJlbGF0ZWRFbGVtKSB7XG4gICAgaWYgKCFlbGVtZW50KSB7XG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICBlbGVtZW50LmNsYXNzTGlzdC5hZGQoQ0xBU1NfTkFNRV9BQ1RJVkUpXG5cbiAgICB0aGlzLl9hY3RpdmF0ZShTZWxlY3RvckVuZ2luZS5nZXRFbGVtZW50RnJvbVNlbGVjdG9yKGVsZW1lbnQpKSAvLyBTZWFyY2ggYW5kIGFjdGl2YXRlL3Nob3cgdGhlIHByb3BlciBzZWN0aW9uXG5cbiAgICBjb25zdCBjb21wbGV0ZSA9ICgpID0+IHtcbiAgICAgIGlmIChlbGVtZW50LmdldEF0dHJpYnV0ZSgncm9sZScpICE9PSAndGFiJykge1xuICAgICAgICBlbGVtZW50LmNsYXNzTGlzdC5hZGQoQ0xBU1NfTkFNRV9TSE9XKVxuICAgICAgICByZXR1cm5cbiAgICAgIH1cblxuICAgICAgZWxlbWVudC5yZW1vdmVBdHRyaWJ1dGUoJ3RhYmluZGV4JylcbiAgICAgIGVsZW1lbnQuc2V0QXR0cmlidXRlKCdhcmlhLXNlbGVjdGVkJywgdHJ1ZSlcbiAgICAgIHRoaXMuX3RvZ2dsZURyb3BEb3duKGVsZW1lbnQsIHRydWUpXG4gICAgICBFdmVudEhhbmRsZXIudHJpZ2dlcihlbGVtZW50LCBFVkVOVF9TSE9XTiwge1xuICAgICAgICByZWxhdGVkVGFyZ2V0OiByZWxhdGVkRWxlbVxuICAgICAgfSlcbiAgICB9XG5cbiAgICB0aGlzLl9xdWV1ZUNhbGxiYWNrKGNvbXBsZXRlLCBlbGVtZW50LCBlbGVtZW50LmNsYXNzTGlzdC5jb250YWlucyhDTEFTU19OQU1FX0ZBREUpKVxuICB9XG5cbiAgX2RlYWN0aXZhdGUoZWxlbWVudCwgcmVsYXRlZEVsZW0pIHtcbiAgICBpZiAoIWVsZW1lbnQpIHtcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIGVsZW1lbnQuY2xhc3NMaXN0LnJlbW92ZShDTEFTU19OQU1FX0FDVElWRSlcbiAgICBlbGVtZW50LmJsdXIoKVxuXG4gICAgdGhpcy5fZGVhY3RpdmF0ZShTZWxlY3RvckVuZ2luZS5nZXRFbGVtZW50RnJvbVNlbGVjdG9yKGVsZW1lbnQpKSAvLyBTZWFyY2ggYW5kIGRlYWN0aXZhdGUgdGhlIHNob3duIHNlY3Rpb24gdG9vXG5cbiAgICBjb25zdCBjb21wbGV0ZSA9ICgpID0+IHtcbiAgICAgIGlmIChlbGVtZW50LmdldEF0dHJpYnV0ZSgncm9sZScpICE9PSAndGFiJykge1xuICAgICAgICBlbGVtZW50LmNsYXNzTGlzdC5yZW1vdmUoQ0xBU1NfTkFNRV9TSE9XKVxuICAgICAgICByZXR1cm5cbiAgICAgIH1cblxuICAgICAgZWxlbWVudC5zZXRBdHRyaWJ1dGUoJ2FyaWEtc2VsZWN0ZWQnLCBmYWxzZSlcbiAgICAgIGVsZW1lbnQuc2V0QXR0cmlidXRlKCd0YWJpbmRleCcsICctMScpXG4gICAgICB0aGlzLl90b2dnbGVEcm9wRG93bihlbGVtZW50LCBmYWxzZSlcbiAgICAgIEV2ZW50SGFuZGxlci50cmlnZ2VyKGVsZW1lbnQsIEVWRU5UX0hJRERFTiwgeyByZWxhdGVkVGFyZ2V0OiByZWxhdGVkRWxlbSB9KVxuICAgIH1cblxuICAgIHRoaXMuX3F1ZXVlQ2FsbGJhY2soY29tcGxldGUsIGVsZW1lbnQsIGVsZW1lbnQuY2xhc3NMaXN0LmNvbnRhaW5zKENMQVNTX05BTUVfRkFERSkpXG4gIH1cblxuICBfa2V5ZG93bihldmVudCkge1xuICAgIGlmICghKFtBUlJPV19MRUZUX0tFWSwgQVJST1dfUklHSFRfS0VZLCBBUlJPV19VUF9LRVksIEFSUk9XX0RPV05fS0VZLCBIT01FX0tFWSwgRU5EX0tFWV0uaW5jbHVkZXMoZXZlbnQua2V5KSkpIHtcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpLy8gc3RvcFByb3BhZ2F0aW9uL3ByZXZlbnREZWZhdWx0IGJvdGggYWRkZWQgdG8gc3VwcG9ydCB1cC9kb3duIGtleXMgd2l0aG91dCBzY3JvbGxpbmcgdGhlIHBhZ2VcbiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpXG5cbiAgICBjb25zdCBjaGlsZHJlbiA9IHRoaXMuX2dldENoaWxkcmVuKCkuZmlsdGVyKGVsZW1lbnQgPT4gIWlzRGlzYWJsZWQoZWxlbWVudCkpXG4gICAgbGV0IG5leHRBY3RpdmVFbGVtZW50XG5cbiAgICBpZiAoW0hPTUVfS0VZLCBFTkRfS0VZXS5pbmNsdWRlcyhldmVudC5rZXkpKSB7XG4gICAgICBuZXh0QWN0aXZlRWxlbWVudCA9IGNoaWxkcmVuW2V2ZW50LmtleSA9PT0gSE9NRV9LRVkgPyAwIDogY2hpbGRyZW4ubGVuZ3RoIC0gMV1cbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3QgaXNOZXh0ID0gW0FSUk9XX1JJR0hUX0tFWSwgQVJST1dfRE9XTl9LRVldLmluY2x1ZGVzKGV2ZW50LmtleSlcbiAgICAgIG5leHRBY3RpdmVFbGVtZW50ID0gZ2V0TmV4dEFjdGl2ZUVsZW1lbnQoY2hpbGRyZW4sIGV2ZW50LnRhcmdldCwgaXNOZXh0LCB0cnVlKVxuICAgIH1cblxuICAgIGlmIChuZXh0QWN0aXZlRWxlbWVudCkge1xuICAgICAgbmV4dEFjdGl2ZUVsZW1lbnQuZm9jdXMoeyBwcmV2ZW50U2Nyb2xsOiB0cnVlIH0pXG4gICAgICBUYWIuZ2V0T3JDcmVhdGVJbnN0YW5jZShuZXh0QWN0aXZlRWxlbWVudCkuc2hvdygpXG4gICAgfVxuICB9XG5cbiAgX2dldENoaWxkcmVuKCkgeyAvLyBjb2xsZWN0aW9uIG9mIGlubmVyIGVsZW1lbnRzXG4gICAgcmV0dXJuIFNlbGVjdG9yRW5naW5lLmZpbmQoU0VMRUNUT1JfSU5ORVJfRUxFTSwgdGhpcy5fcGFyZW50KVxuICB9XG5cbiAgX2dldEFjdGl2ZUVsZW0oKSB7XG4gICAgcmV0dXJuIHRoaXMuX2dldENoaWxkcmVuKCkuZmluZChjaGlsZCA9PiB0aGlzLl9lbGVtSXNBY3RpdmUoY2hpbGQpKSB8fCBudWxsXG4gIH1cblxuICBfc2V0SW5pdGlhbEF0dHJpYnV0ZXMocGFyZW50LCBjaGlsZHJlbikge1xuICAgIHRoaXMuX3NldEF0dHJpYnV0ZUlmTm90RXhpc3RzKHBhcmVudCwgJ3JvbGUnLCAndGFibGlzdCcpXG5cbiAgICBmb3IgKGNvbnN0IGNoaWxkIG9mIGNoaWxkcmVuKSB7XG4gICAgICB0aGlzLl9zZXRJbml0aWFsQXR0cmlidXRlc09uQ2hpbGQoY2hpbGQpXG4gICAgfVxuICB9XG5cbiAgX3NldEluaXRpYWxBdHRyaWJ1dGVzT25DaGlsZChjaGlsZCkge1xuICAgIGNoaWxkID0gdGhpcy5fZ2V0SW5uZXJFbGVtZW50KGNoaWxkKVxuICAgIGNvbnN0IGlzQWN0aXZlID0gdGhpcy5fZWxlbUlzQWN0aXZlKGNoaWxkKVxuICAgIGNvbnN0IG91dGVyRWxlbSA9IHRoaXMuX2dldE91dGVyRWxlbWVudChjaGlsZClcbiAgICBjaGlsZC5zZXRBdHRyaWJ1dGUoJ2FyaWEtc2VsZWN0ZWQnLCBpc0FjdGl2ZSlcblxuICAgIGlmIChvdXRlckVsZW0gIT09IGNoaWxkKSB7XG4gICAgICB0aGlzLl9zZXRBdHRyaWJ1dGVJZk5vdEV4aXN0cyhvdXRlckVsZW0sICdyb2xlJywgJ3ByZXNlbnRhdGlvbicpXG4gICAgfVxuXG4gICAgaWYgKCFpc0FjdGl2ZSkge1xuICAgICAgY2hpbGQuc2V0QXR0cmlidXRlKCd0YWJpbmRleCcsICctMScpXG4gICAgfVxuXG4gICAgdGhpcy5fc2V0QXR0cmlidXRlSWZOb3RFeGlzdHMoY2hpbGQsICdyb2xlJywgJ3RhYicpXG5cbiAgICAvLyBzZXQgYXR0cmlidXRlcyB0byB0aGUgcmVsYXRlZCBwYW5lbCB0b29cbiAgICB0aGlzLl9zZXRJbml0aWFsQXR0cmlidXRlc09uVGFyZ2V0UGFuZWwoY2hpbGQpXG4gIH1cblxuICBfc2V0SW5pdGlhbEF0dHJpYnV0ZXNPblRhcmdldFBhbmVsKGNoaWxkKSB7XG4gICAgY29uc3QgdGFyZ2V0ID0gU2VsZWN0b3JFbmdpbmUuZ2V0RWxlbWVudEZyb21TZWxlY3RvcihjaGlsZClcblxuICAgIGlmICghdGFyZ2V0KSB7XG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICB0aGlzLl9zZXRBdHRyaWJ1dGVJZk5vdEV4aXN0cyh0YXJnZXQsICdyb2xlJywgJ3RhYnBhbmVsJylcblxuICAgIGlmIChjaGlsZC5pZCkge1xuICAgICAgdGhpcy5fc2V0QXR0cmlidXRlSWZOb3RFeGlzdHModGFyZ2V0LCAnYXJpYS1sYWJlbGxlZGJ5JywgYCR7Y2hpbGQuaWR9YClcbiAgICB9XG4gIH1cblxuICBfdG9nZ2xlRHJvcERvd24oZWxlbWVudCwgb3Blbikge1xuICAgIGNvbnN0IG91dGVyRWxlbSA9IHRoaXMuX2dldE91dGVyRWxlbWVudChlbGVtZW50KVxuICAgIGlmICghb3V0ZXJFbGVtLmNsYXNzTGlzdC5jb250YWlucyhDTEFTU19EUk9QRE9XTikpIHtcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIGNvbnN0IHRvZ2dsZSA9IChzZWxlY3RvciwgY2xhc3NOYW1lKSA9PiB7XG4gICAgICBjb25zdCBlbGVtZW50ID0gU2VsZWN0b3JFbmdpbmUuZmluZE9uZShzZWxlY3Rvciwgb3V0ZXJFbGVtKVxuICAgICAgaWYgKGVsZW1lbnQpIHtcbiAgICAgICAgZWxlbWVudC5jbGFzc0xpc3QudG9nZ2xlKGNsYXNzTmFtZSwgb3BlbilcbiAgICAgIH1cbiAgICB9XG5cbiAgICB0b2dnbGUoU0VMRUNUT1JfRFJPUERPV05fVE9HR0xFLCBDTEFTU19OQU1FX0FDVElWRSlcbiAgICB0b2dnbGUoU0VMRUNUT1JfRFJPUERPV05fTUVOVSwgQ0xBU1NfTkFNRV9TSE9XKVxuICAgIG91dGVyRWxlbS5zZXRBdHRyaWJ1dGUoJ2FyaWEtZXhwYW5kZWQnLCBvcGVuKVxuICB9XG5cbiAgX3NldEF0dHJpYnV0ZUlmTm90RXhpc3RzKGVsZW1lbnQsIGF0dHJpYnV0ZSwgdmFsdWUpIHtcbiAgICBpZiAoIWVsZW1lbnQuaGFzQXR0cmlidXRlKGF0dHJpYnV0ZSkpIHtcbiAgICAgIGVsZW1lbnQuc2V0QXR0cmlidXRlKGF0dHJpYnV0ZSwgdmFsdWUpXG4gICAgfVxuICB9XG5cbiAgX2VsZW1Jc0FjdGl2ZShlbGVtKSB7XG4gICAgcmV0dXJuIGVsZW0uY2xhc3NMaXN0LmNvbnRhaW5zKENMQVNTX05BTUVfQUNUSVZFKVxuICB9XG5cbiAgLy8gVHJ5IHRvIGdldCB0aGUgaW5uZXIgZWxlbWVudCAodXN1YWxseSB0aGUgLm5hdi1saW5rKVxuICBfZ2V0SW5uZXJFbGVtZW50KGVsZW0pIHtcbiAgICByZXR1cm4gZWxlbS5tYXRjaGVzKFNFTEVDVE9SX0lOTkVSX0VMRU0pID8gZWxlbSA6IFNlbGVjdG9yRW5naW5lLmZpbmRPbmUoU0VMRUNUT1JfSU5ORVJfRUxFTSwgZWxlbSlcbiAgfVxuXG4gIC8vIFRyeSB0byBnZXQgdGhlIG91dGVyIGVsZW1lbnQgKHVzdWFsbHkgdGhlIC5uYXYtaXRlbSlcbiAgX2dldE91dGVyRWxlbWVudChlbGVtKSB7XG4gICAgcmV0dXJuIGVsZW0uY2xvc2VzdChTRUxFQ1RPUl9PVVRFUikgfHwgZWxlbVxuICB9XG5cbiAgLy8gU3RhdGljXG4gIHN0YXRpYyBqUXVlcnlJbnRlcmZhY2UoY29uZmlnKSB7XG4gICAgcmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBkYXRhID0gVGFiLmdldE9yQ3JlYXRlSW5zdGFuY2UodGhpcylcblxuICAgICAgaWYgKHR5cGVvZiBjb25maWcgIT09ICdzdHJpbmcnKSB7XG4gICAgICAgIHJldHVyblxuICAgICAgfVxuXG4gICAgICBpZiAoZGF0YVtjb25maWddID09PSB1bmRlZmluZWQgfHwgY29uZmlnLnN0YXJ0c1dpdGgoJ18nKSB8fCBjb25maWcgPT09ICdjb25zdHJ1Y3RvcicpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihgTm8gbWV0aG9kIG5hbWVkIFwiJHtjb25maWd9XCJgKVxuICAgICAgfVxuXG4gICAgICBkYXRhW2NvbmZpZ10oKVxuICAgIH0pXG4gIH1cbn1cblxuLyoqXG4gKiBEYXRhIEFQSSBpbXBsZW1lbnRhdGlvblxuICovXG5cbkV2ZW50SGFuZGxlci5vbihkb2N1bWVudCwgRVZFTlRfQ0xJQ0tfREFUQV9BUEksIFNFTEVDVE9SX0RBVEFfVE9HR0xFLCBmdW5jdGlvbiAoZXZlbnQpIHtcbiAgaWYgKFsnQScsICdBUkVBJ10uaW5jbHVkZXModGhpcy50YWdOYW1lKSkge1xuICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KClcbiAgfVxuXG4gIGlmIChpc0Rpc2FibGVkKHRoaXMpKSB7XG4gICAgcmV0dXJuXG4gIH1cblxuICBUYWIuZ2V0T3JDcmVhdGVJbnN0YW5jZSh0aGlzKS5zaG93KClcbn0pXG5cbi8qKlxuICogSW5pdGlhbGl6ZSBvbiBmb2N1c1xuICovXG5FdmVudEhhbmRsZXIub24od2luZG93LCBFVkVOVF9MT0FEX0RBVEFfQVBJLCAoKSA9PiB7XG4gIGZvciAoY29uc3QgZWxlbWVudCBvZiBTZWxlY3RvckVuZ2luZS5maW5kKFNFTEVDVE9SX0RBVEFfVE9HR0xFX0FDVElWRSkpIHtcbiAgICBUYWIuZ2V0T3JDcmVhdGVJbnN0YW5jZShlbGVtZW50KVxuICB9XG59KVxuLyoqXG4gKiBqUXVlcnlcbiAqL1xuXG5kZWZpbmVKUXVlcnlQbHVnaW4oVGFiKVxuXG5leHBvcnQgZGVmYXVsdCBUYWJcbiIsIi8qKlxuICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAqIEJvb3RzdHJhcCB0b2FzdC5qc1xuICogTGljZW5zZWQgdW5kZXIgTUlUIChodHRwczovL2dpdGh1Yi5jb20vdHdicy9ib290c3RyYXAvYmxvYi9tYWluL0xJQ0VOU0UpXG4gKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICovXG5cbmltcG9ydCBCYXNlQ29tcG9uZW50IGZyb20gJy4vYmFzZS1jb21wb25lbnQuanMnXG5pbXBvcnQgRXZlbnRIYW5kbGVyIGZyb20gJy4vZG9tL2V2ZW50LWhhbmRsZXIuanMnXG5pbXBvcnQgeyBlbmFibGVEaXNtaXNzVHJpZ2dlciB9IGZyb20gJy4vdXRpbC9jb21wb25lbnQtZnVuY3Rpb25zLmpzJ1xuaW1wb3J0IHsgZGVmaW5lSlF1ZXJ5UGx1Z2luLCByZWZsb3cgfSBmcm9tICcuL3V0aWwvaW5kZXguanMnXG5cbi8qKlxuICogQ29uc3RhbnRzXG4gKi9cblxuY29uc3QgTkFNRSA9ICd0b2FzdCdcbmNvbnN0IERBVEFfS0VZID0gJ2JzLnRvYXN0J1xuY29uc3QgRVZFTlRfS0VZID0gYC4ke0RBVEFfS0VZfWBcblxuY29uc3QgRVZFTlRfTU9VU0VPVkVSID0gYG1vdXNlb3ZlciR7RVZFTlRfS0VZfWBcbmNvbnN0IEVWRU5UX01PVVNFT1VUID0gYG1vdXNlb3V0JHtFVkVOVF9LRVl9YFxuY29uc3QgRVZFTlRfRk9DVVNJTiA9IGBmb2N1c2luJHtFVkVOVF9LRVl9YFxuY29uc3QgRVZFTlRfRk9DVVNPVVQgPSBgZm9jdXNvdXQke0VWRU5UX0tFWX1gXG5jb25zdCBFVkVOVF9ISURFID0gYGhpZGUke0VWRU5UX0tFWX1gXG5jb25zdCBFVkVOVF9ISURERU4gPSBgaGlkZGVuJHtFVkVOVF9LRVl9YFxuY29uc3QgRVZFTlRfU0hPVyA9IGBzaG93JHtFVkVOVF9LRVl9YFxuY29uc3QgRVZFTlRfU0hPV04gPSBgc2hvd24ke0VWRU5UX0tFWX1gXG5cbmNvbnN0IENMQVNTX05BTUVfRkFERSA9ICdmYWRlJ1xuY29uc3QgQ0xBU1NfTkFNRV9ISURFID0gJ2hpZGUnIC8vIEBkZXByZWNhdGVkIC0ga2VwdCBoZXJlIG9ubHkgZm9yIGJhY2t3YXJkcyBjb21wYXRpYmlsaXR5XG5jb25zdCBDTEFTU19OQU1FX1NIT1cgPSAnc2hvdydcbmNvbnN0IENMQVNTX05BTUVfU0hPV0lORyA9ICdzaG93aW5nJ1xuXG5jb25zdCBEZWZhdWx0VHlwZSA9IHtcbiAgYW5pbWF0aW9uOiAnYm9vbGVhbicsXG4gIGF1dG9oaWRlOiAnYm9vbGVhbicsXG4gIGRlbGF5OiAnbnVtYmVyJ1xufVxuXG5jb25zdCBEZWZhdWx0ID0ge1xuICBhbmltYXRpb246IHRydWUsXG4gIGF1dG9oaWRlOiB0cnVlLFxuICBkZWxheTogNTAwMFxufVxuXG4vKipcbiAqIENsYXNzIGRlZmluaXRpb25cbiAqL1xuXG5jbGFzcyBUb2FzdCBleHRlbmRzIEJhc2VDb21wb25lbnQge1xuICBjb25zdHJ1Y3RvcihlbGVtZW50LCBjb25maWcpIHtcbiAgICBzdXBlcihlbGVtZW50LCBjb25maWcpXG5cbiAgICB0aGlzLl90aW1lb3V0ID0gbnVsbFxuICAgIHRoaXMuX2hhc01vdXNlSW50ZXJhY3Rpb24gPSBmYWxzZVxuICAgIHRoaXMuX2hhc0tleWJvYXJkSW50ZXJhY3Rpb24gPSBmYWxzZVxuICAgIHRoaXMuX3NldExpc3RlbmVycygpXG4gIH1cblxuICAvLyBHZXR0ZXJzXG4gIHN0YXRpYyBnZXQgRGVmYXVsdCgpIHtcbiAgICByZXR1cm4gRGVmYXVsdFxuICB9XG5cbiAgc3RhdGljIGdldCBEZWZhdWx0VHlwZSgpIHtcbiAgICByZXR1cm4gRGVmYXVsdFR5cGVcbiAgfVxuXG4gIHN0YXRpYyBnZXQgTkFNRSgpIHtcbiAgICByZXR1cm4gTkFNRVxuICB9XG5cbiAgLy8gUHVibGljXG4gIHNob3coKSB7XG4gICAgY29uc3Qgc2hvd0V2ZW50ID0gRXZlbnRIYW5kbGVyLnRyaWdnZXIodGhpcy5fZWxlbWVudCwgRVZFTlRfU0hPVylcblxuICAgIGlmIChzaG93RXZlbnQuZGVmYXVsdFByZXZlbnRlZCkge1xuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgdGhpcy5fY2xlYXJUaW1lb3V0KClcblxuICAgIGlmICh0aGlzLl9jb25maWcuYW5pbWF0aW9uKSB7XG4gICAgICB0aGlzLl9lbGVtZW50LmNsYXNzTGlzdC5hZGQoQ0xBU1NfTkFNRV9GQURFKVxuICAgIH1cblxuICAgIGNvbnN0IGNvbXBsZXRlID0gKCkgPT4ge1xuICAgICAgdGhpcy5fZWxlbWVudC5jbGFzc0xpc3QucmVtb3ZlKENMQVNTX05BTUVfU0hPV0lORylcbiAgICAgIEV2ZW50SGFuZGxlci50cmlnZ2VyKHRoaXMuX2VsZW1lbnQsIEVWRU5UX1NIT1dOKVxuXG4gICAgICB0aGlzLl9tYXliZVNjaGVkdWxlSGlkZSgpXG4gICAgfVxuXG4gICAgdGhpcy5fZWxlbWVudC5jbGFzc0xpc3QucmVtb3ZlKENMQVNTX05BTUVfSElERSkgLy8gQGRlcHJlY2F0ZWRcbiAgICByZWZsb3codGhpcy5fZWxlbWVudClcbiAgICB0aGlzLl9lbGVtZW50LmNsYXNzTGlzdC5hZGQoQ0xBU1NfTkFNRV9TSE9XLCBDTEFTU19OQU1FX1NIT1dJTkcpXG5cbiAgICB0aGlzLl9xdWV1ZUNhbGxiYWNrKGNvbXBsZXRlLCB0aGlzLl9lbGVtZW50LCB0aGlzLl9jb25maWcuYW5pbWF0aW9uKVxuICB9XG5cbiAgaGlkZSgpIHtcbiAgICBpZiAoIXRoaXMuaXNTaG93bigpKSB7XG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICBjb25zdCBoaWRlRXZlbnQgPSBFdmVudEhhbmRsZXIudHJpZ2dlcih0aGlzLl9lbGVtZW50LCBFVkVOVF9ISURFKVxuXG4gICAgaWYgKGhpZGVFdmVudC5kZWZhdWx0UHJldmVudGVkKSB7XG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICBjb25zdCBjb21wbGV0ZSA9ICgpID0+IHtcbiAgICAgIHRoaXMuX2VsZW1lbnQuY2xhc3NMaXN0LmFkZChDTEFTU19OQU1FX0hJREUpIC8vIEBkZXByZWNhdGVkXG4gICAgICB0aGlzLl9lbGVtZW50LmNsYXNzTGlzdC5yZW1vdmUoQ0xBU1NfTkFNRV9TSE9XSU5HLCBDTEFTU19OQU1FX1NIT1cpXG4gICAgICBFdmVudEhhbmRsZXIudHJpZ2dlcih0aGlzLl9lbGVtZW50LCBFVkVOVF9ISURERU4pXG4gICAgfVxuXG4gICAgdGhpcy5fZWxlbWVudC5jbGFzc0xpc3QuYWRkKENMQVNTX05BTUVfU0hPV0lORylcbiAgICB0aGlzLl9xdWV1ZUNhbGxiYWNrKGNvbXBsZXRlLCB0aGlzLl9lbGVtZW50LCB0aGlzLl9jb25maWcuYW5pbWF0aW9uKVxuICB9XG5cbiAgZGlzcG9zZSgpIHtcbiAgICB0aGlzLl9jbGVhclRpbWVvdXQoKVxuXG4gICAgaWYgKHRoaXMuaXNTaG93bigpKSB7XG4gICAgICB0aGlzLl9lbGVtZW50LmNsYXNzTGlzdC5yZW1vdmUoQ0xBU1NfTkFNRV9TSE9XKVxuICAgIH1cblxuICAgIHN1cGVyLmRpc3Bvc2UoKVxuICB9XG5cbiAgaXNTaG93bigpIHtcbiAgICByZXR1cm4gdGhpcy5fZWxlbWVudC5jbGFzc0xpc3QuY29udGFpbnMoQ0xBU1NfTkFNRV9TSE9XKVxuICB9XG5cbiAgLy8gUHJpdmF0ZVxuXG4gIF9tYXliZVNjaGVkdWxlSGlkZSgpIHtcbiAgICBpZiAoIXRoaXMuX2NvbmZpZy5hdXRvaGlkZSkge1xuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgaWYgKHRoaXMuX2hhc01vdXNlSW50ZXJhY3Rpb24gfHwgdGhpcy5faGFzS2V5Ym9hcmRJbnRlcmFjdGlvbikge1xuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgdGhpcy5fdGltZW91dCA9IHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgdGhpcy5oaWRlKClcbiAgICB9LCB0aGlzLl9jb25maWcuZGVsYXkpXG4gIH1cblxuICBfb25JbnRlcmFjdGlvbihldmVudCwgaXNJbnRlcmFjdGluZykge1xuICAgIHN3aXRjaCAoZXZlbnQudHlwZSkge1xuICAgICAgY2FzZSAnbW91c2VvdmVyJzpcbiAgICAgIGNhc2UgJ21vdXNlb3V0Jzoge1xuICAgICAgICB0aGlzLl9oYXNNb3VzZUludGVyYWN0aW9uID0gaXNJbnRlcmFjdGluZ1xuICAgICAgICBicmVha1xuICAgICAgfVxuXG4gICAgICBjYXNlICdmb2N1c2luJzpcbiAgICAgIGNhc2UgJ2ZvY3Vzb3V0Jzoge1xuICAgICAgICB0aGlzLl9oYXNLZXlib2FyZEludGVyYWN0aW9uID0gaXNJbnRlcmFjdGluZ1xuICAgICAgICBicmVha1xuICAgICAgfVxuXG4gICAgICBkZWZhdWx0OiB7XG4gICAgICAgIGJyZWFrXG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGlzSW50ZXJhY3RpbmcpIHtcbiAgICAgIHRoaXMuX2NsZWFyVGltZW91dCgpXG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICBjb25zdCBuZXh0RWxlbWVudCA9IGV2ZW50LnJlbGF0ZWRUYXJnZXRcbiAgICBpZiAodGhpcy5fZWxlbWVudCA9PT0gbmV4dEVsZW1lbnQgfHwgdGhpcy5fZWxlbWVudC5jb250YWlucyhuZXh0RWxlbWVudCkpIHtcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIHRoaXMuX21heWJlU2NoZWR1bGVIaWRlKClcbiAgfVxuXG4gIF9zZXRMaXN0ZW5lcnMoKSB7XG4gICAgRXZlbnRIYW5kbGVyLm9uKHRoaXMuX2VsZW1lbnQsIEVWRU5UX01PVVNFT1ZFUiwgZXZlbnQgPT4gdGhpcy5fb25JbnRlcmFjdGlvbihldmVudCwgdHJ1ZSkpXG4gICAgRXZlbnRIYW5kbGVyLm9uKHRoaXMuX2VsZW1lbnQsIEVWRU5UX01PVVNFT1VULCBldmVudCA9PiB0aGlzLl9vbkludGVyYWN0aW9uKGV2ZW50LCBmYWxzZSkpXG4gICAgRXZlbnRIYW5kbGVyLm9uKHRoaXMuX2VsZW1lbnQsIEVWRU5UX0ZPQ1VTSU4sIGV2ZW50ID0+IHRoaXMuX29uSW50ZXJhY3Rpb24oZXZlbnQsIHRydWUpKVxuICAgIEV2ZW50SGFuZGxlci5vbih0aGlzLl9lbGVtZW50LCBFVkVOVF9GT0NVU09VVCwgZXZlbnQgPT4gdGhpcy5fb25JbnRlcmFjdGlvbihldmVudCwgZmFsc2UpKVxuICB9XG5cbiAgX2NsZWFyVGltZW91dCgpIHtcbiAgICBjbGVhclRpbWVvdXQodGhpcy5fdGltZW91dClcbiAgICB0aGlzLl90aW1lb3V0ID0gbnVsbFxuICB9XG5cbiAgLy8gU3RhdGljXG4gIHN0YXRpYyBqUXVlcnlJbnRlcmZhY2UoY29uZmlnKSB7XG4gICAgcmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBkYXRhID0gVG9hc3QuZ2V0T3JDcmVhdGVJbnN0YW5jZSh0aGlzLCBjb25maWcpXG5cbiAgICAgIGlmICh0eXBlb2YgY29uZmlnID09PSAnc3RyaW5nJykge1xuICAgICAgICBpZiAodHlwZW9mIGRhdGFbY29uZmlnXSA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGBObyBtZXRob2QgbmFtZWQgXCIke2NvbmZpZ31cImApXG4gICAgICAgIH1cblxuICAgICAgICBkYXRhW2NvbmZpZ10odGhpcylcbiAgICAgIH1cbiAgICB9KVxuICB9XG59XG5cbi8qKlxuICogRGF0YSBBUEkgaW1wbGVtZW50YXRpb25cbiAqL1xuXG5lbmFibGVEaXNtaXNzVHJpZ2dlcihUb2FzdClcblxuLyoqXG4gKiBqUXVlcnlcbiAqL1xuXG5kZWZpbmVKUXVlcnlQbHVnaW4oVG9hc3QpXG5cbmV4cG9ydCBkZWZhdWx0IFRvYXN0XG4iLCIvKipcbiAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gKiBCb290c3RyYXAgaW5kZXgudW1kLmpzXG4gKiBMaWNlbnNlZCB1bmRlciBNSVQgKGh0dHBzOi8vZ2l0aHViLmNvbS90d2JzL2Jvb3RzdHJhcC9ibG9iL21haW4vTElDRU5TRSlcbiAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gKi9cblxuaW1wb3J0IEFsZXJ0IGZyb20gJy4vc3JjL2FsZXJ0LmpzJ1xuaW1wb3J0IEJ1dHRvbiBmcm9tICcuL3NyYy9idXR0b24uanMnXG5pbXBvcnQgQ2Fyb3VzZWwgZnJvbSAnLi9zcmMvY2Fyb3VzZWwuanMnXG5pbXBvcnQgQ29sbGFwc2UgZnJvbSAnLi9zcmMvY29sbGFwc2UuanMnXG5pbXBvcnQgRHJvcGRvd24gZnJvbSAnLi9zcmMvZHJvcGRvd24uanMnXG5pbXBvcnQgTW9kYWwgZnJvbSAnLi9zcmMvbW9kYWwuanMnXG5pbXBvcnQgT2ZmY2FudmFzIGZyb20gJy4vc3JjL29mZmNhbnZhcy5qcydcbmltcG9ydCBQb3BvdmVyIGZyb20gJy4vc3JjL3BvcG92ZXIuanMnXG5pbXBvcnQgU2Nyb2xsU3B5IGZyb20gJy4vc3JjL3Njcm9sbHNweS5qcydcbmltcG9ydCBUYWIgZnJvbSAnLi9zcmMvdGFiLmpzJ1xuaW1wb3J0IFRvYXN0IGZyb20gJy4vc3JjL3RvYXN0LmpzJ1xuaW1wb3J0IFRvb2x0aXAgZnJvbSAnLi9zcmMvdG9vbHRpcC5qcydcblxuZXhwb3J0IGRlZmF1bHQge1xuICBBbGVydCxcbiAgQnV0dG9uLFxuICBDYXJvdXNlbCxcbiAgQ29sbGFwc2UsXG4gIERyb3Bkb3duLFxuICBNb2RhbCxcbiAgT2ZmY2FudmFzLFxuICBQb3BvdmVyLFxuICBTY3JvbGxTcHksXG4gIFRhYixcbiAgVG9hc3QsXG4gIFRvb2x0aXBcbn1cbiJdLCJzb3VyY2VSb290IjoiIn0=
|