PageSourceSearch

https://voltx-demo.pages.dev/assets/index-CHctqO4e.js

js voltx-demo.pages.dev collected 2026-10-03 06:03:46 UTC 150,557 bytes, 4,422 lines download raw bytes

1(function polyfill() {
2	const relList = document.createElement("link").relList;
3	if (relList && relList.supports && relList.supports("modulepreload")) return;
4	for (const link of document.querySelectorAll("link[rel=\"modulepreload\"]")) processPreload(link);
5	new MutationObserver((mutations) => {
6		for (const mutation of mutations) {
7			if (mutation.type !== "childList") continue;
8			for (const node of mutation.addedNodes) if (node.tagName === "LINK" && node.rel === "modulepreload") processPreload(node);
9		}
10	}).observe(document, {
11		childList: true,
12		subtree: true
13	});
14	function getFetchOpts(link) {
15		const fetchOpts = {};
16		if (link.integrity) fetchOpts.integrity = link.integrity;
17		if (link.referrerPolicy) fetchOpts.referrerPolicy = link.referrerPolicy;
18		if (link.crossOrigin === "use-credentials") fetchOpts.credentials = "include";
19		else if (link.crossOrigin === "anonymous") fetchOpts.credentials = "omit";
20		else fetchOpts.credentials = "same-origin";
21		return fetchOpts;
22	}
23	function processPreload(link) {
24		if (link.ep) return;
25		link.ep = true;
26		const fetchOpts = getFetchOpts(link);
27		fetch(link.href, fetchOpts);
28	}
29})();
30function kebabToCamel(str) {
31	return str.replaceAll(/-([a-z])/g, (_, letter) => letter.toUpperCase());
32}
33function isNil(value) {
34	return value === null || value === void 0;
35}
36function isSignal(value) {
37	return typeof value === "object" && value !== null && "get" in value && "subscribe" in value && typeof value.get === "function" && typeof value.subscribe === "function";
38}
39function findScopedSignal(scope, path) {
40	const trimmed = path.trim();
41	if (!trimmed) return;
42	const parts = trimmed.split(".");
43	let current = scope;
44	for (const part of parts) {
45		if (isNil(current) || typeof current !== "object") return;
46		const record = current;
47		if (Object.hasOwn(record, part)) {
48			current = record[part];
49			continue;
50		}
51		const camelCandidate = kebabToCamel(part);
52		if (Object.hasOwn(record, camelCandidate)) {
53			current = record[camelCandidate];
54			continue;
55		}
56		const lowerPart = part.toLowerCase();
57		const matchedKey = Object.keys(record).find((key) => key.toLowerCase() === lowerPart);
58		if (!matchedKey) return;
59		current = record[matchedKey];
60	}
61	if (isSignal(current)) return current;
62}
63function getComputedAttributes(el$1) {
64	const computed$1 = /* @__PURE__ */ new Map();
65	for (const attr of el$1.attributes) if (attr.name.startsWith("data-volt-computed:")) {
66		const name = attr.name.slice(19);
67		const camelName = kebabToCamel(name);
68		computed$1.set(camelName, attr.value);
69	}
70	return computed$1;
71}
72function sleep(ms) {
73	return new Promise((resolve) => setTimeout(resolve, ms));
74}
75function extractDeps(expr, scope) {
76	const deps = [];
77	const seen = /* @__PURE__ */ new Set();
78	const storeCalls = expr.matchAll(/\$store\.(get|set|has)\s*\(\s*['"]([^'"]+)['"]\s*(?:,|\))/g);
79	for (const match of storeCalls) {
80		const key = match[2];
81		const storeKey = `$store.${key}`;
82		if (seen.has(storeKey)) continue;
83		seen.add(storeKey);
84		const store$1 = scope.$store;
85		if (store$1 && typeof store$1 === "object" && "_signals" in store$1) {
86			const signal$1 = store$1._signals.get(key);
87			if (signal$1 && !deps.includes(signal$1)) deps.push(signal$1);
88		}
89	}
90	const matches = expr.matchAll(/\b([a-zA-Z_$][\w$]*(?:\.[a-zA-Z_$][\w$]*)*)\b/g);
91	for (const match of matches) {
92		const path = match[1];
93		if ([
94			"true",
95			"false",
96			"null",
97			"undefined"
98		].includes(path)) continue;
99		if (seen.has(path)) continue;
100		seen.add(path);
101		const signal$1 = findScopedSignal(scope, path);
102		if (signal$1) {
103			deps.push(signal$1);
104			continue;
105		}
106		const topLevel = path.split(".")[0];
107		const value = scope[topLevel];
108		if (isSignal(value) && !deps.includes(value)) deps.push(value);
109	}
110	return deps;
111}
112function updateAndRegister(ctx, update, expr) {
113	update();
114	const deps = extractDeps(expr, ctx.scope);
115	for (const dep of deps) {
116		const unsubscribe = dep.subscribe(update);
117		ctx.cleanups.push(unsubscribe);
118	}
119}
120var transitionRegistry = /* @__PURE__ */ new Map();
121var builtinPresets = {
122	fade: {
123		enter: {
124			from: { opacity: 0 },
125			to: { opacity: 1 },
126			duration: 300,
127			easing: "ease"
128		},
129		leave: {
130			from: { opacity: 1 },
131			to: { opacity: 0 },
132			duration: 300,
133			easing: "ease"
134		}
135	},
136	"slide-up": {
137		enter: {
138			from: {
139				opacity: 0,
140				transform: "translateY(20px)"
141			},
142			to: {
143				opacity: 1,
144				transform: "translateY(0)"
145			},
146			duration: 300,
147			easing: "ease-out"
148		},
149		leave: {
150			from: {
151				opacity: 1,
152				transform: "translateY(0)"
153			},
154			to: {
155				opacity: 0,
156				transform: "translateY(-20px)"
157			},
158			duration: 300,
159			easing: "ease-in"
160		}
161	},
162	"slide-down": {
163		enter: {
164			from: {
165				opacity: 0,
166				transform: "translateY(-20px)"
167			},
168			to: {
169				opacity: 1,
170				transform: "translateY(0)"
171			},
172			duration: 300,
173			easing: "ease-out"
174		},
175		leave: {
176			from: {
177				opacity: 1,
178				transform: "translateY(0)"
179			},
180			to: {
181				opacity: 0,
182				transform: "translateY(20px)"
183			},
184			duration: 300,
185			easing: "ease-in"
186		}
187	},
188	"slide-left": {
189		enter: {
190			from: {
191				opacity: 0,
192				transform: "translateX(20px)"
193			},
194			to: {
195				opacity: 1,
196				transform: "translateX(0)"
197			},
198			duration: 300,
199			easing: "ease-out"
200		},
201		leave: {
202			from: {
203				opacity: 1,
204				transform: "translateX(0)"
205			},
206			to: {
207				opacity: 0,
208				transform: "translateX(-20px)"
209			},
210			duration: 300,
211			easing: "ease-in"
212		}
213	},
214	"slide-right": {
215		enter: {
216			from: {
217				opacity: 0,
218				transform: "translateX(-20px)"
219			},
220			to: {
221				opacity: 1,
222				transform: "translateX(0)"
223			},
224			duration: 300,
225			easing: "ease-out"
226		},
227		leave: {
228			from: {
229				opacity: 1,
230				transform: "translateX(0)"
231			},
232			to: {
233				opacity: 0,
234				transform: "translateX(20px)"
235			},
236			duration: 300,
237			easing: "ease-in"
238		}
239	},
240	scale: {
241		enter: {
242			from: {
243				opacity: 0,
244				transform: "scale(0.95)"
245			},
246			to: {
247				opacity: 1,
248				transform: "scale(1)"
249			},
250			duration: 300,
251			easing: "ease-out"
252		},
253		leave: {
254			from: {
255				opacity: 1,
256				transform: "scale(1)"
257			},
258			to: {
259				opacity: 0,
260				transform: "scale(0.95)"
261			},
262			duration: 300,
263			easing: "ease-in"
264		}
265	},
266	blur: {
267		enter: {
268			from: {
269				opacity: 0,
270				filter: "blur(10px)"
271			},
272			to: {
273				opacity: 1,
274				filter: "blur(0)"
275			},
276			duration: 300,
277			easing: "ease"
278		},
279		leave: {
280			from: {
281				opacity: 1,
282				filter: "blur(0)"
283			},
284			to: {
285				opacity: 0,
286				filter: "blur(10px)"
287			},
288			duration: 300,
289			easing: "ease"
290		}
291	}
292};
293function initBuiltinPresets() {
294	for (const [name, preset] of Object.entries(builtinPresets)) transitionRegistry.set(name, preset);
295}
296initBuiltinPresets();
297function getTransition(name) {
298	return transitionRegistry.get(name);
299}
300function parseTransitionValue(value) {
301	const parts = value.split(".");
302	const presetName = parts[0]?.trim();
303	if (!presetName) return;
304	const preset = getTransition(presetName);
305	if (!preset) {
306		console.error(`[Volt] Unknown transition preset: "${presetName}"`);
307		return;
308	}
309	const result = { preset };
310	if (parts.length > 1) {
311		const duration = Number.parseInt(parts[1], 10);
312		if (!Number.isNaN(duration)) result.duration = duration;
313	}
314	if (parts.length > 2) {
315		const delay = Number.parseInt(parts[2], 10);
316		if (!Number.isNaN(delay)) result.delay = delay;
317	}
318	return result;
319}
320const easings = {
321	linear: "linear",
322	ease: "ease",
323	"ease-in": "ease-in",
324	"ease-out": "ease-out",
325	"ease-in-out": "ease-in-out",
326	"ease-in-sine": "cubic-bezier(0.12, 0, 0.39, 0)",
327	"ease-out-sine": "cubic-bezier(0.61, 1, 0.88, 1)",
328	"ease-in-out-sine": "cubic-bezier(0.37, 0, 0.63, 1)",
329	"ease-in-quad": "cubic-bezier(0.11, 0, 0.5, 0)",
330	"ease-out-quad": "cubic-bezier(0.5, 1, 0.89, 1)",
331	"ease-in-out-quad": "cubic-bezier(0.45, 0, 0.55, 1)",
332	"ease-in-cubic": "cubic-bezier(0.32, 0, 0.67, 0)",
333	"ease-out-cubic": "cubic-bezier(0.33, 1, 0.68, 1)",
334	"ease-in-out-cubic": "cubic-bezier(0.65, 0, 0.35, 1)",
335	"ease-in-quart": "cubic-bezier(0.5, 0, 0.75, 0)",
336	"ease-out-quart": "cubic-bezier(0.25, 1, 0.5, 1)",
337	"ease-in-out-quart": "cubic-bezier(0.76, 0, 0.24, 1)",
338	"ease-in-quint": "cubic-bezier(0.64, 0, 0.78, 0)",
339	"ease-out-quint": "cubic-bezier(0.22, 1, 0.36, 1)",
340	"ease-in-out-quint": "cubic-bezier(0.83, 0, 0.17, 1)",
341	"ease-in-expo": "cubic-bezier(0.7, 0, 0.84, 0)",
342	"ease-out-expo": "cubic-bezier(0.16, 1, 0.3, 1)",
343	"ease-in-out-expo": "cubic-bezier(0.87, 0, 0.13, 1)",
344	"ease-in-circ": "cubic-bezier(0.55, 0, 1, 0.45)",
345	"ease-out-circ": "cubic-bezier(0, 0.55, 0.45, 1)",
346	"ease-in-out-circ": "cubic-bezier(0.85, 0, 0.15, 1)",
347	"ease-in-back": "cubic-bezier(0.36, 0, 0.66, -0.56)",
348	"ease-out-back": "cubic-bezier(0.34, 1.56, 0.64, 1)",
349	"ease-in-out-back": "cubic-bezier(0.68, -0.6, 0.32, 1.6)"
350};
351function getEasing(name) {
352	return easings[name] ?? name;
353}
354function prefersReducedMotion() {
355	if (globalThis.window === void 0 || !globalThis.matchMedia) return false;
356	return globalThis.matchMedia("(prefers-reduced-motion: reduce)").matches;
357}
358function applyOverrides(phase, duration, delay) {
359	return {
360		...phase,
361		...duration !== void 0 && { duration },
362		...delay !== void 0 && { delay }
363	};
364}
365function supportsViewTransitions() {
366	return typeof document !== "undefined" && "startViewTransition" in document;
367}
368async function startViewTransition(cb, opts = {}) {
369	const { respectReducedMotion = true, forceFallback = false } = opts;
370	if (respectReducedMotion && prefersReducedMotion()) {
371		await cb();
372		return;
373	}
374	if (!forceFallback && supportsViewTransitions()) {
375		const namedElements = applyViewTransitionNames(opts.name, opts.elements);
376		try {
377			await document.startViewTransition(cb).finished;
378		} finally {
379			removeViewTransitionNames(namedElements);
380		}
381	} else await cb();
382}
383function applyViewTransitionNames(baseName, elements) {
384	const originalNames = /* @__PURE__ */ new Map();
385	if (!baseName || !elements || elements.length === 0) return originalNames;
386	for (const [index, element] of elements.entries()) {
387		const originalValue = element.style.viewTransitionName;
388		originalNames.set(element, originalValue);
389		const transitionName = elements.length === 1 ? baseName : `${baseName}-${index}`;
390		element.style.viewTransitionName = transitionName;
391	}
392	return originalNames;
393}
394function removeViewTransitionNames(namedElements) {
395	for (const [element, originalValue] of namedElements) if (originalValue) element.style.viewTransitionName = originalValue;
396	else element.style.viewTransitionName = "";
397}
398function withViewTransition(cb, respectReducedMotion = true) {
399	if (respectReducedMotion && prefersReducedMotion()) {
400		cb();
401		return;
402	}
403	if (supportsViewTransitions()) document.startViewTransition(cb);
404	else cb();
405}
406function applyStyles(element, styles) {
407	for (const [property, value] of Object.entries(styles)) {
408		const cssProperty = property.replaceAll(/[A-Z]/g, (m) => `-${m.toLowerCase()}`);
409		element.style.setProperty(cssProperty, String(value));
410	}
411}
412function applyClasses(el$1, classes) {
413	for (const cls of classes) el$1.classList.add(cls);
414}
415function rmClasses(el$1, classes) {
416	for (const cls of classes) el$1.classList.remove(cls);
417}
418async function execEnter(element, phase, useViewTransitions) {
419	const duration = phase.duration ?? 300;
420	const delay = phase.delay ?? 0;
421	const easing = getEasing(phase.easing ?? "ease");
422	if (prefersReducedMotion()) {
423		if (phase.to) applyStyles(element, phase.to);
424		if (phase.classes) applyClasses(element, phase.classes);
425		return;
426	}
427	if (phase.from) applyStyles(element, phase.from);
428	if (phase.classes) applyClasses(element, phase.classes);
429	element.offsetHeight;
430	element.style.transition = `all ${duration}ms ${easing} ${delay}ms`;
431	if (delay > 0) await sleep(delay);
432	const transitionPromise = new Promise((resolve) => {
433		const handleTransitionEnd = (event) => {
434			if (event.target === element) {
435				element.removeEventListener("transitionend", handleTransitionEnd);
436				resolve();
437			}
438		};
439		element.addEventListener("transitionend", handleTransitionEnd);
440		setTimeout(() => {
441			element.removeEventListener("transitionend", handleTransitionEnd);
442			resolve();
443		}, duration + delay + 50);
444	});
445	if (useViewTransitions) withViewTransition(() => {
446		if (phase.to) applyStyles(element, phase.to);
447	}, false);
448	else if (phase.to) applyStyles(element, phase.to);
449	await transitionPromise;
450	element.style.transition = "";
451	if (phase.classes) rmClasses(element, phase.classes);
452}
453async function execLeave(element, phase, useViewTransitions) {
454	const duration = phase.duration ?? 300;
455	const delay = phase.delay ?? 0;
456	const easing = getEasing(phase.easing ?? "ease");
457	if (prefersReducedMotion()) {
458		if (phase.to) applyStyles(element, phase.to);
459		if (phase.classes) applyClasses(element, phase.classes);
460		return;
461	}
462	if (phase.from) applyStyles(element, phase.from);
463	if (phase.classes) applyClasses(element, phase.classes);
464	element.offsetHeight;
465	element.style.transition = `all ${duration}ms ${easing} ${delay}ms`;
466	if (delay > 0) await sleep(delay);
467	const transitionPromise = new Promise((resolve) => {
468		const handleTransitionEnd = (event) => {
469			if (event.target === element) {
470				element.removeEventListener("transitionend", handleTransitionEnd);
471				resolve();
472			}
473		};
474		element.addEventListener("transitionend", handleTransitionEnd);
475		setTimeout(() => {
476			element.removeEventListener("transitionend", handleTransitionEnd);
477			resolve();
478		}, duration + delay + 50);
479	});
480	if (useViewTransitions) withViewTransition(() => {
481		if (phase.to) applyStyles(element, phase.to);
482	}, false);
483	else if (phase.to) applyStyles(element, phase.to);
484	await transitionPromise;
485	element.style.transition = "";
486	if (phase.classes) rmClasses(element, phase.classes);
487}
488function parseSurgeValue(value) {
489	const parts = value.split(":");
490	if (parts.length === 2) {
491		const [signalPath, presetValue] = parts;
492		const parsed$1 = parseTransitionValue(presetValue.trim());
493		if (!parsed$1) return;
494		return {
495			enterPreset: parsed$1.preset.enter,
496			leavePreset: parsed$1.preset.leave,
497			signalPath: signalPath.trim(),
498			useViewTransitions: true
499		};
500	}
501	const parsed = parseTransitionValue(value.trim());
502	if (!parsed) return;
503	return {
504		enterPreset: parsed.preset.enter,
505		leavePreset: parsed.preset.leave,
506		useViewTransitions: true
507	};
508}
509function ensureInlineSurgeState(element) {
510	if (!element._vxSurgeConf) {
511		const attr = element.dataset.voltSurge;
512		if (attr) {
513			const parsed = parseSurgeValue(attr);
514			if (parsed) element._vxSurgeConf = parsed;
515		}
516	}
517	if (!element._vxSurgeEnter) {
518		const enterAttr = element.dataset["voltSurge:enter"];
519		if (enterAttr) {
520			const enterPhase = parsePhaseValue(enterAttr, "enter");
521			if (enterPhase) element._vxSurgeEnter = enterPhase;
522		}
523	}
524	if (!element._vxSurgeLeave) {
525		const leaveAttr = element.dataset["voltSurge:leave"];
526		if (leaveAttr) {
527			const leavePhase = parsePhaseValue(leaveAttr, "leave");
528			if (leavePhase) element._vxSurgeLeave = leavePhase;
529		}
530	}
531}
532function parsePhaseValue(value, phase) {
533	const parsed = parseTransitionValue(value.trim());
534	if (!parsed) return;
535	const presetPhase = phase === "enter" ? parsed.preset.enter : parsed.preset.leave;
536	return applyOverrides(presetPhase, parsed.duration, parsed.delay);
537}
538function surgePlugin(ctx, value) {
539	const el$1 = ctx.element;
540	if (value.includes(":")) {
541		const [phase, presetValue] = value.split(":", 2);
542		if (phase === "enter") {
543			const enterPhase = parsePhaseValue(presetValue, "enter");
544			if (!enterPhase) {
545				console.error(`[Volt] Invalid surge enter value: "${value}"`);
546				return;
547			}
548			el$1._vxSurgeEnter = enterPhase;
549			return;
550		}
551		if (phase === "leave") {
552			const leavePhase = parsePhaseValue(presetValue, "leave");
553			if (!leavePhase) {
554				console.error(`[Volt] Invalid surge leave value: "${value}"`);
555				return;
556			}
557			el$1._vxSurgeLeave = leavePhase;
558			return;
559		}
560	}
561	const config = parseSurgeValue(value);
562	if (!config) {
563		console.error(`[Volt] Invalid surge value: "${value}"`);
564		return;
565	}
566	if (!config.signalPath) {
567		el$1._vxSurgeConf = config;
568		return;
569	}
570	const signal$1 = ctx.findSignal(config.signalPath);
571	if (!signal$1) {
572		console.error(`[Volt] Signal "${config.signalPath}" not found for surge binding`);
573		return;
574	}
575	let isVisible = Boolean(signal$1.get());
576	let isTransitioning = false;
577	if (!isVisible) el$1.style.display = "none";
578	const handleTransition = async (shouldShow) => {
579		if (isTransitioning || shouldShow === isVisible) return;
580		isTransitioning = true;
581		if (shouldShow && config.enterPreset) {
582			el$1.style.display = "";
583			await execEnter(el$1, config.enterPreset, config.useViewTransitions);
584			isVisible = true;
585		} else if (!shouldShow && config.leavePreset) {
586			await execLeave(el$1, config.leavePreset, config.useViewTransitions);
587			el$1.style.display = "none";
588			isVisible = false;
589		}
590		isTransitioning = false;
591	};
592	const unsubscribe = signal$1.subscribe((value$1) => {
593		handleTransition(Boolean(value$1));
594	});
595	ctx.addCleanup(unsubscribe);
596}
597async function executeSurgeEnter(element) {
598	const surgeEl = element;
599	ensureInlineSurgeState(surgeEl);
600	const config = surgeEl._vxSurgeConf;
601	const enterPhase = surgeEl._vxSurgeEnter ?? config?.enterPreset;
602	if (!enterPhase) return;
603	const useViewTransitions = config?.useViewTransitions ?? true;
604	await execEnter(element, enterPhase, useViewTransitions);
605}
606async function executeSurgeLeave(element) {
607	const surgeEl = element;
608	ensureInlineSurgeState(surgeEl);
609	const config = surgeEl._vxSurgeConf;
610	const leavePhase = surgeEl._vxSurgeLeave ?? config?.leavePreset;
611	if (!leavePhase) return;
612	const useViewTransitions = config?.useViewTransitions ?? true;
613	await execLeave(element, leavePhase, useViewTransitions);
614}
615function hasSurge(element) {
616	const surgeEl = element;
617	ensureInlineSurgeState(surgeEl);
618	return Boolean(surgeEl._vxSurgeConf || surgeEl._vxSurgeEnter || surgeEl._vxSurgeLeave);
619}
620const BOOLEAN_ATTRS = [
621	"disabled",
622	"checked",
623	"selected",
624	"readonly",
625	"required",
626	"multiple",
627	"autofocus",
628	"autoplay",
629	"controls",
630	"loop",
631	"muted"
632];
633const DANGEROUS_PROPERTIES = [
634	"__proto__",
635	"prototype",
636	"constructor"
637];
638const DANGEROUS_GLOBALS = [
639	"window",
640	"self",
641	"global",
642	"globalThis",
643	"process",
644	"require",
645	"import",
646	"module",
647	"exports"
648];
649const SAFE_GLOBALS = [
650	"Array",
651	"Object",
652	"String",
653	"Number",
654	"Boolean",
655	"Date",
656	"Math",
657	"JSON",
658	"RegExp",
659	"Map",
660	"Set",
661	"Promise"
662];
663function walkDOM(root) {
664	const elements = [];
665	function walk(element) {
666		if (hasVoltAttr(element)) {
667			elements.push(element);
668			if (Object.hasOwn(element.dataset, "voltFor") || Object.hasOwn(element.dataset, "voltIf")) return;
669		}
670		for (const child of element.children) walk(child);
671	}
672	walk(root);
673	return elements;
674}
675function hasVoltAttr(el$1) {
676	return [...el$1.attributes].some((attribute) => attribute.name.startsWith("data-volt-"));
677}
678function getVoltAttrs(el$1) {
679	const attrs = /* @__PURE__ */ new Map();
680	for (const attr of el$1.attributes) if (attr.name.startsWith("data-volt-")) {
681		const name = attr.name.slice(10);
682		if (name === "state" || name.startsWith("computed:")) continue;
683		attrs.set(name, attr.value);
684	}
685	return attrs;
686}
687function setText(el$1, value) {
688	el$1.textContent = String(value ?? "");
689}
690function setHTML(el$1, value) {
691	el$1.innerHTML = value;
692}
693function toggleClass(el$1, cls, add) {
694	el$1.classList.toggle(cls, add);
695}
696function isWrappedSignal(value) {
697	return value !== null && typeof value === "object" && typeof value.get === "function" && typeof value.subscribe === "function";
698}
699function unwrapIfSignal(value) {
700	if (isWrappedSignal(value)) return value.get();
701	return value;
702}
703function parseClassBinding(value) {
704	const classes = /* @__PURE__ */ new Map();
705	switch (typeof value) {
706		case "string":
707			for (const cls of value.split(/\s+/).filter(Boolean)) classes.set(cls, true);
708			break;
709		case "object":
710			if (value !== null) for (const [key, value_] of Object.entries(value)) {
711				const unwrapped = unwrapIfSignal(value_);
712				classes.set(key, Boolean(unwrapped));
713			}
714			break;
715		case "boolean":
716		case "number":
717			classes.set(String(value), true);
718			break;
719	}
720	return classes;
721}
722var VoltError = class VoltError extends Error {
723	source;
724	level;
725	element;
726	directive;
727	expression;
728	cause;
729	timestamp;
730	context;
731	_stopped = false;
732	constructor(cause, context) {
733		const message = VoltError.buildMessage(cause, context);
734		super(message);
735		this.name = "VoltError";
736		this.cause = cause;
737		this.source = context.source;
738		this.level = context.level ?? "error";
739		this.element = context.element;
740		this.directive = context.directive;
741		this.expression = context.expression;
742		this.context = context;
743		this.timestamp = Date.now();
744		if (Error.captureStackTrace) Error.captureStackTrace(this, this.constructor);
745	}
746	stopPropagation() {
747		this._stopped = true;
748	}
749	get stopped() {
750		return this._stopped;
751	}
752	static buildMessage(cause, context) {
753		const parts = [];
754		const level = context.level ?? "error";
755		parts.push(`[${level.toUpperCase()}] [${context.source}
755] ${cause.message}`);
756		if (context.directive) parts.push(`Directive: ${context.directive}`);
757		if (context.expression) {
758			const truncated = context.expression.length > 100 ? `${context.expression.slice(0, 100)}...` : context.expression;
759			parts.push(`Expression: ${truncated}`);
760		}
761		if (context.pluginName) parts.push(`Plugin: ${context.pluginName}`);
762		if (context.httpMethod && context.httpUrl) {
763			parts.push(`HTTP: ${context.httpMethod} ${context.httpUrl}`);
764			if (context.httpStatus) parts.push(`Status: ${context.httpStatus}`);
765		}
766		if (context.hookName) parts.push(`Hook: ${context.hookName}`);
767		if (context.element) {
768			const tag = context.element.tagName.toLowerCase();
769			const id = context.element.id ? `#${context.element.id}` : "";
770			const cls = context.element.className ? `.${context.element.className.split(" ").join(".")}` : "";
771			parts.push(`Element: <${tag}${id}${cls}>`);
772		}
773		return parts.join(" | ");
774	}
775	toJSON() {
776		return {
777			name: this.name,
778			message: this.message,
779			source: this.source,
780			level: this.level,
781			directive: this.directive,
782			expression: this.expression,
783			timestamp: this.timestamp,
784			context: this.context,
785			cause: {
786				name: this.cause.name,
787				message: this.cause.message,
788				stack: this.cause.stack
789			},
790			stack: this.stack
791		};
792	}
793};
794var EvaluatorError = class extends VoltError {
795	constructor(cause, context) {
796		super(cause, {
797			...context,
798			source: "evaluator"
799		});
800		this.name = "EvaluatorError";
801	}
802};
803var BindingError = class extends VoltError {
804	constructor(cause, context) {
805		super(cause, {
806			...context,
807			source: "binding"
808		});
809		this.name = "BindingError";
810	}
811};
812var EffectError = class extends VoltError {
813	constructor(cause, context) {
814		super(cause, {
815			...context,
816			source: "effect"
817		});
818		this.name = "EffectError";
819	}
820};
821var HttpError = class extends VoltError {
822	constructor(cause, context) {
823		super(cause, {
824			...context,
825			source: "http"
826		});
827		this.name = "HttpError";
828	}
829};
830var PluginError = class extends VoltError {
831	constructor(cause, context) {
832		super(cause, {
833			...context,
834			source: "plugin"
835		});
836		this.name = "PluginError";
837	}
838};
839var LifecycleError = class extends VoltError {
840	constructor(cause, context) {
841		super(cause, {
842			...context,
843			source: "lifecycle"
844		});
845		this.name = "LifecycleError";
846	}
847};
848var ChargeError = class extends VoltError {
849	constructor(cause, context) {
850		super(cause, {
851			...context,
852			source: "charge"
853		});
854		this.name = "ChargeError";
855	}
856};
857var UserError = class extends VoltError {
858	constructor(cause, context) {
859		super(cause, {
860			...context,
861			source: "user"
862		});
863		this.name = "UserError";
864	}
865};
866var errorHandlers = [];
867function report(error, context) {
868	const errorObj = error instanceof Error ? error : new Error(String(error));
869	const voltError = createErrorBySource(errorObj, context);
870	if (errorHandlers.length === 0) {
871		const logFn = voltError.level === "warn" ? console.warn : console.error;
872		logFn(voltError.message);
873		logFn("Caused by:", voltError.cause);
874		if (voltError.element) logFn("Element:", voltError.element);
875		if (voltError.level === "fatal") throw voltError;
876		return;
877	}
878	for (const handler of errorHandlers) try {
879		handler(voltError);
880		if (voltError.stopped) break;
881	} catch (handlerError) {
882		console.error("Error in error handler:", handlerError);
883	}
884	if (voltError.level === "fatal") throw voltError;
885}
886function createErrorBySource(cause, context) {
887	switch (context.source) {
888		case "evaluator": return new EvaluatorError(cause, context);
889		case "binding": return new BindingError(cause, context);
890		case "effect": return new EffectError(cause, context);
891		case "http": return new HttpError(cause, context);
892		case "plugin": return new PluginError(cause, context);
893		case "lifecycle": return new LifecycleError(cause, context);
894		case "charge": return new ChargeError(cause, context);
895		case "user": return new UserError(cause, context);
896		default: return new VoltError(cause, context);
897	}
898}
899var EvaluationError = class extends Error {
900	expr;
901	cause;
902	constructor(expression, cause) {
903		const message = cause instanceof Error ? cause.message : String(cause);
904		super(`Error evaluating "${expression}": ${message}`);
905		this.name = "EvaluationError";
906		this.expr = expression;
907		this.cause = cause;
908	}
909};
910var dangerousProps = new Set(DANGEROUS_PROPERTIES);
911var dangerousGlobals = new Set(DANGEROUS_GLOBALS);
912var safeGlobals = new Set(SAFE_GLOBALS);
913var defaultWrapOptions = { unwrapSignals: false };
914var readWrapOptions = { unwrapSignals: true };
915function isDangerousProperty(key) {
916	if (typeof key !== "string" && typeof key !== "symbol") return false;
917	return dangerousProps.has(String(key));
918}
919function hasSetMethod(dep) {
920	return typeof dep === "object" && dep !== null && "set" in dep && typeof dep.set === "function";
921}
922function wrapSignal(signal$1, options$1) {
923	const hasSet = hasSetMethod(signal$1);
924	const wrapper = {
925		get: signal$1.get,
926		subscribe: signal$1.subscribe,
927		valueOf: () => signal$1.get(),
928		toString: () => String(signal$1.get()),
929		[Symbol.toPrimitive]: (_hint) => signal$1.get()
930	};
931	if (hasSet) wrapper.set = signal$1.set;
932	return new Proxy(wrapper, {
933		get(target, prop) {
934			if (isDangerousProperty(prop)) return;
935			if (prop === "get" || prop === "subscribe") return target[prop];
936			if (prop === "set" && hasSet) return target[prop];
937			if (prop === "valueOf" || prop === "toString" || prop === Symbol.toPrimitive) return target[prop];
938			if (prop === Symbol.iterator) {
939				const unwrapped$1 = signal$1.get();
940				if (unwrapped$1 && typeof unwrapped$1 === "object" && Symbol.iterator in unwrapped$1) return unwrapped$1[Symbol.iterator].bind(unwrapped$1);
941				return;
942			}
943			const unwrapped = signal$1.get();
944			if (unwrapped && (typeof unwrapped === "object" || typeof unwrapped === "function")) return wrapValue(unwrapped, options$1)[prop];
945			if (unwrapped !== null && unwrapped !== void 0) {
946				const boxed = new Object(unwrapped);
947				const value = Reflect.get(boxed, prop, boxed);
948				if (typeof value === "function") return value.bind(unwrapped);
949				return wrapValue(value, options$1);
950			}
951		},
952		has(_target, prop) {
953			if (isDangerousProperty(prop)) return false;
954			if (prop === "get" || prop === "subscribe") return true;
955			if (prop === "set" && hasSet) return true;
956			if (prop === Symbol.iterator) {
957				const unwrapped$1 = signal$1.get();
958				return unwrapped$1 !== null && unwrapped$1 !== void 0 && typeof unwrapped$1 === "object" && Symbol.iterator in unwrapped$1;
959			}
960			const unwrapped = signal$1.get();
961			if (unwrapped && (typeof unwrapped === "object" || typeof unwrapped === "function")) return prop in unwrapped;
962			if (unwrapped !== null && unwrapped !== void 0) {
963				const boxed = new Object(unwrapped);
964				return Reflect.has(boxed, prop);
965			}
966			return false;
967		}
968	});
969}
970function wrapValue(value, options$1 = defaultWrapOptions) {
971	if (value === null || value === void 0) return value;
972	if (isSignal(value)) {
973		if (options$1.unwrapSignals) return wrapValue(value.get(), options$1);
974		return wrapSignal(value, options$1);
975	}
976	if (typeof value !== "object" && typeof value !== "function") return value;
977	return new Proxy(value, {
978		get(target, prop) {
979			if (isDangerousProperty(prop)) return;
980			const result = target[prop];
981			if (typeof result === "function") return result.bind(target);
982			return wrapValue(result, options$1);
983		},
984		set(target, prop, newValue) {
985			if (isDangerousProperty(prop)) return true;
986			target[prop] = newValue;
987			return true;
988		},
989		has(target, prop) {
990			if (isDangerousProperty(prop)) return false;
991			return prop in target;
992		}
993	});
994}
995function createScopeProxy(scope, options$1 = defaultWrapOptions) {
996	const base = Object.create(null);
997	return new Proxy(base, {
998		get(_target, prop) {
999			const propStr = String(prop);
1000			if (dangerousGlobals.has(propStr)) return;
1001			if (isDangerousProperty(prop)) return;
1002			if (propStr in scope) {
1003				const value = scope[propStr];
1004				return wrapValue(value, options$1);
1005			}
1006			if (safeGlobals.has(propStr)) return wrapValue(globalThis[propStr], options$1);
1007		},
1008		set(_target, prop, value) {
1009			if (isDangerousProperty(prop)) return true;
1010			const propStr = String(prop);
1011			if (propStr in scope) {
1012				const existing = scope[propStr];
1013				if (isSignal(existing) && hasSetMethod(existing)) {
1014					existing.set(value);
1015					return true;
1016				}
1017			}
1018			scope[propStr] = value;
1019			return true;
1020		},
1021		has(_target, prop) {
1022			if (prop === "$unwrap") return false;
1023			return true;
1024		},
1025		ownKeys(_target) {
1026			return Object.keys(scope).filter((key) => !isDangerousProperty(key));
1027		},
1028		getOwnPropertyDescriptor(_target, prop) {
1029			if (isDangerousProperty(prop)) return;
1030			const propStr = String(prop);
1031			if (propStr in scope) return {
1032				configurable: true,
1033				enumerable: true,
1034				writable: true,
1035				value: scope[propStr]
1036			};
1037		}
1038	});
1039}
1040var exprCache = /* @__PURE__ */ new Map();
1041function isIdentifierStart(char) {
1042	if (char.length === 0) return false;
1043	const code$1 = char.charCodeAt(0);
1044	return code$1 >= 65 && code$1 <= 90 || code$1 >= 97 && code$1 <= 122 || char === "_" || char === "$";
1045}
1046function isIdentifierPart(char) {
1047	if (char.length === 0) return false;
1048	const code$1 = char.charCodeAt(0);
1049	return code$1 >= 65 && code$1 <= 90 || code$1 >= 97 && code$1 <= 122 || code$1 >= 48 && code$1 <= 57 || char === "_" || char === "$";
1050}
1051function isWhitespace(char) {
1052	return char === " " || char === "\n" || char === "\r" || char === "	";
1053}
1054function transformExpr(expr) {
1055	let result = "";
1056	let index = 0;
1057	while (index < expr.length) {
1058		const char = expr[index];
1059		if (char === "!") {
1060			if ((expr[index + 1] ?? "") === "=") {
1061				result += "!";
1062				index += 1;
1063				continue;
1064			}
1065			let cursor = index + 1;
1066			while (cursor < expr.length && isWhitespace(expr[cursor])) cursor += 1;
1067			const identStart = expr[cursor] ?? "";
1068			if (!isIdentifierStart(identStart)) {
1069				result += "!";
1070				index += 1;
1071				continue;
1072			}
1073			let end = cursor + 1;
1074			while (end < expr.length && isIdentifierPart(expr.charAt(end))) end += 1;
1075			while (end < expr.length && expr[end] === ".") {
1076				const afterDot = expr[end + 1] ?? "";
1077				if (!isIdentifierStart(afterDot)) break;
1078				end += 2;
1079				while (end < expr.length && isIdentifierPart(expr.charAt(end))) end += 1;
1080			}
1081			if ((expr[end] ?? "") === "(") {
1082				result += "!";
1083				index += 1;
1084				continue;
1085			}
1086			const identifier = expr.slice(cursor, end);
1087			result += "!$unwrap(" + identifier + ")";
1088			index = end;
1089			continue;
1090		}
1091		if (char === ":" && index > 0) {
1092			result += char;
1093			index += 1;
1094			while (index < expr.length && isWhitespace(expr[index])) {
1095				result += expr[index];
1096				index += 1;
1097			}
1098			if (index < expr.length && isIdentifierStart(expr[index])) {
1099				const identStart = index;
1100				let identEnd = identStart + 1;
1101				while (identEnd < expr.length && isIdentifierPart(expr[identEnd])) identEnd += 1;
1102				let lookahead = identEnd;
1103				while (lookahead < expr.length && isWhitespace(expr[lookahead])) lookahead += 1;
1104				const afterIdent = expr[lookahead] ?? "";
1105				if (afterIdent === "," || afterIdent === "}" || lookahead >= expr.length || afterIdent === ")") {
1106					const identifier = expr.slice(identStart, identEnd);
1107					result += "$unwrap(" + identifier + ")";
1108					index = identEnd;
1109					continue;
1110				}
1111			}
1112			continue;
1113		}
1114		result += char;
1115		index += 1;
1116	}
1117	return result;
1118}
1119function unwrapMaybeSignal(value) {
1120	if (isSignal(value)) return value.get();
1121	return value;
1122}
1123function compileExpr(expr, isStmt = false) {
1124	const cacheKey = `${isStmt ? "stmt" : "expr"}:${expr}`;
1125	let fn = exprCache.get(cacheKey);
1126	if (fn) return fn;
1127	try {
1128		const transformed = transformExpr(expr);
1129		if (isStmt) fn = new Function("$scope", "$unwrap", `with($scope){${transformed}}`);
1130		else fn = new Function("$scope", "$unwrap", `with($scope){return(${transformed})}`);
1131		exprCache.set(cacheKey, fn);
1132		return fn;
1133	} catch (error) {
1134		throw new EvaluationError(expr, error);
1135	}
1136}
1137function unwrapSignal(value) {
1138	if (isSignal(value)) return value.get();
1139	if (value && typeof value === "object" && typeof value.get === "function" && typeof value.subscribe === "function") return value.get();
1140	return value;
1141}
1142function evaluate(expr, scope, opts) {
1143	try {
1144		const fn = compileExpr(expr, false);
1145		const wrapOptions = opts?.unwrapSignals === false ? defaultWrapOptions : readWrapOptions;
1146		const proxiedScope = createScopeProxy(scope, wrapOptions);
1147		const result = fn(proxiedScope, unwrapMaybeSignal);
1148		return unwrapSignal(result);
1149	} catch (error) {
1150		if (error instanceof EvaluationError) throw error;
1151		if (error instanceof ReferenceError) return;
1152		throw new EvaluationError(expr, error);
1153	}
1154}
1155var lifecycleHooks = new Map([
1156	["beforeMount", /* @__PURE__ */ new Set()],
1157	["afterMount", /* @__PURE__ */ new Set()],
1158	["beforeUnmount", /* @__PURE__ */ new Set()],
1159	["afterUnmount", /* @__PURE__ */ new Set()]
1160]);
1161var elementLifecycleStates = /* @__PURE__ */ new WeakMap();
1162function execGlobalHooks(hookName, root, scope) {
1163	const hooks = lifecycleHooks.get(hookName);
1164	if (!hooks || hooks.size === 0) return;
1165	for (const callback of hooks) try {
1166		if (hookName === "beforeMount" || hookName === "afterMount") {
1167			if (scope !== void 0) callback(root, scope);
1168		} else callback(root);
1169	} catch (error) {
1170		report(error, {
1171			source: "lifecycle",
1172			element: root,
1173			hookName
1174		});
1175	}
1176}
1177function getElementLifecycleState(element) {
1178	let state = elementLifecycleStates.get(element);
1179	if (!state) {
1180		state = {
1181			isMounted: false,
1182			bindings: /* @__PURE__ */ new Set(),
1183			onMount: /* @__PURE__ */ new Set(),
1184			onUnmount: /* @__PURE__ */ new Set()
1185		};
1186		elementLifecycleStates.set(element, state);
1187	}
1188	return state;
1189}
1190function notifyElementMounted(el$1) {
1191	const state = getElementLifecycleState(el$1);
1192	if (state.isMounted) return;
1193	state.isMounted = true;
1194	for (const callback of state.onMount) try {
1195		callback();
1196	} catch (error) {
1197		report(error, {
1198			source: "lifecycle",
1199			element: el$1,
1200			hookName: "onMount"
1201		});
1202	}
1203}
1204function notifyElementUnmounted(el$1) {
1205	const state = getElementLifecycleState(el$1);
1206	if (!state.isMounted) return;
1207	state.isMounted = false;
1208	for (const callback of state.onUnmount) try {
1209		callback();
1210	} catch (error) {
1211		report(error, {
1212			source: "lifecycle",
1213			element: el$1,
1214			hookName: "onUnmount"
1215		});
1216	}
1217	elementLifecycleStates.delete(el$1);
1218}
1219function notifyBindingCreated(element, name) {
1220	getElementLifecycleState(element).bindings.add(name);
1221}
1222function parseModifiers(attrName) {
1223	const parts = attrName.split("-");
1224	if (parts.length === 1) return {
1225		baseName: attrName,
1226		modifiers: []
1227	};
1228	const baseName = parts[0];
1229	const modifiers = [];
1230	const KNOWN_MODIFIERS = new Set([
1231		"prevent",
1232		"stop",
1233		"self",
1234		"window",
1235		"document",
1236		"once",
1237		"debounce",
1238		"throttle",
1239		"passive",
1240		"number",
1241		"trim",
1242		"lazy",
1243		"replace",
1244		"prefetch",
1245		"notransition"
1246	]);
1247	let i = 1;
1248	while (i < parts.length) {
1249		const part = parts[i];
1250		const numMatch = /^([a-zA-Z]+)(\d+)$/.exec(part);
1251		if (numMatch && KNOWN_MODIFIERS.has(numMatch[1])) {
1252			modifiers.push({
1253				name: numMatch[1],
1254				value: Number(numMatch[2])
1255			});
1256			i++;
1257		} else if (KNOWN_MODIFIERS.has(part)) {
1258			if (i + 1 < parts.length) {
1259				const numValue = Number(parts[i + 1]);
1260				if (!Number.isNaN(numValue)) {
1261					modifiers.push({
1262						name: part,
1263						value: numValue
1264					});
1265					i += 2;
1266					continue;
1267				}
1268			}
1269			modifiers.push({ name: part });
1270			i++;
1271		} else break;
1272	}
1273	if (modifiers.length === 0) return {
1274		baseName: attrName,
1275		modifiers: []
1276	};
1277	return {
1278		baseName,
1279		modifiers
1280	};
1281}
1282function hasModifier(modifiers, name) {
1283	return modifiers.some((m) => m.name === name);
1284}
1285function getModifierValue(modifiers, name, defaultValue) {
1286	return modifiers.find((m) => m.name === name)?.value ?? defaultValue;
1287}
1288function debounce(fn, wait) {
1289	let timeoutId;
1290	const debounced = function(...args) {
1291		if (timeoutId !== void 0) clearTimeout(timeoutId);
1292		timeoutId = setTimeout(() => {
1293			timeoutId = void 0;
1294			fn.apply(this, args);
1295		}, wait);
1296	};
1297	debounced.cancel = () => {
1298		if (timeoutId !== void 0) {
1299			clearTimeout(timeoutId);
1300			timeoutId = void 0;
1301		}
1302	};
1303	return debounced;
1304}
1305function throttle(fn, wait) {
1306	let timeoutId;
1307	let lastExecutionTime = 0;
1308	let pendingArgs;
1309	let pendingThis;
1310	const throttled = function(...args) {
1311		const now = Date.now();
1312		const timeSinceLastExecution = now - lastExecutionTime;
1313		pendingArgs = args;
1314		pendingThis = this;
1315		if (timeSinceLastExecution >= wait) {
1316			lastExecutionTime = now;
1317			fn.apply(this, args);
1318			pendingArgs = void 0;
1319			pendingThis = void 0;
1320		} else if (timeoutId === void 0) {
1321			const remainingTime = wait - timeSinceLastExecution;
1322			timeoutId = setTimeout(() => {
1323				timeoutId = void 0;
1324				lastExecutionTime = Date.now();
1325				if (pendingArgs !== void 0) {
1326					fn.apply(pendingThis, pendingArgs);
1327					pendingArgs = void 0;
1328					pendingThis = void 0;
1329				}
1330			}, remainingTime);
1331		}
1332	};
1333	throttled.cancel = () => {
1334		if (timeoutId !== void 0) {
1335			clearTimeout(timeoutId);
1336			timeoutId = void 0;
1337		}
1338		pendingArgs = void 0;
1339		pendingThis = void 0;
1340	};
1341	return throttled;
1342}
1343var pluginRegistry = /* @__PURE__ */ new Map();
1344function registerPlugin(name, handler) {
1345	if (pluginRegistry.has(name)) console.warn(`Plugin "${name}" is already registered. Overwriting.`);
1346	pluginRegistry.set(name, handler);
1347}
1348function getPlugin(name) {
1349	return pluginRegistry.get(name);
1350}
1351var scopeMetadataMap = /* @__PURE__ */ new WeakMap();
1352function createScopeMetadata(scope, origin, parent) {
1353	const metadata = {
1354		origin,
1355		pins: /* @__PURE__ */ new Map(),
1356		uidCounter: 0,
1357		parent
1358	};
1359	scopeMetadataMap.set(scope, metadata);
1360	return metadata;
1361}
1362function registerPin(scope, name, element) {
1363	const metadata = scopeMetadataMap.get(scope);
1364	if (metadata) metadata.pins.set(name, element);
1365}
1366function getPin(scope, name) {
1367	return scopeMetadataMap.get(scope)?.pins.get(name);
1368}
1369function incrementUidCounter(scope) {
1370	const metadata = scopeMetadataMap.get(scope);
1371	if (!metadata) return 0;
1372	return ++metadata.uidCounter;
1373}
1374function createPulse() {
1375	return (cb) => {
1376		queueMicrotask(cb);
1377	};
1378}
1379function createUid(scope) {
1380	return (prefix) => {
1381		const counter = incrementUidCounter(scope);
1382		return prefix ? `volt-${prefix}-${counter}` : `volt-${counter}`;
1383	};
1384}
1385function createArc(element) {
1386	return (eventName, detail) => {
1387		const event = new CustomEvent(eventName, {
1388			detail,
1389			bubbles: true,
1390			composed: true,
1391			cancelable: true
1392		});
1393		element.dispatchEvent(event);
1394	};
1395}
1396function createProbe(scope) {
1397	return (expr, cb) => {
1398		const unsubs = [];
1399		let isDisposed = false;
1400		const runProbe = () => {
1401			if (isDisposed) return;
1402			try {
1403				const value = evaluate(expr, scope);
1404				cb(value);
1405			} catch (error) {
1406				console.error("Error in $probe expression:", error);
1407			}
1408		};
1409		try {
1410			const deps = extractDeps(expr, scope);
1411			for (const dep of deps) {
1412				const unsubscribe = dep.subscribe(runProbe);
1413				unsubs.push(unsubscribe);
1414			}
1415		} catch (error) {
1416			console.error("Error extracting dependencies for $probe:", error);
1417		}
1418		runProbe();
1419		return () => {
1420			isDisposed = true;
1421			for (const unsub of unsubs) try {
1422				unsub();
1423			} catch (error) {
1424				console.error("Error unsubscribing $probe:", error);
1425			}
1426		};
1427	};
1428}
1429var trackingStack = [];
1430function getActiveContext() {
1431	return trackingStack.at(-1);
1432}
1433function startTracking(source) {
1434	const context = {
1435		deps: /* @__PURE__ */ new Set(),
1436		source
1437	};
1438	trackingStack.push(context);
1439	return context;
1440}
1441function stopTracking() {
1442	const context = trackingStack.pop();
1443	if (!context) {
1444		console.warn("stopTracking called without matching startTracking");
1445		return [];
1446	}
1447	return [...context.deps];
1448}
1449function recordDep(dep) {
1450	const context = getActiveContext();
1451	if (!context) return;
1452	if (context.source === dep) throw new Error("Circular dependency detected: a signal cannot depend on itself");
1453	context.deps.add(dep);
1454}
1455function signal(initialValue) {
1456	let value = initialValue;
1457	const subscribers = /* @__PURE__ */ new Set();
1458	const notify = () => {
1459		const snapshot = [...subscribers];
1460		for (const callback of snapshot) try {
1461			callback(value);
1462		} catch (error) {
1463			report(error, { source: "effect" });
1464		}
1465	};
1466	const sig = {
1467		get() {
1468			recordDep(sig);
1469			return value;
1470		},
1471		set(newValue) {
1472			if (value === newValue) return;
1473			value = newValue;
1474			notify();
1475		},
1476		subscribe(callback) {
1477			subscribers.add(callback);
1478			return () => {
1479				subscribers.delete(callback);
1480			};
1481		}
1482	};
1483	return sig;
1484}
1485function computed(compute) {
1486	let value;
1487	let isInitialized = false;
1488	let isRecomputing = false;
1489	const subs = /* @__PURE__ */ new Set();
1490	const unsubscribers = [];
1491	const notify = () => {
1492		const snapshot = [...subs];
1493		for (const cb of snapshot) try {
1494			cb(value);
1495		} catch (error) {
1496			report(error, { source: "effect" });
1497		}
1498	};
1499	const recompute = () => {
1500		if (isRecomputing) throw new Error("Circular dependency detected in computed signal");
1501		isRecomputing = true;
1502		let shouldNotify = false;
1503		try {
1504			for (const unsub of unsubscribers) unsub();
1505			unsubscribers.length = 0;
1506			startTracking(comp);
1507			try {
1508				const newValue = compute();
1509				if (!isInitialized || value !== newValue) {
1510					value = newValue;
1511					isInitialized = true;
1512					shouldNotify = subs.size > 0;
1513				}
1514			} catch (error) {
1515				report(error, { source: "effect" });
1516				throw error;
1517			} finally {
1518				const deps = stopTracking();
1519				for (const dep of deps) {
1520					const unsub = dep.subscribe(recompute);
1521					unsubscribers.push(unsub);
1522				}
1523			}
1524		} finally {
1525			isRecomputing = false;
1526		}
1527		if (shouldNotify) notify();
1528	};
1529	const comp = {
1530		get() {
1531			if (!isInitialized) recompute();
1532			recordDep(comp);
1533			return value;
1534		},
1535		subscribe(callback) {
1536			if (!isInitialized) recompute();
1537			subs.add(callback);
1538			return () => {
1539				subs.delete(callback);
1540			};
1541		}
1542	};
1543	return comp;
1544}
1545var storeSignals = /* @__PURE__ */ new Map();
1546var store = {
1547	_signals: storeSignals,
1548	get(key) {
1549		const sig = storeSignals.get(key);
1550		return sig ? sig.get() : void 0;
1551	},
1552	set(key, value) {
1553		const sig = storeSignals.get(key);
1554		if (sig) sig.set(value);
1555		else storeSignals.set(key, signal(value));
1556	},
1557	has(key) {
1558		return storeSignals.has(key);
1559	}
1560};
1561function registerStore(state) {
1562	for (const [key, value] of Object.entries(state)) if (value && typeof value === "object" && "get" in value && "set" in value && "subscribe" in value) {
1563		storeSignals.set(key, value);
1564		Object.defineProperty(store, key, {
1565			get: () => value,
1566			enumerable: true,
1567			configurable: true
1568		});
1569	} else {
1570		const sig = signal(value);
1571		storeSignals.set(key, sig);
1572		Object.defineProperty(store, key, {
1573			get: () => sig,
1574			enumerable: true,
1575			configurable: true
1576		});
1577	}
1578}
1579function getStore() {
1580	return store;
1581}
1582var directiveRegistry = /* @__PURE__ */ new Map();
1583function registerDirective(name, handler) {
1584	directiveRegistry.set(name, handler);
1585}
1586function scheduleTransitionTask(cb) {
1587	let executed = false;
1588	const wrapped = () => {
1589		if (executed) return;
1590		executed = true;
1591		cb();
1592	};
1593	if (typeof requestAnimationFrame === "function") requestAnimationFrame(wrapped);
1594	setTimeout(wrapped, 16);
1595}
1596function mount(root, scope) {
1597	injectSpecialVars(scope, root);
1598	execGlobalHooks("beforeMount", root, scope);
1599	const elements = walkDOM(root).filter((element) => {
1600		let current = element;
1601		while (current) {
1602			if (Object.hasOwn(current.dataset, "voltSkip")) return false;
1603			if (current === root) break;
1604			current = current.parentElement;
1605		}
1606		return true;
1607	});
1608	const allCleanups = [];
1609	const mountedElements = [];
1610	for (const el$1 of elements) {
1611		if (Object.hasOwn(el$1.dataset, "voltCloak")) delete el$1.dataset.voltCloak;
1612		const attributes = getVoltAttrs(el$1);
1613		const context = {
1614			element: el$1,
1615			scope,
1616			cleanups: []
1617		};
1618		if (attributes.has("for")) {
1619			const forExpression = attributes.get("for");
1620			bindFor(context, forExpression);
1621			notifyBindingCreated(el$1, "for");
1622		} else if (attributes.has("if")) {
1623			const ifExpression = attributes.get("if");
1624			bindIf(context, ifExpression);
1625			notifyBindingCreated(el$1, "if");
1626		} else for (const [name, value] of attributes) {
1627			bindAttribute(context, name, value);
1628			notifyBindingCreated(el$1, name);
1629		}
1630		notifyElementMounted(el$1);
1631		mountedElements.push(el$1);
1632		allCleanups.push(...context.cleanups);
1633	}
1634	execGlobalHooks("afterMount", root, scope);
1635	return () => {
1636		execGlobalHooks("beforeUnmount", root);
1637		for (const element of mountedElements) notifyElementUnmounted(element);
1638		for (const cleanup of allCleanups) try {
1639			cleanup();
1640		} catch (error) {
1641			report(error, {
1642				source: "binding",
1643				element: root
1644			});
1645		}
1646		execGlobalHooks("afterUnmount", root);
1647	};
1648}
1649function execPlugin(plugin, ctx, val, base) {
1650	const pluginCtx = createPluginCtx(ctx);
1651	try {
1652		plugin(pluginCtx, val);
1653	} catch (error) {
1654		report(error, {
1655			source: "plugin",
1656			element: ctx.element,
1657			directive: `data-volt-${base}`,
1658			pluginName: base
1659		});
1660	}
1661}
1662function bindAttribute(ctx, name, value) {
1663	if (name.startsWith("on-")) {
1664		const eventSpec = name.slice(3);
1665		const { baseName: eventName, modifiers: modifiers$1 } = parseModifiers(eventSpec);
1666		bindEvent(ctx, eventName, value, modifiers$1);
1667		return;
1668	}
1669	if (name.startsWith("bind:") || name.startsWith("bind-")) {
1670		const attrSpec = name.slice(5);
1671		const { baseName: attrName, modifiers: modifiers$1 } = parseModifiers(attrSpec);
1672		bindAttr(ctx, attrName, value, modifiers$1);
1673		return;
1674	}
1675	if (name.includes(":")) {
1676		const colonIndex = name.indexOf(":");
1677		const pluginName = name.slice(0, colonIndex);
1678		const suffix = name.slice(colonIndex + 1);
1679		const plugin = getPlugin(pluginName);
1680		if (plugin) {
1681			const combinedVal = `${suffix}:${value}`;
1682			execPlugin(plugin, ctx, combinedVal, pluginName);
1683			return;
1684		}
1685	}
1686	const { baseName, modifiers } = parseModifiers(name);
1687	switch (baseName) {
1688		case "text":
1689			bindNode("text")(ctx, value);
1690			break;
1691		case "html":
1692			bindNode("html")(ctx, value);
1693			break;
1694		case "class":
1695			bindClass(ctx, value);
1696			break;
1697		case "show":
1698			bindShow(ctx, value);
1699			break;
1700		case "style":
1701			bindStyle(ctx, value);
1702			break;
1703		case "model":
1704			bindModel(ctx, value, modifiers);
1705			break;
1706		case "pin":
1707			bindPin(ctx, value);
1708			break;
1709		case "init":
1710			bindInit(ctx, value);
1711			break;
1712		case "for":
1713			bindFor(ctx, value);
1714			break;
1715		case "else": break;
1716		default: {
1717			const directiveHandler = directiveRegistry.get(baseName);
1718			if (directiveHandler) {
1719				directiveHandler(ctx, value, modifiers);
1720				return;
1721			}
1722			const plugin = getPlugin(baseName);
1723			if (plugin) execPlugin(plugin, ctx, value, baseName);
1724			else console.warn(`Unknown binding: data-volt-${baseName}`);
1725		}
1726	}
1727}
1728function bindNode(kind) {
1729	return function(ctx, expr) {
1730		const update = () => {
1731			const value = evaluate(expr, ctx.scope);
1732			if (kind === "text") setText(ctx.element, value);
1733			else setHTML(ctx.element, String(value ?? ""));
1734		};
1735		updateAndRegister(ctx, update, expr);
1736	};
1737}
1738function bindClass(ctx, expr) {
1739	let prevClasses = /* @__PURE__ */ new Map();
1740	const update = () => {
1741		const value = evaluate(expr, ctx.scope);
1742		const classes = parseClassBinding(value);
1743		for (const [className] of prevClasses) if (!classes.has(className)) toggleClass(ctx.element, className, false);
1744		for (const [className, shouldAdd] of classes) toggleClass(ctx.element, className, shouldAdd);
1745		prevClasses = classes;
1746	};
1747	updateAndRegister(ctx, update, expr);
1748}
1749function bindShow(ctx, expr) {
1750	const el$1 = ctx.element;
1751	const originalInlineDisplay = el$1.style.display;
1752	if (!hasSurge(el$1)) {
1753		const update$1 = () => {
1754			const value = evaluate(expr, ctx.scope);
1755			if (Boolean(value)) el$1.style.display = originalInlineDisplay;
1756			else el$1.style.display = "none";
1757		};
1758		updateAndRegister(ctx, update$1, expr);
1759		return;
1760	}
1761	let isVisible = el$1.style.display !== "none";
1762	let isTransitioning = false;
1763	const update = () => {
1764		const value = evaluate(expr, ctx.scope);
1765		const shouldShow = Boolean(value);
1766		if (shouldShow === isVisible || isTransitioning) return;
1767		isTransitioning = true;
1768		scheduleTransitionTask(() => {
1769			(async () => {
1770				try {
1771					if (shouldShow) {
1772						el$1.style.display = originalInlineDisplay;
1773						await executeSurgeEnter(el$1);
1774						isVisible = true;
1775					} else {
1776						await executeSurgeLeave(el$1);
1777						el$1.style.display = "none";
1778						isVisible = false;
1779					}
1780				} finally {
1781					isTransitioning = false;
1782				}
1783			})();
1784		});
1785	};
1786	updateAndRegister(ctx, update, expr);
1787}
1788function bindStyle(ctx, expr) {
1789	const element = ctx.element;
1790	const update = () => {
1791		const value = evaluate(expr, ctx.scope);
1792		if (typeof value === "object" && value !== null) for (const [key, val] of Object.entries(value)) {
1793			const cssKey = key.replaceAll(/[A-Z]/g, (m) => `-${m.toLowerCase()}`);
1794			if (isNil(val)) element.style.removeProperty(cssKey);
1795			else try {
1796				element.style.setProperty(cssKey, String(val));
1797			} catch (error) {
1798				report(error, {
1799					source: "binding",
1800					element,
1801					directive: "data-volt-style",
1802					expression: expr
1803				});
1804			}
1805		}
1806		else if (typeof value === "string") element.style.cssText = value;
1807	};
1808	updateAndRegister(ctx, update, expr);
1809}
1810function extractStatements(expr) {
1811	const statements = [];
1812	let current = "";
1813	let depth = 0;
1814	let inString = null;
1815	for (const [i, char] of [...expr].entries()) {
1816		const prev = i > 0 ? expr[i - 1] : "";
1817		if ((char === "\"" || char === "'") && prev !== "\\") {
1818			if (inString === char) inString = null;
1819			else if (inString === null) inString = char;
1820		}
1821		if (inString === null) {
1822			if (char === "(" || char === "{" || char === "[") depth++;
1823			else if (char === ")" || char === "}" || char === "]") depth--;
1824		}
1825		if (char === ";" && depth === 0 && inString === null) {
1826			if (current.trim()) statements.push(current.trim());
1827			current = "";
1828		} else current += char;
1829	}
1830	if (current.trim()) statements.push(current.trim());
1831	return statements;
1832}
1833function bindEvent(ctx, eventName, expr, modifiers = []) {
1834	const executeHandler = (event) => {
1835		const eventScope = {
1836			...ctx.scope,
1837			$el: ctx.element,
1838			$event: event
1839		};
1840		try {
1841			const statements = extractStatements(expr);
1842			let result;
1843			for (const stmt of statements) result = evaluate(stmt, eventScope, { unwrapSignals: false });
1844			if (typeof result === "function") result(event);
1845		} catch (error) {
1846			report(error, {
1847				source: "binding",
1848				element: ctx.element,
1849				directive: `data-volt-on-${eventName}`,
1850				expression: expr
1851			});
1852		}
1853	};
1854	let wrappedExecute = executeHandler;
1855	if (hasModifier(modifiers, "debounce")) {
1856		const wait = getModifierValue(modifiers, "debounce", 300);
1857		const debouncedExecute = debounce(executeHandler, wait);
1858		wrappedExecute = debouncedExecute;
1859		ctx.cleanups.push(() => debouncedExecute.cancel());
1860	} else if (hasModifier(modifiers, "throttle")) {
1861		const wait = getModifierValue(modifiers, "throttle", 300);
1862		const throttledExecute = throttle(executeHandler, wait);
1863		wrappedExecute = throttledExecute;
1864		ctx.cleanups.push(() => throttledExecute.cancel());
1865	}
1866	const handler = (event) => {
1867		if (hasModifier(modifiers, "self") && event.target !== ctx.element) return;
1868		if (hasModifier(modifiers, "prevent")) event.preventDefault();
1869		if (hasModifier(modifiers, "stop")) event.stopPropagation();
1870		wrappedExecute(event);
1871	};
1872	const target = hasModifier(modifiers, "window") ? globalThis : hasModifier(modifiers, "document") ? document : ctx.element;
1873	const options$1 = {};
1874	if (hasModifier(modifiers, "once")) options$1.once = true;
1875	if (hasModifier(modifiers, "passive")) options$1.passive = true;
1876	target.addEventListener(eventName, handler, options$1);
1877	ctx.cleanups.push(() => {
1878		target.removeEventListener(eventName, handler, options$1);
1879	});
1880}
1881function getNestedProperty(obj, path) {
1882	let current = obj;
1883	for (const key of path) {
1884		if (current == null || typeof current !== "object") return;
1885		current = current[key];
1886	}
1887	return current;
1888}
1889function setNestedProperty(obj, path, value) {
1890	if (path.length === 0) return value;
1891	if (obj == null || typeof obj !== "object") return obj;
1892	const clone = Array.isArray(obj) ? [...obj] : { ...obj };
1893	const [head, ...tail] = path;
1894	if (tail.length === 0) clone[head] = value;
1895	else clone[head] = setNestedProperty(clone[head], tail, value);
1896	return clone;
1897}
1898function findModelSignal(scope, path) {
1899	const signal$1 = findScopedSignal(scope, path);
1900	if (signal$1) return {
1901		signal: signal$1,
1902		propertyPath: []
1903	};
1904	const parts = path.split(".");
1905	for (let i = parts.length - 1; i > 0; i--) {
1906		const prefix = parts.slice(0, i).join(".");
1907		const testSignal = findScopedSignal(scope, prefix);
1908		if (testSignal) {
1909			const propertyPath = parts.slice(i);
1910			return {
1911				signal: testSignal,
1912				propertyPath
1913			};
1914		}
1915	}
1916	return null;
1917}
1918function bindModel(context, signalPath, modifiers = []) {
1919	const result = findModelSignal(context.scope, signalPath);
1920	if (!result) {
1921		report(/* @__PURE__ */ new Error(`Signal "${signalPath}" not found`), {
1922			source: "binding",
1923			element: context.element,
1924			directive: "data-volt-model",
1925			expression: signalPath
1926		});
1927		return;
1928	}
1929	const { signal: signal$1, propertyPath } = result;
1930	const element = context.element;
1931	const type = element instanceof HTMLInputElement ? element.type : null;
1932	const getValue = () => {
1933		const signalValue = signal$1.get();
1934		return propertyPath.length > 0 ? getNestedProperty(signalValue, propertyPath) : signalValue;
1935	};
1936	const initialValue = getValue();
1937	setElementValue(element, initialValue, type);
1938	const unsubscribe = signal$1.subscribe(() => {
1939		const value = getValue();
1940		setElementValue(element, value, type);
1941	});
1942	context.cleanups.push(unsubscribe);
1943	const isLazy = hasModifier(modifiers, "lazy");
1944	const isNumber = hasModifier(modifiers, "number");
1945	const isTrim = hasModifier(modifiers, "trim");
1946	const eventName = isLazy ? "change" : type === "checkbox" || type === "radio" ? "change" : "input";
1947	const baseHandler = () => {
1948		let value = getElementValue(element, type);
1949		if (typeof value === "string") {
1950			if (isTrim) value = value.trim();
1951			if (isNumber) value = value === "" ? NaN : Number(value);
1952		}
1953		if (propertyPath.length > 0) {
1954			const currentObj = signal$1.get();
1955			const updatedObj = setNestedProperty(currentObj, propertyPath, value);
1956			signal$1.set(updatedObj);
1957		} else signal$1.set(value);
1958	};
1959	let handler = baseHandler;
1960	if (hasModifier(modifiers, "debounce")) {
1961		const wait = getModifierValue(modifiers, "debounce", 300);
1962		const debouncedHandler = debounce(baseHandler, wait);
1963		handler = debouncedHandler;
1964		context.cleanups.push(() => debouncedHandler.cancel());
1965	}
1966	element.addEventListener(eventName, handler);
1967	context.cleanups.push(() => {
1968		element.removeEventListener(eventName, handler);
1969	});
1970}
1971function setElementValue(el$1, value, type) {
1972	if (el$1 instanceof HTMLInputElement) switch (type) {
1973		case "checkbox":
1974			el$1.checked = Boolean(value);
1975			break;
1976		case "radio":
1977			el$1.checked = el$1.value === String(value);
1978			break;
1979		case "number":
1980			el$1.value = String(value ?? "");
1981			break;
1982		default: el$1.value = String(value ?? "");
1983	}
1984	else if (el$1 instanceof HTMLSelectElement) el$1.value = String(value ?? "");
1985	else if (el$1 instanceof HTMLTextAreaElement) el$1.value = String(value ?? "");
1986}
1987function getElementValue(el$1, type) {
1988	if (el$1 instanceof HTMLInputElement) {
1989		if (type === "checkbox") return el$1.checked;
1990		if (type === "number") return el$1.valueAsNumber;
1991		return el$1.value;
1992	}
1993	if (el$1 instanceof HTMLSelectElement) return el$1.value;
1994	if (el$1 instanceof HTMLTextAreaElement) return el$1.value;
1995	return "";
1996}
1997function bindAttr(ctx, attrName, expr, modifiers = []) {
1998	const isNumber = hasModifier(modifiers, "number");
1999	const isTrim = hasModifier(modifiers, "trim");
2000	const update = () => {
2001		let value = evaluate(expr, ctx.scope);
2002		if (typeof value === "string") {
2003			if (isTrim) value = value.trim();
2004			if (isNumber) value = value === "" ? NaN : Number(value);
2005		}
2006		if (new Set(BOOLEAN_ATTRS).has(attrName)) if (value) ctx.element.setAttribute(attrName, "");
2007		else ctx.element.removeAttribute(attrName);
2008		else if (isNil(value) || value === false) ctx.element.removeAttribute(attrName);
2009		else ctx.element.setAttribute(attrName, String(value));
2010	};
2011	updateAndRegister(ctx, update, expr);
2012}
2013function bindInit(ctx, expr) {
2014	try {
2015		const statements = extractStatements(expr);
2016		for (const stmt of statements) evaluate(stmt, ctx.scope, { unwrapSignals: false });
2017	} catch (error) {
2018		report(error, {
2019			source: "binding",
2020			element: ctx.element,
2021			directive: "data-volt-init",
2022			expression: expr
2023		});
2024	}
2025}
2026function bindPin(ctx, name) {
2027	registerPin(ctx.scope, name, ctx.element);
2028}
2029function bindFor(ctx, expr) {
2030	const parsed = parseForExpr(expr);
2031	if (!parsed) {
2032		report(/* @__PURE__ */ new Error(`Invalid data-volt-for expression: "${expr}"`), {
2033			source: "binding",
2034			element: ctx.element,
2035			directive: "data-volt-for",
2036			expression: expr
2037		});
2038		return;
2039	}
2040	const { itemName, indexName, arrayPath } = parsed;
2041	const templ = ctx.element;
2042	if (!templ.parentElement) {
2043		report(/* @__PURE__ */ new Error("data-volt-for element must have a parent"), {
2044			source: "binding",
2045			element: ctx.element,
2046			directive: "data-volt-for",
2047			expression: expr
2048		});
2049		return;
2050	}
2051	const placeholder = document.createComment(`for: ${expr}`);
2052	templ.before(placeholder);
2053	templ.remove();
2054	const renderedElements = [];
2055	const renderedCleanups = [];
2056	const render = () => {
2057		for (const cleanup of renderedCleanups) cleanup();
2058		renderedCleanups.length = 0;
2059		for (const element of renderedElements) element.remove();
2060		renderedElements.length = 0;
2061		const arrayValue = evaluate(arrayPath, ctx.scope);
2062		if (!Array.isArray(arrayValue)) return;
2063		for (const [index, item] of arrayValue.entries()) {
2064			const clone = templ.cloneNode(true);
2065			delete clone.dataset.voltFor;
2066			const itemScope = {
2067				...ctx.scope,
2068				[itemName]: item
2069			};
2070			if (indexName) itemScope[indexName] = index;
2071			const cleanup = mount(clone, itemScope);
2072			renderedCleanups.push(cleanup);
2073			renderedElements.push(clone);
2074			placeholder.before(clone);
2075		}
2076	};
2077	updateAndRegister(ctx, render, expr);
2078	ctx.cleanups.push(() => {
2079		for (const cleanup of renderedCleanups) cleanup();
2080	});
2081}
2082function bindIf(ctx, expr) {
2083	const ifTempl = ctx.element;
2084	if (!ifTempl.parentElement) {
2085		report(/* @__PURE__ */ new Error("data-volt-if element must have a parent"), {
2086			source: "binding",
2087			element: ctx.element,
2088			directive: "data-volt-if",
2089			expression: expr
2090		});
2091		return;
2092	}
2093	let elseTempl;
2094	let nextSibling = ifTempl.nextElementSibling;
2095	while (nextSibling && nextSibling.nodeType !== 1) nextSibling = nextSibling.nextElementSibling;
2096	if (nextSibling && Object.hasOwn(nextSibling.dataset, "voltElse")) {
2097		elseTempl = nextSibling;
2098		elseTempl.remove();
2099	}
2100	const placeholder = document.createComment(`if: ${expr}`);
2101	ifTempl.before(placeholder);
2102	ifTempl.remove();
2103	const ifHasSurge = hasSurge(ifTempl);
2104	const elseHasSurge = elseTempl ? hasSurge(elseTempl) : false;
2105	const anySurge = ifHasSurge || elseHasSurge;
2106	let currentElement;
2107	let currentCleanup;
2108	let currentBranch;
2109	let isTransitioning = false;
2110	let pendingRender = false;
2111	const render = () => {
2112		const condition = evaluate(expr, ctx.scope);
2113		const targetBranch = Boolean(condition) ? "if" : elseTempl ? "else" : void 0;
2114		if (targetBranch === currentBranch || isTransitioning) {
2115			if (isTransitioning) pendingRender = true;
2116			return;
2117		}
2118		if (!anySurge) {
2119			if (currentCleanup) {
2120				currentCleanup();
2121				currentCleanup = void 0;
2122			}
2123			if (currentElement) {
2124				currentElement.remove();
2125				currentElement = void 0;
2126			}
2127			if (targetBranch === "if") {
2128				currentElement = ifTempl.cloneNode(true);
2129				delete currentElement.dataset.voltIf;
2130				currentCleanup = mount(currentElement, ctx.scope);
2131				placeholder.before(currentElement);
2132				currentBranch = "if";
2133			} else if (targetBranch === "else" && elseTempl) {
2134				currentElement = elseTempl.cloneNode(true);
2135				delete currentElement.dataset.voltElse;
2136				currentCleanup = mount(currentElement, ctx.scope);
2137				placeholder.before(currentElement);
2138				currentBranch = "else";
2139			} else currentBranch = void 0;
2140			return;
2141		}
2142		isTransitioning = true;
2143		(async () => {
2144			try {
2145				if (currentElement) {
2146					const currentEl = currentElement;
2147					if (currentBranch === "if" ? ifHasSurge : elseHasSurge) await executeSurgeLeave(currentEl);
2148					if (currentCleanup) {
2149						currentCleanup();
2150						currentCleanup = void 0;
2151					}
2152					currentElement.remove();
2153					currentElement = void 0;
2154				}
2155				if (targetBranch === "if") {
2156					currentElement = ifTempl.cloneNode(true);
2157					delete currentElement.dataset.voltIf;
2158					placeholder.before(currentElement);
2159					if (ifHasSurge) await executeSurgeEnter(currentElement);
2160					currentCleanup = mount(currentElement, ctx.scope);
2161					currentBranch = "if";
2162				} else if (targetBranch === "else" && elseTempl) {
2163					currentElement = elseTempl.cloneNode(true);
2164					delete currentElement.dataset.voltElse;
2165					placeholder.before(currentElement);
2166					if (elseHasSurge) await executeSurgeEnter(currentElement);
2167					currentCleanup = mount(currentElement, ctx.scope);
2168					currentBranch = "else";
2169				} else currentBranch = void 0;
2170			} finally {
2171				isTransitioning = false;
2172				if (pendingRender) {
2173					pendingRender = false;
2174					render();
2175				}
2176			}
2177		})();
2178	};
2179	updateAndRegister(ctx, render, expr);
2180	ctx.cleanups.push(() => {
2181		if (currentCleanup) currentCleanup();
2182	});
2183}
2184function parseForExpr(expr) {
2185	const trimmed = expr.trim();
2186	const withIndex = /^\((\w+)\s*,\s*(\w+)\)\s+in\s+(.+)$/.exec(trimmed);
2187	if (withIndex) return {
2188		itemName: withIndex[1],
2189		indexName: withIndex[2],
2190		arrayPath: withIndex[3].trim()
2191	};
2192	const simple = /^(\w+)\s+in\s+(.+)$/.exec(trimmed);
2193	if (simple) return {
2194		itemName: simple[1],
2195		indexName: void 0,
2196		arrayPath: simple[2].trim()
2197	};
2198}
2199function createPluginCtx(ctx) {
2200	const mountCallbacks = [];
2201	const unmountCallbacks = [];
2202	const beforeBindingCallbacks = [];
2203	const afterBindingCallbacks = [];
2204	const lifecycle = {
2205		onMount: (cb) => {
2206			mountCallbacks.push(cb);
2207			try {
2208				cb();
2209			} catch (error) {
2210				report(error, {
2211					source: "plugin",
2212					element: ctx.element,
2213					hookName: "onMount"
2214				});
2215			}
2216		},
2217		onUnmount: (cb) => {
2218			unmountCallbacks.push(cb);
2219		},
2220		beforeBinding: (cb) => {
2221			beforeBindingCallbacks.push(cb);
2222			try {
2223				cb();
2224			} catch (error) {
2225				report(error, {
2226					source: "plugin",
2227					element: ctx.element,
2228					hookName: "beforeBinding"
2229				});
2230			}
2231		},
2232		afterBinding: (cb) => {
2233			afterBindingCallbacks.push(cb);
2234			queueMicrotask(() => {
2235				try {
2236					cb();
2237				} catch (error) {
2238					report(error, {
2239						source: "plugin",
2240						element: ctx.element,
2241						hookName: "afterBinding"
2242					});
2243				}
2244			});
2245		}
2246	};
2247	ctx.cleanups.push(() => {
2248		for (const cb of unmountCallbacks) try {
2249			cb();
2250		} catch (error) {
2251			report(error, {
2252				source: "plugin",
2253				element: ctx.element,
2254				hookName: "onUnmount"
2255			});
2256		}
2257	});
2258	return {
2259		element: ctx.element,
2260		scope: ctx.scope,
2261		addCleanup: (fn) => {
2262			ctx.cleanups.push(fn);
2263		},
2264		findSignal: (path) => findScopedSignal(ctx.scope, path),
2265		evaluate: (expr, options$1) => evaluate(expr, ctx.scope, options$1),
2266		lifecycle
2267	};
2268}
2269function injectSpecialVars(scope, root) {
2270	createScopeMetadata(scope, root);
2271	scope.$store = getStore();
2272	scope.$pulse = createPulse();
2273	scope.$origin = root;
2274	scope.$scope = scope;
2275	scope.$pins = new Proxy({}, {
2276		get(_target, prop) {
2277			if (typeof prop === "string") return getPin(scope, prop);
2278		},
2279		has(_target, prop) {
2280			if (typeof prop === "string") return getPin(scope, prop) !== void 0;
2281			return false;
2282		}
2283	});
2284	scope.$uid = createUid(scope);
2285	scope.$arc = createArc(root);
2286	scope.$probe = createProbe(scope);
2287}
2288function charge(rootSelector = "[data-volt]") {
2289	parseDeclarativeStore();
2290	const elements = document.querySelectorAll(rootSelector);
2291	const chargedRoots = [];
2292	for (const element of elements) try {
2293		const scope = createScopeFromElement(element);
2294		const cleanup = mount(element, scope);
2295		chargedRoots.push({
2296			element,
2297			scope,
2298			cleanup
2299		});
2300	} catch (error) {
2301		report(error, {
2302			source: "charge",
2303			element
2304		});
2305	}
2306	return {
2307		roots: chargedRoots,
2308		cleanup: () => {
2309			for (const root of chargedRoots) try {
2310				root.cleanup();
2311			} catch (error) {
2312				report(error, {
2313					source: "charge",
2314					element: root.element
2315				});
2316			}
2317		}
2318	};
2319}
2320function createScopeFromElement(el$1) {
2321	const scope = {};
2322	const stateAttr = el$1.dataset.voltState;
2323	if (stateAttr) try {
2324		const stateData = JSON.parse(stateAttr);
2325		if (typeof stateData !== "object" || isNil(stateData) || Array.isArray(stateData)) report(/* @__PURE__ */ new Error(`data-volt-state must be a JSON object, got ${typeof stateData}`), {
2326			source: "charge",
2327			level: "fatal",
2328			element: el$1,
2329			directive: "data-volt-state",
2330			expression: stateAttr
2331		});
2332		else for (const [key, value] of Object.entries(stateData)) scope[key] = signal(value);
2333	} catch (error) {
2334		report(error, {
2335			source: "charge",
2336			level: "fatal",
2337			element: el$1,
2338			directive: "data-volt-state",
2339			expression: stateAttr
2340		});
2341	}
2342	const computedAttrs = getComputedAttributes(el$1);
2343	for (const [name, expression] of computedAttrs) try {
2344		scope[name] = computed(() => evaluate(expression, scope));
2345	} catch (error) {
2346		report(error, {
2347			source: "charge",
2348			element: el$1,
2349			directive: `data-volt-computed:${name}`,
2350			expression
2351		});
2352	}
2353	return scope;
2354}
2355function parseDeclarativeStore() {
2356	const scripts = document.querySelectorAll("script[data-volt-store][type=\"application/json\"]");
2357	for (const script of scripts) try {
2358		const content = script.textContent?.trim();
2359		if (!content) continue;
2360		const data = JSON.parse(content);
2361		if (typeof data !== "object" || isNil(data) || Array.isArray(data)) {
2362			report(/* @__PURE__ */ new Error(`data-volt-store script must contain a JSON object, got: ${typeof data}`), {
2363				source: "charge",
2364				level: "fatal",
2365				element: script,
2366				directive: "data-volt-store"
2367			});
2368			continue;
2369		}
2370		registerStore(data);
2371	} catch (error) {
2372		report(error, {
2373			source: "charge",
2374			level: "fatal",
2375			element: script,
2376			directive: "data-volt-store"
2377		});
2378	}
2379}
2380var scrollPositions = /* @__PURE__ */ new Map();
2381var focusSelectors = /* @__PURE__ */ new Map();
2382var currentRouterMode = "history";
2383function setRouterMode(mode) {
2384	currentRouterMode = mode;
2385}
2386function getLocationKey() {
2387	if (currentRouterMode === "hash") return globalThis.location.hash.slice(1) || "/";
2388	return `${globalThis.location.pathname}${globalThis.location.search}`;
2389}
2390function bindNavigate(ctx, value, modifiers = []) {
2391	const element = ctx.element;
2392	if (element instanceof HTMLAnchorElement) handleLinkNavigation(ctx, value, modifiers);
2393	else if (element instanceof HTMLFormElement) handleFormNavigation(ctx, value, modifiers);
2394	else console.warn("data-volt-navigate only works on <a> and <form> elements");
2395}
2396function handleLinkNavigation(ctx, value, modifiers) {
2397	const link = ctx.element;
2398	const targetUrl = value || link.getAttribute("href");
2399	if (!targetUrl) {
2400		console.warn("data-volt-navigate: no URL specified and no href found");
2401		return;
2402	}
2403	if (hasModifier(modifiers, "prefetch")) {
2404		const viewportPrefetch = hasModifier(modifiers, "viewport");
2405		setupPrefetch(link, targetUrl, { viewport: viewportPrefetch });
2406	}
2407	const clickHandler = async (event) => {
2408		if (event.ctrlKey || event.metaKey || event.shiftKey || event.button !== 0) return;
2409		if (isExternalLink(targetUrl)) return;
2410		event.preventDefault();
2411		const useReplace = hasModifier(modifiers, "replace");
2412		const useTransition = !hasModifier(modifiers, "notransition");
2413		await navigateTo(targetUrl, {
2414			replace: useReplace,
2415			transition: useTransition,
2416			transitionName: "page-transition"
2417		});
2418	};
2419	link.addEventListener("click", clickHandler);
2420	ctx.cleanups.push(() => link.removeEventListener("click", clickHandler));
2421}
2422function handleFormNavigation(ctx, value, modifiers) {
2423	const form$1 = ctx.element;
2424	const targetUrl = value || form$1.getAttribute("action") || globalThis.location.pathname;
2425	const submitHandler = async (event) => {
2426		event.preventDefault();
2427		const formData = new FormData(form$1);
2428		const method = form$1.method.toLowerCase();
2429		const useReplace = hasModifier(modifiers, "replace");
2430		const useTransition = !hasModifier(modifiers, "notransition");
2431		if (method === "get") {
2432			const params = new URLSearchParams(formData);
2433			const url = `${targetUrl}?${params.toString()}`;
2434			await navigateTo(url, {
2435				replace: useReplace,
2436				transition: useTransition,
2437				transitionName: "page-transition"
2438			});
2439		} else console.warn("data-volt-navigate: POST/PUT/PATCH forms should use data-volt-post/put/patch");
2440	};
2441	form$1.addEventListener("submit", submitHandler);
2442	ctx.cleanups.push(() => form$1.removeEventListener("submit", submitHandler));
2443}
2444async function navigateTo(url, options$1 = {}) {
2445	const { replace = false, transition = true, transitionName = "page-transition" } = options$1;
2446	const currentKey = getLocationKey();
2447	scrollPositions.set(currentKey, {
2448		x: window.scrollX,
2449		y: window.scrollY
2450	});
2451	const activeElement = document.activeElement;
2452	const focusSelector = activeElement && activeElement !== document.body ? getElementSelector(activeElement) : void 0;
2453	if (focusSelector) focusSelectors.set(currentKey, focusSelector);
2454	const state = {
2455		scrollPosition: {
2456			x: window.scrollX,
2457			y: window.scrollY
2458		},
2459		focusSelector,
2460		timestamp: Date.now()
2461	};
2462	const performNavigation = async () => {
2463		if (currentRouterMode === "hash") {
2464			const hash = url.startsWith("#") ? url : `#${url}`;
2465			if (replace) globalThis.history.replaceState(state, "", hash);
2466			else globalThis.location.hash = hash;
2467		} else if (replace) globalThis.history.replaceState(state, "", url);
2468		else globalThis.history.pushState(state, "", url);
2469		globalThis.dispatchEvent(new CustomEvent("volt:navigate", {
2470			detail: {
2471				url,
2472				replace
2473			},
2474			bubbles: true,
2475			cancelable: false
2476		}));
2477		window.scrollTo(0, 0);
2478		resetFocusAfterNavigation();
2479	};
2480	if (transition && typeof transitionName === "string") await startViewTransition(performNavigation, { name: transitionName });
2481	else await performNavigation();
2482}
2483function getElementSelector(element) {
2484	if (element.id) return `#${element.id}`;
2485	if (element.hasAttribute("name")) {
2486		const name = element.getAttribute("name");
2487		return `${element.tagName.toLowerCase()}[name="${name}"]`;
2488	}
2489	for (const attr of element.attributes) if (attr.name.startsWith("data-volt-")) return `[${attr.name}="${attr.value}"]`;
2490	if (element.hasAttribute("aria-label")) return `[aria-label="${element.getAttribute("aria-label")}"]`;
2491	const parent = element.parentElement;
2492	if (!parent) return void 0;
2493	const index = [...parent.children].indexOf(element);
2494	return `${element.tagName.toLowerCase()}:nth-child(${index + 1})`;
2495}
2496function resetFocusAfterNavigation() {
2497	const main = document.querySelector("main, [role='main'], #main-content");
2498	if (main instanceof HTMLElement && main.tabIndex < 0) main.tabIndex = -1;
2499	if (main instanceof HTMLElement) {
2500		main.focus({ preventScroll: true });
2501		return;
2502	}
2503	const firstHeading = document.querySelector("h1");
2504	if (firstHeading instanceof HTMLElement) {
2505		if (firstHeading.tabIndex < 0) firstHeading.tabIndex = -1;
2506		firstHeading.focus({ preventScroll: true });
2507		return;
2508	}
2509	document.body.focus({ preventScroll: true });
2510}
2511function restoreFocus(selector) {
2512	try {
2513		const element = document.querySelector(selector);
2514		if (element instanceof HTMLElement) {
2515			element.focus({ preventScroll: true });
2516			return true;
2517		}
2518	} catch (error) {
2519		console.warn(`Could not restore focus to selector: ${selector}`, error);
2520	}
2521	return false;
2522}
2523function isExternalLink(url) {
2524	try {
2525		return new URL(url, globalThis.location.origin).origin !== globalThis.location.origin;
2526	} catch {
2527		return false;
2528	}
2529}
2530function setupPrefetch(element, url, opts = {}) {
2531	const { viewport = false } = opts;
2532	let prefetched = false;
2533	const prefetch = () => {
2534		if (prefetched) return;
2535		prefetched = true;
2536		fetch(url, {
2537			method: "GET",
2538			priority: "low",
2539			credentials: "same-origin"
2540		}).catch(() => {
2541			const link = document.createElement("link");
2542			link.rel = "prefetch";
2543			link.href = url;
2544			document.head.append(link);
2545		});
2546	};
2547	if (viewport) {
2548		const observer = new IntersectionObserver((entries) => {
2549			for (const entry of entries) if (entry.isIntersecting) {
2550				prefetch();
2551				observer.disconnect();
2552			}
2553		}, { rootMargin: "50px" });
2554		observer.observe(element);
2555	} else {
2556		element.addEventListener("mouseenter", prefetch, {
2557			once: true,
2558			passive: true
2559		});
2560		element.addEventListener("focus", prefetch, {
2561			once: true,
2562			passive: true
2563		});
2564	}
2565}
2566function initNavigationListener() {
2567	const handleNavigation = (state = null) => {
2568		const key = getLocationKey();
2569		const savedPosition = scrollPositions.get(key);
2570		const savedFocus = focusSelectors.get(key);
2571		if (savedPosition) window.scrollTo(savedPosition.x, savedPosition.y);
2572		else if (state?.scrollPosition) window.scrollTo(state.scrollPosition.x, state.scrollPosition.y);
2573		if (savedFocus) restoreFocus(savedFocus);
2574		else if (state?.focusSelector) restoreFocus(state.focusSelector);
2575		else resetFocusAfterNavigation();
2576		globalThis.dispatchEvent(new CustomEvent("volt:popstate", {
2577			detail: { state },
2578			bubbles: true,
2579			cancelable: false
2580		}));
2581	};
2582	const handlePopState = (event) => {
2583		const state = event.state;
2584		handleNavigation(state);
2585	};
2586	const handleHashChange = () => {
2587		if (currentRouterMode === "hash") handleNavigation();
2588	};
2589	globalThis.addEventListener("popstate", handlePopState);
2590	globalThis.addEventListener("hashchange", handleHashChange);
2591	return () => {
2592		globalThis.removeEventListener("popstate", handlePopState);
2593		globalThis.removeEventListener("hashchange", handleHashChange);
2594	};
2595}
2596registerDirective("navigate", bindNavigate);
2597var storageAdapterRegistry = /* @__PURE__ */ new Map();
2598var localStorageAdapter = {
2599	get(key) {
2600		const value = localStorage.getItem(key);
2601		if (isNil(value)) return void 0;
2602		try {
2603			return JSON.parse(value);
2604		} catch {
2605			return value;
2606		}
2607	},
2608	set(key, value) {
2609		localStorage.setItem(key, JSON.stringify(value));
2610	},
2611	remove(key) {
2612		localStorage.removeItem(key);
2613	}
2614};
2615var sessionStorageAdapter = {
2616	get(key) {
2617		const value = sessionStorage.getItem(key);
2618		if (isNil(value)) return void 0;
2619		try {
2620			return JSON.parse(value);
2621		} catch {
2622			return value;
2623		}
2624	},
2625	set(key, value) {
2626		sessionStorage.setItem(key, JSON.stringify(value));
2627	},
2628	remove(key) {
2629		sessionStorage.removeItem(key);
2630	}
2631};
2632var idbAdapter = {
2633	async get(key) {
2634		const db = await openDB();
2635		return new Promise((resolve, reject) => {
2636			const request$1 = db.transaction(["voltStore"], "readonly").objectStore("voltStore").get(key);
2637			request$1.onsuccess = () => {
2638				resolve(request$1.result?.value);
2639			};
2640			request$1.onerror = () => {
2641				reject(request$1.error);
2642			};
2643		});
2644	},
2645	async set(key, value) {
2646		const db = await openDB();
2647		return new Promise((resolve, reject) => {
2648			const request$1 = db.transaction(["voltStore"], "readwrite").objectStore("voltStore").put({
2649				key,
2650				value
2651			});
2652			request$1.onsuccess = () => {
2653				resolve();
2654			};
2655			request$1.onerror = () => {
2656				reject(request$1.error);
2657			};
2658		});
2659	},
2660	async remove(key) {
2661		const db = await openDB();
2662		return new Promise((resolve, reject) => {
2663			const request$1 = db.transaction(["voltStore"], "readwrite").objectStore("voltStore").delete(key);
2664			request$1.onsuccess = () => {
2665				resolve();
2666			};
2667			request$1.onerror = () => {
2668				reject(request$1.error);
2669			};
2670		});
2671	}
2672};
2673var dbPromise;
2674function openDB() {
2675	if (dbPromise) return dbPromise;
2676	dbPromise = new Promise((resolve, reject) => {
2677		const request$1 = indexedDB.open("voltDB", 1);
2678		request$1.onupgradeneeded = () => {
2679			const db = request$1.result;
2680			if (!db.objectStoreNames.contains("voltStore")) db.createObjectStore("voltStore", { keyPath: "key" });
2681		};
2682		request$1.onsuccess = () => {
2683			resolve(request$1.result);
2684		};
2685		request$1.onerror = () => {
2686			reject(request$1.error);
2687		};
2688	});
2689	return dbPromise;
2690}
2691function getStorageAdapter(type) {
2692	switch (type) {
2693		case "local": return localStorageAdapter;
2694		case "session": return sessionStorageAdapter;
2695		case "indexeddb": return idbAdapter;
2696		default: return storageAdapterRegistry.get(type);
2697	}
2698}
2699function resolveCanonicalPath$1(scope, rawPath) {
2700	const trimmed = rawPath.trim();
2701	if (!trimmed) return trimmed;
2702	const parts = trimmed.split(".");
2703	const resolved = [];
2704	let current = scope;
2705	for (const part of parts) {
2706		if (isNil(current) || typeof current !== "object") {
2707			resolved.push(part);
2708			current = void 0;
2709			continue;
2710		}
2711		const record = current;
2712		if (Object.hasOwn(record, part)) {
2713			resolved.push(part);
2714			current = record[part];
2715			continue;
2716		}
2717		const camelCandidate = kebabToCamel(part);
2718		if (Object.hasOwn(record, camelCandidate)) {
2719			resolved.push(camelCandidate);
2720			current = record[camelCandidate];
2721			continue;
2722		}
2723		const lower = part.toLowerCase();
2724		const matchedKey = Object.keys(record).find((key) => key.toLowerCase() === lower);
2725		if (matchedKey) {
2726			resolved.push(matchedKey);
2727			current = record[matchedKey];
2728			continue;
2729		}
2730		resolved.push(part);
2731		current = void 0;
2732	}
2733	return resolved.join(".");
2734}
2735function resolveSignal$1(ctx, rawPath) {
2736	const trimmed = rawPath.trim();
2737	if (!trimmed) return;
2738	const canonicalPath = resolveCanonicalPath$1(ctx.scope, trimmed);
2739	const candidatePaths = new Set([canonicalPath, trimmed]);
2740	for (const candidate of candidatePaths) {
2741		const found = ctx.findSignal(candidate);
2742		if (found) return {
2743			path: candidate,
2744			signal: found
2745		};
2746	}
2747}
2748function normalizeStorageType(type) {
2749	const original = type.trim();
2750	switch (original.toLowerCase().replaceAll(/[\s_-]/g, "")) {
2751		case "local":
2752		case "localstorage": return {
2753			key: "local",
2754			original
2755		};
2756		case "session":
2757		case "sessionstorage": return {
2758			key: "session",
2759			original
2760		};
2761		case "indexeddb":
2762		case "indexed-db": return {
2763			key: "indexeddb",
2764			original
2765		};
2766		default: return {
2767			key: original,
2768			original
2769		};
2770	}
2771}
2772function persistPlugin(ctx, value) {
2773	const parts = value.split(":");
2774	if (parts.length !== 2) {
2775		console.error(`Invalid persist binding: "${value}". Expected format: "signalPath:storageType"`);
2776		return;
2777	}
2778	const [signalPath, storageType] = parts;
2779	const resolvedSignal = resolveSignal$1(ctx, signalPath);
2780	if (!resolvedSignal) {
2781		console.error(`Signal "${signalPath.trim()}" not found in scope for persist binding`);
2782		return;
2783	}
2784	const { key: adapterKey, original } = normalizeStorageType(storageType);
2785	const adapter = getStorageAdapter(adapterKey) ?? (adapterKey === original ? void 0 : getStorageAdapter(original));
2786	if (!adapter) {
2787		console.error(`Unknown storage type: "${storageType.trim()}"`);
2788		return;
2789	}
2790	const storageKey = `volt:${resolvedSignal.path}`;
2791	try {
2792		const result = adapter.get(storageKey);
2793		if (result instanceof Promise) result.then((storedValue) => {
2794			if (storedValue !== void 0) resolvedSignal.signal.set(storedValue);
2795		}).catch((error) => {
2796			console.error(`Failed to load persisted value for "${signalPath.trim()}":`, error);
2797		});
2798		else if (result !== void 0) resolvedSignal.signal.set(result);
2799	} catch (error) {
2800		console.error(`Failed to load persisted value for "${signalPath.trim()}":`, error);
2801	}
2802	const unsubscribe = resolvedSignal.signal.subscribe((newValue) => {
2803		try {
2804			const result = adapter.set(storageKey, newValue);
2805			if (result instanceof Promise) result.catch((error) => {
2806				console.error(`Failed to persist value for "${signalPath.trim()}":`, error);
2807			});
2808		} catch (error) {
2809			console.error(`Failed to persist value for "${signalPath.trim()}":`, error);
2810		}
2811	});
2812	ctx.addCleanup(unsubscribe);
2813}
2814function scrollPlugin(ctx, value) {
2815	if (value === "history") {
2816		handleScrollHistory(ctx);
2817		return;
2818	}
2819	const parts = value.split(":");
2820	if (parts.length !== 2) {
2821		console.error(`Invalid scroll binding: "${value}". Expected format: "mode:signalPath" or "history"`);
2822		return;
2823	}
2824	const [mode, signalPath] = parts.map((p$1) => p$1.trim());
2825	switch (mode) {
2826		case "restore":
2827			handleScrollRestore(ctx, signalPath);
2828			break;
2829		case "scrollTo":
2830			handleScrollTo(ctx, signalPath);
2831			break;
2832		case "spy":
2833			handleScrollSpy(ctx, signalPath);
2834			break;
2835		case "smooth":
2836			handleSmoothScroll(ctx, signalPath);
2837			break;
2838		default: console.error(`Unknown scroll mode: "${mode}"`);
2839	}
2840}
2841function handleScrollRestore(ctx, signalPath) {
2842	const signal$1 = ctx.findSignal(signalPath);
2843	if (!signal$1) {
2844		console.error(`Signal "${signalPath}" not found for scroll restore`);
2845		return;
2846	}
2847	const element = ctx.element;
2848	const savedPosition = signal$1.get();
2849	if (typeof savedPosition === "number") element.scrollTop = savedPosition;
2850	const savePosition = () => {
2851		signal$1.set(element.scrollTop);
2852	};
2853	element.addEventListener("scroll", savePosition, { passive: true });
2854	ctx.addCleanup(() => {
2855		element.removeEventListener("scroll", savePosition);
2856	});
2857}
2858function handleScrollTo(ctx, signalPath) {
2859	const signal$1 = ctx.findSignal(signalPath);
2860	if (!signal$1) {
2861		console.error(`Signal "${signalPath}" not found for scrollTo`);
2862		return;
2863	}
2864	const element = ctx.element;
2865	const elementId = element.id;
2866	const checkAndScroll = (target) => {
2867		if (target === elementId || target === `#${elementId}`) element.scrollIntoView({
2868			behavior: "smooth",
2869			block: "start"
2870		});
2871	};
2872	checkAndScroll(signal$1.get());
2873	const unsubscribe = signal$1.subscribe(checkAndScroll);
2874	ctx.addCleanup(unsubscribe);
2875}
2876function handleScrollSpy(ctx, signalPath) {
2877	const signal$1 = ctx.findSignal(signalPath);
2878	if (!signal$1) {
2879		console.error(`Signal "${signalPath}" not found for scroll spy`);
2880		return;
2881	}
2882	const element = ctx.element;
2883	const observer = new IntersectionObserver((entries) => {
2884		for (const entry of entries) if (entry.target === element) signal$1.set(entry.isIntersecting);
2885	}, { threshold: .1 });
2886	observer.observe(element);
2887	ctx.addCleanup(() => {
2888		observer.disconnect();
2889	});
2890}
2891function handleSmoothScroll(ctx, signalPath) {
2892	const signal$1 = ctx.findSignal(signalPath);
2893	if (!signal$1) {
2894		console.error(`Signal "${signalPath}" not found for smooth scroll`);
2895		return;
2896	}
2897	const element = ctx.element;
2898	const applyBehavior = (value) => {
2899		if (value === true || value === "smooth") element.style.scrollBehavior = "smooth";
2900		else if (value === false || value === "auto") element.style.scrollBehavior = "auto";
2901	};
2902	applyBehavior(signal$1.get());
2903	const unsubscribe = signal$1.subscribe(applyBehavior);
2904	ctx.addCleanup(() => {
2905		unsubscribe();
2906		element.style.scrollBehavior = "";
2907	});
2908}
2909function handleScrollHistory(ctx) {
2910	const element = ctx.element;
2911	const scrollPositions$1 = /* @__PURE__ */ new Map();
2912	const handleNavigate = () => {
2913		const key = `${globalThis.location.pathname}${globalThis.location.search}`;
2914		scrollPositions$1.set(key, element.scrollTop);
2915	};
2916	const handlePopstate = () => {
2917		const key = `${globalThis.location.pathname}${globalThis.location.search}`;
2918		const savedPosition = scrollPositions$1.get(key);
2919		if (savedPosition !== void 0) requestAnimationFrame(() => {
2920			element.scrollTop = savedPosition;
2921		});
2922	};
2923	globalThis.addEventListener("volt:navigate", handleNavigate);
2924	globalThis.addEventListener("volt:popstate", handlePopstate);
2925	ctx.addCleanup(() => {
2926		globalThis.removeEventListener("volt:navigate", handleNavigate);
2927		globalThis.removeEventListener("volt:popstate", handlePopstate);
2928	});
2929}
2930var animationRegistry = /* @__PURE__ */ new Map();
2931var keyframeRegistry = /* @__PURE__ */ new Map();
2932var keyframeSheet;
2933var keyframeCounter = 0;
2934var builtinAnimations = {
2935	bounce: {
2936		keyframes: [
2937			{
2938				offset: 0,
2939				transform: "translateY(0)"
2940			},
2941			{
2942				offset: .25,
2943				transform: "translateY(-20px)"
2944			},
2945			{
2946				offset: .5,
2947				transform: "translateY(0)"
2948			},
2949			{
2950				offset: .75,
2951				transform: "translateY(-10px)"
2952			},
2953			{
2954				offset: 1,
2955				transform: "translateY(0)"
2956			}
2957		],
2958		duration: 100,
2959		iterations: 1,
2960		timing: "ease"
2961	},
2962	shake: {
2963		keyframes: [
2964			{
2965				offset: 0,
2966				transform: "translateX(0)"
2967			},
2968			{
2969				offset: .1,
2970				transform: "translateX(-10px)"
2971			},
2972			{
2973				offset: .2,
2974				transform: "translateX(10px)"
2975			},
2976			{
2977				offset: .3,
2978				transform: "translateX(-10px)"
2979			},
2980			{
2981				offset: .4,
2982				transform: "translateX(10px)"
2983			},
2984			{
2985				offset: .5,
2986				transform: "translateX(-10px)"
2987			},
2988			{
2989				offset: .6,
2990				transform: "translateX(10px)"
2991			},
2992			{
2993				offset: .7,
2994				transform: "translateX(-10px)"
2995			},
2996			{
2997				offset: .8,
2998				transform: "translateX(10px)"
2999			},
3000			{
3001				offset: .9,
3002				transform: "translateX(-10px)"
3003			},
3004			{
3005				offset: 1,
3006				transform: "translateX(0)"
3007			}
3008		],
3009		duration: 500,
3010		iterations: 1,
3011		timing: "ease"
3012	},
3013	pulse: {
3014		keyframes: [
3015			{
3016				offset: 0,
3017				transform: "scale(1)",
3018				opacity: "1"
3019			},
3020			{
3021				offset: .5,
3022				transform: "scale(1.05)",
3023				opacity: "0.9"
3024			},
3025			{
3026				offset: 1,
3027				transform: "scale(1)",
3028				opacity: "1"
3029			}
3030		],
3031		duration: 1e3,
3032		iterations: Number.POSITIVE_INFINITY,
3033		timing: "ease-in-out"
3034	},
3035	spin: {
3036		keyframes: [{
3037			offset: 0,
3038			transform: "rotate(0deg)"
3039		}, {
3040			offset: 1,
3041			transform: "rotate(360deg)"
3042		}],
3043		duration: 1e3,
3044		iterations: Number.POSITIVE_INFINITY,
3045		timing: "linear"
3046	},
3047	flash: {
3048		keyframes: [
3049			{
3050				offset: 0,
3051				opacity: "1"
3052			},
3053			{
3054				offset: .25,
3055				opacity: "0"
3056			},
3057			{
3058				offset: .5,
3059				opacity: "1"
3060			},
3061			{
3062				offset: .75,
3063				opacity: "0"
3064			},
3065			{
3066				offset: 1,
3067				opacity: "1"
3068			}
3069		],
3070		duration: 1e3,
3071		iterations: 1,
3072		timing: "linear"
3073	}
3074};
3075function initBuiltinAnimations() {
3076	for (const [name, preset] of Object.entries(builtinAnimations)) animationRegistry.set(name, preset);
3077}
3078initBuiltinAnimations();
3079function getAnimation(name) {
3080	return animationRegistry.get(name);
3081}
3082function parseShiftValue(value) {
3083	const colonIndex = value.indexOf(":");
3084	if (colonIndex !== -1) {
3085		const signalPath = value.slice(0, colonIndex).trim();
3086		const animationPart = value.slice(colonIndex + 1).trim();
3087		const parsed = parseAnimationValue(animationPart);
3088		if (!parsed) return;
3089		return {
3090			...parsed,
3091			signalPath
3092		};
3093	}
3094	return parseAnimationValue(value);
3095}
3096function parseAnimationValue(value) {
3097	const parts = value.split(".");
3098	const animationName = parts[0]?.trim();
3099	if (!animationName) return;
3100	const result = { animationName };
3101	if (parts.length > 1) {
3102		const duration = Number.parseInt(parts[1], 10);
3103		if (!Number.isNaN(duration)) result.duration = duration;
3104	}
3105	if (parts.length > 2) {
3106		const iterations = Number.parseInt(parts[2], 10);
3107		if (!Number.isNaN(iterations)) result.iterations = iterations;
3108	}
3109	return result;
3110}
3111function stopAnimation(el$1) {
3112	el$1.style.animation = "";
3113	el$1.style.animationName = "";
3114	el$1.style.animationDuration = "";
3115	el$1.style.animationTimingFunction = "";
3116	el$1.style.animationIterationCount = "";
3117	el$1.style.animationFillMode = "";
3118	restoreOriginalDisplay(el$1);
3119}
3120function applyAnimation(el$1, preset, duration, iterations) {
3121	if (prefersReducedMotion()) return;
3122	const effectiveDuration = duration ?? preset.duration;
3123	const effectiveIterations = iterations ?? preset.iterations;
3124	const animationName = getOrCreateKeyframes(preset);
3125	if (!animationName) return;
3126	ensureInlineBlockForTransforms(el$1, effectiveIterations === Number.POSITIVE_INFINITY);
3127	resetCssAnimation(el$1);
3128	el$1.style.animationName = animationName;
3129	el$1.style.animationDuration = `${effectiveDuration}ms`;
3130	el$1.style.animationTimingFunction = preset.timing;
3131	el$1.style.animationIterationCount = effectiveIterations === Number.POSITIVE_INFINITY ? "infinite" : String(effectiveIterations);
3132	el$1.style.animationFillMode = "forwards";
3133	const runs = Number.parseInt(el$1.dataset.voltShiftRuns ?? "0", 10) + 1;
3134	el$1.dataset.voltShiftRuns = String(runs);
3135	if (effectiveIterations !== Number.POSITIVE_INFINITY) {
3136		const totalDuration = effectiveDuration * effectiveIterations;
3137		setTimeout(() => {
3138			if (el$1.style.animationName === animationName) stopAnimation(el$1);
3139		}, totalDuration);
3140	}
3141}
3142function resetCssAnimation(el$1) {
3143	if (!el$1.style.animationName) return;
3144	el$1.style.animation = "none";
3145	el$1.offsetWidth;
3146	el$1.style.animation = "";
3147	el$1.style.animationName = "";
3148}
3149function ensureKeyframeSheet() {
3150	if (keyframeSheet) return keyframeSheet;
3151	if (typeof document === "undefined" || !document.head) return;
3152	const styleEl = document.createElement("style");
3153	styleEl.dataset.voltShift = "true";
3154	document.head.append(styleEl);
3155	keyframeSheet = styleEl.sheet ?? void 0;
3156	return keyframeSheet;
3157}
3158function toCssProperty(property) {
3159	return property.replaceAll(/[A-Z]/g, (match) => `-${match.toLowerCase()}`);
3160}
3161function getOrCreateKeyframes(preset) {
3162	const key = JSON.stringify(preset.keyframes) + preset.timing;
3163	if (keyframeRegistry.has(key)) return keyframeRegistry.get(key);
3164	const sheet = ensureKeyframeSheet();
3165	if (!sheet) return;
3166	const animationName = `volt-shift-${keyframeCounter += 1}`;
3167	keyframeRegistry.set(key, animationName);
3168	const frames = preset.keyframes.map((frame, index) => {
3169		const offset = frame.offset ?? (preset.keyframes.length > 1 ? index / (preset.keyframes.length - 1) : 0);
3170		const percent = Math.round(offset * 1e4) / 100;
3171		const declarations = Object.entries(frame).filter(([prop]) => prop !== "offset").map(([prop, value]) => `${toCssProperty(prop)}: ${value};`).join(" ");
3172		return `${percent}% { ${declarations} }`;
3173	}).join(" ");
3174	sheet.insertRule(`@keyframes ${animationName} { ${frames} }`, sheet.cssRules.length);
3175	return animationName;
3176}
3177function ensureInlineBlockForTransforms(el$1, isInf) {
3178	if (el$1.dataset.voltShiftDisplayManaged) return;
3179	if (typeof getComputedStyle !== "function") return;
3180	if (!el$1.isConnected) return;
3181	el$1.offsetHeight;
3182	if (getComputedStyle(el$1).display !== "inline") return;
3183	el$1.dataset.voltShiftDisplayManaged = isInf ? "infinite" : "managed";
3184	el$1.dataset.voltShiftOriginalDisplay = el$1.style.display ?? "";
3185	if (!el$1.dataset.voltShiftOriginalTransformOrigin) el$1.dataset.voltShiftOriginalTransformOrigin = el$1.style.transformOrigin ?? "";
3186	el$1.style.display = "inline-block";
3187	if (!el$1.style.transformOrigin) el$1.style.transformOrigin = "center center";
3188}
3189function restoreOriginalDisplay(element) {
3190	const state = element.dataset.voltShiftDisplayManaged;
3191	if (!state || state === "infinite") return;
3192	const original = element.dataset.voltShiftOriginalDisplay ?? "";
3193	element.style.display = original;
3194	const originalOrigin = element.dataset.voltShiftOriginalTransformOrigin ?? "";
3195	element.style.transformOrigin = originalOrigin;
3196	delete element.dataset.voltShiftDisplayManaged;
3197	delete element.dataset.voltShiftOriginalDisplay;
3198	delete element.dataset.voltShiftOriginalTransformOrigin;
3199}
3200function shiftPlugin(ctx, value) {
3201	const el$1 = ctx.element;
3202	const parsed = parseShiftValue(value);
3203	if (!parsed) {
3204		console.error(`[Volt] Invalid shift value: "${value}"`);
3205		return;
3206	}
3207	const preset = getAnimation(parsed.animationName);
3208	if (!preset) {
3209		console.error(`[Volt] Unknown animation preset: "${parsed.animationName}"`);
3210		return;
3211	}
3212	if (parsed.signalPath) {
3213		const signal$1 = ctx.findSignal(parsed.signalPath);
3214		if (!signal$1) {
3215			console.error(`[Volt] Signal "${parsed.signalPath}" not found for shift binding`);
3216			return;
3217		}
3218		const isInfinite = (parsed.iterations ?? preset.iterations) === Number.POSITIVE_INFINITY;
3219		let previousValue = signal$1.get();
3220		const unsubscribe = signal$1.subscribe((value$1) => {
3221			if (value$1 !== previousValue) {
3222				if (value$1) applyAnimation(el$1, preset, parsed.duration, parsed.iterations);
3223				else if (isInfinite && el$1.style.animationName) stopAnimation(el$1);
3224			}
3225			previousValue = value$1;
3226		});
3227		ctx.addCleanup(unsubscribe);
3228		if (signal$1.get()) ctx.lifecycle.onMount(() => {
3229			requestAnimationFrame(() => {
3230				applyAnimation(el$1, preset, parsed.duration, parsed.iterations);
3231			});
3232		});
3233	} else ctx.lifecycle.onMount(() => {
3234		requestAnimationFrame(() => {
3235			applyAnimation(el$1, preset, parsed.duration, parsed.iterations);
3236		});
3237	});
3238}
3239function normalizeMode(mode) {
3240	switch (mode.trim().toLowerCase().replaceAll(/[\s_-]/g, "")) {
3241		case "read": return "read";
3242		case "sync":
3243		case "bidirectional": return "sync";
3244		case "query":
3245		case "search": return "sync";
3246		case "hash": return "hash";
3247		case "history":
3248		case "route": return "history";
3249		default: return;
3250	}
3251}
3252function resolveCanonicalPath(scope, rawPath) {
3253	const trimmed = rawPath.trim();
3254	if (!trimmed) return trimmed;
3255	const parts = trimmed.split(".");
3256	const resolved = [];
3257	let current = scope;
3258	for (const part of parts) {
3259		if (isNil(current) || typeof current !== "object") {
3260			resolved.push(part);
3261			current = void 0;
3262			continue;
3263		}
3264		const record = current;
3265		if (Object.hasOwn(record, part)) {
3266			resolved.push(part);
3267			current = record[part];
3268			continue;
3269		}
3270		const camelCandidate = kebabToCamel(part);
3271		if (Object.hasOwn(record, camelCandidate)) {
3272			resolved.push(camelCandidate);
3273			current = record[camelCandidate];
3274			continue;
3275		}
3276		const lower = part.toLowerCase();
3277		const matchedKey = Object.keys(record).find((key) => key.toLowerCase() === lower);
3278		if (matchedKey) {
3279			resolved.push(matchedKey);
3280			current = record[matchedKey];
3281			continue;
3282		}
3283		resolved.push(part);
3284		current = void 0;
3285	}
3286	return resolved.join(".");
3287}
3288function resolveSignal(ctx, rawPath) {
3289	const trimmed = rawPath.trim();
3290	if (!trimmed) return;
3291	const canonicalPath = resolveCanonicalPath(ctx.scope, trimmed);
3292	const candidatePaths = new Set([canonicalPath, trimmed]);
3293	for (const candidate of candidatePaths) {
3294		const found = ctx.findSignal(candidate);
3295		if (found) return {
3296			path: candidate,
3297			signal: found
3298		};
3299	}
3300}
3301function urlPlugin(ctx, value) {
3302	const parts = value.split(":").map((part) => part.trim()).filter((part) => part.length > 0);
3303	if (parts.length < 2) {
3304		console.error(`Invalid url binding: "${value}". Expected format: "mode:signalPath[:basePath]" or "signalPath:mode[:basePath]"`);
3305		return;
3306	}
3307	const firstMode = normalizeMode(parts[0]);
3308	const secondMode = normalizeMode(parts[1] ?? "");
3309	let mode;
3310	let signalPath;
3311	let basePath;
3312	if (firstMode) {
3313		mode = firstMode;
3314		signalPath = parts[1] ?? "";
3315		basePath = parts.slice(2).join(":") || void 0;
3316	} else if (secondMode) {
3317		mode = secondMode;
3318		signalPath = parts[0];
3319		basePath = parts.slice(2).join(":") || void 0;
3320	} else {
3321		console.error(`Unknown url mode in binding "${value}"`);
3322		return;
3323	}
3324	if (!signalPath) {
3325		console.error(`Signal path missing for url binding "${value}"`);
3326		return;
3327	}
3328	const resolvedSignal = resolveSignal(ctx, signalPath);
3329	if (!resolvedSignal) {
3330		console.error(`Signal "${signalPath}" not found for url binding`);
3331		return;
3332	}
3333	switch (mode) {
3334		case "read":
3335			handleReadURL(resolvedSignal);
3336			break;
3337		case "sync":
3338			handleSyncURL(ctx, resolvedSignal);
3339			break;
3340		case "hash":
3341			handleHashRouting(ctx, resolvedSignal);
3342			break;
3343		case "history":
3344			handleHistoryRouting(ctx, resolvedSignal, basePath);
3345			break;
3346	}
3347}
3348function handleReadURL(resolved) {
3349	const paramValue = new URLSearchParams(globalThis.location.search).get(resolved.path);
3350	if (paramValue !== null) resolved.signal.set(deserializeValue(paramValue));
3351}
3352function handleSyncURL(ctx, resolved) {
3353	const paramValue = new URLSearchParams(globalThis.location.search).get(resolved.path);
3354	if (paramValue !== null) resolved.signal.set(deserializeValue(paramValue));
3355	let isUpdatingFromUrl = false;
3356	let updateTimeout;
3357	const updateUrl = (value) => {
3358		if (isUpdatingFromUrl) return;
3359		if (updateTimeout) clearTimeout(updateTimeout);
3360		updateTimeout = setTimeout(() => {
3361			const params = new URLSearchParams(globalThis.location.search);
3362			const serialized = serializeValue(value);
3363			if (isNil(serialized) || serialized === "") params.delete(resolved.path);
3364			else params.set(resolved.path, serialized);
3365			const newSearch = params.toString();
3366			const newUrl = newSearch ? `?${newSearch}` : globalThis.location.pathname;
3367			globalThis.history.pushState({}, "", newUrl);
3368		}, 100);
3369	};
3370	const handlePopState = () => {
3371		isUpdatingFromUrl = true;
3372		const paramValue$1 = new URLSearchParams(globalThis.location.search).get(resolved.path);
3373		if (isNil(paramValue$1)) resolved.signal.set("");
3374		else resolved.signal.set(deserializeValue(paramValue$1));
3375		isUpdatingFromUrl = false;
3376	};
3377	const unsubscribe = resolved.signal.subscribe(updateUrl);
3378	globalThis.addEventListener("popstate", handlePopState);
3379	ctx.addCleanup(() => {
3380		unsubscribe();
3381		globalThis.removeEventListener("popstate", handlePopState);
3382		if (updateTimeout) clearTimeout(updateTimeout);
3383	});
3384}
3385function handleHashRouting(ctx, resolved) {
3386	const currentHash = globalThis.location.hash.slice(1);
3387	if (currentHash) resolved.signal.set(currentHash);
3388	let isUpdatingFromHash = false;
3389	const updateHash = (value) => {
3390		if (isUpdatingFromHash) return;
3391		const hashValue = String(value ?? "");
3392		const newHash = hashValue ? `#${hashValue}` : "";
3393		if (globalThis.location.hash !== newHash) globalThis.history.pushState({}, "", newHash || globalThis.location.pathname);
3394	};
3395	const handleHashChange = () => {
3396		isUpdatingFromHash = true;
3397		const currentHash$1 = globalThis.location.hash.slice(1);
3398		resolved.signal.set(currentHash$1);
3399		isUpdatingFromHash = false;
3400	};
3401	const unsubscribe = resolved.signal.subscribe(updateHash);
3402	globalThis.addEventListener("hashchange", handleHashChange);
3403	ctx.addCleanup(() => {
3404		unsubscribe();
3405		globalThis.removeEventListener("hashchange", handleHashChange);
3406	});
3407}
3408function serializeValue(value) {
3409	if (isNil(value)) return "";
3410	if (typeof value === "string") return value;
3411	if (typeof value === "number" || typeof value === "boolean") return String(value);
3412	return JSON.stringify(value);
3413}
3414function deserializeValue(value) {
3415	if (value === "true") return true;
3416	if (value === "false") return false;
3417	if (value === "null") return null;
3418	if (value === "undefined") return void 0;
3419	const numberValue = Number(value);
3420	if (!Number.isNaN(numberValue) && value !== "") return numberValue;
3421	try {
3422		return JSON.parse(value);
3423	} catch {
3424		return value;
3425	}
3426}
3427function normalizeRoute(path) {
3428	if (!path) return "/";
3429	return path.startsWith("/") ? path : `/${path}`;
3430}
3431function handleHistoryRouting(ctx, resolved, basePath) {
3432	const base = basePath?.trim() ?? "";
3433	const extractRoute = () => {
3434		const fullPath = globalThis.location.pathname + globalThis.location.search;
3435		if (base && fullPath.startsWith(base)) {
3436			const stripped = fullPath.slice(base.length) || "/";
3437			return normalizeRoute(stripped);
3438		}
3439		return normalizeRoute(fullPath);
3440	};
3441	const currentRoute = extractRoute();
3442	resolved.signal.set(currentRoute);
3443	let isUpdatingFromHistory = false;
3444	const updateUrl = (value) => {
3445		if (isUpdatingFromHistory) return;
3446		const route = normalizeRoute(String(value ?? "/"));
3447		const fullPath = base ? `${base}${route}` : route;
3448		if (globalThis.location.pathname + globalThis.location.search !== fullPath) {
3449			globalThis.history.pushState({}, "", fullPath);
3450			globalThis.dispatchEvent(new CustomEvent("volt:navigate", {
3451				detail: {
3452					url: fullPath,
3453					route
3454				},
3455				bubbles: true,
3456				cancelable: false
3457			}));
3458		}
3459	};
3460	const handlePopState = () => {
3461		isUpdatingFromHistory = true;
3462		const route = extractRoute();
3463		resolved.signal.set(route);
3464		globalThis.dispatchEvent(new CustomEvent("volt:popstate", {
3465			detail: { route },
3466			bubbles: true,
3467			cancelable: false
3468		}));
3469		isUpdatingFromHistory = false;
3470	};
3471	const handleNavigate = () => {
3472		isUpdatingFromHistory = true;
3473		resolved.signal.set(extractRoute());
3474		isUpdatingFromHistory = false;
3475	};
3476	const unsubscribe = resolved.signal.subscribe(updateUrl);
3477	globalThis.addEventListener("popstate", handlePopState);
3478	globalThis.addEventListener("volt:navigate", handleNavigate);
3479	ctx.addCleanup(() => {
3480		unsubscribe();
3481		globalThis.removeEventListener("popstate", handlePopState);
3482		globalThis.removeEventListener("volt:navigate", handleNavigate);
3483	});
3484}
3485var indicatorStrategies = /* @__PURE__ */ new WeakMap();
3486async function request(conf) {
3487	const { method, url, headers = {}, body } = conf;
3488	try {
3489		const response = await fetch(url, {
3490			method,
3491			headers: { ...headers },
3492			body
3493		});
3494		const contentType = response.headers.get("content-type") || "";
3495		const isHTML = contentType.includes("text/html");
3496		const isJSON = contentType.includes("application/json");
3497		let html;
3498		let json;
3499		if (isHTML) html = await response.text();
3500		else if (isJSON) json = await response.json();
3501		else html = await response.text();
3502		return {
3503			status: response.status,
3504			statusText: response.statusText,
3505			headers: response.headers,
3506			html,
3507			json,
3508			ok: response.ok
3509		};
3510	} catch (error) {
3511		throw new Error(`HTTP request failed: ${error instanceof Error ? error.message : String(error)}`);
3512	}
3513}
3514function captureState(root) {
3515	const state = {
3516		focusPath: null,
3517		scrollPositions: /* @__PURE__ */ new Map(),
3518		inputValues: /* @__PURE__ */ new Map()
3519	};
3520	const activeEl = document.activeElement;
3521	if (activeEl && root.contains(activeEl)) state.focusPath = getElementPath(activeEl, root);
3522	const walker = document.createTreeWalker(root, NodeFilter.SHOW_ELEMENT);
3523	let currentNode = walker.currentNode;
3524	while (currentNode) {
3525		const el$1 = currentNode;
3526		const path = getElementPath(el$1, root);
3527		if (el$1.scrollTop > 0 || el$1.scrollLeft > 0) state.scrollPositions.set(path, {
3528			top: el$1.scrollTop,
3529			left: el$1.scrollLeft
3530		});
3531		if (el$1 instanceof HTMLInputElement) if (el$1.type === "checkbox" || el$1.type === "radio") state.inputValues.set(path, el$1.checked);
3532		else state.inputValues.set(path, el$1.value);
3533		else if (el$1 instanceof HTMLTextAreaElement || el$1 instanceof HTMLSelectElement) state.inputValues.set(path, el$1.value);
3534		currentNode = walker.nextNode();
3535	}
3536	return state;
3537}
3538function getElementPath(el$1, root) {
3539	const path = [];
3540	let current = el$1;
3541	while (current && current !== root) {
3542		const parent = current.parentElement;
3543		if (!parent) break;
3544		const index = [...parent.children].indexOf(current);
3545		if (index === -1) break;
3546		path.unshift(index);
3547		current = parent;
3548	}
3549	return path;
3550}
3551function getElementByPath(path, root) {
3552	let current = root;
3553	for (const index of path) {
3554		const children = [...current.children];
3555		if (index >= children.length) return null;
3556		current = children[index];
3557	}
3558	return current;
3559}
3560function restoreState(root, state) {
3561	if (state.focusPath) {
3562		const element = getElementByPath(state.focusPath, root);
3563		if (element instanceof HTMLElement) element.focus();
3564	}
3565	for (const [path, position] of state.scrollPositions) {
3566		const element = getElementByPath(path, root);
3567		if (element) {
3568			element.scrollTop = position.top;
3569			element.scrollLeft = position.left;
3570		}
3571	}
3572	for (const [path, value] of state.inputValues) {
3573		const element = getElementByPath(path, root);
3574		if (element instanceof HTMLInputElement) if (element.type === "checkbox" || element.type === "radio") element.checked = value;
3575		else element.value = value;
3576		else if (element instanceof HTMLTextAreaElement || element instanceof HTMLSelectElement) element.value = value;
3577	}
3578}
3579function swap(target, content, strategy = "innerHTML") {
3580	const state = strategy === "innerHTML" || strategy === "outerHTML" ? captureState(target) : null;
3581	switch (strategy) {
3582		case "innerHTML":
3583			target.innerHTML = content;
3584			if (state) restoreState(target, state);
3585			break;
3586		case "outerHTML": {
3587			const parent = target.parentElement;
3588			const nextSibling = target.nextElementSibling;
3589			target.outerHTML = content;
3590			if (state && parent) {
3591				const newElement = nextSibling ? nextSibling.previousElementSibling : parent.lastElementChild;
3592				if (newElement) restoreState(newElement, state);
3593			}
3594			break;
3595		}
3596		case "beforebegin":
3597			target.insertAdjacentHTML("beforebegin", content);
3598			break;
3599		case "afterbegin":
3600			target.insertAdjacentHTML("afterbegin", content);
3601			break;
3602		case "beforeend":
3603			target.insertAdjacentHTML("beforeend", content);
3604			break;
3605		case "afterend":
3606			target.insertAdjacentHTML("afterend", content);
3607			break;
3608		case "delete":
3609			target.remove();
3610			break;
3611		case "none": break;
3612		default: report(/* @__PURE__ */ new Error(`Unknown swap strategy: ${strategy}`), {
3613			source: "http",
3614			level: "warn",
3615			element: target
3616		});
3617	}
3618}
3619function serializeForm(form$1) {
3620	return new FormData(form$1);
3621}
3622function parseHttpConfig(el$1, scope) {
3623	const dataset = el$1.dataset;
3624	const trigger = dataset.voltTrigger || getDefaultTrigger(el$1);
3625	let target = el$1;
3626	if (dataset.voltTarget) {
3627		const trimmed = dataset.voltTarget.trim();
3628		if (trimmed.startsWith("\"") && trimmed.endsWith("\"") || trimmed.startsWith("'") && trimmed.endsWith("'")) target = trimmed.slice(1, -1);
3629		else {
3630			const targetValue = evaluate(dataset.voltTarget, scope);
3631			if (typeof targetValue === "string") target = targetValue;
3632			else if (targetValue instanceof Element) target = targetValue;
3633		}
3634	}
3635	const swap$1 = dataset.voltSwap || "innerHTML";
3636	let headers = {};
3637	if (dataset.voltHeaders) try {
3638		const headersValue = evaluate(dataset.voltHeaders, scope);
3639		if (typeof headersValue === "object" && headersValue !== null) headers = headersValue;
3640	} catch (error) {
3641		report(error, {
3642			source: "http",
3643			element: el$1,
3644			directive: "data-volt-headers",
3645			expression: dataset.voltHeaders
3646		});
3647	}
3648	let retry;
3649	if (dataset.voltRetry) {
3650		const maxAttempts = Number.parseInt(dataset.voltRetry, 10);
3651		const initialDelay = dataset.voltRetryDelay ? Number.parseInt(dataset.voltRetryDelay, 10) : 1e3;
3652		if (!Number.isNaN(maxAttempts) && maxAttempts > 0) retry = {
3653			maxAttempts,
3654			initialDelay
3655		};
3656	}
3657	const indicator = dataset.voltIndicator;
3658	return {
3659		trigger,
3660		target,
3661		swap: swap$1,
3662		headers,
3663		retry,
3664		indicator
3665	};
3666}
3667function getDefaultTrigger(el$1) {
3668	if (el$1 instanceof HTMLFormElement) return "submit";
3669	return "click";
3670}
3671function setLoadingState(el$1, indicator) {
3672	el$1.dataset.voltLoading = "true";
3673	if (indicator) showIndicator(indicator);
3674	el$1.dispatchEvent(new CustomEvent("volt:loading", {
3675		detail: { element: el$1 },
3676		bubbles: true,
3677		cancelable: false
3678	}));
3679}
3680function setErrorState(el$1, msg, indicator) {
3681	el$1.dataset.voltError = msg;
3682	if (indicator) hideIndicator(indicator);
3683	el$1.dispatchEvent(new CustomEvent("volt:error", {
3684		detail: {
3685			element: el$1,
3686			message: msg
3687		},
3688		bubbles: true,
3689		cancelable: false
3690	}));
3691}
3692function clearStates(el$1, indicator) {
3693	delete el$1.dataset.voltLoading;
3694	delete el$1.dataset.voltError;
3695	delete el$1.dataset.voltRetryAttempt;
3696	if (indicator) hideIndicator(indicator);
3697	el$1.dispatchEvent(new CustomEvent("volt:success", {
3698		detail: { element: el$1 },
3699		bubbles: true,
3700		cancelable: false
3701	}));
3702}
3703function detectIndicatorStrategy(el$1) {
3704	if (indicatorStrategies.has(el$1)) return indicatorStrategies.get(el$1);
3705	const htmlElement = el$1;
3706	const inlineDisplay = htmlElement.style.display;
3707	const computedDisplay = globalThis.getComputedStyle(htmlElement).display;
3708	if (inlineDisplay === "none" || computedDisplay === "none") {
3709		indicatorStrategies.set(el$1, "display");
3710		return "display";
3711	}
3712	if ([...el$1.classList].some((cls) => cls.toLowerCase().includes("hidden"))) {
3713		indicatorStrategies.set(el$1, "class");
3714		return "class";
3715	}
3716	indicatorStrategies.set(el$1, "class");
3717	return "class";
3718}
3719function showIndicatorElement(el$1) {
3720	const strategy = detectIndicatorStrategy(el$1);
3721	const htmlElement = el$1;
3722	if (strategy === "display") htmlElement.style.display = "";
3723	else {
3724		const hiddenClass = [...el$1.classList].find((cls) => cls.toLowerCase().includes("hidden")) || "hidden";
3725		el$1.classList.remove(hiddenClass);
3726	}
3727}
3728function hideIndicatorElement(el$1) {
3729	const strategy = detectIndicatorStrategy(el$1);
3730	const htmlElement = el$1;
3731	if (strategy === "display") htmlElement.style.display = "none";
3732	else {
3733		const hiddenClass = [...el$1.classList].find((cls) => cls.toLowerCase().includes("hidden")) || "hidden";
3734		el$1.classList.add(hiddenClass);
3735	}
3736}
3737function showIndicator(selector) {
3738	const indicators = document.querySelectorAll(selector);
3739	for (const indicator of indicators) showIndicatorElement(indicator);
3740}
3741function hideIndicator(selector) {
3742	const indicators = document.querySelectorAll(selector);
3743	for (const indicator of indicators) hideIndicatorElement(indicator);
3744}
3745function resolveTarget(targetConf, defaultEl) {
3746	if (targetConf instanceof Element) return targetConf;
3747	if (targetConf === "this" || targetConf === "") return defaultEl;
3748	const target = document.querySelector(targetConf);
3749	if (!target) {
3750		report(/* @__PURE__ */ new Error(`Target element not found: ${targetConf}`), {
3751			source: "http",
3752			level: "warn",
3753			element: defaultEl,
3754			directive: "data-volt-target"
3755		});
3756		return;
3757	}
3758	return target;
3759}
3760function classifyError(error) {
3761	if (error instanceof Error && error.message.includes("HTTP")) {
3762		const match = error.message.match(/HTTP (\d+):/);
3763		if (match) {
3764			const status = Number.parseInt(match[1], 10);
3765			if (status >= 500 && status < 600) return "server";
3766			if (status >= 400 && status < 500) return "client";
3767		}
3768	}
3769	if (error instanceof Error && (error.message.includes("fetch") || error.message.includes("network"))) return "network";
3770	return "other";
3771}
3772function shouldRetry(error) {
3773	const errorType = classifyError(error);
3774	return errorType === "network" || errorType === "server";
3775}
3776function calculateRetryDelay(error, attempt, initialDelay) {
3777	const errorType = classifyError(error);
3778	if (errorType === "network") return 0;
3779	if (errorType === "server") return initialDelay * 2 ** attempt;
3780	return 0;
3781}
3782async function performRequest(el$1, method, url, conf, body) {
3783	const target = resolveTarget(conf.target, el$1);
3784	if (!target) return;
3785	setLoadingState(target, conf.indicator);
3786	let lastError;
3787	const maxAttempts = conf.retry ? conf.retry.maxAttempts + 1 : 1;
3788	const initialDelay = conf.retry?.initialDelay ?? 1e3;
3789	for (let attempt = 0; attempt < maxAttempts; attempt++) try {
3790		if (attempt > 0) {
3791			target.dataset.voltRetryAttempt = String(attempt);
3792			target.dataset.voltLoading = "retrying";
3793			target.dispatchEvent(new CustomEvent("volt:retry", {
3794				detail: {
3795					element: target,
3796					attempt
3797				},
3798				bubbles: true,
3799				cancelable: false
3800			}));
3801		}
3802		const response = await request({
3803			method,
3804			url,
3805			headers: conf.headers,
3806			body
3807		});
3808		if (!response.ok) throw new Error(`HTTP ${response.status}: ${response.statusText}`);
3809		clearStates(target, conf.indicator);
3810		if (response.html !== void 0) swap(target, response.html, conf.swap);
3811		else if (response.json !== void 0) console.warn("JSON responses are not yet integrated 
3811with signal updates. HTML response expected.");
3812		return;
3813	} catch (error) {
3814		lastError = error;
3815		const isLastAttempt = attempt === maxAttempts - 1;
3816		const canRetry = conf.retry && shouldRetry(error);
3817		if (isLastAttempt || !canRetry) break;
3818		const delay = calculateRetryDelay(error, attempt, initialDelay);
3819		if (delay > 0) await sleep(delay);
3820	}
3821	const errorMessage = lastError instanceof Error ? lastError.message : String(lastError);
3822	setErrorState(target, errorMessage, conf.indicator);
3823	report(lastError, {
3824		source: "http",
3825		element: el$1,
3826		httpMethod: method,
3827		httpUrl: url
3828	});
3829}
3830function bindGet(ctx, url) {
3831	bindHttpMethod(ctx, "GET", url);
3832}
3833function bindPost(ctx, url) {
3834	bindHttpMethod(ctx, "POST", url);
3835}
3836function bindPut(ctx, url) {
3837	bindHttpMethod(ctx, "PUT", url);
3838}
3839function bindPatch(ctx, url) {
3840	bindHttpMethod(ctx, "PATCH", url);
3841}
3842function bindDelete(ctx, url) {
3843	bindHttpMethod(ctx, "DELETE", url);
3844}
3845function bindHttpMethod(ctx, method, url) {
3846	const config = parseHttpConfig(ctx.element, ctx.scope);
3847	const urlValue = evaluate(url, ctx.scope);
3848	const resolvedUrl = String(urlValue);
3849	const handler = async (event) => {
3850		if (config.trigger === "submit" || ctx.element instanceof HTMLFormElement) event.preventDefault();
3851		let body;
3852		if (method !== "GET" && method !== "DELETE" && ctx.element instanceof HTMLFormElement) body = serializeForm(ctx.element);
3853		await performRequest(ctx.element, method, resolvedUrl, config, body);
3854	};
3855	ctx.element.addEventListener(config.trigger, handler);
3856	const cleanup = () => {
3857		ctx.element.removeEventListener(config.trigger, handler);
3858	};
3859	if ("addCleanup" in ctx) ctx.addCleanup(cleanup);
3860	else ctx.cleanups.push(cleanup);
3861}
3862registerDirective("get", bindGet);
3863registerDirective("post", bindPost);
3864registerDirective("put", bindPut);
3865registerDirective("patch", bindPatch);
3866registerDirective("delete", bindDelete);
3867const el = (tag, attrs, ...children) => {
3868	const element = document.createElement(tag);
3869	if (typeof attrs === "string") element.className = attrs;
3870	else if (attrs) for (const [key, value] of Object.entries(attrs)) {
3871		if (isNil(value) || value === false) continue;
3872		if (value === true) element.setAttribute(key, "");
3873		else element.setAttribute(key, String(value));
3874	}
3875	for (const child of children) if (typeof child === "string") element.append(document.createTextNode(child));
3876	else element.append(child);
3877	return element;
3878};
3879const repeat = (createFn, items, attrs) => {
3880	return items.map((item) => createFn(attrs, item));
3881};
3882function kv(pairs, dtAttrs, ddAttrs) {
3883	const elements = [];
3884	for (const [term, definition] of pairs) elements.push(dt(dtAttrs, term), dd(ddAttrs, definition));
3885	return elements;
3886}
3887function options(items, attrs) {
3888	return items.map(([value, label$1]) => {
3889		const optionAttrs = typeof attrs === "string" ? {
3890			class: attrs,
3891			value
3892		} : {
3893			...attrs,
3894			value
3895		};
3896		return option(optionAttrs, label$1);
3897	});
3898}
3899function labelFor(labelText, inputAttrs, labelAttrs) {
3900	const labelElement = label(typeof labelAttrs === "string" ? labelAttrs : {
3901		...labelAttrs,
3902		for: inputAttrs.id
3903	}, labelText);
3904	const inputElement = input(inputAttrs);
3905	return [labelElement, inputElement];
3906}
3907function labelWith(labelText, inputAttrs, labelAttrs) {
3908	const inputElement = input(inputAttrs);
3909	if (typeof labelText === "string") return label(labelAttrs, inputElement, " ", labelText);
3910	return label(labelAttrs, inputElement, " ", ...labelText);
3911}
3912function buttons(items, sharedAttrs) {
3913	return items.map((item) => {
3914		if (Array.isArray(item)) {
3915			const [label$1, onClick$1] = item;
3916			const attrs$1 = {
3917				...typeof sharedAttrs === "object" && sharedAttrs !== null ? sharedAttrs : {},
3918				"data-volt-on-click": onClick$1
3919			};
3920			return button(attrs$1, label$1);
3921		}
3922		const { label: buttonLabel, onClick,...restAttrs } = item;
3923		const attrs = {
3924			...typeof sharedAttrs === "object" && sharedAttrs !== null ? sharedAttrs : {},
3925			...restAttrs,
3926			"data-volt-on-click": onClick
3927		};
3928		return button(attrs, buttonLabel);
3929	});
3930}
3931const h1 = (attrs, ...children) => el("h1", attrs, ...children);
3932const h2 = (attrs, ...children) => el("h2", attrs, ...children);
3933const h3 = (attrs, ...children) => el("h3", attrs, ...children);
3934const h4 = (attrs, ...children) => el("h4", attrs, ...children);
3935const h5 = (attrs, ...children) => el("h5", attrs, ...children);
3936const h6 = (attrs, ...children) => el("h6", attrs, ...children);
3937const p = (attrs, ...children) => el("p", attrs, ...children);
3938const div = (attrs, ...children) => el("div", attrs, ...children);
3939const span = (attrs, ...children) => el("span", attrs, ...children);
3940const small = (attrs, ...children) => el("small", attrs, ...children);
3941const article = (attrs, ...children) => el("article", attrs, ...children);
3942const section = (attrs, ...children) => el("section", attrs, ...children);
3943const header = (attrs, ...children) => el("header", attrs, ...children);
3944const footer = (attrs, ...children) => el("footer", attrs, ...children);
3945const nav = (attrs, ...children) => el("nav", attrs, ...children);
3946const ul = (attrs, ...children) => el("ul", attrs, ...children);
3947const ol = (attrs, ...children) => el("ol", attrs, ...children);
3948const li = (attrs, ...children) => el("li", attrs, ...children);
3949const dl = (attrs, ...children) => el("dl", attrs, ...children);
3950const dt = (attrs, ...children) => el("dt", attrs, ...children);
3951const dd = (attrs, ...children) => el("dd", attrs, ...children);
3952const a = (attrs, ...children) => el("a", attrs, ...children);
3953const button = (attrs, ...children) => el("button", attrs, ...children);
3954const input = (attrs) => el("input", attrs);
3955const textarea = (attrs, ...children) => el("textarea", attrs, ...children);
3956const select = (attrs, ...children) => el("select", attrs, ...children);
3957const option = (attrs, ...children) => el("option", attrs, ...children);
3958const label = (attrs, ...children) => el("label", attrs, ...children);
3959const form = (attrs, ...children) => el("form", attrs, ...children);
3960const fieldset = (attrs, ...children) => el("fieldset", attrs, ...children);
3961const legend = (attrs, ...children) => el("legend", attrs, ...children);
3962const table = (attrs, ...children) => el("table", attrs, ...children);
3963const thead = (attrs, ...children) => el("thead", attrs, ...children);
3964const tbody = (attrs, ...children) => el("tbody", attrs, ...children);
3965const tr = (attrs, ...children) => el("tr", attrs, ...children);
3966const th = (attrs, ...children) => el("th", attrs, ...children);
3967const td = (attrs, ...children) => el("td", attrs, ...children);
3968const blockquote = (attrs, ...children) => el("blockquote", attrs, ...children);
3969const cite = (attrs, ...children) => el("cite", attrs, ...children);
3970const code = (attrs, ...children) => el("code", attrs, ...children);
3971const pre = (attrs, ...children) => el("pre", attrs, ...children);
3972const dialog = (attrs, ...children) => el("dialog", attrs, ...children);
3973const details = (attrs, ...children) => el("details", attrs, ...children);
3974const summary = (attrs, ...children) => el("summary", attrs, ...children);
3975const strong = (attrs, ...children) => el("strong", attrs, ...children);
3976const em = (attrs, ...children) => el("em", attrs, ...children);
3977const del = (attrs, ...children) => el("del", attrs, ...children);
3978const abbr = (attrs, ...children) => el("abbr", attrs, ...children);
3979function createAnimationsSection() {
3980	return article({ id: "animations" }, h2(null, "Animation Demos"), section(null, h3(null, "Surge Plugin: Enter/Leave Transitions"), p(null, "The surge plugin provides smooth transitions when elements appear or disappear.", small
3980(null, "Toggle elements to see fade, slide, scale, and blur transitions. All integrate automatically with data-volt-if and data-volt-show bindings.")), details(null, summary(null, "Fade"), button({ "data-volt-on-click": "showFade.set(!showFade)" }, "Toggle Fade"), blockquote({
3981		"data-volt-if": "showFade",
3982		"data-volt-surge": "fade"
3983	}, "Fades in and out smoothly")), details(null, summary(null, "Slide Down"), button({ "data-volt-on-click": "showSlideDown.set(!showSlideDown)" }, "Toggle Slide"), blockquote({
3984		"data-volt-if": "showSlideDown",
3985		"data-volt-surge": "slide-down"
3986	}, "Slides down from above")), details(null, summary(null, "Scale"), button({ "data-volt-on-click": "showScale.set(!showScale)" }, "Toggle Scale"), blockquote({
3987		"data-volt-if": "showScale",
3988		"data-volt-surge": "scale"
3989	}, "Scales up smoothly")), details(null, summary(null, "Blur"), button({ "data-volt-on-click": "showBlur.set(!showBlur)" }, "Toggle Blur"), blockquote({
3990		"data-volt-if": "showBlur",
3991		"data-volt-surge": "blur"
3992	}, "Blur effect transition"))), section(null, h3(null, "Custom Timing"), p(null, "Override transition duration and delay using dot notation.", small(null, "Syntax: data-volt-surge=\"preset.duration.delay\" (times in milliseconds)")), details(null, summary(null, "Slow Fade (1000ms)"), button({ "data-volt-on-click": "showSlowFade.set(!showSlowFade)" }, "Toggle"), blockquote({
3993		"data-volt-if": "showSlowFade",
3994		"data-volt-surge": "fade.1000"
3995	}, "Very slow fade")), details(null, summary(null, "Delayed Slide (500ms + 200ms delay)"), button({ "data-volt-on-click": "showDelayedSlide.set(!showDelayedSlide)" }, "Toggle"), blockquote({
3996		"data-volt-if": "showDelayedSlide",
3997		"data-volt-surge": "slide-down.500.200"
3998	}, "Slides with delay"))), section(null, h3(null, "Different Enter/Leave Transitions"), p(null, "Specify different transitions for entering and leaving.", small(null, "Use data-volt-surge:enter and data-volt-surge:leave for granular control")), button({ "data-volt-on-click": "showGranular.set(!showGranular)" }, "Toggle Mixed Transition"), blockquote({
3999		"data-volt-if": "showGranular",
4000		"data-volt-surge:enter": "slide-down.400",
4001		"data-volt-surge:leave": "fade.200"
4002	}, "Slides in, fades out")), section(null, h3(null, "Shift Plugin: Keyframe Animations"), p(null, "The shift plugin applies CSS keyframe animations for attention effects.", small(null, "Click buttons to trigger animations. Some run continuously, others on demand.")), div({ style: "display: flex; gap: 0.5rem; flex-wrap: wrap;" }, button({
4003		"data-volt-on-click": "triggerBounce.set(triggerBounce + 1)",
4004		"data-volt-shift": "triggerBounce:bounce"
4005	}, "Bounce"), button({
4006		"data-volt-on-click": "triggerShake.set(triggerShake + 1)",
4007		"data-volt-shift": "triggerShake:shake"
4008	}, "Shake"), button({ "data-volt-shift": "pulse" }, "Pulse (Continuous)"), button({
4009		"data-volt-on-click": "triggerFlash.set(triggerFlash + 1)",
4010		"data-volt-shift": "triggerFlash:flash"
4011	}, "Flash")), p(null, button({ "data-volt-on-click": "spinningGear.set(!spinningGear)" }, "Toggle Spin"), " Spinning gear: ", span({
4012		"data-volt-shift": "spinningGear:spin",
4013		style: "font-size: 2rem;"
4014	}, "⚙️"))), section(null, h3(null, "Custom Animation Settings"), p(null, "Override animation duration and iteration count.", small(null, "Syntax: data-volt-shift=\"animation.duration.iterations\"")), div({ style: "display: flex; gap: 0.5rem; flex-wrap: wrap;" }, button({
4015		"data-volt-on-click": "triggerTripleBounce.set(triggerTripleBounce + 1)",
4016		"data-volt-shift": "triggerTripleBounce:bounce.800.3"
4017	}, "Triple Bounce (800ms each)"), button({
4018		"data-volt-on-click": "triggerLongShake.set(triggerLongShake + 1)",
4019		"data-volt-shift": "triggerLongShake:shake.1000.2"
4020	}, "Long Shake (1000ms, 2x)"))), section(null, h3(null, "Combined Effects"), p(null, "Surge and shift can be combined for complex animation choreography.", small(null, "Toggle to see content that fades in, then bounces on mount")), button({ "data-volt-on-click": "showCombined.set(!showCombined)" }, "Toggle Combined Animation"), p(null, strong(null, "Animated sidenote:"), " This paragraph keeps the flow of the article while the sidenote animates into view.", " ", small
4020({
4021		"data-volt-if": "showCombined",
4022		"data-volt-surge": "fade.400",
4023		"data-volt-shift": "bounce"
4024	}, "This margin note fades into place and bounces to grab your attention."))));
4025}
4026function createCssSection() {
4027	return article({ id: "css" }, h2(null, "VoltX.css"), section(null, h3(null, "Headings & Hierarchy"), p(null, "Volt CSS provides a harmonious type scale based on a 1.25 ratio (major third).", small(null, "The modular scale creates visual hierarchy without requiring any CSS classes. Font sizes range from 0.889rem to 2.566rem."), " All headings automatically receive appropriate sizing, spacing, and weight."), h4(null, "Level 4 Heading"), p(null, "Demonstrates the fourth level of hierarchy."), h5(null, "Level 5 Heading"), p(null, "Even smaller, but still distinct and readable."), h6(null, "Level 6 Heading"), p(null, "The smallest heading level in the hierarchy.")), section(null, h3(null, "Tufte-Style Sidenotes"), p(null, "One of the signature features of Volt CSS is Tufte-style sidenotes.", small(null, "Edward Tufte is renowned for his work on information design and data visualization. His books feature extensive use of margin notes that provide context without interrupting the main narrative flow."), " These appear in the margin on desktop and inline on mobile devices."), p(null, "Sidenotes are created using the semantic ", code(null, "<small>"), " element.", small(null, "The <small> element represents side comments and fine print, making it semantically appropriate for sidenotes. No custom attributes needed!"), " This keeps markup clean and portable while maintaining semantic meaning."), p(null, "The responsive behavior ensures readability across all devices.", small(null, "On narrow screens, sidenotes appear inline with subtle styling. On wider screens (≥1200px), they float into the right margin."), " Try resizing your browser to see the effect.")), section(null, h3(null, "Lists"), p(null, "Both ordered and unordered lists are styled with appropriate spacing:"), h4(null, "Unordered List"), ul(null, ...repeat(li, [
4028		"Reactive signals for state management",
4029		"Computed values derived from signals",
4030		"Effect system for side effects",
4031		"Declarative data binding via attributes"
4032	])), h4(null, "Ordered List"), ol(null, ...repeat(li, [
4033		"Define your signals and computed values",
4034		"Write semantic HTML markup",
4035		"Add data-volt-* attributes for reactivity",
4036		"Mount the scope and watch the magic happen"
4037	])), h4(null, "Description List"), dl(null, ...kv([
4038		["Signal", "A reactive primitive that holds a value and notifies subscribers of changes."],
4039		["Computed", "A derived value that automatically updates when its dependencies change."],
4040		["Effect", "A side effect that runs when its reactive dependencies change."]
4041	]))), section(null, h3(null, "Blockquotes & Citations"), blockquote(null, p(null, "Perfection is achieved, not when there is nothing more to add, but when there is nothing left to take away."), cite(null, "Antoine de Saint-Exupéry")), blockquote(null, p(null, "The best programs are written so that computing machines can perform them quickly and so that human beings can understand them clearly."), cite(null, "Donald Knuth"))), section(null, h3(null, "Code & Preformatted Text"), p(null, "Inline code uses ", code(null, "monospace font"), " for clarity."), p(null, "Code blocks preserve formatting and provide syntax-appropriate styling:"), pre(null, code(null, `import { signal, computed, mount } from 'volt';
4042
4043const count = signal(0);
4044const doubled = computed(() => count.get() * 2);
4045
4046mount(document.querySelector('#app'), {
4047  count,
4048  doubled,
4049  increment: () => count.set(count.get() + 1)
4050});`))), section(null, h3(null, "Tables"), p(null, "Tables receive zebra striping and responsive styling automatically.", small(null, "Tables use alternating row colors for improved scannability. On mobile, they remain scrollable horizontally if needed.")), table(null, thead(null, tr(null, ...repeat(th, [
4051		"Feature",
4052		"Volt.js",
4053		"Framework X",
4054		"Framework Y"
4055	]))), tbody(null, tr(null, ...repeat(td, [
4056		"Bundle Size",
4057		"< 15KB gzipped",
4058		"~40KB",
4059		"~30KB"
4060	])), tr(null, td(null, "Virtual DOM"), td(null, "No"), td(null, "Yes"), td(null, "Yes")), tr(null, ...repeat(td, [
4061		"Reactive System",
4062		"Signals",
4063		"Proxy-based",
4064		"Observable"
4065	])), tr(null, ...repeat(td, [
4066		"Learning Curve",
4067		"Gentle",
4068		"Moderate",
4069		"Steep"
4070	]))))), section(null, h3(null, "Tooltips"), p(null, "VoltX CSS includes pure-CSS tooltips with zero JavaScript. Try hovering over these examples:"), p(null, abbr({
4071		"data-vx-tooltip": "Tooltips appear on top by default",
4072		"data-placement": "top"
4073	}, "Top"), " · ", abbr({
4074		"data-vx-tooltip": "Tooltips can appear on the right",
4075		"data-placement": "right"
4076	}, "Right"), " · ", abbr({
4077		"data-vx-tooltip": "Tooltips can appear on the bottom",
4078		"data-placement": "bottom"
4079	}, "Bottom"), " · ", abbr({
4080		"data-vx-tooltip": "Tooltips can appear on the left",
4081		"data-placement": "left"
4082	}, "Left")), p(null, small(null, "Tooltips use the data-vx-tooltip attribute and are styled with pure CSS. They automatically hide on mobile devices for better touch interaction.")), h4(null, "Implementation"), p(null, "Add the ", code(null, "data-vx-tooltip"), " attribute with your tooltip text, and optionally specify ", code(null, "data-placement"), " (top, right, bottom, left) for positioning."), pre(null, code(null, `<abbr data-vx-tooltip="Helpful tooltip text"
4083      data-placement="top">
4084  Hover me
4085</abbr>`))), section(null, h3(null, "Accordions"), p(null, "Native HTML ", code(null, "<details>"), " and ", code(null, "<summary>"), " elements provide semantic accordion functionality.", small
4085(null, "The details element is fully accessible by default, with keyboard navigation built in. VoltX CSS styles it beautifully without requiring any JavaScript.")), details(null, summary(null, "What is VoltX.js?"), p(null, "VoltX.js is a lightweight reactive framework for building declarative user interfaces. It uses signals for reactivity and provides HTML-driven behavior through data-volt-* attributes.")), details(null, summary(null, "How does reactivity work?"), p(null, "VoltX uses a signal-based reactive system. When a signal changes, all computed values and effects that depend on it automatically update. The DOM bindings subscribe to these signals and update the UI accordingly.")), details(null, summary(null, "What about styling?"), p(null, "VoltX CSS is a classless CSS framework inspired by Pico CSS and Tufte CSS. It provides beautiful, semantic styling without requiring any CSS classes. Just write semantic HTML and it looks great!"))), section(null, h3(null, "Dialogs"), p(null, "Native ", code(null, "<dialog>"), " elements provide semantic modal functionality with built-in accessibility.", small(null, "The dialog element includes keyboard handling (ESC to close), focus trapping, and backdrop support. Modern browsers support it natively."), " VoltX CSS styles dialogs elegantly with proper backdrop blur and animations."), p(null, "Dialogs require JavaScript to open and close (using ", code(null, "showModal()"), " and ", code(null, "close()"), " methods). ", "See the ", a({ href: "/interactivity" }, "Interactivity section"), " for a working dialog demo."), h4(null, "Structure"), p(null, "Dialogs should follow this semantic structure for proper styling:"), pre(null, code(null, `<dialog id="my-dialog">
4086  <article>
4087    <header>
4088      <h3>Dialog Title</h3>
4089      <button aria-label="Close">×</button>
4090    </header>
4091    <!-- Dialog content -->
4092    <footer>
4093      <button>Cancel</button>
4094      <button>Confirm</button>
4095    </footer>
4096  </article>
4097</dialog>`))), section(null, h3(null, "Additional Features"), p(null, "VoltX CSS includes comprehensive styling for all semantic HTML elements:"), ul(null, ...repeat(li, [
4098		"Typography with modular scale and Tufte-style sidenotes",
4099		"Form elements with consistent, accessible styling",
4100		"Tables with zebra striping and responsive behavior",
4101		"Code blocks with syntax-appropriate styling",
4102		"Blockquotes and citations",
4103		"Responsive images and media",
4104		"And much more, all without CSS classes!"
4105	])), p(null, "Explore the other sections of this demo to see these features in action.")));
4106}
4107function createFormsSection() {
4108	return article({ id: "forms" }, h2(null, "Forms & Two-Way Binding"), section(null, h3(null, "Complete Form Example"), p(null, "The ", code(null, "data-volt-model"), " attribute provides two-way data binding.", small(null, "Changes in the input automatically update the signal, and changes to the signal automatically update the input. No manual event handlers needed!")), form({ "data-volt-on-submit": "$helpers.handleFormSubmit($event)" }, fieldset(null, legend(null, "User Information"), ...labelFor("Name", {
4109		type: "text",
4110		id: "name",
4111		"data-volt-model": "formData.name",
4112		placeholder: "John Doe",
4113		required: true
4114	}), ...labelFor("Email", {
4115		type: "email",
4116		id: "email",
4117		"data-volt-model": "formData.email",
4118		placeholder: "[email protected]",
4119		required: true
4120	}), label({ for: "bio" }, "Bio"), textarea({
4121		id: "bio",
4122		"data-volt-model": "formData.bio",
4123		placeholder: "Tell us about yourself...",
4124		rows: "4"
4125	}), label({ for: "country" }, "Country"), select({
4126		id: "country",
4127		"data-volt-model": "formData.country"
4128	}, ...options([
4129		["us", "United States"],
4130		["uk", "United Kingdom"],
4131		["ca", "Canada"],
4132		["au", "Australia"],
4133		["other", "Other"]
4134	])), labelWith("Subscribe to newsletter", {
4135		type: "checkbox",
4136		"data-volt-model": "formData.newsletter"
4137	}), fieldset(null, legend(null, "Plan"), labelWith("Free", {
4138		type: "radio",
4139		name: "plan",
4140		value: "free",
4141		"data-volt-model": "formData.plan"
4142	}), labelWith("Pro", {
4143		type: "radio",
4144		name: "plan",
4145		value: "pro",
4146		"data-volt-model": "formData.plan"
4147	}), labelWith("Enterprise", {
4148		type: "radio",
4149		name: "plan",
4150		value: "enterprise",
4151		"data-volt-model": "formData.plan"
4152	})), button({ type: "submit" }, "Submit Form"), button({ type: "reset" }, "Clear"))), details(null, summary(null, "Current Form Data (Live)"), pre(null, code({ "data-volt-text": "JSON.stringify(formData, null, 2)" }, "Loading...")))));
4153}
4154function createHomeSection() {
4155	return article({ id: "home" }, section(null, h2(null, "VoltX.js: Declarative Reactivity for the Modern Web"), p(null, "VoltX.js is a lightweight reactive framework that brings signal-based reactivity to HTML.", small
4155(null, "Build rich, interactive applications using declarative markup without writing JavaScript. No virtual DOM, no build step, no dependencies—just pure reactive primitives and HTML attributes."))), section(null, h3(null, "Why VoltX.js?"), dl(null, ...kv([
4156		["< 15KB Gzipped", "Smaller than most icon libraries. Ships only what you need with zero dependencies."],
4157		["Declarative-First", "Build entire applications using only HTML attributes. JavaScript is optional for complex logic."],
4158		["Signal-Based Reactivity", "Fine-grained reactivity that updates only what changed. No virtual DOM diffing."],
4159		["Zero Build Step", "Import from npm or CDN and start building. No webpack, no rollup, no configuration."],
4160		["Progressive Enhancement", "Works with server-rendered HTML. Add reactivity incrementally where needed."],
4161		["Standards-Based", "Built on standard DOM APIs. No proprietary JSX or template syntax."]
4162	]))), section(null, h3(null, "Quick Start"), p(null, "Get started with VoltX.js in seconds:"), pre(null, code(null, `<!-- Include VoltX.js from CDN -->
4163<script type="module">
4164  import { charge } from 'https://esm.sh/voltx.js';
4165  charge();
4166<\/script>
4167
4168<!-- Declare reactive state in HTML -->
4169<div data-volt data-volt-state='{"count": 0}'
4170     data-volt-computed:doubled="count * 2">
4171  <p>Count: <span data-volt-text="count"></span></p>
4172  <p>Doubled: <span data-volt-text="doubled"></span></p>
4173  <button data-volt-on-click="count.set(count + 1)">
4174    Increment
4175  </button>
4176</div>`)), p(null, "That's it! No build step, no configuration, no JavaScript beyond the import. ", strong(null, "The state, reactivity, and interactions are all declared in HTML."))), section(null, h3(null, "Explore the Features"), p(null, "Navigate through the demo to see VoltX.js in action:"), ul(null, li(null, strong(null, "Typography & CSS"), " - Explore Volt CSS, our classless CSS framework with Tufte-style sidenotes"), li(null, strong(null, "Interactivity"), " - See dialogs, buttons, and event handling with declarative bindings"), li(null, strong(null, "Forms"), " - Two-way data binding with all standard form elements"), li(null, strong(null, "Reactivity"), " - Conditional rendering, list rendering, and computed values"), li(null, strong(null, "Plugins"), " - Persistence, scroll management, URL synchronization, and more"), li(null, strong(null, "Animations"), " - Built-in transitions and keyframe animations with zero configuration")), p(null, "Use the navigation above to explore each section.")), section(null, h3(null, "Learn More"), p(null, a({ href: "https://github.com/stormlightlabs/volt" }, "GitHub Repository"), " | ", a({ href: "https://stormlightlabs.github.io/volt" }, "Documentation"), " | ", a({ href: "https://www.npmjs.com/package/voltx.js" }, "npm Package"), " | ", a({ href: "https://jsr.io/@voltx/core" }, "JSR Package"))));
4177}
4178function createInteractivitySection() {
4179	return article({ id: "interactivity" }, h2(null, "Dialogs & Interactivity"), section(null, h3(null, "Native Dialog Element"), p(null, "The HTML ", code(null, "<dialog>"), " element provides semantic modal functionality.", small(null, "Modern browsers support the dialog element natively, providing built-in accessibility features and keyboard handling (ESC to close, focus trapping, etc.)."), " VoltX CSS styles it elegantly, and VoltX.js handles the interaction."), button({ "data-volt-on-click": "$helpers.openDialog('demo-dialog'); dialogMessage.set(''); dialogInput.set('')" }, "Open Dialog"), p({
4180		"data-volt-if": "dialogMessage",
4181		"data-volt-text": "dialogMessage"
4182	}), dialog({ id: "demo-dialog" }, article(null, header(null, h3(null, "Dialog Demo"), button({
4183		"data-volt-on-click": "$helpers.closeDialog('demo-dialog')",
4184		"aria-label": "Close"
4185	}, "×")), form({
4186		id: "demo-dialog-form",
4187		"data-volt-on-submit": "$event.preventDefault(); dialogMessage.set('You entered: ' + dialogInput); setTimeout(() => $helpers.closeDialog('demo-dialog'), 2000)"
4188	}, ...labelFor("Enter something:", {
4189		type: "text",
4190		id: "dialog-input",
4191		"data-volt-model": "dialogInput",
4192		placeholder: "Type here...",
4193		required: true
4194	})), footer(null, button({
4195		type: "button",
4196		"data-volt-on-click": "$helpers.closeDialog('demo-dialog')"
4197	}, "Cancel"), button({
4198		type: "submit",
4199		form: "demo-dialog-form"
4200	}, "Submit"))))), section(null, h3(null, "Button Interactions"), p(null, "Count: ", strong({ "data-volt-text": "count" }, "0"), " | Doubled: ", strong({ "data-volt-text": "doubled" }, "0")), div({ style: "display: flex; gap: 0.5rem; flex-wrap: wrap;" }, ...buttons([
4201		["Increment", "count.set(count + 1)"],
4202		["Decrement", "count.set(count - 1)"],
4203		["Reset", "count.set(0)"],
4204		["Update Header", "message.set('Count is now ' + count)"]
4205	]))));
4206}
4207function createPluginsSection() {
4208	return article({ id: "plugins" }, h2(null, "Plugin Demos"), section(null, h3(null, "Persist Plugin"), p(null, "The persist plugin syncs signals with localStorage, sessionStorage, or IndexedDB.", small
4208(null, "Try incrementing the counter, then refresh the page. The value persists! This uses localStorage by default.")), p(null, "Persisted Count: ", strong({ "data-volt-text": "persistedCount" }, "0")), div({ "data-volt-persist:persistedCount": "localStorage" }, button({ "data-volt-on-click": "persistedCount.set(persistedCount + 1)" }, "Increment Persisted"), " ", button({ "data-volt-on-click": "persistedCount.set(0)" }, "Reset Persisted"))), section(null, h3(null, "Scroll Plugin"), p(null, "The scroll plugin provides scroll tracking and smooth scrolling utilities.", small(null, "Current scroll position is tracked in real-time. The scroll position updates as you scroll the page, and you can jump to sections smoothly.")), p(null, "Current Scroll Position: ", strong({ "data-volt-text": "Math.round(scrollPosition)" }, "0"), "px"), div({ style: "display: flex; gap: 0.5rem; flex-wrap: wrap;" }, button({ "data-volt-on-click": "$helpers.scrollToTop()" }, "Scroll to Top"), button({ "data-volt-on-click": "$helpers.scrollToSection('typography')" }, "Go to Typography"), button({ "data-volt-on-click": "$helpers.scrollToSection('forms')" }, "Go to Forms"), button({ "data-volt-on-click": "$helpers.scrollToSection('plugins')" }, "Go to Plugins"))), section(null, h3(null, "URL Plugin"), p(null, "The URL plugin syncs signals with URL query parameters or hash.", small(null, "Try typing in the input below. Notice how the URL updates automatically! Bookmark the URL and return later - the state is preserved.")), div({
4209		"data-volt-url:urlParam": "query",
4210		"style": "max-width: var(--content-width);"
4211	}, ...labelFor("URL Parameter (synced with ?urlParam=...)", {
4212		type: "text",
4213		id: "url-input",
4214		"data-volt-model": "urlParam",
4215		placeholder: "Type to update URL..."
4216	}), p(null, "Current value: ", strong({ "data-volt-text": "urlParam || '(empty)'" }, "Loading...")))));
4217}
4218function createReactivitySection() {
4219	const style = el("style", null, `.active {
4220  color: var(--color-accent);
4221  font-weight: bold;
4222}
4223.highlight {
4224  background: var(--color-mark);
4225  padding: 0.25rem 0.5rem;
4226  border-radius: var(--radius-sm);
4227}`);
4228	return article({ id: "reactivity" }, h2(null, "Reactivity Features"), section(null, h3(null, "Conditional Rendering"), p(null, "Use ", code(null, "data-volt-if"), " and ", code(null, "data-volt-else"), " for conditional display:"), button({ "data-volt-on-click": "showAdvanced.set(!showAdvanced)" }, span({ "data-volt-text": "showAdvanced ? 'Hide' : 'Show'" }, "Show"), " Advanced Options"), div({ "data-volt-if": "showAdvanced" }, h4(null, "Advanced Configuration"), p(null, "These options are only visible when advanced mode is enabled."), labelWith("Enable debug mode", { type: "checkbox" }), labelWith("Use experimental features", { type: "checkbox" })), div({ "data-volt-else": true }, p(null, em(null, "Advanced options are hidden. Click the button above to reveal them.")))), section(null, h3(null, "List Rendering"), p(null, "Use ", code(null, "data-volt-for"), " to render dynamic lists.", small(null, `The syntax is "item in items" where items is a signal or expression. Each item gets its own scope with access to the item data and parent scope.`)), div(null, input({
4229		type: "text",
4230		"data-volt-model": "newTodoText",
4231		placeholder: "New todo...",
4232		"data-volt-on-keydown": "$event.key === 'Enter' && newTodoText.trim() ? (todos.set([...todos, {id: todoIdCounter, text: newTodoText.trim(), done: false}]), todoIdCounter.set(todoIdCounter + 1), newTodoText.set('')) : null"
4233	}), button({ "data-volt-on-click": "newTodoText.trim() ? (todos.set([...todos, {id: todoIdCounter, text: newTodoText.trim(), done: false}]), todoIdCounter.set(todoIdCounter + 1), newTodoText.set('')) : null" }, "Add Todo")), h4(null, "Active Todos (", span({ "data-volt-text": "activeTodos.length" }, "0"), ")"), ul(null, li({ "data-volt-for": "todo in activeTodos" }, input({
4234		type: "checkbox",
4235		"data-volt-on-change": "todos.set(todos.map(t => t.id === todo.id ? {...t, done: !t.done} : t))"
4236	}), " ", span({ "data-volt-text": "todo.text" }, "Todo item"), " ", button({ "data-volt-on-click": "todos.set(todos.filter(t => t.id !== todo.id))" }, "Remove"))), h4(null, "Completed Todos (", span({ "data-volt-text": "completedTodos.length" }, "0"), ")"), ul(null, li({ "data-volt-for": "todo in completedTodos" }, input({
4237		type: "checkbox",
4238		checked: true,
4239		"data-volt-on-change": "todos.set(todos.map(t => t.id === todo.id ? {...t, done: !t.done} : t))"
4240	}), " ", del({ "data-volt-text": "todo.text" }, "Todo item"), " ", button({ "data-volt-on-click": "todos.set(todos.filter(t => t.id !== todo.id))" }, "Remove")))), section(null, h3(null, "Class Bindings"), p(null, "Toggle CSS classes reactively using ", co
4240de(null, "data-volt-class"), ":"), p({ "data-volt-class": "{ active: isActive, highlight: isHighlighted }" }, "This paragraph has dynamic classes. Try the buttons below!"), button({ "data-volt-on-click": "isActive.set(!isActive)" }, "Toggle Active (currently: ", span({ "data-volt-text": "isActive ? 'ON' : 'OFF'" }, "OFF"), ")"), " ", button({ "data-volt-on-click": "isHighlighted.set(!isHighlighted)" }, "Toggle Highlight (currently: ", span({ "data-volt-text": "isHighlighted ? 'ON' : 'OFF'" }, "OFF"), ")"), style));
4241}
4242setRouterMode("hash");
4243registerPlugin("persist", persistPlugin);
4244registerPlugin("scroll", scrollPlugin);
4245registerPlugin("url", urlPlugin);
4246registerPlugin("surge", surgePlugin);
4247registerPlugin("shift", shiftPlugin);
4248var helpers = {
4249	openDialog(id) {
4250		const dialog$1 = document.querySelector(`#${id}`);
4251		if (dialog$1) dialog$1.showModal();
4252	},
4253	closeDialog(id) {
4254		const dialog$1 = document.querySelector(`#${id}`);
4255		if (dialog$1) dialog$1.close();
4256	},
4257	scrollToTop() {
4258		window.scrollTo({
4259			top: 0,
4260			behavior: "smooth"
4261		});
4262	},
4263	scrollToSection(id) {
4264		const element = document.querySelector(`#${id}`);
4265		if (element) element.scrollIntoView({ behavior: "smooth" });
4266	},
4267	handleFormSubmit(event) {
4268		event.preventDefault();
4269		const form$1 = event.target;
4270		const formData = new FormData(form$1);
4271		const data = Object.fromEntries(formData.entries());
4272		console.log("Form submitted:", data);
4273		alert("Form submitted! Check console for data.");
4274	}
4275};
4276var buildNav = () => nav(null, a({
4277	"data-volt-navigate": "",
4278	href: "/"
4279}, "Home"), " | ", a({
4280	"data-volt-navigate": "",
4281	href: "/css"
4282}, "CSS"), " | ", a({
4283	"data-volt-navigate": "",
4284	href: "/interactivity"
4285}, "Interactivity"), " | ", a({
4286	"data-volt-navigate": "",
4287	href: "/forms"
4288}, "Forms"), " | ", a({
4289	"data-volt-navigate": "",
4290	href: "/reactivity"
4291}, "Reactivity"), " | ", a({
4292	"data-volt-navigate": "",
4293	href: "/plugins"
4294}, "Plugins"), " | ", a({
4295	"data-volt-navigate": "",
4296	href: "/animations"
4297}, "Animations"));
4298function getCurrentPageFromPath() {
4299	if (globalThis.location.hash) {
4300		const hash = globalThis.location.hash.slice(1);
4301		if (hash === "/" || hash === "") return "home";
4302		return hash.slice(1);
4303	}
4304	const path = globalThis.location.pathname;
4305	if (path === "/" || path === "") return "home";
4306	return path.slice(1);
4307}
4308function buildDemoStructure() {
4309	const initialState = {
4310		currentPage: getCurrentPageFromPath(),
4311		message: "Welcome to the VoltX.js Demo",
4312		count: 0,
4313		formData: {
4314			name: "",
4315			email: "",
4316			bio: "",
4317			country: "us",
4318			newsletter: false,
4319			plan: "free"
4320		},
4321		todos: [
4322			{
4323				id: 1,
4324				text: "Learn VoltX.js",
4325				done: false
4326			},
4327			{
4328				id: 2,
4329				text: "Build an app",
4330				done: false
4331			},
4332			{
4333				id: 3,
4334				text: "Ship to production",
4335				done: false
4336			}
4337		],
4338		newTodoText: "",
4339		todoIdCounter: 4,
4340		showAdvanced: false,
4341		isActive: true,
4342		isHighlighted: false,
4343		dialogMessage: "",
4344		dialogInput: "",
4345		persistedCount: 0,
4346		scrollPosition: 0,
4347		urlParam: "",
4348		showFade: false,
4349		showSlideDown: false,
4350		showScale: false,
4351		showBlur: false,
4352		showSlowFade: false,
4353		showDelayedSlide: false,
4354		showGranular: false,
4355		showCombined: false,
4356		triggerBounce: 0,
4357		triggerShake: 0,
4358		triggerFlash: 0,
4359		triggerTripleBounce: 0,
4360		triggerLongShake: 0,
4361		spinningGear: true
4362	};
4363	return div({
4364		"data-volt": "",
4365		"data-volt-state": JSON.stringify(initialState),
4366		"data-volt-computed:doubled": "count * 2",
4367		"data-volt-computed:active-todos": "todos.filter(t => !t.done)",
4368		"data-volt-computed:completed-todos": "todos.filter(t => t.done)"
4369	}, header(null, h1({ "data-volt-text": "message" }, "Loading..."), p(null, "A comprehensive demo showcasing VoltX.js reactive framework and Volt CSS classless styling.", small(null, "This demo demonstrates both the framework's reactive capabilities and the elegant, semantic styling of Volt CSS. No CSS classes needed!"), buildNav())), el("main", null, div({ "data-volt-if": "currentPage === 'home'" }, createHomeSection()), div({ "data-volt-if": "currentPage === 'css'" }, createCssSection()), div({ "data-volt-if": "currentPage === 'interactivity'" }, createInteractivitySection()), div({ "data-volt-if": "currentPage === 'forms'" }, createFormsSection()), div({ "data-volt-if": "currentPage === 'reactivity'" }, createReactivitySection()), div({ "data-volt-if": "currentPage === 'plugins'" }, createPluginsSection()), div({ "data-volt-if": "currentPage === 'animations'" }, createAnimationsSection())), footer(null, p(null, "Built with ", a({ href: "https://github.com/stormlightlabs/volt" }, "VoltX.js"), " - A lightweight, reactive hypermedia framework"), p(null, "This demo showcases both VoltX's reactive features and VoltX.css' classless styling.")));
4370}
4371function setupDemo() {
4372	const app = document.querySelector("#app");
4373	if (!app) {
4374		console.error("App container not found");
4375		return;
4376	}
4377	const demoStructure = buildDemoStructure();
4378	app.append(demoStructure);
4379	const chargeResult = charge();
4380	const cleanupNav = initNavigationListener();
4381	const rootScope = chargeResult.roots[0]?.scope;
4382	if (!rootScope) {
4383		console.error("Failed to get root scope from charge result");
4384		return;
4385	}
4386	rootScope.$helpers = helpers;
4387	const handleNavigate = (event) => {
4388		const url = event.detail?.url || "";
4389		let page = "home";
4390		if (url.startsWith("#")) {
4391			const hash = url.slice(1);
4392			page = hash === "/" || hash === "" ? "home" : hash.slice(1);
4393		} else if (url) page = url === "/" || url === "" ? "home" : url.slice(1);
4394		else page = getCurrentPageFromPath();
4395		const currentPageSignal = rootScope.currentPage;
4396		if (currentPageSignal && isSignal(currentPageSignal)) currentPageSignal.set(page);
4397		window.scrollTo({
4398			top: 0,
4399			behavior: "instant"
4400		});
4401	};
4402	const handlePopstate = () => {
4403		const page = getCurrentPageFromPath();
4404		const currentPageSignal = rootScope.currentPage;
4405		if (currentPageSignal && isSignal(currentPageSignal)) currentPageSignal.set(page);
4406	};
4407	const handleScroll = () => {
4408		const scrollPositionSignal = rootScope.scrollPosition;
4409		if (scrollPositionSignal && isSignal(scrollPositionSignal)) scrollPositionSignal.set(window.scrollY);
4410	};
4411	globalThis.addEventListener("volt:navigate", handleNavigate);
4412	globalThis.addEventListener("volt:popstate", handlePopstate);
4413	window.addEventListener("scroll", handleScroll);
4414	return () => {
4415		chargeResult.cleanup();
4416		cleanupNav();
4417		globalThis.removeEventListener("volt:navigate", handleNavigate);
4418		globalThis.removeEventListener("volt:popstate", handlePopstate);
4419		window.removeEventListener("scroll", handleScroll);
4420	};
4421}
4422setupDemo();

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.