@strategicos/ui 0.8.0 → 0.9.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.
Files changed (33) hide show
  1. package/README.md +23 -8
  2. package/THIRD_PARTY_NOTICES.md +2 -2
  3. package/dist/components/date-input.d.ts +46 -0
  4. package/dist/components/date-input.d.ts.map +1 -0
  5. package/dist/components/date-input.js +202 -0
  6. package/dist/components/date-input.js.map +1 -0
  7. package/dist/components/date-picker-input.d.ts +49 -0
  8. package/dist/components/date-picker-input.d.ts.map +1 -0
  9. package/dist/components/date-picker-input.js +126 -0
  10. package/dist/components/date-picker-input.js.map +1 -0
  11. package/dist/components/date-time-picker.d.ts +27 -0
  12. package/dist/components/date-time-picker.d.ts.map +1 -0
  13. package/dist/components/date-time-picker.js +77 -0
  14. package/dist/components/date-time-picker.js.map +1 -0
  15. package/dist/components/dates.d.ts +94 -0
  16. package/dist/components/dates.d.ts.map +1 -0
  17. package/dist/components/dates.js +94 -0
  18. package/dist/components/dates.js.map +1 -0
  19. package/dist/components/time-input.d.ts +16 -0
  20. package/dist/components/time-input.d.ts.map +1 -0
  21. package/dist/components/time-input.js +18 -0
  22. package/dist/components/time-input.js.map +1 -0
  23. package/package.json +1 -1
  24. package/src/components/date-input.tsx +287 -0
  25. package/src/components/date-picker-input.tsx +287 -0
  26. package/src/components/date-time-picker.tsx +152 -0
  27. package/src/components/dates.tsx +274 -0
  28. package/src/components/time-input.tsx +34 -0
  29. package/dist/components/date-picker.d.ts +0 -78
  30. package/dist/components/date-picker.d.ts.map +0 -1
  31. package/dist/components/date-picker.js +0 -142
  32. package/dist/components/date-picker.js.map +0 -1
  33. package/src/components/date-picker.tsx +0 -414
