@alfadocs/ui-kit-debug 0.75.0 → 0.78.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (151) hide show
  1. package/dist/_chunks/{address-fields-COyjgqxA.js → address-fields-7k59FnJ6.js} +2 -2
  2. package/dist/_chunks/{address-fields-COyjgqxA.js.map → address-fields-7k59FnJ6.js.map} +1 -1
  3. package/dist/_chunks/{booking-B1Qkcl3c.js → booking-CLmeXtGv.js} +2 -2
  4. package/dist/_chunks/{booking-B1Qkcl3c.js.map → booking-CLmeXtGv.js.map} +1 -1
  5. package/dist/_chunks/{country-select-DYHDLEjG.js → country-select-BN9nedAp.js} +2 -2
  6. package/dist/_chunks/{country-select-DYHDLEjG.js.map → country-select-BN9nedAp.js.map} +1 -1
  7. package/dist/_chunks/document-preview-nwfulDEs.js +290 -0
  8. package/dist/_chunks/document-preview-nwfulDEs.js.map +1 -0
  9. package/dist/_chunks/{file-manager-UF8dkQF1.js → file-manager-DfTG7bxx.js} +394 -399
  10. package/dist/_chunks/file-manager-DfTG7bxx.js.map +1 -0
  11. package/dist/_chunks/flag-Cnmivlrl.js +641 -0
  12. package/dist/_chunks/{flag-DZ6V7-hU.js.map → flag-Cnmivlrl.js.map} +1 -1
  13. package/dist/_chunks/{header-settings-4cwQzeFc.js → header-settings-DMfdx0Vq.js} +2 -2
  14. package/dist/_chunks/{header-settings-4cwQzeFc.js.map → header-settings-DMfdx0Vq.js.map} +1 -1
  15. package/dist/_chunks/{locale-picker-GNF3lo8K.js → locale-picker-EyvPrwDc.js} +2 -2
  16. package/dist/_chunks/{locale-picker-GNF3lo8K.js.map → locale-picker-EyvPrwDc.js.map} +1 -1
  17. package/dist/_chunks/{marketplace-app-shell-D_1tF4La.js → marketplace-app-shell-Bxq1PYAj.js} +2 -2
  18. package/dist/_chunks/{marketplace-app-shell-D_1tF4La.js.map → marketplace-app-shell-Bxq1PYAj.js.map} +1 -1
  19. package/dist/_chunks/{patient-details-DP4wKyq4.js → patient-details-zy76MRh7.js} +3 -3
  20. package/dist/_chunks/{patient-details-DP4wKyq4.js.map → patient-details-zy76MRh7.js.map} +1 -1
  21. package/dist/_chunks/periodontal-chart-CYBhr9vc.js +1305 -0
  22. package/dist/_chunks/periodontal-chart-CYBhr9vc.js.map +1 -0
  23. package/dist/_chunks/{phone-input-dtnrvnZf.js → phone-input-D00ZBAm-.js} +2 -2
  24. package/dist/_chunks/{phone-input-dtnrvnZf.js.map → phone-input-D00ZBAm-.js.map} +1 -1
  25. package/dist/agent-catalog.json +149 -1
  26. package/dist/agent-i18n/en.json +2 -0
  27. package/dist/components/address-fields/index.js +1 -1
  28. package/dist/components/booking/index.js +1 -1
  29. package/dist/components/country-select/index.js +1 -1
  30. package/dist/components/document-preview/document-preview.d.ts +35 -2
  31. package/dist/components/document-preview/document-preview.d.ts.map +1 -1
  32. package/dist/components/document-preview/index.d.ts +1 -1
  33. package/dist/components/document-preview/index.d.ts.map +1 -1
  34. package/dist/components/document-preview/index.js +1 -1
  35. package/dist/components/file-manager/file-manager.d.ts.map +1 -1
  36. package/dist/components/file-manager/index.js +1 -1
  37. package/dist/components/file-manager/list-view.d.ts.map +1 -1
  38. package/dist/components/flag/flag.d.ts.map +1 -1
  39. package/dist/components/flag/index.js +1 -1
  40. package/dist/components/header-settings/index.js +1 -1
  41. package/dist/components/locale-picker/index.js +1 -1
  42. package/dist/components/patient-details/index.js +1 -1
  43. package/dist/components/periodontal-chart/index.d.ts +2 -2
  44. package/dist/components/periodontal-chart/index.d.ts.map +1 -1
  45. package/dist/components/periodontal-chart/index.js +8 -7
  46. package/dist/components/periodontal-chart/periodontal-chart-data.d.ts +45 -0
  47. package/dist/components/periodontal-chart/periodontal-chart-data.d.ts.map +1 -1
  48. package/dist/components/periodontal-chart/periodontal-chart.agent.d.ts.map +1 -1
  49. package/dist/components/periodontal-chart/periodontal-chart.d.ts +3 -1
  50. package/dist/components/periodontal-chart/periodontal-chart.d.ts.map +1 -1
  51. package/dist/components/phone-input/index.js +1 -1
  52. package/dist/i18n/locales/ar.d.ts +8 -1
  53. package/dist/i18n/locales/ar.d.ts.map +1 -1
  54. package/dist/i18n/locales/ar.js +8 -1
  55. package/dist/i18n/locales/ar.js.map +1 -1
  56. package/dist/i18n/locales/de.d.ts +8 -1
  57. package/dist/i18n/locales/de.d.ts.map +1 -1
  58. package/dist/i18n/locales/de.js +8 -1
  59. package/dist/i18n/locales/de.js.map +1 -1
  60. package/dist/i18n/locales/el.d.ts +8 -1
  61. package/dist/i18n/locales/el.d.ts.map +1 -1
  62. package/dist/i18n/locales/el.js +8 -1
  63. package/dist/i18n/locales/el.js.map +1 -1
  64. package/dist/i18n/locales/en.d.ts +8 -1
  65. package/dist/i18n/locales/en.d.ts.map +1 -1
  66. package/dist/i18n/locales/en.js +8 -1
  67. package/dist/i18n/locales/en.js.map +1 -1
  68. package/dist/i18n/locales/es.d.ts +8 -1
  69. package/dist/i18n/locales/es.d.ts.map +1 -1
  70. package/dist/i18n/locales/es.js +8 -1
  71. package/dist/i18n/locales/es.js.map +1 -1
  72. package/dist/i18n/locales/fr.d.ts +8 -1
  73. package/dist/i18n/locales/fr.d.ts.map +1 -1
  74. package/dist/i18n/locales/fr.js +8 -1
  75. package/dist/i18n/locales/fr.js.map +1 -1
  76. package/dist/i18n/locales/hi.d.ts +8 -1
  77. package/dist/i18n/locales/hi.d.ts.map +1 -1
  78. package/dist/i18n/locales/hi.js +8 -1
  79. package/dist/i18n/locales/hi.js.map +1 -1
  80. package/dist/i18n/locales/it.d.ts +8 -1
  81. package/dist/i18n/locales/it.d.ts.map +1 -1
  82. package/dist/i18n/locales/it.js +8 -1
  83. package/dist/i18n/locales/it.js.map +1 -1
  84. package/dist/i18n/locales/ja.d.ts +8 -1
  85. package/dist/i18n/locales/ja.d.ts.map +1 -1
  86. package/dist/i18n/locales/ja.js +8 -1
  87. package/dist/i18n/locales/ja.js.map +1 -1
  88. package/dist/i18n/locales/nl.d.ts +8 -1
  89. package/dist/i18n/locales/nl.d.ts.map +1 -1
  90. package/dist/i18n/locales/nl.js +8 -1
  91. package/dist/i18n/locales/nl.js.map +1 -1
  92. package/dist/i18n/locales/pl.d.ts +8 -1
  93. package/dist/i18n/locales/pl.d.ts.map +1 -1
  94. package/dist/i18n/locales/pl.js +8 -1
  95. package/dist/i18n/locales/pl.js.map +1 -1
  96. package/dist/i18n/locales/pt.d.ts +8 -1
  97. package/dist/i18n/locales/pt.d.ts.map +1 -1
  98. package/dist/i18n/locales/pt.js +8 -1
  99. package/dist/i18n/locales/pt.js.map +1 -1
  100. package/dist/i18n/locales/ro.d.ts +8 -1
  101. package/dist/i18n/locales/ro.d.ts.map +1 -1
  102. package/dist/i18n/locales/ro.js +8 -1
  103. package/dist/i18n/locales/ro.js.map +1 -1
  104. package/dist/i18n/locales/ru.d.ts +8 -1
  105. package/dist/i18n/locales/ru.d.ts.map +1 -1
  106. package/dist/i18n/locales/ru.js +8 -1
  107. package/dist/i18n/locales/ru.js.map +1 -1
  108. package/dist/i18n/locales/sq.d.ts +8 -1
  109. package/dist/i18n/locales/sq.d.ts.map +1 -1
  110. package/dist/i18n/locales/sq.js +8 -1
  111. package/dist/i18n/locales/sq.js.map +1 -1
  112. package/dist/i18n/locales/sv.d.ts +8 -1
  113. package/dist/i18n/locales/sv.d.ts.map +1 -1
  114. package/dist/i18n/locales/sv.js +8 -1
  115. package/dist/i18n/locales/sv.js.map +1 -1
  116. package/dist/i18n/locales/tr.d.ts +8 -1
  117. package/dist/i18n/locales/tr.d.ts.map +1 -1
  118. package/dist/i18n/locales/tr.js +8 -1
  119. package/dist/i18n/locales/tr.js.map +1 -1
  120. package/dist/i18n/locales/zh.d.ts +8 -1
  121. package/dist/i18n/locales/zh.d.ts.map +1 -1
  122. package/dist/i18n/locales/zh.js +8 -1
  123. package/dist/i18n/locales/zh.js.map +1 -1
  124. package/dist/index.js +217 -216
  125. package/dist/locales/ar.json +8 -1
  126. package/dist/locales/de.json +8 -1
  127. package/dist/locales/el.json +8 -1
  128. package/dist/locales/en.json +8 -1
  129. package/dist/locales/es.json +8 -1
  130. package/dist/locales/fr.json +8 -1
  131. package/dist/locales/hi.json +8 -1
  132. package/dist/locales/it.json +8 -1
  133. package/dist/locales/ja.json +8 -1
  134. package/dist/locales/nl.json +8 -1
  135. package/dist/locales/pl.json +8 -1
  136. package/dist/locales/pt.json +8 -1
  137. package/dist/locales/ro.json +8 -1
  138. package/dist/locales/ru.json +8 -1
  139. package/dist/locales/sq.json +8 -1
  140. package/dist/locales/sv.json +8 -1
  141. package/dist/locales/tr.json +8 -1
  142. package/dist/locales/zh.json +8 -1
  143. package/dist/patterns/marketplace-app-shell/index.js +1 -1
  144. package/dist/tokens.css +2 -1
  145. package/package.json +1 -1
  146. package/dist/_chunks/document-preview-CGSM_au9.js +0 -181
  147. package/dist/_chunks/document-preview-CGSM_au9.js.map +0 -1
  148. package/dist/_chunks/file-manager-UF8dkQF1.js.map +0 -1
  149. package/dist/_chunks/flag-DZ6V7-hU.js +0 -637
  150. package/dist/_chunks/periodontal-chart-D8hOFmde.js +0 -1173
  151. package/dist/_chunks/periodontal-chart-D8hOFmde.js.map +0 -1
