pict-section-formeditor 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (178) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +118 -0
  3. package/docs/.nojekyll +0 -0
  4. package/docs/README.md +162 -0
  5. package/docs/_sidebar.md +23 -0
  6. package/docs/_topbar.md +5 -0
  7. package/docs/cover.md +12 -0
  8. package/docs/css/docuserve.css +73 -0
  9. package/docs/index.html +39 -0
  10. package/docs/retold-catalog.json +224 -0
  11. package/docs/retold-keyword-index.json +46846 -0
  12. package/example_applications/form_editor/.quackage.json +10 -0
  13. package/example_applications/form_editor/FormEditor-Example-Application.js +226 -0
  14. package/example_applications/form_editor/html/icon-chooser.html +375 -0
  15. package/example_applications/form_editor/html/index.html +54 -0
  16. package/example_applications/form_editor/package.json +50 -0
  17. package/package.json +55 -0
  18. package/sample_manifests/Complex-Table.json +974 -0
  19. package/sample_manifests/Distill-Example.json +200 -0
  20. package/sample_manifests/Gradebook-Assignment.json +38 -0
  21. package/sample_manifests/Gradebook-Student.json +40 -0
  22. package/sample_manifests/Manyfest-Editor.json +347 -0
  23. package/sample_manifests/Simple-Form.json +232 -0
  24. package/sample_manifests/Simple-Table.json +79 -0
  25. package/source/Pict-Section-FormEditor-DefaultConfiguration.js +3321 -0
  26. package/source/Pict-Section-FormEditor.js +35 -0
  27. package/source/providers/Pict-Provider-ChildPictManager-Application.js +40 -0
  28. package/source/providers/Pict-Provider-ChildPictManager.js +238 -0
  29. package/source/providers/Pict-Provider-FormEditorDocumentation.js +356 -0
  30. package/source/providers/Pict-Provider-FormEditorDragDrop.js +535 -0
  31. package/source/providers/Pict-Provider-FormEditorIconography.js +1002 -0
  32. package/source/providers/Pict-Provider-FormEditorManifestOps.js +1443 -0
  33. package/source/providers/Pict-Provider-FormEditorRendering.js +730 -0
  34. package/source/providers/Pict-Provider-FormEditorUtilities.js +862 -0
  35. package/source/providers/Pict-Provider-PreviewCSS.js +42 -0
  36. package/source/views/PictView-FormEditor-InlineEditing.js +309 -0
  37. package/source/views/PictView-FormEditor-InputTypePicker.js +532 -0
  38. package/source/views/PictView-FormEditor-PropertiesPanel.js +7730 -0
  39. package/source/views/PictView-FormEditor.js +681 -0
  40. package/test/Pict-Section-FormEditor_tests.js +4102 -0
  41. package/user-documentation/.pict_documentation_topics.json +695 -0
  42. package/user-documentation/Getting-Started.md +32 -0
  43. package/user-documentation/Groups.md +52 -0
  44. package/user-documentation/Inputs.md +98 -0
  45. package/user-documentation/Sections.md +36 -0
  46. package/user-documentation/Shortcuts.md +44 -0
  47. package/user-documentation/Solver-Expression-Walkthrough.md +176 -0
  48. package/user-documentation/Solver-Expressions-Advanced.md +344 -0
  49. package/user-documentation/Solver-Functions.md +213 -0
  50. package/user-documentation/Solvers.md +81 -0
  51. package/user-documentation/ToC.md +18 -0
  52. package/user-documentation/solverfunctions/abs.md +84 -0
  53. package/user-documentation/solverfunctions/aggregationhistogram.md +83 -0
  54. package/user-documentation/solverfunctions/aggregationhistogrambyobject.md +64 -0
  55. package/user-documentation/solverfunctions/arrayconcat.md +64 -0
  56. package/user-documentation/solverfunctions/avg.md +81 -0
  57. package/user-documentation/solverfunctions/bucketset.md +69 -0
  58. package/user-documentation/solverfunctions/ceil.md +70 -0
  59. package/user-documentation/solverfunctions/cleanvaluearray.md +66 -0
  60. package/user-documentation/solverfunctions/cleanvalueobject.md +68 -0
  61. package/user-documentation/solverfunctions/colorgroupbackground.md +60 -0
  62. package/user-documentation/solverfunctions/colorinputbackground.md +62 -0
  63. package/user-documentation/solverfunctions/colorinputbackgroundtabular.md +64 -0
  64. package/user-documentation/solverfunctions/colorsectionbackground.md +59 -0
  65. package/user-documentation/solverfunctions/compare.md +72 -0
  66. package/user-documentation/solverfunctions/concat.md +73 -0
  67. package/user-documentation/solverfunctions/concatraw.md +73 -0
  68. package/user-documentation/solverfunctions/cos.md +75 -0
  69. package/user-documentation/solverfunctions/count.md +73 -0
  70. package/user-documentation/solverfunctions/countset.md +65 -0
  71. package/user-documentation/solverfunctions/countsetelements.md +63 -0
  72. package/user-documentation/solverfunctions/createarrayfromabsolutevalues.md +63 -0
  73. package/user-documentation/solverfunctions/createvalueobjectbyhashes.md +69 -0
  74. package/user-documentation/solverfunctions/cumulativesummation.md +96 -0
  75. package/user-documentation/solverfunctions/dateadddays.md +79 -0
  76. package/user-documentation/solverfunctions/dateaddhours.md +74 -0
  77. package/user-documentation/solverfunctions/dateaddmilliseconds.md +65 -0
  78. package/user-documentation/solverfunctions/dateaddminutes.md +72 -0
  79. package/user-documentation/solverfunctions/dateaddmonths.md +74 -0
  80. package/user-documentation/solverfunctions/dateaddseconds.md +66 -0
  81. package/user-documentation/solverfunctions/dateaddweeks.md +73 -0
  82. package/user-documentation/solverfunctions/dateaddyears.md +74 -0
  83. package/user-documentation/solverfunctions/datedaydifference.md +84 -0
  84. package/user-documentation/solverfunctions/datefromparts.md +81 -0
  85. package/user-documentation/solverfunctions/datehourdifference.md +64 -0
  86. package/user-documentation/solverfunctions/datemathadd.md +72 -0
  87. package/user-documentation/solverfunctions/datemilliseconddifference.md +64 -0
  88. package/user-documentation/solverfunctions/dateminutedifference.md +64 -0
  89. package/user-documentation/solverfunctions/datemonthdifference.md +66 -0
  90. package/user-documentation/solverfunctions/dateseconddifference.md +64 -0
  91. package/user-documentation/solverfunctions/dateweekdifference.md +65 -0
  92. package/user-documentation/solverfunctions/dateyeardifference.md +64 -0
  93. package/user-documentation/solverfunctions/differencearrays.md +59 -0
  94. package/user-documentation/solverfunctions/disablesolverordinal.md +58 -0
  95. package/user-documentation/solverfunctions/distributionhistogram.md +96 -0
  96. package/user-documentation/solverfunctions/distributionhistogrambyobject.md +64 -0
  97. package/user-documentation/solverfunctions/enablesolverordinal.md +57 -0
  98. package/user-documentation/solverfunctions/entryinset.md +72 -0
  99. package/user-documentation/solverfunctions/euler.md +77 -0
  100. package/user-documentation/solverfunctions/exp.md +74 -0
  101. package/user-documentation/solverfunctions/findfirstvaluebyexactmatch.md +67 -0
  102. package/user-documentation/solverfunctions/findfirstvaluebystringincludes.md +67 -0
  103. package/user-documentation/solverfunctions/flatten.md +76 -0
  104. package/user-documentation/solverfunctions/floor.md +70 -0
  105. package/user-documentation/solverfunctions/gaussianelimination.md +75 -0
  106. package/user-documentation/solverfunctions/generatearrayofobjectsfromsets.md +70 -0
  107. package/user-documentation/solverfunctions/generatehtmlhexcolor.md +67 -0
  108. package/user-documentation/solverfunctions/getvalue.md +90 -0
  109. package/user-documentation/solverfunctions/getvaluearray.md +64 -0
  110. package/user-documentation/solverfunctions/getvalueobject.md +67 -0
  111. package/user-documentation/solverfunctions/hidesections.md +58 -0
  112. package/user-documentation/solverfunctions/if.md +109 -0
  113. package/user-documentation/solverfunctions/iterativeseries.md +107 -0
  114. package/user-documentation/solverfunctions/join.md +75 -0
  115. package/user-documentation/solverfunctions/joinraw.md +64 -0
  116. package/user-documentation/solverfunctions/largestinset.md +63 -0
  117. package/user-documentation/solverfunctions/leastsquares.md +66 -0
  118. package/user-documentation/solverfunctions/linest.md +58 -0
  119. package/user-documentation/solverfunctions/log.md +74 -0
  120. package/user-documentation/solverfunctions/logvalues.md +65 -0
  121. package/user-documentation/solverfunctions/match.md +71 -0
  122. package/user-documentation/solverfunctions/matrixinverse.md +67 -0
  123. package/user-documentation/solverfunctions/matrixmultiply.md +71 -0
  124. package/user-documentation/solverfunctions/matrixtranspose.md +72 -0
  125. package/user-documentation/solverfunctions/matrixvectormultiply.md +69 -0
  126. package/user-documentation/solverfunctions/max.md +73 -0
  127. package/user-documentation/solverfunctions/mean.md +63 -0
  128. package/user-documentation/solverfunctions/median.md +79 -0
  129. package/user-documentation/solverfunctions/min.md +73 -0
  130. package/user-documentation/solverfunctions/mode.md +66 -0
  131. package/user-documentation/solverfunctions/objectkeystoarray.md +66 -0
  132. package/user-documentation/solverfunctions/objectvaluessortbyexternalobjectarray.md +65 -0
  133. package/user-documentation/solverfunctions/objectvaluestoarray.md +67 -0
  134. package/user-documentation/solverfunctions/percent.md +75 -0
  135. package/user-documentation/solverfunctions/pi.md +77 -0
  136. package/user-documentation/solverfunctions/polynomialregression.md +69 -0
  137. package/user-documentation/solverfunctions/predict.md +71 -0
  138. package/user-documentation/solverfunctions/rad.md +85 -0
  139. package/user-documentation/solverfunctions/randomfloat.md +63 -0
  140. package/user-documentation/solverfunctions/randomfloatbetween.md +72 -0
  141. package/user-documentation/solverfunctions/randomfloatupto.md +65 -0
  142. package/user-documentation/solverfunctions/randominteger.md +56 -0
  143. package/user-documentation/solverfunctions/randomintegerbetween.md +72 -0
  144. package/user-documentation/solverfunctions/randomintegerupto.md +64 -0
  145. package/user-documentation/solverfunctions/refreshtabularsection.md +57 -0
  146. package/user-documentation/solverfunctions/resolvehtmlentities.md +64 -0
  147. package/user-documentation/solverfunctions/round.md +111 -0
  148. package/user-documentation/solverfunctions/runsolvers.md +49 -0
  149. package/user-documentation/solverfunctions/setconcatenate.md +64 -0
  150. package/user-documentation/solverfunctions/setgroupvisibility.md +60 -0
  151. package/user-documentation/solverfunctions/setsectionvisibility.md +59 -0
  152. package/user-documentation/solverfunctions/setsolverordinalenabled.md +59 -0
  153. package/user-documentation/solverfunctions/settabularrowlength.md +57 -0
  154. package/user-documentation/solverfunctions/setvalue.md +65 -0
  155. package/user-documentation/solverfunctions/showsections.md +58 -0
  156. package/user-documentation/solverfunctions/sin.md +83 -0
  157. package/user-documentation/solverfunctions/slice.md +80 -0
  158. package/user-documentation/solverfunctions/smallestinset.md +63 -0
  159. package/user-documentation/solverfunctions/sortarray.md +58 -0
  160. package/user-documentation/solverfunctions/sorthistogram.md +70 -0
  161. package/user-documentation/solverfunctions/sorthistogrambykeys.md +69 -0
  162. package/user-documentation/solverfunctions/sortset.md +75 -0
  163. package/user-documentation/solverfunctions/sqrt.md +85 -0
  164. package/user-documentation/solverfunctions/stdev.md +81 -0
  165. package/user-documentation/solverfunctions/stdeva.md +58 -0
  166. package/user-documentation/solverfunctions/stdevp.md +83 -0
  167. package/user-documentation/solverfunctions/stringcountsegments.md +66 -0
  168. package/user-documentation/solverfunctions/stringgetsegments.md +74 -0
  169. package/user-documentation/solverfunctions/subtractingsummation.md +66 -0
  170. package/user-documentation/solverfunctions/sum.md +78 -0
  171. package/user-documentation/solverfunctions/tan.md +78 -0
  172. package/user-documentation/solverfunctions/tofixed.md +75 -0
  173. package/user-documentation/solverfunctions/unionarrays.md +59 -0
  174. package/user-documentation/solverfunctions/uniquearray.md +58 -0
  175. package/user-documentation/solverfunctions/var.md +67 -0
  176. package/user-documentation/solverfunctions/vara.md +58 -0
  177. package/user-documentation/solverfunctions/varp.md +66 -0
  178. package/user-documentation/solverfunctions/when.md +98 -0
