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_Frontend_Bundle.js === */
|
||
window.rsxapp = window.rsxapp || {};
|
||
window.rsxapp.module_paths = {"bootstrap5_src":"rsx\/theme\/vendor\/bootstrap5\/scss"};
|
||
|
||
|
||
/* === storage/rsx-build/bundles/npm_Frontend_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,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInN0b3JhZ2UvcnN4LXRtcC9idW5kbGVfY29uZmlnX0Zyb250ZW5kX0J1bmRsZS5qcyIsInN0b3JhZ2UvcnN4LWJ1aWxkL2J1bmRsZXMvbnBtX0Zyb250ZW5kX0J1bmRsZV82NDU5ZThlZDBmNjBiZGE0ZjEyMTQyMDc2NjAxMmQ1My5qcyIsIi4uLy4uL2pzL3NyYy9kb20vZGF0YS5qcyIsIi4uLy4uL2pzL3NyYy91dGlsL2luZGV4LmpzIiwiLi4vLi4vanMvc3JjL2RvbS9ldmVudC1oYW5kbGVyLmpzIiwiLi4vLi4vanMvc3JjL2RvbS9tYW5pcHVsYXRvci5qcyIsIi4uLy4uL2pzL3NyYy91dGlsL2NvbmZpZy5qcyIsIi4uLy4uL2pzL3NyYy9iYXNlLWNvbXBvbmVudC5qcyIsIi4uLy4uL2pzL3NyYy9kb20vc2VsZWN0b3ItZW5naW5lLmpzIiwiLi4vLi4vanMvc3JjL3V0aWwvY29tcG9uZW50LWZ1bmN0aW9ucy5qcyIsIi4uLy4uL2pzL3NyYy9hbGVydC5qcyIsIi4uLy4uL2pzL3NyYy9idXR0b24uanMiLCIuLi8uLi9qcy9zcmMvdXRpbC9zd2lwZS5qcyIsIi4uLy4uL2pzL3NyYy9jYXJvdXNlbC5qcyIsIi4uLy4uL2pzL3NyYy9jb2xsYXBzZS5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvZW51bXMuanMiLCIuLi8uLi9ub2RlX21vZHVsZXMvQHBvcHBlcmpzL2NvcmUvbGliL2RvbS11dGlscy9nZXROb2RlTmFtZS5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvZG9tLXV0aWxzL2dldFdpbmRvdy5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvZG9tLXV0aWxzL2luc3RhbmNlT2YuanMiLCIuLi8uLi9ub2RlX21vZHVsZXMvQHBvcHBlcmpzL2NvcmUvbGliL21vZGlmaWVycy9hcHBseVN0eWxlcy5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvdXRpbHMvZ2V0QmFzZVBsYWNlbWVudC5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvdXRpbHMvbWF0aC5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvdXRpbHMvdXNlckFnZW50LmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL0Bwb3BwZXJqcy9jb3JlL2xpYi9kb20tdXRpbHMvaXNMYXlvdXRWaWV3cG9ydC5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvZG9tLXV0aWxzL2dldEJvdW5kaW5nQ2xpZW50UmVjdC5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvZG9tLXV0aWxzL2dldExheW91dFJlY3QuanMiLCIuLi8uLi9ub2RlX21vZHVsZXMvQHBvcHBlcmpzL2NvcmUvbGliL2RvbS11dGlscy9jb250YWlucy5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvZG9tLXV0aWxzL2dldENvbXB1dGVkU3R5bGUuanMiLCIuLi8uLi9ub2RlX21vZHVsZXMvQHBvcHBlcmpzL2NvcmUvbGliL2RvbS11dGlscy9pc1RhYmxlRWxlbWVudC5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvZG9tLXV0aWxzL2dldERvY3VtZW50RWxlbWVudC5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvZG9tLXV0aWxzL2dldFBhcmVudE5vZGUuanMiLCIuLi8uLi9ub2RlX21vZHVsZXMvQHBvcHBlcmpzL2NvcmUvbGliL2RvbS11dGlscy9nZXRPZmZzZXRQYXJlbnQuanMiLCIuLi8uLi9ub2RlX21vZHVsZXMvQHBvcHBlcmpzL2NvcmUvbGliL3V0aWxzL2dldE1haW5BeGlzRnJvbVBsYWNlbWVudC5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvdXRpbHMvd2l0aGluLmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL0Bwb3BwZXJqcy9jb3JlL2xpYi91dGlscy9nZXRGcmVzaFNpZGVPYmplY3QuanMiLCIuLi8uLi9ub2RlX21vZHVsZXMvQHBvcHBlcmpzL2NvcmUvbGliL3V0aWxzL21lcmdlUGFkZGluZ09iamVjdC5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvdXRpbHMvZXhwYW5kVG9IYXNoTWFwLmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL0Bwb3BwZXJqcy9jb3JlL2xpYi9tb2RpZmllcnMvYXJyb3cuanMiLCIuLi8uLi9ub2RlX21vZHVsZXMvQHBvcHBlcmpzL2NvcmUvbGliL3V0aWxzL2dldFZhcmlhdGlvbi5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvbW9kaWZpZXJzL2NvbXB1dGVTdHlsZXMuanMiLCIuLi8uLi9ub2RlX21vZHVsZXMvQHBvcHBlcmpzL2NvcmUvbGliL21vZGlmaWVycy9ldmVudExpc3RlbmVycy5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvdXRpbHMvZ2V0T3Bwb3NpdGVQbGFjZW1lbnQuanMiLCIuLi8uLi9ub2RlX21vZHVsZXMvQHBvcHBlcmpzL2NvcmUvbGliL3V0aWxzL2dldE9wcG9zaXRlVmFyaWF0aW9uUGxhY2VtZW50LmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL0Bwb3BwZXJqcy9jb3JlL2xpYi9kb20tdXRpbHMvZ2V0V2luZG93U2Nyb2xsLmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL0Bwb3BwZXJqcy9jb3JlL2xpYi9kb20tdXRpbHMvZ2V0V2luZG93U2Nyb2xsQmFyWC5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvZG9tLXV0aWxzL2dldFZpZXdwb3J0UmVjdC5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvZG9tLXV0aWxzL2dldERvY3VtZW50UmVjdC5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvZG9tLXV0aWxzL2lzU2Nyb2xsUGFyZW50LmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL0Bwb3BwZXJqcy9jb3JlL2xpYi9kb20tdXRpbHMvZ2V0U2Nyb2xsUGFyZW50LmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL0Bwb3BwZXJqcy9jb3JlL2xpYi9kb20tdXRpbHMvbGlzdFNjcm9sbFBhcmVudHMuanMiLCIuLi8uLi9ub2RlX21vZHVsZXMvQHBvcHBlcmpzL2NvcmUvbGliL3V0aWxzL3JlY3RUb0NsaWVudFJlY3QuanMiLCIuLi8uLi9ub2RlX21vZHVsZXMvQHBvcHBlcmpzL2NvcmUvbGliL2RvbS11dGlscy9nZXRDbGlwcGluZ1JlY3QuanMiLCIuLi8uLi9ub2RlX21vZHVsZXMvQHBvcHBlcmpzL2NvcmUvbGliL3V0aWxzL2NvbXB1dGVPZmZzZXRzLmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL0Bwb3BwZXJqcy9jb3JlL2xpYi91dGlscy9kZXRlY3RPdmVyZmxvdy5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvdXRpbHMvY29tcHV0ZUF1dG9QbGFjZW1lbnQuanMiLCIuLi8uLi9ub2RlX21vZHVsZXMvQHBvcHBlcmpzL2NvcmUvbGliL21vZGlmaWVycy9mbGlwLmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL0Bwb3BwZXJqcy9jb3JlL2xpYi9tb2RpZmllcnMvaGlkZS5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvbW9kaWZpZXJzL29mZnNldC5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvbW9kaWZpZXJzL3BvcHBlck9mZnNldHMuanMiLCIuLi8uLi9ub2RlX21vZHVsZXMvQHBvcHBlcmpzL2NvcmUvbGliL3V0aWxzL2dldEFsdEF4aXMuanMiLCIuLi8uLi9ub2RlX21vZHVsZXMvQHBvcHBlcmpzL2NvcmUvbGliL21vZGlmaWVycy9wcmV2ZW50T3ZlcmZsb3cuanMiLCIuLi8uLi9ub2RlX21vZHVsZXMvQHBvcHBlcmpzL2NvcmUvbGliL2RvbS11dGlscy9nZXRIVE1MRWxlbWVudFNjcm9sbC5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvZG9tLXV0aWxzL2dldE5vZGVTY3JvbGwuanMiLCIuLi8uLi9ub2RlX21vZHVsZXMvQHBvcHBlcmpzL2NvcmUvbGliL2RvbS11dGlscy9nZXRDb21wb3NpdGVSZWN0LmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL0Bwb3BwZXJqcy9jb3JlL2xpYi91dGlscy9vcmRlck1vZGlmaWVycy5qcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9AcG9wcGVyanMvY29yZS9saWIvdXRpbHMvZGVib3VuY2UuanMiLCIuLi8uLi9ub2RlX21vZHVsZXMvQHBvcHBlcmpzL2NvcmUvbGliL3V0aWxzL21lcmdlQnlOYW1lLmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL0Bwb3BwZXJqcy9jb3JlL2xpYi9jcmVhdGVQb3BwZXIuanMiLCIuLi8uLi9ub2RlX21vZHVsZXMvQHBvcHBlcmpzL2NvcmUvbGliL3BvcHBlci1saXRlLmpzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL0Bwb3BwZXJqcy9jb3JlL2xpYi9wb3BwZXIuanMiLCIuLi8uLi9qcy9zcmMvZHJvcGRvd24uanMiLCIuLi8uLi9qcy9zcmMvdXRpbC9iYWNrZHJvcC5qcyIsIi4uLy4uL2pzL3NyYy91dGlsL2ZvY3VzdHJhcC5qcyIsIi4uLy4uL2pzL3NyYy91dGlsL3Njcm9sbGJhci5qcyIsIi4uLy4uL2pzL3NyYy9tb2RhbC5qcyIsIi4uLy4uL2pzL3NyYy9vZmZjYW52YXMuanMiLCIuLi8uLi9qcy9zcmMvdXRpbC9zYW5pdGl6ZXIuanMiLCIuLi8uLi9qcy9zcmMvdXRpbC90ZW1wbGF0ZS1mYWN0b3J5LmpzIiwiLi4vLi4vanMvc3JjL3Rvb2x0aXAuanMiLCIuLi8uLi9qcy9zcmMvcG9wb3Zlci5qcyIsIi4uLy4uL2pzL3NyYy9zY3JvbGxzcHkuanMiLCIuLi8uLi9qcy9zcmMvdGFiLmpzIiwiLi4vLi4vanMvc3JjL3RvYXN0LmpzIiwiLi4vLi4vanMvaW5kZXgudW1kLmpzIl0sIm5hbWVzIjpbImVsZW1lbnRNYXAiLCJNYXAiLCJEYXRhIiwic2V0IiwiZWxlbWVudCIsImtleSIsImluc3RhbmNlIiwiaGFzIiwiaW5zdGFuY2VNYXAiLCJnZXQiLCJzaXplIiwiY29uc29sZSIsImVycm9yIiwiQXJyYXkiLCJmcm9tIiwia2V5cyIsInJlbW92ZSIsImRlbGV0ZSIsIk1BWF9VSUQiLCJNSUxMSVNFQ09ORFNfTVVMVElQTElFUiIsIlRSQU5TSVRJT05fRU5EIiwicGFyc2VTZWxlY3RvciIsInNlbGVjdG9yIiwid2luZG93IiwiQ1NTIiwiZXNjYXBlIiwicmVwbGFjZSIsIm1hdGNoIiwiaWQiLCJ0b1R5cGUiLCJvYmplY3QiLCJ1bmRlZmluZWQiLCJPYmplY3QiLCJwcm90b3R5cGUiLCJ0b1N0cmluZyIsImNhbGwiLCJ0b0xvd2VyQ2FzZSIsImdldFVJRCIsInByZWZpeCIsIk1hdGgiLCJmbG9vciIsInJhbmRvbSIsImRvY3VtZW50IiwiZ2V0RWxlbWVudEJ5SWQiLCJnZXRUcmFuc2l0aW9uRHVyYXRpb25Gcm9tRWxlbWVudCIsInRyYW5zaXRpb25EdXJhdGlvbiIsInRyYW5zaXRpb25EZWxheSIsImdldENvbXB1dGVkU3R5bGUiLCJmbG9hdFRyYW5zaXRpb25EdXJhdGlvbiIsIk51bWJlciIsInBhcnNlRmxvYXQiLCJmbG9hdFRyYW5zaXRpb25EZWxheSIsInNwbGl0IiwidHJpZ2dlclRyYW5zaXRpb25FbmQiLCJkaXNwYXRjaEV2ZW50IiwiRXZlbnQiLCJpc0VsZW1lbnQkMSIsImpxdWVyeSIsIm5vZGVUeXBlIiwiZ2V0RWxlbWVudCIsImxlbmd0aCIsInF1ZXJ5U2VsZWN0b3IiLCJpc1Zpc2libGUiLCJnZXRDbGllbnRSZWN0cyIsImVsZW1lbnRJc1Zpc2libGUiLCJnZXRQcm9wZXJ0eVZhbHVlIiwiY2xvc2VkRGV0YWlscyIsImNsb3Nlc3QiLCJzdW1tYXJ5IiwicGFyZW50Tm9kZSIsImlzRGlzYWJsZWQiLCJOb2RlIiwiRUxFTUVOVF9OT0RFIiwiY2xhc3NMaXN0IiwiY29udGFpbnMiLCJkaXNhYmxlZCIsImhhc0F0dHJpYnV0ZSIsImdldEF0dHJpYnV0ZSIsImZpbmRTaGFkb3dSb290IiwiZG9jdW1lbnRFbGVtZW50IiwiYXR0YWNoU2hhZG93IiwiZ2V0Um9vdE5vZGUiLCJyb290IiwiU2hhZG93Um9vdCIsIm5vb3AiLCJyZWZsb3ciLCJvZmZzZXRIZWlnaHQiLCJnZXRqUXVlcnkiLCJqUXVlcnkiLCJib2R5IiwiRE9NQ29udGVudExvYWRlZENhbGxiYWNrcyIsIm9uRE9NQ29udGVudExvYWRlZCIsImNhbGxiYWNrIiwicmVhZHlTdGF0ZSIsImFkZEV2ZW50TGlzdGVuZXIiLCJwdXNoIiwiaXNSVEwiLCJkaXIiLCJkZWZpbmVKUXVlcnlQbHVnaW4iLCJwbHVnaW4iLCIkIiwibmFtZSIsIk5BTUUiLCJKUVVFUllfTk9fQ09ORkxJQ1QiLCJmbiIsImpRdWVyeUludGVyZmFjZSIsIkNvbnN0cnVjdG9yIiwibm9Db25mbGljdCIsImV4ZWN1dGUiLCJwb3NzaWJsZUNhbGxiYWNrIiwiYXJncyIsImFyZ3VtZW50cyIsImRlZmF1bHRWYWx1ZSIsImV4ZWN1dGVBZnRlclRyYW5zaXRpb24iLCJ0cmFuc2l0aW9uRWxlbWVudCIsIndhaXRGb3JUcmFuc2l0aW9uIiwiZHVyYXRpb25QYWRkaW5nIiwiZW11bGF0ZWREdXJhdGlvbiIsImNhbGxlZCIsImhhbmRsZXIiLCJfcmVmNiIsInRhcmdldCIsInJlbW92ZUV2ZW50TGlzdGVuZXIiLCJzZXRUaW1lb3V0IiwiZ2V0TmV4dEFjdGl2ZUVsZW1lbnQiLCJsaXN0IiwiYWN0aXZlRWxlbWVudCIsInNob3VsZEdldE5leHQiLCJpc0N5Y2xlQWxsb3dlZCIsImxpc3RMZW5ndGgiLCJpbmRleCIsImluZGV4T2YiLCJtYXgiLCJtaW4iLCJuYW1lc3BhY2VSZWdleCIsInN0cmlwTmFtZVJlZ2V4Iiwic3RyaXBVaWRSZWdleCIsImV2ZW50UmVnaXN0cnkiLCJ1aWRFdmVudCIsImN1c3RvbUV2ZW50cyIsIm1vdXNlZW50ZXIiLCJtb3VzZWxlYXZlIiwibmF0aXZlRXZlbnRzIiwiU2V0IiwibWFrZUV2ZW50VWlkIiwidWlkIiwiZ2V0RWxlbWVudEV2ZW50cyIsImJvb3RzdHJhcEhhbmRsZXIiLCJldmVudCIsImh5ZHJhdGVPYmoiLCJkZWxlZ2F0ZVRhcmdldCIsIm9uZU9mZiIsIkV2ZW50SGFuZGxlciIsIm9mZiIsInR5cGUiLCJhcHBseSIsImJvb3RzdHJhcERlbGVnYXRpb25IYW5kbGVyIiwiZG9tRWxlbWVudHMiLCJxdWVyeVNlbGVjdG9yQWxsIiwiZG9tRWxlbWVudCIsImZpbmRIYW5kbGVyIiwiZXZlbnRzIiwiY2FsbGFibGUiLCJkZWxlZ2F0aW9uU2VsZWN0b3IiLCJ2YWx1ZXMiLCJmaW5kIiwibm9ybWFsaXplUGFyYW1ldGVycyIsIm9yaWdpbmFsVHlwZUV2ZW50IiwiZGVsZWdhdGlvbkZ1bmN0aW9uIiwiaXNEZWxlZ2F0ZWQiLCJ0eXBlRXZlbnQiLCJnZXRUeXBlRXZlbnQiLCJhZGRIYW5kbGVyIiwid3JhcEZ1bmN0aW9uIiwicmVsYXRlZFRhcmdldCIsImhhbmRsZXJzIiwicHJldmlvdXNGdW5jdGlvbiIsInJlbW92ZUhhbmRsZXIiLCJCb29sZWFuIiwicmVtb3ZlTmFtZXNwYWNlZEhhbmRsZXJzIiwibmFtZXNwYWNlIiwic3RvcmVFbGVtZW50RXZlbnQiLCJoYW5kbGVyS2V5IiwiZW50cmllcyIsImluY2x1ZGVzIiwib24iLCJvbmUiLCJpbk5hbWVzcGFjZSIsImlzTmFtZXNwYWNlIiwic3RhcnRzV2l0aCIsImVsZW1lbnRFdmVudCIsInNsaWNlIiwia2V5SGFuZGxlcnMiLCJ0cmlnZ2VyIiwialF1ZXJ5RXZlbnQiLCJidWJibGVzIiwibmF0aXZlRGlzcGF0Y2giLCJkZWZhdWx0UHJldmVudGVkIiwiaXNQcm9wYWdhdGlvblN0b3BwZWQiLCJpc0ltbWVkaWF0ZVByb3BhZ2F0aW9uU3RvcHBlZCIsImlzRGVmYXVsdFByZXZlbnRlZCIsImV2dCIsImNhbmNlbGFibGUiLCJwcmV2ZW50RGVmYXVsdCIsIm9iaiIsIm1ldGEiLCJ2YWx1ZSIsIl91bnVzZWQiLCJkZWZpbmVQcm9wZXJ0eSIsImNvbmZpZ3VyYWJsZSIsIm5vcm1hbGl6ZURhdGEiLCJKU09OIiwicGFyc2UiLCJkZWNvZGVVUklDb21wb25lbnQiLCJub3JtYWxpemVEYXRhS2V5IiwiY2hyIiwiTWFuaXB1bGF0b3IiLCJzZXREYXRhQXR0cmlidXRlIiwic2V0QXR0cmlidXRlIiwicmVtb3ZlRGF0YUF0dHJpYnV0ZSIsInJlbW92ZUF0dHJpYnV0ZSIsImdldERhdGFBdHRyaWJ1dGVzIiwiYXR0cmlidXRlcyIsImJzS2V5cyIsImRhdGFzZXQiLCJmaWx0ZXIiLCJwdXJlS2V5IiwiY2hhckF0IiwiZ2V0RGF0YUF0dHJpYnV0ZSIsIkNvbmZpZyIsIkRlZmF1bHQiLCJEZWZhdWx0VHlwZSIsIkVycm9yIiwiX2dldENvbmZpZyIsImNvbmZpZyIsIl9tZXJnZUNvbmZpZ09iaiIsIl9jb25maWdBZnRlck1lcmdlIiwiX3R5cGVDaGVja0NvbmZpZyIsImpzb25Db25maWciLCJjb25zdHJ1Y3RvciIsImNvbmZpZ1R5cGVzIiwicHJvcGVydHkiLCJleHBlY3RlZFR5cGVzIiwidmFsdWVUeXBlIiwiUmVnRXhwIiwidGVzdCIsIlR5cGVFcnJvciIsInRvVXBwZXJDYXNlIiwiVkVSU0lPTiIsIkJhc2VDb21wb25lbnQiLCJfZWxlbWVudCIsIl9jb25maWciLCJEQVRBX0tFWSIsImRpc3Bvc2UiLCJFVkVOVF9LRVkiLCJwcm9wZXJ0eU5hbWUiLCJnZXRPd25Qcm9wZXJ0eU5hbWVzIiwiX3F1ZXVlQ2FsbGJhY2siLCJpc0FuaW1hdGVkIiwiZ2V0SW5zdGFuY2UiLCJnZXRPckNyZWF0ZUluc3RhbmNlIiwiZXZlbnROYW1lIiwiZ2V0U2VsZWN0b3IiLCJocmVmQXR0cmlidXRlIiwidHJpbSIsIm1hcCIsInNlbCIsImpvaW4iLCJTZWxlY3RvckVuZ2luZSIsImNvbmNhdCIsIkVsZW1lbnQiLCJmaW5kT25lIiwiY2hpbGRyZW4iLCJjaGlsZCIsIm1hdGNoZXMiLCJwYXJlbnRzIiwiYW5jZXN0b3IiLCJwcmV2IiwicHJldmlvdXMiLCJwcmV2aW91c0VsZW1lbnRTaWJsaW5nIiwibmV4dCIsIm5leHRFbGVtZW50U2libGluZyIsImZvY3VzYWJsZUNoaWxkcmVuIiwiZm9jdXNhYmxlcyIsImVsIiwiZ2V0U2VsZWN0b3JGcm9tRWxlbWVudCIsImdldEVsZW1lbnRGcm9tU2VsZWN0b3IiLCJnZXRNdWx0aXBsZUVsZW1lbnRzRnJvbVNlbGVjdG9yIiwiZW5hYmxlRGlzbWlzc1RyaWdnZXIiLCJjb21wb25lbnQiLCJtZXRob2QiLCJjbGlja0V2ZW50IiwidGFnTmFtZSIsIk5BTUUkZiIsIkRBVEFfS0VZJGEiLCJFVkVOVF9LRVkkYiIsIkVWRU5UX0NMT1NFIiwiRVZFTlRfQ0xPU0VEIiwiQ0xBU1NfTkFNRV9GQURFJDUiLCJDTEFTU19OQU1FX1NIT1ckOCIsIkFsZXJ0IiwiY2xvc2UiLCJjbG9zZUV2ZW50IiwiX2Rlc3Ryb3lFbGVtZW50IiwiZWFjaCIsImRhdGEiLCJOQU1FJGUiLCJEQVRBX0tFWSQ5IiwiRVZFTlRfS0VZJGEiLCJEQVRBX0FQSV9LRVkkNiIsIkNMQVNTX05BTUVfQUNUSVZFJDMiLCJTRUxFQ1RPUl9EQVRBX1RPR0dMRSQ1IiwiRVZFTlRfQ0xJQ0tfREFUQV9BUEkkNiIsIkJ1dHRvbiIsInRvZ2dsZSIsImJ1dHRvbiIsIk5BTUUkZCIsIkVWRU5UX0tFWSQ5IiwiRVZFTlRfVE9VQ0hTVEFSVCIsIkVWRU5UX1RPVUNITU9WRSIsIkVWRU5UX1RPVUNIRU5EIiwiRVZFTlRfUE9JTlRFUkRPV04iLCJFVkVOVF9QT0lOVEVSVVAiLCJQT0lOVEVSX1RZUEVfVE9VQ0giLCJQT0lOVEVSX1RZUEVfUEVOIiwiQ0xBU1NfTkFNRV9QT0lOVEVSX0VWRU5UIiwiU1dJUEVfVEhSRVNIT0xEIiwiRGVmYXVsdCRjIiwiZW5kQ2FsbGJhY2siLCJsZWZ0Q2FsbGJhY2siLCJyaWdodENhbGxiYWNrIiwiRGVmYXVsdFR5cGUkYyIsIlN3aXBlIiwiaXNTdXBwb3J0ZWQiLCJfZGVsdGFYIiwiX3N1cHBvcnRQb2ludGVyRXZlbnRzIiwiUG9pbnRlckV2ZW50IiwiX2luaXRFdmVudHMiLCJfc3RhcnQiLCJ0b3VjaGVzIiwiY2xpZW50WCIsIl9ldmVudElzUG9pbnRlclBlblRvdWNoIiwiX2VuZCIsIl9oYW5kbGVTd2lwZSIsIl9tb3ZlIiwiYWJzRGVsdGFYIiwiYWJzIiwiZGlyZWN0aW9uIiwiYWRkIiwicG9pbnRlclR5cGUiLCJuYXZpZ2F0b3IiLCJtYXhUb3VjaFBvaW50cyIsIk5BTUUkYyIsIkRBVEFfS0VZJDgiLCJFVkVOVF9LRVkkOCIsIkRBVEFfQVBJX0tFWSQ1IiwiQVJST1dfTEVGVF9LRVkkMSIsIkFSUk9XX1JJR0hUX0tFWSQxIiwiVE9VQ0hFVkVOVF9DT01QQVRfV0FJVCIsIk9SREVSX05FWFQiLCJPUkRFUl9QUkVWIiwiRElSRUNUSU9OX0xFRlQiLCJESVJFQ1RJT05fUklHSFQiLCJFVkVOVF9TTElERSIsIkVWRU5UX1NMSUQiLCJFVkVOVF9LRVlET1dOJDEiLCJFVkVOVF9NT1VTRUVOVEVSJDEiLCJFVkVOVF9NT1VTRUxFQVZFJDEiLCJFVkVOVF9EUkFHX1NUQVJUIiwiRVZFTlRfTE9BRF9EQVRBX0FQSSQzIiwiRVZFTlRfQ0xJQ0tfREFUQV9BUEkkNSIsIkNMQVNTX05BTUVfQ0FST1VTRUwiLCJDTEFTU19OQU1FX0FDVElWRSQyIiwiQ0xBU1NfTkFNRV9TTElERSIsIkNMQVNTX05BTUVfRU5EIiwiQ0xBU1NfTkFNRV9TVEFSVCIsIkNMQVNTX05BTUVfTkVYVCIsIkNMQVNTX05BTUVfUFJFViIsIlNFTEVDVE9SX0FDVElWRSIsIlNFTEVDVE9SX0lURU0iLCJTRUxFQ1RPUl9BQ1RJVkVfSVRFTSIsIlNFTEVDVE9SX0lURU1fSU1HIiwiU0VMRUNUT1JfSU5ESUNBVE9SUyIsIlNFTEVDVE9SX0RBVEFfU0xJREUiLCJTRUxFQ1RPUl9EQVRBX1JJREUiLCJLRVlfVE9fRElSRUNUSU9OIiwiRGVmYXVsdCRiIiwiaW50ZXJ2YWwiLCJrZXlib2FyZCIsInBhdXNlIiwicmlkZSIsInRvdWNoIiwid3JhcCIsIkRlZmF1bHRUeXBlJGIiLCJDYXJvdXNlbCIsIl9pbnRlcnZhbCIsIl9hY3RpdmVFbGVtZW50IiwiX2lzU2xpZGluZyIsInRvdWNoVGltZW91dCIsIl9zd2lwZUhlbHBlciIsIl9pbmRpY2F0b3JzRWxlbWVudCIsIl9hZGRFdmVudExpc3RlbmVycyIsImN5Y2xlIiwiX3NsaWRlIiwibmV4dFdoZW5WaXNpYmxlIiwiaGlkZGVuIiwiX2NsZWFySW50ZXJ2YWwiLCJfdXBkYXRlSW50ZXJ2YWwiLCJzZXRJbnRlcnZhbCIsIl9tYXliZUVuYWJsZUN5Y2xlIiwidG8iLCJpdGVtcyIsIl9nZXRJdGVtcyIsImFjdGl2ZUluZGV4IiwiX2dldEl0ZW1JbmRleCIsIl9nZXRBY3RpdmUiLCJvcmRlciIsImRlZmF1bHRJbnRlcnZhbCIsIl9rZXlkb3duIiwiX2FkZFRvdWNoRXZlbnRMaXN0ZW5lcnMiLCJpbWciLCJlbmRDYWxsQmFjayIsImNsZWFyVGltZW91dCIsInN3aXBlQ29uZmlnIiwiX2RpcmVjdGlvblRvT3JkZXIiLCJfc2V0QWN0aXZlSW5kaWNhdG9yRWxlbWVudCIsImFjdGl2ZUluZGljYXRvciIsIm5ld0FjdGl2ZUluZGljYXRvciIsImVsZW1lbnRJbnRlcnZhbCIsInBhcnNlSW50IiwiaXNOZXh0IiwibmV4dEVsZW1lbnQiLCJuZXh0RWxlbWVudEluZGV4IiwidHJpZ2dlckV2ZW50IiwiX29yZGVyVG9EaXJlY3Rpb24iLCJzbGlkZUV2ZW50IiwiaXNDeWNsaW5nIiwiZGlyZWN0aW9uYWxDbGFzc05hbWUiLCJvcmRlckNsYXNzTmFtZSIsImNvbXBsZXRlQ2FsbEJhY2siLCJfaXNBbmltYXRlZCIsImNsZWFySW50ZXJ2YWwiLCJjYXJvdXNlbCIsInNsaWRlSW5kZXgiLCJjYXJvdXNlbHMiLCJOQU1FJGIiLCJEQVRBX0tFWSQ3IiwiRVZFTlRfS0VZJDciLCJEQVRBX0FQSV9LRVkkNCIsIkVWRU5UX1NIT1ckNiIsIkVWRU5UX1NIT1dOJDYiLCJFVkVOVF9ISURFJDYiLCJFVkVOVF9ISURERU4kNiIsIkVWRU5UX0NMSUNLX0RBVEFfQVBJJDQiLCJDTEFTU19OQU1FX1NIT1ckNyIsIkNMQVNTX05BTUVfQ09MTEFQU0UiLCJDTEFTU19OQU1FX0NPTExBUFNJTkciLCJDTEFTU19OQU1FX0NPTExBUFNFRCIsIkNMQVNTX05BTUVfREVFUEVSX0NISUxEUkVOIiwiQ0xBU1NfTkFNRV9IT1JJWk9OVEFMIiwiV0lEVEgiLCJIRUlHSFQiLCJTRUxFQ1RPUl9BQ1RJVkVTIiwiU0VMRUNUT1JfREFUQV9UT0dHTEUkNCIsIkRlZmF1bHQkYSIsInBhcmVudCIsIkRlZmF1bHRUeXBlJGEiLCJDb2xsYXBzZSIsIl9pc1RyYW5zaXRpb25pbmciLCJfdHJpZ2dlckFycmF5IiwidG9nZ2xlTGlzdCIsImVsZW0iLCJmaWx0ZXJFbGVtZW50IiwiZm91bmRFbGVtZW50IiwiX2luaXRpYWxpemVDaGlsZHJlbiIsIl9hZGRBcmlhQW5kQ29sbGFwc2VkQ2xhc3MiLCJfaXNTaG93biIsImhpZGUiLCJzaG93IiwiYWN0aXZlQ2hpbGRyZW4iLCJfZ2V0Rmlyc3RMZXZlbENoaWxkcmVuIiwic3RhcnRFdmVudCIsImFjdGl2ZUluc3RhbmNlIiwiZGltZW5zaW9uIiwiX2dldERpbWVuc2lvbiIsInN0eWxlIiwiY29tcGxldGUiLCJjYXBpdGFsaXplZERpbWVuc2lvbiIsInNjcm9sbFNpemUiLCJnZXRCb3VuZGluZ0NsaWVudFJlY3QiLCJzZWxlY3RlZCIsInRyaWdnZXJBcnJheSIsImlzT3BlbiIsInRvcCIsImJvdHRvbSIsInJpZ2h0IiwibGVmdCIsImF1dG8iLCJiYXNlUGxhY2VtZW50cyIsInN0YXJ0IiwiZW5kIiwiY2xpcHBpbmdQYXJlbnRzIiwidmlld3BvcnQiLCJwb3BwZXIiLCJyZWZlcmVuY2UiLCJ2YXJpYXRpb25QbGFjZW1lbnRzIiwicmVkdWNlIiwiYWNjIiwicGxhY2VtZW50IiwicGxhY2VtZW50cyIsImJlZm9yZVJlYWQiLCJyZWFkIiwiYWZ0ZXJSZWFkIiwiYmVmb3JlTWFpbiIsIm1haW4iLCJhZnRlck1haW4iLCJiZWZvcmVXcml0ZSIsIndyaXRlIiwiYWZ0ZXJXcml0ZSIsIm1vZGlmaWVyUGhhc2VzIiwiZ2V0Tm9kZU5hbWUiLCJub2RlTmFtZSIsImdldFdpbmRvdyIsIm5vZGUiLCJvd25lckRvY3VtZW50IiwiZGVmYXVsdFZpZXciLCJpc0VsZW1lbnQiLCJPd25FbGVtZW50IiwiaXNIVE1MRWxlbWVudCIsIkhUTUxFbGVtZW50IiwiaXNTaGFkb3dSb290IiwiYXBwbHlTdHlsZXMiLCJfcmVmIiwic3RhdGUiLCJlbGVtZW50cyIsImZvckVhY2giLCJzdHlsZXMiLCJhc3NpZ24iLCJlZmZlY3QkMiIsImVmZmVjdCIsIl9yZWYyIiwiaW5pdGlhbFN0eWxlcyIsInBvc2l0aW9uIiwib3B0aW9ucyIsInN0cmF0ZWd5IiwibWFyZ2luIiwiYXJyb3ciLCJzdHlsZVByb3BlcnRpZXMiLCJoYXNPd25Qcm9wZXJ0eSIsImF0dHJpYnV0ZSIsImFwcGx5U3R5bGVzJDEiLCJlbmFibGVkIiwicGhhc2UiLCJyZXF1aXJlcyIsImdldEJhc2VQbGFjZW1lbnQiLCJyb3VuZCIsImdldFVBU3RyaW5nIiwidWFEYXRhIiwidXNlckFnZW50RGF0YSIsImJyYW5kcyIsImlzQXJyYXkiLCJpdGVtIiwiYnJhbmQiLCJ2ZXJzaW9uIiwidXNlckFnZW50IiwiaXNMYXlvdXRWaWV3cG9ydCIsImluY2x1ZGVTY2FsZSIsImlzRml4ZWRTdHJhdGVneSIsImNsaWVudFJlY3QiLCJzY2FsZVgiLCJzY2FsZVkiLCJvZmZzZXRXaWR0aCIsIndpZHRoIiwiaGVpZ2h0IiwidmlzdWFsVmlld3BvcnQiLCJhZGRWaXN1YWxPZmZzZXRzIiwieCIsIm9mZnNldExlZnQiLCJ5Iiwib2Zmc2V0VG9wIiwiZ2V0TGF5b3V0UmVjdCIsInJvb3ROb2RlIiwiaXNTYW1lTm9kZSIsImhvc3QiLCJnZXRDb21wdXRlZFN0eWxlJDEiLCJpc1RhYmxlRWxlbWVudCIsImdldERvY3VtZW50RWxlbWVudCIsImdldFBhcmVudE5vZGUiLCJhc3NpZ25lZFNsb3QiLCJnZXRUcnVlT2Zmc2V0UGFyZW50Iiwib2Zmc2V0UGFyZW50IiwiZ2V0Q29udGFpbmluZ0Jsb2NrIiwiaXNGaXJlZm94IiwiaXNJRSIsImVsZW1lbnRDc3MiLCJjdXJyZW50Tm9kZSIsImNzcyIsInRyYW5zZm9ybSIsInBlcnNwZWN0aXZlIiwiY29udGFpbiIsIndpbGxDaGFuZ2UiLCJnZXRPZmZzZXRQYXJlbnQiLCJnZXRNYWluQXhpc0Zyb21QbGFjZW1lbnQiLCJ3aXRoaW4iLCJtaW4kMSIsIm1heCQxIiwid2l0aGluTWF4Q2xhbXAiLCJ2IiwiZ2V0RnJlc2hTaWRlT2JqZWN0IiwibWVyZ2VQYWRkaW5nT2JqZWN0IiwicGFkZGluZ09iamVjdCIsImV4cGFuZFRvSGFzaE1hcCIsImhhc2hNYXAiLCJ0b1BhZGRpbmdPYmplY3QiLCJwYWRkaW5nIiwicmVjdHMiLCJfc3RhdGUkbW9kaWZpZXJzRGF0YSQiLCJhcnJvd0VsZW1lbnQiLCJwb3BwZXJPZmZzZXRzIiwibW9kaWZpZXJzRGF0YSIsImJhc2VQbGFjZW1lbnQiLCJheGlzIiwiaXNWZXJ0aWNhbCIsImxlbiIsImFycm93UmVjdCIsIm1pblByb3AiLCJtYXhQcm9wIiwiZW5kRGlmZiIsInN0YXJ0RGlmZiIsImFycm93T2Zmc2V0UGFyZW50IiwiY2xpZW50U2l6ZSIsImNsaWVudEhlaWdodCIsImNsaWVudFdpZHRoIiwiY2VudGVyVG9SZWZlcmVuY2UiLCJjZW50ZXIiLCJvZmZzZXQiLCJheGlzUHJvcCIsImNlbnRlck9mZnNldCIsImVmZmVjdCQxIiwiX29wdGlvbnMkZWxlbWVudCIsImFycm93JDEiLCJyZXF1aXJlc0lmRXhpc3RzIiwiZ2V0VmFyaWF0aW9uIiwidW5zZXRTaWRlcyIsInJvdW5kT2Zmc2V0c0J5RFBSIiwid2luIiwiZHByIiwiZGV2aWNlUGl4ZWxSYXRpbyIsIm1hcFRvU3R5bGVzIiwiX09iamVjdCRhc3NpZ24yIiwicG9wcGVyUmVjdCIsInZhcmlhdGlvbiIsIm9mZnNldHMiLCJncHVBY2NlbGVyYXRpb24iLCJhZGFwdGl2ZSIsInJvdW5kT2Zmc2V0cyIsImlzRml4ZWQiLCJfb2Zmc2V0cyR4IiwiX29mZnNldHMkeSIsIl9yZWYzIiwiaGFzWCIsImhhc1kiLCJzaWRlWCIsInNpZGVZIiwiaGVpZ2h0UHJvcCIsIndpZHRoUHJvcCIsIm9mZnNldFkiLCJvZmZzZXRYIiwiY29tbW9uU3R5bGVzIiwiX3JlZjQiLCJfT2JqZWN0JGFzc2lnbiIsImNvbXB1dGVTdHlsZXMiLCJfcmVmNSIsIl9vcHRpb25zJGdwdUFjY2VsZXJhdCIsIl9vcHRpb25zJGFkYXB0aXZlIiwiX29wdGlvbnMkcm91bmRPZmZzZXRzIiwiY29tcHV0ZVN0eWxlcyQxIiwicGFzc2l2ZSIsIl9vcHRpb25zJHNjcm9sbCIsInNjcm9sbCIsIl9vcHRpb25zJHJlc2l6ZSIsInJlc2l6ZSIsInNjcm9sbFBhcmVudHMiLCJzY3JvbGxQYXJlbnQiLCJ1cGRhdGUiLCJldmVudExpc3RlbmVycyIsImhhc2gkMSIsImdldE9wcG9zaXRlUGxhY2VtZW50IiwibWF0Y2hlZCIsImhhc2giLCJnZXRPcHBvc2l0ZVZhcmlhdGlvblBsYWNlbWVudCIsImdldFdpbmRvd1Njcm9sbCIsInNjcm9sbExlZnQiLCJwYWdlWE9mZnNldCIsInNjcm9sbFRvcCIsInBhZ2VZT2Zmc2V0IiwiZ2V0V2luZG93U2Nyb2xsQmFyWCIsImdldFZpZXdwb3J0UmVjdCIsImh0bWwiLCJsYXlvdXRWaWV3cG9ydCIsImdldERvY3VtZW50UmVjdCIsIl9lbGVtZW50JG93bmVyRG9jdW1lbiIsIndpblNjcm9sbCIsInNjcm9sbFdpZHRoIiwic2Nyb2xsSGVpZ2h0IiwiaXNTY3JvbGxQYXJlbnQiLCJfZ2V0Q29tcHV0ZWRTdHlsZSIsIm92ZXJmbG93Iiwib3ZlcmZsb3dYIiwib3ZlcmZsb3dZIiwiZ2V0U2Nyb2xsUGFyZW50IiwibGlzdFNjcm9sbFBhcmVudHMiLCJpc0JvZHkiLCJ1cGRhdGVkTGlzdCIsInJlY3RUb0NsaWVudFJlY3QiLCJyZWN0IiwiZ2V0SW5uZXJCb3VuZGluZ0NsaWVudFJlY3QiLCJjbGllbnRUb3AiLCJjbGllbnRMZWZ0IiwiZ2V0Q2xpZW50UmVjdEZyb21NaXhlZFR5cGUiLCJjbGlwcGluZ1BhcmVudCIsImdldENsaXBwaW5nUGFyZW50cyIsImNhbkVzY2FwZUNsaXBwaW5nIiwiY2xpcHBlckVsZW1lbnQiLCJnZXRDbGlwcGluZ1JlY3QiLCJib3VuZGFyeSIsInJvb3RCb3VuZGFyeSIsIm1haW5DbGlwcGluZ1BhcmVudHMiLCJmaXJzdENsaXBwaW5nUGFyZW50IiwiY2xpcHBpbmdSZWN0IiwiYWNjUmVjdCIsImNvbXB1dGVPZmZzZXRzIiwiY29tbW9uWCIsImNvbW1vblkiLCJtYWluQXhpcyIsImRldGVjdE92ZXJmbG93IiwiX29wdGlvbnMiLCJfb3B0aW9ucyRwbGFjZW1lbnQiLCJfb3B0aW9ucyRzdHJhdGVneSIsIl9vcHRpb25zJGJvdW5kYXJ5IiwiX29wdGlvbnMkcm9vdEJvdW5kYXJ5IiwiX29wdGlvbnMkZWxlbWVudENvbnRlIiwiZWxlbWVudENvbnRleHQiLCJfb3B0aW9ucyRhbHRCb3VuZGFyeSIsImFsdEJvdW5kYXJ5IiwiX29wdGlvbnMkcGFkZGluZyIsImFsdENvbnRleHQiLCJjbGlwcGluZ0NsaWVudFJlY3QiLCJjb250ZXh0RWxlbWVudCIsInJlZmVyZW5jZUNsaWVudFJlY3QiLCJwb3BwZXJDbGllbnRSZWN0IiwiZWxlbWVudENsaWVudFJlY3QiLCJvdmVyZmxvd09mZnNldHMiLCJvZmZzZXREYXRhIiwibXVsdGlwbHkiLCJjb21wdXRlQXV0b1BsYWNlbWVudCIsImZsaXBWYXJpYXRpb25zIiwiX29wdGlvbnMkYWxsb3dlZEF1dG9QIiwiYWxsb3dlZEF1dG9QbGFjZW1lbnRzIiwicGxhY2VtZW50cyQxIiwiYWxsb3dlZFBsYWNlbWVudHMiLCJvdmVyZmxvd3MiLCJzb3J0IiwiYSIsImIiLCJnZXRFeHBhbmRlZEZhbGxiYWNrUGxhY2VtZW50cyIsIm9wcG9zaXRlUGxhY2VtZW50IiwiZmxpcCIsIl9za2lwIiwiX29wdGlvbnMkbWFpbkF4aXMiLCJjaGVja01haW5BeGlzIiwiX29wdGlvbnMkYWx0QXhpcyIsImFsdEF4aXMiLCJjaGVja0FsdEF4aXMiLCJzcGVjaWZpZWRGYWxsYmFja1BsYWNlbWVudHMiLCJmYWxsYmFja1BsYWNlbWVudHMiLCJfb3B0aW9ucyRmbGlwVmFyaWF0aW8iLCJwcmVmZXJyZWRQbGFjZW1lbnQiLCJpc0Jhc2VQbGFjZW1lbnQiLCJyZWZlcmVuY2VSZWN0IiwiY2hlY2tzTWFwIiwibWFrZUZhbGxiYWNrQ2hlY2tzIiwiZmlyc3RGaXR0aW5nUGxhY2VtZW50IiwiaSIsIl9iYXNlUGxhY2VtZW50IiwiaXNTdGFydFZhcmlhdGlvbiIsIm1haW5WYXJpYXRpb25TaWRlIiwiYWx0VmFyaWF0aW9uU2lkZSIsImNoZWNrcyIsImV2ZXJ5IiwiY2hlY2siLCJudW1iZXJPZkNoZWNrcyIsIl9sb29wIiwiX2kiLCJmaXR0aW5nUGxhY2VtZW50IiwiX3JldCIsInJlc2V0IiwiZmxpcCQxIiwiZ2V0U2lkZU9mZnNldHMiLCJwcmV2ZW50ZWRPZmZzZXRzIiwiaXNBbnlTaWRlRnVsbHlDbGlwcGVkIiwic29tZSIsInNpZGUiLCJwcmV2ZW50T3ZlcmZsb3ciLCJyZWZlcmVuY2VPdmVyZmxvdyIsInBvcHBlckFsdE92ZXJmbG93IiwicmVmZXJlbmNlQ2xpcHBpbmdPZmZzZXRzIiwicG9wcGVyRXNjYXBlT2Zmc2V0cyIsImlzUmVmZXJlbmNlSGlkZGVuIiwiaGFzUG9wcGVyRXNjYXBlZCIsImhpZGUkMSIsImRpc3RhbmNlQW5kU2tpZGRpbmdUb1hZIiwiaW52ZXJ0RGlzdGFuY2UiLCJza2lkZGluZyIsImRpc3RhbmNlIiwiX29wdGlvbnMkb2Zmc2V0IiwiX2RhdGEkc3RhdGUkcGxhY2VtZW50Iiwib2Zmc2V0JDEiLCJwb3BwZXJPZmZzZXRzJDEiLCJnZXRBbHRBeGlzIiwiX29wdGlvbnMkdGV0aGVyIiwidGV0aGVyIiwiX29wdGlvbnMkdGV0aGVyT2Zmc2V0IiwidGV0aGVyT2Zmc2V0IiwidGV0aGVyT2Zmc2V0VmFsdWUiLCJub3JtYWxpemVkVGV0aGVyT2Zmc2V0VmFsdWUiLCJvZmZzZXRNb2RpZmllclN0YXRlIiwiX29mZnNldE1vZGlmaWVyU3RhdGUkIiwibWFpblNpZGUiLCJhbHRTaWRlIiwiYWRkaXRpdmUiLCJtaW5MZW4iLCJtYXhMZW4iLCJhcnJvd1BhZGRpbmdPYmplY3QiLCJhcnJvd1BhZGRpbmdNaW4iLCJhcnJvd1BhZGRpbmdNYXgiLCJhcnJvd0xlbiIsIm1pbk9mZnNldCIsIm1heE9mZnNldCIsImNsaWVudE9mZnNldCIsIm9mZnNldE1vZGlmaWVyVmFsdWUiLCJ0ZXRoZXJNaW4iLCJ0ZXRoZXJNYXgiLCJwcmV2ZW50ZWRPZmZzZXQiLCJfb2Zmc2V0TW9kaWZpZXJTdGF0ZSQyIiwiX21haW5TaWRlIiwiX2FsdFNpZGUiLCJfb2Zmc2V0IiwiX2xlbiIsIl9taW4iLCJfbWF4IiwiaXNPcmlnaW5TaWRlIiwiX29mZnNldE1vZGlmaWVyVmFsdWUiLCJfdGV0aGVyTWluIiwiX3RldGhlck1heCIsIl9wcmV2ZW50ZWRPZmZzZXQiLCJwcmV2ZW50T3ZlcmZsb3ckMSIsImdldEhUTUxFbGVtZW50U2Nyb2xsIiwiZ2V0Tm9kZVNjcm9sbCIsImlzRWxlbWVudFNjYWxlZCIsImdldENvbXBvc2l0ZVJlY3QiLCJlbGVtZW50T3JWaXJ0dWFsRWxlbWVudCIsImlzT2Zmc2V0UGFyZW50QW5FbGVtZW50Iiwib2Zmc2V0UGFyZW50SXNTY2FsZWQiLCJtb2RpZmllcnMiLCJ2aXNpdGVkIiwicmVzdWx0IiwibW9kaWZpZXIiLCJkZXAiLCJkZXBNb2RpZmllciIsIm9yZGVyTW9kaWZpZXJzIiwib3JkZXJlZE1vZGlmaWVycyIsImRlYm91bmNlIiwicGVuZGluZyIsIlByb21pc2UiLCJyZXNvbHZlIiwidGhlbiIsIm1lcmdlQnlOYW1lIiwibWVyZ2VkIiwiY3VycmVudCIsImV4aXN0aW5nIiwiREVGQVVMVF9PUFRJT05TIiwiYXJlVmFsaWRFbGVtZW50cyIsIl9rZXkiLCJwb3BwZXJHZW5lcmF0b3IiLCJnZW5lcmF0b3JPcHRpb25zIiwiX2dlbmVyYXRvck9wdGlvbnMiLCJfZ2VuZXJhdG9yT3B0aW9ucyRkZWYiLCJkZWZhdWx0TW9kaWZpZXJzIiwiX2dlbmVyYXRvck9wdGlvbnMkZGVmMiIsImRlZmF1bHRPcHRpb25zIiwiY3JlYXRlUG9wcGVyIiwiZWZmZWN0Q2xlYW51cEZucyIsImlzRGVzdHJveWVkIiwic2V0T3B0aW9ucyIsInNldE9wdGlvbnNBY3Rpb24iLCJjbGVhbnVwTW9kaWZpZXJFZmZlY3RzIiwibSIsInJ1bk1vZGlmaWVyRWZmZWN0cyIsImZvcmNlVXBkYXRlIiwiX3N0YXRlJGVsZW1lbnRzIiwiX3N0YXRlJG9yZGVyZWRNb2RpZmllIiwiX3N0YXRlJG9yZGVyZWRNb2RpZmllMiIsImRlc3Ryb3kiLCJvbkZpcnN0VXBkYXRlIiwiX3JlZiRvcHRpb25zIiwiY2xlYW51cEZuIiwibm9vcEZuIiwiY3JlYXRlUG9wcGVyJDIiLCJkZWZhdWx0TW9kaWZpZXJzJDEiLCJjcmVhdGVQb3BwZXIkMSIsIk5BTUUkYSIsIkRBVEFfS0VZJDYiLCJFVkVOVF9LRVkkNiIsIkRBVEFfQVBJX0tFWSQzIiwiRVNDQVBFX0tFWSQyIiwiVEFCX0tFWSQxIiwiQVJST1dfVVBfS0VZJDEiLCJBUlJPV19ET1dOX0tFWSQxIiwiUklHSFRfTU9VU0VfQlVUVE9OIiwiRVZFTlRfSElERSQ1IiwiRVZFTlRfSElEREVOJDUiLCJFVkVOVF9TSE9XJDUiLCJFVkVOVF9TSE9XTiQ1IiwiRVZFTlRfQ0xJQ0tfREFUQV9BUEkkMyIsIkVWRU5UX0tFWURPV05fREFUQV9BUEkiLCJFVkVOVF9LRVlVUF9EQVRBX0FQSSIsIkNMQVNTX05BTUVfU0hPVyQ2IiwiQ0xBU1NfTkFNRV9EUk9QVVAiLCJDTEFTU19OQU1FX0RST1BFTkQiLCJDTEFTU19OQU1FX0RST1BTVEFSVCIsIkNMQVNTX05BTUVfRFJPUFVQX0NFTlRFUiIsIkNMQVNTX05BTUVfRFJPUERPV05fQ0VOVEVSIiwiU0VMRUNUT1JfREFUQV9UT0dHTEUkMyIsIlNFTEVDVE9SX0RBVEFfVE9HR0xFX1NIT1dOIiwiU0VMRUNUT1JfTUVOVSIsIlNFTEVDVE9SX05BVkJBUiIsIlNFTEVDVE9SX05BVkJBUl9OQVYiLCJTRUxFQ1RPUl9WSVNJQkxFX0lURU1TIiwiUExBQ0VNRU5UX1RPUCIsIlBMQUNFTUVOVF9UT1BFTkQiLCJQTEFDRU1FTlRfQk9UVE9NIiwiUExBQ0VNRU5UX0JPVFRPTUVORCIsIlBMQUNFTUVOVF9SSUdIVCIsIlBMQUNFTUVOVF9MRUZUIiwiUExBQ0VNRU5UX1RPUENFTlRFUiIsIlBMQUNFTUVOVF9CT1RUT01DRU5URVIiLCJEZWZhdWx0JDkiLCJhdXRvQ2xvc2UiLCJkaXNwbGF5IiwicG9wcGVyQ29uZmlnIiwiRGVmYXVsdFR5cGUkOSIsIkRyb3Bkb3duIiwiX3BvcHBlciIsIl9wYXJlbnQiLCJfbWVudSIsIl9pbk5hdmJhciIsIl9kZXRlY3ROYXZiYXIiLCJzaG93RXZlbnQiLCJfY3JlYXRlUG9wcGVyIiwiZm9jdXMiLCJfY29tcGxldGVIaWRlIiwiaGlkZUV2ZW50IiwiUG9wcGVyIiwicmVmZXJlbmNlRWxlbWVudCIsIl9nZXRQb3BwZXJDb25maWciLCJfZ2V0UGxhY2VtZW50IiwicGFyZW50RHJvcGRvd24iLCJpc0VuZCIsIl9nZXRPZmZzZXQiLCJwb3BwZXJEYXRhIiwiZGVmYXVsdEJzUG9wcGVyQ29uZmlnIiwiX3NlbGVjdE1lbnVJdGVtIiwiX3JlZjciLCJjbGVhck1lbnVzIiwib3BlblRvZ2dsZXMiLCJjb250ZXh0IiwiY29tcG9zZWRQYXRoIiwiaXNNZW51VGFyZ2V0IiwiZGF0YUFwaUtleWRvd25IYW5kbGVyIiwiaXNJbnB1dCIsImlzRXNjYXBlRXZlbnQiLCJpc1VwT3JEb3duRXZlbnQiLCJnZXRUb2dnbGVCdXR0b24iLCJzdG9wUHJvcGFnYXRpb24iLCJOQU1FJDkiLCJDTEFTU19OQU1FX0ZBREUkNCIsIkNMQVNTX05BTUVfU0hPVyQ1IiwiRVZFTlRfTU9VU0VET1dOIiwiRGVmYXVsdCQ4IiwiY2xhc3NOYW1lIiwiY2xpY2tDYWxsYmFjayIsInJvb3RFbGVtZW50IiwiRGVmYXVsdFR5cGUkOCIsIkJhY2tkcm9wIiwiX2lzQXBwZW5kZWQiLCJfYXBwZW5kIiwiX2dldEVsZW1lbnQiLCJfZW11bGF0ZUFuaW1hdGlvbiIsImJhY2tkcm9wIiwiY3JlYXRlRWxlbWVudCIsImFwcGVuZCIsIk5BTUUkOCIsIkRBVEFfS0VZJDUiLCJFVkVOVF9LRVkkNSIsIkVWRU5UX0ZPQ1VTSU4kMiIsIkVWRU5UX0tFWURPV05fVEFCIiwiVEFCX0tFWSIsIlRBQl9OQVZfRk9SV0FSRCIsIlRBQl9OQVZfQkFDS1dBUkQiLCJEZWZhdWx0JDciLCJhdXRvZm9jdXMiLCJ0cmFwRWxlbWVudCIsIkRlZmF1bHRUeXBlJDciLCJGb2N1c1RyYXAiLCJfaXNBY3RpdmUiLCJfbGFzdFRhYk5hdkRpcmVjdGlvbiIsImFjdGl2YXRlIiwiX2hhbmRsZUZvY3VzaW4iLCJfaGFuZGxlS2V5ZG93biIsImRlYWN0aXZhdGUiLCJzaGlmdEtleSIsIlNFTEVDVE9SX0ZJWEVEX0NPTlRFTlQiLCJTRUxFQ1RPUl9TVElDS1lfQ09OVEVOVCIsIlBST1BFUlRZX1BBRERJTkciLCJQUk9QRVJUWV9NQVJHSU4iLCJTY3JvbGxCYXJIZWxwZXIiLCJnZXRXaWR0aCIsImRvY3VtZW50V2lkdGgiLCJpbm5lcldpZHRoIiwiX2Rpc2FibGVPdmVyRmxvdyIsIl9zZXRFbGVtZW50QXR0cmlidXRlcyIsImNhbGN1bGF0ZWRWYWx1ZSIsIl9yZXNldEVsZW1lbnRBdHRyaWJ1dGVzIiwiaXNPdmVyZmxvd2luZyIsIl9zYXZlSW5pdGlhbEF0dHJpYnV0ZSIsInN0eWxlUHJvcGVydHkiLCJzY3JvbGxiYXJXaWR0aCIsIm1hbmlwdWxhdGlvbkNhbGxCYWNrIiwic2V0UHJvcGVydHkiLCJfYXBwbHlNYW5pcHVsYXRpb25DYWxsYmFjayIsImFjdHVhbFZhbHVlIiwicmVtb3ZlUHJvcGVydHkiLCJjYWxsQmFjayIsIk5BTUUkNyIsIkRBVEFfS0VZJDQiLCJFVkVOVF9LRVkkNCIsIkRBVEFfQVBJX0tFWSQyIiwiRVNDQVBFX0tFWSQxIiwiRVZFTlRfSElERSQ0IiwiRVZFTlRfSElERV9QUkVWRU5URUQkMSIsIkVWRU5UX0hJRERFTiQ0IiwiRVZFTlRfU0hPVyQ0IiwiRVZFTlRfU0hPV04kNCIsIkVWRU5UX1JFU0laRSQxIiwiRVZFTlRfQ0xJQ0tfRElTTUlTUyIsIkVWRU5UX01PVVNFRE9XTl9ESVNNSVNTIiwiRVZFTlRfS0VZRE9XTl9ESVNNSVNTJDEiLCJFVkVOVF9DTElDS19EQVRBX0FQSSQyIiwiQ0xBU1NfTkFNRV9PUEVOIiwiQ0xBU1NfTkFNRV9GQURFJDMiLCJDTEFTU19OQU1FX1NIT1ckNCIsIkNMQVNTX05BTUVfU1RBVElDIiwiT1BFTl9TRUxFQ1RPUiQxIiwiU0VMRUNUT1JfRElBTE9HIiwiU0VMRUNUT1JfTU9EQUxfQk9EWSIsIlNFTEVDVE9SX0RBVEFfVE9HR0xFJDIiLCJEZWZhdWx0JDYiLCJEZWZhdWx0VHlwZSQ2IiwiTW9kYWwiLCJfZGlhbG9nIiwiX2JhY2tkcm9wIiwiX2luaXRpYWxpemVCYWNrRHJvcCIsIl9mb2N1c3RyYXAiLCJfaW5pdGlhbGl6ZUZvY3VzVHJhcCIsIl9zY3JvbGxCYXIiLCJfYWRqdXN0RGlhbG9nIiwiX3Nob3dFbGVtZW50IiwiX2hpZGVNb2RhbCIsImhhbmRsZVVwZGF0ZSIsIm1vZGFsQm9keSIsInRyYW5zaXRpb25Db21wbGV0ZSIsIl90cmlnZ2VyQmFja2Ryb3BUcmFuc2l0aW9uIiwiZXZlbnQyIiwiX3Jlc2V0QWRqdXN0bWVudHMiLCJpc01vZGFsT3ZlcmZsb3dpbmciLCJpbml0aWFsT3ZlcmZsb3dZIiwiaXNCb2R5T3ZlcmZsb3dpbmciLCJwYWRkaW5nTGVmdCIsInBhZGRpbmdSaWdodCIsImFscmVhZHlPcGVuIiwiTkFNRSQ2IiwiREFUQV9LRVkkMyIsIkVWRU5UX0tFWSQzIiwiREFUQV9BUElfS0VZJDEiLCJFVkVOVF9MT0FEX0RBVEFfQVBJJDIiLCJFU0NBUEVfS0VZIiwiQ0xBU1NfTkFNRV9TSE9XJDMiLCJDTEFTU19OQU1FX1NIT1dJTkckMSIsIkNMQVNTX05BTUVfSElESU5HIiwiQ0xBU1NfTkFNRV9CQUNLRFJPUCIsIk9QRU5fU0VMRUNUT1IiLCJFVkVOVF9TSE9XJDMiLCJFVkVOVF9TSE9XTiQzIiwiRVZFTlRfSElERSQzIiwiRVZFTlRfSElERV9QUkVWRU5URUQiLCJFVkVOVF9ISURERU4kMyIsIkVWRU5UX1JFU0laRSIsIkVWRU5UX0NMSUNLX0RBVEFfQVBJJDEiLCJFVkVOVF9LRVlET1dOX0RJU01JU1MiLCJTRUxFQ1RPUl9EQVRBX1RPR0dMRSQxIiwiRGVmYXVsdCQ1IiwiRGVmYXVsdFR5cGUkNSIsIk9mZmNhbnZhcyIsImJsdXIiLCJjb21wbGV0ZUNhbGxiYWNrIiwiQVJJQV9BVFRSSUJVVEVfUEFUVEVSTiIsIkRlZmF1bHRBbGxvd2xpc3QiLCJhcmVhIiwiYnIiLCJjb2wiLCJjb2RlIiwiZGQiLCJkaXYiLCJkbCIsImR0IiwiZW0iLCJociIsImgxIiwiaDIiLCJoMyIsImg0IiwiaDUiLCJoNiIsImxpIiwib2wiLCJwIiwicHJlIiwicyIsInNtYWxsIiwic3BhbiIsInN1YiIsInN1cCIsInN0cm9uZyIsInUiLCJ1bCIsInVyaUF0dHJpYnV0ZXMiLCJTQUZFX1VSTF9QQVRURVJOIiwiYWxsb3dlZEF0dHJpYnV0ZSIsImFsbG93ZWRBdHRyaWJ1dGVMaXN0IiwiYXR0cmlidXRlTmFtZSIsIm5vZGVWYWx1ZSIsImF0dHJpYnV0ZVJlZ2V4IiwicmVnZXgiLCJzYW5pdGl6ZUh0bWwiLCJ1bnNhZmVIdG1sIiwiYWxsb3dMaXN0Iiwic2FuaXRpemVGdW5jdGlvbiIsImRvbVBhcnNlciIsIkRPTVBhcnNlciIsImNyZWF0ZWREb2N1bWVudCIsInBhcnNlRnJvbVN0cmluZyIsImVsZW1lbnROYW1lIiwiYXR0cmlidXRlTGlzdCIsImFsbG93ZWRBdHRyaWJ1dGVzIiwiaW5uZXJIVE1MIiwiTkFNRSQ1IiwiRGVmYXVsdCQ0IiwiY29udGVudCIsImV4dHJhQ2xhc3MiLCJzYW5pdGl6ZSIsInNhbml0aXplRm4iLCJ0ZW1wbGF0ZSIsIkRlZmF1bHRUeXBlJDQiLCJEZWZhdWx0Q29udGVudFR5cGUiLCJlbnRyeSIsIlRlbXBsYXRlRmFjdG9yeSIsImdldENvbnRlbnQiLCJfcmVzb2x2ZVBvc3NpYmxlRnVuY3Rpb24iLCJoYXNDb250ZW50IiwiY2hhbmdlQ29udGVudCIsIl9jaGVja0NvbnRlbnQiLCJ0b0h0bWwiLCJ0ZW1wbGF0ZVdyYXBwZXIiLCJfbWF5YmVTYW5pdGl6ZSIsInRleHQiLCJfc2V0Q29udGVudCIsImFyZyIsInRlbXBsYXRlRWxlbWVudCIsIl9wdXRFbGVtZW50SW5UZW1wbGF0ZSIsInRleHRDb250ZW50IiwiTkFNRSQ0IiwiRElTQUxMT1dFRF9BVFRSSUJVVEVTIiwiQ0xBU1NfTkFNRV9GQURFJDIiLCJDTEFTU19OQU1FX01PREFMIiwiQ0xBU1NfTkFNRV9TSE9XJDIiLCJTRUxFQ1RPUl9UT09MVElQX0lOTkVSIiwiU0VMRUNUT1JfTU9EQUwiLCJFVkVOVF9NT0RBTF9ISURFIiwiVFJJR0dFUl9IT1ZFUiIsIlRSSUdHRVJfRk9DVVMiLCJUUklHR0VSX0NMSUNLIiwiVFJJR0dFUl9NQU5VQUwiLCJFVkVOVF9ISURFJDIiLCJFVkVOVF9ISURERU4kMiIsIkVWRU5UX1NIT1ckMiIsIkVWRU5UX1NIT1dOJDIiLCJFVkVOVF9JTlNFUlRFRCIsIkVWRU5UX0NMSUNLJDEiLCJFVkVOVF9GT0NVU0lOJDEiLCJFVkVOVF9GT0NVU09VVCQxIiwiRVZFTlRfTU9VU0VFTlRFUiIsIkVWRU5UX01PVVNFTEVBVkUiLCJBdHRhY2htZW50TWFwIiwiQVVUTyIsIlRPUCIsIlJJR0hUIiwiQk9UVE9NIiwiTEVGVCIsIkRlZmF1bHQkMyIsImFuaW1hdGlvbiIsImNvbnRhaW5lciIsImN1c3RvbUNsYXNzIiwiZGVsYXkiLCJ0aXRsZSIsIkRlZmF1bHRUeXBlJDMiLCJUb29sdGlwIiwiX2lzRW5hYmxlZCIsIl90aW1lb3V0IiwiX2lzSG92ZXJlZCIsIl9hY3RpdmVUcmlnZ2VyIiwiX3RlbXBsYXRlRmFjdG9yeSIsIl9uZXdDb250ZW50IiwidGlwIiwiX3NldExpc3RlbmVycyIsIl9maXhUaXRsZSIsImVuYWJsZSIsImRpc2FibGUiLCJ0b2dnbGVFbmFibGVkIiwiY2xpY2siLCJfbGVhdmUiLCJfZW50ZXIiLCJfaGlkZU1vZGFsSGFuZGxlciIsIl9kaXNwb3NlUG9wcGVyIiwiX2lzV2l0aENvbnRlbnQiLCJzaGFkb3dSb290IiwiaXNJblRoZURvbSIsIl9nZXRUaXBFbGVtZW50IiwiX2lzV2l0aEFjdGl2ZVRyaWdnZXIiLCJfZ2V0VGl0bGUiLCJfY3JlYXRlVGlwRWxlbWVudCIsIl9nZXRDb250ZW50Rm9yVGVtcGxhdGUiLCJfZ2V0VGVtcGxhdGVGYWN0b3J5IiwidGlwSWQiLCJzZXRDb250ZW50IiwiX2luaXRpYWxpemVPbkRlbGVnYXRlZFRhcmdldCIsIl9nZXREZWxlZ2F0ZUNvbmZpZyIsImF0dGFjaG1lbnQiLCJ0cmlnZ2VycyIsImV2ZW50SW4iLCJldmVudE91dCIsIl9zZXRUaW1lb3V0IiwidGltZW91dCIsImRhdGFBdHRyaWJ1dGVzIiwiZGF0YUF0dHJpYnV0ZSIsIk5BTUUkMyIsIlNFTEVDVE9SX1RJVExFIiwiU0VMRUNUT1JfQ09OVEVOVCIsIkRlZmF1bHQkMiIsIkRlZmF1bHRUeXBlJDIiLCJQb3BvdmVyIiwiX2dldENvbnRlbnQiLCJOQU1FJDIiLCJEQVRBX0tFWSQyIiwiRVZFTlRfS0VZJDIiLCJEQVRBX0FQSV9LRVkiLCJFVkVOVF9BQ1RJVkFURSIsIkVWRU5UX0NMSUNLIiwiRVZFTlRfTE9BRF9EQVRBX0FQSSQxIiwiQ0xBU1NfTkFNRV9EUk9QRE9XTl9JVEVNIiwiQ0xBU1NfTkFNRV9BQ1RJVkUkMSIsIlNFTEVDVE9SX0RBVEFfU1BZIiwiU0VMRUNUT1JfVEFSR0VUX0xJTktTIiwiU0VMRUNUT1JfTkFWX0xJU1RfR1JPVVAiLCJTRUxFQ1RPUl9OQVZfTElOS1MiLCJTRUxFQ1RPUl9OQVZfSVRFTVMiLCJTRUxFQ1RPUl9MSVNUX0lURU1TIiwiU0VMRUNUT1JfTElOS19JVEVNUyIsIlNFTEVDVE9SX0RST1BET1dOIiwiU0VMRUNUT1JfRFJPUERPV05fVE9HR0xFJDEiLCJEZWZhdWx0JDEiLCJyb290TWFyZ2luIiwic21vb3RoU2Nyb2xsIiwidGhyZXNob2xkIiwiRGVmYXVsdFR5cGUkMSIsIlNjcm9sbFNweSIsIl90YXJnZXRMaW5rcyIsIl9vYnNlcnZhYmxlU2VjdGlvbnMiLCJfcm9vdEVsZW1lbnQiLCJfYWN0aXZlVGFyZ2V0IiwiX29ic2VydmVyIiwiX3ByZXZpb3VzU2Nyb2xsRGF0YSIsInZpc2libGVFbnRyeVRvcCIsInBhcmVudFNjcm9sbFRvcCIsInJlZnJlc2giLCJfaW5pdGlhbGl6ZVRhcmdldHNBbmRPYnNlcnZhYmxlcyIsIl9tYXliZUVuYWJsZVNtb290aFNjcm9sbCIsImRpc2Nvbm5lY3QiLCJfZ2V0TmV3T2JzZXJ2ZXIiLCJzZWN0aW9uIiwib2JzZXJ2ZSIsIm9ic2VydmFibGVTZWN0aW9uIiwic2Nyb2xsVG8iLCJiZWhhdmlvciIsIkludGVyc2VjdGlvbk9ic2VydmVyIiwiX29ic2VydmVyQ2FsbGJhY2siLCJ0YXJnZXRFbGVtZW50IiwiX3Byb2Nlc3MiLCJ1c2VyU2Nyb2xsc0Rvd24iLCJpc0ludGVyc2VjdGluZyIsIl9jbGVhckFjdGl2ZUNsYXNzIiwiZW50cnlJc0xvd2VyVGhhblByZXZpb3VzIiwidGFyZ2V0TGlua3MiLCJhbmNob3IiLCJkZWNvZGVVUkkiLCJfYWN0aXZhdGVQYXJlbnRzIiwibGlzdEdyb3VwIiwiYWN0aXZlTm9kZXMiLCJzcHkiLCJOQU1FJDEiLCJEQVRBX0tFWSQxIiwiRVZFTlRfS0VZJDEiLCJFVkVOVF9ISURFJDEiLCJFVkVOVF9ISURERU4kMSIsIkVWRU5UX1NIT1ckMSIsIkVWRU5UX1NIT1dOJDEiLCJFVkVOVF9DTElDS19EQVRBX0FQSSIsIkVWRU5UX0tFWURPV04iLCJFVkVOVF9MT0FEX0RBVEFfQVBJIiwiQVJST1dfTEVGVF9LRVkiLCJBUlJPV19SSUdIVF9LRVkiLCJBUlJPV19VUF9LRVkiLCJBUlJPV19ET1dOX0tFWSIsIkhPTUVfS0VZIiwiRU5EX0tFWSIsIkNMQVNTX05BTUVfQUNUSVZFIiwiQ0xBU1NfTkFNRV9GQURFJDEiLCJDTEFTU19OQU1FX1NIT1ckMSIsIkNMQVNTX0RST1BET1dOIiwiU0VMRUNUT1JfRFJPUERPV05fVE9HR0xFIiwiU0VMRUNUT1JfRFJPUERPV05fTUVOVSIsIk5PVF9TRUxFQ1RPUl9EUk9QRE9XTl9UT0dHTEUiLCJTRUxFQ1RPUl9UQUJfUEFORUwiLCJTRUxFQ1RPUl9PVVRFUiIsIlNFTEVDVE9SX0lOTkVSIiwiU0VMRUNUT1JfREFUQV9UT0dHTEUiLCJTRUxFQ1RPUl9JTk5FUl9FTEVNIiwiU0VMRUNUT1JfREFUQV9UT0dHTEVfQUNUSVZFIiwiVGFiIiwiX3NldEluaXRpYWxBdHRyaWJ1dGVzIiwiX2dldENoaWxkcmVuIiwiaW5uZXJFbGVtIiwiX2VsZW1Jc0FjdGl2ZSIsImFjdGl2ZSIsIl9nZXRBY3RpdmVFbGVtIiwiX2RlYWN0aXZhdGUiLCJfYWN0aXZhdGUiLCJyZWxhdGVkRWxlbSIsIl90b2dnbGVEcm9wRG93biIsIm5leHRBY3RpdmVFbGVtZW50IiwicHJldmVudFNjcm9sbCIsIl9zZXRBdHRyaWJ1dGVJZk5vdEV4aXN0cyIsIl9zZXRJbml0aWFsQXR0cmlidXRlc09uQ2hpbGQiLCJfZ2V0SW5uZXJFbGVtZW50IiwiaXNBY3RpdmUiLCJvdXRlckVsZW0iLCJfZ2V0T3V0ZXJFbGVtZW50IiwiX3NldEluaXRpYWxBdHRyaWJ1dGVzT25UYXJnZXRQYW5lbCIsIm9wZW4iLCJFVkVOVF9NT1VTRU9WRVIiLCJFVkVOVF9NT1VTRU9VVCIsIkVWRU5UX0ZPQ1VTSU4iLCJFVkVOVF9GT0NVU09VVCIsIkVWRU5UX0hJREUiLCJFVkVOVF9ISURERU4iLCJFVkVOVF9TSE9XIiwiRVZFTlRfU0hPV04iLCJDTEFTU19OQU1FX0ZBREUiLCJDTEFTU19OQU1FX0hJREUiLCJDTEFTU19OQU1FX1NIT1ciLCJDTEFTU19OQU1FX1NIT1dJTkciLCJhdXRvaGlkZSIsIlRvYXN0IiwiX2hhc01vdXNlSW50ZXJhY3Rpb24iLCJfaGFzS2V5Ym9hcmRJbnRlcmFjdGlvbiIsIl9jbGVhclRpbWVvdXQiLCJfbWF5YmVTY2hlZHVsZUhpZGUiLCJpc1Nob3duIiwiX29uSW50ZXJhY3Rpb24iLCJpc0ludGVyYWN0aW5nIiwiaW5kZXhfdW1kIl0sIm1hcHBpbmdzIjoiO0FBQUE7QUFDQTs7OztBQ0RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7Ozs7Ozs7Ozs7O0VDMXBFQTs7Ozs7OztFQU9BOzs7RUFJQSxNQUFNQSxVQUFVLEdBQUcsSUFBSUMsR0FBRyxFQUFFO0VBRTVCLE1BQUFDLElBQUEsR0FBZTtJQUNiQyxHQUFHQSxDQUFDQyxPQUFPLEVBQUVDLEdBQUcsRUFBRUMsUUFBUSxFQUFFO01BQzFCLElBQUksQ0FBQ04sVUFBVSxDQUFDTyxHQUFHLENBQUNILE9BQU8sQ0FBQyxFQUFFO1FBQzVCSixVQUFVLENBQUNHLEdBQUcsQ0FBQ0MsT0FBTyxFQUFFLElBQUlILEdBQUcsRUFBRSxDQUFDO01BQ3BDO01BRUEsTUFBTU8sV0FBVyxHQUFHUixVQUFVLENBQUNTLEdBQUcsQ0FBQ0wsT0FBTyxDQUFDOztNQUUzQztNQUNBO01BQ0EsSUFBSSxDQUFDSSxXQUFXLENBQUNELEdBQUcsQ0FBQ0YsR0FBRyxDQUFDLElBQUlHLFdBQVcsQ0FBQ0UsSUFBSSxLQUFLLENBQUMsRUFBRTtRQUNuRDtRQUNBQyxPQUFPLENBQUNDLEtBQUssQ0FBRSwrRUFBOEVDLEtBQUssQ0FBQ0MsSUFBSSxDQUFDTixXQUFXLENBQUNPLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFFLEdBQUUsQ0FBQztRQUNsSTtNQUNGO01BRUFQLFdBQVcsQ0FBQ0wsR0FBRyxDQUFDRSxHQUFHLEVBQUVDLFFBQVEsQ0FBQztLQUMvQjtJQUVERyxHQUFHQSxDQUFDTCxPQUFPLEVBQUVDLEdBQUcsRUFBRTtNQUNoQixJQUFJTCxVQUFVLENBQUNPLEdBQUcsQ0FBQ0gsT0FBTyxDQUFDLEVBQUU7UUFDM0IsT0FBT0osVUFBVSxDQUFDUyxHQUFHLENBQUNMLE9BQU8sQ0FBQyxDQUFDSyxHQUFHLENBQUNKLEdBQUcsQ0FBQyxJQUFJLElBQUk7TUFDakQ7TUFFQSxPQUFPLElBQUk7S0FDWjtJQUVEVyxNQUFNQSxDQUFDWixPQUFPLEVBQUVDLEdBQUcsRUFBRTtNQUNuQixJQUFJLENBQUNMLFVBQVUsQ0FBQ08sR0FBRyxDQUFDSCxPQUFPLENBQUMsRUFBRTtRQUM1QjtNQUNGO01BRUEsTUFBTUksV0FBVyxHQUFHUixVQUFVLENBQUNTLEdBQUcsQ0FBQ0wsT0FBTyxDQUFDO01BRTNDSSxXQUFXLENBQUNTLE1BQU0sQ0FBQ1osR0FBRyxDQUFDOztNQUV2QjtNQUNBLElBQUlHLFdBQVcsQ0FBQ0UsSUFBSSxLQUFLLENBQUMsRUFBRTtRQUMxQlYsVUFBVSxDQUFDaUIsTUFBTSxDQUFDYixPQUFPLENBQUM7TUFDNUI7SUFDRjtFQUNGLENBQUM7O0VDdEREOzs7Ozs7O0VBT0EsTUFBTWMsT0FBTyxHQUFHLE9BQVM7RUFDekIsTUFBTUMsdUJBQXVCLEdBQUcsSUFBSTtFQUNwQyxNQUFNQyxjQUFjLEdBQUcsZUFBZTs7RUFFdEM7Ozs7O0VBS0EsTUFBTUMsYUFBYSxHQUFHQyxRQUFRLElBQUk7SUFDaEMsSUFBSUEsUUFBUSxJQUFJQyxNQUFNLENBQUNDLEdBQUcsSUFBSUQsTUFBTSxDQUFDQyxHQUFHLENBQUNDLE1BQU0sRUFBRTtNQUMvQztNQUNBSCxRQUFRLEdBQUdBLFFBQVEsQ0FBQ0ksT0FBTyxDQUFDLGVBQWUsRUFBRSxDQUFDQyxLQUFLLEVBQUVDLEVBQUUsS0FBTSxJQUFHSixHQUFHLENBQUNDLE1BQU0sQ0FBQ0csRUFBRSxDQUFFLEVBQUMsQ0FBQztJQUNuRjtJQUVBLE9BQU9OLFFBQVE7RUFDakIsQ0FBQzs7RUFFRDtFQUNBLE1BQU1PLE1BQU0sR0FBR0MsTUFBTSxJQUFJO0lBQ3ZCLElBQUlBLE1BQU0sS0FBSyxJQUFJLElBQUlBLE1BQU0sS0FBS0MsU0FBUyxFQUFFO01BQzNDLE9BQVEsR0FBRUQsTUFBTyxFQUFDO0lBQ3BCO0lBRUEsT0FBT0UsTUFBTSxDQUFDQyxTQUFTLENBQUNDLFFBQVEsQ0FBQ0MsSUFBSSxDQUFDTCxNQUFNLENBQUMsQ0FBQ0gsS0FBSyxDQUFDLGFBQWEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDUyxXQUFXLEVBQUU7RUFDckYsQ0FBQzs7RUFFRDs7OztFQUlBLE1BQU1DLE1BQU0sR0FBR0MsTUFBTSxJQUFJO0lBQ3ZCLEdBQUc7TUFDREEsTUFBTSxJQUFJQyxJQUFJLENBQUNDLEtBQUssQ0FBQ0QsSUFBSSxDQUFDRSxNQUFNLEVBQUUsR0FBR3ZCLE9BQU8sQ0FBQztJQUMvQyxDQUFDLFFBQVF3QixRQUFRLENBQUNDLGNBQWMsQ0FBQ0wsTUFBTSxDQUFDO0lBRXhDLE9BQU9BLE1BQU07RUFDZixDQUFDO0VBRUQsTUFBTU0sZ0NBQWdDLEdBQUd4QyxPQUFPLElBQUk7SUFDbEQsSUFBSSxDQUFDQSxPQUFPLEVBQUU7TUFDWixPQUFPLENBQUM7SUFDVjs7SUFFQTtJQUNBLElBQUk7TUFBRXlDLGtCQUFrQjtNQUFFQztJQUFnQixDQUFDLEdBQUd2QixNQUFNLENBQUN3QixnQkFBZ0IsQ0FBQzNDLE9BQU8sQ0FBQztJQUU5RSxNQUFNNEMsdUJBQXVCLEdBQUdDLE1BQU0sQ0FBQ0MsVUFBVSxDQUFDTCxrQkFBa0IsQ0FBQztJQUNyRSxNQUFNTSxvQkFBb0IsR0FBR0YsTUFBTSxDQUFDQyxVQUFVLENBQUNKLGVBQWUsQ0FBQzs7SUFFL0Q7SUFDQSxJQUFJLENBQUNFLHVCQUF1QixJQUFJLENBQUNHLG9CQUFvQixFQUFFO01BQ3JELE9BQU8sQ0FBQztJQUNWOztJQUVBO0lBQ0FOLGtCQUFrQixHQUFHQSxrQkFBa0IsQ0FBQ08sS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUNyRE4sZUFBZSxHQUFHQSxlQUFlLENBQUNNLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFFL0MsT0FBTyxDQUFDSCxNQUFNLENBQUNDLFVBQVUsQ0FBQ0wsa0JBQWtCLENBQUMsR0FBR0ksTUFBTSxDQUFDQyxVQUFVLENBQUNKLGVBQWUsQ0FBQyxJQUFJM0IsdUJBQXVCO0VBQy9HLENBQUM7RUFFRCxNQUFNa0Msb0JBQW9CLEdBQUdqRCxPQUFPLElBQUk7SUFDdENBLE9BQU8sQ0FBQ2tELGFBQWEsQ0FBQyxJQUFJQyxLQUFLLENBQUNuQyxjQUFjLENBQUMsQ0FBQztFQUNsRCxDQUFDO0VBRUQsTUFBTW9DLFdBQVMsR0FBRzFCLE1BQU0sSUFBSTtJQUMxQixJQUFJLENBQUNBLE1BQU0sSUFBSSxPQUFPQSxNQUFNLEtBQUssUUFBUSxFQUFFO01BQ3pDLE9BQU8sS0FBSztJQUNkO0lBRUEsSUFBSSxPQUFPQSxNQUFNLENBQUMyQixNQUFNLEtBQUssV0FBVyxFQUFFO01BQ3hDM0IsTUFBTSxHQUFHQSxNQUFNLENBQUMsQ0FBQyxDQUFDO0lBQ3BCO0lBRUEsT0FBTyxPQUFPQSxNQUFNLENBQUM0QixRQUFRLEtBQUssV0FBVztFQUMvQyxDQUFDO0VBRUQsTUFBTUMsVUFBVSxHQUFHN0IsTUFBTSxJQUFJO0lBQzNCO0lBQ0EsSUFBSTBCLFdBQVMsQ0FBQzFCLE1BQU0sQ0FBQyxFQUFFO01BQ3JCLE9BQU9BLE1BQU0sQ0FBQzJCLE1BQU0sR0FBRzNCLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBR0EsTUFBTTtJQUMzQztJQUVBLElBQUksT0FBT0EsTUFBTSxLQUFLLFFBQVEsSUFBSUEsTUFBTSxDQUFDOEIsTUFBTSxHQUFHLENBQUMsRUFBRTtNQUNuRCxPQUFPbEIsUUFBUSxDQUFDbUIsYUFBYSxDQUFDeEMsYUFBYSxDQUFDUyxNQUFNLENBQUMsQ0FBQztJQUN0RDtJQUVBLE9BQU8sSUFBSTtFQUNiLENBQUM7RUFFRCxNQUFNZ0MsU0FBUyxHQUFHMUQsT0FBTyxJQUFJO0lBQzNCLElBQUksQ0FBQ29ELFdBQVMsQ0FBQ3BELE9BQU8sQ0FBQyxJQUFJQSxPQUFPLENBQUMyRCxjQUFjLEVBQUUsQ0FBQ0gsTUFBTSxLQUFLLENBQUMsRUFBRTtNQUNoRSxPQUFPLEtBQUs7SUFDZDtJQUVBLE1BQU1JLGdCQUFnQixHQUFHakIsZ0JBQWdCLENBQUMzQyxPQUFPLENBQUMsQ0FBQzZELGdCQUFnQixDQUFDLFlBQVksQ0FBQyxLQUFLLFNBQVM7SUFDL0Y7SUFDQSxNQUFNQyxhQUFhLEdBQUc5RCxPQUFPLENBQUMrRCxPQUFPLENBQUMscUJBQXFCLENBQUM7SUFFNUQsSUFBSSxDQUFDRCxhQUFhLEVBQUU7TUFDbEIsT0FBT0YsZ0JBQWdCO0lBQ3pCO0lBRUEsSUFBSUUsYUFBYSxLQUFLOUQsT0FBTyxFQUFFO01BQzdCLE1BQU1nRSxPQUFPLEdBQUdoRSxPQUFPLENBQUMrRCxPQUFPLENBQUMsU0FBUyxDQUFDO01BQzFDLElBQUlDLE9BQU8sSUFBSUEsT0FBTyxDQUFDQyxVQUFVLEtBQUtILGFBQWEsRUFBRTtRQUNuRCxPQUFPLEtBQUs7TUFDZDtNQUVBLElBQUlFLE9BQU8sS0FBSyxJQUFJLEVBQUU7UUFDcEIsT0FBTyxLQUFLO01BQ2Q7SUFDRjtJQUVBLE9BQU9KLGdCQUFnQjtFQUN6QixDQUFDO0VBRUQsTUFBTU0sVUFBVSxHQUFHbEUsT0FBTyxJQUFJO0lBQzVCLElBQUksQ0FBQ0EsT0FBTyxJQUFJQSxPQUFPLENBQUNzRCxRQUFRLEtBQUthLElBQUksQ0FBQ0MsWUFBWSxFQUFFO01BQ3RELE9BQU8sSUFBSTtJQUNiO0lBRUEsSUFBSXBFLE9BQU8sQ0FBQ3FFLFNBQVMsQ0FBQ0MsUUFBUSxDQUFDLFVBQVUsQ0FBQyxFQUFFO01BQzFDLE9BQU8sSUFBSTtJQUNiO0lBRUEsSUFBSSxPQUFPdEUsT0FBTyxDQUFDdUUsUUFBUSxLQUFLLFdBQVcsRUFBRTtNQUMzQyxPQUFPdkUsT0FBTyxDQUFDdUUsUUFBUTtJQUN6QjtJQUVBLE9BQU92RSxPQUFPLENBQUN3RSxZQUFZLENBQUMsVUFBVSxDQUFDLElBQUl4RSxPQUFPLENBQUN5RSxZQUFZLENBQUMsVUFBVSxDQUFDLEtBQUssT0FBTztFQUN6RixDQUFDO0VBRUQsTUFBTUMsY0FBYyxHQUFHMUUsT0FBTyxJQUFJO0lBQ2hDLElBQUksQ0FBQ3NDLFFBQVEsQ0FBQ3FDLGVBQWUsQ0FBQ0MsWUFBWSxFQUFFO01BQzFDLE9BQU8sSUFBSTtJQUNiOztJQUVBO0lBQ0EsSUFBSSxPQUFPNUUsT0FBTyxDQUFDNkUsV0FBVyxLQUFLLFVBQVUsRUFBRTtNQUM3QyxNQUFNQyxJQUFJLEdBQUc5RSxPQUFPLENBQUM2RSxXQUFXLEVBQUU7TUFDbEMsT0FBT0MsSUFBSSxZQUFZQyxVQUFVLEdBQUdELElBQUksR0FBRyxJQUFJO0lBQ2pEO0lBRUEsSUFBSTlFLE9BQU8sWUFBWStFLFVBQVUsRUFBRTtNQUNqQyxPQUFPL0UsT0FBTztJQUNoQjs7SUFFQTtJQUNBLElBQUksQ0FBQ0EsT0FBTyxDQUFDaUUsVUFBVSxFQUFFO01BQ3ZCLE9BQU8sSUFBSTtJQUNiO0lBRUEsT0FBT1MsY0FBYyxDQUFDMUUsT0FBTyxDQUFDaUUsVUFBVSxDQUFDO0VBQzNDLENBQUM7RUFFRCxNQUFNZSxJQUFJLEdBQUdBLENBQUEsS0FBTSxFQUFFOztFQUVyQjs7Ozs7Ozs7RUFRQSxNQUFNQyxNQUFNLEdBQUdqRixPQUFPLElBQUk7SUFDeEJBLE9BQU8sQ0FBQ2tGLFlBQVksQ0FBQztFQUN2QixDQUFDO0VBRUQsTUFBTUMsU0FBUyxHQUFHQSxDQUFBLEtBQU07SUFDdEIsSUFBSWhFLE1BQU0sQ0FBQ2lFLE1BQU0sSUFBSSxDQUFDOUMsUUFBUSxDQUFDK0MsSUFBSSxDQUFDYixZQUFZLENBQUMsbUJBQW1CLENBQUMsRUFBRTtNQUNyRSxPQUFPckQsTUFBTSxDQUFDaUUsTUFBTTtJQUN0QjtJQUVBLE9BQU8sSUFBSTtFQUNiLENBQUM7RUFFRCxNQUFNRSx5QkFBeUIsR0FBRyxFQUFFO0VBRXBDLE1BQU1DLGtCQUFrQixHQUFHQyxRQUFRLElBQUk7SUFDckMsSUFBSWxELFFBQVEsQ0FBQ21ELFVBQVUsS0FBSyxTQUFTLEVBQUU7TUFDckM7TUFDQSxJQUFJLENBQUNILHlCQUF5QixDQUFDOUIsTUFBTSxFQUFFO1FBQ3JDbEIsUUFBUSxDQUFDb0QsZ0JBQWdCLENBQUMsa0JBQWtCLEVBQUUsTUFBTTtVQUNsRCxLQUFLLE1BQU1GLFFBQVEsSUFBSUYseUJBQXlCLEVBQUU7WUFDaERFLFFBQVEsRUFBRTtVQUNaO1FBQ0YsQ0FBQyxDQUFDO01BQ0o7TUFFQUYseUJBQXlCLENBQUNLLElBQUksQ0FBQ0gsUUFBUSxDQUFDO0lBQzFDLENBQUMsTUFBTTtNQUNMQSxRQUFRLEVBQUU7SUFDWjtFQUNGLENBQUM7RUFFRCxNQUFNSSxLQUFLLEdBQUdBLENBQUEsS0FBTXRELFFBQVEsQ0FBQ3FDLGVBQWUsQ0FBQ2tCLEdBQUcsS0FBSyxLQUFLO0VBRTFELE1BQU1DLGtCQUFrQixHQUFHQyxNQUFNLElBQUk7SUFDbkNSLGtCQUFrQixDQUFDLE1BQU07TUFDdkIsTUFBTVMsQ0FBQyxHQUFHYixTQUFTLEVBQUU7TUFDckI7TUFDQSxJQUFJYSxDQUFDLEVBQUU7UUFDTCxNQUFNQyxJQUFJLEdBQUdGLE1BQU0sQ0FBQ0csSUFBSTtRQUN4QixNQUFNQyxrQkFBa0IsR0FBR0gsQ0FBQyxDQUFDSSxFQUFFLENBQUNILElBQUksQ0FBQztRQUNyQ0QsQ0FBQyxDQUFDSSxFQUFFLENBQUNILElBQUksQ0FBQyxHQUFHRixNQUFNLENBQUNNLGVBQWU7UUFDbkNMLENBQUMsQ0FBQ0ksRUFBRSxDQUFDSCxJQUFJLENBQUMsQ0FBQ0ssV0FBVyxHQUFHUCxNQUFNO1FBQy9CQyxDQUFDLENBQUNJLEVBQUUsQ0FBQ0gsSUFBSSxDQUFDLENBQUNNLFVBQVUsR0FBRyxNQUFNO1VBQzVCUCxDQUFDLENBQUNJLEVBQUUsQ0FBQ0gsSUFBSSxDQUFDLEdBQUdFLGtCQUFrQjtVQUMvQixPQUFPSixNQUFNLENBQUNNLGVBQWU7U0FDOUI7TUFDSDtJQUNGLENBQUMsQ0FBQztFQUNKLENBQUM7RUFFRCxNQUFNRyxPQUFPLEdBQUcsU0FBQUEsQ0FBQ0MsZ0JBQWdCLEVBQWlEO0lBQUEsSUFBL0NDLElBQUksR0FBQUMsU0FBQSxDQUFBbkQsTUFBQSxRQUFBbUQsU0FBQSxRQUFBaEYsU0FBQSxHQUFBZ0YsU0FBQSxNQUFHLEVBQUU7SUFBQSxJQUFFQyxZQUFZLEdBQUFELFNBQUEsQ0FBQW5ELE1BQUEsUUFBQW1ELFNBQUEsUUFBQWhGLFNBQUEsR0FBQWdGLFNBQUEsTUFBR0YsZ0JBQWdCO0lBQzNFLE9BQU8sT0FBT0EsZ0JBQWdCLEtBQUssVUFBVSxHQUFHQSxnQkFBZ0IsQ0FBQyxHQUFHQyxJQUFJLENBQUMsR0FBR0UsWUFBWTtFQUMxRixDQUFDO0VBRUQsTUFBTUMsc0JBQXNCLEdBQUcsU0FBQUEsQ0FBQ3JCLFFBQVEsRUFBRXNCLGlCQUFpQixFQUErQjtJQUFBLElBQTdCQyxpQkFBaUIsR0FBQUosU0FBQSxDQUFBbkQsTUFBQSxRQUFBbUQsU0FBQSxRQUFBaEYsU0FBQSxHQUFBZ0YsU0FBQSxNQUFHLElBQUk7SUFDbkYsSUFBSSxDQUFDSSxpQkFBaUIsRUFBRTtNQUN0QlAsT0FBTyxDQUFDaEIsUUFBUSxDQUFDO01BQ2pCO0lBQ0Y7SUFFQSxNQUFNd0IsZUFBZSxHQUFHLENBQUM7SUFDekIsTUFBTUMsZ0JBQWdCLEdBQUd6RSxnQ0FBZ0MsQ0FBQ3NFLGlCQUFpQixDQUFDLEdBQUdFLGVBQWU7SUFFOUYsSUFBSUUsTUFBTSxHQUFHLEtBQUs7SUFFbEIsTUFBTUMsT0FBTyxHQUFHQyxLQUFBLElBQWdCO01BQUEsSUFBZjtRQUFFQztNQUFPLENBQUMsR0FBQUQsS0FBQTtNQUN6QixJQUFJQyxNQUFNLEtBQUtQLGlCQUFpQixFQUFFO1FBQ2hDO01BQ0Y7TUFFQUksTUFBTSxHQUFHLElBQUk7TUFDYkosaUJBQWlCLENBQUNRLG1CQUFtQixDQUFDdEcsY0FBYyxFQUFFbUcsT0FBTyxDQUFDO01BQzlEWCxPQUFPLENBQUNoQixRQUFRLENBQUM7S0FDbEI7SUFFRHNCLGlCQUFpQixDQUFDcEIsZ0JBQWdCLENBQUMxRSxjQUFjLEVBQUVtRyxPQUFPLENBQUM7SUFDM0RJLFVBQVUsQ0FBQyxNQUFNO01BQ2YsSUFBSSxDQUFDTCxNQUFNLEVBQUU7UUFDWGpFLG9CQUFvQixDQUFDNkQsaUJBQWlCLENBQUM7TUFDekM7S0FDRCxFQUFFRyxnQkFBZ0IsQ0FBQztFQUN0QixDQUFDOztFQUVEOzs7Ozs7Ozs7RUFTQSxNQUFNTyxvQkFBb0IsR0FBR0EsQ0FBQ0MsSUFBSSxFQUFFQyxhQUFhLEVBQUVDLGFBQWEsRUFBRUMsY0FBYyxLQUFLO0lBQ25GLE1BQU1DLFVBQVUsR0FBR0osSUFBSSxDQUFDakUsTUFBTTtJQUM5QixJQUFJc0UsS0FBSyxHQUFHTCxJQUFJLENBQUNNLE9BQU8sQ0FBQ0wsYUFBYSxDQUFDOztJQUV2QztJQUNBO0lBQ0EsSUFBSUksS0FBSyxLQUFLLENBQUMsQ0FBQyxFQUFFO01BQ2hCLE9BQU8sQ0FBQ0gsYUFBYSxJQUFJQyxjQUFjLEdBQUdILElBQUksQ0FBQ0ksVUFBVSxHQUFHLENBQUMsQ0FBQyxHQUFHSixJQUFJLENBQUMsQ0FBQyxDQUFDO0lBQzFFO0lBRUFLLEtBQUssSUFBSUgsYUFBYSxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7SUFFL0IsSUFBSUMsY0FBYyxFQUFFO01BQ2xCRSxLQUFLLEdBQUcsQ0FBQ0EsS0FBSyxHQUFHRCxVQUFVLElBQUlBLFVBQVU7SUFDM0M7SUFFQSxPQUFPSixJQUFJLENBQUN0RixJQUFJLENBQUM2RixHQUFHLENBQUMsQ0FBQyxFQUFFN0YsSUFBSSxDQUFDOEYsR0FBRyxDQUFDSCxLQUFLLEVBQUVELFVBQVUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0VBQzNELENBQUM7O0VDM1JEOzs7Ozs7O0VBU0E7Ozs7RUFJQSxNQUFNSyxjQUFjLEdBQUcsb0JBQW9CO0VBQzNDLE1BQU1DLGNBQWMsR0FBRyxNQUFNO0VBQzdCLE1BQU1DLGFBQWEsR0FBRyxRQUFRO0VBQzlCLE1BQU1DLGFBQWEsR0FBRyxFQUFFLENBQUM7RUFDekIsSUFBSUMsUUFBUSxHQUFHLENBQUM7RUFDaEIsTUFBTUMsWUFBWSxHQUFHO0lBQ25CQyxVQUFVLEVBQUUsV0FBVztJQUN2QkMsVUFBVSxFQUFFO0VBQ2QsQ0FBQztFQUVELE1BQU1DLFlBQVksR0FBRyxJQUFJQyxHQUFHLENBQUMsQ0FDM0IsT0FBTyxFQUNQLFVBQVUsRUFDVixTQUFTLEVBQ1QsV0FBVyxFQUNYLGFBQWEsRUFDYixZQUFZLEVBQ1osZ0JBQWdCLEVBQ2hCLFdBQVcsRUFDWCxVQUFVLEVBQ1YsV0FBVyxFQUNYLGFBQWEsRUFDYixXQUFXLEVBQ1gsU0FBUyxFQUNULFVBQVUsRUFDVixPQUFPLEVBQ1AsbUJBQW1CLEVBQ25CLFlBQVksRUFDWixXQUFXLEVBQ1gsVUFBVSxFQUNWLGFBQWEsRUFDYixhQUFhLEVBQ2IsYUFBYSxFQUNiLFdBQVcsRUFDWCxjQUFjLEVBQ2QsZUFBZSxFQUNmLGNBQWMsRUFDZCxlQUFlLEVBQ2YsWUFBWSxFQUNaLE9BQU8sRUFDUCxNQUFNLEVBQ04sUUFBUSxFQUNSLE9BQU8sRUFDUCxRQUFRLEVBQ1IsUUFBUSxFQUNSLFNBQVMsRUFDVCxVQUFVLEVBQ1YsTUFBTSxFQUNOLFFBQVEsRUFDUixjQUFjLEVBQ2QsUUFBUSxFQUNSLE1BQU0sRUFDTixrQkFBa0IsRUFDbEIsa0JBQWtCLEVBQ2xCLE9BQU8sRUFDUCxPQUFPLEVBQ1AsUUFBUSxDQUNULENBQUM7O0VBRUY7Ozs7RUFJQSxTQUFTQyxZQUFZQSxDQUFDNUksT0FBTyxFQUFFNkksR0FBRyxFQUFFO0lBQ2xDLE9BQVFBLEdBQUcsSUFBSyxHQUFFQSxHQUFJLEtBQUlQLFFBQVEsRUFBRyxFQUFDLElBQUt0SSxPQUFPLENBQUNzSSxRQUFRLElBQUlBLFFBQVEsRUFBRTtFQUMzRTtFQUVBLFNBQVNRLGdCQUFnQkEsQ0FBQzlJLE9BQU8sRUFBRTtJQUNqQyxNQUFNNkksR0FBRyxHQUFHRCxZQUFZLENBQUM1SSxPQUFPLENBQUM7SUFFakNBLE9BQU8sQ0FBQ3NJLFFBQVEsR0FBR08sR0FBRztJQUN0QlIsYUFBYSxDQUFDUSxHQUFHLENBQUMsR0FBR1IsYUFBYSxDQUFDUSxHQUFHLENBQUMsSUFBSSxFQUFFO0lBRTdDLE9BQU9SLGFBQWEsQ0FBQ1EsR0FBRyxDQUFDO0VBQzNCO0VBRUEsU0FBU0UsZ0JBQWdCQSxDQUFDL0ksT0FBTyxFQUFFb0csRUFBRSxFQUFFO0lBQ3JDLE9BQU8sU0FBU2UsT0FBT0EsQ0FBQzZCLEtBQUssRUFBRTtNQUM3QkMsVUFBVSxDQUFDRCxLQUFLLEVBQUU7UUFBRUUsY0FBYyxFQUFFbEo7TUFBUSxDQUFDLENBQUM7TUFFOUMsSUFBSW1ILE9BQU8sQ0FBQ2dDLE1BQU0sRUFBRTtRQUNsQkMsWUFBWSxDQUFDQyxHQUFHLENBQUNySixPQUFPLEVBQUVnSixLQUFLLENBQUNNLElBQUksRUFBRWxELEVBQUUsQ0FBQztNQUMzQztNQUVBLE9BQU9BLEVBQUUsQ0FBQ21ELEtBQUssQ0FBQ3ZKLE9BQU8sRUFBRSxDQUFDZ0osS0FBSyxDQUFDLENBQUM7S0FDbEM7RUFDSDtFQUVBLFNBQVNRLDBCQUEwQkEsQ0FBQ3hKLE9BQU8sRUFBRWtCLFFBQVEsRUFBRWtGLEVBQUUsRUFBRTtJQUN6RCxPQUFPLFNBQVNlLE9BQU9BLENBQUM2QixLQUFLLEVBQUU7TUFDN0IsTUFBTVMsV0FBVyxHQUFHekosT0FBTyxDQUFDMEosZ0JBQWdCLENBQUN4SSxRQUFRLENBQUM7TUFFdEQsS0FBSyxJQUFJO1FBQUVtRztNQUFPLENBQUMsR0FBRzJCLEtBQUssRUFBRTNCLE1BQU0sSUFBSUEsTUFBTSxLQUFLLElBQUksRUFBRUEsTUFBTSxHQUFHQSxNQUFNLENBQUNwRCxVQUFVLEVBQUU7UUFDbEYsS0FBSyxNQUFNMEYsVUFBVSxJQUFJRixXQUFXLEVBQUU7VUFDcEMsSUFBSUUsVUFBVSxLQUFLdEMsTUFBTSxFQUFFO1lBQ3pCO1VBQ0Y7VUFFQTRCLFVBQVUsQ0FBQ0QsS0FBSyxFQUFFO1lBQUVFLGNBQWMsRUFBRTdCO1VBQU8sQ0FBQyxDQUFDO1VBRTdDLElBQUlGLE9BQU8sQ0FBQ2dDLE1BQU0sRUFBRTtZQUNsQkMsWUFBWSxDQUFDQyxHQUFHLENBQUNySixPQUFPLEVBQUVnSixLQUFLLENBQUNNLElBQUksRUFBRXBJLFFBQVEsRUFBRWtGLEVBQUUsQ0FBQztVQUNyRDtVQUVBLE9BQU9BLEVBQUUsQ0FBQ21ELEtBQUssQ0FBQ2xDLE1BQU0sRUFBRSxDQUFDMkIsS0FBSyxDQUFDLENBQUM7UUFDbEM7TUFDRjtLQUNEO0VBQ0g7RUFFQSxTQUFTWSxXQUFXQSxDQUFDQyxNQUFNLEVBQUVDLFFBQVEsRUFBNkI7SUFBQSxJQUEzQkMsa0JBQWtCLEdBQUFwRCxTQUFBLENBQUFuRCxNQUFBLFFBQUFtRCxTQUFBLFFBQUFoRixTQUFBLEdBQUFnRixTQUFBLE1BQUcsSUFBSTtJQUM5RCxPQUFPL0UsTUFBTSxDQUFDb0ksTUFBTSxDQUFDSCxNQUFNLENBQUMsQ0FDekJJLElBQUksQ0FBQ2pCLEtBQUssSUFBSUEsS0FBSyxDQUFDYyxRQUFRLEtBQUtBLFFBQVEsSUFBSWQsS0FBSyxDQUFDZSxrQkFBa0IsS0FBS0Esa0JBQWtCLENBQUM7RUFDbEc7RUFFQSxTQUFTRyxtQkFBbUJBLENBQUNDLGlCQUFpQixFQUFFaEQsT0FBTyxFQUFFaUQsa0JBQWtCLEVBQUU7SUFDM0UsTUFBTUMsV0FBVyxHQUFHLE9BQU9sRCxPQUFPLEtBQUssUUFBUTtJQUMvQztJQUNBLE1BQU0yQyxRQUFRLEdBQUdPLFdBQVcsR0FBR0Qsa0JBQWtCLEdBQUlqRCxPQUFPLElBQUlpRCxrQkFBbUI7SUFDbkYsSUFBSUUsU0FBUyxHQUFHQyxZQUFZLENBQUNKLGlCQUFpQixDQUFDO0lBRS9DLElBQUksQ0FBQ3pCLFlBQVksQ0FBQ3ZJLEdBQUcsQ0FBQ21LLFNBQVMsQ0FBQyxFQUFFO01BQ2hDQSxTQUFTLEdBQUdILGlCQUFpQjtJQUMvQjtJQUVBLE9BQU8sQ0FBQ0UsV0FBVyxFQUFFUCxRQUFRLEVBQUVRLFNBQVMsQ0FBQztFQUMzQztFQUVBLFNBQVNFLFVBQVVBLENBQUN4SyxPQUFPLEVBQUVtSyxpQkFBaUIsRUFBRWhELE9BQU8sRUFBRWlELGtCQUFrQixFQUFFakIsTUFBTSxFQUFFO0lBQ25GLElBQUksT0FBT2dCLGlCQUFpQixLQUFLLFFBQVEsSUFBSSxDQUFDbkssT0FBTyxFQUFFO01BQ3JEO0lBQ0Y7SUFFQSxJQUFJLENBQUNxSyxXQUFXLEVBQUVQLFFBQVEsRUFBRVEsU0FBUyxDQUFDLEdBQUdKLG1CQUFtQixDQUFDQyxpQkFBaUIsRUFBRWhELE9BQU8sRUFBRWlELGtCQUFrQixDQUFDOztJQUU1RztJQUNBO0lBQ0EsSUFBSUQsaUJBQWlCLElBQUk1QixZQUFZLEVBQUU7TUFDckMsTUFBTWtDLFlBQVksR0FBR3JFLEVBQUUsSUFBSTtRQUN6QixPQUFPLFVBQVU0QyxLQUFLLEVBQUU7VUFDdEIsSUFBSSxDQUFDQSxLQUFLLENBQUMwQixhQUFhLElBQUsxQixLQUFLLENBQUMwQixhQUFhLEtBQUsxQixLQUFLLENBQUNFLGNBQWMsSUFBSSxDQUFDRixLQUFLLENBQUNFLGNBQWMsQ0FBQzVFLFFBQVEsQ0FBQzBFLEtBQUssQ0FBQzBCLGFBQWEsQ0FBRSxFQUFFO1lBQ2pJLE9BQU90RSxFQUFFLENBQUNyRSxJQUFJLENBQUMsSUFBSSxFQUFFaUgsS0FBSyxDQUFDO1VBQzdCO1NBQ0Q7T0FDRjtNQUVEYyxRQUFRLEdBQUdXLFlBQVksQ0FBQ1gsUUFBUSxDQUFDO0lBQ25DO0lBRUEsTUFBTUQsTUFBTSxHQUFHZixnQkFBZ0IsQ0FBQzlJLE9BQU8sQ0FBQztJQUN4QyxNQUFNMkssUUFBUSxHQUFHZCxNQUFNLENBQUNTLFNBQVMsQ0FBQyxLQUFLVCxNQUFNLENBQUNTLFNBQVMsQ0FBQyxHQUFHLEVBQUUsQ0FBQztJQUM5RCxNQUFNTSxnQkFBZ0IsR0FBR2hCLFdBQVcsQ0FBQ2UsUUFBUSxFQUFFYixRQUFRLEVBQUVPLFdBQVcsR0FBR2xELE9BQU8sR0FBRyxJQUFJLENBQUM7SUFFdEYsSUFBSXlELGdCQUFnQixFQUFFO01BQ3BCQSxnQkFBZ0IsQ0FBQ3pCLE1BQU0sR0FBR3lCLGdCQUFnQixDQUFDekIsTUFBTSxJQUFJQSxNQUFNO01BRTNEO0lBQ0Y7SUFFQSxNQUFNTixHQUFHLEdBQUdELFlBQVksQ0FBQ2tCLFFBQVEsRUFBRUssaUJBQWlCLENBQUM3SSxPQUFPLENBQUM0RyxjQUFjLEVBQUUsRUFBRSxDQUFDLENBQUM7SUFDakYsTUFBTTlCLEVBQUUsR0FBR2lFLFdBQVcsR0FDcEJiLDBCQUEwQixDQUFDeEosT0FBTyxFQUFFbUgsT0FBTyxFQUFFMkMsUUFBUSxDQUFDLEdBQ3REZixnQkFBZ0IsQ0FBQy9JLE9BQU8sRUFBRThKLFFBQVEsQ0FBQztJQUVyQzFELEVBQUUsQ0FBQzJELGtCQUFrQixHQUFHTSxXQUFXLEdBQUdsRCxPQUFPLEdBQUcsSUFBSTtJQUNwRGYsRUFBRSxDQUFDMEQsUUFBUSxHQUFHQSxRQUFRO0lBQ3RCMUQsRUFBRSxDQUFDK0MsTUFBTSxHQUFHQSxNQUFNO0lBQ2xCL0MsRUFBRSxDQUFDa0MsUUFBUSxHQUFHTyxHQUFHO0lBQ2pCOEIsUUFBUSxDQUFDOUIsR0FBRyxDQUFDLEdBQUd6QyxFQUFFO0lBRWxCcEcsT0FBTyxDQUFDMEYsZ0JBQWdCLENBQUM0RSxTQUFTLEVBQUVsRSxFQUFFLEVBQUVpRSxXQUFXLENBQUM7RUFDdEQ7RUFFQSxTQUFTUSxhQUFhQSxDQUFDN0ssT0FBTyxFQUFFNkosTUFBTSxFQUFFUyxTQUFTLEVBQUVuRCxPQUFPLEVBQUU0QyxrQkFBa0IsRUFBRTtJQUM5RSxNQUFNM0QsRUFBRSxHQUFHd0QsV0FBVyxDQUFDQyxNQUFNLENBQUNTLFNBQVMsQ0FBQyxFQUFFbkQsT0FBTyxFQUFFNEMsa0JBQWtCLENBQUM7SUFFdEUsSUFBSSxDQUFDM0QsRUFBRSxFQUFFO01BQ1A7SUFDRjtJQUVBcEcsT0FBTyxDQUFDc0gsbUJBQW1CLENBQUNnRCxTQUFTLEVBQUVsRSxFQUFFLEVBQUUwRSxPQUFPLENBQUNmLGtCQUFrQixDQUFDLENBQUM7SUFDdkUsT0FBT0YsTUFBTSxDQUFDUyxTQUFTLENBQUMsQ0FBQ2xFLEVBQUUsQ0FBQ2tDLFFBQVEsQ0FBQztFQUN2QztFQUVBLFNBQVN5Qyx3QkFBd0JBLENBQUMvSyxPQUFPLEVBQUU2SixNQUFNLEVBQUVTLFNBQVMsRUFBRVUsU0FBUyxFQUFFO0lBQ3ZFLE1BQU1DLGlCQUFpQixHQUFHcEIsTUFBTSxDQUFDUyxTQUFTLENBQUMsSUFBSSxFQUFFO0lBRWpELEtBQUssTUFBTSxDQUFDWSxVQUFVLEVBQUVsQyxLQUFLLENBQUMsSUFBSXBILE1BQU0sQ0FBQ3VKLE9BQU8sQ0FBQ0YsaUJBQWlCLENBQUMsRUFBRTtNQUNuRSxJQUFJQyxVQUFVLENBQUNFLFFBQVEsQ0FBQ0osU0FBUyxDQUFDLEVBQUU7UUFDbENILGFBQWEsQ0FBQzdLLE9BQU8sRUFBRTZKLE1BQU0sRUFBRVMsU0FBUyxFQUFFdEIsS0FBSyxDQUFDYyxRQUFRLEVBQUVkLEtBQUssQ0FBQ2Usa0JBQWtCLENBQUM7TUFDckY7SUFDRjtFQUNGO0VBRUEsU0FBU1EsWUFBWUEsQ0FBQ3ZCLEtBQUssRUFBRTtJQUMzQjtJQUNBQSxLQUFLLEdBQUdBLEtBQUssQ0FBQzFILE9BQU8sQ0FBQzZHLGNBQWMsRUFBRSxFQUFFLENBQUM7SUFDekMsT0FBT0ksWUFBWSxDQUFDUyxLQUFLLENBQUMsSUFBSUEsS0FBSztFQUNyQztFQUVBLE1BQU1JLFlBQVksR0FBRztJQUNuQmlDLEVBQUVBLENBQUNyTCxPQUFPLEVBQUVnSixLQUFLLEVBQUU3QixPQUFPLEVBQUVpRCxrQkFBa0IsRUFBRTtNQUM5Q0ksVUFBVSxDQUFDeEssT0FBTyxFQUFFZ0osS0FBSyxFQUFFN0IsT0FBTyxFQUFFaUQsa0JBQWtCLEVBQUUsS0FBSyxDQUFDO0tBQy9EO0lBRURrQixHQUFHQSxDQUFDdEwsT0FBTyxFQUFFZ0osS0FBSyxFQUFFN0IsT0FBTyxFQUFFaUQsa0JBQWtCLEVBQUU7TUFDL0NJLFVBQVUsQ0FBQ3hLLE9BQU8sRUFBRWdKLEtBQUssRUFBRTdCLE9BQU8sRUFBRWlELGtCQUFrQixFQUFFLElBQUksQ0FBQztLQUM5RDtJQUVEZixHQUFHQSxDQUFDckosT0FBTyxFQUFFbUssaUJBQWlCLEVBQUVoRCxPQUFPLEVBQUVpRCxrQkFBa0IsRUFBRTtNQUMzRCxJQUFJLE9BQU9ELGlCQUFpQixLQUFLLFFBQVEsSUFBSSxDQUFDbkssT0FBTyxFQUFFO1FBQ3JEO01BQ0Y7TUFFQSxNQUFNLENBQUNxSyxXQUFXLEVBQUVQLFFBQVEsRUFBRVEsU0FBUyxDQUFDLEdBQUdKLG1CQUFtQixDQUFDQyxpQkFBaUIsRUFBRWhELE9BQU8sRUFBRWlELGtCQUFrQixDQUFDO01BQzlHLE1BQU1tQixXQUFXLEdBQUdqQixTQUFTLEtBQUtILGlCQUFpQjtNQUNuRCxNQUFNTixNQUFNLEdBQUdmLGdCQUFnQixDQUFDOUksT0FBTyxDQUFDO01BQ3hDLE1BQU1pTCxpQkFBaUIsR0FBR3BCLE1BQU0sQ0FBQ1MsU0FBUyxDQUFDLElBQUksRUFBRTtNQUNqRCxNQUFNa0IsV0FBVyxHQUFHckIsaUJBQWlCLENBQUNzQixVQUFVLENBQUMsR0FBRyxDQUFDO01BRXJELElBQUksT0FBTzNCLFFBQVEsS0FBSyxXQUFXLEVBQUU7UUFDbkM7UUFDQSxJQUFJLENBQUNsSSxNQUFNLENBQUNqQixJQUFJLENBQUNzSyxpQkFBaUIsQ0FBQyxDQUFDekgsTUFBTSxFQUFFO1VBQzFDO1FBQ0Y7UUFFQXFILGFBQWEsQ0FBQzdLLE9BQU8sRUFBRTZKLE1BQU0sRUFBRVMsU0FBUyxFQUFFUixRQUFRLEVBQUVPLFdBQVcsR0FBR2xELE9BQU8sR0FBRyxJQUFJLENBQUM7UUFDakY7TUFDRjtNQUVBLElBQUlxRSxXQUFXLEVBQUU7UUFDZixLQUFLLE1BQU1FLFlBQVksSUFBSTlKLE1BQU0sQ0FBQ2pCLElBQUksQ0FBQ2tKLE1BQU0sQ0FBQyxFQUFFO1VBQzlDa0Isd0JBQXdCLENBQUMvSyxPQUFPLEVBQUU2SixNQUFNLEVBQUU2QixZQUFZLEVBQUV2QixpQkFBaUIsQ0FBQ3dCLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNyRjtNQUNGO01BRUEsS0FBSyxNQUFNLENBQUNDLFdBQVcsRUFBRTVDLEtBQUssQ0FBQyxJQUFJcEgsTUFBTSxDQUFDdUosT0FBTyxDQUFDRixpQkFBaUIsQ0FBQyxFQUFFO1FBQ3BFLE1BQU1DLFVBQVUsR0FBR1UsV0FBVyxDQUFDdEssT0FBTyxDQUFDOEcsYUFBYSxFQUFFLEVBQUUsQ0FBQztRQUV6RCxJQUFJLENBQUNtRCxXQUFXLElBQUlwQixpQkFBaUIsQ0FBQ2lCLFFBQVEsQ0FBQ0YsVUFBVSxDQUFDLEVBQUU7VUFDMURMLGFBQWEsQ0FBQzdLLE9BQU8sRUFBRTZKLE1BQU0sRUFBRVMsU0FBUyxFQUFFdEIsS0FBSyxDQUFDYyxRQUFRLEVBQUVkLEtBQUssQ0FBQ2Usa0JBQWtCLENBQUM7UUFDckY7TUFDRjtLQUNEO0lBRUQ4QixPQUFPQSxDQUFDN0wsT0FBTyxFQUFFZ0osS0FBSyxFQUFFdEMsSUFBSSxFQUFFO01BQzVCLElBQUksT0FBT3NDLEtBQUssS0FBSyxRQUFRLElBQUksQ0FBQ2hKLE9BQU8sRUFBRTtRQUN6QyxPQUFPLElBQUk7TUFDYjtNQUVBLE1BQU1nRyxDQUFDLEdBQUdiLFNBQVMsRUFBRTtNQUNyQixNQUFNbUYsU0FBUyxHQUFHQyxZQUFZLENBQUN2QixLQUFLLENBQUM7TUFDckMsTUFBTXVDLFdBQVcsR0FBR3ZDLEtBQUssS0FBS3NCLFNBQVM7TUFFdkMsSUFBSXdCLFdBQVcsR0FBRyxJQUFJO01BQ3RCLElBQUlDLE9BQU8sR0FBRyxJQUFJO01BQ2xCLElBQUlDLGNBQWMsR0FBRyxJQUFJO01BQ3pCLElBQUlDLGdCQUFnQixHQUFHLEtBQUs7TUFFNUIsSUFBSVYsV0FBVyxJQUFJdkYsQ0FBQyxFQUFFO1FBQ3BCOEYsV0FBVyxHQUFHOUYsQ0FBQyxDQUFDN0MsS0FBSyxDQUFDNkYsS0FBSyxFQUFFdEMsSUFBSSxDQUFDO1FBRWxDVixDQUFDLENBQUNoRyxPQUFPLENBQUMsQ0FBQzZMLE9BQU8sQ0FBQ0MsV0FBVyxDQUFDO1FBQy9CQyxPQUFPLEdBQUcsQ0FBQ0QsV0FBVyxDQUFDSSxvQkFBb0IsRUFBRTtRQUM3Q0YsY0FBYyxHQUFHLENBQUNGLFdBQVcsQ0FBQ0ssNkJBQTZCLEVBQUU7UUFDN0RGLGdCQUFnQixHQUFHSCxXQUFXLENBQUNNLGtCQUFrQixFQUFFO01BQ3JEO01BRUEsTUFBTUMsR0FBRyxHQUFHcEQsVUFBVSxDQUFDLElBQUk5RixLQUFLLENBQUM2RixLQUFLLEVBQUU7UUFBRStDLE9BQU87UUFBRU8sVUFBVSxFQUFFO09BQU0sQ0FBQyxFQUFFNUYsSUFBSSxDQUFDO01BRTdFLElBQUl1RixnQkFBZ0IsRUFBRTtRQUNwQkksR0FBRyxDQUFDRSxjQUFjLEVBQUU7TUFDdEI7TUFFQSxJQUFJUCxjQUFjLEVBQUU7UUFDbEJoTSxPQUFPLENBQUNrRCxhQUFhLENBQUNtSixHQUFHLENBQUM7TUFDNUI7TUFFQSxJQUFJQSxHQUFHLENBQUNKLGdCQUFnQixJQUFJSCxXQUFXLEVBQUU7UUFDdkNBLFdBQVcsQ0FBQ1MsY0FBYyxFQUFFO01BQzlCO01BRUEsT0FBT0YsR0FBRztJQUNaO0VBQ0YsQ0FBQztFQUVELFNBQVNwRCxVQUFVQSxDQUFDdUQsR0FBRyxFQUFhO0lBQUEsSUFBWEMsSUFBSSxHQUFBOUYsU0FBQSxDQUFBbkQsTUFBQSxRQUFBbUQsU0FBQSxRQUFBaEYsU0FBQSxHQUFBZ0YsU0FBQSxNQUFHLEVBQUU7SUFDaEMsS0FBSyxNQUFNLENBQUMxRyxHQUFHLEVBQUV5TSxLQUFLLENBQUMsSUFBSTlLLE1BQU0sQ0FBQ3VKLE9BQU8sQ0FBQ3NCLElBQUksQ0FBQyxFQUFFO01BQy9DLElBQUk7UUFDRkQsR0FBRyxDQUFDdk0sR0FBRyxDQUFDLEdBQUd5TSxLQUFLO09BQ2pCLENBQUMsT0FBQUMsT0FBQSxFQUFNO1FBQ04vSyxNQUFNLENBQUNnTCxjQUFjLENBQUNKLEdBQUcsRUFBRXZNLEdBQUcsRUFBRTtVQUM5QjRNLFlBQVksRUFBRSxJQUFJO1VBQ2xCeE0sR0FBR0EsQ0FBQSxFQUFHO1lBQ0osT0FBT3FNLEtBQUs7VUFDZDtRQUNGLENBQUMsQ0FBQztNQUNKO0lBQ0Y7SUFFQSxPQUFPRixHQUFHO0VBQ1o7O0VDMVRBOzs7Ozs7O0VBT0EsU0FBU00sYUFBYUEsQ0FBQ0osS0FBSyxFQUFFO0lBQzVCLElBQUlBLEtBQUssS0FBSyxNQUFNLEVBQUU7TUFDcEIsT0FBTyxJQUFJO0lBQ2I7SUFFQSxJQUFJQSxLQUFLLEtBQUssT0FBTyxFQUFFO01BQ3JCLE9BQU8sS0FBSztJQUNkO0lBRUEsSUFBSUEsS0FBSyxLQUFLN0osTUFBTSxDQUFDNkosS0FBSyxDQUFDLENBQUM1SyxRQUFRLEVBQUUsRUFBRTtNQUN0QyxPQUFPZSxNQUFNLENBQUM2SixLQUFLLENBQUM7SUFDdEI7SUFFQSxJQUFJQSxLQUFLLEtBQUssRUFBRSxJQUFJQSxLQUFLLEtBQUssTUFBTSxFQUFFO01BQ3BDLE9BQU8sSUFBSTtJQUNiO0lBRUEsSUFBSSxPQUFPQSxLQUFLLEtBQUssUUFBUSxFQUFFO01BQzdCLE9BQU9BLEtBQUs7SUFDZDtJQUVBLElBQUk7TUFDRixPQUFPSyxJQUFJLENBQUNDLEtBQUssQ0FBQ0Msa0JBQWtCLENBQUNQLEtBQUssQ0FBQyxDQUFDO0tBQzdDLENBQUMsT0FBQUMsT0FBQSxFQUFNO01BQ04sT0FBT0QsS0FBSztJQUNkO0VBQ0Y7RUFFQSxTQUFTUSxnQkFBZ0JBLENBQUNqTixHQUFHLEVBQUU7SUFDN0IsT0FBT0EsR0FBRyxDQUFDcUIsT0FBTyxDQUFDLFFBQVEsRUFBRTZMLEdBQUcsSUFBSyxJQUFHQSxHQUFHLENBQUNuTCxXQUFXLEVBQUcsRUFBQyxDQUFDO0VBQzlEO0VBRUEsTUFBTW9MLFdBQVcsR0FBRztJQUNsQkMsZ0JBQWdCQSxDQUFDck4sT0FBTyxFQUFFQyxHQUFHLEVBQUV5TSxLQUFLLEVBQUU7TUFDcEMxTSxPQUFPLENBQUNzTixZQUFZLENBQUUsV0FBVUosZ0JBQWdCLENBQUNqTixHQUFHLENBQUUsRUFBQyxFQUFFeU0sS0FBSyxDQUFDO0tBQ2hFO0lBRURhLG1CQUFtQkEsQ0FBQ3ZOLE9BQU8sRUFBRUMsR0FBRyxFQUFFO01BQ2hDRCxPQUFPLENBQUN3TixlQUFlLENBQUUsV0FBVU4sZ0JBQWdCLENBQUNqTixHQUFHLENBQUUsRUFBQyxDQUFDO0tBQzVEO0lBRUR3TixpQkFBaUJBLENBQUN6TixPQUFPLEVBQUU7TUFDekIsSUFBSSxDQUFDQSxPQUFPLEVBQUU7UUFDWixPQUFPLEVBQUU7TUFDWDtNQUVBLE1BQU0wTixVQUFVLEdBQUcsRUFBRTtNQUNyQixNQUFNQyxNQUFNLEdBQUcvTCxNQUFNLENBQUNqQixJQUFJLENBQUNYLE9BQU8sQ0FBQzROLE9BQU8sQ0FBQyxDQUFDQyxNQUFNLENBQUM1TixHQUFHLElBQUlBLEdBQUcsQ0FBQ3dMLFVBQVUsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDeEwsR0FBRyxDQUFDd0wsVUFBVSxDQUFDLFVBQVUsQ0FBQyxDQUFDO01BRTlHLEtBQUssTUFBTXhMLEdBQUcsSUFBSTBOLE1BQU0sRUFBRTtRQUN4QixJQUFJRyxPQUFPLEdBQUc3TixHQUFHLENBQUNxQixPQUFPLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQztRQUNwQ3dNLE9BQU8sR0FBR0EsT0FBTyxDQUFDQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMvTCxXQUFXLEVBQUUsR0FBRzhMLE9BQU8sQ0FBQ25DLEtBQUssQ0FBQyxDQUFDLEVBQUVtQyxPQUFPLENBQUN0SyxNQUFNLENBQUM7UUFDNUVrSyxVQUFVLENBQUNJLE9BQU8sQ0FBQyxHQUFHaEIsYUFBYSxDQUFDOU0sT0FBTyxDQUFDNE4sT0FBTyxDQUFDM04sR0FBRyxDQUFDLENBQUM7TUFDM0Q7TUFFQSxPQUFPeU4sVUFBVTtLQUNsQjtJQUVETSxnQkFBZ0JBLENBQUNoTyxPQUFPLEVBQUVDLEdBQUcsRUFBRTtNQUM3QixPQUFPNk0sYUFBYSxDQUFDOU0sT0FBTyxDQUFDeUUsWUFBWSxDQUFFLFdBQVV5SSxnQkFBZ0IsQ0FBQ2pOLEdBQUcsQ0FBRSxFQUFDLENBQUMsQ0FBQztJQUNoRjtFQUNGLENBQUM7O0VDcEVEOzs7Ozs7O0VBVUE7Ozs7RUFJQSxNQUFNZ08sTUFBTSxDQUFDO0lBQ1g7SUFDQSxXQUFXQyxPQUFPQSxDQUFBLEVBQUc7TUFDbkIsT0FBTyxFQUFFO0lBQ1g7SUFFQSxXQUFXQyxXQUFXQSxDQUFBLEVBQUc7TUFDdkIsT0FBTyxFQUFFO0lBQ1g7SUFFQSxXQUFXakksSUFBSUEsQ0FBQSxFQUFHO01BQ2hCLE1BQU0sSUFBSWtJLEtBQUssQ0FBQyxxRUFBcUUsQ0FBQztJQUN4RjtJQUVBQyxVQUFVQSxDQUFDQyxNQUFNLEVBQUU7TUFDakJBLE1BQU0sR0FBRyxJQUFJLENBQUNDLGVBQWUsQ0FBQ0QsTUFBTSxDQUFDO01BQ3JDQSxNQUFNLEdBQUcsSUFBSSxDQUFDRSxpQkFBaUIsQ0FBQ0YsTUFBTSxDQUFDO01BQ3ZDLElBQUksQ0FBQ0csZ0JBQWdCLENBQUNILE1BQU0sQ0FBQztNQUM3QixPQUFPQSxNQUFNO0lBQ2Y7SUFFQUUsaUJBQWlCQSxDQUFDRixNQUFNLEVBQUU7TUFDeEIsT0FBT0EsTUFBTTtJQUNmO0lBRUFDLGVBQWVBLENBQUNELE1BQU0sRUFBRXRPLE9BQU8sRUFBRTtNQUMvQixNQUFNME8sVUFBVSxHQUFHdEwsV0FBUyxDQUFDcEQsT0FBTyxDQUFDLEdBQUdvTixXQUFXLENBQUNZLGdCQUFnQixDQUFDaE8sT0FBTyxFQUFFLFFBQVEsQ0FBQyxHQUFHLEVBQUUsQ0FBQzs7TUFFN0YsT0FBTztRQUNMLEdBQUcsSUFBSSxDQUFDMk8sV0FBVyxDQUFDVCxPQUFPO1FBQzNCLElBQUksT0FBT1EsVUFBVSxLQUFLLFFBQVEsR0FBR0EsVUFBVSxHQUFHLEVBQUU7UUFDcEQsSUFBSXRMLFdBQVMsQ0FBQ3BELE9BQU8sQ0FBQyxHQUFHb04sV0FBVyxDQUFDSyxpQkFBaUIsQ0FBQ3pOLE9BQU8sQ0FBQyxHQUFHLEVBQUU7UUFDcEUsSUFBSSxPQUFPc08sTUFBTSxLQUFLLFFBQVEsR0FBR0EsTUFBTSxHQUFHLEVBQUU7T0FDN0M7SUFDSDtJQUVBRyxnQkFBZ0JBLENBQUNILE1BQU0sRUFBOEM7TUFBQSxJQUE1Q00sV0FBVyxHQUFBakksU0FBQSxDQUFBbkQsTUFBQSxRQUFBbUQsU0FBQSxRQUFBaEYsU0FBQSxHQUFBZ0YsU0FBQSxNQUFHLElBQUksQ0FBQ2dJLFdBQVcsQ0FBQ1IsV0FBVztNQUNqRSxLQUFLLE1BQU0sQ0FBQ1UsUUFBUSxFQUFFQyxhQUFhLENBQUMsSUFBSWxOLE1BQU0sQ0FBQ3VKLE9BQU8sQ0FBQ3lELFdBQVcsQ0FBQyxFQUFFO1FBQ25FLE1BQU1sQyxLQUFLLEdBQUc0QixNQUFNLENBQUNPLFFBQVEsQ0FBQztRQUM5QixNQUFNRSxTQUFTLEdBQUczTCxXQUFTLENBQUNzSixLQUFLLENBQUMsR0FBRyxTQUFTLEdBQUdqTCxNQUFNLENBQUNpTCxLQUFLLENBQUM7UUFFOUQsSUFBSSxDQUFDLElBQUlzQyxNQUFNLENBQUNGLGFBQWEsQ0FBQyxDQUFDRyxJQUFJLENBQUNGLFNBQVMsQ0FBQyxFQUFFO1VBQzlDLE1BQU0sSUFBSUcsU0FBUyxDQUNoQixHQUFFLElBQUksQ0FBQ1AsV0FBVyxDQUFDekksSUFBSSxDQUFDaUosV0FBVyxFQUFHLGFBQVlOLFFBQVMsb0JBQW1CRSxTQUFVLHdCQUF1QkQsYUFBYyxJQUNoSSxDQUFDO1FBQ0g7TUFDRjtJQUNGO0VBQ0Y7O0VDOURBOzs7Ozs7O0VBWUE7Ozs7RUFJQSxNQUFNTSxPQUFPLEdBQUcsT0FBTzs7RUFFdkI7Ozs7RUFJQSxNQUFNQyxhQUFhLFNBQVNwQixNQUFNLENBQUM7SUFDakNVLFdBQVdBLENBQUMzTyxPQUFPLEVBQUVzTyxNQUFNLEVBQUU7TUFDM0IsS0FBSyxFQUFFO01BRVB0TyxPQUFPLEdBQUd1RCxVQUFVLENBQUN2RCxPQUFPLENBQUM7TUFDN0IsSUFBSSxDQUFDQSxPQUFPLEVBQUU7UUFDWjtNQUNGO01BRUEsSUFBSSxDQUFDc1AsUUFBUSxHQUFHdFAsT0FBTztNQUN2QixJQUFJLENBQUN1UCxPQUFPLEdBQUcsSUFBSSxDQUFDbEIsVUFBVSxDQUFDQyxNQUFNLENBQUM7TUFFdEN4TyxJQUFJLENBQUNDLEdBQUcsQ0FBQyxJQUFJLENBQUN1UCxRQUFRLEVBQUUsSUFBSSxDQUFDWCxXQUFXLENBQUNhLFFBQVEsRUFBRSxJQUFJLENBQUM7SUFDMUQ7O0lBRUE7SUFDQUMsT0FBT0EsQ0FBQSxFQUFHO01BQ1IzUCxJQUFJLENBQUNjLE1BQU0sQ0FBQyxJQUFJLENBQUMwTyxRQUFRLEVBQUUsSUFBSSxDQUFDWCxXQUFXLENBQUNhLFFBQVEsQ0FBQztNQUNyRHBHLFlBQVksQ0FBQ0MsR0FBRyxDQUFDLElBQUksQ0FBQ2lHLFFBQVEsRUFBRSxJQUFJLENBQUNYLFdBQVcsQ0FBQ2UsU0FBUyxDQUFDO01BRTNELEtBQUssTUFBTUMsWUFBWSxJQUFJL04sTUFBTSxDQUFDZ08sbUJBQW1CLENBQUMsSUFBSSxDQUFDLEVBQUU7UUFDM0QsSUFBSSxDQUFDRCxZQUFZLENBQUMsR0FBRyxJQUFJO01BQzNCO0lBQ0Y7SUFFQUUsY0FBY0EsQ0FBQ3JLLFFBQVEsRUFBRXhGLE9BQU8sRUFBcUI7TUFBQSxJQUFuQjhQLFVBQVUsR0FBQW5KLFNBQUEsQ0FBQW5ELE1BQUEsUUFBQW1ELFNBQUEsUUFBQWhGLFNBQUEsR0FBQWdGLFNBQUEsTUFBRyxJQUFJO01BQ2pERSxzQkFBc0IsQ0FBQ3JCLFFBQVEsRUFBRXhGLE9BQU8sRUFBRThQLFVBQVUsQ0FBQztJQUN2RDtJQUVBekIsVUFBVUEsQ0FBQ0MsTUFBTSxFQUFFO01BQ2pCQSxNQUFNLEdBQUcsSUFBSSxDQUFDQyxlQUFlLENBQUNELE1BQU0sRUFBRSxJQUFJLENBQUNnQixRQUFRLENBQUM7TUFDcERoQixNQUFNLEdBQUcsSUFBSSxDQUFDRSxpQkFBaUIsQ0FBQ0YsTUFBTSxDQUFDO01BQ3ZDLElBQUksQ0FBQ0csZ0JBQWdCLENBQUNILE1BQU0sQ0FBQztNQUM3QixPQUFPQSxNQUFNO0lBQ2Y7O0lBRUE7SUFDQSxPQUFPeUIsV0FBV0EsQ0FBQy9QLE9BQU8sRUFBRTtNQUMxQixPQUFPRixJQUFJLENBQUNPLEdBQUcsQ0FBQ2tELFVBQVUsQ0FBQ3ZELE9BQU8sQ0FBQyxFQUFFLElBQUksQ0FBQ3dQLFFBQVEsQ0FBQztJQUNyRDtJQUVBLE9BQU9RLG1CQUFtQkEsQ0FBQ2hRLE9BQU8sRUFBZTtNQUFBLElBQWJzTyxNQUFNLEdBQUEzSCxTQUFBLENBQUFuRCxNQUFBLFFBQUFtRCxTQUFBLFFBQUFoRixTQUFBLEdBQUFnRixTQUFBLE1BQUcsRUFBRTtNQUM3QyxPQUFPLElBQUksQ0FBQ29KLFdBQVcsQ0FBQy9QLE9BQU8sQ0FBQyxJQUFJLElBQUksSUFBSSxDQUFDQSxPQUFPLEVBQUUsT0FBT3NPLE1BQU0sS0FBSyxRQUFRLEdBQUdBLE1BQU0sR0FBRyxJQUFJLENBQUM7SUFDbkc7SUFFQSxXQUFXYyxPQUFPQSxDQUFBLEVBQUc7TUFDbkIsT0FBT0EsT0FBTztJQUNoQjtJQUVBLFdBQVdJLFFBQVFBLENBQUEsRUFBRztNQUNwQixPQUFRLE1BQUssSUFBSSxDQUFDdEosSUFBSyxFQUFDO0lBQzFCO0lBRUEsV0FBV3dKLFNBQVNBLENBQUEsRUFBRztNQUNyQixPQUFRLElBQUcsSUFBSSxDQUFDRixRQUFTLEVBQUM7SUFDNUI7SUFFQSxPQUFPUyxTQUFTQSxDQUFDaEssSUFBSSxFQUFFO01BQ3JCLE9BQVEsR0FBRUEsSUFBSyxHQUFFLElBQUksQ0FBQ3lKLFNBQVUsRUFBQztJQUNuQztFQUNGOztFQ2xGQTs7Ozs7OztFQVNBLE1BQU1RLFdBQVcsR0FBR2xRLE9BQU8sSUFBSTtJQUM3QixJQUFJa0IsUUFBUSxHQUFHbEIsT0FBTyxDQUFDeUUsWUFBWSxDQUFDLGdCQUFnQixDQUFDO0lBRXJELElBQUksQ0FBQ3ZELFFBQVEsSUFBSUEsUUFBUSxLQUFLLEdBQUcsRUFBRTtNQUNqQyxJQUFJaVAsYUFBYSxHQUFHblEsT0FBTyxDQUFDeUUsWUFBWSxDQUFDLE1BQU0sQ0FBQzs7TUFFaEQ7TUFDQTtNQUNBO01BQ0E7TUFDQSxJQUFJLENBQUMwTCxhQUFhLElBQUssQ0FBQ0EsYUFBYSxDQUFDL0UsUUFBUSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMrRSxhQUFhLENBQUMxRSxVQUFVLENBQUMsR0FBRyxDQUFFLEVBQUU7UUFDdEYsT0FBTyxJQUFJO01BQ2I7O01BRUE7TUFDQSxJQUFJMEUsYUFBYSxDQUFDL0UsUUFBUSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMrRSxhQUFhLENBQUMxRSxVQUFVLENBQUMsR0FBRyxDQUFDLEVBQUU7UUFDakUwRSxhQUFhLEdBQUksSUFBR0EsYUFBYSxDQUFDbk4sS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBRSxFQUFDO01BQ25EO01BRUE5QixRQUFRLEdBQUdpUCxhQUFhLElBQUlBLGFBQWEsS0FBSyxHQUFHLEdBQUdBLGFBQWEsQ0FBQ0MsSUFBSSxFQUFFLEdBQUcsSUFBSTtJQUNqRjtJQUVBLE9BQU9sUCxRQUFRLEdBQUdBLFFBQVEsQ0FBQzhCLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQ3FOLEdBQUcsQ0FBQ0MsR0FBRyxJQUFJclAsYUFBYSxDQUFDcVAsR0FBRyxDQUFDLENBQUMsQ0FBQ0MsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLElBQUk7RUFDdkYsQ0FBQztFQUVELE1BQU1DLGNBQWMsR0FBRztJQUNyQnZHLElBQUlBLENBQUMvSSxRQUFRLEVBQXNDO01BQUEsSUFBcENsQixPQUFPLEdBQUEyRyxTQUFBLENBQUFuRCxNQUFBLFFBQUFtRCxTQUFBLFFBQUFoRixTQUFBLEdBQUFnRixTQUFBLE1BQUdyRSxRQUFRLENBQUNxQyxlQUFlO01BQy9DLE9BQU8sRUFBRSxDQUFDOEwsTUFBTSxDQUFDLEdBQUdDLE9BQU8sQ0FBQzdPLFNBQVMsQ0FBQzZILGdCQUFnQixDQUFDM0gsSUFBSSxDQUFDL0IsT0FBTyxFQUFFa0IsUUFBUSxDQUFDLENBQUM7S0FDaEY7SUFFRHlQLE9BQU9BLENBQUN6UCxRQUFRLEVBQXNDO01BQUEsSUFBcENsQixPQUFPLEdBQUEyRyxTQUFBLENBQUFuRCxNQUFBLFFBQUFtRCxTQUFBLFFBQUFoRixTQUFBLEdBQUFnRixTQUFBLE1BQUdyRSxRQUFRLENBQUNxQyxlQUFlO01BQ2xELE9BQU8rTCxPQUFPLENBQUM3TyxTQUFTLENBQUM0QixhQUFhLENBQUMxQixJQUFJLENBQUMvQixPQUFPLEVBQUVrQixRQUFRLENBQUM7S0FDL0Q7SUFFRDBQLFFBQVFBLENBQUM1USxPQUFPLEVBQUVrQixRQUFRLEVBQUU7TUFDMUIsT0FBTyxFQUFFLENBQUN1UCxNQUFNLENBQUMsR0FBR3pRLE9BQU8sQ0FBQzRRLFFBQVEsQ0FBQyxDQUFDL0MsTUFBTSxDQUFDZ0QsS0FBSyxJQUFJQSxLQUFLLENBQUNDLE9BQU8sQ0FBQzVQLFFBQVEsQ0FBQyxDQUFDO0tBQy9FO0lBRUQ2UCxPQUFPQSxDQUFDL1EsT0FBTyxFQUFFa0IsUUFBUSxFQUFFO01BQ3pCLE1BQU02UCxPQUFPLEdBQUcsRUFBRTtNQUNsQixJQUFJQyxRQUFRLEdBQUdoUixPQUFPLENBQUNpRSxVQUFVLENBQUNGLE9BQU8sQ0FBQzdDLFFBQVEsQ0FBQztNQUVuRCxPQUFPOFAsUUFBUSxFQUFFO1FBQ2ZELE9BQU8sQ0FBQ3BMLElBQUksQ0FBQ3FMLFFBQVEsQ0FBQztRQUN0QkEsUUFBUSxHQUFHQSxRQUFRLENBQUMvTSxVQUFVLENBQUNGLE9BQU8sQ0FBQzdDLFFBQVEsQ0FBQztNQUNsRDtNQUVBLE9BQU82UCxPQUFPO0tBQ2Y7SUFFREUsSUFBSUEsQ0FBQ2pSLE9BQU8sRUFBRWtCLFFBQVEsRUFBRTtNQUN0QixJQUFJZ1EsUUFBUSxHQUFHbFIsT0FBTyxDQUFDbVIsc0JBQXNCO01BRTdDLE9BQU9ELFFBQVEsRUFBRTtRQUNmLElBQUlBLFFBQVEsQ0FBQ0osT0FBTyxDQUFDNVAsUUFBUSxDQUFDLEVBQUU7VUFDOUIsT0FBTyxDQUFDZ1EsUUFBUSxDQUFDO1FBQ25CO1FBRUFBLFFBQVEsR0FBR0EsUUFBUSxDQUFDQyxzQkFBc0I7TUFDNUM7TUFFQSxPQUFPLEVBQUU7S0FDVjtJQUNEO0lBQ0FDLElBQUlBLENBQUNwUixPQUFPLEVBQUVrQixRQUFRLEVBQUU7TUFDdEIsSUFBSWtRLElBQUksR0FBR3BSLE9BQU8sQ0FBQ3FSLGtCQUFrQjtNQUVyQyxPQUFPRCxJQUFJLEVBQUU7UUFDWCxJQUFJQSxJQUFJLENBQUNOLE9BQU8sQ0FBQzVQLFFBQVEsQ0FBQyxFQUFFO1VBQzFCLE9BQU8sQ0FBQ2tRLElBQUksQ0FBQztRQUNmO1FBRUFBLElBQUksR0FBR0EsSUFBSSxDQUFDQyxrQkFBa0I7TUFDaEM7TUFFQSxPQUFPLEVBQUU7S0FDVjtJQUVEQyxpQkFBaUJBLENBQUN0UixPQUFPLEVBQUU7TUFDekIsTUFBTXVSLFVBQVUsR0FBRyxDQUNqQixHQUFHLEVBQ0gsUUFBUSxFQUNSLE9BQU8sRUFDUCxVQUFVLEVBQ1YsUUFBUSxFQUNSLFNBQVMsRUFDVCxZQUFZLEVBQ1osMEJBQTBCLENBQzNCLENBQUNsQixHQUFHLENBQUNuUCxRQUFRLElBQUssR0FBRUEsUUFBUyx1QkFBc0IsQ0FBQyxDQUFDcVAsSUFBSSxDQUFDLEdBQUcsQ0FBQztNQUUvRCxPQUFPLElBQUksQ0FBQ3RHLElBQUksQ0FBQ3NILFVBQVUsRUFBRXZSLE9BQU8sQ0FBQyxDQUFDNk4sTUFBTSxDQUFDMkQsRUFBRSxJQUFJLENBQUN0TixVQUFVLENBQUNzTixFQUFFLENBQUMsSUFBSTlOLFNBQVMsQ0FBQzhOLEVBQUUsQ0FBQyxDQUFDO0tBQ3JGO0lBRURDLHNCQUFzQkEsQ0FBQ3pSLE9BQU8sRUFBRTtNQUM5QixNQUFNa0IsUUFBUSxHQUFHZ1AsV0FBVyxDQUFDbFEsT0FBTyxDQUFDO01BRXJDLElBQUlrQixRQUFRLEVBQUU7UUFDWixPQUFPc1AsY0FBYyxDQUFDRyxPQUFPLENBQUN6UCxRQUFRLENBQUMsR0FBR0EsUUFBUSxHQUFHLElBQUk7TUFDM0Q7TUFFQSxPQUFPLElBQUk7S0FDWjtJQUVEd1Esc0JBQXNCQSxDQUFDMVIsT0FBTyxFQUFFO01BQzlCLE1BQU1rQixRQUFRLEdBQUdnUCxXQUFXLENBQUNsUSxPQUFPLENBQUM7TUFFckMsT0FBT2tCLFFBQVEsR0FBR3NQLGNBQWMsQ0FBQ0csT0FBTyxDQUFDelAsUUFBUSxDQUFDLEdBQUcsSUFBSTtLQUMxRDtJQUVEeVEsK0JBQStCQSxDQUFDM1IsT0FBTyxFQUFFO01BQ3ZDLE1BQU1rQixRQUFRLEdBQUdnUCxXQUFXLENBQUNsUSxPQUFPLENBQUM7TUFFckMsT0FBT2tCLFFBQVEsR0FBR3NQLGNBQWMsQ0FBQ3ZHLElBQUksQ0FBQy9JLFFBQVEsQ0FBQyxHQUFHLEVBQUU7SUFDdEQ7RUFDRixDQUFDOztFQzNIRDs7Ozs7OztFQVdBLE1BQU0wUSxvQkFBb0IsR0FBRyxTQUFBQSxDQUFDQyxTQUFTLEVBQXNCO0lBQUEsSUFBcEJDLE1BQU0sR0FBQW5MLFNBQUEsQ0FBQW5ELE1BQUEsUUFBQW1ELFNBQUEsUUFBQWhGLFNBQUEsR0FBQWdGLFNBQUEsTUFBRyxNQUFNO0lBQ3RELE1BQU1vTCxVQUFVLEdBQUksZ0JBQWVGLFNBQVMsQ0FBQ25DLFNBQVUsRUFBQztJQUN4RCxNQUFNekosSUFBSSxHQUFHNEwsU0FBUyxDQUFDM0wsSUFBSTtJQUUzQmtELFlBQVksQ0FBQ2lDLEVBQUUsQ0FBQy9JLFFBQVEsRUFBRXlQLFVBQVUsRUFBRyxxQkFBb0I5TCxJQUFLLElBQUcsRUFBRSxVQUFVK0MsS0FBSyxFQUFFO01BQ3BGLElBQUksQ0FBQyxHQUFHLEVBQUUsTUFBTSxDQUFDLENBQUNvQyxRQUFRLENBQUMsSUFBSSxDQUFDNEcsT0FBTyxDQUFDLEVBQUU7UUFDeENoSixLQUFLLENBQUN1RCxjQUFjLEVBQUU7TUFDeEI7TUFFQSxJQUFJckksVUFBVSxDQUFDLElBQUksQ0FBQyxFQUFFO1FBQ3BCO01BQ0Y7TUFFQSxNQUFNbUQsTUFBTSxHQUFHbUosY0FBYyxDQUFDa0Isc0JBQXNCLENBQUMsSUFBSSxDQUFDLElBQUksSUFBSSxDQUFDM04sT0FBTyxDQUFFLElBQUdrQyxJQUFLLEVBQUMsQ0FBQztNQUN0RixNQUFNL0YsUUFBUSxHQUFHMlIsU0FBUyxDQUFDN0IsbUJBQW1CLENBQUMzSSxNQUFNLENBQUM7O01BRXREO01BQ0FuSCxRQUFRLENBQUM0UixNQUFNLENBQUMsRUFBRTtJQUNwQixDQUFDLENBQUM7RUFDSixDQUFDOztFQzlCRDs7Ozs7OztFQVlBOzs7O0VBSUEsTUFBTUcsTUFBSSxHQUFHLE9BQU87RUFDcEIsTUFBTUMsVUFBUSxHQUFHLFVBQVU7RUFDM0IsTUFBTUMsV0FBUyxHQUFJLElBQUdELFVBQVMsRUFBQztFQUVoQyxNQUFNRSxXQUFXLEdBQUksUUFBT0QsV0FBVSxFQUFDO0VBQ3ZDLE1BQU1FLFlBQVksR0FBSSxTQUFRRixXQUFVLEVBQUM7RUFDekMsTUFBTUcsaUJBQWUsR0FBRyxNQUFNO0VBQzlCLE1BQU1DLGlCQUFlLEdBQUcsTUFBTTs7RUFFOUI7Ozs7RUFJQSxNQUFNQyxLQUFLLFNBQVNuRCxhQUFhLENBQUM7SUFDaEM7SUFDQSxXQUFXbkosSUFBSUEsQ0FBQSxFQUFHO01BQ2hCLE9BQU8rTCxNQUFJO0lBQ2I7O0lBRUE7SUFDQVEsS0FBS0EsQ0FBQSxFQUFHO01BQ04sTUFBTUMsVUFBVSxHQUFHdEosWUFBWSxDQUFDeUMsT0FBTyxDQUFDLElBQUksQ0FBQ3lELFFBQVEsRUFBRThDLFdBQVcsQ0FBQztNQUVuRSxJQUFJTSxVQUFVLENBQUN6RyxnQkFBZ0IsRUFBRTtRQUMvQjtNQUNGO01BRUEsSUFBSSxDQUFDcUQsUUFBUSxDQUFDakwsU0FBUyxDQUFDekQsTUFBTSxDQUFDMlIsaUJBQWUsQ0FBQztNQUUvQyxNQUFNekMsVUFBVSxHQUFHLElBQUksQ0FBQ1IsUUFBUSxDQUFDakwsU0FBUyxDQUFDQyxRQUFRLENBQUNnTyxpQkFBZSxDQUFDO01BQ3BFLElBQUksQ0FBQ3pDLGNBQWMsQ0FBQyxNQUFNLElBQUksQ0FBQzhDLGVBQWUsRUFBRSxFQUFFLElBQUksQ0FBQ3JELFFBQVEsRUFBRVEsVUFBVSxDQUFDO0lBQzlFOztJQUVBO0lBQ0E2QyxlQUFlQSxDQUFBLEVBQUc7TUFDaEIsSUFBSSxDQUFDckQsUUFBUSxDQUFDMU8sTUFBTSxFQUFFO01BQ3RCd0ksWUFBWSxDQUFDeUMsT0FBTyxDQUFDLElBQUksQ0FBQ3lELFFBQVEsRUFBRStDLFlBQVksQ0FBQztNQUNqRCxJQUFJLENBQUM1QyxPQUFPLEVBQUU7SUFDaEI7O0lBRUE7SUFDQSxPQUFPcEosZUFBZUEsQ0FBQ2lJLE1BQU0sRUFBRTtNQUM3QixPQUFPLElBQUksQ0FBQ3NFLElBQUksQ0FBQyxZQUFZO1FBQzNCLE1BQU1DLElBQUksR0FBR0wsS0FBSyxDQUFDeEMsbUJBQW1CLENBQUMsSUFBSSxDQUFDO1FBRTVDLElBQUksT0FBTzFCLE1BQU0sS0FBSyxRQUFRLEVBQUU7VUFDOUI7UUFDRjtRQUVBLElBQUl1RSxJQUFJLENBQUN2RSxNQUFNLENBQUMsS0FBSzNNLFNBQVMsSUFBSTJNLE1BQU0sQ0FBQzdDLFVBQVUsQ0FBQyxHQUFHLENBQUMsSUFBSTZDLE1BQU0sS0FBSyxhQUFhLEVBQUU7VUFDcEYsTUFBTSxJQUFJWSxTQUFTLENBQUUsb0JBQW1CWixNQUFPLEdBQUUsQ0FBQztRQUNwRDtRQUVBdUUsSUFBSSxDQUFDdkUsTUFBTSxDQUFDLENBQUMsSUFBSSxDQUFDO01BQ3BCLENBQUMsQ0FBQztJQUNKO0VBQ0Y7O0VBRUE7Ozs7RUFJQXNELG9CQUFvQixDQUFDWSxLQUFLLEVBQUUsT0FBTyxDQUFDOztFQUVwQzs7OztFQUlBMU0sa0JBQWtCLENBQUMwTSxLQUFLLENBQUM7O0VDcEZ6Qjs7Ozs7OztFQVdBOzs7O0VBSUEsTUFBTU0sTUFBSSxHQUFHLFFBQVE7RUFDckIsTUFBTUMsVUFBUSxHQUFHLFdBQVc7RUFDNUIsTUFBTUMsV0FBUyxHQUFJLElBQUdELFVBQVMsRUFBQztFQUNoQyxNQUFNRSxjQUFZLEdBQUcsV0FBVztFQUVoQyxNQUFNQyxtQkFBaUIsR0FBRyxRQUFRO0VBQ2xDLE1BQU1DLHNCQUFvQixHQUFHLDJCQUEyQjtFQUN4RCxNQUFNQyxzQkFBb0IsR0FBSSxRQUFPSixXQUFVLEdBQUVDLGNBQWEsRUFBQzs7RUFFL0Q7Ozs7RUFJQSxNQUFNSSxNQUFNLFNBQVNoRSxhQUFhLENBQUM7SUFDakM7SUFDQSxXQUFXbkosSUFBSUEsQ0FBQSxFQUFHO01BQ2hCLE9BQU80TSxNQUFJO0lBQ2I7O0lBRUE7SUFDQVEsTUFBTUEsQ0FBQSxFQUFHO01BQ1A7TUFDQSxJQUFJLENBQUNoRSxRQUFRLENBQUNoQyxZQUFZLENBQUMsY0FBYyxFQUFFLElBQUksQ0FBQ2dDLFFBQVEsQ0FBQ2pMLFNBQVMsQ0FBQ2lQLE1BQU0sQ0FBQ0osbUJBQWlCLENBQUMsQ0FBQztJQUMvRjs7SUFFQTtJQUNBLE9BQU83TSxlQUFlQSxDQUFDaUksTUFBTSxFQUFFO01BQzdCLE9BQU8sSUFBSSxDQUFDc0UsSUFBSSxDQUFDLFlBQVk7UUFDM0IsTUFBTUMsSUFBSSxHQUFHUSxNQUFNLENBQUNyRCxtQkFBbUIsQ0FBQyxJQUFJLENBQUM7UUFFN0MsSUFBSTFCLE1BQU0sS0FBSyxRQUFRLEVBQUU7VUFDdkJ1RSxJQUFJLENBQUN2RSxNQUFNLENBQUMsRUFBRTtRQUNoQjtNQUNGLENBQUMsQ0FBQztJQUNKO0VBQ0Y7O0VBRUE7Ozs7RUFJQWxGLFlBQVksQ0FBQ2lDLEVBQUUsQ0FBQy9JLFFBQVEsRUFBRThRLHNCQUFvQixFQUFFRCxzQkFBb0IsRUFBRW5LLEtBQUssSUFBSTtJQUM3RUEsS0FBSyxDQUFDdUQsY0FBYyxFQUFFO0lBRXRCLE1BQU1nSCxNQUFNLEdBQUd2SyxLQUFLLENBQUMzQixNQUFNLENBQUN0RCxPQUFPLENBQUNvUCxzQkFBb0IsQ0FBQztJQUN6RCxNQUFNTixJQUFJLEdBQUdRLE1BQU0sQ0FBQ3JELG1CQUFtQixDQUFDdUQsTUFBTSxDQUFDO0lBRS9DVixJQUFJLENBQUNTLE1BQU0sRUFBRTtFQUNmLENBQUMsQ0FBQzs7RUFFRjs7OztFQUlBeE4sa0JBQWtCLENBQUN1TixNQUFNLENBQUM7O0VDckUxQjs7Ozs7OztFQVdBOzs7O0VBSUEsTUFBTUcsTUFBSSxHQUFHLE9BQU87RUFDcEIsTUFBTUMsV0FBUyxHQUFHLFdBQVc7RUFDN0IsTUFBTUMsZ0JBQWdCLEdBQUksYUFBWUQsV0FBVSxFQUFDO0VBQ2pELE1BQU1FLGVBQWUsR0FBSSxZQUFXRixXQUFVLEVBQUM7RUFDL0MsTUFBTUcsY0FBYyxHQUFJLFdBQVVILFdBQVUsRUFBQztFQUM3QyxNQUFNSSxpQkFBaUIsR0FBSSxjQUFhSixXQUFVLEVBQUM7RUFDbkQsTUFBTUssZUFBZSxHQUFJLFlBQVdMLFdBQVUsRUFBQztFQUMvQyxNQUFNTSxrQkFBa0IsR0FBRyxPQUFPO0VBQ2xDLE1BQU1DLGdCQUFnQixHQUFHLEtBQUs7RUFDOUIsTUFBTUMsd0JBQXdCLEdBQUcsZUFBZTtFQUNoRCxNQUFNQyxlQUFlLEdBQUcsRUFBRTtFQUUxQixNQUFNQyxTQUFPLEdBQUc7SUFDZEMsV0FBVyxFQUFFLElBQUk7SUFDakJDLFlBQVksRUFBRSxJQUFJO0lBQ2xCQyxhQUFhLEVBQUU7RUFDakIsQ0FBQztFQUVELE1BQU1DLGFBQVcsR0FBRztJQUNsQkgsV0FBVyxFQUFFLGlCQUFpQjtJQUM5QkMsWUFBWSxFQUFFLGlCQUFpQjtJQUMvQkMsYUFBYSxFQUFFO0VBQ2pCLENBQUM7O0VBRUQ7Ozs7RUFJQSxNQUFNRSxLQUFLLFNBQVN2RyxNQUFNLENBQUM7SUFDekJVLFdBQVdBLENBQUMzTyxPQUFPLEVBQUVzTyxNQUFNLEVBQUU7TUFDM0IsS0FBSyxFQUFFO01BQ1AsSUFBSSxDQUFDZ0IsUUFBUSxHQUFHdFAsT0FBTztNQUV2QixJQUFJLENBQUNBLE9BQU8sSUFBSSxDQUFDd1UsS0FBSyxDQUFDQyxXQUFXLEVBQUUsRUFBRTtRQUNwQztNQUNGO01BRUEsSUFBSSxDQUFDbEYsT0FBTyxHQUFHLElBQUksQ0FBQ2xCLFVBQVUsQ0FBQ0MsTUFBTSxDQUFDO01BQ3RDLElBQUksQ0FBQ29HLE9BQU8sR0FBRyxDQUFDO01BQ2hCLElBQUksQ0FBQ0MscUJBQXFCLEdBQUc3SixPQUFPLENBQUMzSixNQUFNLENBQUN5VCxZQUFZLENBQUM7TUFDekQsSUFBSSxDQUFDQyxXQUFXLEVBQUU7SUFDcEI7O0lBRUE7SUFDQSxXQUFXM0csT0FBT0EsQ0FBQSxFQUFHO01BQ25CLE9BQU9pRyxTQUFPO0lBQ2hCO0lBRUEsV0FBV2hHLFdBQVdBLENBQUEsRUFBRztNQUN2QixPQUFPb0csYUFBVztJQUNwQjtJQUVBLFdBQVdyTyxJQUFJQSxDQUFBLEVBQUc7TUFDaEIsT0FBT3NOLE1BQUk7SUFDYjs7SUFFQTtJQUNBL0QsT0FBT0EsQ0FBQSxFQUFHO01BQ1JyRyxZQUFZLENBQUNDLEdBQUcsQ0FBQyxJQUFJLENBQUNpRyxRQUFRLEVBQUVtRSxXQUFTLENBQUM7SUFDNUM7O0lBRUE7SUFDQXFCLE1BQU1BLENBQUM5TCxLQUFLLEVBQUU7TUFDWixJQUFJLENBQUMsSUFBSSxDQUFDMkwscUJBQXFCLEVBQUU7UUFDL0IsSUFBSSxDQUFDRCxPQUFPLEdBQUcxTCxLQUFLLENBQUMrTCxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUNDLE9BQU87UUFFdkM7TUFDRjtNQUVBLElBQUksSUFBSSxDQUFDQyx1QkFBdUIsQ0FBQ2pNLEtBQUssQ0FBQyxFQUFFO1FBQ3ZDLElBQUksQ0FBQzBMLE9BQU8sR0FBRzFMLEtBQUssQ0FBQ2dNLE9BQU87TUFDOUI7SUFDRjtJQUVBRSxJQUFJQSxDQUFDbE0sS0FBSyxFQUFFO01BQ1YsSUFBSSxJQUFJLENBQUNpTSx1QkFBdUIsQ0FBQ2pNLEtBQUssQ0FBQyxFQUFFO1FBQ3ZDLElBQUksQ0FBQzBMLE9BQU8sR0FBRzFMLEtBQUssQ0FBQ2dNLE9BQU8sR0FBRyxJQUFJLENBQUNOLE9BQU87TUFDN0M7TUFFQSxJQUFJLENBQUNTLFlBQVksRUFBRTtNQUNuQjNPLE9BQU8sQ0FBQyxJQUFJLENBQUMrSSxPQUFPLENBQUM2RSxXQUFXLENBQUM7SUFDbkM7SUFFQWdCLEtBQUtBLENBQUNwTSxLQUFLLEVBQUU7TUFDWCxJQUFJLENBQUMwTCxPQUFPLEdBQUcxTCxLQUFLLENBQUMrTCxPQUFPLElBQUkvTCxLQUFLLENBQUMrTCxPQUFPLENBQUN2UixNQUFNLEdBQUcsQ0FBQyxHQUN0RCxDQUFDLEdBQ0R3RixLQUFLLENBQUMrTCxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUNDLE9BQU8sR0FBRyxJQUFJLENBQUNOLE9BQU87SUFDM0M7SUFFQVMsWUFBWUEsQ0FBQSxFQUFHO01BQ2IsTUFBTUUsU0FBUyxHQUFHbFQsSUFBSSxDQUFDbVQsR0FBRyxDQUFDLElBQUksQ0FBQ1osT0FBTyxDQUFDO01BRXhDLElBQUlXLFNBQVMsSUFBSW5CLGVBQWUsRUFBRTtRQUNoQztNQUNGO01BRUEsTUFBTXFCLFNBQVMsR0FBR0YsU0FBUyxHQUFHLElBQUksQ0FBQ1gsT0FBTztNQUUxQyxJQUFJLENBQUNBLE9BQU8sR0FBRyxDQUFDO01BRWhCLElBQUksQ0FBQ2EsU0FBUyxFQUFFO1FBQ2Q7TUFDRjtNQUVBL08sT0FBTyxDQUFDK08sU0FBUyxHQUFHLENBQUMsR0FBRyxJQUFJLENBQUNoRyxPQUFPLENBQUMrRSxhQUFhLEdBQUcsSUFBSSxDQUFDL0UsT0FBTyxDQUFDOEUsWUFBWSxDQUFDO0lBQ2pGO0lBRUFRLFdBQVdBLENBQUEsRUFBRztNQUNaLElBQUksSUFBSSxDQUFDRixxQkFBcUIsRUFBRTtRQUM5QnZMLFlBQVksQ0FBQ2lDLEVBQUUsQ0FBQyxJQUFJLENBQUNpRSxRQUFRLEVBQUV1RSxpQkFBaUIsRUFBRTdLLEtBQUssSUFBSSxJQUFJLENBQUM4TCxNQUFNLENBQUM5TCxLQUFLLENBQUMsQ0FBQztRQUM5RUksWUFBWSxDQUFDaUMsRUFBRSxDQUFDLElBQUksQ0FBQ2lFLFFBQVEsRUFBRXdFLGVBQWUsRUFBRTlLLEtBQUssSUFBSSxJQUFJLENBQUNrTSxJQUFJLENBQUNsTSxLQUFLLENBQUMsQ0FBQztRQUUxRSxJQUFJLENBQUNzRyxRQUFRLENBQUNqTCxTQUFTLENBQUNtUixHQUFHLENBQUN2Qix3QkFBd0IsQ0FBQztNQUN2RCxDQUFDLE1BQU07UUFDTDdLLFlBQVksQ0FBQ2lDLEVBQUUsQ0FBQyxJQUFJLENBQUNpRSxRQUFRLEVBQUVvRSxnQkFBZ0IsRUFBRTFLLEtBQUssSUFBSSxJQUFJLENBQUM4TCxNQUFNLENBQUM5TCxLQUFLLENBQUMsQ0FBQztRQUM3RUksWUFBWSxDQUFDaUMsRUFBRSxDQUFDLElBQUksQ0FBQ2lFLFFBQVEsRUFBRXFFLGVBQWUsRUFBRTNLLEtBQUssSUFBSSxJQUFJLENBQUNvTSxLQUFLLENBQUNwTSxLQUFLLENBQUMsQ0FBQztRQUMzRUksWUFBWSxDQUFDaUMsRUFBRSxDQUFDLElBQUksQ0FBQ2lFLFFBQVEsRUFBRXNFLGNBQWMsRUFBRTVLLEtBQUssSUFBSSxJQUFJLENBQUNrTSxJQUFJLENBQUNsTSxLQUFLLENBQUMsQ0FBQztNQUMzRTtJQUNGO0lBRUFpTSx1QkFBdUJBLENBQUNqTSxLQUFLLEVBQUU7TUFDN0IsT0FBTyxJQUFJLENBQUMyTCxxQkFBcUIsS0FBSzNMLEtBQUssQ0FBQ3lNLFdBQVcsS0FBS3pCLGdCQUFnQixJQUFJaEwsS0FBSyxDQUFDeU0sV0FBVyxLQUFLMUIsa0JBQWtCLENBQUM7SUFDM0g7O0lBRUE7SUFDQSxPQUFPVSxXQUFXQSxDQUFBLEVBQUc7TUFDbkIsT0FBTyxjQUFjLElBQUluUyxRQUFRLENBQUNxQyxlQUFlLElBQUkrUSxTQUFTLENBQUNDLGNBQWMsR0FBRyxDQUFDO0lBQ25GO0VBQ0Y7O0VDL0lBOzs7Ozs7O0VBcUJBOzs7O0VBSUEsTUFBTUMsTUFBSSxHQUFHLFVBQVU7RUFDdkIsTUFBTUMsVUFBUSxHQUFHLGFBQWE7RUFDOUIsTUFBTUMsV0FBUyxHQUFJLElBQUdELFVBQVMsRUFBQztFQUNoQyxNQUFNRSxjQUFZLEdBQUcsV0FBVztFQUVoQyxNQUFNQyxnQkFBYyxHQUFHLFdBQVc7RUFDbEMsTUFBTUMsaUJBQWUsR0FBRyxZQUFZO0VBQ3BDLE1BQU1DLHNCQUFzQixHQUFHLEdBQUcsQ0FBQzs7RUFFbkMsTUFBTUMsVUFBVSxHQUFHLE1BQU07RUFDekIsTUFBTUMsVUFBVSxHQUFHLE1BQU07RUFDekIsTUFBTUMsY0FBYyxHQUFHLE1BQU07RUFDN0IsTUFBTUMsZUFBZSxHQUFHLE9BQU87RUFFL0IsTUFBTUMsV0FBVyxHQUFJLFFBQU9ULFdBQVUsRUFBQztFQUN2QyxNQUFNVSxVQUFVLEdBQUksT0FBTVYsV0FBVSxFQUFDO0VBQ3JDLE1BQU1XLGVBQWEsR0FBSSxVQUFTWCxXQUFVLEVBQUM7RUFDM0MsTUFBTVksa0JBQWdCLEdBQUksYUFBWVosV0FBVSxFQUFDO0VBQ2pELE1BQU1hLGtCQUFnQixHQUFJLGFBQVliLFdBQVUsRUFBQztFQUNqRCxNQUFNYyxnQkFBZ0IsR0FBSSxZQUFXZCxXQUFVLEVBQUM7RUFDaEQsTUFBTWUscUJBQW1CLEdBQUksT0FBTWYsV0FBVSxHQUFFQyxjQUFhLEVBQUM7RUFDN0QsTUFBTWUsc0JBQW9CLEdBQUksUUFBT2hCLFdBQVUsR0FBRUMsY0FBYSxFQUFDO0VBRS9ELE1BQU1nQixtQkFBbUIsR0FBRyxVQUFVO0VBQ3RDLE1BQU1DLG1CQUFpQixHQUFHLFFBQVE7RUFDbEMsTUFBTUMsZ0JBQWdCLEdBQUcsT0FBTztFQUNoQyxNQUFNQyxjQUFjLEdBQUcsbUJBQW1CO0VBQzFDLE1BQU1DLGdCQUFnQixHQUFHLHFCQUFxQjtFQUM5QyxNQUFNQyxlQUFlLEdBQUcsb0JBQW9CO0VBQzVDLE1BQU1DLGVBQWUsR0FBRyxvQkFBb0I7RUFFNUMsTUFBTUMsZUFBZSxHQUFHLFNBQVM7RUFDakMsTUFBTUMsYUFBYSxHQUFHLGdCQUFnQjtFQUN0QyxNQUFNQyxvQkFBb0IsR0FBR0YsZUFBZSxHQUFHQyxhQUFhO0VBQzVELE1BQU1FLGlCQUFpQixHQUFHLG9CQUFvQjtFQUM5QyxNQUFNQyxtQkFBbUIsR0FBRyxzQkFBc0I7RUFDbEQsTUFBTUMsbUJBQW1CLEdBQUcscUNBQXFDO0VBQ2pFLE1BQU1DLGtCQUFrQixHQUFHLDJCQUEyQjtFQUV0RCxNQUFNQyxnQkFBZ0IsR0FBRztJQUN2QixDQUFDN0IsZ0JBQWMsR0FBR00sZUFBZTtJQUNqQyxDQUFDTCxpQkFBZSxHQUFHSTtFQUNyQixDQUFDO0VBRUQsTUFBTXlCLFNBQU8sR0FBRztJQUNkQyxRQUFRLEVBQUUsSUFBSTtJQUNkQyxRQUFRLEVBQUUsSUFBSTtJQUNkQyxLQUFLLEVBQUUsT0FBTztJQUNkQyxJQUFJLEVBQUUsS0FBSztJQUNYQyxLQUFLLEVBQUUsSUFBSTtJQUNYQyxJQUFJLEVBQUU7RUFDUixDQUFDO0VBRUQsTUFBTUMsYUFBVyxHQUFHO0lBQ2xCTixRQUFRLEVBQUUsa0JBQWtCO0lBQUU7SUFDOUJDLFFBQVEsRUFBRSxTQUFTO0lBQ25CQyxLQUFLLEVBQUUsa0JBQWtCO0lBQ3pCQyxJQUFJLEVBQUUsa0JBQWtCO0lBQ3hCQyxLQUFLLEVBQUUsU0FBUztJQUNoQkMsSUFBSSxFQUFFO0VBQ1IsQ0FBQzs7RUFFRDs7OztFQUlBLE1BQU1FLFFBQVEsU0FBU2pKLGFBQWEsQ0FBQztJQUNuQ1YsV0FBV0EsQ0FBQzNPLE9BQU8sRUFBRXNPLE1BQU0sRUFBRTtNQUMzQixLQUFLLENBQUN0TyxPQUFPLEVBQUVzTyxNQUFNLENBQUM7TUFFdEIsSUFBSSxDQUFDaUssU0FBUyxHQUFHLElBQUk7TUFDckIsSUFBSSxDQUFDQyxjQUFjLEdBQUcsSUFBSTtNQUMxQixJQUFJLENBQUNDLFVBQVUsR0FBRyxLQUFLO01BQ3ZCLElBQUksQ0FBQ0MsWUFBWSxHQUFHLElBQUk7TUFDeEIsSUFBSSxDQUFDQyxZQUFZLEdBQUcsSUFBSTtNQUV4QixJQUFJLENBQUNDLGtCQUFrQixHQUFHcEksY0FBYyxDQUFDRyxPQUFPLENBQUMrRyxtQkFBbUIsRUFBRSxJQUFJLENBQUNwSSxRQUFRLENBQUM7TUFDcEYsSUFBSSxDQUFDdUosa0JBQWtCLEVBQUU7TUFFekIsSUFBSSxJQUFJLENBQUN0SixPQUFPLENBQUMySSxJQUFJLEtBQUtuQixtQkFBbUIsRUFBRTtRQUM3QyxJQUFJLENBQUMrQixLQUFLLEVBQUU7TUFDZDtJQUNGOztJQUVBO0lBQ0EsV0FBVzVLLE9BQU9BLENBQUEsRUFBRztNQUNuQixPQUFPNEosU0FBTztJQUNoQjtJQUVBLFdBQVczSixXQUFXQSxDQUFBLEVBQUc7TUFDdkIsT0FBT2tLLGFBQVc7SUFDcEI7SUFFQSxXQUFXblMsSUFBSUEsQ0FBQSxFQUFHO01BQ2hCLE9BQU8wUCxNQUFJO0lBQ2I7O0lBRUE7SUFDQXhFLElBQUlBLENBQUEsRUFBRztNQUNMLElBQUksQ0FBQzJILE1BQU0sQ0FBQzVDLFVBQVUsQ0FBQztJQUN6QjtJQUVBNkMsZUFBZUEsQ0FBQSxFQUFHO01BQ2hCO01BQ0E7TUFDQTtNQUNBLElBQUksQ0FBQzFXLFFBQVEsQ0FBQzJXLE1BQU0sSUFBSXZWLFNBQVMsQ0FBQyxJQUFJLENBQUM0TCxRQUFRLENBQUMsRUFBRTtRQUNoRCxJQUFJLENBQUM4QixJQUFJLEVBQUU7TUFDYjtJQUNGO0lBRUFILElBQUlBLENBQUEsRUFBRztNQUNMLElBQUksQ0FBQzhILE1BQU0sQ0FBQzNDLFVBQVUsQ0FBQztJQUN6QjtJQUVBNkIsS0FBS0EsQ0FBQSxFQUFHO01BQ04sSUFBSSxJQUFJLENBQUNRLFVBQVUsRUFBRTtRQUNuQnhWLG9CQUFvQixDQUFDLElBQUksQ0FBQ3FNLFFBQVEsQ0FBQztNQUNyQztNQUVBLElBQUksQ0FBQzRKLGNBQWMsRUFBRTtJQUN2QjtJQUVBSixLQUFLQSxDQUFBLEVBQUc7TUFDTixJQUFJLENBQUNJLGNBQWMsRUFBRTtNQUNyQixJQUFJLENBQUNDLGVBQWUsRUFBRTtNQUV0QixJQUFJLENBQUNaLFNBQVMsR0FBR2EsV0FBVyxDQUFDLE1BQU0sSUFBSSxDQUFDSixlQUFlLEVBQUUsRUFBRSxJQUFJLENBQUN6SixPQUFPLENBQUN3SSxRQUFRLENBQUM7SUFDbkY7SUFFQXNCLGlCQUFpQkEsQ0FBQSxFQUFHO01BQ2xCLElBQUksQ0FBQyxJQUFJLENBQUM5SixPQUFPLENBQUMySSxJQUFJLEVBQUU7UUFDdEI7TUFDRjtNQUVBLElBQUksSUFBSSxDQUFDTyxVQUFVLEVBQUU7UUFDbkJyUCxZQUFZLENBQUNrQyxHQUFHLENBQUMsSUFBSSxDQUFDZ0UsUUFBUSxFQUFFa0gsVUFBVSxFQUFFLE1BQU0sSUFBSSxDQUFDc0MsS0FBSyxFQUFFLENBQUM7UUFDL0Q7TUFDRjtNQUVBLElBQUksQ0FBQ0EsS0FBSyxFQUFFO0lBQ2Q7SUFFQVEsRUFBRUEsQ0FBQ3hSLEtBQUssRUFBRTtNQUNSLE1BQU15UixLQUFLLEdBQUcsSUFBSSxDQUFDQyxTQUFTLEVBQUU7TUFDOUIsSUFBSTFSLEtBQUssR0FBR3lSLEtBQUssQ0FBQy9WLE1BQU0sR0FBRyxDQUFDLElBQUlzRSxLQUFLLEdBQUcsQ0FBQyxFQUFFO1FBQ3pDO01BQ0Y7TUFFQSxJQUFJLElBQUksQ0FBQzJRLFVBQVUsRUFBRTtRQUNuQnJQLFlBQVksQ0FBQ2tDLEdBQUcsQ0FBQyxJQUFJLENBQUNnRSxRQUFRLEVBQUVrSCxVQUFVLEVBQUUsTUFBTSxJQUFJLENBQUM4QyxFQUFFLENBQUN4UixLQUFLLENBQUMsQ0FBQztRQUNqRTtNQUNGO01BRUEsTUFBTTJSLFdBQVcsR0FBRyxJQUFJLENBQUNDLGFBQWEsQ0FBQyxJQUFJLENBQUNDLFVBQVUsRUFBRSxDQUFDO01BQ3pELElBQUlGLFdBQVcsS0FBSzNSLEtBQUssRUFBRTtRQUN6QjtNQUNGO01BRUEsTUFBTThSLEtBQUssR0FBRzlSLEtBQUssR0FBRzJSLFdBQVcsR0FBR3RELFVBQVUsR0FBR0MsVUFBVTtNQUUzRCxJQUFJLENBQUMyQyxNQUFNLENBQUNhLEtBQUssRUFBRUwsS0FBSyxDQUFDelIsS0FBSyxDQUFDLENBQUM7SUFDbEM7SUFFQTJILE9BQU9BLENBQUEsRUFBRztNQUNSLElBQUksSUFBSSxDQUFDa0osWUFBWSxFQUFFO1FBQ3JCLElBQUksQ0FBQ0EsWUFBWSxDQUFDbEosT0FBTyxFQUFFO01BQzdCO01BRUEsS0FBSyxDQUFDQSxPQUFPLEVBQUU7SUFDakI7O0lBRUE7SUFDQWpCLGlCQUFpQkEsQ0FBQ0YsTUFBTSxFQUFFO01BQ3hCQSxNQUFNLENBQUN1TCxlQUFlLEdBQUd2TCxNQUFNLENBQUN5SixRQUFRO01BQ3hDLE9BQU96SixNQUFNO0lBQ2Y7SUFFQXVLLGtCQUFrQkEsQ0FBQSxFQUFHO01BQ25CLElBQUksSUFBSSxDQUFDdEosT0FBTyxDQUFDeUksUUFBUSxFQUFFO1FBQ3pCNU8sWUFBWSxDQUFDaUMsRUFBRSxDQUFDLElBQUksQ0FBQ2lFLFFBQVEsRUFBRW1ILGVBQWEsRUFBRXpOLEtBQUssSUFBSSxJQUFJLENBQUM4USxRQUFRLENBQUM5USxLQUFLLENBQUMsQ0FBQztNQUM5RTtNQUVBLElBQUksSUFBSSxDQUFDdUcsT0FBTyxDQUFDMEksS0FBSyxLQUFLLE9BQU8sRUFBRTtRQUNsQzdPLFlBQVksQ0FBQ2lDLEVBQUUsQ0FBQyxJQUFJLENBQUNpRSxRQUFRLEVBQUVvSCxrQkFBZ0IsRUFBRSxNQUFNLElBQUksQ0FBQ3VCLEtBQUssRUFBRSxDQUFDO1FBQ3BFN08sWUFBWSxDQUFDaUMsRUFBRSxDQUFDLElBQUksQ0FBQ2lFLFFBQVEsRUFBRXFILGtCQUFnQixFQUFFLE1BQU0sSUFBSSxDQUFDMEMsaUJBQWlCLEVBQUUsQ0FBQztNQUNsRjtNQUVBLElBQUksSUFBSSxDQUFDOUosT0FBTyxDQUFDNEksS0FBSyxJQUFJM0QsS0FBSyxDQUFDQyxXQUFXLEVBQUUsRUFBRTtRQUM3QyxJQUFJLENBQUNzRix1QkFBdUIsRUFBRTtNQUNoQztJQUNGO0lBRUFBLHVCQUF1QkEsQ0FBQSxFQUFHO01BQ3hCLEtBQUssTUFBTUMsR0FBRyxJQUFJeEosY0FBYyxDQUFDdkcsSUFBSSxDQUFDd04saUJBQWlCLEVBQUUsSUFBSSxDQUFDbkksUUFBUSxDQUFDLEVBQUU7UUFDdkVsRyxZQUFZLENBQUNpQyxFQUFFLENBQUMyTyxHQUFHLEVBQUVwRCxnQkFBZ0IsRUFBRTVOLEtBQUssSUFBSUEsS0FBSyxDQUFDdUQsY0FBYyxFQUFFLENBQUM7TUFDekU7TUFFQSxNQUFNME4sV0FBVyxHQUFHQSxDQUFBLEtBQU07UUFDeEIsSUFBSSxJQUFJLENBQUMxSyxPQUFPLENBQUMwSSxLQUFLLEtBQUssT0FBTyxFQUFFO1VBQ2xDO1FBQ0Y7O1FBRUE7UUFDQTtRQUNBO1FBQ0E7UUFDQTtRQUNBO1FBQ0E7O1FBRUEsSUFBSSxDQUFDQSxLQUFLLEVBQUU7UUFDWixJQUFJLElBQUksQ0FBQ1MsWUFBWSxFQUFFO1VBQ3JCd0IsWUFBWSxDQUFDLElBQUksQ0FBQ3hCLFlBQVksQ0FBQztRQUNqQztRQUVBLElBQUksQ0FBQ0EsWUFBWSxHQUFHblIsVUFBVSxDQUFDLE1BQU0sSUFBSSxDQUFDOFIsaUJBQWlCLEVBQUUsRUFBRW5ELHNCQUFzQixHQUFHLElBQUksQ0FBQzNHLE9BQU8sQ0FBQ3dJLFFBQVEsQ0FBQztPQUMvRztNQUVELE1BQU1vQyxXQUFXLEdBQUc7UUFDbEI5RixZQUFZLEVBQUVBLENBQUEsS0FBTSxJQUFJLENBQUMwRSxNQUFNLENBQUMsSUFBSSxDQUFDcUIsaUJBQWlCLENBQUMvRCxjQUFjLENBQUMsQ0FBQztRQUN2RS9CLGFBQWEsRUFBRUEsQ0FBQSxLQUFNLElBQUksQ0FBQ3lFLE1BQU0sQ0FBQyxJQUFJLENBQUNxQixpQkFBaUIsQ0FBQzlELGVBQWUsQ0FBQyxDQUFDO1FBQ3pFbEMsV0FBVyxFQUFFNkY7T0FDZDtNQUVELElBQUksQ0FBQ3RCLFlBQVksR0FBRyxJQUFJbkUsS0FBSyxDQUFDLElBQUksQ0FBQ2xGLFFBQVEsRUFBRTZLLFdBQVcsQ0FBQztJQUMzRDtJQUVBTCxRQUFRQSxDQUFDOVEsS0FBSyxFQUFFO01BQ2QsSUFBSSxpQkFBaUIsQ0FBQ2lHLElBQUksQ0FBQ2pHLEtBQUssQ0FBQzNCLE1BQU0sQ0FBQzJLLE9BQU8sQ0FBQyxFQUFFO1FBQ2hEO01BQ0Y7TUFFQSxNQUFNdUQsU0FBUyxHQUFHc0MsZ0JBQWdCLENBQUM3TyxLQUFLLENBQUMvSSxHQUFHLENBQUM7TUFDN0MsSUFBSXNWLFNBQVMsRUFBRTtRQUNidk0sS0FBSyxDQUFDdUQsY0FBYyxFQUFFO1FBQ3RCLElBQUksQ0FBQ3dNLE1BQU0sQ0FBQyxJQUFJLENBQUNxQixpQkFBaUIsQ0FBQzdFLFNBQVMsQ0FBQyxDQUFDO01BQ2hEO0lBQ0Y7SUFFQW1FLGFBQWFBLENBQUMxWixPQUFPLEVBQUU7TUFDckIsT0FBTyxJQUFJLENBQUN3WixTQUFTLEVBQUUsQ0FBQ3pSLE9BQU8sQ0FBQy9ILE9BQU8sQ0FBQztJQUMxQztJQUVBcWEsMEJBQTBCQSxDQUFDdlMsS0FBSyxFQUFFO01BQ2hDLElBQUksQ0FBQyxJQUFJLENBQUM4USxrQkFBa0IsRUFBRTtRQUM1QjtNQUNGO01BRUEsTUFBTTBCLGVBQWUsR0FBRzlKLGNBQWMsQ0FBQ0csT0FBTyxDQUFDMkcsZUFBZSxFQUFFLElBQUksQ0FBQ3NCLGtCQUFrQixDQUFDO01BRXhGMEIsZUFBZSxDQUFDalcsU0FBUyxDQUFDekQsTUFBTSxDQUFDb1csbUJBQWlCLENBQUM7TUFDbkRzRCxlQUFlLENBQUM5TSxlQUFlLENBQUMsY0FBYyxDQUFDO01BRS9DLE1BQU0rTSxrQkFBa0IsR0FBRy9KLGNBQWMsQ0FBQ0csT0FBTyxDQUFFLHNCQUFxQjdJLEtBQU0sSUFBRyxFQUFFLElBQUksQ0FBQzhRLGtCQUFrQixDQUFDO01BRTNHLElBQUkyQixrQkFBa0IsRUFBRTtRQUN0QkEsa0JBQWtCLENBQUNsVyxTQUFTLENBQUNtUixHQUFHLENBQUN3QixtQkFBaUIsQ0FBQztRQUNuRHVELGtCQUFrQixDQUFDak4sWUFBWSxDQUFDLGNBQWMsRUFBRSxNQUFNLENBQUM7TUFDekQ7SUFDRjtJQUVBNkwsZUFBZUEsQ0FBQSxFQUFHO01BQ2hCLE1BQU1uWixPQUFPLEdBQUcsSUFBSSxDQUFDd1ksY0FBYyxJQUFJLElBQUksQ0FBQ21CLFVBQVUsRUFBRTtNQUV4RCxJQUFJLENBQUMzWixPQUFPLEVBQUU7UUFDWjtNQUNGO01BRUEsTUFBTXdhLGVBQWUsR0FBRzNYLE1BQU0sQ0FBQzRYLFFBQVEsQ0FBQ3phLE9BQU8sQ0FBQ3lFLFlBQVksQ0FBQyxrQkFBa0IsQ0FBQyxFQUFFLEVBQUUsQ0FBQztNQUVyRixJQUFJLENBQUM4SyxPQUFPLENBQUN3SSxRQUFRLEdBQUd5QyxlQUFlLElBQUksSUFBSSxDQUFDakwsT0FBTyxDQUFDc0ssZUFBZTtJQUN6RTtJQUVBZCxNQUFNQSxDQUFDYSxLQUFLLEVBQWtCO01BQUEsSUFBaEI1WixPQUFPLEdBQUEyRyxTQUFBLENBQUFuRCxNQUFBLFFBQUFtRCxTQUFBLFFBQUFoRixTQUFBLEdBQUFnRixTQUFBLE1BQUcsSUFBSTtNQUMxQixJQUFJLElBQUksQ0FBQzhSLFVBQVUsRUFBRTtRQUNuQjtNQUNGO01BRUEsTUFBTS9RLGFBQWEsR0FBRyxJQUFJLENBQUNpUyxVQUFVLEVBQUU7TUFDdkMsTUFBTWUsTUFBTSxHQUFHZCxLQUFLLEtBQUt6RCxVQUFVO01BQ25DLE1BQU13RSxXQUFXLEdBQUczYSxPQUFPLElBQUl3SCxvQkFBb0IsQ0FBQyxJQUFJLENBQUNnUyxTQUFTLEVBQUUsRUFBRTlSLGFBQWEsRUFBRWdULE1BQU0sRUFBRSxJQUFJLENBQUNuTCxPQUFPLENBQUM2SSxJQUFJLENBQUM7TUFFL0csSUFBSXVDLFdBQVcsS0FBS2pULGFBQWEsRUFBRTtRQUNqQztNQUNGO01BRUEsTUFBTWtULGdCQUFnQixHQUFHLElBQUksQ0FBQ2xCLGFBQWEsQ0FBQ2lCLFdBQVcsQ0FBQztNQUV4RCxNQUFNRSxZQUFZLEdBQUc1SyxTQUFTLElBQUk7UUFDaEMsT0FBTzdHLFlBQVksQ0FBQ3lDLE9BQU8sQ0FBQyxJQUFJLENBQUN5RCxRQUFRLEVBQUVXLFNBQVMsRUFBRTtVQUNwRHZGLGFBQWEsRUFBRWlRLFdBQVc7VUFDMUJwRixTQUFTLEVBQUUsSUFBSSxDQUFDdUYsaUJBQWlCLENBQUNsQixLQUFLLENBQUM7VUFDeENsWixJQUFJLEVBQUUsSUFBSSxDQUFDZ1osYUFBYSxDQUFDaFMsYUFBYSxDQUFDO1VBQ3ZDNFIsRUFBRSxFQUFFc0I7UUFDTixDQUFDLENBQUM7T0FDSDtNQUVELE1BQU1HLFVBQVUsR0FBR0YsWUFBWSxDQUFDdEUsV0FBVyxDQUFDO01BRTVDLElBQUl3RSxVQUFVLENBQUM5TyxnQkFBZ0IsRUFBRTtRQUMvQjtNQUNGO01BRUEsSUFBSSxDQUFDdkUsYUFBYSxJQUFJLENBQUNpVCxXQUFXLEVBQUU7UUFDbEM7UUFDQTtRQUNBO01BQ0Y7TUFFQSxNQUFNSyxTQUFTLEdBQUdsUSxPQUFPLENBQUMsSUFBSSxDQUFDeU4sU0FBUyxDQUFDO01BQ3pDLElBQUksQ0FBQ04sS0FBSyxFQUFFO01BRVosSUFBSSxDQUFDUSxVQUFVLEdBQUcsSUFBSTtNQUV0QixJQUFJLENBQUM0QiwwQkFBMEIsQ0FBQ08sZ0JBQWdCLENBQUM7TUFDakQsSUFBSSxDQUFDcEMsY0FBYyxHQUFHbUMsV0FBVztNQUVqQyxNQUFNTSxvQkFBb0IsR0FBR1AsTUFBTSxHQUFHdkQsZ0JBQWdCLEdBQUdELGNBQWM7TUFDdkUsTUFBTWdFLGNBQWMsR0FBR1IsTUFBTSxHQUFHdEQsZUFBZSxHQUFHQyxlQUFlO01BRWpFc0QsV0FBVyxDQUFDdFcsU0FBUyxDQUFDbVIsR0FBRyxDQUFDMEYsY0FBYyxDQUFDO01BRXpDalcsTUFBTSxDQUFDMFYsV0FBVyxDQUFDO01BRW5CalQsYUFBYSxDQUFDckQsU0FBUyxDQUFDbVIsR0FBRyxDQUFDeUYsb0JBQW9CLENBQUM7TUFDakROLFdBQVcsQ0FBQ3RXLFNBQVMsQ0FBQ21SLEdBQUcsQ0FBQ3lGLG9CQUFvQixDQUFDO01BRS9DLE1BQU1FLGdCQUFnQixHQUFHQSxDQUFBLEtBQU07UUFDN0JSLFdBQVcsQ0FBQ3RXLFNBQVMsQ0FBQ3pELE1BQU0sQ0FBQ3FhLG9CQUFvQixFQUFFQyxjQUFjLENBQUM7UUFDbEVQLFdBQVcsQ0FBQ3RXLFNBQVMsQ0FBQ21SLEdBQUcsQ0FBQ3dCLG1CQUFpQixDQUFDO1FBRTVDdFAsYUFBYSxDQUFDckQsU0FBUyxDQUFDekQsTUFBTSxDQUFDb1csbUJBQWlCLEVBQUVrRSxjQUFjLEVBQUVELG9CQUFvQixDQUFDO1FBRXZGLElBQUksQ0FBQ3hDLFVBQVUsR0FBRyxLQUFLO1FBRXZCb0MsWUFBWSxDQUFDckUsVUFBVSxDQUFDO09BQ3pCO01BRUQsSUFBSSxDQUFDM0csY0FBYyxDQUFDc0wsZ0JBQWdCLEVBQUV6VCxhQUFhLEVBQUUsSUFBSSxDQUFDMFQsV0FBVyxFQUFFLENBQUM7TUFFeEUsSUFBSUosU0FBUyxFQUFFO1FBQ2IsSUFBSSxDQUFDbEMsS0FBSyxFQUFFO01BQ2Q7SUFDRjtJQUVBc0MsV0FBV0EsQ0FBQSxFQUFHO01BQ1osT0FBTyxJQUFJLENBQUM5TCxRQUFRLENBQUNqTCxTQUFTLENBQUNDLFFBQVEsQ0FBQzJTLGdCQUFnQixDQUFDO0lBQzNEO0lBRUEwQyxVQUFVQSxDQUFBLEVBQUc7TUFDWCxPQUFPbkosY0FBYyxDQUFDRyxPQUFPLENBQUM2RyxvQkFBb0IsRUFBRSxJQUFJLENBQUNsSSxRQUFRLENBQUM7SUFDcEU7SUFFQWtLLFNBQVNBLENBQUEsRUFBRztNQUNWLE9BQU9oSixjQUFjLENBQUN2RyxJQUFJLENBQUNzTixhQUFhLEVBQUUsSUFBSSxDQUFDakksUUFBUSxDQUFDO0lBQzFEO0lBRUE0SixjQUFjQSxDQUFBLEVBQUc7TUFDZixJQUFJLElBQUksQ0FBQ1gsU0FBUyxFQUFFO1FBQ2xCOEMsYUFBYSxDQUFDLElBQUksQ0FBQzlDLFNBQVMsQ0FBQztRQUM3QixJQUFJLENBQUNBLFNBQVMsR0FBRyxJQUFJO01BQ3ZCO0lBQ0Y7SUFFQTZCLGlCQUFpQkEsQ0FBQzdFLFNBQVMsRUFBRTtNQUMzQixJQUFJM1AsS0FBSyxFQUFFLEVBQUU7UUFDWCxPQUFPMlAsU0FBUyxLQUFLYyxjQUFjLEdBQUdELFVBQVUsR0FBR0QsVUFBVTtNQUMvRDtNQUVBLE9BQU9aLFNBQVMsS0FBS2MsY0FBYyxHQUFHRixVQUFVLEdBQUdDLFVBQVU7SUFDL0Q7SUFFQTBFLGlCQUFpQkEsQ0FBQ2xCLEtBQUssRUFBRTtNQUN2QixJQUFJaFUsS0FBSyxFQUFFLEVBQUU7UUFDWCxPQUFPZ1UsS0FBSyxLQUFLeEQsVUFBVSxHQUFHQyxjQUFjLEdBQUdDLGVBQWU7TUFDaEU7TUFFQSxPQUFPc0QsS0FBSyxLQUFLeEQsVUFBVSxHQUFHRSxlQUFlLEdBQUdELGNBQWM7SUFDaEU7O0lBRUE7SUFDQSxPQUFPaFEsZUFBZUEsQ0FBQ2lJLE1BQU0sRUFBRTtNQUM3QixPQUFPLElBQUksQ0FBQ3NFLElBQUksQ0FBQyxZQUFZO1FBQzNCLE1BQU1DLElBQUksR0FBR3lGLFFBQVEsQ0FBQ3RJLG1CQUFtQixDQUFDLElBQUksRUFBRTFCLE1BQU0sQ0FBQztRQUV2RCxJQUFJLE9BQU9BLE1BQU0sS0FBSyxRQUFRLEVBQUU7VUFDOUJ1RSxJQUFJLENBQUN5RyxFQUFFLENBQUNoTCxNQUFNLENBQUM7VUFDZjtRQUNGO1FBRUEsSUFBSSxPQUFPQSxNQUFNLEtBQUssUUFBUSxFQUFFO1VBQzlCLElBQUl1RSxJQUFJLENBQUN2RSxNQUFNLENBQUMsS0FBSzNNLFNBQVMsSUFBSTJNLE1BQU0sQ0FBQzdDLFVBQVUsQ0FBQyxHQUFHLENBQUMsSUFBSTZDLE1BQU0sS0FBSyxhQUFhLEVBQUU7WUFDcEYsTUFBTSxJQUFJWSxTQUFTLENBQUUsb0JBQW1CWixNQUFPLEdBQUUsQ0FBQztVQUNwRDtVQUVBdUUsSUFBSSxDQUFDdkUsTUFBTSxDQUFDLEVBQUU7UUFDaEI7TUFDRixDQUFDLENBQUM7SUFDSjtFQUNGOztFQUVBOzs7O0VBSUFsRixZQUFZLENBQUNpQyxFQUFFLENBQUMvSSxRQUFRLEVBQUV3VSxzQkFBb0IsRUFBRWEsbUJBQW1CLEVBQUUsVUFBVTNPLEtBQUssRUFBRTtJQUNwRixNQUFNM0IsTUFBTSxHQUFHbUosY0FBYyxDQUFDa0Isc0JBQXNCLENBQUMsSUFBSSxDQUFDO0lBRTFELElBQUksQ0FBQ3JLLE1BQU0sSUFBSSxDQUFDQSxNQUFNLENBQUNoRCxTQUFTLENBQUNDLFFBQVEsQ0FBQ3lTLG1CQUFtQixDQUFDLEVBQUU7TUFDOUQ7SUFDRjtJQUVBL04sS0FBSyxDQUFDdUQsY0FBYyxFQUFFO0lBRXRCLE1BQU0rTyxRQUFRLEdBQUdoRCxRQUFRLENBQUN0SSxtQkFBbUIsQ0FBQzNJLE1BQU0sQ0FBQztJQUNyRCxNQUFNa1UsVUFBVSxHQUFHLElBQUksQ0FBQzlXLFlBQVksQ0FBQyxrQkFBa0IsQ0FBQztJQUV4RCxJQUFJOFcsVUFBVSxFQUFFO01BQ2RELFFBQVEsQ0FBQ2hDLEVBQUUsQ0FBQ2lDLFVBQVUsQ0FBQztNQUN2QkQsUUFBUSxDQUFDakMsaUJBQWlCLEVBQUU7TUFDNUI7SUFDRjtJQUVBLElBQUlqTSxXQUFXLENBQUNZLGdCQUFnQixDQUFDLElBQUksRUFBRSxPQUFPLENBQUMsS0FBSyxNQUFNLEVBQUU7TUFDMURzTixRQUFRLENBQUNsSyxJQUFJLEVBQUU7TUFDZmtLLFFBQVEsQ0FBQ2pDLGlCQUFpQixFQUFFO01BQzVCO0lBQ0Y7SUFFQWlDLFFBQVEsQ0FBQ3JLLElBQUksRUFBRTtJQUNmcUssUUFBUSxDQUFDakMsaUJBQWlCLEVBQUU7RUFDOUIsQ0FBQyxDQUFDO0VBRUZqUSxZQUFZLENBQUNpQyxFQUFFLENBQUNsSyxNQUFNLEVBQUUwVixxQkFBbUIsRUFBRSxNQUFNO0lBQ2pELE1BQU0yRSxTQUFTLEdBQUdoTCxjQUFjLENBQUN2RyxJQUFJLENBQUMyTixrQkFBa0IsQ0FBQztJQUV6RCxLQUFLLE1BQU0wRCxRQUFRLElBQUlFLFNBQVMsRUFBRTtNQUNoQ2xELFFBQVEsQ0FBQ3RJLG1CQUFtQixDQUFDc0wsUUFBUSxDQUFDO0lBQ3hDO0VBQ0YsQ0FBQyxDQUFDOztFQUVGOzs7O0VBSUF4VixrQkFBa0IsQ0FBQ3dTLFFBQVEsQ0FBQzs7RUN2ZDVCOzs7Ozs7O0VBZ0JBOzs7O0VBSUEsTUFBTW1ELE1BQUksR0FBRyxVQUFVO0VBQ3ZCLE1BQU1DLFVBQVEsR0FBRyxhQUFhO0VBQzlCLE1BQU1DLFdBQVMsR0FBSSxJQUFHRCxVQUFTLEVBQUM7RUFDaEMsTUFBTUUsY0FBWSxHQUFHLFdBQVc7RUFFaEMsTUFBTUMsWUFBVSxHQUFJLE9BQU1GLFdBQVUsRUFBQztFQUNyQyxNQUFNRyxhQUFXLEdBQUksUUFBT0gsV0FBVSxFQUFDO0VBQ3ZDLE1BQU1JLFlBQVUsR0FBSSxPQUFNSixXQUFVLEVBQUM7RUFDckMsTUFBTUssY0FBWSxHQUFJLFNBQVFMLFdBQVUsRUFBQztFQUN6QyxNQUFNTSxzQkFBb0IsR0FBSSxRQUFPTixXQUFVLEdBQUVDLGNBQWEsRUFBQztFQUUvRCxNQUFNTSxpQkFBZSxHQUFHLE1BQU07RUFDOUIsTUFBTUMsbUJBQW1CLEdBQUcsVUFBVTtFQUN0QyxNQUFNQyxxQkFBcUIsR0FBRyxZQUFZO0VBQzFDLE1BQU1DLG9CQUFvQixHQUFHLFdBQVc7RUFDeEMsTUFBTUMsMEJBQTBCLEdBQUksV0FBVUgsbUJBQW9CLEtBQUlBLG1CQUFvQixFQUFDO0VBQzNGLE1BQU1JLHFCQUFxQixHQUFHLHFCQUFxQjtFQUVuRCxNQUFNQyxLQUFLLEdBQUcsT0FBTztFQUNyQixNQUFNQyxNQUFNLEdBQUcsUUFBUTtFQUV2QixNQUFNQyxnQkFBZ0IsR0FBRyxzQ0FBc0M7RUFDL0QsTUFBTUMsc0JBQW9CLEdBQUcsNkJBQTZCO0VBRTFELE1BQU1DLFNBQU8sR0FBRztJQUNkQyxNQUFNLEVBQUUsSUFBSTtJQUNadkosTUFBTSxFQUFFO0VBQ1YsQ0FBQztFQUVELE1BQU13SixhQUFXLEdBQUc7SUFDbEJELE1BQU0sRUFBRSxnQkFBZ0I7SUFDeEJ2SixNQUFNLEVBQUU7RUFDVixDQUFDOztFQUVEOzs7O0VBSUEsTUFBTXlKLFFBQVEsU0FBUzFOLGFBQWEsQ0FBQztJQUNuQ1YsV0FBV0EsQ0FBQzNPLE9BQU8sRUFBRXNPLE1BQU0sRUFBRTtNQUMzQixLQUFLLENBQUN0TyxPQUFPLEVBQUVzTyxNQUFNLENBQUM7TUFFdEIsSUFBSSxDQUFDME8sZ0JBQWdCLEdBQUcsS0FBSztNQUM3QixJQUFJLENBQUNDLGFBQWEsR0FBRyxFQUFFO01BRXZCLE1BQU1DLFVBQVUsR0FBRzFNLGNBQWMsQ0FBQ3ZHLElBQUksQ0FBQzBTLHNCQUFvQixDQUFDO01BRTVELEtBQUssTUFBTVEsSUFBSSxJQUFJRCxVQUFVLEVBQUU7UUFDN0IsTUFBTWhjLFFBQVEsR0FBR3NQLGNBQWMsQ0FBQ2lCLHNCQUFzQixDQUFDMEwsSUFBSSxDQUFDO1FBQzVELE1BQU1DLGFBQWEsR0FBRzVNLGNBQWMsQ0FBQ3ZHLElBQUksQ0FBQy9JLFFBQVEsQ0FBQyxDQUNoRDJNLE1BQU0sQ0FBQ3dQLFlBQVksSUFBSUEsWUFBWSxLQUFLLElBQUksQ0FBQy9OLFFBQVEsQ0FBQztRQUV6RCxJQUFJcE8sUUFBUSxLQUFLLElBQUksSUFBSWtjLGFBQWEsQ0FBQzVaLE1BQU0sRUFBRTtVQUM3QyxJQUFJLENBQUN5WixhQUFhLENBQUN0WCxJQUFJLENBQUN3WCxJQUFJLENBQUM7UUFDL0I7TUFDRjtNQUVBLElBQUksQ0FBQ0csbUJBQW1CLEVBQUU7TUFFMUIsSUFBSSxDQUFDLElBQUksQ0FBQy9OLE9BQU8sQ0FBQ3NOLE1BQU0sRUFBRTtRQUN4QixJQUFJLENBQUNVLHlCQUF5QixDQUFDLElBQUksQ0FBQ04sYUFBYSxFQUFFLElBQUksQ0FBQ08sUUFBUSxFQUFFLENBQUM7TUFDckU7TUFFQSxJQUFJLElBQUksQ0FBQ2pPLE9BQU8sQ0FBQytELE1BQU0sRUFBRTtRQUN2QixJQUFJLENBQUNBLE1BQU0sRUFBRTtNQUNmO0lBQ0Y7O0lBRUE7SUFDQSxXQUFXcEYsT0FBT0EsQ0FBQSxFQUFHO01BQ25CLE9BQU8wTyxTQUFPO0lBQ2hCO0lBRUEsV0FBV3pPLFdBQVdBLENBQUEsRUFBRztNQUN2QixPQUFPMk8sYUFBVztJQUNwQjtJQUVBLFdBQVc1VyxJQUFJQSxDQUFBLEVBQUc7TUFDaEIsT0FBT3VWLE1BQUk7SUFDYjs7SUFFQTtJQUNBbkksTUFBTUEsQ0FBQSxFQUFHO01BQ1AsSUFBSSxJQUFJLENBQUNrSyxRQUFRLEVBQUUsRUFBRTtRQUNuQixJQUFJLENBQUNDLElBQUksRUFBRTtNQUNiLENBQUMsTUFBTTtRQUNMLElBQUksQ0FBQ0MsSUFBSSxFQUFFO01BQ2I7SUFDRjtJQUVBQSxJQUFJQSxDQUFBLEVBQUc7TUFDTCxJQUFJLElBQUksQ0FBQ1YsZ0JBQWdCLElBQUksSUFBSSxDQUFDUSxRQUFRLEVBQUUsRUFBRTtRQUM1QztNQUNGO01BRUEsSUFBSUcsY0FBYyxHQUFHLEVBQUU7O01BRXZCO01BQ0EsSUFBSSxJQUFJLENBQUNwTyxPQUFPLENBQUNzTixNQUFNLEVBQUU7UUFDdkJjLGNBQWMsR0FBRyxJQUFJLENBQUNDLHNCQUFzQixDQUFDbEIsZ0JBQWdCLENBQUMsQ0FDM0Q3TyxNQUFNLENBQUM3TixPQUFPLElBQUlBLE9BQU8sS0FBSyxJQUFJLENBQUNzUCxRQUFRLENBQUMsQ0FDNUNlLEdBQUcsQ0FBQ3JRLE9BQU8sSUFBSStjLFFBQVEsQ0FBQy9NLG1CQUFtQixDQUFDaFEsT0FBTyxFQUFFO1VBQUVzVCxNQUFNLEVBQUU7UUFBTSxDQUFDLENBQUMsQ0FBQztNQUM3RTtNQUVBLElBQUlxSyxjQUFjLENBQUNuYSxNQUFNLElBQUltYSxjQUFjLENBQUMsQ0FBQyxDQUFDLENBQUNYLGdCQUFnQixFQUFFO1FBQy9EO01BQ0Y7TUFFQSxNQUFNYSxVQUFVLEdBQUd6VSxZQUFZLENBQUN5QyxPQUFPLENBQUMsSUFBSSxDQUFDeUQsUUFBUSxFQUFFdU0sWUFBVSxDQUFDO01BQ2xFLElBQUlnQyxVQUFVLENBQUM1UixnQkFBZ0IsRUFBRTtRQUMvQjtNQUNGO01BRUEsS0FBSyxNQUFNNlIsY0FBYyxJQUFJSCxjQUFjLEVBQUU7UUFDM0NHLGNBQWMsQ0FBQ0wsSUFBSSxFQUFFO01BQ3ZCO01BRUEsTUFBTU0sU0FBUyxHQUFHLElBQUksQ0FBQ0MsYUFBYSxFQUFFO01BRXRDLElBQUksQ0FBQzFPLFFBQVEsQ0FBQ2pMLFNBQVMsQ0FBQ3pELE1BQU0sQ0FBQ3ViLG1CQUFtQixDQUFDO01BQ25ELElBQUksQ0FBQzdNLFFBQVEsQ0FBQ2pMLFNBQVMsQ0FBQ21SLEdBQUcsQ0FBQzRHLHFCQUFxQixDQUFDO01BRWxELElBQUksQ0FBQzlNLFFBQVEsQ0FBQzJPLEtBQUssQ0FBQ0YsU0FBUyxDQUFDLEdBQUcsQ0FBQztNQUVsQyxJQUFJLENBQUNSLHlCQUF5QixDQUFDLElBQUksQ0FBQ04sYUFBYSxFQUFFLElBQUksQ0FBQztNQUN4RCxJQUFJLENBQUNELGdCQUFnQixHQUFHLElBQUk7TUFFNUIsTUFBTWtCLFFBQVEsR0FBR0EsQ0FBQSxLQUFNO1FBQ3JCLElBQUksQ0FBQ2xCLGdCQUFnQixHQUFHLEtBQUs7UUFFN0IsSUFBSSxDQUFDMU4sUUFBUSxDQUFDakwsU0FBUyxDQUFDekQsTUFBTSxDQUFDd2IscUJBQXFCLENBQUM7UUFDckQsSUFBSSxDQUFDOU0sUUFBUSxDQUFDakwsU0FBUyxDQUFDbVIsR0FBRyxDQUFDMkcsbUJBQW1CLEVBQUVELGlCQUFlLENBQUM7UUFFakUsSUFBSSxDQUFDNU0sUUFBUSxDQUFDMk8sS0FBSyxDQUFDRixTQUFTLENBQUMsR0FBRyxFQUFFO1FBRW5DM1UsWUFBWSxDQUFDeUMsT0FBTyxDQUFDLElBQUksQ0FBQ3lELFFBQVEsRUFBRXdNLGFBQVcsQ0FBQztPQUNqRDtNQUVELE1BQU1xQyxvQkFBb0IsR0FBR0osU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDNU8sV0FBVyxFQUFFLEdBQUc0TyxTQUFTLENBQUNwUyxLQUFLLENBQUMsQ0FBQyxDQUFDO01BQzVFLE1BQU15UyxVQUFVLEdBQUksU0FBUUQsb0JBQXFCLEVBQUM7TUFFbEQsSUFBSSxDQUFDdE8sY0FBYyxDQUFDcU8sUUFBUSxFQUFFLElBQUksQ0FBQzVPLFFBQVEsRUFBRSxJQUFJLENBQUM7TUFDbEQsSUFBSSxDQUFDQSxRQUFRLENBQUMyTyxLQUFLLENBQUNGLFNBQVMsQ0FBQyxHQUFJLEdBQUUsSUFBSSxDQUFDek8sUUFBUSxDQUFDOE8sVUFBVSxDQUFFLElBQUc7SUFDbkU7SUFFQVgsSUFBSUEsQ0FBQSxFQUFHO01BQ0wsSUFBSSxJQUFJLENBQUNULGdCQUFnQixJQUFJLENBQUMsSUFBSSxDQUFDUSxRQUFRLEVBQUUsRUFBRTtRQUM3QztNQUNGO01BRUEsTUFBTUssVUFBVSxHQUFHelUsWUFBWSxDQUFDeUMsT0FBTyxDQUFDLElBQUksQ0FBQ3lELFFBQVEsRUFBRXlNLFlBQVUsQ0FBQztNQUNsRSxJQUFJOEIsVUFBVSxDQUFDNVIsZ0JBQWdCLEVBQUU7UUFDL0I7TUFDRjtNQUVBLE1BQU04UixTQUFTLEdBQUcsSUFBSSxDQUFDQyxhQUFhLEVBQUU7TUFFdEMsSUFBSSxDQUFDMU8sUUFBUSxDQUFDMk8sS0FBSyxDQUFDRixTQUFTLENBQUMsR0FBSSxHQUFFLElBQUksQ0FBQ3pPLFFBQVEsQ0FBQytPLHFCQUFxQixFQUFFLENBQUNOLFNBQVMsQ0FBRSxJQUFHO01BRXhGOVksTUFBTSxDQUFDLElBQUksQ0FBQ3FLLFFBQVEsQ0FBQztNQUVyQixJQUFJLENBQUNBLFFBQVEsQ0FBQ2pMLFNBQVMsQ0FBQ21SLEdBQUcsQ0FBQzRHLHFCQUFxQixDQUFDO01BQ2xELElBQUksQ0FBQzlNLFFBQVEsQ0FBQ2pMLFNBQVMsQ0FBQ3pELE1BQU0sQ0FBQ3ViLG1CQUFtQixFQUFFRCxpQkFBZSxDQUFDO01BRXBFLEtBQUssTUFBTXJRLE9BQU8sSUFBSSxJQUFJLENBQUNvUixhQUFhLEVBQUU7UUFDeEMsTUFBTWpkLE9BQU8sR0FBR3dRLGNBQWMsQ0FBQ2tCLHNCQUFzQixDQUFDN0YsT0FBTyxDQUFDO1FBRTlELElBQUk3TCxPQUFPLElBQUksQ0FBQyxJQUFJLENBQUN3ZCxRQUFRLENBQUN4ZCxPQUFPLENBQUMsRUFBRTtVQUN0QyxJQUFJLENBQUN1ZCx5QkFBeUIsQ0FBQyxDQUFDMVIsT0FBTyxDQUFDLEVBQUUsS0FBSyxDQUFDO1FBQ2xEO01BQ0Y7TUFFQSxJQUFJLENBQUNtUixnQkFBZ0IsR0FBRyxJQUFJO01BRTVCLE1BQU1rQixRQUFRLEdBQUdBLENBQUEsS0FBTTtRQUNyQixJQUFJLENBQUNsQixnQkFBZ0IsR0FBRyxLQUFLO1FBQzdCLElBQUksQ0FBQzFOLFFBQVEsQ0FBQ2pMLFNBQVMsQ0FBQ3pELE1BQU0sQ0FBQ3diLHFCQUFxQixDQUFDO1FBQ3JELElBQUksQ0FBQzlNLFFBQVEsQ0FBQ2pMLFNBQVMsQ0FBQ21SLEdBQUcsQ0FBQzJHLG1CQUFtQixDQUFDO1FBQ2hEL1MsWUFBWSxDQUFDeUMsT0FBTyxDQUFDLElBQUksQ0FBQ3lELFFBQVEsRUFBRTBNLGNBQVksQ0FBQztPQUNsRDtNQUVELElBQUksQ0FBQzFNLFFBQVEsQ0FBQzJPLEtBQUssQ0FBQ0YsU0FBUyxDQUFDLEdBQUcsRUFBRTtNQUVuQyxJQUFJLENBQUNsTyxjQUFjLENBQUNxTyxRQUFRLEVBQUUsSUFBSSxDQUFDNU8sUUFBUSxFQUFFLElBQUksQ0FBQztJQUNwRDtJQUVBa08sUUFBUUEsQ0FBQSxFQUEwQjtNQUFBLElBQXpCeGQsT0FBTyxHQUFBMkcsU0FBQSxDQUFBbkQsTUFBQSxRQUFBbUQsU0FBQSxRQUFBaEYsU0FBQSxHQUFBZ0YsU0FBQSxNQUFHLElBQUksQ0FBQzJJLFFBQVE7TUFDOUIsT0FBT3RQLE9BQU8sQ0FBQ3FFLFNBQVMsQ0FBQ0MsUUFBUSxDQUFDNFgsaUJBQWUsQ0FBQztJQUNwRDs7SUFFQTtJQUNBMU4saUJBQWlCQSxDQUFDRixNQUFNLEVBQUU7TUFDeEJBLE1BQU0sQ0FBQ2dGLE1BQU0sR0FBR3hJLE9BQU8sQ0FBQ3dELE1BQU0sQ0FBQ2dGLE1BQU0sQ0FBQyxDQUFDO01BQ3ZDaEYsTUFBTSxDQUFDdU8sTUFBTSxHQUFHdFosVUFBVSxDQUFDK0ssTUFBTSxDQUFDdU8sTUFBTSxDQUFDO01BQ3pDLE9BQU92TyxNQUFNO0lBQ2Y7SUFFQTBQLGFBQWFBLENBQUEsRUFBRztNQUNkLE9BQU8sSUFBSSxDQUFDMU8sUUFBUSxDQUFDakwsU0FBUyxDQUFDQyxRQUFRLENBQUNpWSxxQkFBcUIsQ0FBQyxHQUFHQyxLQUFLLEdBQUdDLE1BQU07SUFDakY7SUFFQWEsbUJBQW1CQSxDQUFBLEVBQUc7TUFDcEIsSUFBSSxDQUFDLElBQUksQ0FBQy9OLE9BQU8sQ0FBQ3NOLE1BQU0sRUFBRTtRQUN4QjtNQUNGO01BRUEsTUFBTWpNLFFBQVEsR0FBRyxJQUFJLENBQUNnTixzQkFBc0IsQ0FBQ2pCLHNCQUFvQixDQUFDO01BRWxFLEtBQUssTUFBTTNjLE9BQU8sSUFBSTRRLFFBQVEsRUFBRTtRQUM5QixNQUFNME4sUUFBUSxHQUFHOU4sY0FBYyxDQUFDa0Isc0JBQXNCLENBQUMxUixPQUFPLENBQUM7UUFFL0QsSUFBSXNlLFFBQVEsRUFBRTtVQUNaLElBQUksQ0FBQ2YseUJBQXlCLENBQUMsQ0FBQ3ZkLE9BQU8sQ0FBQyxFQUFFLElBQUksQ0FBQ3dkLFFBQVEsQ0FBQ2MsUUFBUSxDQUFDLENBQUM7UUFDcEU7TUFDRjtJQUNGO0lBRUFWLHNCQUFzQkEsQ0FBQzFjLFFBQVEsRUFBRTtNQUMvQixNQUFNMFAsUUFBUSxHQUFHSixjQUFjLENBQUN2RyxJQUFJLENBQUNxUywwQkFBMEIsRUFBRSxJQUFJLENBQUMvTSxPQUFPLENBQUNzTixNQUFNLENBQUM7TUFDckY7TUFDQSxPQUFPck0sY0FBYyxDQUFDdkcsSUFBSSxDQUFDL0ksUUFBUSxFQUFFLElBQUksQ0FBQ3FPLE9BQU8sQ0FBQ3NOLE1BQU0sQ0FBQyxDQUFDaFAsTUFBTSxDQUFDN04sT0FBTyxJQUFJLENBQUM0USxRQUFRLENBQUN4RixRQUFRLENBQUNwTCxPQUFPLENBQUMsQ0FBQztJQUMxRztJQUVBdWQseUJBQXlCQSxDQUFDZ0IsWUFBWSxFQUFFQyxNQUFNLEVBQUU7TUFDOUMsSUFBSSxDQUFDRCxZQUFZLENBQUMvYSxNQUFNLEVBQUU7UUFDeEI7TUFDRjtNQUVBLEtBQUssTUFBTXhELE9BQU8sSUFBSXVlLFlBQVksRUFBRTtRQUNsQ3ZlLE9BQU8sQ0FBQ3FFLFNBQVMsQ0FBQ2lQLE1BQU0sQ0FBQytJLG9CQUFvQixFQUFFLENBQUNtQyxNQUFNLENBQUM7UUFDdkR4ZSxPQUFPLENBQUNzTixZQUFZLENBQUMsZUFBZSxFQUFFa1IsTUFBTSxDQUFDO01BQy9DO0lBQ0Y7O0lBRUE7SUFDQSxPQUFPblksZUFBZUEsQ0FBQ2lJLE1BQU0sRUFBRTtNQUM3QixNQUFNaUIsT0FBTyxHQUFHLEVBQUU7TUFDbEIsSUFBSSxPQUFPakIsTUFBTSxLQUFLLFFBQVEsSUFBSSxXQUFXLENBQUNXLElBQUksQ0FBQ1gsTUFBTSxDQUFDLEVBQUU7UUFDMURpQixPQUFPLENBQUMrRCxNQUFNLEdBQUcsS0FBSztNQUN4QjtNQUVBLE9BQU8sSUFBSSxDQUFDVixJQUFJLENBQUMsWUFBWTtRQUMzQixNQUFNQyxJQUFJLEdBQUdrSyxRQUFRLENBQUMvTSxtQkFBbUIsQ0FBQyxJQUFJLEVBQUVULE9BQU8sQ0FBQztRQUV4RCxJQUFJLE9BQU9qQixNQUFNLEtBQUssUUFBUSxFQUFFO1VBQzlCLElBQUksT0FBT3VFLElBQUksQ0FBQ3ZFLE1BQU0sQ0FBQyxLQUFLLFdBQVcsRUFBRTtZQUN2QyxNQUFNLElBQUlZLFNBQVMsQ0FBRSxvQkFBbUJaLE1BQU8sR0FBRSxDQUFDO1VBQ3BEO1VBRUF1RSxJQUFJLENBQUN2RSxNQUFNLENBQUMsRUFBRTtRQUNoQjtNQUNGLENBQUMsQ0FBQztJQUNKO0VBQ0Y7O0VBRUE7Ozs7RUFJQWxGLFlBQVksQ0FBQ2lDLEVBQUUsQ0FBQy9JLFFBQVEsRUFBRTJaLHNCQUFvQixFQUFFVSxzQkFBb0IsRUFBRSxVQUFVM1QsS0FBSyxFQUFFO0lBQ3JGO0lBQ0EsSUFBSUEsS0FBSyxDQUFDM0IsTUFBTSxDQUFDMkssT0FBTyxLQUFLLEdBQUcsSUFBS2hKLEtBQUssQ0FBQ0UsY0FBYyxJQUFJRixLQUFLLENBQUNFLGNBQWMsQ0FBQzhJLE9BQU8sS0FBSyxHQUFJLEVBQUU7TUFDbEdoSixLQUFLLENBQUN1RCxjQUFjLEVBQUU7SUFDeEI7SUFFQSxLQUFLLE1BQU12TSxPQUFPLElBQUl3USxjQUFjLENBQUNtQiwrQkFBK0IsQ0FBQyxJQUFJLENBQUMsRUFBRTtNQUMxRW9MLFFBQVEsQ0FBQy9NLG1CQUFtQixDQUFDaFEsT0FBTyxFQUFFO1FBQUVzVCxNQUFNLEVBQUU7TUFBTSxDQUFDLENBQUMsQ0FBQ0EsTUFBTSxFQUFFO0lBQ25FO0VBQ0YsQ0FBQyxDQUFDOztFQUVGOzs7O0VBSUF4TixrQkFBa0IsQ0FBQ2lYLFFBQVEsQ0FBQztFQ3RTckIsSUFBSTBCLEdBQUcsR0FBRyxLQUFLO0VBQ2YsSUFBSUMsTUFBTSxHQUFHLFFBQVE7RUFDckIsSUFBSUMsS0FBSyxHQUFHLE9BQU87RUFDbkIsSUFBSUMsSUFBSSxHQUFHLE1BQU07RUFDakIsSUFBSUMsSUFBSSxHQUFHLE1BQU07RUFDakIsSUFBSUMsY0FBYyxHQUFHLENBQUNMLEdBQUcsRUFBRUMsTUFBTSxFQUFFQyxLQUFLLEVBQUVDLElBQUksQ0FBQztFQUMvQyxJQUFJRyxLQUFLLEdBQUcsT0FBTztFQUNuQixJQUFJQyxHQUFHLEdBQUcsS0FBSztFQUNmLElBQUlDLGVBQWUsR0FBRyxpQkFBaUI7RUFDdkMsSUFBSUMsUUFBUSxHQUFHLFVBQVU7RUFDekIsSUFBSUMsTUFBTSxHQUFHLFFBQVE7RUFDckIsSUFBSUMsU0FBUyxHQUFHLFdBQVc7RUFDM0IsSUFBSUMsbUJBQW1CLGdCQUFnQlAsY0FBYyxDQUFDUSxNQUFNLENBQUMsVUFBVUMsR0FBRyxFQUFFQyxTQUFTLEVBQUU7SUFDNUYsT0FBT0QsR0FBRyxDQUFDOU8sTUFBTSxDQUFDLENBQUMrTyxTQUFTLEdBQUcsR0FBRyxHQUFHVCxLQUFLLEVBQUVTLFNBQVMsR0FBRyxHQUFHLEdBQUdSLEdBQUcsQ0FBQyxDQUFDO0VBQ3JFLENBQUMsRUFBRSxFQUFFLENBQUM7RUFDQyxJQUFJUyxVQUFVLGdCQUFnQixFQUFFLENBQUNoUCxNQUFNLENBQUNxTyxjQUFjLEVBQUUsQ0FBQ0QsSUFBSSxDQUFDLENBQUMsQ0FBQ1MsTUFBTSxDQUFDLFVBQVVDLEdBQUcsRUFBRUMsU0FBUyxFQUFFO0lBQ3RHLE9BQU9ELEdBQUcsQ0FBQzlPLE1BQU0sQ0FBQyxDQUFDK08sU0FBUyxFQUFFQSxTQUFTLEdBQUcsR0FBRyxHQUFHVCxLQUFLLEVBQUVTLFNBQVMsR0FBRyxHQUFHLEdBQUdSLEdBQUcsQ0FBQyxDQUFDO0VBQ2hGLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQzs7RUFFQSxJQUFJVSxVQUFVLEdBQUcsWUFBWTtFQUM3QixJQUFJQyxJQUFJLEdBQUcsTUFBTTtFQUNqQixJQUFJQyxTQUFTLEdBQUcsV0FBVyxDQUFDOztFQUU1QixJQUFJQyxVQUFVLEdBQUcsWUFBWTtFQUM3QixJQUFJQyxJQUFJLEdBQUcsTUFBTTtFQUNqQixJQUFJQyxTQUFTLEdBQUcsV0FBVyxDQUFDOztFQUU1QixJQUFJQyxXQUFXLEdBQUcsYUFBYTtFQUMvQixJQUFJQyxLQUFLLEdBQUcsT0FBTztFQUNuQixJQUFJQyxVQUFVLEdBQUcsWUFBWTtFQUM3QixJQUFJQyxjQUFjLEdBQUcsQ0FBQ1QsVUFBVSxFQUFFQyxJQUFJLEVBQUVDLFNBQVMsRUFBRUMsVUFBVSxFQUFFQyxJQUFJLEVBQUVDLFNBQVMsRUFBRUMsV0FBVyxFQUFFQyxLQUFLLEVBQUVDLFVBQVUsQ0FBQztFQzlCdkcsU0FBU0UsV0FBV0EsQ0FBQ3BnQixPQUFPLEVBQUU7SUFDM0MsT0FBT0EsT0FBTyxHQUFHLENBQUNBLE9BQU8sQ0FBQ3FnQixRQUFRLElBQUksRUFBRSxFQUFFcmUsV0FBVyxFQUFFLEdBQUcsSUFBSTtFQUNoRTtFQ0ZlLFNBQVNzZSxTQUFTQSxDQUFDQyxJQUFJLEVBQUU7SUFDdEMsSUFBSUEsSUFBSSxJQUFJLElBQUksRUFBRTtNQUNoQixPQUFPcGYsTUFBTTtJQUNqQjtJQUVFLElBQUlvZixJQUFJLENBQUN6ZSxRQUFRLEVBQUUsS0FBSyxpQkFBaUIsRUFBRTtNQUN6QyxJQUFJMGUsYUFBYSxHQUFHRCxJQUFJLENBQUNDLGFBQWE7TUFDdEMsT0FBT0EsYUFBYSxHQUFHQSxhQUFhLENBQUNDLFdBQVcsSUFBSXRmLE1BQU0sR0FBR0EsTUFBTTtJQUN2RTtJQUVFLE9BQU9vZixJQUFJO0VBQ2I7RUNUQSxTQUFTRyxTQUFTQSxDQUFDSCxJQUFJLEVBQUU7SUFDdkIsSUFBSUksVUFBVSxHQUFHTCxTQUFTLENBQUNDLElBQUksQ0FBQyxDQUFDN1AsT0FBTztJQUN4QyxPQUFPNlAsSUFBSSxZQUFZSSxVQUFVLElBQUlKLElBQUksWUFBWTdQLE9BQU87RUFDOUQ7RUFFQSxTQUFTa1EsYUFBYUEsQ0FBQ0wsSUFBSSxFQUFFO0lBQzNCLElBQUlJLFVBQVUsR0FBR0wsU0FBUyxDQUFDQyxJQUFJLENBQUMsQ0FBQ00sV0FBVztJQUM1QyxPQUFPTixJQUFJLFlBQVlJLFVBQVUsSUFBSUosSUFBSSxZQUFZTSxXQUFXO0VBQ2xFO0VBRUEsU0FBU0MsWUFBWUEsQ0FBQ1AsSUFBSSxFQUFFO0lBQzVCO0lBQ0UsSUFBSSxPQUFPeGIsVUFBVSxLQUFLLFdBQVcsRUFBRTtNQUNyQyxPQUFPLEtBQUs7SUFDaEI7SUFFRSxJQUFJNGIsVUFBVSxHQUFHTCxTQUFTLENBQUNDLElBQUksQ0FBQyxDQUFDeGIsVUFBVTtJQUMzQyxPQUFPd2IsSUFBSSxZQUFZSSxVQUFVLElBQUlKLElBQUksWUFBWXhiLFVBQVU7RUFDakU7O0VDbEJBOztFQUVBLFNBQVNnYyxXQUFXQSxDQUFDQyxJQUFJLEVBQUU7SUFDekIsSUFBSUMsS0FBSyxHQUFHRCxJQUFJLENBQUNDLEtBQUs7SUFDdEJyZixNQUFNLENBQUNqQixJQUFJLENBQUNzZ0IsS0FBSyxDQUFDQyxRQUFRLENBQUMsQ0FBQ0MsT0FBTyxDQUFDLFVBQVVsYixJQUFJLEVBQUU7TUFDbEQsSUFBSWdZLEtBQUssR0FBR2dELEtBQUssQ0FBQ0csTUFBTSxDQUFDbmIsSUFBSSxDQUFDLElBQUksRUFBRTtNQUNwQyxJQUFJeUgsVUFBVSxHQUFHdVQsS0FBSyxDQUFDdlQsVUFBVSxDQUFDekgsSUFBSSxDQUFDLElBQUksRUFBRTtNQUM3QyxJQUFJakcsT0FBTyxHQUFHaWhCLEtBQUssQ0FBQ0MsUUFBUSxDQUFDamIsSUFBSSxDQUFDLENBQUM7O01BRW5DLElBQUksQ0FBQzJhLGFBQWEsQ0FBQzVnQixPQUFPLENBQUMsSUFBSSxDQUFDb2dCLFdBQVcsQ0FBQ3BnQixPQUFPLENBQUMsRUFBRTtRQUNwRDtNQUNOLENBQUs7TUFDTDtNQUNBOztNQUdJNEIsTUFBTSxDQUFDeWYsTUFBTSxDQUFDcmhCLE9BQU8sQ0FBQ2llLEtBQUssRUFBRUEsS0FBSyxDQUFDO01BQ25DcmMsTUFBTSxDQUFDakIsSUFBSSxDQUFDK00sVUFBVSxDQUFDLENBQUN5VCxPQUFPLENBQUMsVUFBVWxiLElBQUksRUFBRTtRQUM5QyxJQUFJeUcsS0FBSyxHQUFHZ0IsVUFBVSxDQUFDekgsSUFBSSxDQUFDO1FBRTVCLElBQUl5RyxLQUFLLEtBQUssS0FBSyxFQUFFO1VBQ25CMU0sT0FBTyxDQUFDd04sZUFBZSxDQUFDdkgsSUFBSSxDQUFDO1FBQ3JDLENBQU8sTUFBTTtVQUNMakcsT0FBTyxDQUFDc04sWUFBWSxDQUFDckgsSUFBSSxFQUFFeUcsS0FBSyxLQUFLLElBQUksR0FBRyxFQUFFLEdBQUdBLEtBQUssQ0FBQztRQUMvRDtNQUNBLENBQUssQ0FBQztJQUNOLENBQUcsQ0FBQztFQUNKO0VBRUEsU0FBUzRVLFFBQU1DLENBQUNDLEtBQUssRUFBRTtJQUNyQixJQUFJUCxLQUFLLEdBQUdPLEtBQUssQ0FBQ1AsS0FBSztJQUN2QixJQUFJUSxhQUFhLEdBQUc7TUFDbEJ0QyxNQUFNLEVBQUU7UUFDTnVDLFFBQVEsRUFBRVQsS0FBSyxDQUFDVSxPQUFPLENBQUNDLFFBQVE7UUFDaENoRCxJQUFJLEVBQUUsR0FBRztRQUNUSCxHQUFHLEVBQUUsR0FBRztRQUNSb0QsTUFBTSxFQUFFO01BQ2QsQ0FBSztNQUNEQyxLQUFLLEVBQUU7UUFDTEosUUFBUSxFQUFFO01BQ2hCLENBQUs7TUFDRHRDLFNBQVMsRUFBRTtJQUNmLENBQUc7SUFDRHhkLE1BQU0sQ0FBQ3lmLE1BQU0sQ0FBQ0osS0FBSyxDQUFDQyxRQUFRLENBQUMvQixNQUFNLENBQUNsQixLQUFLLEVBQUV3RCxhQUFhLENBQUN0QyxNQUFNLENBQUM7SUFDaEU4QixLQUFLLENBQUNHLE1BQU0sR0FBR0ssYUFBYTtJQUU1QixJQUFJUixLQUFLLENBQUNDLFFBQVEsQ0FBQ1ksS0FBSyxFQUFFO01BQ3hCbGdCLE1BQU0sQ0FBQ3lmLE1BQU0sQ0FBQ0osS0FBSyxDQUFDQyxRQUFRLENBQUNZLEtBQUssQ0FBQzdELEtBQUssRUFBRXdELGFBQWEsQ0FBQ0ssS0FBSyxDQUFDO0lBQ2xFO0lBRUUsT0FBTyxZQUFZO01BQ2pCbGdCLE1BQU0sQ0FBQ2pCLElBQUksQ0FBQ3NnQixLQUFLLENBQUNDLFFBQVEsQ0FBQyxDQUFDQyxPQUFPLENBQUMsVUFBVWxiLElBQUksRUFBRTtRQUNsRCxJQUFJakcsT0FBTyxHQUFHaWhCLEtBQUssQ0FBQ0MsUUFBUSxDQUFDamIsSUFBSSxDQUFDO1FBQ2xDLElBQUl5SCxVQUFVLEdBQUd1VCxLQUFLLENBQUN2VCxVQUFVLENBQUN6SCxJQUFJLENBQUMsSUFBSSxFQUFFO1FBQzdDLElBQUk4YixlQUFlLEdBQUduZ0IsTUFBTSxDQUFDakIsSUFBSSxDQUFDc2dCLEtBQUssQ0FBQ0csTUFBTSxDQUFDWSxjQUFjLENBQUMvYixJQUFJLENBQUMsR0FBR2diLEtBQUssQ0FBQ0csTUFBTSxDQUFDbmIsSUFBSSxDQUFDLEdBQUd3YixhQUFhLENBQUN4YixJQUFJLENBQUMsQ0FBQyxDQUFDOztRQUVoSCxJQUFJZ1ksS0FBSyxHQUFHOEQsZUFBZSxDQUFDekMsTUFBTSxDQUFDLFVBQVVyQixLQUFLLEVBQUVwUCxRQUFRLEVBQUU7VUFDNURvUCxLQUFLLENBQUNwUCxRQUFRLENBQUMsR0FBRyxFQUFFO1VBQ3BCLE9BQU9vUCxLQUFLO1FBQ3BCLENBQU8sRUFBRSxFQUFFLENBQUMsQ0FBQzs7UUFFUCxJQUFJLENBQUMyQyxhQUFhLENBQUM1Z0IsT0FBTyxDQUFDLElBQUksQ0FBQ29nQixXQUFXLENBQUNwZ0IsT0FBTyxDQUFDLEVBQUU7VUFDcEQ7UUFDUjtRQUVNNEIsTUFBTSxDQUFDeWYsTUFBTSxDQUFDcmhCLE9BQU8sQ0FBQ2llLEtBQUssRUFBRUEsS0FBSyxDQUFDO1FBQ25DcmMsTUFBTSxDQUFDakIsSUFBSSxDQUFDK00sVUFBVSxDQUFDLENBQUN5VCxPQUFPLENBQUMsVUFBVWMsU0FBUyxFQUFFO1VBQ25EamlCLE9BQU8sQ0FBQ3dOLGVBQWUsQ0FBQ3lVLFNBQVMsQ0FBQztRQUMxQyxDQUFPLENBQUM7TUFDUixDQUFLLENBQUM7SUFDTixDQUFHO0VBQ0gsQ0FBQzs7RUFHRCxNQUFBQyxhQUFBLEdBQWU7SUFDYmpjLElBQUksRUFBRSxhQUFhO0lBQ25Ca2MsT0FBTyxFQUFFLElBQUk7SUFDYkMsS0FBSyxFQUFFLE9BQU87SUFDZGhjLEVBQUUsRUFBRTJhLFdBQVc7SUFDZlEsTUFBTSxFQUFFRCxRQUFNO0lBQ2RlLFFBQVEsRUFBRSxDQUFDLGVBQWU7RUFDNUIsQ0FBQztFQ2xGYyxTQUFTQyxnQkFBZ0JBLENBQUM5QyxTQUFTLEVBQUU7SUFDbEQsT0FBT0EsU0FBUyxDQUFDeGMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztFQUNoQztFQ0hPLElBQUlnRixHQUFHLEdBQUc3RixJQUFJLENBQUM2RixHQUFHO0VBQ2xCLElBQUlDLEdBQUcsR0FBRzlGLElBQUksQ0FBQzhGLEdBQUc7RUFDbEIsSUFBSXNhLEtBQUssR0FBR3BnQixJQUFJLENBQUNvZ0IsS0FBSztFQ0ZkLFNBQVNDLFdBQVdBLENBQUEsRUFBRztJQUNwQyxJQUFJQyxNQUFNLEdBQUcvTSxTQUFTLENBQUNnTixhQUFhO0lBRXBDLElBQUlELE1BQU0sSUFBSSxJQUFJLElBQUlBLE1BQU0sQ0FBQ0UsTUFBTSxJQUFJbGlCLEtBQUssQ0FBQ21pQixPQUFPLENBQUNILE1BQU0sQ0FBQ0UsTUFBTSxDQUFDLEVBQUU7TUFDbkUsT0FBT0YsTUFBTSxDQUFDRSxNQUFNLENBQUN0UyxHQUFHLENBQUMsVUFBVXdTLElBQUksRUFBRTtRQUN2QyxPQUFPQSxJQUFJLENBQUNDLEtBQUssR0FBRyxHQUFHLEdBQUdELElBQUksQ0FBQ0UsT0FBTztNQUM1QyxDQUFLLENBQUMsQ0FBQ3hTLElBQUksQ0FBQyxHQUFHLENBQUM7SUFDaEI7SUFFRSxPQUFPbUYsU0FBUyxDQUFDc04sU0FBUztFQUM1QjtFQ1RlLFNBQVNDLGdCQUFnQkEsQ0FBQSxFQUFHO0lBQ3pDLE9BQU8sQ0FBQyxnQ0FBZ0MsQ0FBQ2hVLElBQUksQ0FBQ3VULFdBQVcsRUFBRSxDQUFDO0VBQzlEO0VDQ2UsU0FBU25FLHFCQUFxQkEsQ0FBQ3JlLE9BQU8sRUFBRWtqQixZQUFZLEVBQUVDLGVBQWUsRUFBRTtJQUNwRixJQUFJRCxZQUFZLEtBQUssS0FBSyxDQUFDLEVBQUU7TUFDM0JBLFlBQVksR0FBRyxLQUFLO0lBQ3hCO0lBRUUsSUFBSUMsZUFBZSxLQUFLLEtBQUssQ0FBQyxFQUFFO01BQzlCQSxlQUFlLEdBQUcsS0FBSztJQUMzQjtJQUVFLElBQUlDLFVBQVUsR0FBR3BqQixPQUFPLENBQUNxZSxxQkFBcUIsRUFBRTtJQUNoRCxJQUFJZ0YsTUFBTSxHQUFHLENBQUM7SUFDZCxJQUFJQyxNQUFNLEdBQUcsQ0FBQztJQUVkLElBQUlKLFlBQVksSUFBSXRDLGFBQWEsQ0FBQzVnQixPQUFPLENBQUMsRUFBRTtNQUMxQ3FqQixNQUFNLEdBQUdyakIsT0FBTyxDQUFDdWpCLFdBQVcsR0FBRyxDQUFDLEdBQUdoQixLQUFLLENBQUNhLFVBQVUsQ0FBQ0ksS0FBSyxDQUFDLEdBQUd4akIsT0FBTyxDQUFDdWpCLFdBQVcsSUFBSSxDQUFDLEdBQUcsQ0FBQztNQUN6RkQsTUFBTSxHQUFHdGpCLE9BQU8sQ0FBQ2tGLFlBQVksR0FBRyxDQUFDLEdBQUdxZCxLQUFLLENBQUNhLFVBQVUsQ0FBQ0ssTUFBTSxDQUFDLEdBQUd6akIsT0FBTyxDQUFDa0YsWUFBWSxJQUFJLENBQUMsR0FBRyxDQUFDO0lBQ2hHO0lBRUUsSUFBSThiLElBQUksR0FBR04sU0FBUyxDQUFDMWdCLE9BQU8sQ0FBQyxHQUFHc2dCLFNBQVMsQ0FBQ3RnQixPQUFPLENBQUMsR0FBR21CLE1BQU07TUFDdkR1aUIsY0FBYyxHQUFHMUMsSUFBSSxDQUFDMEMsY0FBYztJQUV4QyxJQUFJQyxnQkFBZ0IsR0FBRyxDQUFDVixnQkFBZ0IsRUFBRSxJQUFJRSxlQUFlO0lBQzdELElBQUlTLENBQUMsR0FBRyxDQUFDUixVQUFVLENBQUN4RSxJQUFJLElBQUkrRSxnQkFBZ0IsSUFBSUQsY0FBYyxHQUFHQSxjQUFjLENBQUNHLFVBQVUsR0FBRyxDQUFDLENBQUMsSUFBSVIsTUFBTTtJQUN6RyxJQUFJUyxDQUFDLEdBQUcsQ0FBQ1YsVUFBVSxDQUFDM0UsR0FBRyxJQUFJa0YsZ0JBQWdCLElBQUlELGNBQWMsR0FBR0EsY0FBYyxDQUFDSyxTQUFTLEdBQUcsQ0FBQyxDQUFDLElBQUlULE1BQU07SUFDdkcsSUFBSUUsS0FBSyxHQUFHSixVQUFVLENBQUNJLEtBQUssR0FBR0gsTUFBTTtJQUNyQyxJQUFJSSxNQUFNLEdBQUdMLFVBQVUsQ0FBQ0ssTUFBTSxHQUFHSCxNQUFNO0lBQ3ZDLE9BQU87TUFDTEUsS0FBSyxFQUFFQSxLQUFLO01BQ1pDLE1BQU0sRUFBRUEsTUFBTTtNQUNkaEYsR0FBRyxFQUFFcUYsQ0FBQztNQUNObkYsS0FBSyxFQUFFaUYsQ0FBQyxHQUFHSixLQUFLO01BQ2hCOUUsTUFBTSxFQUFFb0YsQ0FBQyxHQUFHTCxNQUFNO01BQ2xCN0UsSUFBSSxFQUFFZ0YsQ0FBQztNQUNQQSxDQUFDLEVBQUVBLENBQUM7TUFDSkUsQ0FBQyxFQUFFQTtJQUNQLENBQUc7RUFDSDs7RUN2Q0E7O0VBRWUsU0FBU0UsYUFBYUEsQ0FBQ2hrQixPQUFPLEVBQUU7SUFDN0MsSUFBSW9qQixVQUFVLEdBQUcvRSxxQkFBcUIsQ0FBQ3JlLE9BQU8sQ0FBQyxDQUFDO0lBQ2xEOztJQUVFLElBQUl3akIsS0FBSyxHQUFHeGpCLE9BQU8sQ0FBQ3VqQixXQUFXO0lBQy9CLElBQUlFLE1BQU0sR0FBR3pqQixPQUFPLENBQUNrRixZQUFZO0lBRWpDLElBQUkvQyxJQUFJLENBQUNtVCxHQUFHLENBQUM4TixVQUFVLENBQUNJLEtBQUssR0FBR0EsS0FBSyxDQUFDLElBQUksQ0FBQyxFQUFFO01BQzNDQSxLQUFLLEdBQUdKLFVBQVUsQ0FBQ0ksS0FBSztJQUM1QjtJQUVFLElBQUlyaEIsSUFBSSxDQUFDbVQsR0FBRyxDQUFDOE4sVUFBVSxDQUFDSyxNQUFNLEdBQUdBLE1BQU0sQ0FBQyxJQUFJLENBQUMsRUFBRTtNQUM3Q0EsTUFBTSxHQUFHTCxVQUFVLENBQUNLLE1BQU07SUFDOUI7SUFFRSxPQUFPO01BQ0xHLENBQUMsRUFBRTVqQixPQUFPLENBQUM2akIsVUFBVTtNQUNyQkMsQ0FBQyxFQUFFOWpCLE9BQU8sQ0FBQytqQixTQUFTO01BQ3BCUCxLQUFLLEVBQUVBLEtBQUs7TUFDWkMsTUFBTSxFQUFFQTtJQUNaLENBQUc7RUFDSDtFQ3ZCZSxTQUFTbmYsUUFBUUEsQ0FBQ3VZLE1BQU0sRUFBRWhNLEtBQUssRUFBRTtJQUM5QyxJQUFJb1QsUUFBUSxHQUFHcFQsS0FBSyxDQUFDaE0sV0FBVyxJQUFJZ00sS0FBSyxDQUFDaE0sV0FBVyxFQUFFLENBQUM7O0lBRXhELElBQUlnWSxNQUFNLENBQUN2WSxRQUFRLENBQUN1TSxLQUFLLENBQUMsRUFBRTtNQUMxQixPQUFPLElBQUk7SUFDZixDQUFHO0lBQUEsS0FDSSxJQUFJb1QsUUFBUSxJQUFJbkQsWUFBWSxDQUFDbUQsUUFBUSxDQUFDLEVBQUU7TUFDekMsSUFBSTdTLElBQUksR0FBR1AsS0FBSztNQUVoQixHQUFHO1FBQ0QsSUFBSU8sSUFBSSxJQUFJeUwsTUFBTSxDQUFDcUgsVUFBVSxDQUFDOVMsSUFBSSxDQUFDLEVBQUU7VUFDbkMsT0FBTyxJQUFJO1FBQ3JCLENBQVM7O1FBR0RBLElBQUksR0FBR0EsSUFBSSxDQUFDbk4sVUFBVSxJQUFJbU4sSUFBSSxDQUFDK1MsSUFBSTtNQUMzQyxDQUFPLFFBQVEvUyxJQUFJO0lBQ25CLENBQUs7O0lBR0gsT0FBTyxLQUFLO0VBQ2Q7RUNyQmUsU0FBU2dULGtCQUFnQnpoQixDQUFDM0MsT0FBTyxFQUFFO0lBQ2hELE9BQU9zZ0IsU0FBUyxDQUFDdGdCLE9BQU8sQ0FBQyxDQUFDMkMsZ0JBQWdCLENBQUMzQyxPQUFPLENBQUM7RUFDckQ7RUNGZSxTQUFTcWtCLGNBQWNBLENBQUNya0IsT0FBTyxFQUFFO0lBQzlDLE9BQU8sQ0FBQyxPQUFPLEVBQUUsSUFBSSxFQUFFLElBQUksQ0FBQyxDQUFDK0gsT0FBTyxDQUFDcVksV0FBVyxDQUFDcGdCLE9BQU8sQ0FBQyxDQUFDLElBQUksQ0FBQztFQUNqRTtFQ0ZlLFNBQVNza0Isa0JBQWtCQSxDQUFDdGtCLE9BQU8sRUFBRTtJQUNwRDtJQUNFLE9BQU8sQ0FBQyxDQUFDMGdCLFNBQVMsQ0FBQzFnQixPQUFPLENBQUMsR0FBR0EsT0FBTyxDQUFDd2dCLGFBQWE7SUFBQTtJQUNuRHhnQixPQUFPLENBQUNzQyxRQUFRLEtBQUtuQixNQUFNLENBQUNtQixRQUFRLEVBQUVxQyxlQUFlO0VBQ3ZEO0VDRmUsU0FBUzRmLGFBQWFBLENBQUN2a0IsT0FBTyxFQUFFO0lBQzdDLElBQUlvZ0IsV0FBVyxDQUFDcGdCLE9BQU8sQ0FBQyxLQUFLLE1BQU0sRUFBRTtNQUNuQyxPQUFPQSxPQUFPO0lBQ2xCO0lBRUU7TUFBQTtNQUNGO01BQ0E7TUFDSUEsT0FBTyxDQUFDd2tCLFlBQVk7TUFBQTtNQUNwQnhrQixPQUFPLENBQUNpRSxVQUFVO01BQUE7TUFDbEI2YyxZQUFZLENBQUM5Z0IsT0FBTyxDQUFDLEdBQUdBLE9BQU8sQ0FBQ21rQixJQUFJLEdBQUcsSUFBSSxDQUFDO01BQUE7TUFDaEQ7TUFDSUcsa0JBQWtCLENBQUN0a0IsT0FBTyxDQUFDO0lBQUE7RUFHL0I7RUNWQSxTQUFTeWtCLG1CQUFtQkEsQ0FBQ3prQixPQUFPLEVBQUU7SUFDcEMsSUFBSSxDQUFDNGdCLGFBQWEsQ0FBQzVnQixPQUFPLENBQUM7SUFBQTtJQUMzQm9rQixrQkFBZ0IsQ0FBQ3BrQixPQUFPLENBQUMsQ0FBQzBoQixRQUFRLEtBQUssT0FBTyxFQUFFO01BQzlDLE9BQU8sSUFBSTtJQUNmO0lBRUUsT0FBTzFoQixPQUFPLENBQUMwa0IsWUFBWTtFQUM3QixDQUFDO0VBQ0Q7O0VBR0EsU0FBU0Msa0JBQWtCQSxDQUFDM2tCLE9BQU8sRUFBRTtJQUNuQyxJQUFJNGtCLFNBQVMsR0FBRyxVQUFVLENBQUMzVixJQUFJLENBQUN1VCxXQUFXLEVBQUUsQ0FBQztJQUM5QyxJQUFJcUMsSUFBSSxHQUFHLFVBQVUsQ0FBQzVWLElBQUksQ0FBQ3VULFdBQVcsRUFBRSxDQUFDO0lBRXpDLElBQUlxQyxJQUFJLElBQUlqRSxhQUFhLENBQUM1Z0IsT0FBTyxDQUFDLEVBQUU7TUFDdEM7TUFDSSxJQUFJOGtCLFVBQVUsR0FBR1Ysa0JBQWdCLENBQUNwa0IsT0FBTyxDQUFDO01BRTFDLElBQUk4a0IsVUFBVSxDQUFDcEQsUUFBUSxLQUFLLE9BQU8sRUFBRTtRQUNuQyxPQUFPLElBQUk7TUFDakI7SUFDQTtJQUVFLElBQUlxRCxXQUFXLEdBQUdSLGFBQWEsQ0FBQ3ZrQixPQUFPLENBQUM7SUFFeEMsSUFBSThnQixZQUFZLENBQUNpRSxXQUFXLENBQUMsRUFBRTtNQUM3QkEsV0FBVyxHQUFHQSxXQUFXLENBQUNaLElBQUk7SUFDbEM7SUFFRSxPQUFPdkQsYUFBYSxDQUFDbUUsV0FBVyxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsTUFBTSxDQUFDLENBQUNoZCxPQUFPLENBQUNxWSxXQUFXLENBQUMyRSxXQUFXLENBQUMsQ0FBQyxHQUFHLENBQUMsRUFBRTtNQUMzRixJQUFJQyxHQUFHLEdBQUdaLGtCQUFnQixDQUFDVyxXQUFXLENBQUMsQ0FBQztNQUM1QztNQUNBOztNQUVJLElBQUlDLEdBQUcsQ0FBQ0MsU0FBUyxLQUFLLE1BQU0sSUFBSUQsR0FBRyxDQUFDRSxXQUFXLEtBQUssTUFBTSxJQUFJRixHQUFHLENBQUNHLE9BQU8sS0FBSyxPQUFPLElBQUksQ0FBQyxXQUFXLEVBQUUsYUFBYSxDQUFDLENBQUNwZCxPQUFPLENBQUNpZCxHQUFHLENBQUNJLFVBQVUsQ0FBQyxLQUFLLENBQUMsQ0FBQyxJQUFJUixTQUFTLElBQUlJLEdBQUcsQ0FBQ0ksVUFBVSxLQUFLLFFBQVEsSUFBSVIsU0FBUyxJQUFJSSxHQUFHLENBQUNuWCxNQUFNLElBQUltWCxHQUFHLENBQUNuWCxNQUFNLEtBQUssTUFBTSxFQUFFO1FBQ3BQLE9BQU9rWCxXQUFXO01BQ3hCLENBQUssTUFBTTtRQUNMQSxXQUFXLEdBQUdBLFdBQVcsQ0FBQzlnQixVQUFVO01BQzFDO0lBQ0E7SUFFRSxPQUFPLElBQUk7RUFDYixDQUFDO0VBQ0Q7O0VBR2UsU0FBU29oQixlQUFlQSxDQUFDcmxCLE9BQU8sRUFBRTtJQUMvQyxJQUFJbUIsTUFBTSxHQUFHbWYsU0FBUyxDQUFDdGdCLE9BQU8sQ0FBQztJQUMvQixJQUFJMGtCLFlBQVksR0FBR0QsbUJBQW1CLENBQUN6a0IsT0FBTyxDQUFDO0lBRS9DLE9BQU8wa0IsWUFBWSxJQUFJTCxjQUFjLENBQUNLLFlBQVksQ0FBQyxJQUFJTixrQkFBZ0IsQ0FBQ00sWUFBWSxDQUFDLENBQUNoRCxRQUFRLEtBQUssUUFBUSxFQUFFO01BQzNHZ0QsWUFBWSxHQUFHRCxtQkFBbUIsQ0FBQ0MsWUFBWSxDQUFDO0lBQ3BEO0lBRUUsSUFBSUEsWUFBWSxLQUFLdEUsV0FBVyxDQUFDc0UsWUFBWSxDQUFDLEtBQUssTUFBTSxJQUFJdEUsV0FBVyxDQUFDc0UsWUFBWSxDQUFDLEtBQUssTUFBTSxJQUFJTixrQkFBZ0IsQ0FBQ00sWUFBWSxDQUFDLENBQUNoRCxRQUFRLEtBQUssUUFBUSxDQUFDLEVBQUU7TUFDMUosT0FBT3ZnQixNQUFNO0lBQ2pCO0lBRUUsT0FBT3VqQixZQUFZLElBQUlDLGtCQUFrQixDQUFDM2tCLE9BQU8sQ0FBQyxJQUFJbUIsTUFBTTtFQUM5RDtFQ3BFZSxTQUFTbWtCLHdCQUF3QkEsQ0FBQzlGLFNBQVMsRUFBRTtJQUMxRCxPQUFPLENBQUMsS0FBSyxFQUFFLFFBQVEsQ0FBQyxDQUFDelgsT0FBTyxDQUFDeVgsU0FBUyxDQUFDLElBQUksQ0FBQyxHQUFHLEdBQUcsR0FBRyxHQUFHO0VBQzlEO0VDRE8sU0FBUytGLE1BQU1BLENBQUNDLEtBQUcsRUFBRTlZLEtBQUssRUFBRStZLEtBQUcsRUFBRTtJQUN0QyxPQUFPemQsR0FBTyxDQUFDd2QsS0FBRyxFQUFFdmQsR0FBTyxDQUFDeUUsS0FBSyxFQUFFK1ksS0FBRyxDQUFDLENBQUM7RUFDMUM7RUFDTyxTQUFTQyxjQUFjQSxDQUFDemQsR0FBRyxFQUFFeUUsS0FBSyxFQUFFMUUsR0FBRyxFQUFFO0lBQzlDLElBQUkyZCxDQUFDLEdBQUdKLE1BQU0sQ0FBQ3RkLEdBQUcsRUFBRXlFLEtBQUssRUFBRTFFLEdBQUcsQ0FBQztJQUMvQixPQUFPMmQsQ0FBQyxHQUFHM2QsR0FBRyxHQUFHQSxHQUFHLEdBQUcyZCxDQUFDO0VBQzFCO0VDUGUsU0FBU0Msa0JBQWtCQSxDQUFBLEVBQUc7SUFDM0MsT0FBTztNQUNMbkgsR0FBRyxFQUFFLENBQUM7TUFDTkUsS0FBSyxFQUFFLENBQUM7TUFDUkQsTUFBTSxFQUFFLENBQUM7TUFDVEUsSUFBSSxFQUFFO0lBQ1YsQ0FBRztFQUNIO0VDTmUsU0FBU2lILGtCQUFrQkEsQ0FBQ0MsYUFBYSxFQUFFO0lBQ3hELE9BQU9sa0IsTUFBTSxDQUFDeWYsTUFBTSxDQUFDLEVBQUUsRUFBRXVFLGtCQUFrQixFQUFFLEVBQUVFLGFBQWEsQ0FBQztFQUMvRDtFQ0hlLFNBQVNDLGVBQWVBLENBQUNyWixLQUFLLEVBQUUvTCxJQUFJLEVBQUU7SUFDbkQsT0FBT0EsSUFBSSxDQUFDMmUsTUFBTSxDQUFDLFVBQVUwRyxPQUFPLEVBQUUvbEIsR0FBRyxFQUFFO01BQ3pDK2xCLE9BQU8sQ0FBQy9sQixHQUFHLENBQUMsR0FBR3lNLEtBQUs7TUFDcEIsT0FBT3NaLE9BQU87SUFDbEIsQ0FBRyxFQUFFLEVBQUUsQ0FBQztFQUNSO0VDS0EsSUFBSUMsZUFBZSxHQUFHLFNBQVNBLGVBQWVBLENBQUNDLE9BQU8sRUFBRWpGLEtBQUssRUFBRTtJQUM3RGlGLE9BQU8sR0FBRyxPQUFPQSxPQUFPLEtBQUssVUFBVSxHQUFHQSxPQUFPLENBQUN0a0IsTUFBTSxDQUFDeWYsTUFBTSxDQUFDLEVBQUUsRUFBRUosS0FBSyxDQUFDa0YsS0FBSyxFQUFFO01BQy9FM0csU0FBUyxFQUFFeUIsS0FBSyxDQUFDekI7SUFDckIsQ0FBRyxDQUFDLENBQUMsR0FBRzBHLE9BQU87SUFDYixPQUFPTCxrQkFBa0IsQ0FBQyxPQUFPSyxPQUFPLEtBQUssUUFBUSxHQUFHQSxPQUFPLEdBQUdILGVBQWUsQ0FBQ0csT0FBTyxFQUFFcEgsY0FBYyxDQUFDLENBQUM7RUFDN0csQ0FBQztFQUVELFNBQVNnRCxLQUFLQSxDQUFDZCxJQUFJLEVBQUU7SUFDbkIsSUFBSW9GLHFCQUFxQjtJQUV6QixJQUFJbkYsS0FBSyxHQUFHRCxJQUFJLENBQUNDLEtBQUs7TUFDbEJoYixJQUFJLEdBQUcrYSxJQUFJLENBQUMvYSxJQUFJO01BQ2hCMGIsT0FBTyxHQUFHWCxJQUFJLENBQUNXLE9BQU87SUFDMUIsSUFBSTBFLFlBQVksR0FBR3BGLEtBQUssQ0FBQ0MsUUFBUSxDQUFDWSxLQUFLO0lBQ3ZDLElBQUl3RSxhQUFhLEdBQUdyRixLQUFLLENBQUNzRixhQUFhLENBQUNELGFBQWE7SUFDckQsSUFBSUUsYUFBYSxHQUFHbEUsZ0JBQWdCLENBQUNyQixLQUFLLENBQUN6QixTQUFTLENBQUM7SUFDckQsSUFBSWlILElBQUksR0FBR25CLHdCQUF3QixDQUFDa0IsYUFBYSxDQUFDO0lBQ2xELElBQUlFLFVBQVUsR0FBRyxDQUFDOUgsSUFBSSxFQUFFRCxLQUFLLENBQUMsQ0FBQzVXLE9BQU8sQ0FBQ3llLGFBQWEsQ0FBQyxJQUFJLENBQUM7SUFDMUQsSUFBSUcsR0FBRyxHQUFHRCxVQUFVLEdBQUcsUUFBUSxHQUFHLE9BQU87SUFFekMsSUFBSSxDQUFDTCxZQUFZLElBQUksQ0FBQ0MsYUFBYSxFQUFFO01BQ25DO0lBQ0o7SUFFRSxJQUFJUixhQUFhLEdBQUdHLGVBQWUsQ0FBQ3RFLE9BQU8sQ0FBQ3VFLE9BQU8sRUFBRWpGLEtBQUssQ0FBQztJQUMzRCxJQUFJMkYsU0FBUyxHQUFHNUMsYUFBYSxDQUFDcUMsWUFBWSxDQUFDO0lBQzNDLElBQUlRLE9BQU8sR0FBR0osSUFBSSxLQUFLLEdBQUcsR0FBR2hJLEdBQUcsR0FBR0csSUFBSTtJQUN2QyxJQUFJa0ksT0FBTyxHQUFHTCxJQUFJLEtBQUssR0FBRyxHQUFHL0gsTUFBTSxHQUFHQyxLQUFLO0lBQzNDLElBQUlvSSxPQUFPLEdBQUc5RixLQUFLLENBQUNrRixLQUFLLENBQUMvRyxTQUFTLENBQUN1SCxHQUFHLENBQUMsR0FBRzFGLEtBQUssQ0FBQ2tGLEtBQUssQ0FBQy9HLFNBQVMsQ0FBQ3FILElBQUksQ0FBQyxHQUFHSCxhQUFhLENBQUNHLElBQUksQ0FBQyxHQUFHeEYsS0FBSyxDQUFDa0YsS0FBSyxDQUFDaEgsTUFBTSxDQUFDd0gsR0FBRyxDQUFDO0lBQ3RILElBQUlLLFNBQVMsR0FBR1YsYUFBYSxDQUFDRyxJQUFJLENBQUMsR0FBR3hGLEtBQUssQ0FBQ2tGLEtBQUssQ0FBQy9HLFNBQVMsQ0FBQ3FILElBQUksQ0FBQztJQUNqRSxJQUFJUSxpQkFBaUIsR0FBRzVCLGVBQWUsQ0FBQ2dCLFlBQVksQ0FBQztJQUNyRCxJQUFJYSxVQUFVLEdBQUdELGlCQUFpQixHQUFHUixJQUFJLEtBQUssR0FBRyxHQUFHUSxpQkFBaUIsQ0FBQ0UsWUFBWSxJQUFJLENBQUMsR0FBR0YsaUJBQWlCLENBQUNHLFdBQVcsSUFBSSxDQUFDLEdBQUcsQ0FBQztJQUNoSSxJQUFJQyxpQkFBaUIsR0FBR04sT0FBTyxHQUFHLENBQUMsR0FBR0MsU0FBUyxHQUFHLENBQUMsQ0FBQztJQUN0RDs7SUFFRSxJQUFJL2UsR0FBRyxHQUFHNmQsYUFBYSxDQUFDZSxPQUFPLENBQUM7SUFDaEMsSUFBSTdlLEdBQUcsR0FBR2tmLFVBQVUsR0FBR04sU0FBUyxDQUFDRCxHQUFHLENBQUMsR0FBR2IsYUFBYSxDQUFDZ0IsT0FBTyxDQUFDO0lBQzlELElBQUlRLE1BQU0sR0FBR0osVUFBVSxHQUFHLENBQUMsR0FBR04sU0FBUyxDQUFDRCxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUdVLGlCQUFpQjtJQUNwRSxJQUFJRSxNQUFNLEdBQUdoQyxNQUFNLENBQUN0ZCxHQUFHLEVBQUVxZixNQUFNLEVBQUV0ZixHQUFHLENBQUMsQ0FBQzs7SUFFdEMsSUFBSXdmLFFBQVEsR0FBR2YsSUFBSTtJQUNuQnhGLEtBQUssQ0FBQ3NGLGFBQWEsQ0FBQ3RnQixJQUFJLENBQUMsSUFBSW1nQixxQkFBcUIsR0FBRyxFQUFFLEVBQUVBLHFCQUFxQixDQUFDb0IsUUFBUSxDQUFDLEdBQUdELE1BQU0sRUFBRW5CLHFCQUFxQixDQUFDcUIsWUFBWSxHQUFHRixNQUFNLEdBQUdELE1BQU0sRUFBRWxCLHFCQUFxQixDQUFDO0VBQ2pMO0VBRUEsU0FBU3NCLFFBQU1uRyxDQUFDQyxLQUFLLEVBQUU7SUFDckIsSUFBSVAsS0FBSyxHQUFHTyxLQUFLLENBQUNQLEtBQUs7TUFDbkJVLE9BQU8sR0FBR0gsS0FBSyxDQUFDRyxPQUFPO0lBQzNCLElBQUlnRyxnQkFBZ0IsR0FBR2hHLE9BQU8sQ0FBQzNoQixPQUFPO01BQ2xDcW1CLFlBQVksR0FBR3NCLGdCQUFnQixLQUFLLEtBQUssQ0FBQyxHQUFHLHFCQUFxQixHQUFHQSxnQkFBZ0I7SUFFekYsSUFBSXRCLFlBQVksSUFBSSxJQUFJLEVBQUU7TUFDeEI7SUFDSixDQUFHOztJQUdELElBQUksT0FBT0EsWUFBWSxLQUFLLFFBQVEsRUFBRTtNQUNwQ0EsWUFBWSxHQUFHcEYsS0FBSyxDQUFDQyxRQUFRLENBQUMvQixNQUFNLENBQUMxYixhQUFhLENBQUM0aUIsWUFBWSxDQUFDO01BRWhFLElBQUksQ0FBQ0EsWUFBWSxFQUFFO1FBQ2pCO01BQ047SUFDQTtJQUVFLElBQUksQ0FBQy9oQixRQUFRLENBQUMyYyxLQUFLLENBQUNDLFFBQVEsQ0FBQy9CLE1BQU0sRUFBRWtILFlBQVksQ0FBQyxFQUFFO01BQ2xEO0lBQ0o7SUFFRXBGLEtBQUssQ0FBQ0MsUUFBUSxDQUFDWSxLQUFLLEdBQUd1RSxZQUFZO0VBQ3JDLENBQUM7O0VBR0QsTUFBQXVCLE9BQUEsR0FBZTtJQUNiM2hCLElBQUksRUFBRSxPQUFPO0lBQ2JrYyxPQUFPLEVBQUUsSUFBSTtJQUNiQyxLQUFLLEVBQUUsTUFBTTtJQUNiaGMsRUFBRSxFQUFFMGIsS0FBSztJQUNUUCxNQUFNLEVBQUVtRyxRQUFNO0lBQ2RyRixRQUFRLEVBQUUsQ0FBQyxlQUFlLENBQUM7SUFDM0J3RixnQkFBZ0IsRUFBRSxDQUFDLGlCQUFpQjtFQUN0QyxDQUFDO0VDekZjLFNBQVNDLFlBQVlBLENBQUN0SSxTQUFTLEVBQUU7SUFDOUMsT0FBT0EsU0FBUyxDQUFDeGMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztFQUNoQztFQ09BLElBQUkra0IsVUFBVSxHQUFHO0lBQ2Z0SixHQUFHLEVBQUUsTUFBTTtJQUNYRSxLQUFLLEVBQUUsTUFBTTtJQUNiRCxNQUFNLEVBQUUsTUFBTTtJQUNkRSxJQUFJLEVBQUU7RUFDUixDQUFDLENBQUM7RUFDRjtFQUNBOztFQUVBLFNBQVNvSixpQkFBaUJBLENBQUNoSCxJQUFJLEVBQUVpSCxHQUFHLEVBQUU7SUFDcEMsSUFBSXJFLENBQUMsR0FBRzVDLElBQUksQ0FBQzRDLENBQUM7TUFDVkUsQ0FBQyxHQUFHOUMsSUFBSSxDQUFDOEMsQ0FBQztJQUNkLElBQUlvRSxHQUFHLEdBQUdELEdBQUcsQ0FBQ0UsZ0JBQWdCLElBQUksQ0FBQztJQUNuQyxPQUFPO01BQ0x2RSxDQUFDLEVBQUVyQixLQUFLLENBQUNxQixDQUFDLEdBQUdzRSxHQUFHLENBQUMsR0FBR0EsR0FBRyxJQUFJLENBQUM7TUFDNUJwRSxDQUFDLEVBQUV2QixLQUFLLENBQUN1QixDQUFDLEdBQUdvRSxHQUFHLENBQUMsR0FBR0EsR0FBRyxJQUFJO0lBQy9CLENBQUc7RUFDSDtFQUVPLFNBQVNFLFdBQVdBLENBQUM1RyxLQUFLLEVBQUU7SUFDakMsSUFBSTZHLGVBQWU7SUFFbkIsSUFBSWxKLE1BQU0sR0FBR3FDLEtBQUssQ0FBQ3JDLE1BQU07TUFDckJtSixVQUFVLEdBQUc5RyxLQUFLLENBQUM4RyxVQUFVO01BQzdCOUksU0FBUyxHQUFHZ0MsS0FBSyxDQUFDaEMsU0FBUztNQUMzQitJLFNBQVMsR0FBRy9HLEtBQUssQ0FBQytHLFNBQVM7TUFDM0JDLE9BQU8sR0FBR2hILEtBQUssQ0FBQ2dILE9BQU87TUFDdkI5RyxRQUFRLEdBQUdGLEtBQUssQ0FBQ0UsUUFBUTtNQUN6QitHLGVBQWUsR0FBR2pILEtBQUssQ0FBQ2lILGVBQWU7TUFDdkNDLFFBQVEsR0FBR2xILEtBQUssQ0FBQ2tILFFBQVE7TUFDekJDLFlBQVksR0FBR25ILEtBQUssQ0FBQ21ILFlBQVk7TUFDakNDLE9BQU8sR0FBR3BILEtBQUssQ0FBQ29ILE9BQU87SUFDM0IsSUFBSUMsVUFBVSxHQUFHTCxPQUFPLENBQUM1RSxDQUFDO01BQ3RCQSxDQUFDLEdBQUdpRixVQUFVLEtBQUssS0FBSyxDQUFDLEdBQUcsQ0FBQyxHQUFHQSxVQUFVO01BQzFDQyxVQUFVLEdBQUdOLE9BQU8sQ0FBQzFFLENBQUM7TUFDdEJBLENBQUMsR0FBR2dGLFVBQVUsS0FBSyxLQUFLLENBQUMsR0FBRyxDQUFDLEdBQUdBLFVBQVU7SUFFOUMsSUFBSUMsS0FBSyxHQUFHLE9BQU9KLFlBQVksS0FBSyxVQUFVLEdBQUdBLFlBQVksQ0FBQztNQUM1RC9FLENBQUMsRUFBRUEsQ0FBQztNQUNKRSxDQUFDLEVBQUVBO0lBQ1AsQ0FBRyxDQUFDLEdBQUc7TUFDSEYsQ0FBQyxFQUFFQSxDQUFDO01BQ0pFLENBQUMsRUFBRUE7SUFDUCxDQUFHO0lBRURGLENBQUMsR0FBR21GLEtBQUssQ0FBQ25GLENBQUM7SUFDWEUsQ0FBQyxHQUFHaUYsS0FBSyxDQUFDakYsQ0FBQztJQUNYLElBQUlrRixJQUFJLEdBQUdSLE9BQU8sQ0FBQ3hHLGNBQWMsQ0FBQyxHQUFHLENBQUM7SUFDdEMsSUFBSWlILElBQUksR0FBR1QsT0FBTyxDQUFDeEcsY0FBYyxDQUFDLEdBQUcsQ0FBQztJQUN0QyxJQUFJa0gsS0FBSyxHQUFHdEssSUFBSTtJQUNoQixJQUFJdUssS0FBSyxHQUFHMUssR0FBRztJQUNmLElBQUl3SixHQUFHLEdBQUc5bUIsTUFBTTtJQUVoQixJQUFJdW5CLFFBQVEsRUFBRTtNQUNaLElBQUloRSxZQUFZLEdBQUdXLGVBQWUsQ0FBQ2xHLE1BQU0sQ0FBQztNQUMxQyxJQUFJaUssVUFBVSxHQUFHLGNBQWM7TUFDL0IsSUFBSUMsU0FBUyxHQUFHLGFBQWE7TUFFN0IsSUFBSTNFLFlBQVksS0FBS3BFLFNBQVMsQ0FBQ25CLE1BQU0sQ0FBQyxFQUFFO1FBQ3RDdUYsWUFBWSxHQUFHSixrQkFBa0IsQ0FBQ25GLE1BQU0sQ0FBQztRQUV6QyxJQUFJaUYsa0JBQWdCLENBQUNNLFlBQVksQ0FBQyxDQUFDaEQsUUFBUSxLQUFLLFFBQVEsSUFBSUEsUUFBUSxLQUFLLFVBQVUsRUFBRTtVQUNuRjBILFVBQVUsR0FBRyxjQUFjO1VBQzNCQyxTQUFTLEdBQUcsYUFBYTtRQUNqQztNQUNBLENBQUs7O01BR0QzRSxZQUFZLEdBQUdBLFlBQVk7TUFFM0IsSUFBSWxGLFNBQVMsS0FBS2YsR0FBRyxJQUFJLENBQUNlLFNBQVMsS0FBS1osSUFBSSxJQUFJWSxTQUFTLEtBQUtiLEtBQUssS0FBSzRKLFNBQVMsS0FBS3ZKLEdBQUcsRUFBRTtRQUN6Rm1LLEtBQUssR0FBR3pLLE1BQU07UUFDZCxJQUFJNEssT0FBTyxHQUFHVixPQUFPLElBQUlsRSxZQUFZLEtBQUt1RCxHQUFHLElBQUlBLEdBQUcsQ0FBQ3ZFLGNBQWMsR0FBR3VFLEdBQUcsQ0FBQ3ZFLGNBQWMsQ0FBQ0QsTUFBTTtRQUFBO1FBQy9GaUIsWUFBWSxDQUFDMEUsVUFBVSxDQUFDO1FBQ3hCdEYsQ0FBQyxJQUFJd0YsT0FBTyxHQUFHaEIsVUFBVSxDQUFDN0UsTUFBTTtRQUNoQ0ssQ0FBQyxJQUFJMkUsZUFBZSxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7TUFDbkM7TUFFSSxJQUFJakosU0FBUyxLQUFLWixJQUFJLElBQUksQ0FBQ1ksU0FBUyxLQUFLZixHQUFHLElBQUllLFNBQVMsS0FBS2QsTUFBTSxLQUFLNkosU0FBUyxLQUFLdkosR0FBRyxFQUFFO1FBQzFGa0ssS0FBSyxHQUFHdkssS0FBSztRQUNiLElBQUk0SyxPQUFPLEdBQUdYLE9BQU8sSUFBSWxFLFlBQVksS0FBS3VELEdBQUcsSUFBSUEsR0FBRyxDQUFDdkUsY0FBYyxHQUFHdUUsR0FBRyxDQUFDdkUsY0FBYyxDQUFDRixLQUFLO1FBQUE7UUFDOUZrQixZQUFZLENBQUMyRSxTQUFTLENBQUM7UUFDdkJ6RixDQUFDLElBQUkyRixPQUFPLEdBQUdqQixVQUFVLENBQUM5RSxLQUFLO1FBQy9CSSxDQUFDLElBQUk2RSxlQUFlLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQztNQUNuQztJQUNBO0lBRUUsSUFBSWUsWUFBWSxHQUFHNW5CLE1BQU0sQ0FBQ3lmLE1BQU0sQ0FBQztNQUMvQkssUUFBUSxFQUFFQTtJQUNkLENBQUcsRUFBRWdILFFBQVEsSUFBSVgsVUFBVSxDQUFDO0lBRTFCLElBQUkwQixLQUFLLEdBQUdkLFlBQVksS0FBSyxJQUFJLEdBQUdYLGlCQUFpQixDQUFDO01BQ3BEcEUsQ0FBQyxFQUFFQSxDQUFDO01BQ0pFLENBQUMsRUFBRUE7SUFDUCxDQUFHLEVBQUV4RCxTQUFTLENBQUNuQixNQUFNLENBQUMsQ0FBQyxHQUFHO01BQ3RCeUUsQ0FBQyxFQUFFQSxDQUFDO01BQ0pFLENBQUMsRUFBRUE7SUFDUCxDQUFHO0lBRURGLENBQUMsR0FBRzZGLEtBQUssQ0FBQzdGLENBQUM7SUFDWEUsQ0FBQyxHQUFHMkYsS0FBSyxDQUFDM0YsQ0FBQztJQUVYLElBQUkyRSxlQUFlLEVBQUU7TUFDbkIsSUFBSWlCLGNBQWM7TUFFbEIsT0FBTzluQixNQUFNLENBQUN5ZixNQUFNLENBQUMsRUFBRSxFQUFFbUksWUFBWSxHQUFHRSxjQUFjLEdBQUcsRUFBRSxFQUFFQSxjQUFjLENBQUNQLEtBQUssQ0FBQyxHQUFHRixJQUFJLEdBQUcsR0FBRyxHQUFHLEVBQUUsRUFBRVMsY0FBYyxDQUFDUixLQUFLLENBQUMsR0FBR0YsSUFBSSxHQUFHLEdBQUcsR0FBRyxFQUFFLEVBQUVVLGNBQWMsQ0FBQ3pFLFNBQVMsR0FBRyxDQUFDZ0QsR0FBRyxDQUFDRSxnQkFBZ0IsSUFBSSxDQUFDLEtBQUssQ0FBQyxHQUFHLFlBQVksR0FBR3ZFLENBQUMsR0FBRyxNQUFNLEdBQUdFLENBQUMsR0FBRyxLQUFLLEdBQUcsY0FBYyxHQUFHRixDQUFDLEdBQUcsTUFBTSxHQUFHRSxDQUFDLEdBQUcsUUFBUSxFQUFFNEYsY0FBYyxFQUFFO0lBQ3JUO0lBRUUsT0FBTzluQixNQUFNLENBQUN5ZixNQUFNLENBQUMsRUFBRSxFQUFFbUksWUFBWSxHQUFHbkIsZUFBZSxHQUFHLEVBQUUsRUFBRUEsZUFBZSxDQUFDYyxLQUFLLENBQUMsR0FBR0YsSUFBSSxHQUFHbkYsQ0FBQyxHQUFHLElBQUksR0FBRyxFQUFFLEVBQUV1RSxlQUFlLENBQUNhLEtBQUssQ0FBQyxHQUFHRixJQUFJLEdBQUdwRixDQUFDLEdBQUcsSUFBSSxHQUFHLEVBQUUsRUFBRXlFLGVBQWUsQ0FBQ3BELFNBQVMsR0FBRyxFQUFFLEVBQUVvRCxlQUFlLEVBQUU7RUFDL007RUFFQSxTQUFTc0IsYUFBYUEsQ0FBQ0MsS0FBSyxFQUFFO0lBQzVCLElBQUkzSSxLQUFLLEdBQUcySSxLQUFLLENBQUMzSSxLQUFLO01BQ25CVSxPQUFPLEdBQUdpSSxLQUFLLENBQUNqSSxPQUFPO0lBQzNCLElBQUlrSSxxQkFBcUIsR0FBR2xJLE9BQU8sQ0FBQzhHLGVBQWU7TUFDL0NBLGVBQWUsR0FBR29CLHFCQUFxQixLQUFLLEtBQUssQ0FBQyxHQUFHLElBQUksR0FBR0EscUJBQXFCO01BQ2pGQyxpQkFBaUIsR0FBR25JLE9BQU8sQ0FBQytHLFFBQVE7TUFDcENBLFFBQVEsR0FBR29CLGlCQUFpQixLQUFLLEtBQUssQ0FBQyxHQUFHLElBQUksR0FBR0EsaUJBQWlCO01BQ2xFQyxxQkFBcUIsR0FBR3BJLE9BQU8sQ0FBQ2dILFlBQVk7TUFDNUNBLFlBQVksR0FBR29CLHFCQUFxQixLQUFLLEtBQUssQ0FBQyxHQUFHLElBQUksR0FBR0EscUJBQXFCO0lBQ2xGLElBQUlQLFlBQVksR0FBRztNQUNqQmhLLFNBQVMsRUFBRThDLGdCQUFnQixDQUFDckIsS0FBSyxDQUFDekIsU0FBUyxDQUFDO01BQzVDK0ksU0FBUyxFQUFFVCxZQUFZLENBQUM3RyxLQUFLLENBQUN6QixTQUFTLENBQUM7TUFDeENMLE1BQU0sRUFBRThCLEtBQUssQ0FBQ0MsUUFBUSxDQUFDL0IsTUFBTTtNQUM3Qm1KLFVBQVUsRUFBRXJILEtBQUssQ0FBQ2tGLEtBQUssQ0FBQ2hILE1BQU07TUFDOUJzSixlQUFlLEVBQUVBLGVBQWU7TUFDaENHLE9BQU8sRUFBRTNILEtBQUssQ0FBQ1UsT0FBTyxDQUFDQyxRQUFRLEtBQUs7SUFDeEMsQ0FBRztJQUVELElBQUlYLEtBQUssQ0FBQ3NGLGFBQWEsQ0FBQ0QsYUFBYSxJQUFJLElBQUksRUFBRTtNQUM3Q3JGLEtBQUssQ0FBQ0csTUFBTSxDQUFDakMsTUFBTSxHQUFHdmQsTUFBTSxDQUFDeWYsTUFBTSxDQUFDLEVBQUUsRUFBRUosS0FBSyxDQUFDRyxNQUFNLENBQUNqQyxNQUFNLEVBQUVpSixXQUFXLENBQUN4bUIsTUFBTSxDQUFDeWYsTUFBTSxDQUFDLEVBQUUsRUFBRW1JLFlBQVksRUFBRTtRQUN2R2hCLE9BQU8sRUFBRXZILEtBQUssQ0FBQ3NGLGFBQWEsQ0FBQ0QsYUFBYTtRQUMxQzVFLFFBQVEsRUFBRVQsS0FBSyxDQUFDVSxPQUFPLENBQUNDLFFBQVE7UUFDaEM4RyxRQUFRLEVBQUVBLFFBQVE7UUFDbEJDLFlBQVksRUFBRUE7TUFDcEIsQ0FBSyxDQUFDLENBQUMsQ0FBQztJQUNSO0lBRUUsSUFBSTFILEtBQUssQ0FBQ3NGLGFBQWEsQ0FBQ3pFLEtBQUssSUFBSSxJQUFJLEVBQUU7TUFDckNiLEtBQUssQ0FBQ0csTUFBTSxDQUFDVSxLQUFLLEdBQUdsZ0IsTUFBTSxDQUFDeWYsTUFBTSxDQUFDLEVBQUUsRUFBRUosS0FBSyxDQUFDRyxNQUFNLENBQUNVLEtBQUssRUFBRXNHLFdBQVcsQ0FBQ3htQixNQUFNLENBQUN5ZixNQUFNLENBQUMsRUFBRSxFQUFFbUksWUFBWSxFQUFFO1FBQ3JHaEIsT0FBTyxFQUFFdkgsS0FBSyxDQUFDc0YsYUFBYSxDQUFDekUsS0FBSztRQUNsQ0osUUFBUSxFQUFFLFVBQVU7UUFDcEJnSCxRQUFRLEVBQUUsS0FBSztRQUNmQyxZQUFZLEVBQUVBO01BQ3BCLENBQUssQ0FBQyxDQUFDLENBQUM7SUFDUjtJQUVFMUgsS0FBSyxDQUFDdlQsVUFBVSxDQUFDeVIsTUFBTSxHQUFHdmQsTUFBTSxDQUFDeWYsTUFBTSxDQUFDLEVBQUUsRUFBRUosS0FBSyxDQUFDdlQsVUFBVSxDQUFDeVIsTUFBTSxFQUFFO01BQ25FLHVCQUF1QixFQUFFOEIsS0FBSyxDQUFDekI7SUFDbkMsQ0FBRyxDQUFDO0VBQ0osQ0FBQzs7RUFHRCxNQUFBd0ssZUFBQSxHQUFlO0lBQ2IvakIsSUFBSSxFQUFFLGVBQWU7SUFDckJrYyxPQUFPLEVBQUUsSUFBSTtJQUNiQyxLQUFLLEVBQUUsYUFBYTtJQUNwQmhjLEVBQUUsRUFBRXVqQixhQUFhO0lBQ2pCOVcsSUFBSSxFQUFFO0VBQ1IsQ0FBQztFQ3RLRCxJQUFJb1gsT0FBTyxHQUFHO0lBQ1pBLE9BQU8sRUFBRTtFQUNYLENBQUM7RUFFRCxTQUFTMUksTUFBTUEsQ0FBQ1AsSUFBSSxFQUFFO0lBQ3BCLElBQUlDLEtBQUssR0FBR0QsSUFBSSxDQUFDQyxLQUFLO01BQ2xCL2dCLFFBQVEsR0FBRzhnQixJQUFJLENBQUM5Z0IsUUFBUTtNQUN4QnloQixPQUFPLEdBQUdYLElBQUksQ0FBQ1csT0FBTztJQUMxQixJQUFJdUksZUFBZSxHQUFHdkksT0FBTyxDQUFDd0ksTUFBTTtNQUNoQ0EsTUFBTSxHQUFHRCxlQUFlLEtBQUssS0FBSyxDQUFDLEdBQUcsSUFBSSxHQUFHQSxlQUFlO01BQzVERSxlQUFlLEdBQUd6SSxPQUFPLENBQUMwSSxNQUFNO01BQ2hDQSxNQUFNLEdBQUdELGVBQWUsS0FBSyxLQUFLLENBQUMsR0FBRyxJQUFJLEdBQUdBLGVBQWU7SUFDaEUsSUFBSWpwQixNQUFNLEdBQUdtZixTQUFTLENBQUNXLEtBQUssQ0FBQ0MsUUFBUSxDQUFDL0IsTUFBTSxDQUFDO0lBQzdDLElBQUltTCxhQUFhLEdBQUcsRUFBRSxDQUFDN1osTUFBTSxDQUFDd1EsS0FBSyxDQUFDcUosYUFBYSxDQUFDbEwsU0FBUyxFQUFFNkIsS0FBSyxDQUFDcUosYUFBYSxDQUFDbkwsTUFBTSxDQUFDO0lBRXhGLElBQUlnTCxNQUFNLEVBQUU7TUFDVkcsYUFBYSxDQUFDbkosT0FBTyxDQUFDLFVBQVVvSixZQUFZLEVBQUU7UUFDNUNBLFlBQVksQ0FBQzdrQixnQkFBZ0IsQ0FBQyxRQUFRLEVBQUV4RixRQUFRLENBQUNzcUIsTUFBTSxFQUFFUCxPQUFPLENBQUM7TUFDdkUsQ0FBSyxDQUFDO0lBQ047SUFFRSxJQUFJSSxNQUFNLEVBQUU7TUFDVmxwQixNQUFNLENBQUN1RSxnQkFBZ0IsQ0FBQyxRQUFRLEVBQUV4RixRQUFRLENBQUNzcUIsTUFBTSxFQUFFUCxPQUFPLENBQUM7SUFDL0Q7SUFFRSxPQUFPLFlBQVk7TUFDakIsSUFBSUUsTUFBTSxFQUFFO1FBQ1ZHLGFBQWEsQ0FBQ25KLE9BQU8sQ0FBQyxVQUFVb0osWUFBWSxFQUFFO1VBQzVDQSxZQUFZLENBQUNqakIsbUJBQW1CLENBQUMsUUFBUSxFQUFFcEgsUUFBUSxDQUFDc3FCLE1BQU0sRUFBRVAsT0FBTyxDQUFDO1FBQzVFLENBQU8sQ0FBQztNQUNSO01BRUksSUFBSUksTUFBTSxFQUFFO1FBQ1ZscEIsTUFBTSxDQUFDbUcsbUJBQW1CLENBQUMsUUFBUSxFQUFFcEgsUUFBUSxDQUFDc3FCLE1BQU0sRUFBRVAsT0FBTyxDQUFDO01BQ3BFO0lBQ0EsQ0FBRztFQUNILENBQUM7O0VBR0QsTUFBQVEsY0FBQSxHQUFlO0lBQ2J4a0IsSUFBSSxFQUFFLGdCQUFnQjtJQUN0QmtjLE9BQU8sRUFBRSxJQUFJO0lBQ2JDLEtBQUssRUFBRSxPQUFPO0lBQ2RoYyxFQUFFLEVBQUUsU0FBU0EsRUFBRUEsQ0FBQSxFQUFHLEVBQUU7SUFDcEJtYixNQUFNLEVBQUVBLE1BQU07SUFDZDFPLElBQUksRUFBRTtFQUNSLENBQUM7RUNoREQsSUFBSTZYLE1BQUksR0FBRztJQUNUOUwsSUFBSSxFQUFFLE9BQU87SUFDYkQsS0FBSyxFQUFFLE1BQU07SUFDYkQsTUFBTSxFQUFFLEtBQUs7SUFDYkQsR0FBRyxFQUFFO0VBQ1AsQ0FBQztFQUNjLFNBQVNrTSxvQkFBb0JBLENBQUNuTCxTQUFTLEVBQUU7SUFDdEQsT0FBT0EsU0FBUyxDQUFDbGUsT0FBTyxDQUFDLHdCQUF3QixFQUFFLFVBQVVzcEIsT0FBTyxFQUFFO01BQ3BFLE9BQU9GLE1BQUksQ0FBQ0UsT0FBTyxDQUFDO0lBQ3hCLENBQUcsQ0FBQztFQUNKO0VDVkEsSUFBSUMsSUFBSSxHQUFHO0lBQ1Q5TCxLQUFLLEVBQUUsS0FBSztJQUNaQyxHQUFHLEVBQUU7RUFDUCxDQUFDO0VBQ2MsU0FBUzhMLDZCQUE2QkEsQ0FBQ3RMLFNBQVMsRUFBRTtJQUMvRCxPQUFPQSxTQUFTLENBQUNsZSxPQUFPLENBQUMsWUFBWSxFQUFFLFVBQVVzcEIsT0FBTyxFQUFFO01BQ3hELE9BQU9DLElBQUksQ0FBQ0QsT0FBTyxDQUFDO0lBQ3hCLENBQUcsQ0FBQztFQUNKO0VDUGUsU0FBU0csZUFBZUEsQ0FBQ3hLLElBQUksRUFBRTtJQUM1QyxJQUFJMEgsR0FBRyxHQUFHM0gsU0FBUyxDQUFDQyxJQUFJLENBQUM7SUFDekIsSUFBSXlLLFVBQVUsR0FBRy9DLEdBQUcsQ0FBQ2dELFdBQVc7SUFDaEMsSUFBSUMsU0FBUyxHQUFHakQsR0FBRyxDQUFDa0QsV0FBVztJQUMvQixPQUFPO01BQ0xILFVBQVUsRUFBRUEsVUFBVTtNQUN0QkUsU0FBUyxFQUFFQTtJQUNmLENBQUc7RUFDSDtFQ05lLFNBQVNFLG1CQUFtQkEsQ0FBQ3ByQixPQUFPLEVBQUU7SUFDckQ7SUFDQTtJQUNBO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUFDRSxPQUFPcWUscUJBQXFCLENBQUNpRyxrQkFBa0IsQ0FBQ3RrQixPQUFPLENBQUMsQ0FBQyxDQUFDNGUsSUFBSSxHQUFHbU0sZUFBZSxDQUFDL3FCLE9BQU8sQ0FBQyxDQUFDZ3JCLFVBQVU7RUFDdEc7RUNSZSxTQUFTSyxlQUFlQSxDQUFDcnJCLE9BQU8sRUFBRTRoQixRQUFRLEVBQUU7SUFDekQsSUFBSXFHLEdBQUcsR0FBRzNILFNBQVMsQ0FBQ3RnQixPQUFPLENBQUM7SUFDNUIsSUFBSXNyQixJQUFJLEdBQUdoSCxrQkFBa0IsQ0FBQ3RrQixPQUFPLENBQUM7SUFDdEMsSUFBSTBqQixjQUFjLEdBQUd1RSxHQUFHLENBQUN2RSxjQUFjO0lBQ3ZDLElBQUlGLEtBQUssR0FBRzhILElBQUksQ0FBQ2xFLFdBQVc7SUFDNUIsSUFBSTNELE1BQU0sR0FBRzZILElBQUksQ0FBQ25FLFlBQVk7SUFDOUIsSUFBSXZELENBQUMsR0FBRyxDQUFDO0lBQ1QsSUFBSUUsQ0FBQyxHQUFHLENBQUM7SUFFVCxJQUFJSixjQUFjLEVBQUU7TUFDbEJGLEtBQUssR0FBR0UsY0FBYyxDQUFDRixLQUFLO01BQzVCQyxNQUFNLEdBQUdDLGNBQWMsQ0FBQ0QsTUFBTTtNQUM5QixJQUFJOEgsY0FBYyxHQUFHdEksZ0JBQWdCLEVBQUU7TUFFdkMsSUFBSXNJLGNBQWMsSUFBSSxDQUFDQSxjQUFjLElBQUkzSixRQUFRLEtBQUssT0FBTyxFQUFFO1FBQzdEZ0MsQ0FBQyxHQUFHRixjQUFjLENBQUNHLFVBQVU7UUFDN0JDLENBQUMsR0FBR0osY0FBYyxDQUFDSyxTQUFTO01BQ2xDO0lBQ0E7SUFFRSxPQUFPO01BQ0xQLEtBQUssRUFBRUEsS0FBSztNQUNaQyxNQUFNLEVBQUVBLE1BQU07TUFDZEcsQ0FBQyxFQUFFQSxDQUFDLEdBQUd3SCxtQkFBbUIsQ0FBQ3ByQixPQUFPLENBQUM7TUFDbkM4akIsQ0FBQyxFQUFFQTtJQUNQLENBQUc7RUFDSDs7RUN6QkE7O0VBRWUsU0FBUzBILGVBQWVBLENBQUN4ckIsT0FBTyxFQUFFO0lBQy9DLElBQUl5ckIscUJBQXFCO0lBRXpCLElBQUlILElBQUksR0FBR2hILGtCQUFrQixDQUFDdGtCLE9BQU8sQ0FBQztJQUN0QyxJQUFJMHJCLFNBQVMsR0FBR1gsZUFBZSxDQUFDL3FCLE9BQU8sQ0FBQztJQUN4QyxJQUFJcUYsSUFBSSxHQUFHLENBQUNvbUIscUJBQXFCLEdBQUd6ckIsT0FBTyxDQUFDd2dCLGFBQWEsS0FBSyxJQUFJLEdBQUcsS0FBSyxDQUFDLEdBQUdpTCxxQkFBcUIsQ0FBQ3BtQixJQUFJO0lBQ3hHLElBQUltZSxLQUFLLEdBQUd4YixHQUFHLENBQUNzakIsSUFBSSxDQUFDSyxXQUFXLEVBQUVMLElBQUksQ0FBQ2xFLFdBQVcsRUFBRS9oQixJQUFJLEdBQUdBLElBQUksQ0FBQ3NtQixXQUFXLEdBQUcsQ0FBQyxFQUFFdG1CLElBQUksR0FBR0EsSUFBSSxDQUFDK2hCLFdBQVcsR0FBRyxDQUFDLENBQUM7SUFDN0csSUFBSTNELE1BQU0sR0FBR3piLEdBQUcsQ0FBQ3NqQixJQUFJLENBQUNNLFlBQVksRUFBRU4sSUFBSSxDQUFDbkUsWUFBWSxFQUFFOWhCLElBQUksR0FBR0EsSUFBSSxDQUFDdW1CLFlBQVksR0FBRyxDQUFDLEVBQUV2bUIsSUFBSSxHQUFHQSxJQUFJLENBQUM4aEIsWUFBWSxHQUFHLENBQUMsQ0FBQztJQUNsSCxJQUFJdkQsQ0FBQyxHQUFHLENBQUM4SCxTQUFTLENBQUNWLFVBQVUsR0FBR0ksbUJBQW1CLENBQUNwckIsT0FBTyxDQUFDO0lBQzVELElBQUk4akIsQ0FBQyxHQUFHLENBQUM0SCxTQUFTLENBQUNSLFNBQVM7SUFFNUIsSUFBSTlHLGtCQUFnQixDQUFDL2UsSUFBSSxJQUFJaW1CLElBQUksQ0FBQyxDQUFDL1YsU0FBUyxLQUFLLEtBQUssRUFBRTtNQUN0RHFPLENBQUMsSUFBSTViLEdBQUcsQ0FBQ3NqQixJQUFJLENBQUNsRSxXQUFXLEVBQUUvaEIsSUFBSSxHQUFHQSxJQUFJLENBQUMraEIsV0FBVyxHQUFHLENBQUMsQ0FBQyxHQUFHNUQsS0FBSztJQUNuRTtJQUVFLE9BQU87TUFDTEEsS0FBSyxFQUFFQSxLQUFLO01BQ1pDLE1BQU0sRUFBRUEsTUFBTTtNQUNkRyxDQUFDLEVBQUVBLENBQUM7TUFDSkUsQ0FBQyxFQUFFQTtJQUNQLENBQUc7RUFDSDtFQzNCZSxTQUFTK0gsY0FBY0EsQ0FBQzdyQixPQUFPLEVBQUU7SUFDaEQ7SUFDRSxJQUFJOHJCLGlCQUFpQixHQUFHMUgsa0JBQWdCLENBQUNwa0IsT0FBTyxDQUFDO01BQzdDK3JCLFFBQVEsR0FBR0QsaUJBQWlCLENBQUNDLFFBQVE7TUFDckNDLFNBQVMsR0FBR0YsaUJBQWlCLENBQUNFLFNBQVM7TUFDdkNDLFNBQVMsR0FBR0gsaUJBQWlCLENBQUNHLFNBQVM7SUFFM0MsT0FBTyw0QkFBNEIsQ0FBQ2hkLElBQUksQ0FBQzhjLFFBQVEsR0FBR0UsU0FBUyxHQUFHRCxTQUFTLENBQUM7RUFDNUU7RUNMZSxTQUFTRSxlQUFlQSxDQUFDM0wsSUFBSSxFQUFFO0lBQzVDLElBQUksQ0FBQyxNQUFNLEVBQUUsTUFBTSxFQUFFLFdBQVcsQ0FBQyxDQUFDeFksT0FBTyxDQUFDcVksV0FBVyxDQUFDRyxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsRUFBRTtNQUNyRTtNQUNJLE9BQU9BLElBQUksQ0FBQ0MsYUFBYSxDQUFDbmIsSUFBSTtJQUNsQztJQUVFLElBQUl1YixhQUFhLENBQUNMLElBQUksQ0FBQyxJQUFJc0wsY0FBYyxDQUFDdEwsSUFBSSxDQUFDLEVBQUU7TUFDL0MsT0FBT0EsSUFBSTtJQUNmO0lBRUUsT0FBTzJMLGVBQWUsQ0FBQzNILGFBQWEsQ0FBQ2hFLElBQUksQ0FBQyxDQUFDO0VBQzdDOztFQ1hBOzs7Ozs7O0VBT2UsU0FBUzRMLGlCQUFpQkEsQ0FBQ25zQixPQUFPLEVBQUV5SCxJQUFJLEVBQUU7SUFDdkQsSUFBSWdrQixxQkFBcUI7SUFFekIsSUFBSWhrQixJQUFJLEtBQUssS0FBSyxDQUFDLEVBQUU7TUFDbkJBLElBQUksR0FBRyxFQUFFO0lBQ2I7SUFFRSxJQUFJOGlCLFlBQVksR0FBRzJCLGVBQWUsQ0FBQ2xzQixPQUFPLENBQUM7SUFDM0MsSUFBSW9zQixNQUFNLEdBQUc3QixZQUFZLE1BQU0sQ0FBQ2tCLHFCQUFxQixHQUFHenJCLE9BQU8sQ0FBQ3dnQixhQUFhLEtBQUssSUFBSSxHQUFHLEtBQUssQ0FBQyxHQUFHaUwscUJBQXFCLENBQUNwbUIsSUFBSSxDQUFDO0lBQzdILElBQUk0aUIsR0FBRyxHQUFHM0gsU0FBUyxDQUFDaUssWUFBWSxDQUFDO0lBQ2pDLElBQUlsakIsTUFBTSxHQUFHK2tCLE1BQU0sR0FBRyxDQUFDbkUsR0FBRyxDQUFDLENBQUN4WCxNQUFNLENBQUN3WCxHQUFHLENBQUN2RSxjQUFjLElBQUksRUFBRSxFQUFFbUksY0FBYyxDQUFDdEIsWUFBWSxDQUFDLEdBQUdBLFlBQVksR0FBRyxFQUFFLENBQUMsR0FBR0EsWUFBWTtJQUM3SCxJQUFJOEIsV0FBVyxHQUFHNWtCLElBQUksQ0FBQ2dKLE1BQU0sQ0FBQ3BKLE1BQU0sQ0FBQztJQUNyQyxPQUFPK2tCLE1BQU0sR0FBR0MsV0FBVztJQUFBO0lBQzNCQSxXQUFXLENBQUM1YixNQUFNLENBQUMwYixpQkFBaUIsQ0FBQzVILGFBQWEsQ0FBQ2xkLE1BQU0sQ0FBQyxDQUFDLENBQUM7RUFDOUQ7RUN6QmUsU0FBU2lsQixnQkFBZ0JBLENBQUNDLElBQUksRUFBRTtJQUM3QyxPQUFPM3FCLE1BQU0sQ0FBQ3lmLE1BQU0sQ0FBQyxFQUFFLEVBQUVrTCxJQUFJLEVBQUU7TUFDN0IzTixJQUFJLEVBQUUyTixJQUFJLENBQUMzSSxDQUFDO01BQ1puRixHQUFHLEVBQUU4TixJQUFJLENBQUN6SSxDQUFDO01BQ1huRixLQUFLLEVBQUU0TixJQUFJLENBQUMzSSxDQUFDLEdBQUcySSxJQUFJLENBQUMvSSxLQUFLO01BQzFCOUUsTUFBTSxFQUFFNk4sSUFBSSxDQUFDekksQ0FBQyxHQUFHeUksSUFBSSxDQUFDOUk7SUFDMUIsQ0FBRyxDQUFDO0VBQ0o7RUNRQSxTQUFTK0ksMEJBQTBCQSxDQUFDeHNCLE9BQU8sRUFBRTRoQixRQUFRLEVBQUU7SUFDckQsSUFBSTJLLElBQUksR0FBR2xPLHFCQUFxQixDQUFDcmUsT0FBTyxFQUFFLEtBQUssRUFBRTRoQixRQUFRLEtBQUssT0FBTyxDQUFDO0lBQ3RFMkssSUFBSSxDQUFDOU4sR0FBRyxHQUFHOE4sSUFBSSxDQUFDOU4sR0FBRyxHQUFHemUsT0FBTyxDQUFDeXNCLFNBQVM7SUFDdkNGLElBQUksQ0FBQzNOLElBQUksR0FBRzJOLElBQUksQ0FBQzNOLElBQUksR0FBRzVlLE9BQU8sQ0FBQzBzQixVQUFVO0lBQzFDSCxJQUFJLENBQUM3TixNQUFNLEdBQUc2TixJQUFJLENBQUM5TixHQUFHLEdBQUd6ZSxPQUFPLENBQUNtbkIsWUFBWTtJQUM3Q29GLElBQUksQ0FBQzVOLEtBQUssR0FBRzROLElBQUksQ0FBQzNOLElBQUksR0FBRzVlLE9BQU8sQ0FBQ29uQixXQUFXO0lBQzVDbUYsSUFBSSxDQUFDL0ksS0FBSyxHQUFHeGpCLE9BQU8sQ0FBQ29uQixXQUFXO0lBQ2hDbUYsSUFBSSxDQUFDOUksTUFBTSxHQUFHempCLE9BQU8sQ0FBQ21uQixZQUFZO0lBQ2xDb0YsSUFBSSxDQUFDM0ksQ0FBQyxHQUFHMkksSUFBSSxDQUFDM04sSUFBSTtJQUNsQjJOLElBQUksQ0FBQ3pJLENBQUMsR0FBR3lJLElBQUksQ0FBQzlOLEdBQUc7SUFDakIsT0FBTzhOLElBQUk7RUFDYjtFQUVBLFNBQVNJLDBCQUEwQkEsQ0FBQzNzQixPQUFPLEVBQUU0c0IsY0FBYyxFQUFFaEwsUUFBUSxFQUFFO0lBQ3JFLE9BQU9nTCxjQUFjLEtBQUsxTixRQUFRLEdBQUdvTixnQkFBZ0IsQ0FBQ2pCLGVBQWUsQ0FBQ3JyQixPQUFPLEVBQUU0aEIsUUFBUSxDQUFDLENBQUMsR0FBR2xCLFNBQVMsQ0FBQ2tNLGNBQWMsQ0FBQyxHQUFHSiwwQkFBMEIsQ0FBQ0ksY0FBYyxFQUFFaEwsUUFBUSxDQUFDLEdBQUcwSyxnQkFBZ0IsQ0FBQ2QsZUFBZSxDQUFDbEgsa0JBQWtCLENBQUN0a0IsT0FBTyxDQUFDLENBQUMsQ0FBQztFQUMvTyxDQUFDO0VBQ0Q7RUFDQTs7RUFHQSxTQUFTNnNCLGtCQUFrQkEsQ0FBQzdzQixPQUFPLEVBQUU7SUFDbkMsSUFBSWlmLGVBQWUsR0FBR2tOLGlCQUFpQixDQUFDNUgsYUFBYSxDQUFDdmtCLE9BQU8sQ0FBQyxDQUFDO0lBQy9ELElBQUk4c0IsaUJBQWlCLEdBQUcsQ0FBQyxVQUFVLEVBQUUsT0FBTyxDQUFDLENBQUMva0IsT0FBTyxDQUFDcWMsa0JBQWdCLENBQUNwa0IsT0FBTyxDQUFDLENBQUMwaEIsUUFBUSxDQUFDLElBQUksQ0FBQztJQUM5RixJQUFJcUwsY0FBYyxHQUFHRCxpQkFBaUIsSUFBSWxNLGFBQWEsQ0FBQzVnQixPQUFPLENBQUMsR0FBR3FsQixlQUFlLENBQUNybEIsT0FBTyxDQUFDLEdBQUdBLE9BQU87SUFFckcsSUFBSSxDQUFDMGdCLFNBQVMsQ0FBQ3FNLGNBQWMsQ0FBQyxFQUFFO01BQzlCLE9BQU8sRUFBRTtJQUNiLENBQUc7O0lBR0QsT0FBTzlOLGVBQWUsQ0FBQ3BSLE1BQU0sQ0FBQyxVQUFVK2UsY0FBYyxFQUFFO01BQ3RELE9BQU9sTSxTQUFTLENBQUNrTSxjQUFjLENBQUMsSUFBSXRvQixRQUFRLENBQUNzb0IsY0FBYyxFQUFFRyxjQUFjLENBQUMsSUFBSTNNLFdBQVcsQ0FBQ3dNLGNBQWMsQ0FBQyxLQUFLLE1BQU07SUFDMUgsQ0FBRyxDQUFDO0VBQ0osQ0FBQztFQUNEOztFQUdlLFNBQVNJLGVBQWVBLENBQUNodEIsT0FBTyxFQUFFaXRCLFFBQVEsRUFBRUMsWUFBWSxFQUFFdEwsUUFBUSxFQUFFO0lBQ2pGLElBQUl1TCxtQkFBbUIsR0FBR0YsUUFBUSxLQUFLLGlCQUFpQixHQUFHSixrQkFBa0IsQ0FBQzdzQixPQUFPLENBQUMsR0FBRyxFQUFFLENBQUN5USxNQUFNLENBQUN3YyxRQUFRLENBQUM7SUFDNUcsSUFBSWhPLGVBQWUsR0FBRyxFQUFFLENBQUN4TyxNQUFNLENBQUMwYyxtQkFBbUIsRUFBRSxDQUFDRCxZQUFZLENBQUMsQ0FBQztJQUNwRSxJQUFJRSxtQkFBbUIsR0FBR25PLGVBQWUsQ0FBQyxDQUFDLENBQUM7SUFDNUMsSUFBSW9PLFlBQVksR0FBR3BPLGVBQWUsQ0FBQ0ssTUFBTSxDQUFDLFVBQVVnTyxPQUFPLEVBQUVWLGNBQWMsRUFBRTtNQUMzRSxJQUFJTCxJQUFJLEdBQUdJLDBCQUEwQixDQUFDM3NCLE9BQU8sRUFBRTRzQixjQUFjLEVBQUVoTCxRQUFRLENBQUM7TUFDeEUwTCxPQUFPLENBQUM3TyxHQUFHLEdBQUd6VyxHQUFHLENBQUN1a0IsSUFBSSxDQUFDOU4sR0FBRyxFQUFFNk8sT0FBTyxDQUFDN08sR0FBRyxDQUFDO01BQ3hDNk8sT0FBTyxDQUFDM08sS0FBSyxHQUFHMVcsR0FBRyxDQUFDc2tCLElBQUksQ0FBQzVOLEtBQUssRUFBRTJPLE9BQU8sQ0FBQzNPLEtBQUssQ0FBQztNQUM5QzJPLE9BQU8sQ0FBQzVPLE1BQU0sR0FBR3pXLEdBQUcsQ0FBQ3NrQixJQUFJLENBQUM3TixNQUFNLEVBQUU0TyxPQUFPLENBQUM1TyxNQUFNLENBQUM7TUFDakQ0TyxPQUFPLENBQUMxTyxJQUFJLEdBQUc1VyxHQUFHLENBQUN1a0IsSUFBSSxDQUFDM04sSUFBSSxFQUFFME8sT0FBTyxDQUFDMU8sSUFBSSxDQUFDO01BQzNDLE9BQU8wTyxPQUFPO0lBQ2xCLENBQUcsRUFBRVgsMEJBQTBCLENBQUMzc0IsT0FBTyxFQUFFb3RCLG1CQUFtQixFQUFFeEwsUUFBUSxDQUFDLENBQUM7SUFDdEV5TCxZQUFZLENBQUM3SixLQUFLLEdBQUc2SixZQUFZLENBQUMxTyxLQUFLLEdBQUcwTyxZQUFZLENBQUN6TyxJQUFJO0lBQzNEeU8sWUFBWSxDQUFDNUosTUFBTSxHQUFHNEosWUFBWSxDQUFDM08sTUFBTSxHQUFHMk8sWUFBWSxDQUFDNU8sR0FBRztJQUM1RDRPLFlBQVksQ0FBQ3pKLENBQUMsR0FBR3lKLFlBQVksQ0FBQ3pPLElBQUk7SUFDbEN5TyxZQUFZLENBQUN2SixDQUFDLEdBQUd1SixZQUFZLENBQUM1TyxHQUFHO0lBQ2pDLE9BQU80TyxZQUFZO0VBQ3JCO0VDakVlLFNBQVNFLGNBQWNBLENBQUN2TSxJQUFJLEVBQUU7SUFDM0MsSUFBSTVCLFNBQVMsR0FBRzRCLElBQUksQ0FBQzVCLFNBQVM7TUFDMUJwZixPQUFPLEdBQUdnaEIsSUFBSSxDQUFDaGhCLE9BQU87TUFDdEJ3ZixTQUFTLEdBQUd3QixJQUFJLENBQUN4QixTQUFTO0lBQzlCLElBQUlnSCxhQUFhLEdBQUdoSCxTQUFTLEdBQUc4QyxnQkFBZ0IsQ0FBQzlDLFNBQVMsQ0FBQyxHQUFHLElBQUk7SUFDbEUsSUFBSStJLFNBQVMsR0FBRy9JLFNBQVMsR0FBR3NJLFlBQVksQ0FBQ3RJLFNBQVMsQ0FBQyxHQUFHLElBQUk7SUFDMUQsSUFBSWdPLE9BQU8sR0FBR3BPLFNBQVMsQ0FBQ3dFLENBQUMsR0FBR3hFLFNBQVMsQ0FBQ29FLEtBQUssR0FBRyxDQUFDLEdBQUd4akIsT0FBTyxDQUFDd2pCLEtBQUssR0FBRyxDQUFDO0lBQ25FLElBQUlpSyxPQUFPLEdBQUdyTyxTQUFTLENBQUMwRSxDQUFDLEdBQUcxRSxTQUFTLENBQUNxRSxNQUFNLEdBQUcsQ0FBQyxHQUFHempCLE9BQU8sQ0FBQ3lqQixNQUFNLEdBQUcsQ0FBQztJQUNyRSxJQUFJK0UsT0FBTztJQUVYLFFBQVFoQyxhQUFhO01BQ25CLEtBQUsvSCxHQUFHO1FBQ04rSixPQUFPLEdBQUc7VUFDUjVFLENBQUMsRUFBRTRKLE9BQU87VUFDVjFKLENBQUMsRUFBRTFFLFNBQVMsQ0FBQzBFLENBQUMsR0FBRzlqQixPQUFPLENBQUN5akI7UUFDakMsQ0FBTztRQUNEO01BRUYsS0FBSy9FLE1BQU07UUFDVDhKLE9BQU8sR0FBRztVQUNSNUUsQ0FBQyxFQUFFNEosT0FBTztVQUNWMUosQ0FBQyxFQUFFMUUsU0FBUyxDQUFDMEUsQ0FBQyxHQUFHMUUsU0FBUyxDQUFDcUU7UUFDbkMsQ0FBTztRQUNEO01BRUYsS0FBSzlFLEtBQUs7UUFDUjZKLE9BQU8sR0FBRztVQUNSNUUsQ0FBQyxFQUFFeEUsU0FBUyxDQUFDd0UsQ0FBQyxHQUFHeEUsU0FBUyxDQUFDb0UsS0FBSztVQUNoQ00sQ0FBQyxFQUFFMko7UUFDWCxDQUFPO1FBQ0Q7TUFFRixLQUFLN08sSUFBSTtRQUNQNEosT0FBTyxHQUFHO1VBQ1I1RSxDQUFDLEVBQUV4RSxTQUFTLENBQUN3RSxDQUFDLEdBQUc1akIsT0FBTyxDQUFDd2pCLEtBQUs7VUFDOUJNLENBQUMsRUFBRTJKO1FBQ1gsQ0FBTztRQUNEO01BRUY7UUFDRWpGLE9BQU8sR0FBRztVQUNSNUUsQ0FBQyxFQUFFeEUsU0FBUyxDQUFDd0UsQ0FBQztVQUNkRSxDQUFDLEVBQUUxRSxTQUFTLENBQUMwRTtRQUNyQixDQUFPO0lBQ1A7SUFFRSxJQUFJNEosUUFBUSxHQUFHbEgsYUFBYSxHQUFHbEIsd0JBQXdCLENBQUNrQixhQUFhLENBQUMsR0FBRyxJQUFJO0lBRTdFLElBQUlrSCxRQUFRLElBQUksSUFBSSxFQUFFO01BQ3BCLElBQUkvRyxHQUFHLEdBQUcrRyxRQUFRLEtBQUssR0FBRyxHQUFHLFFBQVEsR0FBRyxPQUFPO01BRS9DLFFBQVFuRixTQUFTO1FBQ2YsS0FBS3hKLEtBQUs7VUFDUnlKLE9BQU8sQ0FBQ2tGLFFBQVEsQ0FBQyxHQUFHbEYsT0FBTyxDQUFDa0YsUUFBUSxDQUFDLElBQUl0TyxTQUFTLENBQUN1SCxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUczbUIsT0FBTyxDQUFDMm1CLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQztVQUMvRTtRQUVGLEtBQUszSCxHQUFHO1VBQ053SixPQUFPLENBQUNrRixRQUFRLENBQUMsR0FBR2xGLE9BQU8sQ0FBQ2tGLFFBQVEsQ0FBQyxJQUFJdE8sU0FBUyxDQUFDdUgsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHM21CLE9BQU8sQ0FBQzJtQixHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7VUFDL0U7TUFHUjtJQUNBO0lBRUUsT0FBTzZCLE9BQU87RUFDaEI7RUMzRGUsU0FBU21GLGNBQWNBLENBQUMxTSxLQUFLLEVBQUVVLE9BQU8sRUFBRTtJQUNyRCxJQUFJQSxPQUFPLEtBQUssS0FBSyxDQUFDLEVBQUU7TUFDdEJBLE9BQU8sR0FBRyxFQUFFO0lBQ2hCO0lBRUUsSUFBSWlNLFFBQVEsR0FBR2pNLE9BQU87TUFDbEJrTSxrQkFBa0IsR0FBR0QsUUFBUSxDQUFDcE8sU0FBUztNQUN2Q0EsU0FBUyxHQUFHcU8sa0JBQWtCLEtBQUssS0FBSyxDQUFDLEdBQUc1TSxLQUFLLENBQUN6QixTQUFTLEdBQUdxTyxrQkFBa0I7TUFDaEZDLGlCQUFpQixHQUFHRixRQUFRLENBQUNoTSxRQUFRO01BQ3JDQSxRQUFRLEdBQUdrTSxpQkFBaUIsS0FBSyxLQUFLLENBQUMsR0FBRzdNLEtBQUssQ0FBQ1csUUFBUSxHQUFHa00saUJBQWlCO01BQzVFQyxpQkFBaUIsR0FBR0gsUUFBUSxDQUFDWCxRQUFRO01BQ3JDQSxRQUFRLEdBQUdjLGlCQUFpQixLQUFLLEtBQUssQ0FBQyxHQUFHOU8sZUFBZSxHQUFHOE8saUJBQWlCO01BQzdFQyxxQkFBcUIsR0FBR0osUUFBUSxDQUFDVixZQUFZO01BQzdDQSxZQUFZLEdBQUdjLHFCQUFxQixLQUFLLEtBQUssQ0FBQyxHQUFHOU8sUUFBUSxHQUFHOE8scUJBQXFCO01BQ2xGQyxxQkFBcUIsR0FBR0wsUUFBUSxDQUFDTSxjQUFjO01BQy9DQSxjQUFjLEdBQUdELHFCQUFxQixLQUFLLEtBQUssQ0FBQyxHQUFHOU8sTUFBTSxHQUFHOE8scUJBQXFCO01BQ2xGRSxvQkFBb0IsR0FBR1AsUUFBUSxDQUFDUSxXQUFXO01BQzNDQSxXQUFXLEdBQUdELG9CQUFvQixLQUFLLEtBQUssQ0FBQyxHQUFHLEtBQUssR0FBR0Esb0JBQW9CO01BQzVFRSxnQkFBZ0IsR0FBR1QsUUFBUSxDQUFDMUgsT0FBTztNQUNuQ0EsT0FBTyxHQUFHbUksZ0JBQWdCLEtBQUssS0FBSyxDQUFDLEdBQUcsQ0FBQyxHQUFHQSxnQkFBZ0I7SUFDaEUsSUFBSXZJLGFBQWEsR0FBR0Qsa0JBQWtCLENBQUMsT0FBT0ssT0FBTyxLQUFLLFFBQVEsR0FBR0EsT0FBTyxHQUFHSCxlQUFlLENBQUNHLE9BQU8sRUFBRXBILGNBQWMsQ0FBQyxDQUFDO0lBQ3hILElBQUl3UCxVQUFVLEdBQUdKLGNBQWMsS0FBSy9PLE1BQU0sR0FBR0MsU0FBUyxHQUFHRCxNQUFNO0lBQy9ELElBQUltSixVQUFVLEdBQUdySCxLQUFLLENBQUNrRixLQUFLLENBQUNoSCxNQUFNO0lBQ25DLElBQUluZixPQUFPLEdBQUdpaEIsS0FBSyxDQUFDQyxRQUFRLENBQUNrTixXQUFXLEdBQUdFLFVBQVUsR0FBR0osY0FBYyxDQUFDO0lBQ3ZFLElBQUlLLGtCQUFrQixHQUFHdkIsZUFBZSxDQUFDdE0sU0FBUyxDQUFDMWdCLE9BQU8sQ0FBQyxHQUFHQSxPQUFPLEdBQUdBLE9BQU8sQ0FBQ3d1QixjQUFjLElBQUlsSyxrQkFBa0IsQ0FBQ3JELEtBQUssQ0FBQ0MsUUFBUSxDQUFDL0IsTUFBTSxDQUFDLEVBQUU4TixRQUFRLEVBQUVDLFlBQVksRUFBRXRMLFFBQVEsQ0FBQztJQUM5SyxJQUFJNk0sbUJBQW1CLEdBQUdwUSxxQkFBcUIsQ0FBQzRDLEtBQUssQ0FBQ0MsUUFBUSxDQUFDOUIsU0FBUyxDQUFDO0lBQ3pFLElBQUlrSCxhQUFhLEdBQUdpSCxjQUFjLENBQUM7TUFDakNuTyxTQUFTLEVBQUVxUCxtQkFBbUI7TUFDOUJ6dUIsT0FBTyxFQUFFc29CLFVBQVU7TUFDbkIxRyxRQUFRLEVBQUUsVUFBVTtNQUNwQnBDLFNBQVMsRUFBRUE7SUFDZixDQUFHLENBQUM7SUFDRixJQUFJa1AsZ0JBQWdCLEdBQUdwQyxnQkFBZ0IsQ0FBQzFxQixNQUFNLENBQUN5ZixNQUFNLENBQUMsRUFBRSxFQUFFaUgsVUFBVSxFQUFFaEMsYUFBYSxDQUFDLENBQUM7SUFDckYsSUFBSXFJLGlCQUFpQixHQUFHVCxjQUFjLEtBQUsvTyxNQUFNLEdBQUd1UCxnQkFBZ0IsR0FBR0QsbUJBQW1CLENBQUM7SUFDN0Y7O0lBRUUsSUFBSUcsZUFBZSxHQUFHO01BQ3BCblEsR0FBRyxFQUFFOFAsa0JBQWtCLENBQUM5UCxHQUFHLEdBQUdrUSxpQkFBaUIsQ0FBQ2xRLEdBQUcsR0FBR3FILGFBQWEsQ0FBQ3JILEdBQUc7TUFDdkVDLE1BQU0sRUFBRWlRLGlCQUFpQixDQUFDalEsTUFBTSxHQUFHNlAsa0JBQWtCLENBQUM3UCxNQUFNLEdBQUdvSCxhQUFhLENBQUNwSCxNQUFNO01BQ25GRSxJQUFJLEVBQUUyUCxrQkFBa0IsQ0FBQzNQLElBQUksR0FBRytQLGlCQUFpQixDQUFDL1AsSUFBSSxHQUFHa0gsYUFBYSxDQUFDbEgsSUFBSTtNQUMzRUQsS0FBSyxFQUFFZ1EsaUJBQWlCLENBQUNoUSxLQUFLLEdBQUc0UCxrQkFBa0IsQ0FBQzVQLEtBQUssR0FBR21ILGFBQWEsQ0FBQ25IO0lBQzlFLENBQUc7SUFDRCxJQUFJa1EsVUFBVSxHQUFHNU4sS0FBSyxDQUFDc0YsYUFBYSxDQUFDZ0IsTUFBTSxDQUFDOztJQUU1QyxJQUFJMkcsY0FBYyxLQUFLL08sTUFBTSxJQUFJMFAsVUFBVSxFQUFFO01BQzNDLElBQUl0SCxNQUFNLEdBQUdzSCxVQUFVLENBQUNyUCxTQUFTLENBQUM7TUFDbEM1ZCxNQUFNLENBQUNqQixJQUFJLENBQUNpdUIsZUFBZSxDQUFDLENBQUN6TixPQUFPLENBQUMsVUFBVWxoQixHQUFHLEVBQUU7UUFDbEQsSUFBSTZ1QixRQUFRLEdBQUcsQ0FBQ25RLEtBQUssRUFBRUQsTUFBTSxDQUFDLENBQUMzVyxPQUFPLENBQUM5SCxHQUFHLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUN6RCxJQUFJd21CLElBQUksR0FBRyxDQUFDaEksR0FBRyxFQUFFQyxNQUFNLENBQUMsQ0FBQzNXLE9BQU8sQ0FBQzlILEdBQUcsQ0FBQyxJQUFJLENBQUMsR0FBRyxHQUFHLEdBQUcsR0FBRztRQUN0RDJ1QixlQUFlLENBQUMzdUIsR0FBRyxDQUFDLElBQUlzbkIsTUFBTSxDQUFDZCxJQUFJLENBQUMsR0FBR3FJLFFBQVE7TUFDckQsQ0FBSyxDQUFDO0lBQ047SUFFRSxPQUFPRixlQUFlO0VBQ3hCO0VDNURlLFNBQVNHLG9CQUFvQkEsQ0FBQzlOLEtBQUssRUFBRVUsT0FBTyxFQUFFO0lBQzNELElBQUlBLE9BQU8sS0FBSyxLQUFLLENBQUMsRUFBRTtNQUN0QkEsT0FBTyxHQUFHLEVBQUU7SUFDaEI7SUFFRSxJQUFJaU0sUUFBUSxHQUFHak0sT0FBTztNQUNsQm5DLFNBQVMsR0FBR29PLFFBQVEsQ0FBQ3BPLFNBQVM7TUFDOUJ5TixRQUFRLEdBQUdXLFFBQVEsQ0FBQ1gsUUFBUTtNQUM1QkMsWUFBWSxHQUFHVSxRQUFRLENBQUNWLFlBQVk7TUFDcENoSCxPQUFPLEdBQUcwSCxRQUFRLENBQUMxSCxPQUFPO01BQzFCOEksY0FBYyxHQUFHcEIsUUFBUSxDQUFDb0IsY0FBYztNQUN4Q0MscUJBQXFCLEdBQUdyQixRQUFRLENBQUNzQixxQkFBcUI7TUFDdERBLHFCQUFxQixHQUFHRCxxQkFBcUIsS0FBSyxLQUFLLENBQUMsR0FBR3hQLFVBQWEsR0FBR3dQLHFCQUFxQjtJQUNwRyxJQUFJMUcsU0FBUyxHQUFHVCxZQUFZLENBQUN0SSxTQUFTLENBQUM7SUFDdkMsSUFBSTJQLFlBQVUsR0FBRzVHLFNBQVMsR0FBR3lHLGNBQWMsR0FBRzNQLG1CQUFtQixHQUFHQSxtQkFBbUIsQ0FBQ3hSLE1BQU0sQ0FBQyxVQUFVMlIsU0FBUyxFQUFFO01BQ2xILE9BQU9zSSxZQUFZLENBQUN0SSxTQUFTLENBQUMsS0FBSytJLFNBQVM7SUFDaEQsQ0FBRyxDQUFDLEdBQUd6SixjQUFjO0lBQ25CLElBQUlzUSxpQkFBaUIsR0FBR0QsWUFBVSxDQUFDdGhCLE1BQU0sQ0FBQyxVQUFVMlIsU0FBUyxFQUFFO01BQzdELE9BQU8wUCxxQkFBcUIsQ0FBQ25uQixPQUFPLENBQUN5WCxTQUFTLENBQUMsSUFBSSxDQUFDO0lBQ3hELENBQUcsQ0FBQztJQUVGLElBQUk0UCxpQkFBaUIsQ0FBQzVyQixNQUFNLEtBQUssQ0FBQyxFQUFFO01BQ2xDNHJCLGlCQUFpQixHQUFHRCxZQUFVO0lBQ2xDLENBQUc7O0lBR0QsSUFBSUUsU0FBUyxHQUFHRCxpQkFBaUIsQ0FBQzlQLE1BQU0sQ0FBQyxVQUFVQyxHQUFHLEVBQUVDLFNBQVMsRUFBRTtNQUNqRUQsR0FBRyxDQUFDQyxTQUFTLENBQUMsR0FBR21PLGNBQWMsQ0FBQzFNLEtBQUssRUFBRTtRQUNyQ3pCLFNBQVMsRUFBRUEsU0FBUztRQUNwQnlOLFFBQVEsRUFBRUEsUUFBUTtRQUNsQkMsWUFBWSxFQUFFQSxZQUFZO1FBQzFCaEgsT0FBTyxFQUFFQTtNQUNmLENBQUssQ0FBQyxDQUFDNUQsZ0JBQWdCLENBQUM5QyxTQUFTLENBQUMsQ0FBQztNQUMvQixPQUFPRCxHQUFHO0lBQ2QsQ0FBRyxFQUFFLEVBQUUsQ0FBQztJQUNOLE9BQU8zZCxNQUFNLENBQUNqQixJQUFJLENBQUMwdUIsU0FBUyxDQUFDLENBQUNDLElBQUksQ0FBQyxVQUFVQyxDQUFDLEVBQUVDLENBQUMsRUFBRTtNQUNqRCxPQUFPSCxTQUFTLENBQUNFLENBQUMsQ0FBQyxHQUFHRixTQUFTLENBQUNHLENBQUMsQ0FBQztJQUN0QyxDQUFHLENBQUM7RUFDSjtFQ2xDQSxTQUFTQyw2QkFBNkJBLENBQUNqUSxTQUFTLEVBQUU7SUFDaEQsSUFBSThDLGdCQUFnQixDQUFDOUMsU0FBUyxDQUFDLEtBQUtYLElBQUksRUFBRTtNQUN4QyxPQUFPLEVBQUU7SUFDYjtJQUVFLElBQUk2USxpQkFBaUIsR0FBRy9FLG9CQUFvQixDQUFDbkwsU0FBUyxDQUFDO0lBQ3ZELE9BQU8sQ0FBQ3NMLDZCQUE2QixDQUFDdEwsU0FBUyxDQUFDLEVBQUVrUSxpQkFBaUIsRUFBRTVFLDZCQUE2QixDQUFDNEUsaUJBQWlCLENBQUMsQ0FBQztFQUN4SDtFQUVBLFNBQVNDLElBQUlBLENBQUMzTyxJQUFJLEVBQUU7SUFDbEIsSUFBSUMsS0FBSyxHQUFHRCxJQUFJLENBQUNDLEtBQUs7TUFDbEJVLE9BQU8sR0FBR1gsSUFBSSxDQUFDVyxPQUFPO01BQ3RCMWIsSUFBSSxHQUFHK2EsSUFBSSxDQUFDL2EsSUFBSTtJQUVwQixJQUFJZ2IsS0FBSyxDQUFDc0YsYUFBYSxDQUFDdGdCLElBQUksQ0FBQyxDQUFDMnBCLEtBQUssRUFBRTtNQUNuQztJQUNKO0lBRUUsSUFBSUMsaUJBQWlCLEdBQUdsTyxPQUFPLENBQUMrTCxRQUFRO01BQ3BDb0MsYUFBYSxHQUFHRCxpQkFBaUIsS0FBSyxLQUFLLENBQUMsR0FBRyxJQUFJLEdBQUdBLGlCQUFpQjtNQUN2RUUsZ0JBQWdCLEdBQUdwTyxPQUFPLENBQUNxTyxPQUFPO01BQ2xDQyxZQUFZLEdBQUdGLGdCQUFnQixLQUFLLEtBQUssQ0FBQyxHQUFHLElBQUksR0FBR0EsZ0JBQWdCO01BQ3BFRywyQkFBMkIsR0FBR3ZPLE9BQU8sQ0FBQ3dPLGtCQUFrQjtNQUN4RGpLLE9BQU8sR0FBR3ZFLE9BQU8sQ0FBQ3VFLE9BQU87TUFDekIrRyxRQUFRLEdBQUd0TCxPQUFPLENBQUNzTCxRQUFRO01BQzNCQyxZQUFZLEdBQUd2TCxPQUFPLENBQUN1TCxZQUFZO01BQ25Da0IsV0FBVyxHQUFHek0sT0FBTyxDQUFDeU0sV0FBVztNQUNqQ2dDLHFCQUFxQixHQUFHek8sT0FBTyxDQUFDcU4sY0FBYztNQUM5Q0EsY0FBYyxHQUFHb0IscUJBQXFCLEtBQUssS0FBSyxDQUFDLEdBQUcsSUFBSSxHQUFHQSxxQkFBcUI7TUFDaEZsQixxQkFBcUIsR0FBR3ZOLE9BQU8sQ0FBQ3VOLHFCQUFxQjtJQUN6RCxJQUFJbUIsa0JBQWtCLEdBQUdwUCxLQUFLLENBQUNVLE9BQU8sQ0FBQ25DLFNBQVM7SUFDaEQsSUFBSWdILGFBQWEsR0FBR2xFLGdCQUFnQixDQUFDK04sa0JBQWtCLENBQUM7SUFDeEQsSUFBSUMsZUFBZSxHQUFHOUosYUFBYSxLQUFLNkosa0JBQWtCO0lBQzFELElBQUlGLGtCQUFrQixHQUFHRCwyQkFBMkIsS0FBS0ksZUFBZSxJQUFJLENBQUN0QixjQUFjLEdBQUcsQ0FBQ3JFLG9CQUFvQixDQUFDMEYsa0JBQWtCLENBQUMsQ0FBQyxHQUFHWiw2QkFBNkIsQ0FBQ1ksa0JBQWtCLENBQUMsQ0FBQztJQUM3TCxJQUFJNVEsVUFBVSxHQUFHLENBQUM0USxrQkFBa0IsQ0FBQyxDQUFDNWYsTUFBTSxDQUFDMGYsa0JBQWtCLENBQUMsQ0FBQzdRLE1BQU0sQ0FBQyxVQUFVQyxHQUFHLEVBQUVDLFNBQVMsRUFBRTtNQUNoRyxPQUFPRCxHQUFHLENBQUM5TyxNQUFNLENBQUM2UixnQkFBZ0IsQ0FBQzlDLFNBQVMsQ0FBQyxLQUFLWCxJQUFJLEdBQUdrUSxvQkFBb0IsQ0FBQzlOLEtBQUssRUFBRTtRQUNuRnpCLFNBQVMsRUFBRUEsU0FBUztRQUNwQnlOLFFBQVEsRUFBRUEsUUFBUTtRQUNsQkMsWUFBWSxFQUFFQSxZQUFZO1FBQzFCaEgsT0FBTyxFQUFFQSxPQUFPO1FBQ2hCOEksY0FBYyxFQUFFQSxjQUFjO1FBQzlCRSxxQkFBcUIsRUFBRUE7TUFDN0IsQ0FBSyxDQUFDLEdBQUcxUCxTQUFTLENBQUM7SUFDbkIsQ0FBRyxFQUFFLEVBQUUsQ0FBQztJQUNOLElBQUkrUSxhQUFhLEdBQUd0UCxLQUFLLENBQUNrRixLQUFLLENBQUMvRyxTQUFTO0lBQ3pDLElBQUlrSixVQUFVLEdBQUdySCxLQUFLLENBQUNrRixLQUFLLENBQUNoSCxNQUFNO0lBQ25DLElBQUlxUixTQUFTLEdBQUcsSUFBSTN3QixHQUFHLEVBQUU7SUFDekIsSUFBSTR3QixrQkFBa0IsR0FBRyxJQUFJO0lBQzdCLElBQUlDLHFCQUFxQixHQUFHalIsVUFBVSxDQUFDLENBQUMsQ0FBQztJQUV6QyxLQUFLLElBQUlrUixDQUFDLEdBQUcsQ0FBQyxFQUFFQSxDQUFDLEdBQUdsUixVQUFVLENBQUNqYyxNQUFNLEVBQUVtdEIsQ0FBQyxFQUFFLEVBQUU7TUFDMUMsSUFBSW5SLFNBQVMsR0FBR0MsVUFBVSxDQUFDa1IsQ0FBQyxDQUFDO01BRTdCLElBQUlDLGNBQWMsR0FBR3RPLGdCQUFnQixDQUFDOUMsU0FBUyxDQUFDO01BRWhELElBQUlxUixnQkFBZ0IsR0FBRy9JLFlBQVksQ0FBQ3RJLFNBQVMsQ0FBQyxLQUFLVCxLQUFLO01BQ3hELElBQUkySCxVQUFVLEdBQUcsQ0FBQ2pJLEdBQUcsRUFBRUMsTUFBTSxDQUFDLENBQUMzVyxPQUFPLENBQUM2b0IsY0FBYyxDQUFDLElBQUksQ0FBQztNQUMzRCxJQUFJakssR0FBRyxHQUFHRCxVQUFVLEdBQUcsT0FBTyxHQUFHLFFBQVE7TUFDekMsSUFBSXFGLFFBQVEsR0FBRzRCLGNBQWMsQ0FBQzFNLEtBQUssRUFBRTtRQUNuQ3pCLFNBQVMsRUFBRUEsU0FBUztRQUNwQnlOLFFBQVEsRUFBRUEsUUFBUTtRQUNsQkMsWUFBWSxFQUFFQSxZQUFZO1FBQzFCa0IsV0FBVyxFQUFFQSxXQUFXO1FBQ3hCbEksT0FBTyxFQUFFQTtNQUNmLENBQUssQ0FBQztNQUNGLElBQUk0SyxpQkFBaUIsR0FBR3BLLFVBQVUsR0FBR21LLGdCQUFnQixHQUFHbFMsS0FBSyxHQUFHQyxJQUFJLEdBQUdpUyxnQkFBZ0IsR0FBR25TLE1BQU0sR0FBR0QsR0FBRztNQUV0RyxJQUFJOFIsYUFBYSxDQUFDNUosR0FBRyxDQUFDLEdBQUcyQixVQUFVLENBQUMzQixHQUFHLENBQUMsRUFBRTtRQUN4Q21LLGlCQUFpQixHQUFHbkcsb0JBQW9CLENBQUNtRyxpQkFBaUIsQ0FBQztNQUNqRTtNQUVJLElBQUlDLGdCQUFnQixHQUFHcEcsb0JBQW9CLENBQUNtRyxpQkFBaUIsQ0FBQztNQUM5RCxJQUFJRSxNQUFNLEdBQUcsRUFBRTtNQUVmLElBQUlsQixhQUFhLEVBQUU7UUFDakJrQixNQUFNLENBQUNyckIsSUFBSSxDQUFDb21CLFFBQVEsQ0FBQzZFLGNBQWMsQ0FBQyxJQUFJLENBQUMsQ0FBQztNQUNoRDtNQUVJLElBQUlYLFlBQVksRUFBRTtRQUNoQmUsTUFBTSxDQUFDcnJCLElBQUksQ0FBQ29tQixRQUFRLENBQUMrRSxpQkFBaUIsQ0FBQyxJQUFJLENBQUMsRUFBRS9FLFFBQVEsQ0FBQ2dGLGdCQUFnQixDQUFDLElBQUksQ0FBQyxDQUFDO01BQ3BGO01BRUksSUFBSUMsTUFBTSxDQUFDQyxLQUFLLENBQUMsVUFBVUMsS0FBSyxFQUFFO1FBQ2hDLE9BQU9BLEtBQUs7TUFDbEIsQ0FBSyxDQUFDLEVBQUU7UUFDRlIscUJBQXFCLEdBQUdsUixTQUFTO1FBQ2pDaVIsa0JBQWtCLEdBQUcsS0FBSztRQUMxQjtNQUNOO01BRUlELFNBQVMsQ0FBQ3p3QixHQUFHLENBQUN5ZixTQUFTLEVBQUV3UixNQUFNLENBQUM7SUFDcEM7SUFFRSxJQUFJUCxrQkFBa0IsRUFBRTtNQUMxQjtNQUNJLElBQUlVLGNBQWMsR0FBR25DLGNBQWMsR0FBRyxDQUFDLEdBQUcsQ0FBQztNQUUzQyxJQUFJb0MsS0FBSyxHQUFHLFNBQVNBLEtBQUtBLENBQUNDLEVBQUUsRUFBRTtRQUM3QixJQUFJQyxnQkFBZ0IsR0FBRzdSLFVBQVUsQ0FBQ3hWLElBQUksQ0FBQyxVQUFVdVYsU0FBUyxFQUFFO1VBQzFELElBQUl3UixNQUFNLEdBQUdSLFNBQVMsQ0FBQ253QixHQUFHLENBQUNtZixTQUFTLENBQUM7VUFFckMsSUFBSXdSLE1BQU0sRUFBRTtZQUNWLE9BQU9BLE1BQU0sQ0FBQ3JsQixLQUFLLENBQUMsQ0FBQyxFQUFFMGxCLEVBQUUsQ0FBQyxDQUFDSixLQUFLLENBQUMsVUFBVUMsS0FBSyxFQUFFO2NBQ2hELE9BQU9BLEtBQUs7WUFDeEIsQ0FBVyxDQUFDO1VBQ1o7UUFDQSxDQUFPLENBQUM7UUFFRixJQUFJSSxnQkFBZ0IsRUFBRTtVQUNwQloscUJBQXFCLEdBQUdZLGdCQUFnQjtVQUN4QyxPQUFPLE9BQU87UUFDdEI7TUFDQSxDQUFLO01BRUQsS0FBSyxJQUFJRCxFQUFFLEdBQUdGLGNBQWMsRUFBRUUsRUFBRSxHQUFHLENBQUMsRUFBRUEsRUFBRSxFQUFFLEVBQUU7UUFDMUMsSUFBSUUsSUFBSSxHQUFHSCxLQUFLLENBQUNDLEVBQUUsQ0FBQztRQUVwQixJQUFJRSxJQUFJLEtBQUssT0FBTyxFQUFFO01BQzVCO0lBQ0E7SUFFRSxJQUFJdFEsS0FBSyxDQUFDekIsU0FBUyxLQUFLa1IscUJBQXFCLEVBQUU7TUFDN0N6UCxLQUFLLENBQUNzRixhQUFhLENBQUN0Z0IsSUFBSSxDQUFDLENBQUMycEIsS0FBSyxHQUFHLElBQUk7TUFDdEMzTyxLQUFLLENBQUN6QixTQUFTLEdBQUdrUixxQkFBcUI7TUFDdkN6UCxLQUFLLENBQUN1USxLQUFLLEdBQUcsSUFBSTtJQUN0QjtFQUNBLENBQUM7O0VBR0QsTUFBQUMsTUFBQSxHQUFlO0lBQ2J4ckIsSUFBSSxFQUFFLE1BQU07SUFDWmtjLE9BQU8sRUFBRSxJQUFJO0lBQ2JDLEtBQUssRUFBRSxNQUFNO0lBQ2JoYyxFQUFFLEVBQUV1cEIsSUFBSTtJQUNSOUgsZ0JBQWdCLEVBQUUsQ0FBQyxRQUFRLENBQUM7SUFDNUJoVixJQUFJLEVBQUU7TUFDSitjLEtBQUssRUFBRTtJQUNYO0VBQ0EsQ0FBQztFQy9JRCxTQUFTOEIsY0FBY0EsQ0FBQzNGLFFBQVEsRUFBRVEsSUFBSSxFQUFFb0YsZ0JBQWdCLEVBQUU7SUFDeEQsSUFBSUEsZ0JBQWdCLEtBQUssS0FBSyxDQUFDLEVBQUU7TUFDL0JBLGdCQUFnQixHQUFHO1FBQ2pCL04sQ0FBQyxFQUFFLENBQUM7UUFDSkUsQ0FBQyxFQUFFO01BQ1QsQ0FBSztJQUNMO0lBRUUsT0FBTztNQUNMckYsR0FBRyxFQUFFc04sUUFBUSxDQUFDdE4sR0FBRyxHQUFHOE4sSUFBSSxDQUFDOUksTUFBTSxHQUFHa08sZ0JBQWdCLENBQUM3TixDQUFDO01BQ3BEbkYsS0FBSyxFQUFFb04sUUFBUSxDQUFDcE4sS0FBSyxHQUFHNE4sSUFBSSxDQUFDL0ksS0FBSyxHQUFHbU8sZ0JBQWdCLENBQUMvTixDQUFDO01BQ3ZEbEYsTUFBTSxFQUFFcU4sUUFBUSxDQUFDck4sTUFBTSxHQUFHNk4sSUFBSSxDQUFDOUksTUFBTSxHQUFHa08sZ0JBQWdCLENBQUM3TixDQUFDO01BQzFEbEYsSUFBSSxFQUFFbU4sUUFBUSxDQUFDbk4sSUFBSSxHQUFHMk4sSUFBSSxDQUFDL0ksS0FBSyxHQUFHbU8sZ0JBQWdCLENBQUMvTjtJQUN4RCxDQUFHO0VBQ0g7RUFFQSxTQUFTZ08scUJBQXFCQSxDQUFDN0YsUUFBUSxFQUFFO0lBQ3ZDLE9BQU8sQ0FBQ3ROLEdBQUcsRUFBRUUsS0FBSyxFQUFFRCxNQUFNLEVBQUVFLElBQUksQ0FBQyxDQUFDaVQsSUFBSSxDQUFDLFVBQVVDLElBQUksRUFBRTtNQUNyRCxPQUFPL0YsUUFBUSxDQUFDK0YsSUFBSSxDQUFDLElBQUksQ0FBQztJQUM5QixDQUFHLENBQUM7RUFDSjtFQUVBLFNBQVNyVSxJQUFJQSxDQUFDdUQsSUFBSSxFQUFFO0lBQ2xCLElBQUlDLEtBQUssR0FBR0QsSUFBSSxDQUFDQyxLQUFLO01BQ2xCaGIsSUFBSSxHQUFHK2EsSUFBSSxDQUFDL2EsSUFBSTtJQUNwQixJQUFJc3FCLGFBQWEsR0FBR3RQLEtBQUssQ0FBQ2tGLEtBQUssQ0FBQy9HLFNBQVM7SUFDekMsSUFBSWtKLFVBQVUsR0FBR3JILEtBQUssQ0FBQ2tGLEtBQUssQ0FBQ2hILE1BQU07SUFDbkMsSUFBSXdTLGdCQUFnQixHQUFHMVEsS0FBSyxDQUFDc0YsYUFBYSxDQUFDd0wsZUFBZTtJQUMxRCxJQUFJQyxpQkFBaUIsR0FBR3JFLGNBQWMsQ0FBQzFNLEtBQUssRUFBRTtNQUM1Q2lOLGNBQWMsRUFBRTtJQUNwQixDQUFHLENBQUM7SUFDRixJQUFJK0QsaUJBQWlCLEdBQUd0RSxjQUFjLENBQUMxTSxLQUFLLEVBQUU7TUFDNUNtTixXQUFXLEVBQUU7SUFDakIsQ0FBRyxDQUFDO0lBQ0YsSUFBSThELHdCQUF3QixHQUFHUixjQUFjLENBQUNNLGlCQUFpQixFQUFFekIsYUFBYSxDQUFDO0lBQy9FLElBQUk0QixtQkFBbUIsR0FBR1QsY0FBYyxDQUFDTyxpQkFBaUIsRUFBRTNKLFVBQVUsRUFBRXFKLGdCQUFnQixDQUFDO0lBQ3pGLElBQUlTLGlCQUFpQixHQUFHUixxQkFBcUIsQ0FBQ00sd0JBQXdCLENBQUM7SUFDdkUsSUFBSUcsZ0JBQWdCLEdBQUdULHFCQUFxQixDQUFDTyxtQkFBbUIsQ0FBQztJQUNqRWxSLEtBQUssQ0FBQ3NGLGFBQWEsQ0FBQ3RnQixJQUFJLENBQUMsR0FBRztNQUMxQmlzQix3QkFBd0IsRUFBRUEsd0JBQXdCO01BQ2xEQyxtQkFBbUIsRUFBRUEsbUJBQW1CO01BQ3hDQyxpQkFBaUIsRUFBRUEsaUJBQWlCO01BQ3BDQyxnQkFBZ0IsRUFBRUE7SUFDdEIsQ0FBRztJQUNEcFIsS0FBSyxDQUFDdlQsVUFBVSxDQUFDeVIsTUFBTSxHQUFHdmQsTUFBTSxDQUFDeWYsTUFBTSxDQUFDLEVBQUUsRUFBRUosS0FBSyxDQUFDdlQsVUFBVSxDQUFDeVIsTUFBTSxFQUFFO01BQ25FLDhCQUE4QixFQUFFaVQsaUJBQWlCO01BQ2pELHFCQUFxQixFQUFFQztJQUMzQixDQUFHLENBQUM7RUFDSixDQUFDOztFQUdELE1BQUFDLE1BQUEsR0FBZTtJQUNicnNCLElBQUksRUFBRSxNQUFNO0lBQ1prYyxPQUFPLEVBQUUsSUFBSTtJQUNiQyxLQUFLLEVBQUUsTUFBTTtJQUNieUYsZ0JBQWdCLEVBQUUsQ0FBQyxpQkFBaUIsQ0FBQztJQUNyQ3poQixFQUFFLEVBQUVxWDtFQUNOLENBQUM7RUN6RE0sU0FBUzhVLHVCQUF1QkEsQ0FBQy9TLFNBQVMsRUFBRTJHLEtBQUssRUFBRW9CLE1BQU0sRUFBRTtJQUNoRSxJQUFJZixhQUFhLEdBQUdsRSxnQkFBZ0IsQ0FBQzlDLFNBQVMsQ0FBQztJQUMvQyxJQUFJZ1QsY0FBYyxHQUFHLENBQUM1VCxJQUFJLEVBQUVILEdBQUcsQ0FBQyxDQUFDMVcsT0FBTyxDQUFDeWUsYUFBYSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUM7SUFFckUsSUFBSXhGLElBQUksR0FBRyxPQUFPdUcsTUFBTSxLQUFLLFVBQVUsR0FBR0EsTUFBTSxDQUFDM2xCLE1BQU0sQ0FBQ3lmLE1BQU0sQ0FBQyxFQUFFLEVBQUU4RSxLQUFLLEVBQUU7UUFDeEUzRyxTQUFTLEVBQUVBO01BQ2YsQ0FBRyxDQUFDLENBQUMsR0FBRytILE1BQU07TUFDUmtMLFFBQVEsR0FBR3pSLElBQUksQ0FBQyxDQUFDLENBQUM7TUFDbEIwUixRQUFRLEdBQUcxUixJQUFJLENBQUMsQ0FBQyxDQUFDO0lBRXRCeVIsUUFBUSxHQUFHQSxRQUFRLElBQUksQ0FBQztJQUN4QkMsUUFBUSxHQUFHLENBQUNBLFFBQVEsSUFBSSxDQUFDLElBQUlGLGNBQWM7SUFDM0MsT0FBTyxDQUFDNVQsSUFBSSxFQUFFRCxLQUFLLENBQUMsQ0FBQzVXLE9BQU8sQ0FBQ3llLGFBQWEsQ0FBQyxJQUFJLENBQUMsR0FBRztNQUNqRDVDLENBQUMsRUFBRThPLFFBQVE7TUFDWDVPLENBQUMsRUFBRTJPO0lBQ1AsQ0FBRyxHQUFHO01BQ0Y3TyxDQUFDLEVBQUU2TyxRQUFRO01BQ1gzTyxDQUFDLEVBQUU0TztJQUNQLENBQUc7RUFDSDtFQUVBLFNBQVNuTCxNQUFNQSxDQUFDL0YsS0FBSyxFQUFFO0lBQ3JCLElBQUlQLEtBQUssR0FBR08sS0FBSyxDQUFDUCxLQUFLO01BQ25CVSxPQUFPLEdBQUdILEtBQUssQ0FBQ0csT0FBTztNQUN2QjFiLElBQUksR0FBR3ViLEtBQUssQ0FBQ3ZiLElBQUk7SUFDckIsSUFBSTBzQixlQUFlLEdBQUdoUixPQUFPLENBQUM0RixNQUFNO01BQ2hDQSxNQUFNLEdBQUdvTCxlQUFlLEtBQUssS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEdBQUdBLGVBQWU7SUFDbEUsSUFBSTlmLElBQUksR0FBRzRNLFVBQVUsQ0FBQ0gsTUFBTSxDQUFDLFVBQVVDLEdBQUcsRUFBRUMsU0FBUyxFQUFFO01BQ3JERCxHQUFHLENBQUNDLFNBQVMsQ0FBQyxHQUFHK1MsdUJBQXVCLENBQUMvUyxTQUFTLEVBQUV5QixLQUFLLENBQUNrRixLQUFLLEVBQUVvQixNQUFNLENBQUM7TUFDeEUsT0FBT2hJLEdBQUc7SUFDZCxDQUFHLEVBQUUsRUFBRSxDQUFDO0lBQ04sSUFBSXFULHFCQUFxQixHQUFHL2YsSUFBSSxDQUFDb08sS0FBSyxDQUFDekIsU0FBUyxDQUFDO01BQzdDb0UsQ0FBQyxHQUFHZ1AscUJBQXFCLENBQUNoUCxDQUFDO01BQzNCRSxDQUFDLEdBQUc4TyxxQkFBcUIsQ0FBQzlPLENBQUM7SUFFL0IsSUFBSTdDLEtBQUssQ0FBQ3NGLGFBQWEsQ0FBQ0QsYUFBYSxJQUFJLElBQUksRUFBRTtNQUM3Q3JGLEtBQUssQ0FBQ3NGLGFBQWEsQ0FBQ0QsYUFBYSxDQUFDMUMsQ0FBQyxJQUFJQSxDQUFDO01BQ3hDM0MsS0FBSyxDQUFDc0YsYUFBYSxDQUFDRCxhQUFhLENBQUN4QyxDQUFDLElBQUlBLENBQUM7SUFDNUM7SUFFRTdDLEtBQUssQ0FBQ3NGLGFBQWEsQ0FBQ3RnQixJQUFJLENBQUMsR0FBRzRNLElBQUk7RUFDbEMsQ0FBQzs7RUFHRCxNQUFBZ2dCLFFBQUEsR0FBZTtJQUNiNXNCLElBQUksRUFBRSxRQUFRO0lBQ2RrYyxPQUFPLEVBQUUsSUFBSTtJQUNiQyxLQUFLLEVBQUUsTUFBTTtJQUNiQyxRQUFRLEVBQUUsQ0FBQyxlQUFlLENBQUM7SUFDM0JqYyxFQUFFLEVBQUVtaEI7RUFDTixDQUFDO0VDbkRELFNBQVNqQixhQUFhQSxDQUFDdEYsSUFBSSxFQUFFO0lBQzNCLElBQUlDLEtBQUssR0FBR0QsSUFBSSxDQUFDQyxLQUFLO01BQ2xCaGIsSUFBSSxHQUFHK2EsSUFBSSxDQUFDL2EsSUFBSTtJQUN0QjtJQUNBO0lBQ0E7SUFDQTtJQUNFZ2IsS0FBSyxDQUFDc0YsYUFBYSxDQUFDdGdCLElBQUksQ0FBQyxHQUFHc25CLGNBQWMsQ0FBQztNQUN6Q25PLFNBQVMsRUFBRTZCLEtBQUssQ0FBQ2tGLEtBQUssQ0FBQy9HLFNBQVM7TUFDaENwZixPQUFPLEVBQUVpaEIsS0FBSyxDQUFDa0YsS0FBSyxDQUFDaEgsTUFBTTtNQUMzQnlDLFFBQVEsRUFBRSxVQUFVO01BQ3BCcEMsU0FBUyxFQUFFeUIsS0FBSyxDQUFDekI7SUFDckIsQ0FBRyxDQUFDO0VBQ0osQ0FBQzs7RUFHRCxNQUFBc1QsZUFBQSxHQUFlO0lBQ2I3c0IsSUFBSSxFQUFFLGVBQWU7SUFDckJrYyxPQUFPLEVBQUUsSUFBSTtJQUNiQyxLQUFLLEVBQUUsTUFBTTtJQUNiaGMsRUFBRSxFQUFFa2dCLGFBQWE7SUFDakJ6VCxJQUFJLEVBQUU7RUFDUixDQUFDO0VDeEJjLFNBQVNrZ0IsVUFBVUEsQ0FBQ3RNLElBQUksRUFBRTtJQUN2QyxPQUFPQSxJQUFJLEtBQUssR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHO0VBQ2pDO0VDVUEsU0FBU3NMLGVBQWVBLENBQUMvUSxJQUFJLEVBQUU7SUFDN0IsSUFBSUMsS0FBSyxHQUFHRCxJQUFJLENBQUNDLEtBQUs7TUFDbEJVLE9BQU8sR0FBR1gsSUFBSSxDQUFDVyxPQUFPO01BQ3RCMWIsSUFBSSxHQUFHK2EsSUFBSSxDQUFDL2EsSUFBSTtJQUNwQixJQUFJNHBCLGlCQUFpQixHQUFHbE8sT0FBTyxDQUFDK0wsUUFBUTtNQUNwQ29DLGFBQWEsR0FBR0QsaUJBQWlCLEtBQUssS0FBSyxDQUFDLEdBQUcsSUFBSSxHQUFHQSxpQkFBaUI7TUFDdkVFLGdCQUFnQixHQUFHcE8sT0FBTyxDQUFDcU8sT0FBTztNQUNsQ0MsWUFBWSxHQUFHRixnQkFBZ0IsS0FBSyxLQUFLLENBQUMsR0FBRyxLQUFLLEdBQUdBLGdCQUFnQjtNQUNyRTlDLFFBQVEsR0FBR3RMLE9BQU8sQ0FBQ3NMLFFBQVE7TUFDM0JDLFlBQVksR0FBR3ZMLE9BQU8sQ0FBQ3VMLFlBQVk7TUFDbkNrQixXQUFXLEdBQUd6TSxPQUFPLENBQUN5TSxXQUFXO01BQ2pDbEksT0FBTyxHQUFHdkUsT0FBTyxDQUFDdUUsT0FBTztNQUN6QjhNLGVBQWUsR0FBR3JSLE9BQU8sQ0FBQ3NSLE1BQU07TUFDaENBLE1BQU0sR0FBR0QsZUFBZSxLQUFLLEtBQUssQ0FBQyxHQUFHLElBQUksR0FBR0EsZUFBZTtNQUM1REUscUJBQXFCLEdBQUd2UixPQUFPLENBQUN3UixZQUFZO01BQzVDQSxZQUFZLEdBQUdELHFCQUFxQixLQUFLLEtBQUssQ0FBQyxHQUFHLENBQUMsR0FBR0EscUJBQXFCO0lBQy9FLElBQUluSCxRQUFRLEdBQUc0QixjQUFjLENBQUMxTSxLQUFLLEVBQUU7TUFDbkNnTSxRQUFRLEVBQUVBLFFBQVE7TUFDbEJDLFlBQVksRUFBRUEsWUFBWTtNQUMxQmhILE9BQU8sRUFBRUEsT0FBTztNQUNoQmtJLFdBQVcsRUFBRUE7SUFDakIsQ0FBRyxDQUFDO0lBQ0YsSUFBSTVILGFBQWEsR0FBR2xFLGdCQUFnQixDQUFDckIsS0FBSyxDQUFDekIsU0FBUyxDQUFDO0lBQ3JELElBQUkrSSxTQUFTLEdBQUdULFlBQVksQ0FBQzdHLEtBQUssQ0FBQ3pCLFNBQVMsQ0FBQztJQUM3QyxJQUFJOFEsZUFBZSxHQUFHLENBQUMvSCxTQUFTO0lBQ2hDLElBQUltRixRQUFRLEdBQUdwSSx3QkFBd0IsQ0FBQ2tCLGFBQWEsQ0FBQztJQUN0RCxJQUFJd0osT0FBTyxHQUFHK0MsVUFBVSxDQUFDckYsUUFBUSxDQUFDO0lBQ2xDLElBQUlwSCxhQUFhLEdBQUdyRixLQUFLLENBQUNzRixhQUFhLENBQUNELGFBQWE7SUFDckQsSUFBSWlLLGFBQWEsR0FBR3RQLEtBQUssQ0FBQ2tGLEtBQUssQ0FBQy9HLFNBQVM7SUFDekMsSUFBSWtKLFVBQVUsR0FBR3JILEtBQUssQ0FBQ2tGLEtBQUssQ0FBQ2hILE1BQU07SUFDbkMsSUFBSWlVLGlCQUFpQixHQUFHLE9BQU9ELFlBQVksS0FBSyxVQUFVLEdBQUdBLFlBQVksQ0FBQ3Z4QixNQUFNLENBQUN5ZixNQUFNLENBQUMsRUFBRSxFQUFFSixLQUFLLENBQUNrRixLQUFLLEVBQUU7TUFDdkczRyxTQUFTLEVBQUV5QixLQUFLLENBQUN6QjtJQUNyQixDQUFHLENBQUMsQ0FBQyxHQUFHMlQsWUFBWTtJQUNsQixJQUFJRSwyQkFBMkIsR0FBRyxPQUFPRCxpQkFBaUIsS0FBSyxRQUFRLEdBQUc7TUFDeEUxRixRQUFRLEVBQUUwRixpQkFBaUI7TUFDM0JwRCxPQUFPLEVBQUVvRDtJQUNiLENBQUcsR0FBR3h4QixNQUFNLENBQUN5ZixNQUFNLENBQUM7TUFDaEJxTSxRQUFRLEVBQUUsQ0FBQztNQUNYc0MsT0FBTyxFQUFFO0lBQ2IsQ0FBRyxFQUFFb0QsaUJBQWlCLENBQUM7SUFDckIsSUFBSUUsbUJBQW1CLEdBQUdyUyxLQUFLLENBQUNzRixhQUFhLENBQUNnQixNQUFNLEdBQUd0RyxLQUFLLENBQUNzRixhQUFhLENBQUNnQixNQUFNLENBQUN0RyxLQUFLLENBQUN6QixTQUFTLENBQUMsR0FBRyxJQUFJO0lBQ3pHLElBQUkzTSxJQUFJLEdBQUc7TUFDVCtRLENBQUMsRUFBRSxDQUFDO01BQ0pFLENBQUMsRUFBRTtJQUNQLENBQUc7SUFFRCxJQUFJLENBQUN3QyxhQUFhLEVBQUU7TUFDbEI7SUFDSjtJQUVFLElBQUl3SixhQUFhLEVBQUU7TUFDakIsSUFBSXlELHFCQUFxQjtNQUV6QixJQUFJQyxRQUFRLEdBQUc5RixRQUFRLEtBQUssR0FBRyxHQUFHalAsR0FBRyxHQUFHRyxJQUFJO01BQzVDLElBQUk2VSxPQUFPLEdBQUcvRixRQUFRLEtBQUssR0FBRyxHQUFHaFAsTUFBTSxHQUFHQyxLQUFLO01BQy9DLElBQUlnSSxHQUFHLEdBQUcrRyxRQUFRLEtBQUssR0FBRyxHQUFHLFFBQVEsR0FBRyxPQUFPO01BQy9DLElBQUluRyxNQUFNLEdBQUdqQixhQUFhLENBQUNvSCxRQUFRLENBQUM7TUFDcEMsSUFBSWxJLEtBQUcsR0FBRytCLE1BQU0sR0FBR3dFLFFBQVEsQ0FBQ3lILFFBQVEsQ0FBQztNQUNyQyxJQUFJL04sS0FBRyxHQUFHOEIsTUFBTSxHQUFHd0UsUUFBUSxDQUFDMEgsT0FBTyxDQUFDO01BQ3BDLElBQUlDLFFBQVEsR0FBR1QsTUFBTSxHQUFHLENBQUMzSyxVQUFVLENBQUMzQixHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQztNQUNoRCxJQUFJZ04sTUFBTSxHQUFHcEwsU0FBUyxLQUFLeEosS0FBSyxHQUFHd1IsYUFBYSxDQUFDNUosR0FBRyxDQUFDLEdBQUcyQixVQUFVLENBQUMzQixHQUFHLENBQUM7TUFDdkUsSUFBSWlOLE1BQU0sR0FBR3JMLFNBQVMsS0FBS3hKLEtBQUssR0FBRyxDQUFDdUosVUFBVSxDQUFDM0IsR0FBRyxDQUFDLEdBQUcsQ0FBQzRKLGFBQWEsQ0FBQzVKLEdBQUcsQ0FBQyxDQUFDO01BQzlFOztNQUVJLElBQUlOLFlBQVksR0FBR3BGLEtBQUssQ0FBQ0MsUUFBUSxDQUFDWSxLQUFLO01BQ3ZDLElBQUk4RSxTQUFTLEdBQUdxTSxNQUFNLElBQUk1TSxZQUFZLEdBQUdyQyxhQUFhLENBQUNxQyxZQUFZLENBQUMsR0FBRztRQUNyRTdDLEtBQUssRUFBRSxDQUFDO1FBQ1JDLE1BQU0sRUFBRTtNQUNkLENBQUs7TUFDRCxJQUFJb1Esa0JBQWtCLEdBQUc1UyxLQUFLLENBQUNzRixhQUFhLENBQUMsa0JBQWtCLENBQUMsR0FBR3RGLEtBQUssQ0FBQ3NGLGFBQWEsQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDTCxPQUFPLEdBQUdOLGtCQUFrQixFQUFFO01BQ3pJLElBQUlrTyxlQUFlLEdBQUdELGtCQUFrQixDQUFDTCxRQUFRLENBQUM7TUFDbEQsSUFBSU8sZUFBZSxHQUFHRixrQkFBa0IsQ0FBQ0osT0FBTyxDQUFDLENBQUM7TUFDdEQ7TUFDQTtNQUNBO01BQ0E7O01BRUksSUFBSU8sUUFBUSxHQUFHek8sTUFBTSxDQUFDLENBQUMsRUFBRWdMLGFBQWEsQ0FBQzVKLEdBQUcsQ0FBQyxFQUFFQyxTQUFTLENBQUNELEdBQUcsQ0FBQyxDQUFDO01BQzVELElBQUlzTixTQUFTLEdBQUczRCxlQUFlLEdBQUdDLGFBQWEsQ0FBQzVKLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRytNLFFBQVEsR0FBR00sUUFBUSxHQUFHRixlQUFlLEdBQUdULDJCQUEyQixDQUFDM0YsUUFBUSxHQUFHaUcsTUFBTSxHQUFHSyxRQUFRLEdBQUdGLGVBQWUsR0FBR1QsMkJBQTJCLENBQUMzRixRQUFRO01BQ3BOLElBQUl3RyxTQUFTLEdBQUc1RCxlQUFlLEdBQUcsQ0FBQ0MsYUFBYSxDQUFDNUosR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHK00sUUFBUSxHQUFHTSxRQUFRLEdBQUdELGVBQWUsR0FBR1YsMkJBQTJCLENBQUMzRixRQUFRLEdBQUdrRyxNQUFNLEdBQUdJLFFBQVEsR0FBR0QsZUFBZSxHQUFHViwyQkFBMkIsQ0FBQzNGLFFBQVE7TUFDck4sSUFBSXpHLGlCQUFpQixHQUFHaEcsS0FBSyxDQUFDQyxRQUFRLENBQUNZLEtBQUssSUFBSXVELGVBQWUsQ0FBQ3BFLEtBQUssQ0FBQ0MsUUFBUSxDQUFDWSxLQUFLLENBQUM7TUFDckYsSUFBSXFTLFlBQVksR0FBR2xOLGlCQUFpQixHQUFHeUcsUUFBUSxLQUFLLEdBQUcsR0FBR3pHLGlCQUFpQixDQUFDd0YsU0FBUyxJQUFJLENBQUMsR0FBR3hGLGlCQUFpQixDQUFDeUYsVUFBVSxJQUFJLENBQUMsR0FBRyxDQUFDO01BQ2xJLElBQUkwSCxtQkFBbUIsR0FBRyxDQUFDYixxQkFBcUIsR0FBR0QsbUJBQW1CLElBQUksSUFBSSxHQUFHLEtBQUssQ0FBQyxHQUFHQSxtQkFBbUIsQ0FBQzVGLFFBQVEsQ0FBQyxLQUFLLElBQUksR0FBRzZGLHFCQUFxQixHQUFHLENBQUM7TUFDNUosSUFBSWMsU0FBUyxHQUFHOU0sTUFBTSxHQUFHME0sU0FBUyxHQUFHRyxtQkFBbUIsR0FBR0QsWUFBWTtNQUN2RSxJQUFJRyxTQUFTLEdBQUcvTSxNQUFNLEdBQUcyTSxTQUFTLEdBQUdFLG1CQUFtQjtNQUN4RCxJQUFJRyxlQUFlLEdBQUdoUCxNQUFNLENBQUMwTixNQUFNLEdBQUdockIsR0FBTyxDQUFDdWQsS0FBRyxFQUFFNk8sU0FBUyxDQUFDLEdBQUc3TyxLQUFHLEVBQUUrQixNQUFNLEVBQUUwTCxNQUFNLEdBQUdqckIsR0FBTyxDQUFDeWQsS0FBRyxFQUFFNk8sU0FBUyxDQUFDLEdBQUc3TyxLQUFHLENBQUM7TUFDcEhhLGFBQWEsQ0FBQ29ILFFBQVEsQ0FBQyxHQUFHNkcsZUFBZTtNQUN6QzFoQixJQUFJLENBQUM2YSxRQUFRLENBQUMsR0FBRzZHLGVBQWUsR0FBR2hOLE1BQU07SUFDN0M7SUFFRSxJQUFJMEksWUFBWSxFQUFFO01BQ2hCLElBQUl1RSxzQkFBc0I7TUFFMUIsSUFBSUMsU0FBUyxHQUFHL0csUUFBUSxLQUFLLEdBQUcsR0FBR2pQLEdBQUcsR0FBR0csSUFBSTtNQUU3QyxJQUFJOFYsUUFBUSxHQUFHaEgsUUFBUSxLQUFLLEdBQUcsR0FBR2hQLE1BQU0sR0FBR0MsS0FBSztNQUVoRCxJQUFJZ1csT0FBTyxHQUFHck8sYUFBYSxDQUFDMEosT0FBTyxDQUFDO01BRXBDLElBQUk0RSxJQUFJLEdBQUc1RSxPQUFPLEtBQUssR0FBRyxHQUFHLFFBQVEsR0FBRyxPQUFPO01BRS9DLElBQUk2RSxJQUFJLEdBQUdGLE9BQU8sR0FBRzVJLFFBQVEsQ0FBQzBJLFNBQVMsQ0FBQztNQUV4QyxJQUFJSyxJQUFJLEdBQUdILE9BQU8sR0FBRzVJLFFBQVEsQ0FBQzJJLFFBQVEsQ0FBQztNQUV2QyxJQUFJSyxZQUFZLEdBQUcsQ0FBQ3RXLEdBQUcsRUFBRUcsSUFBSSxDQUFDLENBQUM3VyxPQUFPLENBQUN5ZSxhQUFhLENBQUMsS0FBSyxDQUFDLENBQUM7TUFFNUQsSUFBSXdPLG9CQUFvQixHQUFHLENBQUNSLHNCQUFzQixHQUFHbEIsbUJBQW1CLElBQUksSUFBSSxHQUFHLEtBQUssQ0FBQyxHQUFHQSxtQkFBbUIsQ0FBQ3RELE9BQU8sQ0FBQyxLQUFLLElBQUksR0FBR3dFLHNCQUFzQixHQUFHLENBQUM7TUFFOUosSUFBSVMsVUFBVSxHQUFHRixZQUFZLEdBQUdGLElBQUksR0FBR0YsT0FBTyxHQUFHcEUsYUFBYSxDQUFDcUUsSUFBSSxDQUFDLEdBQUd0TSxVQUFVLENBQUNzTSxJQUFJLENBQUMsR0FBR0ksb0JBQW9CLEdBQUczQiwyQkFBMkIsQ0FBQ3JELE9BQU87TUFFcEosSUFBSWtGLFVBQVUsR0FBR0gsWUFBWSxHQUFHSixPQUFPLEdBQUdwRSxhQUFhLENBQUNxRSxJQUFJLENBQUMsR0FBR3RNLFVBQVUsQ0FBQ3NNLElBQUksQ0FBQyxHQUFHSSxvQkFBb0IsR0FBRzNCLDJCQUEyQixDQUFDckQsT0FBTyxHQUFHOEUsSUFBSTtNQUVwSixJQUFJSyxnQkFBZ0IsR0FBR2xDLE1BQU0sSUFBSThCLFlBQVksR0FBR3JQLGNBQWMsQ0FBQ3VQLFVBQVUsRUFBRU4sT0FBTyxFQUFFTyxVQUFVLENBQUMsR0FBRzNQLE1BQU0sQ0FBQzBOLE1BQU0sR0FBR2dDLFVBQVUsR0FBR0osSUFBSSxFQUFFRixPQUFPLEVBQUUxQixNQUFNLEdBQUdpQyxVQUFVLEdBQUdKLElBQUksQ0FBQztNQUV6S3hPLGFBQWEsQ0FBQzBKLE9BQU8sQ0FBQyxHQUFHbUYsZ0JBQWdCO01BQ3pDdGlCLElBQUksQ0FBQ21kLE9BQU8sQ0FBQyxHQUFHbUYsZ0JBQWdCLEdBQUdSLE9BQU87SUFDOUM7SUFFRTFULEtBQUssQ0FBQ3NGLGFBQWEsQ0FBQ3RnQixJQUFJLENBQUMsR0FBRzRNLElBQUk7RUFDbEMsQ0FBQzs7RUFHRCxNQUFBdWlCLGlCQUFBLEdBQWU7SUFDYm52QixJQUFJLEVBQUUsaUJBQWlCO0lBQ3ZCa2MsT0FBTyxFQUFFLElBQUk7SUFDYkMsS0FBSyxFQUFFLE1BQU07SUFDYmhjLEVBQUUsRUFBRTJyQixlQUFlO0lBQ25CbEssZ0JBQWdCLEVBQUUsQ0FBQyxRQUFRO0VBQzdCLENBQUM7RUM3SWMsU0FBU3dOLG9CQUFvQkEsQ0FBQ3IxQixPQUFPLEVBQUU7SUFDcEQsT0FBTztNQUNMZ3JCLFVBQVUsRUFBRWhyQixPQUFPLENBQUNnckIsVUFBVTtNQUM5QkUsU0FBUyxFQUFFbHJCLE9BQU8sQ0FBQ2tyQjtJQUN2QixDQUFHO0VBQ0g7RUNEZSxTQUFTb0ssYUFBYUEsQ0FBQy9VLElBQUksRUFBRTtJQUMxQyxJQUFJQSxJQUFJLEtBQUtELFNBQVMsQ0FBQ0MsSUFBSSxDQUFDLElBQUksQ0FBQ0ssYUFBYSxDQUFDTCxJQUFJLENBQUMsRUFBRTtNQUNwRCxPQUFPd0ssZUFBZSxDQUFDeEssSUFBSSxDQUFDO0lBQ2hDLENBQUcsTUFBTTtNQUNMLE9BQU84VSxvQkFBb0IsQ0FBQzlVLElBQUksQ0FBQztJQUNyQztFQUNBO0VDREEsU0FBU2dWLGVBQWVBLENBQUN2MUIsT0FBTyxFQUFFO0lBQ2hDLElBQUl1c0IsSUFBSSxHQUFHdnNCLE9BQU8sQ0FBQ3FlLHFCQUFxQixFQUFFO0lBQzFDLElBQUlnRixNQUFNLEdBQUdkLEtBQUssQ0FBQ2dLLElBQUksQ0FBQy9JLEtBQUssQ0FBQyxHQUFHeGpCLE9BQU8sQ0FBQ3VqQixXQUFXLElBQUksQ0FBQztJQUN6RCxJQUFJRCxNQUFNLEdBQUdmLEtBQUssQ0FBQ2dLLElBQUksQ0FBQzlJLE1BQU0sQ0FBQyxHQUFHempCLE9BQU8sQ0FBQ2tGLFlBQVksSUFBSSxDQUFDO0lBQzNELE9BQU9tZSxNQUFNLEtBQUssQ0FBQyxJQUFJQyxNQUFNLEtBQUssQ0FBQztFQUNyQyxDQUFDO0VBQ0Q7O0VBR2UsU0FBU2tTLGdCQUFnQkEsQ0FBQ0MsdUJBQXVCLEVBQUUvUSxZQUFZLEVBQUVrRSxPQUFPLEVBQUU7SUFDdkYsSUFBSUEsT0FBTyxLQUFLLEtBQUssQ0FBQyxFQUFFO01BQ3RCQSxPQUFPLEdBQUcsS0FBSztJQUNuQjtJQUVFLElBQUk4TSx1QkFBdUIsR0FBRzlVLGFBQWEsQ0FBQzhELFlBQVksQ0FBQztJQUN6RCxJQUFJaVIsb0JBQW9CLEdBQUcvVSxhQUFhLENBQUM4RCxZQUFZLENBQUMsSUFBSTZRLGVBQWUsQ0FBQzdRLFlBQVksQ0FBQztJQUN2RixJQUFJL2YsZUFBZSxHQUFHMmYsa0JBQWtCLENBQUNJLFlBQVksQ0FBQztJQUN0RCxJQUFJNkgsSUFBSSxHQUFHbE8scUJBQXFCLENBQUNvWCx1QkFBdUIsRUFBRUUsb0JBQW9CLEVBQUUvTSxPQUFPLENBQUM7SUFDeEYsSUFBSXVCLE1BQU0sR0FBRztNQUNYYSxVQUFVLEVBQUUsQ0FBQztNQUNiRSxTQUFTLEVBQUU7SUFDZixDQUFHO0lBQ0QsSUFBSTFDLE9BQU8sR0FBRztNQUNaNUUsQ0FBQyxFQUFFLENBQUM7TUFDSkUsQ0FBQyxFQUFFO0lBQ1AsQ0FBRztJQUVELElBQUk0Uix1QkFBdUIsSUFBSSxDQUFDQSx1QkFBdUIsSUFBSSxDQUFDOU0sT0FBTyxFQUFFO01BQ25FLElBQUl4SSxXQUFXLENBQUNzRSxZQUFZLENBQUMsS0FBSyxNQUFNO01BQUE7TUFDeENtSCxjQUFjLENBQUNsbkIsZUFBZSxDQUFDLEVBQUU7UUFDL0J3bEIsTUFBTSxHQUFHbUwsYUFBYSxDQUFDNVEsWUFBWSxDQUFDO01BQzFDO01BRUksSUFBSTlELGFBQWEsQ0FBQzhELFlBQVksQ0FBQyxFQUFFO1FBQy9COEQsT0FBTyxHQUFHbksscUJBQXFCLENBQUNxRyxZQUFZLEVBQUUsSUFBSSxDQUFDO1FBQ25EOEQsT0FBTyxDQUFDNUUsQ0FBQyxJQUFJYyxZQUFZLENBQUNnSSxVQUFVO1FBQ3BDbEUsT0FBTyxDQUFDMUUsQ0FBQyxJQUFJWSxZQUFZLENBQUMrSCxTQUFTO01BQ3pDLENBQUssTUFBTSxJQUFJOW5CLGVBQWUsRUFBRTtRQUMxQjZqQixPQUFPLENBQUM1RSxDQUFDLEdBQUd3SCxtQkFBbUIsQ0FBQ3ptQixlQUFlLENBQUM7TUFDdEQ7SUFDQTtJQUVFLE9BQU87TUFDTGlmLENBQUMsRUFBRTJJLElBQUksQ0FBQzNOLElBQUksR0FBR3VMLE1BQU0sQ0FBQ2EsVUFBVSxHQUFHeEMsT0FBTyxDQUFDNUUsQ0FBQztNQUM1Q0UsQ0FBQyxFQUFFeUksSUFBSSxDQUFDOU4sR0FBRyxHQUFHMEwsTUFBTSxDQUFDZSxTQUFTLEdBQUcxQyxPQUFPLENBQUMxRSxDQUFDO01BQzFDTixLQUFLLEVBQUUrSSxJQUFJLENBQUMvSSxLQUFLO01BQ2pCQyxNQUFNLEVBQUU4SSxJQUFJLENBQUM5STtJQUNqQixDQUFHO0VBQ0g7RUN2REEsU0FBUzdKLEtBQUtBLENBQUNnYyxTQUFTLEVBQUU7SUFDeEIsSUFBSXZsQixHQUFHLEdBQUcsSUFBSXhRLEdBQUcsRUFBRTtJQUNuQixJQUFJZzJCLE9BQU8sR0FBRyxJQUFJbHRCLEdBQUcsRUFBRTtJQUN2QixJQUFJbXRCLE1BQU0sR0FBRyxFQUFFO0lBQ2ZGLFNBQVMsQ0FBQ3pVLE9BQU8sQ0FBQyxVQUFVNFUsUUFBUSxFQUFFO01BQ3BDMWxCLEdBQUcsQ0FBQ3RRLEdBQUcsQ0FBQ2cyQixRQUFRLENBQUM5dkIsSUFBSSxFQUFFOHZCLFFBQVEsQ0FBQztJQUNwQyxDQUFHLENBQUMsQ0FBQzs7SUFFSCxTQUFTekcsSUFBSUEsQ0FBQ3lHLFFBQVEsRUFBRTtNQUN0QkYsT0FBTyxDQUFDcmdCLEdBQUcsQ0FBQ3VnQixRQUFRLENBQUM5dkIsSUFBSSxDQUFDO01BQzFCLElBQUlvYyxRQUFRLEdBQUcsRUFBRSxDQUFDNVIsTUFBTSxDQUFDc2xCLFFBQVEsQ0FBQzFULFFBQVEsSUFBSSxFQUFFLEVBQUUwVCxRQUFRLENBQUNsTyxnQkFBZ0IsSUFBSSxFQUFFLENBQUM7TUFDbEZ4RixRQUFRLENBQUNsQixPQUFPLENBQUMsVUFBVTZVLEdBQUcsRUFBRTtRQUM5QixJQUFJLENBQUNILE9BQU8sQ0FBQzExQixHQUFHLENBQUM2MUIsR0FBRyxDQUFDLEVBQUU7VUFDckIsSUFBSUMsV0FBVyxHQUFHNWxCLEdBQUcsQ0FBQ2hRLEdBQUcsQ0FBQzIxQixHQUFHLENBQUM7VUFFOUIsSUFBSUMsV0FBVyxFQUFFO1lBQ2YzRyxJQUFJLENBQUMyRyxXQUFXLENBQUM7VUFDM0I7UUFDQTtNQUNBLENBQUssQ0FBQztNQUNGSCxNQUFNLENBQUNud0IsSUFBSSxDQUFDb3dCLFFBQVEsQ0FBQztJQUN6QjtJQUVFSCxTQUFTLENBQUN6VSxPQUFPLENBQUMsVUFBVTRVLFFBQVEsRUFBRTtNQUNwQyxJQUFJLENBQUNGLE9BQU8sQ0FBQzExQixHQUFHLENBQUM0MUIsUUFBUSxDQUFDOXZCLElBQUksQ0FBQyxFQUFFO1FBQ3JDO1FBQ01xcEIsSUFBSSxDQUFDeUcsUUFBUSxDQUFDO01BQ3BCO0lBQ0EsQ0FBRyxDQUFDO0lBQ0YsT0FBT0QsTUFBTTtFQUNmO0VBRWUsU0FBU0ksY0FBY0EsQ0FBQ04sU0FBUyxFQUFFO0lBQ2xEO0lBQ0UsSUFBSU8sZ0JBQWdCLEdBQUd2YyxLQUFLLENBQUNnYyxTQUFTLENBQUMsQ0FBQzs7SUFFeEMsT0FBT3pWLGNBQWMsQ0FBQ2IsTUFBTSxDQUFDLFVBQVVDLEdBQUcsRUFBRTZDLEtBQUssRUFBRTtNQUNqRCxPQUFPN0MsR0FBRyxDQUFDOU8sTUFBTSxDQUFDMGxCLGdCQUFnQixDQUFDdG9CLE1BQU0sQ0FBQyxVQUFVa29CLFFBQVEsRUFBRTtRQUM1RCxPQUFPQSxRQUFRLENBQUMzVCxLQUFLLEtBQUtBLEtBQUs7TUFDckMsQ0FBSyxDQUFDLENBQUM7SUFDUCxDQUFHLEVBQUUsRUFBRSxDQUFDO0VBQ1I7RUMzQ2UsU0FBU2dVLFFBQVFBLENBQUNod0IsRUFBRSxFQUFFO0lBQ25DLElBQUlpd0IsT0FBTztJQUNYLE9BQU8sWUFBWTtNQUNqQixJQUFJLENBQUNBLE9BQU8sRUFBRTtRQUNaQSxPQUFPLEdBQUcsSUFBSUMsT0FBTyxDQUFDLFVBQVVDLE9BQU8sRUFBRTtVQUN2Q0QsT0FBTyxDQUFDQyxPQUFPLEVBQUUsQ0FBQ0MsSUFBSSxDQUFDLFlBQVk7WUFDakNILE9BQU8sR0FBRzEwQixTQUFTO1lBQ25CNDBCLE9BQU8sQ0FBQ253QixFQUFFLEVBQUUsQ0FBQztVQUN2QixDQUFTLENBQUM7UUFDVixDQUFPLENBQUM7TUFDUjtNQUVJLE9BQU9pd0IsT0FBTztJQUNsQixDQUFHO0VBQ0g7RUNkZSxTQUFTSSxXQUFXQSxDQUFDYixTQUFTLEVBQUU7SUFDN0MsSUFBSWMsTUFBTSxHQUFHZCxTQUFTLENBQUN0VyxNQUFNLENBQUMsVUFBVW9YLE1BQU0sRUFBRUMsT0FBTyxFQUFFO01BQ3ZELElBQUlDLFFBQVEsR0FBR0YsTUFBTSxDQUFDQyxPQUFPLENBQUMxd0IsSUFBSSxDQUFDO01BQ25DeXdCLE1BQU0sQ0FBQ0MsT0FBTyxDQUFDMXdCLElBQUksQ0FBQyxHQUFHMndCLFFBQVEsR0FBR2gxQixNQUFNLENBQUN5ZixNQUFNLENBQUMsRUFBRSxFQUFFdVYsUUFBUSxFQUFFRCxPQUFPLEVBQUU7UUFDckVoVixPQUFPLEVBQUUvZixNQUFNLENBQUN5ZixNQUFNLENBQUMsRUFBRSxFQUFFdVYsUUFBUSxDQUFDalYsT0FBTyxFQUFFZ1YsT0FBTyxDQUFDaFYsT0FBTyxDQUFDO1FBQzdEOU8sSUFBSSxFQUFFalIsTUFBTSxDQUFDeWYsTUFBTSxDQUFDLEVBQUUsRUFBRXVWLFFBQVEsQ0FBQy9qQixJQUFJLEVBQUU4akIsT0FBTyxDQUFDOWpCLElBQUk7TUFDekQsQ0FBSyxDQUFDLEdBQUc4akIsT0FBTztNQUNaLE9BQU9ELE1BQU07SUFDakIsQ0FBRyxFQUFFLEVBQUUsQ0FBQyxDQUFDOztJQUVQLE9BQU85MEIsTUFBTSxDQUFDakIsSUFBSSxDQUFDKzFCLE1BQU0sQ0FBQyxDQUFDcm1CLEdBQUcsQ0FBQyxVQUFVcFEsR0FBRyxFQUFFO01BQzVDLE9BQU95MkIsTUFBTSxDQUFDejJCLEdBQUcsQ0FBQztJQUN0QixDQUFHLENBQUM7RUFDSjtFQ0pBLElBQUk0MkIsZUFBZSxHQUFHO0lBQ3BCclgsU0FBUyxFQUFFLFFBQVE7SUFDbkJvVyxTQUFTLEVBQUUsRUFBRTtJQUNiaFUsUUFBUSxFQUFFO0VBQ1osQ0FBQztFQUVELFNBQVNrVixnQkFBZ0JBLENBQUEsRUFBRztJQUMxQixLQUFLLElBQUlsQyxJQUFJLEdBQUdqdUIsU0FBUyxDQUFDbkQsTUFBTSxFQUFFa0QsSUFBSSxHQUFHLElBQUlqRyxLQUFLLENBQUNtMEIsSUFBSSxDQUFDLEVBQUVtQyxJQUFJLEdBQUcsQ0FBQyxFQUFFQSxJQUFJLEdBQUduQyxJQUFJLEVBQUVtQyxJQUFJLEVBQUUsRUFBRTtNQUN2RnJ3QixJQUFJLENBQUNxd0IsSUFBSSxDQUFDLEdBQUdwd0IsU0FBUyxDQUFDb3dCLElBQUksQ0FBQztJQUNoQztJQUVFLE9BQU8sQ0FBQ3J3QixJQUFJLENBQUNtckIsSUFBSSxDQUFDLFVBQVU3eEIsT0FBTyxFQUFFO01BQ25DLE9BQU8sRUFBRUEsT0FBTyxJQUFJLE9BQU9BLE9BQU8sQ0FBQ3FlLHFCQUFxQixLQUFLLFVBQVUsQ0FBQztJQUM1RSxDQUFHLENBQUM7RUFDSjtFQUVPLFNBQVMyWSxlQUFlQSxDQUFDQyxnQkFBZ0IsRUFBRTtJQUNoRCxJQUFJQSxnQkFBZ0IsS0FBSyxLQUFLLENBQUMsRUFBRTtNQUMvQkEsZ0JBQWdCLEdBQUcsRUFBRTtJQUN6QjtJQUVFLElBQUlDLGlCQUFpQixHQUFHRCxnQkFBZ0I7TUFDcENFLHFCQUFxQixHQUFHRCxpQkFBaUIsQ0FBQ0UsZ0JBQWdCO01BQzFEQSxnQkFBZ0IsR0FBR0QscUJBQXFCLEtBQUssS0FBSyxDQUFDLEdBQUcsRUFBRSxHQUFHQSxxQkFBcUI7TUFDaEZFLHNCQUFzQixHQUFHSCxpQkFBaUIsQ0FBQ0ksY0FBYztNQUN6REEsY0FBYyxHQUFHRCxzQkFBc0IsS0FBSyxLQUFLLENBQUMsR0FBR1IsZUFBZSxHQUFHUSxzQkFBc0I7SUFDakcsT0FBTyxTQUFTRSxZQUFZQSxDQUFDblksU0FBUyxFQUFFRCxNQUFNLEVBQUV3QyxPQUFPLEVBQUU7TUFDdkQsSUFBSUEsT0FBTyxLQUFLLEtBQUssQ0FBQyxFQUFFO1FBQ3RCQSxPQUFPLEdBQUcyVixjQUFjO01BQzlCO01BRUksSUFBSXJXLEtBQUssR0FBRztRQUNWekIsU0FBUyxFQUFFLFFBQVE7UUFDbkIyVyxnQkFBZ0IsRUFBRSxFQUFFO1FBQ3BCeFUsT0FBTyxFQUFFL2YsTUFBTSxDQUFDeWYsTUFBTSxDQUFDLEVBQUUsRUFBRXdWLGVBQWUsRUFBRVMsY0FBYyxDQUFDO1FBQzNEL1EsYUFBYSxFQUFFLEVBQUU7UUFDakJyRixRQUFRLEVBQUU7VUFDUjlCLFNBQVMsRUFBRUEsU0FBUztVQUNwQkQsTUFBTSxFQUFFQTtRQUNoQixDQUFPO1FBQ0R6UixVQUFVLEVBQUUsRUFBRTtRQUNkMFQsTUFBTSxFQUFFO01BQ2QsQ0FBSztNQUNELElBQUlvVyxnQkFBZ0IsR0FBRyxFQUFFO01BQ3pCLElBQUlDLFdBQVcsR0FBRyxLQUFLO01BQ3ZCLElBQUl2M0IsUUFBUSxHQUFHO1FBQ2IrZ0IsS0FBSyxFQUFFQSxLQUFLO1FBQ1p5VyxVQUFVLEVBQUUsU0FBU0EsVUFBVUEsQ0FBQ0MsZ0JBQWdCLEVBQUU7VUFDaEQsSUFBSWhXLE9BQU8sR0FBRyxPQUFPZ1csZ0JBQWdCLEtBQUssVUFBVSxHQUFHQSxnQkFBZ0IsQ0FBQzFXLEtBQUssQ0FBQ1UsT0FBTyxDQUFDLEdBQUdnVyxnQkFBZ0I7VUFDekdDLHNCQUFzQixFQUFFO1VBQ3hCM1csS0FBSyxDQUFDVSxPQUFPLEdBQUcvZixNQUFNLENBQUN5ZixNQUFNLENBQUMsRUFBRSxFQUFFaVcsY0FBYyxFQUFFclcsS0FBSyxDQUFDVSxPQUFPLEVBQUVBLE9BQU8sQ0FBQztVQUN6RVYsS0FBSyxDQUFDcUosYUFBYSxHQUFHO1lBQ3BCbEwsU0FBUyxFQUFFc0IsU0FBUyxDQUFDdEIsU0FBUyxDQUFDLEdBQUcrTSxpQkFBaUIsQ0FBQy9NLFNBQVMsQ0FBQyxHQUFHQSxTQUFTLENBQUNvUCxjQUFjLEdBQUdyQyxpQkFBaUIsQ0FBQy9NLFNBQVMsQ0FBQ29QLGNBQWMsQ0FBQyxHQUFHLEVBQUU7WUFDNUlyUCxNQUFNLEVBQUVnTixpQkFBaUIsQ0FBQ2hOLE1BQU07VUFDMUMsQ0FBUyxDQUFDO1VBQ1Y7O1VBRVEsSUFBSWdYLGdCQUFnQixHQUFHRCxjQUFjLENBQUNPLFdBQVcsQ0FBQyxFQUFFLENBQUNobUIsTUFBTSxDQUFDMm1CLGdCQUFnQixFQUFFblcsS0FBSyxDQUFDVSxPQUFPLENBQUNpVSxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUM7O1VBRXpHM1UsS0FBSyxDQUFDa1YsZ0JBQWdCLEdBQUdBLGdCQUFnQixDQUFDdG9CLE1BQU0sQ0FBQyxVQUFVZ3FCLENBQUMsRUFBRTtZQUM1RCxPQUFPQSxDQUFDLENBQUMxVixPQUFPO1VBQzFCLENBQVMsQ0FBQztVQUNGMlYsa0JBQWtCLEVBQUU7VUFDcEIsT0FBTzUzQixRQUFRLENBQUNzcUIsTUFBTSxFQUFFO1FBQ2hDLENBQU87UUFDUDtRQUNBO1FBQ0E7UUFDQTtRQUNBO1FBQ011TixXQUFXLEVBQUUsU0FBU0EsV0FBV0EsQ0FBQSxFQUFHO1VBQ2xDLElBQUlOLFdBQVcsRUFBRTtZQUNmO1VBQ1Y7VUFFUSxJQUFJTyxlQUFlLEdBQUcvVyxLQUFLLENBQUNDLFFBQVE7WUFDaEM5QixTQUFTLEdBQUc0WSxlQUFlLENBQUM1WSxTQUFTO1lBQ3JDRCxNQUFNLEdBQUc2WSxlQUFlLENBQUM3WSxNQUFNLENBQUM7VUFDNUM7O1VBRVEsSUFBSSxDQUFDMlgsZ0JBQWdCLENBQUMxWCxTQUFTLEVBQUVELE1BQU0sQ0FBQyxFQUFFO1lBQ3hDO1VBQ1YsQ0FBUzs7VUFHRDhCLEtBQUssQ0FBQ2tGLEtBQUssR0FBRztZQUNaL0csU0FBUyxFQUFFb1csZ0JBQWdCLENBQUNwVyxTQUFTLEVBQUVpRyxlQUFlLENBQUNsRyxNQUFNLENBQUMsRUFBRThCLEtBQUssQ0FBQ1UsT0FBTyxDQUFDQyxRQUFRLEtBQUssT0FBTyxDQUFDO1lBQ25HekMsTUFBTSxFQUFFNkUsYUFBYSxDQUFDN0UsTUFBTTtVQUN0QyxDQUFTLENBQUM7VUFDVjtVQUNBO1VBQ0E7VUFDQTs7VUFFUThCLEtBQUssQ0FBQ3VRLEtBQUssR0FBRyxLQUFLO1VBQ25CdlEsS0FBSyxDQUFDekIsU0FBUyxHQUFHeUIsS0FBSyxDQUFDVSxPQUFPLENBQUNuQyxTQUFTLENBQUM7VUFDbEQ7VUFDQTtVQUNBOztVQUVReUIsS0FBSyxDQUFDa1YsZ0JBQWdCLENBQUNoVixPQUFPLENBQUMsVUFBVTRVLFFBQVEsRUFBRTtZQUNqRCxPQUFPOVUsS0FBSyxDQUFDc0YsYUFBYSxDQUFDd1AsUUFBUSxDQUFDOXZCLElBQUksQ0FBQyxHQUFHckUsTUFBTSxDQUFDeWYsTUFBTSxDQUFDLEVBQUUsRUFBRTBVLFFBQVEsQ0FBQ2xqQixJQUFJLENBQUM7VUFDdEYsQ0FBUyxDQUFDO1VBRUYsS0FBSyxJQUFJL0ssS0FBSyxHQUFHLENBQUMsRUFBRUEsS0FBSyxHQUFHbVosS0FBSyxDQUFDa1YsZ0JBQWdCLENBQUMzeUIsTUFBTSxFQUFFc0UsS0FBSyxFQUFFLEVBQUU7WUFDbEUsSUFBSW1aLEtBQUssQ0FBQ3VRLEtBQUssS0FBSyxJQUFJLEVBQUU7Y0FDeEJ2USxLQUFLLENBQUN1USxLQUFLLEdBQUcsS0FBSztjQUNuQjFwQixLQUFLLEdBQUcsQ0FBQyxDQUFDO2NBQ1Y7WUFDWjtZQUVVLElBQUltd0IscUJBQXFCLEdBQUdoWCxLQUFLLENBQUNrVixnQkFBZ0IsQ0FBQ3J1QixLQUFLLENBQUM7Y0FDckQxQixFQUFFLEdBQUc2eEIscUJBQXFCLENBQUM3eEIsRUFBRTtjQUM3Qjh4QixzQkFBc0IsR0FBR0QscUJBQXFCLENBQUN0VyxPQUFPO2NBQ3REaU0sUUFBUSxHQUFHc0ssc0JBQXNCLEtBQUssS0FBSyxDQUFDLEdBQUcsRUFBRSxHQUFHQSxzQkFBc0I7Y0FDMUVqeUIsSUFBSSxHQUFHZ3lCLHFCQUFxQixDQUFDaHlCLElBQUk7WUFFckMsSUFBSSxPQUFPRyxFQUFFLEtBQUssVUFBVSxFQUFFO2NBQzVCNmEsS0FBSyxHQUFHN2EsRUFBRSxDQUFDO2dCQUNUNmEsS0FBSyxFQUFFQSxLQUFLO2dCQUNaVSxPQUFPLEVBQUVpTSxRQUFRO2dCQUNqQjNuQixJQUFJLEVBQUVBLElBQUk7Z0JBQ1YvRixRQUFRLEVBQUVBO2NBQ3hCLENBQWEsQ0FBQyxJQUFJK2dCLEtBQUs7WUFDdkI7VUFDQTtRQUNBLENBQU87UUFDUDtRQUNBO1FBQ011SixNQUFNLEVBQUU0TCxRQUFRLENBQUMsWUFBWTtVQUMzQixPQUFPLElBQUlFLE9BQU8sQ0FBQyxVQUFVQyxPQUFPLEVBQUU7WUFDcENyMkIsUUFBUSxDQUFDNjNCLFdBQVcsRUFBRTtZQUN0QnhCLE9BQU8sQ0FBQ3RWLEtBQUssQ0FBQztVQUN4QixDQUFTLENBQUM7UUFDVixDQUFPLENBQUM7UUFDRmtYLE9BQU8sRUFBRSxTQUFTQSxPQUFPQSxDQUFBLEVBQUc7VUFDMUJQLHNCQUFzQixFQUFFO1VBQ3hCSCxXQUFXLEdBQUcsSUFBSTtRQUMxQjtNQUNBLENBQUs7TUFFRCxJQUFJLENBQUNYLGdCQUFnQixDQUFDMVgsU0FBUyxFQUFFRCxNQUFNLENBQUMsRUFBRTtRQUN4QyxPQUFPamYsUUFBUTtNQUNyQjtNQUVJQSxRQUFRLENBQUN3M0IsVUFBVSxDQUFDL1YsT0FBTyxDQUFDLENBQUM2VSxJQUFJLENBQUMsVUFBVXZWLEtBQUssRUFBRTtRQUNqRCxJQUFJLENBQUN3VyxXQUFXLElBQUk5VixPQUFPLENBQUN5VyxhQUFhLEVBQUU7VUFDekN6VyxPQUFPLENBQUN5VyxhQUFhLENBQUNuWCxLQUFLLENBQUM7UUFDcEM7TUFDQSxDQUFLLENBQUMsQ0FBQztNQUNQO01BQ0E7TUFDQTtNQUNBOztNQUVJLFNBQVM2VyxrQkFBa0JBLENBQUEsRUFBRztRQUM1QjdXLEtBQUssQ0FBQ2tWLGdCQUFnQixDQUFDaFYsT0FBTyxDQUFDLFVBQVVILElBQUksRUFBRTtVQUM3QyxJQUFJL2EsSUFBSSxHQUFHK2EsSUFBSSxDQUFDL2EsSUFBSTtZQUNoQm95QixZQUFZLEdBQUdyWCxJQUFJLENBQUNXLE9BQU87WUFDM0JBLE9BQU8sR0FBRzBXLFlBQVksS0FBSyxLQUFLLENBQUMsR0FBRyxFQUFFLEdBQUdBLFlBQVk7WUFDckQ5VyxNQUFNLEdBQUdQLElBQUksQ0FBQ08sTUFBTTtVQUV4QixJQUFJLE9BQU9BLE1BQU0sS0FBSyxVQUFVLEVBQUU7WUFDaEMsSUFBSStXLFNBQVMsR0FBRy9XLE1BQU0sQ0FBQztjQUNyQk4sS0FBSyxFQUFFQSxLQUFLO2NBQ1poYixJQUFJLEVBQUVBLElBQUk7Y0FDVi9GLFFBQVEsRUFBRUEsUUFBUTtjQUNsQnloQixPQUFPLEVBQUVBO1lBQ3JCLENBQVcsQ0FBQztZQUVGLElBQUk0VyxNQUFNLEdBQUcsU0FBU0EsTUFBTUEsQ0FBQSxFQUFHLEVBQUU7WUFFakNmLGdCQUFnQixDQUFDN3hCLElBQUksQ0FBQzJ5QixTQUFTLElBQUlDLE1BQU0sQ0FBQztVQUNwRDtRQUNBLENBQU8sQ0FBQztNQUNSO01BRUksU0FBU1gsc0JBQXNCQSxDQUFBLEVBQUc7UUFDaENKLGdCQUFnQixDQUFDclcsT0FBTyxDQUFDLFVBQVUvYSxFQUFFLEVBQUU7VUFDckMsT0FBT0EsRUFBRSxFQUFFO1FBQ25CLENBQU8sQ0FBQztRQUNGb3hCLGdCQUFnQixHQUFHLEVBQUU7TUFDM0I7TUFFSSxPQUFPdDNCLFFBQVE7SUFDbkIsQ0FBRztFQUNIO0VBQ08sSUFBSXM0QixjQUFZLGdCQUFnQnhCLGVBQWUsRUFBRSxDQUFDOztFQy9MekQsSUFBSXlCLGtCQUFnQixHQUFHLENBQUNoTyxjQUFjLEVBQUVxSSxlQUFhLEVBQUU5SSxlQUFhLEVBQUU5SCxhQUFXLENBQUM7RUFDbEYsSUFBSXdXLGNBQVksZ0JBQWdCMUIsZUFBZSxDQUFDO0lBQzlDSSxnQkFBZ0IsRUFBRXFCO0VBQ3BCLENBQUMsQ0FBQyxDQUFDOztFQ0VILElBQUlyQixnQkFBZ0IsR0FBRyxDQUFDM00sY0FBYyxFQUFFcUksZUFBYSxFQUFFOUksZUFBYSxFQUFFOUgsYUFBVyxFQUFFMlEsUUFBTSxFQUFFcEIsTUFBSSxFQUFFMkQsaUJBQWUsRUFBRXhOLE9BQUssRUFBRTBLLE1BQUksQ0FBQztFQUM5SCxJQUFJaUYsWUFBWSxnQkFBZ0JQLGVBQWUsQ0FBQztJQUM5Q0ksZ0JBQWdCLEVBQUVBO0VBQ3BCLENBQUMsQ0FBQyxDQUFDOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0VDYkg7Ozs7Ozs7RUF3QkE7Ozs7RUFJQSxNQUFNdUIsTUFBSSxHQUFHLFVBQVU7RUFDdkIsTUFBTUMsVUFBUSxHQUFHLGFBQWE7RUFDOUIsTUFBTUMsV0FBUyxHQUFJLElBQUdELFVBQVMsRUFBQztFQUNoQyxNQUFNRSxjQUFZLEdBQUcsV0FBVztFQUVoQyxNQUFNQyxZQUFVLEdBQUcsUUFBUTtFQUMzQixNQUFNQyxTQUFPLEdBQUcsS0FBSztFQUNyQixNQUFNQyxjQUFZLEdBQUcsU0FBUztFQUM5QixNQUFNQyxnQkFBYyxHQUFHLFdBQVc7RUFDbEMsTUFBTUMsa0JBQWtCLEdBQUcsQ0FBQyxDQUFDOztFQUU3QixNQUFNQyxZQUFVLEdBQUksT0FBTVAsV0FBVSxFQUFDO0VBQ3JDLE1BQU1RLGNBQVksR0FBSSxTQUFRUixXQUFVLEVBQUM7RUFDekMsTUFBTVMsWUFBVSxHQUFJLE9BQU1ULFdBQVUsRUFBQztFQUNyQyxNQUFNVSxhQUFXLEdBQUksUUFBT1YsV0FBVSxFQUFDO0VBQ3ZDLE1BQU1XLHNCQUFvQixHQUFJLFFBQU9YLFdBQVUsR0FBRUMsY0FBYSxFQUFDO0VBQy9ELE1BQU1XLHNCQUFzQixHQUFJLFVBQVNaLFdBQVUsR0FBRUMsY0FBYSxFQUFDO0VBQ25FLE1BQU1ZLG9CQUFvQixHQUFJLFFBQU9iLFdBQVUsR0FBRUMsY0FBYSxFQUFDO0VBRS9ELE1BQU1hLGlCQUFlLEdBQUcsTUFBTTtFQUM5QixNQUFNQyxpQkFBaUIsR0FBRyxRQUFRO0VBQ2xDLE1BQU1DLGtCQUFrQixHQUFHLFNBQVM7RUFDcEMsTUFBTUMsb0JBQW9CLEdBQUcsV0FBVztFQUN4QyxNQUFNQyx3QkFBd0IsR0FBRyxlQUFlO0VBQ2hELE1BQU1DLDBCQUEwQixHQUFHLGlCQUFpQjtFQUVwRCxNQUFNQyxzQkFBb0IsR0FBRywyREFBMkQ7RUFDeEYsTUFBTUMsMEJBQTBCLEdBQUksR0FBRUQsc0JBQXFCLElBQUdOLGlCQUFnQixFQUFDO0VBQy9FLE1BQU1RLGFBQWEsR0FBRyxnQkFBZ0I7RUFDdEMsTUFBTUMsZUFBZSxHQUFHLFNBQVM7RUFDakMsTUFBTUMsbUJBQW1CLEdBQUcsYUFBYTtFQUN6QyxNQUFNQyxzQkFBc0IsR0FBRyw2REFBNkQ7RUFFNUYsTUFBTUMsYUFBYSxHQUFHMzBCLEtBQUssRUFBRSxHQUFHLFNBQVMsR0FBRyxXQUFXO0VBQ3ZELE1BQU00MEIsZ0JBQWdCLEdBQUc1MEIsS0FBSyxFQUFFLEdBQUcsV0FBVyxHQUFHLFNBQVM7RUFDMUQsTUFBTTYwQixnQkFBZ0IsR0FBRzcwQixLQUFLLEVBQUUsR0FBRyxZQUFZLEdBQUcsY0FBYztFQUNoRSxNQUFNODBCLG1CQUFtQixHQUFHOTBCLEtBQUssRUFBRSxHQUFHLGNBQWMsR0FBRyxZQUFZO0VBQ25FLE1BQU0rMEIsZUFBZSxHQUFHLzBCLEtBQUssRUFBRSxHQUFHLFlBQVksR0FBRyxhQUFhO0VBQzlELE1BQU1nMUIsY0FBYyxHQUFHaDFCLEtBQUssRUFBRSxHQUFHLGFBQWEsR0FBRyxZQUFZO0VBQzdELE1BQU1pMUIsbUJBQW1CLEdBQUcsS0FBSztFQUNqQyxNQUFNQyxzQkFBc0IsR0FBRyxRQUFRO0VBRXZDLE1BQU1DLFNBQU8sR0FBRztJQUNkQyxTQUFTLEVBQUUsSUFBSTtJQUNmL04sUUFBUSxFQUFFLGlCQUFpQjtJQUMzQmdPLE9BQU8sRUFBRSxTQUFTO0lBQ2xCMVQsTUFBTSxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQztJQUNkMlQsWUFBWSxFQUFFLElBQUk7SUFDbEI5YixTQUFTLEVBQUU7RUFDYixDQUFDO0VBRUQsTUFBTStiLGFBQVcsR0FBRztJQUNsQkgsU0FBUyxFQUFFLGtCQUFrQjtJQUM3Qi9OLFFBQVEsRUFBRSxrQkFBa0I7SUFDNUJnTyxPQUFPLEVBQUUsUUFBUTtJQUNqQjFULE1BQU0sRUFBRSx5QkFBeUI7SUFDakMyVCxZQUFZLEVBQUUsd0JBQXdCO0lBQ3RDOWIsU0FBUyxFQUFFO0VBQ2IsQ0FBQzs7RUFFRDs7OztFQUlBLE1BQU1nYyxRQUFRLFNBQVMvckIsYUFBYSxDQUFDO0lBQ25DVixXQUFXQSxDQUFDM08sT0FBTyxFQUFFc08sTUFBTSxFQUFFO01BQzNCLEtBQUssQ0FBQ3RPLE9BQU8sRUFBRXNPLE1BQU0sQ0FBQztNQUV0QixJQUFJLENBQUMrc0IsT0FBTyxHQUFHLElBQUk7TUFDbkIsSUFBSSxDQUFDQyxPQUFPLEdBQUcsSUFBSSxDQUFDaHNCLFFBQVEsQ0FBQ3JMLFVBQVUsQ0FBQztNQUN4QztNQUNBLElBQUksQ0FBQ3MzQixLQUFLLEdBQUcvcUIsY0FBYyxDQUFDWSxJQUFJLENBQUMsSUFBSSxDQUFDOUIsUUFBUSxFQUFFNnFCLGFBQWEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUMvRDNwQixjQUFjLENBQUNTLElBQUksQ0FBQyxJQUFJLENBQUMzQixRQUFRLEVBQUU2cUIsYUFBYSxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQ3BEM3BCLGNBQWMsQ0FBQ0csT0FBTyxDQUFDd3BCLGFBQWEsRUFBRSxJQUFJLENBQUNtQixPQUFPLENBQUM7TUFDckQsSUFBSSxDQUFDRSxTQUFTLEdBQUcsSUFBSSxDQUFDQyxhQUFhLEVBQUU7SUFDdkM7O0lBRUE7SUFDQSxXQUFXdnRCLE9BQU9BLENBQUEsRUFBRztNQUNuQixPQUFPNnNCLFNBQU87SUFDaEI7SUFFQSxXQUFXNXNCLFdBQVdBLENBQUEsRUFBRztNQUN2QixPQUFPZ3RCLGFBQVc7SUFDcEI7SUFFQSxXQUFXajFCLElBQUlBLENBQUEsRUFBRztNQUNoQixPQUFPeXlCLE1BQUk7SUFDYjs7SUFFQTtJQUNBcmxCLE1BQU1BLENBQUEsRUFBRztNQUNQLE9BQU8sSUFBSSxDQUFDa0ssUUFBUSxFQUFFLEdBQUcsSUFBSSxDQUFDQyxJQUFJLEVBQUUsR0FBRyxJQUFJLENBQUNDLElBQUksRUFBRTtJQUNwRDtJQUVBQSxJQUFJQSxDQUFBLEVBQUc7TUFDTCxJQUFJeFosVUFBVSxDQUFDLElBQUksQ0FBQ29MLFFBQVEsQ0FBQyxJQUFJLElBQUksQ0FBQ2tPLFFBQVEsRUFBRSxFQUFFO1FBQ2hEO01BQ0Y7TUFFQSxNQUFNOVMsYUFBYSxHQUFHO1FBQ3BCQSxhQUFhLEVBQUUsSUFBSSxDQUFDNEU7T0FDckI7TUFFRCxNQUFNb3NCLFNBQVMsR0FBR3R5QixZQUFZLENBQUN5QyxPQUFPLENBQUMsSUFBSSxDQUFDeUQsUUFBUSxFQUFFZ3FCLFlBQVUsRUFBRTV1QixhQUFhLENBQUM7TUFFaEYsSUFBSWd4QixTQUFTLENBQUN6dkIsZ0JBQWdCLEVBQUU7UUFDOUI7TUFDRjtNQUVBLElBQUksQ0FBQzB2QixhQUFhLEVBQUU7O01BRXBCO01BQ0E7TUFDQTtNQUNBO01BQ0EsSUFBSSxjQUFjLElBQUlyNUIsUUFBUSxDQUFDcUMsZUFBZSxJQUFJLENBQUMsSUFBSSxDQUFDMjJCLE9BQU8sQ0FBQ3YzQixPQUFPLENBQUNzMkIsbUJBQW1CLENBQUMsRUFBRTtRQUM1RixLQUFLLE1BQU1yNkIsT0FBTyxJQUFJLEVBQUUsQ0FBQ3lRLE1BQU0sQ0FBQyxHQUFHbk8sUUFBUSxDQUFDK0MsSUFBSSxDQUFDdUwsUUFBUSxDQUFDLEVBQUU7VUFDMUR4SCxZQUFZLENBQUNpQyxFQUFFLENBQUNyTCxPQUFPLEVBQUUsV0FBVyxFQUFFZ0YsSUFBSSxDQUFDO1FBQzdDO01BQ0Y7TUFFQSxJQUFJLENBQUNzSyxRQUFRLENBQUNzc0IsS0FBSyxFQUFFO01BQ3JCLElBQUksQ0FBQ3RzQixRQUFRLENBQUNoQyxZQUFZLENBQUMsZUFBZSxFQUFFLElBQUksQ0FBQztNQUVqRCxJQUFJLENBQUNpdUIsS0FBSyxDQUFDbDNCLFNBQVMsQ0FBQ21SLEdBQUcsQ0FBQ21rQixpQkFBZSxDQUFDO01BQ3pDLElBQUksQ0FBQ3JxQixRQUFRLENBQUNqTCxTQUFTLENBQUNtUixHQUFHLENBQUNta0IsaUJBQWUsQ0FBQztNQUM1Q3Z3QixZQUFZLENBQUN5QyxPQUFPLENBQUMsSUFBSSxDQUFDeUQsUUFBUSxFQUFFaXFCLGFBQVcsRUFBRTd1QixhQUFhLENBQUM7SUFDakU7SUFFQStTLElBQUlBLENBQUEsRUFBRztNQUNMLElBQUl2WixVQUFVLENBQUMsSUFBSSxDQUFDb0wsUUFBUSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUNrTyxRQUFRLEVBQUUsRUFBRTtRQUNqRDtNQUNGO01BRUEsTUFBTTlTLGFBQWEsR0FBRztRQUNwQkEsYUFBYSxFQUFFLElBQUksQ0FBQzRFO09BQ3JCO01BRUQsSUFBSSxDQUFDdXNCLGFBQWEsQ0FBQ254QixhQUFhLENBQUM7SUFDbkM7SUFFQStFLE9BQU9BLENBQUEsRUFBRztNQUNSLElBQUksSUFBSSxDQUFDNHJCLE9BQU8sRUFBRTtRQUNoQixJQUFJLENBQUNBLE9BQU8sQ0FBQ2xELE9BQU8sRUFBRTtNQUN4QjtNQUVBLEtBQUssQ0FBQzFvQixPQUFPLEVBQUU7SUFDakI7SUFFQSthLE1BQU1BLENBQUEsRUFBRztNQUNQLElBQUksQ0FBQ2dSLFNBQVMsR0FBRyxJQUFJLENBQUNDLGFBQWEsRUFBRTtNQUNyQyxJQUFJLElBQUksQ0FBQ0osT0FBTyxFQUFFO1FBQ2hCLElBQUksQ0FBQ0EsT0FBTyxDQUFDN1EsTUFBTSxFQUFFO01BQ3ZCO0lBQ0Y7O0lBRUE7SUFDQXFSLGFBQWFBLENBQUNueEIsYUFBYSxFQUFFO01BQzNCLE1BQU1veEIsU0FBUyxHQUFHMXlCLFlBQVksQ0FBQ3lDLE9BQU8sQ0FBQyxJQUFJLENBQUN5RCxRQUFRLEVBQUU4cEIsWUFBVSxFQUFFMXVCLGFBQWEsQ0FBQztNQUNoRixJQUFJb3hCLFNBQVMsQ0FBQzd2QixnQkFBZ0IsRUFBRTtRQUM5QjtNQUNGOztNQUVBO01BQ0E7TUFDQSxJQUFJLGNBQWMsSUFBSTNKLFFBQVEsQ0FBQ3FDLGVBQWUsRUFBRTtRQUM5QyxLQUFLLE1BQU0zRSxPQUFPLElBQUksRUFBRSxDQUFDeVEsTUFBTSxDQUFDLEdBQUduTyxRQUFRLENBQUMrQyxJQUFJLENBQUN1TCxRQUFRLENBQUMsRUFBRTtVQUMxRHhILFlBQVksQ0FBQ0MsR0FBRyxDQUFDckosT0FBTyxFQUFFLFdBQVcsRUFBRWdGLElBQUksQ0FBQztRQUM5QztNQUNGO01BRUEsSUFBSSxJQUFJLENBQUNxMkIsT0FBTyxFQUFFO1FBQ2hCLElBQUksQ0FBQ0EsT0FBTyxDQUFDbEQsT0FBTyxFQUFFO01BQ3hCO01BRUEsSUFBSSxDQUFDb0QsS0FBSyxDQUFDbDNCLFNBQVMsQ0FBQ3pELE1BQU0sQ0FBQys0QixpQkFBZSxDQUFDO01BQzVDLElBQUksQ0FBQ3JxQixRQUFRLENBQUNqTCxTQUFTLENBQUN6RCxNQUFNLENBQUMrNEIsaUJBQWUsQ0FBQztNQUMvQyxJQUFJLENBQUNycUIsUUFBUSxDQUFDaEMsWUFBWSxDQUFDLGVBQWUsRUFBRSxPQUFPLENBQUM7TUFDcERGLFdBQVcsQ0FBQ0csbUJBQW1CLENBQUMsSUFBSSxDQUFDZ3VCLEtBQUssRUFBRSxRQUFRLENBQUM7TUFDckRueUIsWUFBWSxDQUFDeUMsT0FBTyxDQUFDLElBQUksQ0FBQ3lELFFBQVEsRUFBRStwQixjQUFZLEVBQUUzdUIsYUFBYSxDQUFDO0lBQ2xFO0lBRUEyRCxVQUFVQSxDQUFDQyxNQUFNLEVBQUU7TUFDakJBLE1BQU0sR0FBRyxLQUFLLENBQUNELFVBQVUsQ0FBQ0MsTUFBTSxDQUFDO01BRWpDLElBQUksT0FBT0EsTUFBTSxDQUFDOFEsU0FBUyxLQUFLLFFBQVEsSUFBSSxDQUFDaGMsV0FBUyxDQUFDa0wsTUFBTSxDQUFDOFEsU0FBUyxDQUFDLElBQ3RFLE9BQU85USxNQUFNLENBQUM4USxTQUFTLENBQUNmLHFCQUFxQixLQUFLLFVBQVUsRUFDNUQ7UUFDQTtRQUNBLE1BQU0sSUFBSW5QLFNBQVMsQ0FBRSxHQUFFeXBCLE1BQUksQ0FBQ3hwQixXQUFXLEVBQUcsZ0dBQStGLENBQUM7TUFDNUk7TUFFQSxPQUFPYixNQUFNO0lBQ2Y7SUFFQXF0QixhQUFhQSxDQUFBLEVBQUc7TUFDZCxJQUFJLE9BQU9JLE1BQU0sS0FBSyxXQUFXLEVBQUU7UUFDakMsTUFBTSxJQUFJN3NCLFNBQVMsQ0FBQywrREFBK0QsQ0FBQztNQUN0RjtNQUVBLElBQUk4c0IsZ0JBQWdCLEdBQUcsSUFBSSxDQUFDMXNCLFFBQVE7TUFFcEMsSUFBSSxJQUFJLENBQUNDLE9BQU8sQ0FBQzZQLFNBQVMsS0FBSyxRQUFRLEVBQUU7UUFDdkM0YyxnQkFBZ0IsR0FBRyxJQUFJLENBQUNWLE9BQU87T0FDaEMsTUFBTSxJQUFJbDRCLFdBQVMsQ0FBQyxJQUFJLENBQUNtTSxPQUFPLENBQUM2UCxTQUFTLENBQUMsRUFBRTtRQUM1QzRjLGdCQUFnQixHQUFHejRCLFVBQVUsQ0FBQyxJQUFJLENBQUNnTSxPQUFPLENBQUM2UCxTQUFTLENBQUM7T0FDdEQsTUFBTSxJQUFJLE9BQU8sSUFBSSxDQUFDN1AsT0FBTyxDQUFDNlAsU0FBUyxLQUFLLFFBQVEsRUFBRTtRQUNyRDRjLGdCQUFnQixHQUFHLElBQUksQ0FBQ3pzQixPQUFPLENBQUM2UCxTQUFTO01BQzNDO01BRUEsTUFBTThiLFlBQVksR0FBRyxJQUFJLENBQUNlLGdCQUFnQixFQUFFO01BQzVDLElBQUksQ0FBQ1osT0FBTyxHQUFHOUQsWUFBbUIsQ0FBQ3lFLGdCQUFnQixFQUFFLElBQUksQ0FBQ1QsS0FBSyxFQUFFTCxZQUFZLENBQUM7SUFDaEY7SUFFQTFkLFFBQVFBLENBQUEsRUFBRztNQUNULE9BQU8sSUFBSSxDQUFDK2QsS0FBSyxDQUFDbDNCLFNBQVMsQ0FBQ0MsUUFBUSxDQUFDcTFCLGlCQUFlLENBQUM7SUFDdkQ7SUFFQXVDLGFBQWFBLENBQUEsRUFBRztNQUNkLE1BQU1DLGNBQWMsR0FBRyxJQUFJLENBQUNiLE9BQU87TUFFbkMsSUFBSWEsY0FBYyxDQUFDOTNCLFNBQVMsQ0FBQ0MsUUFBUSxDQUFDdTFCLGtCQUFrQixDQUFDLEVBQUU7UUFDekQsT0FBT2MsZUFBZTtNQUN4QjtNQUVBLElBQUl3QixjQUFjLENBQUM5M0IsU0FBUyxDQUFDQyxRQUFRLENBQUN3MUIsb0JBQW9CLENBQUMsRUFBRTtRQUMzRCxPQUFPYyxjQUFjO01BQ3ZCO01BRUEsSUFBSXVCLGNBQWMsQ0FBQzkzQixTQUFTLENBQUNDLFFBQVEsQ0FBQ3kxQix3QkFBd0IsQ0FBQyxFQUFFO1FBQy9ELE9BQU9jLG1CQUFtQjtNQUM1QjtNQUVBLElBQUlzQixjQUFjLENBQUM5M0IsU0FBUyxDQUFDQyxRQUFRLENBQUMwMUIsMEJBQTBCLENBQUMsRUFBRTtRQUNqRSxPQUFPYyxzQkFBc0I7TUFDL0I7O01BRUE7TUFDQSxNQUFNc0IsS0FBSyxHQUFHejVCLGdCQUFnQixDQUFDLElBQUksQ0FBQzQ0QixLQUFLLENBQUMsQ0FBQzEzQixnQkFBZ0IsQ0FBQyxlQUFlLENBQUMsQ0FBQ3VNLElBQUksRUFBRSxLQUFLLEtBQUs7TUFFN0YsSUFBSStyQixjQUFjLENBQUM5M0IsU0FBUyxDQUFDQyxRQUFRLENBQUNzMUIsaUJBQWlCLENBQUMsRUFBRTtRQUN4RCxPQUFPd0MsS0FBSyxHQUFHNUIsZ0JBQWdCLEdBQUdELGFBQWE7TUFDakQ7TUFFQSxPQUFPNkIsS0FBSyxHQUFHMUIsbUJBQW1CLEdBQUdELGdCQUFnQjtJQUN2RDtJQUVBZ0IsYUFBYUEsQ0FBQSxFQUFHO01BQ2QsT0FBTyxJQUFJLENBQUNuc0IsUUFBUSxDQUFDdkwsT0FBTyxDQUFDcTJCLGVBQWUsQ0FBQyxLQUFLLElBQUk7SUFDeEQ7SUFFQWlDLFVBQVVBLENBQUEsRUFBRztNQUNYLE1BQU07UUFBRTlVO09BQVEsR0FBRyxJQUFJLENBQUNoWSxPQUFPO01BRS9CLElBQUksT0FBT2dZLE1BQU0sS0FBSyxRQUFRLEVBQUU7UUFDOUIsT0FBT0EsTUFBTSxDQUFDdmtCLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQ3FOLEdBQUcsQ0FBQzNELEtBQUssSUFBSTdKLE1BQU0sQ0FBQzRYLFFBQVEsQ0FBQy9OLEtBQUssRUFBRSxFQUFFLENBQUMsQ0FBQztNQUNuRTtNQUVBLElBQUksT0FBTzZhLE1BQU0sS0FBSyxVQUFVLEVBQUU7UUFDaEMsT0FBTytVLFVBQVUsSUFBSS9VLE1BQU0sQ0FBQytVLFVBQVUsRUFBRSxJQUFJLENBQUNodEIsUUFBUSxDQUFDO01BQ3hEO01BRUEsT0FBT2lZLE1BQU07SUFDZjtJQUVBMFUsZ0JBQWdCQSxDQUFBLEVBQUc7TUFDakIsTUFBTU0scUJBQXFCLEdBQUc7UUFDNUIvYyxTQUFTLEVBQUUsSUFBSSxDQUFDMGMsYUFBYSxFQUFFO1FBQy9CdEcsU0FBUyxFQUFFLENBQUM7VUFDVjN2QixJQUFJLEVBQUUsaUJBQWlCO1VBQ3ZCMGIsT0FBTyxFQUFFO1lBQ1BzTCxRQUFRLEVBQUUsSUFBSSxDQUFDMWQsT0FBTyxDQUFDMGQ7VUFDekI7UUFDRixDQUFDLEVBQ0Q7VUFDRWhuQixJQUFJLEVBQUUsUUFBUTtVQUNkMGIsT0FBTyxFQUFFO1lBQ1A0RixNQUFNLEVBQUUsSUFBSSxDQUFDOFUsVUFBVTtVQUN6QjtTQUNEO09BQ0Y7O01BRUQ7TUFDQSxJQUFJLElBQUksQ0FBQ2IsU0FBUyxJQUFJLElBQUksQ0FBQ2pzQixPQUFPLENBQUMwckIsT0FBTyxLQUFLLFFBQVEsRUFBRTtRQUN2RDd0QixXQUFXLENBQUNDLGdCQUFnQixDQUFDLElBQUksQ0FBQ2t1QixLQUFLLEVBQUUsUUFBUSxFQUFFLFFBQVEsQ0FBQyxDQUFDO1FBQzdEZ0IscUJBQXFCLENBQUMzRyxTQUFTLEdBQUcsQ0FBQztVQUNqQzN2QixJQUFJLEVBQUUsYUFBYTtVQUNuQmtjLE9BQU8sRUFBRTtRQUNYLENBQUMsQ0FBQztNQUNKO01BRUEsT0FBTztRQUNMLEdBQUdvYSxxQkFBcUI7UUFDeEIsR0FBRy8xQixPQUFPLENBQUMsSUFBSSxDQUFDK0ksT0FBTyxDQUFDMnJCLFlBQVksRUFBRSxDQUFDcUIscUJBQXFCLENBQUM7T0FDOUQ7SUFDSDtJQUVBQyxlQUFlQSxDQUFBQyxLQUFBLEVBQWtCO01BQUEsSUFBakI7UUFBRXg4QixHQUFHO1FBQUVvSDtNQUFPLENBQUMsR0FBQW8xQixLQUFBO01BQzdCLE1BQU1sakIsS0FBSyxHQUFHL0ksY0FBYyxDQUFDdkcsSUFBSSxDQUFDcXdCLHNCQUFzQixFQUFFLElBQUksQ0FBQ2lCLEtBQUssQ0FBQyxDQUFDMXRCLE1BQU0sQ0FBQzdOLE9BQU8sSUFBSTBELFNBQVMsQ0FBQzFELE9BQU8sQ0FBQyxDQUFDO01BRTNHLElBQUksQ0FBQ3VaLEtBQUssQ0FBQy9WLE1BQU0sRUFBRTtRQUNqQjtNQUNGOztNQUVBO01BQ0E7TUFDQWdFLG9CQUFvQixDQUFDK1IsS0FBSyxFQUFFbFMsTUFBTSxFQUFFcEgsR0FBRyxLQUFLaTVCLGdCQUFjLEVBQUUsQ0FBQzNmLEtBQUssQ0FBQ25PLFFBQVEsQ0FBQy9ELE1BQU0sQ0FBQyxDQUFDLENBQUN1MEIsS0FBSyxFQUFFO0lBQzlGOztJQUVBO0lBQ0EsT0FBT3YxQixlQUFlQSxDQUFDaUksTUFBTSxFQUFFO01BQzdCLE9BQU8sSUFBSSxDQUFDc0UsSUFBSSxDQUFDLFlBQVk7UUFDM0IsTUFBTUMsSUFBSSxHQUFHdW9CLFFBQVEsQ0FBQ3ByQixtQkFBbUIsQ0FBQyxJQUFJLEVBQUUxQixNQUFNLENBQUM7UUFFdkQsSUFBSSxPQUFPQSxNQUFNLEtBQUssUUFBUSxFQUFFO1VBQzlCO1FBQ0Y7UUFFQSxJQUFJLE9BQU91RSxJQUFJLENBQUN2RSxNQUFNLENBQUMsS0FBSyxXQUFXLEVBQUU7VUFDdkMsTUFBTSxJQUFJWSxTQUFTLENBQUUsb0JBQW1CWixNQUFPLEdBQUUsQ0FBQztRQUNwRDtRQUVBdUUsSUFBSSxDQUFDdkUsTUFBTSxDQUFDLEVBQUU7TUFDaEIsQ0FBQyxDQUFDO0lBQ0o7SUFFQSxPQUFPb3VCLFVBQVVBLENBQUMxekIsS0FBSyxFQUFFO01BQ3ZCLElBQUlBLEtBQUssQ0FBQ3VLLE1BQU0sS0FBSzRsQixrQkFBa0IsSUFBS253QixLQUFLLENBQUNNLElBQUksS0FBSyxPQUFPLElBQUlOLEtBQUssQ0FBQy9JLEdBQUcsS0FBSys0QixTQUFRLEVBQUU7UUFDNUY7TUFDRjtNQUVBLE1BQU0yRCxXQUFXLEdBQUduc0IsY0FBYyxDQUFDdkcsSUFBSSxDQUFDaXdCLDBCQUEwQixDQUFDO01BRW5FLEtBQUssTUFBTTVtQixNQUFNLElBQUlxcEIsV0FBVyxFQUFFO1FBQ2hDLE1BQU1DLE9BQU8sR0FBR3hCLFFBQVEsQ0FBQ3JyQixXQUFXLENBQUN1RCxNQUFNLENBQUM7UUFDNUMsSUFBSSxDQUFDc3BCLE9BQU8sSUFBSUEsT0FBTyxDQUFDcnRCLE9BQU8sQ0FBQ3lyQixTQUFTLEtBQUssS0FBSyxFQUFFO1VBQ25EO1FBQ0Y7UUFFQSxNQUFNNkIsWUFBWSxHQUFHN3pCLEtBQUssQ0FBQzZ6QixZQUFZLEVBQUU7UUFDekMsTUFBTUMsWUFBWSxHQUFHRCxZQUFZLENBQUN6eEIsUUFBUSxDQUFDd3hCLE9BQU8sQ0FBQ3JCLEtBQUssQ0FBQztRQUN6RCxJQUNFc0IsWUFBWSxDQUFDenhCLFFBQVEsQ0FBQ3d4QixPQUFPLENBQUN0dEIsUUFBUSxDQUFDLElBQ3RDc3RCLE9BQU8sQ0FBQ3J0QixPQUFPLENBQUN5ckIsU0FBUyxLQUFLLFFBQVEsSUFBSSxDQUFDOEIsWUFBYSxJQUN4REYsT0FBTyxDQUFDcnRCLE9BQU8sQ0FBQ3lyQixTQUFTLEtBQUssU0FBUyxJQUFJOEIsWUFBYSxFQUN6RDtVQUNBO1FBQ0Y7O1FBRUE7UUFDQSxJQUFJRixPQUFPLENBQUNyQixLQUFLLENBQUNqM0IsUUFBUSxDQUFDMEUsS0FBSyxDQUFDM0IsTUFBTSxDQUFDLEtBQU0yQixLQUFLLENBQUNNLElBQUksS0FBSyxPQUFPLElBQUlOLEtBQUssQ0FBQy9JLEdBQUcsS0FBSys0QixTQUFPLElBQUssb0NBQW9DLENBQUMvcEIsSUFBSSxDQUFDakcsS0FBSyxDQUFDM0IsTUFBTSxDQUFDMkssT0FBTyxDQUFDLENBQUMsRUFBRTtVQUNsSztRQUNGO1FBRUEsTUFBTXRILGFBQWEsR0FBRztVQUFFQSxhQUFhLEVBQUVreUIsT0FBTyxDQUFDdHRCO1NBQVU7UUFFekQsSUFBSXRHLEtBQUssQ0FBQ00sSUFBSSxLQUFLLE9BQU8sRUFBRTtVQUMxQm9CLGFBQWEsQ0FBQ3FILFVBQVUsR0FBRy9JLEtBQUs7UUFDbEM7UUFFQTR6QixPQUFPLENBQUNmLGFBQWEsQ0FBQ254QixhQUFhLENBQUM7TUFDdEM7SUFDRjtJQUVBLE9BQU9xeUIscUJBQXFCQSxDQUFDL3pCLEtBQUssRUFBRTtNQUNsQztNQUNBOztNQUVBLE1BQU1nMEIsT0FBTyxHQUFHLGlCQUFpQixDQUFDL3RCLElBQUksQ0FBQ2pHLEtBQUssQ0FBQzNCLE1BQU0sQ0FBQzJLLE9BQU8sQ0FBQztNQUM1RCxNQUFNaXJCLGFBQWEsR0FBR2owQixLQUFLLENBQUMvSSxHQUFHLEtBQUs4NEIsWUFBVTtNQUM5QyxNQUFNbUUsZUFBZSxHQUFHLENBQUNqRSxjQUFZLEVBQUVDLGdCQUFjLENBQUMsQ0FBQzl0QixRQUFRLENBQUNwQyxLQUFLLENBQUMvSSxHQUFHLENBQUM7TUFFMUUsSUFBSSxDQUFDaTlCLGVBQWUsSUFBSSxDQUFDRCxhQUFhLEVBQUU7UUFDdEM7TUFDRjtNQUVBLElBQUlELE9BQU8sSUFBSSxDQUFDQyxhQUFhLEVBQUU7UUFDN0I7TUFDRjtNQUVBajBCLEtBQUssQ0FBQ3VELGNBQWMsRUFBRTs7TUFFdEI7TUFDQSxNQUFNNHdCLGVBQWUsR0FBRyxJQUFJLENBQUNyc0IsT0FBTyxDQUFDbXBCLHNCQUFvQixDQUFDLEdBQ3hELElBQUksR0FDSHpwQixjQUFjLENBQUNTLElBQUksQ0FBQyxJQUFJLEVBQUVncEIsc0JBQW9CLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFDakR6cEIsY0FBYyxDQUFDWSxJQUFJLENBQUMsSUFBSSxFQUFFNm9CLHNCQUFvQixDQUFDLENBQUMsQ0FBQyxDQUFDLElBQ2xEenBCLGNBQWMsQ0FBQ0csT0FBTyxDQUFDc3BCLHNCQUFvQixFQUFFanhCLEtBQUssQ0FBQ0UsY0FBYyxDQUFDakYsVUFBVSxDQUFFO01BRWxGLE1BQU0vRCxRQUFRLEdBQUdrN0IsUUFBUSxDQUFDcHJCLG1CQUFtQixDQUFDbXRCLGVBQWUsQ0FBQztNQUU5RCxJQUFJRCxlQUFlLEVBQUU7UUFDbkJsMEIsS0FBSyxDQUFDbzBCLGVBQWUsRUFBRTtRQUN2Qmw5QixRQUFRLENBQUN3ZCxJQUFJLEVBQUU7UUFDZnhkLFFBQVEsQ0FBQ3M4QixlQUFlLENBQUN4ekIsS0FBSyxDQUFDO1FBQy9CO01BQ0Y7TUFFQSxJQUFJOUksUUFBUSxDQUFDc2QsUUFBUSxFQUFFLEVBQUU7UUFBRTtRQUN6QnhVLEtBQUssQ0FBQ28wQixlQUFlLEVBQUU7UUFDdkJsOUIsUUFBUSxDQUFDdWQsSUFBSSxFQUFFO1FBQ2YwZixlQUFlLENBQUN2QixLQUFLLEVBQUU7TUFDekI7SUFDRjtFQUNGOztFQUVBOzs7O0VBSUF4eUIsWUFBWSxDQUFDaUMsRUFBRSxDQUFDL0ksUUFBUSxFQUFFbTNCLHNCQUFzQixFQUFFUSxzQkFBb0IsRUFBRW1CLFFBQVEsQ0FBQzJCLHFCQUFxQixDQUFDO0VBQ3ZHM3pCLFlBQVksQ0FBQ2lDLEVBQUUsQ0FBQy9JLFFBQVEsRUFBRW0zQixzQkFBc0IsRUFBRVUsYUFBYSxFQUFFaUIsUUFBUSxDQUFDMkIscUJBQXFCLENBQUM7RUFDaEczekIsWUFBWSxDQUFDaUMsRUFBRSxDQUFDL0ksUUFBUSxFQUFFazNCLHNCQUFvQixFQUFFNEIsUUFBUSxDQUFDc0IsVUFBVSxDQUFDO0VBQ3BFdHpCLFlBQVksQ0FBQ2lDLEVBQUUsQ0FBQy9JLFFBQVEsRUFBRW8zQixvQkFBb0IsRUFBRTBCLFFBQVEsQ0FBQ3NCLFVBQVUsQ0FBQztFQUNwRXR6QixZQUFZLENBQUNpQyxFQUFFLENBQUMvSSxRQUFRLEVBQUVrM0Isc0JBQW9CLEVBQUVTLHNCQUFvQixFQUFFLFVBQVVqeEIsS0FBSyxFQUFFO0lBQ3JGQSxLQUFLLENBQUN1RCxjQUFjLEVBQUU7SUFDdEI2dUIsUUFBUSxDQUFDcHJCLG1CQUFtQixDQUFDLElBQUksQ0FBQyxDQUFDc0QsTUFBTSxFQUFFO0VBQzdDLENBQUMsQ0FBQzs7RUFFRjs7OztFQUlBeE4sa0JBQWtCLENBQUNzMUIsUUFBUSxDQUFDOztFQ3BjNUI7Ozs7Ozs7RUFhQTs7OztFQUlBLE1BQU1pQyxNQUFJLEdBQUcsVUFBVTtFQUN2QixNQUFNQyxpQkFBZSxHQUFHLE1BQU07RUFDOUIsTUFBTUMsaUJBQWUsR0FBRyxNQUFNO0VBQzlCLE1BQU1DLGVBQWUsR0FBSSxnQkFBZUgsTUFBSyxFQUFDO0VBRTlDLE1BQU1JLFNBQU8sR0FBRztJQUNkQyxTQUFTLEVBQUUsZ0JBQWdCO0lBQzNCQyxhQUFhLEVBQUUsSUFBSTtJQUNuQjd0QixVQUFVLEVBQUUsS0FBSztJQUNqQnBNLFNBQVMsRUFBRSxJQUFJO0lBQUU7SUFDakJrNkIsV0FBVyxFQUFFLE1BQU07RUFDckIsQ0FBQztFQUVELE1BQU1DLGFBQVcsR0FBRztJQUNsQkgsU0FBUyxFQUFFLFFBQVE7SUFDbkJDLGFBQWEsRUFBRSxpQkFBaUI7SUFDaEM3dEIsVUFBVSxFQUFFLFNBQVM7SUFDckJwTSxTQUFTLEVBQUUsU0FBUztJQUNwQms2QixXQUFXLEVBQUU7RUFDZixDQUFDOztFQUVEOzs7O0VBSUEsTUFBTUUsUUFBUSxTQUFTN3ZCLE1BQU0sQ0FBQztJQUM1QlUsV0FBV0EsQ0FBQ0wsTUFBTSxFQUFFO01BQ2xCLEtBQUssRUFBRTtNQUNQLElBQUksQ0FBQ2lCLE9BQU8sR0FBRyxJQUFJLENBQUNsQixVQUFVLENBQUNDLE1BQU0sQ0FBQztNQUN0QyxJQUFJLENBQUN5dkIsV0FBVyxHQUFHLEtBQUs7TUFDeEIsSUFBSSxDQUFDenVCLFFBQVEsR0FBRyxJQUFJO0lBQ3RCOztJQUVBO0lBQ0EsV0FBV3BCLE9BQU9BLENBQUEsRUFBRztNQUNuQixPQUFPdXZCLFNBQU87SUFDaEI7SUFFQSxXQUFXdHZCLFdBQVdBLENBQUEsRUFBRztNQUN2QixPQUFPMHZCLGFBQVc7SUFDcEI7SUFFQSxXQUFXMzNCLElBQUlBLENBQUEsRUFBRztNQUNoQixPQUFPbTNCLE1BQUk7SUFDYjs7SUFFQTtJQUNBM2YsSUFBSUEsQ0FBQ2xZLFFBQVEsRUFBRTtNQUNiLElBQUksQ0FBQyxJQUFJLENBQUMrSixPQUFPLENBQUM3TCxTQUFTLEVBQUU7UUFDM0I4QyxPQUFPLENBQUNoQixRQUFRLENBQUM7UUFDakI7TUFDRjtNQUVBLElBQUksQ0FBQ3c0QixPQUFPLEVBQUU7TUFFZCxNQUFNaCtCLE9BQU8sR0FBRyxJQUFJLENBQUNpK0IsV0FBVyxFQUFFO01BQ2xDLElBQUksSUFBSSxDQUFDMXVCLE9BQU8sQ0FBQ08sVUFBVSxFQUFFO1FBQzNCN0ssTUFBTSxDQUFDakYsT0FBTyxDQUFDO01BQ2pCO01BRUFBLE9BQU8sQ0FBQ3FFLFNBQVMsQ0FBQ21SLEdBQUcsQ0FBQytuQixpQkFBZSxDQUFDO01BRXRDLElBQUksQ0FBQ1csaUJBQWlCLENBQUMsTUFBTTtRQUMzQjEzQixPQUFPLENBQUNoQixRQUFRLENBQUM7TUFDbkIsQ0FBQyxDQUFDO0lBQ0o7SUFFQWlZLElBQUlBLENBQUNqWSxRQUFRLEVBQUU7TUFDYixJQUFJLENBQUMsSUFBSSxDQUFDK0osT0FBTyxDQUFDN0wsU0FBUyxFQUFFO1FBQzNCOEMsT0FBTyxDQUFDaEIsUUFBUSxDQUFDO1FBQ2pCO01BQ0Y7TUFFQSxJQUFJLENBQUN5NEIsV0FBVyxFQUFFLENBQUM1NUIsU0FBUyxDQUFDekQsTUFBTSxDQUFDMjhCLGlCQUFlLENBQUM7TUFFcEQsSUFBSSxDQUFDVyxpQkFBaUIsQ0FBQyxNQUFNO1FBQzNCLElBQUksQ0FBQ3p1QixPQUFPLEVBQUU7UUFDZGpKLE9BQU8sQ0FBQ2hCLFFBQVEsQ0FBQztNQUNuQixDQUFDLENBQUM7SUFDSjtJQUVBaUssT0FBT0EsQ0FBQSxFQUFHO01BQ1IsSUFBSSxDQUFDLElBQUksQ0FBQ3N1QixXQUFXLEVBQUU7UUFDckI7TUFDRjtNQUVBMzBCLFlBQVksQ0FBQ0MsR0FBRyxDQUFDLElBQUksQ0FBQ2lHLFFBQVEsRUFBRWt1QixlQUFlLENBQUM7TUFFaEQsSUFBSSxDQUFDbHVCLFFBQVEsQ0FBQzFPLE1BQU0sRUFBRTtNQUN0QixJQUFJLENBQUNtOUIsV0FBVyxHQUFHLEtBQUs7SUFDMUI7O0lBRUE7SUFDQUUsV0FBV0EsQ0FBQSxFQUFHO01BQ1osSUFBSSxDQUFDLElBQUksQ0FBQzN1QixRQUFRLEVBQUU7UUFDbEIsTUFBTTZ1QixRQUFRLEdBQUc3N0IsUUFBUSxDQUFDODdCLGFBQWEsQ0FBQyxLQUFLLENBQUM7UUFDOUNELFFBQVEsQ0FBQ1QsU0FBUyxHQUFHLElBQUksQ0FBQ251QixPQUFPLENBQUNtdUIsU0FBUztRQUMzQyxJQUFJLElBQUksQ0FBQ251QixPQUFPLENBQUNPLFVBQVUsRUFBRTtVQUMzQnF1QixRQUFRLENBQUM5NUIsU0FBUyxDQUFDbVIsR0FBRyxDQUFDOG5CLGlCQUFlLENBQUM7UUFDekM7UUFFQSxJQUFJLENBQUNodUIsUUFBUSxHQUFHNnVCLFFBQVE7TUFDMUI7TUFFQSxPQUFPLElBQUksQ0FBQzd1QixRQUFRO0lBQ3RCO0lBRUFkLGlCQUFpQkEsQ0FBQ0YsTUFBTSxFQUFFO01BQ3hCO01BQ0FBLE1BQU0sQ0FBQ3N2QixXQUFXLEdBQUdyNkIsVUFBVSxDQUFDK0ssTUFBTSxDQUFDc3ZCLFdBQVcsQ0FBQztNQUNuRCxPQUFPdHZCLE1BQU07SUFDZjtJQUVBMHZCLE9BQU9BLENBQUEsRUFBRztNQUNSLElBQUksSUFBSSxDQUFDRCxXQUFXLEVBQUU7UUFDcEI7TUFDRjtNQUVBLE1BQU0vOUIsT0FBTyxHQUFHLElBQUksQ0FBQ2krQixXQUFXLEVBQUU7TUFDbEMsSUFBSSxDQUFDMXVCLE9BQU8sQ0FBQ3F1QixXQUFXLENBQUNTLE1BQU0sQ0FBQ3IrQixPQUFPLENBQUM7TUFFeENvSixZQUFZLENBQUNpQyxFQUFFLENBQUNyTCxPQUFPLEVBQUV3OUIsZUFBZSxFQUFFLE1BQU07UUFDOUNoM0IsT0FBTyxDQUFDLElBQUksQ0FBQytJLE9BQU8sQ0FBQ291QixhQUFhLENBQUM7TUFDckMsQ0FBQyxDQUFDO01BRUYsSUFBSSxDQUFDSSxXQUFXLEdBQUcsSUFBSTtJQUN6QjtJQUVBRyxpQkFBaUJBLENBQUMxNEIsUUFBUSxFQUFFO01BQzFCcUIsc0JBQXNCLENBQUNyQixRQUFRLEVBQUUsSUFBSSxDQUFDeTRCLFdBQVcsRUFBRSxFQUFFLElBQUksQ0FBQzF1QixPQUFPLENBQUNPLFVBQVUsQ0FBQztJQUMvRTtFQUNGOztFQ3BKQTs7Ozs7OztFQVdBOzs7O0VBSUEsTUFBTXd1QixNQUFJLEdBQUcsV0FBVztFQUN4QixNQUFNQyxVQUFRLEdBQUcsY0FBYztFQUMvQixNQUFNQyxXQUFTLEdBQUksSUFBR0QsVUFBUyxFQUFDO0VBQ2hDLE1BQU1FLGVBQWEsR0FBSSxVQUFTRCxXQUFVLEVBQUM7RUFDM0MsTUFBTUUsaUJBQWlCLEdBQUksY0FBYUYsV0FBVSxFQUFDO0VBRW5ELE1BQU1HLE9BQU8sR0FBRyxLQUFLO0VBQ3JCLE1BQU1DLGVBQWUsR0FBRyxTQUFTO0VBQ2pDLE1BQU1DLGdCQUFnQixHQUFHLFVBQVU7RUFFbkMsTUFBTUMsU0FBTyxHQUFHO0lBQ2RDLFNBQVMsRUFBRSxJQUFJO0lBQ2ZDLFdBQVcsRUFBRSxJQUFJO0VBQ25CLENBQUM7RUFFRCxNQUFNQyxhQUFXLEdBQUc7SUFDbEJGLFNBQVMsRUFBRSxTQUFTO0lBQ3BCQyxXQUFXLEVBQUU7RUFDZixDQUFDOztFQUVEOzs7O0VBSUEsTUFBTUUsU0FBUyxTQUFTanhCLE1BQU0sQ0FBQztJQUM3QlUsV0FBV0EsQ0FBQ0wsTUFBTSxFQUFFO01BQ2xCLEtBQUssRUFBRTtNQUNQLElBQUksQ0FBQ2lCLE9BQU8sR0FBRyxJQUFJLENBQUNsQixVQUFVLENBQUNDLE1BQU0sQ0FBQztNQUN0QyxJQUFJLENBQUM2d0IsU0FBUyxHQUFHLEtBQUs7TUFDdEIsSUFBSSxDQUFDQyxvQkFBb0IsR0FBRyxJQUFJO0lBQ2xDOztJQUVBO0lBQ0EsV0FBV2x4QixPQUFPQSxDQUFBLEVBQUc7TUFDbkIsT0FBTzR3QixTQUFPO0lBQ2hCO0lBRUEsV0FBVzN3QixXQUFXQSxDQUFBLEVBQUc7TUFDdkIsT0FBTzh3QixhQUFXO0lBQ3BCO0lBRUEsV0FBVy80QixJQUFJQSxDQUFBLEVBQUc7TUFDaEIsT0FBT280QixNQUFJO0lBQ2I7O0lBRUE7SUFDQWUsUUFBUUEsQ0FBQSxFQUFHO01BQ1QsSUFBSSxJQUFJLENBQUNGLFNBQVMsRUFBRTtRQUNsQjtNQUNGO01BRUEsSUFBSSxJQUFJLENBQUM1dkIsT0FBTyxDQUFDd3ZCLFNBQVMsRUFBRTtRQUMxQixJQUFJLENBQUN4dkIsT0FBTyxDQUFDeXZCLFdBQVcsQ0FBQ3BELEtBQUssRUFBRTtNQUNsQztNQUVBeHlCLFlBQVksQ0FBQ0MsR0FBRyxDQUFDL0csUUFBUSxFQUFFazhCLFdBQVMsQ0FBQyxDQUFDO01BQ3RDcDFCLFlBQVksQ0FBQ2lDLEVBQUUsQ0FBQy9JLFFBQVEsRUFBRW04QixlQUFhLEVBQUV6MUIsS0FBSyxJQUFJLElBQUksQ0FBQ3MyQixjQUFjLENBQUN0MkIsS0FBSyxDQUFDLENBQUM7TUFDN0VJLFlBQVksQ0FBQ2lDLEVBQUUsQ0FBQy9JLFFBQVEsRUFBRW84QixpQkFBaUIsRUFBRTExQixLQUFLLElBQUksSUFBSSxDQUFDdTJCLGNBQWMsQ0FBQ3YyQixLQUFLLENBQUMsQ0FBQztNQUVqRixJQUFJLENBQUNtMkIsU0FBUyxHQUFHLElBQUk7SUFDdkI7SUFFQUssVUFBVUEsQ0FBQSxFQUFHO01BQ1gsSUFBSSxDQUFDLElBQUksQ0FBQ0wsU0FBUyxFQUFFO1FBQ25CO01BQ0Y7TUFFQSxJQUFJLENBQUNBLFNBQVMsR0FBRyxLQUFLO01BQ3RCLzFCLFlBQVksQ0FBQ0MsR0FBRyxDQUFDL0csUUFBUSxFQUFFazhCLFdBQVMsQ0FBQztJQUN2Qzs7SUFFQTtJQUNBYyxjQUFjQSxDQUFDdDJCLEtBQUssRUFBRTtNQUNwQixNQUFNO1FBQUVnMkI7T0FBYSxHQUFHLElBQUksQ0FBQ3p2QixPQUFPO01BRXBDLElBQUl2RyxLQUFLLENBQUMzQixNQUFNLEtBQUsvRSxRQUFRLElBQUkwRyxLQUFLLENBQUMzQixNQUFNLEtBQUsyM0IsV0FBVyxJQUFJQSxXQUFXLENBQUMxNkIsUUFBUSxDQUFDMEUsS0FBSyxDQUFDM0IsTUFBTSxDQUFDLEVBQUU7UUFDbkc7TUFDRjtNQUVBLE1BQU02WixRQUFRLEdBQUcxUSxjQUFjLENBQUNjLGlCQUFpQixDQUFDMHRCLFdBQVcsQ0FBQztNQUU5RCxJQUFJOWQsUUFBUSxDQUFDMWQsTUFBTSxLQUFLLENBQUMsRUFBRTtRQUN6Qnc3QixXQUFXLENBQUNwRCxLQUFLLEVBQUU7TUFDckIsQ0FBQyxNQUFNLElBQUksSUFBSSxDQUFDd0Qsb0JBQW9CLEtBQUtQLGdCQUFnQixFQUFFO1FBQ3pEM2QsUUFBUSxDQUFDQSxRQUFRLENBQUMxZCxNQUFNLEdBQUcsQ0FBQyxDQUFDLENBQUNvNEIsS0FBSyxFQUFFO01BQ3ZDLENBQUMsTUFBTTtRQUNMMWEsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDMGEsS0FBSyxFQUFFO01BQ3JCO0lBQ0Y7SUFFQTJELGNBQWNBLENBQUN2MkIsS0FBSyxFQUFFO01BQ3BCLElBQUlBLEtBQUssQ0FBQy9JLEdBQUcsS0FBSzArQixPQUFPLEVBQUU7UUFDekI7TUFDRjtNQUVBLElBQUksQ0FBQ1Msb0JBQW9CLEdBQUdwMkIsS0FBSyxDQUFDeTJCLFFBQVEsR0FBR1osZ0JBQWdCLEdBQUdELGVBQWU7SUFDakY7RUFDRjs7RUNoSEE7Ozs7Ozs7RUFXQTs7OztFQUlBLE1BQU1jLHNCQUFzQixHQUFHLG1EQUFtRDtFQUNsRixNQUFNQyx1QkFBdUIsR0FBRyxhQUFhO0VBQzdDLE1BQU1DLGdCQUFnQixHQUFHLGVBQWU7RUFDeEMsTUFBTUMsZUFBZSxHQUFHLGNBQWM7O0VBRXRDOzs7O0VBSUEsTUFBTUMsZUFBZSxDQUFDO0lBQ3BCbnhCLFdBQVdBLENBQUEsRUFBRztNQUNaLElBQUksQ0FBQ1csUUFBUSxHQUFHaE4sUUFBUSxDQUFDK0MsSUFBSTtJQUMvQjs7SUFFQTtJQUNBMDZCLFFBQVFBLENBQUEsRUFBRztNQUNUO01BQ0EsTUFBTUMsYUFBYSxHQUFHMTlCLFFBQVEsQ0FBQ3FDLGVBQWUsQ0FBQ3lpQixXQUFXO01BQzFELE9BQU9qbEIsSUFBSSxDQUFDbVQsR0FBRyxDQUFDblUsTUFBTSxDQUFDOCtCLFVBQVUsR0FBR0QsYUFBYSxDQUFDO0lBQ3BEO0lBRUF2aUIsSUFBSUEsQ0FBQSxFQUFHO01BQ0wsTUFBTStGLEtBQUssR0FBRyxJQUFJLENBQUN1YyxRQUFRLEVBQUU7TUFDN0IsSUFBSSxDQUFDRyxnQkFBZ0IsRUFBRTtNQUN2QjtNQUNBLElBQUksQ0FBQ0MscUJBQXFCLENBQUMsSUFBSSxDQUFDN3dCLFFBQVEsRUFBRXN3QixnQkFBZ0IsRUFBRVEsZUFBZSxJQUFJQSxlQUFlLEdBQUc1YyxLQUFLLENBQUM7TUFDdkc7TUFDQSxJQUFJLENBQUMyYyxxQkFBcUIsQ0FBQ1Qsc0JBQXNCLEVBQUVFLGdCQUFnQixFQUFFUSxlQUFlLElBQUlBLGVBQWUsR0FBRzVjLEtBQUssQ0FBQztNQUNoSCxJQUFJLENBQUMyYyxxQkFBcUIsQ0FBQ1IsdUJBQXVCLEVBQUVFLGVBQWUsRUFBRU8sZUFBZSxJQUFJQSxlQUFlLEdBQUc1YyxLQUFLLENBQUM7SUFDbEg7SUFFQWdPLEtBQUtBLENBQUEsRUFBRztNQUNOLElBQUksQ0FBQzZPLHVCQUF1QixDQUFDLElBQUksQ0FBQy93QixRQUFRLEVBQUUsVUFBVSxDQUFDO01BQ3ZELElBQUksQ0FBQyt3Qix1QkFBdUIsQ0FBQyxJQUFJLENBQUMvd0IsUUFBUSxFQUFFc3dCLGdCQUFnQixDQUFDO01BQzdELElBQUksQ0FBQ1MsdUJBQXVCLENBQUNYLHNCQUFzQixFQUFFRSxnQkFBZ0IsQ0FBQztNQUN0RSxJQUFJLENBQUNTLHVCQUF1QixDQUFDVix1QkFBdUIsRUFBRUUsZUFBZSxDQUFDO0lBQ3hFO0lBRUFTLGFBQWFBLENBQUEsRUFBRztNQUNkLE9BQU8sSUFBSSxDQUFDUCxRQUFRLEVBQUUsR0FBRyxDQUFDO0lBQzVCOztJQUVBO0lBQ0FHLGdCQUFnQkEsQ0FBQSxFQUFHO01BQ2pCLElBQUksQ0FBQ0sscUJBQXFCLENBQUMsSUFBSSxDQUFDanhCLFFBQVEsRUFBRSxVQUFVLENBQUM7TUFDckQsSUFBSSxDQUFDQSxRQUFRLENBQUMyTyxLQUFLLENBQUM4TixRQUFRLEdBQUcsUUFBUTtJQUN6QztJQUVBb1UscUJBQXFCQSxDQUFDai9CLFFBQVEsRUFBRXMvQixhQUFhLEVBQUVoN0IsUUFBUSxFQUFFO01BQ3ZELE1BQU1pN0IsY0FBYyxHQUFHLElBQUksQ0FBQ1YsUUFBUSxFQUFFO01BQ3RDLE1BQU1XLG9CQUFvQixHQUFHMWdDLE9BQU8sSUFBSTtRQUN0QyxJQUFJQSxPQUFPLEtBQUssSUFBSSxDQUFDc1AsUUFBUSxJQUFJbk8sTUFBTSxDQUFDOCtCLFVBQVUsR0FBR2pnQyxPQUFPLENBQUNvbkIsV0FBVyxHQUFHcVosY0FBYyxFQUFFO1VBQ3pGO1FBQ0Y7UUFFQSxJQUFJLENBQUNGLHFCQUFxQixDQUFDdmdDLE9BQU8sRUFBRXdnQyxhQUFhLENBQUM7UUFDbEQsTUFBTUosZUFBZSxHQUFHai9CLE1BQU0sQ0FBQ3dCLGdCQUFnQixDQUFDM0MsT0FBTyxDQUFDLENBQUM2RCxnQkFBZ0IsQ0FBQzI4QixhQUFhLENBQUM7UUFDeEZ4Z0MsT0FBTyxDQUFDaWUsS0FBSyxDQUFDMGlCLFdBQVcsQ0FBQ0gsYUFBYSxFQUFHLEdBQUVoN0IsUUFBUSxDQUFDM0MsTUFBTSxDQUFDQyxVQUFVLENBQUNzOUIsZUFBZSxDQUFDLENBQUUsSUFBRyxDQUFDO09BQzlGO01BRUQsSUFBSSxDQUFDUSwwQkFBMEIsQ0FBQzEvQixRQUFRLEVBQUV3L0Isb0JBQW9CLENBQUM7SUFDakU7SUFFQUgscUJBQXFCQSxDQUFDdmdDLE9BQU8sRUFBRXdnQyxhQUFhLEVBQUU7TUFDNUMsTUFBTUssV0FBVyxHQUFHN2dDLE9BQU8sQ0FBQ2llLEtBQUssQ0FBQ3BhLGdCQUFnQixDQUFDMjhCLGFBQWEsQ0FBQztNQUNqRSxJQUFJSyxXQUFXLEVBQUU7UUFDZnp6QixXQUFXLENBQUNDLGdCQUFnQixDQUFDck4sT0FBTyxFQUFFd2dDLGFBQWEsRUFBRUssV0FBVyxDQUFDO01BQ25FO0lBQ0Y7SUFFQVIsdUJBQXVCQSxDQUFDbi9CLFFBQVEsRUFBRXMvQixhQUFhLEVBQUU7TUFDL0MsTUFBTUUsb0JBQW9CLEdBQUcxZ0MsT0FBTyxJQUFJO1FBQ3RDLE1BQU0wTSxLQUFLLEdBQUdVLFdBQVcsQ0FBQ1ksZ0JBQWdCLENBQUNoTyxPQUFPLEVBQUV3Z0MsYUFBYSxDQUFDO1FBQ2xFO1FBQ0EsSUFBSTl6QixLQUFLLEtBQUssSUFBSSxFQUFFO1VBQ2xCMU0sT0FBTyxDQUFDaWUsS0FBSyxDQUFDNmlCLGNBQWMsQ0FBQ04sYUFBYSxDQUFDO1VBQzNDO1FBQ0Y7UUFFQXB6QixXQUFXLENBQUNHLG1CQUFtQixDQUFDdk4sT0FBTyxFQUFFd2dDLGFBQWEsQ0FBQztRQUN2RHhnQyxPQUFPLENBQUNpZSxLQUFLLENBQUMwaUIsV0FBVyxDQUFDSCxhQUFhLEVBQUU5ekIsS0FBSyxDQUFDO09BQ2hEO01BRUQsSUFBSSxDQUFDazBCLDBCQUEwQixDQUFDMS9CLFFBQVEsRUFBRXcvQixvQkFBb0IsQ0FBQztJQUNqRTtJQUVBRSwwQkFBMEJBLENBQUMxL0IsUUFBUSxFQUFFNi9CLFFBQVEsRUFBRTtNQUM3QyxJQUFJMzlCLFdBQVMsQ0FBQ2xDLFFBQVEsQ0FBQyxFQUFFO1FBQ3ZCNi9CLFFBQVEsQ0FBQzcvQixRQUFRLENBQUM7UUFDbEI7TUFDRjtNQUVBLEtBQUssTUFBTW9QLEdBQUcsSUFBSUUsY0FBYyxDQUFDdkcsSUFBSSxDQUFDL0ksUUFBUSxFQUFFLElBQUksQ0FBQ29PLFFBQVEsQ0FBQyxFQUFFO1FBQzlEeXhCLFFBQVEsQ0FBQ3p3QixHQUFHLENBQUM7TUFDZjtJQUNGO0VBQ0Y7O0VDL0dBOzs7Ozs7O0VBa0JBOzs7O0VBSUEsTUFBTTB3QixNQUFJLEdBQUcsT0FBTztFQUNwQixNQUFNQyxVQUFRLEdBQUcsVUFBVTtFQUMzQixNQUFNQyxXQUFTLEdBQUksSUFBR0QsVUFBUyxFQUFDO0VBQ2hDLE1BQU1FLGNBQVksR0FBRyxXQUFXO0VBQ2hDLE1BQU1DLFlBQVUsR0FBRyxRQUFRO0VBRTNCLE1BQU1DLFlBQVUsR0FBSSxPQUFNSCxXQUFVLEVBQUM7RUFDckMsTUFBTUksc0JBQW9CLEdBQUksZ0JBQWVKLFdBQVUsRUFBQztFQUN4RCxNQUFNSyxjQUFZLEdBQUksU0FBUUwsV0FBVSxFQUFDO0VBQ3pDLE1BQU1NLFlBQVUsR0FBSSxPQUFNTixXQUFVLEVBQUM7RUFDckMsTUFBTU8sYUFBVyxHQUFJLFFBQU9QLFdBQVUsRUFBQztFQUN2QyxNQUFNUSxjQUFZLEdBQUksU0FBUVIsV0FBVSxFQUFDO0VBQ3pDLE1BQU1TLG1CQUFtQixHQUFJLGdCQUFlVCxXQUFVLEVBQUM7RUFDdkQsTUFBTVUsdUJBQXVCLEdBQUksb0JBQW1CVixXQUFVLEVBQUM7RUFDL0QsTUFBTVcsdUJBQXFCLEdBQUksa0JBQWlCWCxXQUFVLEVBQUM7RUFDM0QsTUFBTVksc0JBQW9CLEdBQUksUUFBT1osV0FBVSxHQUFFQyxjQUFhLEVBQUM7RUFFL0QsTUFBTVksZUFBZSxHQUFHLFlBQVk7RUFDcEMsTUFBTUMsaUJBQWUsR0FBRyxNQUFNO0VBQzlCLE1BQU1DLGlCQUFlLEdBQUcsTUFBTTtFQUM5QixNQUFNQyxpQkFBaUIsR0FBRyxjQUFjO0VBRXhDLE1BQU1DLGVBQWEsR0FBRyxhQUFhO0VBQ25DLE1BQU1DLGVBQWUsR0FBRyxlQUFlO0VBQ3ZDLE1BQU1DLG1CQUFtQixHQUFHLGFBQWE7RUFDekMsTUFBTUMsc0JBQW9CLEdBQUcsMEJBQTBCO0VBRXZELE1BQU1DLFNBQU8sR0FBRztJQUNkcEUsUUFBUSxFQUFFLElBQUk7SUFDZHZDLEtBQUssRUFBRSxJQUFJO0lBQ1g1akIsUUFBUSxFQUFFO0VBQ1osQ0FBQztFQUVELE1BQU13cUIsYUFBVyxHQUFHO0lBQ2xCckUsUUFBUSxFQUFFLGtCQUFrQjtJQUM1QnZDLEtBQUssRUFBRSxTQUFTO0lBQ2hCNWpCLFFBQVEsRUFBRTtFQUNaLENBQUM7O0VBRUQ7Ozs7RUFJQSxNQUFNeXFCLEtBQUssU0FBU3B6QixhQUFhLENBQUM7SUFDaENWLFdBQVdBLENBQUMzTyxPQUFPLEVBQUVzTyxNQUFNLEVBQUU7TUFDM0IsS0FBSyxDQUFDdE8sT0FBTyxFQUFFc08sTUFBTSxDQUFDO01BRXRCLElBQUksQ0FBQ28wQixPQUFPLEdBQUdseUIsY0FBYyxDQUFDRyxPQUFPLENBQUN5eEIsZUFBZSxFQUFFLElBQUksQ0FBQzl5QixRQUFRLENBQUM7TUFDckUsSUFBSSxDQUFDcXpCLFNBQVMsR0FBRyxJQUFJLENBQUNDLG1CQUFtQixFQUFFO01BQzNDLElBQUksQ0FBQ0MsVUFBVSxHQUFHLElBQUksQ0FBQ0Msb0JBQW9CLEVBQUU7TUFDN0MsSUFBSSxDQUFDdGxCLFFBQVEsR0FBRyxLQUFLO01BQ3JCLElBQUksQ0FBQ1IsZ0JBQWdCLEdBQUcsS0FBSztNQUM3QixJQUFJLENBQUMrbEIsVUFBVSxHQUFHLElBQUlqRCxlQUFlLEVBQUU7TUFFdkMsSUFBSSxDQUFDam5CLGtCQUFrQixFQUFFO0lBQzNCOztJQUVBO0lBQ0EsV0FBVzNLLE9BQU9BLENBQUEsRUFBRztNQUNuQixPQUFPcTBCLFNBQU87SUFDaEI7SUFFQSxXQUFXcDBCLFdBQVdBLENBQUEsRUFBRztNQUN2QixPQUFPcTBCLGFBQVc7SUFDcEI7SUFFQSxXQUFXdDhCLElBQUlBLENBQUEsRUFBRztNQUNoQixPQUFPODZCLE1BQUk7SUFDYjs7SUFFQTtJQUNBMXRCLE1BQU1BLENBQUM1SSxhQUFhLEVBQUU7TUFDcEIsT0FBTyxJQUFJLENBQUM4UyxRQUFRLEdBQUcsSUFBSSxDQUFDQyxJQUFJLEVBQUUsR0FBRyxJQUFJLENBQUNDLElBQUksQ0FBQ2hULGFBQWEsQ0FBQztJQUMvRDtJQUVBZ1QsSUFBSUEsQ0FBQ2hULGFBQWEsRUFBRTtNQUNsQixJQUFJLElBQUksQ0FBQzhTLFFBQVEsSUFBSSxJQUFJLENBQUNSLGdCQUFnQixFQUFFO1FBQzFDO01BQ0Y7TUFFQSxNQUFNMGUsU0FBUyxHQUFHdHlCLFlBQVksQ0FBQ3lDLE9BQU8sQ0FBQyxJQUFJLENBQUN5RCxRQUFRLEVBQUVreUIsWUFBVSxFQUFFO1FBQ2hFOTJCO01BQ0YsQ0FBQyxDQUFDO01BRUYsSUFBSWd4QixTQUFTLENBQUN6dkIsZ0JBQWdCLEVBQUU7UUFDOUI7TUFDRjtNQUVBLElBQUksQ0FBQ3VSLFFBQVEsR0FBRyxJQUFJO01BQ3BCLElBQUksQ0FBQ1IsZ0JBQWdCLEdBQUcsSUFBSTtNQUU1QixJQUFJLENBQUMrbEIsVUFBVSxDQUFDdGxCLElBQUksRUFBRTtNQUV0Qm5iLFFBQVEsQ0FBQytDLElBQUksQ0FBQ2hCLFNBQVMsQ0FBQ21SLEdBQUcsQ0FBQ3VzQixlQUFlLENBQUM7TUFFNUMsSUFBSSxDQUFDaUIsYUFBYSxFQUFFO01BRXBCLElBQUksQ0FBQ0wsU0FBUyxDQUFDamxCLElBQUksQ0FBQyxNQUFNLElBQUksQ0FBQ3VsQixZQUFZLENBQUN2NEIsYUFBYSxDQUFDLENBQUM7SUFDN0Q7SUFFQStTLElBQUlBLENBQUEsRUFBRztNQUNMLElBQUksQ0FBQyxJQUFJLENBQUNELFFBQVEsSUFBSSxJQUFJLENBQUNSLGdCQUFnQixFQUFFO1FBQzNDO01BQ0Y7TUFFQSxNQUFNOGUsU0FBUyxHQUFHMXlCLFlBQVksQ0FBQ3lDLE9BQU8sQ0FBQyxJQUFJLENBQUN5RCxRQUFRLEVBQUUreEIsWUFBVSxDQUFDO01BRWpFLElBQUl2RixTQUFTLENBQUM3dkIsZ0JBQWdCLEVBQUU7UUFDOUI7TUFDRjtNQUVBLElBQUksQ0FBQ3VSLFFBQVEsR0FBRyxLQUFLO01BQ3JCLElBQUksQ0FBQ1IsZ0JBQWdCLEdBQUcsSUFBSTtNQUM1QixJQUFJLENBQUM2bEIsVUFBVSxDQUFDckQsVUFBVSxFQUFFO01BRTVCLElBQUksQ0FBQ2x3QixRQUFRLENBQUNqTCxTQUFTLENBQUN6RCxNQUFNLENBQUNxaEMsaUJBQWUsQ0FBQztNQUUvQyxJQUFJLENBQUNweUIsY0FBYyxDQUFDLE1BQU0sSUFBSSxDQUFDcXpCLFVBQVUsRUFBRSxFQUFFLElBQUksQ0FBQzV6QixRQUFRLEVBQUUsSUFBSSxDQUFDOEwsV0FBVyxFQUFFLENBQUM7SUFDakY7SUFFQTNMLE9BQU9BLENBQUEsRUFBRztNQUNSckcsWUFBWSxDQUFDQyxHQUFHLENBQUNsSSxNQUFNLEVBQUUrL0IsV0FBUyxDQUFDO01BQ25DOTNCLFlBQVksQ0FBQ0MsR0FBRyxDQUFDLElBQUksQ0FBQ3E1QixPQUFPLEVBQUV4QixXQUFTLENBQUM7TUFFekMsSUFBSSxDQUFDeUIsU0FBUyxDQUFDbHpCLE9BQU8sRUFBRTtNQUN4QixJQUFJLENBQUNvekIsVUFBVSxDQUFDckQsVUFBVSxFQUFFO01BRTVCLEtBQUssQ0FBQy92QixPQUFPLEVBQUU7SUFDakI7SUFFQTB6QixZQUFZQSxDQUFBLEVBQUc7TUFDYixJQUFJLENBQUNILGFBQWEsRUFBRTtJQUN0Qjs7SUFFQTtJQUNBSixtQkFBbUJBLENBQUEsRUFBRztNQUNwQixPQUFPLElBQUk5RSxRQUFRLENBQUM7UUFDbEJwNkIsU0FBUyxFQUFFb0gsT0FBTyxDQUFDLElBQUksQ0FBQ3lFLE9BQU8sQ0FBQzR1QixRQUFRLENBQUM7UUFBRTtRQUMzQ3J1QixVQUFVLEVBQUUsSUFBSSxDQUFDc0wsV0FBVztNQUM5QixDQUFDLENBQUM7SUFDSjtJQUVBMG5CLG9CQUFvQkEsQ0FBQSxFQUFHO01BQ3JCLE9BQU8sSUFBSTVELFNBQVMsQ0FBQztRQUNuQkYsV0FBVyxFQUFFLElBQUksQ0FBQzF2QjtNQUNwQixDQUFDLENBQUM7SUFDSjtJQUVBMnpCLFlBQVlBLENBQUN2NEIsYUFBYSxFQUFFO01BQzFCO01BQ0EsSUFBSSxDQUFDcEksUUFBUSxDQUFDK0MsSUFBSSxDQUFDZixRQUFRLENBQUMsSUFBSSxDQUFDZ0wsUUFBUSxDQUFDLEVBQUU7UUFDMUNoTixRQUFRLENBQUMrQyxJQUFJLENBQUNnNUIsTUFBTSxDQUFDLElBQUksQ0FBQy91QixRQUFRLENBQUM7TUFDckM7TUFFQSxJQUFJLENBQUNBLFFBQVEsQ0FBQzJPLEtBQUssQ0FBQ2dkLE9BQU8sR0FBRyxPQUFPO01BQ3JDLElBQUksQ0FBQzNyQixRQUFRLENBQUM5QixlQUFlLENBQUMsYUFBYSxDQUFDO01BQzVDLElBQUksQ0FBQzhCLFFBQVEsQ0FBQ2hDLFlBQVksQ0FBQyxZQUFZLEVBQUUsSUFBSSxDQUFDO01BQzlDLElBQUksQ0FBQ2dDLFFBQVEsQ0FBQ2hDLFlBQVksQ0FBQyxNQUFNLEVBQUUsUUFBUSxDQUFDO01BQzVDLElBQUksQ0FBQ2dDLFFBQVEsQ0FBQzRiLFNBQVMsR0FBRyxDQUFDO01BRTNCLE1BQU1rWSxTQUFTLEdBQUc1eUIsY0FBYyxDQUFDRyxPQUFPLENBQUMweEIsbUJBQW1CLEVBQUUsSUFBSSxDQUFDSyxPQUFPLENBQUM7TUFDM0UsSUFBSVUsU0FBUyxFQUFFO1FBQ2JBLFNBQVMsQ0FBQ2xZLFNBQVMsR0FBRyxDQUFDO01BQ3pCO01BRUFqbUIsTUFBTSxDQUFDLElBQUksQ0FBQ3FLLFFBQVEsQ0FBQztNQUVyQixJQUFJLENBQUNBLFFBQVEsQ0FBQ2pMLFNBQVMsQ0FBQ21SLEdBQUcsQ0FBQ3lzQixpQkFBZSxDQUFDO01BRTVDLE1BQU1vQixrQkFBa0IsR0FBR0EsQ0FBQSxLQUFNO1FBQy9CLElBQUksSUFBSSxDQUFDOXpCLE9BQU8sQ0FBQ3FzQixLQUFLLEVBQUU7VUFDdEIsSUFBSSxDQUFDaUgsVUFBVSxDQUFDeEQsUUFBUSxFQUFFO1FBQzVCO1FBRUEsSUFBSSxDQUFDcmlCLGdCQUFnQixHQUFHLEtBQUs7UUFDN0I1VCxZQUFZLENBQUN5QyxPQUFPLENBQUMsSUFBSSxDQUFDeUQsUUFBUSxFQUFFbXlCLGFBQVcsRUFBRTtVQUMvQy8yQjtRQUNGLENBQUMsQ0FBQztPQUNIO01BRUQsSUFBSSxDQUFDbUYsY0FBYyxDQUFDd3pCLGtCQUFrQixFQUFFLElBQUksQ0FBQ1gsT0FBTyxFQUFFLElBQUksQ0FBQ3RuQixXQUFXLEVBQUUsQ0FBQztJQUMzRTtJQUVBdkMsa0JBQWtCQSxDQUFBLEVBQUc7TUFDbkJ6UCxZQUFZLENBQUNpQyxFQUFFLENBQUMsSUFBSSxDQUFDaUUsUUFBUSxFQUFFdXlCLHVCQUFxQixFQUFFNzRCLEtBQUssSUFBSTtRQUM3RCxJQUFJQSxLQUFLLENBQUMvSSxHQUFHLEtBQUttaEMsWUFBVSxFQUFFO1VBQzVCO1FBQ0Y7UUFFQSxJQUFJLElBQUksQ0FBQzd4QixPQUFPLENBQUN5SSxRQUFRLEVBQUU7VUFDekIsSUFBSSxDQUFDeUYsSUFBSSxFQUFFO1VBQ1g7UUFDRjtRQUVBLElBQUksQ0FBQzZsQiwwQkFBMEIsRUFBRTtNQUNuQyxDQUFDLENBQUM7TUFFRmw2QixZQUFZLENBQUNpQyxFQUFFLENBQUNsSyxNQUFNLEVBQUV1Z0MsY0FBWSxFQUFFLE1BQU07UUFDMUMsSUFBSSxJQUFJLENBQUNsa0IsUUFBUSxJQUFJLENBQUMsSUFBSSxDQUFDUixnQkFBZ0IsRUFBRTtVQUMzQyxJQUFJLENBQUNnbUIsYUFBYSxFQUFFO1FBQ3RCO01BQ0YsQ0FBQyxDQUFDO01BRUY1NUIsWUFBWSxDQUFDaUMsRUFBRSxDQUFDLElBQUksQ0FBQ2lFLFFBQVEsRUFBRXN5Qix1QkFBdUIsRUFBRTU0QixLQUFLLElBQUk7UUFDL0Q7UUFDQUksWUFBWSxDQUFDa0MsR0FBRyxDQUFDLElBQUksQ0FBQ2dFLFFBQVEsRUFBRXF5QixtQkFBbUIsRUFBRTRCLE1BQU0sSUFBSTtVQUM3RCxJQUFJLElBQUksQ0FBQ2owQixRQUFRLEtBQUt0RyxLQUFLLENBQUMzQixNQUFNLElBQUksSUFBSSxDQUFDaUksUUFBUSxLQUFLaTBCLE1BQU0sQ0FBQ2w4QixNQUFNLEVBQUU7WUFDckU7VUFDRjtVQUVBLElBQUksSUFBSSxDQUFDa0ksT0FBTyxDQUFDNHVCLFFBQVEsS0FBSyxRQUFRLEVBQUU7WUFDdEMsSUFBSSxDQUFDbUYsMEJBQTBCLEVBQUU7WUFDakM7VUFDRjtVQUVBLElBQUksSUFBSSxDQUFDL3pCLE9BQU8sQ0FBQzR1QixRQUFRLEVBQUU7WUFDekIsSUFBSSxDQUFDMWdCLElBQUksRUFBRTtVQUNiO1FBQ0YsQ0FBQyxDQUFDO01BQ0osQ0FBQyxDQUFDO0lBQ0o7SUFFQXlsQixVQUFVQSxDQUFBLEVBQUc7TUFDWCxJQUFJLENBQUM1ekIsUUFBUSxDQUFDMk8sS0FBSyxDQUFDZ2QsT0FBTyxHQUFHLE1BQU07TUFDcEMsSUFBSSxDQUFDM3JCLFFBQVEsQ0FBQ2hDLFlBQVksQ0FBQyxhQUFhLEVBQUUsSUFBSSxDQUFDO01BQy9DLElBQUksQ0FBQ2dDLFFBQVEsQ0FBQzlCLGVBQWUsQ0FBQyxZQUFZLENBQUM7TUFDM0MsSUFBSSxDQUFDOEIsUUFBUSxDQUFDOUIsZUFBZSxDQUFDLE1BQU0sQ0FBQztNQUNyQyxJQUFJLENBQUN3UCxnQkFBZ0IsR0FBRyxLQUFLO01BRTdCLElBQUksQ0FBQzJsQixTQUFTLENBQUNsbEIsSUFBSSxDQUFDLE1BQU07UUFDeEJuYixRQUFRLENBQUMrQyxJQUFJLENBQUNoQixTQUFTLENBQUN6RCxNQUFNLENBQUNtaEMsZUFBZSxDQUFDO1FBQy9DLElBQUksQ0FBQ3lCLGlCQUFpQixFQUFFO1FBQ3hCLElBQUksQ0FBQ1QsVUFBVSxDQUFDdlIsS0FBSyxFQUFFO1FBQ3ZCcG9CLFlBQVksQ0FBQ3lDLE9BQU8sQ0FBQyxJQUFJLENBQUN5RCxRQUFRLEVBQUVpeUIsY0FBWSxDQUFDO01BQ25ELENBQUMsQ0FBQztJQUNKO0lBRUFubUIsV0FBV0EsQ0FBQSxFQUFHO01BQ1osT0FBTyxJQUFJLENBQUM5TCxRQUFRLENBQUNqTCxTQUFTLENBQUNDLFFBQVEsQ0FBQzA5QixpQkFBZSxDQUFDO0lBQzFEO0lBRUFzQiwwQkFBMEJBLENBQUEsRUFBRztNQUMzQixNQUFNeEgsU0FBUyxHQUFHMXlCLFlBQVksQ0FBQ3lDLE9BQU8sQ0FBQyxJQUFJLENBQUN5RCxRQUFRLEVBQUVneUIsc0JBQW9CLENBQUM7TUFDM0UsSUFBSXhGLFNBQVMsQ0FBQzd2QixnQkFBZ0IsRUFBRTtRQUM5QjtNQUNGO01BRUEsTUFBTXczQixrQkFBa0IsR0FBRyxJQUFJLENBQUNuMEIsUUFBUSxDQUFDc2MsWUFBWSxHQUFHdHBCLFFBQVEsQ0FBQ3FDLGVBQWUsQ0FBQ3dpQixZQUFZO01BQzdGLE1BQU11YyxnQkFBZ0IsR0FBRyxJQUFJLENBQUNwMEIsUUFBUSxDQUFDMk8sS0FBSyxDQUFDZ08sU0FBUztNQUN0RDtNQUNBLElBQUl5WCxnQkFBZ0IsS0FBSyxRQUFRLElBQUksSUFBSSxDQUFDcDBCLFFBQVEsQ0FBQ2pMLFNBQVMsQ0FBQ0MsUUFBUSxDQUFDNDlCLGlCQUFpQixDQUFDLEVBQUU7UUFDeEY7TUFDRjtNQUVBLElBQUksQ0FBQ3VCLGtCQUFrQixFQUFFO1FBQ3ZCLElBQUksQ0FBQ24wQixRQUFRLENBQUMyTyxLQUFLLENBQUNnTyxTQUFTLEdBQUcsUUFBUTtNQUMxQztNQUVBLElBQUksQ0FBQzNjLFFBQVEsQ0FBQ2pMLFNBQVMsQ0FBQ21SLEdBQUcsQ0FBQzBzQixpQkFBaUIsQ0FBQztNQUM5QyxJQUFJLENBQUNyeUIsY0FBYyxDQUFDLE1BQU07UUFDeEIsSUFBSSxDQUFDUCxRQUFRLENBQUNqTCxTQUFTLENBQUN6RCxNQUFNLENBQUNzaEMsaUJBQWlCLENBQUM7UUFDakQsSUFBSSxDQUFDcnlCLGNBQWMsQ0FBQyxNQUFNO1VBQ3hCLElBQUksQ0FBQ1AsUUFBUSxDQUFDMk8sS0FBSyxDQUFDZ08sU0FBUyxHQUFHeVgsZ0JBQWdCO1FBQ2xELENBQUMsRUFBRSxJQUFJLENBQUNoQixPQUFPLENBQUM7TUFDbEIsQ0FBQyxFQUFFLElBQUksQ0FBQ0EsT0FBTyxDQUFDO01BRWhCLElBQUksQ0FBQ3B6QixRQUFRLENBQUNzc0IsS0FBSyxFQUFFO0lBQ3ZCOztJQUVBOzs7O0lBSUFvSCxhQUFhQSxDQUFBLEVBQUc7TUFDZCxNQUFNUyxrQkFBa0IsR0FBRyxJQUFJLENBQUNuMEIsUUFBUSxDQUFDc2MsWUFBWSxHQUFHdHBCLFFBQVEsQ0FBQ3FDLGVBQWUsQ0FBQ3dpQixZQUFZO01BQzdGLE1BQU1zWixjQUFjLEdBQUcsSUFBSSxDQUFDc0MsVUFBVSxDQUFDaEQsUUFBUSxFQUFFO01BQ2pELE1BQU00RCxpQkFBaUIsR0FBR2xELGNBQWMsR0FBRyxDQUFDO01BRTVDLElBQUlrRCxpQkFBaUIsSUFBSSxDQUFDRixrQkFBa0IsRUFBRTtRQUM1QyxNQUFNNTBCLFFBQVEsR0FBR2pKLEtBQUssRUFBRSxHQUFHLGFBQWEsR0FBRyxjQUFjO1FBQ3pELElBQUksQ0FBQzBKLFFBQVEsQ0FBQzJPLEtBQUssQ0FBQ3BQLFFBQVEsQ0FBQyxHQUFJLEdBQUU0eEIsY0FBZSxJQUFHO01BQ3ZEO01BRUEsSUFBSSxDQUFDa0QsaUJBQWlCLElBQUlGLGtCQUFrQixFQUFFO1FBQzVDLE1BQU01MEIsUUFBUSxHQUFHakosS0FBSyxFQUFFLEdBQUcsY0FBYyxHQUFHLGFBQWE7UUFDekQsSUFBSSxDQUFDMEosUUFBUSxDQUFDMk8sS0FBSyxDQUFDcFAsUUFBUSxDQUFDLEdBQUksR0FBRTR4QixjQUFlLElBQUc7TUFDdkQ7SUFDRjtJQUVBK0MsaUJBQWlCQSxDQUFBLEVBQUc7TUFDbEIsSUFBSSxDQUFDbDBCLFFBQVEsQ0FBQzJPLEtBQUssQ0FBQzJsQixXQUFXLEdBQUcsRUFBRTtNQUNwQyxJQUFJLENBQUN0MEIsUUFBUSxDQUFDMk8sS0FBSyxDQUFDNGxCLFlBQVksR0FBRyxFQUFFO0lBQ3ZDOztJQUVBO0lBQ0EsT0FBT3g5QixlQUFlQSxDQUFDaUksTUFBTSxFQUFFNUQsYUFBYSxFQUFFO01BQzVDLE9BQU8sSUFBSSxDQUFDa0ksSUFBSSxDQUFDLFlBQVk7UUFDM0IsTUFBTUMsSUFBSSxHQUFHNHZCLEtBQUssQ0FBQ3p5QixtQkFBbUIsQ0FBQyxJQUFJLEVBQUUxQixNQUFNLENBQUM7UUFFcEQsSUFBSSxPQUFPQSxNQUFNLEtBQUssUUFBUSxFQUFFO1VBQzlCO1FBQ0Y7UUFFQSxJQUFJLE9BQU91RSxJQUFJLENBQUN2RSxNQUFNLENBQUMsS0FBSyxXQUFXLEVBQUU7VUFDdkMsTUFBTSxJQUFJWSxTQUFTLENBQUUsb0JBQW1CWixNQUFPLEdBQUUsQ0FBQztRQUNwRDtRQUVBdUUsSUFBSSxDQUFDdkUsTUFBTSxDQUFDLENBQUM1RCxhQUFhLENBQUM7TUFDN0IsQ0FBQyxDQUFDO0lBQ0o7RUFDRjs7RUFFQTs7OztFQUlBdEIsWUFBWSxDQUFDaUMsRUFBRSxDQUFDL0ksUUFBUSxFQUFFdy9CLHNCQUFvQixFQUFFUSxzQkFBb0IsRUFBRSxVQUFVdDVCLEtBQUssRUFBRTtJQUNyRixNQUFNM0IsTUFBTSxHQUFHbUosY0FBYyxDQUFDa0Isc0JBQXNCLENBQUMsSUFBSSxDQUFDO0lBRTFELElBQUksQ0FBQyxHQUFHLEVBQUUsTUFBTSxDQUFDLENBQUN0RyxRQUFRLENBQUMsSUFBSSxDQUFDNEcsT0FBTyxDQUFDLEVBQUU7TUFDeENoSixLQUFLLENBQUN1RCxjQUFjLEVBQUU7SUFDeEI7SUFFQW5ELFlBQVksQ0FBQ2tDLEdBQUcsQ0FBQ2pFLE1BQU0sRUFBRW02QixZQUFVLEVBQUU5RixTQUFTLElBQUk7TUFDaEQsSUFBSUEsU0FBUyxDQUFDenZCLGdCQUFnQixFQUFFO1FBQzlCO1FBQ0E7TUFDRjtNQUVBN0MsWUFBWSxDQUFDa0MsR0FBRyxDQUFDakUsTUFBTSxFQUFFazZCLGNBQVksRUFBRSxNQUFNO1FBQzNDLElBQUk3OUIsU0FBUyxDQUFDLElBQUksQ0FBQyxFQUFFO1VBQ25CLElBQUksQ0FBQ2s0QixLQUFLLEVBQUU7UUFDZDtNQUNGLENBQUMsQ0FBQztJQUNKLENBQUMsQ0FBQzs7SUFFRjtJQUNBLE1BQU1rSSxXQUFXLEdBQUd0ekIsY0FBYyxDQUFDRyxPQUFPLENBQUN3eEIsZUFBYSxDQUFDO0lBQ3pELElBQUkyQixXQUFXLEVBQUU7TUFDZnJCLEtBQUssQ0FBQzF5QixXQUFXLENBQUMrekIsV0FBVyxDQUFDLENBQUNybUIsSUFBSSxFQUFFO0lBQ3ZDO0lBRUEsTUFBTTVLLElBQUksR0FBRzR2QixLQUFLLENBQUN6eUIsbUJBQW1CLENBQUMzSSxNQUFNLENBQUM7SUFFOUN3TCxJQUFJLENBQUNTLE1BQU0sQ0FBQyxJQUFJLENBQUM7RUFDbkIsQ0FBQyxDQUFDO0VBRUYxQixvQkFBb0IsQ0FBQzZ3QixLQUFLLENBQUM7O0VBRTNCOzs7O0VBSUEzOEIsa0JBQWtCLENBQUMyOEIsS0FBSyxDQUFDOztFQ3ZYekI7Ozs7Ozs7RUFvQkE7Ozs7RUFJQSxNQUFNc0IsTUFBSSxHQUFHLFdBQVc7RUFDeEIsTUFBTUMsVUFBUSxHQUFHLGNBQWM7RUFDL0IsTUFBTUMsV0FBUyxHQUFJLElBQUdELFVBQVMsRUFBQztFQUNoQyxNQUFNRSxjQUFZLEdBQUcsV0FBVztFQUNoQyxNQUFNQyxxQkFBbUIsR0FBSSxPQUFNRixXQUFVLEdBQUVDLGNBQWEsRUFBQztFQUM3RCxNQUFNRSxVQUFVLEdBQUcsUUFBUTtFQUUzQixNQUFNQyxpQkFBZSxHQUFHLE1BQU07RUFDOUIsTUFBTUMsb0JBQWtCLEdBQUcsU0FBUztFQUNwQyxNQUFNQyxpQkFBaUIsR0FBRyxRQUFRO0VBQ2xDLE1BQU1DLG1CQUFtQixHQUFHLG9CQUFvQjtFQUNoRCxNQUFNQyxhQUFhLEdBQUcsaUJBQWlCO0VBRXZDLE1BQU1DLFlBQVUsR0FBSSxPQUFNVCxXQUFVLEVBQUM7RUFDckMsTUFBTVUsYUFBVyxHQUFJLFFBQU9WLFdBQVUsRUFBQztFQUN2QyxNQUFNVyxZQUFVLEdBQUksT0FBTVgsV0FBVSxFQUFDO0VBQ3JDLE1BQU1ZLG9CQUFvQixHQUFJLGdCQUFlWixXQUFVLEVBQUM7RUFDeEQsTUFBTWEsY0FBWSxHQUFJLFNBQVFiLFdBQVUsRUFBQztFQUN6QyxNQUFNYyxZQUFZLEdBQUksU0FBUWQsV0FBVSxFQUFDO0VBQ3pDLE1BQU1lLHNCQUFvQixHQUFJLFFBQU9mLFdBQVUsR0FBRUMsY0FBYSxFQUFDO0VBQy9ELE1BQU1lLHFCQUFxQixHQUFJLGtCQUFpQmhCLFdBQVUsRUFBQztFQUUzRCxNQUFNaUIsc0JBQW9CLEdBQUcsOEJBQThCO0VBRTNELE1BQU1DLFNBQU8sR0FBRztJQUNkaEgsUUFBUSxFQUFFLElBQUk7SUFDZG5tQixRQUFRLEVBQUUsSUFBSTtJQUNkbVMsTUFBTSxFQUFFO0VBQ1YsQ0FBQztFQUVELE1BQU1pYixhQUFXLEdBQUc7SUFDbEJqSCxRQUFRLEVBQUUsa0JBQWtCO0lBQzVCbm1CLFFBQVEsRUFBRSxTQUFTO0lBQ25CbVMsTUFBTSxFQUFFO0VBQ1YsQ0FBQzs7RUFFRDs7OztFQUlBLE1BQU1rYixTQUFTLFNBQVNoMkIsYUFBYSxDQUFDO0lBQ3BDVixXQUFXQSxDQUFDM08sT0FBTyxFQUFFc08sTUFBTSxFQUFFO01BQzNCLEtBQUssQ0FBQ3RPLE9BQU8sRUFBRXNPLE1BQU0sQ0FBQztNQUV0QixJQUFJLENBQUNrUCxRQUFRLEdBQUcsS0FBSztNQUNyQixJQUFJLENBQUNtbEIsU0FBUyxHQUFHLElBQUksQ0FBQ0MsbUJBQW1CLEVBQUU7TUFDM0MsSUFBSSxDQUFDQyxVQUFVLEdBQUcsSUFBSSxDQUFDQyxvQkFBb0IsRUFBRTtNQUM3QyxJQUFJLENBQUNqcUIsa0JBQWtCLEVBQUU7SUFDM0I7O0lBRUE7SUFDQSxXQUFXM0ssT0FBT0EsQ0FBQSxFQUFHO01BQ25CLE9BQU9pM0IsU0FBTztJQUNoQjtJQUVBLFdBQVdoM0IsV0FBV0EsQ0FBQSxFQUFHO01BQ3ZCLE9BQU9pM0IsYUFBVztJQUNwQjtJQUVBLFdBQVdsL0IsSUFBSUEsQ0FBQSxFQUFHO01BQ2hCLE9BQU82OUIsTUFBSTtJQUNiOztJQUVBO0lBQ0F6d0IsTUFBTUEsQ0FBQzVJLGFBQWEsRUFBRTtNQUNwQixPQUFPLElBQUksQ0FBQzhTLFFBQVEsR0FBRyxJQUFJLENBQUNDLElBQUksRUFBRSxHQUFHLElBQUksQ0FBQ0MsSUFBSSxDQUFDaFQsYUFBYSxDQUFDO0lBQy9EO0lBRUFnVCxJQUFJQSxDQUFDaFQsYUFBYSxFQUFFO01BQ2xCLElBQUksSUFBSSxDQUFDOFMsUUFBUSxFQUFFO1FBQ2pCO01BQ0Y7TUFFQSxNQUFNa2UsU0FBUyxHQUFHdHlCLFlBQVksQ0FBQ3lDLE9BQU8sQ0FBQyxJQUFJLENBQUN5RCxRQUFRLEVBQUVvMUIsWUFBVSxFQUFFO1FBQUVoNkI7TUFBYyxDQUFDLENBQUM7TUFFcEYsSUFBSWd4QixTQUFTLENBQUN6dkIsZ0JBQWdCLEVBQUU7UUFDOUI7TUFDRjtNQUVBLElBQUksQ0FBQ3VSLFFBQVEsR0FBRyxJQUFJO01BQ3BCLElBQUksQ0FBQ21sQixTQUFTLENBQUNqbEIsSUFBSSxFQUFFO01BRXJCLElBQUksQ0FBQyxJQUFJLENBQUNuTyxPQUFPLENBQUM0YSxNQUFNLEVBQUU7UUFDeEIsSUFBSTJWLGVBQWUsRUFBRSxDQUFDcmlCLElBQUksRUFBRTtNQUM5QjtNQUVBLElBQUksQ0FBQ25PLFFBQVEsQ0FBQ2hDLFlBQVksQ0FBQyxZQUFZLEVBQUUsSUFBSSxDQUFDO01BQzlDLElBQUksQ0FBQ2dDLFFBQVEsQ0FBQ2hDLFlBQVksQ0FBQyxNQUFNLEVBQUUsUUFBUSxDQUFDO01BQzVDLElBQUksQ0FBQ2dDLFFBQVEsQ0FBQ2pMLFNBQVMsQ0FBQ21SLEdBQUcsQ0FBQzh1QixvQkFBa0IsQ0FBQztNQUUvQyxNQUFNbnBCLGdCQUFnQixHQUFHQSxDQUFBLEtBQU07UUFDN0IsSUFBSSxDQUFDLElBQUksQ0FBQzVMLE9BQU8sQ0FBQzRhLE1BQU0sSUFBSSxJQUFJLENBQUM1YSxPQUFPLENBQUM0dUIsUUFBUSxFQUFFO1VBQ2pELElBQUksQ0FBQzBFLFVBQVUsQ0FBQ3hELFFBQVEsRUFBRTtRQUM1QjtRQUVBLElBQUksQ0FBQy92QixRQUFRLENBQUNqTCxTQUFTLENBQUNtUixHQUFHLENBQUM2dUIsaUJBQWUsQ0FBQztRQUM1QyxJQUFJLENBQUMvMEIsUUFBUSxDQUFDakwsU0FBUyxDQUFDekQsTUFBTSxDQUFDMGpDLG9CQUFrQixDQUFDO1FBQ2xEbDdCLFlBQVksQ0FBQ3lDLE9BQU8sQ0FBQyxJQUFJLENBQUN5RCxRQUFRLEVBQUVxMUIsYUFBVyxFQUFFO1VBQUVqNkI7UUFBYyxDQUFDLENBQUM7T0FDcEU7TUFFRCxJQUFJLENBQUNtRixjQUFjLENBQUNzTCxnQkFBZ0IsRUFBRSxJQUFJLENBQUM3TCxRQUFRLEVBQUUsSUFBSSxDQUFDO0lBQzVEO0lBRUFtTyxJQUFJQSxDQUFBLEVBQUc7TUFDTCxJQUFJLENBQUMsSUFBSSxDQUFDRCxRQUFRLEVBQUU7UUFDbEI7TUFDRjtNQUVBLE1BQU1zZSxTQUFTLEdBQUcxeUIsWUFBWSxDQUFDeUMsT0FBTyxDQUFDLElBQUksQ0FBQ3lELFFBQVEsRUFBRXMxQixZQUFVLENBQUM7TUFFakUsSUFBSTlJLFNBQVMsQ0FBQzd2QixnQkFBZ0IsRUFBRTtRQUM5QjtNQUNGO01BRUEsSUFBSSxDQUFDNDJCLFVBQVUsQ0FBQ3JELFVBQVUsRUFBRTtNQUM1QixJQUFJLENBQUNsd0IsUUFBUSxDQUFDZzJCLElBQUksRUFBRTtNQUNwQixJQUFJLENBQUM5bkIsUUFBUSxHQUFHLEtBQUs7TUFDckIsSUFBSSxDQUFDbE8sUUFBUSxDQUFDakwsU0FBUyxDQUFDbVIsR0FBRyxDQUFDK3VCLGlCQUFpQixDQUFDO01BQzlDLElBQUksQ0FBQzVCLFNBQVMsQ0FBQ2xsQixJQUFJLEVBQUU7TUFFckIsTUFBTThuQixnQkFBZ0IsR0FBR0EsQ0FBQSxLQUFNO1FBQzdCLElBQUksQ0FBQ2oyQixRQUFRLENBQUNqTCxTQUFTLENBQUN6RCxNQUFNLENBQUN5akMsaUJBQWUsRUFBRUUsaUJBQWlCLENBQUM7UUFDbEUsSUFBSSxDQUFDajFCLFFBQVEsQ0FBQzlCLGVBQWUsQ0FBQyxZQUFZLENBQUM7UUFDM0MsSUFBSSxDQUFDOEIsUUFBUSxDQUFDOUIsZUFBZSxDQUFDLE1BQU0sQ0FBQztRQUVyQyxJQUFJLENBQUMsSUFBSSxDQUFDK0IsT0FBTyxDQUFDNGEsTUFBTSxFQUFFO1VBQ3hCLElBQUkyVixlQUFlLEVBQUUsQ0FBQ3RPLEtBQUssRUFBRTtRQUMvQjtRQUVBcG9CLFlBQVksQ0FBQ3lDLE9BQU8sQ0FBQyxJQUFJLENBQUN5RCxRQUFRLEVBQUV3MUIsY0FBWSxDQUFDO09BQ2xEO01BRUQsSUFBSSxDQUFDajFCLGNBQWMsQ0FBQzAxQixnQkFBZ0IsRUFBRSxJQUFJLENBQUNqMkIsUUFBUSxFQUFFLElBQUksQ0FBQztJQUM1RDtJQUVBRyxPQUFPQSxDQUFBLEVBQUc7TUFDUixJQUFJLENBQUNrekIsU0FBUyxDQUFDbHpCLE9BQU8sRUFBRTtNQUN4QixJQUFJLENBQUNvekIsVUFBVSxDQUFDckQsVUFBVSxFQUFFO01BQzVCLEtBQUssQ0FBQy92QixPQUFPLEVBQUU7SUFDakI7O0lBRUE7SUFDQW16QixtQkFBbUJBLENBQUEsRUFBRztNQUNwQixNQUFNakYsYUFBYSxHQUFHQSxDQUFBLEtBQU07UUFDMUIsSUFBSSxJQUFJLENBQUNwdUIsT0FBTyxDQUFDNHVCLFFBQVEsS0FBSyxRQUFRLEVBQUU7VUFDdEMvMEIsWUFBWSxDQUFDeUMsT0FBTyxDQUFDLElBQUksQ0FBQ3lELFFBQVEsRUFBRXUxQixvQkFBb0IsQ0FBQztVQUN6RDtRQUNGO1FBRUEsSUFBSSxDQUFDcG5CLElBQUksRUFBRTtPQUNaOztNQUVEO01BQ0EsTUFBTS9aLFNBQVMsR0FBR29ILE9BQU8sQ0FBQyxJQUFJLENBQUN5RSxPQUFPLENBQUM0dUIsUUFBUSxDQUFDO01BRWhELE9BQU8sSUFBSUwsUUFBUSxDQUFDO1FBQ2xCSixTQUFTLEVBQUU4RyxtQkFBbUI7UUFDOUI5Z0MsU0FBUztRQUNUb00sVUFBVSxFQUFFLElBQUk7UUFDaEI4dEIsV0FBVyxFQUFFLElBQUksQ0FBQ3R1QixRQUFRLENBQUNyTCxVQUFVO1FBQ3JDMDVCLGFBQWEsRUFBRWo2QixTQUFTLEdBQUdpNkIsYUFBYSxHQUFHO01BQzdDLENBQUMsQ0FBQztJQUNKO0lBRUFtRixvQkFBb0JBLENBQUEsRUFBRztNQUNyQixPQUFPLElBQUk1RCxTQUFTLENBQUM7UUFDbkJGLFdBQVcsRUFBRSxJQUFJLENBQUMxdkI7TUFDcEIsQ0FBQyxDQUFDO0lBQ0o7SUFFQXVKLGtCQUFrQkEsQ0FBQSxFQUFHO01BQ25CelAsWUFBWSxDQUFDaUMsRUFBRSxDQUFDLElBQUksQ0FBQ2lFLFFBQVEsRUFBRTIxQixxQkFBcUIsRUFBRWo4QixLQUFLLElBQUk7UUFDN0QsSUFBSUEsS0FBSyxDQUFDL0ksR0FBRyxLQUFLbWtDLFVBQVUsRUFBRTtVQUM1QjtRQUNGO1FBRUEsSUFBSSxJQUFJLENBQUM3MEIsT0FBTyxDQUFDeUksUUFBUSxFQUFFO1VBQ3pCLElBQUksQ0FBQ3lGLElBQUksRUFBRTtVQUNYO1FBQ0Y7UUFFQXJVLFlBQVksQ0FBQ3lDLE9BQU8sQ0FBQyxJQUFJLENBQUN5RCxRQUFRLEVBQUV1MUIsb0JBQW9CLENBQUM7TUFDM0QsQ0FBQyxDQUFDO0lBQ0o7O0lBRUE7SUFDQSxPQUFPeCtCLGVBQWVBLENBQUNpSSxNQUFNLEVBQUU7TUFDN0IsT0FBTyxJQUFJLENBQUNzRSxJQUFJLENBQUMsWUFBWTtRQUMzQixNQUFNQyxJQUFJLEdBQUd3eUIsU0FBUyxDQUFDcjFCLG1CQUFtQixDQUFDLElBQUksRUFBRTFCLE1BQU0sQ0FBQztRQUV4RCxJQUFJLE9BQU9BLE1BQU0sS0FBSyxRQUFRLEVBQUU7VUFDOUI7UUFDRjtRQUVBLElBQUl1RSxJQUFJLENBQUN2RSxNQUFNLENBQUMsS0FBSzNNLFNBQVMsSUFBSTJNLE1BQU0sQ0FBQzdDLFVBQVUsQ0FBQyxHQUFHLENBQUMsSUFBSTZDLE1BQU0sS0FBSyxhQUFhLEVBQUU7VUFDcEYsTUFBTSxJQUFJWSxTQUFTLENBQUUsb0JBQW1CWixNQUFPLEdBQUUsQ0FBQztRQUNwRDtRQUVBdUUsSUFBSSxDQUFDdkUsTUFBTSxDQUFDLENBQUMsSUFBSSxDQUFDO01BQ3BCLENBQUMsQ0FBQztJQUNKO0VBQ0Y7O0VBRUE7Ozs7RUFJQWxGLFlBQVksQ0FBQ2lDLEVBQUUsQ0FBQy9JLFFBQVEsRUFBRTBpQyxzQkFBb0IsRUFBRUUsc0JBQW9CLEVBQUUsVUFBVWw4QixLQUFLLEVBQUU7SUFDckYsTUFBTTNCLE1BQU0sR0FBR21KLGNBQWMsQ0FBQ2tCLHNCQUFzQixDQUFDLElBQUksQ0FBQztJQUUxRCxJQUFJLENBQUMsR0FBRyxFQUFFLE1BQU0sQ0FBQyxDQUFDdEcsUUFBUSxDQUFDLElBQUksQ0FBQzRHLE9BQU8sQ0FBQyxFQUFFO01BQ3hDaEosS0FBSyxDQUFDdUQsY0FBYyxFQUFFO0lBQ3hCO0lBRUEsSUFBSXJJLFVBQVUsQ0FBQyxJQUFJLENBQUMsRUFBRTtNQUNwQjtJQUNGO0lBRUFrRixZQUFZLENBQUNrQyxHQUFHLENBQUNqRSxNQUFNLEVBQUV5OUIsY0FBWSxFQUFFLE1BQU07TUFDM0M7TUFDQSxJQUFJcGhDLFNBQVMsQ0FBQyxJQUFJLENBQUMsRUFBRTtRQUNuQixJQUFJLENBQUNrNEIsS0FBSyxFQUFFO01BQ2Q7SUFDRixDQUFDLENBQUM7O0lBRUY7SUFDQSxNQUFNa0ksV0FBVyxHQUFHdHpCLGNBQWMsQ0FBQ0csT0FBTyxDQUFDOHpCLGFBQWEsQ0FBQztJQUN6RCxJQUFJWCxXQUFXLElBQUlBLFdBQVcsS0FBS3o4QixNQUFNLEVBQUU7TUFDekNnK0IsU0FBUyxDQUFDdDFCLFdBQVcsQ0FBQyt6QixXQUFXLENBQUMsQ0FBQ3JtQixJQUFJLEVBQUU7SUFDM0M7SUFFQSxNQUFNNUssSUFBSSxHQUFHd3lCLFNBQVMsQ0FBQ3IxQixtQkFBbUIsQ0FBQzNJLE1BQU0sQ0FBQztJQUNsRHdMLElBQUksQ0FBQ1MsTUFBTSxDQUFDLElBQUksQ0FBQztFQUNuQixDQUFDLENBQUM7RUFFRmxLLFlBQVksQ0FBQ2lDLEVBQUUsQ0FBQ2xLLE1BQU0sRUFBRWdqQyxxQkFBbUIsRUFBRSxNQUFNO0lBQ2pELEtBQUssTUFBTWpqQyxRQUFRLElBQUlzUCxjQUFjLENBQUN2RyxJQUFJLENBQUN3NkIsYUFBYSxDQUFDLEVBQUU7TUFDekRZLFNBQVMsQ0FBQ3IxQixtQkFBbUIsQ0FBQzlPLFFBQVEsQ0FBQyxDQUFDd2MsSUFBSSxFQUFFO0lBQ2hEO0VBQ0YsQ0FBQyxDQUFDO0VBRUZ0VSxZQUFZLENBQUNpQyxFQUFFLENBQUNsSyxNQUFNLEVBQUU0akMsWUFBWSxFQUFFLE1BQU07SUFDMUMsS0FBSyxNQUFNL2tDLE9BQU8sSUFBSXdRLGNBQWMsQ0FBQ3ZHLElBQUksQ0FBQyw4Q0FBOEMsQ0FBQyxFQUFFO01BQ3pGLElBQUl0SCxnQkFBZ0IsQ0FBQzNDLE9BQU8sQ0FBQyxDQUFDMGhCLFFBQVEsS0FBSyxPQUFPLEVBQUU7UUFDbEQyakIsU0FBUyxDQUFDcjFCLG1CQUFtQixDQUFDaFEsT0FBTyxDQUFDLENBQUN5ZCxJQUFJLEVBQUU7TUFDL0M7SUFDRjtFQUNGLENBQUMsQ0FBQztFQUVGN0wsb0JBQW9CLENBQUN5ekIsU0FBUyxDQUFDOztFQUUvQjs7OztFQUlBdi9CLGtCQUFrQixDQUFDdS9CLFNBQVMsQ0FBQzs7RUN2UjdCOzs7Ozs7O0VBT0E7RUFDQSxNQUFNRyxzQkFBc0IsR0FBRyxnQkFBZ0I7RUFFeEMsTUFBTUMsZ0JBQWdCLEdBQUc7SUFDOUI7SUFDQSxHQUFHLEVBQUUsQ0FBQyxPQUFPLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFFRCxzQkFBc0IsQ0FBQztJQUNuRWpXLENBQUMsRUFBRSxDQUFDLFFBQVEsRUFBRSxNQUFNLEVBQUUsT0FBTyxFQUFFLEtBQUssQ0FBQztJQUNyQ21XLElBQUksRUFBRSxFQUFFO0lBQ1JsVyxDQUFDLEVBQUUsRUFBRTtJQUNMbVcsRUFBRSxFQUFFLEVBQUU7SUFDTkMsR0FBRyxFQUFFLEVBQUU7SUFDUEMsSUFBSSxFQUFFLEVBQUU7SUFDUkMsRUFBRSxFQUFFLEVBQUU7SUFDTkMsR0FBRyxFQUFFLEVBQUU7SUFDUEMsRUFBRSxFQUFFLEVBQUU7SUFDTkMsRUFBRSxFQUFFLEVBQUU7SUFDTkMsRUFBRSxFQUFFLEVBQUU7SUFDTkMsRUFBRSxFQUFFLEVBQUU7SUFDTkMsRUFBRSxFQUFFLEVBQUU7SUFDTkMsRUFBRSxFQUFFLEVBQUU7SUFDTkMsRUFBRSxFQUFFLEVBQUU7SUFDTkMsRUFBRSxFQUFFLEVBQUU7SUFDTkMsRUFBRSxFQUFFLEVBQUU7SUFDTkMsRUFBRSxFQUFFLEVBQUU7SUFDTjlWLENBQUMsRUFBRSxFQUFFO0lBQ0wzVyxHQUFHLEVBQUUsQ0FBQyxLQUFLLEVBQUUsUUFBUSxFQUFFLEtBQUssRUFBRSxPQUFPLEVBQUUsT0FBTyxFQUFFLFFBQVEsQ0FBQztJQUN6RDBzQixFQUFFLEVBQUUsRUFBRTtJQUNOQyxFQUFFLEVBQUUsRUFBRTtJQUNOQyxDQUFDLEVBQUUsRUFBRTtJQUNMQyxHQUFHLEVBQUUsRUFBRTtJQUNQQyxDQUFDLEVBQUUsRUFBRTtJQUNMQyxLQUFLLEVBQUUsRUFBRTtJQUNUQyxJQUFJLEVBQUUsRUFBRTtJQUNSQyxHQUFHLEVBQUUsRUFBRTtJQUNQQyxHQUFHLEVBQUUsRUFBRTtJQUNQQyxNQUFNLEVBQUUsRUFBRTtJQUNWQyxDQUFDLEVBQUUsRUFBRTtJQUNMQyxFQUFFLEVBQUU7RUFDTixDQUFDO0VBQ0Q7O0VBRUEsTUFBTUMsYUFBYSxHQUFHLElBQUkzK0IsR0FBRyxDQUFDLENBQzVCLFlBQVksRUFDWixNQUFNLEVBQ04sTUFBTSxFQUNOLFVBQVUsRUFDVixVQUFVLEVBQ1YsUUFBUSxFQUNSLEtBQUssRUFDTCxZQUFZLENBQ2IsQ0FBQzs7RUFFRjs7Ozs7O0VBTUE7RUFDQSxNQUFNNCtCLGdCQUFnQixHQUFHLHlEQUF5RDtFQUVsRixNQUFNQyxnQkFBZ0IsR0FBR0EsQ0FBQ3ZsQixTQUFTLEVBQUV3bEIsb0JBQW9CLEtBQUs7SUFDNUQsTUFBTUMsYUFBYSxHQUFHemxCLFNBQVMsQ0FBQzVCLFFBQVEsQ0FBQ3JlLFdBQVcsRUFBRTtJQUV0RCxJQUFJeWxDLG9CQUFvQixDQUFDcjhCLFFBQVEsQ0FBQ3M4QixhQUFhLENBQUMsRUFBRTtNQUNoRCxJQUFJSixhQUFhLENBQUNubkMsR0FBRyxDQUFDdW5DLGFBQWEsQ0FBQyxFQUFFO1FBQ3BDLE9BQU81OEIsT0FBTyxDQUFDeThCLGdCQUFnQixDQUFDdDRCLElBQUksQ0FBQ2dULFNBQVMsQ0FBQzBsQixTQUFTLENBQUMsQ0FBQztNQUM1RDtNQUVBLE9BQU8sSUFBSTtJQUNiOztJQUVBO0lBQ0EsT0FBT0Ysb0JBQW9CLENBQUM1NUIsTUFBTSxDQUFDKzVCLGNBQWMsSUFBSUEsY0FBYyxZQUFZNTRCLE1BQU0sQ0FBQyxDQUNuRjZpQixJQUFJLENBQUNnVyxLQUFLLElBQUlBLEtBQUssQ0FBQzU0QixJQUFJLENBQUN5NEIsYUFBYSxDQUFDLENBQUM7RUFDN0MsQ0FBQztFQUVNLFNBQVNJLFlBQVlBLENBQUNDLFVBQVUsRUFBRUMsU0FBUyxFQUFFQyxnQkFBZ0IsRUFBRTtJQUNwRSxJQUFJLENBQUNGLFVBQVUsQ0FBQ3ZrQyxNQUFNLEVBQUU7TUFDdEIsT0FBT3VrQyxVQUFVO0lBQ25CO0lBRUEsSUFBSUUsZ0JBQWdCLElBQUksT0FBT0EsZ0JBQWdCLEtBQUssVUFBVSxFQUFFO01BQzlELE9BQU9BLGdCQUFnQixDQUFDRixVQUFVLENBQUM7SUFDckM7SUFFQSxNQUFNRyxTQUFTLEdBQUcsSUFBSS9tQyxNQUFNLENBQUNnbkMsU0FBUyxFQUFFO0lBQ3hDLE1BQU1DLGVBQWUsR0FBR0YsU0FBUyxDQUFDRyxlQUFlLENBQUNOLFVBQVUsRUFBRSxXQUFXLENBQUM7SUFDMUUsTUFBTTdtQixRQUFRLEdBQUcsRUFBRSxDQUFDelEsTUFBTSxDQUFDLEdBQUcyM0IsZUFBZSxDQUFDL2lDLElBQUksQ0FBQ3FFLGdCQUFnQixDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBRXpFLEtBQUssTUFBTTFKLE9BQU8sSUFBSWtoQixRQUFRLEVBQUU7TUFDOUIsTUFBTW9uQixXQUFXLEdBQUd0b0MsT0FBTyxDQUFDcWdCLFFBQVEsQ0FBQ3JlLFdBQVcsRUFBRTtNQUVsRCxJQUFJLENBQUNKLE1BQU0sQ0FBQ2pCLElBQUksQ0FBQ3FuQyxTQUFTLENBQUMsQ0FBQzU4QixRQUFRLENBQUNrOUIsV0FBVyxDQUFDLEVBQUU7UUFDakR0b0MsT0FBTyxDQUFDWSxNQUFNLEVBQUU7UUFDaEI7TUFDRjtNQUVBLE1BQU0ybkMsYUFBYSxHQUFHLEVBQUUsQ0FBQzkzQixNQUFNLENBQUMsR0FBR3pRLE9BQU8sQ0FBQzBOLFVBQVUsQ0FBQztNQUN0RCxNQUFNODZCLGlCQUFpQixHQUFHLEVBQUUsQ0FBQy8zQixNQUFNLENBQUN1M0IsU0FBUyxDQUFDLEdBQUcsQ0FBQyxJQUFJLEVBQUUsRUFBRUEsU0FBUyxDQUFDTSxXQUFXLENBQUMsSUFBSSxFQUFFLENBQUM7TUFFdkYsS0FBSyxNQUFNcm1CLFNBQVMsSUFBSXNtQixhQUFhLEVBQUU7UUFDckMsSUFBSSxDQUFDZixnQkFBZ0IsQ0FBQ3ZsQixTQUFTLEVBQUV1bUIsaUJBQWlCLENBQUMsRUFBRTtVQUNuRHhvQyxPQUFPLENBQUN3TixlQUFlLENBQUN5VSxTQUFTLENBQUM1QixRQUFRLENBQUM7UUFDN0M7TUFDRjtJQUNGO0lBRUEsT0FBTytuQixlQUFlLENBQUMvaUMsSUFBSSxDQUFDb2pDLFNBQVM7RUFDdkM7O0VDcEhBOzs7Ozs7O0VBWUE7Ozs7RUFJQSxNQUFNQyxNQUFJLEdBQUcsaUJBQWlCO0VBRTlCLE1BQU1DLFNBQU8sR0FBRztJQUNkWCxTQUFTLEVBQUV2QyxnQkFBZ0I7SUFDM0JtRCxPQUFPLEVBQUUsRUFBRTtJQUFFO0lBQ2JDLFVBQVUsRUFBRSxFQUFFO0lBQ2R2ZCxJQUFJLEVBQUUsS0FBSztJQUNYd2QsUUFBUSxFQUFFLElBQUk7SUFDZEMsVUFBVSxFQUFFLElBQUk7SUFDaEJDLFFBQVEsRUFBRTtFQUNaLENBQUM7RUFFRCxNQUFNQyxhQUFXLEdBQUc7SUFDbEJqQixTQUFTLEVBQUUsUUFBUTtJQUNuQlksT0FBTyxFQUFFLFFBQVE7SUFDakJDLFVBQVUsRUFBRSxtQkFBbUI7SUFDL0J2ZCxJQUFJLEVBQUUsU0FBUztJQUNmd2QsUUFBUSxFQUFFLFNBQVM7SUFDbkJDLFVBQVUsRUFBRSxpQkFBaUI7SUFDN0JDLFFBQVEsRUFBRTtFQUNaLENBQUM7RUFFRCxNQUFNRSxrQkFBa0IsR0FBRztJQUN6QkMsS0FBSyxFQUFFLGdDQUFnQztJQUN2Q2pvQyxRQUFRLEVBQUU7RUFDWixDQUFDOztFQUVEOzs7O0VBSUEsTUFBTWtvQyxlQUFlLFNBQVNuN0IsTUFBTSxDQUFDO0lBQ25DVSxXQUFXQSxDQUFDTCxNQUFNLEVBQUU7TUFDbEIsS0FBSyxFQUFFO01BQ1AsSUFBSSxDQUFDaUIsT0FBTyxHQUFHLElBQUksQ0FBQ2xCLFVBQVUsQ0FBQ0MsTUFBTSxDQUFDO0lBQ3hDOztJQUVBO0lBQ0EsV0FBV0osT0FBT0EsQ0FBQSxFQUFHO01BQ25CLE9BQU95NkIsU0FBTztJQUNoQjtJQUVBLFdBQVd4NkIsV0FBV0EsQ0FBQSxFQUFHO01BQ3ZCLE9BQU84NkIsYUFBVztJQUNwQjtJQUVBLFdBQVcvaUMsSUFBSUEsQ0FBQSxFQUFHO01BQ2hCLE9BQU93aUMsTUFBSTtJQUNiOztJQUVBO0lBQ0FXLFVBQVVBLENBQUEsRUFBRztNQUNYLE9BQU96bkMsTUFBTSxDQUFDb0ksTUFBTSxDQUFDLElBQUksQ0FBQ3VGLE9BQU8sQ0FBQ3E1QixPQUFPLENBQUMsQ0FDdkN2NEIsR0FBRyxDQUFDL0IsTUFBTSxJQUFJLElBQUksQ0FBQ2c3Qix3QkFBd0IsQ0FBQ2g3QixNQUFNLENBQUMsQ0FBQyxDQUNwRFQsTUFBTSxDQUFDL0MsT0FBTyxDQUFDO0lBQ3BCO0lBRUF5K0IsVUFBVUEsQ0FBQSxFQUFHO01BQ1gsT0FBTyxJQUFJLENBQUNGLFVBQVUsRUFBRSxDQUFDN2xDLE1BQU0sR0FBRyxDQUFDO0lBQ3JDO0lBRUFnbUMsYUFBYUEsQ0FBQ1osT0FBTyxFQUFFO01BQ3JCLElBQUksQ0FBQ2EsYUFBYSxDQUFDYixPQUFPLENBQUM7TUFDM0IsSUFBSSxDQUFDcjVCLE9BQU8sQ0FBQ3E1QixPQUFPLEdBQUc7UUFBRSxHQUFHLElBQUksQ0FBQ3I1QixPQUFPLENBQUNxNUIsT0FBTztRQUFFLEdBQUdBO09BQVM7TUFDOUQsT0FBTyxJQUFJO0lBQ2I7SUFFQWMsTUFBTUEsQ0FBQSxFQUFHO01BQ1AsTUFBTUMsZUFBZSxHQUFHcm5DLFFBQVEsQ0FBQzg3QixhQUFhLENBQUMsS0FBSyxDQUFDO01BQ3JEdUwsZUFBZSxDQUFDbEIsU0FBUyxHQUFHLElBQUksQ0FBQ21CLGNBQWMsQ0FBQyxJQUFJLENBQUNyNkIsT0FBTyxDQUFDeTVCLFFBQVEsQ0FBQztNQUV0RSxLQUFLLE1BQU0sQ0FBQzluQyxRQUFRLEVBQUUyb0MsSUFBSSxDQUFDLElBQUlqb0MsTUFBTSxDQUFDdUosT0FBTyxDQUFDLElBQUksQ0FBQ29FLE9BQU8sQ0FBQ3E1QixPQUFPLENBQUMsRUFBRTtRQUNuRSxJQUFJLENBQUNrQixXQUFXLENBQUNILGVBQWUsRUFBRUUsSUFBSSxFQUFFM29DLFFBQVEsQ0FBQztNQUNuRDtNQUVBLE1BQU04bkMsUUFBUSxHQUFHVyxlQUFlLENBQUMvNEIsUUFBUSxDQUFDLENBQUMsQ0FBQztNQUM1QyxNQUFNaTRCLFVBQVUsR0FBRyxJQUFJLENBQUNTLHdCQUF3QixDQUFDLElBQUksQ0FBQy81QixPQUFPLENBQUNzNUIsVUFBVSxDQUFDO01BRXpFLElBQUlBLFVBQVUsRUFBRTtRQUNkRyxRQUFRLENBQUMza0MsU0FBUyxDQUFDbVIsR0FBRyxDQUFDLEdBQUdxekIsVUFBVSxDQUFDN2xDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQztNQUNsRDtNQUVBLE9BQU9nbUMsUUFBUTtJQUNqQjs7SUFFQTtJQUNBdjZCLGdCQUFnQkEsQ0FBQ0gsTUFBTSxFQUFFO01BQ3ZCLEtBQUssQ0FBQ0csZ0JBQWdCLENBQUNILE1BQU0sQ0FBQztNQUM5QixJQUFJLENBQUNtN0IsYUFBYSxDQUFDbjdCLE1BQU0sQ0FBQ3M2QixPQUFPLENBQUM7SUFDcEM7SUFFQWEsYUFBYUEsQ0FBQ00sR0FBRyxFQUFFO01BQ2pCLEtBQUssTUFBTSxDQUFDN29DLFFBQVEsRUFBRTBuQyxPQUFPLENBQUMsSUFBSWhuQyxNQUFNLENBQUN1SixPQUFPLENBQUM0K0IsR0FBRyxDQUFDLEVBQUU7UUFDckQsS0FBSyxDQUFDdDdCLGdCQUFnQixDQUFDO1VBQUV2TixRQUFRO1VBQUVpb0MsS0FBSyxFQUFFUDtTQUFTLEVBQUVNLGtCQUFrQixDQUFDO01BQzFFO0lBQ0Y7SUFFQVksV0FBV0EsQ0FBQ2QsUUFBUSxFQUFFSixPQUFPLEVBQUUxbkMsUUFBUSxFQUFFO01BQ3ZDLE1BQU04b0MsZUFBZSxHQUFHeDVCLGNBQWMsQ0FBQ0csT0FBTyxDQUFDelAsUUFBUSxFQUFFOG5DLFFBQVEsQ0FBQztNQUVsRSxJQUFJLENBQUNnQixlQUFlLEVBQUU7UUFDcEI7TUFDRjtNQUVBcEIsT0FBTyxHQUFHLElBQUksQ0FBQ1Usd0JBQXdCLENBQUNWLE9BQU8sQ0FBQztNQUVoRCxJQUFJLENBQUNBLE9BQU8sRUFBRTtRQUNab0IsZUFBZSxDQUFDcHBDLE1BQU0sRUFBRTtRQUN4QjtNQUNGO01BRUEsSUFBSXdDLFdBQVMsQ0FBQ3dsQyxPQUFPLENBQUMsRUFBRTtRQUN0QixJQUFJLENBQUNxQixxQkFBcUIsQ0FBQzFtQyxVQUFVLENBQUNxbEMsT0FBTyxDQUFDLEVBQUVvQixlQUFlLENBQUM7UUFDaEU7TUFDRjtNQUVBLElBQUksSUFBSSxDQUFDejZCLE9BQU8sQ0FBQytiLElBQUksRUFBRTtRQUNyQjBlLGVBQWUsQ0FBQ3ZCLFNBQVMsR0FBRyxJQUFJLENBQUNtQixjQUFjLENBQUNoQixPQUFPLENBQUM7UUFDeEQ7TUFDRjtNQUVBb0IsZUFBZSxDQUFDRSxXQUFXLEdBQUd0QixPQUFPO0lBQ3ZDO0lBRUFnQixjQUFjQSxDQUFDRyxHQUFHLEVBQUU7TUFDbEIsT0FBTyxJQUFJLENBQUN4NkIsT0FBTyxDQUFDdTVCLFFBQVEsR0FBR2hCLFlBQVksQ0FBQ2lDLEdBQUcsRUFBRSxJQUFJLENBQUN4NkIsT0FBTyxDQUFDeTRCLFNBQVMsRUFBRSxJQUFJLENBQUN6NEIsT0FBTyxDQUFDdzVCLFVBQVUsQ0FBQyxHQUFHZ0IsR0FBRztJQUN6RztJQUVBVCx3QkFBd0JBLENBQUNTLEdBQUcsRUFBRTtNQUM1QixPQUFPdmpDLE9BQU8sQ0FBQ3VqQyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUM3QjtJQUVBRSxxQkFBcUJBLENBQUNqcUMsT0FBTyxFQUFFZ3FDLGVBQWUsRUFBRTtNQUM5QyxJQUFJLElBQUksQ0FBQ3o2QixPQUFPLENBQUMrYixJQUFJLEVBQUU7UUFDckIwZSxlQUFlLENBQUN2QixTQUFTLEdBQUcsRUFBRTtRQUM5QnVCLGVBQWUsQ0FBQzNMLE1BQU0sQ0FBQ3IrQixPQUFPLENBQUM7UUFDL0I7TUFDRjtNQUVBZ3FDLGVBQWUsQ0FBQ0UsV0FBVyxHQUFHbHFDLE9BQU8sQ0FBQ2txQyxXQUFXO0lBQ25EO0VBQ0Y7O0VDN0pBOzs7Ozs7O0VBaUJBOzs7O0VBSUEsTUFBTUMsTUFBSSxHQUFHLFNBQVM7RUFDdEIsTUFBTUMscUJBQXFCLEdBQUcsSUFBSXpoQyxHQUFHLENBQUMsQ0FBQyxVQUFVLEVBQUUsV0FBVyxFQUFFLFlBQVksQ0FBQyxDQUFDO0VBRTlFLE1BQU0waEMsaUJBQWUsR0FBRyxNQUFNO0VBQzlCLE1BQU1DLGdCQUFnQixHQUFHLE9BQU87RUFDaEMsTUFBTUMsaUJBQWUsR0FBRyxNQUFNO0VBRTlCLE1BQU1DLHNCQUFzQixHQUFHLGdCQUFnQjtFQUMvQyxNQUFNQyxjQUFjLEdBQUksSUFBR0gsZ0JBQWlCLEVBQUM7RUFFN0MsTUFBTUksZ0JBQWdCLEdBQUcsZUFBZTtFQUV4QyxNQUFNQyxhQUFhLEdBQUcsT0FBTztFQUM3QixNQUFNQyxhQUFhLEdBQUcsT0FBTztFQUM3QixNQUFNQyxhQUFhLEdBQUcsT0FBTztFQUM3QixNQUFNQyxjQUFjLEdBQUcsUUFBUTtFQUUvQixNQUFNQyxZQUFVLEdBQUcsTUFBTTtFQUN6QixNQUFNQyxjQUFZLEdBQUcsUUFBUTtFQUM3QixNQUFNQyxZQUFVLEdBQUcsTUFBTTtFQUN6QixNQUFNQyxhQUFXLEdBQUcsT0FBTztFQUMzQixNQUFNQyxjQUFjLEdBQUcsVUFBVTtFQUNqQyxNQUFNQyxhQUFXLEdBQUcsT0FBTztFQUMzQixNQUFNQyxlQUFhLEdBQUcsU0FBUztFQUMvQixNQUFNQyxnQkFBYyxHQUFHLFVBQVU7RUFDakMsTUFBTUMsZ0JBQWdCLEdBQUcsWUFBWTtFQUNyQyxNQUFNQyxnQkFBZ0IsR0FBRyxZQUFZO0VBRXJDLE1BQU1DLGFBQWEsR0FBRztJQUNwQkMsSUFBSSxFQUFFLE1BQU07SUFDWkMsR0FBRyxFQUFFLEtBQUs7SUFDVkMsS0FBSyxFQUFFaG1DLEtBQUssRUFBRSxHQUFHLE1BQU0sR0FBRyxPQUFPO0lBQ2pDaW1DLE1BQU0sRUFBRSxRQUFRO0lBQ2hCQyxJQUFJLEVBQUVsbUMsS0FBSyxFQUFFLEdBQUcsT0FBTyxHQUFHO0VBQzVCLENBQUM7RUFFRCxNQUFNbW1DLFNBQU8sR0FBRztJQUNkL0QsU0FBUyxFQUFFdkMsZ0JBQWdCO0lBQzNCdUcsU0FBUyxFQUFFLElBQUk7SUFDZi9lLFFBQVEsRUFBRSxpQkFBaUI7SUFDM0JnZixTQUFTLEVBQUUsS0FBSztJQUNoQkMsV0FBVyxFQUFFLEVBQUU7SUFDZkMsS0FBSyxFQUFFLENBQUM7SUFDUmhjLGtCQUFrQixFQUFFLENBQUMsS0FBSyxFQUFFLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxDQUFDO0lBQ3REN0UsSUFBSSxFQUFFLEtBQUs7SUFDWC9ELE1BQU0sRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUM7SUFDZC9ILFNBQVMsRUFBRSxLQUFLO0lBQ2hCMGIsWUFBWSxFQUFFLElBQUk7SUFDbEI0TixRQUFRLEVBQUUsSUFBSTtJQUNkQyxVQUFVLEVBQUUsSUFBSTtJQUNoQjduQyxRQUFRLEVBQUUsS0FBSztJQUNmOG5DLFFBQVEsRUFBRSxzQ0FBc0MsR0FDdEMsbUNBQW1DLEdBQ25DLG1DQUFtQyxHQUNuQyxRQUFRO0lBQ2xCb0QsS0FBSyxFQUFFLEVBQUU7SUFDVHZnQyxPQUFPLEVBQUU7RUFDWCxDQUFDO0VBRUQsTUFBTXdnQyxhQUFXLEdBQUc7SUFDbEJyRSxTQUFTLEVBQUUsUUFBUTtJQUNuQmdFLFNBQVMsRUFBRSxTQUFTO0lBQ3BCL2UsUUFBUSxFQUFFLGtCQUFrQjtJQUM1QmdmLFNBQVMsRUFBRSwwQkFBMEI7SUFDckNDLFdBQVcsRUFBRSxtQkFBbUI7SUFDaENDLEtBQUssRUFBRSxpQkFBaUI7SUFDeEJoYyxrQkFBa0IsRUFBRSxPQUFPO0lBQzNCN0UsSUFBSSxFQUFFLFNBQVM7SUFDZi9ELE1BQU0sRUFBRSx5QkFBeUI7SUFDakMvSCxTQUFTLEVBQUUsbUJBQW1CO0lBQzlCMGIsWUFBWSxFQUFFLHdCQUF3QjtJQUN0QzROLFFBQVEsRUFBRSxTQUFTO0lBQ25CQyxVQUFVLEVBQUUsaUJBQWlCO0lBQzdCN25DLFFBQVEsRUFBRSxrQkFBa0I7SUFDNUI4bkMsUUFBUSxFQUFFLFFBQVE7SUFDbEJvRCxLQUFLLEVBQUUsMkJBQTJCO0lBQ2xDdmdDLE9BQU8sRUFBRTtFQUNYLENBQUM7O0VBRUQ7Ozs7RUFJQSxNQUFNeWdDLE9BQU8sU0FBU2o5QixhQUFhLENBQUM7SUFDbENWLFdBQVdBLENBQUMzTyxPQUFPLEVBQUVzTyxNQUFNLEVBQUU7TUFDM0IsSUFBSSxPQUFPeXRCLE1BQU0sS0FBSyxXQUFXLEVBQUU7UUFDakMsTUFBTSxJQUFJN3NCLFNBQVMsQ0FBQyw4REFBOEQsQ0FBQztNQUNyRjtNQUVBLEtBQUssQ0FBQ2xQLE9BQU8sRUFBRXNPLE1BQU0sQ0FBQzs7TUFFdEI7TUFDQSxJQUFJLENBQUNpK0IsVUFBVSxHQUFHLElBQUk7TUFDdEIsSUFBSSxDQUFDQyxRQUFRLEdBQUcsQ0FBQztNQUNqQixJQUFJLENBQUNDLFVBQVUsR0FBRyxJQUFJO01BQ3RCLElBQUksQ0FBQ0MsY0FBYyxHQUFHLEVBQUU7TUFDeEIsSUFBSSxDQUFDclIsT0FBTyxHQUFHLElBQUk7TUFDbkIsSUFBSSxDQUFDc1IsZ0JBQWdCLEdBQUcsSUFBSTtNQUM1QixJQUFJLENBQUNDLFdBQVcsR0FBRyxJQUFJOztNQUV2QjtNQUNBLElBQUksQ0FBQ0MsR0FBRyxHQUFHLElBQUk7TUFFZixJQUFJLENBQUNDLGFBQWEsRUFBRTtNQUVwQixJQUFJLENBQUMsSUFBSSxDQUFDdjlCLE9BQU8sQ0FBQ3JPLFFBQVEsRUFBRTtRQUMxQixJQUFJLENBQUM2ckMsU0FBUyxFQUFFO01BQ2xCO0lBQ0Y7O0lBRUE7SUFDQSxXQUFXNytCLE9BQU9BLENBQUEsRUFBRztNQUNuQixPQUFPNjlCLFNBQU87SUFDaEI7SUFFQSxXQUFXNTlCLFdBQVdBLENBQUEsRUFBRztNQUN2QixPQUFPaytCLGFBQVc7SUFDcEI7SUFFQSxXQUFXbm1DLElBQUlBLENBQUEsRUFBRztNQUNoQixPQUFPaWtDLE1BQUk7SUFDYjs7SUFFQTtJQUNBNkMsTUFBTUEsQ0FBQSxFQUFHO01BQ1AsSUFBSSxDQUFDVCxVQUFVLEdBQUcsSUFBSTtJQUN4QjtJQUVBVSxPQUFPQSxDQUFBLEVBQUc7TUFDUixJQUFJLENBQUNWLFVBQVUsR0FBRyxLQUFLO0lBQ3pCO0lBRUFXLGFBQWFBLENBQUEsRUFBRztNQUNkLElBQUksQ0FBQ1gsVUFBVSxHQUFHLENBQUMsSUFBSSxDQUFDQSxVQUFVO0lBQ3BDO0lBRUFqNUIsTUFBTUEsQ0FBQSxFQUFHO01BQ1AsSUFBSSxDQUFDLElBQUksQ0FBQ2k1QixVQUFVLEVBQUU7UUFDcEI7TUFDRjtNQUVBLElBQUksQ0FBQ0csY0FBYyxDQUFDUyxLQUFLLEdBQUcsQ0FBQyxJQUFJLENBQUNULGNBQWMsQ0FBQ1MsS0FBSztNQUN0RCxJQUFJLElBQUksQ0FBQzN2QixRQUFRLEVBQUUsRUFBRTtRQUNuQixJQUFJLENBQUM0dkIsTUFBTSxFQUFFO1FBQ2I7TUFDRjtNQUVBLElBQUksQ0FBQ0MsTUFBTSxFQUFFO0lBQ2Y7SUFFQTU5QixPQUFPQSxDQUFBLEVBQUc7TUFDUnlLLFlBQVksQ0FBQyxJQUFJLENBQUNzeUIsUUFBUSxDQUFDO01BRTNCcGpDLFlBQVksQ0FBQ0MsR0FBRyxDQUFDLElBQUksQ0FBQ2lHLFFBQVEsQ0FBQ3ZMLE9BQU8sQ0FBQzBtQyxjQUFjLENBQUMsRUFBRUMsZ0JBQWdCLEVBQUUsSUFBSSxDQUFDNEMsaUJBQWlCLENBQUM7TUFFakcsSUFBSSxJQUFJLENBQUNoK0IsUUFBUSxDQUFDN0ssWUFBWSxDQUFDLHdCQUF3QixDQUFDLEVBQUU7UUFDeEQsSUFBSSxDQUFDNkssUUFBUSxDQUFDaEMsWUFBWSxDQUFDLE9BQU8sRUFBRSxJQUFJLENBQUNnQyxRQUFRLENBQUM3SyxZQUFZLENBQUMsd0JBQXdCLENBQUMsQ0FBQztNQUMzRjtNQUVBLElBQUksQ0FBQzhvQyxjQUFjLEVBQUU7TUFDckIsS0FBSyxDQUFDOTlCLE9BQU8sRUFBRTtJQUNqQjtJQUVBaU8sSUFBSUEsQ0FBQSxFQUFHO01BQ0wsSUFBSSxJQUFJLENBQUNwTyxRQUFRLENBQUMyTyxLQUFLLENBQUNnZCxPQUFPLEtBQUssTUFBTSxFQUFFO1FBQzFDLE1BQU0sSUFBSTdzQixLQUFLLENBQUMscUNBQXFDLENBQUM7TUFDeEQ7TUFFQSxJQUFJLEVBQUUsSUFBSSxDQUFDby9CLGNBQWMsRUFBRSxJQUFJLElBQUksQ0FBQ2pCLFVBQVUsQ0FBQyxFQUFFO1FBQy9DO01BQ0Y7TUFFQSxNQUFNN1EsU0FBUyxHQUFHdHlCLFlBQVksQ0FBQ3lDLE9BQU8sQ0FBQyxJQUFJLENBQUN5RCxRQUFRLEVBQUUsSUFBSSxDQUFDWCxXQUFXLENBQUNzQixTQUFTLENBQUNnN0IsWUFBVSxDQUFDLENBQUM7TUFDN0YsTUFBTXdDLFVBQVUsR0FBRy9vQyxjQUFjLENBQUMsSUFBSSxDQUFDNEssUUFBUSxDQUFDO01BQ2hELE1BQU1vK0IsVUFBVSxHQUFHLENBQUNELFVBQVUsSUFBSSxJQUFJLENBQUNuK0IsUUFBUSxDQUFDa1IsYUFBYSxDQUFDN2IsZUFBZSxFQUFFTCxRQUFRLENBQUMsSUFBSSxDQUFDZ0wsUUFBUSxDQUFDO01BRXRHLElBQUlvc0IsU0FBUyxDQUFDenZCLGdCQUFnQixJQUFJLENBQUN5aEMsVUFBVSxFQUFFO1FBQzdDO01BQ0Y7O01BRUE7TUFDQSxJQUFJLENBQUNILGNBQWMsRUFBRTtNQUVyQixNQUFNVixHQUFHLEdBQUcsSUFBSSxDQUFDYyxjQUFjLEVBQUU7TUFFakMsSUFBSSxDQUFDcitCLFFBQVEsQ0FBQ2hDLFlBQVksQ0FBQyxrQkFBa0IsRUFBRXUvQixHQUFHLENBQUNwb0MsWUFBWSxDQUFDLElBQUksQ0FBQyxDQUFDO01BRXRFLE1BQU07UUFBRXduQztPQUFXLEdBQUcsSUFBSSxDQUFDMThCLE9BQU87TUFFbEMsSUFBSSxDQUFDLElBQUksQ0FBQ0QsUUFBUSxDQUFDa1IsYUFBYSxDQUFDN2IsZUFBZSxDQUFDTCxRQUFRLENBQUMsSUFBSSxDQUFDdW9DLEdBQUcsQ0FBQyxFQUFFO1FBQ25FWixTQUFTLENBQUM1TixNQUFNLENBQUN3TyxHQUFHLENBQUM7UUFDckJ6akMsWUFBWSxDQUFDeUMsT0FBTyxDQUFDLElBQUksQ0FBQ3lELFFBQVEsRUFBRSxJQUFJLENBQUNYLFdBQVcsQ0FBQ3NCLFNBQVMsQ0FBQ2s3QixjQUFjLENBQUMsQ0FBQztNQUNqRjtNQUVBLElBQUksQ0FBQzlQLE9BQU8sR0FBRyxJQUFJLENBQUNNLGFBQWEsQ0FBQ2tSLEdBQUcsQ0FBQztNQUV0Q0EsR0FBRyxDQUFDeG9DLFNBQVMsQ0FBQ21SLEdBQUcsQ0FBQyswQixpQkFBZSxDQUFDOztNQUVsQztNQUNBO01BQ0E7TUFDQTtNQUNBLElBQUksY0FBYyxJQUFJam9DLFFBQVEsQ0FBQ3FDLGVBQWUsRUFBRTtRQUM5QyxLQUFLLE1BQU0zRSxPQUFPLElBQUksRUFBRSxDQUFDeVEsTUFBTSxDQUFDLEdBQUduTyxRQUFRLENBQUMrQyxJQUFJLENBQUN1TCxRQUFRLENBQUMsRUFBRTtVQUMxRHhILFlBQVksQ0FBQ2lDLEVBQUUsQ0FBQ3JMLE9BQU8sRUFBRSxXQUFXLEVBQUVnRixJQUFJLENBQUM7UUFDN0M7TUFDRjtNQUVBLE1BQU1rWixRQUFRLEdBQUdBLENBQUEsS0FBTTtRQUNyQjlVLFlBQVksQ0FBQ3lDLE9BQU8sQ0FBQyxJQUFJLENBQUN5RCxRQUFRLEVBQUUsSUFBSSxDQUFDWCxXQUFXLENBQUNzQixTQUFTLENBQUNpN0IsYUFBVyxDQUFDLENBQUM7UUFFNUUsSUFBSSxJQUFJLENBQUN1QixVQUFVLEtBQUssS0FBSyxFQUFFO1VBQzdCLElBQUksQ0FBQ1csTUFBTSxFQUFFO1FBQ2Y7UUFFQSxJQUFJLENBQUNYLFVBQVUsR0FBRyxLQUFLO09BQ3hCO01BRUQsSUFBSSxDQUFDNThCLGNBQWMsQ0FBQ3FPLFFBQVEsRUFBRSxJQUFJLENBQUMydUIsR0FBRyxFQUFFLElBQUksQ0FBQ3p4QixXQUFXLEVBQUUsQ0FBQztJQUM3RDtJQUVBcUMsSUFBSUEsQ0FBQSxFQUFHO01BQ0wsSUFBSSxDQUFDLElBQUksQ0FBQ0QsUUFBUSxFQUFFLEVBQUU7UUFDcEI7TUFDRjtNQUVBLE1BQU1zZSxTQUFTLEdBQUcxeUIsWUFBWSxDQUFDeUMsT0FBTyxDQUFDLElBQUksQ0FBQ3lELFFBQVEsRUFBRSxJQUFJLENBQUNYLFdBQVcsQ0FBQ3NCLFNBQVMsQ0FBQzg2QixZQUFVLENBQUMsQ0FBQztNQUM3RixJQUFJalAsU0FBUyxDQUFDN3ZCLGdCQUFnQixFQUFFO1FBQzlCO01BQ0Y7TUFFQSxNQUFNNGdDLEdBQUcsR0FBRyxJQUFJLENBQUNjLGNBQWMsRUFBRTtNQUNqQ2QsR0FBRyxDQUFDeG9DLFNBQVMsQ0FBQ3pELE1BQU0sQ0FBQzJwQyxpQkFBZSxDQUFDOztNQUVyQztNQUNBO01BQ0EsSUFBSSxjQUFjLElBQUlqb0MsUUFBUSxDQUFDcUMsZUFBZSxFQUFFO1FBQzlDLEtBQUssTUFBTTNFLE9BQU8sSUFBSSxFQUFFLENBQUN5USxNQUFNLENBQUMsR0FBR25PLFFBQVEsQ0FBQytDLElBQUksQ0FBQ3VMLFFBQVEsQ0FBQyxFQUFFO1VBQzFEeEgsWUFBWSxDQUFDQyxHQUFHLENBQUNySixPQUFPLEVBQUUsV0FBVyxFQUFFZ0YsSUFBSSxDQUFDO1FBQzlDO01BQ0Y7TUFFQSxJQUFJLENBQUMwbkMsY0FBYyxDQUFDN0IsYUFBYSxDQUFDLEdBQUcsS0FBSztNQUMxQyxJQUFJLENBQUM2QixjQUFjLENBQUM5QixhQUFhLENBQUMsR0FBRyxLQUFLO01BQzFDLElBQUksQ0FBQzhCLGNBQWMsQ0FBQy9CLGFBQWEsQ0FBQyxHQUFHLEtBQUs7TUFDMUMsSUFBSSxDQUFDOEIsVUFBVSxHQUFHLElBQUksQ0FBQzs7TUFFdkIsTUFBTXZ1QixRQUFRLEdBQUdBLENBQUEsS0FBTTtRQUNyQixJQUFJLElBQUksQ0FBQzB2QixvQkFBb0IsRUFBRSxFQUFFO1VBQy9CO1FBQ0Y7UUFFQSxJQUFJLENBQUMsSUFBSSxDQUFDbkIsVUFBVSxFQUFFO1VBQ3BCLElBQUksQ0FBQ2MsY0FBYyxFQUFFO1FBQ3ZCO1FBRUEsSUFBSSxDQUFDaitCLFFBQVEsQ0FBQzlCLGVBQWUsQ0FBQyxrQkFBa0IsQ0FBQztRQUNqRHBFLFlBQVksQ0FBQ3lDLE9BQU8sQ0FBQyxJQUFJLENBQUN5RCxRQUFRLEVBQUUsSUFBSSxDQUFDWCxXQUFXLENBQUNzQixTQUFTLENBQUMrNkIsY0FBWSxDQUFDLENBQUM7T0FDOUU7TUFFRCxJQUFJLENBQUNuN0IsY0FBYyxDQUFDcU8sUUFBUSxFQUFFLElBQUksQ0FBQzJ1QixHQUFHLEVBQUUsSUFBSSxDQUFDenhCLFdBQVcsRUFBRSxDQUFDO0lBQzdEO0lBRUFvUCxNQUFNQSxDQUFBLEVBQUc7TUFDUCxJQUFJLElBQUksQ0FBQzZRLE9BQU8sRUFBRTtRQUNoQixJQUFJLENBQUNBLE9BQU8sQ0FBQzdRLE1BQU0sRUFBRTtNQUN2QjtJQUNGOztJQUVBO0lBQ0FnakIsY0FBY0EsQ0FBQSxFQUFHO01BQ2YsT0FBTzFpQyxPQUFPLENBQUMsSUFBSSxDQUFDK2lDLFNBQVMsRUFBRSxDQUFDO0lBQ2xDO0lBRUFGLGNBQWNBLENBQUEsRUFBRztNQUNmLElBQUksQ0FBQyxJQUFJLENBQUNkLEdBQUcsRUFBRTtRQUNiLElBQUksQ0FBQ0EsR0FBRyxHQUFHLElBQUksQ0FBQ2lCLGlCQUFpQixDQUFDLElBQUksQ0FBQ2xCLFdBQVcsSUFBSSxJQUFJLENBQUNtQixzQkFBc0IsRUFBRSxDQUFDO01BQ3RGO01BRUEsT0FBTyxJQUFJLENBQUNsQixHQUFHO0lBQ2pCO0lBRUFpQixpQkFBaUJBLENBQUNsRixPQUFPLEVBQUU7TUFDekIsTUFBTWlFLEdBQUcsR0FBRyxJQUFJLENBQUNtQixtQkFBbUIsQ0FBQ3BGLE9BQU8sQ0FBQyxDQUFDYyxNQUFNLEVBQUU7O01BRXREO01BQ0EsSUFBSSxDQUFDbUQsR0FBRyxFQUFFO1FBQ1IsT0FBTyxJQUFJO01BQ2I7TUFFQUEsR0FBRyxDQUFDeG9DLFNBQVMsQ0FBQ3pELE1BQU0sQ0FBQ3lwQyxpQkFBZSxFQUFFRSxpQkFBZSxDQUFDO01BQ3REO01BQ0FzQyxHQUFHLENBQUN4b0MsU0FBUyxDQUFDbVIsR0FBRyxDQUFFLE1BQUssSUFBSSxDQUFDN0csV0FBVyxDQUFDekksSUFBSyxPQUFNLENBQUM7TUFFckQsTUFBTStuQyxLQUFLLEdBQUdoc0MsTUFBTSxDQUFDLElBQUksQ0FBQzBNLFdBQVcsQ0FBQ3pJLElBQUksQ0FBQyxDQUFDcEUsUUFBUSxFQUFFO01BRXREK3FDLEdBQUcsQ0FBQ3YvQixZQUFZLENBQUMsSUFBSSxFQUFFMmdDLEtBQUssQ0FBQztNQUU3QixJQUFJLElBQUksQ0FBQzd5QixXQUFXLEVBQUUsRUFBRTtRQUN0Qnl4QixHQUFHLENBQUN4b0MsU0FBUyxDQUFDbVIsR0FBRyxDQUFDNjBCLGlCQUFlLENBQUM7TUFDcEM7TUFFQSxPQUFPd0MsR0FBRztJQUNaO0lBRUFxQixVQUFVQSxDQUFDdEYsT0FBTyxFQUFFO01BQ2xCLElBQUksQ0FBQ2dFLFdBQVcsR0FBR2hFLE9BQU87TUFDMUIsSUFBSSxJQUFJLENBQUNwckIsUUFBUSxFQUFFLEVBQUU7UUFDbkIsSUFBSSxDQUFDK3ZCLGNBQWMsRUFBRTtRQUNyQixJQUFJLENBQUM3dkIsSUFBSSxFQUFFO01BQ2I7SUFDRjtJQUVBc3dCLG1CQUFtQkEsQ0FBQ3BGLE9BQU8sRUFBRTtNQUMzQixJQUFJLElBQUksQ0FBQytELGdCQUFnQixFQUFFO1FBQ3pCLElBQUksQ0FBQ0EsZ0JBQWdCLENBQUNuRCxhQUFhLENBQUNaLE9BQU8sQ0FBQztNQUM5QyxDQUFDLE1BQU07UUFDTCxJQUFJLENBQUMrRCxnQkFBZ0IsR0FBRyxJQUFJdkQsZUFBZSxDQUFDO1VBQzFDLEdBQUcsSUFBSSxDQUFDNzVCLE9BQU87VUFDZjtVQUNBO1VBQ0FxNUIsT0FBTztVQUNQQyxVQUFVLEVBQUUsSUFBSSxDQUFDUyx3QkFBd0IsQ0FBQyxJQUFJLENBQUMvNUIsT0FBTyxDQUFDMjhCLFdBQVc7UUFDcEUsQ0FBQyxDQUFDO01BQ0o7TUFFQSxPQUFPLElBQUksQ0FBQ1MsZ0JBQWdCO0lBQzlCO0lBRUFvQixzQkFBc0JBLENBQUEsRUFBRztNQUN2QixPQUFPO1FBQ0wsQ0FBQ3ZELHNCQUFzQixHQUFHLElBQUksQ0FBQ3FELFNBQVM7T0FDekM7SUFDSDtJQUVBQSxTQUFTQSxDQUFBLEVBQUc7TUFDVixPQUFPLElBQUksQ0FBQ3ZFLHdCQUF3QixDQUFDLElBQUksQ0FBQy81QixPQUFPLENBQUM2OEIsS0FBSyxDQUFDLElBQUksSUFBSSxDQUFDOThCLFFBQVEsQ0FBQzdLLFlBQVksQ0FBQyx3QkFBd0IsQ0FBQztJQUNsSDs7SUFFQTtJQUNBMHBDLDRCQUE0QkEsQ0FBQ25sQyxLQUFLLEVBQUU7TUFDbEMsT0FBTyxJQUFJLENBQUMyRixXQUFXLENBQUNxQixtQkFBbUIsQ0FBQ2hILEtBQUssQ0FBQ0UsY0FBYyxFQUFFLElBQUksQ0FBQ2tsQyxrQkFBa0IsRUFBRSxDQUFDO0lBQzlGO0lBRUFoekIsV0FBV0EsQ0FBQSxFQUFHO01BQ1osT0FBTyxJQUFJLENBQUM3TCxPQUFPLENBQUN5OEIsU0FBUyxJQUFLLElBQUksQ0FBQ2EsR0FBRyxJQUFJLElBQUksQ0FBQ0EsR0FBRyxDQUFDeG9DLFNBQVMsQ0FBQ0MsUUFBUSxDQUFDK2xDLGlCQUFlLENBQUU7SUFDN0Y7SUFFQTdzQixRQUFRQSxDQUFBLEVBQUc7TUFDVCxPQUFPLElBQUksQ0FBQ3F2QixHQUFHLElBQUksSUFBSSxDQUFDQSxHQUFHLENBQUN4b0MsU0FBUyxDQUFDQyxRQUFRLENBQUNpbUMsaUJBQWUsQ0FBQztJQUNqRTtJQUVBNU8sYUFBYUEsQ0FBQ2tSLEdBQUcsRUFBRTtNQUNqQixNQUFNcnRCLFNBQVMsR0FBR2haLE9BQU8sQ0FBQyxJQUFJLENBQUMrSSxPQUFPLENBQUNpUSxTQUFTLEVBQUUsQ0FBQyxJQUFJLEVBQUVxdEIsR0FBRyxFQUFFLElBQUksQ0FBQ3Y5QixRQUFRLENBQUMsQ0FBQztNQUM3RSxNQUFNKytCLFVBQVUsR0FBRzVDLGFBQWEsQ0FBQ2pzQixTQUFTLENBQUNyUSxXQUFXLEVBQUUsQ0FBQztNQUN6RCxPQUFPb29CLFlBQW1CLENBQUMsSUFBSSxDQUFDam9CLFFBQVEsRUFBRXU5QixHQUFHLEVBQUUsSUFBSSxDQUFDNVEsZ0JBQWdCLENBQUNvUyxVQUFVLENBQUMsQ0FBQztJQUNuRjtJQUVBaFMsVUFBVUEsQ0FBQSxFQUFHO01BQ1gsTUFBTTtRQUFFOVU7T0FBUSxHQUFHLElBQUksQ0FBQ2hZLE9BQU87TUFFL0IsSUFBSSxPQUFPZ1ksTUFBTSxLQUFLLFFBQVEsRUFBRTtRQUM5QixPQUFPQSxNQUFNLENBQUN2a0IsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDcU4sR0FBRyxDQUFDM0QsS0FBSyxJQUFJN0osTUFBTSxDQUFDNFgsUUFBUSxDQUFDL04sS0FBSyxFQUFFLEVBQUUsQ0FBQyxDQUFDO01BQ25FO01BRUEsSUFBSSxPQUFPNmEsTUFBTSxLQUFLLFVBQVUsRUFBRTtRQUNoQyxPQUFPK1UsVUFBVSxJQUFJL1UsTUFBTSxDQUFDK1UsVUFBVSxFQUFFLElBQUksQ0FBQ2h0QixRQUFRLENBQUM7TUFDeEQ7TUFFQSxPQUFPaVksTUFBTTtJQUNmO0lBRUEraEIsd0JBQXdCQSxDQUFDUyxHQUFHLEVBQUU7TUFDNUIsT0FBT3ZqQyxPQUFPLENBQUN1akMsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDejZCLFFBQVEsQ0FBQyxDQUFDO0lBQ3RDO0lBRUEyc0IsZ0JBQWdCQSxDQUFDb1MsVUFBVSxFQUFFO01BQzNCLE1BQU05UixxQkFBcUIsR0FBRztRQUM1Qi9jLFNBQVMsRUFBRTZ1QixVQUFVO1FBQ3JCelksU0FBUyxFQUFFLENBQ1Q7VUFDRTN2QixJQUFJLEVBQUUsTUFBTTtVQUNaMGIsT0FBTyxFQUFFO1lBQ1B3TyxrQkFBa0IsRUFBRSxJQUFJLENBQUM1Z0IsT0FBTyxDQUFDNGdCO1VBQ25DO1FBQ0YsQ0FBQyxFQUNEO1VBQ0VscUIsSUFBSSxFQUFFLFFBQVE7VUFDZDBiLE9BQU8sRUFBRTtZQUNQNEYsTUFBTSxFQUFFLElBQUksQ0FBQzhVLFVBQVU7VUFDekI7UUFDRixDQUFDLEVBQ0Q7VUFDRXAyQixJQUFJLEVBQUUsaUJBQWlCO1VBQ3ZCMGIsT0FBTyxFQUFFO1lBQ1BzTCxRQUFRLEVBQUUsSUFBSSxDQUFDMWQsT0FBTyxDQUFDMGQ7VUFDekI7UUFDRixDQUFDLEVBQ0Q7VUFDRWhuQixJQUFJLEVBQUUsT0FBTztVQUNiMGIsT0FBTyxFQUFFO1lBQ1AzaEIsT0FBTyxFQUFHLElBQUcsSUFBSSxDQUFDMk8sV0FBVyxDQUFDekksSUFBSztVQUNyQztRQUNGLENBQUMsRUFDRDtVQUNFRCxJQUFJLEVBQUUsaUJBQWlCO1VBQ3ZCa2MsT0FBTyxFQUFFLElBQUk7VUFDYkMsS0FBSyxFQUFFLFlBQVk7VUFDbkJoYyxFQUFFLEVBQUV5TSxJQUFJLElBQUk7WUFDVjtZQUNBO1lBQ0EsSUFBSSxDQUFDODZCLGNBQWMsRUFBRSxDQUFDcmdDLFlBQVksQ0FBQyx1QkFBdUIsRUFBRXVGLElBQUksQ0FBQ29PLEtBQUssQ0FBQ3pCLFNBQVMsQ0FBQztVQUNuRjtTQUNEO09BRUo7TUFFRCxPQUFPO1FBQ0wsR0FBRytjLHFCQUFxQjtRQUN4QixHQUFHLzFCLE9BQU8sQ0FBQyxJQUFJLENBQUMrSSxPQUFPLENBQUMyckIsWUFBWSxFQUFFLENBQUNxQixxQkFBcUIsQ0FBQztPQUM5RDtJQUNIO0lBRUF1USxhQUFhQSxDQUFBLEVBQUc7TUFDZCxNQUFNd0IsUUFBUSxHQUFHLElBQUksQ0FBQy8rQixPQUFPLENBQUMxRCxPQUFPLENBQUM3SSxLQUFLLENBQUMsR0FBRyxDQUFDO01BRWhELEtBQUssTUFBTTZJLE9BQU8sSUFBSXlpQyxRQUFRLEVBQUU7UUFDOUIsSUFBSXppQyxPQUFPLEtBQUssT0FBTyxFQUFFO1VBQ3ZCekMsWUFBWSxDQUFDaUMsRUFBRSxDQUFDLElBQUksQ0FBQ2lFLFFBQVEsRUFBRSxJQUFJLENBQUNYLFdBQVcsQ0FBQ3NCLFNBQVMsQ0FBQ203QixhQUFXLENBQUMsRUFBRSxJQUFJLENBQUM3N0IsT0FBTyxDQUFDck8sUUFBUSxFQUFFOEgsS0FBSyxJQUFJO1lBQ3RHLE1BQU00ekIsT0FBTyxHQUFHLElBQUksQ0FBQ3VSLDRCQUE0QixDQUFDbmxDLEtBQUssQ0FBQztZQUN4RDR6QixPQUFPLENBQUN0cEIsTUFBTSxFQUFFO1VBQ2xCLENBQUMsQ0FBQztRQUNKLENBQUMsTUFBTSxJQUFJekgsT0FBTyxLQUFLaS9CLGNBQWMsRUFBRTtVQUNyQyxNQUFNeUQsT0FBTyxHQUFHMWlDLE9BQU8sS0FBSzgrQixhQUFhLEdBQ3ZDLElBQUksQ0FBQ2g4QixXQUFXLENBQUNzQixTQUFTLENBQUNzN0IsZ0JBQWdCLENBQUMsR0FDNUMsSUFBSSxDQUFDNThCLFdBQVcsQ0FBQ3NCLFNBQVMsQ0FBQ283QixlQUFhLENBQUM7VUFDM0MsTUFBTW1ELFFBQVEsR0FBRzNpQyxPQUFPLEtBQUs4K0IsYUFBYSxHQUN4QyxJQUFJLENBQUNoOEIsV0FBVyxDQUFDc0IsU0FBUyxDQUFDdTdCLGdCQUFnQixDQUFDLEdBQzVDLElBQUksQ0FBQzc4QixXQUFXLENBQUNzQixTQUFTLENBQUNxN0IsZ0JBQWMsQ0FBQztVQUU1Q2xpQyxZQUFZLENBQUNpQyxFQUFFLENBQUMsSUFBSSxDQUFDaUUsUUFBUSxFQUFFaS9CLE9BQU8sRUFBRSxJQUFJLENBQUNoL0IsT0FBTyxDQUFDck8sUUFBUSxFQUFFOEgsS0FBSyxJQUFJO1lBQ3RFLE1BQU00ekIsT0FBTyxHQUFHLElBQUksQ0FBQ3VSLDRCQUE0QixDQUFDbmxDLEtBQUssQ0FBQztZQUN4RDR6QixPQUFPLENBQUM4UCxjQUFjLENBQUMxakMsS0FBSyxDQUFDTSxJQUFJLEtBQUssU0FBUyxHQUFHc2hDLGFBQWEsR0FBR0QsYUFBYSxDQUFDLEdBQUcsSUFBSTtZQUN2Ri9OLE9BQU8sQ0FBQ3lRLE1BQU0sRUFBRTtVQUNsQixDQUFDLENBQUM7VUFDRmprQyxZQUFZLENBQUNpQyxFQUFFLENBQUMsSUFBSSxDQUFDaUUsUUFBUSxFQUFFay9CLFFBQVEsRUFBRSxJQUFJLENBQUNqL0IsT0FBTyxDQUFDck8sUUFBUSxFQUFFOEgsS0FBSyxJQUFJO1lBQ3ZFLE1BQU00ekIsT0FBTyxHQUFHLElBQUksQ0FBQ3VSLDRCQUE0QixDQUFDbmxDLEtBQUssQ0FBQztZQUN4RDR6QixPQUFPLENBQUM4UCxjQUFjLENBQUMxakMsS0FBSyxDQUFDTSxJQUFJLEtBQUssVUFBVSxHQUFHc2hDLGFBQWEsR0FBR0QsYUFBYSxDQUFDLEdBQy9FL04sT0FBTyxDQUFDdHRCLFFBQVEsQ0FBQ2hMLFFBQVEsQ0FBQzBFLEtBQUssQ0FBQzBCLGFBQWEsQ0FBQztZQUVoRGt5QixPQUFPLENBQUN3USxNQUFNLEVBQUU7VUFDbEIsQ0FBQyxDQUFDO1FBQ0o7TUFDRjtNQUVBLElBQUksQ0FBQ0UsaUJBQWlCLEdBQUcsTUFBTTtRQUM3QixJQUFJLElBQUksQ0FBQ2grQixRQUFRLEVBQUU7VUFDakIsSUFBSSxDQUFDbU8sSUFBSSxFQUFFO1FBQ2I7T0FDRDtNQUVEclUsWUFBWSxDQUFDaUMsRUFBRSxDQUFDLElBQUksQ0FBQ2lFLFFBQVEsQ0FBQ3ZMLE9BQU8sQ0FBQzBtQyxjQUFjLENBQUMsRUFBRUMsZ0JBQWdCLEVBQUUsSUFBSSxDQUFDNEMsaUJBQWlCLENBQUM7SUFDbEc7SUFFQVAsU0FBU0EsQ0FBQSxFQUFHO01BQ1YsTUFBTVgsS0FBSyxHQUFHLElBQUksQ0FBQzk4QixRQUFRLENBQUM3SyxZQUFZLENBQUMsT0FBTyxDQUFDO01BRWpELElBQUksQ0FBQzJuQyxLQUFLLEVBQUU7UUFDVjtNQUNGO01BRUEsSUFBSSxDQUFDLElBQUksQ0FBQzk4QixRQUFRLENBQUM3SyxZQUFZLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUM2SyxRQUFRLENBQUM0NkIsV0FBVyxDQUFDOTVCLElBQUksRUFBRSxFQUFFO1FBQ2xGLElBQUksQ0FBQ2QsUUFBUSxDQUFDaEMsWUFBWSxDQUFDLFlBQVksRUFBRTgrQixLQUFLLENBQUM7TUFDakQ7TUFFQSxJQUFJLENBQUM5OEIsUUFBUSxDQUFDaEMsWUFBWSxDQUFDLHdCQUF3QixFQUFFOCtCLEtBQUssQ0FBQyxDQUFDO01BQzVELElBQUksQ0FBQzk4QixRQUFRLENBQUM5QixlQUFlLENBQUMsT0FBTyxDQUFDO0lBQ3hDO0lBRUE2L0IsTUFBTUEsQ0FBQSxFQUFHO01BQ1AsSUFBSSxJQUFJLENBQUM3dkIsUUFBUSxFQUFFLElBQUksSUFBSSxDQUFDaXZCLFVBQVUsRUFBRTtRQUN0QyxJQUFJLENBQUNBLFVBQVUsR0FBRyxJQUFJO1FBQ3RCO01BQ0Y7TUFFQSxJQUFJLENBQUNBLFVBQVUsR0FBRyxJQUFJO01BRXRCLElBQUksQ0FBQ2dDLFdBQVcsQ0FBQyxNQUFNO1FBQ3JCLElBQUksSUFBSSxDQUFDaEMsVUFBVSxFQUFFO1VBQ25CLElBQUksQ0FBQy91QixJQUFJLEVBQUU7UUFDYjtPQUNELEVBQUUsSUFBSSxDQUFDbk8sT0FBTyxDQUFDNDhCLEtBQUssQ0FBQ3p1QixJQUFJLENBQUM7SUFDN0I7SUFFQTB2QixNQUFNQSxDQUFBLEVBQUc7TUFDUCxJQUFJLElBQUksQ0FBQ1Esb0JBQW9CLEVBQUUsRUFBRTtRQUMvQjtNQUNGO01BRUEsSUFBSSxDQUFDbkIsVUFBVSxHQUFHLEtBQUs7TUFFdkIsSUFBSSxDQUFDZ0MsV0FBVyxDQUFDLE1BQU07UUFDckIsSUFBSSxDQUFDLElBQUksQ0FBQ2hDLFVBQVUsRUFBRTtVQUNwQixJQUFJLENBQUNodkIsSUFBSSxFQUFFO1FBQ2I7T0FDRCxFQUFFLElBQUksQ0FBQ2xPLE9BQU8sQ0FBQzQ4QixLQUFLLENBQUMxdUIsSUFBSSxDQUFDO0lBQzdCO0lBRUFneEIsV0FBV0EsQ0FBQ3RuQyxPQUFPLEVBQUV1bkMsT0FBTyxFQUFFO01BQzVCeDBCLFlBQVksQ0FBQyxJQUFJLENBQUNzeUIsUUFBUSxDQUFDO01BQzNCLElBQUksQ0FBQ0EsUUFBUSxHQUFHamxDLFVBQVUsQ0FBQ0osT0FBTyxFQUFFdW5DLE9BQU8sQ0FBQztJQUM5QztJQUVBZCxvQkFBb0JBLENBQUEsRUFBRztNQUNyQixPQUFPaHNDLE1BQU0sQ0FBQ29JLE1BQU0sQ0FBQyxJQUFJLENBQUMwaUMsY0FBYyxDQUFDLENBQUN0aEMsUUFBUSxDQUFDLElBQUksQ0FBQztJQUMxRDtJQUVBaUQsVUFBVUEsQ0FBQ0MsTUFBTSxFQUFFO01BQ2pCLE1BQU1xZ0MsY0FBYyxHQUFHdmhDLFdBQVcsQ0FBQ0ssaUJBQWlCLENBQUMsSUFBSSxDQUFDNkIsUUFBUSxDQUFDO01BRW5FLEtBQUssTUFBTXMvQixhQUFhLElBQUlodEMsTUFBTSxDQUFDakIsSUFBSSxDQUFDZ3VDLGNBQWMsQ0FBQyxFQUFFO1FBQ3ZELElBQUl2RSxxQkFBcUIsQ0FBQ2pxQyxHQUFHLENBQUN5dUMsYUFBYSxDQUFDLEVBQUU7VUFDNUMsT0FBT0QsY0FBYyxDQUFDQyxhQUFhLENBQUM7UUFDdEM7TUFDRjtNQUVBdGdDLE1BQU0sR0FBRztRQUNQLEdBQUdxZ0MsY0FBYztRQUNqQixJQUFJLE9BQU9yZ0MsTUFBTSxLQUFLLFFBQVEsSUFBSUEsTUFBTSxHQUFHQSxNQUFNLEdBQUcsRUFBRTtPQUN2RDtNQUNEQSxNQUFNLEdBQUcsSUFBSSxDQUFDQyxlQUFlLENBQUNELE1BQU0sQ0FBQztNQUNyQ0EsTUFBTSxHQUFHLElBQUksQ0FBQ0UsaUJBQWlCLENBQUNGLE1BQU0sQ0FBQztNQUN2QyxJQUFJLENBQUNHLGdCQUFnQixDQUFDSCxNQUFNLENBQUM7TUFDN0IsT0FBT0EsTUFBTTtJQUNmO0lBRUFFLGlCQUFpQkEsQ0FBQ0YsTUFBTSxFQUFFO01BQ3hCQSxNQUFNLENBQUMyOUIsU0FBUyxHQUFHMzlCLE1BQU0sQ0FBQzI5QixTQUFTLEtBQUssS0FBSyxHQUFHM3BDLFFBQVEsQ0FBQytDLElBQUksR0FBRzlCLFVBQVUsQ0FBQytLLE1BQU0sQ0FBQzI5QixTQUFTLENBQUM7TUFFNUYsSUFBSSxPQUFPMzlCLE1BQU0sQ0FBQzY5QixLQUFLLEtBQUssUUFBUSxFQUFFO1FBQ3BDNzlCLE1BQU0sQ0FBQzY5QixLQUFLLEdBQUc7VUFDYnp1QixJQUFJLEVBQUVwUCxNQUFNLENBQUM2OUIsS0FBSztVQUNsQjF1QixJQUFJLEVBQUVuUCxNQUFNLENBQUM2OUI7U0FDZDtNQUNIO01BRUEsSUFBSSxPQUFPNzlCLE1BQU0sQ0FBQzg5QixLQUFLLEtBQUssUUFBUSxFQUFFO1FBQ3BDOTlCLE1BQU0sQ0FBQzg5QixLQUFLLEdBQUc5OUIsTUFBTSxDQUFDODlCLEtBQUssQ0FBQ3RxQyxRQUFRLEVBQUU7TUFDeEM7TUFFQSxJQUFJLE9BQU93TSxNQUFNLENBQUNzNkIsT0FBTyxLQUFLLFFBQVEsRUFBRTtRQUN0Q3Q2QixNQUFNLENBQUNzNkIsT0FBTyxHQUFHdDZCLE1BQU0sQ0FBQ3M2QixPQUFPLENBQUM5bUMsUUFBUSxFQUFFO01BQzVDO01BRUEsT0FBT3dNLE1BQU07SUFDZjtJQUVBOC9CLGtCQUFrQkEsQ0FBQSxFQUFHO01BQ25CLE1BQU05L0IsTUFBTSxHQUFHLEVBQUU7TUFFakIsS0FBSyxNQUFNLENBQUNyTyxHQUFHLEVBQUV5TSxLQUFLLENBQUMsSUFBSTlLLE1BQU0sQ0FBQ3VKLE9BQU8sQ0FBQyxJQUFJLENBQUNvRSxPQUFPLENBQUMsRUFBRTtRQUN2RCxJQUFJLElBQUksQ0FBQ1osV0FBVyxDQUFDVCxPQUFPLENBQUNqTyxHQUFHLENBQUMsS0FBS3lNLEtBQUssRUFBRTtVQUMzQzRCLE1BQU0sQ0FBQ3JPLEdBQUcsQ0FBQyxHQUFHeU0sS0FBSztRQUNyQjtNQUNGO01BRUE0QixNQUFNLENBQUNwTixRQUFRLEdBQUcsS0FBSztNQUN2Qm9OLE1BQU0sQ0FBQ3pDLE9BQU8sR0FBRyxRQUFROztNQUV6QjtNQUNBO01BQ0E7TUFDQSxPQUFPeUMsTUFBTTtJQUNmO0lBRUFpL0IsY0FBY0EsQ0FBQSxFQUFHO01BQ2YsSUFBSSxJQUFJLENBQUNsUyxPQUFPLEVBQUU7UUFDaEIsSUFBSSxDQUFDQSxPQUFPLENBQUNsRCxPQUFPLEVBQUU7UUFDdEIsSUFBSSxDQUFDa0QsT0FBTyxHQUFHLElBQUk7TUFDckI7TUFFQSxJQUFJLElBQUksQ0FBQ3dSLEdBQUcsRUFBRTtRQUNaLElBQUksQ0FBQ0EsR0FBRyxDQUFDanNDLE1BQU0sRUFBRTtRQUNqQixJQUFJLENBQUNpc0MsR0FBRyxHQUFHLElBQUk7TUFDakI7SUFDRjs7SUFFQTtJQUNBLE9BQU94bUMsZUFBZUEsQ0FBQ2lJLE1BQU0sRUFBRTtNQUM3QixPQUFPLElBQUksQ0FBQ3NFLElBQUksQ0FBQyxZQUFZO1FBQzNCLE1BQU1DLElBQUksR0FBR3k1QixPQUFPLENBQUN0OEIsbUJBQW1CLENBQUMsSUFBSSxFQUFFMUIsTUFBTSxDQUFDO1FBRXRELElBQUksT0FBT0EsTUFBTSxLQUFLLFFBQVEsRUFBRTtVQUM5QjtRQUNGO1FBRUEsSUFBSSxPQUFPdUUsSUFBSSxDQUFDdkUsTUFBTSxDQUFDLEtBQUssV0FBVyxFQUFFO1VBQ3ZDLE1BQU0sSUFBSVksU0FBUyxDQUFFLG9CQUFtQlosTUFBTyxHQUFFLENBQUM7UUFDcEQ7UUFFQXVFLElBQUksQ0FBQ3ZFLE1BQU0sQ0FBQyxFQUFFO01BQ2hCLENBQUMsQ0FBQztJQUNKO0VBQ0Y7O0VBRUE7Ozs7RUFJQXhJLGtCQUFrQixDQUFDd21DLE9BQU8sQ0FBQzs7RUN0bkIzQjs7Ozs7OztFQVVBOzs7O0VBSUEsTUFBTXVDLE1BQUksR0FBRyxTQUFTO0VBRXRCLE1BQU1DLGNBQWMsR0FBRyxpQkFBaUI7RUFDeEMsTUFBTUMsZ0JBQWdCLEdBQUcsZUFBZTtFQUV4QyxNQUFNQyxTQUFPLEdBQUc7SUFDZCxHQUFHMUMsT0FBTyxDQUFDcCtCLE9BQU87SUFDbEIwNkIsT0FBTyxFQUFFLEVBQUU7SUFDWHJoQixNQUFNLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDO0lBQ2QvSCxTQUFTLEVBQUUsT0FBTztJQUNsQndwQixRQUFRLEVBQUUsc0NBQXNDLEdBQzlDLG1DQUFtQyxHQUNuQyxrQ0FBa0MsR0FDbEMsa0NBQWtDLEdBQ2xDLFFBQVE7SUFDVm45QixPQUFPLEVBQUU7RUFDWCxDQUFDO0VBRUQsTUFBTW9qQyxhQUFXLEdBQUc7SUFDbEIsR0FBRzNDLE9BQU8sQ0FBQ24rQixXQUFXO0lBQ3RCeTZCLE9BQU8sRUFBRTtFQUNYLENBQUM7O0VBRUQ7Ozs7RUFJQSxNQUFNc0csT0FBTyxTQUFTNUMsT0FBTyxDQUFDO0lBQzVCO0lBQ0EsV0FBV3ArQixPQUFPQSxDQUFBLEVBQUc7TUFDbkIsT0FBTzhnQyxTQUFPO0lBQ2hCO0lBRUEsV0FBVzdnQyxXQUFXQSxDQUFBLEVBQUc7TUFDdkIsT0FBTzhnQyxhQUFXO0lBQ3BCO0lBRUEsV0FBVy9vQyxJQUFJQSxDQUFBLEVBQUc7TUFDaEIsT0FBTzJvQyxNQUFJO0lBQ2I7O0lBRUE7SUFDQXJCLGNBQWNBLENBQUEsRUFBRztNQUNmLE9BQU8sSUFBSSxDQUFDSyxTQUFTLEVBQUUsSUFBSSxJQUFJLENBQUNzQixXQUFXLEVBQUU7SUFDL0M7O0lBRUE7SUFDQXBCLHNCQUFzQkEsQ0FBQSxFQUFHO01BQ3ZCLE9BQU87UUFDTCxDQUFDZSxjQUFjLEdBQUcsSUFBSSxDQUFDakIsU0FBUyxFQUFFO1FBQ2xDLENBQUNrQixnQkFBZ0IsR0FBRyxJQUFJLENBQUNJLFdBQVc7T0FDckM7SUFDSDtJQUVBQSxXQUFXQSxDQUFBLEVBQUc7TUFDWixPQUFPLElBQUksQ0FBQzdGLHdCQUF3QixDQUFDLElBQUksQ0FBQy81QixPQUFPLENBQUNxNUIsT0FBTyxDQUFDO0lBQzVEOztJQUVBO0lBQ0EsT0FBT3ZpQyxlQUFlQSxDQUFDaUksTUFBTSxFQUFFO01BQzdCLE9BQU8sSUFBSSxDQUFDc0UsSUFBSSxDQUFDLFlBQVk7UUFDM0IsTUFBTUMsSUFBSSxHQUFHcThCLE9BQU8sQ0FBQ2wvQixtQkFBbUIsQ0FBQyxJQUFJLEVBQUUxQixNQUFNLENBQUM7UUFFdEQsSUFBSSxPQUFPQSxNQUFNLEtBQUssUUFBUSxFQUFFO1VBQzlCO1FBQ0Y7UUFFQSxJQUFJLE9BQU91RSxJQUFJLENBQUN2RSxNQUFNLENBQUMsS0FBSyxXQUFXLEVBQUU7VUFDdkMsTUFBTSxJQUFJWSxTQUFTLENBQUUsb0JBQW1CWixNQUFPLEdBQUUsQ0FBQztRQUNwRDtRQUVBdUUsSUFBSSxDQUFDdkUsTUFBTSxDQUFDLEVBQUU7TUFDaEIsQ0FBQyxDQUFDO0lBQ0o7RUFDRjs7RUFFQTs7OztFQUlBeEksa0JBQWtCLENBQUNvcEMsT0FBTyxDQUFDOztFQzlGM0I7Ozs7Ozs7RUFjQTs7OztFQUlBLE1BQU1FLE1BQUksR0FBRyxXQUFXO0VBQ3hCLE1BQU1DLFVBQVEsR0FBRyxjQUFjO0VBQy9CLE1BQU1DLFdBQVMsR0FBSSxJQUFHRCxVQUFTLEVBQUM7RUFDaEMsTUFBTUUsWUFBWSxHQUFHLFdBQVc7RUFFaEMsTUFBTUMsY0FBYyxHQUFJLFdBQVVGLFdBQVUsRUFBQztFQUM3QyxNQUFNRyxXQUFXLEdBQUksUUFBT0gsV0FBVSxFQUFDO0VBQ3ZDLE1BQU1JLHFCQUFtQixHQUFJLE9BQU1KLFdBQVUsR0FBRUMsWUFBYSxFQUFDO0VBRTdELE1BQU1JLHdCQUF3QixHQUFHLGVBQWU7RUFDaEQsTUFBTUMsbUJBQWlCLEdBQUcsUUFBUTtFQUVsQyxNQUFNQyxpQkFBaUIsR0FBRyx3QkFBd0I7RUFDbEQsTUFBTUMscUJBQXFCLEdBQUcsUUFBUTtFQUN0QyxNQUFNQyx1QkFBdUIsR0FBRyxtQkFBbUI7RUFDbkQsTUFBTUMsa0JBQWtCLEdBQUcsV0FBVztFQUN0QyxNQUFNQyxrQkFBa0IsR0FBRyxXQUFXO0VBQ3RDLE1BQU1DLG1CQUFtQixHQUFHLGtCQUFrQjtFQUM5QyxNQUFNQyxtQkFBbUIsR0FBSSxHQUFFSCxrQkFBbUIsS0FBSUMsa0JBQW1CLE1BQUtELGtCQUFtQixLQUFJRSxtQkFBb0IsRUFBQztFQUMxSCxNQUFNRSxpQkFBaUIsR0FBRyxXQUFXO0VBQ3JDLE1BQU1DLDBCQUF3QixHQUFHLGtCQUFrQjtFQUVuRCxNQUFNQyxTQUFPLEdBQUc7SUFDZC9vQixNQUFNLEVBQUUsSUFBSTtJQUFFO0lBQ2RncEIsVUFBVSxFQUFFLGNBQWM7SUFDMUJDLFlBQVksRUFBRSxLQUFLO0lBQ25CbnBDLE1BQU0sRUFBRSxJQUFJO0lBQ1pvcEMsU0FBUyxFQUFFLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxDQUFDO0VBQ3pCLENBQUM7RUFFRCxNQUFNQyxhQUFXLEdBQUc7SUFDbEJucEIsTUFBTSxFQUFFLGVBQWU7SUFBRTtJQUN6QmdwQixVQUFVLEVBQUUsUUFBUTtJQUNwQkMsWUFBWSxFQUFFLFNBQVM7SUFDdkJucEMsTUFBTSxFQUFFLFNBQVM7SUFDakJvcEMsU0FBUyxFQUFFO0VBQ2IsQ0FBQzs7RUFFRDs7OztFQUlBLE1BQU1FLFNBQVMsU0FBU3RoQyxhQUFhLENBQUM7SUFDcENWLFdBQVdBLENBQUMzTyxPQUFPLEVBQUVzTyxNQUFNLEVBQUU7TUFDM0IsS0FBSyxDQUFDdE8sT0FBTyxFQUFFc08sTUFBTSxDQUFDOztNQUV0QjtNQUNBLElBQUksQ0FBQ3NpQyxZQUFZLEdBQUcsSUFBSS93QyxHQUFHLEVBQUU7TUFDN0IsSUFBSSxDQUFDZ3hDLG1CQUFtQixHQUFHLElBQUloeEMsR0FBRyxFQUFFO01BQ3BDLElBQUksQ0FBQ2l4QyxZQUFZLEdBQUdudUMsZ0JBQWdCLENBQUMsSUFBSSxDQUFDMk0sUUFBUSxDQUFDLENBQUMyYyxTQUFTLEtBQUssU0FBUyxHQUFHLElBQUksR0FBRyxJQUFJLENBQUMzYyxRQUFRO01BQ2xHLElBQUksQ0FBQ3loQyxhQUFhLEdBQUcsSUFBSTtNQUN6QixJQUFJLENBQUNDLFNBQVMsR0FBRyxJQUFJO01BQ3JCLElBQUksQ0FBQ0MsbUJBQW1CLEdBQUc7UUFDekJDLGVBQWUsRUFBRSxDQUFDO1FBQ2xCQyxlQUFlLEVBQUU7T0FDbEI7TUFDRCxJQUFJLENBQUNDLE9BQU8sRUFBRSxDQUFDO0lBQ2pCOztJQUVBO0lBQ0EsV0FBV2xqQyxPQUFPQSxDQUFBLEVBQUc7TUFDbkIsT0FBT29pQyxTQUFPO0lBQ2hCO0lBRUEsV0FBV25pQyxXQUFXQSxDQUFBLEVBQUc7TUFDdkIsT0FBT3VpQyxhQUFXO0lBQ3BCO0lBRUEsV0FBV3hxQyxJQUFJQSxDQUFBLEVBQUc7TUFDaEIsT0FBT2twQyxNQUFJO0lBQ2I7O0lBRUE7SUFDQWdDLE9BQU9BLENBQUEsRUFBRztNQUNSLElBQUksQ0FBQ0MsZ0NBQWdDLEVBQUU7TUFDdkMsSUFBSSxDQUFDQyx3QkFBd0IsRUFBRTtNQUUvQixJQUFJLElBQUksQ0FBQ04sU0FBUyxFQUFFO1FBQ2xCLElBQUksQ0FBQ0EsU0FBUyxDQUFDTyxVQUFVLEVBQUU7TUFDN0IsQ0FBQyxNQUFNO1FBQ0wsSUFBSSxDQUFDUCxTQUFTLEdBQUcsSUFBSSxDQUFDUSxlQUFlLEVBQUU7TUFDekM7TUFFQSxLQUFLLE1BQU1DLE9BQU8sSUFBSSxJQUFJLENBQUNaLG1CQUFtQixDQUFDN21DLE1BQU0sRUFBRSxFQUFFO1FBQ3ZELElBQUksQ0FBQ2duQyxTQUFTLENBQUNVLE9BQU8sQ0FBQ0QsT0FBTyxDQUFDO01BQ2pDO0lBQ0Y7SUFFQWhpQyxPQUFPQSxDQUFBLEVBQUc7TUFDUixJQUFJLENBQUN1aEMsU0FBUyxDQUFDTyxVQUFVLEVBQUU7TUFDM0IsS0FBSyxDQUFDOWhDLE9BQU8sRUFBRTtJQUNqQjs7SUFFQTtJQUNBakIsaUJBQWlCQSxDQUFDRixNQUFNLEVBQUU7TUFDeEI7TUFDQUEsTUFBTSxDQUFDakgsTUFBTSxHQUFHOUQsVUFBVSxDQUFDK0ssTUFBTSxDQUFDakgsTUFBTSxDQUFDLElBQUkvRSxRQUFRLENBQUMrQyxJQUFJOztNQUUxRDtNQUNBaUosTUFBTSxDQUFDaWlDLFVBQVUsR0FBR2ppQyxNQUFNLENBQUNpWixNQUFNLEdBQUksR0FBRWpaLE1BQU0sQ0FBQ2laLE1BQU8sYUFBWSxHQUFHalosTUFBTSxDQUFDaWlDLFVBQVU7TUFFckYsSUFBSSxPQUFPamlDLE1BQU0sQ0FBQ21pQyxTQUFTLEtBQUssUUFBUSxFQUFFO1FBQ3hDbmlDLE1BQU0sQ0FBQ21pQyxTQUFTLEdBQUduaUMsTUFBTSxDQUFDbWlDLFNBQVMsQ0FBQ3p0QyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUNxTixHQUFHLENBQUMzRCxLQUFLLElBQUk3SixNQUFNLENBQUNDLFVBQVUsQ0FBQzRKLEtBQUssQ0FBQyxDQUFDO01BQ3ZGO01BRUEsT0FBTzRCLE1BQU07SUFDZjtJQUVBZ2pDLHdCQUF3QkEsQ0FBQSxFQUFHO01BQ3pCLElBQUksQ0FBQyxJQUFJLENBQUMvaEMsT0FBTyxDQUFDaWhDLFlBQVksRUFBRTtRQUM5QjtNQUNGOztNQUVBO01BQ0FwbkMsWUFBWSxDQUFDQyxHQUFHLENBQUMsSUFBSSxDQUFDa0csT0FBTyxDQUFDbEksTUFBTSxFQUFFb29DLFdBQVcsQ0FBQztNQUVsRHJtQyxZQUFZLENBQUNpQyxFQUFFLENBQUMsSUFBSSxDQUFDa0UsT0FBTyxDQUFDbEksTUFBTSxFQUFFb29DLFdBQVcsRUFBRUsscUJBQXFCLEVBQUU5bUMsS0FBSyxJQUFJO1FBQ2hGLE1BQU0yb0MsaUJBQWlCLEdBQUcsSUFBSSxDQUFDZCxtQkFBbUIsQ0FBQ3h3QyxHQUFHLENBQUMySSxLQUFLLENBQUMzQixNQUFNLENBQUN3akIsSUFBSSxDQUFDO1FBQ3pFLElBQUk4bUIsaUJBQWlCLEVBQUU7VUFDckIzb0MsS0FBSyxDQUFDdUQsY0FBYyxFQUFFO1VBQ3RCLE1BQU16SCxJQUFJLEdBQUcsSUFBSSxDQUFDZ3NDLFlBQVksSUFBSTN2QyxNQUFNO1VBQ3hDLE1BQU1zaUIsTUFBTSxHQUFHa3VCLGlCQUFpQixDQUFDNXRCLFNBQVMsR0FBRyxJQUFJLENBQUN6VSxRQUFRLENBQUN5VSxTQUFTO1VBQ3BFLElBQUlqZixJQUFJLENBQUM4c0MsUUFBUSxFQUFFO1lBQ2pCOXNDLElBQUksQ0FBQzhzQyxRQUFRLENBQUM7Y0FBRW56QixHQUFHLEVBQUVnRixNQUFNO2NBQUVvdUIsUUFBUSxFQUFFO1lBQVMsQ0FBQyxDQUFDO1lBQ2xEO1VBQ0Y7O1VBRUE7VUFDQS9zQyxJQUFJLENBQUNvbUIsU0FBUyxHQUFHekgsTUFBTTtRQUN6QjtNQUNGLENBQUMsQ0FBQztJQUNKO0lBRUErdEIsZUFBZUEsQ0FBQSxFQUFHO01BQ2hCLE1BQU03dkIsT0FBTyxHQUFHO1FBQ2Q3YyxJQUFJLEVBQUUsSUFBSSxDQUFDZ3NDLFlBQVk7UUFDdkJMLFNBQVMsRUFBRSxJQUFJLENBQUNsaEMsT0FBTyxDQUFDa2hDLFNBQVM7UUFDakNGLFVBQVUsRUFBRSxJQUFJLENBQUNoaEMsT0FBTyxDQUFDZ2hDO09BQzFCO01BRUQsT0FBTyxJQUFJdUIsb0JBQW9CLENBQUMzbUMsT0FBTyxJQUFJLElBQUksQ0FBQzRtQyxpQkFBaUIsQ0FBQzVtQyxPQUFPLENBQUMsRUFBRXdXLE9BQU8sQ0FBQztJQUN0Rjs7SUFFQTtJQUNBb3dCLGlCQUFpQkEsQ0FBQzVtQyxPQUFPLEVBQUU7TUFDekIsTUFBTTZtQyxhQUFhLEdBQUc3SSxLQUFLLElBQUksSUFBSSxDQUFDeUgsWUFBWSxDQUFDdndDLEdBQUcsQ0FBRSxJQUFHOG9DLEtBQUssQ0FBQzloQyxNQUFNLENBQUM3RixFQUFHLEVBQUMsQ0FBQztNQUMzRSxNQUFNNjlCLFFBQVEsR0FBRzhKLEtBQUssSUFBSTtRQUN4QixJQUFJLENBQUM4SCxtQkFBbUIsQ0FBQ0MsZUFBZSxHQUFHL0gsS0FBSyxDQUFDOWhDLE1BQU0sQ0FBQzBjLFNBQVM7UUFDakUsSUFBSSxDQUFDa3VCLFFBQVEsQ0FBQ0QsYUFBYSxDQUFDN0ksS0FBSyxDQUFDLENBQUM7T0FDcEM7TUFFRCxNQUFNZ0ksZUFBZSxHQUFHLENBQUMsSUFBSSxDQUFDTCxZQUFZLElBQUl4dUMsUUFBUSxDQUFDcUMsZUFBZSxFQUFFdW1CLFNBQVM7TUFDakYsTUFBTWduQixlQUFlLEdBQUdmLGVBQWUsSUFBSSxJQUFJLENBQUNGLG1CQUFtQixDQUFDRSxlQUFlO01BQ25GLElBQUksQ0FBQ0YsbUJBQW1CLENBQUNFLGVBQWUsR0FBR0EsZUFBZTtNQUUxRCxLQUFLLE1BQU1oSSxLQUFLLElBQUloK0IsT0FBTyxFQUFFO1FBQzNCLElBQUksQ0FBQ2crQixLQUFLLENBQUNnSixjQUFjLEVBQUU7VUFDekIsSUFBSSxDQUFDcEIsYUFBYSxHQUFHLElBQUk7VUFDekIsSUFBSSxDQUFDcUIsaUJBQWlCLENBQUNKLGFBQWEsQ0FBQzdJLEtBQUssQ0FBQyxDQUFDO1VBRTVDO1FBQ0Y7UUFFQSxNQUFNa0osd0JBQXdCLEdBQUdsSixLQUFLLENBQUM5aEMsTUFBTSxDQUFDMGMsU0FBUyxJQUFJLElBQUksQ0FBQ2t0QixtQkFBbUIsQ0FBQ0MsZUFBZTtRQUNuRztRQUNBLElBQUlnQixlQUFlLElBQUlHLHdCQUF3QixFQUFFO1VBQy9DaFQsUUFBUSxDQUFDOEosS0FBSyxDQUFDO1VBQ2Y7VUFDQSxJQUFJLENBQUNnSSxlQUFlLEVBQUU7WUFDcEI7VUFDRjtVQUVBO1FBQ0Y7O1FBRUE7UUFDQSxJQUFJLENBQUNlLGVBQWUsSUFBSSxDQUFDRyx3QkFBd0IsRUFBRTtVQUNqRGhULFFBQVEsQ0FBQzhKLEtBQUssQ0FBQztRQUNqQjtNQUNGO0lBQ0Y7SUFFQWtJLGdDQUFnQ0EsQ0FBQSxFQUFHO01BQ2pDLElBQUksQ0FBQ1QsWUFBWSxHQUFHLElBQUkvd0MsR0FBRyxFQUFFO01BQzdCLElBQUksQ0FBQ2d4QyxtQkFBbUIsR0FBRyxJQUFJaHhDLEdBQUcsRUFBRTtNQUVwQyxNQUFNeXlDLFdBQVcsR0FBRzloQyxjQUFjLENBQUN2RyxJQUFJLENBQUM2bEMscUJBQXFCLEVBQUUsSUFBSSxDQUFDdmdDLE9BQU8sQ0FBQ2xJLE1BQU0sQ0FBQztNQUVuRixLQUFLLE1BQU1rckMsTUFBTSxJQUFJRCxXQUFXLEVBQUU7UUFDaEM7UUFDQSxJQUFJLENBQUNDLE1BQU0sQ0FBQzFuQixJQUFJLElBQUkzbUIsVUFBVSxDQUFDcXVDLE1BQU0sQ0FBQyxFQUFFO1VBQ3RDO1FBQ0Y7UUFFQSxNQUFNWixpQkFBaUIsR0FBR25oQyxjQUFjLENBQUNHLE9BQU8sQ0FBQzZoQyxTQUFTLENBQUNELE1BQU0sQ0FBQzFuQixJQUFJLENBQUMsRUFBRSxJQUFJLENBQUN2YixRQUFRLENBQUM7O1FBRXZGO1FBQ0EsSUFBSTVMLFNBQVMsQ0FBQ2l1QyxpQkFBaUIsQ0FBQyxFQUFFO1VBQ2hDLElBQUksQ0FBQ2YsWUFBWSxDQUFDN3dDLEdBQUcsQ0FBQ3l5QyxTQUFTLENBQUNELE1BQU0sQ0FBQzFuQixJQUFJLENBQUMsRUFBRTBuQixNQUFNLENBQUM7VUFDckQsSUFBSSxDQUFDMUIsbUJBQW1CLENBQUM5d0MsR0FBRyxDQUFDd3lDLE1BQU0sQ0FBQzFuQixJQUFJLEVBQUU4bUIsaUJBQWlCLENBQUM7UUFDOUQ7TUFDRjtJQUNGO0lBRUFNLFFBQVFBLENBQUM1cUMsTUFBTSxFQUFFO01BQ2YsSUFBSSxJQUFJLENBQUMwcEMsYUFBYSxLQUFLMXBDLE1BQU0sRUFBRTtRQUNqQztNQUNGO01BRUEsSUFBSSxDQUFDK3FDLGlCQUFpQixDQUFDLElBQUksQ0FBQzdpQyxPQUFPLENBQUNsSSxNQUFNLENBQUM7TUFDM0MsSUFBSSxDQUFDMHBDLGFBQWEsR0FBRzFwQyxNQUFNO01BQzNCQSxNQUFNLENBQUNoRCxTQUFTLENBQUNtUixHQUFHLENBQUNvNkIsbUJBQWlCLENBQUM7TUFDdkMsSUFBSSxDQUFDNkMsZ0JBQWdCLENBQUNwckMsTUFBTSxDQUFDO01BRTdCK0IsWUFBWSxDQUFDeUMsT0FBTyxDQUFDLElBQUksQ0FBQ3lELFFBQVEsRUFBRWtnQyxjQUFjLEVBQUU7UUFBRTlrQyxhQUFhLEVBQUVyRDtNQUFPLENBQUMsQ0FBQztJQUNoRjtJQUVBb3JDLGdCQUFnQkEsQ0FBQ3ByQyxNQUFNLEVBQUU7TUFDdkI7TUFDQSxJQUFJQSxNQUFNLENBQUNoRCxTQUFTLENBQUNDLFFBQVEsQ0FBQ3FyQyx3QkFBd0IsQ0FBQyxFQUFFO1FBQ3ZEbi9CLGNBQWMsQ0FBQ0csT0FBTyxDQUFDMC9CLDBCQUF3QixFQUFFaHBDLE1BQU0sQ0FBQ3RELE9BQU8sQ0FBQ3FzQyxpQkFBaUIsQ0FBQyxDQUFDLENBQ2hGL3JDLFNBQVMsQ0FBQ21SLEdBQUcsQ0FBQ282QixtQkFBaUIsQ0FBQztRQUNuQztNQUNGO01BRUEsS0FBSyxNQUFNOEMsU0FBUyxJQUFJbGlDLGNBQWMsQ0FBQ08sT0FBTyxDQUFDMUosTUFBTSxFQUFFMG9DLHVCQUF1QixDQUFDLEVBQUU7UUFDL0U7UUFDQTtRQUNBLEtBQUssTUFBTWx0QixJQUFJLElBQUlyUyxjQUFjLENBQUNTLElBQUksQ0FBQ3loQyxTQUFTLEVBQUV2QyxtQkFBbUIsQ0FBQyxFQUFFO1VBQ3RFdHRCLElBQUksQ0FBQ3hlLFNBQVMsQ0FBQ21SLEdBQUcsQ0FBQ282QixtQkFBaUIsQ0FBQztRQUN2QztNQUNGO0lBQ0Y7SUFFQXdDLGlCQUFpQkEsQ0FBQ3YxQixNQUFNLEVBQUU7TUFDeEJBLE1BQU0sQ0FBQ3hZLFNBQVMsQ0FBQ3pELE1BQU0sQ0FBQ2d2QyxtQkFBaUIsQ0FBQztNQUUxQyxNQUFNK0MsV0FBVyxHQUFHbmlDLGNBQWMsQ0FBQ3ZHLElBQUksQ0FBRSxHQUFFNmxDLHFCQUFzQixJQUFHRixtQkFBa0IsRUFBQyxFQUFFL3lCLE1BQU0sQ0FBQztNQUNoRyxLQUFLLE1BQU0wRCxJQUFJLElBQUlveUIsV0FBVyxFQUFFO1FBQzlCcHlCLElBQUksQ0FBQ2xjLFNBQVMsQ0FBQ3pELE1BQU0sQ0FBQ2d2QyxtQkFBaUIsQ0FBQztNQUMxQztJQUNGOztJQUVBO0lBQ0EsT0FBT3ZwQyxlQUFlQSxDQUFDaUksTUFBTSxFQUFFO01BQzdCLE9BQU8sSUFBSSxDQUFDc0UsSUFBSSxDQUFDLFlBQVk7UUFDM0IsTUFBTUMsSUFBSSxHQUFHODlCLFNBQVMsQ0FBQzNnQyxtQkFBbUIsQ0FBQyxJQUFJLEVBQUUxQixNQUFNLENBQUM7UUFFeEQsSUFBSSxPQUFPQSxNQUFNLEtBQUssUUFBUSxFQUFFO1VBQzlCO1FBQ0Y7UUFFQSxJQUFJdUUsSUFBSSxDQUFDdkUsTUFBTSxDQUFDLEtBQUszTSxTQUFTLElBQUkyTSxNQUFNLENBQUM3QyxVQUFVLENBQUMsR0FBRyxDQUFDLElBQUk2QyxNQUFNLEtBQUssYUFBYSxFQUFFO1VBQ3BGLE1BQU0sSUFBSVksU0FBUyxDQUFFLG9CQUFtQlosTUFBTyxHQUFFLENBQUM7UUFDcEQ7UUFFQXVFLElBQUksQ0FBQ3ZFLE1BQU0sQ0FBQyxFQUFFO01BQ2hCLENBQUMsQ0FBQztJQUNKO0VBQ0Y7O0VBRUE7Ozs7RUFJQWxGLFlBQVksQ0FBQ2lDLEVBQUUsQ0FBQ2xLLE1BQU0sRUFBRXV1QyxxQkFBbUIsRUFBRSxNQUFNO0lBQ2pELEtBQUssTUFBTWtELEdBQUcsSUFBSXBpQyxjQUFjLENBQUN2RyxJQUFJLENBQUM0bEMsaUJBQWlCLENBQUMsRUFBRTtNQUN4RGMsU0FBUyxDQUFDM2dDLG1CQUFtQixDQUFDNGlDLEdBQUcsQ0FBQztJQUNwQztFQUNGLENBQUMsQ0FBQzs7RUFFRjs7OztFQUlBOXNDLGtCQUFrQixDQUFDNnFDLFNBQVMsQ0FBQzs7RUNyUzdCOzs7Ozs7O0VBWUE7Ozs7RUFJQSxNQUFNa0MsTUFBSSxHQUFHLEtBQUs7RUFDbEIsTUFBTUMsVUFBUSxHQUFHLFFBQVE7RUFDekIsTUFBTUMsV0FBUyxHQUFJLElBQUdELFVBQVMsRUFBQztFQUVoQyxNQUFNRSxZQUFVLEdBQUksT0FBTUQsV0FBVSxFQUFDO0VBQ3JDLE1BQU1FLGNBQVksR0FBSSxTQUFRRixXQUFVLEVBQUM7RUFDekMsTUFBTUcsWUFBVSxHQUFJLE9BQU1ILFdBQVUsRUFBQztFQUNyQyxNQUFNSSxhQUFXLEdBQUksUUFBT0osV0FBVSxFQUFDO0VBQ3ZDLE1BQU1LLG9CQUFvQixHQUFJLFFBQU9MLFdBQVUsRUFBQztFQUNoRCxNQUFNTSxhQUFhLEdBQUksVUFBU04sV0FBVSxFQUFDO0VBQzNDLE1BQU1PLG1CQUFtQixHQUFJLE9BQU1QLFdBQVUsRUFBQztFQUU5QyxNQUFNUSxjQUFjLEdBQUcsV0FBVztFQUNsQyxNQUFNQyxlQUFlLEdBQUcsWUFBWTtFQUNwQyxNQUFNQyxZQUFZLEdBQUcsU0FBUztFQUM5QixNQUFNQyxjQUFjLEdBQUcsV0FBVztFQUNsQyxNQUFNQyxRQUFRLEdBQUcsTUFBTTtFQUN2QixNQUFNQyxPQUFPLEdBQUcsS0FBSztFQUVyQixNQUFNQyxpQkFBaUIsR0FBRyxRQUFRO0VBQ2xDLE1BQU1DLGlCQUFlLEdBQUcsTUFBTTtFQUM5QixNQUFNQyxpQkFBZSxHQUFHLE1BQU07RUFDOUIsTUFBTUMsY0FBYyxHQUFHLFVBQVU7RUFFakMsTUFBTUMsd0JBQXdCLEdBQUcsa0JBQWtCO0VBQ25ELE1BQU1DLHNCQUFzQixHQUFHLGdCQUFnQjtFQUMvQyxNQUFNQyw0QkFBNEIsR0FBSSxRQUFPRix3QkFBeUIsR0FBRTtFQUV4RSxNQUFNRyxrQkFBa0IsR0FBRyxxQ0FBcUM7RUFDaEUsTUFBTUMsY0FBYyxHQUFHLDZCQUE2QjtFQUNwRCxNQUFNQyxjQUFjLEdBQUksWUFBV0gsNEJBQTZCLHFCQUFvQkEsNEJBQTZCLGlCQUFnQkEsNEJBQTZCLEVBQUM7RUFDL0osTUFBTUksb0JBQW9CLEdBQUcsMEVBQTBFLENBQUM7RUFDeEcsTUFBTUMsbUJBQW1CLEdBQUksR0FBRUYsY0FBZSxLQUFJQyxvQkFBcUIsRUFBQztFQUV4RSxNQUFNRSwyQkFBMkIsR0FBSSxJQUFHWixpQkFBa0IsNEJBQTJCQSxpQkFBa0IsNkJBQTRCQSxpQkFBa0IseUJBQXdCOztFQUU3Szs7OztFQUlBLE1BQU1hLEdBQUcsU0FBU3JsQyxhQUFhLENBQUM7SUFDOUJWLFdBQVdBLENBQUMzTyxPQUFPLEVBQUU7TUFDbkIsS0FBSyxDQUFDQSxPQUFPLENBQUM7TUFDZCxJQUFJLENBQUNzN0IsT0FBTyxHQUFHLElBQUksQ0FBQ2hzQixRQUFRLENBQUN2TCxPQUFPLENBQUNxd0Msa0JBQWtCLENBQUM7TUFFeEQsSUFBSSxDQUFDLElBQUksQ0FBQzlZLE9BQU8sRUFBRTtRQUNqQjtRQUNBO1FBQ0E7TUFDRjs7TUFFQTtNQUNBLElBQUksQ0FBQ3FaLHFCQUFxQixDQUFDLElBQUksQ0FBQ3JaLE9BQU8sRUFBRSxJQUFJLENBQUNzWixZQUFZLEVBQUUsQ0FBQztNQUU3RHhyQyxZQUFZLENBQUNpQyxFQUFFLENBQUMsSUFBSSxDQUFDaUUsUUFBUSxFQUFFK2pDLGFBQWEsRUFBRXJxQyxLQUFLLElBQUksSUFBSSxDQUFDOFEsUUFBUSxDQUFDOVEsS0FBSyxDQUFDLENBQUM7SUFDOUU7O0lBRUE7SUFDQSxXQUFXOUMsSUFBSUEsQ0FBQSxFQUFHO01BQ2hCLE9BQU8yc0MsTUFBSTtJQUNiOztJQUVBO0lBQ0FuMUIsSUFBSUEsQ0FBQSxFQUFHO01BQUU7TUFDUCxNQUFNbTNCLFNBQVMsR0FBRyxJQUFJLENBQUN2bEMsUUFBUTtNQUMvQixJQUFJLElBQUksQ0FBQ3dsQyxhQUFhLENBQUNELFNBQVMsQ0FBQyxFQUFFO1FBQ2pDO01BQ0Y7O01BRUE7TUFDQSxNQUFNRSxNQUFNLEdBQUcsSUFBSSxDQUFDQyxjQUFjLEVBQUU7TUFFcEMsTUFBTWxaLFNBQVMsR0FBR2laLE1BQU0sR0FDdEIzckMsWUFBWSxDQUFDeUMsT0FBTyxDQUFDa3BDLE1BQU0sRUFBRS9CLFlBQVUsRUFBRTtRQUFFdG9DLGFBQWEsRUFBRW1xQztPQUFXLENBQUMsR0FDdEUsSUFBSTtNQUVOLE1BQU1uWixTQUFTLEdBQUd0eUIsWUFBWSxDQUFDeUMsT0FBTyxDQUFDZ3BDLFNBQVMsRUFBRTNCLFlBQVUsRUFBRTtRQUFFeG9DLGFBQWEsRUFBRXFxQztNQUFPLENBQUMsQ0FBQztNQUV4RixJQUFJclosU0FBUyxDQUFDenZCLGdCQUFnQixJQUFLNnZCLFNBQVMsSUFBSUEsU0FBUyxDQUFDN3ZCLGdCQUFpQixFQUFFO1FBQzNFO01BQ0Y7TUFFQSxJQUFJLENBQUNncEMsV0FBVyxDQUFDRixNQUFNLEVBQUVGLFNBQVMsQ0FBQztNQUNuQyxJQUFJLENBQUNLLFNBQVMsQ0FBQ0wsU0FBUyxFQUFFRSxNQUFNLENBQUM7SUFDbkM7O0lBRUE7SUFDQUcsU0FBU0EsQ0FBQ2wxQyxPQUFPLEVBQUVtMUMsV0FBVyxFQUFFO01BQzlCLElBQUksQ0FBQ24xQyxPQUFPLEVBQUU7UUFDWjtNQUNGO01BRUFBLE9BQU8sQ0FBQ3FFLFNBQVMsQ0FBQ21SLEdBQUcsQ0FBQ3ErQixpQkFBaUIsQ0FBQztNQUV4QyxJQUFJLENBQUNxQixTQUFTLENBQUMxa0MsY0FBYyxDQUFDa0Isc0JBQXNCLENBQUMxUixPQUFPLENBQUMsQ0FBQyxDQUFDOztNQUUvRCxNQUFNa2UsUUFBUSxHQUFHQSxDQUFBLEtBQU07UUFDckIsSUFBSWxlLE9BQU8sQ0FBQ3lFLFlBQVksQ0FBQyxNQUFNLENBQUMsS0FBSyxLQUFLLEVBQUU7VUFDMUN6RSxPQUFPLENBQUNxRSxTQUFTLENBQUNtUixHQUFHLENBQUN1K0IsaUJBQWUsQ0FBQztVQUN0QztRQUNGO1FBRUEvekMsT0FBTyxDQUFDd04sZUFBZSxDQUFDLFVBQVUsQ0FBQztRQUNuQ3hOLE9BQU8sQ0FBQ3NOLFlBQVksQ0FBQyxlQUFlLEVBQUUsSUFBSSxDQUFDO1FBQzNDLElBQUksQ0FBQzhuQyxlQUFlLENBQUNwMUMsT0FBTyxFQUFFLElBQUksQ0FBQztRQUNuQ29KLFlBQVksQ0FBQ3lDLE9BQU8sQ0FBQzdMLE9BQU8sRUFBRW16QyxhQUFXLEVBQUU7VUFDekN6b0MsYUFBYSxFQUFFeXFDO1FBQ2pCLENBQUMsQ0FBQztPQUNIO01BRUQsSUFBSSxDQUFDdGxDLGNBQWMsQ0FBQ3FPLFFBQVEsRUFBRWxlLE9BQU8sRUFBRUEsT0FBTyxDQUFDcUUsU0FBUyxDQUFDQyxRQUFRLENBQUN3dkMsaUJBQWUsQ0FBQyxDQUFDO0lBQ3JGO0lBRUFtQixXQUFXQSxDQUFDajFDLE9BQU8sRUFBRW0xQyxXQUFXLEVBQUU7TUFDaEMsSUFBSSxDQUFDbjFDLE9BQU8sRUFBRTtRQUNaO01BQ0Y7TUFFQUEsT0FBTyxDQUFDcUUsU0FBUyxDQUFDekQsTUFBTSxDQUFDaXpDLGlCQUFpQixDQUFDO01BQzNDN3pDLE9BQU8sQ0FBQ3NsQyxJQUFJLEVBQUU7TUFFZCxJQUFJLENBQUMyUCxXQUFXLENBQUN6a0MsY0FBYyxDQUFDa0Isc0JBQXNCLENBQUMxUixPQUFPLENBQUMsQ0FBQyxDQUFDOztNQUVqRSxNQUFNa2UsUUFBUSxHQUFHQSxDQUFBLEtBQU07UUFDckIsSUFBSWxlLE9BQU8sQ0FBQ3lFLFlBQVksQ0FBQyxNQUFNLENBQUMsS0FBSyxLQUFLLEVBQUU7VUFDMUN6RSxPQUFPLENBQUNxRSxTQUFTLENBQUN6RCxNQUFNLENBQUNtekMsaUJBQWUsQ0FBQztVQUN6QztRQUNGO1FBRUEvekMsT0FBTyxDQUFDc04sWUFBWSxDQUFDLGVBQWUsRUFBRSxLQUFLLENBQUM7UUFDNUN0TixPQUFPLENBQUNzTixZQUFZLENBQUMsVUFBVSxFQUFFLElBQUksQ0FBQztRQUN0QyxJQUFJLENBQUM4bkMsZUFBZSxDQUFDcDFDLE9BQU8sRUFBRSxLQUFLLENBQUM7UUFDcENvSixZQUFZLENBQUN5QyxPQUFPLENBQUM3TCxPQUFPLEVBQUVpekMsY0FBWSxFQUFFO1VBQUV2b0MsYUFBYSxFQUFFeXFDO1FBQVksQ0FBQyxDQUFDO09BQzVFO01BRUQsSUFBSSxDQUFDdGxDLGNBQWMsQ0FBQ3FPLFFBQVEsRUFBRWxlLE9BQU8sRUFBRUEsT0FBTyxDQUFDcUUsU0FBUyxDQUFDQyxRQUFRLENBQUN3dkMsaUJBQWUsQ0FBQyxDQUFDO0lBQ3JGO0lBRUFoNkIsUUFBUUEsQ0FBQzlRLEtBQUssRUFBRTtNQUNkLElBQUksQ0FBRSxDQUFDdXFDLGNBQWMsRUFBRUMsZUFBZSxFQUFFQyxZQUFZLEVBQUVDLGNBQWMsRUFBRUMsUUFBUSxFQUFFQyxPQUFPLENBQUMsQ0FBQ3hvQyxRQUFRLENBQUNwQyxLQUFLLENBQUMvSSxHQUFHLENBQUUsRUFBRTtRQUM3RztNQUNGO01BRUErSSxLQUFLLENBQUNvMEIsZUFBZSxFQUFFO01BQ3ZCcDBCLEtBQUssQ0FBQ3VELGNBQWMsRUFBRTtNQUV0QixNQUFNcUUsUUFBUSxHQUFHLElBQUksQ0FBQ2drQyxZQUFZLEVBQUUsQ0FBQy9tQyxNQUFNLENBQUM3TixPQUFPLElBQUksQ0FBQ2tFLFVBQVUsQ0FBQ2xFLE9BQU8sQ0FBQyxDQUFDO01BQzVFLElBQUlxMUMsaUJBQWlCO01BRXJCLElBQUksQ0FBQzFCLFFBQVEsRUFBRUMsT0FBTyxDQUFDLENBQUN4b0MsUUFBUSxDQUFDcEMsS0FBSyxDQUFDL0ksR0FBRyxDQUFDLEVBQUU7UUFDM0NvMUMsaUJBQWlCLEdBQUd6a0MsUUFBUSxDQUFDNUgsS0FBSyxDQUFDL0ksR0FBRyxLQUFLMHpDLFFBQVEsR0FBRyxDQUFDLEdBQUcvaUMsUUFBUSxDQUFDcE4sTUFBTSxHQUFHLENBQUMsQ0FBQztNQUNoRixDQUFDLE1BQU07UUFDTCxNQUFNa1gsTUFBTSxHQUFHLENBQUM4NEIsZUFBZSxFQUFFRSxjQUFjLENBQUMsQ0FBQ3RvQyxRQUFRLENBQUNwQyxLQUFLLENBQUMvSSxHQUFHLENBQUM7UUFDcEVvMUMsaUJBQWlCLEdBQUc3dEMsb0JBQW9CLENBQUNvSixRQUFRLEVBQUU1SCxLQUFLLENBQUMzQixNQUFNLEVBQUVxVCxNQUFNLEVBQUUsSUFBSSxDQUFDO01BQ2hGO01BRUEsSUFBSTI2QixpQkFBaUIsRUFBRTtRQUNyQkEsaUJBQWlCLENBQUN6WixLQUFLLENBQUM7VUFBRTBaLGFBQWEsRUFBRTtRQUFLLENBQUMsQ0FBQztRQUNoRFosR0FBRyxDQUFDMWtDLG1CQUFtQixDQUFDcWxDLGlCQUFpQixDQUFDLENBQUMzM0IsSUFBSSxFQUFFO01BQ25EO0lBQ0Y7SUFFQWszQixZQUFZQSxDQUFBLEVBQUc7TUFBRTtNQUNmLE9BQU9wa0MsY0FBYyxDQUFDdkcsSUFBSSxDQUFDdXFDLG1CQUFtQixFQUFFLElBQUksQ0FBQ2xaLE9BQU8sQ0FBQztJQUMvRDtJQUVBMFosY0FBY0EsQ0FBQSxFQUFHO01BQ2YsT0FBTyxJQUFJLENBQUNKLFlBQVksRUFBRSxDQUFDM3FDLElBQUksQ0FBQzRHLEtBQUssSUFBSSxJQUFJLENBQUNpa0MsYUFBYSxDQUFDamtDLEtBQUssQ0FBQyxDQUFDLElBQUksSUFBSTtJQUM3RTtJQUVBOGpDLHFCQUFxQkEsQ0FBQzkzQixNQUFNLEVBQUVqTSxRQUFRLEVBQUU7TUFDdEMsSUFBSSxDQUFDMmtDLHdCQUF3QixDQUFDMTRCLE1BQU0sRUFBRSxNQUFNLEVBQUUsU0FBUyxDQUFDO01BRXhELEtBQUssTUFBTWhNLEtBQUssSUFBSUQsUUFBUSxFQUFFO1FBQzVCLElBQUksQ0FBQzRrQyw0QkFBNEIsQ0FBQzNrQyxLQUFLLENBQUM7TUFDMUM7SUFDRjtJQUVBMmtDLDRCQUE0QkEsQ0FBQzNrQyxLQUFLLEVBQUU7TUFDbENBLEtBQUssR0FBRyxJQUFJLENBQUM0a0MsZ0JBQWdCLENBQUM1a0MsS0FBSyxDQUFDO01BQ3BDLE1BQU02a0MsUUFBUSxHQUFHLElBQUksQ0FBQ1osYUFBYSxDQUFDamtDLEtBQUssQ0FBQztNQUMxQyxNQUFNOGtDLFNBQVMsR0FBRyxJQUFJLENBQUNDLGdCQUFnQixDQUFDL2tDLEtBQUssQ0FBQztNQUM5Q0EsS0FBSyxDQUFDdkQsWUFBWSxDQUFDLGVBQWUsRUFBRW9vQyxRQUFRLENBQUM7TUFFN0MsSUFBSUMsU0FBUyxLQUFLOWtDLEtBQUssRUFBRTtRQUN2QixJQUFJLENBQUMwa0Msd0JBQXdCLENBQUNJLFNBQVMsRUFBRSxNQUFNLEVBQUUsY0FBYyxDQUFDO01BQ2xFO01BRUEsSUFBSSxDQUFDRCxRQUFRLEVBQUU7UUFDYjdrQyxLQUFLLENBQUN2RCxZQUFZLENBQUMsVUFBVSxFQUFFLElBQUksQ0FBQztNQUN0QztNQUVBLElBQUksQ0FBQ2lvQyx3QkFBd0IsQ0FBQzFrQyxLQUFLLEVBQUUsTUFBTSxFQUFFLEtBQUssQ0FBQzs7TUFFbkQ7TUFDQSxJQUFJLENBQUNnbEMsa0NBQWtDLENBQUNobEMsS0FBSyxDQUFDO0lBQ2hEO0lBRUFnbEMsa0NBQWtDQSxDQUFDaGxDLEtBQUssRUFBRTtNQUN4QyxNQUFNeEosTUFBTSxHQUFHbUosY0FBYyxDQUFDa0Isc0JBQXNCLENBQUNiLEtBQUssQ0FBQztNQUUzRCxJQUFJLENBQUN4SixNQUFNLEVBQUU7UUFDWDtNQUNGO01BRUEsSUFBSSxDQUFDa3VDLHdCQUF3QixDQUFDbHVDLE1BQU0sRUFBRSxNQUFNLEVBQUUsVUFBVSxDQUFDO01BRXpELElBQUl3SixLQUFLLENBQUNyUCxFQUFFLEVBQUU7UUFDWixJQUFJLENBQUMrekMsd0JBQXdCLENBQUNsdUMsTUFBTSxFQUFFLGlCQUFpQixFQUFHLEdBQUV3SixLQUFLLENBQUNyUCxFQUFHLEVBQUMsQ0FBQztNQUN6RTtJQUNGO0lBRUE0ekMsZUFBZUEsQ0FBQ3AxQyxPQUFPLEVBQUU4MUMsSUFBSSxFQUFFO01BQzdCLE1BQU1ILFNBQVMsR0FBRyxJQUFJLENBQUNDLGdCQUFnQixDQUFDNTFDLE9BQU8sQ0FBQztNQUNoRCxJQUFJLENBQUMyMUMsU0FBUyxDQUFDdHhDLFNBQVMsQ0FBQ0MsUUFBUSxDQUFDMHZDLGNBQWMsQ0FBQyxFQUFFO1FBQ2pEO01BQ0Y7TUFFQSxNQUFNMWdDLE1BQU0sR0FBR0EsQ0FBQ3BTLFFBQVEsRUFBRXc4QixTQUFTLEtBQUs7UUFDdEMsTUFBTTE5QixPQUFPLEdBQUd3USxjQUFjLENBQUNHLE9BQU8sQ0FBQ3pQLFFBQVEsRUFBRXkwQyxTQUFTLENBQUM7UUFDM0QsSUFBSTMxQyxPQUFPLEVBQUU7VUFDWEEsT0FBTyxDQUFDcUUsU0FBUyxDQUFDaVAsTUFBTSxDQUFDb3FCLFNBQVMsRUFBRW9ZLElBQUksQ0FBQztRQUMzQztPQUNEO01BRUR4aUMsTUFBTSxDQUFDMmdDLHdCQUF3QixFQUFFSixpQkFBaUIsQ0FBQztNQUNuRHZnQyxNQUFNLENBQUM0Z0Msc0JBQXNCLEVBQUVILGlCQUFlLENBQUM7TUFDL0M0QixTQUFTLENBQUNyb0MsWUFBWSxDQUFDLGVBQWUsRUFBRXdvQyxJQUFJLENBQUM7SUFDL0M7SUFFQVAsd0JBQXdCQSxDQUFDdjFDLE9BQU8sRUFBRWlpQixTQUFTLEVBQUV2VixLQUFLLEVBQUU7TUFDbEQsSUFBSSxDQUFDMU0sT0FBTyxDQUFDd0UsWUFBWSxDQUFDeWQsU0FBUyxDQUFDLEVBQUU7UUFDcENqaUIsT0FBTyxDQUFDc04sWUFBWSxDQUFDMlUsU0FBUyxFQUFFdlYsS0FBSyxDQUFDO01BQ3hDO0lBQ0Y7SUFFQW9vQyxhQUFhQSxDQUFDMzNCLElBQUksRUFBRTtNQUNsQixPQUFPQSxJQUFJLENBQUM5WSxTQUFTLENBQUNDLFFBQVEsQ0FBQ3V2QyxpQkFBaUIsQ0FBQztJQUNuRDs7SUFFQTtJQUNBNEIsZ0JBQWdCQSxDQUFDdDRCLElBQUksRUFBRTtNQUNyQixPQUFPQSxJQUFJLENBQUNyTSxPQUFPLENBQUMwakMsbUJBQW1CLENBQUMsR0FBR3IzQixJQUFJLEdBQUczTSxjQUFjLENBQUNHLE9BQU8sQ0FBQzZqQyxtQkFBbUIsRUFBRXIzQixJQUFJLENBQUM7SUFDckc7O0lBRUE7SUFDQXk0QixnQkFBZ0JBLENBQUN6NEIsSUFBSSxFQUFFO01BQ3JCLE9BQU9BLElBQUksQ0FBQ3BaLE9BQU8sQ0FBQ3N3QyxjQUFjLENBQUMsSUFBSWwzQixJQUFJO0lBQzdDOztJQUVBO0lBQ0EsT0FBTzlXLGVBQWVBLENBQUNpSSxNQUFNLEVBQUU7TUFDN0IsT0FBTyxJQUFJLENBQUNzRSxJQUFJLENBQUMsWUFBWTtRQUMzQixNQUFNQyxJQUFJLEdBQUc2aEMsR0FBRyxDQUFDMWtDLG1CQUFtQixDQUFDLElBQUksQ0FBQztRQUUxQyxJQUFJLE9BQU8xQixNQUFNLEtBQUssUUFBUSxFQUFFO1VBQzlCO1FBQ0Y7UUFFQSxJQUFJdUUsSUFBSSxDQUFDdkUsTUFBTSxDQUFDLEtBQUszTSxTQUFTLElBQUkyTSxNQUFNLENBQUM3QyxVQUFVLENBQUMsR0FBRyxDQUFDLElBQUk2QyxNQUFNLEtBQUssYUFBYSxFQUFFO1VBQ3BGLE1BQU0sSUFBSVksU0FBUyxDQUFFLG9CQUFtQlosTUFBTyxHQUFFLENBQUM7UUFDcEQ7UUFFQXVFLElBQUksQ0FBQ3ZFLE1BQU0sQ0FBQyxFQUFFO01BQ2hCLENBQUMsQ0FBQztJQUNKO0VBQ0Y7O0VBRUE7Ozs7RUFJQWxGLFlBQVksQ0FBQ2lDLEVBQUUsQ0FBQy9JLFFBQVEsRUFBRTh3QyxvQkFBb0IsRUFBRW1CLG9CQUFvQixFQUFFLFVBQVV2ckMsS0FBSyxFQUFFO0lBQ3JGLElBQUksQ0FBQyxHQUFHLEVBQUUsTUFBTSxDQUFDLENBQUNvQyxRQUFRLENBQUMsSUFBSSxDQUFDNEcsT0FBTyxDQUFDLEVBQUU7TUFDeENoSixLQUFLLENBQUN1RCxjQUFjLEVBQUU7SUFDeEI7SUFFQSxJQUFJckksVUFBVSxDQUFDLElBQUksQ0FBQyxFQUFFO01BQ3BCO0lBQ0Y7SUFFQXd3QyxHQUFHLENBQUMxa0MsbUJBQW1CLENBQUMsSUFBSSxDQUFDLENBQUMwTixJQUFJLEVBQUU7RUFDdEMsQ0FBQyxDQUFDOztFQUVGOzs7RUFHQXRVLFlBQVksQ0FBQ2lDLEVBQUUsQ0FBQ2xLLE1BQU0sRUFBRW15QyxtQkFBbUIsRUFBRSxNQUFNO0lBQ2pELEtBQUssTUFBTXR6QyxPQUFPLElBQUl3USxjQUFjLENBQUN2RyxJQUFJLENBQUN3cUMsMkJBQTJCLENBQUMsRUFBRTtNQUN0RUMsR0FBRyxDQUFDMWtDLG1CQUFtQixDQUFDaFEsT0FBTyxDQUFDO0lBQ2xDO0VBQ0YsQ0FBQyxDQUFDO0VBQ0Y7Ozs7RUFJQThGLGtCQUFrQixDQUFDNHVDLEdBQUcsQ0FBQzs7RUN4VHZCOzs7Ozs7O0VBWUE7Ozs7RUFJQSxNQUFNeHVDLElBQUksR0FBRyxPQUFPO0VBQ3BCLE1BQU1zSixRQUFRLEdBQUcsVUFBVTtFQUMzQixNQUFNRSxTQUFTLEdBQUksSUFBR0YsUUFBUyxFQUFDO0VBRWhDLE1BQU11bUMsZUFBZSxHQUFJLFlBQVdybUMsU0FBVSxFQUFDO0VBQy9DLE1BQU1zbUMsY0FBYyxHQUFJLFdBQVV0bUMsU0FBVSxFQUFDO0VBQzdDLE1BQU11bUMsYUFBYSxHQUFJLFVBQVN2bUMsU0FBVSxFQUFDO0VBQzNDLE1BQU13bUMsY0FBYyxHQUFJLFdBQVV4bUMsU0FBVSxFQUFDO0VBQzdDLE1BQU15bUMsVUFBVSxHQUFJLE9BQU16bUMsU0FBVSxFQUFDO0VBQ3JDLE1BQU0wbUMsWUFBWSxHQUFJLFNBQVExbUMsU0FBVSxFQUFDO0VBQ3pDLE1BQU0ybUMsVUFBVSxHQUFJLE9BQU0zbUMsU0FBVSxFQUFDO0VBQ3JDLE1BQU00bUMsV0FBVyxHQUFJLFFBQU81bUMsU0FBVSxFQUFDO0VBRXZDLE1BQU02bUMsZUFBZSxHQUFHLE1BQU07RUFDOUIsTUFBTUMsZUFBZSxHQUFHLE1BQU0sQ0FBQztFQUMvQixNQUFNQyxlQUFlLEdBQUcsTUFBTTtFQUM5QixNQUFNQyxrQkFBa0IsR0FBRyxTQUFTO0VBRXBDLE1BQU12b0MsV0FBVyxHQUFHO0lBQ2xCNjlCLFNBQVMsRUFBRSxTQUFTO0lBQ3BCMkssUUFBUSxFQUFFLFNBQVM7SUFDbkJ4SyxLQUFLLEVBQUU7RUFDVCxDQUFDO0VBRUQsTUFBTWorQixPQUFPLEdBQUc7SUFDZDg5QixTQUFTLEVBQUUsSUFBSTtJQUNmMkssUUFBUSxFQUFFLElBQUk7SUFDZHhLLEtBQUssRUFBRTtFQUNULENBQUM7O0VBRUQ7Ozs7RUFJQSxNQUFNeUssS0FBSyxTQUFTdm5DLGFBQWEsQ0FBQztJQUNoQ1YsV0FBV0EsQ0FBQzNPLE9BQU8sRUFBRXNPLE1BQU0sRUFBRTtNQUMzQixLQUFLLENBQUN0TyxPQUFPLEVBQUVzTyxNQUFNLENBQUM7TUFFdEIsSUFBSSxDQUFDaytCLFFBQVEsR0FBRyxJQUFJO01BQ3BCLElBQUksQ0FBQ3FLLG9CQUFvQixHQUFHLEtBQUs7TUFDakMsSUFBSSxDQUFDQyx1QkFBdUIsR0FBRyxLQUFLO01BQ3BDLElBQUksQ0FBQ2hLLGFBQWEsRUFBRTtJQUN0Qjs7SUFFQTtJQUNBLFdBQVc1K0IsT0FBT0EsQ0FBQSxFQUFHO01BQ25CLE9BQU9BLE9BQU87SUFDaEI7SUFFQSxXQUFXQyxXQUFXQSxDQUFBLEVBQUc7TUFDdkIsT0FBT0EsV0FBVztJQUNwQjtJQUVBLFdBQVdqSSxJQUFJQSxDQUFBLEVBQUc7TUFDaEIsT0FBT0EsSUFBSTtJQUNiOztJQUVBO0lBQ0F3WCxJQUFJQSxDQUFBLEVBQUc7TUFDTCxNQUFNZ2UsU0FBUyxHQUFHdHlCLFlBQVksQ0FBQ3lDLE9BQU8sQ0FBQyxJQUFJLENBQUN5RCxRQUFRLEVBQUUrbUMsVUFBVSxDQUFDO01BRWpFLElBQUkzYSxTQUFTLENBQUN6dkIsZ0JBQWdCLEVBQUU7UUFDOUI7TUFDRjtNQUVBLElBQUksQ0FBQzhxQyxhQUFhLEVBQUU7TUFFcEIsSUFBSSxJQUFJLENBQUN4bkMsT0FBTyxDQUFDeThCLFNBQVMsRUFBRTtRQUMxQixJQUFJLENBQUMxOEIsUUFBUSxDQUFDakwsU0FBUyxDQUFDbVIsR0FBRyxDQUFDK2dDLGVBQWUsQ0FBQztNQUM5QztNQUVBLE1BQU1yNEIsUUFBUSxHQUFHQSxDQUFBLEtBQU07UUFDckIsSUFBSSxDQUFDNU8sUUFBUSxDQUFDakwsU0FBUyxDQUFDekQsTUFBTSxDQUFDODFDLGtCQUFrQixDQUFDO1FBQ2xEdHRDLFlBQVksQ0FBQ3lDLE9BQU8sQ0FBQyxJQUFJLENBQUN5RCxRQUFRLEVBQUVnbkMsV0FBVyxDQUFDO1FBRWhELElBQUksQ0FBQ1Usa0JBQWtCLEVBQUU7T0FDMUI7TUFFRCxJQUFJLENBQUMxbkMsUUFBUSxDQUFDakwsU0FBUyxDQUFDekQsTUFBTSxDQUFDNDFDLGVBQWUsQ0FBQyxDQUFDO01BQ2hEdnhDLE1BQU0sQ0FBQyxJQUFJLENBQUNxSyxRQUFRLENBQUM7TUFDckIsSUFBSSxDQUFDQSxRQUFRLENBQUNqTCxTQUFTLENBQUNtUixHQUFHLENBQUNpaEMsZUFBZSxFQUFFQyxrQkFBa0IsQ0FBQztNQUVoRSxJQUFJLENBQUM3bUMsY0FBYyxDQUFDcU8sUUFBUSxFQUFFLElBQUksQ0FBQzVPLFFBQVEsRUFBRSxJQUFJLENBQUNDLE9BQU8sQ0FBQ3k4QixTQUFTLENBQUM7SUFDdEU7SUFFQXZ1QixJQUFJQSxDQUFBLEVBQUc7TUFDTCxJQUFJLENBQUMsSUFBSSxDQUFDdzVCLE9BQU8sRUFBRSxFQUFFO1FBQ25CO01BQ0Y7TUFFQSxNQUFNbmIsU0FBUyxHQUFHMXlCLFlBQVksQ0FBQ3lDLE9BQU8sQ0FBQyxJQUFJLENBQUN5RCxRQUFRLEVBQUU2bUMsVUFBVSxDQUFDO01BRWpFLElBQUlyYSxTQUFTLENBQUM3dkIsZ0JBQWdCLEVBQUU7UUFDOUI7TUFDRjtNQUVBLE1BQU1pUyxRQUFRLEdBQUdBLENBQUEsS0FBTTtRQUNyQixJQUFJLENBQUM1TyxRQUFRLENBQUNqTCxTQUFTLENBQUNtUixHQUFHLENBQUNnaEMsZUFBZSxDQUFDLENBQUM7UUFDN0MsSUFBSSxDQUFDbG5DLFFBQVEsQ0FBQ2pMLFNBQVMsQ0FBQ3pELE1BQU0sQ0FBQzgxQyxrQkFBa0IsRUFBRUQsZUFBZSxDQUFDO1FBQ25FcnRDLFlBQVksQ0FBQ3lDLE9BQU8sQ0FBQyxJQUFJLENBQUN5RCxRQUFRLEVBQUU4bUMsWUFBWSxDQUFDO09BQ2xEO01BRUQsSUFBSSxDQUFDOW1DLFFBQVEsQ0FBQ2pMLFNBQVMsQ0FBQ21SLEdBQUcsQ0FBQ2toQyxrQkFBa0IsQ0FBQztNQUMvQyxJQUFJLENBQUM3bUMsY0FBYyxDQUFDcU8sUUFBUSxFQUFFLElBQUksQ0FBQzVPLFFBQVEsRUFBRSxJQUFJLENBQUNDLE9BQU8sQ0FBQ3k4QixTQUFTLENBQUM7SUFDdEU7SUFFQXY4QixPQUFPQSxDQUFBLEVBQUc7TUFDUixJQUFJLENBQUNzbkMsYUFBYSxFQUFFO01BRXBCLElBQUksSUFBSSxDQUFDRSxPQUFPLEVBQUUsRUFBRTtRQUNsQixJQUFJLENBQUMzbkMsUUFBUSxDQUFDakwsU0FBUyxDQUFDekQsTUFBTSxDQUFDNjFDLGVBQWUsQ0FBQztNQUNqRDtNQUVBLEtBQUssQ0FBQ2huQyxPQUFPLEVBQUU7SUFDakI7SUFFQXduQyxPQUFPQSxDQUFBLEVBQUc7TUFDUixPQUFPLElBQUksQ0FBQzNuQyxRQUFRLENBQUNqTCxTQUFTLENBQUNDLFFBQVEsQ0FBQ215QyxlQUFlLENBQUM7SUFDMUQ7O0lBRUE7O0lBRUFPLGtCQUFrQkEsQ0FBQSxFQUFHO01BQ25CLElBQUksQ0FBQyxJQUFJLENBQUN6bkMsT0FBTyxDQUFDb25DLFFBQVEsRUFBRTtRQUMxQjtNQUNGO01BRUEsSUFBSSxJQUFJLENBQUNFLG9CQUFvQixJQUFJLElBQUksQ0FBQ0MsdUJBQXVCLEVBQUU7UUFDN0Q7TUFDRjtNQUVBLElBQUksQ0FBQ3RLLFFBQVEsR0FBR2psQyxVQUFVLENBQUMsTUFBTTtRQUMvQixJQUFJLENBQUNrVyxJQUFJLEVBQUU7TUFDYixDQUFDLEVBQUUsSUFBSSxDQUFDbE8sT0FBTyxDQUFDNDhCLEtBQUssQ0FBQztJQUN4QjtJQUVBK0ssY0FBY0EsQ0FBQ2x1QyxLQUFLLEVBQUVtdUMsYUFBYSxFQUFFO01BQ25DLFFBQVFudUMsS0FBSyxDQUFDTSxJQUFJO1FBQ2hCLEtBQUssV0FBVztRQUNoQixLQUFLLFVBQVU7VUFBRTtZQUNmLElBQUksQ0FBQ3V0QyxvQkFBb0IsR0FBR00sYUFBYTtZQUN6QztVQUNGO1FBRUEsS0FBSyxTQUFTO1FBQ2QsS0FBSyxVQUFVO1VBQUU7WUFDZixJQUFJLENBQUNMLHVCQUF1QixHQUFHSyxhQUFhO1lBQzVDO1VBQ0Y7TUFLRjtNQUVBLElBQUlBLGFBQWEsRUFBRTtRQUNqQixJQUFJLENBQUNKLGFBQWEsRUFBRTtRQUNwQjtNQUNGO01BRUEsTUFBTXA4QixXQUFXLEdBQUczUixLQUFLLENBQUMwQixhQUFhO01BQ3ZDLElBQUksSUFBSSxDQUFDNEUsUUFBUSxLQUFLcUwsV0FBVyxJQUFJLElBQUksQ0FBQ3JMLFFBQVEsQ0FBQ2hMLFFBQVEsQ0FBQ3FXLFdBQVcsQ0FBQyxFQUFFO1FBQ3hFO01BQ0Y7TUFFQSxJQUFJLENBQUNxOEIsa0JBQWtCLEVBQUU7SUFDM0I7SUFFQWxLLGFBQWFBLENBQUEsRUFBRztNQUNkMWpDLFlBQVksQ0FBQ2lDLEVBQUUsQ0FBQyxJQUFJLENBQUNpRSxRQUFRLEVBQUV5bUMsZUFBZSxFQUFFL3NDLEtBQUssSUFBSSxJQUFJLENBQUNrdUMsY0FBYyxDQUFDbHVDLEtBQUssRUFBRSxJQUFJLENBQUMsQ0FBQztNQUMxRkksWUFBWSxDQUFDaUMsRUFBRSxDQUFDLElBQUksQ0FBQ2lFLFFBQVEsRUFBRTBtQyxjQUFjLEVBQUVodEMsS0FBSyxJQUFJLElBQUksQ0FBQ2t1QyxjQUFjLENBQUNsdUMsS0FBSyxFQUFFLEtBQUssQ0FBQyxDQUFDO01BQzFGSSxZQUFZLENBQUNpQyxFQUFFLENBQUMsSUFBSSxDQUFDaUUsUUFBUSxFQUFFMm1DLGFBQWEsRUFBRWp0QyxLQUFLLElBQUksSUFBSSxDQUFDa3VDLGNBQWMsQ0FBQ2x1QyxLQUFLLEVBQUUsSUFBSSxDQUFDLENBQUM7TUFDeEZJLFlBQVksQ0FBQ2lDLEVBQUUsQ0FBQyxJQUFJLENBQUNpRSxRQUFRLEVBQUU0bUMsY0FBYyxFQUFFbHRDLEtBQUssSUFBSSxJQUFJLENBQUNrdUMsY0FBYyxDQUFDbHVDLEtBQUssRUFBRSxLQUFLLENBQUMsQ0FBQztJQUM1RjtJQUVBK3RDLGFBQWFBLENBQUEsRUFBRztNQUNkNzhCLFlBQVksQ0FBQyxJQUFJLENBQUNzeUIsUUFBUSxDQUFDO01BQzNCLElBQUksQ0FBQ0EsUUFBUSxHQUFHLElBQUk7SUFDdEI7O0lBRUE7SUFDQSxPQUFPbm1DLGVBQWVBLENBQUNpSSxNQUFNLEVBQUU7TUFDN0IsT0FBTyxJQUFJLENBQUNzRSxJQUFJLENBQUMsWUFBWTtRQUMzQixNQUFNQyxJQUFJLEdBQUcrakMsS0FBSyxDQUFDNW1DLG1CQUFtQixDQUFDLElBQUksRUFBRTFCLE1BQU0sQ0FBQztRQUVwRCxJQUFJLE9BQU9BLE1BQU0sS0FBSyxRQUFRLEVBQUU7VUFDOUIsSUFBSSxPQUFPdUUsSUFBSSxDQUFDdkUsTUFBTSxDQUFDLEtBQUssV0FBVyxFQUFFO1lBQ3ZDLE1BQU0sSUFBSVksU0FBUyxDQUFFLG9CQUFtQlosTUFBTyxHQUFFLENBQUM7VUFDcEQ7VUFFQXVFLElBQUksQ0FBQ3ZFLE1BQU0sQ0FBQyxDQUFDLElBQUksQ0FBQztRQUNwQjtNQUNGLENBQUMsQ0FBQztJQUNKO0VBQ0Y7O0VBRUE7Ozs7RUFJQXNELG9CQUFvQixDQUFDZ2xDLEtBQUssQ0FBQzs7RUFFM0I7Ozs7RUFJQTl3QyxrQkFBa0IsQ0FBQzh3QyxLQUFLLENBQUM7O0VDOU56Qjs7Ozs7OztFQW9CQSxNQUFBUSxTQUFBLEdBQWU7SUFDYjVrQyxLQUFLO0lBQ0xhLE1BQU07SUFDTmlGLFFBQVE7SUFDUnlFLFFBQVE7SUFDUnFlLFFBQVE7SUFDUnFILEtBQUs7SUFDTDRDLFNBQVM7SUFDVDZKLE9BQU87SUFDUHlCLFNBQVM7SUFDVCtELEdBQUc7SUFDSGtDLEtBQUs7SUFDTHRLO0VBQ0YsQ0FBQyIsImZpbGUiOiJidW5kbGVfb3V0cHV0X0Zyb250ZW5kX0J1bmRsZS5qcyIsInNvdXJjZXNDb250ZW50IjpbIndpbmRvdy5yc3hhcHAgPSB3aW5kb3cucnN4YXBwIHx8IHt9O1xud2luZG93LnJzeGFwcC5tb2R1bGVfcGF0aHMgPSB7XCJib290c3RyYXA1X3NyY1wiOlwicnN4XFwvdGhlbWVcXC92ZW5kb3JcXC9ib290c3RyYXA1XFwvc2Nzc1wifTtcbiIsIigoKSA9PiB7XG4gIC8vIG5vZGVfbW9kdWxlcy9AanFodG1sL2NvcmUvZGlzdC9pbmRleC5qc1xuICB2YXIgTGlmZWN5Y2xlTWFuYWdlciA9IGNsYXNzIF9MaWZlY3ljbGVNYW5hZ2VyIHtcbiAgICBzdGF0aWMgZ2V0X2luc3RhbmNlKCkge1xuICAgICAgaWYgKCFfTGlmZWN5Y2xlTWFuYWdlci5pbnN0YW5jZSkge1xuICAgICAgICBfTGlmZWN5Y2xlTWFuYWdlci5pbnN0YW5jZSA9IG5ldyBfTGlmZWN5Y2xlTWFuYWdlcigpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIF9MaWZlY3ljbGVNYW5hZ2VyLmluc3RhbmNlO1xuICAgIH1cbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgIHRoaXMuYWN0aXZlX2NvbXBvbmVudHMgPSAvKiBAX19QVVJFX18gKi8gbmV3IFNldCgpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBCb290IGEgY29tcG9uZW50IC0gcnVuIGl0cyBmdWxsIGxpZmVjeWNsZVxuICAgICAqIENhbGxlZCB3aGVuIGNvbXBvbmVudCBpcyBjcmVhdGVkXG4gICAgICovXG4gICAgYXN5bmMgYm9vdF9jb21wb25lbnQoY29tcG9uZW50KSB7XG4gICAgICB0aGlzLmFjdGl2ZV9jb21wb25lbnRzLmFkZChjb21wb25lbnQpO1xuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgY29tcG9uZW50LmNyZWF0ZSgpO1xuICAgICAgICBpZiAoY29tcG9uZW50Ll9zdG9wcGVkKVxuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgY29tcG9uZW50LnRyaWdnZXIoXCJjcmVhdGVcIik7XG4gICAgICAgIGxldCByZW5kZXJfaWQgPSBjb21wb25lbnQuX3JlbmRlcigpO1xuICAgICAgICBpZiAoY29tcG9uZW50Ll9zdG9wcGVkKVxuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgYXdhaXQgY29tcG9uZW50LmxvYWQoKTtcbiAgICAgICAgaWYgKGNvbXBvbmVudC5fc3RvcHBlZClcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIGlmIChjb21wb25lbnQuc2hvdWxkX3JlcmVuZGVyKCkpIHtcbiAgICAgICAgICByZW5kZXJfaWQgPSBjb21wb25lbnQuX3JlbmRlcigpO1xuICAgICAgICAgIGlmIChjb21wb25lbnQuX3N0b3BwZWQpXG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGNvbXBvbmVudC5fcmVuZGVyX2NvdW50ICE9PSByZW5kZXJfaWQpIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgYXdhaXQgY29tcG9uZW50LnJlYWR5KCk7XG4gICAgICAgIGlmIChjb21wb25lbnQuX3N0b3BwZWQpXG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICBhd2FpdCBjb21wb25lbnQudHJpZ2dlcihcInJlYWR5XCIpO1xuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgY29uc29sZS5lcnJvcihgRXJyb3IgYm9vdGluZyBjb21wb25lbnQgJHtjb21wb25lbnQuY29tcG9uZW50X25hbWUoKX06YCwgZXJyb3IpO1xuICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgIH1cbiAgICB9XG4gICAgLyoqXG4gICAgICogVW5yZWdpc3RlciBhIGNvbXBvbmVudCAoY2FsbGVkIG9uIGRlc3Ryb3kpXG4gICAgICovXG4gICAgdW5yZWdpc3Rlcl9jb21wb25lbnQoY29tcG9uZW50KSB7XG4gICAgICB0aGlzLmFjdGl2ZV9jb21wb25lbnRzLmRlbGV0ZShjb21wb25lbnQpO1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBXYWl0IGZvciBhbGwgYWN0aXZlIGNvbXBvbmVudHMgdG8gcmVhY2ggcmVhZHkgc3RhdGVcbiAgICAgKi9cbiAgICBhc3luYyB3YWl0X2Zvcl9yZWFkeSgpIHtcbiAgICAgIGNvbnN0IHJlYWR5X3Byb21pc2VzID0gW107XG4gICAgICBmb3IgKGNvbnN0IGNvbXBvbmVudCBvZiB0aGlzLmFjdGl2ZV9jb21wb25lbnRzKSB7XG4gICAgICAgIGlmIChjb21wb25lbnQuX3JlYWR5X3N0YXRlIDwgNCkge1xuICAgICAgICAgIHJlYWR5X3Byb21pc2VzLnB1c2gobmV3IFByb21pc2UoKHJlc29sdmUpID0+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=
|