# elementor/4.3.0/assets/js/packages/editor-interactions/editor-interactions.js

Elementor Website Builder – more than just a page builder, version 4.3.0. 2,081 lines.

- Page: https://pluginprobe.com/plugins/elementor/4.3.0/code/assets/js/packages/editor-interactions/editor-interactions.js
- Raw: https://pluginprobe.com/plugins/elementor/4.3.0/raw/assets/js/packages/editor-interactions/editor-interactions.js
- Modified: 2026-09-01T11:47:36+00:00

Line numbers below start at 1. Link to a line or a range by appending a fragment to the
page URL, for example `https://pluginprobe.com/plugins/elementor/4.3.0/code/assets/js/packages/editor-interactions/editor-interactions.js#L10-L20`.

```javascript
(function(react, _elementor_icons, _elementor_ui, _wordpress_i18n, _elementor_session, _elementor_editor_elements, _elementor_editor_v1_adapters, _elementor_editor_props, _elementor_editor_controls, _elementor_events, _elementor_editor_responsive, _elementor_editor_mcp, _elementor_editor_ui, _elementor_utils, _elementor_schema) {

//#region \0rolldown/runtime.js
	var __create = Object.create;
	var __defProp = Object.defineProperty;
	var __name = (target, value) => __defProp(target, "name", {
		value,
		configurable: true
	});
	var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
	var __getOwnPropNames = Object.getOwnPropertyNames;
	var __getProtoOf = Object.getPrototypeOf;
	var __hasOwnProp = Object.prototype.hasOwnProperty;
	var __exportAll = (all, no_symbols) => {
		let target = {};
		for (var name in all) {
			__defProp(target, name, {
				get: all[name],
				enumerable: true
			});
		}
		if (!no_symbols) {
			__defProp(target, Symbol.toStringTag, { value: "Module" });
		}
		return target;
	};
	var __copyProps = (to, from, except, desc) => {
		if (from && typeof from === "object" || typeof from === "function") {
			for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
				key = keys[i];
				if (!__hasOwnProp.call(to, key) && key !== except) {
					__defProp(to, key, {
						get: ((k) => from[k]).bind(null, key),
						enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
					});
				}
			}
		}
		return to;
	};
	var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
		value: mod,
		enumerable: true
	}) : target, mod));

//#endregion
react = __toESM(react);

//#region packages/packages/core/editor-interactions/src/components/empty-state.tsx
	var EmptyState = ({ onCreateInteraction }) => {
		return /* @__PURE__ */ react.createElement(_elementor_ui.Stack, {
			alignItems: "center",
			justifyContent: "center",
			height: "100%",
			color: "text.secondary",
			sx: {
				p: 2.5,
				pt: 8,
				pb: 5.5
			},
			gap: 1.5
		}, /* @__PURE__ */ react.createElement(_elementor_icons.SwipeIcon, { fontSize: "large" }), /* @__PURE__ */ react.createElement(_elementor_ui.Typography, {
			align: "center",
			variant: "subtitle2"
		}, (0, _wordpress_i18n.__)("Animate elements with Interactions", "elementor")), /* @__PURE__ */ react.createElement(_elementor_ui.Typography, {
			align: "center",
			variant: "caption",
			maxWidth: "170px"
		}, (0, _wordpress_i18n.__)("Add entrance animations and effects triggered by user interactions such as page load or scroll.", "elementor")), /* @__PURE__ */ react.createElement(_elementor_ui.Button, {
			variant: "outlined",
			color: "secondary",
			size: "small",
			sx: { mt: 1 },
			onClick: onCreateInteraction
		}, (0, _wordpress_i18n.__)("Create an interaction", "elementor")));
	};

//#endregion
//#region packages/packages/core/editor-interactions/src/interactions-controls-registry.ts
	var controlsRegistry = /* @__PURE__ */ new Map();
	function registerInteractionsControl({ type, component, options }) {
		controlsRegistry.set(type, {
			type,
			component,
			options
		});
	}
	function getInteractionsControl(type) {
		return controlsRegistry.get(type);
	}
	function getInteractionsControlOptions(type) {
		return controlsRegistry.get(type)?.options ?? [];
	}

//#endregion
//#region packages/packages/core/editor-interactions/src/configs/time-constants.ts
	var TIME_UNITS = ["s", "ms"];

//#endregion
//#region packages/packages/core/editor-interactions/src/utils/size-transform-utils.ts
	var SIZE_REGEX = /^(?:(-?\d*\.?\d+)([a-z%]+)|([a-z%]+))$/i;
	var parseSizeValue = (value, allowedUnits, defaultValue, defaultUnit) => {
		if (typeof value === "number") return {
			size: value,
			unit: defaultUnit
		};
		const sizeValue = tryParse(value, allowedUnits, defaultUnit);
		if (sizeValue) return sizeValue;
		if (defaultValue) {
			const fallbackSize = tryParse(defaultValue, allowedUnits, defaultUnit);
			if (fallbackSize) return fallbackSize;
		}
		return createSizeValue(null, defaultUnit);
	};
	var tryParse = (value, allowedUnits, defaultUnit) => {
		if (typeof value === "number") return createSizeValue(value, defaultUnit);
		const match = value && value.match(SIZE_REGEX);
		if (!match) {
			if (value) return {
				size: Number(value),
				unit: defaultUnit
			};
			return null;
		}
		const size = match[1] ? parseFloat(match[1]) : null;
		const unit = match[2] || match[3];
		if (!allowedUnits.includes(unit)) return null;
		return createSizeValue(size, unit);
	};
	var formatSizeValue = ({ size, unit }) => {
		return `${size ?? ""}${unit}`;
	};
	var createSizeValue = (size, unit) => {
		return {
			size,
			unit
		};
	};

//#endregion
//#region packages/packages/core/editor-interactions/src/utils/custom-effect-to-prop-value.ts
	var CUSTOM_EFFECT_TYPE = "custom-effect";
	var KEYFRAMES_TYPE = "keyframes";
	var KEYFRAME_STOP_TYPE = "keyframe-stop";
	var KEYFRAME_STOP_SETTINGS_TYPE = "keyframe-stop-settings";
	var SIZE_TYPE = "size";
	var NUMBER_TYPE = "number";
	var TRANSFORM_SCALE_TYPE = "transform-scale";
	var TRANSFORM_ROTATE_TYPE = "transform-rotate";
	var TRANSFORM_MOVE_TYPE = "transform-move";
	var TRANSFORM_SKEW_TYPE = "transform-skew";
	var UNIT_PERCENT = "%";
	var UNIT_DEG = "deg";
	var UNIT_PX = "px";
	var isPlainCustomEffect = (v) => typeof v === "object" && v !== null && "keyframes" in v && Array.isArray(v.keyframes) && !("$$type" in v);
	var toSizePropValue = (size, unit = UNIT_PERCENT) => ({
		$$type: SIZE_TYPE,
		value: {
			size,
			unit
		}
	});
	var toNumberPropValue = (n) => ({
		$$type: NUMBER_TYPE,
		value: n
	});
	var toDimensionalNumberPropValue = (type, plain, defaults) => ({
		$$type: type,
		value: {
			x: toNumberPropValue(plain.x ?? defaults.x),
			y: toNumberPropValue(plain.y ?? defaults.y),
			z: toNumberPropValue(plain.z ?? defaults.z)
		}
	});
	var toDimensionalSizePropValue = (type, plain, defaults, unit) => ({
		$$type: type,
		value: {
			x: toSizePropValue(plain.x ?? defaults.x, unit),
			y: toSizePropValue(plain.y ?? defaults.y, unit),
			z: toSizePropValue(plain.z ?? defaults.z, unit)
		}
	});
	var toSkewPropValue = (plain) => ({
		$$type: TRANSFORM_SKEW_TYPE,
		value: {
			x: toSizePropValue(plain.x ?? 0, UNIT_DEG),
			y: toSizePropValue(plain.y ?? 0, UNIT_DEG)
		}
	});
	var toKeyframeStopSettingsPropValue = (plain) => {
		const value = {};
		if (plain.opacity !== void 0) {
			const percent = plain.opacity <= 1 ? Math.round(plain.opacity * 100) : plain.opacity;
			value.opacity = toSizePropValue(percent);
		}
		if (plain.scale !== void 0) value.scale = toDimensionalNumberPropValue(TRANSFORM_SCALE_TYPE, plain.scale, {
			x: 1,
			y: 1,
			z: 1
		});
		if (plain.rotate !== void 0) value.rotate = toDimensionalSizePropValue(TRANSFORM_ROTATE_TYPE, plain.rotate, {
			x: 0,
			y: 0,
			z: 0
		}, UNIT_DEG);
		if (plain.move !== void 0) value.move = toDimensionalSizePropValue(TRANSFORM_MOVE_TYPE, plain.move, {
			x: 0,
			y: 0,
			z: 0
		}, UNIT_PX);
		if (plain.skew !== void 0) value.skew = toSkewPropValue(plain.skew);
		return {
			$$type: KEYFRAME_STOP_SETTINGS_TYPE,
			value
		};
	};
	var isPlainKeyframe = (v) => typeof v === "object" && v !== null && "stop" in v && "value" in v && !("$$type" in v);
	var toKeyframeStopPropValue = (item) => {
		if (!isPlainKeyframe(item)) return item;
		return {
			$$type: KEYFRAME_STOP_TYPE,
			value: {
				stop: toSizePropValue(item.stop),
				settings: toKeyframeStopSettingsPropValue(item.value)
			}
		};
	};
	var toKeyframesPropValue = (keyframes) => ({
		$$type: KEYFRAMES_TYPE,
		value: keyframes.map(toKeyframeStopPropValue)
	});
	var plainCustomEffectToPropValue = (plain) => ({
		$$type: CUSTOM_EFFECT_TYPE,
		value: { keyframes: toKeyframesPropValue(plain.keyframes) }
	});
	var toCustomEffectPropValue = (customEffects) => {
		if (customEffects === void 0) return;
		if (isPlainCustomEffect(customEffects)) return plainCustomEffectToPropValue(customEffects);
		return customEffects;
	};

//#endregion
//#region packages/packages/core/editor-interactions/src/utils/get-interactions-config.ts
	function getInteractionsConfig() {
		return window.ElementorInteractionsConfig ?? {};
	}

//#endregion
//#region packages/packages/core/editor-interactions/src/utils/temp-id-utils.ts
	var TEMP_ID_PREFIX = "temp-";
	var TEMP_ID_REGEX = /^temp-[a-z0-9]+$/i;
	function generateTempInteractionId() {
		return `${TEMP_ID_PREFIX}${Math.random().toString(36).substring(2, 11)}`;
	}
	function isTempId(id) {
		return !!id && TEMP_ID_REGEX.test(id);
	}

//#endregion
//#region packages/packages/core/editor-interactions/src/utils/prop-value-utils.ts
	var createString = (value) => ({
		$$type: "string",
		value
	});
	var createNumber = (value) => ({
		$$type: "number",
		value
	});
	var createTimingConfig = (duration, delay) => ({
		$$type: "timing-config",
		value: {
			duration: _elementor_editor_props.sizePropTypeUtil.create(parseSizeValue(duration, TIME_UNITS, void 0, "ms")),
			delay: _elementor_editor_props.sizePropTypeUtil.create(parseSizeValue(delay, TIME_UNITS, void 0, "ms"))
		}
	});
	var createBoolean = (value) => ({
		$$type: "boolean",
		value
	});
	var createConfig = ({ replay, easing = "easeIn", relativeTo = "viewport", repeat = "", times = 1, start = 85, end = 15 }) => ({
		$$type: "config",
		value: {
			replay: createBoolean(replay),
			easing: createString(easing),
			relativeTo: createString(relativeTo),
			repeat: createString(repeat),
			times: createNumber(times),
			start: createSize(start, "%"),
			end: createSize(end, "%")
		}
	});
	var createSize = (value, defaultUnit, defaultValue) => {
		if (!value) return;
		return _elementor_editor_props.sizePropTypeUtil.create(parseSizeValue(value, ["%"], defaultValue, defaultUnit));
	};
	var extractBoolean = (prop, fallback = false) => {
		return prop?.value ?? fallback;
	};
	var createExcludedBreakpoints = (breakpoints) => ({
		$$type: "excluded-breakpoints",
		value: breakpoints.map(createString)
	});
	var createInteractionBreakpoints = (excluded) => ({
		$$type: "interaction-breakpoints",
		value: { excluded: createExcludedBreakpoints(excluded) }
	});
	var extractExcludedBreakpoints = (breakpoints) => {
		return breakpoints?.value.excluded.value.map((bp) => bp.value) ?? [];
	};
	var createAnimationPreset = ({ effect, type, direction, duration, delay, replay = false, easing = "easeIn", relativeTo, repeat, times, start, end, customEffects }) => {
		const customEffectProp = toCustomEffectPropValue(customEffects);
		return {
			$$type: "animation-preset-props",
			value: {
				effect: createString(effect),
				...customEffectProp !== void 0 && { custom_effect: customEffectProp },
				type: createString(type),
				direction: createString(direction ?? ""),
				timing_config: createTimingConfig(duration, delay),
				config: createConfig({
					replay,
					easing,
					relativeTo,
					repeat,
					times,
					start,
					end
				})
			}
		};
	};
	var createInteractionItem = ({ trigger, effect, type, direction, duration, delay, interactionId, replay = false, easing = "easeIn", relativeTo, repeat, times, start, end, excludedBreakpoints, customEffects }) => ({
		$$type: "interaction-item",
		value: {
			...interactionId && { interaction_id: createString(interactionId) },
			trigger: createString(trigger ?? ""),
			animation: createAnimationPreset({
				effect: effect ?? "",
				type: type ?? "",
				direction,
				duration: duration ?? 0,
				delay: delay ?? 0,
				replay,
				easing,
				relativeTo,
				repeat,
				times,
				start,
				end,
				customEffects
			}),
			...excludedBreakpoints && excludedBreakpoints.length > 0 && { breakpoints: createInteractionBreakpoints(excludedBreakpoints) }
		}
	});
	var createDefaultInteractionItem = () => {
		const { constants } = getInteractionsConfig();
		return createInteractionItem({
			trigger: "load",
			effect: "fade",
			type: "in",
			duration: constants.defaultDuration,
			delay: constants.defaultDelay,
			replay: false,
			easing: constants.defaultEasing,
			interactionId: generateTempInteractionId()
		});
	};
	var createDefaultInteractions = () => ({
		version: 1,
		items: [createDefaultInteractionItem()]
	});
	var extractString = (prop, fallback = "") => {
		return prop?.value ?? fallback;
	};
	var extractSize = (prop, defaultValue) => {
		if (!prop?.value) return defaultValue;
		return formatSizeValue(prop.value);
	};
	var TRIGGER_LABELS$1 = {
		load: "On page load",
		scrollIn: "Scroll into view",
		scrollOut: "Scroll out of view",
		scrollOn: "While scrolling"
	};
	var capitalize$1 = /* @__PURE__ */ __name((str) => {
		return str.charAt(0).toUpperCase() + str.slice(1);
	}, "capitalize");
	var buildDisplayLabel = (item) => {
		const trigger = extractString(item.trigger);
		const effect = extractString(item.animation.value.effect);
		const type = extractString(item.animation.value.type);
		return `${TRIGGER_LABELS$1[trigger] || capitalize$1(trigger)}: ${capitalize$1(effect)} ${"custom" === effect ? "" : capitalize$1(type)}`;
	};

//#endregion
//#region packages/packages/core/editor-interactions/src/utils/is-supported-interaction-item.ts
	function isSupportedInteractionItem(interaction) {
		const value = interaction.value;
		if (true === extractBoolean(value.animation.value.config?.value.replay)) return hasSupport("replay", "yes");
		const trigger = extractString(value.trigger);
		const easing = extractString(value.animation.value.config?.value.easing);
		const effect = extractString(value.animation.value.effect);
		return [
			["trigger", trigger],
			["easing", easing],
			["effect", effect]
		].every(([controlType, controlValue]) => {
			if (controlValue === "" || controlValue === null) return true;
			return hasSupport(controlType, controlValue);
		});
	}
	function hasSupport(controlType, controlValue) {
		const supportedOptions = getInteractionsControlOptions(controlType);
		if (1 > supportedOptions.length) return true;
		return supportedOptions.includes(controlValue);
	}

//#endregion
//#region packages/packages/core/editor-interactions/src/utils/filter-interactions.ts
	var filterInteractions = (interactions) => {
		return interactions.filter((interaction) => {
			return isSupportedInteractionItem(interaction);
		});
	};

//#endregion
//#region packages/packages/core/editor-interactions/src/hooks/use-element-interactions.ts
	var useElementInteractions = (elementId) => {
		const [interactions, setInteractions] = (0, react.useState)(() => {
			const initial = (0, _elementor_editor_elements.getElementInteractions)(elementId);
			const filteredInteractions = filterInteractions(initial?.items ?? []);
			return {
				version: initial?.version ?? 1,
				items: filteredInteractions
			};
		});
		(0, _elementor_editor_v1_adapters.__privateUseListenTo)((0, _elementor_editor_v1_adapters.windowEvent)("elementor/element/update_interactions"), () => {
			const newInteractions = (0, _elementor_editor_elements.getElementInteractions)(elementId);
			const filteredInteractions = filterInteractions(newInteractions?.items ?? []);
			setInteractions({
				version: newInteractions?.version ?? 1,
				items: filteredInteractions
			});
		}, [elementId]);
		return interactions;
	};

//#endregion
//#region packages/packages/core/editor-interactions/src/contexts/interactions-context.tsx
	var InteractionsContext = (0, react.createContext)(null);
	var DEFAULT_INTERACTIONS = {
		version: 1,
		items: []
	};
	var InteractionsProvider = ({ children, elementId }) => {
		const rawInteractions = useElementInteractions(elementId);
		(0, react.useEffect)(() => {
			window.dispatchEvent(new CustomEvent("elementor/element/update_interactions"));
		}, []);
		const interactions = rawInteractions ?? DEFAULT_INTERACTIONS;
		const undoableSetInteractions = (0, react.useMemo)(() => (0, _elementor_editor_v1_adapters.undoable)({
			do: ({ interactions: newInteractions }) => {
				const previous = (0, _elementor_editor_elements.getElementInteractions)(elementId);
				(0, _elementor_editor_elements.updateElementInteractions)({
					elementId,
					interactions: newInteractions
				});
				return previous;
			},
			undo: (_, previous) => {
				(0, _elementor_editor_elements.updateElementInteractions)({
					elementId,
					interactions: previous?.items?.length ? previous : void 0
				});
			}
		}, {
			title: (0, _elementor_editor_elements.getElementLabel)(elementId),
			subtitle: ({ operationType }) => operationType === "apply" ? (0, _wordpress_i18n.__)("Interaction Applied", "elementor") : (0, _wordpress_i18n.__)("Interaction Deleted", "elementor")
		}), [elementId]);
		const setInteractions = (value) => {
			const normalizedValue = value && value.items?.length === 0 ? void 0 : value;
			const prevItemCount = interactions.items?.length ?? 0;
			const newItemCount = normalizedValue?.items?.length ?? 0;
			if (newItemCount > prevItemCount) undoableSetInteractions({
				interactions: normalizedValue,
				operationType: "apply"
			});
			else if (newItemCount < prevItemCount) undoableSetInteractions({
				interactions: normalizedValue,
				operationType: "delete"
			});
			else (0, _elementor_editor_elements.updateElementInteractions)({
				elementId,
				interactions: normalizedValue
			});
		};
		const playInteractions = (interactionId) => {
			(0, _elementor_editor_elements.playElementInteractions)(elementId, interactionId);
		};
		const contextValue = {
			elementId,
			interactions,
			setInteractions,
			playInteractions
		};
		return /* @__PURE__ */ react.createElement(InteractionsContext.Provider, { value: contextValue }, children);
	};
	var useInteractionsContext = () => {
		const context = (0, react.useContext)(InteractionsContext);
		if (!context) throw new Error("useInteractionsContext must be used within InteractionsProvider");
		return context;
	};

//#endregion
//#region packages/packages/core/editor-interactions/src/contexts/popup-state-context.tsx
	var PopupStateContext = (0, react.createContext)(void 0);
	var PopupStateProvider = ({ children }) => {
		const [openByDefault, setOpenByDefault] = (0, react.useState)(false);
		const triggerDefaultOpen = (0, react.useCallback)(() => {
			setOpenByDefault(true);
		}, []);
		const resetDefaultOpen = (0, react.useCallback)(() => {
			setOpenByDefault(false);
		}, []);
		return /* @__PURE__ */ react.createElement(PopupStateContext.Provider, { value: {
			openByDefault,
			triggerDefaultOpen,
			resetDefaultOpen
		} }, children);
	};

//#endregion
//#region packages/packages/core/editor-interactions/src/contexts/interactions-item-context.tsx
	var InteractionItemContext = (0, react.createContext)(null);
	function InteractionItemContextProvider({ value, children }) {
		return /* @__PURE__ */ react.createElement(InteractionItemContext.Provider, { value }, children);
	}
	function useInteractionItemContext() {
		const context = (0, react.useContext)(InteractionItemContext);
		if (!context) throw new Error("useInteractionItemContext must be used within InteractionItemContextProvider");
		return context;
	}

//#endregion
//#region packages/packages/core/editor-interactions/src/utils/scroll-interaction-event.ts
	var SCROLL_INTERACTION_EVENT = "elementor/interactions/scroll-change";
	function dispatchScrollInteraction(data) {
		window.dispatchEvent(new CustomEvent(SCROLL_INTERACTION_EVENT, { detail: data }));
	}
	function extractScrollOverlayParams(interaction, defaults) {
		return {
			trigger: extractString(interaction.trigger, defaults.trigger),
			start: extractSize(interaction.animation.value.config?.value.start, defaults.start),
			end: extractSize(interaction.animation.value.config?.value.end, defaults.end),
			relativeTo: extractString(interaction.animation.value.config?.value.relativeTo, defaults.relativeTo)
		};
	}
	function syncGridOverlay(trigger, start, end, relativeTo) {
		if (trigger === "scrollOn") dispatchScrollInteraction({
			start,
			end,
			relativeTo
		});
		else dispatchScrollInteraction(null);
	}

//#endregion
//#region packages/packages/core/editor-interactions/src/utils/tracking.ts
	var TRIGGER_LABELS = {
		load: "On page load",
		scrollIn: "Scroll into view",
		scrollOut: "Scroll out of view",
		scrollOn: "While scrolling",
		hover: "Hover",
		click: "Click"
	};
	var capitalize = (s) => s.charAt(0).toUpperCase() + s.slice(1);
	var trackInteractionCreated = (elementId, item) => {
		const { dispatchEvent, config } = (0, _elementor_events.getMixpanel)();
		if (!config?.names?.interactions?.created) return;
		const trigger = extractString(item.value.trigger);
		const effect = extractString(item.value.animation.value.effect);
		const type = extractString(item.value.animation.value.type);
		dispatchEvent?.(config.names.interactions.created, {
			window_name: config?.appTypes?.editor,
			interaction_type: config?.triggers?.click,
			target_name: (0, _elementor_editor_elements.getElementLabel)(elementId),
			interaction_result: "interaction_created",
			target_location: config?.locations?.widgetPanel,
			location_l1: (0, _elementor_editor_elements.getElementLabel)(elementId),
			location_l2: "interactions",
			interaction_description: "interaction_created",
			interaction_trigger: TRIGGER_LABELS[trigger] ?? capitalize(trigger),
			interaction_effect: effect === "custom" ? capitalize(effect) : `${capitalize(effect)} ${capitalize(type)}`
		});
	};

//#endregion
//#region packages/packages/core/editor-interactions/src/utils/resolve-direction.ts
	var resolveDirection = (hasDirection, newEffect, newDirection, currentDirection, currentEffect) => {
		if (newEffect === "slide" && !newDirection) return "top";
		if (currentEffect === "slide" && hasDirection) return newDirection || "top";
		if (hasDirection) return newDirection;
		return currentDirection;
	};

//#endregion
//#region packages/packages/core/editor-interactions/src/components/controls/time-frame-indicator.tsx
	function TimeFrameIndicator({ value, onChange, defaultValue }) {
		const sizeValue = parseSizeValue(value, TIME_UNITS, defaultValue, "ms");
		const handleChange = (0, react.useCallback)((size) => {
			onChange(formatSizeValue(size));
		}, [onChange]);
		const handleBlur = (event) => {
			if (!event.target.value) handleChange(parseSizeValue(defaultValue, TIME_UNITS, void 0, "ms"));
		};
		return /* @__PURE__ */ react.createElement(_elementor_editor_controls.SizeComponent, {
			units: TIME_UNITS,
			value: sizeValue,
			setValue: handleChange,
			onBlur: handleBlur,
			InputProps: { inputProps: { min: 0 } }
		});
	}

//#endregion
//#region packages/packages/core/editor-interactions/src/components/field.tsx
	var Field = ({ label, children }) => {
		return /* @__PURE__ */ react.createElement(_elementor_ui.Grid, {
			item: true,
			xs: 12,
			"aria-label": `${label} control`
		}, /* @__PURE__ */ react.createElement(_elementor_editor_controls.PopoverGridContainer, null, /* @__PURE__ */ react.createElement(_elementor_ui.Grid, {
			item: true,
			xs: 6
		}, /* @__PURE__ */ react.createElement(_elementor_editor_controls.ControlFormLabel, null, label)), /* @__PURE__ */ react.createElement(_elementor_ui.Grid, {
			item: true,
			xs: 6
		}, children)));
	};

//#endregion
//#region packages/packages/core/editor-interactions/src/components/interaction-details.tsx
	var DEFAULT_VALUES = {
		trigger: "load",
		effect: "fade",
		type: "in",
		direction: "",
		duration: 600,
		delay: 0,
		replay: false,
		easing: "easeIn",
		relativeTo: "viewport",
		repeat: "",
		times: 1,
		start: 85,
		end: 15
	};
	var TRIGGERS_WITHOUT_REPLAY = [
		"load",
		"scrollOn",
		"hover",
		"click"
	];
	var controlVisibilityConfig = {
		replay: (values) => !TRIGGERS_WITHOUT_REPLAY.includes(values.trigger),
		custom: (values) => values.effect === "custom",
		effectType: (values) => values.effect !== "custom",
		direction: (values) => values.effect !== "custom",
		relativeTo: (values) => values.trigger === "scrollOn",
		start: (values) => values.trigger === "scrollOn",
		end: (values) => values.trigger === "scrollOn",
		repeat: (values) => values.trigger !== "scrollOn",
		times: (values) => values.trigger !== "scrollOn" && values.repeat === "times",
		duration: (values) => {
			return !(values.trigger === "scrollOn");
		},
		delay: (values) => {
			return !(values.trigger === "scrollOn");
		}
	};
	function normalizeTimesValue(value, fallback) {
		const numericValue = Number(value);
		if (!Number.isFinite(numericValue)) return fallback;
		return Math.max(1, Math.floor(numericValue));
	}
	function useControlComponent(controlName, isVisible = true) {
		return (0, react.useMemo)(() => {
			if (!isVisible) return null;
			return getInteractionsControl(controlName)?.component ?? null;
		}, [controlName, isVisible]);
	}
	var InteractionDetails = ({ interaction, onChange, onPlayInteraction }) => {
		const trigger = extractString(interaction.trigger, DEFAULT_VALUES.trigger);
		const effect = extractString(interaction.animation.value.effect, DEFAULT_VALUES.effect);
		const customEffects = interaction.animation.value.custom_effect;
		const type = extractString(interaction.animation.value.type, DEFAULT_VALUES.type);
		const direction = extractString(interaction.animation.value.direction, DEFAULT_VALUES.direction);
		const duration = extractSize(interaction.animation.value.timing_config.value.duration);
		const delay = extractSize(interaction.animation.value.timing_config.value.delay);
		const replay = extractBoolean(interaction.animation.value.config?.value.replay, DEFAULT_VALUES.replay);
		const easing = extractString(interaction.animation.value.config?.value.easing, DEFAULT_VALUES.easing);
		const relativeTo = extractString(interaction.animation.value.config?.value.relativeTo, DEFAULT_VALUES.relativeTo);
		const configValue = interaction.animation.value.config?.value;
		const repeat = extractString(configValue?.repeat, DEFAULT_VALUES.repeat);
		const times = normalizeTimesValue(configValue?.times?.value, DEFAULT_VALUES.times);
		const start = extractSize(interaction.animation.value.config?.value.start, DEFAULT_VALUES.start);
		const end = extractSize(interaction.animation.value.config?.value.end, DEFAULT_VALUES.end);
		const interactionValues = {
			trigger,
			effect,
			type,
			direction,
			duration,
			delay,
			easing,
			replay,
			relativeTo,
			repeat,
			times,
			start,
			end,
			customEffects
		};
		const TriggerControl = useControlComponent("trigger", true);
		const EffectControl = useControlComponent("effect");
		const ReplayControl = useControlComponent("replay", controlVisibilityConfig.replay(interactionValues));
		const RelativeToControl = useControlComponent("relativeTo", controlVisibilityConfig.relativeTo(interactionValues));
		const StartControl = useControlComponent("start", controlVisibilityConfig.start(interactionValues));
		const EndControl = useControlComponent("end", controlVisibilityConfig.end(interactionValues));
		const CustomEffectControl = useControlComponent("customEffects", controlVisibilityConfig.custom(interactionValues));
		const EffectTypeControl = useControlComponent("effectType", controlVisibilityConfig.effectType(interactionValues));
		const DirectionControl = useControlComponent("direction", controlVisibilityConfig.direction(interactionValues));
		const RepeatControl = useControlComponent("repeat", controlVisibilityConfig.repeat(interactionValues));
		const TimesControl = useControlComponent("times", controlVisibilityConfig.times(interactionValues));
		const EasingControl = useControlComponent("easing");
		const updateInteraction = (updates) => {
			const resolvedDirectionValue = resolveDirection("direction" in updates, updates.effect, updates.direction, direction, effect);
			const updatedInteraction = {
				...interaction,
				interaction_id: interaction.interaction_id,
				trigger: createString(updates.trigger ?? trigger),
				animation: createAnimationPreset({
					effect: updates.effect ?? effect,
					type: updates.type ?? type,
					direction: resolvedDirectionValue,
					duration: updates.duration ?? duration,
					delay: updates.delay ?? delay,
					replay: updates.replay ?? replay,
					easing: updates.easing ?? easing,
					relativeTo: updates.relativeTo ?? relativeTo,
					repeat: updates.repeat ?? repeat,
					times: updates.times ?? times,
					start: updates.start ?? start,
					end: updates.end ?? end,
					customEffects: updates.customEffects ?? customEffects
				})
			};
			onChange(updatedInteraction);
			syncGridOverlay(updates.trigger ?? trigger, updates.start ?? start, updates.end ?? end, updates.relativeTo ?? relativeTo);
			const interactionId = extractString(updatedInteraction.interaction_id);
			setTimeout(() => {
				onPlayInteraction(interactionId);
			}, 0);
		};
		return /* @__PURE__ */ react.createElement(_elementor_editor_controls.PopoverContent, { p: 1.5 }, /* @__PURE__ */ react.createElement(_elementor_ui.Grid, {
			container: true,
			spacing: 1.5
		}, TriggerControl && /* @__PURE__ */ react.createElement(Field, { label: (0, _wordpress_i18n.__)("Trigger", "elementor") }, /* @__PURE__ */ react.createElement(TriggerControl, {
			value: trigger,
			onChange: (v) => updateInteraction({ trigger: v })
		})), ReplayControl && /* @__PURE__ */ react.createElement(Field, { label: (0, _wordpress_i18n.__)("Replay", "elementor") }, /* @__PURE__ */ react.createElement(ReplayControl, {
			value: replay,
			onChange: (v) => updateInteraction({ replay: v }),
			disabled: true
		}))), /* @__PURE__ */ react.createElement(_elementor_ui.Divider, null), /* @__PURE__ */ react.createElement(_elementor_ui.Grid, {
			container: true,
			spacing: 1.5
		}, EffectControl && /* @__PURE__ */ react.createElement(Field, { label: (0, _wordpress_i18n.__)("Effect", "elementor") }, /* @__PURE__ */ react.createElement(EffectControl, {
			value: effect,
			onChange: (v) => updateInteraction({ effect: v })
		})), CustomEffectControl && /* @__PURE__ */ react.createElement(Field, { label: (0, _wordpress_i18n.__)("Custom Effect", "elementor") }, /* @__PURE__ */ react.createElement(CustomEffectControl, {
			value: customEffects,
			onChange: (v) => updateInteraction({ customEffects: v })
		})), EffectTypeControl && /* @__PURE__ */ react.createElement(Field, { label: (0, _wordpress_i18n.__)("Type", "elementor") }, /* @__PURE__ */ react.createElement(EffectTypeControl, {
			value: type,
			onChange: (v) => updateInteraction({ type: v })
		})), DirectionControl && /* @__PURE__ */ react.createElement(Field, { label: (0, _wordpress_i18n.__)("Direction", "elementor") }, /* @__PURE__ */ react.createElement(DirectionControl, {
			value: direction,
			onChange: (v) => updateInteraction({ direction: v }),
			interactionType: type
		})), RepeatControl && /* @__PURE__ */ react.createElement(Field, { label: (0, _wordpress_i18n.__)("Repeat", "elementor") }, /* @__PURE__ */ react.createElement(RepeatControl, {
			value: repeat,
			onChange: (v) => updateInteraction({ repeat: v })
		})), TimesControl && /* @__PURE__ */ react.createElement(Field, { label: (0, _wordpress_i18n.__)("Times", "elementor") }, /* @__PURE__ */ react.createElement(TimesControl, {
			value: times,
			onChange: (v) => updateInteraction({ times: normalizeTimesValue(v, DEFAULT_VALUES.times) })
		})), controlVisibilityConfig.duration(interactionValues) && /* @__PURE__ */ react.createElement(Field, { label: (0, _wordpress_i18n.__)("Duration", "elementor") }, /* @__PURE__ */ react.createElement(TimeFrameIndicator, {
			value: String(duration),
			onChange: (v) => updateInteraction({ duration: v }),
			defaultValue: DEFAULT_VALUES.duration
		})), controlVisibilityConfig.delay(interactionValues) && /* @__PURE__ */ react.createElement(Field, { label: (0, _wordpress_i18n.__)("Delay", "elementor") }, /* @__PURE__ */ react.createElement(TimeFrameIndicator, {
			value: String(delay),
			onChange: (v) => updateInteraction({ delay: v }),
			defaultValue: DEFAULT_VALUES.delay
		}))), controlVisibilityConfig.relativeTo(interactionValues) && RelativeToControl && /* @__PURE__ */ react.createElement(react.Fragment, null, /* @__PURE__ */ react.createElement(_elementor_ui.Divider, null), /* @__PURE__ */ react.createElement(_elementor_ui.Grid, {
			container: true,
			spacing: 1.5
		}, StartControl && /* @__PURE__ */ react.createElement(Field, { label: (0, _wordpress_i18n.__)("Start", "elementor") }, /* @__PURE__ */ react.createElement(StartControl, {
			value: parseSizeValue(start, ["%"]).size?.toString() ?? "",
			onChange: (v) => updateInteraction({ start: v })
		})), EndControl && /* @__PURE__ */ react.createElement(Field, { label: (0, _wordpress_i18n.__)("End", "elementor") }, /* @__PURE__ */ react.createElement(EndControl, {
			value: parseSizeValue(end, ["%"]).size?.toString() ?? "",
			onChange: (v) => updateInteraction({ end: v })
		})), /* @__PURE__ */ react.createElement(Field, { label: (0, _wordpress_i18n.__)("Relative To", "elementor") }, /* @__PURE__ */ react.createElement(RelativeToControl, {
			value: relativeTo,
			onChange: (v) => updateInteraction({ relativeTo: v })
		}))), /* @__PURE__ */ react.createElement(_elementor_ui.Divider, null)), EasingControl && /* @__PURE__ */ react.createElement(_elementor_ui.Grid, {
			container: true,
			spacing: 1.5
		}, /* @__PURE__ */ react.createElement(Field, { label: (0, _wordpress_i18n.__)("Easing", "elementor") }, /* @__PURE__ */ react.createElement(EasingControl, {
			value: easing,
			onChange: (v) => {
				updateInteraction({ easing: v });
			}
		}))));
	};

//#endregion
//#region packages/packages/core/editor-interactions/src/components/interaction-settings.tsx
	var SIZE = "tiny";
	var InteractionSettings = ({ interaction, onChange }) => {
		const breakpoints = (0, _elementor_editor_responsive.useBreakpoints)();
		const availableBreakpoints = (0, react.useMemo)(() => breakpoints.map((breakpoint) => ({
			label: breakpoint.label,
			value: String(breakpoint.id)
		})), [breakpoints]);
		const [selectedBreakpoints, setSelectedBreakpoints] = (0, react.useState)(() => {
			const excluded = extractExcludedBreakpoints(interaction.breakpoints).filter((excludedBreakpoint) => {
				return availableBreakpoints.some(({ value }) => value === excludedBreakpoint);
			});
			return availableBreakpoints.filter(({ value }) => {
				return !excluded.includes(value);
			});
		});
		const handleBreakpointChange = (0, react.useCallback)((_, newValue) => {
			setSelectedBreakpoints(newValue);
			const selectedValues = newValue.map((option) => option.value);
			const newExcluded = availableBreakpoints.filter((breakpoint) => !selectedValues.includes(breakpoint.value)).map((breakpoint) => breakpoint.value);
			const updatedInteraction = {
				...interaction,
				...newExcluded.length > 0 && { breakpoints: createInteractionBreakpoints(newExcluded) }
			};
			if (newExcluded.length === 0) delete updatedInteraction.breakpoints;
			onChange(updatedInteraction);
		}, [
			interaction,
			availableBreakpoints,
			onChange
		]);
		return /* @__PURE__ */ react.createElement(_elementor_editor_controls.PopoverContent, { p: 1.5 }, /* @__PURE__ */ react.createElement(_elementor_ui.Grid, {
			container: true,
			spacing: 1.5
		}, /* @__PURE__ */ react.createElement(_elementor_ui.Grid, {
			item: true,
			xs: 12
		}, /* @__PURE__ */ react.createElement(_elementor_ui.Stack, {
			direction: "column",
			gap: 1
		}, /* @__PURE__ */ react.createElement(_elementor_editor_controls.ControlFormLabel, { sx: { width: "100%" } }, (0, _wordpress_i18n.__)("Trigger on", "elementor")), /* @__PURE__ */ react.createElement(_elementor_ui.Autocomplete, {
			fullWidth: true,
			multiple: true,
			value: selectedBreakpoints,
			onChange: handleBreakpointChange,
			size: SIZE,
			options: availableBreakpoints,
			isOptionEqualToValue: (option, value) => option.value === value.value,
			renderInput: (params) => /* @__PURE__ */ react.createElement(_elementor_ui.TextField, { ...params }),
			renderTags: (values, getTagProps) => values.map((option, index) => {
				const { key, ...chipProps } = getTagProps({ index });
				return /* @__PURE__ */ react.createElement(_elementor_ui.Chip, {
					key,
					size: SIZE,
					label: option.label,
					...chipProps
				});
			})
		})))));
	};

//#endregion
//#region packages/packages/core/editor-interactions/src/components/interactions-list-item.tsx
	var InteractionsListItem = ({ index, value: interaction }) => {
		const { getTabsProps, getTabProps, getTabPanelProps } = (0, _elementor_ui.useTabs)("details");
		const context = useInteractionItemContext();
		const handleChange = (0, react.useCallback)((newInteractionValue) => {
			context?.onInteractionChange(index, newInteractionValue);
		}, [context, index]);
		const handlePlayInteraction = (0, react.useCallback)((interactionId2) => {
			context?.onPlayInteraction(interactionId2);
		}, [context]);
		const interactionId = extractString(interaction.value.interaction_id);
		return /* @__PURE__ */ react.createElement(react.Fragment, null, /* @__PURE__ */ react.createElement(_elementor_ui.Tabs, {
			size: "small",
			variant: "fullWidth",
			"aria-label": (0, _wordpress_i18n.__)("Interaction", "elementor"),
			...getTabsProps()
		}, /* @__PURE__ */ react.createElement(_elementor_ui.Tab, {
			label: (0, _wordpress_i18n.__)("Details", "elementor"),
			...getTabProps("details")
		}), /* @__PURE__ */ react.createElement(_elementor_ui.Tab, {
			label: (0, _wordpress_i18n.__)("Settings", "elementor"),
			...getTabProps("settings")
		})), /* @__PURE__ */ react.createElement(_elementor_ui.Divider, null), /* @__PURE__ */ react.createElement(_elementor_ui.TabPanel, {
			sx: { p: 0 },
			...getTabPanelProps("details")
		}, /* @__PURE__ */ react.createElement(InteractionDetails, {
			key: interactionId,
			interaction: interaction.value,
			onChange: handleChange,
			onPlayInteraction: handlePlayInteraction
		})), /* @__PURE__ */ react.createElement(_elementor_ui.TabPanel, {
			sx: { p: 0 },
			...getTabPanelProps("settings")
		}, /* @__PURE__ */ react.createElement(InteractionSettings, {
			key: interactionId,
			interaction: interaction.value,
			onChange: handleChange
		})));
	};

//#endregion
//#region packages/packages/core/editor-interactions/src/components/interactions-list.tsx
	var MAX_NUMBER_OF_INTERACTIONS = 5;
	function InteractionsList(props) {
		const { interactions, onSelectInteractions, onPlayInteraction, triggerCreateOnShowEmpty } = props;
		const { elementId } = useInteractionsContext();
		const hasInitializedRef = (0, react.useRef)(false);
		const newlyCreatedIdsRef = (0, react.useRef)(/* @__PURE__ */ new Set());
		const handleUpdateInteractions = (0, react.useCallback)((newInteractions) => {
			onSelectInteractions(newInteractions);
		}, [onSelectInteractions]);
		(0, react.useEffect)(() => {
			if (triggerCreateOnShowEmpty && !hasInitializedRef.current && (!interactions.items || interactions.items?.length === 0)) {
				hasInitializedRef.current = true;
				const newItem = createDefaultInteractionItem();
				newlyCreatedIdsRef.current.add(extractString(newItem.value.interaction_id));
				handleUpdateInteractions({
					version: 1,
					items: [newItem]
				});
			}
		}, [
			triggerCreateOnShowEmpty,
			interactions.items,
			handleUpdateInteractions
		]);
		const isMaxNumberOfInteractionsReached = (0, react.useMemo)(() => {
			return interactions.items?.length >= 5;
		}, [interactions.items?.length]);
		const infotipContent = isMaxNumberOfInteractionsReached ? /* @__PURE__ */ react.createElement(_elementor_ui.Alert, {
			color: "secondary",
			icon: /* @__PURE__ */ react.createElement(_elementor_icons.InfoCircleFilledIcon, null),
			size: "small"
		}, /* @__PURE__ */ react.createElement(_elementor_ui.AlertTitle, null, (0, _wordpress_i18n.__)("Interactions", "elementor")), /* @__PURE__ */ react.createElement(_elementor_ui.Box, { component: "span" }, (0, _wordpress_i18n.__)("You've reached the limit of 5 interactions for this element. Please remove an interaction before creating a new one.", "elementor"))) : void 0;
		const handleRepeaterChange = (0, react.useCallback)((newItems, _, meta) => {
			handleUpdateInteractions({
				...interactions,
				items: newItems
			});
			if (meta?.action?.type === "add") {
				const addedItem = meta.action.payload[0]?.item;
				if (addedItem) newlyCreatedIdsRef.current.add(extractString(addedItem.value.interaction_id));
			}
		}, [interactions, handleUpdateInteractions]);
		const handleInteractionChange = (0, react.useCallback)((index, newInteractionValue) => {
			const newItems = structuredClone(interactions.items);
			newItems[index] = {
				$$type: "interaction-item",
				value: newInteractionValue
			};
			handleUpdateInteractions({
				...interactions,
				items: newItems
			});
		}, [interactions, handleUpdateInteractions]);
		const contextValue = (0, react.useMemo)(() => ({
			onInteractionChange: handleInteractionChange,
			onPlayInteraction
		}), [handleInteractionChange, onPlayInteraction]);
		return /* @__PURE__ */ react.createElement(InteractionItemContextProvider, { value: contextValue }, /* @__PURE__ */ react.createElement(_elementor_editor_controls.Repeater, {
			openOnAdd: true,
			openItem: triggerCreateOnShowEmpty ? 0 : void 0,
			label: (0, _wordpress_i18n.__)("Interactions", "elementor"),
			values: interactions.items,
			setValues: handleRepeaterChange,
			showDuplicate: false,
			showToggle: false,
			isSortable: false,
			disableAddItemButton: isMaxNumberOfInteractionsReached,
			addButtonInfotipContent: infotipContent,
			itemSettings: {
				initialValues: createDefaultInteractionItem(),
				Label: ({ value }) => buildDisplayLabel(value.value),
				Icon: () => null,
				Content: InteractionsListItem,
				onPopoverOpen: (value) => {
					const { trigger, start, end, relativeTo } = extractScrollOverlayParams(value.value, DEFAULT_VALUES);
					syncGridOverlay(trigger, start, end, relativeTo);
				},
				onPopoverClose: (value) => {
					dispatchScrollInteraction(null);
					const id = extractString(value.value.interaction_id);
					if (newlyCreatedIdsRef.current.has(id)) {
						newlyCreatedIdsRef.current.delete(id);
						trackInteractionCreated(elementId, value);
					}
				},
				actions: (value) => /* @__PURE__ */ react.createElement(_elementor_ui.Tooltip, {
					key: "preview",
					placement: "top",
					title: (0, _wordpress_i18n.__)("Preview", "elementor")
				}, /* @__PURE__ */ react.createElement(_elementor_ui.IconButton, {
					"aria-label": (0, _wordpress_i18n.__)("Play interaction", "elementor"),
					size: "tiny",
					onClick: () => onPlayInteraction(extractString(value.value.interaction_id))
				}, /* @__PURE__ */ react.createElement(_elementor_icons.PlayerPlayIcon, { fontSize: "tiny" })))
			}
		}));
	}

//#endregion
//#region packages/packages/core/editor-interactions/src/components/interactions-tab.tsx
	var InteractionsTab = ({ elementId }) => {
		return /* @__PURE__ */ react.createElement(PopupStateProvider, null, /* @__PURE__ */ react.createElement(InteractionsTabContent, { elementId }));
	};
	function InteractionsTabContent({ elementId }) {
		const existingInteractions = useElementInteractions(elementId);
		const firstInteractionState = (0, react.useState)(false);
		const hasInteractions = existingInteractions?.items?.length || firstInteractionState[0];
		return /* @__PURE__ */ react.createElement(_elementor_session.SessionStorageProvider, { prefix: elementId }, hasInteractions ? /* @__PURE__ */ react.createElement(InteractionsProvider, { elementId }, /* @__PURE__ */ react.createElement(InteractionsContent, { firstInteractionState })) : /* @__PURE__ */ react.createElement(EmptyState, { onCreateInteraction: () => {
			firstInteractionState[1](true);
		} }));
	}
	function InteractionsContent({ firstInteractionState }) {
		const { interactions, setInteractions, playInteractions } = useInteractionsContext();
		const applyInteraction = (0, react.useCallback)((newInteractions) => {
			firstInteractionState[1](false);
			if (!newInteractions) {
				setInteractions(void 0);
				return;
			}
			setInteractions(newInteractions);
		}, [setInteractions, firstInteractionState]);
		return /* @__PURE__ */ react.createElement(_elementor_ui.Stack, {
			sx: {
				m: 1,
				p: 1.5
			},
			gap: 2
		}, /* @__PURE__ */ react.createElement(InteractionsList, {
			triggerCreateOnShowEmpty: firstInteractionState[0],
			interactions,
			onSelectInteractions: applyInteraction,
			onPlayInteraction: playInteractions
		}));
	}

//#endregion
//#region packages/packages/core/editor-interactions/src/utils/create-interactions-repository.ts
	var createInteractionsRepository = () => {
		const providers = [];
		const getProviders = () => {
			return providers.slice(0).sort((a, b) => a.priority > b.priority ? -1 : 1);
		};
		const register = (provider) => {
			providers.push(provider);
		};
		const all = () => {
			return getProviders().flatMap((provider) => provider.actions.all());
		};
		const subscribe = (cb) => {
			const unsubscribes = providers.map((provider) => provider.subscribe(cb));
			return () => {
				unsubscribes.forEach((unsubscribe) => unsubscribe());
			};
		};
		const getProviderByKey = (key) => {
			return providers.find((provider) => {
				try {
					return provider.getKey() === key;
				} catch {
					return false;
				}
			});
		};
		return {
			all,
			register,
			subscribe,
			getProviders,
			getProviderByKey
		};
	};

//#endregion
//#region packages/packages/core/editor-interactions/src/interactions-repository.ts
	var interactionsRepository = createInteractionsRepository();

//#endregion
//#region packages/packages/core/editor-interactions/src/utils/create-interactions-provider.ts
	var DEFAULT_PRIORITY = 10;
	function createInteractionsProvider({ key, priority = DEFAULT_PRIORITY, subscribe = () => () => {}, actions }) {
		return {
			getKey: typeof key === "string" ? () => key : key,
			priority,
			subscribe,
			actions: { all: actions.all }
		};
	}

//#endregion
//#region packages/packages/core/editor-interactions/src/providers/document-elements-interactions-provider.ts
	var ELEMENTS_INTERACTIONS_PROVIDER_KEY_PREFIX = "document-elements-interactions-";
	var documentElementsInteractionsProvider = createInteractionsProvider({
		key: () => {
			const documentId = (0, _elementor_editor_elements.getCurrentDocumentId)();
			if (!documentId) return `${ELEMENTS_INTERACTIONS_PROVIDER_KEY_PREFIX}pending`;
			return `${ELEMENTS_INTERACTIONS_PROVIDER_KEY_PREFIX}${documentId}`;
		},
		priority: 50,
		subscribe: (cb) => {
			return (0, _elementor_editor_v1_adapters.__privateListenTo)([(0, _elementor_editor_v1_adapters.windowEvent)("elementor/element/update_interactions")], () => cb());
		},
		actions: { all: () => {
			return (0, _elementor_editor_elements.getElements)().filter((element) => {
				const interactions = (0, _elementor_editor_elements.getElementInteractions)(element.id);
				if (!interactions) return false;
				return interactions?.items?.length > 0;
			}).map((element) => {
				const interactions = (0, _elementor_editor_elements.getElementInteractions)(element.id);
				return {
					elementId: element.id,
					dataId: element.id,
					interactions: interactions || {
						version: 1,
						items: []
					}
				};
			});
		} }
	});

//#endregion
//#region packages/packages/core/editor-interactions/src/commands/get-clipboard-elements.ts
	function getClipboardElements(storageKey = "clipboard") {
		try {
			return JSON.parse(localStorage.getItem("elementor") ?? "{}")[storageKey]?.elements;
		} catch {
			return;
		}
	}

//#endregion
//#region packages/packages/core/editor-interactions/src/commands/paste-interactions.ts
	function isAtomicContainer(container) {
		const type = container?.model.get("widgetType") || container?.model.get("elType");
		const elementConfig = (0, _elementor_editor_elements.getWidgetsCache)()?.[type];
		return Boolean(elementConfig?.atomic_props_schema);
	}
	function getTitleForContainers(containers) {
		return containers.length > 1 ? (0, _wordpress_i18n.__)("Elements", "elementor") : (0, _elementor_editor_elements.getElementLabel)(containers[0].id);
	}
	function normalizeClipboardInteractions(raw) {
		if (!raw) return null;
		const parsed = typeof raw === "string" ? JSON.parse(raw) : raw;
		const payload = {
			version: parsed?.version ?? 1,
			items: parsed?.items?.filter((item) => isSupportedInteractionItem(item)) ?? []
		};
		if (!payload.items.length) return null;
		return payload;
	}
	function regenerateInteractionIds(interactions) {
		const cloned = structuredClone(interactions);
		cloned.items?.forEach((item) => {
			if (item.$$type === "interaction-item" && item.value) item.value.interaction_id = createString(generateTempInteractionId());
		});
		return cloned;
	}
	function initPasteInteractionsCommand() {
		const undoablePasteInteractions = (0, _elementor_editor_v1_adapters.undoable)({
			do: ({ containers, newInteractions }) => {
				const pasted = regenerateInteractionIds(newInteractions);
				return containers.map((container) => {
					const elementId = container.id;
					const previous = (0, _elementor_editor_elements.getElementInteractions)(elementId);
					(0, _elementor_editor_elements.updateElementInteractions)({
						elementId,
						interactions: pasted
					});
					return {
						elementId,
						previous: previous ?? {
							version: 1,
							items: []
						}
					};
				});
			},
			undo: (_, revertData) => {
				revertData.forEach(({ elementId, previous }) => {
					(0, _elementor_editor_elements.updateElementInteractions)({
						elementId,
						interactions: previous.items?.length ? previous : void 0
					});
				});
			}
		}, {
			title: ({ containers }) => getTitleForContainers(containers),
			subtitle: (0, _wordpress_i18n.__)("Interactions Pasted", "elementor")
		});
		(0, _elementor_editor_v1_adapters.__privateListenTo)((0, _elementor_editor_v1_adapters.commandStartEvent)("document/elements/paste-interactions"), (e) => {
			const args = e.args;
			const containers = args.containers ?? (args.container ? [args.container] : []);
			const storageKey = args.storageKey ?? "clipboard";
			if (!containers.length) return;
			const [clipboardElement] = getClipboardElements(storageKey) ?? [];
			if (!clipboardElement) return;
			const newInteractions = normalizeClipboardInteractions(clipboardElement.interactions);
			if (!newInteractions) return;
			const validContainers = containers.filter((c) => (0, _elementor_editor_elements.getContainer)(c.id)).filter(isAtomicContainer);
			if (!validContainers.length) return;
			undoablePasteInteractions({
				containers: validContainers,
				newInteractions
			});
		});
	}

//#endregion
//#region packages/packages/core/editor-interactions/src/components/controls/direction.tsx
	var AXIS = {
		top: "vertical",
		bottom: "vertical",
		left: "horizontal",
		right: "horizontal"
	};
	function parseValue(value) {
		return value.split("-").filter(Boolean);
	}
	function serializeValue(directions) {
		const vertical = directions.find((d) => d === "top" || d === "bottom");
		const horizontal = directions.find((d) => d === "left" || d === "right");
		if (vertical && horizontal) return `${vertical}-${horizontal}`;
		return directions[0] ?? "";
	}
	function toggleDirection(current, clicked) {
		if (current.includes(clicked)) return current.filter((d) => d !== clicked);
		return [...current.filter((d) => AXIS[d] !== AXIS[clicked]), clicked];
	}
	function Direction({ value, onChange, interactionType }) {
		const isIn = interactionType === "in";
		const options = (0, react.useMemo)(() => [
			{
				dir: "top",
				label: isIn ? (0, _wordpress_i18n.__)("From top", "elementor") : (0, _wordpress_i18n.__)("To top", "elementor"),
				Icon: isIn ? _elementor_icons.ArrowDownSmallIcon : _elementor_icons.ArrowUpSmallIcon
			},
			{
				dir: "bottom",
				label: isIn ? (0, _wordpress_i18n.__)("From bottom", "elementor") : (0, _wordpress_i18n.__)("To bottom", "elementor"),
				Icon: isIn ? _elementor_icons.ArrowUpSmallIcon : _elementor_icons.ArrowDownSmallIcon
			},
			{
				dir: "left",
				label: isIn ? (0, _wordpress_i18n.__)("From left", "elementor") : (0, _wordpress_i18n.__)("To left", "elementor"),
				Icon: isIn ? _elementor_icons.ArrowRightIcon : _elementor_icons.ArrowLeftIcon
			},
			{
				dir: "right",
				label: isIn ? (0, _wordpress_i18n.__)("From right", "elementor") : (0, _wordpress_i18n.__)("To right", "elementor"),
				Icon: isIn ? _elementor_icons.ArrowLeftIcon : _elementor_icons.ArrowRightIcon
			}
		], [isIn]);
		const selectedDirections = (0, react.useMemo)(() => parseValue(value), [value]);
		return /* @__PURE__ */ react.createElement(_elementor_editor_controls.StyledToggleButtonGroup, {
			size: "tiny",
			justify: "end",
			sx: {
				display: "grid",
				gridTemplateColumns: "repeat(4, minmax(0, 25%))",
				width: "100%"
			}
		}, options.map(({ dir, label, Icon }) => /* @__PURE__ */ react.createElement(_elementor_ui.Tooltip, {
			key: dir,
			title: label,
			disableFocusListener: true,
			placement: "top"
		}, /* @__PURE__ */ react.createElement(_elementor_editor_controls.StyledToggleButton, {
			value: dir,
			selected: selectedDirections.includes(dir),
			"aria-label": label,
			size: "tiny",
			isPlaceholder: false,
			onChange: () => {
				onChange(serializeValue(toggleDirection(selectedDirections, dir)));
			}
		}, /* @__PURE__ */ react.createElement(Icon, { fontSize: "tiny" })))));
	}

//#endregion
//#region packages/packages/core/editor-interactions/src/ui/interactions-promotion-chip.tsx
	var InteractionsPromotionChip = (0, react.forwardRef)(({ content, upgradeUrl, anchorRef, trackingData }, ref) => {
		const [isOpen, setIsOpen] = (0, react.useState)(false);
		(0, _elementor_editor_ui.useCanvasClickHandler)(isOpen, () => setIsOpen(false));
		const toggle = (0, react.useCallback)(() => {
			setIsOpen((prev) => {
				if (!prev) (0, _elementor_editor_controls.trackViewPromotion)(trackingData);
				return !prev;
			});
		}, [trackingData]);
		(0, react.useImperativeHandle)(ref, () => ({ toggle }), [toggle]);
		const handleToggle = (e) => {
			e.stopPropagation();
			toggle();
		};
		return /* @__PURE__ */ react.createElement(_elementor_editor_ui.PromotionPopover, {
			open: isOpen,
			title: (0, _wordpress_i18n.__)("Interactions", "elementor"),
			content,
			ctaText: (0, _wordpress_i18n.__)("Upgrade now", "elementor"),
			ctaUrl: upgradeUrl,
			anchorRef,
			placement: anchorRef ? "right-start" : void 0,
			onClose: (e) => {
				e.stopPropagation();
				setIsOpen(false);
			},
			onCtaClick: () => (0, _elementor_editor_controls.trackUpgradePromotionClick)(trackingData)
		}, /* @__PURE__ */ react.createElement(_elementor_ui.Box, {
			onMouseDown: (e) => e.stopPropagation(),
			onClick: handleToggle,
			sx: {
				cursor: "pointer",
				display: "inline-flex",
				mr: 1
			}
		}, /* @__PURE__ */ react.createElement(_elementor_editor_ui.PromotionChip, null)));
	});

//#endregion
//#region packages/packages/core/editor-interactions/src/ui/promotion-select.tsx
	function PromotionSelect({ value, onChange, baseOptions, disabledOptions, promotionLabel, promotionContent, upgradeUrl, trackingData }) {
		const promotionRef = (0, react.useRef)(null);
		const anchorRef = (0, react.useRef)(null);
		return /* @__PURE__ */ react.createElement(_elementor_ui.Select, {
			value,
			onChange: (e) => onChange?.(e.target.value),
			fullWidth: true,
			displayEmpty: true,
			size: "tiny",
			MenuProps: { disablePortal: true }
		}, Object.entries(baseOptions).map(([key, label]) => /* @__PURE__ */ react.createElement(_elementor_editor_ui.MenuListItem, {
			key,
			value: key
		}, label)), /* @__PURE__ */ react.createElement(_elementor_ui.MenuSubheader, {
			ref: anchorRef,
			sx: {
				cursor: "pointer",
				color: "text.tertiary",
				fontWeight: "400",
				display: "flex",
				alignItems: "center"
			},
			onMouseDown: (e) => {
				e.stopPropagation();
				promotionRef.current?.toggle();
			}
		}, promotionLabel ?? (0, _wordpress_i18n.__)("PRO features", "elementor"), /* @__PURE__ */ react.createElement(InteractionsPromotionChip, {
			content: promotionContent,
			upgradeUrl,
			ref: promotionRef,
			anchorRef,
			trackingData
		})), Object.entries(disabledOptions).map(([key, label]) => /* @__PURE__ */ react.createElement(_elementor_editor_ui.MenuListItem, {
			key,
			value: key,
			disabled: true,
			sx: { pl: 3 }
		}, label)));
	}

//#endregion
//#region packages/packages/core/editor-interactions/src/components/controls/easing.tsx
	var TRACKING_DATA$4 = {
		target_name: "interactions_easing",
		location_l2: "interactions"
	};
	var EASING_OPTIONS = {
		easeIn: (0, _wordpress_i18n.__)("Ease In", "elementor"),
		easeInOut: (0, _wordpress_i18n.__)("Ease In Out", "elementor"),
		easeOut: (0, _wordpress_i18n.__)("Ease Out", "elementor"),
		backIn: (0, _wordpress_i18n.__)("Back In", "elementor"),
		backInOut: (0, _wordpress_i18n.__)("Back In Out", "elementor"),
		backOut: (0, _wordpress_i18n.__)("Back Out", "elementor"),
		linear: (0, _wordpress_i18n.__)("Linear", "elementor")
	};
	var BASE_EASINGS = ["easeIn"];
	function Easing({}) {
		const baseOptions = Object.fromEntries(Object.entries(EASING_OPTIONS).filter(([key]) => BASE_EASINGS.includes(key)));
		const disabledOptions = Object.fromEntries(Object.entries(EASING_OPTIONS).filter(([key]) => !BASE_EASINGS.includes(key)));
		return /* @__PURE__ */ react.createElement(PromotionSelect, {
			value: DEFAULT_VALUES.easing,
			baseOptions,
			disabledOptions,
			promotionContent: (0, _wordpress_i18n.__)("Upgrade to control the smoothness of the interaction.", "elementor"),
			upgradeUrl: "https://go.elementor.com/go-pro-interactions-easing-modal/",
			trackingData: TRACKING_DATA$4
		});
	}

//#endregion
//#region packages/packages/core/editor-interactions/src/components/controls/effect.tsx
	var TRACKING_DATA$3 = {
		target_name: "interactions_effect",
		location_l2: "interactions"
	};
	var EFFECT_OPTIONS = {
		fade: (0, _wordpress_i18n.__)("Fade", "elementor"),
		slide: (0, _wordpress_i18n.__)("Slide", "elementor"),
		scale: (0, _wordpress_i18n.__)("Scale", "elementor"),
		custom: (0, _wordpress_i18n.__)("Custom", "elementor")
	};
	var BASE_EFFECTS = [
		"fade",
		"slide",
		"scale"
	];
	function Effect({ value, onChange }) {
		const baseOptions = Object.fromEntries(Object.entries(EFFECT_OPTIONS).filter(([key]) => BASE_EFFECTS.includes(key)));
		const disabledOptions = Object.fromEntries(Object.entries(EFFECT_OPTIONS).filter(([key]) => !BASE_EFFECTS.includes(key)));
		return /* @__PURE__ */ react.createElement(PromotionSelect, {
			value: value in baseOptions ? value : DEFAULT_VALUES.effect,
			onChange,
			baseOptions,
			disabledOptions,
			promotionLabel: (0, _wordpress_i18n.__)("PRO effects", "elementor"),
			promotionContent: (0, _wordpress_i18n.__)("Upgrade to further customize your animation with opacity, scale, move, rotate and more.", "elementor"),
			upgradeUrl: "https://go.elementor.com/go-pro-interactions-custom-effect-modal/",
			trackingData: TRACKING_DATA$3
		});
	}

//#endregion
//#region packages/packages/core/editor-interactions/src/components/controls/effect-type.tsx
	function EffectType({ value, onChange }) {
		const options = [{
			value: "in",
			label: (0, _wordpress_i18n.__)("In", "elementor"),
			renderContent: () => (0, _wordpress_i18n.__)("In", "elementor"),
			showTooltip: true
		}, {
			value: "out",
			label: (0, _wordpress_i18n.__)("Out", "elementor"),
			renderContent: () => (0, _wordpress_i18n.__)("Out", "elementor"),
			showTooltip: true
		}];
		return /* @__PURE__ */ react.createElement(_elementor_editor_controls.ToggleButtonGroupUi, {
			items: options,
			exclusive: true,
			onChange,
			value
		});
	}

//#endregion
//#region packages/packages/core/editor-interactions/src/ui/promotion-overlay-layout.tsx
	var OVERLAY_GRID = "1 / 1";
	var CHIP_OFFSET = "50%";
	var PromotionOverlayLayout = (0, react.forwardRef)(({ children, promotionChip }, ref) => /* @__PURE__ */ react.createElement(_elementor_ui.Box, {
		ref,
		sx: {
			display: "grid",
			alignItems: "center"
		}
	}, /* @__PURE__ */ react.createElement(_elementor_ui.Box, { sx: { gridArea: OVERLAY_GRID } }, children), /* @__PURE__ */ react.createElement(_elementor_ui.Box, { sx: {
		gridArea: OVERLAY_GRID,
		marginInlineEnd: CHIP_OFFSET,
		justifySelf: "end"
	} }, promotionChip)));

//#endregion
//#region packages/packages/core/editor-interactions/src/components/controls/repeat.tsx
	var TRACKING_DATA$2 = {
		target_name: "interactions_repeat",
		location_l2: "interactions"
	};
	var REPEAT_OPTIONS = {
		times: (0, _wordpress_i18n.__)("times", "elementor"),
		loop: (0, _wordpress_i18n.__)("loop", "elementor")
	};
	var REPEAT_TOOLTIPS = {
		times: (0, _wordpress_i18n.__)("Enable number", "elementor"),
		loop: (0, _wordpress_i18n.__)("Infinite repeat", "elementor")
	};
	function Repeat() {
		const repeatContainerRef = (0, react.useRef)(null);
		const options = [{
			value: REPEAT_OPTIONS.times,
			disabled: true,
			label: REPEAT_TOOLTIPS.times,
			renderContent: ({ size }) => /* @__PURE__ */ react.createElement(_elementor_icons.Number123Icon, { fontSize: size }),
			showTooltip: true
		}, {
			value: REPEAT_OPTIONS.loop,
			disabled: true,
			label: REPEAT_TOOLTIPS.loop,
			renderContent: ({ size }) => /* @__PURE__ */ react.createElement(_elementor_icons.RepeatIcon, { fontSize: size }),
			showTooltip: true
		}];
		return /* @__PURE__ */ react.createElement(PromotionOverlayLayout, {
			ref: repeatContainerRef,
			promotionChip: /* @__PURE__ */ react.createElement(InteractionsPromotionChip, {
				content: (0, _wordpress_i18n.__)("Upgrade to control how many times the animation repeats.", "elementor"),
				upgradeUrl: "https://go.elementor.com/go-pro-interactions-repeat-modal/",
				anchorRef: repeatContainerRef,
				trackingData: TRACKING_DATA$2
			})
		}, /* @__PURE__ */ react.createElement(_elementor_editor_controls.ToggleButtonGroupUi, {
			items: options,
			exclusive: true,
			onChange: () => {},
			value: ""
		}));
	}

//#endregion
//#region packages/packages/core/editor-interactions/src/components/controls/replay.tsx
	var TRACKING_DATA$1 = {
		target_name: "interactions_replay",
		location_l2: "interactions"
	};
	var REPLAY_OPTIONS = {
		no: (0, _wordpress_i18n.__)("No", "elementor"),
		yes: (0, _wordpress_i18n.__)("Yes", "elementor")
	};
	var BASE_REPLAY = ["no"];
	function Replay({ onChange }) {
		const replayContainerRef = (0, react.useRef)(null);
		const options = [{
			value: false,
			disabled: false,
			label: REPLAY_OPTIONS.no,
			renderContent: ({ size }) => /* @__PURE__ */ react.createElement(_elementor_icons.MinusIcon, { fontSize: size }),
			showTooltip: true
		}, {
			value: true,
			disabled: true,
			label: REPLAY_OPTIONS.yes,
			renderContent: ({ size }) => /* @__PURE__ */ react.createElement(_elementor_icons.CheckIcon, { fontSize: size }),
			showTooltip: true
		}];
		return /* @__PURE__ */ react.createElement(PromotionOverlayLayout, {
			ref: replayContainerRef,
			promotionChip: /* @__PURE__ */ react.createElement(InteractionsPromotionChip, {
				content: (0, _wordpress_i18n.__)("Upgrade to run the animation every time its trigger occurs.", "elementor"),
				upgradeUrl: "https://go.elementor.com/go-pro-interactions-replay-modal/",
				anchorRef: replayContainerRef,
				trackingData: TRACKING_DATA$1
			})
		}, /* @__PURE__ */ react.createElement(_elementor_editor_controls.ToggleButtonGroupUi, {
			items: options,
			exclusive: true,
			onChange,
			value: false
		}));
	}

//#endregion
//#region packages/packages/core/editor-interactions/src/components/controls/trigger.tsx
	var TRACKING_DATA = {
		target_name: "interactions_trigger",
		location_l2: "interactions"
	};
	var TRIGGER_OPTIONS = {
		load: (0, _wordpress_i18n.__)("Page load", "elementor"),
		scrollIn: (0, _wordpress_i18n.__)("Scroll into view", "elementor"),
		scrollOn: (0, _wordpress_i18n.__)("While scrolling", "elementor"),
		hover: (0, _wordpress_i18n.__)("On hover", "elementor"),
		click: (0, _wordpress_i18n.__)("On click", "elementor")
	};
	var BASE_TRIGGERS = ["load", "scrollIn"];
	function Trigger({ value, onChange }) {
		const baseOptions = Object.fromEntries(Object.entries(TRIGGER_OPTIONS).filter(([key]) => BASE_TRIGGERS.includes(key)));
		const disabledOptions = Object.fromEntries(Object.entries(TRIGGER_OPTIONS).filter(([key]) => !BASE_TRIGGERS.includes(key)));
		return /* @__PURE__ */ react.createElement(PromotionSelect, {
			value: value in baseOptions ? value : DEFAULT_VALUES.trigger,
			onChange,
			baseOptions,
			disabledOptions,
			promotionLabel: (0, _wordpress_i18n.__)("PRO triggers", "elementor"),
			promotionContent: (0, _wordpress_i18n.__)("Upgrade to unlock more interactions triggers.", "elementor"),
			upgradeUrl: "https://go.elementor.com/go-pro-interactions-triggers-modal/",
			trackingData: TRACKING_DATA
		});
	}

//#endregion
//#region packages/packages/core/editor-interactions/src/hooks/on-duplicate.ts
	function initCleanInteractionIdsOnDuplicate() {
		(0, _elementor_editor_v1_adapters.registerDataHook)("after", "document/elements/duplicate", (_args, result) => {
			if (!result || typeof result === "boolean" && result === false) return;
			(Array.isArray(result) ? result : [result]).forEach((container) => {
				cleanInteractionIdsRecursive(container.id);
			});
			window.dispatchEvent(new CustomEvent("elementor/element/update_interactions"));
		});
	}
	function cleanInteractionIdsRecursive(elementId) {
		const container = (0, _elementor_editor_elements.getContainer)(elementId);
		if (!container) return;
		(0, _elementor_editor_elements.getAllDescendants)(container).forEach((element) => {
			cleanInteractionIds(element.id);
		});
	}
	function cleanInteractionIds(elementId) {
		const container = (0, _elementor_editor_elements.getContainer)(elementId);
		if (!container) return;
		const interactions = container.model.get("interactions");
		if (!interactions || !interactions.items) return;
		const updatedInteractions = structuredClone(interactions);
		updatedInteractions?.items?.forEach((interaction) => {
			if (interaction.$$type === "interaction-item" && interaction.value) interaction.value.interaction_id = createString(generateTempInteractionId());
		});
		container.model.set("interactions", updatedInteractions);
	}

//#endregion
//#region packages/packages/core/editor-interactions/src/mcp/tools/schema.ts
	var baseSchema = {
		trigger: _elementor_schema.z.enum(["load", "scrollIn"]).optional().describe("Event that triggers the animation"),
		effect: _elementor_schema.z.enum([
			"fade",
			"slide",
			"scale"
		]).optional().describe("Animation effect type"),
		effectType: _elementor_schema.z.enum(["in", "out"]).optional().describe("Whether the animation plays in or out"),
		direction: _elementor_schema.z.enum([
			"top",
			"bottom",
			"left",
			"right",
			"top-left",
			"top-right",
			"bottom-left",
			"bottom-right"
		]).optional().describe("Direction of the Animation. Can be one of the following or empty if not needed. At slide effect, this is required field."),
		duration: _elementor_schema.z.number().min(0).max(1e4).optional().describe("Animation duration in milliseconds"),
		delay: _elementor_schema.z.number().min(0).max(1e4).optional().describe("Animation delay in milliseconds"),
		easing: _elementor_schema.z.enum(["easeIn"]).optional().describe("Easing function for the animation. Use \"easeIn\" for free tier."),
		excludedBreakpoints: _elementor_schema.z.array(_elementor_schema.z.enum([
			"widescreen",
			"desktop",
			"laptop",
			"tablet_extra",
			"tablet",
			"mobile_extra",
			"mobile"
		])).optional().describe("Breakpoint IDs on which this interaction is disabled (e.g. [\"mobile\", \"tablet\"]). Fetch the \"elementor://breakpoints/list\" resource to get the valid IDs for the current site. Omit to enable on all breakpoints.")
	};
	var proSchema = {
		trigger: _elementor_schema.z.enum([
			"load",
			"scrollIn",
			"scrollOut",
			"scrollOn",
			"hover",
			"click"
		]).optional().describe("Event that triggers the animation"),
		effect: _elementor_schema.z.enum([
			"fade",
			"slide",
			"scale",
			"custom"
		]).optional().describe("Animation effect type"),
		easing: _elementor_schema.z.enum([
			"easeIn",
			"easeInOut",
			"easeOut",
			"backIn",
			"backInOut",
			"backOut",
			"linear"
		]).optional().describe("Easing function for the animation."),
		customEffects: _elementor_schema.z.object({ keyframes: _elementor_schema.z.array(_elementor_schema.z.object({
			stop: _elementor_schema.z.number().describe("The stop of the keyframe in percent, can be either 0 or 100"),
			value: _elementor_schema.z.object({
				opacity: _elementor_schema.z.number().min(0).max(1).describe("The opacity of the keyframe"),
				scale: _elementor_schema.z.object({
					x: _elementor_schema.z.number().min(0).max(1).describe("The x scale of the keyframe"),
					y: _elementor_schema.z.number().min(0).max(1).describe("The y scale of the keyframe")
				}).optional().describe("The scale of the keyframe"),
				rotate: _elementor_schema.z.object({
					x: _elementor_schema.z.number().min(0).max(360).describe("The x rotate of the keyframe"),
					y: _elementor_schema.z.number().min(0).max(360).describe("The y rotate of the keyframe"),
					z: _elementor_schema.z.number().min(0).max(360).describe("The z rotate of the keyframe")
				}).optional().describe("The rotate of the keyframe"),
				move: _elementor_schema.z.object({
					x: _elementor_schema.z.number().min(0).max(1).describe("The x move of the keyframe"),
					y: _elementor_schema.z.number().min(0).max(1).describe("The y move of the keyframe"),
					z: _elementor_schema.z.number().min(0).max(1).describe("The z move of the keyframe")
				}).optional().describe("The move of the keyframe"),
				skew: _elementor_schema.z.object({
					x: _elementor_schema.z.number().min(0).max(360).describe("The x skew of the keyframe"),
					y: _elementor_schema.z.number().min(0).max(360).describe("The y skew of the keyframe")
				}).optional().describe("The skew of the keyframe")
			})
		})).describe("The keyframes of the custom effect") }).optional().describe("The custom effect to use for the animation")
	};

//#endregion
//#region packages/packages/core/editor-interactions/src/mcp/resources/interactions-schema-resource.ts
	var INTERACTIONS_SCHEMA_URI = "elementor://interactions/schema";
	var initInteractionsSchemaResource = (reg) => {
		const { resource } = reg;
		const schema = (0, _elementor_utils.isProActive)() ? {
			...baseSchema,
			...proSchema
		} : baseSchema;
		resource("interactions-schema", INTERACTIONS_SCHEMA_URI, { description: "Schema describing all available options for element interactions." }, async () => {
			return { contents: [{
				uri: INTERACTIONS_SCHEMA_URI,
				mimeType: "application/json",
				text: JSON.stringify(schema)
			}] };
		});
	};

//#endregion
//#region packages/packages/core/editor-interactions/src/mcp/constants.ts
	var MAX_INTERACTIONS_PER_ELEMENT = 5;
	var EDITOR_INTERACTIONS_MCP_SHORT_DESCRIPTION = `Everything related to V4 ( Atomic ) interactions.
