@mieweb/ui 0.11.0-dev.32 → 0.11.0-dev.34

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 (108) hide show
  1. package/dist/{chunk-PJN4HM2X.cjs → chunk-3O3Q3DX7.cjs} +21 -21
  2. package/dist/{chunk-PJN4HM2X.cjs.map → chunk-3O3Q3DX7.cjs.map} +1 -1
  3. package/dist/{chunk-M42FTWY2.cjs → chunk-46RYJYN2.cjs} +6 -6
  4. package/dist/{chunk-M42FTWY2.cjs.map → chunk-46RYJYN2.cjs.map} +1 -1
  5. package/dist/{chunk-JMAZ2GKT.js → chunk-4GSFVD5V.js} +3 -3
  6. package/dist/{chunk-JMAZ2GKT.js.map → chunk-4GSFVD5V.js.map} +1 -1
  7. package/dist/{chunk-2R3ILG4Y.cjs → chunk-4M2KE4O5.cjs} +7 -7
  8. package/dist/{chunk-2R3ILG4Y.cjs.map → chunk-4M2KE4O5.cjs.map} +1 -1
  9. package/dist/{chunk-L52HKEUD.js → chunk-4SUEBKTY.js} +3 -3
  10. package/dist/{chunk-L52HKEUD.js.map → chunk-4SUEBKTY.js.map} +1 -1
  11. package/dist/{chunk-SCYLVQWA.cjs → chunk-6O6EYKOG.cjs} +130 -874
  12. package/dist/chunk-6O6EYKOG.cjs.map +1 -0
  13. package/dist/{chunk-INMDLVUB.cjs → chunk-6UYMO3PF.cjs} +7 -2
  14. package/dist/chunk-6UYMO3PF.cjs.map +1 -0
  15. package/dist/{chunk-2Z2GFDRS.cjs → chunk-DXNVQQYN.cjs} +4 -4
  16. package/dist/{chunk-2Z2GFDRS.cjs.map → chunk-DXNVQQYN.cjs.map} +1 -1
  17. package/dist/{chunk-JN2CL7MK.js → chunk-EWPNM6OO.js} +25 -5
  18. package/dist/chunk-EWPNM6OO.js.map +1 -0
  19. package/dist/{chunk-JQAGNAY2.js → chunk-EX7Q5545.js} +4 -4
  20. package/dist/{chunk-JQAGNAY2.js.map → chunk-EX7Q5545.js.map} +1 -1
  21. package/dist/{chunk-YG7BR76Y.js → chunk-GMNF4E7B.js} +3 -42
  22. package/dist/chunk-GMNF4E7B.js.map +1 -0
  23. package/dist/chunk-HTZ27DGZ.js +46 -0
  24. package/dist/chunk-HTZ27DGZ.js.map +1 -0
  25. package/dist/{chunk-SNAMNKFH.js → chunk-JEXEFWEM.js} +7 -2
  26. package/dist/chunk-JEXEFWEM.js.map +1 -0
  27. package/dist/{chunk-KIVEYQGA.cjs → chunk-MSX2P5JE.cjs} +2 -48
  28. package/dist/chunk-MSX2P5JE.cjs.map +1 -0
  29. package/dist/{chunk-VV2U36T6.cjs → chunk-MZR634HI.cjs} +9 -9
  30. package/dist/{chunk-VV2U36T6.cjs.map → chunk-MZR634HI.cjs.map} +1 -1
  31. package/dist/{chunk-JCO62XMU.cjs → chunk-NCPDUJKJ.cjs} +43 -26
  32. package/dist/chunk-NCPDUJKJ.cjs.map +1 -0
  33. package/dist/{chunk-DG3CXR24.js → chunk-NW6D6AFL.js} +80 -819
  34. package/dist/chunk-NW6D6AFL.js.map +1 -0
  35. package/dist/{chunk-BP4LXRC6.cjs → chunk-PGJLW2NO.cjs} +7 -7
  36. package/dist/{chunk-BP4LXRC6.cjs.map → chunk-PGJLW2NO.cjs.map} +1 -1
  37. package/dist/chunk-PHYQSCP6.cjs +54 -0
  38. package/dist/chunk-PHYQSCP6.cjs.map +1 -0
  39. package/dist/{chunk-ZFJJMDV3.js → chunk-RTADGBBN.js} +3 -3
  40. package/dist/{chunk-ZFJJMDV3.js.map → chunk-RTADGBBN.js.map} +1 -1
  41. package/dist/{chunk-FQUSSPXX.cjs → chunk-S2CJ57BX.cjs} +25 -5
  42. package/dist/chunk-S2CJ57BX.cjs.map +1 -0
  43. package/dist/{chunk-KSQQBFDQ.js → chunk-SPGP252Q.js} +43 -26
  44. package/dist/chunk-SPGP252Q.js.map +1 -0
  45. package/dist/{chunk-67SD6VPF.cjs → chunk-SVC7NPQ6.cjs} +6 -6
  46. package/dist/{chunk-67SD6VPF.cjs.map → chunk-SVC7NPQ6.cjs.map} +1 -1
  47. package/dist/{chunk-TWQSMUE6.js → chunk-VMEVLBI3.js} +46 -38
  48. package/dist/chunk-VMEVLBI3.js.map +1 -0
  49. package/dist/{chunk-QNJEDBIN.js → chunk-X5HLVACK.js} +4 -4
  50. package/dist/{chunk-QNJEDBIN.js.map → chunk-X5HLVACK.js.map} +1 -1
  51. package/dist/{chunk-LC3JL2HB.cjs → chunk-XEHD2HA5.cjs} +46 -38
  52. package/dist/chunk-XEHD2HA5.cjs.map +1 -0
  53. package/dist/{chunk-R3MJKY63.js → chunk-YGSPIDE4.js} +3 -3
  54. package/dist/{chunk-R3MJKY63.js.map → chunk-YGSPIDE4.js.map} +1 -1
  55. package/dist/{chunk-7LKTIZLR.js → chunk-YR45POH2.js} +3 -3
  56. package/dist/{chunk-7LKTIZLR.js.map → chunk-YR45POH2.js.map} +1 -1
  57. package/dist/components/AlertDialog/index.cjs +6 -6
  58. package/dist/components/AlertDialog/index.js +2 -2
  59. package/dist/components/EmailEditor/index.cjs +14 -12
  60. package/dist/components/EmailEditor/index.js +5 -3
  61. package/dist/components/KeyboardShortcutsOverlay/index.cjs +4 -4
  62. package/dist/components/KeyboardShortcutsOverlay/index.js +2 -2
  63. package/dist/components/MediaEditor/index.cjs +7 -7
  64. package/dist/components/MediaEditor/index.js +2 -2
  65. package/dist/components/MediaFeed/index.cjs +3 -3
  66. package/dist/components/MediaFeed/index.js +2 -2
  67. package/dist/components/Modal/index.cjs +9 -9
  68. package/dist/components/Modal/index.js +1 -1
  69. package/dist/components/RichTextEditor/index.cjs +6 -4
  70. package/dist/components/RichTextEditor/index.js +3 -1
  71. package/dist/components/SuperChat/index.cjs +3 -3
  72. package/dist/components/SuperChat/index.js +2 -2
  73. package/dist/components/Textarea/index.cjs +7 -5
  74. package/dist/components/Textarea/index.js +4 -2
  75. package/dist/esheet.cjs +1119 -1393
  76. package/dist/esheet.cjs.map +1 -1
  77. package/dist/esheet.d.cts +211 -4
  78. package/dist/esheet.d.ts +211 -4
  79. package/dist/esheet.js +946 -1239
  80. package/dist/esheet.js.map +1 -1
  81. package/dist/hooks/index.cjs +41 -40
  82. package/dist/hooks/index.js +2 -1
  83. package/dist/index.cjs +1058 -285
  84. package/dist/index.cjs.map +1 -1
  85. package/dist/index.d.cts +6 -2
  86. package/dist/index.d.ts +6 -2
  87. package/dist/index.js +809 -20
  88. package/dist/index.js.map +1 -1
  89. package/dist/{model-NPW2JMHZ.cjs → model-EFXX5JZN.cjs} +18 -18
  90. package/dist/{model-NPW2JMHZ.cjs.map → model-EFXX5JZN.cjs.map} +1 -1
  91. package/dist/{model-SG5H3TCJ.js → model-TAARSYDY.js} +4 -4
  92. package/dist/{model-SG5H3TCJ.js.map → model-TAARSYDY.js.map} +1 -1
  93. package/dist/styles.css +1 -1
  94. package/dist/tailwind-preset.cjs +4 -4
  95. package/dist/tailwind-preset.js +1 -1
  96. package/package.json +1 -1
  97. package/dist/chunk-DG3CXR24.js.map +0 -1
  98. package/dist/chunk-FQUSSPXX.cjs.map +0 -1
  99. package/dist/chunk-INMDLVUB.cjs.map +0 -1
  100. package/dist/chunk-JCO62XMU.cjs.map +0 -1
  101. package/dist/chunk-JN2CL7MK.js.map +0 -1
  102. package/dist/chunk-KIVEYQGA.cjs.map +0 -1
  103. package/dist/chunk-KSQQBFDQ.js.map +0 -1
  104. package/dist/chunk-LC3JL2HB.cjs.map +0 -1
  105. package/dist/chunk-SCYLVQWA.cjs.map +0 -1
  106. package/dist/chunk-SNAMNKFH.js.map +0 -1
  107. package/dist/chunk-TWQSMUE6.js.map +0 -1
  108. package/dist/chunk-YG7BR76Y.js.map +0 -1
package/dist/esheet.cjs CHANGED
@@ -1,33 +1,34 @@
1
1
  'use strict';
2
2
 
3
3
  require('./chunk-K2BY7YPJ.cjs');
4
- var chunkM42FTWY2_cjs = require('./chunk-M42FTWY2.cjs');
5
- var chunkSCYLVQWA_cjs = require('./chunk-SCYLVQWA.cjs');
6
- var chunkJCO62XMU_cjs = require('./chunk-JCO62XMU.cjs');
4
+ var chunk46RYJYN2_cjs = require('./chunk-46RYJYN2.cjs');
5
+ var chunk6O6EYKOG_cjs = require('./chunk-6O6EYKOG.cjs');
6
+ var chunkNCPDUJKJ_cjs = require('./chunk-NCPDUJKJ.cjs');
7
7
  require('./chunk-GLG6UE2H.cjs');
8
8
  var chunkSV6YGK4U_cjs = require('./chunk-SV6YGK4U.cjs');
9
- var chunkG7EQ3JPX_cjs = require('./chunk-G7EQ3JPX.cjs');
10
- var chunkAIJAFPGJ_cjs = require('./chunk-AIJAFPGJ.cjs');
9
+ require('./chunk-G7EQ3JPX.cjs');
10
+ require('./chunk-AIJAFPGJ.cjs');
11
11
  var chunkPHUTJKHL_cjs = require('./chunk-PHUTJKHL.cjs');
12
- var chunk2Z2GFDRS_cjs = require('./chunk-2Z2GFDRS.cjs');
13
- require('./chunk-FQUSSPXX.cjs');
12
+ var chunkDXNVQQYN_cjs = require('./chunk-DXNVQQYN.cjs');
13
+ require('./chunk-S2CJ57BX.cjs');
14
14
  var chunkFSLI5IKP_cjs = require('./chunk-FSLI5IKP.cjs');
15
15
  require('./chunk-YP5T6NZD.cjs');
16
16
  var chunkUPWIJC6I_cjs = require('./chunk-UPWIJC6I.cjs');
17
17
  require('./chunk-ZNUMOJOI.cjs');
18
18
  require('./chunk-PINIBEIU.cjs');
19
19
  require('./chunk-MJWFNV3L.cjs');
20
- var chunk7AECNMYV_cjs = require('./chunk-7AECNMYV.cjs');
21
- require('./chunk-LC3JL2HB.cjs');
20
+ require('./chunk-7AECNMYV.cjs');
21
+ require('./chunk-XEHD2HA5.cjs');
22
22
  require('./chunk-I44YNYI6.cjs');
23
23
  var chunkZ5S5JEJD_cjs = require('./chunk-Z5S5JEJD.cjs');
24
24
  require('./chunk-GF2BE4FB.cjs');
25
25
  require('./chunk-CPDNX3LS.cjs');
26
+ require('./chunk-PHYQSCP6.cjs');
26
27
  require('./chunk-NNEFAUHV.cjs');
27
28
  var chunkFHY3K6PL_cjs = require('./chunk-FHY3K6PL.cjs');
28
29
  require('./chunk-FSGEDDF2.cjs');
29
30
  require('./chunk-AOHJILLU.cjs');
30
- var chunkCW75IKA6_cjs = require('./chunk-CW75IKA6.cjs');
31
+ require('./chunk-CW75IKA6.cjs');
31
32
  require('./chunk-C7RVKV25.cjs');
32
33
  require('./chunk-SCV7C55E.cjs');
33
34
  require('./chunk-L7L5S2HO.cjs');
@@ -46,6 +47,7 @@ var renderer = require('@esheet/renderer');
46
47
  var DOMPurify = require('dompurify');
47
48
  var jsxRuntime = require('react/jsx-runtime');
48
49
  var fields = require('@esheet/fields');
50
+ var yaml = require('yaml');
49
51
  var builder = require('@esheet/builder');
50
52
 
