PageSourceSearch

https://ferimex.sk/assets/@symfony/ux-live-component/live_controller-ajwV4na.js

js ferimex.sk collected 2026-10-08 20:39:26 UTC 92,718 bytes, 2,555 lines download raw bytes

1import { Controller } from "@hotwired/stimulus";
2var BackendRequest_default = class {
3	promise;
4	actions;
5	updatedModels;
6	isResolved = false;
7	constructor(promise, actions, updateModels) {
8		this.promise = promise;
9		this.promise.then((response) => {
10			this.isResolved = true;
11			return response;
12		});
13		this.actions = actions;
14		this.updatedModels = updateModels;
15	}
16	containsOneOfActions(targetedActions) {
17		return this.actions.filter((action) => targetedActions.includes(action)).length > 0;
18	}
19	areAnyModelsUpdated(targetedModels) {
20		return this.updatedModels.filter((model) => targetedModels.includes(model)).length > 0;
21	}
22};
23var RequestBuilder_default = class {
24	url;
25	method;
26	credentials;
27	constructor(url, method = "post", credentials = "same-origin") {
28		this.url = url;
29		this.method = method;
30		this.credentials = credentials;
31	}
32	buildRequest(props, actions, updated, children, updatedPropsFromParent, files) {
33		const splitUrl = this.url.split("?");
34		let [url] = splitUrl;
35		const [, queryString] = splitUrl;
36		const params = new URLSearchParams(queryString || "");
37		const fetchOptions = {};
38		fetchOptions.credentials = this.credentials;
39		fetchOptions.headers = {
40			Accept: "application/vnd.live-component+html",
41			"X-Requested-With": "XMLHttpRequest",
42			"X-Live-Url": window.location.pathname + window.location.search
43		};
44		const totalFiles = Object.entries(files).reduce((total, current) => total + current.length, 0);
45		const hasFingerprints = Object.keys(children).length > 0;
46		if (actions.length === 0 && totalFiles === 0 && this.method === "get" && this.willDataFitInUrl(JSON.stringify(props), JSON.stringify(updated), params, JSON.stringify(children), JSON.stringify(updatedPropsFromParent))) {
47			params.set("props", JSON.stringify(props));
48			params.set("updated", JSON.stringify(updated));
49			if (Object.keys(updatedPropsFromParent).length > 0) params.set("propsFromParent", JSON.stringify(updatedPropsFromParent));
50			if (hasFingerprints) params.set("children", JSON.stringify(children));
51			fetchOptions.method = "GET";
52		} else {
53			fetchOptions.method = "POST";
54			const requestData = {
55				props,
56				updated
57			};
58			if (Object.keys(updatedPropsFromParent).length > 0) requestData.propsFromParent = updatedPropsFromParent;
59			if (hasFingerprints) requestData.children = children;
60			if (actions.length > 0) if (actions.length === 1) {
61				requestData.args = actions[0].args;
62				url += `/${encodeURIComponent(actions[0].name)}`;
63			} else {
64				url += "/_batch";
65				requestData.actions = actions;
66			}
67			const formData = new FormData();
68			formData.append("data", JSON.stringify(requestData));
69			for (const [key, value] of Object.entries(files)) {
70				const length = value.length;
71				for (let i = 0; i < length; ++i) formData.append(key, value[i]);
72			}
73			fetchOptions.body = formData;
74		}
75		const paramsString = params.toString();
76		return {
77			url: `${url}${paramsString.length > 0 ? `?${paramsString}` : ""}`,
78			fetchOptions
79		};
80	}
81	willDataFitInUrl(propsJson, updatedJson, params, childrenJson, propsFromParentJson) {
82		return (new URLSearchParams(propsJson + updatedJson + childrenJson + propsFromParentJson).toString() + params.toString()).length < 1500;
83	}
84};
85var Backend_default = class {
86	requestBuilder;
87	constructor(url, method = "post", credentials = "same-origin") {
88		this.requestBuilder = new RequestBuilder_default(url, method, credentials);
89	}
90	makeRequest(props, actions, updated, children, updatedPropsFromParent, files) {
91		const { url, fetchOptions } = this.requestBuilder.buildRequest(props, actions, updated, children, updatedPropsFromParent, files);
92		return new BackendRequest_default(fetch(url, fetchOptions), actions.map((backendAction) => backendAction.name), Object.keys(updated));
93	}
94};
95var BackendResponse_default = class {
96	response;
97	body;
98	liveUrl;
99	download = null;
100	parsePromise = null;
101	constructor(response) {
102		this.response = response;
103	}
104	async getBody() {
105		if (!this.parsePromise) this.parsePromise = this.parse();
106		await this.parsePromise;
107		return this.body;
108	}
109	getDownload() {
110		return this.download;
111	}
112	getLiveUrl() {
113		if (void 0 === this.liveUrl) this.liveUrl = this.response.headers.get("X-Live-Url");
114		return this.liveUrl;
115	}
116	getDownloadUrl() {
117		return this.response.headers.get("X-Live-Download-Url");
118	}
119	isRemoved() {
120		return this.response.headers.has("X-Live-Remove");
121	}
122	async parse() {
123		const htmlLength = this.response.headers.get("X-Live-Html-Length");
124		if (null === htmlLength) {
125			this.body = await this.response.text();
126			return;
127		}
128		const buffer = await this.response.arrayBuffer();
129		const splitAt = Number.parseInt(htmlLength, 10);
130		this.body = new TextDecoder().decode(buffer.slice(0, splitAt));
131		this.download = {
132			filename: decodeFilename(this.response.headers.get("X-Live-Download-Filename")),
133			blob: new Blob([buffer.slice(splitAt)], { type: this.response.headers.get("X-Live-Download-Type") ?? "application/octet-stream" })
134		};
135	}
136};
137function decodeFilename(value) {
138	if (!value) return "download";
139	try {
140		return decodeURIComponent(value) || "download";
141	} catch {
142		return "download";
143	}
144}
145function getElementAsTagText(element) {
146	return element.innerHTML ? element.outerHTML.slice(0, element.outerHTML.indexOf(element.innerHTML)) : element.outerHTML;
147}
148let componentMapByElement = /* @__PURE__ */ new WeakMap();
149let componentMapByComponent = /* @__PURE__ */ new Map();
150const registerComponent = (component) => {
151	componentMapByElement.set(component.element, component);
152	componentMapByComponent.set(component, component.name);
153};
154const unregisterComponent = (component) => {
155	componentMapByElement.delete(component.element);
156	componentMapByComponent.delete(component);
157};
158const getComponent = (element) => new Promise((resolve, reject) => {
159	let count = 0;
160	const maxCount = 10;
161	const interval = setInterval(() => {
162		const component = componentMapByElement.get(element);
163		if (component) {
164			clearInterval(interval);
165			resolve(component);
166		}
167		count++;
168		if (count > maxCount) {
169			clearInterval(interval);
170			reject(/* @__PURE__ */ new Error(`Component not found for element ${getElementAsTagText(element)}`));
171		}
172	}, 5);
173});
174const findComponents = (currentComponent, onlyParents, onlyMatchName) => {
175	const components = [];
176	componentMapByComponent.forEach((componentName, component) => {
177		if (onlyParents && (currentComponent === component || !component.element.contains(currentComponent.element))) return;
178		if (onlyMatchName && componentName !== onlyMatchName) return;
179		components.push(component);
180	});
181	return components;
182};
183const findChildren = (currentComponent) => {
184	const children = [];
185	componentMapByComponent.forEach((componentName, component) => {
186		if (currentComponent === component) return;
187		if (!currentComponent.element.contains(component.element)) return;
188		let foundChildComponent = false;
189		componentMapByComponent.forEach((childComponentName, childComponent) => {
190			if (foundChildComponent) return;
191			if (childComponent === component) return;
192			if (childComponent.element.contains(component.element)) foundChildComponent = true;
193		});
194		children.push(component);
195	});
196	return children;
197};
198const findParent = (currentComponent) => {
199	let parentElement = currentComponent.element.parentElement;
200	while (parentElement) {
201		const component = componentMapByElement.get(parentElement);
202		if (component) return component;
203		parentElement = parentElement.parentElement;
204	}
205	return null;
206};
207function parseDirectives(content) {
208	const directives = [];
209	if (!content) return directives;
210	let currentActionName = "";
211	let currentArgumentValue = "";
212	let currentArguments = [];
213	let currentModifiers = [];
214	let state = "action";
215	const getLastActionName = () => {
216		if (currentActionName) return currentActionName;
217		if (directives.length === 0) throw new Error("Could not find any directives");
218		return directives[directives.length - 1].action;
219	};
220	const pushInstruction = () => {
221		directives.push({
222			action: currentActionName,
223			args: currentArguments,
224			modifiers: currentModifiers,
225			getString: () => {
226				return content;
227			}
228		});
229		currentActionName = "";
230		currentArgumentValue = "";
231		currentArguments = [];
232		currentModifiers = [];
233		state = "action";
234	};
235	const pushArgument = () => {
236		currentArguments.push(currentArgumentValue.trim());
237		currentArgumentValue = "";
238	};
239	const pushModifier = () => {
240		if (currentArguments.length > 1) throw new Error(`The modifier "${currentActionName}()" does not support multiple arguments.`);
241		currentModifiers.push({
242			name: currentActionName,
243			value: currentArguments.length > 0 ? currentArguments[0] : null
244		});
245		currentActionName = "";
246		currentArguments = [];
247		state = "action";
248	};
249	for (let i = 0; i < content.length; i++) {
250		const char = content[i];
251		switch (state) {
252			case "action":
253				if (char === "(") {
254					state = "arguments";
255					break;
256				}
257				if (char === " ") {
258					if (currentActionName) pushInstruction();
259					break;
260				}
261				if (char === "|") {
262					pushModifier();
263					break;
264				}
265				currentActionName += char;
266				break;
267			case "arguments":
268				if (char === ")") {
269					pushArgument();
270					state = "after_arguments";
271					break;
272				}
273				if (char === ",") {
274					pushArgument();
275					break;
276				}
277				currentArgumentValue += char;
278				break;
279			case "after_arguments":
280				if (char === "|") {
281					pushModifier();
282					break;
283				}
284				if (char !== " ") throw new Error(`Missing space after ${getLastActionName()}()`);
285				pushInstruction();
286				break;
287		}
288	}
289	switch (state) {
290		case "action":
291		case "after_arguments":
292			if (currentActionName) pushInstruction();
293			break;
294		default: throw new Error(`Did you forget to add a closing ")" after "${currentActionName}"?`);
295	}
296	return directives;
297}
298function combineSpacedArray(parts) {
299	const finalParts = [];
300	parts.forEach((part) => {
301		finalParts.push(...trimAll(part).split(" "));
302	});
303	return finalParts;
304}
305function trimAll(str) {
306	return str.replace(/[\s]+/g, " ").trim();
307}
308function normalizeModelName(model) {
309	if (!model.includes("[") && !model.includes("]")) return model;
310	return model.replace(/\[]$/, "").split("[").map((s) => s.replace("]", "")).join(".");
311}
312function getValueFromElement(element, valueStore) {
313	if (element instanceof HTMLInputElement) {
314		if (element.type === "checkbox") {
315			const modelNameData = getModelDirectiveFromElement(element, false);
316			if (modelNameData !== null) {
317				const modelValue = valueStore.get(modelNameData.action);
318				if (Array.isArray(modelValue)) return getMultipleCheckboxValue(element, modelValue);
319				if (Object(modelValue) === modelValue) return getMultipleCheckboxValue(element, Object.values(modelValue));
320			}
321			if (element.hasAttribute("value")) return element.checked ? element.getAttribute("value") : null;
322			return element.checked;
323		}
324		return inputValue(element);
325	}
326	if (element instanceof HTMLSelectElement) {
327		if (element.multiple) return Array.from(element.selectedOptions).map((el) => el.value);
328		return element.value;
329	}
330	if (element.hasAttribute("data-value")) return element.dataset.value;
331	if ("value" in element) return element.value;
332	if (element.hasAttribute("value")) return element.getAttribute("value");
333	return null;
334}
335function setValueOnElement(element, value) {
336	if (element instanceof HTMLInputElement) {
337		if (element.type === "file") return;
338		if (element.type === "radio") {
339			element.checked = element.value == value;
340			return;
341		}
342		if (element.type === "checkbox") {
343			if (Array.isArray(value)) element.checked = value.some((val) => val == element.value);
344			else if (element.hasAttribute("value")) element.checked = element.value == value;
345			else element.checked = value;
346			return;
347		}
348	}
349	if (element instanceof HTMLSelectElement) {
350		const arrayWrappedValue = [].concat(value).map((value) => {
351			return `${value}`;
352		});
353		Array.from(element.options).forEach((option) => {
354			option.selected = arrayWrappedValue.includes(option.value);
355		});
356		return;
357	}
358	value = value === void 0 ? "" : value;
359	element.value = value;
360}
361function getAllModelDirectiveFromElements(element) {
362	if (!element.dataset.model) return [];
363	const directives = parseDirectives(element.dataset.model);
364	directives.forEach((directive) => {
365		if (directive.args.length > 0) throw new Error(`The data-model="${element.dataset.model}" format is invalid: it does not support passing arguments to the model.`);
366		directive.action = normalizeModelName(directive.action);
367	});
368	return directives;
369}
370function getModelDirectiveFromElement(element, throwOnMissing = true) {
371	const dataModelDirectives = getAllModelDirectiveFromElements(element);
372	if (dataModelDirectives.length > 0) return dataModelDirectives[0];
373	if (element.getAttribute("name")) {
374		const formElement = element.closest("form");
375		if (formElement && "model" in formElement.dataset) {
376			const directive = parseDirectives(formElement.dataset.model || "*")[0];
377			if (directive.args.length > 0) throw new Error(`The data-model="${formElement.dataset.model}" format is invalid: it does not support passing arguments to the model.`);
378			directive.action = normalizeModelName(element.getAttribute("name"));
379			return directive;
380		}
381	}
382	if (!throwOnMissing) return null;
383	throw new Error(`Cannot determine the model name for "${getElementAsTagText(element)}": the element must either have a "data-model" (or "name" attribute living inside a <form data-model="*">).`);
384}
385function elementBelongsToThisComponent(element, component) {
386	if (component.element === element) return true;
387	if (!component.element.contains(element)) return false;
388	return element.closest("[data-controller~=\"live\"]") === component.element;
389}
390function cloneHTMLElement(element) {
391	const newElement = element.cloneNode(true);
392	if (!(newElement instanceof HTMLElement)) throw new Error("Could not clone element");
393	return newElement;
394}
395function htmlToElement(html) {
396	const template = document.createElement("template");
397	html = html.trim();
398	template.innerHTML = html;
399	if (template.content.childElementCount > 1) throw new Error(`Component HTML contains ${template.content.childElementCount} elements, but only 1 root element is allowed.`);
400	const child = template.content.firstElementChild;
401	if (!child) throw new Error("Child not found");
402	if (!(child instanceof HTMLElement)) throw new Error(`Created element is not an HTMLElement: ${html.trim()}`);
403	return child;
404}
405const getMultipleCheckboxValue = (element, currentValues) => {
406	const finalValues = [...currentValues];
407	const value = inputValue(element);
408	const index = currentValues.indexOf(value);
409	if (element.checked) {
410		if (index === -1) finalValues.push(value);
411		return finalValues;
412	}
413	if (index > -1) finalValues.splice(index, 1);
414	return finalValues;
415};
416const inputValue = (element) => element.dataset.value ? element.dataset.value : element.value;
417function isTextualInputElement(el) {
418	return el instanceof HTMLInputElement && [
419		"text",
420		"email",
421		"password",
422		"search",
423		"tel",
424		"url"
425	].includes(el.type);
426}
427function isTextareaElement(el) {
428	return el instanceof HTMLTextAreaElement;
429}
430function isNumericalInputElement(element) {
431	return element instanceof HTMLInputElement && ["number", "range"].includes(element.type);
432}
433var HookManager_default = class {
434	hooks = /* @__PURE__ */ new Map();
435	register(hookName, callback) {
436		const hooks = this.hooks.get(hookName) || [];
437		hooks.push(callback);
438		this.hooks.set(hookName, hooks);
439	}
440	unregister(hookName, callback) {
441		const hooks = this.hooks.get(hookName) || [];
442		const index = hooks.indexOf(callback);
443		if (index === -1) return;
444		hooks.splice(index, 1);
445		this.hooks.set(hookName, hooks);
446	}
447	triggerHook(hookName, ...args) {
448		(this.hooks.get(hookName) || []).forEach((callback) => {
449			callback(...args);
450		});
451	}
452};
453var Idiomorph = (function() {
454	"use strict";
455	const noOp = () => {};
456	const defaults = {
457		morphStyle: "outerHTML",
458		callbacks: {
459			beforeNodeAdded: noOp,
460			afterNodeAdded: noOp,
461			beforeNodeMorphed: noOp,
462			afterNodeMorphed: noOp,
463			beforeNodeRemoved: noOp,
464			afterNodeRemoved: noOp,
465			beforeAttributeUpdated: noOp
466		},
467		head: {
468			style: "merge",
469			shouldPreserve: (elt) => elt.getAttribute("im-preserve") === "true",
470			shouldReAppend: (elt) => elt.getAttribute("im-re-append") === "true",
471			shouldRemove: noOp,
472			afterHeadMorphed: noOp
473		},
474		restoreFocus: true
475	};
476	function morph(oldNode, newContent, config = {}) {
477		oldNode = normalizeElement(oldNode);
478		const newNode = normalizeParent(newContent);
479		const ctx = createMorphContext(oldNode, newNode, config);
480		const morphedNodes = saveAndRestoreFocus(ctx, () => {
481			return withHeadBlocking(ctx, oldNode, newNode, (ctx) => {
482				if (ctx.morphStyle === "innerHTML") {
483					morphChildren(ctx, oldNode, newNode);
484					return Array.from(oldNode.childNodes);
485				} else return morphOuterHTML(ctx, oldNode, newNode);
486			});
487		});
488		ctx.pantry.remove();
489		return morphedNodes;
490	}
491	function morphOuterHTML(ctx, oldNode, newNode) {
492		const oldParent = normalizeParent(oldNode);
493		morphChildren(ctx, oldParent, newNode, oldNode, oldNode.nextSibling);
494		return Array.from(oldParent.childNodes);
495	}
496	function saveAndRestoreFocus(ctx, fn) {
497		if (!ctx.config.restoreFocus) return fn();
498		let activeElement = document.activeElement;
499		if (!(activeElement instanceof HTMLInputElement || activeElement instanceof HTMLTextAreaElement)) return fn();
500		const { id: activeElementId, selectionStart, selectionEnd } = activeElement;
501		const results = fn();
502		if (activeElementId && activeElementId !== document.activeElement?.getAttribute("id")) {
503			activeElement = ctx.target.querySelector(`[id="${activeElementId}"]`);
504			activeElement?.focus();
505		}
506		if (activeElement && !activeElement.selectionEnd && selectionEnd) activeElement.setSelectionRange(selectionStart, selectionEnd);
507		return results;
508	}
509	const morphChildren = (function() {
510		function morphChildren(ctx, oldParent, newParent, insertionPoint = null, endPoint = null) {
511			if (oldParent instanceof HTMLTemplateElement && newParent instanceof HTMLTemplateElement) {
512				oldParent = oldParent.content;
513				newParent = newParent.content;
514			}
515			insertionPoint ||= oldParent.firstChild;
516			for (const newChild of newParent.childNodes) {
517				if (insertionPoint && insertionPoint != endPoint) {
518					const bestMatch = findBestMatch(ctx, newChild, insertionPoint, endPoint);
519					if (bestMatch) {
520						if (bestMatch !== insertionPoint) removeNodesBetween(ctx, insertionPoint, bestMatch);
521						morphNode(bestMatch, newChild, ctx);
522						insertionPoint = bestMatch.nextSibling;
523						continue;
524					}
525				}
526				if (newChild instanceof Element) {
527					const newChildId = newChild.getAttribute("id");
528					if (ctx.persistentIds.has(newChildId)) {
529						const movedChild = moveBeforeById(oldParent, newChildId, insertionPoint, ctx);
530						morphNode(movedChild, newChild, ctx);
531						insertionPoint = movedChild.nextSibling;
532						continue;
533					}
534				}
535				const insertedNode = createNode(oldParent, newChild, insertionPoint, ctx);
536				if (insertedNode) insertionPoint = insertedNode.nextSibling;
537			}
538			while (insertionPoint && insertionPoint != endPoint) {
539				const tempNode = insertionPoint;
540				insertionPoint = insertionPoint.nextSibling;
541				removeNode(ctx, tempNode);
542			}
543		}
544		function createNode(oldParent, newChild, insertionPoint, ctx) {
545			if (ctx.callbacks.beforeNodeAdded(newChild) === false) return null;
546			if (ctx.idMap.has(newChild)) {
547				const newEmptyChild = document.createElement(newChild.tagName);
548				oldParent.insertBefore(newEmptyChild, insertionPoint);
549				morphNode(newEmptyChild, newChild, ctx);
550				ctx.callbacks.afterNodeAdded(newEmptyChild);
551				return newEmptyChild;
552			} else {
553				const newClonedChild = document.importNode(newChild, true);
554				oldParent.insertBefore(newClonedChild, insertionPoint);
555				ctx.callbacks.afterNodeAdded(newClonedChild);
556				return newClonedChild;
557			}
558		}
559		const findBestMatch = (function() {
560			function findBestMatch(ctx, node, startPoint, endPoint) {
561				let softMatch = null;
562				let nextSibling = node.nextSibling;
563				let siblingSoftMatchCount = 0;
564				let cursor = startPoint;
565				while (cursor && cursor != endPoint) {
566					if (isSoftMatch(cursor, node)) {
567						if (isIdSetMatch(ctx, cursor, node)) return cursor;
568						if (softMatch === null) {
569							if (!ctx.idMap.has(cursor)) softMatch = cursor;
570						}
571					}
572					if (softMatch === null && nextSibling && isSoftMatch(cursor, nextSibling)) {
573						siblingSoftMatchCount++;
574						nextSibling = nextSibling.nextSibling;
575						if (siblingSoftMatchCount >= 2) softMatch = void 0;
576					}
577					if (ctx.activeElementAndParents.includes(cursor)) break;
578					cursor = cursor.nextSibling;
579				}
580				return softMatch || null;
581			}
582			function isIdSetMatch(ctx, oldNode, newNode) {
583				let oldSet = ctx.idMap.get(oldNode);
584				let newSet = ctx.idMap.get(newNode);
585				if (!newSet || !oldSet) return false;
586				for (const id of oldSet) if (newSet.has(id)) return true;
587				return false;
588			}
589			function isSoftMatch(oldNode, newNode) {
590				const oldElt = oldNode;
591				const newElt = newNode;
592				return oldElt.nodeType === newElt.nodeType && oldElt.tagName === newElt.tagName && (!oldElt.getAttribute?.("id") || oldElt.getAttribute?.("id") === newElt.getAttribute?.("id"));
593			}
594			return findBestMatch;
595		})();
596		function removeNode(ctx, node) {
597			if (ctx.idMap.has(node)) moveBefore(ctx.pantry, node, null);
598			else {
599				if (ctx.callbacks.beforeNodeRemoved(node) === false) return;
600				node.parentNode?.removeChild(node);
601				ctx.callbacks.afterNodeRemoved(node);
602			}
603		}
604		function removeNodesBetween(ctx, startInclusive, endExclusive) {
605			let cursor = startInclusive;
606			while (cursor && cursor !== endExclusive) {
607				let tempNode = cursor;
608				cursor = cursor.nextSibling;
609				removeNode(ctx, tempNode);
610			}
611			return cursor;
612		}
613		function moveBeforeById(parentNode, id, after, ctx) {
614			const target = ctx.target.getAttribute?.("id") === id && ctx.target || ctx.target.querySelector(`[id="${id}"]`) || ctx.pantry.querySelector(`[id="${id}"]`);
615			removeElementFromAncestorsIdMaps(target, ctx);
616			moveBefore(parentNode, target, after);
617			return target;
618		}
619		function removeElementFromAncestorsIdMaps(element, ctx) {
620			const id = element.getAttribute("id");
621			while (element = element.parentNode) {
622				let idSet = ctx.idMap.get(element);
623				if (idSet) {
624					idSet.delete(id);
625					if (!idSet.size) ctx.idMap.delete(element);
626				}
627			}
628		}
629		function moveBefore(parentNode, element, after) {
630			if (parentNode.moveBefore) try {
631				parentNode.moveBefore(element, after);
632			} catch (e) {
633				parentNode.insertBefore(element, after);
634			}
635			else parentNode.insertBefore(element, after);
636		}
637		return morphChildren;
638	})();
639	const morphNode = (function() {
640		function morphNode(oldNode, newContent, ctx) {
641			if (ctx.ignoreActive && oldNode === document.activeElement) return null;
642			if (ctx.callbacks.beforeNodeMorphed(oldNode, newContent) === false) return oldNode;
643			if (oldNode instanceof HTMLHeadElement && ctx.head.ignore) {} else if (oldNode instanceof HTMLHeadElement && ctx.head.style !== "morph") handleHeadElement(oldNode, newContent, ctx);
644			else {
645				morphAttributes(oldNode, newContent, ctx);
646				if (!ignoreValueOfActiveElement(oldNode, ctx)) morphChildren(ctx, oldNode, newContent);
647			}
648			ctx.callbacks.afterNodeMorphed(oldNode, newContent);
649			return oldNode;
650		}
651		function morphAttributes(oldNode, newNode, ctx) {
652			let type = newNode.nodeType;
653			if (type === 1) {
654				const oldElt = oldNode;
655				const newElt = newNode;
656				const oldAttributes = oldElt.attributes;
657				const newAttributes = newElt.attributes;
658				for (const newAttribute of newAttributes) {
659					if (ignoreAttribute(newAttribute.name, oldElt, "update", ctx)) continue;
660					if (oldElt.getAttribute(newAttribute.name) !== newAttribute.value) oldElt.setAttribute(newAttribute.name, newAttribute.value);
661				}
662				for (let i = oldAttributes.length - 1; 0 <= i; i--) {
663					const oldAttribute = oldAttributes[i];
664					if (!oldAttribute) continue;
665					if (!newElt.hasAttribute(oldAttribute.name)) {
666						if (ignoreAttribute(oldAttribute.name, oldElt, "remove", ctx)) continue;
667						oldElt.removeAttribute(oldAttribute.name);
668					}
669				}
670				if (!ignoreValueOfActiveElement(oldElt, ctx)) syncInputValue(oldElt, newElt, ctx);
671			}
672			if (type === 8 || type === 3) {
673				if (oldNode.nodeValue !== newNode.nodeValue) oldNode.nodeValue = newNode.nodeValue;
674			}
675		}
676		function syncInputValue(oldElement, newElement, ctx) {
677			if (oldElement instanceof HTMLInputElement && newElement instanceof HTMLInputElement && newElement.type !== "file") {
678				let newValue = newElement.value;
679				let oldValue = oldElement.value;
680				syncBooleanAttribute(oldElement, newElement, "checked", ctx);
681				syncBooleanAttribute(oldElement, newElement, "disabled", ctx);
682				if (!newElement.hasAttribute("value")) {
683					if (!ignoreAttribute("value", oldElement, "remove", ctx)) {
684						oldElement.value = "";
685						oldElement.removeAttribute("value");
686					}
687				} else if (oldValue !== newValue) {
688					if (!ignoreAttribute("value", oldElement, "update", ctx)) {
689						oldElement.setAttribute("value", newValue);
690						oldElement.value = newValue;
691					}
692				}
693			} else if (oldElement instanceof HTMLOptionElement && newElement instanceof HTMLOptionElement) syncBooleanAttribute(oldElement, newElement, "selected", ctx);
694			else if (oldElement instanceof HTMLTextAreaElement && newElement instanceof HTMLTextAreaElement) {
695				let newValue = newElement.value;
696				let oldValue = oldElement.value;
697				if (ignoreAttribute("value", oldElement, "update", ctx)) return;
698				if (newValue !== oldValue) oldElement.value = newValue;
699				if (oldElement.firstChild && oldElement.firstChild.nodeValue !== newValue) oldElement.firstChild.nodeValue = newValue;
700			}
701		}
702		function syncBooleanAttribute(oldElement, newElement, attributeName, ctx) {
703			const newLiveValue = newElement[attributeName];
704			if (newLiveValue !== oldElement[attributeName]) {
705				const ignoreUpdate = ignoreAttribute(attributeName, oldElement, "update", ctx);
706				if (!ignoreUpdate) oldElement[attributeName] = newElement[attributeName];
707				if (newLiveValue) {
708					if (!ignoreUpdate) oldElement.setAttribute(attributeName, "");
709				} else if (!ignoreAttribute(attributeName, oldElement, "remove", ctx)) oldElement.removeAttribute(attributeName);
710			}
711		}
712		function ignoreAttribute(attr, element, updateType, ctx) {
713			if (attr === "value" && ctx.ignoreActiveValue && element === document.activeElement) return true;
714			return ctx.callbacks.beforeAttributeUpdated(attr, element, updateType) === false;
715		}
716		function ignoreValueOfActiveElement(possibleActiveElement, ctx) {
717			return !!ctx.ignoreActiveValue && possibleActiveElement === document.activeElement && possibleActiveElement !== document.body;
718		}
719		return morphNode;
720	})();
721	function withHeadBlocking(ctx, oldNode, newNode, callback) {
722		if (ctx.head.block) {
723			const oldHead = oldNode.querySelector("head");
724			const newHead = newNode.querySelector("head");
725			if (oldHead && newHead) {
726				const promises = handleHeadElement(oldHead, newHead, ctx);
727				return Promise.all(promises).then(() => {
728					return callback(Object.assign(ctx, { head: {
729						block: false,
730						ignore: true
731					} }));
732				});
733			}
734		}
735		return callback(ctx);
736	}
737	function handleHeadElement(oldHead, newHead, ctx) {
738		let added = [];
739		let removed = [];
740		let preserved = [];
741		let nodesToAppend = [];
742		let srcToNewHeadNodes = /* @__PURE__ */ new Map();
743		for (const newHeadChild of newHead.children) srcToNewHeadNodes.set(newHeadChild.outerHTML, newHeadChild);
744		for (const currentHeadElt of oldHead.children) {
745			let inNewContent = srcToNewHeadNodes.has(currentHeadElt.outerHTML);
746			let isReAppended = ctx.head.shouldReAppend(currentHeadElt);
747			let isPreserved = ctx.head.shouldPreserve(currentHeadElt);
748			if (inNewContent || isPreserved) if (isReAppended) removed.push(currentHeadElt);
749			else {
750				srcToNewHeadNodes.delete(currentHeadElt.outerHTML);
751				preserved.push(currentHeadElt);
752			}
753			else if (ctx.head.style === "append") {
754				if (isReAppended) {
755					removed.push(currentHeadElt);
756					nodesToAppend.push(currentHeadElt);
757				}
758			} else if (ctx.head.shouldRemove(currentHeadElt) !== false) removed.push(currentHeadElt);
759		}
760		nodesToAppend.push(...srcToNewHeadNodes.values());
761		let promises = [];
762		for (const newNode of nodesToAppend) {
763			let newElt = document.createRange().createContextualFragment(newNode.outerHTML).firstChild;
764			if (ctx.callbacks.beforeNodeAdded(newElt) !== false) {
765				if ("href" in newElt && newElt.href || "src" in newElt && newElt.src) {
766					/** @type {(result?: any) => void} */ let resolve;
767					let promise = new Promise(function(_resolve) {
768						resolve = _resolve;
769					});
770					newElt.addEventListener("load", function() {
771						resolve();
772					});
773					promises.push(promise);
774				}
775				oldHead.appendChild(newElt);
776				ctx.callbacks.afterNodeAdded(newElt);
777				added.push(newElt);
778			}
779		}
780		for (const removedElement of removed) if (ctx.callbacks.beforeNodeRemoved(removedElement) !== false) {
781			oldHead.removeChild(removedElement);
782			ctx.callbacks.afterNodeRemoved(removedElement);
783		}
784		ctx.head.afterHeadMorphed(oldHead, {
785			added,
786			kept: preserved,
787			removed
788		});
789		return promises;
790	}
791	const createMorphContext = (function() {
792		function createMorphContext(oldNode, newContent, config) {
793			const { persistentIds, idMap } = createIdMaps(oldNode, newContent);
794			const mergedConfig = mergeDefaults(config);
795			const morphStyle = mergedConfig.morphStyle || "outerHTML";
796			if (!["innerHTML", "outerHTML"].includes(morphStyle)) throw `Do not understand how to morph style ${morphStyle}`;
797			return {
798				target: oldNode,
799				newContent,
800				config: mergedConfig,
801				morphStyle,
802				ignoreActive: mergedConfig.ignoreActive,
803				ignoreActiveValue: mergedConfig.ignoreActiveValue,
804				restoreFocus: mergedConfig.restoreFocus,
805				idMap,
806				persistentIds,
807				pantry: createPantry(),
808				activeElementAndParents: createActiveElementAndParents(oldNode),
809				callbacks: mergedConfig.callbacks,
810				head: mergedConfig.head
811			};
812		}
813		function mergeDefaults(config) {
814			let finalConfig = Object.assign({}, defaults);
815			Object.assign(finalConfig, config);
816			finalConfig.callbacks = Object.assign({}, defaults.callbacks, config.callbacks);
817			finalConfig.head = Object.assign({}, defaults.head, config.head);
818			return finalConfig;
819		}
820		function createPantry() {
821			const pantry = document.createElement("div");
822			pantry.hidden = true;
823			document.body.insertAdjacentElement("afterend", pantry);
824			return pantry;
825		}
826		function createActiveElementAndParents(oldNode) {
827			let activeElementAndParents = [];
828			let elt = document.activeElement;
829			if (elt?.tagName !== "BODY" && oldNode.contains(elt)) while (elt) {
830				activeElementAndParents.push(elt);
831				if (elt === oldNode) break;
832				elt = elt.parentElement;
833			}
834			return activeElementAndParents;
835		}
836		function findIdElements(root) {
837			let elements = Array.from(root.querySelectorAll("[id]"));
838			if (root.getAttribute?.("id")) elements.push(root);
839			return elements;
840		}
841		function populateIdMapWithTree(idMap, persistentIds, root, elements) {
842			for (const elt of elements) {
843				const id = elt.getAttribute("id");
844				if (persistentIds.has(id)) {
845					let current = elt;
846					while (current) {
847						let idSet = idMap.get(current);
848						if (idSet == null) {
849							idSet = /* @__PURE__ */ new Set();
850							idMap.set(current, idSet);
851						}
852						idSet.add(id);
853						if (current === root) break;
854						current = current.parentElement;
855					}
856				}
857			}
858		}
859		function createIdMaps(oldContent, newContent) {
860			const oldIdElements = findIdElements(oldContent);
861			const newIdElements = findIdElements(newContent);
862			const persistentIds = createPersistentIds(oldIdElements, newIdElements);
863			let idMap = /* @__PURE__ */ new Map();
864			populateIdMapWithTree(idMap, persistentIds, oldContent, oldIdElements);
865			populateIdMapWithTree(idMap, persistentIds, newContent.__idiomorphRoot || newContent, newIdElements);
866			return {
867				persistentIds,
868				idMap
869			};
870		}
871		function createPersistentIds(oldIdElements, newIdElements) {
872			let duplicateIds = /* @__PURE__ */ new Set();
873			let oldIdTagNameMap = /* @__PURE__ */ new Map();
874			for (const { id, tagName } of oldIdElements) if (oldIdTagNameMap.has(id)) duplicateIds.add(id);
875			else oldIdTagNameMap.set(id, tagName);
876			let persistentIds = /* @__PURE__ */ new Set();
877			for (const { id, tagName } of newIdElements) if (persistentIds.has(id)) duplicateIds.add(id);
878			else if (oldIdTagNameMap.get(id) === tagName) persistentIds.add(id);
879			for (const id of duplicateIds) persistentIds.delete(id);
880			return persistentIds;
881		}
882		return createMorphContext;
883	})();
884	const { normalizeElement, normalizeParent } = (function() {
885		const generatedByIdiomorph = /* @__PURE__ */ new WeakSet();
886		function normalizeElement(content) {
887			if (content instanceof Document) return content.documentElement;
888			else return content;
889		}
890		function normalizeParent(newContent) {
891			if (newContent == null) return document.createElement("div");
892			else if (typeof newContent === "string") return normalizeParent(parseContent(newContent));
893			else if (generatedByIdiomorph.has(newContent)) return newContent;
894			else if (newContent instanceof Node) if (newContent.parentNode) return new SlicedParentNode(newContent);
895			else {
896				const dummyParent = document.createElement("div");
897				dummyParent.append(newContent);
898				return dummyParent;
899			}
900			else {
901				const dummyParent = document.createElement("div");
902				for (const elt of [...newContent]) dummyParent.append(elt);
903				return dummyParent;
904			}
905		}
906		class SlicedParentNode {
907			constructor(node) {
908				this.originalNode = node;
909				this.realParentNode = node.parentNode;
910				this.previousSibling = node.previousSibling;
911				this.nextSibling = node.nextSibling;
912			}
913			get childNodes() {
914				const nodes = [];
915				let cursor = this.previousSibling ? this.previousSibling.nextSibling : this.realParentNode.firstChild;
916				while (cursor && cursor != this.nextSibling) {
917					nodes.push(cursor);
918					cursor = cursor.nextSibling;
919				}
920				return nodes;
921			}
922			querySelectorAll(selector) {
923				return this.childNodes.reduce((results, node) => {
924					if (node instanceof Element) {
925						if (node.matches(selector)) results.push(node);
926						const nodeList = node.querySelectorAll(selector);
927						for (let i = 0; i < nodeList.length; i++) results.push(nodeList[i]);
928					}
929					return results;
930				}, []);
931			}
932			insertBefore(node, referenceNode) {
933				return this.realParentNode.insertBefore(node, referenceNode);
934			}
935			moveBefore(node, referenceNode) {
936				return this.realParentNode.moveBefore(node, referenceNode);
937			}
938			get __idiomorphRoot() {
939				return this.originalNode;
940			}
941		}
942		function parseContent(newContent) {
943			let parser = new DOMParser();
944			let contentWithSvgsRemoved = newContent.replace(/<svg(\s[^>]*>|>)([\s\S]*?)<\/svg>/gim, "");
945			if (contentWithSvgsRemoved.match(/<\/html>/) || contentWithSvgsRemoved.match(/<\/head>/) || contentWithSvgsRemoved.match(/<\/body>/)) {
946				let content = parser.parseFromString(newContent, "text/html");
947				if (contentWithSvgsRemoved.match(/<\/html>/)) {
948					generatedByIdiomorph.add(content);
949					return content;
950				} else {
951					let htmlElement = content.firstChild;
952					if (htmlElement) generatedByIdiomorph.add(htmlElement);
953					return htmlElement;
954				}
955			} else {
956				let content = parser.parseFromString("<body><template>" + newContent + "</template></body>", "text/html").body.querySelector("template").content;
957				generatedByIdiomorph.add(content);
958				return content;
959			}
960		}
961		return {
962			normalizeElement,
963			normalizeParent
964		};
965	})();
966	return {
967		morph,
968		defaults
969	};
970})();
971function normalizeAttributesForComparison(element) {
972	if (!(element instanceof HTMLInputElement && element.type === "file")) {
973		if ("value" in element) element.setAttribute("value", element.value);
974		else if (element.hasAttribute("value")) element.setAttribute("value", "");
975	}
976	Array.from(element.children).forEach((child) => {
977		normalizeAttributesForComparison(child);
978	});
979}
980const syncAttributes = (fromEl, toEl) => {
981	for (let i = 0; i < fromEl.attributes.length; i++) {
982		const attr = fromEl.attributes[i];
983		toEl.setAttribute(attr.name, attr.value);
984	}
985};
986const setId = (element, id) => {
987	if (id === null) element.removeAttribute("id");
988	else element.setAttribute("id", id);
989};
990function executeMorphdom(rootFromElement, rootToElement, modifiedFieldElements, getElementValue, externalMutationTracker, childComponents = []) {
991	const externallyChangedIds = /* @__PURE__ */ new Map();
992	try {
993		for (const [element, originalId] of externalMutationTracker.getOriginalIds()) {
994			externallyChangedIds.set(element, element.getAttribute("id"));
995			setId(element, originalId);
996		}
997		for (const { element, id } of childComponents) if (id && element.getAttribute("id") !== id) {
998			externallyChangedIds.set(element, element.getAttribute("id"));
999			setId(element, id);
1000		}
1001		const originalElementIdsToSwapAfter = [];
1002		const originalElementsToPreserve = /* @__PURE__ */ new Map();
1003		const markElementAsNeedingPostMorphSwap = (id, replaceWithClone) => {
1004			const oldElement = originalElementsToPreserve.get(id);
1005			if (!(oldElement instanceof HTMLElement)) throw new Error(`Original element with id ${id} not found`);
1006			originalElementIdsToSwapAfter.push(id);
1007			if (!replaceWithClone) return null;
1008			const clonedOldElement = cloneHTMLElement(oldElement);
1009			oldElement.replaceWith(clonedOldElement);
1010			return clonedOldElement;
1011		};
1012		rootToElement.querySelectorAll("[data-live-preserve]").forEach((newElement) => {
1013			const id = newElement.id;
1014			if (!id) throw new Error("The data-live-preserve attribute requires an id attribute to be set on the element");
1015			const oldElement = rootFromElement.querySelector(`#${id}`);
1016			if (!(oldElement instanceof HTMLElement)) throw new Error(`The element with id "${id}" was not found in the original HTML`);
1017			newElement.removeAttribute("data-live-preserve");
1018			originalElementsToPreserve.set(id, oldElement);
1019			syncAttributes(newElement, oldElement);
1020		});
1021		Idiomorph.morph(rootFromElement, rootToElement, { callbacks: {
1022			beforeNodeMorphed: (fromEl, toEl) => {
1023				if (!(fromEl instanceof Element) || !(toEl instanceof Element)) return true;
1024				if (fromEl === rootFromElement) return true;
1025				if (fromEl.id && originalElementsToPreserve.has(fromEl.id)) {
1026					if (fromEl.id === toEl.id) return false;
1027					const clonedFromEl = markElementAsNeedingPostMorphSwap(fromEl.id, true);
1028					if (!clonedFromEl) throw new Error("missing clone");
1029					Idiomorph.morph(clonedFromEl, toEl);
1030					return false;
1031				}
1032				if (fromEl instanceof HTMLElement && toEl instanceof HTMLElement) {
1033					if (typeof fromEl.__x !== "undefined") {
1034						if (!window.Alpine) throw new Error("Unable to access Alpine.js though the global window.Alpine variable. Please make sure Alpine.js is loaded before Symfony UX LiveComponent.");
1035						if (typeof window.Alpine.morph !== "function") throw new Error("Unable to access Alpine.js morph function. Please make sure the Alpine.js Morp
1035h plugin is installed and loaded, see https://alpinejs.dev/plugins/morph for more information.");
1036						window.Alpine.morph(fromEl.__x, toEl);
1037					}
1038					if (externalMutationTracker.wasElementAdded(fromEl)) {
1039						const id = fromEl.getAttribute("id");
1040						if (id && id === toEl.getAttribute("id")) return false;
1041						toEl.before(document.createComment(""));
1042						return false;
1043					}
1044					if (modifiedFieldElements.includes(fromEl)) setValueOnElement(toEl, getElementValue(fromEl));
1045					if (fromEl === document.activeElement && fromEl !== document.body && null !== getModelDirectiveFromElement(fromEl, false)) setValueOnElement(toEl, getElementValue(fromEl));
1046					const elementChanges = externalMutationTracker.getChangedElement(fromEl);
1047					if (elementChanges) {
1048						const serverId = toEl.getAttribute("id");
1049						elementChanges.applyToElement(toEl);
1050						if (externallyChangedIds.has(fromEl)) setId(toEl, serverId);
1051					}
1052					if (fromEl.nodeName.toUpperCase() !== "OPTION" && fromEl.isEqualNode(toEl)) {
1053						const normalizedFromEl = cloneHTMLElement(fromEl);
1054						normalizeAttributesForComparison(normalizedFromEl);
1055						const normalizedToEl = cloneHTMLElement(toEl);
1056						normalizeAttributesForComparison(normalizedToEl);
1057						if (normalizedFromEl.isEqualNode(normalizedToEl)) return false;
1058					}
1059				}
1060				if (fromEl.hasAttribute("data-skip-morph") || fromEl.id && fromEl.id !== toEl.id) {
1061					fromEl.innerHTML = toEl.innerHTML;
1062					return true;
1063				}
1064				if (fromEl.parentElement?.hasAttribute("data-skip-morph")) return false;
1065				return !fromEl.hasAttribute("data-live-ignore");
1066			},
1067			beforeNodeRemoved(node) {
1068				if (!(node instanceof HTMLElement)) return true;
1069				if (node.id && originalElementsToPreserve.has(node.id)) {
1070					markElementAsNeedingPostMorphSwap(node.id, false);
1071					return true;
1072				}
1073				if (externalMutationTracker.wasElementAdded(node)) return false;
1074				return !node.hasAttribute("data-live-ignore");
1075			}
1076		} });
1077		originalElementIdsToSwapAfter.forEach((id) => {
1078			const newElement = rootFromElement.querySelector(`#${id}`);
1079			const originalElement = originalElementsToPreserve.get(id);
1080			if (!(newElement instanceof HTMLElement) || !(originalElement instanceof HTMLElement)) throw new Error("Missing elements.");
1081			newElement.replaceWith(originalElement);
1082		});
1083	} finally {
1084		for (const [element, id] of externallyChangedIds) setId(element, id);
1085	}
1086}
1087var ChangingItemsTracker_default = class {
1088	changedItems = /* @__PURE__ */ new Map();
1089	removedItems = /* @__PURE__ */ new Map();
1090	setItem(itemName, newValue, previousValue) {
1091		if (this.removedItems.has(itemName)) {
1092			const removedRecord = this.removedItems.get(itemName);
1093			this.removedItems.delete(itemName);
1094			if (removedRecord.original === newValue) return;
1095		}
1096		if (this.changedItems.has(itemName)) {
1097			const originalRecord = this.changedItems.get(itemName);
1098			if (originalRecord.original === newValue) {
1099				this.changedItems.delete(itemName);
1100				return;
1101			}
1102			this.changedItems.set(itemName, {
1103				original: originalRecord.original,
1104				new: newValue
1105			});
1106			return;
1107		}
1108		this.changedItems.set(itemName, {
1109			original: previousValue,
1110			new: newValue
1111		});
1112	}
1113	removeItem(itemName, currentValue) {
1114		let trueOriginalValue = currentValue;
1115		if (this.changedItems.has(itemName)) {
1116			trueOriginalValue = this.changedItems.get(itemName).original;
1117			this.changedItems.delete(itemName);
1118			if (trueOriginalValue === null) return;
1119		}
1120		if (!this.removedItems.has(itemName)) this.removedItems.set(itemName, { original: trueOriginalValue });
1121	}
1122	getChangedItems() {
1123		return Array.from(this.changedItems, ([name, { new: value }]) => ({
1124			name,
1125			value
1126		}));
1127	}
1128	getRemovedItems() {
1129		return Array.from(this.removedItems.keys());
1130	}
1131	isEmpty() {
1132		return this.changedItems.size === 0 && this.removedItems.size === 0;
1133	}
1134};
1135var ElementChanges = class {
1136	addedClasses = /* @__PURE__ */ new Set();
1137	removedClasses = /* @__PURE__ */ new Set();
1138	styleChanges = new ChangingItemsTracker_default();
1139	attributeChanges = new ChangingItemsTracker_default();
1140	addClass(className) {
1141		if (!this.removedClasses.delete(className)) this.addedClasses.add(className);
1142	}
1143	removeClass(className) {
1144		if (!this.addedClasses.delete(className)) this.removedClasses.add(className);
1145	}
1146	addStyle(styleName, newValue, originalValue) {
1147		this.styleChanges.setItem(styleName, newValue, originalValue);
1148	}
1149	removeStyle(styleName, originalValue) {
1150		this.styleChanges.removeItem(styleName, originalValue);
1151	}
1152	addAttribute(attributeName, newValue, originalValue) {
1153		this.attributeChanges.setItem(attributeName, newValue, originalValue);
1154	}
1155	removeAttribute(attributeName, originalValue) {
1156		this.attributeChanges.removeItem(attributeName, originalValue);
1157	}
1158	getAddedClasses() {
1159		return [...this.addedClasses];
1160	}
1161	getRemovedClasses() {
1162		return [...this.removedClasses];
1163	}
1164	getChangedStyles() {
1165		return this.styleChanges.getChangedItems();
1166	}
1167	getRemovedStyles() {
1168		return this.styleChanges.getRemovedItems();
1169	}
1170	getChangedAttributes() {
1171		return this.attributeChanges.getChangedItems();
1172	}
1173	getRemovedAttributes() {
1174		return this.attributeChanges.getRemovedItems();
1175	}
1176	applyToElement(element) {
1177		element.classList.add(...this.addedClasses);
1178		element.classList.remove(...this.removedClasses);
1179		this.styleChanges.getChangedItems().forEach((change) => {
1180			if (/!\s*important/i.test(change.value)) element.style.setProperty(change.name, change.value.replace(/!\s*important/i, "").trim(), "important");
1181			else element.style.setProperty(change.name, change.value);
1182		});
1183		this.styleChanges.getRemovedItems().forEach((styleName) => {
1184			element.style.removeProperty(styleName);
1185		});
1186		this.attributeChanges.getChangedItems().forEach((change) => {
1187			element.setAttribute(change.name, change.value);
1188		});
1189		this.attributeChanges.getRemovedItems().forEach((attributeName) => {
1190			element.removeAttribute(attributeName);
1191		});
1192	}
1193	isEmpty() {
1194		return this.addedClasses.size === 0 && this.removedClasses.size === 0 && this.styleChanges.isEmpty() && this.attributeChanges.isEmpty();
1195	}
1196};
1197var ExternalMutationTracker_default = class {
1198	element;
1199	shouldTrackChangeCallback;
1200	mutationObserver;
1201	changedElements = /* @__PURE__ */ new WeakMap();
1202	changedElementsCount = 0;
1203	addedElements = [];
1204	removedElements = [];
1205	isStarted = false;
1206	originalIds = /* @__PURE__ */ new Map();
1207	constructor(element, shouldTrackChangeCallback) {
1208		this.element = element;
1209		this.shouldTrackChangeCallback = shouldTrackChangeCallback;
1210		this.mutationObserver = new MutationObserver(this.onMutations.bind(this));
1211	}
1212	start() {
1213		if (this.isStarted) return;
1214		this.mutationObserver.observe(this.element, {
1215			childList: true,
1216			subtree: true,
1217			attributes: true,
1218			attributeOldValue: true
1219		});
1220		this.isStarted = true;
1221	}
1222	stop() {
1223		if (this.isStarted) {
1224			this.mutationObserver.disconnect();
1225			this.isStarted = false;
1226		}
1227	}
1228	getChangedElement(element) {
1229		return this.changedElements.has(element) ? this.changedElements.get(element) : null;
1230	}
1231	getOriginalIds() {
1232		for (const element of this.originalIds.keys()) if (!this.element.contains(element)) this.originalIds.delete(element);
1233		return this.originalIds;
1234	}
1235	getAddedElements() {
1236		return this.addedElements;
1237	}
1238	wasElementAdded(element) {
1239		return this.addedElements.includes(element);
1240	}
1241	handlePendingChanges() {
1242		this.onMutations(this.mutationObserver.takeRecords());
1243	}
1244	onMutations(mutations) {
1245		const handledAttributeMutations = /* @__PURE__ */ new WeakMap();
1246		for (const mutation of mutations) {
1247			const element = mutation.target;
1248			if (!this.shouldTrackChangeCallback(element)) continue;
1249			if (this.isElementAddedByTranslation(element)) continue;
1250			let isChangeInAddedElement = false;
1251			for (const addedElement of this.addedElements) if (addedElement.contains(element)) {
1252				isChangeInAddedElement = true;
1253				break;
1254			}
1255			if (isChangeInAddedElement) continue;
1256			switch (mutation.type) {
1257				case "childList":
1258					this.handleChildListMutation(mutation);
1259					break;
1260				case "attributes":
1261					if (!handledAttributeMutations.has(element)) handledAttributeMutations.set(element, []);
1262					if (!handledAttributeMutations.get(element).includes(mutation.attributeName)) {
1263						this.handleAttributeMutation(mutation);
1264						handledAttributeMutations.set(element, [...handledAttributeMutations.get(element), mutation.attributeName]);
1265					}
1266					break;
1267			}
1268		}
1269	}
1270	handleChildListMutation(mutation) {
1271		mutation.addedNodes.forEach((node) => {
1272			if (!(node instanceof Element)) return;
1273			if (this.removedElements.includes(node)) {
1274				this.removedElements.splice(this.removedElements.indexOf(node), 1);
1275				return;
1276			}
1277			if (this.isElementAddedByTranslation(node)) return;
1278			this.addedElements.push(node);
1279		});
1280		mutation.removedNodes.forEach((node) => {
1281			if (!(node instanceof Element)) return;
1282			if (this.addedElements.includes(node)) {
1283				this.addedElements.splice(this.addedElements.indexOf(node), 1);
1284				return;
1285			}
1286			this.removedElements.push(node);
1287		});
1288	}
1289	handleAttributeMutation(mutation) {
1290		const element = mutation.target;
1291		if (!this.changedElements.has(element)) {
1292			this.changedElements.set(element, new ElementChanges());
1293			this.changedElementsCount++;
1294		}
1295		const changedElement = this.changedElements.get(element);
1296		switch (mutation.attributeName) {
1297			case "class":
1298				this.handleClassAttributeMutation(mutation, changedElement);
1299				break;
1300			case "style":
1301				this.handleStyleAttributeMutation(mutation, changedElement);
1302				break;
1303			default: this.handleGenericAttributeMutation(mutation, changedElement);
1304		}
1305		if (changedElement.isEmpty()) {
1306			this.changedElements.delete(element);
1307			this.changedElementsCount--;
1308		}
1309	}
1310	handleClassAttributeMutation(mutation, elementChanges) {
1311		const element = mutation.target;
1312		const previousValues = (mutation.oldValue || "").match(/(\S+)/gu) || [];
1313		const newValues = [].slice.call(element.classList);
1314		const addedValues = newValues.filter((value) => !previousValues.includes(value));
1315		const removedValues = previousValues.filter((value) => !newValues.includes(value));
1316		addedValues.forEach((value) => {
1317			elementChanges.addClass(value);
1318		});
1319		removedValues.forEach((value) => {
1320			elementChanges.removeClass(value);
1321		});
1322	}
1323	handleStyleAttributeMutation(mutation, elementChanges) {
1324		const element = mutation.target;
1325		const previousValue = mutation.oldValue || "";
1326		const previousStyles = this.extractStyles(previousValue);
1327		const newValue = element.getAttribute("style") || "";
1328		const newStyles = this.extractStyles(newValue);
1329		const addedOrChangedStyles = Object.keys(newStyles).filter((key) => previousStyles[key] === void 0 || previousStyles[key] !== newStyles[key]);
1330		const removedStyles = Object.keys(previousStyles).filter((key) => !newStyles[key]);
1331		addedOrChangedStyles.forEach((style) => {
1332			elementChanges.addStyle(style, newStyles[style], previousStyles[style] === void 0 ? null : previousStyles[style]);
1333		});
1334		removedStyles.forEach((style) => {
1335			elementChanges.removeStyle(style, previousStyles[style]);
1336		});
1337	}
1338	handleGenericAttributeMutation(mutation, elementChanges) {
1339		const attributeName = mutation.attributeName;
1340		const element = mutation.target;
1341		if (attributeName === "id") {
1342			if (!this.originalIds.has(element)) this.originalIds.set(element, mutation.oldValue);
1343			if (element.getAttribute("id") === this.originalIds.get(element)) this.originalIds.delete(element);
1344		}
1345		let oldValue = mutation.oldValue;
1346		let newValue = element.getAttribute(attributeName);
1347		if (oldValue === attributeName) oldValue = "";
1348		if (newValue === attributeName) newValue = "";
1349		if (!element.hasAttribute(attributeName)) {
1350			if (oldValue === null) return;
1351			elementChanges.removeAttribute(attributeName, mutation.oldValue);
1352			return;
1353		}
1354		if (newValue === oldValue) return;
1355		elementChanges.addAttribute(attributeName, element.getAttribute(attributeName), mutation.oldValue);
1356	}
1357	extractStyles(styles) {
1358		const styleObject = {};
1359		styles.split(";").forEach((style) => {
1360			const parts = style.split(":");
1361			if (parts.length === 1) return;
1362			const property = parts[0].trim();
1363			styleObject[property] = parts.slice(1).join(":").trim();
1364		});
1365		return styleObject;
1366	}
1367	isElementAddedByTranslation(element) {
1368		return element.tagName === "FONT" && element.getAttribute("style") === "vertical-align: inherit;";
1369	}
1370};
1371var UnsyncedInputsTracker_default = class {
1372	component;
1373	modelElementResolver;
1374	unsyncedInputs;
1375	elementEventListeners = [{
1376		event: "input",
1377		callback: (event) => this.handleInputEvent(event)
1378	}];
1379	constructor(component, modelElementResolver) {
1380		this.component = component;
1381		this.modelElementResolver = modelElementResolver;
1382		this.unsyncedInputs = new UnsyncedInputContainer();
1383	}
1384	activate() {
1385		this.elementEventListeners.forEach(({ event, callback }) => {
1386			this.component.element.addEventListener(event, callback);
1387		});
1388	}
1389	deactivate() {
1390		this.elementEventListeners.forEach(({ event, callback }) => {
1391			this.component.element.removeEventListener(event, callback);
1392		});
1393	}
1394	markModelAsSynced(modelName) {
1395		this.unsyncedInputs.markModelAsSynced(modelName);
1396	}
1397	handleInputEvent(event) {
1398		const target = event.target;
1399		if (!target) return;
1400		this.updateModelFromElement(target);
1401	}
1402	updateModelFromElement(element) {
1403		if (!elementBelongsToThisComponent(element, this.component)) return;
1404		if (!(element instanceof HTMLElement)) throw new Error("Could not update model for non HTMLElement");
1405		const modelName = this.modelElementResolver.getModelName(element);
1406		this.unsyncedInputs.add(element, modelName);
1407	}
1408	getUnsyncedInputs() {
1409		return this.unsyncedInputs.allUnsyncedInputs();
1410	}
1411	getUnsyncedModels() {
1412		return Array.from(this.unsyncedInputs.getUnsyncedModelNames());
1413	}
1414	resetUnsyncedFields() {
1415		this.unsyncedInputs.resetUnsyncedFields();
1416	}
1417};
1418var UnsyncedInputContainer = class {
1419	unsyncedModelFields;
1420	unsyncedNonModelFields = [];
1421	unsyncedModelNames = [];
1422	constructor() {
1423		this.unsyncedModelFields = /* @__PURE__ */ new Map();
1424	}
1425	add(element, modelName = null) {
1426		if (modelName) {
1427			this.unsyncedModelFields.set(modelName, element);
1428			if (!this.unsyncedModelNames.includes(modelName)) this.unsyncedModelNames.push(modelName);
1429			return;
1430		}
1431		this.unsyncedNonModelFields.push(element);
1432	}
1433	resetUnsyncedFields() {
1434		this.unsyncedModelFields.forEach((value, key) => {
1435			if (!this.unsyncedModelNames.includes(key)) this.unsyncedModelFields.delete(key);
1436		});
1437	}
1438	allUnsyncedInputs() {
1439		return [...this.unsyncedNonModelFields, ...this.unsyncedModelFields.values()];
1440	}
1441	markModelAsSynced(modelName) {
1442		const index = this.unsyncedModelNames.indexOf(modelName);
1443		if (index !== -1) this.unsyncedModelNames.splice(index, 1);
1444	}
1445	getUnsyncedModelNames() {
1446		return this.unsyncedModelNames;
1447	}
1448};
1449function getDeepData(data, propertyPath) {
1450	const { currentLevelData, finalKey } = parseDeepData(data, propertyPath);
1451	if (currentLevelData === void 0) return;
1452	return currentLevelData[finalKey];
1453}
1454const parseDeepData = (data, propertyPath) => {
1455	const finalData = JSON.parse(JSON.stringify(data));
1456	let currentLevelData = finalData;
1457	const parts = propertyPath.split(".");
1458	for (let i = 0; i < parts.length - 1; i++) currentLevelData = currentLevelData[parts[i]];
1459	const finalKey = parts[parts.length - 1];
1460	return {
1461		currentLevelData,
1462		finalData,
1463		finalKey,
1464		parts
1465	};
1466};
1467var ValueStore_default = class {
1468	props = {};
1469	dirtyProps = {};
1470	pendingProps = {};
1471	updatedPropsFromParent = {};
1472	constructor(props) {
1473		this.props = props;
1474	}
1475	get(name) {
1476		const normalizedName = normalizeModelName(name);
1477		if (this.dirtyProps[normalizedName] !== void 0) return this.dirtyProps[normalizedName];
1478		if (this.pendingProps[normalizedName] !== void 0) return this.pendingProps[normalizedName];
1479		if (this.props[normalizedName] !== void 0) return this.props[normalizedName];
1480		return getDeepData(this.props, normalizedName);
1481	}
1482	has(name) {
1483		return this.get(name) !== void 0;
1484	}
1485	set(name, value) {
1486		const normalizedName = normalizeModelName(name);
1487		if (this.get(normalizedName) === value) return false;
1488		this.dirtyProps[normalizedName] = value;
1489		return true;
1490	}
1491	getOriginalProps() {
1492		return { ...this.props };
1493	}
1494	getDirtyProps() {
1495		return { ...this.dirtyProps };
1496	}
1497	getUpdatedPropsFromParent() {
1498		return { ...this.updatedPropsFromParent };
1499	}
1500	flushDirtyPropsToPending() {
1501		this.pendingProps = { ...this.dirtyProps };
1502		this.dirtyProps = {};
1503	}
1504	reinitializeAllProps(props) {
1505		this.props = props;
1506		this.updatedPropsFromParent = {};
1507		this.pendingProps = {};
1508	}
1509	pushPendingPropsBackToDirty() {
1510		this.dirtyProps = {
1511			...this.pendingProps,
1512			...this.dirtyProps
1513		};
1514		this.pendingProps = {};
1515	}
1516	storeNewPropsFromParent(props) {
1517		let changed = false;
1518		for (const [key, value] of Object.entries(props)) if (this.get(key) !== value) changed = true;
1519		if (changed) this.updatedPropsFromParent = props;
1520		return changed;
1521	}
1522};
1523var Component = class {
1524	element;
1525	name;
1526	listeners;
1527	backend;
1528	elementDriver;
1529	id;
1530	fingerprint = "";
1531	valueStore;
1532	unsyncedInputsTracker;
1533	hooks;
1534	defaultDebounce = 150;
1535	backendRequest = null;
1536	pendingActions = [];
1537	pendingFiles = {};
1538	isRequestPending = false;
1539	isRemoved = false;
1540	requestDebounceTimeout = null;
1541	nextRequestPromise;
1542	nextRequestPromiseResolve;
1543	externalMutationTracker;
1544	constructor(element, name, props, listeners, id, backend, elementDriver) {
1545		this.element = element;
1546		this.name = name;
1547		this.backend = backend;
1548		this.elementDriver = elementDriver;
1549		this.id = id;
1550		this.listeners = /* @__PURE__ */ new Map();
1551		listeners.forEach((listener) => {
1552			if (!this.listeners.has(listener.event)) this.listeners.set(listener.event, []);
1553			this.listeners.get(listener.event)?.push(listener.action);
1554		});
1555		this.valueStore = new ValueStore_default(props);
1556		this.unsyncedInputsTracker = new UnsyncedInputsTracker_default(this, elementDriver);
1557		this.hooks = new HookManager_default();
1558		this.resetPromise();
1559		this.externalMutationTracker = new ExternalMutationTracker_default(this.element, (element) => elementBelongsToThisComponent(element, this));
1560		this.externalMutationTracker.start();
1561	}
1562	getOriginalId() {
1563		this.externalMutationTracker.handlePendingChanges();
1564		const originalIds = this.externalMutationTracker.getOriginalIds();
1565		return originalIds.has(this.element) ? originalIds.get(this.element) : this.element.getAttribute("id");
1566	}
1567	addPlugin(plugin) {
1568		plugin.attachToComponent(this);
1569	}
1570	connect() {
1571		registerComponent(this);
1572		this.hooks.triggerHook("connect", this);
1573		this.unsyncedInputsTracker.activate();
1574		this.externalMutationTracker.start();
1575	}
1576	disconnect() {
1577		unregisterComponent(this);
1578		this.hooks.triggerHook("disconnect", this);
1579		this.clearRequestDebounceTimeout();
1580		this.unsyncedInputsTracker.deactivate();
1581		this.externalMutationTracker.stop();
1582	}
1583	on(hookName, callback) {
1584		this.hooks.register(hookName, callback);
1585	}
1586	off(hookName, callback) {
1587		this.hooks.unregister(hookName, callback);
1588	}
1589	set(model, value, reRender = false, debounce = false) {
1590		const promise = this.nextRequestPromise;
1591		const modelName = normalizeModelName(model);
1592		if (!this.valueStore.has(modelName)) throw new Error(`Invalid model name "${model}".`);
1593		const isChanged = this.valueStore.set(modelName, value);
1594		this.hooks.triggerHook("model:set", model, value, this);
1595		this.unsyncedInputsTracker.markModelAsSynced(modelName);
1596		if (reRender && isChanged) this.debouncedStartRequest(debounce);
1597		return promise;
1598	}
1599	getData(model) {
1600		const modelName = normalizeModelName(model);
1601		if (!this.valueStore.has(modelName)) throw new Error(`Invalid model "${model}".`);
1602		return this.valueStore.get(modelName);
1603	}
1604	action(name, args = {}, debounce = false) {
1605		const promise = this.nextRequestPromise;
1606		this.pendingActions.push({
1607			name,
1608			args
1609		});
1610		this.debouncedStartRequest(debounce);
1611		return promise;
1612	}
1613	files(key, input) {
1614		this.pendingFiles[key] = input;
1615	}
1616	render() {
1617		const promise = this.nextRequestPromise;
1618		this.tryStartingRequest();
1619		return promise;
1620	}
1621	getUnsyncedModels() {
1622		return this.unsyncedInputsTracker.getUnsyncedModels();
1623	}
1624	emit(name, data, onlyMatchingComponentsNamed = null) {
1625		this.performEmit(name, data, false, onlyMatchingComponentsNamed);
1626	}
1627	emitUp(name, data, onlyMatchingComponentsNamed = null) {
1628		this.performEmit(name, data, true, onlyMatchingComponentsNamed);
1629	}
1630	emitSelf(name, data) {
1631		this.doEmit(name, data);
1632	}
1633	performEmit(name, data, emitUp, matchingName) {
1634		findComponents(this, emitUp, matchingName).forEach((component) => {
1635			component.doEmit(name, data);
1636		});
1637	}
1638	doEmit(name, data) {
1639		if (!this.listeners.has(name)) return;
1640		(this.listeners.get(name) || []).forEach((action) => {
1641			this.action(action, data, 1);
1642		});
1643	}
1644	isTurboEnabled() {
1645		return typeof Turbo !== "undefined" && !this.element.closest("[data-turbo=\"false\"]");
1646	}
1647	removeFromPage() {
1648		this.isRemoved = true;
1649		this.disconnect();
1650		const element = this.element;
1651		for (const name of element.getAttributeNames()) if (name.startsWith("data-live-") && name.endsWith("-value")) element.removeAttribute(name);
1652		element.setAttribute("data-live-removing", "");
1653		requestAnimationFrame(() => {
1654			const animations = (element.getAnimations?.({ subtree: true }) ?? []).filter((animation) => animation.effect?.getComputedTiming().endTime !== Number.POSITIVE_INFINITY);
1655			Promise.allSettled(animations.map((animation) => animation.finished)).then(() => {
1656				element.remove();
1657			});
1658		});
1659	}
1660	tryStartingRequest() {
1661		if (this.isRemoved) return;
1662		if (!this.backendRequest) {
1663			this.performRequest();
1664			return;
1665		}
1666		this.isRequestPending = true;
1667	}
1668	performRequest() {
1669		const thisPromiseResolve = this.nextRequestPromiseResolve;
1670		this.resetPromise();
1671		this.unsyncedInputsTracker.resetUnsyncedFields();
1672		const filesToSend = {};
1673		for (const [key, value] of Object.entries(this.pendingFiles)) if (value.files) filesToSend[key] = value.files;
1674		const actionsToSend = this.pendingActions.slice(0, 50);
1675		const remainingActions = this.pendingActions.slice(50);
1676		const requestConfig = {
1677			props: this.valueStore.getOriginalProps(),
1678			actions: actionsToSend,
1679			updated: this.valueStore.getDirtyProps(),
1680			children: {},
1681			updatedPropsFromParent: this.valueStore.getUpdatedPropsFromParent(),
1682			files: filesToSend
1683		};
1684		this.hooks.triggerHook("request:started", requestConfig);
1685		this.backendRequest = this.backend.makeRequest(requestConfig.props, requestConfig.actions, requestConfig.updated, requestConfig.children, requestConfig.updatedPropsFromParent, requestConfig.files);
1686		this.hooks.triggerHook("loading.state:started", this.element, this.backendRequest);
1687		this.pendingActions = remainingActions;
1688		this.valueStore.flushDirtyPropsToPending();
1689		this.isRequestPending = remainingActions.length > 0;
1690		this.backendRequest.promise.then(async (response) => {
1691			const backendResponse = new BackendResponse_default(response);
1692			const headers = backendResponse.response.headers;
1693			for (const input of Object.values(this.pendingFiles)) input.value = "";
1694			const html = await backendResponse.getBody();
1695			if (!headers.get("Content-Type")?.includes("application/vnd.live-component+html") && !headers.get("X-Live-Redirect") && !headers.has("X-Live-Remove")) {
1696				const controls = { displayError: true };
1697				this.valueStore.pushPendingPropsBackToDirty();
1698				this.hooks.triggerHook("response:error", backendResponse, controls);
1699				if (controls.displayError) this.renderError(html);
1700				this.backendRequest = null;
1701				thisPromiseResolve(backendResponse);
1702				return response;
1703			}
1704			if (backendResponse.isRemoved()) {
1705				this.isRemoved = true;
1706				this.processRerender(html, backendResponse);
1707				this.backendRequest = null;
1708				thisPromiseResolve(backendResponse);
1709				this.removeFromPage();
1710				return response;
1711			}
1712			const liveUrl = backendResponse.getLiveUrl();
1713			if (liveUrl) history.replaceState(history.state, "", new URL(liveUrl + window.location.hash, window.location.origin));
1714			this.processRerender(html, backendResponse);
1715			this.backendRequest = null;
1716			thisPromiseResolve(backendResponse);
1717			if (this.isRequestPending) {
1718				this.isRequestPending = false;
1719				this.performRequest();
1720			}
1721			return response;
1722		});
1723	}
1724	processRerender(html, backendResponse) {
1725		const controls = { shouldRender: true };
1726		this.hooks.triggerHook("render:started", html, backendResponse, controls);
1727		if (!controls.shouldRender) return;
1728		if (backendResponse.response.headers.get("Location")) {
1729			if (this.isTurboEnabled()) Turbo.visit(backendResponse.response.headers.get("Location"));
1730			else window.location.href = backendResponse.response.headers.get("Location") || "";
1731			return;
1732		}
1733		this.hooks.triggerHook("loading.state:finished", this.element);
1734		const modifiedModelValues = {};
1735		Object.keys(this.valueStore.getDirtyProps()).forEach((modelName) => {
1736			modifiedModelValues[modelName] = this.valueStore.get(modelName);
1737		});
1738		let newElement;
1739		try {
1740			newElement = htmlToElement(html);
1741			if (!newElement.matches("[data-controller~=live]")) throw new Error("A live component template must contain a single root controller element.");
1742		} catch (error) {
1743			console.error(`There was a problem with the '${this.name}' component HTML returned:`, { id: this.id });
1744			throw error;
1745		}
1746		this.externalMutationTracker.handlePendingChanges();
1747		this.externalMutationTracker.stop();
1748		executeMorphdom(this.element, newElement, this.unsyncedInputsTracker.getUnsyncedInputs(), (element) => getValueFromElement(element, this.valueStore), this.externalMutationTracker, findChildren(this));
1749		this.externalMutationTracker.start();
1750		const newProps = this.elementDriver.getComponentProps();
1751		this.valueStore.reinitializeAllProps(newProps);
1752		const eventsToEmit = this.elementDriver.getEventsToEmit();
1753		const browserEventsToDispatch = this.elementDriver.getBrowserEventsToDispatch();
1754		Object.keys(modifiedModelValues).forEach((modelName) => {
1755			this.valueStore.set(modelName, modifiedModelValues[modelName]);
1756		});
1757		eventsToEmit.forEach(({ event, data, target, componentName }) => {
1758			if (target === "up") {
1759				this.emitUp(event, data, componentName);
1760				return;
1761			}
1762			if (target === "self") {
1763				this.emitSelf(event, data);
1764				return;
1765			}
1766			this.emit(event, data, componentName);
1767		});
1768		browserEventsToDispatch.forEach(({ event, payload }) => {
1769			this.element.dispatchEvent(new CustomEvent(event, {
1770				detail: payload,
1771				bubbles: true
1772			}));
1773		});
1774		try {
1775			const downloadUrl = backendResponse.getDownloadUrl();
1776			const download = backendResponse.getDownload();
1777			if (downloadUrl) triggerDownload({ url: downloadUrl });
1778			else if (download) triggerDownload(download);
1779		} catch (error) {
1780			console.error("Could not start the download:", error);
1781		}
1782		this.hooks.triggerHook("render:finished", this);
1783	}
1784	calculateDebounce(debounce) {
1785		if (debounce === true) return this.defaultDebounce;
1786		if (debounce === false) return 0;
1787		return debounce;
1788	}
1789	clearRequestDebounceTimeout() {
1790		if (this.requestDebounceTimeout) {
1791			clearTimeout(this.requestDebounceTimeout);
1792			this.requestDebounceTimeout = null;
1793		}
1794	}
1795	debouncedStartRequest(debounce) {
1796		this.clearRequestDebounceTimeout();
1797		this.requestDebounceTimeout = window.setTimeout(() => {
1798			this.render();
1799		}, this.calculateDebounce(debounce));
1800	}
1801	renderError(html) {
1802		let modal = document.getElementById("live-component-error");
1803		if (modal) modal.innerHTML = "";
1804		else {
1805			modal = document.createElement("div");
1806			modal.id = "live-component-error";
1807			modal.style.padding = "50px";
1808			modal.style.backgroundColor = "rgba(0, 0, 0, .5)";
1809			modal.style.zIndex = "100000";
1810			modal.style.position = "fixed";
1811			modal.style.top = "0px";
1812			modal.style.bottom = "0px";
1813			modal.style.left = "0px";
1814			modal.style.right = "0px";
1815			modal.style.display = "flex";
1816			modal.style.flexDirection = "column";
1817		}
1818		const iframe = document.createElement("iframe");
1819		iframe.style.borderRadius = "5px";
1820		iframe.style.flexGrow = "1";
1821		modal.appendChild(iframe);
1822		document.body.prepend(modal);
1823		document.body.style.overflow = "hidden";
1824		if (iframe.contentWindow) {
1825			iframe.contentWindow.document.open();
1826			iframe.contentWindow.document.write(html);
1827			iframe.contentWindow.document.close();
1828		}
1829		const closeModal = (modal) => {
1830			if (modal) modal.outerHTML = "";
1831			document.body.style.overflow = "visible";
1832		};
1833		modal.addEventListener("click", () => closeModal(modal));
1834		modal.setAttribute("tabindex", "0");
1835		modal.addEventListener("keydown", (e) => {
1836			if (e.key === "Escape") closeModal(modal);
1837		});
1838		modal.focus();
1839	}
1840	resetPromise() {
1841		this.nextRequestPromise = new Promise((resolve) => {
1842			this.nextRequestPromiseResolve = resolve;
1843		});
1844	}
1845	_updateFromParentProps(props) {
1846		if (this.valueStore.storeNewPropsFromParent(props)) this.render();
1847	}
1848};
1849function proxifyComponent(component) {
1850	return new Proxy(component, {
1851		get(component, prop) {
1852			if (prop in component || typeof prop !== "string") {
1853				if (typeof component[prop] === "function") {
1854					const callable = component[prop];
1855					return (...args) => {
1856						return callable.apply(component, args);
1857					};
1858				}
1859				return Reflect.get(component, prop);
1860			}
1861			if (component.valueStore.has(prop)) return component.getData(prop);
1862			if ("toJSON" === prop || "then" === prop) return;
1863			return (args) => {
1864				return component.action.apply(component, [prop, args]);
1865			};
1866		},
1867		set(target, property, value) {
1868			if (property in target) {
1869				target[property] = value;
1870				return true;
1871			}
1872			target.set(property, value);
1873			return true;
1874		}
1875	});
1876}
1877function triggerDownload(download) {
1878	const fromUrl = "url" in download;
1879	const href = fromUrl ? download.url : URL.createObjectURL(download.blob);
1880	const link = Object.assign(document.createElement("a"), {
1881		href,
1882		download: fromUrl ? "" : download.filename,
1883		style: "display: none"
1884	});
1885	document.body.appendChild(link);
1886	link.click();
1887	setTimeout(() => {
1888		document.body.removeChild(link);
1889		if (!fromUrl) URL.revokeObjectURL(href);
1890	}, 75);
1891}
1892var StimulusElementDriver = class {
1893	controller;
1894	constructor(controller) {
1895		this.controller = controller;
1896	}
1897	getModelName(element) {
1898		const modelDirective = getModelDirectiveFromElement(element, false);
1899		if (!modelDirective) return null;
1900		return modelDirective.action;
1901	}
1902	getComponentProps() {
1903		return this.controller.propsValue;
1904	}
1905	getEventsToEmit() {
1906		return this.controller.eventsToEmitValue;
1907	}
1908	getBrowserEventsToDispatch() {
1909		return this.controller.eventsToDispatchValue;
1910	}
1911};
1912function get_model_binding_default(modelDirective) {
1913	let shouldRender = true;
1914	let targetEventName = null;
1915	let debounce = false;
1916	let minLength = null;
1917	let maxLength = null;
1918	let minValue = null;
1919	let maxValue = null;
1920	modelDirective.modifiers.forEach((modifier) => {
1921		switch (modifier.name) {
1922			case "on":
1923				if (!modifier.value) throw new Error(`The "on" modifier in ${modelDirective.getString()} requires a value - e.g. on(change).`);
1924				if (!["input", "change"].includes(modifier.value)) throw new Error(`The "on" modifier in ${modelDirective.getString()} only accepts the arguments "input" or "change".`);
1925				targetEventName = modifier.value;
1926				break;
1927			case "norender":
1928				shouldRender = false;
1929				break;
1930			case "debounce":
1931				debounce = modifier.value ? Number.parseInt(modifier.value) : true;
1932				break;
1933			case "min_length":
1934				minLength = modifier.value ? Number.parseInt(modifier.value) : null;
1935				break;
1936			case "max_length":
1937				maxLength = modifier.value ? Number.parseInt(modifier.value) : null;
1938				break;
1939			case "min_value":
1940				minValue = modifier.value ? Number.parseFloat(modifier.value) : null;
1941				break;
1942			case "max_value":
1943				maxValue = modifier.value ? Number.parseFloat(modifier.value) : null;
1944				break;
1945			default: throw new Error(`Unknown modifier "${modifier.name}" in data-model="${modelDirective.getString()}".`);
1946		}
1947	});
1948	const [modelName, innerModelName] = modelDirective.action.split(":");
1949	return {
1950		modelName,
1951		innerModelName: innerModelName || null,
1952		shouldRender,
1953		debounce,
1954		targetEventName,
1955		minLength,
1956		maxLength,
1957		minValue,
1958		maxValue
1959	};
1960}
1961var ChildComponentPlugin_default = class {
1962	component;
1963	parentModelBindings = [];
1964	constructor(component) {
1965		this.component = component;
1966		const modelDirectives = getAllModelDirectiveFromElements(this.component.element);
1967		this.parentModelBindings = modelDirectives.map(get_model_binding_default);
1968	}
1969	attachToComponent(component) {
1970		component.on("request:started", (requestData) => {
1971			requestData.children = this.getChildrenFingerprints();
1972		});
1973		component.on("model:set", (model, value) => {
1974			this.notifyParentModelChange(model, value);
1975		});
1976	}
1977	getChildrenFingerprints() {
1978		const fingerprints = {};
1979		this.getChildren().forEach((child) => {
1980			if (!child.id) throw new Error("missing id");
1981			fingerprints[child.id] = {
1982				fingerprint: child.fingerprint,
1983				tag: child.element.tagName.toLowerCase()
1984			};
1985		});
1986		return fingerprints;
1987	}
1988	notifyParentModelChange(modelName, value) {
1989		const parentComponent = findParent(this.component);
1990		if (!parentComponent) return;
1991		this.parentModelBindings.forEach((modelBinding) => {
1992			if ((modelBinding.innerModelName || "value") !== modelName) return;
1993			parentComponent.set(modelBinding.modelName, value, modelBinding.shouldRender, modelBinding.debounce);
1994		});
1995	}
1996	getChildren() {
1997		return findChildren(this.component);
1998	}
1999};
2000var LazyPlugin_default = class {
2001	intersectionObserver = null;
2002	attachToComponent(component) {
2003		if ("lazy" !== component.element.attributes.getNamedItem("loading")?.value) return;
2004		component.on("connect", () => {
2005			this.getObserver().observe(component.element);
2006		});
2007		component.on("disconnect", () => {
2008			this.intersectionObserver?.unobserve(component.element);
2009		});
2010	}
2011	getObserver() {
2012		if (!this.intersectionObserver) this.intersectionObserver = new IntersectionObserver((entries, observer) => {
2013			entries.forEach((entry) => {
2014				if (entry.isIntersecting) {
2015					entry.target.dispatchEvent(new CustomEvent("live:appear"));
2016					observer.unobserve(entry.target);
2017				}
2018			});
2019		});
2020		return this.intersectionObserver;
2021	}
2022};
2023var LoadingPlugin_default = class {
2024	attachToComponent(component) {
2025		component.on("loading.state:started", (element, request) => {
2026			this.startLoading(component, element, request);
2027		});
2028		component.on("loading.state:finished", (element) => {
2029			this.finishLoading(component, element);
2030		});
2031		this.finishLoading(component, component.element);
2032	}
2033	startLoading(component, targetElement, backendRequest) {
2034		this.handleLoadingToggle(component, true, targetElement, backendRequest);
2035	}
2036	finishLoading(component, targetElement) {
2037		this.handleLoadingToggle(component, false, targetElement, null);
2038	}
2039	handleLoadingToggle(component, isLoading, targetElement, backendRequest) {
2040		if (isLoading) targetElement.setAttribute("aria-busy", "true");
2041		else targetElement.removeAttribute("aria-busy");
2042		this.getLoadingDirectives(component, targetElement).forEach(({ element, directives }) => {
2043			if (isLoading) this.addAttributes(element, ["data-live-is-loading"]);
2044			else this.removeAttributes(element, ["data-live-is-loading"]);
2045			directives.forEach((directive) => {
2046				this.handleLoadingDirective(element, isLoading, directive, backendRequest);
2047			});
2048		});
2049	}
2050	handleLoadingDirective(element, isLoading, directive, backendRequest) {
2051		const finalAction = parseLoadingAction(directive.action, isLoading);
2052		const targetedActions = [];
2053		const targetedModels = [];
2054		let delay = 0;
2055		const validModifiers = /* @__PURE__ */ new Map();
2056		validModifiers.set("delay", (modifier) => {
2057			if (!isLoading) return;
2058			delay = modifier.value ? Number.parseInt(modifier.value) : 200;
2059		});
2060		validModifiers.set("action", (modifier) => {
2061			if (!modifier.value) throw new Error(`The "action" in data-loading must have an action name - e.g. action(foo). It's missing for "${directive.getString()}"`);
2062			targetedActions.push(modifier.value);
2063		});
2064		validModifiers.set("model", (modifier) => {
2065			if (!modifier.value) throw new Error(`The "model" in data-loading must have an action name - e.g. model(foo). It's missing for "${directive.getString()}"`);
2066			targetedModels.push(modifier.value);
2067		});
2068		directive.modifiers.forEach((modifier) => {
2069			if (validModifiers.has(modifier.name)) {
2070				(validModifiers.get(modifier.name) ?? (() => {}))(modifier);
2071				return;
2072			}
2073			throw new Error(`Unknown modifier "${modifier.name}" used in data-loading="${directive.getString()}". Available modifiers are: ${Array.from(validModifiers.keys()).join(", ")}.`);
2074		});
2075		if (isLoading && targetedActions.length > 0 && backendRequest && !backendRequest.containsOneOfActions(targetedActions)) return;
2076		if (isLoading && targetedModels.length > 0 && backendRequest && !backendRequest.areAnyModelsUpdated(targetedModels)) return;
2077		let loadingDirective;
2078		switch (finalAction) {
2079			case "show":
2080				loadingDirective = () => this.showElement(element);
2081				break;
2082			case "hide":
2083				loadingDirective = () => this.hideElement(element);
2084				break;
2085			case "addClass":
2086				loadingDirective = () => this.addClass(element, directive.args);
2087				break;
2088			case "removeClass":
2089				loadingDirective = () => this.removeClass(element, directive.args);
2090				break;
2091			case "addAttribute":
2092				loadingDirective = () => this.addAttributes(element, directive.args);
2093				break;
2094			case "removeAttribute":
2095				loadingDirective = () => this.removeAttributes(element, directive.args);
2096				break;
2097			default: throw new Error(`Unknown data-loading action "${finalAction}"`);
2098		}
2099		if (delay) {
2100			window.setTimeout(() => {
2101				if (backendRequest && !backendRequest.isResolved) loadingDirective();
2102			}, delay);
2103			return;
2104		}
2105		loadingDirective();
2106	}
2107	getLoadingDirectives(component, element) {
2108		const loadingDirectives = [];
2109		let matchingElements = Array.from(element.querySelectorAll("[data-loading]"));
2110		matchingElements = matchingElements.filter((elt) => elementBelongsToThisComponent(elt, component));
2111		matchingElements = matchingElements.filter((elt) => !elt.closest("[data-live-ignore]"));
2112		if (element.hasAttribute("data-loading")) matchingElements = [element, ...matchingElements];
2113		matchingElements.forEach((element) => {
2114			if (!(element instanceof HTMLElement) && !(element instanceof SVGElement)) throw new Error("Invalid Element Type");
2115			const directives = parseDirectives(element.dataset.loading || "show");
2116			loadingDirectives.push({
2117				element,
2118				directives
2119			});
2120		});
2121		return loadingDirectives;
2122	}
2123	showElement(element) {
2124		element.style.display = "revert";
2125	}
2126	hideElement(element) {
2127		element.style.display = "none";
2128	}
2129	addClass(element, classes) {
2130		element.classList.add(...combineSpacedArray(classes));
2131	}
2132	removeClass(element, classes) {
2133		element.classList.remove(...combineSpacedArray(classes));
2134		if (element.classList.length === 0) element.removeAttribute("class");
2135	}
2136	addAttributes(element, attributes) {
2137		attributes.forEach((attribute) => {
2138			element.setAttribute(attribute, "");
2139		});
2140	}
2141	removeAttributes(element, attributes) {
2142		attributes.forEach((attribute) => {
2143			element.removeAttribute(attribute);
2144		});
2145	}
2146};
2147const parseLoadingAction = (action, isLoading) => {
2148	switch (action) {
2149		case "show": return isLoading ? "show" : "hide";
2150		case "hide": return isLoading ? "hide" : "show";
2151		case "addClass": return isLoading ? "addClass" : "removeClass";
2152		case "removeClass": return isLoading ? "removeClass" : "addClass";
2153		case "addAttribute": return isLoading ? "addAttribute" : "removeAttribute";
2154		case "removeAttribute": return isLoading ? "removeAttribute" : "addAttribute";
2155	}
2156	throw new Error(`Unknown data-loading action "${action}"`);
2157};
2158var PageUnloadingPlugin_default = class {
2159	isConnected = false;
2160	attachToComponent(component) {
2161		component.on("render:started", (html, response, controls) => {
2162			if (!this.isConnected) controls.shouldRender = false;
2163		});
2164		component.on("connect", () => {
2165			this.isConnected = true;
2166		});
2167		component.on("disconnect", () => {
2168			this.isConnected = false;
2169		});
2170	}
2171};
2172var PollingDirector_default = class {
2173	component;
2174	isPollingActive = true;
2175	polls;
2176	pollingIntervals = [];
2177	constructor(component) {
2178		this.component = component;
2179	}
2180	addPoll(actionName, duration) {
2181		this.polls.push({
2182			actionName,
2183			duration
2184		});
2185		if (this.isPollingActive) this.initiatePoll(actionName, duration);
2186	}
2187	startAllPolling() {
2188		if (this.isPollingActive) return;
2189		this.isPollingActive = true;
2190		this.polls.forEach(({ actionName, duration }) => {
2191			this.initiatePoll(actionName, duration);
2192		});
2193	}
2194	stopAllPolling() {
2195		this.isPollingActive = false;
2196		this.pollingIntervals.forEach((interval) => {
2197			clearInterval(interval);
2198		});
2199	}
2200	clearPolling() {
2201		this.stopAllPolling();
2202		this.polls = [];
2203		this.startAllPolling();
2204	}
2205	initiatePoll(actionName, duration) {
2206		let callback;
2207		if (actionName === "$render") callback = () => {
2208			this.component.render();
2209		};
2210		else callback = () => {
2211			this.component.action(actionName, {}, 0);
2212		};
2213		const timer = window.setInterval(() => {
2214			callback();
2215		}, duration);
2216		this.pollingIntervals.push(timer);
2217	}
2218};
2219var PollingPlugin_default = class {
2220	element;
2221	pollingDirector;
2222	attachToComponent(component) {
2223		this.element = component.element;
2224		this.pollingDirector = new PollingDirector_default(component);
2225		this.initializePolling();
2226		component.on("connect", () => {
2227			this.pollingDirector.startAllPolling();
2228		});
2229		component.on("disconnect", () => {
2230			this.pollingDirector.stopAllPolling();
2231		});
2232		component.on("render:finished", () => {
2233			this.initializePolling();
2234		});
2235	}
2236	addPoll(actionName, duration) {
2237		this.pollingDirector.addPoll(actionName, duration);
2238	}
2239	clearPolling() {
2240		this.pollingDirector.clearPolling();
2241	}
2242	initializePolling() {
2243		this.clearPolling();
2244		if (this.element.dataset.poll === void 0) return;
2245		const rawPollConfig = this.element.dataset.poll;
2246		parseDirectives(rawPollConfig || "$render").forEach((directive) => {
2247			let duration = 2e3;
2248			directive.modifiers.forEach((modifier) => {
2249				switch (modifier.name) {
2250					case "delay":
2251						if (modifier.value) duration = Number.parseInt(modifier.value);
2252						break;
2253					default: console.warn(`Unknown modifier "${modifier.name}" in data-poll "${rawPollConfig}".`);
2254				}
2255			});
2256			this.addPoll(directive.action, duration);
2257		});
2258	}
2259};
2260var SetValueOntoModelFieldsPlugin_default = class {
2261	attachToComponent(component) {
2262		this.synchronizeValueOfModelFields(component);
2263		component.on("render:finished", () => {
2264			this.synchronizeValueOfModelFields(component);
2265		});
2266	}
2267	synchronizeValueOfModelFields(component) {
2268		component.element.querySelectorAll("[data-model]").forEach((element) => {
2269			if (!(element instanceof HTMLElement)) throw new Error("Invalid element using data-model.");
2270			if (element instanceof HTMLFormElement) return;
2271			if (!elementBelongsToThisComponent(element, component)) return;
2272			const modelDirective = getModelDirectiveFromElement(element);
2273			if (!modelDirective) return;
2274			const modelName = modelDirective.action;
2275			if (component.getUnsyncedModels().includes(modelName)) return;
2276			if (component.valueStore.has(modelName)) setValueOnElement(element, component.valueStore.get(modelName));
2277			if (element instanceof HTMLSelectElement && !element.multiple) component.valueStore.set(modelName, getValueFromElement(element, component.valueStore));
2278		});
2279	}
2280};
2281var ValidatedFieldsPlugin_default = class {
2282	attachToComponent(component) {
2283		component.on("model:set", (modelName) => {
2284			this.handleModelSet(modelName, component.valueStore);
2285		});
2286	}
2287	handleModelSet(modelName, valueStore) {
2288		if (valueStore.has("validatedFields")) {
2289			const validatedFields = [...valueStore.get("validatedFields")];
2290			if (!validatedFields.includes(modelName)) validatedFields.push(modelName);
2291			valueStore.set("validatedFields", validatedFields);
2292		}
2293	}
2294};
2295var LiveControllerDefault = class LiveControllerDefault extends Controller {
2296	static values = {
2297		name: String,
2298		url: String,
2299		props: {
2300			type: Object,
2301			default: {}
2302		},
2303		propsUpdatedFromParent: {
2304			type: Object,
2305			default: {}
2306		},
2307		listeners: {
2308			type: Array,
2309			default: []
2310		},
2311		eventsToEmit: {
2312			type: Array,
2313			default: []
2314		},
2315		eventsToDispatch: {
2316			type: Array,
2317			default: []
2318		},
2319		debounce: {
2320			type: Number,
2321			default: 150
2322		},
2323		fingerprint: {
2324			type: String,
2325			default: ""
2326		},
2327		requestMethod: {
2328			type: String,
2329			default: "post"
2330		},
2331		fetchCredentials: {
2332			type: String,
2333			default: "same-origin"
2334		}
2335	};
2336	proxiedComponent;
2337	mutationObserver;
2338	component;
2339	pendingActionTriggerModelElement = null;
2340	elementEventListeners = [{
2341		event: "input",
2342		callback: (event) => this.handleInputEvent(event)
2343	}, {
2344		event: "change",
2345		callback: (event) => this.handleChangeEvent(event)
2346	}];
2347	pendingFiles = {};
2348	static backendFactory = (controller) => new Backend_default(controller.urlValue, controller.requestMethodValue, controller.fetchCredentialsValue);
2349	initialize() {
2350		this.mutationObserver = new MutationObserver(this.onMutations.bind(this));
2351		this.createComponent();
2352	}
2353	connect() {
2354		this.connectComponent();
2355		this.mutationObserver.observe(this.element, { attributes: true });
2356	}
2357	disconnect() {
2358		this.disconnectComponent();
2359		this.mutationObserver.disconnect();
2360	}
2361	update(event) {
2362		if (event.type === "input" || event.type === "change") throw new Error(`Since LiveComponents 2.3, you no longer need data-action="live#update" on form elements. Found on element: ${getElementAsTagText(event.currentTarget)}`);
2363		this.updateModelFromElementEvent(event.currentTarget, null);
2364	}
2365	action(event) {
2366		const params = event.params;
2367		if (!params.action) throw new Error(`No action name provided on element: ${getElementAsTagText(event.currentTarget)}. Did you forget to add the "data-live-action-param" attribute?`);
2368		const rawAction = params.action;
2369		const actionArgs = { ...params };
2370		delete actionArgs.action;
2371		const directives = parseDirectives(rawAction);
2372		let debounce = false;
2373		directives.forEach((directive) => {
2374			let pendingFiles = {};
2375			const validModifiers = /* @__PURE__ */ new Map();
2376			validModifiers.set("stop", () => {
2377				event.stopPropagation();
2378			});
2379			validModifiers.set("self", () => {
2380				if (event.target !== event.currentTarget) return;
2381			});
2382			validModifiers.set("debounce", (modifier) => {
2383				debounce = modifier.value ? Number.parseInt(modifier.value) : true;
2384			});
2385			validModifiers.set("files", (modifier) => {
2386				if (!modifier.value) pendingFiles = this.pendingFiles;
2387				else if (this.pendingFiles[modifier.value]) pendingFiles[modifier.value] = this.pendingFiles[modifier.value];
2388			});
2389			directive.modifiers.forEach((modifier) => {
2390				if (validModifiers.has(modifier.name)) {
2391					(validModifiers.get(modifier.name) ?? (() => {}))(modifier);
2392					return;
2393				}
2394				console.warn(`Unknown modifier ${modifier.name} in action "${rawAction}". Available modifiers are: ${Array.from(validModifiers.keys()).join(", ")}.`);
2395			});
2396			for (const [key, input] of Object.entries(pendingFiles)) {
2397				if (input.files) this.component.files(key, input);
2398				delete this.pendingFiles[key];
2399			}
2400			this.component.action(directive.action, actionArgs, debounce);
2401			if (getModelDirectiveFromElement(event.currentTarget, false)) this.pendingActionTriggerModelElement = event.currentTarget;
2402		});
2403	}
2404	$render() {
2405		return this.component.render();
2406	}
2407	emit(event) {
2408		this.getEmitDirectives(event).forEach(({ name, data, nameMatch }) => {
2409			this.component.emit(name, data, nameMatch);
2410		});
2411	}
2412	emitUp(event) {
2413		this.getEmitDirectives(event).forEach(({ name, data, nameMatch }) => {
2414			this.component.emitUp(name, data, nameMatch);
2415		});
2416	}
2417	emitSelf(event) {
2418		this.getEmitDirectives(event).forEach(({ name, data }) => {
2419			this.component.emitSelf(name, data);
2420		});
2421	}
2422	$updateModel(model, value, shouldRender = true, debounce = true) {
2423		return this.component.set(model, value, shouldRender, debounce);
2424	}
2425	propsUpdatedFromParentValueChanged() {
2426		this.component._updateFromParentProps(this.propsUpdatedFromParentValue);
2427	}
2428	fingerprintValueChanged() {
2429		this.component.fingerprint = this.fingerprintValue;
2430	}
2431	getEmitDirectives(event) {
2432		const params = event.params;
2433		if (!params.event) throw new Error(`No event name provided on element: ${getElementAsTagText(event.currentTarget)}. Did you forget to add the "data-live-event-param" attribute?`);
2434		const eventInfo = params.event;
2435		const eventArgs = { ...params };
2436		delete eventArgs.event;
2437		const directives = parseDirectives(eventInfo);
2438		const emits = [];
2439		directives.forEach((directive) => {
2440			let nameMatch = null;
2441			directive.modifiers.forEach((modifier) => {
2442				switch (modifier.name) {
2443					case "name":
2444						nameMatch = modifier.value;
2445						break;
2446					default: throw new Error(`Unknown modifier ${modifier.name} in event "${eventInfo}".`);
2447				}
2448			});
2449			emits.push({
2450				name: directive.action,
2451				data: eventArgs,
2452				nameMatch
2453			});
2454		});
2455		return emits;
2456	}
2457	createComponent() {
2458		const id = this.element.id || null;
2459		this.component = new Component(this.element, this.nameValue, this.propsValue, this.listenersValue, id, LiveControllerDefault.backendFactory(this), new StimulusElementDriver(this));
2460		this.proxiedComponent = proxifyComponent(this.component);
2461		Object.defineProperty(this.element, "__component", {
2462			value: this.proxiedComponent,
2463			writable: true
2464		});
2465		if (this.hasDebounceValue) this.component.defaultDebounce = this.debounceValue;
2466		[
2467			new LoadingPlugin_default(),
2468			new LazyPlugin_default(),
2469			new ValidatedFieldsPlugin_default(),
2470			new PageUnloadingPlugin_default(),
2471			new PollingPlugin_default(),
2472			new SetValueOntoModelFieldsPlugin_default(),
2473			new ChildComponentPlugin_default(this.component)
2474		].forEach((plugin) => {
2475			this.component.addPlugin(plugin);
2476		});
2477	}
2478	connectComponent() {
2479		this.component.connect();
2480		this.mutationObserver.observe(this.element, { attributes: true });
2481		this.elementEventListeners.forEach(({ event, callback }) => {
2482			this.component.element.addEventListener(event, callback);
2483		});
2484		this.dispatchEvent("connect");
2485	}
2486	disconnectComponent() {
2487		this.component.disconnect();
2488		this.elementEventListeners.forEach(({ event, callback }) => {
2489			this.component.element.removeEventListener(event, callback);
2490		});
2491		this.dispatchEvent("disconnect");
2492	}
2493	handleInputEvent(event) {
2494		const target = event.target;
2495		if (!target) return;
2496		this.updateModelFromElementEvent(target, "input");
2497	}
2498	handleChangeEvent(event) {
2499		const target = event.target;
2500		if (!target) return;
2501		this.updateModelFromElementEvent(target, "change");
2502	}
2503	updateModelFromElementEvent(element, eventName) {
2504		if (!elementBelongsToThisComponent(element, this.component)) return;
2505		if (!(element instanceof HTMLElement)) throw new Error("Could not update model for non HTMLElement");
2506		if (element instanceof HTMLInputElement && element.type === "file") {
2507			const key = element.name;
2508			if (element.files?.length) this.pendingFiles[key] = element;
2509			else if (this.pendingFiles[key]) delete this.pendingFiles[key];
2510		}
2511		const modelDirective = getModelDirectiveFromElement(element, false);
2512		if (!modelDirective) return;
2513		const modelBinding = get_model_binding_default(modelDirective);
2514		if (!modelBinding.targetEventName) modelBinding.targetEventName = "input";
2515		if (this.pendingActionTriggerModelElement === element) modelBinding.shouldRender = false;
2516		if (eventName === "change" && modelBinding.targetEventName === "input") modelBinding.targetEventName = "change";
2517		if (eventName && modelBinding.targetEventName !== eventName) return;
2518		if (false === modelBinding.debounce) if (modelBinding.targetEventName === "input") modelBinding.debounce = true;
2519		else modelBinding.debounce = 0;
2520		const finalValue = getValueFromElement(element, this.component.valueStore);
2521		const finalValueIsEmpty = finalValue === "" || finalValue === null || finalValue === void 0;
2522		if (isTextualInputElement(element) || isTextareaElement(element)) {
2523			if (!finalValueIsEmpty && modelBinding.minLength !== null && typeof finalValue === "string" && finalValue.length < modelBinding.minLength) return;
2524			if (!finalValueIsEmpty && modelBinding.maxLength !== null && typeof finalValue === "string" && finalValue.length > modelBinding.maxLength) return;
2525		}
2526		if (isNumericalInputElement(element)) {
2527			if (!finalValueIsEmpty) {
2528				const numericValue = Number(finalValue);
2529				if (modelBinding.minValue !== null && numericValue < modelBinding.minValue) return;
2530				if (modelBinding.maxValue !== null && numericValue > modelBinding.maxValue) return;
2531			}
2532		}
2533		this.component.set(modelBinding.modelName, finalValue, modelBinding.shouldRender, modelBinding.debounce);
2534	}
2535	dispatchEvent(name, detail = {}, canBubble = true, cancelable = false) {
2536		detail.controller = this;
2537		detail.component = this.proxiedComponent;
2538		this.dispatch(name, {
2539			detail,
2540			prefix: "live",
2541			cancelable,
2542			bubbles: canBubble
2543		});
2544	}
2545	onMutations(mutations) {
2546		mutations.forEach((mutation) => {
2547			if (mutation.type === "attributes" && mutation.attributeName === "id" && this.component.getOriginalId() !== this.component.id) {
2548				this.disconnectComponent();
2549				this.createComponent();
2550				this.connectComponent();
2551			}
2552		});
2553	}
2554};
2555export { Component, LiveControllerDefault as default, getComponent };

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.