@bazous/ui 0.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +150 -0
- package/dist/answers/AnswerPicture.d.ts +13 -0
- package/dist/answers/contract.d.ts +160 -0
- package/dist/answers/draw.d.ts +16 -0
- package/dist/answers/index.d.ts +6 -0
- package/dist/answers/messages.d.ts +3 -0
- package/dist/answers.js +10 -0
- package/dist/answers.js.map +1 -0
- package/dist/canvas/index.d.ts +32 -0
- package/dist/canvas.js +285 -0
- package/dist/canvas.js.map +1 -0
- package/dist/contract/snapshot.d.ts +173 -0
- package/dist/engine/scenario.d.ts +40 -0
- package/dist/format/index.d.ts +37 -0
- package/dist/i18n/index.d.ts +25 -0
- package/dist/i18n/shared.d.ts +3 -0
- package/dist/index-yeBMtDf1.js +649 -0
- package/dist/index-yeBMtDf1.js.map +1 -0
- package/dist/index.d.ts +20 -0
- package/dist/index.js +1258 -0
- package/dist/index.js.map +1 -0
- package/dist/modules/Question.d.ts +18 -0
- package/dist/modules/available-now/index.d.ts +8 -0
- package/dist/modules/due-before-payday/index.d.ts +9 -0
- package/dist/modules/low-point/index.d.ts +12 -0
- package/dist/modules/margin-after-payday/index.d.ts +9 -0
- package/dist/modules/monthly-structure/index.d.ts +24 -0
- package/dist/modules/next-actions/index.d.ts +13 -0
- package/dist/modules/pay-cycles/index.d.ts +31 -0
- package/dist/modules/registry.d.ts +7 -0
- package/dist/modules/types.d.ts +77 -0
- package/dist/modules/what-if/index.d.ts +6 -0
- package/dist/primitives/CashflowChart.d.ts +22 -0
- package/dist/primitives/index.d.ts +57 -0
- package/dist/styles.css +1 -0
- package/package.json +84 -0
- package/schema/answers.schema.json +719 -0
- package/schema/canvas.json +181 -0
- package/schema/snapshot.schema.json +821 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,1258 @@
|
|
|
1
|
+
import { n as H, s as I, t as y, a as J, d as E, b as O, c as ae, e as te, f as ie, M as Q, g as re } from "./index-yeBMtDf1.js";
|
|
2
|
+
import { L as Qe, h as Ke, i as Ge, j as Ue, T as Ze, V as Je, k as Xe, l as Ye, m as en, o as nn, p as an, q as tn, r as rn, u as on, v as sn } from "./index-yeBMtDf1.js";
|
|
3
|
+
import { jsx as r, jsxs as d, Fragment as M } from "react/jsx-runtime";
|
|
4
|
+
import { useRef as W, useState as L, useEffect as X, useMemo as q, useLayoutEffect as oe } from "react";
|
|
5
|
+
const se = {
|
|
6
|
+
fr: {
|
|
7
|
+
brand: "Bazous",
|
|
8
|
+
sample: "APERÇU · DONNÉES FICTIVES",
|
|
9
|
+
notEnough: "Pas encore assez de données pour répondre.",
|
|
10
|
+
today: "Aujourd’hui",
|
|
11
|
+
payday: "Salaire {date}",
|
|
12
|
+
"inDays.one": "Dans {n} jour",
|
|
13
|
+
"inDays.other": "Dans {n} jours",
|
|
14
|
+
equivalent: "{cur} équivalent",
|
|
15
|
+
theme: "Thème",
|
|
16
|
+
themeDark: "Sombre",
|
|
17
|
+
themeLight: "Clair",
|
|
18
|
+
language: "Langue"
|
|
19
|
+
},
|
|
20
|
+
de: {
|
|
21
|
+
brand: "Bazous",
|
|
22
|
+
sample: "VORSCHAU · FIKTIVE DATEN",
|
|
23
|
+
notEnough: "Noch nicht genug Daten für eine Antwort.",
|
|
24
|
+
today: "Heute",
|
|
25
|
+
payday: "Lohn {date}",
|
|
26
|
+
"inDays.one": "In {n} Tag",
|
|
27
|
+
"inDays.other": "In {n} Tagen",
|
|
28
|
+
equivalent: "{cur}-Gegenwert",
|
|
29
|
+
theme: "Darstellung",
|
|
30
|
+
themeDark: "Dunkel",
|
|
31
|
+
themeLight: "Hell",
|
|
32
|
+
language: "Sprache"
|
|
33
|
+
},
|
|
34
|
+
it: {
|
|
35
|
+
brand: "Bazous",
|
|
36
|
+
sample: "ANTEPRIMA · DATI FITTIZI",
|
|
37
|
+
notEnough: "Dati non ancora sufficienti per rispondere.",
|
|
38
|
+
today: "Oggi",
|
|
39
|
+
payday: "Stipendio {date}",
|
|
40
|
+
"inDays.one": "Tra {n} giorno",
|
|
41
|
+
"inDays.other": "Tra {n} giorni",
|
|
42
|
+
equivalent: "equivalente {cur}",
|
|
43
|
+
theme: "Tema",
|
|
44
|
+
themeDark: "Scuro",
|
|
45
|
+
themeLight: "Chiaro",
|
|
46
|
+
language: "Lingua"
|
|
47
|
+
},
|
|
48
|
+
rm: {
|
|
49
|
+
brand: "Bazous",
|
|
50
|
+
sample: "PREVISTA · DATAS FICTIVAS",
|
|
51
|
+
notEnough: "Anc betg avunda datas per respunder.",
|
|
52
|
+
today: "Oz",
|
|
53
|
+
payday: "Salari {date}",
|
|
54
|
+
"inDays.one": "En {n} di",
|
|
55
|
+
"inDays.other": "En {n} dis",
|
|
56
|
+
equivalent: "equivalent {cur}",
|
|
57
|
+
theme: "Design",
|
|
58
|
+
themeDark: "Stgir",
|
|
59
|
+
themeLight: "Cler",
|
|
60
|
+
language: "Lingua"
|
|
61
|
+
},
|
|
62
|
+
en: {
|
|
63
|
+
brand: "Bazous",
|
|
64
|
+
sample: "PREVIEW · SAMPLE DATA",
|
|
65
|
+
notEnough: "Not enough data to answer yet.",
|
|
66
|
+
today: "Today",
|
|
67
|
+
payday: "Payday {date}",
|
|
68
|
+
"inDays.one": "In {n} day",
|
|
69
|
+
"inDays.other": "In {n} days",
|
|
70
|
+
equivalent: "{cur} equivalent",
|
|
71
|
+
theme: "Theme",
|
|
72
|
+
themeDark: "Dark",
|
|
73
|
+
themeLight: "Light",
|
|
74
|
+
language: "Language"
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
function P({ question: e, title: n, meta: a, actions: i, children: o, className: t }) {
|
|
78
|
+
return /* @__PURE__ */ d("article", { className: `bz-card${t ? ` ${t}` : ""}`, children: [
|
|
79
|
+
(e || n || a || i) && /* @__PURE__ */ d("header", { className: "bz-card-head", children: [
|
|
80
|
+
/* @__PURE__ */ d("div", { className: "bz-card-titles", children: [
|
|
81
|
+
e && /* @__PURE__ */ r("p", { className: "bz-question", children: e }),
|
|
82
|
+
n && /* @__PURE__ */ r("h2", { className: "bz-title", children: n })
|
|
83
|
+
] }),
|
|
84
|
+
a && /* @__PURE__ */ r("span", { className: "bz-meta", children: a }),
|
|
85
|
+
i && /* @__PURE__ */ r("div", { className: "bz-card-actions", children: i })
|
|
86
|
+
] }),
|
|
87
|
+
o
|
|
88
|
+
] });
|
|
89
|
+
}
|
|
90
|
+
function B({ question: e, label: n, value: a, unit: i, note: o, tone: t, emphasis: s }) {
|
|
91
|
+
return /* @__PURE__ */ d("article", { className: `bz-tile${s ? " bz-tile-emphasis" : ""}`, "aria-label": e, children: [
|
|
92
|
+
/* @__PURE__ */ r("p", { className: "bz-eyebrow", children: n }),
|
|
93
|
+
/* @__PURE__ */ d("p", { className: `bz-tile-value${t ? ` bz-${t}` : ""}`, children: [
|
|
94
|
+
a,
|
|
95
|
+
" ",
|
|
96
|
+
/* @__PURE__ */ r("span", { className: "bz-unit", children: i })
|
|
97
|
+
] }),
|
|
98
|
+
o && /* @__PURE__ */ r("p", { className: "bz-note", children: o })
|
|
99
|
+
] });
|
|
100
|
+
}
|
|
101
|
+
function Be({ date: e, title: n, sub: a, amount: i, amountTone: o, late: t, children: s }) {
|
|
102
|
+
return /* @__PURE__ */ d("div", { className: `bz-row${t ? " bz-late" : ""}`, children: [
|
|
103
|
+
e !== void 0 && /* @__PURE__ */ r("span", { className: "bz-date", children: e }),
|
|
104
|
+
/* @__PURE__ */ d("div", { className: "bz-row-body", children: [
|
|
105
|
+
/* @__PURE__ */ r("strong", { children: n }),
|
|
106
|
+
a && /* @__PURE__ */ r("span", { children: a })
|
|
107
|
+
] }),
|
|
108
|
+
i !== void 0 && /* @__PURE__ */ r("strong", { className: `bz-amount${o ? ` bz-${o}` : ""}`, children: i }),
|
|
109
|
+
s
|
|
110
|
+
] });
|
|
111
|
+
}
|
|
112
|
+
function x({ children: e, onClick: n, variant: a = "secondary", disabled: i }) {
|
|
113
|
+
return /* @__PURE__ */ r("button", { type: "button", className: `bz-button bz-${a}`, onClick: n, disabled: i, children: e });
|
|
114
|
+
}
|
|
115
|
+
function le({ options: e, value: n, onChange: a, label: i }) {
|
|
116
|
+
return /* @__PURE__ */ r("div", { className: "bz-seg", role: "group", "aria-label": i, children: e.map((o) => /* @__PURE__ */ r("button", { type: "button", className: o.key === n ? "bz-on" : "", "aria-pressed": o.key === n, onClick: () => a(o.key), children: o.label }, o.key)) });
|
|
117
|
+
}
|
|
118
|
+
function R({ tone: e }) {
|
|
119
|
+
return /* @__PURE__ */ r("i", { className: `bz-dot bz-dot-${e}`, "aria-hidden": "true" });
|
|
120
|
+
}
|
|
121
|
+
function j({ children: e }) {
|
|
122
|
+
return /* @__PURE__ */ r("p", { className: "bz-empty", children: e });
|
|
123
|
+
}
|
|
124
|
+
const V = ["bz-shade-1", "bz-shade-2", "bz-shade-3", "bz-shade-4"], K = 880, z = { left: 52, right: 10, top: 40, bottom: 34 };
|
|
125
|
+
function ce(e) {
|
|
126
|
+
const n = W(null), [a, i] = L(K);
|
|
127
|
+
return X(() => {
|
|
128
|
+
const o = n.current;
|
|
129
|
+
if (!o || typeof ResizeObserver > "u") return;
|
|
130
|
+
const t = new ResizeObserver(([s]) => {
|
|
131
|
+
const l = Math.round(s?.contentRect.width ?? K);
|
|
132
|
+
l > 0 && i(Math.max(300, l));
|
|
133
|
+
});
|
|
134
|
+
return t.observe(o), () => t.disconnect();
|
|
135
|
+
}, []), /* @__PURE__ */ r("div", { ref: n, className: "bz-chart-box", children: /* @__PURE__ */ r(de, { ...e, W: a }) });
|
|
136
|
+
}
|
|
137
|
+
function de({ base: e, scenario: n, today: a, incomes: i, markers: o, labels: t, W: s }) {
|
|
138
|
+
const l = s < 560 ? 260 : 330, c = s < 560, f = [...e.points, ...n?.points ?? []].flatMap((u) => u.peak === void 0 ? [u.balance] : [u.balance, u.peak]), v = e.points.length;
|
|
139
|
+
if (v === 0) return null;
|
|
140
|
+
const _ = ue(Math.min(0, ...f), Math.max(0, ...f), 4), m = _[0] ?? 0, p = _[_.length - 1] ?? 1, b = (u) => z.left + u / Math.max(v - 1, 1) * (s - z.left - z.right), w = (u) => z.top + (p - u) / (p - m || 1) * (l - z.top - z.bottom), g = (u) => e.points.findIndex((N) => N.date === u), D = (u) => e.points[g(u)]?.balance ?? 0, h = w(0), k = l - z.bottom, $ = g(e.low.date), T = b($), S = Math.abs(T - b(0)) > (c ? 110 : 70) ? [{ i: 0, anchor: "start" }] : [];
|
|
141
|
+
for (const u of o) {
|
|
142
|
+
const N = g(u.date);
|
|
143
|
+
!c && N > 0 && N < v - 1 && S.every((A) => Math.abs(b(A.i) - b(N)) > 60) && Math.abs(b(N) - T) > 70 && S.push({ i: N, anchor: "middle" });
|
|
144
|
+
}
|
|
145
|
+
Math.abs(b(v - 1) - T) > (c ? 110 : 70) && S.push({ i: v - 1, anchor: "end" });
|
|
146
|
+
const C = b(g(a)), Y = i.some((u) => g(u) >= 0 && Math.abs(b(g(u)) - C) < 90), ee = e.points[0], ne = e.points[v - 1];
|
|
147
|
+
return /* @__PURE__ */ d("svg", { className: "bz-chart", viewBox: `0 0 ${s} ${l}`, role: "img", "aria-label": t.aria, children: [
|
|
148
|
+
h < k && /* @__PURE__ */ r("rect", { x: z.left, y: h, width: s - z.left - z.right, height: k - h, className: "bz-chart-danger" }),
|
|
149
|
+
_.map((u) => /* @__PURE__ */ d("g", { children: [
|
|
150
|
+
/* @__PURE__ */ r("line", { x1: z.left, x2: s - z.right, y1: w(u), y2: w(u), className: u === 0 ? "bz-chart-zero" : "bz-chart-grid" }),
|
|
151
|
+
/* @__PURE__ */ r("text", { x: z.left - 8, y: w(u) + 4, textAnchor: "end", className: u === 0 ? "bz-chart-tick bz-strong" : "bz-chart-tick", children: H(u) })
|
|
152
|
+
] }, u)),
|
|
153
|
+
i.map((u) => {
|
|
154
|
+
if (g(u) < 0) return null;
|
|
155
|
+
const N = c ? I(u) : t.payday(I(u)), A = b(g(u)) + N.length * 6.5 > s - z.right;
|
|
156
|
+
return /* @__PURE__ */ d("g", { children: [
|
|
157
|
+
/* @__PURE__ */ r("line", { x1: b(g(u)), x2: b(g(u)), y1: z.top, y2: k, className: "bz-chart-income" }),
|
|
158
|
+
/* @__PURE__ */ r("text", { x: b(g(u)) + (A ? -4 : 4), y: z.top - 10, textAnchor: A ? "end" : "start", className: "bz-chart-label bz-income", children: N })
|
|
159
|
+
] }, u);
|
|
160
|
+
}),
|
|
161
|
+
g(a) >= 0 && /* @__PURE__ */ d("g", { children: [
|
|
162
|
+
/* @__PURE__ */ r("line", { x1: C, x2: C, y1: z.top, y2: k, className: "bz-chart-today" }),
|
|
163
|
+
/* @__PURE__ */ r("text", { x: C + 4, y: Y ? z.top - 26 : z.top - 10, className: "bz-chart-label bz-today", children: t.today })
|
|
164
|
+
] }),
|
|
165
|
+
n && /* @__PURE__ */ r("polyline", { points: G(n.points, b, w), className: "bz-chart-scenario" }),
|
|
166
|
+
/* @__PURE__ */ r("polyline", { points: G(e.points, b, w), className: "bz-chart-base" }),
|
|
167
|
+
o.map((u) => g(u.date) >= 0 && /* @__PURE__ */ d("g", { children: [
|
|
168
|
+
/* @__PURE__ */ r("circle", { cx: b(g(u.date)), cy: w(D(u.date)), r: "5", className: "bz-chart-dot" }),
|
|
169
|
+
!c && /* @__PURE__ */ r("text", { x: b(g(u.date)) + 10, y: w(D(u.date)) + 4, className: "bz-chart-label", children: u.label })
|
|
170
|
+
] }, `${u.date}-${u.label}`)),
|
|
171
|
+
$ >= 0 && /* @__PURE__ */ d("g", { children: [
|
|
172
|
+
/* @__PURE__ */ r("circle", { cx: T, cy: w(e.low.balance), r: "7", className: "bz-chart-low" }),
|
|
173
|
+
/* @__PURE__ */ d("text", { x: T, y: l - 8, textAnchor: T > s - 60 ? "end" : "middle", className: "bz-chart-label bz-low", children: [
|
|
174
|
+
I(e.low.date),
|
|
175
|
+
" · ",
|
|
176
|
+
H(e.low.balance)
|
|
177
|
+
] })
|
|
178
|
+
] }),
|
|
179
|
+
S.map((u) => {
|
|
180
|
+
const N = u.i === 0 ? ee : u.i === v - 1 ? ne : e.points[u.i];
|
|
181
|
+
return N ? /* @__PURE__ */ r("text", { x: b(u.i), y: l - 8, textAnchor: u.anchor, className: "bz-chart-tick", children: I(N.date) }, u.i) : null;
|
|
182
|
+
})
|
|
183
|
+
] });
|
|
184
|
+
}
|
|
185
|
+
function G(e, n, a) {
|
|
186
|
+
const i = [];
|
|
187
|
+
let o = null;
|
|
188
|
+
return e.forEach((t, s) => {
|
|
189
|
+
(o === null || t.balance !== o || t.peak !== void 0 || s === e.length - 1) && (t.peak !== void 0 && i.push(`${n(s).toFixed(1)},${a(t.peak).toFixed(1)}`), i.push(`${n(s).toFixed(1)},${a(t.balance).toFixed(1)}`)), o = t.balance;
|
|
190
|
+
}), i.join(" ");
|
|
191
|
+
}
|
|
192
|
+
function ue(e, n, a) {
|
|
193
|
+
const i = (n - e) / Math.max(a, 1) || 1, o = 10 ** Math.floor(Math.log10(i)), t = [1, 2, 2.5, 5, 10].map((f) => f * o).find((f) => f >= i) ?? o * 10, s = Math.floor(e / t) * t, l = Math.ceil(n / t) * t, c = [];
|
|
194
|
+
for (let f = s; f <= l + t / 2; f += t) c.push(Math.round(f));
|
|
195
|
+
return c.length < 2 && c.push(Math.round(s + t)), c;
|
|
196
|
+
}
|
|
197
|
+
function me(e) {
|
|
198
|
+
const n = e.second_income_date ?? J(e.as_of, 30), { start: a, end: i } = e.main_cycle, o = e.events.filter((c) => c.direction === "outflow" && c.date >= a && c.date <= i).sort((c, f) => y(f.amount) - y(c.amount)).slice(0, 2), t = [], [s, l] = o;
|
|
199
|
+
if (s && t.push({ id: `split:${s.ref_id ?? s.label}`, kind: "split", event: s, target: n }), l && t.push({ id: `defer:${l.ref_id ?? l.label}`, kind: "defer", event: l, target: n }), e.next_income_date) {
|
|
200
|
+
const c = e.events.find((f) => f.direction === "inflow" && f.date === e.next_income_date);
|
|
201
|
+
if (c) {
|
|
202
|
+
const f = Math.round(y(c.amount) * 0.4 / 500) * 500;
|
|
203
|
+
f > 0 && t.push({ id: `reserve:${e.next_income_date}`, kind: "reserve", event: c, target: n, reserve: f });
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
return t;
|
|
207
|
+
}
|
|
208
|
+
function U(e, n, a) {
|
|
209
|
+
const i = [], o = a.filter((m) => n.has(m.id)), t = new Map(o.filter((m) => m.kind !== "reserve").map((m) => [m.event.ref_id ?? m.event.label, m])), s = o.find((m) => m.kind === "reserve");
|
|
210
|
+
for (const m of e.events) {
|
|
211
|
+
const p = y(m.amount) * (m.direction === "inflow" ? 1 : -1), b = t.get(m.ref_id ?? m.label);
|
|
212
|
+
b ? b.kind === "defer" ? i.push({ date: b.target, amount: p }) : (i.push({ date: m.date, amount: p / 2 }), i.push({ date: b.target, amount: p / 2 })) : i.push({ date: m.date, amount: p });
|
|
213
|
+
}
|
|
214
|
+
if (s?.reserve && e.next_income_date) {
|
|
215
|
+
const m = e.next_income_date, p = e.second_income_date ?? e.horizon_end;
|
|
216
|
+
let b = y(e.opening_balance);
|
|
217
|
+
const w = [...i].sort((g, D) => g.date.localeCompare(D.date) || D.amount - g.amount);
|
|
218
|
+
i.length = 0;
|
|
219
|
+
for (const g of w) {
|
|
220
|
+
if (g.date >= m && g.date < p && g.amount < 0 && b + g.amount < s.reserve) {
|
|
221
|
+
i.push({ date: p, amount: g.amount });
|
|
222
|
+
continue;
|
|
223
|
+
}
|
|
224
|
+
b += g.amount, i.push(g);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
const l = /* @__PURE__ */ new Map();
|
|
228
|
+
for (const m of i) {
|
|
229
|
+
if (m.date < e.as_of || m.date > e.horizon_end) continue;
|
|
230
|
+
const p = l.get(m.date) ?? { inflow: 0, outflow: 0 };
|
|
231
|
+
m.amount >= 0 ? p.inflow += m.amount : p.outflow += m.amount, l.set(m.date, p);
|
|
232
|
+
}
|
|
233
|
+
let c = y(e.opening_balance), f = { date: e.as_of, balance: c, daysFromNow: 0 };
|
|
234
|
+
const v = [], _ = E(e.as_of, e.horizon_end);
|
|
235
|
+
for (let m = 0; m <= _; m++) {
|
|
236
|
+
const p = J(e.as_of, m), b = l.get(p), w = b && b.inflow > 0 && b.outflow < 0 ? c + b.inflow : void 0;
|
|
237
|
+
c = F(c + (b ? b.inflow + b.outflow : 0)), c < f.balance && (f = { date: p, balance: c, daysFromNow: m }), v.push(w === void 0 ? { date: p, balance: c } : { date: p, balance: c, peak: F(w) });
|
|
238
|
+
}
|
|
239
|
+
return { points: v, low: f, end: { date: e.horizon_end, balance: c } };
|
|
240
|
+
}
|
|
241
|
+
function he(e) {
|
|
242
|
+
let n = y(e.opening_balance);
|
|
243
|
+
const a = e.points.map((o) => {
|
|
244
|
+
const t = y(o.inflows), s = y(o.outflows), l = y(o.closing_balance), c = t > 0 && s > 0 ? { date: o.date, balance: l, peak: F(n + t) } : { date: o.date, balance: l };
|
|
245
|
+
return n = l, c;
|
|
246
|
+
}), i = a[a.length - 1];
|
|
247
|
+
return {
|
|
248
|
+
points: a,
|
|
249
|
+
low: { date: e.low_point.date, balance: y(e.low_point.balance), daysFromNow: e.low_point.days_from_now },
|
|
250
|
+
end: { date: e.end_of_horizon.date, balance: i ? i.balance : y(e.end_of_horizon.balance) }
|
|
251
|
+
};
|
|
252
|
+
}
|
|
253
|
+
const F = (e) => Math.round(e * 100) / 100;
|
|
254
|
+
function je(e) {
|
|
255
|
+
return e;
|
|
256
|
+
}
|
|
257
|
+
const pe = /* @__PURE__ */ new Set(["bank", "prepaid", "cash"]), be = {
|
|
258
|
+
id: "available-now",
|
|
259
|
+
size: "tile",
|
|
260
|
+
question: {
|
|
261
|
+
fr: "Combien ai-je maintenant ?",
|
|
262
|
+
de: "Wie viel habe ich jetzt?",
|
|
263
|
+
it: "Quanto ho adesso?",
|
|
264
|
+
rm: "Quant hai jau ussa?",
|
|
265
|
+
en: "How much do I have now?"
|
|
266
|
+
},
|
|
267
|
+
reads: ["opening_balance", "base_currency", "accounts", "data_quality"],
|
|
268
|
+
messages: {
|
|
269
|
+
fr: { label: "Disponible maintenant", "missing.one": "{n} compte sans solde", "missing.other": "{n} comptes sans solde", none: "Aucun solde renseigné" },
|
|
270
|
+
de: { label: "Jetzt verfügbar", "missing.one": "{n} Konto ohne Saldo", "missing.other": "{n} Konten ohne Saldo", none: "Noch kein Saldo erfasst" },
|
|
271
|
+
it: { label: "Disponibile ora", "missing.one": "{n} conto senza saldo", "missing.other": "{n} conti senza saldo", none: "Nessun saldo inserito" },
|
|
272
|
+
rm: { label: "Disponibel ussa", "missing.one": "{n} conto senza saldo", "missing.other": "{n} contos senza saldo", none: "Anc nagin saldo endatà" },
|
|
273
|
+
en: { label: "Available now", "missing.one": "{n} account without a balance", "missing.other": "{n} accounts without a balance", none: "No balance entered yet" }
|
|
274
|
+
},
|
|
275
|
+
select: (e) => ({
|
|
276
|
+
amount: e.opening_balance,
|
|
277
|
+
currency: e.base_currency,
|
|
278
|
+
known: e.accounts.filter((n) => n.balance !== null && pe.has(n.account_type)).map((n) => n.name),
|
|
279
|
+
missing: e.data_quality.accounts_without_balance.length
|
|
280
|
+
}),
|
|
281
|
+
View: ({ model: e, t: n, fmt: a }) => {
|
|
282
|
+
const i = [...e.known.length ? [e.known.join(", ")] : [], ...e.missing ? [n("missing", { n: e.missing })] : []];
|
|
283
|
+
return /* @__PURE__ */ r(
|
|
284
|
+
B,
|
|
285
|
+
{
|
|
286
|
+
question: n("question"),
|
|
287
|
+
label: n("label"),
|
|
288
|
+
value: a.num(e.amount),
|
|
289
|
+
unit: e.currency,
|
|
290
|
+
tone: y(e.amount) < 0 ? "neg" : void 0,
|
|
291
|
+
note: i.join(" · ") || n("none")
|
|
292
|
+
}
|
|
293
|
+
);
|
|
294
|
+
}
|
|
295
|
+
}, ge = {
|
|
296
|
+
id: "due-before-payday",
|
|
297
|
+
size: "tile",
|
|
298
|
+
question: {
|
|
299
|
+
fr: "Que dois-je payer avant le salaire ?",
|
|
300
|
+
de: "Was muss ich vor dem Lohn bezahlen?",
|
|
301
|
+
it: "Cosa devo pagare prima dello stipendio?",
|
|
302
|
+
rm: "Tge stoss jau pajar avant il salari?",
|
|
303
|
+
en: "What do I owe before payday?"
|
|
304
|
+
},
|
|
305
|
+
reads: ["due_before_next_income", "gap_before_next_income", "opening_balance", "next_income_date", "base_currency"],
|
|
306
|
+
messages: {
|
|
307
|
+
fr: { label: "À payer avant le revenu · {day} {date}", labelNone: "Aucun revenu prévu", covered: "Couvert · il reste {rest}", short: "Il manque {gap} avant le revenu", split: "{due} dus − {available} disponibles" },
|
|
308
|
+
de: { label: "Vor dem Einkommen fällig · {day} {date}", labelNone: "Kein Einkommen geplant", covered: "Gedeckt · es bleiben {rest}", short: "Bis zum Einkommen fehlen {gap}", split: "{due} fällig − {available} verfügbar" },
|
|
309
|
+
it: { label: "Da pagare prima del reddito · {day} {date}", labelNone: "Nessun reddito previsto", covered: "Coperto · restano {rest}", short: "Mancano {gap} prima del reddito", split: "{due} dovuti − {available} disponibili" },
|
|
310
|
+
rm: { label: "Da pajar avant il salari · {day} {date}", labelNone: "Nagin salari previs", covered: "Cuvrì · i restan {rest}", short: "I mancan {gap} avant il salari", split: "{due} da pajar − {available} disponibels" },
|
|
311
|
+
en: { label: "Due before payday · {day} {date}", labelNone: "No income scheduled", covered: "Covered · {rest} left", short: "{gap} short before payday", split: "{due} due − {available} available" }
|
|
312
|
+
},
|
|
313
|
+
select: (e) => ({
|
|
314
|
+
due: e.due_before_next_income,
|
|
315
|
+
available: e.opening_balance,
|
|
316
|
+
gap: e.gap_before_next_income,
|
|
317
|
+
currency: e.base_currency,
|
|
318
|
+
payday: e.next_income_date
|
|
319
|
+
}),
|
|
320
|
+
View: ({ model: e, t: n, fmt: a }) => {
|
|
321
|
+
const i = y(e.gap), o = i < 0;
|
|
322
|
+
return /* @__PURE__ */ r(
|
|
323
|
+
B,
|
|
324
|
+
{
|
|
325
|
+
question: n("question"),
|
|
326
|
+
label: e.payday ? n("label", { day: a.weekday(e.payday), date: a.shortDate(e.payday) }) : n("labelNone"),
|
|
327
|
+
value: a.num(e.due),
|
|
328
|
+
unit: e.currency,
|
|
329
|
+
tone: o ? "neg" : void 0,
|
|
330
|
+
note: /* @__PURE__ */ d(M, { children: [
|
|
331
|
+
o ? n("short", { gap: a.num(Math.abs(i)) }) : n("covered", { rest: a.num(i) }),
|
|
332
|
+
/* @__PURE__ */ r("br", {}),
|
|
333
|
+
n("split", { due: a.num(e.due), available: a.num(e.available) })
|
|
334
|
+
] })
|
|
335
|
+
}
|
|
336
|
+
);
|
|
337
|
+
}
|
|
338
|
+
}, fe = {
|
|
339
|
+
id: "low-point",
|
|
340
|
+
size: "tile",
|
|
341
|
+
question: {
|
|
342
|
+
fr: "Jusqu’où puis-je descendre ?",
|
|
343
|
+
de: "Wie tief sinkt mein Saldo?",
|
|
344
|
+
it: "Quanto scenderà il saldo?",
|
|
345
|
+
rm: "Quant bass vegn il saldo?",
|
|
346
|
+
en: "How low might I go?"
|
|
347
|
+
},
|
|
348
|
+
reads: ["low_point", "next_income_date", "second_income_date", "base_currency"],
|
|
349
|
+
messages: {
|
|
350
|
+
fr: { label: "Point bas prévu · {day} {date}", "before.one": "{n} jour avant le revenu du {date}", "before.other": "{n} jours avant le revenu du {date}" },
|
|
351
|
+
de: { label: "Prognostizierter Tiefpunkt · {day} {date}", "before.one": "{n} Tag vor dem Einkommen am {date}", "before.other": "{n} Tage vor dem Einkommen am {date}" },
|
|
352
|
+
it: { label: "Minimo previsto · {day} {date}", "before.one": "{n} giorno prima del reddito del {date}", "before.other": "{n} giorni prima del reddito del {date}" },
|
|
353
|
+
rm: { label: "Punct bass previs · {day} {date}", "before.one": "{n} di avant il salari dals {date}", "before.other": "{n} dis avant il salari dals {date}" },
|
|
354
|
+
en: { label: "Projected low point · {day} {date}", "before.one": "{n} day before the {date} income", "before.other": "{n} days before the {date} income" }
|
|
355
|
+
},
|
|
356
|
+
select: (e) => {
|
|
357
|
+
const n = [e.next_income_date, e.second_income_date].find((a) => !!a && a > e.low_point.date) ?? null;
|
|
358
|
+
return {
|
|
359
|
+
balance: e.low_point.balance,
|
|
360
|
+
date: e.low_point.date,
|
|
361
|
+
days: e.low_point.days_from_now,
|
|
362
|
+
currency: e.base_currency,
|
|
363
|
+
beforeIncome: n ? { days: E(e.low_point.date, n), date: n } : null
|
|
364
|
+
};
|
|
365
|
+
},
|
|
366
|
+
View: ({ model: e, t: n, fmt: a }) => {
|
|
367
|
+
const i = e.days === 0 ? n("today") : n("inDays", { n: e.days }), o = e.beforeIncome ? `${i} · ${n("before", { n: e.beforeIncome.days, date: a.shortDate(e.beforeIncome.date) })}` : i;
|
|
368
|
+
return /* @__PURE__ */ r(
|
|
369
|
+
B,
|
|
370
|
+
{
|
|
371
|
+
emphasis: !0,
|
|
372
|
+
question: n("question"),
|
|
373
|
+
label: n("label", { day: a.weekday(e.date), date: a.shortDate(e.date) }),
|
|
374
|
+
value: a.num(e.balance),
|
|
375
|
+
unit: e.currency,
|
|
376
|
+
tone: y(e.balance) < 0 ? "neg" : void 0,
|
|
377
|
+
note: o
|
|
378
|
+
}
|
|
379
|
+
);
|
|
380
|
+
}
|
|
381
|
+
}, ye = {
|
|
382
|
+
id: "margin-after-payday",
|
|
383
|
+
size: "tile",
|
|
384
|
+
question: {
|
|
385
|
+
fr: "Que me restera-t-il ?",
|
|
386
|
+
de: "Was bleibt mir?",
|
|
387
|
+
it: "Cosa mi resterà?",
|
|
388
|
+
rm: "Tge ma resta?",
|
|
389
|
+
en: "What will be left?"
|
|
390
|
+
},
|
|
391
|
+
reads: ["end_of_horizon", "second_income_date", "data_quality", "base_currency"],
|
|
392
|
+
messages: {
|
|
393
|
+
fr: { label: "Marge au {date}", labelTwo: "Marge au {date} · 2 salaires", ok: "Après toutes les échéances connues", "missing.one": "{n} récurrence encore sans montant", "missing.other": "{n} récurrences encore sans montant" },
|
|
394
|
+
de: { label: "Spielraum am {date}", labelTwo: "Spielraum am {date} · 2 Löhne", ok: "Nach allen bekannten Fälligkeiten", "missing.one": "{n} wiederkehrender Posten noch ohne Betrag", "missing.other": "{n} wiederkehrende Posten noch ohne Betrag" },
|
|
395
|
+
it: { label: "Margine al {date}", labelTwo: "Margine al {date} · 2 stipendi", ok: "Dopo tutte le scadenze note", "missing.one": "{n} ricorrenza ancora senza importo", "missing.other": "{n} ricorrenze ancora senza importo" },
|
|
396
|
+
rm: { label: "Margin ils {date}", labelTwo: "Margin ils {date} · 2 salaris", ok: "Suenter tut ils termins enconuschents", "missing.one": "{n} repetiziun anc senza summa", "missing.other": "{n} repetiziuns anc senza summa" },
|
|
397
|
+
en: { label: "Margin on {date}", labelTwo: "Margin on {date} · 2 paydays", ok: "After every known bill", "missing.one": "{n} recurring item still without an amount", "missing.other": "{n} recurring items still without an amount" }
|
|
398
|
+
},
|
|
399
|
+
select: (e) => ({
|
|
400
|
+
balance: e.end_of_horizon.balance,
|
|
401
|
+
date: e.end_of_horizon.date,
|
|
402
|
+
twoIncomes: !!e.second_income_date,
|
|
403
|
+
currency: e.base_currency,
|
|
404
|
+
missing: e.data_quality.rules_without_amount.length
|
|
405
|
+
}),
|
|
406
|
+
View: ({ model: e, t: n, fmt: a }) => /* @__PURE__ */ r(
|
|
407
|
+
B,
|
|
408
|
+
{
|
|
409
|
+
question: n("question"),
|
|
410
|
+
label: n(e.twoIncomes ? "labelTwo" : "label", { date: a.shortDate(e.date) }),
|
|
411
|
+
value: a.signed(e.balance),
|
|
412
|
+
unit: e.currency,
|
|
413
|
+
tone: O(e.balance),
|
|
414
|
+
note: e.missing > 0 ? n("missing", { n: e.missing }) : n("ok")
|
|
415
|
+
}
|
|
416
|
+
)
|
|
417
|
+
}, ve = {
|
|
418
|
+
id: "monthly-structure",
|
|
419
|
+
size: "narrow",
|
|
420
|
+
question: {
|
|
421
|
+
fr: "Combien me coûte un mois ?",
|
|
422
|
+
de: "Was kostet mich ein Monat?",
|
|
423
|
+
it: "Quanto mi costa un mese?",
|
|
424
|
+
rm: "Quant ma custa in mais?",
|
|
425
|
+
en: "What does a month cost me?"
|
|
426
|
+
},
|
|
427
|
+
reads: ["structure", "debts", "data_quality", "second_income_date", "base_currency"],
|
|
428
|
+
messages: {
|
|
429
|
+
fr: { title: "Structure mensuelle", fixedOf: "{cur} de charges fixes / {income} de revenus", others: "Autres ({names})", marginTitle: "Marge structurelle", margin: "≈ {amount} {cur} / mois", noIncome: "Revenus récurrents non définis", ratio: "Taux de charges fixes : {p} %.", "missing.one": "{n} récurrence sans montant non comptée.", "missing.other": "{n} récurrences sans montant non comptées.", debts: "Dettes court terme", target: "objectif zéro au {date}", empty: "Aucune récurrence active." },
|
|
430
|
+
de: { title: "Monatliche Struktur", fixedOf: "{cur} Fixkosten / {income} Einkommen", others: "Übrige ({names})", marginTitle: "Struktureller Spielraum", margin: "≈ {amount} {cur} / Monat", noIncome: "Wiederkehrendes Einkommen fehlt", ratio: "Fixkostenquote: {p} %.", "missing.one": "{n} Posten ohne Betrag nicht eingerechnet.", "missing.other": "{n} Posten ohne Betrag nicht eingerechnet.", debts: "Kurzfristige Schulden", target: "Ziel null bis {date}", empty: "Keine wiederkehrenden Posten." },
|
|
431
|
+
it: { title: "Struttura mensile", fixedOf: "{cur} di costi fissi / {income} di reddito", others: "Altro ({names})", marginTitle: "Margine strutturale", margin: "≈ {amount} {cur} / mese", noIncome: "Reddito ricorrente non definito", ratio: "Quota di costi fissi: {p} %.", "missing.one": "{n} ricorrenza senza importo non conteggiata.", "missing.other": "{n} ricorrenze senza importo non conteggiate.", debts: "Debiti a breve termine", target: "obiettivo zero entro il {date}", empty: "Nessuna ricorrenza attiva." },
|
|
432
|
+
rm: { title: "Structura mensila", fixedOf: "{cur} custs fixs / {income} entradas", others: "Auters ({names})", marginTitle: "Margin structural", margin: "≈ {amount} {cur} / mais", noIncome: "Entradas regularas betg definidas", ratio: "Quota da custs fixs: {p} %.", "missing.one": "{n} repetiziun senza summa betg quintada.", "missing.other": "{n} repetiziuns senza summa betg quintadas.", debts: "Debits a curta vista", target: "finamira nulla fin ils {date}", empty: "Naginas repetiziuns activas." },
|
|
433
|
+
en: { title: "Monthly structure", fixedOf: "{cur} fixed costs / {income} income", others: "Other ({names})", marginTitle: "Structural margin", margin: "≈ {amount} {cur} / month", noIncome: "No recurring income set", ratio: "Fixed-cost ratio: {p}%.", "missing.one": "{n} item without an amount not counted.", "missing.other": "{n} items without an amount not counted.", debts: "Short-term debt", target: "target zero by {date}", empty: "No active recurring items." }
|
|
434
|
+
},
|
|
435
|
+
select: (e) => {
|
|
436
|
+
const n = e.structure.by_category.map((i) => ({ category: i.category, amount: y(i.amount) })), a = n.length <= 4 ? n : [...n.slice(0, 3), { category: "", amount: n.slice(3).reduce((i, o) => i + o.amount, 0), others: n.slice(3).map((i) => i.category) }];
|
|
437
|
+
return {
|
|
438
|
+
fixed: e.structure.fixed_monthly,
|
|
439
|
+
income: e.structure.income_monthly,
|
|
440
|
+
ratio: e.structure.fixed_ratio_percent,
|
|
441
|
+
margin: e.structure.structural_margin,
|
|
442
|
+
slices: a,
|
|
443
|
+
currency: e.base_currency,
|
|
444
|
+
missing: e.data_quality.rules_without_amount.length,
|
|
445
|
+
debts: e.debts.items.length ? { total: e.debts.total_base, items: e.debts.items.map((i) => ({ name: i.name, principal: i.principal })) } : null,
|
|
446
|
+
target: e.second_income_date
|
|
447
|
+
};
|
|
448
|
+
},
|
|
449
|
+
View: ({ model: e, t: n, fmt: a }) => {
|
|
450
|
+
const i = y(e.income), o = (t) => t.others ? n("others", { names: t.others.join(", ") }) : t.category;
|
|
451
|
+
return /* @__PURE__ */ d(P, { question: n("question"), title: n("title"), children: [
|
|
452
|
+
/* @__PURE__ */ d("div", { className: "bz-inline", children: [
|
|
453
|
+
/* @__PURE__ */ r("strong", { className: "bz-figure", children: a.num(e.fixed) }),
|
|
454
|
+
/* @__PURE__ */ r("span", { className: "bz-note", children: n("fixedOf", { cur: e.currency, income: a.num(e.income) }) })
|
|
455
|
+
] }),
|
|
456
|
+
/* @__PURE__ */ r("div", { className: "bz-stack", role: "img", "aria-label": e.slices.map((t) => `${o(t)} ${a.num(t.amount)}`).join(", "), children: e.slices.map((t, s) => /* @__PURE__ */ r("i", { className: V[s], style: { width: `${i > 0 ? t.amount / i * 100 : 0}%` } }, o(t))) }),
|
|
457
|
+
/* @__PURE__ */ d("div", { className: "bz-cats", children: [
|
|
458
|
+
e.slices.map((t, s) => /* @__PURE__ */ d("div", { children: [
|
|
459
|
+
/* @__PURE__ */ r("i", { className: V[s] }),
|
|
460
|
+
/* @__PURE__ */ r("span", { children: o(t) }),
|
|
461
|
+
/* @__PURE__ */ r("strong", { children: a.num(t.amount) })
|
|
462
|
+
] }, o(t))),
|
|
463
|
+
e.slices.length === 0 && /* @__PURE__ */ r(j, { children: n("empty") })
|
|
464
|
+
] }),
|
|
465
|
+
/* @__PURE__ */ r("hr", { className: "bz-rule" }),
|
|
466
|
+
/* @__PURE__ */ r("p", { className: "bz-eyebrow", children: n("marginTitle") }),
|
|
467
|
+
/* @__PURE__ */ r("strong", { className: `bz-figure-s bz-${O(e.margin ?? 0)}`, children: e.margin ? n("margin", { amount: a.num(e.margin), cur: e.currency }) : n("noIncome") }),
|
|
468
|
+
/* @__PURE__ */ d("p", { className: "bz-note", children: [
|
|
469
|
+
e.ratio ? n("ratio", { p: a.num(e.ratio) }) : "",
|
|
470
|
+
e.missing > 0 ? ` ${n("missing", { n: e.missing })}` : ""
|
|
471
|
+
] }),
|
|
472
|
+
e.debts && /* @__PURE__ */ d(M, { children: [
|
|
473
|
+
/* @__PURE__ */ r("hr", { className: "bz-rule" }),
|
|
474
|
+
/* @__PURE__ */ r("p", { className: "bz-eyebrow", children: n("debts") }),
|
|
475
|
+
/* @__PURE__ */ d("strong", { className: "bz-figure-s", children: [
|
|
476
|
+
a.num(e.debts.total),
|
|
477
|
+
" ",
|
|
478
|
+
e.currency
|
|
479
|
+
] }),
|
|
480
|
+
/* @__PURE__ */ d("p", { className: "bz-note", children: [
|
|
481
|
+
e.debts.items.map((t) => `${t.name} ${a.num(t.principal)}`).join(" · "),
|
|
482
|
+
e.target ? ` · ${n("target", { date: a.shortDate(e.target) })}` : ""
|
|
483
|
+
] })
|
|
484
|
+
] })
|
|
485
|
+
] });
|
|
486
|
+
}
|
|
487
|
+
}, we = [
|
|
488
|
+
{ key: "late", accepts: (e) => e.type === "overdue" || e.type === "due_today" },
|
|
489
|
+
{ key: "beforePayday", accepts: (e) => e.type === "before_income" },
|
|
490
|
+
{ key: "toConfirm", accepts: (e) => e.type === "undated" || e.type === "needs_review" || e.type === "missing_amounts" },
|
|
491
|
+
{ key: "toPlan", accepts: (e) => e.type === "plan" }
|
|
492
|
+
], ze = {
|
|
493
|
+
id: "next-actions",
|
|
494
|
+
size: "wide",
|
|
495
|
+
question: {
|
|
496
|
+
fr: "Que faire ensuite ?",
|
|
497
|
+
de: "Was kommt als Nächstes?",
|
|
498
|
+
it: "Cosa faccio dopo?",
|
|
499
|
+
rm: "Tge vegn suenter?",
|
|
500
|
+
en: "What next?"
|
|
501
|
+
},
|
|
502
|
+
reads: ["actions", "base_currency", "next_income_date"],
|
|
503
|
+
messages: {
|
|
504
|
+
fr: {
|
|
505
|
+
title: "À traiter",
|
|
506
|
+
"count.one": "{n} décision · {m} min",
|
|
507
|
+
"count.other": "{n} décisions · {m} min",
|
|
508
|
+
empty: "Rien à traiter aujourd’hui.",
|
|
509
|
+
"g.late": "En retard",
|
|
510
|
+
"g.beforePayday": "À payer avant le prochain salaire",
|
|
511
|
+
"g.toConfirm": "Sans date ou à confirmer",
|
|
512
|
+
"g.toPlan": "À planifier",
|
|
513
|
+
overdue: "{label} · échu depuis le {date}",
|
|
514
|
+
dueToday: "{label} · échu aujourd’hui",
|
|
515
|
+
beforePayday: "{label} · à payer avant le salaire · {date}",
|
|
516
|
+
undated: "{label} · date à confirmer",
|
|
517
|
+
markPaid: "Marquer payé",
|
|
518
|
+
planOn: "Planifier le {date}",
|
|
519
|
+
plan: "{label} · {amount} avant le {date}",
|
|
520
|
+
planBody: "Échéance après le salaire : rien à faire avant, prévoyez-la dans le prochain cycle.",
|
|
521
|
+
review: "{label} · à qualifier",
|
|
522
|
+
reviewTx: "Transaction du {date} · {amount}",
|
|
523
|
+
reviewOb: "Échéance du {date} · {amount}",
|
|
524
|
+
confidence: "confiance {p} %",
|
|
525
|
+
internal: "Transfert interne",
|
|
526
|
+
expense: "Dépense",
|
|
527
|
+
accept: "Valider",
|
|
528
|
+
cancel: "Annuler",
|
|
529
|
+
"missing.one": "{n} récurrence sans montant",
|
|
530
|
+
"missing.other": "{n} récurrences sans montant",
|
|
531
|
+
missingBody: "{items} · la marge finale est fausse tant qu’elles manquent",
|
|
532
|
+
complete: "Compléter"
|
|
533
|
+
},
|
|
534
|
+
de: {
|
|
535
|
+
title: "Zu erledigen",
|
|
536
|
+
"count.one": "{n} Entscheidung · {m} Min.",
|
|
537
|
+
"count.other": "{n} Entscheidungen · {m} Min.",
|
|
538
|
+
empty: "Heute nichts zu erledigen.",
|
|
539
|
+
"g.late": "Überfällig",
|
|
540
|
+
"g.beforePayday": "Vor dem nächsten Lohn zu bezahlen",
|
|
541
|
+
"g.toConfirm": "Ohne Datum oder zu bestätigen",
|
|
542
|
+
"g.toPlan": "Zu planen",
|
|
543
|
+
overdue: "{label} · überfällig seit {date}",
|
|
544
|
+
dueToday: "{label} · heute fällig",
|
|
545
|
+
beforePayday: "{label} · vor dem Lohn fällig · {date}",
|
|
546
|
+
undated: "{label} · Datum zu bestätigen",
|
|
547
|
+
markPaid: "Als bezahlt markieren",
|
|
548
|
+
planOn: "Auf {date} planen",
|
|
549
|
+
plan: "{label} · {amount} bis {date}",
|
|
550
|
+
planBody: "Nach dem Lohn fällig: vorher ist nichts zu tun, planen Sie sie im nächsten Zyklus ein.",
|
|
551
|
+
review: "{label} · zu prüfen",
|
|
552
|
+
reviewTx: "Transaktion vom {date} · {amount}",
|
|
553
|
+
reviewOb: "Fälligkeit vom {date} · {amount}",
|
|
554
|
+
confidence: "Sicherheit {p} %",
|
|
555
|
+
internal: "Interne Überweisung",
|
|
556
|
+
expense: "Ausgabe",
|
|
557
|
+
accept: "Bestätigen",
|
|
558
|
+
cancel: "Stornieren",
|
|
559
|
+
"missing.one": "{n} wiederkehrender Posten ohne Betrag",
|
|
560
|
+
"missing.other": "{n} wiederkehrende Posten ohne Betrag",
|
|
561
|
+
missingBody: "{items} · der Spielraum stimmt erst, wenn sie erfasst sind",
|
|
562
|
+
complete: "Ergänzen"
|
|
563
|
+
},
|
|
564
|
+
it: {
|
|
565
|
+
title: "Da fare",
|
|
566
|
+
"count.one": "{n} decisione · {m} min",
|
|
567
|
+
"count.other": "{n} decisioni · {m} min",
|
|
568
|
+
empty: "Niente da fare oggi.",
|
|
569
|
+
"g.late": "In ritardo",
|
|
570
|
+
"g.beforePayday": "Da pagare prima del prossimo stipendio",
|
|
571
|
+
"g.toConfirm": "Senza data o da confermare",
|
|
572
|
+
"g.toPlan": "Da pianificare",
|
|
573
|
+
overdue: "{label} · scaduto dal {date}",
|
|
574
|
+
dueToday: "{label} · scade oggi",
|
|
575
|
+
beforePayday: "{label} · da pagare prima dello stipendio · {date}",
|
|
576
|
+
undated: "{label} · data da confermare",
|
|
577
|
+
markPaid: "Segna come pagato",
|
|
578
|
+
planOn: "Pianifica il {date}",
|
|
579
|
+
plan: "{label} · {amount} entro il {date}",
|
|
580
|
+
planBody: "Scade dopo lo stipendio: niente da fare prima, la preveda nel prossimo ciclo.",
|
|
581
|
+
review: "{label} · da verificare",
|
|
582
|
+
reviewTx: "Transazione del {date} · {amount}",
|
|
583
|
+
reviewOb: "Scadenza del {date} · {amount}",
|
|
584
|
+
confidence: "affidabilità {p} %",
|
|
585
|
+
internal: "Trasferimento interno",
|
|
586
|
+
expense: "Spesa",
|
|
587
|
+
accept: "Conferma",
|
|
588
|
+
cancel: "Annulla",
|
|
589
|
+
"missing.one": "{n} ricorrenza senza importo",
|
|
590
|
+
"missing.other": "{n} ricorrenze senza importo",
|
|
591
|
+
missingBody: "{items} · il margine finale è sbagliato finché mancano",
|
|
592
|
+
complete: "Completa"
|
|
593
|
+
},
|
|
594
|
+
rm: {
|
|
595
|
+
title: "Da far",
|
|
596
|
+
"count.one": "{n} decisiun · {m} min",
|
|
597
|
+
"count.other": "{n} decisiuns · {m} min",
|
|
598
|
+
empty: "Oz nagut da far.",
|
|
599
|
+
"g.late": "Retardà",
|
|
600
|
+
"g.beforePayday": "Da pajar avant il proxim salari",
|
|
601
|
+
"g.toConfirm": "Senza data u da confermar",
|
|
602
|
+
"g.toPlan": "Da planisar",
|
|
603
|
+
overdue: "{label} · scadì dapi ils {date}",
|
|
604
|
+
dueToday: "{label} · scada oz",
|
|
605
|
+
beforePayday: "{label} · da pajar avant il salari · {date}",
|
|
606
|
+
undated: "{label} · data da confermar",
|
|
607
|
+
markPaid: "Marcar sco pajà",
|
|
608
|
+
planOn: "Planisar ils {date}",
|
|
609
|
+
plan: "{label} · {amount} fin ils {date}",
|
|
610
|
+
planBody: "Scadenza suenter il salari: nagut da far avant, planisai ella en il proxim ciclus.",
|
|
611
|
+
review: "{label} · da controllar",
|
|
612
|
+
reviewTx: "Transacziun dals {date} · {amount}",
|
|
613
|
+
reviewOb: "Termin dals {date} · {amount}",
|
|
614
|
+
confidence: "fidanza {p} %",
|
|
615
|
+
internal: "Transfer intern",
|
|
616
|
+
expense: "Expensa",
|
|
617
|
+
accept: "Confermar",
|
|
618
|
+
cancel: "Annullar",
|
|
619
|
+
"missing.one": "{n} repetiziun senza summa",
|
|
620
|
+
"missing.other": "{n} repetiziuns senza summa",
|
|
621
|
+
missingBody: "{items} · il margin final è fauss uschè ditg ch’ellas mancan",
|
|
622
|
+
complete: "Cumplettar"
|
|
623
|
+
},
|
|
624
|
+
en: {
|
|
625
|
+
title: "To do",
|
|
626
|
+
"count.one": "{n} decision · {m} min",
|
|
627
|
+
"count.other": "{n} decisions · {m} min",
|
|
628
|
+
empty: "Nothing to do today.",
|
|
629
|
+
"g.late": "Overdue",
|
|
630
|
+
"g.beforePayday": "Due before next payday",
|
|
631
|
+
"g.toConfirm": "No date or to confirm",
|
|
632
|
+
"g.toPlan": "To schedule",
|
|
633
|
+
overdue: "{label} · overdue since {date}",
|
|
634
|
+
dueToday: "{label} · due today",
|
|
635
|
+
beforePayday: "{label} · due before payday · {date}",
|
|
636
|
+
undated: "{label} · date to confirm",
|
|
637
|
+
markPaid: "Mark paid",
|
|
638
|
+
planOn: "Schedule on {date}",
|
|
639
|
+
plan: "{label} · {amount} by {date}",
|
|
640
|
+
planBody: "Due after payday: nothing to do before then, plan it in the next cycle.",
|
|
641
|
+
review: "{label} · to review",
|
|
642
|
+
reviewTx: "Transaction on {date} · {amount}",
|
|
643
|
+
reviewOb: "Bill due {date} · {amount}",
|
|
644
|
+
confidence: "confidence {p}%",
|
|
645
|
+
internal: "Internal transfer",
|
|
646
|
+
expense: "Expense",
|
|
647
|
+
accept: "Confirm",
|
|
648
|
+
cancel: "Cancel",
|
|
649
|
+
"missing.one": "{n} recurring item without an amount",
|
|
650
|
+
"missing.other": "{n} recurring items without an amount",
|
|
651
|
+
missingBody: "{items} · the final margin is wrong until they are filled in",
|
|
652
|
+
complete: "Fill in"
|
|
653
|
+
}
|
|
654
|
+
},
|
|
655
|
+
select: (e) => ({
|
|
656
|
+
groups: we.map((n) => ({ key: n.key, items: e.actions.filter(n.accepts) })).filter((n) => n.items.length > 0),
|
|
657
|
+
count: e.actions.length,
|
|
658
|
+
currency: e.base_currency,
|
|
659
|
+
payday: e.next_income_date
|
|
660
|
+
}),
|
|
661
|
+
View: ({ model: e, t: n, fmt: a, onAction: i }) => /* @__PURE__ */ d(P, { question: n("question"), title: n("title"), meta: e.count > 0 ? n("count", { n: e.count, m: Math.max(1, Math.ceil(e.count / 2)) }) : void 0, children: [
|
|
662
|
+
e.count === 0 && /* @__PURE__ */ r(j, { children: n("empty") }),
|
|
663
|
+
e.groups.map((o) => /* @__PURE__ */ d("div", { className: "bz-group", children: [
|
|
664
|
+
/* @__PURE__ */ d("h3", { className: "bz-group-title", children: [
|
|
665
|
+
n(`g.${o.key}`),
|
|
666
|
+
" ",
|
|
667
|
+
/* @__PURE__ */ r("span", { children: o.items.length })
|
|
668
|
+
] }),
|
|
669
|
+
o.items.map((t, s) => /* @__PURE__ */ r(_e, { a: t, currency: e.currency, payday: e.payday, t: n, fmt: a, onAction: i }, `${t.type}-${"ref_id" in t ? t.ref_id : s}`))
|
|
670
|
+
] }, o.key))
|
|
671
|
+
] })
|
|
672
|
+
};
|
|
673
|
+
function _e({ a: e, currency: n, payday: a, t: i, fmt: o, onAction: t }) {
|
|
674
|
+
if (e.type === "missing_amounts")
|
|
675
|
+
return /* @__PURE__ */ d("div", { className: "bz-row bz-action", children: [
|
|
676
|
+
/* @__PURE__ */ r(R, { tone: "warn" }),
|
|
677
|
+
/* @__PURE__ */ d("div", { className: "bz-row-body", children: [
|
|
678
|
+
/* @__PURE__ */ r("strong", { children: i("missing", { n: e.items.length }) }),
|
|
679
|
+
/* @__PURE__ */ r("span", { children: i("missingBody", { items: e.items.join(", ") }) })
|
|
680
|
+
] }),
|
|
681
|
+
/* @__PURE__ */ r(x, { onClick: () => t({ type: "open", target: "recurrences" }), children: i("complete") })
|
|
682
|
+
] });
|
|
683
|
+
const s = e.confidence ? ` · ${i("confidence", { p: o.num(y(e.confidence) * 100) })}` : "";
|
|
684
|
+
if (e.type === "needs_review") {
|
|
685
|
+
const l = e.kind === "transaction";
|
|
686
|
+
return /* @__PURE__ */ d("div", { className: "bz-row bz-action", children: [
|
|
687
|
+
/* @__PURE__ */ r(R, { tone: "warn" }),
|
|
688
|
+
/* @__PURE__ */ d("div", { className: "bz-row-body", children: [
|
|
689
|
+
/* @__PURE__ */ r("strong", { children: i("review", { label: e.label }) }),
|
|
690
|
+
/* @__PURE__ */ d("span", { children: [
|
|
691
|
+
i(l ? "reviewTx" : "reviewOb", { date: o.shortDate(e.date), amount: o.money(e.amount, e.currency) }),
|
|
692
|
+
s
|
|
693
|
+
] })
|
|
694
|
+
] }),
|
|
695
|
+
l ? /* @__PURE__ */ d(M, { children: [
|
|
696
|
+
/* @__PURE__ */ r(x, { onClick: () => t({ type: "classify_transaction", ref_id: e.ref_id, internal_transfer: !0 }), children: i("internal") }),
|
|
697
|
+
/* @__PURE__ */ r(x, { onClick: () => t({ type: "classify_transaction", ref_id: e.ref_id, internal_transfer: !1 }), children: i("expense") })
|
|
698
|
+
] }) : /* @__PURE__ */ d(M, { children: [
|
|
699
|
+
/* @__PURE__ */ r(x, { onClick: () => t({ type: "review_obligation", ref_id: e.ref_id, decision: "accept" }), children: i("accept") }),
|
|
700
|
+
/* @__PURE__ */ r(x, { variant: "ghost", onClick: () => t({ type: "review_obligation", ref_id: e.ref_id, decision: "cancel" }), children: i("cancel") })
|
|
701
|
+
] })
|
|
702
|
+
] });
|
|
703
|
+
}
|
|
704
|
+
return /* @__PURE__ */ r(ke, { a: e, currency: n, payday: a, conf: s, t: i, fmt: o, onAction: t });
|
|
705
|
+
}
|
|
706
|
+
function ke({ a: e, currency: n, payday: a, conf: i, t: o, fmt: t, onAction: s }) {
|
|
707
|
+
const l = e.currency === n ? t.money(e.amount, e.currency) : `${t.money(e.amount, e.currency)} · ${t.num(e.amount_base)} ${n}`, c = t.shortDate(e.date), f = e.type === "overdue" ? o("overdue", { label: e.label, date: c }) : e.type === "due_today" ? o("dueToday", { label: e.label }) : e.type === "before_income" ? o("beforePayday", { label: e.label, date: c }) : e.type === "undated" ? o("undated", { label: e.label }) : o("plan", { label: e.label, amount: t.money(e.amount, e.currency), date: c }), v = e.type === "plan" ? e.description || o("planBody") : [l, e.description].filter(Boolean).join(" · "), _ = (e.type === "overdue" || e.type === "due_today") && a && e.date && a > e.date ? a : null, m = e.type === "overdue" || e.type === "due_today" ? "danger" : e.type === "plan" ? "muted" : "warn";
|
|
708
|
+
return /* @__PURE__ */ d("div", { className: "bz-row bz-action", children: [
|
|
709
|
+
/* @__PURE__ */ r(R, { tone: m }),
|
|
710
|
+
/* @__PURE__ */ d("div", { className: "bz-row-body", children: [
|
|
711
|
+
/* @__PURE__ */ r("strong", { children: f }),
|
|
712
|
+
/* @__PURE__ */ d("span", { children: [
|
|
713
|
+
v,
|
|
714
|
+
i
|
|
715
|
+
] })
|
|
716
|
+
] }),
|
|
717
|
+
_ && /* @__PURE__ */ r(x, { onClick: () => s({ type: "reschedule", ref_id: e.ref_id, date: _ }), children: o("planOn", { date: t.shortDate(_) }) }),
|
|
718
|
+
/* @__PURE__ */ r(x, { variant: e.type === "overdue" || e.type === "due_today" ? "primary" : "secondary", onClick: () => s({ type: "mark_paid", ref_id: e.ref_id }), children: o("markPaid") })
|
|
719
|
+
] });
|
|
720
|
+
}
|
|
721
|
+
const Ne = {
|
|
722
|
+
id: "pay-cycles",
|
|
723
|
+
size: "full",
|
|
724
|
+
question: {
|
|
725
|
+
fr: "Qu’est-ce qui tombe à chaque salaire ?",
|
|
726
|
+
de: "Was fällt in jeder Lohnperiode an?",
|
|
727
|
+
it: "Cosa scade in ogni periodo di paga?",
|
|
728
|
+
rm: "Tge croda en mintga perioda da salari?",
|
|
729
|
+
en: "What falls due each pay cycle?"
|
|
730
|
+
},
|
|
731
|
+
reads: ["cycles", "events", "next_income_date", "horizon_end", "as_of", "data_quality", "base_currency"],
|
|
732
|
+
messages: {
|
|
733
|
+
fr: { title: "Échéances par cycle de paie", sub: "{n} sorties · {cur} équivalent, devise d’origine entre parenthèses", all: "Toutes les échéances →", compact: "Vue condensée ←", before: "Avant le revenu du {date}", cycle: "Cycle {from} → {to}", until: "au {date}", "group.one": "{n} échéance · déplier", "group.other": "{n} échéances · déplier", paid: "Payé", recurring: "récurrence", "missing.one": "{n} récurrence sans montant", "missing.other": "{n} récurrences sans montant", toEnter: "à saisir", empty: "Aucune sortie." },
|
|
734
|
+
de: { title: "Fälligkeiten pro Lohnperiode", sub: "{n} Ausgaben · {cur}-Gegenwert, Originalwährung in Klammern", all: "Alle Fälligkeiten →", compact: "Kompakte Ansicht ←", before: "Vor dem Einkommen am {date}", cycle: "Periode {from} → {to}", until: "bis {date}", "group.one": "{n} Fälligkeit · aufklappen", "group.other": "{n} Fälligkeiten · aufklappen", paid: "Bezahlt", recurring: "wiederkehrend", "missing.one": "{n} wiederkehrender Posten ohne Betrag", "missing.other": "{n} wiederkehrende Posten ohne Betrag", toEnter: "erfassen", empty: "Keine Ausgaben." },
|
|
735
|
+
it: { title: "Scadenze per periodo di paga", sub: "{n} uscite · equivalente {cur}, valuta originale tra parentesi", all: "Tutte le scadenze →", compact: "Vista compatta ←", before: "Prima del reddito del {date}", cycle: "Periodo {from} → {to}", until: "al {date}", "group.one": "{n} scadenza · espandi", "group.other": "{n} scadenze · espandi", paid: "Pagato", recurring: "ricorrente", "missing.one": "{n} ricorrenza senza importo", "missing.other": "{n} ricorrenze senza importo", toEnter: "da inserire", empty: "Nessuna uscita." },
|
|
736
|
+
rm: { title: "Termins per perioda da salari", sub: "{n} sortidas · equivalent {cur}, valuta originala tranter parentesas", all: "Tut ils termins →", compact: "Vista cumpacta ←", before: "Avant il salari dals {date}", cycle: "Perioda {from} → {to}", until: "fin ils {date}", "group.one": "{n} termin · extender", "group.other": "{n} termins · extender", paid: "Pajà", recurring: "repetitiv", "missing.one": "{n} repetiziun senza summa", "missing.other": "{n} repetiziuns senza summa", toEnter: "endatar", empty: "Naginas sortidas." },
|
|
737
|
+
en: { title: "Bills by pay cycle", sub: "{n} outflows · {cur} equivalent, original currency in brackets", all: "All bills →", compact: "Compact view ←", before: "Before the {date} income", cycle: "Cycle {from} → {to}", until: "to {date}", "group.one": "{n} bill · expand", "group.other": "{n} bills · expand", paid: "Paid", recurring: "recurring", "missing.one": "{n} recurring item without an amount", "missing.other": "{n} recurring items without an amount", toEnter: "to enter", empty: "No outflows." }
|
|
738
|
+
},
|
|
739
|
+
select: (e) => {
|
|
740
|
+
const n = e.cycles.length - 1;
|
|
741
|
+
return {
|
|
742
|
+
columns: e.cycles.map((a, i) => ({
|
|
743
|
+
key: a.key,
|
|
744
|
+
title: a.key === "before_income" ? { kind: "before", date: e.next_income_date ?? a.end } : { kind: "cycle", from: a.start, to: a.end },
|
|
745
|
+
totalOut: a.total_out,
|
|
746
|
+
totalIn: a.total_in,
|
|
747
|
+
truncated: i === n && a.end === e.horizon_end && E(a.start, a.end) < 25 ? a.end : null,
|
|
748
|
+
cycle: a
|
|
749
|
+
})),
|
|
750
|
+
outflows: e.events.filter((a) => a.direction === "outflow").length,
|
|
751
|
+
currency: e.base_currency,
|
|
752
|
+
today: e.as_of,
|
|
753
|
+
missing: e.data_quality.rules_without_amount.length
|
|
754
|
+
};
|
|
755
|
+
},
|
|
756
|
+
View: ({ model: e, t: n, fmt: a, onAction: i }) => {
|
|
757
|
+
const [o, t] = L(!1);
|
|
758
|
+
return /* @__PURE__ */ r(
|
|
759
|
+
P,
|
|
760
|
+
{
|
|
761
|
+
question: n("question"),
|
|
762
|
+
title: n("title"),
|
|
763
|
+
meta: n("sub", { n: e.outflows, cur: e.currency }),
|
|
764
|
+
actions: /* @__PURE__ */ r(x, { variant: "link", onClick: () => t((s) => !s), children: n(o ? "compact" : "all") }),
|
|
765
|
+
children: /* @__PURE__ */ r("div", { className: "bz-cycles", children: e.columns.map((s, l) => /* @__PURE__ */ r(xe, { col: s, all: o, missing: l === e.columns.length - 1 ? e.missing : 0, currency: e.currency, today: e.today, t: n, fmt: a, onAction: i }, s.key)) })
|
|
766
|
+
}
|
|
767
|
+
);
|
|
768
|
+
}
|
|
769
|
+
};
|
|
770
|
+
function xe({ col: e, all: n, missing: a, currency: i, today: o, t, fmt: s, onAction: l }) {
|
|
771
|
+
const [c, f] = L(/* @__PURE__ */ new Set()), v = n ? e.cycle.items : e.cycle.items.filter((p) => p.direction === "outflow"), _ = n ? v.map((p) => ({ key: `${p.ref_id}-${p.date}`, items: [p] })) : Se(v), m = e.title.kind === "before" ? t("before", { date: s.shortDate(e.title.date) }) : t("cycle", { from: s.shortDate(e.title.from), to: s.shortDate(e.title.to) });
|
|
772
|
+
return /* @__PURE__ */ d("div", { className: "bz-cycle", children: [
|
|
773
|
+
/* @__PURE__ */ d("div", { className: "bz-cycle-head", children: [
|
|
774
|
+
/* @__PURE__ */ r("span", { children: m }),
|
|
775
|
+
/* @__PURE__ */ d("strong", { className: y(e.totalOut) > 0 ? "bz-neg" : "bz-muted", children: [
|
|
776
|
+
s.signed(-y(e.totalOut)),
|
|
777
|
+
n && y(e.totalIn) > 0 && /* @__PURE__ */ d("span", { className: "bz-pos", children: [
|
|
778
|
+
" ",
|
|
779
|
+
s.signed(e.totalIn)
|
|
780
|
+
] }),
|
|
781
|
+
e.truncated && /* @__PURE__ */ d("span", { className: "bz-muted", children: [
|
|
782
|
+
" ",
|
|
783
|
+
t("until", { date: s.shortDate(e.truncated) })
|
|
784
|
+
] })
|
|
785
|
+
] })
|
|
786
|
+
] }),
|
|
787
|
+
_.map((p) => {
|
|
788
|
+
if (p.items.length === 1 || c.has(p.key))
|
|
789
|
+
return p.items.map((g) => /* @__PURE__ */ r(De, { e: g, currency: i, today: o, t, fmt: s, onAction: l }, `${g.ref_id}-${g.date}-${g.label}`));
|
|
790
|
+
const b = p.items[0], w = p.items[p.items.length - 1];
|
|
791
|
+
return /* @__PURE__ */ d("button", { type: "button", className: "bz-row bz-row-button", onClick: () => f((g) => new Set(g).add(p.key)), children: [
|
|
792
|
+
/* @__PURE__ */ r("span", { className: "bz-date", children: s.dateSpan(b.date, w.date) }),
|
|
793
|
+
/* @__PURE__ */ d("div", { className: "bz-row-body bz-wrap", children: [
|
|
794
|
+
/* @__PURE__ */ r("strong", { children: p.items.map((g) => Te(g.label)).join(", ") }),
|
|
795
|
+
/* @__PURE__ */ r("span", { children: t("group", { n: p.items.length }) })
|
|
796
|
+
] }),
|
|
797
|
+
/* @__PURE__ */ r("strong", { className: "bz-amount", children: s.num(p.items.reduce((g, D) => g + y(D.amount), 0)) })
|
|
798
|
+
] }, p.key);
|
|
799
|
+
}),
|
|
800
|
+
v.length === 0 && /* @__PURE__ */ r(j, { children: t("empty") }),
|
|
801
|
+
a > 0 && /* @__PURE__ */ d("button", { type: "button", className: "bz-row bz-row-button bz-warn-row", onClick: () => l({ type: "open", target: "recurrences" }), children: [
|
|
802
|
+
/* @__PURE__ */ r("span", { className: "bz-date", children: "?" }),
|
|
803
|
+
/* @__PURE__ */ r("div", { className: "bz-row-body bz-wrap", children: /* @__PURE__ */ r("strong", { children: t("missing", { n: a }) }) }),
|
|
804
|
+
/* @__PURE__ */ r("strong", { className: "bz-amount", children: t("toEnter") })
|
|
805
|
+
] })
|
|
806
|
+
] });
|
|
807
|
+
}
|
|
808
|
+
function De({ e, currency: n, today: a, t: i, fmt: o, onAction: t }) {
|
|
809
|
+
const s = e.date < a || e.status === "overdue", l = e.currency !== n, c = e.kind === "obligation" && e.ref_id && E(a, e.date) <= 0;
|
|
810
|
+
return /* @__PURE__ */ d("div", { className: `bz-row${s ? " bz-late" : ""}`, children: [
|
|
811
|
+
/* @__PURE__ */ r("span", { className: "bz-date", children: o.shortDate(e.date) }),
|
|
812
|
+
/* @__PURE__ */ d("div", { className: "bz-row-body", children: [
|
|
813
|
+
/* @__PURE__ */ d("strong", { children: [
|
|
814
|
+
e.direction === "inflow" ? "+ " : "",
|
|
815
|
+
e.label
|
|
816
|
+
] }),
|
|
817
|
+
l && /* @__PURE__ */ d("span", { children: [
|
|
818
|
+
"(",
|
|
819
|
+
o.money(e.original_amount, e.currency),
|
|
820
|
+
")"
|
|
821
|
+
] }),
|
|
822
|
+
!l && e.kind === "recurrence" && /* @__PURE__ */ r("span", { children: i("recurring") })
|
|
823
|
+
] }),
|
|
824
|
+
/* @__PURE__ */ r("strong", { className: `bz-amount${e.direction === "inflow" ? " bz-pos" : ""}`, children: o.num(e.amount) }),
|
|
825
|
+
c && /* @__PURE__ */ r(x, { variant: "ghost", onClick: () => t({ type: "mark_paid", ref_id: e.ref_id }), children: i("paid") })
|
|
826
|
+
] });
|
|
827
|
+
}
|
|
828
|
+
function Se(e) {
|
|
829
|
+
const n = [...e].sort((l, c) => l.date.localeCompare(c.date) || y(c.amount) - y(l.amount)), a = n.reduce((l, c) => l + y(c.amount), 0), i = (l) => y(l.amount) >= Math.max(400, a * 0.08) || l.status === "overdue", o = [];
|
|
830
|
+
let t = [];
|
|
831
|
+
const s = () => {
|
|
832
|
+
const l = t[0], c = t[t.length - 1];
|
|
833
|
+
l && c && o.push({ key: `${l.date}-${c.date}-${t.length}`, items: t }), t = [];
|
|
834
|
+
};
|
|
835
|
+
for (const l of n) {
|
|
836
|
+
if (i(l)) {
|
|
837
|
+
s(), o.push({ key: `${l.ref_id}-${l.date}`, items: [l] });
|
|
838
|
+
continue;
|
|
839
|
+
}
|
|
840
|
+
const c = t[0];
|
|
841
|
+
c && (E(c.date, l.date) > 7 || t.length >= 4) && s(), t.push(l);
|
|
842
|
+
}
|
|
843
|
+
return s(), o;
|
|
844
|
+
}
|
|
845
|
+
function Te(e) {
|
|
846
|
+
if (e.length <= 18) return e;
|
|
847
|
+
let n = "";
|
|
848
|
+
for (const a of e.split(/\s+/)) {
|
|
849
|
+
const i = n ? `${n} ${a}` : a;
|
|
850
|
+
if (i.length > 18) break;
|
|
851
|
+
n = i;
|
|
852
|
+
}
|
|
853
|
+
return n || e.slice(0, 18);
|
|
854
|
+
}
|
|
855
|
+
const qe = ["7", "30", "cycles", "90"], Me = {
|
|
856
|
+
id: "what-if",
|
|
857
|
+
size: "full",
|
|
858
|
+
question: {
|
|
859
|
+
fr: "Et si je décale un paiement ?",
|
|
860
|
+
de: "Und wenn ich eine Zahlung verschiebe?",
|
|
861
|
+
it: "E se sposto un pagamento?",
|
|
862
|
+
rm: "E sche jau spustel in pajament?",
|
|
863
|
+
en: "What if I move a payment?"
|
|
864
|
+
},
|
|
865
|
+
reads: ["points", "events", "main_cycle", "low_point", "end_of_horizon", "next_income_date", "second_income_date", "as_of", "horizon_end", "opening_balance", "base_currency"],
|
|
866
|
+
messages: {
|
|
867
|
+
fr: {
|
|
868
|
+
title: "Trésorerie prévisionnelle",
|
|
869
|
+
span: "{from} → {to} · {cur} équivalent",
|
|
870
|
+
horizon: "Horizon",
|
|
871
|
+
"h.7": "7J",
|
|
872
|
+
"h.30": "30J",
|
|
873
|
+
"h.cycles": "2 salaires",
|
|
874
|
+
"h.90": "90J",
|
|
875
|
+
base: "Base",
|
|
876
|
+
scenario: "Scénario : {name}",
|
|
877
|
+
overdraft: "Découvert",
|
|
878
|
+
aria: "Trésorerie du {from} au {to}, point bas {low} le {date}",
|
|
879
|
+
why: "Pourquoi {low} le {date} ?",
|
|
880
|
+
whyBody: "Entre le {start} et le {end}, {out} {cur} sortent pour {in} entrés.",
|
|
881
|
+
"drivers.one": "{n} poste fait {share} % des sorties :",
|
|
882
|
+
"drivers.other": "{n} postes font {share} % des sorties :",
|
|
883
|
+
levers: "Leviers",
|
|
884
|
+
split: "{label} en 2 tranches ({a} / {b})",
|
|
885
|
+
defer: "Reporter {label} au {date}",
|
|
886
|
+
reserve: "Garder {amount} de réserve après le {date}",
|
|
887
|
+
effectLow: "Point bas {from} → {to}",
|
|
888
|
+
effectEnd: "Marge {date} {from} → {to}",
|
|
889
|
+
effectSafe: "Aucun jour sous zéro jusqu’au {date}",
|
|
890
|
+
result: "Scénario : point bas {low} le {date}, marge finale {end}.",
|
|
891
|
+
save: "Enregistrer comme scénario →",
|
|
892
|
+
noOut: "Aucune sortie prévue."
|
|
893
|
+
},
|
|
894
|
+
de: {
|
|
895
|
+
title: "Liquiditätsprognose",
|
|
896
|
+
span: "{from} → {to} · {cur}-Gegenwert",
|
|
897
|
+
horizon: "Zeitraum",
|
|
898
|
+
"h.7": "7T",
|
|
899
|
+
"h.30": "30T",
|
|
900
|
+
"h.cycles": "2 Löhne",
|
|
901
|
+
"h.90": "90T",
|
|
902
|
+
base: "Basis",
|
|
903
|
+
scenario: "Szenario: {name}",
|
|
904
|
+
overdraft: "Überzug",
|
|
905
|
+
aria: "Liquidität vom {from} bis {to}, Tiefpunkt {low} am {date}",
|
|
906
|
+
why: "Warum {low} am {date}?",
|
|
907
|
+
whyBody: "Zwischen {start} und {end} gehen {out} {cur} hinaus und {in} herein.",
|
|
908
|
+
"drivers.one": "{n} Posten macht {share} % der Ausgaben aus:",
|
|
909
|
+
"drivers.other": "{n} Posten machen {share} % der Ausgaben aus:",
|
|
910
|
+
levers: "Hebel",
|
|
911
|
+
split: "{label} in 2 Raten ({a} / {b})",
|
|
912
|
+
defer: "{label} auf {date} verschieben",
|
|
913
|
+
reserve: "{amount} Reserve nach dem {date} behalten",
|
|
914
|
+
effectLow: "Tiefpunkt {from} → {to}",
|
|
915
|
+
effectEnd: "Spielraum {date} {from} → {to}",
|
|
916
|
+
effectSafe: "Kein Tag unter null bis {date}",
|
|
917
|
+
result: "Szenario: Tiefpunkt {low} am {date}, Spielraum am Ende {end}.",
|
|
918
|
+
save: "Als Szenario speichern →",
|
|
919
|
+
noOut: "Keine Ausgaben geplant."
|
|
920
|
+
},
|
|
921
|
+
it: {
|
|
922
|
+
title: "Previsione di liquidità",
|
|
923
|
+
span: "{from} → {to} · equivalente {cur}",
|
|
924
|
+
horizon: "Orizzonte",
|
|
925
|
+
"h.7": "7G",
|
|
926
|
+
"h.30": "30G",
|
|
927
|
+
"h.cycles": "2 stipendi",
|
|
928
|
+
"h.90": "90G",
|
|
929
|
+
base: "Base",
|
|
930
|
+
scenario: "Scenario: {name}",
|
|
931
|
+
overdraft: "Scoperto",
|
|
932
|
+
aria: "Liquidità dal {from} al {to}, minimo {low} il {date}",
|
|
933
|
+
why: "Perché {low} il {date}?",
|
|
934
|
+
whyBody: "Tra il {start} e il {end} escono {out} {cur} ed entrano {in}.",
|
|
935
|
+
"drivers.one": "{n} voce fa il {share} % delle uscite:",
|
|
936
|
+
"drivers.other": "{n} voci fanno il {share} % delle uscite:",
|
|
937
|
+
levers: "Leve",
|
|
938
|
+
split: "{label} in 2 rate ({a} / {b})",
|
|
939
|
+
defer: "Rinviare {label} al {date}",
|
|
940
|
+
reserve: "Tenere {amount} di riserva dopo il {date}",
|
|
941
|
+
effectLow: "Minimo {from} → {to}",
|
|
942
|
+
effectEnd: "Margine {date} {from} → {to}",
|
|
943
|
+
effectSafe: "Nessun giorno sotto zero fino al {date}",
|
|
944
|
+
result: "Scenario: minimo {low} il {date}, margine finale {end}.",
|
|
945
|
+
save: "Salva come scenario →",
|
|
946
|
+
noOut: "Nessuna uscita prevista."
|
|
947
|
+
},
|
|
948
|
+
rm: {
|
|
949
|
+
title: "Prognosa da liquiditad",
|
|
950
|
+
span: "{from} → {to} · equivalent {cur}",
|
|
951
|
+
horizon: "Orizont",
|
|
952
|
+
"h.7": "7D",
|
|
953
|
+
"h.30": "30D",
|
|
954
|
+
"h.cycles": "2 salaris",
|
|
955
|
+
"h.90": "90D",
|
|
956
|
+
base: "Basa",
|
|
957
|
+
scenario: "Scenari: {name}",
|
|
958
|
+
overdraft: "Surtratga",
|
|
959
|
+
aria: "Liquiditad dals {from} fin ils {to}, punct bass {low} ils {date}",
|
|
960
|
+
why: "Pertge {low} ils {date}?",
|
|
961
|
+
whyBody: "Tranter ils {start} ed ils {end} sortan {out} {cur} ed entran {in}.",
|
|
962
|
+
"drivers.one": "{n} post fa {share} % da las sortidas:",
|
|
963
|
+
"drivers.other": "{n} posts fan {share} % da las sortidas:",
|
|
964
|
+
levers: "Levas",
|
|
965
|
+
split: "{label} en 2 ratas ({a} / {b})",
|
|
966
|
+
defer: "Spustar {label} sin ils {date}",
|
|
967
|
+
reserve: "Tegnair {amount} reserva suenter ils {date}",
|
|
968
|
+
effectLow: "Punct bass {from} → {to}",
|
|
969
|
+
effectEnd: "Margin {date} {from} → {to}",
|
|
970
|
+
effectSafe: "Nagin di sut nulla fin ils {date}",
|
|
971
|
+
result: "Scenari: punct bass {low} ils {date}, margin final {end}.",
|
|
972
|
+
save: "Memorisar sco scenari →",
|
|
973
|
+
noOut: "Naginas sortidas previsas."
|
|
974
|
+
},
|
|
975
|
+
en: {
|
|
976
|
+
title: "Cash-flow forecast",
|
|
977
|
+
span: "{from} → {to} · {cur} equivalent",
|
|
978
|
+
horizon: "Horizon",
|
|
979
|
+
"h.7": "7D",
|
|
980
|
+
"h.30": "30D",
|
|
981
|
+
"h.cycles": "2 paydays",
|
|
982
|
+
"h.90": "90D",
|
|
983
|
+
base: "Baseline",
|
|
984
|
+
scenario: "Scenario: {name}",
|
|
985
|
+
overdraft: "Overdraft",
|
|
986
|
+
aria: "Cash from {from} to {to}, low point {low} on {date}",
|
|
987
|
+
why: "Why {low} on {date}?",
|
|
988
|
+
whyBody: "Between {start} and {end}, {out} {cur} goes out and {in} comes in.",
|
|
989
|
+
"drivers.one": "{n} item makes up {share}% of outflows:",
|
|
990
|
+
"drivers.other": "{n} items make up {share}% of outflows:",
|
|
991
|
+
levers: "Levers",
|
|
992
|
+
split: "{label} in 2 instalments ({a} / {b})",
|
|
993
|
+
defer: "Move {label} to {date}",
|
|
994
|
+
reserve: "Keep {amount} in reserve after {date}",
|
|
995
|
+
effectLow: "Low point {from} → {to}",
|
|
996
|
+
effectEnd: "Margin {date} {from} → {to}",
|
|
997
|
+
effectSafe: "No day below zero until {date}",
|
|
998
|
+
result: "Scenario: low point {low} on {date}, final margin {end}.",
|
|
999
|
+
save: "Save as scenario →",
|
|
1000
|
+
noOut: "No outflows planned."
|
|
1001
|
+
}
|
|
1002
|
+
},
|
|
1003
|
+
select: (e) => e.points.length > 0 ? { snapshot: e } : null,
|
|
1004
|
+
View: ({ model: e, t: n, fmt: a, ctx: i, onAction: o }) => {
|
|
1005
|
+
const t = e.snapshot, s = t.base_currency, l = q(() => he(t), [t]), c = q(() => me(t), [t]), f = W(!1), [v, _] = L(/* @__PURE__ */ new Set());
|
|
1006
|
+
X(() => {
|
|
1007
|
+
f.current || _(c[0] ? /* @__PURE__ */ new Set([c[0].id]) : /* @__PURE__ */ new Set());
|
|
1008
|
+
}, [c]);
|
|
1009
|
+
const m = q(() => v.size > 0 ? U(t, v, c) : null, [t, v, c]), p = c.filter((h) => v.has(h.id)), b = (h) => Pe(h, n, a.num, a.shortDate), w = t.main_cycle.drivers, g = w.reduce((h, k) => h + y(k.share), 0), D = $e(t, a.num);
|
|
1010
|
+
return /* @__PURE__ */ d("div", { className: "bz-split", children: [
|
|
1011
|
+
/* @__PURE__ */ d(
|
|
1012
|
+
P,
|
|
1013
|
+
{
|
|
1014
|
+
className: "bz-span-2",
|
|
1015
|
+
question: n("question"),
|
|
1016
|
+
title: n("title"),
|
|
1017
|
+
meta: n("span", { from: a.shortDate(t.as_of), to: a.shortDate(t.horizon_end), cur: s }),
|
|
1018
|
+
actions: /* @__PURE__ */ r(
|
|
1019
|
+
le,
|
|
1020
|
+
{
|
|
1021
|
+
label: n("horizon"),
|
|
1022
|
+
value: i.horizon,
|
|
1023
|
+
options: qe.map((h) => ({ key: h, label: n(`h.${h}`) })),
|
|
1024
|
+
onChange: (h) => o({ type: "set_horizon", horizon: h })
|
|
1025
|
+
}
|
|
1026
|
+
),
|
|
1027
|
+
children: [
|
|
1028
|
+
/* @__PURE__ */ r(
|
|
1029
|
+
ce,
|
|
1030
|
+
{
|
|
1031
|
+
base: l,
|
|
1032
|
+
scenario: m,
|
|
1033
|
+
today: t.as_of,
|
|
1034
|
+
incomes: [t.next_income_date, t.second_income_date].filter((h) => !!h),
|
|
1035
|
+
markers: D,
|
|
1036
|
+
labels: {
|
|
1037
|
+
today: n("today"),
|
|
1038
|
+
payday: (h) => n("payday", { date: h }),
|
|
1039
|
+
aria: n("aria", { from: a.shortDate(t.as_of), to: a.shortDate(t.horizon_end), low: a.num(l.low.balance), date: a.shortDate(l.low.date) })
|
|
1040
|
+
}
|
|
1041
|
+
}
|
|
1042
|
+
),
|
|
1043
|
+
/* @__PURE__ */ d("div", { className: "bz-legend", children: [
|
|
1044
|
+
/* @__PURE__ */ d("span", { children: [
|
|
1045
|
+
/* @__PURE__ */ r("i", { className: "bz-sw bz-sw-base" }),
|
|
1046
|
+
n("base")
|
|
1047
|
+
] }),
|
|
1048
|
+
m && /* @__PURE__ */ d("span", { children: [
|
|
1049
|
+
/* @__PURE__ */ r("i", { className: "bz-sw bz-sw-scenario" }),
|
|
1050
|
+
n("scenario", { name: p.map(b).join(" + ") })
|
|
1051
|
+
] }),
|
|
1052
|
+
/* @__PURE__ */ d("span", { children: [
|
|
1053
|
+
/* @__PURE__ */ r("i", { className: "bz-sw bz-sw-danger" }),
|
|
1054
|
+
n("overdraft")
|
|
1055
|
+
] })
|
|
1056
|
+
] })
|
|
1057
|
+
]
|
|
1058
|
+
}
|
|
1059
|
+
),
|
|
1060
|
+
/* @__PURE__ */ d(P, { title: n("why", { low: a.num(t.low_point.balance), date: a.shortDate(t.low_point.date) }), children: [
|
|
1061
|
+
/* @__PURE__ */ d("p", { className: "bz-body", children: [
|
|
1062
|
+
n("whyBody", { start: a.shortDate(t.main_cycle.start), end: a.shortDate(t.main_cycle.end), out: a.num(t.main_cycle.total_out), in: a.num(t.main_cycle.total_in), cur: s }),
|
|
1063
|
+
w.length > 0 && ` ${n("drivers", { n: w.length, share: a.num(g) })}`
|
|
1064
|
+
] }),
|
|
1065
|
+
/* @__PURE__ */ d("div", { className: "bz-bars", children: [
|
|
1066
|
+
w.map((h, k) => /* @__PURE__ */ d("div", { className: "bz-bar", children: [
|
|
1067
|
+
/* @__PURE__ */ r("i", { className: V[Math.min(k, 3)], style: { width: `${Math.max(6, y(h.share) * 2.4)}px` } }),
|
|
1068
|
+
/* @__PURE__ */ d("span", { children: [
|
|
1069
|
+
h.label,
|
|
1070
|
+
" ",
|
|
1071
|
+
/* @__PURE__ */ r("em", { children: a.shortDate(h.date) })
|
|
1072
|
+
] }),
|
|
1073
|
+
/* @__PURE__ */ r("strong", { children: a.num(h.amount) })
|
|
1074
|
+
] }, `${h.label}-${h.date}`)),
|
|
1075
|
+
w.length === 0 && /* @__PURE__ */ r("p", { className: "bz-empty", children: n("noOut") })
|
|
1076
|
+
] }),
|
|
1077
|
+
c.length > 0 && /* @__PURE__ */ d(M, { children: [
|
|
1078
|
+
/* @__PURE__ */ r("hr", { className: "bz-rule" }),
|
|
1079
|
+
/* @__PURE__ */ r("p", { className: "bz-eyebrow", children: n("levers") }),
|
|
1080
|
+
/* @__PURE__ */ r("div", { className: "bz-levers", children: c.map((h) => {
|
|
1081
|
+
const k = U(t, /* @__PURE__ */ new Set([h.id]), c), $ = v.has(h.id);
|
|
1082
|
+
return /* @__PURE__ */ d("label", { className: $ ? "bz-lever bz-on" : "bz-lever", children: [
|
|
1083
|
+
/* @__PURE__ */ r(
|
|
1084
|
+
"input",
|
|
1085
|
+
{
|
|
1086
|
+
type: "checkbox",
|
|
1087
|
+
checked: $,
|
|
1088
|
+
onChange: () => {
|
|
1089
|
+
f.current = !0, _((T) => {
|
|
1090
|
+
const S = new Set(T);
|
|
1091
|
+
return S.has(h.id) ? S.delete(h.id) : S.add(h.id), S;
|
|
1092
|
+
});
|
|
1093
|
+
}
|
|
1094
|
+
}
|
|
1095
|
+
),
|
|
1096
|
+
/* @__PURE__ */ d("span", { children: [
|
|
1097
|
+
/* @__PURE__ */ r("strong", { children: b(h) }),
|
|
1098
|
+
/* @__PURE__ */ r("em", { children: h.kind === "reserve" && k.low.balance >= 0 ? n("effectSafe", { date: a.shortDate(t.horizon_end) }) : k.low.balance === l.low.balance ? /* @__PURE__ */ d(M, { children: [
|
|
1099
|
+
n("effectEnd", { date: a.shortDate(t.horizon_end), from: a.signed(l.end.balance), to: "" }),
|
|
1100
|
+
/* @__PURE__ */ r("b", { className: `bz-${O(k.end.balance)}`, children: a.signed(k.end.balance) })
|
|
1101
|
+
] }) : /* @__PURE__ */ d(M, { children: [
|
|
1102
|
+
n("effectLow", { from: a.num(l.low.balance), to: "" }),
|
|
1103
|
+
/* @__PURE__ */ r("b", { className: `bz-${O(k.low.balance)}`, children: a.num(k.low.balance) })
|
|
1104
|
+
] }) })
|
|
1105
|
+
] })
|
|
1106
|
+
] }, h.id);
|
|
1107
|
+
}) }),
|
|
1108
|
+
m && /* @__PURE__ */ r("p", { className: "bz-note", children: n("result", { low: a.num(m.low.balance), date: a.shortDate(m.low.date), end: a.signed(m.end.balance) }) }),
|
|
1109
|
+
/* @__PURE__ */ r(
|
|
1110
|
+
x,
|
|
1111
|
+
{
|
|
1112
|
+
variant: "ghost",
|
|
1113
|
+
disabled: !m,
|
|
1114
|
+
onClick: () => m && o({
|
|
1115
|
+
type: "save_scenario",
|
|
1116
|
+
name: p.map(b).join(" + ").slice(0, 120),
|
|
1117
|
+
levers: p.map((h) => ({ id: h.id, kind: h.kind, label: b(h), ref_id: h.event.ref_id, target: h.target, amount: h.reserve ? String(h.reserve) : h.event.amount })),
|
|
1118
|
+
low_before: String(l.low.balance),
|
|
1119
|
+
low_after: String(m.low.balance)
|
|
1120
|
+
}),
|
|
1121
|
+
children: n("save")
|
|
1122
|
+
}
|
|
1123
|
+
)
|
|
1124
|
+
] })
|
|
1125
|
+
] })
|
|
1126
|
+
] });
|
|
1127
|
+
}
|
|
1128
|
+
};
|
|
1129
|
+
function Pe(e, n, a, i) {
|
|
1130
|
+
const o = y(e.event.amount);
|
|
1131
|
+
return e.kind === "split" ? n("split", { label: e.event.label, a: a(o / 2), b: a(o / 2) }) : e.kind === "reserve" ? n("reserve", { amount: a(e.reserve ?? 0), date: i(e.event.date) }) : n("defer", { label: e.event.label, date: i(e.target) });
|
|
1132
|
+
}
|
|
1133
|
+
function $e(e, n) {
|
|
1134
|
+
const a = /* @__PURE__ */ new Map();
|
|
1135
|
+
for (const i of e.main_cycle.drivers) {
|
|
1136
|
+
const o = a.get(i.date) ?? { labels: [], amount: 0 };
|
|
1137
|
+
o.labels.push(Ee(i.label)), o.amount += y(i.amount), a.set(i.date, o);
|
|
1138
|
+
}
|
|
1139
|
+
return [...a.entries()].slice(0, 3).map(([i, o]) => ({
|
|
1140
|
+
date: i,
|
|
1141
|
+
label: `${o.labels.length <= 2 ? o.labels.join(" + ") : `${o.labels[0]} +${o.labels.length - 1}`} −${n(o.amount)}`
|
|
1142
|
+
}));
|
|
1143
|
+
}
|
|
1144
|
+
function Ee(e) {
|
|
1145
|
+
if (e.length <= 18) return e;
|
|
1146
|
+
let n = "";
|
|
1147
|
+
for (const a of e.split(/\s+/)) {
|
|
1148
|
+
const i = n ? `${n} ${a}` : a;
|
|
1149
|
+
if (i.length > 18) break;
|
|
1150
|
+
n = i;
|
|
1151
|
+
}
|
|
1152
|
+
return n || e.slice(0, 18);
|
|
1153
|
+
}
|
|
1154
|
+
const Ce = [
|
|
1155
|
+
be,
|
|
1156
|
+
ge,
|
|
1157
|
+
fe,
|
|
1158
|
+
ye,
|
|
1159
|
+
Me,
|
|
1160
|
+
ze,
|
|
1161
|
+
ve,
|
|
1162
|
+
Ne
|
|
1163
|
+
];
|
|
1164
|
+
function Re(e) {
|
|
1165
|
+
return Ce.find((n) => n.id === e);
|
|
1166
|
+
}
|
|
1167
|
+
function Z({ module: e, snapshot: n, locale: a, horizon: i = "cycles", onAction: o = () => {
|
|
1168
|
+
} }) {
|
|
1169
|
+
const t = q(() => ({ locale: a, horizon: i }), [a, i]), s = q(
|
|
1170
|
+
() => ae(a, se, e.messages, {
|
|
1171
|
+
fr: { question: e.question.fr },
|
|
1172
|
+
de: { question: e.question.de },
|
|
1173
|
+
it: { question: e.question.it },
|
|
1174
|
+
rm: { question: e.question.rm },
|
|
1175
|
+
en: { question: e.question.en }
|
|
1176
|
+
}),
|
|
1177
|
+
[a, e]
|
|
1178
|
+
), l = q(() => te(a), [a]), c = q(() => e.select(n, t), [e, n, t]);
|
|
1179
|
+
if (c === null)
|
|
1180
|
+
return /* @__PURE__ */ r(P, { question: s("question"), children: /* @__PURE__ */ r(j, { children: s("notEnough") }) });
|
|
1181
|
+
const f = e.View;
|
|
1182
|
+
return /* @__PURE__ */ r(f, { model: c, t: s, fmt: l, ctx: t, onAction: o });
|
|
1183
|
+
}
|
|
1184
|
+
function Ve({ modules: e, theme: n = "dark", ...a }) {
|
|
1185
|
+
const i = e.filter((t) => t.size === "tile"), o = e.filter((t) => t.size !== "tile");
|
|
1186
|
+
return /* @__PURE__ */ d("div", { className: "bz", "data-theme": n, children: [
|
|
1187
|
+
i.length > 0 && /* @__PURE__ */ r("section", { className: "bz-tiles", children: i.map((t) => /* @__PURE__ */ r(Z, { module: t, ...a }, t.id)) }),
|
|
1188
|
+
/* @__PURE__ */ r("section", { className: "bz-grid", children: o.map((t) => /* @__PURE__ */ r("div", { className: `bz-slot bz-slot-${t.size}`, "data-module": t.id, children: /* @__PURE__ */ r(Z, { module: t, ...a }) }, t.id)) })
|
|
1189
|
+
] });
|
|
1190
|
+
}
|
|
1191
|
+
const Ae = (e) => Math.round(Math.min(Math.max(e || Q, re), Q));
|
|
1192
|
+
function Fe({ visual: e, locale: n, className: a }) {
|
|
1193
|
+
const i = W(null);
|
|
1194
|
+
return oe(() => {
|
|
1195
|
+
const o = i.current;
|
|
1196
|
+
if (!o) return;
|
|
1197
|
+
let t = 0;
|
|
1198
|
+
const s = () => {
|
|
1199
|
+
const c = Ae(o.clientWidth);
|
|
1200
|
+
if (c === t) return;
|
|
1201
|
+
t = c;
|
|
1202
|
+
const f = ie(e, n, o.ownerDocument, { width: t });
|
|
1203
|
+
o.replaceChildren(...f ? [f] : []), o.hidden = !f;
|
|
1204
|
+
};
|
|
1205
|
+
if (s(), typeof ResizeObserver > "u") return;
|
|
1206
|
+
const l = new ResizeObserver(s);
|
|
1207
|
+
return l.observe(o), () => l.disconnect();
|
|
1208
|
+
}, [e, n]), /* @__PURE__ */ r("div", { ref: i, className: a ? `bz-answer-picture ${a}` : "bz-answer-picture", hidden: !e });
|
|
1209
|
+
}
|
|
1210
|
+
export {
|
|
1211
|
+
Fe as AnswerPicture,
|
|
1212
|
+
x as Button,
|
|
1213
|
+
P as Card,
|
|
1214
|
+
ce as CashflowChart,
|
|
1215
|
+
Ve as Dashboard,
|
|
1216
|
+
R as Dot,
|
|
1217
|
+
j as Empty,
|
|
1218
|
+
Qe as LOCALES,
|
|
1219
|
+
Ke as LOCALE_NAMES,
|
|
1220
|
+
Ge as LOCALE_TAGS,
|
|
1221
|
+
Q as MAX_WIDTH,
|
|
1222
|
+
Ue as MINUS,
|
|
1223
|
+
re as MIN_WIDTH,
|
|
1224
|
+
Ce as MODULES,
|
|
1225
|
+
Z as Question,
|
|
1226
|
+
Be as Row,
|
|
1227
|
+
V as SHADES,
|
|
1228
|
+
le as Segmented,
|
|
1229
|
+
Ze as THOUSANDS,
|
|
1230
|
+
B as Tile,
|
|
1231
|
+
Je as VISUAL_KINDS,
|
|
1232
|
+
J as addDays,
|
|
1233
|
+
Xe as answerMessages,
|
|
1234
|
+
he as baseSeries,
|
|
1235
|
+
me as buildLevers,
|
|
1236
|
+
U as computeSeries,
|
|
1237
|
+
te as createFormatters,
|
|
1238
|
+
ae as createT,
|
|
1239
|
+
Ye as dateSpan,
|
|
1240
|
+
E as daysBetween,
|
|
1241
|
+
je as defineModule,
|
|
1242
|
+
ie as drawVisual,
|
|
1243
|
+
Re as findModule,
|
|
1244
|
+
en as isLocale,
|
|
1245
|
+
nn as isoDate,
|
|
1246
|
+
an as money,
|
|
1247
|
+
ue as niceTicks,
|
|
1248
|
+
H as num,
|
|
1249
|
+
tn as parseDate,
|
|
1250
|
+
rn as pickLocale,
|
|
1251
|
+
se as sharedMessages,
|
|
1252
|
+
I as shortDate,
|
|
1253
|
+
on as shorten,
|
|
1254
|
+
sn as signed,
|
|
1255
|
+
y as toNumber,
|
|
1256
|
+
O as tone
|
|
1257
|
+
};
|
|
1258
|
+
//# sourceMappingURL=index.js.map
|