import { i as require_react, n as require_compiler_runtime, r as require_jsx_runtime, t as theme, u as __toESM } from "./theme.mnyG70gE.chunk.js";
import { Gt as useDispatch, Kr as send, Kt as useSelector, Qr as v4, U as pushModal, Xt as payeeQueries, Zr as setUndoState, an as useAccounts, cr as useQuery, ii as useTranslation, oi as Trans, v as styles, wn as groupById, x as css } from "./extends.CfN_tLZB.chunk.js";
import { $o as baseInputStyle, $t as describeSchedule, Ai as Menu, Br as parseDate, Ci as useSelectedItems, Cn as mapField, Ei as useSyncedPref, Gn as accountBalance, H as usePayeesById, Jn as allAccountBalance, Li as SvgSearchAlternate, Ll as AnimatedLoading, Nn as calculateRunningBalancesBottomUp, Qt as computeSchedulePreviewTransactions, Ri as SvgRemove, Si as useSelectedDispatch, V as usePayees, Xu as q, Zo as Input, Zt as getNormalisedString, _i as useSheetValue, _s as Button, ct as useCategories, cu as View, di as TableHeader, gs as Text, hs as Link, ii as Field, ki as Popover, mn as ungroupTransactions, ms as SpaceBetween, mt as useContextMenu, n as Value, oi as Row, rs as SvgRightArrow2, si as SelectCell, ti as Cell, vn as friendlyOp, wn as translateRuleStage, xi as useSelected, xt as useSchedules, yi as SelectedProvider, yn as getAllocationMethods, yt as useCachedSchedules } from "./merge.C77XY6IK.chunk.js";
//#region src/components/common/InfiniteScrollWrapper.tsx
var import_compiler_runtime = require_compiler_runtime();
var import_react = /* @__PURE__ */ __toESM(require_react());
var import_jsx_runtime = require_jsx_runtime();
/**
* Wrapper around an infinitely loading list.
* Calls the `loadMore` callback when the bottom of the list is reached
* by scrolling to the bottom of the list.
*/
function InfiniteScrollWrapper(t0) {
	const $ = (0, import_compiler_runtime.c)(9);
	const { loadMore, children } = t0;
	const scrollRef = (0, import_react.useRef)(null);
	let t1;
	if ($[0] !== loadMore) {
		t1 = function onScroll(e) {
			if (loadMore && Math.abs(e.currentTarget.scrollHeight - e.currentTarget.clientHeight - e.currentTarget.scrollTop) < 1) loadMore();
		};
		$[0] = loadMore;
		$[1] = t1;
	} else t1 = $[1];
	const onScroll = t1;
	let t2;
	if ($[2] === Symbol.for("react.memo_cache_sentinel")) {
		t2 = {
			flex: 1,
			outline: "none",
			"& .animated .animated-row": { transition: ".25s transform" },
			marginBottom: -1
		};
		$[2] = t2;
	} else t2 = $[2];
	let t3;
	if ($[3] === Symbol.for("react.memo_cache_sentinel")) {
		t3 = {
			maxWidth: "100%",
			overflow: "auto"
		};
		$[3] = t3;
	} else t3 = $[3];
	let t4;
	if ($[4] !== children) {
		t4 = /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { children });
		$[4] = children;
		$[5] = t4;
	} else t4 = $[5];
	let t5;
	if ($[6] !== onScroll || $[7] !== t4) {
		t5 = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(View, {
			style: t2,
			tabIndex: 0,
			"data-testid": "table",
			children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(View, {
				innerRef: scrollRef,
				style: t3,
				onScroll,
				children: t4
			})
		});
		$[6] = onScroll;
		$[7] = t4;
		$[8] = t5;
	} else t5 = $[8];
	return t5;
}
//#endregion
//#region src/components/common/Search.tsx
function Search(t0) {
	const $ = (0, import_compiler_runtime.c)(35);
	const { ref, value, onChange, placeholder, isInModal: t1, width: t2, height, style } = t0;
	const isInModal = t1 === void 0 ? false : t1;
	const width = t2 === void 0 ? 250 : t2;
	const { t } = useTranslation();
	const [focused, setFocused] = (0, import_react.useState)(false);
	const clearButtonPadding = ((height ?? 24) - 8) / 2;
	const t3 = isInModal ? void 0 : "transparent";
	const t4 = isInModal ? void 0 : theme.formInputBackground;
	let t5;
	if ($[0] !== focused || $[1] !== isInModal) {
		t5 = focused && {
			boxShadow: "0 0 0 1px " + theme.formInputShadowSelected,
			...isInModal ? {} : { backgroundColor: theme.formInputBackgroundSelected }
		};
		$[0] = focused;
		$[1] = isInModal;
		$[2] = t5;
	} else t5 = $[2];
	let t6;
	if ($[3] !== height || $[4] !== style || $[5] !== t3 || $[6] !== t4 || $[7] !== t5 || $[8] !== width) {
		t6 = {
			...baseInputStyle,
			padding: 0,
			flexDirection: "row",
			alignItems: "center",
			width,
			height,
			flex: "",
			borderColor: t3,
			backgroundColor: t4,
			...style,
			...t5
		};
		$[3] = height;
		$[4] = style;
		$[5] = t3;
		$[6] = t4;
		$[7] = t5;
		$[8] = width;
		$[9] = t6;
	} else t6 = $[9];
	const t7 = value ? theme.menuItemTextSelected : "inherit";
	let t8;
	if ($[10] !== t7) {
		t8 = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SvgSearchAlternate, { style: {
			width: 13,
			height: 13,
			flexShrink: 0,
			color: t7,
			margin: 5,
			marginRight: 0
		} });
		$[10] = t7;
		$[11] = t8;
	} else t8 = $[11];
	let t9;
	if ($[12] !== onChange) {
		t9 = () => onChange("");
		$[12] = onChange;
		$[13] = t9;
	} else t9 = $[13];
	let t10;
	if ($[14] !== isInModal) {
		t10 = css({
			width: "100%",
			"::placeholder": {
				color: theme.formInputTextPlaceholder,
				transition: "color .25s"
			},
			"&[data-focused]": isInModal ? {} : { "::placeholder": { color: theme.formInputTextPlaceholderSelected } },
			flex: 1,
			"&, &[data-focused], &[data-hovered]": {
				border: 0,
				backgroundColor: "transparent",
				boxShadow: "none",
				color: "inherit"
			}
		});
		$[14] = isInModal;
		$[15] = t10;
	} else t10 = $[15];
	let t11;
	let t12;
	if ($[16] === Symbol.for("react.memo_cache_sentinel")) {
		t11 = () => {
			setFocused(true);
		};
		t12 = () => {
			setFocused(false);
		};
		$[16] = t11;
		$[17] = t12;
	} else {
		t11 = $[16];
		t12 = $[17];
	}
	let t13;
	if ($[18] !== onChange || $[19] !== placeholder || $[20] !== ref || $[21] !== t10 || $[22] !== t9 || $[23] !== value) {
		t13 = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Input, {
			ref,
			value,
			placeholder,
			onEscape: t9,
			onChangeValue: onChange,
			className: t10,
			onFocus: t11,
			onBlur: t12
		});
		$[18] = onChange;
		$[19] = placeholder;
		$[20] = ref;
		$[21] = t10;
		$[22] = t9;
		$[23] = value;
		$[24] = t13;
	} else t13 = $[24];
	let t14;
	if ($[25] !== clearButtonPadding || $[26] !== onChange || $[27] !== t || $[28] !== value) {
		t14 = value && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(View, {
			title: t("Clear search term"),
			children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
				variant: "bare",
				style: { padding: `${clearButtonPadding}px 8px ${clearButtonPadding}px ${clearButtonPadding}px` },
				onPress: () => onChange(""),
				children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SvgRemove, { style: {
					width: 8,
					height: 8
				} })
			})
		});
		$[25] = clearButtonPadding;
		$[26] = onChange;
		$[27] = t;
		$[28] = value;
		$[29] = t14;
	} else t14 = $[29];
	let t15;
	if ($[30] !== t13 || $[31] !== t14 || $[32] !== t6 || $[33] !== t8) {
		t15 = /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(View, {
			style: t6,
			children: [
				t8,
				t13,
				t14
			]
		});
		$[30] = t13;
		$[31] = t14;
		$[32] = t6;
		$[33] = t8;
		$[34] = t15;
	} else t15 = $[34];
	return t15;
}
//#endregion
//#region src/hooks/usePreviewTransactions.ts
function usePreviewTransactions({ filter, options } = {}) {
	const [previewTransactions, setPreviewTransactions] = (0, import_react.useState)([]);
	const { isLoading: isSchedulesLoading, error: scheduleQueryError, schedules, statuses } = useCachedSchedules();
	const [isLoading, setIsLoading] = (0, import_react.useState)(isSchedulesLoading);
	const [error, setError] = (0, import_react.useState)(void 0);
	const [upcomingLength] = useSyncedPref("upcomingScheduledTransactionLength");
	const scheduleTransactions = (0, import_react.useMemo)(() => {
		if (isSchedulesLoading) return [];
		return computeSchedulePreviewTransactions(schedules, statuses, upcomingLength, filter);
	}, [
		filter,
		isSchedulesLoading,
		schedules,
		statuses,
		upcomingLength
	]);
	(0, import_react.useEffect)(() => {
		let isUnmounted = false;
		setError(void 0);
		if (scheduleTransactions.length === 0) {
			setIsLoading(false);
			setPreviewTransactions([]);
			return;
		}
		setIsLoading(true);
		Promise.all(scheduleTransactions.map((transaction) => send("rules-run", { transaction }))).then((newTrans) => {
			if (!isUnmounted) {
				const withDefaults = newTrans.map((t) => ({
					...t,
					category: t.schedule != null ? statuses.get(t.schedule) : void 0,
					schedule: t.schedule,
					subtransactions: t.subtransactions?.map((st) => ({
						...st,
						id: "preview/" + st.id,
						schedule: t.schedule
					}))
				}));
				withDefaults.sort((a, b) => parseDate(b.date).getTime() - parseDate(a.date).getTime() || a.amount - b.amount);
				setPreviewTransactions(ungroupTransactions(withDefaults));
				setIsLoading(false);
			}
		}).catch((error) => {
			if (!isUnmounted) {
				setError(error);
				setIsLoading(false);
			}
		});
		return () => {
			isUnmounted = true;
		};
	}, [
		scheduleTransactions,
		schedules,
		statuses,
		upcomingLength
	]);
	const runningBalances = (0, import_react.useMemo)(() => {
		if (!options?.calculateRunningBalances) return /* @__PURE__ */ new Map();
		return calculateRunningBalancesBottomUp(previewTransactions, "all", options?.startingBalance);
	}, [
		previewTransactions,
		options?.calculateRunningBalances,
		options?.startingBalance
	]);
	const returnError = error || scheduleQueryError;
	return {
		previewTransactions,
		runningBalances,
		isLoading: isLoading || isSchedulesLoading,
		...returnError && { error: returnError }
	};
}
//#endregion
//#region src/hooks/useAccountPreviewTransactions.ts
/**
* Preview transactions for a given account or all accounts if no `accountId` is provided.
* This will invert the payees, accounts, and amounts accordingly depending on which account
* the preview transactions are being viewed from.
*/
function useAccountPreviewTransactions({ accountId }) {
	const { data: accounts = [] } = useAccounts();
	const accountsById = (0, import_react.useMemo)(() => groupById(accounts), [accounts]);
	const { data: payees = [] } = usePayees();
	const payeesById = (0, import_react.useMemo)(() => groupById(payees), [payees]);
	const getPayeeByTransferAccount = (0, import_react.useCallback)((transferAccountId) => payees.find((p) => p.transfer_acct === transferAccountId) || null, [payees]);
	const getTransferAccountByPayee = (0, import_react.useCallback)((payeeId) => {
		if (!payeeId) return null;
		const transferAccountId = payeesById[payeeId]?.transfer_acct;
		if (!transferAccountId) return null;
		return accountsById[transferAccountId];
	}, [accountsById, payeesById]);
	const accountSchedulesFilter = (0, import_react.useCallback)((schedule) => !accountId || schedule._account === accountId || getTransferAccountByPayee(schedule._payee)?.id === accountId, [accountId, getTransferAccountByPayee]);
	const accountBalanceValue = useSheetValue(accountId ? accountBalance(accountId) : allAccountBalance());
	const [showBalances] = useSyncedPref(`show-balances-${accountId}`);
	const { previewTransactions: allPreviewTransactions, runningBalances: allRunningBalances, isLoading, error } = usePreviewTransactions({
		filter: accountSchedulesFilter,
		options: {
			calculateRunningBalances: showBalances === "true",
			startingBalance: accountBalanceValue ?? 0
		}
	});
	return (0, import_react.useMemo)(() => {
		if (!accountId) return {
			previewTransactions: allPreviewTransactions,
			runningBalances: allRunningBalances,
			isLoading,
			error
		};
		const { transactions: previewTransactions, runningBalances: previewRunningBalances } = inverseBasedOnAccount({
			accountId,
			transactions: allPreviewTransactions,
			runningBalances: allRunningBalances,
			startingBalance: accountBalanceValue ?? 0,
			getPayeeByTransferAccount,
			getTransferAccountByPayee
		});
		const transactionIds = new Set(previewTransactions.map((t) => t.id));
		return {
			isLoading,
			previewTransactions,
			runningBalances: new Map([...previewRunningBalances.entries()].filter(([id]) => transactionIds.has(id))),
			error
		};
	}, [
		accountId,
		allPreviewTransactions,
		accountBalanceValue,
		allRunningBalances,
		getPayeeByTransferAccount,
		getTransferAccountByPayee,
		isLoading,
		error
	]);
}
function inverseBasedOnAccount({ accountId, transactions, runningBalances, startingBalance, getPayeeByTransferAccount, getTransferAccountByPayee }) {
	const mappedTransactions = transactions.map((transaction) => {
		const inverse = transaction.account !== accountId;
		const subtransactions = transaction.subtransactions?.map((st) => ({
			...st,
			amount: inverse ? -st.amount : st.amount,
			payee: (inverse ? getPayeeByTransferAccount(st.account)?.id : st.payee) || "",
			account: inverse ? getTransferAccountByPayee(st.payee)?.id || "" : st.account
		}));
		return {
			inversed: inverse,
			...transaction,
			amount: inverse ? -transaction.amount : transaction.amount,
			payee: (inverse ? getPayeeByTransferAccount(transaction.account)?.id : transaction.payee) || "",
			account: inverse ? getTransferAccountByPayee(transaction.payee)?.id || "" : transaction.account,
			...subtransactions && { subtransactions }
		};
	});
	return {
		transactions: mappedTransactions,
		runningBalances: mappedTransactions.some((t) => t.inversed) ? calculateRunningBalancesBottomUp(mappedTransactions, "all", startingBalance ?? 0) : runningBalances
	};
}
//#endregion
//#region src/hooks/useFailedAccounts.ts
function useFailedAccounts() {
	const failedAccounts = useSelector((state) => state.account.failedAccounts);
	return (0, import_react.useMemo)(() => new Map(Object.entries(failedAccounts)), [failedAccounts]);
}
//#endregion
//#region src/components/rules/RulesHeader.tsx
function RulesHeader() {
	const $ = (0, import_compiler_runtime.c)(18);
	const { t } = useTranslation();
	const selectedItems = useSelectedItems();
	const dispatchSelected = useSelectedDispatch();
	let t0;
	if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
		t0 = {};
		$[0] = t0;
	} else t0 = $[0];
	const t1 = selectedItems.size > 0;
	let t2;
	if ($[1] !== dispatchSelected) {
		t2 = (e) => dispatchSelected({
			type: "select-all",
			isRangeSelect: e.shiftKey
		});
		$[1] = dispatchSelected;
		$[2] = t2;
	} else t2 = $[2];
	let t3;
	if ($[3] !== t1 || $[4] !== t2) {
		t3 = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SelectCell, {
			exposed: true,
			focused: false,
			selected: t1,
			onSelect: t2
		});
		$[3] = t1;
		$[4] = t2;
		$[5] = t3;
	} else t3 = $[5];
	let t4;
	if ($[6] !== t) {
		t4 = t("Stage");
		$[6] = t;
		$[7] = t4;
	} else t4 = $[7];
	let t5;
	if ($[8] !== t4) {
		t5 = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Cell, {
			value: t4,
			width: 50
		});
		$[8] = t4;
		$[9] = t5;
	} else t5 = $[9];
	let t6;
	if ($[10] !== t) {
		t6 = t("Rule");
		$[10] = t;
		$[11] = t6;
	} else t6 = $[11];
	let t7;
	if ($[12] !== t6) {
		t7 = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Cell, {
			value: t6,
			width: "flex"
		});
		$[12] = t6;
		$[13] = t7;
	} else t7 = $[13];
	let t8;
	if ($[14] !== t3 || $[15] !== t5 || $[16] !== t7) {
		t8 = /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(TableHeader, {
			style: t0,
			children: [
				t3,
				t5,
				t7
			]
		});
		$[14] = t3;
		$[15] = t5;
		$[16] = t7;
		$[17] = t8;
	} else t8 = $[17];
	return t8;
}
//#endregion
//#region src/util/ruleUtils.ts
function groupActionsBySplitIndex(actions) {
	return actions.reduce((acc, action) => {
		const splitIndex = "options" in action ? action.options?.splitIndex ?? 0 : 0;
		acc[splitIndex] = acc[splitIndex] ?? {
			id: v4(),
			actions: []
		};
		acc[splitIndex].actions.push(action);
		return acc;
	}, []);
}
//#endregion
//#region src/components/rules/ScheduleValue.tsx
function ScheduleValue(t0) {
	const $ = (0, import_compiler_runtime.c)(18);
	const { value } = t0;
	const { t } = useTranslation();
	const { data: t1 } = usePayeesById();
	let t2;
	if ($[0] !== t1) {
		t2 = t1 === void 0 ? {} : t1;
		$[0] = t1;
		$[1] = t2;
	} else t2 = $[1];
	const byId = t2;
	let t3;
	if ($[2] === Symbol.for("react.memo_cache_sentinel")) {
		t3 = q("schedules").select("*");
		$[2] = t3;
	} else t3 = $[2];
	const schedulesQuery = t3;
	let t4;
	if ($[3] === Symbol.for("react.memo_cache_sentinel")) {
		t4 = { query: schedulesQuery };
		$[3] = t4;
	} else t4 = $[3];
	const { schedules: t5, isLoading } = useSchedules(t4);
	let t6;
	if ($[4] !== t5) {
		t6 = t5 === void 0 ? [] : t5;
		$[4] = t5;
		$[5] = t6;
	} else t6 = $[5];
	const schedules = t6;
	if (isLoading) {
		let t7;
		if ($[6] !== t) {
			t7 = t("Loading...");
			$[6] = t;
			$[7] = t7;
		} else t7 = $[7];
		let t8;
		let t9;
		if ($[8] === Symbol.for("react.memo_cache_sentinel")) {
			t8 = { display: "inline-flex" };
			t9 = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(AnimatedLoading, {
				width: 10,
				height: 10
			});
			$[8] = t8;
			$[9] = t9;
		} else {
			t8 = $[8];
			t9 = $[9];
		}
		let t10;
		if ($[10] !== t7) {
			t10 = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(View, {
				"aria-label": t7,
				style: t8,
				children: t9
			});
			$[10] = t7;
			$[11] = t10;
		} else t10 = $[11];
		return t10;
	}
	let t7;
	if ($[12] !== byId) {
		t7 = (schedule) => describeSchedule(schedule, byId[schedule._payee]);
		$[12] = byId;
		$[13] = t7;
	} else t7 = $[13];
	let t8;
	if ($[14] !== schedules || $[15] !== t7 || $[16] !== value) {
		t8 = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Value, {
			value,
			field: "rule",
			data: schedules,
			describe: t7
		});
		$[14] = schedules;
		$[15] = t7;
		$[16] = value;
		$[17] = t8;
	} else t8 = $[17];
	return t8;
}
//#endregion
//#region src/components/rules/ActionExpression.tsx
var valueStyle$1 = { color: theme.pillTextHighlighted };
function ActionExpression(t0) {
	const $ = (0, import_compiler_runtime.c)(10);
	let props;
	let style;
	if ($[0] !== t0) {
		({style, ...props} = t0);
		$[0] = t0;
		$[1] = props;
		$[2] = style;
	} else {
		props = $[1];
		style = $[2];
	}
	let t1;
	if ($[3] !== style) {
		t1 = {
			display: "block",
			maxWidth: "100%",
			color: theme.pillText,
			backgroundColor: theme.pillBackgroundLight,
			borderRadius: 4,
			padding: "3px 5px",
			whiteSpace: "nowrap",
			overflow: "hidden",
			textOverflow: "ellipsis",
			...style
		};
		$[3] = style;
		$[4] = t1;
	} else t1 = $[4];
	let t2;
	if ($[5] !== props) {
		t2 = props.op === "set" ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SetActionExpression, { ...props }) : props.op === "set-split-amount" ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SetSplitAmountActionExpression, { ...props }) : props.op === "link-schedule" ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(LinkScheduleActionExpression, { ...props }) : props.op === "prepend-notes" ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(PrependNoteActionExpression, { ...props }) : props.op === "append-notes" ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(AppendNoteActionExpression, { ...props }) : props.op === "delete-transaction" ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(DeleteTransactionActionExpression, { ...props }) : null;
		$[5] = props;
		$[6] = t2;
	} else t2 = $[6];
	let t3;
	if ($[7] !== t1 || $[8] !== t2) {
		t3 = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(View, {
			style: t1,
			children: t2
		});
		$[7] = t1;
		$[8] = t2;
		$[9] = t3;
	} else t3 = $[9];
	return t3;
}
function SetActionExpression(t0) {
	const $ = (0, import_compiler_runtime.c)(23);
	const { op, field, value, options } = t0;
	const { t } = useTranslation();
	let t1;
	if ($[0] !== op) {
		t1 = friendlyOp(op);
		$[0] = op;
		$[1] = t1;
	} else t1 = $[1];
	let t2;
	if ($[2] !== t1) {
		t2 = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { children: t1 });
		$[2] = t1;
		$[3] = t2;
	} else t2 = $[3];
	let t3;
	if ($[4] !== field || $[5] !== options) {
		t3 = mapField(field, options);
		$[4] = field;
		$[5] = options;
		$[6] = t3;
	} else t3 = $[6];
	let t4;
	if ($[7] !== t3) {
		t4 = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
			style: valueStyle$1,
			children: t3
		});
		$[7] = t3;
		$[8] = t4;
	} else t4 = $[8];
	let t5;
	if ($[9] !== t) {
		t5 = t("to ");
		$[9] = t;
		$[10] = t5;
	} else t5 = $[10];
	let t6;
	if ($[11] !== t5) {
		t6 = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { children: t5 });
		$[11] = t5;
		$[12] = t6;
	} else t6 = $[12];
	let t7;
	if ($[13] !== field || $[14] !== options || $[15] !== t || $[16] !== value) {
		t7 = options?.formula ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { children: t("formula ") }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
			style: valueStyle$1,
			children: options.formula
		})] }) : options?.template ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { children: t("template ") }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
			style: valueStyle$1,
			children: options.template
		})] }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Value, {
			style: valueStyle$1,
			value,
			field
		});
		$[13] = field;
		$[14] = options;
		$[15] = t;
		$[16] = value;
		$[17] = t7;
	} else t7 = $[17];
	let t8;
	if ($[18] !== t2 || $[19] !== t4 || $[20] !== t6 || $[21] !== t7) {
		t8 = /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
			t2,
			" ",
			t4,
			" ",
			t6,
			t7
		] });
		$[18] = t2;
		$[19] = t4;
		$[20] = t6;
		$[21] = t7;
		$[22] = t8;
	} else t8 = $[22];
	return t8;
}
function SetSplitAmountActionExpression(t0) {
	const $ = (0, import_compiler_runtime.c)(17);
	const { op, value, options } = t0;
	const { t } = useTranslation();
	const method = options?.method;
	if (!method) return null;
	let t1;
	if ($[0] !== op) {
		t1 = friendlyOp(op);
		$[0] = op;
		$[1] = t1;
	} else t1 = $[1];
	let t2;
	if ($[2] !== t1) {
		t2 = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { children: t1 });
		$[2] = t1;
		$[3] = t2;
	} else t2 = $[3];
	let t3;
	if ($[4] === Symbol.for("react.memo_cache_sentinel")) {
		t3 = getAllocationMethods();
		$[4] = t3;
	} else t3 = $[4];
	const t4 = t3[method];
	let t5;
	if ($[5] !== t4) {
		t5 = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
			style: valueStyle$1,
			children: t4
		});
		$[5] = t4;
		$[6] = t5;
	} else t5 = $[6];
	const t6 = method !== "remainder" && ": ";
	let t7;
	if ($[7] !== method || $[8] !== options || $[9] !== t || $[10] !== value) {
		t7 = options?.method === "formula" ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { children: t("formula ") }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
			style: valueStyle$1,
			children: options.formula
		})] }) : method === "fixed-amount" ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Value, {
			style: valueStyle$1,
			value,
			field: "amount"
		}) : method === "fixed-percent" ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, {
			style: valueStyle$1,
			children: [value, "%"]
		}) : null;
		$[7] = method;
		$[8] = options;
		$[9] = t;
		$[10] = value;
		$[11] = t7;
	} else t7 = $[11];
	let t8;
	if ($[12] !== t2 || $[13] !== t5 || $[14] !== t6 || $[15] !== t7) {
		t8 = /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
			t2,
			" ",
			t5,
			t6,
			t7
		] });
		$[12] = t2;
		$[13] = t5;
		$[14] = t6;
		$[15] = t7;
		$[16] = t8;
	} else t8 = $[16];
	return t8;
}
function LinkScheduleActionExpression(t0) {
	const $ = (0, import_compiler_runtime.c)(9);
	const { op, value } = t0;
	let t1;
	if ($[0] !== op) {
		t1 = friendlyOp(op);
		$[0] = op;
		$[1] = t1;
	} else t1 = $[1];
	let t2;
	if ($[2] !== t1) {
		t2 = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { children: t1 });
		$[2] = t1;
		$[3] = t2;
	} else t2 = $[3];
	let t3;
	if ($[4] !== value) {
		t3 = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ScheduleValue, { value });
		$[4] = value;
		$[5] = t3;
	} else t3 = $[5];
	let t4;
	if ($[6] !== t2 || $[7] !== t3) {
		t4 = /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
			t2,
			" ",
			t3
		] });
		$[6] = t2;
		$[7] = t3;
		$[8] = t4;
	} else t4 = $[8];
	return t4;
}
function PrependNoteActionExpression(t0) {
	const $ = (0, import_compiler_runtime.c)(9);
	const { op, value } = t0;
	let t1;
	if ($[0] !== op) {
		t1 = friendlyOp(op);
		$[0] = op;
		$[1] = t1;
	} else t1 = $[1];
	let t2;
	if ($[2] !== t1) {
		t2 = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { children: t1 });
		$[2] = t1;
		$[3] = t2;
	} else t2 = $[3];
	let t3;
	if ($[4] !== value) {
		t3 = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Value, {
			style: valueStyle$1,
			value,
			field: "notes"
		});
		$[4] = value;
		$[5] = t3;
	} else t3 = $[5];
	let t4;
	if ($[6] !== t2 || $[7] !== t3) {
		t4 = /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
			t2,
			" ",
			t3
		] });
		$[6] = t2;
		$[7] = t3;
		$[8] = t4;
	} else t4 = $[8];
	return t4;
}
function AppendNoteActionExpression(t0) {
	const $ = (0, import_compiler_runtime.c)(9);
	const { op, value } = t0;
	let t1;
	if ($[0] !== op) {
		t1 = friendlyOp(op);
		$[0] = op;
		$[1] = t1;
	} else t1 = $[1];
	let t2;
	if ($[2] !== t1) {
		t2 = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { children: t1 });
		$[2] = t1;
		$[3] = t2;
	} else t2 = $[3];
	let t3;
	if ($[4] !== value) {
		t3 = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Value, {
			style: valueStyle$1,
			value,
			field: "notes"
		});
		$[4] = value;
		$[5] = t3;
	} else t3 = $[5];
	let t4;
	if ($[6] !== t2 || $[7] !== t3) {
		t4 = /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
			t2,
			" ",
			t3
		] });
		$[6] = t2;
		$[7] = t3;
		$[8] = t4;
	} else t4 = $[8];
	return t4;
}
function DeleteTransactionActionExpression(t0) {
	const $ = (0, import_compiler_runtime.c)(4);
	const { op } = t0;
	let t1;
	if ($[0] !== op) {
		t1 = friendlyOp(op);
		$[0] = op;
		$[1] = t1;
	} else t1 = $[1];
	let t2;
	if ($[2] !== t1) {
		t2 = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { children: t1 });
		$[2] = t1;
		$[3] = t2;
	} else t2 = $[3];
	return t2;
}
//#endregion
//#region src/components/rules/ConditionExpression.tsx
var valueStyle = { color: theme.pillTextHighlighted };
function ConditionExpression(t0) {
	const $ = (0, import_compiler_runtime.c)(24);
	const { field, op, value, options, prefix, style, inline } = t0;
	let t1;
	if ($[0] !== style) {
		t1 = {
			display: "block",
			maxWidth: "100%",
			color: theme.pillText,
			backgroundColor: theme.pillBackgroundLight,
			borderRadius: 4,
			padding: "3px 5px",
			whiteSpace: "nowrap",
			overflow: "hidden",
			textOverflow: "ellipsis",
			...style
		};
		$[0] = style;
		$[1] = t1;
	} else t1 = $[1];
	let t2;
	if ($[2] !== prefix) {
		t2 = prefix && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, { children: [prefix, " "] });
		$[2] = prefix;
		$[3] = t2;
	} else t2 = $[3];
	let t3;
	if ($[4] !== field || $[5] !== options) {
		t3 = mapField(field, options);
		$[4] = field;
		$[5] = options;
		$[6] = t3;
	} else t3 = $[6];
	let t4;
	if ($[7] !== t3) {
		t4 = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
			style: valueStyle,
			children: t3
		});
		$[7] = t3;
		$[8] = t4;
	} else t4 = $[8];
	let t5;
	if ($[9] !== op) {
		t5 = friendlyOp(op);
		$[9] = op;
		$[10] = t5;
	} else t5 = $[10];
	let t6;
	if ($[11] !== t5) {
		t6 = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { children: t5 });
		$[11] = t5;
		$[12] = t6;
	} else t6 = $[12];
	let t7;
	if ($[13] !== field || $[14] !== inline || $[15] !== op || $[16] !== value) {
		t7 = !["onbudget", "offbudget"].includes(op?.toLocaleLowerCase()) && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Value, {
			style: valueStyle,
			value,
			field,
			inline
		});
		$[13] = field;
		$[14] = inline;
		$[15] = op;
		$[16] = value;
		$[17] = t7;
	} else t7 = $[17];
	let t8;
	if ($[18] !== t1 || $[19] !== t2 || $[20] !== t4 || $[21] !== t6 || $[22] !== t7) {
		t8 = /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(View, {
			style: t1,
			children: [
				t2,
				t4,
				" ",
				t6,
				" ",
				t7
			]
		});
		$[18] = t1;
		$[19] = t2;
		$[20] = t4;
		$[21] = t6;
		$[22] = t7;
		$[23] = t8;
	} else t8 = $[23];
	return t8;
}
//#endregion
//#region src/components/rules/RuleRow.tsx
var RuleRow = (0, import_react.memo)((t0) => {
	const $ = (0, import_compiler_runtime.c)(93);
	const { rule, hovered, selected, onHover, onEditRule, onDeleteRule } = t0;
	const dispatchSelected = useSelectedDispatch();
	const borderColor = selected ? theme.tableBorderSelected : "none";
	const backgroundFocus = hovered;
	const actionSplits = groupActionsBySplitIndex(rule.actions);
	const hasSplits = actionSplits.length > 1;
	let t1;
	if ($[0] !== rule.actions) {
		t1 = rule.actions.some(_temp$1);
		$[0] = rule.actions;
		$[1] = t1;
	} else t1 = $[1];
	const hasSchedule = t1;
	const { t } = useTranslation();
	const triggerRef = (0, import_react.useRef)(null);
	const { setMenuOpen, menuOpen, handleContextMenu, position } = useContextMenu();
	const T0 = Row;
	const t2 = "auto";
	const t3 = selected ? 101 : "auto";
	const t4 = selected ? theme.tableRowBackgroundHighlight : backgroundFocus ? theme.tableRowBackgroundHover : theme.tableBackground;
	let t5;
	if ($[2] !== borderColor || $[3] !== t3 || $[4] !== t4) {
		t5 = {
			fontSize: 13,
			zIndex: t3,
			borderColor,
			backgroundColor: t4
		};
		$[2] = borderColor;
		$[3] = t3;
		$[4] = t4;
		$[5] = t5;
	} else t5 = $[5];
	const t6 = true;
	let t7;
	if ($[6] !== onHover || $[7] !== rule.id) {
		t7 = () => onHover && onHover(rule.id);
		$[6] = onHover;
		$[7] = rule.id;
		$[8] = t7;
	} else t7 = $[8];
	let t8;
	if ($[9] !== onHover) {
		t8 = () => onHover && onHover(null);
		$[9] = onHover;
		$[10] = t8;
	} else t8 = $[10];
	let t9;
	if ($[11] !== setMenuOpen) {
		t9 = () => setMenuOpen(false);
		$[11] = setMenuOpen;
		$[12] = t9;
	} else t9 = $[12];
	let t10;
	if ($[13] === Symbol.for("react.memo_cache_sentinel")) {
		t10 = {
			width: 200,
			margin: 1
		};
		$[13] = t10;
	} else t10 = $[13];
	let t11;
	if ($[14] !== onEditRule || $[15] !== t) {
		t11 = onEditRule && {
			name: "edit",
			text: t("Edit")
		};
		$[14] = onEditRule;
		$[15] = t;
		$[16] = t11;
	} else t11 = $[16];
	let t12;
	if ($[17] !== hasSchedule || $[18] !== onDeleteRule || $[19] !== t) {
		t12 = onDeleteRule && !hasSchedule && {
			name: "delete",
			text: t("Delete")
		};
		$[17] = hasSchedule;
		$[18] = onDeleteRule;
		$[19] = t;
		$[20] = t12;
	} else t12 = $[20];
	let t13;
	if ($[21] !== t11 || $[22] !== t12) {
		t13 = [t11, t12];
		$[21] = t11;
		$[22] = t12;
		$[23] = t13;
	} else t13 = $[23];
	let t14;
	if ($[24] !== onDeleteRule || $[25] !== onEditRule || $[26] !== rule || $[27] !== setMenuOpen) {
		t14 = (name) => {
			bb46: switch (name) {
				case "delete":
					onDeleteRule(rule);
					break bb46;
				case "edit":
					onEditRule(rule);
					break bb46;
				default: throw new Error(`Unrecognized menu option: ${String(name)}`);
			}
			setMenuOpen(false);
		};
		$[24] = onDeleteRule;
		$[25] = onEditRule;
		$[26] = rule;
		$[27] = setMenuOpen;
		$[28] = t14;
	} else t14 = $[28];
	let t15;
	if ($[29] !== t13 || $[30] !== t14) {
		t15 = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Menu, {
			items: t13,
			onMenuSelect: t14
		});
		$[29] = t13;
		$[30] = t14;
		$[31] = t15;
	} else t15 = $[31];
	let t16;
	if ($[32] !== menuOpen || $[33] !== position || $[34] !== t15 || $[35] !== t9) {
		t16 = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Popover, {
			triggerRef,
			placement: "bottom start",
			isOpen: menuOpen,
			onOpenChange: t9,
			...position,
			style: t10,
			isNonModal: true,
			children: t15
		});
		$[32] = menuOpen;
		$[33] = position;
		$[34] = t15;
		$[35] = t9;
		$[36] = t16;
	} else t16 = $[36];
	const t17 = hovered || selected;
	let t18;
	if ($[37] !== dispatchSelected || $[38] !== rule.id) {
		t18 = (e) => {
			dispatchSelected({
				type: "select",
				id: rule.id,
				isRangeSelect: e.shiftKey
			});
		};
		$[37] = dispatchSelected;
		$[38] = rule.id;
		$[39] = t18;
	} else t18 = $[39];
	let t19;
	if ($[40] !== selected || $[41] !== t17 || $[42] !== t18) {
		t19 = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SelectCell, {
			exposed: t17,
			focused: true,
			onSelect: t18,
			selected
		});
		$[40] = selected;
		$[41] = t17;
		$[42] = t18;
		$[43] = t19;
	} else t19 = $[43];
	let t20;
	if ($[44] === Symbol.for("react.memo_cache_sentinel")) {
		t20 = { color: theme.tableText };
		$[44] = t20;
	} else t20 = $[44];
	let t21;
	if ($[45] !== rule.stage) {
		t21 = rule.stage && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(View, {
			style: {
				alignSelf: "flex-start",
				margin: 5,
				backgroundColor: theme.pillBackgroundSelected,
				color: theme.pillTextSelected,
				borderRadius: 4,
				padding: "3px 5px"
			},
			children: translateRuleStage(rule.stage)
		});
		$[45] = rule.stage;
		$[46] = t21;
	} else t21 = $[46];
	let t22;
	if ($[47] !== t21) {
		t22 = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Cell, {
			name: "stage",
			width: 50,
			plain: true,
			style: t20,
			children: t21
		});
		$[47] = t21;
		$[48] = t22;
	} else t22 = $[48];
	const T1 = Field;
	const t23 = "flex";
	let t24;
	if ($[49] === Symbol.for("react.memo_cache_sentinel")) {
		t24 = { padding: "15px 0" };
		$[49] = t24;
	} else t24 = $[49];
	const t25 = false;
	const T2 = SpaceBetween;
	let t26;
	if ($[50] === Symbol.for("react.memo_cache_sentinel")) {
		t26 = { alignItems: "center" };
		$[50] = t26;
	} else t26 = $[50];
	let t27;
	if ($[51] === Symbol.for("react.memo_cache_sentinel")) {
		t27 = {
			flex: 1,
			alignItems: "flex-start"
		};
		$[51] = t27;
	} else t27 = $[51];
	let t28;
	if ($[52] !== rule.conditions || $[53] !== rule.conditionsOp) {
		let t29;
		if ($[55] !== rule.conditionsOp) {
			t29 = (cond, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ConditionExpression, {
				field: cond.field,
				op: cond.op,
				inline: true,
				value: cond.value,
				options: cond.options,
				prefix: i > 0 ? friendlyOp(rule.conditionsOp) : null,
				style: i !== 0 && { marginTop: 3 }
			}, i);
			$[55] = rule.conditionsOp;
			$[56] = t29;
		} else t29 = $[56];
		t28 = rule.conditions.map(t29);
		$[52] = rule.conditions;
		$[53] = rule.conditionsOp;
		$[54] = t28;
	} else t28 = $[54];
	let t29;
	if ($[57] !== t28) {
		t29 = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(View, {
			style: t27,
			"data-testid": "conditions",
			children: t28
		});
		$[57] = t28;
		$[58] = t29;
	} else t29 = $[58];
	let t30;
	if ($[59] === Symbol.for("react.memo_cache_sentinel")) {
		t30 = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SvgRightArrow2, { style: {
			width: 12,
			height: 12,
			color: theme.tableText
		} }) });
		$[59] = t30;
	} else t30 = $[59];
	const T3 = View;
	let t31;
	if ($[60] === Symbol.for("react.memo_cache_sentinel")) {
		t31 = {
			flex: 1,
			alignItems: "flex-start"
		};
		$[60] = t31;
	} else t31 = $[60];
	const t32 = "actions";
	const t33 = hasSplits ? actionSplits.map((split, i_0) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(View, {
		style: {
			width: "100%",
			display: "flex",
			flexDirection: "column",
			alignItems: "flex-start",
			marginTop: i_0 > 0 ? 3 : 0,
			padding: "5px",
			borderColor: theme.tableBorder,
			borderWidth: "1px",
			borderRadius: "5px"
		},
		children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
			style: {
				...styles.smallText,
				color: theme.pageTextLight,
				marginBottom: 6
			},
			children: i_0 ? t("Split {{num}}", { num: i_0 }) : t("Apply to all")
		}), split.actions.map(_temp2$1)]
	}, split.id)) : rule.actions.map(_temp3$1);
	let t34;
	if ($[61] !== T3 || $[62] !== t31 || $[63] !== t33) {
		t34 = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(T3, {
			style: t31,
			"data-testid": t32,
			children: t33
		});
		$[61] = T3;
		$[62] = t31;
		$[63] = t33;
		$[64] = t34;
	} else t34 = $[64];
	let t35;
	if ($[65] !== T2 || $[66] !== t26 || $[67] !== t29 || $[68] !== t30 || $[69] !== t34) {
		t35 = /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(T2, {
			style: t26,
			children: [
				t29,
				t30,
				t34
			]
		});
		$[65] = T2;
		$[66] = t26;
		$[67] = t29;
		$[68] = t30;
		$[69] = t34;
		$[70] = t35;
	} else t35 = $[70];
	let t36;
	if ($[71] !== T1 || $[72] !== t24 || $[73] !== t35) {
		t36 = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(T1, {
			width: t23,
			style: t24,
			truncate: t25,
			children: t35
		});
		$[71] = T1;
		$[72] = t24;
		$[73] = t35;
		$[74] = t36;
	} else t36 = $[74];
	let t37;
	if ($[75] === Symbol.for("react.memo_cache_sentinel")) {
		t37 = {
			padding: "0 15px",
			paddingLeft: 5
		};
		$[75] = t37;
	} else t37 = $[75];
	let t38;
	if ($[76] !== onEditRule || $[77] !== rule) {
		t38 = () => onEditRule(rule);
		$[76] = onEditRule;
		$[77] = rule;
		$[78] = t38;
	} else t38 = $[78];
	let t39;
	if ($[79] === Symbol.for("react.memo_cache_sentinel")) {
		t39 = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Trans, { children: "Edit" });
		$[79] = t39;
	} else t39 = $[79];
	let t40;
	if ($[80] !== t38) {
		t40 = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Cell, {
			name: "edit",
			plain: true,
			style: t37,
			children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
				onPress: t38,
				children: t39
			})
		});
		$[80] = t38;
		$[81] = t40;
	} else t40 = $[81];
	let t41;
	if ($[82] !== T0 || $[83] !== handleContextMenu || $[84] !== t16 || $[85] !== t19 || $[86] !== t22 || $[87] !== t36 || $[88] !== t40 || $[89] !== t5 || $[90] !== t7 || $[91] !== t8) {
		t41 = /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(T0, {
			ref: triggerRef,
			height: t2,
			style: t5,
			collapsed: t6,
			onMouseEnter: t7,
			onMouseLeave: t8,
			onContextMenu: handleContextMenu,
			children: [
				t16,
				t19,
				t22,
				t36,
				t40
			]
		});
		$[82] = T0;
		$[83] = handleContextMenu;
		$[84] = t16;
		$[85] = t19;
		$[86] = t22;
		$[87] = t36;
		$[88] = t40;
		$[89] = t5;
		$[90] = t7;
		$[91] = t8;
		$[92] = t41;
	} else t41 = $[92];
	return t41;
});
RuleRow.displayName = "RuleRow";
function _temp$1(t0) {
	const { op } = t0;
	return op === "link-schedule";
}
function _temp2$1(action, j) {
	return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ActionExpression, {
		...action,
		style: j !== 0 && { marginTop: 3 }
	}, j);
}
function _temp3$1(action_0, i_1) {
	return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ActionExpression, {
		...action_0,
		style: i_1 !== 0 && { marginTop: 3 }
	}, i_1);
}
//#endregion
//#region src/components/rules/RulesList.tsx
function RulesList(t0) {
	const $ = (0, import_compiler_runtime.c)(15);
	const { rules, selectedItems, hoveredRule, onHover, onEditRule, onDeleteRule } = t0;
	if (rules.length === 0) return null;
	let t1;
	if ($[0] !== hoveredRule || $[1] !== onDeleteRule || $[2] !== onEditRule || $[3] !== onHover || $[4] !== rules || $[5] !== selectedItems) {
		let t2;
		if ($[7] !== hoveredRule || $[8] !== onDeleteRule || $[9] !== onEditRule || $[10] !== onHover || $[11] !== selectedItems) {
			t2 = (rule) => {
				return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(RuleRow, {
					rule,
					hovered: hoveredRule === rule.id,
					selected: selectedItems.has(rule.id),
					onHover,
					onEditRule,
					onDeleteRule
				}, rule.id);
			};
			$[7] = hoveredRule;
			$[8] = onDeleteRule;
			$[9] = onEditRule;
			$[10] = onHover;
			$[11] = selectedItems;
			$[12] = t2;
		} else t2 = $[12];
		t1 = rules.map(t2);
		$[0] = hoveredRule;
		$[1] = onDeleteRule;
		$[2] = onEditRule;
		$[3] = onHover;
		$[4] = rules;
		$[5] = selectedItems;
		$[6] = t1;
	} else t1 = $[6];
	let t2;
	if ($[13] !== t1) {
		t2 = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(View, { children: t1 });
		$[13] = t1;
		$[14] = t2;
	} else t2 = $[14];
	return t2;
}
//#endregion
//#region src/components/ManageRules.tsx
function mapValue(field, value, { payees = [], categories = [], accounts = [] }) {
	if (!value) return "";
	let object = null;
	if (field === "payee") object = payees.find((p) => p.id === value);
	else if (field === "category") object = categories.find((c) => c.id === value);
	else if (field === "account") object = accounts.find((a) => a.id === value);
	else return value;
	if (object) return object.name;
	return "(deleted)";
}
function ruleToString(rule, data) {
	const conditions = rule.conditions.flatMap((cond) => [
		mapField(cond.field),
		friendlyOp(cond.op),
		cond.op === "oneOf" || cond.op === "notOneOf" ? Array.isArray(cond.value) ? cond.value.map((v) => mapValue(cond.field, v, data)).join(", ") : mapValue(cond.field, cond.value, data) : mapValue(cond.field, cond.value, data)
	]);
	const actions = rule.actions.flatMap((action) => {
		if (action.op === "set") return [
			friendlyOp(action.op),
			mapField(action.field),
			"to",
			mapValue(action.field, action.value, data)
		];
		else if (action.op === "link-schedule") {
			const schedule = data.schedules?.find((s) => s.id === String(action.value));
			return [friendlyOp(action.op), schedule ? describeSchedule(schedule, data.payees?.find((p) => p.id === schedule._payee)) : "-"];
		} else if (action.op === "prepend-notes" || action.op === "append-notes") {
			const noteValue = String(action.value || "");
			return [friendlyOp(action.op), "“" + noteValue + "”"];
		} else if (action.op === "delete-transaction") return [friendlyOp(action.op), "(delete)"];
		else return [];
	});
	return (rule.stage || "") + " " + conditions.join(" ") + " " + actions.join(" ");
}
function ManageRules(t0) {
	const $ = (0, import_compiler_runtime.c)(98);
	const { isModal, payeeId, setLoading: t1 } = t0;
	const setLoading = t1 === void 0 ? _temp : t1;
	const { t } = useTranslation();
	let t2;
	if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
		t2 = [];
		$[0] = t2;
	} else t2 = $[0];
	const [allRules, setAllRules] = (0, import_react.useState)(t2);
	const [page, setPage] = (0, import_react.useState)(0);
	const [filter, setFilter] = (0, import_react.useState)("");
	const dispatch = useDispatch();
	let t3;
	if ($[1] === Symbol.for("react.memo_cache_sentinel")) {
		t3 = q("schedules").select("*");
		$[1] = t3;
	} else t3 = $[1];
	let t4;
	if ($[2] === Symbol.for("react.memo_cache_sentinel")) {
		t4 = { query: t3 };
		$[2] = t4;
	} else t4 = $[2];
	const { schedules: t5 } = useSchedules(t4);
	let t6;
	if ($[3] !== t5) {
		t6 = t5 === void 0 ? [] : t5;
		$[3] = t5;
		$[4] = t6;
	} else t6 = $[4];
	const schedules = t6;
	const { data: t7 } = useCategories();
	let t8;
	if ($[5] !== t7) {
		t8 = t7 === void 0 ? { list: [] } : t7;
		$[5] = t7;
		$[6] = t8;
	} else t8 = $[6];
	const { list: categories } = t8;
	const { data: payees } = usePayees();
	const { data: t9 } = useAccounts();
	let t10;
	if ($[7] !== t9) {
		t10 = t9 === void 0 ? [] : t9;
		$[7] = t9;
		$[8] = t10;
	} else t10 = $[8];
	const accounts = t10;
	let t11;
	if ($[9] !== accounts || $[10] !== categories || $[11] !== payees || $[12] !== schedules) {
		t11 = {
			payees,
			accounts,
			schedules,
			categories
		};
		$[9] = accounts;
		$[10] = categories;
		$[11] = payees;
		$[12] = schedules;
		$[13] = t11;
	} else t11 = $[13];
	const filterData = t11;
	let t12;
	if ($[14] !== allRules || $[15] !== filter || $[16] !== filterData || $[17] !== page || $[18] !== schedules) {
		let t13;
		if ($[20] !== schedules) {
			t13 = (rule) => {
				const schedule_0 = schedules.find((schedule) => schedule.rule === rule.id);
				return schedule_0 ? schedule_0.completed === false : true;
			};
			$[20] = schedules;
			$[21] = t13;
		} else t13 = $[21];
		const rules = allRules.filter(t13);
		t12 = (filter === "" ? rules : rules.filter((rule_0) => getNormalisedString(ruleToString(rule_0, filterData)).includes(getNormalisedString(filter)))).slice(0, 100 + page * 50);
		$[14] = allRules;
		$[15] = filter;
		$[16] = filterData;
		$[17] = page;
		$[18] = schedules;
		$[19] = t12;
	} else t12 = $[19];
	const filteredRules = t12;
	let t13;
	if ($[22] === Symbol.for("react.memo_cache_sentinel")) {
		t13 = [];
		$[22] = t13;
	} else t13 = $[22];
	const selectedInst = useSelected("manage-rules", filteredRules, t13);
	const [hoveredRule, setHoveredRule] = (0, import_react.useState)(null);
	let t14;
	if ($[23] === Symbol.for("react.memo_cache_sentinel")) {
		t14 = (value) => {
			setFilter(value);
			setPage(0);
		};
		$[23] = t14;
	} else t14 = $[23];
	const onSearchChange = t14;
	let t15;
	if ($[24] !== payeeId || $[25] !== setLoading) {
		t15 = async function loadRules() {
			setLoading(true);
			let loadedRules;
			if (payeeId) loadedRules = await send("payees-get-rules", { id: payeeId });
			else loadedRules = await send("rules-get");
			setAllRules(loadedRules);
			return loadedRules;
		};
		$[24] = payeeId;
		$[25] = setLoading;
		$[26] = t15;
	} else t15 = $[26];
	const loadRules = t15;
	let t16;
	if ($[27] !== loadRules || $[28] !== payeeId || $[29] !== setLoading) {
		t16 = () => {
			const loadData = async function loadData() {
				await loadRules();
				setLoading(false);
			};
			if (payeeId) setUndoState("openModal", {
				name: "manage-rules",
				options: {}
			});
			loadData();
			return _temp2;
		};
		$[27] = loadRules;
		$[28] = payeeId;
		$[29] = setLoading;
		$[30] = t16;
	} else t16 = $[30];
	const init = (0, import_react.useEffectEvent)(t16);
	let t17;
	if ($[31] !== init) {
		t17 = () => init();
		$[31] = init;
		$[32] = t17;
	} else t17 = $[32];
	let t18;
	if ($[33] === Symbol.for("react.memo_cache_sentinel")) {
		t18 = [];
		$[33] = t18;
	} else t18 = $[33];
	(0, import_react.useEffect)(t17, t18);
	let t19;
	if ($[34] === Symbol.for("react.memo_cache_sentinel")) {
		t19 = function loadMore() {
			setPage(_temp3);
		};
		$[34] = t19;
	} else t19 = $[34];
	const loadMore = t19;
	let t20;
	if ($[35] !== loadRules || $[36] !== selectedInst || $[37] !== setLoading || $[38] !== t) {
		t20 = async () => {
			setLoading(true);
			const { someDeletionsFailed } = await send("rule-delete-all", [...selectedInst.items]);
			if (someDeletionsFailed) alert(t("Some rules were not deleted because they are linked to schedules."));
			await loadRules();
			selectedInst.dispatch({ type: "select-none" });
			setLoading(false);
		};
		$[35] = loadRules;
		$[36] = selectedInst;
		$[37] = setLoading;
		$[38] = t;
		$[39] = t20;
	} else t20 = $[39];
	const onDeleteSelected = t20;
	let t21;
	if ($[40] !== loadRules || $[41] !== setLoading) {
		t21 = async function onDeleteRule(id) {
			setLoading(true);
			await send("rule-delete", id);
			await loadRules();
			setLoading(false);
		};
		$[40] = loadRules;
		$[41] = setLoading;
		$[42] = t21;
	} else t21 = $[42];
	const onDeleteRule = t21;
	let t22;
	if ($[43] !== dispatch || $[44] !== loadRules || $[45] !== setLoading) {
		t22 = (rule_1) => {
			dispatch(pushModal({ modal: {
				name: "edit-rule",
				options: {
					rule: rule_1,
					onSave: async () => {
						await loadRules();
						setLoading(false);
					}
				}
			} }));
		};
		$[43] = dispatch;
		$[44] = loadRules;
		$[45] = setLoading;
		$[46] = t22;
	} else t22 = $[46];
	const onEditRule = t22;
	let t23;
	if ($[47] !== dispatch || $[48] !== loadRules || $[49] !== payeeId || $[50] !== setLoading) {
		t23 = function onCreateRule() {
			dispatch(pushModal({ modal: {
				name: "edit-rule",
				options: {
					rule: {
						stage: null,
						conditionsOp: "and",
						conditions: [{
							field: "payee",
							op: "is",
							value: payeeId || null,
							type: "id"
						}],
						actions: [{
							op: "set",
							field: "category",
							value: null,
							type: "id"
						}]
					},
					onSave: async () => {
						await loadRules();
						setLoading(false);
					}
				}
			} }));
		};
		$[47] = dispatch;
		$[48] = loadRules;
		$[49] = payeeId;
		$[50] = setLoading;
		$[51] = t23;
	} else t23 = $[51];
	const onCreateRule = t23;
	let t24;
	if ($[52] === Symbol.for("react.memo_cache_sentinel")) {
		t24 = (id_0) => {
			setHoveredRule(id_0);
		};
		$[52] = t24;
	} else t24 = $[52];
	const onHover = t24;
	const t25 = isModal ? "0 13px 15px" : "0 0 15px";
	let t26;
	if ($[53] !== t25) {
		t26 = {
			flexDirection: "row",
			alignItems: "center",
			padding: t25,
			flexShrink: 0
		};
		$[53] = t25;
		$[54] = t26;
	} else t26 = $[54];
	let t27;
	if ($[55] === Symbol.for("react.memo_cache_sentinel")) {
		t27 = {
			color: theme.pageTextLight,
			flexDirection: "row",
			alignItems: "center",
			width: "50%"
		};
		$[55] = t27;
	} else t27 = $[55];
	let t28;
	if ($[56] === Symbol.for("react.memo_cache_sentinel")) {
		t28 = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Trans, { children: "Rules are always run in the order that you see them." });
		$[56] = t28;
	} else t28 = $[56];
	let t29;
	if ($[57] === Symbol.for("react.memo_cache_sentinel")) {
		t29 = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(View, {
			style: t27,
			children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, { children: [
				t28,
				" ",
				/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Link, {
					variant: "external",
					to: "https://actualbudget.org/docs/budgeting/rules/",
					linkColor: "muted",
					children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Trans, { children: "Learn more" })
				})
			] })
		});
		$[57] = t29;
	} else t29 = $[57];
	let t30;
	if ($[58] === Symbol.for("react.memo_cache_sentinel")) {
		t30 = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(View, { style: { flex: 1 } });
		$[58] = t30;
	} else t30 = $[58];
	let t31;
	if ($[59] !== t) {
		t31 = t("Filter rules...");
		$[59] = t;
		$[60] = t31;
	} else t31 = $[60];
	let t32;
	if ($[61] !== filter || $[62] !== t31) {
		t32 = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Search, {
			placeholder: t31,
			value: filter,
			onChange: onSearchChange
		});
		$[61] = filter;
		$[62] = t31;
		$[63] = t32;
	} else t32 = $[63];
	let t33;
	if ($[64] !== t26 || $[65] !== t32) {
		t33 = /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(View, {
			style: t26,
			children: [
				t29,
				t30,
				t32
			]
		});
		$[64] = t26;
		$[65] = t32;
		$[66] = t33;
	} else t33 = $[66];
	let t34;
	if ($[67] === Symbol.for("react.memo_cache_sentinel")) {
		t34 = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(RulesHeader, {});
		$[67] = t34;
	} else t34 = $[67];
	let t35;
	if ($[68] !== filteredRules || $[69] !== hoveredRule || $[70] !== onDeleteRule || $[71] !== onEditRule || $[72] !== selectedInst.items || $[73] !== t) {
		t35 = /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(View, {
			style: styles.tableContainer,
			children: [t34, /* @__PURE__ */ (0, import_jsx_runtime.jsx)(InfiniteScrollWrapper, {
				loadMore,
				children: filteredRules.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(EmptyMessage, {
					text: t("No rules"),
					style: { marginTop: 15 }
				}) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(RulesList, {
					rules: filteredRules,
					selectedItems: selectedInst.items,
					hoveredRule,
					onHover,
					onEditRule,
					onDeleteRule: (rule_3) => onDeleteRule(rule_3.id)
				})
			})]
		});
		$[68] = filteredRules;
		$[69] = hoveredRule;
		$[70] = onDeleteRule;
		$[71] = onEditRule;
		$[72] = selectedInst.items;
		$[73] = t;
		$[74] = t35;
	} else t35 = $[74];
	const t36 = isModal ? 13 : 0;
	const t37 = isModal && "1px solid " + theme.pillBorder;
	let t38;
	if ($[75] !== t36 || $[76] !== t37) {
		t38 = {
			paddingBlock: 15,
			paddingInline: t36,
			borderTop: t37,
			flexShrink: 0
		};
		$[75] = t36;
		$[76] = t37;
		$[77] = t38;
	} else t38 = $[77];
	let t39;
	if ($[78] === Symbol.for("react.memo_cache_sentinel")) {
		t39 = { justifyContent: "flex-end" };
		$[78] = t39;
	} else t39 = $[78];
	let t40;
	if ($[79] !== onDeleteSelected || $[80] !== selectedInst.items.size) {
		t40 = selectedInst.items.size > 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
			onPress: onDeleteSelected,
			children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Trans, {
				count: selectedInst.items.size,
				children: [
					"Delete ",
					{ count: selectedInst.items.size },
					" rules"
				]
			})
		});
		$[79] = onDeleteSelected;
		$[80] = selectedInst.items.size;
		$[81] = t40;
	} else t40 = $[81];
	let t41;
	if ($[82] === Symbol.for("react.memo_cache_sentinel")) {
		t41 = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Trans, { children: "Create new rule" });
		$[82] = t41;
	} else t41 = $[82];
	let t42;
	if ($[83] !== onCreateRule) {
		t42 = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button, {
			variant: "primary",
			onPress: onCreateRule,
			children: t41
		});
		$[83] = onCreateRule;
		$[84] = t42;
	} else t42 = $[84];
	let t43;
	if ($[85] !== t40 || $[86] !== t42) {
		t43 = /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(SpaceBetween, {
			gap: 10,
			style: t39,
			children: [t40, t42]
		});
		$[85] = t40;
		$[86] = t42;
		$[87] = t43;
	} else t43 = $[87];
	let t44;
	if ($[88] !== t38 || $[89] !== t43) {
		t44 = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(View, {
			style: t38,
			children: t43
		});
		$[88] = t38;
		$[89] = t43;
		$[90] = t44;
	} else t44 = $[90];
	let t45;
	if ($[91] !== t33 || $[92] !== t35 || $[93] !== t44) {
		t45 = /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(View, { children: [
			t33,
			t35,
			t44
		] });
		$[91] = t33;
		$[92] = t35;
		$[93] = t44;
		$[94] = t45;
	} else t45 = $[94];
	let t46;
	if ($[95] !== selectedInst || $[96] !== t45) {
		t46 = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SelectedProvider, {
			instance: selectedInst,
			children: t45
		});
		$[95] = selectedInst;
		$[96] = t45;
		$[97] = t46;
	} else t46 = $[97];
	return t46;
}
function _temp3(page_0) {
	return page_0 + 1;
}
function _temp2() {
	setUndoState("openModal", null);
}
function _temp() {}
function EmptyMessage(t0) {
	const $ = (0, import_compiler_runtime.c)(5);
	const { text, style } = t0;
	let t1;
	if ($[0] !== style) {
		t1 = {
			textAlign: "center",
			color: theme.pageTextSubdued,
			fontStyle: "italic",
			fontSize: 13,
			marginTop: 5,
			style
		};
		$[0] = style;
		$[1] = t1;
	} else t1 = $[1];
	let t2;
	if ($[2] !== t1 || $[3] !== text) {
		t2 = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(View, {
			style: t1,
			children: text
		});
		$[2] = t1;
		$[3] = text;
		$[4] = t2;
	} else t2 = $[4];
	return t2;
}
//#endregion
//#region src/hooks/usePayeeRuleCounts.ts
function usePayeeRuleCounts() {
	return useQuery(payeeQueries.ruleCounts());
}
//#endregion
//#region src/components/payees/PayeeRuleCountLabel.tsx
function PayeeRuleCountLabel(t0) {
	const $ = (0, import_compiler_runtime.c)(6);
	const { count, isLoading, style } = t0;
	let t1;
	if ($[0] !== count || $[1] !== isLoading) {
		t1 = isLoading ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(View, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(AnimatedLoading, { style: {
			width: 12,
			height: 12
		} }) }) : count > 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Trans, {
			count,
			children: [{ count }, " associated rules"]
		}) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Trans, { children: "Create rule" });
		$[0] = count;
		$[1] = isLoading;
		$[2] = t1;
	} else t1 = $[2];
	let t2;
	if ($[3] !== style || $[4] !== t1) {
		t2 = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
			style,
			children: t1
		});
		$[3] = style;
		$[4] = t1;
		$[5] = t2;
	} else t2 = $[5];
	return t2;
}
//#endregion
//#region src/components/banksync/bankSyncUtils.ts
var BUILT_IN_BANK_SYNC_PROVIDERS = [
	"goCardless",
	"simpleFin",
	"pluggyai"
];
var SYNC_PROVIDER_KEYS = [
	...BUILT_IN_BANK_SYNC_PROVIDERS,
	"enableBanking",
	"unlinked"
];
var syncProviderKeysSet = new Set(SYNC_PROVIDER_KEYS);
function isSyncProvider(value) {
	return syncProviderKeysSet.has(value);
}
function getSyncSourceReadable(translate) {
	return {
		goCardless: "GoCardless",
		simpleFin: "SimpleFIN",
		pluggyai: "Pluggy.ai",
		enableBanking: "Enable Banking",
		unlinked: translate("Unlinked")
	};
}
function groupBankSyncAccounts(accounts) {
	const groupedAccounts = {};
	for (const account of accounts) {
		if (account.closed) continue;
		const syncSource = account.account_sync_source ?? "unlinked";
		const existingAccounts = groupedAccounts[syncSource];
		if (existingAccounts) existingAccounts.push(account);
		else groupedAccounts[syncSource] = [account];
	}
	const sortedEntries = Object.entries(groupedAccounts).filter((entry) => isSyncProvider(entry[0]) && entry[1] != null).sort(([keyA], [keyB]) => {
		if (keyA === "unlinked") return 1;
		if (keyB === "unlinked") return -1;
		return keyA.localeCompare(keyB);
	});
	const sortedAccounts = {};
	for (const [syncSource, providerAccounts] of sortedEntries) sortedAccounts[syncSource] = providerAccounts;
	return sortedAccounts;
}
function getGroupedBankSyncEntries(groupedAccounts) {
	return Object.entries(groupedAccounts).filter((entry) => isSyncProvider(entry[0]) && entry[1] != null);
}
//#endregion
export { PayeeRuleCountLabel as a, ruleToString as c, groupActionsBySplitIndex as d, useFailedAccounts as f, InfiniteScrollWrapper as g, Search as h, groupBankSyncAccounts as i, ConditionExpression as l, usePreviewTransactions as m, getGroupedBankSyncEntries as n, usePayeeRuleCounts as o, useAccountPreviewTransactions as p, getSyncSourceReadable as r, ManageRules as s, BUILT_IN_BANK_SYNC_PROVIDERS as t, ActionExpression as u };

//# sourceMappingURL=bankSyncUtils.Dn5uvBJt.chunk.js.map