@f1studio/form-spec 5.0.0-alpha.101 → 5.0.0-alpha.103

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 (161) hide show
  1. package/Components/HelloComponent.d.ts +20 -0
  2. package/Components/HelloComponent.d.ts.map +1 -0
  3. package/Designer.d.ts.map +1 -0
  4. package/FormSpec.TS/Designer.js +2 -2
  5. package/FormSpec.TS/Designer.js.map +1 -1
  6. package/FormSpec.TS/Designer.ts.map +1 -1
  7. package/FormSpec.TS/FormSpec.js +210 -143
  8. package/FormSpec.TS/FormSpec.js.map +1 -1
  9. package/FormSpec.TS/FormSpec.ts.map +1 -1
  10. package/FormSpec.TS/FormSpecHelpers.js +62 -40
  11. package/FormSpec.TS/FormSpecHelpers.js.map +1 -1
  12. package/FormSpec.TS/FormSpecHelpers.ts.map +1 -1
  13. package/FormSpec.TS/FormSpecValues.js +207 -0
  14. package/FormSpec.TS/FormSpecValues.js.map +1 -0
  15. package/FormSpec.TS/FormSpecValues.ts.map +1 -0
  16. package/FormSpec.TS/Helpers.js +26 -25
  17. package/FormSpec.TS/Helpers.js.map +1 -1
  18. package/FormSpec.TS/Helpers.ts.map +1 -1
  19. package/FormSpec.TS/Interop/FormSpec.Api.Helpers.js +85 -125
  20. package/FormSpec.TS/Interop/FormSpec.Api.Helpers.js.map +1 -1
  21. package/FormSpec.TS/Interop/FormSpec.Api.Helpers.ts.map +1 -1
  22. package/FormSpec.TS/Interop/FormSpec.Api.Option.js +37 -7
  23. package/FormSpec.TS/Interop/FormSpec.Api.Option.js.map +1 -1
  24. package/FormSpec.TS/Interop/FormSpec.Api.Option.ts.map +1 -1
  25. package/FormSpec.TS/Interop/FormSpec.Values.Api.Option.js +103 -80
  26. package/FormSpec.TS/Interop/FormSpec.Values.Api.Option.js.map +1 -1
  27. package/FormSpec.TS/Interop/FormSpec.Values.Api.Option.ts.map +1 -1
  28. package/FormSpec.TS/PathwayExecutor.js +371 -125
  29. package/FormSpec.TS/PathwayExecutor.js.map +1 -1
  30. package/FormSpec.TS/PathwayExecutor.ts.map +1 -1
  31. package/FormSpec.TS/PathwayValidator.js +14 -26
  32. package/FormSpec.TS/PathwayValidator.js.map +1 -1
  33. package/FormSpec.TS/PathwayValidator.ts.map +1 -1
  34. package/FormSpec.TS/Renderers/FormSpecMarkdownRenderer.ts.map +1 -1
  35. package/FormSpec.TS/Renderers/PathwayRenderers.js +35 -26
  36. package/FormSpec.TS/Renderers/PathwayRenderers.js.map +1 -1
  37. package/FormSpec.TS/Renderers/PathwayRenderers.ts.map +1 -1
  38. package/FormSpec.TS/fable_modules/Fable.Form.3.0.0/Base.fs +0 -0
  39. package/FormSpec.TS/fable_modules/Fable.Form.3.0.0/Error.fs +0 -0
  40. package/FormSpec.TS/fable_modules/Fable.Form.3.0.0/Extensions.fs +0 -0
  41. package/FormSpec.TS/fable_modules/Fable.Form.3.0.0/Fable.Form.fableproj +0 -0
  42. package/FormSpec.TS/fable_modules/Fable.Form.3.0.0/Field.fs +0 -0
  43. package/FormSpec.TS/fable_modules/Fable.Form.Simple.5.0.1/Fable.Form.Simple.fableproj +0 -0
  44. package/FormSpec.TS/fable_modules/Fable.Form.Simple.5.0.1/Form.fs +0 -0
  45. package/FormSpec.TS/fable_modules/Fable.React.Types.18.3.0/Fable.React.Extensions.fs +0 -0
  46. package/FormSpec.TS/fable_modules/Fable.React.Types.18.3.0/Fable.React.Hooks.fs +0 -0
  47. package/FormSpec.TS/fable_modules/Fable.React.Types.18.3.0/Fable.React.Types.fableproj +0 -0
  48. package/FormSpec.TS/fable_modules/Fable.React.Types.18.3.0/Fable.React.fs +0 -0
  49. package/FormSpec.TS/fable_modules/Fable.ReactDom.Types.18.2.0/Fable.ReactDom.Types.fableproj +0 -0
  50. package/FormSpec.TS/fable_modules/Fable.ReactDom.Types.18.2.0/Fable.ReactDom.fs +0 -0
  51. package/FormSpec.TS/fable_modules/Feliz.2.7.0/BorderStyle.fs +0 -0
  52. package/FormSpec.TS/fable_modules/Feliz.2.7.0/Colors.fs +0 -0
  53. package/FormSpec.TS/fable_modules/Feliz.2.7.0/Feliz.fableproj +0 -0
  54. package/FormSpec.TS/fable_modules/Feliz.2.7.0/Fonts.fs +0 -0
  55. package/FormSpec.TS/fable_modules/Feliz.2.7.0/GridTypes.fs +0 -0
  56. package/FormSpec.TS/fable_modules/Feliz.2.7.0/Html.fs +0 -0
  57. package/FormSpec.TS/fable_modules/Feliz.2.7.0/Interop.fs +0 -0
  58. package/FormSpec.TS/fable_modules/Feliz.2.7.0/Key.fs +0 -0
  59. package/FormSpec.TS/fable_modules/Feliz.2.7.0/Length.fs +0 -0
  60. package/FormSpec.TS/fable_modules/Feliz.2.7.0/Locale.fs +0 -0
  61. package/FormSpec.TS/fable_modules/Feliz.2.7.0/Properties.fs +0 -0
  62. package/FormSpec.TS/fable_modules/Feliz.2.7.0/React.fs +0 -0
  63. package/FormSpec.TS/fable_modules/Feliz.2.7.0/ReactDOM.fs +0 -0
  64. package/FormSpec.TS/fable_modules/Feliz.2.7.0/ReactInterop.js +0 -0
  65. package/FormSpec.TS/fable_modules/Feliz.2.7.0/ReactInterop.js.map +0 -0
  66. package/FormSpec.TS/fable_modules/Feliz.2.7.0/ReactTypes.fs +0 -0
  67. package/FormSpec.TS/fable_modules/Feliz.2.7.0/StyleTypes.fs +0 -0
  68. package/FormSpec.TS/fable_modules/Feliz.2.7.0/Styles.fs +0 -0
  69. package/FormSpec.TS/fable_modules/Feliz.2.7.0/Svg.fs +0 -0
  70. package/FormSpec.TS/fable_modules/Feliz.2.7.0/TextDecorationLine.fs +0 -0
  71. package/FormSpec.TS/fable_modules/Feliz.2.7.0/TextDecorationStyle.fs +0 -0
  72. package/FormSpec.TS/fable_modules/Feliz.2.7.0/Transform.fs +0 -0
  73. package/FormSpec.TS/fable_modules/Feliz.2.7.0/TransformOrigin.fs +0 -0
  74. package/FormSpec.TS/fable_modules/Feliz.2.7.0/TransitionProperty.fs +0 -0
  75. package/FormSpec.TS/fable_modules/Feliz.2.7.0/Types.fs +0 -0
  76. package/FormSpec.TS/fable_modules/Thoth.Json.10.4.1/Decode.fs +0 -0
  77. package/FormSpec.TS/fable_modules/Thoth.Json.10.4.1/Encode.fs +0 -0
  78. package/FormSpec.TS/fable_modules/Thoth.Json.10.4.1/Encode.fs.js.map +1 -1
  79. package/FormSpec.TS/fable_modules/Thoth.Json.10.4.1/Encode.fs.ts.map +1 -1
  80. package/FormSpec.TS/fable_modules/Thoth.Json.10.4.1/Extra.fs +0 -0
  81. package/FormSpec.TS/fable_modules/Thoth.Json.10.4.1/Thoth.Json.fableproj +0 -0
  82. package/FormSpec.TS/fable_modules/Thoth.Json.10.4.1/Types.fs +0 -0
  83. package/FormSpec.TS/fable_modules/project_cracked.json +1 -1
  84. package/FormSpec.d.ts +56 -43
  85. package/FormSpec.d.ts.map +1 -0
  86. package/FormSpecHelpers.d.ts +18 -12
  87. package/FormSpecHelpers.d.ts.map +1 -0
  88. package/FormSpecValues.d.ts +62 -0
  89. package/FormSpecValues.d.ts.map +1 -0
  90. package/Helpers.d.ts +11 -10
  91. package/Helpers.d.ts.map +1 -0
  92. package/Interfaces.d.ts.map +1 -0
  93. package/Interop/FormSpec.Api.Helpers.d.ts +25 -28
  94. package/Interop/FormSpec.Api.Helpers.d.ts.map +1 -1
  95. package/Interop/FormSpec.Api.Option.d.ts +10 -6
  96. package/Interop/FormSpec.Api.Option.d.ts.map +1 -1
  97. package/Interop/FormSpec.Values.Api.Option.d.ts +35 -22
  98. package/Interop/FormSpec.Values.Api.Option.d.ts.map +1 -1
  99. package/Logging/LogTypes.d.ts +112 -0
  100. package/Logging/LogTypes.d.ts.map +1 -0
  101. package/Migrator.d.ts.map +1 -0
  102. package/PathwayDataExtractor.d.ts.map +1 -0
  103. package/PathwayExecutor.d.ts +63 -33
  104. package/PathwayExecutor.d.ts.map +1 -0
  105. package/PathwayValidator.d.ts.map +1 -0
  106. package/PluginInterface.d.ts.map +1 -0
  107. package/Prelude.d.ts.map +1 -0
  108. package/README.TS.md +621 -621
  109. package/README.md +98 -85
  110. package/Renderers/FormSpecMarkdownRenderer.d.ts +11 -0
  111. package/Renderers/FormSpecMarkdownRenderer.d.ts.map +1 -0
  112. package/Renderers/MermaidRenderer.d.ts +48 -0
  113. package/Renderers/MermaidRenderer.d.ts.map +1 -0
  114. package/Renderers/PathwayRenderers.d.ts +59 -0
  115. package/Renderers/PathwayRenderers.d.ts.map +1 -0
  116. package/fable_modules/Thoth.Json.10.4.1/Decode.fs.d.ts +126 -0
  117. package/fable_modules/Thoth.Json.10.4.1/Decode.fs.d.ts.map +1 -0
  118. package/fable_modules/Thoth.Json.10.4.1/Encode.fs.d.ts +163 -0
  119. package/fable_modules/Thoth.Json.10.4.1/Encode.fs.d.ts.map +1 -0
  120. package/fable_modules/Thoth.Json.10.4.1/Types.fs.d.ts +66 -0
  121. package/fable_modules/Thoth.Json.10.4.1/Types.fs.d.ts.map +1 -0
  122. package/package.json +53 -39
  123. package/src/Components/HelloComponent.ts +48 -48
  124. package/src/Designer.ts +389 -389
  125. package/src/FormSpec.ts +3154 -3114
  126. package/src/FormSpecHelpers.ts +397 -374
  127. package/src/FormSpecValues.ts +158 -0
  128. package/src/Helpers.ts +766 -765
  129. package/src/Interfaces.ts +166 -166
  130. package/src/Interop/FormSpec.Api.Helpers.ts +835 -872
  131. package/src/Interop/FormSpec.Api.Option.ts +1637 -1618
  132. package/src/Interop/FormSpec.Values.Api.Option.ts +1241 -1214
  133. package/src/Logging/LogTypes.ts +212 -212
  134. package/src/Migrator.ts +156 -156
  135. package/src/PathwayDataExtractor.ts +290 -290
  136. package/src/PathwayExecutor.ts +1379 -1102
  137. package/src/PathwayValidator.ts +238 -244
  138. package/src/PluginInterface.ts +79 -79
  139. package/src/Prelude.ts +21 -21
  140. package/src/Renderers/FormSpecMarkdownRenderer.ts +875 -874
  141. package/src/Renderers/MermaidRenderer.ts +218 -218
  142. package/src/Renderers/PathwayRenderers.ts +208 -200
  143. package/src/Components/HelloComponent.ts.map +0 -1
  144. package/src/Designer.ts.map +0 -1
  145. package/src/FormSpec.ts.map +0 -1
  146. package/src/FormSpecHelpers.ts.map +0 -1
  147. package/src/Helpers.ts.map +0 -1
  148. package/src/Interfaces.ts.map +0 -1
  149. package/src/Interop/FormSpec.Api.Helpers.ts.map +0 -1
  150. package/src/Interop/FormSpec.Api.Option.ts.map +0 -1
  151. package/src/Interop/FormSpec.Values.Api.Option.ts.map +0 -1
  152. package/src/Logging/LogTypes.ts.map +0 -1
  153. package/src/Migrator.ts.map +0 -1
  154. package/src/PathwayDataExtractor.ts.map +0 -1
  155. package/src/PathwayExecutor.ts.map +0 -1
  156. package/src/PathwayValidator.ts.map +0 -1
  157. package/src/PluginInterface.ts.map +0 -1
  158. package/src/Prelude.ts.map +0 -1
  159. package/src/Renderers/FormSpecMarkdownRenderer.ts.map +0 -1
  160. package/src/Renderers/MermaidRenderer.ts.map +0 -1
  161. package/src/Renderers/PathwayRenderers.ts.map +0 -1
