const SigPro = (() => { const doc = typeof document !== "undefined" ? document : null; const isFunc = (f) => typeof f === "function"; const isArr = Array.isArray; let activeEffect = null, currentOwner = null; const queue = new Set(); const tick = () => { const runs = [...queue]; queue.clear(); runs.forEach(fn => fn()); if (queue.size) tick(); }; const onUnmount = (fn) => currentOwner?._cleanups.add(fn); const cleanupNode = (node) => { if (node._cleanups) { node._cleanups.forEach(f => f()); node._cleanups.clear(); } node.childNodes?.forEach(cleanupNode); }; const effect = (fn) => { const runner = () => { stop(); const prevEff = activeEffect, prevOwn = currentOwner; activeEffect = runner; currentOwner = runner; try { runner._cb = fn(); } finally { activeEffect = prevEff; currentOwner = prevOwn; } }; const stop = () => { runner._deps?.forEach(subs => subs.delete(runner)); runner._deps?.clear(); if (isFunc(runner._cb)) runner._cb(); runner._cleanups?.forEach(f => f()); runner._cleanups?.clear(); }; Object.assign(runner, { _deps: new Set(), _cleanups: new Set(), stop }); if (currentOwner) onUnmount(stop); runner(); return stop; }; const signal = (val) => { const subs = new Set(); return (...args) => { if (args.length) { const next = isFunc(args[0]) ? args[0](val) : args[0]; if (!Object.is(val, next)) { val = next; subs.forEach(e => { queue.add(e); if (queue.size === 1) queueMicrotask(tick); }); } } else { if (activeEffect) { subs.add(activeEffect); activeEffect._deps.add(subs); } return val; } }; }; const computed = (fn) => { const s = signal(); effect(() => s(fn())); return () => s(); }; const h = (tag, props = {}, children = []) => { if (props instanceof Node || isArr(props) || typeof props !== 'object') { children = props; props = {}; } const isSVG = /^(svg|path|circle|rect|line|polyline|polygon|g|defs|text|tspan|use)$/.test(tag); const el = isSVG ? doc.createElementNS("http://www.w3.org/2000/svg", tag) : doc.createElement(tag); el._cleanups = new Set(); for (let [k, v] of Object.entries(props)) { if (k === "ref") { isFunc(v) ? v(el) : (v.current = el); continue; } if (k.startsWith("on")) { const ev = k.slice(2).toLowerCase(); el.addEventListener(ev, v); el._cleanups.add(() => el.removeEventListener(ev, v)); } else if (isFunc(v)) { el._cleanups.add(effect(() => { const val = v(), safe = (k === 'src' || k === 'href') && String(val).includes('javascript:') ? '#' : val; k === "class" ? (el.className = safe || "") : (safe == null || safe === false ? el.removeAttribute(k) : el.setAttribute(k, safe === true ? "" : safe)); })); if (/^(INPUT|TEXTAREA|SELECT)$/.test(el.tagName) && (k === "value" || k === "checked")) { el.addEventListener(k === "checked" ? "change" : "input", (e) => v(e.target[k === "checked" ? "checked" : "value"])); } } else el.setAttribute(k, v); } const ensureNode = (n) => n instanceof Node ? n : doc.createTextNode(String(n ?? "")); const append = (c) => { if (isArr(c)) return c.forEach(append); if (isFunc(c)) { const m = doc.createTextNode(""); el.appendChild(m); let curr = []; el._cleanups.add(effect(() => { const res = c(), next = (isArr(res) ? res : [res]).flat().map(ensureNode); curr.forEach(n => { cleanupNode(n); n.remove(); }); next.forEach(n => m.parentNode?.insertBefore(n, m)); curr = next; })); } else if (c !== null && c !== false) el.appendChild(ensureNode(c)); }; append(children); if (currentOwner) onUnmount(() => cleanupNode(el)); return el; }; const If = (cond, thenFn, elseFn = null) => { let last, cached; return () => { const v = !!(isFunc(cond) ? cond() : cond); if (v === last) return cached; last = v; const target = v ? thenFn : elseFn; return cached = isFunc(target) ? target() : target; }; }; const For = (list, keyFn, itemFn) => { let cache = new Map(); return () => { const items = (isFunc(list) ? list() : list) || []; const nextCache = new Map(); const nodes = items.map((item, i) => { const key = keyFn(item, i); const node = cache.get(key) || itemFn(item, i); nextCache.set(key, node); return node; }); for (const [k, n] of cache) if (!nextCache.has(k)) { cleanupNode(n); n.remove(); } cache = nextCache; return nodes; }; }; const mount = (comp, target) => { const t = typeof target === "string" ? doc.querySelector(target) : target; cleanupNode(t); const prev = currentOwner, _cleanups = new Set(); currentOwner = { _cleanups }; const node = h(comp); currentOwner = prev; node._cleanups = new Set([...(node._cleanups || []), ..._cleanups]); t.replaceChildren(node); return () => cleanupNode(node); }; return { signal, computed, effect, h, If, For, mount, onUnmount }; })();