@@ -0,0 +1,344 @@
1
+ # Solver Expressions Advanced Topics
2
+
3
+ This article covers scope rules, tabular group solvers, data creation, set operations, MAP/SERIES expressions, and ordinal-based execution control.
4
+
5
+ ## Scope: Global Form vs Tabular Group
6
+
7
+ Understanding scope is essential for writing correct solver expressions.
8
+
9
+ ### Global Form Scope (Section Solvers)
10
+
11
+ Section-level solvers operate in the global form scope. They can read and write any input address in the form. When a section solver references a hash like `Price`, it resolves to the top-level form data.
12
+
13
+ ```
14
+ Total = Price * Quantity
15
+ ```
16
+
17
+ This reads `Price` and `Quantity` from the form's AppData and writes `Total` back to the form's AppData.
18
+
19
+ Section solvers can also read from the broader application state using `getvalue`:
20
+
21
+ ```
22
+ TaxRate = getvalue("AppData.Settings.TaxRate")
23
+ ```
24
+
25
+ ### Tabular/RecordSet Scope (Group Solvers)
26
+
27
+ Tabular and RecordSet groups have their own solver arrays (`RecordSetSolvers`). These solvers execute once per row in the data set. Inside a group solver, hash references resolve to the current row's data rather than the global form.
28
+
29
+ For example, if a Tabular group displays rows from `AppData.LineItems` and each row has `Price`, `Quantity`, and `LineTotal` fields, a group solver like:
30
+
31
+ ```
32
+ LineTotal = Price * Quantity
33
+ ```
34
+
35
+ runs for each row individually. `Price` refers to that row's price, not a global form input. The result `LineTotal` is written back to that same row.
36
+
37
+ ### Crossing Scope Boundaries
38
+
39
+ Group solvers can access global form data using `getvalue`:
40
+
41
+ ```
42
+ LineTotal = Price * Quantity * (1 + getvalue("AppData.FormData.TaxRate"))
43
+ ```
44
+
45
+ Conversely, section solvers can aggregate data from tabular groups using array-aware functions:
46
+
47
+ ```
48
+ OrderTotal = sum(flatten(getvalue("AppData.LineItems[].LineTotal")))
49
+ ```
50
+
51
+ The `[]` syntax in `getvalue` gathers a value from every element of the array.
52
+
53
+ ## Creating Data in Scope
54
+
55
+ Solver expressions can create new data that did not exist in the original form inputs. When you assign to a hash that is not a declared input, the value is stored in the solver's destination object and is available to subsequent solvers.
56
+
57
+ ```
58
+ TaxAmount = Subtotal * TaxRate
59
+ GrandTotal = Subtotal + TaxAmount
60
+ ```
61
+
62
+ Even if `TaxAmount` is not a form input, the second expression can still reference it because it was created by the first expression in the same solver pass.
63
+
64
+ ### Writing to Application State
65
+
66
+ Use `setvalue` to write data to a specific path in the application state:
67
+
68
+ ```
69
+ setvalue("AppData.Computed.OrderSummary.Total", GrandTotal)
70
+ ```
71
+
72
+ This is useful for making computed results available to other parts of the application, not just the form.
73
+
74
+ ### Null Coalescence for Defaults
75
+
76
+ Use `?=` to set initial values without overwriting existing data:
77
+
78
+ ```
79
+ DefaultShipping ?= 5.99
80
+ DefaultCurrency ?= "USD"
81
+ ```
82
+
83
+ These only write if the target is currently empty, so user edits are preserved.
84
+
85
+ ## Set Operations and Array Manipulation
86
+
87
+ Many solver functions work with arrays (called "sets" in the expression language). These are essential for working with lists of data.
88
+
89
+ ### Building Arrays
90
+
91
+ The comma operator creates a set from individual values:
92
+
93
+ ```
94
+ Colors = "Red", "Green", "Blue"
95
+ ```
96
+
97
+ Use `flatten` to extract arrays from nested data:
98
+
99
+ ```
100
+ AllCities = flatten(getvalue("AppData.Regions[].Cities[].Name"))
101
+ ```
102
+
103
+ Use `getvaluearray` to gather specific paths into a single array:
104
+
105
+ ```
106
+ KeyMetrics = getvaluearray("AppData.Revenue", "AppData.Costs", "AppData.Profit")
107
+ ```
108
+
109
+ ### Filtering and Transforming
110
+
111
+ `uniquearray` removes duplicates:
112
+
113
+ ```
114
+ UniqueStates = uniquearray(AllStates)
115
+ ```
116
+
117
+ `sortarray` sorts values:
118
+
119
+ ```
120
+ SortedNames = sortarray(AllNames)
121
+ ```
122
+
123
+ `slice` extracts a portion:
124
+
125
+ ```
126
+ TopFive = slice(SortedScores, 0, 5)
127
+ ```
128
+
129
+ ### Set Algebra
130
+
131
+ Combine or compare arrays:
132
+
133
+ ```
134
+ AllMembers = unionarrays(TeamA, TeamB)
135
+ OnlyInA = differencearrays(TeamA, TeamB)
136
+ ```
137
+
138
+ ### Searching
139
+
140
+ Find specific values in arrays of objects:
141
+
142
+ ```
143
+ FoundCity = findfirstvaluebyexactmatch(getvalue("AppData.Cities"), "state", "Colorado", "city")
144
+ ```
145
+
146
+ This searches the Cities array for the first entry where `state` equals `"Colorado"` and returns its `city` field.
147
+
148
+ ```
149
+ MatchIndex = match("Denver", CityNames)
150
+ ```
151
+
152
+ This returns the zero-based index of `"Denver"` in the array, similar to a spreadsheet MATCH function.
153
+
154
+ ## MAP Expressions
155
+
156
+ MAP transforms each element of an array using an expression:
157
+
158
+ ```
159
+ Result = MAP VAR x FROM Values : x * 2
160
+ ```
161
+
162
+ Given `Values = [1, 2, 3, 4, 5]`, this produces `[2, 4, 6, 8, 10]`.
163
+
164
+ Multiple variables iterate in parallel:
165
+
166
+ ```
167
+ Distances = MAP VAR lat FROM Latitudes VAR lon FROM Longitudes : sqrt(lat^2 + lon^2)
168
+ ```
169
+
170
+ MAP is powerful for transforming tabular data, computing derived columns, or preparing data for charts.
171
+
172
+ ## SERIES Expressions
173
+
174
+ SERIES generates a sequence of computed values over a numeric range:
175
+
176
+ ```
177
+ XValues = SERIES FROM 0 TO 100 STEP 5 : n
178
+ ```
179
+
180
+ This produces `[0, 5, 10, 15, ..., 100]`. The variable `n` holds the current step value, and `stepIndex` holds the zero-based index.
181
+
182
+ ```
183
+ Curve = SERIES FROM 0 TO 10 STEP 0.5 : n^2 + 2*n + 1
184
+ ```
185
+
186
+ Series variables (FROM, TO, STEP) can reference other solver values:
187
+
188
+ ```
189
+ DataPoints = SERIES FROM StartX TO EndX STEP Resolution : BaseValue + (n * Slope)
190
+ ```
191
+
192
+ ## Ordinal-Based Execution Control
193
+
194
+ ### Multi-Pass Computation
195
+
196
+ Ordinals let you organize solvers into execution phases:
197
+
198
+ - **Ordinal 1** (default): Core calculations — compute raw values
199
+ - **Ordinal 2**: Derived calculations — aggregate results from ordinal 1
200
+ - **Ordinal 3**: UI updates — color cells, show/hide sections based on computed values
201
+
202
+ ### Dynamic Ordinal Control
203
+
204
+ You can enable or disable entire ordinals at runtime:
205
+
206
+ ```
207
+ disablesolverordinal(3)
208
+ ```
209
+
210
+ This prevents all ordinal-3 solvers from executing. Re-enable them later:
211
+
212
+ ```
213
+ enablesolverordinal(3)
214
+ ```
215
+
216
+ Or conditionally toggle based on form state:
217
+
218
+ ```
219
+ setsolverordinalenabled(2, IsAdvancedMode)
220
+ ```
221
+
222
+ This is useful for performance optimization — skip expensive calculations when their results are not needed.
223
+
224
+ ## Form UI Control from Solvers
225
+
226
+ Solvers can directly control form appearance and visibility.
227
+
228
+ ### Section and Group Visibility
229
+
230
+ Show or hide parts of the form based on data:
231
+
232
+ ```
233
+ setsectionvisibility("AdvancedOptions", ShowAdvanced)
234
+ setsectionvisibility("BasicOptions", if(ShowAdvanced, "==", "true", "0", "1"))
235
+ ```
236
+
237
+ For bulk operations:
238
+
239
+ ```
240
+ showsections(VisibleSections)
241
+ hidesections(HiddenSections)
242
+ ```
243
+
244
+ Where `VisibleSections` and `HiddenSections` are arrays of section hashes.
245
+
246
+ ### Conditional Coloring
247
+
248
+ Highlight cells or sections based on computed values:
249
+
250
+ ```
251
+ AlertColor = if(Total, ">", Budget, "#FFE0E0", "#E0FFE0")
252
+ colorsectionbackground("Summary", AlertColor)
253
+ ```
254
+
255
+ For individual inputs:
256
+
257
+ ```
258
+ colorinputbackground("S1", "Total", if(Total, ">", Budget, "#FF0000", "#000000"))
259
+ ```
260
+
261
+ For tabular cells, specify the row index:
262
+
263
+ ```
264
+ colorinputbackgroundtabular("Data", "DataGroup", "Status", RowIndex, StatusColor)
265
+ ```
266
+
267
+ ### Tabular Row Management
268
+
269
+ Control the number of rows in a tabular group:
270
+
271
+ ```
272
+ settabularrowlength("DataSection", "DataGroup", DesiredRowCount)
273
+ ```
274
+
275
+ After modifying tabular data, force a display refresh:
276
+
277
+ ```
278
+ refreshtabularsection("DataSection", "DataGroup")
279
+ ```
280
+
281
+ ## Histogram and Aggregation
282
+
283
+ Histograms group and summarize data by field values.
284
+
285
+ ### Distribution Histogram
286
+
287
+ Count occurrences of each unique value:
288
+
289
+ ```
290
+ StateCounts = distributionhistogram("AppData.Cities", "state")
291
+ ```
292
+
293
+ Result: `{ "Colorado": 21, "New York": 15, "California": 42, ... }`
294
+
295
+ ### Aggregation Histogram
296
+
297
+ Sum a numeric field grouped by a category:
298
+
299
+ ```
300
+ PopulationByState = aggregationhistogram("AppData.Cities", "state", "population")
301
+ ```
302
+
303
+ Result: `{ "Colorado": "5773714", "New York": "19453561", ... }`
304
+
305
+ ### Working with Histogram Results
306
+
307
+ Extract keys and values for charting:
308
+
309
+ ```
310
+ StateNames = objectkeystoarray(StateCounts)
311
+ StateValues = objectvaluestoarray(StateCounts)
312
+ SortedHistogram = sorthistogram(StateCounts)
313
+ ```
314
+
315
+ ## Regression and Prediction
316
+
317
+ Fit models to data and make predictions:
318
+
319
+ ```
320
+ Coefficients = linest(flatten(getvalue("AppData.XData")), flatten(getvalue("AppData.YData")))
321
+ PredictedY = predict(Coefficients, NewXValue)
322
+ ```
323
+
324
+ For polynomial regression:
325
+
326
+ ```
327
+ PolyCoefficients = polynomialregression(XValues, YValues, 3)
328
+ ```
329
+
330
+ ## Debugging Expressions
331
+
332
+ Use `logvalues` to print intermediate values to the browser console:
333
+
334
+ ```
335
+ Debug = logvalues("Tax:", TaxRate, "Subtotal:", Subtotal, "Total:", Total)
336
+ ```
337
+
338
+ This logs each value and returns the last one. It helps track down issues in complex solver chains.
339
+
340
+ ## Next Steps
341
+
342
+ - Browse the [Solver Functions](Solver-Functions.md) reference for every available function
343
+ - Review the [Solver Expression Walkthrough](Solver-Expression-Walkthrough.md) for basics
344
+ - Return to the [Table of Contents](ToC.md)
@@ -0,0 +1,213 @@
1
+ # Solver Functions
2
+
3
+ A complete reference of all functions available in solver expressions. Functions are case-insensitive.
4
+
5
+ See the [Solver Expression Walkthrough](Solver-Expression-Walkthrough.md) for an introduction or [Advanced Topics](Solver-Expressions-Advanced.md) for scope rules and complex patterns.
6
+
7
+ ## Conditional
8
+
9
+ - [if](solverfunctions/if.md) -- Conditional comparison: `if(left, operator, right, trueValue, falseValue)`
10
+ - [when](solverfunctions/when.md) -- Truthy check: `when(value, trueResult, falseResult)`
11
+
12
+ ## Math
13
+
14
+ - [abs](solverfunctions/abs.md) -- Absolute value
15
+ - [ceil](solverfunctions/ceil.md) -- Round up to nearest integer
16
+ - [compare](solverfunctions/compare.md) -- Compare two values
17
+ - [cos](solverfunctions/cos.md) -- Cosine (radians)
18
+ - [euler](solverfunctions/euler.md) -- Euler's number (e)
19
+ - [exp](solverfunctions/exp.md) -- Exponential (e^x)
20
+ - [floor](solverfunctions/floor.md) -- Round down to nearest integer
21
+ - [log](solverfunctions/log.md) -- Natural logarithm
22
+ - [percent](solverfunctions/percent.md) -- Percentage calculation
23
+ - [pi](solverfunctions/pi.md) -- Pi constant
24
+ - [rad](solverfunctions/rad.md) -- Degrees to radians
25
+ - [round](solverfunctions/round.md) -- Round to decimal places
26
+ - [sin](solverfunctions/sin.md) -- Sine (radians)
27
+ - [sqrt](solverfunctions/sqrt.md) -- Square root
28
+ - [tan](solverfunctions/tan.md) -- Tangent (radians)
29
+ - [tofixed](solverfunctions/tofixed.md) -- Format to fixed decimal places
30
+
31
+ ## Statistics
32
+
33
+ - [avg](solverfunctions/avg.md) -- Average (alias for mean)
34
+ - [count](solverfunctions/count.md) -- Count elements in array
35
+ - [countset](solverfunctions/countset.md) -- Count set elements
36
+ - [countsetelements](solverfunctions/countsetelements.md) -- Count elements in histogram
37
+ - [max](solverfunctions/max.md) -- Maximum value
38
+ - [mean](solverfunctions/mean.md) -- Arithmetic mean
39
+ - [median](solverfunctions/median.md) -- Median value
40
+ - [min](solverfunctions/min.md) -- Minimum value
41
+ - [mode](solverfunctions/mode.md) -- Most frequent value
42
+ - [stdev](solverfunctions/stdev.md) -- Sample standard deviation
43
+ - [stdeva](solverfunctions/stdeva.md) -- Sample standard deviation (alias)
44
+ - [stdevp](solverfunctions/stdevp.md) -- Population standard deviation
45
+ - [sum](solverfunctions/sum.md) -- Sum of values
46
+ - [var](solverfunctions/var.md) -- Sample variance
47
+ - [vara](solverfunctions/vara.md) -- Sample variance (alias)
48
+ - [varp](solverfunctions/varp.md) -- Population variance
49
+
50
+ ## String
51
+
52
+ - [concat](solverfunctions/concat.md) -- Concatenate with spaces
53
+ - [concatraw](solverfunctions/concatraw.md) -- Concatenate without spaces
54
+ - [join](solverfunctions/join.md) -- Join with separator
55
+ - [joinraw](solverfunctions/joinraw.md) -- Join without entity resolution
56
+ - [resolvehtmlentities](solverfunctions/resolvehtmlentities.md) -- Resolve HTML entities
57
+ - [stringcountsegments](solverfunctions/stringcountsegments.md) -- Count string segments
58
+ - [stringgetsegments](solverfunctions/stringgetsegments.md) -- Split string into segments
59
+
60
+ ## Array & Set Operations
61
+
62
+ - [arrayconcat](solverfunctions/arrayconcat.md) -- Concatenate arrays
63
+ - [differencearrays](solverfunctions/differencearrays.md) -- Set difference of two arrays
64
+ - [flatten](solverfunctions/flatten.md) -- Flatten nested arrays
65
+ - [setconcatenate](solverfunctions/setconcatenate.md) -- Concatenate sets
66
+ - [slice](solverfunctions/slice.md) -- Extract a portion of an array
67
+ - [sortarray](solverfunctions/sortarray.md) -- Sort an array
68
+ - [sortset](solverfunctions/sortset.md) -- Sort a set with precision
69
+ - [unionarrays](solverfunctions/unionarrays.md) -- Set union of two arrays
70
+ - [uniquearray](solverfunctions/uniquearray.md) -- Remove duplicates from array
71
+
72
+ ## Set Inspection
73
+
74
+ - [bucketset](solverfunctions/bucketset.md) -- Bucket values into ranges
75
+ - [entryinset](solverfunctions/entryinset.md) -- Get entry from set by index
76
+ - [largestinset](solverfunctions/largestinset.md) -- Largest value in a set
77
+ - [smallestinset](solverfunctions/smallestinset.md) -- Smallest value in a set
78
+
79
+ ## Cumulative Operations
80
+
81
+ - [cumulativesummation](solverfunctions/cumulativesummation.md) -- Running total over a set
82
+ - [iterativeseries](solverfunctions/iterativeseries.md) -- Iterative computation over array
83
+ - [subtractingsummation](solverfunctions/subtractingsummation.md) -- Running subtraction over a set
84
+
85
+ ## Histogram & Aggregation
86
+
87
+ - [aggregationhistogram](solverfunctions/aggregationhistogram.md) -- Sum values grouped by field (from AppData path)
88
+ - [aggregationhistogrambyobject](solverfunctions/aggregationhistogrambyobject.md) -- Sum values grouped by field (from object)
89
+ - [distributionhistogram](solverfunctions/distributionhistogram.md) -- Count occurrences by field (from AppData path)
90
+ - [distributionhistogrambyobject](solverfunctions/distributionhistogrambyobject.md) -- Count occurrences by field (from object)
91
+ - [sorthistogram](solverfunctions/sorthistogram.md) -- Sort histogram by values
92
+ - [sorthistogrambykeys](solverfunctions/sorthistogrambykeys.md) -- Sort histogram by keys
93
+
94
+ ## Value Access
95
+
96
+ - [getvalue](solverfunctions/getvalue.md) -- Read value from application state
97
+ - [setvalue](solverfunctions/setvalue.md) -- Write value to application state
98
+ - [getvaluearray](solverfunctions/getvaluearray.md) -- Gather multiple values into array
99
+ - [getvalueobject](solverfunctions/getvalueobject.md) -- Gather multiple values into object
100
+ - [createvalueobjectbyhashes](solverfunctions/createvalueobjectbyhashes.md) -- Create object from hash references
101
+
102
+ ## Object & Array Utilities
103
+
104
+ - [cleanvaluearray](solverfunctions/cleanvaluearray.md) -- Remove empty values from array
105
+ - [cleanvalueobject](solverfunctions/cleanvalueobject.md) -- Remove empty values from object
106
+ - [createarrayfromabsolutevalues](solverfunctions/createarrayfromabsolutevalues.md) -- Create array from absolute values
107
+ - [generatearrayofobjectsfromsets](solverfunctions/generatearrayofobjectsfromsets.md) -- Generate objects from sets
108
+ - [objectkeystoarray](solverfunctions/objectkeystoarray.md) -- Extract object keys as array
109
+ - [objectvaluestoarray](solverfunctions/objectvaluestoarray.md) -- Extract object values as array
110
+ - [objectvaluessortbyexternalobjectarray](solverfunctions/objectvaluessortbyexternalobjectarray.md) -- Sort object values by external array
111
+
112
+ ## Search
113
+
114
+ - [findfirstvaluebyexactmatch](solverfunctions/findfirstvaluebyexactmatch.md) -- Find first matching entry in array
115
+ - [findfirstvaluebystringincludes](solverfunctions/findfirstvaluebystringincludes.md) -- Find first entry containing a string
116
+ - [match](solverfunctions/match.md) -- Find index of value in array (spreadsheet-style MATCH)
117
+
118
+ ## Date
119
+
120
+ - [datefromparts](solverfunctions/datefromparts.md) -- Create date from year, month, day, etc.
121
+ - [datemilliseconddifference](solverfunctions/datemilliseconddifference.md) -- Milliseconds between two dates
122
+ - [dateseconddifference](solverfunctions/dateseconddifference.md) -- Seconds between two dates
123
+ - [dateminutedifference](solverfunctions/dateminutedifference.md) -- Minutes between two dates
124
+ - [datehourdifference](solverfunctions/datehourdifference.md) -- Hours between two dates
125
+ - [datedaydifference](solverfunctions/datedaydifference.md) -- Days between two dates
126
+ - [dateweekdifference](solverfunctions/dateweekdifference.md) -- Weeks between two dates
127
+ - [datemonthdifference](solverfunctions/datemonthdifference.md) -- Months between two dates
128
+ - [dateyeardifference](solverfunctions/dateyeardifference.md) -- Years between two dates
129
+ - [datemathadd](solverfunctions/datemathadd.md) -- Add time to a date (generic)
130
+ - [dateaddmilliseconds](solverfunctions/dateaddmilliseconds.md) -- Add milliseconds to a date
131
+ - [dateaddseconds](solverfunctions/dateaddseconds.md) -- Add seconds to a date
132
+ - [dateaddminutes](solverfunctions/dateaddminutes.md) -- Add minutes to a date
133
+ - [dateaddhours](solverfunctions/dateaddhours.md) -- Add hours to a date
134
+ - [dateadddays](solverfunctions/dateadddays.md) -- Add days to a date
135
+ - [dateaddweeks](solverfunctions/dateaddweeks.md) -- Add weeks to a date
136
+ - [dateaddmonths](solverfunctions/dateaddmonths.md) -- Add months to a date
137
+ - [dateaddyears](solverfunctions/dateaddyears.md) -- Add years to a date
138
+
139
+ ## Random Data Generation
140
+
141
+ - [randominteger](solverfunctions/randominteger.md) -- Random integer
142
+ - [randomintegerbetween](solverfunctions/randomintegerbetween.md) -- Random integer in range
143
+ - [randomintegerupto](solverfunctions/randomintegerupto.md) -- Random integer up to max
144
+ - [randomfloat](solverfunctions/randomfloat.md) -- Random float
145
+ - [randomfloatbetween](solverfunctions/randomfloatbetween.md) -- Random float in range
146
+ - [randomfloatupto](solverfunctions/randomfloatupto.md) -- Random float up to max
147
+
148
+ ## Regression & Matrix
149
+
150
+ - [gaussianelimination](solverfunctions/gaussianelimination.md) -- Gaussian elimination
151
+ - [leastsquares](solverfunctions/leastsquares.md) -- Least squares regression
152
+ - [linest](solverfunctions/linest.md) -- Linear regression (alias for leastsquares)
153
+ - [matrixinverse](solverfunctions/matrixinverse.md) -- Inverse of a matrix
154
+ - [matrixmultiply](solverfunctions/matrixmultiply.md) -- Multiply two matrices
155
+ - [matrixtranspose](solverfunctions/matrixtranspose.md) -- Transpose a matrix
156
+ - [matrixvectormultiply](solverfunctions/matrixvectormultiply.md) -- Multiply matrix by vector
157
+ - [polynomialregression](solverfunctions/polynomialregression.md) -- Polynomial regression fit
158
+ - [predict](solverfunctions/predict.md) -- Predict from regression model
159
+
160
+ ## Form UI Control
161
+
162
+ These functions control the visual appearance and behavior of the running form.
163
+
164
+ - [colorgroupbackground](solverfunctions/colorgroupbackground.md) -- Set group background color
165
+ - [colorinputbackground](solverfunctions/colorinputbackground.md) -- Set input background color
166
+ - [colorinputbackgroundtabular](solverfunctions/colorinputbackgroundtabular.md) -- Set tabular cell background color
167
+ - [colorsectionbackground](solverfunctions/colorsectionbackground.md) -- Set section background color
168
+ - [disablesolverordinal](solverfunctions/disablesolverordinal.md) -- Disable a solver execution ordinal
169
+ - [enablesolverordinal](solverfunctions/enablesolverordinal.md) -- Enable a solver execution ordinal
170
+ - [generatehtmlhexcolor](solverfunctions/generatehtmlhexcolor.md) -- Generate hex color from RGB values
171
+ - [hidesections](solverfunctions/hidesections.md) -- Hide form sections
172
+ - [refreshtabularsection](solverfunctions/refreshtabularsection.md) -- Refresh tabular display
173
+ - [runsolvers](solverfunctions/runsolvers.md) -- Re-run all solver expressions
174
+ - [setgroupvisibility](solverfunctions/setgroupvisibility.md) -- Set group visibility
175
+ - [setsectionvisibility](solverfunctions/setsectionvisibility.md) -- Set section visibility
176
+ - [setsolverordinalenabled](solverfunctions/setsolverordinalenabled.md) -- Enable or disable solver ordinal
177
+ - [settabularrowlength](solverfunctions/settabularrowlength.md) -- Set tabular row count
178
+ - [showsections](solverfunctions/showsections.md) -- Show form sections
179
+
180
+ ## Debugging
181
+
182
+ - [logvalues](solverfunctions/logvalues.md) -- Log values to browser console
183
+
184
+ ## Operators
185
+
186
+ | Operator | Description | Precedence |
187
+ |----------|-------------|------------|
188
+ | `^` | Exponentiation | Highest |
189
+ | `*` `/` `%` | Multiply, Divide, Modulus | High |
190
+ | `+` `-` | Add, Subtract | Medium |
191
+ | `,` | Set concatenation | Low |
192
+ | `=` | Assignment | Lowest |
193
+ | `?=` | Null coalescence assignment | Lowest |
194
+
195
+ ## Expression Syntax
196
+
197
+ ### MAP
198
+
199
+ ```
200
+ Result = MAP VAR x FROM ArrayValue : x * 2
201
+ ```
202
+
203
+ ### SERIES
204
+
205
+ ```
206
+ Result = SERIES FROM 0 TO 100 STEP 5 : n^2
207
+ ```
208
+
209
+ ### MONTECARLO
210
+
211
+ ```
212
+ Result = MONTECARLO SAMPLECOUNT 1000 VAR x PT x 0 PT x 100 : x^2
213
+ ```
@@ -0,0 +1,81 @@
1
+ # Solvers
2
+
3
+ Solvers are expressions that compute values, transform data, or control form behavior. They run when the form renders and can assign calculated results to input fields.
4
+
5
+ ## What is a Solver Expression?
6
+
7
+ A solver expression is a string written in the Fable expression syntax. It can reference input addresses, perform arithmetic, call built-in functions, and assign results to data paths. Solvers are attached to sections or to tabular/recordset groups.
8
+
9
+ ## Where Solvers Live
10
+
11
+ - **Section Solvers** -- Attached to a section and evaluated in the context of that section's data. Most solvers are section-level.
12
+ - **Group Solvers (RecordSet)** -- Attached to a Tabular or RecordSet group and evaluated for each record in the set. Only groups with a Tabular or RecordSet layout can have their own solvers.
13
+
14
+ ## The Solver Editor Tab
15
+
16
+ The **Solver Editor** tab provides a focused environment for writing and editing solver expressions. It has three areas:
17
+
18
+ ### Code Editor
19
+
20
+ The main editing area uses a syntax-highlighted code editor. Write your solver expression here. The editor supports the Fable expression language with highlighting for operators, addresses, and functions.
21
+
22
+ ### Ordinal
23
+
24
+ Each solver has an ordinal number that controls its execution order. Solvers with lower ordinals run first. The default ordinal is 1. If you need a solver to run before or after others, adjust its ordinal value.
25
+
26
+ - When a solver has the default ordinal (1), it is stored as a simple string in the manifest.
27
+ - When you set a non-default ordinal, the solver is promoted to an object with `Expression` and `Ordinal` properties.
28
+ - Clearing the ordinal (or setting it back to 1) demotes the solver back to a simple string.
29
+
30
+ ### Reference List
31
+
32
+ A searchable list of all inputs in the form, organized by section. Each entry shows:
33
+
34
+ - The input name and hash
35
+ - The data address
36
+ - An **Insert** button that pastes the address into the code editor at the cursor
37
+
38
+ Use the search box to filter inputs by name, hash, address, or section.
39
+
40
+ ## The Solvers Tab
41
+
42
+ The **Solvers** tab provides a read-only overview of all solver expressions across the form. It is organized into sections:
43
+
44
+ ### Solver Health
45
+
46
+ At the top, a health summary shows any potential issues:
47
+
48
+ - **Expressions with no hash** -- Solver expressions that do not assign a value to any input. These may be intentional (side-effect expressions) or may indicate a missing assignment.
49
+ - **Unresolved references** -- Addresses referenced in solver expressions that do not match any input in the form. These may indicate typos or deleted inputs.
50
+
51
+ ### Solver List
52
+
53
+ Below the health section, all solvers are listed grouped by their parent section or group. Each solver expression is clickable and opens directly in the Solver Editor.
54
+
55
+ ### Input Solver Info
56
+
57
+ When you select an input in the visual editor, the Input tab in the properties panel shows solver information for that input:
58
+
59
+ - **Assigned by** -- Which solver expression assigns a value to this input (if any). Clickable to open in the Solver Editor.
60
+ - **Referenced by** -- All solver expressions that read this input's value. Each is clickable.
61
+
62
+ ## Adding a Solver
63
+
64
+ There are two ways to add a solver:
65
+
66
+ 1. **From the properties panel** -- In the Section tab, use the solvers list to add a new solver to the selected section.
67
+ 2. **From the Add Solver helper** -- At the bottom of both the Solvers tab and the Solver Editor tab, a dropdown lets you select a target section or group, then click **+ Add Solver** to create a new empty solver and open it in the editor.
68
+
69
+ ## Managing Solvers
70
+
71
+ - **Edit** -- Click any solver expression in the Solvers tab or properties panel to open it in the Solver Editor.
72
+ - **Reorder** -- Use the up/down arrow buttons next to each solver in the properties panel. When drag-and-drop is enabled, solvers can be dragged to reorder.
73
+ - **Delete** -- Click the delete button next to a solver in the properties panel.
74
+
75
+ ## Next Steps
76
+
77
+ - Read the [Solver Expression Walkthrough](Solver-Expression-Walkthrough.md) for a step-by-step introduction to writing expressions
78
+ - Explore [Solver Expressions Advanced Topics](Solver-Expressions-Advanced.md) for scope rules, set operations, and MAP/SERIES
79
+ - Browse the [Solver Functions](Solver-Functions.md) reference for every available function
80
+ - Learn about [Inputs & Data Types](Inputs.md) to understand what solvers reference
81
+ - Return to the [Table of Contents](ToC.md)
@@ -0,0 +1,18 @@
1
+ # Form Editor Help
2
+
3
+ Welcome to the Form Editor. Use the links below to learn about each part of the editor.
4
+
5
+ ## Topics
6
+
7
+ - [Getting Started](Getting-Started.md) -- Overview of the form editor and how to begin building forms
8
+ - [Sections](Sections.md) -- How to create and configure form sections
9
+ - [Groups](Groups.md) -- Organizing inputs into groups within sections
10
+ - [Inputs & Data Types](Inputs.md) -- Adding inputs, choosing data types and input types
11
+ - [Solvers](Solvers.md) -- Writing solver expressions for computed values
12
+ - [Keyboard Shortcuts](Shortcuts.md) -- Productivity shortcuts for the form editor
13
+
14
+ ## Solver Expression Guides
15
+
16
+ - [Solver Expression Walkthrough](Solver-Expression-Walkthrough.md) -- Step-by-step introduction to writing solver expressions
17
+ - [Solver Expressions Advanced Topics](Solver-Expressions-Advanced.md) -- Scope rules, tabular solvers, set operations, and MAP/SERIES
18
+ - [Solver Functions](Solver-Functions.md) -- Complete categorized reference of all available functions