{"version":3,"file":"nuclo.mjs","names":["globalScope","RESERVED_LIFECYCLE_ATTRIBUTES","fallbackEventListeners","nativeEventHandlers","eventAttributeToProperty","attribute","firstEventCharacter","setEventAttribute","property","element","listener","handlers","i","type","list","previous","removeEventAttributes","target","listeners","logError","message","error","isBrowser","SERIALIZING_KEY","globalScope$1","shared","isSerializing","serializingScratch","all","pending","membersByRoot","hasRoots","reindex","EMPTY","track","kind","ref","membersOf","root","NO_ROOTS","rootsMemo","unmemoized","rootsAtOrAbove","node","start","roots","n","idsByRoot","indexMember","members","set","sweepAt","MIN_SWEEP","sweepCollected","indexPending","k","queue","scopeRootsById","scopeRootFinalizer","id","normalizeScopeIds","normalized","seen","raw","ids","addScopeRoot","el","getScopeRoots","scopeIds","a","scope","parent","reactiveTextNodes","reactiveTextNodesByNode","reactiveElements","reactiveElementsByNode","registerReactiveTextNode","existing","resolver","lastValue","registerReactiveElement","entry","cleanupReactiveTextNode","cleanupReactiveElement","cleanupNodeTree","removeAllListeners","disposeElementLifecycle","hasActiveLifecycleRegistrations","child","children","safeRemoveChild","safeInsertBefore","newNode","referenceNode","createMarker","text","createMarkerPair","prefix","clearBetweenMarkers","current","startMarker","endMarker","next","insertNodesBefore","nodes","withScopedInsertion","host","originalAppend","originalInsert","callback","_hydrating","_force","_cursors","isHydrating","isForceHydrating","startHydration","force","endHydration","runWithoutHydration","wasHydrating","fn","peekChild","setCursor","runFreshAtCursor","at","build","isWhitespaceText","skipWhitespaceText","advanced","drop","claimChild","claimBareText","sibling","claimMarkerPair","startPrefix","endText","depth","end","claimElement","candidate","name","tagName","cleanupUnclaimedChildren","lastOriginalChild","records","activeCount","mountQueue","shouldSkip","ensureRecord","record","pushSlot","slot","cb","registerMount","registerDestroy","setNodeDisposer","dispose","runMount","cleanup","runDestroy","fireMount","mount","flushMountQueue","batch","mountQueueMark","cancelMountsSince","mark","wasMounted","destroy","isMounted","FACTORY_TAG","FACTORY_MODS","EVENT_MODIFIER","metadataOnlyFactoryDepth","metadataOnlyStubPool","metadataOnlyPoolIndex","acquireMetadataOnlyFactory","setFactoryMeta","tag","mods","getFactoryMods","getFactoryTag","markEventModifier","isEventModifier","isMetadataOnlyFactoryMode","withMetadataOnlyFactories","item","index","getMetadataOnlyFactoryCheckpoint","releaseMetadataOnlyFactories","checkpoint","factory","elementListeners","trackListener","tracked","info","detachListener","noopEventModifier","createLifecycleModifier","createTrackedListener","currentTarget","event","on","options","isPrimitive","value","isNode","isObject","isFunction","isZeroArityFunction","toText","createReactiveTextNode","str","initial","txt","notifyReactiveTextNodes","notifyTextSet","NO_LEAVES","leafPos","leafCursor","restoreLeafCursor","pos","openLeaves","tmpl","putLeaf","last","setsAttribute","slots","key","analyzeFactory","mod","t","childMods","childTag","v","attrs","keys","specs","vt","eventProperty","events","subtreeEvents","leafCount","s","cleanupTemplateRow","props","prepareSkeleton","skeleton","spec","instantiateTemplate","attrCount","_k","resolved","leaves","textNode","adoptTemplateLeaves","flushRowLeaves","UNSET_LAST_VALUE","updateRecord","nextValue","cacheable","applied","registerAttributeResolver","resolvers","notifyReactiveElements","notifyElementSet","assignInlineStyles","style","styles","applyReactiveStyle","applyStyleAttribute","styleValue","staticClassNames","reactiveClassNameFlags","getClass","setClass","addClassTokens","len","className","joinClasses","result","cls","classes","initReactiveClassName","classSet","resetClassNameTracking","hasReactiveClassName","addStaticClasses","mergeReactiveClassName","staticClasses","reactiveClassName","token","mergeStaticClassName","newClassName","currentClassName","selectValues","setSelectValue","select","retrySelectValue","forgetSelectValue","setAttributeValue","merge","applyReactiveClassName","applySingleAttribute","shouldMergeClassName","applyAttributes","valueLast","attributes","mergeClassName","isClassNameOnlyObject","nextChildIsTextComment","claimTextAfterMarker","expected","created","applyNodeModifier","modifier","parentNode","claimed","wrapTextNode","emptyText","produced","fragment","activeWhenRuntimes","whenRuntimeByMarker","whenMarkerFinalizer","evaluateActiveCondition","groups","condition","elseContent","renderWhenContent","runtime","newActive","renderContentItems","registerWhenRuntime","getWhenRuntime","updateWhenRuntimes","updateWhenSet","renderContentItem","maybeNode","items","applyModifiers","localIndex","startIndex","hydrating","modifiers","resetReusedElement","createElementFactory","stub","svg","createHtmlTagBuilder","createSvgTagBuilder","emptyRegistry","page","runtimeByMarker","viewsByAnchor","SSR_KEY","registry","scratch","reg","markerFinalizer","waiting","forgetPending","claimingRegions","dropped","marker","dropRegion","rt","shown","view","detach","pendView","pruneRegions","anchor","placed","removeView","registerRegion","old","known","onMarkerDisposed","anchorRef","waitingView","addView","takeOrphans","orphans","regionOf","isViewAnchor","getRegion","liveRegionAt","unpend","attachViews","earlier","views","before","stamp","decodeCount","match","markerText","showIn","setRange","first","stop","showEmpty","placeView","e","h","reclaimView","claimAt","cursor","hostCursor","from","content","claimRange","boundary","leftover","boundaryAfter","claimEmpty","reclaimEmpty","underneath","sweepRegions","arraysEqual","b","activeListRuntimes","listRuntimeByMarker","listMarkerFinalizer","updateListFlushEpoch","registerListRuntime","normalizeItems","toRowElement","rebuildRowNormally","renderItem","renderItemWithTemplate","template","canUseTemplate","outer","adopted","clone","cleanupRow","shape","removeRow","bulkClearRecords","longestIncreasingSubsequence","arr","predecessor","tails","x","lo","hi","mid","idx","buildAndInsert","endIndexExclusive","dyn","targetRecords","selectOwning","sync","selectedValue","diffRows","fallback","oldRecords","oldLen","newLen","maxTrim","suffix","maxSuffix","oldStart","oldEnd","newStart","newEnd","fresh","oldWinLen","newWinLen","sources","reusedCount","pinEnd","pinnedCount","buckets","j","oldIndex","stable","pinnedOnly","survivorOldIndices","survivorPositions","lis","windowRecords","nullCount","src","firstFlushed","merged","w","newRuntime","createListRuntime","hydrateListRuntime","itemsProvider","createListRuntimeNormal","pair","renderFn","currentItems","recordNode","updateListRuntimes","updateListSet","encodeBranch","activeIndex","decodeBranch","WhenBuilderImpl","additionalGroup","newElseContent","serverBranch","contentToRender","createWhenBuilderFunction","builder","when","updaters","update","render","makeRuntime","empty","freshRegion","hydrateRegion","live","region","claimAnchor","into","targets","idOrRegions","forcedComponents","forcedRoots","forcedRootFinalizer","unwrapComponent","built","registerForcedRoot","component","nodeModFn","targetParent","hydrate","hydrateRoot","forceUpdate","write","read","parentEl","elementNode","stale","after","createState","ENGINE_STATE_KEY","globalScope","cachedState","getState","registerQueries","query","queries","state","createGroup","group","groupQueryOf","groupQueries","cached","rule","brace","ruleIdentity","rememberExternalRule","contextKeyOf","texts","consumeExternalRule","indexExternalRules","rules","prelude","insertBase","inserted","insertGrouped","getOrCreateGroup","direct","ensureSheet","r","bucket","hash","input","c","appendKeyPart","expandAmpersands","expanded","quote","code","replacement","selectorFor","selector","isValidClassName","second","atomBlock","contextKey","prop","decls","declKey","exactName","body","mergeBlocks","concat","lastIndex","decl","conflictKeyOf","meta","getStyleEpoch","addRawRule","dedupeKey","getCssText","out","resetStyles","camelToKebab","firstUpper","PSEUDO","ALIAS","COMPOSITE","TOKEN_PROP","UNITLESS","kebabCache","kebab","toQuery","screen","isBareCondition","leadsWithNot","combineQuery","inner","outerCondition","innerCondition","mergeStyle","source","StyleResultImpl","makeResult","pickClass","picked","prev","collectClassString","collectClasses","inputs","composeClassName","cxPairMemo","isPlainCxObject","cx","only","epoch","hit","BASE_CONTEXT","createCss","screens","theme","memo","toCssValue","bucketFor","walk","raws","pseudo","composite","css","named","nameOrStyle","maybeStyle","isBase","flatDecls","keyframes","frames","globalStyle","variants","normalize","config","groupNames","defaults","baseStyle","compounds","compoundStyle","conditions","cache","cacheEpoch","selection","chosen","compound","matches","defaultInstance","getDefaultInstance","HTML_TAGS","SVG_TAGS","defineLazyGlobal","create","registerHtmlTag","registerSvgTag","exportName","registerGlobalTagBuilders","initializeRuntime"],"sources":["../src/element/event-attributes.ts","../src/shared/errors.ts","../src/shared/environment.ts","../src/shared/serializing.ts","../src/update/scope.ts","../src/update/registry.ts","../src/shared/dom.ts","../src/hydration.ts","../src/element/lifecycle.ts","../src/element/factory-meta.ts","../src/element/events.ts","../src/shared/type-guards.ts","../src/update/reactive-text.ts","../src/list/template.ts","../src/update/reactive-attributes.ts","../src/element/inline-style.ts","../src/element/class-name.ts","../src/element/attributes.ts","../src/element/modifiers.ts","../src/when/runtime.ts","../src/element/factory.ts","../src/region/runtime.ts","../src/list/runtime.ts","../src/when/builder.ts","../src/when/index.ts","../src/update/update.ts","../src/list/index.ts","../src/region/index.ts","../src/render.ts","../src/style/engine.ts","../src/shared/strings.ts","../src/style/css.ts","../src/element/tags.ts","../src/bootstrap.ts"],"sourcesContent":["const ON_DOUBLE_CLICK = \"onDoubleClick\";\n\n/**\n * `onMount`/`onDestroy` look like `on*` event attributes but aren't real DOM\n * events — there is no native `onmount`/`ondestroy` IDL property for\n * `\"onmount\" in element` to find, so without this exclusion they'd fall into\n * the generic addEventListener fallback below and silently never fire (the\n * browser never dispatches a \"mount\"/\"destroy\" event). attributes.ts special-\n * cases these two keys before ever calling this function; the exclusion here\n * is what makes list/template.ts's row-template analysis correctly bail its\n * skeleton-clone fast path for rows using them too (see element/lifecycle.ts).\n */\nconst RESERVED_LIFECYCLE_ATTRIBUTES = new Set([\"onMount\", \"onDestroy\"]);\n\n/**\n * Flat [name, listener, name, listener, ...] pairs. A Map per element made\n * every event-carrying list row pay a Map allocation (and its retained size);\n * elements almost always carry one or two handlers, so a linear scan over a\n * tiny array wins on both.\n */\ntype EventListenerPairs = Array<string | EventListener>;\n\nconst fallbackEventListeners = new WeakMap<EventTarget, EventListenerPairs>();\nconst nativeEventHandlers = new WeakMap<HTMLElement, EventListenerPairs>();\n\n/** Converts a public camel-cased event attribute to its native IDL property. */\nexport function eventAttributeToProperty(attribute: string): string | null {\n  if (\n    attribute.length <= 2\n    || attribute.charCodeAt(0) !== 111 /* o */\n    || attribute.charCodeAt(1) !== 110 /* n */\n  ) {\n    return null;\n  }\n\n  const firstEventCharacter = attribute.charCodeAt(2);\n  if (firstEventCharacter < 65 /* A */ || firstEventCharacter > 90 /* Z */) {\n    return null;\n  }\n\n  if (RESERVED_LIFECYCLE_ATTRIBUTES.has(attribute)) return null;\n  if (attribute === ON_DOUBLE_CLICK) return \"ondblclick\";\n  return attribute.toLowerCase();\n}\n\n/** Assigns an event attribute, falling back when the IDL property is absent. */\nexport function setEventAttribute(\n  element: HTMLElement,\n  property: string,\n  listener: EventListener,\n) {\n  if (property in element) {\n    (element as unknown as Record<string, unknown>)[property] = listener;\n    const handlers = nativeEventHandlers.get(element);\n    if (!handlers) {\n      nativeEventHandlers.set(element, [property, listener]);\n      return;\n    }\n    for (let i = 0; i < handlers.length; i += 2) {\n      if (handlers[i] === property) {\n        handlers[i + 1] = listener;\n        return;\n      }\n    }\n    handlers.push(property, listener);\n    return;\n  }\n\n  const type = property.slice(2);\n  const list = fallbackEventListeners.get(element);\n  if (list) {\n    for (let i = 0; i < list.length; i += 2) {\n      if (list[i] !== type) continue;\n\n      const previous = list[i + 1] as EventListener;\n      if (previous === listener) return;\n      element.removeEventListener(type, previous);\n      element.addEventListener(type, listener);\n      list[i + 1] = listener;\n      return;\n    }\n\n    element.addEventListener(type, listener);\n    list.push(type, listener);\n    return;\n  }\n\n  element.addEventListener(type, listener);\n  fallbackEventListeners.set(element, [type, listener]);\n}\n\n/** Releases only handlers installed through nuclo's event attributes. */\nexport function removeEventAttributes(element: HTMLElement) {\n  const handlers = nativeEventHandlers.get(element);\n  if (handlers) {\n    const target = element as unknown as Record<string, unknown>;\n    for (let i = 0; i < handlers.length; i += 2) {\n      const property = handlers[i] as string;\n      // Leave a handler that external code replaced after our assignment alone.\n      if (target[property] === handlers[i + 1]) target[property] = null;\n    }\n    nativeEventHandlers.delete(element);\n  }\n  const listeners = fallbackEventListeners.get(element);\n  if (listeners) {\n    for (let i = 0; i < listeners.length; i += 2) {\n      element.removeEventListener(listeners[i] as string, listeners[i + 1] as EventListener);\n    }\n    fallbackEventListeners.delete(element);\n  }\n}\n","export function logError(message: string, error?: Error | unknown) {\n  if (typeof console !== 'undefined') {\n    console.error(`nuclo: ${message}`, error);\n  }\n}","/**\n * Simplified environment detection - minimal overhead for smaller bundle size\n */\n\n// Basic environment detection - no complex caching or edge cases\nexport const isBrowser = typeof window !== 'undefined' && typeof document !== 'undefined';\n","/**\n * \"A tree is being built for renderToString()\" flag.\n *\n * True while renderToString() runs. Text children must keep their\n * `<!-- text-N -->` markers in this mode so the emitted HTML stays hydratable\n * — even when `isBrowser` is true (SSR under jsdom/happy-dom globals, or an\n * isomorphic worker that provides a DOM) — and nothing built for a throwaway\n * server tree may register itself anywhere (lifecycle hooks, reactive nodes,\n * list/when runtimes, scope roots). A pure client render leaves this false.\n *\n * Kept on globalThis under a Symbol.for key (like style/engine.ts's registry)\n * rather than in a module-level `let`: `nuclo` and `nuclo/ssr` ship as\n * separate bundles, each with its own module scope. renderToString() (in\n * nuclo/ssr) sets the flag and the tag builders (in nuclo) read it — as a\n * module variable those would be two unrelated booleans.\n */\nconst SERIALIZING_KEY = Symbol.for(\"nuclo.serializing.v1\");\ninterface SerializingState { on: boolean; scratch: Map<string, unknown> }\nconst globalScope = globalThis as unknown as Record<symbol, SerializingState | undefined>;\nconst shared = globalScope[SERIALIZING_KEY]\n  ?? (globalScope[SERIALIZING_KEY] = { on: false, scratch: new Map<string, unknown>() });\n\nexport function isSerializing() {\n  return shared.on;\n}\n\n/**\n * Scratch space for the current renderToString() call, emptied when that call\n * ends.\n *\n * A server renders every request from one process, so any registry a feature\n * keeps in module scope is shared by every request and every user at once.\n * Anything a server tree needs to look up mid-build goes here instead: it is\n * reachable for exactly as long as the tree is being built, and nothing from\n * one request is reachable from the next. Keys are namespaced by the feature\n * that owns them.\n */\nexport function serializingScratch(): Map<string, unknown> {\n  return shared.scratch;\n}\n\n/**\n * Runs `fn` with serialization mode enabled, restoring the previous state\n * afterwards (so nested/re-entrant renderToString calls behave correctly).\n */\nexport function runSerializing<T>(fn: () => T): T {\n  const previous = shared.on;\n  shared.on = true;\n  try {\n    return fn();\n  } finally {\n    shared.on = previous;\n    // Only the outermost call clears: a nested renderToString() is still part\n    // of the same request and the tree around it is still being built.\n    if (!shared.on) shared.scratch.clear();\n  }\n}\n","/**\n * scope() – tags an element as the root of a named update scope so\n * `update(\"name\")` can refresh just that part of the page.\n *\n * ── Membership index ─────────────────────────────────────────────────────\n * update(\"id\") must not visit every reactive node on the page and ask\n * `root.contains(node)`: with N scoped components each refreshing itself\n * per frame that is O(N²) per frame. Instead every registry (list markers,\n * when markers, reactive elements, reactive text nodes) is a *kind* here:\n * the global iteration set of each kind lives in `all`, and every member\n * also goes through `pending`. The next update() drains `pending`, walking\n * each new node's ancestors once and adding it to the member set of every\n * scope root above it — nested roots included, so update(\"outer\") reaches\n * what update(\"inner\") does. A scoped update then iterates only the member\n * sets of its roots.\n *\n * Membership is computed from the DOM when the node is first seen by an\n * update(), not at registration: nuclo builds subtrees detached and attaches\n * them in one shot, so at registration time a node's ancestors are not in\n * place yet. A node still detached at that point is left out — the passes\n * prune disconnected nodes from the registries anyway.\n *\n * Member sets hold the registries' own WeakRefs, so they pin nothing: a\n * collected member is swept amortized O(1) on insert, and the passes drop\n * disconnected members as they go.\n */\nimport { isBrowser } from \"../shared/environment\";\nimport { isSerializing } from \"../shared/serializing\";\n\n/** The roots update(...ids) resolved; the passes iterate their members. */\nexport interface UpdateScope {\n  roots: readonly Element[];\n}\n\n/** Member kinds, in the order update() runs them. */\nexport const LIST_KIND = 0;\nexport const WHEN_KIND = 1;\nexport const ELEMENT_KIND = 2;\nexport const TEXT_KIND = 3;\nconst KINDS = 4;\n\ntype Members = Set<WeakRef<Node>>[];\n\n/** Global iteration set per kind — the registries' sets. */\nexport const all: Members = [new Set(), new Set(), new Set(), new Set()];\n/** Members registered since the last update(), per kind, not yet indexed. */\nconst pending: WeakRef<Node>[][] = [[], [], [], []];\nlet membersByRoot = new WeakMap<Element, Members>();\n/** No scope() ever ran: pending is dropped instead of indexed. */\nlet hasRoots = false;\n/** A scope() ran on an element already in the document, whose descendants may already be indexed. */\nlet reindex = false;\n\nconst EMPTY: Set<WeakRef<Node>> = new Set();\n\n/** Registers a member: in its kind's global set now, indexed by the next update(). */\nexport function track(kind: number, ref: WeakRef<Node>) {\n  all[kind].add(ref);\n  pending[kind].push(ref);\n}\n\n/** The members of `kind` under `root` (empty if none were indexed). */\nexport function membersOf(root: Element, kind: number): Set<WeakRef<Node>> {\n  return membersByRoot.get(root)?.[kind] ?? EMPTY;\n}\n\nconst NO_ROOTS: readonly Element[] = [];\n/**\n * Scope roots at or above each node, memoized for one indexPending() call:\n * the members of a list row share every ancestor above the row, so after the\n * first one the others stop at their parent. The DOM does not change during\n * a drain, so the memo is never stale.\n */\nlet rootsMemo: Map<Node, readonly Element[]> | null = null;\nconst unmemoized: Node[] = [];\n\nfunction rootsAtOrAbove(start: Node): readonly Element[] {\n  let node: Node | null = start;\n  let roots: readonly Element[] | undefined;\n  while (node && (roots = rootsMemo!.get(node)) === undefined) {\n    unmemoized.push(node);\n    node = node.parentNode;\n  }\n  if (roots === undefined) roots = NO_ROOTS;\n  for (let i = unmemoized.length - 1; i >= 0; i--) {\n    const n = unmemoized[i];\n    if (n.nodeType === 1 && idsByRoot.has(n as Element)) roots = [n as Element, ...roots];\n    rootsMemo!.set(n, roots);\n  }\n  unmemoized.length = 0;\n  return roots;\n}\n\nfunction indexMember(kind: number, ref: WeakRef<Node>) {\n  const node = ref.deref();\n  if (!node || !node.isConnected) return;\n  // A text node or marker is never a root: start from its parent.\n  const roots = rootsAtOrAbove(node.nodeType === 1 ? node : node.parentNode!);\n  for (let i = 0; i < roots.length; i++) {\n    const root = roots[i];\n    let members = membersByRoot.get(root);\n    if (!members) membersByRoot.set(root, members = [new Set(), new Set(), new Set(), new Set()]);\n    const set = members[kind];\n    set.add(ref);\n    if (set.size >= (sweepAt.get(set) ?? MIN_SWEEP)) sweepCollected(set);\n  }\n}\n\n/** Indexes everything registered since the last update(). Called by update() before its passes. */\nexport function indexPending() {\n  if (reindex) {\n    reindex = false;\n    membersByRoot = new WeakMap();\n    rootsMemo = new Map();\n    for (let k = 0; k < KINDS; k++) {\n      pending[k].length = 0;\n      for (const ref of all[k]) indexMember(k, ref);\n    }\n    rootsMemo = null;\n    return;\n  }\n  for (let k = 0; k < KINDS; k++) {\n    const queue = pending[k];\n    if (queue.length === 0) continue;\n    if (hasRoots) {\n      rootsMemo ??= new Map();\n      for (let i = 0; i < queue.length; i++) indexMember(k, queue[i]);\n    }\n    queue.length = 0;\n  }\n  rootsMemo = null;\n}\n\ntype ScopeId = string;\n\n/**\n * Stores weak references to scope root elements.\n * Using WeakRef prevents memory leaks - elements can be garbage collected when removed from DOM.\n */\nexport const scopeRootsById = new Map<ScopeId, Set<WeakRef<Element>>>();\n\n/**\n * Drops a collected root's entry — and its id, once no root is left under it.\n * Without this, per-row ids (scope(`row-${id}`)) that are never passed to\n * update() again would stay in the map forever: one id, one Set and one dead\n * WeakRef per row the app ever rendered. The sweeps below only bound a single\n * id's set, not the number of ids.\n */\nconst scopeRootFinalizer = typeof FinalizationRegistry !== \"undefined\"\n  ? new FinalizationRegistry<{ id: ScopeId; ref: WeakRef<Element> }>(({ id, ref }) => {\n      const set = scopeRootsById.get(id);\n      if (set?.delete(ref) && set.size === 0) scopeRootsById.delete(id);\n    })\n  : null;\n\nfunction normalizeScopeIds(ids: readonly string[]): ScopeId[] {\n  const normalized: ScopeId[] = [];\n  const seen = new Set<ScopeId>();\n\n  for (const raw of ids) {\n    if (typeof raw !== \"string\") continue;\n    const id = raw.trim();\n    if (!id) continue;\n    if (seen.has(id)) continue;\n    seen.add(id);\n    normalized.push(id);\n  }\n\n  return normalized;\n}\n\n/** Ids each root is already registered under: O(1) dedup instead of a set scan. */\nconst idsByRoot = new WeakMap<Element, Set<ScopeId>>();\n/** Sweep a set of dead refs once it grows past this; doubles with the live size. */\nconst sweepAt = new WeakMap<Set<WeakRef<object>>, number>();\nconst MIN_SWEEP = 64;\n\n/** Drops collected refs at amortized O(1) per add. Detached ones are kept. */\nfunction sweepCollected(set: Set<WeakRef<object>>) {\n  for (const ref of set) if (ref.deref() === undefined) set.delete(ref);\n  sweepAt.set(set, Math.max(MIN_SWEEP, set.size * 2));\n}\n\nfunction addScopeRoot(id: ScopeId, el: Element) {\n  let ids = idsByRoot.get(el);\n  if (!ids) idsByRoot.set(el, ids = new Set());\n  // Re-registration (forceUpdate() reclaim) must not grow the set.\n  if (ids.has(id)) return;\n  ids.add(id);\n  hasRoots = true;\n  // A root that is already in the document (hydration, or scope() applied by\n  // hand) may have descendants the index already filed elsewhere.\n  if (el.isConnected) reindex = true;\n\n  let set = scopeRootsById.get(id);\n  if (!set) scopeRootsById.set(id, set = new Set());\n  const ref = new WeakRef(el);\n  set.add(ref);\n  scopeRootFinalizer?.register(el, { id, ref });\n\n  // Ids that are never passed to update(id) are never pruned by getScopeRoots(),\n  // so list rows scoped with scope(\"row\") would grow the set forever. Detached\n  // roots are kept: they are legitimately unattached while their tree is still\n  // being built.\n  if (set.size >= (sweepAt.get(set) ?? MIN_SWEEP)) sweepCollected(set);\n}\n\nexport function getScopeRoots(ids: readonly string[]): Element[] {\n  const scopeIds = normalizeScopeIds(ids);\n  if (scopeIds.length === 0) return [];\n\n  const roots = new Set<Element>();\n\n  for (const id of scopeIds) {\n    const set = scopeRootsById.get(id);\n    if (!set) continue;\n\n    for (const ref of set) {\n      const el = ref.deref();\n      // Collected or disconnected: drop it (deleting while iterating a Set is safe).\n      if (el === undefined) set.delete(ref);\n      else if (!el.isConnected) {\n        set.delete(ref);\n        idsByRoot.get(el)?.delete(id); // let scope() re-register it if it comes back\n      } else roots.add(el);\n    }\n\n    if (set.size === 0) scopeRootsById.delete(id);\n  }\n\n  // A root inside another root in the set is covered by it: its members are\n  // a subset of the outer root's, so visiting both would run them twice.\n  if (roots.size > 1) {\n    for (const root of roots) {\n      for (let a = root.parentNode; a; a = a.parentNode) {\n        if (roots.has(a as Element)) { roots.delete(root); break; }\n      }\n    }\n  }\n\n  return Array.from(roots);\n}\n\nexport function scope<TTagName extends ElementTagName = ElementTagName>(\n  ...ids: string[]\n): NodeModFn<TTagName> {\n  const scopeIds = normalizeScopeIds(ids);\n\n  return function(parent: ExpandedElement<TTagName>) {\n    if (!isBrowser || isSerializing()) return;\n    if (!(parent instanceof Element)) return;\n    for (const id of scopeIds) addScopeRoot(id, parent);\n  };\n}\n","/**\n * Shared types and registries for reactive nodes.\n * Single source of truth — imported by reactive-text.ts and reactive-attributes.ts.\n *\n * Registry structure: the iteration sets only hold WeakRefs; the entries live\n * in WeakMaps keyed by the node, one flat object per node (its WeakRef plus\n * its reactive state). Storing entries in a strongly-held map would pin the\n * node in memory forever; with WeakMap storage the whole entry is collectible\n * as soon as the node is unreachable.\n *\n * Dead WeakRefs left in the iteration sets are pruned by the notify passes as\n * they iterate (deref() === undefined, or node disconnected). Registration is\n * the hottest path in list-heavy renders (one text node + often one element\n * per row), so no per-node FinalizationRegistry is used here: its register()\n * cost per row outweighs keeping the sets tidy between updates, and a stale\n * husk is just an empty WeakRef until the next update() sweeps it.\n */\n\nimport { all, track, ELEMENT_KIND, TEXT_KIND } from \"./scope\";\n\nexport type TextResolver = () => unknown;\n\n/**\n * A reactive text node. Resolver results render with the DSL's text\n * semantics: nullish and non-primitive values render as \"\".\n */\nexport interface ReactiveTextEntry {\n  ref: WeakRef<Text>;\n  resolver: TextResolver;\n  lastValue: string;\n}\n\nexport type AttributeResolver = () => unknown;\n\n/**\n * Writes a resolved value to the element. A shared module-level function\n * (not a per-registration closure), so a reactive attribute costs no closure.\n * Returning `false` reports that the write did not take (a <select> value\n * whose <option> does not exist yet): the value is then not cached, so the\n * next update() applies it again.\n */\nexport type AttributeApplier = (element: Element, key: string, value: unknown) => boolean | void;\n\nexport interface AttributeResolverRecord {\n  key: string;\n  resolver: AttributeResolver;\n  apply: AttributeApplier;\n  lastValue: unknown;\n}\n\nexport interface ReactiveElementEntry {\n  ref: WeakRef<Element>;\n  /**\n   * Flat keyed array rather than a Map: elements almost always carry one or\n   * two reactive attributes, so linear key lookup on registration beats a Map\n   * allocation per element, and the per-update flush iterates with a plain\n   * index loop (no iterator/destructuring allocations).\n   */\n  attributeResolvers: AttributeResolverRecord[];\n}\n\n/** Iteration set of weak references to reactive text nodes (owned by the scope index). */\nexport const reactiveTextNodes = all[TEXT_KIND] as Set<WeakRef<Text>>;\n\n/** O(1) lookup of a reactive text node's entry. */\nexport const reactiveTextNodesByNode = new WeakMap<Text, ReactiveTextEntry>();\n\n/** Iteration set of weak references to reactive elements (owned by the scope index). */\nexport const reactiveElements = all[ELEMENT_KIND] as Set<WeakRef<Element>>;\n\n/** O(1) lookup of a reactive element's entry. */\nexport const reactiveElementsByNode = new WeakMap<Element, ReactiveElementEntry>();\n\n/**\n * Registers a reactive text node. Re-registration (e.g. repeated hydration)\n * replaces the resolver and last value in place.\n */\nexport function registerReactiveTextNode(node: Text, resolver: TextResolver, lastValue: string) {\n  const existing = reactiveTextNodesByNode.get(node);\n  if (existing) {\n    existing.resolver = resolver;\n    existing.lastValue = lastValue;\n    return;\n  }\n  const ref = new WeakRef(node);\n  track(TEXT_KIND, ref);\n  reactiveTextNodesByNode.set(node, { ref, resolver, lastValue });\n}\n\n/** Returns the element's reactive entry, creating and registering it on first use. */\nexport function registerReactiveElement(element: Element): ReactiveElementEntry {\n  let entry = reactiveElementsByNode.get(element);\n  if (!entry) {\n    const ref = new WeakRef(element);\n    entry = { ref, attributeResolvers: [] };\n    track(ELEMENT_KIND, ref);\n    reactiveElementsByNode.set(element, entry);\n  }\n  return entry;\n}\n\n/** Unregisters a reactive text node (called when nuclo removes it). */\nexport function cleanupReactiveTextNode(node: Text) {\n  const entry = reactiveTextNodesByNode.get(node);\n  if (entry) {\n    reactiveTextNodes.delete(entry.ref);\n    reactiveTextNodesByNode.delete(node);\n  }\n}\n\n/** Unregisters a reactive element (called when nuclo removes it). */\nexport function cleanupReactiveElement(element: Element) {\n  const entry = reactiveElementsByNode.get(element);\n  if (entry) {\n    reactiveElements.delete(entry.ref);\n    reactiveElementsByNode.delete(element);\n  }\n}\n","import { logError } from \"./errors\";\nimport { isBrowser } from \"./environment\";\nimport { removeAllListeners } from \"../element/events\";\nimport { cleanupReactiveTextNode, cleanupReactiveElement } from \"../update/registry\";\nimport { disposeElementLifecycle, hasActiveLifecycleRegistrations } from \"../element/lifecycle\";\n\nexport const SVG_NAMESPACE = 'http://www.w3.org/2000/svg';\n\n/**\n * Recursively removes all event listeners and reactive subscriptions from a node and its descendants\n * to prevent memory leaks when elements are removed from the DOM.\n */\nexport function cleanupNodeTree(node: Node) {\n  // Clean up the node itself based on its type. Order-independent bookkeeping\n  // (listeners, reactive registrations) runs up front; onDestroy is fired\n  // below, after descendants — see the comment there.\n  const type = node.nodeType;\n  if (type === 1 /* ELEMENT_NODE */) {\n    const element = node as HTMLElement;\n    removeAllListeners(element);\n    cleanupReactiveElement(element);\n  } else if (type === 3 /* TEXT_NODE */) {\n    cleanupReactiveTextNode(node as Text);\n    return;\n  } else if (type === 8) {\n    // A region's start marker or a view's anchor carries a disposer.\n    disposeElementLifecycle(node);\n    return;\n  }\n\n  // Recursively clean up all child nodes\n  // Destroy callbacks can mutate the tree: snapshot only when hooks exist. In\n  // a real DOM, ordinary cleanup walks siblings — reading `childNodes` makes\n  // the engine allocate and cache a live NodeList on every visited node, which\n  // dominated bulk list clears. The SSR polyfill keeps children in a plain\n  // array (its sibling getters are O(n)), so it iterates that directly.\n  if (isBrowser && !hasActiveLifecycleRegistrations()) {\n    for (let child = node.firstChild; child !== null; child = child.nextSibling) cleanupNodeTree(child);\n  } else {\n    const children = hasActiveLifecycleRegistrations() ? Array.from(node.childNodes) : node.childNodes;\n    for (let i = 0; i < children.length; i++) cleanupNodeTree(children[i]);\n  }\n\n  // Fire onDestroy last — after every descendant's onDestroy has already run\n  // (post-order) — so a parent's teardown can rely on its children having\n  // already released whatever they were using (e.g. a subscription or timer\n  // the parent owns and children only read from). This mirrors onMount's own\n  // order, which is naturally parent-before-child (registration order is\n  // construction order: a parent's own onMount/{onMount} modifier is applied\n  // before its child factories are even invoked) — so mount is top-down,\n  // destroy is bottom-up, the same LIFO discipline nested resource scopes\n  // always use. No-op unless this exact element registered a callback.\n  if (type === 1) {\n    disposeElementLifecycle(node as HTMLElement);\n  }\n}\n\nexport function safeRemoveChild(child: Node) {\n  if (!child?.parentNode) return false;\n  try {\n    // Clean up all event listeners before removing the element\n    cleanupNodeTree(child);\n    // A destroy callback may already have removed the node.\n    child.parentNode?.removeChild(child);\n    return true;\n  } catch (error) {\n    logError('Failed to remove child node', error);\n    return false;\n  }\n}\n\nfunction safeInsertBefore(parent: Node, newNode: Node, referenceNode: Node | null) {\n  try {\n    parent.insertBefore(newNode, referenceNode);\n    return true;\n  } catch (error) {\n    logError('Failed to insert node before reference', error);\n    return false;\n  }\n}\n\n/**\n * Creates one of nuclo's own marker comments (text / list / when). The extra\n * argument is ignored by a real DOM; the SSR polyfill records it so\n * renderToString() can emit markers without inspecting their text.\n */\nexport function createMarker(text: string): Comment {\n  return (document as unknown as { createComment(data: string, marker: boolean): Comment }).createComment(text, true);\n}\n\nexport function createMarkerPair(prefix: string, id: number): { start: Comment; end: Comment } {\n  return { start: createMarker(`${prefix}-start-${id}`), end: createMarker(`${prefix}-end`) };\n}\n\nexport function clearBetweenMarkers(startMarker: Comment, endMarker: Comment) {\n  let current = startMarker.nextSibling;\n  while (current && current !== endMarker) {\n    const next = current.nextSibling;\n    safeRemoveChild(current);\n    current = next;\n  }\n}\n\nexport function insertNodesBefore(nodes: Node[], referenceNode: Node) {\n  const parent = referenceNode.parentNode;\n  if (parent) {\n    for (let i = 0; i < nodes.length; i++) {\n      safeInsertBefore(parent, nodes[i], referenceNode);\n    }\n  }\n}\n\n/**\n * Creates a scoped DOM insertion context that temporarily redirects appendChild\n * to insertBefore at a specific reference node. This is useful for inserting\n * content at specific positions in the DOM tree.\n *\n * @param host - The host element\n * @param referenceNode - The node before which new nodes should be inserted\n * @param callback - Function to execute with the scoped context\n * @returns The result of the callback\n */\nexport function withScopedInsertion<T, THost extends Element | object>(\n  host: THost,\n  referenceNode: Node,\n  callback: () => T\n): T {\n  const parent = host as unknown as Node & ParentNode;\n  const originalAppend = Object.getOwnPropertyDescriptor(parent, \"appendChild\");\n  const originalInsert = parent.insertBefore;\n\n  // Temporarily override appendChild to insert before the reference node\n  // TypeScript doesn't like this override but it's safe at runtime\n  (parent as unknown as Record<string, unknown>).appendChild = function(node: Node): Node {\n    return originalInsert.call(parent, node, referenceNode);\n  };\n\n  try {\n    return callback();\n  } finally {\n    // Restore original method\n    if (originalAppend) Object.defineProperty(parent, \"appendChild\", originalAppend);\n    else Reflect.deleteProperty(parent, \"appendChild\");\n  }\n}\n","/**\n * Hydration context — tracks global hydration state and per-parent cursor positions.\n *\n * During hydration the component tree is built against an existing DOM tree\n * (produced by SSR).  Instead of creating new nodes, factories claim existing\n * children from their parent element by advancing a cursor.\n *\n * The cursor is a *node pointer* (the next unclaimed child), not an index.\n * Indexed childNodes access is O(n) after any tree/attribute mutation in\n * jsdom (live NodeList re-materialization) which made hydration O(n²);\n * firstChild/nextSibling pointers are O(1) in every DOM implementation.\n */\n\nimport { safeRemoveChild, withScopedInsertion } from \"./shared/dom\";\n\n// The serialization flag is realm-shared state (see shared/serializing.ts);\n// re-exported here for callers that already import hydration helpers.\nexport { isSerializing, runSerializing } from \"./shared/serializing\";\n\nlet _hydrating = false;\n// True while forceUpdate() re-hydrates a live, client-rendered tree: text\n// claims work without `<!-- text-N -->` markers and reused elements get their\n// previous listeners/class state reset before modifiers re-apply.\nlet _force = false;\n// Missing entry = cursor at parent.firstChild; null = past the last child.\nlet _cursors = new WeakMap<Node, Node | null>();\n\nexport function isHydrating() {\n  return _hydrating;\n}\n\n/** True only inside a forceUpdate() pass (never during plain hydrate()). */\nexport function isForceHydrating() {\n  return _hydrating && _force;\n}\n\nexport function startHydration(force = false) {\n  _hydrating = true;\n  _force = force;\n  // Each hydration pass starts with a clean cursor slate. Stale cursors from\n  // a previous pass would desynchronize claims when a container's content is\n  // replaced and re-hydrated (HMR, islands re-mounting).\n  _cursors = new WeakMap<Node, Node | null>();\n}\n\nexport function endHydration() {\n  _hydrating = false;\n  _force = false;\n  // Cursor values are strong node references (the next unclaimed sibling).\n  // Dropped with the pass, so a node the app removes later is not kept alive\n  // by its parent's cursor until the next pass replaces the map.\n  _cursors = new WeakMap<Node, Node | null>();\n}\n\n/**\n * Runs a callback with hydration temporarily disabled, restoring the previous\n * state afterwards.  Used when a server/client mismatch forces a subtree to be\n * rendered fresh in the middle of a hydration pass — fresh rendering must not\n * claim nodes from the surrounding SSR DOM.\n */\nexport function runWithoutHydration<T>(fn: () => T): T {\n  const wasHydrating = _hydrating;\n  _hydrating = false;\n  try {\n    return fn();\n  } finally {\n    _hydrating = wasHydrating;\n  }\n}\n\n/**\n * Returns the next unclaimed child of a parent node (or null at the end)\n * without advancing the cursor.\n */\nexport function peekChild(parent: Node): Node | null {\n  const entry = _cursors.get(parent);\n  return entry === undefined ? parent.firstChild : entry;\n}\n\n/**\n * Sets the cursor to a specific child node (or null for \"past the end\").\n */\nexport function setCursor(parent: Node, node: Node | null) {\n  _cursors.set(parent, node);\n}\n\n/**\n * Builds a fresh list()/when() block in the middle of a hydration pass, when\n * there are no SSR markers to claim. The block's appends land at the claim\n * cursor (not after the still-unclaimed children) and the cursor is pinned\n * behind it, so no later sibling can claim the block's fresh nodes.\n */\nexport function runFreshAtCursor<T>(parent: Node, build: () => T): T {\n  const at = peekChild(parent);\n  // Pin: with no entry, peekChild would follow the block's new firstChild.\n  setCursor(parent, at);\n  return runWithoutHydration(() => at ? withScopedInsertion(parent, at, build) : build());\n}\n\nfunction isWhitespaceText(node: Node) {\n  return node.nodeType === 3 && !/\\S/.test(node.textContent || '');\n}\n\n/**\n * Advances the cursor past whitespace-only text nodes.\n *\n * Nuclo's own SSR output never produces bare whitespace text nodes (text\n * children are always preceded by a `<!-- text-N -->` marker), so unmarked\n * whitespace comes from the surrounding template or an HTML\n * formatter/minifier.  Skipping (without removing) keeps the cursor aligned\n * while leaving the document's visual whitespace untouched.\n *\n * forceUpdate() is different: the DOM it walks was built by nuclo, where a\n * bare whitespace text is a real text child. One that sits where the new tree\n * expects an element or a marker is a child the tree no longer produces — it\n * is dropped (`drop`), or it would survive in front of the cursor forever.\n */\nexport function skipWhitespaceText(parent: Node, drop = _force) {\n  let child = peekChild(parent);\n  let advanced = false;\n  while (child && isWhitespaceText(child)) {\n    const next = child.nextSibling;\n    if (drop) safeRemoveChild(child);\n    child = next;\n    advanced = true;\n  }\n  if (advanced) {\n    setCursor(parent, child);\n  }\n}\n\n/**\n * Claims the next child node from parent at the current cursor position.\n * Advances the cursor by one.\n */\nexport function claimChild(parent: Node): Node | null {\n  const child = peekChild(parent);\n  if (child) {\n    setCursor(parent, child.nextSibling);\n  }\n  return child;\n}\n\n/**\n * forceUpdate() text claim: claims the next child when it is a bare text node\n * (client renders emit no `<!-- text-N -->` markers). Whitespace-only text\n * that is followed by a text marker is SSR template formatting, not content —\n * it is left for the marker path, which skips it. Returns null when nothing\n * claimable is at the cursor.\n */\nexport function claimBareText(parent: Node): Text | null {\n  const next = peekChild(parent);\n  if (!next || next.nodeType !== 3) return null;\n  if (isWhitespaceText(next)) {\n    let sibling = next.nextSibling;\n    while (sibling && isWhitespaceText(sibling)) sibling = sibling.nextSibling;\n    if (\n      sibling && sibling.nodeType === 8 &&\n      (sibling.textContent ?? \"\").trimStart().startsWith(\"text-\")\n    ) return null;\n  }\n  claimChild(parent);\n  return next as Text;\n}\n\n/**\n * Claims a server-rendered `<!--{prefix}-start-…-->` … `<!--{prefix}-end-->`\n * block (list()/when()) at the cursor, leaving the cursor just after the start\n * marker. Returns null, claiming nothing, when the next child isn't a start\n * marker. Pairs are depth-counted because directly nested blocks share a\n * host. A missing end marker (corrupt/truncated SSR output) is recreated right\n * after the start marker and reported as `recreated`.\n */\nexport function claimMarkerPair(\n  parent: Node,\n  prefix: \"list\" | \"when\" | \"region\",\n): { start: Comment; end: Comment; recreated: boolean } | null {\n  skipWhitespaceText(parent);\n  const start = peekChild(parent);\n  const startPrefix = prefix + \"-start-\";\n  if (!start || start.nodeType !== 8 || !start.textContent?.startsWith(startPrefix)) return null;\n  claimChild(parent);\n  const endText = prefix + \"-end\";\n  let depth = 0;\n  for (let node = start.nextSibling; node; node = node.nextSibling) {\n    if (node.nodeType !== 8) continue;\n    const text = node.textContent;\n    if (text === endText) {\n      if (depth === 0) return { start: start as Comment, end: node as Comment, recreated: false };\n      depth--;\n    } else if (text?.startsWith(startPrefix)) {\n      depth++;\n    }\n  }\n  const end = document.createComment(endText);\n  parent.insertBefore(end, start.nextSibling);\n  return { start: start as Comment, end, recreated: true };\n}\n\n/**\n * Attempts to claim an existing element from the parent during hydration.\n * Returns the claimed element if the next child matches the expected tag, or null.\n */\nexport function claimElement(parent: Node, tagName: string): Element | null {\n  if (!_hydrating) return null;\n  skipWhitespaceText(parent);\n  const candidate = peekChild(parent);\n  if (candidate && candidate.nodeType === 1) {\n    // HTML elements report \"DIV\"; SVG elements keep their case — exact match\n    // first, so camelCase SVG tags (linearGradient, clipPath) are claimable.\n    const name = (candidate as Element).tagName;\n    if (name === tagName || name.toLowerCase() === tagName) return claimChild(parent) as Element;\n  }\n  return null;\n}\n\n/**\n * Removes unclaimed SSR children from a hydrated element.\n * Must be called after modifiers have been applied to a claimed element.\n * Removes nodes from the cursor through `lastOriginalChild` (the element's\n * last child before modifiers ran) — fresh nodes sit before the cursor and\n * nodes a modifier appended itself come after that boundary; both are\n * preserved.\n *\n * When `lastOriginalChild` is no longer a child, the modifiers already dealt\n * with every original node: a `textContent`/`innerHTML` attribute replaced\n * them wholesale, or the claim walk reached and dropped it. Whatever the\n * element holds now is the new build's own content — walking it for a boundary\n * that is gone would remove all of it.\n */\nexport function cleanupUnclaimedChildren(node: Node, lastOriginalChild: Node | null) {\n  if (!lastOriginalChild || lastOriginalChild.parentNode !== node) return;\n  let current = peekChild(node);\n  while (current) {\n    const next = current === lastOriginalChild ? null : current.nextSibling;\n    // safeRemoveChild (not a bare removeChild): during forceUpdate() the\n    // unclaimed nodes were live — their listeners, registrations and\n    // onDestroy hooks must be released, not just detached.\n    safeRemoveChild(current);\n    current = next;\n  }\n  setCursor(node, null);\n}\n","/**\n * Mount/destroy lifecycle hooks.\n *\n * Two equivalent ways to register them, both funneling into this module:\n *   - `on(\"mount\", cb)` / `on(\"destroy\", cb)`            (./events.ts)\n *   - `{ onMount: cb }` / `{ onDestroy: cb }` attributes  (./attributes.ts)\n *\n * ── Mount timing ─────────────────────────────────────────────────────────\n * A freshly created element is still detached while its own subtree (and,\n * for the initial page render, every ancestor up to the root) is being\n * assembled — nuclo builds a tree fully off-document before attaching it in\n * one shot (render()/hydrate()), and list()/when() do the same for the\n * rows/branches they insert into an already-connected host. So onMount can't\n * fire the instant a modifier runs; the element is queued and the queue is\n * flushed once the surrounding operation (render(), hydrate(), or update())\n * finishes inserting its nodes — at that point the element is guaranteed\n * connected. See flushMountQueue() and its call sites in render.ts/update.ts.\n *\n * ── Destroy timing ───────────────────────────────────────────────────────\n * onDestroy fires eagerly and synchronously the moment nuclo removes the\n * element through its own machinery — see the disposeElementLifecycle() call\n * in shared/dom.ts's cleanupNodeTree(), which every ordinary removal\n * (list()/when() diffing, any safeRemoveChild() call) already goes through.\n * list()'s bulk clear/replace also cleans each row before detaching it, so\n * destroy fires at removal time there too.\n *\n * An element removed through means nuclo never observes (e.g. a raw\n * `node.remove()` or `innerHTML = ''` on a container built by render()) never\n * gets its onDestroy callbacks or onMount cleanups run — not even on a later\n * update(). This file does not use a MutationObserver, and update() only\n * prunes disconnected nodes from its registries without disposing their\n * lifecycles. That never leaks memory (all bookkeeping below is\n * WeakMap-based, exactly like every other nuclo registry — see\n * test/memory/gc-collectability.test.ts), but timers or subscriptions the\n * app started in onMount keep running. Apps that need teardown should remove\n * the subtree through nuclo, e.g. by switching off a when() around it.\n *\n * ── Ordering (parent/child, any depth) ──────────────────────────────────\n * Neither mechanism below cares how many list()s, when()s, or plain\n * component functions wrap an element — every element gets its own\n * independent WeakMap record, keyed by the element itself, so correctness\n * never depends on nesting depth. What nesting *does* affect is the relative\n * order two related elements' callbacks fire in, which follows normal\n * resource-scoping discipline in both directions:\n *  - onMount fires parent-before-child. This falls out of queue order for\n *    free — a parent's own {onMount}/on(\"mount\", ...) modifier is applied\n *    (queuing it) before the child factories in its own modifier list are\n *    even invoked, since applying modifiers is a synchronous, in-order walk.\n *    A child's onMount can safely assume any context the parent's onMount\n *    set up is already in place.\n *  - onDestroy fires child-before-parent (cleanupNodeTree() in shared/dom.ts\n *    recurses into every descendant before disposing the node itself). A\n *    parent's onDestroy can safely release something its children were\n *    still using — they have already run by the time it does.\n * Together: mount is top-down, destroy is bottom-up — the same order a\n * `try { ... } finally { ... }` stack of nested resource scopes unwinds in,\n * applied to the DOM tree instead of the call stack.\n *\n * ── Memory ───────────────────────────────────────────────────────────────\n * Per-element bookkeeping lives in a WeakMap keyed by the element, so it is\n * collectible the instant nothing else references the element — exactly the\n * same shape as list/runtime.ts's and update/registry.ts's registries. The\n * mountQueue holds only WeakRefs, so abandoned builds are collectible even\n * if no later operation flushes the queue. Completed mount callbacks are\n * released immediately; only their returned cleanup survives until destroy.\n */\n\nimport { logError } from \"../shared/errors\";\nimport { isBrowser } from \"../shared/environment\";\nimport { isForceHydrating, isSerializing } from \"../hydration\";\n\ntype CallbackSlot<T> = T | T[];\n\n// Plain numeric constants rather than `const enum` — this project's tsconfig\n// enables erasableSyntaxOnly, which `const enum` (a non-erasable construct:\n// it needs its values inlined by the TS compiler itself) is incompatible\n// with. Mirrors the same pattern already used by list/template.ts's\n// LEAF_TEXT/LEAF_CLASSNAME/SLOT_*/ATTR_* constants.\ntype LifecycleStateValue = 0 | 1 | 2;\n/** Registered, not yet flushed (or already disposed before it could be). */\nconst STATE_PENDING: LifecycleStateValue = 0;\nconst STATE_MOUNTED: LifecycleStateValue = 1;\nconst STATE_DISPOSED: LifecycleStateValue = 2;\n\ninterface LifecycleRecord {\n  mount: CallbackSlot<MountCallback<Element>> | null;\n  destroy: CallbackSlot<DestroyCallback<Element>> | null;\n  /**\n   * nuclo's own teardown for a marker node (a region's start marker, a\n   * view's anchor). Unlike `destroy`, it runs whether or not the node ever\n   * mounted: a tree discarded half-built (cancelMountsSince) may already have\n   * put a view's content into a live region elsewhere.\n   */\n  dispose: ((node: Node) => void) | null;\n  state: LifecycleStateValue;\n}\n\n// Keyed by Node, not Element: comment markers register a disposer too.\nconst records = new WeakMap<Node, LifecycleRecord>();\n\n/**\n * Count of Pending/Mounted records not yet disposed. Without live callbacks,\n * cleanupNodeTree() can walk childNodes without a mutation-safe snapshot.\n * Raw DOM removals can leave this count high, causing only extra snapshots.\n */\nlet activeCount = 0;\n\nlet mountQueue: WeakRef<Node>[] = [];\n\nfunction shouldSkip() {\n  // isSerializing() is checked in addition to isBrowser (unlike on()'s plain\n  // DOM-event path) because renderToString() can run under jsdom, where\n  // isBrowser is true. A DOM event registered there is inert (nothing ever\n  // dispatches it), but a mount callback registered there would actually\n  // *run* — including any side effects, like starting a timer or opening a\n  // subscription — purely from serializing a page to a string. Skipping\n  // registration entirely during serialization avoids that.\n  return !isBrowser || isSerializing();\n}\n\n/**\n * A new record is Pending and queued exactly once, right here: every later\n * registration for the element finds the record already queued (or already\n * mounted/disposed), so no per-record \"queued\" flag is needed.\n */\nfunction ensureRecord(node: Node): LifecycleRecord {\n  let record = records.get(node);\n  if (!record) {\n    record = { mount: null, destroy: null, dispose: null, state: STATE_PENDING };\n    records.set(node, record);\n    activeCount++;\n    mountQueue.push(new WeakRef(node));\n  }\n  return record;\n}\n\nfunction pushSlot<T>(slot: CallbackSlot<T> | null, cb: T): CallbackSlot<T> {\n  if (slot === null) return cb;\n  if (Array.isArray(slot)) {\n    slot.push(cb);\n    return slot;\n  }\n  return [slot, cb];\n}\n\n/** Registers a mount callback for `element`. See the module doc for timing. */\nexport function registerMount<TElement extends Element>(\n  element: TElement,\n  callback: MountCallback<TElement>,\n) {\n  if (shouldSkip()) return;\n  const record = ensureRecord(element);\n  // Not reachable through the tag-builder DSL (every modifier — on()/attrs —\n  // runs once, synchronously, while the element is still Pending) — only via\n  // a direct, manual on(\"mount\", cb)(element, 0) call on an element nuclo has\n  // already disposed. Dropped rather than stored so it can't grow the\n  // record's callback list for an element that will never mount again.\n  if (record.state === STATE_DISPOSED) return;\n  // forceUpdate() reclaim: the element is already Mounted — its original\n  // callbacks stay in force. Re-applied hooks are dropped: mount must not\n  // re-fire for an element that never left the document, and repeated force\n  // passes must not grow the callback slots.\n  if (record.state !== STATE_PENDING && isForceHydrating()) return;\n  record.mount = pushSlot(record.mount, callback as MountCallback<Element>);\n}\n\n/** Registers a destroy callback for `element`. See the module doc for timing. */\nexport function registerDestroy<TElement extends Element>(\n  element: TElement,\n  callback: DestroyCallback<TElement>,\n) {\n  if (shouldSkip()) return;\n  const record = ensureRecord(element);\n  if (record.state === STATE_DISPOSED) return; // see registerMount()\n  if (record.state !== STATE_PENDING && isForceHydrating()) return; // see registerMount()\n  record.destroy = pushSlot(record.destroy, callback as DestroyCallback<Element>);\n}\n\n/**\n * Internal: nuclo's own teardown for a marker node, run once when nuclo\n * removes it (see `dispose` on the record). Idempotent per node, so a\n * forceUpdate() reclaim that passes the same function again changes nothing.\n */\nexport function setNodeDisposer(node: Node, dispose: (node: Node) => void) {\n  if (shouldSkip()) return;\n  const record = ensureRecord(node);\n  if (record.state === STATE_DISPOSED) return;\n  record.dispose = dispose;\n}\n\nfunction runMount(element: Element, callback: MountCallback<Element>, record: LifecycleRecord) {\n  if (record.state !== STATE_MOUNTED) return;\n  try {\n    const cleanup = callback(element);\n    if (typeof cleanup === \"function\") {\n      // A mount-returned cleanup takes no arguments (matches the\n      // useEffect()/onMount() convention) while DestroyCallback is called\n      // with the element — but storing it as-is, uncast wrapper, is safe and\n      // avoids allocating a closure for every mount that returns one: JS\n      // silently ignores call arguments a function doesn't declare, so\n      // runDestroy()'s `callback(element)` just calls `cleanup()` with an\n      // extra, unused argument.\n      // The callback may synchronously remove itself through a nested update.\n      if (records.get(element)?.state === STATE_DISPOSED) runDestroy(element, cleanup);\n      else record.destroy = pushSlot(record.destroy, cleanup);\n    }\n  } catch (error) {\n    logError(\"Error in mount callback\", error);\n  }\n}\n\nfunction runDestroy(element: Element, callback: DestroyCallback<Element>) {\n  try {\n    callback(element);\n  } catch (error) {\n    logError(\"Error in destroy callback\", error);\n  }\n}\n\nfunction fireMount(element: Element) {\n  // Queued only by ensureRecord(), right after the record was stored. A\n  // marker node's record has no mount callbacks; it just turns Mounted here.\n  const record = records.get(element)!;\n  // Disposed before its queued turn came up (e.g. built and discarded within\n  // the same pass) — the mount never observably happened, so don't fire it.\n  if (record.state !== STATE_PENDING) return;\n  record.state = STATE_MOUNTED;\n\n  const mount = record.mount;\n  record.mount = null;\n  if (mount === null) return;\n  if (Array.isArray(mount)) {\n    for (let i = 0; i < mount.length; i++) runMount(element, mount[i], record);\n  } else {\n    runMount(element, mount, record);\n  }\n}\n\n/**\n * Flushes every element queued since the last flush, firing its mount\n * callback(s) now that the surrounding render()/hydrate()/update() pass has\n * finished inserting nodes into the (connected) document.\n *\n * Swaps the shared queue out to a local batch before iterating, so a mount\n * callback that itself triggers a nested update() (which pushes onto a fresh\n * queue and flushes it in its own, inner call) can't corrupt or be corrupted\n * by the batch this call is still draining.\n */\nexport function flushMountQueue() {\n  if (mountQueue.length === 0) return;\n  const batch = mountQueue;\n  mountQueue = [];\n  for (let i = 0; i < batch.length; i++) {\n    const element = batch[i].deref();\n    if (element) fireMount(element as Element);\n  }\n}\n\n/** Current end of the mount queue — pass it to cancelMountsSince(). */\nexport function mountQueueMark() {\n  return mountQueue.length;\n}\n\n/**\n * Cancels the mounts queued since `mark` for elements that never made it into\n * the document: the operation that was building them threw, so they were\n * discarded instead of attached. Left queued, the next flush would fire\n * onMount on a detached element — one nuclo never removes, so its cleanup and\n * onDestroy could never run. Elements that did get attached keep their turn.\n */\nexport function cancelMountsSince(mark: number) {\n  for (let i = mountQueue.length - 1; i >= mark; i--) {\n    const element = mountQueue[i].deref();\n    if (element && !element.isConnected) disposeElementLifecycle(element);\n  }\n}\n\n/**\n * Finalizes one element's lifecycle: silently cancels a mount that never got\n * to run (state was still Pending — built and discarded within one pass), or\n * fires its destroy callback(s) (state was Mounted). Idempotent — safe to\n * call more than once for the same element, e.g. once eagerly from\n * cleanupNodeTree() and, redundantly, once more from a fast-path caller that\n * doesn't know whether the eager walk already reached this node.\n */\nexport function disposeElementLifecycle(node: Node) {\n  const record = records.get(node);\n  if (!record) return;\n  if (record.state === STATE_DISPOSED) return;\n\n  const wasMounted = record.state === STATE_MOUNTED;\n  record.state = STATE_DISPOSED;\n  activeCount--;\n\n  const dispose = record.dispose;\n  if (dispose !== null) {\n    record.dispose = null;\n    try {\n      dispose(node);\n    } catch (error) {\n      logError(\"Error disposing node\", error);\n    }\n  }\n\n  const element = node as Element;\n  if (wasMounted) {\n    const destroy = record.destroy;\n    if (destroy !== null) {\n      if (Array.isArray(destroy)) {\n        for (let i = 0; i < destroy.length; i++) runDestroy(element, destroy[i]);\n      } else {\n        runDestroy(element, destroy);\n      }\n    }\n  }\n\n  // Drop references eagerly instead of waiting for the WeakMap entry to be\n  // collected along with the element — the callbacks (and anything they\n  // closed over) become unreachable from here immediately.\n  record.mount = null;\n  record.destroy = null;\n}\n\n/** True once the node's queued mount has flushed: nuclo attached the tree it is in. */\nexport function isMounted(node: Node) {\n  return records.get(node)?.state === STATE_MOUNTED;\n}\n\n/** Whether cleanup must snapshot children that lifecycle callbacks could mutate. */\nexport function hasActiveLifecycleRegistrations() {\n  return activeCount > 0;\n}\n","/**\n * Internal factory metadata.\n *\n * Tag builders return opaque factory closures; the list() template engine\n * needs to see through them (tag name + modifier list) to decide whether a\n * row can be built by cloning a skeleton instead of running the factory.\n * The metadata is attached under symbols so nothing leaks into the public\n * API surface or enumerable properties.\n */\n\nexport const FACTORY_TAG = Symbol(\"nuclo.factory.tag\");\nexport const FACTORY_MODS = Symbol(\"nuclo.factory.mods\");\n/**\n * Marks the modifier returned by on() for a native DOM event. Applying it only\n * attaches a listener to its parent (it produces no node and reads no row\n * state), so the list() template engine can replay it on a skeleton clone\n * exactly as the normal build path would.\n */\nexport const EVENT_MODIFIER = Symbol(\"nuclo.event.modifier\");\nlet metadataOnlyFactoryDepth = 0;\n\n/**\n * Metadata-only factories (list() template rows past the first) are read\n * once, via getFactoryTag/getFactoryMods, during the same synchronous render\n * pass that created them, and are never invoked or retained afterward — so a\n * small pool of stub functions can be reused across rows instead of\n * allocating a fresh closure per tag-builder call. Each row checkpoints the\n * pool before rendering and releases its metadata after consumption, including\n * on failure. Nested renders use later slots so they cannot overwrite an\n * outer row's still-live factory tree.\n */\nconst metadataOnlyStubPool: Array<() => null> = [];\nlet metadataOnlyPoolIndex = 0;\n\nexport function acquireMetadataOnlyFactory(): () => null {\n  if (metadataOnlyPoolIndex >= metadataOnlyStubPool.length) {\n    metadataOnlyStubPool.push(() => null);\n  }\n  return metadataOnlyStubPool[metadataOnlyPoolIndex++]!;\n}\n\ninterface TaggedFactory {\n  [FACTORY_TAG]?: string;\n  [FACTORY_MODS]?: readonly unknown[];\n}\n\nexport function setFactoryMeta(\n  factory: unknown,\n  tag: string,\n  mods: readonly unknown[],\n) {\n  (factory as TaggedFactory)[FACTORY_TAG] = tag;\n  (factory as TaggedFactory)[FACTORY_MODS] = mods;\n}\n\n/** Returns the modifier list of a tag-builder factory, or undefined. */\nexport function getFactoryMods(fn: unknown): readonly unknown[] | undefined {\n  return typeof fn === \"function\" ? (fn as TaggedFactory)[FACTORY_MODS] : undefined;\n}\n\n/** Returns the tag name of a tag-builder factory, or undefined. */\nexport function getFactoryTag(fn: unknown): string | undefined {\n  return typeof fn === \"function\" ? (fn as TaggedFactory)[FACTORY_TAG] : undefined;\n}\n\nexport function markEventModifier<T extends object>(fn: T): T {\n  (fn as { [EVENT_MODIFIER]?: boolean })[EVENT_MODIFIER] = true;\n  return fn;\n}\n\n/** True for a modifier returned by on() for a native DOM event. */\nexport function isEventModifier(fn: unknown) {\n  return typeof fn === \"function\" && (fn as { [EVENT_MODIFIER]?: boolean })[EVENT_MODIFIER] === true;\n}\n\nexport function isMetadataOnlyFactoryMode() {\n  return metadataOnlyFactoryDepth > 0;\n}\n\n/**\n * Takes the render function and its two args directly (rather than a `() =>`\n * thunk) so the hot per-row call in list/runtime.ts doesn't allocate a\n * closure just to defer a single call.\n */\nexport function withMetadataOnlyFactories<TItem, T>(fn: (item: TItem, index: number) => T, item: TItem, index: number): T {\n  metadataOnlyFactoryDepth++;\n  try {\n    return fn(item, index);\n  } finally {\n    metadataOnlyFactoryDepth--;\n  }\n}\n\nexport function getMetadataOnlyFactoryCheckpoint() {\n  return metadataOnlyPoolIndex;\n}\n\nexport function releaseMetadataOnlyFactories(checkpoint: number) {\n  while (metadataOnlyPoolIndex > checkpoint) {\n    const factory = metadataOnlyStubPool[--metadataOnlyPoolIndex] as TaggedFactory;\n    factory[FACTORY_TAG] = undefined;\n    factory[FACTORY_MODS] = undefined;\n  }\n}\n","/**\n * Typed event listener helper.\n *\n * Usage:\n *   button(\n *     \"Click\",\n *     on(\"click\", (e) => {\n *       // e and currentTarget are inferred from the native event map\n *     })\n *   )\n *\n * Design notes:\n * - Returns a NodeModFn so it can be used like any other modifier.\n * - Produces no child node (returns void in the modifier body).\n * - Provides strong typing of the event object based on the DOM event name.\n * - Stores listener references in a WeakMap to prevent memory leaks.\n * - Listeners are automatically cleaned up when elements are garbage collected.\n */\n\nimport { removeEventAttributes } from \"./event-attributes\";\nimport { logError } from \"../shared/errors\";\nimport { isBrowser } from \"../shared/environment\";\nimport { registerMount, registerDestroy } from \"./lifecycle\";\nimport { markEventModifier } from \"./factory-meta\";\n\ntype EventListenerOptions = boolean | AddEventListenerOptions;\n\ninterface TrackedListener {\n  type: string;\n  wrapped: EventListener;\n  capture: boolean;\n}\n\ntype TrackedListeners = TrackedListener | TrackedListener[];\n\n/**\n * Tracks attached listeners per element so removeAllListeners() can detach them.\n *\n * The common single-listener case stores its registration directly. An array\n * is allocated only when an element has multiple distinct listeners. A\n * registration belongs to the reusable modifier rather than an attachment, so\n * applying one modifier to many elements adds no per-element metadata objects.\n * Only the capture flag is retained because it is the sole option compared by\n * removeEventListener.\n */\nconst elementListeners = new WeakMap<HTMLElement, TrackedListeners>();\n\n/**\n * Store listener info for an element to enable cleanup.\n */\nfunction trackListener(\n  element: HTMLElement,\n  info: TrackedListener,\n) {\n  const tracked = elementListeners.get(element);\n  if (!tracked) {\n    elementListeners.set(element, info);\n  } else if (Array.isArray(tracked)) {\n    if (!tracked.includes(info)) tracked.push(info);\n  } else if (tracked !== info) {\n    elementListeners.set(element, [tracked, info]);\n  }\n}\n\n/**\n * Detach a single tracked listener from the DOM.\n */\nfunction detachListener(\n  element: HTMLElement,\n  info: TrackedListener,\n) {\n  element.removeEventListener(info.type, info.wrapped, info.capture);\n}\n\n/**\n * Detaches every listener on()/nuclo attached to `element` (called when nuclo\n * removes the element).\n */\nexport function removeAllListeners(element: HTMLElement) {\n  removeEventAttributes(element);\n  const tracked = elementListeners.get(element);\n  if (!tracked) return;\n  if (Array.isArray(tracked)) {\n    for (let i = 0; i < tracked.length; i++) detachListener(element, tracked[i]);\n  } else {\n    detachListener(element, tracked);\n  }\n  elementListeners.delete(element);\n}\n\nfunction noopEventModifier(_parent: ExpandedElement<ElementTagName>) {}\n\n/**\n * \"mount\"/\"destroy\" are pseudo-events: there is no native DOM event to\n * addEventListener for, so on()'s runtime dispatches them here instead of\n * through createTrackedListener(). See element/lifecycle.ts for what\n * registerMount()/registerDestroy() actually do and when the callback fires.\n */\nfunction createLifecycleModifier<TTagName extends ElementTagName>(\n  kind: \"mount\" | \"destroy\",\n  callback: (element: HTMLElementTagNameMap[TTagName]) => unknown,\n): NodeModFn<TTagName> {\n  if (!isBrowser) return noopEventModifier as NodeModFn<TTagName>;\n\n  return function(parent: ExpandedElement<TTagName>) {\n    if (!parent) return;\n    const el = parent as unknown as HTMLElementTagNameMap[TTagName];\n    if (kind === \"mount\") {\n      registerMount(el, callback as MountCallback<HTMLElementTagNameMap[TTagName]>);\n    } else {\n      registerDestroy(el, callback as DestroyCallback<HTMLElementTagNameMap[TTagName]>);\n    }\n  };\n}\n\nfunction createTrackedListener<TTagName extends ElementTagName>(\n  type: string,\n  listener: TypedEventListener<HTMLElementTagNameMap[TTagName], Event>,\n  capture: boolean,\n): TrackedListener {\n  const wrapped = function(this: EventTarget, event: Event) {\n    const currentTarget = this as HTMLElementTagNameMap[TTagName];\n    try {\n      listener.call(\n        currentTarget,\n        event as Event & { currentTarget: HTMLElementTagNameMap[TTagName] },\n      );\n    } catch (error) {\n      logError(`Error in '${type}' listener`, error);\n    }\n  };\n\n  return { type, wrapped, capture };\n}\n\n/**\n * Overload for standard HTMLElement events (strongly typed via lib.dom.d.ts)\n */\nexport function on<\n  K extends NucloHTMLElementEventName,\n  TTagName extends NucloHTMLElementTagNameForEvent<K> = NucloHTMLElementTagNameForEvent<K>,\n>(\n  type: K,\n  listener: TypedEventListener<\n    HTMLElementTagNameMap[TTagName],\n    NucloHTMLElementEventForName<K>\n  >,\n  options?: EventListenerOptions\n): NodeModFn<TTagName>;\n\n/**\n * Fires once, after the element has been created and connected to the live\n * document. Equivalent to `{ onMount: ... }`. May return a cleanup function —\n * equivalent to also registering it with on(\"destroy\", ...).\n *\n * Listed before the generic string overload below on purpose: \"mount\" is a\n * string too, so a less specific overload earlier would shadow this one.\n */\nexport function on<TTagName extends ElementTagName = ElementTagName>(\n  type: \"mount\",\n  listener: MountCallback<HTMLElementTagNameMap[TTagName]>,\n): NodeModFn<TTagName>;\n\n/** Fires once the element has been removed. Equivalent to `{ onDestroy: ... }`. */\nexport function on<TTagName extends ElementTagName = ElementTagName>(\n  type: \"destroy\",\n  listener: DestroyCallback<HTMLElementTagNameMap[TTagName]>,\n): NodeModFn<TTagName>;\n\n/**\n * Fallback / custom event overload (arbitrary event names or custom event types).\n * Specify a custom event type with the E generic if needed:\n *   on<\"my-event\", CustomEvent<MyDetail>>(\"my-event\", e => { ... })\n */\nexport function on<\n  K extends string,\n  E extends Event = Event,\n  TTagName extends ElementTagName = ElementTagName\n>(\n  type: K,\n  listener: TypedEventListener<HTMLElementTagNameMap[TTagName], E>,\n  options?: EventListenerOptions\n): NodeModFn<TTagName>;\n\nexport function on<TTagName extends ElementTagName = ElementTagName>(\n  type: string,\n  listener:\n    | TypedEventListener<HTMLElementTagNameMap[TTagName], Event>\n    | MountCallback<HTMLElementTagNameMap[TTagName]>\n    | DestroyCallback<HTMLElementTagNameMap[TTagName]>,\n  options?: EventListenerOptions\n): NodeModFn<TTagName> {\n  if (type === \"mount\" || type === \"destroy\") {\n    return createLifecycleModifier<TTagName>(\n      type,\n      listener as (element: HTMLElementTagNameMap[TTagName]) => unknown,\n    );\n  }\n\n  if (!isBrowser) return noopEventModifier as NodeModFn<TTagName>;\n\n  const capture = options === true\n    || (options !== null && typeof options === \"object\" && options.capture === true);\n  // type is neither \"mount\" nor \"destroy\" past the check above, so listener\n  // is really the TypedEventListener member of the union — TS can't narrow a\n  // union on a check of a different parameter, hence the cast.\n  const info = createTrackedListener(\n    type,\n    listener as TypedEventListener<HTMLElementTagNameMap[TTagName], Event>,\n    capture,\n  );\n\n  // Marked so list() row templates can replay it on cloned rows instead of\n  // falling back to a full per-row build (see list/template.ts SLOT_EVENT).\n  return markEventModifier(function(parent: ExpandedElement<TTagName>) {\n    // Type guard: verify parent is an HTMLElement with addEventListener\n    if (!parent || typeof (parent as HTMLElement).addEventListener !== \"function\") {\n      return;\n    }\n\n    const el = parent as HTMLElementTagNameMap[TTagName];\n\n    el.addEventListener(type, info.wrapped, options);\n\n    // Track the listener so removeAllListeners() can detach it later.\n    trackListener(el, info);\n  });\n}\n","export function isPrimitive(value: unknown): value is Primitive {\n\treturn value === null || (typeof value !== \"object\" && typeof value !== \"function\");\n}\n\nexport function isNode<T>(value: T): value is T & Node {\n\tif (value instanceof Node) return true;\n\tif (typeof value !== 'object' || value === null) return false;\n\t// Recognize polyfill DOM objects (plain objects with a numeric nodeType)\n\treturn typeof (value as { nodeType?: unknown }).nodeType === 'number';\n}\n\nexport function isObject(value: unknown): value is object {\n\treturn typeof value === \"object\" && value !== null;\n}\n\n/**\n * Narrows `value` to a callable. The generic `<T extends Function>` is intentionally\n * removed: it allowed callers to assert any specific function signature via the type\n * parameter without a runtime check, which is unsafe. Use explicit casts at call sites\n * when a more specific signature is needed.\n */\nexport function isFunction(value: unknown): value is (...args: unknown[]) => unknown {\n\treturn typeof value === \"function\";\n}\n\nexport function isZeroArityFunction(value: unknown): value is () => unknown {\n\treturn isFunction(value) && value.length === 0;\n}\n","import { logError } from \"../shared/errors\";\nimport { membersOf, TEXT_KIND, type UpdateScope } from \"./scope\";\nimport { reactiveTextNodes, reactiveTextNodesByNode, registerReactiveTextNode, type TextResolver } from \"./registry\";\nimport { isBrowser } from \"../shared/environment\";\nimport { isSerializing } from \"../shared/serializing\";\n\n/** DSL text semantics: nullish and non-primitive values render as \"\". */\nexport function toText(value: unknown) {\n  return value == null || typeof value === \"object\" || typeof value === \"function\" ? \"\" : String(value);\n}\n\n/**\n * Creates a text node showing `initial` (the resolver's already-evaluated\n * value) and registers it so every update() re-evaluates `resolver` into it.\n */\nexport function createReactiveTextNode(resolver: TextResolver, initial: unknown): Text {\n  const str = toText(initial);\n  const txt = document.createTextNode(str);\n  if (isBrowser && !isSerializing()) registerReactiveTextNode(txt, resolver, str);\n  return txt;\n}\n\n/**\n * Re-evaluates every registered reactive text node (under `scope`'s roots,\n * if given) and writes the ones whose text changed. Disconnected and\n * collected nodes are pruned as the pass goes.\n */\nexport function notifyReactiveTextNodes(scope?: UpdateScope) {\n  if (!scope) return notifyTextSet(reactiveTextNodes);\n  for (const root of scope.roots) notifyTextSet(membersOf(root, TEXT_KIND) as Set<WeakRef<Text>>);\n}\n\nfunction notifyTextSet(set: Set<WeakRef<Text>>) {\n  for (const ref of set) {\n    const node = ref.deref();\n    const entry = node && reactiveTextNodesByNode.get(node);\n    // A scope member whose node was unregistered and registered again is\n    // stale: its live entry carries a newer ref.\n    if (!entry || entry.ref !== ref || !node.isConnected) {\n      if (entry && entry.ref === ref) reactiveTextNodesByNode.delete(node);\n      set.delete(ref);\n      reactiveTextNodes.delete(ref);\n      continue;\n    }\n\n    let value: string;\n    try {\n      value = toText(entry.resolver());\n    } catch (e) {\n      logError(\"Failed to update reactive text node\", e);\n      value = \"\";\n    }\n    if (value !== entry.lastValue) {\n      node.textContent = value;\n      entry.lastValue = value;\n    }\n  }\n}\n","/**\n * Row-template cloning for list().\n *\n * Building a row through the normal pipeline costs one createElement + a full\n * modifier pass per element. For a keyed list every row comes from the same\n * render function, so the structure is identical across rows and only the\n * leaves differ (text values, event handlers, reactive resolvers, and —\n * rarely — static attribute values). This module:\n *\n *  1. analyzes the first row's factory tree (via the internal factory\n *     metadata symbols) and, when every modifier falls into a supported\n *     shape, records a slot program for the row;\n *  2. clones the first row's built element as a skeleton (cloneNode does not\n *     copy property-assigned `on*` handlers or reactive registrations, and\n *     reactive classNames are scrubbed so a selected first row can't leak\n *     its state into the skeleton);\n *  3. builds every other row as skeleton.cloneNode(true) + a patch pass that\n *     walks the new factory tree in lockstep with the slot program.\n *\n * on() modifiers for native DOM events are supported: they only attach a\n * listener to their parent, so each clone replays them exactly as the normal\n * build would (cloneNode never copies addEventListener listeners, so the\n * skeleton itself stays listener-free).\n *\n * Any construct outside the supported shape (style objects, on(\"mount\") /\n * on(\"destroy\") and other arbitrary NodeModFns, nested list()/when(), node\n * children, resolvers returning non-primitives, the same attribute key set by\n * two attribute objects of one element, SVG) bails to the normal build path —\n * the template is per-list state, so unsupported lists simply never activate\n * it. A per-row shape mismatch (heterogeneous render output) deactivates the\n * template for that list and rebuilds the row normally.\n */\n\nimport { getFactoryMods, getFactoryTag, isEventModifier } from \"../element/factory-meta\";\nimport { eventAttributeToProperty, setEventAttribute } from \"../element/event-attributes\";\nimport { removeAllListeners } from \"../element/events\";\nimport { isNode } from \"../shared/type-guards\";\nimport { cleanupReactiveElement, cleanupReactiveTextNode } from \"../update/registry\";\nimport { toText } from \"../update/reactive-text\";\n\nexport const LEAF_TEXT = 0;\nexport const LEAF_CLASSNAME = 1;\n\n/** Array slots per leaf in RowLeaves: kind, node, resolver, last value. */\nexport const LEAF_STRIDE = 4;\n\n/**\n * A clone's dynamic leaves, owned by its list record instead of the global\n * reactive registries: template rows have a known lifetime (they live and die\n * with their record), so update() can flush them with a tight array walk —\n * no WeakRef/WeakMap bookkeeping per row, nothing for the GC sweeps to prune.\n *\n * Stored flat — [kind, node, fn, last, kind, node, fn, last, ...] — rather\n * than as one object per leaf: a row costs a single small array instead of an\n * array plus an object per leaf, which is the bulk of a template row's\n * retained bookkeeping and allocation.\n */\nexport type RowLeaves = unknown[];\n\nexport const SLOT_ATTRS = 0;\nexport const SLOT_TEXT = 1;\nexport const SLOT_REACTIVE_TEXT = 2;\nexport const SLOT_CHILD = 3;\nexport const SLOT_NULL = 4;\nexport const SLOT_EVENT = 5;\n\nexport const ATTR_STATIC = 0;\nexport const ATTR_EVENT = 1;\nexport const ATTR_REACTIVE_CLASSNAME = 2;\nexport const ATTR_NULL = 3;\n\nexport interface AttrSpec {\n  key: string;\n  kind: number;\n  /** Static attrs: element exposes the key as a property (filled from the skeleton). */\n  prop: boolean;\n  /**\n   * Static attrs: a skeleton clone already carries the first-row value, so a\n   * row with that same value needs no write. False for state cloneNode() does\n   * not copy (e.g. a <select>'s value) — those rows always write.\n   */\n  cloned: boolean;\n  /** Static attrs: first-row value. Events: normalized native property name. Else undefined (one shape for every spec). */\n  value: unknown;\n}\n\n/**\n * One object shape for every slot (unused fields null) so `slot.kind` reads\n * stay monomorphic in the per-row patch loop; a union of shapes made that\n * property access polymorphic for every slot of every row.\n */\nexport interface TemplateSlot {\n  kind: number;\n  /** SLOT_ATTRS only. */\n  keys: AttrSpec[] | null;\n  /** SLOT_CHILD only. */\n  child: TemplateNode | null;\n}\n\nfunction slot(kind: number, keys: AttrSpec[] | null = null, child: TemplateNode | null = null): TemplateSlot {\n  return { kind, keys, child };\n}\n\nexport interface TemplateNode {\n  tag: string;\n  slots: TemplateSlot[];\n  /** This element carries event handlers (an on() modifier or an `on*` attribute). */\n  events: boolean;\n  /** Any element in this subtree (itself included) carries event handlers. */\n  subtreeEvents: boolean;\n  /**\n   * Native IDL handler properties (`onclick`, ...) this element's `on*`\n   * attributes set. Filled by prepareSkeleton(). Clones assign these\n   * directly — no per-element bookkeeping, the slot program is the record of\n   * what to release — and cleanup nulls them.\n   */\n  eventProps: string[] | null;\n  /** Slots a row's RowLeaves array needs (LEAF_STRIDE per dynamic leaf, subtree included). */\n  leafCount: number;\n  /**\n   * Handlers that went through addEventListener (on() modifiers, or an `on*`\n   * attribute the element has no IDL property for) and are tracked per\n   * element; cleanup releases them with removeAllListeners().\n   */\n  tracked: boolean;\n}\n\n/**\n * Shared leaves of a template row that has none. Every template-built row\n * gets a non-null `dyn`, which is how the cleanup paths tell it from a row\n * built normally (whose subtree may hold registrations the template never\n * produces).\n */\nexport const NO_LEAVES: RowLeaves = [];\n\n/**\n * Write cursor into the row being patched. A template knows its leaf count,\n * so each row gets an exact-size array written by index — no shared scratch\n * buffer to push into and slice out of. A resolver probed mid-row may render\n * a nested list, which opens rows of its own: callers save the cursor with\n * leafCursor() before openLeaves() and put it back after the row.\n */\nlet leafPos = 0;\n\nexport function leafCursor() {\n  return leafPos;\n}\n\nexport function restoreLeafCursor(pos: number) {\n  leafPos = pos;\n}\n\nexport function openLeaves(tmpl: TemplateNode): RowLeaves {\n  leafPos = 0;\n  return tmpl.leafCount === 0 ? NO_LEAVES : new Array<unknown>(tmpl.leafCount);\n}\n\nfunction putLeaf(leaves: RowLeaves, kind: number, node: Node, fn: unknown, last: string) {\n  leaves[leafPos] = kind;\n  leaves[leafPos + 1] = node;\n  leaves[leafPos + 2] = fn;\n  leaves[leafPos + 3] = last;\n  leafPos += LEAF_STRIDE;\n}\n\nexport interface ListTemplate {\n  tmpl: TemplateNode;\n  skeleton: Element;\n}\n\n/** True when an earlier attribute object of the same element already sets `key`. */\nfunction setsAttribute(slots: readonly TemplateSlot[], key: string) {\n  for (let i = 0; i < slots.length; i++) {\n    const slot = slots[i];\n    if (slot.kind !== SLOT_ATTRS) continue;\n    for (let k = 0; k < slot.keys!.length; k++) {\n      if (slot.keys![k].key === key && slot.keys![k].kind !== ATTR_NULL) return true;\n    }\n  }\n  return false;\n}\n\n/**\n * Classifies a factory's modifier tree into a slot program, or returns null\n * when any modifier falls outside the supported shape.\n */\nexport function analyzeFactory(tag: string, mods: readonly unknown[]): TemplateNode | null {\n  const slots: TemplateSlot[] = [];\n\n  for (let i = 0; i < mods.length; i++) {\n    const mod = mods[i];\n    if (mod == null) {\n      slots.push(slot(SLOT_NULL));\n      continue;\n    }\n\n    const t = typeof mod;\n\n    if (t === \"function\") {\n      const childMods = getFactoryMods(mod);\n      if (childMods !== undefined) {\n        const childTag = getFactoryTag(mod);\n        if (!childTag) return null;\n        const child = analyzeFactory(childTag, childMods);\n        if (!child) return null;\n        slots.push(slot(SLOT_CHILD, null, child));\n        continue;\n      }\n      if ((mod as () => unknown).length === 0) {\n        // Probe once to confirm this is a text resolver. className-object\n        // results (css()/cx()), nodes and nested builders are handled by the\n        // normal path only.\n        let v: unknown;\n        try {\n          v = (mod as () => unknown)();\n        } catch {\n          return null;\n        }\n        if (v == null || (typeof v !== \"object\" && typeof v !== \"function\")) {\n          slots.push(slot(SLOT_REACTIVE_TEXT));\n          continue;\n        }\n        return null;\n      }\n      if (isEventModifier(mod)) {\n        slots.push(slot(SLOT_EVENT));\n        continue;\n      }\n      // on(\"mount\"/\"destroy\"), when()/list() blocks, arbitrary NodeModFns.\n      return null;\n    }\n\n    if (t === \"object\") {\n      if (isNode(mod)) return null;\n      const attrs = mod as Record<string, unknown>;\n      const keys = Object.keys(attrs);\n      const specs: AttrSpec[] = [];\n      for (let k = 0; k < keys.length; k++) {\n        const key = keys[k];\n        const v = attrs[key];\n        if (v == null) {\n          specs.push({ key, kind: ATTR_NULL, prop: false, cloned: false, value: undefined });\n          continue;\n        }\n        if (key === \"style\") return null;\n        // The same key set by two attribute objects (className merging, or a\n        // plain \"last one wins\" attribute): patching a clone slot by slot\n        // can't replay that — a later slot whose value equals its first-row\n        // value is skipped, leaving an earlier slot's row value in place.\n        if (setsAttribute(slots, key)) return null;\n        const vt = typeof v;\n        if (vt === \"function\") {\n          const eventProperty = eventAttributeToProperty(key);\n          if (eventProperty) {\n            specs.push({ key, kind: ATTR_EVENT, prop: false, cloned: false, value: eventProperty });\n            continue;\n          }\n          if (key === \"className\" && (v as () => unknown).length === 0) {\n            specs.push({ key, kind: ATTR_REACTIVE_CLASSNAME, prop: false, cloned: false, value: undefined });\n            continue;\n          }\n          // Reactive non-className attributes need skeleton scrubbing per\n          // key to stay correct — not worth it; normal path handles them.\n          return null;\n        }\n        if (vt === \"object\") return null;\n        specs.push({ key, kind: ATTR_STATIC, prop: false, cloned: false, value: v });\n      }\n      slots.push(slot(SLOT_ATTRS, specs));\n      continue;\n    }\n\n    // string | number | boolean → static text child\n    slots.push(slot(SLOT_TEXT));\n  }\n\n  let events = false;\n  let subtreeEvents = false;\n  let leafCount = 0;\n  for (let i = 0; i < slots.length; i++) {\n    const s = slots[i];\n    if (s.kind === SLOT_EVENT) events = true;\n    else if (s.kind === SLOT_REACTIVE_TEXT) leafCount += LEAF_STRIDE;\n    else if (s.kind === SLOT_CHILD) {\n      subtreeEvents ||= s.child!.subtreeEvents;\n      leafCount += s.child!.leafCount;\n    } else if (s.kind === SLOT_ATTRS) {\n      for (let k = 0; k < s.keys!.length; k++) {\n        if (s.keys![k].kind === ATTR_EVENT) events = true;\n        else if (s.keys![k].kind === ATTR_REACTIVE_CLASSNAME) leafCount += LEAF_STRIDE;\n      }\n    }\n  }\n  // `tracked` starts conservative; prepareSkeleton() narrows it.\n  return { tag, slots, events, subtreeEvents: events || subtreeEvents, eventProps: null, tracked: events, leafCount };\n}\n\n/**\n * Releases a template row's event handlers before its DOM is dropped — the\n * only bookkeeping a template row holds outside its record. Its reactive\n * leaves are record-owned, and analysis bails on lifecycle hooks, nested\n * blocks and anything else cleanupNodeTree() would have to visit, so the\n * walk follows the slot program straight to the event-carrying elements and\n * skips every subtree without one — instead of a WeakMap probe per node.\n */\nexport function cleanupTemplateRow(tmpl: TemplateNode, el: Element) {\n  if (!tmpl.subtreeEvents) return;\n  const props = tmpl.eventProps;\n  if (props !== null) {\n    const target = el as unknown as Record<string, unknown>;\n    // A clone's handler is whatever the row set; nothing else of nuclo's\n    // writes these properties on a template row.\n    for (let i = 0; i < props.length; i++) if (typeof target[props[i]] === \"function\") target[props[i]] = null;\n  }\n  if (tmpl.tracked) removeAllListeners(el as HTMLElement);\n  const slots = tmpl.slots;\n  let child: Node | null = el.firstChild;\n  for (let i = 0; i < slots.length && child !== null; i++) {\n    const slot = slots[i];\n    switch (slot.kind) {\n      case SLOT_TEXT:\n      case SLOT_REACTIVE_TEXT:\n        child = child.nextSibling;\n        break;\n      case SLOT_CHILD:\n        if (slot.child!.subtreeEvents) cleanupTemplateRow(slot.child!, child as Element);\n        child = child.nextSibling;\n        break;\n      // SLOT_ATTRS / SLOT_NULL / SLOT_EVENT: no node produced\n    }\n  }\n}\n\n/**\n * One-time skeleton pass: fills each static attr's property-vs-attribute\n * flag and scrubs reactive classNames (the first row may have rendered with\n * row-specific state, e.g. a selected row's \"danger\" class).\n */\nexport function prepareSkeleton(tmpl: TemplateNode, skeleton: Element) {\n  const slots = tmpl.slots;\n  let child: Node | null = skeleton.firstChild;\n  let tracked = false;\n  for (let i = 0; i < slots.length; i++) {\n    const slot = slots[i];\n    switch (slot.kind) {\n      case SLOT_EVENT:\n        tracked = true;\n        break;\n      case SLOT_ATTRS: {\n        const specs = slot.keys!;\n        for (let k = 0; k < specs.length; k++) {\n          const spec = specs[k];\n          if (spec.kind === ATTR_EVENT) {\n            spec.prop = (spec.value as string) in skeleton;\n            if (spec.prop) (tmpl.eventProps ??= []).push(spec.value as string);\n            else tracked = true;\n          } else if (spec.kind === ATTR_STATIC) {\n            spec.prop = spec.key in skeleton;\n            spec.cloned = spec.prop\n              ? (skeleton as unknown as Record<string, unknown>)[spec.key] === spec.value\n              : skeleton.getAttribute(spec.key) === String(spec.value);\n          } else if (spec.kind === ATTR_REACTIVE_CLASSNAME) {\n            // Drop the attribute rather than assigning \"\": className = \"\"\n            // leaves an empty class=\"\" that every clone would copy — per-row\n            // attribute storage and style work the normal build never has.\n            // The reactive resolver is this element's only class source, and\n            // clones only write className when it resolves non-empty.\n            skeleton.removeAttribute(\"class\");\n          }\n        }\n        break;\n      }\n      case SLOT_TEXT:\n      case SLOT_REACTIVE_TEXT:\n        child = child && child.nextSibling;\n        break;\n      case SLOT_CHILD:\n        if (!child) return;\n        prepareSkeleton(slot.child!, child as Element);\n        child = child.nextSibling;\n        break;\n      // SLOT_NULL: no node produced\n    }\n  }\n  tmpl.tracked = tracked;\n}\n\n/**\n * Patches a skeleton clone from a fresh factory tree. Returns false on any\n * shape mismatch — the caller then rebuilds the row through the normal path\n * (a partially patched clone is safe to abandon: its reactive registrations\n * are weak and disconnected, so the next update() sweeps them).\n */\nexport function instantiateTemplate(\n  tmpl: TemplateNode,\n  mods: readonly unknown[],\n  el: Element,\n  leaves: RowLeaves,\n) {\n  const slots = tmpl.slots;\n  if (mods.length !== slots.length) return false;\n  let child: Node | null = el.firstChild;\n\n  for (let i = 0; i < slots.length; i++) {\n    const slot = slots[i];\n    const mod = mods[i];\n\n    switch (slot.kind) {\n      case SLOT_ATTRS: {\n        if (mod == null || typeof mod !== \"object\") return false;\n        const attrs = mod as Record<string, unknown>;\n        const specs = slot.keys!;\n        let attrCount = 0;\n        for (const _k in attrs) attrCount++;\n        if (attrCount !== specs.length) return false;\n        for (let k = 0; k < specs.length; k++) {\n          const spec = specs[k];\n          const v = attrs[spec.key];\n          switch (spec.kind) {\n            case ATTR_STATIC: {\n              if (v == null || typeof v === \"object\" || typeof v === \"function\") return false;\n              if (v === spec.value && spec.cloned) break;\n              if (spec.prop) {\n                const target = el as unknown as Record<string, unknown>;\n                if (target[spec.key] !== v) target[spec.key] = v;\n              } else {\n                const s = String(v);\n                if (el.getAttribute(spec.key) !== s) el.setAttribute(spec.key, s);\n              }\n              break;\n            }\n            case ATTR_EVENT: {\n              if (typeof v !== \"function\") return false;\n              const eventProperty = spec.value as string;\n              // Fresh clone, known property: a plain assignment. The slot\n              // program (eventProps) is what cleanup consults, so no\n              // per-element handler bookkeeping is needed.\n              if (spec.prop) (el as unknown as Record<string, unknown>)[eventProperty] = v;\n              else setEventAttribute(el as HTMLElement, eventProperty, v as EventListener);\n              break;\n            }\n            case ATTR_REACTIVE_CLASSNAME: {\n              if (typeof v !== \"function\" || (v as () => unknown).length !== 0) return false;\n              // Single-source reactive className (analysis bails on mixed\n              // static+reactive), and the skeleton is scrubbed to \"\" — so a\n              // plain className assignment is exact, no merge needed.\n              const fn = v as () => unknown;\n              let resolved: unknown;\n              try {\n                resolved = fn();\n              } catch {\n                return false;\n              }\n              const s = resolved ? String(resolved) : \"\";\n              if (s) (el as HTMLElement).className = s;\n              putLeaf(leaves, LEAF_CLASSNAME, el, fn, s);\n              break;\n            }\n            case ATTR_NULL: {\n              // The key must be there and nullish: a row whose object has a\n              // different key in its place also reads as undefined here, and\n              // would otherwise lose that attribute.\n              if (v != null || !(spec.key in attrs)) return false;\n              break;\n            }\n          }\n        }\n        break;\n      }\n\n      case SLOT_TEXT: {\n        if (mod == null || typeof mod === \"object\" || typeof mod === \"function\") return false;\n        if (!child) return false;\n        (child as Text).nodeValue = String(mod);\n        child = child.nextSibling;\n        break;\n      }\n\n      case SLOT_REACTIVE_TEXT: {\n        if (typeof mod !== \"function\" || (mod as () => unknown).length !== 0) return false;\n        if (getFactoryMods(mod) !== undefined) return false;\n        if (!child) return false;\n        let v: unknown;\n        try {\n          v = (mod as () => unknown)();\n        } catch {\n          return false;\n        }\n        if (v != null && (typeof v === \"object\" || typeof v === \"function\")) return false;\n        const s = toText(v);\n        const textNode = child as Text;\n        textNode.nodeValue = s;\n        putLeaf(leaves, LEAF_TEXT, textNode, mod, s);\n        child = textNode.nextSibling;\n        break;\n      }\n\n      case SLOT_CHILD: {\n        const childMods = getFactoryMods(mod);\n        if (childMods === undefined) return false;\n        if (getFactoryTag(mod) !== slot.child!.tag) return false;\n        if (!child) return false;\n        if (!instantiateTemplate(slot.child!, childMods, child as Element, leaves)) return false;\n        child = child.nextSibling;\n        break;\n      }\n\n      case SLOT_NULL: {\n        if (mod != null) return false;\n        break;\n      }\n\n      case SLOT_EVENT: {\n        if (!isEventModifier(mod)) return false;\n        // Same call the normal build makes (applyNodeModifier): attaches and\n        // tracks this row's listener on the clone. Produces no node.\n        (mod as (parent: Element, index: number) => void)(el, 0);\n        break;\n      }\n    }\n  }\n  return true;\n}\n\n/**\n * Converts the normally-built first row of a compatible template into the same\n * record-owned dynamic leaf representation used by skeleton clones.\n *\n * The normal builder has already registered reactive text/className leaves in\n * the global registries. Template rows have a tighter lifetime through their\n * list record, so unregister those first-row leaves and let updateListRuntimes()\n * flush them with the rest of the templated rows.\n */\nexport function adoptTemplateLeaves(\n  tmpl: TemplateNode,\n  mods: readonly unknown[],\n  el: Element,\n  leaves: RowLeaves,\n) {\n  const slots = tmpl.slots;\n  if (mods.length !== slots.length) return false;\n  let child: Node | null = el.firstChild;\n\n  for (let i = 0; i < slots.length; i++) {\n    const slot = slots[i];\n    const mod = mods[i];\n\n    switch (slot.kind) {\n      case SLOT_ATTRS: {\n        if (mod == null || typeof mod !== \"object\") return false;\n        const attrs = mod as Record<string, unknown>;\n        const specs = slot.keys!;\n        let k = 0;\n        for (const key in attrs) {\n          if (k >= specs.length) return false;\n          const spec = specs[k];\n          if (spec.key !== key) return false;\n          k++;\n          const v = attrs[key];\n          if (spec.kind === ATTR_REACTIVE_CLASSNAME) {\n            if (typeof v !== \"function\" || (v as () => unknown).length !== 0) return false;\n            cleanupReactiveElement(el);\n            putLeaf(leaves, LEAF_CLASSNAME, el, v, (el as HTMLElement).className);\n          }\n        }\n        if (k !== specs.length) return false;\n        break;\n      }\n\n      case SLOT_TEXT:\n        if (!child) return false;\n        child = child.nextSibling;\n        break;\n\n      case SLOT_REACTIVE_TEXT: {\n        if (typeof mod !== \"function\" || (mod as () => unknown).length !== 0) return false;\n        if (!child || child.nodeType !== 3) return false;\n        const textNode = child as Text;\n        cleanupReactiveTextNode(textNode);\n        putLeaf(leaves, LEAF_TEXT, textNode, mod, textNode.nodeValue ?? \"\");\n        child = textNode.nextSibling;\n        break;\n      }\n\n      case SLOT_CHILD: {\n        const childMods = getFactoryMods(mod);\n        if (childMods === undefined) return false;\n        if (getFactoryTag(mod) !== slot.child!.tag) return false;\n        if (!child) return false;\n        if (!adoptTemplateLeaves(slot.child!, childMods, child as Element, leaves)) return false;\n        child = child.nextSibling;\n        break;\n      }\n\n      case SLOT_NULL:\n        if (mod != null) return false;\n        break;\n\n      case SLOT_EVENT:\n        // The normal build already attached this listener; nothing to adopt.\n        if (!isEventModifier(mod)) return false;\n        break;\n    }\n  }\n  return true;\n}\n\n/**\n * Flushes a template row's dynamic leaves: re-evaluates each resolver and\n * writes the DOM only on change. Resolver errors leave the previous value in\n * place (matching the notify passes' error tolerance).\n */\nexport function flushRowLeaves(leaves: RowLeaves) {\n  for (let i = 0; i < leaves.length; i += LEAF_STRIDE) {\n    let v: unknown;\n    try {\n      v = (leaves[i + 2] as () => unknown)();\n    } catch {\n      continue;\n    }\n    if (leaves[i] === LEAF_TEXT) {\n      const s = toText(v);\n      if (s !== leaves[i + 3]) {\n        (leaves[i + 1] as Text).nodeValue = s;\n        leaves[i + 3] = s;\n      }\n    } else {\n      const s = v ? String(v) : \"\";\n      if (s !== leaves[i + 3]) {\n        (leaves[i + 1] as HTMLElement).className = s;\n        leaves[i + 3] = s;\n      }\n    }\n  }\n}\n","import { logError } from \"../shared/errors\";\nimport { membersOf, ELEMENT_KIND, type UpdateScope } from \"./scope\";\nimport { reactiveElements, reactiveElementsByNode, registerReactiveElement } from \"./registry\";\nimport type { AttributeApplier, AttributeResolver, AttributeResolverRecord } from \"./registry\";\nimport { isBrowser } from \"../shared/environment\";\nimport { isSerializing } from \"../shared/serializing\";\n\nconst UNSET_LAST_VALUE = {};\n\nfunction updateRecord(element: Element, record: AttributeResolverRecord) {\n  let nextValue: unknown;\n  try {\n    nextValue = record.resolver();\n  } catch (e) {\n    logError(`Failed to resolve reactive attribute: ${record.key}`, e);\n    return;\n  }\n\n  // Objects/arrays may be mutated in place (e.g. style objects), so only\n  // primitives are compared against the last applied value.\n  const cacheable = nextValue === null || typeof nextValue !== \"object\";\n  if (cacheable && Object.is(nextValue, record.lastValue)) return;\n\n  try {\n    const applied = record.apply(element, record.key, nextValue);\n    record.lastValue = cacheable && applied !== false ? nextValue : UNSET_LAST_VALUE;\n  } catch (e) {\n    logError(`Failed to apply reactive attribute: ${record.key}`, e);\n  }\n}\n\n/**\n * Makes `resolver` the reactive source of `element`'s `key`: applied now and\n * re-evaluated on every update(). Registering a key again replaces its\n * previous resolver. During SSR the value is applied once and nothing is\n * registered (update() never runs server-side).\n */\nexport function registerAttributeResolver<TTagName extends ElementTagName>(\n  element: ExpandedElement<TTagName>,\n  key: string,\n  resolver: AttributeResolver,\n  apply: AttributeApplier,\n) {\n  const el = element as unknown as Element;\n  const record: AttributeResolverRecord = { key, resolver, apply, lastValue: UNSET_LAST_VALUE };\n  if (isBrowser && !isSerializing()) {\n    const resolvers = registerReactiveElement(el).attributeResolvers;\n    let i = 0;\n    while (i < resolvers.length && resolvers[i].key !== key) i++;\n    resolvers[i] = record;\n  }\n  updateRecord(el, record);\n}\n\n/**\n * Re-evaluates the attribute resolvers of every registered reactive element\n * (under `scope`'s roots, if given). Disconnected and collected elements are\n * pruned as the pass goes.\n */\nexport function notifyReactiveElements(scope?: UpdateScope) {\n  if (!scope) return notifyElementSet(reactiveElements);\n  for (const root of scope.roots) notifyElementSet(membersOf(root, ELEMENT_KIND) as Set<WeakRef<Element>>);\n}\n\nfunction notifyElementSet(set: Set<WeakRef<Element>>) {\n  for (const ref of set) {\n    const el = ref.deref();\n    const entry = el && reactiveElementsByNode.get(el);\n    // A scope member whose element was unregistered and registered again\n    // (forceUpdate() reclaim) is stale: its live entry carries a newer ref.\n    if (!entry || entry.ref !== ref || !el.isConnected) {\n      if (entry && entry.ref === ref) reactiveElementsByNode.delete(el);\n      set.delete(ref);\n      reactiveElements.delete(ref);\n      continue;\n    }\n\n    const resolvers = entry.attributeResolvers;\n    for (let i = 0; i < resolvers.length; i++) updateRecord(el, resolvers[i]);\n  }\n}\n","import { isFunction } from \"../shared/type-guards\";\nimport { registerAttributeResolver } from \"../update/reactive-attributes\";\nimport { logError } from \"../shared/errors\";\n\ntype StyleAssignment = CSSStyleObject;\ntype StyleResolver = () => StyleAssignment | null | undefined;\n\n/**\n * Assigns each property of `styles` to the element's inline style (camelCase\n * or kebab-case keys); null, undefined and \"\" remove the property.\n */\nexport function assignInlineStyles<TTagName extends ElementTagName>(\n  element: ExpandedElement<TTagName>,\n  styles: StyleAssignment | null | undefined,\n) {\n  const style = element.style as unknown as Record<string, string> | undefined;\n  if (!style || !styles) return;\n\n  for (const property in styles) {\n    const value = (styles as Record<string, unknown>)[property];\n    try {\n      style[property] = value == null ? \"\" : String(value);\n    } catch {\n      // Don't stringify the value in the message: that may be what threw.\n      logError(`Failed to set style property '${property}'`);\n    }\n  }\n}\n\nfunction applyReactiveStyle(element: Element, _key: string, styles: unknown) {\n  assignInlineStyles(element as unknown as ExpandedElement, styles as StyleAssignment | null | undefined);\n}\n\nexport function applyStyleAttribute<TTagName extends ElementTagName>(\n  element: ExpandedElement<TTagName>,\n  styleValue: StyleAssignment | StyleResolver | null | undefined\n) {\n  if (isFunction(styleValue)) {\n    registerAttributeResolver(element, 'style', styleValue, applyReactiveStyle);\n  } else {\n    assignInlineStyles(element, styleValue);\n  }\n}\n","// WeakMap/WeakSet replace expando properties — zero `any`, automatic GC on element removal.\nconst staticClassNames = new WeakMap<Element, Set<string>>();\nconst reactiveClassNameFlags = new WeakSet<Element>();\n\n// SVG's `className` is a read-only SVGAnimatedString, so non-HTML elements go\n// through the `class` attribute. The SSR polyfill's elements are all\n// HTMLElement and keep the plain `.className` string the serializer reads.\nfunction getClass(el: Element) {\n\treturn el instanceof HTMLElement ? el.className : el.getAttribute('class') || '';\n}\n\nfunction setClass(el: Element, value: string) {\n\tif (el instanceof HTMLElement) el.className = value;\n\telse el.setAttribute('class', value);\n}\n\n/**\n * Splits a className string into non-empty tokens and adds them to a Set.\n * Single-pass via charCodeAt — avoids intermediate array from split().filter().\n */\nfunction addClassTokens(target: Set<string>, className: string) {\n\tconst len = className.length;\n\tlet start = 0;\n\tfor (let i = 0; i <= len; i++) {\n\t\tif (i === len || className.charCodeAt(i) === 32) { // 32 = ' '\n\t\t\tif (i > start) target.add(className.substring(start, i));\n\t\t\tstart = i + 1;\n\t\t}\n\t}\n}\n\n/**\n * Joins a Set of class names into a single space-separated string.\n */\nfunction joinClasses(classes: Set<string>) {\n\tlet result = '';\n\tfor (const cls of classes) {\n\t\tif (result) result += ' ';\n\t\tresult += cls;\n\t}\n\treturn result;\n}\n\n// Mark element as having a reactive className and capture static classes.\n// Only allocate the tracking Set when the element actually has static classes —\n// reactive-only elements (the common case, e.g. a list row's `class={...}`)\n// skip the Set entirely. mergeReactiveClassName/addStaticClasses both handle a\n// missing Set, so an empty one carries no information.\nexport function initReactiveClassName(el: Element) {\n\tconst current = getClass(el);\n\tif (current && !staticClassNames.has(el)) {\n\t\tconst classSet = new Set<string>();\n\t\taddClassTokens(classSet, current);\n\t\tstaticClassNames.set(el, classSet);\n\t}\n\treactiveClassNameFlags.add(el);\n}\n\n// Drop all className bookkeeping for an element (forceUpdate() reclaim).\nexport function resetClassNameTracking(el: Element) {\n\tstaticClassNames.delete(el);\n\treactiveClassNameFlags.delete(el);\n}\n\n// Check if element has a reactive className\nexport function hasReactiveClassName(el: Element) {\n\treturn reactiveClassNameFlags.has(el);\n}\n\n// Add static classes to the element's tracked set\nexport function addStaticClasses(el: Element, className: string) {\n\tif (!className) return;\n\tlet classSet = staticClassNames.get(el);\n\tif (!classSet) {\n\t\tclassSet = new Set<string>();\n\t\tstaticClassNames.set(el, classSet);\n\t}\n\taddClassTokens(classSet, className);\n}\n\n// Merge reactive className with static classes — called on every reactive update\nexport function mergeReactiveClassName(el: Element, reactiveClassName: string) {\n\tconst staticClasses = staticClassNames.get(el);\n\n\tif (!staticClasses || staticClasses.size === 0) {\n\t\t// Skip the DOM write when nothing changes — the common case is the very\n\t\t// first apply of a reactive className resolving to '' on a fresh element.\n\t\tconst next = reactiveClassName || '';\n\t\tif (getClass(el) !== next) setClass(el, next);\n\t\treturn;\n\t}\n\tif (!reactiveClassName) {\n\t\tsetClass(el, joinClasses(staticClasses));\n\t\treturn;\n\t}\n\t// Hot path: static + reactive. Avoid new Set() — build string directly\n\t// and deduplicate by checking if reactive tokens already exist in static set\n\tlet result = joinClasses(staticClasses);\n\tconst len = reactiveClassName.length;\n\tlet start = 0;\n\tfor (let i = 0; i <= len; i++) {\n\t\tif (i === len || reactiveClassName.charCodeAt(i) === 32) {\n\t\t\tif (i > start) {\n\t\t\t\tconst token = reactiveClassName.substring(start, i);\n\t\t\t\tif (!staticClasses.has(token)) {\n\t\t\t\t\tresult += ' ' + token;\n\t\t\t\t}\n\t\t\t}\n\t\t\tstart = i + 1;\n\t\t}\n\t}\n\tsetClass(el, result);\n}\n\n// Merge static className (for non-reactive className attributes)\nexport function mergeStaticClassName(el: Element, newClassName: string) {\n\tif (!newClassName) return;\n\tconst currentClassName = getClass(el);\n\tif (currentClassName && currentClassName !== newClassName) {\n\t\tconst existing = new Set<string>();\n\t\taddClassTokens(existing, currentClassName);\n\t\taddClassTokens(existing, newClassName);\n\t\tsetClass(el, joinClasses(existing));\n\t} else {\n\t\tsetClass(el, newClassName);\n\t}\n}\n","import { isFunction } from \"../shared/type-guards\";\nimport { registerAttributeResolver } from \"../update/reactive-attributes\";\nimport { applyStyleAttribute } from \"./inline-style\";\nimport { SVG_NAMESPACE } from \"../shared/dom\";\nimport { eventAttributeToProperty, setEventAttribute } from \"./event-attributes\";\nimport { registerMount, registerDestroy } from \"./lifecycle\";\nimport {\n\tinitReactiveClassName,\n\thasReactiveClassName,\n\taddStaticClasses,\n\tmergeReactiveClassName,\n\tmergeStaticClassName\n} from \"./class-name\";\n\ntype AttributeKey<TTagName extends ElementTagName> = keyof ExpandedElementAttributes<TTagName>;\ntype AttributeCandidate<TTagName extends ElementTagName> =\n  ExpandedElementAttributes<TTagName>[AttributeKey<TTagName>];\n\n/**\n * The value each <select> was last asked to show.\n *\n * A select only accepts a value one of its options carries, and attributes\n * are applied before children — so `select({ value }, option(...), ...)`\n * writes the value into a select that has no options yet and the browser\n * drops it. hydrate()/forceUpdate() have the mirror problem: the value is\n * applied against the old options, which are then re-labelled in place. The\n * element factory therefore re-applies it once the children are settled.\n */\nconst selectValues = new WeakMap<Element, unknown>();\n\n/**\n * Sets a <select>'s value. When no option carries it (yet) the assignment\n * would only deselect everything, so the previous selection is put back;\n * `false` keeps a reactive value uncached so every update() retries it until\n * an option matches.\n */\nfunction setSelectValue(select: HTMLSelectElement, v: unknown): boolean | void {\n  const value = String(v);\n  selectValues.set(select, v);\n  if (select.value === value) return;\n  const previous = select.selectedIndex;\n  select.value = value;\n  if (select.value === value) return;\n  select.selectedIndex = previous;\n  return false;\n}\n\n/**\n * Re-applies a <select>'s value once its children are built (called by the\n * element factory): the options it needs exist only now.\n */\nexport function retrySelectValue(el: Element) {\n  const value = selectValues.get(el);\n  if (value !== undefined) setSelectValue(el as HTMLSelectElement, value);\n}\n\n/** Drops a reused <select>'s remembered value before its new build re-applies (or omits) it. */\nexport function forgetSelectValue(el: Element) {\n  selectValues.delete(el);\n}\n\n/**\n * Applies a resolved (non-function) attribute value to an element.\n *\n * Module-level rather than a closure inside applySingleAttribute so neither\n * the static-attribute path (the bulk of attributes in list rows) nor a\n * reactive attribute (it is the registered applier, `merge` left unset)\n * allocates anything per attribute.\n *\n * Returns false when the write did not take (see setSelectValue), which keeps\n * a reactive value from being cached until it does.\n */\nfunction setAttributeValue(\n  el: Element,\n  key: string,\n  v: unknown,\n  merge?: boolean,\n): boolean | void {\n  if (v == null) return;\n\n  // Special handling for className to merge instead of replace (only for non-reactive updates)\n  if (merge && key === 'className') {\n    mergeStaticClassName(el, String(v));\n    return;\n  }\n\n  // SVG elements should always use setAttribute for most attributes\n  // because many SVG properties are read-only (className included)\n  if (el instanceof Element && el.namespaceURI === SVG_NAMESPACE) {\n    el.setAttribute(key === 'className' ? 'class' : key, String(v));\n  } else if (key in el) {\n    // For HTML elements, try to set as property first\n    if (key === 'value' && el.localName === 'select') return setSelectValue(el as HTMLSelectElement, v);\n    try {\n      (el as unknown as Record<string, unknown>)[key] = v;\n    } catch {\n      // If property is read-only, fall back to setAttribute\n      if (el instanceof Element) {\n        el.setAttribute(key, String(v));\n      }\n    }\n  } else if (el instanceof Element) {\n    el.setAttribute(key, String(v));\n  }\n}\n\nfunction applyReactiveClassName(el: Element, _key: string, v: unknown) {\n  mergeReactiveClassName(el, String(v || ''));\n}\n\nexport function applySingleAttribute<TTagName extends ElementTagName>(\n  el: ExpandedElement<TTagName>,\n  key: AttributeKey<TTagName>,\n  raw: AttributeCandidate<TTagName> | undefined,\n  shouldMergeClassName = false,\n) {\n  if (raw == null) return;\n  const k = key as string;\n\n  if (k === \"style\") {\n    applyStyleAttribute(el, raw as unknown as ValueOrFactory<CSSStyleObject>);\n    return;\n  }\n\n  if (isFunction(raw)) {\n    // onMount/onDestroy aren't real DOM events (no native onmount/ondestroy\n    // IDL property exists) — checked first so they never fall into the\n    // generic on* handling below, which would silently register a dead\n    // addEventListener(\"mount\"/\"destroy\", ...) that the browser never fires.\n    if (k === \"onMount\") {\n      registerMount(el as unknown as Element, raw as MountCallback<Element>);\n      return;\n    }\n    if (k === \"onDestroy\") {\n      registerDestroy(el as unknown as Element, raw as DestroyCallback<Element>);\n      return;\n    }\n\n    // Keep the dominant event path free of event-name normalization.\n    if (k === \"onClick\") {\n      setEventAttribute(el as HTMLElement, \"onclick\", raw as EventListener);\n      return;\n    }\n\n    if (\n      k.charCodeAt(0) === 111 /* o */\n      && k.charCodeAt(1) === 110 /* n */\n    ) {\n      // Camel-cased `on*` props are handlers, not reactive value resolvers.\n      const eventProperty = eventAttributeToProperty(k);\n      if (eventProperty) {\n        setEventAttribute(el as HTMLElement, eventProperty, raw as EventListener);\n        return;\n      }\n\n      // Preserve runtime compatibility for native lowercase IDL properties\n      // passed from untyped JavaScript. Public types reject these names.\n      if (k in el) {\n        setEventAttribute(el as HTMLElement, k, raw as EventListener);\n        return;\n      }\n    }\n\n    if (raw.length === 0) {\n      // Type narrowing: zero-arity function that returns an attribute value\n      const resolver = raw as () => AttributeCandidate<TTagName>;\n\n      // For reactive className, we need to track which classes are reactive\n      // so we can preserve static classes when the reactive className changes\n      if (k === 'className') {\n        initReactiveClassName(el as unknown as Element);\n        registerAttributeResolver(el, k, resolver, applyReactiveClassName);\n      } else {\n        registerAttributeResolver(el, k, resolver, setAttributeValue);\n      }\n      return;\n    }\n    // Non-event functions with parameters fall through and are assigned as-is\n    // (same as any other static value), matching previous behavior.\n  }\n\n  // Static attributes should merge classNames\n  // For className, if there's already a reactive className, add to static classes\n  const node = el as unknown as Element;\n  if (k === 'className' && hasReactiveClassName(node)) {\n    // There's already a reactive className; update the tracked set and DOM atomically.\n    const newClassName = String(raw || '');\n    if (newClassName) {\n      addStaticClasses(node, newClassName);\n      mergeStaticClassName(node, newClassName);\n    }\n    return;\n  }\n  setAttributeValue(node, k, raw, shouldMergeClassName);\n}\n\nexport function applyAttributes<TTagName extends ElementTagName>(\n  element: ExpandedElement<TTagName>,\n  attributes: ExpandedElementAttributes<TTagName>,\n  mergeClassName = true,\n) {\n  // An <input>'s value is sanitized against its type/min/max/step as they\n  // stand when it is written (a range input clamps it), so it is applied\n  // after the object's other keys — `{ value: 150, max: 200 }` must not\n  // clamp to the default max of 100.\n  let valueLast = false;\n  // for-in over Object.keys() avoids allocating a key array per element —\n  // attribute objects are always plain literals, so no prototype keys leak in.\n  for (const k in attributes) {\n    if (k === 'value' && (element as unknown as Element).localName === 'input') {\n      valueLast = true;\n      continue;\n    }\n    const key = k as AttributeKey<TTagName>;\n    const value = (attributes as Record<string, unknown>)[k] as\n      AttributeCandidate<TTagName> | undefined;\n    // Only merge className for non-className keys OR when explicitly enabled for className\n    const shouldMerge = mergeClassName && key === 'className';\n    applySingleAttribute(element, key, value, shouldMerge);\n  }\n  if (valueLast) {\n    applySingleAttribute(\n      element,\n      'value' as AttributeKey<TTagName>,\n      (attributes as Record<string, unknown>).value as AttributeCandidate<TTagName> | undefined,\n    );\n  }\n}\n","/**\n * Interprets every argument passed to a tag builder: strings/numbers become\n * text nodes, objects become attributes, functions become reactive text or\n * nested builders, Nodes are appended as-is.\n */\nimport { applyAttributes } from \"./attributes\";\nimport { createReactiveTextNode, toText } from \"../update/reactive-text\";\nimport { cleanupReactiveTextNode, registerReactiveTextNode } from \"../update/registry\";\nimport { logError } from \"../shared/errors\";\nimport { isFunction, isNode, isObject, isPrimitive, isZeroArityFunction } from \"../shared/type-guards\";\nimport { isHydrating, isForceHydrating, isSerializing, claimBareText, claimChild, peekChild, setCursor, skipWhitespaceText } from \"../hydration\";\nimport { isBrowser } from \"../shared/environment\";\nimport { createMarker } from \"../shared/dom\";\n\nexport type NodeModifier<TTagName extends ElementTagName = ElementTagName> =\n\t| NodeMod<TTagName>\n\t| NodeModFn<TTagName>\n\t| AnyParentNodeModifier;\n\n/**\n * Shape of a css()/cx() StyleResult: an object whose only own key is\n * `className`. Typed as readonly to signal it should not be mutated.\n */\ninterface ClassNameOnlyObject {\n\treadonly className: string;\n}\n\nfunction isClassNameOnlyObject(v: unknown): v is ClassNameOnlyObject {\n\treturn (\n\t\tisObject(v) &&\n\t\t!isNode(v) &&\n\t\t'className' in v &&\n\t\ttypeof (v as { className: unknown }).className === 'string' &&\n\t\tObject.keys(v).length === 1\n\t);\n}\n\nfunction nextChildIsTextComment(parent: Node) {\n\tskipWhitespaceText(parent);\n\tconst child = peekChild(parent);\n\treturn !!child && child.nodeType === 8 &&\n\t\t(child as Comment).textContent?.trimStart().startsWith('text-') === true;\n}\n\n/**\n * Claims the text node that follows an already-claimed `<!-- text-N -->`\n * marker and patches its content to the client value.\n *\n * The HTML parser drops empty text nodes, so SSR output for an empty string\n * has a marker with no text node after it — in that case a fresh text node is\n * inserted at the cursor to keep the DOM identical to a client render.\n * Content mismatches (data changed between SSR and hydration) are patched so\n * hydration always converges on the client value.\n */\nfunction claimTextAfterMarker(parent: Node, expected: string): Text {\n\tconst next = peekChild(parent);\n\tif (next && next.nodeType === 3) {\n\t\tclaimChild(parent);\n\t\tif (next.textContent !== expected) {\n\t\t\tnext.textContent = expected;\n\t\t}\n\t\treturn next as Text;\n\t}\n\tconst created = document.createTextNode(expected);\n\tparent.insertBefore(created, next);\n\tsetCursor(parent, next);\n\treturn created;\n}\n\nexport function applyNodeModifier<TTagName extends ElementTagName>(\n\tparent: ExpandedElement<TTagName>,\n\tmodifier: NodeModifier<TTagName>,\n\tindex: number,\n): Node | null {\n\tif (modifier == null) return null;\n\n\tif (isFunction(modifier)) {\n\t\t// Handle zero-argument functions (reactive text or reactive className)\n\t\tif (isZeroArityFunction(modifier)) {\n\t\t\ttry {\n\t\t\t\tconst v = modifier();\n\n\t\t\t\t// A css()/cx() result (only own key: a `className` string) makes this a\n\t\t\t\t// reactive className instead of reactive text.\n\t\t\t\tif (isClassNameOnlyObject(v)) {\n\t\t\t\t\tconst classNameFn = (): string => {\n\t\t\t\t\t\tconst result = modifier();\n\t\t\t\t\t\treturn isClassNameOnlyObject(result) ? result.className : \"\";\n\t\t\t\t\t};\n\t\t\t\t\tapplyAttributes(parent, { className: classNameFn } as ExpandedElementAttributes<TTagName>);\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\n\t\t\t\tif (isPrimitive(v)) {\n\t\t\t\t\t// Nullish probes register as empty reactive text instead of being\n\t\t\t\t\t// dropped: a resolver with no value yet (data still loading) must\n\t\t\t\t\t// stay reactive so a later update() can fill it in. The resolver is\n\t\t\t\t\t// registered raw — the notify pass renders nullish/non-primitive\n\t\t\t\t\t// results as \"\" — so no wrapper closure is allocated per text node.\n\t\t\t\t\tif (isHydrating()) {\n\t\t\t\t\t\tconst parentNode = parent as unknown as Node;\n\t\t\t\t\t\tconst expected = toText(v);\n\t\t\t\t\t\t// forceUpdate(): client-rendered text nodes carry no marker —\n\t\t\t\t\t\t// claim the bare text node, patch it, swap in the new resolver.\n\t\t\t\t\t\tif (isForceHydrating()) {\n\t\t\t\t\t\t\tconst claimed = claimBareText(parentNode);\n\t\t\t\t\t\t\tif (claimed) {\n\t\t\t\t\t\t\t\tif (claimed.textContent !== expected) claimed.textContent = expected;\n\t\t\t\t\t\t\t\tregisterReactiveTextNode(claimed, modifier, expected);\n\t\t\t\t\t\t\t\treturn null;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (nextChildIsTextComment(parentNode)) {\n\t\t\t\t\t\t\tclaimChild(parentNode); // skip <!-- text-N --> comment\n\t\t\t\t\t\t\tregisterReactiveTextNode(claimTextAfterMarker(parentNode, expected), modifier, expected);\n\t\t\t\t\t\t\treturn null;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn wrapTextNode(index, createReactiveTextNode(modifier, v));\n\t\t\t\t}\n\t\t\t\treturn null;\n\t\t\t} catch (error) {\n\t\t\t\tlogError(\"Error evaluating reactive text function:\", error);\n\t\t\t\treturn wrapTextNode(index, createReactiveTextNode(emptyText, \"\"));\n\t\t\t}\n\t\t}\n\n\t\t// Handle NodeModFn functions\n\t\tconst produced = (modifier as NodeModFn<TTagName>)(parent, index);\n\t\tif (produced == null) return null;\n\t\tif (isPrimitive(produced)) return wrapTextNode(index, document.createTextNode(String(produced)));\n\t\tif (isNode(produced)) return produced;\n\t\tif (isObject(produced)) {\n\t\t\tapplyAttributes(parent, produced as ExpandedElementAttributes<TTagName>);\n\t\t}\n\t\treturn null;\n\t}\n\n\t// Handle non-function modifiers\n\tconst candidate = modifier as NodeMod<TTagName>;\n\tif (isPrimitive(candidate)) {\n\t\tif (isHydrating()) {\n\t\t\tconst parentNode = parent as unknown as Node;\n\t\t\tconst expected = String(candidate);\n\t\t\t// forceUpdate(): claim and patch the bare client-rendered text node.\n\t\t\t// The node may have been reactive in the previous build (the tree\n\t\t\t// shifted) — unregister it, or the next update() would overwrite\n\t\t\t// this static text with the stale resolver's value.\n\t\t\tconst force = isForceHydrating();\n\t\t\tif (force) {\n\t\t\t\tconst claimed = claimBareText(parentNode);\n\t\t\t\tif (claimed) {\n\t\t\t\t\tcleanupReactiveTextNode(claimed);\n\t\t\t\t\tif (claimed.textContent !== expected) claimed.textContent = expected;\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (nextChildIsTextComment(parentNode)) {\n\t\t\t\tclaimChild(parentNode); // skip <!-- text-N --> comment\n\t\t\t\tconst claimed = claimTextAfterMarker(parentNode, expected);\n\t\t\t\tif (force) cleanupReactiveTextNode(claimed);\n\t\t\t\treturn null;\n\t\t\t}\n\t\t}\n\t\treturn wrapTextNode(index, document.createTextNode(String(candidate)));\n\t}\n\tif (isNode(candidate)) return candidate;\n\tapplyAttributes(parent, candidate as ExpandedElementAttributes<TTagName>);\n\treturn null;\n}\n\n/**\n * Wraps a freshly created text node for insertion.\n *\n * The `<!-- text-N -->` marker only exists so hydration can pair an SSR text\n * node with its client resolver. A pure client render never hydrates, so the\n * marker (and the DocumentFragment that carries it) is dead weight: two extra\n * DOM nodes and a fragment allocation per text child that nothing ever reads.\n * In that case we return the bare text node — halving the per-row DOM node\n * count and the DOM inserts in list-heavy renders.\n *\n * SSR (isBrowser === false, or renderToString's serialization mode) and the\n * hydration-mismatch fresh-render path keep the marker so the emitted/repaired\n * DOM stays hydratable.\n */\nfunction wrapTextNode(index: number, textNode: Text): Node {\n\tif (isBrowser && !isHydrating() && !isSerializing()) {\n\t\treturn textNode;\n\t}\n\tconst fragment = document.createDocumentFragment();\n\tfragment.appendChild(createMarker(` text-${index} `));\n\tfragment.appendChild(textNode);\n\treturn fragment;\n}\n\n/** Resolver for text whose first evaluation threw: stays empty. */\nfunction emptyText() {\n\treturn \"\";\n}\n","import { clearBetweenMarkers, insertNodesBefore, withScopedInsertion } from \"../shared/dom\";\nimport { all, membersOf, track, WHEN_KIND, type UpdateScope } from \"../update/scope\";\nimport { applyNodeModifier } from \"../element/modifiers\";\nimport { getFactoryMods } from \"../element/factory-meta\";\nimport { mountQueueMark, cancelMountsSince } from \"../element/lifecycle\";\nimport { isFunction, isZeroArityFunction } from \"../shared/type-guards\";\nimport { logError } from \"../shared/errors\";\n\nexport interface WhenGroup<TTagName extends ElementTagName = ElementTagName> {\n  condition: WhenCondition;\n  content: ReadonlyArray<WhenContent<TTagName>>;\n}\n\nexport interface WhenRuntime<TTagName extends ElementTagName = ElementTagName> {\n  startMarker: Comment;\n  endMarker: Comment;\n  host: ExpandedElement<TTagName>;\n  index: number;\n  groups: ReadonlyArray<WhenGroup<TTagName>>;\n  elseContent: ReadonlyArray<WhenContent<TTagName>>;\n  /**\n   * Tracks which branch is currently rendered:\n   *  - null:  nothing rendered yet (initial state)\n   *  - -1:    else branch is active\n   *  - >= 0:  groups[activeIndex] is active\n   */\n  activeIndex: number | null;\n}\n\n/**\n * Registry of active when runtimes.\n *\n * The iteration set only holds WeakRefs; the runtime itself lives in a\n * WeakMap keyed by its start marker. This keeps the global registry free of\n * strong references to the runtime (which holds the host element, branch\n * content, and markers), so removing the surrounding DOM subtree makes the\n * runtime collectible — even if update() is never called again. The\n * FinalizationRegistry prunes dead WeakRefs once the marker is collected;\n * updateWhenRuntimes() also prunes as it iterates.\n */\nconst activeWhenRuntimes = all[WHEN_KIND] as Set<WeakRef<Comment>>;\nconst whenRuntimeByMarker = new WeakMap<Comment, WhenRuntime<ElementTagName>>();\nconst whenMarkerFinalizer = typeof FinalizationRegistry !== \"undefined\"\n  ? new FinalizationRegistry<WeakRef<Comment>>((ref) => { activeWhenRuntimes.delete(ref); })\n  : null;\n\n/**\n * Evaluates which condition branch should be active.\n * Returns the index of the first truthy condition, -1 for else branch, or null for no match.\n */\nexport function evaluateActiveCondition<TTagName extends ElementTagName>(\n  groups: ReadonlyArray<WhenGroup<TTagName>>,\n  elseContent: ReadonlyArray<WhenContent<TTagName>>\n): number | null {\n  for (let i = 0; i < groups.length; i++) {\n    const condition = groups[i].condition;\n    if (typeof condition === \"function\" ? condition() : condition) {\n      return i;\n    }\n  }\n  return elseContent.length > 0 ? -1 : null;\n}\n\n/**\n * Main render function for when/else conditionals.\n * Evaluates conditions, clears old content, and renders the active branch.\n */\nexport function renderWhenContent<TTagName extends ElementTagName>(\n  runtime: WhenRuntime<TTagName>\n) {\n  const { groups, elseContent, host, index, endMarker } = runtime;\n\n  const newActive = evaluateActiveCondition(groups, elseContent);\n\n  // No change needed\n  if (newActive === runtime.activeIndex) return;\n\n  // Clear previous content and update active index\n  clearBetweenMarkers(runtime.startMarker, runtime.endMarker);\n  runtime.activeIndex = newActive;\n\n  // Nothing to render\n  if (newActive === null) return;\n\n  // Render the active branch\n  const contentToRender = newActive >= 0 ? groups[newActive].content : elseContent;\n  renderContentItems(contentToRender, host, index, endMarker);\n}\n\n/**\n * Registers a when runtime for tracking and updates.\n * Uses WeakRef to prevent memory leaks when elements are removed.\n * The runtime object itself is mutable and will be updated in place.\n */\nexport function registerWhenRuntime<TTagName extends ElementTagName>(\n  runtime: WhenRuntime<TTagName>\n) {\n  const existing = whenRuntimeByMarker.get(runtime.startMarker);\n  whenRuntimeByMarker.set(runtime.startMarker, runtime as WhenRuntime<ElementTagName>);\n  // Re-registration for the same markers (forceUpdate() reclaim): the new\n  // runtime replaced the old in the WeakMap; the iteration set and finalizer\n  // already track this marker, so adding again would only grow the set.\n  if (existing) return;\n  const ref = new WeakRef(runtime.startMarker);\n  track(WHEN_KIND, ref);\n  whenMarkerFinalizer?.register(runtime.startMarker, ref);\n}\n\n/** The live runtime registered for a claimed start marker, if any. */\nexport function getWhenRuntime(startMarker: Comment): WhenRuntime<ElementTagName> | undefined {\n  return whenRuntimeByMarker.get(startMarker);\n}\n\n/**\n * Updates all active when/else conditional runtimes.\n *\n * Re-evaluates all conditional branches and re-renders if the active branch has changed.\n * Automatically cleans up runtimes that are garbage collected or disconnected from DOM.\n *\n * This function should be called after state changes that affect conditional expressions.\n *\n * @example\n * ```ts\n * isLoggedIn.value = true;\n * updateWhenRuntimes(); // All when() conditionals re-evaluate\n * ```\n */\nexport function updateWhenRuntimes(scope?: UpdateScope) {\n  if (!scope) return updateWhenSet(activeWhenRuntimes);\n  for (const root of scope.roots) updateWhenSet(membersOf(root, WHEN_KIND) as Set<WeakRef<Comment>>);\n}\n\n/** `set` is the global registry or one scope root's members; pruning hits both. */\nfunction updateWhenSet(set: Set<WeakRef<Comment>>) {\n  for (const ref of set) {\n    const startMarker = ref.deref();\n\n    // Comment node was garbage collected\n    if (startMarker === undefined) {\n      set.delete(ref);\n      activeWhenRuntimes.delete(ref);\n      continue;\n    }\n\n    const runtime = whenRuntimeByMarker.get(startMarker);\n    if (!runtime) {\n      set.delete(ref);\n      activeWhenRuntimes.delete(ref);\n      continue;\n    }\n\n    // Check if markers are still connected to DOM\n    if (!startMarker.isConnected || !runtime.endMarker.isConnected) {\n      whenRuntimeByMarker.delete(startMarker);\n      set.delete(ref);\n      activeWhenRuntimes.delete(ref);\n      continue;\n    }\n\n    const mark = mountQueueMark();\n    try {\n      renderWhenContent(runtime);\n    } catch (error) {\n      // Clean up runtimes that throw errors\n      logError(\"when() branch threw during update; unregistering this conditional\", error);\n      whenRuntimeByMarker.delete(startMarker);\n      set.delete(ref);\n      activeWhenRuntimes.delete(ref);\n      // Content built but never inserted must not mount on the next flush.\n      cancelMountsSince(mark);\n    }\n  }\n}\n\n// ─── Content rendering ───────────────────────────────────────────────────────\n/**\n * Renders a single content item and returns the resulting node if any.\n */\nfunction renderContentItem<TTagName extends ElementTagName>(\n  item: WhenContent<TTagName>,\n  host: ExpandedElement<TTagName>,\n  index: number,\n  endMarker: Node\n): Node | null {\n  // Primitives, attribute objects, reactive text and tag-builder factories\n  // (which build their element detached) never append to the host themselves:\n  // the caller inserts whatever node comes back. Keeping them off the scoped\n  // path matters — it adds and deletes an own `appendChild` on the host, which\n  // drops the element out of the engine's fast property mode for good.\n  if (!isFunction(item) || isZeroArityFunction(item) || getFactoryMods(item) !== undefined) {\n    return applyNodeModifier(host, item, index);\n  }\n\n  // Other functions (nested when()/list() blocks, custom modifiers) may append\n  // to the host: scope those appends so they land before endMarker.\n  return withScopedInsertion(host, endMarker, () => {\n    const maybeNode = applyNodeModifier(host, item, index);\n    // Only include nodes that weren't already inserted\n    return maybeNode && !maybeNode.parentNode ? maybeNode : null;\n  });\n}\n\n/**\n * Renders a list of content items before `endMarker` (any reference node in\n * the host — a region inserts ahead of its unclaimed server markup), in\n * source order.\n *\n * Each node is inserted as soon as its item produces it: nested when()/list()\n * blocks insert their own markers while they run, so collecting the element\n * nodes and inserting them afterwards would put every nested block ahead of\n * the siblings written before it.\n */\nexport function renderContentItems<TTagName extends ElementTagName>(\n  items: ReadonlyArray<WhenContent<TTagName>>,\n  host: ExpandedElement<TTagName>,\n  index: number,\n  endMarker: Node\n) {\n  for (const item of items) {\n    const node = renderContentItem(item, host, index, endMarker);\n    if (node) insertNodesBefore([node], endMarker);\n  }\n}\n","/**\n * Element creation: builds HTML/SVG elements and applies the modifier list\n * that was passed to a tag builder (children, attributes, text, on(), ...).\n */\nimport { applyNodeModifier, type NodeModifier } from \"./modifiers\";\nimport { forgetSelectValue, retrySelectValue } from \"./attributes\";\nimport { SVG_NAMESPACE } from \"../shared/dom\";\nimport { claimElement, claimChild, cleanupUnclaimedChildren, isHydrating, isForceHydrating, peekChild, setCursor } from \"../hydration\";\nimport { removeAllListeners } from \"./events\";\nimport { resetClassNameTracking } from \"./class-name\";\nimport { cleanupReactiveElement } from \"../update/registry\";\nimport { acquireMetadataOnlyFactory, isMetadataOnlyFactoryMode, setFactoryMeta } from \"./factory-meta\";\n\n/**\n * Applies modifiers to an element, appending newly produced Nodes while avoiding\n * duplicate DOM insertions (i.e. only appends if parentNode differs).\n *\n * `localIndex` advances once per appended child so each reactive/static text\n * modifier gets a unique `text-N` marker; it is internal bookkeeping only and\n * is not returned (no production caller consumed the previous result object).\n */\nexport function applyModifiers<TTagName extends ElementTagName>(\n  element: ExpandedElement<TTagName>,\n  modifiers: ReadonlyArray<NodeModifier<TTagName>>,\n  startIndex = 0\n) {\n  let localIndex = startIndex;\n  const parentNode = element as unknown as Node & ParentNode;\n  // Hoisted: constant for this frame — runWithoutHydration() only affects\n  // nested calls, which hoist their own value.\n  const hydrating = isHydrating();\n  const force = isForceHydrating();\n\n  for (let i = 0; i < modifiers.length; i += 1) {\n    const mod = modifiers[i];\n    // Fast null/undefined skip\n    if (mod == null) continue;\n\n    const produced = applyNodeModifier(element, mod, localIndex);\n    if (!produced) continue;\n\n    // Only append if the node isn't already where we expect\n    if (produced.parentNode !== parentNode) {\n      // hydrate()/forceUpdate(): a fresh node (nothing to claim, or a\n      // structural mismatch) lands at the claim cursor, keeping sibling\n      // order — a plain append would put it after the cursor, where a later\n      // sibling's claim would reach it. insertBefore(x, null) === append.\n      // The cursor is then pinned explicitly: with no entry, peekChild falls\n      // back to firstChild, which the insertion may have just changed.\n      if (hydrating) {\n        const at = peekChild(parentNode);\n        parentNode.insertBefore(produced, at);\n        setCursor(parentNode, at);\n      } else {\n        parentNode.appendChild(produced);\n      }\n    } else if (force && peekChild(parentNode) === produced) {\n      // A raw Node child that is already in place (same instance passed\n      // again): claim it so cleanupUnclaimedChildren doesn't remove it.\n      claimChild(parentNode);\n    }\n    localIndex += 1;\n  }\n}\n\n/**\n * Clears state a claimed element carries from its previous build so\n * re-applying the current modifiers converges instead of accumulating.\n *\n * Every claim (hydrate() and forceUpdate()) rebuilds class state from scratch:\n * the existing class attribute is the output of className modifiers, and left\n * in place initReactiveClassName would capture it as static classes that a\n * dynamic className then adds to instead of replacing.\n *\n * forceUpdate() also detaches on() and event-attribute listeners (the re-applied modifiers\n * re-attach), drops reactive attribute resolvers (re-registered) and rebuilds\n * inline style. Attributes the new tree no longer sets keep their old values —\n * nuclo keeps no per-element attribute manifest to diff against.\n */\nfunction resetReusedElement(el: Element, force: boolean) {\n  resetClassNameTracking(el);\n  el.removeAttribute(\"class\");\n  if (!force) return;\n  removeAllListeners(el as HTMLElement);\n  cleanupReactiveElement(el);\n  el.removeAttribute(\"style\");\n}\n\n/**\n * Creates an element factory for `tagName` with the given modifiers. SVG\n * factories create namespaced elements and stay opaque to the list() template\n * engine (no factory metadata outside metadata-only mode), so rows containing\n * SVG always build through the normal path.\n */\nfunction createElementFactory(tagName: string, modifiers: ReadonlyArray<unknown>, svg: boolean): unknown {\n  if (isMetadataOnlyFactoryMode()) {\n    const stub = acquireMetadataOnlyFactory();\n    setFactoryMeta(stub, tagName, modifiers);\n    return stub;\n  }\n\n  const factory = function(parent?: Node, index = 0): Element {\n    const claimed = parent ? claimElement(parent, tagName) : null;\n    if (claimed) {\n      resetReusedElement(claimed, isForceHydrating());\n      if (tagName === \"select\") forgetSelectValue(claimed);\n    }\n    const el = claimed ?? (svg ? document.createElementNS(SVG_NAMESPACE, tagName) : document.createElement(tagName));\n    const lastOriginalChild = claimed ? el.lastChild : null;\n    applyModifiers(el as unknown as ExpandedElement, modifiers as ReadonlyArray<NodeModifier>, index);\n    if (claimed) cleanupUnclaimedChildren(el, lastOriginalChild);\n    // A select's value can only be applied once its options are in place.\n    if (tagName === \"select\") retrySelectValue(el);\n    return el;\n  };\n  // Lets the list() template engine see the factory's structure (internal\n  // symbols — invisible to the public API).\n  if (!svg) setFactoryMeta(factory, tagName, modifiers);\n  return factory;\n}\n\n/**\n * Creates an HTML tag builder function.\n */\nexport function createHtmlTagBuilder<TTagName extends ElementTagName>(\n  tagName: TTagName,\n): ExpandedElementBuilder<TTagName> {\n  return (...mods) => createElementFactory(tagName, mods, false) as DetachedExpandedElementFactory<TTagName>;\n}\n\n/**\n * Creates an SVG tag builder function.\n */\nexport function createSvgTagBuilder<TTagName extends keyof SVGElementTagNameMap>(\n  tagName: TTagName,\n): ExpandedSVGElementBuilder<TTagName> {\n  return (...mods) => createElementFactory(tagName, mods, true) as DetachedSVGElementFactory<TTagName>;\n}\n","import { clearBetweenMarkers, safeRemoveChild } from \"../shared/dom\";\nimport { renderContentItems } from \"../when/runtime\";\nimport { isHydrating, peekChild, setCursor } from \"../hydration\";\nimport { isSerializing, serializingScratch } from \"../shared/serializing\";\nimport { applyModifiers } from \"../element/factory\";\nimport { isMounted, setNodeDisposer } from \"../element/lifecycle\";\nimport type { NodeModifier } from \"../element/modifiers\";\n\n/**\n * One into() placement. A view is a portal: its content lives between its\n * region's markers, and the view itself is a single `<!--view-N-->` anchor\n * comment standing where it was written. The anchor is what ties the content\n * to the view's own lifetime — when nuclo removes the anchor (its when()\n * closes, its list() row goes, its tree is replaced), the content leaves the\n * region with it, and a view whose region has not been built yet waits for\n * as long as its anchor is in the tree.\n */\nexport interface ViewRuntime {\n  id: string;\n  content: readonly WhenContent<ElementTagName>[];\n  anchor: Comment;\n  /**\n   * The region showing this view; null while it waits for one. Held weakly,\n   * like everything else that points into the DOM: a view outlives a region\n   * wiped behind nuclo's back, and must not keep that layout in memory. A\n   * region collected under a view leaves it orphaned until the next region\n   * with its id takes it — see takeOrphans().\n   */\n  region: WeakRef<RegionRuntime<ElementTagName>> | null;\n  /** Its entry in the waiting list, while it waits. */\n  pendingRef: WeakRef<Comment> | null;\n  /** Its entry in the placed list, while a region holds it. */\n  placedRef?: WeakRef<Comment> | null;\n  /**\n   * First and last top-level node of its content between the region's\n   * markers, both null when the content produced nothing. Top-level nodes are\n   * stable: a nested list()/when() only ever changes what sits between its own\n   * markers, so the range stays correct until the region or the view drops it.\n   * Weak for the same reason as `region`.\n   */\n  first: WeakRef<Node> | null;\n  last: WeakRef<Node> | null;\n}\n\n/**\n * A region is a named place in the tree; `into()` calls fill it from anywhere\n * else, in any order. The region owns a marker pair and every view's content\n * is inserted between them.\n */\nexport interface RegionRuntime<TTagName extends ElementTagName = ElementTagName> {\n  id: string;\n  type: RegionType;\n  empty: readonly WhenContent<TTagName>[];\n  startMarker: Comment;\n  endMarker: Comment;\n  host: ExpandedElement<TTagName>;\n  index: number;\n  /** The views it shows, in arrival order — one at most for \"latest\". */\n  views: ViewRuntime[];\n  /**\n   * \"latest\" only: the views a newer one replaced, oldest first. They keep\n   * their place so the one underneath shows again — rebuilt — when the view\n   * on top leaves, which is what lets a layer open over a page in a latest\n   * region and close without taking the page with it.\n   */\n  hidden: ViewRuntime[];\n  /** True while the `empty` content occupies the markers. */\n  showingEmpty: boolean;\n  /**\n   * Server markup between the markers that no into() has claimed yet, and the\n   * cursor to claim it from. Null outside a hydration pass. The region's own\n   * host cursor is parked past the end marker as usual — the host keeps\n   * hydrating its later children — so claiming swaps this one in and out.\n   */\n  claimCursor: Node | null;\n  claiming: boolean;\n  /**\n   * Views that arrived while one was being placed — a view's content placing\n   * another view into the same region. Placed once the first is done, in\n   * order, so neither's node range swallows the other's.\n   */\n  deferred: Array<[ViewRuntime, ViewRuntime | null]> | null;\n}\n\n/**\n * Regions are addressed by id, which has to survive until an into() looks it\n * up, but must not keep a detached layout alive. Same shape as the when()\n * registry: the id map holds only a WeakRef to the start marker (which the DOM\n * holds strongly while it is in the tree) and the runtime hangs off it in a\n * WeakMap, so dropping the subtree drops the runtime, its host and its\n * content. Views waiting for a region are kept the same way, by a WeakRef to\n * their anchor, and so are the views a region shows: a view holds its region\n * only weakly, so the placed list is how a region that takes the id over\n * finds the views of one that was collected.\n *\n * This registry belongs to one page. On a server the same module scope serves\n * every request and every user at once, so a server tree never touches it —\n * it gets one that lives and dies with the one renderToString() call, which\n * is also the only window in which its regions can be looked up.\n */\ninterface Registry {\n  /** region id → start marker of the live region. */\n  regions: Map<string, WeakRef<Comment>>;\n  /** region id → anchors of the views waiting for it, in arrival order. */\n  pending: Map<string, Set<WeakRef<Comment>>>;\n  /** region id → anchors of the views a region with this id shows or hides, in arrival order. */\n  placed: Map<string, Set<WeakRef<Comment>>>;\n}\n\nfunction emptyRegistry(): Registry {\n  return { regions: new Map(), pending: new Map(), placed: new Map() };\n}\n\nconst page: Registry = emptyRegistry();\nconst runtimeByMarker = new WeakMap<Comment, RegionRuntime<ElementTagName>>();\nconst viewsByAnchor = new WeakMap<Comment, ViewRuntime[]>();\n\nconst SSR_KEY = \"region.registry\";\n\n/** The registry for whoever is asking: this page, or this request. */\nfunction registry(): Registry {\n  if (!isSerializing()) return page;\n  const scratch = serializingScratch();\n  let reg = scratch.get(SSR_KEY) as Registry | undefined;\n  if (!reg) scratch.set(SSR_KEY, (reg = emptyRegistry()));\n  return reg;\n}\n\n/**\n * Prunes the page registry once a marker is collected — the case nuclo never\n * saw the removal (a container's innerHTML wiped). A region's entry goes by\n * id; a waiting view's entry is unregistered as soon as it is placed or its\n * anchor is removed, so only the wiped ones ever reach the callback.\n */\nconst markerFinalizer = typeof FinalizationRegistry !== \"undefined\"\n  ? new FinalizationRegistry<{ id: string; ref: WeakRef<Comment>; waiting: boolean }>(({ id, ref, waiting }) => {\n      if (waiting) forgetPending(page, id, ref);\n      else if (page.regions.get(id) === ref) page.regions.delete(id);\n    })\n  : null;\n\n/** Regions holding unclaimed server markup, swept when the pass ends. */\nconst claimingRegions: Array<RegionRuntime<ElementTagName>> = [];\n\n/**\n * A marker nuclo once attached that is no longer in the document: its tree\n * was dropped behind nuclo's back (a container's innerHTML wiped), so nothing\n * disposed it. Until it is collected it would still answer lookups — a region\n * would take views meant for its replacement, and a view would render stale\n * content into a region built later. A marker that was never attached is a\n * tree still being built, which is detached by design. The same test every\n * other registry applies on update().\n */\nfunction dropped(marker: Comment) {\n  return isMounted(marker) && !marker.isConnected;\n}\n\n/** Unregisters a region; its views go back to waiting for the next one with this id. */\nexport function dropRegion(rt: RegionRuntime<ElementTagName>) {\n  runtimeByMarker.delete(rt.startMarker);\n  const reg = registry();\n  if (reg.regions.get(rt.id)?.deref() === rt.startMarker) reg.regions.delete(rt.id);\n  const shown = [...rt.hidden, ...rt.views];\n  rt.hidden.length = 0;\n  rt.views.length = 0;\n  for (const view of shown) {\n    detach(view);\n    // A view whose own tree was wiped along with the region has no one left\n    // to wait for.\n    if (!dropped(view.anchor)) pendView(view);\n  }\n}\n\n/**\n * update()'s pass over the registry: a region or a into (waiting or shown) in\n * a tree that left the document behind nuclo's back is let go of now rather\n * than on its next lookup, so a live view does not keep a wiped layout alive,\n * and a wiped view neither stays in a live region nor waits for one.\n */\nexport function pruneRegions() {\n  const reg = registry();\n  for (const [id, waiting] of reg.pending) {\n    for (const ref of waiting) {\n      const anchor = ref.deref();\n      if (anchor && !dropped(anchor)) continue;\n      waiting.delete(ref);\n      if (!isSerializing()) markerFinalizer?.unregister(ref);\n      const view = anchor && viewsByAnchor.get(anchor)?.find((v) => v.pendingRef === ref);\n      if (view) view.pendingRef = null;\n    }\n    if (waiting.size === 0) reg.pending.delete(id);\n  }\n  for (const [id, placed] of reg.placed) {\n    for (const ref of placed) if (!ref.deref()) placed.delete(ref);\n    if (placed.size === 0) reg.placed.delete(id);\n  }\n  for (const [id, ref] of reg.regions) {\n    const marker = ref.deref();\n    if (!marker) {\n      reg.regions.delete(id);\n      continue;\n    }\n    const rt = runtimeByMarker.get(marker);\n    if (!rt) continue;\n    if (dropped(marker)) {\n      dropRegion(rt);\n      continue;\n    }\n    for (const view of [...rt.hidden, ...rt.views]) if (dropped(view.anchor)) removeView(view);\n  }\n}\n\nexport function registerRegion<TTagName extends ElementTagName>(runtime: RegionRuntime<TTagName>) {\n  const rt = runtime as unknown as RegionRuntime<ElementTagName>;\n  const reg = registry();\n  const previous = reg.regions.get(rt.id)?.deref();\n  // Two regions answering to the same id are fighting over the same views:\n  // whichever registered last wins and the other stays empty forever. Only a\n  // region already in the document is caught here — two written side by side\n  // in one tree are both detached until render() inserts them, and nothing\n  // distinguishes that from the ordinary case of a replaced tree re-using its\n  // id.\n  if (previous && previous !== rt.startMarker && previous.isConnected) {\n    console.warn(\n      `nuclo: two regions share the id \"${rt.id}\". Every into(\"${rt.id}\", …) now ` +\n        \"goes to the one built last; the other stays empty. Give each region its own id.\",\n    );\n  } else if (previous && previous !== rt.startMarker && dropped(previous)) {\n    // The id is being re-used by the replacement of a wiped tree: views that\n    // were showing in the old region (from trees still alive) come over.\n    const old = runtimeByMarker.get(previous);\n    if (old) dropRegion(old);\n  }\n  const known = runtimeByMarker.has(rt.startMarker);\n  const ref = new WeakRef(rt.startMarker);\n  reg.regions.set(rt.id, ref);\n  runtimeByMarker.set(rt.startMarker, rt);\n  // The finalizer prunes the page-lifetime map only; the request-scoped one is\n  // dropped wholesale when the render ends. A marker re-registered by a later\n  // pass is already on the finalizer's books.\n  if (!known && !isSerializing()) markerFinalizer?.register(rt.startMarker, { id: rt.id, ref, waiting: false });\n  setNodeDisposer(rt.startMarker, onMarkerDisposed);\n  if (rt.claiming) claimingRegions.push(rt);\n  // The region takes the views that were waiting for it, in the order they\n  // arrived — then those of an earlier region with this id that was collected\n  // before nuclo saw it go, as update() would have handed them on.\n  const waiting = reg.pending.get(rt.id);\n  if (waiting) {\n    reg.pending.delete(rt.id);\n    for (const anchorRef of waiting) {\n      if (!isSerializing()) markerFinalizer?.unregister(anchorRef);\n      const view = waitingView(anchorRef, rt.id);\n      if (!view) continue;\n      view.pendingRef = null;\n      addView(rt, view, null);\n    }\n  }\n  for (const view of takeOrphans(reg, rt.id)) addView(rt, view, null);\n}\n\n/**\n * The views whose region with this id was collected — a layout wiped behind\n * nuclo's back with no update() since — in arrival order, taken off the\n * placed list. Views wiped along with it are left behind.\n */\nfunction takeOrphans(reg: Registry, id: string): ViewRuntime[] {\n  const placed = reg.placed.get(id);\n  if (!placed) return [];\n  const orphans: ViewRuntime[] = [];\n  for (const ref of placed) {\n    const anchor = ref.deref();\n    const view = anchor && viewsByAnchor.get(anchor)?.find((v) => v.placedRef === ref);\n    if (view && regionOf(view)) continue;\n    placed.delete(ref);\n    if (!view) continue;\n    detach(view);\n    if (!dropped(view.anchor)) orphans.push(view);\n  }\n  if (placed.size === 0) reg.placed.delete(id);\n  return orphans;\n}\n\n/**\n * True for the anchor comment an into() left where it was written. list()\n * accepts one as a row, which is what lets a page place itself: the row is\n * the anchor, and the row leaving the list takes the content out of the region.\n */\nexport function isViewAnchor(node: Node) {\n  return node.nodeType === 8 && viewsByAnchor.has(node as Comment);\n}\n\n\n/** The live region registered under an id, if one is still in the tree. */\nexport function getRegion(id: string): RegionRuntime<ElementTagName> | undefined {\n  const reg = registry();\n  const marker = reg.regions.get(id)?.deref();\n  if (!marker) {\n    reg.regions.delete(id);\n    return undefined;\n  }\n  const rt = runtimeByMarker.get(marker);\n  if (rt && dropped(marker)) {\n    dropRegion(rt);\n    return undefined;\n  }\n  return rt;\n}\n\n/**\n * The region already live on a claimed marker pair — a forceUpdate() pass, or\n * hydrate() over a tree that is live already. Its runtime and views are kept;\n * each into() re-running in the pass then reclaims its own content in place.\n */\nexport function liveRegionAt(start: Comment, end: Comment): RegionRuntime<ElementTagName> | undefined {\n  const rt = runtimeByMarker.get(start);\n  return rt && rt.endMarker === end ? rt : undefined;\n}\n\n/** How many views are waiting for a region with this id (for tests). */\nexport function pendingViewCount(id: string) {\n  return registry().pending.get(id)?.size ?? 0;\n}\n\n/** The still-waiting view behind a pending entry, or nothing once its anchor is gone or it was placed. */\nfunction waitingView(ref: WeakRef<Comment>, id: string): ViewRuntime | undefined {\n  const anchor = ref.deref();\n  if (!anchor || dropped(anchor)) return undefined;\n  return viewsByAnchor.get(anchor)?.find((v) => v.id === id && v.region === null);\n}\n\nfunction forgetPending(reg: Registry, id: string, ref: WeakRef<Comment>) {\n  const waiting = reg.pending.get(id);\n  if (!waiting) return;\n  waiting.delete(ref);\n  if (waiting.size === 0) reg.pending.delete(id);\n}\n\n/** Queues a view for a region that does not exist yet. */\nfunction pendView(view: ViewRuntime) {\n  if (view.pendingRef) return;\n  const reg = registry();\n  let waiting = reg.pending.get(view.id);\n  if (!waiting) reg.pending.set(view.id, (waiting = new Set()));\n  const ref = new WeakRef(view.anchor);\n  view.pendingRef = ref;\n  waiting.add(ref);\n  // The ref is its own unregister token: one registration per entry.\n  if (!isSerializing()) markerFinalizer?.register(view.anchor, { id: view.id, ref, waiting: true }, ref);\n}\n\n/** Takes a view off the waiting list. */\nfunction unpend(view: ViewRuntime) {\n  const ref = view.pendingRef;\n  if (!ref) return;\n  view.pendingRef = null;\n  forgetPending(registry(), view.id, ref);\n  if (!isSerializing()) markerFinalizer?.unregister(ref);\n}\n\n/**\n * Ties the views written at one anchor to it and places each in its region —\n * or, for a region not built yet, leaves it waiting. During hydration the\n * anchor may be one claimed from a live tree, whose earlier views are then\n * replaced: a view still shown by its region reclaims that content in place,\n * and one still waiting keeps its place in the waiting list.\n */\nexport function attachViews(anchor: Comment, views: ViewRuntime[]) {\n  const earlier = viewsByAnchor.get(anchor);\n  for (const old of earlier ?? []) {\n    if (!views.some((view) => view.id === old.id)) removeView(old);\n  }\n  viewsByAnchor.set(anchor, views);\n  setNodeDisposer(anchor, onMarkerDisposed);\n  for (const view of views) {\n    const before = earlier?.find((v) => v.id === view.id) ?? null;\n    if (before) {\n      view.pendingRef = before.pendingRef;\n      before.pendingRef = null;\n    }\n    const rt = getRegion(view.id);\n    if (rt) {\n      unpend(view);\n      addView(rt, view, before);\n    } else {\n      pendView(view);\n    }\n  }\n}\n\n/** `region-start-{index}-v{views}`, so hydration knows what the server left. */\nfunction stamp(rt: RegionRuntime<ElementTagName>) {\n  rt.startMarker.textContent = `region-start-${rt.index}-v${rt.views.length}`;\n}\n\n/** Reads the view count out of an SSR start marker. */\nexport function decodeCount(markerText: string | null) {\n  const match = /-v(\\d+)$/.exec(markerText || \"\");\n  return match ? parseInt(match[1], 10) : 0;\n}\n\n/** The region showing a view: null while it waits, and once its region was collected. */\nfunction regionOf(view: ViewRuntime): RegionRuntime<ElementTagName> | null {\n  return view.region?.deref() ?? null;\n}\n\n/**\n * Records that `rt` shows `view`. A view taking over from `earlier` on the\n * same anchor (a pass re-running a live tree) takes over its placed entry too,\n * and with it its place in arrival order.\n */\nfunction showIn(view: ViewRuntime, rt: RegionRuntime<ElementTagName>, earlier: ViewRuntime | null = null) {\n  view.region = new WeakRef(rt);\n  if (earlier?.placedRef) {\n    view.placedRef = earlier.placedRef;\n    earlier.placedRef = null;\n  }\n  if (view.placedRef) return;\n  const reg = registry();\n  let placed = reg.placed.get(view.id);\n  if (!placed) reg.placed.set(view.id, (placed = new Set()));\n  view.placedRef = new WeakRef(view.anchor);\n  placed.add(view.placedRef);\n}\n\nfunction detach(view: ViewRuntime) {\n  view.region = null;\n  view.first = null;\n  view.last = null;\n  const ref = view.placedRef;\n  if (!ref) return;\n  view.placedRef = null;\n  const reg = registry();\n  const placed = reg.placed.get(view.id);\n  if (!placed) return;\n  placed.delete(ref);\n  if (placed.size === 0) reg.placed.delete(view.id);\n}\n\n/** Records which nodes a view just produced: everything between `before` and `stop`. */\nfunction setRange(view: ViewRuntime, before: Node, stop: Node) {\n  const first = before.nextSibling;\n  view.first = first === stop || !first ? null : new WeakRef(first);\n  view.last = view.first ? new WeakRef(stop.previousSibling!) : null;\n}\n\n/** Puts the region back to its `empty` content, replacing whatever it holds. */\nexport function showEmpty<TTagName extends ElementTagName>(runtime: RegionRuntime<TTagName>) {\n  const rt = runtime as unknown as RegionRuntime<ElementTagName>;\n  clearBetweenMarkers(rt.startMarker, rt.endMarker);\n  for (const view of rt.views) detach(view);\n  for (const view of rt.hidden) detach(view);\n  rt.views.length = 0;\n  rt.hidden.length = 0;\n  rt.showingEmpty = true;\n  if (rt.empty.length) renderContentItems(rt.empty, rt.host, rt.index, rt.endMarker);\n  stamp(rt);\n}\n\n/**\n * Adds one into()'s content to a region.\n *\n * \"stack\" keeps every view, bottom first — the view that arrives second opens\n * over the first without touching it, so the content underneath keeps its DOM,\n * its focus and its form state. \"latest\" keeps only the newest.\n *\n * `earlier` is the view this one replaces on the same anchor (a hydration pass\n * re-running a live tree): if the region still shows it, the new view takes\n * over its place and claims its nodes.\n */\nfunction addView(\n  rt: RegionRuntime<ElementTagName>,\n  view: ViewRuntime,\n  earlier: ViewRuntime | null,\n) {\n  // Arrived from inside the content being placed right now: its turn comes\n  // once that content is complete, so the two node ranges stay separate.\n  if (rt.deferred) {\n    rt.deferred.push([view, earlier]);\n    return;\n  }\n  rt.deferred = [];\n  try {\n    placeView(rt, view, earlier);\n  } finally {\n    const next = rt.deferred;\n    rt.deferred = null;\n    for (const [v, e] of next) addView(rt, v, e);\n  }\n}\n\nfunction placeView(rt: RegionRuntime<ElementTagName>, view: ViewRuntime, earlier: ViewRuntime | null) {\n  if (earlier && regionOf(earlier) === rt) {\n    // A view underneath a newer one keeps its place there, still unseen.\n    const h = rt.hidden.indexOf(earlier);\n    if (h !== -1) {\n      rt.hidden[h] = view;\n      showIn(view, rt, earlier);\n      earlier.region = null;\n      return;\n    }\n    reclaimView(rt, view, earlier);\n    return;\n  }\n  if (rt.showingEmpty || (rt.type === \"latest\" && rt.views.length > 0)) {\n    // Clearing throws away the server markup along with everything else, so it\n    // also ends any claim in progress: the rest of this region renders fresh.\n    clearBetweenMarkers(rt.startMarker, rt.endMarker);\n    // A latest region shows only the newest, but the one it replaces is not\n    // gone: it comes back when the newer view leaves.\n    for (const old of rt.views) {\n      old.first = null;\n      old.last = null;\n      rt.hidden.push(old);\n    }\n    rt.views.length = 0;\n    rt.showingEmpty = false;\n    rt.claiming = false;\n    rt.claimCursor = null;\n  }\n  rt.views.push(view);\n  showIn(view, rt);\n  if (isHydrating() && rt.claiming) {\n    const { before, cursor } = claimAt(rt, view.content);\n    setRange(view, before, cursor);\n  } else {\n    // A view built fresh while the region is still claiming (a when() branch\n    // the server did not render) goes in ahead of the unclaimed server\n    // markup, or the sweep would take it for leftovers.\n    const at = rt.claiming && rt.claimCursor ? rt.claimCursor : rt.endMarker;\n    const before = at.previousSibling!;\n    renderContentItems(view.content, rt.host, rt.index, at);\n    setRange(view, before, at);\n  }\n  stamp(rt);\n}\n\n/**\n * Claims the region's unclaimed server markup for `content`, advancing the\n * claim cursor past it. Nothing is removed: what follows may belong to a view\n * that has not run yet, so leftovers are judged by the sweep.\n *\n * applyModifiers rather than a bare render: a node the content could not claim\n * is inserted at the claim cursor instead of dropped, exactly as when() does\n * for a branch it is re-running over SSR output.\n */\nfunction claimAt(\n  rt: RegionRuntime<ElementTagName>,\n  content: readonly WhenContent<ElementTagName>[],\n): { before: Node; cursor: Node } {\n  const parent = rt.host as unknown as Node;\n  const hostCursor = peekChild(parent);\n  const from = rt.claimCursor ?? rt.endMarker;\n  const before = from.previousSibling!;\n  setCursor(parent, from);\n  for (const item of content) applyModifiers(rt.host, [item as NodeModifier<ElementTagName>], rt.index);\n  const cursor = peekChild(parent) ?? rt.endMarker;\n  rt.claimCursor = cursor;\n  setCursor(parent, hostCursor);\n  return { before, cursor };\n}\n\n/**\n * Re-runs `content` over the nodes from `from` up to `stop` (exclusive),\n * claiming what matches and dropping the rest. Returns the node before the\n * range, for setRange().\n */\nfunction claimRange(\n  rt: RegionRuntime<ElementTagName>,\n  content: readonly WhenContent<ElementTagName>[],\n  from: Node,\n  stop: Node,\n): Node {\n  const parent = rt.host as unknown as Node;\n  const hostCursor = peekChild(parent);\n  const before = from.previousSibling!;\n  // A non-claimable boundary keeps growing content from consuming the next view.\n  const boundary = document.createComment(\"region-claim-boundary\");\n  parent.insertBefore(boundary, stop);\n  setCursor(parent, from === stop ? boundary : from);\n  try {\n    for (const item of content) applyModifiers(rt.host, [item as NodeModifier<ElementTagName>], rt.index);\n    let leftover = peekChild(parent);\n    while (leftover && leftover !== boundary) {\n      const next: Node | null = leftover.nextSibling;\n      safeRemoveChild(leftover);\n      leftover = next;\n    }\n  } finally {\n    parent.removeChild(boundary);\n    setCursor(parent, hostCursor);\n  }\n  return before;\n}\n\n/** The node right after a view's content: the next view's first node, or the end marker. */\nfunction boundaryAfter(rt: RegionRuntime<ElementTagName>, view: ViewRuntime): Node {\n  const last = view.last?.deref();\n  if (last) return last.nextSibling ?? rt.endMarker;\n  for (let i = rt.views.indexOf(view) + 1; i < rt.views.length; i++) {\n    const first = rt.views[i].first?.deref();\n    if (first) return first;\n  }\n  return rt.endMarker;\n}\n\n/** A view re-running over its own earlier content takes its place and claims its nodes. */\nfunction reclaimView(rt: RegionRuntime<ElementTagName>, view: ViewRuntime, earlier: ViewRuntime) {\n  const stop = boundaryAfter(rt, earlier);\n  const before = claimRange(rt, view.content, earlier.first?.deref() ?? stop, stop);\n  rt.views[rt.views.indexOf(earlier)] = view;\n  showIn(view, rt, earlier);\n  detach(earlier);\n  setRange(view, before, stop);\n  stamp(rt);\n}\n\n/**\n * Claims the server's `empty` content in place, for a region that had no views\n * on either side. Leaves the region claiming, so the sweep still drops\n * anything the empty content did not account for.\n */\nexport function claimEmpty<TTagName extends ElementTagName>(runtime: RegionRuntime<TTagName>) {\n  const rt = runtime as unknown as RegionRuntime<ElementTagName>;\n  if (rt.empty.length) claimAt(rt, rt.empty);\n  rt.showingEmpty = true;\n}\n\n/** Re-claims a live region's `empty` content in place (a pass re-running a live tree). */\nexport function reclaimEmpty(rt: RegionRuntime<ElementTagName>) {\n  claimRange(rt, rt.empty, rt.startMarker.nextSibling ?? rt.endMarker, rt.endMarker);\n}\n\n/** Takes a view's content out of its region; the region falls back to `empty` when none is left. */\nfunction removeView(view: ViewRuntime) {\n  unpend(view);\n  const rt = regionOf(view);\n  if (!rt) {\n    // Waiting, or orphaned by a collected region: nothing left to take out.\n    detach(view);\n    return;\n  }\n  const h = rt.hidden.indexOf(view);\n  if (h !== -1) {\n    rt.hidden.splice(h, 1);\n    detach(view);\n    return;\n  }\n  const i = rt.views.indexOf(view);\n  if (i !== -1) {\n    rt.views.splice(i, 1);\n    const last = view.last?.deref();\n    const stop = last ? last.nextSibling : null;\n    let node = view.first?.deref() ?? null;\n    while (node && node !== stop) {\n      const next: Node | null = node.nextSibling;\n      safeRemoveChild(node);\n      node = next;\n    }\n  }\n  detach(view);\n  if (i === -1) return;\n  if (rt.views.length > 0 || rt.claiming) {\n    // Mid-hydration the sweep decides, once it knows which views stayed.\n    stamp(rt);\n    return;\n  }\n  // The view underneath shows again, rebuilt; with none left, `empty` does.\n  const underneath = rt.hidden.pop();\n  if (underneath) addView(rt, underneath, null);\n  else showEmpty(rt);\n}\n\n/**\n * nuclo removed a marker node of ours. A view's anchor takes its content out\n * of the region. A region's start marker unregisters the region and puts its\n * views back to waiting, in order, so a region that returns under the same id\n * (a layout switched off and on) shows them again.\n */\nfunction onMarkerDisposed(node: Node) {\n  const anchor = node as Comment;\n  const views = viewsByAnchor.get(anchor);\n  if (views) {\n    viewsByAnchor.delete(anchor);\n    for (const view of views) removeView(view);\n    return;\n  }\n  const rt = runtimeByMarker.get(anchor);\n  if (rt) dropRegion(rt);\n}\n\n/**\n * Drops server markup no into() claimed, once the hydration pass is over.\n *\n * Nothing announces \"this region has all its views now\" mid-pass, so the\n * leftovers can only be judged at the end: a client that renders fewer views\n * than the server did leaves the tail of the region unclaimed.\n */\nexport function sweepRegions() {\n  for (const rt of claimingRegions) {\n    // A region torn down mid-pass (inside a when() branch the client did not\n    // keep) is no longer the one under its marker; nothing of it is settled.\n    if (rt.claiming && runtimeByMarker.get(rt.startMarker) === rt) {\n      let leftover = rt.claimCursor;\n      while (leftover && leftover !== rt.endMarker) {\n        const next: Node | null = leftover.nextSibling;\n        safeRemoveChild(leftover);\n        leftover = next;\n      }\n      // A region the client left with no views at all falls back to `empty`.\n      if (rt.views.length === 0 && !rt.showingEmpty) showEmpty(rt);\n    }\n    rt.claiming = false;\n    rt.claimCursor = null;\n  }\n  claimingRegions.length = 0;\n}\n","/**\n * Keyed list runtime: renders `list(provider, render)` blocks and keeps their\n * DOM rows in sync with the provider's items on every update().\n *\n * sync() is a keyed diff over item identity (===):\n *  1. skip when the items are unchanged (arraysEqual),\n *  2. trim rows that already back the same item at the same position from both\n *     ends — pure appends, prepends, insertions and deletions then need no\n *     keying structures at all,\n *  3. key the remaining window by item identity (same-position rows pinned\n *     first, duplicate items matched FIFO), remove the rows whose item is gone,\n *  4. place the window anchored backwards from the row after it: survivors on\n *     the longest increasing subsequence of old positions never move, and runs\n *     of freshly built rows are batched into DocumentFragments.\n */\nimport { createMarkerPair, clearBetweenMarkers, safeRemoveChild, cleanupNodeTree } from \"../shared/dom\";\nimport { isHydrating, isSerializing, claimMarkerPair, peekChild, setCursor, runFreshAtCursor } from \"../hydration\";\nimport type { ListRuntime, ListItemRecord } from \"./types\";\nimport { all, membersOf, track, LIST_KIND, type UpdateScope } from \"../update/scope\";\nimport { isBrowser } from \"../shared/environment\";\nimport { getFactoryMods, getFactoryTag, withMetadataOnlyFactories, getMetadataOnlyFactoryCheckpoint, releaseMetadataOnlyFactories } from \"../element/factory-meta\";\nimport { analyzeFactory, prepareSkeleton, instantiateTemplate, adoptTemplateLeaves, flushRowLeaves, cleanupTemplateRow, openLeaves, leafCursor, restoreLeafCursor } from \"./template\";\nimport { mountQueueMark, cancelMountsSince } from \"../element/lifecycle\";\nimport { isViewAnchor } from \"../region/runtime\";\n\nfunction arraysEqual<T>(a: readonly T[], b: readonly T[]) {\n  if (a === b) return true;\n  if (a.length !== b.length) return false;\n  for (let i = 0; i < a.length; i++) {\n    if (a[i] !== b[i]) return false;\n  }\n  return true;\n}\n\n/**\n * Registry of active list runtimes.\n *\n * The iteration set only holds WeakRefs; the runtime itself lives in a\n * WeakMap keyed by its start marker. This keeps the global registry free of\n * strong references to the runtime (which holds the host element, records,\n * and markers), so removing a list's DOM subtree makes the whole runtime\n * collectible — even if update() is never called again. The\n * FinalizationRegistry prunes dead WeakRefs from the set once the marker is\n * collected; updateListRuntimes() also prunes as it iterates.\n */\nconst activeListRuntimes = all[LIST_KIND] as Set<WeakRef<Comment>>;\nconst listRuntimeByMarker = new WeakMap<Comment, ListRuntime<unknown, ElementTagName>>();\nconst listMarkerFinalizer = typeof FinalizationRegistry !== \"undefined\"\n  ? new FinalizationRegistry<WeakRef<Comment>>((ref) => { activeListRuntimes.delete(ref); })\n  : null;\nlet updateListFlushEpoch = 0;\n\nfunction registerListRuntime(startMarker: Comment, runtime: ListRuntime<unknown, ElementTagName>) {\n  const existing = listRuntimeByMarker.get(startMarker);\n  listRuntimeByMarker.set(startMarker, runtime);\n  // Re-registration for the same markers (forceUpdate() reclaim): see\n  // registerWhenRuntime() — adding another WeakRef would only grow the set.\n  if (existing) return;\n  const ref = new WeakRef(startMarker);\n  track(LIST_KIND, ref);\n  listMarkerFinalizer?.register(startMarker, ref);\n}\n\nfunction normalizeItems<TItem>(items: ListItemsInput<TItem>): readonly TItem[] {\n  return Array.isArray(items) ? items : Array.from(items);\n}\n\n/**\n * Resolves a render() result — a tag-builder factory / NodeModFn (called with\n * the host) or an already-built element — to the row node. A into() is a row\n * too: its anchor stands in the list and its content lives in the region, so\n * the row leaving the list takes the content with it. Anything else (null,\n * primitives, attribute objects, other non-element nodes) renders no row.\n */\nfunction toRowElement<TTagName extends ElementTagName>(\n  result: unknown,\n  host: ExpandedElement<TTagName>,\n  index: number,\n): ExpandedElement<TTagName> | null {\n  const value = typeof result === \"function\" ? (result as NodeModFn<TTagName>)(host, index) : result;\n  if (value === null || typeof value !== \"object\") return null;\n  return \"tagName\" in value || isViewAnchor(value as Node) ? (value as ExpandedElement<TTagName>) : null;\n}\n\n/**\n * Renders a row through the un-templated path. Used whenever a row's shape\n * doesn't match (or no longer matches) the list's active template — the\n * caller has already reset `runtime.template`.\n */\nfunction rebuildRowNormally<TItem, TTagName extends ElementTagName>(\n  runtime: ListRuntime<TItem, TTagName>,\n  item: TItem,\n  index: number,\n): ExpandedElement<TTagName> | null {\n  return toRowElement(runtime.renderItem(item, index), runtime.host, index);\n}\n\nfunction renderItem<TItem, TTagName extends ElementTagName>(\n  runtime: ListRuntime<TItem, TTagName>,\n  item: TItem,\n  index: number,\n) {\n  const checkpoint = getMetadataOnlyFactoryCheckpoint();\n  try {\n    return renderItemWithTemplate(runtime, item, index);\n  } finally {\n    releaseMetadataOnlyFactories(checkpoint);\n  }\n}\n\nfunction renderItemWithTemplate<TItem, TTagName extends ElementTagName>(\n  runtime: ListRuntime<TItem, TTagName>,\n  item: TItem,\n  index: number,\n): ExpandedElement<TTagName> | null {\n  runtime.lastRenderLeaves = null;\n  const template = runtime.template;\n  const canUseTemplate = isBrowser && !isHydrating() && !isSerializing();\n\n  // Row-template fast path: rows from the same render function share their\n  // structure, so after analyzing the first row every following row is a\n  // skeleton clone + leaf patch instead of a full per-element build.\n  const result = template && canUseTemplate\n    ? withMetadataOnlyFactories(runtime.renderItem, item, index)\n    : runtime.renderItem(item, index);\n\n  if (template !== null && canUseTemplate) {\n    const mods = getFactoryMods(result);\n    if (mods !== undefined) {\n      if (template === undefined) {\n        const tag = getFactoryTag(result);\n        const tmpl = tag ? analyzeFactory(tag, mods) : null;\n        const el = toRowElement(result, runtime.host, index);\n        if (tmpl && el) {\n          const skeleton = (el as unknown as Node).cloneNode(true) as Element;\n          prepareSkeleton(tmpl, skeleton);\n          const outer = leafCursor();\n          const leaves = openLeaves(tmpl);\n          let adopted = false;\n          try {\n            adopted = adoptTemplateLeaves(tmpl, mods, el as unknown as Element, leaves);\n            if (adopted) runtime.lastRenderLeaves = leaves;\n          } finally {\n            restoreLeafCursor(outer);\n          }\n          if (!adopted) {\n            runtime.template = null;\n            runtime.lastRenderLeaves = null;\n            return el;\n          }\n          runtime.template = { tmpl, skeleton };\n          runtime.rowShape = tmpl;\n        } else {\n          runtime.template = null;\n        }\n        return el;\n      }\n      const clone = template.skeleton.cloneNode(true) as Element;\n      const outer = leafCursor();\n      const leaves = openLeaves(template.tmpl);\n      try {\n        if (getFactoryTag(result) === template.tmpl.tag && instantiateTemplate(template.tmpl, mods, clone, leaves)) {\n          runtime.lastRenderLeaves = leaves;\n          return clone as unknown as ExpandedElement<TTagName>;\n        }\n      } finally {\n        restoreLeafCursor(outer);\n      }\n      // Heterogeneous rows: deactivate and rebuild this row normally. The\n      // abandoned clone is disconnected and unregistered — plain garbage.\n      // (lastRenderLeaves is already null from the top of this call.)\n      runtime.template = null;\n      return rebuildRowNormally(runtime, item, index);\n    } else if (template === undefined) {\n      runtime.template = null;\n    } else {\n      runtime.template = null;\n      return rebuildRowNormally(runtime, item, index);\n    }\n  }\n\n  return toRowElement(result, runtime.host, index);\n}\n\n/**\n * Releases a row's bookkeeping before its DOM goes. A template-built row\n * (`dyn !== null`) holds nothing cleanupNodeTree() would find except event\n * handlers, and its slot program says exactly where those are.\n */\nfunction cleanupRow<TItem, TTagName extends ElementTagName>(\n  runtime: ListRuntime<TItem, TTagName>,\n  record: ListItemRecord<TItem, TTagName>,\n) {\n  const node = record.element as unknown as Node;\n  const shape = runtime.rowShape;\n  if (record.dyn !== null && shape) cleanupTemplateRow(shape, node as Element);\n  else cleanupNodeTree(node);\n}\n\n/** Detaches one row (partial removals); the bulk paths use bulkClearRecords. */\nfunction removeRow<TItem, TTagName extends ElementTagName>(\n  runtime: ListRuntime<TItem, TTagName>,\n  record: ListItemRecord<TItem, TTagName>,\n) {\n  const shape = runtime.rowShape;\n  if (record.dyn === null || !shape) return safeRemoveChild(record.element as unknown as Node);\n  const node = record.element as unknown as Node;\n  if (!node.parentNode) return false;\n  cleanupTemplateRow(shape, node as Element);\n  node.parentNode.removeChild(node);\n  return true;\n}\n\n/**\n * Cleans every row before detaching it. Weak bookkeeping permits collection,\n * but retained DOM nodes must stop invoking removed views' event handlers.\n * Keep the native bulk removal below to avoid Range's quadratic DOM walk.\n * Returns false without mutation when the markers no longer share a parent.\n */\nfunction bulkClearRecords<TItem, TTagName extends ElementTagName>(\n  runtime: ListRuntime<TItem, TTagName>,\n  records: ReadonlyArray<ListItemRecord<TItem, TTagName>>,\n  parent: Node & ParentNode,\n  startMarker: Comment,\n  endMarker: Comment,\n) {\n  if (startMarker.parentNode !== parent || endMarker.parentNode !== parent) return false;\n\n  for (let i = 0; i < records.length; i++) {\n    if (records[i].element) cleanupRow(runtime, records[i]);\n  }\n\n  // Fastest clear: when the list spans the whole parent (the common case — a\n  // tbody or ul dedicated to the list), one textContent write drops every row\n  // in a single native call, then the marker pair is re-attached (same nodes,\n  // so registry identity is preserved).\n  if (isBrowser && parent.firstChild === startMarker && parent.lastChild === endMarker) {\n    (parent as Node).textContent = \"\";\n    parent.appendChild(startMarker);\n    parent.appendChild(endMarker);\n    return true;\n  }\n\n  for (let i = 0; i < records.length; i++) {\n    const node = records[i].element as unknown as Node | null;\n    // Detach the row (guard against an already-moved/detached element so a\n    // stale record can't throw). Children of the row go with it in one call.\n    if (node && node.parentNode === parent) parent.removeChild(node);\n  }\n  return true;\n}\n\n/** sync(): anchor on pinned rows alone when at most this many survivors move. */\nconst PINNED_ONLY_MAX_MOVES = 8;\n/** ...and only in windows this large, where skipping the LIS actually pays. */\nconst PINNED_ONLY_MIN_PINNED = 32;\n\n/**\n * Computes a longest strictly-increasing subsequence of `arr` and returns the\n * indices (into `arr`) that belong to it, in ascending order. O(n log n).\n *\n * Used so reordering only moves the minimum number of DOM nodes: records whose\n * old position sits on the increasing subsequence are already in the correct\n * relative order and never touched; everything else is repositioned.\n */\nfunction longestIncreasingSubsequence(arr: number[]): number[] {\n  const n = arr.length;\n  if (n === 0) return [];\n  const predecessor = new Array<number>(n);\n  // tails[k] = index into arr of the smallest tail of an increasing\n  // subsequence of length k+1.\n  const tails: number[] = [];\n  for (let i = 0; i < n; i++) {\n    const x = arr[i];\n    let lo = 0;\n    let hi = tails.length;\n    while (lo < hi) {\n      const mid = (lo + hi) >> 1;\n      if (arr[tails[mid]] < x) lo = mid + 1;\n      else hi = mid;\n    }\n    predecessor[i] = lo > 0 ? tails[lo - 1] : -1;\n    if (lo === tails.length) tails.push(i);\n    else tails[lo] = i;\n  }\n  let k = tails.length;\n  let idx = tails[k - 1];\n  const result = new Array<number>(k);\n  while (k > 0) {\n    result[--k] = idx;\n    idx = predecessor[idx];\n  }\n  return result;\n}\n\n/**\n * Renders items in [startIndex, endIndexExclusive) and inserts their elements\n * before `anchor` as a single DocumentFragment. Appends the created records to\n * `targetRecords` in order.\n */\nfunction buildAndInsert<TItem, TTagName extends ElementTagName>(\n  runtime: ListRuntime<TItem, TTagName>,\n  parent: Node & ParentNode,\n  items: readonly TItem[],\n  startIndex: number,\n  endIndexExclusive: number,\n  anchor: Node,\n  targetRecords: ListItemRecord<TItem, TTagName>[],\n) {\n  const fragment = document.createDocumentFragment();\n  for (let i = startIndex; i < endIndexExclusive; i++) {\n    const item = items[i];\n    const element = renderItem(runtime, item, i);\n    if (!element) continue;\n    const dyn = runtime.lastRenderLeaves;\n    targetRecords.push({\n      item,\n      element,\n      dyn,\n      dynCreatedAt: dyn ? runtime.currentFlushEpoch : undefined,\n    });\n    runtime.lastRenderLeaves = null;\n    fragment.appendChild(element as unknown as Node);\n  }\n  if (fragment.firstChild) parent.insertBefore(fragment, anchor);\n}\n\n/**\n * The single-choice <select> whose options a list renders: its direct parent,\n * or an <optgroup>'s parent. (A `multiple` select has no one value to keep.)\n */\nfunction selectOwning(parent: Node | null): HTMLSelectElement | null {\n  if (!parent) return null;\n  const node = parent.nodeName === \"OPTGROUP\" ? parent.parentNode : parent;\n  return node && node.nodeName === \"SELECT\" && !(node as HTMLSelectElement).multiple ? node as HTMLSelectElement : null;\n}\n\nexport function sync<TItem, TTagName extends ElementTagName>(\n  runtime: ListRuntime<TItem, TTagName>\n) {\n  const items = normalizeItems(runtime.itemsProvider());\n\n  if (arraysEqual(runtime.lastSyncedItems, items)) return;\n\n  // Removing, moving or rebuilding <option>s makes the browser re-pick the\n  // selection — rows rebuilt from refetched data, or a plain reorder, would\n  // silently change what a <select> shows. Keep it on the value it had.\n  const select = isBrowser ? selectOwning(runtime.startMarker.parentNode) : null;\n  const selectedValue = select && select.selectedIndex >= 0 ? select.value : null;\n\n  const mark = mountQueueMark();\n  try {\n    diffRows(runtime, items);\n    if (selectedValue !== null && select!.value !== selectedValue) {\n      const fallback = select!.selectedIndex;\n      select!.value = selectedValue;\n      // No option carries that value any more: keep the browser's pick.\n      if (select!.value !== selectedValue) select!.selectedIndex = fallback;\n    }\n  } catch (error) {\n    // A render function threw mid-diff: rows may already be removed, moved or\n    // recorded without being inserted, so the records no longer mirror the\n    // DOM. Reset to an empty list — the next sync rebuilds it from scratch\n    // instead of diffing against a state that does not exist.\n    const { startMarker, endMarker } = runtime;\n    if (startMarker.parentNode && startMarker.parentNode === endMarker.parentNode) {\n      clearBetweenMarkers(startMarker, endMarker);\n    }\n    runtime.records = [];\n    runtime.lastSyncedItems = [];\n    runtime.allRecordsCreatedAt = undefined;\n    // Rows built but never inserted must not mount on a later flush.\n    cancelMountsSince(mark);\n    throw error;\n  }\n}\n\nfunction diffRows<TItem, TTagName extends ElementTagName>(\n  runtime: ListRuntime<TItem, TTagName>,\n  items: readonly TItem[],\n) {\n  const { startMarker, endMarker } = runtime;\n  const parent = (startMarker.parentNode ?? (runtime.host as unknown as Node & ParentNode)) as\n    Node & ParentNode;\n\n  const oldRecords = runtime.records;\n  const oldLen = oldRecords.length;\n  const newLen = items.length;\n\n  // Fast path — clear: clean the rows before the native bulk removal.\n  if (newLen === 0) {\n    if (oldLen > 0 && !bulkClearRecords(runtime, oldRecords, parent, startMarker, endMarker)) {\n      for (let i = 0; i < oldLen; i++) removeRow(runtime, oldRecords[i]);\n    }\n    runtime.records = [];\n    runtime.lastSyncedItems = [];\n    runtime.allRecordsCreatedAt = undefined;\n    return;\n  }\n\n  // Trim rows that already back the same item at the same position from both\n  // ends. They never move, and most updates (append, prepend, single insert or\n  // delete) reduce to an empty window on one side.\n  let prefix = 0;\n  const maxTrim = Math.min(oldLen, newLen);\n  while (prefix < maxTrim && oldRecords[prefix].item === items[prefix]) prefix++;\n  let suffix = 0;\n  const maxSuffix = maxTrim - prefix;\n  while (suffix < maxSuffix && oldRecords[oldLen - 1 - suffix].item === items[newLen - 1 - suffix]) {\n    suffix++;\n  }\n\n  const oldStart = prefix;\n  const oldEnd = oldLen - suffix;\n  const newStart = prefix;\n  const newEnd = newLen - suffix;\n\n  // Every old row was trimmed → pure insertion (first render, append, prepend,\n  // middle insert). Build the new rows into one fragment before the row that\n  // follows the gap. (An empty new window is a no-op here.)\n  if (oldStart === oldEnd) {\n    const anchor: Node = oldEnd < oldLen ? (oldRecords[oldEnd].element as unknown as Node) : endMarker;\n    if (oldEnd === oldLen) {\n      buildAndInsert(runtime, parent, items, newStart, newEnd, anchor, oldRecords);\n      runtime.allRecordsCreatedAt = oldLen === 0 ? runtime.currentFlushEpoch : undefined;\n    } else {\n      const fresh: ListItemRecord<TItem, TTagName>[] = [];\n      buildAndInsert(runtime, parent, items, newStart, newEnd, anchor, fresh);\n      runtime.records = oldRecords.slice(0, oldStart).concat(fresh, oldRecords.slice(oldStart));\n      runtime.allRecordsCreatedAt = undefined;\n    }\n    runtime.lastSyncedItems = items.slice();\n    return;\n  }\n\n  // Every new row was trimmed → pure removal. This is always partial (a full\n  // clear was handled above), so remove each row eagerly.\n  if (newStart === newEnd) {\n    for (let i = oldStart; i < oldEnd; i++) removeRow(runtime, oldRecords[i]);\n    oldRecords.splice(oldStart, oldEnd - oldStart);\n    runtime.allRecordsCreatedAt = undefined;\n    runtime.lastSyncedItems = items.slice();\n    return;\n  }\n\n  // General keyed diff over the window ---------------------------------------\n  const oldWinLen = oldEnd - oldStart;\n  const newWinLen = newEnd - newStart;\n\n  // sources[j] = index into oldRecords of the record backing new position\n  // newStart + j, or -1 when the row must be freshly rendered.\n  const sources = new Array<number>(newWinLen).fill(-1);\n  // claimed[i - oldStart] = the old record was matched to a new position.\n  const claimed = new Uint8Array(oldWinLen);\n  let reusedCount = 0;\n\n  // Pin records whose item is unchanged at the same position. This keeps\n  // duplicate item references attached to their original rows.\n  const pinEnd = Math.min(oldEnd, newEnd);\n  for (let i = prefix; i < pinEnd; i++) {\n    if (oldRecords[i].item === items[i]) {\n      sources[i - newStart] = i;\n      claimed[i - oldStart] = 1;\n      reusedCount++;\n    }\n  }\n  const pinnedCount = reusedCount;\n\n  // Bucket in reverse DOM order so pop() matches duplicates FIFO in O(1). The value\n  // is a single old index, promoted to an index array only when the same item\n  // occurs more than once (duplicates are matched FIFO).\n  const buckets = new Map<TItem, number | number[]>();\n  for (let i = oldEnd - 1; i >= oldStart; i--) {\n    if (claimed[i - oldStart]) continue;\n    const item = oldRecords[i].item;\n    const entry = buckets.get(item);\n    if (entry === undefined) buckets.set(item, i);\n    else if (typeof entry === \"number\") buckets.set(item, [entry, i]);\n    else entry.push(i);\n  }\n\n  for (let j = 0; j < newWinLen; j++) {\n    if (sources[j] !== -1) continue;\n    const entry = buckets.get(items[newStart + j]);\n    if (entry === undefined) continue;\n    let oldIndex: number;\n    if (typeof entry === \"number\") {\n      oldIndex = entry;\n      buckets.delete(items[newStart + j]);\n    } else {\n      oldIndex = entry.pop()!;\n      if (entry.length === 0) buckets.delete(items[newStart + j]);\n    }\n    sources[j] = oldIndex;\n    claimed[oldIndex - oldStart] = 1;\n    reusedCount++;\n  }\n\n  // Nothing survives anywhere → full replace: bulk-detach all old rows and\n  // build every new row into a single fragment.\n  if (reusedCount === 0 && oldStart === 0 && oldEnd === oldLen) {\n    if (!bulkClearRecords(runtime, oldRecords, parent, startMarker, endMarker)) {\n      for (let i = 0; i < oldLen; i++) removeRow(runtime, oldRecords[i]);\n    }\n    const fresh: ListItemRecord<TItem, TTagName>[] = [];\n    buildAndInsert(runtime, parent, items, 0, newLen, endMarker, fresh);\n    runtime.records = fresh;\n    runtime.allRecordsCreatedAt = runtime.currentFlushEpoch;\n    runtime.lastSyncedItems = items.slice();\n    return;\n  }\n\n  // Remove stale rows BEFORE placement. A removed element left in the DOM\n  // would end up interleaved with the survivors the placement phase leaves\n  // untouched.\n  for (let i = oldStart; i < oldEnd; i++) {\n    if (!claimed[i - oldStart]) removeRow(runtime, oldRecords[i]);\n  }\n\n  // Determine the minimal set of survivors that must move. Survivors whose old\n  // positions form an increasing subsequence are already correctly ordered.\n  //\n  // Pinned rows (same index before and after) are such a subsequence on their\n  // own. When nearly every survivor is pinned — swapping two rows of a large\n  // list — anchoring on them alone moves only the few unpinned survivors and\n  // skips the O(n log n) LIS pass and its arrays. The true LIS can save at\n  // most `unpinned` moves over that, so the shortcut is bounded to a handful.\n  let stable: Uint8Array | null = null;\n  const unpinned = reusedCount - pinnedCount;\n  const pinnedOnly = unpinned <= PINNED_ONLY_MAX_MOVES && pinnedCount >= PINNED_ONLY_MIN_PINNED;\n  if (reusedCount > 0 && !pinnedOnly) {\n    const survivorOldIndices: number[] = [];\n    const survivorPositions: number[] = [];\n    for (let j = 0; j < newWinLen; j++) {\n      if (sources[j] !== -1) {\n        survivorOldIndices.push(sources[j]);\n        survivorPositions.push(j);\n      }\n    }\n    stable = new Uint8Array(newWinLen);\n    const lis = longestIncreasingSubsequence(survivorOldIndices);\n    for (let k = 0; k < lis.length; k++) stable[survivorPositions[lis[k]]] = 1;\n  }\n\n  // Place the window anchored backwards from the first row after it. Runs of\n  // freshly created rows are batched into a fragment; survivors on the LIS are\n  // left untouched.\n  const windowRecords = new Array<ListItemRecord<TItem, TTagName> | null>(newWinLen);\n  let nullCount = 0;\n  let anchor: Node = oldEnd < oldLen ? (oldRecords[oldEnd].element as unknown as Node) : endMarker;\n  let fragment: DocumentFragment | null = null;\n\n  for (let j = newWinLen - 1; j >= 0; j--) {\n    const src = sources[j];\n\n    if (src === -1) {\n      // Fresh row. Prefer batching consecutive new rows into a fragment (one\n      // DOM insert); prepending keeps ascending order.\n      const item = items[newStart + j];\n      const element = renderItem(runtime, item, newStart + j);\n      if (!element) {\n        windowRecords[j] = null;\n        nullCount++;\n        continue;\n      }\n      const dyn = runtime.lastRenderLeaves;\n      windowRecords[j] = {\n        item,\n        element,\n        dyn,\n        dynCreatedAt: dyn ? runtime.currentFlushEpoch : undefined,\n      };\n      runtime.lastRenderLeaves = null;\n      fragment ??= document.createDocumentFragment();\n      fragment.insertBefore(element as unknown as Node, fragment.firstChild);\n      continue;\n    }\n\n    // Survivor: flush any pending fresh rows (they belong after it), moving\n    // the anchor to the first flushed node so this row lands before them.\n    const record = oldRecords[src];\n    windowRecords[j] = record;\n    const node = record.element as unknown as Node;\n    if (fragment && fragment.firstChild) {\n      const firstFlushed = fragment.firstChild;\n      parent.insertBefore(fragment, anchor);\n      anchor = firstFlushed;\n      fragment = null;\n    }\n    // Pinned-only mode: a survivor is pinned iff it kept its index (a bucket\n    // match can never land on its own old index — the pin pass took those).\n    if (stable ? !stable[j] : !(pinnedOnly && src === newStart + j)) {\n      parent.insertBefore(node, anchor);\n    }\n    anchor = node;\n  }\n  if (fragment && fragment.firstChild) parent.insertBefore(fragment, anchor);\n\n  // Stitch the untouched prefix and suffix around the window's records.\n  const merged = new Array<ListItemRecord<TItem, TTagName>>(\n    oldStart + (newWinLen - nullCount) + (oldLen - oldEnd),\n  );\n  let w = 0;\n  for (let i = 0; i < oldStart; i++) merged[w++] = oldRecords[i];\n  for (let j = 0; j < newWinLen; j++) {\n    const record = windowRecords[j];\n    if (record) merged[w++] = record;\n  }\n  for (let i = oldEnd; i < oldLen; i++) merged[w++] = oldRecords[i];\n  runtime.records = merged;\n  runtime.allRecordsCreatedAt = undefined;\n  runtime.lastSyncedItems = items.slice();\n}\n\n/** Every field initialized up front so all runtimes share one object shape. */\nfunction newRuntime<TItem, TTagName extends ElementTagName>(\n  itemsProvider: ListItemsProvider<TItem>,\n  renderItem: ListRenderFunction<TItem, TTagName>,\n  startMarker: Comment,\n  endMarker: Comment,\n  records: ListItemRecord<TItem, TTagName>[],\n  host: ExpandedElement<TTagName>,\n  lastSyncedItems: readonly TItem[],\n): ListRuntime<TItem, TTagName> {\n  return {\n    itemsProvider,\n    renderItem,\n    startMarker,\n    endMarker,\n    records,\n    host,\n    lastSyncedItems,\n    template: undefined,\n    rowShape: null,\n    lastRenderLeaves: null,\n    currentFlushEpoch: undefined,\n    allRecordsCreatedAt: undefined,\n  };\n}\n\nexport function createListRuntime<TItem, TTagName extends ElementTagName = ElementTagName>(\n  itemsProvider: ListItemsProvider<TItem>,\n  renderItem: ListRenderFunction<TItem, TTagName>,\n  host: ExpandedElement<TTagName>,\n  index: number,\n): ListRuntime<TItem, TTagName> {\n  if (isHydrating()) {\n    return hydrateListRuntime(itemsProvider, renderItem, host, index);\n  }\n\n  return createListRuntimeNormal(itemsProvider, renderItem, host, index);\n}\n\nfunction createListRuntimeNormal<TItem, TTagName extends ElementTagName>(\n  itemsProvider: ListItemsProvider<TItem>,\n  renderItem: ListRenderFunction<TItem, TTagName>,\n  host: ExpandedElement<TTagName>,\n  index: number,\n): ListRuntime<TItem, TTagName> {\n  const { start: startMarker, end: endMarker } = createMarkerPair(\"list\", index);\n\n  const runtime = newRuntime(itemsProvider, renderItem, startMarker, endMarker, [], host, []);\n\n  const parentNode = host as unknown as Node & ParentNode;\n  parentNode.appendChild(startMarker);\n  parentNode.appendChild(endMarker);\n\n  sync(runtime);\n\n  if (isBrowser && !isSerializing()) {\n    // Register for future update() calls — never for a renderToString() tree\n    registerListRuntime(startMarker, runtime as ListRuntime<unknown, ElementTagName>);\n  }\n\n  return runtime;\n}\n\nfunction hydrateListRuntime<TItem, TTagName extends ElementTagName>(\n  itemsProvider: ListItemsProvider<TItem>,\n  renderFn: ListRenderFunction<TItem, TTagName>,\n  host: ExpandedElement<TTagName>,\n  index: number,\n): ListRuntime<TItem, TTagName> {\n  const parentNode = host as unknown as Node & ParentNode;\n\n  // No list markers at the cursor: build the list fresh. A recreated end\n  // marker (corrupt/truncated SSR output) makes every item claim below miss,\n  // so those rows render fresh too.\n  const pair = claimMarkerPair(parentNode, \"list\");\n  if (!pair) return runFreshAtCursor(parentNode, () => createListRuntimeNormal(itemsProvider, renderFn, host, index));\n  const { start: startMarker, end: endMarker } = pair;\n\n  // Get current items and claim existing elements by running render functions\n  const currentItems = normalizeItems(itemsProvider());\n  const records: ListItemRecord<TItem, TTagName>[] = [];\n\n  for (let i = 0; i < currentItems.length; i++) {\n    const element = toRowElement(renderFn(currentItems[i], i), host, i);\n    // Same record shape as sync() creates, so record access stays monomorphic.\n    if (element) records.push({ item: currentItems[i], element, dyn: null, dynCreatedAt: undefined });\n  }\n\n  // Reconcile server/client mismatches.\n  // 1) Server rendered more items than the client has: remove the leftover\n  //    nodes between the claim cursor and the end marker.\n  let leftover = peekChild(parentNode);\n  while (leftover && leftover !== endMarker) {\n    const next: Node | null = leftover.nextSibling;\n    safeRemoveChild(leftover);\n    leftover = next;\n  }\n\n  // 2) Client has items the claim pass could not match: place them in item\n  //    order, anchored backwards from the end marker (same strategy as sync()).\n  let anchor: Node = endMarker;\n  for (let i = records.length - 1; i >= 0; i--) {\n    const recordNode = records[i].element as unknown as Node;\n    if (recordNode.parentNode !== parentNode || recordNode.nextSibling !== anchor) {\n      parentNode.insertBefore(recordNode, anchor);\n    }\n    anchor = recordNode;\n  }\n\n  // Advance cursor past end marker\n  setCursor(parentNode, endMarker.nextSibling);\n\n  const runtime = newRuntime(itemsProvider, renderFn, startMarker, endMarker, records, host, currentItems.slice());\n\n  if (isBrowser && !isSerializing()) {\n    registerListRuntime(startMarker, runtime as ListRuntime<unknown, ElementTagName>);\n  }\n\n  return runtime;\n}\n\nexport function updateListRuntimes(scope?: UpdateScope) {\n  updateListFlushEpoch++;\n  if (!scope) return updateListSet(activeListRuntimes);\n  for (const root of scope.roots) updateListSet(membersOf(root, LIST_KIND) as Set<WeakRef<Comment>>);\n}\n\n/** `set` is the global registry or one scope root's members; pruning hits both. */\nfunction updateListSet(set: Set<WeakRef<Comment>>) {\n  for (const ref of set) {\n    const startMarker = ref.deref();\n\n    // Marker was garbage collected\n    if (!startMarker) {\n      set.delete(ref);\n      activeListRuntimes.delete(ref);\n      continue;\n    }\n\n    const runtime = listRuntimeByMarker.get(startMarker);\n    if (!runtime) {\n      set.delete(ref);\n      activeListRuntimes.delete(ref);\n      continue;\n    }\n\n    // Clean up if disconnected from DOM\n    if (!startMarker.isConnected || !runtime.endMarker.isConnected) {\n      listRuntimeByMarker.delete(startMarker);\n      set.delete(ref);\n      activeListRuntimes.delete(ref);\n      continue;\n    }\n\n    runtime.currentFlushEpoch = updateListFlushEpoch;\n    try {\n      sync(runtime);\n    } finally {\n      runtime.currentFlushEpoch = undefined;\n    }\n\n    // Flush template rows' record-owned dynamic leaves. Rows built through\n    // the normal path registered globally and are flushed by the notify\n    // passes instead.\n    if (runtime.allRecordsCreatedAt === updateListFlushEpoch) continue;\n    const records = runtime.records;\n    for (let i = 0; i < records.length; i++) {\n      if (records[i].dynCreatedAt === updateListFlushEpoch) continue;\n      const dyn = records[i].dyn;\n      if (dyn) flushRowLeaves(dyn);\n    }\n  }\n}\n","import { createMarkerPair, clearBetweenMarkers, safeRemoveChild } from \"../shared/dom\";\nimport type { WhenGroup, WhenRuntime } from \"./runtime\";\nimport { renderWhenContent, registerWhenRuntime, getWhenRuntime, evaluateActiveCondition, renderContentItems } from \"./runtime\";\nimport { isBrowser } from \"../shared/environment\";\nimport { isHydrating, isSerializing, claimMarkerPair, peekChild, setCursor, runWithoutHydration, runFreshAtCursor } from \"../hydration\";\nimport { applyModifiers } from \"../element/factory\";\nimport type { NodeModifier } from \"../element/modifiers\";\n\n/**\n * Encodes the active branch into the start marker so hydration can detect\n * server/client branch mismatches: `when-start-{index}-b{branch}` where\n * branch is the group index, -1 for the else branch, or `n` for none.\n */\nfunction encodeBranch(index: number, activeIndex: number | null) {\n  return `when-start-${index}-b${activeIndex === null ? 'n' : activeIndex}`;\n}\n\n/**\n * Reads the branch encoded in an SSR start marker.\n * Returns `undefined` for legacy markers without branch info.\n */\nfunction decodeBranch(markerText: string | null): number | null | undefined {\n  const match = /-b(n|-?\\d+)$/.exec(markerText || '');\n  if (!match) return undefined;\n  return match[1] === 'n' ? null : parseInt(match[1], 10);\n}\n\nclass WhenBuilderImpl<TTagName extends ElementTagName = ElementTagName> {\n  // Never mutated after construction, so chained builders and every runtime\n  // rendered from this builder share them instead of copying.\n  private readonly groups: ReadonlyArray<WhenGroup<TTagName>>;\n  private readonly elseContent: ReadonlyArray<WhenContent<TTagName>>;\n\n  constructor(groups: ReadonlyArray<WhenGroup<TTagName>>, elseContent: ReadonlyArray<WhenContent<TTagName>>) {\n    this.groups = groups;\n    this.elseContent = elseContent;\n  }\n\n  cloneWith(\n    additionalGroup?: WhenGroup<TTagName>,\n    newElseContent?: ReadonlyArray<WhenContent<TTagName>>,\n  ): WhenBuilderImpl<TTagName> {\n    return new WhenBuilderImpl(\n      additionalGroup ? [...this.groups, additionalGroup] : this.groups,\n      newElseContent ?? this.elseContent,\n    );\n  }\n\n  render(host: ExpandedElement<TTagName>, index: number): Node {\n    return isHydrating() ? this.hydrateRender(host, index) : this.freshRender(host, index);\n  }\n\n  private freshRender(host: ExpandedElement<TTagName>, index: number): Node {\n    const { start: startMarker, end: endMarker } = createMarkerPair(\"when\", index);\n    const runtime = this.createRuntimeFromMarkers(host, index, startMarker, endMarker);\n\n    const parent = host as unknown as Node & ParentNode;\n    parent.appendChild(startMarker);\n    parent.appendChild(endMarker);\n\n    renderWhenContent(runtime);\n\n    // Record which branch was rendered so hydration can detect mismatches.\n    startMarker.textContent = encodeBranch(index, runtime.activeIndex);\n\n    return startMarker;\n  }\n\n  private hydrateRender(host: ExpandedElement<TTagName>, index: number): Node {\n    const parentNode = host as unknown as Node & ParentNode;\n\n    // No when markers at the cursor (SSR output without Nuclo markers):\n    // create new markers and render from scratch.\n    const pair = claimMarkerPair(parentNode, \"when\");\n    if (!pair) return runFreshAtCursor(parentNode, () => this.freshRender(host, index));\n    const { start: startMarker, end: endMarker } = pair;\n\n    // Determine which branch the client wants and which is rendered. A live\n    // runtime (forceUpdate() reclaim) knows its actual branch — the marker\n    // text only encodes the branch at SSR time and goes stale after\n    // client-side toggles.\n    const activeIndex = evaluateActiveCondition(this.groups, this.elseContent);\n    const existing = getWhenRuntime(startMarker);\n    const serverBranch = existing ? existing.activeIndex : decodeBranch(startMarker.textContent);\n    const branchMatches = !pair.recreated &&\n      (serverBranch === undefined || serverBranch === activeIndex);\n\n    if (branchMatches) {\n      // Re-run active branch content to register reactivity on existing nodes\n      if (activeIndex !== null) {\n        const contentToRender = activeIndex >= 0 ? this.groups[activeIndex].content : this.elseContent;\n        // applyModifiers (not a bare applyNodeModifier): a node that could\n        // not be claimed is inserted at the claim cursor instead of dropped.\n        // One call per item — every branch item shares the block's `index`,\n        // as in renderContentItems.\n        for (const item of contentToRender) {\n          applyModifiers(host, [item as NodeModifier<TTagName>], index);\n        }\n      }\n      // Remove the SSR nodes the branch did not claim (same as list()).\n      let leftover = peekChild(parentNode);\n      while (leftover && leftover !== endMarker) {\n        const next: Node | null = leftover.nextSibling;\n        safeRemoveChild(leftover);\n        leftover = next;\n      }\n    } else {\n      // Server rendered a different branch (or the markup is unusable):\n      // drop the server content and render the client branch fresh.\n      clearBetweenMarkers(startMarker, endMarker);\n      if (activeIndex !== null) {\n        const contentToRender = activeIndex >= 0 ? this.groups[activeIndex].content : this.elseContent;\n        runWithoutHydration(() => renderContentItems(contentToRender, host, index, endMarker));\n      }\n    }\n\n    // Advance cursor past end marker\n    setCursor(parentNode, endMarker.nextSibling);\n\n    this.createRuntimeFromMarkers(host, index, startMarker, endMarker, activeIndex);\n\n    return startMarker;\n  }\n\n  private createRuntimeFromMarkers(\n    host: ExpandedElement<TTagName>,\n    index: number,\n    startMarker: Comment,\n    endMarker: Comment,\n    activeIndex: number | null = null,\n  ): WhenRuntime<TTagName> {\n    const runtime: WhenRuntime<TTagName> = {\n      startMarker,\n      endMarker,\n      host,\n      index,\n      groups: this.groups,\n      elseContent: this.elseContent,\n      activeIndex,\n    };\n\n    if (isBrowser && !isSerializing()) {\n      registerWhenRuntime(runtime);\n    }\n\n    return runtime;\n  }\n}\n\nexport function createWhenBuilderFunction<TTagName extends ElementTagName>(\n  builder: WhenBuilderImpl<TTagName>\n): WhenBuilder<TTagName> {\n  const nodeModFn = function(host: ExpandedElement<TTagName>, index: number): Node {\n    return builder.render(host, index);\n  };\n\n  return Object.assign(nodeModFn, {\n    when: function(condition: WhenCondition, ...content: WhenContent<TTagName>[]): WhenBuilder<TTagName> {\n      return createWhenBuilderFunction(builder.cloneWith({ condition, content }));\n    },\n    else: function(...content: WhenContent<TTagName>[]): WhenBuilder<TTagName> {\n      return createWhenBuilderFunction(builder.cloneWith(undefined, content));\n    },\n  }) as unknown as WhenBuilder<TTagName>;\n}\n\nexport { WhenBuilderImpl };\n","import { WhenBuilderImpl, createWhenBuilderFunction } from \"./builder\";\n\nexport { updateWhenRuntimes } from \"./runtime\";\n\n/**\n * Creates a conditional rendering block (when/else logic).\n *\n * Renders different content based on boolean conditions, similar to if/else statements.\n * Conditions can be static booleans (read once) or functions that are re-evaluated\n * on every update().\n *\n * @param condition - Boolean value or function returning a boolean\n * @param content - Content to render when condition is true\n * @returns A builder that allows chaining additional .when() or .else() branches\n *\n * @example\n * ```ts\n * let isLoggedIn = false;\n *\n * div(\n *   when(() => isLoggedIn,\n *     span('Welcome back!')\n *   )\n *   .else(\n *     button('Login', { onClick: () => { isLoggedIn = true; update(); } })\n *   )\n * )\n * ```\n *\n * @example\n * ```ts\n * // Multiple conditions\n * let status: 'loading' | 'error' | 'ready' = 'loading';\n *\n * div(\n *   when(() => status === 'loading',\n *     p('Loading…')\n *   )\n *   .when(() => status === 'error',\n *     p('Something went wrong')\n *   )\n *   .else(\n *     p('Ready')\n *   )\n * )\n * ```\n */\nexport function when<TTagName extends ElementTagName = ElementTagName>(\n  condition: WhenCondition,\n  ...content: WhenContent<TTagName>[]\n): WhenBuilder<TTagName> {\n  const builder = new WhenBuilderImpl<TTagName>([{ condition, content }], []);\n  return createWhenBuilderFunction(builder);\n}\n","/**\n * update() – the heart of nuclo's reactivity. Re-runs every registered\n * reactive part of the page: lists, when() blocks, function-valued\n * attributes and text.\n */\nimport { updateListRuntimes } from \"../list/runtime\";\nimport { notifyReactiveElements } from \"./reactive-attributes\";\nimport { notifyReactiveTextNodes } from \"./reactive-text\";\nimport { updateWhenRuntimes } from \"../when\";\nimport { pruneRegions } from \"../region/runtime\";\nimport { getScopeRoots, indexPending, type UpdateScope } from \"./scope\";\nimport { flushMountQueue } from \"../element/lifecycle\";\n\n// `satisfies` checks every entry matches the signature without widening the tuple type.\nconst updaters = [\n\t// First: a region or view whose tree left the document behind nuclo's back\n\t// is let go of before any when()/list() content runs and looks regions up.\n\tpruneRegions,\n\tupdateListRuntimes,\n\tupdateWhenRuntimes,\n\tnotifyReactiveElements,\n\tnotifyReactiveTextNodes,\n] satisfies ReadonlyArray<(scope?: UpdateScope) => void>;\n\nexport function update(...scopeIds: string[]) {\n\t// File everything registered since the last pass under its scope roots,\n\t// now that the trees it was built in are attached.\n\tindexPending();\n\tconst scope: UpdateScope | undefined = scopeIds.length > 0 ? { roots: getScopeRoots(scopeIds) } : undefined;\n\n\tfor (const fn of updaters) fn(scope);\n\n\t// Every updater above may have inserted new nodes (a new list() row or a\n\t// newly-true when() branch) into an already-connected host. Flush once,\n\t// after all of them ran, so onMount fires exactly once per pass with the\n\t// DOM already settled — not once per updater.\n\tflushMountQueue();\n}\n","import { createListRuntime } from \"./runtime\";\n\n/**\n * Maps items to DOM elements, keeping them in sync with changes.\n * Returns a function compatible with both HTML and SVG contexts.\n */\nexport function list<TItem, TTagName extends ElementTagName = ElementTagName>(\n  itemsProvider: ListItemsProvider<TItem>,\n  render: ListRenderFunction<TItem, TTagName>,\n): ListModifier<TTagName> {\n  return function<TParent extends ElementTagName>(host: ExpandedElement<TParent>, index: number): Comment {\n    const runtime = createListRuntime(itemsProvider, render, host as unknown as ExpandedElement<TTagName>, index);\n    // Return the start marker comment node\n    // Comment is a Node, making this compatible with both HTML and SVG modifiers\n    return runtime.startMarker;\n  } as unknown as ListModifier<TTagName>;\n}\n","import { createMarker, createMarkerPair } from \"../shared/dom\";\nimport {\n  claimChild,\n  claimMarkerPair,\n  isHydrating,\n  peekChild,\n  runFreshAtCursor,\n  runWithoutHydration,\n  setCursor,\n  skipWhitespaceText,\n} from \"../hydration\";\nimport type { RegionRuntime, ViewRuntime } from \"./runtime\";\nimport {\n  attachViews,\n  claimEmpty,\n  decodeCount,\n  dropRegion,\n  liveRegionAt,\n  reclaimEmpty,\n  registerRegion,\n  showEmpty,\n} from \"./runtime\";\n\nexport { sweepRegions } from \"./runtime\";\n\nfunction makeRuntime(\n  options: RegionOptions,\n  host: ExpandedElement<ElementTagName>,\n  index: number,\n  startMarker: Comment,\n  endMarker: Comment,\n): RegionRuntime<ElementTagName> {\n  const empty = options.empty === undefined ? [] : [options.empty];\n  return {\n    id: options.id,\n    type: options.type ?? \"latest\",\n    empty,\n    startMarker,\n    endMarker,\n    host,\n    index,\n    views: [],\n    hidden: [],\n    showingEmpty: false,\n    claimCursor: null,\n    claiming: false,\n    deferred: null,\n  };\n}\n\nfunction freshRegion(\n  options: RegionOptions,\n  host: ExpandedElement<ElementTagName>,\n  index: number,\n): Comment {\n  const { start, end } = createMarkerPair(\"region\", index);\n  const parent = host as unknown as Node & ParentNode;\n  parent.appendChild(start);\n  parent.appendChild(end);\n\n  const runtime = makeRuntime(options, host, index, start, end);\n  // `empty` first: registering drains the views that were waiting for this\n  // id, and the first of them replaces it.\n  showEmpty(runtime);\n  registerRegion(runtime);\n  return start;\n}\n\nfunction hydrateRegion(\n  options: RegionOptions,\n  host: ExpandedElement<ElementTagName>,\n  index: number,\n): Comment {\n  const parent = host as unknown as Node & ParentNode;\n\n  // No region markers at the cursor (SSR output from something else): build\n  // the region from scratch, as when() and list() do.\n  const pair = claimMarkerPair(parent, \"region\");\n  if (!pair) return runFreshAtCursor(parent, () => freshRegion(options, host, index));\n  const { start, end } = pair;\n\n  // The host carries on hydrating its own later children past the region. The\n  // region's content is claimed through a cursor of its own, because the\n  // into() that claims it runs somewhere else entirely in the tree.\n  setCursor(parent, end.nextSibling);\n\n  // A region already live on these markers — forceUpdate(), or hydrate() over\n  // a tree that is live — keeps its runtime and its views: every into() that\n  // re-runs in this pass reclaims its own content in place, so nothing here\n  // can tell a view in another root from server leftovers and nothing is\n  // swept. Only the options are taken fresh.\n  const live = liveRegionAt(start, end);\n  if (live && (live.id !== options.id || live.type !== (options.type ?? \"latest\"))) {\n    dropRegion(live);\n    const runtime = makeRuntime(options, host, index, start, end);\n    runWithoutHydration(() => {\n      showEmpty(runtime);\n      registerRegion(runtime);\n    });\n    return start;\n  }\n  if (live) {\n    live.type = options.type ?? \"latest\";\n    live.empty = options.empty === undefined ? [] : [options.empty];\n    live.host = host;\n    live.index = index;\n    if (live.showingEmpty) reclaimEmpty(live);\n    return start;\n  }\n\n  const runtime = makeRuntime(options, host, index, start, end);\n  if (pair.recreated) {\n    showEmpty(runtime);\n    registerRegion(runtime);\n    return start;\n  }\n\n  runtime.claiming = true;\n  runtime.claimCursor = start.nextSibling;\n  // `-v0` means the server had no views either and what sits between the\n  // markers is the `empty` content — claim it rather than rebuild it. Before\n  // registering: the views waiting for this id replace it, as they would have\n  // on the server had they existed there.\n  if (decodeCount(start.textContent) === 0) claimEmpty(runtime);\n  registerRegion(runtime);\n  return start;\n}\n\n/**\n * Marks a named place in the tree for `into()` to fill.\n *\n * A region decouples *where* content appears from *who* builds it: the layout\n * says `region({ id: \"main\" })` and anything, at any depth, can put content\n * there with `into(\"main\", …)` — no props threaded through every component in\n * between.\n *\n * `type` decides what happens when a region holds more than one view:\n * `\"stack\"` renders all of them, in arrival order, and `\"latest\"` (the\n * default) renders only the newest.\n *\n * Order does not matter: a view written before its region, or rendered into\n * a different root earlier, waits and shows up the moment the region is\n * built. A region that goes away (its when() closes) hands its views back to\n * waiting, so a region that returns under the same id shows them again.\n *\n * @example\n * ```ts\n * div(\n *   region({\n *     id: \"main\",\n *     type: \"stack\",\n *     empty: div(\"Nothing open.\"),\n *   }),\n * )\n *\n * // anywhere else, at any depth, before or after\n * into(\"main\", h1(\"Hello from the main region\"))\n * ```\n */\nexport function region(options: RegionOptions): MarkerModifier {\n  return function (host: ExpandedElement<ElementTagName>, index: number) {\n    return isHydrating() ? hydrateRegion(options, host, index) : freshRegion(options, host, index);\n  };\n}\n\n/** Claims the `<!--view-N-->` anchor the server left at the cursor, if any. */\nfunction claimAnchor(parent: Node): Comment | null {\n  skipWhitespaceText(parent);\n  const next = peekChild(parent);\n  if (!next || next.nodeType !== 8 || !next.textContent?.startsWith(\"view-\")) return null;\n  claimChild(parent);\n  return next as Comment;\n}\n\n/**\n * Renders content into the `region()` with a matching id, wherever that region\n * sits in the tree.\n *\n * `into()` is a portal: where it is written it leaves only an anchor comment,\n * so a component can declare where its own output belongs instead of being\n * handed down to the right place. A page loaded by a router is the usual case\n * — it returns an `into()` and lands in the app's layout without the layout,\n * or the app, knowing anything about it.\n *\n * The content lives exactly as long as the view does: when the `when()` that\n * holds the view closes, or its `list()` row goes, the content leaves the\n * region too. A view whose region is not built yet waits for it.\n *\n * Pass one id, or an object to fill several regions at once. Either form\n * nests: an `into()` inside another view's content targets its own region.\n *\n * @example\n * ```ts\n * // one region\n * into(\"main\", div(h1(\"Eager route\")))\n *\n * // several at once\n * into({\n *   main: div(h1(\"Eager route\")),\n *   sidebar: div(\"Related links\"),\n * })\n * ```\n */\nexport function into(id: string, ...content: WhenContent[]): MarkerModifier;\nexport function into(\n  regions: Readonly<Record<string, WhenContent | readonly WhenContent[]>>,\n): MarkerModifier;\nexport function into(\n  idOrRegions: string | Readonly<Record<string, unknown>>,\n  ...content: WhenContent[]\n): MarkerModifier {\n  const targets: Array<[string, readonly WhenContent<ElementTagName>[]]> =\n    typeof idOrRegions === \"string\"\n      ? [[idOrRegions, content]]\n      : Object.entries(idOrRegions).map(([id, value]) => [\n          id,\n          (Array.isArray(value) ? value : [value]) as readonly WhenContent<ElementTagName>[],\n        ]);\n\n  return function (host: ExpandedElement<ElementTagName>, index: number) {\n    const parent = host as unknown as Node & ParentNode;\n    const anchor = (isHydrating() && claimAnchor(parent)) || createMarker(`view-${index}`);\n    const views: ViewRuntime[] = targets.map(([id, items]) => ({\n      id,\n      content: items,\n      anchor,\n      region: null,\n      pendingRef: null,\n      first: null,\n      last: null,\n    }));\n    attachViews(anchor, views);\n    return anchor;\n  };\n}\n","import { startHydration, endHydration, peekChild, setCursor, skipWhitespaceText } from \"./hydration\";\nimport { sweepRegions } from \"./region\";\nimport { safeRemoveChild } from \"./shared/dom\";\nimport { flushMountQueue, mountQueueMark, cancelMountsSince } from \"./element/lifecycle\";\nimport { isFunction, isZeroArityFunction } from \"./shared/type-guards\";\nimport { isBrowser } from \"./shared/environment\";\nimport { logError } from \"./shared/errors\";\n\n/**\n * A zero-arity component function. Rendering one (render(App) instead of\n * render(App())) lets a bare forceUpdate() re-invoke it later to rebuild the\n * tree with fresh static values.\n */\ntype Component<TTagName extends ElementTagName> = () => NodeModFn<TTagName>;\n\ninterface ForcedRoot {\n  root: WeakRef<Element>;\n}\n\n/**\n * Iteration holds only weak roots; component closures live under their DOM\n * root in a WeakMap so a closure capturing its own root is collectible too.\n */\nconst forcedComponents = new WeakMap<Element, { component: Component<ElementTagName> }>();\nconst forcedRoots: ForcedRoot[] = [];\nconst forcedRootFinalizer = typeof FinalizationRegistry !== \"undefined\"\n  ? new FinalizationRegistry<ForcedRoot>((entry) => {\n      const i = forcedRoots.indexOf(entry);\n      if (i !== -1) forcedRoots.splice(i, 1);\n    })\n  : null;\n\n/**\n * Distinguishes render(App, ...) — a zero-arity component returning a\n * NodeModFn — from render(App(), ...) — the NodeModFn itself (which always\n * declares (parent, index)). Anything else passes through unchanged.\n */\nfunction unwrapComponent<TTagName extends ElementTagName>(\n  fn: NodeModFn<TTagName> | Component<TTagName>,\n): { build: NodeModFn<TTagName>; component: Component<TTagName> | null } {\n  if (isZeroArityFunction(fn)) {\n    const built = (fn as Component<TTagName>)();\n    if (isFunction(built)) {\n      return { build: built as NodeModFn<TTagName>, component: fn as Component<TTagName> };\n    }\n  }\n  return { build: fn as NodeModFn<TTagName>, component: null };\n}\n\nfunction registerForcedRoot(element: unknown, component: Component<ElementTagName> | null) {\n  if (!component || !isBrowser) return;\n  if (!element || (element as Node).nodeType !== 1) return;\n  const root = element as Element;\n  const existing = forcedComponents.get(root);\n  if (existing) {\n    existing.component = component;\n    return;\n  }\n  const entry: ForcedRoot = { root: new WeakRef(root) };\n  forcedComponents.set(root, { component });\n  forcedRoots.push(entry);\n  forcedRootFinalizer?.register(element as Element, entry, entry);\n}\n\n/**\n * Renders a component to a parent element by calling it and appending the result.\n *\n * Pass the component function itself (not its result) to make the root\n * refreshable by a bare forceUpdate() call:\n *\n * ```ts\n * const App = () => div(h1(\"Hello\"));\n * render(App, container);  // forceUpdate() can now rebuild this root\n * render(App(), container); // also valid — but invisible to forceUpdate()\n * ```\n *\n * @param nodeModFn A component function, or a built NodeModFn (div(), h1(), ...)\n * @param parent The parent element to render into (defaults to document.body)\n * @param index The index to pass to the NodeModFn (defaults to 0)\n * @returns The rendered element\n */\nexport function render(\n  nodeModFn: MarkerModifier | (() => MarkerModifier),\n  parent?: Element,\n  index?: number,\n): Comment;\nexport function render<TTagName extends ElementTagName = ElementTagName>(\n  nodeModFn: NodeModFn<TTagName> | (() => NodeModFn<TTagName>),\n  parent?: Element,\n  index?: number\n): ExpandedElement<TTagName>;\nexport function render<TTagName extends ElementTagName = ElementTagName>(\n  nodeModFn: NodeModFn<TTagName> | (() => NodeModFn<TTagName>),\n  parent?: Element,\n  index = 0\n): ExpandedElement<TTagName> | Comment {\n  const { build, component } = unwrapComponent(nodeModFn);\n  const targetParent = (parent || document.body) as ExpandedElement<TTagName>;\n  const mark = mountQueueMark();\n  let element: ExpandedElement<TTagName>;\n  try {\n    element = build(targetParent, index) as ExpandedElement<TTagName>;\n    // Marker blocks (region, list, when) attach their own start/end pair and\n    // return the start marker: re-appending it would move it past the end.\n    if ((element as unknown as Node).parentNode !== targetParent) {\n      (targetParent as unknown as Node).appendChild(element as Node);\n    }\n  } catch (error) {\n    // The half-built tree is discarded: nothing in it may mount later.\n    cancelMountsSince(mark);\n    throw error;\n  }\n  // The whole tree was built off-document and just got attached in this one\n  // call — every onMount queued while building it can fire now.\n  flushMountQueue();\n  registerForcedRoot(element, component as Component<ElementTagName> | null);\n  return element;\n}\n\n/**\n * Hydrates an existing server-rendered DOM tree by walking it in parallel with\n * the component tree, reusing existing nodes and re-attaching reactivity.\n *\n * Instead of clearing the container and creating new DOM nodes (like render()),\n * hydrate() claims existing nodes from the SSR output and registers reactive\n * text nodes, attributes, event listeners, list runtimes, and when runtimes\n * on them.\n *\n * Like render(), passing the component function itself (hydrate(App, ...))\n * makes the root refreshable by a bare forceUpdate() call.\n *\n * @param nodeModFn A component function, or the NodeModFn used for SSR\n * @param parent The parent element containing the SSR HTML (defaults to document.body)\n * @returns The hydrated root element\n *\n * @example\n * ```ts\n * // Server: const html = renderToString(App());\n * // Client:\n * const app = document.getElementById(\"app\")!;\n * // app.innerHTML already contains the SSR HTML\n * hydrate(App, app);\n * ```\n */\nexport function hydrate(\n  nodeModFn: MarkerModifier | (() => MarkerModifier),\n  parent?: Element,\n): Comment;\nexport function hydrate<TTagName extends ElementTagName = ElementTagName>(\n  nodeModFn: NodeModFn<TTagName> | (() => NodeModFn<TTagName>),\n  parent?: Element,\n): ExpandedElement<TTagName>;\nexport function hydrate<TTagName extends ElementTagName = ElementTagName>(\n  nodeModFn: NodeModFn<TTagName> | (() => NodeModFn<TTagName>),\n  parent?: Element,\n): ExpandedElement<TTagName> | Comment {\n  const { build, component } = unwrapComponent(nodeModFn);\n  const element = hydrateRoot(build, parent, false, null);\n  registerForcedRoot(element, component as Component<ElementTagName> | null);\n  return element;\n}\n\n/**\n * Re-evaluates every component-rendered root against its live DOM — including\n * static values that update() never touches (plain strings, numbers,\n * attribute literals captured when the tree was built):\n *\n * ```ts\n * const App = () => div(h1(labels[language].title), ...);\n * render(App, container);   // pass the component function, not App()\n * // later, after `language` changed:\n * forceUpdate();            // every such root is rebuilt in place\n * ```\n *\n * Existing DOM nodes are reused in place (same claim walk as hydrate()), so\n * element state — focus, input values, scroll — survives. Listeners, reactive\n * resolvers and class/inline-style state on reused elements are replaced by\n * the new build; lifecycle hooks on reused elements keep their original\n * registrations (onMount does not re-fire). Nodes the new tree no longer\n * produces are removed with full cleanup (onDestroy fires) — including\n * whitespace-only text inside the tree that sits where an element or block is\n * now expected (the container's own whitespace is never touched).\n *\n * Roots rendered from an already-built tree (render(App())) are not\n * registered — their static values were captured and cannot be re-evaluated.\n * The explicit form forceUpdate(App(), parent) force-rehydrates one tree\n * manually and returns its root element.\n *\n * Use update() for ordinary reactivity — forceUpdate() is for rare, sweeping\n * changes (e.g. switching the UI language).\n */\nexport function forceUpdate(): void;\nexport function forceUpdate(\n  nodeModFn: MarkerModifier | (() => MarkerModifier),\n  parent?: Element,\n): Comment;\nexport function forceUpdate<TTagName extends ElementTagName = ElementTagName>(\n  nodeModFn: NodeModFn<TTagName> | (() => NodeModFn<TTagName>),\n  parent?: Element,\n): ExpandedElement<TTagName>;\nexport function forceUpdate<TTagName extends ElementTagName = ElementTagName>(\n  nodeModFn?: NodeModFn<TTagName> | (() => NodeModFn<TTagName>),\n  parent?: Element,\n): ExpandedElement<TTagName> | Comment | void {\n  if (nodeModFn !== undefined) {\n    const { build } = unwrapComponent(nodeModFn);\n    return hydrateRoot(build, parent, true, null);\n  }\n\n  let write = 0;\n  for (let read = 0; read < forcedRoots.length; read++) {\n    const entry = forcedRoots[read];\n    const root = entry.root.deref();\n    const parentEl = root?.parentNode;\n    // Collected, disconnected or reparented-out-of-an-element roots drop out.\n    if (!root || !root.isConnected || !parentEl || parentEl.nodeType !== 1) {\n      forcedRootFinalizer?.unregister(entry);\n      if (root) forcedComponents.delete(root);\n      continue;\n    }\n    const record = forcedComponents.get(root)!;\n    try {\n      const build = record.component();\n      const el = hydrateRoot(\n        build,\n        parentEl as Element,\n        true,\n        root,\n      );\n      // The walk replaces the root only on a tag mismatch — track the new one.\n      if ((el as unknown) !== root) {\n        forcedComponents.delete(root);\n        forcedComponents.set(el as unknown as Element, record);\n        entry.root = new WeakRef(el as unknown as Element);\n        forcedRootFinalizer?.unregister(entry);\n        forcedRootFinalizer?.register(el as unknown as Element, entry, entry);\n      }\n    } catch (error) {\n      logError(\"forceUpdate(): component threw; keeping this root's previous DOM\", error);\n    }\n    forcedRoots[write++] = entry;\n  }\n  forcedRoots.length = write;\n}\n\nfunction hydrateRoot<TTagName extends ElementTagName>(\n  nodeModFn: NodeModFn<TTagName>,\n  parent: Element | undefined,\n  force: boolean,\n  at: Element | null,\n): ExpandedElement<TTagName> {\n  const targetParent = (parent || document.body) as ExpandedElement<TTagName>;\n  const parentNode = targetParent as unknown as Node & ParentNode;\n  startHydration(force);\n  // A known root (bare forceUpdate()): pin the claim cursor to it so the walk\n  // starts exactly there — foreign siblings in the parent are never touched.\n  if (at) setCursor(parentNode, at);\n  // The container belongs to the app, not to nuclo: step over its template\n  // whitespace here so a force pass (which drops stale whitespace text inside\n  // the tree it rebuilds) never removes it.\n  else if (force) skipWhitespaceText(parentNode, false);\n  const mark = mountQueueMark();\n  let element: ExpandedElement<TTagName>;\n  try {\n    element = nodeModFn(targetParent, 0) as ExpandedElement<TTagName>;\n    const elementNode = element as unknown as Node | null | undefined;\n    // Claim failed (empty container or tag mismatch): the factory built a\n    // fresh, detached root. Replace the mismatched SSR node at the cursor —\n    // or append when there is nothing to replace — so the app is always live\n    // in the document. Only the single candidate node is touched; siblings\n    // (other roots, scripts) are preserved.\n    if (elementNode && elementNode.nodeType === 1 && elementNode.parentNode !== parentNode) {\n      const stale = peekChild(parentNode);\n      if (stale) {\n        const after = stale.nextSibling;\n        parentNode.insertBefore(elementNode, stale);\n        safeRemoveChild(stale);\n        setCursor(parentNode, after);\n      } else {\n        parentNode.appendChild(elementNode);\n        setCursor(parentNode, null);\n      }\n    }\n  } catch (error) {\n    // Fresh nodes of the half-built tree are discarded: they may not mount\n    // later. Claimed nodes are live in the document and keep their turn.\n    cancelMountsSince(mark);\n    throw error;\n  } finally {\n    endHydration();\n    // After the pass, not during it: only now is it settled which views a\n    // region got, so server markup none of them claimed can be dropped.\n    sweepRegions();\n  }\n  // Claimed nodes were already connected (they're existing SSR output inside\n  // the live `parent`); freshly-built replacement nodes just got attached\n  // above. Either way, by this point everything nodeModFn() touched is\n  // settled in the document, so queued onMount callbacks can fire — but only\n  // on this success path. Placed outside the try/finally on purpose: if\n  // nodeModFn() throws, the tree it was building is incomplete/inconsistent,\n  // so any mounts it had already queued are left Pending rather than fired.\n  flushMountQueue();\n  return element;\n}\n","/**\n * Shared generated-CSS engine state.\n *\n * One stylesheet, one rule registry, shared by every `createCss` instance so\n * identical declarations dedupe globally and cascade order stays deterministic:\n * base rules first (insertion order), then one grouping rule per at-rule query\n * in registration order (theme `screens` order).\n *\n * Browser: rules are injected through CSSOM with O(1) appends — no rescans.\n * SSR: rules accumulate in the registry; `getCssText()` serializes them.\n *\n * The state below lives on `globalThis`, keyed by a `Symbol.for(...)` (the\n * global symbol registry, shared by every realm-local copy of this module).\n * `nuclo` publishes `.`, `./ssr`, and `./polyfill` as independently built\n * bundle files (see tsdown.config.ts) — a consumer that resolves them\n * through normal package resolution (any bundler/runtime that doesn't\n * alias every subpath to this same source file) loads two or three\n * separate copies of this module, each with its own module-scope\n * variables. Without a realm-wide singleton, `css()` (from `nuclo`) would\n * mint rules into one copy's registry while `getCssText()` (from\n * `nuclo/ssr`) reads an entirely different, always-empty one — SSR output\n * would render the right classes with no matching CSS at all. Storing the registry on `globalThis` instead makes\n * every copy of this module share the same state regardless of how many\n * times it ends up bundled.\n *\n * The registry never shrinks on its own: atomCache/atomMeta/rawKeys/\n * baseRules/queryRules retain every rule for the life of the process —\n * content-addressed dedup needs a durable record of what each class means,\n * and the engine has no way to know whether a minted class still backs a\n * live DOM node (it's deliberately decoupled from element/list lifecycle),\n * so it can't safely evict. Only resetStyles() (a manual test helper)\n * clears it. This is fine for the intended use — a bounded design-token\n * vocabulary — but a caller piping truly per-instance dynamic values\n * through css({ raw: {...} }) (e.g. per-row data in a list) mints one\n * permanent class per unique value; prefer the `style` prop\n * (element/inline-style.ts) for values that vary per instance rather than\n * per design token. See test/style/registry-growth.test.ts.\n */\n\nexport interface BlockMeta {\n\treadonly query: string | undefined;\n\treadonly suffix: string;\n\treadonly decls: ReadonlyArray<readonly [string, string]>;\n\t/** Author-supplied identity from `css(name, …)`; inherited by cx() merges. */\n\treadonly name: string | undefined;\n}\n\ninterface EngineState {\n\t// Registry — the source of truth for all generated CSS.\n\t// atomCache: declaration-block key -> class name (dedup)\n\t// atomMeta: class name -> what the class means (its selector context and its\n\t// declarations). This is what lets cx() merge two same-context classes at the\n\t// declaration level instead of guessing: the engine can always recover the\n\t// exact content of any class it minted.\n\tatomCache: Map<string, string>;\n\tatomMeta: Map<string, BlockMeta>;\n\trawKeys: Set<string>;\n\tbaseRules: string[];\n\tqueryRules: Map<string, string[]>;\n\tstyleEpoch: number;\n\n\t// Memoized getCssText() output. SSR calls getCssText() once per request, but the\n\t// rule set is stable after warmup — so the serialized sheet is recomputed only\n\t// when a new rule is actually recorded. Invalidated in record() and resetStyles().\n\tcssTextCache: string | null;\n\n\t// Browser CSSOM state. Base rules occupy [0, baseRuleCount); grouping rules\n\t// (one per query, created in registration order) live after them. CSSRule\n\t// references stay live when indices shift, so insertion never rescans.\n\tsheet: CSSStyleSheet | null;\n\tsheetDocument: Document | null;\n\tbaseRuleCount: number;\n\tgroupRules: Map<string, CSSGroupingRule>;\n\n\t// Normalized rules already sitting in a freshly-adopted stylesheet that this\n\t// module didn't insert itself — e.g. server-rendered CSS being hydrated.\n\t// Rebuilt on every fresh bind in ensureSheet(); null when there is nothing\n\t// external to guard against.\n\texternalRules: Map<string, Set<string>> | null;\n\thasExternalGroups: boolean;\n}\n\nfunction createState(): EngineState {\n\treturn {\n\t\tatomCache: new Map(),\n\t\tatomMeta: new Map(),\n\t\trawKeys: new Set(),\n\t\tbaseRules: [],\n\t\tqueryRules: new Map(),\n\t\tstyleEpoch: 0,\n\t\tcssTextCache: null,\n\t\tsheet: null,\n\t\tsheetDocument: null,\n\t\tbaseRuleCount: 0,\n\t\tgroupRules: new Map(),\n\t\texternalRules: null,\n\t\thasExternalGroups: false,\n\t};\n}\n\nconst ENGINE_STATE_KEY = Symbol.for(\"nuclo.style.engine.v1\");\nconst globalScope = globalThis as unknown as Record<symbol, EngineState>;\n// Importing the runtime does not allocate the registry until styling is used.\nlet cachedState: EngineState | undefined;\nfunction getState(): EngineState {\n\treturn cachedState ??= globalScope[ENGINE_STATE_KEY] ?? (globalScope[ENGINE_STATE_KEY] = createState());\n}\n\n/** Pre-register at-rule queries so their cascade order follows theme order. */\nexport function registerQueries(queries: Iterable<string>) {\n\tfor (const query of queries) {\n\t\tconst state = getState();\n\t\tif (!state.queryRules.has(query)) state.queryRules.set(query, []);\n\t}\n}\n\nfunction createGroup(s: CSSStyleSheet, query: string): CSSGroupingRule | null {\n\tconst state = getState();\n\ttry {\n\t\tconst idx = s.cssRules.length;\n\t\ts.insertRule(query + \"{}\", idx);\n\t\tconst group = s.cssRules[idx] as CSSGroupingRule;\n\t\tstate.groupRules.set(query, group);\n\t\tstate.groupRules.set(groupQueryOf(group), group);\n\t\treturn group;\n\t} catch {\n\t\treturn null; // unsupported at-rule in this environment\n\t}\n}\n\n// A group prelude is stable while its children grow. Reading cssText on each\n// insertion would serialize all previous children and make loading quadratic.\n// Weak keys allow detached stylesheets to be collected after reset/rebinding.\nconst groupQueries = new WeakMap<CSSRule, string>();\nfunction groupQueryOf(rule: CSSRule) {\n\tconst cached = groupQueries.get(rule);\n\tif (cached !== undefined) return cached;\n\tconst text = rule.cssText;\n\tconst brace = text.indexOf(\"{\");\n\tconst query = (brace === -1 ? text : text.slice(0, brace)).trim();\n\tgroupQueries.set(rule, query);\n\treturn query;\n}\n\nfunction ruleIdentity(rule: CSSRule) {\n\treturn rule instanceof CSSStyleRule ? rule.selectorText : groupQueryOf(rule);\n}\n\nfunction rememberExternalRule(rule: CSSRule, query: string | undefined) {\n\tconst state = getState();\n\tif (!state.externalRules) return;\n\tconst key = contextKeyOf(query, ruleIdentity(rule));\n\tlet texts = state.externalRules.get(key);\n\tif (!texts) {\n\t\ttexts = new Set();\n\t\tstate.externalRules.set(key, texts);\n\t}\n\ttexts.add(rule.cssText);\n}\n\nfunction consumeExternalRule(rule: CSSRule, query: string | undefined) {\n\tconst state = getState();\n\tif (!state.externalRules) return false;\n\tconst key = contextKeyOf(query, ruleIdentity(rule));\n\tconst texts = state.externalRules.get(key);\n\tif (!texts?.delete(rule.cssText)) return false;\n\tif (texts.size === 0) state.externalRules.delete(key);\n\tif (state.externalRules.size === 0) state.externalRules = null;\n\treturn true;\n}\n\n/**\n * Index an already-populated stylesheet found on adopt (SSR output, most\n * commonly): every top-level conditional grouping rule (@media/@container/…)\n * is registered into groupRules (by its reconstructed at-rule text) so later\n * record() calls append into it instead of creating a sibling duplicate. The\n * other rules are indexed by scope, selector/prelude, and normalized cssText\n * so exact server/client matches can be skipped without hiding a changed\n * named or global rule that happens to reuse the same selector.\n */\nfunction indexExternalRules(rules: CSSRuleList) {\n\tconst state = getState();\n\tfor (let i = 0; i < rules.length; i++) {\n\t\tconst rule = rules[i];\n\t\tif (rule instanceof CSSStyleRule) {\n\t\t\trememberExternalRule(rule, undefined);\n\t\t\tcontinue;\n\t\t}\n\t\tconst prelude = groupQueryOf(rule);\n\t\tif (\"cssRules\" in rule && !prelude.startsWith(\"@keyframes\")) {\n\t\t\tconst group = rule as CSSGroupingRule;\n\t\t\tstate.hasExternalGroups = true;\n\t\t\tstate.groupRules.set(prelude, group);\n\t\t\tfor (let j = 0; j < group.cssRules.length; j++) {\n\t\t\t\trememberExternalRule(group.cssRules[j], prelude);\n\t\t\t}\n\t\t} else {\n\t\t\t// @keyframes, @font-face, … — one-shot rules matched by prelude.\n\t\t\trememberExternalRule(rule, undefined);\n\t\t}\n\t}\n}\n\nfunction insertBase(s: CSSStyleSheet, rule: string) {\n\tconst state = getState();\n\ttry {\n\t\ts.insertRule(rule, state.baseRuleCount);\n\t\tconst inserted = s.cssRules[state.baseRuleCount];\n\t\tif (consumeExternalRule(inserted, undefined)) {\n\t\t\ts.deleteRule(state.baseRuleCount);\n\t\t\treturn;\n\t\t}\n\t\tstate.baseRuleCount++;\n\t} catch {\n\t\t// Invalid value/selector: drop the declaration, like browsers do for bad CSS.\n\t}\n}\n\nfunction insertGrouped(group: CSSGroupingRule, rule: string) {\n\tconst state = getState();\n\ttry {\n\t\tconst index = group.cssRules.length;\n\t\tgroup.insertRule(rule, index);\n\t\tconst inserted = group.cssRules[index];\n\t\tif (state.externalRules && consumeExternalRule(inserted, groupQueryOf(group))) group.deleteRule(index);\n\t} catch {\n\t\t// Invalid value/selector: drop the declaration, like browsers do for bad CSS.\n\t}\n}\n\nfunction getOrCreateGroup(s: CSSStyleSheet, query: string): CSSGroupingRule | null {\n\tconst state = getState();\n\tconst direct = state.groupRules.get(query);\n\tif (direct) return direct;\n\tif (!state.hasExternalGroups) return createGroup(s, query);\n\n\t// CSSOM may normalize whitespace in an at-rule prelude. Normalize the\n\t// authored query through a temporary empty group before deciding that an\n\t// adopted SSR group is missing.\n\ttry {\n\t\tconst index = s.cssRules.length;\n\t\ts.insertRule(query + \"{}\", index);\n\t\tconst normalized = groupQueryOf(s.cssRules[index]);\n\t\ts.deleteRule(index);\n\t\tconst existing = state.groupRules.get(normalized);\n\t\tif (existing) {\n\t\t\tstate.groupRules.set(query, existing);\n\t\t\treturn existing;\n\t\t}\n\t} catch {\n\t\treturn null;\n\t}\n\treturn createGroup(s, query);\n}\n\n/**\n * Returns the live stylesheet, (re)binding when the document changes — e.g.\n * fresh jsdom documents between tests. Rebinding replays the whole registry,\n * which replaces v1's per-call classExistsInDOM() DOM scans with a single\n * replay per document.\n */\nexport function ensureSheet(): CSSStyleSheet | null {\n\tconst state = getState();\n\tif (typeof document === \"undefined\") return null;\n\t// The nuclo SSR polyfill provides a document without getElementById — in\n\t// that context rules accumulate in the registry for getCssText() only.\n\tif (typeof document.getElementById !== \"function\") return null;\n\tif (\n\t\tstate.sheet &&\n\t\tstate.sheetDocument === document &&\n\t\tstate.sheet.ownerNode &&\n\t\t(state.sheet.ownerNode as Element).isConnected\n\t) {\n\t\treturn state.sheet;\n\t}\n\tconst existing = document.getElementById(\"nuclo-styles\");\n\tlet el: HTMLStyleElement;\n\tif (existing?.tagName === \"STYLE\") {\n\t\tel = existing as HTMLStyleElement;\n\t} else {\n\t\tel = document.createElement(\"style\");\n\t\tel.id = \"nuclo-styles\";\n\t\tif (existing) existing.replaceWith(el);\n\t\telse document.head.appendChild(el);\n\t}\n\tstate.sheet = el.sheet;\n\tstate.sheetDocument = document;\n\tstate.groupRules.clear();\n\tstate.baseRuleCount = 0;\n\tstate.externalRules = null;\n\tstate.hasExternalGroups = false;\n\tif (!state.sheet) return null;\n\tif (state.sheet.cssRules.length > 0) {\n\t\t// Leading top-level non-group rules (style rules, @keyframes — before\n\t\t// the first @media/@container group) are this element's existing\n\t\t// \"base\" region — count them so insertBase() keeps inserting new base\n\t\t// rules right after them, still ahead of every group.\n\t\tlet i = 0;\n\t\twhile (i < state.sheet.cssRules.length) {\n\t\t\tconst r = state.sheet.cssRules[i];\n\t\t\tif (!(r instanceof CSSStyleRule) && \"cssRules\" in r && !groupQueryOf(r).startsWith(\"@keyframes\")) break;\n\t\t\ti++;\n\t\t}\n\t\tstate.baseRuleCount = i;\n\t\tstate.externalRules = new Map();\n\t\tindexExternalRules(state.sheet.cssRules);\n\t}\n\tfor (const rule of state.baseRules) insertBase(state.sheet, rule);\n\tfor (const [query, rules] of state.queryRules) {\n\t\tconst group = getOrCreateGroup(state.sheet, query);\n\t\tif (group) for (const rule of rules) insertGrouped(group, rule);\n\t}\n\treturn state.sheet;\n}\n\nfunction record(rule: string, query: string | undefined) {\n\tconst state = getState();\n\t// Bind/replay *before* this rule joins the registry, so a fresh bind's\n\t// replay only ever covers previously-known rules — never this one twice.\n\tconst s = ensureSheet();\n\n\tif (query === undefined) {\n\t\tstate.baseRules.push(rule);\n\t} else {\n\t\tlet bucket = state.queryRules.get(query);\n\t\tif (!bucket) {\n\t\t\tbucket = [];\n\t\t\tstate.queryRules.set(query, bucket);\n\t\t}\n\t\tbucket.push(rule);\n\t}\n\tstate.cssTextCache = null; // a new rule changes the serialized sheet\n\n\tif (s) {\n\t\tif (query === undefined) {\n\t\t\tinsertBase(s, rule);\n\t\t} else {\n\t\t\tconst group = getOrCreateGroup(s, query);\n\t\t\tif (group) insertGrouped(group, rule);\n\t\t}\n\t}\n}\n\n/**\n * Content-addressed ~42-bit hash (two interleaved FNV-1a style passes). Class\n * names must match between server and client for SSR hydration, so a counter\n * is not an option; 42 bits keeps collision odds low (~1e-5 at 10k\n * unique declaration blocks).\n */\nexport function hash(input: string) {\n\tlet a = 0x811c9dc5;\n\tlet b = 0x7ee3623b;\n\tfor (let i = 0; i < input.length; i++) {\n\t\tconst c = input.charCodeAt(i);\n\t\ta = Math.imul(a ^ c, 0x01000193);\n\t\tb = Math.imul(b ^ c, 0x85ebca6b);\n\t}\n\treturn (a >>> 0).toString(36) + ((b >>> 9) % 1296).toString(36);\n}\n\n/** Length-prefixed (query, selector-suffix) key — unambiguous for any strings. */\nexport function contextKeyOf(query: string | undefined, suffix: string) {\n\tconst queryPart = query === undefined ? \"-\" : \"+\" + query.length + \":\" + query;\n\treturn queryPart + suffix.length + \":\" + suffix;\n}\n\nfunction appendKeyPart(key: string, value: string) {\n\treturn key + value.length + \":\" + value;\n}\n\nexport function expandAmpersands(input: string, replacement: string) {\n\tlet expanded = \"\";\n\tlet quote = 0;\n\tfor (let i = 0; i < input.length; i++) {\n\t\tconst code = input.charCodeAt(i);\n\t\tif (code === 92 /* \\\\ */ && i + 1 < input.length) {\n\t\t\texpanded += input[i] + input[++i];\n\t\t\tcontinue;\n\t\t}\n\t\tif (quote !== 0) {\n\t\t\texpanded += input[i];\n\t\t\tif (code === quote) quote = 0;\n\t\t\tcontinue;\n\t\t}\n\t\tif (code === 34 /* \" */ || code === 39 /* ' */) {\n\t\t\tquote = code;\n\t\t\texpanded += input[i];\n\t\t} else {\n\t\t\texpanded += code === 38 /* & */ ? replacement : input[i];\n\t\t}\n\t}\n\treturn expanded;\n}\n\nfunction selectorFor(className: string, suffix: string) {\n\tconst selector = \".\" + className;\n\treturn selector + expandAmpersands(suffix, selector);\n}\n\n/**\n * True for strings usable verbatim as an unescaped CSS class selector:\n * letters/digits/`-`/`_`, not starting with a digit or `-`+digit.\n * Char-code loop rather than a RegExp — this runs on the cold mint path but\n * stays allocation-free either way.\n */\nfunction isValidClassName(name: string) {\n\tif (name.length === 0 || name === \"-\") return false;\n\tfor (let i = 0; i < name.length; i++) {\n\t\tconst c = name.charCodeAt(i);\n\t\tconst ok =\n\t\t\t(c >= 97 && c <= 122) || // a-z\n\t\t\t(c >= 65 && c <= 90) || // A-Z\n\t\t\tc === 45 || c === 95 || // - _\n\t\t\t(i > 0 && c >= 48 && c <= 57); // 0-9, never leading\n\t\tif (!ok) return false;\n\t}\n\t// \"-9foo\" is not a valid identifier start either.\n\tif (name.charCodeAt(0) === 45 && name.length > 1) {\n\t\tconst second = name.charCodeAt(1);\n\t\tif (second >= 48 && second <= 57) return false;\n\t}\n\treturn true;\n}\n\n/**\n * Mint (or reuse) the class for a declaration block in a selector context.\n *\n * Declarations keep their authored order — CSS resolves shorthand/longhand\n * and repeated-property conflicts by declaration order, so reordering (e.g.\n * alphabetical sorting) would silently change what `{ pt: 20, p: 16 }` means.\n * The cost is that the same declarations authored in a different order mint a\n * second, content-identical class — harmless, and rare in practice.\n *\n * `name` is the author's identity for the style (`css(\"app-root\", …)`). It\n * becomes part of the cache key, so two different names never share a class\n * even with identical declarations. With `exactName`, this block *is* the\n * named one and takes the name verbatim; otherwise the name is only a\n * readable prefix on a content-addressed prefix (`app-root-1a2b3c`), which is\n * how a named style's non-base contexts and its cx() merges stay identifiable\n * in devtools without ever colliding with the base class.\n */\nexport function atomBlock(\n\tquery: string | undefined,\n\tsuffix: string,\n\tdecls: ReadonlyArray<readonly [string, string]>,\n\tname?: string,\n\texactName = false,\n) {\n\tconst state = getState();\n\tlet contextKey = contextKeyOf(query, suffix);\n\tfor (const [prop, value] of decls) {\n\t\tcontextKey = appendKeyPart(appendKeyPart(contextKey, prop), value);\n\t}\n\tif (name !== undefined && !isValidClassName(name)) {\n\t\tconsole.warn(\n\t\t\t`[nuclo] css() name ${JSON.stringify(name)} is not a valid CSS class name ` +\n\t\t\t\t\"(letters, digits, - and _ only, not starting with a digit); falling back to a generated name.\",\n\t\t);\n\t\tname = undefined;\n\t}\n\tconst declKey = name === undefined ? \"a\" + contextKey : \"n\" + appendKeyPart(\"\", name) + contextKey;\n\tlet className = state.atomCache.get(declKey);\n\tif (className !== undefined) {\n\t\t// Touch the sheet so a swapped document (tests) gets the replayed rules.\n\t\tensureSheet();\n\t\treturn className;\n\t}\n\n\tif (name === undefined) {\n\t\tclassName = \"n\" + hash(declKey);\n\t} else {\n\t\tclassName = exactName ? name : name + \"-\" + hash(declKey);\n\t\tif (state.atomMeta.has(className)) {\n\t\t\tconsole.warn(\n\t\t\t\t`[nuclo] css() name ${JSON.stringify(className)} is already used by a different style. ` +\n\t\t\t\t\t\"Both rules are emitted under the same class, so they will override each other — rename one.\",\n\t\t\t);\n\t\t}\n\t}\n\n\tlet body = \"\";\n\tfor (const [prop, value] of decls) body += (body ? \";\" : \"\") + prop + \":\" + value;\n\tstate.atomCache.set(declKey, className);\n\tstate.atomMeta.set(className, { query, suffix, decls, name });\n\trecord(selectorFor(className, suffix) + \"{\" + body + \"}\", query);\n\treturn className;\n}\n\n/**\n * Merge two same-context generated classes into one: `second`'s declarations\n * override `first`'s per exact property (shorthand/longhand interplay is left\n * to CSS order), and the combined block mints its own content-addressed class\n * — so cx(base, override) keeps base's untouched properties instead of\n * dropping the whole base class. Deterministic: the same pair always yields\n * the same class name, on server and client alike. A named base passes its\n * name down as a prefix, so `cx(appRoot, active)` reads as `app-root-1a2b3c`.\n */\nexport function mergeBlocks(first: string, second: string) {\n\tconst state = getState();\n\tconst a = state.atomMeta.get(first);\n\tconst b = state.atomMeta.get(second);\n\tif (!a || !b) return second; // unknown input — nothing to merge with\n\tconst concat = [...a.decls, ...b.decls];\n\t// Keep only the last occurrence of each exact property, at its position —\n\t// so a later `padding` still fully resets an earlier `padding-top`.\n\tconst lastIndex = new Map<string, number>();\n\tfor (let i = 0; i < concat.length; i++) lastIndex.set(concat[i][0], i);\n\tconst merged = concat.filter((decl, i) => lastIndex.get(decl[0]) === i);\n\treturn atomBlock(a.query, a.suffix, merged, a.name ?? b.name);\n}\n\n/** Conflict key (query|suffix) for a generated class — lets cx() group classes by selector context. */\nexport function conflictKeyOf(className: string): string | undefined {\n\tconst state = getState();\n\tconst meta = state.atomMeta.get(className);\n\treturn meta === undefined ? undefined : contextKeyOf(meta.query, meta.suffix);\n}\n\n/** Current registry generation, used to invalidate per-instance WeakMap hits after resetStyles(). */\nexport function getStyleEpoch() {\n\treturn (cachedState ?? globalScope[ENGINE_STATE_KEY])?.styleEpoch ?? 0;\n}\n\n/** Register a non-atomic rule (keyframes, global styles) once per dedupe key. */\nexport function addRawRule(dedupeKey: string, rule: string) {\n\tconst state = getState();\n\tif (state.rawKeys.has(dedupeKey)) {\n\t\tensureSheet();\n\t\treturn;\n\t}\n\tstate.rawKeys.add(dedupeKey);\n\trecord(rule, undefined);\n}\n\n/** All generated CSS — base rules first, then at-rule groups in registration order. */\nexport function getCssText() {\n\tconst state = getState();\n\tif (state.cssTextCache !== null) return state.cssTextCache;\n\tlet out = state.baseRules.join(\"\");\n\tfor (const [query, rules] of state.queryRules) {\n\t\tif (rules.length > 0) out += query + \"{\" + rules.join(\"\") + \"}\";\n\t}\n\tstate.cssTextCache = out;\n\treturn out;\n}\n\n/** Clear all engine state (test helper). Removes the injected style element. */\nexport function resetStyles() {\n\tconst state = getState();\n\tstate.atomCache.clear();\n\tstate.atomMeta.clear();\n\tstate.rawKeys.clear();\n\tstate.baseRules.length = 0;\n\tstate.queryRules.clear();\n\tstate.groupRules.clear();\n\tstate.cssTextCache = null;\n\tstate.baseRuleCount = 0;\n\tstate.sheet = null;\n\tstate.sheetDocument = null;\n\tstate.externalRules = null;\n\tstate.hasExternalGroups = false;\n\tstate.styleEpoch++;\n\tif (typeof document !== \"undefined\") {\n\t\tdocument.getElementById(\"nuclo-styles\")?.remove();\n\t}\n}\n","/**\n * camelCase → kebab-case for CSS property (and attribute) names. A leading\n * capital becomes a leading dash, as vendor prefixes need\n * (WebkitTransition → -webkit-transition). Char-code loop with a\n * no-uppercase fast path: SSR runs this per style declaration.\n */\nexport function camelToKebab(str: string) {\n  let firstUpper = 0;\n  for (; firstUpper < str.length; firstUpper++) {\n    const code = str.charCodeAt(firstUpper);\n    if (code >= 65 && code <= 90) break;\n  }\n  if (firstUpper === str.length) return str;\n\n  let result = str.slice(0, firstUpper);\n  for (let i = firstUpper; i < str.length; i++) {\n    const code = str.charCodeAt(i);\n    // A-Z is 65-90, a-z is 97-122 (difference of 32)\n    result += code >= 65 && code <= 90 ? '-' + String.fromCharCode(code + 32) : str[i];\n  }\n  return result;\n}\n\nconst ATTR_ESCAPE_RE = /[&<>\"']/;\nconst TEXT_ESCAPE_RE = /[&<>]/;\n\n/**\n * Escapes HTML special characters in attribute values (includes \" and ')\n */\nexport function escapeHtml(text: string) {\n  // Fast path: most strings contain no special characters at all.\n  const first = ATTR_ESCAPE_RE.exec(text);\n  if (!first) return text;\n\n  let result = '';\n  let last = 0;\n  for (let i = first.index; i < text.length; i++) {\n    let escaped: string;\n    switch (text.charCodeAt(i)) {\n      case 38: escaped = '&amp;'; break;   // &\n      case 60: escaped = '&lt;'; break;    // <\n      case 62: escaped = '&gt;'; break;    // >\n      case 34: escaped = '&quot;'; break;  // \"\n      case 39: escaped = '&#039;'; break;  // '\n      default: continue;\n    }\n    result += text.slice(last, i) + escaped;\n    last = i + 1;\n  }\n  return result + text.slice(last);\n}\n\n/**\n * Escapes HTML special characters in text node content.\n * Only &, < and > need escaping — quotes are safe inside text nodes.\n */\nexport function escapeText(text: string) {\n  const first = TEXT_ESCAPE_RE.exec(text);\n  if (!first) return text;\n\n  let result = '';\n  let last = 0;\n  for (let i = first.index; i < text.length; i++) {\n    let escaped: string;\n    switch (text.charCodeAt(i)) {\n      case 38: escaped = '&amp;'; break;  // &\n      case 60: escaped = '&lt;'; break;   // <\n      case 62: escaped = '&gt;'; break;   // >\n      default: continue;\n    }\n    result += text.slice(last, i) + escaped;\n    last = i + 1;\n  }\n  return result + text.slice(last);\n}\n\n/**\n * IDL property name → HTML content attribute name, for the camelCase keys a\n * real element reflects (tabIndex → tabindex, htmlFor → for,\n * ariaDescribedBy → aria-describedby, httpEquiv → http-equiv). Lowercase and\n * kebab-case names pass through unchanged. SSR runs this per polyfill attribute.\n */\nexport function propertyToAttribute(name: string) {\n  switch (name) {\n    case 'htmlFor': return 'for';\n    case 'httpEquiv': return 'http-equiv';\n    case 'acceptCharset': return 'accept-charset';\n    case 'defaultValue': return 'value';\n    case 'defaultChecked': return 'checked';\n    case 'defaultSelected': return 'selected';\n  }\n  // ARIA reflection: one dash after \"aria\", the rest lowercased\n  // (ariaDescribedBy → aria-describedby, not aria-described-by).\n  const c = name.charCodeAt(4);\n  if (c >= 65 && c <= 90 && name.startsWith('aria')) return 'aria-' + name.slice(4).toLowerCase();\n  return name.toLowerCase();\n}\n","/**\n * nuclo styling — theme-aware, typed CSS-in-TS.\n *\n * One typed object in, one generated class per selector context out (a class\n * groups every declaration that shares its query + pseudo-selector, so a\n * base style and a :hover override always compile to at least two classes):\n *\n *   const { css, cx } = createCss({\n *     colors: { primary: \"#6366f1\" },\n *     screens: { md: \"(min-width: 768px)\" },\n *   });\n *   const button = css({ px: 24, py: 12, bg: \"primary\", rounded: 8, hover: { bg: \"#4f46e5\" } });\n *   div(button, \"Save\"); // button is { className } — a regular nuclo attributes object\n */\nimport { atomBlock, addRawRule, conflictKeyOf, contextKeyOf, ensureSheet, expandAmpersands, getStyleEpoch, hash, mergeBlocks, registerQueries } from \"./engine\";\nimport { camelToKebab } from \"../shared/strings\";\n\n// ---------------------------------------------------------------------------\n// Types live in types/style.d.ts (shipped with the package) so the published\n// global declarations can import them without reaching into unpublished src/.\n// They are re-exported here so module-style consumers keep the same surface.\n// ---------------------------------------------------------------------------\nimport type {\n\tClassInput,\n\tCssInstance,\n\tFlatStyle,\n\tKeyframeFrames,\n\tPseudo,\n\tStyle,\n\tStyleResult,\n\tThemeConfig,\n\tVariantDefinitions,\n\tVariantProps,\n\tVariantsConfig,\n\tVariantsFn,\n} from \"../../types/style\";\n\nexport type {\n\tClassInput,\n\tCssInstance,\n\tCSSProperties,\n\tFlatStyle,\n\tKeyframeFrames,\n\tKeyframeStop,\n\tPseudo,\n\tSize,\n\tStyle,\n\tStyleResult,\n\tThemeConfig,\n\tVariantDefinitions,\n\tVariantProps,\n\tVariantsConfig,\n\tVariantsFn,\n} from \"../../types/style\";\n\n\nconst PSEUDO = {\n\thover: \":hover\",\n\tfocus: \":focus\",\n\tfocusVisible: \":focus-visible\",\n\tfocusWithin: \":focus-within\",\n\tactive: \":active\",\n\tvisited: \":visited\",\n\tdisabled: \":disabled\",\n\tenabled: \":enabled\",\n\tchecked: \":checked\",\n\trequired: \":required\",\n\tinvalid: \":invalid\",\n\tvalid: \":valid\",\n\treadOnly: \":read-only\",\n\tfirst: \":first-child\",\n\tlast: \":last-child\",\n\tonly: \":only-child\",\n\todd: \":nth-child(odd)\",\n\teven: \":nth-child(even)\",\n\tempty: \":empty\",\n\tplaceholderShown: \":placeholder-shown\",\n\tplaceholder: \"::placeholder\",\n\tbefore: \"::before\",\n\tafter: \"::after\",\n\tselection: \"::selection\",\n\tmarker: \"::marker\",\n\tfirstLine: \"::first-line\",\n\tfirstLetter: \"::first-letter\",\n} as const satisfies Record<Pseudo, string>;\n\n// ---------------------------------------------------------------------------\n// Runtime tables\n// ---------------------------------------------------------------------------\nconst ALIAS: Record<string, readonly string[]> = {\n\tbg: [\"background\"],\n\tp: [\"padding\"],\n\tpx: [\"padding-left\", \"padding-right\"],\n\tpy: [\"padding-top\", \"padding-bottom\"],\n\tpt: [\"padding-top\"], pr: [\"padding-right\"], pb: [\"padding-bottom\"], pl: [\"padding-left\"],\n\tm: [\"margin\"],\n\tmx: [\"margin-left\", \"margin-right\"],\n\tmy: [\"margin-top\", \"margin-bottom\"],\n\tmt: [\"margin-top\"], mr: [\"margin-right\"], mb: [\"margin-bottom\"], ml: [\"margin-left\"],\n\tw: [\"width\"], h: [\"height\"],\n\tminW: [\"min-width\"], maxW: [\"max-width\"], minH: [\"min-height\"], maxH: [\"max-height\"],\n\tsize: [\"width\", \"height\"],\n\ttext: [\"font-size\"],\n\tfont: [\"font-family\"],\n\tweight: [\"font-weight\"],\n\tleading: [\"line-height\"],\n\ttracking: [\"letter-spacing\"],\n\talign: [\"text-align\"],\n\titems: [\"align-items\"],\n\tjustify: [\"justify-content\"],\n\tz: [\"z-index\"],\n\trounded: [\"border-radius\"],\n\tshadow: [\"box-shadow\"],\n\tselect: [\"user-select\"],\n};\n\nconst COMPOSITE: Record<string, Record<string, string>> = {\n\trow: { display: \"flex\", \"flex-direction\": \"row\" },\n\tcol: { display: \"flex\", \"flex-direction\": \"column\" },\n\tcenter: { \"align-items\": \"center\", \"justify-content\": \"center\" },\n\ttruncate: { overflow: \"hidden\", \"text-overflow\": \"ellipsis\", \"white-space\": \"nowrap\" },\n};\n\n/** CSS property → theme token table it resolves against. */\nconst TOKEN_PROP: Record<string, keyof ThemeConfig> = {\n\tbackground: \"colors\",\n\t\"background-color\": \"colors\",\n\tcolor: \"colors\",\n\t\"border-color\": \"colors\",\n\t\"border-top-color\": \"colors\",\n\t\"border-right-color\": \"colors\",\n\t\"border-bottom-color\": \"colors\",\n\t\"border-left-color\": \"colors\",\n\t\"outline-color\": \"colors\",\n\t\"caret-color\": \"colors\",\n\t\"text-decoration-color\": \"colors\",\n\t\"font-family\": \"fonts\",\n\t\"box-shadow\": \"shadows\",\n\t\"border-radius\": \"radii\",\n};\n\n/** Properties where bare numbers stay unitless instead of becoming px. */\nconst UNITLESS = new Set([\n\t\"z-index\", \"opacity\", \"font-weight\", \"line-height\", \"flex\", \"flex-grow\",\n\t\"flex-shrink\", \"order\", \"aspect-ratio\", \"zoom\", \"scale\", \"column-count\",\n\t\"orphans\", \"widows\", \"tab-size\", \"animation-iteration-count\", \"grid-column\", \"grid-row\",\n]);\n\n// Property names repeat across css() calls, so conversions are memoized, with\n// a ceiling for arbitrary custom property names. Already-lowercase names skip\n// the cache entirely.\nconst kebabCache = new Map<string, string>();\nfunction kebab(prop: string) {\n\tif (!/[A-Z]/.test(prop)) return prop;\n\tlet out = kebabCache.get(prop);\n\tif (out === undefined) {\n\t\tout = camelToKebab(prop);\n\t\tif (kebabCache.size >= 512) kebabCache.clear();\n\t\tkebabCache.set(prop, out);\n\t}\n\treturn out;\n}\n\nfunction toQuery(screen: string) {\n\treturn screen.charCodeAt(0) === 64 /* @ */ ? screen : \"@media \" + screen;\n}\n\n/**\n * True for an @media prelude that is a bare condition list (\"(min-width: 40em)\n * and (hover)\") rather than one led by a media type (\"print\", \"only screen\").\n * Only a bare list can sit on the right of an `and`: per the media-query\n * grammar a type (and the `only` keyword) must lead the whole query, so\n * \"(min-width: 768px) and print\" is not a valid query — every browser\n * normalizes it to `not all` and the block silently never matches.\n */\nfunction isBareCondition(condition: string) {\n\treturn condition.charCodeAt(0) === 40 /* ( */;\n}\n\n/** A leading `not` negates the whole query, so it can never be flattened with `and`. */\nfunction leadsWithNot(condition: string) {\n\tif (!condition.startsWith(\"not\")) return false;\n\tconst after = condition.charCodeAt(3);\n\treturn Number.isNaN(after) || after === 32 /* space */ || after === 40 /* ( */;\n}\n\nfunction combineQuery(outer: string | undefined, inner: string) {\n\t// Nested @media conditions combine with \"and\"; other combinations: inner wins.\n\tif (outer !== undefined && outer.startsWith(\"@media\") && inner.startsWith(\"@media\")) {\n\t\tconst outerCondition = outer.slice(6).trim();\n\t\tconst innerCondition = inner.slice(6).trim();\n\t\t// Put the media-type side first — the only arrangement the grammar allows.\n\t\tif (!leadsWithNot(outerCondition) && !leadsWithNot(innerCondition)) {\n\t\t\tif (isBareCondition(innerCondition)) return \"@media \" + outerCondition + \" and \" + innerCondition;\n\t\t\tif (isBareCondition(outerCondition)) return \"@media \" + innerCondition + \" and \" + outerCondition;\n\t\t}\n\t\t// Two media types, or a `not` on either side: no single flat prelude means\n\t\t// what was authored, and the engine emits one group per query rather than\n\t\t// nested groups. Drop the outer condition (as for any other nested at-rule)\n\t\t// instead of emitting a prelude that silently matches nothing.\n\t\tconsole.warn(\n\t\t\t`[nuclo] cannot combine nested media queries ${JSON.stringify(outer)} and ${JSON.stringify(inner)}; ` +\n\t\t\t\t\"using the inner query alone. Author one query that states both conditions.\",\n\t\t);\n\t\treturn inner;\n\t}\n\treturn inner;\n}\n\n/**\n * Deep-merge style objects, later sources winning per property — recurses\n * into nested pseudo/screen/&/@ blocks and `raw` so a style set two levels\n * deep still overrides precisely. Used by variants() to combine base with\n * selected variants/compounds *before* compiling: css() mints one class per\n * selector context, so merging after compilation (via cx()) would only be\n * able to replace a whole context's class, not override one property in it.\n */\nfunction mergeStyle(target: Record<string, unknown>, source: Record<string, unknown>): Record<string, unknown> {\n\tfor (const key in source) {\n\t\tconst value = source[key];\n\t\tconst existing = target[key];\n\t\tif (\n\t\t\tvalue !== null && typeof value === \"object\" && !Array.isArray(value) &&\n\t\t\texisting !== null && typeof existing === \"object\" && !Array.isArray(existing)\n\t\t) {\n\t\t\ttarget[key] = mergeStyle({ ...(existing as Record<string, unknown>) }, value as Record<string, unknown>);\n\t\t} else {\n\t\t\ttarget[key] = value;\n\t\t}\n\t}\n\treturn target;\n}\n\n// A class rather than an object literal + Object.defineProperty: toString()\n// lives on the prototype, which is non-enumerable by spec at no per-call\n// cost — attribute application iterates Object.keys()/for-in and must only\n// see className, same contract the old defineProperty call paid for on\n// every mint. This runs on every cx() call (no cache) and every css() cache\n// miss, so the allocation shape matters.\nclass StyleResultImpl {\n\treadonly className: string;\n\tconstructor(className: string) {\n\t\tthis.className = className;\n\t}\n\ttoString() {\n\t\treturn this.className;\n\t}\n}\n\nfunction makeResult(className: string): StyleResult {\n\treturn new StyleResultImpl(className);\n}\n\nfunction pickClass(picked: Map<string, string>, name: string) {\n\tconst key = conflictKeyOf(name);\n\tif (key === undefined) {\n\t\t// External class the engine didn't mint — pass through, dedupe by name.\n\t\tpicked.set(name, name);\n\t\treturn;\n\t}\n\tconst prev = picked.get(key);\n\tif (prev === undefined || prev === name) picked.set(key, name);\n\t// Same selector context seen twice: merge declaration-wise, later wins per\n\t// property. Minting is content-addressed, so a redundant merge (override\n\t// restates every property) collapses back to the override's own class.\n\telse picked.set(key, mergeBlocks(prev, name));\n}\n\nfunction collectClassString(className: string, picked: Map<string, string>) {\n\tlet start = 0;\n\tfor (let i = 0; i <= className.length; i++) {\n\t\tconst code = i === className.length ? 32 : className.charCodeAt(i);\n\t\tconst whitespace = code === 32 || code === 9 || code === 10 || code === 12 || code === 13;\n\t\tif (!whitespace) continue;\n\t\tif (i > start) pickClass(picked, className.slice(start, i));\n\t\tstart = i + 1;\n\t}\n}\n\nfunction collectClasses(inputs: readonly ClassInput[], picked: Map<string, string>) {\n\tfor (const input of inputs) {\n\t\tif (!input) continue;\n\t\tif (typeof input === \"string\") {\n\t\t\tcollectClassString(input, picked);\n\t\t} else if (Array.isArray(input)) {\n\t\t\tcollectClasses(input, picked);\n\t\t} else {\n\t\t\tcollectClassString((input as StyleResult).className, picked);\n\t\t}\n\t}\n}\n\nfunction composeClassName(inputs: readonly ClassInput[]) {\n\tconst picked = new Map<string, string>();\n\tcollectClasses(inputs, picked);\n\tlet className = \"\";\n\tfor (const name of picked.values()) className += (className ? \" \" : \"\") + name;\n\treturn className;\n}\n\n// Memoizes cx(a, b) by the identity of its two arguments — the shape of a\n// per-render `cx(base, active)` conditional-class helper, called with the\n// same two object references every time. Mirrors css()'s own memo (below):\n// nested WeakMaps so entries die with either argument, epoch-gated so a\n// resetStyles() call can't hand back a className with no backing rule.\nconst cxPairMemo = new WeakMap<object, WeakMap<object, { epoch: number; first: string; second: string; result: StyleResult }>>();\n\nfunction isPlainCxObject(value: ClassInput): value is StyleResult {\n\treturn !!value && typeof value === \"object\" && !Array.isArray(value);\n}\n\n/**\n * Compose class lists with exact conflict resolution: when two inputs style\n * the same (query, selector-suffix) context, their declaration blocks merge\n * with the later input winning per property — the merged block gets its own\n * content-addressed class, so `cx(base, active)` keeps every base property\n * the active style doesn't override. Works because the engine remembers what\n * every class it minted means. Unknown external classes pass through as-is.\n * Nested arrays are flattened, so `cx([a, cond && b], c)` composes the same\n * as `cx(a, cond && b, c)`.\n */\nexport function cx(...inputs: ClassInput[]): StyleResult {\n\tif (inputs.length === 0) return makeResult(\"\");\n\tif (inputs.length === 1) {\n\t\tconst only = inputs[0];\n\t\tif (!only) return makeResult(\"\");\n\t\tif (!Array.isArray(only)) {\n\t\t\tconst name = typeof only === \"string\" ? only : (only as StyleResult).className;\n\t\t\t// Multiple tokens may include conflicting generated classes even in one input.\n\t\t\tif (!/[\\t\\n\\f\\r ]/.test(name)) return makeResult(name);\n\t\t}\n\t}\n\n\tif (inputs.length === 2 && isPlainCxObject(inputs[0]) && isPlainCxObject(inputs[1])) {\n\t\tconst a = inputs[0] as object;\n\t\tconst b = inputs[1] as object;\n\t\tconst epoch = getStyleEpoch();\n\t\tconst inner = cxPairMemo.get(a);\n\t\tconst hit = inner?.get(b);\n\t\tif (hit !== undefined && hit.epoch === epoch && hit.first === inputs[0].className && hit.second === inputs[1].className) {\n\t\t\tensureSheet();\n\t\t\treturn hit.result;\n\t\t}\n\n\t\tconst result = makeResult(composeClassName(inputs));\n\t\tconst bucket = inner ?? new WeakMap<object, { epoch: number; first: string; second: string; result: StyleResult }>();\n\t\tbucket.set(b, { epoch, first: inputs[0].className, second: inputs[1].className, result });\n\t\tif (!inner) cxPairMemo.set(a, bucket);\n\t\treturn result;\n\t}\n\n\treturn makeResult(composeClassName(inputs));\n}\n\n/** Context key of a style's base (no query, no selector suffix) declarations. */\nconst BASE_CONTEXT = contextKeyOf(undefined, \"\");\n\n// ---------------------------------------------------------------------------\n// Factory\n// ---------------------------------------------------------------------------\nexport function createCss<const T extends ThemeConfig>(theme: T = {} as T): CssInstance<T> {\n\tconst screens: Record<string, string> = theme.screens ?? {};\n\tregisterQueries(Object.values(screens).map(toQuery));\n\n\t// Fast path for repeated css() calls on the same style object. Holds the\n\t// name it was compiled under so a re-compile under a different name can't\n\t// hand back the wrong classes. WeakMap: entries die with the style object.\n\tconst memo = new WeakMap<object, { epoch: number; name: string | undefined; result: StyleResult }>();\n\n\tfunction toCssValue(prop: string, value: string | number) {\n\t\tif (typeof value === \"number\") {\n\t\t\treturn value === 0 || UNITLESS.has(prop) ? String(value) : value + \"px\";\n\t\t}\n\t\tconst group = TOKEN_PROP[prop];\n\t\tif (group !== undefined) {\n\t\t\tconst hit = (theme[group] as Record<string, string> | undefined)?.[value];\n\t\t\tif (hit !== undefined) return hit;\n\t\t}\n\t\treturn value;\n\t}\n\n\t/** Every (query, selector-suffix) context touched by one css() call collects its declarations here, then compiles to a single class. */\n\ttype Bucket = { query: string | undefined; suffix: string; decls: Array<[string, string]> };\n\n\tfunction bucketFor(buckets: Map<string, Bucket>, query: string | undefined, suffix: string): Bucket {\n\t\tconst key = contextKeyOf(query, suffix);\n\t\tlet bucket = buckets.get(key);\n\t\tif (!bucket) {\n\t\t\tbucket = { query, suffix, decls: [] };\n\t\t\tbuckets.set(key, bucket);\n\t\t}\n\t\treturn bucket;\n\t}\n\n\tfunction walk(style: Record<string, unknown>, query: string | undefined, suffix: string, buckets: Map<string, Bucket>) {\n\t\tfor (const key in style) {\n\t\t\tconst value = style[key];\n\t\t\tif (value == null || value === false) continue;\n\n\t\t\tif (typeof value === \"object\") {\n\t\t\t\tif (key === \"raw\") {\n\t\t\t\t\tconst raws = value as Record<string, string | number>;\n\t\t\t\t\tconst decls = bucketFor(buckets, query, suffix).decls;\n\t\t\t\t\tfor (const prop in raws) decls.push([prop, toCssValue(prop, raws[prop])]);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tconst pseudo = (PSEUDO as Record<string, string | undefined>)[key];\n\t\t\t\tif (pseudo !== undefined) {\n\t\t\t\t\twalk(value as Record<string, unknown>, query, suffix + pseudo, buckets);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tconst screen = screens[key];\n\t\t\t\tif (screen !== undefined) {\n\t\t\t\t\twalk(value as Record<string, unknown>, combineQuery(query, toQuery(screen)), suffix, buckets);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tconst first = key.charCodeAt(0);\n\t\t\t\tif (first === 38 /* & */) {\n\t\t\t\t\tconst nested = expandAmpersands(key, \"&\" + suffix);\n\t\t\t\t\twalk(value as Record<string, unknown>, query, nested.slice(1), buckets);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif (first === 64 /* @ */) {\n\t\t\t\t\twalk(value as Record<string, unknown>, combineQuery(query, key), suffix, buckets);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tcontinue; // unknown nested key — unreachable through the typed API\n\t\t\t}\n\n\t\t\tif (value === true) {\n\t\t\t\tconst composite = COMPOSITE[key];\n\t\t\t\tif (composite) {\n\t\t\t\t\tconst decls = bucketFor(buckets, query, suffix).decls;\n\t\t\t\t\tfor (const prop in composite) decls.push([prop, composite[prop]]);\n\t\t\t\t}\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconst targets = ALIAS[key];\n\t\t\tif (targets !== undefined) {\n\t\t\t\tconst decls = bucketFor(buckets, query, suffix).decls;\n\t\t\t\tfor (const prop of targets) decls.push([prop, toCssValue(prop, value as string | number)]);\n\t\t\t} else {\n\t\t\t\tconst prop = kebab(key);\n\t\t\t\tbucketFor(buckets, query, suffix).decls.push([prop, toCssValue(prop, value as string | number)]);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Compile a style object into classes — one per (query, selector-suffix)\n\t * context it touches, not one per property. Idempotent and cached.\n\t *\n\t * An optional leading name gives the style a stable, readable identity:\n\t *\n\t *   css(\"app-root\", { minHeight: \"100vh\", hover: { color: \"red\" } })\n\t *   // → \"app-root app-root-1a2b3c\"\n\t *\n\t * The base context takes the name verbatim; the style's other contexts\n\t * (pseudo-selectors, media queries) take it as a prefix on a\n\t * content-addressed suffix so they stay greppable without ever colliding.\n\t * Named styles are keyed by name as well as content, so they never share a\n\t * class with an unrelated style — which also means they don't dedupe\n\t * against identical anonymous blocks. Name the styles you want to find in\n\t * devtools; leave the rest anonymous to keep the sheet small.\n\t */\n\tfunction css(name: string, style: Style<T>): StyleResult;\n\tfunction css(style: Style<T>): StyleResult;\n\tfunction css(nameOrStyle: string | Style<T>, maybeStyle?: Style<T>): StyleResult {\n\t\tconst named = typeof nameOrStyle === \"string\";\n\t\tconst style = (named ? maybeStyle : nameOrStyle) as Style<T>;\n\t\tconst name = named ? nameOrStyle : undefined;\n\t\tif (style == null) return makeResult(\"\");\n\n\t\t// The memo is keyed by style-object identity; the same object compiled\n\t\t// under two different names must not reuse the first result.\n\t\tconst epoch = getStyleEpoch();\n\t\tconst hit = memo.get(style);\n\t\tif (hit !== undefined && hit.epoch === epoch && hit.name === name) {\n\t\t\tensureSheet();\n\t\t\treturn hit.result;\n\t\t}\n\n\t\tconst buckets = new Map<string, Bucket>();\n\t\twalk(style as Record<string, unknown>, undefined, \"\", buckets);\n\t\tconst classes: string[] = [];\n\t\tfor (const bucket of buckets.values()) {\n\t\t\tif (bucket.decls.length === 0) continue;\n\t\t\tconst isBase = bucket.query === undefined && bucket.suffix === \"\";\n\t\t\tclasses.push(atomBlock(bucket.query, bucket.suffix, bucket.decls, name, isBase));\n\t\t}\n\t\tconst result = makeResult(classes.join(\" \"));\n\t\tmemo.set(style, { epoch, name, result });\n\t\treturn result;\n\t}\n\n\t/** Top-level declarations only (nested blocks are ignored), serialized. */\n\tfunction flatDecls(style: Record<string, unknown>) {\n\t\tconst buckets = new Map<string, Bucket>();\n\t\twalk(style, undefined, \"\", buckets);\n\t\tlet decls = \"\";\n\t\tfor (const [prop, value] of buckets.get(BASE_CONTEXT)?.decls ?? []) decls += (decls ? \";\" : \"\") + prop + \":\" + value;\n\t\treturn decls;\n\t}\n\n\t/** Register a @keyframes block; returns its generated name for use in `animation`. */\n\tfunction keyframes(frames: KeyframeFrames<T>) {\n\t\tlet body = \"\";\n\t\tfor (const stop in frames) {\n\t\t\tbody += stop + \"{\" + flatDecls(frames[stop] as Record<string, unknown>) + \"}\";\n\t\t}\n\t\tconst name = \"nk\" + hash(body);\n\t\taddRawRule(name, \"@keyframes \" + name + \"{\" + body + \"}\");\n\t\treturn name;\n\t}\n\n\t/** Global selector styles (body, resets). Flat properties only. */\n\tfunction globalStyle(selector: string, style: FlatStyle<T>) {\n\t\tconst rule = selector + \"{\" + flatDecls(style as Record<string, unknown>) + \"}\";\n\t\taddRawRule(\"g|\" + rule, rule);\n\t}\n\n\t/**\n\t * Compile a typed variants recipe into a call-with-props function.\n\t *\n\t *   const button = variants({\n\t *     base: { rounded: 8, weight: 600 },\n\t *     variants: {\n\t *       intent: { primary: { bg: \"primary\" }, danger: { bg: \"danger\" } },\n\t *       size:   { sm: { px: 8, py: 4 }, lg: { px: 16, py: 10 } },\n\t *       block:  { true: { display: \"block\", w: \"100%\" } },\n\t *     },\n\t *     defaultVariants: { intent: \"primary\", size: \"sm\" },\n\t *     compoundVariants: [{ intent: \"danger\", size: \"lg\", css: { weight: 700 } }],\n\t *   });\n\t *   div(button({ intent: \"danger\", size: \"lg\" }), \"Delete\");\n\t *\n\t * A call resolves defaults + props into a selection, deep-merges base with\n\t * every matching variant/compound's raw style object (later sources win\n\t * per property — not per class, since css() now mints one class per\n\t * selector context rather than one per property), compiles the merge with\n\t * css(), and caches the result per selection — repeated calls are a Map\n\t * lookup.\n\t */\n\tfunction variants<const V extends VariantDefinitions<T>>(\n\t\tconfig: VariantsConfig<T, V>,\n\t): VariantsFn<V> {\n\t\tconst normalize = (value: unknown): string =>\n\t\t\tvalue === true ? \"true\" : value === false ? \"false\" : String(value);\n\n\t\tconst groups = (config.variants ?? {}) as Record<string, Record<string, Style<T>>>;\n\t\tconst groupNames = Object.keys(groups);\n\t\tconst defaults = (config.defaultVariants ?? {}) as Record<string, unknown>;\n\t\tconst baseStyle = (config.base ?? null) as Record<string, unknown> | null;\n\n\t\tconst compounds = (config.compoundVariants ?? []).map((entry) => {\n\t\t\tconst { css: compoundStyle, ...match } = entry as VariantProps<V> & { css: Style<T> };\n\t\t\tconst conditions: Record<string, string> = {};\n\t\t\tfor (const group in match) conditions[group] = normalize((match as Record<string, unknown>)[group]);\n\t\t\treturn { conditions, style: compoundStyle as Record<string, unknown> };\n\t\t});\n\n\t\tconst cache = new Map<string, StyleResult>();\n\t\tlet cacheEpoch = getStyleEpoch();\n\n\t\treturn function recipe(props?: VariantProps<V>): StyleResult {\n\t\t\tconst epoch = getStyleEpoch();\n\t\t\tif (cacheEpoch !== epoch) {\n\t\t\t\tcache.clear();\n\t\t\t\tcacheEpoch = epoch;\n\t\t\t}\n\t\t\t// Resolve final selection: defaults, overridden by explicit props.\n\t\t\tconst selection: Record<string, string> = {};\n\t\t\tfor (const group of groupNames) {\n\t\t\t\tconst provided = props ? (props as Record<string, unknown>)[group] : undefined;\n\t\t\t\tconst chosen = provided !== undefined && provided !== null ? provided : defaults[group];\n\t\t\t\tif (chosen === undefined || chosen === null) continue;\n\t\t\t\tselection[group] = normalize(chosen);\n\t\t\t}\n\n\t\t\t// Cache the compiled result per selection (stable group order).\n\t\t\tlet key = \"\";\n\t\t\tfor (const group of groupNames) {\n\t\t\t\tconst value = selection[group];\n\t\t\t\tkey += group.length + \":\" + group;\n\t\t\t\tkey += value === undefined ? \"-\" : \"+\" + value.length + \":\" + value;\n\t\t\t}\n\t\t\tconst cached = cache.get(key);\n\t\t\tif (cached) {\n\t\t\t\tensureSheet();\n\t\t\t\treturn cached;\n\t\t\t}\n\n\t\t\tlet merged: Record<string, unknown> = {};\n\t\t\tif (baseStyle) merged = mergeStyle(merged, baseStyle);\n\t\t\tfor (const group of groupNames) {\n\t\t\t\tconst value = selection[group];\n\t\t\t\tif (value !== undefined) {\n\t\t\t\t\tconst style = groups[group][value];\n\t\t\t\t\tif (style) merged = mergeStyle(merged, style as Record<string, unknown>);\n\t\t\t\t}\n\t\t\t}\n\t\t\tfor (const compound of compounds) {\n\t\t\t\tlet matches = true;\n\t\t\t\tfor (const group in compound.conditions) {\n\t\t\t\t\tif (selection[group] !== compound.conditions[group]) {\n\t\t\t\t\t\tmatches = false;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (matches) merged = mergeStyle(merged, compound.style);\n\t\t\t}\n\n\t\t\tconst result = css(merged as Style<T>);\n\t\t\tcache.set(key, result);\n\t\t\treturn result;\n\t\t};\n\t}\n\n\treturn { css, cx, variants, keyframes, globalStyle, theme };\n}\n\n// ---------------------------------------------------------------------------\n// Default themeless instance — registered as globals by the runtime bootstrap.\n// Apps with design tokens create their own instance via createCss(theme).\n//\n// Built lazily on first use rather than at module load: most apps that\n// import nuclo never call css()/variants()/keyframes()/globalStyle(), and\n// createCss() eagerly allocates a memo WeakMap and walks the (empty) theme's\n// screens — work worth skipping entirely for those apps.\n// ---------------------------------------------------------------------------\nlet defaultInstance: CssInstance<object> | undefined;\nfunction getDefaultInstance(): CssInstance<object> {\n\treturn (defaultInstance ??= createCss({}));\n}\n\n/** Themeless css() — full property/variant typing, no tokens or screens. */\nexport const css: {\n\t(name: string, style: Style<object>): StyleResult;\n\t(style: Style<object>): StyleResult;\n} = (nameOrStyle: string | Style<object>, style?: Style<object>): StyleResult =>\n\ttypeof nameOrStyle === \"string\"\n\t\t? getDefaultInstance().css(nameOrStyle, style as Style<object>)\n\t\t: getDefaultInstance().css(nameOrStyle);\n/** Themeless variants() recipe helper. */\nexport const variants: <const V extends VariantDefinitions<object>>(\n\tconfig: VariantsConfig<object, V>,\n) => VariantsFn<V> = (config) => getDefaultInstance().variants(config);\n/** Themeless keyframes() helper. */\nexport const keyframes: (frames: KeyframeFrames<object>) => string = (frames) => getDefaultInstance().keyframes(frames);\n/** Themeless globalStyle() helper. */\nexport const globalStyle: (selector: string, style: FlatStyle<object>) => void = (selector, style) =>\n\tgetDefaultInstance().globalStyle(selector, style);\n","/**\n * The HTML/SVG tag catalogue and the code that turns every tag into a global\n * builder function (`div(...)`, `span(...)`, `rectSvg(...)`, ...).\n */\nimport { createHtmlTagBuilder, createSvgTagBuilder } from \"./factory\";\n\nexport const HTML_TAGS = [\n  \"a\", \"abbr\", \"address\", \"area\", \"article\", \"aside\", \"audio\", \"b\", \"base\",\n  \"bdi\", \"bdo\", \"blockquote\", \"body\", \"br\", \"button\", \"canvas\", \"caption\",\n  \"cite\", \"code\", \"col\", \"colgroup\", \"data\", \"datalist\", \"dd\", \"del\", \"details\",\n  \"dfn\", \"dialog\", \"div\", \"dl\", \"dt\", \"em\", \"embed\", \"fieldset\", \"figcaption\",\n  \"figure\", \"footer\", \"form\", \"h1\", \"h2\", \"h3\", \"h4\", \"h5\", \"h6\", \"head\",\n  \"header\", \"hgroup\", \"hr\", \"html\", \"i\", \"iframe\", \"img\", \"input\", \"ins\",\n  \"kbd\", \"label\", \"legend\", \"li\", \"link\", \"main\", \"map\", \"mark\", \"menu\",\n  \"meta\", \"meter\", \"nav\", \"noscript\", \"object\", \"ol\", \"optgroup\", \"option\",\n  \"output\", \"p\", \"picture\", \"pre\", \"progress\", \"q\", \"rp\", \"rt\", \"ruby\", \"s\",\n  \"samp\", \"script\", \"search\", \"section\", \"select\", \"slot\", \"small\", \"source\",\n  \"span\", \"strong\", \"style\", \"sub\", \"summary\", \"sup\", \"table\", \"tbody\", \"td\",\n  \"template\", \"textarea\", \"tfoot\", \"th\", \"thead\", \"time\", \"title\", \"tr\",\n  \"track\", \"u\", \"ul\", \"var\", \"video\", \"wbr\",\n] as const satisfies ReadonlyArray<ElementTagName>;\n\nexport const SVG_TAGS = [\n  \"a\", \"animate\", \"animateMotion\", \"animateTransform\", \"circle\", \"clipPath\",\n  \"defs\", \"desc\", \"ellipse\", \"feBlend\", \"feColorMatrix\", \"feComponentTransfer\",\n  \"feComposite\", \"feConvolveMatrix\", \"feDiffuseLighting\", \"feDisplacementMap\",\n  \"feDistantLight\", \"feDropShadow\", \"feFlood\", \"feFuncA\", \"feFuncB\", \"feFuncG\",\n  \"feFuncR\", \"feGaussianBlur\", \"feImage\", \"feMerge\", \"feMergeNode\", \"feMorphology\",\n  \"feOffset\", \"fePointLight\", \"feSpecularLighting\", \"feSpotLight\", \"feTile\",\n  \"feTurbulence\", \"filter\", \"foreignObject\", \"g\", \"image\", \"line\", \"linearGradient\",\n  \"marker\", \"mask\", \"metadata\", \"mpath\", \"path\", \"pattern\", \"polygon\", \"polyline\",\n  \"radialGradient\", \"rect\", \"script\", \"set\", \"stop\", \"style\", \"svg\", \"switch\",\n  \"symbol\", \"text\", \"textPath\", \"title\", \"tspan\", \"use\", \"view\",\n] as const satisfies ReadonlyArray<keyof SVGElementTagNameMap>;\n\n\n// Tag builders are installed as self-overwriting lazy getters instead of\n// being created eagerly: registerGlobalTagBuilders() touches ~180 HTML+SVG\n// tags, but a typical app only ever calls a handful of them. Deferring the\n// createHtmlTagBuilder()/createSvgTagBuilder() closure allocation to first\n// access keeps boot-time work and idle memory proportional to what the app\n// actually uses instead of the whole tag catalogue.\nfunction defineLazyGlobal<T>(target: Record<string, unknown>, key: string, tagName: T, create: (tagName: T) => unknown) {\n  Object.defineProperty(target, key, {\n    configurable: true,\n    enumerable: true,\n    get(): unknown {\n      const value = create(tagName);\n      Object.defineProperty(target, key, { value, configurable: true, enumerable: true, writable: true });\n      return value;\n    },\n    // A plain accessor-only property would throw on direct assignment\n    // (`globalThis.div = ...`), unlike the eager `target[tagName] = builder`\n    // it replaces. Route writes through the same \"become a normal data\n    // property\" path so overwriting behaves exactly as before.\n    set(value: unknown) {\n      Object.defineProperty(target, key, { value, configurable: true, enumerable: true, writable: true });\n    },\n  });\n}\n\nfunction registerHtmlTag(target: Record<string, unknown>, tagName: ElementTagName) {\n  // Don't overwrite non-function properties (safety check)\n  if (tagName in target && typeof target[tagName] !== 'function') {\n    return;\n  }\n  defineLazyGlobal(target, tagName, tagName, createHtmlTagBuilder);\n  // `var` is a reserved word, so the declared global is `var_` — register it\n  // under that name too (the bare `var` key stays for globalThis[\"var\"] access).\n  if (tagName === \"var\") {\n    defineLazyGlobal(target, \"var_\", tagName, createHtmlTagBuilder);\n  }\n}\n\nfunction registerSvgTag(target: Record<string, unknown>, tagName: keyof SVGElementTagNameMap) {\n  // All SVG tags use camelCase Svg suffix: aSvg, rectSvg, pathSvg, etc.\n  const exportName = `${tagName}Svg`;\n\n  if (!(exportName in target)) {\n    defineLazyGlobal(target, exportName, tagName, createSvgTagBuilder);\n  }\n}\n\nexport function registerGlobalTagBuilders(target: Record<string, unknown> = globalThis) {\n  const marker = \"__nuclo_tags_registered\";\n  if ((target as Record<string, boolean>)[marker]) return;\n\n  // Register SVG tags with Svg suffix\n  for (let i = 0; i < SVG_TAGS.length; i++) {\n    registerSvgTag(target, SVG_TAGS[i]);\n  }\n\n  // Register HTML tags\n  for (let i = 0; i < HTML_TAGS.length; i++) {\n    registerHtmlTag(target, HTML_TAGS[i]);\n  }\n\n  (target as Record<string, boolean>)[marker] = true;\n}\n","import { registerGlobalTagBuilders } from \"./element/tags\";\nimport { list } from \"./list\";\nimport { update } from \"./update/update\";\nimport { when } from \"./when\";\nimport { region, into } from \"./region\";\nimport { on } from \"./element/events\";\nimport { render, hydrate, forceUpdate } from \"./render\";\nimport { scope } from \"./update/scope\";\nimport { createCss, css, cx, variants, keyframes, globalStyle } from \"./style\";\n\n/**\n * Initializes the nuclo runtime by exposing tag builders and utilities.\n */\n\nexport function initializeRuntime() {\n  registerGlobalTagBuilders();\n\n  const registry = globalThis as Record<string, unknown>;\n  registry.list = list;\n  registry.update = update;\n  registry.when = when;\n  registry.region = region;\n  registry.into = into;\n  registry.on = on;\n  registry.scope = scope;\n  registry.render = render;\n  registry.hydrate = hydrate;\n  registry.forceUpdate = forceUpdate;\n\n  // Styling — a themeless default instance plus the factory for themed ones.\n  // None of these names collide with window/globalThis properties.\n  registry.createCss = createCss;\n  registry.css = css;\n  registry.cx = cx;\n  registry.variants = variants;\n  registry.keyframes = keyframes;\n  registry.globalStyle = globalStyle;\n}\n\ninitializeRuntime();\n"],"mappings":"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"}