@@ -1,1102 +1,1379 @@
1
- import { FSharpRef, Record, Union } from "@fable-org/fable-library-js/Types.js";
2
- import { fold, tryPick, sortByDescending, truncate, length, sortBy, tryHead, filter, ofArray as ofArray_1, append, empty, tryFind as tryFind_1, head, tail, isEmpty, choose, concat, forAll, singleton, exists, collect, map, FSharpList } from "@fable-org/fable-library-js/List.js";
3
- import { tuple_type, bool_type, float64_type, lambda_type, class_type, record_type, int32_type, union_type, list_type, string_type, TypeInfo } from "@fable-org/fable-library-js/Reflection.js";
4
- import { ClinicalPathway_PathwayExecutionMode_$reflection, ClinicalPathway_SetFieldValueAction, ClinicalPathway_FieldValueSource_$union, ClinicalPathway_PathwayExecutionMode_$union, ClinicalPathway_SelectionStrategy_$union, ClinicalPathway_CombinationStrategy_$union, ClinicalPathway_StateType_$union, ClinicalPathway_StateDefinition, Shared_PluginPropertyKey, Shared_FieldOption, Spec_FieldType_$union, Shared_FieldOptionKey, ClinicalPathway_TransitionCondition_$union, ClinicalPathway_LogicalOp_$union, ClinicalPathway_StateEvaluator_$union, Shared_FieldValue_Single, Shared_ConditionValue_$union, ClinicalPathway_FieldEvaluator_$union, Values_StepOrder, Shared_PluginDataProperty, Shared_FieldValue_$union, Values_FieldDetails$1, Shared_PluginDataProperty_$reflection, Shared_MatrixItemKey, Shared_FieldAnswer, Spec_FormStep$1, Spec_FormField$1, Shared_TransitionKey_$reflection, Shared_TransitionKey, Shared_FieldKey_$reflection, Values_DynamicFormResultData$1_$reflection, ClinicalPathway_ActionInfo_$reflection, Spec_FormSpec$1_$reflection, ClinicalPathway_ClinicalPathwaySpec_$reflection, Shared_FieldKey, Values_DynamicFormResultData$1, ClinicalPathway_ActionInfo_$union, Spec_FormSpec$1, ClinicalPathway_ClinicalPathwaySpec, Shared_StateKey_$reflection, Shared_StateKey, ClinicalPathway_TransitionDefinition_$reflection, ClinicalPathway_TransitionDefinition } from "./FormSpec.js";
5
- import { uint8, float64, int32 } from "@fable-org/fable-library-js/Int32.js";
6
- import { equals, compare, comparePrimitives, stringHash, IComparable, IEquatable } from "@fable-org/fable-library-js/Util.js";
7
- import { difference, union, empty as empty_1, FSharpSet__get_IsEmpty, FSharpSet__get_Count, contains, ofList as ofList_1, isSubset, ofArray, map as map_2, toList, FSharpSet } from "@fable-org/fable-library-js/Set.js";
8
- import { map as map_3, setItem, iterateIndexed, fill } from "@fable-org/fable-library-js/Array.js";
9
- import { getBytesInt32 } from "@fable-org/fable-library-js/BitConverter.js";
10
- import { arrayToGuid } from "@fable-org/fable-library-js/Guid.js";
11
- import { empty as empty_2, FSharpMap__Add, toSeq, toList as toList_1, ofSeq, tryFind, FSharpMap, ofList } from "@fable-org/fable-library-js/Map.js";
12
- import { defaultArg, toArray, some, map as map_4, bind, value as value_3, Option } from "@fable-org/fable-library-js/Option.js";
13
- import { map as map_1, collect as collect_1 } from "@fable-org/fable-library-js/Seq.js";
14
- import { printf, toText, isNullOrWhiteSpace, join } from "@fable-org/fable-library-js/String.js";
15
- import { Auto_generateBoxedEncoder_437914C6, toString } from "./fable_modules/Thoth.Json.10.4.1/Encode.fs.js";
16
- import { tryParse } from "@fable-org/fable-library-js/Double.js";
17
- import { create, isMatch } from "@fable-org/fable-library-js/RegExp.js";
18
- import { now } from "@fable-org/fable-library-js/Date.js";
19
-
20
- export type TransitionStatus_$union =
21
- | TransitionStatus<0>
22
- | TransitionStatus<1>
23
- | TransitionStatus<2>
24
-
25
- export type TransitionStatus_$cases = {
26
- 0: ["Satisfied", []],
27
- 1: ["Failed", []],
28
- 2: ["Pending", [FSharpList<string>]]
29
- }
30
-
31
- export function TransitionStatus_Satisfied() {
32
- return new TransitionStatus<0>(0, []);
33
- }
34
-
35
- export function TransitionStatus_Failed() {
36
- return new TransitionStatus<1>(1, []);
37
- }
38
-
39
- export function TransitionStatus_Pending(missingFields: FSharpList<string>) {
40
- return new TransitionStatus<2>(2, [missingFields]);
41
- }
42
-
43
- export class TransitionStatus<Tag extends keyof TransitionStatus_$cases> extends Union<Tag, TransitionStatus_$cases[Tag][0]> {
44
- constructor(readonly tag: Tag, readonly fields: TransitionStatus_$cases[Tag][1]) {
45
- super();
46
- }
47
- cases() {
48
- return ["Satisfied", "Failed", "Pending"];
49
- }
50
- }
51
-
52
- export function TransitionStatus_$reflection(): TypeInfo {
53
- return union_type("F1.Studio.PathwayExecutor.TransitionStatus", [], TransitionStatus, () => [[], [], [["missingFields", list_type(string_type)]]]);
54
- }
55
-
56
- export class MatchedTransition extends Record implements IEquatable<MatchedTransition>, IComparable<MatchedTransition> {
57
- readonly Transition: ClinicalPathway_TransitionDefinition;
58
- readonly Priority: int32;
59
- readonly Status: TransitionStatus_$union;
60
- constructor(Transition: ClinicalPathway_TransitionDefinition, Priority: int32, Status: TransitionStatus_$union) {
61
- super();
62
- this.Transition = Transition;
63
- this.Priority = (Priority | 0);
64
- this.Status = Status;
65
- }
66
- }
67
-
68
- export function MatchedTransition_$reflection(): TypeInfo {
69
- return record_type("F1.Studio.PathwayExecutor.MatchedTransition", [], MatchedTransition, () => [["Transition", ClinicalPathway_TransitionDefinition_$reflection()], ["Priority", int32_type], ["Status", TransitionStatus_$reflection()]]);
70
- }
71
-
72
- export class ExecutionLogEntry extends Record implements IEquatable<ExecutionLogEntry>, IComparable<ExecutionLogEntry> {
73
- readonly Timestamp: Date;
74
- readonly StateKey: Shared_StateKey;
75
- readonly Action: string;
76
- readonly Details: string;
77
- constructor(Timestamp: Date, StateKey: Shared_StateKey, Action: string, Details: string) {
78
- super();
79
- this.Timestamp = Timestamp;
80
- this.StateKey = StateKey;
81
- this.Action = Action;
82
- this.Details = Details;
83
- }
84
- }
85
-
86
- export function ExecutionLogEntry_$reflection(): TypeInfo {
87
- return record_type("F1.Studio.PathwayExecutor.ExecutionLogEntry", [], ExecutionLogEntry, () => [["Timestamp", class_type("System.DateTime")], ["StateKey", Shared_StateKey_$reflection()], ["Action", string_type], ["Details", string_type]]);
88
- }
89
-
90
- export class ExecutionContext$1<FieldType> extends Record {
91
- readonly PathwaySpec: ClinicalPathway_ClinicalPathwaySpec;
92
- readonly FormSpec: Spec_FormSpec$1<FieldType>;
93
- readonly CurrentStates: FSharpSet<Shared_StateKey>;
94
- readonly VisitedStates: FSharpSet<Shared_StateKey>;
95
- readonly CompletedStates: FSharpSet<Shared_StateKey>;
96
- readonly ActiveTransitions: FSharpList<MatchedTransition>;
97
- readonly PendingTransitions: FSharpList<MatchedTransition>;
98
- readonly ExecutedActions: FSharpList<ClinicalPathway_ActionInfo_$union>;
99
- readonly FormData: Values_DynamicFormResultData$1<FieldType>;
100
- readonly FieldResolver: ((arg0: string) => Shared_FieldKey);
101
- readonly ExecutionLog: FSharpList<ExecutionLogEntry>;
102
- constructor(PathwaySpec: ClinicalPathway_ClinicalPathwaySpec, FormSpec: Spec_FormSpec$1<FieldType>, CurrentStates: FSharpSet<Shared_StateKey>, VisitedStates: FSharpSet<Shared_StateKey>, CompletedStates: FSharpSet<Shared_StateKey>, ActiveTransitions: FSharpList<MatchedTransition>, PendingTransitions: FSharpList<MatchedTransition>, ExecutedActions: FSharpList<ClinicalPathway_ActionInfo_$union>, FormData: Values_DynamicFormResultData$1<FieldType>, FieldResolver: ((arg0: string) => Shared_FieldKey), ExecutionLog: FSharpList<ExecutionLogEntry>) {
103
- super();
104
- this.PathwaySpec = PathwaySpec;
105
- this.FormSpec = FormSpec;
106
- this.CurrentStates = CurrentStates;
107
- this.VisitedStates = VisitedStates;
108
- this.CompletedStates = CompletedStates;
109
- this.ActiveTransitions = ActiveTransitions;
110
- this.PendingTransitions = PendingTransitions;
111
- this.ExecutedActions = ExecutedActions;
112
- this.FormData = FormData;
113
- this.FieldResolver = FieldResolver;
114
- this.ExecutionLog = ExecutionLog;
115
- }
116
- }
117
-
118
- export function ExecutionContext$1_$reflection(gen0: TypeInfo): TypeInfo {
119
- return record_type("F1.Studio.PathwayExecutor.ExecutionContext`1", [gen0], ExecutionContext$1, () => [["PathwaySpec", ClinicalPathway_ClinicalPathwaySpec_$reflection()], ["FormSpec", Spec_FormSpec$1_$reflection(gen0)], ["CurrentStates", class_type("Microsoft.FSharp.Collections.FSharpSet`1", [Shared_StateKey_$reflection()])], ["VisitedStates", class_type("Microsoft.FSharp.Collections.FSharpSet`1", [Shared_StateKey_$reflection()])], ["CompletedStates", class_type("Microsoft.FSharp.Collections.FSharpSet`1", [Shared_StateKey_$reflection()])], ["ActiveTransitions", list_type(MatchedTransition_$reflection())], ["PendingTransitions", list_type(MatchedTransition_$reflection())], ["ExecutedActions", list_type(ClinicalPathway_ActionInfo_$reflection())], ["FormData", Values_DynamicFormResultData$1_$reflection(gen0)], ["FieldResolver", lambda_type(string_type, Shared_FieldKey_$reflection())], ["ExecutionLog", list_type(ExecutionLogEntry_$reflection())]]);
120
- }
121
-
122
- export class PredictedPathway extends Record implements IEquatable<PredictedPathway>, IComparable<PredictedPathway> {
123
- readonly PathwayId: string;
124
- readonly Probability: float64;
125
- readonly RequiredFields: FSharpList<string>;
126
- readonly ExpectedActions: FSharpList<ClinicalPathway_ActionInfo_$union>;
127
- readonly TargetState: string;
128
- constructor(PathwayId: string, Probability: float64, RequiredFields: FSharpList<string>, ExpectedActions: FSharpList<ClinicalPathway_ActionInfo_$union>, TargetState: string) {
129
- super();
130
- this.PathwayId = PathwayId;
131
- this.Probability = Probability;
132
- this.RequiredFields = RequiredFields;
133
- this.ExpectedActions = ExpectedActions;
134
- this.TargetState = TargetState;
135
- }
136
- }
137
-
138
- export function PredictedPathway_$reflection(): TypeInfo {
139
- return record_type("F1.Studio.PathwayExecutor.PredictedPathway", [], PredictedPathway, () => [["PathwayId", string_type], ["Probability", float64_type], ["RequiredFields", list_type(string_type)], ["ExpectedActions", list_type(ClinicalPathway_ActionInfo_$reflection())], ["TargetState", string_type]]);
140
- }
141
-
142
- export class IncrementalExecutionResult$1<FieldType> extends Record {
143
- readonly Context: ExecutionContext$1<FieldType>;
144
- readonly NewlyActivatedStates: FSharpList<string>;
145
- readonly NewlyActiveTransitions: FSharpList<ClinicalPathway_TransitionDefinition>;
146
- readonly PredictedOutcomes: FSharpList<PredictedPathway>;
147
- readonly CompletionPercentage: float64;
148
- readonly IsComplete: boolean;
149
- constructor(Context: ExecutionContext$1<FieldType>, NewlyActivatedStates: FSharpList<string>, NewlyActiveTransitions: FSharpList<ClinicalPathway_TransitionDefinition>, PredictedOutcomes: FSharpList<PredictedPathway>, CompletionPercentage: float64, IsComplete: boolean) {
150
- super();
151
- this.Context = Context;
152
- this.NewlyActivatedStates = NewlyActivatedStates;
153
- this.NewlyActiveTransitions = NewlyActiveTransitions;
154
- this.PredictedOutcomes = PredictedOutcomes;
155
- this.CompletionPercentage = CompletionPercentage;
156
- this.IsComplete = IsComplete;
157
- }
158
- }
159
-
160
- export function IncrementalExecutionResult$1_$reflection(gen0: TypeInfo): TypeInfo {
161
- return record_type("F1.Studio.PathwayExecutor.IncrementalExecutionResult`1", [gen0], IncrementalExecutionResult$1, () => [["Context", ExecutionContext$1_$reflection(gen0)], ["NewlyActivatedStates", list_type(string_type)], ["NewlyActiveTransitions", list_type(ClinicalPathway_TransitionDefinition_$reflection())], ["PredictedOutcomes", list_type(PredictedPathway_$reflection())], ["CompletionPercentage", float64_type], ["IsComplete", bool_type]]);
162
- }
163
-
164
- export class ClinicalPlan extends Record implements IEquatable<ClinicalPlan>, IComparable<ClinicalPlan> {
165
- readonly PlanId: string;
166
- readonly Actions: FSharpList<ClinicalPathway_ActionInfo_$union>;
167
- readonly TargetState: string;
168
- readonly Priority: int32;
169
- constructor(PlanId: string, Actions: FSharpList<ClinicalPathway_ActionInfo_$union>, TargetState: string, Priority: int32) {
170
- super();
171
- this.PlanId = PlanId;
172
- this.Actions = Actions;
173
- this.TargetState = TargetState;
174
- this.Priority = (Priority | 0);
175
- }
176
- }
177
-
178
- export function ClinicalPlan_$reflection(): TypeInfo {
179
- return record_type("F1.Studio.PathwayExecutor.ClinicalPlan", [], ClinicalPlan, () => [["PlanId", string_type], ["Actions", list_type(ClinicalPathway_ActionInfo_$reflection())], ["TargetState", string_type], ["Priority", int32_type]]);
180
- }
181
-
182
- export class VisualizationState extends Record implements IEquatable<VisualizationState>, IComparable<VisualizationState> {
183
- readonly CurrentStates: FSharpSet<Shared_StateKey>;
184
- readonly VisitedStates: FSharpSet<Shared_StateKey>;
185
- readonly ActiveTransitions: FSharpList<Shared_TransitionKey>;
186
- readonly PendingTransitions: FSharpList<Shared_TransitionKey>;
187
- readonly CompletedTransitions: FSharpList<string>;
188
- readonly PredictedOutcomes: FSharpList<PredictedPathway>;
189
- constructor(CurrentStates: FSharpSet<Shared_StateKey>, VisitedStates: FSharpSet<Shared_StateKey>, ActiveTransitions: FSharpList<Shared_TransitionKey>, PendingTransitions: FSharpList<Shared_TransitionKey>, CompletedTransitions: FSharpList<string>, PredictedOutcomes: FSharpList<PredictedPathway>) {
190
- super();
191
- this.CurrentStates = CurrentStates;
192
- this.VisitedStates = VisitedStates;
193
- this.ActiveTransitions = ActiveTransitions;
194
- this.PendingTransitions = PendingTransitions;
195
- this.CompletedTransitions = CompletedTransitions;
196
- this.PredictedOutcomes = PredictedOutcomes;
197
- }
198
- }
199
-
200
- export function VisualizationState_$reflection(): TypeInfo {
201
- return record_type("F1.Studio.PathwayExecutor.VisualizationState", [], VisualizationState, () => [["CurrentStates", class_type("Microsoft.FSharp.Collections.FSharpSet`1", [Shared_StateKey_$reflection()])], ["VisitedStates", class_type("Microsoft.FSharp.Collections.FSharpSet`1", [Shared_StateKey_$reflection()])], ["ActiveTransitions", list_type(Shared_TransitionKey_$reflection())], ["PendingTransitions", list_type(Shared_TransitionKey_$reflection())], ["CompletedTransitions", list_type(string_type)], ["PredictedOutcomes", list_type(PredictedPathway_$reflection())]]);
202
- }
203
-
204
- /**
205
- * Generate deterministic GUID from field label
206
- */
207
- export function FieldResolver_generateFieldKey(fieldName: string): Shared_FieldKey {
208
- const hash: int32 = stringHash(fieldName) | 0;
209
- const bytes: uint8[] = fill(new Array(16), 0, 16, 0);
210
- iterateIndexed<uint8>((i: int32, b: uint8): void => {
211
- if (i < 4) {
212
- setItem(bytes, i, b);
213
- }
214
- }, Array.from(getBytesInt32(hash)));
215
- iterateIndexed<uint8>((i_1: int32, b_1: uint8): void => {
216
- if (i_1 < 4) {
217
- setItem(bytes, i_1 + 4, b_1);
218
- }
219
- }, Array.from(getBytesInt32(hash >> 1)));
220
- iterateIndexed<uint8>((i_2: int32, b_2: uint8): void => {
221
- if (i_2 < 4) {
222
- setItem(bytes, i_2 + 8, b_2);
223
- }
224
- }, Array.from(getBytesInt32(hash >> 2)));
225
- iterateIndexed<uint8>((i_3: int32, b_3: uint8): void => {
226
- if (i_3 < 4) {
227
- setItem(bytes, i_3 + 12, b_3);
228
- }
229
- }, Array.from(getBytesInt32(hash >> 3)));
230
- return new Shared_FieldKey(arrayToGuid(bytes));
231
- }
232
-
233
- /**
234
- * Create resolver that maps pathway field references to FieldKeys
235
- */
236
- export function FieldResolver_createResolver<FieldType>(formSpec: Spec_FormSpec$1<FieldType>): ((arg0: string) => Shared_FieldKey) {
237
- const labelToFieldKey: FSharpMap<string, Shared_FieldKey> = ofList<string, Shared_FieldKey>(map<Spec_FormField$1<FieldType>, [string, Shared_FieldKey]>((field: Spec_FormField$1<FieldType>): [string, Shared_FieldKey] => ([field.Label.toLocaleLowerCase().trim(), field.FieldKey] as [string, Shared_FieldKey]), collect<Spec_FormStep$1<FieldType>, Spec_FormField$1<FieldType>>((step: Spec_FormStep$1<FieldType>): FSharpList<Spec_FormField$1<FieldType>> => step.Fields, formSpec.Steps)), {
238
- Compare: comparePrimitives,
239
- });
240
- return (fieldReference: string): Shared_FieldKey => {
241
- const matchValue: Option<Shared_FieldKey> = tryFind<string, Shared_FieldKey>(fieldReference.toLocaleLowerCase().trim(), labelToFieldKey);
242
- return (matchValue == null) ? FieldResolver_generateFieldKey(fieldReference) : value_3(matchValue);
243
- };
244
- }
245
-
246
- /**
247
- * Extract field values from form data using resolver
248
- */
249
- export function FieldResolver_extractFieldValues<FieldType>(resolver: ((arg0: string) => Shared_FieldKey), formData: Values_DynamicFormResultData$1<FieldType>): FSharpMap<Shared_FieldKey, string> {
250
- return ofSeq<Shared_FieldKey, string>(collect_1<[Values_StepOrder, FSharpMap<Shared_FieldKey, Values_FieldDetails$1<FieldType>>], Iterable<[Shared_FieldKey, string]>, [Shared_FieldKey, string]>((tupledArg: [Values_StepOrder, FSharpMap<Shared_FieldKey, Values_FieldDetails$1<FieldType>>]): Iterable<[Shared_FieldKey, string]> => map_1<[Shared_FieldKey, Values_FieldDetails$1<FieldType>], [Shared_FieldKey, string]>((tupledArg_1: [Shared_FieldKey, Values_FieldDetails$1<FieldType>]): [Shared_FieldKey, string] => {
251
- let matchValue: Shared_FieldValue_$union, pluginData: FSharpList<Shared_PluginDataProperty>;
252
- return [tupledArg_1[0], (matchValue = tupledArg_1[1].FieldValue, (matchValue.tag === /* Multiple */ 1) ? join(",", toList<string>(map_2<Shared_FieldAnswer, string>((a: Shared_FieldAnswer): string => a.Value, matchValue.fields[0], {
253
- Compare: comparePrimitives,
254
- }))) : ((matchValue.tag === /* Matrix */ 2) ? join(",", map<[Shared_MatrixItemKey, string], string>((tupledArg_2: [Shared_MatrixItemKey, string]): string => tupledArg_2[1], toList_1<Shared_MatrixItemKey, string>(matchValue.fields[0].Values))) : ((matchValue.tag === /* PluginData */ 3) ? ((pluginData = matchValue.fields[0], toString(0, Auto_generateBoxedEncoder_437914C6(list_type(Shared_PluginDataProperty_$reflection()), undefined, undefined, undefined)(pluginData)))) : matchValue.fields[0].Value)))] as [Shared_FieldKey, string];
255
- }, toSeq<Shared_FieldKey, Values_FieldDetails$1<FieldType>>(tupledArg[1])), toSeq<Values_StepOrder, FSharpMap<Shared_FieldKey, Values_FieldDetails$1<FieldType>>>(formData.ResultSteps)), {
256
- Compare: compare,
257
- });
258
- }
259
-
260
- /**
261
- * Evaluate a field condition with a specific evaluator (string-based, kept for backward compatibility)
262
- */
263
- export function evaluateFieldCondition(actualValue: string, evaluator: ClinicalPathway_FieldEvaluator_$union, expectedValue: string): boolean {
264
- switch (evaluator.tag) {
265
- case /* NotEquals */ 1:
266
- return actualValue.trim().toLocaleLowerCase() !== expectedValue.trim().toLocaleLowerCase();
267
- case /* GreaterThan */ 5: {
268
- let matchValue: [boolean, float64];
269
- let outArg = 0;
270
- matchValue = ([tryParse(actualValue, new FSharpRef<float64>((): float64 => outArg, (v: float64): void => {
271
- outArg = v;
272
- })), outArg] as [boolean, float64]);
273
- let matchValue_1: [boolean, float64];
274
- let outArg_1 = 0;
275
- matchValue_1 = ([tryParse(expectedValue, new FSharpRef<float64>((): float64 => outArg_1, (v_1: float64): void => {
276
- outArg_1 = v_1;
277
- })), outArg_1] as [boolean, float64]);
278
- let matchResult: int32;
279
- if (matchValue[0]) {
280
- if (matchValue_1[0]) {
281
- matchResult = 0;
282
- }
283
- else {
284
- matchResult = 1;
285
- }
286
- }
287
- else {
288
- matchResult = 1;
289
- }
290
- switch (matchResult) {
291
- case 0:
292
- return matchValue[1] > matchValue_1[1];
293
- default:
294
- return false;
295
- }
296
- }
297
- case /* GreaterOrEqual */ 6: {
298
- let matchValue_3: [boolean, float64];
299
- let outArg_2 = 0;
300
- matchValue_3 = ([tryParse(actualValue, new FSharpRef<float64>((): float64 => outArg_2, (v_2: float64): void => {
301
- outArg_2 = v_2;
302
- })), outArg_2] as [boolean, float64]);
303
- let matchValue_4: [boolean, float64];
304
- let outArg_3 = 0;
305
- matchValue_4 = ([tryParse(expectedValue, new FSharpRef<float64>((): float64 => outArg_3, (v_3: float64): void => {
306
- outArg_3 = v_3;
307
- })), outArg_3] as [boolean, float64]);
308
- let matchResult_1: int32;
309
- if (matchValue_3[0]) {
310
- if (matchValue_4[0]) {
311
- matchResult_1 = 0;
312
- }
313
- else {
314
- matchResult_1 = 1;
315
- }
316
- }
317
- else {
318
- matchResult_1 = 1;
319
- }
320
- switch (matchResult_1) {
321
- case 0:
322
- return matchValue_3[1] >= matchValue_4[1];
323
- default:
324
- return false;
325
- }
326
- }
327
- case /* LessThan */ 7: {
328
- let matchValue_6: [boolean, float64];
329
- let outArg_4 = 0;
330
- matchValue_6 = ([tryParse(actualValue, new FSharpRef<float64>((): float64 => outArg_4, (v_4: float64): void => {
331
- outArg_4 = v_4;
332
- })), outArg_4] as [boolean, float64]);
333
- let matchValue_7: [boolean, float64];
334
- let outArg_5 = 0;
335
- matchValue_7 = ([tryParse(expectedValue, new FSharpRef<float64>((): float64 => outArg_5, (v_5: float64): void => {
336
- outArg_5 = v_5;
337
- })), outArg_5] as [boolean, float64]);
338
- let matchResult_2: int32;
339
- if (matchValue_6[0]) {
340
- if (matchValue_7[0]) {
341
- matchResult_2 = 0;
342
- }
343
- else {
344
- matchResult_2 = 1;
345
- }
346
- }
347
- else {
348
- matchResult_2 = 1;
349
- }
350
- switch (matchResult_2) {
351
- case 0:
352
- return matchValue_6[1] < matchValue_7[1];
353
- default:
354
- return false;
355
- }
356
- }
357
- case /* LessOrEqual */ 8: {
358
- let matchValue_9: [boolean, float64];
359
- let outArg_6 = 0;
360
- matchValue_9 = ([tryParse(actualValue, new FSharpRef<float64>((): float64 => outArg_6, (v_6: float64): void => {
361
- outArg_6 = v_6;
362
- })), outArg_6] as [boolean, float64]);
363
- let matchValue_10: [boolean, float64];
364
- let outArg_7 = 0;
365
- matchValue_10 = ([tryParse(expectedValue, new FSharpRef<float64>((): float64 => outArg_7, (v_7: float64): void => {
366
- outArg_7 = v_7;
367
- })), outArg_7] as [boolean, float64]);
368
- let matchResult_3: int32;
369
- if (matchValue_9[0]) {
370
- if (matchValue_10[0]) {
371
- matchResult_3 = 0;
372
- }
373
- else {
374
- matchResult_3 = 1;
375
- }
376
- }
377
- else {
378
- matchResult_3 = 1;
379
- }
380
- switch (matchResult_3) {
381
- case 0:
382
- return matchValue_9[1] <= matchValue_10[1];
383
- default:
384
- return false;
385
- }
386
- }
387
- case /* Contains */ 9:
388
- return actualValue.toLocaleLowerCase().indexOf(expectedValue.toLocaleLowerCase()) >= 0;
389
- case /* IsPresent */ 10:
390
- if (!isNullOrWhiteSpace(actualValue) && (actualValue.toLocaleLowerCase() !== "false")) {
391
- return actualValue.toLocaleLowerCase() !== "no";
392
- }
393
- else {
394
- return false;
395
- }
396
- case /* IsAbsent */ 11:
397
- if (isNullOrWhiteSpace(actualValue) ? true : (actualValue.toLocaleLowerCase() === "false")) {
398
- return true;
399
- }
400
- else {
401
- return actualValue.toLocaleLowerCase() === "no";
402
- }
403
- case /* MatchesPattern */ 12:
404
- return isMatch(create(evaluator.fields[0]), actualValue);
405
- case /* InRange */ 13: {
406
- const minVal: int32 = evaluator.fields[0] | 0;
407
- const maxVal: int32 = evaluator.fields[1] | 0;
408
- let matchValue_12: [boolean, float64];
409
- let outArg_8 = 0;
410
- matchValue_12 = ([tryParse(actualValue, new FSharpRef<float64>((): float64 => outArg_8, (v_8: float64): void => {
411
- outArg_8 = v_8;
412
- })), outArg_8] as [boolean, float64]);
413
- if (matchValue_12[0]) {
414
- const actual_4: float64 = matchValue_12[1];
415
- if (actual_4 >= minVal) {
416
- return actual_4 <= maxVal;
417
- }
418
- else {
419
- return false;
420
- }
421
- }
422
- else {
423
- return false;
424
- }
425
- }
426
- case /* InSet */ 2:
427
- return exists<string>((v_9: string): boolean => (v_9.trim().toLocaleLowerCase() === actualValue.trim().toLocaleLowerCase()), evaluator.fields[0]);
428
- case /* NotInSet */ 3:
429
- return !exists<string>((v_10: string): boolean => (v_10.trim().toLocaleLowerCase() === actualValue.trim().toLocaleLowerCase()), evaluator.fields[0]);
430
- case /* ContainsAll */ 4: {
431
- const values_2: FSharpList<string> = evaluator.fields[0];
432
- const actualParts: FSharpSet<string> = ofArray<string>(map_3<string, string>((s: string): string => s.trim().toLocaleLowerCase(), actualValue.split(",")), {
433
- Compare: comparePrimitives,
434
- });
435
- return isSubset<string>(ofList_1<string>(map<string, string>((s_1: string): string => s_1.trim().toLocaleLowerCase(), values_2), {
436
- Compare: comparePrimitives,
437
- }), actualParts);
438
- }
439
- default:
440
- return actualValue.trim().toLocaleLowerCase() === expectedValue.trim().toLocaleLowerCase();
441
- }
442
- }
443
-
444
- /**
445
- * Evaluate a field condition with ConditionValue (type-aware comparison)
446
- */
447
- export function evaluateFieldConditionWithConditionValue(actualFieldValue: Shared_FieldValue_$union, evaluator: ClinicalPathway_FieldEvaluator_$union, expectedConditionValue: Shared_ConditionValue_$union): boolean {
448
- let pluginData: FSharpList<Shared_PluginDataProperty>, pluginData_1: Shared_PluginDataProperty;
449
- return evaluateFieldCondition((actualFieldValue.tag === /* Multiple */ 1) ? join(",", toList<string>(map_2<Shared_FieldAnswer, string>((a: Shared_FieldAnswer): string => a.Value, actualFieldValue.fields[0], {
450
- Compare: comparePrimitives,
451
- }))) : ((actualFieldValue.tag === /* Matrix */ 2) ? join(",", map<[Shared_MatrixItemKey, string], string>((tupledArg: [Shared_MatrixItemKey, string]): string => tupledArg[1], toList_1<Shared_MatrixItemKey, string>(actualFieldValue.fields[0].Values))) : ((actualFieldValue.tag === /* PluginData */ 3) ? ((pluginData = actualFieldValue.fields[0], toString(0, Auto_generateBoxedEncoder_437914C6(list_type(Shared_PluginDataProperty_$reflection()), undefined, undefined, undefined)(pluginData)))) : actualFieldValue.fields[0].Value)), evaluator, (expectedConditionValue.tag === /* Multiple */ 1) ? join(",", toList<string>(expectedConditionValue.fields[0])) : ((expectedConditionValue.tag === /* Matrix */ 2) ? join(",", map<[Shared_MatrixItemKey, string], string>((tupledArg_1: [Shared_MatrixItemKey, string]): string => tupledArg_1[1], toList_1<Shared_MatrixItemKey, string>(expectedConditionValue.fields[0]))) : ((expectedConditionValue.tag === /* PluginData */ 3) ? ((pluginData_1 = expectedConditionValue.fields[0], toString(0, Auto_generateBoxedEncoder_437914C6(Shared_PluginDataProperty_$reflection(), undefined, undefined, undefined)(pluginData_1)))) : expectedConditionValue.fields[0])));
452
- }
453
-
454
- /**
455
- * Recursively evaluate a transition condition with partial data support
456
- */
457
- export function evaluateTransitionWithPartialData<FieldType>(resolver: ((arg0: string) => Shared_FieldKey), formSpec: Option<Spec_FormSpec$1<FieldType>>, fieldValues: FSharpMap<Shared_FieldKey, string>, visitedStates: FSharpSet<Shared_StateKey>, condition: ClinicalPathway_TransitionCondition_$union): TransitionStatus_$union {
458
- let pluginData: Shared_PluginDataProperty, pluginData_1: Shared_PluginDataProperty;
459
- switch (condition.tag) {
460
- case /* FieldCondition */ 0: {
461
- const fieldKey: Shared_FieldKey = condition.fields[0];
462
- const evaluator: ClinicalPathway_FieldEvaluator_$union = condition.fields[1];
463
- const conditionValue: Shared_ConditionValue_$union = condition.fields[2];
464
- const matchValue: Option<string> = tryFind<Shared_FieldKey, string>(fieldKey, fieldValues);
465
- if (matchValue == null) {
466
- return TransitionStatus_Pending(singleton(fieldKey.fields[0]));
467
- }
468
- else if (evaluateFieldConditionWithConditionValue(Shared_FieldValue_Single(new Shared_FieldAnswer(fieldKey, "", value_3(matchValue))), evaluator, conditionValue)) {
469
- return TransitionStatus_Satisfied();
470
- }
471
- else {
472
- return TransitionStatus_Failed();
473
- }
474
- }
475
- case /* StateCondition */ 3: {
476
- const evaluator_1: ClinicalPathway_StateEvaluator_$union = condition.fields[1];
477
- const stateVisited: boolean = contains<Shared_StateKey>(condition.fields[0], visitedStates);
478
- switch (evaluator_1.tag) {
479
- case /* HasValue */ 1:
480
- if (stateVisited) {
481
- return TransitionStatus_Satisfied();
482
- }
483
- else {
484
- return TransitionStatus_Failed();
485
- }
486
- case /* HasError */ 2:
487
- return TransitionStatus_Failed();
488
- case /* WasSkipped */ 3:
489
- if (!stateVisited) {
490
- return TransitionStatus_Satisfied();
491
- }
492
- else {
493
- return TransitionStatus_Failed();
494
- }
495
- default:
496
- if (stateVisited) {
497
- return TransitionStatus_Satisfied();
498
- }
499
- else {
500
- return TransitionStatus_Failed();
501
- }
502
- }
503
- }
504
- case /* CompositeCondition */ 4: {
505
- const logicalOp: ClinicalPathway_LogicalOp_$union = condition.fields[0];
506
- const conditions: FSharpList<ClinicalPathway_TransitionCondition_$union> = condition.fields[1];
507
- switch (logicalOp.tag) {
508
- case /* Or */ 1: {
509
- const results_1: FSharpList<TransitionStatus_$union> = map<ClinicalPathway_TransitionCondition_$union, TransitionStatus_$union>((condition_2: ClinicalPathway_TransitionCondition_$union): TransitionStatus_$union => evaluateTransitionWithPartialData<FieldType>(resolver, formSpec, fieldValues, visitedStates, condition_2), conditions);
510
- if (exists<TransitionStatus_$union>((r_3: TransitionStatus_$union): boolean => equals(r_3, TransitionStatus_Satisfied()), results_1)) {
511
- return TransitionStatus_Satisfied();
512
- }
513
- else if (forAll<TransitionStatus_$union>((r_4: TransitionStatus_$union): boolean => equals(r_4, TransitionStatus_Failed()), results_1)) {
514
- return TransitionStatus_Failed();
515
- }
516
- else {
517
- return TransitionStatus_Pending(concat<string>(choose<TransitionStatus_$union, FSharpList<string>>((r_5: TransitionStatus_$union): Option<FSharpList<string>> => {
518
- if (r_5.tag === /* Pending */ 2) {
519
- return r_5.fields[0];
520
- }
521
- else {
522
- return undefined;
523
- }
524
- }, results_1)));
525
- }
526
- }
527
- case /* Not */ 2: {
528
- let matchResult: int32, cond: ClinicalPathway_TransitionCondition_$union;
529
- if (!isEmpty(conditions)) {
530
- if (isEmpty(tail(conditions))) {
531
- matchResult = 0;
532
- cond = head(conditions);
533
- }
534
- else {
535
- matchResult = 1;
536
- }
537
- }
538
- else {
539
- matchResult = 1;
540
- }
541
- switch (matchResult) {
542
- case 0: {
543
- const matchValue_1: TransitionStatus_$union = evaluateTransitionWithPartialData<FieldType>(resolver, formSpec, fieldValues, visitedStates, cond!);
544
- switch (matchValue_1.tag) {
545
- case /* Failed */ 1:
546
- return TransitionStatus_Satisfied();
547
- case /* Pending */ 2:
548
- return TransitionStatus_Pending(matchValue_1.fields[0]);
549
- default:
550
- return TransitionStatus_Failed();
551
- }
552
- }
553
- default:
554
- return TransitionStatus_Failed();
555
- }
556
- }
557
- default: {
558
- const results: FSharpList<TransitionStatus_$union> = map<ClinicalPathway_TransitionCondition_$union, TransitionStatus_$union>((condition_1: ClinicalPathway_TransitionCondition_$union): TransitionStatus_$union => evaluateTransitionWithPartialData<FieldType>(resolver, formSpec, fieldValues, visitedStates, condition_1), conditions);
559
- if (exists<TransitionStatus_$union>((r: TransitionStatus_$union): boolean => equals(r, TransitionStatus_Failed()), results)) {
560
- return TransitionStatus_Failed();
561
- }
562
- else if (forAll<TransitionStatus_$union>((r_1: TransitionStatus_$union): boolean => equals(r_1, TransitionStatus_Satisfied()), results)) {
563
- return TransitionStatus_Satisfied();
564
- }
565
- else {
566
- return TransitionStatus_Pending(concat<string>(choose<TransitionStatus_$union, FSharpList<string>>((r_2: TransitionStatus_$union): Option<FSharpList<string>> => {
567
- if (r_2.tag === /* Pending */ 2) {
568
- return r_2.fields[0];
569
- }
570
- else {
571
- return undefined;
572
- }
573
- }, results)));
574
- }
575
- }
576
- }
577
- }
578
- case /* TestResultCondition */ 5: {
579
- const result: string = condition.fields[1];
580
- return TransitionStatus_Pending(singleton(condition.fields[0]));
581
- }
582
- case /* FieldOptionCondition */ 1: {
583
- const optionKey: Shared_FieldOptionKey = condition.fields[2];
584
- const matrixItemKey: Option<Shared_MatrixItemKey> = condition.fields[1];
585
- const fieldKey_1: Shared_FieldKey = condition.fields[0];
586
- const evaluator_2: ClinicalPathway_FieldEvaluator_$union = condition.fields[3];
587
- const conditionValue_1: Shared_ConditionValue_$union = condition.fields[4];
588
- const optionValueOpt: Option<string> = (formSpec == null) ? undefined : bind<Spec_FormField$1<FieldType>, string>((field_1: Spec_FormField$1<FieldType>): Option<string> => {
589
- const fieldType = field_1.FieldType as Spec_FieldType_$union;
590
- return map_4<Shared_FieldOption, string>((opt_1: Shared_FieldOption): string => opt_1.Value, tryFind_1<Shared_FieldOption>((opt: Shared_FieldOption): boolean => equals(opt.OptionKey, optionKey), (fieldType.tag === /* SingleChoice */ 13) ? fieldType.fields[0].Options : ((fieldType.tag === /* Radio */ 12) ? fieldType.fields[0].Options : ((fieldType.tag === /* Dropdown */ 14) ? fieldType.fields[0].Options : ((fieldType.tag === /* MultiChoice */ 15) ? fieldType.fields[0].Options : ((fieldType.tag === /* CheckboxList */ 16) ? fieldType.fields[0].Options : empty<Shared_FieldOption>()))))));
591
- }, tryFind_1<Spec_FormField$1<FieldType>>((field: Spec_FormField$1<FieldType>): boolean => equals(field.FieldKey, fieldKey_1), collect<Spec_FormStep$1<FieldType>, Spec_FormField$1<FieldType>>((step: Spec_FormStep$1<FieldType>): FSharpList<Spec_FormField$1<FieldType>> => step.Fields, value_3(formSpec).Steps)));
592
- const matchValue_2: Option<string> = tryFind<Shared_FieldKey, string>(fieldKey_1, fieldValues);
593
- if (optionValueOpt == null) {
594
- const guid_1: string = optionKey.fields[0];
595
- console.error(some("[evaluateTransition] FieldOptionCondition: Could not find option in formSpec for optionKey:"), guid_1);
596
- return TransitionStatus_Failed();
597
- }
598
- else if (matchValue_2 == null) {
599
- return TransitionStatus_Pending(singleton(fieldKey_1.fields[0]));
600
- }
601
- else {
602
- const actualValueStr_1: string = value_3(matchValue_2);
603
- const optionValue: string = value_3(optionValueOpt);
604
- const actualValues: FSharpSet<string> = ofArray<string>(map_3<string, string>((s: string): string => s.trim().toLocaleLowerCase(), actualValueStr_1.split(",")), {
605
- Compare: comparePrimitives,
606
- });
607
- const containsOption: boolean = contains<string>(optionValue.trim().toLocaleLowerCase(), actualValues);
608
- switch (evaluator_2.tag) {
609
- case /* Equals */ 0:
610
- if (containsOption) {
611
- return TransitionStatus_Satisfied();
612
- }
613
- else {
614
- return TransitionStatus_Failed();
615
- }
616
- case /* NotEquals */ 1:
617
- if (!containsOption) {
618
- return TransitionStatus_Satisfied();
619
- }
620
- else {
621
- return TransitionStatus_Failed();
622
- }
623
- case /* IsPresent */ 10:
624
- if (containsOption) {
625
- return TransitionStatus_Satisfied();
626
- }
627
- else {
628
- return TransitionStatus_Failed();
629
- }
630
- case /* IsAbsent */ 11:
631
- if (!containsOption) {
632
- return TransitionStatus_Satisfied();
633
- }
634
- else {
635
- return TransitionStatus_Failed();
636
- }
637
- default:
638
- if (evaluateFieldCondition(actualValueStr_1, evaluator_2, (conditionValue_1.tag === /* Multiple */ 1) ? join(",", toList<string>(conditionValue_1.fields[0])) : ((conditionValue_1.tag === /* Matrix */ 2) ? join(",", map<[Shared_MatrixItemKey, string], string>((tupledArg: [Shared_MatrixItemKey, string]): string => tupledArg[1], toList_1<Shared_MatrixItemKey, string>(conditionValue_1.fields[0]))) : ((conditionValue_1.tag === /* PluginData */ 3) ? ((pluginData = conditionValue_1.fields[0], toString(0, Auto_generateBoxedEncoder_437914C6(Shared_PluginDataProperty_$reflection(), undefined, undefined, undefined)(pluginData)))) : conditionValue_1.fields[0])))) {
639
- return TransitionStatus_Satisfied();
640
- }
641
- else {
642
- return TransitionStatus_Failed();
643
- }
644
- }
645
- }
646
- }
647
- case /* PluginPropertyCondition */ 2: {
648
- const propertyKey: Shared_PluginPropertyKey = condition.fields[1];
649
- const fieldKey_2: Shared_FieldKey = condition.fields[0];
650
- const evaluator_3: ClinicalPathway_FieldEvaluator_$union = condition.fields[2];
651
- const conditionValue_2: Shared_ConditionValue_$union = condition.fields[3];
652
- const matchValue_4: Option<string> = tryFind<Shared_FieldKey, string>(fieldKey_2, fieldValues);
653
- if (matchValue_4 == null) {
654
- return TransitionStatus_Pending(singleton(fieldKey_2.fields[0]));
655
- }
656
- else {
657
- const actualValueStr_2: string = value_3(matchValue_4);
658
- try {
659
- const actualFieldValue_1: Shared_FieldValue_$union = Shared_FieldValue_Single(new Shared_FieldAnswer(fieldKey_2, "", actualValueStr_2));
660
- return evaluateFieldCondition(actualValueStr_2, evaluator_3, (conditionValue_2.tag === /* Multiple */ 1) ? join(",", toList<string>(conditionValue_2.fields[0])) : ((conditionValue_2.tag === /* Matrix */ 2) ? join(",", map<[Shared_MatrixItemKey, string], string>((tupledArg_1: [Shared_MatrixItemKey, string]): string => tupledArg_1[1], toList_1<Shared_MatrixItemKey, string>(conditionValue_2.fields[0]))) : ((conditionValue_2.tag === /* PluginData */ 3) ? ((pluginData_1 = conditionValue_2.fields[0], toString(0, Auto_generateBoxedEncoder_437914C6(Shared_PluginDataProperty_$reflection(), undefined, undefined, undefined)(pluginData_1)))) : conditionValue_2.fields[0]))) ? TransitionStatus_Satisfied() : TransitionStatus_Failed();
661
- }
662
- catch (ex: any) {
663
- return TransitionStatus_Failed();
664
- }
665
- }
666
- }
667
- default:
668
- return TransitionStatus_Satisfied();
669
- }
670
- }
671
-
672
- /**
673
- * Find a state by key
674
- */
675
- export function findState(stateKey: Shared_StateKey, states: FSharpList<ClinicalPathway_StateDefinition>): Option<ClinicalPathway_StateDefinition> {
676
- return tryFind_1<ClinicalPathway_StateDefinition>((s: ClinicalPathway_StateDefinition): boolean => equals(s.StateKey, stateKey), states);
677
- }
678
-
679
- /**
680
- * Extract actions from state
681
- */
682
- export function extractActionsFromState(state: ClinicalPathway_StateDefinition): FSharpList<ClinicalPathway_ActionInfo_$union> {
683
- const matchValue: ClinicalPathway_StateType_$union = state.StateType;
684
- switch (matchValue.tag) {
685
- case /* Action */ 2:
686
- return singleton(matchValue.fields[0]);
687
- case /* CompoundAction */ 3:
688
- return matchValue.fields[0];
689
- case /* ConditionalAction */ 4: {
690
- const condition: ClinicalPathway_TransitionCondition_$union = matchValue.fields[0];
691
- return append(singleton(matchValue.fields[1]), ofArray_1(toArray<ClinicalPathway_ActionInfo_$union>(matchValue.fields[2])));
692
- }
693
- default:
694
- return empty<ClinicalPathway_ActionInfo_$union>();
695
- }
696
- }
697
-
698
- /**
699
- * Check if a state is terminal
700
- */
701
- export function isTerminalState(state: ClinicalPathway_StateDefinition): boolean {
702
- if (state.StateType.tag === /* Terminal */ 5) {
703
- return true;
704
- }
705
- else {
706
- return false;
707
- }
708
- }
709
-
710
- /**
711
- * Evaluate all transitions from current states
712
- */
713
- export function evaluateAllTransitions<FieldType>(context: ExecutionContext$1<FieldType>): FSharpList<MatchedTransition> {
714
- const fieldValues: FSharpMap<Shared_FieldKey, string> = FieldResolver_extractFieldValues<FieldType>(context.FieldResolver, context.FormData);
715
- console.log(some("[evaluateAllTransitions] Extracted field values:"), fieldValues);
716
- console.log(some("[evaluateAllTransitions] Current states in context:"), context.CurrentStates);
717
- console.log(some("[evaluateAllTransitions] All transitions in pathway:"), context.PathwaySpec.Transitions);
718
- const transitionsFromCurrentStates: FSharpList<ClinicalPathway_TransitionDefinition> = filter<ClinicalPathway_TransitionDefinition>((t: ClinicalPathway_TransitionDefinition): boolean => {
719
- const isFromCurrentState: boolean = contains<Shared_StateKey>(t.FromState, context.CurrentStates);
720
- console.log(some("[evaluateAllTransitions] Transition from"), t.FromState, "to", t.ToState, "FromCurrentState=", isFromCurrentState);
721
- return isFromCurrentState;
722
- }, context.PathwaySpec.Transitions);
723
- console.log(some("[evaluateAllTransitions] Transitions from current states:"), transitionsFromCurrentStates);
724
- return map<ClinicalPathway_TransitionDefinition, MatchedTransition>((transition: ClinicalPathway_TransitionDefinition): MatchedTransition => {
725
- console.log(some("[evaluateAllTransitions] Evaluating transition:"), transition.TransitionKey);
726
- console.log(some("[evaluateAllTransitions] Transition condition:"), transition.Condition);
727
- const status: TransitionStatus_$union = evaluateTransitionWithPartialData<FieldType>(context.FieldResolver, context.FormSpec, fieldValues, context.VisitedStates, transition.Condition);
728
- console.log(some("[evaluateAllTransitions] Transition status:"), status);
729
- return new MatchedTransition(transition, defaultArg(transition.Priority, 999), status);
730
- }, transitionsFromCurrentStates);
731
- }
732
-
733
- /**
734
- * Separate matched transitions into active, pending, and failed
735
- */
736
- export function categorizeTransitions(transitions: FSharpList<MatchedTransition>): [FSharpList<MatchedTransition>, FSharpList<MatchedTransition>, FSharpList<MatchedTransition>] {
737
- return [filter<MatchedTransition>((t: MatchedTransition): boolean => equals(t.Status, TransitionStatus_Satisfied()), transitions), filter<MatchedTransition>((t_1: MatchedTransition): boolean => {
738
- if (t_1.Status.tag === /* Pending */ 2) {
739
- return true;
740
- }
741
- else {
742
- return false;
743
- }
744
- }, transitions), filter<MatchedTransition>((t_2: MatchedTransition): boolean => equals(t_2.Status, TransitionStatus_Failed()), transitions)] as [FSharpList<MatchedTransition>, FSharpList<MatchedTransition>, FSharpList<MatchedTransition>];
745
- }
746
-
747
- /**
748
- * Apply execution mode strategy to select transitions
749
- */
750
- export function selectTransitionsByMode(mode: ClinicalPathway_PathwayExecutionMode_$union, activeTransitions: FSharpList<MatchedTransition>): FSharpList<MatchedTransition> {
751
- switch (mode.tag) {
752
- case /* MultiPathway */ 1: {
753
- const matchValue_1: ClinicalPathway_CombinationStrategy_$union = mode.fields[0].CombinationStrategy;
754
- switch (matchValue_1.tag) {
755
- case /* NonConflicting */ 1:
756
- return activeTransitions;
757
- case /* Complementary */ 2:
758
- return activeTransitions;
759
- default:
760
- return activeTransitions;
761
- }
762
- }
763
- case /* TriggerBased */ 2:
764
- return activeTransitions;
765
- default: {
766
- const matchValue: ClinicalPathway_SelectionStrategy_$union = mode.fields[0].SelectionStrategy;
767
- switch (matchValue.tag) {
768
- case /* MostSpecific */ 1:
769
- return ofArray_1(toArray<MatchedTransition>(tryHead<MatchedTransition>(sortBy<MatchedTransition, int32>((m_1: MatchedTransition): int32 => m_1.Priority, activeTransitions, {
770
- Compare: comparePrimitives,
771
- }))));
772
- case /* ClinicalSeverity */ 2:
773
- return ofArray_1(toArray<MatchedTransition>(tryHead<MatchedTransition>(sortBy<MatchedTransition, int32>((m_2: MatchedTransition): int32 => m_2.Priority, activeTransitions, {
774
- Compare: comparePrimitives,
775
- }))));
776
- default:
777
- return ofArray_1(toArray<MatchedTransition>(tryHead<MatchedTransition>(sortBy<MatchedTransition, int32>((m: MatchedTransition): int32 => m.Priority, activeTransitions, {
778
- Compare: comparePrimitives,
779
- }))));
780
- }
781
- }
782
- }
783
- }
784
-
785
- /**
786
- * Calculate probability based on satisfied conditions and pending fields
787
- */
788
- export function calculateProbability(status: TransitionStatus_$union, totalConditions: int32): float64 {
789
- switch (status.tag) {
790
- case /* Failed */ 1:
791
- return 0;
792
- case /* Pending */ 2:
793
- return (totalConditions - length(status.fields[0])) / totalConditions;
794
- default:
795
- return 1;
796
- }
797
- }
798
-
799
- /**
800
- * Predict possible outcomes based on current form state
801
- */
802
- export function predictOutcomes<FieldType>(context: ExecutionContext$1<FieldType>): FSharpList<PredictedPathway> {
803
- return truncate<PredictedPathway>(5, sortByDescending<PredictedPathway, float64>((p: PredictedPathway): float64 => p.Probability, choose<MatchedTransition, PredictedPathway>((matched: MatchedTransition): Option<PredictedPathway> => {
804
- const matchValue: TransitionStatus_$union = matched.Status;
805
- switch (matchValue.tag) {
806
- case /* Pending */ 2: {
807
- const fields: FSharpList<string> = matchValue.fields[0];
808
- const matchValue_2: Option<ClinicalPathway_StateDefinition> = findState(matched.Transition.ToState, context.PathwaySpec.States);
809
- if (matchValue_2 == null) {
810
- return undefined;
811
- }
812
- else {
813
- const toStateStr_1: string = matched.Transition.ToState.fields[0];
814
- return new PredictedPathway(toStateStr_1, 0.5, fields, extractActionsFromState(value_3(matchValue_2)), toStateStr_1);
815
- }
816
- }
817
- case /* Failed */ 1:
818
- return undefined;
819
- default: {
820
- const matchValue_1: Option<ClinicalPathway_StateDefinition> = findState(matched.Transition.ToState, context.PathwaySpec.States);
821
- if (matchValue_1 == null) {
822
- return undefined;
823
- }
824
- else {
825
- const toStateStr: string = matched.Transition.ToState.fields[0];
826
- return new PredictedPathway(toStateStr, 1, empty<string>(), extractActionsFromState(value_3(matchValue_1)), toStateStr);
827
- }
828
- }
829
- }
830
- }, evaluateAllTransitions<FieldType>(context)), {
831
- Compare: comparePrimitives,
832
- }));
833
- }
834
-
835
- /**
836
- * Calculate completion percentage based on states visited and actions executed
837
- */
838
- export function calculateCompletionPercentage<FieldType>(context: ExecutionContext$1<FieldType>): float64 {
839
- const totalStates: float64 = length(context.PathwaySpec.States);
840
- if (totalStates === 0) {
841
- return 0;
842
- }
843
- else {
844
- return (FSharpSet__get_Count(context.VisitedStates) / totalStates) * 100;
845
- }
846
- }
847
-
848
- /**
849
- * Check if pathway execution is complete
850
- */
851
- export function isExecutionComplete<FieldType>(context: ExecutionContext$1<FieldType>): boolean {
852
- if (exists<ClinicalPathway_StateDefinition>(isTerminalState, choose<Shared_StateKey, ClinicalPathway_StateDefinition>((sk: Shared_StateKey): Option<ClinicalPathway_StateDefinition> => findState(sk, context.PathwaySpec.States), toList<Shared_StateKey>(context.CurrentStates)))) {
853
- return true;
854
- }
855
- else if (isEmpty(categorizeTransitions(context.ActiveTransitions)[0])) {
856
- return !FSharpSet__get_IsEmpty(context.CurrentStates);
857
- }
858
- else {
859
- return false;
860
- }
861
- }
862
-
863
- /**
864
- * Initialize execution context from scratch
865
- */
866
- export function initializeExecution<FieldType>(formSpec: Spec_FormSpec$1<FieldType>, formData: Values_DynamicFormResultData$1<FieldType>): ExecutionContext$1<FieldType> {
867
- const matchValue: Option<ClinicalPathway_ClinicalPathwaySpec> = formSpec.ClinicalPathway;
868
- if (matchValue == null) {
869
- throw new Error("No clinical pathway found in form spec");
870
- }
871
- else {
872
- const pathway: ClinicalPathway_ClinicalPathwaySpec = value_3(matchValue);
873
- const resolver: ((arg0: string) => Shared_FieldKey) = FieldResolver_createResolver<FieldType>(formSpec);
874
- let initialStates: FSharpList<Shared_StateKey>;
875
- const matchValue_1: Option<Shared_StateKey> = pathway.InitialState;
876
- if (matchValue_1 == null) {
877
- const statesWithIncoming: FSharpSet<Shared_StateKey> = ofList_1<Shared_StateKey>(map<ClinicalPathway_TransitionDefinition, Shared_StateKey>((t: ClinicalPathway_TransitionDefinition): Shared_StateKey => t.ToState, pathway.Transitions), {
878
- Compare: compare,
879
- });
880
- const candidates: FSharpList<Shared_StateKey> = map<ClinicalPathway_StateDefinition, Shared_StateKey>((s_1: ClinicalPathway_StateDefinition): Shared_StateKey => s_1.StateKey, filter<ClinicalPathway_StateDefinition>((s: ClinicalPathway_StateDefinition): boolean => !contains<Shared_StateKey>(s.StateKey, statesWithIncoming), pathway.States));
881
- initialStates = (isEmpty(candidates) ? defaultArg(map_4<ClinicalPathway_StateDefinition, FSharpList<Shared_StateKey>>((s_2: ClinicalPathway_StateDefinition): FSharpList<Shared_StateKey> => singleton(s_2.StateKey), tryHead<ClinicalPathway_StateDefinition>(pathway.States)), empty<Shared_StateKey>()) : candidates);
882
- }
883
- else {
884
- initialStates = singleton(value_3(matchValue_1));
885
- }
886
- return new ExecutionContext$1(pathway, formSpec, ofList_1<Shared_StateKey>(initialStates, {
887
- Compare: compare,
888
- }), ofList_1<Shared_StateKey>(initialStates, {
889
- Compare: compare,
890
- }), empty_1<Shared_StateKey>({
891
- Compare: compare,
892
- }), empty<MatchedTransition>(), empty<MatchedTransition>(), empty<ClinicalPathway_ActionInfo_$union>(), formData, resolver, map<Shared_StateKey, ExecutionLogEntry>((stateKey: Shared_StateKey): ExecutionLogEntry => (new ExecutionLogEntry(now(), stateKey, "Initialized", "Starting state")), initialStates));
893
- }
894
- }
895
-
896
- /**
897
- * Resolve field value source to actual string value
898
- */
899
- export function resolveFieldValueSource<FieldType>(valueSource: ClinicalPathway_FieldValueSource_$union, formSpec: Spec_FormSpec$1<FieldType>, formData: Values_DynamicFormResultData$1<FieldType>): string {
900
- switch (valueSource.tag) {
901
- case /* FieldReference */ 1:
902
- return defaultArg(tryFind<Shared_FieldKey, string>(valueSource.fields[0], FieldResolver_extractFieldValues<FieldType>(FieldResolver_createResolver<FieldType>(formSpec), formData)), "");
903
- case /* OptionKey */ 2: {
904
- const optionKey: Shared_FieldOptionKey = valueSource.fields[0];
905
- return defaultArg(tryPick<Spec_FormField$1<FieldType>, string>((field: Spec_FormField$1<FieldType>): Option<string> => {
906
- const fieldType = field.FieldType as Spec_FieldType_$union;
907
- return map_4<Shared_FieldOption, string>((opt_1: Shared_FieldOption): string => opt_1.Description, tryFind_1<Shared_FieldOption>((opt: Shared_FieldOption): boolean => equals(opt.OptionKey, optionKey), (fieldType.tag === /* SingleChoice */ 13) ? fieldType.fields[0].Options : ((fieldType.tag === /* MultiChoice */ 15) ? fieldType.fields[0].Options : ((fieldType.tag === /* CheckboxList */ 16) ? fieldType.fields[0].Options : ((fieldType.tag === /* Dropdown */ 14) ? fieldType.fields[0].Options : ((fieldType.tag === /* Radio */ 12) ? fieldType.fields[0].Options : empty<Shared_FieldOption>()))))));
908
- }, collect<Spec_FormStep$1<FieldType>, Spec_FormField$1<FieldType>>((step: Spec_FormStep$1<FieldType>): FSharpList<Spec_FormField$1<FieldType>> => step.Fields, formSpec.Steps)), "");
909
- }
910
- default:
911
- return valueSource.fields[0];
912
- }
913
- }
914
-
915
- /**
916
- * Execute SetFieldValue action and update form data
917
- */
918
- export function executeSetFieldValueAction<FieldType>(action: ClinicalPathway_SetFieldValueAction, formSpec: Spec_FormSpec$1<FieldType>, formData: Values_DynamicFormResultData$1<FieldType>): Values_DynamicFormResultData$1<FieldType> {
919
- let matchValue: Option<ClinicalPathway_TransitionCondition_$union>, condition: ClinicalPathway_TransitionCondition_$union, fieldValues: FSharpMap<Shared_FieldKey, string>, fieldType: Spec_FieldType_$union;
920
- if (!((matchValue = action.Condition, (matchValue == null) ? true : ((condition = value_3(matchValue), (fieldValues = FieldResolver_extractFieldValues<FieldType>(FieldResolver_createResolver<FieldType>(formSpec), formData), evaluateTransitionWithPartialData<FieldType>(FieldResolver_createResolver<FieldType>(formSpec), formSpec, fieldValues, empty_1<Shared_StateKey>({
921
- Compare: compare,
922
- }), condition).tag === /* Satisfied */ 0)))))) {
923
- return formData;
924
- }
925
- else {
926
- const valueToSet: string = resolveFieldValueSource<FieldType>(action.Value, formSpec, formData);
927
- const targetFieldOpt: Option<Spec_FormField$1<FieldType>> = tryFind_1<Spec_FormField$1<FieldType>>((field: Spec_FormField$1<FieldType>): boolean => equals(field.FieldKey, action.TargetField), collect<Spec_FormStep$1<FieldType>, Spec_FormField$1<FieldType>>((step: Spec_FormStep$1<FieldType>): FSharpList<Spec_FormField$1<FieldType>> => step.Fields, formSpec.Steps));
928
- if (targetFieldOpt == null) {
929
- return formData;
930
- }
931
- else {
932
- const targetField: Spec_FormField$1<FieldType> = value_3(targetFieldOpt);
933
- const stepOpt: Option<Spec_FormStep$1<FieldType>> = tryFind_1<Spec_FormStep$1<FieldType>>((step_1: Spec_FormStep$1<FieldType>): boolean => exists<Spec_FormField$1<FieldType>>((f: Spec_FormField$1<FieldType>): boolean => equals(f.FieldKey, action.TargetField), step_1.Fields), formSpec.Steps);
934
- if (stepOpt == null) {
935
- return formData;
936
- }
937
- else {
938
- const stepOrder: Values_StepOrder = new Values_StepOrder(value_3(stepOpt).StepOrder);
939
- const fieldAnswer: Shared_FieldAnswer = new Shared_FieldAnswer(action.TargetField, targetField.Label, valueToSet);
940
- return new Values_DynamicFormResultData$1(formData.ResultFormSpecDetails, FSharpMap__Add(formData.ResultSteps, stepOrder, FSharpMap__Add(defaultArg(tryFind<Values_StepOrder, FSharpMap<Shared_FieldKey, Values_FieldDetails$1<FieldType>>>(stepOrder, formData.ResultSteps), empty_2<Shared_FieldKey, Values_FieldDetails$1<FieldType>>({
941
- Compare: compare,
942
- })), action.TargetField, (fieldType = (targetField.FieldType as Spec_FieldType_$union), new Values_FieldDetails$1(targetField.FieldOrder, action.TargetField, targetField.Label, Shared_FieldValue_Single(fieldAnswer), targetField.FieldType, map<Shared_FieldOption, Shared_FieldOption>((opt: Shared_FieldOption): Shared_FieldOption => (new Shared_FieldOption(opt.Description, opt.Value, opt.OptionKey)), (fieldType.tag === /* SingleChoice */ 13) ? fieldType.fields[0].Options : ((fieldType.tag === /* MultiChoice */ 15) ? fieldType.fields[0].Options : ((fieldType.tag === /* CheckboxList */ 16) ? fieldType.fields[0].Options : ((fieldType.tag === /* Dropdown */ 14) ? fieldType.fields[0].Options : ((fieldType.tag === /* Radio */ 12) ? fieldType.fields[0].Options : empty<Shared_FieldOption>()))))))))));
943
- }
944
- }
945
- }
946
- }
947
-
948
- /**
949
- * Execute an action and return updated form data
950
- */
951
- export function executeAction<FieldType>(action: ClinicalPathway_ActionInfo_$union, formSpec: Spec_FormSpec$1<FieldType>, formData: Values_DynamicFormResultData$1<FieldType>): Values_DynamicFormResultData$1<FieldType> {
952
- if (action.tag === /* SetFieldValue */ 10) {
953
- return executeSetFieldValueAction<FieldType>(action.fields[0], formSpec, formData);
954
- }
955
- else {
956
- return formData;
957
- }
958
- }
959
-
960
- /**
961
- * Execute all actions from a list and return updated form data
962
- */
963
- export function executeActions<FieldType>(actions: FSharpList<ClinicalPathway_ActionInfo_$union>, formSpec: Spec_FormSpec$1<FieldType>, formData: Values_DynamicFormResultData$1<FieldType>): Values_DynamicFormResultData$1<FieldType> {
964
- return fold<ClinicalPathway_ActionInfo_$union, Values_DynamicFormResultData$1<FieldType>>((currentData: Values_DynamicFormResultData$1<FieldType>, action: ClinicalPathway_ActionInfo_$union): Values_DynamicFormResultData$1<FieldType> => executeAction<FieldType>(action, formSpec, currentData), formData, actions);
965
- }
966
-
967
- /**
968
- * Execute one step of the pathway (incremental execution)
969
- */
970
- export function executeStep<FieldType>(context_mut: ExecutionContext$1<FieldType>, maxIterations_mut: int32): ExecutionContext$1<FieldType> {
971
- executeStep:
972
- while (true) {
973
- const context: ExecutionContext$1<FieldType> = context_mut, maxIterations: int32 = maxIterations_mut;
974
- if (maxIterations <= 0) {
975
- return context;
976
- }
977
- else {
978
- const patternInput: [FSharpList<MatchedTransition>, FSharpList<MatchedTransition>, FSharpList<MatchedTransition>] = categorizeTransitions(evaluateAllTransitions<FieldType>(context));
979
- const pending: FSharpList<MatchedTransition> = patternInput[1];
980
- const active: FSharpList<MatchedTransition> = patternInput[0];
981
- const selectedTransitions: FSharpList<MatchedTransition> = selectTransitionsByMode(context.PathwaySpec.ExecutionMode, active);
982
- if (isEmpty(selectedTransitions)) {
983
- return new ExecutionContext$1(context.PathwaySpec, context.FormSpec, context.CurrentStates, context.VisitedStates, context.CompletedStates, active, pending, context.ExecutedActions, context.FormData, context.FieldResolver, context.ExecutionLog);
984
- }
985
- else {
986
- const newStates: FSharpSet<Shared_StateKey> = ofList_1<Shared_StateKey>(map<MatchedTransition, Shared_StateKey>((t: MatchedTransition): Shared_StateKey => t.Transition.ToState, selectedTransitions), {
987
- Compare: compare,
988
- });
989
- const newActions: FSharpList<ClinicalPathway_ActionInfo_$union> = collect<ClinicalPathway_StateDefinition, ClinicalPathway_ActionInfo_$union>(extractActionsFromState, choose<Shared_StateKey, ClinicalPathway_StateDefinition>((sk: Shared_StateKey): Option<ClinicalPathway_StateDefinition> => findState(sk, context.PathwaySpec.States), toList<Shared_StateKey>(newStates)));
990
- const updatedFormData: Values_DynamicFormResultData$1<FieldType> = executeActions<FieldType>(newActions, context.FormSpec, context.FormData);
991
- const newLogEntries: FSharpList<ExecutionLogEntry> = map<MatchedTransition, ExecutionLogEntry>((t_1: MatchedTransition): ExecutionLogEntry => {
992
- let arg: string, arg_1: string;
993
- return new ExecutionLogEntry(now(), t_1.Transition.ToState, "Transitioned", (arg = t_1.Transition.FromState.fields[0], (arg_1 = t_1.Transition.TransitionKey.fields[0], toText(printf("From %s via %s"))(arg)(arg_1))));
994
- }, selectedTransitions);
995
- const updatedContext: ExecutionContext$1<FieldType> = new ExecutionContext$1(context.PathwaySpec, context.FormSpec, newStates, union<Shared_StateKey>(context.VisitedStates, newStates), union<Shared_StateKey>(context.CompletedStates, context.CurrentStates), active, pending, append(context.ExecutedActions, newActions), updatedFormData, context.FieldResolver, append(context.ExecutionLog, newLogEntries));
996
- if (isExecutionComplete<FieldType>(updatedContext)) {
997
- return updatedContext;
998
- }
999
- else {
1000
- context_mut = updatedContext;
1001
- maxIterations_mut = (maxIterations - 1);
1002
- continue executeStep;
1003
- }
1004
- }
1005
- }
1006
- break;
1007
- }
1008
- }
1009
-
1010
- /**
1011
- * Process incremental updates as form fills
1012
- */
1013
- export function executeIncremental<FieldType>(context: ExecutionContext$1<FieldType>, formData: Values_DynamicFormResultData$1<FieldType>): IncrementalExecutionResult$1<FieldType> {
1014
- let previousTransitionKeys: FSharpSet<Shared_TransitionKey>, newKeys: FSharpSet<Shared_TransitionKey>;
1015
- const startingAtTerminal: boolean = exists<ClinicalPathway_StateDefinition>(isTerminalState, choose<Shared_StateKey, ClinicalPathway_StateDefinition>((sk: Shared_StateKey): Option<ClinicalPathway_StateDefinition> => findState(sk, context.PathwaySpec.States), toList<Shared_StateKey>(context.CurrentStates)));
1016
- const updatedContext: ExecutionContext$1<FieldType> = new ExecutionContext$1(context.PathwaySpec, context.FormSpec, context.CurrentStates, context.VisitedStates, context.CompletedStates, context.ActiveTransitions, context.PendingTransitions, context.ExecutedActions, formData, context.FieldResolver, context.ExecutionLog);
1017
- const newContext: ExecutionContext$1<FieldType> = executeStep<FieldType>(updatedContext, 100);
1018
- return new IncrementalExecutionResult$1(newContext, map<Shared_StateKey, string>((_arg: Shared_StateKey): string => _arg.fields[0], toList<Shared_StateKey>(difference<Shared_StateKey>(newContext.CurrentStates, updatedContext.CurrentStates))), (previousTransitionKeys = ofList_1<Shared_TransitionKey>(map<MatchedTransition, Shared_TransitionKey>((t: MatchedTransition): Shared_TransitionKey => t.Transition.TransitionKey, updatedContext.ActiveTransitions), {
1019
- Compare: compare,
1020
- }), (newKeys = difference<Shared_TransitionKey>(ofList_1<Shared_TransitionKey>(map<MatchedTransition, Shared_TransitionKey>((t_1: MatchedTransition): Shared_TransitionKey => t_1.Transition.TransitionKey, newContext.ActiveTransitions), {
1021
- Compare: compare,
1022
- }), previousTransitionKeys), map<MatchedTransition, ClinicalPathway_TransitionDefinition>((t_3: MatchedTransition): ClinicalPathway_TransitionDefinition => t_3.Transition, filter<MatchedTransition>((t_2: MatchedTransition): boolean => contains<Shared_TransitionKey>(t_2.Transition.TransitionKey, newKeys), newContext.ActiveTransitions)))), predictOutcomes<FieldType>(newContext), calculateCompletionPercentage<FieldType>(newContext), isExecutionComplete<FieldType>(newContext));
1023
- }
1024
-
1025
- /**
1026
- * Get visualization state from execution context
1027
- */
1028
- export function getVisualizationState<FieldType>(context: ExecutionContext$1<FieldType>): VisualizationState {
1029
- const patternInput: [FSharpList<MatchedTransition>, FSharpList<MatchedTransition>, FSharpList<MatchedTransition>] = categorizeTransitions(context.ActiveTransitions);
1030
- const completedTransitions: FSharpList<string> = map<ExecutionLogEntry, string>((log_1: ExecutionLogEntry): string => log_1.Details, filter<ExecutionLogEntry>((log: ExecutionLogEntry): boolean => (log.Action === "Transitioned"), context.ExecutionLog));
1031
- return new VisualizationState(context.CurrentStates, context.VisitedStates, map<MatchedTransition, Shared_TransitionKey>((t: MatchedTransition): Shared_TransitionKey => t.Transition.TransitionKey, patternInput[0]), map<MatchedTransition, Shared_TransitionKey>((t_1: MatchedTransition): Shared_TransitionKey => t_1.Transition.TransitionKey, patternInput[1]), completedTransitions, predictOutcomes<FieldType>(context));
1032
- }
1033
-
1034
- /**
1035
- * Extract final clinical plans from execution context
1036
- */
1037
- export function extractClinicalPlans<FieldType>(context: ExecutionContext$1<FieldType>): FSharpList<ClinicalPlan> {
1038
- return sortBy<ClinicalPlan, int32>((plan: ClinicalPlan): int32 => plan.Priority, choose<Shared_StateKey, ClinicalPlan>((stateKey: Shared_StateKey): Option<ClinicalPlan> => {
1039
- const matchValue: Option<ClinicalPathway_StateDefinition> = findState(stateKey, context.PathwaySpec.States);
1040
- let matchResult: int32, state_1: ClinicalPathway_StateDefinition;
1041
- if (matchValue != null) {
1042
- if (!isEmpty(extractActionsFromState(value_3(matchValue)))) {
1043
- matchResult = 0;
1044
- state_1 = value_3(matchValue);
1045
- }
1046
- else {
1047
- matchResult = 1;
1048
- }
1049
- }
1050
- else {
1051
- matchResult = 1;
1052
- }
1053
- switch (matchResult) {
1054
- case 0: {
1055
- const stateKeyStr: string = stateKey.fields[0];
1056
- return new ClinicalPlan(stateKeyStr, extractActionsFromState(state_1!), stateKeyStr, state_1!.StateOrder);
1057
- }
1058
- default:
1059
- return undefined;
1060
- }
1061
- }, toList<Shared_StateKey>(context.CurrentStates)), {
1062
- Compare: comparePrimitives,
1063
- });
1064
- }
1065
-
1066
- export class PathwayExecutionResult$1<FieldType> extends Record implements IEquatable<PathwayExecutionResult$1<FieldType>>, IComparable<PathwayExecutionResult$1<FieldType>> {
1067
- readonly PathwayId: string;
1068
- readonly StartState: string;
1069
- readonly CurrentState: string;
1070
- readonly ExecutionMode: ClinicalPathway_PathwayExecutionMode_$union;
1071
- readonly SelectedPaths: FSharpList<string>;
1072
- readonly RejectedPaths: FSharpList<[string, string]>;
1073
- readonly ExecutedActions: FSharpList<ClinicalPathway_ActionInfo_$union>;
1074
- readonly VisitedStates: FSharpList<string>;
1075
- readonly TransitionsUsed: FSharpList<string>;
1076
- readonly FormData: Values_DynamicFormResultData$1<FieldType>;
1077
- readonly ExecutionTime: Date;
1078
- readonly Success: boolean;
1079
- readonly Errors: FSharpList<string>;
1080
- constructor(PathwayId: string, StartState: string, CurrentState: string, ExecutionMode: ClinicalPathway_PathwayExecutionMode_$union, SelectedPaths: FSharpList<string>, RejectedPaths: FSharpList<[string, string]>, ExecutedActions: FSharpList<ClinicalPathway_ActionInfo_$union>, VisitedStates: FSharpList<string>, TransitionsUsed: FSharpList<string>, FormData: Values_DynamicFormResultData$1<FieldType>, ExecutionTime: Date, Success: boolean, Errors: FSharpList<string>) {
1081
- super();
1082
- this.PathwayId = PathwayId;
1083
- this.StartState = StartState;
1084
- this.CurrentState = CurrentState;
1085
- this.ExecutionMode = ExecutionMode;
1086
- this.SelectedPaths = SelectedPaths;
1087
- this.RejectedPaths = RejectedPaths;
1088
- this.ExecutedActions = ExecutedActions;
1089
- this.VisitedStates = VisitedStates;
1090
- this.TransitionsUsed = TransitionsUsed;
1091
- this.FormData = FormData;
1092
- this.ExecutionTime = ExecutionTime;
1093
- this.Success = Success;
1094
- this.Errors = Errors;
1095
- }
1096
- }
1097
-
1098
- export function PathwayExecutionResult$1_$reflection(gen0: TypeInfo): TypeInfo {
1099
- return record_type("F1.Studio.PathwayExecutor.PathwayExecutionResult`1", [gen0], PathwayExecutionResult$1, () => [["PathwayId", string_type], ["StartState", string_type], ["CurrentState", string_type], ["ExecutionMode", ClinicalPathway_PathwayExecutionMode_$reflection()], ["SelectedPaths", list_type(string_type)], ["RejectedPaths", list_type(tuple_type(string_type, string_type))], ["ExecutedActions", list_type(ClinicalPathway_ActionInfo_$reflection())], ["VisitedStates", list_type(string_type)], ["TransitionsUsed", list_type(string_type)], ["FormData", Values_DynamicFormResultData$1_$reflection(gen0)], ["ExecutionTime", class_type("System.DateTime")], ["Success", bool_type], ["Errors", list_type(string_type)]]);
1100
- }
1101
-
1102
- //# sourceMappingURL=PathwayExecutor.ts.map
1
+ import { FSharpRef, Record, Union } from "@fable-org/fable-library-js/Types.js";
2
+ import { fold, findIndex, tryPick, sortByDescending, truncate, length, sortBy, tryHead, filter as filter_1, ofArray as ofArray_1, append, empty, head, tail, concat, singleton, forAll, exists, collect, map, sumBy, sum, isEmpty, choose, tryFind, FSharpList } from "@fable-org/fable-library-js/List.js";
3
+ import { tuple_type, bool_type, float64_type, lambda_type, class_type, record_type, int32_type, union_type, list_type, string_type, TypeInfo } from "@fable-org/fable-library-js/Reflection.js";
4
+ import { ClinicalPathway_PathwayExecutionMode_$reflection, ClinicalPathway_SetFieldValueAction, ClinicalPathway_FieldValueSource_$union, ClinicalPathway_PathwayExecutionMode_$union, ClinicalPathway_SelectionStrategy_$union, ClinicalPathway_CombinationStrategy_$union, ClinicalPathway_StateType_$union, ClinicalPathway_StateDefinition, Shared_PluginPropertyKey, Shared_FieldOptionKey, ClinicalPathway_TransitionCondition_$union, ClinicalPathway_LogicalOp_$union, ClinicalPathway_StateEvaluator_$union, Shared_FieldValue_Single, Shared_ConditionValue_$union, Shared_MatrixAnswer, ClinicalPathway_FieldEvaluator_$union, Shared_PluginDataProperty, Shared_PluginDataProperty_$reflection, Spec_Score, Spec_ScoreRange, Spec_FormStep$1, Spec_FormField$1, Shared_FieldValue_$union, Shared_MatrixItemKey, Shared_FieldAnswer, Shared_FieldOption, Spec_FieldType, Shared_TransitionKey_$reflection, Shared_TransitionKey, Shared_FieldKey_$reflection, ClinicalPathway_ActionInfo_$reflection, Spec_FormSpec$1_$reflection, Spec_FieldType_$reflection, ClinicalPathway_ClinicalPathwaySpec_$reflection, Shared_FieldKey, ClinicalPathway_ActionInfo_$union, Spec_FieldType_$union, Spec_FormSpec$1, ClinicalPathway_ClinicalPathwaySpec, Shared_StateKey_$reflection, Shared_StateKey, ClinicalPathway_TransitionDefinition_$reflection, ClinicalPathway_TransitionDefinition } from "./FormSpec.js";
5
+ import { tryParse as tryParse_1, uint8, float64, int32 } from "@fable-org/fable-library-js/Int32.js";
6
+ import { uncurry2, int32ToString, equals, compare, comparePrimitives, stringHash, IComparable, IEquatable } from "@fable-org/fable-library-js/Util.js";
7
+ import { difference, union, empty as empty_1, FSharpSet__get_IsEmpty, FSharpSet__get_Count, contains, ofList as ofList_1, isSubset, ofArray, map as map_1, toList, FSharpSet } from "@fable-org/fable-library-js/Set.js";
8
+ import { toArray, filter, map as map_3, defaultArg, value as value_3, bind, Option } from "@fable-org/fable-library-js/Option.js";
9
+ import { tryFind as tryFind_1, FSharpMap, ofList, toList as toList_1 } from "@fable-org/fable-library-js/Map.js";
10
+ import { updateField, getFieldDetails, FieldDetails$1, fieldToDetails } from "./FormSpecValues.js";
11
+ import { choose as choose_1, sum as sum_1, map as map_2, setItem, iterateIndexed, fill } from "@fable-org/fable-library-js/Array.js";
12
+ import { getBytesInt32 } from "@fable-org/fable-library-js/BitConverter.js";
13
+ import { arrayToGuid } from "@fable-org/fable-library-js/Guid.js";
14
+ import { printf, toText, isNullOrEmpty, isNullOrWhiteSpace, join } from "@fable-org/fable-library-js/String.js";
15
+ import { Auto_generateBoxedEncoder_437914C6, toString } from "./fable_modules/Thoth.Json.10.4.1/Encode.fs.js";
16
+ import { tryParse } from "@fable-org/fable-library-js/Double.js";
17
+ import { create, isMatch } from "@fable-org/fable-library-js/RegExp.js";
18
+ import { Auto_generateBoxedDecoder_Z6670B51, fromString } from "./fable_modules/Thoth.Json.10.4.1/Decode.fs.js";
19
+ import { FSharpResult$2_$union } from "@fable-org/fable-library-js/Result.js";
20
+ import { PluginValueRegistry_tryGet, IPluginValueConverter } from "./PluginInterface.js";
21
+ import { now } from "@fable-org/fable-library-js/Date.js";
22
+
23
+ export type TransitionStatus_$union =
24
+ | TransitionStatus<0>
25
+ | TransitionStatus<1>
26
+ | TransitionStatus<2>
27
+
28
+ export type TransitionStatus_$cases = {
29
+ 0: ["Satisfied", []],
30
+ 1: ["Failed", []],
31
+ 2: ["Pending", [FSharpList<string>]]
32
+ }
33
+
34
+ export function TransitionStatus_Satisfied() {
35
+ return new TransitionStatus<0>(0, []);
36
+ }
37
+
38
+ export function TransitionStatus_Failed() {
39
+ return new TransitionStatus<1>(1, []);
40
+ }
41
+
42
+ export function TransitionStatus_Pending(missingFields: FSharpList<string>) {
43
+ return new TransitionStatus<2>(2, [missingFields]);
44
+ }
45
+
46
+ export class TransitionStatus<Tag extends keyof TransitionStatus_$cases> extends Union<Tag, TransitionStatus_$cases[Tag][0]> {
47
+ constructor(readonly tag: Tag, readonly fields: TransitionStatus_$cases[Tag][1]) {
48
+ super();
49
+ }
50
+ cases() {
51
+ return ["Satisfied", "Failed", "Pending"];
52
+ }
53
+ }
54
+
55
+ export function TransitionStatus_$reflection(): TypeInfo {
56
+ return union_type("F1.Studio.PathwayExecutor.TransitionStatus", [], TransitionStatus, () => [[], [], [["missingFields", list_type(string_type)]]]);
57
+ }
58
+
59
+ export class MatchedTransition extends Record implements IEquatable<MatchedTransition>, IComparable<MatchedTransition> {
60
+ readonly Transition: ClinicalPathway_TransitionDefinition;
61
+ readonly Priority: int32;
62
+ readonly Status: TransitionStatus_$union;
63
+ constructor(Transition: ClinicalPathway_TransitionDefinition, Priority: int32, Status: TransitionStatus_$union) {
64
+ super();
65
+ this.Transition = Transition;
66
+ this.Priority = (Priority | 0);
67
+ this.Status = Status;
68
+ }
69
+ }
70
+
71
+ export function MatchedTransition_$reflection(): TypeInfo {
72
+ return record_type("F1.Studio.PathwayExecutor.MatchedTransition", [], MatchedTransition, () => [["Transition", ClinicalPathway_TransitionDefinition_$reflection()], ["Priority", int32_type], ["Status", TransitionStatus_$reflection()]]);
73
+ }
74
+
75
+ export class ExecutionLogEntry extends Record implements IEquatable<ExecutionLogEntry>, IComparable<ExecutionLogEntry> {
76
+ readonly Timestamp: Date;
77
+ readonly StateKey: Shared_StateKey;
78
+ readonly Action: string;
79
+ readonly Details: string;
80
+ constructor(Timestamp: Date, StateKey: Shared_StateKey, Action: string, Details: string) {
81
+ super();
82
+ this.Timestamp = Timestamp;
83
+ this.StateKey = StateKey;
84
+ this.Action = Action;
85
+ this.Details = Details;
86
+ }
87
+ }
88
+
89
+ export function ExecutionLogEntry_$reflection(): TypeInfo {
90
+ return record_type("F1.Studio.PathwayExecutor.ExecutionLogEntry", [], ExecutionLogEntry, () => [["Timestamp", class_type("System.DateTime")], ["StateKey", Shared_StateKey_$reflection()], ["Action", string_type], ["Details", string_type]]);
91
+ }
92
+
93
+ export class ExecutionContext extends Record {
94
+ readonly PathwaySpec: ClinicalPathway_ClinicalPathwaySpec;
95
+ readonly FormSpec: Spec_FormSpec$1<Spec_FieldType_$union>;
96
+ readonly CurrentStates: FSharpSet<Shared_StateKey>;
97
+ readonly VisitedStates: FSharpSet<Shared_StateKey>;
98
+ readonly CompletedStates: FSharpSet<Shared_StateKey>;
99
+ readonly ActiveTransitions: FSharpList<MatchedTransition>;
100
+ readonly PendingTransitions: FSharpList<MatchedTransition>;
101
+ readonly ExecutedActions: FSharpList<ClinicalPathway_ActionInfo_$union>;
102
+ readonly FieldResolver: ((arg0: string) => Shared_FieldKey);
103
+ readonly ExecutionLog: FSharpList<ExecutionLogEntry>;
104
+ constructor(PathwaySpec: ClinicalPathway_ClinicalPathwaySpec, FormSpec: Spec_FormSpec$1<Spec_FieldType_$union>, CurrentStates: FSharpSet<Shared_StateKey>, VisitedStates: FSharpSet<Shared_StateKey>, CompletedStates: FSharpSet<Shared_StateKey>, ActiveTransitions: FSharpList<MatchedTransition>, PendingTransitions: FSharpList<MatchedTransition>, ExecutedActions: FSharpList<ClinicalPathway_ActionInfo_$union>, FieldResolver: ((arg0: string) => Shared_FieldKey), ExecutionLog: FSharpList<ExecutionLogEntry>) {
105
+ super();
106
+ this.PathwaySpec = PathwaySpec;
107
+ this.FormSpec = FormSpec;
108
+ this.CurrentStates = CurrentStates;
109
+ this.VisitedStates = VisitedStates;
110
+ this.CompletedStates = CompletedStates;
111
+ this.ActiveTransitions = ActiveTransitions;
112
+ this.PendingTransitions = PendingTransitions;
113
+ this.ExecutedActions = ExecutedActions;
114
+ this.FieldResolver = FieldResolver;
115
+ this.ExecutionLog = ExecutionLog;
116
+ }
117
+ }
118
+
119
+ export function ExecutionContext_$reflection(): TypeInfo {
120
+ return record_type("F1.Studio.PathwayExecutor.ExecutionContext", [], ExecutionContext, () => [["PathwaySpec", ClinicalPathway_ClinicalPathwaySpec_$reflection()], ["FormSpec", Spec_FormSpec$1_$reflection(Spec_FieldType_$reflection())], ["CurrentStates", class_type("Microsoft.FSharp.Collections.FSharpSet`1", [Shared_StateKey_$reflection()])], ["VisitedStates", class_type("Microsoft.FSharp.Collections.FSharpSet`1", [Shared_StateKey_$reflection()])], ["CompletedStates", class_type("Microsoft.FSharp.Collections.FSharpSet`1", [Shared_StateKey_$reflection()])], ["ActiveTransitions", list_type(MatchedTransition_$reflection())], ["PendingTransitions", list_type(MatchedTransition_$reflection())], ["ExecutedActions", list_type(ClinicalPathway_ActionInfo_$reflection())], ["FieldResolver", lambda_type(string_type, Shared_FieldKey_$reflection())], ["ExecutionLog", list_type(ExecutionLogEntry_$reflection())]]);
121
+ }
122
+
123
+ export class PredictedPathway extends Record implements IEquatable<PredictedPathway>, IComparable<PredictedPathway> {
124
+ readonly PathwayId: string;
125
+ readonly Probability: float64;
126
+ readonly RequiredFields: FSharpList<string>;
127
+ readonly ExpectedActions: FSharpList<ClinicalPathway_ActionInfo_$union>;
128
+ readonly TargetState: string;
129
+ constructor(PathwayId: string, Probability: float64, RequiredFields: FSharpList<string>, ExpectedActions: FSharpList<ClinicalPathway_ActionInfo_$union>, TargetState: string) {
130
+ super();
131
+ this.PathwayId = PathwayId;
132
+ this.Probability = Probability;
133
+ this.RequiredFields = RequiredFields;
134
+ this.ExpectedActions = ExpectedActions;
135
+ this.TargetState = TargetState;
136
+ }
137
+ }
138
+
139
+ export function PredictedPathway_$reflection(): TypeInfo {
140
+ return record_type("F1.Studio.PathwayExecutor.PredictedPathway", [], PredictedPathway, () => [["PathwayId", string_type], ["Probability", float64_type], ["RequiredFields", list_type(string_type)], ["ExpectedActions", list_type(ClinicalPathway_ActionInfo_$reflection())], ["TargetState", string_type]]);
141
+ }
142
+
143
+ export class IncrementalExecutionResult extends Record {
144
+ readonly Context: ExecutionContext;
145
+ readonly NewlyActivatedStates: FSharpList<string>;
146
+ readonly NewlyActiveTransitions: FSharpList<ClinicalPathway_TransitionDefinition>;
147
+ readonly PredictedOutcomes: FSharpList<PredictedPathway>;
148
+ readonly CompletionPercentage: float64;
149
+ readonly IsComplete: boolean;
150
+ constructor(Context: ExecutionContext, NewlyActivatedStates: FSharpList<string>, NewlyActiveTransitions: FSharpList<ClinicalPathway_TransitionDefinition>, PredictedOutcomes: FSharpList<PredictedPathway>, CompletionPercentage: float64, IsComplete: boolean) {
151
+ super();
152
+ this.Context = Context;
153
+ this.NewlyActivatedStates = NewlyActivatedStates;
154
+ this.NewlyActiveTransitions = NewlyActiveTransitions;
155
+ this.PredictedOutcomes = PredictedOutcomes;
156
+ this.CompletionPercentage = CompletionPercentage;
157
+ this.IsComplete = IsComplete;
158
+ }
159
+ }
160
+
161
+ export function IncrementalExecutionResult_$reflection(): TypeInfo {
162
+ return record_type("F1.Studio.PathwayExecutor.IncrementalExecutionResult", [], IncrementalExecutionResult, () => [["Context", ExecutionContext_$reflection()], ["NewlyActivatedStates", list_type(string_type)], ["NewlyActiveTransitions", list_type(ClinicalPathway_TransitionDefinition_$reflection())], ["PredictedOutcomes", list_type(PredictedPathway_$reflection())], ["CompletionPercentage", float64_type], ["IsComplete", bool_type]]);
163
+ }
164
+
165
+ export class ClinicalPlan extends Record implements IEquatable<ClinicalPlan>, IComparable<ClinicalPlan> {
166
+ readonly PlanId: string;
167
+ readonly Actions: FSharpList<ClinicalPathway_ActionInfo_$union>;
168
+ readonly TargetState: string;
169
+ readonly Priority: int32;
170
+ constructor(PlanId: string, Actions: FSharpList<ClinicalPathway_ActionInfo_$union>, TargetState: string, Priority: int32) {
171
+ super();
172
+ this.PlanId = PlanId;
173
+ this.Actions = Actions;
174
+ this.TargetState = TargetState;
175
+ this.Priority = (Priority | 0);
176
+ }
177
+ }
178
+
179
+ export function ClinicalPlan_$reflection(): TypeInfo {
180
+ return record_type("F1.Studio.PathwayExecutor.ClinicalPlan", [], ClinicalPlan, () => [["PlanId", string_type], ["Actions", list_type(ClinicalPathway_ActionInfo_$reflection())], ["TargetState", string_type], ["Priority", int32_type]]);
181
+ }
182
+
183
+ export class VisualizationState extends Record implements IEquatable<VisualizationState>, IComparable<VisualizationState> {
184
+ readonly CurrentStates: FSharpSet<Shared_StateKey>;
185
+ readonly VisitedStates: FSharpSet<Shared_StateKey>;
186
+ readonly ActiveTransitions: FSharpList<Shared_TransitionKey>;
187
+ readonly PendingTransitions: FSharpList<Shared_TransitionKey>;
188
+ readonly CompletedTransitions: FSharpList<string>;
189
+ readonly PredictedOutcomes: FSharpList<PredictedPathway>;
190
+ constructor(CurrentStates: FSharpSet<Shared_StateKey>, VisitedStates: FSharpSet<Shared_StateKey>, ActiveTransitions: FSharpList<Shared_TransitionKey>, PendingTransitions: FSharpList<Shared_TransitionKey>, CompletedTransitions: FSharpList<string>, PredictedOutcomes: FSharpList<PredictedPathway>) {
191
+ super();
192
+ this.CurrentStates = CurrentStates;
193
+ this.VisitedStates = VisitedStates;
194
+ this.ActiveTransitions = ActiveTransitions;
195
+ this.PendingTransitions = PendingTransitions;
196
+ this.CompletedTransitions = CompletedTransitions;
197
+ this.PredictedOutcomes = PredictedOutcomes;
198
+ }
199
+ }
200
+
201
+ export function VisualizationState_$reflection(): TypeInfo {
202
+ return record_type("F1.Studio.PathwayExecutor.VisualizationState", [], VisualizationState, () => [["CurrentStates", class_type("Microsoft.FSharp.Collections.FSharpSet`1", [Shared_StateKey_$reflection()])], ["VisitedStates", class_type("Microsoft.FSharp.Collections.FSharpSet`1", [Shared_StateKey_$reflection()])], ["ActiveTransitions", list_type(Shared_TransitionKey_$reflection())], ["PendingTransitions", list_type(Shared_TransitionKey_$reflection())], ["CompletedTransitions", list_type(string_type)], ["PredictedOutcomes", list_type(PredictedPathway_$reflection())]]);
203
+ }
204
+
205
+ /**
206
+ * Extract options from a field type (single source of truth for scoring)
207
+ * This is THE ONLY place where we extract scoring information from fields
208
+ */
209
+ export function ScoreCalculator_extractFieldOptions<FieldType>(fieldType: FieldType): Option<FSharpList<Shared_FieldOption>> {
210
+ const matchValue: any = fieldType;
211
+ if (matchValue instanceof Spec_FieldType) {
212
+ const ft = matchValue as Spec_FieldType_$union;
213
+ switch (ft.tag) {
214
+ case /* Radio */ 12:
215
+ return ft.fields[0].Options;
216
+ case /* SingleChoice */ 13:
217
+ return ft.fields[0].Options;
218
+ case /* Dropdown */ 14:
219
+ return ft.fields[0].Options;
220
+ case /* TextAutoComplete */ 18:
221
+ return ft.fields[0].Options;
222
+ case /* MultiChoice */ 15:
223
+ return ft.fields[0].Options;
224
+ case /* CheckboxList */ 16:
225
+ return ft.fields[0].Options;
226
+ case /* TagList */ 17:
227
+ return ft.fields[0].Options;
228
+ case /* Matrix */ 19:
229
+ return ft.fields[0].Options;
230
+ default:
231
+ return undefined;
232
+ }
233
+ }
234
+ else {
235
+ return undefined;
236
+ }
237
+ }
238
+
239
+ /**
240
+ * Calculate score for a field value given its options
241
+ */
242
+ export function ScoreCalculator_calculateFieldValueScore(options: FSharpList<Shared_FieldOption>, fieldValue: Shared_FieldValue_$union): Option<int32> {
243
+ switch (fieldValue.tag) {
244
+ case /* Single */ 0: {
245
+ const answer: Shared_FieldAnswer = fieldValue.fields[0];
246
+ return bind<Shared_FieldOption, int32>((opt_1: Shared_FieldOption): Option<int32> => opt_1.Score, tryFind<Shared_FieldOption>((opt: Shared_FieldOption): boolean => (opt.Value === answer.Value), options));
247
+ }
248
+ case /* Multiple */ 1: {
249
+ const _arg: FSharpList<int32> = choose<Shared_FieldAnswer, int32>((answer_1: Shared_FieldAnswer): Option<int32> => bind<Shared_FieldOption, int32>((opt_3: Shared_FieldOption): Option<int32> => opt_3.Score, tryFind<Shared_FieldOption>((opt_2: Shared_FieldOption): boolean => (opt_2.Value === answer_1.Value), options)), toList<Shared_FieldAnswer>(fieldValue.fields[0]));
250
+ if (isEmpty(_arg)) {
251
+ return undefined;
252
+ }
253
+ else {
254
+ return sum<int32>(_arg, {
255
+ GetZero: (): int32 => 0,
256
+ Add: (x: int32, y: int32): int32 => (x + y),
257
+ });
258
+ }
259
+ }
260
+ case /* Matrix */ 2: {
261
+ const _arg_2: FSharpList<int32> = choose<[Shared_MatrixItemKey, string], int32>((tupledArg: [Shared_MatrixItemKey, string]): Option<int32> => bind<Shared_FieldOption, int32>((opt_5: Shared_FieldOption): Option<int32> => opt_5.Score, tryFind<Shared_FieldOption>((opt_4: Shared_FieldOption): boolean => (opt_4.Value === tupledArg[1]), options)), toList_1<Shared_MatrixItemKey, string>(fieldValue.fields[0].Values));
262
+ if (isEmpty(_arg_2)) {
263
+ return undefined;
264
+ }
265
+ else {
266
+ return sum<int32>(_arg_2, {
267
+ GetZero: (): int32 => 0,
268
+ Add: (x_1: int32, y_1: int32): int32 => (x_1 + y_1),
269
+ });
270
+ }
271
+ }
272
+ default:
273
+ return undefined;
274
+ }
275
+ }
276
+
277
+ /**
278
+ * Calculate score for a single field
279
+ */
280
+ export function ScoreCalculator_calculateFieldScore<FieldType>(field: Spec_FormField$1<FieldType>, fieldValue: Shared_FieldValue_$union): Option<int32> {
281
+ return bind<FSharpList<Shared_FieldOption>, int32>((options: FSharpList<Shared_FieldOption>): Option<int32> => ScoreCalculator_calculateFieldValueScore(options, fieldValue), ScoreCalculator_extractFieldOptions<FieldType>(field.FieldType));
282
+ }
283
+
284
+ /**
285
+ * Calculate total score for a form step (reads from FormSpec step fields)
286
+ */
287
+ export function ScoreCalculator_calculateStepScore(formSpec: Spec_FormSpec$1<Spec_FieldType_$union>, step: Spec_FormStep$1<Spec_FieldType_$union>): int32 {
288
+ return sum<int32>(choose<Spec_FormField$1<Spec_FieldType_$union>, int32>((field: Spec_FormField$1<Spec_FieldType_$union>): Option<int32> => ScoreCalculator_calculateFieldScore<Spec_FieldType_$union>(field, fieldToDetails(field).FieldValue), step.Fields), {
289
+ GetZero: (): int32 => 0,
290
+ Add: (x: int32, y: int32): int32 => (x + y),
291
+ });
292
+ }
293
+
294
+ /**
295
+ * Calculate total score for entire form (reads from FormSpec)
296
+ */
297
+ export function ScoreCalculator_calculateTotalScore(formSpec: Spec_FormSpec$1<Spec_FieldType_$union>): int32 {
298
+ return sumBy<Spec_FormStep$1<Spec_FieldType_$union>, int32>((step: Spec_FormStep$1<Spec_FieldType_$union>): int32 => ScoreCalculator_calculateStepScore(formSpec, step), formSpec.Steps, {
299
+ GetZero: (): int32 => 0,
300
+ Add: (x: int32, y: int32): int32 => (x + y),
301
+ });
302
+ }
303
+
304
+ /**
305
+ * Get score range for a given score value
306
+ */
307
+ export function ScoreCalculator_getScoreRange(score: Option<Spec_Score>, value: int32): Option<Spec_ScoreRange> {
308
+ if (score != null) {
309
+ return tryFind<Spec_ScoreRange>((range: Spec_ScoreRange): boolean => {
310
+ if (value >= range.Min) {
311
+ return value <= range.Max;
312
+ }
313
+ else {
314
+ return false;
315
+ }
316
+ }, value_3(score).ScoreRanges);
317
+ }
318
+ else {
319
+ return undefined;
320
+ }
321
+ }
322
+
323
+ /**
324
+ * Generate deterministic GUID from field label
325
+ */
326
+ export function FieldResolver_generateFieldKey(fieldName: string): Shared_FieldKey {
327
+ const hash: int32 = stringHash(fieldName) | 0;
328
+ const bytes: uint8[] = fill(new Array(16), 0, 16, 0);
329
+ iterateIndexed<uint8>((i: int32, b: uint8): void => {
330
+ if (i < 4) {
331
+ setItem(bytes, i, b);
332
+ }
333
+ }, Array.from(getBytesInt32(hash)));
334
+ iterateIndexed<uint8>((i_1: int32, b_1: uint8): void => {
335
+ if (i_1 < 4) {
336
+ setItem(bytes, i_1 + 4, b_1);
337
+ }
338
+ }, Array.from(getBytesInt32(hash >> 1)));
339
+ iterateIndexed<uint8>((i_2: int32, b_2: uint8): void => {
340
+ if (i_2 < 4) {
341
+ setItem(bytes, i_2 + 8, b_2);
342
+ }
343
+ }, Array.from(getBytesInt32(hash >> 2)));
344
+ iterateIndexed<uint8>((i_3: int32, b_3: uint8): void => {
345
+ if (i_3 < 4) {
346
+ setItem(bytes, i_3 + 12, b_3);
347
+ }
348
+ }, Array.from(getBytesInt32(hash >> 3)));
349
+ return new Shared_FieldKey(arrayToGuid(bytes));
350
+ }
351
+
352
+ /**
353
+ * Create resolver that maps pathway field references to FieldKeys
354
+ */
355
+ export function FieldResolver_createResolver(formSpec: Spec_FormSpec$1<Spec_FieldType_$union>): ((arg0: string) => Shared_FieldKey) {
356
+ const labelToFieldKey: FSharpMap<string, Shared_FieldKey> = ofList<string, Shared_FieldKey>(map<Spec_FormField$1<Spec_FieldType_$union>, [string, Shared_FieldKey]>((field: Spec_FormField$1<Spec_FieldType_$union>): [string, Shared_FieldKey] => ([field.Label.toLocaleLowerCase().trim(), field.FieldKey] as [string, Shared_FieldKey]), collect<Spec_FormStep$1<Spec_FieldType_$union>, Spec_FormField$1<Spec_FieldType_$union>>((step: Spec_FormStep$1<Spec_FieldType_$union>): FSharpList<Spec_FormField$1<Spec_FieldType_$union>> => step.Fields, formSpec.Steps)), {
357
+ Compare: comparePrimitives,
358
+ });
359
+ return (fieldReference: string): Shared_FieldKey => {
360
+ const matchValue: Option<Shared_FieldKey> = tryFind_1<string, Shared_FieldKey>(fieldReference.toLocaleLowerCase().trim(), labelToFieldKey);
361
+ return (matchValue == null) ? FieldResolver_generateFieldKey(fieldReference) : value_3(matchValue);
362
+ };
363
+ }
364
+
365
+ /**
366
+ * Extract field values from form spec (reads from FormSpec)
367
+ */
368
+ export function FieldResolver_extractFieldValues(resolver: ((arg0: string) => Shared_FieldKey), formSpec: Spec_FormSpec$1<Spec_FieldType_$union>): FSharpMap<Shared_FieldKey, string> {
369
+ return ofList<Shared_FieldKey, string>(collect<Spec_FormStep$1<Spec_FieldType_$union>, [Shared_FieldKey, string]>((step: Spec_FormStep$1<Spec_FieldType_$union>): FSharpList<[Shared_FieldKey, string]> => map<Spec_FormField$1<Spec_FieldType_$union>, [Shared_FieldKey, string]>((field: Spec_FormField$1<Spec_FieldType_$union>): [Shared_FieldKey, string] => {
370
+ let matchValue: Shared_FieldValue_$union, pluginData: FSharpList<Shared_PluginDataProperty>;
371
+ return [field.FieldKey, (matchValue = fieldToDetails(field).FieldValue, (matchValue.tag === /* Multiple */ 1) ? join(",", toList<string>(map_1<Shared_FieldAnswer, string>((a: Shared_FieldAnswer): string => a.Value, matchValue.fields[0], {
372
+ Compare: comparePrimitives,
373
+ }))) : ((matchValue.tag === /* Matrix */ 2) ? join(",", map<[Shared_MatrixItemKey, string], string>((tupledArg: [Shared_MatrixItemKey, string]): string => tupledArg[1], toList_1<Shared_MatrixItemKey, string>(matchValue.fields[0].Values))) : ((matchValue.tag === /* PluginData */ 3) ? ((pluginData = matchValue.fields[0], toString(0, Auto_generateBoxedEncoder_437914C6(list_type(Shared_PluginDataProperty_$reflection()), undefined, undefined, undefined)(pluginData)))) : matchValue.fields[0].Value)))] as [Shared_FieldKey, string];
374
+ }, step.Fields), formSpec.Steps), {
375
+ Compare: compare,
376
+ });
377
+ }
378
+
379
+ /**
380
+ * Evaluate a field condition with a specific evaluator (string-based, kept for backward compatibility)
381
+ */
382
+ export function evaluateFieldCondition(actualValue: string, evaluator: ClinicalPathway_FieldEvaluator_$union, expectedValue: string): boolean {
383
+ switch (evaluator.tag) {
384
+ case /* NotEquals */ 1:
385
+ return actualValue.trim().toLocaleLowerCase() !== expectedValue.trim().toLocaleLowerCase();
386
+ case /* GreaterThan */ 5: {
387
+ let matchValue: [boolean, float64];
388
+ let outArg = 0;
389
+ matchValue = ([tryParse(actualValue, new FSharpRef<float64>((): float64 => outArg, (v: float64): void => {
390
+ outArg = v;
391
+ })), outArg] as [boolean, float64]);
392
+ let matchValue_1: [boolean, float64];
393
+ let outArg_1 = 0;
394
+ matchValue_1 = ([tryParse(expectedValue, new FSharpRef<float64>((): float64 => outArg_1, (v_1: float64): void => {
395
+ outArg_1 = v_1;
396
+ })), outArg_1] as [boolean, float64]);
397
+ let matchResult: int32;
398
+ if (matchValue[0]) {
399
+ if (matchValue_1[0]) {
400
+ matchResult = 0;
401
+ }
402
+ else {
403
+ matchResult = 1;
404
+ }
405
+ }
406
+ else {
407
+ matchResult = 1;
408
+ }
409
+ switch (matchResult) {
410
+ case 0:
411
+ return matchValue[1] > matchValue_1[1];
412
+ default:
413
+ return false;
414
+ }
415
+ }
416
+ case /* GreaterOrEqual */ 6: {
417
+ let matchValue_3: [boolean, float64];
418
+ let outArg_2 = 0;
419
+ matchValue_3 = ([tryParse(actualValue, new FSharpRef<float64>((): float64 => outArg_2, (v_2: float64): void => {
420
+ outArg_2 = v_2;
421
+ })), outArg_2] as [boolean, float64]);
422
+ let matchValue_4: [boolean, float64];
423
+ let outArg_3 = 0;
424
+ matchValue_4 = ([tryParse(expectedValue, new FSharpRef<float64>((): float64 => outArg_3, (v_3: float64): void => {
425
+ outArg_3 = v_3;
426
+ })), outArg_3] as [boolean, float64]);
427
+ let matchResult_1: int32;
428
+ if (matchValue_3[0]) {
429
+ if (matchValue_4[0]) {
430
+ matchResult_1 = 0;
431
+ }
432
+ else {
433
+ matchResult_1 = 1;
434
+ }
435
+ }
436
+ else {
437
+ matchResult_1 = 1;
438
+ }
439
+ switch (matchResult_1) {
440
+ case 0:
441
+ return matchValue_3[1] >= matchValue_4[1];
442
+ default:
443
+ return false;
444
+ }
445
+ }
446
+ case /* LessThan */ 7: {
447
+ let matchValue_6: [boolean, float64];
448
+ let outArg_4 = 0;
449
+ matchValue_6 = ([tryParse(actualValue, new FSharpRef<float64>((): float64 => outArg_4, (v_4: float64): void => {
450
+ outArg_4 = v_4;
451
+ })), outArg_4] as [boolean, float64]);
452
+ let matchValue_7: [boolean, float64];
453
+ let outArg_5 = 0;
454
+ matchValue_7 = ([tryParse(expectedValue, new FSharpRef<float64>((): float64 => outArg_5, (v_5: float64): void => {
455
+ outArg_5 = v_5;
456
+ })), outArg_5] as [boolean, float64]);
457
+ let matchResult_2: int32;
458
+ if (matchValue_6[0]) {
459
+ if (matchValue_7[0]) {
460
+ matchResult_2 = 0;
461
+ }
462
+ else {
463
+ matchResult_2 = 1;
464
+ }
465
+ }
466
+ else {
467
+ matchResult_2 = 1;
468
+ }
469
+ switch (matchResult_2) {
470
+ case 0:
471
+ return matchValue_6[1] < matchValue_7[1];
472
+ default:
473
+ return false;
474
+ }
475
+ }
476
+ case /* LessOrEqual */ 8: {
477
+ let matchValue_9: [boolean, float64];
478
+ let outArg_6 = 0;
479
+ matchValue_9 = ([tryParse(actualValue, new FSharpRef<float64>((): float64 => outArg_6, (v_6: float64): void => {
480
+ outArg_6 = v_6;
481
+ })), outArg_6] as [boolean, float64]);
482
+ let matchValue_10: [boolean, float64];
483
+ let outArg_7 = 0;
484
+ matchValue_10 = ([tryParse(expectedValue, new FSharpRef<float64>((): float64 => outArg_7, (v_7: float64): void => {
485
+ outArg_7 = v_7;
486
+ })), outArg_7] as [boolean, float64]);
487
+ let matchResult_3: int32;
488
+ if (matchValue_9[0]) {
489
+ if (matchValue_10[0]) {
490
+ matchResult_3 = 0;
491
+ }
492
+ else {
493
+ matchResult_3 = 1;
494
+ }
495
+ }
496
+ else {
497
+ matchResult_3 = 1;
498
+ }
499
+ switch (matchResult_3) {
500
+ case 0:
501
+ return matchValue_9[1] <= matchValue_10[1];
502
+ default:
503
+ return false;
504
+ }
505
+ }
506
+ case /* Contains */ 9:
507
+ return actualValue.toLocaleLowerCase().indexOf(expectedValue.toLocaleLowerCase()) >= 0;
508
+ case /* IsPresent */ 10:
509
+ if (!isNullOrWhiteSpace(actualValue) && (actualValue.toLocaleLowerCase() !== "false")) {
510
+ return actualValue.toLocaleLowerCase() !== "no";
511
+ }
512
+ else {
513
+ return false;
514
+ }
515
+ case /* IsAbsent */ 11:
516
+ if (isNullOrWhiteSpace(actualValue) ? true : (actualValue.toLocaleLowerCase() === "false")) {
517
+ return true;
518
+ }
519
+ else {
520
+ return actualValue.toLocaleLowerCase() === "no";
521
+ }
522
+ case /* MatchesPattern */ 12:
523
+ return isMatch(create(evaluator.fields[0]), actualValue);
524
+ case /* InRange */ 13: {
525
+ const minVal: int32 = evaluator.fields[0] | 0;
526
+ const maxVal: int32 = evaluator.fields[1] | 0;
527
+ let matchValue_12: [boolean, float64];
528
+ let outArg_8 = 0;
529
+ matchValue_12 = ([tryParse(actualValue.trim(), new FSharpRef<float64>((): float64 => outArg_8, (v_8: float64): void => {
530
+ outArg_8 = v_8;
531
+ })), outArg_8] as [boolean, float64]);
532
+ if (matchValue_12[0]) {
533
+ const actual_4: float64 = matchValue_12[1];
534
+ if (actual_4 >= minVal) {
535
+ return actual_4 <= maxVal;
536
+ }
537
+ else {
538
+ return false;
539
+ }
540
+ }
541
+ else {
542
+ return false;
543
+ }
544
+ }
545
+ case /* InSet */ 2:
546
+ return exists<string>((v_9: string): boolean => (v_9.trim().toLocaleLowerCase() === actualValue.trim().toLocaleLowerCase()), evaluator.fields[0]);
547
+ case /* NotInSet */ 3:
548
+ return !exists<string>((v_10: string): boolean => (v_10.trim().toLocaleLowerCase() === actualValue.trim().toLocaleLowerCase()), evaluator.fields[0]);
549
+ case /* ContainsAll */ 4: {
550
+ const values_2: FSharpList<string> = evaluator.fields[0];
551
+ const actualParts: FSharpSet<string> = ofArray<string>(map_2<string, string>((s: string): string => s.trim().toLocaleLowerCase(), actualValue.split(",")), {
552
+ Compare: comparePrimitives,
553
+ });
554
+ return isSubset<string>(ofList_1<string>(map<string, string>((s_1: string): string => s_1.trim().toLocaleLowerCase(), values_2), {
555
+ Compare: comparePrimitives,
556
+ }), actualParts);
557
+ }
558
+ default:
559
+ return actualValue.trim().toLocaleLowerCase() === expectedValue.trim().toLocaleLowerCase();
560
+ }
561
+ }
562
+
563
+ /**
564
+ * Evaluate Matrix condition: check specific item(s) in the matrix (e.g. PHQ-9 item 9 = suicidal ideation)
565
+ * ConditionValue.Matrix [[itemKey, expectedVal]] means "item should have this value"
566
+ * For NotEquals: trigger when item value ≠ expected (e.g. item 9 ≠ "0" → suicidal ideation endorsed)
567
+ */
568
+ export function evaluateMatrixItemCondition(actualMatrix: Shared_MatrixAnswer, evaluator: ClinicalPathway_FieldEvaluator_$union, expectedMatrix: FSharpMap<Shared_MatrixItemKey, string>): boolean {
569
+ const entries: FSharpList<[Shared_MatrixItemKey, string]> = toList_1<Shared_MatrixItemKey, string>(expectedMatrix);
570
+ if (isEmpty(entries)) {
571
+ return false;
572
+ }
573
+ else {
574
+ const allMatch: boolean = forAll<[Shared_MatrixItemKey, string]>((tupledArg: [Shared_MatrixItemKey, string]): boolean => {
575
+ const expectedVal: string = tupledArg[1];
576
+ const actualVal: string = defaultArg(tryFind_1<Shared_MatrixItemKey, string>(tupledArg[0], actualMatrix.Values), "0");
577
+ switch (evaluator.tag) {
578
+ case /* Equals */ 0:
579
+ return actualVal.trim().toLocaleLowerCase() === expectedVal.trim().toLocaleLowerCase();
580
+ case /* NotEquals */ 1:
581
+ return actualVal.trim().toLocaleLowerCase() !== expectedVal.trim().toLocaleLowerCase();
582
+ default:
583
+ return evaluateFieldCondition(actualVal, evaluator, expectedVal);
584
+ }
585
+ }, entries);
586
+ switch (evaluator.tag) {
587
+ case /* Equals */ 0:
588
+ return allMatch;
589
+ case /* NotEquals */ 1:
590
+ return allMatch;
591
+ default:
592
+ return allMatch;
593
+ }
594
+ }
595
+ }
596
+
597
+ /**
598
+ * Evaluate a field condition with ConditionValue (type-aware comparison)
599
+ */
600
+ export function evaluateFieldConditionWithConditionValue(actualFieldValue: Shared_FieldValue_$union, evaluator: ClinicalPathway_FieldEvaluator_$union, expectedConditionValue: Shared_ConditionValue_$union): boolean {
601
+ let pluginData: FSharpList<Shared_PluginDataProperty>, pluginData_1: Shared_PluginDataProperty;
602
+ let matchResult: int32, actualMatrix: Shared_MatrixAnswer, expectedMatrix: FSharpMap<Shared_MatrixItemKey, string>;
603
+ if (actualFieldValue.tag === /* Matrix */ 2) {
604
+ if (expectedConditionValue.tag === /* Matrix */ 2) {
605
+ matchResult = 0;
606
+ actualMatrix = actualFieldValue.fields[0];
607
+ expectedMatrix = expectedConditionValue.fields[0];
608
+ }
609
+ else {
610
+ matchResult = 1;
611
+ }
612
+ }
613
+ else {
614
+ matchResult = 1;
615
+ }
616
+ switch (matchResult) {
617
+ case 0:
618
+ return evaluateMatrixItemCondition(actualMatrix!, evaluator, expectedMatrix!);
619
+ default:
620
+ return evaluateFieldCondition((actualFieldValue.tag === /* Multiple */ 1) ? join(",", toList<string>(map_1<Shared_FieldAnswer, string>((a: Shared_FieldAnswer): string => a.Value, actualFieldValue.fields[0], {
621
+ Compare: comparePrimitives,
622
+ }))) : ((actualFieldValue.tag === /* Matrix */ 2) ? join(",", map<[Shared_MatrixItemKey, string], string>((tupledArg: [Shared_MatrixItemKey, string]): string => tupledArg[1], toList_1<Shared_MatrixItemKey, string>(actualFieldValue.fields[0].Values))) : ((actualFieldValue.tag === /* PluginData */ 3) ? ((pluginData = actualFieldValue.fields[0], toString(0, Auto_generateBoxedEncoder_437914C6(list_type(Shared_PluginDataProperty_$reflection()), undefined, undefined, undefined)(pluginData)))) : actualFieldValue.fields[0].Value)), evaluator, (expectedConditionValue.tag === /* Multiple */ 1) ? join(",", toList<string>(expectedConditionValue.fields[0])) : ((expectedConditionValue.tag === /* Matrix */ 2) ? join(",", map<[Shared_MatrixItemKey, string], string>((tupledArg_1: [Shared_MatrixItemKey, string]): string => tupledArg_1[1], toList_1<Shared_MatrixItemKey, string>(expectedConditionValue.fields[0]))) : ((expectedConditionValue.tag === /* PluginData */ 3) ? ((pluginData_1 = expectedConditionValue.fields[0], toString(0, Auto_generateBoxedEncoder_437914C6(Shared_PluginDataProperty_$reflection(), undefined, undefined, undefined)(pluginData_1)))) : expectedConditionValue.fields[0])));
623
+ }
624
+ }
625
+
626
+ /**
627
+ * Recursively evaluate a transition condition with partial data support
628
+ */
629
+ export function evaluateTransitionWithPartialData(resolver: ((arg0: string) => Shared_FieldKey), formSpec: Option<Spec_FormSpec$1<Spec_FieldType_$union>>, fieldValues: FSharpMap<Shared_FieldKey, string>, visitedStates: FSharpSet<Shared_StateKey>, formSpecForScores: Option<Spec_FormSpec$1<Spec_FieldType_$union>>, condition: ClinicalPathway_TransitionCondition_$union): TransitionStatus_$union {
630
+ let score: int32, data_1: Spec_FormSpec$1<Spec_FieldType_$union>, score_2: int32, pluginData: Shared_PluginDataProperty;
631
+ switch (condition.tag) {
632
+ case /* FieldCondition */ 0: {
633
+ const fieldKey: Shared_FieldKey = condition.fields[0];
634
+ const evaluator: ClinicalPathway_FieldEvaluator_$union = condition.fields[1];
635
+ const conditionValue: Shared_ConditionValue_$union = condition.fields[2];
636
+ if (evaluator.tag === /* InRange */ 13) {
637
+ const minVal: int32 = evaluator.fields[0] | 0;
638
+ const maxVal: int32 = evaluator.fields[1] | 0;
639
+ let matchResult: int32, data: Spec_FormSpec$1<Spec_FieldType_$union>, spec: Spec_FormSpec$1<Spec_FieldType_$union>;
640
+ if (formSpec != null) {
641
+ if (formSpecForScores != null) {
642
+ matchResult = 0;
643
+ data = value_3(formSpecForScores);
644
+ spec = value_3(formSpec);
645
+ }
646
+ else {
647
+ matchResult = 1;
648
+ }
649
+ }
650
+ else {
651
+ matchResult = 1;
652
+ }
653
+ switch (matchResult) {
654
+ case 0: {
655
+ const fieldScoreOpt: Option<int32> = bind<Spec_FormField$1<Spec_FieldType_$union>, int32>((field_1: Spec_FormField$1<Spec_FieldType_$union>): Option<int32> => bind<FieldDetails$1<Spec_FieldType_$union>, int32>((details: FieldDetails$1<Spec_FieldType_$union>): Option<int32> => ScoreCalculator_calculateFieldScore<Spec_FieldType_$union>(field_1, details.FieldValue), getFieldDetails(data!, fieldKey)), tryFind<Spec_FormField$1<Spec_FieldType_$union>>((field: Spec_FormField$1<Spec_FieldType_$union>): boolean => equals(field.FieldKey, fieldKey), collect<Spec_FormStep$1<Spec_FieldType_$union>, Spec_FormField$1<Spec_FieldType_$union>>((step: Spec_FormStep$1<Spec_FieldType_$union>): FSharpList<Spec_FormField$1<Spec_FieldType_$union>> => step.Fields, spec!.Steps)));
656
+ if (fieldScoreOpt == null) {
657
+ return TransitionStatus_Pending(singleton(fieldKey.fields[0]));
658
+ }
659
+ else if ((score = (value_3(fieldScoreOpt) | 0), (score >= minVal) && (score <= maxVal))) {
660
+ const score_1: int32 = value_3(fieldScoreOpt) | 0;
661
+ return TransitionStatus_Satisfied();
662
+ }
663
+ else {
664
+ return TransitionStatus_Failed();
665
+ }
666
+ }
667
+ default:
668
+ return TransitionStatus_Pending(singleton(fieldKey.fields[0]));
669
+ }
670
+ }
671
+ else {
672
+ const actualFieldValueOpt: Option<Shared_FieldValue_$union> = (conditionValue.tag === /* Matrix */ 2) ? ((formSpecForScores != null) ? ((data_1 = value_3(formSpecForScores), map_3<FieldDetails$1<Spec_FieldType_$union>, Shared_FieldValue_$union>((details_1: FieldDetails$1<Spec_FieldType_$union>): Shared_FieldValue_$union => details_1.FieldValue, getFieldDetails(data_1, fieldKey)))) : undefined) : undefined;
673
+ if (actualFieldValueOpt == null) {
674
+ const matchValue_2: Option<string> = tryFind_1<Shared_FieldKey, string>(fieldKey, fieldValues);
675
+ if (matchValue_2 == null) {
676
+ return TransitionStatus_Pending(singleton(fieldKey.fields[0]));
677
+ }
678
+ else if (evaluateFieldConditionWithConditionValue(Shared_FieldValue_Single(new Shared_FieldAnswer(fieldKey, "", value_3(matchValue_2))), evaluator, conditionValue)) {
679
+ return TransitionStatus_Satisfied();
680
+ }
681
+ else {
682
+ return TransitionStatus_Failed();
683
+ }
684
+ }
685
+ else if (evaluateFieldConditionWithConditionValue(value_3(actualFieldValueOpt), evaluator, conditionValue)) {
686
+ return TransitionStatus_Satisfied();
687
+ }
688
+ else {
689
+ return TransitionStatus_Failed();
690
+ }
691
+ }
692
+ }
693
+ case /* ScoreInRange */ 3: {
694
+ const minScore: int32 = condition.fields[0] | 0;
695
+ const maxScore: int32 = condition.fields[1] | 0;
696
+ if (formSpecForScores != null) {
697
+ const totalScore: int32 = ScoreCalculator_calculateTotalScore(value_3(formSpecForScores)) | 0;
698
+ if ((totalScore >= minScore) && (totalScore <= maxScore)) {
699
+ return TransitionStatus_Satisfied();
700
+ }
701
+ else {
702
+ return TransitionStatus_Failed();
703
+ }
704
+ }
705
+ else {
706
+ return TransitionStatus_Pending(singleton("form_score"));
707
+ }
708
+ }
709
+ case /* FieldScoreInRange */ 4: {
710
+ const minScore_1: int32 = condition.fields[1] | 0;
711
+ const maxScore_1: int32 = condition.fields[2] | 0;
712
+ const fieldKey_1: Shared_FieldKey = condition.fields[0];
713
+ if (formSpecForScores != null) {
714
+ const spec_2: Spec_FormSpec$1<Spec_FieldType_$union> = value_3(formSpecForScores);
715
+ const fieldScoreOpt_1: Option<int32> = bind<Spec_FormField$1<Spec_FieldType_$union>, int32>((field_3: Spec_FormField$1<Spec_FieldType_$union>): Option<int32> => bind<FieldDetails$1<Spec_FieldType_$union>, int32>((details_2: FieldDetails$1<Spec_FieldType_$union>): Option<int32> => ScoreCalculator_calculateFieldScore<Spec_FieldType_$union>(field_3, details_2.FieldValue), getFieldDetails(spec_2, fieldKey_1)), tryFind<Spec_FormField$1<Spec_FieldType_$union>>((field_2: Spec_FormField$1<Spec_FieldType_$union>): boolean => equals(field_2.FieldKey, fieldKey_1), collect<Spec_FormStep$1<Spec_FieldType_$union>, Spec_FormField$1<Spec_FieldType_$union>>((step_1: Spec_FormStep$1<Spec_FieldType_$union>): FSharpList<Spec_FormField$1<Spec_FieldType_$union>> => step_1.Fields, spec_2.Steps)));
716
+ if (fieldScoreOpt_1 == null) {
717
+ return TransitionStatus_Pending(singleton(fieldKey_1.fields[0]));
718
+ }
719
+ else if ((score_2 = (value_3(fieldScoreOpt_1) | 0), (score_2 >= minScore_1) && (score_2 <= maxScore_1))) {
720
+ const score_3: int32 = value_3(fieldScoreOpt_1) | 0;
721
+ return TransitionStatus_Satisfied();
722
+ }
723
+ else {
724
+ return TransitionStatus_Failed();
725
+ }
726
+ }
727
+ else {
728
+ return TransitionStatus_Pending(singleton(fieldKey_1.fields[0]));
729
+ }
730
+ }
731
+ case /* StateCondition */ 5: {
732
+ const evaluator_1: ClinicalPathway_StateEvaluator_$union = condition.fields[1];
733
+ const stateVisited: boolean = contains<Shared_StateKey>(condition.fields[0], visitedStates);
734
+ switch (evaluator_1.tag) {
735
+ case /* HasValue */ 1:
736
+ if (stateVisited) {
737
+ return TransitionStatus_Satisfied();
738
+ }
739
+ else {
740
+ return TransitionStatus_Failed();
741
+ }
742
+ case /* HasError */ 2:
743
+ return TransitionStatus_Failed();
744
+ case /* WasSkipped */ 3:
745
+ if (!stateVisited) {
746
+ return TransitionStatus_Satisfied();
747
+ }
748
+ else {
749
+ return TransitionStatus_Failed();
750
+ }
751
+ default:
752
+ if (stateVisited) {
753
+ return TransitionStatus_Satisfied();
754
+ }
755
+ else {
756
+ return TransitionStatus_Failed();
757
+ }
758
+ }
759
+ }
760
+ case /* CompositeCondition */ 6: {
761
+ const logicalOp: ClinicalPathway_LogicalOp_$union = condition.fields[0];
762
+ const conditions: FSharpList<ClinicalPathway_TransitionCondition_$union> = condition.fields[1];
763
+ switch (logicalOp.tag) {
764
+ case /* Or */ 1: {
765
+ const results_1: FSharpList<TransitionStatus_$union> = map<ClinicalPathway_TransitionCondition_$union, TransitionStatus_$union>((condition_2: ClinicalPathway_TransitionCondition_$union): TransitionStatus_$union => evaluateTransitionWithPartialData(resolver, formSpec, fieldValues, visitedStates, formSpecForScores, condition_2), conditions);
766
+ if (exists<TransitionStatus_$union>((r_3: TransitionStatus_$union): boolean => equals(r_3, TransitionStatus_Satisfied()), results_1)) {
767
+ return TransitionStatus_Satisfied();
768
+ }
769
+ else if (forAll<TransitionStatus_$union>((r_4: TransitionStatus_$union): boolean => equals(r_4, TransitionStatus_Failed()), results_1)) {
770
+ return TransitionStatus_Failed();
771
+ }
772
+ else {
773
+ return TransitionStatus_Pending(concat<string>(choose<TransitionStatus_$union, FSharpList<string>>((r_5: TransitionStatus_$union): Option<FSharpList<string>> => {
774
+ if (r_5.tag === /* Pending */ 2) {
775
+ return r_5.fields[0];
776
+ }
777
+ else {
778
+ return undefined;
779
+ }
780
+ }, results_1)));
781
+ }
782
+ }
783
+ case /* Not */ 2: {
784
+ let matchResult_1: int32, cond: ClinicalPathway_TransitionCondition_$union;
785
+ if (!isEmpty(conditions)) {
786
+ if (isEmpty(tail(conditions))) {
787
+ matchResult_1 = 0;
788
+ cond = head(conditions);
789
+ }
790
+ else {
791
+ matchResult_1 = 1;
792
+ }
793
+ }
794
+ else {
795
+ matchResult_1 = 1;
796
+ }
797
+ switch (matchResult_1) {
798
+ case 0: {
799
+ const matchValue_3: TransitionStatus_$union = evaluateTransitionWithPartialData(resolver, formSpec, fieldValues, visitedStates, formSpecForScores, cond!);
800
+ switch (matchValue_3.tag) {
801
+ case /* Failed */ 1:
802
+ return TransitionStatus_Satisfied();
803
+ case /* Pending */ 2:
804
+ return TransitionStatus_Pending(matchValue_3.fields[0]);
805
+ default:
806
+ return TransitionStatus_Failed();
807
+ }
808
+ }
809
+ default:
810
+ return TransitionStatus_Failed();
811
+ }
812
+ }
813
+ default: {
814
+ const results: FSharpList<TransitionStatus_$union> = map<ClinicalPathway_TransitionCondition_$union, TransitionStatus_$union>((condition_1: ClinicalPathway_TransitionCondition_$union): TransitionStatus_$union => evaluateTransitionWithPartialData(resolver, formSpec, fieldValues, visitedStates, formSpecForScores, condition_1), conditions);
815
+ if (exists<TransitionStatus_$union>((r: TransitionStatus_$union): boolean => equals(r, TransitionStatus_Failed()), results)) {
816
+ return TransitionStatus_Failed();
817
+ }
818
+ else if (forAll<TransitionStatus_$union>((r_1: TransitionStatus_$union): boolean => equals(r_1, TransitionStatus_Satisfied()), results)) {
819
+ return TransitionStatus_Satisfied();
820
+ }
821
+ else {
822
+ return TransitionStatus_Pending(concat<string>(choose<TransitionStatus_$union, FSharpList<string>>((r_2: TransitionStatus_$union): Option<FSharpList<string>> => {
823
+ if (r_2.tag === /* Pending */ 2) {
824
+ return r_2.fields[0];
825
+ }
826
+ else {
827
+ return undefined;
828
+ }
829
+ }, results)));
830
+ }
831
+ }
832
+ }
833
+ }
834
+ case /* TestResultCondition */ 7: {
835
+ const result: string = condition.fields[1];
836
+ return TransitionStatus_Pending(singleton(condition.fields[0]));
837
+ }
838
+ case /* FieldOptionCondition */ 1: {
839
+ const optionKey: Shared_FieldOptionKey = condition.fields[2];
840
+ const matrixItemKey: Option<Shared_MatrixItemKey> = condition.fields[1];
841
+ const fieldKey_2: Shared_FieldKey = condition.fields[0];
842
+ const evaluator_2: ClinicalPathway_FieldEvaluator_$union = condition.fields[3];
843
+ const conditionValue_1: Shared_ConditionValue_$union = condition.fields[4];
844
+ const optionValueOpt: Option<string> = (formSpec == null) ? undefined : bind<Spec_FormField$1<Spec_FieldType_$union>, string>((field_5: Spec_FormField$1<Spec_FieldType_$union>): Option<string> => {
845
+ const fieldType = field_5.FieldType as Spec_FieldType_$union;
846
+ return map_3<Shared_FieldOption, string>((opt_1: Shared_FieldOption): string => opt_1.Value, tryFind<Shared_FieldOption>((opt: Shared_FieldOption): boolean => equals(opt.OptionKey, optionKey), (fieldType.tag === /* SingleChoice */ 13) ? fieldType.fields[0].Options : ((fieldType.tag === /* Radio */ 12) ? fieldType.fields[0].Options : ((fieldType.tag === /* Dropdown */ 14) ? fieldType.fields[0].Options : ((fieldType.tag === /* MultiChoice */ 15) ? fieldType.fields[0].Options : ((fieldType.tag === /* CheckboxList */ 16) ? fieldType.fields[0].Options : empty<Shared_FieldOption>()))))));
847
+ }, tryFind<Spec_FormField$1<Spec_FieldType_$union>>((field_4: Spec_FormField$1<Spec_FieldType_$union>): boolean => equals(field_4.FieldKey, fieldKey_2), collect<Spec_FormStep$1<Spec_FieldType_$union>, Spec_FormField$1<Spec_FieldType_$union>>((step_2: Spec_FormStep$1<Spec_FieldType_$union>): FSharpList<Spec_FormField$1<Spec_FieldType_$union>> => step_2.Fields, value_3(formSpec).Steps)));
848
+ const matchValue_4: Option<string> = tryFind_1<Shared_FieldKey, string>(fieldKey_2, fieldValues);
849
+ if (optionValueOpt == null) {
850
+ return TransitionStatus_Failed();
851
+ }
852
+ else if (matchValue_4 == null) {
853
+ return TransitionStatus_Pending(singleton(fieldKey_2.fields[0]));
854
+ }
855
+ else {
856
+ const actualValueStr_1: string = value_3(matchValue_4);
857
+ const optionValue: string = value_3(optionValueOpt);
858
+ const actualValues: FSharpSet<string> = ofArray<string>(map_2<string, string>((s: string): string => s.trim().toLocaleLowerCase(), actualValueStr_1.split(",")), {
859
+ Compare: comparePrimitives,
860
+ });
861
+ const containsOption: boolean = contains<string>(optionValue.trim().toLocaleLowerCase(), actualValues);
862
+ switch (evaluator_2.tag) {
863
+ case /* Equals */ 0:
864
+ if (containsOption) {
865
+ return TransitionStatus_Satisfied();
866
+ }
867
+ else {
868
+ return TransitionStatus_Failed();
869
+ }
870
+ case /* NotEquals */ 1:
871
+ if (!containsOption) {
872
+ return TransitionStatus_Satisfied();
873
+ }
874
+ else {
875
+ return TransitionStatus_Failed();
876
+ }
877
+ case /* IsPresent */ 10:
878
+ if (containsOption) {
879
+ return TransitionStatus_Satisfied();
880
+ }
881
+ else {
882
+ return TransitionStatus_Failed();
883
+ }
884
+ case /* IsAbsent */ 11:
885
+ if (!containsOption) {
886
+ return TransitionStatus_Satisfied();
887
+ }
888
+ else {
889
+ return TransitionStatus_Failed();
890
+ }
891
+ default:
892
+ if (evaluateFieldCondition(actualValueStr_1, evaluator_2, (conditionValue_1.tag === /* Multiple */ 1) ? join(",", toList<string>(conditionValue_1.fields[0])) : ((conditionValue_1.tag === /* Matrix */ 2) ? join(",", map<[Shared_MatrixItemKey, string], string>((tupledArg: [Shared_MatrixItemKey, string]): string => tupledArg[1], toList_1<Shared_MatrixItemKey, string>(conditionValue_1.fields[0]))) : ((conditionValue_1.tag === /* PluginData */ 3) ? ((pluginData = conditionValue_1.fields[0], toString(0, Auto_generateBoxedEncoder_437914C6(Shared_PluginDataProperty_$reflection(), undefined, undefined, undefined)(pluginData)))) : conditionValue_1.fields[0])))) {
893
+ return TransitionStatus_Satisfied();
894
+ }
895
+ else {
896
+ return TransitionStatus_Failed();
897
+ }
898
+ }
899
+ }
900
+ }
901
+ case /* PluginPropertyCondition */ 2: {
902
+ const propertyKey: Shared_PluginPropertyKey = condition.fields[1];
903
+ const fieldKey_3: Shared_FieldKey = condition.fields[0];
904
+ const evaluator_3: ClinicalPathway_FieldEvaluator_$union = condition.fields[2];
905
+ const conditionValue_2: Shared_ConditionValue_$union = condition.fields[3];
906
+ const matchValue_6: Option<string> = tryFind_1<Shared_FieldKey, string>(fieldKey_3, fieldValues);
907
+ if (matchValue_6 == null) {
908
+ return TransitionStatus_Pending(singleton(fieldKey_3.fields[0]));
909
+ }
910
+ else {
911
+ const actualValueStr_2: string = value_3(matchValue_6);
912
+ try {
913
+ const pluginIdOpt: Option<string> = filter<string>((id: string): boolean => !isNullOrEmpty(id), bind<Spec_FormSpec$1<Spec_FieldType_$union>, string>((spec_4: Spec_FormSpec$1<Spec_FieldType_$union>): Option<string> => map_3<Spec_FormField$1<Spec_FieldType_$union>, string>((f_1: Spec_FormField$1<Spec_FieldType_$union>): string => {
914
+ const ft = f_1.FieldType as Spec_FieldType_$union;
915
+ switch (ft.tag) {
916
+ case /* PluginField */ 22:
917
+ return ft.fields[0].PluginId;
918
+ case /* Matrix */ 19:
919
+ return "Fable.Form.Simple.Bulma.Fields.LikertField";
920
+ default:
921
+ return "";
922
+ }
923
+ }, tryFind<Spec_FormField$1<Spec_FieldType_$union>>((f: Spec_FormField$1<Spec_FieldType_$union>): boolean => equals(f.FieldKey, fieldKey_3), collect<Spec_FormStep$1<Spec_FieldType_$union>, Spec_FormField$1<Spec_FieldType_$union>>((s_1: Spec_FormStep$1<Spec_FieldType_$union>): FSharpList<Spec_FormField$1<Spec_FieldType_$union>> => s_1.Fields, spec_4.Steps))), formSpec));
924
+ return evaluateFieldCondition((pluginIdOpt == null) ? actualValueStr_2 : defaultArg(bind<IPluginValueConverter, string>((converter: IPluginValueConverter): Option<string> => map_3<Shared_PluginDataProperty, string>((propMeta: Shared_PluginDataProperty): string => {
925
+ if (propMeta.Name === "TotalScore") {
926
+ return int32ToString(sum_1<int32>(choose_1<string, int32>((s_2: string): Option<int32> => {
927
+ let matchValue_7: [boolean, int32];
928
+ let outArg = 0;
929
+ matchValue_7 = ([tryParse_1(s_2.trim(), 511, false, 32, new FSharpRef<int32>((): int32 => outArg, (v_2: int32): void => {
930
+ outArg = (v_2 | 0);
931
+ })), outArg] as [boolean, int32]);
932
+ if (matchValue_7[0]) {
933
+ return matchValue_7[1];
934
+ }
935
+ else {
936
+ return undefined;
937
+ }
938
+ }, actualValueStr_2.split(",")), {
939
+ GetZero: (): int32 => 0,
940
+ Add: (x_1: int32, y_1: int32): int32 => (x_1 + y_1),
941
+ }));
942
+ }
943
+ else {
944
+ const matchValue_8: FSharpResult$2_$union<FSharpList<Shared_PluginDataProperty>, string> = fromString<FSharpList<Shared_PluginDataProperty>>(uncurry2(Auto_generateBoxedDecoder_Z6670B51(list_type(Shared_PluginDataProperty_$reflection()), undefined, undefined)), actualValueStr_2);
945
+ if (matchValue_8.tag === /* Error */ 1) {
946
+ return actualValueStr_2;
947
+ }
948
+ else {
949
+ return defaultArg(map_3<Shared_PluginDataProperty, string>((p_1: Shared_PluginDataProperty): string => p_1.Value, tryFind<Shared_PluginDataProperty>((p: Shared_PluginDataProperty): boolean => equals(p.PropertyKey, propertyKey), matchValue_8.fields[0])), actualValueStr_2);
950
+ }
951
+ }
952
+ }, converter.GetPropertyMetadataByKey(propertyKey)), PluginValueRegistry_tryGet(value_3(pluginIdOpt))), actualValueStr_2), evaluator_3, (conditionValue_2.tag === /* Multiple */ 1) ? join(",", toList<string>(conditionValue_2.fields[0])) : ((conditionValue_2.tag === /* Matrix */ 2) ? join(",", map<[Shared_MatrixItemKey, string], string>((tupledArg_1: [Shared_MatrixItemKey, string]): string => tupledArg_1[1], toList_1<Shared_MatrixItemKey, string>(conditionValue_2.fields[0]))) : ((conditionValue_2.tag === /* PluginData */ 3) ? "" : conditionValue_2.fields[0]))) ? TransitionStatus_Satisfied() : TransitionStatus_Failed();
953
+ }
954
+ catch (ex: any) {
955
+ return TransitionStatus_Failed();
956
+ }
957
+ }
958
+ }
959
+ default:
960
+ return TransitionStatus_Satisfied();
961
+ }
962
+ }
963
+
964
+ /**
965
+ * Find a state by key
966
+ */
967
+ export function findState(stateKey: Shared_StateKey, states: FSharpList<ClinicalPathway_StateDefinition>): Option<ClinicalPathway_StateDefinition> {
968
+ return tryFind<ClinicalPathway_StateDefinition>((s: ClinicalPathway_StateDefinition): boolean => equals(s.StateKey, stateKey), states);
969
+ }
970
+
971
+ /**
972
+ * Extract actions from state
973
+ */
974
+ export function extractActionsFromState(state: ClinicalPathway_StateDefinition): FSharpList<ClinicalPathway_ActionInfo_$union> {
975
+ const matchValue: ClinicalPathway_StateType_$union = state.StateType;
976
+ switch (matchValue.tag) {
977
+ case /* Action */ 2:
978
+ return singleton(matchValue.fields[0]);
979
+ case /* CompoundAction */ 3:
980
+ return matchValue.fields[0];
981
+ case /* ConditionalAction */ 4: {
982
+ const condition: ClinicalPathway_TransitionCondition_$union = matchValue.fields[0];
983
+ return append(singleton(matchValue.fields[1]), ofArray_1(toArray<ClinicalPathway_ActionInfo_$union>(matchValue.fields[2])));
984
+ }
985
+ default:
986
+ return empty<ClinicalPathway_ActionInfo_$union>();
987
+ }
988
+ }
989
+
990
+ /**
991
+ * Check if a state is terminal
992
+ */
993
+ export function isTerminalState(state: ClinicalPathway_StateDefinition): boolean {
994
+ if (state.StateType.tag === /* Terminal */ 5) {
995
+ return true;
996
+ }
997
+ else {
998
+ return false;
999
+ }
1000
+ }
1001
+
1002
+ /**
1003
+ * Evaluate all transitions from current states
1004
+ */
1005
+ export function evaluateAllTransitions<FieldType>(context: ExecutionContext): FSharpList<MatchedTransition> {
1006
+ const fieldValues: FSharpMap<Shared_FieldKey, string> = FieldResolver_extractFieldValues(context.FieldResolver, context.FormSpec);
1007
+ return map<ClinicalPathway_TransitionDefinition, MatchedTransition>((transition: ClinicalPathway_TransitionDefinition): MatchedTransition => {
1008
+ const status: TransitionStatus_$union = evaluateTransitionWithPartialData(context.FieldResolver, context.FormSpec, fieldValues, context.VisitedStates, context.FormSpec, transition.Condition);
1009
+ return new MatchedTransition(transition, defaultArg(transition.Priority, 999), status);
1010
+ }, filter_1<ClinicalPathway_TransitionDefinition>((t: ClinicalPathway_TransitionDefinition): boolean => contains<Shared_StateKey>(t.FromState, context.CurrentStates), context.PathwaySpec.Transitions));
1011
+ }
1012
+
1013
+ /**
1014
+ * Separate matched transitions into active, pending, and failed
1015
+ */
1016
+ export function categorizeTransitions(transitions: FSharpList<MatchedTransition>): [FSharpList<MatchedTransition>, FSharpList<MatchedTransition>, FSharpList<MatchedTransition>] {
1017
+ return [filter_1<MatchedTransition>((t: MatchedTransition): boolean => equals(t.Status, TransitionStatus_Satisfied()), transitions), filter_1<MatchedTransition>((t_1: MatchedTransition): boolean => {
1018
+ if (t_1.Status.tag === /* Pending */ 2) {
1019
+ return true;
1020
+ }
1021
+ else {
1022
+ return false;
1023
+ }
1024
+ }, transitions), filter_1<MatchedTransition>((t_2: MatchedTransition): boolean => equals(t_2.Status, TransitionStatus_Failed()), transitions)] as [FSharpList<MatchedTransition>, FSharpList<MatchedTransition>, FSharpList<MatchedTransition>];
1025
+ }
1026
+
1027
+ /**
1028
+ * Apply execution mode strategy to select transitions
1029
+ */
1030
+ export function selectTransitionsByMode(mode: ClinicalPathway_PathwayExecutionMode_$union, activeTransitions: FSharpList<MatchedTransition>): FSharpList<MatchedTransition> {
1031
+ switch (mode.tag) {
1032
+ case /* MultiPathway */ 1: {
1033
+ const matchValue_1: ClinicalPathway_CombinationStrategy_$union = mode.fields[0].CombinationStrategy;
1034
+ switch (matchValue_1.tag) {
1035
+ case /* NonConflicting */ 1:
1036
+ return activeTransitions;
1037
+ case /* Complementary */ 2:
1038
+ return activeTransitions;
1039
+ default:
1040
+ return activeTransitions;
1041
+ }
1042
+ }
1043
+ case /* TriggerBased */ 2:
1044
+ return activeTransitions;
1045
+ default: {
1046
+ const matchValue: ClinicalPathway_SelectionStrategy_$union = mode.fields[0].SelectionStrategy;
1047
+ switch (matchValue.tag) {
1048
+ case /* MostSpecific */ 1:
1049
+ return ofArray_1(toArray<MatchedTransition>(tryHead<MatchedTransition>(sortBy<MatchedTransition, int32>((m_1: MatchedTransition): int32 => m_1.Priority, activeTransitions, {
1050
+ Compare: comparePrimitives,
1051
+ }))));
1052
+ case /* ClinicalSeverity */ 2:
1053
+ return ofArray_1(toArray<MatchedTransition>(tryHead<MatchedTransition>(sortBy<MatchedTransition, int32>((m_2: MatchedTransition): int32 => m_2.Priority, activeTransitions, {
1054
+ Compare: comparePrimitives,
1055
+ }))));
1056
+ default:
1057
+ return ofArray_1(toArray<MatchedTransition>(tryHead<MatchedTransition>(sortBy<MatchedTransition, int32>((m: MatchedTransition): int32 => m.Priority, activeTransitions, {
1058
+ Compare: comparePrimitives,
1059
+ }))));
1060
+ }
1061
+ }
1062
+ }
1063
+ }
1064
+
1065
+ /**
1066
+ * Calculate probability based on satisfied conditions and pending fields
1067
+ */
1068
+ export function calculateProbability(status: TransitionStatus_$union, totalConditions: int32): float64 {
1069
+ switch (status.tag) {
1070
+ case /* Failed */ 1:
1071
+ return 0;
1072
+ case /* Pending */ 2:
1073
+ return (totalConditions - length(status.fields[0])) / totalConditions;
1074
+ default:
1075
+ return 1;
1076
+ }
1077
+ }
1078
+
1079
+ /**
1080
+ * Predict possible outcomes based on current form state
1081
+ */
1082
+ export function predictOutcomes(context: ExecutionContext): FSharpList<PredictedPathway> {
1083
+ return truncate<PredictedPathway>(5, sortByDescending<PredictedPathway, float64>((p: PredictedPathway): float64 => p.Probability, choose<MatchedTransition, PredictedPathway>((matched: MatchedTransition): Option<PredictedPathway> => {
1084
+ const matchValue: TransitionStatus_$union = matched.Status;
1085
+ switch (matchValue.tag) {
1086
+ case /* Pending */ 2: {
1087
+ const fields: FSharpList<string> = matchValue.fields[0];
1088
+ const matchValue_2: Option<ClinicalPathway_StateDefinition> = findState(matched.Transition.ToState, context.PathwaySpec.States);
1089
+ if (matchValue_2 == null) {
1090
+ return undefined;
1091
+ }
1092
+ else {
1093
+ const toStateStr_1: string = matched.Transition.ToState.fields[0];
1094
+ return new PredictedPathway(toStateStr_1, 0.5, fields, extractActionsFromState(value_3(matchValue_2)), toStateStr_1);
1095
+ }
1096
+ }
1097
+ case /* Failed */ 1:
1098
+ return undefined;
1099
+ default: {
1100
+ const matchValue_1: Option<ClinicalPathway_StateDefinition> = findState(matched.Transition.ToState, context.PathwaySpec.States);
1101
+ if (matchValue_1 == null) {
1102
+ return undefined;
1103
+ }
1104
+ else {
1105
+ const toStateStr: string = matched.Transition.ToState.fields[0];
1106
+ return new PredictedPathway(toStateStr, 1, empty<string>(), extractActionsFromState(value_3(matchValue_1)), toStateStr);
1107
+ }
1108
+ }
1109
+ }
1110
+ }, evaluateAllTransitions<any>(context)), {
1111
+ Compare: comparePrimitives,
1112
+ }));
1113
+ }
1114
+
1115
+ /**
1116
+ * Calculate completion percentage based on states visited and actions executed
1117
+ */
1118
+ export function calculateCompletionPercentage(context: ExecutionContext): float64 {
1119
+ const totalStates: float64 = length(context.PathwaySpec.States);
1120
+ if (totalStates === 0) {
1121
+ return 0;
1122
+ }
1123
+ else {
1124
+ return (FSharpSet__get_Count(context.VisitedStates) / totalStates) * 100;
1125
+ }
1126
+ }
1127
+
1128
+ /**
1129
+ * Check if pathway execution is complete
1130
+ */
1131
+ export function isExecutionComplete(context: ExecutionContext): boolean {
1132
+ if (exists<ClinicalPathway_StateDefinition>(isTerminalState, choose<Shared_StateKey, ClinicalPathway_StateDefinition>((sk: Shared_StateKey): Option<ClinicalPathway_StateDefinition> => findState(sk, context.PathwaySpec.States), toList<Shared_StateKey>(context.CurrentStates)))) {
1133
+ return true;
1134
+ }
1135
+ else if (isEmpty(categorizeTransitions(context.ActiveTransitions)[0])) {
1136
+ return !FSharpSet__get_IsEmpty(context.CurrentStates);
1137
+ }
1138
+ else {
1139
+ return false;
1140
+ }
1141
+ }
1142
+
1143
+ /**
1144
+ * Initialize execution context from scratch
1145
+ */
1146
+ export function initializeExecution(formSpec: Spec_FormSpec$1<Spec_FieldType_$union>): ExecutionContext {
1147
+ const matchValue: Option<ClinicalPathway_ClinicalPathwaySpec> = formSpec.ClinicalPathway;
1148
+ if (matchValue == null) {
1149
+ throw new Error("No clinical pathway found in form spec");
1150
+ }
1151
+ else {
1152
+ const pathway: ClinicalPathway_ClinicalPathwaySpec = value_3(matchValue);
1153
+ const resolver: ((arg0: string) => Shared_FieldKey) = FieldResolver_createResolver(formSpec);
1154
+ let initialStates: FSharpList<Shared_StateKey>;
1155
+ const matchValue_1: Option<Shared_StateKey> = pathway.InitialState;
1156
+ if (matchValue_1 == null) {
1157
+ const statesWithIncoming: FSharpSet<Shared_StateKey> = ofList_1<Shared_StateKey>(map<ClinicalPathway_TransitionDefinition, Shared_StateKey>((t: ClinicalPathway_TransitionDefinition): Shared_StateKey => t.ToState, pathway.Transitions), {
1158
+ Compare: compare,
1159
+ });
1160
+ const candidates: FSharpList<Shared_StateKey> = map<ClinicalPathway_StateDefinition, Shared_StateKey>((s_1: ClinicalPathway_StateDefinition): Shared_StateKey => s_1.StateKey, filter_1<ClinicalPathway_StateDefinition>((s: ClinicalPathway_StateDefinition): boolean => !contains<Shared_StateKey>(s.StateKey, statesWithIncoming), pathway.States));
1161
+ initialStates = (isEmpty(candidates) ? defaultArg(map_3<ClinicalPathway_StateDefinition, FSharpList<Shared_StateKey>>((s_2: ClinicalPathway_StateDefinition): FSharpList<Shared_StateKey> => singleton(s_2.StateKey), tryHead<ClinicalPathway_StateDefinition>(pathway.States)), empty<Shared_StateKey>()) : candidates);
1162
+ }
1163
+ else {
1164
+ initialStates = singleton(value_3(matchValue_1));
1165
+ }
1166
+ return new ExecutionContext(pathway, formSpec, ofList_1<Shared_StateKey>(initialStates, {
1167
+ Compare: compare,
1168
+ }), ofList_1<Shared_StateKey>(initialStates, {
1169
+ Compare: compare,
1170
+ }), empty_1<Shared_StateKey>({
1171
+ Compare: compare,
1172
+ }), empty<MatchedTransition>(), empty<MatchedTransition>(), empty<ClinicalPathway_ActionInfo_$union>(), resolver, map<Shared_StateKey, ExecutionLogEntry>((stateKey: Shared_StateKey): ExecutionLogEntry => (new ExecutionLogEntry(now(), stateKey, "Initialized", "Starting state")), initialStates));
1173
+ }
1174
+ }
1175
+
1176
+ /**
1177
+ * Resolve field value source to actual string value
1178
+ */
1179
+ export function resolveFieldValueSource(valueSource: ClinicalPathway_FieldValueSource_$union, formSpec: Spec_FormSpec$1<Spec_FieldType_$union>): string {
1180
+ switch (valueSource.tag) {
1181
+ case /* FieldReference */ 1:
1182
+ return defaultArg(tryFind_1<Shared_FieldKey, string>(valueSource.fields[0], FieldResolver_extractFieldValues(FieldResolver_createResolver(formSpec), formSpec)), "");
1183
+ case /* OptionKey */ 2: {
1184
+ const optionKey: Shared_FieldOptionKey = valueSource.fields[0];
1185
+ return defaultArg(tryPick<Spec_FormField$1<Spec_FieldType_$union>, string>((field: Spec_FormField$1<Spec_FieldType_$union>): Option<string> => {
1186
+ const fieldType = field.FieldType as Spec_FieldType_$union;
1187
+ return map_3<Shared_FieldOption, string>((opt_1: Shared_FieldOption): string => opt_1.Description, tryFind<Shared_FieldOption>((opt: Shared_FieldOption): boolean => equals(opt.OptionKey, optionKey), (fieldType.tag === /* SingleChoice */ 13) ? fieldType.fields[0].Options : ((fieldType.tag === /* MultiChoice */ 15) ? fieldType.fields[0].Options : ((fieldType.tag === /* CheckboxList */ 16) ? fieldType.fields[0].Options : ((fieldType.tag === /* Dropdown */ 14) ? fieldType.fields[0].Options : ((fieldType.tag === /* Radio */ 12) ? fieldType.fields[0].Options : empty<Shared_FieldOption>()))))));
1188
+ }, collect<Spec_FormStep$1<Spec_FieldType_$union>, Spec_FormField$1<Spec_FieldType_$union>>((step: Spec_FormStep$1<Spec_FieldType_$union>): FSharpList<Spec_FormField$1<Spec_FieldType_$union>> => step.Fields, formSpec.Steps)), "");
1189
+ }
1190
+ default:
1191
+ return valueSource.fields[0];
1192
+ }
1193
+ }
1194
+
1195
+ /**
1196
+ * Execute SetFieldValue action and update form spec
1197
+ */
1198
+ export function executeSetFieldValueAction(action: ClinicalPathway_SetFieldValueAction, formSpec: Spec_FormSpec$1<Spec_FieldType_$union>): Spec_FormSpec$1<Spec_FieldType_$union> {
1199
+ let matchValue: Option<ClinicalPathway_TransitionCondition_$union>, condition: ClinicalPathway_TransitionCondition_$union, fieldValues: FSharpMap<Shared_FieldKey, string>;
1200
+ if (!((matchValue = action.Condition, (matchValue == null) ? true : ((condition = value_3(matchValue), (fieldValues = FieldResolver_extractFieldValues(FieldResolver_createResolver(formSpec), formSpec), evaluateTransitionWithPartialData(FieldResolver_createResolver(formSpec), formSpec, fieldValues, empty_1<Shared_StateKey>({
1201
+ Compare: compare,
1202
+ }), formSpec, condition).tag === /* Satisfied */ 0)))))) {
1203
+ return formSpec;
1204
+ }
1205
+ else {
1206
+ const valueToSet: string = resolveFieldValueSource(action.Value, formSpec);
1207
+ const targetFieldOpt: Option<Spec_FormField$1<Spec_FieldType_$union>> = tryFind<Spec_FormField$1<Spec_FieldType_$union>>((field: Spec_FormField$1<Spec_FieldType_$union>): boolean => equals(field.FieldKey, action.TargetField), collect<Spec_FormStep$1<Spec_FieldType_$union>, Spec_FormField$1<Spec_FieldType_$union>>((step: Spec_FormStep$1<Spec_FieldType_$union>): FSharpList<Spec_FormField$1<Spec_FieldType_$union>> => step.Fields, formSpec.Steps));
1208
+ if (targetFieldOpt == null) {
1209
+ return formSpec;
1210
+ }
1211
+ else {
1212
+ const targetField: Spec_FormField$1<Spec_FieldType_$union> = value_3(targetFieldOpt);
1213
+ const stepOpt: Option<Spec_FormStep$1<Spec_FieldType_$union>> = tryFind<Spec_FormStep$1<Spec_FieldType_$union>>((step_1: Spec_FormStep$1<Spec_FieldType_$union>): boolean => exists<Spec_FormField$1<Spec_FieldType_$union>>((f: Spec_FormField$1<Spec_FieldType_$union>): boolean => equals(f.FieldKey, action.TargetField), step_1.Fields), formSpec.Steps);
1214
+ if (stepOpt == null) {
1215
+ return formSpec;
1216
+ }
1217
+ else {
1218
+ const step_2: Spec_FormStep$1<Spec_FieldType_$union> = value_3(stepOpt);
1219
+ return updateField<Spec_FieldType_$union>(formSpec, action.TargetField, Shared_FieldValue_Single(new Shared_FieldAnswer(action.TargetField, targetField.Label, valueToSet)), findIndex<Spec_FormStep$1<Spec_FieldType_$union>>((s: Spec_FormStep$1<Spec_FieldType_$union>): boolean => (s.StepOrder === step_2.StepOrder), formSpec.Steps));
1220
+ }
1221
+ }
1222
+ }
1223
+ }
1224
+
1225
+ /**
1226
+ * Execute an action and return updated form spec
1227
+ */
1228
+ export function executeAction(action: ClinicalPathway_ActionInfo_$union, formSpec: Spec_FormSpec$1<Spec_FieldType_$union>): Spec_FormSpec$1<Spec_FieldType_$union> {
1229
+ if (action.tag === /* SetFieldValue */ 10) {
1230
+ return executeSetFieldValueAction(action.fields[0], formSpec);
1231
+ }
1232
+ else {
1233
+ return formSpec;
1234
+ }
1235
+ }
1236
+
1237
+ /**
1238
+ * Execute all actions from a list and return updated form spec
1239
+ */
1240
+ export function executeActions(actions: FSharpList<ClinicalPathway_ActionInfo_$union>, formSpec: Spec_FormSpec$1<Spec_FieldType_$union>): Spec_FormSpec$1<Spec_FieldType_$union> {
1241
+ return fold<ClinicalPathway_ActionInfo_$union, Spec_FormSpec$1<Spec_FieldType_$union>>((currentSpec: Spec_FormSpec$1<Spec_FieldType_$union>, action: ClinicalPathway_ActionInfo_$union): Spec_FormSpec$1<Spec_FieldType_$union> => executeAction(action, currentSpec), formSpec, actions);
1242
+ }
1243
+
1244
+ /**
1245
+ * Execute one step of the pathway (incremental execution)
1246
+ */
1247
+ export function executeStep(context_mut: ExecutionContext, maxIterations_mut: int32): ExecutionContext {
1248
+ executeStep:
1249
+ while (true) {
1250
+ const context: ExecutionContext = context_mut, maxIterations: int32 = maxIterations_mut;
1251
+ if (maxIterations <= 0) {
1252
+ return context;
1253
+ }
1254
+ else {
1255
+ const patternInput: [FSharpList<MatchedTransition>, FSharpList<MatchedTransition>, FSharpList<MatchedTransition>] = categorizeTransitions(evaluateAllTransitions<any>(context));
1256
+ const pending: FSharpList<MatchedTransition> = patternInput[1];
1257
+ const active: FSharpList<MatchedTransition> = patternInput[0];
1258
+ const selectedTransitions: FSharpList<MatchedTransition> = selectTransitionsByMode(context.PathwaySpec.ExecutionMode, active);
1259
+ if (isEmpty(selectedTransitions)) {
1260
+ return new ExecutionContext(context.PathwaySpec, context.FormSpec, context.CurrentStates, context.VisitedStates, context.CompletedStates, active, pending, context.ExecutedActions, context.FieldResolver, context.ExecutionLog);
1261
+ }
1262
+ else {
1263
+ const newStates: FSharpSet<Shared_StateKey> = ofList_1<Shared_StateKey>(map<MatchedTransition, Shared_StateKey>((t: MatchedTransition): Shared_StateKey => t.Transition.ToState, selectedTransitions), {
1264
+ Compare: compare,
1265
+ });
1266
+ const newActions: FSharpList<ClinicalPathway_ActionInfo_$union> = collect<ClinicalPathway_StateDefinition, ClinicalPathway_ActionInfo_$union>(extractActionsFromState, choose<Shared_StateKey, ClinicalPathway_StateDefinition>((sk: Shared_StateKey): Option<ClinicalPathway_StateDefinition> => findState(sk, context.PathwaySpec.States), toList<Shared_StateKey>(newStates)));
1267
+ const updatedFormSpec: Spec_FormSpec$1<Spec_FieldType_$union> = executeActions(newActions, context.FormSpec);
1268
+ const newLogEntries: FSharpList<ExecutionLogEntry> = map<MatchedTransition, ExecutionLogEntry>((t_1: MatchedTransition): ExecutionLogEntry => {
1269
+ let arg: string, arg_1: string;
1270
+ return new ExecutionLogEntry(now(), t_1.Transition.ToState, "Transitioned", (arg = t_1.Transition.FromState.fields[0], (arg_1 = t_1.Transition.TransitionKey.fields[0], toText(printf("From %s via %s"))(arg)(arg_1))));
1271
+ }, selectedTransitions);
1272
+ const updatedContext: ExecutionContext = new ExecutionContext(context.PathwaySpec, updatedFormSpec, newStates, union<Shared_StateKey>(context.VisitedStates, newStates), union<Shared_StateKey>(context.CompletedStates, context.CurrentStates), active, pending, append(context.ExecutedActions, newActions), context.FieldResolver, append(context.ExecutionLog, newLogEntries));
1273
+ if (isExecutionComplete(updatedContext)) {
1274
+ return updatedContext;
1275
+ }
1276
+ else {
1277
+ context_mut = updatedContext;
1278
+ maxIterations_mut = (maxIterations - 1);
1279
+ continue executeStep;
1280
+ }
1281
+ }
1282
+ }
1283
+ break;
1284
+ }
1285
+ }
1286
+
1287
+ /**
1288
+ * Process incremental updates as form fills
1289
+ */
1290
+ export function executeIncremental(context: ExecutionContext, formSpec: Spec_FormSpec$1<Spec_FieldType_$union>): IncrementalExecutionResult {
1291
+ let previousTransitionKeys: FSharpSet<Shared_TransitionKey>, newKeys: FSharpSet<Shared_TransitionKey>;
1292
+ const startingAtTerminal: boolean = exists<ClinicalPathway_StateDefinition>(isTerminalState, choose<Shared_StateKey, ClinicalPathway_StateDefinition>((sk: Shared_StateKey): Option<ClinicalPathway_StateDefinition> => findState(sk, context.PathwaySpec.States), toList<Shared_StateKey>(context.CurrentStates)));
1293
+ const updatedContext: ExecutionContext = new ExecutionContext(context.PathwaySpec, formSpec, context.CurrentStates, context.VisitedStates, context.CompletedStates, context.ActiveTransitions, context.PendingTransitions, context.ExecutedActions, context.FieldResolver, context.ExecutionLog);
1294
+ const newContext: ExecutionContext = executeStep(updatedContext, 100);
1295
+ return new IncrementalExecutionResult(newContext, map<Shared_StateKey, string>((_arg: Shared_StateKey): string => _arg.fields[0], toList<Shared_StateKey>(difference<Shared_StateKey>(newContext.CurrentStates, updatedContext.CurrentStates))), (previousTransitionKeys = ofList_1<Shared_TransitionKey>(map<MatchedTransition, Shared_TransitionKey>((t: MatchedTransition): Shared_TransitionKey => t.Transition.TransitionKey, updatedContext.ActiveTransitions), {
1296
+ Compare: compare,
1297
+ }), (newKeys = difference<Shared_TransitionKey>(ofList_1<Shared_TransitionKey>(map<MatchedTransition, Shared_TransitionKey>((t_1: MatchedTransition): Shared_TransitionKey => t_1.Transition.TransitionKey, newContext.ActiveTransitions), {
1298
+ Compare: compare,
1299
+ }), previousTransitionKeys), map<MatchedTransition, ClinicalPathway_TransitionDefinition>((t_3: MatchedTransition): ClinicalPathway_TransitionDefinition => t_3.Transition, filter_1<MatchedTransition>((t_2: MatchedTransition): boolean => contains<Shared_TransitionKey>(t_2.Transition.TransitionKey, newKeys), newContext.ActiveTransitions)))), predictOutcomes(newContext), calculateCompletionPercentage(newContext), isExecutionComplete(newContext));
1300
+ }
1301
+
1302
+ /**
1303
+ * Get visualization state from execution context
1304
+ */
1305
+ export function getVisualizationState(context: ExecutionContext): VisualizationState {
1306
+ const patternInput: [FSharpList<MatchedTransition>, FSharpList<MatchedTransition>, FSharpList<MatchedTransition>] = categorizeTransitions(context.ActiveTransitions);
1307
+ const completedTransitions: FSharpList<string> = map<ExecutionLogEntry, string>((log_1: ExecutionLogEntry): string => log_1.Details, filter_1<ExecutionLogEntry>((log: ExecutionLogEntry): boolean => (log.Action === "Transitioned"), context.ExecutionLog));
1308
+ return new VisualizationState(context.CurrentStates, context.VisitedStates, map<MatchedTransition, Shared_TransitionKey>((t: MatchedTransition): Shared_TransitionKey => t.Transition.TransitionKey, patternInput[0]), map<MatchedTransition, Shared_TransitionKey>((t_1: MatchedTransition): Shared_TransitionKey => t_1.Transition.TransitionKey, patternInput[1]), completedTransitions, predictOutcomes(context));
1309
+ }
1310
+
1311
+ /**
1312
+ * Extract final clinical plans from execution context
1313
+ */
1314
+ export function extractClinicalPlans(context: ExecutionContext): FSharpList<ClinicalPlan> {
1315
+ return sortBy<ClinicalPlan, int32>((plan: ClinicalPlan): int32 => plan.Priority, choose<Shared_StateKey, ClinicalPlan>((stateKey: Shared_StateKey): Option<ClinicalPlan> => {
1316
+ const matchValue: Option<ClinicalPathway_StateDefinition> = findState(stateKey, context.PathwaySpec.States);
1317
+ let matchResult: int32, state_1: ClinicalPathway_StateDefinition;
1318
+ if (matchValue != null) {
1319
+ if (!isEmpty(extractActionsFromState(value_3(matchValue)))) {
1320
+ matchResult = 0;
1321
+ state_1 = value_3(matchValue);
1322
+ }
1323
+ else {
1324
+ matchResult = 1;
1325
+ }
1326
+ }
1327
+ else {
1328
+ matchResult = 1;
1329
+ }
1330
+ switch (matchResult) {
1331
+ case 0: {
1332
+ const stateKeyStr: string = stateKey.fields[0];
1333
+ return new ClinicalPlan(stateKeyStr, extractActionsFromState(state_1!), stateKeyStr, state_1!.StateOrder);
1334
+ }
1335
+ default:
1336
+ return undefined;
1337
+ }
1338
+ }, toList<Shared_StateKey>(context.CurrentStates)), {
1339
+ Compare: comparePrimitives,
1340
+ });
1341
+ }
1342
+
1343
+ export class PathwayExecutionResult$1<FieldType> extends Record implements IEquatable<PathwayExecutionResult$1<FieldType>>, IComparable<PathwayExecutionResult$1<FieldType>> {
1344
+ readonly PathwayId: string;
1345
+ readonly StartState: string;
1346
+ readonly CurrentState: string;
1347
+ readonly ExecutionMode: ClinicalPathway_PathwayExecutionMode_$union;
1348
+ readonly SelectedPaths: FSharpList<string>;
1349
+ readonly RejectedPaths: FSharpList<[string, string]>;
1350
+ readonly ExecutedActions: FSharpList<ClinicalPathway_ActionInfo_$union>;
1351
+ readonly VisitedStates: FSharpList<string>;
1352
+ readonly TransitionsUsed: FSharpList<string>;
1353
+ readonly FormSpec: Spec_FormSpec$1<FieldType>;
1354
+ readonly ExecutionTime: Date;
1355
+ readonly Success: boolean;
1356
+ readonly Errors: FSharpList<string>;
1357
+ constructor(PathwayId: string, StartState: string, CurrentState: string, ExecutionMode: ClinicalPathway_PathwayExecutionMode_$union, SelectedPaths: FSharpList<string>, RejectedPaths: FSharpList<[string, string]>, ExecutedActions: FSharpList<ClinicalPathway_ActionInfo_$union>, VisitedStates: FSharpList<string>, TransitionsUsed: FSharpList<string>, FormSpec: Spec_FormSpec$1<FieldType>, ExecutionTime: Date, Success: boolean, Errors: FSharpList<string>) {
1358
+ super();
1359
+ this.PathwayId = PathwayId;
1360
+ this.StartState = StartState;
1361
+ this.CurrentState = CurrentState;
1362
+ this.ExecutionMode = ExecutionMode;
1363
+ this.SelectedPaths = SelectedPaths;
1364
+ this.RejectedPaths = RejectedPaths;
1365
+ this.ExecutedActions = ExecutedActions;
1366
+ this.VisitedStates = VisitedStates;
1367
+ this.TransitionsUsed = TransitionsUsed;
1368
+ this.FormSpec = FormSpec;
1369
+ this.ExecutionTime = ExecutionTime;
1370
+ this.Success = Success;
1371
+ this.Errors = Errors;
1372
+ }
1373
+ }
1374
+
1375
+ export function PathwayExecutionResult$1_$reflection(gen0: TypeInfo): TypeInfo {
1376
+ return record_type("F1.Studio.PathwayExecutor.PathwayExecutionResult`1", [gen0], PathwayExecutionResult$1, () => [["PathwayId", string_type], ["StartState", string_type], ["CurrentState", string_type], ["ExecutionMode", ClinicalPathway_PathwayExecutionMode_$reflection()], ["SelectedPaths", list_type(string_type)], ["RejectedPaths", list_type(tuple_type(string_type, string_type))], ["ExecutedActions", list_type(ClinicalPathway_ActionInfo_$reflection())], ["VisitedStates", list_type(string_type)], ["TransitionsUsed", list_type(string_type)], ["FormSpec", Spec_FormSpec$1_$reflection(gen0)], ["ExecutionTime", class_type("System.DateTime")], ["Success", bool_type], ["Errors", list_type(string_type)]]);
1377
+ }
1378
+
1379
+ //# sourceMappingURL=PathwayExecutor.ts.map