@alfadocs/ui-kit-debug 1.33.0 → 1.35.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/_chunks/appointment-card-Bh_CIlc6.js +431 -0
- package/dist/_chunks/appointment-card-Bh_CIlc6.js.map +1 -0
- package/dist/_chunks/appointment-timeline-De-Wqdkw.js +449 -0
- package/dist/_chunks/appointment-timeline-De-Wqdkw.js.map +1 -0
- package/dist/_chunks/{appointment-tray-DCk8gHod.js → appointment-tray-4I9wTAi4.js} +2 -2
- package/dist/_chunks/{appointment-tray-DCk8gHod.js.map → appointment-tray-4I9wTAi4.js.map} +1 -1
- package/dist/_chunks/{calendar-workspace-BX-zDyVR.js → calendar-workspace-UywR5gUl.js} +7 -7
- package/dist/_chunks/{calendar-workspace-BX-zDyVR.js.map → calendar-workspace-UywR5gUl.js.map} +1 -1
- package/dist/_chunks/{care-plan-card-CZW476Kg.js → care-plan-card-DHVhBcvs.js} +3 -3
- package/dist/_chunks/{care-plan-card-CZW476Kg.js.map → care-plan-card-DHVhBcvs.js.map} +1 -1
- package/dist/_chunks/{care-plan-entry-card-BMUYagEw.js → care-plan-entry-card-Dx6IdTcR.js} +2 -2
- package/dist/_chunks/{care-plan-entry-card-BMUYagEw.js.map → care-plan-entry-card-Dx6IdTcR.js.map} +1 -1
- package/dist/_chunks/{care-plan-header-B5CBE0zu.js → care-plan-header-UTX5ZD74.js} +2 -2
- package/dist/_chunks/{care-plan-header-B5CBE0zu.js.map → care-plan-header-UTX5ZD74.js.map} +1 -1
- package/dist/_chunks/{clinical-note-card-D2WTV2CO.js → clinical-note-card-CTRzmqvv.js} +83 -81
- package/dist/_chunks/clinical-note-card-CTRzmqvv.js.map +1 -0
- package/dist/_chunks/{contact-profile-card-BZqi8Hck.js → contact-profile-card-DSI9uumA.js} +17 -16
- package/dist/_chunks/{contact-profile-card-BZqi8Hck.js.map → contact-profile-card-DSI9uumA.js.map} +1 -1
- package/dist/_chunks/{control-room-rail-iO_BCaq1.js → control-room-rail-5MbhjsxN.js} +2 -2
- package/dist/_chunks/{control-room-rail-iO_BCaq1.js.map → control-room-rail-5MbhjsxN.js.map} +1 -1
- package/dist/_chunks/{entity-card-DmrgYSEX.js → entity-card-9_62gY7l.js} +4 -4
- package/dist/_chunks/{entity-card-DmrgYSEX.js.map → entity-card-9_62gY7l.js.map} +1 -1
- package/dist/_chunks/format-price-BkMEbeW3.js +47 -0
- package/dist/_chunks/format-price-BkMEbeW3.js.map +1 -0
- package/dist/_chunks/{format-price-DNqXPa_q.js → languages-CZqBaPwI.js} +8 -38
- package/dist/_chunks/languages-CZqBaPwI.js.map +1 -0
- package/dist/_chunks/money.agent-Dw55UxUA.js +116 -0
- package/dist/_chunks/money.agent-Dw55UxUA.js.map +1 -0
- package/dist/_chunks/notes-panel-BjLt-kiP.js +469 -0
- package/dist/_chunks/notes-panel-BjLt-kiP.js.map +1 -0
- package/dist/_chunks/{operator-hero-D7-iiFQ9.js → operator-hero-aG_qyn6g.js} +2 -2
- package/dist/_chunks/{operator-hero-D7-iiFQ9.js.map → operator-hero-aG_qyn6g.js.map} +1 -1
- package/dist/_chunks/{payment-request-card-lmKLwsDs.js → payment-request-card-DvEsWEkC.js} +2 -2
- package/dist/_chunks/{payment-request-card-lmKLwsDs.js.map → payment-request-card-DvEsWEkC.js.map} +1 -1
- package/dist/_chunks/{practice-results-DjEzPgAK.js → practice-results-kayDEorM.js} +15 -14
- package/dist/_chunks/{practice-results-DjEzPgAK.js.map → practice-results-kayDEorM.js.map} +1 -1
- package/dist/_chunks/{rich-text-editor-CQ7yZdG3.js → rich-text-editor-CCI-Y3DN.js} +3 -5
- package/dist/_chunks/rich-text-editor-CCI-Y3DN.js.map +1 -0
- package/dist/_chunks/{task-card-BUgK6yZT.js → task-card-BalrLkSz.js} +41 -40
- package/dist/_chunks/task-card-BalrLkSz.js.map +1 -0
- package/dist/_chunks/{task-tray-CYG6rj2s.js → task-tray-COo-RlDv.js} +2 -2
- package/dist/_chunks/{task-tray-CYG6rj2s.js.map → task-tray-COo-RlDv.js.map} +1 -1
- package/dist/_chunks/tasks-panel-DLKpSNoE.js +844 -0
- package/dist/_chunks/tasks-panel-DLKpSNoE.js.map +1 -0
- package/dist/_chunks/tool-rail-ONaV-Nzz.js +588 -0
- package/dist/_chunks/tool-rail-ONaV-Nzz.js.map +1 -0
- package/dist/_chunks/use-check-animation--I3cS00X.js +28 -0
- package/dist/_chunks/use-check-animation--I3cS00X.js.map +1 -0
- package/dist/_chunks/use-list-reflow-Cw43nxw5.js +100 -0
- package/dist/_chunks/use-list-reflow-Cw43nxw5.js.map +1 -0
- package/dist/agent-catalog.json +15 -1
- package/dist/components/_shared/format-price.d.ts +15 -0
- package/dist/components/_shared/format-price.d.ts.map +1 -1
- package/dist/components/appointment-card/appointment-card.d.ts +36 -1
- package/dist/components/appointment-card/appointment-card.d.ts.map +1 -1
- package/dist/components/appointment-card/index.js +2 -2
- package/dist/components/appointment-timeline/appointment-timeline.d.ts +6 -0
- package/dist/components/appointment-timeline/appointment-timeline.d.ts.map +1 -1
- package/dist/components/appointment-timeline/index.js +1 -1
- package/dist/components/care-plan-card/index.js +1 -1
- package/dist/components/care-plan-entry-card/index.js +1 -1
- package/dist/components/care-plan-header/index.js +1 -1
- package/dist/components/clinical-note-card/clinical-note-card.d.ts +8 -1
- package/dist/components/clinical-note-card/clinical-note-card.d.ts.map +1 -1
- package/dist/components/clinical-note-card/index.js +1 -1
- package/dist/components/command-palette/command-palette.d.ts +7 -7
- package/dist/components/contact-profile-card/index.js +1 -1
- package/dist/components/control-room-rail/index.js +1 -1
- package/dist/components/index.d.ts +1 -0
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/money/index.d.ts +4 -0
- package/dist/components/money/index.d.ts.map +1 -0
- package/dist/components/money/index.js +6 -0
- package/dist/components/money/index.js.map +1 -0
- package/dist/components/money/money.agent.d.ts +3 -0
- package/dist/components/money/money.agent.d.ts.map +1 -0
- package/dist/components/money/money.d.ts +38 -0
- package/dist/components/money/money.d.ts.map +1 -0
- package/dist/components/notes-panel/index.js +1 -1
- package/dist/components/notes-panel/notes-panel.d.ts +16 -1
- package/dist/components/notes-panel/notes-panel.d.ts.map +1 -1
- package/dist/components/operator-hero/index.js +1 -1
- package/dist/components/payment-card/index.js +1 -1
- package/dist/components/practice-results/index.js +1 -1
- package/dist/components/rich-text-editor/help-me-write-overlay.d.ts.map +1 -1
- package/dist/components/rich-text-editor/index.js +1 -1
- package/dist/components/rich-text-editor/rich-text-editor.d.ts +1 -1
- package/dist/components/rich-text-editor/rich-text-editor.d.ts.map +1 -1
- package/dist/components/task-card/index.js +1 -1
- package/dist/components/task-card/task-card.d.ts +11 -3
- package/dist/components/task-card/task-card.d.ts.map +1 -1
- package/dist/components/task-tray/index.js +1 -1
- package/dist/components/tasks-panel/index.js +1 -1
- package/dist/components/tasks-panel/tasks-panel.d.ts +1 -1
- package/dist/components/tasks-panel/tasks-panel.d.ts.map +1 -1
- package/dist/components/tool-rail/index.js +1 -1
- package/dist/components/tool-rail/tool-rail.d.ts.map +1 -1
- package/dist/hooks/index.d.ts +3 -0
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/index.js +43 -37
- package/dist/hooks/index.js.map +1 -1
- package/dist/hooks/use-check-animation.d.ts +53 -0
- package/dist/hooks/use-check-animation.d.ts.map +1 -0
- package/dist/hooks/use-exit-transition.d.ts +48 -0
- package/dist/hooks/use-exit-transition.d.ts.map +1 -0
- package/dist/hooks/use-list-reflow.d.ts +47 -0
- package/dist/hooks/use-list-reflow.d.ts.map +1 -0
- package/dist/host-compat.css +8 -2
- package/dist/i18n/locales/ar.d.ts +10 -0
- package/dist/i18n/locales/ar.d.ts.map +1 -1
- package/dist/i18n/locales/ar.js +12 -2
- package/dist/i18n/locales/ar.js.map +1 -1
- package/dist/i18n/locales/de.d.ts +10 -0
- package/dist/i18n/locales/de.d.ts.map +1 -1
- package/dist/i18n/locales/de.js +12 -2
- package/dist/i18n/locales/de.js.map +1 -1
- package/dist/i18n/locales/el.d.ts +10 -0
- package/dist/i18n/locales/el.d.ts.map +1 -1
- package/dist/i18n/locales/el.js +12 -2
- package/dist/i18n/locales/el.js.map +1 -1
- package/dist/i18n/locales/en.d.ts +10 -0
- package/dist/i18n/locales/en.d.ts.map +1 -1
- package/dist/i18n/locales/en.js +12 -2
- package/dist/i18n/locales/en.js.map +1 -1
- package/dist/i18n/locales/es.d.ts +10 -0
- package/dist/i18n/locales/es.d.ts.map +1 -1
- package/dist/i18n/locales/es.js +12 -2
- package/dist/i18n/locales/es.js.map +1 -1
- package/dist/i18n/locales/fr.d.ts +10 -0
- package/dist/i18n/locales/fr.d.ts.map +1 -1
- package/dist/i18n/locales/fr.js +12 -2
- package/dist/i18n/locales/fr.js.map +1 -1
- package/dist/i18n/locales/hi.d.ts +10 -0
- package/dist/i18n/locales/hi.d.ts.map +1 -1
- package/dist/i18n/locales/hi.js +12 -2
- package/dist/i18n/locales/hi.js.map +1 -1
- package/dist/i18n/locales/it.d.ts +13 -3
- package/dist/i18n/locales/it.d.ts.map +1 -1
- package/dist/i18n/locales/it.js +14 -4
- package/dist/i18n/locales/it.js.map +1 -1
- package/dist/i18n/locales/ja.d.ts +10 -0
- package/dist/i18n/locales/ja.d.ts.map +1 -1
- package/dist/i18n/locales/ja.js +12 -2
- package/dist/i18n/locales/ja.js.map +1 -1
- package/dist/i18n/locales/nl.d.ts +10 -0
- package/dist/i18n/locales/nl.d.ts.map +1 -1
- package/dist/i18n/locales/nl.js +12 -2
- package/dist/i18n/locales/nl.js.map +1 -1
- package/dist/i18n/locales/pl.d.ts +10 -0
- package/dist/i18n/locales/pl.d.ts.map +1 -1
- package/dist/i18n/locales/pl.js +12 -2
- package/dist/i18n/locales/pl.js.map +1 -1
- package/dist/i18n/locales/pt.d.ts +10 -0
- package/dist/i18n/locales/pt.d.ts.map +1 -1
- package/dist/i18n/locales/pt.js +12 -2
- package/dist/i18n/locales/pt.js.map +1 -1
- package/dist/i18n/locales/ro.d.ts +10 -0
- package/dist/i18n/locales/ro.d.ts.map +1 -1
- package/dist/i18n/locales/ro.js +12 -2
- package/dist/i18n/locales/ro.js.map +1 -1
- package/dist/i18n/locales/ru.d.ts +10 -0
- package/dist/i18n/locales/ru.d.ts.map +1 -1
- package/dist/i18n/locales/ru.js +12 -2
- package/dist/i18n/locales/ru.js.map +1 -1
- package/dist/i18n/locales/sq.d.ts +10 -0
- package/dist/i18n/locales/sq.d.ts.map +1 -1
- package/dist/i18n/locales/sq.js +12 -2
- package/dist/i18n/locales/sq.js.map +1 -1
- package/dist/i18n/locales/sv.d.ts +10 -0
- package/dist/i18n/locales/sv.d.ts.map +1 -1
- package/dist/i18n/locales/sv.js +12 -2
- package/dist/i18n/locales/sv.js.map +1 -1
- package/dist/i18n/locales/tr.d.ts +10 -0
- package/dist/i18n/locales/tr.d.ts.map +1 -1
- package/dist/i18n/locales/tr.js +12 -2
- package/dist/i18n/locales/tr.js.map +1 -1
- package/dist/i18n/locales/zh.d.ts +10 -0
- package/dist/i18n/locales/zh.d.ts.map +1 -1
- package/dist/i18n/locales/zh.js +12 -2
- package/dist/i18n/locales/zh.js.map +1 -1
- package/dist/index.js +919 -916
- package/dist/index.js.map +1 -1
- package/dist/locales/ar.json +12 -2
- package/dist/locales/de.json +12 -2
- package/dist/locales/el.json +12 -2
- package/dist/locales/en.json +12 -2
- package/dist/locales/es.json +12 -2
- package/dist/locales/fr.json +12 -2
- package/dist/locales/hi.json +12 -2
- package/dist/locales/it.json +14 -4
- package/dist/locales/ja.json +12 -2
- package/dist/locales/nl.json +12 -2
- package/dist/locales/pl.json +12 -2
- package/dist/locales/pt.json +12 -2
- package/dist/locales/ro.json +12 -2
- package/dist/locales/ru.json +12 -2
- package/dist/locales/sq.json +12 -2
- package/dist/locales/sv.json +12 -2
- package/dist/locales/tr.json +12 -2
- package/dist/locales/zh.json +12 -2
- package/dist/patterns/calendar/index.js +1 -1
- package/dist/tokens.css +2 -1
- package/package.json +5 -1
- package/dist/_chunks/appointment-card-D-oj_ugh.js +0 -296
- package/dist/_chunks/appointment-card-D-oj_ugh.js.map +0 -1
- package/dist/_chunks/appointment-timeline-CymGHyIP.js +0 -403
- package/dist/_chunks/appointment-timeline-CymGHyIP.js.map +0 -1
- package/dist/_chunks/clinical-note-card-D2WTV2CO.js.map +0 -1
- package/dist/_chunks/format-price-DNqXPa_q.js.map +0 -1
- package/dist/_chunks/notes-panel-C4G-mhZ9.js +0 -380
- package/dist/_chunks/notes-panel-C4G-mhZ9.js.map +0 -1
- package/dist/_chunks/rich-text-editor-CQ7yZdG3.js.map +0 -1
- package/dist/_chunks/task-card-BUgK6yZT.js.map +0 -1
- package/dist/_chunks/tasks-panel-DQuaVvl5.js +0 -757
- package/dist/_chunks/tasks-panel-DQuaVvl5.js.map +0 -1
- package/dist/_chunks/tool-rail-8Scslq3X.js +0 -524
- package/dist/_chunks/tool-rail-8Scslq3X.js.map +0 -1
|
@@ -1,403 +0,0 @@
|
|
|
1
|
-
import { jsxs as S, jsx as o, Fragment as ke } from "react/jsx-runtime";
|
|
2
|
-
import { forwardRef as be, useId as Te, useMemo as F, useRef as T, useState as Z, useCallback as x, useImperativeHandle as xe } from "react";
|
|
3
|
-
import { c as De } from "./index-D2ZczOXr.js";
|
|
4
|
-
import { useTranslation as we } from "react-i18next";
|
|
5
|
-
import { A as Re } from "./appointment-card-D-oj_ugh.js";
|
|
6
|
-
import { B as A } from "./button-nJaPh_HC.js";
|
|
7
|
-
import { B as Ie } from "./button-group-CaxRJsNG.js";
|
|
8
|
-
import { D as Se } from "./date-picker-B6NW_PS5.js";
|
|
9
|
-
import { P as je } from "./panel-header-D313n_9-.js";
|
|
10
|
-
import { S as Ce } from "./skeleton-CZbwyJAA.js";
|
|
11
|
-
import { E as He } from "./empty-state-X0sVPfVo.js";
|
|
12
|
-
import { u as O } from "./use-isomorphic-layout-effect-BGfaCOP1.js";
|
|
13
|
-
import { u as Fe } from "./use-prefers-reduced-motion-BMwIQRjB.js";
|
|
14
|
-
import { u as Me } from "./registry-DvAUVLHh.js";
|
|
15
|
-
import { C as Ne } from "./calendar-days-BGWklvE-.js";
|
|
16
|
-
const _e = {
|
|
17
|
-
id: "appointment-timeline",
|
|
18
|
-
// 'pick' backs select_item (non-persisting activation through
|
|
19
|
-
// onOpenAppointment); 'scroll' backs jump_to_today, which re-anchors the
|
|
20
|
-
// scroll viewport (mirrors practice-results' scroll_to_result).
|
|
21
|
-
capabilities: ["scroll", "pick"],
|
|
22
|
-
state: {
|
|
23
|
-
items: {
|
|
24
|
-
type: "Array<{ id: string; state: string }>",
|
|
25
|
-
descriptionKey: "ui.agent.appointmentTimeline.state.items",
|
|
26
|
-
description: "Currently-rendered appointments. Ids + lifecycle state only — never patient identity.",
|
|
27
|
-
read: (n) => n.getItems()
|
|
28
|
-
}
|
|
29
|
-
},
|
|
30
|
-
actions: {
|
|
31
|
-
select_item: {
|
|
32
|
-
safety: "read",
|
|
33
|
-
argsType: "{ id: string }",
|
|
34
|
-
argsSchema: {
|
|
35
|
-
type: "object",
|
|
36
|
-
properties: { id: { type: "string" } },
|
|
37
|
-
required: ["id"]
|
|
38
|
-
},
|
|
39
|
-
idempotent: !0,
|
|
40
|
-
descriptionKey: "ui.agent.appointmentTimeline.actions.selectItem",
|
|
41
|
-
description: "Activate the appointment with the given id.",
|
|
42
|
-
invoke: (n, i) => {
|
|
43
|
-
n.selectItem(i.id);
|
|
44
|
-
}
|
|
45
|
-
},
|
|
46
|
-
jump_to_today: {
|
|
47
|
-
safety: "read",
|
|
48
|
-
idempotent: !0,
|
|
49
|
-
descriptionKey: "ui.agent.appointmentTimeline.actions.jumpToToday",
|
|
50
|
-
description: "Re-anchor the timeline scroll on today's appointments.",
|
|
51
|
-
invoke: (n) => {
|
|
52
|
-
n.jumpToToday();
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
},
|
|
56
|
-
domHooks: {
|
|
57
|
-
root: {
|
|
58
|
-
attr: "data-component",
|
|
59
|
-
value: "appointment-timeline",
|
|
60
|
-
description: "Marks the AppointmentTimeline wrapper."
|
|
61
|
-
},
|
|
62
|
-
instanceId: {
|
|
63
|
-
attr: "data-component-id",
|
|
64
|
-
sourceProp: "id",
|
|
65
|
-
description: "Sourced from the id prop. Required to address a specific timeline from the agent."
|
|
66
|
-
},
|
|
67
|
-
item: {
|
|
68
|
-
attr: "data-appointment-id",
|
|
69
|
-
description: "Stable appointment id emitted on each rendered AppointmentCard inside the timeline."
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
}, L = 96, ze = De(
|
|
73
|
-
[
|
|
74
|
-
"ds:flex ds:flex-col ds:h-full ds:min-h-0",
|
|
75
|
-
"ds:bg-[color:var(--card)] ds:text-[color:var(--card-foreground)]"
|
|
76
|
-
].join(" "),
|
|
77
|
-
{ variants: { size: { sm: "", md: "" } }, defaultVariants: { size: "sm" } }
|
|
78
|
-
), Be = [
|
|
79
|
-
"ds:flex-1 ds:min-h-0 ds:overflow-y-auto",
|
|
80
|
-
"ds:flex ds:flex-col ds:gap-[var(--spacing-sm)]",
|
|
81
|
-
"ds:px-[var(--spacing-sm)] ds:py-[var(--spacing-xs)]",
|
|
82
|
-
"ds:[--atl-mask-top:black] ds:[--atl-mask-bottom:black]",
|
|
83
|
-
"ds:data-[fade-top=true]:[--atl-mask-top:transparent]",
|
|
84
|
-
"ds:data-[fade-bottom=true]:[--atl-mask-bottom:transparent]",
|
|
85
|
-
"ds:[mask-image:linear-gradient(to_bottom,var(--atl-mask-top)_0,black_var(--atl-fade-distance,var(--spacing-lg)),black_calc(100%-var(--atl-fade-distance,var(--spacing-lg))),var(--atl-mask-bottom)_100%)]",
|
|
86
|
-
"ds:motion-reduce:[mask-image:none]",
|
|
87
|
-
"ds:[.theme-accessible_&]:[mask-image:none]",
|
|
88
|
-
"ds:forced-colors:[mask-image:none]",
|
|
89
|
-
"ds:focus-visible:outline-[length:var(--focus-ring-width)] ds:focus-visible:outline-solid",
|
|
90
|
-
"ds:focus-visible:outline-[color:var(--ring)] ds:focus-visible:[outline-offset:-2px]",
|
|
91
|
-
"ds:forced-colors:focus-visible:outline-[CanvasText]"
|
|
92
|
-
].join(" ");
|
|
93
|
-
function y(n) {
|
|
94
|
-
const i = `${n.getMonth() + 1}`.padStart(2, "0"), l = `${n.getDate()}`.padStart(2, "0");
|
|
95
|
-
return `${n.getFullYear()}-${i}-${l}`;
|
|
96
|
-
}
|
|
97
|
-
function Ke(n) {
|
|
98
|
-
const i = [...n].sort(
|
|
99
|
-
(u, m) => +new Date(u.startIso) - +new Date(m.startIso)
|
|
100
|
-
), l = /* @__PURE__ */ new Map();
|
|
101
|
-
for (const u of i) {
|
|
102
|
-
const m = new Date(u.startIso), h = y(m);
|
|
103
|
-
let c = l.get(h);
|
|
104
|
-
c || (c = {
|
|
105
|
-
key: h,
|
|
106
|
-
date: new Date(m.getFullYear(), m.getMonth(), m.getDate()),
|
|
107
|
-
items: []
|
|
108
|
-
}, l.set(h, c)), c.items.push(u);
|
|
109
|
-
}
|
|
110
|
-
return [...l.values()];
|
|
111
|
-
}
|
|
112
|
-
const Ae = be(
|
|
113
|
-
({
|
|
114
|
-
id: n,
|
|
115
|
-
items: i,
|
|
116
|
-
nowIso: l,
|
|
117
|
-
title: u,
|
|
118
|
-
locale: m,
|
|
119
|
-
currency: h,
|
|
120
|
-
size: c = "sm",
|
|
121
|
-
showPatient: M = !1,
|
|
122
|
-
onOpenAppointment: f,
|
|
123
|
-
onLoadEarlier: v,
|
|
124
|
-
onLoadLater: p,
|
|
125
|
-
hasMoreEarlier: k,
|
|
126
|
-
hasMoreLater: N,
|
|
127
|
-
loadingEarlier: j = !1,
|
|
128
|
-
loadingLater: C = !1,
|
|
129
|
-
showFilters: J = !0,
|
|
130
|
-
onJumpToDate: H,
|
|
131
|
-
emptyTitle: ee,
|
|
132
|
-
emptyDescription: te,
|
|
133
|
-
className: se,
|
|
134
|
-
"aria-label": ne,
|
|
135
|
-
...ie
|
|
136
|
-
}, oe) => {
|
|
137
|
-
const { t: a, i18n: ae } = we(), Y = Te(), P = Fe(), $ = m ?? ae.language, E = u ?? a("appointmentTimeline.title"), r = F(
|
|
138
|
-
() => l ? new Date(l) : /* @__PURE__ */ new Date(),
|
|
139
|
-
[l]
|
|
140
|
-
), g = F(() => Ke(i), [i]), q = k ?? !!v, G = N ?? !!p, _ = F(() => {
|
|
141
|
-
if (g.length === 0) return;
|
|
142
|
-
const e = y(r), t = g.map((s) => s.key);
|
|
143
|
-
return t.includes(e) ? e : t.find((s) => s >= e) ?? t[t.length - 1];
|
|
144
|
-
}, [g, r]), D = T(null), w = T(/* @__PURE__ */ new Map()), V = T(!1), z = T(void 0), W = T(0), [re, le] = Z(!1), [ce, de] = Z(!1), R = x(() => {
|
|
145
|
-
const e = D.current;
|
|
146
|
-
if (!e) return;
|
|
147
|
-
const { scrollTop: t, scrollHeight: s, clientHeight: d } = e;
|
|
148
|
-
le(t > 1), de(t + d < s - 1);
|
|
149
|
-
}, []), I = x(
|
|
150
|
-
(e, t) => {
|
|
151
|
-
const s = D.current;
|
|
152
|
-
if (!s) return;
|
|
153
|
-
let d = w.current.get(e);
|
|
154
|
-
if (!d) {
|
|
155
|
-
const K = [...w.current.keys()].sort(), X = K.find((ve) => ve >= e) ?? K[K.length - 1];
|
|
156
|
-
d = X ? w.current.get(X) : void 0;
|
|
157
|
-
}
|
|
158
|
-
if (!d) return;
|
|
159
|
-
const he = d.getBoundingClientRect().top - s.getBoundingClientRect().top;
|
|
160
|
-
s.scrollTo({
|
|
161
|
-
top: s.scrollTop + he,
|
|
162
|
-
behavior: t && !P ? "smooth" : "auto"
|
|
163
|
-
});
|
|
164
|
-
},
|
|
165
|
-
[P]
|
|
166
|
-
);
|
|
167
|
-
O(() => {
|
|
168
|
-
var s;
|
|
169
|
-
const e = D.current;
|
|
170
|
-
if (!e) return;
|
|
171
|
-
const t = (s = g[0]) == null ? void 0 : s.key;
|
|
172
|
-
if (!V.current)
|
|
173
|
-
g.length > 0 && _ && (I(_, !1), V.current = !0);
|
|
174
|
-
else if (z.current && t && t < z.current) {
|
|
175
|
-
const d = e.scrollHeight - W.current;
|
|
176
|
-
d > 0 && (e.scrollTop += d);
|
|
177
|
-
}
|
|
178
|
-
z.current = t, W.current = e.scrollHeight, R();
|
|
179
|
-
}, [g, _, I, R]), O(() => {
|
|
180
|
-
const e = D.current;
|
|
181
|
-
if (!e || typeof ResizeObserver > "u") return;
|
|
182
|
-
const t = new ResizeObserver(R);
|
|
183
|
-
return t.observe(e), () => t.disconnect();
|
|
184
|
-
}, [R]);
|
|
185
|
-
const me = x(() => {
|
|
186
|
-
R();
|
|
187
|
-
const e = D.current;
|
|
188
|
-
if (!e) return;
|
|
189
|
-
const { scrollTop: t, scrollHeight: s, clientHeight: d } = e;
|
|
190
|
-
v && q && !j && t <= L && v(), p && G && !C && s - t - d <= L && p();
|
|
191
|
-
}, [
|
|
192
|
-
R,
|
|
193
|
-
v,
|
|
194
|
-
p,
|
|
195
|
-
q,
|
|
196
|
-
G,
|
|
197
|
-
j,
|
|
198
|
-
C
|
|
199
|
-
]), b = x(
|
|
200
|
-
(e) => {
|
|
201
|
-
const t = y(e), s = w.current.has(t);
|
|
202
|
-
I(t, !0), s || H == null || H(e.toISOString());
|
|
203
|
-
},
|
|
204
|
-
[I, H]
|
|
205
|
-
), pe = x(() => b(r), [b, r]), ue = x(() => {
|
|
206
|
-
const e = new Date(r), t = (e.getDay() + 6) % 7;
|
|
207
|
-
e.setDate(e.getDate() - t), b(e);
|
|
208
|
-
}, [b, r]), fe = x(() => {
|
|
209
|
-
b(new Date(r.getFullYear(), r.getMonth(), 1));
|
|
210
|
-
}, [b, r]), B = T(i);
|
|
211
|
-
B.current = i;
|
|
212
|
-
const Q = T(null);
|
|
213
|
-
xe(oe, () => Q.current, []);
|
|
214
|
-
const ge = F(
|
|
215
|
-
() => ({
|
|
216
|
-
getItems: () => B.current.map((e) => ({ id: e.id, state: e.state })),
|
|
217
|
-
selectItem: (e) => {
|
|
218
|
-
const t = B.current.find((s) => s.id === e);
|
|
219
|
-
t && (f == null || f(t));
|
|
220
|
-
},
|
|
221
|
-
jumpToToday: () => I(y(r), !0)
|
|
222
|
-
}),
|
|
223
|
-
[f, I, r]
|
|
224
|
-
);
|
|
225
|
-
Me(_e, ge, n);
|
|
226
|
-
const ye = g.length === 0 && !j && !C, U = (e) => /* @__PURE__ */ o(
|
|
227
|
-
"div",
|
|
228
|
-
{
|
|
229
|
-
"aria-hidden": "true",
|
|
230
|
-
className: "ds:flex ds:flex-col ds:gap-[var(--spacing-2xs)] ds:py-[var(--spacing-xs)]",
|
|
231
|
-
children: /* @__PURE__ */ o(Ce, { variant: "rectangular", height: "3.5rem" })
|
|
232
|
-
},
|
|
233
|
-
e
|
|
234
|
-
);
|
|
235
|
-
return /* @__PURE__ */ S(
|
|
236
|
-
"section",
|
|
237
|
-
{
|
|
238
|
-
ref: Q,
|
|
239
|
-
"data-component": "appointment-timeline",
|
|
240
|
-
"data-component-id": n,
|
|
241
|
-
"aria-label": ne ?? E,
|
|
242
|
-
className: ze({ size: c, className: se }),
|
|
243
|
-
...ie,
|
|
244
|
-
children: [
|
|
245
|
-
/* @__PURE__ */ o(
|
|
246
|
-
je,
|
|
247
|
-
{
|
|
248
|
-
icon: /* @__PURE__ */ o(Ne, {}),
|
|
249
|
-
title: E,
|
|
250
|
-
filters: J ? /* @__PURE__ */ S(ke, { children: [
|
|
251
|
-
/* @__PURE__ */ S(Ie, { label: a("appointmentTimeline.filtersLabel"), children: [
|
|
252
|
-
/* @__PURE__ */ o(A, { intent: "outline", size: "sm", onClick: pe, children: a("appointmentTimeline.today") }),
|
|
253
|
-
/* @__PURE__ */ o(A, { intent: "outline", size: "sm", onClick: ue, children: a("appointmentTimeline.thisWeek") }),
|
|
254
|
-
/* @__PURE__ */ o(A, { intent: "outline", size: "sm", onClick: fe, children: a("appointmentTimeline.thisMonth") })
|
|
255
|
-
] }),
|
|
256
|
-
/* @__PURE__ */ o("label", { htmlFor: Y, className: "ds:sr-only", children: a("appointmentTimeline.jumpToDate") }),
|
|
257
|
-
/* @__PURE__ */ o(
|
|
258
|
-
Se,
|
|
259
|
-
{
|
|
260
|
-
id: Y,
|
|
261
|
-
size: "sm",
|
|
262
|
-
placeholder: a("appointmentTimeline.jumpToDate"),
|
|
263
|
-
onChange: (e) => {
|
|
264
|
-
e && b(e);
|
|
265
|
-
}
|
|
266
|
-
}
|
|
267
|
-
)
|
|
268
|
-
] }) : void 0
|
|
269
|
-
}
|
|
270
|
-
),
|
|
271
|
-
ye ? /* @__PURE__ */ o("div", { className: "ds:flex-1 ds:p-[var(--spacing-md)]", children: /* @__PURE__ */ o(
|
|
272
|
-
He,
|
|
273
|
-
{
|
|
274
|
-
variant: "first-use",
|
|
275
|
-
size: "sm",
|
|
276
|
-
title: ee ?? a("appointmentTimeline.empty.title"),
|
|
277
|
-
description: te ?? a("appointmentTimeline.empty.description")
|
|
278
|
-
}
|
|
279
|
-
) }) : /* @__PURE__ */ S(
|
|
280
|
-
"div",
|
|
281
|
-
{
|
|
282
|
-
ref: D,
|
|
283
|
-
tabIndex: 0,
|
|
284
|
-
onScroll: me,
|
|
285
|
-
"data-fade-top": re ? "true" : void 0,
|
|
286
|
-
"data-fade-bottom": ce ? "true" : void 0,
|
|
287
|
-
className: Be,
|
|
288
|
-
children: [
|
|
289
|
-
j ? U("loading-earlier") : null,
|
|
290
|
-
/* @__PURE__ */ o(
|
|
291
|
-
"ol",
|
|
292
|
-
{
|
|
293
|
-
role: "list",
|
|
294
|
-
className: "ds:m-0 ds:flex ds:list-none ds:flex-col ds:gap-[var(--spacing-md)] ds:p-0",
|
|
295
|
-
children: g.map((e) => /* @__PURE__ */ S(
|
|
296
|
-
"li",
|
|
297
|
-
{
|
|
298
|
-
ref: (t) => {
|
|
299
|
-
t ? w.current.set(e.key, t) : w.current.delete(e.key);
|
|
300
|
-
},
|
|
301
|
-
className: "ds:flex ds:flex-col ds:gap-[var(--spacing-2xs)]",
|
|
302
|
-
children: [
|
|
303
|
-
/* @__PURE__ */ o(
|
|
304
|
-
Ye,
|
|
305
|
-
{
|
|
306
|
-
date: e.date,
|
|
307
|
-
now: r,
|
|
308
|
-
locale: $,
|
|
309
|
-
todayLabel: a("appointmentTimeline.today"),
|
|
310
|
-
tomorrowLabel: a("appointmentTimeline.tomorrow"),
|
|
311
|
-
yesterdayLabel: a("appointmentTimeline.yesterday")
|
|
312
|
-
}
|
|
313
|
-
),
|
|
314
|
-
/* @__PURE__ */ o(
|
|
315
|
-
"ul",
|
|
316
|
-
{
|
|
317
|
-
role: "list",
|
|
318
|
-
className: "ds:m-0 ds:flex ds:list-none ds:flex-col ds:gap-[var(--spacing-sm)] ds:p-0",
|
|
319
|
-
children: e.items.map((t) => /* @__PURE__ */ o(
|
|
320
|
-
Re,
|
|
321
|
-
{
|
|
322
|
-
item: t,
|
|
323
|
-
size: c,
|
|
324
|
-
surface: "elevated",
|
|
325
|
-
showPatient: M,
|
|
326
|
-
locale: $,
|
|
327
|
-
currency: h,
|
|
328
|
-
onActivate: f,
|
|
329
|
-
"data-appointment-id": t.id
|
|
330
|
-
},
|
|
331
|
-
t.id
|
|
332
|
-
))
|
|
333
|
-
}
|
|
334
|
-
)
|
|
335
|
-
]
|
|
336
|
-
},
|
|
337
|
-
e.key
|
|
338
|
-
))
|
|
339
|
-
}
|
|
340
|
-
),
|
|
341
|
-
C ? U("loading-later") : null
|
|
342
|
-
]
|
|
343
|
-
}
|
|
344
|
-
)
|
|
345
|
-
]
|
|
346
|
-
}
|
|
347
|
-
);
|
|
348
|
-
}
|
|
349
|
-
);
|
|
350
|
-
Ae.displayName = "AppointmentTimeline";
|
|
351
|
-
function Ye({
|
|
352
|
-
date: n,
|
|
353
|
-
now: i,
|
|
354
|
-
locale: l,
|
|
355
|
-
todayLabel: u,
|
|
356
|
-
tomorrowLabel: m,
|
|
357
|
-
yesterdayLabel: h
|
|
358
|
-
}) {
|
|
359
|
-
const c = y(n), M = y(i), f = new Date(i);
|
|
360
|
-
f.setDate(i.getDate() + 1);
|
|
361
|
-
const v = new Date(i);
|
|
362
|
-
v.setDate(i.getDate() - 1);
|
|
363
|
-
const p = c === M;
|
|
364
|
-
let k;
|
|
365
|
-
if (p) k = u;
|
|
366
|
-
else if (c === y(f)) k = m;
|
|
367
|
-
else if (c === y(v)) k = h;
|
|
368
|
-
else {
|
|
369
|
-
const N = n.getFullYear() === i.getFullYear();
|
|
370
|
-
k = new Intl.DateTimeFormat(l, {
|
|
371
|
-
weekday: "short",
|
|
372
|
-
day: "numeric",
|
|
373
|
-
month: "short",
|
|
374
|
-
...N ? {} : { year: "numeric" }
|
|
375
|
-
}).format(n);
|
|
376
|
-
}
|
|
377
|
-
return /* @__PURE__ */ S(
|
|
378
|
-
"div",
|
|
379
|
-
{
|
|
380
|
-
"data-today": p ? "true" : void 0,
|
|
381
|
-
className: [
|
|
382
|
-
"ds:sticky ds:top-0 ds:z-[1] ds:bg-[color:var(--card)] ds:py-[var(--spacing-2xs)]",
|
|
383
|
-
"ds:flex ds:items-center ds:gap-[var(--spacing-2xs)] type-eyebrow",
|
|
384
|
-
p ? "ds:text-[color:var(--primary)] ds:font-semibold" : "ds:text-[color:var(--muted-foreground)]"
|
|
385
|
-
].join(" "),
|
|
386
|
-
children: [
|
|
387
|
-
p ? /* @__PURE__ */ o(
|
|
388
|
-
"span",
|
|
389
|
-
{
|
|
390
|
-
"aria-hidden": "true",
|
|
391
|
-
className: "ds:size-1.5 ds:shrink-0 ds:rounded-[var(--radius-full)] ds:bg-[color:var(--primary)]"
|
|
392
|
-
}
|
|
393
|
-
) : null,
|
|
394
|
-
k
|
|
395
|
-
]
|
|
396
|
-
}
|
|
397
|
-
);
|
|
398
|
-
}
|
|
399
|
-
export {
|
|
400
|
-
Ae as A,
|
|
401
|
-
_e as a
|
|
402
|
-
};
|
|
403
|
-
//# sourceMappingURL=appointment-timeline-CymGHyIP.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"appointment-timeline-CymGHyIP.js","sources":["../../src/components/appointment-timeline/appointment-timeline.agent.ts","../../src/components/appointment-timeline/appointment-timeline.tsx"],"sourcesContent":["/* -------------------------------------------------------------------- */\n/* Agent adapter — AppointmentTimeline. */\n/* */\n/* Timeline surface: read appointment ids + lifecycle state (never */\n/* patient names / treatments), activate a row through the curated handle, */\n/* and re-anchor the scroll on today. In-page (no open/close). */\n/* `showPatient` is presentation only — it changes which name each row */\n/* leads with, never what the adapter reads or exposes. */\n/* -------------------------------------------------------------------- */\n\nimport type { AgentAdapter } from '../../agent/types';\nimport type { AppointmentTimelineHandle } from './appointment-timeline';\n\nexport const appointmentTimelineAgent: AgentAdapter<AppointmentTimelineHandle> =\n {\n id: 'appointment-timeline',\n // 'pick' backs select_item (non-persisting activation through\n // onOpenAppointment); 'scroll' backs jump_to_today, which re-anchors the\n // scroll viewport (mirrors practice-results' scroll_to_result).\n capabilities: ['scroll', 'pick'],\n state: {\n items: {\n type: 'Array<{ id: string; state: string }>',\n descriptionKey: 'ui.agent.appointmentTimeline.state.items',\n description:\n 'Currently-rendered appointments. Ids + lifecycle state only — never patient identity.',\n read: (handle) => handle.getItems(),\n },\n },\n actions: {\n select_item: {\n safety: 'read',\n argsType: '{ id: string }',\n argsSchema: {\n type: 'object',\n properties: { id: { type: 'string' } },\n required: ['id'],\n },\n idempotent: true,\n descriptionKey: 'ui.agent.appointmentTimeline.actions.selectItem',\n description: 'Activate the appointment with the given id.',\n invoke: (handle, args: { id: string }) => {\n handle.selectItem(args.id);\n },\n },\n jump_to_today: {\n safety: 'read',\n idempotent: true,\n descriptionKey: 'ui.agent.appointmentTimeline.actions.jumpToToday',\n description: \"Re-anchor the timeline scroll on today's appointments.\",\n invoke: (handle) => {\n handle.jumpToToday();\n },\n },\n },\n domHooks: {\n root: {\n attr: 'data-component',\n value: 'appointment-timeline',\n description: 'Marks the AppointmentTimeline wrapper.',\n },\n instanceId: {\n attr: 'data-component-id',\n sourceProp: 'id',\n description:\n 'Sourced from the id prop. Required to address a specific timeline from the agent.',\n },\n item: {\n attr: 'data-appointment-id',\n description:\n 'Stable appointment id emitted on each rendered AppointmentCard inside the timeline.',\n },\n },\n };\n","import {\n forwardRef,\n useCallback,\n useId,\n useImperativeHandle,\n useMemo,\n useRef,\n useState,\n type HTMLAttributes,\n type ReactNode,\n} from 'react';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { useTranslation } from 'react-i18next';\nimport { CalendarDays } from 'lucide-react';\nimport { AppointmentCard, type AppointmentItem } from '../appointment-card';\nimport { Button } from '../button';\nimport { ButtonGroup } from '../button-group';\nimport { DatePicker } from '../date-picker';\nimport { PanelHeader } from '../panel-header';\nimport { Skeleton } from '../skeleton/skeleton';\nimport { EmptyState } from '../empty-state/empty-state';\nimport { useIsomorphicLayoutEffect } from '../../hooks/use-isomorphic-layout-effect';\nimport { usePrefersReducedMotion } from '../../hooks/use-prefers-reduced-motion';\nimport { useAgentRegistration } from '../../agent/registry';\nimport { appointmentTimelineAgent } from './appointment-timeline.agent';\n\n/* -------------------------------------------------------------------- */\n/* AppointmentTimeline */\n/* */\n/* A vertical, day-grouped appointment timeline for the Control Room */\n/* rail. Unlike AppointmentTray (a bordered card of a flat list), this */\n/* fills the rail edge-to-edge: appointments are grouped under day */\n/* headers, the scroll is anchored on TODAY, and it scrolls infinitely */\n/* into the past and future — the consumer feeds more via onLoadEarlier */\n/* / onLoadLater as either edge is reached (scroll position is preserved */\n/* when earlier items prepend). Date-filter presets + a jump-to-date */\n/* picker re-anchor the scroll. Top + bottom transparent gradient fades */\n/* (a block-axis mask) signal more content beyond each edge. */\n/* */\n/* Each row reuses AppointmentCard (care-plan + chair chips included). */\n/* All visible text flows through useTranslation('ui') against the */\n/* `appointmentTimeline.*` namespace; no PHI reaches the agent adapter. */\n/* -------------------------------------------------------------------- */\n\n/* How close (px) to an edge before the matching load callback fires. */\nconst EDGE_LOAD_THRESHOLD = 96;\n\n/* -------------------------------------------------------------------- */\n/* Types */\n/* -------------------------------------------------------------------- */\n\n/** Curated imperative handle — identifiers + lifecycle state only. */\nexport interface AppointmentTimelineHandle {\n getItems: () => Array<{ id: string; state: string }>;\n selectItem: (id: string) => void;\n jumpToToday: () => void;\n}\n\nexport interface AppointmentTimelineProps extends Omit<\n HTMLAttributes<HTMLElement>,\n 'onClick' | 'id' | 'title'\n> {\n /** Stable instance id, surfaced as `data-component-id`. */\n id?: string;\n /** Appointments to render — any order; grouped + sorted internally. */\n items: AppointmentItem[];\n /**\n * ISO-8601 \"now\" anchor — the timeline scrolls to this day on mount and the\n * \"Today\" preset returns to it. Defaults to the current instant. Stories pass\n * a fixed value for deterministic snapshots.\n */\n nowIso?: string;\n /** Panel heading. Defaults to the localised \"Appointments\". */\n title?: string;\n /** BCP-47 locale override for day headers + each AppointmentCard. */\n locale?: string;\n /** ISO-4217 currency code passed to each AppointmentCard. */\n currency?: string;\n /** Visual density passed to each AppointmentCard. */\n size?: 'sm' | 'md';\n /**\n * Lead each row with the PATIENT (avatar + name as the row title) rather\n * than the operator. Default `false`: the timeline was built for a\n * patient-scoped rail, where repeating the name on every row is noise. A\n * clinic-wide agenda — \"who is coming in next\" across the practice —\n * passes `true`, and rows with no patient read as \"No patient\".\n */\n showPatient?: boolean;\n /** Fires when a row is activated. */\n onOpenAppointment?: (item: AppointmentItem) => void;\n\n /* ----- Infinite scroll ----- */\n /** Load earlier (past) appointments — fired when the top edge is reached. */\n onLoadEarlier?: () => void;\n /** Load later (future) appointments — fired when the bottom edge is reached. */\n onLoadLater?: () => void;\n /** Whether more past appointments exist. Defaults to `true` when `onLoadEarlier` is set. */\n hasMoreEarlier?: boolean;\n /** Whether more future appointments exist. Defaults to `true` when `onLoadLater` is set. */\n hasMoreLater?: boolean;\n /** Show a loading row at the top edge. */\n loadingEarlier?: boolean;\n /** Show a loading row at the bottom edge. */\n loadingLater?: boolean;\n\n /* ----- Filters ----- */\n /** Show the date-filter row (presets + jump-to-date). Default `true`. */\n showFilters?: boolean;\n /**\n * Fired when a jump-to-date / preset targets a day outside the loaded range,\n * so the consumer can load it. The timeline scrolls to the nearest rendered\n * day until then.\n */\n onJumpToDate?: (dateIso: string) => void;\n\n /* ----- Empty ----- */\n emptyTitle?: string;\n emptyDescription?: string;\n\n /** Accessible name for the panel region (defaults to `title`). */\n 'aria-label'?: string;\n}\n\n/* -------------------------------------------------------------------- */\n/* CVA */\n/* -------------------------------------------------------------------- */\n\nconst rootVariants = cva(\n [\n 'ds:flex ds:flex-col ds:h-full ds:min-h-0',\n 'ds:bg-[color:var(--card)] ds:text-[color:var(--card-foreground)]',\n ].join(' '),\n { variants: { size: { sm: '', md: '' } }, defaultVariants: { size: 'sm' } },\n);\n\n/* Scroll region with a block-axis fade mask. The CSS custom properties flip to\n `transparent` at whichever edge has more content (data-fade-top /\n data-fade-bottom), mirroring the TabBar edge-mask technique on the Y axis.\n Disabled under reduced-motion, the accessible theme, and forced-colors. */\nconst scrollRegionClasses = [\n 'ds:flex-1 ds:min-h-0 ds:overflow-y-auto',\n 'ds:flex ds:flex-col ds:gap-[var(--spacing-sm)]',\n 'ds:px-[var(--spacing-sm)] ds:py-[var(--spacing-xs)]',\n 'ds:[--atl-mask-top:black] ds:[--atl-mask-bottom:black]',\n 'ds:data-[fade-top=true]:[--atl-mask-top:transparent]',\n 'ds:data-[fade-bottom=true]:[--atl-mask-bottom:transparent]',\n 'ds:[mask-image:linear-gradient(to_bottom,var(--atl-mask-top)_0,black_var(--atl-fade-distance,var(--spacing-lg)),black_calc(100%-var(--atl-fade-distance,var(--spacing-lg))),var(--atl-mask-bottom)_100%)]',\n 'ds:motion-reduce:[mask-image:none]',\n 'ds:[.theme-accessible_&]:[mask-image:none]',\n 'ds:forced-colors:[mask-image:none]',\n 'ds:focus-visible:outline-[length:var(--focus-ring-width)] ds:focus-visible:outline-solid',\n 'ds:focus-visible:outline-[color:var(--ring)] ds:focus-visible:[outline-offset:-2px]',\n 'ds:forced-colors:focus-visible:outline-[CanvasText]',\n].join(' ');\n\n/* -------------------------------------------------------------------- */\n/* Day grouping + header labels */\n/* -------------------------------------------------------------------- */\n\ninterface DayGroup {\n key: string;\n date: Date;\n items: AppointmentItem[];\n}\n\n/** Local calendar day key (`YYYY-MM-DD`) — sorts chronologically as a string. */\nfunction localDayKey(d: Date): string {\n const m = `${d.getMonth() + 1}`.padStart(2, '0');\n const day = `${d.getDate()}`.padStart(2, '0');\n return `${d.getFullYear()}-${m}-${day}`;\n}\n\nfunction groupByDay(items: AppointmentItem[]): DayGroup[] {\n const sorted = [...items].sort(\n (a, b) => +new Date(a.startIso) - +new Date(b.startIso),\n );\n const map = new Map<string, DayGroup>();\n for (const item of sorted) {\n const d = new Date(item.startIso);\n const key = localDayKey(d);\n let group = map.get(key);\n if (!group) {\n group = {\n key,\n date: new Date(d.getFullYear(), d.getMonth(), d.getDate()),\n items: [],\n };\n map.set(key, group);\n }\n group.items.push(item);\n }\n return [...map.values()];\n}\n\n/* -------------------------------------------------------------------- */\n/* Component */\n/* -------------------------------------------------------------------- */\n\nexport const AppointmentTimeline = forwardRef<\n HTMLElement,\n AppointmentTimelineProps\n>(\n (\n {\n id,\n items,\n nowIso,\n title,\n locale,\n currency,\n size = 'sm',\n showPatient = false,\n onOpenAppointment,\n onLoadEarlier,\n onLoadLater,\n hasMoreEarlier,\n hasMoreLater,\n loadingEarlier = false,\n loadingLater = false,\n showFilters = true,\n onJumpToDate,\n emptyTitle,\n emptyDescription,\n className,\n 'aria-label': ariaLabel,\n ...rest\n },\n ref,\n ) => {\n const { t, i18n } = useTranslation();\n const jumpId = useId();\n const prefersReducedMotion = usePrefersReducedMotion();\n const resolvedLocale = locale ?? i18n.language;\n\n const heading = title ?? t('appointmentTimeline.title');\n const now = useMemo(\n () => (nowIso ? new Date(nowIso) : new Date()),\n [nowIso],\n );\n\n const groups = useMemo(() => groupByDay(items), [items]);\n\n const moreEarlier = hasMoreEarlier ?? !!onLoadEarlier;\n const moreLater = hasMoreLater ?? !!onLoadLater;\n\n /* The day to anchor on: today if present, else the nearest upcoming day,\n else the last day we have. */\n const anchorKey = useMemo(() => {\n if (groups.length === 0) return undefined;\n const todayKey = localDayKey(now);\n const keys = groups.map((g) => g.key);\n if (keys.includes(todayKey)) return todayKey;\n return keys.find((k) => k >= todayKey) ?? keys[keys.length - 1];\n }, [groups, now]);\n\n const scrollRef = useRef<HTMLDivElement>(null);\n const dayElRefs = useRef<Map<string, HTMLElement>>(new Map());\n const hasAnchored = useRef(false);\n const prevFirstKey = useRef<string | undefined>(undefined);\n const prevScrollHeight = useRef(0);\n\n const [fadeTop, setFadeTop] = useState(false);\n const [fadeBottom, setFadeBottom] = useState(false);\n\n const updateEdges = useCallback(() => {\n const region = scrollRef.current;\n if (!region) return;\n const { scrollTop, scrollHeight, clientHeight } = region;\n setFadeTop(scrollTop > 1);\n setFadeBottom(scrollTop + clientHeight < scrollHeight - 1);\n }, []);\n\n /* Scroll a day into view at the top of the region. Falls back to the\n nearest rendered day on/after the target (presets may land on an empty\n day). Uses getBoundingClientRect so it is offsetParent-agnostic. */\n const scrollToKey = useCallback(\n (targetKey: string, smooth: boolean) => {\n const region = scrollRef.current;\n if (!region) return;\n let el = dayElRefs.current.get(targetKey);\n if (!el) {\n const keys = [...dayElRefs.current.keys()].sort();\n const next =\n keys.find((k) => k >= targetKey) ?? keys[keys.length - 1];\n el = next ? dayElRefs.current.get(next) : undefined;\n }\n if (!el) return;\n const delta =\n el.getBoundingClientRect().top - region.getBoundingClientRect().top;\n region.scrollTo({\n top: region.scrollTop + delta,\n behavior: smooth && !prefersReducedMotion ? 'smooth' : 'auto',\n });\n },\n [prefersReducedMotion],\n );\n\n /* Anchor on mount; preserve the viewport when earlier days prepend. */\n useIsomorphicLayoutEffect(() => {\n const region = scrollRef.current;\n if (!region) return;\n const firstKey = groups[0]?.key;\n if (!hasAnchored.current) {\n if (groups.length > 0 && anchorKey) {\n scrollToKey(anchorKey, false);\n hasAnchored.current = true;\n }\n } else if (\n prevFirstKey.current &&\n firstKey &&\n firstKey < prevFirstKey.current\n ) {\n const grew = region.scrollHeight - prevScrollHeight.current;\n if (grew > 0) region.scrollTop += grew;\n }\n prevFirstKey.current = firstKey;\n prevScrollHeight.current = region.scrollHeight;\n updateEdges();\n }, [groups, anchorKey, scrollToKey, updateEdges]);\n\n /* Recompute the fades when the region resizes. */\n useIsomorphicLayoutEffect(() => {\n const region = scrollRef.current;\n if (!region || typeof ResizeObserver === 'undefined') return undefined;\n const observer = new ResizeObserver(updateEdges);\n observer.observe(region);\n return () => observer.disconnect();\n }, [updateEdges]);\n\n const handleScroll = useCallback(() => {\n updateEdges();\n const region = scrollRef.current;\n if (!region) return;\n const { scrollTop, scrollHeight, clientHeight } = region;\n if (\n onLoadEarlier &&\n moreEarlier &&\n !loadingEarlier &&\n scrollTop <= EDGE_LOAD_THRESHOLD\n ) {\n onLoadEarlier();\n }\n if (\n onLoadLater &&\n moreLater &&\n !loadingLater &&\n scrollHeight - scrollTop - clientHeight <= EDGE_LOAD_THRESHOLD\n ) {\n onLoadLater();\n }\n }, [\n updateEdges,\n onLoadEarlier,\n onLoadLater,\n moreEarlier,\n moreLater,\n loadingEarlier,\n loadingLater,\n ]);\n\n /* ----- Filter actions ----- */\n const jumpTo = useCallback(\n (date: Date) => {\n const key = localDayKey(date);\n const known = dayElRefs.current.has(key);\n scrollToKey(key, true);\n if (!known) onJumpToDate?.(date.toISOString());\n },\n [scrollToKey, onJumpToDate],\n );\n\n const handleToday = useCallback(() => jumpTo(now), [jumpTo, now]);\n const handleThisWeek = useCallback(() => {\n const start = new Date(now);\n const dow = (start.getDay() + 6) % 7; // Monday-based week start\n start.setDate(start.getDate() - dow);\n jumpTo(start);\n }, [jumpTo, now]);\n const handleThisMonth = useCallback(() => {\n jumpTo(new Date(now.getFullYear(), now.getMonth(), 1));\n }, [jumpTo, now]);\n\n /* ----- Agent handle ----- */\n const itemsRef = useRef<AppointmentItem[]>(items);\n itemsRef.current = items;\n const innerRef = useRef<HTMLElement>(null);\n useImperativeHandle(ref, () => innerRef.current as HTMLElement, []);\n\n const handle = useMemo<AppointmentTimelineHandle>(\n () => ({\n getItems: () =>\n itemsRef.current.map((i) => ({ id: i.id, state: i.state })),\n selectItem: (targetId: string) => {\n const found = itemsRef.current.find((i) => i.id === targetId);\n if (found) onOpenAppointment?.(found);\n },\n jumpToToday: () => scrollToKey(localDayKey(now), true),\n }),\n [onOpenAppointment, scrollToKey, now],\n );\n useAgentRegistration(appointmentTimelineAgent, handle, id);\n\n const isEmpty = groups.length === 0 && !loadingEarlier && !loadingLater;\n\n const loadingRow = (key: string) => (\n <div\n key={key}\n aria-hidden=\"true\"\n className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-2xs)] ds:py-[var(--spacing-xs)]\"\n >\n <Skeleton variant=\"rectangular\" height=\"3.5rem\" />\n </div>\n );\n\n return (\n <section\n ref={innerRef}\n data-component=\"appointment-timeline\"\n data-component-id={id}\n aria-label={ariaLabel ?? heading}\n className={rootVariants({ size, className })}\n {...rest}\n >\n {/* Shared rail header: title + (optional) filter row + divider. This\n panel owns its own scroll/fill, so the header stays a fixed band\n (sticky={false}). The rail injects the favourite/close cluster via\n PanelHeaderActionsProvider; standalone it renders none. */}\n <PanelHeader\n icon={<CalendarDays />}\n title={heading}\n filters={\n showFilters ? (\n <>\n <ButtonGroup label={t('appointmentTimeline.filtersLabel')}>\n <Button intent=\"outline\" size=\"sm\" onClick={handleToday}>\n {t('appointmentTimeline.today')}\n </Button>\n <Button intent=\"outline\" size=\"sm\" onClick={handleThisWeek}>\n {t('appointmentTimeline.thisWeek')}\n </Button>\n <Button intent=\"outline\" size=\"sm\" onClick={handleThisMonth}>\n {t('appointmentTimeline.thisMonth')}\n </Button>\n </ButtonGroup>\n <label htmlFor={jumpId} className=\"ds:sr-only\">\n {t('appointmentTimeline.jumpToDate')}\n </label>\n <DatePicker\n id={jumpId}\n size=\"sm\"\n placeholder={t('appointmentTimeline.jumpToDate')}\n onChange={(date) => {\n if (date) jumpTo(date);\n }}\n />\n </>\n ) : undefined\n }\n />\n\n {isEmpty ? (\n <div className=\"ds:flex-1 ds:p-[var(--spacing-md)]\">\n <EmptyState\n variant=\"first-use\"\n size=\"sm\"\n title={emptyTitle ?? t('appointmentTimeline.empty.title')}\n description={\n emptyDescription ?? t('appointmentTimeline.empty.description')\n }\n />\n </div>\n ) : (\n <div\n ref={scrollRef}\n // The scroll region must be keyboard-focusable so arrow / Home /\n // End can drive it (axe scrollable-region-focusable); jsx-a11y's\n // generic rule doesn't know this element scrolls.\n // eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex\n tabIndex={0}\n onScroll={handleScroll}\n data-fade-top={fadeTop ? 'true' : undefined}\n data-fade-bottom={fadeBottom ? 'true' : undefined}\n className={scrollRegionClasses}\n >\n {loadingEarlier ? loadingRow('loading-earlier') : null}\n {/* eslint-disable-next-line jsx-a11y/no-redundant-roles -- role=\"list\" is NOT redundant: WebKit drops implicit list semantics when list-style is none */}\n <ol\n role=\"list\"\n className=\"ds:m-0 ds:flex ds:list-none ds:flex-col ds:gap-[var(--spacing-md)] ds:p-0\"\n >\n {groups.map((group) => (\n <li\n key={group.key}\n ref={(node) => {\n if (node) dayElRefs.current.set(group.key, node);\n else dayElRefs.current.delete(group.key);\n }}\n className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-2xs)]\"\n >\n <DayHeader\n date={group.date}\n now={now}\n locale={resolvedLocale}\n todayLabel={t('appointmentTimeline.today')}\n tomorrowLabel={t('appointmentTimeline.tomorrow')}\n yesterdayLabel={t('appointmentTimeline.yesterday')}\n />\n {/* eslint-disable-next-line jsx-a11y/no-redundant-roles -- role=\"list\" is NOT redundant: WebKit drops implicit list semantics when list-style is none */}\n <ul\n role=\"list\"\n className=\"ds:m-0 ds:flex ds:list-none ds:flex-col ds:gap-[var(--spacing-sm)] ds:p-0\"\n >\n {group.items.map((item) => (\n <AppointmentCard\n key={item.id}\n item={item}\n size={size}\n surface=\"elevated\"\n showPatient={showPatient}\n locale={resolvedLocale}\n currency={currency}\n onActivate={onOpenAppointment}\n data-appointment-id={item.id}\n />\n ))}\n </ul>\n </li>\n ))}\n </ol>\n {loadingLater ? loadingRow('loading-later') : null}\n </div>\n )}\n </section>\n );\n },\n);\n\nAppointmentTimeline.displayName = 'AppointmentTimeline';\n\n/* -------------------------------------------------------------------- */\n/* Day header — sticky label per day group */\n/* -------------------------------------------------------------------- */\n\ninterface DayHeaderProps {\n date: Date;\n now: Date;\n locale: string | undefined;\n todayLabel: string;\n tomorrowLabel: string;\n yesterdayLabel: string;\n}\n\nfunction DayHeader({\n date,\n now,\n locale,\n todayLabel,\n tomorrowLabel,\n yesterdayLabel,\n}: DayHeaderProps): ReactNode {\n const key = localDayKey(date);\n const todayKey = localDayKey(now);\n const tomorrow = new Date(now);\n tomorrow.setDate(now.getDate() + 1);\n const yesterday = new Date(now);\n yesterday.setDate(now.getDate() - 1);\n\n const isToday = key === todayKey;\n\n let label: string;\n if (isToday) label = todayLabel;\n else if (key === localDayKey(tomorrow)) label = tomorrowLabel;\n else if (key === localDayKey(yesterday)) label = yesterdayLabel;\n else {\n const sameYear = date.getFullYear() === now.getFullYear();\n label = new Intl.DateTimeFormat(locale, {\n weekday: 'short',\n day: 'numeric',\n month: 'short',\n ...(sameYear ? {} : { year: 'numeric' }),\n }).format(date);\n }\n\n // Today's group is marked with the brand colour + a leading dot so the\n // current day reads at a glance. `--primary` clears AA on the card in every\n // theme (violet-500 light, magenta on dark); the dot is decorative.\n return (\n <div\n data-today={isToday ? 'true' : undefined}\n className={[\n 'ds:sticky ds:top-0 ds:z-[1] ds:bg-[color:var(--card)] ds:py-[var(--spacing-2xs)]',\n 'ds:flex ds:items-center ds:gap-[var(--spacing-2xs)] type-eyebrow',\n isToday\n ? 'ds:text-[color:var(--primary)] ds:font-semibold'\n : 'ds:text-[color:var(--muted-foreground)]',\n ].join(' ')}\n >\n {isToday ? (\n <span\n aria-hidden=\"true\"\n className=\"ds:size-1.5 ds:shrink-0 ds:rounded-[var(--radius-full)] ds:bg-[color:var(--primary)]\"\n />\n ) : null}\n {label}\n </div>\n );\n}\n\n/** Re-export of the size variant union for downstream typing. */\nexport type AppointmentTimelineSize = NonNullable<\n VariantProps<typeof rootVariants>['size']\n>;\n"],"names":["appointmentTimelineAgent","handle","args","EDGE_LOAD_THRESHOLD","rootVariants","cva","scrollRegionClasses","localDayKey","d","m","day","groupByDay","items","sorted","a","b","map","item","key","group","AppointmentTimeline","forwardRef","id","nowIso","title","locale","currency","size","showPatient","onOpenAppointment","onLoadEarlier","onLoadLater","hasMoreEarlier","hasMoreLater","loadingEarlier","loadingLater","showFilters","onJumpToDate","emptyTitle","emptyDescription","className","ariaLabel","rest","ref","t","i18n","useTranslation","jumpId","useId","prefersReducedMotion","usePrefersReducedMotion","resolvedLocale","heading","now","useMemo","groups","moreEarlier","moreLater","anchorKey","todayKey","keys","g","k","scrollRef","useRef","dayElRefs","hasAnchored","prevFirstKey","prevScrollHeight","fadeTop","setFadeTop","useState","fadeBottom","setFadeBottom","updateEdges","useCallback","region","scrollTop","scrollHeight","clientHeight","scrollToKey","targetKey","smooth","el","next","delta","useIsomorphicLayoutEffect","firstKey","_a","grew","observer","handleScroll","jumpTo","date","known","handleToday","handleThisWeek","start","dow","handleThisMonth","itemsRef","innerRef","useImperativeHandle","i","targetId","found","useAgentRegistration","isEmpty","loadingRow","jsx","Skeleton","jsxs","PanelHeader","CalendarDays","Fragment","ButtonGroup","Button","DatePicker","EmptyState","node","DayHeader","AppointmentCard","todayLabel","tomorrowLabel","yesterdayLabel","tomorrow","yesterday","isToday","label","sameYear"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"clinical-note-card-D2WTV2CO.js","sources":["../../node_modules/lucide-react/dist/esm/icons/flag.mjs","../../node_modules/lucide-react/dist/esm/icons/pin.mjs","../../src/components/clinical-note-card/clinical-note-card.agent.ts","../../src/components/clinical-note-card/clinical-note-card.tsx"],"sourcesContent":["/**\n * @license lucide-react v1.22.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\n \"path\",\n {\n d: \"M4 22V4a1 1 0 0 1 .4-.8A6 6 0 0 1 8 2c3 0 5 2 7.333 2q2 0 3.067-.8A1 1 0 0 1 20 4v10a1 1 0 0 1-.4.8A6 6 0 0 1 16 16c-3 0-5-2-8-2a6 6 0 0 0-4 1.528\",\n key: \"1jaruq\"\n }\n ]\n];\nconst Flag = createLucideIcon(\"flag\", __iconNode);\n\nexport { __iconNode, Flag as default };\n//# sourceMappingURL=flag.mjs.map\n","/**\n * @license lucide-react v1.22.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"path\", { d: \"M12 17v5\", key: \"bb1du9\" }],\n [\n \"path\",\n {\n d: \"M9 10.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-.76a2 2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8a2 2 0 0 0 0 4 1 1 0 0 1 1 1z\",\n key: \"1nkz8b\"\n }\n ]\n];\nconst Pin = createLucideIcon(\"pin\", __iconNode);\n\nexport { __iconNode, Pin as default };\n//# sourceMappingURL=pin.mjs.map\n","/* -------------------------------------------------------------------- */\n/* Agent adapter — ClinicalNoteCard. */\n/* */\n/* Read-only presentation surface. Exposes the note's id + structural */\n/* flags (pinned / flagged / attachment kind) so a future MCP UI bridge */\n/* can locate and describe a rendered note. NEVER reads the note body or */\n/* any author identity — those are PHI and stay out of the agent layer. */\n/* -------------------------------------------------------------------- */\n\nimport type { AgentAdapter } from '../../agent/types';\nimport type { ClinicalNoteCardHandle } from './clinical-note-card';\n\nexport const clinicalNoteCardAgent: AgentAdapter<ClinicalNoteCardHandle> = {\n id: 'clinical-note-card',\n capabilities: [],\n state: {\n noteId: {\n type: 'string | undefined',\n descriptionKey: 'ui.agent.clinicalNoteCard.state.noteId',\n description: 'Stable identifier of the rendered note, when supplied.',\n read: (handle) => handle.getNoteId(),\n },\n pinned: {\n type: 'boolean',\n descriptionKey: 'ui.agent.clinicalNoteCard.state.pinned',\n description: 'Whether the note is pinned to the top of the timeline.',\n read: (handle) => handle.isPinned(),\n },\n flagged: {\n type: 'boolean',\n descriptionKey: 'ui.agent.clinicalNoteCard.state.flagged',\n description: 'Whether the note is flagged for follow-up.',\n read: (handle) => handle.isFlagged(),\n },\n attachmentKind: {\n type: \"'patient' | 'carePlan' | 'carePlanEntry' | 'phase' | 'xray' | undefined\",\n descriptionKey: 'ui.agent.clinicalNoteCard.state.attachmentKind',\n description:\n 'Structural kind the note is attached to. Never the attachment identity or content.',\n read: (handle) => handle.getAttachmentKind(),\n },\n },\n actions: {},\n domHooks: {\n root: {\n attr: 'data-component',\n value: 'clinical-note-card',\n description:\n 'Marks the ClinicalNoteCard root. Also emits data-pinned / data-flagged / data-attached-to structural hooks.',\n },\n instanceId: {\n attr: 'data-component-id',\n sourceProp: 'id',\n description: 'Sourced from the id prop — addresses a specific note.',\n },\n },\n};\n","import {\n forwardRef,\n useId,\n useMemo,\n useState,\n type HTMLAttributes,\n type ReactNode,\n} from 'react';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { useTranslation } from 'react-i18next';\nimport { Flag, Pin, FileText, Layers, ScanLine, User } from 'lucide-react';\nimport { Avatar } from '../avatar/avatar';\nimport { Badge } from '../badge/badge';\nimport { Card } from '../card/card';\nimport { Link } from '../link/link';\nimport { Timestamp } from '../timestamp';\nimport { SafeHtml } from '../_shared/safe-html';\nimport { isSafeEntityUrl } from '../_shared/is-safe-url';\nimport { useClampOverflow } from '../../hooks/use-clamp-overflow';\nimport { useAgentRegistration } from '../../agent/registry';\nimport { clinicalNoteCardAgent } from './clinical-note-card.agent';\n\n/* -------------------------------------------------------------------- */\n/* ClinicalNoteCard */\n/* */\n/* A single clinical note — the free-text annotation an operator writes */\n/* against a patient, care plan, treatment phase, or x-ray. Replaces the */\n/* bespoke \"nota clinica\" rows scattered across the platform patient */\n/* timeline. Composes Card + Avatar (author) + Timestamp + Badge/Tag */\n/* (clinical / pinned / flagged) + Link (attachment) and renders the */\n/* markdown body through the shared SafeHtml helper — the only sanctioned */\n/* carrier of dangerouslySetInnerHTML (constraint §8). */\n/* */\n/* All visible text flows through useTranslation('ui') against the */\n/* `clinicalNoteCard.*` namespace. No PHI is read by the agent adapter — */\n/* only the note id and structural flags are exposed. */\n/* -------------------------------------------------------------------- */\n\n/* -------------------------------------------------------------------- */\n/* Public types */\n/* -------------------------------------------------------------------- */\n\n/** Author identity — drives the avatar + visible byline. */\nexport interface ClinicalNoteAuthor {\n /** Display name. */\n name: string;\n /** Optional avatar image URL. */\n avatarUrl?: string;\n}\n\n/**\n * What the note is attached to. Discriminated by `kind`:\n * - `patient` — a free-standing note on the patient record.\n * - `carePlan` — attached to a care plan (estimate / treatment plan),\n * identified by its number, with an optional deep link.\n * - `carePlanEntry` — attached to one entry inside a care plan, naming the\n * care and (optionally) the listed elements.\n * - `phase` — attached to a treatment phase, labelled.\n * - `xray` — attached to an x-ray / radiograph, optionally labelled.\n *\n * Every non-patient kind takes an optional `url`: a safe one turns the chip\n * into a link, an unsafe one keeps the chip.\n */\nexport type NoteAttachment =\n | { kind: 'patient' }\n | { kind: 'carePlan'; number: string; url?: string }\n | {\n kind: 'carePlanEntry';\n careName: string;\n elements?: string[];\n url?: string;\n }\n | { kind: 'phase'; label: string; url?: string }\n | { kind: 'xray'; label?: string; url?: string };\n\n/** Imperative handle exposed to the agent runtime — identifiers / flags only. */\nexport interface ClinicalNoteCardHandle {\n /** The note's stable id, when supplied. */\n getNoteId: () => string | undefined;\n /** Whether the note is currently pinned. */\n isPinned: () => boolean;\n /** Whether the note is currently flagged. */\n isFlagged: () => boolean;\n /** The attachment kind the note is bound to. */\n getAttachmentKind: () => NoteAttachment['kind'] | undefined;\n}\n\nexport interface ClinicalNoteCardProps extends Omit<\n HTMLAttributes<HTMLDivElement>,\n 'aria-label' | 'children' | 'content' | 'title'\n> {\n /** Agent-readiness consumer id, surfaced as `data-component-id`. */\n id?: string;\n /**\n * ISO-8601 timestamp the note refers to (the clinical date). Drives the\n * primary `<Timestamp>`. An empty string renders no timestamp (an undated\n * imported note).\n */\n dateIso: string;\n /**\n * ISO-8601 timestamp the note was authored, when it differs from\n * `dateIso`. Rendered as a secondary \"added\" line.\n */\n createdAtIso?: string;\n /** Author identity — avatar + byline. Optional for system notes. */\n author?: ClinicalNoteAuthor;\n /** The operator the note is credited to: a secondary \"Operator: …\" byline. */\n operatorName?: string;\n /**\n * A deleted note kept for the record. Shows a \"Deleted\" badge and keeps the\n * body out of the DOM until the reader presses \"Show deleted note\". Not an\n * access control: the body is one press away.\n */\n deleted?: boolean;\n /**\n * Whether this is a clinical note (vs. an administrative one). When true a\n * \"Clinical\" badge is shown so the note's nature is unambiguous at a glance.\n */\n clinical?: boolean;\n /** What the note is attached to — drives a contextual chip + optional link. */\n attachedTo?: NoteAttachment;\n /**\n * The note body, authored in a small, safe subset of Markdown (bold,\n * italic, inline code, links, line breaks, simple lists). Rendered through\n * the shared `SafeHtml` helper with the `markdown` sanitiser profile —\n * raw HTML and unsafe link schemes are stripped.\n */\n content: string;\n /**\n * How `content` is authored. `'markdown'` (default) runs the small Markdown\n * subset through the converter; `'html'` treats `content` as rich HTML\n * (e.g. Redactor output) and renders it through SafeHtml's `rich-text`\n * profile, so colours, sizes, tables and images survive sanitisation.\n */\n contentFormat?: 'markdown' | 'html';\n /** Pin the note to the top of a timeline — shows a \"Pinned\" chip. */\n pinned?: boolean;\n /** Flag the note for follow-up / attention — shows a \"Flagged\" chip. */\n flagged?: boolean;\n /**\n * When provided, the pinned chip becomes an `aria-pressed` toggle button so\n * the note can be (un)pinned in place — the pin glyph fills and tints to the\n * accent when pinned (no button fill). Omit for a static, display-only card.\n */\n onTogglePin?: () => void;\n /** As `onTogglePin`, for the flagged state (warning-tinted when flagged). */\n onToggleFlag?: () => void;\n /**\n * Clamp the rendered body to five lines. When the body is taller than the\n * clamp, a \"Read more\" / \"Read less\" disclosure toggles the full text in\n * place — the note stays a read-only display surface, so this is the\n * sighted-user escape hatch (assistive tech reads the full body regardless).\n */\n truncate?: boolean;\n /**\n * `'elevated'` (default) wraps the note in `<Card variant=\"elevated\">`.\n * `'flat'` drops the chrome for use inside an existing Card / timeline rail.\n */\n surface?: 'flat' | 'elevated';\n /** Override the default region aria-label. */\n 'aria-label'?: string;\n}\n\n/* -------------------------------------------------------------------- */\n/* CVA — root */\n/* -------------------------------------------------------------------- */\n\nconst rootVariants = cva('ds:w-full ds:text-[color:var(--foreground)]', {\n variants: {\n surface: { flat: '', elevated: '' },\n },\n defaultVariants: { surface: 'elevated' },\n});\n\n/* Body clamp — applied only when `truncate` is set. Logical-safe. */\nconst bodyVariants = cva(\n [\n 'type-body-sm ds:text-[color:var(--foreground)]',\n 'ds:break-words',\n '[&_a]:ds:underline [&_a]:ds:underline-offset-2',\n '[&_code]:ds:rounded-[var(--radius-sm)] [&_code]:ds:bg-muted/30 [&_code]:ds:ps-[var(--spacing-xs)] [&_code]:ds:pe-[var(--spacing-xs)] [&_code]:ds:font-[family-name:var(--font-mono)]',\n '[&_p]:ds:m-0 [&_p+p]:ds:mt-[var(--spacing-sm)]',\n // `list-disc` / `list-decimal` are load-bearing: the card renders host\n // HTML inside `[data-component]`, where preflight's `list-style: none`\n // still applies. Without them the indent lands but the markers do not.\n 'ds:[&_ul]:m-0 ds:[&_ul]:ps-[var(--spacing-md)] ds:[&_ul]:list-disc ds:[&_ol]:m-0 ds:[&_ol]:ps-[var(--spacing-md)] ds:[&_ol]:list-decimal',\n // Rich-text (Redactor) extras — harmless on markdown notes, which carry\n // none of these tags. Headings, inline images and tables stay readable.\n '[&_h2]:type-title-item [&_h3]:type-title-item [&_h2]:ds:m-0 [&_h3]:ds:m-0',\n '[&_img]:ds:max-w-full [&_img]:ds:h-auto [&_img]:ds:rounded-[var(--radius-sm)]',\n '[&_table]:ds:my-[var(--spacing-sm)] [&_table]:ds:w-full [&_table]:ds:border-collapse',\n '[&_th]:ds:border [&_th]:ds:border-[color:var(--border)] [&_th]:ds:ps-[var(--spacing-xs)] [&_th]:ds:pe-[var(--spacing-xs)] [&_th]:ds:py-[var(--spacing-2xs)] [&_th]:ds:text-start',\n '[&_td]:ds:border [&_td]:ds:border-[color:var(--border)] [&_td]:ds:ps-[var(--spacing-xs)] [&_td]:ds:pe-[var(--spacing-xs)] [&_td]:ds:py-[var(--spacing-2xs)]',\n ].join(' '),\n {\n variants: {\n truncate: {\n true: 'ds:[overflow:hidden] ds:[display:-webkit-box] ds:[-webkit-box-orient:vertical] ds:[-webkit-line-clamp:5]',\n false: '',\n },\n },\n defaultVariants: { truncate: false },\n },\n);\n\n/* -------------------------------------------------------------------- */\n/* Inline affordances — pin / flag toggle + read-more disclosure */\n/* -------------------------------------------------------------------- */\n\n/* Pin / flag toggle. A raw button (not IconButton) so the pressed state\n reads as a FILLED glyph + colour tint rather than a filled button — the\n same treatment as the Sidebar favourite star. The compact box keeps a\n --min-target-size hit area on touch via the ::before expansion. */\nconst noteToggleBase = [\n 'ds:relative ds:inline-flex ds:items-center ds:justify-center ds:shrink-0',\n 'ds:size-7 ds:rounded-[var(--radius-sm)]',\n 'ds:before:absolute ds:before:inset-x-[calc((var(--min-target-size)-100%)/-2)] ds:before:inset-y-[calc((var(--min-target-size)-100%)/-2)] ds:before:content-[\"\"] ds:sm:before:hidden',\n 'ds:hover:bg-[color:var(--muted)]/20',\n 'ds:focus-visible:outline-[length:var(--focus-ring-width)] ds:focus-visible:outline-solid',\n 'ds:focus-visible:outline-[color:var(--ring)] ds:focus-visible:outline-offset-[length:var(--focus-ring-offset)]',\n 'ds:forced-colors:focus-visible:outline-[CanvasText]',\n 'ds:transition-[color,background-color] ds:duration-[var(--animation-duration)]',\n 'ds:motion-reduce:transition-none',\n].join(' ');\n\n/* Read-more / read-less disclosure — an inline text toggle in the flow of\n the body copy (exempt from target-size the same way an inline link is). */\nconst readMoreClasses = [\n 'ds:mt-[var(--spacing-2xs)] ds:inline-flex ds:items-center ds:self-start',\n 'ds:text-[length:var(--font-size-xs)] ds:font-semibold',\n 'ds:underline ds:underline-offset-2 ds:text-[color:var(--primary)] ds:hover:no-underline',\n 'ds:rounded-[var(--radius-sm)]',\n 'ds:focus-visible:outline-[length:var(--focus-ring-width)] ds:focus-visible:outline-solid',\n 'ds:focus-visible:outline-[color:var(--ring)] ds:focus-visible:outline-offset-[length:var(--focus-ring-offset)]',\n 'ds:forced-colors:focus-visible:outline-[CanvasText]',\n].join(' ');\n\nconst deletedDisclosure = cva([\n readMoreClasses,\n 'ds:[min-block-size:var(--min-target-size)] ds:[min-inline-size:var(--min-target-size)]',\n]);\n\ninterface NoteToggleProps {\n /** The lucide glyph, pre-configured with `fill` + size by the caller. */\n icon: ReactNode;\n /** Current pressed state. */\n pressed: boolean;\n /** Accessible label (flips between the on / off verb). */\n label: string;\n /** Colour class applied while pressed (accent for pin, warning for flag). */\n activeClassName: string;\n onToggle: () => void;\n}\n\nfunction NoteToggle({\n icon,\n pressed,\n label,\n activeClassName,\n onToggle,\n}: NoteToggleProps) {\n return (\n <button\n type=\"button\"\n aria-pressed={pressed}\n aria-label={label}\n onClick={onToggle}\n className={[\n noteToggleBase,\n pressed\n ? activeClassName\n : 'ds:text-[color:var(--muted-foreground)] ds:hover:text-[color:var(--foreground)]',\n ].join(' ')}\n >\n {icon}\n </button>\n );\n}\n\n/* -------------------------------------------------------------------- */\n/* Markdown → safe HTML */\n/* */\n/* A dependency-free converter for the small Markdown subset the note */\n/* body supports. The output is then passed to `SafeHtml` (markdown */\n/* profile) which strips everything outside the allow-list — so even a */\n/* hostile note can only ever emit the sanitised tag set. We never call */\n/* dangerouslySetInnerHTML ourselves; SafeHtml is the single carrier. */\n/* -------------------------------------------------------------------- */\n\n/** HTML-escape a raw text run before re-inserting our own safe markup. */\nfunction escapeHtml(input: string): string {\n return input\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/\"/g, '"');\n}\n\n/** Apply inline markdown (bold, italic, code, links) to an escaped run. */\nfunction renderInlineHtml(escaped: string): string {\n let out = escaped;\n // Inline code first so its contents aren't re-processed.\n out = out.replace(/`([^`]+)`/g, '<code>$1</code>');\n out = out.replace(/\\*\\*([^*]+)\\*\\*/g, '<strong>$1</strong>');\n out = out.replace(/\\*([^*]+)\\*/g, '<em>$1</em>');\n // Links — the href is left as-authored; SafeHtml's markdown profile\n // rejects any scheme outside http(s)/mailto/tel at sanitise time.\n out = out.replace(\n /\\[([^\\]]+)\\]\\(([^)\\s]+)\\)/g,\n '<a href=\"$2\" target=\"_blank\" rel=\"noopener noreferrer\">$1</a>',\n );\n return out;\n}\n\n/** Convert the supported Markdown subset into an HTML string. */\nfunction markdownToHtml(input: string): string {\n const blocks = input.split(/\\n{2,}/);\n return blocks\n .map((block) => {\n const lines = block.split('\\n');\n const isUnordered = lines.every((l) => /^\\s*[-*]\\s+/.test(l));\n const isOrdered = lines.every((l) => /^\\s*\\d+\\.\\s+/.test(l));\n if (isUnordered && lines.length > 0) {\n const items = lines\n .map((l) => l.replace(/^\\s*[-*]\\s+/, ''))\n .map((l) => `<li>${renderInlineHtml(escapeHtml(l))}</li>`)\n .join('');\n return `<ul>${items}</ul>`;\n }\n if (isOrdered && lines.length > 0) {\n const items = lines\n .map((l) => l.replace(/^\\s*\\d+\\.\\s+/, ''))\n .map((l) => `<li>${renderInlineHtml(escapeHtml(l))}</li>`)\n .join('');\n return `<ol>${items}</ol>`;\n }\n const paragraph = renderInlineHtml(escapeHtml(block)).replace(\n /\\n/g,\n '<br />',\n );\n return `<p>${paragraph}</p>`;\n })\n .join('');\n}\n\n/* -------------------------------------------------------------------- */\n/* Component */\n/* -------------------------------------------------------------------- */\n\nexport const ClinicalNoteCard = forwardRef<\n HTMLDivElement,\n ClinicalNoteCardProps\n>(\n (\n {\n id,\n dateIso,\n createdAtIso,\n author,\n operatorName,\n deleted,\n clinical,\n attachedTo,\n content,\n contentFormat = 'markdown',\n pinned,\n flagged,\n onTogglePin,\n onToggleFlag,\n truncate = false,\n surface = 'elevated',\n 'aria-label': ariaLabel,\n className,\n ...rest\n },\n ref,\n ) => {\n const { t } = useTranslation();\n const headingId = useId();\n const bodyId = useId();\n const [expanded, setExpanded] = useState(false);\n const [deletedOpen, setDeletedOpen] = useState(false);\n const [previousDeleted, setPreviousDeleted] = useState(!!deleted);\n if (previousDeleted !== !!deleted) {\n setPreviousDeleted(!!deleted);\n setDeletedOpen(false);\n }\n // A deleted note's body stays empty and hidden until the reader reveals it.\n const bodyHidden = !!deleted && !deletedOpen;\n\n // Only measure while clamped — once expanded there's nothing to clip.\n const { ref: clampRef, isOverflowing } = useClampOverflow<HTMLDivElement>(\n truncate && !expanded && !bodyHidden,\n );\n // Show the disclosure once the body overflows; keep it while expanded so\n // the user can collapse again.\n const showReadMore = truncate && !bodyHidden && (isOverflowing || expanded);\n\n // Markdown notes are converted to a safe HTML subset; rich-text (Redactor)\n // notes are passed through verbatim and sanitised by SafeHtml's broader\n // `rich-text` profile at render. Either way SafeHtml is the only carrier.\n const bodyHtml = useMemo(\n () => (contentFormat === 'html' ? content : markdownToHtml(content)),\n [content, contentFormat],\n );\n\n const resolvedAriaLabel = ariaLabel ?? t('clinicalNoteCard.regionLabel');\n\n useAgentRegistration(\n clinicalNoteCardAgent,\n {\n getNoteId: () => id,\n isPinned: () => !!pinned,\n isFlagged: () => !!flagged,\n getAttachmentKind: () => attachedTo?.kind,\n },\n id,\n );\n\n /* ----- Attachment chip / link ----- */\n // A safe host url turns the chip into a link; otherwise it stays a chip.\n const linkOrChip = (\n label: string,\n icon: ReactNode,\n variant: 'info' | 'neutral',\n url: string | undefined,\n ): ReactNode =>\n url && isSafeEntityUrl(url) ? (\n <Link href={url} intent=\"default\" startIcon={icon}>\n {label}\n </Link>\n ) : (\n <Badge variant={variant} size=\"sm\" leading={icon}>\n {label}\n </Badge>\n );\n\n let attachmentNode: ReactNode = null;\n if (attachedTo) {\n switch (attachedTo.kind) {\n case 'patient':\n attachmentNode = (\n <Badge\n variant=\"neutral\"\n size=\"sm\"\n leading={<User aria-hidden=\"true\" />}\n >\n {t('clinicalNoteCard.attachment.patient')}\n </Badge>\n );\n break;\n case 'carePlan':\n attachmentNode = linkOrChip(\n t('clinicalNoteCard.attachment.carePlan', {\n number: attachedTo.number,\n }),\n <FileText aria-hidden=\"true\" />,\n 'info',\n attachedTo.url,\n );\n break;\n case 'carePlanEntry':\n attachmentNode = linkOrChip(\n attachedTo.elements && attachedTo.elements.length > 0\n ? t('clinicalNoteCard.attachment.carePlanEntryWithElements', {\n care: attachedTo.careName,\n elements: attachedTo.elements.join(', '),\n })\n : t('clinicalNoteCard.attachment.carePlanEntry', {\n care: attachedTo.careName,\n }),\n <FileText aria-hidden=\"true\" />,\n 'info',\n attachedTo.url,\n );\n break;\n case 'phase':\n attachmentNode = linkOrChip(\n t('clinicalNoteCard.attachment.phase', { label: attachedTo.label }),\n <Layers aria-hidden=\"true\" />,\n 'neutral',\n attachedTo.url,\n );\n break;\n case 'xray':\n attachmentNode = linkOrChip(\n attachedTo.label\n ? t('clinicalNoteCard.attachment.xrayWithLabel', {\n label: attachedTo.label,\n })\n : t('clinicalNoteCard.attachment.xray'),\n <ScanLine aria-hidden=\"true\" />,\n 'neutral',\n attachedTo.url,\n );\n break;\n }\n }\n\n const inner = (\n <div className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-sm)]\">\n {/* Header: author + date + status chips */}\n <div className=\"ds:flex ds:items-start ds:gap-[var(--spacing-sm)]\">\n {author ? (\n <Avatar\n name={author.name}\n src={author.avatarUrl}\n size=\"sm\"\n className=\"ds:shrink-0\"\n aria-hidden=\"true\"\n role=\"presentation\"\n aria-label={undefined}\n />\n ) : null}\n <div className=\"ds:flex-1 ds:min-w-0 ds:flex ds:flex-col ds:gap-[var(--spacing-2xs)]\">\n {author ? (\n <span\n id={headingId}\n className=\"type-title-item ds:text-[color:var(--foreground)] ds:truncate\"\n >\n {author.name}\n </span>\n ) : (\n <span id={headingId} className=\"ds:sr-only\">\n {resolvedAriaLabel}\n </span>\n )}\n {operatorName ? (\n <span className=\"type-meta ds:text-[color:var(--muted-foreground)] ds:break-words\">\n {t('clinicalNoteCard.operator', { name: operatorName })}\n </span>\n ) : null}\n <span className=\"ds:flex ds:flex-wrap ds:items-center ds:gap-x-[var(--spacing-xs)] ds:gap-y-[var(--spacing-2xs)] ds:empty:hidden\">\n {dateIso ? (\n <Timestamp value={dateIso} shape=\"bare\" size=\"sm\" />\n ) : null}\n {createdAtIso && createdAtIso !== dateIso ? (\n <span className=\"type-meta ds:text-[color:var(--muted-foreground)]\">\n {t('clinicalNoteCard.added')}{' '}\n <Timestamp value={createdAtIso} shape=\"bare\" size=\"sm\" />\n </span>\n ) : null}\n </span>\n </div>\n {deleted ||\n clinical ||\n onTogglePin ||\n onToggleFlag ||\n pinned ||\n flagged ? (\n <span className=\"ds:ms-auto ds:flex ds:shrink-0 ds:flex-wrap ds:items-center ds:justify-end ds:gap-[var(--spacing-xs)]\">\n {deleted ? (\n <Badge variant=\"error\" size=\"sm\">\n {t('clinicalNoteCard.deleted')}\n </Badge>\n ) : null}\n {clinical ? (\n <Badge variant=\"brand\" size=\"sm\">\n {t('clinicalNoteCard.clinical')}\n </Badge>\n ) : null}\n {/* Pin + flag — grouped tightly together, kept clear of the\n clinical badge by the cluster's larger gap. Each is an\n interactive toggle when a handler is supplied (filled glyph +\n tint when active, no button fill), else a static chip. */}\n {onTogglePin || onToggleFlag || pinned || flagged ? (\n <span className=\"ds:flex ds:items-center ds:gap-[var(--spacing-2xs)]\">\n {onTogglePin ? (\n <NoteToggle\n pressed={!!pinned}\n onToggle={onTogglePin}\n label={\n pinned\n ? t('clinicalNoteCard.unpin')\n : t('clinicalNoteCard.pin')\n }\n activeClassName=\"ds:text-[color:var(--accent)]\"\n icon={\n <Pin\n aria-hidden=\"true\"\n className=\"ds:size-4\"\n fill={pinned ? 'currentColor' : 'none'}\n />\n }\n />\n ) : pinned ? (\n <Badge\n variant=\"accent\"\n size=\"sm\"\n leading={<Pin aria-hidden=\"true\" />}\n >\n {t('clinicalNoteCard.pinned')}\n </Badge>\n ) : null}\n {onToggleFlag ? (\n <NoteToggle\n pressed={!!flagged}\n onToggle={onToggleFlag}\n label={\n flagged\n ? t('clinicalNoteCard.unflag')\n : t('clinicalNoteCard.flag')\n }\n activeClassName=\"ds:text-[color:var(--warning-readable)]\"\n icon={\n <Flag\n aria-hidden=\"true\"\n className=\"ds:size-4\"\n fill={flagged ? 'currentColor' : 'none'}\n />\n }\n />\n ) : flagged ? (\n <Badge\n variant=\"warning\"\n size=\"sm\"\n leading={<Flag aria-hidden=\"true\" />}\n >\n {t('clinicalNoteCard.flagged')}\n </Badge>\n ) : null}\n </span>\n ) : null}\n </span>\n ) : null}\n </div>\n\n {deleted ? (\n <button\n type=\"button\"\n aria-expanded={deletedOpen}\n aria-controls={bodyId}\n onClick={() => setDeletedOpen((prev) => !prev)}\n className={deletedDisclosure()}\n >\n {deletedOpen\n ? t('clinicalNoteCard.hideDeleted')\n : t('clinicalNoteCard.showDeleted')}\n </button>\n ) : null}\n {/* Body — rendered via the sanctioned SafeHtml carrier. Markdown notes\n use the tight markdown profile; rich-text notes the broader one.\n When `truncate`, the body clamps to five lines with a read-more\n disclosure once it overflows. */}\n <SafeHtml\n ref={clampRef}\n id={truncate || deleted ? bodyId : undefined}\n hidden={bodyHidden}\n html={bodyHidden ? '' : bodyHtml}\n profile={contentFormat === 'html' ? 'rich-text' : 'markdown'}\n className={bodyVariants({ truncate: truncate && !expanded })}\n />\n {showReadMore ? (\n <button\n type=\"button\"\n aria-expanded={expanded}\n aria-controls={bodyId}\n onClick={() => setExpanded((prev) => !prev)}\n className={readMoreClasses}\n >\n {expanded\n ? t('clinicalNoteCard.readLess')\n : t('clinicalNoteCard.readMore')}\n </button>\n ) : null}\n\n {/* Attachment context */}\n {attachmentNode ? (\n <div className=\"ds:flex ds:flex-wrap ds:items-center ds:gap-[var(--spacing-xs)]\">\n {attachmentNode}\n </div>\n ) : null}\n </div>\n );\n\n return (\n <div\n ref={ref}\n role=\"article\"\n aria-label={resolvedAriaLabel}\n aria-labelledby={headingId}\n data-component=\"clinical-note-card\"\n data-component-id={id}\n data-pinned={pinned ? 'true' : undefined}\n data-flagged={flagged ? 'true' : undefined}\n data-deleted={deleted ? 'true' : undefined}\n data-attached-to={attachedTo?.kind}\n id={id}\n className={rootVariants({ surface, className })}\n {...rest}\n >\n {surface === 'elevated' ? (\n <Card variant=\"elevated\">\n <Card.Body>{inner}</Card.Body>\n </Card>\n ) : (\n inner\n )}\n </div>\n );\n },\n);\n\nClinicalNoteCard.displayName = 'ClinicalNoteCard';\n\n/** Re-export of the surface variant union for downstream typing. */\nexport type ClinicalNoteCardSurface = NonNullable<\n VariantProps<typeof rootVariants>['surface']\n>;\n"],"names":["__iconNode","Flag","createLucideIcon","Pin","clinicalNoteCardAgent","handle","rootVariants","cva","bodyVariants","noteToggleBase","readMoreClasses","deletedDisclosure","NoteToggle","icon","pressed","label","activeClassName","onToggle","jsx","escapeHtml","input","renderInlineHtml","escaped","out","markdownToHtml","block","lines","isUnordered","l","isOrdered","ClinicalNoteCard","forwardRef","id","dateIso","createdAtIso","author","operatorName","deleted","clinical","attachedTo","content","contentFormat","pinned","flagged","onTogglePin","onToggleFlag","truncate","surface","ariaLabel","className","rest","ref","t","useTranslation","headingId","useId","bodyId","expanded","setExpanded","useState","deletedOpen","setDeletedOpen","previousDeleted","setPreviousDeleted","bodyHidden","clampRef","isOverflowing","useClampOverflow","showReadMore","bodyHtml","useMemo","resolvedAriaLabel","useAgentRegistration","linkOrChip","variant","url","isSafeEntityUrl","Link","Badge","attachmentNode","User","FileText","Layers","ScanLine","inner","jsxs","Avatar","Timestamp","prev","SafeHtml","Card"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AASA,MAAMA,KAAa;AAAA,EACjB;AAAA,IACE;AAAA,IACA;AAAA,MACE,GAAG;AAAA,MACH,KAAK;AAAA,IACX;AAAA,EACA;AACA,GACMC,IAAOC,EAAiB,QAAQF,EAAU;AClBhD;AAAA;AAAA;AAAA;AAAA;AAAA;AASA,MAAMA,KAAa;AAAA,EACjB,CAAC,QAAQ,EAAE,GAAG,YAAY,KAAK,SAAQ,CAAE;AAAA,EACzC;AAAA,IACE;AAAA,IACA;AAAA,MACE,GAAG;AAAA,MACH,KAAK;AAAA,IACX;AAAA,EACA;AACA,GACMG,IAAMD,EAAiB,OAAOF,EAAU,GCPjCI,KAA8D;AAAA,EACzE,IAAI;AAAA,EACJ,cAAc,CAAA;AAAA,EACd,OAAO;AAAA,IACL,QAAQ;AAAA,MACN,MAAM;AAAA,MACN,gBAAgB;AAAA,MAChB,aAAa;AAAA,MACb,MAAM,CAACC,MAAWA,EAAO,UAAA;AAAA,IAAU;AAAA,IAErC,QAAQ;AAAA,MACN,MAAM;AAAA,MACN,gBAAgB;AAAA,MAChB,aAAa;AAAA,MACb,MAAM,CAACA,MAAWA,EAAO,SAAA;AAAA,IAAS;AAAA,IAEpC,SAAS;AAAA,MACP,MAAM;AAAA,MACN,gBAAgB;AAAA,MAChB,aAAa;AAAA,MACb,MAAM,CAACA,MAAWA,EAAO,UAAA;AAAA,IAAU;AAAA,IAErC,gBAAgB;AAAA,MACd,MAAM;AAAA,MACN,gBAAgB;AAAA,MAChB,aACE;AAAA,MACF,MAAM,CAACA,MAAWA,EAAO,kBAAA;AAAA,IAAkB;AAAA,EAC7C;AAAA,EAEF,SAAS,CAAA;AAAA,EACT,UAAU;AAAA,IACR,MAAM;AAAA,MACJ,MAAM;AAAA,MACN,OAAO;AAAA,MACP,aACE;AAAA,IAAA;AAAA,IAEJ,YAAY;AAAA,MACV,MAAM;AAAA,MACN,YAAY;AAAA,MACZ,aAAa;AAAA,IAAA;AAAA,EACf;AAEJ,GC+GMC,KAAeC,EAAI,+CAA+C;AAAA,EACtE,UAAU;AAAA,IACR,SAAS,EAAE,MAAM,IAAI,UAAU,GAAA;AAAA,EAAG;AAAA,EAEpC,iBAAiB,EAAE,SAAS,WAAA;AAC9B,CAAC,GAGKC,KAAeD;AAAA,EACnB;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA;AAAA;AAAA;AAAA,IAIA;AAAA;AAAA;AAAA,IAGA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAA,EACA,KAAK,GAAG;AAAA,EACV;AAAA,IACE,UAAU;AAAA,MACR,UAAU;AAAA,QACR,MAAM;AAAA,QACN,OAAO;AAAA,MAAA;AAAA,IACT;AAAA,IAEF,iBAAiB,EAAE,UAAU,GAAA;AAAA,EAAM;AAEvC,GAUME,KAAiB;AAAA,EACrB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,EAAE,KAAK,GAAG,GAIJC,IAAkB;AAAA,EACtB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,EAAE,KAAK,GAAG,GAEJC,KAAoBJ,EAAI;AAAA,EAC5BG;AAAA,EACA;AACF,CAAC;AAcD,SAASE,EAAW;AAAA,EAClB,MAAAC;AAAA,EACA,SAAAC;AAAA,EACA,OAAAC;AAAA,EACA,iBAAAC;AAAA,EACA,UAAAC;AACF,GAAoB;AAClB,SACE,gBAAAC;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,MAAK;AAAA,MACL,gBAAcJ;AAAA,MACd,cAAYC;AAAA,MACZ,SAASE;AAAA,MACT,WAAW;AAAA,QACTR;AAAA,QACAK,IACIE,IACA;AAAA,MAAA,EACJ,KAAK,GAAG;AAAA,MAET,UAAAH;AAAA,IAAA;AAAA,EAAA;AAGP;AAaA,SAASM,EAAWC,GAAuB;AACzC,SAAOA,EACJ,QAAQ,MAAM,OAAO,EACrB,QAAQ,MAAM,MAAM,EACpB,QAAQ,MAAM,MAAM,EACpB,QAAQ,MAAM,QAAQ;AAC3B;AAGA,SAASC,EAAiBC,GAAyB;AACjD,MAAIC,IAAMD;AAEV,SAAAC,IAAMA,EAAI,QAAQ,cAAc,iBAAiB,GACjDA,IAAMA,EAAI,QAAQ,oBAAoB,qBAAqB,GAC3DA,IAAMA,EAAI,QAAQ,gBAAgB,aAAa,GAG/CA,IAAMA,EAAI;AAAA,IACR;AAAA,IACA;AAAA,EAAA,GAEKA;AACT;AAGA,SAASC,GAAeJ,GAAuB;AAE7C,SADeA,EAAM,MAAM,QAAQ,EAEhC,IAAI,CAACK,MAAU;AACd,UAAMC,IAAQD,EAAM,MAAM;AAAA,CAAI,GACxBE,IAAcD,EAAM,MAAM,CAACE,MAAM,cAAc,KAAKA,CAAC,CAAC,GACtDC,IAAYH,EAAM,MAAM,CAACE,MAAM,eAAe,KAAKA,CAAC,CAAC;AAC3D,WAAID,KAAeD,EAAM,SAAS,IAKzB,OAJOA,EACX,IAAI,CAAC,MAAM,EAAE,QAAQ,eAAe,EAAE,CAAC,EACvC,IAAI,CAAC,MAAM,OAAOL,EAAiBF,EAAW,CAAC,CAAC,CAAC,OAAO,EACxD,KAAK,EAAE,CACS,UAEjBU,KAAaH,EAAM,SAAS,IAKvB,OAJOA,EACX,IAAI,CAAC,MAAM,EAAE,QAAQ,gBAAgB,EAAE,CAAC,EACxC,IAAI,CAAC,MAAM,OAAOL,EAAiBF,EAAW,CAAC,CAAC,CAAC,OAAO,EACxD,KAAK,EAAE,CACS,UAMd,MAJWE,EAAiBF,EAAWM,CAAK,CAAC,EAAE;AAAA,MACpD;AAAA,MACA;AAAA,IAAA,CAEoB;AAAA,EACxB,CAAC,EACA,KAAK,EAAE;AACZ;AAMO,MAAMK,KAAmBC;AAAA,EAI9B,CACE;AAAA,IACE,IAAAC;AAAA,IACA,SAAAC;AAAA,IACA,cAAAC;AAAA,IACA,QAAAC;AAAA,IACA,cAAAC;AAAA,IACA,SAAAC;AAAA,IACA,UAAAC;AAAA,IACA,YAAAC;AAAA,IACA,SAAAC;AAAA,IACA,eAAAC,IAAgB;AAAA,IAChB,QAAAC;AAAA,IACA,SAAAC;AAAA,IACA,aAAAC;AAAA,IACA,cAAAC;AAAA,IACA,UAAAC,IAAW;AAAA,IACX,SAAAC,IAAU;AAAA,IACV,cAAcC;AAAA,IACd,WAAAC;AAAA,IACA,GAAGC;AAAA,EAAA,GAELC,MACG;AACH,UAAM,EAAE,GAAAC,EAAA,IAAMC,GAAA,GACRC,IAAYC,EAAA,GACZC,IAASD,EAAA,GACT,CAACE,GAAUC,CAAW,IAAIC,EAAS,EAAK,GACxC,CAACC,GAAaC,CAAc,IAAIF,EAAS,EAAK,GAC9C,CAACG,GAAiBC,CAAkB,IAAIJ,EAAS,CAAC,CAACtB,CAAO;AAChE,IAAIyB,MAAoB,CAAC,CAACzB,MACxB0B,EAAmB,CAAC,CAAC1B,CAAO,GAC5BwB,EAAe,EAAK;AAGtB,UAAMG,IAAa,CAAC,CAAC3B,KAAW,CAACuB,GAG3B,EAAE,KAAKK,GAAU,eAAAC,GAAA,IAAkBC;AAAA,MACvCrB,KAAY,CAACW,KAAY,CAACO;AAAA,IAAA,GAItBI,KAAetB,KAAY,CAACkB,MAAeE,MAAiBT,IAK5DY,KAAWC;AAAA,MACf,MAAO7B,MAAkB,SAASD,IAAUhB,GAAegB,CAAO;AAAA,MAClE,CAACA,GAASC,CAAa;AAAA,IAAA,GAGnB8B,IAAoBvB,KAAaI,EAAE,8BAA8B;AAEvE,IAAAoB;AAAA,MACEpE;AAAA,MACA;AAAA,QACE,WAAW,MAAM4B;AAAA,QACjB,UAAU,MAAM,CAAC,CAACU;AAAA,QAClB,WAAW,MAAM,CAAC,CAACC;AAAA,QACnB,mBAAmB,MAAMJ,KAAA,gBAAAA,EAAY;AAAA,MAAA;AAAA,MAEvCP;AAAA,IAAA;AAKF,UAAMyC,IAAa,CACjB1D,GACAF,GACA6D,IACAC,MAEAA,KAAOC,GAAgBD,CAAG,IACxB,gBAAAzD,EAAC2D,IAAA,EAAK,MAAMF,GAAK,QAAO,WAAU,WAAW9D,GAC1C,UAAAE,EAAA,CACH,IAEA,gBAAAG,EAAC4D,GAAA,EAAM,SAAAJ,IAAkB,MAAK,MAAK,SAAS7D,GACzC,UAAAE,GACH;AAGJ,QAAIgE,IAA4B;AAChC,QAAIxC;AACF,cAAQA,EAAW,MAAA;AAAA,QACjB,KAAK;AACH,UAAAwC,IACE,gBAAA7D;AAAA,YAAC4D;AAAA,YAAA;AAAA,cACC,SAAQ;AAAA,cACR,MAAK;AAAA,cACL,SAAS,gBAAA5D,EAAC8D,IAAA,EAAK,eAAY,OAAA,CAAO;AAAA,cAEjC,YAAE,qCAAqC;AAAA,YAAA;AAAA,UAAA;AAG5C;AAAA,QACF,KAAK;AACH,UAAAD,IAAiBN;AAAA,YACfrB,EAAE,wCAAwC;AAAA,cACxC,QAAQb,EAAW;AAAA,YAAA,CACpB;AAAA,YACD,gBAAArB,EAAC+D,GAAA,EAAS,eAAY,OAAA,CAAO;AAAA,YAC7B;AAAA,YACA1C,EAAW;AAAA,UAAA;AAEb;AAAA,QACF,KAAK;AACH,UAAAwC,IAAiBN;AAAA,YACflC,EAAW,YAAYA,EAAW,SAAS,SAAS,IAChDa,EAAE,yDAAyD;AAAA,cACzD,MAAMb,EAAW;AAAA,cACjB,UAAUA,EAAW,SAAS,KAAK,IAAI;AAAA,YAAA,CACxC,IACDa,EAAE,6CAA6C;AAAA,cAC7C,MAAMb,EAAW;AAAA,YAAA,CAClB;AAAA,YACL,gBAAArB,EAAC+D,GAAA,EAAS,eAAY,OAAA,CAAO;AAAA,YAC7B;AAAA,YACA1C,EAAW;AAAA,UAAA;AAEb;AAAA,QACF,KAAK;AACH,UAAAwC,IAAiBN;AAAA,YACfrB,EAAE,qCAAqC,EAAE,OAAOb,EAAW,OAAO;AAAA,YAClE,gBAAArB,EAACgE,IAAA,EAAO,eAAY,OAAA,CAAO;AAAA,YAC3B;AAAA,YACA3C,EAAW;AAAA,UAAA;AAEb;AAAA,QACF,KAAK;AACH,UAAAwC,IAAiBN;AAAA,YACflC,EAAW,QACPa,EAAE,6CAA6C;AAAA,cAC7C,OAAOb,EAAW;AAAA,YAAA,CACnB,IACDa,EAAE,kCAAkC;AAAA,YACxC,gBAAAlC,EAACiE,IAAA,EAAS,eAAY,OAAA,CAAO;AAAA,YAC7B;AAAA,YACA5C,EAAW;AAAA,UAAA;AAEb;AAAA,MAAA;AAIN,UAAM6C,IACJ,gBAAAC,EAAC,OAAA,EAAI,WAAU,kDAEb,UAAA;AAAA,MAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,qDACZ,UAAA;AAAA,QAAAlD,IACC,gBAAAjB;AAAA,UAACoE;AAAA,UAAA;AAAA,YACC,MAAMnD,EAAO;AAAA,YACb,KAAKA,EAAO;AAAA,YACZ,MAAK;AAAA,YACL,WAAU;AAAA,YACV,eAAY;AAAA,YACZ,MAAK;AAAA,YACL,cAAY;AAAA,UAAA;AAAA,QAAA,IAEZ;AAAA,QACJ,gBAAAkD,EAAC,OAAA,EAAI,WAAU,wEACZ,UAAA;AAAA,UAAAlD,IACC,gBAAAjB;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,IAAIoC;AAAA,cACJ,WAAU;AAAA,cAET,UAAAnB,EAAO;AAAA,YAAA;AAAA,UAAA,IAGV,gBAAAjB,EAAC,QAAA,EAAK,IAAIoC,GAAW,WAAU,cAC5B,UAAAiB,GACH;AAAA,UAEDnC,IACC,gBAAAlB,EAAC,QAAA,EAAK,WAAU,oEACb,UAAAkC,EAAE,6BAA6B,EAAE,MAAMhB,EAAA,CAAc,EAAA,CACxD,IACE;AAAA,UACJ,gBAAAiD,EAAC,QAAA,EAAK,WAAU,mHACb,UAAA;AAAA,YAAApD,IACC,gBAAAf,EAACqE,KAAU,OAAOtD,GAAS,OAAM,QAAO,MAAK,MAAK,IAChD;AAAA,YACHC,KAAgBA,MAAiBD,IAChC,gBAAAoD,EAAC,QAAA,EAAK,WAAU,qDACb,UAAA;AAAA,cAAAjC,EAAE,wBAAwB;AAAA,cAAG;AAAA,gCAC7BmC,GAAA,EAAU,OAAOrD,GAAc,OAAM,QAAO,MAAK,KAAA,CAAK;AAAA,YAAA,EAAA,CACzD,IACE;AAAA,UAAA,EAAA,CACN;AAAA,QAAA,GACF;AAAA,QACCG,KACDC,KACAM,KACAC,KACAH,KACAC,IACE,gBAAA0C,EAAC,QAAA,EAAK,WAAU,yGACb,UAAA;AAAA,UAAAhD,IACC,gBAAAnB,EAAC4D,KAAM,SAAQ,SAAQ,MAAK,MACzB,UAAA1B,EAAE,0BAA0B,EAAA,CAC/B,IACE;AAAA,UACHd,IACC,gBAAApB,EAAC4D,GAAA,EAAM,SAAQ,SAAQ,MAAK,MACzB,UAAA1B,EAAE,2BAA2B,EAAA,CAChC,IACE;AAAA,UAKHR,KAAeC,KAAgBH,KAAUC,IACxC,gBAAA0C,EAAC,QAAA,EAAK,WAAU,uDACb,UAAA;AAAA,YAAAzC,IACC,gBAAA1B;AAAA,cAACN;AAAA,cAAA;AAAA,gBACC,SAAS,CAAC,CAAC8B;AAAA,gBACX,UAAUE;AAAA,gBACV,OAEMQ,EADJV,IACM,2BACA,sBADwB;AAAA,gBAGhC,iBAAgB;AAAA,gBAChB,MACE,gBAAAxB;AAAA,kBAACf;AAAA,kBAAA;AAAA,oBACC,eAAY;AAAA,oBACZ,WAAU;AAAA,oBACV,MAAMuC,IAAS,iBAAiB;AAAA,kBAAA;AAAA,gBAAA;AAAA,cAClC;AAAA,YAAA,IAGFA,IACF,gBAAAxB;AAAA,cAAC4D;AAAA,cAAA;AAAA,gBACC,SAAQ;AAAA,gBACR,MAAK;AAAA,gBACL,SAAS,gBAAA5D,EAACf,GAAA,EAAI,eAAY,OAAA,CAAO;AAAA,gBAEhC,YAAE,yBAAyB;AAAA,cAAA;AAAA,YAAA,IAE5B;AAAA,YACH0C,IACC,gBAAA3B;AAAA,cAACN;AAAA,cAAA;AAAA,gBACC,SAAS,CAAC,CAAC+B;AAAA,gBACX,UAAUE;AAAA,gBACV,OAEMO,EADJT,IACM,4BACA,uBADyB;AAAA,gBAGjC,iBAAgB;AAAA,gBAChB,MACE,gBAAAzB;AAAA,kBAACjB;AAAA,kBAAA;AAAA,oBACC,eAAY;AAAA,oBACZ,WAAU;AAAA,oBACV,MAAM0C,IAAU,iBAAiB;AAAA,kBAAA;AAAA,gBAAA;AAAA,cACnC;AAAA,YAAA,IAGFA,IACF,gBAAAzB;AAAA,cAAC4D;AAAA,cAAA;AAAA,gBACC,SAAQ;AAAA,gBACR,MAAK;AAAA,gBACL,SAAS,gBAAA5D,EAACjB,GAAA,EAAK,eAAY,OAAA,CAAO;AAAA,gBAEjC,YAAE,0BAA0B;AAAA,cAAA;AAAA,YAAA,IAE7B;AAAA,UAAA,EAAA,CACN,IACE;AAAA,QAAA,EAAA,CACN,IACE;AAAA,MAAA,GACN;AAAA,MAECoC,IACC,gBAAAnB;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,MAAK;AAAA,UACL,iBAAe0C;AAAA,UACf,iBAAeJ;AAAA,UACf,SAAS,MAAMK,EAAe,CAAC2B,MAAS,CAACA,CAAI;AAAA,UAC7C,WAAW7E,GAAA;AAAA,UAEV,UACGyC,EADHQ,IACK,iCACA,8BAD8B;AAAA,QACA;AAAA,MAAA,IAEpC;AAAA,MAKJ,gBAAA1C;AAAA,QAACuE;AAAA,QAAA;AAAA,UACC,KAAKxB;AAAA,UACL,IAAInB,KAAYT,IAAUmB,IAAS;AAAA,UACnC,QAAQQ;AAAA,UACR,MAAMA,IAAa,KAAKK;AAAA,UACxB,SAAS5B,MAAkB,SAAS,cAAc;AAAA,UAClD,WAAWjC,GAAa,EAAE,UAAUsC,KAAY,CAACW,GAAU;AAAA,QAAA;AAAA,MAAA;AAAA,MAE5DW,KACC,gBAAAlD;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,MAAK;AAAA,UACL,iBAAeuC;AAAA,UACf,iBAAeD;AAAA,UACf,SAAS,MAAME,EAAY,CAAC8B,MAAS,CAACA,CAAI;AAAA,UAC1C,WAAW9E;AAAA,UAEV,UACG0C,EADHK,IACK,8BACA,2BAD2B;AAAA,QACA;AAAA,MAAA,IAEjC;AAAA,MAGHsB,IACC,gBAAA7D,EAAC,OAAA,EAAI,WAAU,mEACZ,aACH,IACE;AAAA,IAAA,GACN;AAGF,WACE,gBAAAA;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,KAAAiC;AAAA,QACA,MAAK;AAAA,QACL,cAAYoB;AAAA,QACZ,mBAAiBjB;AAAA,QACjB,kBAAe;AAAA,QACf,qBAAmBtB;AAAA,QACnB,eAAaU,IAAS,SAAS;AAAA,QAC/B,gBAAcC,IAAU,SAAS;AAAA,QACjC,gBAAcN,IAAU,SAAS;AAAA,QACjC,oBAAkBE,KAAA,gBAAAA,EAAY;AAAA,QAC9B,IAAAP;AAAA,QACA,WAAW1B,GAAa,EAAE,SAAAyC,GAAS,WAAAE,GAAW;AAAA,QAC7C,GAAGC;AAAA,QAEH,UAAAH,MAAY,aACX,gBAAA7B,EAACwE,GAAA,EAAK,SAAQ,YACZ,UAAA,gBAAAxE,EAACwE,EAAK,MAAL,EAAW,UAAAN,EAAA,CAAM,EAAA,CACpB,IAEAA;AAAA,MAAA;AAAA,IAAA;AAAA,EAIR;AACF;AAEAtD,GAAiB,cAAc;","x_google_ignoreList":[0,1]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"format-price-DNqXPa_q.js","sources":["../../node_modules/lucide-react/dist/esm/icons/banknote.mjs","../../node_modules/lucide-react/dist/esm/icons/languages.mjs","../../src/components/_shared/format-price.ts"],"sourcesContent":["/**\n * @license lucide-react v1.22.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"rect\", { width: \"20\", height: \"12\", x: \"2\", y: \"6\", rx: \"2\", key: \"9lu3g6\" }],\n [\"circle\", { cx: \"12\", cy: \"12\", r: \"2\", key: \"1c9p78\" }],\n [\"path\", { d: \"M6 12h.01M18 12h.01\", key: \"113zkx\" }]\n];\nconst Banknote = createLucideIcon(\"banknote\", __iconNode);\n\nexport { __iconNode, Banknote as default };\n//# sourceMappingURL=banknote.mjs.map\n","/**\n * @license lucide-react v1.22.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.mjs';\n\nconst __iconNode = [\n [\"path\", { d: \"m5 8 6 6\", key: \"1wu5hv\" }],\n [\"path\", { d: \"m4 14 6-6 2-3\", key: \"1k1g8d\" }],\n [\"path\", { d: \"M2 5h12\", key: \"or177f\" }],\n [\"path\", { d: \"M7 2h1\", key: \"1t2jsx\" }],\n [\"path\", { d: \"m22 22-5-10-5 10\", key: \"don7ne\" }],\n [\"path\", { d: \"M14 18h6\", key: \"1m8k6r\" }]\n];\nconst Languages = createLucideIcon(\"languages\", __iconNode);\n\nexport { __iconNode, Languages as default };\n//# sourceMappingURL=languages.mjs.map\n","/**\n * Shared money formatter for the kit's \"price in minor units\" convention.\n *\n * Every component that renders a price takes the amount as an integer in\n * the smallest currency unit (cents / centesimi) plus an ISO-4217\n * `currencyCode`, and the KIT does the formatting — the consumer never\n * hands the kit a pre-rendered string. Lifted from the file-local\n * duplicate in `contact-profile-card.tsx` when PracticeResults adopted\n * the same convention, so both surfaces render an identical price for\n * identical input.\n *\n * Not to be confused with `formatPaymentAmount` (payment-form): that one\n * is the checkout formatter and falls back to an `en` currency string so\n * a raw integer can never leak into a payment UI. This is the lightweight\n * leaf helper for read-only price captions — it lives in `_shared` so a\n * SERP card can use it without pulling the payment-form module graph in.\n * Both apply the same zero-decimal divisor rule; only the failure\n * behaviour differs.\n */\n\n/**\n * Currencies with no minor unit — the integer IS the major amount, so\n * dividing by 100 would render the price 100× too small. Pinned to\n * Stripe's list: https://stripe.com/docs/currencies#zero-decimal\n *\n * Kept in step with `ZERO_DECIMAL_CURRENCIES` in\n * `src/components/payment-form/payment-form.tsx`. Consolidating the two\n * into one exported set is a follow-up — payment-form is a shipped\n * subpath entry and re-pointing it is out of scope here.\n */\nconst ZERO_DECIMAL_CURRENCIES = new Set<string>([\n 'BIF',\n 'CLP',\n 'DJF',\n 'GNF',\n 'IDR',\n 'JPY',\n 'KMF',\n 'KRW',\n 'MGA',\n 'PYG',\n 'RWF',\n 'UGX',\n 'VND',\n 'VUV',\n 'XAF',\n 'XOF',\n 'XPF',\n]);\n\nexport function formatPrice(\n minorUnits: number,\n currency: string,\n locale: string,\n): string {\n const iso = currency.toUpperCase();\n const major = ZERO_DECIMAL_CURRENCIES.has(iso)\n ? minorUnits\n : minorUnits / 100;\n try {\n return new Intl.NumberFormat(locale, {\n style: 'currency',\n currency: iso,\n }).format(major);\n } catch {\n // Locale or currency code rejected. Fall back to a plain amount — but\n // keep the zero-decimal rule, or the fallback would reintroduce the very\n // bug this module exists to fix (`JPY 8000` reading as \"8000.00\"), and\n // keep the ISO code so the reader is not left with a bare number.\n const amount = ZERO_DECIMAL_CURRENCIES.has(iso)\n ? String(major)\n : major.toFixed(2);\n return `${amount} ${iso}`;\n }\n}\n"],"names":["__iconNode","Banknote","createLucideIcon","Languages","ZERO_DECIMAL_CURRENCIES","formatPrice","minorUnits","currency","locale","iso","major"],"mappings":";AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AASA,MAAMA,IAAa;AAAA,EACjB,CAAC,QAAQ,EAAE,OAAO,MAAM,QAAQ,MAAM,GAAG,KAAK,GAAG,KAAK,IAAI,KAAK,KAAK,SAAQ,CAAE;AAAA,EAC9E,CAAC,UAAU,EAAE,IAAI,MAAM,IAAI,MAAM,GAAG,KAAK,KAAK,UAAU;AAAA,EACxD,CAAC,QAAQ,EAAE,GAAG,uBAAuB,KAAK,SAAQ,CAAE;AACtD,GACMC,IAAWC,EAAiB,YAAYF,CAAU;ACdxD;AAAA;AAAA;AAAA;AAAA;AAAA;AASA,MAAMA,IAAa;AAAA,EACjB,CAAC,QAAQ,EAAE,GAAG,YAAY,KAAK,SAAQ,CAAE;AAAA,EACzC,CAAC,QAAQ,EAAE,GAAG,iBAAiB,KAAK,SAAQ,CAAE;AAAA,EAC9C,CAAC,QAAQ,EAAE,GAAG,WAAW,KAAK,SAAQ,CAAE;AAAA,EACxC,CAAC,QAAQ,EAAE,GAAG,UAAU,KAAK,SAAQ,CAAE;AAAA,EACvC,CAAC,QAAQ,EAAE,GAAG,oBAAoB,KAAK,SAAQ,CAAE;AAAA,EACjD,CAAC,QAAQ,EAAE,GAAG,YAAY,KAAK,SAAQ,CAAE;AAC3C,GACMG,IAAYD,EAAiB,aAAaF,CAAU,GCapDI,wBAA8B,IAAY;AAAA,EAC9C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAEM,SAASC,EACdC,GACAC,GACAC,GACQ;AACR,QAAMC,IAAMF,EAAS,YAAA,GACfG,IAAQN,EAAwB,IAAIK,CAAG,IACzCH,IACAA,IAAa;AACjB,MAAI;AACF,WAAO,IAAI,KAAK,aAAaE,GAAQ;AAAA,MACnC,OAAO;AAAA,MACP,UAAUC;AAAA,IAAA,CACX,EAAE,OAAOC,CAAK;AAAA,EACjB,QAAQ;AAQN,WAAO,GAHQN,EAAwB,IAAIK,CAAG,IAC1C,OAAOC,CAAK,IACZA,EAAM,QAAQ,CAAC,CACH,IAAID,CAAG;AAAA,EACzB;AACF;","x_google_ignoreList":[0,1]}
|