@coherent.js/client 1.0.0-beta.8 → 1.0.0-rc.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +2122 -931
- package/dist/index.js.map +4 -4
- package/package.json +2 -6
- package/src/index.js +1 -10
- package/types/index.d.ts +0 -53
- package/dist/client/hmr.d.ts +0 -1
- package/dist/client/hmr.d.ts.map +0 -1
- package/dist/client/hmr.js +0 -107
- package/dist/client/hmr.js.map +0 -1
- package/dist/client/hydration.d.ts +0 -55
- package/dist/client/hydration.d.ts.map +0 -1
- package/dist/client/hydration.js +0 -1593
- package/dist/client/hydration.js.map +0 -1
- package/types/hydration.d.ts +0 -66
package/dist/index.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": ["../src/hydration.js"],
|
|
4
|
-
"sourcesContent": ["/**\n * Client-side hydration utilities for Coherent.js\n *\n * This module provides utilities for hydrating server-rendered HTML\n * with client-side interactivity.\n */\n\n// Store for component instances\nconst componentInstances = new WeakMap();\n\n/**\n * Extract key from Coherent.js vNode\n * @param {Object|string|number} vNode - Virtual node\n * @returns {string|number|undefined} - The key if present\n */\nfunction getKey(vNode) {\n if (!vNode || typeof vNode !== 'object' || Array.isArray(vNode)) {\n return undefined;\n }\n const tagName = Object.keys(vNode)[0];\n const props = vNode[tagName];\n if (props && typeof props === 'object') {\n return props.key;\n }\n return undefined;\n}\n\n/**\n * Extract initial state from DOM element data attributes\n * \n * @param {HTMLElement} element - The DOM element\n * @param {Object} options - Hydration options\n * @returns {Object|null} The initial state or null\n */\nfunction extractInitialState(element, options = {}) {\n // Check if we're in a browser environment\n if (typeof window === 'undefined') {\n return options.initialState || null;\n }\n \n // Check if element has getAttribute method\n if (!element || typeof element.getAttribute !== 'function') {\n return options.initialState || null;\n }\n \n try {\n // Look for data-coherent-state attribute\n const stateAttr = element.getAttribute('data-coherent-state');\n if (stateAttr) {\n return JSON.parse(stateAttr);\n }\n \n // Look for specific state attributes\n const state = {};\n let hasState = false;\n \n // Extract common state patterns\n const countAttr = element.getAttribute('data-count');\n if (countAttr !== null) {\n state.count = parseInt(countAttr, 10) || 0;\n hasState = true;\n }\n \n const stepAttr = element.getAttribute('data-step');\n if (stepAttr !== null) {\n state.step = parseInt(stepAttr, 10) || 1;\n hasState = true;\n }\n \n const todosAttr = element.getAttribute('data-todos');\n if (todosAttr) {\n state.todos = JSON.parse(todosAttr);\n hasState = true;\n }\n \n const valueAttr = element.getAttribute('data-value');\n if (valueAttr !== null) {\n state.value = valueAttr;\n hasState = true;\n }\n \n // Check for initial props in options\n if (options.initialState) {\n return { ...options.initialState, ...state };\n }\n \n return hasState ? state : null;\n } catch (_error) {\n console.warn('Error extracting initial state:', _error);\n return options.initialState || null;\n }\n}\n\n/**\n * Hydrate a DOM element with a Coherent component\n * \n * @param {HTMLElement} element - The DOM element to hydrate\n * @param {Function} component - The Coherent component function\n * @param {Object} props - The props to pass to the component\n * @param {Object} options - Hydration options\n * @returns {Object} The hydrated component instance\n */\nfunction hydrate(element, component, props = {}, options = {}) {\n // Hydration process initiated\n \n if (typeof window === 'undefined') {\n console.warn('Hydration can only be performed in a browser environment');\n return null;\n }\n \n // Validate component\n if (typeof component !== 'function') {\n console.error('Hydrate error: component must be a function, received:', typeof component);\n return null;\n }\n \n // Check if element is already hydrated\n if (componentInstances.has(element)) {\n const existingInstance = componentInstances.get(element);\n return existingInstance;\n }\n \n // Extract initial state from data attributes if available\n const initialState = extractInitialState(element, options);\n \n // Create component instance with state management\n const instance = {\n element,\n component,\n props: {...props},\n state: initialState,\n isHydrated: true,\n eventListeners: [],\n options: {...options},\n previousVirtualElement: null,\n \n // Update method for re-rendering\n update(newProps) {\n this.props = { ...this.props, ...newProps };\n this.rerender();\n return this; // Return instance for chaining\n },\n \n // Re-render the component with current state\n rerender() {\n try {\n // Always use the fallback patching method to preserve hydration\n this.fallbackRerender();\n } catch (_error) {\n console.error('Error during component re-render:', _error);\n }\n },\n \n // Fallback re-render method using existing patching\n fallbackRerender() {\n try {\n // Call the component function with current props and state\n const componentProps = { ...this.props, ...(this.state || {}) };\n \n // Check if component is a function before calling\n if (typeof this.component !== 'function') {\n console.error('Component is not a function:', this.component);\n return;\n }\n \n const newVirtualElement = this.component(componentProps);\n \n // Store the previous virtual element for comparison\n if (!this.previousVirtualElement) {\n this.previousVirtualElement = this.virtualElementFromDOM(this.element);\n }\n \n // Perform intelligent DOM diffing and patching\n this.patchDOM(this.element, this.previousVirtualElement, newVirtualElement);\n \n // Re-attach event listeners for input elements only\n attachFunctionEventListeners(this.element, newVirtualElement, this, { inputsOnly: true });\n \n // Store the new virtual element for next comparison\n this.previousVirtualElement = newVirtualElement;\n \n // Component re-rendered successfully with fallback\n } catch (_error) {\n console.error('Error during component re-render (fallback):', _error);\n }\n },\n \n // Create virtual element representation from existing DOM\n virtualElementFromDOM(domElement) {\n // Check if we're in a browser environment\n if (typeof window === 'undefined' || typeof Node === 'undefined') {\n return null;\n }\n \n if (domElement.nodeType === Node.TEXT_NODE) {\n return domElement.textContent;\n }\n \n if (domElement.nodeType !== Node.ELEMENT_NODE) {\n return null;\n }\n \n const tagName = domElement.tagName.toLowerCase();\n const props = {};\n const children = [];\n \n // Extract attributes\n if (domElement.attributes) {\n Array.from(domElement.attributes).forEach(attr => {\n const name = attr.name === 'class' ? 'className' : attr.name;\n props[name] = attr.value;\n });\n }\n \n // Extract children\n if (domElement.childNodes) {\n Array.from(domElement.childNodes).forEach(child => {\n if (child.nodeType === Node.TEXT_NODE) {\n const text = child.textContent.trim();\n if (text) children.push(text);\n } else if (child.nodeType === Node.ELEMENT_NODE) {\n const childVNode = this.virtualElementFromDOM(child);\n if (childVNode) children.push(childVNode);\n }\n });\n }\n \n if (children.length > 0) {\n props.children = children;\n }\n \n return { [tagName]: props };\n },\n \n // Intelligent DOM patching with minimal changes\n patchDOM(domElement, oldVNode, newVNode) {\n // Handle text nodes\n if (typeof newVNode === 'string' || typeof newVNode === 'number') {\n const newText = String(newVNode);\n // Check if we're in a browser environment\n if (typeof window === 'undefined' || typeof Node === 'undefined' || typeof document === 'undefined') {\n return;\n }\n \n if (domElement.nodeType === Node.TEXT_NODE) {\n if (domElement.textContent !== newText) {\n domElement.textContent = newText;\n }\n } else {\n // Replace element with text node\n const textNode = document.createTextNode(newText);\n if (domElement.parentNode) {\n domElement.parentNode.replaceChild(textNode, domElement);\n }\n }\n return;\n }\n \n // Handle null/undefined\n if (!newVNode) {\n domElement.remove();\n return;\n }\n \n // Handle arrays\n if (Array.isArray(newVNode)) {\n // This shouldn't happen at the root level, but handle gracefully\n console.warn('Array virtual node at root level');\n return;\n }\n \n // Handle element nodes\n const newTagName = Object.keys(newVNode)[0];\n \n // Check if tag name changed\n if (domElement.tagName.toLowerCase() !== newTagName.toLowerCase()) {\n // Need to replace the entire element\n // Check if we're in a browser environment\n if (typeof window === 'undefined' || typeof document === 'undefined') {\n return;\n }\n \n const newElement = this.createDOMElement(newVNode);\n if (domElement.parentNode) {\n domElement.parentNode.replaceChild(newElement, domElement);\n }\n attachEventListeners(newElement, this);\n return;\n }\n \n // Update attributes\n this.patchAttributes(domElement, oldVNode, newVNode);\n \n // Update children\n this.patchChildren(domElement, oldVNode, newVNode);\n \n // Re-attach event listeners if needed\n attachEventListeners(domElement, this);\n },\n \n // Patch element attributes efficiently\n patchAttributes(domElement, oldVNode, newVNode) {\n // Check if we're in a browser environment\n if (typeof window === 'undefined' || typeof document === 'undefined') {\n return;\n }\n \n // Check if domElement has required methods\n if (!domElement || typeof domElement.setAttribute !== 'function' || typeof domElement.removeAttribute !== 'function') {\n return;\n }\n \n const oldTagName = oldVNode ? Object.keys(oldVNode)[0] : null;\n const newTagName = Object.keys(newVNode)[0];\n const oldProps = oldVNode && oldTagName ? (oldVNode[oldTagName] || {}) : {};\n const newProps = newVNode[newTagName] || {};\n \n // Remove old attributes that are no longer present\n Object.keys(oldProps).forEach(key => {\n if (key === 'children' || key === 'text') return;\n if (!(key in newProps)) {\n const attrName = key === 'className' ? 'class' : key;\n domElement.removeAttribute(attrName);\n }\n });\n \n // Add or update new attributes\n Object.keys(newProps).forEach(key => {\n if (key === 'children' || key === 'text') return;\n const newValue = newProps[key];\n const oldValue = oldProps[key];\n \n if (newValue !== oldValue) {\n const attrName = key === 'className' ? 'class' : key;\n \n if (newValue === true) {\n domElement.setAttribute(attrName, '');\n } else if (newValue === false || newValue === null) {\n domElement.removeAttribute(attrName);\n } else {\n domElement.setAttribute(attrName, String(newValue));\n }\n }\n });\n },\n \n // Get children array from a vNode\n getVNodeChildren(vNode) {\n if (!vNode || typeof vNode !== 'object' || Array.isArray(vNode)) {\n return [];\n }\n const tagName = Object.keys(vNode)[0];\n const props = vNode[tagName];\n if (!props || typeof props !== 'object') {\n return [];\n }\n if (props.children) {\n return Array.isArray(props.children) ? props.children : [props.children];\n }\n if (props.text !== undefined) {\n return [props.text];\n }\n return [];\n },\n\n // Patch children with key-based reconciliation\n patchChildren(domElement, oldVNode, newVNode) {\n // Check if we're in a browser environment\n if (typeof window === 'undefined' || typeof Node === 'undefined' || typeof document === 'undefined') {\n return;\n }\n\n // Check if domElement has required methods\n if (!domElement || typeof domElement.childNodes === 'undefined' || typeof domElement.appendChild !== 'function') {\n return;\n }\n\n const oldChildren = this.getVNodeChildren(oldVNode);\n const newChildren = this.getVNodeChildren(newVNode);\n\n // Get current DOM children (excluding whitespace-only text nodes)\n let domChildren = [];\n if (typeof Array.from === 'function' && domElement.childNodes) {\n try {\n domChildren = Array.from(domElement.childNodes).filter(node => {\n return node.nodeType === Node.ELEMENT_NODE ||\n (node.nodeType === Node.TEXT_NODE && node.textContent && node.textContent.trim());\n });\n } catch (_error) {\n console.warn('Failed to convert childNodes to array:', _error);\n domChildren = [];\n }\n }\n\n // Build key -> {vNode, index, domNode} maps\n const oldKeyMap = new Map();\n const oldIndexMap = new Map(); // For keyless items, track by index\n\n oldChildren.forEach((child, i) => {\n const key = getKey(child);\n if (key !== undefined) {\n oldKeyMap.set(key, { vNode: child, index: i, domNode: domChildren[i] });\n } else {\n oldIndexMap.set(i, { vNode: child, index: i, domNode: domChildren[i] });\n }\n });\n\n // Track which old nodes are reused\n const usedOldNodes = new Set();\n\n // Process new children\n newChildren.forEach((newChild, newIndex) => {\n const newKey = getKey(newChild);\n let oldEntry = null;\n\n // Try to find matching old node\n if (newKey !== undefined && oldKeyMap.has(newKey)) {\n oldEntry = oldKeyMap.get(newKey);\n usedOldNodes.add(newKey);\n } else if (newKey === undefined && oldIndexMap.has(newIndex)) {\n // Keyless fallback: match by index\n oldEntry = oldIndexMap.get(newIndex);\n usedOldNodes.add(`index:${newIndex}`);\n }\n\n if (oldEntry && oldEntry.domNode) {\n // Patch existing node\n this.patchDOM(oldEntry.domNode, oldEntry.vNode, newChild);\n\n // Move node if position changed\n const currentPosition = Array.from(domElement.childNodes).filter(node => {\n return node.nodeType === Node.ELEMENT_NODE ||\n (node.nodeType === Node.TEXT_NODE && node.textContent && node.textContent.trim());\n }).indexOf(oldEntry.domNode);\n\n if (currentPosition !== newIndex) {\n const referenceNode = domElement.childNodes[newIndex];\n if (referenceNode) {\n domElement.insertBefore(oldEntry.domNode, referenceNode);\n } else {\n domElement.appendChild(oldEntry.domNode);\n }\n }\n } else {\n // Create new node\n const newElement = this.createDOMElement(newChild);\n if (newElement) {\n const referenceNode = domElement.childNodes[newIndex];\n if (referenceNode) {\n domElement.insertBefore(newElement, referenceNode);\n } else {\n domElement.appendChild(newElement);\n }\n }\n }\n });\n\n // Remove old nodes that weren't reused\n oldKeyMap.forEach((entry, key) => {\n if (!usedOldNodes.has(key) && entry.domNode && entry.domNode.parentNode) {\n entry.domNode.remove();\n }\n });\n\n // Remove keyless old nodes that weren't matched by index\n oldIndexMap.forEach((entry, index) => {\n if (!usedOldNodes.has(`index:${index}`) && entry.domNode && entry.domNode.parentNode) {\n entry.domNode.remove();\n }\n });\n },\n \n // Create DOM element from virtual element\n createDOMElement(vNode) {\n if (typeof vNode === 'string' || typeof vNode === 'number') {\n return document.createTextNode(String(vNode));\n }\n \n if (!vNode || typeof vNode !== 'object') {\n return document.createTextNode('');\n }\n \n if (Array.isArray(vNode)) {\n const fragment = document.createDocumentFragment();\n vNode.forEach(child => {\n fragment.appendChild(this.createDOMElement(child));\n });\n return fragment;\n }\n \n const tagName = Object.keys(vNode)[0];\n const props = vNode[tagName] || {};\n const element = document.createElement(tagName);\n \n // Set attributes\n Object.keys(props).forEach(key => {\n if (key === 'children' || key === 'text') return;\n \n const value = props[key];\n const attrName = key === 'className' ? 'class' : key;\n \n if (value === true) {\n element.setAttribute(attrName, '');\n } else if (value !== false && value !== null) {\n element.setAttribute(attrName, String(value));\n }\n });\n \n // Add children\n if (props.children) {\n const children = Array.isArray(props.children) ? props.children : [props.children];\n children.forEach(child => {\n element.appendChild(this.createDOMElement(child));\n });\n } else if (props.text) {\n element.appendChild(document.createTextNode(String(props.text)));\n }\n \n return element;\n },\n \n // Render virtual element to HTML string\n renderVirtualElement(element) {\n if (typeof element === 'string' || typeof element === 'number') {\n return String(element);\n }\n \n if (!element || typeof element !== 'object') {\n return '';\n }\n \n // Handle arrays of elements\n if (Array.isArray(element)) {\n return element.map(el => this.renderVirtualElement(el)).join('');\n }\n \n // Handle Coherent.js object syntax\n const tagName = Object.keys(element)[0];\n const props = element[tagName];\n \n if (!props || typeof props !== 'object') {\n return `<${tagName}></${tagName}>`;\n }\n \n // Build attributes\n let attributes = '';\n const children = [];\n \n Object.keys(props).forEach(key => {\n if (key === 'children') {\n if (Array.isArray(props.children)) {\n children.push(...props.children);\n } else {\n children.push(props.children);\n }\n } else if (key === 'text') {\n children.push(props.text);\n } else {\n const attrName = key === 'className' ? 'class' : key;\n const value = props[key];\n if (value === true) {\n attributes += ` ${attrName}`;\n } else if (value !== false && value !== null && value !== undefined) {\n attributes += ` ${attrName}=\"${String(value).replace(/\"/g, '"')}\"`;\n }\n }\n });\n \n // Render children\n const childrenHTML = children.map(child => this.renderVirtualElement(child)).join('');\n \n // Check if it's a void element\n const voidElements = new Set(['area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input', 'link', 'meta', 'param', 'source', 'track', 'wbr']);\n \n if (voidElements.has(tagName.toLowerCase())) {\n return `<${tagName}${attributes}>`;\n }\n \n return `<${tagName}${attributes}>${childrenHTML}</${tagName}>`;\n },\n \n // Destroy the component and clean up\n destroy() {\n // Remove event listeners\n this.eventListeners.forEach(({element, event, handler}) => {\n if (element.removeEventListener) {\n element.removeEventListener(event, handler);\n }\n });\n \n // Clean up state\n this.state = null;\n this.isHydrated = false;\n \n // Remove from instances map\n componentInstances.delete(this.element);\n \n // Component destroyed\n },\n \n // Set state (for components with state)\n setState(newState) {\n if (!this.state) {\n this.state = {};\n }\n \n const oldState = {...this.state};\n this.state = typeof newState === 'function' ? \n {...this.state, ...newState(this.state)} : \n {...this.state, ...newState};\n \n // Trigger re-render\n this.rerender();\n \n // Call state change callback if exists\n if (this.onStateChange) {\n this.onStateChange(this.state, oldState);\n }\n },\n \n // Add event listener that will be cleaned up on destroy\n addEventListener(targetElement, event, handler) {\n if (targetElement.addEventListener) {\n targetElement.addEventListener(event, handler);\n this.eventListeners.push({element: targetElement, event, handler});\n }\n }\n };\n \n // Store instance\n componentInstances.set(element, instance);\n \n // Store the instance on the root element for event handler access\n if (element && typeof element.setAttribute === 'function') {\n element.__coherentInstance = instance;\n // Also add a data attribute to identify this as a coherent component\n if (!element.hasAttribute('data-coherent-component')) {\n element.setAttribute('data-coherent-component', 'true');\n }\n }\n \n // Re-execute component to get fresh virtual DOM with function handlers\n // For withState components, we need to ensure the state management is properly initialized\n const componentProps = { ...instance.props };\n \n // If this is a withState component, initialize its state properly\n if (instance.component.__stateContainer) {\n // Initialize state container with hydrated state if available\n if (instance.state) {\n instance.component.__stateContainer.setState(instance.state);\n }\n \n // Override the instance setState to use the state container\n instance.setState = (newState) => {\n // Update the state container\n instance.component.__stateContainer.setState(newState);\n \n // Update the instance state for consistency\n const updatedState = instance.component.__stateContainer.getState();\n instance.state = updatedState;\n \n // Trigger re-render\n instance.rerender();\n };\n }\n \n // Execute component function to get fresh virtual DOM\n const freshVirtualElement = instance.component(componentProps);\n \n // Try to inspect the structure more carefully\n if (freshVirtualElement && typeof freshVirtualElement === 'object') {\n const tagName = Object.keys(freshVirtualElement)[0];\n // Process root element and children\n if (freshVirtualElement[tagName]) {\n }\n }\n \n // Attach function-based event listeners from the fresh virtual DOM\n attachFunctionEventListeners(element, freshVirtualElement, instance);\n \n // Skip legacy event listeners to avoid conflicts with function handlers\n // Skip legacy event attachment to prevent conflicts\n \n // Component hydrated\n \n return instance;\n}\n\n// Global registry for event handlers\nconst eventRegistry = {};\n\n/**\n * Register an event handler for later use\n * @param {string} id - Unique identifier for the event handler\n * @param {Function} handler - The event handler function\n */\nexport function registerEventHandler(id, handler) {\n eventRegistry[id] = handler;\n}\n\n/**\n * Global event handler that can be called from inline event attributes\n * @param {string} eventId - The event handler ID\n * @param {Element} element - The DOM element\n * @param {Event} event - The event object\n */\nif (typeof window !== 'undefined') {\n // Initialize event registries if they don't exist\n window.__coherentEventRegistry = window.__coherentEventRegistry || {};\n window.__coherentActionRegistry = window.__coherentActionRegistry || {};\n \n window.__coherentEventHandler = function(eventId, element, event) {\n // Event handler called\n \n // Try to get the function from the event registry first\n let handlerFunc = window.__coherentEventRegistry[eventId];\n \n // If not found in event registry, try action registry\n if (!handlerFunc && window.__coherentActionRegistry[eventId]) {\n handlerFunc = window.__coherentActionRegistry[eventId];\n }\n \n if (handlerFunc) {\n // Try to find the component instance associated with this element\n let componentElement = element;\n while (componentElement && !componentElement.hasAttribute('data-coherent-component')) {\n componentElement = componentElement.parentElement;\n }\n \n if (componentElement && componentElement.__coherentInstance) {\n // We found the component instance\n const instance = componentElement.__coherentInstance;\n const state = instance.state || {};\n const setState = instance.setState ? instance.setState.bind(instance) : (() => {});\n \n try {\n // Call the handler function with the element as context and pass event, state, setState\n handlerFunc.call(element, event, state, setState);\n } catch (_error) {\n console.warn(`Error executing coherent event handler:`, _error);\n }\n } else {\n // Fallback: call the handler without component context\n try {\n handlerFunc.call(element, event);\n } catch (_error) {\n console.warn(`Error executing coherent event handler (no component context):`, _error);\n }\n }\n } else {\n console.warn(`Event handler not found for ID: ${eventId}`);\n }\n };\n}\n\n/**\n * Updates DOM elements to reflect state changes using direct DOM manipulation.\n * This function serves as the main entry point for synchronizing component state\n * with the visual representation in the DOM.\n * \n * @param {HTMLElement} rootElement - The root component element containing the UI to update\n * @param {Object} state - The new state object containing updated component data\n * @since 0.1.2\n */\nfunction updateDOMWithState(rootElement, state) {\n if (!rootElement || !state) return;\n \n // Use direct DOM updates to avoid breaking event handlers\n updateDOMElementsDirectly(rootElement, state);\n \n // Also update any dynamic content that needs to be re-rendered\n updateDynamicContent(rootElement, state);\n}\n\n/**\n * Simple virtual DOM to DOM rendering fallback\n * \n * @param {Object} vdom - Virtual DOM object\n * @param {HTMLElement} container - Container element\n */\n// eslint-disable-next-line no-unused-vars -- kept for future SSR fallback rendering\nfunction renderVirtualDOMToElement(vdom, container) {\n if (!vdom || !container) return;\n \n // Handle different virtual DOM structures\n if (typeof vdom === 'string') {\n container.textContent = vdom;\n return;\n }\n \n if (typeof vdom === 'object') {\n // Get the tag name (first key)\n const tagName = Object.keys(vdom)[0];\n if (!tagName) return;\n \n const element = document.createElement(tagName);\n const props = vdom[tagName] || {};\n \n // Set attributes and properties\n Object.keys(props).forEach(key => {\n if (key === 'children') {\n // Handle children\n const children = props.children;\n if (Array.isArray(children)) {\n children.forEach(child => {\n renderVirtualDOMToElement(child, element);\n });\n } else if (children) {\n renderVirtualDOMToElement(children, element);\n }\n } else if (key === 'text') {\n element.textContent = props[key];\n } else if (key.startsWith('on')) {\n // Skip event handlers for now - they'll be attached separately\n } else {\n // Set attribute\n element.setAttribute(key, props[key]);\n }\n });\n \n container.appendChild(element);\n }\n}\n\n/**\n * Performs direct DOM updates by finding elements with data-ref attributes\n * and updating their content to match the current state. This approach ensures\n * that UI elements stay synchronized with component state without full re-rendering.\n * \n * @param {HTMLElement} rootElement - The root component element to search within\n * @param {Object} state - The current state object containing updated values\n * @since 0.1.2\n */\nfunction updateDOMElementsDirectly(rootElement, state) {\n // Update elements with data-ref attributes that correspond to state values\n const refElements = rootElement.querySelectorAll('[data-ref]');\n refElements.forEach(element => {\n const ref = element.getAttribute('data-ref');\n if (ref && state.hasOwnProperty(ref)) {\n // Update text content based on the reference\n if (ref === 'count') {\n element.textContent = `Count: ${state.count}`;\n } else if (ref === 'step') {\n element.textContent = `Step: ${state.step}`;\n } else {\n element.textContent = state[ref];\n }\n }\n });\n \n // Update input values that correspond to state\n const inputs = rootElement.querySelectorAll('input');\n inputs.forEach(input => {\n if (input.type === 'number' && state.step !== undefined) {\n input.value = state.step;\n } else if (input.type === 'text' && state.newTodo !== undefined) {\n // DON'T override input value if user is actively typing\n // Only update if the input is not focused (user not typing)\n if (document.activeElement !== input) {\n input.value = state.newTodo;\n }\n }\n });\n}\n\n/**\n * Updates dynamic content sections such as lists, statistics, and interactive elements.\n * This function handles complex UI updates that require more than simple text replacement,\n * including filtering, sorting, and structural changes to the DOM.\n * \n * @param {HTMLElement} rootElement - The root component element containing dynamic content\n * @param {Object} state - The current state object with updated data\n * @since 0.1.2\n */\nfunction updateDynamicContent(rootElement, state) {\n // Update todo list if present\n if (state.todos !== undefined) {\n updateTodoList(rootElement, state);\n }\n \n // Update todo stats if present\n if (state.todos !== undefined) {\n updateTodoStats(rootElement, state);\n }\n \n // Update filter buttons if present\n if (state.filter !== undefined) {\n updateFilterButtons(rootElement, state);\n }\n}\n\n/**\n * Updates the todo list display by rebuilding the list items based on current state.\n * Handles filtering (all/active/completed) and creates new DOM elements for each todo.\n * After updating the DOM, re-attaches event handlers to ensure interactivity.\n * \n * @param {HTMLElement} rootElement - The root component element containing the todo list\n * @param {Object} state - The current state object containing todos array and filter settings\n * @since 0.1.2\n */\nfunction updateTodoList(rootElement, state) {\n const todoList = rootElement.querySelector('.todo-list');\n if (!todoList) return;\n \n // Filter todos based on current filter\n const filteredTodos = state.todos.filter(todo => {\n if (state.filter === 'active') return !todo.completed;\n if (state.filter === 'completed') return todo.completed;\n return true;\n });\n \n // Clear current list\n todoList.innerHTML = '';\n \n // Add filtered todos\n filteredTodos.forEach(todo => {\n const li = document.createElement('li');\n li.className = `todo-item ${todo.completed ? 'completed' : ''}`;\n \n li.innerHTML = `\n <input type=\"checkbox\" ${todo.completed ? 'checked' : ''} class=\"todo-checkbox\" data-todo-id=\"${todo.id}\">\n <span class=\"todo-text\">${todo.text}</span>\n <button class=\"btn btn-danger btn-small\" data-todo-id=\"${todo.id}\" data-action=\"remove\">\u00D7</button>\n `;\n \n todoList.appendChild(li);\n });\n \n // Re-attach function-based event handlers to newly created DOM elements\n // This is necessary because manually created DOM elements don't automatically get\n // the function-based handlers from the virtual DOM\n reattachTodoEventHandlers(rootElement, state);\n}\n\n/**\n * Update todo statistics display\n * \n * @param {HTMLElement} rootElement - The root component element\n * @param {Object} state - The new state\n */\nfunction updateTodoStats(rootElement, state) {\n const statsElement = rootElement.querySelector('.todo-stats');\n if (!statsElement || !state.todos) return;\n \n const stats = {\n total: state.todos.length,\n completed: state.todos.filter(todo => todo.completed).length,\n active: state.todos.filter(todo => !todo.completed).length\n };\n \n statsElement.innerHTML = `\n <span class=\"stat-item\">Total: ${stats.total}</span>\n <span class=\"stat-item\">Active: ${stats.active}</span>\n <span class=\"stat-item\">Completed: ${stats.completed}</span>\n `;\n}\n\n/**\n * Update filter button states\n * \n * @param {HTMLElement} rootElement - The root component element\n * @param {Object} state - The new state\n */\nfunction updateFilterButtons(rootElement, state) {\n const filterButtons = rootElement.querySelectorAll('.filter-btn');\n filterButtons.forEach(button => {\n const buttonText = button.textContent.toLowerCase();\n if (buttonText === state.filter || (buttonText === 'all' && state.filter === 'all')) {\n button.classList.add('active');\n } else {\n button.classList.remove('active');\n }\n });\n}\n\n/**\n * Re-attaches event handlers to dynamically created todo items after DOM updates.\n * This function is essential for maintaining interactivity when todo items are\n * recreated during state changes. Handles both delete buttons and toggle checkboxes.\n * \n * @param {HTMLElement} rootElement - The root component element containing todo items\n * @param {Object} state - The current state object for context\n * @since 0.1.2\n */\nfunction reattachTodoEventHandlers(rootElement) {\n // Find the component instance to get access to the component's handlers\n const componentInstance = rootElement.__coherentInstance;\n if (!componentInstance || !componentInstance.component) {\n console.warn('\u26A0\uFE0F No component instance found for re-attaching todo event handlers');\n return;\n }\n \n // Get the component's removeTodo and toggleTodo functions\n // These should be available in the component's scope\n const component = componentInstance.component;\n \n // Re-attach delete button handlers\n const deleteButtons = rootElement.querySelectorAll('button[data-action=\"remove\"]');\n deleteButtons.forEach(button => {\n const todoId = parseInt(button.getAttribute('data-todo-id'));\n if (todoId) {\n // Remove any existing handler to prevent duplicates\n const handlerKey = `__coherent_click_handler`;\n if (button[handlerKey]) {\n button.removeEventListener('click', button[handlerKey]);\n }\n \n // Create new handler that calls the component's removeTodo function\n const clickHandler = (event) => {\n event.preventDefault();\n \n // Get current state and setState from component\n if (component.__stateContainer) {\n const currentState = component.__stateContainer.getState();\n const setState = component.__stateContainer.setState.bind(component.__stateContainer);\n \n // Remove the todo\n setState({\n todos: currentState.todos.filter(todo => todo.id !== todoId)\n });\n \n // Trigger DOM update to reflect the state change\n const updatedState = component.__stateContainer.getState();\n updateDOMWithState(rootElement, updatedState);\n }\n };\n \n // Attach the handler\n button.addEventListener('click', clickHandler);\n button[handlerKey] = clickHandler;\n }\n });\n \n // Re-attach checkbox handlers\n const checkboxes = rootElement.querySelectorAll('.todo-checkbox');\n checkboxes.forEach(checkbox => {\n const todoId = parseInt(checkbox.getAttribute('data-todo-id'));\n if (todoId) {\n // Remove any existing handler to prevent duplicates\n const handlerKey = `__coherent_change_handler`;\n if (checkbox[handlerKey]) {\n checkbox.removeEventListener('change', checkbox[handlerKey]);\n }\n \n // Create new handler that calls the component's toggleTodo function\n const changeHandler = () => {\n // Get current state and setState from component\n if (component.__stateContainer) {\n const currentState = component.__stateContainer.getState();\n const setState = component.__stateContainer.setState.bind(component.__stateContainer);\n \n // Toggle the todo\n setState({\n todos: currentState.todos.map(todo => \n todo.id === todoId ? { ...todo, completed: !todo.completed } : todo\n )\n });\n \n // Trigger DOM update to reflect the state change\n const updatedState = component.__stateContainer.getState();\n updateDOMWithState(rootElement, updatedState);\n }\n };\n \n // Attach the handler\n checkbox.addEventListener('change', changeHandler);\n checkbox[handlerKey] = changeHandler;\n }\n });\n}\n\n/**\n * Attaches function-based event listeners from virtual DOM definitions to real DOM elements.\n * This is the core mechanism that enables interactive components by bridging the gap\n * between virtual DOM event handlers and actual browser events. Prevents duplicate\n * handlers and ensures proper state management integration.\n * \n * @param {HTMLElement} rootElement - The root DOM element to search for event targets\n * @param {Object} virtualElement - The virtual DOM element containing function handlers\n * @param {Object} instance - The component instance providing state and context\n * @since 0.1.2\n */\nfunction attachFunctionEventListeners(rootElement, virtualElement, instance, options = {}) {\n if (!rootElement || !virtualElement || typeof window === 'undefined') {\n return;\n }\n \n // Helper function to traverse virtual DOM and find function handlers\n function traverseAndAttach(domElement, vElement, path = []) {\n if (!vElement || typeof vElement !== 'object') return;\n \n // Handle array of virtual elements\n if (Array.isArray(vElement)) {\n vElement.forEach((child, index) => {\n const childElement = domElement.children[index];\n if (childElement) {\n traverseAndAttach(childElement, child, [...path, index]);\n }\n });\n return;\n }\n \n // Handle single virtual element\n const tagName = Object.keys(vElement)[0];\n const elementProps = vElement[tagName];\n \n if (elementProps && typeof elementProps === 'object') {\n // Look for event handler functions\n const eventHandlers = ['onclick', 'onchange', 'oninput', 'onfocus', 'onblur', 'onsubmit', 'onkeypress', 'onkeydown', 'onkeyup', 'onmouseenter', 'onmouseleave'];\n \n eventHandlers.forEach(eventName => {\n const handler = elementProps[eventName];\n if (typeof handler === 'function') {\n const eventType = eventName.substring(2); // Remove 'on' prefix\n \n // If inputsOnly option is set, only attach input-related events and click events on dynamically generated elements\n if (options.inputsOnly) {\n const inputEvents = ['input', 'change', 'keypress'];\n const isDynamicElement = domElement.closest('.todo-item') || domElement.closest('[data-dynamic]');\n \n if (!inputEvents.includes(eventType) && !(eventType === 'click' && isDynamicElement)) {\n return; // Skip non-input events except clicks on dynamic elements\n }\n }\n \n // Special handling for input events\n \n // Check if handler is already attached to prevent duplicates\n const handlerKey = `__coherent_${eventType}_handler`;\n if (domElement[handlerKey]) {\n // Remove the old handler first\n domElement.removeEventListener(eventType, domElement[handlerKey]);\n delete domElement[handlerKey];\n }\n \n // Create a wrapper that provides component context\n const wrappedHandler = (event) => {\n try {\n // Only prevent default for non-input events and non-form events\n if (eventType !== 'input' && eventType !== 'change' && eventType !== 'keypress') {\n event.preventDefault();\n }\n \n // Execute the function handler with proper context\n \n // Extract state and setState from the component's current execution context\n let currentState = {};\n let currentSetState = () => {};\n \n // For withState components, use the state container\n if (instance.component && instance.component.__stateContainer) {\n currentState = instance.component.__stateContainer.getState();\n currentSetState = (newState) => {\n // Call the component's setState method\n instance.component.__stateContainer.setState(newState);\n \n // Update the instance state for consistency\n if (instance.state && typeof newState === 'object') {\n Object.assign(instance.state, newState);\n }\n \n // Get the updated state after setState\n instance.component.__stateContainer.getState();\n \n // Trigger component re-render to reflect the new state\n const componentRoot = domElement.closest('[data-coherent-component]');\n if (componentRoot && componentRoot.__coherentInstance) {\n componentRoot.__coherentInstance.rerender();\n }\n };\n } else if (instance.state) {\n // Fallback for non-withState components\n currentState = instance.state;\n currentSetState = (newState) => {\n if (typeof newState === 'object') {\n Object.assign(instance.state, newState);\n }\n \n // Trigger component re-render to reflect the new state\n const componentRoot = domElement.closest('[data-coherent-component]');\n if (componentRoot && componentRoot.__coherentInstance) {\n componentRoot.__coherentInstance.rerender();\n }\n };\n }\n \n // Call the original handler with event, state, and setState\n const result = handler.call(domElement, event, currentState, currentSetState);\n \n return result;\n } catch (_error) {\n console.error(`Error in ${eventName} handler:`, _error);\n }\n };\n \n // Remove any existing onclick attributes that might interfere\n if (domElement.hasAttribute(eventName)) {\n domElement.removeAttribute(eventName);\n }\n \n // Store the handler reference to prevent duplicates\n domElement[handlerKey] = wrappedHandler;\n \n // Add the new event listener (use capture only for non-input events)\n const useCapture = eventType !== 'input' && eventType !== 'change';\n domElement.addEventListener(eventType, wrappedHandler, useCapture);\n \n // Input event handler attached successfully\n \n // Add to instance's event listeners for cleanup\n if (instance.eventListeners && Array.isArray(instance.eventListeners)) {\n instance.eventListeners.push({\n element: domElement,\n event: eventType,\n handler: wrappedHandler\n });\n }\n }\n });\n \n // Recursively handle children\n if (elementProps.children) {\n const children = Array.isArray(elementProps.children) ? elementProps.children : [elementProps.children];\n children.forEach((child, index) => {\n const childElement = domElement.children[index];\n if (childElement && child) {\n traverseAndAttach(childElement, child, [...path, 'children', index]);\n }\n });\n }\n }\n }\n \n // Start traversal from the root\n traverseAndAttach(rootElement, virtualElement);\n}\n\n/**\n * Attach event listeners from data attributes\n * \n * @param {HTMLElement} element - The root element\n * @param {Object} instance - The component instance\n */\nfunction attachEventListeners(element, instance) {\n // Check if we're in a browser environment\n try {\n // Clear any existing event listeners if this is a re-hydration\n if (instance && instance.eventListeners && Array.isArray(instance.eventListeners)) {\n instance.eventListeners.forEach(({ element, event, handler }) => {\n if (element && typeof element.removeEventListener === 'function') {\n element.removeEventListener(event, handler);\n }\n });\n instance.eventListeners = [];\n }\n \n // Check if we're in a browser environment\n if (typeof window === 'undefined' || typeof document === 'undefined') {\n return;\n }\n \n // Check if element has required methods\n if (!element || typeof element.querySelectorAll !== 'function') {\n return;\n }\n \n // Find all elements with data-action attributes\n const actionElements = element.querySelectorAll('[data-action]');\n \n actionElements.forEach(actionElement => {\n // Check if element has required methods\n if (!actionElement || typeof actionElement.getAttribute !== 'function') return;\n \n const action = actionElement.getAttribute('data-action');\n const target = actionElement.getAttribute('data-target') || 'default';\n const event = actionElement.getAttribute('data-event') || 'click';\n \n if (action) {\n const handler = (e) => {\n if (e && typeof e.preventDefault === 'function') {\n e.preventDefault(); // Prevent default behavior for better control\n }\n handleComponentAction(e, action, target, instance);\n };\n \n // Add event listener\n if (typeof actionElement.addEventListener === 'function') {\n actionElement.addEventListener(event, handler);\n \n // Store for cleanup\n if (instance.eventListeners && Array.isArray(instance.eventListeners)) {\n instance.eventListeners.push({\n element: actionElement,\n event,\n handler\n });\n }\n }\n }\n });\n \n // Check for inline event attributes and warn users to use safer alternatives\n const eventAttributes = ['onclick', 'onchange', 'oninput', 'onfocus', 'onblur', 'onsubmit'];\n \n eventAttributes.forEach(eventName => {\n const attributeSelector = `[${eventName}]`;\n const elements = element.querySelectorAll(attributeSelector);\n \n elements.forEach(elementWithEvent => {\n // Check if element has required methods\n if (!elementWithEvent || typeof elementWithEvent.getAttribute !== 'function') return;\n \n const eventAttr = elementWithEvent.getAttribute(eventName);\n \n if (eventAttr) {\n // Warn about inline event attributes - they are not supported for security reasons\n console.warn(\n `[Coherent.js] Inline event attribute \"${eventName}=\"${eventAttr}\" found but not supported.\\n` +\n `For security and CSP compliance, use one of these alternatives:\\n` +\n `1. Function-based handlers: Pass functions directly in virtual DOM\\n` +\n `2. Data-action registry: <button data-action=\"actionId\" data-event=\"click\">\\n` +\n `3. Event registry: <button data-coherent-event=\"handlerId\" data-coherent-event-type=\"click\">\\n` +\n `See documentation for details.`\n );\n }\n });\n });\n \n // Also look for data-action attributes (new approach)\n const dataActionElements = element.querySelectorAll('[data-action]');\n \n dataActionElements.forEach(actionElement => {\n // Check if element has required methods\n if (!actionElement || typeof actionElement.getAttribute !== 'function') return;\n \n const actionId = actionElement.getAttribute('data-action');\n const eventType = actionElement.getAttribute('data-event') || 'click';\n \n if (actionId) {\n // Get the function from the action registry\n let handlerFunc = null;\n \n // Try to get from action registry (server-side stored)\n if (typeof window !== 'undefined' && window.__coherentActionRegistry && window.__coherentActionRegistry[actionId]) {\n handlerFunc = window.__coherentActionRegistry[actionId];\n } else {\n console.warn(`No handler found for action ${actionId}`, window.__coherentActionRegistry);\n }\n \n if (handlerFunc && typeof handlerFunc === 'function') {\n // Mark as processed to avoid duplicate handling\n if (typeof actionElement.hasAttribute === 'function' && !actionElement.hasAttribute(`data-hydrated-${eventType}`)) {\n actionElement.setAttribute(`data-hydrated-${eventType}`, 'true');\n \n const handler = (e) => {\n try {\n // Try to find the component instance associated with this element\n let componentElement = actionElement;\n while (componentElement && !componentElement.hasAttribute('data-coherent-component')) {\n componentElement = componentElement.parentElement;\n }\n \n if (componentElement && componentElement.__coherentInstance) {\n // We found the component instance\n const instance = componentElement.__coherentInstance;\n const state = instance.state || {};\n const setState = instance.setState || (() => {});\n \n // Call the handler function with the element as context and pass event, state, setState\n handlerFunc.call(actionElement, e, state, setState);\n } else {\n // Fallback: call the handler without component context\n handlerFunc.call(actionElement, e);\n }\n } catch (_error) {\n console.warn(`Error executing action handler for ${actionId}:`, _error);\n }\n };\n \n if (typeof actionElement.addEventListener === 'function') {\n actionElement.addEventListener(eventType, handler);\n if (instance && instance.eventListeners && Array.isArray(instance.eventListeners)) {\n instance.eventListeners.push({\n element: actionElement,\n event: eventType,\n handler\n });\n }\n }\n }\n }\n }\n });\n \n // Also look for Coherent-specific event handlers (data-coherent-event)\n const coherentEventElements = element.querySelectorAll('[data-coherent-event]');\n \n coherentEventElements.forEach(elementWithCoherentEvent => {\n // Check if element has required methods\n if (!elementWithCoherentEvent || typeof elementWithCoherentEvent.getAttribute !== 'function') return;\n \n const eventId = elementWithCoherentEvent.getAttribute('data-coherent-event');\n const eventType = elementWithCoherentEvent.getAttribute('data-coherent-event-type');\n \n if (eventId && eventType) {\n // Get the function from the registry\n let handlerFunc = null;\n \n // Try to get from global registry (server-side stored)\n if (typeof window !== 'undefined' && window.__coherentEventRegistry && window.__coherentEventRegistry[eventId]) {\n handlerFunc = window.__coherentEventRegistry[eventId];\n }\n \n if (handlerFunc && typeof handlerFunc === 'function') {\n // Mark as processed to avoid duplicate handling\n if (typeof elementWithCoherentEvent.hasAttribute === 'function' && !elementWithCoherentEvent.hasAttribute(`data-hydrated-${eventType}`)) {\n elementWithCoherentEvent.setAttribute(`data-hydrated-${eventType}`, 'true');\n \n const handler = (e) => {\n try {\n // Call the original function with proper context\n // Pass the event, state, and setState as parameters\n const state = instance.state || {};\n const setState = instance.setState || (() => {});\n \n // Bind the function to the element and call it with the event\n handlerFunc.call(elementWithCoherentEvent, e, state, setState);\n } catch (_error) {\n console.warn(`Error executing coherent event handler:`, _error);\n }\n };\n \n if (typeof elementWithCoherentEvent.addEventListener === 'function') {\n elementWithCoherentEvent.addEventListener(eventType, handler);\n if (instance.eventListeners && Array.isArray(instance.eventListeners)) {\n instance.eventListeners.push({\n element: elementWithCoherentEvent,\n event: eventType,\n handler\n });\n }\n }\n }\n }\n }\n });\n \n } catch (_error) {\n console.warn('Error attaching event listeners:', _error);\n }\n}\n\n/**\n * Handle component actions\n * \n * @param {Event} event - The DOM event\n * @param {string} action - The action name\n * @param {string} target - The target identifier\n * @param {Object} instance - The component instance\n */\nfunction handleComponentAction(event, action, target, instance) {\n // Handle common actions\n switch (action) {\n case 'increment':\n if (instance.state && instance.state.count !== undefined) {\n const step = instance.state.step || 1;\n instance.setState({count: instance.state.count + step});\n \n // Update the DOM directly for immediate feedback\n const countElement = instance.element.querySelector('[data-ref=\"count\"]');\n if (countElement) {\n countElement.textContent = `Count: ${instance.state.count + step}`;\n }\n }\n break;\n case 'decrement':\n if (instance.state && instance.state.count !== undefined) {\n const step = instance.state.step || 1;\n instance.setState({count: instance.state.count - step});\n \n // Update the DOM directly for immediate feedback\n const countElement = instance.element.querySelector('[data-ref=\"count\"]');\n if (countElement) {\n countElement.textContent = `Count: ${instance.state.count - step}`;\n }\n }\n break;\n case 'reset':\n if (instance.state) {\n const initialCount = instance.props.initialCount || 0;\n instance.setState({count: initialCount});\n \n // Update the DOM directly for immediate feedback\n const countElement = instance.element.querySelector('[data-ref=\"count\"]');\n if (countElement) {\n countElement.textContent = `Count: ${initialCount}`;\n }\n }\n break;\n case 'changeStep':\n // Get the input value\n const inputElement = event.target;\n if (inputElement && inputElement.value) {\n const stepValue = parseInt(inputElement.value, 10);\n if (!isNaN(stepValue) && stepValue >= 1 && stepValue <= 10) {\n instance.setState({step: stepValue});\n \n // Update the DOM directly for immediate feedback\n const stepElement = instance.element.querySelector('[data-ref=\"step\"]');\n if (stepElement) {\n stepElement.textContent = `Step: ${stepValue}`;\n }\n }\n }\n break;\n case 'toggle':\n const todoIndex = event.target && event.target.getAttribute ? \n parseInt(event.target.getAttribute('data-todo-index')) : -1;\n if (todoIndex >= 0 && instance.state && instance.state.todos && instance.state.todos[todoIndex]) {\n const newTodos = [...instance.state.todos];\n newTodos[todoIndex].completed = !newTodos[todoIndex].completed;\n instance.setState({todos: newTodos});\n }\n break;\n case 'add':\n if (typeof document !== 'undefined' && document.getElementById) {\n const input = document.getElementById(`new-todo-${target}`);\n if (input && input.value && input.value.trim()) {\n if (instance.state && instance.state.todos) {\n const newTodos = [\n ...instance.state.todos,\n { text: input.value.trim(), completed: false }\n ];\n instance.setState({todos: newTodos});\n input.value = '';\n }\n }\n }\n break;\n default:\n // Check if this is a custom method on the instance\n if (instance && typeof instance[action] === 'function') {\n try {\n // Call the custom method on the instance\n instance[action](event, target);\n } catch (_error) {\n console.warn(`Error executing custom action ${action}:`, _error);\n }\n } else {\n // Check if this is a function handler in the action registry\n if (typeof window !== 'undefined' && window.__coherentActionRegistry && window.__coherentActionRegistry[action]) {\n const handlerFunc = window.__coherentActionRegistry[action];\n \n // Get the component state and setState function if available\n const state = instance ? (instance.state || {}) : {};\n const setState = instance && instance.setState ? instance.setState.bind(instance) : (() => {});\n \n try {\n // Call the handler function with event, state, and setState\n handlerFunc(event, state, setState);\n } catch (_error) {\n console.warn(`Error executing action handler ${action}:`, _error);\n }\n } else {\n // Custom action handling would go here\n // Custom action executed\n }\n }\n }\n}\n\n/**\n * Hydrate multiple elements with their corresponding components\n * \n * @param {Array} elements - Array of DOM elements to hydrate\n * @param {Array} components - Array of Coherent component functions\n * @param {Array} propsArray - Array of props for each component\n * @returns {Array} Array of hydrated component instances\n */\nfunction hydrateAll(elements, components, propsArray = []) {\n if (elements.length !== components.length) {\n throw new Error('Number of elements must match number of components');\n }\n \n return elements.map((element, index) => {\n const component = components[index];\n const props = propsArray[index] || {};\n return hydrate(element, component, props);\n });\n}\n\n/**\n * Find and hydrate elements by CSS selector\n * \n * @param {string} selector - CSS selector to find elements\n * @param {Function} component - The Coherent component function\n * @param {Object} props - The props to pass to the component\n * @returns {Array} Array of hydrated component instances\n */\nfunction hydrateBySelector(selector, component, props = {}) {\n if (typeof window === 'undefined' || !document.querySelectorAll) {\n return [];\n }\n \n const elements = document.querySelectorAll(selector);\n return Array.from(elements).map(element => hydrate(element, component, props));\n}\n\n/**\n * Enable client-side interactivity for event handlers\n * \n * @param {HTMLElement} rootElement - The root element to enable events on\n */\nfunction enableClientEvents(rootElement = document) {\n if (typeof window === 'undefined' || !rootElement.querySelectorAll) {\n return;\n }\n \n // This function is now handled automatically during hydration\n // but can be called to enable events on dynamically added elements\n // Client events enabled\n}\n\n/**\n * Create a hydratable component\n * \n * @param {Function} component - The Coherent component function\n * @param {Object} options - Hydration options\n * @returns {Function} A component that can be hydrated\n */\nfunction makeHydratable(component, options = {}) {\n // Extract component name from options or use function name\n const componentName = options.componentName || component.name || 'AnonymousComponent';\n \n // Create a new function that wraps the original component\n const hydratableComponent = function(props = {}) {\n return component(props);\n };\n \n // Set the component name on the hydratable component function\n Object.defineProperty(hydratableComponent, 'name', {\n value: componentName,\n writable: false\n });\n \n // Copy all properties from the original component, including withState metadata\n Object.keys(component).forEach(key => {\n hydratableComponent[key] = component[key];\n });\n \n // Copy prototype if it exists\n if (component.prototype) {\n hydratableComponent.prototype = Object.create(component.prototype);\n }\n \n // Special handling for withState wrapped components\n if (component.__wrappedComponent && component.__stateContainer) {\n hydratableComponent.__wrappedComponent = component.__wrappedComponent;\n hydratableComponent.__stateContainer = component.__stateContainer;\n }\n \n // Add hydration metadata to the component\n hydratableComponent.isHydratable = true;\n hydratableComponent.hydrationOptions = options;\n \n // Add auto-hydration functionality\n hydratableComponent.autoHydrate = function(componentRegistry = {}) {\n // Register this component if not already registered\n if (!componentRegistry[hydratableComponent.name || 'AnonymousComponent']) {\n componentRegistry[hydratableComponent.name || 'AnonymousComponent'] = hydratableComponent;\n }\n \n // Call the global autoHydrate function\n autoHydrate(componentRegistry);\n };\n \n // Mark this component as hydratable\n hydratableComponent.isHydratable = true;\n \n // Add a method to manually set hydration data for cases where we need to override\n hydratableComponent.withHydrationData = function(customProps = {}, customState = null) {\n return {\n render: function(props = {}) {\n const mergedProps = { ...customProps, ...props };\n const result = hydratableComponent(mergedProps);\n const hydrationData = hydratableComponent.getHydrationData(mergedProps, customState);\n \n // Add hydration attributes to the root element\n if (result && typeof result === 'object' && !Array.isArray(result)) {\n const tagName = Object.keys(result)[0];\n const elementProps = result[tagName];\n \n if (elementProps && typeof elementProps === 'object') {\n // Add hydration attributes\n Object.keys(hydrationData.hydrationAttributes).forEach(attr => {\n const value = hydrationData.hydrationAttributes[attr];\n if (value !== null) {\n elementProps[attr] = value;\n }\n });\n }\n }\n \n return result;\n }\n };\n };\n\n // Add a method to get hydration data\n hydratableComponent.getHydrationData = function(props = {}, state = null) {\n return {\n componentName: componentName,\n props,\n initialState: options.initialState,\n // Add data attributes for hydration\n hydrationAttributes: {\n 'data-coherent-component': componentName,\n 'data-coherent-state': state ? JSON.stringify(state) : (options.initialState ? JSON.stringify(options.initialState) : null),\n 'data-coherent-props': Object.keys(props).length > 0 ? JSON.stringify(props) : null\n }\n };\n };\n\n // Add a method to render with hydration data\n hydratableComponent.renderWithHydration = function(props = {}) {\n const result = hydratableComponent(props);\n \n // Try to extract state from the component if it's a withState wrapped component\n let state = null;\n if (hydratableComponent.__wrappedComponent && hydratableComponent.__stateContainer) {\n // This is a withState wrapped component, try to get its state\n try {\n state = hydratableComponent.__stateContainer.getState();\n } catch (e) {\n // If we can't get the state, that's OK\n console.warn('Could not get component state:', e);\n }\n }\n \n const hydrationData = hydratableComponent.getHydrationData(props, state);\n \n // Add hydration attributes to the root element\n if (result && typeof result === 'object' && !Array.isArray(result)) {\n const tagName = Object.keys(result)[0];\n const elementProps = result[tagName];\n \n if (elementProps && typeof elementProps === 'object') {\n // Add hydration attributes\n Object.keys(hydrationData.hydrationAttributes).forEach(attr => {\n const value = hydrationData.hydrationAttributes[attr];\n if (value !== null) {\n elementProps[attr] = value;\n }\n });\n }\n }\n \n return result;\n };\n \n return hydratableComponent;\n}\n\n/**\n * Auto-hydrate all components on page load\n * \n * @param {Object} componentRegistry - Registry of component functions\n */\nfunction autoHydrate(componentRegistry = {}) {\n if (typeof window === 'undefined' || typeof document === 'undefined') {\n return;\n }\n \n // autoHydrate called\n \n // Check if registry is actually the window object (common mistake)\n if (componentRegistry === window) {\n console.warn('\u26A0\uFE0F Component registry is the window object! This suggests the registry was not properly initialized.');\n // Falling back to window.componentRegistry\n componentRegistry = window.componentRegistry || {};\n }\n \n // Initialize registries if they don't exist\n window.__coherentEventRegistry = window.__coherentEventRegistry || {};\n window.__coherentActionRegistry = window.__coherentActionRegistry || {};\n \n // Wait for DOM to be ready\n const hydrateComponents = () => {\n const hydrateableElements = document.querySelectorAll('[data-coherent-component]');\n \n hydrateableElements.forEach(element => {\n const componentName = element.getAttribute('data-coherent-component');\n \n // Look for the component in the registry\n let component = componentRegistry[componentName];\n \n // If not found by exact name, try to find it by checking if it's a hydratable component\n if (!component) {\n // Component not found by name, searching registry...\n for (const comp of Object.values(componentRegistry)) {\n if (comp && comp.isHydratable) {\n component = comp;\n break;\n }\n }\n }\n \n if (!component) {\n console.error(`\u274C Component ${componentName} not found in registry`);\n return; // Skip this element\n }\n \n if (component) {\n try {\n // Extract props from data attributes\n const propsAttr = element.getAttribute('data-coherent-props');\n const props = propsAttr ? JSON.parse(propsAttr) : {};\n \n // Extract initial state\n const stateAttr = element.getAttribute('data-coherent-state');\n const initialState = stateAttr ? JSON.parse(stateAttr) : null;\n \n // Hydrate the component\n const instance = hydrate(element, component, props, { initialState });\n \n if (instance) {\n // Component auto-hydrated successfully\n } else {\n console.warn(`\u274C Failed to hydrate component: ${componentName}`);\n }\n } catch (_error) {\n console.error(`\u274C Failed to auto-hydrate component ${componentName}:`, _error);\n }\n }\n });\n \n // Also enable client events for any remaining elements\n enableClientEvents();\n };\n \n // Run hydration when DOM is ready\n if (document.readyState === 'loading') {\n document.addEventListener('DOMContentLoaded', hydrateComponents);\n } else {\n hydrateComponents();\n }\n}\n\n// Also export individual functions for convenience\nexport {\n hydrate,\n hydrateAll,\n hydrateBySelector,\n enableClientEvents,\n makeHydratable,\n autoHydrate\n};\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": ["
|
|
3
|
+
"sources": ["../src/events/registry.js", "../src/events/wrapper.js", "../src/events/delegation.js", "../src/hydration/state-serializer.js", "../src/hydration/mismatch-detector.js", "../src/hydrate.js", "../src/hmr/cleanup-tracker.js", "../src/hmr/state-capturer.js", "../src/hmr/overlay.js", "../src/hmr/indicator.js", "../src/hmr/module-tracker.js", "../src/hmr/client.js"],
|
|
4
|
+
"sourcesContent": ["/**\n * Handler Registry for Coherent.js Event Delegation\n *\n * Maps handler IDs to their corresponding functions and component context.\n * Handlers are identified by ID (from data-coherent-{event} attributes) rather\n * than by element reference, allowing them to survive DOM updates.\n */\n\n/**\n * HandlerRegistry class\n * Stores handler functions with their associated component context\n */\nexport class HandlerRegistry {\n constructor() {\n /** @type {Map<string, {handler: Function, componentRef: object|null}>} */\n this.handlers = new Map();\n }\n\n /**\n * Register a handler with optional component context\n * @param {string} handlerId - Unique identifier for the handler\n * @param {Function} handler - The event handler function\n * @param {object|null} componentRef - Optional component reference with state/setState\n */\n register(handlerId, handler, componentRef = null) {\n if (typeof handler !== 'function') {\n throw new Error(`Handler must be a function, received: ${typeof handler}`);\n }\n this.handlers.set(handlerId, { handler, componentRef });\n }\n\n /**\n * Unregister a handler by ID\n * @param {string} handlerId - The handler ID to remove\n * @returns {boolean} True if handler was removed, false if not found\n */\n unregister(handlerId) {\n return this.handlers.delete(handlerId);\n }\n\n /**\n * Get a handler entry by ID\n * @param {string} handlerId - The handler ID to look up\n * @returns {{handler: Function, componentRef: object|null}|undefined} Handler entry or undefined\n */\n get(handlerId) {\n return this.handlers.get(handlerId);\n }\n\n /**\n * Check if a handler is registered\n * @param {string} handlerId - The handler ID to check\n * @returns {boolean} True if handler exists\n */\n has(handlerId) {\n return this.handlers.has(handlerId);\n }\n\n /**\n * Clear all registered handlers\n */\n clear() {\n this.handlers.clear();\n }\n\n /**\n * Get all handler IDs registered for a specific component\n * @param {object} componentRef - The component reference to search for\n * @returns {string[]} Array of handler IDs belonging to this component\n */\n getByComponent(componentRef) {\n if (!componentRef) {\n return [];\n }\n\n const handlerIds = [];\n for (const [handlerId, entry] of this.handlers) {\n if (entry.componentRef === componentRef) {\n handlerIds.push(handlerId);\n }\n }\n return handlerIds;\n }\n\n /**\n * Get the number of registered handlers\n * @returns {number} Count of registered handlers\n */\n get size() {\n return this.handlers.size;\n }\n}\n\n/**\n * Singleton handler registry instance\n * Use this for global event delegation\n */\nexport const handlerRegistry = new HandlerRegistry();\n", "/**\n * Event Wrapper for Coherent.js\n *\n * Wraps native DOM events with component context, providing handlers\n * access to component state, setState, and props.\n */\n\n/**\n * @typedef {object} CoherentEvent\n * @property {Event} originalEvent - The native DOM event\n * @property {Element} target - The element with the data-coherent-* attribute\n * @property {function(): void} preventDefault - Delegates to originalEvent.preventDefault()\n * @property {function(): void} stopPropagation - Delegates to originalEvent.stopPropagation()\n * @property {function|null} component - The component function (if available)\n * @property {object|null} state - Current component state (if available)\n * @property {function|null} setState - State setter function (if available)\n * @property {object|null} props - Component props (if available)\n */\n\n/**\n * Wrap a native DOM event with component context\n *\n * @param {Event} originalEvent - The native DOM event\n * @param {Element} target - The element that matched the data attribute selector\n * @param {object|null} componentRef - Optional component reference object\n * @param {function} [componentRef.component] - The component function\n * @param {object} [componentRef.state] - Current component state\n * @param {function} [componentRef.setState] - State setter function\n * @param {object} [componentRef.props] - Component props\n * @returns {CoherentEvent} Wrapped event with component context\n */\nexport function wrapEvent(originalEvent, target, componentRef = null) {\n return {\n // Native event access\n originalEvent,\n target,\n\n // Delegate common methods\n preventDefault() {\n originalEvent.preventDefault();\n },\n\n stopPropagation() {\n originalEvent.stopPropagation();\n },\n\n // Component context (null if no componentRef provided)\n component: componentRef?.component ?? null,\n state: componentRef?.state ?? null,\n setState: componentRef?.setState ?? null,\n props: componentRef?.props ?? null,\n };\n}\n", "/**\n * Event Delegation for Coherent.js\n *\n * Document-level event delegation that routes events to handlers via\n * data-coherent-{eventType} attributes. This ensures event handlers\n * survive DOM updates since they're registered by ID, not by element.\n */\n\nimport { handlerRegistry as defaultRegistry } from './registry.js';\nimport { wrapEvent } from './wrapper.js';\n\n/**\n * EventDelegation class\n * Manages document-level event listeners and routes to registered handlers\n */\nexport class EventDelegation {\n /**\n * @param {import('./registry.js').HandlerRegistry} [registry] - Handler registry instance\n */\n constructor(registry = defaultRegistry) {\n this.registry = registry;\n this.initialized = false;\n this.root = null;\n this.boundHandlers = new Map();\n\n /**\n * Event types to delegate\n * Focus/blur use capture phase because they don't bubble\n */\n this.eventTypes = [\n 'click',\n 'change',\n 'input',\n 'submit',\n 'focus',\n 'blur',\n 'keydown',\n 'keyup',\n 'keypress',\n ];\n }\n\n /**\n * Initialize event delegation by attaching listeners to the root element\n * @param {Document|Element} [root=document] - Root element for event delegation\n */\n initialize(root = typeof document !== 'undefined' ? document : null) {\n if (this.initialized) {\n return;\n }\n\n if (!root) {\n // No DOM available (SSR context)\n return;\n }\n\n this.root = root;\n\n for (const eventType of this.eventTypes) {\n const handler = (event) => this.handleEvent(event, eventType);\n\n // Focus and blur don't bubble - must use capture phase\n const useCapture = eventType === 'focus' || eventType === 'blur';\n\n // Submit needs preventDefault capability, others can be passive\n const options = {\n capture: useCapture,\n passive: eventType !== 'submit',\n };\n\n root.addEventListener(eventType, handler, options);\n this.boundHandlers.set(eventType, { handler, options });\n }\n\n this.initialized = true;\n }\n\n /**\n * Handle a delegated event\n * @param {Event} event - The DOM event\n * @param {string} eventType - The type of event (click, change, etc.)\n */\n handleEvent(event, eventType) {\n const target = event.target;\n if (!target || typeof target.closest !== 'function') {\n return;\n }\n\n // Find the nearest element with the appropriate data attribute\n const attrName = `data-coherent-${eventType}`;\n const delegateTarget = target.closest(`[${attrName}]`);\n\n if (!delegateTarget) {\n return;\n }\n\n // Get the handler ID from the attribute\n const handlerId = delegateTarget.getAttribute(attrName);\n if (!handlerId) {\n return;\n }\n\n // Look up the handler in the registry\n const entry = this.registry.get(handlerId);\n if (!entry) {\n return;\n }\n\n // Wrap the event with component context and call the handler\n const wrappedEvent = wrapEvent(event, delegateTarget, entry.componentRef);\n entry.handler(wrappedEvent);\n }\n\n /**\n * Destroy the event delegation system\n * Removes all listeners and clears the registry\n */\n destroy() {\n if (!this.initialized || !this.root) {\n return;\n }\n\n // Remove all event listeners\n for (const [eventType, { handler, options }] of this.boundHandlers) {\n this.root.removeEventListener(eventType, handler, options);\n }\n\n this.boundHandlers.clear();\n this.registry.clear();\n this.initialized = false;\n this.root = null;\n }\n\n /**\n * Check if the delegation system is initialized\n * @returns {boolean} True if initialized\n */\n isInitialized() {\n return this.initialized;\n }\n}\n\n/**\n * Singleton event delegation instance\n * Use this for global event delegation\n */\nexport const eventDelegation = new EventDelegation();\n", "/**\n * State serialization utilities for Coherent.js hydration\n *\n * Uses base64 encoding to safely embed state in data attributes\n * without escaping issues.\n */\n\n/**\n * Serialize component state to base64-encoded JSON string\n *\n * @param {Object} state - Component state object\n * @returns {string|null} - Base64 encoded state or null if empty/invalid\n */\nexport function serializeState(state) {\n if (!state || typeof state !== 'object') return null;\n\n // Filter out non-serializable values (functions, symbols, undefined)\n const serializable = {};\n let hasSerializable = false;\n\n for (const [key, value] of Object.entries(state)) {\n if (isSerializable(value)) {\n serializable[key] = value;\n hasSerializable = true;\n }\n // Silently omit functions, symbols, undefined - they reconstruct on hydrate\n }\n\n if (!hasSerializable) return null;\n\n try {\n const json = JSON.stringify(serializable);\n // Use encodeURIComponent to handle unicode, then btoa for base64\n return btoa(encodeURIComponent(json));\n } catch (e) {\n console.warn('[Coherent.js] Failed to serialize state:', e);\n return null;\n }\n}\n\n/**\n * Deserialize state from base64-encoded JSON string\n *\n * @param {string} encoded - Base64 encoded state string\n * @returns {Object|null} - Deserialized state or null if invalid\n */\nexport function deserializeState(encoded) {\n if (!encoded || typeof encoded !== 'string') return null;\n\n try {\n const json = decodeURIComponent(atob(encoded));\n return JSON.parse(json);\n } catch (e) {\n console.warn('[Coherent.js] Failed to deserialize state:', e);\n return null;\n }\n}\n\n/**\n * Extract state from a DOM element's data-state attribute\n *\n * @param {HTMLElement} element - DOM element to extract state from\n * @returns {Object|null} - Extracted state or null\n */\nexport function extractState(element) {\n if (!element || typeof element.getAttribute !== 'function') {\n return null;\n }\n\n const encoded = element.getAttribute('data-state');\n return deserializeState(encoded);\n}\n\n/**\n * Check if a value is serializable to JSON\n * @private\n */\nfunction isSerializable(value) {\n if (value === undefined) return false;\n if (value === null) return true;\n if (typeof value === 'function') return false;\n if (typeof value === 'symbol') return false;\n if (typeof value === 'bigint') return false; // BigInt not JSON serializable\n\n // Arrays and objects need recursive check\n if (Array.isArray(value)) {\n return value.every(isSerializable);\n }\n\n if (typeof value === 'object') {\n // Check for circular references would be expensive here\n // JSON.stringify will catch them in serializeState\n return true;\n }\n\n return true; // primitives (string, number, boolean)\n}\n\n/**\n * Size warning threshold (bytes)\n * Warn if serialized state exceeds this\n */\nconst STATE_SIZE_WARNING_THRESHOLD = 10 * 1024; // 10KB\n\n/**\n * Serialize state with size warning\n *\n * @param {Object} state - Component state\n * @param {string} componentName - Component name for warning message\n * @returns {string|null} - Serialized state\n */\nexport function serializeStateWithWarning(state, componentName = 'Unknown') {\n const encoded = serializeState(state);\n\n if (encoded && encoded.length > STATE_SIZE_WARNING_THRESHOLD) {\n console.warn(\n `[Coherent.js] Large state detected for component \"${componentName}\": ` +\n `${Math.round(encoded.length / 1024)}KB. Consider using a state management ` +\n `solution for large datasets.`\n );\n }\n\n return encoded;\n}\n", "/**\n * Mismatch detection for Coherent.js hydration\n *\n * Compares server-rendered DOM against client virtual DOM to detect\n * hydration mismatches in development mode.\n */\n\n/**\n * Format path segments into readable string\n * @param {Array} segments - Path segments\n * @returns {string} - Formatted path\n */\nexport function formatPath(segments) {\n if (!segments || segments.length === 0) return 'root';\n return segments.join('.');\n}\n\n/**\n * Get children from virtual node\n * @private\n */\nfunction getVNodeChildren(vNode) {\n if (!vNode || typeof vNode !== 'object' || Array.isArray(vNode)) {\n return [];\n }\n const tagName = Object.keys(vNode)[0];\n const props = vNode[tagName];\n if (!props || typeof props !== 'object') {\n return [];\n }\n if (props.children) {\n return Array.isArray(props.children) ? props.children : [props.children];\n }\n if (props.text !== undefined) {\n return [String(props.text)];\n }\n return [];\n}\n\n/**\n * Detect mismatches between DOM and virtual DOM\n *\n * @param {Element} domElement - Real DOM element\n * @param {Object|string|number} virtualNode - Virtual DOM node\n * @param {Array} path - Current path for error reporting\n * @returns {Array} - Array of mismatch objects\n */\nexport function detectMismatch(domElement, virtualNode, path = []) {\n const mismatches = [];\n\n // Handle null/undefined virtual node\n if (virtualNode === null || virtualNode === undefined) {\n return mismatches;\n }\n\n // Handle text nodes (string or number in virtual DOM)\n if (typeof virtualNode === 'string' || typeof virtualNode === 'number') {\n const expectedText = String(virtualNode).trim();\n\n // DOM might be a text node or element containing text\n let actualText;\n if (domElement.nodeType === 3) { // Node.TEXT_NODE\n actualText = domElement.textContent?.trim() || '';\n } else {\n // For element nodes, get direct text content\n actualText = domElement.textContent?.trim() || '';\n }\n\n if (actualText !== expectedText) {\n mismatches.push({\n path: formatPath(path),\n type: 'text',\n expected: expectedText,\n actual: actualText,\n domPath: getDOMPath(domElement)\n });\n }\n return mismatches;\n }\n\n // Handle arrays\n if (Array.isArray(virtualNode)) {\n virtualNode.forEach((child, index) => {\n const domChild = getDOMChildAtIndex(domElement, index);\n if (domChild) {\n const childMismatches = detectMismatch(\n domChild,\n child,\n [...path, `[${index}]`]\n );\n mismatches.push(...childMismatches);\n } else {\n mismatches.push({\n path: formatPath([...path, `[${index}]`]),\n type: 'missing_element',\n expected: describeVNode(child),\n actual: null,\n domPath: `${getDOMPath(domElement)} > child[${index}]`\n });\n }\n });\n return mismatches;\n }\n\n // Handle element nodes\n if (typeof virtualNode !== 'object') {\n return mismatches;\n }\n\n const tagName = Object.keys(virtualNode)[0];\n const props = virtualNode[tagName] || {};\n\n // Check tag name\n const domTagName = domElement.tagName?.toLowerCase();\n if (domTagName !== tagName.toLowerCase()) {\n mismatches.push({\n path: formatPath(path),\n type: 'tagName',\n expected: tagName,\n actual: domTagName,\n domPath: getDOMPath(domElement)\n });\n // Can't continue comparing if tag is different\n return mismatches;\n }\n\n // Check critical attributes\n const attributeChecks = [\n { virtual: 'className', dom: 'class' },\n { virtual: 'id', dom: 'id' },\n { virtual: 'type', dom: 'type' },\n { virtual: 'value', dom: 'value' },\n { virtual: 'checked', dom: 'checked' },\n { virtual: 'disabled', dom: 'disabled' },\n { virtual: 'href', dom: 'href' },\n { virtual: 'src', dom: 'src' }\n ];\n\n attributeChecks.forEach(({ virtual, dom }) => {\n const expectedValue = props[virtual];\n if (expectedValue === undefined) return;\n\n const actualValue = domElement.getAttribute(dom);\n const expectedStr = String(expectedValue);\n\n // Handle boolean attributes\n if (typeof expectedValue === 'boolean') {\n const actualBool = actualValue !== null;\n if (expectedValue !== actualBool) {\n mismatches.push({\n path: formatPath([...path, `@${dom}`]),\n type: 'attribute',\n expected: expectedValue,\n actual: actualBool,\n domPath: getDOMPath(domElement)\n });\n }\n return;\n }\n\n if (expectedStr !== actualValue) {\n mismatches.push({\n path: formatPath([...path, `@${dom}`]),\n type: 'attribute',\n expected: expectedStr,\n actual: actualValue,\n domPath: getDOMPath(domElement)\n });\n }\n });\n\n // Recursively check children\n const vChildren = getVNodeChildren({ [tagName]: props });\n const dChildren = getSignificantDOMChildren(domElement);\n\n // Check for child count mismatch\n if (vChildren.length !== dChildren.length) {\n mismatches.push({\n path: formatPath([...path, 'children']),\n type: 'children_count',\n expected: vChildren.length,\n actual: dChildren.length,\n domPath: getDOMPath(domElement)\n });\n }\n\n // Compare each child\n const maxChildren = Math.max(vChildren.length, dChildren.length);\n for (let i = 0; i < maxChildren; i++) {\n const vChild = vChildren[i];\n const dChild = dChildren[i];\n\n if (vChild && dChild) {\n const childMismatches = detectMismatch(\n dChild,\n vChild,\n [...path, `children[${i}]`]\n );\n mismatches.push(...childMismatches);\n } else if (vChild && !dChild) {\n mismatches.push({\n path: formatPath([...path, `children[${i}]`]),\n type: 'missing_dom_child',\n expected: describeVNode(vChild),\n actual: null,\n domPath: getDOMPath(domElement)\n });\n } else if (!vChild && dChild) {\n mismatches.push({\n path: formatPath([...path, `children[${i}]`]),\n type: 'extra_dom_child',\n expected: null,\n actual: describeNode(dChild),\n domPath: getDOMPath(domElement)\n });\n }\n }\n\n return mismatches;\n}\n\n/**\n * Report mismatches to console with detailed information\n *\n * @param {Array} mismatches - Array of mismatch objects\n * @param {Object} options - Reporting options\n */\nexport function reportMismatches(mismatches, options = {}) {\n if (!mismatches || mismatches.length === 0) return;\n\n const { componentName = 'Unknown', strict = false } = options;\n\n const header = `[Coherent.js] Hydration mismatch detected in \"${componentName}\"!\\n` +\n `Found ${mismatches.length} difference(s) between server and client:\\n`;\n\n const details = mismatches.map((m, i) => {\n return `\\n${i + 1}. ${m.type} at ${m.path}\\n` +\n ` DOM path: ${m.domPath}\\n` +\n ` Expected: ${JSON.stringify(m.expected)}\\n` +\n ` Actual: ${JSON.stringify(m.actual)}`;\n }).join('');\n\n const advice = '\\n\\nThis usually happens when:\\n' +\n ' - Server renders with different data than client\\n' +\n ' - Using Date.now(), Math.random(), or browser-only APIs during render\\n' +\n ' - Component is not pure (has side effects during render)\\n';\n\n console.warn(header + details + advice);\n\n if (strict) {\n throw new Error(`Hydration failed: ${mismatches.length} mismatch(es) found. See console for details.`);\n }\n}\n\n/**\n * Get significant DOM children (elements and non-empty text nodes)\n * @private\n */\nfunction getSignificantDOMChildren(element) {\n if (!element || !element.childNodes) return [];\n\n return Array.from(element.childNodes).filter(node => {\n if (node.nodeType === 1) return true; // Element node\n if (node.nodeType === 3) { // Text node\n return node.textContent && node.textContent.trim().length > 0;\n }\n return false;\n });\n}\n\n/**\n * Get DOM child at specific index (considering only significant children)\n * @private\n */\nfunction getDOMChildAtIndex(parent, index) {\n const children = getSignificantDOMChildren(parent);\n return children[index] || null;\n}\n\n/**\n * Get a readable DOM path for debugging\n * @private\n */\nfunction getDOMPath(element) {\n if (!element || !element.tagName) return '(unknown)';\n\n const parts = [];\n let current = element;\n\n while (current && current.tagName) {\n let selector = current.tagName.toLowerCase();\n\n if (current.id) {\n selector += `#${current.id}`;\n } else if (current.className && typeof current.className === 'string') {\n const classes = current.className.trim().split(/\\s+/).slice(0, 2);\n if (classes.length > 0 && classes[0]) {\n selector += `.${classes.join('.')}`;\n }\n }\n\n parts.unshift(selector);\n current = current.parentElement;\n\n // Limit depth\n if (parts.length > 5) {\n parts.unshift('...');\n break;\n }\n }\n\n return parts.join(' > ');\n}\n\n/**\n * Describe a virtual node for error messages\n * @private\n */\nfunction describeVNode(vNode) {\n if (typeof vNode === 'string' || typeof vNode === 'number') {\n return `text: \"${String(vNode).substring(0, 50)}\"`;\n }\n if (Array.isArray(vNode)) {\n return `array[${vNode.length}]`;\n }\n if (typeof vNode === 'object' && vNode !== null) {\n const tagName = Object.keys(vNode)[0];\n return `<${tagName}>`;\n }\n return String(vNode);\n}\n\n/**\n * Describe a DOM node for error messages\n * @private\n */\nfunction describeNode(node) {\n if (!node) return '(null)';\n if (node.nodeType === 3) { // Text node\n return `text: \"${(node.textContent || '').substring(0, 50)}\"`;\n }\n if (node.nodeType === 1) { // Element\n return `<${node.tagName.toLowerCase()}>`;\n }\n return `node(type=${node.nodeType})`;\n}\n", "/**\n * Clean hydrate() API for Coherent.js\n *\n * Integrates event delegation, state serialization, and mismatch detection\n * into a simple function: hydrate(component, container, options)\n *\n * @module @coherent.js/client/hydrate\n */\n\nimport { eventDelegation, handlerRegistry } from './events/index.js';\nimport { extractState, serializeState } from './hydration/index.js';\nimport { detectMismatch, reportMismatches } from './hydration/index.js';\n\n/**\n * Hydrate a server-rendered component\n *\n * @param {Function} component - Component function that returns virtual DOM\n * @param {HTMLElement} container - DOM element containing server-rendered HTML\n * @param {Object} [options] - Hydration options\n * @param {Object} [options.initialState] - Initial state to override extracted state\n * @param {boolean} [options.detectMismatch=true] - Enable mismatch detection (dev mode)\n * @param {boolean} [options.strict=false] - Throw on mismatch instead of warning\n * @param {Function} [options.onMismatch] - Custom mismatch handler\n * @param {Object} [options.props] - Additional props to pass to component\n * @returns {Object} Control object with unmount(), rerender(), getState(), setState()\n */\nexport function hydrate(component, container, options = {}) {\n // Validate inputs\n if (typeof component !== 'function') {\n throw new Error(\n `hydrate() requires a component function, received: ${typeof component}`\n );\n }\n\n if (!container || typeof container.getAttribute !== 'function') {\n throw new Error(\n `hydrate() requires a valid DOM element as container, received: ${\n container === null ? 'null' : typeof container\n }`\n );\n }\n\n // Initialize event delegation (idempotent)\n eventDelegation.initialize();\n\n // Extract options with defaults\n const {\n initialState: providedState,\n detectMismatch: shouldDetectMismatch = process.env.NODE_ENV !== 'production',\n strict = false,\n onMismatch,\n props: additionalProps = {},\n } = options;\n\n // Extract state from DOM data-state attribute, or use provided initial state\n let state = providedState ?? extractState(container) ?? {};\n\n // Store event listeners for cleanup\n const eventListeners = [];\n\n // Track registered handler IDs for cleanup\n const registeredHandlerIds = new Set();\n\n // Create component reference for handler registry\n const componentRef = {\n getState: () => state,\n setState: (newState) => {\n if (typeof newState === 'function') {\n state = { ...state, ...newState(state) };\n } else {\n state = { ...state, ...newState };\n }\n // Re-render on state change\n doRerender();\n },\n };\n\n // Generate virtual DOM from component\n const componentProps = { ...additionalProps, ...state };\n let virtualDOM = component(componentProps);\n\n // Detect mismatches if enabled\n if (shouldDetectMismatch) {\n const mismatches = detectMismatch(container, virtualDOM);\n\n if (mismatches.length > 0) {\n if (onMismatch) {\n onMismatch(mismatches);\n } else {\n reportMismatches(mismatches, {\n componentName: component.name || 'Anonymous',\n strict,\n });\n }\n }\n }\n\n // Walk virtual DOM and register event handlers\n registerEventHandlers(container, virtualDOM, componentRef, registeredHandlerIds);\n\n /**\n * Re-render the component with current state\n */\n function doRerender() {\n const newProps = { ...additionalProps, ...state };\n virtualDOM = component(newProps);\n\n // Update DOM with new virtual DOM\n // For now, we do a simple patch - just update text content and attributes\n // Full reconciliation would be in a separate module\n patchDOM(container, virtualDOM);\n\n // Re-register event handlers after DOM update\n registerEventHandlers(container, virtualDOM, componentRef, registeredHandlerIds);\n }\n\n /**\n * Unmount the component and clean up\n */\n function unmount() {\n // Remove registered event handlers\n for (const handlerId of registeredHandlerIds) {\n handlerRegistry.unregister(handlerId);\n }\n registeredHandlerIds.clear();\n\n // Remove direct event listeners\n for (const { element, event, handler, options } of eventListeners) {\n element.removeEventListener(event, handler, options);\n }\n eventListeners.length = 0;\n\n // Clear container's hydration marker\n container.removeAttribute('data-coherent-hydrated');\n }\n\n /**\n * Force re-render with optional new props\n * @param {Object} [newProps] - New props to merge\n */\n function rerender(newProps) {\n if (newProps) {\n Object.assign(additionalProps, newProps);\n }\n doRerender();\n }\n\n /**\n * Get current state\n * @returns {Object} Current state\n */\n function getState() {\n return { ...state };\n }\n\n /**\n * Set state and trigger re-render\n * @param {Object|Function} newState - New state or updater function\n */\n function setState(newState) {\n componentRef.setState(newState);\n }\n\n // Mark container as hydrated\n container.setAttribute('data-coherent-hydrated', 'true');\n\n // Return control object\n return {\n unmount,\n rerender,\n getState,\n setState,\n };\n}\n\n/**\n * Walk virtual DOM tree and register event handlers\n * @private\n */\nfunction registerEventHandlers(domElement, vNode, componentRef, handlerIds) {\n if (!vNode || typeof vNode !== 'object' || Array.isArray(vNode)) {\n return;\n }\n\n const tagName = Object.keys(vNode)[0];\n const props = vNode[tagName];\n\n if (!props || typeof props !== 'object') {\n return;\n }\n\n // Look for event handler props (on* functions)\n const eventProps = Object.keys(props).filter(\n (key) => key.startsWith('on') && typeof props[key] === 'function'\n );\n\n for (const eventProp of eventProps) {\n const eventType = eventProp.slice(2).toLowerCase(); // onClick -> click\n const handler = props[eventProp];\n\n // Generate unique handler ID\n const handlerId = `${tagName}-${eventType}-${Math.random().toString(36).slice(2, 9)}`;\n\n // Register handler\n handlerRegistry.register(handlerId, handler, componentRef);\n handlerIds.add(handlerId);\n\n // Set data attribute on DOM element for delegation\n const attrName = `data-coherent-${eventType}`;\n if (domElement.setAttribute) {\n domElement.setAttribute(attrName, handlerId);\n }\n }\n\n // Recursively process children\n const children = getVNodeChildren(props);\n const domChildren = getSignificantDOMChildren(domElement);\n\n children.forEach((child, index) => {\n if (child && typeof child === 'object' && !Array.isArray(child) && domChildren[index]) {\n registerEventHandlers(domChildren[index], child, componentRef, handlerIds);\n }\n });\n}\n\n/**\n * Simple DOM patching for re-renders\n * @private\n */\nfunction patchDOM(domElement, vNode) {\n if (!vNode || !domElement) {\n return;\n }\n\n // Handle text/number\n if (typeof vNode === 'string' || typeof vNode === 'number') {\n if (domElement.textContent !== String(vNode)) {\n domElement.textContent = String(vNode);\n }\n return;\n }\n\n // Handle arrays\n if (Array.isArray(vNode)) {\n return; // Array patching would need reconciliation\n }\n\n if (typeof vNode !== 'object') {\n return;\n }\n\n const tagName = Object.keys(vNode)[0];\n const props = vNode[tagName] || {};\n\n // Update attributes\n const attributeMap = {\n className: 'class',\n htmlFor: 'for',\n };\n\n for (const [key, value] of Object.entries(props)) {\n if (key === 'children' || key === 'text' || key.startsWith('on')) {\n continue;\n }\n\n const attrName = attributeMap[key] || key;\n\n if (value === true) {\n domElement.setAttribute(attrName, '');\n } else if (value === false || value === null || value === undefined) {\n domElement.removeAttribute(attrName);\n } else if (domElement.getAttribute(attrName) !== String(value)) {\n domElement.setAttribute(attrName, String(value));\n }\n }\n\n // Handle text content\n if (props.text !== undefined) {\n const textContent = String(props.text);\n if (domElement.textContent !== textContent) {\n domElement.textContent = textContent;\n }\n return;\n }\n\n // Recursively patch children\n const children = getVNodeChildren(props);\n const domChildren = getSignificantDOMChildren(domElement);\n\n children.forEach((child, index) => {\n if (domChildren[index]) {\n patchDOM(domChildren[index], child);\n }\n });\n}\n\n/**\n * Get children from virtual node props\n * @private\n */\nfunction getVNodeChildren(props) {\n if (!props) return [];\n if (props.children) {\n return Array.isArray(props.children) ? props.children : [props.children];\n }\n return [];\n}\n\n/**\n * Get significant DOM children (elements and non-whitespace text)\n * @private\n */\nfunction getSignificantDOMChildren(element) {\n if (!element || !element.childNodes) return [];\n\n return Array.from(element.childNodes).filter((node) => {\n if (node.nodeType === 1) return true; // Element\n if (node.nodeType === 3) {\n // Text node\n return node.textContent && node.textContent.trim().length > 0;\n }\n return false;\n });\n}\n\nexport default hydrate;\n", "/**\n * CleanupTracker - Tracks and automatically cleans up module resources during HMR\n *\n * Prevents memory leaks by tracking timers, intervals, event listeners, and fetch\n * requests created by modules. When a module is disposed during HMR, all its\n * tracked resources are automatically cleaned up.\n *\n * @module @coherent.js/client/hmr/cleanup-tracker\n */\n\n/**\n * Tracks module resources for cleanup during HMR\n */\nexport class CleanupTracker {\n constructor() {\n /**\n * Per-module resource tracking\n * @type {Map<string, { timers: Set<number>, intervals: Set<number>, listeners: Array, abortControllers: Set<AbortController> }>}\n */\n this.moduleResources = new Map();\n }\n\n /**\n * Create a tracked context for a module\n *\n * Returns an object with tracked versions of setTimeout, setInterval,\n * addEventListener, and fetch that automatically clean up on module disposal.\n *\n * @param {string} moduleId - Unique identifier for the module\n * @returns {Object} Tracked context with setTimeout, setInterval, etc.\n */\n createContext(moduleId) {\n const resources = {\n timers: new Set(),\n intervals: new Set(),\n listeners: [],\n abortControllers: new Set(),\n };\n\n this.moduleResources.set(moduleId, resources);\n\n const context = {\n /**\n * Tracked setTimeout - auto-removes from tracking on completion\n * @param {Function} callback - Function to execute\n * @param {number} delay - Delay in milliseconds\n * @param {...*} args - Additional arguments to pass to callback\n * @returns {number} Timer ID\n */\n setTimeout: (callback, delay, ...args) => {\n const id = setTimeout(\n (...a) => {\n resources.timers.delete(id);\n callback(...a);\n },\n delay,\n ...args\n );\n resources.timers.add(id);\n return id;\n },\n\n /**\n * Tracked setInterval - stores in intervals set until cleared\n * @param {Function} callback - Function to execute\n * @param {number} delay - Interval in milliseconds\n * @param {...*} args - Additional arguments to pass to callback\n * @returns {number} Interval ID\n */\n setInterval: (callback, delay, ...args) => {\n const id = setInterval(callback, delay, ...args);\n resources.intervals.add(id);\n return id;\n },\n\n /**\n * Clear a tracked timeout\n * @param {number} id - Timer ID to clear\n */\n clearTimeout: (id) => {\n resources.timers.delete(id);\n clearTimeout(id);\n },\n\n /**\n * Clear a tracked interval\n * @param {number} id - Interval ID to clear\n */\n clearInterval: (id) => {\n resources.intervals.delete(id);\n clearInterval(id);\n },\n\n /**\n * Tracked addEventListener - stores listener info for removal on cleanup\n * @param {EventTarget} target - Element or object to attach listener to\n * @param {string} event - Event type\n * @param {Function} handler - Event handler function\n * @param {Object|boolean} [options] - Listener options\n */\n addEventListener: (target, event, handler, options) => {\n target.addEventListener(event, handler, options);\n resources.listeners.push({ target, event, handler, options });\n },\n\n /**\n * Create a tracked AbortController\n * @returns {AbortController} Tracked AbortController\n */\n createAbortController: () => {\n const controller = new AbortController();\n resources.abortControllers.add(controller);\n return controller;\n },\n\n /**\n * Tracked fetch - creates AbortController automatically, cleans up on completion\n * @param {string|URL} url - URL to fetch\n * @param {Object} [options] - Fetch options\n * @returns {Promise<Response>} Fetch promise\n */\n fetch: (url, options = {}) => {\n const controller = new AbortController();\n resources.abortControllers.add(controller);\n\n // Merge signals if one was provided\n const mergedOptions = {\n ...options,\n signal: controller.signal,\n };\n\n return fetch(url, mergedOptions).finally(() => {\n resources.abortControllers.delete(controller);\n });\n },\n };\n\n return context;\n }\n\n /**\n * Cleanup all resources for a module\n *\n * Called during HMR module disposal. Clears all timers, intervals,\n * removes all event listeners, and aborts all pending fetch requests.\n *\n * @param {string} moduleId - Module identifier to clean up\n */\n cleanup(moduleId) {\n const resources = this.moduleResources.get(moduleId);\n if (!resources) return;\n\n // Clear all timers\n for (const id of resources.timers) {\n clearTimeout(id);\n }\n resources.timers.clear();\n\n // Clear all intervals\n for (const id of resources.intervals) {\n clearInterval(id);\n }\n resources.intervals.clear();\n\n // Remove all event listeners\n for (const { target, event, handler, options } of resources.listeners) {\n try {\n target.removeEventListener(event, handler, options);\n } catch {\n // Target may no longer exist\n }\n }\n resources.listeners.length = 0;\n\n // Abort all pending fetches\n for (const controller of resources.abortControllers) {\n try {\n controller.abort();\n } catch {\n // Ignore abort errors\n }\n }\n resources.abortControllers.clear();\n\n this.moduleResources.delete(moduleId);\n }\n\n /**\n * Check for potential resource leaks (for development mode)\n *\n * Logs warnings if resources weren't cleaned up before module disposal.\n * Call this before cleanup() to detect potential leaks.\n *\n * @param {string} moduleId - Module identifier to check\n */\n checkForLeaks(moduleId) {\n const resources = this.moduleResources.get(moduleId);\n if (!resources) return;\n\n const warnings = [];\n\n if (resources.timers.size > 0) {\n warnings.push(`${resources.timers.size} timer(s) not cleaned up`);\n }\n if (resources.intervals.size > 0) {\n warnings.push(`${resources.intervals.size} interval(s) not cleaned up`);\n }\n if (resources.listeners.length > 0) {\n warnings.push(`${resources.listeners.length} listener(s) not cleaned up`);\n }\n if (resources.abortControllers.size > 0) {\n warnings.push(\n `${resources.abortControllers.size} pending fetch(es) not aborted`\n );\n }\n\n if (warnings.length > 0) {\n console.warn(`[HMR] Potential leak in module ${moduleId}: ${warnings.join(', ')}`);\n }\n }\n\n /**\n * Check if a module has tracked resources\n * @param {string} moduleId - Module identifier\n * @returns {boolean} True if module has resources\n */\n hasResources(moduleId) {\n return this.moduleResources.has(moduleId);\n }\n\n /**\n * Get resource counts for a module (for testing/debugging)\n * @param {string} moduleId - Module identifier\n * @returns {Object|null} Resource counts or null if module not tracked\n */\n getResourceCounts(moduleId) {\n const resources = this.moduleResources.get(moduleId);\n if (!resources) return null;\n\n return {\n timers: resources.timers.size,\n intervals: resources.intervals.size,\n listeners: resources.listeners.length,\n abortControllers: resources.abortControllers.size,\n };\n }\n}\n\n/**\n * Singleton cleanup tracker instance\n * @type {CleanupTracker}\n */\nexport const cleanupTracker = new CleanupTracker();\n", "/**\n * StateCapturer - Captures and restores form input state and scroll positions during HMR\n *\n * Preserves user input and scroll positions across hot module replacement updates,\n * providing a seamless development experience. Only restores scroll position if\n * the page layout hasn't changed significantly.\n *\n * @module @coherent.js/client/hmr/state-capturer\n */\n\n/**\n * Captures and restores form/scroll state during HMR\n */\nexport class StateCapturer {\n constructor() {\n /**\n * Captured form input states\n * @type {Map<string, { value: string, type: string, selectionStart?: number, selectionEnd?: number, checked?: boolean }>}\n */\n this.capturedInputs = new Map();\n\n /**\n * Captured scroll positions\n * @type {Map<string, { top: number, left: number }>}\n */\n this.scrollPositions = new Map();\n\n /**\n * Layout snapshot for change detection\n * @type {Object|null}\n */\n this.layoutSnapshot = null;\n }\n\n /**\n * Generate a stable key for an input element\n *\n * Uses multiple factors to identify inputs across HMR updates:\n * 1. ID (most stable)\n * 2. Name + type\n * 3. Form context\n * 4. DOM path (fallback)\n *\n * @param {HTMLInputElement|HTMLTextAreaElement|HTMLSelectElement} input - Input element\n * @returns {string} Stable key for the input\n */\n getInputKey(input) {\n const parts = [];\n\n // ID is most stable\n if (input.id) {\n parts.push(`#${input.id}`);\n return parts.join(':');\n }\n\n // Name + type combination\n if (input.name) {\n parts.push(`[name=\"${input.name}\"]`);\n }\n\n if (input.type) {\n parts.push(`[type=\"${input.type}\"]`);\n }\n\n // Form context if available\n if (input.form?.id) {\n parts.push(`form#${input.form.id}`);\n }\n\n // Fallback: DOM path\n if (parts.length === 0) {\n parts.push(this.getElementPath(input));\n }\n\n return parts.join(':');\n }\n\n /**\n * Build a CSS-like path for an element\n *\n * @param {HTMLElement} element - Element to build path for\n * @returns {string} CSS-like path (e.g., \"form > div:nth-of-type(2) > input\")\n */\n getElementPath(element) {\n const path = [];\n let current = element;\n\n while (current && current !== document.body && path.length < 10) {\n let selector = current.tagName.toLowerCase();\n\n // Add class names (limited to avoid overly long selectors)\n if (current.className && typeof current.className === 'string') {\n const classes = current.className.trim().split(/\\s+/).slice(0, 2);\n if (classes.length > 0 && classes[0]) {\n selector += `.${classes.join('.')}`;\n }\n }\n\n // Add nth-of-type for disambiguation\n if (current.parentElement) {\n const siblings = current.parentElement.querySelectorAll(\n `:scope > ${current.tagName.toLowerCase()}`\n );\n if (siblings.length > 1) {\n const index = Array.from(siblings).indexOf(current);\n selector += `:nth-of-type(${index + 1})`;\n }\n }\n\n path.unshift(selector);\n current = current.parentElement;\n }\n\n return path.join(' > ');\n }\n\n /**\n * Capture all form input states\n *\n * Iterates through all input, textarea, and select elements,\n * capturing their values, selection state, and checked state.\n *\n * @returns {Map<string, Object>} Map of input keys to their captured state\n */\n captureFormState() {\n this.capturedInputs.clear();\n\n const inputs = document.querySelectorAll('input, textarea, select');\n\n for (const input of inputs) {\n const key = this.getInputKey(input);\n const state = {\n value: input.value,\n type: input.type || input.tagName.toLowerCase(),\n };\n\n // Capture selection for text-like inputs\n if (\n typeof input.selectionStart === 'number' &&\n (input.type === 'text' ||\n input.type === 'search' ||\n input.type === 'url' ||\n input.type === 'tel' ||\n input.type === 'password' ||\n input.tagName.toLowerCase() === 'textarea')\n ) {\n state.selectionStart = input.selectionStart;\n state.selectionEnd = input.selectionEnd;\n }\n\n // Capture checked state for checkboxes/radios\n if (input.type === 'checkbox' || input.type === 'radio') {\n state.checked = input.checked;\n }\n\n this.capturedInputs.set(key, state);\n }\n\n return this.capturedInputs;\n }\n\n /**\n * Restore form input states after HMR update\n *\n * Finds inputs by their captured keys and restores their values,\n * only if the input type matches (to avoid corrupting data).\n */\n restoreFormState() {\n for (const [key, state] of this.capturedInputs) {\n const inputs = this.findInputsByKey(key);\n\n for (const input of inputs) {\n // Only restore if type matches\n const currentType = input.type || input.tagName.toLowerCase();\n if (currentType !== state.type) {\n continue;\n }\n\n // Restore checkbox/radio checked state\n if (state.checked !== undefined) {\n input.checked = state.checked;\n continue;\n }\n\n // Restore value\n input.value = state.value;\n\n // Restore selection if applicable and input is not focused\n if (\n state.selectionStart !== undefined &&\n document.activeElement !== input\n ) {\n try {\n input.setSelectionRange(state.selectionStart, state.selectionEnd);\n } catch {\n // Some input types don't support setSelectionRange\n }\n }\n }\n }\n }\n\n /**\n * Find inputs matching a captured key\n *\n * @param {string} key - Captured input key\n * @returns {HTMLElement[]} Array of matching input elements\n */\n findInputsByKey(key) {\n // ID-based key\n if (key.startsWith('#')) {\n const id = key.slice(1);\n const el = document.getElementById(id);\n return el ? [el] : [];\n }\n\n // Name-based key\n const nameMatch = key.match(/\\[name=\"([^\"]+)\"\\]/);\n if (nameMatch) {\n const name = nameMatch[1];\n const typeMatch = key.match(/\\[type=\"([^\"]+)\"\\]/);\n const type = typeMatch ? typeMatch[1] : null;\n\n let selector = `[name=\"${name}\"]`;\n if (type) {\n selector += `[type=\"${type}\"]`;\n }\n\n return Array.from(document.querySelectorAll(selector));\n }\n\n // Path-based key - try to query directly\n try {\n const el = document.querySelector(key);\n return el ? [el] : [];\n } catch {\n return [];\n }\n }\n\n /**\n * Capture scroll positions for window and scrollable containers\n *\n * Captures scroll positions for:\n * - Window (scrollX/scrollY)\n * - Elements with [data-coherent-scroll-preserve] attribute\n * - Elements with overflow that have actual scrolling\n */\n captureScrollPositions() {\n this.scrollPositions.clear();\n\n // Window scroll\n this.scrollPositions.set('window', {\n top: window.scrollY,\n left: window.scrollX,\n });\n\n // Find scrollable containers with explicit marker\n const markedScrollables = document.querySelectorAll(\n '[data-coherent-scroll-preserve]'\n );\n for (const el of markedScrollables) {\n const key = this.getScrollableKey(el);\n this.scrollPositions.set(key, {\n top: el.scrollTop,\n left: el.scrollLeft,\n });\n }\n\n // Find elements with overflow that have actual scroll content\n const overflowElements = document.querySelectorAll(\n '[style*=\"overflow\"], [class]'\n );\n for (const el of overflowElements) {\n const style = window.getComputedStyle(el);\n const hasOverflow =\n style.overflow === 'auto' ||\n style.overflow === 'scroll' ||\n style.overflowY === 'auto' ||\n style.overflowY === 'scroll' ||\n style.overflowX === 'auto' ||\n style.overflowX === 'scroll';\n\n if (\n hasOverflow &&\n (el.scrollHeight > el.clientHeight || el.scrollWidth > el.clientWidth)\n ) {\n const key = this.getScrollableKey(el);\n if (!this.scrollPositions.has(key)) {\n this.scrollPositions.set(key, {\n top: el.scrollTop,\n left: el.scrollLeft,\n });\n }\n }\n }\n\n return this.scrollPositions;\n }\n\n /**\n * Generate a stable key for a scrollable element\n *\n * @param {HTMLElement} el - Scrollable element\n * @returns {string} Key for the element\n */\n getScrollableKey(el) {\n if (el.id) {\n return `#${el.id}`;\n }\n\n const component = el.getAttribute('data-coherent-component');\n if (component) {\n return `[data-coherent-component=\"${component}\"]`;\n }\n\n return this.getElementPath(el);\n }\n\n /**\n * Capture layout snapshot for change detection\n *\n * Captures body dimensions and positions of anchor elements\n * (elements with data-coherent-component attribute).\n */\n captureLayout() {\n this.layoutSnapshot = {\n bodyHeight: document.body.scrollHeight,\n bodyWidth: document.body.scrollWidth,\n anchors: new Map(),\n };\n\n // Capture positions of component elements as anchors\n const components = document.querySelectorAll('[data-coherent-component]');\n for (const el of components) {\n const rect = el.getBoundingClientRect();\n const key = this.getScrollableKey(el);\n this.layoutSnapshot.anchors.set(key, {\n top: rect.top,\n left: rect.left,\n width: rect.width,\n height: rect.height,\n });\n }\n }\n\n /**\n * Check if layout changed significantly (>50px shift)\n *\n * Returns true if:\n * - Body dimensions changed by more than 50px\n * - Any anchor element position shifted by more than 50px\n *\n * @returns {boolean} True if layout changed significantly\n */\n layoutChangedSignificantly() {\n if (!this.layoutSnapshot) {\n return false;\n }\n\n const THRESHOLD = 50; // pixels\n\n // Check body dimensions\n const heightDiff = Math.abs(\n document.body.scrollHeight - this.layoutSnapshot.bodyHeight\n );\n const widthDiff = Math.abs(\n document.body.scrollWidth - this.layoutSnapshot.bodyWidth\n );\n\n if (heightDiff > THRESHOLD || widthDiff > THRESHOLD) {\n return true;\n }\n\n // Check anchor element positions\n for (const [key, oldRect] of this.layoutSnapshot.anchors) {\n const el = this.findElementByKey(key);\n if (!el) {\n continue;\n }\n\n const newRect = el.getBoundingClientRect();\n const topDiff = Math.abs(newRect.top - oldRect.top);\n const leftDiff = Math.abs(newRect.left - oldRect.left);\n\n if (topDiff > THRESHOLD || leftDiff > THRESHOLD) {\n return true;\n }\n }\n\n return false;\n }\n\n /**\n * Find an element by its scrollable key\n *\n * @param {string} key - Element key\n * @returns {HTMLElement|null} Found element or null\n */\n findElementByKey(key) {\n if (key === 'window') {\n return null;\n }\n\n if (key.startsWith('#')) {\n return document.getElementById(key.slice(1));\n }\n\n try {\n return document.querySelector(key);\n } catch {\n return null;\n }\n }\n\n /**\n * Restore scroll positions if layout hasn't changed significantly\n *\n * Logs a message if scroll restoration is skipped due to layout changes.\n */\n restoreScrollPositions() {\n if (this.layoutChangedSignificantly()) {\n console.log('[HMR] Layout changed significantly, not restoring scroll');\n return;\n }\n\n // Restore window scroll\n const windowPos = this.scrollPositions.get('window');\n if (windowPos) {\n window.scrollTo(windowPos.left, windowPos.top);\n }\n\n // Restore container scrolls\n for (const [key, pos] of this.scrollPositions) {\n if (key === 'window') {\n continue;\n }\n\n const el = this.findElementByKey(key);\n if (el) {\n el.scrollTop = pos.top;\n el.scrollLeft = pos.left;\n }\n }\n }\n\n /**\n * Capture all state (form + scroll + layout)\n *\n * Convenience method that calls all capture methods.\n */\n captureAll() {\n this.captureFormState();\n this.captureScrollPositions();\n this.captureLayout();\n }\n\n /**\n * Restore all state (form + scroll)\n *\n * Convenience method that calls all restore methods.\n */\n restoreAll() {\n this.restoreFormState();\n this.restoreScrollPositions();\n }\n\n /**\n * Clear all captured state\n */\n clear() {\n this.capturedInputs.clear();\n this.scrollPositions.clear();\n this.layoutSnapshot = null;\n }\n}\n\n/**\n * Singleton state capturer instance\n * @type {StateCapturer}\n */\nexport const stateCapturer = new StateCapturer();\n", "/**\n * HMR Error Overlay\n *\n * Displays error information in a full-screen overlay with Shadow DOM isolation.\n * Provides click-to-open editor support and keyboard/click dismissal.\n *\n * @module @coherent.js/client/hmr/overlay\n */\n\n/**\n * Escape HTML special characters to prevent XSS.\n * @param {string} str - String to escape\n * @returns {string} Escaped string\n */\nexport function escapeHtml(str) {\n return String(str)\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/\"/g, '"');\n}\n\n/**\n * Format code frame with line numbers and highlight.\n * @param {string} frame - Code frame content\n * @param {number} highlightLine - Line number to highlight (1-based)\n * @param {number} [startLine=1] - Starting line number for the frame\n * @returns {string} Formatted HTML string\n */\nexport function formatCodeFrame(frame, highlightLine, startLine = 1) {\n if (!frame) return '';\n\n const lines = frame.split('\\n');\n return lines.map((content, i) => {\n const lineNum = startLine + i;\n const isHighlight = lineNum === highlightLine;\n return `<div class=\"line${isHighlight ? ' highlight' : ''}\">\n <span class=\"line-number\">${lineNum}</span>\n <span class=\"line-content\">${escapeHtml(content)}</span>\n </div>`;\n }).join('');\n}\n\n/**\n * Editor URL scheme map for click-to-open functionality.\n */\nconst EDITOR_URLS = {\n vscode: (file, line) => `vscode://file/${file}:${line}`,\n cursor: (file, line) => `cursor://file/${file}:${line}`,\n 'vscode-insiders': (file, line) => `vscode-insiders://file/${file}:${line}`,\n atom: (file, line) => `atom://core/open/file?filename=${file}&line=${line}`,\n sublime: (file, line) => `subl://open?url=file://${file}&line=${line}`,\n webstorm: (file, line) => `webstorm://open?file=${file}&line=${line}`,\n idea: (file, line) => `idea://open?file=${file}&line=${line}`\n};\n\n/**\n * CSS styles for the error overlay (Dracula-inspired color scheme).\n */\nconst OVERLAY_STYLES = `\n :host {\n position: fixed;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n z-index: 99999;\n --bg: #181818;\n --text: #f8f8f2;\n --red: #ff5555;\n --yellow: #f1fa8c;\n --purple: #bd93f9;\n --cyan: #8be9fd;\n --code-bg: #282a36;\n --line-num: #6272a4;\n }\n .backdrop {\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n background: rgba(0, 0, 0, 0.66);\n }\n .container {\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n width: min(800px, 90vw);\n max-height: 90vh;\n overflow: auto;\n background: var(--bg);\n border-radius: 8px;\n box-shadow: 0 20px 40px rgba(0, 0, 0, 0.5);\n font-family: 'SF Mono', Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace;\n }\n .header {\n padding: 16px 20px;\n background: var(--red);\n color: white;\n display: flex;\n justify-content: space-between;\n align-items: center;\n border-radius: 8px 8px 0 0;\n }\n .title {\n font-weight: bold;\n font-size: 16px;\n }\n .close-btn {\n background: none;\n border: none;\n color: white;\n font-size: 24px;\n cursor: pointer;\n padding: 0 8px;\n line-height: 1;\n }\n .close-btn:hover {\n opacity: 0.8;\n }\n .content {\n padding: 20px;\n color: var(--text);\n }\n .message {\n font-size: 18px;\n color: var(--red);\n margin-bottom: 20px;\n word-break: break-word;\n }\n .file {\n color: var(--cyan);\n margin-bottom: 16px;\n cursor: pointer;\n text-decoration: underline;\n }\n .file:hover {\n color: var(--purple);\n }\n .code-frame {\n background: var(--code-bg);\n padding: 16px;\n border-radius: 4px;\n overflow-x: auto;\n font-size: 14px;\n line-height: 1.5;\n margin-bottom: 16px;\n }\n .line {\n display: flex;\n }\n .line-number {\n width: 50px;\n color: var(--line-num);\n text-align: right;\n padding-right: 16px;\n user-select: none;\n flex-shrink: 0;\n }\n .line-content {\n flex: 1;\n white-space: pre;\n }\n .line.highlight {\n background: rgba(255, 85, 85, 0.2);\n }\n .line.highlight .line-content {\n color: var(--red);\n }\n .stack {\n margin-top: 20px;\n font-size: 12px;\n color: var(--line-num);\n white-space: pre-wrap;\n max-height: 200px;\n overflow-y: auto;\n }\n .tip {\n margin-top: 16px;\n padding: 12px;\n background: rgba(189, 147, 249, 0.1);\n border-left: 3px solid var(--purple);\n font-size: 13px;\n color: var(--text);\n }\n .tip strong {\n color: var(--purple);\n }\n`;\n\n/**\n * Error overlay class for HMR error display.\n * Uses Shadow DOM for complete style isolation.\n */\nexport class ErrorOverlay {\n constructor() {\n /** @type {{ host: HTMLElement, shadow: ShadowRoot } | null} */\n this.overlay = null;\n /** @type {string} */\n this.editor = this._getStoredEditor();\n /** @type {((e: KeyboardEvent) => void) | null} */\n this.escapeHandler = null;\n }\n\n /**\n * Get stored editor preference from localStorage.\n * @returns {string} Editor name\n * @private\n */\n _getStoredEditor() {\n try {\n return localStorage.getItem('coherent-editor') || 'vscode';\n } catch {\n return 'vscode';\n }\n }\n\n /**\n * Create the overlay element with Shadow DOM.\n * @returns {{ host: HTMLElement, shadow: ShadowRoot }} Overlay elements\n */\n createOverlay() {\n if (this.overlay) return this.overlay;\n\n const host = document.createElement('div');\n host.id = 'coherent-error-overlay';\n const shadow = host.attachShadow({ mode: 'open' });\n\n const style = document.createElement('style');\n style.textContent = OVERLAY_STYLES;\n shadow.appendChild(style);\n\n this.overlay = { host, shadow };\n return this.overlay;\n }\n\n /**\n * Show the error overlay with error details.\n * @param {Object} error - Error details\n * @param {string} error.message - Error message\n * @param {string} [error.file] - File path\n * @param {number} [error.line] - Line number\n * @param {number} [error.column] - Column number\n * @param {string} [error.frame] - Code frame with context\n * @param {string} [error.stack] - Stack trace\n */\n show(error) {\n const { host, shadow } = this.createOverlay();\n\n // Clear previous content (but keep styles)\n const existingWrapper = shadow.querySelector('.wrapper');\n if (existingWrapper) existingWrapper.remove();\n\n // Calculate start line for code frame (center on error line)\n const frameLines = error.frame ? error.frame.split('\\n').length : 0;\n const startLine = error.line ? Math.max(1, error.line - Math.floor(frameLines / 2)) : 1;\n\n const wrapper = document.createElement('div');\n wrapper.className = 'wrapper';\n wrapper.innerHTML = `\n <div class=\"backdrop\"></div>\n <div class=\"container\">\n <div class=\"header\">\n <span class=\"title\">HMR Error</span>\n <button class=\"close-btn\" title=\"Close (Escape)\">×</button>\n </div>\n <div class=\"content\">\n <div class=\"message\">${escapeHtml(error.message || 'Unknown error')}</div>\n ${error.file ? `\n <div class=\"file\" data-file=\"${escapeHtml(error.file)}\" data-line=\"${error.line || 1}\">\n ${escapeHtml(error.file)}${error.line ? `:${error.line}` : ''}${error.column ? `:${error.column}` : ''}\n </div>\n ` : ''}\n ${error.frame ? `\n <div class=\"code-frame\">${formatCodeFrame(error.frame, error.line, startLine)}</div>\n ` : ''}\n ${error.stack ? `\n <div class=\"stack\">${escapeHtml(error.stack)}</div>\n ` : ''}\n <div class=\"tip\">\n Press <strong>Escape</strong> or click the X to dismiss.\n ${error.file ? ` Click the file path to open in ${this.editor}.` : ''}\n </div>\n </div>\n </div>\n `;\n\n shadow.appendChild(wrapper);\n\n // Event handlers\n const closeBtn = wrapper.querySelector('.close-btn');\n const backdrop = wrapper.querySelector('.backdrop');\n const fileLink = wrapper.querySelector('.file');\n\n closeBtn?.addEventListener('click', () => this.hide());\n backdrop?.addEventListener('click', () => this.hide());\n fileLink?.addEventListener('click', (e) => {\n const target = e.target;\n const file = target.dataset.file;\n const line = parseInt(target.dataset.line, 10) || 1;\n this.openInEditor(file, line);\n });\n\n // Escape key handler\n this.escapeHandler = (e) => {\n if (e.key === 'Escape') this.hide();\n };\n document.addEventListener('keydown', this.escapeHandler);\n\n // Add to DOM if not already\n if (!host.parentNode) {\n document.body.appendChild(host);\n }\n }\n\n /**\n * Hide and remove the error overlay.\n */\n hide() {\n if (this.overlay?.host.parentNode) {\n this.overlay.host.parentNode.removeChild(this.overlay.host);\n }\n if (this.escapeHandler) {\n document.removeEventListener('keydown', this.escapeHandler);\n this.escapeHandler = null;\n }\n // Reset overlay reference so it can be recreated\n this.overlay = null;\n }\n\n /**\n * Open file in configured editor.\n * @param {string} file - File path\n * @param {number} [line=1] - Line number\n */\n openInEditor(file, line = 1) {\n const urlGenerator = EDITOR_URLS[this.editor] || EDITOR_URLS.vscode;\n const url = urlGenerator(file, line);\n window.open(url, '_self');\n }\n\n /**\n * Set preferred editor and store in localStorage.\n * @param {string} editor - Editor name (vscode, cursor, vscode-insiders, atom, sublime, webstorm, idea)\n */\n setEditor(editor) {\n this.editor = editor;\n try {\n localStorage.setItem('coherent-editor', editor);\n } catch {\n // Ignore localStorage errors\n }\n }\n}\n\n/**\n * Singleton instance of ErrorOverlay.\n */\nexport const errorOverlay = new ErrorOverlay();\n", "/**\n * HMR Connection Status Indicator\n *\n * Displays a small colored dot in the bottom-right corner indicating\n * WebSocket connection status. Unobtrusive design per CONTEXT.md decision.\n *\n * @module @coherent.js/client/hmr/indicator\n */\n\n/**\n * Status color mapping for connection states.\n */\nconst STATUS_COLORS = {\n connected: '#10b981', // Green\n disconnected: '#ef4444', // Red\n reconnecting: '#f59e0b', // Yellow/amber\n error: '#ef4444' // Red\n};\n\n/**\n * Status title mapping for accessibility.\n */\nconst STATUS_TITLES = {\n connected: 'HMR: Connected',\n disconnected: 'HMR: Disconnected',\n reconnecting: 'HMR: Reconnecting...',\n error: 'HMR: Error'\n};\n\n/**\n * Default/initial color before status is set.\n */\nconst DEFAULT_COLOR = '#666';\n\n/**\n * Connection status indicator class.\n * Shows an 8px colored dot in the bottom-right corner of the viewport.\n */\nexport class ConnectionIndicator {\n constructor() {\n /** @type {HTMLElement | null} */\n this.indicator = null;\n }\n\n /**\n * Create the indicator element if it doesn't exist.\n * Uses inline styles to avoid external CSS dependencies.\n */\n create() {\n if (this.indicator) return;\n\n const el = document.createElement('div');\n el.id = 'coherent-hmr-indicator';\n el.style.cssText = `\n position: fixed;\n bottom: 8px;\n right: 8px;\n width: 8px;\n height: 8px;\n border-radius: 50%;\n background: ${DEFAULT_COLOR};\n z-index: 99998;\n pointer-events: none;\n transition: background 0.3s ease;\n `;\n el.title = 'HMR: Initializing';\n\n document.body.appendChild(el);\n this.indicator = el;\n }\n\n /**\n * Update the indicator status.\n * Creates the element if it doesn't exist (lazy initialization).\n *\n * @param {string} status - Status string: 'connected', 'disconnected', 'reconnecting', or 'error'\n */\n update(status) {\n if (!this.indicator) {\n this.create();\n }\n\n const color = STATUS_COLORS[status] || STATUS_COLORS.disconnected;\n const title = STATUS_TITLES[status] || 'HMR: Unknown';\n\n this.indicator.style.background = color;\n this.indicator.title = title;\n }\n\n /**\n * Remove the indicator from the DOM.\n */\n destroy() {\n if (this.indicator?.parentNode) {\n this.indicator.parentNode.removeChild(this.indicator);\n }\n this.indicator = null;\n }\n}\n\n/**\n * Singleton instance of ConnectionIndicator.\n */\nexport const connectionIndicator = new ConnectionIndicator();\n", "/**\n * ModuleTracker - Tracks module graph and HMR boundaries\n *\n * Provides a Vite-compatible hot context API for modules to declare\n * how they should be handled during HMR updates. Tracks accept/dispose\n * handlers and persistent data that survives updates.\n *\n * @module @coherent.js/client/hmr/module-tracker\n */\n\n/**\n * Tracks module HMR registrations and provides hot context API\n */\nexport class ModuleTracker {\n constructor() {\n /**\n * Module registrations map\n * @type {Map<string, { accept: Function|null, acceptDeps: { deps: string[], callback: Function }|null, dispose: Function|null, prune: Function|null, data: Object }>}\n */\n this.modules = new Map();\n\n /**\n * WebSocket reference for invalidation messages\n * @type {WebSocket|null}\n */\n this.socket = null;\n }\n\n /**\n * Set WebSocket reference for invalidation messages\n * @param {WebSocket|null} socket - WebSocket connection\n */\n setSocket(socket) {\n this.socket = socket;\n }\n\n /**\n * Create a hot context for a module (Vite-compatible API)\n *\n * Returns an object with:\n * - data: Persistent object that survives HMR updates\n * - accept(callback): Register self-update handler\n * - acceptDeps(deps, callback): Register dependency update handler\n * - dispose(callback): Register cleanup handler called before replacement\n * - prune(callback): Register handler for when module is removed\n * - invalidate(message): Signal that module cannot hot-update\n *\n * @param {string} moduleId - Unique identifier for the module\n * @returns {Object} Hot context object\n */\n createHotContext(moduleId) {\n // Get or create module data, preserving existing data object\n let moduleData = this.modules.get(moduleId);\n if (!moduleData) {\n moduleData = {\n accept: null,\n acceptDeps: null,\n dispose: null,\n prune: null,\n data: {},\n };\n this.modules.set(moduleId, moduleData);\n }\n\n const tracker = this;\n\n return {\n /**\n * Persistent data object that survives HMR updates.\n * Use this to preserve state across module replacements.\n */\n get data() {\n return moduleData.data;\n },\n\n /**\n * Accept self updates.\n * Called when this module is updated and can handle its own replacement.\n *\n * @param {Function} [callback] - Optional callback receiving the new module\n */\n accept(callback) {\n moduleData.accept = callback || (() => {});\n },\n\n /**\n * Accept dependency updates.\n * Called when one of the specified dependencies is updated.\n *\n * @param {string|string[]} deps - Dependency module ID(s)\n * @param {Function} callback - Callback receiving updated dependencies\n */\n acceptDeps(deps, callback) {\n const depsArray = Array.isArray(deps) ? deps : [deps];\n moduleData.acceptDeps = { deps: depsArray, callback };\n },\n\n /**\n * Register disposal callback.\n * Called before the module is replaced, receives the data object\n * to allow saving state for the next version.\n *\n * @param {Function} callback - Cleanup handler, receives data object\n */\n dispose(callback) {\n moduleData.dispose = callback;\n },\n\n /**\n * Register prune callback.\n * Called when the module is completely removed from the module graph.\n *\n * @param {Function} callback - Prune handler\n */\n prune(callback) {\n moduleData.prune = callback;\n },\n\n /**\n * Invalidate this module.\n * Signals that the module cannot be hot-updated and should propagate\n * the update to its importers.\n *\n * @param {string} [message] - Optional message explaining why\n */\n invalidate(message) {\n const WS_OPEN = typeof WebSocket !== 'undefined' ? WebSocket.OPEN : 1;\n if (tracker.socket?.readyState === WS_OPEN) {\n tracker.socket.send(JSON.stringify({\n type: 'invalidate',\n moduleId,\n message,\n }));\n }\n // Log for debugging\n console.log(`[HMR] Module ${moduleId} invalidated${message ? `: ${message}` : ''}`);\n },\n };\n }\n\n /**\n * Check if a module can be hot-updated\n *\n * Returns true if the module has registered an accept handler.\n *\n * @param {string} moduleId - Module identifier\n * @returns {boolean} True if module accepts HMR updates\n */\n canHotUpdate(moduleId) {\n const moduleData = this.modules.get(moduleId);\n return !!(moduleData?.accept || moduleData?.acceptDeps);\n }\n\n /**\n * Check if a module is an HMR boundary\n *\n * A module is considered a boundary if:\n * - It has an accept handler registered\n * - It exports __hmrBoundary = true\n * - It is associated with a data-coherent-component element\n *\n * @param {string} moduleId - Module identifier\n * @param {Object} [moduleExports] - Optional module exports to check for __hmrBoundary\n * @returns {boolean} True if module is an HMR boundary\n */\n isHmrBoundary(moduleId, moduleExports) {\n // Check for accept handler\n if (this.canHotUpdate(moduleId)) {\n return true;\n }\n\n // Check for explicit __hmrBoundary export\n if (moduleExports?.__hmrBoundary === true) {\n return true;\n }\n\n // Check for coherent component presence (by convention)\n // Extract component name from module path\n const componentName = this.extractComponentName(moduleId);\n if (componentName && typeof document !== 'undefined') {\n const hasComponent = document.querySelector(\n `[data-coherent-component=\"${componentName}\"]`\n );\n if (hasComponent) {\n return true;\n }\n }\n\n return false;\n }\n\n /**\n * Extract a potential component name from module path\n *\n * @param {string} moduleId - Module path\n * @returns {string|null} Component name or null\n * @private\n */\n extractComponentName(moduleId) {\n // Extract filename without extension\n const match = moduleId.match(/\\/([^/]+?)(?:\\.[^.]+)?$/);\n if (match) {\n return match[1];\n }\n return null;\n }\n\n /**\n * Execute dispose callback for a module\n *\n * Calls the registered dispose handler with the data object,\n * allowing the module to save state for the next version.\n *\n * @param {string} moduleId - Module identifier\n * @returns {Object|null} The data object (for passing to next version)\n */\n executeDispose(moduleId) {\n const moduleData = this.modules.get(moduleId);\n if (!moduleData) {\n return null;\n }\n\n // Call dispose handler with data object\n if (typeof moduleData.dispose === 'function') {\n try {\n moduleData.dispose(moduleData.data);\n } catch (err) {\n console.error(`[HMR] Error in dispose handler for ${moduleId}:`, err);\n }\n }\n\n return moduleData.data;\n }\n\n /**\n * Execute accept callback for a module\n *\n * Calls the registered accept handler with the new module.\n *\n * @param {string} moduleId - Module identifier\n * @param {Object} [newModule] - The newly imported module\n * @returns {boolean} True if accept handler was called\n */\n executeAccept(moduleId, newModule) {\n const moduleData = this.modules.get(moduleId);\n if (!moduleData?.accept) {\n return false;\n }\n\n try {\n moduleData.accept(newModule);\n return true;\n } catch (err) {\n console.error(`[HMR] Error in accept handler for ${moduleId}:`, err);\n return false;\n }\n }\n\n /**\n * Execute acceptDeps callback for a module\n *\n * Calls the registered acceptDeps handler with the updated dependencies.\n *\n * @param {string} moduleId - Module identifier\n * @param {Object} updatedDeps - Map of dependency moduleId -> new module\n * @returns {boolean} True if acceptDeps handler was called\n */\n executeAcceptDeps(moduleId, updatedDeps) {\n const moduleData = this.modules.get(moduleId);\n if (!moduleData?.acceptDeps) {\n return false;\n }\n\n try {\n const { deps, callback } = moduleData.acceptDeps;\n // Build array of updated modules in same order as deps\n const modules = deps.map((dep) => updatedDeps[dep]);\n callback(modules);\n return true;\n } catch (err) {\n console.error(`[HMR] Error in acceptDeps handler for ${moduleId}:`, err);\n return false;\n }\n }\n\n /**\n * Execute prune callback for a module\n *\n * Called when a module is removed from the module graph.\n *\n * @param {string} moduleId - Module identifier\n */\n executePrune(moduleId) {\n const moduleData = this.modules.get(moduleId);\n if (!moduleData?.prune) {\n return;\n }\n\n try {\n moduleData.prune();\n } catch (err) {\n console.error(`[HMR] Error in prune handler for ${moduleId}:`, err);\n }\n\n // Remove module from tracking\n this.modules.delete(moduleId);\n }\n\n /**\n * Check if module is registered\n *\n * @param {string} moduleId - Module identifier\n * @returns {boolean} True if module is registered\n */\n hasModule(moduleId) {\n return this.modules.has(moduleId);\n }\n\n /**\n * Get module data (for testing/debugging)\n *\n * @param {string} moduleId - Module identifier\n * @returns {Object|null} Module data or null\n */\n getModuleData(moduleId) {\n return this.modules.get(moduleId) || null;\n }\n\n /**\n * Clear all module registrations (for testing)\n */\n clear() {\n this.modules.clear();\n }\n}\n\n/**\n * Singleton module tracker instance\n * @type {ModuleTracker}\n */\nexport const moduleTracker = new ModuleTracker();\n\n/**\n * Convenience function to create a hot context for a module\n *\n * @param {string} moduleId - Module identifier\n * @returns {Object} Hot context object\n */\nexport function createHotContext(moduleId) {\n return moduleTracker.createHotContext(moduleId);\n}\n", "/**\n * HMRClient - Orchestrates WebSocket connection and HMR updates\n *\n * Integrates all HMR modules (cleanup tracker, state capturer, error overlay,\n * connection indicator) to provide seamless hot module replacement with\n * state preservation.\n *\n * @module @coherent.js/client/hmr/client\n */\n\nimport { cleanupTracker } from './cleanup-tracker.js';\nimport { stateCapturer } from './state-capturer.js';\nimport { errorOverlay } from './overlay.js';\nimport { connectionIndicator } from './indicator.js';\nimport { moduleTracker } from './module-tracker.js';\n\n/**\n * Parse error stack to extract file/line info\n *\n * @param {Error} error - Error object\n * @returns {{ file: string|null, line: number|null, column: number|null }} Parsed location\n */\nfunction parseErrorLocation(error) {\n const result = { file: null, line: null, column: null };\n\n if (!error.stack) {\n return result;\n }\n\n // Match common stack trace formats:\n // Chrome/Node: \"at Function (file.js:10:5)\"\n // Firefox: \"Function@file.js:10:5\"\n // Safari: \"file.js:10:5\"\n const patterns = [\n /at\\s+.*?\\((.+?):(\\d+):(\\d+)\\)/, // Chrome/Node with parens\n /at\\s+(.+?):(\\d+):(\\d+)/, // Chrome/Node without parens\n /@(.+?):(\\d+):(\\d+)/, // Firefox\n /^(.+?):(\\d+):(\\d+)/, // Safari\n ];\n\n const lines = error.stack.split('\\n');\n for (const line of lines) {\n for (const pattern of patterns) {\n const match = line.match(pattern);\n if (match) {\n result.file = match[1];\n result.line = parseInt(match[2], 10);\n result.column = parseInt(match[3], 10);\n return result;\n }\n }\n }\n\n return result;\n}\n\n/**\n * HMR Client class - manages WebSocket connection and update orchestration\n */\nexport class HMRClient {\n constructor() {\n /**\n * WebSocket connection\n * @type {WebSocket|null}\n */\n this.socket = null;\n\n /**\n * Connection state\n * @type {boolean}\n */\n this.connected = false;\n\n /**\n * Reconnection attempt counter\n * @type {number}\n */\n this.reconnectAttempts = 0;\n\n /**\n * Maximum reconnection attempts\n * @type {number}\n */\n this.maxReconnectAttempts = 10;\n\n /**\n * Base reconnection delay in ms\n * @type {number}\n */\n this.reconnectDelay = 1000;\n\n /**\n * Whether we've had a disconnect (for reload detection)\n * @type {boolean}\n */\n this.hadDisconnect = false;\n\n /**\n * Reconnect timeout ID\n * @type {number|null}\n */\n this.reconnectTimeout = null;\n\n /**\n * Initialization flag\n * @type {boolean}\n */\n this.initialized = false;\n }\n\n /**\n * Connect to the dev server WebSocket\n *\n * Establishes WebSocket connection with automatic reconnection using\n * exponential backoff with jitter.\n *\n * @returns {void}\n */\n connect() {\n if (typeof window === 'undefined') {\n return;\n }\n\n // Clear any pending reconnect\n if (this.reconnectTimeout !== null) {\n clearTimeout(this.reconnectTimeout);\n this.reconnectTimeout = null;\n }\n\n try {\n const protocol = location.protocol === 'https:' ? 'wss' : 'ws';\n const wsUrl = `${protocol}://${location.host}`;\n this.socket = new WebSocket(wsUrl);\n\n // Share socket with module tracker for invalidation messages\n moduleTracker.setSocket(this.socket);\n\n this.socket.addEventListener('open', () => {\n console.log('[HMR] Connected');\n this.connected = true;\n this.reconnectAttempts = 0;\n connectionIndicator.update('connected');\n\n // Send connection acknowledgment\n this.socket.send(JSON.stringify({ type: 'connected' }));\n\n // If reconnecting after disconnect, reload (server may have restarted)\n if (this.hadDisconnect) {\n console.log('[HMR] Reconnected after disconnect, reloading page');\n setTimeout(() => location.reload(), 200);\n return;\n }\n });\n\n this.socket.addEventListener('close', () => {\n this.connected = false;\n this.hadDisconnect = true;\n connectionIndicator.update('disconnected');\n moduleTracker.setSocket(null);\n this.scheduleReconnect();\n });\n\n this.socket.addEventListener('error', (event) => {\n console.warn('[HMR] WebSocket error:', event);\n connectionIndicator.update('error');\n try {\n this.socket.close();\n } catch {\n // Ignore close errors\n }\n });\n\n this.socket.addEventListener('message', (event) => {\n this.handleMessage(event);\n });\n } catch (error) {\n console.warn('[HMR] Failed to connect:', error);\n this.scheduleReconnect();\n }\n }\n\n /**\n * Schedule a reconnection attempt with exponential backoff\n *\n * @private\n */\n scheduleReconnect() {\n if (this.reconnectAttempts >= this.maxReconnectAttempts) {\n console.warn('[HMR] Max reconnection attempts reached');\n connectionIndicator.update('disconnected');\n return;\n }\n\n connectionIndicator.update('reconnecting');\n\n // Exponential backoff with jitter\n const delay = Math.min(\n this.reconnectDelay * Math.pow(2, this.reconnectAttempts) + Math.random() * 1000,\n 30000\n );\n this.reconnectAttempts++;\n\n console.log(`[HMR] Reconnecting in ${Math.round(delay)}ms (attempt ${this.reconnectAttempts}/${this.maxReconnectAttempts})`);\n\n this.reconnectTimeout = setTimeout(() => {\n this.reconnectTimeout = null;\n this.connect();\n }, delay);\n }\n\n /**\n * Handle incoming WebSocket message\n *\n * @param {MessageEvent} event - WebSocket message event\n * @private\n */\n handleMessage(event) {\n let data;\n try {\n data = JSON.parse(event.data);\n } catch {\n return;\n }\n\n console.log('[HMR] message', data.type, data.filePath || data.webPath || '');\n\n switch (data.type) {\n case 'connected':\n // Connection acknowledged\n break;\n\n case 'hmr-full-reload':\n case 'reload':\n console.warn('[HMR] Server requested full reload');\n location.reload();\n break;\n\n case 'hmr-component-update':\n case 'hmr-update':\n this.handleUpdate(data);\n break;\n\n case 'hmr-error':\n this.showError(data.error || data);\n break;\n\n case 'preview-update':\n // No-op: used by dashboard for live preview panes\n break;\n\n default:\n // Unknown message type, ignore\n break;\n }\n }\n\n /**\n * Handle module update\n *\n * Orchestrates the full HMR update cycle:\n * 1. Capture form/scroll state\n * 2. Execute dispose handlers\n * 3. Clean up module resources\n * 4. Re-import module\n * 5. Execute accept handlers\n * 6. Restore state\n *\n * @param {Object} data - Update message data\n * @param {string} [data.filePath] - File path that changed\n * @param {string} [data.webPath] - Web-accessible path\n * @param {string} [data.updateType] - Type of update (component, style, etc.)\n */\n async handleUpdate(data) {\n const filePath = data.webPath || data.filePath || '';\n const moduleId = filePath;\n\n try {\n // 1. Capture current state\n stateCapturer.captureAll();\n\n // 2. Execute dispose handler if registered\n if (moduleTracker.hasModule(moduleId)) {\n moduleTracker.executeDispose(moduleId);\n }\n\n // 3. Clean up module resources\n if (cleanupTracker.hasResources(moduleId)) {\n cleanupTracker.checkForLeaks(moduleId);\n cleanupTracker.cleanup(moduleId);\n }\n\n // 4. Re-import module with cache bust\n const importPath = filePath.startsWith('/') ? filePath : `/${filePath}`;\n const newModule = await import(`${importPath}?t=${Date.now()}`);\n\n // 5. Execute accept handler if module can hot-update\n const accepted = moduleTracker.canHotUpdate(moduleId);\n if (accepted) {\n moduleTracker.executeAccept(moduleId, newModule);\n } else {\n // Fall back to autoHydrate for components without explicit accept\n await this.fallbackHydrate();\n }\n\n // 6. Restore state\n stateCapturer.restoreAll();\n\n // 7. Hide error overlay (in case previous error is now fixed)\n errorOverlay.hide();\n\n // 8. Log success\n console.log(`[HMR] Updated: ${data.updateType || 'module'} ${filePath}`);\n } catch (error) {\n this.handleUpdateError(error, filePath);\n }\n }\n\n /**\n * Fall back to autoHydrate for non-HMR-aware modules\n *\n * @private\n */\n async fallbackHydrate() {\n try {\n // Try to import autoHydrate from the hydration module\n const { autoHydrate } = await import('../hydration.js');\n\n // If examples register a component registry on window, prefer targeted hydrate\n if (typeof window !== 'undefined' && window.componentRegistry) {\n autoHydrate(window.componentRegistry);\n } else {\n autoHydrate();\n }\n } catch {\n // autoHydrate not available or failed\n console.warn('[HMR] autoHydrate not available, component may need manual refresh');\n }\n }\n\n /**\n * Handle update error\n *\n * @param {Error} error - Error that occurred\n * @param {string} filePath - File that was being updated\n * @private\n */\n handleUpdateError(error, filePath) {\n console.error('[HMR] Update failed:', error);\n\n // Parse error location from stack\n const location = parseErrorLocation(error);\n\n // Build error details for overlay\n const errorDetails = {\n message: error.message || 'Unknown error during HMR update',\n file: location.file || filePath,\n line: location.line,\n column: location.column,\n stack: error.stack,\n };\n\n this.showError(errorDetails);\n }\n\n /**\n * Show error overlay\n *\n * @param {Object} error - Error details\n */\n showError(error) {\n errorOverlay.show(error);\n }\n\n /**\n * Hide error overlay\n */\n hideError() {\n errorOverlay.hide();\n }\n\n /**\n * Initialize HMR client\n *\n * Guards against double initialization and connects to dev server.\n *\n * @returns {void}\n */\n initialize() {\n if (typeof window === 'undefined') {\n return;\n }\n\n // Guard against double initialization\n if (window.__coherent_hmr_initialized || this.initialized) {\n return;\n }\n\n window.__coherent_hmr_initialized = true;\n this.initialized = true;\n\n this.connect();\n }\n\n /**\n * Disconnect and clean up\n *\n * @returns {void}\n */\n disconnect() {\n if (this.reconnectTimeout !== null) {\n clearTimeout(this.reconnectTimeout);\n this.reconnectTimeout = null;\n }\n\n if (this.socket) {\n try {\n this.socket.close();\n } catch {\n // Ignore close errors\n }\n this.socket = null;\n }\n\n this.connected = false;\n moduleTracker.setSocket(null);\n connectionIndicator.destroy();\n }\n\n /**\n * Check if client is connected\n *\n * @returns {boolean} True if connected\n */\n isConnected() {\n return this.connected;\n }\n}\n\n/**\n * Singleton HMR client instance\n * @type {HMRClient}\n */\nexport const hmrClient = new HMRClient();\n"],
|
|
5
|
+
"mappings": ";AAYO,IAAM,kBAAN,MAAsB;AAAA,EAC3B,cAAc;AAEZ,SAAK,WAAW,oBAAI,IAAI;AAAA,EAC1B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,SAAS,WAAW,SAAS,eAAe,MAAM;AAChD,QAAI,OAAO,YAAY,YAAY;AACjC,YAAM,IAAI,MAAM,yCAAyC,OAAO,OAAO,EAAE;AAAA,IAC3E;AACA,SAAK,SAAS,IAAI,WAAW,EAAE,SAAS,aAAa,CAAC;AAAA,EACxD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,WAAW,WAAW;AACpB,WAAO,KAAK,SAAS,OAAO,SAAS;AAAA,EACvC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,IAAI,WAAW;AACb,WAAO,KAAK,SAAS,IAAI,SAAS;AAAA,EACpC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,IAAI,WAAW;AACb,WAAO,KAAK,SAAS,IAAI,SAAS;AAAA,EACpC;AAAA;AAAA;AAAA;AAAA,EAKA,QAAQ;AACN,SAAK,SAAS,MAAM;AAAA,EACtB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,eAAe,cAAc;AAC3B,QAAI,CAAC,cAAc;AACjB,aAAO,CAAC;AAAA,IACV;AAEA,UAAM,aAAa,CAAC;AACpB,eAAW,CAAC,WAAW,KAAK,KAAK,KAAK,UAAU;AAC9C,UAAI,MAAM,iBAAiB,cAAc;AACvC,mBAAW,KAAK,SAAS;AAAA,MAC3B;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,IAAI,OAAO;AACT,WAAO,KAAK,SAAS;AAAA,EACvB;AACF;AAMO,IAAM,kBAAkB,IAAI,gBAAgB;;;AClE5C,SAAS,UAAU,eAAe,QAAQ,eAAe,MAAM;AACpE,SAAO;AAAA;AAAA,IAEL;AAAA,IACA;AAAA;AAAA,IAGA,iBAAiB;AACf,oBAAc,eAAe;AAAA,IAC/B;AAAA,IAEA,kBAAkB;AAChB,oBAAc,gBAAgB;AAAA,IAChC;AAAA;AAAA,IAGA,WAAW,cAAc,aAAa;AAAA,IACtC,OAAO,cAAc,SAAS;AAAA,IAC9B,UAAU,cAAc,YAAY;AAAA,IACpC,OAAO,cAAc,SAAS;AAAA,EAChC;AACF;;;ACrCO,IAAM,kBAAN,MAAsB;AAAA;AAAA;AAAA;AAAA,EAI3B,YAAY,WAAW,iBAAiB;AACtC,SAAK,WAAW;AAChB,SAAK,cAAc;AACnB,SAAK,OAAO;AACZ,SAAK,gBAAgB,oBAAI,IAAI;AAM7B,SAAK,aAAa;AAAA,MAChB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,WAAW,OAAO,OAAO,aAAa,cAAc,WAAW,MAAM;AACnE,QAAI,KAAK,aAAa;AACpB;AAAA,IACF;AAEA,QAAI,CAAC,MAAM;AAET;AAAA,IACF;AAEA,SAAK,OAAO;AAEZ,eAAW,aAAa,KAAK,YAAY;AACvC,YAAM,UAAU,CAAC,UAAU,KAAK,YAAY,OAAO,SAAS;AAG5D,YAAM,aAAa,cAAc,WAAW,cAAc;AAG1D,YAAM,UAAU;AAAA,QACd,SAAS;AAAA,QACT,SAAS,cAAc;AAAA,MACzB;AAEA,WAAK,iBAAiB,WAAW,SAAS,OAAO;AACjD,WAAK,cAAc,IAAI,WAAW,EAAE,SAAS,QAAQ,CAAC;AAAA,IACxD;AAEA,SAAK,cAAc;AAAA,EACrB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,YAAY,OAAO,WAAW;AAC5B,UAAM,SAAS,MAAM;AACrB,QAAI,CAAC,UAAU,OAAO,OAAO,YAAY,YAAY;AACnD;AAAA,IACF;AAGA,UAAM,WAAW,iBAAiB,SAAS;AAC3C,UAAM,iBAAiB,OAAO,QAAQ,IAAI,QAAQ,GAAG;AAErD,QAAI,CAAC,gBAAgB;AACnB;AAAA,IACF;AAGA,UAAM,YAAY,eAAe,aAAa,QAAQ;AACtD,QAAI,CAAC,WAAW;AACd;AAAA,IACF;AAGA,UAAM,QAAQ,KAAK,SAAS,IAAI,SAAS;AACzC,QAAI,CAAC,OAAO;AACV;AAAA,IACF;AAGA,UAAM,eAAe,UAAU,OAAO,gBAAgB,MAAM,YAAY;AACxE,UAAM,QAAQ,YAAY;AAAA,EAC5B;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,UAAU;AACR,QAAI,CAAC,KAAK,eAAe,CAAC,KAAK,MAAM;AACnC;AAAA,IACF;AAGA,eAAW,CAAC,WAAW,EAAE,SAAS,QAAQ,CAAC,KAAK,KAAK,eAAe;AAClE,WAAK,KAAK,oBAAoB,WAAW,SAAS,OAAO;AAAA,IAC3D;AAEA,SAAK,cAAc,MAAM;AACzB,SAAK,SAAS,MAAM;AACpB,SAAK,cAAc;AACnB,SAAK,OAAO;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,gBAAgB;AACd,WAAO,KAAK;AAAA,EACd;AACF;AAMO,IAAM,kBAAkB,IAAI,gBAAgB;;;ACrI5C,SAAS,eAAe,OAAO;AACpC,MAAI,CAAC,SAAS,OAAO,UAAU,SAAU,QAAO;AAGhD,QAAM,eAAe,CAAC;AACtB,MAAI,kBAAkB;AAEtB,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,KAAK,GAAG;AAChD,QAAI,eAAe,KAAK,GAAG;AACzB,mBAAa,GAAG,IAAI;AACpB,wBAAkB;AAAA,IACpB;AAAA,EAEF;AAEA,MAAI,CAAC,gBAAiB,QAAO;AAE7B,MAAI;AACF,UAAM,OAAO,KAAK,UAAU,YAAY;AAExC,WAAO,KAAK,mBAAmB,IAAI,CAAC;AAAA,EACtC,SAAS,GAAG;AACV,YAAQ,KAAK,4CAA4C,CAAC;AAC1D,WAAO;AAAA,EACT;AACF;AAQO,SAAS,iBAAiB,SAAS;AACxC,MAAI,CAAC,WAAW,OAAO,YAAY,SAAU,QAAO;AAEpD,MAAI;AACF,UAAM,OAAO,mBAAmB,KAAK,OAAO,CAAC;AAC7C,WAAO,KAAK,MAAM,IAAI;AAAA,EACxB,SAAS,GAAG;AACV,YAAQ,KAAK,8CAA8C,CAAC;AAC5D,WAAO;AAAA,EACT;AACF;AAQO,SAAS,aAAa,SAAS;AACpC,MAAI,CAAC,WAAW,OAAO,QAAQ,iBAAiB,YAAY;AAC1D,WAAO;AAAA,EACT;AAEA,QAAM,UAAU,QAAQ,aAAa,YAAY;AACjD,SAAO,iBAAiB,OAAO;AACjC;AAMA,SAAS,eAAe,OAAO;AAC7B,MAAI,UAAU,OAAW,QAAO;AAChC,MAAI,UAAU,KAAM,QAAO;AAC3B,MAAI,OAAO,UAAU,WAAY,QAAO;AACxC,MAAI,OAAO,UAAU,SAAU,QAAO;AACtC,MAAI,OAAO,UAAU,SAAU,QAAO;AAGtC,MAAI,MAAM,QAAQ,KAAK,GAAG;AACxB,WAAO,MAAM,MAAM,cAAc;AAAA,EACnC;AAEA,MAAI,OAAO,UAAU,UAAU;AAG7B,WAAO;AAAA,EACT;AAEA,SAAO;AACT;AAMA,IAAM,+BAA+B,KAAK;AASnC,SAAS,0BAA0B,OAAO,gBAAgB,WAAW;AAC1E,QAAM,UAAU,eAAe,KAAK;AAEpC,MAAI,WAAW,QAAQ,SAAS,8BAA8B;AAC5D,YAAQ;AAAA,MACN,qDAAqD,aAAa,MAC/D,KAAK,MAAM,QAAQ,SAAS,IAAI,CAAC;AAAA,IAEtC;AAAA,EACF;AAEA,SAAO;AACT;;;AC/GO,SAAS,WAAW,UAAU;AACnC,MAAI,CAAC,YAAY,SAAS,WAAW,EAAG,QAAO;AAC/C,SAAO,SAAS,KAAK,GAAG;AAC1B;AAMA,SAAS,iBAAiB,OAAO;AAC/B,MAAI,CAAC,SAAS,OAAO,UAAU,YAAY,MAAM,QAAQ,KAAK,GAAG;AAC/D,WAAO,CAAC;AAAA,EACV;AACA,QAAM,UAAU,OAAO,KAAK,KAAK,EAAE,CAAC;AACpC,QAAM,QAAQ,MAAM,OAAO;AAC3B,MAAI,CAAC,SAAS,OAAO,UAAU,UAAU;AACvC,WAAO,CAAC;AAAA,EACV;AACA,MAAI,MAAM,UAAU;AAClB,WAAO,MAAM,QAAQ,MAAM,QAAQ,IAAI,MAAM,WAAW,CAAC,MAAM,QAAQ;AAAA,EACzE;AACA,MAAI,MAAM,SAAS,QAAW;AAC5B,WAAO,CAAC,OAAO,MAAM,IAAI,CAAC;AAAA,EAC5B;AACA,SAAO,CAAC;AACV;AAUO,SAAS,eAAe,YAAY,aAAa,OAAO,CAAC,GAAG;AACjE,QAAM,aAAa,CAAC;AAGpB,MAAI,gBAAgB,QAAQ,gBAAgB,QAAW;AACrD,WAAO;AAAA,EACT;AAGA,MAAI,OAAO,gBAAgB,YAAY,OAAO,gBAAgB,UAAU;AACtE,UAAM,eAAe,OAAO,WAAW,EAAE,KAAK;AAG9C,QAAI;AACJ,QAAI,WAAW,aAAa,GAAG;AAC7B,mBAAa,WAAW,aAAa,KAAK,KAAK;AAAA,IACjD,OAAO;AAEL,mBAAa,WAAW,aAAa,KAAK,KAAK;AAAA,IACjD;AAEA,QAAI,eAAe,cAAc;AAC/B,iBAAW,KAAK;AAAA,QACd,MAAM,WAAW,IAAI;AAAA,QACrB,MAAM;AAAA,QACN,UAAU;AAAA,QACV,QAAQ;AAAA,QACR,SAAS,WAAW,UAAU;AAAA,MAChC,CAAC;AAAA,IACH;AACA,WAAO;AAAA,EACT;AAGA,MAAI,MAAM,QAAQ,WAAW,GAAG;AAC9B,gBAAY,QAAQ,CAAC,OAAO,UAAU;AACpC,YAAM,WAAW,mBAAmB,YAAY,KAAK;AACrD,UAAI,UAAU;AACZ,cAAM,kBAAkB;AAAA,UACtB;AAAA,UACA;AAAA,UACA,CAAC,GAAG,MAAM,IAAI,KAAK,GAAG;AAAA,QACxB;AACA,mBAAW,KAAK,GAAG,eAAe;AAAA,MACpC,OAAO;AACL,mBAAW,KAAK;AAAA,UACd,MAAM,WAAW,CAAC,GAAG,MAAM,IAAI,KAAK,GAAG,CAAC;AAAA,UACxC,MAAM;AAAA,UACN,UAAU,cAAc,KAAK;AAAA,UAC7B,QAAQ;AAAA,UACR,SAAS,GAAG,WAAW,UAAU,CAAC,YAAY,KAAK;AAAA,QACrD,CAAC;AAAA,MACH;AAAA,IACF,CAAC;AACD,WAAO;AAAA,EACT;AAGA,MAAI,OAAO,gBAAgB,UAAU;AACnC,WAAO;AAAA,EACT;AAEA,QAAM,UAAU,OAAO,KAAK,WAAW,EAAE,CAAC;AAC1C,QAAM,QAAQ,YAAY,OAAO,KAAK,CAAC;AAGvC,QAAM,aAAa,WAAW,SAAS,YAAY;AACnD,MAAI,eAAe,QAAQ,YAAY,GAAG;AACxC,eAAW,KAAK;AAAA,MACd,MAAM,WAAW,IAAI;AAAA,MACrB,MAAM;AAAA,MACN,UAAU;AAAA,MACV,QAAQ;AAAA,MACR,SAAS,WAAW,UAAU;AAAA,IAChC,CAAC;AAED,WAAO;AAAA,EACT;AAGA,QAAM,kBAAkB;AAAA,IACtB,EAAE,SAAS,aAAa,KAAK,QAAQ;AAAA,IACrC,EAAE,SAAS,MAAM,KAAK,KAAK;AAAA,IAC3B,EAAE,SAAS,QAAQ,KAAK,OAAO;AAAA,IAC/B,EAAE,SAAS,SAAS,KAAK,QAAQ;AAAA,IACjC,EAAE,SAAS,WAAW,KAAK,UAAU;AAAA,IACrC,EAAE,SAAS,YAAY,KAAK,WAAW;AAAA,IACvC,EAAE,SAAS,QAAQ,KAAK,OAAO;AAAA,IAC/B,EAAE,SAAS,OAAO,KAAK,MAAM;AAAA,EAC/B;AAEA,kBAAgB,QAAQ,CAAC,EAAE,SAAS,IAAI,MAAM;AAC5C,UAAM,gBAAgB,MAAM,OAAO;AACnC,QAAI,kBAAkB,OAAW;AAEjC,UAAM,cAAc,WAAW,aAAa,GAAG;AAC/C,UAAM,cAAc,OAAO,aAAa;AAGxC,QAAI,OAAO,kBAAkB,WAAW;AACtC,YAAM,aAAa,gBAAgB;AACnC,UAAI,kBAAkB,YAAY;AAChC,mBAAW,KAAK;AAAA,UACd,MAAM,WAAW,CAAC,GAAG,MAAM,IAAI,GAAG,EAAE,CAAC;AAAA,UACrC,MAAM;AAAA,UACN,UAAU;AAAA,UACV,QAAQ;AAAA,UACR,SAAS,WAAW,UAAU;AAAA,QAChC,CAAC;AAAA,MACH;AACA;AAAA,IACF;AAEA,QAAI,gBAAgB,aAAa;AAC/B,iBAAW,KAAK;AAAA,QACd,MAAM,WAAW,CAAC,GAAG,MAAM,IAAI,GAAG,EAAE,CAAC;AAAA,QACrC,MAAM;AAAA,QACN,UAAU;AAAA,QACV,QAAQ;AAAA,QACR,SAAS,WAAW,UAAU;AAAA,MAChC,CAAC;AAAA,IACH;AAAA,EACF,CAAC;AAGD,QAAM,YAAY,iBAAiB,EAAE,CAAC,OAAO,GAAG,MAAM,CAAC;AACvD,QAAM,YAAY,0BAA0B,UAAU;AAGtD,MAAI,UAAU,WAAW,UAAU,QAAQ;AACzC,eAAW,KAAK;AAAA,MACd,MAAM,WAAW,CAAC,GAAG,MAAM,UAAU,CAAC;AAAA,MACtC,MAAM;AAAA,MACN,UAAU,UAAU;AAAA,MACpB,QAAQ,UAAU;AAAA,MAClB,SAAS,WAAW,UAAU;AAAA,IAChC,CAAC;AAAA,EACH;AAGA,QAAM,cAAc,KAAK,IAAI,UAAU,QAAQ,UAAU,MAAM;AAC/D,WAAS,IAAI,GAAG,IAAI,aAAa,KAAK;AACpC,UAAM,SAAS,UAAU,CAAC;AAC1B,UAAM,SAAS,UAAU,CAAC;AAE1B,QAAI,UAAU,QAAQ;AACpB,YAAM,kBAAkB;AAAA,QACtB;AAAA,QACA;AAAA,QACA,CAAC,GAAG,MAAM,YAAY,CAAC,GAAG;AAAA,MAC5B;AACA,iBAAW,KAAK,GAAG,eAAe;AAAA,IACpC,WAAW,UAAU,CAAC,QAAQ;AAC5B,iBAAW,KAAK;AAAA,QACd,MAAM,WAAW,CAAC,GAAG,MAAM,YAAY,CAAC,GAAG,CAAC;AAAA,QAC5C,MAAM;AAAA,QACN,UAAU,cAAc,MAAM;AAAA,QAC9B,QAAQ;AAAA,QACR,SAAS,WAAW,UAAU;AAAA,MAChC,CAAC;AAAA,IACH,WAAW,CAAC,UAAU,QAAQ;AAC5B,iBAAW,KAAK;AAAA,QACd,MAAM,WAAW,CAAC,GAAG,MAAM,YAAY,CAAC,GAAG,CAAC;AAAA,QAC5C,MAAM;AAAA,QACN,UAAU;AAAA,QACV,QAAQ,aAAa,MAAM;AAAA,QAC3B,SAAS,WAAW,UAAU;AAAA,MAChC,CAAC;AAAA,IACH;AAAA,EACF;AAEA,SAAO;AACT;AAQO,SAAS,iBAAiB,YAAY,UAAU,CAAC,GAAG;AACzD,MAAI,CAAC,cAAc,WAAW,WAAW,EAAG;AAE5C,QAAM,EAAE,gBAAgB,WAAW,SAAS,MAAM,IAAI;AAEtD,QAAM,SAAS,iDAAiD,aAAa;AAAA,QAClE,WAAW,MAAM;AAAA;AAE5B,QAAM,UAAU,WAAW,IAAI,CAAC,GAAG,MAAM;AACvC,WAAO;AAAA,EAAK,IAAI,CAAC,KAAK,EAAE,IAAI,OAAO,EAAE,IAAI;AAAA,eACvB,EAAE,OAAO;AAAA,eACT,KAAK,UAAU,EAAE,QAAQ,CAAC;AAAA,eAC1B,KAAK,UAAU,EAAE,MAAM,CAAC;AAAA,EAC5C,CAAC,EAAE,KAAK,EAAE;AAEV,QAAM,SAAS;AAKf,UAAQ,KAAK,SAAS,UAAU,MAAM;AAEtC,MAAI,QAAQ;AACV,UAAM,IAAI,MAAM,qBAAqB,WAAW,MAAM,+CAA+C;AAAA,EACvG;AACF;AAMA,SAAS,0BAA0B,SAAS;AAC1C,MAAI,CAAC,WAAW,CAAC,QAAQ,WAAY,QAAO,CAAC;AAE7C,SAAO,MAAM,KAAK,QAAQ,UAAU,EAAE,OAAO,UAAQ;AACnD,QAAI,KAAK,aAAa,EAAG,QAAO;AAChC,QAAI,KAAK,aAAa,GAAG;AACvB,aAAO,KAAK,eAAe,KAAK,YAAY,KAAK,EAAE,SAAS;AAAA,IAC9D;AACA,WAAO;AAAA,EACT,CAAC;AACH;AAMA,SAAS,mBAAmB,QAAQ,OAAO;AACzC,QAAM,WAAW,0BAA0B,MAAM;AACjD,SAAO,SAAS,KAAK,KAAK;AAC5B;AAMA,SAAS,WAAW,SAAS;AAC3B,MAAI,CAAC,WAAW,CAAC,QAAQ,QAAS,QAAO;AAEzC,QAAM,QAAQ,CAAC;AACf,MAAI,UAAU;AAEd,SAAO,WAAW,QAAQ,SAAS;AACjC,QAAI,WAAW,QAAQ,QAAQ,YAAY;AAE3C,QAAI,QAAQ,IAAI;AACd,kBAAY,IAAI,QAAQ,EAAE;AAAA,IAC5B,WAAW,QAAQ,aAAa,OAAO,QAAQ,cAAc,UAAU;AACrE,YAAM,UAAU,QAAQ,UAAU,KAAK,EAAE,MAAM,KAAK,EAAE,MAAM,GAAG,CAAC;AAChE,UAAI,QAAQ,SAAS,KAAK,QAAQ,CAAC,GAAG;AACpC,oBAAY,IAAI,QAAQ,KAAK,GAAG,CAAC;AAAA,MACnC;AAAA,IACF;AAEA,UAAM,QAAQ,QAAQ;AACtB,cAAU,QAAQ;AAGlB,QAAI,MAAM,SAAS,GAAG;AACpB,YAAM,QAAQ,KAAK;AACnB;AAAA,IACF;AAAA,EACF;AAEA,SAAO,MAAM,KAAK,KAAK;AACzB;AAMA,SAAS,cAAc,OAAO;AAC5B,MAAI,OAAO,UAAU,YAAY,OAAO,UAAU,UAAU;AAC1D,WAAO,UAAU,OAAO,KAAK,EAAE,UAAU,GAAG,EAAE,CAAC;AAAA,EACjD;AACA,MAAI,MAAM,QAAQ,KAAK,GAAG;AACxB,WAAO,SAAS,MAAM,MAAM;AAAA,EAC9B;AACA,MAAI,OAAO,UAAU,YAAY,UAAU,MAAM;AAC/C,UAAM,UAAU,OAAO,KAAK,KAAK,EAAE,CAAC;AACpC,WAAO,IAAI,OAAO;AAAA,EACpB;AACA,SAAO,OAAO,KAAK;AACrB;AAMA,SAAS,aAAa,MAAM;AAC1B,MAAI,CAAC,KAAM,QAAO;AAClB,MAAI,KAAK,aAAa,GAAG;AACvB,WAAO,WAAW,KAAK,eAAe,IAAI,UAAU,GAAG,EAAE,CAAC;AAAA,EAC5D;AACA,MAAI,KAAK,aAAa,GAAG;AACvB,WAAO,IAAI,KAAK,QAAQ,YAAY,CAAC;AAAA,EACvC;AACA,SAAO,aAAa,KAAK,QAAQ;AACnC;;;AC/TO,SAAS,QAAQ,WAAW,WAAW,UAAU,CAAC,GAAG;AAE1D,MAAI,OAAO,cAAc,YAAY;AACnC,UAAM,IAAI;AAAA,MACR,sDAAsD,OAAO,SAAS;AAAA,IACxE;AAAA,EACF;AAEA,MAAI,CAAC,aAAa,OAAO,UAAU,iBAAiB,YAAY;AAC9D,UAAM,IAAI;AAAA,MACR,kEACE,cAAc,OAAO,SAAS,OAAO,SACvC;AAAA,IACF;AAAA,EACF;AAGA,kBAAgB,WAAW;AAG3B,QAAM;AAAA,IACJ,cAAc;AAAA,IACd,gBAAgB,uBAAuB;AAAA,IACvC,SAAS;AAAA,IACT;AAAA,IACA,OAAO,kBAAkB,CAAC;AAAA,EAC5B,IAAI;AAGJ,MAAI,QAAQ,iBAAiB,aAAa,SAAS,KAAK,CAAC;AAGzD,QAAM,iBAAiB,CAAC;AAGxB,QAAM,uBAAuB,oBAAI,IAAI;AAGrC,QAAM,eAAe;AAAA,IACnB,UAAU,MAAM;AAAA,IAChB,UAAU,CAAC,aAAa;AACtB,UAAI,OAAO,aAAa,YAAY;AAClC,gBAAQ,EAAE,GAAG,OAAO,GAAG,SAAS,KAAK,EAAE;AAAA,MACzC,OAAO;AACL,gBAAQ,EAAE,GAAG,OAAO,GAAG,SAAS;AAAA,MAClC;AAEA,iBAAW;AAAA,IACb;AAAA,EACF;AAGA,QAAM,iBAAiB,EAAE,GAAG,iBAAiB,GAAG,MAAM;AACtD,MAAI,aAAa,UAAU,cAAc;AAGzC,MAAI,sBAAsB;AACxB,UAAM,aAAa,eAAe,WAAW,UAAU;AAEvD,QAAI,WAAW,SAAS,GAAG;AACzB,UAAI,YAAY;AACd,mBAAW,UAAU;AAAA,MACvB,OAAO;AACL,yBAAiB,YAAY;AAAA,UAC3B,eAAe,UAAU,QAAQ;AAAA,UACjC;AAAA,QACF,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF;AAGA,wBAAsB,WAAW,YAAY,cAAc,oBAAoB;AAK/E,WAAS,aAAa;AACpB,UAAM,WAAW,EAAE,GAAG,iBAAiB,GAAG,MAAM;AAChD,iBAAa,UAAU,QAAQ;AAK/B,aAAS,WAAW,UAAU;AAG9B,0BAAsB,WAAW,YAAY,cAAc,oBAAoB;AAAA,EACjF;AAKA,WAAS,UAAU;AAEjB,eAAW,aAAa,sBAAsB;AAC5C,sBAAgB,WAAW,SAAS;AAAA,IACtC;AACA,yBAAqB,MAAM;AAG3B,eAAW,EAAE,SAAS,OAAO,SAAS,SAAAA,SAAQ,KAAK,gBAAgB;AACjE,cAAQ,oBAAoB,OAAO,SAASA,QAAO;AAAA,IACrD;AACA,mBAAe,SAAS;AAGxB,cAAU,gBAAgB,wBAAwB;AAAA,EACpD;AAMA,WAAS,SAAS,UAAU;AAC1B,QAAI,UAAU;AACZ,aAAO,OAAO,iBAAiB,QAAQ;AAAA,IACzC;AACA,eAAW;AAAA,EACb;AAMA,WAAS,WAAW;AAClB,WAAO,EAAE,GAAG,MAAM;AAAA,EACpB;AAMA,WAAS,SAAS,UAAU;AAC1B,iBAAa,SAAS,QAAQ;AAAA,EAChC;AAGA,YAAU,aAAa,0BAA0B,MAAM;AAGvD,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAMA,SAAS,sBAAsB,YAAY,OAAO,cAAc,YAAY;AAC1E,MAAI,CAAC,SAAS,OAAO,UAAU,YAAY,MAAM,QAAQ,KAAK,GAAG;AAC/D;AAAA,EACF;AAEA,QAAM,UAAU,OAAO,KAAK,KAAK,EAAE,CAAC;AACpC,QAAM,QAAQ,MAAM,OAAO;AAE3B,MAAI,CAAC,SAAS,OAAO,UAAU,UAAU;AACvC;AAAA,EACF;AAGA,QAAM,aAAa,OAAO,KAAK,KAAK,EAAE;AAAA,IACpC,CAAC,QAAQ,IAAI,WAAW,IAAI,KAAK,OAAO,MAAM,GAAG,MAAM;AAAA,EACzD;AAEA,aAAW,aAAa,YAAY;AAClC,UAAM,YAAY,UAAU,MAAM,CAAC,EAAE,YAAY;AACjD,UAAM,UAAU,MAAM,SAAS;AAG/B,UAAM,YAAY,GAAG,OAAO,IAAI,SAAS,IAAI,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,MAAM,GAAG,CAAC,CAAC;AAGnF,oBAAgB,SAAS,WAAW,SAAS,YAAY;AACzD,eAAW,IAAI,SAAS;AAGxB,UAAM,WAAW,iBAAiB,SAAS;AAC3C,QAAI,WAAW,cAAc;AAC3B,iBAAW,aAAa,UAAU,SAAS;AAAA,IAC7C;AAAA,EACF;AAGA,QAAM,WAAWC,kBAAiB,KAAK;AACvC,QAAM,cAAcC,2BAA0B,UAAU;AAExD,WAAS,QAAQ,CAAC,OAAO,UAAU;AACjC,QAAI,SAAS,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,KAAK,KAAK,YAAY,KAAK,GAAG;AACrF,4BAAsB,YAAY,KAAK,GAAG,OAAO,cAAc,UAAU;AAAA,IAC3E;AAAA,EACF,CAAC;AACH;AAMA,SAAS,SAAS,YAAY,OAAO;AACnC,MAAI,CAAC,SAAS,CAAC,YAAY;AACzB;AAAA,EACF;AAGA,MAAI,OAAO,UAAU,YAAY,OAAO,UAAU,UAAU;AAC1D,QAAI,WAAW,gBAAgB,OAAO,KAAK,GAAG;AAC5C,iBAAW,cAAc,OAAO,KAAK;AAAA,IACvC;AACA;AAAA,EACF;AAGA,MAAI,MAAM,QAAQ,KAAK,GAAG;AACxB;AAAA,EACF;AAEA,MAAI,OAAO,UAAU,UAAU;AAC7B;AAAA,EACF;AAEA,QAAM,UAAU,OAAO,KAAK,KAAK,EAAE,CAAC;AACpC,QAAM,QAAQ,MAAM,OAAO,KAAK,CAAC;AAGjC,QAAM,eAAe;AAAA,IACnB,WAAW;AAAA,IACX,SAAS;AAAA,EACX;AAEA,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,KAAK,GAAG;AAChD,QAAI,QAAQ,cAAc,QAAQ,UAAU,IAAI,WAAW,IAAI,GAAG;AAChE;AAAA,IACF;AAEA,UAAM,WAAW,aAAa,GAAG,KAAK;AAEtC,QAAI,UAAU,MAAM;AAClB,iBAAW,aAAa,UAAU,EAAE;AAAA,IACtC,WAAW,UAAU,SAAS,UAAU,QAAQ,UAAU,QAAW;AACnE,iBAAW,gBAAgB,QAAQ;AAAA,IACrC,WAAW,WAAW,aAAa,QAAQ,MAAM,OAAO,KAAK,GAAG;AAC9D,iBAAW,aAAa,UAAU,OAAO,KAAK,CAAC;AAAA,IACjD;AAAA,EACF;AAGA,MAAI,MAAM,SAAS,QAAW;AAC5B,UAAM,cAAc,OAAO,MAAM,IAAI;AACrC,QAAI,WAAW,gBAAgB,aAAa;AAC1C,iBAAW,cAAc;AAAA,IAC3B;AACA;AAAA,EACF;AAGA,QAAM,WAAWD,kBAAiB,KAAK;AACvC,QAAM,cAAcC,2BAA0B,UAAU;AAExD,WAAS,QAAQ,CAAC,OAAO,UAAU;AACjC,QAAI,YAAY,KAAK,GAAG;AACtB,eAAS,YAAY,KAAK,GAAG,KAAK;AAAA,IACpC;AAAA,EACF,CAAC;AACH;AAMA,SAASD,kBAAiB,OAAO;AAC/B,MAAI,CAAC,MAAO,QAAO,CAAC;AACpB,MAAI,MAAM,UAAU;AAClB,WAAO,MAAM,QAAQ,MAAM,QAAQ,IAAI,MAAM,WAAW,CAAC,MAAM,QAAQ;AAAA,EACzE;AACA,SAAO,CAAC;AACV;AAMA,SAASC,2BAA0B,SAAS;AAC1C,MAAI,CAAC,WAAW,CAAC,QAAQ,WAAY,QAAO,CAAC;AAE7C,SAAO,MAAM,KAAK,QAAQ,UAAU,EAAE,OAAO,CAAC,SAAS;AACrD,QAAI,KAAK,aAAa,EAAG,QAAO;AAChC,QAAI,KAAK,aAAa,GAAG;AAEvB,aAAO,KAAK,eAAe,KAAK,YAAY,KAAK,EAAE,SAAS;AAAA,IAC9D;AACA,WAAO;AAAA,EACT,CAAC;AACH;;;ACtTO,IAAM,iBAAN,MAAqB;AAAA,EAC1B,cAAc;AAKZ,SAAK,kBAAkB,oBAAI,IAAI;AAAA,EACjC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,cAAc,UAAU;AACtB,UAAM,YAAY;AAAA,MAChB,QAAQ,oBAAI,IAAI;AAAA,MAChB,WAAW,oBAAI,IAAI;AAAA,MACnB,WAAW,CAAC;AAAA,MACZ,kBAAkB,oBAAI,IAAI;AAAA,IAC5B;AAEA,SAAK,gBAAgB,IAAI,UAAU,SAAS;AAE5C,UAAM,UAAU;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAQd,YAAY,CAAC,UAAU,UAAU,SAAS;AACxC,cAAM,KAAK;AAAA,UACT,IAAI,MAAM;AACR,sBAAU,OAAO,OAAO,EAAE;AAC1B,qBAAS,GAAG,CAAC;AAAA,UACf;AAAA,UACA;AAAA,UACA,GAAG;AAAA,QACL;AACA,kBAAU,OAAO,IAAI,EAAE;AACvB,eAAO;AAAA,MACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MASA,aAAa,CAAC,UAAU,UAAU,SAAS;AACzC,cAAM,KAAK,YAAY,UAAU,OAAO,GAAG,IAAI;AAC/C,kBAAU,UAAU,IAAI,EAAE;AAC1B,eAAO;AAAA,MACT;AAAA;AAAA;AAAA;AAAA;AAAA,MAMA,cAAc,CAAC,OAAO;AACpB,kBAAU,OAAO,OAAO,EAAE;AAC1B,qBAAa,EAAE;AAAA,MACjB;AAAA;AAAA;AAAA;AAAA;AAAA,MAMA,eAAe,CAAC,OAAO;AACrB,kBAAU,UAAU,OAAO,EAAE;AAC7B,sBAAc,EAAE;AAAA,MAClB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MASA,kBAAkB,CAAC,QAAQ,OAAO,SAAS,YAAY;AACrD,eAAO,iBAAiB,OAAO,SAAS,OAAO;AAC/C,kBAAU,UAAU,KAAK,EAAE,QAAQ,OAAO,SAAS,QAAQ,CAAC;AAAA,MAC9D;AAAA;AAAA;AAAA;AAAA;AAAA,MAMA,uBAAuB,MAAM;AAC3B,cAAM,aAAa,IAAI,gBAAgB;AACvC,kBAAU,iBAAiB,IAAI,UAAU;AACzC,eAAO;AAAA,MACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAQA,OAAO,CAAC,KAAK,UAAU,CAAC,MAAM;AAC5B,cAAM,aAAa,IAAI,gBAAgB;AACvC,kBAAU,iBAAiB,IAAI,UAAU;AAGzC,cAAM,gBAAgB;AAAA,UACpB,GAAG;AAAA,UACH,QAAQ,WAAW;AAAA,QACrB;AAEA,eAAO,MAAM,KAAK,aAAa,EAAE,QAAQ,MAAM;AAC7C,oBAAU,iBAAiB,OAAO,UAAU;AAAA,QAC9C,CAAC;AAAA,MACH;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,QAAQ,UAAU;AAChB,UAAM,YAAY,KAAK,gBAAgB,IAAI,QAAQ;AACnD,QAAI,CAAC,UAAW;AAGhB,eAAW,MAAM,UAAU,QAAQ;AACjC,mBAAa,EAAE;AAAA,IACjB;AACA,cAAU,OAAO,MAAM;AAGvB,eAAW,MAAM,UAAU,WAAW;AACpC,oBAAc,EAAE;AAAA,IAClB;AACA,cAAU,UAAU,MAAM;AAG1B,eAAW,EAAE,QAAQ,OAAO,SAAS,QAAQ,KAAK,UAAU,WAAW;AACrE,UAAI;AACF,eAAO,oBAAoB,OAAO,SAAS,OAAO;AAAA,MACpD,QAAQ;AAAA,MAER;AAAA,IACF;AACA,cAAU,UAAU,SAAS;AAG7B,eAAW,cAAc,UAAU,kBAAkB;AACnD,UAAI;AACF,mBAAW,MAAM;AAAA,MACnB,QAAQ;AAAA,MAER;AAAA,IACF;AACA,cAAU,iBAAiB,MAAM;AAEjC,SAAK,gBAAgB,OAAO,QAAQ;AAAA,EACtC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,cAAc,UAAU;AACtB,UAAM,YAAY,KAAK,gBAAgB,IAAI,QAAQ;AACnD,QAAI,CAAC,UAAW;AAEhB,UAAM,WAAW,CAAC;AAElB,QAAI,UAAU,OAAO,OAAO,GAAG;AAC7B,eAAS,KAAK,GAAG,UAAU,OAAO,IAAI,0BAA0B;AAAA,IAClE;AACA,QAAI,UAAU,UAAU,OAAO,GAAG;AAChC,eAAS,KAAK,GAAG,UAAU,UAAU,IAAI,6BAA6B;AAAA,IACxE;AACA,QAAI,UAAU,UAAU,SAAS,GAAG;AAClC,eAAS,KAAK,GAAG,UAAU,UAAU,MAAM,6BAA6B;AAAA,IAC1E;AACA,QAAI,UAAU,iBAAiB,OAAO,GAAG;AACvC,eAAS;AAAA,QACP,GAAG,UAAU,iBAAiB,IAAI;AAAA,MACpC;AAAA,IACF;AAEA,QAAI,SAAS,SAAS,GAAG;AACvB,cAAQ,KAAK,kCAAkC,QAAQ,KAAK,SAAS,KAAK,IAAI,CAAC,EAAE;AAAA,IACnF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,aAAa,UAAU;AACrB,WAAO,KAAK,gBAAgB,IAAI,QAAQ;AAAA,EAC1C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,kBAAkB,UAAU;AAC1B,UAAM,YAAY,KAAK,gBAAgB,IAAI,QAAQ;AACnD,QAAI,CAAC,UAAW,QAAO;AAEvB,WAAO;AAAA,MACL,QAAQ,UAAU,OAAO;AAAA,MACzB,WAAW,UAAU,UAAU;AAAA,MAC/B,WAAW,UAAU,UAAU;AAAA,MAC/B,kBAAkB,UAAU,iBAAiB;AAAA,IAC/C;AAAA,EACF;AACF;AAMO,IAAM,iBAAiB,IAAI,eAAe;;;AC/O1C,IAAM,gBAAN,MAAoB;AAAA,EACzB,cAAc;AAKZ,SAAK,iBAAiB,oBAAI,IAAI;AAM9B,SAAK,kBAAkB,oBAAI,IAAI;AAM/B,SAAK,iBAAiB;AAAA,EACxB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcA,YAAY,OAAO;AACjB,UAAM,QAAQ,CAAC;AAGf,QAAI,MAAM,IAAI;AACZ,YAAM,KAAK,IAAI,MAAM,EAAE,EAAE;AACzB,aAAO,MAAM,KAAK,GAAG;AAAA,IACvB;AAGA,QAAI,MAAM,MAAM;AACd,YAAM,KAAK,UAAU,MAAM,IAAI,IAAI;AAAA,IACrC;AAEA,QAAI,MAAM,MAAM;AACd,YAAM,KAAK,UAAU,MAAM,IAAI,IAAI;AAAA,IACrC;AAGA,QAAI,MAAM,MAAM,IAAI;AAClB,YAAM,KAAK,QAAQ,MAAM,KAAK,EAAE,EAAE;AAAA,IACpC;AAGA,QAAI,MAAM,WAAW,GAAG;AACtB,YAAM,KAAK,KAAK,eAAe,KAAK,CAAC;AAAA,IACvC;AAEA,WAAO,MAAM,KAAK,GAAG;AAAA,EACvB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,eAAe,SAAS;AACtB,UAAM,OAAO,CAAC;AACd,QAAI,UAAU;AAEd,WAAO,WAAW,YAAY,SAAS,QAAQ,KAAK,SAAS,IAAI;AAC/D,UAAI,WAAW,QAAQ,QAAQ,YAAY;AAG3C,UAAI,QAAQ,aAAa,OAAO,QAAQ,cAAc,UAAU;AAC9D,cAAM,UAAU,QAAQ,UAAU,KAAK,EAAE,MAAM,KAAK,EAAE,MAAM,GAAG,CAAC;AAChE,YAAI,QAAQ,SAAS,KAAK,QAAQ,CAAC,GAAG;AACpC,sBAAY,IAAI,QAAQ,KAAK,GAAG,CAAC;AAAA,QACnC;AAAA,MACF;AAGA,UAAI,QAAQ,eAAe;AACzB,cAAM,WAAW,QAAQ,cAAc;AAAA,UACrC,YAAY,QAAQ,QAAQ,YAAY,CAAC;AAAA,QAC3C;AACA,YAAI,SAAS,SAAS,GAAG;AACvB,gBAAM,QAAQ,MAAM,KAAK,QAAQ,EAAE,QAAQ,OAAO;AAClD,sBAAY,gBAAgB,QAAQ,CAAC;AAAA,QACvC;AAAA,MACF;AAEA,WAAK,QAAQ,QAAQ;AACrB,gBAAU,QAAQ;AAAA,IACpB;AAEA,WAAO,KAAK,KAAK,KAAK;AAAA,EACxB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,mBAAmB;AACjB,SAAK,eAAe,MAAM;AAE1B,UAAM,SAAS,SAAS,iBAAiB,yBAAyB;AAElE,eAAW,SAAS,QAAQ;AAC1B,YAAM,MAAM,KAAK,YAAY,KAAK;AAClC,YAAM,QAAQ;AAAA,QACZ,OAAO,MAAM;AAAA,QACb,MAAM,MAAM,QAAQ,MAAM,QAAQ,YAAY;AAAA,MAChD;AAGA,UACE,OAAO,MAAM,mBAAmB,aAC/B,MAAM,SAAS,UACd,MAAM,SAAS,YACf,MAAM,SAAS,SACf,MAAM,SAAS,SACf,MAAM,SAAS,cACf,MAAM,QAAQ,YAAY,MAAM,aAClC;AACA,cAAM,iBAAiB,MAAM;AAC7B,cAAM,eAAe,MAAM;AAAA,MAC7B;AAGA,UAAI,MAAM,SAAS,cAAc,MAAM,SAAS,SAAS;AACvD,cAAM,UAAU,MAAM;AAAA,MACxB;AAEA,WAAK,eAAe,IAAI,KAAK,KAAK;AAAA,IACpC;AAEA,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,mBAAmB;AACjB,eAAW,CAAC,KAAK,KAAK,KAAK,KAAK,gBAAgB;AAC9C,YAAM,SAAS,KAAK,gBAAgB,GAAG;AAEvC,iBAAW,SAAS,QAAQ;AAE1B,cAAM,cAAc,MAAM,QAAQ,MAAM,QAAQ,YAAY;AAC5D,YAAI,gBAAgB,MAAM,MAAM;AAC9B;AAAA,QACF;AAGA,YAAI,MAAM,YAAY,QAAW;AAC/B,gBAAM,UAAU,MAAM;AACtB;AAAA,QACF;AAGA,cAAM,QAAQ,MAAM;AAGpB,YACE,MAAM,mBAAmB,UACzB,SAAS,kBAAkB,OAC3B;AACA,cAAI;AACF,kBAAM,kBAAkB,MAAM,gBAAgB,MAAM,YAAY;AAAA,UAClE,QAAQ;AAAA,UAER;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,gBAAgB,KAAK;AAEnB,QAAI,IAAI,WAAW,GAAG,GAAG;AACvB,YAAM,KAAK,IAAI,MAAM,CAAC;AACtB,YAAM,KAAK,SAAS,eAAe,EAAE;AACrC,aAAO,KAAK,CAAC,EAAE,IAAI,CAAC;AAAA,IACtB;AAGA,UAAM,YAAY,IAAI,MAAM,oBAAoB;AAChD,QAAI,WAAW;AACb,YAAM,OAAO,UAAU,CAAC;AACxB,YAAM,YAAY,IAAI,MAAM,oBAAoB;AAChD,YAAM,OAAO,YAAY,UAAU,CAAC,IAAI;AAExC,UAAI,WAAW,UAAU,IAAI;AAC7B,UAAI,MAAM;AACR,oBAAY,UAAU,IAAI;AAAA,MAC5B;AAEA,aAAO,MAAM,KAAK,SAAS,iBAAiB,QAAQ,CAAC;AAAA,IACvD;AAGA,QAAI;AACF,YAAM,KAAK,SAAS,cAAc,GAAG;AACrC,aAAO,KAAK,CAAC,EAAE,IAAI,CAAC;AAAA,IACtB,QAAQ;AACN,aAAO,CAAC;AAAA,IACV;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,yBAAyB;AACvB,SAAK,gBAAgB,MAAM;AAG3B,SAAK,gBAAgB,IAAI,UAAU;AAAA,MACjC,KAAK,OAAO;AAAA,MACZ,MAAM,OAAO;AAAA,IACf,CAAC;AAGD,UAAM,oBAAoB,SAAS;AAAA,MACjC;AAAA,IACF;AACA,eAAW,MAAM,mBAAmB;AAClC,YAAM,MAAM,KAAK,iBAAiB,EAAE;AACpC,WAAK,gBAAgB,IAAI,KAAK;AAAA,QAC5B,KAAK,GAAG;AAAA,QACR,MAAM,GAAG;AAAA,MACX,CAAC;AAAA,IACH;AAGA,UAAM,mBAAmB,SAAS;AAAA,MAChC;AAAA,IACF;AACA,eAAW,MAAM,kBAAkB;AACjC,YAAM,QAAQ,OAAO,iBAAiB,EAAE;AACxC,YAAM,cACJ,MAAM,aAAa,UACnB,MAAM,aAAa,YACnB,MAAM,cAAc,UACpB,MAAM,cAAc,YACpB,MAAM,cAAc,UACpB,MAAM,cAAc;AAEtB,UACE,gBACC,GAAG,eAAe,GAAG,gBAAgB,GAAG,cAAc,GAAG,cAC1D;AACA,cAAM,MAAM,KAAK,iBAAiB,EAAE;AACpC,YAAI,CAAC,KAAK,gBAAgB,IAAI,GAAG,GAAG;AAClC,eAAK,gBAAgB,IAAI,KAAK;AAAA,YAC5B,KAAK,GAAG;AAAA,YACR,MAAM,GAAG;AAAA,UACX,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAEA,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,iBAAiB,IAAI;AACnB,QAAI,GAAG,IAAI;AACT,aAAO,IAAI,GAAG,EAAE;AAAA,IAClB;AAEA,UAAM,YAAY,GAAG,aAAa,yBAAyB;AAC3D,QAAI,WAAW;AACb,aAAO,6BAA6B,SAAS;AAAA,IAC/C;AAEA,WAAO,KAAK,eAAe,EAAE;AAAA,EAC/B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,gBAAgB;AACd,SAAK,iBAAiB;AAAA,MACpB,YAAY,SAAS,KAAK;AAAA,MAC1B,WAAW,SAAS,KAAK;AAAA,MACzB,SAAS,oBAAI,IAAI;AAAA,IACnB;AAGA,UAAM,aAAa,SAAS,iBAAiB,2BAA2B;AACxE,eAAW,MAAM,YAAY;AAC3B,YAAM,OAAO,GAAG,sBAAsB;AACtC,YAAM,MAAM,KAAK,iBAAiB,EAAE;AACpC,WAAK,eAAe,QAAQ,IAAI,KAAK;AAAA,QACnC,KAAK,KAAK;AAAA,QACV,MAAM,KAAK;AAAA,QACX,OAAO,KAAK;AAAA,QACZ,QAAQ,KAAK;AAAA,MACf,CAAC;AAAA,IACH;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,6BAA6B;AAC3B,QAAI,CAAC,KAAK,gBAAgB;AACxB,aAAO;AAAA,IACT;AAEA,UAAM,YAAY;AAGlB,UAAM,aAAa,KAAK;AAAA,MACtB,SAAS,KAAK,eAAe,KAAK,eAAe;AAAA,IACnD;AACA,UAAM,YAAY,KAAK;AAAA,MACrB,SAAS,KAAK,cAAc,KAAK,eAAe;AAAA,IAClD;AAEA,QAAI,aAAa,aAAa,YAAY,WAAW;AACnD,aAAO;AAAA,IACT;AAGA,eAAW,CAAC,KAAK,OAAO,KAAK,KAAK,eAAe,SAAS;AACxD,YAAM,KAAK,KAAK,iBAAiB,GAAG;AACpC,UAAI,CAAC,IAAI;AACP;AAAA,MACF;AAEA,YAAM,UAAU,GAAG,sBAAsB;AACzC,YAAM,UAAU,KAAK,IAAI,QAAQ,MAAM,QAAQ,GAAG;AAClD,YAAM,WAAW,KAAK,IAAI,QAAQ,OAAO,QAAQ,IAAI;AAErD,UAAI,UAAU,aAAa,WAAW,WAAW;AAC/C,eAAO;AAAA,MACT;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,iBAAiB,KAAK;AACpB,QAAI,QAAQ,UAAU;AACpB,aAAO;AAAA,IACT;AAEA,QAAI,IAAI,WAAW,GAAG,GAAG;AACvB,aAAO,SAAS,eAAe,IAAI,MAAM,CAAC,CAAC;AAAA,IAC7C;AAEA,QAAI;AACF,aAAO,SAAS,cAAc,GAAG;AAAA,IACnC,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,yBAAyB;AACvB,QAAI,KAAK,2BAA2B,GAAG;AACrC,cAAQ,IAAI,0DAA0D;AACtE;AAAA,IACF;AAGA,UAAM,YAAY,KAAK,gBAAgB,IAAI,QAAQ;AACnD,QAAI,WAAW;AACb,aAAO,SAAS,UAAU,MAAM,UAAU,GAAG;AAAA,IAC/C;AAGA,eAAW,CAAC,KAAK,GAAG,KAAK,KAAK,iBAAiB;AAC7C,UAAI,QAAQ,UAAU;AACpB;AAAA,MACF;AAEA,YAAM,KAAK,KAAK,iBAAiB,GAAG;AACpC,UAAI,IAAI;AACN,WAAG,YAAY,IAAI;AACnB,WAAG,aAAa,IAAI;AAAA,MACtB;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,aAAa;AACX,SAAK,iBAAiB;AACtB,SAAK,uBAAuB;AAC5B,SAAK,cAAc;AAAA,EACrB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,aAAa;AACX,SAAK,iBAAiB;AACtB,SAAK,uBAAuB;AAAA,EAC9B;AAAA;AAAA;AAAA;AAAA,EAKA,QAAQ;AACN,SAAK,eAAe,MAAM;AAC1B,SAAK,gBAAgB,MAAM;AAC3B,SAAK,iBAAiB;AAAA,EACxB;AACF;AAMO,IAAM,gBAAgB,IAAI,cAAc;;;ACndxC,SAAS,WAAW,KAAK;AAC9B,SAAO,OAAO,GAAG,EACd,QAAQ,MAAM,OAAO,EACrB,QAAQ,MAAM,MAAM,EACpB,QAAQ,MAAM,MAAM,EACpB,QAAQ,MAAM,QAAQ;AAC3B;AASO,SAAS,gBAAgB,OAAO,eAAe,YAAY,GAAG;AACnE,MAAI,CAAC,MAAO,QAAO;AAEnB,QAAM,QAAQ,MAAM,MAAM,IAAI;AAC9B,SAAO,MAAM,IAAI,CAAC,SAAS,MAAM;AAC/B,UAAM,UAAU,YAAY;AAC5B,UAAM,cAAc,YAAY;AAChC,WAAO,mBAAmB,cAAc,eAAe,EAAE;AAAA,kCAC3B,OAAO;AAAA,mCACN,WAAW,OAAO,CAAC;AAAA;AAAA,EAEpD,CAAC,EAAE,KAAK,EAAE;AACZ;AAKA,IAAM,cAAc;AAAA,EAClB,QAAQ,CAAC,MAAM,SAAS,iBAAiB,IAAI,IAAI,IAAI;AAAA,EACrD,QAAQ,CAAC,MAAM,SAAS,iBAAiB,IAAI,IAAI,IAAI;AAAA,EACrD,mBAAmB,CAAC,MAAM,SAAS,0BAA0B,IAAI,IAAI,IAAI;AAAA,EACzE,MAAM,CAAC,MAAM,SAAS,kCAAkC,IAAI,SAAS,IAAI;AAAA,EACzE,SAAS,CAAC,MAAM,SAAS,0BAA0B,IAAI,SAAS,IAAI;AAAA,EACpE,UAAU,CAAC,MAAM,SAAS,wBAAwB,IAAI,SAAS,IAAI;AAAA,EACnE,MAAM,CAAC,MAAM,SAAS,oBAAoB,IAAI,SAAS,IAAI;AAC7D;AAKA,IAAM,iBAAiB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAyIhB,IAAM,eAAN,MAAmB;AAAA,EACxB,cAAc;AAEZ,SAAK,UAAU;AAEf,SAAK,SAAS,KAAK,iBAAiB;AAEpC,SAAK,gBAAgB;AAAA,EACvB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,mBAAmB;AACjB,QAAI;AACF,aAAO,aAAa,QAAQ,iBAAiB,KAAK;AAAA,IACpD,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,gBAAgB;AACd,QAAI,KAAK,QAAS,QAAO,KAAK;AAE9B,UAAM,OAAO,SAAS,cAAc,KAAK;AACzC,SAAK,KAAK;AACV,UAAM,SAAS,KAAK,aAAa,EAAE,MAAM,OAAO,CAAC;AAEjD,UAAM,QAAQ,SAAS,cAAc,OAAO;AAC5C,UAAM,cAAc;AACpB,WAAO,YAAY,KAAK;AAExB,SAAK,UAAU,EAAE,MAAM,OAAO;AAC9B,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYA,KAAK,OAAO;AACV,UAAM,EAAE,MAAM,OAAO,IAAI,KAAK,cAAc;AAG5C,UAAM,kBAAkB,OAAO,cAAc,UAAU;AACvD,QAAI,gBAAiB,iBAAgB,OAAO;AAG5C,UAAM,aAAa,MAAM,QAAQ,MAAM,MAAM,MAAM,IAAI,EAAE,SAAS;AAClE,UAAM,YAAY,MAAM,OAAO,KAAK,IAAI,GAAG,MAAM,OAAO,KAAK,MAAM,aAAa,CAAC,CAAC,IAAI;AAEtF,UAAM,UAAU,SAAS,cAAc,KAAK;AAC5C,YAAQ,YAAY;AACpB,YAAQ,YAAY;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,iCAQS,WAAW,MAAM,WAAW,eAAe,CAAC;AAAA,YACjE,MAAM,OAAO;AAAA,2CACkB,WAAW,MAAM,IAAI,CAAC,gBAAgB,MAAM,QAAQ,CAAC;AAAA,gBAChF,WAAW,MAAM,IAAI,CAAC,GAAG,MAAM,OAAO,IAAI,MAAM,IAAI,KAAK,EAAE,GAAG,MAAM,SAAS,IAAI,MAAM,MAAM,KAAK,EAAE;AAAA;AAAA,cAEtG,EAAE;AAAA,YACJ,MAAM,QAAQ;AAAA,sCACY,gBAAgB,MAAM,OAAO,MAAM,MAAM,SAAS,CAAC;AAAA,cAC3E,EAAE;AAAA,YACJ,MAAM,QAAQ;AAAA,iCACO,WAAW,MAAM,KAAK,CAAC;AAAA,cAC1C,EAAE;AAAA;AAAA;AAAA,cAGF,MAAM,OAAO,mCAAmC,KAAK,MAAM,MAAM,EAAE;AAAA;AAAA;AAAA;AAAA;AAM7E,WAAO,YAAY,OAAO;AAG1B,UAAM,WAAW,QAAQ,cAAc,YAAY;AACnD,UAAM,WAAW,QAAQ,cAAc,WAAW;AAClD,UAAM,WAAW,QAAQ,cAAc,OAAO;AAE9C,cAAU,iBAAiB,SAAS,MAAM,KAAK,KAAK,CAAC;AACrD,cAAU,iBAAiB,SAAS,MAAM,KAAK,KAAK,CAAC;AACrD,cAAU,iBAAiB,SAAS,CAAC,MAAM;AACzC,YAAM,SAAS,EAAE;AACjB,YAAM,OAAO,OAAO,QAAQ;AAC5B,YAAM,OAAO,SAAS,OAAO,QAAQ,MAAM,EAAE,KAAK;AAClD,WAAK,aAAa,MAAM,IAAI;AAAA,IAC9B,CAAC;AAGD,SAAK,gBAAgB,CAAC,MAAM;AAC1B,UAAI,EAAE,QAAQ,SAAU,MAAK,KAAK;AAAA,IACpC;AACA,aAAS,iBAAiB,WAAW,KAAK,aAAa;AAGvD,QAAI,CAAC,KAAK,YAAY;AACpB,eAAS,KAAK,YAAY,IAAI;AAAA,IAChC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,OAAO;AACL,QAAI,KAAK,SAAS,KAAK,YAAY;AACjC,WAAK,QAAQ,KAAK,WAAW,YAAY,KAAK,QAAQ,IAAI;AAAA,IAC5D;AACA,QAAI,KAAK,eAAe;AACtB,eAAS,oBAAoB,WAAW,KAAK,aAAa;AAC1D,WAAK,gBAAgB;AAAA,IACvB;AAEA,SAAK,UAAU;AAAA,EACjB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,aAAa,MAAM,OAAO,GAAG;AAC3B,UAAM,eAAe,YAAY,KAAK,MAAM,KAAK,YAAY;AAC7D,UAAM,MAAM,aAAa,MAAM,IAAI;AACnC,WAAO,KAAK,KAAK,OAAO;AAAA,EAC1B;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,UAAU,QAAQ;AAChB,SAAK,SAAS;AACd,QAAI;AACF,mBAAa,QAAQ,mBAAmB,MAAM;AAAA,IAChD,QAAQ;AAAA,IAER;AAAA,EACF;AACF;AAKO,IAAM,eAAe,IAAI,aAAa;;;AC5V7C,IAAM,gBAAgB;AAAA,EACpB,WAAW;AAAA;AAAA,EACX,cAAc;AAAA;AAAA,EACd,cAAc;AAAA;AAAA,EACd,OAAO;AAAA;AACT;AAKA,IAAM,gBAAgB;AAAA,EACpB,WAAW;AAAA,EACX,cAAc;AAAA,EACd,cAAc;AAAA,EACd,OAAO;AACT;AAKA,IAAM,gBAAgB;AAMf,IAAM,sBAAN,MAA0B;AAAA,EAC/B,cAAc;AAEZ,SAAK,YAAY;AAAA,EACnB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,SAAS;AACP,QAAI,KAAK,UAAW;AAEpB,UAAM,KAAK,SAAS,cAAc,KAAK;AACvC,OAAG,KAAK;AACR,OAAG,MAAM,UAAU;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,oBAOH,aAAa;AAAA;AAAA;AAAA;AAAA;AAK7B,OAAG,QAAQ;AAEX,aAAS,KAAK,YAAY,EAAE;AAC5B,SAAK,YAAY;AAAA,EACnB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,OAAO,QAAQ;AACb,QAAI,CAAC,KAAK,WAAW;AACnB,WAAK,OAAO;AAAA,IACd;AAEA,UAAM,QAAQ,cAAc,MAAM,KAAK,cAAc;AACrD,UAAM,QAAQ,cAAc,MAAM,KAAK;AAEvC,SAAK,UAAU,MAAM,aAAa;AAClC,SAAK,UAAU,QAAQ;AAAA,EACzB;AAAA;AAAA;AAAA;AAAA,EAKA,UAAU;AACR,QAAI,KAAK,WAAW,YAAY;AAC9B,WAAK,UAAU,WAAW,YAAY,KAAK,SAAS;AAAA,IACtD;AACA,SAAK,YAAY;AAAA,EACnB;AACF;AAKO,IAAM,sBAAsB,IAAI,oBAAoB;;;AC1FpD,IAAM,gBAAN,MAAoB;AAAA,EACzB,cAAc;AAKZ,SAAK,UAAU,oBAAI,IAAI;AAMvB,SAAK,SAAS;AAAA,EAChB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,UAAU,QAAQ;AAChB,SAAK,SAAS;AAAA,EAChB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAgBA,iBAAiB,UAAU;AAEzB,QAAI,aAAa,KAAK,QAAQ,IAAI,QAAQ;AAC1C,QAAI,CAAC,YAAY;AACf,mBAAa;AAAA,QACX,QAAQ;AAAA,QACR,YAAY;AAAA,QACZ,SAAS;AAAA,QACT,OAAO;AAAA,QACP,MAAM,CAAC;AAAA,MACT;AACA,WAAK,QAAQ,IAAI,UAAU,UAAU;AAAA,IACvC;AAEA,UAAM,UAAU;AAEhB,WAAO;AAAA;AAAA;AAAA;AAAA;AAAA,MAKL,IAAI,OAAO;AACT,eAAO,WAAW;AAAA,MACpB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAQA,OAAO,UAAU;AACf,mBAAW,SAAS,aAAa,MAAM;AAAA,QAAC;AAAA,MAC1C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MASA,WAAW,MAAM,UAAU;AACzB,cAAM,YAAY,MAAM,QAAQ,IAAI,IAAI,OAAO,CAAC,IAAI;AACpD,mBAAW,aAAa,EAAE,MAAM,WAAW,SAAS;AAAA,MACtD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MASA,QAAQ,UAAU;AAChB,mBAAW,UAAU;AAAA,MACvB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAQA,MAAM,UAAU;AACd,mBAAW,QAAQ;AAAA,MACrB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MASA,WAAW,SAAS;AAClB,cAAM,UAAU,OAAO,cAAc,cAAc,UAAU,OAAO;AACpE,YAAI,QAAQ,QAAQ,eAAe,SAAS;AAC1C,kBAAQ,OAAO,KAAK,KAAK,UAAU;AAAA,YACjC,MAAM;AAAA,YACN;AAAA,YACA;AAAA,UACF,CAAC,CAAC;AAAA,QACJ;AAEA,gBAAQ,IAAI,gBAAgB,QAAQ,eAAe,UAAU,KAAK,OAAO,KAAK,EAAE,EAAE;AAAA,MACpF;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,aAAa,UAAU;AACrB,UAAM,aAAa,KAAK,QAAQ,IAAI,QAAQ;AAC5C,WAAO,CAAC,EAAE,YAAY,UAAU,YAAY;AAAA,EAC9C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcA,cAAc,UAAU,eAAe;AAErC,QAAI,KAAK,aAAa,QAAQ,GAAG;AAC/B,aAAO;AAAA,IACT;AAGA,QAAI,eAAe,kBAAkB,MAAM;AACzC,aAAO;AAAA,IACT;AAIA,UAAM,gBAAgB,KAAK,qBAAqB,QAAQ;AACxD,QAAI,iBAAiB,OAAO,aAAa,aAAa;AACpD,YAAM,eAAe,SAAS;AAAA,QAC5B,6BAA6B,aAAa;AAAA,MAC5C;AACA,UAAI,cAAc;AAChB,eAAO;AAAA,MACT;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,qBAAqB,UAAU;AAE7B,UAAM,QAAQ,SAAS,MAAM,yBAAyB;AACtD,QAAI,OAAO;AACT,aAAO,MAAM,CAAC;AAAA,IAChB;AACA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,eAAe,UAAU;AACvB,UAAM,aAAa,KAAK,QAAQ,IAAI,QAAQ;AAC5C,QAAI,CAAC,YAAY;AACf,aAAO;AAAA,IACT;AAGA,QAAI,OAAO,WAAW,YAAY,YAAY;AAC5C,UAAI;AACF,mBAAW,QAAQ,WAAW,IAAI;AAAA,MACpC,SAAS,KAAK;AACZ,gBAAQ,MAAM,sCAAsC,QAAQ,KAAK,GAAG;AAAA,MACtE;AAAA,IACF;AAEA,WAAO,WAAW;AAAA,EACpB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,cAAc,UAAU,WAAW;AACjC,UAAM,aAAa,KAAK,QAAQ,IAAI,QAAQ;AAC5C,QAAI,CAAC,YAAY,QAAQ;AACvB,aAAO;AAAA,IACT;AAEA,QAAI;AACF,iBAAW,OAAO,SAAS;AAC3B,aAAO;AAAA,IACT,SAAS,KAAK;AACZ,cAAQ,MAAM,qCAAqC,QAAQ,KAAK,GAAG;AACnE,aAAO;AAAA,IACT;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,kBAAkB,UAAU,aAAa;AACvC,UAAM,aAAa,KAAK,QAAQ,IAAI,QAAQ;AAC5C,QAAI,CAAC,YAAY,YAAY;AAC3B,aAAO;AAAA,IACT;AAEA,QAAI;AACF,YAAM,EAAE,MAAM,SAAS,IAAI,WAAW;AAEtC,YAAM,UAAU,KAAK,IAAI,CAAC,QAAQ,YAAY,GAAG,CAAC;AAClD,eAAS,OAAO;AAChB,aAAO;AAAA,IACT,SAAS,KAAK;AACZ,cAAQ,MAAM,yCAAyC,QAAQ,KAAK,GAAG;AACvE,aAAO;AAAA,IACT;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,aAAa,UAAU;AACrB,UAAM,aAAa,KAAK,QAAQ,IAAI,QAAQ;AAC5C,QAAI,CAAC,YAAY,OAAO;AACtB;AAAA,IACF;AAEA,QAAI;AACF,iBAAW,MAAM;AAAA,IACnB,SAAS,KAAK;AACZ,cAAQ,MAAM,oCAAoC,QAAQ,KAAK,GAAG;AAAA,IACpE;AAGA,SAAK,QAAQ,OAAO,QAAQ;AAAA,EAC9B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,UAAU,UAAU;AAClB,WAAO,KAAK,QAAQ,IAAI,QAAQ;AAAA,EAClC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,cAAc,UAAU;AACtB,WAAO,KAAK,QAAQ,IAAI,QAAQ,KAAK;AAAA,EACvC;AAAA;AAAA;AAAA;AAAA,EAKA,QAAQ;AACN,SAAK,QAAQ,MAAM;AAAA,EACrB;AACF;AAMO,IAAM,gBAAgB,IAAI,cAAc;AAQxC,SAAS,iBAAiB,UAAU;AACzC,SAAO,cAAc,iBAAiB,QAAQ;AAChD;;;ACxUA,SAAS,mBAAmB,OAAO;AACjC,QAAM,SAAS,EAAE,MAAM,MAAM,MAAM,MAAM,QAAQ,KAAK;AAEtD,MAAI,CAAC,MAAM,OAAO;AAChB,WAAO;AAAA,EACT;AAMA,QAAM,WAAW;AAAA,IACf;AAAA;AAAA,IACA;AAAA;AAAA,IACA;AAAA;AAAA,IACA;AAAA;AAAA,EACF;AAEA,QAAM,QAAQ,MAAM,MAAM,MAAM,IAAI;AACpC,aAAW,QAAQ,OAAO;AACxB,eAAW,WAAW,UAAU;AAC9B,YAAM,QAAQ,KAAK,MAAM,OAAO;AAChC,UAAI,OAAO;AACT,eAAO,OAAO,MAAM,CAAC;AACrB,eAAO,OAAO,SAAS,MAAM,CAAC,GAAG,EAAE;AACnC,eAAO,SAAS,SAAS,MAAM,CAAC,GAAG,EAAE;AACrC,eAAO;AAAA,MACT;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAKO,IAAM,YAAN,MAAgB;AAAA,EACrB,cAAc;AAKZ,SAAK,SAAS;AAMd,SAAK,YAAY;AAMjB,SAAK,oBAAoB;AAMzB,SAAK,uBAAuB;AAM5B,SAAK,iBAAiB;AAMtB,SAAK,gBAAgB;AAMrB,SAAK,mBAAmB;AAMxB,SAAK,cAAc;AAAA,EACrB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,UAAU;AACR,QAAI,OAAO,WAAW,aAAa;AACjC;AAAA,IACF;AAGA,QAAI,KAAK,qBAAqB,MAAM;AAClC,mBAAa,KAAK,gBAAgB;AAClC,WAAK,mBAAmB;AAAA,IAC1B;AAEA,QAAI;AACF,YAAM,WAAW,SAAS,aAAa,WAAW,QAAQ;AAC1D,YAAM,QAAQ,GAAG,QAAQ,MAAM,SAAS,IAAI;AAC5C,WAAK,SAAS,IAAI,UAAU,KAAK;AAGjC,oBAAc,UAAU,KAAK,MAAM;AAEnC,WAAK,OAAO,iBAAiB,QAAQ,MAAM;AACzC,gBAAQ,IAAI,iBAAiB;AAC7B,aAAK,YAAY;AACjB,aAAK,oBAAoB;AACzB,4BAAoB,OAAO,WAAW;AAGtC,aAAK,OAAO,KAAK,KAAK,UAAU,EAAE,MAAM,YAAY,CAAC,CAAC;AAGtD,YAAI,KAAK,eAAe;AACtB,kBAAQ,IAAI,oDAAoD;AAChE,qBAAW,MAAM,SAAS,OAAO,GAAG,GAAG;AACvC;AAAA,QACF;AAAA,MACF,CAAC;AAED,WAAK,OAAO,iBAAiB,SAAS,MAAM;AAC1C,aAAK,YAAY;AACjB,aAAK,gBAAgB;AACrB,4BAAoB,OAAO,cAAc;AACzC,sBAAc,UAAU,IAAI;AAC5B,aAAK,kBAAkB;AAAA,MACzB,CAAC;AAED,WAAK,OAAO,iBAAiB,SAAS,CAAC,UAAU;AAC/C,gBAAQ,KAAK,0BAA0B,KAAK;AAC5C,4BAAoB,OAAO,OAAO;AAClC,YAAI;AACF,eAAK,OAAO,MAAM;AAAA,QACpB,QAAQ;AAAA,QAER;AAAA,MACF,CAAC;AAED,WAAK,OAAO,iBAAiB,WAAW,CAAC,UAAU;AACjD,aAAK,cAAc,KAAK;AAAA,MAC1B,CAAC;AAAA,IACH,SAAS,OAAO;AACd,cAAQ,KAAK,4BAA4B,KAAK;AAC9C,WAAK,kBAAkB;AAAA,IACzB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,oBAAoB;AAClB,QAAI,KAAK,qBAAqB,KAAK,sBAAsB;AACvD,cAAQ,KAAK,yCAAyC;AACtD,0BAAoB,OAAO,cAAc;AACzC;AAAA,IACF;AAEA,wBAAoB,OAAO,cAAc;AAGzC,UAAM,QAAQ,KAAK;AAAA,MACjB,KAAK,iBAAiB,KAAK,IAAI,GAAG,KAAK,iBAAiB,IAAI,KAAK,OAAO,IAAI;AAAA,MAC5E;AAAA,IACF;AACA,SAAK;AAEL,YAAQ,IAAI,yBAAyB,KAAK,MAAM,KAAK,CAAC,eAAe,KAAK,iBAAiB,IAAI,KAAK,oBAAoB,GAAG;AAE3H,SAAK,mBAAmB,WAAW,MAAM;AACvC,WAAK,mBAAmB;AACxB,WAAK,QAAQ;AAAA,IACf,GAAG,KAAK;AAAA,EACV;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,cAAc,OAAO;AACnB,QAAI;AACJ,QAAI;AACF,aAAO,KAAK,MAAM,MAAM,IAAI;AAAA,IAC9B,QAAQ;AACN;AAAA,IACF;AAEA,YAAQ,IAAI,iBAAiB,KAAK,MAAM,KAAK,YAAY,KAAK,WAAW,EAAE;AAE3E,YAAQ,KAAK,MAAM;AAAA,MACjB,KAAK;AAEH;AAAA,MAEF,KAAK;AAAA,MACL,KAAK;AACH,gBAAQ,KAAK,oCAAoC;AACjD,iBAAS,OAAO;AAChB;AAAA,MAEF,KAAK;AAAA,MACL,KAAK;AACH,aAAK,aAAa,IAAI;AACtB;AAAA,MAEF,KAAK;AACH,aAAK,UAAU,KAAK,SAAS,IAAI;AACjC;AAAA,MAEF,KAAK;AAEH;AAAA,MAEF;AAEE;AAAA,IACJ;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAkBA,MAAM,aAAa,MAAM;AACvB,UAAM,WAAW,KAAK,WAAW,KAAK,YAAY;AAClD,UAAM,WAAW;AAEjB,QAAI;AAEF,oBAAc,WAAW;AAGzB,UAAI,cAAc,UAAU,QAAQ,GAAG;AACrC,sBAAc,eAAe,QAAQ;AAAA,MACvC;AAGA,UAAI,eAAe,aAAa,QAAQ,GAAG;AACzC,uBAAe,cAAc,QAAQ;AACrC,uBAAe,QAAQ,QAAQ;AAAA,MACjC;AAGA,YAAM,aAAa,SAAS,WAAW,GAAG,IAAI,WAAW,IAAI,QAAQ;AACrE,YAAM,YAAY,MAAM,OAAO,GAAG,UAAU,MAAM,KAAK,IAAI,CAAC;AAG5D,YAAM,WAAW,cAAc,aAAa,QAAQ;AACpD,UAAI,UAAU;AACZ,sBAAc,cAAc,UAAU,SAAS;AAAA,MACjD,OAAO;AAEL,cAAM,KAAK,gBAAgB;AAAA,MAC7B;AAGA,oBAAc,WAAW;AAGzB,mBAAa,KAAK;AAGlB,cAAQ,IAAI,kBAAkB,KAAK,cAAc,QAAQ,IAAI,QAAQ,EAAE;AAAA,IACzE,SAAS,OAAO;AACd,WAAK,kBAAkB,OAAO,QAAQ;AAAA,IACxC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,kBAAkB;AACtB,QAAI;AAEF,YAAM,EAAE,YAAY,IAAI,MAAM,OAAO,iBAAiB;AAGtD,UAAI,OAAO,WAAW,eAAe,OAAO,mBAAmB;AAC7D,oBAAY,OAAO,iBAAiB;AAAA,MACtC,OAAO;AACL,oBAAY;AAAA,MACd;AAAA,IACF,QAAQ;AAEN,cAAQ,KAAK,oEAAoE;AAAA,IACnF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,kBAAkB,OAAO,UAAU;AACjC,YAAQ,MAAM,wBAAwB,KAAK;AAG3C,UAAMC,YAAW,mBAAmB,KAAK;AAGzC,UAAM,eAAe;AAAA,MACnB,SAAS,MAAM,WAAW;AAAA,MAC1B,MAAMA,UAAS,QAAQ;AAAA,MACvB,MAAMA,UAAS;AAAA,MACf,QAAQA,UAAS;AAAA,MACjB,OAAO,MAAM;AAAA,IACf;AAEA,SAAK,UAAU,YAAY;AAAA,EAC7B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,UAAU,OAAO;AACf,iBAAa,KAAK,KAAK;AAAA,EACzB;AAAA;AAAA;AAAA;AAAA,EAKA,YAAY;AACV,iBAAa,KAAK;AAAA,EACpB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,aAAa;AACX,QAAI,OAAO,WAAW,aAAa;AACjC;AAAA,IACF;AAGA,QAAI,OAAO,8BAA8B,KAAK,aAAa;AACzD;AAAA,IACF;AAEA,WAAO,6BAA6B;AACpC,SAAK,cAAc;AAEnB,SAAK,QAAQ;AAAA,EACf;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,aAAa;AACX,QAAI,KAAK,qBAAqB,MAAM;AAClC,mBAAa,KAAK,gBAAgB;AAClC,WAAK,mBAAmB;AAAA,IAC1B;AAEA,QAAI,KAAK,QAAQ;AACf,UAAI;AACF,aAAK,OAAO,MAAM;AAAA,MACpB,QAAQ;AAAA,MAER;AACA,WAAK,SAAS;AAAA,IAChB;AAEA,SAAK,YAAY;AACjB,kBAAc,UAAU,IAAI;AAC5B,wBAAoB,QAAQ;AAAA,EAC9B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,cAAc;AACZ,WAAO,KAAK;AAAA,EACd;AACF;AAMO,IAAM,YAAY,IAAI,UAAU;",
|
|
6
|
+
"names": ["options", "getVNodeChildren", "getSignificantDOMChildren", "location"]
|
|
7
7
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@coherent.js/client",
|
|
3
|
-
"version": "1.0.0-
|
|
3
|
+
"version": "1.0.0-rc.1",
|
|
4
4
|
"description": "Client-side hydration/HMR utilities for Coherent.js",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/index.js",
|
|
@@ -11,10 +11,6 @@
|
|
|
11
11
|
"development": "./src/index.js",
|
|
12
12
|
"import": "./dist/index.js"
|
|
13
13
|
},
|
|
14
|
-
"./hydration": {
|
|
15
|
-
"types": "./types/hydration.d.ts",
|
|
16
|
-
"default": "./src/hydration.js"
|
|
17
|
-
},
|
|
18
14
|
"./events": {
|
|
19
15
|
"types": "./types/events.d.ts",
|
|
20
16
|
"default": "./src/events/index.js"
|
|
@@ -36,7 +32,7 @@
|
|
|
36
32
|
"LICENSE"
|
|
37
33
|
],
|
|
38
34
|
"engines": {
|
|
39
|
-
"node": ">=
|
|
35
|
+
"node": ">=22.0.0"
|
|
40
36
|
},
|
|
41
37
|
"license": "MIT",
|
|
42
38
|
"repository": {
|
package/src/index.js
CHANGED
|
@@ -33,16 +33,7 @@ export {
|
|
|
33
33
|
formatPath,
|
|
34
34
|
} from './hydration/index.js';
|
|
35
35
|
|
|
36
|
-
//
|
|
37
|
-
export {
|
|
38
|
-
hydrate as legacyHydrate,
|
|
39
|
-
hydrateAll,
|
|
40
|
-
hydrateBySelector,
|
|
41
|
-
enableClientEvents,
|
|
42
|
-
makeHydratable,
|
|
43
|
-
autoHydrate,
|
|
44
|
-
registerEventHandler,
|
|
45
|
-
} from './hydration.js';
|
|
36
|
+
// 1.0: removed legacy hydration re-exports — see docs/migration/1.0#removed-legacy-hydration
|
|
46
37
|
|
|
47
38
|
// HMR client (Phase 4)
|
|
48
39
|
export {
|