# Interactions
- Create/update/delete interactions
- Get list of interactions
- Get details of an interaction
`;
	var EDITOR_INTERACTIONS_MCP_DESCRIPTION = `MCP server for managing element interactions and animations. Use this to add, modify, or remove animations and motion effects triggered by user events such as page load or scroll-into-view.
		** IMPORTANT **
		Use the "interactions-schema" resource to get the schema of the interactions.
		Actions:
		- get: Read the current interactions on the element.
		- add: Add a new interaction (max ${5} per element).
		- update: Update an existing interaction by its interactionId.
		- delete: Remove a specific interaction by its interactionId.
		- clear: Remove all interactions from the element.

		For add/update, provide: trigger, effect, effectType, direction (required for slide effect), duration, delay, easing.
		Use excludedBreakpoints to disable the animation on specific responsive breakpoints (e.g. ["mobile", "tablet"]).
		Example Get Request:
		{
			"elementId": "123",
			"action": "get",
			"interactionId": "123",
			"animationData": {
				"trigger": "click",
				"effect": "fade",
			}
		}
		Example Add Request:
		{
			"elementId": "123",
			"action": "add",
			"animationData": {
				"effectType": "in",
				"direction": "top",
				"trigger": "click",
				"effect": "fade",
				"duration": 1000,
				"delay": 0,
				"easing": "easeIn",
				"excludedBreakpoints": ["mobile", "tablet"],
			}
		}
		Example Update Request:
		{
			"elementId": "123",
			"action": "update",
			"interactionId": "123",
			"animationData": {
				"trigger": "click",
				"effect": "fade",
			}
		}
		Example Delete Request:
		{
			"elementId": "123",
			"action": "delete",
			"interactionId": "123",
		}
		Example Clear Request:
		{
			"elementId": "123",
			"action": "clear",
		}`;

//#endregion
//#region packages/packages/core/editor-interactions/src/mcp/tools/manage-element-interaction-tool.ts
	var EMPTY_INTERACTIONS = {
		version: 1,
		items: []
	};
	var EFFECTS_WITHOUT_TYPE = ["custom"];
	var BREAKPOINTS_SCHEMA_URI = "elementor://breakpoints/list";
	var initManageElementInteractionTool = (reg) => {
		const { addTool } = reg;
		const extendedSchema = (0, _elementor_utils.isProActive)() ? {
			...baseSchema,
			...proSchema
		} : baseSchema;
		addTool({
			name: "manage-element-interaction",
			description: `Manage the element interaction.`,
			schema: {
				elementId: _elementor_schema.z.string().describe("The ID of the element to read or modify interactions on"),
				action: _elementor_schema.z.enum([
					"get",
					"add",
					"update",
					"delete",
					"clear"
				]).describe("Operation to perform. Use \"get\" first to inspect existing interactions."),
				interactionId: _elementor_schema.z.string().optional().describe("Interaction ID — required for update and delete. Obtain from a prior \"get\" call."),
				...extendedSchema
			},
			requiredResources: [{
				uri: INTERACTIONS_SCHEMA_URI,
				description: "Interactions schema with all available options"
			}, {
				uri: BREAKPOINTS_SCHEMA_URI,
				description: "Available breakpoint IDs for excludedBreakpoints"
			}],
			isDestructive: true,
			outputSchema: {
				success: _elementor_schema.z.boolean().describe("Whether the action was successful"),
				action: _elementor_schema.z.enum([
					"get",
					"add",
					"update",
					"delete",
					"clear"
				]).describe("Operation to perform. Use \"get\" first to inspect existing interactions."),
				elementId: _elementor_schema.z.string().optional().describe("The ID of the element to read or modify interactions on"),
				interactions: _elementor_schema.z.array(_elementor_schema.z.any()).optional().describe("The interactions on the element"),
				count: _elementor_schema.z.number().optional().describe("The number of interactions on the element")
			},
			handler: (input) => {
				const { elementId, action, interactionId, ...animationData } = input;
				const { effectType, ...restAnimationData } = animationData;
				const effect = restAnimationData.effect;
				const resolvedType = effectType ?? (effect && !EFFECTS_WITHOUT_TYPE.includes(effect) ? "in" : void 0);
				const currentInteractions = interactionsRepository.all().find((data) => data.elementId === elementId)?.interactions ?? EMPTY_INTERACTIONS;
				if (action === "get") {
					const summary = currentInteractions.items.map((item) => {
						const { value } = item;
						const animValue = value.animation.value;
						const timingValue = animValue.timing_config.value;
						const configValue = animValue.config.value;
						return {
							id: extractString(value.interaction_id),
							trigger: extractString(value.trigger),
							effect: extractString(animValue.effect),
							effectType: extractString(animValue.type),
							direction: extractString(animValue.direction),
							duration: extractSize(timingValue.duration),
							delay: extractSize(timingValue.delay),
							easing: extractString(configValue.easing),
							excludedBreakpoints: extractExcludedBreakpoints(value.breakpoints)
						};
					});
					return {
						success: true,
						elementId,
						action,
						interactions: summary,
						count: summary.length
					};
				}
				let updatedItems = [...currentInteractions.items];
				switch (action) {
					case "add": {
						if (updatedItems.length >= 5) throw new Error(`Cannot add more than ${5} interactions per element. Current count: ${updatedItems.length}. Delete an existing interaction first.`);
						const newItem = createInteractionItem({
							interactionId: generateTempInteractionId(),
							...restAnimationData,
							type: resolvedType
						});
						updatedItems = [...updatedItems, newItem];
						break;
					}
					case "update": {
						if (!interactionId) throw new Error("interactionId is required for the update action.");
						const itemIndex = updatedItems.findIndex((item) => extractString(item.value.interaction_id) === interactionId);
						if (itemIndex === -1) throw new Error(`Interaction with ID "${interactionId}" not found on element "${elementId}".`);
						const updatedItem = createInteractionItem({
							interactionId,
							...restAnimationData,
							type: resolvedType
						});
						updatedItems = [
							...updatedItems.slice(0, itemIndex),
							updatedItem,
							...updatedItems.slice(itemIndex + 1)
						];
						break;
					}
					case "delete": {
						if (!interactionId) throw new Error("interactionId is required for the delete action.");
						const beforeCount = updatedItems.length;
						updatedItems = updatedItems.filter((item) => extractString(item.value.interaction_id) !== interactionId);
						if (updatedItems.length === beforeCount) throw new Error(`Interaction with ID "${interactionId}" not found on element "${elementId}".`);
						break;
					}
					case "clear":
						updatedItems = [];
						break;
				}
				const updatedInteractions = {
					...currentInteractions,
					items: updatedItems
				};
				try {
					(0, _elementor_editor_elements.updateElementInteractions)({
						elementId,
						interactions: updatedInteractions
					});
				} catch (error) {
					throw new Error(`Failed to update interactions for element "${elementId}": ${error instanceof Error ? error.message : "Unknown error"}`);
				}
				return {
					success: true,
					action,
					elementId,
					count: updatedItems.length
				};
			}
		});
	};

//#endregion
//#region packages/packages/core/editor-interactions/src/mcp/index.ts
	var initMcpInteractions = (reg) => {
		const { setMCPDescription } = reg;
		setMCPDescription(`Everything related to V4 ( Atomic ) interactions.
