formanitor 0.0.41 → 0.0.42
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/index.cjs +115 -1509
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -33
- package/dist/index.d.ts +2 -33
- package/dist/index.mjs +116 -1507
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -30,326 +30,6 @@ function fieldMetaRequestsMarMedicationOrdersButton(meta) {
|
|
|
30
30
|
return meta[MAR_MEDICATION_ORDERS_META_KEY] === true;
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
-
// src/core/urologyClinicalPathwayMetadata.ts
|
|
34
|
-
function isUrologyTemplate(template) {
|
|
35
|
-
if (!template || typeof template !== "object") return false;
|
|
36
|
-
const t = template;
|
|
37
|
-
return t.meta?.specialization === "urology" || t.specialization === "urology" || t.id === "uro_prescription";
|
|
38
|
-
}
|
|
39
|
-
function shouldFoldUrologyClinicalPathway(template, payload) {
|
|
40
|
-
if (isUrologyTemplate(template)) return true;
|
|
41
|
-
return Object.keys(payload).some(
|
|
42
|
-
(k) => k.startsWith("uro_") || k === "chief_complaints" || k === "chief_complaints_chips"
|
|
43
|
-
);
|
|
44
|
-
}
|
|
45
|
-
var UROLOGY_EXTRA_METADATA_KEYS = ["symptoms", "notes", "vitals"];
|
|
46
|
-
function isUroPlainObject(v) {
|
|
47
|
-
return v !== null && typeof v === "object" && !Array.isArray(v);
|
|
48
|
-
}
|
|
49
|
-
function coerceUrologyBool(value) {
|
|
50
|
-
if (value === true || value === false) return value;
|
|
51
|
-
if (value === "true") return true;
|
|
52
|
-
if (value === "false") return false;
|
|
53
|
-
if (Array.isArray(value)) {
|
|
54
|
-
if (value.includes("yes") || value.includes(true)) return true;
|
|
55
|
-
if (value.length === 0) return false;
|
|
56
|
-
}
|
|
57
|
-
return value;
|
|
58
|
-
}
|
|
59
|
-
function urologyIpssItem(v) {
|
|
60
|
-
const n = Number(v);
|
|
61
|
-
if (!Number.isFinite(n)) return 0;
|
|
62
|
-
return Math.min(5, Math.max(0, Math.round(n)));
|
|
63
|
-
}
|
|
64
|
-
function urologyIpssSevenTotalFromParts(ipss) {
|
|
65
|
-
return ipss.incomplete + ipss.frequency + ipss.intermittency + ipss.urgency + ipss.weakStream + ipss.straining + ipss.nocturia;
|
|
66
|
-
}
|
|
67
|
-
function buildUrologySmartHistoryFromLegacyFlat(flat) {
|
|
68
|
-
return {
|
|
69
|
-
socrates_pain_flank_suprapubic: {
|
|
70
|
-
site: flat.uro_sh_socrates_site,
|
|
71
|
-
onset: flat.uro_sh_socrates_onset,
|
|
72
|
-
character: flat.uro_sh_socrates_character,
|
|
73
|
-
radiation: flat.uro_sh_socrates_radiation,
|
|
74
|
-
associated: flat.uro_sh_socrates_associated,
|
|
75
|
-
timing: flat.uro_sh_socrates_timing,
|
|
76
|
-
exacerbating: flat.uro_sh_socrates_exacerbating,
|
|
77
|
-
severity_0_to_10: flat.uro_sh_socrates_severity
|
|
78
|
-
},
|
|
79
|
-
ipss_international_symptom_score: {
|
|
80
|
-
incomplete_emptying: flat.uro_sh_ipss_incomplete,
|
|
81
|
-
frequency_lt_2h: flat.uro_sh_ipss_frequency,
|
|
82
|
-
intermittency: flat.uro_sh_ipss_intermittency,
|
|
83
|
-
urgency: flat.uro_sh_ipss_urgency,
|
|
84
|
-
weak_stream: flat.uro_sh_ipss_weak_stream,
|
|
85
|
-
straining: flat.uro_sh_ipss_straining,
|
|
86
|
-
nocturia: flat.uro_sh_ipss_nocturia,
|
|
87
|
-
qol_0_to_6: flat.uro_sh_ipss_qol,
|
|
88
|
-
seven_item_total_computed_max_35: flat.uro_sh_ipss_total_display
|
|
89
|
-
},
|
|
90
|
-
haematuria_profile: {
|
|
91
|
-
present: flat.uro_sh_haem_present,
|
|
92
|
-
timing: flat.uro_sh_haem_timing,
|
|
93
|
-
painful: flat.uro_sh_haem_painful,
|
|
94
|
-
clots: flat.uro_sh_haem_clots
|
|
95
|
-
},
|
|
96
|
-
sexual_and_reproductive: {
|
|
97
|
-
erectile_function: flat.uro_sh_sex_erectile,
|
|
98
|
-
libido: flat.uro_sh_sex_libido,
|
|
99
|
-
ejaculation: flat.uro_sh_sex_ejaculation,
|
|
100
|
-
infertility_months: flat.uro_sh_sex_infertility_months
|
|
101
|
-
},
|
|
102
|
-
context_prior_stones_surgery_comorbidity: flat.uro_smart_notes_free ?? ""
|
|
103
|
-
};
|
|
104
|
-
}
|
|
105
|
-
function buildUrologySmartHistoryFromComposite(raw, flat) {
|
|
106
|
-
const soc = isUroPlainObject(raw.socrates) ? raw.socrates : {};
|
|
107
|
-
const ipssIn = isUroPlainObject(raw.ipss) ? raw.ipss : {};
|
|
108
|
-
const haem = isUroPlainObject(raw.haematuria) ? raw.haematuria : {};
|
|
109
|
-
const sex = isUroPlainObject(raw.sexual) ? raw.sexual : {};
|
|
110
|
-
const str2 = (x) => typeof x === "string" ? x : "";
|
|
111
|
-
const sev = Number(soc.severity);
|
|
112
|
-
const severity0to10 = Number.isFinite(sev) ? Math.min(10, Math.max(0, Math.round(sev))) : 0;
|
|
113
|
-
const ipss = {
|
|
114
|
-
incomplete: urologyIpssItem(ipssIn.incomplete),
|
|
115
|
-
frequency: urologyIpssItem(ipssIn.frequency),
|
|
116
|
-
intermittency: urologyIpssItem(ipssIn.intermittency),
|
|
117
|
-
urgency: urologyIpssItem(ipssIn.urgency),
|
|
118
|
-
weakStream: urologyIpssItem(
|
|
119
|
-
ipssIn.weakStream ?? ipssIn.weak_stream
|
|
120
|
-
),
|
|
121
|
-
straining: urologyIpssItem(ipssIn.straining),
|
|
122
|
-
nocturia: urologyIpssItem(ipssIn.nocturia)
|
|
123
|
-
};
|
|
124
|
-
const sevenTotal = urologyIpssSevenTotalFromParts(ipss);
|
|
125
|
-
const qolRaw = Number(raw.ipssQoL);
|
|
126
|
-
const qol = Number.isFinite(qolRaw) ? Math.min(6, Math.max(0, Math.round(qolRaw))) : 0;
|
|
127
|
-
const timingRaw = str2(haem.timing);
|
|
128
|
-
const pastNotes = str2(raw.pastNotes);
|
|
129
|
-
const legacyNotes = flat.uro_smart_notes_free;
|
|
130
|
-
const contextPrior = pastNotes !== "" ? pastNotes : typeof legacyNotes === "string" ? legacyNotes : legacyNotes ?? "";
|
|
131
|
-
const infertilityRaw = Number(sex.infertilityMonths);
|
|
132
|
-
const infertilityMonths = Number.isFinite(infertilityRaw) ? Math.max(0, Math.round(infertilityRaw)) : 0;
|
|
133
|
-
return {
|
|
134
|
-
socrates_pain_flank_suprapubic: {
|
|
135
|
-
site: str2(soc.site),
|
|
136
|
-
onset: str2(soc.onset),
|
|
137
|
-
character: str2(soc.character),
|
|
138
|
-
radiation: str2(soc.radiation),
|
|
139
|
-
associated: str2(soc.associated),
|
|
140
|
-
timing: str2(soc.timing),
|
|
141
|
-
exacerbating: str2(soc.exacerbating),
|
|
142
|
-
severity_0_to_10: severity0to10
|
|
143
|
-
},
|
|
144
|
-
ipss_international_symptom_score: {
|
|
145
|
-
incomplete_emptying: ipss.incomplete,
|
|
146
|
-
frequency_lt_2h: ipss.frequency,
|
|
147
|
-
intermittency: ipss.intermittency,
|
|
148
|
-
urgency: ipss.urgency,
|
|
149
|
-
weak_stream: ipss.weakStream,
|
|
150
|
-
straining: ipss.straining,
|
|
151
|
-
nocturia: ipss.nocturia,
|
|
152
|
-
qol_0_to_6: qol,
|
|
153
|
-
seven_item_total_computed_max_35: sevenTotal
|
|
154
|
-
},
|
|
155
|
-
haematuria_profile: {
|
|
156
|
-
present: haem.present === true,
|
|
157
|
-
timing: timingRaw,
|
|
158
|
-
painful: haem.painful === true,
|
|
159
|
-
clots: haem.clots === true
|
|
160
|
-
},
|
|
161
|
-
sexual_and_reproductive: {
|
|
162
|
-
erectile_function: str2(sex.erectile),
|
|
163
|
-
libido: str2(sex.libido),
|
|
164
|
-
ejaculation: str2(sex.ejaculation),
|
|
165
|
-
infertility_months: infertilityMonths
|
|
166
|
-
},
|
|
167
|
-
context_prior_stones_surgery_comorbidity: contextPrior
|
|
168
|
-
};
|
|
169
|
-
}
|
|
170
|
-
function buildUrologyExaminationFromLegacyFlat(flat) {
|
|
171
|
-
return {
|
|
172
|
-
general: {
|
|
173
|
-
pallor: flat.uro_ex_general_pallor,
|
|
174
|
-
oedema: flat.uro_ex_general_oedema,
|
|
175
|
-
icterus: flat.uro_ex_general_icterus,
|
|
176
|
-
lymphadenopathy: flat.uro_ex_general_lymph
|
|
177
|
-
},
|
|
178
|
-
abdomen: {
|
|
179
|
-
distension: flat.uro_ex_ab_distension,
|
|
180
|
-
surgical_scars: flat.uro_ex_ab_scars,
|
|
181
|
-
visible_mass: flat.uro_ex_ab_mass,
|
|
182
|
-
kidney_palpable: flat.uro_ex_ab_kidney_palpable,
|
|
183
|
-
bladder_palpable: flat.uro_ex_ab_bladder_palpable,
|
|
184
|
-
renal_angle_tender: flat.uro_ex_ab_renal_angle_tender,
|
|
185
|
-
bladder_dullness_retention: flat.uro_ex_ab_bladder_dull
|
|
186
|
-
},
|
|
187
|
-
external_genitalia_scrotum: {
|
|
188
|
-
meatus_abnormal_hypospadias_query: flat.uro_ex_gu_meatus,
|
|
189
|
-
phimosis_paraphimosis: flat.uro_ex_gu_phimosis,
|
|
190
|
-
penile_lesions_ulcers: flat.uro_ex_gu_lesions,
|
|
191
|
-
scrotal_swelling: flat.uro_ex_gu_scrotal_swelling,
|
|
192
|
-
transilluminant: flat.uro_ex_gu_transilluminant,
|
|
193
|
-
tender_testis: flat.uro_ex_gu_tender_testis,
|
|
194
|
-
hydrocele: flat.uro_ex_gu_hydrocele,
|
|
195
|
-
varicocele: flat.uro_ex_gu_varicocele,
|
|
196
|
-
suspicious_mass_urgent: flat.uro_ex_gu_suspicious_mass
|
|
197
|
-
},
|
|
198
|
-
dre_prostate: {
|
|
199
|
-
dre_performed: flat.uro_ex_dre_done,
|
|
200
|
-
estimated_size_grams: flat.uro_ex_dre_size_g,
|
|
201
|
-
consistency: flat.uro_ex_dre_consistency,
|
|
202
|
-
median_sulcus: flat.uro_ex_dre_median_sulcus,
|
|
203
|
-
tenderness_prostatitis_query: flat.uro_ex_dre_tender
|
|
204
|
-
},
|
|
205
|
-
examination_notes_free_text: flat.uro_examination_notes ?? ""
|
|
206
|
-
};
|
|
207
|
-
}
|
|
208
|
-
function buildUrologyExaminationFromComposite(raw) {
|
|
209
|
-
const regions = Array.isArray(raw.regions) ? raw.regions.filter((x) => typeof x === "string") : [];
|
|
210
|
-
const g = isUroPlainObject(raw.general) ? raw.general : {};
|
|
211
|
-
const ab = isUroPlainObject(raw.abdomen) ? raw.abdomen : {};
|
|
212
|
-
const gu = isUroPlainObject(raw.gu) ? raw.gu : {};
|
|
213
|
-
const dr = isUroPlainObject(raw.dre) ? raw.dre : {};
|
|
214
|
-
const dreConsistency = typeof dr.consistency === "string" ? dr.consistency : "";
|
|
215
|
-
const dreMedian = typeof dr.medianSulcus === "string" ? dr.medianSulcus : typeof dr.median_sulcus === "string" ? dr.median_sulcus : "";
|
|
216
|
-
const sizeG = Number(dr.sizeGrams);
|
|
217
|
-
const sizeGrams = Number.isFinite(sizeG) && sizeG >= 0 ? Math.round(sizeG) : 0;
|
|
218
|
-
const notesRaw = raw.examinationNotes;
|
|
219
|
-
const notes = typeof notesRaw === "string" ? notesRaw : "";
|
|
220
|
-
const bool = (x) => x === true;
|
|
221
|
-
return {
|
|
222
|
-
regions_reviewed: regions,
|
|
223
|
-
general: {
|
|
224
|
-
pallor: bool(g.pallor),
|
|
225
|
-
oedema: bool(g.oedema),
|
|
226
|
-
icterus: bool(g.icterus),
|
|
227
|
-
lymphadenopathy: bool(g.lymphadenopathy)
|
|
228
|
-
},
|
|
229
|
-
abdomen: {
|
|
230
|
-
distension: bool(ab.distension),
|
|
231
|
-
surgical_scars: bool(ab.scars),
|
|
232
|
-
visible_mass: bool(ab.mass),
|
|
233
|
-
kidney_palpable: bool(ab.kidneyPalpable),
|
|
234
|
-
bladder_palpable: bool(ab.bladderPalpable),
|
|
235
|
-
renal_angle_tender: bool(ab.renalAngleTender),
|
|
236
|
-
bladder_dullness_retention: bool(ab.bladderDull)
|
|
237
|
-
},
|
|
238
|
-
external_genitalia_scrotum: {
|
|
239
|
-
meatus_abnormal_hypospadias_query: bool(gu.meatusAbnormal),
|
|
240
|
-
phimosis_paraphimosis: bool(gu.phimosis),
|
|
241
|
-
penile_lesions_ulcers: bool(gu.lesions),
|
|
242
|
-
scrotal_swelling: bool(gu.scrotalSwelling),
|
|
243
|
-
transilluminant: bool(gu.transilluminant),
|
|
244
|
-
tender_testis: bool(gu.tenderTestis),
|
|
245
|
-
hydrocele: bool(gu.hydrocele),
|
|
246
|
-
varicocele: bool(gu.varicocele),
|
|
247
|
-
suspicious_mass_urgent: bool(gu.suspiciousMass)
|
|
248
|
-
},
|
|
249
|
-
dre_prostate: {
|
|
250
|
-
dre_performed: bool(dr.done),
|
|
251
|
-
estimated_size_grams: sizeGrams,
|
|
252
|
-
consistency: dreConsistency === "none" ? "" : dreConsistency,
|
|
253
|
-
median_sulcus: dreMedian === "none" ? "" : dreMedian,
|
|
254
|
-
tenderness_prostatitis_query: bool(dr.tenderness)
|
|
255
|
-
},
|
|
256
|
-
examination_notes_free_text: notes
|
|
257
|
-
};
|
|
258
|
-
}
|
|
259
|
-
function buildUrologyDecisionEngineAndRisk(flat) {
|
|
260
|
-
const comp = flat.uro_pathway;
|
|
261
|
-
if (isUroPlainObject(comp)) {
|
|
262
|
-
const riskIn = isUroPlainObject(comp.risk) ? comp.risk : {};
|
|
263
|
-
return {
|
|
264
|
-
decision_engine: {
|
|
265
|
-
stone_disease: {
|
|
266
|
-
stone_size_mm: comp.stoneSizeMm ?? 0,
|
|
267
|
-
hydronephrosis_on_imaging: coerceUrologyBool(comp.hydronephrosis)
|
|
268
|
-
},
|
|
269
|
-
prostate_bph_flow_lab: {
|
|
270
|
-
prostate_volume_cc: comp.prostateVolumeCc ?? 0,
|
|
271
|
-
psa_ng_ml: comp.psaNgMl ?? 0,
|
|
272
|
-
uroflow_qmax_ml_s: comp.uroflowQmaxMlSec ?? 0
|
|
273
|
-
}
|
|
274
|
-
},
|
|
275
|
-
risk_stratification: {
|
|
276
|
-
ckd: coerceUrologyBool(riskIn.ckd),
|
|
277
|
-
diabetes: coerceUrologyBool(riskIn.diabetes),
|
|
278
|
-
anticoagulants: coerceUrologyBool(riskIn.anticoagulants),
|
|
279
|
-
active_infection: coerceUrologyBool(riskIn.activeInfection)
|
|
280
|
-
}
|
|
281
|
-
};
|
|
282
|
-
}
|
|
283
|
-
return {
|
|
284
|
-
decision_engine: {
|
|
285
|
-
stone_disease: {
|
|
286
|
-
stone_size_mm: flat.uro_stone_size_mm,
|
|
287
|
-
hydronephrosis_on_imaging: coerceUrologyBool(flat.uro_stone_hydronephrosis)
|
|
288
|
-
},
|
|
289
|
-
prostate_bph_flow_lab: {
|
|
290
|
-
prostate_volume_cc: flat.uro_prostate_vol_cc,
|
|
291
|
-
psa_ng_ml: flat.uro_psa_ng_ml,
|
|
292
|
-
uroflow_qmax_ml_s: flat.uro_flow_qmax
|
|
293
|
-
}
|
|
294
|
-
},
|
|
295
|
-
risk_stratification: {
|
|
296
|
-
ckd: coerceUrologyBool(flat.uro_risk_ckd),
|
|
297
|
-
diabetes: coerceUrologyBool(flat.uro_risk_diabetes),
|
|
298
|
-
anticoagulants: coerceUrologyBool(flat.uro_risk_anticoag),
|
|
299
|
-
active_infection: coerceUrologyBool(flat.uro_risk_active_infection)
|
|
300
|
-
}
|
|
301
|
-
};
|
|
302
|
-
}
|
|
303
|
-
function attachUrologyClinicalPathwayMetadata(payload, template) {
|
|
304
|
-
if (!shouldFoldUrologyClinicalPathway(template, payload)) return;
|
|
305
|
-
const extra = UROLOGY_EXTRA_METADATA_KEYS;
|
|
306
|
-
const keys = Object.keys(payload).filter(
|
|
307
|
-
(k) => k.startsWith("uro_") || k === "chief_complaints" || k === "chief_complaints_chips" || extra.includes(k)
|
|
308
|
-
);
|
|
309
|
-
if (keys.length === 0) return;
|
|
310
|
-
const flat = {};
|
|
311
|
-
for (const k of keys) {
|
|
312
|
-
flat[k] = payload[k];
|
|
313
|
-
delete payload[k];
|
|
314
|
-
}
|
|
315
|
-
const triage = flat.uro_triage;
|
|
316
|
-
const chiefComplaints = {
|
|
317
|
-
narrative: flat.chief_complaints ?? "",
|
|
318
|
-
chips: flat.chief_complaints_chips ?? [],
|
|
319
|
-
duration: flat.uro_chief_duration ?? "",
|
|
320
|
-
onset: flat.uro_chief_onset ?? "",
|
|
321
|
-
progression: flat.uro_chief_progression ?? "",
|
|
322
|
-
active_syndrome: flat.uro_active_syndrome ?? ""
|
|
323
|
-
};
|
|
324
|
-
const compositeSh = flat.uro_smart_history;
|
|
325
|
-
const compositeEx = flat.uro_examination;
|
|
326
|
-
const smart_history = isUroPlainObject(compositeSh) ? buildUrologySmartHistoryFromComposite(compositeSh, flat) : buildUrologySmartHistoryFromLegacyFlat(flat);
|
|
327
|
-
const examination = isUroPlainObject(compositeEx) ? buildUrologyExaminationFromComposite(compositeEx) : buildUrologyExaminationFromLegacyFlat(flat);
|
|
328
|
-
const { decision_engine, risk_stratification } = buildUrologyDecisionEngineAndRisk(flat);
|
|
329
|
-
const structured = {
|
|
330
|
-
triage_vas_and_flags: triage ?? null,
|
|
331
|
-
chief_complaint_engine: chiefComplaints,
|
|
332
|
-
smart_history,
|
|
333
|
-
examination,
|
|
334
|
-
pathway_triggers_objective_scores: decision_engine,
|
|
335
|
-
risk_stratification,
|
|
336
|
-
encounter_narrative: {
|
|
337
|
-
symptoms: flat.symptoms ?? "",
|
|
338
|
-
notes: flat.notes ?? "",
|
|
339
|
-
vitals: flat.vitals ?? ""
|
|
340
|
-
}
|
|
341
|
-
};
|
|
342
|
-
const existingMetadata = payload.metadata ?? {};
|
|
343
|
-
const existingPathways = existingMetadata.clinical_pathways ?? {};
|
|
344
|
-
payload.metadata = {
|
|
345
|
-
...existingMetadata,
|
|
346
|
-
clinical_pathways: {
|
|
347
|
-
...existingPathways,
|
|
348
|
-
urology: structured
|
|
349
|
-
}
|
|
350
|
-
};
|
|
351
|
-
}
|
|
352
|
-
|
|
353
33
|
// src/core/validate.ts
|
|
354
34
|
var EMAIL_REGEX = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
355
35
|
function validateField(value, field) {
|
|
@@ -1018,233 +698,6 @@ function formatGeneralSurgeryExaminationToNarrative(v) {
|
|
|
1018
698
|
return blocks.join("\n\n");
|
|
1019
699
|
}
|
|
1020
700
|
|
|
1021
|
-
// src/core/urologyPathway.ts
|
|
1022
|
-
var defaultUrologySmartHistory = () => ({
|
|
1023
|
-
socrates: {
|
|
1024
|
-
site: "",
|
|
1025
|
-
onset: "",
|
|
1026
|
-
character: "",
|
|
1027
|
-
radiation: "",
|
|
1028
|
-
associated: "",
|
|
1029
|
-
timing: "",
|
|
1030
|
-
exacerbating: "",
|
|
1031
|
-
severity: 0
|
|
1032
|
-
},
|
|
1033
|
-
ipss: {
|
|
1034
|
-
incomplete: 0,
|
|
1035
|
-
frequency: 0,
|
|
1036
|
-
intermittency: 0,
|
|
1037
|
-
urgency: 0,
|
|
1038
|
-
weakStream: 0,
|
|
1039
|
-
straining: 0,
|
|
1040
|
-
nocturia: 0
|
|
1041
|
-
},
|
|
1042
|
-
ipssQoL: 0,
|
|
1043
|
-
haematuria: { present: false, timing: "", painful: false, clots: false },
|
|
1044
|
-
sexual: { erectile: "", libido: "", ejaculation: "", infertilityMonths: 0 },
|
|
1045
|
-
pastNotes: ""
|
|
1046
|
-
});
|
|
1047
|
-
var defaultUrologyExamination = () => ({
|
|
1048
|
-
regions: [],
|
|
1049
|
-
general: { pallor: false, oedema: false, icterus: false, lymphadenopathy: false },
|
|
1050
|
-
abdomen: {
|
|
1051
|
-
distension: false,
|
|
1052
|
-
scars: false,
|
|
1053
|
-
mass: false,
|
|
1054
|
-
kidneyPalpable: false,
|
|
1055
|
-
bladderPalpable: false,
|
|
1056
|
-
renalAngleTender: false,
|
|
1057
|
-
bladderDull: false
|
|
1058
|
-
},
|
|
1059
|
-
gu: {
|
|
1060
|
-
meatusAbnormal: false,
|
|
1061
|
-
phimosis: false,
|
|
1062
|
-
lesions: false,
|
|
1063
|
-
scrotalSwelling: false,
|
|
1064
|
-
transilluminant: false,
|
|
1065
|
-
tenderTestis: false,
|
|
1066
|
-
hydrocele: false,
|
|
1067
|
-
varicocele: false,
|
|
1068
|
-
suspiciousMass: false
|
|
1069
|
-
},
|
|
1070
|
-
dre: { done: false, sizeGrams: 0, consistency: "", medianSulcus: "", tenderness: false },
|
|
1071
|
-
examinationNotes: ""
|
|
1072
|
-
});
|
|
1073
|
-
function clampInt(n, lo, hi) {
|
|
1074
|
-
if (!Number.isFinite(n)) return lo;
|
|
1075
|
-
return Math.min(hi, Math.max(lo, Math.round(n)));
|
|
1076
|
-
}
|
|
1077
|
-
var SOCRATES_KEYS = [
|
|
1078
|
-
"site",
|
|
1079
|
-
"onset",
|
|
1080
|
-
"character",
|
|
1081
|
-
"radiation",
|
|
1082
|
-
"associated",
|
|
1083
|
-
"timing",
|
|
1084
|
-
"exacerbating"
|
|
1085
|
-
];
|
|
1086
|
-
function urologyIpssSevenTotal(ipss) {
|
|
1087
|
-
return ipss.incomplete + ipss.frequency + ipss.intermittency + ipss.urgency + ipss.weakStream + ipss.straining + ipss.nocturia;
|
|
1088
|
-
}
|
|
1089
|
-
function urologyIpssBand(total) {
|
|
1090
|
-
if (total <= 7) return "Mild";
|
|
1091
|
-
if (total <= 19) return "Moderate";
|
|
1092
|
-
return "Severe";
|
|
1093
|
-
}
|
|
1094
|
-
function normalizeUrologySmartHistory(raw) {
|
|
1095
|
-
const d = defaultUrologySmartHistory();
|
|
1096
|
-
if (!raw || typeof raw !== "object" || Array.isArray(raw)) return d;
|
|
1097
|
-
const v = raw;
|
|
1098
|
-
const socIn = v.socrates && typeof v.socrates === "object" ? v.socrates : {};
|
|
1099
|
-
const socrates = { ...d.socrates };
|
|
1100
|
-
for (const k of SOCRATES_KEYS) {
|
|
1101
|
-
const x = socIn[k];
|
|
1102
|
-
socrates[k] = typeof x === "string" ? x : "";
|
|
1103
|
-
}
|
|
1104
|
-
const sev = Number(socIn.severity);
|
|
1105
|
-
socrates.severity = clampInt(Number.isFinite(sev) ? sev : d.socrates.severity, 0, 10);
|
|
1106
|
-
const ipIn = v.ipss && typeof v.ipss === "object" ? v.ipss : {};
|
|
1107
|
-
const ipss = { ...d.ipss };
|
|
1108
|
-
for (const k of [
|
|
1109
|
-
"incomplete",
|
|
1110
|
-
"frequency",
|
|
1111
|
-
"intermittency",
|
|
1112
|
-
"urgency",
|
|
1113
|
-
"weakStream",
|
|
1114
|
-
"straining",
|
|
1115
|
-
"nocturia"
|
|
1116
|
-
]) {
|
|
1117
|
-
const n = Number(ipIn[k]);
|
|
1118
|
-
ipss[k] = clampInt(Number.isFinite(n) ? n : 0, 0, 5);
|
|
1119
|
-
}
|
|
1120
|
-
const qol = Number(v.ipssQoL);
|
|
1121
|
-
const ipssQoL = clampInt(Number.isFinite(qol) ? qol : d.ipssQoL, 0, 6);
|
|
1122
|
-
const haIn = v.haematuria && typeof v.haematuria === "object" ? v.haematuria : {};
|
|
1123
|
-
const timingRaw = haIn.timing;
|
|
1124
|
-
const haematuria = {
|
|
1125
|
-
present: haIn.present === true,
|
|
1126
|
-
timing: typeof timingRaw === "string" && timingRaw !== "none" && timingRaw.length > 0 ? timingRaw : "",
|
|
1127
|
-
painful: haIn.painful === true,
|
|
1128
|
-
clots: haIn.clots === true
|
|
1129
|
-
};
|
|
1130
|
-
const sxIn = v.sexual && typeof v.sexual === "object" ? v.sexual : {};
|
|
1131
|
-
const str2 = (x) => typeof x === "string" && x.length > 0 && x !== "none" ? x : "";
|
|
1132
|
-
const inf = Number(sxIn.infertilityMonths);
|
|
1133
|
-
const sexual = {
|
|
1134
|
-
erectile: str2(sxIn.erectile),
|
|
1135
|
-
libido: str2(sxIn.libido),
|
|
1136
|
-
ejaculation: str2(sxIn.ejaculation),
|
|
1137
|
-
infertilityMonths: Number.isFinite(inf) && inf >= 0 ? Math.round(inf) : 0
|
|
1138
|
-
};
|
|
1139
|
-
const pastNotes = typeof v.pastNotes === "string" ? v.pastNotes : d.pastNotes;
|
|
1140
|
-
return { socrates, ipss, ipssQoL, haematuria, sexual, pastNotes };
|
|
1141
|
-
}
|
|
1142
|
-
function normalizeUrologyExamination(raw) {
|
|
1143
|
-
const d = defaultUrologyExamination();
|
|
1144
|
-
if (!raw || typeof raw !== "object" || Array.isArray(raw)) return d;
|
|
1145
|
-
const v = raw;
|
|
1146
|
-
const strArr = (x) => Array.isArray(x) ? x.filter((i) => typeof i === "string") : [];
|
|
1147
|
-
const bool = (x) => x === true;
|
|
1148
|
-
const g = v.general && typeof v.general === "object" ? v.general : {};
|
|
1149
|
-
const ab = v.abdomen && typeof v.abdomen === "object" ? v.abdomen : {};
|
|
1150
|
-
const gu = v.gu && typeof v.gu === "object" ? v.gu : {};
|
|
1151
|
-
const dr = v.dre && typeof v.dre === "object" ? v.dre : {};
|
|
1152
|
-
const sg = Number(dr.sizeGrams);
|
|
1153
|
-
const consistencyRaw = dr.consistency;
|
|
1154
|
-
const medianRaw = dr.medianSulcus;
|
|
1155
|
-
const dreEmpty = (x) => !(typeof x === "string" && x.length > 0 && x !== "none");
|
|
1156
|
-
return {
|
|
1157
|
-
regions: strArr(v.regions),
|
|
1158
|
-
general: {
|
|
1159
|
-
pallor: bool(g.pallor),
|
|
1160
|
-
oedema: bool(g.oedema),
|
|
1161
|
-
icterus: bool(g.icterus),
|
|
1162
|
-
lymphadenopathy: bool(g.lymphadenopathy)
|
|
1163
|
-
},
|
|
1164
|
-
abdomen: {
|
|
1165
|
-
distension: bool(ab.distension),
|
|
1166
|
-
scars: bool(ab.scars),
|
|
1167
|
-
mass: bool(ab.mass),
|
|
1168
|
-
kidneyPalpable: bool(ab.kidneyPalpable),
|
|
1169
|
-
bladderPalpable: bool(ab.bladderPalpable),
|
|
1170
|
-
renalAngleTender: bool(ab.renalAngleTender),
|
|
1171
|
-
bladderDull: bool(ab.bladderDull)
|
|
1172
|
-
},
|
|
1173
|
-
gu: {
|
|
1174
|
-
meatusAbnormal: bool(gu.meatusAbnormal),
|
|
1175
|
-
phimosis: bool(gu.phimosis),
|
|
1176
|
-
lesions: bool(gu.lesions),
|
|
1177
|
-
scrotalSwelling: bool(gu.scrotalSwelling),
|
|
1178
|
-
transilluminant: bool(gu.transilluminant),
|
|
1179
|
-
tenderTestis: bool(gu.tenderTestis),
|
|
1180
|
-
hydrocele: bool(gu.hydrocele),
|
|
1181
|
-
varicocele: bool(gu.varicocele),
|
|
1182
|
-
suspiciousMass: bool(gu.suspiciousMass)
|
|
1183
|
-
},
|
|
1184
|
-
dre: {
|
|
1185
|
-
done: bool(dr.done),
|
|
1186
|
-
sizeGrams: Number.isFinite(sg) && sg >= 0 ? Math.round(sg) : 0,
|
|
1187
|
-
consistency: dreEmpty(consistencyRaw) ? "" : String(consistencyRaw),
|
|
1188
|
-
medianSulcus: dreEmpty(medianRaw) ? "" : String(medianRaw),
|
|
1189
|
-
tenderness: bool(dr.tenderness)
|
|
1190
|
-
},
|
|
1191
|
-
examinationNotes: typeof v.examinationNotes === "string" ? v.examinationNotes : d.examinationNotes
|
|
1192
|
-
};
|
|
1193
|
-
}
|
|
1194
|
-
var defaultUrologyPathway = () => ({
|
|
1195
|
-
stoneSizeMm: 0,
|
|
1196
|
-
hydronephrosis: false,
|
|
1197
|
-
prostateVolumeCc: 0,
|
|
1198
|
-
psaNgMl: 0,
|
|
1199
|
-
uroflowQmaxMlSec: 0,
|
|
1200
|
-
risk: {
|
|
1201
|
-
ckd: false,
|
|
1202
|
-
diabetes: false,
|
|
1203
|
-
anticoagulants: false,
|
|
1204
|
-
activeInfection: false
|
|
1205
|
-
}
|
|
1206
|
-
});
|
|
1207
|
-
function clampNonNegativeNumber(x, fallback) {
|
|
1208
|
-
const n = Number(x);
|
|
1209
|
-
if (!Number.isFinite(n) || n < 0) return fallback;
|
|
1210
|
-
return n;
|
|
1211
|
-
}
|
|
1212
|
-
function normalizeUrologyPathway(raw) {
|
|
1213
|
-
const d = defaultUrologyPathway();
|
|
1214
|
-
if (!raw || typeof raw !== "object" || Array.isArray(raw)) return d;
|
|
1215
|
-
const v = raw;
|
|
1216
|
-
const rIn = v.risk && typeof v.risk === "object" && !Array.isArray(v.risk) ? v.risk : {};
|
|
1217
|
-
return {
|
|
1218
|
-
stoneSizeMm: clampNonNegativeNumber(v.stoneSizeMm, d.stoneSizeMm),
|
|
1219
|
-
hydronephrosis: v.hydronephrosis === true,
|
|
1220
|
-
prostateVolumeCc: clampNonNegativeNumber(v.prostateVolumeCc, d.prostateVolumeCc),
|
|
1221
|
-
psaNgMl: clampNonNegativeNumber(v.psaNgMl, d.psaNgMl),
|
|
1222
|
-
uroflowQmaxMlSec: clampNonNegativeNumber(v.uroflowQmaxMlSec, d.uroflowQmaxMlSec),
|
|
1223
|
-
risk: {
|
|
1224
|
-
ckd: rIn.ckd === true,
|
|
1225
|
-
diabetes: rIn.diabetes === true,
|
|
1226
|
-
anticoagulants: rIn.anticoagulants === true,
|
|
1227
|
-
activeInfection: rIn.activeInfection === true
|
|
1228
|
-
}
|
|
1229
|
-
};
|
|
1230
|
-
}
|
|
1231
|
-
function urologyStoneRecommendation(sizeMm, hydronephrosis) {
|
|
1232
|
-
if (sizeMm <= 0) return { plan: "Enter stone size to auto-trigger plan.", surgical: false };
|
|
1233
|
-
if (sizeMm < 5) return { plan: "Conservative + MET (\u03B1-blocker), hydration", surgical: false };
|
|
1234
|
-
if (sizeMm <= 10)
|
|
1235
|
-
return {
|
|
1236
|
-
plan: hydronephrosis ? "URS / SWL \u2014 obstruction present" : "Medical expulsive therapy / URS",
|
|
1237
|
-
surgical: hydronephrosis
|
|
1238
|
-
};
|
|
1239
|
-
return { plan: "URS / PCNL \u2014 surgical clearance indicated", surgical: true };
|
|
1240
|
-
}
|
|
1241
|
-
function urologyProstateProcedure(volumeCc) {
|
|
1242
|
-
if (volumeCc <= 0) return "Enter prostate volume.";
|
|
1243
|
-
if (volumeCc < 30) return "Medical (\u03B1-blocker \xB1 5-ARI)";
|
|
1244
|
-
if (volumeCc <= 80) return "TURP";
|
|
1245
|
-
return "HoLEP / Open simple prostatectomy";
|
|
1246
|
-
}
|
|
1247
|
-
|
|
1248
701
|
// src/core/painScaleFlags.ts
|
|
1249
702
|
function normalizePainScaleFlags(raw, bounds) {
|
|
1250
703
|
const min = bounds?.min ?? 0;
|
|
@@ -1363,12 +816,6 @@ var FormStore = class {
|
|
|
1363
816
|
f.defaultValue ?? { pain: f.min ?? 0, flags: [] },
|
|
1364
817
|
{ min: f.min, max: f.max }
|
|
1365
818
|
);
|
|
1366
|
-
} else if (field.type === "urology_smart_history") {
|
|
1367
|
-
values[field.id] = field.defaultValue ?? defaultUrologySmartHistory();
|
|
1368
|
-
} else if (field.type === "urology_examination") {
|
|
1369
|
-
values[field.id] = field.defaultValue ?? defaultUrologyExamination();
|
|
1370
|
-
} else if (field.type === "urology_pathway") {
|
|
1371
|
-
values[field.id] = field.defaultValue ?? defaultUrologyPathway();
|
|
1372
819
|
} else values[field.id] = null;
|
|
1373
820
|
}
|
|
1374
821
|
});
|
|
@@ -1578,7 +1025,6 @@ var FormStore = class {
|
|
|
1578
1025
|
}
|
|
1579
1026
|
}
|
|
1580
1027
|
});
|
|
1581
|
-
attachUrologyClinicalPathwayMetadata(result, this.schema);
|
|
1582
1028
|
return result;
|
|
1583
1029
|
}
|
|
1584
1030
|
// --- Core Logic ---
|
|
@@ -6551,7 +5997,7 @@ function safeJsonParse(val) {
|
|
|
6551
5997
|
return null;
|
|
6552
5998
|
}
|
|
6553
5999
|
}
|
|
6554
|
-
function
|
|
6000
|
+
function clampInt(val, min, max) {
|
|
6555
6001
|
if (!Number.isFinite(val)) return min;
|
|
6556
6002
|
return Math.max(min, Math.min(max, Math.trunc(val)));
|
|
6557
6003
|
}
|
|
@@ -6561,10 +6007,10 @@ function parseLegacyString(input) {
|
|
|
6561
6007
|
if (gpalMatch) {
|
|
6562
6008
|
const [, g, p, a, l] = gpalMatch;
|
|
6563
6009
|
result.gpal = {
|
|
6564
|
-
G:
|
|
6565
|
-
P:
|
|
6566
|
-
A:
|
|
6567
|
-
L:
|
|
6010
|
+
G: clampInt(Number(g), 0, 20),
|
|
6011
|
+
P: clampInt(Number(p), 0, 20),
|
|
6012
|
+
A: clampInt(Number(a), 0, 20),
|
|
6013
|
+
L: clampInt(Number(l), 0, 20)
|
|
6568
6014
|
};
|
|
6569
6015
|
}
|
|
6570
6016
|
const lmpMatch = input.match(/LMP:\s*([^\n]+)/i);
|
|
@@ -6597,10 +6043,10 @@ function normalizeToDraft(value) {
|
|
|
6597
6043
|
isNewEntry: false,
|
|
6598
6044
|
draft: {
|
|
6599
6045
|
gpal: {
|
|
6600
|
-
G:
|
|
6601
|
-
P:
|
|
6602
|
-
A:
|
|
6603
|
-
L:
|
|
6046
|
+
G: clampInt(Number(gpal.G ?? 0), 0, 20),
|
|
6047
|
+
P: clampInt(Number(gpal.P ?? 0), 0, 20),
|
|
6048
|
+
A: clampInt(Number(gpal.A ?? 0), 0, 20),
|
|
6049
|
+
L: clampInt(Number(gpal.L ?? 0), 0, 20)
|
|
6604
6050
|
},
|
|
6605
6051
|
lmp: typeof lmp === "string" ? lmp : "",
|
|
6606
6052
|
is_pregnant,
|
|
@@ -6618,10 +6064,10 @@ function normalizeToDraft(value) {
|
|
|
6618
6064
|
}
|
|
6619
6065
|
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
6620
6066
|
const gpalFromFlat = {
|
|
6621
|
-
G:
|
|
6622
|
-
P:
|
|
6623
|
-
A:
|
|
6624
|
-
L:
|
|
6067
|
+
G: clampInt(Number(parsed.G ?? parsed.g ?? 0), 0, 20),
|
|
6068
|
+
P: clampInt(Number(parsed.P ?? parsed.p ?? 0), 0, 20),
|
|
6069
|
+
A: clampInt(Number(parsed.A ?? parsed.a ?? 0), 0, 20),
|
|
6070
|
+
L: clampInt(Number(parsed.L ?? parsed.l ?? 0), 0, 20)
|
|
6625
6071
|
};
|
|
6626
6072
|
return {
|
|
6627
6073
|
isNewEntry: false,
|
|
@@ -6773,7 +6219,7 @@ var ObstetricHistoryWidget = ({ fieldId }) => {
|
|
|
6773
6219
|
const sanitizeGpalInput = (raw) => {
|
|
6774
6220
|
const digits = raw.replace(/[^\d]/g, "").slice(0, 2);
|
|
6775
6221
|
if (!digits) return 0;
|
|
6776
|
-
return
|
|
6222
|
+
return clampInt(Number(digits), 0, 20);
|
|
6777
6223
|
};
|
|
6778
6224
|
const handleGpalChange = (key, raw) => {
|
|
6779
6225
|
const prevWasEmpty = draft.gpal[key] === 0 && activeGpalKey === key;
|
|
@@ -10101,7 +9547,7 @@ var THYROID_OPTS = [
|
|
|
10101
9547
|
{ value: "voice_change", label: "Voice change" },
|
|
10102
9548
|
{ value: "thyrotoxicosis", label: "Thyrotoxicosis symptoms" }
|
|
10103
9549
|
];
|
|
10104
|
-
var
|
|
9550
|
+
var SOCRATES_KEYS = [
|
|
10105
9551
|
"site",
|
|
10106
9552
|
"onset",
|
|
10107
9553
|
"character",
|
|
@@ -10195,7 +9641,7 @@ var GsSmartHistoryWidget = ({ fieldId }) => {
|
|
|
10195
9641
|
labelEl,
|
|
10196
9642
|
/* @__PURE__ */ jsxs("div", { className: bodyClass, children: [
|
|
10197
9643
|
showPain ? /* @__PURE__ */ jsx(Panel, { title: "SOCRATES \u2014 pain", children: /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-2 md:grid-cols-4", children: [
|
|
10198
|
-
|
|
9644
|
+
SOCRATES_KEYS.map((k) => /* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
|
|
10199
9645
|
/* @__PURE__ */ jsx("span", { className: "text-[10px] font-medium uppercase tracking-wide text-muted-foreground", children: k }),
|
|
10200
9646
|
/* @__PURE__ */ jsx(
|
|
10201
9647
|
Input,
|
|
@@ -11132,919 +10578,106 @@ var PainScaleFlagsWidget = ({ fieldId }) => {
|
|
|
11132
10578
|
showError && /* @__PURE__ */ jsx("p", { className: "text-xs text-red-500", children: error })
|
|
11133
10579
|
] });
|
|
11134
10580
|
};
|
|
11135
|
-
var
|
|
11136
|
-
|
|
11137
|
-
|
|
11138
|
-
|
|
11139
|
-
|
|
11140
|
-
|
|
11141
|
-
var IPSS_LABELS = {
|
|
11142
|
-
incomplete: "Incomplete emptying",
|
|
11143
|
-
frequency: "Frequency (<2h)",
|
|
11144
|
-
intermittency: "Intermittency",
|
|
11145
|
-
urgency: "Urgency",
|
|
11146
|
-
weakStream: "Weak stream",
|
|
11147
|
-
straining: "Straining",
|
|
11148
|
-
nocturia: "Nocturia (\xD7/night)"
|
|
10581
|
+
var FieldRenderer = ({ fieldId }) => {
|
|
10582
|
+
const { fieldDef, visible } = useField(fieldId);
|
|
10583
|
+
if (!visible || !fieldDef) {
|
|
10584
|
+
return null;
|
|
10585
|
+
}
|
|
10586
|
+
return renderWidget(fieldId, fieldDef);
|
|
11149
10587
|
};
|
|
11150
|
-
|
|
11151
|
-
|
|
11152
|
-
|
|
11153
|
-
|
|
11154
|
-
|
|
11155
|
-
|
|
11156
|
-
|
|
11157
|
-
|
|
11158
|
-
|
|
11159
|
-
|
|
11160
|
-
|
|
11161
|
-
|
|
11162
|
-
|
|
11163
|
-
})
|
|
11164
|
-
|
|
11165
|
-
|
|
11166
|
-
|
|
11167
|
-
|
|
11168
|
-
|
|
11169
|
-
|
|
11170
|
-
|
|
11171
|
-
}
|
|
11172
|
-
|
|
11173
|
-
|
|
11174
|
-
|
|
11175
|
-
|
|
11176
|
-
|
|
11177
|
-
|
|
11178
|
-
|
|
11179
|
-
|
|
11180
|
-
|
|
11181
|
-
|
|
11182
|
-
|
|
11183
|
-
|
|
11184
|
-
|
|
11185
|
-
|
|
11186
|
-
|
|
11187
|
-
|
|
11188
|
-
|
|
11189
|
-
|
|
11190
|
-
|
|
11191
|
-
|
|
11192
|
-
|
|
11193
|
-
|
|
11194
|
-
|
|
11195
|
-
|
|
11196
|
-
|
|
11197
|
-
return;
|
|
11198
|
-
|
|
11199
|
-
|
|
11200
|
-
|
|
11201
|
-
|
|
11202
|
-
|
|
11203
|
-
|
|
11204
|
-
|
|
11205
|
-
|
|
11206
|
-
|
|
11207
|
-
|
|
11208
|
-
|
|
11209
|
-
|
|
11210
|
-
|
|
11211
|
-
|
|
11212
|
-
|
|
11213
|
-
|
|
11214
|
-
|
|
11215
|
-
|
|
11216
|
-
|
|
11217
|
-
|
|
11218
|
-
|
|
11219
|
-
|
|
11220
|
-
|
|
11221
|
-
|
|
11222
|
-
|
|
11223
|
-
|
|
11224
|
-
|
|
11225
|
-
|
|
11226
|
-
|
|
11227
|
-
|
|
11228
|
-
|
|
11229
|
-
|
|
11230
|
-
|
|
11231
|
-
|
|
11232
|
-
|
|
11233
|
-
|
|
11234
|
-
|
|
11235
|
-
|
|
11236
|
-
|
|
11237
|
-
|
|
11238
|
-
|
|
11239
|
-
|
|
11240
|
-
|
|
11241
|
-
|
|
11242
|
-
|
|
11243
|
-
className: "h-8 text-xs",
|
|
11244
|
-
value: safe.socrates.severity,
|
|
11245
|
-
onChange: (e) => setSocrates("severity", e.target.value),
|
|
11246
|
-
disabled
|
|
11247
|
-
}
|
|
11248
|
-
)
|
|
11249
|
-
] })
|
|
11250
|
-
] }) }) : null,
|
|
11251
|
-
showLUTS ? /* @__PURE__ */ jsxs(
|
|
11252
|
-
Panel2,
|
|
11253
|
-
{
|
|
11254
|
-
title: "IPSS \u2014 International Prostate Symptom Score",
|
|
11255
|
-
right: /* @__PURE__ */ jsxs("span", { className: `rounded-full px-2 py-0.5 text-[10px] font-medium ${bandClass}`, children: [
|
|
11256
|
-
ipssTotal,
|
|
11257
|
-
"/35 \u2014 ",
|
|
11258
|
-
ipssBandLabel
|
|
11259
|
-
] }),
|
|
11260
|
-
children: [
|
|
11261
|
-
/* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-2 md:grid-cols-4", children: [
|
|
11262
|
-
Object.keys(IPSS_LABELS).map((k) => /* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
|
|
11263
|
-
/* @__PURE__ */ jsx("span", { className: "text-[10px] uppercase tracking-wide text-muted-foreground", children: IPSS_LABELS[k] }),
|
|
11264
|
-
/* @__PURE__ */ jsxs(
|
|
11265
|
-
Select,
|
|
11266
|
-
{
|
|
11267
|
-
value: String(safe.ipss[k]),
|
|
11268
|
-
onValueChange: (val) => setIpss(k, Number(val)),
|
|
11269
|
-
disabled,
|
|
11270
|
-
children: [
|
|
11271
|
-
/* @__PURE__ */ jsx(SelectTrigger, { className: "h-8 text-xs", children: /* @__PURE__ */ jsx(SelectValue, {}) }),
|
|
11272
|
-
/* @__PURE__ */ jsx(SelectContent, { children: [0, 1, 2, 3, 4, 5].map((n) => /* @__PURE__ */ jsx(SelectItem, { value: String(n), children: n }, n)) })
|
|
11273
|
-
]
|
|
11274
|
-
}
|
|
11275
|
-
)
|
|
11276
|
-
] }, k)),
|
|
11277
|
-
/* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
|
|
11278
|
-
/* @__PURE__ */ jsx("span", { className: "text-[10px] uppercase tracking-wide text-muted-foreground", children: "QoL (0\u20136)" }),
|
|
11279
|
-
/* @__PURE__ */ jsxs(
|
|
11280
|
-
Select,
|
|
11281
|
-
{
|
|
11282
|
-
value: String(safe.ipssQoL),
|
|
11283
|
-
onValueChange: (val) => update({ ...safe, ipssQoL: Math.min(6, Math.max(0, Number(val))) }),
|
|
11284
|
-
disabled,
|
|
11285
|
-
children: [
|
|
11286
|
-
/* @__PURE__ */ jsx(SelectTrigger, { className: "h-8 text-xs", children: /* @__PURE__ */ jsx(SelectValue, {}) }),
|
|
11287
|
-
/* @__PURE__ */ jsx(SelectContent, { children: [0, 1, 2, 3, 4, 5, 6].map((n) => /* @__PURE__ */ jsx(SelectItem, { value: String(n), children: n }, n)) })
|
|
11288
|
-
]
|
|
11289
|
-
}
|
|
11290
|
-
)
|
|
11291
|
-
] })
|
|
11292
|
-
] }),
|
|
11293
|
-
/* @__PURE__ */ jsxs("p", { className: "mt-2 text-[10px] text-muted-foreground", children: [
|
|
11294
|
-
"Bands: 0\u20137 mild \xB7 8\u201319 moderate \xB7 20\u201335 severe.",
|
|
11295
|
-
" ",
|
|
11296
|
-
/* @__PURE__ */ jsx("span", { className: "font-semibold text-foreground", children: "IPSS \u2265 20 \u2192 consider surgical intervention." })
|
|
11297
|
-
] })
|
|
11298
|
-
]
|
|
11299
|
-
}
|
|
11300
|
-
) : null,
|
|
11301
|
-
showHaem ? /* @__PURE__ */ jsxs(Panel2, { title: "Haematuria profile", children: [
|
|
11302
|
-
/* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-3 text-xs md:grid-cols-4", children: [
|
|
11303
|
-
/* @__PURE__ */ jsxs("label", { className: "flex items-center gap-2", children: [
|
|
11304
|
-
/* @__PURE__ */ jsx(
|
|
11305
|
-
Checkbox,
|
|
11306
|
-
{
|
|
11307
|
-
checked: safe.haematuria.present,
|
|
11308
|
-
onCheckedChange: (c) => update({
|
|
11309
|
-
...safe,
|
|
11310
|
-
haematuria: { ...safe.haematuria, present: c === true }
|
|
11311
|
-
}),
|
|
11312
|
-
disabled
|
|
11313
|
-
}
|
|
11314
|
-
),
|
|
11315
|
-
"Present"
|
|
11316
|
-
] }),
|
|
11317
|
-
/* @__PURE__ */ jsxs("label", { className: "flex flex-col gap-1", children: [
|
|
11318
|
-
/* @__PURE__ */ jsx("span", { className: "font-medium", children: "Timing" }),
|
|
11319
|
-
/* @__PURE__ */ jsxs(
|
|
11320
|
-
Select,
|
|
11321
|
-
{
|
|
11322
|
-
value: safe.haematuria.timing || "none",
|
|
11323
|
-
onValueChange: (val) => update({
|
|
11324
|
-
...safe,
|
|
11325
|
-
haematuria: { ...safe.haematuria, timing: val === "none" ? "" : val }
|
|
11326
|
-
}),
|
|
11327
|
-
disabled,
|
|
11328
|
-
children: [
|
|
11329
|
-
/* @__PURE__ */ jsx(SelectTrigger, { className: "h-8 text-xs", children: /* @__PURE__ */ jsx(SelectValue, { placeholder: "\u2014" }) }),
|
|
11330
|
-
/* @__PURE__ */ jsxs(SelectContent, { children: [
|
|
11331
|
-
/* @__PURE__ */ jsx(SelectItem, { value: "none", children: "\u2014" }),
|
|
11332
|
-
/* @__PURE__ */ jsx(SelectItem, { value: "Initial", children: "Initial" }),
|
|
11333
|
-
/* @__PURE__ */ jsx(SelectItem, { value: "Terminal", children: "Terminal" }),
|
|
11334
|
-
/* @__PURE__ */ jsx(SelectItem, { value: "Total", children: "Total" })
|
|
11335
|
-
] })
|
|
11336
|
-
]
|
|
11337
|
-
}
|
|
11338
|
-
)
|
|
11339
|
-
] }),
|
|
11340
|
-
/* @__PURE__ */ jsxs("label", { className: "flex items-center gap-2", children: [
|
|
11341
|
-
/* @__PURE__ */ jsx(
|
|
11342
|
-
Checkbox,
|
|
11343
|
-
{
|
|
11344
|
-
checked: safe.haematuria.painful,
|
|
11345
|
-
onCheckedChange: (c) => update({ ...safe, haematuria: { ...safe.haematuria, painful: c === true } }),
|
|
11346
|
-
disabled
|
|
11347
|
-
}
|
|
11348
|
-
),
|
|
11349
|
-
"Painful"
|
|
11350
|
-
] }),
|
|
11351
|
-
/* @__PURE__ */ jsxs("label", { className: "flex items-center gap-2", children: [
|
|
11352
|
-
/* @__PURE__ */ jsx(
|
|
11353
|
-
Checkbox,
|
|
11354
|
-
{
|
|
11355
|
-
checked: safe.haematuria.clots,
|
|
11356
|
-
onCheckedChange: (c) => update({ ...safe, haematuria: { ...safe.haematuria, clots: c === true } }),
|
|
11357
|
-
disabled
|
|
11358
|
-
}
|
|
11359
|
-
),
|
|
11360
|
-
"Clots"
|
|
11361
|
-
] })
|
|
11362
|
-
] }),
|
|
11363
|
-
/* @__PURE__ */ jsx("p", { className: "mt-2 text-[10px] text-red-600", children: "Painless haematuria = malignancy until proven otherwise." })
|
|
11364
|
-
] }) : null,
|
|
11365
|
-
showSex ? /* @__PURE__ */ jsx(Panel2, { title: "Sexual & reproductive history", children: /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-3 text-xs md:grid-cols-4", children: [
|
|
11366
|
-
/* @__PURE__ */ jsxs("label", { className: "flex flex-col gap-1", children: [
|
|
11367
|
-
/* @__PURE__ */ jsx("span", { className: "font-medium", children: "Erectile function" }),
|
|
11368
|
-
/* @__PURE__ */ jsxs(
|
|
11369
|
-
Select,
|
|
11370
|
-
{
|
|
11371
|
-
value: safe.sexual.erectile || "none",
|
|
11372
|
-
onValueChange: (val) => update({
|
|
11373
|
-
...safe,
|
|
11374
|
-
sexual: { ...safe.sexual, erectile: val === "none" ? "" : val }
|
|
11375
|
-
}),
|
|
11376
|
-
disabled,
|
|
11377
|
-
children: [
|
|
11378
|
-
/* @__PURE__ */ jsx(SelectTrigger, { className: "h-8 text-xs", children: /* @__PURE__ */ jsx(SelectValue, { placeholder: "\u2014" }) }),
|
|
11379
|
-
/* @__PURE__ */ jsxs(SelectContent, { children: [
|
|
11380
|
-
/* @__PURE__ */ jsx(SelectItem, { value: "none", children: "\u2014" }),
|
|
11381
|
-
/* @__PURE__ */ jsx(SelectItem, { value: "Normal", children: "Normal" }),
|
|
11382
|
-
/* @__PURE__ */ jsx(SelectItem, { value: "Mild", children: "Mild" }),
|
|
11383
|
-
/* @__PURE__ */ jsx(SelectItem, { value: "Moderate", children: "Moderate" }),
|
|
11384
|
-
/* @__PURE__ */ jsx(SelectItem, { value: "Severe", children: "Severe" })
|
|
11385
|
-
] })
|
|
11386
|
-
]
|
|
11387
|
-
}
|
|
11388
|
-
)
|
|
11389
|
-
] }),
|
|
11390
|
-
/* @__PURE__ */ jsxs("label", { className: "flex flex-col gap-1", children: [
|
|
11391
|
-
/* @__PURE__ */ jsx("span", { className: "font-medium", children: "Libido" }),
|
|
11392
|
-
/* @__PURE__ */ jsxs(
|
|
11393
|
-
Select,
|
|
11394
|
-
{
|
|
11395
|
-
value: safe.sexual.libido || "none",
|
|
11396
|
-
onValueChange: (val) => update({
|
|
11397
|
-
...safe,
|
|
11398
|
-
sexual: { ...safe.sexual, libido: val === "none" ? "" : val }
|
|
11399
|
-
}),
|
|
11400
|
-
disabled,
|
|
11401
|
-
children: [
|
|
11402
|
-
/* @__PURE__ */ jsx(SelectTrigger, { className: "h-8 text-xs", children: /* @__PURE__ */ jsx(SelectValue, { placeholder: "\u2014" }) }),
|
|
11403
|
-
/* @__PURE__ */ jsxs(SelectContent, { children: [
|
|
11404
|
-
/* @__PURE__ */ jsx(SelectItem, { value: "none", children: "\u2014" }),
|
|
11405
|
-
/* @__PURE__ */ jsx(SelectItem, { value: "Normal", children: "Normal" }),
|
|
11406
|
-
/* @__PURE__ */ jsx(SelectItem, { value: "Reduced", children: "Reduced" })
|
|
11407
|
-
] })
|
|
11408
|
-
]
|
|
11409
|
-
}
|
|
11410
|
-
)
|
|
11411
|
-
] }),
|
|
11412
|
-
/* @__PURE__ */ jsxs("label", { className: "flex flex-col gap-1", children: [
|
|
11413
|
-
/* @__PURE__ */ jsx("span", { className: "font-medium", children: "Ejaculation" }),
|
|
11414
|
-
/* @__PURE__ */ jsxs(
|
|
11415
|
-
Select,
|
|
11416
|
-
{
|
|
11417
|
-
value: safe.sexual.ejaculation || "none",
|
|
11418
|
-
onValueChange: (val) => update({
|
|
11419
|
-
...safe,
|
|
11420
|
-
sexual: { ...safe.sexual, ejaculation: val === "none" ? "" : val }
|
|
11421
|
-
}),
|
|
11422
|
-
disabled,
|
|
11423
|
-
children: [
|
|
11424
|
-
/* @__PURE__ */ jsx(SelectTrigger, { className: "h-8 text-xs", children: /* @__PURE__ */ jsx(SelectValue, { placeholder: "\u2014" }) }),
|
|
11425
|
-
/* @__PURE__ */ jsxs(SelectContent, { children: [
|
|
11426
|
-
/* @__PURE__ */ jsx(SelectItem, { value: "none", children: "\u2014" }),
|
|
11427
|
-
/* @__PURE__ */ jsx(SelectItem, { value: "Normal", children: "Normal" }),
|
|
11428
|
-
/* @__PURE__ */ jsx(SelectItem, { value: "Premature", children: "Premature" }),
|
|
11429
|
-
/* @__PURE__ */ jsx(SelectItem, { value: "Retrograde", children: "Retrograde" }),
|
|
11430
|
-
/* @__PURE__ */ jsx(SelectItem, { value: "Anejaculation", children: "Anejaculation" })
|
|
11431
|
-
] })
|
|
11432
|
-
]
|
|
11433
|
-
}
|
|
11434
|
-
)
|
|
11435
|
-
] }),
|
|
11436
|
-
/* @__PURE__ */ jsxs("label", { className: "flex flex-col gap-1", children: [
|
|
11437
|
-
/* @__PURE__ */ jsx("span", { className: "font-medium", children: "Infertility (months)" }),
|
|
11438
|
-
/* @__PURE__ */ jsx(
|
|
11439
|
-
Input,
|
|
11440
|
-
{
|
|
11441
|
-
type: "number",
|
|
11442
|
-
min: 0,
|
|
11443
|
-
className: "h-8 text-xs",
|
|
11444
|
-
value: safe.sexual.infertilityMonths,
|
|
11445
|
-
onChange: (e) => update({
|
|
11446
|
-
...safe,
|
|
11447
|
-
sexual: {
|
|
11448
|
-
...safe.sexual,
|
|
11449
|
-
infertilityMonths: Math.max(0, Math.round(Number(e.target.value)) || 0)
|
|
11450
|
-
}
|
|
11451
|
-
}),
|
|
11452
|
-
disabled
|
|
11453
|
-
}
|
|
11454
|
-
)
|
|
11455
|
-
] })
|
|
11456
|
-
] }) }) : null,
|
|
11457
|
-
/* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
|
|
11458
|
-
/* @__PURE__ */ jsx(Label, { className: "text-xs font-medium text-slate-700", children: "Past history (stones / surgeries / drugs)" }),
|
|
11459
|
-
/* @__PURE__ */ jsx(
|
|
11460
|
-
Textarea,
|
|
11461
|
-
{
|
|
11462
|
-
className: "min-h-[72px] rounded-md border border-input bg-white text-sm",
|
|
11463
|
-
placeholder: "Prior calculi, urological surgeries, anticoagulants, DM/HTN\u2026",
|
|
11464
|
-
value: safe.pastNotes,
|
|
11465
|
-
onChange: (e) => update({ ...safe, pastNotes: e.target.value }),
|
|
11466
|
-
disabled
|
|
11467
|
-
}
|
|
11468
|
-
)
|
|
11469
|
-
] })
|
|
11470
|
-
] }),
|
|
11471
|
-
showError ? /* @__PURE__ */ jsx("p", { className: "px-3 pb-2 text-xs text-red-500", children: error }) : null
|
|
11472
|
-
] });
|
|
11473
|
-
};
|
|
11474
|
-
var GENERAL_ROWS = [
|
|
11475
|
-
{ key: "pallor", label: "Pallor (chronic dz)" },
|
|
11476
|
-
{ key: "oedema", label: "Oedema (renal)" },
|
|
11477
|
-
{ key: "icterus", label: "Icterus" },
|
|
11478
|
-
{ key: "lymphadenopathy", label: "Lymphadenopathy" }
|
|
11479
|
-
];
|
|
11480
|
-
var ABD_ROWS = [
|
|
11481
|
-
{ key: "distension", label: "Distension" },
|
|
11482
|
-
{ key: "scars", label: "Surgical scars" },
|
|
11483
|
-
{ key: "mass", label: "Visible mass" },
|
|
11484
|
-
{ key: "kidneyPalpable", label: "Kidney palpable" },
|
|
11485
|
-
{ key: "bladderPalpable", label: "Bladder palpable" },
|
|
11486
|
-
{ key: "renalAngleTender", label: "Renal angle tender" },
|
|
11487
|
-
{ key: "bladderDull", label: "Bladder dullness (retention)" }
|
|
11488
|
-
];
|
|
11489
|
-
var GU_ROWS = [
|
|
11490
|
-
{ key: "meatusAbnormal", label: "Meatus abnormal (hypospadias?)" },
|
|
11491
|
-
{ key: "phimosis", label: "Phimosis / paraphimosis" },
|
|
11492
|
-
{ key: "lesions", label: "Penile lesions / ulcers" },
|
|
11493
|
-
{ key: "scrotalSwelling", label: "Scrotal swelling" },
|
|
11494
|
-
{ key: "transilluminant", label: "Transilluminant" },
|
|
11495
|
-
{ key: "tenderTestis", label: "Tender testis" },
|
|
11496
|
-
{ key: "hydrocele", label: "Hydrocele" },
|
|
11497
|
-
{ key: "varicocele", label: "Varicocele" },
|
|
11498
|
-
{ key: "suspiciousMass", label: "Suspicious mass" }
|
|
11499
|
-
];
|
|
11500
|
-
var DRE_CONSISTENCY = ["none", "Soft (benign)", "Firm", "Hard / nodular (malignancy?)"];
|
|
11501
|
-
var DRE_SULCUS = ["none", "Preserved", "Obliterated"];
|
|
11502
|
-
var UrologyExaminationWidget = ({ fieldId }) => {
|
|
11503
|
-
const { fieldDef, value, setValue, setTouched, error, touched, disabled } = useField(fieldId);
|
|
11504
|
-
const { state } = useForm();
|
|
11505
|
-
const showError = !!error && (touched || state.submitAttempted);
|
|
11506
|
-
const safe = useMemo(() => normalizeUrologyExamination(value), [value]);
|
|
11507
|
-
const update = (next) => {
|
|
11508
|
-
setValue(next);
|
|
11509
|
-
setTouched();
|
|
11510
|
-
};
|
|
11511
|
-
const toggleGeneral = (key) => {
|
|
11512
|
-
update({ ...safe, general: { ...safe.general, [key]: !safe.general[key] } });
|
|
11513
|
-
};
|
|
11514
|
-
const toggleAbdomen = (key) => {
|
|
11515
|
-
update({ ...safe, abdomen: { ...safe.abdomen, [key]: !safe.abdomen[key] } });
|
|
11516
|
-
};
|
|
11517
|
-
const toggleGu = (key) => {
|
|
11518
|
-
update({ ...safe, gu: { ...safe.gu, [key]: !safe.gu[key] } });
|
|
11519
|
-
};
|
|
11520
|
-
if (!fieldDef) return null;
|
|
11521
|
-
const theme = getThemeConfig("textarea", fieldDef.theme);
|
|
11522
|
-
const wrapperClass = theme?.wrapperClassName ?? "rounded-md overflow-hidden flex flex-col border border-[#D0D0D0]";
|
|
11523
|
-
const labelClass = theme?.labelClassName;
|
|
11524
|
-
const labelContent = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
11525
|
-
fieldDef.label,
|
|
11526
|
-
fieldDef.required ? /* @__PURE__ */ jsx("span", { className: "ml-1 text-red-500", children: "*" }) : null
|
|
11527
|
-
] });
|
|
11528
|
-
const labelEl = theme ? /* @__PURE__ */ jsx(Label, { className: labelClass, children: labelContent }) : /* @__PURE__ */ jsx(Label, { className: "text-sm font-medium", children: labelContent });
|
|
11529
|
-
const bodyClass = cn(
|
|
11530
|
-
"-mt-1 flex min-w-0 flex-col gap-3 border-t border-[#D0D0D0] bg-white px-3 py-3",
|
|
11531
|
-
disabled && "pointer-events-none opacity-60"
|
|
11532
|
-
);
|
|
11533
|
-
return /* @__PURE__ */ jsxs("div", { className: cn("w-full min-w-0", wrapperClass), children: [
|
|
11534
|
-
labelEl,
|
|
11535
|
-
/* @__PURE__ */ jsxs("div", { className: bodyClass, children: [
|
|
11536
|
-
/* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 gap-3 text-xs md:grid-cols-2 xl:grid-cols-4", children: [
|
|
11537
|
-
/* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
11538
|
-
/* @__PURE__ */ jsx("p", { className: "font-semibold text-slate-800", children: "General" }),
|
|
11539
|
-
GENERAL_ROWS.map((r) => /* @__PURE__ */ jsxs("label", { className: "flex items-center gap-2", children: [
|
|
11540
|
-
/* @__PURE__ */ jsx(
|
|
11541
|
-
Checkbox,
|
|
11542
|
-
{
|
|
11543
|
-
checked: safe.general[r.key],
|
|
11544
|
-
onCheckedChange: () => toggleGeneral(r.key),
|
|
11545
|
-
disabled
|
|
11546
|
-
}
|
|
11547
|
-
),
|
|
11548
|
-
r.label
|
|
11549
|
-
] }, r.key))
|
|
11550
|
-
] }),
|
|
11551
|
-
/* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
11552
|
-
/* @__PURE__ */ jsx("p", { className: "font-semibold text-slate-800", children: "Abdomen" }),
|
|
11553
|
-
ABD_ROWS.map((r) => /* @__PURE__ */ jsxs("label", { className: "flex items-center gap-2", children: [
|
|
11554
|
-
/* @__PURE__ */ jsx(
|
|
11555
|
-
Checkbox,
|
|
11556
|
-
{
|
|
11557
|
-
checked: safe.abdomen[r.key],
|
|
11558
|
-
onCheckedChange: () => toggleAbdomen(r.key),
|
|
11559
|
-
disabled
|
|
11560
|
-
}
|
|
11561
|
-
),
|
|
11562
|
-
r.label
|
|
11563
|
-
] }, r.key))
|
|
11564
|
-
] }),
|
|
11565
|
-
/* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
11566
|
-
/* @__PURE__ */ jsx("p", { className: "font-semibold text-slate-800", children: "External genitalia / scrotum" }),
|
|
11567
|
-
GU_ROWS.map((r) => /* @__PURE__ */ jsxs("label", { className: "flex items-center gap-2", children: [
|
|
11568
|
-
/* @__PURE__ */ jsx(
|
|
11569
|
-
Checkbox,
|
|
11570
|
-
{
|
|
11571
|
-
checked: safe.gu[r.key],
|
|
11572
|
-
onCheckedChange: () => toggleGu(r.key),
|
|
11573
|
-
disabled
|
|
11574
|
-
}
|
|
11575
|
-
),
|
|
11576
|
-
r.key === "suspiciousMass" ? /* @__PURE__ */ jsx("span", { className: "font-medium text-red-600", children: r.label }) : r.label
|
|
11577
|
-
] }, r.key))
|
|
11578
|
-
] }),
|
|
11579
|
-
/* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
11580
|
-
/* @__PURE__ */ jsx("p", { className: "font-semibold text-slate-800", children: "DRE \u2014 Prostate" }),
|
|
11581
|
-
/* @__PURE__ */ jsxs("label", { className: "flex items-center gap-2", children: [
|
|
11582
|
-
/* @__PURE__ */ jsx(
|
|
11583
|
-
Checkbox,
|
|
11584
|
-
{
|
|
11585
|
-
checked: safe.dre.done,
|
|
11586
|
-
onCheckedChange: (c) => update({ ...safe, dre: { ...safe.dre, done: c === true } }),
|
|
11587
|
-
disabled
|
|
11588
|
-
}
|
|
11589
|
-
),
|
|
11590
|
-
"DRE performed"
|
|
11591
|
-
] }),
|
|
11592
|
-
/* @__PURE__ */ jsxs("label", { className: "block", children: [
|
|
11593
|
-
/* @__PURE__ */ jsx("span", { className: "mb-1 block font-medium", children: "Estimated size (g)" }),
|
|
11594
|
-
/* @__PURE__ */ jsx(
|
|
11595
|
-
Input,
|
|
11596
|
-
{
|
|
11597
|
-
type: "number",
|
|
11598
|
-
min: 0,
|
|
11599
|
-
className: "h-8 text-xs",
|
|
11600
|
-
value: safe.dre.sizeGrams,
|
|
11601
|
-
onChange: (e) => {
|
|
11602
|
-
const n = Number(e.target.value);
|
|
11603
|
-
update({
|
|
11604
|
-
...safe,
|
|
11605
|
-
dre: {
|
|
11606
|
-
...safe.dre,
|
|
11607
|
-
sizeGrams: Number.isFinite(n) && n >= 0 ? Math.round(n) : 0
|
|
11608
|
-
}
|
|
11609
|
-
});
|
|
11610
|
-
},
|
|
11611
|
-
disabled
|
|
11612
|
-
}
|
|
11613
|
-
)
|
|
11614
|
-
] }),
|
|
11615
|
-
/* @__PURE__ */ jsxs("label", { className: "block", children: [
|
|
11616
|
-
/* @__PURE__ */ jsx("span", { className: "mb-1 block font-medium", children: "Consistency" }),
|
|
11617
|
-
/* @__PURE__ */ jsxs(
|
|
11618
|
-
Select,
|
|
11619
|
-
{
|
|
11620
|
-
value: safe.dre.consistency || "none",
|
|
11621
|
-
onValueChange: (val) => update({
|
|
11622
|
-
...safe,
|
|
11623
|
-
dre: { ...safe.dre, consistency: val === "none" ? "" : val }
|
|
11624
|
-
}),
|
|
11625
|
-
disabled,
|
|
11626
|
-
children: [
|
|
11627
|
-
/* @__PURE__ */ jsx(SelectTrigger, { className: "h-8 text-xs", children: /* @__PURE__ */ jsx(SelectValue, { placeholder: "\u2014" }) }),
|
|
11628
|
-
/* @__PURE__ */ jsx(SelectContent, { children: DRE_CONSISTENCY.map((opt) => /* @__PURE__ */ jsx(SelectItem, { value: opt, children: opt === "none" ? "\u2014" : opt }, opt)) })
|
|
11629
|
-
]
|
|
11630
|
-
}
|
|
11631
|
-
)
|
|
11632
|
-
] }),
|
|
11633
|
-
/* @__PURE__ */ jsxs("label", { className: "block", children: [
|
|
11634
|
-
/* @__PURE__ */ jsx("span", { className: "mb-1 block font-medium", children: "Median sulcus" }),
|
|
11635
|
-
/* @__PURE__ */ jsxs(
|
|
11636
|
-
Select,
|
|
11637
|
-
{
|
|
11638
|
-
value: safe.dre.medianSulcus || "none",
|
|
11639
|
-
onValueChange: (val) => update({
|
|
11640
|
-
...safe,
|
|
11641
|
-
dre: { ...safe.dre, medianSulcus: val === "none" ? "" : val }
|
|
11642
|
-
}),
|
|
11643
|
-
disabled,
|
|
11644
|
-
children: [
|
|
11645
|
-
/* @__PURE__ */ jsx(SelectTrigger, { className: "h-8 text-xs", children: /* @__PURE__ */ jsx(SelectValue, { placeholder: "\u2014" }) }),
|
|
11646
|
-
/* @__PURE__ */ jsx(SelectContent, { children: DRE_SULCUS.map((opt) => /* @__PURE__ */ jsx(SelectItem, { value: opt, children: opt === "none" ? "\u2014" : opt }, opt)) })
|
|
11647
|
-
]
|
|
11648
|
-
}
|
|
11649
|
-
)
|
|
11650
|
-
] }),
|
|
11651
|
-
/* @__PURE__ */ jsxs("label", { className: "flex items-center gap-2", children: [
|
|
11652
|
-
/* @__PURE__ */ jsx(
|
|
11653
|
-
Checkbox,
|
|
11654
|
-
{
|
|
11655
|
-
checked: safe.dre.tenderness,
|
|
11656
|
-
onCheckedChange: (c) => update({ ...safe, dre: { ...safe.dre, tenderness: c === true } }),
|
|
11657
|
-
disabled
|
|
11658
|
-
}
|
|
11659
|
-
),
|
|
11660
|
-
"Tender (prostatitis?)"
|
|
11661
|
-
] })
|
|
11662
|
-
] })
|
|
11663
|
-
] }),
|
|
11664
|
-
/* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
|
|
11665
|
-
/* @__PURE__ */ jsx(Label, { className: "text-xs font-semibold text-slate-700", children: "Examination notes" }),
|
|
11666
|
-
/* @__PURE__ */ jsx(
|
|
11667
|
-
Textarea,
|
|
11668
|
-
{
|
|
11669
|
-
className: "min-h-[88px] rounded-md border border-input bg-white text-sm",
|
|
11670
|
-
placeholder: "Free-text exam findings\u2026",
|
|
11671
|
-
value: safe.examinationNotes,
|
|
11672
|
-
onChange: (e) => update({ ...safe, examinationNotes: e.target.value }),
|
|
11673
|
-
disabled
|
|
11674
|
-
}
|
|
11675
|
-
)
|
|
11676
|
-
] })
|
|
11677
|
-
] }),
|
|
11678
|
-
showError ? /* @__PURE__ */ jsx("p", { className: "px-3 pb-2 text-xs text-red-500", children: error }) : null
|
|
11679
|
-
] });
|
|
11680
|
-
};
|
|
11681
|
-
var SMART_HISTORY_FIELD = "uro_smart_history";
|
|
11682
|
-
var EXAMINATION_FIELD = "uro_examination";
|
|
11683
|
-
var DRE_HARD = "Hard / nodular (malignancy?)";
|
|
11684
|
-
function Panel3({
|
|
11685
|
-
title,
|
|
11686
|
-
className,
|
|
11687
|
-
children
|
|
11688
|
-
}) {
|
|
11689
|
-
return /* @__PURE__ */ jsxs("div", { className: cn("overflow-hidden rounded-md border border-[#D0D0D0] bg-white", className), children: [
|
|
11690
|
-
/* @__PURE__ */ jsx("div", { className: "border-b border-[#D0D0D0] bg-[#FEE8EC]/50 px-3 py-1.5", children: /* @__PURE__ */ jsx("span", { className: "text-xs font-semibold text-slate-700", children: title }) }),
|
|
11691
|
-
/* @__PURE__ */ jsx("div", { className: "p-3", children })
|
|
11692
|
-
] });
|
|
11693
|
-
}
|
|
11694
|
-
var UrologyPathwayWidget = ({ fieldId }) => {
|
|
11695
|
-
const { fieldDef, value, setValue, setTouched, error, touched, disabled } = useField(fieldId);
|
|
11696
|
-
const { state } = useForm();
|
|
11697
|
-
const showError = !!error && (touched || state.submitAttempted);
|
|
11698
|
-
const safe = useMemo(() => normalizeUrologyPathway(value), [value]);
|
|
11699
|
-
const smart = useMemo(
|
|
11700
|
-
() => normalizeUrologySmartHistory(state.values[SMART_HISTORY_FIELD]),
|
|
11701
|
-
[state.values]
|
|
11702
|
-
);
|
|
11703
|
-
const exam = useMemo(
|
|
11704
|
-
() => normalizeUrologyExamination(state.values[EXAMINATION_FIELD]),
|
|
11705
|
-
[state.values]
|
|
11706
|
-
);
|
|
11707
|
-
const ipssTotal = urologyIpssSevenTotal(smart.ipss);
|
|
11708
|
-
const ipssBandCls = ipssTotal >= 20 ? "bg-red-500/15 text-red-700" : ipssTotal >= 8 ? "bg-amber-500/15 text-amber-900" : "bg-emerald-500/15 text-emerald-800";
|
|
11709
|
-
const stone = useMemo(
|
|
11710
|
-
() => urologyStoneRecommendation(safe.stoneSizeMm, safe.hydronephrosis),
|
|
11711
|
-
[safe.stoneSizeMm, safe.hydronephrosis]
|
|
11712
|
-
);
|
|
11713
|
-
const prostateLine = useMemo(
|
|
11714
|
-
() => urologyProstateProcedure(safe.prostateVolumeCc),
|
|
11715
|
-
[safe.prostateVolumeCc]
|
|
11716
|
-
);
|
|
11717
|
-
const psaHigh = safe.psaNgMl > 4;
|
|
11718
|
-
const qmaxLow = safe.uroflowQmaxMlSec > 0 && Number.isFinite(safe.uroflowQmaxMlSec) && safe.uroflowQmaxMlSec < 10;
|
|
11719
|
-
const update = (next) => {
|
|
11720
|
-
setValue(next);
|
|
11721
|
-
setTouched();
|
|
11722
|
-
};
|
|
11723
|
-
const setRisk = (key, next) => {
|
|
11724
|
-
update({ ...safe, risk: { ...safe.risk, [key]: next } });
|
|
11725
|
-
};
|
|
11726
|
-
if (!fieldDef) return null;
|
|
11727
|
-
const theme = getThemeConfig("textarea", fieldDef.theme);
|
|
11728
|
-
const wrapperClass = theme?.wrapperClassName ?? "rounded-md overflow-hidden flex flex-col border border-[#D0D0D0]";
|
|
11729
|
-
const labelClass = theme?.labelClassName;
|
|
11730
|
-
const labelContent = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
11731
|
-
fieldDef.label,
|
|
11732
|
-
fieldDef.required ? /* @__PURE__ */ jsx("span", { className: "ml-1 text-red-500", children: "*" }) : null
|
|
11733
|
-
] });
|
|
11734
|
-
const labelEl = theme ? /* @__PURE__ */ jsx(Label, { className: labelClass, children: labelContent }) : /* @__PURE__ */ jsx(Label, { className: "text-sm font-medium", children: labelContent });
|
|
11735
|
-
const bodyClass = cn(
|
|
11736
|
-
"-mt-1 flex min-w-0 flex-col gap-3 border-t border-[#D0D0D0] bg-white px-3 py-3",
|
|
11737
|
-
disabled && "pointer-events-none opacity-60"
|
|
11738
|
-
);
|
|
11739
|
-
const subtitle = typeof fieldDef.meta?.subtitle === "string" && fieldDef.meta.subtitle.trim().length > 0 ? fieldDef.meta.subtitle.trim() : "";
|
|
11740
|
-
return /* @__PURE__ */ jsxs("div", { className: cn("w-full min-w-0", wrapperClass), children: [
|
|
11741
|
-
labelEl,
|
|
11742
|
-
/* @__PURE__ */ jsxs("div", { className: bodyClass, children: [
|
|
11743
|
-
subtitle ? /* @__PURE__ */ jsx("p", { className: "-mt-0.5 mb-0 text-xs font-semibold tracking-wide text-slate-700", children: subtitle }) : null,
|
|
11744
|
-
/* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 gap-3 text-xs md:grid-cols-2 xl:grid-cols-4", children: [
|
|
11745
|
-
/* @__PURE__ */ jsxs(Panel3, { title: "Stone disease", children: [
|
|
11746
|
-
/* @__PURE__ */ jsxs("label", { className: "block", children: [
|
|
11747
|
-
/* @__PURE__ */ jsx("span", { className: "mb-1 block font-medium text-slate-700", children: "Stone size (mm)" }),
|
|
11748
|
-
/* @__PURE__ */ jsx(
|
|
11749
|
-
Input,
|
|
11750
|
-
{
|
|
11751
|
-
type: "number",
|
|
11752
|
-
min: 0,
|
|
11753
|
-
step: "any",
|
|
11754
|
-
className: cn(
|
|
11755
|
-
"h-8 text-xs",
|
|
11756
|
-
disabled && "pointer-events-none"
|
|
11757
|
-
),
|
|
11758
|
-
value: safe.stoneSizeMm,
|
|
11759
|
-
onChange: (e) => {
|
|
11760
|
-
const raw = e.target.value;
|
|
11761
|
-
const n = Number(raw);
|
|
11762
|
-
update({
|
|
11763
|
-
...safe,
|
|
11764
|
-
stoneSizeMm: raw === "" || raw === "-" ? 0 : !Number.isFinite(n) ? 0 : Math.max(0, n)
|
|
11765
|
-
});
|
|
11766
|
-
},
|
|
11767
|
-
disabled
|
|
11768
|
-
}
|
|
11769
|
-
)
|
|
11770
|
-
] }),
|
|
11771
|
-
/* @__PURE__ */ jsxs("label", { className: "mt-2 flex items-center gap-2", children: [
|
|
11772
|
-
/* @__PURE__ */ jsx(
|
|
11773
|
-
Checkbox,
|
|
11774
|
-
{
|
|
11775
|
-
checked: safe.hydronephrosis,
|
|
11776
|
-
disabled,
|
|
11777
|
-
onCheckedChange: (checked) => update({ ...safe, hydronephrosis: checked === true })
|
|
11778
|
-
}
|
|
11779
|
-
),
|
|
11780
|
-
/* @__PURE__ */ jsx("span", { className: "text-slate-700", children: "Hydronephrosis on imaging" })
|
|
11781
|
-
] }),
|
|
11782
|
-
/* @__PURE__ */ jsx(
|
|
11783
|
-
"div",
|
|
11784
|
-
{
|
|
11785
|
-
className: cn(
|
|
11786
|
-
"mt-2 rounded p-2 text-[11px]",
|
|
11787
|
-
stone.surgical && safe.stoneSizeMm > 0 ? "bg-red-500/10 text-red-800" : safe.stoneSizeMm > 0 ? "bg-emerald-500/10 text-emerald-900" : "bg-muted/40 text-muted-foreground"
|
|
11788
|
-
),
|
|
11789
|
-
children: stone.plan
|
|
11790
|
-
}
|
|
11791
|
-
),
|
|
11792
|
-
/* @__PURE__ */ jsx("p", { className: "mt-1 text-[10px] text-muted-foreground", children: "Trigger: >10 mm OR obstruction \u2192 surgical." })
|
|
11793
|
-
] }),
|
|
11794
|
-
/* @__PURE__ */ jsxs(Panel3, { title: "Prostate / BPH", children: [
|
|
11795
|
-
/* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-2", children: [
|
|
11796
|
-
/* @__PURE__ */ jsxs("label", { className: "block", children: [
|
|
11797
|
-
/* @__PURE__ */ jsx("span", { className: "mb-1 block font-medium text-slate-700", children: "Volume (cc)" }),
|
|
11798
|
-
/* @__PURE__ */ jsx(
|
|
11799
|
-
Input,
|
|
11800
|
-
{
|
|
11801
|
-
type: "number",
|
|
11802
|
-
min: 0,
|
|
11803
|
-
step: "any",
|
|
11804
|
-
className: cn(
|
|
11805
|
-
"h-8 text-xs",
|
|
11806
|
-
disabled && "pointer-events-none"
|
|
11807
|
-
),
|
|
11808
|
-
value: safe.prostateVolumeCc,
|
|
11809
|
-
onChange: (e) => {
|
|
11810
|
-
const raw = e.target.value;
|
|
11811
|
-
const n = Number(raw);
|
|
11812
|
-
update({
|
|
11813
|
-
...safe,
|
|
11814
|
-
prostateVolumeCc: raw === "" || raw === "-" ? 0 : !Number.isFinite(n) ? 0 : Math.max(0, n)
|
|
11815
|
-
});
|
|
11816
|
-
},
|
|
11817
|
-
disabled
|
|
11818
|
-
}
|
|
11819
|
-
)
|
|
11820
|
-
] }),
|
|
11821
|
-
/* @__PURE__ */ jsxs("label", { className: "block", children: [
|
|
11822
|
-
/* @__PURE__ */ jsx("span", { className: "mb-1 block font-medium text-slate-700", children: "PSA (ng/ml)" }),
|
|
11823
|
-
/* @__PURE__ */ jsx(
|
|
11824
|
-
Input,
|
|
11825
|
-
{
|
|
11826
|
-
type: "number",
|
|
11827
|
-
min: 0,
|
|
11828
|
-
step: 0.1,
|
|
11829
|
-
className: cn(
|
|
11830
|
-
"h-8 text-xs",
|
|
11831
|
-
psaHigh && "border-red-400 text-red-800",
|
|
11832
|
-
disabled && "pointer-events-none"
|
|
11833
|
-
),
|
|
11834
|
-
value: safe.psaNgMl,
|
|
11835
|
-
onChange: (e) => {
|
|
11836
|
-
const raw = e.target.value;
|
|
11837
|
-
const n = Number(raw);
|
|
11838
|
-
update({
|
|
11839
|
-
...safe,
|
|
11840
|
-
psaNgMl: raw === "" || raw === "-" ? 0 : !Number.isFinite(n) ? 0 : Math.max(0, n)
|
|
11841
|
-
});
|
|
11842
|
-
},
|
|
11843
|
-
disabled
|
|
11844
|
-
}
|
|
11845
|
-
)
|
|
11846
|
-
] }),
|
|
11847
|
-
/* @__PURE__ */ jsxs("label", { className: "col-span-2 block", children: [
|
|
11848
|
-
/* @__PURE__ */ jsx("span", { className: "mb-1 block font-medium text-slate-700", children: "Uroflow Qmax (ml/s)" }),
|
|
11849
|
-
/* @__PURE__ */ jsx(
|
|
11850
|
-
Input,
|
|
11851
|
-
{
|
|
11852
|
-
type: "number",
|
|
11853
|
-
min: 0,
|
|
11854
|
-
step: 0.1,
|
|
11855
|
-
className: cn(
|
|
11856
|
-
"h-8 text-xs",
|
|
11857
|
-
qmaxLow && "border-amber-500 text-amber-900",
|
|
11858
|
-
disabled && "pointer-events-none"
|
|
11859
|
-
),
|
|
11860
|
-
value: safe.uroflowQmaxMlSec,
|
|
11861
|
-
onChange: (e) => {
|
|
11862
|
-
const raw = e.target.value;
|
|
11863
|
-
const n = Number(raw);
|
|
11864
|
-
update({
|
|
11865
|
-
...safe,
|
|
11866
|
-
uroflowQmaxMlSec: raw === "" || raw === "-" ? 0 : !Number.isFinite(n) ? 0 : Math.max(0, n)
|
|
11867
|
-
});
|
|
11868
|
-
},
|
|
11869
|
-
disabled
|
|
11870
|
-
}
|
|
11871
|
-
)
|
|
11872
|
-
] })
|
|
11873
|
-
] }),
|
|
11874
|
-
/* @__PURE__ */ jsx(
|
|
11875
|
-
"div",
|
|
11876
|
-
{
|
|
11877
|
-
className: cn(
|
|
11878
|
-
"mt-2 rounded p-2 text-[11px]",
|
|
11879
|
-
safe.prostateVolumeCc > 30 ? "bg-amber-500/10 text-amber-900" : safe.prostateVolumeCc > 0 ? "bg-emerald-500/10 text-emerald-900" : "bg-muted/40 text-muted-foreground"
|
|
11880
|
-
),
|
|
11881
|
-
children: prostateLine
|
|
11882
|
-
}
|
|
11883
|
-
),
|
|
11884
|
-
/* @__PURE__ */ jsx("p", { className: "mt-1 text-[10px] text-muted-foreground", children: "<30 cc medical \xB7 30\u201380 cc TURP \xB7 >80 cc HoLEP/Open" })
|
|
11885
|
-
] }),
|
|
11886
|
-
/* @__PURE__ */ jsxs(Panel3, { title: "IPSS & cues", children: [
|
|
11887
|
-
/* @__PURE__ */ jsxs("div", { className: "mb-2 flex items-center justify-between", children: [
|
|
11888
|
-
/* @__PURE__ */ jsx("span", { className: "text-slate-700", children: "IPSS total" }),
|
|
11889
|
-
/* @__PURE__ */ jsxs("span", { className: `rounded-full px-2 py-0.5 text-[11px] font-semibold ${ipssBandCls}`, children: [
|
|
11890
|
-
ipssTotal,
|
|
11891
|
-
"/35 \xB7 ",
|
|
11892
|
-
urologyIpssBand(ipssTotal)
|
|
11893
|
-
] })
|
|
11894
|
-
] }),
|
|
11895
|
-
/* @__PURE__ */ jsx("div", { className: "mb-3 h-1.5 overflow-hidden rounded-full bg-slate-200", children: /* @__PURE__ */ jsx(
|
|
11896
|
-
"div",
|
|
11897
|
-
{
|
|
11898
|
-
className: cn(
|
|
11899
|
-
"h-full transition-[width]",
|
|
11900
|
-
ipssTotal >= 20 ? "bg-red-500" : ipssTotal >= 8 ? "bg-amber-500" : "bg-emerald-500"
|
|
11901
|
-
),
|
|
11902
|
-
style: { width: `${Math.min(100, ipssTotal / 35 * 100)}%` }
|
|
11903
|
-
}
|
|
11904
|
-
) }),
|
|
11905
|
-
/* @__PURE__ */ jsxs("p", { className: "mb-3 text-[10px] text-muted-foreground", children: [
|
|
11906
|
-
"From smart history (",
|
|
11907
|
-
/* @__PURE__ */ jsx("span", { className: "font-mono text-foreground", children: SMART_HISTORY_FIELD }),
|
|
11908
|
-
"). \u226520 \u2192 consider surgical intervention."
|
|
11909
|
-
] }),
|
|
11910
|
-
/* @__PURE__ */ jsxs("div", { className: "space-y-1.5 text-[11px]", children: [
|
|
11911
|
-
smart.haematuria.present && !smart.haematuria.painful ? /* @__PURE__ */ jsx("div", { className: "rounded bg-red-500/10 p-1.5 text-red-800", children: "Painless haematuria \u2014 mandatory cystoscopy" }) : null,
|
|
11912
|
-
psaHigh ? /* @__PURE__ */ jsx("div", { className: "rounded bg-amber-500/10 p-1.5 text-amber-900", children: "PSA >4 \u2014 workup for Ca prostate" }) : null,
|
|
11913
|
-
exam.dre.consistency === DRE_HARD ? /* @__PURE__ */ jsxs("div", { className: "rounded bg-red-500/10 p-1.5 text-red-800", children: [
|
|
11914
|
-
"Hard / nodular prostate (",
|
|
11915
|
-
/* @__PURE__ */ jsx("span", { className: "font-mono", children: EXAMINATION_FIELD }),
|
|
11916
|
-
") \u2014 biopsy pathway"
|
|
11917
|
-
] }) : null,
|
|
11918
|
-
exam.gu.suspiciousMass ? /* @__PURE__ */ jsx("div", { className: "rounded bg-red-500/10 p-1.5 text-red-800", children: "Suspicious scrotal mass \u2014 urgent surgical eval" }) : null
|
|
11919
|
-
] })
|
|
11920
|
-
] }),
|
|
11921
|
-
/* @__PURE__ */ jsx(Panel3, { title: "Risk stratification", children: /* @__PURE__ */ jsx("div", { className: "space-y-2", children: [
|
|
11922
|
-
["ckd", "CKD"],
|
|
11923
|
-
["diabetes", "Diabetes"],
|
|
11924
|
-
["anticoagulants", "Anticoagulants"],
|
|
11925
|
-
["activeInfection", "Active infection"]
|
|
11926
|
-
].map(([key, lab]) => /* @__PURE__ */ jsxs("label", { className: "flex items-center gap-2", children: [
|
|
11927
|
-
/* @__PURE__ */ jsx(
|
|
11928
|
-
Checkbox,
|
|
11929
|
-
{
|
|
11930
|
-
checked: safe.risk[key],
|
|
11931
|
-
disabled,
|
|
11932
|
-
onCheckedChange: (c) => setRisk(key, c === true)
|
|
11933
|
-
}
|
|
11934
|
-
),
|
|
11935
|
-
/* @__PURE__ */ jsx("span", { className: "text-slate-700", children: lab })
|
|
11936
|
-
] }, key)) }) })
|
|
11937
|
-
] })
|
|
11938
|
-
] }),
|
|
11939
|
-
showError ? /* @__PURE__ */ jsx("p", { className: "px-3 pb-2 text-xs text-red-500", children: error }) : null
|
|
11940
|
-
] });
|
|
11941
|
-
};
|
|
11942
|
-
var FieldRenderer = ({ fieldId }) => {
|
|
11943
|
-
const { fieldDef, visible } = useField(fieldId);
|
|
11944
|
-
if (!visible || !fieldDef) {
|
|
11945
|
-
return null;
|
|
11946
|
-
}
|
|
11947
|
-
return renderWidget(fieldId, fieldDef);
|
|
11948
|
-
};
|
|
11949
|
-
function renderWidget(fieldId, fieldDef) {
|
|
11950
|
-
switch (fieldDef.type) {
|
|
11951
|
-
case "text":
|
|
11952
|
-
case "number":
|
|
11953
|
-
return /* @__PURE__ */ jsx(TextWidget, { fieldId });
|
|
11954
|
-
case "slider":
|
|
11955
|
-
return /* @__PURE__ */ jsx(SliderWidget, { fieldId });
|
|
11956
|
-
case "textarea":
|
|
11957
|
-
if (fieldMetaRequestsMarMedicationOrdersButton(fieldDef.meta)) {
|
|
11958
|
-
return /* @__PURE__ */ jsx(MarMedicationOrdersWidget, { fieldId });
|
|
11959
|
-
}
|
|
11960
|
-
return /* @__PURE__ */ jsx(TextWidget, { fieldId });
|
|
11961
|
-
case "richtext":
|
|
11962
|
-
return /* @__PURE__ */ jsx(RichTextWidget, { fieldId });
|
|
11963
|
-
case "date":
|
|
11964
|
-
return /* @__PURE__ */ jsx(DateWidget, { fieldId });
|
|
11965
|
-
case "datetime":
|
|
11966
|
-
return /* @__PURE__ */ jsx(DateTimeWidget, { fieldId });
|
|
11967
|
-
case "select":
|
|
11968
|
-
return /* @__PURE__ */ jsx(SelectWidget, { fieldId });
|
|
11969
|
-
case "radio":
|
|
11970
|
-
return /* @__PURE__ */ jsx(RadioWidget, { fieldId });
|
|
11971
|
-
case "checkbox":
|
|
11972
|
-
return /* @__PURE__ */ jsx(CheckboxWidget, { fieldId });
|
|
11973
|
-
case "multiselect":
|
|
11974
|
-
return /* @__PURE__ */ jsx(MultiSelectWidget, { fieldId });
|
|
11975
|
-
case "repeatable":
|
|
11976
|
-
return /* @__PURE__ */ jsx(RepeatableWidget, { fieldId });
|
|
11977
|
-
case "image_upload":
|
|
11978
|
-
return /* @__PURE__ */ jsx(ImageUploadWidget, { fieldId });
|
|
11979
|
-
case "media_upload":
|
|
11980
|
-
return /* @__PURE__ */ jsx(MediaUploadWidget, { fieldId });
|
|
11981
|
-
case "signature":
|
|
11982
|
-
return /* @__PURE__ */ jsx(SignatureUploadWidget, { fieldId });
|
|
11983
|
-
case "editable_table":
|
|
11984
|
-
return /* @__PURE__ */ jsx(EditableTableWidget, { fieldId });
|
|
11985
|
-
case "medications":
|
|
11986
|
-
return /* @__PURE__ */ jsx(AddMedicationWidget, { fieldId });
|
|
11987
|
-
case "discharge_medication_orders":
|
|
11988
|
-
return /* @__PURE__ */ jsx(DischargeMedicationOrdersWidget, { fieldId });
|
|
11989
|
-
case "investigations":
|
|
11990
|
-
return /* @__PURE__ */ jsx(AddInvestigationWidget, { fieldId });
|
|
11991
|
-
case "procedures":
|
|
11992
|
-
return /* @__PURE__ */ jsx(AddProcedureWidget, { fieldId });
|
|
11993
|
-
case "differential_diagnosis":
|
|
11994
|
-
return /* @__PURE__ */ jsx(DifferentialDiagnosisWidget, { fieldId });
|
|
11995
|
-
case "vitals":
|
|
11996
|
-
return /* @__PURE__ */ jsx(VitalsWidget, { fieldId });
|
|
11997
|
-
case "hidden_vitals":
|
|
11998
|
-
return /* @__PURE__ */ jsx(HiddenVitalsWidget, { fieldId });
|
|
11999
|
-
case "referral":
|
|
12000
|
-
return /* @__PURE__ */ jsx(ReferralWidget, { fieldId });
|
|
12001
|
-
case "followup":
|
|
12002
|
-
return /* @__PURE__ */ jsx(FollowupWidget, { fieldId });
|
|
12003
|
-
case "smart_textarea":
|
|
12004
|
-
return /* @__PURE__ */ jsx(SmartTextareaWidget, { fieldId });
|
|
12005
|
-
case "diagnosis_textarea":
|
|
12006
|
-
return /* @__PURE__ */ jsx(DiagnosisTextareaWidget, { fieldId });
|
|
12007
|
-
case "obstetric_history":
|
|
12008
|
-
return /* @__PURE__ */ jsx(ObstetricHistoryWidget, { fieldId });
|
|
12009
|
-
case "eye_prescription":
|
|
12010
|
-
return /* @__PURE__ */ jsx(OphthalmologyWidget, { fieldId });
|
|
12011
|
-
case "ophthal_diagnosis":
|
|
12012
|
-
return /* @__PURE__ */ jsx(OphthalDiagnosisWidget, { fieldId });
|
|
12013
|
-
case "orthopedic_exam":
|
|
12014
|
-
return /* @__PURE__ */ jsx(OrthopedicExamWidget, { fieldId });
|
|
12015
|
-
case "general_surgery_smart_history":
|
|
12016
|
-
return /* @__PURE__ */ jsx(GsSmartHistoryWidget, { fieldId });
|
|
12017
|
-
case "general_surgery_examination":
|
|
12018
|
-
return /* @__PURE__ */ jsx(GsExaminationWidget, { fieldId });
|
|
12019
|
-
case "general_surgery_grading":
|
|
12020
|
-
return /* @__PURE__ */ jsx(GsGradingWidget, { fieldId });
|
|
12021
|
-
case "pain_scale_flags":
|
|
12022
|
-
return /* @__PURE__ */ jsx(PainScaleFlagsWidget, { fieldId });
|
|
12023
|
-
case "urology_smart_history":
|
|
12024
|
-
return /* @__PURE__ */ jsx(UrologySmartHistoryWidget, { fieldId });
|
|
12025
|
-
case "urology_examination":
|
|
12026
|
-
return /* @__PURE__ */ jsx(UrologyExaminationWidget, { fieldId });
|
|
12027
|
-
case "urology_pathway":
|
|
12028
|
-
return /* @__PURE__ */ jsx(UrologyPathwayWidget, { fieldId });
|
|
12029
|
-
case "toggle": {
|
|
12030
|
-
const { value, setValue, setTouched, disabled } = useField(fieldId);
|
|
12031
|
-
const store = useFormStore();
|
|
12032
|
-
const excludes = fieldDef.excludes ?? [];
|
|
12033
|
-
return /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
|
|
12034
|
-
/* @__PURE__ */ jsx(
|
|
12035
|
-
Switch,
|
|
12036
|
-
{
|
|
12037
|
-
checked: value === true,
|
|
12038
|
-
disabled,
|
|
12039
|
-
onCheckedChange: (checked) => {
|
|
12040
|
-
setValue(checked);
|
|
12041
|
-
setTouched();
|
|
12042
|
-
if (checked) excludes.forEach((id) => store.setValue(id, false));
|
|
12043
|
-
}
|
|
12044
|
-
}
|
|
12045
|
-
),
|
|
12046
|
-
/* @__PURE__ */ jsx(Label, { className: "text-sm font-medium leading-none cursor-pointer select-none", children: fieldDef.label })
|
|
12047
|
-
] });
|
|
10588
|
+
function renderWidget(fieldId, fieldDef) {
|
|
10589
|
+
switch (fieldDef.type) {
|
|
10590
|
+
case "text":
|
|
10591
|
+
case "number":
|
|
10592
|
+
return /* @__PURE__ */ jsx(TextWidget, { fieldId });
|
|
10593
|
+
case "slider":
|
|
10594
|
+
return /* @__PURE__ */ jsx(SliderWidget, { fieldId });
|
|
10595
|
+
case "textarea":
|
|
10596
|
+
if (fieldMetaRequestsMarMedicationOrdersButton(fieldDef.meta)) {
|
|
10597
|
+
return /* @__PURE__ */ jsx(MarMedicationOrdersWidget, { fieldId });
|
|
10598
|
+
}
|
|
10599
|
+
return /* @__PURE__ */ jsx(TextWidget, { fieldId });
|
|
10600
|
+
case "richtext":
|
|
10601
|
+
return /* @__PURE__ */ jsx(RichTextWidget, { fieldId });
|
|
10602
|
+
case "date":
|
|
10603
|
+
return /* @__PURE__ */ jsx(DateWidget, { fieldId });
|
|
10604
|
+
case "datetime":
|
|
10605
|
+
return /* @__PURE__ */ jsx(DateTimeWidget, { fieldId });
|
|
10606
|
+
case "select":
|
|
10607
|
+
return /* @__PURE__ */ jsx(SelectWidget, { fieldId });
|
|
10608
|
+
case "radio":
|
|
10609
|
+
return /* @__PURE__ */ jsx(RadioWidget, { fieldId });
|
|
10610
|
+
case "checkbox":
|
|
10611
|
+
return /* @__PURE__ */ jsx(CheckboxWidget, { fieldId });
|
|
10612
|
+
case "multiselect":
|
|
10613
|
+
return /* @__PURE__ */ jsx(MultiSelectWidget, { fieldId });
|
|
10614
|
+
case "repeatable":
|
|
10615
|
+
return /* @__PURE__ */ jsx(RepeatableWidget, { fieldId });
|
|
10616
|
+
case "image_upload":
|
|
10617
|
+
return /* @__PURE__ */ jsx(ImageUploadWidget, { fieldId });
|
|
10618
|
+
case "media_upload":
|
|
10619
|
+
return /* @__PURE__ */ jsx(MediaUploadWidget, { fieldId });
|
|
10620
|
+
case "signature":
|
|
10621
|
+
return /* @__PURE__ */ jsx(SignatureUploadWidget, { fieldId });
|
|
10622
|
+
case "editable_table":
|
|
10623
|
+
return /* @__PURE__ */ jsx(EditableTableWidget, { fieldId });
|
|
10624
|
+
case "medications":
|
|
10625
|
+
return /* @__PURE__ */ jsx(AddMedicationWidget, { fieldId });
|
|
10626
|
+
case "discharge_medication_orders":
|
|
10627
|
+
return /* @__PURE__ */ jsx(DischargeMedicationOrdersWidget, { fieldId });
|
|
10628
|
+
case "investigations":
|
|
10629
|
+
return /* @__PURE__ */ jsx(AddInvestigationWidget, { fieldId });
|
|
10630
|
+
case "procedures":
|
|
10631
|
+
return /* @__PURE__ */ jsx(AddProcedureWidget, { fieldId });
|
|
10632
|
+
case "differential_diagnosis":
|
|
10633
|
+
return /* @__PURE__ */ jsx(DifferentialDiagnosisWidget, { fieldId });
|
|
10634
|
+
case "vitals":
|
|
10635
|
+
return /* @__PURE__ */ jsx(VitalsWidget, { fieldId });
|
|
10636
|
+
case "hidden_vitals":
|
|
10637
|
+
return /* @__PURE__ */ jsx(HiddenVitalsWidget, { fieldId });
|
|
10638
|
+
case "referral":
|
|
10639
|
+
return /* @__PURE__ */ jsx(ReferralWidget, { fieldId });
|
|
10640
|
+
case "followup":
|
|
10641
|
+
return /* @__PURE__ */ jsx(FollowupWidget, { fieldId });
|
|
10642
|
+
case "smart_textarea":
|
|
10643
|
+
return /* @__PURE__ */ jsx(SmartTextareaWidget, { fieldId });
|
|
10644
|
+
case "diagnosis_textarea":
|
|
10645
|
+
return /* @__PURE__ */ jsx(DiagnosisTextareaWidget, { fieldId });
|
|
10646
|
+
case "obstetric_history":
|
|
10647
|
+
return /* @__PURE__ */ jsx(ObstetricHistoryWidget, { fieldId });
|
|
10648
|
+
case "eye_prescription":
|
|
10649
|
+
return /* @__PURE__ */ jsx(OphthalmologyWidget, { fieldId });
|
|
10650
|
+
case "ophthal_diagnosis":
|
|
10651
|
+
return /* @__PURE__ */ jsx(OphthalDiagnosisWidget, { fieldId });
|
|
10652
|
+
case "orthopedic_exam":
|
|
10653
|
+
return /* @__PURE__ */ jsx(OrthopedicExamWidget, { fieldId });
|
|
10654
|
+
case "general_surgery_smart_history":
|
|
10655
|
+
return /* @__PURE__ */ jsx(GsSmartHistoryWidget, { fieldId });
|
|
10656
|
+
case "general_surgery_examination":
|
|
10657
|
+
return /* @__PURE__ */ jsx(GsExaminationWidget, { fieldId });
|
|
10658
|
+
case "general_surgery_grading":
|
|
10659
|
+
return /* @__PURE__ */ jsx(GsGradingWidget, { fieldId });
|
|
10660
|
+
case "pain_scale_flags":
|
|
10661
|
+
return /* @__PURE__ */ jsx(PainScaleFlagsWidget, { fieldId });
|
|
10662
|
+
case "toggle": {
|
|
10663
|
+
const { value, setValue, setTouched, disabled } = useField(fieldId);
|
|
10664
|
+
const store = useFormStore();
|
|
10665
|
+
const excludes = fieldDef.excludes ?? [];
|
|
10666
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
|
|
10667
|
+
/* @__PURE__ */ jsx(
|
|
10668
|
+
Switch,
|
|
10669
|
+
{
|
|
10670
|
+
checked: value === true,
|
|
10671
|
+
disabled,
|
|
10672
|
+
onCheckedChange: (checked) => {
|
|
10673
|
+
setValue(checked);
|
|
10674
|
+
setTouched();
|
|
10675
|
+
if (checked) excludes.forEach((id) => store.setValue(id, false));
|
|
10676
|
+
}
|
|
10677
|
+
}
|
|
10678
|
+
),
|
|
10679
|
+
/* @__PURE__ */ jsx(Label, { className: "text-sm font-medium leading-none cursor-pointer select-none", children: fieldDef.label })
|
|
10680
|
+
] });
|
|
12048
10681
|
}
|
|
12049
10682
|
case "suggestion_textarea":
|
|
12050
10683
|
case "complaint_chips":
|
|
@@ -12889,30 +11522,6 @@ var ReadOnlyFieldRenderer = ({
|
|
|
12889
11522
|
].join("\n");
|
|
12890
11523
|
return /* @__PURE__ */ jsx(ReadOnlyText, { fieldDef, value: lines });
|
|
12891
11524
|
}
|
|
12892
|
-
case "urology_smart_history":
|
|
12893
|
-
return /* @__PURE__ */ jsx(
|
|
12894
|
-
ReadOnlyText,
|
|
12895
|
-
{
|
|
12896
|
-
fieldDef,
|
|
12897
|
-
value: value && typeof value === "object" ? JSON.stringify(value, null, 2) : value == null || value === "" ? "\u2014" : String(value)
|
|
12898
|
-
}
|
|
12899
|
-
);
|
|
12900
|
-
case "urology_examination":
|
|
12901
|
-
return /* @__PURE__ */ jsx(
|
|
12902
|
-
ReadOnlyText,
|
|
12903
|
-
{
|
|
12904
|
-
fieldDef,
|
|
12905
|
-
value: value && typeof value === "object" ? JSON.stringify(value, null, 2) : value == null || value === "" ? "\u2014" : String(value)
|
|
12906
|
-
}
|
|
12907
|
-
);
|
|
12908
|
-
case "urology_pathway":
|
|
12909
|
-
return /* @__PURE__ */ jsx(
|
|
12910
|
-
ReadOnlyText,
|
|
12911
|
-
{
|
|
12912
|
-
fieldDef,
|
|
12913
|
-
value: value && typeof value === "object" ? JSON.stringify(value, null, 2) : value == null || value === "" ? "\u2014" : String(value)
|
|
12914
|
-
}
|
|
12915
|
-
);
|
|
12916
11525
|
case "general_surgery_smart_history": {
|
|
12917
11526
|
const structuredDisplay = value && typeof value === "object" ? JSON.stringify(normalizeGeneralSurgerySmartHistory(value), null, 2) : value == null || value === "" ? "\u2014" : String(value);
|
|
12918
11527
|
const hopcDef = resolveFieldDef?.("symptoms");
|
|
@@ -13154,6 +11763,6 @@ function createUploadHandler(options) {
|
|
|
13154
11763
|
};
|
|
13155
11764
|
}
|
|
13156
11765
|
|
|
13157
|
-
export { AddInvestigationField, AddMedicationField, DifferentialDiagnosis, DynamicForm, EMAIL_REGEX, FieldRenderer, FormControls, FormProvider, FormStore, ImageUploadWidget, MAR_MEDICATION_ORDERS_META_KEY, MediaUploadWidget, ReadOnlyForm, ReadOnlyImageUpload, ReadOnlyMediaUpload, ReadOnlySignature, ReadOnlyTable, RichTextWidget, SignatureUploadWidget, SmartForm, SmartTextareaWidget,
|
|
11766
|
+
export { AddInvestigationField, AddMedicationField, DifferentialDiagnosis, DynamicForm, EMAIL_REGEX, FieldRenderer, FormControls, FormProvider, FormStore, ImageUploadWidget, MAR_MEDICATION_ORDERS_META_KEY, MediaUploadWidget, ReadOnlyForm, ReadOnlyImageUpload, ReadOnlyMediaUpload, ReadOnlySignature, ReadOnlyTable, RichTextWidget, SignatureUploadWidget, SmartForm, SmartTextareaWidget, createUploadHandler, evaluateRules, fieldMetaRequestsMarMedicationOrdersButton, useField, useFieldHandlers, useForm, useFormStore, useFrequentItems, usePackages, useSmartKeywords, validateField, validateForm };
|
|
13158
11767
|
//# sourceMappingURL=index.mjs.map
|
|
13159
11768
|
//# sourceMappingURL=index.mjs.map
|