@@ -1,1173 +0,0 @@
1
- import { jsx as s, jsxs as m } from "react/jsx-runtime";
2
- import { forwardRef as Xe, useRef as fe, useState as Ze, useCallback as R, useMemo as be, useImperativeHandle as et } from "react";
3
- import { c as Ce } from "./index-D2ZczOXr.js";
4
- import { useTranslation as tt } from "react-i18next";
5
- import { u as rt } from "./registry-DvAUVLHh.js";
6
- import { e as st, d as nt, f as Me, P as ke, F as at, t as ot } from "./tooth-data-BwuoKFf4.js";
7
- import { P as it } from "./periodontal-chart-card-WVjJAheq.js";
8
- const _ = {
9
- type: "string",
10
- description: "FDI tooth id ('11'–'48' permanent, '51'–'85' primary)."
11
- }, H = {
12
- enum: ["db", "b", "mb", "dl", "l", "ml"],
13
- description: "Probing site: (m/d)b = mesio-/disto-/mid buccal, (m/d)l = mesio-/disto-/mid lingual."
14
- }, ve = {
15
- type: "integer",
16
- description: "Whole millimetres — perio probing is recorded in integer mm."
17
- }, lt = {
18
- type: "object",
19
- properties: {
20
- meanPocketDepthMm: { type: ["number", "null"] },
21
- meanAttachmentLevelMm: { type: ["number", "null"] },
22
- plaquePercent: { type: ["number", "null"] },
23
- bleedingPercent: { type: ["number", "null"] },
24
- scoredSiteCount: { type: "number" },
25
- deepPocketCount: { type: "number" }
26
- }
27
- };
28
- function ct(a) {
29
- if (!a) return null;
30
- const r = { ...a };
31
- return delete r.note, r;
32
- }
33
- const dt = {
34
- id: "periodontal-chart",
35
- // pick — focus a measurement input (transient); set_value / edit_inline —
36
- // record per-site probing readings and per-tooth flags.
37
- capabilities: ["pick", "set_value", "edit_inline"],
38
- state: {
39
- indices: {
40
- type: "object",
41
- descriptionKey: "ui.agent.periodontalChart.state.indices",
42
- description: "Derived whole-mouth indices: mean probing depth, mean attachment level, plaque %, bleeding %, scored-site and deep-pocket counts. Aggregates only — no per-site or patient data.",
43
- read: (a) => a.getIndices()
44
- },
45
- missingTeeth: {
46
- type: "string[]",
47
- descriptionKey: "ui.agent.periodontalChart.state.missingTeeth",
48
- description: "FDI ids of every tooth flagged as missing.",
49
- read: (a) => a.missingTeeth()
50
- },
51
- chartedTeeth: {
52
- type: "string[]",
53
- descriptionKey: "ui.agent.periodontalChart.state.chartedTeeth",
54
- description: "FDI ids of teeth carrying at least one probing reading or flag. Identifiers only — never patient identity or the free-text note.",
55
- read: (a) => Object.entries(a.getValue()).filter(([, r]) => r.missing || r.implant || r.mobility != null || r.furcation && Object.keys(r.furcation).length > 0 ? !0 : (r.sites ? Object.values(r.sites) : []).some(
56
- (u) => u != null && (u.pocketDepthMm != null || u.recessionMm != null || u.bleeding || u.plaque || u.suppuration)
57
- )).map(([r]) => r)
58
- }
59
- },
60
- actions: {
61
- focus_site: {
62
- safety: "read",
63
- argsType: '{ fdi: string; site: PeriodontalSiteId; field: "pocketDepthMm" | "recessionMm" }',
64
- argsSchema: {
65
- type: "object",
66
- properties: {
67
- fdi: _,
68
- site: H,
69
- field: { enum: ["pocketDepthMm", "recessionMm"] }
70
- },
71
- required: ["fdi", "site", "field"]
72
- },
73
- idempotent: !0,
74
- descriptionKey: "ui.agent.periodontalChart.actions.focusSite",
75
- description: "Move focus to a specific probing-measurement input.",
76
- invoke: (a, r) => {
77
- a.focusSite(r.fdi, r.site, r.field);
78
- }
79
- },
80
- get_tooth: {
81
- safety: "read",
82
- argsType: "{ fdi: string }",
83
- argsSchema: {
84
- type: "object",
85
- properties: { fdi: _ },
86
- required: ["fdi"]
87
- },
88
- returns: "object | null",
89
- returnsSchema: { type: ["object", "null"] },
90
- idempotent: !0,
91
- descriptionKey: "ui.agent.periodontalChart.actions.getTooth",
92
- description: "Read one tooth’s structural readings (sites, flags, mobility, furcation). The free-text note is never returned.",
93
- invoke: (a, r) => ct(a.getTooth(r.fdi))
94
- },
95
- get_indices: {
96
- safety: "read",
97
- argsType: "{}",
98
- argsSchema: { type: "object", properties: {} },
99
- returns: "PeriodontalIndices",
100
- returnsSchema: lt,
101
- idempotent: !0,
102
- descriptionKey: "ui.agent.periodontalChart.actions.getIndices",
103
- description: "Read the derived whole-mouth summary indices.",
104
- invoke: (a) => a.getIndices()
105
- },
106
- set_depth: {
107
- safety: "write",
108
- argsType: "{ fdi: string; site: PeriodontalSiteId; mm: number }",
109
- argsSchema: {
110
- type: "object",
111
- properties: { fdi: _, site: H, mm: ve },
112
- required: ["fdi", "site", "mm"]
113
- },
114
- idempotent: !0,
115
- descriptionKey: "ui.agent.periodontalChart.actions.setDepth",
116
- description: "Record the probing pocket depth (mm) at a site.",
117
- invoke: (a, r) => {
118
- a.setSite(r.fdi, r.site, {
119
- pocketDepthMm: Math.max(0, r.mm)
120
- });
121
- }
122
- },
123
- set_recession: {
124
- safety: "write",
125
- argsType: "{ fdi: string; site: PeriodontalSiteId; mm: number }",
126
- argsSchema: {
127
- type: "object",
128
- properties: { fdi: _, site: H, mm: ve },
129
- required: ["fdi", "site", "mm"]
130
- },
131
- idempotent: !0,
132
- descriptionKey: "ui.agent.periodontalChart.actions.setRecession",
133
- description: "Record the gingival recession (mm) at a site.",
134
- invoke: (a, r) => {
135
- a.setSite(r.fdi, r.site, { recessionMm: r.mm });
136
- }
137
- },
138
- toggle_bleeding: {
139
- safety: "write",
140
- argsType: "{ fdi: string; site: PeriodontalSiteId; value: boolean }",
141
- argsSchema: {
142
- type: "object",
143
- properties: {
144
- fdi: _,
145
- site: H,
146
- value: { type: "boolean" }
147
- },
148
- required: ["fdi", "site", "value"]
149
- },
150
- idempotent: !0,
151
- descriptionKey: "ui.agent.periodontalChart.actions.toggleBleeding",
152
- description: "Set bleeding on probing at a site.",
153
- invoke: (a, r) => {
154
- a.setSite(r.fdi, r.site, { bleeding: r.value });
155
- }
156
- },
157
- toggle_plaque: {
158
- safety: "write",
159
- argsType: "{ fdi: string; site: PeriodontalSiteId; value: boolean }",
160
- argsSchema: {
161
- type: "object",
162
- properties: {
163
- fdi: _,
164
- site: H,
165
- value: { type: "boolean" }
166
- },
167
- required: ["fdi", "site", "value"]
168
- },
169
- idempotent: !0,
170
- descriptionKey: "ui.agent.periodontalChart.actions.togglePlaque",
171
- description: "Set plaque presence at a site.",
172
- invoke: (a, r) => {
173
- a.setSite(r.fdi, r.site, { plaque: r.value });
174
- }
175
- },
176
- set_mobility: {
177
- safety: "write",
178
- argsType: "{ fdi: string; grade: 0 | 1 | 2 | 3 }",
179
- argsSchema: {
180
- type: "object",
181
- properties: {
182
- fdi: _,
183
- grade: { enum: [0, 1, 2, 3] }
184
- },
185
- required: ["fdi", "grade"]
186
- },
187
- idempotent: !0,
188
- descriptionKey: "ui.agent.periodontalChart.actions.setMobility",
189
- description: "Set a tooth’s Miller mobility grade (0–3).",
190
- invoke: (a, r) => {
191
- a.setTooth(r.fdi, { mobility: r.grade });
192
- }
193
- },
194
- set_missing: {
195
- safety: "write",
196
- argsType: "{ fdi: string; value: boolean }",
197
- argsSchema: {
198
- type: "object",
199
- properties: { fdi: _, value: { type: "boolean" } },
200
- required: ["fdi", "value"]
201
- },
202
- idempotent: !0,
203
- descriptionKey: "ui.agent.periodontalChart.actions.setMissing",
204
- description: "Flag a tooth present or absent.",
205
- invoke: (a, r) => {
206
- a.setTooth(r.fdi, { missing: r.value });
207
- }
208
- },
209
- clear_tooth: {
210
- safety: "destructive",
211
- argsType: "{ fdi: string }",
212
- argsSchema: {
213
- type: "object",
214
- properties: { fdi: _ },
215
- required: ["fdi"]
216
- },
217
- idempotent: !0,
218
- descriptionKey: "ui.agent.periodontalChart.actions.clearTooth",
219
- description: "Clear every reading from a tooth.",
220
- invoke: (a, r) => {
221
- a.clearTooth(r.fdi);
222
- }
223
- }
224
- },
225
- domHooks: {
226
- root: {
227
- attr: "data-component",
228
- value: "periodontal-chart",
229
- description: "Marks the PeriodontalChart root group."
230
- },
231
- instanceId: {
232
- attr: "data-component-id",
233
- sourceProp: "id",
234
- description: "Sourced from the id prop."
235
- },
236
- item: {
237
- attr: "data-fdi",
238
- description: "Each tooth column header carries its FDI id as `data-fdi`. Every measurement input also carries `data-fdi` + `data-site` + `data-field`. The root `data-mode` exposes interactive vs display."
239
- }
240
- }
241
- }, se = ["db", "b", "mb"], ut = ["dl", "l", "ml"];
242
- function ye(a) {
243
- return a === "buccal" ? se : ut;
244
- }
245
- const we = 4, ne = 6, pt = 20, mt = 5;
246
- function ht(a, r = we, h = ne) {
247
- return a == null || !Number.isFinite(a) ? "normal" : a >= h ? "severe" : a >= r ? "moderate" : "normal";
248
- }
249
- const gt = {
250
- 18: { buccal: 1, lingual: 2 },
251
- 17: { buccal: 1, lingual: 2 },
252
- 16: { buccal: 1, lingual: 2 },
253
- 15: { buccal: 2, lingual: 2 },
254
- 14: { buccal: 0, lingual: 2 },
255
- 24: { buccal: 0, lingual: 2 },
256
- 25: { buccal: 2, lingual: 2 },
257
- 26: { buccal: 1, lingual: 2 },
258
- 27: { buccal: 1, lingual: 2 },
259
- 28: { buccal: 1, lingual: 2 },
260
- 48: { buccal: 1, lingual: 1 },
261
- 47: { buccal: 1, lingual: 1 },
262
- 46: { buccal: 1, lingual: 1 },
263
- 36: { buccal: 1, lingual: 1 },
264
- 37: { buccal: 1, lingual: 1 },
265
- 38: { buccal: 1, lingual: 1 }
266
- };
267
- function ft(a, r) {
268
- var h;
269
- return ((h = gt[a]) == null ? void 0 : h[r]) ?? 0;
270
- }
271
- const bt = ke.slice(0, 16), vt = ke.slice(16), yt = Me.slice(0, 10), xt = Me.slice(10);
272
- function Pe(a) {
273
- return a === "primary" ? { upper: yt, lower: xt } : {
274
- upper: bt,
275
- lower: vt
276
- };
277
- }
278
- function xe(a, r) {
279
- return r === "universal" ? st[a] ?? a : r === "palmer" ? nt[a] ?? a : a;
280
- }
281
- function W(a) {
282
- const r = Math.round(a * 10) / 10;
283
- return r === 0 ? 0 : r;
284
- }
285
- function Ne(a) {
286
- let r = 0, h = 0, u = 0, b = 0, S = 0, I = 0;
287
- for (const L of Object.values(a))
288
- if (!(L.missing || !L.sites))
289
- for (const E of Object.values(L.sites)) {
290
- if (!E) continue;
291
- const D = E.pocketDepthMm;
292
- D == null || !Number.isFinite(D) || (u += 1, r += D, h += D + (E.recessionMm ?? 0), D >= ne && (I += 1), E.bleeding && (b += 1), E.plaque && (S += 1));
293
- }
294
- return u === 0 ? {
295
- meanPocketDepthMm: null,
296
- meanAttachmentLevelMm: null,
297
- plaquePercent: null,
298
- bleedingPercent: null,
299
- scoredSiteCount: 0,
300
- deepPocketCount: 0
301
- } : {
302
- meanPocketDepthMm: W(r / u),
303
- meanAttachmentLevelMm: W(h / u),
304
- plaquePercent: W(S / u * 100),
305
- bleedingPercent: W(b / u * 100),
306
- scoredSiteCount: u,
307
- deepPocketCount: I
308
- };
309
- }
310
- function Lt(a = "permanent") {
311
- const { upper: r, lower: h } = Pe(a), u = {};
312
- for (const b of [...r, ...h]) u[b] = {};
313
- return u;
314
- }
315
- function qt(a) {
316
- const r = [];
317
- for (const [h, u] of Object.entries(a))
318
- if (!(u.missing || !u.sites))
319
- for (const b of it) {
320
- const S = u.sites[b];
321
- if (!S) continue;
322
- const { pocketDepthMm: I, recessionMm: L, bleeding: E, suppuration: D } = S;
323
- I == null && L == null && !E && !D || r.push({
324
- tooth: h,
325
- site: b,
326
- pocketDepthMm: I,
327
- recessionMm: L,
328
- bleeding: E,
329
- suppuration: D
330
- });
331
- }
332
- return r;
333
- }
334
- function Ot(a) {
335
- const r = {};
336
- for (const [h, u] of Object.entries(a))
337
- u.mobility != null && (r[h] = u.mobility);
338
- return r;
339
- }
340
- const Nt = Ce(
341
- "ds:w-full ds:flex ds:flex-col ds:gap-[var(--spacing-lg)] ds:text-[color:var(--foreground)]",
342
- {
343
- variants: {
344
- // Disabled is conveyed by the inputs' own `disabled` state (native
345
- // disabled controls are excluded from the axe contrast check). We must
346
- // NOT dim the whole root with opacity — that would drop the legend,
347
- // captions and headers below the AA contrast floor.
348
- disabled: { true: "ds:cursor-not-allowed", false: "" }
349
- },
350
- defaultVariants: { disabled: !1 }
351
- }
352
- ), Ct = Ce(
353
- "ds:h-6 ds:w-[3.5ch] ds:rounded-[var(--radius-sm)] ds:border ds:bg-[var(--background)] ds:text-center ds:tabular-nums ds:[font-variant-numeric:var(--font-feature-tabular)] ds:outline-none ds:focus-visible:outline-[length:var(--focus-ring-width)] ds:focus-visible:outline-solid ds:focus-visible:outline-[color:var(--ring)] ds:focus-visible:outline-offset-[length:var(--focus-ring-offset)] ds:disabled:cursor-not-allowed ds:disabled:opacity-50",
354
- {
355
- variants: {
356
- severity: {
357
- normal: "ds:border-[color:var(--input)] ds:text-[color:var(--foreground)]",
358
- moderate: "ds:border-[color:var(--warning)] ds:font-semibold ds:text-[color:var(--warning-foreground)]",
359
- severe: "ds:border-[color:var(--destructive)] ds:font-bold ds:text-[color:var(--destructive)]"
360
- }
361
- },
362
- defaultVariants: { severity: "normal" }
363
- }
364
- );
365
- function Mt(a, r, h) {
366
- return { ...a, [r]: { ...a[r], ...h } };
367
- }
368
- function kt(a, r, h, u) {
369
- const b = a[r] ?? {}, S = b.sites ?? {};
370
- return {
371
- ...a,
372
- [r]: {
373
- ...b,
374
- sites: { ...S, [h]: { ...S[h], ...u } }
375
- }
376
- };
377
- }
378
- function wt(a) {
379
- return a === "severe" ? "ds:font-bold ds:text-[color:var(--destructive)]" : a === "moderate" ? "ds:font-semibold ds:text-[color:var(--warning-foreground)]" : "";
380
- }
381
- const Pt = {
382
- db: "disto-buccal",
383
- b: "buccal",
384
- mb: "mesio-buccal",
385
- dl: "disto-lingual",
386
- l: "lingual",
387
- ml: "mesio-lingual"
388
- }, Tt = Xe(
389
- ({
390
- value: a,
391
- defaultValue: r,
392
- onChange: h,
393
- mode: u = "interactive",
394
- disabled: b = !1,
395
- dentition: S = "permanent",
396
- numbering: I = "fdi",
397
- showTeeth: L = !0,
398
- assetBaseUrl: E = "/toothscheme/teeth",
399
- showCurves: D = !0,
400
- showIndices: Te = !0,
401
- moderatePocketMm: Se = we,
402
- severePocketMm: Ee = ne,
403
- locale: De,
404
- "aria-label": Ie,
405
- id: Y,
406
- className: Ae,
407
- ...Re
408
- }, _e) => {
409
- const { t: i, i18n: Le } = tt(), ae = De ?? Le.language ?? "en", G = fe(null), Q = a !== void 0, [qe, Oe] = Ze(
410
- () => r ?? {}
411
- ), v = Q ? a : qe, j = u === "display", A = fe(v);
412
- A.current = v;
413
- const $ = R(
414
- (e) => {
415
- A.current = e, Q || Oe(e), h == null || h(e);
416
- },
417
- [Q, h]
418
- ), K = R(
419
- (e, t, n) => $(kt(A.current, e, t, n)),
420
- [$]
421
- ), F = R(
422
- (e, t) => $(Mt(A.current, e, t)),
423
- [$]
424
- ), oe = R(
425
- (e) => {
426
- const t = { ...A.current };
427
- delete t[e], $(t);
428
- },
429
- [$]
430
- ), ie = R(
431
- (e, t, n) => {
432
- var o, l;
433
- try {
434
- (l = (o = G.current) == null ? void 0 : o.querySelector(
435
- `[data-perio-input][data-fdi="${e}"][data-site="${t}"][data-field="${n}"]`
436
- )) == null || l.focus();
437
- } catch {
438
- }
439
- },
440
- []
441
- ), k = be(
442
- () => Ne(v),
443
- [v]
444
- ), J = be(
445
- () => ({
446
- getValue: () => A.current,
447
- getTooth: (e) => A.current[e],
448
- getIndices: () => Ne(A.current),
449
- missingTeeth: () => Object.entries(A.current).filter(([, e]) => e.missing).map(([e]) => e),
450
- setSite: K,
451
- setTooth: F,
452
- clearTooth: oe,
453
- focusSite: ie
454
- }),
455
- [K, F, oe, ie]
456
- );
457
- et(_e, () => J, [J]), rt(dt, J, Y);
458
- const le = Pe(S), je = Ie ?? i("periodontalChart.ariaLabel", "Periodontal chart"), z = R(
459
- (e) => {
460
- try {
461
- return new Intl.NumberFormat(ae, {
462
- maximumFractionDigits: 1
463
- }).format(e);
464
- } catch {
465
- return String(e);
466
- }
467
- },
468
- [ae]
469
- ), ce = R(
470
- (e) => i(`periodontalChart.site.${e}`, {
471
- defaultValue: Pt[e]
472
- }),
473
- [i]
474
- ), q = R(
475
- (e) => xe(e, I),
476
- [I]
477
- ), w = /* @__PURE__ */ s(
478
- "span",
479
- {
480
- "aria-hidden": "true",
481
- className: "ds:text-[color:var(--muted-foreground)]",
482
- children: i("periodontalChart.cell.empty", "–")
483
- }
484
- ), $e = R((e) => {
485
- var N;
486
- const t = e.target;
487
- if (!((N = t.matches) != null && N.call(t, "[data-perio-input]"))) return;
488
- const n = e.key;
489
- if (n !== "ArrowLeft" && n !== "ArrowRight" && n !== "ArrowUp" && n !== "ArrowDown")
490
- return;
491
- e.preventDefault();
492
- const o = G.current;
493
- if (!o) return;
494
- if (n === "ArrowUp" || n === "ArrowDown") {
495
- const f = t.getAttribute("data-fdi"), P = t.getAttribute("data-site"), x = t.getAttribute("data-field") === "pocketDepthMm" ? "recessionMm" : "pocketDepthMm", T = o.querySelector(
496
- `[data-perio-input][data-fdi="${f}"][data-site="${P}"][data-field="${x}"]`
497
- );
498
- T == null || T.focus(), T == null || T.select();
499
- return;
500
- }
501
- const l = Array.from(
502
- o.querySelectorAll("[data-perio-input]")
503
- ), p = l.indexOf(t);
504
- if (p === -1) return;
505
- const c = l[p + (n === "ArrowRight" ? 1 : -1)];
506
- c == null || c.focus(), c == null || c.select();
507
- }, []), M = "ds:px-[var(--spacing-2xs)] ds:py-[var(--spacing-2xs)] ds:text-center ds:border-b ds:border-[color:var(--border)]", O = "ds:px-[var(--spacing-xs)] ds:py-[var(--spacing-2xs)] ds:text-start ds:font-medium ds:border-b ds:border-[color:var(--border)] ds:whitespace-nowrap", Fe = (e, t, n) => {
508
- var c, N, f;
509
- const o = (f = (N = (c = v[e]) == null ? void 0 : c.sites) == null ? void 0 : N[t]) == null ? void 0 : f[n], l = n === "pocketDepthMm" ? ht(o, Se, Ee) : "normal", p = i(`periodontalChart.input.${n}`, {
510
- tooth: q(e),
511
- site: ce(t),
512
- defaultValue: n === "pocketDepthMm" ? "Tooth {{tooth}} {{site}} pocket depth, millimetres" : "Tooth {{tooth}} {{site}} recession, millimetres"
513
- }), g = l === "severe" ? i("periodontalChart.flag.severe", "severe pocket") : l === "moderate" ? i("periodontalChart.flag.moderate", "moderate pocket") : "";
514
- return j ? o == null || !Number.isFinite(o) ? /* @__PURE__ */ s("span", { className: "ds:inline-block ds:w-[3.5ch]", children: w }) : /* @__PURE__ */ m(
515
- "span",
516
- {
517
- className: `ds:inline-block ds:w-[3.5ch] ds:tabular-nums ds:[font-variant-numeric:var(--font-feature-tabular)] ${wt(
518
- l
519
- )}`,
520
- children: [
521
- /* @__PURE__ */ s("span", { children: z(o) }),
522
- g ? /* @__PURE__ */ m("span", { className: "ds:sr-only", children: [
523
- " ",
524
- g
525
- ] }) : null
526
- ]
527
- }
528
- ) : /* @__PURE__ */ s(
529
- "input",
530
- {
531
- type: "text",
532
- inputMode: "numeric",
533
- autoComplete: "off",
534
- disabled: b,
535
- "aria-label": g ? `${p}, ${g}` : p,
536
- "data-perio-input": "",
537
- "data-fdi": e,
538
- "data-site": t,
539
- "data-field": n,
540
- value: o == null ? "" : String(o),
541
- onFocus: (P) => P.currentTarget.select(),
542
- onChange: (P) => {
543
- const y = P.target.value.trim();
544
- let x;
545
- if (y === "" || y === "-")
546
- x = void 0;
547
- else {
548
- const T = Number(y);
549
- if (!Number.isFinite(T)) return;
550
- x = n === "pocketDepthMm" ? Math.max(0, T) : T;
551
- }
552
- K(
553
- e,
554
- t,
555
- n === "pocketDepthMm" ? { pocketDepthMm: x } : { recessionMm: x }
556
- );
557
- },
558
- className: Ct({ severity: l })
559
- }
560
- );
561
- }, Ve = (e, t, n) => {
562
- var g, c, N;
563
- const o = !!((N = (c = (g = v[e]) == null ? void 0 : g.sites) == null ? void 0 : c[t]) != null && N[n]), l = i(`periodontalChart.toggle.${n}`, {
564
- tooth: q(e),
565
- site: ce(t),
566
- defaultValue: n === "bleeding" ? "Tooth {{tooth}} {{site}} bleeding on probing" : "Tooth {{tooth}} {{site}} plaque"
567
- }), p = n === "bleeding" ? "ds:accent-[var(--destructive)]" : "ds:accent-[var(--warning)]";
568
- return j ? o ? /* @__PURE__ */ s(
569
- "span",
570
- {
571
- role: "img",
572
- "aria-label": l,
573
- className: `ds:inline-block ds:size-2 ds:rounded-[var(--radius-full)] ${n === "bleeding" ? "ds:bg-[var(--destructive)]" : "ds:bg-[var(--warning)]"}`
574
- }
575
- ) : /* @__PURE__ */ s("span", { className: "ds:inline-block ds:size-6", children: w }) : /* @__PURE__ */ m("label", { className: "ds:inline-flex ds:size-6 ds:cursor-pointer ds:items-center ds:justify-center", children: [
576
- /* @__PURE__ */ s("span", { className: "ds:sr-only", children: l }),
577
- /* @__PURE__ */ s(
578
- "input",
579
- {
580
- type: "checkbox",
581
- disabled: b,
582
- checked: o,
583
- onChange: (f) => K(
584
- e,
585
- t,
586
- n === "bleeding" ? { bleeding: f.target.checked } : { plaque: f.target.checked }
587
- ),
588
- className: `ds:size-4 ${p} ds:focus-visible:outline-[length:var(--focus-ring-width)] ds:focus-visible:outline-solid ds:focus-visible:outline-[color:var(--ring)] ds:focus-visible:outline-offset-[length:var(--focus-ring-offset)] ds:disabled:cursor-not-allowed ds:disabled:opacity-50`
589
- }
590
- )
591
- ] });
592
- }, ze = (e, t) => {
593
- var p;
594
- const n = v[e], o = ft(e, t);
595
- if (n != null && n.missing || o === 0) return w;
596
- const l = ((p = n == null ? void 0 : n.furcation) == null ? void 0 : p[t]) ?? [];
597
- return /* @__PURE__ */ s("span", { className: "ds:inline-flex ds:items-center ds:justify-center ds:gap-[var(--spacing-2xs)]", children: Array.from({ length: o }, (g, c) => {
598
- const N = !!l[c], f = i("periodontalChart.toggle.furcation", {
599
- tooth: q(e),
600
- side: i(`periodontalChart.side.${t}`, {
601
- defaultValue: t === "buccal" ? "buccal" : "lingual"
602
- }),
603
- n: c + 1,
604
- defaultValue: "Tooth {{tooth}} {{side}} furcation {{n}}"
605
- });
606
- return j ? N ? /* @__PURE__ */ s(
607
- "span",
608
- {
609
- role: "img",
610
- "aria-label": f,
611
- className: "ds:inline-block ds:size-2 ds:rounded-[var(--radius-full)] ds:bg-[var(--primary)]"
612
- },
613
- c
614
- ) : /* @__PURE__ */ s(
615
- "span",
616
- {
617
- "aria-hidden": "true",
618
- className: "ds:inline-block ds:size-2 ds:rounded-[var(--radius-full)] ds:border ds:border-[color:var(--border)]"
619
- },
620
- c
621
- ) : /* @__PURE__ */ m(
622
- "label",
623
- {
624
- className: "ds:inline-flex ds:size-6 ds:cursor-pointer ds:items-center ds:justify-center",
625
- children: [
626
- /* @__PURE__ */ s("span", { className: "ds:sr-only", children: f }),
627
- /* @__PURE__ */ s(
628
- "input",
629
- {
630
- type: "checkbox",
631
- disabled: b,
632
- checked: N,
633
- onChange: (P) => {
634
- var x;
635
- const y = [...((x = n == null ? void 0 : n.furcation) == null ? void 0 : x[t]) ?? []];
636
- for (; y.length < o; ) y.push(!1);
637
- y[c] = P.target.checked, F(e, {
638
- furcation: { ...n == null ? void 0 : n.furcation, [t]: y }
639
- });
640
- },
641
- className: "ds:size-4 ds:accent-[var(--primary)] ds:focus-visible:outline-[length:var(--focus-ring-width)] ds:focus-visible:outline-solid ds:focus-visible:outline-[color:var(--ring)] ds:focus-visible:outline-offset-[length:var(--focus-ring-offset)] ds:disabled:cursor-not-allowed ds:disabled:opacity-50"
642
- }
643
- )
644
- ]
645
- },
646
- c
647
- );
648
- }) });
649
- }, B = (e, t, n, o, l) => /* @__PURE__ */ m("tr", { children: [
650
- /* @__PURE__ */ s("th", { scope: "row", className: O, children: i(t, n) }),
651
- e.map((p) => {
652
- var g;
653
- return /* @__PURE__ */ s("td", { className: M, children: (g = v[p]) != null && g.missing ? w : /* @__PURE__ */ s("span", { className: "ds:flex ds:items-center ds:justify-center ds:gap-[var(--spacing-2xs)]", children: ye(o).map((c) => /* @__PURE__ */ s("span", { children: Fe(p, c, l) }, c)) }) }, p);
654
- })
655
- ] }), U = (e, t, n, o, l) => /* @__PURE__ */ m("tr", { children: [
656
- /* @__PURE__ */ s("th", { scope: "row", className: O, children: i(t, n) }),
657
- e.map((p) => {
658
- var g;
659
- return /* @__PURE__ */ s("td", { className: M, children: (g = v[p]) != null && g.missing ? w : /* @__PURE__ */ s("span", { className: "ds:flex ds:items-center ds:justify-center ds:gap-[var(--spacing-2xs)]", children: ye(o).map((c) => /* @__PURE__ */ s("span", { children: Ve(p, c, l) }, c)) }) }, p);
660
- })
661
- ] }), de = (e, t) => /* @__PURE__ */ m("tr", { children: [
662
- /* @__PURE__ */ s("th", { scope: "row", className: O, children: i("periodontalChart.row.furcation", "Furcation") }),
663
- e.map((n) => /* @__PURE__ */ s("td", { className: M, children: ze(n, t) }, n))
664
- ] }), ue = (e, t, n, o) => /* @__PURE__ */ m("tr", { children: [
665
- /* @__PURE__ */ s("th", { scope: "row", className: O, children: i(t, n) }),
666
- e.map((l) => {
667
- var c, N;
668
- if (o === "implant" && ((c = v[l]) != null && c.missing))
669
- return /* @__PURE__ */ s("td", { className: M, children: w }, l);
670
- const p = !!((N = v[l]) != null && N[o]), g = i(`periodontalChart.flag.${o}Label`, {
671
- tooth: q(l),
672
- defaultValue: o === "missing" ? "Tooth {{tooth}} missing" : "Tooth {{tooth}} implant"
673
- });
674
- return /* @__PURE__ */ s("td", { className: M, children: j ? p ? /* @__PURE__ */ s(
675
- "span",
676
- {
677
- role: "img",
678
- "aria-label": g,
679
- className: "type-meta ds:font-semibold",
680
- children: o === "missing" ? i("periodontalChart.flag.missingShort", "×") : i("periodontalChart.flag.implantShort", "I")
681
- }
682
- ) : w : /* @__PURE__ */ m("label", { className: "ds:inline-flex ds:size-6 ds:cursor-pointer ds:items-center ds:justify-center", children: [
683
- /* @__PURE__ */ s("span", { className: "ds:sr-only", children: g }),
684
- /* @__PURE__ */ s(
685
- "input",
686
- {
687
- type: "checkbox",
688
- disabled: b,
689
- checked: p,
690
- onChange: (f) => F(
691
- l,
692
- o === "missing" ? { missing: f.target.checked } : { implant: f.target.checked }
693
- ),
694
- className: "ds:size-4 ds:accent-[var(--primary)] ds:focus-visible:outline-[length:var(--focus-ring-width)] ds:focus-visible:outline-solid ds:focus-visible:outline-[color:var(--ring)] ds:focus-visible:outline-offset-[length:var(--focus-ring-offset)] ds:disabled:cursor-not-allowed ds:disabled:opacity-50"
695
- }
696
- )
697
- ] }) }, l);
698
- })
699
- ] }), He = (e) => /* @__PURE__ */ m("tr", { children: [
700
- /* @__PURE__ */ s("th", { scope: "row", className: O, children: i("periodontalChart.row.mobility", "Mobility") }),
701
- e.map((t) => {
702
- var l, p;
703
- if ((l = v[t]) != null && l.missing)
704
- return /* @__PURE__ */ s("td", { className: M, children: w }, t);
705
- const n = (p = v[t]) == null ? void 0 : p.mobility, o = i("periodontalChart.mobility.label", {
706
- tooth: q(t),
707
- defaultValue: "Tooth {{tooth}} mobility grade"
708
- });
709
- return j ? /* @__PURE__ */ s("td", { className: M, children: n == null ? w : /* @__PURE__ */ s("span", { role: "img", "aria-label": o, className: "type-meta", children: n }) }, t) : /* @__PURE__ */ s("td", { className: M, children: /* @__PURE__ */ m(
710
- "select",
711
- {
712
- disabled: b,
713
- "aria-label": o,
714
- value: n == null ? "" : String(n),
715
- onChange: (g) => F(t, {
716
- mobility: g.target.value === "" ? void 0 : Number(g.target.value)
717
- }),
718
- className: "ds:h-6 ds:rounded-[var(--radius-sm)] ds:border ds:border-[color:var(--input)] ds:bg-[var(--background)] ds:text-[color:var(--foreground)] ds:text-center ds:outline-none ds:focus-visible:outline-[length:var(--focus-ring-width)] ds:focus-visible:outline-solid ds:focus-visible:outline-[color:var(--ring)] ds:focus-visible:outline-offset-[length:var(--focus-ring-offset)] ds:disabled:cursor-not-allowed ds:disabled:opacity-50",
719
- children: [
720
- /* @__PURE__ */ s("option", { value: "", children: i("periodontalChart.mobility.none", "–") }),
721
- /* @__PURE__ */ s("option", { value: "0", children: "0" }),
722
- /* @__PURE__ */ s("option", { value: "1", children: "1" }),
723
- /* @__PURE__ */ s("option", { value: "2", children: "2" }),
724
- /* @__PURE__ */ s("option", { value: "3", children: "3" })
725
- ]
726
- }
727
- ) }, t);
728
- })
729
- ] }), Ke = (e) => /* @__PURE__ */ m("tr", { children: [
730
- /* @__PURE__ */ s("th", { scope: "row", className: O, children: i("periodontalChart.row.note", "Note") }),
731
- e.map((t) => {
732
- var l, p;
733
- if ((l = v[t]) != null && l.missing)
734
- return /* @__PURE__ */ s("td", { className: M, children: w }, t);
735
- const n = ((p = v[t]) == null ? void 0 : p.note) ?? "", o = i("periodontalChart.note.label", {
736
- tooth: q(t),
737
- defaultValue: "Tooth {{tooth}} note"
738
- });
739
- return j ? /* @__PURE__ */ s("td", { className: `${M} ds:text-start`, children: n ? /* @__PURE__ */ s("span", { className: "type-meta", children: n }) : w }, t) : /* @__PURE__ */ s("td", { className: M, children: /* @__PURE__ */ s(
740
- "input",
741
- {
742
- type: "text",
743
- disabled: b,
744
- "aria-label": o,
745
- value: n,
746
- onChange: (g) => F(t, { note: g.target.value }),
747
- className: "ds:h-6 ds:w-[6ch] ds:rounded-[var(--radius-sm)] ds:border ds:border-[color:var(--input)] ds:bg-[var(--background)] ds:text-[color:var(--foreground)] ds:px-[var(--spacing-2xs)] ds:outline-none ds:focus-visible:outline-[length:var(--focus-ring-width)] ds:focus-visible:outline-solid ds:focus-visible:outline-[color:var(--ring)] ds:focus-visible:outline-offset-[length:var(--focus-ring-offset)] ds:disabled:cursor-not-allowed ds:disabled:opacity-50"
748
- }
749
- ) }, t);
750
- })
751
- ] }), Be = (e) => /* @__PURE__ */ m("tr", { children: [
752
- /* @__PURE__ */ s("th", { scope: "row", className: O, children: i("periodontalChart.row.tooth", "Tooth") }),
753
- e.map((t) => {
754
- const n = v[t], o = at[t];
755
- if (n != null && n.missing || !o)
756
- return /* @__PURE__ */ s("td", { className: M, children: w }, t);
757
- const l = n != null && n.implant ? "implant" : "default";
758
- return /* @__PURE__ */ s("td", { className: M, children: /* @__PURE__ */ s(
759
- "img",
760
- {
761
- src: ot(o, E, l, "side"),
762
- alt: "",
763
- "aria-hidden": "true",
764
- loading: "lazy",
765
- className: "ds:mx-auto ds:h-12 ds:w-auto ds:max-w-full ds:object-contain"
766
- }
767
- ) }, t);
768
- })
769
- ] }), Ue = (e) => {
770
- var me, he, ge;
771
- const c = (d) => 38 + Math.min(Math.max(0, d), 13) * 6, N = (d) => 38 - Math.min(Math.max(0, d), 5) * 6, f = [], P = [];
772
- let y = [], x = [];
773
- const T = () => {
774
- y.length && f.push(y), x.length && P.push(x), y = [], x = [];
775
- };
776
- let X = 12;
777
- for (const d of e) {
778
- const C = (me = v[d]) == null ? void 0 : me.missing;
779
- for (const Je of se) {
780
- const V = C || (ge = (he = v[d]) == null ? void 0 : he.sites) == null ? void 0 : ge[Je], te = V == null ? void 0 : V.pocketDepthMm, re = V == null ? void 0 : V.recessionMm;
781
- te != null && Number.isFinite(te) ? y.push({ x: X, y: c(te) }) : y.length && (f.push(y), y = []), re != null && Number.isFinite(re) ? x.push({ x: X, y: N(re) }) : x.length && (P.push(x), x = []), X += 24;
782
- }
783
- }
784
- T();
785
- const Z = e.length * se.length * 24, ee = (d) => d.map((C) => `${C.x},${C.y}`).join(" "), Ge = f.flat(), Qe = P.flat();
786
- return /* @__PURE__ */ m(
787
- "svg",
788
- {
789
- viewBox: `0 0 ${Z} 124`,
790
- className: "ds:h-[132px] ds:w-full",
791
- preserveAspectRatio: "none",
792
- "aria-hidden": "true",
793
- focusable: "false",
794
- children: [
795
- [3, 6, 9, 12].map((d) => /* @__PURE__ */ s(
796
- "line",
797
- {
798
- x1: 0,
799
- x2: Z,
800
- y1: c(d),
801
- y2: c(d),
802
- stroke: "var(--border)",
803
- strokeWidth: 1,
804
- strokeDasharray: "2 4"
805
- },
806
- d
807
- )),
808
- /* @__PURE__ */ s(
809
- "line",
810
- {
811
- x1: 0,
812
- x2: Z,
813
- y1: 38,
814
- y2: 38,
815
- stroke: "var(--border)",
816
- strokeWidth: 1.5
817
- }
818
- ),
819
- f.map(
820
- (d, C) => d.length >= 2 ? /* @__PURE__ */ s(
821
- "polygon",
822
- {
823
- points: `${d[0].x},38 ${ee(d)} ${d[d.length - 1].x},38`,
824
- fill: "var(--success)",
825
- fillOpacity: 0.14
826
- },
827
- `fill-${C}`
828
- ) : null
829
- ),
830
- f.map(
831
- (d, C) => d.length >= 2 ? /* @__PURE__ */ s(
832
- "polyline",
833
- {
834
- points: ee(d),
835
- fill: "none",
836
- stroke: "var(--success)",
837
- strokeWidth: 2.5,
838
- strokeLinejoin: "round",
839
- strokeLinecap: "round"
840
- },
841
- `depth-${C}`
842
- ) : null
843
- ),
844
- P.map(
845
- (d, C) => d.length >= 2 ? /* @__PURE__ */ s(
846
- "polyline",
847
- {
848
- points: ee(d),
849
- fill: "none",
850
- stroke: "var(--accent)",
851
- strokeWidth: 2.5,
852
- strokeLinejoin: "round",
853
- strokeLinecap: "round"
854
- },
855
- `margin-${C}`
856
- ) : null
857
- ),
858
- Ge.map((d, C) => /* @__PURE__ */ s(
859
- "circle",
860
- {
861
- cx: d.x,
862
- cy: d.y,
863
- r: 2,
864
- fill: "var(--success)"
865
- },
866
- `dp-${C}`
867
- )),
868
- Qe.map((d, C) => /* @__PURE__ */ s(
869
- "circle",
870
- {
871
- cx: d.x,
872
- cy: d.y,
873
- r: 2,
874
- fill: "var(--accent)"
875
- },
876
- `mp-${C}`
877
- ))
878
- ]
879
- }
880
- );
881
- }, pe = (e, t, n) => /* @__PURE__ */ s("div", { className: "ds:flex ds:flex-col ds:gap-[var(--spacing-xs)]", children: /* @__PURE__ */ m(
882
- "div",
883
- {
884
- tabIndex: 0,
885
- role: "group",
886
- dir: "ltr",
887
- "aria-label": i(t, n),
888
- className: "ds:overflow-x-auto ds:rounded-[var(--radius-sm)] ds:outline-none ds:focus-visible:outline-[length:var(--focus-ring-width)] ds:focus-visible:outline-solid ds:focus-visible:outline-[color:var(--ring)] ds:focus-visible:outline-offset-[length:var(--focus-ring-offset)]",
889
- children: [
890
- /* @__PURE__ */ m("table", { className: "type-body-sm ds:w-full ds:border-collapse", children: [
891
- /* @__PURE__ */ s("caption", { className: "type-label ds:text-start ds:mb-[var(--spacing-2xs)] ds:text-[color:var(--muted-foreground)]", children: i(t, n) }),
892
- /* @__PURE__ */ s("thead", { children: /* @__PURE__ */ m("tr", { children: [
893
- /* @__PURE__ */ s(
894
- "th",
895
- {
896
- scope: "col",
897
- className: "ds:px-[var(--spacing-xs)] ds:py-[var(--spacing-2xs)] ds:text-start ds:border-b ds:border-[color:var(--border)]",
898
- children: i("periodontalChart.column.measure", "Measurement")
899
- }
900
- ),
901
- e.map((o) => /* @__PURE__ */ m(
902
- "th",
903
- {
904
- scope: "col",
905
- "data-fdi": o,
906
- className: "ds:px-[var(--spacing-2xs)] ds:py-[var(--spacing-2xs)] ds:text-center ds:border-b ds:border-[color:var(--border)] ds:tabular-nums ds:[font-variant-numeric:var(--font-feature-tabular)]",
907
- children: [
908
- /* @__PURE__ */ s("span", { className: "ds:sr-only", children: i("periodontalChart.toothHeader", {
909
- tooth: q(o),
910
- defaultValue: "Tooth {{tooth}}"
911
- }) }),
912
- /* @__PURE__ */ s("span", { "aria-hidden": "true", children: xe(o, I) })
913
- ]
914
- },
915
- o
916
- ))
917
- ] }) }),
918
- /* @__PURE__ */ m("tbody", { children: [
919
- ue(
920
- e,
921
- "periodontalChart.row.missing",
922
- "Missing",
923
- "missing"
924
- ),
925
- ue(
926
- e,
927
- "periodontalChart.row.implant",
928
- "Implant",
929
- "implant"
930
- ),
931
- He(e),
932
- B(
933
- e,
934
- "periodontalChart.row.pocketDepthBuccal",
935
- "Pocket depth — buccal",
936
- "buccal",
937
- "pocketDepthMm"
938
- ),
939
- B(
940
- e,
941
- "periodontalChart.row.recessionBuccal",
942
- "Recession — buccal",
943
- "buccal",
944
- "recessionMm"
945
- ),
946
- U(
947
- e,
948
- "periodontalChart.row.bleedingBuccal",
949
- "Bleeding — buccal",
950
- "buccal",
951
- "bleeding"
952
- ),
953
- U(
954
- e,
955
- "periodontalChart.row.plaqueBuccal",
956
- "Plaque — buccal",
957
- "buccal",
958
- "plaque"
959
- ),
960
- de(e, "buccal"),
961
- L ? Be(e) : null,
962
- B(
963
- e,
964
- "periodontalChart.row.pocketDepthLingual",
965
- "Pocket depth — lingual",
966
- "lingual",
967
- "pocketDepthMm"
968
- ),
969
- B(
970
- e,
971
- "periodontalChart.row.recessionLingual",
972
- "Recession — lingual",
973
- "lingual",
974
- "recessionMm"
975
- ),
976
- U(
977
- e,
978
- "periodontalChart.row.bleedingLingual",
979
- "Bleeding — lingual",
980
- "lingual",
981
- "bleeding"
982
- ),
983
- U(
984
- e,
985
- "periodontalChart.row.plaqueLingual",
986
- "Plaque — lingual",
987
- "lingual",
988
- "plaque"
989
- ),
990
- de(e, "lingual"),
991
- Ke(e)
992
- ] })
993
- ] }),
994
- D ? /* @__PURE__ */ s(
995
- "figure",
996
- {
997
- className: "ds:m-0 ds:mt-[var(--spacing-2xs)]",
998
- "aria-label": i("periodontalChart.curve.label", {
999
- arch: i(t, n),
1000
- defaultValue: "{{arch}} probing depth and recession profile"
1001
- }),
1002
- children: Ue(e)
1003
- }
1004
- ) : null
1005
- ]
1006
- }
1007
- ) }), We = () => {
1008
- const e = [
1009
- {
1010
- key: "meanPd",
1011
- label: i("periodontalChart.index.meanPocketDepth", "Mean PD"),
1012
- value: k.meanPocketDepthMm == null ? "–" : i("periodontalChart.unit.mm", {
1013
- value: z(k.meanPocketDepthMm),
1014
- defaultValue: "{{value}} mm"
1015
- }),
1016
- elevated: !1
1017
- },
1018
- {
1019
- key: "meanCal",
1020
- label: i("periodontalChart.index.meanAttachment", "Mean CAL"),
1021
- value: k.meanAttachmentLevelMm == null ? "–" : i("periodontalChart.unit.mm", {
1022
- value: z(k.meanAttachmentLevelMm),
1023
- defaultValue: "{{value}} mm"
1024
- }),
1025
- elevated: !1
1026
- },
1027
- {
1028
- key: "plaque",
1029
- label: i("periodontalChart.index.plaque", "Plaque"),
1030
- value: k.plaquePercent == null ? "–" : i("periodontalChart.unit.percent", {
1031
- value: z(k.plaquePercent),
1032
- defaultValue: "{{value}}%"
1033
- }),
1034
- elevated: k.plaquePercent != null && k.plaquePercent > pt
1035
- },
1036
- {
1037
- key: "bleeding",
1038
- label: i("periodontalChart.index.bleeding", "BoP"),
1039
- value: k.bleedingPercent == null ? "–" : i("periodontalChart.unit.percent", {
1040
- value: z(k.bleedingPercent),
1041
- defaultValue: "{{value}}%"
1042
- }),
1043
- elevated: k.bleedingPercent != null && k.bleedingPercent > mt
1044
- }
1045
- ];
1046
- return /* @__PURE__ */ s(
1047
- "dl",
1048
- {
1049
- className: "type-body-sm ds:flex ds:flex-wrap ds:gap-[var(--spacing-lg)] ds:m-0",
1050
- "aria-label": i("periodontalChart.index.label", "Summary indices"),
1051
- children: e.map((t) => /* @__PURE__ */ m(
1052
- "div",
1053
- {
1054
- className: "ds:flex ds:flex-col ds:gap-[var(--spacing-2xs)]",
1055
- children: [
1056
- /* @__PURE__ */ s("dt", { className: "type-meta ds:text-[color:var(--muted-foreground)]", children: t.label }),
1057
- /* @__PURE__ */ m(
1058
- "dd",
1059
- {
1060
- className: `ds:m-0 ds:tabular-nums ds:[font-variant-numeric:var(--font-feature-tabular)] ${t.elevated ? "ds:font-bold ds:text-[color:var(--destructive)]" : "ds:text-[color:var(--foreground)]"}`,
1061
- children: [
1062
- /* @__PURE__ */ s("span", { children: t.value }),
1063
- t.elevated ? /* @__PURE__ */ m("span", { className: "ds:sr-only", children: [
1064
- " ",
1065
- i("periodontalChart.index.elevated", "elevated")
1066
- ] }) : null
1067
- ]
1068
- }
1069
- )
1070
- ]
1071
- },
1072
- t.key
1073
- ))
1074
- }
1075
- );
1076
- }, Ye = /* @__PURE__ */ m(
1077
- "div",
1078
- {
1079
- role: "group",
1080
- "aria-label": i("periodontalChart.legend.label", "Chart legend"),
1081
- className: "type-meta ds:flex ds:flex-wrap ds:items-center ds:gap-[var(--spacing-md)] ds:text-[color:var(--muted-foreground)]",
1082
- children: [
1083
- /* @__PURE__ */ m("span", { className: "ds:inline-flex ds:items-center ds:gap-[var(--spacing-2xs)]", children: [
1084
- /* @__PURE__ */ s(
1085
- "span",
1086
- {
1087
- "aria-hidden": "true",
1088
- className: "ds:inline-block ds:h-[2px] ds:w-4 ds:bg-[var(--success)]"
1089
- }
1090
- ),
1091
- i("periodontalChart.legend.depth", "Pocket depth")
1092
- ] }),
1093
- /* @__PURE__ */ m("span", { className: "ds:inline-flex ds:items-center ds:gap-[var(--spacing-2xs)]", children: [
1094
- /* @__PURE__ */ s(
1095
- "span",
1096
- {
1097
- "aria-hidden": "true",
1098
- className: "ds:inline-block ds:h-[2px] ds:w-4 ds:bg-[var(--accent)]"
1099
- }
1100
- ),
1101
- i("periodontalChart.legend.recession", "Recession")
1102
- ] }),
1103
- /* @__PURE__ */ m("span", { className: "ds:inline-flex ds:items-center ds:gap-[var(--spacing-2xs)]", children: [
1104
- /* @__PURE__ */ s(
1105
- "span",
1106
- {
1107
- "aria-hidden": "true",
1108
- className: "ds:inline-block ds:size-2 ds:rounded-[var(--radius-full)] ds:bg-[var(--destructive)]"
1109
- }
1110
- ),
1111
- i("periodontalChart.legend.bleeding", "Bleeding on probing")
1112
- ] }),
1113
- /* @__PURE__ */ m("span", { className: "ds:inline-flex ds:items-center ds:gap-[var(--spacing-2xs)]", children: [
1114
- /* @__PURE__ */ s(
1115
- "span",
1116
- {
1117
- "aria-hidden": "true",
1118
- className: "ds:inline-block ds:size-2 ds:rounded-[var(--radius-full)] ds:bg-[var(--warning)]"
1119
- }
1120
- ),
1121
- i("periodontalChart.legend.plaque", "Plaque")
1122
- ] })
1123
- ]
1124
- }
1125
- );
1126
- return (
1127
- // eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions -- roving-tabindex arrow-key nav across the chart group; each input is individually focusable and labelled
1128
- /* @__PURE__ */ m(
1129
- "div",
1130
- {
1131
- ref: G,
1132
- role: "group",
1133
- "aria-label": je,
1134
- "data-component": "periodontal-chart",
1135
- "data-component-id": Y,
1136
- "data-mode": u,
1137
- id: Y,
1138
- ...Re,
1139
- onKeyDown: $e,
1140
- className: Nt({ disabled: b, className: Ae }),
1141
- children: [
1142
- Te ? We() : null,
1143
- pe(le.upper, "periodontalChart.arch.upper", "Upper arch"),
1144
- pe(le.lower, "periodontalChart.arch.lower", "Lower arch"),
1145
- Ye
1146
- ]
1147
- }
1148
- )
1149
- );
1150
- }
1151
- );
1152
- Tt.displayName = "PeriodontalChart";
1153
- export {
1154
- mt as B,
1155
- we as M,
1156
- se as P,
1157
- ne as S,
1158
- gt as a,
1159
- ut as b,
1160
- pt as c,
1161
- Tt as d,
1162
- Ne as e,
1163
- Lt as f,
1164
- ft as g,
1165
- dt as h,
1166
- xe as i,
1167
- ht as j,
1168
- qt as k,
1169
- Pe as p,
1170
- ye as s,
1171
- Ot as t
1172
- };
1173
- //# sourceMappingURL=periodontal-chart-D8hOFmde.js.map