@sentropic/design-system-svelte 0.16.0 → 0.18.0
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/dist/Calendar.svelte +237 -42
- package/dist/Calendar.svelte.d.ts.map +1 -1
- package/dist/ComboChart.svelte +620 -0
- package/dist/ComboChart.svelte.d.ts +28 -0
- package/dist/ComboChart.svelte.d.ts.map +1 -0
- package/dist/FunnelChart.svelte +358 -0
- package/dist/FunnelChart.svelte.d.ts +21 -0
- package/dist/FunnelChart.svelte.d.ts.map +1 -0
- package/dist/GaugeChart.svelte +300 -0
- package/dist/GaugeChart.svelte.d.ts +36 -0
- package/dist/GaugeChart.svelte.d.ts.map +1 -0
- package/dist/KpiCard.svelte +318 -0
- package/dist/KpiCard.svelte.d.ts +36 -0
- package/dist/KpiCard.svelte.d.ts.map +1 -0
- package/dist/Popper.svelte +157 -0
- package/dist/Popper.svelte.d.ts +17 -0
- package/dist/Popper.svelte.d.ts.map +1 -1
- package/dist/Rating.svelte +130 -35
- package/dist/Rating.svelte.d.ts.map +1 -1
- package/dist/SelectableList.svelte +60 -12
- package/dist/SelectableList.svelte.d.ts.map +1 -1
- package/dist/SelectableRow.svelte +23 -8
- package/dist/SelectableRow.svelte.d.ts +5 -4
- package/dist/SelectableRow.svelte.d.ts.map +1 -1
- package/dist/SlideIndicator.svelte +17 -3
- package/dist/SlideIndicator.svelte.d.ts.map +1 -1
- package/dist/TimePicker.svelte +176 -13
- package/dist/TimePicker.svelte.d.ts.map +1 -1
- package/dist/TreemapChart.svelte +448 -0
- package/dist/TreemapChart.svelte.d.ts +26 -0
- package/dist/TreemapChart.svelte.d.ts.map +1 -0
- package/dist/WaterfallChart.svelte +469 -0
- package/dist/WaterfallChart.svelte.d.ts +19 -0
- package/dist/WaterfallChart.svelte.d.ts.map +1 -0
- package/dist/chartContrast.d.ts +6 -0
- package/dist/chartContrast.d.ts.map +1 -0
- package/dist/chartContrast.js +58 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -0
- package/package.json +1 -1
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
export type GaugeChartTone = "neutral" | "info" | "success" | "warning" | "error" | "category1" | "category2" | "category3" | "category4" | "category5" | "category6" | "category7" | "category8";
|
|
2
|
+
/**
|
|
3
|
+
* Seuil de coloration. La bande s'étend depuis `value` (ou le minimum)
|
|
4
|
+
* jusqu'au seuil suivant (ou le maximum). `tone` choisit la couleur.
|
|
5
|
+
*/
|
|
6
|
+
export type GaugeChartThreshold = {
|
|
7
|
+
value: number;
|
|
8
|
+
tone: GaugeChartTone;
|
|
9
|
+
};
|
|
10
|
+
export type GaugeChartFormat = "number" | "percent";
|
|
11
|
+
type GaugeChartProps = {
|
|
12
|
+
value: number;
|
|
13
|
+
min?: number;
|
|
14
|
+
max?: number;
|
|
15
|
+
/** Bandes colorées sur la piste. Triées par `value` croissante. */
|
|
16
|
+
thresholds?: GaugeChartThreshold[];
|
|
17
|
+
/** Libellé décrivant la jauge (a11y + texte sous la valeur). */
|
|
18
|
+
label?: string;
|
|
19
|
+
/** Format de la valeur centrale. */
|
|
20
|
+
format?: GaugeChartFormat;
|
|
21
|
+
/** Suffixe d'unité (ignoré pour `percent`). */
|
|
22
|
+
unit?: string;
|
|
23
|
+
/** Diamètre du SVG. */
|
|
24
|
+
size?: number;
|
|
25
|
+
/** Épaisseur de l'arc. */
|
|
26
|
+
thickness?: number;
|
|
27
|
+
/** Angle de départ en degrés (0 = est, sens horaire). */
|
|
28
|
+
startAngle?: number;
|
|
29
|
+
/** Angle de fin en degrés. */
|
|
30
|
+
endAngle?: number;
|
|
31
|
+
class?: string;
|
|
32
|
+
};
|
|
33
|
+
declare const GaugeChart: import("svelte").Component<GaugeChartProps, {}, "">;
|
|
34
|
+
type GaugeChart = ReturnType<typeof GaugeChart>;
|
|
35
|
+
export default GaugeChart;
|
|
36
|
+
//# sourceMappingURL=GaugeChart.svelte.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GaugeChart.svelte.d.ts","sourceRoot":"","sources":["../src/lib/GaugeChart.svelte.ts"],"names":[],"mappings":"AAGE,MAAM,MAAM,cAAc,GACtB,SAAS,GAAG,MAAM,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,GACpD,WAAW,GAAG,WAAW,GAAG,WAAW,GAAG,WAAW,GACrD,WAAW,GAAG,WAAW,GAAG,WAAW,GAAG,WAAW,CAAC;AAE1D;;;GAGG;AACH,MAAM,MAAM,mBAAmB,GAAG;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,cAAc,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG,QAAQ,GAAG,SAAS,CAAC;AAMpD,KAAK,eAAe,GAAG;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,mEAAmE;IACnE,UAAU,CAAC,EAAE,mBAAmB,EAAE,CAAC;IACnC,gEAAgE;IAChE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,oCAAoC;IACpC,MAAM,CAAC,EAAE,gBAAgB,CAAC;IAC1B,+CAA+C;IAC/C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,uBAAuB;IACvB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,0BAA0B;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,yDAAyD;IACzD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,8BAA8B;IAC9B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AA2JJ,QAAA,MAAM,UAAU,qDAAwC,CAAC;AACzD,KAAK,UAAU,GAAG,UAAU,CAAC,OAAO,UAAU,CAAC,CAAC;AAChD,eAAe,UAAU,CAAC"}
|
|
@@ -0,0 +1,318 @@
|
|
|
1
|
+
<script lang="ts" module>
|
|
2
|
+
export type KpiCardSize = "sm" | "md" | "lg";
|
|
3
|
+
export type KpiCardTrend = "up" | "down" | "flat";
|
|
4
|
+
export type KpiCardFormat = "number" | "currency" | "percent";
|
|
5
|
+
export type KpiCardDeltaFormat = "percent" | "absolute";
|
|
6
|
+
export type KpiCardTone =
|
|
7
|
+
| "category1"
|
|
8
|
+
| "category2"
|
|
9
|
+
| "category3"
|
|
10
|
+
| "category4"
|
|
11
|
+
| "category5"
|
|
12
|
+
| "category6"
|
|
13
|
+
| "category7"
|
|
14
|
+
| "category8";
|
|
15
|
+
</script>
|
|
16
|
+
|
|
17
|
+
<script lang="ts">
|
|
18
|
+
import type { HTMLAttributes } from "svelte/elements";
|
|
19
|
+
import Sparkline from "./Sparkline.svelte";
|
|
20
|
+
|
|
21
|
+
type KpiCardProps = Omit<HTMLAttributes<HTMLElement>, "class"> & {
|
|
22
|
+
/** Valeur principale affichée en grand. */
|
|
23
|
+
value: number | string;
|
|
24
|
+
/** Étiquette de l'indicateur (ex. « Revenu mensuel »). */
|
|
25
|
+
label: string;
|
|
26
|
+
/** Variation par rapport à la période précédente. */
|
|
27
|
+
delta?: number;
|
|
28
|
+
/** Comment exprimer le delta : en pourcentage ou en valeur absolue. */
|
|
29
|
+
deltaFormat?: KpiCardDeltaFormat;
|
|
30
|
+
/** Tendance ; déduite du signe du delta si absente. */
|
|
31
|
+
trend?: KpiCardTrend;
|
|
32
|
+
/** Formatage de la valeur principale via Intl.NumberFormat. */
|
|
33
|
+
format?: KpiCardFormat;
|
|
34
|
+
/** Unité suffixée à la valeur (ex. « ms », « €/mois »). */
|
|
35
|
+
unit?: string;
|
|
36
|
+
/** Code devise ISO 4217 pour format="currency" (défaut EUR). */
|
|
37
|
+
currency?: string;
|
|
38
|
+
/** Locale BCP 47 pour le formatage des nombres (défaut undefined = locale du runtime). */
|
|
39
|
+
locale?: string;
|
|
40
|
+
/** Mini-graphique de tendance optionnel. */
|
|
41
|
+
sparkline?: number[];
|
|
42
|
+
size?: KpiCardSize;
|
|
43
|
+
/** Couleur catégorielle pour l'accent (bordure de gauche). */
|
|
44
|
+
tone?: KpiCardTone;
|
|
45
|
+
class?: string;
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
let {
|
|
49
|
+
value,
|
|
50
|
+
label,
|
|
51
|
+
delta,
|
|
52
|
+
deltaFormat = "percent",
|
|
53
|
+
trend,
|
|
54
|
+
format = "number",
|
|
55
|
+
unit,
|
|
56
|
+
currency = "EUR",
|
|
57
|
+
locale,
|
|
58
|
+
sparkline,
|
|
59
|
+
size = "md",
|
|
60
|
+
tone,
|
|
61
|
+
class: className,
|
|
62
|
+
...rest
|
|
63
|
+
}: KpiCardProps = $props();
|
|
64
|
+
|
|
65
|
+
const resolvedTrend = $derived<KpiCardTrend | undefined>(
|
|
66
|
+
trend ?? (delta == null ? undefined : delta > 0 ? "up" : delta < 0 ? "down" : "flat")
|
|
67
|
+
);
|
|
68
|
+
|
|
69
|
+
const formattedValue = $derived.by(() => {
|
|
70
|
+
if (typeof value === "string") {
|
|
71
|
+
return value;
|
|
72
|
+
}
|
|
73
|
+
if (format === "currency") {
|
|
74
|
+
return new Intl.NumberFormat(locale, { style: "currency", currency }).format(value);
|
|
75
|
+
}
|
|
76
|
+
if (format === "percent") {
|
|
77
|
+
return new Intl.NumberFormat(locale, { style: "percent", maximumFractionDigits: 2 }).format(
|
|
78
|
+
value
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
return new Intl.NumberFormat(locale).format(value);
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
const formattedDelta = $derived.by(() => {
|
|
85
|
+
if (delta == null) {
|
|
86
|
+
return undefined;
|
|
87
|
+
}
|
|
88
|
+
const sign = delta > 0 ? "+" : "";
|
|
89
|
+
if (deltaFormat === "percent") {
|
|
90
|
+
const pct = new Intl.NumberFormat(locale, {
|
|
91
|
+
style: "percent",
|
|
92
|
+
maximumFractionDigits: 1
|
|
93
|
+
}).format(delta);
|
|
94
|
+
return `${sign}${pct}`;
|
|
95
|
+
}
|
|
96
|
+
return `${sign}${new Intl.NumberFormat(locale).format(delta)}`;
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
/** Le sparkline emprunte la couleur sémantique de la tendance. */
|
|
100
|
+
const sparklineTone = $derived(
|
|
101
|
+
resolvedTrend === "up" ? "success" : resolvedTrend === "down" ? "error" : "neutral"
|
|
102
|
+
);
|
|
103
|
+
|
|
104
|
+
const arrow = $derived(
|
|
105
|
+
resolvedTrend === "up" ? "M3 8.5 7 4l4 4.5" : resolvedTrend === "down" ? "M3 5.5 7 10l4-4.5" : "M3 7h8"
|
|
106
|
+
);
|
|
107
|
+
|
|
108
|
+
const trendLabel = $derived(
|
|
109
|
+
resolvedTrend === "up"
|
|
110
|
+
? "en hausse"
|
|
111
|
+
: resolvedTrend === "down"
|
|
112
|
+
? "en baisse"
|
|
113
|
+
: resolvedTrend === "flat"
|
|
114
|
+
? "stable"
|
|
115
|
+
: undefined
|
|
116
|
+
);
|
|
117
|
+
|
|
118
|
+
const ariaLabel = $derived(
|
|
119
|
+
[label, formattedValue, unit, formattedDelta && `${formattedDelta} ${trendLabel ?? ""}`.trim()]
|
|
120
|
+
.filter(Boolean)
|
|
121
|
+
.join(", ")
|
|
122
|
+
);
|
|
123
|
+
|
|
124
|
+
const classes = $derived(
|
|
125
|
+
[
|
|
126
|
+
"st-kpiCard",
|
|
127
|
+
`st-kpiCard--${size}`,
|
|
128
|
+
tone && `st-kpiCard--${tone}`,
|
|
129
|
+
tone && "st-kpiCard--toned",
|
|
130
|
+
className
|
|
131
|
+
]
|
|
132
|
+
.filter(Boolean)
|
|
133
|
+
.join(" ")
|
|
134
|
+
);
|
|
135
|
+
</script>
|
|
136
|
+
|
|
137
|
+
<article {...rest} class={classes} role="group" aria-label={ariaLabel}>
|
|
138
|
+
<p class="st-kpiCard__label">{label}</p>
|
|
139
|
+
|
|
140
|
+
<p class="st-kpiCard__value">
|
|
141
|
+
<span class="st-kpiCard__number">{formattedValue}</span>
|
|
142
|
+
{#if unit}
|
|
143
|
+
<span class="st-kpiCard__unit">{unit}</span>
|
|
144
|
+
{/if}
|
|
145
|
+
</p>
|
|
146
|
+
|
|
147
|
+
{#if formattedDelta || sparkline}
|
|
148
|
+
<div class="st-kpiCard__footer">
|
|
149
|
+
{#if formattedDelta}
|
|
150
|
+
<span
|
|
151
|
+
class="st-kpiCard__delta st-kpiCard__delta--{resolvedTrend ?? 'flat'}"
|
|
152
|
+
aria-hidden="true"
|
|
153
|
+
>
|
|
154
|
+
<svg
|
|
155
|
+
class="st-kpiCard__arrow"
|
|
156
|
+
width="14"
|
|
157
|
+
height="14"
|
|
158
|
+
viewBox="0 0 14 14"
|
|
159
|
+
aria-hidden="true"
|
|
160
|
+
focusable="false"
|
|
161
|
+
>
|
|
162
|
+
<path
|
|
163
|
+
d={arrow}
|
|
164
|
+
fill="none"
|
|
165
|
+
stroke="currentColor"
|
|
166
|
+
stroke-width="1.75"
|
|
167
|
+
stroke-linecap="round"
|
|
168
|
+
stroke-linejoin="round"
|
|
169
|
+
/>
|
|
170
|
+
</svg>
|
|
171
|
+
<span class="st-kpiCard__deltaValue">{formattedDelta}</span>
|
|
172
|
+
</span>
|
|
173
|
+
{/if}
|
|
174
|
+
|
|
175
|
+
{#if sparkline && sparkline.length > 0}
|
|
176
|
+
<Sparkline
|
|
177
|
+
class="st-kpiCard__sparkline"
|
|
178
|
+
data={sparkline}
|
|
179
|
+
tone={sparklineTone}
|
|
180
|
+
area
|
|
181
|
+
/>
|
|
182
|
+
{/if}
|
|
183
|
+
</div>
|
|
184
|
+
{/if}
|
|
185
|
+
</article>
|
|
186
|
+
|
|
187
|
+
<style>
|
|
188
|
+
.st-kpiCard {
|
|
189
|
+
background: var(--st-component-card-background, var(--st-semantic-surface-raised));
|
|
190
|
+
border-width: var(--st-component-card-anatomy-shape-borderWidth, 1px);
|
|
191
|
+
border-style: var(--st-component-card-anatomy-shape-borderStyle, solid);
|
|
192
|
+
border-color: var(--st-component-card-border, var(--st-semantic-border-subtle));
|
|
193
|
+
border-radius: var(--st-component-card-anatomy-shape-radius, 0.5rem);
|
|
194
|
+
box-shadow: var(--st-component-card-shadow, 0 1px 2px rgb(15 23 42 / 0.08));
|
|
195
|
+
color: var(--st-semantic-text-primary);
|
|
196
|
+
display: flex;
|
|
197
|
+
flex-direction: column;
|
|
198
|
+
gap: var(--st-spacing-2, 0.5rem);
|
|
199
|
+
padding: var(--st-spacing-4, 1rem);
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
.st-kpiCard--sm {
|
|
203
|
+
gap: var(--st-spacing-1, 0.25rem);
|
|
204
|
+
padding: var(--st-spacing-3, 0.75rem);
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
.st-kpiCard--lg {
|
|
208
|
+
gap: var(--st-spacing-3, 0.75rem);
|
|
209
|
+
padding: var(--st-spacing-6, 1.5rem);
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/* Accent catégoriel : liseré coloré à gauche. */
|
|
213
|
+
.st-kpiCard--toned {
|
|
214
|
+
border-inline-start-width: var(--st-spacing-1, 0.25rem);
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
.st-kpiCard__label {
|
|
218
|
+
color: var(--st-semantic-text-secondary);
|
|
219
|
+
font-size: 0.8125rem;
|
|
220
|
+
font-weight: 500;
|
|
221
|
+
line-height: 1.25;
|
|
222
|
+
margin: 0;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
.st-kpiCard--lg .st-kpiCard__label {
|
|
226
|
+
font-size: 0.875rem;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
.st-kpiCard__value {
|
|
230
|
+
align-items: baseline;
|
|
231
|
+
color: var(--st-semantic-text-primary);
|
|
232
|
+
display: flex;
|
|
233
|
+
flex-wrap: wrap;
|
|
234
|
+
gap: var(--st-spacing-1, 0.25rem);
|
|
235
|
+
margin: 0;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
.st-kpiCard__number {
|
|
239
|
+
font-size: 1.5rem;
|
|
240
|
+
font-weight: 700;
|
|
241
|
+
letter-spacing: -0.01em;
|
|
242
|
+
line-height: 1.1;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
.st-kpiCard--sm .st-kpiCard__number {
|
|
246
|
+
font-size: 1.25rem;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
.st-kpiCard--lg .st-kpiCard__number {
|
|
250
|
+
font-size: 2.25rem;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
.st-kpiCard__unit {
|
|
254
|
+
color: var(--st-semantic-text-secondary);
|
|
255
|
+
font-size: 0.875rem;
|
|
256
|
+
font-weight: 500;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
.st-kpiCard__footer {
|
|
260
|
+
align-items: center;
|
|
261
|
+
display: flex;
|
|
262
|
+
flex-wrap: wrap;
|
|
263
|
+
gap: var(--st-spacing-3, 0.75rem);
|
|
264
|
+
justify-content: space-between;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
.st-kpiCard__delta {
|
|
268
|
+
align-items: center;
|
|
269
|
+
display: inline-flex;
|
|
270
|
+
font-size: 0.8125rem;
|
|
271
|
+
font-weight: 600;
|
|
272
|
+
gap: var(--st-spacing-1, 0.25rem);
|
|
273
|
+
line-height: 1;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
.st-kpiCard__arrow {
|
|
277
|
+
display: block;
|
|
278
|
+
flex: 0 0 auto;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
.st-kpiCard__delta--up {
|
|
282
|
+
color: var(--st-semantic-feedback-success);
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
.st-kpiCard__delta--down {
|
|
286
|
+
color: var(--st-semantic-feedback-error);
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
.st-kpiCard__delta--flat {
|
|
290
|
+
color: var(--st-semantic-text-secondary);
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
/* Liserés catégoriels — alignés sur la palette data des autres composants. */
|
|
294
|
+
.st-kpiCard--category1 {
|
|
295
|
+
border-inline-start-color: var(--st-semantic-data-category1);
|
|
296
|
+
}
|
|
297
|
+
.st-kpiCard--category2 {
|
|
298
|
+
border-inline-start-color: var(--st-semantic-data-category2);
|
|
299
|
+
}
|
|
300
|
+
.st-kpiCard--category3 {
|
|
301
|
+
border-inline-start-color: var(--st-semantic-data-category3);
|
|
302
|
+
}
|
|
303
|
+
.st-kpiCard--category4 {
|
|
304
|
+
border-inline-start-color: var(--st-semantic-data-category4);
|
|
305
|
+
}
|
|
306
|
+
.st-kpiCard--category5 {
|
|
307
|
+
border-inline-start-color: var(--st-semantic-data-category5);
|
|
308
|
+
}
|
|
309
|
+
.st-kpiCard--category6 {
|
|
310
|
+
border-inline-start-color: var(--st-semantic-data-category6);
|
|
311
|
+
}
|
|
312
|
+
.st-kpiCard--category7 {
|
|
313
|
+
border-inline-start-color: var(--st-semantic-data-category7);
|
|
314
|
+
}
|
|
315
|
+
.st-kpiCard--category8 {
|
|
316
|
+
border-inline-start-color: var(--st-semantic-data-category8);
|
|
317
|
+
}
|
|
318
|
+
</style>
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
export type KpiCardSize = "sm" | "md" | "lg";
|
|
2
|
+
export type KpiCardTrend = "up" | "down" | "flat";
|
|
3
|
+
export type KpiCardFormat = "number" | "currency" | "percent";
|
|
4
|
+
export type KpiCardDeltaFormat = "percent" | "absolute";
|
|
5
|
+
export type KpiCardTone = "category1" | "category2" | "category3" | "category4" | "category5" | "category6" | "category7" | "category8";
|
|
6
|
+
import type { HTMLAttributes } from "svelte/elements";
|
|
7
|
+
type KpiCardProps = Omit<HTMLAttributes<HTMLElement>, "class"> & {
|
|
8
|
+
/** Valeur principale affichée en grand. */
|
|
9
|
+
value: number | string;
|
|
10
|
+
/** Étiquette de l'indicateur (ex. « Revenu mensuel »). */
|
|
11
|
+
label: string;
|
|
12
|
+
/** Variation par rapport à la période précédente. */
|
|
13
|
+
delta?: number;
|
|
14
|
+
/** Comment exprimer le delta : en pourcentage ou en valeur absolue. */
|
|
15
|
+
deltaFormat?: KpiCardDeltaFormat;
|
|
16
|
+
/** Tendance ; déduite du signe du delta si absente. */
|
|
17
|
+
trend?: KpiCardTrend;
|
|
18
|
+
/** Formatage de la valeur principale via Intl.NumberFormat. */
|
|
19
|
+
format?: KpiCardFormat;
|
|
20
|
+
/** Unité suffixée à la valeur (ex. « ms », « €/mois »). */
|
|
21
|
+
unit?: string;
|
|
22
|
+
/** Code devise ISO 4217 pour format="currency" (défaut EUR). */
|
|
23
|
+
currency?: string;
|
|
24
|
+
/** Locale BCP 47 pour le formatage des nombres (défaut undefined = locale du runtime). */
|
|
25
|
+
locale?: string;
|
|
26
|
+
/** Mini-graphique de tendance optionnel. */
|
|
27
|
+
sparkline?: number[];
|
|
28
|
+
size?: KpiCardSize;
|
|
29
|
+
/** Couleur catégorielle pour l'accent (bordure de gauche). */
|
|
30
|
+
tone?: KpiCardTone;
|
|
31
|
+
class?: string;
|
|
32
|
+
};
|
|
33
|
+
declare const KpiCard: import("svelte").Component<KpiCardProps, {}, "">;
|
|
34
|
+
type KpiCard = ReturnType<typeof KpiCard>;
|
|
35
|
+
export default KpiCard;
|
|
36
|
+
//# sourceMappingURL=KpiCard.svelte.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"KpiCard.svelte.d.ts","sourceRoot":"","sources":["../src/lib/KpiCard.svelte.ts"],"names":[],"mappings":"AAGE,MAAM,MAAM,WAAW,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAC7C,MAAM,MAAM,YAAY,GAAG,IAAI,GAAG,MAAM,GAAG,MAAM,CAAC;AAClD,MAAM,MAAM,aAAa,GAAG,QAAQ,GAAG,UAAU,GAAG,SAAS,CAAC;AAC9D,MAAM,MAAM,kBAAkB,GAAG,SAAS,GAAG,UAAU,CAAC;AACxD,MAAM,MAAM,WAAW,GACnB,WAAW,GACX,WAAW,GACX,WAAW,GACX,WAAW,GACX,WAAW,GACX,WAAW,GACX,WAAW,GACX,WAAW,CAAC;AAGlB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAIpD,KAAK,YAAY,GAAG,IAAI,CAAC,cAAc,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC,GAAG;IAC/D,2CAA2C;IAC3C,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC;IACvB,0DAA0D;IAC1D,KAAK,EAAE,MAAM,CAAC;IACd,qDAAqD;IACrD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,uEAAuE;IACvE,WAAW,CAAC,EAAE,kBAAkB,CAAC;IACjC,uDAAuD;IACvD,KAAK,CAAC,EAAE,YAAY,CAAC;IACrB,+DAA+D;IAC/D,MAAM,CAAC,EAAE,aAAa,CAAC;IACvB,2DAA2D;IAC3D,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,gEAAgE;IAChE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,0FAA0F;IAC1F,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,4CAA4C;IAC5C,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,IAAI,CAAC,EAAE,WAAW,CAAC;IACnB,8DAA8D;IAC9D,IAAI,CAAC,EAAE,WAAW,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAiIJ,QAAA,MAAM,OAAO,kDAAwC,CAAC;AACtD,KAAK,OAAO,GAAG,UAAU,CAAC,OAAO,OAAO,CAAC,CAAC;AAC1C,eAAe,OAAO,CAAC"}
|
package/dist/Popper.svelte
CHANGED
|
@@ -44,6 +44,23 @@
|
|
|
44
44
|
class?: string;
|
|
45
45
|
/** Notified whenever the resolved placement changes (after flip). */
|
|
46
46
|
onPlacementChange?: (placement: PopperPlacement) => void;
|
|
47
|
+
/**
|
|
48
|
+
* (a11y, opt-in) When true, traps keyboard focus inside the panel while it
|
|
49
|
+
* is open (Tab cycles through focusable children; Shift+Tab cycles backward).
|
|
50
|
+
* Intended for modal overlays built on top of Popper. Non-modal usage (menus,
|
|
51
|
+
* tooltips) should leave this false (default) to keep the natural tab order.
|
|
52
|
+
*/
|
|
53
|
+
trapFocus?: boolean;
|
|
54
|
+
/**
|
|
55
|
+
* (a11y) When true (default when open), pressing Escape calls `onClose` so
|
|
56
|
+
* the consumer can set `open = false`. Set to false to suppress this behavior.
|
|
57
|
+
*/
|
|
58
|
+
closeOnEscape?: boolean;
|
|
59
|
+
/**
|
|
60
|
+
* Called when the panel requests closing (Escape key, or future outside-click).
|
|
61
|
+
* The consumer is responsible for updating `open` in response.
|
|
62
|
+
*/
|
|
63
|
+
onClose?: () => void;
|
|
47
64
|
children?: Snippet;
|
|
48
65
|
};
|
|
49
66
|
|
|
@@ -158,6 +175,8 @@
|
|
|
158
175
|
</script>
|
|
159
176
|
|
|
160
177
|
<script lang="ts">
|
|
178
|
+
import { untrack } from "svelte";
|
|
179
|
+
|
|
161
180
|
let {
|
|
162
181
|
anchor,
|
|
163
182
|
open = false,
|
|
@@ -170,6 +189,9 @@
|
|
|
170
189
|
portal = true,
|
|
171
190
|
class: className,
|
|
172
191
|
onPlacementChange,
|
|
192
|
+
trapFocus = false,
|
|
193
|
+
closeOnEscape = true,
|
|
194
|
+
onClose,
|
|
173
195
|
children
|
|
174
196
|
}: PopperProps = $props();
|
|
175
197
|
|
|
@@ -243,17 +265,152 @@
|
|
|
243
265
|
};
|
|
244
266
|
});
|
|
245
267
|
|
|
268
|
+
// ─── a11y: focus management ────────────────────────────────────────────────
|
|
269
|
+
// Capture the element that had focus before the panel opened so we can
|
|
270
|
+
// restore it when the panel closes (only when trapFocus is active).
|
|
271
|
+
// SSR-safe (guarded by typeof window).
|
|
272
|
+
// Use a plain variable (not $state) so reads inside the effect are not
|
|
273
|
+
// tracked and don't cause the effect to re-run on every preFocusEl write.
|
|
274
|
+
let preFocusEl: HTMLElement | null = null;
|
|
275
|
+
|
|
276
|
+
$effect(() => {
|
|
277
|
+
if (typeof window === "undefined") return;
|
|
278
|
+
if (open && anchor) {
|
|
279
|
+
untrack(() => {
|
|
280
|
+
// Snapshot the active element at open time only when trapFocus is active,
|
|
281
|
+
// so restoreFocus doesn't steal focus on non-modal usage.
|
|
282
|
+
if (trapFocus) {
|
|
283
|
+
preFocusEl = document.activeElement as HTMLElement | null;
|
|
284
|
+
}
|
|
285
|
+
});
|
|
286
|
+
} else {
|
|
287
|
+
// Panel just closed: restore focus only if trapFocus was active and the
|
|
288
|
+
// original element is still connected to the DOM.
|
|
289
|
+
untrack(() => {
|
|
290
|
+
if (
|
|
291
|
+
trapFocus &&
|
|
292
|
+
preFocusEl &&
|
|
293
|
+
typeof preFocusEl.focus === "function" &&
|
|
294
|
+
document.contains(preFocusEl)
|
|
295
|
+
) {
|
|
296
|
+
preFocusEl.focus();
|
|
297
|
+
}
|
|
298
|
+
preFocusEl = null;
|
|
299
|
+
});
|
|
300
|
+
}
|
|
301
|
+
});
|
|
302
|
+
|
|
303
|
+
/** Returns all keyboard-focusable children of `container`. */
|
|
304
|
+
function getFocusable(container: HTMLElement): HTMLElement[] {
|
|
305
|
+
if (typeof window === "undefined") return [];
|
|
306
|
+
return Array.from(
|
|
307
|
+
container.querySelectorAll<HTMLElement>(
|
|
308
|
+
'a[href],button:not([disabled]),input:not([disabled]),select:not([disabled]),' +
|
|
309
|
+
'textarea:not([disabled]),[tabindex]:not([tabindex="-1"]),[contenteditable="true"]'
|
|
310
|
+
)
|
|
311
|
+
).filter((el) => !el.closest("[disabled]"));
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
// ─── a11y: move focus into the panel on open (trapFocus only) ─────────────
|
|
315
|
+
$effect(() => {
|
|
316
|
+
if (typeof window === "undefined") return;
|
|
317
|
+
if (!open || !trapFocus || !panel) return;
|
|
318
|
+
// Wait for the panel to be mounted before moving focus.
|
|
319
|
+
untrack(() => {
|
|
320
|
+
const focusable = getFocusable(panel!);
|
|
321
|
+
if (focusable.length > 0) {
|
|
322
|
+
focusable[0].focus();
|
|
323
|
+
} else {
|
|
324
|
+
// If no focusable children, focus the panel itself so Escape works.
|
|
325
|
+
panel!.focus();
|
|
326
|
+
}
|
|
327
|
+
});
|
|
328
|
+
});
|
|
329
|
+
|
|
330
|
+
// ─── a11y: recapture focus that escapes the trap (focusin on document) ─────
|
|
331
|
+
$effect(() => {
|
|
332
|
+
if (typeof window === "undefined") return;
|
|
333
|
+
if (!open || !trapFocus) return;
|
|
334
|
+
|
|
335
|
+
function handleFocusIn(e: FocusEvent) {
|
|
336
|
+
if (!panel) return;
|
|
337
|
+
const target = e.target as Node | null;
|
|
338
|
+
// If focus landed outside the panel, bring it back to the first focusable.
|
|
339
|
+
if (target && !panel.contains(target)) {
|
|
340
|
+
const focusable = getFocusable(panel);
|
|
341
|
+
if (focusable.length > 0) {
|
|
342
|
+
focusable[0].focus();
|
|
343
|
+
} else {
|
|
344
|
+
panel.focus();
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
document.addEventListener("focusin", handleFocusIn);
|
|
350
|
+
return () => {
|
|
351
|
+
document.removeEventListener("focusin", handleFocusIn);
|
|
352
|
+
};
|
|
353
|
+
});
|
|
354
|
+
|
|
355
|
+
// ─── a11y: Escape on document (closeOnEscape) ─────────────────────────────
|
|
356
|
+
// Listen on document so the Escape shortcut works even when focus is outside
|
|
357
|
+
// the panel (e.g. before the first Tab, or in an edge case where focus escaped).
|
|
358
|
+
$effect(() => {
|
|
359
|
+
if (typeof window === "undefined") return;
|
|
360
|
+
if (!open || !closeOnEscape) return;
|
|
361
|
+
|
|
362
|
+
function handleDocKeydown(e: KeyboardEvent) {
|
|
363
|
+
if (e.key === "Escape") {
|
|
364
|
+
e.preventDefault();
|
|
365
|
+
onClose?.();
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
document.addEventListener("keydown", handleDocKeydown);
|
|
370
|
+
return () => {
|
|
371
|
+
document.removeEventListener("keydown", handleDocKeydown);
|
|
372
|
+
};
|
|
373
|
+
});
|
|
374
|
+
|
|
375
|
+
/** Keyboard handler attached to the panel for Tab-trap cycling. */
|
|
376
|
+
function handlePanelKeydown(e: KeyboardEvent) {
|
|
377
|
+
if (typeof window === "undefined") return;
|
|
378
|
+
|
|
379
|
+
// Tab trap: cycle focus within the panel.
|
|
380
|
+
if (e.key === "Tab" && trapFocus && panel) {
|
|
381
|
+
const focusable = getFocusable(panel);
|
|
382
|
+
if (focusable.length === 0) { e.preventDefault(); return; }
|
|
383
|
+
const first = focusable[0];
|
|
384
|
+
const last = focusable[focusable.length - 1];
|
|
385
|
+
if (e.shiftKey) {
|
|
386
|
+
if (document.activeElement === first) {
|
|
387
|
+
e.preventDefault();
|
|
388
|
+
last.focus();
|
|
389
|
+
}
|
|
390
|
+
} else {
|
|
391
|
+
if (document.activeElement === last) {
|
|
392
|
+
e.preventDefault();
|
|
393
|
+
first.focus();
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
|
|
246
399
|
const panelStyle = () =>
|
|
247
400
|
`position: ${strategy}; top: ${top}px; left: ${left}px;`;
|
|
248
401
|
const panelSide = () => splitPlacement(resolvedPlacement).side;
|
|
249
402
|
</script>
|
|
250
403
|
|
|
251
404
|
{#snippet floating()}
|
|
405
|
+
<!-- svelte-ignore a11y_no_noninteractive_element_interactions -->
|
|
406
|
+
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
|
252
407
|
<div
|
|
253
408
|
bind:this={panel}
|
|
254
409
|
class={className ? `st-popper ${className}` : "st-popper"}
|
|
255
410
|
data-popper-placement={resolvedPlacement}
|
|
256
411
|
style={panelStyle()}
|
|
412
|
+
tabindex={trapFocus ? -1 : undefined}
|
|
413
|
+
onkeydown={trapFocus ? handlePanelKeydown : undefined}
|
|
257
414
|
>
|
|
258
415
|
{@render children?.()}
|
|
259
416
|
{#if arrow}
|
package/dist/Popper.svelte.d.ts
CHANGED
|
@@ -26,6 +26,23 @@ export type PopperProps = {
|
|
|
26
26
|
class?: string;
|
|
27
27
|
/** Notified whenever the resolved placement changes (after flip). */
|
|
28
28
|
onPlacementChange?: (placement: PopperPlacement) => void;
|
|
29
|
+
/**
|
|
30
|
+
* (a11y, opt-in) When true, traps keyboard focus inside the panel while it
|
|
31
|
+
* is open (Tab cycles through focusable children; Shift+Tab cycles backward).
|
|
32
|
+
* Intended for modal overlays built on top of Popper. Non-modal usage (menus,
|
|
33
|
+
* tooltips) should leave this false (default) to keep the natural tab order.
|
|
34
|
+
*/
|
|
35
|
+
trapFocus?: boolean;
|
|
36
|
+
/**
|
|
37
|
+
* (a11y) When true (default when open), pressing Escape calls `onClose` so
|
|
38
|
+
* the consumer can set `open = false`. Set to false to suppress this behavior.
|
|
39
|
+
*/
|
|
40
|
+
closeOnEscape?: boolean;
|
|
41
|
+
/**
|
|
42
|
+
* Called when the panel requests closing (Escape key, or future outside-click).
|
|
43
|
+
* The consumer is responsible for updating `open` in response.
|
|
44
|
+
*/
|
|
45
|
+
onClose?: () => void;
|
|
29
46
|
children?: Snippet;
|
|
30
47
|
};
|
|
31
48
|
/** Split a placement into its side and (optional) alignment. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Popper.svelte.d.ts","sourceRoot":"","sources":["../src/lib/Popper.svelte.ts"],"names":[],"mappings":"AAGE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAGtC,MAAM,MAAM,cAAc,GAAG,UAAU,GAAG,OAAO,CAAC;AAElD,MAAM,MAAM,eAAe,GACvB,KAAK,GACL,QAAQ,GACR,MAAM,GACN,OAAO,GACP,WAAW,GACX,SAAS,GACT,cAAc,GACd,YAAY,GACZ,YAAY,GACZ,UAAU,GACV,aAAa,GACb,WAAW,CAAC;AAEhB,MAAM,MAAM,UAAU,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,OAAO,CAAC;AAC7D,MAAM,MAAM,WAAW,GAAG,OAAO,GAAG,QAAQ,GAAG,KAAK,CAAC;AAErD,MAAM,MAAM,WAAW,GAAG;IACxB,yDAAyD;IACzD,MAAM,EAAE,WAAW,GAAG,IAAI,CAAC;IAC3B,wEAAwE;IACxE,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,4DAA4D;IAC5D,SAAS,CAAC,EAAE,eAAe,CAAC;IAC5B,gEAAgE;IAChE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,4EAA4E;IAC5E,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,wEAAwE;IACxE,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,yCAAyC;IACzC,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,gCAAgC;IAChC,QAAQ,CAAC,EAAE,cAAc,CAAC;IAC1B,0DAA0D;IAC1D,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,oDAAoD;IACpD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,qEAAqE;IACrE,iBAAiB,CAAC,EAAE,CAAC,SAAS,EAAE,eAAe,KAAK,IAAI,CAAC;IACzD,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,CAAC;AAEF,gEAAgE;AAChE,wBAAgB,cAAc,CAAC,SAAS,EAAE,eAAe,GAAG;IAC1D,IAAI,EAAE,UAAU,CAAC;IACjB,KAAK,EAAE,WAAW,CAAC;CACpB,CAGA;AAED,4DAA4D;AAC5D,wBAAgB,aAAa,CAAC,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,WAAW,GAAG,eAAe,CAEnF;AASD,MAAM,MAAM,IAAI,GAAG;IACjB,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAC7B,UAAU,EAAE,IAAI,EAChB,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE;IACP,SAAS,EAAE,eAAe,CAAC;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,OAAO,CAAC;IACd,KAAK,EAAE,OAAO,CAAC;IACf,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,CAAC;CACxB,GACA;IAAE,SAAS,EAAE,eAAe,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAwD3D;
|
|
1
|
+
{"version":3,"file":"Popper.svelte.d.ts","sourceRoot":"","sources":["../src/lib/Popper.svelte.ts"],"names":[],"mappings":"AAGE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAGtC,MAAM,MAAM,cAAc,GAAG,UAAU,GAAG,OAAO,CAAC;AAElD,MAAM,MAAM,eAAe,GACvB,KAAK,GACL,QAAQ,GACR,MAAM,GACN,OAAO,GACP,WAAW,GACX,SAAS,GACT,cAAc,GACd,YAAY,GACZ,YAAY,GACZ,UAAU,GACV,aAAa,GACb,WAAW,CAAC;AAEhB,MAAM,MAAM,UAAU,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,OAAO,CAAC;AAC7D,MAAM,MAAM,WAAW,GAAG,OAAO,GAAG,QAAQ,GAAG,KAAK,CAAC;AAErD,MAAM,MAAM,WAAW,GAAG;IACxB,yDAAyD;IACzD,MAAM,EAAE,WAAW,GAAG,IAAI,CAAC;IAC3B,wEAAwE;IACxE,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,4DAA4D;IAC5D,SAAS,CAAC,EAAE,eAAe,CAAC;IAC5B,gEAAgE;IAChE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,4EAA4E;IAC5E,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,wEAAwE;IACxE,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,yCAAyC;IACzC,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,gCAAgC;IAChC,QAAQ,CAAC,EAAE,cAAc,CAAC;IAC1B,0DAA0D;IAC1D,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,oDAAoD;IACpD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,qEAAqE;IACrE,iBAAiB,CAAC,EAAE,CAAC,SAAS,EAAE,eAAe,KAAK,IAAI,CAAC;IACzD;;;;;OAKG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;;OAGG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,CAAC;AAEF,gEAAgE;AAChE,wBAAgB,cAAc,CAAC,SAAS,EAAE,eAAe,GAAG;IAC1D,IAAI,EAAE,UAAU,CAAC;IACjB,KAAK,EAAE,WAAW,CAAC;CACpB,CAGA;AAED,4DAA4D;AAC5D,wBAAgB,aAAa,CAAC,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,WAAW,GAAG,eAAe,CAEnF;AASD,MAAM,MAAM,IAAI,GAAG;IACjB,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAC7B,UAAU,EAAE,IAAI,EAChB,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE;IACP,SAAS,EAAE,eAAe,CAAC;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,OAAO,CAAC;IACd,KAAK,EAAE,OAAO,CAAC;IACf,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,CAAC;CACxB,GACA;IAAE,SAAS,EAAE,eAAe,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAwD3D;AAmQH,QAAA,MAAM,MAAM,iDAAwC,CAAC;AACrD,KAAK,MAAM,GAAG,UAAU,CAAC,OAAO,MAAM,CAAC,CAAC;AACxC,eAAe,MAAM,CAAC"}
|