diff --git a/dist/index.js b/dist/index.js index 2fa03c3..5490a4d 100644 --- a/dist/index.js +++ b/dist/index.js @@ -46,7 +46,6 @@ __export(lib_exports, { v: () => v }); module.exports = __toCommonJS(lib_exports); -var textTag = "#text"; var isNodeJs = Boolean(typeof process !== "undefined" && process.versions && process.versions.node); function createDomElement(tag, isSVG = false) { return isSVG ? document.createElementNS("http://www.w3.org/2000/svg", tag) : document.createElement(tag); @@ -69,14 +68,14 @@ var isVnodeComponent = (object) => { }; function domToVnode(dom) { if (dom.nodeType === 3) { - const vnode2 = new Vnode(textTag, {}, [dom.nodeValue]); - vnode2.dom = dom; - return vnode2; + return dom.nodeValue; } const children = []; for (let i = 0, l = dom.childNodes.length; i < l; i++) { const childDom = dom.childNodes[i]; - if (childDom.nodeType === 1 || childDom.nodeType === 3) { + if (childDom.nodeType === 3) { + children.push(childDom.nodeValue); + } else if (childDom.nodeType === 1) { children.push(domToVnode(childDom)); } } @@ -165,14 +164,11 @@ function eventListener(e) { var hideDirective = (test) => (bool, vnode, oldnode) => { const value = test ? bool : !bool; if (value) { - const newdom = document.createTextNode(""); - if (oldnode && oldnode.dom && oldnode.dom.parentNode) { - oldnode.dom.parentNode.replaceChild(newdom, oldnode.dom); + const parentNode = vnode.dom?.parentNode; + if (parentNode) { + const newdom = document.createTextNode(""); + parentNode.replaceChild(newdom, vnode.dom); } - vnode.tag = "#text"; - vnode.children = []; - vnode.props = {}; - vnode.dom = newdom; return false; } }; @@ -419,7 +415,6 @@ function patch(newVnode, oldVnode) { newTree.splice(i, 1); newTreeLength = newTree.length; } else { - newTree[i] = new Vnode(textTag, {}, [newChild]); i++; } } @@ -474,31 +469,30 @@ function patch(newVnode, oldVnode) { const newChild = newTree[i2]; const oldChild = oldTree[i2]; const isGreaterThanOldTreeLength = i2 >= oldTreeLength; - if (newChild.tag === textTag) { - if (isGreaterThanOldTreeLength || oldChild.tag !== textTag) { - newChild.dom = document.createTextNode(newChild.children[0]); + if (newChild instanceof Vnode === false) { + if (isGreaterThanOldTreeLength || oldChild instanceof Vnode) { + const dom = document.createTextNode(newChild); if (isGreaterThanOldTreeLength) { - newVnode.dom.appendChild(newChild.dom); + newVnode.dom.appendChild(dom); } else { - newVnode.dom.replaceChild(newChild.dom, oldChild.dom); - } - } else { - newChild.dom = oldChild.dom; - if (newChild.children[0] !== oldChild.dom.textContent) { - oldChild.dom.textContent = newChild.children[0]; + newVnode.dom.replaceChild(dom, newVnode.dom.childNodes[i2]); } + continue; + } + if (newVnode.dom.childNodes[i2].textContent != newChild) { + newVnode.dom.childNodes[i2].textContent = newChild; } continue; } newChild.isSVG = newVnode.isSVG || newChild.tag === "svg"; - if (isGreaterThanOldTreeLength || newChild.tag !== oldChild.tag) { + if (isGreaterThanOldTreeLength || oldChild instanceof Vnode === false || newChild.tag !== oldChild.tag) { newChild.dom = createDomElement(newChild.tag, newChild.isSVG); - updateAttributes(newChild); if (isGreaterThanOldTreeLength) { newVnode.dom.appendChild(newChild.dom); } else { - newVnode.dom.replaceChild(newChild.dom, oldChild.dom); + newVnode.dom.replaceChild(newChild.dom, newVnode.dom.childNodes[i2]); } + updateAttributes(newChild); patch(newChild); continue; } diff --git a/dist/index.js.map b/dist/index.js.map index 5098892..93aad9c 100644 --- a/dist/index.js.map +++ b/dist/index.js.map @@ -1,7 +1,7 @@ { "version": 3, "sources": ["../lib/index.ts"], - "sourcesContent": ["/* eslint-disable no-use-before-define */\n/* eslint-disable indent */\n/* eslint-disable sonarjs/cognitive-complexity */\n/* eslint-disable complexity */\n\ninterface DefaultRecord extends Record {}\n\n// The VnodeProperties interface represents properties that can be passed to a virtual node.\nexport interface VnodeProperties extends DefaultRecord {\n // A unique key for the virtual node, which can be a string or a number.\n // This is useful for optimizing updates in a list of nodes.\n key?: string | number;\n // A state object that is associated with the virtual node.\n state?: any;\n}\n\n// The DomElement interface extends the Element interface with an index signature.\n// This allows for any additional properties to be added to DOM elements.\nexport interface DomElement extends Element, DefaultRecord {}\n\n// The VnodeInterface represents a virtual node. It has a number of optional fields,\n// including a tag, props, children, and a DOM element.\nexport interface VnodeInterface extends DefaultRecord {\n // The constructor for the virtual node. It takes a tag, props, and children as arguments.\n // The tag can be a string, a component, or a POJO component.\n // eslint-disable-next-line no-unused-vars\n new (tag: string | Component | POJOComponent, props: VnodeProperties, children: Children): VnodeInterface;\n // The tag for the virtual node. It can be a string, a component, or a POJO component.\n tag: string | Component | POJOComponent;\n // The props for the virtual node.\n props: VnodeProperties;\n // The children for the virtual node.\n children: Children;\n // A boolean indicating whether the virtual node is an SVG element.\n isSVG?: boolean;\n // The DOM element that corresponds to the virtual node.\n dom?: DomElement;\n // A boolean indicating whether the virtual node has been processed in the keyed diffing algorithm.\n processed?: boolean;\n}\n\n// The VnodeWithDom interface represents a virtual node that has a DOM element associated with it.\nexport interface VnodeWithDom extends VnodeInterface {\n dom: DomElement;\n}\n\n// The Component interface represents a function that returns a virtual node or a list of virtual nodes.\n// It can also have additional properties.\nexport interface Component extends DefaultRecord {\n // The function that returns a virtual node or a list of virtual nodes.\n // It can take props and children as arguments.\n // eslint-disable-next-line no-unused-vars\n (props?: VnodeProperties | null, ...children: any[]): VnodeInterface | Children | any;\n}\n\n// The POJOComponent interface represents a \"plain old JavaScript object\" (POJO) component.\n// It has a view function that returns a virtual node or a list of virtual nodes,\n// as well as optional props and children.\n// It can be used also to identify class instance components.\nexport interface POJOComponent extends DefaultRecord {\n // The view function that returns a virtual node or a list of virtual nodes.\n view: Component;\n // The props for the component.\n props?: VnodeProperties | null;\n // The children for the component.\n children?: any[];\n}\n\n// The VnodeComponentInterface represents a virtual node that has a component as its tag.\n// It has props and children, just like a regular virtual node.\nexport interface VnodeComponentInterface extends VnodeInterface {\n tag: Component | POJOComponent;\n props: VnodeProperties;\n children: Children;\n}\n\n// The Children interface represents a list of virtual nodes or other values.\nexport interface Children extends Array {}\n\n// The Directive interface represents a function that can be applied to a virtual node.\n// It receives the value, virtual node, and old virtual node as arguments, and can return a boolean value.\n// If only the virtual node is passed, it means its the on create phase for the v-node.\n// If the old virtual node is also passed, it means its the on update phase for the v-node.\nexport interface Directive {\n // eslint-disable-next-line no-unused-vars\n (value: any, vnode: VnodeWithDom, oldVnode?: VnodeWithDom): void | boolean;\n}\n\n// The Directives interface is a mapping of directive names to Directive functions.\nexport interface Directives extends Record {}\n\n// The ReservedProps interface is a mapping of reserved prop names to the value `true`.\n// These prop names cannot be used as custom prop names.\nexport interface ReservedProps extends Record {}\n\n// The Current interface represents the current component and virtual node that are being processed.\nexport interface Current {\n // The current component. It can be a component, a POJO component, or null.\n component: Component | POJOComponent | null;\n // The current virtual node. It must have a DOM element associated with it.\n vnode: VnodeWithDom | null;\n // The old virtual node. It must have a DOM element associated with it.\n oldVnode?: VnodeWithDom | null;\n // The current event. It can be an event or null.\n event: Event | null;\n}\n\n// The V function is the main function for creating virtual nodes.\n// It takes a tag or component, props, and children as arguments, and returns a virtual node.\nexport interface V {\n // eslint-disable-next-line no-unused-vars, no-use-before-define\n (tagOrComponent: string | Component | POJOComponent, props: VnodeProperties | null, ...children: Children):\n | VnodeInterface\n | VnodeComponentInterface;\n // eslint-disable-next-line no-unused-vars, no-use-before-define\n fragment(_: any, ...children: Children): Children;\n}\n\n// 'textTag' is a constant string that is used to represent text nodes in the virtual DOM.\nconst textTag = \"#text\";\n\n// 'isNodeJs' is a boolean that is true if the code is running in a Node.js environment and false otherwise.\n// It is determined by checking if the 'process' global object is defined and has a 'versions' property.\nexport const isNodeJs = Boolean(typeof process !== \"undefined\" && process.versions && process.versions.node);\n\n// 'createDomElement' is a function that creates a new DOM element with the specified tag name.\n// If 'isSVG' is true, it creates an SVG element instead of a regular DOM element.\nexport function createDomElement(tag: string, isSVG: boolean = false): DomElement {\n return isSVG ? document.createElementNS(\"http://www.w3.org/2000/svg\", tag) : document.createElement(tag);\n}\n\n// 'Vnode' is a class that represents a virtual DOM node.\n// It has three properties: 'tag', 'props', and 'children'.\n// 'Vnode' is exported as an object with a type of 'VnodeInterface'.\n// The 'as unknown as VnodeInterface' is used to tell TypeScript that the 'Vnode' function has the same type as 'VnodeInterface'.\nexport const Vnode = function Vnode(this: VnodeInterface, tag: string, props: VnodeProperties, children: Children) {\n // 'this' refers to the current instance of 'Vnode'.\n this.tag = tag;\n this.props = props;\n this.children = children;\n} as unknown as VnodeInterface;\n\n// 'isComponent' is a function that returns true if the given 'component' is a valid component and false otherwise.\n// A component is either a function or an object with a 'view' function.\nexport function isComponent(component: unknown): component is Component {\n return Boolean(\n component && (typeof component === \"function\" || (typeof component === \"object\" && \"view\" in component))\n );\n}\n\n// 'isVnode' is a function that returns true if the given 'object' is a 'Vnode' instance and false otherwise.\nexport const isVnode = (object?: unknown | VnodeInterface): object is VnodeInterface => {\n // Use the 'instanceof' operator to check if 'object' is an instance of 'Vnode'.\n return object instanceof Vnode;\n};\n\n// 'isVnodeComponent' is a function that returns true if the given 'object' is a 'Vnode' instance with a 'tag' property that is a valid component.\n// It returns false otherwise.\nexport const isVnodeComponent = (object?: unknown | VnodeComponentInterface): object is VnodeComponentInterface => {\n // Check if 'object' is a 'Vnode' instance and its 'tag' property is a valid component.\n return isVnode(object) && isComponent(object.tag);\n};\n\n// 'domToVnode' is a function that converts a DOM node to a 'Vnode' instance.\nexport function domToVnode(dom: any): VnodeWithDom {\n // If the child node is a text node, create a 'Vnode' instance with the 'textTag' constant as the 'tag' property.\n // Set the 'dom' property of the 'Vnode' instance to the child DOM node.\n // Push the 'Vnode' instance to the 'children' array.\n if (dom.nodeType === 3) {\n const vnode = new Vnode(textTag, {}, [dom.nodeValue]);\n vnode.dom = dom;\n return vnode as VnodeWithDom;\n }\n\n const children: VnodeWithDom[] = [];\n // Iterate through all child nodes of 'dom'.\n for (let i = 0, l = dom.childNodes.length; i < l; i++) {\n const childDom = dom.childNodes[i];\n // If the child node is an element node, recursively call 'domToVnode' to convert it to a 'Vnode' instance.\n // Push the 'Vnode' instance to the 'children' array.\n if (childDom.nodeType === 1 || childDom.nodeType === 3) {\n children.push(domToVnode(childDom));\n }\n }\n\n const props: VnodeProperties = {};\n // Iterate through all attributes of 'dom'.\n for (let i = 0, l = dom.attributes.length; i < l; i++) {\n const attr = dom.attributes[i];\n // Add the attribute to the 'props' object, using the attribute's name as the key and its value as the value.\n props[attr.nodeName] = attr.nodeValue;\n }\n\n // Create a new 'Vnode' instance with the 'tag' property set to the lowercase version of the DOM node's tag name.\n // Set the 'props' and 'children' properties to the 'props' and 'children' arrays respectively.\n // Set the 'dom' property of the 'Vnode' instance to the DOM node.\n const vnode = new Vnode(dom.tagName.toLowerCase(), props, children);\n vnode.dom = dom;\n return vnode as VnodeWithDom;\n}\n\n// This function takes in an HTML string and creates a virtual node representation of it\n// using the `domToVnode` function. It does this by creating a new `div` element, setting\n// its `innerHTML` to the provided HTML string, and then using `map` to iterate over the\n// `childNodes` of the `div` element, passing each one to `domToVnode` to create a virtual\n// node representation of it. The resulting array of virtual nodes is then returned.\nexport function trust(htmlString: string) {\n const div = createDomElement(\"div\");\n div.innerHTML = htmlString.trim();\n\n return [].map.call(div.childNodes, (item) => domToVnode(item));\n}\n\n/* ========================================================================== */\n/* Main Component implementation */\n/* ========================================================================== */\n\n// These variables are used to store the main component, the main virtual node, and whether\n// the main component is currently mounted.\nlet mainComponent: VnodeComponentInterface | null = null;\nlet mainVnode: VnodeWithDom | null = null;\nlet isMounted = false;\n\n// This object is used to store the current virtual node and component being rendered.\nexport const current: Current = {\n vnode: null,\n oldVnode: null,\n component: null,\n event: null\n};\n\n/* Reserved props ----------------------------------------------------------- */\n// This object is used to store the names of reserved props, which are props that are reserved\n// for special purposes and should not be used as regular component props.\nexport const reservedProps: Record = {\n key: true,\n state: true,\n \"v-keep\": true,\n\n // Built in directives\n \"v-if\": true,\n \"v-unless\": true,\n \"v-for\": true,\n \"v-show\": true,\n \"v-class\": true,\n \"v-html\": true,\n \"v-model\": true,\n \"v-create\": true,\n \"v-update\": true,\n \"v-cleanup\": true\n};\n\n/* Mounting, Updating, Cleanup and Unmounting ------------------------------- */\n// These sets are used to store callbacks for various lifecycle events: mounting, updating,\n// cleaning up, and unmounting.\nconst onCleanupSet: Set = new Set();\nconst onMountSet: Set = new Set();\nconst onUpdateSet: Set = new Set();\nconst onUnmountSet: Set = new Set();\n\n// These functions allow users to register callbacks for the corresponding lifecycle events.\nexport function onMount(callback: Function) {\n if (!isMounted) {\n onMountSet.add(callback);\n }\n}\n\nexport function onUpdate(callback: Function) {\n onUpdateSet.add(callback);\n}\n\nexport function onCleanup(callback: Function) {\n onCleanupSet.add(callback);\n}\n\nexport function onUnmount(callback: Function) {\n if (!isMounted) {\n onUnmountSet.add(callback);\n }\n}\n\n// This function is used to call all the callbacks in a given set.\nfunction callSet(set: Set) {\n for (const callback of set) {\n callback();\n }\n\n set.clear();\n}\n\n/* Event listener ----------------------------------------------------------- */\n\n// This object stores the names of event listeners that have been added\nconst eventListenerNames: Record = {};\n\n// This function is called when an event occurs\nfunction eventListener(e: Event) {\n // Set the current event to the event that occurred so that it can be prevented if necessary\n current.event = e;\n\n // Convert the target of the event to a DOM element\n let dom = e.target as DomElement;\n\n // Create the name of the event listener by adding \"v-on\" to the event type\n const name = `v-on${e.type}`;\n\n // Keep going up the DOM tree until we find an element with an event listener\n // matching the event type\n while (dom) {\n if (dom[name]) {\n // Call the event listener function\n dom[name](e, dom);\n\n // If the default action of the event hasn't been prevented, update the DOM\n if (!e.defaultPrevented) {\n update();\n }\n return;\n }\n dom = dom.parentNode as DomElement;\n }\n\n current.event = null;\n}\n\n/* Directives --------------------------------------------------------------- */\n\n// This function creates a directive that hides an element based on a condition\nconst hideDirective = (test: boolean) => (bool: boolean, vnode: VnodeInterface, oldnode?: VnodeInterface) => {\n // If test is true, use the value of bool. Otherwise, use the opposite of bool.\n const value = test ? bool : !bool;\n\n // If the value is true, hide the element by replacing it with a text node\n if (value) {\n const newdom = document.createTextNode(\"\");\n if (oldnode && oldnode.dom && oldnode.dom.parentNode) {\n oldnode.dom.parentNode.replaceChild(newdom, oldnode.dom);\n }\n vnode.tag = \"#text\";\n vnode.children = [];\n vnode.props = {};\n vnode.dom = newdom as unknown as DomElement;\n return false;\n }\n};\n\n// This object stores all the available directives\nexport const directives: Directives = {\n // The \"v-if\" directive hides an element if the given condition is false\n \"v-if\": hideDirective(false),\n\n // The \"v-unless\" directive hides an element if the given condition is true\n \"v-unless\": hideDirective(true),\n\n // The \"v-for\" directive creates a loop and applies a callback function to each item in the loop\n \"v-for\": (set: unknown[], vnode: VnodeWithDom) => {\n const newChildren: VnodeInterface[] = [];\n const callback = vnode.children[0];\n for (let i = 0, l = set.length; i < l; i++) {\n newChildren.push(callback(set[i], i));\n }\n vnode.children = newChildren;\n },\n\n // The \"v-show\" directive shows or hides an element by setting the \"display\" style property\n \"v-show\": (bool: boolean, vnode: VnodeWithDom) => {\n (\n vnode.dom as unknown as {\n style: { display: string };\n }\n ).style.display = bool ? \"\" : \"none\";\n },\n\n // The \"v-class\" directive adds or removes class names from an element based on a condition\n \"v-class\": (classes: { [x: string]: boolean }, vnode: VnodeWithDom) => {\n // Loop through all the class names in the classes object\n for (const name in classes) {\n // Add or remove the class name from the element's class list based on the value in the classes object\n (vnode.dom as DomElement).classList.toggle(name, classes[name]);\n }\n },\n\n // The \"v-html\" directive sets the inner HTML of an element to the given HTML string\n \"v-html\": (html: string, vnode: VnodeWithDom) => {\n // Set the children of the vnode to a trusted version of the HTML string\n vnode.children = [trust(html)];\n },\n\n // The \"v-model\" directive binds the value of an input element to a model property\n \"v-model\": ([model, property, event]: any[], vnode: VnodeWithDom, oldVnode?: VnodeWithDom) => {\n let value;\n // This function updates the model property when the input element's value changes\n let handler = (e: Event) => (model[property] = (e.target as DomElement & Record).value);\n if (vnode.tag === \"input\") {\n // If the element is an input, use the \"input\" event by default\n event = event || \"oninput\";\n // Depending on the type of input element, use a different handler function\n switch (vnode.props.type) {\n case \"checkbox\": {\n if (Array.isArray(model[property])) {\n // If the model property is an array, add or remove the value from the array when the checkbox is checked or unchecked\n handler = (e: Event) => {\n const val = (e.target as DomElement & Record).value;\n const idx = model[property].indexOf(val);\n if (idx === -1) {\n model[property].push(val);\n } else {\n model[property].splice(idx, 1);\n }\n };\n // If the value is in the array, set the checkbox to be checked\n value = model[property].indexOf(vnode.dom.value) !== -1;\n } else if (\"value\" in vnode.props) {\n // If the input element has a \"value\" attribute, use it to determine the checked state\n handler = () => {\n if (model[property] === vnode.props.value) {\n model[property] = null;\n } else {\n model[property] = vnode.props.value;\n }\n };\n value = model[property] === vnode.props.value;\n } else {\n // If there is no \"value\" attribute, use a boolean value for the model property\n handler = () => (model[property] = !model[property]);\n value = model[property];\n }\n // Set the \"checked\" attribute on the input element\n // eslint-disable-next-line no-use-before-define\n sharedSetAttribute(\"checked\", value, vnode);\n break;\n }\n case \"radio\": {\n // If the element is a radio button, set the \"checked\" attribute based on the value of the model property\n // eslint-disable-next-line no-use-before-define\n sharedSetAttribute(\"checked\", model[property] === vnode.dom.value, vnode);\n break;\n }\n default: {\n // For all other input types, set the \"value\" attribute based on the value of the model property\n // eslint-disable-next-line no-use-before-define\n sharedSetAttribute(\"value\", model[property], vnode);\n }\n }\n } else if (vnode.tag === \"select\") {\n // If the element is a select element, use the \"click\" event by default\n event = event || \"onclick\";\n if (vnode.props.multiple) {\n // If the select element allows multiple selections, update the model property with an array of selected values\n handler = (e: Event & Record) => {\n const val = (e.target as DomElement & Record).value;\n if (e.ctrlKey) {\n // If the Ctrl key is pressed, add or remove the value from the array\n const idx = model[property].indexOf(val);\n if (idx === -1) {\n model[property].push(val);\n } else {\n model[property].splice(idx, 1);\n }\n } else {\n // If the Ctrl key is not pressed, set the model property to an array with the selected value\n model[property].splice(0, model[property].length);\n model[property].push(val);\n }\n };\n // Set the \"selected\" attribute on the options based on whether they are in the model property array\n vnode.children.forEach((child: VnodeInterface) => {\n if (child.tag === \"option\") {\n const value = \"value\" in child.props ? child.props.value : child.children.join(\"\").trim();\n child.props.selected = model[property].indexOf(value) !== -1;\n }\n });\n } else {\n // If the select element does not allow multiple selections, set the \"selected\" attribute on the options based on the value of the model property\n vnode.children.forEach((child: VnodeInterface) => {\n if (child.tag === \"option\") {\n const value = \"value\" in child.props ? child.props.value : child.children.join(\"\").trim();\n child.props.selected = value === model[property];\n }\n });\n }\n } else if (vnode.tag === \"textarea\") {\n // If the element is a textarea, use the \"input\" event by default\n event = event || \"oninput\";\n // Set the textarea's content to the value of the model property\n vnode.children = [model[property]];\n }\n\n // We assume that the prev handler if any will not be changed by the user across patchs\n const prevHandler = vnode.props[event];\n\n // Set the event handler on the element\n // eslint-disable-next-line no-use-before-define\n sharedSetAttribute(\n event,\n (e: Event) => {\n handler(e);\n\n // If the previous handler is defined, call it after the model has been updated\n if (prevHandler) {\n prevHandler(e);\n }\n },\n vnode,\n oldVnode\n );\n },\n\n // The \"v-create\" directive is called when a new virtual node is created.\n // The provided callback function is called with the new virtual node as an argument.\n // This directive is only called once per virtual node, when it is first created.\n // eslint-disable-next-line no-unused-vars\n \"v-create\": (callback: (vnode: VnodeWithDom) => void, vnode: VnodeWithDom, oldVnode?: VnodeWithDom) => {\n // If this is not an update, call the callback function with the new virtual node\n if (!oldVnode) {\n const cleanup = callback(vnode);\n\n // If the callback function returns a function, call it when the update is gonna be cleaned up\n if (typeof cleanup === \"function\") {\n onCleanup(cleanup);\n }\n }\n },\n\n // The \"v-update\" directive is called when an existing virtual node is updated.\n // The provided callback function is called with the new and old virtual nodes as arguments.\n // This directive is only called once per virtual node update.\n \"v-update\": (\n // eslint-disable-next-line no-unused-vars\n callback: (vnode: VnodeWithDom, oldVnode: VnodeWithDom) => void,\n vnode: VnodeWithDom,\n oldVnode?: VnodeWithDom\n ) => {\n // If this is an update, call the callback function with the new and old virtual nodes\n if (oldVnode) {\n const cleanup = callback(vnode, oldVnode);\n\n // If the callback function returns a function, call it when the update is gonna be cleaned up\n if (typeof cleanup === \"function\") {\n onCleanup(cleanup);\n }\n }\n },\n\n // The \"v-cleanup\" directive is called when the update is cleaned up.\n // The provided callback function is called with the old virtual node as an argument.\n // This directive is only called once per virtual node, when the update is cleaned up.\n \"v-cleanup\": (\n // eslint-disable-next-line no-unused-vars\n callback: (vnode: VnodeWithDom, oldVnode?: VnodeWithDom) => void,\n vnode: VnodeWithDom,\n oldVnode?: VnodeWithDom\n ) => {\n // Add the callback function to the list of cleanup functions to be called when the update is cleaned up\n onCleanup(() => callback(vnode, oldVnode));\n }\n};\n// Add a directive to the global directives object, with the key being the name\n// preceded by \"v-\". Also add the name to the global reservedProps object.\nexport function directive(name: string, directive: Directive) {\n const directiveName = `v-${name}`;\n directives[directiveName] = directive;\n reservedProps[directiveName] = true;\n}\n\n// Set an attribute on a virtual DOM node and update the actual DOM element.\n// If the attribute value is a function, add an event listener for the attribute\n// name to the DOM element represented by mainVnode.\n// If oldVnode is provided, compare the new attribute value to the old value\n// and only update the attribute if the values are different.\nfunction sharedSetAttribute(name: string, value: any, newVnode: VnodeWithDom, oldVnode?: VnodeWithDom): void | boolean {\n // If the attribute value is a function, add an event listener for the attribute\n // name to the DOM element represented by mainVnode.\n if (typeof value === \"function\") {\n // Only add the event listener if it hasn't been added yet.\n if (name in eventListenerNames === false) {\n (mainVnode as VnodeWithDom).dom.addEventListener(name.slice(2), eventListener);\n eventListenerNames[name] = true;\n }\n newVnode.dom[`v-${name}`] = value;\n return;\n }\n\n // If the attribute is present on the DOM element and newVnode is not an SVG,\n // update the attribute if the value has changed.\n if (newVnode.isSVG === false && name in newVnode.dom) {\n // eslint-disable-next-line eqeqeq\n if (newVnode.dom[name] != value) {\n newVnode.dom[name] = value;\n }\n return;\n }\n\n // If oldVnode is not provided or the attribute value has changed, update the\n // attribute on the DOM element.\n if (!oldVnode || value !== oldVnode.props[name]) {\n if (value === false) {\n newVnode.dom.removeAttribute(name);\n } else {\n newVnode.dom.setAttribute(name, value);\n }\n }\n}\n\n// Set an attribute on a virtual DOM node and update the actual DOM element.\n// Skip the attribute if it is in the reservedProps object.\nexport function setAttribute(name: string, value: any, newVnode: VnodeWithDom, oldVnode?: VnodeWithDom): void {\n if (reservedProps[name]) {\n return;\n }\n newVnode.props[name] = value;\n sharedSetAttribute(name, value, newVnode, oldVnode);\n}\n\n// Update the attributes on a virtual DOM node. If oldVnode is provided, remove\n// attributes from the DOM element that are not present in newVnode.props but are\n// present in oldVnode.props. Then, iterate over the attributes in newVnode.props\n// and update the DOM element with the attributes using the sharedSetAttribute\n// function. If an attribute is in the reservedProps object and has a corresponding\n// directive in the directives object, call the directive with the attribute value\n// and the two virtual DOM nodes as arguments. If the directive returns false, exit\n// the loop.\nexport function updateAttributes(newVnode: VnodeWithDom, oldVnode?: VnodeWithDom): void {\n // If oldVnode is provided, remove attributes from the DOM element that are not\n // present in newVnode.props but are present in oldVnode.props.\n if (oldVnode) {\n for (const name in oldVnode.props) {\n if (!newVnode.props[name] && !eventListenerNames[name] && !reservedProps[name]) {\n if (newVnode.isSVG === false && name in newVnode.dom) {\n newVnode.dom[name] = null;\n } else {\n newVnode.dom.removeAttribute(name);\n }\n }\n }\n }\n\n // Iterate over the attributes in newVnode.props and update the DOM element with\n // the attributes using the sharedSetAttribute function.\n for (const name in newVnode.props) {\n if (reservedProps[name]) {\n // If there is a directive for the attribute, call it with the attribute value\n // and the two virtual DOM nodes as arguments. If the directive returns false,\n // exit the loop.\n if (directives[name] && directives[name](newVnode.props[name], newVnode, oldVnode) === false) {\n break;\n }\n continue;\n }\n sharedSetAttribute(name, newVnode.props[name], newVnode, oldVnode);\n }\n}\n\n/* patch ------------------------------------------------------------------- */\n\n// Patch a DOM node with a new VNode tree\nexport function patch(newVnode: VnodeWithDom, oldVnode?: VnodeWithDom): void {\n // If the new tree has no children, set the text content of the parent DOM element to an empty string\n if (newVnode.children.length === 0) {\n newVnode.dom.textContent = \"\";\n return;\n }\n\n // Get the children of the new and old virtual DOM nodes\n const newTree = newVnode.children;\n const oldTree = oldVnode?.children || [];\n // Get the length of the old tree\n const oldTreeLength = oldTree.length;\n // Get the length of the new tree\n let newTreeLength = newTree.length;\n // Set the global current object to the new and old virtual DOM nodes\n current.vnode = newVnode;\n current.oldVnode = oldVnode;\n\n // Flatten the new tree\n // Take into account that is necessary to flatten the tree before the patch process\n // to let the hooks and signals work properly\n let i = 0;\n while (i < newTreeLength) {\n const newChild = newTree[i];\n\n // If the new child is a Vnode and is not a text node\n if (newChild instanceof Vnode) {\n // If the tag of the new child is not a string, it is a component\n if (typeof newChild.tag !== \"string\") {\n // Set the current component to the tag of the new child\n current.component = newChild.tag;\n // Replace the new child with the result of calling its view or bind method, passing in the props and children as arguments\n newTree.splice(\n i,\n 1,\n (\"view\" in newChild.tag ? newChild.tag.view.bind(newChild.tag) : newChild.tag.bind(newChild.tag))(\n newChild.props,\n ...newChild.children\n )\n );\n newTreeLength = newTree.length;\n continue;\n } else {\n i++;\n }\n // If the new child is an array, flatten it and continue the loop\n } else if (Array.isArray(newChild)) {\n newTree.splice(i, 1, ...newChild);\n newTreeLength = newTree.length;\n // If the new child is null or undefined, remove it from the new tree and continue the loop\n } else if (newChild == null) {\n newTree.splice(i, 1);\n newTreeLength = newTree.length;\n } else {\n // If the new child is a Vnode, set the text of the Vnode to the text content of its dom property\n newTree[i] = new Vnode(textTag, {}, [newChild]);\n i++;\n }\n }\n\n // If the new tree has no children, set the text content of the parent DOM element to an empty string\n if (newTreeLength === 0) {\n newVnode.dom.textContent = \"\";\n return;\n }\n\n // If the old tree has children and the first child of the new tree is a VNode with a \"key\"\n // attribute and the first child of the old tree is a VNode with a \"key\" attribute, update\n // the DOM element in place by comparing the keys of the nodes in the trees.\n if (\n oldTreeLength > 0 &&\n newTree[0] instanceof Vnode &&\n oldTree[0] instanceof Vnode &&\n \"key\" in newTree[0].props &&\n \"key\" in oldTree[0].props\n ) {\n const oldKeyedList: Record = {};\n const newKeyedList: Record = {};\n const childNodes = newVnode.dom.childNodes;\n\n // Create key maps while also handling removal of nodes not present in newTree\n for (let i = 0; i < oldTreeLength; i++) {\n oldKeyedList[oldTree[i].props.key] = i;\n if (i < newTreeLength) {\n newKeyedList[newTree[i].props.key] = i;\n }\n }\n\n for (let i = 0; i < newTreeLength; i++) {\n const newChild = newTree[i];\n const oldChildIndex = oldKeyedList[newChild.props.key];\n const oldChild = oldTree[oldChildIndex];\n let shouldPatch = true;\n\n if (oldChild) {\n newChild.dom = oldChild.dom;\n if (\"v-keep\" in newChild.props && newChild.props[\"v-keep\"] === oldChild.props[\"v-keep\"]) {\n newChild.children = oldChild.children;\n shouldPatch = false;\n } else {\n updateAttributes(newChild, oldChild);\n }\n } else {\n newChild.dom = createDomElement(newChild.tag, newChild.isSVG);\n updateAttributes(newChild);\n }\n\n const currentNode = childNodes[i];\n if (!currentNode) {\n newVnode.dom.appendChild(newChild.dom);\n } else if (currentNode !== newChild.dom) {\n newVnode.dom.replaceChild(newChild.dom, currentNode);\n }\n\n shouldPatch && patch(newChild, oldChild);\n }\n\n // Remove nodes that don't exist in newTree\n for (let i = newTreeLength; i < oldTreeLength; i++) {\n if (!newKeyedList[oldTree[i].props.key]) {\n const domToRemove = oldTree[i].dom;\n domToRemove.parentNode && domToRemove.parentNode.removeChild(domToRemove);\n }\n }\n return;\n }\n\n // Patch the the old tree\n for (let i = 0; i < newTreeLength; i++) {\n const newChild = newTree[i];\n const oldChild = oldTree[i];\n const isGreaterThanOldTreeLength = i >= oldTreeLength;\n\n // Handle text nodes\n if (newChild.tag === textTag) {\n // If there's no corresponding old child or the old child isn't a text node\n if (isGreaterThanOldTreeLength || oldChild.tag !== textTag) {\n newChild.dom = document.createTextNode(newChild.children[0]); // Create a new text node\n if (isGreaterThanOldTreeLength) {\n // If there's no corresponding old child, append the new text node\n newVnode.dom.appendChild(newChild.dom);\n } else {\n // Replace the old non-text node with the new text node\n newVnode.dom.replaceChild(newChild.dom, oldChild.dom);\n }\n } else {\n // Update the old text node if content has changed\n newChild.dom = oldChild.dom;\n if (newChild.children[0] !== oldChild.dom.textContent) {\n oldChild.dom.textContent = newChild.children[0];\n }\n }\n continue;\n }\n\n // If the new child is not a text node\n // Set the isSVG flag for the new child if it is an SVG element or if the parent is an SVG element\n newChild.isSVG = newVnode.isSVG || newChild.tag === \"svg\";\n\n // If the tag of the new child is different from the tag of the old child\n if (isGreaterThanOldTreeLength || newChild.tag !== oldChild.tag) {\n // Create a new dom element for the new child\n newChild.dom = createDomElement(newChild.tag as string, newChild.isSVG);\n // Update the attributes of the new child\n updateAttributes(newChild as VnodeWithDom);\n if (isGreaterThanOldTreeLength) {\n // Append the new child to the dom\n newVnode.dom.appendChild(newChild.dom);\n } else {\n // Replace the old child in the dom with the new child\n newVnode.dom.replaceChild(newChild.dom, oldChild.dom);\n }\n // Recursively patch the new child\n patch(newChild as VnodeWithDom);\n continue;\n }\n\n // If the tag of the new child is the same as the tag of the old child\n // Set the dom property of the new child to the dom property of the old child\n newChild.dom = oldChild.dom;\n // If the v-keep prop is the same for both the new and old child, set the children of the new child to the children of the old child\n if (\"v-keep\" in newChild.props && newChild.props[\"v-keep\"] === oldChild.props[\"v-keep\"]) {\n newChild.children = oldChild.children;\n continue;\n }\n\n // Update the attributes of the new child based on the old child\n updateAttributes(newChild as VnodeWithDom, oldChild);\n // Recursively patch the new and old children\n patch(newChild as VnodeWithDom, oldChild);\n }\n\n // Remove any old children that are no longer present in the new tree\n for (; newTreeLength < oldTreeLength; newTreeLength++) {\n newVnode.dom.removeChild(oldTree[newTreeLength].dom);\n }\n}\n\n// Update the main Vnode\nexport function update(): void | string {\n // If the main Vnode exists\n if (mainVnode) {\n // Call any cleanup functions that are registered with the onCleanupSet set\n callSet(onCleanupSet);\n // Store a reference to the old main Vnode\n const oldMainVnode = mainVnode;\n // Create a new main Vnode with the main component as its only child\n mainVnode = new Vnode(oldMainVnode.tag, oldMainVnode.props, [mainComponent]) as VnodeWithDom;\n mainVnode.dom = oldMainVnode.dom;\n mainVnode.isSVG = oldMainVnode.isSVG;\n\n // Recursively patch the new and old main Vnodes\n patch(mainVnode, oldMainVnode);\n\n // Call any update or mount functions that are registered with the onUpdateSet or onMountSet set\n callSet(isMounted ? onUpdateSet : onMountSet);\n\n // Set the isMounted flag to true\n isMounted = true;\n\n // Reset the current vnode, oldVnode, and component properties\n current.vnode = null;\n current.oldVnode = null;\n current.component = null;\n\n // If the code is running in a Node.js environment, return the inner HTML of the main Vnode's dom element\n if (isNodeJs) {\n return mainVnode.dom.innerHTML;\n }\n }\n}\n\n// Update custom Vnode\n// It is assumed that a first mount has already occurred, so,\n// the oldVnode is not null and the dom property of the oldVnode is not null\n// You need to set the dom property of the newVnode to the dom property of the oldVnode\n// The same with the isSVG property\n// Prefer this function over patch to allow for cleanup, onUpdate and onMount sets to be called\nexport function updateVnode(vnode: VnodeWithDom, oldVnode: VnodeWithDom): string | void {\n // Call any cleanup functions that are registered with the onCleanupSet set\n callSet(onCleanupSet);\n\n // Recursively patch the new and old main Vnodes\n patch(vnode, oldVnode);\n\n // Set the oldVnode's tag, props, children, dom, and isSVG properties to the newVnode's tag, props, children, dom, and isSVG properties\n // This is necessary to allow for the oldVnode to be used as the newVnode in the next update with the normal update function\n oldVnode.tag = vnode.tag;\n oldVnode.props = { ...vnode.props };\n oldVnode.children = [...vnode.children];\n oldVnode.dom = vnode.dom;\n oldVnode.isSVG = vnode.isSVG;\n\n // Call any update or mount functions that are registered with the onUpdateSet or onMountSet set\n callSet(isMounted ? onUpdateSet : onMountSet);\n\n // Set the isMounted flag to true\n isMounted = true;\n\n // Reset the current vnode, oldVnode, and component properties\n current.vnode = null;\n current.oldVnode = null;\n current.component = null;\n\n if (isNodeJs) {\n return vnode.dom.innerHTML;\n }\n}\n\n// Unmount the main Vnode\nexport function unmount() {\n // If the main Vnode exists\n if (mainVnode) {\n // Set the main component to a null Vnode\n mainComponent = new Vnode(() => null, {}, []) as VnodeComponentInterface;\n // Update the main Vnode\n const result = update();\n // Call any unmount functions that are registered with the onUnmountSet set\n callSet(onUnmountSet);\n\n // Remove any event listeners that were added to the main Vnode's dom element\n for (const name in eventListenerNames) {\n mainVnode.dom.removeEventListener(name.slice(2).toLowerCase(), eventListener);\n Reflect.deleteProperty(eventListenerNames, name);\n }\n\n // Reset the main component and main Vnode\n mainComponent = null;\n mainVnode = null;\n // Set the isMounted flag to false\n isMounted = false;\n // Reset the current vnode, oldVnode, and component properties\n current.vnode = null;\n current.oldVnode = null;\n current.component = null;\n // Return the result of updating the main Vnode\n return result;\n }\n}\n// This function takes in a DOM element or a DOM element selector and a component to be mounted on it.\nexport function mount(dom: string | DomElement, component: any) {\n // Check if the 'dom' argument is a string. If it is, select the first element that matches the given selector.\n // Otherwise, use the 'dom' argument as the container.\n const container =\n typeof dom === \"string\"\n ? isNodeJs\n ? createDomElement(dom, dom === \"svg\")\n : document.querySelectorAll(dom)[0]\n : dom;\n\n // Check if the 'component' argument is a Vnode component or a regular component.\n // If it's a regular component, create a new Vnode component using the 'component' argument as the tag.\n // If it's not a component at all, create a new Vnode component with the 'component' argument as the rendering function.\n const vnodeComponent = isVnodeComponent(component)\n ? component\n : isComponent(component)\n ? new Vnode(component, {}, [])\n : new Vnode(() => component, {}, []);\n\n // If a main component already exists and it's not the same as the current 'vnodeComponent', unmount it.\n if (mainComponent && mainComponent.tag !== vnodeComponent.tag) {\n unmount();\n }\n\n // Set the 'vnodeComponent' as the main component.\n mainComponent = vnodeComponent as VnodeComponentInterface;\n // Convert the container element to a Vnode.\n mainVnode = domToVnode(container);\n // Update the DOM with the new component.\n return update();\n}\n\n// This is a utility function for creating Vnode objects.\n// It takes in a tag or component, and optional props and children arguments.\nexport const v: V = (tagOrComponent, props, ...children) => {\n // Return a new Vnode object using the given arguments.\n return new Vnode(tagOrComponent, props || {}, children);\n};\n\n// This utility function creates a fragment Vnode.\n// It takes in a placeholder and the children arguments, returns only the children.\nv.fragment = (_: VnodeProperties, ...children: Children) => children;\n"], - "mappings": "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", - "names": ["Vnode", "vnode", "value", "directive", "i"] + "sourcesContent": ["/* eslint-disable no-use-before-define */\n/* eslint-disable indent */\n/* eslint-disable sonarjs/cognitive-complexity */\n/* eslint-disable complexity */\n\ninterface DefaultRecord extends Record {}\n\n// The VnodeProperties interface represents properties that can be passed to a virtual node.\nexport interface VnodeProperties extends DefaultRecord {\n // A unique key for the virtual node, which can be a string or a number.\n // This is useful for optimizing updates in a list of nodes.\n key?: string | number;\n // A state object that is associated with the virtual node.\n state?: any;\n}\n\n// The DomElement interface extends the Element interface with an index signature.\n// This allows for any additional properties to be added to DOM elements.\nexport interface DomElement extends Element, DefaultRecord {}\n\n// The VnodeInterface represents a virtual node. It has a number of optional fields,\n// including a tag, props, children, and a DOM element.\nexport interface VnodeInterface extends DefaultRecord {\n // The constructor for the virtual node. It takes a tag, props, and children as arguments.\n // The tag can be a string, a component, or a POJO component.\n // eslint-disable-next-line no-unused-vars\n new (tag: string | Component | POJOComponent, props: VnodeProperties, children: Children): VnodeInterface;\n // The tag for the virtual node. It can be a string, a component, or a POJO component.\n tag: string | Component | POJOComponent;\n // The props for the virtual node.\n props: VnodeProperties;\n // The children for the virtual node.\n children: Children;\n // A boolean indicating whether the virtual node is an SVG element.\n isSVG?: boolean;\n // The DOM element that corresponds to the virtual node.\n dom?: DomElement;\n // A boolean indicating whether the virtual node has been processed in the keyed diffing algorithm.\n processed?: boolean;\n}\n\n// The VnodeWithDom interface represents a virtual node that has a DOM element associated with it.\nexport interface VnodeWithDom extends VnodeInterface {\n dom: DomElement;\n}\n\n// The Component interface represents a function that returns a virtual node or a list of virtual nodes.\n// It can also have additional properties.\nexport interface Component extends DefaultRecord {\n // The function that returns a virtual node or a list of virtual nodes.\n // It can take props and children as arguments.\n // eslint-disable-next-line no-unused-vars\n (props?: VnodeProperties | null, ...children: any[]): VnodeInterface | Children | any;\n}\n\n// The POJOComponent interface represents a \"plain old JavaScript object\" (POJO) component.\n// It has a view function that returns a virtual node or a list of virtual nodes,\n// as well as optional props and children.\n// It can be used also to identify class instance components.\nexport interface POJOComponent extends DefaultRecord {\n // The view function that returns a virtual node or a list of virtual nodes.\n view: Component;\n // The props for the component.\n props?: VnodeProperties | null;\n // The children for the component.\n children?: any[];\n}\n\n// The VnodeComponentInterface represents a virtual node that has a component as its tag.\n// It has props and children, just like a regular virtual node.\nexport interface VnodeComponentInterface extends VnodeInterface {\n tag: Component | POJOComponent;\n props: VnodeProperties;\n children: Children;\n}\n\n// The Children interface represents a list of virtual nodes or other values.\nexport interface Children extends Array {}\n\n// The Directive interface represents a function that can be applied to a virtual node.\n// It receives the value, virtual node, and old virtual node as arguments, and can return a boolean value.\n// If only the virtual node is passed, it means its the on create phase for the v-node.\n// If the old virtual node is also passed, it means its the on update phase for the v-node.\nexport interface Directive {\n // eslint-disable-next-line no-unused-vars\n (value: any, vnode: VnodeWithDom, oldVnode?: VnodeWithDom): void | boolean;\n}\n\n// The Directives interface is a mapping of directive names to Directive functions.\nexport interface Directives extends Record {}\n\n// The ReservedProps interface is a mapping of reserved prop names to the value `true`.\n// These prop names cannot be used as custom prop names.\nexport interface ReservedProps extends Record {}\n\n// The Current interface represents the current component and virtual node that are being processed.\nexport interface Current {\n // The current component. It can be a component, a POJO component, or null.\n component: Component | POJOComponent | null;\n // The current virtual node. It must have a DOM element associated with it.\n vnode: VnodeWithDom | null;\n // The old virtual node. It must have a DOM element associated with it.\n oldVnode?: VnodeWithDom | null;\n // The current event. It can be an event or null.\n event: Event | null;\n}\n\n// The V function is the main function for creating virtual nodes.\n// It takes a tag or component, props, and children as arguments, and returns a virtual node.\nexport interface V {\n // eslint-disable-next-line no-unused-vars, no-use-before-define\n (tagOrComponent: string | Component | POJOComponent, props: VnodeProperties | null, ...children: Children):\n | VnodeInterface\n | VnodeComponentInterface;\n // eslint-disable-next-line no-unused-vars, no-use-before-define\n fragment(_: any, ...children: Children): Children;\n}\n\n// 'textTag' is a constant string that is used to represent text nodes in the virtual DOM.\nconst textTag = \"#text\";\n\n// 'isNodeJs' is a boolean that is true if the code is running in a Node.js environment and false otherwise.\n// It is determined by checking if the 'process' global object is defined and has a 'versions' property.\nexport const isNodeJs = Boolean(typeof process !== \"undefined\" && process.versions && process.versions.node);\n\n// 'createDomElement' is a function that creates a new DOM element with the specified tag name.\n// If 'isSVG' is true, it creates an SVG element instead of a regular DOM element.\nexport function createDomElement(tag: string, isSVG: boolean = false): DomElement {\n return isSVG ? document.createElementNS(\"http://www.w3.org/2000/svg\", tag) : document.createElement(tag);\n}\n\n// 'Vnode' is a class that represents a virtual DOM node.\n// It has three properties: 'tag', 'props', and 'children'.\n// 'Vnode' is exported as an object with a type of 'VnodeInterface'.\n// The 'as unknown as VnodeInterface' is used to tell TypeScript that the 'Vnode' function has the same type as 'VnodeInterface'.\nexport const Vnode = function Vnode(this: VnodeInterface, tag: string, props: VnodeProperties, children: Children) {\n // 'this' refers to the current instance of 'Vnode'.\n this.tag = tag;\n this.props = props;\n this.children = children;\n} as unknown as VnodeInterface;\n\n// 'isComponent' is a function that returns true if the given 'component' is a valid component and false otherwise.\n// A component is either a function or an object with a 'view' function.\nexport function isComponent(component: unknown): component is Component {\n return Boolean(\n component && (typeof component === \"function\" || (typeof component === \"object\" && \"view\" in component))\n );\n}\n\n// 'isVnode' is a function that returns true if the given 'object' is a 'Vnode' instance and false otherwise.\nexport const isVnode = (object?: unknown | VnodeInterface): object is VnodeInterface => {\n // Use the 'instanceof' operator to check if 'object' is an instance of 'Vnode'.\n return object instanceof Vnode;\n};\n\n// 'isVnodeComponent' is a function that returns true if the given 'object' is a 'Vnode' instance with a 'tag' property that is a valid component.\n// It returns false otherwise.\nexport const isVnodeComponent = (object?: unknown | VnodeComponentInterface): object is VnodeComponentInterface => {\n // Check if 'object' is a 'Vnode' instance and its 'tag' property is a valid component.\n return isVnode(object) && isComponent(object.tag);\n};\n\n// 'domToVnode' is a function that converts a DOM node to a 'Vnode' instance.\nexport function domToVnode(dom: any): VnodeWithDom {\n // If the child node is a text node, create a 'Vnode' instance with the 'textTag' constant as the 'tag' property.\n // Set the 'dom' property of the 'Vnode' instance to the child DOM node.\n // Push the 'Vnode' instance to the 'children' array.\n if (dom.nodeType === 3) {\n return dom.nodeValue;\n }\n\n const children: VnodeWithDom[] = [];\n // Iterate through all child nodes of 'dom'.\n for (let i = 0, l = dom.childNodes.length; i < l; i++) {\n const childDom = dom.childNodes[i];\n // If the child node is an element node, recursively call 'domToVnode' to convert it to a 'Vnode' instance.\n // Push the 'Vnode' instance to the 'children' array.\n if (childDom.nodeType === 3) {\n children.push(childDom.nodeValue);\n } else if (childDom.nodeType === 1) {\n children.push(domToVnode(childDom));\n }\n }\n\n const props: VnodeProperties = {};\n // Iterate through all attributes of 'dom'.\n for (let i = 0, l = dom.attributes.length; i < l; i++) {\n const attr = dom.attributes[i];\n // Add the attribute to the 'props' object, using the attribute's name as the key and its value as the value.\n props[attr.nodeName] = attr.nodeValue;\n }\n\n // Create a new 'Vnode' instance with the 'tag' property set to the lowercase version of the DOM node's tag name.\n // Set the 'props' and 'children' properties to the 'props' and 'children' arrays respectively.\n // Set the 'dom' property of the 'Vnode' instance to the DOM node.\n const vnode = new Vnode(dom.tagName.toLowerCase(), props, children);\n vnode.dom = dom;\n return vnode as VnodeWithDom;\n}\n\n// This function takes in an HTML string and creates a virtual node representation of it\n// using the `domToVnode` function. It does this by creating a new `div` element, setting\n// its `innerHTML` to the provided HTML string, and then using `map` to iterate over the\n// `childNodes` of the `div` element, passing each one to `domToVnode` to create a virtual\n// node representation of it. The resulting array of virtual nodes is then returned.\nexport function trust(htmlString: string) {\n const div = createDomElement(\"div\");\n div.innerHTML = htmlString.trim();\n\n return [].map.call(div.childNodes, (item) => domToVnode(item));\n}\n\n/* ========================================================================== */\n/* Main Component implementation */\n/* ========================================================================== */\n\n// These variables are used to store the main component, the main virtual node, and whether\n// the main component is currently mounted.\nlet mainComponent: VnodeComponentInterface | null = null;\nlet mainVnode: VnodeWithDom | null = null;\nlet isMounted = false;\n\n// This object is used to store the current virtual node and component being rendered.\nexport const current: Current = {\n vnode: null,\n oldVnode: null,\n component: null,\n event: null\n};\n\n/* Reserved props ----------------------------------------------------------- */\n// This object is used to store the names of reserved props, which are props that are reserved\n// for special purposes and should not be used as regular component props.\nexport const reservedProps: Record = {\n key: true,\n state: true,\n \"v-keep\": true,\n\n // Built in directives\n \"v-if\": true,\n \"v-unless\": true,\n \"v-for\": true,\n \"v-show\": true,\n \"v-class\": true,\n \"v-html\": true,\n \"v-model\": true,\n \"v-create\": true,\n \"v-update\": true,\n \"v-cleanup\": true\n};\n\n/* Mounting, Updating, Cleanup and Unmounting ------------------------------- */\n// These sets are used to store callbacks for various lifecycle events: mounting, updating,\n// cleaning up, and unmounting.\nconst onCleanupSet: Set = new Set();\nconst onMountSet: Set = new Set();\nconst onUpdateSet: Set = new Set();\nconst onUnmountSet: Set = new Set();\n\n// These functions allow users to register callbacks for the corresponding lifecycle events.\nexport function onMount(callback: Function) {\n if (!isMounted) {\n onMountSet.add(callback);\n }\n}\n\nexport function onUpdate(callback: Function) {\n onUpdateSet.add(callback);\n}\n\nexport function onCleanup(callback: Function) {\n onCleanupSet.add(callback);\n}\n\nexport function onUnmount(callback: Function) {\n if (!isMounted) {\n onUnmountSet.add(callback);\n }\n}\n\n// This function is used to call all the callbacks in a given set.\nfunction callSet(set: Set) {\n for (const callback of set) {\n callback();\n }\n\n set.clear();\n}\n\n/* Event listener ----------------------------------------------------------- */\n\n// This object stores the names of event listeners that have been added\nconst eventListenerNames: Record = {};\n\n// This function is called when an event occurs\nfunction eventListener(e: Event) {\n // Set the current event to the event that occurred so that it can be prevented if necessary\n current.event = e;\n\n // Convert the target of the event to a DOM element\n let dom = e.target as DomElement;\n\n // Create the name of the event listener by adding \"v-on\" to the event type\n const name = `v-on${e.type}`;\n\n // Keep going up the DOM tree until we find an element with an event listener\n // matching the event type\n while (dom) {\n if (dom[name]) {\n // Call the event listener function\n dom[name](e, dom);\n\n // If the default action of the event hasn't been prevented, update the DOM\n if (!e.defaultPrevented) {\n update();\n }\n return;\n }\n dom = dom.parentNode as DomElement;\n }\n\n current.event = null;\n}\n\n/* Directives --------------------------------------------------------------- */\n\n// This function creates a directive that hides an element based on a condition\nconst hideDirective = (test: boolean) => (bool: boolean, vnode: VnodeWithDom, oldnode?: VnodeInterface) => {\n // If test is true, use the value of bool. Otherwise, use the opposite of bool.\n const value = test ? bool : !bool;\n\n // If the value is true, hide the element by replacing it with a text node\n if (value) {\n const parentNode = vnode.dom?.parentNode;\n if (parentNode) {\n const newdom = document.createTextNode(\"\");\n parentNode.replaceChild(newdom, vnode.dom);\n }\n\n return false;\n }\n};\n\n// This object stores all the available directives\nexport const directives: Directives = {\n // The \"v-if\" directive hides an element if the given condition is false\n \"v-if\": hideDirective(false),\n\n // The \"v-unless\" directive hides an element if the given condition is true\n \"v-unless\": hideDirective(true),\n\n // The \"v-for\" directive creates a loop and applies a callback function to each item in the loop\n \"v-for\": (set: unknown[], vnode: VnodeWithDom) => {\n const newChildren: VnodeInterface[] = [];\n const callback = vnode.children[0];\n for (let i = 0, l = set.length; i < l; i++) {\n newChildren.push(callback(set[i], i));\n }\n vnode.children = newChildren;\n },\n\n // The \"v-show\" directive shows or hides an element by setting the \"display\" style property\n \"v-show\": (bool: boolean, vnode: VnodeWithDom) => {\n (\n vnode.dom as unknown as {\n style: { display: string };\n }\n ).style.display = bool ? \"\" : \"none\";\n },\n\n // The \"v-class\" directive adds or removes class names from an element based on a condition\n \"v-class\": (classes: { [x: string]: boolean }, vnode: VnodeWithDom) => {\n // Loop through all the class names in the classes object\n for (const name in classes) {\n // Add or remove the class name from the element's class list based on the value in the classes object\n (vnode.dom as DomElement).classList.toggle(name, classes[name]);\n }\n },\n\n // The \"v-html\" directive sets the inner HTML of an element to the given HTML string\n \"v-html\": (html: string, vnode: VnodeWithDom) => {\n // Set the children of the vnode to a trusted version of the HTML string\n vnode.children = [trust(html)];\n },\n\n // The \"v-model\" directive binds the value of an input element to a model property\n \"v-model\": ([model, property, event]: any[], vnode: VnodeWithDom, oldVnode?: VnodeWithDom) => {\n let value;\n // This function updates the model property when the input element's value changes\n let handler = (e: Event) => (model[property] = (e.target as DomElement & Record).value);\n if (vnode.tag === \"input\") {\n // If the element is an input, use the \"input\" event by default\n event = event || \"oninput\";\n // Depending on the type of input element, use a different handler function\n switch (vnode.props.type) {\n case \"checkbox\": {\n if (Array.isArray(model[property])) {\n // If the model property is an array, add or remove the value from the array when the checkbox is checked or unchecked\n handler = (e: Event) => {\n const val = (e.target as DomElement & Record).value;\n const idx = model[property].indexOf(val);\n if (idx === -1) {\n model[property].push(val);\n } else {\n model[property].splice(idx, 1);\n }\n };\n // If the value is in the array, set the checkbox to be checked\n value = model[property].indexOf(vnode.dom.value) !== -1;\n } else if (\"value\" in vnode.props) {\n // If the input element has a \"value\" attribute, use it to determine the checked state\n handler = () => {\n if (model[property] === vnode.props.value) {\n model[property] = null;\n } else {\n model[property] = vnode.props.value;\n }\n };\n value = model[property] === vnode.props.value;\n } else {\n // If there is no \"value\" attribute, use a boolean value for the model property\n handler = () => (model[property] = !model[property]);\n value = model[property];\n }\n // Set the \"checked\" attribute on the input element\n // eslint-disable-next-line no-use-before-define\n sharedSetAttribute(\"checked\", value, vnode);\n break;\n }\n case \"radio\": {\n // If the element is a radio button, set the \"checked\" attribute based on the value of the model property\n // eslint-disable-next-line no-use-before-define\n sharedSetAttribute(\"checked\", model[property] === vnode.dom.value, vnode);\n break;\n }\n default: {\n // For all other input types, set the \"value\" attribute based on the value of the model property\n // eslint-disable-next-line no-use-before-define\n sharedSetAttribute(\"value\", model[property], vnode);\n }\n }\n } else if (vnode.tag === \"select\") {\n // If the element is a select element, use the \"click\" event by default\n event = event || \"onclick\";\n if (vnode.props.multiple) {\n // If the select element allows multiple selections, update the model property with an array of selected values\n handler = (e: Event & Record) => {\n const val = (e.target as DomElement & Record).value;\n if (e.ctrlKey) {\n // If the Ctrl key is pressed, add or remove the value from the array\n const idx = model[property].indexOf(val);\n if (idx === -1) {\n model[property].push(val);\n } else {\n model[property].splice(idx, 1);\n }\n } else {\n // If the Ctrl key is not pressed, set the model property to an array with the selected value\n model[property].splice(0, model[property].length);\n model[property].push(val);\n }\n };\n // Set the \"selected\" attribute on the options based on whether they are in the model property array\n vnode.children.forEach((child: VnodeInterface) => {\n if (child.tag === \"option\") {\n const value = \"value\" in child.props ? child.props.value : child.children.join(\"\").trim();\n child.props.selected = model[property].indexOf(value) !== -1;\n }\n });\n } else {\n // If the select element does not allow multiple selections, set the \"selected\" attribute on the options based on the value of the model property\n vnode.children.forEach((child: VnodeInterface) => {\n if (child.tag === \"option\") {\n const value = \"value\" in child.props ? child.props.value : child.children.join(\"\").trim();\n child.props.selected = value === model[property];\n }\n });\n }\n } else if (vnode.tag === \"textarea\") {\n // If the element is a textarea, use the \"input\" event by default\n event = event || \"oninput\";\n // Set the textarea's content to the value of the model property\n vnode.children = [model[property]];\n }\n\n // We assume that the prev handler if any will not be changed by the user across patchs\n const prevHandler = vnode.props[event];\n\n // Set the event handler on the element\n // eslint-disable-next-line no-use-before-define\n sharedSetAttribute(\n event,\n (e: Event) => {\n handler(e);\n\n // If the previous handler is defined, call it after the model has been updated\n if (prevHandler) {\n prevHandler(e);\n }\n },\n vnode,\n oldVnode\n );\n },\n\n // The \"v-create\" directive is called when a new virtual node is created.\n // The provided callback function is called with the new virtual node as an argument.\n // This directive is only called once per virtual node, when it is first created.\n // eslint-disable-next-line no-unused-vars\n \"v-create\": (callback: (vnode: VnodeWithDom) => void, vnode: VnodeWithDom, oldVnode?: VnodeWithDom) => {\n // If this is not an update, call the callback function with the new virtual node\n if (!oldVnode) {\n const cleanup = callback(vnode);\n\n // If the callback function returns a function, call it when the update is gonna be cleaned up\n if (typeof cleanup === \"function\") {\n onCleanup(cleanup);\n }\n }\n },\n\n // The \"v-update\" directive is called when an existing virtual node is updated.\n // The provided callback function is called with the new and old virtual nodes as arguments.\n // This directive is only called once per virtual node update.\n \"v-update\": (\n // eslint-disable-next-line no-unused-vars\n callback: (vnode: VnodeWithDom, oldVnode: VnodeWithDom) => void,\n vnode: VnodeWithDom,\n oldVnode?: VnodeWithDom\n ) => {\n // If this is an update, call the callback function with the new and old virtual nodes\n if (oldVnode) {\n const cleanup = callback(vnode, oldVnode);\n\n // If the callback function returns a function, call it when the update is gonna be cleaned up\n if (typeof cleanup === \"function\") {\n onCleanup(cleanup);\n }\n }\n },\n\n // The \"v-cleanup\" directive is called when the update is cleaned up.\n // The provided callback function is called with the old virtual node as an argument.\n // This directive is only called once per virtual node, when the update is cleaned up.\n \"v-cleanup\": (\n // eslint-disable-next-line no-unused-vars\n callback: (vnode: VnodeWithDom, oldVnode?: VnodeWithDom) => void,\n vnode: VnodeWithDom,\n oldVnode?: VnodeWithDom\n ) => {\n // Add the callback function to the list of cleanup functions to be called when the update is cleaned up\n onCleanup(() => callback(vnode, oldVnode));\n }\n};\n// Add a directive to the global directives object, with the key being the name\n// preceded by \"v-\". Also add the name to the global reservedProps object.\nexport function directive(name: string, directive: Directive) {\n const directiveName = `v-${name}`;\n directives[directiveName] = directive;\n reservedProps[directiveName] = true;\n}\n\n// Set an attribute on a virtual DOM node and update the actual DOM element.\n// If the attribute value is a function, add an event listener for the attribute\n// name to the DOM element represented by mainVnode.\n// If oldVnode is provided, compare the new attribute value to the old value\n// and only update the attribute if the values are different.\nfunction sharedSetAttribute(name: string, value: any, newVnode: VnodeWithDom, oldVnode?: VnodeWithDom): void | boolean {\n // If the attribute value is a function, add an event listener for the attribute\n // name to the DOM element represented by mainVnode.\n if (typeof value === \"function\") {\n // Only add the event listener if it hasn't been added yet.\n if (name in eventListenerNames === false) {\n (mainVnode as VnodeWithDom).dom.addEventListener(name.slice(2), eventListener);\n eventListenerNames[name] = true;\n }\n newVnode.dom[`v-${name}`] = value;\n return;\n }\n\n // If the attribute is present on the DOM element and newVnode is not an SVG,\n // update the attribute if the value has changed.\n if (newVnode.isSVG === false && name in newVnode.dom) {\n // eslint-disable-next-line eqeqeq\n if (newVnode.dom[name] != value) {\n newVnode.dom[name] = value;\n }\n return;\n }\n\n // If oldVnode is not provided or the attribute value has changed, update the\n // attribute on the DOM element.\n if (!oldVnode || value !== oldVnode.props[name]) {\n if (value === false) {\n newVnode.dom.removeAttribute(name);\n } else {\n newVnode.dom.setAttribute(name, value);\n }\n }\n}\n\n// Set an attribute on a virtual DOM node and update the actual DOM element.\n// Skip the attribute if it is in the reservedProps object.\nexport function setAttribute(name: string, value: any, newVnode: VnodeWithDom, oldVnode?: VnodeWithDom): void {\n if (reservedProps[name]) {\n return;\n }\n newVnode.props[name] = value;\n sharedSetAttribute(name, value, newVnode, oldVnode);\n}\n\n// Update the attributes on a virtual DOM node. If oldVnode is provided, remove\n// attributes from the DOM element that are not present in newVnode.props but are\n// present in oldVnode.props. Then, iterate over the attributes in newVnode.props\n// and update the DOM element with the attributes using the sharedSetAttribute\n// function. If an attribute is in the reservedProps object and has a corresponding\n// directive in the directives object, call the directive with the attribute value\n// and the two virtual DOM nodes as arguments. If the directive returns false, exit\n// the loop.\nexport function updateAttributes(newVnode: VnodeWithDom, oldVnode?: VnodeWithDom): void {\n // If oldVnode is provided, remove attributes from the DOM element that are not\n // present in newVnode.props but are present in oldVnode.props.\n if (oldVnode) {\n for (const name in oldVnode.props) {\n if (!newVnode.props[name] && !eventListenerNames[name] && !reservedProps[name]) {\n if (newVnode.isSVG === false && name in newVnode.dom) {\n newVnode.dom[name] = null;\n } else {\n newVnode.dom.removeAttribute(name);\n }\n }\n }\n }\n\n // Iterate over the attributes in newVnode.props and update the DOM element with\n // the attributes using the sharedSetAttribute function.\n for (const name in newVnode.props) {\n if (reservedProps[name]) {\n // If there is a directive for the attribute, call it with the attribute value\n // and the two virtual DOM nodes as arguments. If the directive returns false,\n // exit the loop.\n if (directives[name] && directives[name](newVnode.props[name], newVnode, oldVnode) === false) {\n break;\n }\n continue;\n }\n sharedSetAttribute(name, newVnode.props[name], newVnode, oldVnode);\n }\n}\n\n/* patch ------------------------------------------------------------------- */\n\n// Patch a DOM node with a new VNode tree\nexport function patch(newVnode: VnodeWithDom, oldVnode?: VnodeWithDom): void {\n // If the new tree has no children, set the text content of the parent DOM element to an empty string\n if (newVnode.children.length === 0) {\n newVnode.dom.textContent = \"\";\n return;\n }\n\n // Get the children of the new and old virtual DOM nodes\n const newTree = newVnode.children;\n const oldTree = oldVnode?.children || [];\n // Get the length of the old tree\n const oldTreeLength = oldTree.length;\n // Get the length of the new tree\n let newTreeLength = newTree.length;\n // Set the global current object to the new and old virtual DOM nodes\n current.vnode = newVnode;\n current.oldVnode = oldVnode;\n\n // Flatten the new tree\n // Take into account that is necessary to flatten the tree before the patch process\n // to let the hooks and signals work properly\n let i = 0;\n while (i < newTreeLength) {\n const newChild = newTree[i];\n\n // If the new child is a Vnode and is not a text node\n if (newChild instanceof Vnode) {\n // If the tag of the new child is not a string, it is a component\n if (typeof newChild.tag !== \"string\") {\n // Set the current component to the tag of the new child\n current.component = newChild.tag;\n // Replace the new child with the result of calling its view or bind method, passing in the props and children as arguments\n newTree.splice(\n i,\n 1,\n (\"view\" in newChild.tag ? newChild.tag.view.bind(newChild.tag) : newChild.tag.bind(newChild.tag))(\n newChild.props,\n ...newChild.children\n )\n );\n newTreeLength = newTree.length;\n continue;\n } else {\n i++;\n }\n // If the new child is an array, flatten it and continue the loop\n } else if (Array.isArray(newChild)) {\n newTree.splice(i, 1, ...newChild);\n newTreeLength = newTree.length;\n // If the new child is null or undefined, remove it from the new tree and continue the loop\n } else if (newChild == null) {\n newTree.splice(i, 1);\n newTreeLength = newTree.length;\n } else {\n // If the new child is not a Vnode or an array, it is a text node\n // just continue the loop\n i++;\n }\n }\n\n // If the new tree has no children, set the text content of the parent DOM element to an empty string\n if (newTreeLength === 0) {\n newVnode.dom.textContent = \"\";\n return;\n }\n\n // If the old tree has children and the first child of the new tree is a VNode with a \"key\"\n // attribute and the first child of the old tree is a VNode with a \"key\" attribute, update\n // the DOM element in place by comparing the keys of the nodes in the trees.\n if (\n oldTreeLength > 0 &&\n newTree[0] instanceof Vnode &&\n oldTree[0] instanceof Vnode &&\n \"key\" in newTree[0].props &&\n \"key\" in oldTree[0].props\n ) {\n const oldKeyedList: Record = {};\n const newKeyedList: Record = {};\n const childNodes = newVnode.dom.childNodes;\n\n // Create key maps while also handling removal of nodes not present in newTree\n for (let i = 0; i < oldTreeLength; i++) {\n oldKeyedList[oldTree[i].props.key] = i;\n if (i < newTreeLength) {\n newKeyedList[newTree[i].props.key] = i;\n }\n }\n\n for (let i = 0; i < newTreeLength; i++) {\n const newChild = newTree[i];\n const oldChildIndex = oldKeyedList[newChild.props.key];\n const oldChild = oldTree[oldChildIndex];\n let shouldPatch = true;\n\n if (oldChild) {\n newChild.dom = oldChild.dom;\n if (\"v-keep\" in newChild.props && newChild.props[\"v-keep\"] === oldChild.props[\"v-keep\"]) {\n newChild.children = oldChild.children;\n shouldPatch = false;\n } else {\n updateAttributes(newChild, oldChild);\n }\n } else {\n newChild.dom = createDomElement(newChild.tag, newChild.isSVG);\n updateAttributes(newChild);\n }\n\n const currentNode = childNodes[i];\n if (!currentNode) {\n newVnode.dom.appendChild(newChild.dom);\n } else if (currentNode !== newChild.dom) {\n newVnode.dom.replaceChild(newChild.dom, currentNode);\n }\n\n shouldPatch && patch(newChild, oldChild);\n }\n\n // Remove nodes that don't exist in newTree\n for (let i = newTreeLength; i < oldTreeLength; i++) {\n if (!newKeyedList[oldTree[i].props.key]) {\n const domToRemove = oldTree[i].dom;\n domToRemove.parentNode && domToRemove.parentNode.removeChild(domToRemove);\n }\n }\n return;\n }\n\n // Patch the the old tree\n for (let i = 0; i < newTreeLength; i++) {\n const newChild = newTree[i];\n const oldChild = oldTree[i];\n const isGreaterThanOldTreeLength = i >= oldTreeLength;\n\n if (newChild instanceof Vnode === false) {\n if (isGreaterThanOldTreeLength || oldChild instanceof Vnode) {\n // If there's no corresponding old child, create a new text node for the new child\n const dom = document.createTextNode(newChild as string);\n\n if (isGreaterThanOldTreeLength) {\n // Append the new child to the dom\n newVnode.dom.appendChild(dom);\n } else {\n newVnode.dom.replaceChild(dom, newVnode.dom.childNodes[i]);\n }\n continue;\n }\n\n // If the old child is not a vnode\n // eslint-disable-next-line eqeqeq\n if (newVnode.dom.childNodes[i].textContent != newChild) {\n newVnode.dom.childNodes[i].textContent = newChild as string;\n }\n continue;\n }\n\n // Set the isSVG flag for the new child if it is an SVG element or if the parent is an SVG element\n newChild.isSVG = newVnode.isSVG || newChild.tag === \"svg\";\n\n if (isGreaterThanOldTreeLength || oldChild instanceof Vnode === false || newChild.tag !== oldChild.tag) {\n // If there's no corresponding old child, create a new dom element for the new child\n newChild.dom = createDomElement(newChild.tag as string, newChild.isSVG);\n\n if (isGreaterThanOldTreeLength) {\n // Append the new child to the dom\n newVnode.dom.appendChild(newChild.dom);\n } else {\n newVnode.dom.replaceChild(newChild.dom, newVnode.dom.childNodes[i]);\n }\n\n // Update the attributes of the new child\n updateAttributes(newChild as VnodeWithDom);\n\n // Recursively patch the new child\n patch(newChild as VnodeWithDom);\n continue;\n }\n\n // Set the dom property of the new child to the dom property of the old child\n newChild.dom = oldChild.dom;\n // If the v-keep prop is the same for both the new and old child, set the children of the new child to the children of the old child\n if (\"v-keep\" in newChild.props && newChild.props[\"v-keep\"] === oldChild.props[\"v-keep\"]) {\n newChild.children = oldChild.children;\n continue;\n }\n\n // Update the attributes of the new child based on the old child\n updateAttributes(newChild as VnodeWithDom, oldChild as VnodeWithDom);\n // Recursively patch the new and old children\n patch(newChild as VnodeWithDom, oldChild as VnodeWithDom);\n }\n\n // Remove any old children that are no longer present in the new tree\n for (; newTreeLength < oldTreeLength; newTreeLength++) {\n newVnode.dom.removeChild(oldTree[newTreeLength].dom);\n }\n}\n\n// Update the main Vnode\nexport function update(): void | string {\n // If the main Vnode exists\n if (mainVnode) {\n // Call any cleanup functions that are registered with the onCleanupSet set\n callSet(onCleanupSet);\n // Store a reference to the old main Vnode\n const oldMainVnode = mainVnode;\n // Create a new main Vnode with the main component as its only child\n mainVnode = new Vnode(oldMainVnode.tag, oldMainVnode.props, [mainComponent]) as VnodeWithDom;\n mainVnode.dom = oldMainVnode.dom;\n mainVnode.isSVG = oldMainVnode.isSVG;\n\n // Recursively patch the new and old main Vnodes\n patch(mainVnode, oldMainVnode);\n\n // Call any update or mount functions that are registered with the onUpdateSet or onMountSet set\n callSet(isMounted ? onUpdateSet : onMountSet);\n\n // Set the isMounted flag to true\n isMounted = true;\n\n // Reset the current vnode, oldVnode, and component properties\n current.vnode = null;\n current.oldVnode = null;\n current.component = null;\n\n // If the code is running in a Node.js environment, return the inner HTML of the main Vnode's dom element\n if (isNodeJs) {\n return mainVnode.dom.innerHTML;\n }\n }\n}\n\n// Update custom Vnode\n// It is assumed that a first mount has already occurred, so,\n// the oldVnode is not null and the dom property of the oldVnode is not null\n// You need to set the dom property of the newVnode to the dom property of the oldVnode\n// The same with the isSVG property\n// Prefer this function over patch to allow for cleanup, onUpdate and onMount sets to be called\nexport function updateVnode(vnode: VnodeWithDom, oldVnode: VnodeWithDom): string | void {\n // Call any cleanup functions that are registered with the onCleanupSet set\n callSet(onCleanupSet);\n\n // Recursively patch the new and old main Vnodes\n patch(vnode, oldVnode);\n\n // Set the oldVnode's tag, props, children, dom, and isSVG properties to the newVnode's tag, props, children, dom, and isSVG properties\n // This is necessary to allow for the oldVnode to be used as the newVnode in the next update with the normal update function\n oldVnode.tag = vnode.tag;\n oldVnode.props = { ...vnode.props };\n oldVnode.children = [...vnode.children];\n oldVnode.dom = vnode.dom;\n oldVnode.isSVG = vnode.isSVG;\n\n // Call any update or mount functions that are registered with the onUpdateSet or onMountSet set\n callSet(isMounted ? onUpdateSet : onMountSet);\n\n // Set the isMounted flag to true\n isMounted = true;\n\n // Reset the current vnode, oldVnode, and component properties\n current.vnode = null;\n current.oldVnode = null;\n current.component = null;\n\n if (isNodeJs) {\n return vnode.dom.innerHTML;\n }\n}\n\n// Unmount the main Vnode\nexport function unmount() {\n // If the main Vnode exists\n if (mainVnode) {\n // Set the main component to a null Vnode\n mainComponent = new Vnode(() => null, {}, []) as VnodeComponentInterface;\n // Update the main Vnode\n const result = update();\n // Call any unmount functions that are registered with the onUnmountSet set\n callSet(onUnmountSet);\n\n // Remove any event listeners that were added to the main Vnode's dom element\n for (const name in eventListenerNames) {\n mainVnode.dom.removeEventListener(name.slice(2).toLowerCase(), eventListener);\n Reflect.deleteProperty(eventListenerNames, name);\n }\n\n // Reset the main component and main Vnode\n mainComponent = null;\n mainVnode = null;\n // Set the isMounted flag to false\n isMounted = false;\n // Reset the current vnode, oldVnode, and component properties\n current.vnode = null;\n current.oldVnode = null;\n current.component = null;\n // Return the result of updating the main Vnode\n return result;\n }\n}\n// This function takes in a DOM element or a DOM element selector and a component to be mounted on it.\nexport function mount(dom: string | DomElement, component: any) {\n // Check if the 'dom' argument is a string. If it is, select the first element that matches the given selector.\n // Otherwise, use the 'dom' argument as the container.\n const container =\n typeof dom === \"string\"\n ? isNodeJs\n ? createDomElement(dom, dom === \"svg\")\n : document.querySelectorAll(dom)[0]\n : dom;\n\n // Check if the 'component' argument is a Vnode component or a regular component.\n // If it's a regular component, create a new Vnode component using the 'component' argument as the tag.\n // If it's not a component at all, create a new Vnode component with the 'component' argument as the rendering function.\n const vnodeComponent = isVnodeComponent(component)\n ? component\n : isComponent(component)\n ? new Vnode(component, {}, [])\n : new Vnode(() => component, {}, []);\n\n // If a main component already exists and it's not the same as the current 'vnodeComponent', unmount it.\n if (mainComponent && mainComponent.tag !== vnodeComponent.tag) {\n unmount();\n }\n\n // Set the 'vnodeComponent' as the main component.\n mainComponent = vnodeComponent as VnodeComponentInterface;\n // Convert the container element to a Vnode.\n mainVnode = domToVnode(container);\n // Update the DOM with the new component.\n return update();\n}\n\n// This is a utility function for creating Vnode objects.\n// It takes in a tag or component, and optional props and children arguments.\nexport const v: V = (tagOrComponent, props, ...children) => {\n // Return a new Vnode object using the given arguments.\n return new Vnode(tagOrComponent, props || {}, children);\n};\n\n// This utility function creates a fragment Vnode.\n// It takes in a placeholder and the children arguments, returns only the children.\nv.fragment = (_: VnodeProperties, ...children: Children) => children;\n"], + "mappings": "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", + "names": ["Vnode", "value", "directive", "i"] } diff --git a/dist/index.min.js b/dist/index.min.js index fa15fab..7acf350 100644 --- a/dist/index.min.js +++ b/dist/index.min.js @@ -1 +1 @@ -(()=>{var e="#text",o=Boolean("undefined"!=typeof process&&process.versions&&process.versions.node);function n(e,o=!1){return o?document.createElementNS("http://www.w3.org/2000/svg",e):document.createElement(e)}var t=function(e,o,n){this.tag=e,this.props=o,this.children=n};function r(e){return Boolean(e&&("function"==typeof e||"object"==typeof e&&"view"in e))}var d=e=>e instanceof t,i=e=>d(e)&&r(e.tag);function l(o){if(3===o.nodeType){const n=new t(e,{},[o.nodeValue]);return n.dom=o,n}const n=[];for(let e=0,t=o.childNodes.length;el(e))}var p=null,c=null,a=!1,u={vnode:null,oldVnode:null,component:null,event:null},m={key:!0,state:!0,"v-keep":!0,"v-if":!0,"v-unless":!0,"v-for":!0,"v-show":!0,"v-class":!0,"v-html":!0,"v-model":!0,"v-create":!0,"v-update":!0,"v-cleanup":!0},f=new Set,v=new Set,h=new Set,g=new Set;function y(e){f.add(e)}function w(e){for(const o of e)o();e.clear()}var V={};function k(e){u.event=e;let o=e.target;const n=`v-on${e.type}`;for(;o;){if(o[n])return o[n](e,o),void(e.defaultPrevented||A());o=o.parentNode}u.event=null}var C=e=>(o,n,t)=>{if(e?o:!o){const e=document.createTextNode("");return t&&t.dom&&t.dom.parentNode&&t.dom.parentNode.replaceChild(e,t.dom),n.tag="#text",n.children=[],n.props={},n.dom=e,!1}},S={"v-if":C(!1),"v-unless":C(!0),"v-for":(e,o)=>{const n=[],t=o.children[0];for(let o=0,r=e.length;o{o.dom.style.display=e?"":"none"},"v-class":(e,o)=>{for(const n in e)o.dom.classList.toggle(n,e[n])},"v-html":(e,o)=>{o.children=[s(e)]},"v-model":([e,o,n],t,r)=>{let d,i=n=>e[o]=n.target.value;if("input"===t.tag)switch(n=n||"oninput",t.props.type){case"checkbox":Array.isArray(e[o])?(i=n=>{const t=n.target.value,r=e[o].indexOf(t);-1===r?e[o].push(t):e[o].splice(r,1)},d=-1!==e[o].indexOf(t.dom.value)):"value"in t.props?(i=()=>{e[o]===t.props.value?e[o]=null:e[o]=t.props.value},d=e[o]===t.props.value):(i=()=>e[o]=!e[o],d=e[o]),x("checked",d,t);break;case"radio":x("checked",e[o]===t.dom.value,t);break;default:x("value",e[o],t)}else"select"===t.tag?(n=n||"onclick",t.props.multiple?(i=n=>{const t=n.target.value;if(n.ctrlKey){const n=e[o].indexOf(t);-1===n?e[o].push(t):e[o].splice(n,1)}else e[o].splice(0,e[o].length),e[o].push(t)},t.children.forEach(n=>{if("option"===n.tag){const t="value"in n.props?n.props.value:n.children.join("").trim();n.props.selected=-1!==e[o].indexOf(t)}})):t.children.forEach(n=>{if("option"===n.tag){const t="value"in n.props?n.props.value:n.children.join("").trim();n.props.selected=t===e[o]}})):"textarea"===t.tag&&(n=n||"oninput",t.children=[e[o]]);const l=t.props[n];x(n,e=>{i(e),l&&l(e)},t,r)},"v-create":(e,o,n)=>{if(!n){const n=e(o);"function"==typeof n&&y(n)}},"v-update":(e,o,n)=>{if(n){const t=e(o,n);"function"==typeof t&&y(t)}},"v-cleanup":(e,o,n)=>{y(()=>e(o,n))}};function x(e,o,n,t){if("function"==typeof o)return e in V==!1&&(c.dom.addEventListener(e.slice(2),k),V[e]=!0),void(n.dom[`v-${e}`]=o);!1===n.isSVG&&e in n.dom?n.dom[e]!=o&&(n.dom[e]=o):t&&o===t.props[e]||(!1===o?n.dom.removeAttribute(e):n.dom.setAttribute(e,o))}function N(e,o){if(o)for(const n in o.props)e.props[n]||V[n]||m[n]||(!1===e.isSVG&&n in e.dom?e.dom[n]=null:e.dom.removeAttribute(n));for(const n in e.props)if(m[n]){if(S[n]&&!1===S[n](e.props[n],e,o))break}else x(n,e.props[n],e,o)}function b(o,r){if(0===o.children.length)return void(o.dom.textContent="");const d=o.children,i=r?.children||[],l=i.length;let s=d.length;u.vnode=o,u.oldVnode=r;let p=0;for(;p0&&d[0]instanceof t&&i[0]instanceof t&&"key"in d[0].props&&"key"in i[0].props){const e={},t={},r=o.dom.childNodes;for(let o=0;o=l;r.tag!==e?(r.isSVG=o.isSVG||"svg"===r.tag,p||r.tag!==s.tag?(r.dom=n(r.tag,r.isSVG),N(r),p?o.dom.appendChild(r.dom):o.dom.replaceChild(r.dom,s.dom),b(r)):(r.dom=s.dom,"v-keep"in r.props&&r.props["v-keep"]===s.props["v-keep"]?r.children=s.children:(N(r,s),b(r,s)))):p||s.tag!==e?(r.dom=document.createTextNode(r.children[0]),p?o.dom.appendChild(r.dom):o.dom.replaceChild(r.dom,s.dom)):(r.dom=s.dom,r.children[0]!==s.dom.textContent&&(s.dom.textContent=r.children[0]))}for(;snull,{},[]);const e=A();w(g);for(const e in V)c.dom.removeEventListener(e.slice(2).toLowerCase(),k),Reflect.deleteProperty(V,e);return p=null,c=null,a=!1,u.vnode=null,u.oldVnode=null,u.component=null,e}}var T=(e,o,...n)=>new t(e,o||{},n);T.fragment=(e,...o)=>o;var L={Vnode:t,createDomElement:n,current:u,directive:function(e,o){const n=`v-${e}`;S[n]=o,m[n]=!0},directives:S,domToVnode:l,isComponent:r,isNodeJs:o,isVnode:d,isVnodeComponent:i,mount:function(e,d){const s="string"==typeof e?o?n(e,"svg"===e):document.querySelectorAll(e)[0]:e,a=i(d)?d:r(d)?new t(d,{},[]):new t(()=>d,{},[]);return p&&p.tag!==a.tag&&G(),p=a,c=l(s),A()},onCleanup:y,onMount:function(e){a||v.add(e)},onUnmount:function(e){a||g.add(e)},onUpdate:function(e){h.add(e)},patch:b,reservedProps:m,setAttribute:function(e,o,n,t){m[e]||(n.props[e]=o,x(e,o,n,t))},trust:s,unmount:G,update:A,updateAttributes:N,updateVnode:function(e,n){if(w(f),b(e,n),n.tag=e.tag,n.props={...e.props},n.children=[...e.children],n.dom=e.dom,n.isSVG=e.isSVG,w(a?h:v),a=!0,u.vnode=null,u.oldVnode=null,u.component=null,o)return e.dom.innerHTML},v:T};"undefined"!=typeof module?module.exports=L:self.Valyrian=L})();//# sourceMappingURL=index.min.js.map \ No newline at end of file +(()=>{var e=Boolean("undefined"!=typeof process&&process.versions&&process.versions.node);function n(e,n=!1){return n?document.createElementNS("http://www.w3.org/2000/svg",e):document.createElement(e)}var o=function(e,n,o){this.tag=e,this.props=n,this.children=o};function t(e){return Boolean(e&&("function"==typeof e||"object"==typeof e&&"view"in e))}var i=e=>e instanceof o,r=e=>i(e)&&t(e.tag);function d(e){if(3===e.nodeType)return e.nodeValue;const n=[];for(let o=0,t=e.childNodes.length;od(e))}var s=null,c=null,p=!1,a={vnode:null,oldVnode:null,component:null,event:null},u={key:!0,state:!0,"v-keep":!0,"v-if":!0,"v-unless":!0,"v-for":!0,"v-show":!0,"v-class":!0,"v-html":!0,"v-model":!0,"v-create":!0,"v-update":!0,"v-cleanup":!0},f=new Set,m=new Set,v=new Set,h=new Set;function g(e){f.add(e)}function y(e){for(const n of e)n();e.clear()}var V={};function w(e){a.event=e;let n=e.target;const o=`v-on${e.type}`;for(;n;){if(n[o])return n[o](e,n),void(e.defaultPrevented||x());n=n.parentNode}a.event=null}var k=e=>(n,o,t)=>{if(e?n:!n){const e=o.dom?.parentNode;if(e){const n=document.createTextNode("");e.replaceChild(n,o.dom)}return!1}},C={"v-if":k(!1),"v-unless":k(!0),"v-for":(e,n)=>{const o=[],t=n.children[0];for(let n=0,i=e.length;n{n.dom.style.display=e?"":"none"},"v-class":(e,n)=>{for(const o in e)n.dom.classList.toggle(o,e[o])},"v-html":(e,n)=>{n.children=[l(e)]},"v-model":([e,n,o],t,i)=>{let r,d=o=>e[n]=o.target.value;if("input"===t.tag)switch(o=o||"oninput",t.props.type){case"checkbox":Array.isArray(e[n])?(d=o=>{const t=o.target.value,i=e[n].indexOf(t);-1===i?e[n].push(t):e[n].splice(i,1)},r=-1!==e[n].indexOf(t.dom.value)):"value"in t.props?(d=()=>{e[n]===t.props.value?e[n]=null:e[n]=t.props.value},r=e[n]===t.props.value):(d=()=>e[n]=!e[n],r=e[n]),N("checked",r,t);break;case"radio":N("checked",e[n]===t.dom.value,t);break;default:N("value",e[n],t)}else"select"===t.tag?(o=o||"onclick",t.props.multiple?(d=o=>{const t=o.target.value;if(o.ctrlKey){const o=e[n].indexOf(t);-1===o?e[n].push(t):e[n].splice(o,1)}else e[n].splice(0,e[n].length),e[n].push(t)},t.children.forEach(o=>{if("option"===o.tag){const t="value"in o.props?o.props.value:o.children.join("").trim();o.props.selected=-1!==e[n].indexOf(t)}})):t.children.forEach(o=>{if("option"===o.tag){const t="value"in o.props?o.props.value:o.children.join("").trim();o.props.selected=t===e[n]}})):"textarea"===t.tag&&(o=o||"oninput",t.children=[e[n]]);const l=t.props[o];N(o,e=>{d(e),l&&l(e)},t,i)},"v-create":(e,n,o)=>{if(!o){const o=e(n);"function"==typeof o&&g(o)}},"v-update":(e,n,o)=>{if(o){const t=e(n,o);"function"==typeof t&&g(t)}},"v-cleanup":(e,n,o)=>{g(()=>e(n,o))}};function N(e,n,o,t){if("function"==typeof n)return e in V==!1&&(c.dom.addEventListener(e.slice(2),w),V[e]=!0),void(o.dom[`v-${e}`]=n);!1===o.isSVG&&e in o.dom?o.dom[e]!=n&&(o.dom[e]=n):t&&n===t.props[e]||(!1===n?o.dom.removeAttribute(e):o.dom.setAttribute(e,n))}function S(e,n){if(n)for(const o in n.props)e.props[o]||V[o]||u[o]||(!1===e.isSVG&&o in e.dom?e.dom[o]=null:e.dom.removeAttribute(o));for(const o in e.props)if(u[o]){if(C[o]&&!1===C[o](e.props[o],e,n))break}else N(o,e.props[o],e,n)}function b(e,t){if(0===e.children.length)return void(e.dom.textContent="");const i=e.children,r=t?.children||[],d=r.length;let l=i.length;a.vnode=e,a.oldVnode=t;let s=0;for(;s0&&i[0]instanceof o&&r[0]instanceof o&&"key"in i[0].props&&"key"in r[0].props){const o={},t={},s=e.dom.childNodes;for(let e=0;e=d;if(l instanceof o!=!1)l.isSVG=e.isSVG||"svg"===l.tag,c||s instanceof o==!1||l.tag!==s.tag?(l.dom=n(l.tag,l.isSVG),c?e.dom.appendChild(l.dom):e.dom.replaceChild(l.dom,e.dom.childNodes[t]),S(l),b(l)):(l.dom=s.dom,"v-keep"in l.props&&l.props["v-keep"]===s.props["v-keep"]?l.children=s.children:(S(l,s),b(l,s)));else{if(c||s instanceof o){const n=document.createTextNode(l);c?e.dom.appendChild(n):e.dom.replaceChild(n,e.dom.childNodes[t]);continue}e.dom.childNodes[t].textContent!=l&&(e.dom.childNodes[t].textContent=l)}}for(;lnull,{},[]);const e=x();y(h);for(const e in V)c.dom.removeEventListener(e.slice(2).toLowerCase(),w),Reflect.deleteProperty(V,e);return s=null,c=null,p=!1,a.vnode=null,a.oldVnode=null,a.component=null,e}}var G=(e,n,...t)=>new o(e,n||{},t);G.fragment=(e,...n)=>n;var T={Vnode:o,createDomElement:n,current:a,directive:function(e,n){const o=`v-${e}`;C[o]=n,u[o]=!0},directives:C,domToVnode:d,isComponent:t,isNodeJs:e,isVnode:i,isVnodeComponent:r,mount:function(i,l){const p="string"==typeof i?e?n(i,"svg"===i):document.querySelectorAll(i)[0]:i,a=r(l)?l:t(l)?new o(l,{},[]):new o(()=>l,{},[]);return s&&s.tag!==a.tag&&A(),s=a,c=d(p),x()},onCleanup:g,onMount:function(e){p||m.add(e)},onUnmount:function(e){p||h.add(e)},onUpdate:function(e){v.add(e)},patch:b,reservedProps:u,setAttribute:function(e,n,o,t){u[e]||(o.props[e]=n,N(e,n,o,t))},trust:l,unmount:A,update:x,updateAttributes:S,updateVnode:function(n,o){if(y(f),b(n,o),o.tag=n.tag,o.props={...n.props},o.children=[...n.children],o.dom=n.dom,o.isSVG=n.isSVG,y(p?v:m),p=!0,a.vnode=null,a.oldVnode=null,a.component=null,e)return n.dom.innerHTML},v:G};"undefined"!=typeof module?module.exports=T:self.Valyrian=T})();//# sourceMappingURL=index.min.js.map \ No newline at end of file diff --git a/dist/index.min.js.map b/dist/index.min.js.map index 666e774..c619c51 100644 --- a/dist/index.min.js.map +++ b/dist/index.min.js.map @@ -1 +1 @@ -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJ0ZXh0VGFnIiwiaXNOb2RlSnMiLCJCb29sZWFuIiwicHJvY2VzcyIsInZlcnNpb25zIiwibm9kZSIsImNyZWF0ZURvbUVsZW1lbnQiLCJ0YWciLCJpc1NWRyIsImRvY3VtZW50IiwiY3JlYXRlRWxlbWVudE5TIiwiY3JlYXRlRWxlbWVudCIsIlZub2RlIiwicHJvcHMiLCJjaGlsZHJlbiIsInRoaXMiLCJpc0NvbXBvbmVudCIsImNvbXBvbmVudCIsImlzVm5vZGUiLCJvYmplY3QiLCJpc1Zub2RlQ29tcG9uZW50IiwiZG9tVG9Wbm9kZSIsImRvbSIsIm5vZGVUeXBlIiwidm5vZGUiLCJub2RlVmFsdWUiLCJpIiwibCIsImNoaWxkTm9kZXMiLCJsZW5ndGgiLCJjaGlsZERvbSIsInB1c2giLCJhdHRyaWJ1dGVzIiwiYXR0ciIsIm5vZGVOYW1lIiwidGFnTmFtZSIsInRvTG93ZXJDYXNlIiwidHJ1c3QiLCJodG1sU3RyaW5nIiwiZGl2IiwiaW5uZXJIVE1MIiwidHJpbSIsIm1hcCIsImNhbGwiLCJpdGVtIiwibWFpbkNvbXBvbmVudCIsIm1haW5Wbm9kZSIsImlzTW91bnRlZCIsImN1cnJlbnQiLCJvbGRWbm9kZSIsImV2ZW50IiwicmVzZXJ2ZWRQcm9wcyIsImtleSIsInN0YXRlIiwib25DbGVhbnVwU2V0IiwiU2V0Iiwib25Nb3VudFNldCIsIm9uVXBkYXRlU2V0Iiwib25Vbm1vdW50U2V0Iiwib25DbGVhbnVwIiwiY2FsbGJhY2siLCJhZGQiLCJjYWxsU2V0Iiwic2V0IiwiY2xlYXIiLCJldmVudExpc3RlbmVyTmFtZXMiLCJldmVudExpc3RlbmVyIiwiZSIsInRhcmdldCIsIm5hbWUiLCJ0eXBlIiwiZGVmYXVsdFByZXZlbnRlZCIsInVwZGF0ZSIsInBhcmVudE5vZGUiLCJoaWRlRGlyZWN0aXZlIiwidGVzdCIsImJvb2wiLCJvbGRub2RlIiwibmV3ZG9tIiwiY3JlYXRlVGV4dE5vZGUiLCJyZXBsYWNlQ2hpbGQiLCJkaXJlY3RpdmVzIiwibmV3Q2hpbGRyZW4iLCJzdHlsZSIsImRpc3BsYXkiLCJjbGFzc2VzIiwiY2xhc3NMaXN0IiwidG9nZ2xlIiwiaHRtbCIsIm1vZGVsIiwicHJvcGVydHkiLCJ2YWx1ZSIsImhhbmRsZXIiLCJBcnJheSIsImlzQXJyYXkiLCJ2YWwiLCJpZHgiLCJpbmRleE9mIiwic3BsaWNlIiwic2hhcmVkU2V0QXR0cmlidXRlIiwibXVsdGlwbGUiLCJjdHJsS2V5IiwiZm9yRWFjaCIsImNoaWxkIiwiam9pbiIsInNlbGVjdGVkIiwicHJldkhhbmRsZXIiLCJjbGVhbnVwIiwibmV3Vm5vZGUiLCJhZGRFdmVudExpc3RlbmVyIiwic2xpY2UiLCJyZW1vdmVBdHRyaWJ1dGUiLCJzZXRBdHRyaWJ1dGUiLCJ1cGRhdGVBdHRyaWJ1dGVzIiwicGF0Y2giLCJ0ZXh0Q29udGVudCIsIm5ld1RyZWUiLCJvbGRUcmVlIiwib2xkVHJlZUxlbmd0aCIsIm5ld1RyZWVMZW5ndGgiLCJuZXdDaGlsZCIsInZpZXciLCJiaW5kIiwib2xkS2V5ZWRMaXN0IiwibmV3S2V5ZWRMaXN0Iiwib2xkQ2hpbGQiLCJzaG91bGRQYXRjaCIsImN1cnJlbnROb2RlIiwiYXBwZW5kQ2hpbGQiLCJkb21Ub1JlbW92ZSIsInJlbW92ZUNoaWxkIiwiaXNHcmVhdGVyVGhhbk9sZFRyZWVMZW5ndGgiLCJvbGRNYWluVm5vZGUiLCJ1bm1vdW50IiwicmVzdWx0IiwicmVtb3ZlRXZlbnRMaXN0ZW5lciIsIlJlZmxlY3QiLCJkZWxldGVQcm9wZXJ0eSIsInYiLCJ0YWdPckNvbXBvbmVudCIsImZyYWdtZW50IiwiXyIsImRpcmVjdGl2ZSIsImRpcmVjdGl2ZU5hbWUiLCJjb250YWluZXIiLCJxdWVyeVNlbGVjdG9yQWxsIiwidm5vZGVDb21wb25lbnQiXSwic291cmNlcyI6WyIuLi9saWIvaW5kZXgudHMiXSwic291cmNlc0NvbnRlbnQiOlsiLyogZXNsaW50LWRpc2FibGUgbm8tdXNlLWJlZm9yZS1kZWZpbmUgKi9cbi8qIGVzbGludC1kaXNhYmxlIGluZGVudCAqL1xuLyogZXNsaW50LWRpc2FibGUgc29uYXJqcy9jb2duaXRpdmUtY29tcGxleGl0eSAqL1xuLyogZXNsaW50LWRpc2FibGUgY29tcGxleGl0eSAqL1xuXG5pbnRlcmZhY2UgRGVmYXVsdFJlY29yZCBleHRlbmRzIFJlY29yZDxzdHJpbmcgfCBudW1iZXIgfCBzeW1ib2wsIGFueT4ge31cblxuLy8gVGhlIFZub2RlUHJvcGVydGllcyBpbnRlcmZhY2UgcmVwcmVzZW50cyBwcm9wZXJ0aWVzIHRoYXQgY2FuIGJlIHBhc3NlZCB0byBhIHZpcnR1YWwgbm9kZS5cbmV4cG9ydCBpbnRlcmZhY2UgVm5vZGVQcm9wZXJ0aWVzIGV4dGVuZHMgRGVmYXVsdFJlY29yZCB7XG4gIC8vIEEgdW5pcXVlIGtleSBmb3IgdGhlIHZpcnR1YWwgbm9kZSwgd2hpY2ggY2FuIGJlIGEgc3RyaW5nIG9yIGEgbnVtYmVyLlxuICAvLyBUaGlzIGlzIHVzZWZ1bCBmb3Igb3B0aW1pemluZyB1cGRhdGVzIGluIGEgbGlzdCBvZiBub2Rlcy5cbiAga2V5Pzogc3RyaW5nIHwgbnVtYmVyO1xuICAvLyBBIHN0YXRlIG9iamVjdCB0aGF0IGlzIGFzc29jaWF0ZWQgd2l0aCB0aGUgdmlydHVhbCBub2RlLlxuICBzdGF0ZT86IGFueTtcbn1cblxuLy8gVGhlIERvbUVsZW1lbnQgaW50ZXJmYWNlIGV4dGVuZHMgdGhlIEVsZW1lbnQgaW50ZXJmYWNlIHdpdGggYW4gaW5kZXggc2lnbmF0dXJlLlxuLy8gVGhpcyBhbGxvd3MgZm9yIGFueSBhZGRpdGlvbmFsIHByb3BlcnRpZXMgdG8gYmUgYWRkZWQgdG8gRE9NIGVsZW1lbnRzLlxuZXhwb3J0IGludGVyZmFjZSBEb21FbGVtZW50IGV4dGVuZHMgRWxlbWVudCwgRGVmYXVsdFJlY29yZCB7fVxuXG4vLyBUaGUgVm5vZGVJbnRlcmZhY2UgcmVwcmVzZW50cyBhIHZpcnR1YWwgbm9kZS4gSXQgaGFzIGEgbnVtYmVyIG9mIG9wdGlvbmFsIGZpZWxkcyxcbi8vIGluY2x1ZGluZyBhIHRhZywgcHJvcHMsIGNoaWxkcmVuLCBhbmQgYSBET00gZWxlbWVudC5cbmV4cG9ydCBpbnRlcmZhY2UgVm5vZGVJbnRlcmZhY2UgZXh0ZW5kcyBEZWZhdWx0UmVjb3JkIHtcbiAgLy8gVGhlIGNvbnN0cnVjdG9yIGZvciB0aGUgdmlydHVhbCBub2RlLiBJdCB0YWtlcyBhIHRhZywgcHJvcHMsIGFuZCBjaGlsZHJlbiBhcyBhcmd1bWVudHMuXG4gIC8vIFRoZSB0YWcgY2FuIGJlIGEgc3RyaW5nLCBhIGNvbXBvbmVudCwgb3IgYSBQT0pPIGNvbXBvbmVudC5cbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXVudXNlZC12YXJzXG4gIG5ldyAodGFnOiBzdHJpbmcgfCBDb21wb25lbnQgfCBQT0pPQ29tcG9uZW50LCBwcm9wczogVm5vZGVQcm9wZXJ0aWVzLCBjaGlsZHJlbjogQ2hpbGRyZW4pOiBWbm9kZUludGVyZmFjZTtcbiAgLy8gVGhlIHRhZyBmb3IgdGhlIHZpcnR1YWwgbm9kZS4gSXQgY2FuIGJlIGEgc3RyaW5nLCBhIGNvbXBvbmVudCwgb3IgYSBQT0pPIGNvbXBvbmVudC5cbiAgdGFnOiBzdHJpbmcgfCBDb21wb25lbnQgfCBQT0pPQ29tcG9uZW50O1xuICAvLyBUaGUgcHJvcHMgZm9yIHRoZSB2aXJ0dWFsIG5vZGUuXG4gIHByb3BzOiBWbm9kZVByb3BlcnRpZXM7XG4gIC8vIFRoZSBjaGlsZHJlbiBmb3IgdGhlIHZpcnR1YWwgbm9kZS5cbiAgY2hpbGRyZW46IENoaWxkcmVuO1xuICAvLyBBIGJvb2xlYW4gaW5kaWNhdGluZyB3aGV0aGVyIHRoZSB2aXJ0dWFsIG5vZGUgaXMgYW4gU1ZHIGVsZW1lbnQuXG4gIGlzU1ZHPzogYm9vbGVhbjtcbiAgLy8gVGhlIERPTSBlbGVtZW50IHRoYXQgY29ycmVzcG9uZHMgdG8gdGhlIHZpcnR1YWwgbm9kZS5cbiAgZG9tPzogRG9tRWxlbWVudDtcbiAgLy8gQSBib29sZWFuIGluZGljYXRpbmcgd2hldGhlciB0aGUgdmlydHVhbCBub2RlIGhhcyBiZWVuIHByb2Nlc3NlZCBpbiB0aGUga2V5ZWQgZGlmZmluZyBhbGdvcml0aG0uXG4gIHByb2Nlc3NlZD86IGJvb2xlYW47XG59XG5cbi8vIFRoZSBWbm9kZVdpdGhEb20gaW50ZXJmYWNlIHJlcHJlc2VudHMgYSB2aXJ0dWFsIG5vZGUgdGhhdCBoYXMgYSBET00gZWxlbWVudCBhc3NvY2lhdGVkIHdpdGggaXQuXG5leHBvcnQgaW50ZXJmYWNlIFZub2RlV2l0aERvbSBleHRlbmRzIFZub2RlSW50ZXJmYWNlIHtcbiAgZG9tOiBEb21FbGVtZW50O1xufVxuXG4vLyBUaGUgQ29tcG9uZW50IGludGVyZmFjZSByZXByZXNlbnRzIGEgZnVuY3Rpb24gdGhhdCByZXR1cm5zIGEgdmlydHVhbCBub2RlIG9yIGEgbGlzdCBvZiB2aXJ0dWFsIG5vZGVzLlxuLy8gSXQgY2FuIGFsc28gaGF2ZSBhZGRpdGlvbmFsIHByb3BlcnRpZXMuXG5leHBvcnQgaW50ZXJmYWNlIENvbXBvbmVudCBleHRlbmRzIERlZmF1bHRSZWNvcmQge1xuICAvLyBUaGUgZnVuY3Rpb24gdGhhdCByZXR1cm5zIGEgdmlydHVhbCBub2RlIG9yIGEgbGlzdCBvZiB2aXJ0dWFsIG5vZGVzLlxuICAvLyBJdCBjYW4gdGFrZSBwcm9wcyBhbmQgY2hpbGRyZW4gYXMgYXJndW1lbnRzLlxuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tdW51c2VkLXZhcnNcbiAgKHByb3BzPzogVm5vZGVQcm9wZXJ0aWVzIHwgbnVsbCwgLi4uY2hpbGRyZW46IGFueVtdKTogVm5vZGVJbnRlcmZhY2UgfCBDaGlsZHJlbiB8IGFueTtcbn1cblxuLy8gVGhlIFBPSk9Db21wb25lbnQgaW50ZXJmYWNlIHJlcHJlc2VudHMgYSBcInBsYWluIG9sZCBKYXZhU2NyaXB0IG9iamVjdFwiIChQT0pPKSBjb21wb25lbnQuXG4vLyBJdCBoYXMgYSB2aWV3IGZ1bmN0aW9uIHRoYXQgcmV0dXJucyBhIHZpcnR1YWwgbm9kZSBvciBhIGxpc3Qgb2YgdmlydHVhbCBub2Rlcyxcbi8vIGFzIHdlbGwgYXMgb3B0aW9uYWwgcHJvcHMgYW5kIGNoaWxkcmVuLlxuLy8gSXQgY2FuIGJlIHVzZWQgYWxzbyB0byBpZGVudGlmeSBjbGFzcyBpbnN0YW5jZSBjb21wb25lbnRzLlxuZXhwb3J0IGludGVyZmFjZSBQT0pPQ29tcG9uZW50IGV4dGVuZHMgRGVmYXVsdFJlY29yZCB7XG4gIC8vIFRoZSB2aWV3IGZ1bmN0aW9uIHRoYXQgcmV0dXJucyBhIHZpcnR1YWwgbm9kZSBvciBhIGxpc3Qgb2YgdmlydHVhbCBub2Rlcy5cbiAgdmlldzogQ29tcG9uZW50O1xuICAvLyBUaGUgcHJvcHMgZm9yIHRoZSBjb21wb25lbnQuXG4gIHByb3BzPzogVm5vZGVQcm9wZXJ0aWVzIHwgbnVsbDtcbiAgLy8gVGhlIGNoaWxkcmVuIGZvciB0aGUgY29tcG9uZW50LlxuICBjaGlsZHJlbj86IGFueVtdO1xufVxuXG4vLyBUaGUgVm5vZGVDb21wb25lbnRJbnRlcmZhY2UgcmVwcmVzZW50cyBhIHZpcnR1YWwgbm9kZSB0aGF0IGhhcyBhIGNvbXBvbmVudCBhcyBpdHMgdGFnLlxuLy8gSXQgaGFzIHByb3BzIGFuZCBjaGlsZHJlbiwganVzdCBsaWtlIGEgcmVndWxhciB2aXJ0dWFsIG5vZGUuXG5leHBvcnQgaW50ZXJmYWNlIFZub2RlQ29tcG9uZW50SW50ZXJmYWNlIGV4dGVuZHMgVm5vZGVJbnRlcmZhY2Uge1xuICB0YWc6IENvbXBvbmVudCB8IFBPSk9Db21wb25lbnQ7XG4gIHByb3BzOiBWbm9kZVByb3BlcnRpZXM7XG4gIGNoaWxkcmVuOiBDaGlsZHJlbjtcbn1cblxuLy8gVGhlIENoaWxkcmVuIGludGVyZmFjZSByZXByZXNlbnRzIGEgbGlzdCBvZiB2aXJ0dWFsIG5vZGVzIG9yIG90aGVyIHZhbHVlcy5cbmV4cG9ydCBpbnRlcmZhY2UgQ2hpbGRyZW4gZXh0ZW5kcyBBcnJheTxWbm9kZUludGVyZmFjZSB8IFZub2RlQ29tcG9uZW50SW50ZXJmYWNlIHwgYW55PiB7fVxuXG4vLyBUaGUgRGlyZWN0aXZlIGludGVyZmFjZSByZXByZXNlbnRzIGEgZnVuY3Rpb24gdGhhdCBjYW4gYmUgYXBwbGllZCB0byBhIHZpcnR1YWwgbm9kZS5cbi8vIEl0IHJlY2VpdmVzIHRoZSB2YWx1ZSwgdmlydHVhbCBub2RlLCBhbmQgb2xkIHZpcnR1YWwgbm9kZSBhcyBhcmd1bWVudHMsIGFuZCBjYW4gcmV0dXJuIGEgYm9vbGVhbiB2YWx1ZS5cbi8vIElmIG9ubHkgdGhlIHZpcnR1YWwgbm9kZSBpcyBwYXNzZWQsIGl0IG1lYW5zIGl0cyB0aGUgb24gY3JlYXRlIHBoYXNlIGZvciB0aGUgdi1ub2RlLlxuLy8gSWYgdGhlIG9sZCB2aXJ0dWFsIG5vZGUgaXMgYWxzbyBwYXNzZWQsIGl0IG1lYW5zIGl0cyB0aGUgb24gdXBkYXRlIHBoYXNlIGZvciB0aGUgdi1ub2RlLlxuZXhwb3J0IGludGVyZmFjZSBEaXJlY3RpdmUge1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tdW51c2VkLXZhcnNcbiAgKHZhbHVlOiBhbnksIHZub2RlOiBWbm9kZVdpdGhEb20sIG9sZFZub2RlPzogVm5vZGVXaXRoRG9tKTogdm9pZCB8IGJvb2xlYW47XG59XG5cbi8vIFRoZSBEaXJlY3RpdmVzIGludGVyZmFjZSBpcyBhIG1hcHBpbmcgb2YgZGlyZWN0aXZlIG5hbWVzIHRvIERpcmVjdGl2ZSBmdW5jdGlvbnMuXG5leHBvcnQgaW50ZXJmYWNlIERpcmVjdGl2ZXMgZXh0ZW5kcyBSZWNvcmQ8c3RyaW5nLCBEaXJlY3RpdmU+IHt9XG5cbi8vIFRoZSBSZXNlcnZlZFByb3BzIGludGVyZmFjZSBpcyBhIG1hcHBpbmcgb2YgcmVzZXJ2ZWQgcHJvcCBuYW1lcyB0byB0aGUgdmFsdWUgYHRydWVgLlxuLy8gVGhlc2UgcHJvcCBuYW1lcyBjYW5ub3QgYmUgdXNlZCBhcyBjdXN0b20gcHJvcCBuYW1lcy5cbmV4cG9ydCBpbnRlcmZhY2UgUmVzZXJ2ZWRQcm9wcyBleHRlbmRzIFJlY29yZDxzdHJpbmcsIHRydWU+IHt9XG5cbi8vIFRoZSBDdXJyZW50IGludGVyZmFjZSByZXByZXNlbnRzIHRoZSBjdXJyZW50IGNvbXBvbmVudCBhbmQgdmlydHVhbCBub2RlIHRoYXQgYXJlIGJlaW5nIHByb2Nlc3NlZC5cbmV4cG9ydCBpbnRlcmZhY2UgQ3VycmVudCB7XG4gIC8vIFRoZSBjdXJyZW50IGNvbXBvbmVudC4gSXQgY2FuIGJlIGEgY29tcG9uZW50LCBhIFBPSk8gY29tcG9uZW50LCBvciBudWxsLlxuICBjb21wb25lbnQ6IENvbXBvbmVudCB8IFBPSk9Db21wb25lbnQgfCBudWxsO1xuICAvLyBUaGUgY3VycmVudCB2aXJ0dWFsIG5vZGUuIEl0IG11c3QgaGF2ZSBhIERPTSBlbGVtZW50IGFzc29jaWF0ZWQgd2l0aCBpdC5cbiAgdm5vZGU6IFZub2RlV2l0aERvbSB8IG51bGw7XG4gIC8vIFRoZSBvbGQgdmlydHVhbCBub2RlLiBJdCBtdXN0IGhhdmUgYSBET00gZWxlbWVudCBhc3NvY2lhdGVkIHdpdGggaXQuXG4gIG9sZFZub2RlPzogVm5vZGVXaXRoRG9tIHwgbnVsbDtcbiAgLy8gVGhlIGN1cnJlbnQgZXZlbnQuIEl0IGNhbiBiZSBhbiBldmVudCBvciBudWxsLlxuICBldmVudDogRXZlbnQgfCBudWxsO1xufVxuXG4vLyBUaGUgViBmdW5jdGlvbiBpcyB0aGUgbWFpbiBmdW5jdGlvbiBmb3IgY3JlYXRpbmcgdmlydHVhbCBub2Rlcy5cbi8vIEl0IHRha2VzIGEgdGFnIG9yIGNvbXBvbmVudCwgcHJvcHMsIGFuZCBjaGlsZHJlbiBhcyBhcmd1bWVudHMsIGFuZCByZXR1cm5zIGEgdmlydHVhbCBub2RlLlxuZXhwb3J0IGludGVyZmFjZSBWIHtcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXVudXNlZC12YXJzLCBuby11c2UtYmVmb3JlLWRlZmluZVxuICAodGFnT3JDb21wb25lbnQ6IHN0cmluZyB8IENvbXBvbmVudCB8IFBPSk9Db21wb25lbnQsIHByb3BzOiBWbm9kZVByb3BlcnRpZXMgfCBudWxsLCAuLi5jaGlsZHJlbjogQ2hpbGRyZW4pOlxuICAgIHwgVm5vZGVJbnRlcmZhY2VcbiAgICB8IFZub2RlQ29tcG9uZW50SW50ZXJmYWNlO1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tdW51c2VkLXZhcnMsIG5vLXVzZS1iZWZvcmUtZGVmaW5lXG4gIGZyYWdtZW50KF86IGFueSwgLi4uY2hpbGRyZW46IENoaWxkcmVuKTogQ2hpbGRyZW47XG59XG5cbi8vICd0ZXh0VGFnJyBpcyBhIGNvbnN0YW50IHN0cmluZyB0aGF0IGlzIHVzZWQgdG8gcmVwcmVzZW50IHRleHQgbm9kZXMgaW4gdGhlIHZpcnR1YWwgRE9NLlxuY29uc3QgdGV4dFRhZyA9IFwiI3RleHRcIjtcblxuLy8gJ2lzTm9kZUpzJyBpcyBhIGJvb2xlYW4gdGhhdCBpcyB0cnVlIGlmIHRoZSBjb2RlIGlzIHJ1bm5pbmcgaW4gYSBOb2RlLmpzIGVudmlyb25tZW50IGFuZCBmYWxzZSBvdGhlcndpc2UuXG4vLyBJdCBpcyBkZXRlcm1pbmVkIGJ5IGNoZWNraW5nIGlmIHRoZSAncHJvY2VzcycgZ2xvYmFsIG9iamVjdCBpcyBkZWZpbmVkIGFuZCBoYXMgYSAndmVyc2lvbnMnIHByb3BlcnR5LlxuZXhwb3J0IGNvbnN0IGlzTm9kZUpzID0gQm9vbGVhbih0eXBlb2YgcHJvY2VzcyAhPT0gXCJ1bmRlZmluZWRcIiAmJiBwcm9jZXNzLnZlcnNpb25zICYmIHByb2Nlc3MudmVyc2lvbnMubm9kZSk7XG5cbi8vICdjcmVhdGVEb21FbGVtZW50JyBpcyBhIGZ1bmN0aW9uIHRoYXQgY3JlYXRlcyBhIG5ldyBET00gZWxlbWVudCB3aXRoIHRoZSBzcGVjaWZpZWQgdGFnIG5hbWUuXG4vLyBJZiAnaXNTVkcnIGlzIHRydWUsIGl0IGNyZWF0ZXMgYW4gU1ZHIGVsZW1lbnQgaW5zdGVhZCBvZiBhIHJlZ3VsYXIgRE9NIGVsZW1lbnQuXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlRG9tRWxlbWVudCh0YWc6IHN0cmluZywgaXNTVkc6IGJvb2xlYW4gPSBmYWxzZSk6IERvbUVsZW1lbnQge1xuICByZXR1cm4gaXNTVkcgPyBkb2N1bWVudC5jcmVhdGVFbGVtZW50TlMoXCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiLCB0YWcpIDogZG9jdW1lbnQuY3JlYXRlRWxlbWVudCh0YWcpO1xufVxuXG4vLyAnVm5vZGUnIGlzIGEgY2xhc3MgdGhhdCByZXByZXNlbnRzIGEgdmlydHVhbCBET00gbm9kZS5cbi8vIEl0IGhhcyB0aHJlZSBwcm9wZXJ0aWVzOiAndGFnJywgJ3Byb3BzJywgYW5kICdjaGlsZHJlbicuXG4vLyAnVm5vZGUnIGlzIGV4cG9ydGVkIGFzIGFuIG9iamVjdCB3aXRoIGEgdHlwZSBvZiAnVm5vZGVJbnRlcmZhY2UnLlxuLy8gVGhlICdhcyB1bmtub3duIGFzIFZub2RlSW50ZXJmYWNlJyBpcyB1c2VkIHRvIHRlbGwgVHlwZVNjcmlwdCB0aGF0IHRoZSAnVm5vZGUnIGZ1bmN0aW9uIGhhcyB0aGUgc2FtZSB0eXBlIGFzICdWbm9kZUludGVyZmFjZScuXG5leHBvcnQgY29uc3QgVm5vZGUgPSBmdW5jdGlvbiBWbm9kZSh0aGlzOiBWbm9kZUludGVyZmFjZSwgdGFnOiBzdHJpbmcsIHByb3BzOiBWbm9kZVByb3BlcnRpZXMsIGNoaWxkcmVuOiBDaGlsZHJlbikge1xuICAvLyAndGhpcycgcmVmZXJzIHRvIHRoZSBjdXJyZW50IGluc3RhbmNlIG9mICdWbm9kZScuXG4gIHRoaXMudGFnID0gdGFnO1xuICB0aGlzLnByb3BzID0gcHJvcHM7XG4gIHRoaXMuY2hpbGRyZW4gPSBjaGlsZHJlbjtcbn0gYXMgdW5rbm93biBhcyBWbm9kZUludGVyZmFjZTtcblxuLy8gJ2lzQ29tcG9uZW50JyBpcyBhIGZ1bmN0aW9uIHRoYXQgcmV0dXJucyB0cnVlIGlmIHRoZSBnaXZlbiAnY29tcG9uZW50JyBpcyBhIHZhbGlkIGNvbXBvbmVudCBhbmQgZmFsc2Ugb3RoZXJ3aXNlLlxuLy8gQSBjb21wb25lbnQgaXMgZWl0aGVyIGEgZnVuY3Rpb24gb3IgYW4gb2JqZWN0IHdpdGggYSAndmlldycgZnVuY3Rpb24uXG5leHBvcnQgZnVuY3Rpb24gaXNDb21wb25lbnQoY29tcG9uZW50OiB1bmtub3duKTogY29tcG9uZW50IGlzIENvbXBvbmVudCB7XG4gIHJldHVybiBCb29sZWFuKFxuICAgIGNvbXBvbmVudCAmJiAodHlwZW9mIGNvbXBvbmVudCA9PT0gXCJmdW5jdGlvblwiIHx8ICh0eXBlb2YgY29tcG9uZW50ID09PSBcIm9iamVjdFwiICYmIFwidmlld1wiIGluIGNvbXBvbmVudCkpXG4gICk7XG59XG5cbi8vICdpc1Zub2RlJyBpcyBhIGZ1bmN0aW9uIHRoYXQgcmV0dXJucyB0cnVlIGlmIHRoZSBnaXZlbiAnb2JqZWN0JyBpcyBhICdWbm9kZScgaW5zdGFuY2UgYW5kIGZhbHNlIG90aGVyd2lzZS5cbmV4cG9ydCBjb25zdCBpc1Zub2RlID0gKG9iamVjdD86IHVua25vd24gfCBWbm9kZUludGVyZmFjZSk6IG9iamVjdCBpcyBWbm9kZUludGVyZmFjZSA9PiB7XG4gIC8vIFVzZSB0aGUgJ2luc3RhbmNlb2YnIG9wZXJhdG9yIHRvIGNoZWNrIGlmICdvYmplY3QnIGlzIGFuIGluc3RhbmNlIG9mICdWbm9kZScuXG4gIHJldHVybiBvYmplY3QgaW5zdGFuY2VvZiBWbm9kZTtcbn07XG5cbi8vICdpc1Zub2RlQ29tcG9uZW50JyBpcyBhIGZ1bmN0aW9uIHRoYXQgcmV0dXJucyB0cnVlIGlmIHRoZSBnaXZlbiAnb2JqZWN0JyBpcyBhICdWbm9kZScgaW5zdGFuY2Ugd2l0aCBhICd0YWcnIHByb3BlcnR5IHRoYXQgaXMgYSB2YWxpZCBjb21wb25lbnQuXG4vLyBJdCByZXR1cm5zIGZhbHNlIG90aGVyd2lzZS5cbmV4cG9ydCBjb25zdCBpc1Zub2RlQ29tcG9uZW50ID0gKG9iamVjdD86IHVua25vd24gfCBWbm9kZUNvbXBvbmVudEludGVyZmFjZSk6IG9iamVjdCBpcyBWbm9kZUNvbXBvbmVudEludGVyZmFjZSA9PiB7XG4gIC8vIENoZWNrIGlmICdvYmplY3QnIGlzIGEgJ1Zub2RlJyBpbnN0YW5jZSBhbmQgaXRzICd0YWcnIHByb3BlcnR5IGlzIGEgdmFsaWQgY29tcG9uZW50LlxuICByZXR1cm4gaXNWbm9kZShvYmplY3QpICYmIGlzQ29tcG9uZW50KG9iamVjdC50YWcpO1xufTtcblxuLy8gJ2RvbVRvVm5vZGUnIGlzIGEgZnVuY3Rpb24gdGhhdCBjb252ZXJ0cyBhIERPTSBub2RlIHRvIGEgJ1Zub2RlJyBpbnN0YW5jZS5cbmV4cG9ydCBmdW5jdGlvbiBkb21Ub1Zub2RlKGRvbTogYW55KTogVm5vZGVXaXRoRG9tIHtcbiAgLy8gSWYgdGhlIGNoaWxkIG5vZGUgaXMgYSB0ZXh0IG5vZGUsIGNyZWF0ZSBhICdWbm9kZScgaW5zdGFuY2Ugd2l0aCB0aGUgJ3RleHRUYWcnIGNvbnN0YW50IGFzIHRoZSAndGFnJyBwcm9wZXJ0eS5cbiAgLy8gU2V0IHRoZSAnZG9tJyBwcm9wZXJ0eSBvZiB0aGUgJ1Zub2RlJyBpbnN0YW5jZSB0byB0aGUgY2hpbGQgRE9NIG5vZGUuXG4gIC8vIFB1c2ggdGhlICdWbm9kZScgaW5zdGFuY2UgdG8gdGhlICdjaGlsZHJlbicgYXJyYXkuXG4gIGlmIChkb20ubm9kZVR5cGUgPT09IDMpIHtcbiAgICBjb25zdCB2bm9kZSA9IG5ldyBWbm9kZSh0ZXh0VGFnLCB7fSwgW2RvbS5ub2RlVmFsdWVdKTtcbiAgICB2bm9kZS5kb20gPSBkb207XG4gICAgcmV0dXJuIHZub2RlIGFzIFZub2RlV2l0aERvbTtcbiAgfVxuXG4gIGNvbnN0IGNoaWxkcmVuOiBWbm9kZVdpdGhEb21bXSA9IFtdO1xuICAvLyBJdGVyYXRlIHRocm91Z2ggYWxsIGNoaWxkIG5vZGVzIG9mICdkb20nLlxuICBmb3IgKGxldCBpID0gMCwgbCA9IGRvbS5jaGlsZE5vZGVzLmxlbmd0aDsgaSA8IGw7IGkrKykge1xuICAgIGNvbnN0IGNoaWxkRG9tID0gZG9tLmNoaWxkTm9kZXNbaV07XG4gICAgLy8gSWYgdGhlIGNoaWxkIG5vZGUgaXMgYW4gZWxlbWVudCBub2RlLCByZWN1cnNpdmVseSBjYWxsICdkb21Ub1Zub2RlJyB0byBjb252ZXJ0IGl0IHRvIGEgJ1Zub2RlJyBpbnN0YW5jZS5cbiAgICAvLyBQdXNoIHRoZSAnVm5vZGUnIGluc3RhbmNlIHRvIHRoZSAnY2hpbGRyZW4nIGFycmF5LlxuICAgIGlmIChjaGlsZERvbS5ub2RlVHlwZSA9PT0gMSB8fCBjaGlsZERvbS5ub2RlVHlwZSA9PT0gMykge1xuICAgICAgY2hpbGRyZW4ucHVzaChkb21Ub1Zub2RlKGNoaWxkRG9tKSk7XG4gICAgfVxuICB9XG5cbiAgY29uc3QgcHJvcHM6IFZub2RlUHJvcGVydGllcyA9IHt9O1xuICAvLyBJdGVyYXRlIHRocm91Z2ggYWxsIGF0dHJpYnV0ZXMgb2YgJ2RvbScuXG4gIGZvciAobGV0IGkgPSAwLCBsID0gZG9tLmF0dHJpYnV0ZXMubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XG4gICAgY29uc3QgYXR0ciA9IGRvbS5hdHRyaWJ1dGVzW2ldO1xuICAgIC8vIEFkZCB0aGUgYXR0cmlidXRlIHRvIHRoZSAncHJvcHMnIG9iamVjdCwgdXNpbmcgdGhlIGF0dHJpYnV0ZSdzIG5hbWUgYXMgdGhlIGtleSBhbmQgaXRzIHZhbHVlIGFzIHRoZSB2YWx1ZS5cbiAgICBwcm9wc1thdHRyLm5vZGVOYW1lXSA9IGF0dHIubm9kZVZhbHVlO1xuICB9XG5cbiAgLy8gQ3JlYXRlIGEgbmV3ICdWbm9kZScgaW5zdGFuY2Ugd2l0aCB0aGUgJ3RhZycgcHJvcGVydHkgc2V0IHRvIHRoZSBsb3dlcmNhc2UgdmVyc2lvbiBvZiB0aGUgRE9NIG5vZGUncyB0YWcgbmFtZS5cbiAgLy8gU2V0IHRoZSAncHJvcHMnIGFuZCAnY2hpbGRyZW4nIHByb3BlcnRpZXMgdG8gdGhlICdwcm9wcycgYW5kICdjaGlsZHJlbicgYXJyYXlzIHJlc3BlY3RpdmVseS5cbiAgLy8gU2V0IHRoZSAnZG9tJyBwcm9wZXJ0eSBvZiB0aGUgJ1Zub2RlJyBpbnN0YW5jZSB0byB0aGUgRE9NIG5vZGUuXG4gIGNvbnN0IHZub2RlID0gbmV3IFZub2RlKGRvbS50YWdOYW1lLnRvTG93ZXJDYXNlKCksIHByb3BzLCBjaGlsZHJlbik7XG4gIHZub2RlLmRvbSA9IGRvbTtcbiAgcmV0dXJuIHZub2RlIGFzIFZub2RlV2l0aERvbTtcbn1cblxuLy8gVGhpcyBmdW5jdGlvbiB0YWtlcyBpbiBhbiBIVE1MIHN0cmluZyBhbmQgY3JlYXRlcyBhIHZpcnR1YWwgbm9kZSByZXByZXNlbnRhdGlvbiBvZiBpdFxuLy8gdXNpbmcgdGhlIGBkb21Ub1Zub2RlYCBmdW5jdGlvbi4gSXQgZG9lcyB0aGlzIGJ5IGNyZWF0aW5nIGEgbmV3IGBkaXZgIGVsZW1lbnQsIHNldHRpbmdcbi8vIGl0cyBgaW5uZXJIVE1MYCB0byB0aGUgcHJvdmlkZWQgSFRNTCBzdHJpbmcsIGFuZCB0aGVuIHVzaW5nIGBtYXBgIHRvIGl0ZXJhdGUgb3ZlciB0aGVcbi8vIGBjaGlsZE5vZGVzYCBvZiB0aGUgYGRpdmAgZWxlbWVudCwgcGFzc2luZyBlYWNoIG9uZSB0byBgZG9tVG9Wbm9kZWAgdG8gY3JlYXRlIGEgdmlydHVhbFxuLy8gbm9kZSByZXByZXNlbnRhdGlvbiBvZiBpdC4gVGhlIHJlc3VsdGluZyBhcnJheSBvZiB2aXJ0dWFsIG5vZGVzIGlzIHRoZW4gcmV0dXJuZWQuXG5leHBvcnQgZnVuY3Rpb24gdHJ1c3QoaHRtbFN0cmluZzogc3RyaW5nKSB7XG4gIGNvbnN0IGRpdiA9IGNyZWF0ZURvbUVsZW1lbnQoXCJkaXZcIik7XG4gIGRpdi5pbm5lckhUTUwgPSBodG1sU3RyaW5nLnRyaW0oKTtcblxuICByZXR1cm4gW10ubWFwLmNhbGwoZGl2LmNoaWxkTm9kZXMsIChpdGVtKSA9PiBkb21Ub1Zub2RlKGl0ZW0pKTtcbn1cblxuLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0gKi9cbi8qIE1haW4gQ29tcG9uZW50IGltcGxlbWVudGF0aW9uICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovXG4vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSAqL1xuXG4vLyBUaGVzZSB2YXJpYWJsZXMgYXJlIHVzZWQgdG8gc3RvcmUgdGhlIG1haW4gY29tcG9uZW50LCB0aGUgbWFpbiB2aXJ0dWFsIG5vZGUsIGFuZCB3aGV0aGVyXG4vLyB0aGUgbWFpbiBjb21wb25lbnQgaXMgY3VycmVudGx5IG1vdW50ZWQuXG5sZXQgbWFpbkNvbXBvbmVudDogVm5vZGVDb21wb25lbnRJbnRlcmZhY2UgfCBudWxsID0gbnVsbDtcbmxldCBtYWluVm5vZGU6IFZub2RlV2l0aERvbSB8IG51bGwgPSBudWxsO1xubGV0IGlzTW91bnRlZCA9IGZhbHNlO1xuXG4vLyBUaGlzIG9iamVjdCBpcyB1c2VkIHRvIHN0b3JlIHRoZSBjdXJyZW50IHZpcnR1YWwgbm9kZSBhbmQgY29tcG9uZW50IGJlaW5nIHJlbmRlcmVkLlxuZXhwb3J0IGNvbnN0IGN1cnJlbnQ6IEN1cnJlbnQgPSB7XG4gIHZub2RlOiBudWxsLFxuICBvbGRWbm9kZTogbnVsbCxcbiAgY29tcG9uZW50OiBudWxsLFxuICBldmVudDogbnVsbFxufTtcblxuLyogUmVzZXJ2ZWQgcHJvcHMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi9cbi8vIFRoaXMgb2JqZWN0IGlzIHVzZWQgdG8gc3RvcmUgdGhlIG5hbWVzIG9mIHJlc2VydmVkIHByb3BzLCB3aGljaCBhcmUgcHJvcHMgdGhhdCBhcmUgcmVzZXJ2ZWRcbi8vIGZvciBzcGVjaWFsIHB1cnBvc2VzIGFuZCBzaG91bGQgbm90IGJlIHVzZWQgYXMgcmVndWxhciBjb21wb25lbnQgcHJvcHMuXG5leHBvcnQgY29uc3QgcmVzZXJ2ZWRQcm9wczogUmVjb3JkPHN0cmluZywgdHJ1ZT4gPSB7XG4gIGtleTogdHJ1ZSxcbiAgc3RhdGU6IHRydWUsXG4gIFwidi1rZWVwXCI6IHRydWUsXG5cbiAgLy8gQnVpbHQgaW4gZGlyZWN0aXZlc1xuICBcInYtaWZcIjogdHJ1ZSxcbiAgXCJ2LXVubGVzc1wiOiB0cnVlLFxuICBcInYtZm9yXCI6IHRydWUsXG4gIFwidi1zaG93XCI6IHRydWUsXG4gIFwidi1jbGFzc1wiOiB0cnVlLFxuICBcInYtaHRtbFwiOiB0cnVlLFxuICBcInYtbW9kZWxcIjogdHJ1ZSxcbiAgXCJ2LWNyZWF0ZVwiOiB0cnVlLFxuICBcInYtdXBkYXRlXCI6IHRydWUsXG4gIFwidi1jbGVhbnVwXCI6IHRydWVcbn07XG5cbi8qIE1vdW50aW5nLCBVcGRhdGluZywgQ2xlYW51cCBhbmQgVW5tb3VudGluZyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovXG4vLyBUaGVzZSBzZXRzIGFyZSB1c2VkIHRvIHN0b3JlIGNhbGxiYWNrcyBmb3IgdmFyaW91cyBsaWZlY3ljbGUgZXZlbnRzOiBtb3VudGluZywgdXBkYXRpbmcsXG4vLyBjbGVhbmluZyB1cCwgYW5kIHVubW91bnRpbmcuXG5jb25zdCBvbkNsZWFudXBTZXQ6IFNldDxGdW5jdGlvbj4gPSBuZXcgU2V0KCk7XG5jb25zdCBvbk1vdW50U2V0OiBTZXQ8RnVuY3Rpb24+ID0gbmV3IFNldCgpO1xuY29uc3Qgb25VcGRhdGVTZXQ6IFNldDxGdW5jdGlvbj4gPSBuZXcgU2V0KCk7XG5jb25zdCBvblVubW91bnRTZXQ6IFNldDxGdW5jdGlvbj4gPSBuZXcgU2V0KCk7XG5cbi8vIFRoZXNlIGZ1bmN0aW9ucyBhbGxvdyB1c2VycyB0byByZWdpc3RlciBjYWxsYmFja3MgZm9yIHRoZSBjb3JyZXNwb25kaW5nIGxpZmVjeWNsZSBldmVudHMuXG5leHBvcnQgZnVuY3Rpb24gb25Nb3VudChjYWxsYmFjazogRnVuY3Rpb24pIHtcbiAgaWYgKCFpc01vdW50ZWQpIHtcbiAgICBvbk1vdW50U2V0LmFkZChjYWxsYmFjayk7XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIG9uVXBkYXRlKGNhbGxiYWNrOiBGdW5jdGlvbikge1xuICBvblVwZGF0ZVNldC5hZGQoY2FsbGJhY2spO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gb25DbGVhbnVwKGNhbGxiYWNrOiBGdW5jdGlvbikge1xuICBvbkNsZWFudXBTZXQuYWRkKGNhbGxiYWNrKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIG9uVW5tb3VudChjYWxsYmFjazogRnVuY3Rpb24pIHtcbiAgaWYgKCFpc01vdW50ZWQpIHtcbiAgICBvblVubW91bnRTZXQuYWRkKGNhbGxiYWNrKTtcbiAgfVxufVxuXG4vLyBUaGlzIGZ1bmN0aW9uIGlzIHVzZWQgdG8gY2FsbCBhbGwgdGhlIGNhbGxiYWNrcyBpbiBhIGdpdmVuIHNldC5cbmZ1bmN0aW9uIGNhbGxTZXQoc2V0OiBTZXQ8RnVuY3Rpb24+KSB7XG4gIGZvciAoY29uc3QgY2FsbGJhY2sgb2Ygc2V0KSB7XG4gICAgY2FsbGJhY2soKTtcbiAgfVxuXG4gIHNldC5jbGVhcigpO1xufVxuXG4vKiBFdmVudCBsaXN0ZW5lciAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqL1xuXG4vLyBUaGlzIG9iamVjdCBzdG9yZXMgdGhlIG5hbWVzIG9mIGV2ZW50IGxpc3RlbmVycyB0aGF0IGhhdmUgYmVlbiBhZGRlZFxuY29uc3QgZXZlbnRMaXN0ZW5lck5hbWVzOiBSZWNvcmQ8c3RyaW5nLCB0cnVlPiA9IHt9O1xuXG4vLyBUaGlzIGZ1bmN0aW9uIGlzIGNhbGxlZCB3aGVuIGFuIGV2ZW50IG9jY3Vyc1xuZnVuY3Rpb24gZXZlbnRMaXN0ZW5lcihlOiBFdmVudCkge1xuICAvLyBTZXQgdGhlIGN1cnJlbnQgZXZlbnQgdG8gdGhlIGV2ZW50IHRoYXQgb2NjdXJyZWQgc28gdGhhdCBpdCBjYW4gYmUgcHJldmVudGVkIGlmIG5lY2Vzc2FyeVxuICBjdXJyZW50LmV2ZW50ID0gZTtcblxuICAvLyBDb252ZXJ0IHRoZSB0YXJnZXQgb2YgdGhlIGV2ZW50IHRvIGEgRE9NIGVsZW1lbnRcbiAgbGV0IGRvbSA9IGUudGFyZ2V0IGFzIERvbUVsZW1lbnQ7XG5cbiAgLy8gQ3JlYXRlIHRoZSBuYW1lIG9mIHRoZSBldmVudCBsaXN0ZW5lciBieSBhZGRpbmcgXCJ2LW9uXCIgdG8gdGhlIGV2ZW50IHR5cGVcbiAgY29uc3QgbmFtZSA9IGB2LW9uJHtlLnR5cGV9YDtcblxuICAvLyBLZWVwIGdvaW5nIHVwIHRoZSBET00gdHJlZSB1bnRpbCB3ZSBmaW5kIGFuIGVsZW1lbnQgd2l0aCBhbiBldmVudCBsaXN0ZW5lclxuICAvLyBtYXRjaGluZyB0aGUgZXZlbnQgdHlwZVxuICB3aGlsZSAoZG9tKSB7XG4gICAgaWYgKGRvbVtuYW1lXSkge1xuICAgICAgLy8gQ2FsbCB0aGUgZXZlbnQgbGlzdGVuZXIgZnVuY3Rpb25cbiAgICAgIGRvbVtuYW1lXShlLCBkb20pO1xuXG4gICAgICAvLyBJZiB0aGUgZGVmYXVsdCBhY3Rpb24gb2YgdGhlIGV2ZW50IGhhc24ndCBiZWVuIHByZXZlbnRlZCwgdXBkYXRlIHRoZSBET01cbiAgICAgIGlmICghZS5kZWZhdWx0UHJldmVudGVkKSB7XG4gICAgICAgIHVwZGF0ZSgpO1xuICAgICAgfVxuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBkb20gPSBkb20ucGFyZW50Tm9kZSBhcyBEb21FbGVtZW50O1xuICB9XG5cbiAgY3VycmVudC5ldmVudCA9IG51bGw7XG59XG5cbi8qIERpcmVjdGl2ZXMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovXG5cbi8vIFRoaXMgZnVuY3Rpb24gY3JlYXRlcyBhIGRpcmVjdGl2ZSB0aGF0IGhpZGVzIGFuIGVsZW1lbnQgYmFzZWQgb24gYSBjb25kaXRpb25cbmNvbnN0IGhpZGVEaXJlY3RpdmUgPSAodGVzdDogYm9vbGVhbikgPT4gKGJvb2w6IGJvb2xlYW4sIHZub2RlOiBWbm9kZUludGVyZmFjZSwgb2xkbm9kZT86IFZub2RlSW50ZXJmYWNlKSA9PiB7XG4gIC8vIElmIHRlc3QgaXMgdHJ1ZSwgdXNlIHRoZSB2YWx1ZSBvZiBib29sLiBPdGhlcndpc2UsIHVzZSB0aGUgb3Bwb3NpdGUgb2YgYm9vbC5cbiAgY29uc3QgdmFsdWUgPSB0ZXN0ID8gYm9vbCA6ICFib29sO1xuXG4gIC8vIElmIHRoZSB2YWx1ZSBpcyB0cnVlLCBoaWRlIHRoZSBlbGVtZW50IGJ5IHJlcGxhY2luZyBpdCB3aXRoIGEgdGV4dCBub2RlXG4gIGlmICh2YWx1ZSkge1xuICAgIGNvbnN0IG5ld2RvbSA9IGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKFwiXCIpO1xuICAgIGlmIChvbGRub2RlICYmIG9sZG5vZGUuZG9tICYmIG9sZG5vZGUuZG9tLnBhcmVudE5vZGUpIHtcbiAgICAgIG9sZG5vZGUuZG9tLnBhcmVudE5vZGUucmVwbGFjZUNoaWxkKG5ld2RvbSwgb2xkbm9kZS5kb20pO1xuICAgIH1cbiAgICB2bm9kZS50YWcgPSBcIiN0ZXh0XCI7XG4gICAgdm5vZGUuY2hpbGRyZW4gPSBbXTtcbiAgICB2bm9kZS5wcm9wcyA9IHt9O1xuICAgIHZub2RlLmRvbSA9IG5ld2RvbSBhcyB1bmtub3duIGFzIERvbUVsZW1lbnQ7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG59O1xuXG4vLyBUaGlzIG9iamVjdCBzdG9yZXMgYWxsIHRoZSBhdmFpbGFibGUgZGlyZWN0aXZlc1xuZXhwb3J0IGNvbnN0IGRpcmVjdGl2ZXM6IERpcmVjdGl2ZXMgPSB7XG4gIC8vIFRoZSBcInYtaWZcIiBkaXJlY3RpdmUgaGlkZXMgYW4gZWxlbWVudCBpZiB0aGUgZ2l2ZW4gY29uZGl0aW9uIGlzIGZhbHNlXG4gIFwidi1pZlwiOiBoaWRlRGlyZWN0aXZlKGZhbHNlKSxcblxuICAvLyBUaGUgXCJ2LXVubGVzc1wiIGRpcmVjdGl2ZSBoaWRlcyBhbiBlbGVtZW50IGlmIHRoZSBnaXZlbiBjb25kaXRpb24gaXMgdHJ1ZVxuICBcInYtdW5sZXNzXCI6IGhpZGVEaXJlY3RpdmUodHJ1ZSksXG5cbiAgLy8gVGhlIFwidi1mb3JcIiBkaXJlY3RpdmUgY3JlYXRlcyBhIGxvb3AgYW5kIGFwcGxpZXMgYSBjYWxsYmFjayBmdW5jdGlvbiB0byBlYWNoIGl0ZW0gaW4gdGhlIGxvb3BcbiAgXCJ2LWZvclwiOiAoc2V0OiB1bmtub3duW10sIHZub2RlOiBWbm9kZVdpdGhEb20pID0+IHtcbiAgICBjb25zdCBuZXdDaGlsZHJlbjogVm5vZGVJbnRlcmZhY2VbXSA9IFtdO1xuICAgIGNvbnN0IGNhbGxiYWNrID0gdm5vZGUuY2hpbGRyZW5bMF07XG4gICAgZm9yIChsZXQgaSA9IDAsIGwgPSBzZXQubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XG4gICAgICBuZXdDaGlsZHJlbi5wdXNoKGNhbGxiYWNrKHNldFtpXSwgaSkpO1xuICAgIH1cbiAgICB2bm9kZS5jaGlsZHJlbiA9IG5ld0NoaWxkcmVuO1xuICB9LFxuXG4gIC8vIFRoZSBcInYtc2hvd1wiIGRpcmVjdGl2ZSBzaG93cyBvciBoaWRlcyBhbiBlbGVtZW50IGJ5IHNldHRpbmcgdGhlIFwiZGlzcGxheVwiIHN0eWxlIHByb3BlcnR5XG4gIFwidi1zaG93XCI6IChib29sOiBib29sZWFuLCB2bm9kZTogVm5vZGVXaXRoRG9tKSA9PiB7XG4gICAgKFxuICAgICAgdm5vZGUuZG9tIGFzIHVua25vd24gYXMge1xuICAgICAgICBzdHlsZTogeyBkaXNwbGF5OiBzdHJpbmcgfTtcbiAgICAgIH1cbiAgICApLnN0eWxlLmRpc3BsYXkgPSBib29sID8gXCJcIiA6IFwibm9uZVwiO1xuICB9LFxuXG4gIC8vIFRoZSBcInYtY2xhc3NcIiBkaXJlY3RpdmUgYWRkcyBvciByZW1vdmVzIGNsYXNzIG5hbWVzIGZyb20gYW4gZWxlbWVudCBiYXNlZCBvbiBhIGNvbmRpdGlvblxuICBcInYtY2xhc3NcIjogKGNsYXNzZXM6IHsgW3g6IHN0cmluZ106IGJvb2xlYW4gfSwgdm5vZGU6IFZub2RlV2l0aERvbSkgPT4ge1xuICAgIC8vIExvb3AgdGhyb3VnaCBhbGwgdGhlIGNsYXNzIG5hbWVzIGluIHRoZSBjbGFzc2VzIG9iamVjdFxuICAgIGZvciAoY29uc3QgbmFtZSBpbiBjbGFzc2VzKSB7XG4gICAgICAvLyBBZGQgb3IgcmVtb3ZlIHRoZSBjbGFzcyBuYW1lIGZyb20gdGhlIGVsZW1lbnQncyBjbGFzcyBsaXN0IGJhc2VkIG9uIHRoZSB2YWx1ZSBpbiB0aGUgY2xhc3NlcyBvYmplY3RcbiAgICAgICh2bm9kZS5kb20gYXMgRG9tRWxlbWVudCkuY2xhc3NMaXN0LnRvZ2dsZShuYW1lLCBjbGFzc2VzW25hbWVdKTtcbiAgICB9XG4gIH0sXG5cbiAgLy8gVGhlIFwidi1odG1sXCIgZGlyZWN0aXZlIHNldHMgdGhlIGlubmVyIEhUTUwgb2YgYW4gZWxlbWVudCB0byB0aGUgZ2l2ZW4gSFRNTCBzdHJpbmdcbiAgXCJ2LWh0bWxcIjogKGh0bWw6IHN0cmluZywgdm5vZGU6IFZub2RlV2l0aERvbSkgPT4ge1xuICAgIC8vIFNldCB0aGUgY2hpbGRyZW4gb2YgdGhlIHZub2RlIHRvIGEgdHJ1c3RlZCB2ZXJzaW9uIG9mIHRoZSBIVE1MIHN0cmluZ1xuICAgIHZub2RlLmNoaWxkcmVuID0gW3RydXN0KGh0bWwpXTtcbiAgfSxcblxuICAvLyBUaGUgXCJ2LW1vZGVsXCIgZGlyZWN0aXZlIGJpbmRzIHRoZSB2YWx1ZSBvZiBhbiBpbnB1dCBlbGVtZW50IHRvIGEgbW9kZWwgcHJvcGVydHlcbiAgXCJ2LW1vZGVsXCI6IChbbW9kZWwsIHByb3BlcnR5LCBldmVudF06IGFueVtdLCB2bm9kZTogVm5vZGVXaXRoRG9tLCBvbGRWbm9kZT86IFZub2RlV2l0aERvbSkgPT4ge1xuICAgIGxldCB2YWx1ZTtcbiAgICAvLyBUaGlzIGZ1bmN0aW9uIHVwZGF0ZXMgdGhlIG1vZGVsIHByb3BlcnR5IHdoZW4gdGhlIGlucHV0IGVsZW1lbnQncyB2YWx1ZSBjaGFuZ2VzXG4gICAgbGV0IGhhbmRsZXIgPSAoZTogRXZlbnQpID0+IChtb2RlbFtwcm9wZXJ0eV0gPSAoZS50YXJnZXQgYXMgRG9tRWxlbWVudCAmIFJlY29yZDxzdHJpbmcsIGFueT4pLnZhbHVlKTtcbiAgICBpZiAodm5vZGUudGFnID09PSBcImlucHV0XCIpIHtcbiAgICAgIC8vIElmIHRoZSBlbGVtZW50IGlzIGFuIGlucHV0LCB1c2UgdGhlIFwiaW5wdXRcIiBldmVudCBieSBkZWZhdWx0XG4gICAgICBldmVudCA9IGV2ZW50IHx8IFwib25pbnB1dFwiO1xuICAgICAgLy8gRGVwZW5kaW5nIG9uIHRoZSB0eXBlIG9mIGlucHV0IGVsZW1lbnQsIHVzZSBhIGRpZmZlcmVudCBoYW5kbGVyIGZ1bmN0aW9uXG4gICAgICBzd2l0Y2ggKHZub2RlLnByb3BzLnR5cGUpIHtcbiAgICAgICAgY2FzZSBcImNoZWNrYm94XCI6IHtcbiAgICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShtb2RlbFtwcm9wZXJ0eV0pKSB7XG4gICAgICAgICAgICAvLyBJZiB0aGUgbW9kZWwgcHJvcGVydHkgaXMgYW4gYXJyYXksIGFkZCBvciByZW1vdmUgdGhlIHZhbHVlIGZyb20gdGhlIGFycmF5IHdoZW4gdGhlIGNoZWNrYm94IGlzIGNoZWNrZWQgb3IgdW5jaGVja2VkXG4gICAgICAgICAgICBoYW5kbGVyID0gKGU6IEV2ZW50KSA9PiB7XG4gICAgICAgICAgICAgIGNvbnN0IHZhbCA9IChlLnRhcmdldCBhcyBEb21FbGVtZW50ICYgUmVjb3JkPHN0cmluZywgYW55PikudmFsdWU7XG4gICAgICAgICAgICAgIGNvbnN0IGlkeCA9IG1vZGVsW3Byb3BlcnR5XS5pbmRleE9mKHZhbCk7XG4gICAgICAgICAgICAgIGlmIChpZHggPT09IC0xKSB7XG4gICAgICAgICAgICAgICAgbW9kZWxbcHJvcGVydHldLnB1c2godmFsKTtcbiAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBtb2RlbFtwcm9wZXJ0eV0uc3BsaWNlKGlkeCwgMSk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICAvLyBJZiB0aGUgdmFsdWUgaXMgaW4gdGhlIGFycmF5LCBzZXQgdGhlIGNoZWNrYm94IHRvIGJlIGNoZWNrZWRcbiAgICAgICAgICAgIHZhbHVlID0gbW9kZWxbcHJvcGVydHldLmluZGV4T2Yodm5vZGUuZG9tLnZhbHVlKSAhPT0gLTE7XG4gICAgICAgICAgfSBlbHNlIGlmIChcInZhbHVlXCIgaW4gdm5vZGUucHJvcHMpIHtcbiAgICAgICAgICAgIC8vIElmIHRoZSBpbnB1dCBlbGVtZW50IGhhcyBhIFwidmFsdWVcIiBhdHRyaWJ1dGUsIHVzZSBpdCB0byBkZXRlcm1pbmUgdGhlIGNoZWNrZWQgc3RhdGVcbiAgICAgICAgICAgIGhhbmRsZXIgPSAoKSA9PiB7XG4gICAgICAgICAgICAgIGlmIChtb2RlbFtwcm9wZXJ0eV0gPT09IHZub2RlLnByb3BzLnZhbHVlKSB7XG4gICAgICAgICAgICAgICAgbW9kZWxbcHJvcGVydHldID0gbnVsbDtcbiAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBtb2RlbFtwcm9wZXJ0eV0gPSB2bm9kZS5wcm9wcy52YWx1ZTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIHZhbHVlID0gbW9kZWxbcHJvcGVydHldID09PSB2bm9kZS5wcm9wcy52YWx1ZTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gSWYgdGhlcmUgaXMgbm8gXCJ2YWx1ZVwiIGF0dHJpYnV0ZSwgdXNlIGEgYm9vbGVhbiB2YWx1ZSBmb3IgdGhlIG1vZGVsIHByb3BlcnR5XG4gICAgICAgICAgICBoYW5kbGVyID0gKCkgPT4gKG1vZGVsW3Byb3BlcnR5XSA9ICFtb2RlbFtwcm9wZXJ0eV0pO1xuICAgICAgICAgICAgdmFsdWUgPSBtb2RlbFtwcm9wZXJ0eV07XG4gICAgICAgICAgfVxuICAgICAgICAgIC8vIFNldCB0aGUgXCJjaGVja2VkXCIgYXR0cmlidXRlIG9uIHRoZSBpbnB1dCBlbGVtZW50XG4gICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXVzZS1iZWZvcmUtZGVmaW5lXG4gICAgICAgICAgc2hhcmVkU2V0QXR0cmlidXRlKFwiY2hlY2tlZFwiLCB2YWx1ZSwgdm5vZGUpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIGNhc2UgXCJyYWRpb1wiOiB7XG4gICAgICAgICAgLy8gSWYgdGhlIGVsZW1lbnQgaXMgYSByYWRpbyBidXR0b24sIHNldCB0aGUgXCJjaGVja2VkXCIgYXR0cmlidXRlIGJhc2VkIG9uIHRoZSB2YWx1ZSBvZiB0aGUgbW9kZWwgcHJvcGVydHlcbiAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tdXNlLWJlZm9yZS1kZWZpbmVcbiAgICAgICAgICBzaGFyZWRTZXRBdHRyaWJ1dGUoXCJjaGVja2VkXCIsIG1vZGVsW3Byb3BlcnR5XSA9PT0gdm5vZGUuZG9tLnZhbHVlLCB2bm9kZSk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgZGVmYXVsdDoge1xuICAgICAgICAgIC8vIEZvciBhbGwgb3RoZXIgaW5wdXQgdHlwZXMsIHNldCB0aGUgXCJ2YWx1ZVwiIGF0dHJpYnV0ZSBiYXNlZCBvbiB0aGUgdmFsdWUgb2YgdGhlIG1vZGVsIHByb3BlcnR5XG4gICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXVzZS1iZWZvcmUtZGVmaW5lXG4gICAgICAgICAgc2hhcmVkU2V0QXR0cmlidXRlKFwidmFsdWVcIiwgbW9kZWxbcHJvcGVydHldLCB2bm9kZSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKHZub2RlLnRhZyA9PT0gXCJzZWxlY3RcIikge1xuICAgICAgLy8gSWYgdGhlIGVsZW1lbnQgaXMgYSBzZWxlY3QgZWxlbWVudCwgdXNlIHRoZSBcImNsaWNrXCIgZXZlbnQgYnkgZGVmYXVsdFxuICAgICAgZXZlbnQgPSBldmVudCB8fCBcIm9uY2xpY2tcIjtcbiAgICAgIGlmICh2bm9kZS5wcm9wcy5tdWx0aXBsZSkge1xuICAgICAgICAvLyBJZiB0aGUgc2VsZWN0IGVsZW1lbnQgYWxsb3dzIG11bHRpcGxlIHNlbGVjdGlvbnMsIHVwZGF0ZSB0aGUgbW9kZWwgcHJvcGVydHkgd2l0aCBhbiBhcnJheSBvZiBzZWxlY3RlZCB2YWx1ZXNcbiAgICAgICAgaGFuZGxlciA9IChlOiBFdmVudCAmIFJlY29yZDxzdHJpbmcsIGFueT4pID0+IHtcbiAgICAgICAgICBjb25zdCB2YWwgPSAoZS50YXJnZXQgYXMgRG9tRWxlbWVudCAmIFJlY29yZDxzdHJpbmcsIGFueT4pLnZhbHVlO1xuICAgICAgICAgIGlmIChlLmN0cmxLZXkpIHtcbiAgICAgICAgICAgIC8vIElmIHRoZSBDdHJsIGtleSBpcyBwcmVzc2VkLCBhZGQgb3IgcmVtb3ZlIHRoZSB2YWx1ZSBmcm9tIHRoZSBhcnJheVxuICAgICAgICAgICAgY29uc3QgaWR4ID0gbW9kZWxbcHJvcGVydHldLmluZGV4T2YodmFsKTtcbiAgICAgICAgICAgIGlmIChpZHggPT09IC0xKSB7XG4gICAgICAgICAgICAgIG1vZGVsW3Byb3BlcnR5XS5wdXNoKHZhbCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBtb2RlbFtwcm9wZXJ0eV0uc3BsaWNlKGlkeCwgMSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIElmIHRoZSBDdHJsIGtleSBpcyBub3QgcHJlc3NlZCwgc2V0IHRoZSBtb2RlbCBwcm9wZXJ0eSB0byBhbiBhcnJheSB3aXRoIHRoZSBzZWxlY3RlZCB2YWx1ZVxuICAgICAgICAgICAgbW9kZWxbcHJvcGVydHldLnNwbGljZSgwLCBtb2RlbFtwcm9wZXJ0eV0ubGVuZ3RoKTtcbiAgICAgICAgICAgIG1vZGVsW3Byb3BlcnR5XS5wdXNoKHZhbCk7XG4gICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICAvLyBTZXQgdGhlIFwic2VsZWN0ZWRcIiBhdHRyaWJ1dGUgb24gdGhlIG9wdGlvbnMgYmFzZWQgb24gd2hldGhlciB0aGV5IGFyZSBpbiB0aGUgbW9kZWwgcHJvcGVydHkgYXJyYXlcbiAgICAgICAgdm5vZGUuY2hpbGRyZW4uZm9yRWFjaCgoY2hpbGQ6IFZub2RlSW50ZXJmYWNlKSA9PiB7XG4gICAgICAgICAgaWYgKGNoaWxkLnRhZyA9PT0gXCJvcHRpb25cIikge1xuICAgICAgICAgICAgY29uc3QgdmFsdWUgPSBcInZhbHVlXCIgaW4gY2hpbGQucHJvcHMgPyBjaGlsZC5wcm9wcy52YWx1ZSA6IGNoaWxkLmNoaWxkcmVuLmpvaW4oXCJcIikudHJpbSgpO1xuICAgICAgICAgICAgY2hpbGQucHJvcHMuc2VsZWN0ZWQgPSBtb2RlbFtwcm9wZXJ0eV0uaW5kZXhPZih2YWx1ZSkgIT09IC0xO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBJZiB0aGUgc2VsZWN0IGVsZW1lbnQgZG9lcyBub3QgYWxsb3cgbXVsdGlwbGUgc2VsZWN0aW9ucywgc2V0IHRoZSBcInNlbGVjdGVkXCIgYXR0cmlidXRlIG9uIHRoZSBvcHRpb25zIGJhc2VkIG9uIHRoZSB2YWx1ZSBvZiB0aGUgbW9kZWwgcHJvcGVydHlcbiAgICAgICAgdm5vZGUuY2hpbGRyZW4uZm9yRWFjaCgoY2hpbGQ6IFZub2RlSW50ZXJmYWNlKSA9PiB7XG4gICAgICAgICAgaWYgKGNoaWxkLnRhZyA9PT0gXCJvcHRpb25cIikge1xuICAgICAgICAgICAgY29uc3QgdmFsdWUgPSBcInZhbHVlXCIgaW4gY2hpbGQucHJvcHMgPyBjaGlsZC5wcm9wcy52YWx1ZSA6IGNoaWxkLmNoaWxkcmVuLmpvaW4oXCJcIikudHJpbSgpO1xuICAgICAgICAgICAgY2hpbGQucHJvcHMuc2VsZWN0ZWQgPSB2YWx1ZSA9PT0gbW9kZWxbcHJvcGVydHldO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmICh2bm9kZS50YWcgPT09IFwidGV4dGFyZWFcIikge1xuICAgICAgLy8gSWYgdGhlIGVsZW1lbnQgaXMgYSB0ZXh0YXJlYSwgdXNlIHRoZSBcImlucHV0XCIgZXZlbnQgYnkgZGVmYXVsdFxuICAgICAgZXZlbnQgPSBldmVudCB8fCBcIm9uaW5wdXRcIjtcbiAgICAgIC8vIFNldCB0aGUgdGV4dGFyZWEncyBjb250ZW50IHRvIHRoZSB2YWx1ZSBvZiB0aGUgbW9kZWwgcHJvcGVydHlcbiAgICAgIHZub2RlLmNoaWxkcmVuID0gW21vZGVsW3Byb3BlcnR5XV07XG4gICAgfVxuXG4gICAgLy8gV2UgYXNzdW1lIHRoYXQgdGhlIHByZXYgaGFuZGxlciBpZiBhbnkgd2lsbCBub3QgYmUgY2hhbmdlZCBieSB0aGUgdXNlciBhY3Jvc3MgcGF0Y2hzXG4gICAgY29uc3QgcHJldkhhbmRsZXIgPSB2bm9kZS5wcm9wc1tldmVudF07XG5cbiAgICAvLyBTZXQgdGhlIGV2ZW50IGhhbmRsZXIgb24gdGhlIGVsZW1lbnRcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tdXNlLWJlZm9yZS1kZWZpbmVcbiAgICBzaGFyZWRTZXRBdHRyaWJ1dGUoXG4gICAgICBldmVudCxcbiAgICAgIChlOiBFdmVudCkgPT4ge1xuICAgICAgICBoYW5kbGVyKGUpO1xuXG4gICAgICAgIC8vIElmIHRoZSBwcmV2aW91cyBoYW5kbGVyIGlzIGRlZmluZWQsIGNhbGwgaXQgYWZ0ZXIgdGhlIG1vZGVsIGhhcyBiZWVuIHVwZGF0ZWRcbiAgICAgICAgaWYgKHByZXZIYW5kbGVyKSB7XG4gICAgICAgICAgcHJldkhhbmRsZXIoZSk7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgICB2bm9kZSxcbiAgICAgIG9sZFZub2RlXG4gICAgKTtcbiAgfSxcblxuICAvLyBUaGUgXCJ2LWNyZWF0ZVwiIGRpcmVjdGl2ZSBpcyBjYWxsZWQgd2hlbiBhIG5ldyB2aXJ0dWFsIG5vZGUgaXMgY3JlYXRlZC5cbiAgLy8gVGhlIHByb3ZpZGVkIGNhbGxiYWNrIGZ1bmN0aW9uIGlzIGNhbGxlZCB3aXRoIHRoZSBuZXcgdmlydHVhbCBub2RlIGFzIGFuIGFyZ3VtZW50LlxuICAvLyBUaGlzIGRpcmVjdGl2ZSBpcyBvbmx5IGNhbGxlZCBvbmNlIHBlciB2aXJ0dWFsIG5vZGUsIHdoZW4gaXQgaXMgZmlyc3QgY3JlYXRlZC5cbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXVudXNlZC12YXJzXG4gIFwidi1jcmVhdGVcIjogKGNhbGxiYWNrOiAodm5vZGU6IFZub2RlV2l0aERvbSkgPT4gdm9pZCwgdm5vZGU6IFZub2RlV2l0aERvbSwgb2xkVm5vZGU/OiBWbm9kZVdpdGhEb20pID0+IHtcbiAgICAvLyBJZiB0aGlzIGlzIG5vdCBhbiB1cGRhdGUsIGNhbGwgdGhlIGNhbGxiYWNrIGZ1bmN0aW9uIHdpdGggdGhlIG5ldyB2aXJ0dWFsIG5vZGVcbiAgICBpZiAoIW9sZFZub2RlKSB7XG4gICAgICBjb25zdCBjbGVhbnVwID0gY2FsbGJhY2sodm5vZGUpO1xuXG4gICAgICAvLyBJZiB0aGUgY2FsbGJhY2sgZnVuY3Rpb24gcmV0dXJucyBhIGZ1bmN0aW9uLCBjYWxsIGl0IHdoZW4gdGhlIHVwZGF0ZSBpcyBnb25uYSBiZSBjbGVhbmVkIHVwXG4gICAgICBpZiAodHlwZW9mIGNsZWFudXAgPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICBvbkNsZWFudXAoY2xlYW51cCk7XG4gICAgICB9XG4gICAgfVxuICB9LFxuXG4gIC8vIFRoZSBcInYtdXBkYXRlXCIgZGlyZWN0aXZlIGlzIGNhbGxlZCB3aGVuIGFuIGV4aXN0aW5nIHZpcnR1YWwgbm9kZSBpcyB1cGRhdGVkLlxuICAvLyBUaGUgcHJvdmlkZWQgY2FsbGJhY2sgZnVuY3Rpb24gaXMgY2FsbGVkIHdpdGggdGhlIG5ldyBhbmQgb2xkIHZpcnR1YWwgbm9kZXMgYXMgYXJndW1lbnRzLlxuICAvLyBUaGlzIGRpcmVjdGl2ZSBpcyBvbmx5IGNhbGxlZCBvbmNlIHBlciB2aXJ0dWFsIG5vZGUgdXBkYXRlLlxuICBcInYtdXBkYXRlXCI6IChcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tdW51c2VkLXZhcnNcbiAgICBjYWxsYmFjazogKHZub2RlOiBWbm9kZVdpdGhEb20sIG9sZFZub2RlOiBWbm9kZVdpdGhEb20pID0+IHZvaWQsXG4gICAgdm5vZGU6IFZub2RlV2l0aERvbSxcbiAgICBvbGRWbm9kZT86IFZub2RlV2l0aERvbVxuICApID0+IHtcbiAgICAvLyBJZiB0aGlzIGlzIGFuIHVwZGF0ZSwgY2FsbCB0aGUgY2FsbGJhY2sgZnVuY3Rpb24gd2l0aCB0aGUgbmV3IGFuZCBvbGQgdmlydHVhbCBub2Rlc1xuICAgIGlmIChvbGRWbm9kZSkge1xuICAgICAgY29uc3QgY2xlYW51cCA9IGNhbGxiYWNrKHZub2RlLCBvbGRWbm9kZSk7XG5cbiAgICAgIC8vIElmIHRoZSBjYWxsYmFjayBmdW5jdGlvbiByZXR1cm5zIGEgZnVuY3Rpb24sIGNhbGwgaXQgd2hlbiB0aGUgdXBkYXRlIGlzIGdvbm5hIGJlIGNsZWFuZWQgdXBcbiAgICAgIGlmICh0eXBlb2YgY2xlYW51cCA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgIG9uQ2xlYW51cChjbGVhbnVwKTtcbiAgICAgIH1cbiAgICB9XG4gIH0sXG5cbiAgLy8gVGhlIFwidi1jbGVhbnVwXCIgZGlyZWN0aXZlIGlzIGNhbGxlZCB3aGVuIHRoZSB1cGRhdGUgaXMgY2xlYW5lZCB1cC5cbiAgLy8gVGhlIHByb3ZpZGVkIGNhbGxiYWNrIGZ1bmN0aW9uIGlzIGNhbGxlZCB3aXRoIHRoZSBvbGQgdmlydHVhbCBub2RlIGFzIGFuIGFyZ3VtZW50LlxuICAvLyBUaGlzIGRpcmVjdGl2ZSBpcyBvbmx5IGNhbGxlZCBvbmNlIHBlciB2aXJ0dWFsIG5vZGUsIHdoZW4gdGhlIHVwZGF0ZSBpcyBjbGVhbmVkIHVwLlxuICBcInYtY2xlYW51cFwiOiAoXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXVudXNlZC12YXJzXG4gICAgY2FsbGJhY2s6ICh2bm9kZTogVm5vZGVXaXRoRG9tLCBvbGRWbm9kZT86IFZub2RlV2l0aERvbSkgPT4gdm9pZCxcbiAgICB2bm9kZTogVm5vZGVXaXRoRG9tLFxuICAgIG9sZFZub2RlPzogVm5vZGVXaXRoRG9tXG4gICkgPT4ge1xuICAgIC8vIEFkZCB0aGUgY2FsbGJhY2sgZnVuY3Rpb24gdG8gdGhlIGxpc3Qgb2YgY2xlYW51cCBmdW5jdGlvbnMgdG8gYmUgY2FsbGVkIHdoZW4gdGhlIHVwZGF0ZSBpcyBjbGVhbmVkIHVwXG4gICAgb25DbGVhbnVwKCgpID0+IGNhbGxiYWNrKHZub2RlLCBvbGRWbm9kZSkpO1xuICB9XG59O1xuLy8gQWRkIGEgZGlyZWN0aXZlIHRvIHRoZSBnbG9iYWwgZGlyZWN0aXZlcyBvYmplY3QsIHdpdGggdGhlIGtleSBiZWluZyB0aGUgbmFtZVxuLy8gcHJlY2VkZWQgYnkgXCJ2LVwiLiBBbHNvIGFkZCB0aGUgbmFtZSB0byB0aGUgZ2xvYmFsIHJlc2VydmVkUHJvcHMgb2JqZWN0LlxuZXhwb3J0IGZ1bmN0aW9uIGRpcmVjdGl2ZShuYW1lOiBzdHJpbmcsIGRpcmVjdGl2ZTogRGlyZWN0aXZlKSB7XG4gIGNvbnN0IGRpcmVjdGl2ZU5hbWUgPSBgdi0ke25hbWV9YDtcbiAgZGlyZWN0aXZlc1tkaXJlY3RpdmVOYW1lXSA9IGRpcmVjdGl2ZTtcbiAgcmVzZXJ2ZWRQcm9wc1tkaXJlY3RpdmVOYW1lXSA9IHRydWU7XG59XG5cbi8vIFNldCBhbiBhdHRyaWJ1dGUgb24gYSB2aXJ0dWFsIERPTSBub2RlIGFuZCB1cGRhdGUgdGhlIGFjdHVhbCBET00gZWxlbWVudC5cbi8vIElmIHRoZSBhdHRyaWJ1dGUgdmFsdWUgaXMgYSBmdW5jdGlvbiwgYWRkIGFuIGV2ZW50IGxpc3RlbmVyIGZvciB0aGUgYXR0cmlidXRlXG4vLyBuYW1lIHRvIHRoZSBET00gZWxlbWVudCByZXByZXNlbnRlZCBieSBtYWluVm5vZGUuXG4vLyBJZiBvbGRWbm9kZSBpcyBwcm92aWRlZCwgY29tcGFyZSB0aGUgbmV3IGF0dHJpYnV0ZSB2YWx1ZSB0byB0aGUgb2xkIHZhbHVlXG4vLyBhbmQgb25seSB1cGRhdGUgdGhlIGF0dHJpYnV0ZSBpZiB0aGUgdmFsdWVzIGFyZSBkaWZmZXJlbnQuXG5mdW5jdGlvbiBzaGFyZWRTZXRBdHRyaWJ1dGUobmFtZTogc3RyaW5nLCB2YWx1ZTogYW55LCBuZXdWbm9kZTogVm5vZGVXaXRoRG9tLCBvbGRWbm9kZT86IFZub2RlV2l0aERvbSk6IHZvaWQgfCBib29sZWFuIHtcbiAgLy8gSWYgdGhlIGF0dHJpYnV0ZSB2YWx1ZSBpcyBhIGZ1bmN0aW9uLCBhZGQgYW4gZXZlbnQgbGlzdGVuZXIgZm9yIHRoZSBhdHRyaWJ1dGVcbiAgLy8gbmFtZSB0byB0aGUgRE9NIGVsZW1lbnQgcmVwcmVzZW50ZWQgYnkgbWFpblZub2RlLlxuICBpZiAodHlwZW9mIHZhbHVlID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAvLyBPbmx5IGFkZCB0aGUgZXZlbnQgbGlzdGVuZXIgaWYgaXQgaGFzbid0IGJlZW4gYWRkZWQgeWV0LlxuICAgIGlmIChuYW1lIGluIGV2ZW50TGlzdGVuZXJOYW1lcyA9PT0gZmFsc2UpIHtcbiAgICAgIChtYWluVm5vZGUgYXMgVm5vZGVXaXRoRG9tKS5kb20uYWRkRXZlbnRMaXN0ZW5lcihuYW1lLnNsaWNlKDIpLCBldmVudExpc3RlbmVyKTtcbiAgICAgIGV2ZW50TGlzdGVuZXJOYW1lc1tuYW1lXSA9IHRydWU7XG4gICAgfVxuICAgIG5ld1Zub2RlLmRvbVtgdi0ke25hbWV9YF0gPSB2YWx1ZTtcbiAgICByZXR1cm47XG4gIH1cblxuICAvLyBJZiB0aGUgYXR0cmlidXRlIGlzIHByZXNlbnQgb24gdGhlIERPTSBlbGVtZW50IGFuZCBuZXdWbm9kZSBpcyBub3QgYW4gU1ZHLFxuICAvLyB1cGRhdGUgdGhlIGF0dHJpYnV0ZSBpZiB0aGUgdmFsdWUgaGFzIGNoYW5nZWQuXG4gIGlmIChuZXdWbm9kZS5pc1NWRyA9PT0gZmFsc2UgJiYgbmFtZSBpbiBuZXdWbm9kZS5kb20pIHtcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgZXFlcWVxXG4gICAgaWYgKG5ld1Zub2RlLmRvbVtuYW1lXSAhPSB2YWx1ZSkge1xuICAgICAgbmV3Vm5vZGUuZG9tW25hbWVdID0gdmFsdWU7XG4gICAgfVxuICAgIHJldHVybjtcbiAgfVxuXG4gIC8vIElmIG9sZFZub2RlIGlzIG5vdCBwcm92aWRlZCBvciB0aGUgYXR0cmlidXRlIHZhbHVlIGhhcyBjaGFuZ2VkLCB1cGRhdGUgdGhlXG4gIC8vIGF0dHJpYnV0ZSBvbiB0aGUgRE9NIGVsZW1lbnQuXG4gIGlmICghb2xkVm5vZGUgfHwgdmFsdWUgIT09IG9sZFZub2RlLnByb3BzW25hbWVdKSB7XG4gICAgaWYgKHZhbHVlID09PSBmYWxzZSkge1xuICAgICAgbmV3Vm5vZGUuZG9tLnJlbW92ZUF0dHJpYnV0ZShuYW1lKTtcbiAgICB9IGVsc2Uge1xuICAgICAgbmV3Vm5vZGUuZG9tLnNldEF0dHJpYnV0ZShuYW1lLCB2YWx1ZSk7XG4gICAgfVxuICB9XG59XG5cbi8vIFNldCBhbiBhdHRyaWJ1dGUgb24gYSB2aXJ0dWFsIERPTSBub2RlIGFuZCB1cGRhdGUgdGhlIGFjdHVhbCBET00gZWxlbWVudC5cbi8vIFNraXAgdGhlIGF0dHJpYnV0ZSBpZiBpdCBpcyBpbiB0aGUgcmVzZXJ2ZWRQcm9wcyBvYmplY3QuXG5leHBvcnQgZnVuY3Rpb24gc2V0QXR0cmlidXRlKG5hbWU6IHN0cmluZywgdmFsdWU6IGFueSwgbmV3Vm5vZGU6IFZub2RlV2l0aERvbSwgb2xkVm5vZGU/OiBWbm9kZVdpdGhEb20pOiB2b2lkIHtcbiAgaWYgKHJlc2VydmVkUHJvcHNbbmFtZV0pIHtcbiAgICByZXR1cm47XG4gIH1cbiAgbmV3Vm5vZGUucHJvcHNbbmFtZV0gPSB2YWx1ZTtcbiAgc2hhcmVkU2V0QXR0cmlidXRlKG5hbWUsIHZhbHVlLCBuZXdWbm9kZSwgb2xkVm5vZGUpO1xufVxuXG4vLyBVcGRhdGUgdGhlIGF0dHJpYnV0ZXMgb24gYSB2aXJ0dWFsIERPTSBub2RlLiBJZiBvbGRWbm9kZSBpcyBwcm92aWRlZCwgcmVtb3ZlXG4vLyBhdHRyaWJ1dGVzIGZyb20gdGhlIERPTSBlbGVtZW50IHRoYXQgYXJlIG5vdCBwcmVzZW50IGluIG5ld1Zub2RlLnByb3BzIGJ1dCBhcmVcbi8vIHByZXNlbnQgaW4gb2xkVm5vZGUucHJvcHMuIFRoZW4sIGl0ZXJhdGUgb3ZlciB0aGUgYXR0cmlidXRlcyBpbiBuZXdWbm9kZS5wcm9wc1xuLy8gYW5kIHVwZGF0ZSB0aGUgRE9NIGVsZW1lbnQgd2l0aCB0aGUgYXR0cmlidXRlcyB1c2luZyB0aGUgc2hhcmVkU2V0QXR0cmlidXRlXG4vLyBmdW5jdGlvbi4gSWYgYW4gYXR0cmlidXRlIGlzIGluIHRoZSByZXNlcnZlZFByb3BzIG9iamVjdCBhbmQgaGFzIGEgY29ycmVzcG9uZGluZ1xuLy8gZGlyZWN0aXZlIGluIHRoZSBkaXJlY3RpdmVzIG9iamVjdCwgY2FsbCB0aGUgZGlyZWN0aXZlIHdpdGggdGhlIGF0dHJpYnV0ZSB2YWx1ZVxuLy8gYW5kIHRoZSB0d28gdmlydHVhbCBET00gbm9kZXMgYXMgYXJndW1lbnRzLiBJZiB0aGUgZGlyZWN0aXZlIHJldHVybnMgZmFsc2UsIGV4aXRcbi8vIHRoZSBsb29wLlxuZXhwb3J0IGZ1bmN0aW9uIHVwZGF0ZUF0dHJpYnV0ZXMobmV3Vm5vZGU6IFZub2RlV2l0aERvbSwgb2xkVm5vZGU/OiBWbm9kZVdpdGhEb20pOiB2b2lkIHtcbiAgLy8gSWYgb2xkVm5vZGUgaXMgcHJvdmlkZWQsIHJlbW92ZSBhdHRyaWJ1dGVzIGZyb20gdGhlIERPTSBlbGVtZW50IHRoYXQgYXJlIG5vdFxuICAvLyBwcmVzZW50IGluIG5ld1Zub2RlLnByb3BzIGJ1dCBhcmUgcHJlc2VudCBpbiBvbGRWbm9kZS5wcm9wcy5cbiAgaWYgKG9sZFZub2RlKSB7XG4gICAgZm9yIChjb25zdCBuYW1lIGluIG9sZFZub2RlLnByb3BzKSB7XG4gICAgICBpZiAoIW5ld1Zub2RlLnByb3BzW25hbWVdICYmICFldmVudExpc3RlbmVyTmFtZXNbbmFtZV0gJiYgIXJlc2VydmVkUHJvcHNbbmFtZV0pIHtcbiAgICAgICAgaWYgKG5ld1Zub2RlLmlzU1ZHID09PSBmYWxzZSAmJiBuYW1lIGluIG5ld1Zub2RlLmRvbSkge1xuICAgICAgICAgIG5ld1Zub2RlLmRvbVtuYW1lXSA9IG51bGw7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgbmV3Vm5vZGUuZG9tLnJlbW92ZUF0dHJpYnV0ZShuYW1lKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8vIEl0ZXJhdGUgb3ZlciB0aGUgYXR0cmlidXRlcyBpbiBuZXdWbm9kZS5wcm9wcyBhbmQgdXBkYXRlIHRoZSBET00gZWxlbWVudCB3aXRoXG4gIC8vIHRoZSBhdHRyaWJ1dGVzIHVzaW5nIHRoZSBzaGFyZWRTZXRBdHRyaWJ1dGUgZnVuY3Rpb24uXG4gIGZvciAoY29uc3QgbmFtZSBpbiBuZXdWbm9kZS5wcm9wcykge1xuICAgIGlmIChyZXNlcnZlZFByb3BzW25hbWVdKSB7XG4gICAgICAvLyBJZiB0aGVyZSBpcyBhIGRpcmVjdGl2ZSBmb3IgdGhlIGF0dHJpYnV0ZSwgY2FsbCBpdCB3aXRoIHRoZSBhdHRyaWJ1dGUgdmFsdWVcbiAgICAgIC8vIGFuZCB0aGUgdHdvIHZpcnR1YWwgRE9NIG5vZGVzIGFzIGFyZ3VtZW50cy4gSWYgdGhlIGRpcmVjdGl2ZSByZXR1cm5zIGZhbHNlLFxuICAgICAgLy8gZXhpdCB0aGUgbG9vcC5cbiAgICAgIGlmIChkaXJlY3RpdmVzW25hbWVdICYmIGRpcmVjdGl2ZXNbbmFtZV0obmV3Vm5vZGUucHJvcHNbbmFtZV0sIG5ld1Zub2RlLCBvbGRWbm9kZSkgPT09IGZhbHNlKSB7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgY29udGludWU7XG4gICAgfVxuICAgIHNoYXJlZFNldEF0dHJpYnV0ZShuYW1lLCBuZXdWbm9kZS5wcm9wc1tuYW1lXSwgbmV3Vm5vZGUsIG9sZFZub2RlKTtcbiAgfVxufVxuXG4vKiBwYXRjaCAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovXG5cbi8vIFBhdGNoIGEgRE9NIG5vZGUgd2l0aCBhIG5ldyBWTm9kZSB0cmVlXG5leHBvcnQgZnVuY3Rpb24gcGF0Y2gobmV3Vm5vZGU6IFZub2RlV2l0aERvbSwgb2xkVm5vZGU/OiBWbm9kZVdpdGhEb20pOiB2b2lkIHtcbiAgLy8gSWYgdGhlIG5ldyB0cmVlIGhhcyBubyBjaGlsZHJlbiwgc2V0IHRoZSB0ZXh0IGNvbnRlbnQgb2YgdGhlIHBhcmVudCBET00gZWxlbWVudCB0byBhbiBlbXB0eSBzdHJpbmdcbiAgaWYgKG5ld1Zub2RlLmNoaWxkcmVuLmxlbmd0aCA9PT0gMCkge1xuICAgIG5ld1Zub2RlLmRvbS50ZXh0Q29udGVudCA9IFwiXCI7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgLy8gR2V0IHRoZSBjaGlsZHJlbiBvZiB0aGUgbmV3IGFuZCBvbGQgdmlydHVhbCBET00gbm9kZXNcbiAgY29uc3QgbmV3VHJlZSA9IG5ld1Zub2RlLmNoaWxkcmVuO1xuICBjb25zdCBvbGRUcmVlID0gb2xkVm5vZGU/LmNoaWxkcmVuIHx8IFtdO1xuICAvLyBHZXQgdGhlIGxlbmd0aCBvZiB0aGUgb2xkIHRyZWVcbiAgY29uc3Qgb2xkVHJlZUxlbmd0aCA9IG9sZFRyZWUubGVuZ3RoO1xuICAvLyBHZXQgdGhlIGxlbmd0aCBvZiB0aGUgbmV3IHRyZWVcbiAgbGV0IG5ld1RyZWVMZW5ndGggPSBuZXdUcmVlLmxlbmd0aDtcbiAgLy8gU2V0IHRoZSBnbG9iYWwgY3VycmVudCBvYmplY3QgdG8gdGhlIG5ldyBhbmQgb2xkIHZpcnR1YWwgRE9NIG5vZGVzXG4gIGN1cnJlbnQudm5vZGUgPSBuZXdWbm9kZTtcbiAgY3VycmVudC5vbGRWbm9kZSA9IG9sZFZub2RlO1xuXG4gIC8vIEZsYXR0ZW4gdGhlIG5ldyB0cmVlXG4gIC8vIFRha2UgaW50byBhY2NvdW50IHRoYXQgaXMgbmVjZXNzYXJ5IHRvIGZsYXR0ZW4gdGhlIHRyZWUgYmVmb3JlIHRoZSBwYXRjaCBwcm9jZXNzXG4gIC8vIHRvIGxldCB0aGUgaG9va3MgYW5kIHNpZ25hbHMgd29yayBwcm9wZXJseVxuICBsZXQgaSA9IDA7XG4gIHdoaWxlIChpIDwgbmV3VHJlZUxlbmd0aCkge1xuICAgIGNvbnN0IG5ld0NoaWxkID0gbmV3VHJlZVtpXTtcblxuICAgIC8vIElmIHRoZSBuZXcgY2hpbGQgaXMgYSBWbm9kZSBhbmQgaXMgbm90IGEgdGV4dCBub2RlXG4gICAgaWYgKG5ld0NoaWxkIGluc3RhbmNlb2YgVm5vZGUpIHtcbiAgICAgIC8vIElmIHRoZSB0YWcgb2YgdGhlIG5ldyBjaGlsZCBpcyBub3QgYSBzdHJpbmcsIGl0IGlzIGEgY29tcG9uZW50XG4gICAgICBpZiAodHlwZW9mIG5ld0NoaWxkLnRhZyAhPT0gXCJzdHJpbmdcIikge1xuICAgICAgICAvLyBTZXQgdGhlIGN1cnJlbnQgY29tcG9uZW50IHRvIHRoZSB0YWcgb2YgdGhlIG5ldyBjaGlsZFxuICAgICAgICBjdXJyZW50LmNvbXBvbmVudCA9IG5ld0NoaWxkLnRhZztcbiAgICAgICAgLy8gUmVwbGFjZSB0aGUgbmV3IGNoaWxkIHdpdGggdGhlIHJlc3VsdCBvZiBjYWxsaW5nIGl0cyB2aWV3IG9yIGJpbmQgbWV0aG9kLCBwYXNzaW5nIGluIHRoZSBwcm9wcyBhbmQgY2hpbGRyZW4gYXMgYXJndW1lbnRzXG4gICAgICAgIG5ld1RyZWUuc3BsaWNlKFxuICAgICAgICAgIGksXG4gICAgICAgICAgMSxcbiAgICAgICAgICAoXCJ2aWV3XCIgaW4gbmV3Q2hpbGQudGFnID8gbmV3Q2hpbGQudGFnLnZpZXcuYmluZChuZXdDaGlsZC50YWcpIDogbmV3Q2hpbGQudGFnLmJpbmQobmV3Q2hpbGQudGFnKSkoXG4gICAgICAgICAgICBuZXdDaGlsZC5wcm9wcyxcbiAgICAgICAgICAgIC4uLm5ld0NoaWxkLmNoaWxkcmVuXG4gICAgICAgICAgKVxuICAgICAgICApO1xuICAgICAgICBuZXdUcmVlTGVuZ3RoID0gbmV3VHJlZS5sZW5ndGg7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaSsrO1xuICAgICAgfVxuICAgICAgLy8gSWYgdGhlIG5ldyBjaGlsZCBpcyBhbiBhcnJheSwgZmxhdHRlbiBpdCBhbmQgY29udGludWUgdGhlIGxvb3BcbiAgICB9IGVsc2UgaWYgKEFycmF5LmlzQXJyYXkobmV3Q2hpbGQpKSB7XG4gICAgICBuZXdUcmVlLnNwbGljZShpLCAxLCAuLi5uZXdDaGlsZCk7XG4gICAgICBuZXdUcmVlTGVuZ3RoID0gbmV3VHJlZS5sZW5ndGg7XG4gICAgICAvLyBJZiB0aGUgbmV3IGNoaWxkIGlzIG51bGwgb3IgdW5kZWZpbmVkLCByZW1vdmUgaXQgZnJvbSB0aGUgbmV3IHRyZWUgYW5kIGNvbnRpbnVlIHRoZSBsb29wXG4gICAgfSBlbHNlIGlmIChuZXdDaGlsZCA9PSBudWxsKSB7XG4gICAgICBuZXdUcmVlLnNwbGljZShpLCAxKTtcbiAgICAgIG5ld1RyZWVMZW5ndGggPSBuZXdUcmVlLmxlbmd0aDtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gSWYgdGhlIG5ldyBjaGlsZCBpcyBhIFZub2RlLCBzZXQgdGhlIHRleHQgb2YgdGhlIFZub2RlIHRvIHRoZSB0ZXh0IGNvbnRlbnQgb2YgaXRzIGRvbSBwcm9wZXJ0eVxuICAgICAgbmV3VHJlZVtpXSA9IG5ldyBWbm9kZSh0ZXh0VGFnLCB7fSwgW25ld0NoaWxkXSk7XG4gICAgICBpKys7XG4gICAgfVxuICB9XG5cbiAgLy8gSWYgdGhlIG5ldyB0cmVlIGhhcyBubyBjaGlsZHJlbiwgc2V0IHRoZSB0ZXh0IGNvbnRlbnQgb2YgdGhlIHBhcmVudCBET00gZWxlbWVudCB0byBhbiBlbXB0eSBzdHJpbmdcbiAgaWYgKG5ld1RyZWVMZW5ndGggPT09IDApIHtcbiAgICBuZXdWbm9kZS5kb20udGV4dENvbnRlbnQgPSBcIlwiO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIC8vIElmIHRoZSBvbGQgdHJlZSBoYXMgY2hpbGRyZW4gYW5kIHRoZSBmaXJzdCBjaGlsZCBvZiB0aGUgbmV3IHRyZWUgaXMgYSBWTm9kZSB3aXRoIGEgXCJrZXlcIlxuICAvLyBhdHRyaWJ1dGUgYW5kIHRoZSBmaXJzdCBjaGlsZCBvZiB0aGUgb2xkIHRyZWUgaXMgYSBWTm9kZSB3aXRoIGEgXCJrZXlcIiBhdHRyaWJ1dGUsIHVwZGF0ZVxuICAvLyB0aGUgRE9NIGVsZW1lbnQgaW4gcGxhY2UgYnkgY29tcGFyaW5nIHRoZSBrZXlzIG9mIHRoZSBub2RlcyBpbiB0aGUgdHJlZXMuXG4gIGlmIChcbiAgICBvbGRUcmVlTGVuZ3RoID4gMCAmJlxuICAgIG5ld1RyZWVbMF0gaW5zdGFuY2VvZiBWbm9kZSAmJlxuICAgIG9sZFRyZWVbMF0gaW5zdGFuY2VvZiBWbm9kZSAmJlxuICAgIFwia2V5XCIgaW4gbmV3VHJlZVswXS5wcm9wcyAmJlxuICAgIFwia2V5XCIgaW4gb2xkVHJlZVswXS5wcm9wc1xuICApIHtcbiAgICBjb25zdCBvbGRLZXllZExpc3Q6IFJlY29yZDxzdHJpbmcsIG51bWJlcj4gPSB7fTtcbiAgICBjb25zdCBuZXdLZXllZExpc3Q6IFJlY29yZDxzdHJpbmcsIG51bWJlcj4gPSB7fTtcbiAgICBjb25zdCBjaGlsZE5vZGVzID0gbmV3Vm5vZGUuZG9tLmNoaWxkTm9kZXM7XG5cbiAgICAvLyBDcmVhdGUga2V5IG1hcHMgd2hpbGUgYWxzbyBoYW5kbGluZyByZW1vdmFsIG9mIG5vZGVzIG5vdCBwcmVzZW50IGluIG5ld1RyZWVcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IG9sZFRyZWVMZW5ndGg7IGkrKykge1xuICAgICAgb2xkS2V5ZWRMaXN0W29sZFRyZWVbaV0ucHJvcHMua2V5XSA9IGk7XG4gICAgICBpZiAoaSA8IG5ld1RyZWVMZW5ndGgpIHtcbiAgICAgICAgbmV3S2V5ZWRMaXN0W25ld1RyZWVbaV0ucHJvcHMua2V5XSA9IGk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBuZXdUcmVlTGVuZ3RoOyBpKyspIHtcbiAgICAgIGNvbnN0IG5ld0NoaWxkID0gbmV3VHJlZVtpXTtcbiAgICAgIGNvbnN0IG9sZENoaWxkSW5kZXggPSBvbGRLZXllZExpc3RbbmV3Q2hpbGQucHJvcHMua2V5XTtcbiAgICAgIGNvbnN0IG9sZENoaWxkID0gb2xkVHJlZVtvbGRDaGlsZEluZGV4XTtcbiAgICAgIGxldCBzaG91bGRQYXRjaCA9IHRydWU7XG5cbiAgICAgIGlmIChvbGRDaGlsZCkge1xuICAgICAgICBuZXdDaGlsZC5kb20gPSBvbGRDaGlsZC5kb207XG4gICAgICAgIGlmIChcInYta2VlcFwiIGluIG5ld0NoaWxkLnByb3BzICYmIG5ld0NoaWxkLnByb3BzW1widi1rZWVwXCJdID09PSBvbGRDaGlsZC5wcm9wc1tcInYta2VlcFwiXSkge1xuICAgICAgICAgIG5ld0NoaWxkLmNoaWxkcmVuID0gb2xkQ2hpbGQuY2hpbGRyZW47XG4gICAgICAgICAgc2hvdWxkUGF0Y2ggPSBmYWxzZTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB1cGRhdGVBdHRyaWJ1dGVzKG5ld0NoaWxkLCBvbGRDaGlsZCk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG5ld0NoaWxkLmRvbSA9IGNyZWF0ZURvbUVsZW1lbnQobmV3Q2hpbGQudGFnLCBuZXdDaGlsZC5pc1NWRyk7XG4gICAgICAgIHVwZGF0ZUF0dHJpYnV0ZXMobmV3Q2hpbGQpO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBjdXJyZW50Tm9kZSA9IGNoaWxkTm9kZXNbaV07XG4gICAgICBpZiAoIWN1cnJlbnROb2RlKSB7XG4gICAgICAgIG5ld1Zub2RlLmRvbS5hcHBlbmRDaGlsZChuZXdDaGlsZC5kb20pO1xuICAgICAgfSBlbHNlIGlmIChjdXJyZW50Tm9kZSAhPT0gbmV3Q2hpbGQuZG9tKSB7XG4gICAgICAgIG5ld1Zub2RlLmRvbS5yZXBsYWNlQ2hpbGQobmV3Q2hpbGQuZG9tLCBjdXJyZW50Tm9kZSk7XG4gICAgICB9XG5cbiAgICAgIHNob3VsZFBhdGNoICYmIHBhdGNoKG5ld0NoaWxkLCBvbGRDaGlsZCk7XG4gICAgfVxuXG4gICAgLy8gUmVtb3ZlIG5vZGVzIHRoYXQgZG9uJ3QgZXhpc3QgaW4gbmV3VHJlZVxuICAgIGZvciAobGV0IGkgPSBuZXdUcmVlTGVuZ3RoOyBpIDwgb2xkVHJlZUxlbmd0aDsgaSsrKSB7XG4gICAgICBpZiAoIW5ld0tleWVkTGlzdFtvbGRUcmVlW2ldLnByb3BzLmtleV0pIHtcbiAgICAgICAgY29uc3QgZG9tVG9SZW1vdmUgPSBvbGRUcmVlW2ldLmRvbTtcbiAgICAgICAgZG9tVG9SZW1vdmUucGFyZW50Tm9kZSAmJiBkb21Ub1JlbW92ZS5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKGRvbVRvUmVtb3ZlKTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgLy8gUGF0Y2ggdGhlIHRoZSBvbGQgdHJlZVxuICBmb3IgKGxldCBpID0gMDsgaSA8IG5ld1RyZWVMZW5ndGg7IGkrKykge1xuICAgIGNvbnN0IG5ld0NoaWxkID0gbmV3VHJlZVtpXTtcbiAgICBjb25zdCBvbGRDaGlsZCA9IG9sZFRyZWVbaV07XG4gICAgY29uc3QgaXNHcmVhdGVyVGhhbk9sZFRyZWVMZW5ndGggPSBpID49IG9sZFRyZWVMZW5ndGg7XG5cbiAgICAvLyBIYW5kbGUgdGV4dCBub2Rlc1xuICAgIGlmIChuZXdDaGlsZC50YWcgPT09IHRleHRUYWcpIHtcbiAgICAgIC8vIElmIHRoZXJlJ3Mgbm8gY29ycmVzcG9uZGluZyBvbGQgY2hpbGQgb3IgdGhlIG9sZCBjaGlsZCBpc24ndCBhIHRleHQgbm9kZVxuICAgICAgaWYgKGlzR3JlYXRlclRoYW5PbGRUcmVlTGVuZ3RoIHx8IG9sZENoaWxkLnRhZyAhPT0gdGV4dFRhZykge1xuICAgICAgICBuZXdDaGlsZC5kb20gPSBkb2N1bWVudC5jcmVhdGVUZXh0Tm9kZShuZXdDaGlsZC5jaGlsZHJlblswXSk7IC8vIENyZWF0ZSBhIG5ldyB0ZXh0IG5vZGVcbiAgICAgICAgaWYgKGlzR3JlYXRlclRoYW5PbGRUcmVlTGVuZ3RoKSB7XG4gICAgICAgICAgLy8gSWYgdGhlcmUncyBubyBjb3JyZXNwb25kaW5nIG9sZCBjaGlsZCwgYXBwZW5kIHRoZSBuZXcgdGV4dCBub2RlXG4gICAgICAgICAgbmV3Vm5vZGUuZG9tLmFwcGVuZENoaWxkKG5ld0NoaWxkLmRvbSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gUmVwbGFjZSB0aGUgb2xkIG5vbi10ZXh0IG5vZGUgd2l0aCB0aGUgbmV3IHRleHQgbm9kZVxuICAgICAgICAgIG5ld1Zub2RlLmRvbS5yZXBsYWNlQ2hpbGQobmV3Q2hpbGQuZG9tLCBvbGRDaGlsZC5kb20pO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBVcGRhdGUgdGhlIG9sZCB0ZXh0IG5vZGUgaWYgY29udGVudCBoYXMgY2hhbmdlZFxuICAgICAgICBuZXdDaGlsZC5kb20gPSBvbGRDaGlsZC5kb207XG4gICAgICAgIGlmIChuZXdDaGlsZC5jaGlsZHJlblswXSAhPT0gb2xkQ2hpbGQuZG9tLnRleHRDb250ZW50KSB7XG4gICAgICAgICAgb2xkQ2hpbGQuZG9tLnRleHRDb250ZW50ID0gbmV3Q2hpbGQuY2hpbGRyZW5bMF07XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIC8vIElmIHRoZSBuZXcgY2hpbGQgaXMgbm90IGEgdGV4dCBub2RlXG4gICAgLy8gU2V0IHRoZSBpc1NWRyBmbGFnIGZvciB0aGUgbmV3IGNoaWxkIGlmIGl0IGlzIGFuIFNWRyBlbGVtZW50IG9yIGlmIHRoZSBwYXJlbnQgaXMgYW4gU1ZHIGVsZW1lbnRcbiAgICBuZXdDaGlsZC5pc1NWRyA9IG5ld1Zub2RlLmlzU1ZHIHx8IG5ld0NoaWxkLnRhZyA9PT0gXCJzdmdcIjtcblxuICAgIC8vIElmIHRoZSB0YWcgb2YgdGhlIG5ldyBjaGlsZCBpcyBkaWZmZXJlbnQgZnJvbSB0aGUgdGFnIG9mIHRoZSBvbGQgY2hpbGRcbiAgICBpZiAoaXNHcmVhdGVyVGhhbk9sZFRyZWVMZW5ndGggfHwgbmV3Q2hpbGQudGFnICE9PSBvbGRDaGlsZC50YWcpIHtcbiAgICAgIC8vIENyZWF0ZSBhIG5ldyBkb20gZWxlbWVudCBmb3IgdGhlIG5ldyBjaGlsZFxuICAgICAgbmV3Q2hpbGQuZG9tID0gY3JlYXRlRG9tRWxlbWVudChuZXdDaGlsZC50YWcgYXMgc3RyaW5nLCBuZXdDaGlsZC5pc1NWRyk7XG4gICAgICAvLyBVcGRhdGUgdGhlIGF0dHJpYnV0ZXMgb2YgdGhlIG5ldyBjaGlsZFxuICAgICAgdXBkYXRlQXR0cmlidXRlcyhuZXdDaGlsZCBhcyBWbm9kZVdpdGhEb20pO1xuICAgICAgaWYgKGlzR3JlYXRlclRoYW5PbGRUcmVlTGVuZ3RoKSB7XG4gICAgICAgIC8vIEFwcGVuZCB0aGUgbmV3IGNoaWxkIHRvIHRoZSBkb21cbiAgICAgICAgbmV3Vm5vZGUuZG9tLmFwcGVuZENoaWxkKG5ld0NoaWxkLmRvbSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBSZXBsYWNlIHRoZSBvbGQgY2hpbGQgaW4gdGhlIGRvbSB3aXRoIHRoZSBuZXcgY2hpbGRcbiAgICAgICAgbmV3Vm5vZGUuZG9tLnJlcGxhY2VDaGlsZChuZXdDaGlsZC5kb20sIG9sZENoaWxkLmRvbSk7XG4gICAgICB9XG4gICAgICAvLyBSZWN1cnNpdmVseSBwYXRjaCB0aGUgbmV3IGNoaWxkXG4gICAgICBwYXRjaChuZXdDaGlsZCBhcyBWbm9kZVdpdGhEb20pO1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgLy8gSWYgdGhlIHRhZyBvZiB0aGUgbmV3IGNoaWxkIGlzIHRoZSBzYW1lIGFzIHRoZSB0YWcgb2YgdGhlIG9sZCBjaGlsZFxuICAgIC8vIFNldCB0aGUgZG9tIHByb3BlcnR5IG9mIHRoZSBuZXcgY2hpbGQgdG8gdGhlIGRvbSBwcm9wZXJ0eSBvZiB0aGUgb2xkIGNoaWxkXG4gICAgbmV3Q2hpbGQuZG9tID0gb2xkQ2hpbGQuZG9tO1xuICAgIC8vIElmIHRoZSB2LWtlZXAgcHJvcCBpcyB0aGUgc2FtZSBmb3IgYm90aCB0aGUgbmV3IGFuZCBvbGQgY2hpbGQsIHNldCB0aGUgY2hpbGRyZW4gb2YgdGhlIG5ldyBjaGlsZCB0byB0aGUgY2hpbGRyZW4gb2YgdGhlIG9sZCBjaGlsZFxuICAgIGlmIChcInYta2VlcFwiIGluIG5ld0NoaWxkLnByb3BzICYmIG5ld0NoaWxkLnByb3BzW1widi1rZWVwXCJdID09PSBvbGRDaGlsZC5wcm9wc1tcInYta2VlcFwiXSkge1xuICAgICAgbmV3Q2hpbGQuY2hpbGRyZW4gPSBvbGRDaGlsZC5jaGlsZHJlbjtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIC8vIFVwZGF0ZSB0aGUgYXR0cmlidXRlcyBvZiB0aGUgbmV3IGNoaWxkIGJhc2VkIG9uIHRoZSBvbGQgY2hpbGRcbiAgICB1cGRhdGVBdHRyaWJ1dGVzKG5ld0NoaWxkIGFzIFZub2RlV2l0aERvbSwgb2xkQ2hpbGQpO1xuICAgIC8vIFJlY3Vyc2l2ZWx5IHBhdGNoIHRoZSBuZXcgYW5kIG9sZCBjaGlsZHJlblxuICAgIHBhdGNoKG5ld0NoaWxkIGFzIFZub2RlV2l0aERvbSwgb2xkQ2hpbGQpO1xuICB9XG5cbiAgLy8gUmVtb3ZlIGFueSBvbGQgY2hpbGRyZW4gdGhhdCBhcmUgbm8gbG9uZ2VyIHByZXNlbnQgaW4gdGhlIG5ldyB0cmVlXG4gIGZvciAoOyBuZXdUcmVlTGVuZ3RoIDwgb2xkVHJlZUxlbmd0aDsgbmV3VHJlZUxlbmd0aCsrKSB7XG4gICAgbmV3Vm5vZGUuZG9tLnJlbW92ZUNoaWxkKG9sZFRyZWVbbmV3VHJlZUxlbmd0aF0uZG9tKTtcbiAgfVxufVxuXG4vLyBVcGRhdGUgdGhlIG1haW4gVm5vZGVcbmV4cG9ydCBmdW5jdGlvbiB1cGRhdGUoKTogdm9pZCB8IHN0cmluZyB7XG4gIC8vIElmIHRoZSBtYWluIFZub2RlIGV4aXN0c1xuICBpZiAobWFpblZub2RlKSB7XG4gICAgLy8gQ2FsbCBhbnkgY2xlYW51cCBmdW5jdGlvbnMgdGhhdCBhcmUgcmVnaXN0ZXJlZCB3aXRoIHRoZSBvbkNsZWFudXBTZXQgc2V0XG4gICAgY2FsbFNldChvbkNsZWFudXBTZXQpO1xuICAgIC8vIFN0b3JlIGEgcmVmZXJlbmNlIHRvIHRoZSBvbGQgbWFpbiBWbm9kZVxuICAgIGNvbnN0IG9sZE1haW5Wbm9kZSA9IG1haW5Wbm9kZTtcbiAgICAvLyBDcmVhdGUgYSBuZXcgbWFpbiBWbm9kZSB3aXRoIHRoZSBtYWluIGNvbXBvbmVudCBhcyBpdHMgb25seSBjaGlsZFxuICAgIG1haW5Wbm9kZSA9IG5ldyBWbm9kZShvbGRNYWluVm5vZGUudGFnLCBvbGRNYWluVm5vZGUucHJvcHMsIFttYWluQ29tcG9uZW50XSkgYXMgVm5vZGVXaXRoRG9tO1xuICAgIG1haW5Wbm9kZS5kb20gPSBvbGRNYWluVm5vZGUuZG9tO1xuICAgIG1haW5Wbm9kZS5pc1NWRyA9IG9sZE1haW5Wbm9kZS5pc1NWRztcblxuICAgIC8vIFJlY3Vyc2l2ZWx5IHBhdGNoIHRoZSBuZXcgYW5kIG9sZCBtYWluIFZub2Rlc1xuICAgIHBhdGNoKG1haW5Wbm9kZSwgb2xkTWFpblZub2RlKTtcblxuICAgIC8vIENhbGwgYW55IHVwZGF0ZSBvciBtb3VudCBmdW5jdGlvbnMgdGhhdCBhcmUgcmVnaXN0ZXJlZCB3aXRoIHRoZSBvblVwZGF0ZVNldCBvciBvbk1vdW50U2V0IHNldFxuICAgIGNhbGxTZXQoaXNNb3VudGVkID8gb25VcGRhdGVTZXQgOiBvbk1vdW50U2V0KTtcblxuICAgIC8vIFNldCB0aGUgaXNNb3VudGVkIGZsYWcgdG8gdHJ1ZVxuICAgIGlzTW91bnRlZCA9IHRydWU7XG5cbiAgICAvLyBSZXNldCB0aGUgY3VycmVudCB2bm9kZSwgb2xkVm5vZGUsIGFuZCBjb21wb25lbnQgcHJvcGVydGllc1xuICAgIGN1cnJlbnQudm5vZGUgPSBudWxsO1xuICAgIGN1cnJlbnQub2xkVm5vZGUgPSBudWxsO1xuICAgIGN1cnJlbnQuY29tcG9uZW50ID0gbnVsbDtcblxuICAgIC8vIElmIHRoZSBjb2RlIGlzIHJ1bm5pbmcgaW4gYSBOb2RlLmpzIGVudmlyb25tZW50LCByZXR1cm4gdGhlIGlubmVyIEhUTUwgb2YgdGhlIG1haW4gVm5vZGUncyBkb20gZWxlbWVudFxuICAgIGlmIChpc05vZGVKcykge1xuICAgICAgcmV0dXJuIG1haW5Wbm9kZS5kb20uaW5uZXJIVE1MO1xuICAgIH1cbiAgfVxufVxuXG4vLyBVcGRhdGUgY3VzdG9tIFZub2RlXG4vLyBJdCBpcyBhc3N1bWVkIHRoYXQgYSBmaXJzdCBtb3VudCBoYXMgYWxyZWFkeSBvY2N1cnJlZCwgc28sXG4vLyB0aGUgb2xkVm5vZGUgaXMgbm90IG51bGwgYW5kIHRoZSBkb20gcHJvcGVydHkgb2YgdGhlIG9sZFZub2RlIGlzIG5vdCBudWxsXG4vLyBZb3UgbmVlZCB0byBzZXQgdGhlIGRvbSBwcm9wZXJ0eSBvZiB0aGUgbmV3Vm5vZGUgdG8gdGhlIGRvbSBwcm9wZXJ0eSBvZiB0aGUgb2xkVm5vZGVcbi8vIFRoZSBzYW1lIHdpdGggdGhlIGlzU1ZHIHByb3BlcnR5XG4vLyBQcmVmZXIgdGhpcyBmdW5jdGlvbiBvdmVyIHBhdGNoIHRvIGFsbG93IGZvciBjbGVhbnVwLCBvblVwZGF0ZSBhbmQgb25Nb3VudCBzZXRzIHRvIGJlIGNhbGxlZFxuZXhwb3J0IGZ1bmN0aW9uIHVwZGF0ZVZub2RlKHZub2RlOiBWbm9kZVdpdGhEb20sIG9sZFZub2RlOiBWbm9kZVdpdGhEb20pOiBzdHJpbmcgfCB2b2lkIHtcbiAgLy8gQ2FsbCBhbnkgY2xlYW51cCBmdW5jdGlvbnMgdGhhdCBhcmUgcmVnaXN0ZXJlZCB3aXRoIHRoZSBvbkNsZWFudXBTZXQgc2V0XG4gIGNhbGxTZXQob25DbGVhbnVwU2V0KTtcblxuICAvLyBSZWN1cnNpdmVseSBwYXRjaCB0aGUgbmV3IGFuZCBvbGQgbWFpbiBWbm9kZXNcbiAgcGF0Y2godm5vZGUsIG9sZFZub2RlKTtcblxuICAvLyBTZXQgdGhlIG9sZFZub2RlJ3MgdGFnLCBwcm9wcywgY2hpbGRyZW4sIGRvbSwgYW5kIGlzU1ZHIHByb3BlcnRpZXMgdG8gdGhlIG5ld1Zub2RlJ3MgdGFnLCBwcm9wcywgY2hpbGRyZW4sIGRvbSwgYW5kIGlzU1ZHIHByb3BlcnRpZXNcbiAgLy8gVGhpcyBpcyBuZWNlc3NhcnkgdG8gYWxsb3cgZm9yIHRoZSBvbGRWbm9kZSB0byBiZSB1c2VkIGFzIHRoZSBuZXdWbm9kZSBpbiB0aGUgbmV4dCB1cGRhdGUgd2l0aCB0aGUgbm9ybWFsIHVwZGF0ZSBmdW5jdGlvblxuICBvbGRWbm9kZS50YWcgPSB2bm9kZS50YWc7XG4gIG9sZFZub2RlLnByb3BzID0geyAuLi52bm9kZS5wcm9wcyB9O1xuICBvbGRWbm9kZS5jaGlsZHJlbiA9IFsuLi52bm9kZS5jaGlsZHJlbl07XG4gIG9sZFZub2RlLmRvbSA9IHZub2RlLmRvbTtcbiAgb2xkVm5vZGUuaXNTVkcgPSB2bm9kZS5pc1NWRztcblxuICAvLyBDYWxsIGFueSB1cGRhdGUgb3IgbW91bnQgZnVuY3Rpb25zIHRoYXQgYXJlIHJlZ2lzdGVyZWQgd2l0aCB0aGUgb25VcGRhdGVTZXQgb3Igb25Nb3VudFNldCBzZXRcbiAgY2FsbFNldChpc01vdW50ZWQgPyBvblVwZGF0ZVNldCA6IG9uTW91bnRTZXQpO1xuXG4gIC8vIFNldCB0aGUgaXNNb3VudGVkIGZsYWcgdG8gdHJ1ZVxuICBpc01vdW50ZWQgPSB0cnVlO1xuXG4gIC8vIFJlc2V0IHRoZSBjdXJyZW50IHZub2RlLCBvbGRWbm9kZSwgYW5kIGNvbXBvbmVudCBwcm9wZXJ0aWVzXG4gIGN1cnJlbnQudm5vZGUgPSBudWxsO1xuICBjdXJyZW50Lm9sZFZub2RlID0gbnVsbDtcbiAgY3VycmVudC5jb21wb25lbnQgPSBudWxsO1xuXG4gIGlmIChpc05vZGVKcykge1xuICAgIHJldHVybiB2bm9kZS5kb20uaW5uZXJIVE1MO1xuICB9XG59XG5cbi8vIFVubW91bnQgdGhlIG1haW4gVm5vZGVcbmV4cG9ydCBmdW5jdGlvbiB1bm1vdW50KCkge1xuICAvLyBJZiB0aGUgbWFpbiBWbm9kZSBleGlzdHNcbiAgaWYgKG1haW5Wbm9kZSkge1xuICAgIC8vIFNldCB0aGUgbWFpbiBjb21wb25lbnQgdG8gYSBudWxsIFZub2RlXG4gICAgbWFpbkNvbXBvbmVudCA9IG5ldyBWbm9kZSgoKSA9PiBudWxsLCB7fSwgW10pIGFzIFZub2RlQ29tcG9uZW50SW50ZXJmYWNlO1xuICAgIC8vIFVwZGF0ZSB0aGUgbWFpbiBWbm9kZVxuICAgIGNvbnN0IHJlc3VsdCA9IHVwZGF0ZSgpO1xuICAgIC8vIENhbGwgYW55IHVubW91bnQgZnVuY3Rpb25zIHRoYXQgYXJlIHJlZ2lzdGVyZWQgd2l0aCB0aGUgb25Vbm1vdW50U2V0IHNldFxuICAgIGNhbGxTZXQob25Vbm1vdW50U2V0KTtcblxuICAgIC8vIFJlbW92ZSBhbnkgZXZlbnQgbGlzdGVuZXJzIHRoYXQgd2VyZSBhZGRlZCB0byB0aGUgbWFpbiBWbm9kZSdzIGRvbSBlbGVtZW50XG4gICAgZm9yIChjb25zdCBuYW1lIGluIGV2ZW50TGlzdGVuZXJOYW1lcykge1xuICAgICAgbWFpblZub2RlLmRvbS5yZW1vdmVFdmVudExpc3RlbmVyKG5hbWUuc2xpY2UoMikudG9Mb3dlckNhc2UoKSwgZXZlbnRMaXN0ZW5lcik7XG4gICAgICBSZWZsZWN0LmRlbGV0ZVByb3BlcnR5KGV2ZW50TGlzdGVuZXJOYW1lcywgbmFtZSk7XG4gICAgfVxuXG4gICAgLy8gUmVzZXQgdGhlIG1haW4gY29tcG9uZW50IGFuZCBtYWluIFZub2RlXG4gICAgbWFpbkNvbXBvbmVudCA9IG51bGw7XG4gICAgbWFpblZub2RlID0gbnVsbDtcbiAgICAvLyBTZXQgdGhlIGlzTW91bnRlZCBmbGFnIHRvIGZhbHNlXG4gICAgaXNNb3VudGVkID0gZmFsc2U7XG4gICAgLy8gUmVzZXQgdGhlIGN1cnJlbnQgdm5vZGUsIG9sZFZub2RlLCBhbmQgY29tcG9uZW50IHByb3BlcnRpZXNcbiAgICBjdXJyZW50LnZub2RlID0gbnVsbDtcbiAgICBjdXJyZW50Lm9sZFZub2RlID0gbnVsbDtcbiAgICBjdXJyZW50LmNvbXBvbmVudCA9IG51bGw7XG4gICAgLy8gUmV0dXJuIHRoZSByZXN1bHQgb2YgdXBkYXRpbmcgdGhlIG1haW4gVm5vZGVcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG59XG4vLyBUaGlzIGZ1bmN0aW9uIHRha2VzIGluIGEgRE9NIGVsZW1lbnQgb3IgYSBET00gZWxlbWVudCBzZWxlY3RvciBhbmQgYSBjb21wb25lbnQgdG8gYmUgbW91bnRlZCBvbiBpdC5cbmV4cG9ydCBmdW5jdGlvbiBtb3VudChkb206IHN0cmluZyB8IERvbUVsZW1lbnQsIGNvbXBvbmVudDogYW55KSB7XG4gIC8vIENoZWNrIGlmIHRoZSAnZG9tJyBhcmd1bWVudCBpcyBhIHN0cmluZy4gSWYgaXQgaXMsIHNlbGVjdCB0aGUgZmlyc3QgZWxlbWVudCB0aGF0IG1hdGNoZXMgdGhlIGdpdmVuIHNlbGVjdG9yLlxuICAvLyBPdGhlcndpc2UsIHVzZSB0aGUgJ2RvbScgYXJndW1lbnQgYXMgdGhlIGNvbnRhaW5lci5cbiAgY29uc3QgY29udGFpbmVyID1cbiAgICB0eXBlb2YgZG9tID09PSBcInN0cmluZ1wiXG4gICAgICA/IGlzTm9kZUpzXG4gICAgICAgID8gY3JlYXRlRG9tRWxlbWVudChkb20sIGRvbSA9PT0gXCJzdmdcIilcbiAgICAgICAgOiBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKGRvbSlbMF1cbiAgICAgIDogZG9tO1xuXG4gIC8vIENoZWNrIGlmIHRoZSAnY29tcG9uZW50JyBhcmd1bWVudCBpcyBhIFZub2RlIGNvbXBvbmVudCBvciBhIHJlZ3VsYXIgY29tcG9uZW50LlxuICAvLyBJZiBpdCdzIGEgcmVndWxhciBjb21wb25lbnQsIGNyZWF0ZSBhIG5ldyBWbm9kZSBjb21wb25lbnQgdXNpbmcgdGhlICdjb21wb25lbnQnIGFyZ3VtZW50IGFzIHRoZSB0YWcuXG4gIC8vIElmIGl0J3Mgbm90IGEgY29tcG9uZW50IGF0IGFsbCwgY3JlYXRlIGEgbmV3IFZub2RlIGNvbXBvbmVudCB3aXRoIHRoZSAnY29tcG9uZW50JyBhcmd1bWVudCBhcyB0aGUgcmVuZGVyaW5nIGZ1bmN0aW9uLlxuICBjb25zdCB2bm9kZUNvbXBvbmVudCA9IGlzVm5vZGVDb21wb25lbnQoY29tcG9uZW50KVxuICAgID8gY29tcG9uZW50XG4gICAgOiBpc0NvbXBvbmVudChjb21wb25lbnQpXG4gICAgPyBuZXcgVm5vZGUoY29tcG9uZW50LCB7fSwgW10pXG4gICAgOiBuZXcgVm5vZGUoKCkgPT4gY29tcG9uZW50LCB7fSwgW10pO1xuXG4gIC8vIElmIGEgbWFpbiBjb21wb25lbnQgYWxyZWFkeSBleGlzdHMgYW5kIGl0J3Mgbm90IHRoZSBzYW1lIGFzIHRoZSBjdXJyZW50ICd2bm9kZUNvbXBvbmVudCcsIHVubW91bnQgaXQuXG4gIGlmIChtYWluQ29tcG9uZW50ICYmIG1haW5Db21wb25lbnQudGFnICE9PSB2bm9kZUNvbXBvbmVudC50YWcpIHtcbiAgICB1bm1vdW50KCk7XG4gIH1cblxuICAvLyBTZXQgdGhlICd2bm9kZUNvbXBvbmVudCcgYXMgdGhlIG1haW4gY29tcG9uZW50LlxuICBtYWluQ29tcG9uZW50ID0gdm5vZGVDb21wb25lbnQgYXMgVm5vZGVDb21wb25lbnRJbnRlcmZhY2U7XG4gIC8vIENvbnZlcnQgdGhlIGNvbnRhaW5lciBlbGVtZW50IHRvIGEgVm5vZGUuXG4gIG1haW5Wbm9kZSA9IGRvbVRvVm5vZGUoY29udGFpbmVyKTtcbiAgLy8gVXBkYXRlIHRoZSBET00gd2l0aCB0aGUgbmV3IGNvbXBvbmVudC5cbiAgcmV0dXJuIHVwZGF0ZSgpO1xufVxuXG4vLyBUaGlzIGlzIGEgdXRpbGl0eSBmdW5jdGlvbiBmb3IgY3JlYXRpbmcgVm5vZGUgb2JqZWN0cy5cbi8vIEl0IHRha2VzIGluIGEgdGFnIG9yIGNvbXBvbmVudCwgYW5kIG9wdGlvbmFsIHByb3BzIGFuZCBjaGlsZHJlbiBhcmd1bWVudHMuXG5leHBvcnQgY29uc3QgdjogViA9ICh0YWdPckNvbXBvbmVudCwgcHJvcHMsIC4uLmNoaWxkcmVuKSA9PiB7XG4gIC8vIFJldHVybiBhIG5ldyBWbm9kZSBvYmplY3QgdXNpbmcgdGhlIGdpdmVuIGFyZ3VtZW50cy5cbiAgcmV0dXJuIG5ldyBWbm9kZSh0YWdPckNvbXBvbmVudCwgcHJvcHMgfHwge30sIGNoaWxkcmVuKTtcbn07XG5cbi8vIFRoaXMgdXRpbGl0eSBmdW5jdGlvbiBjcmVhdGVzIGEgZnJhZ21lbnQgVm5vZGUuXG4vLyBJdCB0YWtlcyBpbiBhIHBsYWNlaG9sZGVyIGFuZCB0aGUgY2hpbGRyZW4gYXJndW1lbnRzLCByZXR1cm5zIG9ubHkgdGhlIGNoaWxkcmVuLlxudi5mcmFnbWVudCA9IChfOiBWbm9kZVByb3BlcnRpZXMsIC4uLmNoaWxkcmVuOiBDaGlsZHJlbikgPT4gY2hpbGRyZW47XG4iXSwibWFwcGluZ3MiOiJNQXVIQSxJQUFNQSxFQUFVLFFBSUhDLEVBQVdDLFFBQTJCLG9CQUFaQyxTQUEyQkEsUUFBUUMsVUFBWUQsUUFBUUMsU0FBU0MsTUFJaEcsU0FBU0MsRUFBaUJDLEVBQWFDLEdBQWlCLEdBQzdELE9BQU9BLEVBQVFDLFNBQVNDLGdCQUFnQiw2QkFBOEJILEdBQU9FLFNBQVNFLGNBQWNKLEVBQ3RHLENBTU8sSUFBTUssRUFBUSxTQUFxQ0wsRUFBYU0sRUFBd0JDLEdBRTdGQyxLQUFLUixJQUFNQSxFQUNYUSxLQUFLRixNQUFRQSxFQUNiRSxLQUFLRCxTQUFXQSxDQUNsQixFQUlPLFNBQVNFLEVBQVlDLEdBQzFCLE9BQU9mLFFBQ0xlLElBQW1DLG1CQUFkQSxHQUFrRCxpQkFBZEEsR0FBMEIsU0FBVUEsR0FFakcsQ0FHTyxJQUFNQyxFQUFXQyxHQUVmQSxhQUFrQlAsRUFLZFEsRUFBb0JELEdBRXhCRCxFQUFRQyxJQUFXSCxFQUFZRyxFQUFPWixLQUl4QyxTQUFTYyxFQUFXQyxHQUl6QixHQUFxQixJQUFqQkEsRUFBSUMsU0FBZ0IsQ0FDdEIsTUFBTUMsRUFBUSxJQUFJWixFQUFNWixFQUFTLENBQUMsRUFBRyxDQUFDc0IsRUFBSUcsWUFFMUMsT0FEQUQsRUFBTUYsSUFBTUEsRUFDTEUsQ0FDVCxDQUVBLE1BQU1WLEVBQTJCLEdBRWpD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 \ No newline at end of file +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJpc05vZGVKcyIsIkJvb2xlYW4iLCJwcm9jZXNzIiwidmVyc2lvbnMiLCJub2RlIiwiY3JlYXRlRG9tRWxlbWVudCIsInRhZyIsImlzU1ZHIiwiZG9jdW1lbnQiLCJjcmVhdGVFbGVtZW50TlMiLCJjcmVhdGVFbGVtZW50IiwiVm5vZGUiLCJwcm9wcyIsImNoaWxkcmVuIiwidGhpcyIsImlzQ29tcG9uZW50IiwiY29tcG9uZW50IiwiaXNWbm9kZSIsIm9iamVjdCIsImlzVm5vZGVDb21wb25lbnQiLCJkb21Ub1Zub2RlIiwiZG9tIiwibm9kZVR5cGUiLCJub2RlVmFsdWUiLCJpIiwibCIsImNoaWxkTm9kZXMiLCJsZW5ndGgiLCJjaGlsZERvbSIsInB1c2giLCJhdHRyaWJ1dGVzIiwiYXR0ciIsIm5vZGVOYW1lIiwidm5vZGUiLCJ0YWdOYW1lIiwidG9Mb3dlckNhc2UiLCJ0cnVzdCIsImh0bWxTdHJpbmciLCJkaXYiLCJpbm5lckhUTUwiLCJ0cmltIiwibWFwIiwiY2FsbCIsIml0ZW0iLCJtYWluQ29tcG9uZW50IiwibWFpblZub2RlIiwiaXNNb3VudGVkIiwiY3VycmVudCIsIm9sZFZub2RlIiwiZXZlbnQiLCJyZXNlcnZlZFByb3BzIiwia2V5Iiwic3RhdGUiLCJvbkNsZWFudXBTZXQiLCJTZXQiLCJvbk1vdW50U2V0Iiwib25VcGRhdGVTZXQiLCJvblVubW91bnRTZXQiLCJvbkNsZWFudXAiLCJjYWxsYmFjayIsImFkZCIsImNhbGxTZXQiLCJzZXQiLCJjbGVhciIsImV2ZW50TGlzdGVuZXJOYW1lcyIsImV2ZW50TGlzdGVuZXIiLCJlIiwidGFyZ2V0IiwibmFtZSIsInR5cGUiLCJkZWZhdWx0UHJldmVudGVkIiwidXBkYXRlIiwicGFyZW50Tm9kZSIsImhpZGVEaXJlY3RpdmUiLCJ0ZXN0IiwiYm9vbCIsIm9sZG5vZGUiLCJuZXdkb20iLCJjcmVhdGVUZXh0Tm9kZSIsInJlcGxhY2VDaGlsZCIsImRpcmVjdGl2ZXMiLCJuZXdDaGlsZHJlbiIsInN0eWxlIiwiZGlzcGxheSIsImNsYXNzZXMiLCJjbGFzc0xpc3QiLCJ0b2dnbGUiLCJodG1sIiwibW9kZWwiLCJwcm9wZXJ0eSIsInZhbHVlIiwiaGFuZGxlciIsIkFycmF5IiwiaXNBcnJheSIsInZhbCIsImlkeCIsImluZGV4T2YiLCJzcGxpY2UiLCJzaGFyZWRTZXRBdHRyaWJ1dGUiLCJtdWx0aXBsZSIsImN0cmxLZXkiLCJmb3JFYWNoIiwiY2hpbGQiLCJqb2luIiwic2VsZWN0ZWQiLCJwcmV2SGFuZGxlciIsImNsZWFudXAiLCJuZXdWbm9kZSIsImFkZEV2ZW50TGlzdGVuZXIiLCJzbGljZSIsInJlbW92ZUF0dHJpYnV0ZSIsInNldEF0dHJpYnV0ZSIsInVwZGF0ZUF0dHJpYnV0ZXMiLCJwYXRjaCIsInRleHRDb250ZW50IiwibmV3VHJlZSIsIm9sZFRyZWUiLCJvbGRUcmVlTGVuZ3RoIiwibmV3VHJlZUxlbmd0aCIsIm5ld0NoaWxkIiwidmlldyIsImJpbmQiLCJvbGRLZXllZExpc3QiLCJuZXdLZXllZExpc3QiLCJvbGRDaGlsZCIsInNob3VsZFBhdGNoIiwiY3VycmVudE5vZGUiLCJhcHBlbmRDaGlsZCIsImRvbVRvUmVtb3ZlIiwicmVtb3ZlQ2hpbGQiLCJpc0dyZWF0ZXJUaGFuT2xkVHJlZUxlbmd0aCIsIm9sZE1haW5Wbm9kZSIsInVubW91bnQiLCJyZXN1bHQiLCJyZW1vdmVFdmVudExpc3RlbmVyIiwiUmVmbGVjdCIsImRlbGV0ZVByb3BlcnR5IiwidiIsInRhZ09yQ29tcG9uZW50IiwiZnJhZ21lbnQiLCJfIiwiZGlyZWN0aXZlIiwiZGlyZWN0aXZlTmFtZSIsImNvbnRhaW5lciIsInF1ZXJ5U2VsZWN0b3JBbGwiLCJ2bm9kZUNvbXBvbmVudCJdLCJzb3VyY2VzIjpbIi4uL2xpYi9pbmRleC50cyJdLCJzb3VyY2VzQ29udGVudCI6WyIvKiBlc2xpbnQtZGlzYWJsZSBuby11c2UtYmVmb3JlLWRlZmluZSAqL1xuLyogZXNsaW50LWRpc2FibGUgaW5kZW50ICovXG4vKiBlc2xpbnQtZGlzYWJsZSBzb25hcmpzL2NvZ25pdGl2ZS1jb21wbGV4aXR5ICovXG4vKiBlc2xpbnQtZGlzYWJsZSBjb21wbGV4aXR5ICovXG5cbmludGVyZmFjZSBEZWZhdWx0UmVjb3JkIGV4dGVuZHMgUmVjb3JkPHN0cmluZyB8IG51bWJlciB8IHN5bWJvbCwgYW55PiB7fVxuXG4vLyBUaGUgVm5vZGVQcm9wZXJ0aWVzIGludGVyZmFjZSByZXByZXNlbnRzIHByb3BlcnRpZXMgdGhhdCBjYW4gYmUgcGFzc2VkIHRvIGEgdmlydHVhbCBub2RlLlxuZXhwb3J0IGludGVyZmFjZSBWbm9kZVByb3BlcnRpZXMgZXh0ZW5kcyBEZWZhdWx0UmVjb3JkIHtcbiAgLy8gQSB1bmlxdWUga2V5IGZvciB0aGUgdmlydHVhbCBub2RlLCB3aGljaCBjYW4gYmUgYSBzdHJpbmcgb3IgYSBudW1iZXIuXG4gIC8vIFRoaXMgaXMgdXNlZnVsIGZvciBvcHRpbWl6aW5nIHVwZGF0ZXMgaW4gYSBsaXN0IG9mIG5vZGVzLlxuICBrZXk/OiBzdHJpbmcgfCBudW1iZXI7XG4gIC8vIEEgc3RhdGUgb2JqZWN0IHRoYXQgaXMgYXNzb2NpYXRlZCB3aXRoIHRoZSB2aXJ0dWFsIG5vZGUuXG4gIHN0YXRlPzogYW55O1xufVxuXG4vLyBUaGUgRG9tRWxlbWVudCBpbnRlcmZhY2UgZXh0ZW5kcyB0aGUgRWxlbWVudCBpbnRlcmZhY2Ugd2l0aCBhbiBpbmRleCBzaWduYXR1cmUuXG4vLyBUaGlzIGFsbG93cyBmb3IgYW55IGFkZGl0aW9uYWwgcHJvcGVydGllcyB0byBiZSBhZGRlZCB0byBET00gZWxlbWVudHMuXG5leHBvcnQgaW50ZXJmYWNlIERvbUVsZW1lbnQgZXh0ZW5kcyBFbGVtZW50LCBEZWZhdWx0UmVjb3JkIHt9XG5cbi8vIFRoZSBWbm9kZUludGVyZmFjZSByZXByZXNlbnRzIGEgdmlydHVhbCBub2RlLiBJdCBoYXMgYSBudW1iZXIgb2Ygb3B0aW9uYWwgZmllbGRzLFxuLy8gaW5jbHVkaW5nIGEgdGFnLCBwcm9wcywgY2hpbGRyZW4sIGFuZCBhIERPTSBlbGVtZW50LlxuZXhwb3J0IGludGVyZmFjZSBWbm9kZUludGVyZmFjZSBleHRlbmRzIERlZmF1bHRSZWNvcmQge1xuICAvLyBUaGUgY29uc3RydWN0b3IgZm9yIHRoZSB2aXJ0dWFsIG5vZGUuIEl0IHRha2VzIGEgdGFnLCBwcm9wcywgYW5kIGNoaWxkcmVuIGFzIGFyZ3VtZW50cy5cbiAgLy8gVGhlIHRhZyBjYW4gYmUgYSBzdHJpbmcsIGEgY29tcG9uZW50LCBvciBhIFBPSk8gY29tcG9uZW50LlxuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tdW51c2VkLXZhcnNcbiAgbmV3ICh0YWc6IHN0cmluZyB8IENvbXBvbmVudCB8IFBPSk9Db21wb25lbnQsIHByb3BzOiBWbm9kZVByb3BlcnRpZXMsIGNoaWxkcmVuOiBDaGlsZHJlbik6IFZub2RlSW50ZXJmYWNlO1xuICAvLyBUaGUgdGFnIGZvciB0aGUgdmlydHVhbCBub2RlLiBJdCBjYW4gYmUgYSBzdHJpbmcsIGEgY29tcG9uZW50LCBvciBhIFBPSk8gY29tcG9uZW50LlxuICB0YWc6IHN0cmluZyB8IENvbXBvbmVudCB8IFBPSk9Db21wb25lbnQ7XG4gIC8vIFRoZSBwcm9wcyBmb3IgdGhlIHZpcnR1YWwgbm9kZS5cbiAgcHJvcHM6IFZub2RlUHJvcGVydGllcztcbiAgLy8gVGhlIGNoaWxkcmVuIGZvciB0aGUgdmlydHVhbCBub2RlLlxuICBjaGlsZHJlbjogQ2hpbGRyZW47XG4gIC8vIEEgYm9vbGVhbiBpbmRpY2F0aW5nIHdoZXRoZXIgdGhlIHZpcnR1YWwgbm9kZSBpcyBhbiBTVkcgZWxlbWVudC5cbiAgaXNTVkc/OiBib29sZWFuO1xuICAvLyBUaGUgRE9NIGVsZW1lbnQgdGhhdCBjb3JyZXNwb25kcyB0byB0aGUgdmlydHVhbCBub2RlLlxuICBkb20/OiBEb21FbGVtZW50O1xuICAvLyBBIGJvb2xlYW4gaW5kaWNhdGluZyB3aGV0aGVyIHRoZSB2aXJ0dWFsIG5vZGUgaGFzIGJlZW4gcHJvY2Vzc2VkIGluIHRoZSBrZXllZCBkaWZmaW5nIGFsZ29yaXRobS5cbiAgcHJvY2Vzc2VkPzogYm9vbGVhbjtcbn1cblxuLy8gVGhlIFZub2RlV2l0aERvbSBpbnRlcmZhY2UgcmVwcmVzZW50cyBhIHZpcnR1YWwgbm9kZSB0aGF0IGhhcyBhIERPTSBlbGVtZW50IGFzc29jaWF0ZWQgd2l0aCBpdC5cbmV4cG9ydCBpbnRlcmZhY2UgVm5vZGVXaXRoRG9tIGV4dGVuZHMgVm5vZGVJbnRlcmZhY2Uge1xuICBkb206IERvbUVsZW1lbnQ7XG59XG5cbi8vIFRoZSBDb21wb25lbnQgaW50ZXJmYWNlIHJlcHJlc2VudHMgYSBmdW5jdGlvbiB0aGF0IHJldHVybnMgYSB2aXJ0dWFsIG5vZGUgb3IgYSBsaXN0IG9mIHZpcnR1YWwgbm9kZXMuXG4vLyBJdCBjYW4gYWxzbyBoYXZlIGFkZGl0aW9uYWwgcHJvcGVydGllcy5cbmV4cG9ydCBpbnRlcmZhY2UgQ29tcG9uZW50IGV4dGVuZHMgRGVmYXVsdFJlY29yZCB7XG4gIC8vIFRoZSBmdW5jdGlvbiB0aGF0IHJldHVybnMgYSB2aXJ0dWFsIG5vZGUgb3IgYSBsaXN0IG9mIHZpcnR1YWwgbm9kZXMuXG4gIC8vIEl0IGNhbiB0YWtlIHByb3BzIGFuZCBjaGlsZHJlbiBhcyBhcmd1bWVudHMuXG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby11bnVzZWQtdmFyc1xuICAocHJvcHM/OiBWbm9kZVByb3BlcnRpZXMgfCBudWxsLCAuLi5jaGlsZHJlbjogYW55W10pOiBWbm9kZUludGVyZmFjZSB8IENoaWxkcmVuIHwgYW55O1xufVxuXG4vLyBUaGUgUE9KT0NvbXBvbmVudCBpbnRlcmZhY2UgcmVwcmVzZW50cyBhIFwicGxhaW4gb2xkIEphdmFTY3JpcHQgb2JqZWN0XCIgKFBPSk8pIGNvbXBvbmVudC5cbi8vIEl0IGhhcyBhIHZpZXcgZnVuY3Rpb24gdGhhdCByZXR1cm5zIGEgdmlydHVhbCBub2RlIG9yIGEgbGlzdCBvZiB2aXJ0dWFsIG5vZGVzLFxuLy8gYXMgd2VsbCBhcyBvcHRpb25hbCBwcm9wcyBhbmQgY2hpbGRyZW4uXG4vLyBJdCBjYW4gYmUgdXNlZCBhbHNvIHRvIGlkZW50aWZ5IGNsYXNzIGluc3RhbmNlIGNvbXBvbmVudHMuXG5leHBvcnQgaW50ZXJmYWNlIFBPSk9Db21wb25lbnQgZXh0ZW5kcyBEZWZhdWx0UmVjb3JkIHtcbiAgLy8gVGhlIHZpZXcgZnVuY3Rpb24gdGhhdCByZXR1cm5zIGEgdmlydHVhbCBub2RlIG9yIGEgbGlzdCBvZiB2aXJ0dWFsIG5vZGVzLlxuICB2aWV3OiBDb21wb25lbnQ7XG4gIC8vIFRoZSBwcm9wcyBmb3IgdGhlIGNvbXBvbmVudC5cbiAgcHJvcHM/OiBWbm9kZVByb3BlcnRpZXMgfCBudWxsO1xuICAvLyBUaGUgY2hpbGRyZW4gZm9yIHRoZSBjb21wb25lbnQuXG4gIGNoaWxkcmVuPzogYW55W107XG59XG5cbi8vIFRoZSBWbm9kZUNvbXBvbmVudEludGVyZmFjZSByZXByZXNlbnRzIGEgdmlydHVhbCBub2RlIHRoYXQgaGFzIGEgY29tcG9uZW50IGFzIGl0cyB0YWcuXG4vLyBJdCBoYXMgcHJvcHMgYW5kIGNoaWxkcmVuLCBqdXN0IGxpa2UgYSByZWd1bGFyIHZpcnR1YWwgbm9kZS5cbmV4cG9ydCBpbnRlcmZhY2UgVm5vZGVDb21wb25lbnRJbnRlcmZhY2UgZXh0ZW5kcyBWbm9kZUludGVyZmFjZSB7XG4gIHRhZzogQ29tcG9uZW50IHwgUE9KT0NvbXBvbmVudDtcbiAgcHJvcHM6IFZub2RlUHJvcGVydGllcztcbiAgY2hpbGRyZW46IENoaWxkcmVuO1xufVxuXG4vLyBUaGUgQ2hpbGRyZW4gaW50ZXJmYWNlIHJlcHJlc2VudHMgYSBsaXN0IG9mIHZpcnR1YWwgbm9kZXMgb3Igb3RoZXIgdmFsdWVzLlxuZXhwb3J0IGludGVyZmFjZSBDaGlsZHJlbiBleHRlbmRzIEFycmF5PFZub2RlSW50ZXJmYWNlIHwgVm5vZGVDb21wb25lbnRJbnRlcmZhY2UgfCBhbnk+IHt9XG5cbi8vIFRoZSBEaXJlY3RpdmUgaW50ZXJmYWNlIHJlcHJlc2VudHMgYSBmdW5jdGlvbiB0aGF0IGNhbiBiZSBhcHBsaWVkIHRvIGEgdmlydHVhbCBub2RlLlxuLy8gSXQgcmVjZWl2ZXMgdGhlIHZhbHVlLCB2aXJ0dWFsIG5vZGUsIGFuZCBvbGQgdmlydHVhbCBub2RlIGFzIGFyZ3VtZW50cywgYW5kIGNhbiByZXR1cm4gYSBib29sZWFuIHZhbHVlLlxuLy8gSWYgb25seSB0aGUgdmlydHVhbCBub2RlIGlzIHBhc3NlZCwgaXQgbWVhbnMgaXRzIHRoZSBvbiBjcmVhdGUgcGhhc2UgZm9yIHRoZSB2LW5vZGUuXG4vLyBJZiB0aGUgb2xkIHZpcnR1YWwgbm9kZSBpcyBhbHNvIHBhc3NlZCwgaXQgbWVhbnMgaXRzIHRoZSBvbiB1cGRhdGUgcGhhc2UgZm9yIHRoZSB2LW5vZGUuXG5leHBvcnQgaW50ZXJmYWNlIERpcmVjdGl2ZSB7XG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby11bnVzZWQtdmFyc1xuICAodmFsdWU6IGFueSwgdm5vZGU6IFZub2RlV2l0aERvbSwgb2xkVm5vZGU/OiBWbm9kZVdpdGhEb20pOiB2b2lkIHwgYm9vbGVhbjtcbn1cblxuLy8gVGhlIERpcmVjdGl2ZXMgaW50ZXJmYWNlIGlzIGEgbWFwcGluZyBvZiBkaXJlY3RpdmUgbmFtZXMgdG8gRGlyZWN0aXZlIGZ1bmN0aW9ucy5cbmV4cG9ydCBpbnRlcmZhY2UgRGlyZWN0aXZlcyBleHRlbmRzIFJlY29yZDxzdHJpbmcsIERpcmVjdGl2ZT4ge31cblxuLy8gVGhlIFJlc2VydmVkUHJvcHMgaW50ZXJmYWNlIGlzIGEgbWFwcGluZyBvZiByZXNlcnZlZCBwcm9wIG5hbWVzIHRvIHRoZSB2YWx1ZSBgdHJ1ZWAuXG4vLyBUaGVzZSBwcm9wIG5hbWVzIGNhbm5vdCBiZSB1c2VkIGFzIGN1c3RvbSBwcm9wIG5hbWVzLlxuZXhwb3J0IGludGVyZmFjZSBSZXNlcnZlZFByb3BzIGV4dGVuZHMgUmVjb3JkPHN0cmluZywgdHJ1ZT4ge31cblxuLy8gVGhlIEN1cnJlbnQgaW50ZXJmYWNlIHJlcHJlc2VudHMgdGhlIGN1cnJlbnQgY29tcG9uZW50IGFuZCB2aXJ0dWFsIG5vZGUgdGhhdCBhcmUgYmVpbmcgcHJvY2Vzc2VkLlxuZXhwb3J0IGludGVyZmFjZSBDdXJyZW50IHtcbiAgLy8gVGhlIGN1cnJlbnQgY29tcG9uZW50LiBJdCBjYW4gYmUgYSBjb21wb25lbnQsIGEgUE9KTyBjb21wb25lbnQsIG9yIG51bGwuXG4gIGNvbXBvbmVudDogQ29tcG9uZW50IHwgUE9KT0NvbXBvbmVudCB8IG51bGw7XG4gIC8vIFRoZSBjdXJyZW50IHZpcnR1YWwgbm9kZS4gSXQgbXVzdCBoYXZlIGEgRE9NIGVsZW1lbnQgYXNzb2NpYXRlZCB3aXRoIGl0LlxuICB2bm9kZTogVm5vZGVXaXRoRG9tIHwgbnVsbDtcbiAgLy8gVGhlIG9sZCB2aXJ0dWFsIG5vZGUuIEl0IG11c3QgaGF2ZSBhIERPTSBlbGVtZW50IGFzc29jaWF0ZWQgd2l0aCBpdC5cbiAgb2xkVm5vZGU/OiBWbm9kZVdpdGhEb20gfCBudWxsO1xuICAvLyBUaGUgY3VycmVudCBldmVudC4gSXQgY2FuIGJlIGFuIGV2ZW50IG9yIG51bGwuXG4gIGV2ZW50OiBFdmVudCB8IG51bGw7XG59XG5cbi8vIFRoZSBWIGZ1bmN0aW9uIGlzIHRoZSBtYWluIGZ1bmN0aW9uIGZvciBjcmVhdGluZyB2aXJ0dWFsIG5vZGVzLlxuLy8gSXQgdGFrZXMgYSB0YWcgb3IgY29tcG9uZW50LCBwcm9wcywgYW5kIGNoaWxkcmVuIGFzIGFyZ3VtZW50cywgYW5kIHJldHVybnMgYSB2aXJ0dWFsIG5vZGUuXG5leHBvcnQgaW50ZXJmYWNlIFYge1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tdW51c2VkLXZhcnMsIG5vLXVzZS1iZWZvcmUtZGVmaW5lXG4gICh0YWdPckNvbXBvbmVudDogc3RyaW5nIHwgQ29tcG9uZW50IHwgUE9KT0NvbXBvbmVudCwgcHJvcHM6IFZub2RlUHJvcGVydGllcyB8IG51bGwsIC4uLmNoaWxkcmVuOiBDaGlsZHJlbik6XG4gICAgfCBWbm9kZUludGVyZmFjZVxuICAgIHwgVm5vZGVDb21wb25lbnRJbnRlcmZhY2U7XG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby11bnVzZWQtdmFycywgbm8tdXNlLWJlZm9yZS1kZWZpbmVcbiAgZnJhZ21lbnQoXzogYW55LCAuLi5jaGlsZHJlbjogQ2hpbGRyZW4pOiBDaGlsZHJlbjtcbn1cblxuLy8gJ3RleHRUYWcnIGlzIGEgY29uc3RhbnQgc3RyaW5nIHRoYXQgaXMgdXNlZCB0byByZXByZXNlbnQgdGV4dCBub2RlcyBpbiB0aGUgdmlydHVhbCBET00uXG5jb25zdCB0ZXh0VGFnID0gXCIjdGV4dFwiO1xuXG4vLyAnaXNOb2RlSnMnIGlzIGEgYm9vbGVhbiB0aGF0IGlzIHRydWUgaWYgdGhlIGNvZGUgaXMgcnVubmluZyBpbiBhIE5vZGUuanMgZW52aXJvbm1lbnQgYW5kIGZhbHNlIG90aGVyd2lzZS5cbi8vIEl0IGlzIGRldGVybWluZWQgYnkgY2hlY2tpbmcgaWYgdGhlICdwcm9jZXNzJyBnbG9iYWwgb2JqZWN0IGlzIGRlZmluZWQgYW5kIGhhcyBhICd2ZXJzaW9ucycgcHJvcGVydHkuXG5leHBvcnQgY29uc3QgaXNOb2RlSnMgPSBCb29sZWFuKHR5cGVvZiBwcm9jZXNzICE9PSBcInVuZGVmaW5lZFwiICYmIHByb2Nlc3MudmVyc2lvbnMgJiYgcHJvY2Vzcy52ZXJzaW9ucy5ub2RlKTtcblxuLy8gJ2NyZWF0ZURvbUVsZW1lbnQnIGlzIGEgZnVuY3Rpb24gdGhhdCBjcmVhdGVzIGEgbmV3IERPTSBlbGVtZW50IHdpdGggdGhlIHNwZWNpZmllZCB0YWcgbmFtZS5cbi8vIElmICdpc1NWRycgaXMgdHJ1ZSwgaXQgY3JlYXRlcyBhbiBTVkcgZWxlbWVudCBpbnN0ZWFkIG9mIGEgcmVndWxhciBET00gZWxlbWVudC5cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVEb21FbGVtZW50KHRhZzogc3RyaW5nLCBpc1NWRzogYm9vbGVhbiA9IGZhbHNlKTogRG9tRWxlbWVudCB7XG4gIHJldHVybiBpc1NWRyA/IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUyhcImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIsIHRhZykgOiBkb2N1bWVudC5jcmVhdGVFbGVtZW50KHRhZyk7XG59XG5cbi8vICdWbm9kZScgaXMgYSBjbGFzcyB0aGF0IHJlcHJlc2VudHMgYSB2aXJ0dWFsIERPTSBub2RlLlxuLy8gSXQgaGFzIHRocmVlIHByb3BlcnRpZXM6ICd0YWcnLCAncHJvcHMnLCBhbmQgJ2NoaWxkcmVuJy5cbi8vICdWbm9kZScgaXMgZXhwb3J0ZWQgYXMgYW4gb2JqZWN0IHdpdGggYSB0eXBlIG9mICdWbm9kZUludGVyZmFjZScuXG4vLyBUaGUgJ2FzIHVua25vd24gYXMgVm5vZGVJbnRlcmZhY2UnIGlzIHVzZWQgdG8gdGVsbCBUeXBlU2NyaXB0IHRoYXQgdGhlICdWbm9kZScgZnVuY3Rpb24gaGFzIHRoZSBzYW1lIHR5cGUgYXMgJ1Zub2RlSW50ZXJmYWNlJy5cbmV4cG9ydCBjb25zdCBWbm9kZSA9IGZ1bmN0aW9uIFZub2RlKHRoaXM6IFZub2RlSW50ZXJmYWNlLCB0YWc6IHN0cmluZywgcHJvcHM6IFZub2RlUHJvcGVydGllcywgY2hpbGRyZW46IENoaWxkcmVuKSB7XG4gIC8vICd0aGlzJyByZWZlcnMgdG8gdGhlIGN1cnJlbnQgaW5zdGFuY2Ugb2YgJ1Zub2RlJy5cbiAgdGhpcy50YWcgPSB0YWc7XG4gIHRoaXMucHJvcHMgPSBwcm9wcztcbiAgdGhpcy5jaGlsZHJlbiA9IGNoaWxkcmVuO1xufSBhcyB1bmtub3duIGFzIFZub2RlSW50ZXJmYWNlO1xuXG4vLyAnaXNDb21wb25lbnQnIGlzIGEgZnVuY3Rpb24gdGhhdCByZXR1cm5zIHRydWUgaWYgdGhlIGdpdmVuICdjb21wb25lbnQnIGlzIGEgdmFsaWQgY29tcG9uZW50IGFuZCBmYWxzZSBvdGhlcndpc2UuXG4vLyBBIGNvbXBvbmVudCBpcyBlaXRoZXIgYSBmdW5jdGlvbiBvciBhbiBvYmplY3Qgd2l0aCBhICd2aWV3JyBmdW5jdGlvbi5cbmV4cG9ydCBmdW5jdGlvbiBpc0NvbXBvbmVudChjb21wb25lbnQ6IHVua25vd24pOiBjb21wb25lbnQgaXMgQ29tcG9uZW50IHtcbiAgcmV0dXJuIEJvb2xlYW4oXG4gICAgY29tcG9uZW50ICYmICh0eXBlb2YgY29tcG9uZW50ID09PSBcImZ1bmN0aW9uXCIgfHwgKHR5cGVvZiBjb21wb25lbnQgPT09IFwib2JqZWN0XCIgJiYgXCJ2aWV3XCIgaW4gY29tcG9uZW50KSlcbiAgKTtcbn1cblxuLy8gJ2lzVm5vZGUnIGlzIGEgZnVuY3Rpb24gdGhhdCByZXR1cm5zIHRydWUgaWYgdGhlIGdpdmVuICdvYmplY3QnIGlzIGEgJ1Zub2RlJyBpbnN0YW5jZSBhbmQgZmFsc2Ugb3RoZXJ3aXNlLlxuZXhwb3J0IGNvbnN0IGlzVm5vZGUgPSAob2JqZWN0PzogdW5rbm93biB8IFZub2RlSW50ZXJmYWNlKTogb2JqZWN0IGlzIFZub2RlSW50ZXJmYWNlID0+IHtcbiAgLy8gVXNlIHRoZSAnaW5zdGFuY2VvZicgb3BlcmF0b3IgdG8gY2hlY2sgaWYgJ29iamVjdCcgaXMgYW4gaW5zdGFuY2Ugb2YgJ1Zub2RlJy5cbiAgcmV0dXJuIG9iamVjdCBpbnN0YW5jZW9mIFZub2RlO1xufTtcblxuLy8gJ2lzVm5vZGVDb21wb25lbnQnIGlzIGEgZnVuY3Rpb24gdGhhdCByZXR1cm5zIHRydWUgaWYgdGhlIGdpdmVuICdvYmplY3QnIGlzIGEgJ1Zub2RlJyBpbnN0YW5jZSB3aXRoIGEgJ3RhZycgcHJvcGVydHkgdGhhdCBpcyBhIHZhbGlkIGNvbXBvbmVudC5cbi8vIEl0IHJldHVybnMgZmFsc2Ugb3RoZXJ3aXNlLlxuZXhwb3J0IGNvbnN0IGlzVm5vZGVDb21wb25lbnQgPSAob2JqZWN0PzogdW5rbm93biB8IFZub2RlQ29tcG9uZW50SW50ZXJmYWNlKTogb2JqZWN0IGlzIFZub2RlQ29tcG9uZW50SW50ZXJmYWNlID0+IHtcbiAgLy8gQ2hlY2sgaWYgJ29iamVjdCcgaXMgYSAnVm5vZGUnIGluc3RhbmNlIGFuZCBpdHMgJ3RhZycgcHJvcGVydHkgaXMgYSB2YWxpZCBjb21wb25lbnQuXG4gIHJldHVybiBpc1Zub2RlKG9iamVjdCkgJiYgaXNDb21wb25lbnQob2JqZWN0LnRhZyk7XG59O1xuXG4vLyAnZG9tVG9Wbm9kZScgaXMgYSBmdW5jdGlvbiB0aGF0IGNvbnZlcnRzIGEgRE9NIG5vZGUgdG8gYSAnVm5vZGUnIGluc3RhbmNlLlxuZXhwb3J0IGZ1bmN0aW9uIGRvbVRvVm5vZGUoZG9tOiBhbnkpOiBWbm9kZVdpdGhEb20ge1xuICAvLyBJZiB0aGUgY2hpbGQgbm9kZSBpcyBhIHRleHQgbm9kZSwgY3JlYXRlIGEgJ1Zub2RlJyBpbnN0YW5jZSB3aXRoIHRoZSAndGV4dFRhZycgY29uc3RhbnQgYXMgdGhlICd0YWcnIHByb3BlcnR5LlxuICAvLyBTZXQgdGhlICdkb20nIHByb3BlcnR5IG9mIHRoZSAnVm5vZGUnIGluc3RhbmNlIHRvIHRoZSBjaGlsZCBET00gbm9kZS5cbiAgLy8gUHVzaCB0aGUgJ1Zub2RlJyBpbnN0YW5jZSB0byB0aGUgJ2NoaWxkcmVuJyBhcnJheS5cbiAgaWYgKGRvbS5ub2RlVHlwZSA9PT0gMykge1xuICAgIHJldHVybiBkb20ubm9kZVZhbHVlO1xuICB9XG5cbiAgY29uc3QgY2hpbGRyZW46IFZub2RlV2l0aERvbVtdID0gW107XG4gIC8vIEl0ZXJhdGUgdGhyb3VnaCBhbGwgY2hpbGQgbm9kZXMgb2YgJ2RvbScuXG4gIGZvciAobGV0IGkgPSAwLCBsID0gZG9tLmNoaWxkTm9kZXMubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XG4gICAgY29uc3QgY2hpbGREb20gPSBkb20uY2hpbGROb2Rlc1tpXTtcbiAgICAvLyBJZiB0aGUgY2hpbGQgbm9kZSBpcyBhbiBlbGVtZW50IG5vZGUsIHJlY3Vyc2l2ZWx5IGNhbGwgJ2RvbVRvVm5vZGUnIHRvIGNvbnZlcnQgaXQgdG8gYSAnVm5vZGUnIGluc3RhbmNlLlxuICAgIC8vIFB1c2ggdGhlICdWbm9kZScgaW5zdGFuY2UgdG8gdGhlICdjaGlsZHJlbicgYXJyYXkuXG4gICAgaWYgKGNoaWxkRG9tLm5vZGVUeXBlID09PSAzKSB7XG4gICAgICBjaGlsZHJlbi5wdXNoKGNoaWxkRG9tLm5vZGVWYWx1ZSk7XG4gICAgfSBlbHNlIGlmIChjaGlsZERvbS5ub2RlVHlwZSA9PT0gMSkge1xuICAgICAgY2hpbGRyZW4ucHVzaChkb21Ub1Zub2RlKGNoaWxkRG9tKSk7XG4gICAgfVxuICB9XG5cbiAgY29uc3QgcHJvcHM6IFZub2RlUHJvcGVydGllcyA9IHt9O1xuICAvLyBJdGVyYXRlIHRocm91Z2ggYWxsIGF0dHJpYnV0ZXMgb2YgJ2RvbScuXG4gIGZvciAobGV0IGkgPSAwLCBsID0gZG9tLmF0dHJpYnV0ZXMubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XG4gICAgY29uc3QgYXR0ciA9IGRvbS5hdHRyaWJ1dGVzW2ldO1xuICAgIC8vIEFkZCB0aGUgYXR0cmlidXRlIHRvIHRoZSAncHJvcHMnIG9iamVjdCwgdXNpbmcgdGhlIGF0dHJpYnV0ZSdzIG5hbWUgYXMgdGhlIGtleSBhbmQgaXRzIHZhbHVlIGFzIHRoZSB2YWx1ZS5cbiAgICBwcm9wc1thdHRyLm5vZGVOYW1lXSA9IGF0dHIubm9kZVZhbHVlO1xuICB9XG5cbiAgLy8gQ3JlYXRlIGEgbmV3ICdWbm9kZScgaW5zdGFuY2Ugd2l0aCB0aGUgJ3RhZycgcHJvcGVydHkgc2V0IHRvIHRoZSBsb3dlcmNhc2UgdmVyc2lvbiBvZiB0aGUgRE9NIG5vZGUncyB0YWcgbmFtZS5cbiAgLy8gU2V0IHRoZSAncHJvcHMnIGFuZCAnY2hpbGRyZW4nIHByb3BlcnRpZXMgdG8gdGhlICdwcm9wcycgYW5kICdjaGlsZHJlbicgYXJyYXlzIHJlc3BlY3RpdmVseS5cbiAgLy8gU2V0IHRoZSAnZG9tJyBwcm9wZXJ0eSBvZiB0aGUgJ1Zub2RlJyBpbnN0YW5jZSB0byB0aGUgRE9NIG5vZGUuXG4gIGNvbnN0IHZub2RlID0gbmV3IFZub2RlKGRvbS50YWdOYW1lLnRvTG93ZXJDYXNlKCksIHByb3BzLCBjaGlsZHJlbik7XG4gIHZub2RlLmRvbSA9IGRvbTtcbiAgcmV0dXJuIHZub2RlIGFzIFZub2RlV2l0aERvbTtcbn1cblxuLy8gVGhpcyBmdW5jdGlvbiB0YWtlcyBpbiBhbiBIVE1MIHN0cmluZyBhbmQgY3JlYXRlcyBhIHZpcnR1YWwgbm9kZSByZXByZXNlbnRhdGlvbiBvZiBpdFxuLy8gdXNpbmcgdGhlIGBkb21Ub1Zub2RlYCBmdW5jdGlvbi4gSXQgZG9lcyB0aGlzIGJ5IGNyZWF0aW5nIGEgbmV3IGBkaXZgIGVsZW1lbnQsIHNldHRpbmdcbi8vIGl0cyBgaW5uZXJIVE1MYCB0byB0aGUgcHJvdmlkZWQgSFRNTCBzdHJpbmcsIGFuZCB0aGVuIHVzaW5nIGBtYXBgIHRvIGl0ZXJhdGUgb3ZlciB0aGVcbi8vIGBjaGlsZE5vZGVzYCBvZiB0aGUgYGRpdmAgZWxlbWVudCwgcGFzc2luZyBlYWNoIG9uZSB0byBgZG9tVG9Wbm9kZWAgdG8gY3JlYXRlIGEgdmlydHVhbFxuLy8gbm9kZSByZXByZXNlbnRhdGlvbiBvZiBpdC4gVGhlIHJlc3VsdGluZyBhcnJheSBvZiB2aXJ0dWFsIG5vZGVzIGlzIHRoZW4gcmV0dXJuZWQuXG5leHBvcnQgZnVuY3Rpb24gdHJ1c3QoaHRtbFN0cmluZzogc3RyaW5nKSB7XG4gIGNvbnN0IGRpdiA9IGNyZWF0ZURvbUVsZW1lbnQoXCJkaXZcIik7XG4gIGRpdi5pbm5lckhUTUwgPSBodG1sU3RyaW5nLnRyaW0oKTtcblxuICByZXR1cm4gW10ubWFwLmNhbGwoZGl2LmNoaWxkTm9kZXMsIChpdGVtKSA9PiBkb21Ub1Zub2RlKGl0ZW0pKTtcbn1cblxuLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0gKi9cbi8qIE1haW4gQ29tcG9uZW50IGltcGxlbWVudGF0aW9uICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovXG4vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSAqL1xuXG4vLyBUaGVzZSB2YXJpYWJsZXMgYXJlIHVzZWQgdG8gc3RvcmUgdGhlIG1haW4gY29tcG9uZW50LCB0aGUgbWFpbiB2aXJ0dWFsIG5vZGUsIGFuZCB3aGV0aGVyXG4vLyB0aGUgbWFpbiBjb21wb25lbnQgaXMgY3VycmVudGx5IG1vdW50ZWQuXG5sZXQgbWFpbkNvbXBvbmVudDogVm5vZGVDb21wb25lbnRJbnRlcmZhY2UgfCBudWxsID0gbnVsbDtcbmxldCBtYWluVm5vZGU6IFZub2RlV2l0aERvbSB8IG51bGwgPSBudWxsO1xubGV0IGlzTW91bnRlZCA9IGZhbHNlO1xuXG4vLyBUaGlzIG9iamVjdCBpcyB1c2VkIHRvIHN0b3JlIHRoZSBjdXJyZW50IHZpcnR1YWwgbm9kZSBhbmQgY29tcG9uZW50IGJlaW5nIHJlbmRlcmVkLlxuZXhwb3J0IGNvbnN0IGN1cnJlbnQ6IEN1cnJlbnQgPSB7XG4gIHZub2RlOiBudWxsLFxuICBvbGRWbm9kZTogbnVsbCxcbiAgY29tcG9uZW50OiBudWxsLFxuICBldmVudDogbnVsbFxufTtcblxuLyogUmVzZXJ2ZWQgcHJvcHMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi9cbi8vIFRoaXMgb2JqZWN0IGlzIHVzZWQgdG8gc3RvcmUgdGhlIG5hbWVzIG9mIHJlc2VydmVkIHByb3BzLCB3aGljaCBhcmUgcHJvcHMgdGhhdCBhcmUgcmVzZXJ2ZWRcbi8vIGZvciBzcGVjaWFsIHB1cnBvc2VzIGFuZCBzaG91bGQgbm90IGJlIHVzZWQgYXMgcmVndWxhciBjb21wb25lbnQgcHJvcHMuXG5leHBvcnQgY29uc3QgcmVzZXJ2ZWRQcm9wczogUmVjb3JkPHN0cmluZywgdHJ1ZT4gPSB7XG4gIGtleTogdHJ1ZSxcbiAgc3RhdGU6IHRydWUsXG4gIFwidi1rZWVwXCI6IHRydWUsXG5cbiAgLy8gQnVpbHQgaW4gZGlyZWN0aXZlc1xuICBcInYtaWZcIjogdHJ1ZSxcbiAgXCJ2LXVubGVzc1wiOiB0cnVlLFxuICBcInYtZm9yXCI6IHRydWUsXG4gIFwidi1zaG93XCI6IHRydWUsXG4gIFwidi1jbGFzc1wiOiB0cnVlLFxuICBcInYtaHRtbFwiOiB0cnVlLFxuICBcInYtbW9kZWxcIjogdHJ1ZSxcbiAgXCJ2LWNyZWF0ZVwiOiB0cnVlLFxuICBcInYtdXBkYXRlXCI6IHRydWUsXG4gIFwidi1jbGVhbnVwXCI6IHRydWVcbn07XG5cbi8qIE1vdW50aW5nLCBVcGRhdGluZywgQ2xlYW51cCBhbmQgVW5tb3VudGluZyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovXG4vLyBUaGVzZSBzZXRzIGFyZSB1c2VkIHRvIHN0b3JlIGNhbGxiYWNrcyBmb3IgdmFyaW91cyBsaWZlY3ljbGUgZXZlbnRzOiBtb3VudGluZywgdXBkYXRpbmcsXG4vLyBjbGVhbmluZyB1cCwgYW5kIHVubW91bnRpbmcuXG5jb25zdCBvbkNsZWFudXBTZXQ6IFNldDxGdW5jdGlvbj4gPSBuZXcgU2V0KCk7XG5jb25zdCBvbk1vdW50U2V0OiBTZXQ8RnVuY3Rpb24+ID0gbmV3IFNldCgpO1xuY29uc3Qgb25VcGRhdGVTZXQ6IFNldDxGdW5jdGlvbj4gPSBuZXcgU2V0KCk7XG5jb25zdCBvblVubW91bnRTZXQ6IFNldDxGdW5jdGlvbj4gPSBuZXcgU2V0KCk7XG5cbi8vIFRoZXNlIGZ1bmN0aW9ucyBhbGxvdyB1c2VycyB0byByZWdpc3RlciBjYWxsYmFja3MgZm9yIHRoZSBjb3JyZXNwb25kaW5nIGxpZmVjeWNsZSBldmVudHMuXG5leHBvcnQgZnVuY3Rpb24gb25Nb3VudChjYWxsYmFjazogRnVuY3Rpb24pIHtcbiAgaWYgKCFpc01vdW50ZWQpIHtcbiAgICBvbk1vdW50U2V0LmFkZChjYWxsYmFjayk7XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIG9uVXBkYXRlKGNhbGxiYWNrOiBGdW5jdGlvbikge1xuICBvblVwZGF0ZVNldC5hZGQoY2FsbGJhY2spO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gb25DbGVhbnVwKGNhbGxiYWNrOiBGdW5jdGlvbikge1xuICBvbkNsZWFudXBTZXQuYWRkKGNhbGxiYWNrKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIG9uVW5tb3VudChjYWxsYmFjazogRnVuY3Rpb24pIHtcbiAgaWYgKCFpc01vdW50ZWQpIHtcbiAgICBvblVubW91bnRTZXQuYWRkKGNhbGxiYWNrKTtcbiAgfVxufVxuXG4vLyBUaGlzIGZ1bmN0aW9uIGlzIHVzZWQgdG8gY2FsbCBhbGwgdGhlIGNhbGxiYWNrcyBpbiBhIGdpdmVuIHNldC5cbmZ1bmN0aW9uIGNhbGxTZXQoc2V0OiBTZXQ8RnVuY3Rpb24+KSB7XG4gIGZvciAoY29uc3QgY2FsbGJhY2sgb2Ygc2V0KSB7XG4gICAgY2FsbGJhY2soKTtcbiAgfVxuXG4gIHNldC5jbGVhcigpO1xufVxuXG4vKiBFdmVudCBsaXN0ZW5lciAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqL1xuXG4vLyBUaGlzIG9iamVjdCBzdG9yZXMgdGhlIG5hbWVzIG9mIGV2ZW50IGxpc3RlbmVycyB0aGF0IGhhdmUgYmVlbiBhZGRlZFxuY29uc3QgZXZlbnRMaXN0ZW5lck5hbWVzOiBSZWNvcmQ8c3RyaW5nLCB0cnVlPiA9IHt9O1xuXG4vLyBUaGlzIGZ1bmN0aW9uIGlzIGNhbGxlZCB3aGVuIGFuIGV2ZW50IG9jY3Vyc1xuZnVuY3Rpb24gZXZlbnRMaXN0ZW5lcihlOiBFdmVudCkge1xuICAvLyBTZXQgdGhlIGN1cnJlbnQgZXZlbnQgdG8gdGhlIGV2ZW50IHRoYXQgb2NjdXJyZWQgc28gdGhhdCBpdCBjYW4gYmUgcHJldmVudGVkIGlmIG5lY2Vzc2FyeVxuICBjdXJyZW50LmV2ZW50ID0gZTtcblxuICAvLyBDb252ZXJ0IHRoZSB0YXJnZXQgb2YgdGhlIGV2ZW50IHRvIGEgRE9NIGVsZW1lbnRcbiAgbGV0IGRvbSA9IGUudGFyZ2V0IGFzIERvbUVsZW1lbnQ7XG5cbiAgLy8gQ3JlYXRlIHRoZSBuYW1lIG9mIHRoZSBldmVudCBsaXN0ZW5lciBieSBhZGRpbmcgXCJ2LW9uXCIgdG8gdGhlIGV2ZW50IHR5cGVcbiAgY29uc3QgbmFtZSA9IGB2LW9uJHtlLnR5cGV9YDtcblxuICAvLyBLZWVwIGdvaW5nIHVwIHRoZSBET00gdHJlZSB1bnRpbCB3ZSBmaW5kIGFuIGVsZW1lbnQgd2l0aCBhbiBldmVudCBsaXN0ZW5lclxuICAvLyBtYXRjaGluZyB0aGUgZXZlbnQgdHlwZVxuICB3aGlsZSAoZG9tKSB7XG4gICAgaWYgKGRvbVtuYW1lXSkge1xuICAgICAgLy8gQ2FsbCB0aGUgZXZlbnQgbGlzdGVuZXIgZnVuY3Rpb25cbiAgICAgIGRvbVtuYW1lXShlLCBkb20pO1xuXG4gICAgICAvLyBJZiB0aGUgZGVmYXVsdCBhY3Rpb24gb2YgdGhlIGV2ZW50IGhhc24ndCBiZWVuIHByZXZlbnRlZCwgdXBkYXRlIHRoZSBET01cbiAgICAgIGlmICghZS5kZWZhdWx0UHJldmVudGVkKSB7XG4gICAgICAgIHVwZGF0ZSgpO1xuICAgICAgfVxuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBkb20gPSBkb20ucGFyZW50Tm9kZSBhcyBEb21FbGVtZW50O1xuICB9XG5cbiAgY3VycmVudC5ldmVudCA9IG51bGw7XG59XG5cbi8qIERpcmVjdGl2ZXMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovXG5cbi8vIFRoaXMgZnVuY3Rpb24gY3JlYXRlcyBhIGRpcmVjdGl2ZSB0aGF0IGhpZGVzIGFuIGVsZW1lbnQgYmFzZWQgb24gYSBjb25kaXRpb25cbmNvbnN0IGhpZGVEaXJlY3RpdmUgPSAodGVzdDogYm9vbGVhbikgPT4gKGJvb2w6IGJvb2xlYW4sIHZub2RlOiBWbm9kZVdpdGhEb20sIG9sZG5vZGU/OiBWbm9kZUludGVyZmFjZSkgPT4ge1xuICAvLyBJZiB0ZXN0IGlzIHRydWUsIHVzZSB0aGUgdmFsdWUgb2YgYm9vbC4gT3RoZXJ3aXNlLCB1c2UgdGhlIG9wcG9zaXRlIG9mIGJvb2wuXG4gIGNvbnN0IHZhbHVlID0gdGVzdCA/IGJvb2wgOiAhYm9vbDtcblxuICAvLyBJZiB0aGUgdmFsdWUgaXMgdHJ1ZSwgaGlkZSB0aGUgZWxlbWVudCBieSByZXBsYWNpbmcgaXQgd2l0aCBhIHRleHQgbm9kZVxuICBpZiAodmFsdWUpIHtcbiAgICBjb25zdCBwYXJlbnROb2RlID0gdm5vZGUuZG9tPy5wYXJlbnROb2RlO1xuICAgIGlmIChwYXJlbnROb2RlKSB7XG4gICAgICBjb25zdCBuZXdkb20gPSBkb2N1bWVudC5jcmVhdGVUZXh0Tm9kZShcIlwiKTtcbiAgICAgIHBhcmVudE5vZGUucmVwbGFjZUNoaWxkKG5ld2RvbSwgdm5vZGUuZG9tKTtcbiAgICB9XG5cbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbn07XG5cbi8vIFRoaXMgb2JqZWN0IHN0b3JlcyBhbGwgdGhlIGF2YWlsYWJsZSBkaXJlY3RpdmVzXG5leHBvcnQgY29uc3QgZGlyZWN0aXZlczogRGlyZWN0aXZlcyA9IHtcbiAgLy8gVGhlIFwidi1pZlwiIGRpcmVjdGl2ZSBoaWRlcyBhbiBlbGVtZW50IGlmIHRoZSBnaXZlbiBjb25kaXRpb24gaXMgZmFsc2VcbiAgXCJ2LWlmXCI6IGhpZGVEaXJlY3RpdmUoZmFsc2UpLFxuXG4gIC8vIFRoZSBcInYtdW5sZXNzXCIgZGlyZWN0aXZlIGhpZGVzIGFuIGVsZW1lbnQgaWYgdGhlIGdpdmVuIGNvbmRpdGlvbiBpcyB0cnVlXG4gIFwidi11bmxlc3NcIjogaGlkZURpcmVjdGl2ZSh0cnVlKSxcblxuICAvLyBUaGUgXCJ2LWZvclwiIGRpcmVjdGl2ZSBjcmVhdGVzIGEgbG9vcCBhbmQgYXBwbGllcyBhIGNhbGxiYWNrIGZ1bmN0aW9uIHRvIGVhY2ggaXRlbSBpbiB0aGUgbG9vcFxuICBcInYtZm9yXCI6IChzZXQ6IHVua25vd25bXSwgdm5vZGU6IFZub2RlV2l0aERvbSkgPT4ge1xuICAgIGNvbnN0IG5ld0NoaWxkcmVuOiBWbm9kZUludGVyZmFjZVtdID0gW107XG4gICAgY29uc3QgY2FsbGJhY2sgPSB2bm9kZS5jaGlsZHJlblswXTtcbiAgICBmb3IgKGxldCBpID0gMCwgbCA9IHNldC5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICAgIG5ld0NoaWxkcmVuLnB1c2goY2FsbGJhY2soc2V0W2ldLCBpKSk7XG4gICAgfVxuICAgIHZub2RlLmNoaWxkcmVuID0gbmV3Q2hpbGRyZW47XG4gIH0sXG5cbiAgLy8gVGhlIFwidi1zaG93XCIgZGlyZWN0aXZlIHNob3dzIG9yIGhpZGVzIGFuIGVsZW1lbnQgYnkgc2V0dGluZyB0aGUgXCJkaXNwbGF5XCIgc3R5bGUgcHJvcGVydHlcbiAgXCJ2LXNob3dcIjogKGJvb2w6IGJvb2xlYW4sIHZub2RlOiBWbm9kZVdpdGhEb20pID0+IHtcbiAgICAoXG4gICAgICB2bm9kZS5kb20gYXMgdW5rbm93biBhcyB7XG4gICAgICAgIHN0eWxlOiB7IGRpc3BsYXk6IHN0cmluZyB9O1xuICAgICAgfVxuICAgICkuc3R5bGUuZGlzcGxheSA9IGJvb2wgPyBcIlwiIDogXCJub25lXCI7XG4gIH0sXG5cbiAgLy8gVGhlIFwidi1jbGFzc1wiIGRpcmVjdGl2ZSBhZGRzIG9yIHJlbW92ZXMgY2xhc3MgbmFtZXMgZnJvbSBhbiBlbGVtZW50IGJhc2VkIG9uIGEgY29uZGl0aW9uXG4gIFwidi1jbGFzc1wiOiAoY2xhc3NlczogeyBbeDogc3RyaW5nXTogYm9vbGVhbiB9LCB2bm9kZTogVm5vZGVXaXRoRG9tKSA9PiB7XG4gICAgLy8gTG9vcCB0aHJvdWdoIGFsbCB0aGUgY2xhc3MgbmFtZXMgaW4gdGhlIGNsYXNzZXMgb2JqZWN0XG4gICAgZm9yIChjb25zdCBuYW1lIGluIGNsYXNzZXMpIHtcbiAgICAgIC8vIEFkZCBvciByZW1vdmUgdGhlIGNsYXNzIG5hbWUgZnJvbSB0aGUgZWxlbWVudCdzIGNsYXNzIGxpc3QgYmFzZWQgb24gdGhlIHZhbHVlIGluIHRoZSBjbGFzc2VzIG9iamVjdFxuICAgICAgKHZub2RlLmRvbSBhcyBEb21FbGVtZW50KS5jbGFzc0xpc3QudG9nZ2xlKG5hbWUsIGNsYXNzZXNbbmFtZV0pO1xuICAgIH1cbiAgfSxcblxuICAvLyBUaGUgXCJ2LWh0bWxcIiBkaXJlY3RpdmUgc2V0cyB0aGUgaW5uZXIgSFRNTCBvZiBhbiBlbGVtZW50IHRvIHRoZSBnaXZlbiBIVE1MIHN0cmluZ1xuICBcInYtaHRtbFwiOiAoaHRtbDogc3RyaW5nLCB2bm9kZTogVm5vZGVXaXRoRG9tKSA9PiB7XG4gICAgLy8gU2V0IHRoZSBjaGlsZHJlbiBvZiB0aGUgdm5vZGUgdG8gYSB0cnVzdGVkIHZlcnNpb24gb2YgdGhlIEhUTUwgc3RyaW5nXG4gICAgdm5vZGUuY2hpbGRyZW4gPSBbdHJ1c3QoaHRtbCldO1xuICB9LFxuXG4gIC8vIFRoZSBcInYtbW9kZWxcIiBkaXJlY3RpdmUgYmluZHMgdGhlIHZhbHVlIG9mIGFuIGlucHV0IGVsZW1lbnQgdG8gYSBtb2RlbCBwcm9wZXJ0eVxuICBcInYtbW9kZWxcIjogKFttb2RlbCwgcHJvcGVydHksIGV2ZW50XTogYW55W10sIHZub2RlOiBWbm9kZVdpdGhEb20sIG9sZFZub2RlPzogVm5vZGVXaXRoRG9tKSA9PiB7XG4gICAgbGV0IHZhbHVlO1xuICAgIC8vIFRoaXMgZnVuY3Rpb24gdXBkYXRlcyB0aGUgbW9kZWwgcHJvcGVydHkgd2hlbiB0aGUgaW5wdXQgZWxlbWVudCdzIHZhbHVlIGNoYW5nZXNcbiAgICBsZXQgaGFuZGxlciA9IChlOiBFdmVudCkgPT4gKG1vZGVsW3Byb3BlcnR5XSA9IChlLnRhcmdldCBhcyBEb21FbGVtZW50ICYgUmVjb3JkPHN0cmluZywgYW55PikudmFsdWUpO1xuICAgIGlmICh2bm9kZS50YWcgPT09IFwiaW5wdXRcIikge1xuICAgICAgLy8gSWYgdGhlIGVsZW1lbnQgaXMgYW4gaW5wdXQsIHVzZSB0aGUgXCJpbnB1dFwiIGV2ZW50IGJ5IGRlZmF1bHRcbiAgICAgIGV2ZW50ID0gZXZlbnQgfHwgXCJvbmlucHV0XCI7XG4gICAgICAvLyBEZXBlbmRpbmcgb24gdGhlIHR5cGUgb2YgaW5wdXQgZWxlbWVudCwgdXNlIGEgZGlmZmVyZW50IGhhbmRsZXIgZnVuY3Rpb25cbiAgICAgIHN3aXRjaCAodm5vZGUucHJvcHMudHlwZSkge1xuICAgICAgICBjYXNlIFwiY2hlY2tib3hcIjoge1xuICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KG1vZGVsW3Byb3BlcnR5XSkpIHtcbiAgICAgICAgICAgIC8vIElmIHRoZSBtb2RlbCBwcm9wZXJ0eSBpcyBhbiBhcnJheSwgYWRkIG9yIHJlbW92ZSB0aGUgdmFsdWUgZnJvbSB0aGUgYXJyYXkgd2hlbiB0aGUgY2hlY2tib3ggaXMgY2hlY2tlZCBvciB1bmNoZWNrZWRcbiAgICAgICAgICAgIGhhbmRsZXIgPSAoZTogRXZlbnQpID0+IHtcbiAgICAgICAgICAgICAgY29uc3QgdmFsID0gKGUudGFyZ2V0IGFzIERvbUVsZW1lbnQgJiBSZWNvcmQ8c3RyaW5nLCBhbnk+KS52YWx1ZTtcbiAgICAgICAgICAgICAgY29uc3QgaWR4ID0gbW9kZWxbcHJvcGVydHldLmluZGV4T2YodmFsKTtcbiAgICAgICAgICAgICAgaWYgKGlkeCA9PT0gLTEpIHtcbiAgICAgICAgICAgICAgICBtb2RlbFtwcm9wZXJ0eV0ucHVzaCh2YWwpO1xuICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIG1vZGVsW3Byb3BlcnR5XS5zcGxpY2UoaWR4LCAxKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIC8vIElmIHRoZSB2YWx1ZSBpcyBpbiB0aGUgYXJyYXksIHNldCB0aGUgY2hlY2tib3ggdG8gYmUgY2hlY2tlZFxuICAgICAgICAgICAgdmFsdWUgPSBtb2RlbFtwcm9wZXJ0eV0uaW5kZXhPZih2bm9kZS5kb20udmFsdWUpICE9PSAtMTtcbiAgICAgICAgICB9IGVsc2UgaWYgKFwidmFsdWVcIiBpbiB2bm9kZS5wcm9wcykge1xuICAgICAgICAgICAgLy8gSWYgdGhlIGlucHV0IGVsZW1lbnQgaGFzIGEgXCJ2YWx1ZVwiIGF0dHJpYnV0ZSwgdXNlIGl0IHRvIGRldGVybWluZSB0aGUgY2hlY2tlZCBzdGF0ZVxuICAgICAgICAgICAgaGFuZGxlciA9ICgpID0+IHtcbiAgICAgICAgICAgICAgaWYgKG1vZGVsW3Byb3BlcnR5XSA9PT0gdm5vZGUucHJvcHMudmFsdWUpIHtcbiAgICAgICAgICAgICAgICBtb2RlbFtwcm9wZXJ0eV0gPSBudWxsO1xuICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIG1vZGVsW3Byb3BlcnR5XSA9IHZub2RlLnByb3BzLnZhbHVlO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgdmFsdWUgPSBtb2RlbFtwcm9wZXJ0eV0gPT09IHZub2RlLnByb3BzLnZhbHVlO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBJZiB0aGVyZSBpcyBubyBcInZhbHVlXCIgYXR0cmlidXRlLCB1c2UgYSBib29sZWFuIHZhbHVlIGZvciB0aGUgbW9kZWwgcHJvcGVydHlcbiAgICAgICAgICAgIGhhbmRsZXIgPSAoKSA9PiAobW9kZWxbcHJvcGVydHldID0gIW1vZGVsW3Byb3BlcnR5XSk7XG4gICAgICAgICAgICB2YWx1ZSA9IG1vZGVsW3Byb3BlcnR5XTtcbiAgICAgICAgICB9XG4gICAgICAgICAgLy8gU2V0IHRoZSBcImNoZWNrZWRcIiBhdHRyaWJ1dGUgb24gdGhlIGlucHV0IGVsZW1lbnRcbiAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tdXNlLWJlZm9yZS1kZWZpbmVcbiAgICAgICAgICBzaGFyZWRTZXRBdHRyaWJ1dGUoXCJjaGVja2VkXCIsIHZhbHVlLCB2bm9kZSk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgY2FzZSBcInJhZGlvXCI6IHtcbiAgICAgICAgICAvLyBJZiB0aGUgZWxlbWVudCBpcyBhIHJhZGlvIGJ1dHRvbiwgc2V0IHRoZSBcImNoZWNrZWRcIiBhdHRyaWJ1dGUgYmFzZWQgb24gdGhlIHZhbHVlIG9mIHRoZSBtb2RlbCBwcm9wZXJ0eVxuICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby11c2UtYmVmb3JlLWRlZmluZVxuICAgICAgICAgIHNoYXJlZFNldEF0dHJpYnV0ZShcImNoZWNrZWRcIiwgbW9kZWxbcHJvcGVydHldID09PSB2bm9kZS5kb20udmFsdWUsIHZub2RlKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICBkZWZhdWx0OiB7XG4gICAgICAgICAgLy8gRm9yIGFsbCBvdGhlciBpbnB1dCB0eXBlcywgc2V0IHRoZSBcInZhbHVlXCIgYXR0cmlidXRlIGJhc2VkIG9uIHRoZSB2YWx1ZSBvZiB0aGUgbW9kZWwgcHJvcGVydHlcbiAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tdXNlLWJlZm9yZS1kZWZpbmVcbiAgICAgICAgICBzaGFyZWRTZXRBdHRyaWJ1dGUoXCJ2YWx1ZVwiLCBtb2RlbFtwcm9wZXJ0eV0sIHZub2RlKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSBpZiAodm5vZGUudGFnID09PSBcInNlbGVjdFwiKSB7XG4gICAgICAvLyBJZiB0aGUgZWxlbWVudCBpcyBhIHNlbGVjdCBlbGVtZW50LCB1c2UgdGhlIFwiY2xpY2tcIiBldmVudCBieSBkZWZhdWx0XG4gICAgICBldmVudCA9IGV2ZW50IHx8IFwib25jbGlja1wiO1xuICAgICAgaWYgKHZub2RlLnByb3BzLm11bHRpcGxlKSB7XG4gICAgICAgIC8vIElmIHRoZSBzZWxlY3QgZWxlbWVudCBhbGxvd3MgbXVsdGlwbGUgc2VsZWN0aW9ucywgdXBkYXRlIHRoZSBtb2RlbCBwcm9wZXJ0eSB3aXRoIGFuIGFycmF5IG9mIHNlbGVjdGVkIHZhbHVlc1xuICAgICAgICBoYW5kbGVyID0gKGU6IEV2ZW50ICYgUmVjb3JkPHN0cmluZywgYW55PikgPT4ge1xuICAgICAgICAgIGNvbnN0IHZhbCA9IChlLnRhcmdldCBhcyBEb21FbGVtZW50ICYgUmVjb3JkPHN0cmluZywgYW55PikudmFsdWU7XG4gICAgICAgICAgaWYgKGUuY3RybEtleSkge1xuICAgICAgICAgICAgLy8gSWYgdGhlIEN0cmwga2V5IGlzIHByZXNzZWQsIGFkZCBvciByZW1vdmUgdGhlIHZhbHVlIGZyb20gdGhlIGFycmF5XG4gICAgICAgICAgICBjb25zdCBpZHggPSBtb2RlbFtwcm9wZXJ0eV0uaW5kZXhPZih2YWwpO1xuICAgICAgICAgICAgaWYgKGlkeCA9PT0gLTEpIHtcbiAgICAgICAgICAgICAgbW9kZWxbcHJvcGVydHldLnB1c2godmFsKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIG1vZGVsW3Byb3BlcnR5XS5zcGxpY2UoaWR4LCAxKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gSWYgdGhlIEN0cmwga2V5IGlzIG5vdCBwcmVzc2VkLCBzZXQgdGhlIG1vZGVsIHByb3BlcnR5IHRvIGFuIGFycmF5IHdpdGggdGhlIHNlbGVjdGVkIHZhbHVlXG4gICAgICAgICAgICBtb2RlbFtwcm9wZXJ0eV0uc3BsaWNlKDAsIG1vZGVsW3Byb3BlcnR5XS5sZW5ndGgpO1xuICAgICAgICAgICAgbW9kZWxbcHJvcGVydHldLnB1c2godmFsKTtcbiAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICAgIC8vIFNldCB0aGUgXCJzZWxlY3RlZFwiIGF0dHJpYnV0ZSBvbiB0aGUgb3B0aW9ucyBiYXNlZCBvbiB3aGV0aGVyIHRoZXkgYXJlIGluIHRoZSBtb2RlbCBwcm9wZXJ0eSBhcnJheVxuICAgICAgICB2bm9kZS5jaGlsZHJlbi5mb3JFYWNoKChjaGlsZDogVm5vZGVJbnRlcmZhY2UpID0+IHtcbiAgICAgICAgICBpZiAoY2hpbGQudGFnID09PSBcIm9wdGlvblwiKSB7XG4gICAgICAgICAgICBjb25zdCB2YWx1ZSA9IFwidmFsdWVcIiBpbiBjaGlsZC5wcm9wcyA/IGNoaWxkLnByb3BzLnZhbHVlIDogY2hpbGQuY2hpbGRyZW4uam9pbihcIlwiKS50cmltKCk7XG4gICAgICAgICAgICBjaGlsZC5wcm9wcy5zZWxlY3RlZCA9IG1vZGVsW3Byb3BlcnR5XS5pbmRleE9mKHZhbHVlKSAhPT0gLTE7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIElmIHRoZSBzZWxlY3QgZWxlbWVudCBkb2VzIG5vdCBhbGxvdyBtdWx0aXBsZSBzZWxlY3Rpb25zLCBzZXQgdGhlIFwic2VsZWN0ZWRcIiBhdHRyaWJ1dGUgb24gdGhlIG9wdGlvbnMgYmFzZWQgb24gdGhlIHZhbHVlIG9mIHRoZSBtb2RlbCBwcm9wZXJ0eVxuICAgICAgICB2bm9kZS5jaGlsZHJlbi5mb3JFYWNoKChjaGlsZDogVm5vZGVJbnRlcmZhY2UpID0+IHtcbiAgICAgICAgICBpZiAoY2hpbGQudGFnID09PSBcIm9wdGlvblwiKSB7XG4gICAgICAgICAgICBjb25zdCB2YWx1ZSA9IFwidmFsdWVcIiBpbiBjaGlsZC5wcm9wcyA/IGNoaWxkLnByb3BzLnZhbHVlIDogY2hpbGQuY2hpbGRyZW4uam9pbihcIlwiKS50cmltKCk7XG4gICAgICAgICAgICBjaGlsZC5wcm9wcy5zZWxlY3RlZCA9IHZhbHVlID09PSBtb2RlbFtwcm9wZXJ0eV07XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKHZub2RlLnRhZyA9PT0gXCJ0ZXh0YXJlYVwiKSB7XG4gICAgICAvLyBJZiB0aGUgZWxlbWVudCBpcyBhIHRleHRhcmVhLCB1c2UgdGhlIFwiaW5wdXRcIiBldmVudCBieSBkZWZhdWx0XG4gICAgICBldmVudCA9IGV2ZW50IHx8IFwib25pbnB1dFwiO1xuICAgICAgLy8gU2V0IHRoZSB0ZXh0YXJlYSdzIGNvbnRlbnQgdG8gdGhlIHZhbHVlIG9mIHRoZSBtb2RlbCBwcm9wZXJ0eVxuICAgICAgdm5vZGUuY2hpbGRyZW4gPSBbbW9kZWxbcHJvcGVydHldXTtcbiAgICB9XG5cbiAgICAvLyBXZSBhc3N1bWUgdGhhdCB0aGUgcHJldiBoYW5kbGVyIGlmIGFueSB3aWxsIG5vdCBiZSBjaGFuZ2VkIGJ5IHRoZSB1c2VyIGFjcm9zcyBwYXRjaHNcbiAgICBjb25zdCBwcmV2SGFuZGxlciA9IHZub2RlLnByb3BzW2V2ZW50XTtcblxuICAgIC8vIFNldCB0aGUgZXZlbnQgaGFuZGxlciBvbiB0aGUgZWxlbWVudFxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby11c2UtYmVmb3JlLWRlZmluZVxuICAgIHNoYXJlZFNldEF0dHJpYnV0ZShcbiAgICAgIGV2ZW50LFxuICAgICAgKGU6IEV2ZW50KSA9PiB7XG4gICAgICAgIGhhbmRsZXIoZSk7XG5cbiAgICAgICAgLy8gSWYgdGhlIHByZXZpb3VzIGhhbmRsZXIgaXMgZGVmaW5lZCwgY2FsbCBpdCBhZnRlciB0aGUgbW9kZWwgaGFzIGJlZW4gdXBkYXRlZFxuICAgICAgICBpZiAocHJldkhhbmRsZXIpIHtcbiAgICAgICAgICBwcmV2SGFuZGxlcihlKTtcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIHZub2RlLFxuICAgICAgb2xkVm5vZGVcbiAgICApO1xuICB9LFxuXG4gIC8vIFRoZSBcInYtY3JlYXRlXCIgZGlyZWN0aXZlIGlzIGNhbGxlZCB3aGVuIGEgbmV3IHZpcnR1YWwgbm9kZSBpcyBjcmVhdGVkLlxuICAvLyBUaGUgcHJvdmlkZWQgY2FsbGJhY2sgZnVuY3Rpb24gaXMgY2FsbGVkIHdpdGggdGhlIG5ldyB2aXJ0dWFsIG5vZGUgYXMgYW4gYXJndW1lbnQuXG4gIC8vIFRoaXMgZGlyZWN0aXZlIGlzIG9ubHkgY2FsbGVkIG9uY2UgcGVyIHZpcnR1YWwgbm9kZSwgd2hlbiBpdCBpcyBmaXJzdCBjcmVhdGVkLlxuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tdW51c2VkLXZhcnNcbiAgXCJ2LWNyZWF0ZVwiOiAoY2FsbGJhY2s6ICh2bm9kZTogVm5vZGVXaXRoRG9tKSA9PiB2b2lkLCB2bm9kZTogVm5vZGVXaXRoRG9tLCBvbGRWbm9kZT86IFZub2RlV2l0aERvbSkgPT4ge1xuICAgIC8vIElmIHRoaXMgaXMgbm90IGFuIHVwZGF0ZSwgY2FsbCB0aGUgY2FsbGJhY2sgZnVuY3Rpb24gd2l0aCB0aGUgbmV3IHZpcnR1YWwgbm9kZVxuICAgIGlmICghb2xkVm5vZGUpIHtcbiAgICAgIGNvbnN0IGNsZWFudXAgPSBjYWxsYmFjayh2bm9kZSk7XG5cbiAgICAgIC8vIElmIHRoZSBjYWxsYmFjayBmdW5jdGlvbiByZXR1cm5zIGEgZnVuY3Rpb24sIGNhbGwgaXQgd2hlbiB0aGUgdXBkYXRlIGlzIGdvbm5hIGJlIGNsZWFuZWQgdXBcbiAgICAgIGlmICh0eXBlb2YgY2xlYW51cCA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgIG9uQ2xlYW51cChjbGVhbnVwKTtcbiAgICAgIH1cbiAgICB9XG4gIH0sXG5cbiAgLy8gVGhlIFwidi11cGRhdGVcIiBkaXJlY3RpdmUgaXMgY2FsbGVkIHdoZW4gYW4gZXhpc3RpbmcgdmlydHVhbCBub2RlIGlzIHVwZGF0ZWQuXG4gIC8vIFRoZSBwcm92aWRlZCBjYWxsYmFjayBmdW5jdGlvbiBpcyBjYWxsZWQgd2l0aCB0aGUgbmV3IGFuZCBvbGQgdmlydHVhbCBub2RlcyBhcyBhcmd1bWVudHMuXG4gIC8vIFRoaXMgZGlyZWN0aXZlIGlzIG9ubHkgY2FsbGVkIG9uY2UgcGVyIHZpcnR1YWwgbm9kZSB1cGRhdGUuXG4gIFwidi11cGRhdGVcIjogKFxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby11bnVzZWQtdmFyc1xuICAgIGNhbGxiYWNrOiAodm5vZGU6IFZub2RlV2l0aERvbSwgb2xkVm5vZGU6IFZub2RlV2l0aERvbSkgPT4gdm9pZCxcbiAgICB2bm9kZTogVm5vZGVXaXRoRG9tLFxuICAgIG9sZFZub2RlPzogVm5vZGVXaXRoRG9tXG4gICkgPT4ge1xuICAgIC8vIElmIHRoaXMgaXMgYW4gdXBkYXRlLCBjYWxsIHRoZSBjYWxsYmFjayBmdW5jdGlvbiB3aXRoIHRoZSBuZXcgYW5kIG9sZCB2aXJ0dWFsIG5vZGVzXG4gICAgaWYgKG9sZFZub2RlKSB7XG4gICAgICBjb25zdCBjbGVhbnVwID0gY2FsbGJhY2sodm5vZGUsIG9sZFZub2RlKTtcblxuICAgICAgLy8gSWYgdGhlIGNhbGxiYWNrIGZ1bmN0aW9uIHJldHVybnMgYSBmdW5jdGlvbiwgY2FsbCBpdCB3aGVuIHRoZSB1cGRhdGUgaXMgZ29ubmEgYmUgY2xlYW5lZCB1cFxuICAgICAgaWYgKHR5cGVvZiBjbGVhbnVwID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgb25DbGVhbnVwKGNsZWFudXApO1xuICAgICAgfVxuICAgIH1cbiAgfSxcblxuICAvLyBUaGUgXCJ2LWNsZWFudXBcIiBkaXJlY3RpdmUgaXMgY2FsbGVkIHdoZW4gdGhlIHVwZGF0ZSBpcyBjbGVhbmVkIHVwLlxuICAvLyBUaGUgcHJvdmlkZWQgY2FsbGJhY2sgZnVuY3Rpb24gaXMgY2FsbGVkIHdpdGggdGhlIG9sZCB2aXJ0dWFsIG5vZGUgYXMgYW4gYXJndW1lbnQuXG4gIC8vIFRoaXMgZGlyZWN0aXZlIGlzIG9ubHkgY2FsbGVkIG9uY2UgcGVyIHZpcnR1YWwgbm9kZSwgd2hlbiB0aGUgdXBkYXRlIGlzIGNsZWFuZWQgdXAuXG4gIFwidi1jbGVhbnVwXCI6IChcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tdW51c2VkLXZhcnNcbiAgICBjYWxsYmFjazogKHZub2RlOiBWbm9kZVdpdGhEb20sIG9sZFZub2RlPzogVm5vZGVXaXRoRG9tKSA9PiB2b2lkLFxuICAgIHZub2RlOiBWbm9kZVdpdGhEb20sXG4gICAgb2xkVm5vZGU/OiBWbm9kZVdpdGhEb21cbiAgKSA9PiB7XG4gICAgLy8gQWRkIHRoZSBjYWxsYmFjayBmdW5jdGlvbiB0byB0aGUgbGlzdCBvZiBjbGVhbnVwIGZ1bmN0aW9ucyB0byBiZSBjYWxsZWQgd2hlbiB0aGUgdXBkYXRlIGlzIGNsZWFuZWQgdXBcbiAgICBvbkNsZWFudXAoKCkgPT4gY2FsbGJhY2sodm5vZGUsIG9sZFZub2RlKSk7XG4gIH1cbn07XG4vLyBBZGQgYSBkaXJlY3RpdmUgdG8gdGhlIGdsb2JhbCBkaXJlY3RpdmVzIG9iamVjdCwgd2l0aCB0aGUga2V5IGJlaW5nIHRoZSBuYW1lXG4vLyBwcmVjZWRlZCBieSBcInYtXCIuIEFsc28gYWRkIHRoZSBuYW1lIHRvIHRoZSBnbG9iYWwgcmVzZXJ2ZWRQcm9wcyBvYmplY3QuXG5leHBvcnQgZnVuY3Rpb24gZGlyZWN0aXZlKG5hbWU6IHN0cmluZywgZGlyZWN0aXZlOiBEaXJlY3RpdmUpIHtcbiAgY29uc3QgZGlyZWN0aXZlTmFtZSA9IGB2LSR7bmFtZX1gO1xuICBkaXJlY3RpdmVzW2RpcmVjdGl2ZU5hbWVdID0gZGlyZWN0aXZlO1xuICByZXNlcnZlZFByb3BzW2RpcmVjdGl2ZU5hbWVdID0gdHJ1ZTtcbn1cblxuLy8gU2V0IGFuIGF0dHJpYnV0ZSBvbiBhIHZpcnR1YWwgRE9NIG5vZGUgYW5kIHVwZGF0ZSB0aGUgYWN0dWFsIERPTSBlbGVtZW50LlxuLy8gSWYgdGhlIGF0dHJpYnV0ZSB2YWx1ZSBpcyBhIGZ1bmN0aW9uLCBhZGQgYW4gZXZlbnQgbGlzdGVuZXIgZm9yIHRoZSBhdHRyaWJ1dGVcbi8vIG5hbWUgdG8gdGhlIERPTSBlbGVtZW50IHJlcHJlc2VudGVkIGJ5IG1haW5Wbm9kZS5cbi8vIElmIG9sZFZub2RlIGlzIHByb3ZpZGVkLCBjb21wYXJlIHRoZSBuZXcgYXR0cmlidXRlIHZhbHVlIHRvIHRoZSBvbGQgdmFsdWVcbi8vIGFuZCBvbmx5IHVwZGF0ZSB0aGUgYXR0cmlidXRlIGlmIHRoZSB2YWx1ZXMgYXJlIGRpZmZlcmVudC5cbmZ1bmN0aW9uIHNoYXJlZFNldEF0dHJpYnV0ZShuYW1lOiBzdHJpbmcsIHZhbHVlOiBhbnksIG5ld1Zub2RlOiBWbm9kZVdpdGhEb20sIG9sZFZub2RlPzogVm5vZGVXaXRoRG9tKTogdm9pZCB8IGJvb2xlYW4ge1xuICAvLyBJZiB0aGUgYXR0cmlidXRlIHZhbHVlIGlzIGEgZnVuY3Rpb24sIGFkZCBhbiBldmVudCBsaXN0ZW5lciBmb3IgdGhlIGF0dHJpYnV0ZVxuICAvLyBuYW1lIHRvIHRoZSBET00gZWxlbWVudCByZXByZXNlbnRlZCBieSBtYWluVm5vZGUuXG4gIGlmICh0eXBlb2YgdmFsdWUgPT09IFwiZnVuY3Rpb25cIikge1xuICAgIC8vIE9ubHkgYWRkIHRoZSBldmVudCBsaXN0ZW5lciBpZiBpdCBoYXNuJ3QgYmVlbiBhZGRlZCB5ZXQuXG4gICAgaWYgKG5hbWUgaW4gZXZlbnRMaXN0ZW5lck5hbWVzID09PSBmYWxzZSkge1xuICAgICAgKG1haW5Wbm9kZSBhcyBWbm9kZVdpdGhEb20pLmRvbS5hZGRFdmVudExpc3RlbmVyKG5hbWUuc2xpY2UoMiksIGV2ZW50TGlzdGVuZXIpO1xuICAgICAgZXZlbnRMaXN0ZW5lck5hbWVzW25hbWVdID0gdHJ1ZTtcbiAgICB9XG4gICAgbmV3Vm5vZGUuZG9tW2B2LSR7bmFtZX1gXSA9IHZhbHVlO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIC8vIElmIHRoZSBhdHRyaWJ1dGUgaXMgcHJlc2VudCBvbiB0aGUgRE9NIGVsZW1lbnQgYW5kIG5ld1Zub2RlIGlzIG5vdCBhbiBTVkcsXG4gIC8vIHVwZGF0ZSB0aGUgYXR0cmlidXRlIGlmIHRoZSB2YWx1ZSBoYXMgY2hhbmdlZC5cbiAgaWYgKG5ld1Zub2RlLmlzU1ZHID09PSBmYWxzZSAmJiBuYW1lIGluIG5ld1Zub2RlLmRvbSkge1xuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBlcWVxZXFcbiAgICBpZiAobmV3Vm5vZGUuZG9tW25hbWVdICE9IHZhbHVlKSB7XG4gICAgICBuZXdWbm9kZS5kb21bbmFtZV0gPSB2YWx1ZTtcbiAgICB9XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgLy8gSWYgb2xkVm5vZGUgaXMgbm90IHByb3ZpZGVkIG9yIHRoZSBhdHRyaWJ1dGUgdmFsdWUgaGFzIGNoYW5nZWQsIHVwZGF0ZSB0aGVcbiAgLy8gYXR0cmlidXRlIG9uIHRoZSBET00gZWxlbWVudC5cbiAgaWYgKCFvbGRWbm9kZSB8fCB2YWx1ZSAhPT0gb2xkVm5vZGUucHJvcHNbbmFtZV0pIHtcbiAgICBpZiAodmFsdWUgPT09IGZhbHNlKSB7XG4gICAgICBuZXdWbm9kZS5kb20ucmVtb3ZlQXR0cmlidXRlKG5hbWUpO1xuICAgIH0gZWxzZSB7XG4gICAgICBuZXdWbm9kZS5kb20uc2V0QXR0cmlidXRlKG5hbWUsIHZhbHVlKTtcbiAgICB9XG4gIH1cbn1cblxuLy8gU2V0IGFuIGF0dHJpYnV0ZSBvbiBhIHZpcnR1YWwgRE9NIG5vZGUgYW5kIHVwZGF0ZSB0aGUgYWN0dWFsIERPTSBlbGVtZW50LlxuLy8gU2tpcCB0aGUgYXR0cmlidXRlIGlmIGl0IGlzIGluIHRoZSByZXNlcnZlZFByb3BzIG9iamVjdC5cbmV4cG9ydCBmdW5jdGlvbiBzZXRBdHRyaWJ1dGUobmFtZTogc3RyaW5nLCB2YWx1ZTogYW55LCBuZXdWbm9kZTogVm5vZGVXaXRoRG9tLCBvbGRWbm9kZT86IFZub2RlV2l0aERvbSk6IHZvaWQge1xuICBpZiAocmVzZXJ2ZWRQcm9wc1tuYW1lXSkge1xuICAgIHJldHVybjtcbiAgfVxuICBuZXdWbm9kZS5wcm9wc1tuYW1lXSA9IHZhbHVlO1xuICBzaGFyZWRTZXRBdHRyaWJ1dGUobmFtZSwgdmFsdWUsIG5ld1Zub2RlLCBvbGRWbm9kZSk7XG59XG5cbi8vIFVwZGF0ZSB0aGUgYXR0cmlidXRlcyBvbiBhIHZpcnR1YWwgRE9NIG5vZGUuIElmIG9sZFZub2RlIGlzIHByb3ZpZGVkLCByZW1vdmVcbi8vIGF0dHJpYnV0ZXMgZnJvbSB0aGUgRE9NIGVsZW1lbnQgdGhhdCBhcmUgbm90IHByZXNlbnQgaW4gbmV3Vm5vZGUucHJvcHMgYnV0IGFyZVxuLy8gcHJlc2VudCBpbiBvbGRWbm9kZS5wcm9wcy4gVGhlbiwgaXRlcmF0ZSBvdmVyIHRoZSBhdHRyaWJ1dGVzIGluIG5ld1Zub2RlLnByb3BzXG4vLyBhbmQgdXBkYXRlIHRoZSBET00gZWxlbWVudCB3aXRoIHRoZSBhdHRyaWJ1dGVzIHVzaW5nIHRoZSBzaGFyZWRTZXRBdHRyaWJ1dGVcbi8vIGZ1bmN0aW9uLiBJZiBhbiBhdHRyaWJ1dGUgaXMgaW4gdGhlIHJlc2VydmVkUHJvcHMgb2JqZWN0IGFuZCBoYXMgYSBjb3JyZXNwb25kaW5nXG4vLyBkaXJlY3RpdmUgaW4gdGhlIGRpcmVjdGl2ZXMgb2JqZWN0LCBjYWxsIHRoZSBkaXJlY3RpdmUgd2l0aCB0aGUgYXR0cmlidXRlIHZhbHVlXG4vLyBhbmQgdGhlIHR3byB2aXJ0dWFsIERPTSBub2RlcyBhcyBhcmd1bWVudHMuIElmIHRoZSBkaXJlY3RpdmUgcmV0dXJucyBmYWxzZSwgZXhpdFxuLy8gdGhlIGxvb3AuXG5leHBvcnQgZnVuY3Rpb24gdXBkYXRlQXR0cmlidXRlcyhuZXdWbm9kZTogVm5vZGVXaXRoRG9tLCBvbGRWbm9kZT86IFZub2RlV2l0aERvbSk6IHZvaWQge1xuICAvLyBJZiBvbGRWbm9kZSBpcyBwcm92aWRlZCwgcmVtb3ZlIGF0dHJpYnV0ZXMgZnJvbSB0aGUgRE9NIGVsZW1lbnQgdGhhdCBhcmUgbm90XG4gIC8vIHByZXNlbnQgaW4gbmV3Vm5vZGUucHJvcHMgYnV0IGFyZSBwcmVzZW50IGluIG9sZFZub2RlLnByb3BzLlxuICBpZiAob2xkVm5vZGUpIHtcbiAgICBmb3IgKGNvbnN0IG5hbWUgaW4gb2xkVm5vZGUucHJvcHMpIHtcbiAgICAgIGlmICghbmV3Vm5vZGUucHJvcHNbbmFtZV0gJiYgIWV2ZW50TGlzdGVuZXJOYW1lc1tuYW1lXSAmJiAhcmVzZXJ2ZWRQcm9wc1tuYW1lXSkge1xuICAgICAgICBpZiAobmV3Vm5vZGUuaXNTVkcgPT09IGZhbHNlICYmIG5hbWUgaW4gbmV3Vm5vZGUuZG9tKSB7XG4gICAgICAgICAgbmV3Vm5vZGUuZG9tW25hbWVdID0gbnVsbDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBuZXdWbm9kZS5kb20ucmVtb3ZlQXR0cmlidXRlKG5hbWUpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLy8gSXRlcmF0ZSBvdmVyIHRoZSBhdHRyaWJ1dGVzIGluIG5ld1Zub2RlLnByb3BzIGFuZCB1cGRhdGUgdGhlIERPTSBlbGVtZW50IHdpdGhcbiAgLy8gdGhlIGF0dHJpYnV0ZXMgdXNpbmcgdGhlIHNoYXJlZFNldEF0dHJpYnV0ZSBmdW5jdGlvbi5cbiAgZm9yIChjb25zdCBuYW1lIGluIG5ld1Zub2RlLnByb3BzKSB7XG4gICAgaWYgKHJlc2VydmVkUHJvcHNbbmFtZV0pIHtcbiAgICAgIC8vIElmIHRoZXJlIGlzIGEgZGlyZWN0aXZlIGZvciB0aGUgYXR0cmlidXRlLCBjYWxsIGl0IHdpdGggdGhlIGF0dHJpYnV0ZSB2YWx1ZVxuICAgICAgLy8gYW5kIHRoZSB0d28gdmlydHVhbCBET00gbm9kZXMgYXMgYXJndW1lbnRzLiBJZiB0aGUgZGlyZWN0aXZlIHJldHVybnMgZmFsc2UsXG4gICAgICAvLyBleGl0IHRoZSBsb29wLlxuICAgICAgaWYgKGRpcmVjdGl2ZXNbbmFtZV0gJiYgZGlyZWN0aXZlc1tuYW1lXShuZXdWbm9kZS5wcm9wc1tuYW1lXSwgbmV3Vm5vZGUsIG9sZFZub2RlKSA9PT0gZmFsc2UpIHtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBjb250aW51ZTtcbiAgICB9XG4gICAgc2hhcmVkU2V0QXR0cmlidXRlKG5hbWUsIG5ld1Zub2RlLnByb3BzW25hbWVdLCBuZXdWbm9kZSwgb2xkVm5vZGUpO1xuICB9XG59XG5cbi8qIHBhdGNoIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi9cblxuLy8gUGF0Y2ggYSBET00gbm9kZSB3aXRoIGEgbmV3IFZOb2RlIHRyZWVcbmV4cG9ydCBmdW5jdGlvbiBwYXRjaChuZXdWbm9kZTogVm5vZGVXaXRoRG9tLCBvbGRWbm9kZT86IFZub2RlV2l0aERvbSk6IHZvaWQge1xuICAvLyBJZiB0aGUgbmV3IHRyZWUgaGFzIG5vIGNoaWxkcmVuLCBzZXQgdGhlIHRleHQgY29udGVudCBvZiB0aGUgcGFyZW50IERPTSBlbGVtZW50IHRvIGFuIGVtcHR5IHN0cmluZ1xuICBpZiAobmV3Vm5vZGUuY2hpbGRyZW4ubGVuZ3RoID09PSAwKSB7XG4gICAgbmV3Vm5vZGUuZG9tLnRleHRDb250ZW50ID0gXCJcIjtcbiAgICByZXR1cm47XG4gIH1cblxuICAvLyBHZXQgdGhlIGNoaWxkcmVuIG9mIHRoZSBuZXcgYW5kIG9sZCB2aXJ0dWFsIERPTSBub2Rlc1xuICBjb25zdCBuZXdUcmVlID0gbmV3Vm5vZGUuY2hpbGRyZW47XG4gIGNvbnN0IG9sZFRyZWUgPSBvbGRWbm9kZT8uY2hpbGRyZW4gfHwgW107XG4gIC8vIEdldCB0aGUgbGVuZ3RoIG9mIHRoZSBvbGQgdHJlZVxuICBjb25zdCBvbGRUcmVlTGVuZ3RoID0gb2xkVHJlZS5sZW5ndGg7XG4gIC8vIEdldCB0aGUgbGVuZ3RoIG9mIHRoZSBuZXcgdHJlZVxuICBsZXQgbmV3VHJlZUxlbmd0aCA9IG5ld1RyZWUubGVuZ3RoO1xuICAvLyBTZXQgdGhlIGdsb2JhbCBjdXJyZW50IG9iamVjdCB0byB0aGUgbmV3IGFuZCBvbGQgdmlydHVhbCBET00gbm9kZXNcbiAgY3VycmVudC52bm9kZSA9IG5ld1Zub2RlO1xuICBjdXJyZW50Lm9sZFZub2RlID0gb2xkVm5vZGU7XG5cbiAgLy8gRmxhdHRlbiB0aGUgbmV3IHRyZWVcbiAgLy8gVGFrZSBpbnRvIGFjY291bnQgdGhhdCBpcyBuZWNlc3NhcnkgdG8gZmxhdHRlbiB0aGUgdHJlZSBiZWZvcmUgdGhlIHBhdGNoIHByb2Nlc3NcbiAgLy8gdG8gbGV0IHRoZSBob29rcyBhbmQgc2lnbmFscyB3b3JrIHByb3Blcmx5XG4gIGxldCBpID0gMDtcbiAgd2hpbGUgKGkgPCBuZXdUcmVlTGVuZ3RoKSB7XG4gICAgY29uc3QgbmV3Q2hpbGQgPSBuZXdUcmVlW2ldO1xuXG4gICAgLy8gSWYgdGhlIG5ldyBjaGlsZCBpcyBhIFZub2RlIGFuZCBpcyBub3QgYSB0ZXh0IG5vZGVcbiAgICBpZiAobmV3Q2hpbGQgaW5zdGFuY2VvZiBWbm9kZSkge1xuICAgICAgLy8gSWYgdGhlIHRhZyBvZiB0aGUgbmV3IGNoaWxkIGlzIG5vdCBhIHN0cmluZywgaXQgaXMgYSBjb21wb25lbnRcbiAgICAgIGlmICh0eXBlb2YgbmV3Q2hpbGQudGFnICE9PSBcInN0cmluZ1wiKSB7XG4gICAgICAgIC8vIFNldCB0aGUgY3VycmVudCBjb21wb25lbnQgdG8gdGhlIHRhZyBvZiB0aGUgbmV3IGNoaWxkXG4gICAgICAgIGN1cnJlbnQuY29tcG9uZW50ID0gbmV3Q2hpbGQudGFnO1xuICAgICAgICAvLyBSZXBsYWNlIHRoZSBuZXcgY2hpbGQgd2l0aCB0aGUgcmVzdWx0IG9mIGNhbGxpbmcgaXRzIHZpZXcgb3IgYmluZCBtZXRob2QsIHBhc3NpbmcgaW4gdGhlIHByb3BzIGFuZCBjaGlsZHJlbiBhcyBhcmd1bWVudHNcbiAgICAgICAgbmV3VHJlZS5zcGxpY2UoXG4gICAgICAgICAgaSxcbiAgICAgICAgICAxLFxuICAgICAgICAgIChcInZpZXdcIiBpbiBuZXdDaGlsZC50YWcgPyBuZXdDaGlsZC50YWcudmlldy5iaW5kKG5ld0NoaWxkLnRhZykgOiBuZXdDaGlsZC50YWcuYmluZChuZXdDaGlsZC50YWcpKShcbiAgICAgICAgICAgIG5ld0NoaWxkLnByb3BzLFxuICAgICAgICAgICAgLi4ubmV3Q2hpbGQuY2hpbGRyZW5cbiAgICAgICAgICApXG4gICAgICAgICk7XG4gICAgICAgIG5ld1RyZWVMZW5ndGggPSBuZXdUcmVlLmxlbmd0aDtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpKys7XG4gICAgICB9XG4gICAgICAvLyBJZiB0aGUgbmV3IGNoaWxkIGlzIGFuIGFycmF5LCBmbGF0dGVuIGl0IGFuZCBjb250aW51ZSB0aGUgbG9vcFxuICAgIH0gZWxzZSBpZiAoQXJyYXkuaXNBcnJheShuZXdDaGlsZCkpIHtcbiAgICAgIG5ld1RyZWUuc3BsaWNlKGksIDEsIC4uLm5ld0NoaWxkKTtcbiAgICAgIG5ld1RyZWVMZW5ndGggPSBuZXdUcmVlLmxlbmd0aDtcbiAgICAgIC8vIElmIHRoZSBuZXcgY2hpbGQgaXMgbnVsbCBvciB1bmRlZmluZWQsIHJlbW92ZSBpdCBmcm9tIHRoZSBuZXcgdHJlZSBhbmQgY29udGludWUgdGhlIGxvb3BcbiAgICB9IGVsc2UgaWYgKG5ld0NoaWxkID09IG51bGwpIHtcbiAgICAgIG5ld1RyZWUuc3BsaWNlKGksIDEpO1xuICAgICAgbmV3VHJlZUxlbmd0aCA9IG5ld1RyZWUubGVuZ3RoO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBJZiB0aGUgbmV3IGNoaWxkIGlzIG5vdCBhIFZub2RlIG9yIGFuIGFycmF5LCBpdCBpcyBhIHRleHQgbm9kZVxuICAgICAgLy8ganVzdCBjb250aW51ZSB0aGUgbG9vcFxuICAgICAgaSsrO1xuICAgIH1cbiAgfVxuXG4gIC8vIElmIHRoZSBuZXcgdHJlZSBoYXMgbm8gY2hpbGRyZW4sIHNldCB0aGUgdGV4dCBjb250ZW50IG9mIHRoZSBwYXJlbnQgRE9NIGVsZW1lbnQgdG8gYW4gZW1wdHkgc3RyaW5nXG4gIGlmIChuZXdUcmVlTGVuZ3RoID09PSAwKSB7XG4gICAgbmV3Vm5vZGUuZG9tLnRleHRDb250ZW50ID0gXCJcIjtcbiAgICByZXR1cm47XG4gIH1cblxuICAvLyBJZiB0aGUgb2xkIHRyZWUgaGFzIGNoaWxkcmVuIGFuZCB0aGUgZmlyc3QgY2hpbGQgb2YgdGhlIG5ldyB0cmVlIGlzIGEgVk5vZGUgd2l0aCBhIFwia2V5XCJcbiAgLy8gYXR0cmlidXRlIGFuZCB0aGUgZmlyc3QgY2hpbGQgb2YgdGhlIG9sZCB0cmVlIGlzIGEgVk5vZGUgd2l0aCBhIFwia2V5XCIgYXR0cmlidXRlLCB1cGRhdGVcbiAgLy8gdGhlIERPTSBlbGVtZW50IGluIHBsYWNlIGJ5IGNvbXBhcmluZyB0aGUga2V5cyBvZiB0aGUgbm9kZXMgaW4gdGhlIHRyZWVzLlxuICBpZiAoXG4gICAgb2xkVHJlZUxlbmd0aCA+IDAgJiZcbiAgICBuZXdUcmVlWzBdIGluc3RhbmNlb2YgVm5vZGUgJiZcbiAgICBvbGRUcmVlWzBdIGluc3RhbmNlb2YgVm5vZGUgJiZcbiAgICBcImtleVwiIGluIG5ld1RyZWVbMF0ucHJvcHMgJiZcbiAgICBcImtleVwiIGluIG9sZFRyZWVbMF0ucHJvcHNcbiAgKSB7XG4gICAgY29uc3Qgb2xkS2V5ZWRMaXN0OiBSZWNvcmQ8c3RyaW5nLCBudW1iZXI+ID0ge307XG4gICAgY29uc3QgbmV3S2V5ZWRMaXN0OiBSZWNvcmQ8c3RyaW5nLCBudW1iZXI+ID0ge307XG4gICAgY29uc3QgY2hpbGROb2RlcyA9IG5ld1Zub2RlLmRvbS5jaGlsZE5vZGVzO1xuXG4gICAgLy8gQ3JlYXRlIGtleSBtYXBzIHdoaWxlIGFsc28gaGFuZGxpbmcgcmVtb3ZhbCBvZiBub2RlcyBub3QgcHJlc2VudCBpbiBuZXdUcmVlXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBvbGRUcmVlTGVuZ3RoOyBpKyspIHtcbiAgICAgIG9sZEtleWVkTGlzdFtvbGRUcmVlW2ldLnByb3BzLmtleV0gPSBpO1xuICAgICAgaWYgKGkgPCBuZXdUcmVlTGVuZ3RoKSB7XG4gICAgICAgIG5ld0tleWVkTGlzdFtuZXdUcmVlW2ldLnByb3BzLmtleV0gPSBpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbmV3VHJlZUxlbmd0aDsgaSsrKSB7XG4gICAgICBjb25zdCBuZXdDaGlsZCA9IG5ld1RyZWVbaV07XG4gICAgICBjb25zdCBvbGRDaGlsZEluZGV4ID0gb2xkS2V5ZWRMaXN0W25ld0NoaWxkLnByb3BzLmtleV07XG4gICAgICBjb25zdCBvbGRDaGlsZCA9IG9sZFRyZWVbb2xkQ2hpbGRJbmRleF07XG4gICAgICBsZXQgc2hvdWxkUGF0Y2ggPSB0cnVlO1xuXG4gICAgICBpZiAob2xkQ2hpbGQpIHtcbiAgICAgICAgbmV3Q2hpbGQuZG9tID0gb2xkQ2hpbGQuZG9tO1xuICAgICAgICBpZiAoXCJ2LWtlZXBcIiBpbiBuZXdDaGlsZC5wcm9wcyAmJiBuZXdDaGlsZC5wcm9wc1tcInYta2VlcFwiXSA9PT0gb2xkQ2hpbGQucHJvcHNbXCJ2LWtlZXBcIl0pIHtcbiAgICAgICAgICBuZXdDaGlsZC5jaGlsZHJlbiA9IG9sZENoaWxkLmNoaWxkcmVuO1xuICAgICAgICAgIHNob3VsZFBhdGNoID0gZmFsc2U7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdXBkYXRlQXR0cmlidXRlcyhuZXdDaGlsZCwgb2xkQ2hpbGQpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBuZXdDaGlsZC5kb20gPSBjcmVhdGVEb21FbGVtZW50KG5ld0NoaWxkLnRhZywgbmV3Q2hpbGQuaXNTVkcpO1xuICAgICAgICB1cGRhdGVBdHRyaWJ1dGVzKG5ld0NoaWxkKTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgY3VycmVudE5vZGUgPSBjaGlsZE5vZGVzW2ldO1xuICAgICAgaWYgKCFjdXJyZW50Tm9kZSkge1xuICAgICAgICBuZXdWbm9kZS5kb20uYXBwZW5kQ2hpbGQobmV3Q2hpbGQuZG9tKTtcbiAgICAgIH0gZWxzZSBpZiAoY3VycmVudE5vZGUgIT09IG5ld0NoaWxkLmRvbSkge1xuICAgICAgICBuZXdWbm9kZS5kb20ucmVwbGFjZUNoaWxkKG5ld0NoaWxkLmRvbSwgY3VycmVudE5vZGUpO1xuICAgICAgfVxuXG4gICAgICBzaG91bGRQYXRjaCAmJiBwYXRjaChuZXdDaGlsZCwgb2xkQ2hpbGQpO1xuICAgIH1cblxuICAgIC8vIFJlbW92ZSBub2RlcyB0aGF0IGRvbid0IGV4aXN0IGluIG5ld1RyZWVcbiAgICBmb3IgKGxldCBpID0gbmV3VHJlZUxlbmd0aDsgaSA8IG9sZFRyZWVMZW5ndGg7IGkrKykge1xuICAgICAgaWYgKCFuZXdLZXllZExpc3Rbb2xkVHJlZVtpXS5wcm9wcy5rZXldKSB7XG4gICAgICAgIGNvbnN0IGRvbVRvUmVtb3ZlID0gb2xkVHJlZVtpXS5kb207XG4gICAgICAgIGRvbVRvUmVtb3ZlLnBhcmVudE5vZGUgJiYgZG9tVG9SZW1vdmUucGFyZW50Tm9kZS5yZW1vdmVDaGlsZChkb21Ub1JlbW92ZSk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybjtcbiAgfVxuXG4gIC8vIFBhdGNoIHRoZSB0aGUgb2xkIHRyZWVcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBuZXdUcmVlTGVuZ3RoOyBpKyspIHtcbiAgICBjb25zdCBuZXdDaGlsZCA9IG5ld1RyZWVbaV07XG4gICAgY29uc3Qgb2xkQ2hpbGQgPSBvbGRUcmVlW2ldO1xuICAgIGNvbnN0IGlzR3JlYXRlclRoYW5PbGRUcmVlTGVuZ3RoID0gaSA+PSBvbGRUcmVlTGVuZ3RoO1xuXG4gICAgaWYgKG5ld0NoaWxkIGluc3RhbmNlb2YgVm5vZGUgPT09IGZhbHNlKSB7XG4gICAgICBpZiAoaXNHcmVhdGVyVGhhbk9sZFRyZWVMZW5ndGggfHwgb2xkQ2hpbGQgaW5zdGFuY2VvZiBWbm9kZSkge1xuICAgICAgICAvLyBJZiB0aGVyZSdzIG5vIGNvcnJlc3BvbmRpbmcgb2xkIGNoaWxkLCBjcmVhdGUgYSBuZXcgdGV4dCBub2RlIGZvciB0aGUgbmV3IGNoaWxkXG4gICAgICAgIGNvbnN0IGRvbSA9IGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKG5ld0NoaWxkIGFzIHN0cmluZyk7XG5cbiAgICAgICAgaWYgKGlzR3JlYXRlclRoYW5PbGRUcmVlTGVuZ3RoKSB7XG4gICAgICAgICAgLy8gQXBwZW5kIHRoZSBuZXcgY2hpbGQgdG8gdGhlIGRvbVxuICAgICAgICAgIG5ld1Zub2RlLmRvbS5hcHBlbmRDaGlsZChkb20pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIG5ld1Zub2RlLmRvbS5yZXBsYWNlQ2hpbGQoZG9tLCBuZXdWbm9kZS5kb20uY2hpbGROb2Rlc1tpXSk7XG4gICAgICAgIH1cbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIC8vIElmIHRoZSBvbGQgY2hpbGQgaXMgbm90IGEgdm5vZGVcbiAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBlcWVxZXFcbiAgICAgIGlmIChuZXdWbm9kZS5kb20uY2hpbGROb2Rlc1tpXS50ZXh0Q29udGVudCAhPSBuZXdDaGlsZCkge1xuICAgICAgICBuZXdWbm9kZS5kb20uY2hpbGROb2Rlc1tpXS50ZXh0Q29udGVudCA9IG5ld0NoaWxkIGFzIHN0cmluZztcbiAgICAgIH1cbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIC8vIFNldCB0aGUgaXNTVkcgZmxhZyBmb3IgdGhlIG5ldyBjaGlsZCBpZiBpdCBpcyBhbiBTVkcgZWxlbWVudCBvciBpZiB0aGUgcGFyZW50IGlzIGFuIFNWRyBlbGVtZW50XG4gICAgbmV3Q2hpbGQuaXNTVkcgPSBuZXdWbm9kZS5pc1NWRyB8fCBuZXdDaGlsZC50YWcgPT09IFwic3ZnXCI7XG5cbiAgICBpZiAoaXNHcmVhdGVyVGhhbk9sZFRyZWVMZW5ndGggfHwgb2xkQ2hpbGQgaW5zdGFuY2VvZiBWbm9kZSA9PT0gZmFsc2UgfHwgbmV3Q2hpbGQudGFnICE9PSBvbGRDaGlsZC50YWcpIHtcbiAgICAgIC8vIElmIHRoZXJlJ3Mgbm8gY29ycmVzcG9uZGluZyBvbGQgY2hpbGQsIGNyZWF0ZSBhIG5ldyBkb20gZWxlbWVudCBmb3IgdGhlIG5ldyBjaGlsZFxuICAgICAgbmV3Q2hpbGQuZG9tID0gY3JlYXRlRG9tRWxlbWVudChuZXdDaGlsZC50YWcgYXMgc3RyaW5nLCBuZXdDaGlsZC5pc1NWRyk7XG5cbiAgICAgIGlmIChpc0dyZWF0ZXJUaGFuT2xkVHJlZUxlbmd0aCkge1xuICAgICAgICAvLyBBcHBlbmQgdGhlIG5ldyBjaGlsZCB0byB0aGUgZG9tXG4gICAgICAgIG5ld1Zub2RlLmRvbS5hcHBlbmRDaGlsZChuZXdDaGlsZC5kb20pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbmV3Vm5vZGUuZG9tLnJlcGxhY2VDaGlsZChuZXdDaGlsZC5kb20sIG5ld1Zub2RlLmRvbS5jaGlsZE5vZGVzW2ldKTtcbiAgICAgIH1cblxuICAgICAgLy8gVXBkYXRlIHRoZSBhdHRyaWJ1dGVzIG9mIHRoZSBuZXcgY2hpbGRcbiAgICAgIHVwZGF0ZUF0dHJpYnV0ZXMobmV3Q2hpbGQgYXMgVm5vZGVXaXRoRG9tKTtcblxuICAgICAgLy8gUmVjdXJzaXZlbHkgcGF0Y2ggdGhlIG5ldyBjaGlsZFxuICAgICAgcGF0Y2gobmV3Q2hpbGQgYXMgVm5vZGVXaXRoRG9tKTtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIC8vIFNldCB0aGUgZG9tIHByb3BlcnR5IG9mIHRoZSBuZXcgY2hpbGQgdG8gdGhlIGRvbSBwcm9wZXJ0eSBvZiB0aGUgb2xkIGNoaWxkXG4gICAgbmV3Q2hpbGQuZG9tID0gb2xkQ2hpbGQuZG9tO1xuICAgIC8vIElmIHRoZSB2LWtlZXAgcHJvcCBpcyB0aGUgc2FtZSBmb3IgYm90aCB0aGUgbmV3IGFuZCBvbGQgY2hpbGQsIHNldCB0aGUgY2hpbGRyZW4gb2YgdGhlIG5ldyBjaGlsZCB0byB0aGUgY2hpbGRyZW4gb2YgdGhlIG9sZCBjaGlsZFxuICAgIGlmIChcInYta2VlcFwiIGluIG5ld0NoaWxkLnByb3BzICYmIG5ld0NoaWxkLnByb3BzW1widi1rZWVwXCJdID09PSBvbGRDaGlsZC5wcm9wc1tcInYta2VlcFwiXSkge1xuICAgICAgbmV3Q2hpbGQuY2hpbGRyZW4gPSBvbGRDaGlsZC5jaGlsZHJlbjtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIC8vIFVwZGF0ZSB0aGUgYXR0cmlidXRlcyBvZiB0aGUgbmV3IGNoaWxkIGJhc2VkIG9uIHRoZSBvbGQgY2hpbGRcbiAgICB1cGRhdGVBdHRyaWJ1dGVzKG5ld0NoaWxkIGFzIFZub2RlV2l0aERvbSwgb2xkQ2hpbGQgYXMgVm5vZGVXaXRoRG9tKTtcbiAgICAvLyBSZWN1cnNpdmVseSBwYXRjaCB0aGUgbmV3IGFuZCBvbGQgY2hpbGRyZW5cbiAgICBwYXRjaChuZXdDaGlsZCBhcyBWbm9kZVdpdGhEb20sIG9sZENoaWxkIGFzIFZub2RlV2l0aERvbSk7XG4gIH1cblxuICAvLyBSZW1vdmUgYW55IG9sZCBjaGlsZHJlbiB0aGF0IGFyZSBubyBsb25nZXIgcHJlc2VudCBpbiB0aGUgbmV3IHRyZWVcbiAgZm9yICg7IG5ld1RyZWVMZW5ndGggPCBvbGRUcmVlTGVuZ3RoOyBuZXdUcmVlTGVuZ3RoKyspIHtcbiAgICBuZXdWbm9kZS5kb20ucmVtb3ZlQ2hpbGQob2xkVHJlZVtuZXdUcmVlTGVuZ3RoXS5kb20pO1xuICB9XG59XG5cbi8vIFVwZGF0ZSB0aGUgbWFpbiBWbm9kZVxuZXhwb3J0IGZ1bmN0aW9uIHVwZGF0ZSgpOiB2b2lkIHwgc3RyaW5nIHtcbiAgLy8gSWYgdGhlIG1haW4gVm5vZGUgZXhpc3RzXG4gIGlmIChtYWluVm5vZGUpIHtcbiAgICAvLyBDYWxsIGFueSBjbGVhbnVwIGZ1bmN0aW9ucyB0aGF0IGFyZSByZWdpc3RlcmVkIHdpdGggdGhlIG9uQ2xlYW51cFNldCBzZXRcbiAgICBjYWxsU2V0KG9uQ2xlYW51cFNldCk7XG4gICAgLy8gU3RvcmUgYSByZWZlcmVuY2UgdG8gdGhlIG9sZCBtYWluIFZub2RlXG4gICAgY29uc3Qgb2xkTWFpblZub2RlID0gbWFpblZub2RlO1xuICAgIC8vIENyZWF0ZSBhIG5ldyBtYWluIFZub2RlIHdpdGggdGhlIG1haW4gY29tcG9uZW50IGFzIGl0cyBvbmx5IGNoaWxkXG4gICAgbWFpblZub2RlID0gbmV3IFZub2RlKG9sZE1haW5Wbm9kZS50YWcsIG9sZE1haW5Wbm9kZS5wcm9wcywgW21haW5Db21wb25lbnRdKSBhcyBWbm9kZVdpdGhEb207XG4gICAgbWFpblZub2RlLmRvbSA9IG9sZE1haW5Wbm9kZS5kb207XG4gICAgbWFpblZub2RlLmlzU1ZHID0gb2xkTWFpblZub2RlLmlzU1ZHO1xuXG4gICAgLy8gUmVjdXJzaXZlbHkgcGF0Y2ggdGhlIG5ldyBhbmQgb2xkIG1haW4gVm5vZGVzXG4gICAgcGF0Y2gobWFpblZub2RlLCBvbGRNYWluVm5vZGUpO1xuXG4gICAgLy8gQ2FsbCBhbnkgdXBkYXRlIG9yIG1vdW50IGZ1bmN0aW9ucyB0aGF0IGFyZSByZWdpc3RlcmVkIHdpdGggdGhlIG9uVXBkYXRlU2V0IG9yIG9uTW91bnRTZXQgc2V0XG4gICAgY2FsbFNldChpc01vdW50ZWQgPyBvblVwZGF0ZVNldCA6IG9uTW91bnRTZXQpO1xuXG4gICAgLy8gU2V0IHRoZSBpc01vdW50ZWQgZmxhZyB0byB0cnVlXG4gICAgaXNNb3VudGVkID0gdHJ1ZTtcblxuICAgIC8vIFJlc2V0IHRoZSBjdXJyZW50IHZub2RlLCBvbGRWbm9kZSwgYW5kIGNvbXBvbmVudCBwcm9wZXJ0aWVzXG4gICAgY3VycmVudC52bm9kZSA9IG51bGw7XG4gICAgY3VycmVudC5vbGRWbm9kZSA9IG51bGw7XG4gICAgY3VycmVudC5jb21wb25lbnQgPSBudWxsO1xuXG4gICAgLy8gSWYgdGhlIGNvZGUgaXMgcnVubmluZyBpbiBhIE5vZGUuanMgZW52aXJvbm1lbnQsIHJldHVybiB0aGUgaW5uZXIgSFRNTCBvZiB0aGUgbWFpbiBWbm9kZSdzIGRvbSBlbGVtZW50XG4gICAgaWYgKGlzTm9kZUpzKSB7XG4gICAgICByZXR1cm4gbWFpblZub2RlLmRvbS5pbm5lckhUTUw7XG4gICAgfVxuICB9XG59XG5cbi8vIFVwZGF0ZSBjdXN0b20gVm5vZGVcbi8vIEl0IGlzIGFzc3VtZWQgdGhhdCBhIGZpcnN0IG1vdW50IGhhcyBhbHJlYWR5IG9jY3VycmVkLCBzbyxcbi8vIHRoZSBvbGRWbm9kZSBpcyBub3QgbnVsbCBhbmQgdGhlIGRvbSBwcm9wZXJ0eSBvZiB0aGUgb2xkVm5vZGUgaXMgbm90IG51bGxcbi8vIFlvdSBuZWVkIHRvIHNldCB0aGUgZG9tIHByb3BlcnR5IG9mIHRoZSBuZXdWbm9kZSB0byB0aGUgZG9tIHByb3BlcnR5IG9mIHRoZSBvbGRWbm9kZVxuLy8gVGhlIHNhbWUgd2l0aCB0aGUgaXNTVkcgcHJvcGVydHlcbi8vIFByZWZlciB0aGlzIGZ1bmN0aW9uIG92ZXIgcGF0Y2ggdG8gYWxsb3cgZm9yIGNsZWFudXAsIG9uVXBkYXRlIGFuZCBvbk1vdW50IHNldHMgdG8gYmUgY2FsbGVkXG5leHBvcnQgZnVuY3Rpb24gdXBkYXRlVm5vZGUodm5vZGU6IFZub2RlV2l0aERvbSwgb2xkVm5vZGU6IFZub2RlV2l0aERvbSk6IHN0cmluZyB8IHZvaWQge1xuICAvLyBDYWxsIGFueSBjbGVhbnVwIGZ1bmN0aW9ucyB0aGF0IGFyZSByZWdpc3RlcmVkIHdpdGggdGhlIG9uQ2xlYW51cFNldCBzZXRcbiAgY2FsbFNldChvbkNsZWFudXBTZXQpO1xuXG4gIC8vIFJlY3Vyc2l2ZWx5IHBhdGNoIHRoZSBuZXcgYW5kIG9sZCBtYWluIFZub2Rlc1xuICBwYXRjaCh2bm9kZSwgb2xkVm5vZGUpO1xuXG4gIC8vIFNldCB0aGUgb2xkVm5vZGUncyB0YWcsIHByb3BzLCBjaGlsZHJlbiwgZG9tLCBhbmQgaXNTVkcgcHJvcGVydGllcyB0byB0aGUgbmV3Vm5vZGUncyB0YWcsIHByb3BzLCBjaGlsZHJlbiwgZG9tLCBhbmQgaXNTVkcgcHJvcGVydGllc1xuICAvLyBUaGlzIGlzIG5lY2Vzc2FyeSB0byBhbGxvdyBmb3IgdGhlIG9sZFZub2RlIHRvIGJlIHVzZWQgYXMgdGhlIG5ld1Zub2RlIGluIHRoZSBuZXh0IHVwZGF0ZSB3aXRoIHRoZSBub3JtYWwgdXBkYXRlIGZ1bmN0aW9uXG4gIG9sZFZub2RlLnRhZyA9IHZub2RlLnRhZztcbiAgb2xkVm5vZGUucHJvcHMgPSB7IC4uLnZub2RlLnByb3BzIH07XG4gIG9sZFZub2RlLmNoaWxkcmVuID0gWy4uLnZub2RlLmNoaWxkcmVuXTtcbiAgb2xkVm5vZGUuZG9tID0gdm5vZGUuZG9tO1xuICBvbGRWbm9kZS5pc1NWRyA9IHZub2RlLmlzU1ZHO1xuXG4gIC8vIENhbGwgYW55IHVwZGF0ZSBvciBtb3VudCBmdW5jdGlvbnMgdGhhdCBhcmUgcmVnaXN0ZXJlZCB3aXRoIHRoZSBvblVwZGF0ZVNldCBvciBvbk1vdW50U2V0IHNldFxuICBjYWxsU2V0KGlzTW91bnRlZCA/IG9uVXBkYXRlU2V0IDogb25Nb3VudFNldCk7XG5cbiAgLy8gU2V0IHRoZSBpc01vdW50ZWQgZmxhZyB0byB0cnVlXG4gIGlzTW91bnRlZCA9IHRydWU7XG5cbiAgLy8gUmVzZXQgdGhlIGN1cnJlbnQgdm5vZGUsIG9sZFZub2RlLCBhbmQgY29tcG9uZW50IHByb3BlcnRpZXNcbiAgY3VycmVudC52bm9kZSA9IG51bGw7XG4gIGN1cnJlbnQub2xkVm5vZGUgPSBudWxsO1xuICBjdXJyZW50LmNvbXBvbmVudCA9IG51bGw7XG5cbiAgaWYgKGlzTm9kZUpzKSB7XG4gICAgcmV0dXJuIHZub2RlLmRvbS5pbm5lckhUTUw7XG4gIH1cbn1cblxuLy8gVW5tb3VudCB0aGUgbWFpbiBWbm9kZVxuZXhwb3J0IGZ1bmN0aW9uIHVubW91bnQoKSB7XG4gIC8vIElmIHRoZSBtYWluIFZub2RlIGV4aXN0c1xuICBpZiAobWFpblZub2RlKSB7XG4gICAgLy8gU2V0IHRoZSBtYWluIGNvbXBvbmVudCB0byBhIG51bGwgVm5vZGVcbiAgICBtYWluQ29tcG9uZW50ID0gbmV3IFZub2RlKCgpID0+IG51bGwsIHt9LCBbXSkgYXMgVm5vZGVDb21wb25lbnRJbnRlcmZhY2U7XG4gICAgLy8gVXBkYXRlIHRoZSBtYWluIFZub2RlXG4gICAgY29uc3QgcmVzdWx0ID0gdXBkYXRlKCk7XG4gICAgLy8gQ2FsbCBhbnkgdW5tb3VudCBmdW5jdGlvbnMgdGhhdCBhcmUgcmVnaXN0ZXJlZCB3aXRoIHRoZSBvblVubW91bnRTZXQgc2V0XG4gICAgY2FsbFNldChvblVubW91bnRTZXQpO1xuXG4gICAgLy8gUmVtb3ZlIGFueSBldmVudCBsaXN0ZW5lcnMgdGhhdCB3ZXJlIGFkZGVkIHRvIHRoZSBtYWluIFZub2RlJ3MgZG9tIGVsZW1lbnRcbiAgICBmb3IgKGNvbnN0IG5hbWUgaW4gZXZlbnRMaXN0ZW5lck5hbWVzKSB7XG4gICAgICBtYWluVm5vZGUuZG9tLnJlbW92ZUV2ZW50TGlzdGVuZXIobmFtZS5zbGljZSgyKS50b0xvd2VyQ2FzZSgpLCBldmVudExpc3RlbmVyKTtcbiAgICAgIFJlZmxlY3QuZGVsZXRlUHJvcGVydHkoZXZlbnRMaXN0ZW5lck5hbWVzLCBuYW1lKTtcbiAgICB9XG5cbiAgICAvLyBSZXNldCB0aGUgbWFpbiBjb21wb25lbnQgYW5kIG1haW4gVm5vZGVcbiAgICBtYWluQ29tcG9uZW50ID0gbnVsbDtcbiAgICBtYWluVm5vZGUgPSBudWxsO1xuICAgIC8vIFNldCB0aGUgaXNNb3VudGVkIGZsYWcgdG8gZmFsc2VcbiAgICBpc01vdW50ZWQgPSBmYWxzZTtcbiAgICAvLyBSZXNldCB0aGUgY3VycmVudCB2bm9kZSwgb2xkVm5vZGUsIGFuZCBjb21wb25lbnQgcHJvcGVydGllc1xuICAgIGN1cnJlbnQudm5vZGUgPSBudWxsO1xuICAgIGN1cnJlbnQub2xkVm5vZGUgPSBudWxsO1xuICAgIGN1cnJlbnQuY29tcG9uZW50ID0gbnVsbDtcbiAgICAvLyBSZXR1cm4gdGhlIHJlc3VsdCBvZiB1cGRhdGluZyB0aGUgbWFpbiBWbm9kZVxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cbn1cbi8vIFRoaXMgZnVuY3Rpb24gdGFrZXMgaW4gYSBET00gZWxlbWVudCBvciBhIERPTSBlbGVtZW50IHNlbGVjdG9yIGFuZCBhIGNvbXBvbmVudCB0byBiZSBtb3VudGVkIG9uIGl0LlxuZXhwb3J0IGZ1bmN0aW9uIG1vdW50KGRvbTogc3RyaW5nIHwgRG9tRWxlbWVudCwgY29tcG9uZW50OiBhbnkpIHtcbiAgLy8gQ2hlY2sgaWYgdGhlICdkb20nIGFyZ3VtZW50IGlzIGEgc3RyaW5nLiBJZiBpdCBpcywgc2VsZWN0IHRoZSBmaXJzdCBlbGVtZW50IHRoYXQgbWF0Y2hlcyB0aGUgZ2l2ZW4gc2VsZWN0b3IuXG4gIC8vIE90aGVyd2lzZSwgdXNlIHRoZSAnZG9tJyBhcmd1bWVudCBhcyB0aGUgY29udGFpbmVyLlxuICBjb25zdCBjb250YWluZXIgPVxuICAgIHR5cGVvZiBkb20gPT09IFwic3RyaW5nXCJcbiAgICAgID8gaXNOb2RlSnNcbiAgICAgICAgPyBjcmVhdGVEb21FbGVtZW50KGRvbSwgZG9tID09PSBcInN2Z1wiKVxuICAgICAgICA6IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoZG9tKVswXVxuICAgICAgOiBkb207XG5cbiAgLy8gQ2hlY2sgaWYgdGhlICdjb21wb25lbnQnIGFyZ3VtZW50IGlzIGEgVm5vZGUgY29tcG9uZW50IG9yIGEgcmVndWxhciBjb21wb25lbnQuXG4gIC8vIElmIGl0J3MgYSByZWd1bGFyIGNvbXBvbmVudCwgY3JlYXRlIGEgbmV3IFZub2RlIGNvbXBvbmVudCB1c2luZyB0aGUgJ2NvbXBvbmVudCcgYXJndW1lbnQgYXMgdGhlIHRhZy5cbiAgLy8gSWYgaXQncyBub3QgYSBjb21wb25lbnQgYXQgYWxsLCBjcmVhdGUgYSBuZXcgVm5vZGUgY29tcG9uZW50IHdpdGggdGhlICdjb21wb25lbnQnIGFyZ3VtZW50IGFzIHRoZSByZW5kZXJpbmcgZnVuY3Rpb24uXG4gIGNvbnN0IHZub2RlQ29tcG9uZW50ID0gaXNWbm9kZUNvbXBvbmVudChjb21wb25lbnQpXG4gICAgPyBjb21wb25lbnRcbiAgICA6IGlzQ29tcG9uZW50KGNvbXBvbmVudClcbiAgICA/IG5ldyBWbm9kZShjb21wb25lbnQsIHt9LCBbXSlcbiAgICA6IG5ldyBWbm9kZSgoKSA9PiBjb21wb25lbnQsIHt9LCBbXSk7XG5cbiAgLy8gSWYgYSBtYWluIGNvbXBvbmVudCBhbHJlYWR5IGV4aXN0cyBhbmQgaXQncyBub3QgdGhlIHNhbWUgYXMgdGhlIGN1cnJlbnQgJ3Zub2RlQ29tcG9uZW50JywgdW5tb3VudCBpdC5cbiAgaWYgKG1haW5Db21wb25lbnQgJiYgbWFpbkNvbXBvbmVudC50YWcgIT09IHZub2RlQ29tcG9uZW50LnRhZykge1xuICAgIHVubW91bnQoKTtcbiAgfVxuXG4gIC8vIFNldCB0aGUgJ3Zub2RlQ29tcG9uZW50JyBhcyB0aGUgbWFpbiBjb21wb25lbnQuXG4gIG1haW5Db21wb25lbnQgPSB2bm9kZUNvbXBvbmVudCBhcyBWbm9kZUNvbXBvbmVudEludGVyZmFjZTtcbiAgLy8gQ29udmVydCB0aGUgY29udGFpbmVyIGVsZW1lbnQgdG8gYSBWbm9kZS5cbiAgbWFpblZub2RlID0gZG9tVG9Wbm9kZShjb250YWluZXIpO1xuICAvLyBVcGRhdGUgdGhlIERPTSB3aXRoIHRoZSBuZXcgY29tcG9uZW50LlxuICByZXR1cm4gdXBkYXRlKCk7XG59XG5cbi8vIFRoaXMgaXMgYSB1dGlsaXR5IGZ1bmN0aW9uIGZvciBjcmVhdGluZyBWbm9kZSBvYmplY3RzLlxuLy8gSXQgdGFrZXMgaW4gYSB0YWcgb3IgY29tcG9uZW50LCBhbmQgb3B0aW9uYWwgcHJvcHMgYW5kIGNoaWxkcmVuIGFyZ3VtZW50cy5cbmV4cG9ydCBjb25zdCB2OiBWID0gKHRhZ09yQ29tcG9uZW50LCBwcm9wcywgLi4uY2hpbGRyZW4pID0+IHtcbiAgLy8gUmV0dXJuIGEgbmV3IFZub2RlIG9iamVjdCB1c2luZyB0aGUgZ2l2ZW4gYXJndW1lbnRzLlxuICByZXR1cm4gbmV3IFZub2RlKHRhZ09yQ29tcG9uZW50LCBwcm9wcyB8fCB7fSwgY2hpbGRyZW4pO1xufTtcblxuLy8gVGhpcyB1dGlsaXR5IGZ1bmN0aW9uIGNyZWF0ZXMgYSBmcmFnbWVudCBWbm9kZS5cbi8vIEl0IHRha2VzIGluIGEgcGxhY2Vob2xkZXIgYW5kIHRoZSBjaGlsZHJlbiBhcmd1bWVudHMsIHJldHVybnMgb25seSB0aGUgY2hpbGRyZW4uXG52LmZyYWdtZW50ID0gKF86IFZub2RlUHJvcGVydGllcywgLi4uY2hpbGRyZW46IENoaWxkcmVuKSA9PiBjaGlsZHJlbjtcbiJdLCJtYXBwaW5ncyI6Ik1BMkhPLElBQU1BLEVBQVdDLFFBQTJCLG9CQUFaQyxTQUEyQkEsUUFBUUMsVUFBWUQsUUFBUUMsU0FBU0MsTUFJaEcsU0FBU0MsRUFBaUJDLEVBQWFDLEdBQWlCLEdBQzdELE9BQU9BLEVBQVFDLFNBQVNDLGdCQUFnQiw2QkFBOEJILEdBQU9FLFNBQVNFLGNBQWNKLEVBQ3RHLENBTU8sSUFBTUssRUFBUSxTQUFxQ0ws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 \ No newline at end of file diff --git a/dist/index.mjs b/dist/index.mjs index f32d8be..534802a 100644 --- a/dist/index.mjs +++ b/dist/index.mjs @@ -1,5 +1,4 @@ // lib/index.ts -var textTag = "#text"; var isNodeJs = Boolean(typeof process !== "undefined" && process.versions && process.versions.node); function createDomElement(tag, isSVG = false) { return isSVG ? document.createElementNS("http://www.w3.org/2000/svg", tag) : document.createElement(tag); @@ -22,14 +21,14 @@ var isVnodeComponent = (object) => { }; function domToVnode(dom) { if (dom.nodeType === 3) { - const vnode2 = new Vnode(textTag, {}, [dom.nodeValue]); - vnode2.dom = dom; - return vnode2; + return dom.nodeValue; } const children = []; for (let i = 0, l = dom.childNodes.length; i < l; i++) { const childDom = dom.childNodes[i]; - if (childDom.nodeType === 1 || childDom.nodeType === 3) { + if (childDom.nodeType === 3) { + children.push(childDom.nodeValue); + } else if (childDom.nodeType === 1) { children.push(domToVnode(childDom)); } } @@ -118,14 +117,11 @@ function eventListener(e) { var hideDirective = (test) => (bool, vnode, oldnode) => { const value = test ? bool : !bool; if (value) { - const newdom = document.createTextNode(""); - if (oldnode && oldnode.dom && oldnode.dom.parentNode) { - oldnode.dom.parentNode.replaceChild(newdom, oldnode.dom); + const parentNode = vnode.dom?.parentNode; + if (parentNode) { + const newdom = document.createTextNode(""); + parentNode.replaceChild(newdom, vnode.dom); } - vnode.tag = "#text"; - vnode.children = []; - vnode.props = {}; - vnode.dom = newdom; return false; } }; @@ -372,7 +368,6 @@ function patch(newVnode, oldVnode) { newTree.splice(i, 1); newTreeLength = newTree.length; } else { - newTree[i] = new Vnode(textTag, {}, [newChild]); i++; } } @@ -427,31 +422,30 @@ function patch(newVnode, oldVnode) { const newChild = newTree[i2]; const oldChild = oldTree[i2]; const isGreaterThanOldTreeLength = i2 >= oldTreeLength; - if (newChild.tag === textTag) { - if (isGreaterThanOldTreeLength || oldChild.tag !== textTag) { - newChild.dom = document.createTextNode(newChild.children[0]); + if (newChild instanceof Vnode === false) { + if (isGreaterThanOldTreeLength || oldChild instanceof Vnode) { + const dom = document.createTextNode(newChild); if (isGreaterThanOldTreeLength) { - newVnode.dom.appendChild(newChild.dom); + newVnode.dom.appendChild(dom); } else { - newVnode.dom.replaceChild(newChild.dom, oldChild.dom); - } - } else { - newChild.dom = oldChild.dom; - if (newChild.children[0] !== oldChild.dom.textContent) { - oldChild.dom.textContent = newChild.children[0]; + newVnode.dom.replaceChild(dom, newVnode.dom.childNodes[i2]); } + continue; + } + if (newVnode.dom.childNodes[i2].textContent != newChild) { + newVnode.dom.childNodes[i2].textContent = newChild; } continue; } newChild.isSVG = newVnode.isSVG || newChild.tag === "svg"; - if (isGreaterThanOldTreeLength || newChild.tag !== oldChild.tag) { + if (isGreaterThanOldTreeLength || oldChild instanceof Vnode === false || newChild.tag !== oldChild.tag) { newChild.dom = createDomElement(newChild.tag, newChild.isSVG); - updateAttributes(newChild); if (isGreaterThanOldTreeLength) { newVnode.dom.appendChild(newChild.dom); } else { - newVnode.dom.replaceChild(newChild.dom, oldChild.dom); + newVnode.dom.replaceChild(newChild.dom, newVnode.dom.childNodes[i2]); } + updateAttributes(newChild); patch(newChild); continue; } diff --git a/dist/index.mjs.map b/dist/index.mjs.map index c9d4380..185c92d 100644 --- a/dist/index.mjs.map +++ b/dist/index.mjs.map @@ -1,7 +1,7 @@ { "version": 3, "sources": ["../lib/index.ts"], - "sourcesContent": ["/* eslint-disable no-use-before-define */\n/* eslint-disable indent */\n/* eslint-disable sonarjs/cognitive-complexity */\n/* eslint-disable complexity */\n\ninterface DefaultRecord extends Record {}\n\n// The VnodeProperties interface represents properties that can be passed to a virtual node.\nexport interface VnodeProperties extends DefaultRecord {\n // A unique key for the virtual node, which can be a string or a number.\n // This is useful for optimizing updates in a list of nodes.\n key?: string | number;\n // A state object that is associated with the virtual node.\n state?: any;\n}\n\n// The DomElement interface extends the Element interface with an index signature.\n// This allows for any additional properties to be added to DOM elements.\nexport interface DomElement extends Element, DefaultRecord {}\n\n// The VnodeInterface represents a virtual node. It has a number of optional fields,\n// including a tag, props, children, and a DOM element.\nexport interface VnodeInterface extends DefaultRecord {\n // The constructor for the virtual node. It takes a tag, props, and children as arguments.\n // The tag can be a string, a component, or a POJO component.\n // eslint-disable-next-line no-unused-vars\n new (tag: string | Component | POJOComponent, props: VnodeProperties, children: Children): VnodeInterface;\n // The tag for the virtual node. It can be a string, a component, or a POJO component.\n tag: string | Component | POJOComponent;\n // The props for the virtual node.\n props: VnodeProperties;\n // The children for the virtual node.\n children: Children;\n // A boolean indicating whether the virtual node is an SVG element.\n isSVG?: boolean;\n // The DOM element that corresponds to the virtual node.\n dom?: DomElement;\n // A boolean indicating whether the virtual node has been processed in the keyed diffing algorithm.\n processed?: boolean;\n}\n\n// The VnodeWithDom interface represents a virtual node that has a DOM element associated with it.\nexport interface VnodeWithDom extends VnodeInterface {\n dom: DomElement;\n}\n\n// The Component interface represents a function that returns a virtual node or a list of virtual nodes.\n// It can also have additional properties.\nexport interface Component extends DefaultRecord {\n // The function that returns a virtual node or a list of virtual nodes.\n // It can take props and children as arguments.\n // eslint-disable-next-line no-unused-vars\n (props?: VnodeProperties | null, ...children: any[]): VnodeInterface | Children | any;\n}\n\n// The POJOComponent interface represents a \"plain old JavaScript object\" (POJO) component.\n// It has a view function that returns a virtual node or a list of virtual nodes,\n// as well as optional props and children.\n// It can be used also to identify class instance components.\nexport interface POJOComponent extends DefaultRecord {\n // The view function that returns a virtual node or a list of virtual nodes.\n view: Component;\n // The props for the component.\n props?: VnodeProperties | null;\n // The children for the component.\n children?: any[];\n}\n\n// The VnodeComponentInterface represents a virtual node that has a component as its tag.\n// It has props and children, just like a regular virtual node.\nexport interface VnodeComponentInterface extends VnodeInterface {\n tag: Component | POJOComponent;\n props: VnodeProperties;\n children: Children;\n}\n\n// The Children interface represents a list of virtual nodes or other values.\nexport interface Children extends Array {}\n\n// The Directive interface represents a function that can be applied to a virtual node.\n// It receives the value, virtual node, and old virtual node as arguments, and can return a boolean value.\n// If only the virtual node is passed, it means its the on create phase for the v-node.\n// If the old virtual node is also passed, it means its the on update phase for the v-node.\nexport interface Directive {\n // eslint-disable-next-line no-unused-vars\n (value: any, vnode: VnodeWithDom, oldVnode?: VnodeWithDom): void | boolean;\n}\n\n// The Directives interface is a mapping of directive names to Directive functions.\nexport interface Directives extends Record {}\n\n// The ReservedProps interface is a mapping of reserved prop names to the value `true`.\n// These prop names cannot be used as custom prop names.\nexport interface ReservedProps extends Record {}\n\n// The Current interface represents the current component and virtual node that are being processed.\nexport interface Current {\n // The current component. It can be a component, a POJO component, or null.\n component: Component | POJOComponent | null;\n // The current virtual node. It must have a DOM element associated with it.\n vnode: VnodeWithDom | null;\n // The old virtual node. It must have a DOM element associated with it.\n oldVnode?: VnodeWithDom | null;\n // The current event. It can be an event or null.\n event: Event | null;\n}\n\n// The V function is the main function for creating virtual nodes.\n// It takes a tag or component, props, and children as arguments, and returns a virtual node.\nexport interface V {\n // eslint-disable-next-line no-unused-vars, no-use-before-define\n (tagOrComponent: string | Component | POJOComponent, props: VnodeProperties | null, ...children: Children):\n | VnodeInterface\n | VnodeComponentInterface;\n // eslint-disable-next-line no-unused-vars, no-use-before-define\n fragment(_: any, ...children: Children): Children;\n}\n\n// 'textTag' is a constant string that is used to represent text nodes in the virtual DOM.\nconst textTag = \"#text\";\n\n// 'isNodeJs' is a boolean that is true if the code is running in a Node.js environment and false otherwise.\n// It is determined by checking if the 'process' global object is defined and has a 'versions' property.\nexport const isNodeJs = Boolean(typeof process !== \"undefined\" && process.versions && process.versions.node);\n\n// 'createDomElement' is a function that creates a new DOM element with the specified tag name.\n// If 'isSVG' is true, it creates an SVG element instead of a regular DOM element.\nexport function createDomElement(tag: string, isSVG: boolean = false): DomElement {\n return isSVG ? document.createElementNS(\"http://www.w3.org/2000/svg\", tag) : document.createElement(tag);\n}\n\n// 'Vnode' is a class that represents a virtual DOM node.\n// It has three properties: 'tag', 'props', and 'children'.\n// 'Vnode' is exported as an object with a type of 'VnodeInterface'.\n// The 'as unknown as VnodeInterface' is used to tell TypeScript that the 'Vnode' function has the same type as 'VnodeInterface'.\nexport const Vnode = function Vnode(this: VnodeInterface, tag: string, props: VnodeProperties, children: Children) {\n // 'this' refers to the current instance of 'Vnode'.\n this.tag = tag;\n this.props = props;\n this.children = children;\n} as unknown as VnodeInterface;\n\n// 'isComponent' is a function that returns true if the given 'component' is a valid component and false otherwise.\n// A component is either a function or an object with a 'view' function.\nexport function isComponent(component: unknown): component is Component {\n return Boolean(\n component && (typeof component === \"function\" || (typeof component === \"object\" && \"view\" in component))\n );\n}\n\n// 'isVnode' is a function that returns true if the given 'object' is a 'Vnode' instance and false otherwise.\nexport const isVnode = (object?: unknown | VnodeInterface): object is VnodeInterface => {\n // Use the 'instanceof' operator to check if 'object' is an instance of 'Vnode'.\n return object instanceof Vnode;\n};\n\n// 'isVnodeComponent' is a function that returns true if the given 'object' is a 'Vnode' instance with a 'tag' property that is a valid component.\n// It returns false otherwise.\nexport const isVnodeComponent = (object?: unknown | VnodeComponentInterface): object is VnodeComponentInterface => {\n // Check if 'object' is a 'Vnode' instance and its 'tag' property is a valid component.\n return isVnode(object) && isComponent(object.tag);\n};\n\n// 'domToVnode' is a function that converts a DOM node to a 'Vnode' instance.\nexport function domToVnode(dom: any): VnodeWithDom {\n // If the child node is a text node, create a 'Vnode' instance with the 'textTag' constant as the 'tag' property.\n // Set the 'dom' property of the 'Vnode' instance to the child DOM node.\n // Push the 'Vnode' instance to the 'children' array.\n if (dom.nodeType === 3) {\n const vnode = new Vnode(textTag, {}, [dom.nodeValue]);\n vnode.dom = dom;\n return vnode as VnodeWithDom;\n }\n\n const children: VnodeWithDom[] = [];\n // Iterate through all child nodes of 'dom'.\n for (let i = 0, l = dom.childNodes.length; i < l; i++) {\n const childDom = dom.childNodes[i];\n // If the child node is an element node, recursively call 'domToVnode' to convert it to a 'Vnode' instance.\n // Push the 'Vnode' instance to the 'children' array.\n if (childDom.nodeType === 1 || childDom.nodeType === 3) {\n children.push(domToVnode(childDom));\n }\n }\n\n const props: VnodeProperties = {};\n // Iterate through all attributes of 'dom'.\n for (let i = 0, l = dom.attributes.length; i < l; i++) {\n const attr = dom.attributes[i];\n // Add the attribute to the 'props' object, using the attribute's name as the key and its value as the value.\n props[attr.nodeName] = attr.nodeValue;\n }\n\n // Create a new 'Vnode' instance with the 'tag' property set to the lowercase version of the DOM node's tag name.\n // Set the 'props' and 'children' properties to the 'props' and 'children' arrays respectively.\n // Set the 'dom' property of the 'Vnode' instance to the DOM node.\n const vnode = new Vnode(dom.tagName.toLowerCase(), props, children);\n vnode.dom = dom;\n return vnode as VnodeWithDom;\n}\n\n// This function takes in an HTML string and creates a virtual node representation of it\n// using the `domToVnode` function. It does this by creating a new `div` element, setting\n// its `innerHTML` to the provided HTML string, and then using `map` to iterate over the\n// `childNodes` of the `div` element, passing each one to `domToVnode` to create a virtual\n// node representation of it. The resulting array of virtual nodes is then returned.\nexport function trust(htmlString: string) {\n const div = createDomElement(\"div\");\n div.innerHTML = htmlString.trim();\n\n return [].map.call(div.childNodes, (item) => domToVnode(item));\n}\n\n/* ========================================================================== */\n/* Main Component implementation */\n/* ========================================================================== */\n\n// These variables are used to store the main component, the main virtual node, and whether\n// the main component is currently mounted.\nlet mainComponent: VnodeComponentInterface | null = null;\nlet mainVnode: VnodeWithDom | null = null;\nlet isMounted = false;\n\n// This object is used to store the current virtual node and component being rendered.\nexport const current: Current = {\n vnode: null,\n oldVnode: null,\n component: null,\n event: null\n};\n\n/* Reserved props ----------------------------------------------------------- */\n// This object is used to store the names of reserved props, which are props that are reserved\n// for special purposes and should not be used as regular component props.\nexport const reservedProps: Record = {\n key: true,\n state: true,\n \"v-keep\": true,\n\n // Built in directives\n \"v-if\": true,\n \"v-unless\": true,\n \"v-for\": true,\n \"v-show\": true,\n \"v-class\": true,\n \"v-html\": true,\n \"v-model\": true,\n \"v-create\": true,\n \"v-update\": true,\n \"v-cleanup\": true\n};\n\n/* Mounting, Updating, Cleanup and Unmounting ------------------------------- */\n// These sets are used to store callbacks for various lifecycle events: mounting, updating,\n// cleaning up, and unmounting.\nconst onCleanupSet: Set = new Set();\nconst onMountSet: Set = new Set();\nconst onUpdateSet: Set = new Set();\nconst onUnmountSet: Set = new Set();\n\n// These functions allow users to register callbacks for the corresponding lifecycle events.\nexport function onMount(callback: Function) {\n if (!isMounted) {\n onMountSet.add(callback);\n }\n}\n\nexport function onUpdate(callback: Function) {\n onUpdateSet.add(callback);\n}\n\nexport function onCleanup(callback: Function) {\n onCleanupSet.add(callback);\n}\n\nexport function onUnmount(callback: Function) {\n if (!isMounted) {\n onUnmountSet.add(callback);\n }\n}\n\n// This function is used to call all the callbacks in a given set.\nfunction callSet(set: Set) {\n for (const callback of set) {\n callback();\n }\n\n set.clear();\n}\n\n/* Event listener ----------------------------------------------------------- */\n\n// This object stores the names of event listeners that have been added\nconst eventListenerNames: Record = {};\n\n// This function is called when an event occurs\nfunction eventListener(e: Event) {\n // Set the current event to the event that occurred so that it can be prevented if necessary\n current.event = e;\n\n // Convert the target of the event to a DOM element\n let dom = e.target as DomElement;\n\n // Create the name of the event listener by adding \"v-on\" to the event type\n const name = `v-on${e.type}`;\n\n // Keep going up the DOM tree until we find an element with an event listener\n // matching the event type\n while (dom) {\n if (dom[name]) {\n // Call the event listener function\n dom[name](e, dom);\n\n // If the default action of the event hasn't been prevented, update the DOM\n if (!e.defaultPrevented) {\n update();\n }\n return;\n }\n dom = dom.parentNode as DomElement;\n }\n\n current.event = null;\n}\n\n/* Directives --------------------------------------------------------------- */\n\n// This function creates a directive that hides an element based on a condition\nconst hideDirective = (test: boolean) => (bool: boolean, vnode: VnodeInterface, oldnode?: VnodeInterface) => {\n // If test is true, use the value of bool. Otherwise, use the opposite of bool.\n const value = test ? bool : !bool;\n\n // If the value is true, hide the element by replacing it with a text node\n if (value) {\n const newdom = document.createTextNode(\"\");\n if (oldnode && oldnode.dom && oldnode.dom.parentNode) {\n oldnode.dom.parentNode.replaceChild(newdom, oldnode.dom);\n }\n vnode.tag = \"#text\";\n vnode.children = [];\n vnode.props = {};\n vnode.dom = newdom as unknown as DomElement;\n return false;\n }\n};\n\n// This object stores all the available directives\nexport const directives: Directives = {\n // The \"v-if\" directive hides an element if the given condition is false\n \"v-if\": hideDirective(false),\n\n // The \"v-unless\" directive hides an element if the given condition is true\n \"v-unless\": hideDirective(true),\n\n // The \"v-for\" directive creates a loop and applies a callback function to each item in the loop\n \"v-for\": (set: unknown[], vnode: VnodeWithDom) => {\n const newChildren: VnodeInterface[] = [];\n const callback = vnode.children[0];\n for (let i = 0, l = set.length; i < l; i++) {\n newChildren.push(callback(set[i], i));\n }\n vnode.children = newChildren;\n },\n\n // The \"v-show\" directive shows or hides an element by setting the \"display\" style property\n \"v-show\": (bool: boolean, vnode: VnodeWithDom) => {\n (\n vnode.dom as unknown as {\n style: { display: string };\n }\n ).style.display = bool ? \"\" : \"none\";\n },\n\n // The \"v-class\" directive adds or removes class names from an element based on a condition\n \"v-class\": (classes: { [x: string]: boolean }, vnode: VnodeWithDom) => {\n // Loop through all the class names in the classes object\n for (const name in classes) {\n // Add or remove the class name from the element's class list based on the value in the classes object\n (vnode.dom as DomElement).classList.toggle(name, classes[name]);\n }\n },\n\n // The \"v-html\" directive sets the inner HTML of an element to the given HTML string\n \"v-html\": (html: string, vnode: VnodeWithDom) => {\n // Set the children of the vnode to a trusted version of the HTML string\n vnode.children = [trust(html)];\n },\n\n // The \"v-model\" directive binds the value of an input element to a model property\n \"v-model\": ([model, property, event]: any[], vnode: VnodeWithDom, oldVnode?: VnodeWithDom) => {\n let value;\n // This function updates the model property when the input element's value changes\n let handler = (e: Event) => (model[property] = (e.target as DomElement & Record).value);\n if (vnode.tag === \"input\") {\n // If the element is an input, use the \"input\" event by default\n event = event || \"oninput\";\n // Depending on the type of input element, use a different handler function\n switch (vnode.props.type) {\n case \"checkbox\": {\n if (Array.isArray(model[property])) {\n // If the model property is an array, add or remove the value from the array when the checkbox is checked or unchecked\n handler = (e: Event) => {\n const val = (e.target as DomElement & Record).value;\n const idx = model[property].indexOf(val);\n if (idx === -1) {\n model[property].push(val);\n } else {\n model[property].splice(idx, 1);\n }\n };\n // If the value is in the array, set the checkbox to be checked\n value = model[property].indexOf(vnode.dom.value) !== -1;\n } else if (\"value\" in vnode.props) {\n // If the input element has a \"value\" attribute, use it to determine the checked state\n handler = () => {\n if (model[property] === vnode.props.value) {\n model[property] = null;\n } else {\n model[property] = vnode.props.value;\n }\n };\n value = model[property] === vnode.props.value;\n } else {\n // If there is no \"value\" attribute, use a boolean value for the model property\n handler = () => (model[property] = !model[property]);\n value = model[property];\n }\n // Set the \"checked\" attribute on the input element\n // eslint-disable-next-line no-use-before-define\n sharedSetAttribute(\"checked\", value, vnode);\n break;\n }\n case \"radio\": {\n // If the element is a radio button, set the \"checked\" attribute based on the value of the model property\n // eslint-disable-next-line no-use-before-define\n sharedSetAttribute(\"checked\", model[property] === vnode.dom.value, vnode);\n break;\n }\n default: {\n // For all other input types, set the \"value\" attribute based on the value of the model property\n // eslint-disable-next-line no-use-before-define\n sharedSetAttribute(\"value\", model[property], vnode);\n }\n }\n } else if (vnode.tag === \"select\") {\n // If the element is a select element, use the \"click\" event by default\n event = event || \"onclick\";\n if (vnode.props.multiple) {\n // If the select element allows multiple selections, update the model property with an array of selected values\n handler = (e: Event & Record) => {\n const val = (e.target as DomElement & Record).value;\n if (e.ctrlKey) {\n // If the Ctrl key is pressed, add or remove the value from the array\n const idx = model[property].indexOf(val);\n if (idx === -1) {\n model[property].push(val);\n } else {\n model[property].splice(idx, 1);\n }\n } else {\n // If the Ctrl key is not pressed, set the model property to an array with the selected value\n model[property].splice(0, model[property].length);\n model[property].push(val);\n }\n };\n // Set the \"selected\" attribute on the options based on whether they are in the model property array\n vnode.children.forEach((child: VnodeInterface) => {\n if (child.tag === \"option\") {\n const value = \"value\" in child.props ? child.props.value : child.children.join(\"\").trim();\n child.props.selected = model[property].indexOf(value) !== -1;\n }\n });\n } else {\n // If the select element does not allow multiple selections, set the \"selected\" attribute on the options based on the value of the model property\n vnode.children.forEach((child: VnodeInterface) => {\n if (child.tag === \"option\") {\n const value = \"value\" in child.props ? child.props.value : child.children.join(\"\").trim();\n child.props.selected = value === model[property];\n }\n });\n }\n } else if (vnode.tag === \"textarea\") {\n // If the element is a textarea, use the \"input\" event by default\n event = event || \"oninput\";\n // Set the textarea's content to the value of the model property\n vnode.children = [model[property]];\n }\n\n // We assume that the prev handler if any will not be changed by the user across patchs\n const prevHandler = vnode.props[event];\n\n // Set the event handler on the element\n // eslint-disable-next-line no-use-before-define\n sharedSetAttribute(\n event,\n (e: Event) => {\n handler(e);\n\n // If the previous handler is defined, call it after the model has been updated\n if (prevHandler) {\n prevHandler(e);\n }\n },\n vnode,\n oldVnode\n );\n },\n\n // The \"v-create\" directive is called when a new virtual node is created.\n // The provided callback function is called with the new virtual node as an argument.\n // This directive is only called once per virtual node, when it is first created.\n // eslint-disable-next-line no-unused-vars\n \"v-create\": (callback: (vnode: VnodeWithDom) => void, vnode: VnodeWithDom, oldVnode?: VnodeWithDom) => {\n // If this is not an update, call the callback function with the new virtual node\n if (!oldVnode) {\n const cleanup = callback(vnode);\n\n // If the callback function returns a function, call it when the update is gonna be cleaned up\n if (typeof cleanup === \"function\") {\n onCleanup(cleanup);\n }\n }\n },\n\n // The \"v-update\" directive is called when an existing virtual node is updated.\n // The provided callback function is called with the new and old virtual nodes as arguments.\n // This directive is only called once per virtual node update.\n \"v-update\": (\n // eslint-disable-next-line no-unused-vars\n callback: (vnode: VnodeWithDom, oldVnode: VnodeWithDom) => void,\n vnode: VnodeWithDom,\n oldVnode?: VnodeWithDom\n ) => {\n // If this is an update, call the callback function with the new and old virtual nodes\n if (oldVnode) {\n const cleanup = callback(vnode, oldVnode);\n\n // If the callback function returns a function, call it when the update is gonna be cleaned up\n if (typeof cleanup === \"function\") {\n onCleanup(cleanup);\n }\n }\n },\n\n // The \"v-cleanup\" directive is called when the update is cleaned up.\n // The provided callback function is called with the old virtual node as an argument.\n // This directive is only called once per virtual node, when the update is cleaned up.\n \"v-cleanup\": (\n // eslint-disable-next-line no-unused-vars\n callback: (vnode: VnodeWithDom, oldVnode?: VnodeWithDom) => void,\n vnode: VnodeWithDom,\n oldVnode?: VnodeWithDom\n ) => {\n // Add the callback function to the list of cleanup functions to be called when the update is cleaned up\n onCleanup(() => callback(vnode, oldVnode));\n }\n};\n// Add a directive to the global directives object, with the key being the name\n// preceded by \"v-\". Also add the name to the global reservedProps object.\nexport function directive(name: string, directive: Directive) {\n const directiveName = `v-${name}`;\n directives[directiveName] = directive;\n reservedProps[directiveName] = true;\n}\n\n// Set an attribute on a virtual DOM node and update the actual DOM element.\n// If the attribute value is a function, add an event listener for the attribute\n// name to the DOM element represented by mainVnode.\n// If oldVnode is provided, compare the new attribute value to the old value\n// and only update the attribute if the values are different.\nfunction sharedSetAttribute(name: string, value: any, newVnode: VnodeWithDom, oldVnode?: VnodeWithDom): void | boolean {\n // If the attribute value is a function, add an event listener for the attribute\n // name to the DOM element represented by mainVnode.\n if (typeof value === \"function\") {\n // Only add the event listener if it hasn't been added yet.\n if (name in eventListenerNames === false) {\n (mainVnode as VnodeWithDom).dom.addEventListener(name.slice(2), eventListener);\n eventListenerNames[name] = true;\n }\n newVnode.dom[`v-${name}`] = value;\n return;\n }\n\n // If the attribute is present on the DOM element and newVnode is not an SVG,\n // update the attribute if the value has changed.\n if (newVnode.isSVG === false && name in newVnode.dom) {\n // eslint-disable-next-line eqeqeq\n if (newVnode.dom[name] != value) {\n newVnode.dom[name] = value;\n }\n return;\n }\n\n // If oldVnode is not provided or the attribute value has changed, update the\n // attribute on the DOM element.\n if (!oldVnode || value !== oldVnode.props[name]) {\n if (value === false) {\n newVnode.dom.removeAttribute(name);\n } else {\n newVnode.dom.setAttribute(name, value);\n }\n }\n}\n\n// Set an attribute on a virtual DOM node and update the actual DOM element.\n// Skip the attribute if it is in the reservedProps object.\nexport function setAttribute(name: string, value: any, newVnode: VnodeWithDom, oldVnode?: VnodeWithDom): void {\n if (reservedProps[name]) {\n return;\n }\n newVnode.props[name] = value;\n sharedSetAttribute(name, value, newVnode, oldVnode);\n}\n\n// Update the attributes on a virtual DOM node. If oldVnode is provided, remove\n// attributes from the DOM element that are not present in newVnode.props but are\n// present in oldVnode.props. Then, iterate over the attributes in newVnode.props\n// and update the DOM element with the attributes using the sharedSetAttribute\n// function. If an attribute is in the reservedProps object and has a corresponding\n// directive in the directives object, call the directive with the attribute value\n// and the two virtual DOM nodes as arguments. If the directive returns false, exit\n// the loop.\nexport function updateAttributes(newVnode: VnodeWithDom, oldVnode?: VnodeWithDom): void {\n // If oldVnode is provided, remove attributes from the DOM element that are not\n // present in newVnode.props but are present in oldVnode.props.\n if (oldVnode) {\n for (const name in oldVnode.props) {\n if (!newVnode.props[name] && !eventListenerNames[name] && !reservedProps[name]) {\n if (newVnode.isSVG === false && name in newVnode.dom) {\n newVnode.dom[name] = null;\n } else {\n newVnode.dom.removeAttribute(name);\n }\n }\n }\n }\n\n // Iterate over the attributes in newVnode.props and update the DOM element with\n // the attributes using the sharedSetAttribute function.\n for (const name in newVnode.props) {\n if (reservedProps[name]) {\n // If there is a directive for the attribute, call it with the attribute value\n // and the two virtual DOM nodes as arguments. If the directive returns false,\n // exit the loop.\n if (directives[name] && directives[name](newVnode.props[name], newVnode, oldVnode) === false) {\n break;\n }\n continue;\n }\n sharedSetAttribute(name, newVnode.props[name], newVnode, oldVnode);\n }\n}\n\n/* patch ------------------------------------------------------------------- */\n\n// Patch a DOM node with a new VNode tree\nexport function patch(newVnode: VnodeWithDom, oldVnode?: VnodeWithDom): void {\n // If the new tree has no children, set the text content of the parent DOM element to an empty string\n if (newVnode.children.length === 0) {\n newVnode.dom.textContent = \"\";\n return;\n }\n\n // Get the children of the new and old virtual DOM nodes\n const newTree = newVnode.children;\n const oldTree = oldVnode?.children || [];\n // Get the length of the old tree\n const oldTreeLength = oldTree.length;\n // Get the length of the new tree\n let newTreeLength = newTree.length;\n // Set the global current object to the new and old virtual DOM nodes\n current.vnode = newVnode;\n current.oldVnode = oldVnode;\n\n // Flatten the new tree\n // Take into account that is necessary to flatten the tree before the patch process\n // to let the hooks and signals work properly\n let i = 0;\n while (i < newTreeLength) {\n const newChild = newTree[i];\n\n // If the new child is a Vnode and is not a text node\n if (newChild instanceof Vnode) {\n // If the tag of the new child is not a string, it is a component\n if (typeof newChild.tag !== \"string\") {\n // Set the current component to the tag of the new child\n current.component = newChild.tag;\n // Replace the new child with the result of calling its view or bind method, passing in the props and children as arguments\n newTree.splice(\n i,\n 1,\n (\"view\" in newChild.tag ? newChild.tag.view.bind(newChild.tag) : newChild.tag.bind(newChild.tag))(\n newChild.props,\n ...newChild.children\n )\n );\n newTreeLength = newTree.length;\n continue;\n } else {\n i++;\n }\n // If the new child is an array, flatten it and continue the loop\n } else if (Array.isArray(newChild)) {\n newTree.splice(i, 1, ...newChild);\n newTreeLength = newTree.length;\n // If the new child is null or undefined, remove it from the new tree and continue the loop\n } else if (newChild == null) {\n newTree.splice(i, 1);\n newTreeLength = newTree.length;\n } else {\n // If the new child is a Vnode, set the text of the Vnode to the text content of its dom property\n newTree[i] = new Vnode(textTag, {}, [newChild]);\n i++;\n }\n }\n\n // If the new tree has no children, set the text content of the parent DOM element to an empty string\n if (newTreeLength === 0) {\n newVnode.dom.textContent = \"\";\n return;\n }\n\n // If the old tree has children and the first child of the new tree is a VNode with a \"key\"\n // attribute and the first child of the old tree is a VNode with a \"key\" attribute, update\n // the DOM element in place by comparing the keys of the nodes in the trees.\n if (\n oldTreeLength > 0 &&\n newTree[0] instanceof Vnode &&\n oldTree[0] instanceof Vnode &&\n \"key\" in newTree[0].props &&\n \"key\" in oldTree[0].props\n ) {\n const oldKeyedList: Record = {};\n const newKeyedList: Record = {};\n const childNodes = newVnode.dom.childNodes;\n\n // Create key maps while also handling removal of nodes not present in newTree\n for (let i = 0; i < oldTreeLength; i++) {\n oldKeyedList[oldTree[i].props.key] = i;\n if (i < newTreeLength) {\n newKeyedList[newTree[i].props.key] = i;\n }\n }\n\n for (let i = 0; i < newTreeLength; i++) {\n const newChild = newTree[i];\n const oldChildIndex = oldKeyedList[newChild.props.key];\n const oldChild = oldTree[oldChildIndex];\n let shouldPatch = true;\n\n if (oldChild) {\n newChild.dom = oldChild.dom;\n if (\"v-keep\" in newChild.props && newChild.props[\"v-keep\"] === oldChild.props[\"v-keep\"]) {\n newChild.children = oldChild.children;\n shouldPatch = false;\n } else {\n updateAttributes(newChild, oldChild);\n }\n } else {\n newChild.dom = createDomElement(newChild.tag, newChild.isSVG);\n updateAttributes(newChild);\n }\n\n const currentNode = childNodes[i];\n if (!currentNode) {\n newVnode.dom.appendChild(newChild.dom);\n } else if (currentNode !== newChild.dom) {\n newVnode.dom.replaceChild(newChild.dom, currentNode);\n }\n\n shouldPatch && patch(newChild, oldChild);\n }\n\n // Remove nodes that don't exist in newTree\n for (let i = newTreeLength; i < oldTreeLength; i++) {\n if (!newKeyedList[oldTree[i].props.key]) {\n const domToRemove = oldTree[i].dom;\n domToRemove.parentNode && domToRemove.parentNode.removeChild(domToRemove);\n }\n }\n return;\n }\n\n // Patch the the old tree\n for (let i = 0; i < newTreeLength; i++) {\n const newChild = newTree[i];\n const oldChild = oldTree[i];\n const isGreaterThanOldTreeLength = i >= oldTreeLength;\n\n // Handle text nodes\n if (newChild.tag === textTag) {\n // If there's no corresponding old child or the old child isn't a text node\n if (isGreaterThanOldTreeLength || oldChild.tag !== textTag) {\n newChild.dom = document.createTextNode(newChild.children[0]); // Create a new text node\n if (isGreaterThanOldTreeLength) {\n // If there's no corresponding old child, append the new text node\n newVnode.dom.appendChild(newChild.dom);\n } else {\n // Replace the old non-text node with the new text node\n newVnode.dom.replaceChild(newChild.dom, oldChild.dom);\n }\n } else {\n // Update the old text node if content has changed\n newChild.dom = oldChild.dom;\n if (newChild.children[0] !== oldChild.dom.textContent) {\n oldChild.dom.textContent = newChild.children[0];\n }\n }\n continue;\n }\n\n // If the new child is not a text node\n // Set the isSVG flag for the new child if it is an SVG element or if the parent is an SVG element\n newChild.isSVG = newVnode.isSVG || newChild.tag === \"svg\";\n\n // If the tag of the new child is different from the tag of the old child\n if (isGreaterThanOldTreeLength || newChild.tag !== oldChild.tag) {\n // Create a new dom element for the new child\n newChild.dom = createDomElement(newChild.tag as string, newChild.isSVG);\n // Update the attributes of the new child\n updateAttributes(newChild as VnodeWithDom);\n if (isGreaterThanOldTreeLength) {\n // Append the new child to the dom\n newVnode.dom.appendChild(newChild.dom);\n } else {\n // Replace the old child in the dom with the new child\n newVnode.dom.replaceChild(newChild.dom, oldChild.dom);\n }\n // Recursively patch the new child\n patch(newChild as VnodeWithDom);\n continue;\n }\n\n // If the tag of the new child is the same as the tag of the old child\n // Set the dom property of the new child to the dom property of the old child\n newChild.dom = oldChild.dom;\n // If the v-keep prop is the same for both the new and old child, set the children of the new child to the children of the old child\n if (\"v-keep\" in newChild.props && newChild.props[\"v-keep\"] === oldChild.props[\"v-keep\"]) {\n newChild.children = oldChild.children;\n continue;\n }\n\n // Update the attributes of the new child based on the old child\n updateAttributes(newChild as VnodeWithDom, oldChild);\n // Recursively patch the new and old children\n patch(newChild as VnodeWithDom, oldChild);\n }\n\n // Remove any old children that are no longer present in the new tree\n for (; newTreeLength < oldTreeLength; newTreeLength++) {\n newVnode.dom.removeChild(oldTree[newTreeLength].dom);\n }\n}\n\n// Update the main Vnode\nexport function update(): void | string {\n // If the main Vnode exists\n if (mainVnode) {\n // Call any cleanup functions that are registered with the onCleanupSet set\n callSet(onCleanupSet);\n // Store a reference to the old main Vnode\n const oldMainVnode = mainVnode;\n // Create a new main Vnode with the main component as its only child\n mainVnode = new Vnode(oldMainVnode.tag, oldMainVnode.props, [mainComponent]) as VnodeWithDom;\n mainVnode.dom = oldMainVnode.dom;\n mainVnode.isSVG = oldMainVnode.isSVG;\n\n // Recursively patch the new and old main Vnodes\n patch(mainVnode, oldMainVnode);\n\n // Call any update or mount functions that are registered with the onUpdateSet or onMountSet set\n callSet(isMounted ? onUpdateSet : onMountSet);\n\n // Set the isMounted flag to true\n isMounted = true;\n\n // Reset the current vnode, oldVnode, and component properties\n current.vnode = null;\n current.oldVnode = null;\n current.component = null;\n\n // If the code is running in a Node.js environment, return the inner HTML of the main Vnode's dom element\n if (isNodeJs) {\n return mainVnode.dom.innerHTML;\n }\n }\n}\n\n// Update custom Vnode\n// It is assumed that a first mount has already occurred, so,\n// the oldVnode is not null and the dom property of the oldVnode is not null\n// You need to set the dom property of the newVnode to the dom property of the oldVnode\n// The same with the isSVG property\n// Prefer this function over patch to allow for cleanup, onUpdate and onMount sets to be called\nexport function updateVnode(vnode: VnodeWithDom, oldVnode: VnodeWithDom): string | void {\n // Call any cleanup functions that are registered with the onCleanupSet set\n callSet(onCleanupSet);\n\n // Recursively patch the new and old main Vnodes\n patch(vnode, oldVnode);\n\n // Set the oldVnode's tag, props, children, dom, and isSVG properties to the newVnode's tag, props, children, dom, and isSVG properties\n // This is necessary to allow for the oldVnode to be used as the newVnode in the next update with the normal update function\n oldVnode.tag = vnode.tag;\n oldVnode.props = { ...vnode.props };\n oldVnode.children = [...vnode.children];\n oldVnode.dom = vnode.dom;\n oldVnode.isSVG = vnode.isSVG;\n\n // Call any update or mount functions that are registered with the onUpdateSet or onMountSet set\n callSet(isMounted ? onUpdateSet : onMountSet);\n\n // Set the isMounted flag to true\n isMounted = true;\n\n // Reset the current vnode, oldVnode, and component properties\n current.vnode = null;\n current.oldVnode = null;\n current.component = null;\n\n if (isNodeJs) {\n return vnode.dom.innerHTML;\n }\n}\n\n// Unmount the main Vnode\nexport function unmount() {\n // If the main Vnode exists\n if (mainVnode) {\n // Set the main component to a null Vnode\n mainComponent = new Vnode(() => null, {}, []) as VnodeComponentInterface;\n // Update the main Vnode\n const result = update();\n // Call any unmount functions that are registered with the onUnmountSet set\n callSet(onUnmountSet);\n\n // Remove any event listeners that were added to the main Vnode's dom element\n for (const name in eventListenerNames) {\n mainVnode.dom.removeEventListener(name.slice(2).toLowerCase(), eventListener);\n Reflect.deleteProperty(eventListenerNames, name);\n }\n\n // Reset the main component and main Vnode\n mainComponent = null;\n mainVnode = null;\n // Set the isMounted flag to false\n isMounted = false;\n // Reset the current vnode, oldVnode, and component properties\n current.vnode = null;\n current.oldVnode = null;\n current.component = null;\n // Return the result of updating the main Vnode\n return result;\n }\n}\n// This function takes in a DOM element or a DOM element selector and a component to be mounted on it.\nexport function mount(dom: string | DomElement, component: any) {\n // Check if the 'dom' argument is a string. If it is, select the first element that matches the given selector.\n // Otherwise, use the 'dom' argument as the container.\n const container =\n typeof dom === \"string\"\n ? isNodeJs\n ? createDomElement(dom, dom === \"svg\")\n : document.querySelectorAll(dom)[0]\n : dom;\n\n // Check if the 'component' argument is a Vnode component or a regular component.\n // If it's a regular component, create a new Vnode component using the 'component' argument as the tag.\n // If it's not a component at all, create a new Vnode component with the 'component' argument as the rendering function.\n const vnodeComponent = isVnodeComponent(component)\n ? component\n : isComponent(component)\n ? new Vnode(component, {}, [])\n : new Vnode(() => component, {}, []);\n\n // If a main component already exists and it's not the same as the current 'vnodeComponent', unmount it.\n if (mainComponent && mainComponent.tag !== vnodeComponent.tag) {\n unmount();\n }\n\n // Set the 'vnodeComponent' as the main component.\n mainComponent = vnodeComponent as VnodeComponentInterface;\n // Convert the container element to a Vnode.\n mainVnode = domToVnode(container);\n // Update the DOM with the new component.\n return update();\n}\n\n// This is a utility function for creating Vnode objects.\n// It takes in a tag or component, and optional props and children arguments.\nexport const v: V = (tagOrComponent, props, ...children) => {\n // Return a new Vnode object using the given arguments.\n return new Vnode(tagOrComponent, props || {}, children);\n};\n\n// This utility function creates a fragment Vnode.\n// It takes in a placeholder and the children arguments, returns only the children.\nv.fragment = (_: VnodeProperties, ...children: Children) => children;\n"], - "mappings": "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", - "names": ["Vnode", "vnode", "value", "directive", "i"] + "sourcesContent": ["/* eslint-disable no-use-before-define */\n/* eslint-disable indent */\n/* eslint-disable sonarjs/cognitive-complexity */\n/* eslint-disable complexity */\n\ninterface DefaultRecord extends Record {}\n\n// The VnodeProperties interface represents properties that can be passed to a virtual node.\nexport interface VnodeProperties extends DefaultRecord {\n // A unique key for the virtual node, which can be a string or a number.\n // This is useful for optimizing updates in a list of nodes.\n key?: string | number;\n // A state object that is associated with the virtual node.\n state?: any;\n}\n\n// The DomElement interface extends the Element interface with an index signature.\n// This allows for any additional properties to be added to DOM elements.\nexport interface DomElement extends Element, DefaultRecord {}\n\n// The VnodeInterface represents a virtual node. It has a number of optional fields,\n// including a tag, props, children, and a DOM element.\nexport interface VnodeInterface extends DefaultRecord {\n // The constructor for the virtual node. It takes a tag, props, and children as arguments.\n // The tag can be a string, a component, or a POJO component.\n // eslint-disable-next-line no-unused-vars\n new (tag: string | Component | POJOComponent, props: VnodeProperties, children: Children): VnodeInterface;\n // The tag for the virtual node. It can be a string, a component, or a POJO component.\n tag: string | Component | POJOComponent;\n // The props for the virtual node.\n props: VnodeProperties;\n // The children for the virtual node.\n children: Children;\n // A boolean indicating whether the virtual node is an SVG element.\n isSVG?: boolean;\n // The DOM element that corresponds to the virtual node.\n dom?: DomElement;\n // A boolean indicating whether the virtual node has been processed in the keyed diffing algorithm.\n processed?: boolean;\n}\n\n// The VnodeWithDom interface represents a virtual node that has a DOM element associated with it.\nexport interface VnodeWithDom extends VnodeInterface {\n dom: DomElement;\n}\n\n// The Component interface represents a function that returns a virtual node or a list of virtual nodes.\n// It can also have additional properties.\nexport interface Component extends DefaultRecord {\n // The function that returns a virtual node or a list of virtual nodes.\n // It can take props and children as arguments.\n // eslint-disable-next-line no-unused-vars\n (props?: VnodeProperties | null, ...children: any[]): VnodeInterface | Children | any;\n}\n\n// The POJOComponent interface represents a \"plain old JavaScript object\" (POJO) component.\n// It has a view function that returns a virtual node or a list of virtual nodes,\n// as well as optional props and children.\n// It can be used also to identify class instance components.\nexport interface POJOComponent extends DefaultRecord {\n // The view function that returns a virtual node or a list of virtual nodes.\n view: Component;\n // The props for the component.\n props?: VnodeProperties | null;\n // The children for the component.\n children?: any[];\n}\n\n// The VnodeComponentInterface represents a virtual node that has a component as its tag.\n// It has props and children, just like a regular virtual node.\nexport interface VnodeComponentInterface extends VnodeInterface {\n tag: Component | POJOComponent;\n props: VnodeProperties;\n children: Children;\n}\n\n// The Children interface represents a list of virtual nodes or other values.\nexport interface Children extends Array {}\n\n// The Directive interface represents a function that can be applied to a virtual node.\n// It receives the value, virtual node, and old virtual node as arguments, and can return a boolean value.\n// If only the virtual node is passed, it means its the on create phase for the v-node.\n// If the old virtual node is also passed, it means its the on update phase for the v-node.\nexport interface Directive {\n // eslint-disable-next-line no-unused-vars\n (value: any, vnode: VnodeWithDom, oldVnode?: VnodeWithDom): void | boolean;\n}\n\n// The Directives interface is a mapping of directive names to Directive functions.\nexport interface Directives extends Record {}\n\n// The ReservedProps interface is a mapping of reserved prop names to the value `true`.\n// These prop names cannot be used as custom prop names.\nexport interface ReservedProps extends Record {}\n\n// The Current interface represents the current component and virtual node that are being processed.\nexport interface Current {\n // The current component. It can be a component, a POJO component, or null.\n component: Component | POJOComponent | null;\n // The current virtual node. It must have a DOM element associated with it.\n vnode: VnodeWithDom | null;\n // The old virtual node. It must have a DOM element associated with it.\n oldVnode?: VnodeWithDom | null;\n // The current event. It can be an event or null.\n event: Event | null;\n}\n\n// The V function is the main function for creating virtual nodes.\n// It takes a tag or component, props, and children as arguments, and returns a virtual node.\nexport interface V {\n // eslint-disable-next-line no-unused-vars, no-use-before-define\n (tagOrComponent: string | Component | POJOComponent, props: VnodeProperties | null, ...children: Children):\n | VnodeInterface\n | VnodeComponentInterface;\n // eslint-disable-next-line no-unused-vars, no-use-before-define\n fragment(_: any, ...children: Children): Children;\n}\n\n// 'textTag' is a constant string that is used to represent text nodes in the virtual DOM.\nconst textTag = \"#text\";\n\n// 'isNodeJs' is a boolean that is true if the code is running in a Node.js environment and false otherwise.\n// It is determined by checking if the 'process' global object is defined and has a 'versions' property.\nexport const isNodeJs = Boolean(typeof process !== \"undefined\" && process.versions && process.versions.node);\n\n// 'createDomElement' is a function that creates a new DOM element with the specified tag name.\n// If 'isSVG' is true, it creates an SVG element instead of a regular DOM element.\nexport function createDomElement(tag: string, isSVG: boolean = false): DomElement {\n return isSVG ? document.createElementNS(\"http://www.w3.org/2000/svg\", tag) : document.createElement(tag);\n}\n\n// 'Vnode' is a class that represents a virtual DOM node.\n// It has three properties: 'tag', 'props', and 'children'.\n// 'Vnode' is exported as an object with a type of 'VnodeInterface'.\n// The 'as unknown as VnodeInterface' is used to tell TypeScript that the 'Vnode' function has the same type as 'VnodeInterface'.\nexport const Vnode = function Vnode(this: VnodeInterface, tag: string, props: VnodeProperties, children: Children) {\n // 'this' refers to the current instance of 'Vnode'.\n this.tag = tag;\n this.props = props;\n this.children = children;\n} as unknown as VnodeInterface;\n\n// 'isComponent' is a function that returns true if the given 'component' is a valid component and false otherwise.\n// A component is either a function or an object with a 'view' function.\nexport function isComponent(component: unknown): component is Component {\n return Boolean(\n component && (typeof component === \"function\" || (typeof component === \"object\" && \"view\" in component))\n );\n}\n\n// 'isVnode' is a function that returns true if the given 'object' is a 'Vnode' instance and false otherwise.\nexport const isVnode = (object?: unknown | VnodeInterface): object is VnodeInterface => {\n // Use the 'instanceof' operator to check if 'object' is an instance of 'Vnode'.\n return object instanceof Vnode;\n};\n\n// 'isVnodeComponent' is a function that returns true if the given 'object' is a 'Vnode' instance with a 'tag' property that is a valid component.\n// It returns false otherwise.\nexport const isVnodeComponent = (object?: unknown | VnodeComponentInterface): object is VnodeComponentInterface => {\n // Check if 'object' is a 'Vnode' instance and its 'tag' property is a valid component.\n return isVnode(object) && isComponent(object.tag);\n};\n\n// 'domToVnode' is a function that converts a DOM node to a 'Vnode' instance.\nexport function domToVnode(dom: any): VnodeWithDom {\n // If the child node is a text node, create a 'Vnode' instance with the 'textTag' constant as the 'tag' property.\n // Set the 'dom' property of the 'Vnode' instance to the child DOM node.\n // Push the 'Vnode' instance to the 'children' array.\n if (dom.nodeType === 3) {\n return dom.nodeValue;\n }\n\n const children: VnodeWithDom[] = [];\n // Iterate through all child nodes of 'dom'.\n for (let i = 0, l = dom.childNodes.length; i < l; i++) {\n const childDom = dom.childNodes[i];\n // If the child node is an element node, recursively call 'domToVnode' to convert it to a 'Vnode' instance.\n // Push the 'Vnode' instance to the 'children' array.\n if (childDom.nodeType === 3) {\n children.push(childDom.nodeValue);\n } else if (childDom.nodeType === 1) {\n children.push(domToVnode(childDom));\n }\n }\n\n const props: VnodeProperties = {};\n // Iterate through all attributes of 'dom'.\n for (let i = 0, l = dom.attributes.length; i < l; i++) {\n const attr = dom.attributes[i];\n // Add the attribute to the 'props' object, using the attribute's name as the key and its value as the value.\n props[attr.nodeName] = attr.nodeValue;\n }\n\n // Create a new 'Vnode' instance with the 'tag' property set to the lowercase version of the DOM node's tag name.\n // Set the 'props' and 'children' properties to the 'props' and 'children' arrays respectively.\n // Set the 'dom' property of the 'Vnode' instance to the DOM node.\n const vnode = new Vnode(dom.tagName.toLowerCase(), props, children);\n vnode.dom = dom;\n return vnode as VnodeWithDom;\n}\n\n// This function takes in an HTML string and creates a virtual node representation of it\n// using the `domToVnode` function. It does this by creating a new `div` element, setting\n// its `innerHTML` to the provided HTML string, and then using `map` to iterate over the\n// `childNodes` of the `div` element, passing each one to `domToVnode` to create a virtual\n// node representation of it. The resulting array of virtual nodes is then returned.\nexport function trust(htmlString: string) {\n const div = createDomElement(\"div\");\n div.innerHTML = htmlString.trim();\n\n return [].map.call(div.childNodes, (item) => domToVnode(item));\n}\n\n/* ========================================================================== */\n/* Main Component implementation */\n/* ========================================================================== */\n\n// These variables are used to store the main component, the main virtual node, and whether\n// the main component is currently mounted.\nlet mainComponent: VnodeComponentInterface | null = null;\nlet mainVnode: VnodeWithDom | null = null;\nlet isMounted = false;\n\n// This object is used to store the current virtual node and component being rendered.\nexport const current: Current = {\n vnode: null,\n oldVnode: null,\n component: null,\n event: null\n};\n\n/* Reserved props ----------------------------------------------------------- */\n// This object is used to store the names of reserved props, which are props that are reserved\n// for special purposes and should not be used as regular component props.\nexport const reservedProps: Record = {\n key: true,\n state: true,\n \"v-keep\": true,\n\n // Built in directives\n \"v-if\": true,\n \"v-unless\": true,\n \"v-for\": true,\n \"v-show\": true,\n \"v-class\": true,\n \"v-html\": true,\n \"v-model\": true,\n \"v-create\": true,\n \"v-update\": true,\n \"v-cleanup\": true\n};\n\n/* Mounting, Updating, Cleanup and Unmounting ------------------------------- */\n// These sets are used to store callbacks for various lifecycle events: mounting, updating,\n// cleaning up, and unmounting.\nconst onCleanupSet: Set = new Set();\nconst onMountSet: Set = new Set();\nconst onUpdateSet: Set = new Set();\nconst onUnmountSet: Set = new Set();\n\n// These functions allow users to register callbacks for the corresponding lifecycle events.\nexport function onMount(callback: Function) {\n if (!isMounted) {\n onMountSet.add(callback);\n }\n}\n\nexport function onUpdate(callback: Function) {\n onUpdateSet.add(callback);\n}\n\nexport function onCleanup(callback: Function) {\n onCleanupSet.add(callback);\n}\n\nexport function onUnmount(callback: Function) {\n if (!isMounted) {\n onUnmountSet.add(callback);\n }\n}\n\n// This function is used to call all the callbacks in a given set.\nfunction callSet(set: Set) {\n for (const callback of set) {\n callback();\n }\n\n set.clear();\n}\n\n/* Event listener ----------------------------------------------------------- */\n\n// This object stores the names of event listeners that have been added\nconst eventListenerNames: Record = {};\n\n// This function is called when an event occurs\nfunction eventListener(e: Event) {\n // Set the current event to the event that occurred so that it can be prevented if necessary\n current.event = e;\n\n // Convert the target of the event to a DOM element\n let dom = e.target as DomElement;\n\n // Create the name of the event listener by adding \"v-on\" to the event type\n const name = `v-on${e.type}`;\n\n // Keep going up the DOM tree until we find an element with an event listener\n // matching the event type\n while (dom) {\n if (dom[name]) {\n // Call the event listener function\n dom[name](e, dom);\n\n // If the default action of the event hasn't been prevented, update the DOM\n if (!e.defaultPrevented) {\n update();\n }\n return;\n }\n dom = dom.parentNode as DomElement;\n }\n\n current.event = null;\n}\n\n/* Directives --------------------------------------------------------------- */\n\n// This function creates a directive that hides an element based on a condition\nconst hideDirective = (test: boolean) => (bool: boolean, vnode: VnodeWithDom, oldnode?: VnodeInterface) => {\n // If test is true, use the value of bool. Otherwise, use the opposite of bool.\n const value = test ? bool : !bool;\n\n // If the value is true, hide the element by replacing it with a text node\n if (value) {\n const parentNode = vnode.dom?.parentNode;\n if (parentNode) {\n const newdom = document.createTextNode(\"\");\n parentNode.replaceChild(newdom, vnode.dom);\n }\n\n return false;\n }\n};\n\n// This object stores all the available directives\nexport const directives: Directives = {\n // The \"v-if\" directive hides an element if the given condition is false\n \"v-if\": hideDirective(false),\n\n // The \"v-unless\" directive hides an element if the given condition is true\n \"v-unless\": hideDirective(true),\n\n // The \"v-for\" directive creates a loop and applies a callback function to each item in the loop\n \"v-for\": (set: unknown[], vnode: VnodeWithDom) => {\n const newChildren: VnodeInterface[] = [];\n const callback = vnode.children[0];\n for (let i = 0, l = set.length; i < l; i++) {\n newChildren.push(callback(set[i], i));\n }\n vnode.children = newChildren;\n },\n\n // The \"v-show\" directive shows or hides an element by setting the \"display\" style property\n \"v-show\": (bool: boolean, vnode: VnodeWithDom) => {\n (\n vnode.dom as unknown as {\n style: { display: string };\n }\n ).style.display = bool ? \"\" : \"none\";\n },\n\n // The \"v-class\" directive adds or removes class names from an element based on a condition\n \"v-class\": (classes: { [x: string]: boolean }, vnode: VnodeWithDom) => {\n // Loop through all the class names in the classes object\n for (const name in classes) {\n // Add or remove the class name from the element's class list based on the value in the classes object\n (vnode.dom as DomElement).classList.toggle(name, classes[name]);\n }\n },\n\n // The \"v-html\" directive sets the inner HTML of an element to the given HTML string\n \"v-html\": (html: string, vnode: VnodeWithDom) => {\n // Set the children of the vnode to a trusted version of the HTML string\n vnode.children = [trust(html)];\n },\n\n // The \"v-model\" directive binds the value of an input element to a model property\n \"v-model\": ([model, property, event]: any[], vnode: VnodeWithDom, oldVnode?: VnodeWithDom) => {\n let value;\n // This function updates the model property when the input element's value changes\n let handler = (e: Event) => (model[property] = (e.target as DomElement & Record).value);\n if (vnode.tag === \"input\") {\n // If the element is an input, use the \"input\" event by default\n event = event || \"oninput\";\n // Depending on the type of input element, use a different handler function\n switch (vnode.props.type) {\n case \"checkbox\": {\n if (Array.isArray(model[property])) {\n // If the model property is an array, add or remove the value from the array when the checkbox is checked or unchecked\n handler = (e: Event) => {\n const val = (e.target as DomElement & Record).value;\n const idx = model[property].indexOf(val);\n if (idx === -1) {\n model[property].push(val);\n } else {\n model[property].splice(idx, 1);\n }\n };\n // If the value is in the array, set the checkbox to be checked\n value = model[property].indexOf(vnode.dom.value) !== -1;\n } else if (\"value\" in vnode.props) {\n // If the input element has a \"value\" attribute, use it to determine the checked state\n handler = () => {\n if (model[property] === vnode.props.value) {\n model[property] = null;\n } else {\n model[property] = vnode.props.value;\n }\n };\n value = model[property] === vnode.props.value;\n } else {\n // If there is no \"value\" attribute, use a boolean value for the model property\n handler = () => (model[property] = !model[property]);\n value = model[property];\n }\n // Set the \"checked\" attribute on the input element\n // eslint-disable-next-line no-use-before-define\n sharedSetAttribute(\"checked\", value, vnode);\n break;\n }\n case \"radio\": {\n // If the element is a radio button, set the \"checked\" attribute based on the value of the model property\n // eslint-disable-next-line no-use-before-define\n sharedSetAttribute(\"checked\", model[property] === vnode.dom.value, vnode);\n break;\n }\n default: {\n // For all other input types, set the \"value\" attribute based on the value of the model property\n // eslint-disable-next-line no-use-before-define\n sharedSetAttribute(\"value\", model[property], vnode);\n }\n }\n } else if (vnode.tag === \"select\") {\n // If the element is a select element, use the \"click\" event by default\n event = event || \"onclick\";\n if (vnode.props.multiple) {\n // If the select element allows multiple selections, update the model property with an array of selected values\n handler = (e: Event & Record) => {\n const val = (e.target as DomElement & Record).value;\n if (e.ctrlKey) {\n // If the Ctrl key is pressed, add or remove the value from the array\n const idx = model[property].indexOf(val);\n if (idx === -1) {\n model[property].push(val);\n } else {\n model[property].splice(idx, 1);\n }\n } else {\n // If the Ctrl key is not pressed, set the model property to an array with the selected value\n model[property].splice(0, model[property].length);\n model[property].push(val);\n }\n };\n // Set the \"selected\" attribute on the options based on whether they are in the model property array\n vnode.children.forEach((child: VnodeInterface) => {\n if (child.tag === \"option\") {\n const value = \"value\" in child.props ? child.props.value : child.children.join(\"\").trim();\n child.props.selected = model[property].indexOf(value) !== -1;\n }\n });\n } else {\n // If the select element does not allow multiple selections, set the \"selected\" attribute on the options based on the value of the model property\n vnode.children.forEach((child: VnodeInterface) => {\n if (child.tag === \"option\") {\n const value = \"value\" in child.props ? child.props.value : child.children.join(\"\").trim();\n child.props.selected = value === model[property];\n }\n });\n }\n } else if (vnode.tag === \"textarea\") {\n // If the element is a textarea, use the \"input\" event by default\n event = event || \"oninput\";\n // Set the textarea's content to the value of the model property\n vnode.children = [model[property]];\n }\n\n // We assume that the prev handler if any will not be changed by the user across patchs\n const prevHandler = vnode.props[event];\n\n // Set the event handler on the element\n // eslint-disable-next-line no-use-before-define\n sharedSetAttribute(\n event,\n (e: Event) => {\n handler(e);\n\n // If the previous handler is defined, call it after the model has been updated\n if (prevHandler) {\n prevHandler(e);\n }\n },\n vnode,\n oldVnode\n );\n },\n\n // The \"v-create\" directive is called when a new virtual node is created.\n // The provided callback function is called with the new virtual node as an argument.\n // This directive is only called once per virtual node, when it is first created.\n // eslint-disable-next-line no-unused-vars\n \"v-create\": (callback: (vnode: VnodeWithDom) => void, vnode: VnodeWithDom, oldVnode?: VnodeWithDom) => {\n // If this is not an update, call the callback function with the new virtual node\n if (!oldVnode) {\n const cleanup = callback(vnode);\n\n // If the callback function returns a function, call it when the update is gonna be cleaned up\n if (typeof cleanup === \"function\") {\n onCleanup(cleanup);\n }\n }\n },\n\n // The \"v-update\" directive is called when an existing virtual node is updated.\n // The provided callback function is called with the new and old virtual nodes as arguments.\n // This directive is only called once per virtual node update.\n \"v-update\": (\n // eslint-disable-next-line no-unused-vars\n callback: (vnode: VnodeWithDom, oldVnode: VnodeWithDom) => void,\n vnode: VnodeWithDom,\n oldVnode?: VnodeWithDom\n ) => {\n // If this is an update, call the callback function with the new and old virtual nodes\n if (oldVnode) {\n const cleanup = callback(vnode, oldVnode);\n\n // If the callback function returns a function, call it when the update is gonna be cleaned up\n if (typeof cleanup === \"function\") {\n onCleanup(cleanup);\n }\n }\n },\n\n // The \"v-cleanup\" directive is called when the update is cleaned up.\n // The provided callback function is called with the old virtual node as an argument.\n // This directive is only called once per virtual node, when the update is cleaned up.\n \"v-cleanup\": (\n // eslint-disable-next-line no-unused-vars\n callback: (vnode: VnodeWithDom, oldVnode?: VnodeWithDom) => void,\n vnode: VnodeWithDom,\n oldVnode?: VnodeWithDom\n ) => {\n // Add the callback function to the list of cleanup functions to be called when the update is cleaned up\n onCleanup(() => callback(vnode, oldVnode));\n }\n};\n// Add a directive to the global directives object, with the key being the name\n// preceded by \"v-\". Also add the name to the global reservedProps object.\nexport function directive(name: string, directive: Directive) {\n const directiveName = `v-${name}`;\n directives[directiveName] = directive;\n reservedProps[directiveName] = true;\n}\n\n// Set an attribute on a virtual DOM node and update the actual DOM element.\n// If the attribute value is a function, add an event listener for the attribute\n// name to the DOM element represented by mainVnode.\n// If oldVnode is provided, compare the new attribute value to the old value\n// and only update the attribute if the values are different.\nfunction sharedSetAttribute(name: string, value: any, newVnode: VnodeWithDom, oldVnode?: VnodeWithDom): void | boolean {\n // If the attribute value is a function, add an event listener for the attribute\n // name to the DOM element represented by mainVnode.\n if (typeof value === \"function\") {\n // Only add the event listener if it hasn't been added yet.\n if (name in eventListenerNames === false) {\n (mainVnode as VnodeWithDom).dom.addEventListener(name.slice(2), eventListener);\n eventListenerNames[name] = true;\n }\n newVnode.dom[`v-${name}`] = value;\n return;\n }\n\n // If the attribute is present on the DOM element and newVnode is not an SVG,\n // update the attribute if the value has changed.\n if (newVnode.isSVG === false && name in newVnode.dom) {\n // eslint-disable-next-line eqeqeq\n if (newVnode.dom[name] != value) {\n newVnode.dom[name] = value;\n }\n return;\n }\n\n // If oldVnode is not provided or the attribute value has changed, update the\n // attribute on the DOM element.\n if (!oldVnode || value !== oldVnode.props[name]) {\n if (value === false) {\n newVnode.dom.removeAttribute(name);\n } else {\n newVnode.dom.setAttribute(name, value);\n }\n }\n}\n\n// Set an attribute on a virtual DOM node and update the actual DOM element.\n// Skip the attribute if it is in the reservedProps object.\nexport function setAttribute(name: string, value: any, newVnode: VnodeWithDom, oldVnode?: VnodeWithDom): void {\n if (reservedProps[name]) {\n return;\n }\n newVnode.props[name] = value;\n sharedSetAttribute(name, value, newVnode, oldVnode);\n}\n\n// Update the attributes on a virtual DOM node. If oldVnode is provided, remove\n// attributes from the DOM element that are not present in newVnode.props but are\n// present in oldVnode.props. Then, iterate over the attributes in newVnode.props\n// and update the DOM element with the attributes using the sharedSetAttribute\n// function. If an attribute is in the reservedProps object and has a corresponding\n// directive in the directives object, call the directive with the attribute value\n// and the two virtual DOM nodes as arguments. If the directive returns false, exit\n// the loop.\nexport function updateAttributes(newVnode: VnodeWithDom, oldVnode?: VnodeWithDom): void {\n // If oldVnode is provided, remove attributes from the DOM element that are not\n // present in newVnode.props but are present in oldVnode.props.\n if (oldVnode) {\n for (const name in oldVnode.props) {\n if (!newVnode.props[name] && !eventListenerNames[name] && !reservedProps[name]) {\n if (newVnode.isSVG === false && name in newVnode.dom) {\n newVnode.dom[name] = null;\n } else {\n newVnode.dom.removeAttribute(name);\n }\n }\n }\n }\n\n // Iterate over the attributes in newVnode.props and update the DOM element with\n // the attributes using the sharedSetAttribute function.\n for (const name in newVnode.props) {\n if (reservedProps[name]) {\n // If there is a directive for the attribute, call it with the attribute value\n // and the two virtual DOM nodes as arguments. If the directive returns false,\n // exit the loop.\n if (directives[name] && directives[name](newVnode.props[name], newVnode, oldVnode) === false) {\n break;\n }\n continue;\n }\n sharedSetAttribute(name, newVnode.props[name], newVnode, oldVnode);\n }\n}\n\n/* patch ------------------------------------------------------------------- */\n\n// Patch a DOM node with a new VNode tree\nexport function patch(newVnode: VnodeWithDom, oldVnode?: VnodeWithDom): void {\n // If the new tree has no children, set the text content of the parent DOM element to an empty string\n if (newVnode.children.length === 0) {\n newVnode.dom.textContent = \"\";\n return;\n }\n\n // Get the children of the new and old virtual DOM nodes\n const newTree = newVnode.children;\n const oldTree = oldVnode?.children || [];\n // Get the length of the old tree\n const oldTreeLength = oldTree.length;\n // Get the length of the new tree\n let newTreeLength = newTree.length;\n // Set the global current object to the new and old virtual DOM nodes\n current.vnode = newVnode;\n current.oldVnode = oldVnode;\n\n // Flatten the new tree\n // Take into account that is necessary to flatten the tree before the patch process\n // to let the hooks and signals work properly\n let i = 0;\n while (i < newTreeLength) {\n const newChild = newTree[i];\n\n // If the new child is a Vnode and is not a text node\n if (newChild instanceof Vnode) {\n // If the tag of the new child is not a string, it is a component\n if (typeof newChild.tag !== \"string\") {\n // Set the current component to the tag of the new child\n current.component = newChild.tag;\n // Replace the new child with the result of calling its view or bind method, passing in the props and children as arguments\n newTree.splice(\n i,\n 1,\n (\"view\" in newChild.tag ? newChild.tag.view.bind(newChild.tag) : newChild.tag.bind(newChild.tag))(\n newChild.props,\n ...newChild.children\n )\n );\n newTreeLength = newTree.length;\n continue;\n } else {\n i++;\n }\n // If the new child is an array, flatten it and continue the loop\n } else if (Array.isArray(newChild)) {\n newTree.splice(i, 1, ...newChild);\n newTreeLength = newTree.length;\n // If the new child is null or undefined, remove it from the new tree and continue the loop\n } else if (newChild == null) {\n newTree.splice(i, 1);\n newTreeLength = newTree.length;\n } else {\n // If the new child is not a Vnode or an array, it is a text node\n // just continue the loop\n i++;\n }\n }\n\n // If the new tree has no children, set the text content of the parent DOM element to an empty string\n if (newTreeLength === 0) {\n newVnode.dom.textContent = \"\";\n return;\n }\n\n // If the old tree has children and the first child of the new tree is a VNode with a \"key\"\n // attribute and the first child of the old tree is a VNode with a \"key\" attribute, update\n // the DOM element in place by comparing the keys of the nodes in the trees.\n if (\n oldTreeLength > 0 &&\n newTree[0] instanceof Vnode &&\n oldTree[0] instanceof Vnode &&\n \"key\" in newTree[0].props &&\n \"key\" in oldTree[0].props\n ) {\n const oldKeyedList: Record = {};\n const newKeyedList: Record = {};\n const childNodes = newVnode.dom.childNodes;\n\n // Create key maps while also handling removal of nodes not present in newTree\n for (let i = 0; i < oldTreeLength; i++) {\n oldKeyedList[oldTree[i].props.key] = i;\n if (i < newTreeLength) {\n newKeyedList[newTree[i].props.key] = i;\n }\n }\n\n for (let i = 0; i < newTreeLength; i++) {\n const newChild = newTree[i];\n const oldChildIndex = oldKeyedList[newChild.props.key];\n const oldChild = oldTree[oldChildIndex];\n let shouldPatch = true;\n\n if (oldChild) {\n newChild.dom = oldChild.dom;\n if (\"v-keep\" in newChild.props && newChild.props[\"v-keep\"] === oldChild.props[\"v-keep\"]) {\n newChild.children = oldChild.children;\n shouldPatch = false;\n } else {\n updateAttributes(newChild, oldChild);\n }\n } else {\n newChild.dom = createDomElement(newChild.tag, newChild.isSVG);\n updateAttributes(newChild);\n }\n\n const currentNode = childNodes[i];\n if (!currentNode) {\n newVnode.dom.appendChild(newChild.dom);\n } else if (currentNode !== newChild.dom) {\n newVnode.dom.replaceChild(newChild.dom, currentNode);\n }\n\n shouldPatch && patch(newChild, oldChild);\n }\n\n // Remove nodes that don't exist in newTree\n for (let i = newTreeLength; i < oldTreeLength; i++) {\n if (!newKeyedList[oldTree[i].props.key]) {\n const domToRemove = oldTree[i].dom;\n domToRemove.parentNode && domToRemove.parentNode.removeChild(domToRemove);\n }\n }\n return;\n }\n\n // Patch the the old tree\n for (let i = 0; i < newTreeLength; i++) {\n const newChild = newTree[i];\n const oldChild = oldTree[i];\n const isGreaterThanOldTreeLength = i >= oldTreeLength;\n\n if (newChild instanceof Vnode === false) {\n if (isGreaterThanOldTreeLength || oldChild instanceof Vnode) {\n // If there's no corresponding old child, create a new text node for the new child\n const dom = document.createTextNode(newChild as string);\n\n if (isGreaterThanOldTreeLength) {\n // Append the new child to the dom\n newVnode.dom.appendChild(dom);\n } else {\n newVnode.dom.replaceChild(dom, newVnode.dom.childNodes[i]);\n }\n continue;\n }\n\n // If the old child is not a vnode\n // eslint-disable-next-line eqeqeq\n if (newVnode.dom.childNodes[i].textContent != newChild) {\n newVnode.dom.childNodes[i].textContent = newChild as string;\n }\n continue;\n }\n\n // Set the isSVG flag for the new child if it is an SVG element or if the parent is an SVG element\n newChild.isSVG = newVnode.isSVG || newChild.tag === \"svg\";\n\n if (isGreaterThanOldTreeLength || oldChild instanceof Vnode === false || newChild.tag !== oldChild.tag) {\n // If there's no corresponding old child, create a new dom element for the new child\n newChild.dom = createDomElement(newChild.tag as string, newChild.isSVG);\n\n if (isGreaterThanOldTreeLength) {\n // Append the new child to the dom\n newVnode.dom.appendChild(newChild.dom);\n } else {\n newVnode.dom.replaceChild(newChild.dom, newVnode.dom.childNodes[i]);\n }\n\n // Update the attributes of the new child\n updateAttributes(newChild as VnodeWithDom);\n\n // Recursively patch the new child\n patch(newChild as VnodeWithDom);\n continue;\n }\n\n // Set the dom property of the new child to the dom property of the old child\n newChild.dom = oldChild.dom;\n // If the v-keep prop is the same for both the new and old child, set the children of the new child to the children of the old child\n if (\"v-keep\" in newChild.props && newChild.props[\"v-keep\"] === oldChild.props[\"v-keep\"]) {\n newChild.children = oldChild.children;\n continue;\n }\n\n // Update the attributes of the new child based on the old child\n updateAttributes(newChild as VnodeWithDom, oldChild as VnodeWithDom);\n // Recursively patch the new and old children\n patch(newChild as VnodeWithDom, oldChild as VnodeWithDom);\n }\n\n // Remove any old children that are no longer present in the new tree\n for (; newTreeLength < oldTreeLength; newTreeLength++) {\n newVnode.dom.removeChild(oldTree[newTreeLength].dom);\n }\n}\n\n// Update the main Vnode\nexport function update(): void | string {\n // If the main Vnode exists\n if (mainVnode) {\n // Call any cleanup functions that are registered with the onCleanupSet set\n callSet(onCleanupSet);\n // Store a reference to the old main Vnode\n const oldMainVnode = mainVnode;\n // Create a new main Vnode with the main component as its only child\n mainVnode = new Vnode(oldMainVnode.tag, oldMainVnode.props, [mainComponent]) as VnodeWithDom;\n mainVnode.dom = oldMainVnode.dom;\n mainVnode.isSVG = oldMainVnode.isSVG;\n\n // Recursively patch the new and old main Vnodes\n patch(mainVnode, oldMainVnode);\n\n // Call any update or mount functions that are registered with the onUpdateSet or onMountSet set\n callSet(isMounted ? onUpdateSet : onMountSet);\n\n // Set the isMounted flag to true\n isMounted = true;\n\n // Reset the current vnode, oldVnode, and component properties\n current.vnode = null;\n current.oldVnode = null;\n current.component = null;\n\n // If the code is running in a Node.js environment, return the inner HTML of the main Vnode's dom element\n if (isNodeJs) {\n return mainVnode.dom.innerHTML;\n }\n }\n}\n\n// Update custom Vnode\n// It is assumed that a first mount has already occurred, so,\n// the oldVnode is not null and the dom property of the oldVnode is not null\n// You need to set the dom property of the newVnode to the dom property of the oldVnode\n// The same with the isSVG property\n// Prefer this function over patch to allow for cleanup, onUpdate and onMount sets to be called\nexport function updateVnode(vnode: VnodeWithDom, oldVnode: VnodeWithDom): string | void {\n // Call any cleanup functions that are registered with the onCleanupSet set\n callSet(onCleanupSet);\n\n // Recursively patch the new and old main Vnodes\n patch(vnode, oldVnode);\n\n // Set the oldVnode's tag, props, children, dom, and isSVG properties to the newVnode's tag, props, children, dom, and isSVG properties\n // This is necessary to allow for the oldVnode to be used as the newVnode in the next update with the normal update function\n oldVnode.tag = vnode.tag;\n oldVnode.props = { ...vnode.props };\n oldVnode.children = [...vnode.children];\n oldVnode.dom = vnode.dom;\n oldVnode.isSVG = vnode.isSVG;\n\n // Call any update or mount functions that are registered with the onUpdateSet or onMountSet set\n callSet(isMounted ? onUpdateSet : onMountSet);\n\n // Set the isMounted flag to true\n isMounted = true;\n\n // Reset the current vnode, oldVnode, and component properties\n current.vnode = null;\n current.oldVnode = null;\n current.component = null;\n\n if (isNodeJs) {\n return vnode.dom.innerHTML;\n }\n}\n\n// Unmount the main Vnode\nexport function unmount() {\n // If the main Vnode exists\n if (mainVnode) {\n // Set the main component to a null Vnode\n mainComponent = new Vnode(() => null, {}, []) as VnodeComponentInterface;\n // Update the main Vnode\n const result = update();\n // Call any unmount functions that are registered with the onUnmountSet set\n callSet(onUnmountSet);\n\n // Remove any event listeners that were added to the main Vnode's dom element\n for (const name in eventListenerNames) {\n mainVnode.dom.removeEventListener(name.slice(2).toLowerCase(), eventListener);\n Reflect.deleteProperty(eventListenerNames, name);\n }\n\n // Reset the main component and main Vnode\n mainComponent = null;\n mainVnode = null;\n // Set the isMounted flag to false\n isMounted = false;\n // Reset the current vnode, oldVnode, and component properties\n current.vnode = null;\n current.oldVnode = null;\n current.component = null;\n // Return the result of updating the main Vnode\n return result;\n }\n}\n// This function takes in a DOM element or a DOM element selector and a component to be mounted on it.\nexport function mount(dom: string | DomElement, component: any) {\n // Check if the 'dom' argument is a string. If it is, select the first element that matches the given selector.\n // Otherwise, use the 'dom' argument as the container.\n const container =\n typeof dom === \"string\"\n ? isNodeJs\n ? createDomElement(dom, dom === \"svg\")\n : document.querySelectorAll(dom)[0]\n : dom;\n\n // Check if the 'component' argument is a Vnode component or a regular component.\n // If it's a regular component, create a new Vnode component using the 'component' argument as the tag.\n // If it's not a component at all, create a new Vnode component with the 'component' argument as the rendering function.\n const vnodeComponent = isVnodeComponent(component)\n ? component\n : isComponent(component)\n ? new Vnode(component, {}, [])\n : new Vnode(() => component, {}, []);\n\n // If a main component already exists and it's not the same as the current 'vnodeComponent', unmount it.\n if (mainComponent && mainComponent.tag !== vnodeComponent.tag) {\n unmount();\n }\n\n // Set the 'vnodeComponent' as the main component.\n mainComponent = vnodeComponent as VnodeComponentInterface;\n // Convert the container element to a Vnode.\n mainVnode = domToVnode(container);\n // Update the DOM with the new component.\n return update();\n}\n\n// This is a utility function for creating Vnode objects.\n// It takes in a tag or component, and optional props and children arguments.\nexport const v: V = (tagOrComponent, props, ...children) => {\n // Return a new Vnode object using the given arguments.\n return new Vnode(tagOrComponent, props || {}, children);\n};\n\n// This utility function creates a fragment Vnode.\n// It takes in a placeholder and the children arguments, returns only the children.\nv.fragment = (_: VnodeProperties, ...children: Children) => children;\n"], + "mappings": "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", + "names": ["Vnode", "value", "directive", "i"] } diff --git a/lib/index.ts b/lib/index.ts index b416968..ede13dc 100644 --- a/lib/index.ts +++ b/lib/index.ts @@ -167,9 +167,7 @@ export function domToVnode(dom: any): VnodeWithDom { // Set the 'dom' property of the 'Vnode' instance to the child DOM node. // Push the 'Vnode' instance to the 'children' array. if (dom.nodeType === 3) { - const vnode = new Vnode(textTag, {}, [dom.nodeValue]); - vnode.dom = dom; - return vnode as VnodeWithDom; + return dom.nodeValue; } const children: VnodeWithDom[] = []; @@ -178,7 +176,9 @@ export function domToVnode(dom: any): VnodeWithDom { const childDom = dom.childNodes[i]; // If the child node is an element node, recursively call 'domToVnode' to convert it to a 'Vnode' instance. // Push the 'Vnode' instance to the 'children' array. - if (childDom.nodeType === 1 || childDom.nodeType === 3) { + if (childDom.nodeType === 3) { + children.push(childDom.nodeValue); + } else if (childDom.nodeType === 1) { children.push(domToVnode(childDom)); } } @@ -326,20 +326,18 @@ function eventListener(e: Event) { /* Directives --------------------------------------------------------------- */ // This function creates a directive that hides an element based on a condition -const hideDirective = (test: boolean) => (bool: boolean, vnode: VnodeInterface, oldnode?: VnodeInterface) => { +const hideDirective = (test: boolean) => (bool: boolean, vnode: VnodeWithDom, oldnode?: VnodeInterface) => { // If test is true, use the value of bool. Otherwise, use the opposite of bool. const value = test ? bool : !bool; // If the value is true, hide the element by replacing it with a text node if (value) { - const newdom = document.createTextNode(""); - if (oldnode && oldnode.dom && oldnode.dom.parentNode) { - oldnode.dom.parentNode.replaceChild(newdom, oldnode.dom); + const parentNode = vnode.dom?.parentNode; + if (parentNode) { + const newdom = document.createTextNode(""); + parentNode.replaceChild(newdom, vnode.dom); } - vnode.tag = "#text"; - vnode.children = []; - vnode.props = {}; - vnode.dom = newdom as unknown as DomElement; + return false; } }; @@ -708,8 +706,8 @@ export function patch(newVnode: VnodeWithDom, oldVnode?: VnodeWithDom): void { newTree.splice(i, 1); newTreeLength = newTree.length; } else { - // If the new child is a Vnode, set the text of the Vnode to the text content of its dom property - newTree[i] = new Vnode(textTag, {}, [newChild]); + // If the new child is not a Vnode or an array, it is a text node + // just continue the loop i++; } } @@ -787,51 +785,50 @@ export function patch(newVnode: VnodeWithDom, oldVnode?: VnodeWithDom): void { const oldChild = oldTree[i]; const isGreaterThanOldTreeLength = i >= oldTreeLength; - // Handle text nodes - if (newChild.tag === textTag) { - // If there's no corresponding old child or the old child isn't a text node - if (isGreaterThanOldTreeLength || oldChild.tag !== textTag) { - newChild.dom = document.createTextNode(newChild.children[0]); // Create a new text node + if (newChild instanceof Vnode === false) { + if (isGreaterThanOldTreeLength || oldChild instanceof Vnode) { + // If there's no corresponding old child, create a new text node for the new child + const dom = document.createTextNode(newChild as string); + if (isGreaterThanOldTreeLength) { - // If there's no corresponding old child, append the new text node - newVnode.dom.appendChild(newChild.dom); + // Append the new child to the dom + newVnode.dom.appendChild(dom); } else { - // Replace the old non-text node with the new text node - newVnode.dom.replaceChild(newChild.dom, oldChild.dom); - } - } else { - // Update the old text node if content has changed - newChild.dom = oldChild.dom; - if (newChild.children[0] !== oldChild.dom.textContent) { - oldChild.dom.textContent = newChild.children[0]; + newVnode.dom.replaceChild(dom, newVnode.dom.childNodes[i]); } + continue; + } + + // If the old child is not a vnode + // eslint-disable-next-line eqeqeq + if (newVnode.dom.childNodes[i].textContent != newChild) { + newVnode.dom.childNodes[i].textContent = newChild as string; } continue; } - // If the new child is not a text node // Set the isSVG flag for the new child if it is an SVG element or if the parent is an SVG element newChild.isSVG = newVnode.isSVG || newChild.tag === "svg"; - // If the tag of the new child is different from the tag of the old child - if (isGreaterThanOldTreeLength || newChild.tag !== oldChild.tag) { - // Create a new dom element for the new child + if (isGreaterThanOldTreeLength || oldChild instanceof Vnode === false || newChild.tag !== oldChild.tag) { + // If there's no corresponding old child, create a new dom element for the new child newChild.dom = createDomElement(newChild.tag as string, newChild.isSVG); - // Update the attributes of the new child - updateAttributes(newChild as VnodeWithDom); + if (isGreaterThanOldTreeLength) { // Append the new child to the dom newVnode.dom.appendChild(newChild.dom); } else { - // Replace the old child in the dom with the new child - newVnode.dom.replaceChild(newChild.dom, oldChild.dom); + newVnode.dom.replaceChild(newChild.dom, newVnode.dom.childNodes[i]); } + + // Update the attributes of the new child + updateAttributes(newChild as VnodeWithDom); + // Recursively patch the new child patch(newChild as VnodeWithDom); continue; } - // If the tag of the new child is the same as the tag of the old child // Set the dom property of the new child to the dom property of the old child newChild.dom = oldChild.dom; // If the v-keep prop is the same for both the new and old child, set the children of the new child to the children of the old child @@ -841,9 +838,9 @@ export function patch(newVnode: VnodeWithDom, oldVnode?: VnodeWithDom): void { } // Update the attributes of the new child based on the old child - updateAttributes(newChild as VnodeWithDom, oldChild); + updateAttributes(newChild as VnodeWithDom, oldChild as VnodeWithDom); // Recursively patch the new and old children - patch(newChild as VnodeWithDom, oldChild); + patch(newChild as VnodeWithDom, oldChild as VnodeWithDom); } // Remove any old children that are no longer present in the new tree diff --git a/test/hyperscript_test.js b/test/hyperscript_test.js index 709eb52..2ff1e42 100644 --- a/test/hyperscript_test.js +++ b/test/hyperscript_test.js @@ -93,14 +93,7 @@ describe("Hyperscript", () => { id: "unique", class: "unique" }, - children: [ - { - tag: "#text", - props: {}, - children: ["Hola mundo"], - dom: expect.anything() - } - ], + children: ["Hola mundo"], dom: expect.anything() } ]); diff --git a/test/mount_n_update_test.js b/test/mount_n_update_test.js index 8bed78e..990047a 100644 --- a/test/mount_n_update_test.js +++ b/test/mount_n_update_test.js @@ -366,7 +366,7 @@ describe("Mount and update", () => { expect(result10).toEqual("
Hello world 9
"); }); - it.skip("should test deepley nested components", () => { + it("should test deepley nested components", () => { const ChildComponent = () => ( <>
Hello World
Hello 2 @@ -392,8 +392,8 @@ describe("Mount and update", () => { "
HelloWorld
Hello World
Hello 2
HelloWorld
Hello World
Hello 2
" ); - for (let i = 0; i < 1000000; i++) { + /* for (let i = 0; i < 1000000; i++) { update(); - } + } */ }); }); diff --git a/test/node_test.js b/test/node_test.js index 6835e29..e560889 100644 --- a/test/node_test.js +++ b/test/node_test.js @@ -189,7 +189,7 @@ span.hello{display: inline-block} return /* @__PURE__ */ v("button", null, "Hello"); }`); - expect(component2).toMatch(`function(){return A("button",null,"Hello")}`); + expect(component2).toMatch(`function(){return x("button",null,"Hello")}`); }); it("should convert jsx to hyperscript by default", async () => { @@ -201,6 +201,6 @@ span.hello{display: inline-block} return /* @__PURE__ */ v("button", null, "Hello"); }`); - expect(component2).toMatch(`function(){return A("button",null,"Hello")}`); + expect(component2).toMatch(`function(){return x("button",null,"Hello")}`); }); });