51
53
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
@@ -236,7 +238,7 @@ function EncounterMdyView({ source }) {
236
238
  const [failure2, setFailure] = React11__namespace.useState(null);
237
239
  React11__namespace.useEffect(() => {
238
240
  let cancelled = false;
239
- void chunkM42FTWY2_cjs.renderEncounterMdy(source).then((result) => {
241
+ void chunk46RYJYN2_cjs.renderEncounterMdy(source).then((result) => {
240
242
  if (cancelled) return;
241
243
  const html = createEncounterReportHtml(
242
244
  result.html ?? "",
@@ -281,6 +283,31 @@ function EncounterMdyView({ source }) {
281
283
  }
282
284
  );
283
285
  }
286
+ var EsheetSectionContext = React11__namespace.createContext(false);
287
+ function EsheetSectionField(props) {
288
+ const inDocument = React11__namespace.useContext(EsheetSectionContext);
289
+ const { field, isPreview, isRequired, isSoftRequired, nestedChildren } = props;
290
+ const def = field.definition;
291
+ if (!inDocument || !isPreview) return /* @__PURE__ */ jsxRuntime.jsx(fields.SectionField, { ...props });
292
+ const title = def.title || "Section";
293
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "section-field-preview grid gap-1.5", children: [
294
+ /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-foreground m-0 flex items-center gap-2 text-sm font-medium", children: /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "min-w-0 break-words", children: [
295
+ title,
296
+ (isRequired || isSoftRequired) && /* @__PURE__ */ jsxRuntime.jsx(
297
+ chunkZ5S5JEJD_cjs.RequiredMark,
298
+ {
299
+ variant: isSoftRequired && !isRequired ? "warning" : void 0
300
+ }
301
+ )
302
+ ] }) }),
303
+ nestedChildren
304
+ ] });
305
+ }
306
+ function registerEsheetSectionFieldType() {
307
+ const section = fields.getFieldComponent("section");
308
+ if (section === void 0 || section === fields.SectionField)
309
+ fields.registerFieldComponents({ section: EsheetSectionField });
310
+ }
284
311
  var measurements = [
285
312
  { key: "pulse", label: "Pulse", unit: "bpm" },
286
313
  { key: "respiratoryRate", label: "Respiratory rate", unit: "/min" },
@@ -362,7 +389,7 @@ function EncounterVitalsField({
362
389
  const [drafts, setDrafts] = React11__namespace.useState({});
363
390
  const readOnly = !(isPreview && isEnabled) || Boolean(isReadOnly) || Boolean(parsed.error);
364
391
  const definition = field.definition;
365
- const issues = chunkM42FTWY2_cjs.validateEncounterVitals(parsed.value, definition.id);
392
+ const issues = chunk46RYJYN2_cjs.validateEncounterVitals(parsed.value, definition.id);
366
393
  const commit = (value) => {
367
394
  if (!readOnly) {
368
395
  const next = { ...response, answer: JSON.stringify(value), _ai: false };
@@ -654,103 +681,6 @@ function EncounterVitalsField({
654
681
  }
655
682
  );
656
683
  }
657
- function FreeClinicalEntry({
658
- placeholder,
659
- translate,
660
- onFreeText
661
- }) {
662
- const [text, setText] = React11__namespace.useState("");
663
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-w-0 flex-wrap gap-2", children: [
664
- /* @__PURE__ */ jsxRuntime.jsx(
665
- chunkZ5S5JEJD_cjs.Input,
666
- {
667
- "aria-label": translate("Clinical entry"),
668
- placeholder,
669
- value: text,
670
- onChange: (event) => setText(event.target.value)
671
- }
672
- ),
673
- /* @__PURE__ */ jsxRuntime.jsx(
674
- chunkFSARTLUE_cjs.Button,
675
- {
676
- type: "button",
677
- disabled: !text.trim(),
678
- onClick: () => {
679
- onFreeText?.(text.trim());
680
- setText("");
681
- },
682
- children: translate("Add")
683
- }
684
- )
685
- ] });
686
- }
687
- function codedOrderSearch(config, requireCoding = true, translate = (message) => message) {
688
- const CodedOrderSearch = ({
689
- domains,
690
- preferDomains,
691
- preferCodetypes,
692
- billableOnly,
693
- placeholder,
694
- onPick,
695
- onFreeText
696
- }) => {
697
- if (!config)
698
- return /* @__PURE__ */ jsxRuntime.jsx(
699
- FreeClinicalEntry,
700
- {
701
- placeholder,
702
- translate,
703
- onFreeText
704
- }
705
- );
706
- const Lookup = config.component;
707
- const allowedDomains = domains;
708
- return /* @__PURE__ */ jsxRuntime.jsx(
709
- Lookup,
710
- {
711
- indexUrl: config.indexUrl,
712
- locale: config.locale,
713
- domains: allowedDomains,
714
- preferDomains,
715
- preferCodetypes,
716
- billableOnly,
717
- bare: true,
718
- clearOnSelect: true,
719
- placeholder,
720
- onFreeText: requireCoding ? void 0 : onFreeText,
721
- onSelect: (result) => {
722
- if (!result.fullid?.trim() || !result.codetype?.trim() || !result.fullcode?.trim() || !result.label?.trim() || allowedDomains !== void 0 && !allowedDomains.includes(result.domain))
723
- return;
724
- onPick({
725
- fullid: result.fullid,
726
- label: result.label,
727
- codetype: result.codetype,
728
- fullcode: result.fullcode
729
- });
730
- }
731
- }
732
- );
733
- };
734
- return CodedOrderSearch;
735
- }
736
- var clinicalAssessmentClasses = "rounded-none border-0 bg-transparent shadow-none [&_.border-dashed]:rounded-none [&_.border-dashed]:border-0 [&_.border-dashed]:bg-transparent [&_.border-dashed]:p-0 [&_.min-w-64]:min-w-0 [&_[data-slot=assessment-problem]]:rounded-none [&_[data-slot=assessment-problem]]:border-0 [&_[data-slot=assessment-problem]]:px-0 [&_[data-slot=assessment-problem]>ul]:ms-0 [&_[data-slot=assessment-problem]>ul]:border-0 [&_[data-slot=assessment-problem]>ul]:ps-4 [&_button]:min-h-11 [&_button]:min-w-11 [&_input]:min-h-11 [&_select]:min-h-11 [&>[data-slot=card-content]]:p-0 [&>[data-slot=card-content]>section]:border-0 [&>[data-slot=card-content]>section]:bg-transparent [&>[data-slot=card-content]>section]:px-0";
737
- var clinicalEntryCardClasses = "bg-muted/40 min-w-0 space-y-3 rounded-lg p-3";
738
- function ClinicalAddButton({
739
- label,
740
- onClick
741
- }) {
742
- return /* @__PURE__ */ jsxRuntime.jsx(
743
- chunkFSARTLUE_cjs.Button,
744
- {
745
- type: "button",
746
- variant: "ghost",
747
- leftIcon: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Plus, { "aria-hidden": "true" }),
748
- className: "text-primary-800 hover:bg-primary-50 hover:text-primary-900 active:bg-primary-100 dark:text-primary-400 dark:hover:bg-primary-950 dark:hover:text-primary-200 min-h-11",
749
- onClick,
750
- children: label
751
- }
752
- );
753
- }
754
684
  function InvalidClinicalAnswer({
755
685
  label,
756
686
  answer
@@ -801,7 +731,7 @@ function getExternalEncounterConditions(state) {
801
731
  if (!answer) continue;
802
732
  try {
803
733
  const parsed = JSON.parse(answer);
804
- if (chunkM42FTWY2_cjs.validateEncounterConditions(parsed).length > 0) continue;
734
+ if (chunk46RYJYN2_cjs.validateEncounterConditions(parsed).length > 0) continue;
805
735
  for (const concern of parsed.concerns) {
806
736
  if (!byId.has(concern.concernId)) byId.set(concern.concernId, concern);
807
737
  }
@@ -895,18 +825,15 @@ function conditionSystemIdentity(system) {
895
825
  const trimmed = system.trim();
896
826
  if (trimmed === "http://hl7.org/fhir/sid/icd-10-cm") return "ICD-10-CM";
897
827
  if (trimmed === "http://snomed.info/sct") return "SNOMED";
898
- return chunkSCYLVQWA_cjs.normalizeConditionCodingSystem(trimmed);
828
+ return chunk6O6EYKOG_cjs.normalizeConditionCodingSystem(trimmed);
899
829
  }
900
830
  function matchingConditionCode(concern, picked) {
901
831
  return Boolean(
902
- chunkJCO62XMU_cjs.currentAssertion(concern)?.coding?.some(
832
+ chunkNCPDUJKJ_cjs.currentAssertion(concern)?.coding?.some(
903
833
  (coding) => conditionSystemIdentity(coding.system) === conditionSystemIdentity(picked.codetype) && coding.code.trim().toUpperCase() === picked.fullcode.trim().toUpperCase()
904
834
  )
905
835
  );
906
836
  }
907
- function clinicalRequiresCoding(field) {
908
- return field.definition._sourceData?.encounterRequireCoding ?? true;
909
- }
910
837
  function clinicalAnswerResponse(response, answer) {
911
838
  const next = { ...response, answer, _ai: false };
912
839
  delete next.selected;
@@ -918,38 +845,7 @@ function useEncounterAssertionDate(field) {
918
845
  React11__namespace.useEffect(() => {
919
846
  setDate(hostDate ?? "");
920
847
  }, [hostDate]);
921
- return { date, setDate, valid: chunkM42FTWY2_cjs.isEncounterDate(date) };
922
- }
923
- function EncounterAssertionDateInput({
924
- date,
925
- setDate
926
- }) {
927
- const m = chunkFSLI5IKP_cjs.useMessages();
928
- const id = React11__namespace.useId();
929
- const [display, setDisplay] = React11__namespace.useState(() => chunkCW75IKA6_cjs.dateToDisplayFormat(date));
930
- React11__namespace.useEffect(() => {
931
- setDisplay(
932
- (current) => chunkCW75IKA6_cjs.displayFormatToDateString(current) === date ? current : chunkCW75IKA6_cjs.dateToDisplayFormat(date)
933
- );
934
- }, [date]);
935
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-w-0 flex-col gap-1", children: [
936
- /* @__PURE__ */ jsxRuntime.jsx("label", { htmlFor: id, className: "text-sm font-medium", children: m("Assertion date") }),
937
- /* @__PURE__ */ jsxRuntime.jsx(
938
- chunkPHUTJKHL_cjs.DateInput,
939
- {
940
- id,
941
- value: display,
942
- onChange: (value) => {
943
- setDisplay(value);
944
- setDate(chunkCW75IKA6_cjs.displayFormatToDateString(value));
945
- },
946
- showCalendar: true,
947
- width: "fixed",
948
- className: "min-h-11"
949
- }
950
- ),
951
- !chunkM42FTWY2_cjs.isEncounterDate(date) && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground text-sm", children: m("Enter the encounter date before adding or changing a diagnosis.") })
952
- ] });
848
+ return { date, setDate, valid: chunk46RYJYN2_cjs.isEncounterDate(date) };
953
849
  }
954
850
  function readAssessment(answer, externalConcerns) {
955
851
  if (!answer) return { value: { concerns: [], items: [], orders: [] } };
@@ -957,13 +853,13 @@ function readAssessment(answer, externalConcerns) {
957
853
  const parsed = JSON.parse(answer);
958
854
  if (!parsed || typeof parsed !== "object" || Array.isArray(parsed))
959
855
  throw new Error();
960
- if (chunkM42FTWY2_cjs.validateEncounterAssessment(parsed, "", "", externalConcerns).length > 0)
856
+ if (chunk46RYJYN2_cjs.validateEncounterAssessment(parsed, "", "", externalConcerns).length > 0)
961
857
  throw new Error();
962
858
  return { value: parsed };
963
859
  } catch {
964
860
  return {
965
861
  value: { concerns: [], items: [], orders: [] },
966
- error: "The saved assessment answer could not be read. The original answer is retained below; correct it through the visit data before editing."
862
+ error: "unreadable"
967
863
  };
968
864
  }
969
865
  }
@@ -984,11 +880,9 @@ function EncounterAssessmentField({
984
880
  onResponse
985
881
  }) {
986
882
  const m = chunkFSLI5IKP_cjs.useMessages();
987
- const requireCoding = clinicalRequiresCoding(field);
988
883
  const assertionDate = useEncounterAssertionDate(field);
989
884
  const currentDate = React11__namespace.useRef(assertionDate);
990
885
  currentDate.current = assertionDate;
991
- const codeLookup = chunkSCYLVQWA_cjs.useCodeLookupConfig();
992
886
  const state = useClinicalFormState(form);
993
887
  const externalConcerns = React11__namespace.useMemo(
994
888
  () => getExternalEncounterConditions(state),
@@ -1013,10 +907,6 @@ function EncounterAssessmentField({
1013
907
  currentValue.current = value;
1014
908
  const canEdit = React11__namespace.useRef(!readOnly);
1015
909
  canEdit.current = !readOnly;
1016
- const renderSearch = React11__namespace.useMemo(
1017
- () => codeLookup || !requireCoding ? codedOrderSearch(codeLookup, requireCoding, m) : void 0,
1018
- [codeLookup, requireCoding, m]
1019
- );
1020
910
  const definition = field.definition;
1021
911
  const commit = (update) => {
1022
912
  if (!canEdit.current || form.getState().readOnly || form.getState().disposed)
@@ -1031,124 +921,92 @@ function EncounterAssessmentField({
1031
921
  );
1032
922
  };
1033
923
  if (error) {
1034
- return /* @__PURE__ */ jsxRuntime.jsx(
1035
- "section",
924
+ return /* @__PURE__ */ jsxRuntime.jsx(InvalidClinicalAnswer, { label: "assessment", answer: response?.answer });
925
+ }
926
+ return /* @__PURE__ */ jsxRuntime.jsxs("section", { className: "space-y-2", children: [
927
+ /* @__PURE__ */ jsxRuntime.jsx(
928
+ chunk6O6EYKOG_cjs.Assessment,
1036
929
  {
930
+ concerns,
931
+ items: value.items,
932
+ orders: value.orders,
1037
933
  "aria-label": definition.question ?? m("Assessment and plan"),
1038
- className: "space-y-3",
1039
- children: /* @__PURE__ */ jsxRuntime.jsxs(
1040
- "div",
1041
- {
1042
- role: "alert",
1043
- className: "border-destructive text-destructive rounded-lg border p-3",
1044
- children: [
1045
- /* @__PURE__ */ jsxRuntime.jsx("p", { children: m(error) }),
1046
- /* @__PURE__ */ jsxRuntime.jsx(
1047
- "pre",
934
+ readOnly,
935
+ addFormLabel: "Add assessment or order",
936
+ onAddAssessment: !assertionDate.valid ? void 0 : (pick) => {
937
+ if (!currentDate.current.valid) return;
938
+ const existingConcern = pick.code ? concerns.find(
939
+ (concern) => matchingConditionCode(concern, pick.code)
940
+ ) : void 0;
941
+ const existingAssertion = existingConcern && chunkNCPDUJKJ_cjs.currentAssertion(existingConcern);
942
+ if (existingConcern && existingAssertion) {
943
+ commit((next) => ({
944
+ ...next,
945
+ items: [
946
+ ...next.items.filter(
947
+ (item) => item.concernId !== existingConcern.concernId
948
+ ),
1048
949
  {
1049
- tabIndex: 0,
1050
- "aria-label": m("Original assessment answer"),
1051
- className: "mt-2 max-h-48 overflow-auto text-xs break-all whitespace-pre-wrap",
1052
- children: response?.answer
950
+ concernId: existingConcern.concernId,
951
+ assertionId: existingAssertion.id
1053
952
  }
1054
- )
1055
- ]
953
+ ]
954
+ }));
955
+ return;
1056
956
  }
1057
- )
1058
- }
1059
- );
1060
- }
1061
- return /* @__PURE__ */ jsxRuntime.jsx("section", { className: "space-y-2", children: /* @__PURE__ */ jsxRuntime.jsx(
1062
- chunkSCYLVQWA_cjs.Assessment,
1063
- {
1064
- concerns,
1065
- items: value.items,
1066
- orders: value.orders,
1067
- title: null,
1068
- addFormStart: !readOnly && /* @__PURE__ */ jsxRuntime.jsx(EncounterAssertionDateInput, { ...assertionDate }),
1069
- "aria-label": definition.question ?? m("Assessment and plan"),
1070
- className: "rounded-none border-0 bg-transparent shadow-none [&_.border-dashed]:rounded-none [&_.border-dashed]:border-0 [&_.border-dashed]:bg-transparent [&_.border-dashed]:p-0 [&_.min-w-64]:min-w-0 [&_[data-slot=assessment-problem]]:rounded-none [&_[data-slot=assessment-problem]]:border-0 [&_[data-slot=assessment-problem]]:px-0 [&_[data-slot=assessment-problem]>ul]:ms-0 [&_[data-slot=assessment-problem]>ul]:border-0 [&_[data-slot=assessment-problem]>ul]:ps-4 [&_button]:min-h-11 [&_button]:min-w-11 [&_input]:min-h-11 [&_select]:min-h-11 [&>[data-slot=card-content]]:p-0 [&>[data-slot=card-content]>section]:border-0 [&>[data-slot=card-content]>section]:bg-transparent [&>[data-slot=card-content]>section]:px-0",
1071
- readOnly,
1072
- defaultAddMode: "problem",
1073
- addFormLabel: "Add assessment or order",
1074
- renderOrderSearch: renderSearch,
1075
- onAddAssessment: (codeLookup || !requireCoding) && assertionDate.valid ? (pick) => {
1076
- if (!currentDate.current.valid || requireCoding && !pick.code)
1077
- return;
1078
- const existingConcern = pick.code ? concerns.find(
1079
- (concern) => matchingConditionCode(concern, pick.code)
1080
- ) : void 0;
1081
- const existingAssertion = existingConcern && chunkJCO62XMU_cjs.currentAssertion(existingConcern);
1082
- if (existingConcern && existingAssertion) {
957
+ const concernId = globalThis.crypto.randomUUID();
958
+ const assertionId = globalThis.crypto.randomUUID();
1083
959
  commit((next) => ({
1084
960
  ...next,
1085
- items: [
1086
- ...next.items.filter(
1087
- (item) => item.concernId !== existingConcern.concernId
1088
- ),
961
+ concerns: [
962
+ ...next.concerns,
1089
963
  {
1090
- concernId: existingConcern.concernId,
1091
- assertionId: existingAssertion.id
964
+ concernId,
965
+ clinicalStatus: "active",
966
+ source: "manuallyAdded",
967
+ assertions: [
968
+ {
969
+ id: assertionId,
970
+ date: currentDate.current.date,
971
+ text: pick.label,
972
+ verificationStatus: "unconfirmed",
973
+ coding: pick.code ? [
974
+ {
975
+ system: pick.code.codetype,
976
+ code: pick.code.fullcode,
977
+ display: pick.label
978
+ }
979
+ ] : void 0
980
+ }
981
+ ]
1092
982
  }
1093
- ]
983
+ ],
984
+ items: [...next.items, { concernId, assertionId }]
1094
985
  }));
1095
- return;
1096
- }
1097
- const concernId = globalThis.crypto.randomUUID();
1098
- const assertionId = globalThis.crypto.randomUUID();
1099
- commit((next) => ({
1100
- ...next,
1101
- concerns: [
1102
- ...next.concerns,
1103
- {
1104
- concernId,
1105
- clinicalStatus: "active",
1106
- source: "manuallyAdded",
1107
- assertions: [
1108
- {
1109
- id: assertionId,
1110
- date: currentDate.current.date,
1111
- text: pick.label,
1112
- verificationStatus: "unconfirmed",
1113
- coding: pick.code ? [
1114
- {
1115
- system: pick.code.codetype,
1116
- code: pick.code.fullcode,
1117
- display: pick.label
1118
- }
1119
- ] : void 0
1120
- }
1121
- ]
1122
- }
1123
- ],
1124
- items: [...next.items, { concernId, assertionId }]
1125
- }));
1126
- } : void 0,
1127
- onRemoveAssessment: (item) => {
1128
- const wasLocal = currentValue.current.concerns.some(
1129
- (concern) => concern.concernId === item.concernId
1130
- );
1131
- commit((next) => ({
1132
- ...next,
1133
- // Removing the row also drops its local concern record — nothing
1134
- // else can reference it once the orders below are unlinked, and an
1135
- // orphaned uncoded concern would block Save with no visible repair.
1136
- concerns: next.concerns.filter(
1137
- (concern) => concern.concernId !== item.concernId
1138
- ),
1139
- items: next.items.filter(
1140
- (candidate) => candidate.concernId !== item.concernId
1141
- ),
1142
- orders: next.orders.map(
1143
- (order) => order.concernId === item.concernId ? { ...order, concernId: void 0 } : order
1144
- )
1145
- }));
1146
- if (wasLocal && canEdit.current)
1147
- repairEncounterConcernReferences(form.getState(), item.concernId);
1148
- },
1149
- onAddOrder: codeLookup || !requireCoding ? (item, order) => {
1150
- if (requireCoding && !order.code) return;
1151
- commit((next) => ({
986
+ },
987
+ onRemoveAssessment: (item) => {
988
+ const wasLocal = currentValue.current.concerns.some(
989
+ (concern) => concern.concernId === item.concernId
990
+ );
991
+ commit((next) => ({
992
+ ...next,
993
+ // Removing the row also drops its local concern record — nothing
994
+ // else can reference it once the orders below are unlinked, and an
995
+ // orphaned uncoded concern would block Save with no visible repair.
996
+ concerns: next.concerns.filter(
997
+ (concern) => concern.concernId !== item.concernId
998
+ ),
999
+ items: next.items.filter(
1000
+ (candidate) => candidate.concernId !== item.concernId
1001
+ ),
1002
+ orders: next.orders.map(
1003
+ (order) => order.concernId === item.concernId ? { ...order, concernId: void 0 } : order
1004
+ )
1005
+ }));
1006
+ if (wasLocal && canEdit.current)
1007
+ repairEncounterConcernReferences(form.getState(), item.concernId);
1008
+ },
1009
+ onAddOrder: (item, order) => commit((next) => ({
1152
1010
  ...next,
1153
1011
  orders: [
1154
1012
  ...next.orders,
@@ -1158,59 +1016,64 @@ function EncounterAssessmentField({
1158
1016
  concernId: item?.concernId
1159
1017
  }
1160
1018
  ]
1161
- }));
1162
- } : void 0,
1163
- onEditOrder: (order, changes) => commit((next) => ({
1164
- ...next,
1165
- orders: next.orders.map(
1166
- (candidate) => candidate.orderId === order.orderId ? { ...candidate, ...changes } : candidate
1167
- )
1168
- })),
1169
- onRemoveOrder: (order) => commit((next) => ({
1170
- ...next,
1171
- orders: next.orders.filter(
1172
- (candidate) => candidate.orderId !== order.orderId
1173
- )
1174
- })),
1175
- onLinkOrder: (order, concernId) => commit((next) => ({
1176
- ...next,
1177
- orders: next.orders.map(
1178
- (candidate) => candidate.orderId === order.orderId ? { ...candidate, concernId } : candidate
1179
- )
1180
- })),
1181
- onReorderItems: (ids) => commit((next) => ({
1182
- ...next,
1183
- items: reorder(next.items, ids, (item) => item.concernId)
1184
- })),
1185
- onReorderOrders: (ids) => commit((next) => ({
1186
- ...next,
1187
- orders: reorder(next.orders, ids, (order) => order.orderId)
1188
- }))
1189
- }
1190
- ) });
1019
+ })),
1020
+ onEditOrder: (order, changes) => commit((next) => ({
1021
+ ...next,
1022
+ orders: next.orders.map(
1023
+ (candidate) => candidate.orderId === order.orderId ? { ...candidate, ...changes } : candidate
1024
+ )
1025
+ })),
1026
+ onRemoveOrder: (order) => commit((next) => ({
1027
+ ...next,
1028
+ orders: next.orders.filter(
1029
+ (candidate) => candidate.orderId !== order.orderId
1030
+ )
1031
+ })),
1032
+ onLinkOrder: (order, concernId) => commit((next) => ({
1033
+ ...next,
1034
+ orders: next.orders.map(
1035
+ (candidate) => candidate.orderId === order.orderId ? { ...candidate, concernId } : candidate
1036
+ )
1037
+ })),
1038
+ onReorderItems: (ids) => commit((next) => ({
1039
+ ...next,
1040
+ items: reorder(next.items, ids, (item) => item.concernId)
1041
+ })),
1042
+ onReorderOrders: (ids) => commit((next) => ({
1043
+ ...next,
1044
+ orders: reorder(next.orders, ids, (order) => order.orderId)
1045
+ }))
1046
+ }
1047
+ ),
1048
+ !readOnly && !assertionDate.valid && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-muted-foreground text-xs", children: m(
1049
+ "No encounter date \u2014 new diagnoses are disabled; orders can still be added."
1050
+ ) })
1051
+ ] });
1191
1052
  }
1192
1053
 
1193
- // src/components/EncounterVisit/narrativeFindings.ts
1194
- var FINDINGS_ATTRIBUTE = "encounterNarrativeFindings";
1195
- var FINDINGS_TEXT_ATTRIBUTE = "encounterNarrativeFindingsText";
1196
- var HTML_ATTRIBUTE = "encounterNarrativeHtml";
1197
- var TEXT_ATTRIBUTE = "encounterNarrativeText";
1054
+ // src/esheet-fields/narrativeFindings.ts
1055
+ var NARRATIVE_ATTRIBUTES = {
1056
+ html: "narrativeHtml",
1057
+ text: "narrativeText",
1058
+ findings: "narrativeFindings",
1059
+ findingsText: "narrativeFindingsText"
1060
+ };
1198
1061
  function escapedTextHtml(text) {
1199
1062
  return text.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#39;").replace(/\n/g, "<br>");
1200
1063
  }
1201
1064
  function hasNarrativeTagsOnly(html) {
1202
1065
  return !html.replace(/<\/?(?:p|div|strong|b|em|i|u|ul|ol|li)\s*>|<br\s*\/?>/gi, "").includes("<");
1203
1066
  }
1204
- function appendedRichAttributes(response, answer, finding) {
1067
+ function appendedRichAttributes(response, answer, finding, attributes) {
1205
1068
  const previous = response?.answer ?? "";
1206
- const html = response?.attributes?.[HTML_ATTRIBUTE];
1207
- if (answer === previous || response?.attributes?.[TEXT_ATTRIBUTE] !== previous || typeof html !== "string" || !hasNarrativeTagsOnly(html))
1069
+ const html = response?.attributes?.[attributes.html];
1070
+ if (answer === previous || response?.attributes?.[attributes.text] !== previous || typeof html !== "string" || !hasNarrativeTagsOnly(html))
1208
1071
  return {};
1209
1072
  const aligned = previous.endsWith("\n") ? html.replace(/<br\s*\/?>((?:<\/(?:p|div|ul|ol|li)\s*>|\s)*)$/i, "$1") : html;
1210
1073
  const next = `${previous.trim() ? aligned : ""}<p>${escapedTextHtml(finding.text)}${finding.text.endsWith("\n") ? "<br>" : ""}</p>`;
1211
- return { [HTML_ATTRIBUTE]: next, [TEXT_ATTRIBUTE]: answer };
1074
+ return { [attributes.html]: next, [attributes.text]: answer };
1212
1075
  }
1213
- function validEncounterNarrativeFindings(value) {
1076
+ function validNarrativeFindings(value) {
1214
1077
  if (!Array.isArray(value)) return [];
1215
1078
  const ids = /* @__PURE__ */ new Set();
1216
1079
  return value.flatMap((finding) => {
@@ -1235,7 +1098,7 @@ function validEncounterNarrativeFindings(value) {
1235
1098
  ];
1236
1099
  });
1237
1100
  }
1238
- function hasEncounterNarrativeFindingText(answer, text) {
1101
+ function hasNarrativeFindingText(answer, text) {
1239
1102
  const normalize = (value) => value.replace(/\r\n?/g, "\n").trim();
1240
1103
  return `
1241
1104
  ${normalize(answer)}
@@ -1243,46 +1106,39 @@ ${normalize(answer)}
1243
1106
  ${normalize(text)}
1244
1107
  `);
1245
1108
  }
1246
- function getEncounterNarrativeFindings(response) {
1109
+ function getNarrativeFindings(response, attributes = NARRATIVE_ATTRIBUTES) {
1247
1110
  const answer = response?.answer ?? "";
1248
- if (response?.attributes?.[FINDINGS_TEXT_ATTRIBUTE] !== answer) return [];
1249
- const selected = response.attributes[FINDINGS_ATTRIBUTE];
1111
+ if (response?.attributes?.[attributes.findingsText] !== answer) return [];
1112
+ const selected = response.attributes[attributes.findings];
1250
1113
  if (typeof selected !== "string") return [];
1251
1114
  try {
1252
- return validEncounterNarrativeFindings(JSON.parse(selected)).filter(
1253
- (finding) => hasEncounterNarrativeFindingText(answer, finding.text)
1115
+ return validNarrativeFindings(JSON.parse(selected)).filter(
1116
+ (finding) => hasNarrativeFindingText(answer, finding.text)
1254
1117
  );
1255
1118
  } catch {
1256
1119
  return [];
1257
1120
  }
1258
1121
  }
1259
- function applyEncounterNarrativeFinding(response, finding) {
1260
- const validated = validEncounterNarrativeFindings([finding])[0];
1122
+ function applyNarrativeFinding(response, finding, attributes = NARRATIVE_ATTRIBUTES) {
1123
+ const validated = validNarrativeFindings([finding])[0];
1261
1124
  if (!validated) return response ?? {};
1262
- const selected = getEncounterNarrativeFindings(response);
1125
+ const selected = getNarrativeFindings(response, attributes);
1263
1126
  if (selected.some((item) => item.id === validated.id)) return response ?? {};
1264
1127
  const previousAnswer = response?.answer ?? "";
1265
- const answer = hasEncounterNarrativeFindingText(
1266
- previousAnswer,
1267
- validated.text
1268
- ) ? previousAnswer : `${previousAnswer.trim() ? `${previousAnswer}${previousAnswer.endsWith("\n") ? "" : "\n"}` : ""}${validated.text}`;
1128
+ const answer = hasNarrativeFindingText(previousAnswer, validated.text) ? previousAnswer : `${previousAnswer.trim() ? `${previousAnswer}${previousAnswer.endsWith("\n") ? "" : "\n"}` : ""}${validated.text}`;
1269
1129
  return {
1270
1130
  ...response,
1271
1131
  answer,
1272
1132
  _ai: false,
1273
1133
  attributes: {
1274
1134
  ...response?.attributes,
1275
- ...appendedRichAttributes(response, answer, validated),
1276
- [FINDINGS_ATTRIBUTE]: JSON.stringify([...selected, validated]),
1277
- [FINDINGS_TEXT_ATTRIBUTE]: answer
1135
+ ...appendedRichAttributes(response, answer, validated, attributes),
1136
+ [attributes.findings]: JSON.stringify([...selected, validated]),
1137
+ [attributes.findingsText]: answer
1278
1138
  }
1279
1139
  };
1280
1140
  }
1281
- var HTML_ATTRIBUTE2 = "encounterNarrativeHtml";
1282
- var TEXT_ATTRIBUTE2 = "encounterNarrativeText";
1283
- var FINDINGS_ATTRIBUTE2 = "encounterNarrativeFindings";
1284
- var FINDINGS_TEXT_ATTRIBUTE2 = "encounterNarrativeFindingsText";
1285
- function sanitizeEncounterNarrativeHtml(html) {
1141
+ function sanitizeNarrativeHtml(html) {
1286
1142
  return DOMPurify__default.default.sanitize(html, {
1287
1143
  ALLOWED_TAGS: [
1288
1144
  "p",
@@ -1309,9 +1165,9 @@ function sanitizeEncounterNarrativeHtml(html) {
1309
1165
  function textToHtml(text) {
1310
1166
  return text.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#39;").replace(/\n/g, "<br>");
1311
1167
  }
1312
- function encounterNarrativeText(html) {
1168
+ function narrativeText(html) {
1313
1169
  const documentBody = document.createElement("div");
1314
- documentBody.innerHTML = sanitizeEncounterNarrativeHtml(html);
1170
+ documentBody.innerHTML = sanitizeNarrativeHtml(html);
1315
1171
  let text = "";
1316
1172
  const lineBreak = () => {
1317
1173
  if (text && !text.endsWith("\n")) text += "\n";
@@ -1349,12 +1205,12 @@ function encounterNarrativeText(html) {
1349
1205
  documentBody.childNodes.forEach(visit);
1350
1206
  return text.replace(/\u00a0/g, " ").replace(/\n$/, "");
1351
1207
  }
1352
- function responseHtml(response) {
1208
+ function responseHtml(response, attributes) {
1353
1209
  const answer = response?.answer ?? "";
1354
- const attributes = response?.attributes;
1355
- if (typeof window !== "undefined" && attributes?.[TEXT_ATTRIBUTE2] === answer && typeof attributes[HTML_ATTRIBUTE2] === "string") {
1356
- const html = sanitizeEncounterNarrativeHtml(attributes[HTML_ATTRIBUTE2]);
1357
- if (encounterNarrativeText(html) === answer) return html;
1210
+ const responseAttributes = response?.attributes;
1211
+ if (typeof window !== "undefined" && responseAttributes?.[attributes.text] === answer && typeof responseAttributes[attributes.html] === "string") {
1212
+ const html = sanitizeNarrativeHtml(responseAttributes[attributes.html]);
1213
+ if (narrativeText(html) === answer) return html;
1358
1214
  }
1359
1215
  return textToHtml(answer);
1360
1216
  }
@@ -1371,7 +1227,7 @@ function findingShortcuts(findings) {
1371
1227
  }
1372
1228
  return shortcuts;
1373
1229
  }
1374
- function EncounterNarrativeField({
1230
+ function EsheetNarrativeField({
1375
1231
  field,
1376
1232
  response,
1377
1233
  isPreview,
@@ -1379,7 +1235,11 @@ function EncounterNarrativeField({
1379
1235
  isReadOnly,
1380
1236
  isRequired,
1381
1237
  isSoftRequired,
1382
- onResponse
1238
+ onResponse,
1239
+ attributes = NARRATIVE_ATTRIBUTES,
1240
+ findingsKey = "narrativeFindings",
1241
+ hideLabelKey = "narrativeHideLabel",
1242
+ slot = "esheet-narrative"
1383
1243
  }) {
1384
1244
  const m = chunkFSLI5IKP_cjs.useMessages();
1385
1245
  const editorRef = React11__namespace.useRef(null);
@@ -1389,9 +1249,12 @@ function EncounterNarrativeField({
1389
1249
  const definition = field.definition;
1390
1250
  const question = definition.question || m("Narrative");
1391
1251
  const readOnly = !isPreview || !isEnabled || isReadOnly;
1392
- const html = React11__namespace.useMemo(() => responseHtml(response), [response]);
1393
- const findings = validEncounterNarrativeFindings(
1394
- definition._sourceData?.encounterFindings
1252
+ const html = React11__namespace.useMemo(
1253
+ () => responseHtml(response, attributes),
1254
+ [response, attributes]
1255
+ );
1256
+ const findings = validNarrativeFindings(
1257
+ definition._sourceData?.[findingsKey]
1395
1258
  );
1396
1259
  const shortcuts = findingShortcuts(findings);
1397
1260
  const macros = findings.length ? [
@@ -1407,18 +1270,23 @@ function EncounterNarrativeField({
1407
1270
  }
1408
1271
  ] : void 0;
1409
1272
  const publish = (value, previous, selected) => {
1410
- const sanitized = sanitizeEncounterNarrativeHtml(value);
1411
- const answer = encounterNarrativeText(sanitized);
1412
- const attributes = {
1273
+ const sanitized = sanitizeNarrativeHtml(value);
1274
+ const answer = narrativeText(sanitized);
1275
+ const nextAttributes = {
1413
1276
  ...previous?.attributes,
1414
- [HTML_ATTRIBUTE2]: sanitized,
1415
- [TEXT_ATTRIBUTE2]: answer,
1416
- ...selected.length || previous?.attributes?.[FINDINGS_ATTRIBUTE2] !== void 0 ? {
1417
- [FINDINGS_ATTRIBUTE2]: JSON.stringify(selected),
1418
- [FINDINGS_TEXT_ATTRIBUTE2]: answer
1277
+ [attributes.html]: sanitized,
1278
+ [attributes.text]: answer,
1279
+ ...selected.length || previous?.attributes?.[attributes.findings] !== void 0 ? {
1280
+ [attributes.findings]: JSON.stringify(selected),
1281
+ [attributes.findingsText]: answer
1419
1282
  } : {}
1420
1283
  };
1421
- const next = { ...previous, answer, _ai: false, attributes };
1284
+ const next = {
1285
+ ...previous,
1286
+ answer,
1287
+ _ai: false,
1288
+ attributes: nextAttributes
1289
+ };
1422
1290
  delete next.selected;
1423
1291
  responseRef.current = next;
1424
1292
  onResponse(next);
@@ -1432,12 +1300,12 @@ function EncounterNarrativeField({
1432
1300
  String(isRequired || isSoftRequired)
1433
1301
  );
1434
1302
  }, [isRequired, isSoftRequired, labelId, readOnly]);
1435
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-slot": "encounter-narrative", className: "min-w-0", children: [
1303
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-slot": slot, className: "min-w-0", children: [
1436
1304
  /* @__PURE__ */ jsxRuntime.jsxs(
1437
1305
  "div",
1438
1306
  {
1439
1307
  id: labelId,
1440
- className: definition._sourceData?.encounterHideLabel ? "sr-only" : "text-muted-foreground text-sm font-medium",
1308
+ className: definition._sourceData?.[hideLabelKey] ? "sr-only" : "text-muted-foreground text-sm font-medium",
1441
1309
  children: [
1442
1310
  question,
1443
1311
  definition.unit && ` (${definition.unit})`,
@@ -1446,20 +1314,20 @@ function EncounterNarrativeField({
1446
1314
  }
1447
1315
  ),
1448
1316
  /* @__PURE__ */ jsxRuntime.jsx(
1449
- chunk2Z2GFDRS_cjs.TextAreaRich,
1317
+ chunkDXNVQQYN_cjs.TextAreaRich,
1450
1318
  {
1451
1319
  ref: editorRef,
1452
1320
  value: html,
1453
1321
  onChange: (value) => {
1454
1322
  if (readOnly) return;
1455
- const sanitized = sanitizeEncounterNarrativeHtml(value);
1456
- const answer = encounterNarrativeText(sanitized);
1323
+ const sanitized = sanitizeNarrativeHtml(value);
1324
+ const answer = narrativeText(sanitized);
1457
1325
  const previous = responseRef.current;
1458
1326
  publish(
1459
1327
  sanitized,
1460
1328
  previous,
1461
- getEncounterNarrativeFindings(previous).filter(
1462
- (finding) => hasEncounterNarrativeFindingText(answer, finding.text)
1329
+ getNarrativeFindings(previous, attributes).filter(
1330
+ (finding) => hasNarrativeFindingText(answer, finding.text)
1463
1331
  )
1464
1332
  );
1465
1333
  },
@@ -1467,14 +1335,11 @@ function EncounterNarrativeField({
1467
1335
  const finding = findings.find((item) => item.id === macro.id);
1468
1336
  if (!finding || readOnly) return true;
1469
1337
  const previous = responseRef.current;
1470
- const next = applyEncounterNarrativeFinding(previous, finding);
1338
+ const next = applyNarrativeFinding(previous, finding, attributes);
1471
1339
  if (next === previous) return true;
1472
1340
  const answer = previous?.answer ?? "";
1473
- const nextHtml = hasEncounterNarrativeFindingText(
1474
- answer,
1475
- finding.text
1476
- ) ? responseHtml(previous) : `${answer.trim() ? responseHtml(previous) : ""}<p>${textToHtml(finding.text)}</p>`;
1477
- publish(nextHtml, previous, getEncounterNarrativeFindings(next));
1341
+ const nextHtml = hasNarrativeFindingText(answer, finding.text) ? responseHtml(previous, attributes) : `${answer.trim() ? responseHtml(previous, attributes) : ""}<p>${textToHtml(finding.text)}</p>`;
1342
+ publish(nextHtml, previous, getNarrativeFindings(next, attributes));
1478
1343
  return true;
1479
1344
  },
1480
1345
  "aria-label": question,
@@ -1512,17 +1377,58 @@ function EncounterNarrativeField({
1512
1377
  showToolbar: m("Show toolbar"),
1513
1378
  hideToolbar: m("Hide toolbar")
1514
1379
  },
1515
- sanitizeHtml: sanitizeEncounterNarrativeHtml,
1380
+ sanitizeHtml: sanitizeNarrativeHtml,
1516
1381
  className: "mt-1"
1517
1382
  }
1518
1383
  )
1519
1384
  ] });
1520
1385
  }
1386
+ function registerEsheetNarrativeFieldType() {
1387
+ if (fields.getFieldComponent("esheetNarrative")) return;
1388
+ fields.registerCustomFieldTypes({
1389
+ esheetNarrative: {
1390
+ label: "Narrative",
1391
+ category: "rich",
1392
+ answerType: "text",
1393
+ hasOptions: false,
1394
+ hasMatrix: false,
1395
+ defaultProps: { question: "Narrative" },
1396
+ component: EsheetNarrativeField
1397
+ }
1398
+ });
1399
+ }
1400
+
1401
+ // src/components/EncounterVisit/narrativeFindings.ts
1402
+ var ENCOUNTER_NARRATIVE_ATTRIBUTES = {
1403
+ html: "encounterNarrativeHtml",
1404
+ text: "encounterNarrativeText",
1405
+ findings: "encounterNarrativeFindings",
1406
+ findingsText: "encounterNarrativeFindingsText"
1407
+ };
1408
+ function applyEncounterNarrativeFinding(response, finding) {
1409
+ return applyNarrativeFinding(
1410
+ response,
1411
+ finding,
1412
+ ENCOUNTER_NARRATIVE_ATTRIBUTES
1413
+ );
1414
+ }
1415
+ function EncounterNarrativeField(props) {
1416
+ return /* @__PURE__ */ jsxRuntime.jsx(
1417
+ EsheetNarrativeField,
1418
+ {
1419
+ ...props,
1420
+ attributes: ENCOUNTER_NARRATIVE_ATTRIBUTES,
1421
+ findingsKey: "encounterFindings",
1422
+ hideLabelKey: "encounterHideLabel",
1423
+ slot: "encounter-narrative"
1424
+ }
1425
+ );
1426
+ }
1521
1427
  function readValue(answer) {
1522
1428
  if (!answer) return { value: { medications: [] } };
1523
1429
  try {
1524
1430
  const value = JSON.parse(answer);
1525
- if (chunkM42FTWY2_cjs.validateEncounterMedicationValue(value).length) throw new Error();
1431
+ if (chunk46RYJYN2_cjs.validateEncounterMedicationValue(value).length) throw new Error();
1526
1432
  return { value };
1527
1433
  } catch {
1528
1434
  return {
@@ -1531,360 +1437,46 @@ function readValue(answer) {
1531
1437
  };
1532
1438
  }
1533
1439
  }
1534
- function parseAnswerDate(value) {
1535
- const match = /^(\d{4})-(\d{2})-(\d{2})$/.exec(value ?? "");
1536
- return match ? new Date(Number(match[1]), Number(match[2]) - 1, Number(match[3])) : null;
1537
- }
1538
- function toAnswerDate(date) {
1539
- if (!date) return void 0;
1540
- const pad = (part) => String(part).padStart(2, "0");
1541
- return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}`;
1542
- }
1543
- function MedicationCard({
1544
- index,
1545
- medication,
1546
- readOnly,
1547
- requireCoding,
1548
- codeLookup,
1549
- onPatch,
1550
- onRemove
1440
+ function EncounterMedicationField({
1441
+ field,
1442
+ form,
1443
+ response,
1444
+ isPreview,
1445
+ isEnabled,
1446
+ isReadOnly,
1447
+ onResponse
1551
1448
  }) {
1552
- const m = chunkFSLI5IKP_cjs.useMessages();
1553
- const id = React11__namespace.useId();
1554
- const Lookup = codeLookup?.component;
1555
- const text = (value) => value.trim() && value;
1556
- return /* @__PURE__ */ jsxRuntime.jsxs("fieldset", { className: clinicalEntryCardClasses, children: [
1557
- /* @__PURE__ */ jsxRuntime.jsx("legend", { className: "sr-only", children: m("Medication {number}", { number: index }) }),
1558
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between gap-2", children: [
1559
- /* @__PURE__ */ jsxRuntime.jsx("h4", { className: "font-semibold", children: m("Medication {number}", { number: index }) }),
1560
- !readOnly && /* @__PURE__ */ jsxRuntime.jsx(
1561
- chunkFSARTLUE_cjs.Button,
1562
- {
1563
- type: "button",
1564
- variant: "ghost",
1565
- size: "icon",
1566
- className: "shrink-0",
1567
- "aria-label": m("Remove medication {number}", { number: index }),
1568
- onClick: onRemove,
1569
- children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Trash2, { className: "h-4 w-4", "aria-hidden": "true" })
1570
- }
1571
- )
1572
- ] }),
1573
- !readOnly && Lookup && codeLookup ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1.5", children: [
1574
- /* @__PURE__ */ jsxRuntime.jsx(
1575
- Lookup,
1576
- {
1577
- indexUrl: codeLookup.indexUrl,
1578
- locale: codeLookup.locale,
1579
- domains: ["med"],
1580
- bare: true,
1581
- clearOnSelect: false,
1582
- initialQuery: medication.name || void 0,
1583
- initialSearch: false,
1584
- "aria-label": m("Medication"),
1585
- placeholder: m("Search RxNorm / FDB \u2014 e.g. lisinopril"),
1586
- onSelect: (pick) => {
1587
- if (requireCoding && (!pick.codetype.trim() || !pick.fullcode.trim()))
1588
- return;
1589
- onPatch(chunkSCYLVQWA_cjs.lookupToMedicationFields(pick));
1590
- },
1591
- onFreeText: requireCoding ? void 0 : (name) => {
1592
- if (name.trim()) onPatch({ name, code: void 0 });
1593
- }
1594
- }
1595
- ),
1596
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-muted-foreground text-xs", children: medication.code ? m("Coded: {system} {code}", {
1597
- system: medication.code.system,
1598
- code: medication.code.code
1599
- }) : medication.name ? m('Uncoded free text: "{name}" \u2014 pick a result to code it', {
1600
- name: medication.name
1601
- }) : requireCoding ? m("Pick a catalog result to code the medication") : m(
1602
- "Pick a result to code the medication, or press Enter for free text"
1603
- ) })
1604
- ] }) : /* @__PURE__ */ jsxRuntime.jsx(
1605
- chunkZ5S5JEJD_cjs.Input,
1606
- {
1607
- label: m("Medication"),
1608
- className: "min-h-11",
1609
- value: medication.name,
1610
- readOnly: readOnly || requireCoding,
1611
- onChange: (event) => {
1612
- if (event.target.value.trim())
1613
- onPatch({ name: event.target.value, code: void 0 });
1614
- }
1615
- }
1616
- ),
1617
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 gap-3 sm:grid-cols-3", children: [
1618
- /* @__PURE__ */ jsxRuntime.jsx(
1619
- chunkZ5S5JEJD_cjs.Input,
1620
- {
1621
- label: m("Strength"),
1622
- className: "min-h-11",
1623
- value: medication.strength ?? "",
1624
- readOnly,
1625
- onChange: (event) => onPatch({ strength: text(event.target.value) || void 0 })
1626
- }
1627
- ),
1628
- /* @__PURE__ */ jsxRuntime.jsx(
1629
- chunkZ5S5JEJD_cjs.Input,
1630
- {
1631
- label: m("Dose form"),
1632
- className: "min-h-11",
1633
- value: medication.doseForm ?? "",
1634
- readOnly,
1635
- onChange: (event) => (
1636
- // Quantity unit follows the dose form (tablet → tablet,
1637
- // solution → milliliter, …)
1638
- onPatch({
1639
- doseForm: event.target.value || void 0,
1640
- quantityUnit: chunkSCYLVQWA_cjs.doseFormToQuantityUnit(event.target.value)
1641
- })
1642
- )
1643
- }
1644
- ),
1645
- /* @__PURE__ */ jsxRuntime.jsx(
1646
- chunkZ5S5JEJD_cjs.Input,
1647
- {
1648
- label: medication.quantityUnit ? `${m("Quantity")} (${medication.quantityUnit}s)` : m("Quantity"),
1649
- className: "min-h-11",
1650
- inputMode: "decimal",
1651
- value: medication.quantity ?? "",
1652
- readOnly,
1653
- onChange: (event) => onPatch({ quantity: text(event.target.value) || void 0 })
1654
- }
1655
- )
1656
- ] }),
1657
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 gap-3 sm:grid-cols-3", children: [
1658
- /* @__PURE__ */ jsxRuntime.jsx(
1659
- chunkZ5S5JEJD_cjs.Input,
1660
- {
1661
- label: m("Days supply"),
1662
- className: "min-h-11",
1663
- inputMode: "numeric",
1664
- value: medication.daysSupply ?? "",
1665
- readOnly,
1666
- onChange: (event) => onPatch({ daysSupply: text(event.target.value) || void 0 })
1667
- }
1668
- ),
1669
- /* @__PURE__ */ jsxRuntime.jsx(
1670
- chunkZ5S5JEJD_cjs.Input,
1671
- {
1672
- label: m("Refills"),
1673
- className: "min-h-11",
1674
- inputMode: "numeric",
1675
- value: medication.refills ?? "",
1676
- readOnly,
1677
- onChange: (event) => onPatch({ refills: text(event.target.value) || void 0 })
1678
- }
1679
- ),
1680
- readOnly ? /* @__PURE__ */ jsxRuntime.jsx(
1681
- chunkZ5S5JEJD_cjs.Input,
1682
- {
1683
- label: m("Start \u2013 end date"),
1684
- className: "min-h-11",
1685
- value: [medication.startDate, medication.endDate].filter(Boolean).join(" \u2013 "),
1686
- readOnly: true
1687
- }
1688
- ) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0 space-y-1.5", children: [
1689
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-foreground block text-sm font-medium", children: m("Start \u2013 end date") }),
1690
- /* @__PURE__ */ jsxRuntime.jsx(
1691
- chunkSCYLVQWA_cjs.DateRangePicker,
1692
- {
1693
- className: "w-full [&_[data-slot=date-range-trigger]]:min-h-11 [&_[data-slot=date-range-trigger]]:w-full",
1694
- variant: "responsive",
1695
- showPresets: false,
1696
- placeholder: m("Start \u2013 end date"),
1697
- value: {
1698
- start: parseAnswerDate(medication.startDate),
1699
- end: parseAnswerDate(medication.endDate)
1700
- },
1701
- onChange: (range) => onPatch({
1702
- startDate: toAnswerDate(range.start),
1703
- endDate: toAnswerDate(range.end)
1704
- })
1705
- }
1706
- )
1707
- ] })
1708
- ] }),
1709
- /* @__PURE__ */ jsxRuntime.jsxs(
1710
- chunkG7EQ3JPX_cjs.RadioGroup,
1711
- {
1712
- name: `${id}-substitution`,
1713
- label: m("Substitution"),
1714
- value: medication.substitution ?? "0",
1715
- onValueChange: (value) => {
1716
- if (!readOnly) onPatch({ substitution: value });
1717
- },
1718
- orientation: "horizontal",
1719
- size: "sm",
1720
- disabled: readOnly,
1721
- children: [
1722
- /* @__PURE__ */ jsxRuntime.jsx(chunkG7EQ3JPX_cjs.Radio, { value: "0", label: m("Substitution permitted") }),
1723
- /* @__PURE__ */ jsxRuntime.jsx(chunkG7EQ3JPX_cjs.Radio, { value: "1", label: m("Dispense as written (DAW)") })
1724
- ]
1725
- }
1726
- ),
1727
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1.5", children: [
1728
- /* @__PURE__ */ jsxRuntime.jsx(chunkAIJAFPGJ_cjs.Label, { htmlFor: `${id}-sig`, children: m("Sig (patient directions)") }),
1729
- /* @__PURE__ */ jsxRuntime.jsx(
1730
- chunk2Z2GFDRS_cjs.Textarea,
1731
- {
1732
- id: `${id}-sig`,
1733
- rows: 2,
1734
- value: medication.sig ?? "",
1735
- readOnly,
1736
- onChange: (event) => {
1737
- const sig = event.target.value;
1738
- const { route, frequency, prn } = chunkSCYLVQWA_cjs.parseSig(sig);
1739
- onPatch({ sig, route, frequency, prn: prn || void 0 });
1740
- }
1741
- }
1742
- ),
1743
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-muted-foreground text-xs", "aria-live": "polite", children: medication.route || medication.frequency || medication.prn ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1744
- m("Derived:"),
1745
- " ",
1746
- [
1747
- medication.route && m("route {route}", { route: medication.route }),
1748
- medication.frequency && m(medication.frequency.toLowerCase()),
1749
- medication.prn && m("PRN (as needed)")
1750
- ].filter(Boolean).join(" \xB7 ")
1751
- ] }) : m("Route, frequency, and PRN are derived from the directions") })
1752
- ] }),
1753
- /* @__PURE__ */ jsxRuntime.jsx(
1754
- chunkZ5S5JEJD_cjs.Input,
1755
- {
1756
- label: m("Indication"),
1757
- className: "min-h-11",
1758
- value: medication.indication ?? "",
1759
- readOnly,
1760
- onChange: (event) => onPatch({ indication: text(event.target.value) || void 0 })
1761
- }
1762
- ),
1763
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1.5", children: [
1764
- /* @__PURE__ */ jsxRuntime.jsx(chunkAIJAFPGJ_cjs.Label, { htmlFor: `${id}-pharmacy-notes`, children: m("Pharmacy notes") }),
1765
- /* @__PURE__ */ jsxRuntime.jsx(
1766
- chunk2Z2GFDRS_cjs.Textarea,
1767
- {
1768
- id: `${id}-pharmacy-notes`,
1769
- rows: 2,
1770
- value: medication.pharmacyNotes ?? "",
1771
- readOnly,
1772
- onChange: (event) => onPatch({ pharmacyNotes: event.target.value || void 0 })
1773
- }
1774
- )
1775
- ] })
1776
- ] });
1777
- }
1778
- function EncounterMedicationField({
1779
- field,
1780
- form,
1781
- response,
1782
- isPreview,
1783
- isEnabled,
1784
- isReadOnly,
1785
- onResponse
1786
- }) {
1787
- const { value, error } = React11__namespace.useMemo(
1788
- () => readValue(response?.answer),
1789
- [response?.answer]
1790
- );
1791
- const m = chunkFSLI5IKP_cjs.useMessages();
1792
- const requireCoding = clinicalRequiresCoding(field);
1793
- const codeLookup = chunkSCYLVQWA_cjs.useCodeLookupConfig();
1794
- const state = useClinicalFormState(form);
1795
- const [draft, setDraft] = React11__namespace.useState(null);
1796
- const readOnly = !(isPreview && isEnabled) || Boolean(isReadOnly) || state.readOnly || state.disposed || Boolean(error);
1797
- const canEdit = React11__namespace.useRef(!readOnly);
1798
- canEdit.current = !readOnly;
1799
- const currentValue = React11__namespace.useRef(value);
1800
- currentValue.current = value;
1801
- const definition = field.definition;
1802
- const commit = (update) => {
1803
- if (!canEdit.current || form.getState().readOnly || form.getState().disposed)
1804
- return;
1805
- const next = {
1806
- ...currentValue.current,
1807
- medications: update(currentValue.current)
1808
- };
1809
- currentValue.current = next;
1810
- onResponse(
1811
- clinicalAnswerResponse(
1812
- form.getState().responses[field.definition.id] ?? response,
1813
- JSON.stringify(next)
1449
+ const { value, error } = React11__namespace.useMemo(
1450
+ () => readValue(response?.answer),
1451
+ [response?.answer]
1452
+ );
1453
+ const state = useClinicalFormState(form);
1454
+ const readOnly = !(isPreview && isEnabled) || Boolean(isReadOnly) || state.readOnly || state.disposed || Boolean(error);
1455
+ const canEdit = React11__namespace.useRef(!readOnly);
1456
+ canEdit.current = !readOnly;
1457
+ const currentValue = React11__namespace.useRef(value);
1458
+ currentValue.current = value;
1459
+ const commit = (medications) => {
1460
+ if (!canEdit.current || form.getState().readOnly || form.getState().disposed)
1461
+ return;
1462
+ const next = { ...currentValue.current, medications };
1463
+ currentValue.current = next;
1464
+ onResponse(
1465
+ clinicalAnswerResponse(
1466
+ form.getState().responses[field.definition.id] ?? response,
1467
+ JSON.stringify(next)
1814
1468
  )
1815
1469
  );
1816
1470
  };
1817
- const patchMedication = (medication, patch) => {
1818
- if (draft && medication.id === draft.id) {
1819
- const next = { ...draft, ...patch };
1820
- if (next.name.trim()) {
1821
- setDraft(null);
1822
- commit((current) => [...current.medications, next]);
1823
- } else setDraft(next);
1824
- } else {
1825
- commit(
1826
- (current) => current.medications.map(
1827
- (candidate) => candidate.id === medication.id ? { ...candidate, ...patch } : candidate
1828
- )
1829
- );
1830
- }
1831
- };
1832
- const cards = !readOnly && draft ? [...value.medications, draft] : value.medications;
1471
+ if (error)
1472
+ return /* @__PURE__ */ jsxRuntime.jsx(InvalidClinicalAnswer, { label: "medication", answer: response?.answer });
1833
1473
  return /* @__PURE__ */ jsxRuntime.jsx(
1834
- "section",
1474
+ chunk6O6EYKOG_cjs.MedicationReconciliation,
1835
1475
  {
1836
- "aria-label": definition.question ?? m("Presenting medications"),
1837
- className: "min-w-0 space-y-3",
1838
- children: error ? /* @__PURE__ */ jsxRuntime.jsxs("div", { role: "alert", className: "text-destructive space-y-2 text-sm", children: [
1839
- /* @__PURE__ */ jsxRuntime.jsx("p", { children: m(error) }),
1840
- /* @__PURE__ */ jsxRuntime.jsx(
1841
- "pre",
1842
- {
1843
- tabIndex: 0,
1844
- "aria-label": m("Original medication answer"),
1845
- className: "max-h-48 overflow-auto text-xs break-all whitespace-pre-wrap",
1846
- children: response?.answer
1847
- }
1848
- )
1849
- ] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1850
- !readOnly && requireCoding && !codeLookup && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-muted-foreground text-sm", children: m(
1851
- "Connect a medication terminology catalog to add coded medications."
1852
- ) }),
1853
- requireCoding && value.medications.some((medication) => !medication.code) && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-muted-foreground text-sm", children: m(
1854
- "Imported medications without a code are retained. Pick a catalog result to code them."
1855
- ) }),
1856
- readOnly && value.medications.length === 0 && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-muted-foreground text-sm", children: m("No medications recorded.") }),
1857
- cards.map((medication, index) => /* @__PURE__ */ jsxRuntime.jsx(
1858
- MedicationCard,
1859
- {
1860
- index: index + 1,
1861
- medication,
1862
- readOnly,
1863
- requireCoding,
1864
- codeLookup,
1865
- onPatch: (patch) => patchMedication(medication, patch),
1866
- onRemove: () => {
1867
- if (draft && medication.id === draft.id) setDraft(null);
1868
- else
1869
- commit(
1870
- (current) => current.medications.filter(({ id }) => id !== medication.id)
1871
- );
1872
- }
1873
- },
1874
- medication.id
1875
- )),
1876
- !readOnly && !draft && (codeLookup || !requireCoding) && /* @__PURE__ */ jsxRuntime.jsx(
1877
- ClinicalAddButton,
1878
- {
1879
- label: cards.length > 0 ? m("Add another medication") : m("Add medication"),
1880
- onClick: () => setDraft({
1881
- id: globalThis.crypto.randomUUID(),
1882
- name: "",
1883
- status: "unreconciled"
1884
- })
1885
- }
1886
- )
1887
- ] })
1476
+ medications: value.medications,
1477
+ onChange: commit,
1478
+ inlineAddSearch: true,
1479
+ readOnly
1888
1480
  }
1889
1481
  );
1890
1482
  }
@@ -1892,7 +1484,7 @@ function readValue2(answer) {
1892
1484
  if (!answer) return { value: { allergies: [] } };
1893
1485
  try {
1894
1486
  const value = JSON.parse(answer);
1895
- if (chunkM42FTWY2_cjs.validateEncounterAllergyValue(value).length) throw new Error();
1487
+ if (chunk46RYJYN2_cjs.validateEncounterAllergyValue(value).length) throw new Error();
1896
1488
  return { value };
1897
1489
  } catch {
1898
1490
  return {
@@ -1901,201 +1493,6 @@ function readValue2(answer) {
1901
1493
  };
1902
1494
  }
1903
1495
  }
1904
- function AllergyCard({
1905
- index,
1906
- allergy,
1907
- readOnly,
1908
- requireCoding,
1909
- codeLookup,
1910
- onPatch,
1911
- onRemove
1912
- }) {
1913
- const m = chunkFSLI5IKP_cjs.useMessages();
1914
- const id = React11__namespace.useId();
1915
- const Lookup = codeLookup?.component;
1916
- const isDrug = (allergy.type ?? "drug") === "drug";
1917
- const text = (value) => value.trim() && value;
1918
- return /* @__PURE__ */ jsxRuntime.jsxs("fieldset", { className: clinicalEntryCardClasses, children: [
1919
- /* @__PURE__ */ jsxRuntime.jsx("legend", { className: "sr-only", children: m("Allergy {number}", { number: index }) }),
1920
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between gap-2", children: [
1921
- /* @__PURE__ */ jsxRuntime.jsx("h4", { className: "font-semibold", children: m("Allergy {number}", { number: index }) }),
1922
- !readOnly && /* @__PURE__ */ jsxRuntime.jsx(
1923
- chunkFSARTLUE_cjs.Button,
1924
- {
1925
- type: "button",
1926
- variant: "ghost",
1927
- size: "icon",
1928
- className: "shrink-0",
1929
- "aria-label": m("Remove allergy {number}", { number: index }),
1930
- onClick: onRemove,
1931
- children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Trash2, { className: "h-4 w-4", "aria-hidden": "true" })
1932
- }
1933
- )
1934
- ] }),
1935
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 gap-3 sm:grid-cols-3", children: [
1936
- readOnly ? /* @__PURE__ */ jsxRuntime.jsx(
1937
- chunkZ5S5JEJD_cjs.Input,
1938
- {
1939
- label: m("Type"),
1940
- className: "min-h-11",
1941
- value: m(chunkSCYLVQWA_cjs.ALLERGY_TYPE_LABELS[allergy.type ?? "drug"]),
1942
- readOnly: true
1943
- }
1944
- ) : /* @__PURE__ */ jsxRuntime.jsx(
1945
- chunkUPWIJC6I_cjs.Select,
1946
- {
1947
- label: m("Type"),
1948
- className: "[&_[data-slot=select-trigger]]:min-h-11",
1949
- options: Object.keys(chunkSCYLVQWA_cjs.ALLERGY_TYPE_LABELS).map(
1950
- (type) => ({ value: type, label: m(chunkSCYLVQWA_cjs.ALLERGY_TYPE_LABELS[type]) })
1951
- ),
1952
- value: allergy.type ?? "drug",
1953
- onValueChange: (next) => {
1954
- const type = next;
1955
- onPatch({
1956
- type,
1957
- ...type !== (allergy.type ?? "drug") && { code: void 0 }
1958
- });
1959
- }
1960
- }
1961
- ),
1962
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "min-w-0 sm:col-span-2", children: !readOnly && Lookup && codeLookup && (isDrug || requireCoding) ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1.5", children: [
1963
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-foreground block text-sm font-medium", children: m("Allergen") }),
1964
- /* @__PURE__ */ jsxRuntime.jsx(
1965
- Lookup,
1966
- {
1967
- indexUrl: codeLookup.indexUrl,
1968
- locale: codeLookup.locale,
1969
- domains: isDrug ? ["med"] : ["condition"],
1970
- searchCodetypes: isDrug ? void 0 : ["SNOMED US"],
1971
- bare: true,
1972
- clearOnSelect: false,
1973
- initialQuery: allergy.allergen || void 0,
1974
- initialSearch: false,
1975
- "aria-label": m("Allergen"),
1976
- placeholder: isDrug ? m("Search drug allergens \u2014 e.g. penicillin") : m("Search SNOMED allergen substances"),
1977
- onSelect: (pick) => {
1978
- if (requireCoding && (!pick.codetype.trim() || !pick.fullcode.trim()))
1979
- return;
1980
- onPatch({
1981
- allergen: pick.label,
1982
- code: {
1983
- system: pick.codetype,
1984
- code: pick.fullcode,
1985
- display: pick.label
1986
- }
1987
- });
1988
- },
1989
- onFreeText: requireCoding ? void 0 : (allergen) => {
1990
- if (allergen.trim())
1991
- onPatch({ allergen, code: void 0 });
1992
- }
1993
- }
1994
- ),
1995
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-muted-foreground text-xs", children: allergy.code ? m("Coded: {system} {code}", {
1996
- system: allergy.code.system,
1997
- code: allergy.code.code
1998
- }) : allergy.allergen ? m(
1999
- 'Uncoded free text: "{name}" \u2014 pick a result to code it',
2000
- { name: allergy.allergen }
2001
- ) : requireCoding ? m("Pick a catalog result to code the allergen") : m(
2002
- "Pick a result to code the allergen, or press Enter for free text"
2003
- ) })
2004
- ] }) : /* @__PURE__ */ jsxRuntime.jsx(
2005
- chunkZ5S5JEJD_cjs.Input,
2006
- {
2007
- label: m("Allergen"),
2008
- className: "min-h-11",
2009
- value: allergy.allergen,
2010
- readOnly: readOnly || requireCoding,
2011
- onChange: (event) => {
2012
- if (event.target.value.trim())
2013
- onPatch({ allergen: event.target.value, code: void 0 });
2014
- }
2015
- }
2016
- ) })
2017
- ] }),
2018
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 gap-3 sm:grid-cols-2", children: [
2019
- /* @__PURE__ */ jsxRuntime.jsx(
2020
- chunkZ5S5JEJD_cjs.Input,
2021
- {
2022
- label: m("Reaction"),
2023
- className: "min-h-11",
2024
- value: allergy.reaction ?? "",
2025
- readOnly,
2026
- onChange: (event) => onPatch({ reaction: text(event.target.value) || void 0 })
2027
- }
2028
- ),
2029
- /* @__PURE__ */ jsxRuntime.jsx(
2030
- chunkPHUTJKHL_cjs.DateInput,
2031
- {
2032
- label: m("Onset date"),
2033
- className: "min-h-11",
2034
- value: allergy.onsetDate ?? "",
2035
- onChange: (next) => {
2036
- if (!readOnly) onPatch({ onsetDate: next || void 0 });
2037
- }
2038
- }
2039
- )
2040
- ] }),
2041
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 gap-3 sm:grid-cols-2", children: [
2042
- /* @__PURE__ */ jsxRuntime.jsxs(
2043
- chunkG7EQ3JPX_cjs.RadioGroup,
2044
- {
2045
- name: `${id}-kind`,
2046
- label: m("Mechanism"),
2047
- description: m(
2048
- "A true immune-mediated allergy, or a non-immune intolerance (e.g. GI upset)"
2049
- ),
2050
- value: allergy.kind ?? "allergy",
2051
- onValueChange: (next) => {
2052
- if (!readOnly) onPatch({ kind: next });
2053
- },
2054
- orientation: "horizontal",
2055
- size: "sm",
2056
- disabled: readOnly,
2057
- children: [
2058
- /* @__PURE__ */ jsxRuntime.jsx(chunkG7EQ3JPX_cjs.Radio, { value: "allergy", label: m("Allergy") }),
2059
- /* @__PURE__ */ jsxRuntime.jsx(chunkG7EQ3JPX_cjs.Radio, { value: "intolerance", label: m("Intolerance") })
2060
- ]
2061
- }
2062
- ),
2063
- /* @__PURE__ */ jsxRuntime.jsxs(
2064
- chunkG7EQ3JPX_cjs.RadioGroup,
2065
- {
2066
- name: `${id}-severity`,
2067
- label: m("Severity"),
2068
- value: allergy.severity ?? "",
2069
- onValueChange: (next) => {
2070
- if (!readOnly)
2071
- onPatch({ severity: next || void 0 });
2072
- },
2073
- orientation: "horizontal",
2074
- size: "sm",
2075
- disabled: readOnly,
2076
- children: [
2077
- /* @__PURE__ */ jsxRuntime.jsx(chunkG7EQ3JPX_cjs.Radio, { value: "mild", label: m("Mild") }),
2078
- /* @__PURE__ */ jsxRuntime.jsx(chunkG7EQ3JPX_cjs.Radio, { value: "moderate", label: m("Moderate") }),
2079
- /* @__PURE__ */ jsxRuntime.jsx(chunkG7EQ3JPX_cjs.Radio, { value: "severe", label: m("Severe") })
2080
- ]
2081
- }
2082
- )
2083
- ] }),
2084
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1.5", children: [
2085
- /* @__PURE__ */ jsxRuntime.jsx(chunkAIJAFPGJ_cjs.Label, { htmlFor: `${id}-note`, children: m("Note") }),
2086
- /* @__PURE__ */ jsxRuntime.jsx(
2087
- chunk2Z2GFDRS_cjs.Textarea,
2088
- {
2089
- id: `${id}-note`,
2090
- rows: 2,
2091
- value: allergy.note ?? "",
2092
- readOnly,
2093
- onChange: (event) => onPatch({ note: event.target.value || void 0 })
2094
- }
2095
- )
2096
- ] })
2097
- ] });
2098
- }
2099
1496
  function EncounterAllergyField({
2100
1497
  field,
2101
1498
  form,
@@ -2109,17 +1506,12 @@ function EncounterAllergyField({
2109
1506
  () => readValue2(response?.answer),
2110
1507
  [response?.answer]
2111
1508
  );
2112
- const m = chunkFSLI5IKP_cjs.useMessages();
2113
- const requireCoding = clinicalRequiresCoding(field);
2114
- const codeLookup = chunkSCYLVQWA_cjs.useCodeLookupConfig();
2115
1509
  const state = useClinicalFormState(form);
2116
- const [draft, setDraft] = React11__namespace.useState(null);
2117
1510
  const readOnly = !(isPreview && isEnabled) || Boolean(isReadOnly) || state.readOnly || state.disposed || Boolean(error);
2118
1511
  const canEdit = React11__namespace.useRef(!readOnly);
2119
1512
  canEdit.current = !readOnly;
2120
1513
  const currentValue = React11__namespace.useRef(value);
2121
1514
  currentValue.current = value;
2122
- const definition = field.definition;
2123
1515
  const commitValue = (update) => {
2124
1516
  if (!canEdit.current || form.getState().readOnly || form.getState().disposed)
2125
1517
  return;
@@ -2132,97 +1524,25 @@ function EncounterAllergyField({
2132
1524
  )
2133
1525
  );
2134
1526
  };
2135
- const commit = (update) => commitValue((current) => {
2136
- const allergies = update(current);
2137
- return {
2138
- ...current,
2139
- allergies,
2140
- // Any recorded allergy clears the no-known-allergies flag.
2141
- noKnownAllergies: allergies.length > 0 ? void 0 : current.noKnownAllergies
2142
- };
2143
- });
2144
- const patchAllergy = (allergy, patch) => {
2145
- if (draft && allergy.id === draft.id) {
2146
- const next = { ...draft, ...patch };
2147
- if (next.allergen.trim()) {
2148
- setDraft(null);
2149
- commit((current) => [...current.allergies, next]);
2150
- } else setDraft(next);
2151
- } else {
2152
- commit(
2153
- (current) => current.allergies.map(
2154
- (candidate) => candidate.id === allergy.id ? { ...candidate, ...patch } : candidate
2155
- )
2156
- );
2157
- }
2158
- };
2159
- const cards = !readOnly && draft ? [...value.allergies, draft] : value.allergies;
1527
+ if (error)
1528
+ return /* @__PURE__ */ jsxRuntime.jsx(InvalidClinicalAnswer, { label: "allergy", answer: response?.answer });
2160
1529
  return /* @__PURE__ */ jsxRuntime.jsx(
2161
- "section",
1530
+ chunk6O6EYKOG_cjs.AllergyManager,
2162
1531
  {
2163
- "aria-label": definition.question ?? m("Allergies and intolerances"),
2164
- className: "min-w-0 space-y-3",
2165
- children: error ? /* @__PURE__ */ jsxRuntime.jsxs("div", { role: "alert", className: "text-destructive space-y-2 text-sm", children: [
2166
- /* @__PURE__ */ jsxRuntime.jsx("p", { children: m(error) }),
2167
- /* @__PURE__ */ jsxRuntime.jsx(
2168
- "pre",
2169
- {
2170
- tabIndex: 0,
2171
- "aria-label": m("Original allergy answer"),
2172
- className: "max-h-48 overflow-auto text-xs break-all whitespace-pre-wrap",
2173
- children: response?.answer
2174
- }
2175
- )
2176
- ] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2177
- !readOnly && requireCoding && !codeLookup && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-muted-foreground text-sm", children: m(
2178
- "Connect an allergen terminology catalog to add coded allergies."
2179
- ) }),
2180
- requireCoding && value.allergies.some((allergy) => !allergy.code) && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-muted-foreground text-sm", children: m(
2181
- "Imported allergies without a code are retained. Pick a catalog result to code them."
2182
- ) }),
2183
- readOnly && value.allergies.length === 0 && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-muted-foreground text-sm", children: value.noKnownAllergies ? m("No known allergies (NKA).") : m("No allergies recorded.") }),
2184
- cards.map((allergy, index) => /* @__PURE__ */ jsxRuntime.jsx(
2185
- AllergyCard,
2186
- {
2187
- index: index + 1,
2188
- allergy,
2189
- readOnly,
2190
- requireCoding,
2191
- codeLookup,
2192
- onPatch: (patch) => patchAllergy(allergy, patch),
2193
- onRemove: () => {
2194
- if (draft && allergy.id === draft.id) setDraft(null);
2195
- else
2196
- commit(
2197
- (current) => current.allergies.filter(({ id }) => id !== allergy.id)
2198
- );
2199
- }
2200
- },
2201
- allergy.id
2202
- )),
2203
- !readOnly && value.allergies.length === 0 && !draft && /* @__PURE__ */ jsxRuntime.jsx(
2204
- chunk7AECNMYV_cjs.Checkbox,
2205
- {
2206
- label: m("No known allergies (NKA)"),
2207
- checked: value.noKnownAllergies ?? false,
2208
- onChange: (event) => commitValue((current) => ({
2209
- ...current,
2210
- noKnownAllergies: event.target.checked
2211
- }))
2212
- }
2213
- ),
2214
- !readOnly && !draft && (codeLookup || !requireCoding) && /* @__PURE__ */ jsxRuntime.jsx(
2215
- ClinicalAddButton,
2216
- {
2217
- label: cards.length > 0 ? m("Add another allergy") : m("Add allergy"),
2218
- onClick: () => setDraft({
2219
- id: globalThis.crypto.randomUUID(),
2220
- allergen: "",
2221
- type: "drug"
2222
- })
2223
- }
2224
- )
2225
- ] })
1532
+ allergies: value.allergies,
1533
+ onChange: (allergies) => commitValue((current) => ({
1534
+ ...current,
1535
+ allergies,
1536
+ // Any recorded allergy clears the no-known-allergies flag.
1537
+ noKnownAllergies: allergies.length > 0 ? void 0 : current.noKnownAllergies
1538
+ })),
1539
+ noKnownAllergies: value.noKnownAllergies ?? false,
1540
+ onNoKnownAllergiesChange: (noKnownAllergies) => commitValue((current) => ({
1541
+ ...current,
1542
+ noKnownAllergies: current.allergies.length > 0 ? void 0 : noKnownAllergies
1543
+ })),
1544
+ inlineAddSearch: true,
1545
+ readOnly
2226
1546
  }
2227
1547
  );
2228
1548
  }
@@ -2230,7 +1550,7 @@ function readConditions(answer) {
2230
1550
  if (!answer) return { concerns: [] };
2231
1551
  try {
2232
1552
  const parsed = JSON.parse(answer);
2233
- if (!parsed || typeof parsed !== "object" || Array.isArray(parsed) || !("concerns" in parsed) || chunkM42FTWY2_cjs.validateEncounterConditions(parsed).length > 0)
1553
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed) || !("concerns" in parsed) || chunk46RYJYN2_cjs.validateEncounterConditions(parsed).length > 0)
2234
1554
  return void 0;
2235
1555
  return parsed;
2236
1556
  } catch {
@@ -2251,14 +1571,11 @@ function EncounterConditionsField({
2251
1571
  [response?.answer]
2252
1572
  );
2253
1573
  const m = chunkFSLI5IKP_cjs.useMessages();
2254
- const requireCoding = clinicalRequiresCoding(field);
1574
+ const codeLookup = chunk6O6EYKOG_cjs.useCodeLookupConfig();
2255
1575
  const assertionDate = useEncounterAssertionDate(field);
2256
1576
  const currentDate = React11__namespace.useRef(assertionDate);
2257
1577
  currentDate.current = assertionDate;
2258
- const [adding, setAdding] = React11__namespace.useState(false);
2259
- const [manualEditing, setManualEditing] = React11__namespace.useState(false);
2260
1578
  const state = useClinicalFormState(form);
2261
- const codeLookup = chunkSCYLVQWA_cjs.useCodeLookupConfig();
2262
1579
  const readOnly = !(isPreview && isEnabled) || Boolean(isReadOnly) || state.readOnly || state.disposed || !value;
2263
1580
  const currentValue = React11__namespace.useRef(value);
2264
1581
  const currentResponse = React11__namespace.useRef(response);
@@ -2266,211 +1583,210 @@ function EncounterConditionsField({
2266
1583
  const canEdit = React11__namespace.useRef(!readOnly);
2267
1584
  currentValue.current = value;
2268
1585
  canEdit.current = !readOnly;
2269
- const [editing, setEditing] = React11__namespace.useState(
2270
- null
2271
- );
2272
- const definition = field.definition;
2273
- const label = definition.question ?? m("Conditions");
1586
+ const [editor, setEditor] = React11__namespace.useState(null);
2274
1587
  const commit = (update) => {
2275
1588
  if (!canEdit.current || form.getState().readOnly || form.getState().disposed || !currentValue.current)
2276
1589
  return;
1590
+ const next = update(currentValue.current);
1591
+ currentValue.current = next;
2277
1592
  onResponse(
2278
1593
  clinicalAnswerResponse(
2279
1594
  form.getState().responses[field.definition.id] ?? currentResponse.current,
2280
- JSON.stringify(update(currentValue.current))
1595
+ JSON.stringify(next)
2281
1596
  )
2282
1597
  );
2283
1598
  };
2284
- const recordAssertion = (draft, pick) => {
2285
- if (!currentDate.current.valid || requireCoding && !draft.coding?.length)
2286
- return;
1599
+ const saveAssertion = (concernId, draft) => {
1600
+ if (!currentDate.current.valid) return;
1601
+ const assertion = {
1602
+ ...draft,
1603
+ id: globalThis.crypto.randomUUID(),
1604
+ date: currentDate.current.date
1605
+ };
2287
1606
  commit((next) => {
2288
- const assertion = {
2289
- ...draft,
2290
- id: globalThis.crypto.randomUUID(),
2291
- date: currentDate.current.date
2292
- };
2293
- if (editing)
1607
+ if (!concernId)
2294
1608
  return {
2295
1609
  ...next,
2296
- concerns: next.concerns.map(
2297
- (concern) => concern.concernId === editing.concernId ? {
2298
- ...concern,
2299
- assertions: [
2300
- ...concern.assertions,
2301
- {
2302
- ...assertion,
2303
- changeType: draft.changeType ?? "refinement",
2304
- supersedes: chunkJCO62XMU_cjs.currentAssertion(concern)?.id
2305
- }
2306
- ]
2307
- } : concern
2308
- )
1610
+ concerns: [
1611
+ ...next.concerns,
1612
+ {
1613
+ concernId: globalThis.crypto.randomUUID(),
1614
+ clinicalStatus: "active",
1615
+ source: "manuallyAdded",
1616
+ assertions: [assertion]
1617
+ }
1618
+ ]
2309
1619
  };
2310
- if (pick && next.concerns.some((concern) => matchingConditionCode(concern, pick)))
2311
- return next;
2312
1620
  return {
2313
1621
  ...next,
2314
- concerns: [
2315
- ...next.concerns,
2316
- {
2317
- concernId: globalThis.crypto.randomUUID(),
2318
- clinicalStatus: "active",
2319
- source: "manuallyAdded",
2320
- assertions: [assertion]
2321
- }
2322
- ]
1622
+ concerns: next.concerns.map((concern) => {
1623
+ if (concern.concernId !== concernId) return concern;
1624
+ const prior = chunkNCPDUJKJ_cjs.currentAssertion(concern);
1625
+ const assertions = draft.changeType === "revision" && prior ? concern.assertions.map(
1626
+ (candidate) => candidate.id === prior.id ? { ...candidate, verificationStatus: "refuted" } : candidate
1627
+ ) : concern.assertions;
1628
+ return {
1629
+ ...concern,
1630
+ assertions: [
1631
+ ...assertions,
1632
+ { ...assertion, supersedes: prior?.id }
1633
+ ]
1634
+ };
1635
+ })
2323
1636
  };
2324
1637
  });
2325
- if (canEdit.current) {
2326
- setEditing(null);
2327
- setManualEditing(false);
2328
- }
2329
1638
  };
2330
1639
  if (!value)
2331
- return /* @__PURE__ */ jsxRuntime.jsx(InvalidClinicalAnswer, { label, answer: response?.answer });
2332
- const editingConcern = editing ? value.concerns.find(({ concernId }) => concernId === editing.concernId) : void 0;
2333
- const Lookup = codeLookup?.component;
2334
- const problemList = /* @__PURE__ */ jsxRuntime.jsx(
2335
- chunkJCO62XMU_cjs.ProblemList,
1640
+ return /* @__PURE__ */ jsxRuntime.jsx(InvalidClinicalAnswer, { label: "condition", answer: response?.answer });
1641
+ const editorConcern = editor?.concernId ? value.concerns.find(({ concernId }) => concernId === editor.concernId) : void 0;
1642
+ const canAssert = assertionDate.valid;
1643
+ const addSearch = codeLookup && !readOnly && canAssert ? /* @__PURE__ */ jsxRuntime.jsx(
1644
+ codeLookup.component,
2336
1645
  {
2337
- concerns: value.concerns,
2338
- title: null,
2339
- readOnly,
2340
- actions: [
2341
- ...assertionDate.valid && (codeLookup || !requireCoding) ? ["refine"] : [],
2342
- "remove"
2343
- ],
2344
- inlineActions: true,
2345
- className: "rounded-none border-0 bg-transparent shadow-none [&_[data-slot=clinical-list-heading]]:hidden [&_button]:min-h-11 [&_button]:min-w-11 [&>[data-slot=card-content]]:space-y-2 [&>[data-slot=card-content]]:p-0",
2346
- onAction: (concern, action) => {
2347
- if (readOnly) return;
2348
- if (action === "remove") {
2349
- setEditing(
2350
- (current) => current?.concernId === concern.concernId ? null : current
2351
- );
2352
- commit((next) => ({
2353
- ...next,
2354
- concerns: next.concerns.filter(
2355
- (candidate) => candidate.concernId !== concern.concernId
2356
- )
2357
- }));
2358
- if (canEdit.current)
2359
- repairEncounterConcernReferences(
2360
- form.getState(),
2361
- concern.concernId
2362
- );
2363
- } else if (action === "refine") {
2364
- setEditing({ concernId: concern.concernId });
2365
- if (!codeLookup) setManualEditing(true);
2366
- }
1646
+ indexUrl: codeLookup.indexUrl,
1647
+ locale: codeLookup.locale,
1648
+ domains: ["condition"],
1649
+ preferCodetypes: ["ICD10"],
1650
+ bare: true,
1651
+ clearOnSelect: true,
1652
+ placeholder: m("Search conditions to add"),
1653
+ onSelect: (result) => {
1654
+ const coded = result.codetype.trim() && result.fullcode.trim();
1655
+ if (coded && (currentValue.current ?? value).concerns.some(
1656
+ (concern) => matchingConditionCode(concern, result)
1657
+ ))
1658
+ return;
1659
+ saveAssertion(void 0, {
1660
+ text: result.label,
1661
+ verificationStatus: "unconfirmed",
1662
+ ...coded ? {
1663
+ coding: [
1664
+ {
1665
+ system: result.codetype,
1666
+ code: result.fullcode,
1667
+ display: result.label,
1668
+ primary: true
1669
+ }
1670
+ ]
1671
+ } : {}
1672
+ });
2367
1673
  },
2368
- onReorder: (ids) => commit((next) => ({
2369
- ...next,
2370
- concerns: reorderClinicalEntries(
2371
- next.concerns,
2372
- ids,
2373
- ({ concernId }) => concernId
2374
- )
2375
- }))
1674
+ onFreeText: (text) => saveAssertion(void 0, {
1675
+ text,
1676
+ verificationStatus: "unconfirmed"
1677
+ })
2376
1678
  }
2377
- );
2378
- return /* @__PURE__ */ jsxRuntime.jsxs("section", { "aria-label": label, className: "min-w-0 space-y-2", children: [
2379
- !readOnly && (adding || editingConcern || value.concerns.length > 0) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: clinicalEntryCardClasses, children: [
2380
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between gap-2", children: [
2381
- /* @__PURE__ */ jsxRuntime.jsx("h4", { className: "min-w-0 font-semibold break-words", children: editingConcern ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2382
- m("Refine"),
2383
- " ",
2384
- chunkJCO62XMU_cjs.currentAssertion(editingConcern)?.text
2385
- ] }) : m("Add condition") }),
2386
- (editingConcern || value.concerns.length === 0) && /* @__PURE__ */ jsxRuntime.jsx(
2387
- chunkFSARTLUE_cjs.Button,
2388
- {
2389
- type: "button",
2390
- variant: "ghost",
2391
- size: "icon",
2392
- className: "shrink-0",
2393
- "aria-label": m("Cancel"),
2394
- onClick: () => {
2395
- setEditing(null);
2396
- setAdding(false);
2397
- setManualEditing(false);
2398
- },
2399
- children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "h-4 w-4", "aria-hidden": "true" })
1679
+ ) : void 0;
1680
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1681
+ /* @__PURE__ */ jsxRuntime.jsx(
1682
+ chunkNCPDUJKJ_cjs.ProblemList,
1683
+ {
1684
+ concerns: value.concerns,
1685
+ readOnly,
1686
+ actions: canAssert ? ["observe", "refine", "revise", "relate", "resolve", "remove"] : ["relate", "resolve", "remove"],
1687
+ onAction: (concern, action) => {
1688
+ if (action === "remove") {
1689
+ setEditor(null);
1690
+ commit((next) => ({
1691
+ ...next,
1692
+ concerns: next.concerns.filter(
1693
+ (candidate) => candidate.concernId !== concern.concernId
1694
+ )
1695
+ }));
1696
+ if (canEdit.current)
1697
+ repairEncounterConcernReferences(
1698
+ form.getState(),
1699
+ concern.concernId
1700
+ );
1701
+ } else if (action === "resolve") {
1702
+ commit((next) => ({
1703
+ ...next,
1704
+ concerns: next.concerns.map(
1705
+ (candidate) => candidate.concernId === concern.concernId ? { ...candidate, clinicalStatus: "resolved" } : candidate
1706
+ )
1707
+ }));
1708
+ } else if (action === "observe" || action === "refine" || action === "revise" || action === "relate") {
1709
+ setEditor({ mode: action, concernId: concern.concernId });
2400
1710
  }
2401
- )
2402
- ] }),
2403
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-w-0 flex-col gap-3 sm:flex-row sm:flex-wrap sm:items-end", children: [
2404
- /* @__PURE__ */ jsxRuntime.jsx(EncounterAssertionDateInput, { ...assertionDate }),
2405
- assertionDate.valid && Lookup && codeLookup && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "min-w-0 flex-1 sm:basis-56", children: /* @__PURE__ */ jsxRuntime.jsx(
2406
- Lookup,
2407
- {
2408
- indexUrl: codeLookup.indexUrl,
2409
- locale: codeLookup.locale,
2410
- domains: ["condition"],
2411
- preferCodetypes: ["ICD10"],
2412
- bare: true,
2413
- clearOnSelect: true,
2414
- initialQuery: editingConcern ? chunkJCO62XMU_cjs.currentAssertion(editingConcern)?.text : "",
2415
- "aria-label": editingConcern ? m("Recode condition") : m("Add condition"),
2416
- placeholder: editingConcern ? m("Search replacement diagnosis\u2026") : m("Search conditions\u2026"),
2417
- onSelect: (pick) => {
2418
- if (!pick.fullid?.trim() || !pick.codetype?.trim() || !pick.fullcode?.trim() || !pick.label?.trim() || pick.domain !== "condition")
2419
- return;
2420
- recordAssertion(
2421
- {
2422
- text: pick.label,
2423
- verificationStatus: "unconfirmed",
2424
- coding: [
1711
+ },
1712
+ addSearch,
1713
+ onAddProblem: addSearch || !canAssert ? void 0 : (text) => saveAssertion(void 0, {
1714
+ text,
1715
+ verificationStatus: "unconfirmed"
1716
+ }),
1717
+ onAdd: canAssert ? () => setEditor({ mode: "add" }) : void 0,
1718
+ onReorder: (ids) => commit((next) => ({
1719
+ ...next,
1720
+ concerns: reorderClinicalEntries(
1721
+ next.concerns,
1722
+ ids,
1723
+ ({ concernId }) => concernId
1724
+ )
1725
+ }))
1726
+ }
1727
+ ),
1728
+ /* @__PURE__ */ jsxRuntime.jsx(
1729
+ chunk6O6EYKOG_cjs.ConditionEditor,
1730
+ {
1731
+ mode: editor?.mode ?? "add",
1732
+ open: editor !== null,
1733
+ onOpenChange: (open) => {
1734
+ if (!open) setEditor(null);
1735
+ },
1736
+ concern: editor?.mode === "add" ? void 0 : editorConcern,
1737
+ relatableConcerns: value.concerns.filter(
1738
+ ({ concernId }) => concernId !== editor?.concernId
1739
+ ),
1740
+ onSave: (draft) => {
1741
+ saveAssertion(
1742
+ editor?.mode === "add" ? void 0 : editor?.concernId,
1743
+ draft
1744
+ );
1745
+ setEditor(null);
1746
+ },
1747
+ onRelate: (relationship) => {
1748
+ const target = editor?.concernId;
1749
+ if (target)
1750
+ commit((next) => ({
1751
+ ...next,
1752
+ concerns: next.concerns.map(
1753
+ (concern) => concern.concernId === target ? {
1754
+ ...concern,
1755
+ relationships: [
1756
+ ...concern.relationships ?? [],
1757
+ relationship
1758
+ ]
1759
+ } : concern
1760
+ )
1761
+ }));
1762
+ setEditor(null);
1763
+ },
1764
+ onAddObservation: (text) => {
1765
+ const target = editor?.concernId;
1766
+ if (target && currentDate.current.valid)
1767
+ commit((next) => ({
1768
+ ...next,
1769
+ concerns: next.concerns.map(
1770
+ (concern) => concern.concernId === target ? {
1771
+ ...concern,
1772
+ observations: [
1773
+ ...concern.observations ?? [],
2425
1774
  {
2426
- system: pick.codetype,
2427
- code: pick.fullcode,
2428
- display: pick.label,
2429
- primary: true
1775
+ id: globalThis.crypto.randomUUID(),
1776
+ date: currentDate.current.date,
1777
+ text
2430
1778
  }
2431
1779
  ]
2432
- },
2433
- pick
2434
- );
2435
- }
2436
- },
2437
- editing ? editing.concernId : "add"
2438
- ) })
2439
- ] }),
2440
- assertionDate.valid && !requireCoding && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2441
- /* @__PURE__ */ jsxRuntime.jsx(
2442
- chunkFSARTLUE_cjs.Button,
2443
- {
2444
- type: "button",
2445
- onClick: () => {
2446
- setManualEditing(true);
2447
- },
2448
- children: m("Other\u2026")
2449
- }
2450
- ),
2451
- /* @__PURE__ */ jsxRuntime.jsx(
2452
- chunkSCYLVQWA_cjs.ConditionEditor,
2453
- {
2454
- mode: editing ? "refine" : "add",
2455
- open: manualEditing,
2456
- onOpenChange: setManualEditing,
2457
- concern: editingConcern,
2458
- renderCodeSearch: false,
2459
- onSave: (draft) => recordAssertion(draft)
2460
- }
2461
- )
2462
- ] }),
2463
- value.concerns.length > 0 && problemList
2464
- ] }),
2465
- !readOnly && !adding && !editingConcern && value.concerns.length === 0 && (codeLookup || !requireCoding) && /* @__PURE__ */ jsxRuntime.jsx(
2466
- ClinicalAddButton,
2467
- {
2468
- label: m("Add condition"),
2469
- onClick: () => setAdding(true)
1780
+ } : concern
1781
+ )
1782
+ }));
1783
+ setEditor(null);
1784
+ }
2470
1785
  }
2471
1786
  ),
2472
- !readOnly && requireCoding && !codeLookup && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-muted-foreground text-sm", children: m("Coded condition search is unavailable.") }),
2473
- readOnly && problemList
1787
+ !readOnly && !canAssert && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-muted-foreground mt-2 text-xs", children: m(
1788
+ "No encounter date \u2014 conditions cannot be added or revised until the visit provides one."
1789
+ ) })
2474
1790
  ] });
2475
1791
  }
2476
1792
  function readPlan(answer) {
@@ -2479,7 +1795,7 @@ function readPlan(answer) {
2479
1795
  const parsed = JSON.parse(answer);
2480
1796
  if (!parsed || typeof parsed !== "object" || Array.isArray(parsed) || !("orders" in parsed) || !Array.isArray(parsed.orders))
2481
1797
  return void 0;
2482
- if (chunkM42FTWY2_cjs.validateEncounterPlan(parsed).length > 0) return void 0;
1798
+ if (chunk46RYJYN2_cjs.validateEncounterPlan(parsed).length > 0) return void 0;
2483
1799
  return parsed;
2484
1800
  } catch {
2485
1801
  return void 0;
@@ -2502,11 +1818,11 @@ function getPlanConcerns(state) {
2502
1818
  if (!parsed || typeof parsed !== "object" || Array.isArray(parsed))
2503
1819
  continue;
2504
1820
  const assessment = parsed;
2505
- if (chunkM42FTWY2_cjs.validateEncounterConditions({ concerns: assessment.concerns }).length > 0)
1821
+ if (chunk46RYJYN2_cjs.validateEncounterConditions({ concerns: assessment.concerns }).length > 0)
2506
1822
  continue;
2507
1823
  for (const concern of assessment.concerns ?? []) {
2508
1824
  if (concerns.has(concern.concernId)) continue;
2509
- const assertion = chunkJCO62XMU_cjs.currentAssertion(concern);
1825
+ const assertion = chunkNCPDUJKJ_cjs.currentAssertion(concern);
2510
1826
  concerns.set(concern.concernId, concern);
2511
1827
  if (assertion) {
2512
1828
  items.set(concern.concernId, {
@@ -2516,149 +1832,112 @@ function getPlanConcerns(state) {
2516
1832
  }
2517
1833
  }
2518
1834
  for (const item of assessment.items ?? []) {
2519
- if (!chunkM42FTWY2_cjs.validAssessmentItem(item)) continue;
1835
+ if (!chunk46RYJYN2_cjs.validAssessmentItem(item)) continue;
2520
1836
  if (concerns.get(item.concernId)?.assertions.some(({ id }) => id === item.assertionId))
2521
1837
  items.set(item.concernId, item);
2522
1838
  }
2523
- } catch {
2524
- }
2525
- }
2526
- return { concerns: [...concerns.values()], items: [...items.values()] };
2527
- }
2528
- function EncounterPlanField({
2529
- field,
2530
- form,
2531
- response,
2532
- isPreview,
2533
- isEnabled,
2534
- isReadOnly,
2535
- onResponse
2536
- }) {
2537
- const value = React11__namespace.useMemo(
2538
- () => readPlan(response?.answer),
2539
- [response?.answer]
2540
- );
2541
- const m = chunkFSLI5IKP_cjs.useMessages();
2542
- const requireCoding = clinicalRequiresCoding(field);
2543
- const state = useClinicalFormState(form);
2544
- const codeLookup = chunkSCYLVQWA_cjs.useCodeLookupConfig();
2545
- const readOnly = !(isPreview && isEnabled) || Boolean(isReadOnly) || state.readOnly || state.disposed || !value;
2546
- const currentValue = React11__namespace.useRef(value);
2547
- const currentResponse = React11__namespace.useRef(response);
2548
- currentResponse.current = response;
2549
- const canEdit = React11__namespace.useRef(!readOnly);
2550
- currentValue.current = value;
2551
- canEdit.current = !readOnly;
2552
- const { concerns, items } = React11__namespace.useMemo(
2553
- () => getPlanConcerns(state),
2554
- [state]
2555
- );
2556
- const definition = field.definition;
2557
- const label = definition.question ?? m("Plan");
2558
- const commit = (update) => {
2559
- if (!canEdit.current || form.getState().readOnly || form.getState().disposed || !currentValue.current)
2560
- return;
2561
- const next = update(currentValue.current);
2562
- currentValue.current = next;
2563
- onResponse(
2564
- clinicalAnswerResponse(
2565
- form.getState().responses[field.definition.id] ?? currentResponse.current,
2566
- JSON.stringify(next)
2567
- )
2568
- );
2569
- };
2570
- const renderSearch = React11__namespace.useMemo(
2571
- () => codeLookup || !requireCoding ? codedOrderSearch(codeLookup, requireCoding, m) : void 0,
2572
- [codeLookup, requireCoding, m]
2573
- );
2574
- if (!value)
2575
- return /* @__PURE__ */ jsxRuntime.jsx(InvalidClinicalAnswer, { label, answer: response?.answer });
2576
- return /* @__PURE__ */ jsxRuntime.jsxs("section", { "aria-label": label, className: "min-w-0 space-y-2", children: [
2577
- /* @__PURE__ */ jsxRuntime.jsx(
2578
- chunkSCYLVQWA_cjs.Assessment,
2579
- {
2580
- concerns,
2581
- items,
2582
- orders: value.orders,
2583
- title: null,
2584
- className: clinicalAssessmentClasses,
2585
- readOnly,
2586
- rowActions: codeLookup || !requireCoding ? ["add-order"] : [],
2587
- addModes: ["order"],
2588
- addFormLabel: "Add plan order",
2589
- defaultAddMode: "order",
2590
- renderOrderSearch: renderSearch,
2591
- onAddOrder: codeLookup || !requireCoding ? (item, order) => {
2592
- if (requireCoding && !order.code) return;
2593
- commit((next) => ({
2594
- ...next,
2595
- orders: [
2596
- ...next.orders,
2597
- {
2598
- ...order,
2599
- orderId: globalThis.crypto.randomUUID(),
2600
- concernId: item?.concernId
2601
- }
2602
- ]
2603
- }));
2604
- } : void 0,
2605
- onEditOrder: (order, changes) => commit((next) => ({
2606
- ...next,
2607
- orders: next.orders.map(
2608
- (candidate) => candidate.orderId === order.orderId ? { ...candidate, ...changes } : candidate
2609
- )
2610
- })),
2611
- onRemoveOrder: (order) => commit((next) => ({
2612
- ...next,
2613
- orders: next.orders.filter(
2614
- (candidate) => candidate.orderId !== order.orderId
2615
- )
2616
- })),
2617
- onLinkOrder: (order, concernId) => commit((next) => ({
2618
- ...next,
2619
- orders: next.orders.map(
2620
- (candidate) => candidate.orderId === order.orderId ? { ...candidate, concernId } : candidate
2621
- )
2622
- })),
2623
- onReorderOrders: (ids) => commit((next) => ({
2624
- ...next,
2625
- orders: reorderClinicalEntries(
2626
- next.orders,
2627
- ids,
2628
- ({ orderId }) => orderId
2629
- )
2630
- }))
2631
- }
2632
- ),
2633
- !readOnly && requireCoding && !codeLookup && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-muted-foreground text-sm", children: m("Coded order search is unavailable.") })
2634
- ] });
2635
- }
2636
- var EncounterSectionContext = React11__namespace.createContext(false);
2637
- function EncounterSectionField(props) {
2638
- const inEncounter = React11__namespace.useContext(EncounterSectionContext);
2639
- const { field, isPreview, isRequired, isSoftRequired, nestedChildren } = props;
2640
- const def = field.definition;
2641
- if (!inEncounter || !isPreview) return /* @__PURE__ */ jsxRuntime.jsx(fields.SectionField, { ...props });
2642
- const title = def.title || "Section";
2643
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "section-field-preview grid gap-1.5", children: [
2644
- /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-foreground m-0 flex items-center gap-2 text-sm font-medium", children: /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "min-w-0 break-words", children: [
2645
- title,
2646
- (isRequired || isSoftRequired) && /* @__PURE__ */ jsxRuntime.jsx(
2647
- chunkZ5S5JEJD_cjs.RequiredMark,
2648
- {
2649
- variant: isSoftRequired && !isRequired ? "warning" : void 0
2650
- }
1839
+ } catch {
1840
+ }
1841
+ }
1842
+ return { concerns: [...concerns.values()], items: [...items.values()] };
1843
+ }
1844
+ function EncounterPlanField({
1845
+ field,
1846
+ form,
1847
+ response,
1848
+ isPreview,
1849
+ isEnabled,
1850
+ isReadOnly,
1851
+ onResponse
1852
+ }) {
1853
+ const value = React11__namespace.useMemo(
1854
+ () => readPlan(response?.answer),
1855
+ [response?.answer]
1856
+ );
1857
+ const m = chunkFSLI5IKP_cjs.useMessages();
1858
+ const state = useClinicalFormState(form);
1859
+ const readOnly = !(isPreview && isEnabled) || Boolean(isReadOnly) || state.readOnly || state.disposed || !value;
1860
+ const currentValue = React11__namespace.useRef(value);
1861
+ const currentResponse = React11__namespace.useRef(response);
1862
+ currentResponse.current = response;
1863
+ const canEdit = React11__namespace.useRef(!readOnly);
1864
+ currentValue.current = value;
1865
+ canEdit.current = !readOnly;
1866
+ const { concerns, items } = React11__namespace.useMemo(
1867
+ () => getPlanConcerns(state),
1868
+ [state]
1869
+ );
1870
+ const definition = field.definition;
1871
+ const label = definition.question ?? m("Plan");
1872
+ const commit = (update) => {
1873
+ if (!canEdit.current || form.getState().readOnly || form.getState().disposed || !currentValue.current)
1874
+ return;
1875
+ const next = update(currentValue.current);
1876
+ currentValue.current = next;
1877
+ onResponse(
1878
+ clinicalAnswerResponse(
1879
+ form.getState().responses[field.definition.id] ?? currentResponse.current,
1880
+ JSON.stringify(next)
2651
1881
  )
2652
- ] }) }),
2653
- nestedChildren
2654
- ] });
1882
+ );
1883
+ };
1884
+ if (!value)
1885
+ return /* @__PURE__ */ jsxRuntime.jsx(InvalidClinicalAnswer, { label, answer: response?.answer });
1886
+ return /* @__PURE__ */ jsxRuntime.jsx("section", { "aria-label": label, className: "min-w-0 space-y-2", children: /* @__PURE__ */ jsxRuntime.jsx(
1887
+ chunk6O6EYKOG_cjs.Assessment,
1888
+ {
1889
+ concerns,
1890
+ items,
1891
+ orders: value.orders,
1892
+ title: label,
1893
+ readOnly,
1894
+ rowActions: ["add-order"],
1895
+ addModes: ["order"],
1896
+ addFormLabel: "Add plan order",
1897
+ onAddOrder: (item, order) => commit((next) => ({
1898
+ ...next,
1899
+ orders: [
1900
+ ...next.orders,
1901
+ {
1902
+ ...order,
1903
+ orderId: globalThis.crypto.randomUUID(),
1904
+ concernId: item?.concernId
1905
+ }
1906
+ ]
1907
+ })),
1908
+ onEditOrder: (order, changes) => commit((next) => ({
1909
+ ...next,
1910
+ orders: next.orders.map(
1911
+ (candidate) => candidate.orderId === order.orderId ? { ...candidate, ...changes } : candidate
1912
+ )
1913
+ })),
1914
+ onRemoveOrder: (order) => commit((next) => ({
1915
+ ...next,
1916
+ orders: next.orders.filter(
1917
+ (candidate) => candidate.orderId !== order.orderId
1918
+ )
1919
+ })),
1920
+ onLinkOrder: (order, concernId) => commit((next) => ({
1921
+ ...next,
1922
+ orders: next.orders.map(
1923
+ (candidate) => candidate.orderId === order.orderId ? { ...candidate, concernId } : candidate
1924
+ )
1925
+ })),
1926
+ onReorderOrders: (ids) => commit((next) => ({
1927
+ ...next,
1928
+ orders: reorderClinicalEntries(
1929
+ next.orders,
1930
+ ids,
1931
+ ({ orderId }) => orderId
1932
+ )
1933
+ }))
1934
+ }
1935
+ ) });
2655
1936
  }
2656
1937
 
2657
1938
  // src/components/EncounterVisit/fields.ts
2658
1939
  function registerEncounterFieldTypes() {
2659
- const section = fields.getFieldComponent("section");
2660
- if (section === void 0 || section === fields.SectionField)
2661
- fields.registerFieldComponents({ section: EncounterSectionField });
1940
+ registerEsheetSectionFieldType();
2662
1941
  const clinicalFields = {
2663
1942
  encounterMedications: {
2664
1943
  label: "Encounter medications",
@@ -2800,7 +2079,7 @@ function createEncounterVisitTools(options) {
2800
2079
  }
2801
2080
  function definition() {
2802
2081
  const current = options.getDefinition();
2803
- chunkM42FTWY2_cjs.validateEncounterDefinition(current);
2082
+ chunk46RYJYN2_cjs.validateEncounterDefinition(current);
2804
2083
  return current;
2805
2084
  }
2806
2085
  function section(sectionId) {
@@ -2820,7 +2099,7 @@ function createEncounterVisitTools(options) {
2820
2099
  throw new ToolError("READ_ONLY", "This visit is read-only.");
2821
2100
  }
2822
2101
  function snapshot() {
2823
- return chunkM42FTWY2_cjs.createEncounterSnapshot(definition(), options.getResponses());
2102
+ return chunk46RYJYN2_cjs.createEncounterSnapshot(definition(), options.getResponses());
2824
2103
  }
2825
2104
  function write(sectionId, fieldId, response, targetReadingId) {
2826
2105
  const currentDefinition = definition();
@@ -2830,7 +2109,7 @@ function createEncounterVisitTools(options) {
2830
2109
  ({ id }) => id === sectionId
2831
2110
  );
2832
2111
  const isChoice = target?.observations?.some(
2833
- (observation) => chunkM42FTWY2_cjs.getEncounterFieldId(sectionId, observation.id) === fieldId && observation.type === "choice"
2112
+ (observation) => chunk46RYJYN2_cjs.getEncounterFieldId(sectionId, observation.id) === fieldId && observation.type === "choice"
2834
2113
  );
2835
2114
  if (!isChoice) delete replacement.selected;
2836
2115
  const next = { ...previous, [fieldId]: replacement };
@@ -2842,19 +2121,19 @@ function createEncounterVisitTools(options) {
2842
2121
  issue.message
2843
2122
  ]);
2844
2123
  const previousIssueKeys = new Set(
2845
- chunkM42FTWY2_cjs.validateEncounterResponses(currentDefinition, previous).map(issueKey)
2124
+ chunk46RYJYN2_cjs.validateEncounterResponses(currentDefinition, previous).map(issueKey)
2846
2125
  );
2847
- const issues = chunkM42FTWY2_cjs.validateEncounterResponses(currentDefinition, next).filter(
2126
+ const issues = chunk46RYJYN2_cjs.validateEncounterResponses(currentDefinition, next).filter(
2848
2127
  (issue) => issue.sectionId === sectionId && issue.fieldId === fieldId && issue.code !== "required" && (!targetReadingId || !issue.readingId || issue.readingId === targetReadingId) || issue.fieldId !== fieldId && issue.code !== "required" && !previousIssueKeys.has(issueKey(issue))
2849
2128
  );
2850
2129
  if (issues.length)
2851
2130
  throw new ToolError("INVALID_RESPONSE", issues[0].message, issues);
2852
2131
  options.setResponses(next);
2853
- return chunkM42FTWY2_cjs.createEncounterSnapshot(currentDefinition, next);
2132
+ return chunk46RYJYN2_cjs.createEncounterSnapshot(currentDefinition, next);
2854
2133
  }
2855
2134
  function structured(sectionId, value, targetReadingId) {
2856
2135
  assertJsonValue(value);
2857
- const fieldId = chunkM42FTWY2_cjs.getEncounterFieldId(sectionId, "value");
2136
+ const fieldId = chunk46RYJYN2_cjs.getEncounterFieldId(sectionId, "value");
2858
2137
  return write(
2859
2138
  sectionId,
2860
2139
  fieldId,
@@ -2866,7 +2145,7 @@ function createEncounterVisitTools(options) {
2866
2145
  );
2867
2146
  }
2868
2147
  function vitalValue(sectionId) {
2869
- const fieldId = chunkM42FTWY2_cjs.getEncounterFieldId(sectionId, "value");
2148
+ const fieldId = chunk46RYJYN2_cjs.getEncounterFieldId(sectionId, "value");
2870
2149
  const answer = options.getResponses()[fieldId]?.answer;
2871
2150
  if (!answer?.trim()) return { readings: [] };
2872
2151
  let value;
@@ -2915,7 +2194,7 @@ function createEncounterVisitTools(options) {
2915
2194
  }
2916
2195
  if (typeof text !== "string")
2917
2196
  throw new ToolError("INVALID_ARGUMENT", "text must be a string.");
2918
- const fieldId = chunkM42FTWY2_cjs.getEncounterFieldId(sectionId);
2197
+ const fieldId = chunk46RYJYN2_cjs.getEncounterFieldId(sectionId);
2919
2198
  return write(sectionId, fieldId, {
2920
2199
  ...options.getResponses()[fieldId],
2921
2200
  answer: text
@@ -2925,7 +2204,7 @@ function createEncounterVisitTools(options) {
2925
2204
  writable();
2926
2205
  const current = section(sectionId);
2927
2206
  requireId(findingId, "findingId");
2928
- let fieldId = chunkM42FTWY2_cjs.getEncounterFieldId(sectionId);
2207
+ let fieldId = chunk46RYJYN2_cjs.getEncounterFieldId(sectionId);
2929
2208
  let findings = current.findings;
2930
2209
  if (observationId !== void 0) {
2931
2210
  requireId(observationId, "observationId");
@@ -2937,7 +2216,7 @@ function createEncounterVisitTools(options) {
2937
2216
  "UNKNOWN_OBSERVATION",
2938
2217
  "Common findings require a configured text observation."
2939
2218
  );
2940
- fieldId = chunkM42FTWY2_cjs.getEncounterFieldId(sectionId, observationId);
2219
+ fieldId = chunk46RYJYN2_cjs.getEncounterFieldId(sectionId, observationId);
2941
2220
  findings = observation.findings;
2942
2221
  } else if (current.kind !== "narrative" && !current.narrative) {
2943
2222
  throw new ToolError(
@@ -2977,7 +2256,7 @@ function createEncounterVisitTools(options) {
2977
2256
  "UNKNOWN_OBSERVATION",
2978
2257
  `Unknown observation: ${observationId}.`
2979
2258
  );
2980
- const fieldId = chunkM42FTWY2_cjs.getEncounterFieldId(sectionId, observationId);
2259
+ const fieldId = chunk46RYJYN2_cjs.getEncounterFieldId(sectionId, observationId);
2981
2260
  const response = { ...options.getResponses()[fieldId] };
2982
2261
  delete response.answer;
2983
2262
  delete response.selected;
@@ -3019,9 +2298,9 @@ function createEncounterVisitTools(options) {
3019
2298
  throw new ToolError("INVALID_ARGUMENT", "reading must be an object.");
3020
2299
  requireId(reading.id, "reading.id");
3021
2300
  assertJsonValue(reading);
3022
- const issues = chunkM42FTWY2_cjs.validateEncounterVitals(
2301
+ const issues = chunk46RYJYN2_cjs.validateEncounterVitals(
3023
2302
  { readings: [reading] },
3024
- chunkM42FTWY2_cjs.getEncounterFieldId(sectionId, "value"),
2303
+ chunk46RYJYN2_cjs.getEncounterFieldId(sectionId, "value"),
3025
2304
  sectionId
3026
2305
  );
3027
2306
  if (issues.length)
@@ -3092,7 +2371,7 @@ function createEncounterVisitTools(options) {
3092
2371
  return structured(sectionId, parsed);
3093
2372
  }),
3094
2373
  validateVisit: () => run(() => {
3095
- const issues = chunkM42FTWY2_cjs.validateEncounterResponses(
2374
+ const issues = chunk46RYJYN2_cjs.validateEncounterResponses(
3096
2375
  definition(),
3097
2376
  options.getResponses()
3098
2377
  );
@@ -3105,11 +2384,11 @@ function createEncounterVisitTools(options) {
3105
2384
  if (typeof body !== "string")
3106
2385
  throw new ToolError("INVALID_ARGUMENT", "body must be a string.");
3107
2386
  const currentDefinition = definition();
3108
- const next = chunkM42FTWY2_cjs.updateEncounterDocumentBody(options.getResponses(), body, {
2387
+ const next = chunk46RYJYN2_cjs.updateEncounterDocumentBody(options.getResponses(), body, {
3109
2388
  _ai: true
3110
2389
  });
3111
2390
  options.setResponses(next);
3112
- return chunkM42FTWY2_cjs.createEncounterSnapshot(currentDefinition, next);
2391
+ return chunk46RYJYN2_cjs.createEncounterSnapshot(currentDefinition, next);
3113
2392
  }),
3114
2393
  navigateToSection: (sectionId) => run(() => {
3115
2394
  section(sectionId);
@@ -3430,12 +2709,12 @@ function ensureFields() {
3430
2709
  }
3431
2710
  var esheetDefaultsSettled = false;
3432
2711
  var EncounterVisit = React11__namespace.forwardRef(function EncounterVisit2({ definition, initialMdy, codeLookup, messages, ...props }, ref) {
3433
- const inheritedCodeLookup = chunkSCYLVQWA_cjs.useCodeLookupConfig();
2712
+ const inheritedCodeLookup = chunk6O6EYKOG_cjs.useCodeLookupConfig();
3434
2713
  const parsed = React11__namespace.useMemo(
3435
- () => initialMdy === void 0 ? null : chunkM42FTWY2_cjs.parseEncounterMdy(initialMdy),
2714
+ () => initialMdy === void 0 ? null : chunk46RYJYN2_cjs.parseEncounterMdy(initialMdy),
3436
2715
  [initialMdy]
3437
2716
  );
3438
- const visitDefinition = definition ?? parsed?.definition ?? chunkM42FTWY2_cjs.DEFAULT_ENCOUNTER_VISIT_DEFINITION;
2717
+ const visitDefinition = definition ?? parsed?.definition ?? chunk46RYJYN2_cjs.DEFAULT_ENCOUNTER_VISIT_DEFINITION;
3439
2718
  const loadErrors = parsed?.diagnostics.filter(
3440
2719
  (diagnostic) => diagnostic.severity === "error" && diagnostic.code !== "dangling-link"
3441
2720
  ) ?? [];
@@ -3481,7 +2760,7 @@ var EncounterVisit = React11__namespace.forwardRef(function EncounterVisit2({ de
3481
2760
  form.pages.forEach((page) => visitFields(page.fields));
3482
2761
  return JSON.stringify(shapes.sort((a, b) => a.id.localeCompare(b.id)));
3483
2762
  };
3484
- if (fieldShapes(parsed.form) !== fieldShapes(chunkM42FTWY2_cjs.createEncounterFormDefinition(visitDefinition))) {
2763
+ if (fieldShapes(parsed.form) !== fieldShapes(chunk46RYJYN2_cjs.createEncounterFormDefinition(visitDefinition))) {
3485
2764
  throw new Error(
3486
2765
  "The MDY fields do not match the supplied encounter definition."
3487
2766
  );
@@ -3497,7 +2776,7 @@ var EncounterVisit = React11__namespace.forwardRef(function EncounterVisit2({ de
3497
2776
  },
3498
2777
  visitDefinition.id
3499
2778
  );
3500
- return /* @__PURE__ */ jsxRuntime.jsx(chunkSCYLVQWA_cjs.CodeLookupContext.Provider, { value: codeLookup ?? inheritedCodeLookup, children: /* @__PURE__ */ jsxRuntime.jsx(chunkFSLI5IKP_cjs.MessagesProvider, { messages, children: session }) });
2779
+ return /* @__PURE__ */ jsxRuntime.jsx(chunk6O6EYKOG_cjs.CodeLookupContext.Provider, { value: codeLookup ?? inheritedCodeLookup, children: /* @__PURE__ */ jsxRuntime.jsx(chunkFSLI5IKP_cjs.MessagesProvider, { messages, children: session }) });
3501
2780
  });
3502
2781
  var EncounterVisitSession = React11__namespace.forwardRef(function EncounterVisitSession2({
3503
2782
  definition,
@@ -3530,22 +2809,22 @@ var EncounterVisitSession = React11__namespace.forwardRef(function EncounterVisi
3530
2809
  [definitionJson]
3531
2810
  );
3532
2811
  const form = React11__namespace.useMemo(
3533
- () => chunkM42FTWY2_cjs.createEncounterFormDefinition(stableDefinition),
2812
+ () => chunk46RYJYN2_cjs.createEncounterFormDefinition(stableDefinition),
3534
2813
  [stableDefinition]
3535
2814
  );
3536
2815
  const [initialSeed] = React11__namespace.useState(() => {
3537
2816
  if (initialMdy === void 0) return initialResponses ?? {};
3538
- const document2 = chunkM42FTWY2_cjs.parseEncounterMdy(initialMdy);
2817
+ const document2 = chunk46RYJYN2_cjs.parseEncounterMdy(initialMdy);
3539
2818
  return {
3540
2819
  ...document2.response ?? {},
3541
- [chunkM42FTWY2_cjs.ENCOUNTER_DOCUMENT_FIELD_ID]: chunkM42FTWY2_cjs.encounterDocumentResponse(initialMdy)
2820
+ [chunk46RYJYN2_cjs.ENCOUNTER_DOCUMENT_FIELD_ID]: chunk46RYJYN2_cjs.encounterDocumentResponse(initialMdy)
3542
2821
  };
3543
2822
  });
3544
2823
  const [snapshot, setSnapshot] = React11__namespace.useState(
3545
- () => chunkM42FTWY2_cjs.createEncounterSnapshot(stableDefinition, initialSeed)
2824
+ () => chunk46RYJYN2_cjs.createEncounterSnapshot(stableDefinition, initialSeed)
3546
2825
  );
3547
2826
  const [richBodySeed] = React11__namespace.useState(
3548
- () => chunkM42FTWY2_cjs.parseEncounterMdy(snapshot.mdy).body
2827
+ () => chunk46RYJYN2_cjs.parseEncounterMdy(snapshot.mdy).body
3549
2828
  );
3550
2829
  const [activeSection, setActiveSection] = React11__namespace.useState(
3551
2830
  stableDefinition.sections[0].id
@@ -3593,18 +2872,18 @@ var EncounterVisitSession = React11__namespace.forwardRef(function EncounterVisi
3593
2872
  const store = renderer$1.current?.getFormStore();
3594
2873
  if (!store) return;
3595
2874
  const current = store.getState().responses;
3596
- if (current[chunkM42FTWY2_cjs.ENCOUNTER_DOCUMENT_FIELD_ID]?.answer === body) return;
3597
- const next = chunkM42FTWY2_cjs.updateEncounterDocumentBody(current, body, { _ai: false });
2875
+ if (current[chunk46RYJYN2_cjs.ENCOUNTER_DOCUMENT_FIELD_ID]?.answer === body) return;
2876
+ const next = chunk46RYJYN2_cjs.updateEncounterDocumentBody(current, body, { _ai: false });
3598
2877
  store.getState().setResponse(
3599
- chunkM42FTWY2_cjs.ENCOUNTER_DOCUMENT_FIELD_ID,
3600
- next[chunkM42FTWY2_cjs.ENCOUNTER_DOCUMENT_FIELD_ID]
2878
+ chunk46RYJYN2_cjs.ENCOUNTER_DOCUMENT_FIELD_ID,
2879
+ next[chunk46RYJYN2_cjs.ENCOUNTER_DOCUMENT_FIELD_ID]
3601
2880
  );
3602
2881
  }, []);
3603
2882
  const flushEditor = React11__namespace.useCallback(async () => {
3604
2883
  if (richEditor.current && latest.current.mode === "rich" && !latest.current.readOnly && !latest.current.saving) {
3605
- const before = renderer$1.current?.getRawResponse()[chunkM42FTWY2_cjs.ENCOUNTER_DOCUMENT_FIELD_ID];
2884
+ const before = renderer$1.current?.getRawResponse()[chunk46RYJYN2_cjs.ENCOUNTER_DOCUMENT_FIELD_ID];
3606
2885
  const body = await richEditor.current.getContent();
3607
- const after = renderer$1.current?.getRawResponse()[chunkM42FTWY2_cjs.ENCOUNTER_DOCUMENT_FIELD_ID];
2886
+ const after = renderer$1.current?.getRawResponse()[chunk46RYJYN2_cjs.ENCOUNTER_DOCUMENT_FIELD_ID];
3608
2887
  if (after !== before && after?.answer !== before?.answer) return;
3609
2888
  writeBody(body);
3610
2889
  }
@@ -3646,7 +2925,7 @@ var EncounterVisitSession = React11__namespace.forwardRef(function EncounterVisi
3646
2925
  );
3647
2926
  React11__namespace.useLayoutEffect(() => {
3648
2927
  if (mode !== "esheet" || pendingSection === null) return;
3649
- const fieldId = chunkM42FTWY2_cjs.getEncounterSectionFieldId(pendingSection);
2928
+ const fieldId = chunk46RYJYN2_cjs.getEncounterSectionFieldId(pendingSection);
3650
2929
  const section = Array.from(
3651
2930
  root.current?.querySelectorAll("[data-field-id]") ?? []
3652
2931
  ).find((element) => element.dataset.fieldId === fieldId);
@@ -3688,7 +2967,7 @@ var EncounterVisitSession = React11__namespace.forwardRef(function EncounterVisi
3688
2967
  React11__namespace.useImperativeHandle(
3689
2968
  ref,
3690
2969
  () => ({
3691
- getSnapshot: () => chunkM42FTWY2_cjs.createEncounterSnapshot(
2970
+ getSnapshot: () => chunk46RYJYN2_cjs.createEncounterSnapshot(
3692
2971
  latest.current.definition,
3693
2972
  renderer$1.current?.getRawResponse() ?? responses.current
3694
2973
  ),
@@ -3781,7 +3060,7 @@ var EncounterVisitSession = React11__namespace.forwardRef(function EncounterVisi
3781
3060
  previousFocus.focus();
3782
3061
  };
3783
3062
  }, [resolverField]);
3784
- const mdyFields = chunkM42FTWY2_cjs.getEncounterMdyFields(snapshot);
3063
+ const mdyFields = chunk46RYJYN2_cjs.getEncounterMdyFields(snapshot);
3785
3064
  const resolvedField = mdyFields.find((field) => field.id === resolverField);
3786
3065
  const resolvedNativeFieldId = resolvedField?.fieldId;
3787
3066
  const resolvedSectionId = resolvedField?.sectionId;
@@ -3791,7 +3070,7 @@ var EncounterVisitSession = React11__namespace.forwardRef(function EncounterVisi
3791
3070
  );
3792
3071
  sections?.forEach((element) => {
3793
3072
  const wrapper2 = element.closest("[data-field-id]");
3794
- const focused = resolvedSectionId && wrapper2?.dataset.fieldId === chunkM42FTWY2_cjs.getEncounterSectionFieldId(resolvedSectionId);
3073
+ const focused = resolvedSectionId && wrapper2?.dataset.fieldId === chunk46RYJYN2_cjs.getEncounterSectionFieldId(resolvedSectionId);
3795
3074
  element.toggleAttribute("data-encounter-focus", Boolean(focused));
3796
3075
  wrapper2?.toggleAttribute("data-encounter-focus", Boolean(focused));
3797
3076
  });
@@ -3807,7 +3086,7 @@ var EncounterVisitSession = React11__namespace.forwardRef(function EncounterVisi
3807
3086
  unsubscribe.current?.();
3808
3087
  const publish = () => {
3809
3088
  responses.current = store.getState().responses;
3810
- const next = chunkM42FTWY2_cjs.createEncounterSnapshot(
3089
+ const next = chunk46RYJYN2_cjs.createEncounterSnapshot(
3811
3090
  latest.current.definition,
3812
3091
  responses.current
3813
3092
  );
@@ -3851,7 +3130,7 @@ var EncounterVisitSession = React11__namespace.forwardRef(function EncounterVisi
3851
3130
  }
3852
3131
  if (!latest.current.onSubmit || latest.current.readOnly || latest.current.saving)
3853
3132
  return;
3854
- const next = chunkM42FTWY2_cjs.createEncounterSnapshot(
3133
+ const next = chunk46RYJYN2_cjs.createEncounterSnapshot(
3855
3134
  latest.current.definition,
3856
3135
  renderer$1.current?.getRawResponse() ?? responses.current
3857
3136
  );
@@ -3885,7 +3164,7 @@ var EncounterVisitSession = React11__namespace.forwardRef(function EncounterVisi
3885
3164
  }
3886
3165
  };
3887
3166
  const documentedSections = snapshot.definition.sections.filter(
3888
- (section) => chunkM42FTWY2_cjs.getEncounterSectionFieldIds(section).some(
3167
+ (section) => chunk46RYJYN2_cjs.getEncounterSectionFieldIds(section).some(
3889
3168
  (fieldId) => snapshot.observations.some(
3890
3169
  (observation) => observation.fieldId === fieldId
3891
3170
  )
@@ -3981,7 +3260,7 @@ var EncounterVisitSession = React11__namespace.forwardRef(function EncounterVisi
3981
3260
  EncounterMdyEditor,
3982
3261
  {
3983
3262
  ref: richEditor,
3984
- body: chunkM42FTWY2_cjs.getEncounterDocumentBody(snapshot.responses) ?? richBodySeed,
3263
+ body: chunk46RYJYN2_cjs.getEncounterDocumentBody(snapshot.responses) ?? richBodySeed,
3985
3264
  fieldIds: mdyFields.map((field) => field.id),
3986
3265
  fields: mdyFields.map((field) => ({
3987
3266
  id: field.id,
@@ -4079,7 +3358,7 @@ var EncounterVisitSession = React11__namespace.forwardRef(function EncounterVisi
4079
3358
  }
4080
3359
  )
4081
3360
  ] }),
4082
- /* @__PURE__ */ jsxRuntime.jsx(EncounterSectionContext.Provider, { value: true, children: /* @__PURE__ */ jsxRuntime.jsx(
3361
+ /* @__PURE__ */ jsxRuntime.jsx(EsheetSectionContext.Provider, { value: true, children: /* @__PURE__ */ jsxRuntime.jsx(
4083
3362
  renderer.EsheetRenderer,
4084
3363
  {
4085
3364
  ref: renderer$1,
@@ -4137,6 +3416,434 @@ var EncounterVisitSession = React11__namespace.forwardRef(function EncounterVisi
4137
3416
  }
4138
3417
  );
4139
3418
  });
3419
+ function getRichTextEsheetFieldId(sectionId) {
3420
+ return `richtext:${encodeURIComponent(sectionId)}:value`;
3421
+ }
3422
+ function getRichTextEsheetSectionFieldId(sectionId) {
3423
+ return `richtext:${encodeURIComponent(sectionId)}:section`;
3424
+ }
3425
+ function nonempty(value) {
3426
+ return typeof value === "string" && value.trim().length > 0;
3427
+ }
3428
+ function invalid(message) {
3429
+ throw new Error(`Invalid RichTextEsheet definition: ${message}`);
3430
+ }
3431
+ function validateRichTextEsheetDefinition(definition) {
3432
+ if (!definition || typeof definition !== "object")
3433
+ invalid("expected an object");
3434
+ if (!nonempty(definition.id) || !nonempty(definition.title))
3435
+ invalid("id and title must be nonempty strings");
3436
+ if (!Array.isArray(definition.sections) || definition.sections.length === 0)
3437
+ invalid("at least one section is required");
3438
+ const sectionIds = /* @__PURE__ */ new Set();
3439
+ for (const section of definition.sections) {
3440
+ if (!section || typeof section !== "object")
3441
+ invalid("expected a section object");
3442
+ if (!nonempty(section.id) || !nonempty(section.title))
3443
+ invalid("each section requires an id and title");
3444
+ if (sectionIds.has(section.id))
3445
+ invalid(`duplicate section id ${section.id}`);
3446
+ sectionIds.add(section.id);
3447
+ if (section.description !== void 0 && typeof section.description !== "string")
3448
+ invalid(`invalid description in ${section.id}`);
3449
+ if (section.required !== void 0 && typeof section.required !== "boolean")
3450
+ invalid(`required must be boolean in ${section.id}`);
3451
+ if (section.fieldType !== void 0 && !nonempty(section.fieldType))
3452
+ invalid(`fieldType must be a nonempty string in ${section.id}`);
3453
+ if (section.findings === void 0) continue;
3454
+ if (!Array.isArray(section.findings))
3455
+ invalid(`findings must be an array in ${section.id}`);
3456
+ const findingIds = /* @__PURE__ */ new Set();
3457
+ for (const finding of section.findings) {
3458
+ if (!finding || typeof finding !== "object" || !nonempty(finding.id) || !nonempty(finding.label) || !nonempty(finding.text))
3459
+ invalid(`findings require id, label and text in ${section.id}`);
3460
+ if (findingIds.has(finding.id))
3461
+ invalid(`duplicate finding id ${finding.id} in ${section.id}`);
3462
+ findingIds.add(finding.id);
3463
+ }
3464
+ }
3465
+ }
3466
+ function partyFindings(parties) {
3467
+ return (parties ?? []).map((party) => ({
3468
+ // Content-derived identity: editing or reordering a party yields a new
3469
+ // macro id, so the updated text stays insertable after an earlier
3470
+ // version was applied (selection dedupe is by id).
3471
+ id: `party:${encodeURIComponent(party.role)}:${encodeURIComponent(
3472
+ party.name
3473
+ )}:${encodeURIComponent(party.detail ?? "")}`,
3474
+ label: `${party.role}: ${party.name}`,
3475
+ text: party.detail ? `${party.name} (${party.detail})` : party.name
3476
+ }));
3477
+ }
3478
+ function createRichTextEsheetFormDefinition(definition, parties) {
3479
+ validateRichTextEsheetDefinition(definition);
3480
+ const partyMacros = partyFindings(parties);
3481
+ return {
3482
+ id: definition.id,
3483
+ title: definition.title,
3484
+ pages: [
3485
+ {
3486
+ id: `${definition.id}:document`,
3487
+ title: definition.title,
3488
+ fields: definition.sections.map((section) => {
3489
+ const fields = [];
3490
+ if (section.description) {
3491
+ fields.push({
3492
+ id: `${getRichTextEsheetSectionFieldId(section.id)}:description`,
3493
+ fieldType: "display",
3494
+ content: section.description,
3495
+ width: "full"
3496
+ });
3497
+ }
3498
+ const fieldType = section.fieldType ?? "esheetNarrative";
3499
+ fields.push({
3500
+ id: getRichTextEsheetFieldId(section.id),
3501
+ fieldType,
3502
+ question: section.title,
3503
+ required: section.required,
3504
+ width: "full",
3505
+ // Keyed off the resolved type: an explicit 'esheetNarrative'
3506
+ // override keeps its findings, macros and hidden label.
3507
+ _sourceData: fieldType === "esheetNarrative" ? {
3508
+ narrativeHideLabel: true,
3509
+ narrativeFindings: [
3510
+ ...section.findings ?? [],
3511
+ ...partyMacros
3512
+ ]
3513
+ } : void 0
3514
+ });
3515
+ return {
3516
+ id: getRichTextEsheetSectionFieldId(section.id),
3517
+ fieldType: "section",
3518
+ title: section.title,
3519
+ sectionCollapse: "expanded",
3520
+ width: "full",
3521
+ fields
3522
+ };
3523
+ })
3524
+ }
3525
+ ]
3526
+ };
3527
+ }
3528
+ function record(value) {
3529
+ return value !== null && typeof value === "object" && !Array.isArray(value);
3530
+ }
3531
+ function hasValue(value) {
3532
+ if (typeof value === "string") return value.trim().length > 0;
3533
+ if (typeof value === "number" || typeof value === "boolean") return true;
3534
+ if (Array.isArray(value)) return value.some(hasValue);
3535
+ if (record(value)) return Object.values(value).some(hasValue);
3536
+ return false;
3537
+ }
3538
+ function valueText(value) {
3539
+ if (typeof value === "string") return value.trim();
3540
+ if (typeof value === "number" || typeof value === "boolean")
3541
+ return String(value);
3542
+ if (Array.isArray(value))
3543
+ return value.map(valueText).filter(Boolean).join(", ");
3544
+ return "";
3545
+ }
3546
+ function selectedText(selected) {
3547
+ if (Array.isArray(selected))
3548
+ return selected.map(selectedText).filter(Boolean).join(", ");
3549
+ if (!record(selected)) return "";
3550
+ if ("value" in selected) {
3551
+ if (!hasValue(selected.value)) return "";
3552
+ const text = valueText(selected.value);
3553
+ const label = typeof selected.label === "string" ? selected.label.trim() : "";
3554
+ return label && label !== text ? `${label}: ${text}` : text;
3555
+ }
3556
+ return Object.values(selected).map(selectedText).filter(Boolean).join(", ");
3557
+ }
3558
+ function sectionText(responses, sectionId) {
3559
+ const response = responses[getRichTextEsheetFieldId(sectionId)];
3560
+ return valueText(response?.answer) || selectedText(response?.selected);
3561
+ }
3562
+ function markdownText(value) {
3563
+ return value.replace(/&/g, "&amp;").replace(/[\\[\]`*_~<>]/g, "\\$&");
3564
+ }
3565
+ function markdownHeading(value) {
3566
+ return markdownText(value).replace(/\r?\n/g, " \xB7 ");
3567
+ }
3568
+ function markdownBody(value) {
3569
+ return value.split(/\r?\n/).map(
3570
+ (line) => markdownText(line.trim()).replace(/^([#+-])/, "\\$1").replace(/^(\d+)([.)])/, "$1\\$2")
3571
+ ).filter(Boolean).join("\n\n");
3572
+ }
3573
+ function createRichTextEsheetSnapshot(definition, responses, parties) {
3574
+ validateRichTextEsheetDefinition(definition);
3575
+ const documentedSections = definition.sections.filter((section) => sectionText(responses, section.id).length > 0).map((section) => section.id);
3576
+ const errors = definition.sections.filter(
3577
+ (section) => section.required && !documentedSections.includes(section.id)
3578
+ ).map((section) => ({
3579
+ sectionId: section.id,
3580
+ message: `${section.title} is required.`
3581
+ }));
3582
+ const frontMatter = {
3583
+ richTextEsheet: { id: definition.id, title: definition.title },
3584
+ ...parties?.length ? { parties } : {}
3585
+ };
3586
+ const body = definition.sections.filter((section) => documentedSections.includes(section.id)).map(
3587
+ (section) => `## ${markdownHeading(section.title)}
3588
+
3589
+ ${markdownBody(
3590
+ sectionText(responses, section.id)
3591
+ )}`
3592
+ ).join("\n\n");
3593
+ const mdy = `---
3594
+ ${yaml.stringify(frontMatter)}---
3595
+
3596
+ # ${markdownHeading(
3597
+ definition.title
3598
+ )}
3599
+ ${body ? `
3600
+ ${body}
3601
+ ` : ""}`;
3602
+ return { definition, responses, documentedSections, errors, mdy };
3603
+ }
3604
+ var RichTextEsheet = React11__namespace.forwardRef(function RichTextEsheet2({ messages, ...props }, ref) {
3605
+ return /* @__PURE__ */ jsxRuntime.jsx(chunkFSLI5IKP_cjs.MessagesProvider, { messages, children: /* @__PURE__ */ jsxRuntime.jsx(RichTextEsheetSession, { ...props, ref }, props.definition.id) });
3606
+ });
3607
+ function ensureFields2() {
3608
+ registerEsheetSectionFieldType();
3609
+ registerEsheetNarrativeFieldType();
3610
+ }
3611
+ var esheetDefaultsSettled2 = false;
3612
+ var RichTextEsheetSession = React11__namespace.forwardRef(function RichTextEsheetSession2({
3613
+ definition,
3614
+ parties,
3615
+ initialResponses,
3616
+ onChange,
3617
+ onSubmit,
3618
+ readOnly = false,
3619
+ className,
3620
+ ...props
3621
+ }, ref) {
3622
+ ensureFields2();
3623
+ const [fieldsSettled, setFieldsSettled] = React11__namespace.useState(
3624
+ () => esheetDefaultsSettled2
3625
+ );
3626
+ React11__namespace.useLayoutEffect(() => {
3627
+ if (!esheetDefaultsSettled2) {
3628
+ esheetDefaultsSettled2 = true;
3629
+ ensureFields2();
3630
+ }
3631
+ setFieldsSettled(true);
3632
+ }, []);
3633
+ const m = chunkFSLI5IKP_cjs.useMessages();
3634
+ const configJson = JSON.stringify({ definition, parties });
3635
+ const stable = React11__namespace.useMemo(
3636
+ () => JSON.parse(configJson),
3637
+ [configJson]
3638
+ );
3639
+ const form = React11__namespace.useMemo(
3640
+ () => createRichTextEsheetFormDefinition(stable.definition, stable.parties),
3641
+ [stable]
3642
+ );
3643
+ const [initialSeed] = React11__namespace.useState(() => initialResponses ?? {});
3644
+ const [snapshot, setSnapshot] = React11__namespace.useState(
3645
+ () => createRichTextEsheetSnapshot(stable.definition, initialSeed, stable.parties)
3646
+ );
3647
+ const [showErrors, setShowErrors] = React11__namespace.useState(false);
3648
+ const [saving, setSaving] = React11__namespace.useState(false);
3649
+ const submissionPending = React11__namespace.useRef(false);
3650
+ const [saveMessage, setSaveMessage] = React11__namespace.useState("");
3651
+ const renderer$1 = React11__namespace.useRef(null);
3652
+ const root = React11__namespace.useRef(null);
3653
+ const unsubscribe = React11__namespace.useRef(null);
3654
+ const responses = React11__namespace.useRef(initialSeed);
3655
+ const latest = React11__namespace.useRef({ stable, onChange, onSubmit, readOnly, m });
3656
+ latest.current = { stable, onChange, onSubmit, readOnly, m };
3657
+ const rendererInput = React11__namespace.useMemo(
3658
+ () => ({ definition: form, responses: responses.current }),
3659
+ [form]
3660
+ );
3661
+ const currentSnapshot = React11__namespace.useCallback(() => {
3662
+ const { stable: stable2 } = latest.current;
3663
+ return createRichTextEsheetSnapshot(
3664
+ stable2.definition,
3665
+ renderer$1.current?.getRawResponse() ?? responses.current,
3666
+ stable2.parties
3667
+ );
3668
+ }, []);
3669
+ const focusSection = React11__namespace.useCallback((sectionId) => {
3670
+ const fieldId = getRichTextEsheetSectionFieldId(sectionId);
3671
+ const section = Array.from(
3672
+ root.current?.querySelectorAll("[data-field-id]") ?? []
3673
+ ).find((element) => element.dataset.fieldId === fieldId);
3674
+ if (!section) return;
3675
+ section.tabIndex = -1;
3676
+ section.focus({ preventScroll: true });
3677
+ section.scrollIntoView?.({ block: "start", behavior: "auto" });
3678
+ }, []);
3679
+ React11__namespace.useImperativeHandle(
3680
+ ref,
3681
+ () => ({ getSnapshot: currentSnapshot, focusSection }),
3682
+ [currentSnapshot, focusSection]
3683
+ );
3684
+ const handleReady = React11__namespace.useCallback(() => {
3685
+ const store = renderer$1.current?.getFormStore();
3686
+ if (!store) return;
3687
+ unsubscribe.current?.();
3688
+ const publish = () => {
3689
+ responses.current = store.getState().responses;
3690
+ const next = currentSnapshot();
3691
+ setSnapshot(next);
3692
+ latest.current.onChange?.(next);
3693
+ };
3694
+ unsubscribe.current = store.subscribe((state, previous) => {
3695
+ if (state.responses !== previous.responses) {
3696
+ setSaveMessage("");
3697
+ publish();
3698
+ }
3699
+ });
3700
+ publish();
3701
+ }, [currentSnapshot]);
3702
+ React11__namespace.useLayoutEffect(() => {
3703
+ unsubscribe.current?.();
3704
+ unsubscribe.current = null;
3705
+ }, [rendererInput]);
3706
+ React11__namespace.useEffect(() => () => unsubscribe.current?.(), []);
3707
+ const submit = async () => {
3708
+ const context = latest.current;
3709
+ if (!context.onSubmit || context.readOnly || saving || submissionPending.current)
3710
+ return;
3711
+ submissionPending.current = true;
3712
+ try {
3713
+ const next = currentSnapshot();
3714
+ setShowErrors(true);
3715
+ if (next.errors.length > 0) {
3716
+ setSnapshot(next);
3717
+ setSaveMessage(m("Resolve the highlighted sections before saving."));
3718
+ focusSection(next.errors[0].sectionId);
3719
+ return;
3720
+ }
3721
+ renderer$1.current?.getFormStore().getState().setReadOnly(true);
3722
+ setSaving(true);
3723
+ setSaveMessage("");
3724
+ try {
3725
+ await context.onSubmit(next);
3726
+ setSaveMessage(latest.current.m("Document saved."));
3727
+ } catch (error) {
3728
+ setSaveMessage(
3729
+ error instanceof Error ? error.message : latest.current.m(
3730
+ "Unable to save this document. Your draft is still here."
3731
+ )
3732
+ );
3733
+ } finally {
3734
+ renderer$1.current?.getFormStore().getState().setReadOnly(latest.current.readOnly);
3735
+ setSaving(false);
3736
+ }
3737
+ } finally {
3738
+ submissionPending.current = false;
3739
+ }
3740
+ };
3741
+ return /* @__PURE__ */ jsxRuntime.jsxs(
3742
+ "div",
3743
+ {
3744
+ ...props,
3745
+ ref: root,
3746
+ "data-slot": "richtext-esheet",
3747
+ className: chunkS5RVSXDV_cjs.cn(
3748
+ "richtext-esheet bg-background text-foreground min-w-0",
3749
+ className
3750
+ ),
3751
+ children: [
3752
+ /* @__PURE__ */ jsxRuntime.jsxs("header", { className: "flex flex-wrap items-start justify-between gap-2 px-2 pt-3 pb-2 sm:px-3", children: [
3753
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0", children: [
3754
+ /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-lg font-semibold", children: m(stable.definition.title) }),
3755
+ stable.parties && stable.parties.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("dl", { className: "mt-1 space-y-0.5 text-sm", children: stable.parties.map((party, index) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap gap-x-1.5", children: [
3756
+ /* @__PURE__ */ jsxRuntime.jsx("dt", { className: "text-muted-foreground", children: m(party.role) }),
3757
+ /* @__PURE__ */ jsxRuntime.jsxs("dd", { dir: "auto", className: "break-words", children: [
3758
+ party.name,
3759
+ party.detail && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-muted-foreground", children: [
3760
+ " ",
3761
+ "(",
3762
+ party.detail,
3763
+ ")"
3764
+ ] })
3765
+ ] })
3766
+ ] }, index)) })
3767
+ ] }),
3768
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-muted-foreground text-xs", children: /* @__PURE__ */ jsxRuntime.jsx("bdi", { children: m("{count} of {total} sections documented", {
3769
+ count: snapshot.documentedSections.length,
3770
+ total: stable.definition.sections.length
3771
+ }) }) })
3772
+ ] }),
3773
+ /* @__PURE__ */ jsxRuntime.jsxs(
3774
+ "div",
3775
+ {
3776
+ "data-slot": "richtext-esheet-document",
3777
+ className: "min-w-0 px-2 pt-2 pb-4 sm:px-3",
3778
+ children: [
3779
+ showErrors && snapshot.errors.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs(
3780
+ "div",
3781
+ {
3782
+ role: "alert",
3783
+ className: "border-destructive/40 bg-destructive/5 mb-4 rounded-lg border p-3 text-sm",
3784
+ children: [
3785
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "font-semibold", children: m("Sections need attention") }),
3786
+ /* @__PURE__ */ jsxRuntime.jsx("ul", { className: "mt-2 space-y-1", children: snapshot.errors.map((issue) => /* @__PURE__ */ jsxRuntime.jsx("li", { children: /* @__PURE__ */ jsxRuntime.jsx(
3787
+ "button",
3788
+ {
3789
+ type: "button",
3790
+ className: "text-destructive min-h-11 text-start underline underline-offset-2",
3791
+ onClick: () => focusSection(issue.sectionId),
3792
+ children: m("{section} is required.", {
3793
+ section: stable.definition.sections.find(
3794
+ (section) => section.id === issue.sectionId
3795
+ )?.title ?? issue.sectionId
3796
+ })
3797
+ }
3798
+ ) }, issue.sectionId)) })
3799
+ ]
3800
+ }
3801
+ ),
3802
+ /* @__PURE__ */ jsxRuntime.jsx(EsheetSectionContext.Provider, { value: true, children: /* @__PURE__ */ jsxRuntime.jsx(
3803
+ renderer.EsheetRenderer,
3804
+ {
3805
+ ref: renderer$1,
3806
+ formDataInput: rendererInput.definition,
3807
+ initialResponses: rendererInput.responses,
3808
+ onReady: handleReady,
3809
+ strict: true,
3810
+ readOnly: readOnly || saving,
3811
+ fitToContainer: true,
3812
+ topNavigation: false,
3813
+ bottomNavigation: false,
3814
+ className: "richtext-esheet-renderer"
3815
+ },
3816
+ fieldsSettled ? "settled" : "priming"
3817
+ ) })
3818
+ ]
3819
+ }
3820
+ ),
3821
+ /* @__PURE__ */ jsxRuntime.jsxs("footer", { className: "bg-background sticky bottom-0 z-10 flex flex-wrap items-center justify-between gap-2 px-2 pt-2 pb-[max(0.5rem,env(safe-area-inset-bottom))] sm:px-3", children: [
3822
+ /* @__PURE__ */ jsxRuntime.jsx(
3823
+ "p",
3824
+ {
3825
+ role: "status",
3826
+ "aria-live": "polite",
3827
+ className: "text-muted-foreground min-w-0 text-sm",
3828
+ children: saveMessage || (readOnly ? m("Read-only document") : "")
3829
+ }
3830
+ ),
3831
+ onSubmit && /* @__PURE__ */ jsxRuntime.jsx(
3832
+ chunkFSARTLUE_cjs.Button,
3833
+ {
3834
+ type: "button",
3835
+ className: "min-h-11",
3836
+ disabled: readOnly || saving,
3837
+ leftIcon: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Save, { size: 16, "aria-hidden": "true" }),
3838
+ onClick: () => void submit(),
3839
+ children: m(saving ? "Saving\u2026" : "Save document")
3840
+ }
3841
+ )
3842
+ ] })
3843
+ ]
3844
+ }
3845
+ );
3846
+ });
4140
3847
  function parseValue(answer) {
4141
3848
  if (!answer) return { medications: [] };
4142
3849
  try {
@@ -4167,7 +3874,7 @@ function MedicationListField({
4167
3874
  return definition.medications ?? [];
4168
3875
  }, [response?.answer, definition.medications]);
4169
3876
  return /* @__PURE__ */ jsxRuntime.jsx(
4170
- chunkSCYLVQWA_cjs.MedicationReconciliation,
3877
+ chunk6O6EYKOG_cjs.MedicationReconciliation,
4171
3878
  {
4172
3879
  medications,
4173
3880
  onChange: (next) => onResponse({ answer: JSON.stringify({ medications: next }) }),
@@ -4225,7 +3932,7 @@ function AllergyListField({
4225
3932
  codeLookup
4226
3933
  }) {
4227
3934
  const definition = field.definition;
4228
- const ambientCodeLookup = chunkSCYLVQWA_cjs.useCodeLookupConfig();
3935
+ const ambientCodeLookup = chunk6O6EYKOG_cjs.useCodeLookupConfig();
4229
3936
  const effectiveCodeLookup = codeLookup === false ? void 0 : codeLookup ?? ambientCodeLookup ?? void 0;
4230
3937
  const value = React11__namespace.useMemo(() => {
4231
3938
  if (response?.answer) return parseValue2(response.answer);
@@ -4235,7 +3942,7 @@ function AllergyListField({
4235
3942
  onResponse({ answer: JSON.stringify(next) });
4236
3943
  };
4237
3944
  return /* @__PURE__ */ jsxRuntime.jsx(
4238
- chunkSCYLVQWA_cjs.AllergyManager,
3945
+ chunk6O6EYKOG_cjs.AllergyManager,
4239
3946
  {
4240
3947
  allergies: value.allergies,
4241
3948
  onChange: (allergies) => commit({
@@ -4277,123 +3984,123 @@ function registerMieEsheetFields(options) {
4277
3984
 
4278
3985
  Object.defineProperty(exports, "DEFAULT_ENCOUNTER_VISIT_DEFINITION", {
4279
3986
  enumerable: true,
4280
- get: function () { return chunkM42FTWY2_cjs.DEFAULT_ENCOUNTER_VISIT_DEFINITION; }
3987
+ get: function () { return chunk46RYJYN2_cjs.DEFAULT_ENCOUNTER_VISIT_DEFINITION; }
4281
3988
  });
4282
3989
  Object.defineProperty(exports, "ENCOUNTER_DOCUMENT_FIELD_ID", {
4283
3990
  enumerable: true,
4284
- get: function () { return chunkM42FTWY2_cjs.ENCOUNTER_DOCUMENT_FIELD_ID; }
3991
+ get: function () { return chunk46RYJYN2_cjs.ENCOUNTER_DOCUMENT_FIELD_ID; }
4285
3992
  });
4286
3993
  Object.defineProperty(exports, "EXAMPLE_ENCOUNTER_VISIT_RESPONSES", {
4287
3994
  enumerable: true,
4288
- get: function () { return chunkM42FTWY2_cjs.EXAMPLE_ENCOUNTER_VISIT_RESPONSES; }
3995
+ get: function () { return chunk46RYJYN2_cjs.EXAMPLE_ENCOUNTER_VISIT_RESPONSES; }
4289
3996
  });
4290
3997
  Object.defineProperty(exports, "createEncounterFormDefinition", {
4291
3998
  enumerable: true,
4292
- get: function () { return chunkM42FTWY2_cjs.createEncounterFormDefinition; }
3999
+ get: function () { return chunk46RYJYN2_cjs.createEncounterFormDefinition; }
4293
4000
  });
4294
4001
  Object.defineProperty(exports, "createEncounterMdy", {
4295
4002
  enumerable: true,
4296
- get: function () { return chunkM42FTWY2_cjs.createEncounterMdy; }
4003
+ get: function () { return chunk46RYJYN2_cjs.createEncounterMdy; }
4297
4004
  });
4298
4005
  Object.defineProperty(exports, "createEncounterSnapshot", {
4299
4006
  enumerable: true,
4300
- get: function () { return chunkM42FTWY2_cjs.createEncounterSnapshot; }
4007
+ get: function () { return chunk46RYJYN2_cjs.createEncounterSnapshot; }
4301
4008
  });
4302
4009
  Object.defineProperty(exports, "encounterDocumentResponse", {
4303
4010
  enumerable: true,
4304
- get: function () { return chunkM42FTWY2_cjs.encounterDocumentResponse; }
4011
+ get: function () { return chunk46RYJYN2_cjs.encounterDocumentResponse; }
4305
4012
  });
4306
4013
  Object.defineProperty(exports, "getEncounterConcerns", {
4307
4014
  enumerable: true,
4308
- get: function () { return chunkM42FTWY2_cjs.getEncounterConcerns; }
4015
+ get: function () { return chunk46RYJYN2_cjs.getEncounterConcerns; }
4309
4016
  });
4310
4017
  Object.defineProperty(exports, "getEncounterDocumentBody", {
4311
4018
  enumerable: true,
4312
- get: function () { return chunkM42FTWY2_cjs.getEncounterDocumentBody; }
4019
+ get: function () { return chunk46RYJYN2_cjs.getEncounterDocumentBody; }
4313
4020
  });
4314
4021
  Object.defineProperty(exports, "getEncounterFieldId", {
4315
4022
  enumerable: true,
4316
- get: function () { return chunkM42FTWY2_cjs.getEncounterFieldId; }
4023
+ get: function () { return chunk46RYJYN2_cjs.getEncounterFieldId; }
4317
4024
  });
4318
4025
  Object.defineProperty(exports, "getEncounterMdyFields", {
4319
4026
  enumerable: true,
4320
- get: function () { return chunkM42FTWY2_cjs.getEncounterMdyFields; }
4027
+ get: function () { return chunk46RYJYN2_cjs.getEncounterMdyFields; }
4321
4028
  });
4322
4029
  Object.defineProperty(exports, "getEncounterSectionFieldId", {
4323
4030
  enumerable: true,
4324
- get: function () { return chunkM42FTWY2_cjs.getEncounterSectionFieldId; }
4031
+ get: function () { return chunk46RYJYN2_cjs.getEncounterSectionFieldId; }
4325
4032
  });
4326
4033
  Object.defineProperty(exports, "getEncounterSectionFieldIds", {
4327
4034
  enumerable: true,
4328
- get: function () { return chunkM42FTWY2_cjs.getEncounterSectionFieldIds; }
4035
+ get: function () { return chunk46RYJYN2_cjs.getEncounterSectionFieldIds; }
4329
4036
  });
4330
4037
  Object.defineProperty(exports, "parseEncounterAssessment", {
4331
4038
  enumerable: true,
4332
- get: function () { return chunkM42FTWY2_cjs.parseEncounterAssessment; }
4039
+ get: function () { return chunk46RYJYN2_cjs.parseEncounterAssessment; }
4333
4040
  });
4334
4041
  Object.defineProperty(exports, "parseEncounterConditions", {
4335
4042
  enumerable: true,
4336
- get: function () { return chunkM42FTWY2_cjs.parseEncounterConditions; }
4043
+ get: function () { return chunk46RYJYN2_cjs.parseEncounterConditions; }
4337
4044
  });
4338
4045
  Object.defineProperty(exports, "parseEncounterMdy", {
4339
4046
  enumerable: true,
4340
- get: function () { return chunkM42FTWY2_cjs.parseEncounterMdy; }
4047
+ get: function () { return chunk46RYJYN2_cjs.parseEncounterMdy; }
4341
4048
  });
4342
4049
  Object.defineProperty(exports, "parseEncounterPlan", {
4343
4050
  enumerable: true,
4344
- get: function () { return chunkM42FTWY2_cjs.parseEncounterPlan; }
4051
+ get: function () { return chunk46RYJYN2_cjs.parseEncounterPlan; }
4345
4052
  });
4346
4053
  Object.defineProperty(exports, "parseEncounterVitals", {
4347
4054
  enumerable: true,
4348
- get: function () { return chunkM42FTWY2_cjs.parseEncounterVitals; }
4055
+ get: function () { return chunk46RYJYN2_cjs.parseEncounterVitals; }
4349
4056
  });
4350
4057
  Object.defineProperty(exports, "refreshEncounterMdyLinks", {
4351
4058
  enumerable: true,
4352
- get: function () { return chunkM42FTWY2_cjs.refreshEncounterMdyLinks; }
4059
+ get: function () { return chunk46RYJYN2_cjs.refreshEncounterMdyLinks; }
4353
4060
  });
4354
4061
  Object.defineProperty(exports, "renderEncounterMdy", {
4355
4062
  enumerable: true,
4356
- get: function () { return chunkM42FTWY2_cjs.renderEncounterMdy; }
4063
+ get: function () { return chunk46RYJYN2_cjs.renderEncounterMdy; }
4357
4064
  });
4358
4065
  Object.defineProperty(exports, "updateEncounterDocumentBody", {
4359
4066
  enumerable: true,
4360
- get: function () { return chunkM42FTWY2_cjs.updateEncounterDocumentBody; }
4067
+ get: function () { return chunk46RYJYN2_cjs.updateEncounterDocumentBody; }
4361
4068
  });
4362
4069
  Object.defineProperty(exports, "validAssessmentItem", {
4363
4070
  enumerable: true,
4364
- get: function () { return chunkM42FTWY2_cjs.validAssessmentItem; }
4071
+ get: function () { return chunk46RYJYN2_cjs.validAssessmentItem; }
4365
4072
  });
4366
4073
  Object.defineProperty(exports, "validateEncounterAllergyValue", {
4367
4074
  enumerable: true,
4368
- get: function () { return chunkM42FTWY2_cjs.validateEncounterAllergyValue; }
4075
+ get: function () { return chunk46RYJYN2_cjs.validateEncounterAllergyValue; }
4369
4076
  });
4370
4077
  Object.defineProperty(exports, "validateEncounterAssessment", {
4371
4078
  enumerable: true,
4372
- get: function () { return chunkM42FTWY2_cjs.validateEncounterAssessment; }
4079
+ get: function () { return chunk46RYJYN2_cjs.validateEncounterAssessment; }
4373
4080
  });
4374
4081
  Object.defineProperty(exports, "validateEncounterConditions", {
4375
4082
  enumerable: true,
4376
- get: function () { return chunkM42FTWY2_cjs.validateEncounterConditions; }
4083
+ get: function () { return chunk46RYJYN2_cjs.validateEncounterConditions; }
4377
4084
  });
4378
4085
  Object.defineProperty(exports, "validateEncounterDefinition", {
4379
4086
  enumerable: true,
4380
- get: function () { return chunkM42FTWY2_cjs.validateEncounterDefinition; }
4087
+ get: function () { return chunk46RYJYN2_cjs.validateEncounterDefinition; }
4381
4088
  });
4382
4089
  Object.defineProperty(exports, "validateEncounterMedicationValue", {
4383
4090
  enumerable: true,
4384
- get: function () { return chunkM42FTWY2_cjs.validateEncounterMedicationValue; }
4091
+ get: function () { return chunk46RYJYN2_cjs.validateEncounterMedicationValue; }
4385
4092
  });
4386
4093
  Object.defineProperty(exports, "validateEncounterPlan", {
4387
4094
  enumerable: true,
4388
- get: function () { return chunkM42FTWY2_cjs.validateEncounterPlan; }
4095
+ get: function () { return chunk46RYJYN2_cjs.validateEncounterPlan; }
4389
4096
  });
4390
4097
  Object.defineProperty(exports, "validateEncounterResponses", {
4391
4098
  enumerable: true,
4392
- get: function () { return chunkM42FTWY2_cjs.validateEncounterResponses; }
4099
+ get: function () { return chunk46RYJYN2_cjs.validateEncounterResponses; }
4393
4100
  });
4394
4101
  Object.defineProperty(exports, "validateEncounterVitals", {
4395
4102
  enumerable: true,
4396
- get: function () { return chunkM42FTWY2_cjs.validateEncounterVitals; }
4103
+ get: function () { return chunk46RYJYN2_cjs.validateEncounterVitals; }
4397
4104
  });
4398
4105
  Object.defineProperty(exports, "EsheetRenderer", {
4399
4106
  enumerable: true,
@@ -4414,12 +4121,31 @@ exports.EncounterNarrativeField = EncounterNarrativeField;
4414
4121
  exports.EncounterPlanField = EncounterPlanField;
4415
4122
  exports.EncounterVisit = EncounterVisit;
4416
4123
  exports.EncounterVitalsField = EncounterVitalsField;
4124
+ exports.EsheetNarrativeField = EsheetNarrativeField;
4125
+ exports.EsheetSectionContext = EsheetSectionContext;
4126
+ exports.EsheetSectionField = EsheetSectionField;
4417
4127
  exports.MedicationListField = MedicationListField;
4128
+ exports.NARRATIVE_ATTRIBUTES = NARRATIVE_ATTRIBUTES;
4129
+ exports.RichTextEsheet = RichTextEsheet;
4130
+ exports.applyNarrativeFinding = applyNarrativeFinding;
4418
4131
  exports.createEncounterVisitTools = createEncounterVisitTools;
4132
+ exports.createRichTextEsheetFormDefinition = createRichTextEsheetFormDefinition;
4133
+ exports.createRichTextEsheetSnapshot = createRichTextEsheetSnapshot;
4419
4134
  exports.executeEncounterVisitToolCall = executeEncounterVisitToolCall;
4135
+ exports.getNarrativeFindings = getNarrativeFindings;
4136
+ exports.getRichTextEsheetFieldId = getRichTextEsheetFieldId;
4137
+ exports.getRichTextEsheetSectionFieldId = getRichTextEsheetSectionFieldId;
4138
+ exports.hasNarrativeFindingText = hasNarrativeFindingText;
4139
+ exports.narrativeText = narrativeText;
4140
+ exports.partyFindings = partyFindings;
4420
4141
  exports.registerAllergyListFieldType = registerAllergyListFieldType;
4421
4142
  exports.registerEncounterFieldTypes = registerEncounterFieldTypes;
4143
+ exports.registerEsheetNarrativeFieldType = registerEsheetNarrativeFieldType;
4144
+ exports.registerEsheetSectionFieldType = registerEsheetSectionFieldType;
4422
4145
  exports.registerMedicationListFieldType = registerMedicationListFieldType;
4423
4146
  exports.registerMieEsheetFields = registerMieEsheetFields;
4147
+ exports.sanitizeNarrativeHtml = sanitizeNarrativeHtml;
4148
+ exports.validNarrativeFindings = validNarrativeFindings;
4149
+ exports.validateRichTextEsheetDefinition = validateRichTextEsheetDefinition;
4424
4150
  //# sourceMappingURL=esheet.cjs.map
4425
4151
  //# sourceMappingURL=esheet.cjs.map