# Interactions
- Create/update/delete interactions
- Get list of interactions
- Get details of an interaction
`);
		initInteractionsSchemaResource(reg);
		initManageElementInteractionTool(reg);
	};

//#endregion
//#region packages/packages/core/editor-interactions/src/init.ts
	function init() {
		try {
			interactionsRepository.register(documentElementsInteractionsProvider);
			initCleanInteractionIdsOnDuplicate();
			initPasteInteractionsCommand();
			registerInteractionsControl({
				type: "trigger",
				component: Trigger,
				options: ["load", "scrollIn"]
			});
			registerInteractionsControl({
				type: "easing",
				component: Easing,
				options: ["easeIn"]
			});
			registerInteractionsControl({
				type: "replay",
				component: Replay,
				options: ["no"]
			});
			registerInteractionsControl({
				type: "effectType",
				component: EffectType,
				options: ["in", "out"]
			});
			registerInteractionsControl({
				type: "direction",
				component: Direction,
				options: [
					"top",
					"bottom",
					"left",
					"right"
				]
			});
			registerInteractionsControl({
				type: "effect",
				component: Effect,
				options: [
					"fade",
					"slide",
					"scale"
				]
			});
			registerInteractionsControl({
				type: "repeat",
				component: Repeat
			});
			initMcpInteractions((0, _elementor_editor_mcp.getMCPByDomain)("interactions", {
				docs: EDITOR_INTERACTIONS_MCP_DESCRIPTION,
				instructions: EDITOR_INTERACTIONS_MCP_SHORT_DESCRIPTION
			}));
		} catch (error) {
			throw error;
		}
	}

//#endregion
//#region packages/packages/core/editor-interactions/src/index.ts
	var src_exports = /* @__PURE__ */ __exportAll({
		BASE_EASINGS: () => BASE_EASINGS,
		BASE_EFFECTS: () => BASE_EFFECTS,
		BASE_REPLAY: () => BASE_REPLAY,
		BASE_TRIGGERS: () => BASE_TRIGGERS,
		DEFAULT_VALUES: () => DEFAULT_VALUES,
		EASING_OPTIONS: () => EASING_OPTIONS,
		EFFECT_OPTIONS: () => EFFECT_OPTIONS,
		ELEMENTS_INTERACTIONS_PROVIDER_KEY_PREFIX: () => ELEMENTS_INTERACTIONS_PROVIDER_KEY_PREFIX,
		EmptyState: () => EmptyState,
		InteractionsTab: () => InteractionsTab,
		REPEAT_OPTIONS: () => REPEAT_OPTIONS,
		REPEAT_TOOLTIPS: () => REPEAT_TOOLTIPS,
		REPLAY_OPTIONS: () => REPLAY_OPTIONS,
		SCROLL_INTERACTION_EVENT: () => SCROLL_INTERACTION_EVENT,
		TRIGGER_OPTIONS: () => TRIGGER_OPTIONS,
		buildDisplayLabel: () => buildDisplayLabel,
		createAnimationPreset: () => createAnimationPreset,
		createBoolean: () => createBoolean,
		createConfig: () => createConfig,
		createDefaultInteractionItem: () => createDefaultInteractionItem,
		createDefaultInteractions: () => createDefaultInteractions,
		createExcludedBreakpoints: () => createExcludedBreakpoints,
		createInteractionBreakpoints: () => createInteractionBreakpoints,
		createInteractionItem: () => createInteractionItem,
		createInteractionsProvider: () => createInteractionsProvider,
		createNumber: () => createNumber,
		createString: () => createString,
		createTimingConfig: () => createTimingConfig,
		dispatchScrollInteraction: () => dispatchScrollInteraction,
		extractBoolean: () => extractBoolean,
		extractExcludedBreakpoints: () => extractExcludedBreakpoints,
		extractScrollOverlayParams: () => extractScrollOverlayParams,
		extractSize: () => extractSize,
		extractString: () => extractString,
		formatSizeValue: () => formatSizeValue,
		generateTempInteractionId: () => generateTempInteractionId,
		getInteractionsConfig: () => getInteractionsConfig,
		init: () => init,
		interactionsRepository: () => interactionsRepository,
		isTempId: () => isTempId,
		parseSizeValue: () => parseSizeValue,
		registerInteractionsControl: () => registerInteractionsControl,
		resolveDirection: () => resolveDirection,
		syncGridOverlay: () => syncGridOverlay,
		useElementInteractions: () => useElementInteractions
	});

//#endregion
//#region \0elementor-package-library-entry
	(window.elementorV2 = window.elementorV2 || {}).editorInteractions = src_exports;

//#endregion
})(React, elementorV2.icons, elementorV2.ui, wp.i18n, elementorV2.session, elementorV2.editorElements, elementorV2.editorV1Adapters, elementorV2.editorProps, elementorV2.editorControls, elementorV2.events, elementorV2.editorResponsive, elementorV2.editorMcp, elementorV2.editorUi, elementorV2.utils, elementorV2.schema);
window.elementorV2.editorInteractions?.init?.();
//# sourceMappingURL=editor-interactions.js.map
```