@@ -0,0 +1,274 @@
1
+ "use client"
2
+
3
+ // Peças derivadas do DatePicker do Tremor (Apache-2.0) e modificadas pela
4
+ // Strategicos. Ver THIRD_PARTY_NOTICES.md.
5
+
6
+ import * as React from "react"
7
+ import { CalendarIcon, XIcon } from "lucide-react"
8
+ import type { Matcher } from "react-day-picker"
9
+
10
+ import { cn } from "../lib/utils.js"
11
+ import { Button } from "./button.js"
12
+ import { PopoverTrigger } from "./popover.js"
13
+ import { selectTriggerVariants } from "./select.js"
14
+
15
+ /**
16
+ * Utilitários dos campos de data (DateInput, DatePickerInput, DateTimePicker).
17
+ *
18
+ * Os valores seguem o Mantine 8: texto, nunca `Date`.
19
+ * - data: "AAAA-MM-DD" (como o <input type="date">)
20
+ * - data e hora: "AAAA-MM-DD HH:mm:ss"
21
+ * Sem fuso: 2026-10-15 é 15/10 em qualquer lugar. Um Date à meia-noite UTC
22
+ * vira o dia 14 no Brasil.
23
+ */
24
+
25
+ const DATE_RE = /^(\d{4})-(\d{2})-(\d{2})(?:[ T](\d{2}):(\d{2})(?::(\d{2}))?)?$/
26
+
27
+ /** "AAAA-MM-DD" ou "AAAA-MM-DD HH:mm[:ss]" → Date local. Vazio ou inválido →
28
+ * undefined. */
29
+ function parseDateValue(value: string | null | undefined): Date | undefined {
30
+ const m = value ? DATE_RE.exec(value) : null
31
+ if (!m) return undefined
32
+ const [y, mo, d, h = "0", mi = "0", s = "0"] = m.slice(1)
33
+ const date = new Date(Number(y), Number(mo) - 1, Number(d), Number(h), Number(mi), Number(s))
34
+ // 2026-02-31 não existe: o Date rolaria para março.
35
+ if (date.getMonth() !== Number(mo) - 1 || Number(h) > 23 || Number(mi) > 59 || Number(s) > 59) return undefined
36
+ return date
37
+ }
38
+
39
+ const pad = (n: number) => String(n).padStart(2, "0")
40
+
41
+ /** Date → "AAAA-MM-DD" (dia local). */
42
+ function toDateValue(date: Date): string {
43
+ return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}`
44
+ }
45
+
46
+ /** Date → "AAAA-MM-DD HH:mm:ss" (hora local). */
47
+ function toDateTimeValue(date: Date): string {
48
+ return `${toDateValue(date)} ${pad(date.getHours())}:${pad(date.getMinutes())}:${pad(date.getSeconds())}`
49
+ }
50
+
51
+ /** 15/10/2026 */
52
+ const formatDate = (date: Date) => date.toLocaleDateString("pt-BR")
53
+
54
+ /** 15/10/2026 14:30 */
55
+ const formatDateTime = (date: Date) => `${formatDate(date)} ${pad(date.getHours())}:${pad(date.getMinutes())}`
56
+
57
+ // ── Limites ───────────────────────────────────────────────────────────────────
58
+
59
+ function clampDate(date: Date, min?: Date, max?: Date) {
60
+ if (min && date < min) return min
61
+ if (max && date > max) return max
62
+ return date
63
+ }
64
+
65
+ /** Dias fora de [min, max] para o `disabled` do Calendar. */
66
+ function outOfRange(min?: Date, max?: Date): Matcher[] {
67
+ const m: Matcher[] = []
68
+ if (min) m.push({ before: min })
69
+ if (max) m.push({ after: max })
70
+ return m
71
+ }
72
+
73
+ /** Compara só o dia ("AAAA-MM-DD…" ordena como texto). */
74
+ function inRange(value: string, minDate?: string, maxDate?: string) {
75
+ const day = value.slice(0, 10)
76
+ return (!minDate || day >= minDate.slice(0, 10)) && (!maxDate || day <= maxDate.slice(0, 10))
77
+ }
78
+
79
+ // ── Peças comuns ──────────────────────────────────────────────────────────────
80
+
81
+ type FieldControlProps = {
82
+ id?: string
83
+ "aria-label"?: string
84
+ "aria-describedby"?: string
85
+ "aria-invalid"?: React.AriaAttributes["aria-invalid"]
86
+ }
87
+
88
+ /** Gatilho dos pickers: o visual do SelectTrigger, com ícone de calendário e,
89
+ * opcionalmente, um X para limpar. Vai dentro de um <Popover>. */
90
+ function PickerTrigger({
91
+ text,
92
+ placeholder,
93
+ open,
94
+ size = "default",
95
+ disabled,
96
+ clearable,
97
+ onClear,
98
+ className,
99
+ wrapperClassName,
100
+ slot,
101
+ controlProps,
102
+ }: {
103
+ text: string | null
104
+ placeholder: string
105
+ open: boolean
106
+ size?: "sm" | "default" | null
107
+ disabled?: boolean
108
+ clearable?: boolean
109
+ onClear: () => void
110
+ className?: string
111
+ wrapperClassName?: string
112
+ slot: string
113
+ controlProps: FieldControlProps
114
+ }) {
115
+ const showClear = clearable && !!text && !disabled
116
+
117
+ const trigger = (
118
+ <PopoverTrigger asChild disabled={disabled}>
119
+ <button
120
+ type="button"
121
+ aria-haspopup="dialog"
122
+ aria-expanded={open}
123
+ data-slot={slot}
124
+ data-size={size ?? "default"}
125
+ data-placeholder={text ? undefined : ""}
126
+ {...controlProps}
127
+ className={cn(
128
+ selectTriggerVariants({ size }),
129
+ "w-full min-w-0 cursor-pointer justify-start text-left tabular-nums",
130
+ showClear && "pr-9",
131
+ className
132
+ )}
133
+ >
134
+ <CalendarIcon className="text-muted-foreground" />
135
+ <span className="min-w-0 flex-1 truncate">{text ?? placeholder}</span>
136
+ </button>
137
+ </PopoverTrigger>
138
+ )
139
+
140
+ if (!clearable) return trigger
141
+ return (
142
+ <div data-slot={`${slot}-wrapper`} className={cn("relative w-full min-w-0", wrapperClassName)}>
143
+ {trigger}
144
+ {showClear && <ClearButton onClick={onClear} />}
145
+ </div>
146
+ )
147
+ }
148
+
149
+ /** X de limpar. Fica ao lado do gatilho, não dentro: botão dentro de botão não
150
+ * é HTML válido. */
151
+ function ClearButton({ onClick, className }: { onClick: () => void; className?: string }) {
152
+ return (
153
+ <button
154
+ type="button"
155
+ onClick={onClick}
156
+ aria-label="Limpar data"
157
+ className={cn(
158
+ "absolute inset-y-0 right-1.5 my-auto flex size-6 cursor-pointer items-center justify-center rounded text-muted-foreground outline-none hover:text-foreground focus-visible:ring-3 focus-visible:ring-ring/50",
159
+ className
160
+ )}
161
+ >
162
+ <XIcon className="size-4" />
163
+ </button>
164
+ )
165
+ }
166
+
167
+ /** Atalhos ao lado do calendário (no celular, uma faixa em cima). */
168
+ function PresetList<T>({
169
+ presets,
170
+ isActive,
171
+ isDisabled,
172
+ onSelect,
173
+ }: {
174
+ presets: { label: string; value: T }[]
175
+ isActive: (value: T) => boolean
176
+ isDisabled: (value: T) => boolean
177
+ onSelect: (value: T) => void
178
+ }) {
179
+ return (
180
+ <ul
181
+ data-slot="date-picker-presets"
182
+ className="flex gap-1 overflow-x-auto border-b border-border p-2 sm:w-40 sm:flex-col sm:overflow-visible sm:border-r sm:border-b-0"
183
+ >
184
+ {presets.map(p => (
185
+ <li key={p.label} className="shrink-0">
186
+ <button
187
+ type="button"
188
+ disabled={isDisabled(p.value)}
189
+ aria-pressed={isActive(p.value)}
190
+ onClick={() => onSelect(p.value)}
191
+ className="w-full cursor-pointer truncate rounded-md px-2.5 py-1.5 text-left text-sm whitespace-nowrap outline-none transition-colors hover:bg-accent hover:text-accent-foreground focus-visible:ring-3 focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 aria-pressed:bg-accent aria-pressed:font-medium"
192
+ >
193
+ {p.label}
194
+ </button>
195
+ </li>
196
+ ))}
197
+ </ul>
198
+ )
199
+ }
200
+
201
+ /** Rodapé do calendário: algo à esquerda (dica, hora) e, com
202
+ * `withApplyButton`, Cancelar e Aplicar à direita. Para texto de dica, use
203
+ * <PickerHint>; o rodapé não tinge o que vai nele (a hora é um campo). */
204
+ function PickerFooter({
205
+ children,
206
+ onCancel,
207
+ onApply,
208
+ applyDisabled,
209
+ }: {
210
+ children?: React.ReactNode
211
+ onCancel?: () => void
212
+ onApply?: () => void
213
+ applyDisabled?: boolean
214
+ }) {
215
+ return (
216
+ <div data-slot="date-picker-footer" className="flex flex-wrap items-center gap-2 border-t border-border p-3">
217
+ <div className="min-w-0 flex-1">{children}</div>
218
+ {onApply && (
219
+ <div className="flex shrink-0 gap-2">
220
+ <Button type="button" variant="ghost" onClick={onCancel}>Cancelar</Button>
221
+ <Button type="button" onClick={onApply} disabled={applyDisabled}>Aplicar</Button>
222
+ </div>
223
+ )}
224
+ </div>
225
+ )
226
+ }
227
+
228
+ function PickerHint({ children }: { children: React.ReactNode }) {
229
+ return <span aria-live="polite" className="text-xs text-muted-foreground">{children}</span>
230
+ }
231
+
232
+ /** Props comuns aos pickers (DatePickerInput e DateTimePicker). */
233
+ type PickerBaseProps = FieldControlProps & {
234
+ placeholder?: string
235
+ /** Primeiro dia que pode ser escolhido ("AAAA-MM-DD"). */
236
+ minDate?: string
237
+ /** Último dia que pode ser escolhido ("AAAA-MM-DD"). */
238
+ maxDate?: string
239
+ /** Um X no gatilho limpa o valor. */
240
+ clearable?: boolean
241
+ /** Rodapé com Cancelar e Aplicar: a escolha só vale ao aplicar, e fechar
242
+ * de outro jeito descarta. Sem ele, escolher já grava. */
243
+ withApplyButton?: boolean
244
+ /** Como o valor aparece no gatilho. */
245
+ valueFormatter?: (date: Date) => string
246
+ /** "dropdown" troca o título do mês por seletores de mês e ano. */
247
+ captionLayout?: "label" | "dropdown" | "dropdown-months" | "dropdown-years"
248
+ size?: "sm" | "default"
249
+ disabled?: boolean
250
+ /** Classes do gatilho. */
251
+ className?: string
252
+ /** Classes do invólucro, que só existe com `clearable`. */
253
+ wrapperClassName?: string
254
+ align?: "start" | "center" | "end"
255
+ onOpenChange?: (open: boolean) => void
256
+ }
257
+
258
+ export {
259
+ parseDateValue,
260
+ toDateValue,
261
+ toDateTimeValue,
262
+ formatDate,
263
+ formatDateTime,
264
+ clampDate,
265
+ outOfRange,
266
+ inRange,
267
+ PickerTrigger,
268
+ ClearButton,
269
+ PresetList,
270
+ PickerFooter,
271
+ PickerHint,
272
+ type FieldControlProps,
273
+ type PickerBaseProps,
274
+ }
@@ -0,0 +1,34 @@
1
+ "use client"
2
+
3
+ import * as React from "react"
4
+
5
+ import { cn } from "../lib/utils.js"
6
+ import { Input, type InputProps } from "./input.js"
7
+
8
+ /**
9
+ * Hora, como o TimeInput do Mantine: o <input type="time"> do navegador, no
10
+ * visual do Input. O valor é "HH:mm" (ou "HH:mm:ss" com `withSeconds`).
11
+ *
12
+ * <Field label="Horário"><TimeInput value={hora} onChange={e => setHora(e.target.value)} /></Field>
13
+ *
14
+ * O formato de 12 ou 24 horas segue o sistema do usuário — no Brasil, 24 horas.
15
+ * O relógio à direita é o do navegador (abre a lista de horas no Chrome).
16
+ */
17
+ function TimeInput({
18
+ withSeconds = false,
19
+ className,
20
+ ...props
21
+ }: Omit<InputProps, "type"> & {
22
+ withSeconds?: boolean
23
+ }) {
24
+ return (
25
+ <Input
26
+ type="time"
27
+ step={withSeconds ? 1 : 60}
28
+ className={cn("tabular-nums", className)}
29
+ {...props}
30
+ />
31
+ )
32
+ }
33
+
34
+ export { TimeInput }
@@ -1,78 +0,0 @@
1
- import * as React from "react";
2
- /** "AAAA-MM-DD" → Date local à meia-noite. Valor vazio ou inválido → undefined. */
3
- declare function parseDateValue(value: string | null | undefined): Date | undefined;
4
- /** Date → "AAAA-MM-DD" no dia local. */
5
- declare function toDateValue(date: Date): string;
6
- type FieldProps = {
7
- id?: string;
8
- "aria-label"?: string;
9
- "aria-describedby"?: string;
10
- "aria-invalid"?: React.AriaAttributes["aria-invalid"];
11
- };
12
- type CommonProps = FieldProps & {
13
- placeholder?: string;
14
- /** Primeiro dia que pode ser escolhido ("AAAA-MM-DD"). */
15
- minDate?: string;
16
- /** Último dia que pode ser escolhido ("AAAA-MM-DD"). */
17
- maxDate?: string;
18
- /** Um X no gatilho limpa o valor. */
19
- clearable?: boolean;
20
- /** Como a data aparece no gatilho. Padrão: dd/mm/aaaa. */
21
- formatValue?: (date: Date) => string;
22
- /** "dropdown" troca o título do mês por seletores de mês e ano. */
23
- captionLayout?: "label" | "dropdown" | "dropdown-months" | "dropdown-years";
24
- size?: "sm" | "default";
25
- disabled?: boolean;
26
- /** Classes do gatilho. */
27
- className?: string;
28
- /** Classes do invólucro, que só existe com `clearable`. */
29
- wrapperClassName?: string;
30
- align?: "start" | "center" | "end";
31
- onOpenChange?: (open: boolean) => void;
32
- };
33
- export type DatePreset = {
34
- label: string;
35
- value: string;
36
- };
37
- /**
38
- * Escolha de uma data num calendário, como o DatePickerInput do Mantine. Base:
39
- * o DatePicker do Tremor, no visual do kit (gatilho igual ao do Select).
40
- *
41
- * <Field label="Prazo">
42
- * <DatePicker value={prazo} onValueChange={setPrazo} minDate={inicio} clearable />
43
- * </Field>
44
- *
45
- * O valor é "AAAA-MM-DD" ou `null` (ver `parseDateValue`/`toDateValue`).
46
- * Escolher o dia já fecha. `presets` põe atalhos ao lado ("Hoje", "Fim do
47
- * mês"…); os que caem fora de `minDate`/`maxDate` ficam desabilitados.
48
- *
49
- * Teclado: o calendário abre com o foco no dia escolhido (ou hoje); setas
50
- * andam pelos dias, PageUp/PageDown pelos meses, Enter escolhe, Esc fecha.
51
- */
52
- declare function DatePicker({ value, onValueChange, placeholder, minDate, maxDate, clearable, presets, formatValue, captionLayout, size, disabled, className, wrapperClassName, align, onOpenChange, ...props }: CommonProps & {
53
- value: string | null;
54
- onValueChange: (value: string | null) => void;
55
- presets?: DatePreset[];
56
- }): React.JSX.Element;
57
- export type DateRangeValue = [string | null, string | null];
58
- export type DateRangePreset = {
59
- label: string;
60
- value: [string, string];
61
- };
62
- /**
63
- * Escolha de um período (início e fim) num calendário de dois meses — um só no
64
- * celular. Base: o DateRangePicker do Tremor, no visual do kit.
65
- *
66
- * <DateRangePicker value={[inicio, fim]} onValueChange={([i, f]) => { … }} />
67
- *
68
- * O primeiro clique marca o início e o segundo, o fim; aí fecha e grava. Se o
69
- * segundo dia vier antes do primeiro, os dois trocam de lugar. Fechar no meio
70
- * descarta o período começado e mantém o anterior.
71
- */
72
- declare function DateRangePicker({ value, onValueChange, placeholder, minDate, maxDate, clearable, presets, formatValue, captionLayout, size, disabled, className, wrapperClassName, align, onOpenChange, ...props }: CommonProps & {
73
- value: DateRangeValue;
74
- onValueChange: (value: DateRangeValue) => void;
75
- presets?: DateRangePreset[];
76
- }): React.JSX.Element;
77
- export { DatePicker, DateRangePicker, parseDateValue, toDateValue };
78
- //# sourceMappingURL=date-picker.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"date-picker.d.ts","sourceRoot":"","sources":["../../src/components/date-picker.tsx"],"names":[],"mappings":"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"}
@@ -1,142 +0,0 @@
1
- "use client";
2
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
- // Derivado do DatePicker do Tremor (Apache-2.0) e modificado pela Strategicos.
4
- // Ver THIRD_PARTY_NOTICES.md.
5
- import * as React from "react";
6
- import { CalendarIcon, XIcon } from "lucide-react";
7
- import { useIsMobile } from "../hooks/use-mobile.js";
8
- import { cn } from "../lib/utils.js";
9
- import { Calendar } from "./calendar.js";
10
- import { useFieldControl } from "./field.js";
11
- import { Popover, PopoverContent, PopoverTrigger } from "./popover.js";
12
- import { selectTriggerVariants } from "./select.js";
13
- // ── Valores ───────────────────────────────────────────────────────────────────
14
- // As datas entram e saem como "AAAA-MM-DD", como no Mantine 8 e no
15
- // <input type="date">: sem hora e sem fuso, 2026-10-15 é 15/10 em qualquer
16
- // lugar. Um Date à meia-noite UTC vira o dia 14 no Brasil.
17
- /** "AAAA-MM-DD" → Date local à meia-noite. Valor vazio ou inválido → undefined. */
18
- function parseDateValue(value) {
19
- const m = value ? /^(\d{4})-(\d{2})-(\d{2})$/.exec(value) : null;
20
- if (!m)
21
- return undefined;
22
- const date = new Date(Number(m[1]), Number(m[2]) - 1, Number(m[3]));
23
- // 2026-02-31 não existe: o Date rolaria para março.
24
- return date.getMonth() === Number(m[2]) - 1 ? date : undefined;
25
- }
26
- /** Date → "AAAA-MM-DD" no dia local. */
27
- function toDateValue(date) {
28
- const p = (n) => String(n).padStart(2, "0");
29
- return `${date.getFullYear()}-${p(date.getMonth() + 1)}-${p(date.getDate())}`;
30
- }
31
- const formatBR = (date) => date.toLocaleDateString("pt-BR");
32
- function clampDate(date, min, max) {
33
- if (min && date < min)
34
- return min;
35
- if (max && date > max)
36
- return max;
37
- return date;
38
- }
39
- function outOfRange(min, max) {
40
- const m = [];
41
- if (min)
42
- m.push({ before: min });
43
- if (max)
44
- m.push({ after: max });
45
- return m;
46
- }
47
- function inRange(value, minDate, maxDate) {
48
- return (!minDate || value >= minDate) && (!maxDate || value <= maxDate);
49
- }
50
- function PickerTrigger({ text, placeholder, open, size = "default", disabled, clearable, onClear, className, wrapperClassName, slot, controlProps, }) {
51
- const showClear = clearable && !!text && !disabled;
52
- const trigger = (_jsx(PopoverTrigger, { asChild: true, disabled: disabled, children: _jsxs("button", { type: "button", "aria-haspopup": "dialog", "aria-expanded": open, "data-slot": slot, "data-size": size, "data-placeholder": text ? undefined : "", ...controlProps, className: cn(selectTriggerVariants({ size }), "w-full min-w-0 cursor-pointer justify-start text-left tabular-nums", showClear && "pr-9", className), children: [_jsx(CalendarIcon, { className: "text-muted-foreground" }), _jsx("span", { className: "min-w-0 flex-1 truncate", children: text ?? placeholder })] }) }));
53
- if (!clearable)
54
- return trigger;
55
- return (_jsxs("div", { "data-slot": `${slot}-wrapper`, className: cn("relative w-full min-w-0", wrapperClassName), children: [trigger, showClear && (
56
- // Irmão do gatilho, não filho: botão dentro de botão não é HTML válido.
57
- _jsx("button", { type: "button", onClick: onClear, "aria-label": "Limpar data", className: "absolute inset-y-0 right-1.5 my-auto flex size-6 cursor-pointer items-center justify-center rounded text-muted-foreground outline-none hover:text-foreground focus-visible:ring-3 focus-visible:ring-ring/50", children: _jsx(XIcon, { className: "size-4" }) }))] }));
58
- }
59
- /** Atalhos ao lado do calendário (no celular, uma faixa em cima). */
60
- function PresetList({ presets, isActive, isDisabled, onSelect, }) {
61
- return (_jsx("ul", { "data-slot": "date-picker-presets", className: "flex gap-1 overflow-x-auto border-b border-border p-2 sm:w-40 sm:flex-col sm:overflow-visible sm:border-r sm:border-b-0", children: presets.map(p => (_jsx("li", { className: "shrink-0", children: _jsx("button", { type: "button", disabled: isDisabled(p.value), "aria-pressed": isActive(p.value), onClick: () => onSelect(p.value), className: "w-full cursor-pointer truncate rounded-md px-2.5 py-1.5 text-left text-sm whitespace-nowrap outline-none transition-colors hover:bg-accent hover:text-accent-foreground focus-visible:ring-3 focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 aria-pressed:bg-accent aria-pressed:font-medium", children: p.label }) }, p.label))) }));
62
- }
63
- /**
64
- * Escolha de uma data num calendário, como o DatePickerInput do Mantine. Base:
65
- * o DatePicker do Tremor, no visual do kit (gatilho igual ao do Select).
66
- *
67
- * <Field label="Prazo">
68
- * <DatePicker value={prazo} onValueChange={setPrazo} minDate={inicio} clearable />
69
- * </Field>
70
- *
71
- * O valor é "AAAA-MM-DD" ou `null` (ver `parseDateValue`/`toDateValue`).
72
- * Escolher o dia já fecha. `presets` põe atalhos ao lado ("Hoje", "Fim do
73
- * mês"…); os que caem fora de `minDate`/`maxDate` ficam desabilitados.
74
- *
75
- * Teclado: o calendário abre com o foco no dia escolhido (ou hoje); setas
76
- * andam pelos dias, PageUp/PageDown pelos meses, Enter escolhe, Esc fecha.
77
- */
78
- function DatePicker({ value, onValueChange, placeholder = "Selecione a data", minDate, maxDate, clearable = false, presets, formatValue = formatBR, captionLayout, size, disabled, className, wrapperClassName, align = "start", onOpenChange, ...props }) {
79
- const controlProps = useFieldControl(props, { withRequired: false });
80
- const [open, setOpen] = React.useState(false);
81
- const selected = parseDateValue(value);
82
- const min = parseDateValue(minDate);
83
- const max = parseDateValue(maxDate);
84
- function handleOpenChange(o) {
85
- setOpen(o);
86
- onOpenChange?.(o);
87
- }
88
- function pick(v) {
89
- onValueChange(v);
90
- handleOpenChange(false);
91
- }
92
- return (_jsxs(Popover, { open: open, onOpenChange: handleOpenChange, children: [_jsx(PickerTrigger, { slot: "date-picker-trigger", text: selected ? formatValue(selected) : null, placeholder: placeholder, open: open, size: size, disabled: disabled, clearable: clearable, onClear: () => onValueChange(null), className: className, wrapperClassName: wrapperClassName, controlProps: controlProps }), _jsxs(PopoverContent, { align: align, className: "flex w-auto max-w-[calc(100vw-2rem)] flex-col p-0 sm:flex-row",
93
- // O foco vai para o dia (autoFocus do calendário), não para o 1º botão.
94
- onOpenAutoFocus: e => e.preventDefault(), children: [presets && presets.length > 0 && (_jsx(PresetList, { presets: presets, isActive: v => v === value, isDisabled: v => !inRange(v, minDate, maxDate), onSelect: pick })), _jsx(Calendar, { mode: "single", required: true, autoFocus: true, selected: selected, onSelect: d => pick(toDateValue(d)), defaultMonth: selected ?? clampDate(new Date(), min, max), startMonth: min, endMonth: max, disabled: outOfRange(min, max), captionLayout: captionLayout })] })] }));
95
- }
96
- /**
97
- * Escolha de um período (início e fim) num calendário de dois meses — um só no
98
- * celular. Base: o DateRangePicker do Tremor, no visual do kit.
99
- *
100
- * <DateRangePicker value={[inicio, fim]} onValueChange={([i, f]) => { … }} />
101
- *
102
- * O primeiro clique marca o início e o segundo, o fim; aí fecha e grava. Se o
103
- * segundo dia vier antes do primeiro, os dois trocam de lugar. Fechar no meio
104
- * descarta o período começado e mantém o anterior.
105
- */
106
- function DateRangePicker({ value, onValueChange, placeholder = "Selecione o período", minDate, maxDate, clearable = false, presets, formatValue = formatBR, captionLayout, size, disabled, className, wrapperClassName, align = "start", onOpenChange, ...props }) {
107
- const controlProps = useFieldControl(props, { withRequired: false });
108
- const isMobile = useIsMobile();
109
- const [open, setOpen] = React.useState(false);
110
- // Início escolhido nesta abertura, à espera do fim.
111
- const [pendingFrom, setPendingFrom] = React.useState(null);
112
- const from = parseDateValue(value[0]);
113
- const to = parseDateValue(value[1]);
114
- const min = parseDateValue(minDate);
115
- const max = parseDateValue(maxDate);
116
- function handleOpenChange(o) {
117
- setOpen(o);
118
- setPendingFrom(null);
119
- onOpenChange?.(o);
120
- }
121
- function commit(range) {
122
- onValueChange(range);
123
- handleOpenChange(false);
124
- }
125
- function pickDay(day) {
126
- if (!pendingFrom) {
127
- setPendingFrom(day);
128
- return;
129
- }
130
- const [s, e] = day < pendingFrom ? [day, pendingFrom] : [pendingFrom, day];
131
- commit([toDateValue(s), toDateValue(e)]);
132
- }
133
- const text = from
134
- ? `${formatValue(from)} – ${to ? formatValue(to) : "…"}`
135
- : null;
136
- return (_jsxs(Popover, { open: open, onOpenChange: handleOpenChange, children: [_jsx(PickerTrigger, { slot: "date-range-picker-trigger", text: text, placeholder: placeholder, open: open, size: size, disabled: disabled, clearable: clearable, onClear: () => onValueChange([null, null]), className: className, wrapperClassName: wrapperClassName, controlProps: controlProps }), _jsxs(PopoverContent, { align: align, className: "flex w-auto max-w-[calc(100vw-2rem)] flex-col p-0 sm:flex-row", onOpenAutoFocus: e => e.preventDefault(), children: [presets && presets.length > 0 && (_jsx(PresetList, { presets: presets, isActive: v => v[0] === value[0] && v[1] === value[1], isDisabled: v => !inRange(v[0], minDate, maxDate) || !inRange(v[1], minDate, maxDate), onSelect: commit })), _jsxs("div", { className: "flex flex-col", children: [_jsx(Calendar, { mode: "range", autoFocus: true, numberOfMonths: isMobile ? 1 : 2,
137
- // O cálculo de intervalo é nosso (pickDay): o do DayPicker já
138
- // fecha um intervalo de um dia no primeiro clique.
139
- selected: pendingFrom ? { from: pendingFrom, to: undefined } : { from, to }, onSelect: (_, day) => pickDay(day), defaultMonth: from ?? clampDate(new Date(), min, max), startMonth: min, endMonth: max, disabled: outOfRange(min, max), captionLayout: captionLayout }), _jsx("p", { "aria-live": "polite", className: "border-t border-border px-3 py-2 text-xs text-muted-foreground", children: pendingFrom ? "Agora escolha o último dia." : "Escolha o primeiro dia." })] })] })] }));
140
- }
141
- export { DatePicker, DateRangePicker, parseDateValue, toDateValue };
142
- //# sourceMappingURL=date-picker.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"date-picker.js","sourceRoot":"","sources":["../../src/components/date-picker.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAA;;AAEZ,+EAA+E;AAC/E,8BAA8B;AAE9B,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,cAAc,CAAA;AAGlD,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAA;AACpD,OAAO,EAAE,EAAE,EAAE,MAAM,iBAAiB,CAAA;AACpC,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AACxC,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AAC5C,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AACtE,OAAO,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAA;AAEnD,iFAAiF;AACjF,mEAAmE;AACnE,2EAA2E;AAC3E,2DAA2D;AAE3D,mFAAmF;AACnF,SAAS,cAAc,CAAC,KAAgC;IACtD,MAAM,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,2BAA2B,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;IAChE,IAAI,CAAC,CAAC;QAAE,OAAO,SAAS,CAAA;IACxB,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;IACnE,oDAAoD;IACpD,OAAO,IAAI,CAAC,QAAQ,EAAE,KAAK,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAA;AAChE,CAAC;AAED,wCAAwC;AACxC,SAAS,WAAW,CAAC,IAAU;IAC7B,MAAM,CAAC,GAAG,CAAC,CAAS,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAA;IACnD,OAAO,GAAG,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,EAAE,CAAA;AAC/E,CAAC;AAED,MAAM,QAAQ,GAAG,CAAC,IAAU,EAAE,EAAE,CAAC,IAAI,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAA;AAEjE,SAAS,SAAS,CAAC,IAAU,EAAE,GAAU,EAAE,GAAU;IACnD,IAAI,GAAG,IAAI,IAAI,GAAG,GAAG;QAAE,OAAO,GAAG,CAAA;IACjC,IAAI,GAAG,IAAI,IAAI,GAAG,GAAG;QAAE,OAAO,GAAG,CAAA;IACjC,OAAO,IAAI,CAAA;AACb,CAAC;AAED,SAAS,UAAU,CAAC,GAAU,EAAE,GAAU;IACxC,MAAM,CAAC,GAAc,EAAE,CAAA;IACvB,IAAI,GAAG;QAAE,CAAC,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAA;IAChC,IAAI,GAAG;QAAE,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAA;IAC/B,OAAO,CAAC,CAAA;AACV,CAAC;AAED,SAAS,OAAO,CAAC,KAAa,EAAE,OAAgB,EAAE,OAAgB;IAChE,OAAO,CAAC,CAAC,OAAO,IAAI,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,OAAO,IAAI,KAAK,IAAI,OAAO,CAAC,CAAA;AACzE,CAAC;AAiCD,SAAS,aAAa,CAAC,EACrB,IAAI,EACJ,WAAW,EACX,IAAI,EACJ,IAAI,GAAG,SAAS,EAChB,QAAQ,EACR,SAAS,EACT,OAAO,EACP,SAAS,EACT,gBAAgB,EAChB,IAAI,EACJ,YAAY,GAab;IACC,MAAM,SAAS,GAAG,SAAS,IAAI,CAAC,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAA;IAElD,MAAM,OAAO,GAAG,CACd,KAAC,cAAc,IAAC,OAAO,QAAC,QAAQ,EAAE,QAAQ,YACxC,kBACE,IAAI,EAAC,QAAQ,mBACC,QAAQ,mBACP,IAAI,eACR,IAAI,eACJ,IAAI,sBACG,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,KACnC,YAAY,EAChB,SAAS,EAAE,EAAE,CACX,qBAAqB,CAAC,EAAE,IAAI,EAAE,CAAC,EAC/B,oEAAoE,EACpE,SAAS,IAAI,MAAM,EACnB,SAAS,CACV,aAED,KAAC,YAAY,IAAC,SAAS,EAAC,uBAAuB,GAAG,EAClD,eAAM,SAAS,EAAC,yBAAyB,YAAE,IAAI,IAAI,WAAW,GAAQ,IAC/D,GACM,CAClB,CAAA;IAED,IAAI,CAAC,SAAS;QAAE,OAAO,OAAO,CAAA;IAC9B,OAAO,CACL,4BAAgB,GAAG,IAAI,UAAU,EAAE,SAAS,EAAE,EAAE,CAAC,yBAAyB,EAAE,gBAAgB,CAAC,aAC1F,OAAO,EACP,SAAS,IAAI;YACZ,wEAAwE;YACxE,iBACE,IAAI,EAAC,QAAQ,EACb,OAAO,EAAE,OAAO,gBACL,aAAa,EACxB,SAAS,EAAC,8MAA8M,YAExN,KAAC,KAAK,IAAC,SAAS,EAAC,QAAQ,GAAG,GACrB,CACV,IACG,CACP,CAAA;AACH,CAAC;AAED,qEAAqE;AACrE,SAAS,UAAU,CAAI,EACrB,OAAO,EACP,QAAQ,EACR,UAAU,EACV,QAAQ,GAMT;IACC,OAAO,CACL,0BACY,qBAAqB,EAC/B,SAAS,EAAC,yHAAyH,YAElI,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAChB,aAAkB,SAAS,EAAC,UAAU,YACpC,iBACE,IAAI,EAAC,QAAQ,EACb,QAAQ,EAAE,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,kBACf,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,EAC/B,OAAO,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,EAChC,SAAS,EAAC,0TAA0T,YAEnU,CAAC,CAAC,KAAK,GACD,IATF,CAAC,CAAC,KAAK,CAUX,CACN,CAAC,GACC,CACN,CAAA;AACH,CAAC;AAMD;;;;;;;;;;;;;;GAcG;AACH,SAAS,UAAU,CAAC,EAClB,KAAK,EACL,aAAa,EACb,WAAW,GAAG,kBAAkB,EAChC,OAAO,EACP,OAAO,EACP,SAAS,GAAG,KAAK,EACjB,OAAO,EACP,WAAW,GAAG,QAAQ,EACtB,aAAa,EACb,IAAI,EACJ,QAAQ,EACR,SAAS,EACT,gBAAgB,EAChB,KAAK,GAAG,OAAO,EACf,YAAY,EACZ,GAAG,KAAK,EAKT;IACC,MAAM,YAAY,GAAG,eAAe,CAAC,KAAK,EAAE,EAAE,YAAY,EAAE,KAAK,EAAE,CAAC,CAAA;IACpE,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAA;IAC7C,MAAM,QAAQ,GAAG,cAAc,CAAC,KAAK,CAAC,CAAA;IACtC,MAAM,GAAG,GAAG,cAAc,CAAC,OAAO,CAAC,CAAA;IACnC,MAAM,GAAG,GAAG,cAAc,CAAC,OAAO,CAAC,CAAA;IAEnC,SAAS,gBAAgB,CAAC,CAAU;QAClC,OAAO,CAAC,CAAC,CAAC,CAAA;QACV,YAAY,EAAE,CAAC,CAAC,CAAC,CAAA;IACnB,CAAC;IAED,SAAS,IAAI,CAAC,CAAS;QACrB,aAAa,CAAC,CAAC,CAAC,CAAA;QAChB,gBAAgB,CAAC,KAAK,CAAC,CAAA;IACzB,CAAC;IAED,OAAO,CACL,MAAC,OAAO,IAAC,IAAI,EAAE,IAAI,EAAE,YAAY,EAAE,gBAAgB,aACjD,KAAC,aAAa,IACZ,IAAI,EAAC,qBAAqB,EAC1B,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,EAC7C,WAAW,EAAE,WAAW,EACxB,IAAI,EAAE,IAAI,EACV,IAAI,EAAE,IAAI,EACV,QAAQ,EAAE,QAAQ,EAClB,SAAS,EAAE,SAAS,EACpB,OAAO,EAAE,GAAG,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,EAClC,SAAS,EAAE,SAAS,EACpB,gBAAgB,EAAE,gBAAgB,EAClC,YAAY,EAAE,YAAY,GAC1B,EACF,MAAC,cAAc,IACb,KAAK,EAAE,KAAK,EACZ,SAAS,EAAC,+DAA+D;gBACzE,wEAAwE;gBACxE,eAAe,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,cAAc,EAAE,aAEvC,OAAO,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,IAAI,CAChC,KAAC,UAAU,IACT,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,KAAK,EAC1B,UAAU,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,EAC9C,QAAQ,EAAE,IAAI,GACd,CACH,EACD,KAAC,QAAQ,IACP,IAAI,EAAC,QAAQ,EACb,QAAQ,QACR,SAAS,QACT,QAAQ,EAAE,QAAQ,EAClB,QAAQ,EAAE,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,EACnC,YAAY,EAAE,QAAQ,IAAI,SAAS,CAAC,IAAI,IAAI,EAAE,EAAE,GAAG,EAAE,GAAG,CAAC,EACzD,UAAU,EAAE,GAAG,EACf,QAAQ,EAAE,GAAG,EACb,QAAQ,EAAE,UAAU,CAAC,GAAG,EAAE,GAAG,CAAC,EAC9B,aAAa,EAAE,aAAa,GAC5B,IACa,IACT,CACX,CAAA;AACH,CAAC;AAOD;;;;;;;;;GASG;AACH,SAAS,eAAe,CAAC,EACvB,KAAK,EACL,aAAa,EACb,WAAW,GAAG,qBAAqB,EACnC,OAAO,EACP,OAAO,EACP,SAAS,GAAG,KAAK,EACjB,OAAO,EACP,WAAW,GAAG,QAAQ,EACtB,aAAa,EACb,IAAI,EACJ,QAAQ,EACR,SAAS,EACT,gBAAgB,EAChB,KAAK,GAAG,OAAO,EACf,YAAY,EACZ,GAAG,KAAK,EAKT;IACC,MAAM,YAAY,GAAG,eAAe,CAAC,KAAK,EAAE,EAAE,YAAY,EAAE,KAAK,EAAE,CAAC,CAAA;IACpE,MAAM,QAAQ,GAAG,WAAW,EAAE,CAAA;IAC9B,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAA;IAC7C,oDAAoD;IACpD,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAc,IAAI,CAAC,CAAA;IAEvE,MAAM,IAAI,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAA;IACrC,MAAM,EAAE,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAA;IACnC,MAAM,GAAG,GAAG,cAAc,CAAC,OAAO,CAAC,CAAA;IACnC,MAAM,GAAG,GAAG,cAAc,CAAC,OAAO,CAAC,CAAA;IAEnC,SAAS,gBAAgB,CAAC,CAAU;QAClC,OAAO,CAAC,CAAC,CAAC,CAAA;QACV,cAAc,CAAC,IAAI,CAAC,CAAA;QACpB,YAAY,EAAE,CAAC,CAAC,CAAC,CAAA;IACnB,CAAC;IAED,SAAS,MAAM,CAAC,KAAuB;QACrC,aAAa,CAAC,KAAK,CAAC,CAAA;QACpB,gBAAgB,CAAC,KAAK,CAAC,CAAA;IACzB,CAAC;IAED,SAAS,OAAO,CAAC,GAAS;QACxB,IAAI,CAAC,WAAW,EAAE,CAAC;YAAC,cAAc,CAAC,GAAG,CAAC,CAAC;YAAC,OAAM;QAAC,CAAC;QACjD,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,GAAG,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,CAAC,CAAA;QAC1E,MAAM,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;IAC1C,CAAC;IAED,MAAM,IAAI,GAAG,IAAI;QACf,CAAC,CAAC,GAAG,WAAW,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE;QACxD,CAAC,CAAC,IAAI,CAAA;IAER,OAAO,CACL,MAAC,OAAO,IAAC,IAAI,EAAE,IAAI,EAAE,YAAY,EAAE,gBAAgB,aACjD,KAAC,aAAa,IACZ,IAAI,EAAC,2BAA2B,EAChC,IAAI,EAAE,IAAI,EACV,WAAW,EAAE,WAAW,EACxB,IAAI,EAAE,IAAI,EACV,IAAI,EAAE,IAAI,EACV,QAAQ,EAAE,QAAQ,EAClB,SAAS,EAAE,SAAS,EACpB,OAAO,EAAE,GAAG,EAAE,CAAC,aAAa,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,EAC1C,SAAS,EAAE,SAAS,EACpB,gBAAgB,EAAE,gBAAgB,EAClC,YAAY,EAAE,YAAY,GAC1B,EACF,MAAC,cAAc,IACb,KAAK,EAAE,KAAK,EACZ,SAAS,EAAC,+DAA+D,EACzE,eAAe,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,cAAc,EAAE,aAEvC,OAAO,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,IAAI,CAChC,KAAC,UAAU,IACT,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC,EACrD,UAAU,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,EACrF,QAAQ,EAAE,MAAM,GAChB,CACH,EACD,eAAK,SAAS,EAAC,eAAe,aAC5B,KAAC,QAAQ,IACP,IAAI,EAAC,OAAO,EACZ,SAAS,QACT,cAAc,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;gCAChC,8DAA8D;gCAC9D,mDAAmD;gCACnD,QAAQ,EAAE,WAAW,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,EAC3E,QAAQ,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,EAClC,YAAY,EAAE,IAAI,IAAI,SAAS,CAAC,IAAI,IAAI,EAAE,EAAE,GAAG,EAAE,GAAG,CAAC,EACrD,UAAU,EAAE,GAAG,EACf,QAAQ,EAAE,GAAG,EACb,QAAQ,EAAE,UAAU,CAAC,GAAG,EAAE,GAAG,CAAC,EAC9B,aAAa,EAAE,aAAa,GAC5B,EACF,yBAAa,QAAQ,EAAC,SAAS,EAAC,gEAAgE,YAC7F,WAAW,CAAC,CAAC,CAAC,6BAA6B,CAAC,CAAC,CAAC,yBAAyB,GACtE,IACA,IACS,IACT,CACX,CAAA;AACH,CAAC;AAED,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,cAAc,EAAE,WAAW,EAAE,CAAA"}