@elaraai/e3-ui 1.0.103 → 1.0.105

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 (287) hide show
  1. package/dist/src/allocation/functions.d.ts +2 -1
  2. package/dist/src/allocation/functions.d.ts.map +1 -1
  3. package/dist/src/allocation/functions.js +3 -2
  4. package/dist/src/allocation/functions.js.map +1 -1
  5. package/dist/src/allocation/index.d.ts +120 -1
  6. package/dist/src/allocation/index.d.ts.map +1 -1
  7. package/dist/src/allocation/index.js +24 -4
  8. package/dist/src/allocation/index.js.map +1 -1
  9. package/dist/src/bind/data-indexed.d.ts +25 -4
  10. package/dist/src/bind/data-indexed.d.ts.map +1 -1
  11. package/dist/src/bind/data-indexed.js +58 -7
  12. package/dist/src/bind/data-indexed.js.map +1 -1
  13. package/dist/src/bind/data.d.ts +12 -14
  14. package/dist/src/bind/data.d.ts.map +1 -1
  15. package/dist/src/bind/data.js +11 -11
  16. package/dist/src/bind/data.js.map +1 -1
  17. package/dist/src/bind/func.d.ts +7 -2
  18. package/dist/src/bind/func.d.ts.map +1 -1
  19. package/dist/src/bind/func.js +10 -3
  20. package/dist/src/bind/func.js.map +1 -1
  21. package/dist/src/calendar/index.d.ts +148 -1
  22. package/dist/src/calendar/index.d.ts.map +1 -1
  23. package/dist/src/calendar/index.js +55 -5
  24. package/dist/src/calendar/index.js.map +1 -1
  25. package/dist/src/flowchart/canvas.d.ts +32 -14
  26. package/dist/src/flowchart/canvas.d.ts.map +1 -1
  27. package/dist/src/flowchart/canvas.js +21 -6
  28. package/dist/src/flowchart/canvas.js.map +1 -1
  29. package/dist/src/flowchart/details.d.ts +469 -0
  30. package/dist/src/flowchart/details.d.ts.map +1 -0
  31. package/dist/src/flowchart/details.js +1035 -0
  32. package/dist/src/flowchart/details.js.map +1 -0
  33. package/dist/src/flowchart/flowchart.d.ts +16 -72
  34. package/dist/src/flowchart/flowchart.d.ts.map +1 -1
  35. package/dist/src/flowchart/flowchart.js +10 -1
  36. package/dist/src/flowchart/flowchart.js.map +1 -1
  37. package/dist/src/flowchart/index.d.ts +282 -251
  38. package/dist/src/flowchart/index.d.ts.map +1 -1
  39. package/dist/src/flowchart/index.js +234 -220
  40. package/dist/src/flowchart/index.js.map +1 -1
  41. package/dist/src/flowchart/kinds.d.ts +438 -0
  42. package/dist/src/flowchart/kinds.d.ts.map +1 -0
  43. package/dist/src/flowchart/kinds.js +799 -0
  44. package/dist/src/flowchart/kinds.js.map +1 -0
  45. package/dist/src/flowchart/library.d.ts +154 -739
  46. package/dist/src/flowchart/library.d.ts.map +1 -1
  47. package/dist/src/flowchart/library.js +191 -673
  48. package/dist/src/flowchart/library.js.map +1 -1
  49. package/dist/src/flowchart/payload.d.ts +3652 -7843
  50. package/dist/src/flowchart/payload.d.ts.map +1 -1
  51. package/dist/src/flowchart/payload.js +331 -469
  52. package/dist/src/flowchart/payload.js.map +1 -1
  53. package/dist/src/flowchart/templates.d.ts +657 -0
  54. package/dist/src/flowchart/templates.d.ts.map +1 -0
  55. package/dist/src/flowchart/templates.js +658 -0
  56. package/dist/src/flowchart/templates.js.map +1 -0
  57. package/dist/src/flowchart/types.d.ts +2258 -214
  58. package/dist/src/flowchart/types.d.ts.map +1 -1
  59. package/dist/src/flowchart/types.js +374 -124
  60. package/dist/src/flowchart/types.js.map +1 -1
  61. package/dist/src/index.d.ts +13 -15
  62. package/dist/src/index.d.ts.map +1 -1
  63. package/dist/src/index.js +24 -29
  64. package/dist/src/index.js.map +1 -1
  65. package/dist/src/internal.d.ts +5 -7
  66. package/dist/src/internal.d.ts.map +1 -1
  67. package/dist/src/internal.js +12 -19
  68. package/dist/src/internal.js.map +1 -1
  69. package/dist/src/ontology/index.d.ts +44 -15
  70. package/dist/src/ontology/index.d.ts.map +1 -1
  71. package/dist/src/ontology/index.js +19 -11
  72. package/dist/src/ontology/index.js.map +1 -1
  73. package/dist/src/plan/event-rows.d.ts +2 -1
  74. package/dist/src/plan/event-rows.d.ts.map +1 -1
  75. package/dist/src/plan/event-rows.js +6 -4
  76. package/dist/src/plan/event-rows.js.map +1 -1
  77. package/dist/src/plan/ir.d.ts +1 -0
  78. package/dist/src/plan/ir.d.ts.map +1 -1
  79. package/dist/src/plan/plan.d.ts +145 -1
  80. package/dist/src/plan/plan.d.ts.map +1 -1
  81. package/dist/src/plan/plan.js +67 -3
  82. package/dist/src/plan/plan.js.map +1 -1
  83. package/dist/src/plan/types.d.ts +1 -0
  84. package/dist/src/plan/types.d.ts.map +1 -1
  85. package/dist/src/query/builder.d.ts +362 -315
  86. package/dist/src/query/builder.d.ts.map +1 -1
  87. package/dist/src/query/builder.js +12 -1
  88. package/dist/src/query/builder.js.map +1 -1
  89. package/dist/src/query/index.d.ts +5 -1
  90. package/dist/src/query/index.d.ts.map +1 -1
  91. package/dist/src/query/index.js +3 -1
  92. package/dist/src/query/index.js.map +1 -1
  93. package/dist/src/roster/fit.d.ts +5 -2
  94. package/dist/src/roster/fit.d.ts.map +1 -1
  95. package/dist/src/roster/fit.js +5 -3
  96. package/dist/src/roster/fit.js.map +1 -1
  97. package/dist/src/roster/index.d.ts +103 -2
  98. package/dist/src/roster/index.d.ts.map +1 -1
  99. package/dist/src/roster/index.js +45 -6
  100. package/dist/src/roster/index.js.map +1 -1
  101. package/dist/src/runtime/index.d.ts +1 -3
  102. package/dist/src/runtime/index.d.ts.map +1 -1
  103. package/dist/src/runtime/index.js +1 -3
  104. package/dist/src/runtime/index.js.map +1 -1
  105. package/dist/src/schedule/record-window.d.ts +1 -0
  106. package/dist/src/schedule/record-window.d.ts.map +1 -1
  107. package/dist/src/schematic/index.d.ts +1 -1
  108. package/dist/src/schematic/index.d.ts.map +1 -1
  109. package/dist/src/schematic/index.js +1 -1
  110. package/dist/src/schematic/index.js.map +1 -1
  111. package/dist/src/schematic/kinds.d.ts +4 -24
  112. package/dist/src/schematic/kinds.d.ts.map +1 -1
  113. package/dist/src/schematic/kinds.js +8 -212
  114. package/dist/src/schematic/kinds.js.map +1 -1
  115. package/dist/src/schematic/payload.d.ts +140 -1
  116. package/dist/src/schematic/payload.d.ts.map +1 -1
  117. package/dist/src/schematic/payload.js +38 -1
  118. package/dist/src/schematic/payload.js.map +1 -1
  119. package/dist/src/schematic/types.d.ts.map +1 -1
  120. package/dist/src/schematic/types.js +4 -36
  121. package/dist/src/schematic/types.js.map +1 -1
  122. package/dist/src/schematic/window.d.ts +9 -42
  123. package/dist/src/schematic/window.d.ts.map +1 -1
  124. package/dist/src/schematic/window.js +10 -115
  125. package/dist/src/schematic/window.js.map +1 -1
  126. package/dist/src/sheet/actions.d.ts +388 -0
  127. package/dist/src/sheet/actions.d.ts.map +1 -0
  128. package/dist/src/sheet/actions.js +594 -0
  129. package/dist/src/sheet/actions.js.map +1 -0
  130. package/dist/src/sheet/bridge.d.ts +12 -1
  131. package/dist/src/sheet/bridge.d.ts.map +1 -1
  132. package/dist/src/sheet/bridge.js +30 -6
  133. package/dist/src/sheet/bridge.js.map +1 -1
  134. package/dist/src/sheet/columns.d.ts +5 -2
  135. package/dist/src/sheet/columns.d.ts.map +1 -1
  136. package/dist/src/sheet/columns.js.map +1 -1
  137. package/dist/src/sheet/draft-bridge.d.ts +9 -4
  138. package/dist/src/sheet/draft-bridge.d.ts.map +1 -1
  139. package/dist/src/sheet/draft-bridge.js +22 -7
  140. package/dist/src/sheet/draft-bridge.js.map +1 -1
  141. package/dist/src/sheet/fields.d.ts +13 -0
  142. package/dist/src/sheet/fields.d.ts.map +1 -1
  143. package/dist/src/sheet/fields.js +3 -0
  144. package/dist/src/sheet/fields.js.map +1 -1
  145. package/dist/src/sheet/index.d.ts +32 -2
  146. package/dist/src/sheet/index.d.ts.map +1 -1
  147. package/dist/src/sheet/index.js +18 -3
  148. package/dist/src/sheet/index.js.map +1 -1
  149. package/dist/src/sheet/library.d.ts +8 -0
  150. package/dist/src/sheet/library.d.ts.map +1 -1
  151. package/dist/src/sheet/root.d.ts +23 -1
  152. package/dist/src/sheet/root.d.ts.map +1 -1
  153. package/dist/src/sheet/root.js +40 -5
  154. package/dist/src/sheet/root.js.map +1 -1
  155. package/dist/src/sheet/sheet.d.ts +7843 -4132
  156. package/dist/src/sheet/sheet.d.ts.map +1 -1
  157. package/dist/src/sheet/sheet.js +41 -2
  158. package/dist/src/sheet/sheet.js.map +1 -1
  159. package/dist/src/sheet/templates.d.ts +4 -0
  160. package/dist/src/sheet/templates.d.ts.map +1 -1
  161. package/dist/src/sheet/types.d.ts +12449 -5268
  162. package/dist/src/sheet/types.d.ts.map +1 -1
  163. package/dist/src/sheet/types.js +114 -2
  164. package/dist/src/sheet/types.js.map +1 -1
  165. package/dist/src/utils/derive.d.ts +1 -1
  166. package/dist/src/utils/derive.js +1 -1
  167. package/dist/src/utils/record-kind.d.ts +625 -0
  168. package/dist/src/utils/record-kind.d.ts.map +1 -0
  169. package/dist/src/utils/record-kind.js +450 -0
  170. package/dist/src/utils/record-kind.js.map +1 -0
  171. package/dist/src/utils/views.d.ts +55 -0
  172. package/dist/src/utils/views.d.ts.map +1 -0
  173. package/dist/src/utils/views.js +72 -0
  174. package/dist/src/utils/views.js.map +1 -0
  175. package/dist/src/utils/vocabulary.d.ts +48 -0
  176. package/dist/src/utils/vocabulary.d.ts.map +1 -0
  177. package/dist/src/utils/vocabulary.js +47 -0
  178. package/dist/src/utils/vocabulary.js.map +1 -0
  179. package/dist/test/allocation/allocation.examples.d.ts +2 -0
  180. package/dist/test/allocation/allocation.examples.d.ts.map +1 -1
  181. package/dist/test/allocation/allocation.examples.js +81 -2
  182. package/dist/test/allocation/allocation.examples.js.map +1 -1
  183. package/dist/test/bind/func/func.examples.d.ts +19 -1
  184. package/dist/test/bind/func/func.examples.d.ts.map +1 -1
  185. package/dist/test/bind/func/func.examples.js +36 -1
  186. package/dist/test/bind/func/func.examples.js.map +1 -1
  187. package/dist/test/calendar/calendar.examples.d.ts +2 -0
  188. package/dist/test/calendar/calendar.examples.d.ts.map +1 -1
  189. package/dist/test/calendar/calendar.examples.js +80 -2
  190. package/dist/test/calendar/calendar.examples.js.map +1 -1
  191. package/dist/test/decision/queue.examples.d.ts +1 -0
  192. package/dist/test/decision/queue.examples.d.ts.map +1 -1
  193. package/dist/test/decision/queue.examples.js +12 -0
  194. package/dist/test/decision/queue.examples.js.map +1 -1
  195. package/dist/test/examples-package.d.ts.map +1 -1
  196. package/dist/test/examples-package.js +5 -4
  197. package/dist/test/examples-package.js.map +1 -1
  198. package/dist/test/flowchart/flowchart.examples.d.ts +1250 -4605
  199. package/dist/test/flowchart/flowchart.examples.d.ts.map +1 -1
  200. package/dist/test/flowchart/flowchart.examples.js +861 -512
  201. package/dist/test/flowchart/flowchart.examples.js.map +1 -1
  202. package/dist/test/ontology/ontology.examples.d.ts +2 -3
  203. package/dist/test/ontology/ontology.examples.d.ts.map +1 -1
  204. package/dist/test/ontology/ontology.examples.js +32 -21
  205. package/dist/test/ontology/ontology.examples.js.map +1 -1
  206. package/dist/test/plan/plan-events.examples.d.ts +1 -0
  207. package/dist/test/plan/plan-events.examples.d.ts.map +1 -1
  208. package/dist/test/plan/plan-events.examples.js +44 -0
  209. package/dist/test/plan/plan-events.examples.js.map +1 -1
  210. package/dist/test/plan/plan-nested.examples.d.ts +2 -2
  211. package/dist/test/plan/plan-nested.examples.js +5 -5
  212. package/dist/test/plan/plan-nested.examples.js.map +1 -1
  213. package/dist/test/plan/plan-records.examples.d.ts.map +1 -1
  214. package/dist/test/plan/plan-records.examples.js +1 -1
  215. package/dist/test/plan/plan-records.examples.js.map +1 -1
  216. package/dist/test/query/query.examples.d.ts +2 -0
  217. package/dist/test/query/query.examples.d.ts.map +1 -1
  218. package/dist/test/query/query.examples.js +37 -1
  219. package/dist/test/query/query.examples.js.map +1 -1
  220. package/dist/test/roster/roster.examples.d.ts +2 -0
  221. package/dist/test/roster/roster.examples.d.ts.map +1 -1
  222. package/dist/test/roster/roster.examples.js +76 -15
  223. package/dist/test/roster/roster.examples.js.map +1 -1
  224. package/dist/test/schematic/schematic-records.examples.d.ts.map +1 -1
  225. package/dist/test/schematic/schematic-records.examples.js +6 -4
  226. package/dist/test/schematic/schematic-records.examples.js.map +1 -1
  227. package/dist/test/schematic/schematic.examples.d.ts +1 -0
  228. package/dist/test/schematic/schematic.examples.d.ts.map +1 -1
  229. package/dist/test/schematic/schematic.examples.js +144 -0
  230. package/dist/test/schematic/schematic.examples.js.map +1 -1
  231. package/dist/test/sheet/sheet-actions.examples.d.ts +1264 -0
  232. package/dist/test/sheet/sheet-actions.examples.d.ts.map +1 -0
  233. package/dist/test/sheet/sheet-actions.examples.js +394 -0
  234. package/dist/test/sheet/sheet-actions.examples.js.map +1 -0
  235. package/dist/test/sheet/sheet.examples.d.ts +1 -0
  236. package/dist/test/sheet/sheet.examples.d.ts.map +1 -1
  237. package/dist/test/sheet/sheet.examples.js +77 -0
  238. package/dist/test/sheet/sheet.examples.js.map +1 -1
  239. package/dist/test/studio/studio.examples.d.ts +1 -0
  240. package/dist/test/studio/studio.examples.d.ts.map +1 -1
  241. package/dist/test/studio/studio.examples.js +18 -8
  242. package/dist/test/studio/studio.examples.js.map +1 -1
  243. package/package.json +12 -12
  244. package/dist/src/diff/index.d.ts +0 -407
  245. package/dist/src/diff/index.d.ts.map +0 -1
  246. package/dist/src/diff/index.js +0 -203
  247. package/dist/src/diff/index.js.map +0 -1
  248. package/dist/src/experiment/index.d.ts +0 -1033
  249. package/dist/src/experiment/index.d.ts.map +0 -1
  250. package/dist/src/experiment/index.js +0 -197
  251. package/dist/src/experiment/index.js.map +0 -1
  252. package/dist/src/experiment/types.d.ts +0 -1093
  253. package/dist/src/experiment/types.d.ts.map +0 -1
  254. package/dist/src/experiment/types.js +0 -423
  255. package/dist/src/experiment/types.js.map +0 -1
  256. package/dist/src/flowchart/over.d.ts +0 -227
  257. package/dist/src/flowchart/over.d.ts.map +0 -1
  258. package/dist/src/flowchart/over.js +0 -213
  259. package/dist/src/flowchart/over.js.map +0 -1
  260. package/dist/src/flowchart/patch.d.ts +0 -64
  261. package/dist/src/flowchart/patch.d.ts.map +0 -1
  262. package/dist/src/flowchart/patch.js +0 -67
  263. package/dist/src/flowchart/patch.js.map +0 -1
  264. package/dist/src/flowchart/values.d.ts +0 -271
  265. package/dist/src/flowchart/values.d.ts.map +0 -1
  266. package/dist/src/flowchart/values.js +0 -220
  267. package/dist/src/flowchart/values.js.map +0 -1
  268. package/dist/src/flowchart/window.d.ts +0 -306
  269. package/dist/src/flowchart/window.d.ts.map +0 -1
  270. package/dist/src/flowchart/window.js +0 -63
  271. package/dist/src/flowchart/window.js.map +0 -1
  272. package/dist/src/runtime/diff.d.ts +0 -36
  273. package/dist/src/runtime/diff.d.ts.map +0 -1
  274. package/dist/src/runtime/diff.js +0 -34
  275. package/dist/src/runtime/diff.js.map +0 -1
  276. package/dist/src/runtime/experiment.d.ts +0 -48
  277. package/dist/src/runtime/experiment.d.ts.map +0 -1
  278. package/dist/src/runtime/experiment.js +0 -10
  279. package/dist/src/runtime/experiment.js.map +0 -1
  280. package/dist/test/diff/diff.examples.d.ts +0 -313
  281. package/dist/test/diff/diff.examples.d.ts.map +0 -1
  282. package/dist/test/diff/diff.examples.js +0 -452
  283. package/dist/test/diff/diff.examples.js.map +0 -1
  284. package/dist/test/experiment/experiment.examples.d.ts +0 -1512
  285. package/dist/test/experiment/experiment.examples.d.ts.map +0 -1
  286. package/dist/test/experiment/experiment.examples.js +0 -609
  287. package/dist/test/experiment/experiment.examples.js.map +0 -1
@@ -4,578 +4,927 @@ import { jsx as _jsx, jsxs as _jsxs } from "@elaraai/e3-ui/jsx-runtime";
4
4
  * Dual-licensed under AGPL-3.0 and commercial license. See LICENSE for details.
5
5
  */
6
6
  /** @jsxImportSource @elaraai/e3-ui */
7
- import { ArrayType, BooleanType, DateTimeType, DictType, East, FloatType, FunctionType, IntegerType, NullType, OptionType, PatchType, SetType, StringType, StructType, example, none, some, variant, } from "@elaraai/east";
8
- import { Badge, Box, Button, Configurator, Editing, HStack, Reactive, Slice, State, Switch, Text, UIComponentType, VStack } from "@elaraai/east-ui";
7
+ import { ArrayType, DateTimeType, DictType, East, FloatType, IntegerType, NullType, OptionType, PatchType, SetType, StringType, StructType, VariantType, example, none, some, variant, } from "@elaraai/east";
8
+ import { Badge, Box, Fields, Reactive, Slice, State, UIComponentType, VStack } from "@elaraai/east-ui";
9
9
  import { Data, Flowchart, Record } from "@elaraai/e3-ui";
10
10
  import e3 from "@elaraai/e3";
11
11
  // ============================================================================
12
- // The Flowchart's examples (#1251): the one `<Flowchart>`, each in its frame —
13
- // one toolbar holding every control the flowchart has, the banners, the open
14
- // flow's canvas in main, the footer, and the panes it is given. The slots of
15
- // EXAMPLES_AUTHORING.md §8, few and full (FB40):
12
+ // The Flowchart's examples (#1500, `Flowchart Records Spec.md` §2): one
13
+ // flowchart over the app's records — its states and its transitions, and
14
+ // beside them its lanes and its decisions, each a record of the app's keyed by
15
+ // String, its rows the app's own type and its fields mapped to the
16
+ // Flowchart's roles. No record here holds a type of the Flowchart's.
16
17
  //
17
- // - `flowchartFlows`, the front door: a record of the depot's flows by name,
18
- // and its Flows tab (§3.1);
19
- // - `flowchartVariants`, THE configurator: the legend, the minimap and read
20
- // only as axes over the host's flows (`data`), which its `onApply` commits,
21
- // the selection and a traced path heard in its aside;
22
- // - `flowchartLibrary`, the depot's flows (§3.3): the Flows tab, the step and
23
- // transition templates and the decisions' owners, each a record of its own
24
- // that one rail narrows, each card dropped on the canvas;
25
- // - `flowchartDepot`, a flow from the host's tables (§3.4): decisions,
26
- // evidence, a state class, an in-place transition and an unresolved one,
27
- // read only;
28
- // - `flowchartHandover`, the host's one flow, top down, with no pane;
29
- // - `flowchartDetail`, a record's one flow edited on the canvas, a
30
- // connection veto, and a state's and a transition's own Details.
18
+ // - `flowchartDwell`, the front door: the states, the transitions and the
19
+ // lanes, three records read whole, read only, and each state's time in
20
+ // state on its card — one histogram, read from the app's own rows;
21
+ // - `flowchartDepot`, the depot in full: the states and the transitions read
22
+ // through their sources of the rail and edited through their patch doors, a
23
+ // preset narrowing both to one flow; the lanes and the decisions read
24
+ // whole; both kinds' details on the cards, the labels, the legend and the
25
+ // inspector, read by the drawn rows' keys; the services the rail picks
26
+ // weighing the states' details, each read their own figures hold added up
27
+ // by kind; and the library's Steps, Transitions, Lanes and Owners tabs, each
28
+ // list of cards following its own source;
29
+ // - `flowchartDepotEditing`, the four records bound editable and read whole,
30
+ // and the app's check on a drafted state;
31
+ // - `flowchartDepotDimmed`, the rail's choices drawn as context: every row
32
+ // read through its source, those the narrowing leaves out faded, and the
33
+ // states' details read by key, opening weighed by one service: Held's time
34
+ // in state its international parcels' own, and the returns' states, which
35
+ // hold none, saying no data;
36
+ // - `flowchartDepotPhone`, the depot at a phone's width: its cards keep their
37
+ // bars and lines, and the canvas pans a lane at a time;
38
+ // - `flowchartDepotTopDown`, the depot read only and top down, its minimap
39
+ // drawn, no pane, and each selection and traced path heard by the host;
40
+ // - `flowchartWording`, the depot in its own words (#1516): each kind named by
41
+ // its own `name`, and `vocabulary` naming a transition's planned and
42
+ // observed kinds;
43
+ // - `flowchartFlagColors`, each state's flags as tags on its card and in the
44
+ // legend, their looks read from the app's own data;
45
+ // - `flowchartTicketMinutes`, a support desk's minutes in state on each card,
46
+ // counted into the app's own uneven bins, the axis naming the edges it lists;
47
+ // - `flowchartTicketMinutesLinear`, the same bins drawn to scale: each bar as
48
+ // wide as its span and as tall as its count over it.
31
49
  //
32
- // Its panes are optional props, and the examples show each combination: none
33
- // (`flowchartHandover`), a library (`flowchartVariants`), an inspector
34
- // (`flowchartDepot`, read only; `flowchartDetail`, its own Details), and both
35
- // (`flowchartFlows`, `flowchartLibrary`). Between them, one flow
36
- // (`flowchartHandover`, `flowchartDepot`, `flowchartDetail`) and many
37
- // (`flowchartFlows`, `flowchartVariants`, `flowchartLibrary`).
38
- //
39
- // Every flowchart binds its flows from e3, so each runs on e3-web in the
40
- // showcase (§2a): a record of flows written with `Flowchart.values`, whose
41
- // patch mutation every Save commits through; an input of one flow written
42
- // with `Flowchart.value`; or the host's tables, each an input. A flowchart's
43
- // narrowing is one `Slice.bindRecords` (#1346): a `flows` source over a record
44
- // of flows narrows the Flows tab, which pages it, and each other source the
45
- // templates list or the tab that names it; the host's tables are never
46
- // narrowed. `State` holds only what the viewer owns: the configurator's axes
47
- // and what it heard.
48
- //
49
- // A flowchart fills its parent, as a ui task's page fills the window: each
50
- // example gives it a box of its own height. One page shows them all, so every
51
- // flowchart but the first is named (`name`), and keeps its viewer's state
52
- // apart.
50
+ // Each binds its records from e3, so the showcase draws each on e3-web. A
51
+ // flowchart fills its parent, as a ui task's page fills the window: each
52
+ // example gives it a box of its own height, and its own `name`, which keeps
53
+ // its viewer's state apart on a page showing them all. Every figure is made
54
+ // up.
53
55
  // ============================================================================
54
- // The depot's flows, by name: each a whole flowchart, written as literals and
55
- // checked when the package builds.
56
- export const depotFlows = e3.record("flowchart_depot_flows", Flowchart.Types.Flows, {
57
- initial: Flowchart.values({
58
- "Inbound parcels": {
59
- description: "From the trailer to the van",
60
- lanes: [{ key: "intake", label: "Intake" }, { key: "sort", label: "Sort" }, { key: "load", label: "Load" }],
61
- states: [
62
- { key: "ARV", label: "Arrived", lane: "intake" },
63
- { key: "SCN", label: "Scanned", lane: "intake" },
64
- { key: "CH*", label: "Sort chutes", lane: "sort", members: 12n },
65
- { key: "LDD", label: "Loaded", lane: "load" },
66
- ],
67
- links: [
68
- { from: "ARV", to: "SCN" },
69
- { from: "SCN", to: "CH*", trigger: "route" },
70
- { from: "CH*", to: "LDD" },
71
- { from: "SCN", to: "SCN", kind: "observed" },
72
- ],
73
- triggers: [{ key: "route", label: "route", owner: "sort-planner" }],
74
- },
75
- "Returns": {
76
- description: "From the counter back to the sender",
77
- lanes: [{ key: "counter", label: "Counter" }, { key: "check", label: "Check" }, { key: "out", label: "Out" }],
78
- states: [
79
- { key: "RCV", label: "Received", lane: "counter" },
80
- { key: "INS", label: "Inspected", lane: "check" },
81
- { key: "RSD", label: "Resent", lane: "out" },
82
- ],
83
- links: [{ from: "RCV", to: "INS" }, { from: "INS", to: "RSD" }, { from: "INS", to: "BIN", kind: "observed" }],
84
- },
85
- }),
86
- mutations: (mutation) => ({
87
- patch: mutation.patch(),
88
- }),
56
+ // The depot's states, transitions, lanes and decisions: four records of the app's, keyed by String. A state's key
57
+ // is its code; a transition names its ends by their keys and its decision by the decision's, and a state its lane by
58
+ // the lane's.
59
+ export const DepotState = StructType({
60
+ name: StringType, // what its card calls it
61
+ phase: StringType, // the lane it stands in, by the lane's key
62
+ seq: FloatType, // its place in its lane
63
+ slots: OptionType(IntegerType), // a class of interchangeable states: the ×N badge
64
+ flow: StringType, // the flow it belongs to: one record holds the depot's flows
89
65
  });
90
- // A lone flow, edited on the canvas: a record of flows with one entry, bound
91
- // with its patch mutation.
92
- export const collectionFlows = e3.record("flowchart_collection_flows", Flowchart.Types.Flows, {
93
- initial: Flowchart.values({
94
- "Collections": {
95
- description: "From the booking to the depot's door",
96
- lanes: [{ key: "book", label: "Book" }, { key: "van", label: "Van" }, { key: "depot", label: "Depot" }],
97
- states: [
98
- { key: "BKD", label: "Booked", lane: "book" },
99
- { key: "CLD", label: "Collected", lane: "van" },
100
- { key: "RCV", label: "Received", lane: "depot" },
101
- ],
102
- links: [{ key: "BKD→CLD", from: "BKD", to: "CLD" }, { key: "CLD→RCV", from: "CLD", to: "RCV" }],
103
- },
104
- }),
105
- mutations: (mutation) => ({
106
- patch: mutation.patch(),
66
+ export const DepotTransition = StructType({
67
+ src: StringType, // the state it leaves, by its key
68
+ dst: StringType, // the state it enters
69
+ kind: VariantType({ planned: NullType, observed: NullType }),
70
+ trigger: OptionType(StringType), // the decision that governs it, by its key
71
+ volume: OptionType(FloatType), // the parcels measured on it
72
+ n: OptionType(IntegerType), // the moves behind them
73
+ at: OptionType(DateTimeType), // when they were measured
74
+ flow: StringType,
75
+ });
76
+ export const DepotLane = StructType({ label: StringType, seq: FloatType });
77
+ export const DepotDecision = StructType({ name: StringType, owner: StringType });
78
+ export const depotStates = e3.record("flowchart_depot_states", DictType(StringType, DepotState), {
79
+ initial: new Map([
80
+ ["ARV", { name: "Arrived", phase: "intake", seq: 1, slots: none, flow: "Parcels" }],
81
+ ["SCN", { name: "Scanned", phase: "intake", seq: 2, slots: none, flow: "Parcels" }],
82
+ ["IND", { name: "Inducted", phase: "induct", seq: 1, slots: none, flow: "Parcels" }],
83
+ ["LBL", { name: "Relabelled", phase: "induct", seq: 2, slots: none, flow: "Parcels" }],
84
+ ["CH*", { name: "Sort chutes (class)", phase: "sort", seq: 1, slots: some(14n), flow: "Parcels" }],
85
+ ["SRD", { name: "Sorted", phase: "sort", seq: 2, slots: none, flow: "Parcels" }],
86
+ ["HLD", { name: "Held", phase: "hold", seq: 1, slots: none, flow: "Parcels" }],
87
+ ["CLR", { name: "Cleared", phase: "hold", seq: 2, slots: none, flow: "Parcels" }],
88
+ ["LDD", { name: "Loaded", phase: "dispatch", seq: 1, slots: none, flow: "Parcels" }],
89
+ ["DSP", { name: "Dispatched", phase: "dispatch", seq: 2, slots: none, flow: "Parcels" }],
90
+ // The returns flow's states, beside the parcels'.
91
+ ["RCV", { name: "Received", phase: "intake", seq: 3, slots: none, flow: "Returns" }],
92
+ ["INS", { name: "Inspected", phase: "hold", seq: 3, slots: none, flow: "Returns" }],
93
+ ["RSD", { name: "Resent", phase: "dispatch", seq: 3, slots: none, flow: "Returns" }],
94
+ ]),
95
+ mutations: (mutation) => ({ patch: mutation.patch() }),
96
+ indexes: (index) => ({
97
+ flowchart_states_by_flow: index.on(["flow"]),
98
+ flowchart_states_by_lane: index.on(["flow", "phase"]),
107
99
  }),
108
100
  });
109
- // One flow, for an app that has only one: the host's, read only.
110
- export const handoverFlow = e3.input("flowchart_handover", Flowchart.Types.Flow, variant("value", Flowchart.value({
111
- description: "From the last scan to the driver's signature",
112
- lanes: [{ key: "load", label: "Load" }, { key: "road", label: "Road" }, { key: "door", label: "Door" }],
113
- states: [
114
- { key: "LDD", label: "Loaded", lane: "load" },
115
- { key: "DSP", label: "Dispatched", lane: "road" },
116
- { key: "DLV", label: "Delivered", lane: "door" },
117
- { key: "RTN", label: "Returned", lane: "door" },
118
- ],
119
- links: [
120
- { from: "LDD", to: "DSP" },
121
- { from: "DSP", to: "DLV", trigger: "attempt" },
122
- { from: "DSP", to: "RTN", kind: "observed", trigger: "attempt" },
123
- ],
124
- triggers: [{ key: "attempt", label: "attempt", owner: "driver" }],
125
- })));
126
- // The library's records (#1248, #1346): each tab its own bound data, apart
127
- // from the flows and from the other tabs — the step types by code, the
128
- // transition types by name and the roles that own a decision, each a record
129
- // of its own, its cards its rows by key, and each indexed on the field the
130
- // rail narrows it by.
131
- export const StepTemplate = StructType({ name: StringType, kind: StringType, slots: OptionType(IntegerType) });
132
- export const stepTemplates = e3.record("flowchart_step_templates", DictType(StringType, StepTemplate), {
101
+ export const depotTransitions = e3.record("flowchart_depot_transitions", DictType(StringType, DepotTransition), {
133
102
  initial: new Map([
134
- ["ARV", { name: "Arrived", kind: "Intake", slots: none }],
135
- ["SCN", { name: "Scanned", kind: "Intake", slots: none }],
136
- ["CH*", { name: "Sort chutes", kind: "Sort", slots: some(12n) }],
137
- ["HLD", { name: "Held", kind: "Hold", slots: none }],
138
- ["LDD", { name: "Loaded", kind: "Load", slots: none }],
103
+ ["l1", { src: "ARV", dst: "SCN", kind: variant("planned", null), trigger: none, volume: some(18460), n: some(412n), at: some(new Date("2026-06-30T00:00:00Z")), flow: "Parcels" }],
104
+ ["l2", { src: "SCN", dst: "IND", kind: variant("planned", null), trigger: none, volume: some(18390), n: some(409n), at: some(new Date("2026-06-30T00:00:00Z")), flow: "Parcels" }],
105
+ // In place: parcels inducted again, counted but not weighed.
106
+ ["l3", { src: "IND", dst: "IND", kind: variant("observed", null), trigger: none, volume: none, n: some(2n), at: some(new Date("2026-06-30T00:00:00Z")), flow: "Parcels" }],
107
+ ["l4", { src: "IND", dst: "CH*", kind: variant("planned", null), trigger: some("route"), volume: some(17350), n: some(386n), at: some(new Date("2026-06-30T00:00:00Z")), flow: "Parcels" }],
108
+ ["l5", { src: "CH*", dst: "SRD", kind: variant("planned", null), trigger: none, volume: some(18210), n: some(405n), at: some(new Date("2026-06-30T00:00:00Z")), flow: "Parcels" }],
109
+ ["l6", { src: "SRD", dst: "HLD", kind: variant("planned", null), trigger: none, volume: some(8420), n: some(188n), at: some(new Date("2026-06-30T00:00:00Z")), flow: "Parcels" }],
110
+ ["l7", { src: "HLD", dst: "CLR", kind: variant("planned", null), trigger: some("customs"), volume: some(8350), n: some(186n), at: some(new Date("2026-06-30T00:00:00Z")), flow: "Parcels" }],
111
+ ["l8", { src: "CLR", dst: "LDD", kind: variant("planned", null), trigger: none, volume: some(8240), n: some(183n), at: some(new Date("2026-06-30T00:00:00Z")), flow: "Parcels" }],
112
+ ["l9", { src: "LDD", dst: "DSP", kind: variant("planned", null), trigger: none, volume: some(17030), n: some(378n), at: some(new Date("2026-06-30T00:00:00Z")), flow: "Parcels" }],
113
+ // Its far end names a state no row is keyed by: drawn as a ghost, and listed in Issues.
114
+ ["l10", { src: "DSP", dst: "DLV", kind: variant("planned", null), trigger: none, volume: none, n: none, at: none, flow: "Parcels" }],
115
+ // Observed, not planned: parcels relabelled before they are sorted.
116
+ ["l11", { src: "IND", dst: "LBL", kind: variant("observed", null), trigger: none, volume: some(980), n: some(22n), at: some(new Date("2026-06-30T00:00:00Z")), flow: "Parcels" }],
117
+ ["l12", { src: "LBL", dst: "CH*", kind: variant("observed", null), trigger: none, volume: some(975), n: some(22n), at: some(new Date("2026-06-30T00:00:00Z")), flow: "Parcels" }],
118
+ ["l13", { src: "SRD", dst: "LDD", kind: variant("planned", null), trigger: none, volume: some(8790), n: some(195n), at: some(new Date("2026-06-30T00:00:00Z")), flow: "Parcels" }],
119
+ ["r1", { src: "RCV", dst: "INS", kind: variant("planned", null), trigger: none, volume: some(640), n: some(15n), at: some(new Date("2026-06-30T00:00:00Z")), flow: "Returns" }],
120
+ ["r2", { src: "INS", dst: "RSD", kind: variant("planned", null), trigger: none, volume: some(610), n: some(14n), at: some(new Date("2026-06-30T00:00:00Z")), flow: "Returns" }],
139
121
  ]),
122
+ mutations: (mutation) => ({ patch: mutation.patch() }),
140
123
  indexes: (index) => ({
141
- flowchart_steps_by_kind: index.on(["kind"]),
124
+ flowchart_transitions_by_flow: index.on(["flow"]),
142
125
  }),
126
+ });
127
+ export const depotLanes = e3.record("flowchart_depot_lanes", DictType(StringType, DepotLane), {
128
+ initial: new Map([
129
+ ["intake", { label: "Intake", seq: 1 }], ["induct", { label: "Induct", seq: 2 }], ["sort", { label: "Sort", seq: 3 }],
130
+ ["hold", { label: "Hold", seq: 4 }], ["dispatch", { label: "Dispatch", seq: 5 }],
131
+ ]),
132
+ mutations: (mutation) => ({ patch: mutation.patch() }),
133
+ });
134
+ export const depotDecisions = e3.record("flowchart_depot_decisions", DictType(StringType, DepotDecision), {
135
+ initial: new Map([["route", { name: "route", owner: "sort-planner" }], ["customs", { name: "customs", owner: "customs-desk" }]]),
136
+ mutations: (mutation) => ({ patch: mutation.patch() }),
137
+ });
138
+ // Two records a flowchart can bind beside the depot's: its lanes as the sort plan fixes them, whose door refuses every
139
+ // change; and its decisions with the states queued at each.
140
+ /** The depot's lanes as the sort plan fixes them: the same lanes, which no Save changes. */
141
+ export const depotFixedLanes = e3.record("flowchart_depot_fixed_lanes", DictType(StringType, DepotLane), {
142
+ initial: new Map([
143
+ ["intake", { label: "Intake", seq: 1 }], ["induct", { label: "Induct", seq: 2 }], ["sort", { label: "Sort", seq: 3 }],
144
+ ["hold", { label: "Hold", seq: 4 }], ["dispatch", { label: "Dispatch", seq: 5 }],
145
+ ]),
143
146
  mutations: (mutation) => ({
144
- // The step types' patch door: what another writer adds a step type through, the Steps tab's cards following.
145
- patch: mutation.patch(),
147
+ // A checked door: it refuses every change, naming why — what a Save over these lanes is answered.
148
+ patch: mutation.reduce(East.function([DictType(StringType, DepotLane), PatchType(DictType(StringType, DepotLane))], DictType(StringType, DepotLane), ($, lanes, _patch) => {
149
+ $.error("the lanes are fixed by the sort plan");
150
+ return lanes;
151
+ })),
146
152
  }),
147
153
  });
148
- export const MoveTemplate = StructType({ kind: Flowchart.Types.Kind, decision: OptionType(StringType), note: StringType });
149
- export const moveTemplates = e3.record("flowchart_move_templates", DictType(StringType, MoveTemplate), {
154
+ /** A decision with the states queued at it, by key: a state's Del takes its key out of the queue. */
155
+ export const DepotQueuedDecision = StructType({ name: StringType, owner: StringType, queue: ArrayType(StringType) });
156
+ export const depotQueuedDecisions = e3.record("flowchart_depot_queued_decisions", DictType(StringType, DepotQueuedDecision), {
150
157
  initial: new Map([
151
- ["Observed", { kind: variant("observed", null), decision: none, note: "Mined from the scans" }],
152
- ["Planned", { kind: variant("planned", null), decision: none, note: "The designed path" }],
153
- ["Routed", { kind: variant("planned", null), decision: some("route"), note: "Governed by the route decision" }],
158
+ ["route", { name: "route", owner: "sort-planner", queue: ["IND", "SRD"] }],
159
+ ["customs", { name: "customs", owner: "customs-desk", queue: ["HLD"] }],
154
160
  ]),
155
- indexes: (index) => ({
156
- flowchart_moves_by_kind: index.on(["kind"]),
157
- }),
161
+ mutations: (mutation) => ({ patch: mutation.patch() }),
158
162
  });
159
- export const DecisionOwner = StructType({ name: StringType, desk: StringType });
160
- export const decisionOwners = e3.record("flowchart_decision_owners", DictType(StringType, DecisionOwner), {
163
+ // What one service's parcels did in a state: the same figures as the state's own, for that service alone.
164
+ export const ServiceEvidence = StructType({
165
+ flags: SetType(StringType), // what the app's task flags this service's parcels with
166
+ parcels: IntegerType, // its parcels through the state
167
+ waiting: IntegerType, // still in it when measured
168
+ hours: ArrayType(IntegerType), // its parcels by time in state: a count a bin, in the bins' order
169
+ exceptions: DictType(StringType, IntegerType), // its parcels by what went wrong
170
+ });
171
+ // What the depot measured in each state and on each transition: the app's own rows, keyed as the states and
172
+ // the transitions are, written by its evidence task through each record's door.
173
+ export const StateEvidence = StructType({
174
+ flags: SetType(StringType), // what the app's task flags the state with
175
+ equipment: SetType(StringType), // what handles parcels there
176
+ shifts: SetType(StringType), // the shifts that staff it
177
+ parcels: IntegerType, // through the state
178
+ waiting: IntegerType, // still in it when measured
179
+ hours: ArrayType(IntegerType), // parcels by time in state: a count a bin, in the bins' order
180
+ service: DictType(StringType, IntegerType), // parcels by service
181
+ exceptions: DictType(StringType, IntegerType), // parcels by what went wrong
182
+ byService: DictType(StringType, ServiceEvidence), // each service's own: Standard, Priority, Economy, International
183
+ });
184
+ export const MoveEvidence = StructType({
185
+ region: DictType(StringType, IntegerType),
186
+ service: DictType(StringType, IntegerType),
187
+ origins: DictType(StringType, StructType({ parcels: IntegerType, late: IntegerType })),
188
+ });
189
+ // What the evidence task last wrote, made up: a row a state but Dispatched, whose card says no data. Each row
190
+ // files each service's own figures apart, which add up to its own: their parcels are its Service list's counts,
191
+ // their waiting adds to its waiting, their hours bin by bin to its hours, their exceptions by name to its
192
+ // exceptions, and their flags join to its flags. The returns take no international parcels: their states hold no
193
+ // International entry.
194
+ export const stateEvidence = e3.record("flowchart_depot_state_evidence", DictType(StringType, StateEvidence), {
161
195
  initial: new Map([
162
- ["sort-planner", { name: "Sort planner", desk: "Sort hall" }],
163
- ["customs-desk", { name: "Customs desk", desk: "Hold bay" }],
196
+ ["ARV", {
197
+ flags: new Set(), equipment: new Set(["Conveyor"]), shifts: new Set(["Early", "Late", "Night"]),
198
+ parcels: 18460n, waiting: 60n,
199
+ hours: [5538n, 6277n, 3692n, 1846n, 738n, 369n, 0n, 0n, 0n, 0n, 0n, 0n],
200
+ service: new Map([["Standard", 10337n], ["Priority", 4615n], ["Economy", 2400n], ["International", 1108n]]),
201
+ exceptions: new Map([["Late arrival", 52n], ["Damaged packaging", 11n]]),
202
+ byService: new Map([
203
+ ["Standard", { flags: new Set(), parcels: 10337n, waiting: 33n, hours: [3005n, 3534n, 2118n, 1062n, 417n, 201n, 0n, 0n, 0n, 0n, 0n, 0n], exceptions: new Map([["Late arrival", 26n], ["Damaged packaging", 6n]]) }],
204
+ ["Priority", { flags: new Set(), parcels: 4615n, waiting: 15n, hours: [1735n, 1637n, 788n, 316n, 100n, 39n, 0n, 0n, 0n, 0n, 0n, 0n], exceptions: new Map([["Late arrival", 11n], ["Damaged packaging", 3n]]) }],
205
+ ["Economy", { flags: new Set(), parcels: 2400n, waiting: 8n, hours: [589n, 781n, 528n, 298n, 132n, 72n, 0n, 0n, 0n, 0n, 0n, 0n], exceptions: new Map([["Late arrival", 12n], ["Damaged packaging", 1n]]) }],
206
+ ["International", { flags: new Set(), parcels: 1108n, waiting: 4n, hours: [209n, 325n, 258n, 170n, 89n, 57n, 0n, 0n, 0n, 0n, 0n, 0n], exceptions: new Map([["Late arrival", 3n], ["Damaged packaging", 1n]]) }],
207
+ ]),
208
+ }],
209
+ ["SCN", {
210
+ flags: new Set(["Fragile"]), equipment: new Set(["Scanner", "Conveyor"]), shifts: new Set(["Early", "Late", "Night"]),
211
+ parcels: 18390n, waiting: 35n,
212
+ hours: [7723n, 5701n, 2759n, 1471n, 552n, 184n, 0n, 0n, 0n, 0n, 0n, 0n],
213
+ service: new Map([["Standard", 10298n], ["Priority", 4598n], ["Economy", 2391n], ["International", 1103n]]),
214
+ exceptions: new Map([["Unreadable label", 61n], ["Damaged packaging", 9n]]),
215
+ byService: new Map([
216
+ ["Standard", { flags: new Set(["Fragile"]), parcels: 10298n, waiting: 20n, hours: [4236n, 3228n, 1584n, 842n, 309n, 99n, 0n, 0n, 0n, 0n, 0n, 0n], exceptions: new Map([["Unreadable label", 34n], ["Damaged packaging", 5n]]) }],
217
+ ["Priority", { flags: new Set(), parcels: 4598n, waiting: 9n, hours: [2307n, 1411n, 555n, 237n, 70n, 18n, 0n, 0n, 0n, 0n, 0n, 0n], exceptions: new Map([["Unreadable label", 15n], ["Damaged packaging", 2n]]) }],
218
+ ["Economy", { flags: new Set(), parcels: 2391n, waiting: 4n, hours: [860n, 739n, 409n, 245n, 101n, 37n, 0n, 0n, 0n, 0n, 0n, 0n], exceptions: new Map([["Unreadable label", 8n], ["Damaged packaging", 1n]]) }],
219
+ ["International", { flags: new Set(), parcels: 1103n, waiting: 2n, hours: [320n, 323n, 211n, 147n, 72n, 30n, 0n, 0n, 0n, 0n, 0n, 0n], exceptions: new Map([["Unreadable label", 4n], ["Damaged packaging", 1n]]) }],
220
+ ]),
221
+ }],
222
+ ["IND", {
223
+ flags: new Set(["Oversize", "Fragile"]), equipment: new Set(["Conveyor", "Scanner"]), shifts: new Set(["Early", "Late"]),
224
+ parcels: 18390n, waiting: 120n,
225
+ hours: [2207n, 4781n, 5517n, 3310n, 1655n, 736n, 184n, 0n, 0n, 0n, 0n, 0n],
226
+ service: new Map([["Standard", 10482n], ["Priority", 4414n], ["Economy", 2391n], ["International", 1103n]]),
227
+ exceptions: new Map([["Missort", 22n]]),
228
+ byService: new Map([
229
+ ["Standard", { flags: new Set(["Oversize", "Fragile"]), parcels: 10482n, waiting: 68n, hours: [1183n, 2685n, 3191n, 1939n, 964n, 419n, 101n, 0n, 0n, 0n, 0n, 0n], exceptions: new Map([["Missort", 13n]]) }],
230
+ ["Priority", { flags: new Set(), parcels: 4414n, waiting: 29n, hours: [750n, 1367n, 1303n, 635n, 254n, 88n, 17n, 0n, 0n, 0n, 0n, 0n], exceptions: new Map([["Missort", 5n]]) }],
231
+ ["Economy", { flags: new Set(["Oversize"]), parcels: 2391n, waiting: 16n, hours: [209n, 533n, 715n, 489n, 274n, 135n, 36n, 0n, 0n, 0n, 0n, 0n], exceptions: new Map([["Missort", 3n]]) }],
232
+ ["International", { flags: new Set(), parcels: 1103n, waiting: 7n, hours: [65n, 196n, 308n, 247n, 163n, 94n, 30n, 0n, 0n, 0n, 0n, 0n], exceptions: new Map([["Missort", 1n]]) }],
233
+ ]),
234
+ }],
235
+ ["LBL", {
236
+ flags: new Set(["At risk"]), equipment: new Set(["Label printer", "Scanner"]), shifts: new Set(["Late"]),
237
+ parcels: 980n, waiting: 15n,
238
+ hours: [20n, 59n, 137n, 255n, 273n, 157n, 59n, 20n, 0n, 0n, 0n, 0n],
239
+ service: new Map([["Standard", 471n], ["Priority", 294n], ["Economy", 137n], ["International", 78n]]),
240
+ exceptions: new Map([["Unreadable label", 712n], ["Address check", 268n]]),
241
+ byService: new Map([
242
+ ["Standard", { flags: new Set(), parcels: 471n, waiting: 7n, hours: [9n, 25n, 63n, 123n, 135n, 78n, 29n, 9n, 0n, 0n, 0n, 0n], exceptions: new Map([["Unreadable label", 342n], ["Address check", 129n]]) }],
243
+ ["Priority", { flags: new Set(["At risk"]), parcels: 294n, waiting: 5n, hours: [10n, 27n, 53n, 83n, 74n, 34n, 10n, 3n, 0n, 0n, 0n, 0n], exceptions: new Map([["Unreadable label", 214n], ["Address check", 80n]]) }],
244
+ ["Economy", { flags: new Set(), parcels: 137n, waiting: 2n, hours: [1n, 5n, 15n, 33n, 41n, 27n, 11n, 4n, 0n, 0n, 0n, 0n], exceptions: new Map([["Unreadable label", 99n], ["Address check", 38n]]) }],
245
+ ["International", { flags: new Set(), parcels: 78n, waiting: 1n, hours: [0n, 2n, 6n, 16n, 23n, 18n, 9n, 4n, 0n, 0n, 0n, 0n], exceptions: new Map([["Unreadable label", 57n], ["Address check", 21n]]) }],
246
+ ]),
247
+ }],
248
+ ["CH*", {
249
+ flags: new Set(["At risk"]), equipment: new Set(["Conveyor", "Scanner"]), shifts: new Set(["Early", "Late", "Night", "Weekend"]),
250
+ parcels: 18290n, waiting: 140n,
251
+ hours: [1463n, 4024n, 6218n, 4024n, 1646n, 732n, 183n, 0n, 0n, 0n, 0n, 0n],
252
+ service: new Map([["Standard", 10425n], ["Priority", 4390n], ["Economy", 2378n], ["International", 1097n]]),
253
+ exceptions: new Map([["Missort", 41n], ["Chute full", 26n]]),
254
+ byService: new Map([
255
+ ["Standard", { flags: new Set(), parcels: 10425n, waiting: 80n, hours: [776n, 2242n, 3579n, 2350n, 960n, 418n, 100n, 0n, 0n, 0n, 0n, 0n], exceptions: new Map([["Missort", 23n], ["Chute full", 15n]]) }],
256
+ ["Priority", { flags: new Set(["At risk"]), parcels: 4390n, waiting: 34n, hours: [512n, 1186n, 1519n, 801n, 262n, 92n, 18n, 0n, 0n, 0n, 0n, 0n], exceptions: new Map([["Missort", 10n], ["Chute full", 6n]]) }],
257
+ ["Economy", { flags: new Set(), parcels: 2378n, waiting: 18n, hours: [134n, 438n, 787n, 583n, 268n, 132n, 36n, 0n, 0n, 0n, 0n, 0n], exceptions: new Map([["Missort", 5n], ["Chute full", 3n]]) }],
258
+ ["International", { flags: new Set(), parcels: 1097n, waiting: 8n, hours: [41n, 158n, 333n, 290n, 156n, 90n, 29n, 0n, 0n, 0n, 0n, 0n], exceptions: new Map([["Missort", 3n], ["Chute full", 2n]]) }],
259
+ ]),
260
+ }],
261
+ ["SRD", {
262
+ flags: new Set(["Fragile"]), equipment: new Set(["Conveyor"]), shifts: new Set(["Early", "Late"]),
263
+ parcels: 17210n, waiting: 50n,
264
+ hours: [861n, 2065n, 4303n, 4818n, 3098n, 1377n, 516n, 172n, 0n, 0n, 0n, 0n],
265
+ service: new Map([["Standard", 9981n], ["Priority", 4303n], ["Economy", 2065n], ["International", 861n]]),
266
+ exceptions: new Map([["Missort", 14n], ["Damaged packaging", 6n]]),
267
+ byService: new Map([
268
+ ["Standard", { flags: new Set(["Fragile"]), parcels: 9981n, waiting: 29n, hours: [441n, 1128n, 2467n, 2852n, 1863n, 827n, 305n, 98n, 0n, 0n, 0n, 0n], exceptions: new Map([["Missort", 8n], ["Damaged packaging", 3n]]) }],
269
+ ["Priority", { flags: new Set(), parcels: 4303n, waiting: 12n, hours: [341n, 701n, 1230n, 1141n, 598n, 213n, 63n, 16n, 0n, 0n, 0n, 0n], exceptions: new Map([["Missort", 3n], ["Damaged packaging", 2n]]) }],
270
+ ["Economy", { flags: new Set(), parcels: 2065n, waiting: 6n, hours: [63n, 183n, 453n, 591n, 434n, 218n, 90n, 33n, 0n, 0n, 0n, 0n], exceptions: new Map([["Missort", 2n], ["Damaged packaging", 1n]]) }],
271
+ ["International", { flags: new Set(), parcels: 861n, waiting: 3n, hours: [16n, 53n, 153n, 234n, 203n, 119n, 58n, 25n, 0n, 0n, 0n, 0n], exceptions: new Map([["Missort", 1n]]) }],
272
+ ]),
273
+ }],
274
+ ["HLD", {
275
+ flags: new Set(["Customs", "Hazmat", "At risk", "Cold chain", "Oversize"]), equipment: new Set(["Forklift", "X-ray", "Scanner"]), shifts: new Set(["Early", "Late"]),
276
+ parcels: 1080n, waiting: 70n,
277
+ hours: [0n, 11n, 22n, 54n, 97n, 151n, 183n, 162n, 173n, 130n, 65n, 32n],
278
+ service: new Map([["Standard", 335n], ["Priority", 130n], ["Economy", 76n], ["International", 539n]]),
279
+ exceptions: new Map([["Missing documents", 412n], ["Duty unpaid", 236n], ["Address check", 98n], ["Damaged packaging", 44n]]),
280
+ byService: new Map([
281
+ ["Standard", { flags: new Set(["Oversize"]), parcels: 335n, waiting: 22n, hours: [0n, 4n, 9n, 22n, 39n, 57n, 63n, 50n, 45n, 29n, 12n, 5n], exceptions: new Map([["Missing documents", 28n], ["Duty unpaid", 11n], ["Address check", 30n], ["Damaged packaging", 14n]]) }],
282
+ ["Priority", { flags: new Set(["At risk", "Cold chain"]), parcels: 130n, waiting: 8n, hours: [0n, 5n, 8n, 15n, 22n, 26n, 23n, 14n, 10n, 5n, 2n, 0n], exceptions: new Map([["Missing documents", 11n], ["Duty unpaid", 4n], ["Address check", 12n], ["Damaged packaging", 5n]]) }],
283
+ ["Economy", { flags: new Set(["Hazmat", "Oversize"]), parcels: 76n, waiting: 5n, hours: [0n, 1n, 1n, 3n, 7n, 11n, 14n, 12n, 12n, 9n, 4n, 2n], exceptions: new Map([["Missing documents", 7n], ["Duty unpaid", 3n], ["Address check", 7n], ["Damaged packaging", 3n]]) }],
284
+ ["International", { flags: new Set(["Customs"]), parcels: 539n, waiting: 35n, hours: [0n, 1n, 4n, 14n, 29n, 57n, 83n, 86n, 106n, 87n, 47n, 25n], exceptions: new Map([["Missing documents", 366n], ["Duty unpaid", 218n], ["Address check", 49n], ["Damaged packaging", 22n]]) }],
285
+ ]),
286
+ }],
287
+ ["CLR", {
288
+ flags: new Set(["Customs"]), equipment: new Set(["Label printer", "Scanner", "X-ray"]), shifts: new Set(["Early", "Late"]),
289
+ parcels: 18170n, waiting: 18n,
290
+ hours: [1817n, 3634n, 4542n, 3634n, 2180n, 1454n, 727n, 182n, 0n, 0n, 0n, 0n],
291
+ service: new Map([["Standard", 10175n], ["Priority", 4361n], ["Economy", 2362n], ["International", 1272n]]),
292
+ exceptions: new Map([["Duty refund", 12n]]),
293
+ byService: new Map([
294
+ ["Standard", { flags: new Set(), parcels: 10175n, waiting: 10n, hours: [943n, 1989n, 2575n, 2097n, 1257n, 823n, 397n, 94n, 0n, 0n, 0n, 0n], exceptions: new Map([["Duty refund", 4n]]) }],
295
+ ["Priority", { flags: new Set(), parcels: 4361n, waiting: 4n, hours: [663n, 1122n, 1166n, 762n, 367n, 193n, 74n, 14n, 0n, 0n, 0n, 0n], exceptions: new Map([["Duty refund", 2n]]) }],
296
+ ["Economy", { flags: new Set(), parcels: 2362n, waiting: 3n, hours: [159n, 377n, 551n, 506n, 342n, 253n, 137n, 37n, 0n, 0n, 0n, 0n], exceptions: new Map([["Duty refund", 1n]]) }],
297
+ ["International", { flags: new Set(["Customs"]), parcels: 1272n, waiting: 1n, hours: [52n, 146n, 250n, 269n, 214n, 185n, 119n, 37n, 0n, 0n, 0n, 0n], exceptions: new Map([["Duty refund", 5n]]) }],
298
+ ]),
299
+ }],
300
+ ["LDD", {
301
+ flags: new Set(["Hazmat", "Oversize"]), equipment: new Set(["Forklift", "Scanner"]), shifts: new Set(["Early", "Late", "Night"]),
302
+ parcels: 17030n, waiting: 210n,
303
+ hours: [681n, 1362n, 2725n, 4088n, 3747n, 2384n, 1362n, 511n, 170n, 0n, 0n, 0n],
304
+ service: new Map([["Standard", 9707n], ["Priority", 4087n], ["Economy", 2214n], ["International", 1022n]]),
305
+ exceptions: new Map([["Vehicle late", 140n], ["Overweight", 31n]]),
306
+ byService: new Map([
307
+ ["Standard", { flags: new Set(["Oversize"]), parcels: 9707n, waiting: 120n, hours: [334n, 717n, 1515n, 2358n, 2205n, 1407n, 792n, 288n, 91n, 0n, 0n, 0n], exceptions: new Map([["Vehicle late", 75n], ["Overweight", 18n]]) }],
308
+ ["Priority", { flags: new Set(), parcels: 4087n, waiting: 50n, hours: [286n, 493n, 835n, 1043n, 782n, 401n, 181n, 53n, 13n, 0n, 0n, 0n], exceptions: new Map([["Vehicle late", 31n], ["Overweight", 7n]]) }],
309
+ ["Economy", { flags: new Set(["Hazmat", "Oversize"]), parcels: 2214n, waiting: 27n, hours: [49n, 119n, 282n, 495n, 522n, 375n, 239n, 98n, 35n, 0n, 0n, 0n], exceptions: new Map([["Vehicle late", 26n], ["Overweight", 4n]]) }],
310
+ ["International", { flags: new Set(), parcels: 1022n, waiting: 13n, hours: [12n, 33n, 93n, 192n, 238n, 201n, 150n, 72n, 31n, 0n, 0n, 0n], exceptions: new Map([["Vehicle late", 8n], ["Overweight", 2n]]) }],
311
+ ]),
312
+ }],
313
+ ["RCV", {
314
+ flags: new Set(["Fragile"]), equipment: new Set(["Scanner"]), shifts: new Set(["Weekend"]),
315
+ parcels: 640n, waiting: 25n,
316
+ hours: [64n, 115n, 154n, 141n, 90n, 51n, 19n, 6n, 0n, 0n, 0n, 0n],
317
+ service: new Map([["Standard", 435n], ["Priority", 128n], ["Economy", 77n]]),
318
+ exceptions: new Map([["Missing documents", 18n]]),
319
+ byService: new Map([
320
+ ["Standard", { flags: new Set(["Fragile"]), parcels: 435n, waiting: 17n, hours: [39n, 75n, 104n, 98n, 64n, 37n, 14n, 4n, 0n, 0n, 0n, 0n], exceptions: new Map([["Missing documents", 12n]]) }],
321
+ ["Priority", { flags: new Set(), parcels: 128n, waiting: 5n, hours: [19n, 29n, 33n, 25n, 13n, 6n, 2n, 1n, 0n, 0n, 0n, 0n], exceptions: new Map([["Missing documents", 4n]]) }],
322
+ ["Economy", { flags: new Set(), parcels: 77n, waiting: 3n, hours: [6n, 11n, 17n, 18n, 13n, 8n, 3n, 1n, 0n, 0n, 0n, 0n], exceptions: new Map([["Missing documents", 2n]]) }],
323
+ ]),
324
+ }],
325
+ ["INS", {
326
+ flags: new Set(["At risk", "Customs"]), equipment: new Set(["X-ray"]), shifts: new Set(["Early"]),
327
+ parcels: 640n, waiting: 30n,
328
+ hours: [0n, 13n, 38n, 77n, 128n, 154n, 115n, 64n, 38n, 13n, 0n, 0n],
329
+ service: new Map([["Standard", 435n], ["Priority", 128n], ["Economy", 77n]]),
330
+ exceptions: new Map([["Damaged packaging", 27n]]),
331
+ byService: new Map([
332
+ ["Standard", { flags: new Set(["Customs"]), parcels: 435n, waiting: 20n, hours: [0n, 7n, 23n, 49n, 86n, 106n, 81n, 46n, 27n, 10n, 0n, 0n], exceptions: new Map([["Damaged packaging", 18n]]) }],
333
+ ["Priority", { flags: new Set(["At risk"]), parcels: 128n, waiting: 6n, hours: [0n, 5n, 12n, 21n, 29n, 30n, 18n, 8n, 4n, 1n, 0n, 0n], exceptions: new Map([["Damaged packaging", 6n]]) }],
334
+ ["Economy", { flags: new Set(), parcels: 77n, waiting: 4n, hours: [0n, 1n, 3n, 7n, 13n, 18n, 16n, 10n, 7n, 2n, 0n, 0n], exceptions: new Map([["Damaged packaging", 3n]]) }],
335
+ ]),
336
+ }],
337
+ ["RSD", {
338
+ flags: new Set(), equipment: new Set(["Scanner"]), shifts: new Set(["Early"]),
339
+ parcels: 610n, waiting: 0n,
340
+ hours: [122n, 183n, 159n, 85n, 43n, 18n, 0n, 0n, 0n, 0n, 0n, 0n],
341
+ service: new Map([["Standard", 415n], ["Priority", 122n], ["Economy", 73n]]),
342
+ exceptions: new Map(),
343
+ byService: new Map([
344
+ ["Standard", { flags: new Set(), parcels: 415n, waiting: 0n, hours: [78n, 123n, 110n, 60n, 31n, 13n, 0n, 0n, 0n, 0n, 0n, 0n], exceptions: new Map() }],
345
+ ["Priority", { flags: new Set(), parcels: 122n, waiting: 0n, hours: [32n, 41n, 29n, 13n, 5n, 2n, 0n, 0n, 0n, 0n, 0n, 0n], exceptions: new Map() }],
346
+ ["Economy", { flags: new Set(), parcels: 73n, waiting: 0n, hours: [12n, 19n, 20n, 12n, 7n, 3n, 0n, 0n, 0n, 0n, 0n, 0n], exceptions: new Map() }],
347
+ ]),
348
+ }],
164
349
  ]),
165
- indexes: (index) => ({
166
- flowchart_owners_by_desk: index.on(["desk"]),
350
+ mutations: (mutation) => ({ patch: mutation.patch() }),
351
+ // Each service's own figures, a range of the index by the service's name: what the rail's picks read.
352
+ indexes: (index) => ({ flowchart_evidence_by_service: index.entries("byService") }),
353
+ });
354
+ // A row a transition with a volume: the in-place one and the one to Delivered have none, and their labels keep their evidence alone.
355
+ export const moveEvidence = e3.record("flowchart_depot_move_evidence", DictType(StringType, MoveEvidence), {
356
+ initial: new Map([
357
+ ["l1", {
358
+ region: new Map([["Metro", 8491n], ["Regional", 6092n], ["Remote", 2769n], ["Overseas", 1108n]]),
359
+ service: new Map([["Standard", 10337n], ["Priority", 4615n], ["Economy", 2400n], ["International", 1108n]]),
360
+ origins: new Map([["Air hub", { parcels: 5350n, late: 84n }], ["Harbour hub", { parcels: 4377n, late: 135n }], ["Rail yard", { parcels: 2233n, late: 27n }], ["Depot 02", { parcels: 1680n, late: 20n }], ["Depot 05", { parcels: 1349n, late: 9n }], ["Depot 07", { parcels: 995n, late: 13n }], ["Depot 11", { parcels: 730n, late: 4n }], ["City counter", { parcels: 619n, late: 7n }], ["Partner pickup", { parcels: 508n, late: 11n }], ["Returns desk", { parcels: 354n, late: 2n }], ["Locker bank", { parcels: 265n, late: 0n }]]),
361
+ }],
362
+ ["l2", {
363
+ region: new Map([["Metro", 8459n], ["Regional", 6069n], ["Remote", 2759n], ["Overseas", 1103n]]),
364
+ service: new Map([["Standard", 10298n], ["Priority", 4598n], ["Economy", 2391n], ["International", 1103n]]),
365
+ origins: new Map([["Air hub", { parcels: 5330n, late: 84n }], ["Harbour hub", { parcels: 4361n, late: 134n }], ["Rail yard", { parcels: 2224n, late: 26n }], ["Depot 02", { parcels: 1674n, late: 20n }], ["Depot 05", { parcels: 1343n, late: 9n }], ["Depot 07", { parcels: 991n, late: 13n }], ["Depot 11", { parcels: 727n, late: 4n }], ["City counter", { parcels: 617n, late: 7n }], ["Partner pickup", { parcels: 507n, late: 11n }], ["Returns desk", { parcels: 352n, late: 2n }], ["Locker bank", { parcels: 264n, late: 0n }]]),
366
+ }],
367
+ ["l4", {
368
+ region: new Map([["Metro", 8153n], ["Regional", 5726n], ["Remote", 2603n], ["Overseas", 868n]]),
369
+ service: new Map([["Standard", 9889n], ["Priority", 4164n], ["Economy", 2256n], ["International", 1041n]]),
370
+ origins: new Map([["Air hub", { parcels: 5029n, late: 79n }], ["Harbour hub", { parcels: 4114n, late: 127n }], ["Rail yard", { parcels: 2099n, late: 25n }], ["Depot 02", { parcels: 1579n, late: 19n }], ["Depot 05", { parcels: 1267n, late: 8n }], ["Depot 07", { parcels: 935n, late: 12n }], ["Depot 11", { parcels: 686n, late: 4n }], ["City counter", { parcels: 582n, late: 6n }], ["Partner pickup", { parcels: 478n, late: 10n }], ["Returns desk", { parcels: 332n, late: 2n }], ["Locker bank", { parcels: 249n, late: 0n }]]),
371
+ }],
372
+ ["l5", {
373
+ region: new Map([["Metro", 8376n], ["Regional", 6009n], ["Remote", 2732n], ["Overseas", 1093n]]),
374
+ service: new Map([["Standard", 10380n], ["Priority", 4370n], ["Economy", 2367n], ["International", 1093n]]),
375
+ origins: new Map([["Air hub", { parcels: 5277n, late: 83n }], ["Harbour hub", { parcels: 4318n, late: 133n }], ["Rail yard", { parcels: 2203n, late: 26n }], ["Depot 02", { parcels: 1657n, late: 20n }], ["Depot 05", { parcels: 1330n, late: 9n }], ["Depot 07", { parcels: 981n, late: 13n }], ["Depot 11", { parcels: 720n, late: 4n }], ["City counter", { parcels: 611n, late: 7n }], ["Partner pickup", { parcels: 502n, late: 11n }], ["Returns desk", { parcels: 349n, late: 2n }], ["Locker bank", { parcels: 262n, late: 0n }]]),
376
+ }],
377
+ ["l6", {
378
+ region: new Map([["Metro", 1179n], ["Regional", 758n], ["Remote", 421n], ["Overseas", 6062n]]),
379
+ service: new Map([["Standard", 2610n], ["Priority", 1010n], ["Economy", 589n], ["International", 4211n]]),
380
+ origins: new Map([["Air hub", { parcels: 2441n, late: 38n }], ["Harbour hub", { parcels: 1997n, late: 62n }], ["Rail yard", { parcels: 1018n, late: 12n }], ["Depot 02", { parcels: 766n, late: 9n }], ["Depot 05", { parcels: 615n, late: 4n }], ["Depot 07", { parcels: 454n, late: 6n }], ["Depot 11", { parcels: 333n, late: 2n }], ["City counter", { parcels: 282n, late: 3n }], ["Partner pickup", { parcels: 232n, late: 5n }], ["Returns desk", { parcels: 161n, late: 1n }], ["Locker bank", { parcels: 121n, late: 0n }]]),
381
+ }],
382
+ ["l7", {
383
+ region: new Map([["Metro", 1169n], ["Regional", 752n], ["Remote", 418n], ["Overseas", 6011n]]),
384
+ service: new Map([["Standard", 2589n], ["Priority", 1002n], ["Economy", 585n], ["International", 4174n]]),
385
+ origins: new Map([["Air hub", { parcels: 2420n, late: 38n }], ["Harbour hub", { parcels: 1980n, late: 61n }], ["Rail yard", { parcels: 1010n, late: 12n }], ["Depot 02", { parcels: 760n, late: 9n }], ["Depot 05", { parcels: 610n, late: 4n }], ["Depot 07", { parcels: 450n, late: 6n }], ["Depot 11", { parcels: 330n, late: 2n }], ["City counter", { parcels: 280n, late: 3n }], ["Partner pickup", { parcels: 230n, late: 5n }], ["Returns desk", { parcels: 160n, late: 1n }], ["Locker bank", { parcels: 120n, late: 0n }]]),
386
+ }],
387
+ ["l8", {
388
+ region: new Map([["Metro", 3296n], ["Regional", 2472n], ["Remote", 1154n], ["Overseas", 1318n]]),
389
+ service: new Map([["Standard", 4120n], ["Priority", 1813n], ["Economy", 989n], ["International", 1318n]]),
390
+ origins: new Map([["Air hub", { parcels: 2388n, late: 37n }], ["Harbour hub", { parcels: 1954n, late: 60n }], ["Rail yard", { parcels: 997n, late: 12n }], ["Depot 02", { parcels: 750n, late: 9n }], ["Depot 05", { parcels: 602n, late: 4n }], ["Depot 07", { parcels: 444n, late: 6n }], ["Depot 11", { parcels: 326n, late: 2n }], ["City counter", { parcels: 276n, late: 3n }], ["Partner pickup", { parcels: 227n, late: 5n }], ["Returns desk", { parcels: 158n, late: 1n }], ["Locker bank", { parcels: 118n, late: 0n }]]),
391
+ }],
392
+ ["l9", {
393
+ region: new Map([["Metro", 8003n], ["Regional", 5620n], ["Remote", 2555n], ["Overseas", 852n]]),
394
+ service: new Map([["Standard", 9876n], ["Priority", 4258n], ["Economy", 2044n], ["International", 852n]]),
395
+ origins: new Map([["Air hub", { parcels: 4936n, late: 78n }], ["Harbour hub", { parcels: 4038n, late: 124n }], ["Rail yard", { parcels: 2060n, late: 24n }], ["Depot 02", { parcels: 1550n, late: 18n }], ["Depot 05", { parcels: 1244n, late: 8n }], ["Depot 07", { parcels: 918n, late: 12n }], ["Depot 11", { parcels: 673n, late: 4n }], ["City counter", { parcels: 571n, late: 6n }], ["Partner pickup", { parcels: 469n, late: 10n }], ["Returns desk", { parcels: 326n, late: 2n }], ["Locker bank", { parcels: 245n, late: 0n }]]),
396
+ }],
397
+ ["l11", {
398
+ region: new Map([["Metro", 294n], ["Regional", 274n], ["Remote", 216n], ["Overseas", 196n]]),
399
+ service: new Map([["Standard", 471n], ["Priority", 294n], ["Economy", 137n], ["International", 78n]]),
400
+ origins: new Map([["Air hub", { parcels: 283n, late: 4n }], ["Harbour hub", { parcels: 232n, late: 7n }], ["Rail yard", { parcels: 119n, late: 1n }], ["Depot 02", { parcels: 89n, late: 1n }], ["Depot 05", { parcels: 72n, late: 0n }], ["Depot 07", { parcels: 53n, late: 1n }], ["Depot 11", { parcels: 39n, late: 0n }], ["City counter", { parcels: 33n, late: 0n }], ["Partner pickup", { parcels: 27n, late: 1n }], ["Returns desk", { parcels: 19n, late: 0n }], ["Locker bank", { parcels: 14n, late: 0n }]]),
401
+ }],
402
+ ["l12", {
403
+ region: new Map([["Metro", 292n], ["Regional", 273n], ["Remote", 215n], ["Overseas", 195n]]),
404
+ service: new Map([["Standard", 467n], ["Priority", 293n], ["Economy", 137n], ["International", 78n]]),
405
+ origins: new Map([["Air hub", { parcels: 281n, late: 4n }], ["Harbour hub", { parcels: 231n, late: 7n }], ["Rail yard", { parcels: 118n, late: 1n }], ["Depot 02", { parcels: 89n, late: 1n }], ["Depot 05", { parcels: 71n, late: 0n }], ["Depot 07", { parcels: 53n, late: 1n }], ["Depot 11", { parcels: 39n, late: 0n }], ["City counter", { parcels: 33n, late: 0n }], ["Partner pickup", { parcels: 27n, late: 1n }], ["Returns desk", { parcels: 19n, late: 0n }], ["Locker bank", { parcels: 14n, late: 0n }]]),
406
+ }],
407
+ ["l13", {
408
+ region: new Map([["Metro", 4570n], ["Regional", 2989n], ["Remote", 1055n], ["Overseas", 176n]]),
409
+ service: new Map([["Standard", 5450n], ["Priority", 2285n], ["Economy", 1055n]]),
410
+ origins: new Map([["Air hub", { parcels: 2549n, late: 40n }], ["Harbour hub", { parcels: 2084n, late: 64n }], ["Rail yard", { parcels: 1063n, late: 13n }], ["Depot 02", { parcels: 800n, late: 9n }], ["Depot 05", { parcels: 642n, late: 4n }], ["Depot 07", { parcels: 474n, late: 6n }], ["Depot 11", { parcels: 347n, late: 2n }], ["City counter", { parcels: 295n, late: 3n }], ["Partner pickup", { parcels: 242n, late: 5n }], ["Returns desk", { parcels: 168n, late: 1n }], ["Locker bank", { parcels: 126n, late: 0n }]]),
411
+ }],
412
+ ["r1", {
413
+ region: new Map([["Metro", 371n], ["Regional", 192n], ["Remote", 77n]]),
414
+ service: new Map([["Standard", 397n], ["Priority", 128n], ["Economy", 77n], ["International", 38n]]),
415
+ origins: new Map([["Air hub", { parcels: 187n, late: 3n }], ["Harbour hub", { parcels: 152n, late: 5n }], ["Rail yard", { parcels: 77n, late: 1n }], ["Depot 02", { parcels: 58n, late: 1n }], ["Depot 05", { parcels: 47n, late: 0n }], ["Depot 07", { parcels: 34n, late: 0n }], ["Depot 11", { parcels: 25n, late: 0n }], ["City counter", { parcels: 21n, late: 0n }], ["Partner pickup", { parcels: 18n, late: 0n }], ["Returns desk", { parcels: 12n, late: 0n }], ["Locker bank", { parcels: 9n, late: 0n }]]),
416
+ }],
417
+ ["r2", {
418
+ region: new Map([["Metro", 354n], ["Regional", 183n], ["Remote", 73n]]),
419
+ service: new Map([["Standard", 378n], ["Priority", 122n], ["Economy", 73n], ["International", 37n]]),
420
+ origins: new Map([["Air hub", { parcels: 175n, late: 3n }], ["Harbour hub", { parcels: 145n, late: 4n }], ["Rail yard", { parcels: 74n, late: 1n }], ["Depot 02", { parcels: 56n, late: 1n }], ["Depot 05", { parcels: 45n, late: 0n }], ["Depot 07", { parcels: 33n, late: 0n }], ["Depot 11", { parcels: 24n, late: 0n }], ["City counter", { parcels: 20n, late: 0n }], ["Partner pickup", { parcels: 17n, late: 0n }], ["Returns desk", { parcels: 12n, late: 0n }], ["Locker bank", { parcels: 9n, late: 0n }]]),
421
+ }],
422
+ ]),
423
+ mutations: (mutation) => ({ patch: mutation.patch() }),
424
+ });
425
+ // The library's cards, records the app's users keep: each a name, a group and the values a new row takes — a state's
426
+ // every field but its lane and its place, a transition's every field but its ends.
427
+ export const StepCard = StructType({
428
+ name: StringType,
429
+ group: StringType,
430
+ values: StructType({ name: StringType, slots: OptionType(IntegerType), flow: StringType }),
431
+ });
432
+ export const MoveCard = StructType({
433
+ name: StringType,
434
+ group: StringType,
435
+ values: StructType({
436
+ kind: VariantType({ planned: NullType, observed: NullType }), trigger: OptionType(StringType),
437
+ volume: OptionType(FloatType), n: OptionType(IntegerType), at: OptionType(DateTimeType), flow: StringType,
167
438
  }),
168
439
  });
169
- // The depot's own tables (§3.4), each an input of the app's own rows: its
170
- // steps by phase, the transitions mined from its scans and its decisions.
171
- // `Flowchart.over` builds one flow from them; a task narrows the rows it
172
- // builds one from, for the flowchart narrows no table of the host's (#1346).
173
- export const DepotState = StructType({ code: StringType, name: StringType, phase: StringType, slots: OptionType(IntegerType) });
174
- export const depotStates = e3.input("flowchart_depot_states", ArrayType(DepotState), variant("value", [
175
- { code: "ARV", name: "Arrived", phase: "intake", slots: none },
176
- { code: "SCN", name: "Scanned", phase: "intake", slots: none },
177
- { code: "IND", name: "Inducting", phase: "induct", slots: none },
178
- { code: "LBL", name: "Labelled", phase: "induct", slots: none },
179
- { code: "CH*", name: "Sort chutes (class)", phase: "sort", slots: some(14n) },
180
- { code: "SRD", name: "Sorted", phase: "sort", slots: none },
181
- { code: "HLD", name: "Held", phase: "hold", slots: none },
182
- { code: "CLR", name: "Cleared", phase: "hold", slots: none },
183
- { code: "LDD", name: "Loaded", phase: "dispatch", slots: none },
184
- { code: "DSP", name: "Dispatched", phase: "dispatch", slots: none },
185
- ]));
186
- export const ScanTransition = StructType({
187
- id: StringType, src: StringType, dst: StringType, kind: Flowchart.Types.Kind,
188
- trigger: OptionType(StringType), parcels: OptionType(FloatType), n: OptionType(IntegerType),
189
- at: DateTimeType, service: StringType, units: ArrayType(StringType),
440
+ export const stepCards = e3.record("flowchart_step_cards", DictType(StringType, StepCard), {
441
+ initial: new Map([
442
+ ["scan", { name: "Scan point", group: "Intake", values: { name: "Scan point", slots: none, flow: "Parcels" } }],
443
+ ["chutes", { name: "Sort chutes", group: "Sort", values: { name: "Sort chutes", slots: some(12n), flow: "Parcels" } }],
444
+ ["desk", { name: "Exception desk", group: "Hold", values: { name: "Exception desk", slots: none, flow: "Parcels" } }],
445
+ ]),
446
+ indexes: (index) => ({ flowchart_step_cards_by_group: index.on(["group"]) }),
190
447
  });
191
- export const scanTransitions = e3.input("flowchart_depot_scans", ArrayType(ScanTransition), variant("value", [
192
- { id: "l1", src: "ARV", dst: "SCN", kind: variant("planned", null), trigger: none, parcels: some(18460.0), n: some(412n), at: new Date("2026-06-30T00:00:00Z"), service: "standard", units: ["C"] },
193
- { id: "l2", src: "SCN", dst: "IND", kind: variant("planned", null), trigger: none, parcels: some(7720.0), n: some(171n), at: new Date("2026-06-30T00:00:00Z"), service: "standard", units: ["C"] },
194
- { id: "l3", src: "IND", dst: "IND", kind: variant("planned", null), trigger: none, parcels: none, n: some(2n), at: new Date("2026-06-30T00:00:00Z"), service: "standard", units: ["C"] },
195
- { id: "l4", src: "IND", dst: "CH*", kind: variant("planned", null), trigger: some("route"), parcels: some(17350.0), n: some(386n), at: new Date("2026-06-30T00:00:00Z"), service: "standard", units: ["C", "T"] },
196
- { id: "l5", src: "CH*", dst: "SRD", kind: variant("planned", null), trigger: none, parcels: some(17210.0), n: some(383n), at: new Date("2026-06-30T00:00:00Z"), service: "standard", units: ["T"] },
197
- { id: "l6", src: "SRD", dst: "HLD", kind: variant("observed", null), trigger: none, parcels: some(1080.0), n: some(24n), at: new Date("2026-06-30T00:00:00Z"), service: "express", units: ["T"] },
198
- { id: "l7", src: "HLD", dst: "CLR", kind: variant("planned", null), trigger: some("customs"), parcels: some(8350.0), n: some(186n), at: new Date("2026-06-30T00:00:00Z"), service: "standard", units: ["T"] },
199
- { id: "l8", src: "CLR", dst: "LDD", kind: variant("planned", null), trigger: none, parcels: some(8240.0), n: some(183n), at: new Date("2026-06-30T00:00:00Z"), service: "standard", units: ["T"] },
200
- { id: "l9", src: "LDD", dst: "DSP", kind: variant("planned", null), trigger: none, parcels: some(8160.0), n: some(181n), at: new Date("2026-06-30T00:00:00Z"), service: "standard", units: [] },
201
- { id: "l10", src: "DSP", dst: "DLV", kind: variant("planned", null), trigger: none, parcels: none, n: none, at: new Date("2026-06-30T00:00:00Z"), service: "standard", units: [] },
202
- ]));
203
- export const DepotDecision = StructType({ id: StringType, name: StringType, who: StringType });
204
- export const depotDecisions = e3.input("flowchart_depot_decisions", ArrayType(DepotDecision), variant("value", [
205
- { id: "route", name: "route", who: "sort-planner" },
206
- { id: "customs", name: "customs", who: "customs-desk" },
207
- ]));
208
- export const flowchartFlows = example({
209
- keywords: ["Flowchart", "record", "Flows", "Flowchart.values", "Record.bind", "flow", "many flows", "e3.record", "Flowchart.library.flows", "Flows tab", "New flow"],
210
- description: "A record of flows by name — the depot's inbound parcels and its returns — bound with its patch mutation, the inbound flow opened first and the Flows tab listing every flow",
211
- fn: East.function([], UIComponentType, (_$) => (_jsx(Reactive, { children: $ => {
212
- const flows = $.let(Record.bind(depotFlows));
213
- return (_jsx(Box, { height: "500px", children: _jsx(Flowchart, { record: flows, flow: "Inbound parcels", library: [Flowchart.library.flows()] }) }));
214
- } }))),
215
- inputs: [],
448
+ export const moveCards = e3.record("flowchart_move_cards", DictType(StringType, MoveCard), {
449
+ initial: new Map([
450
+ ["planned", { name: "Planned", group: "Kinds",
451
+ values: { kind: variant("planned", null), trigger: none, volume: none, n: none, at: none, flow: "Parcels" } }],
452
+ ["reroute", { name: "Observed reroute", group: "Kinds",
453
+ values: { kind: variant("observed", null), trigger: none, volume: none, n: none, at: none, flow: "Parcels" } }],
454
+ ["routed", { name: "Routed by the sort plan", group: "Decisions",
455
+ values: { kind: variant("planned", null), trigger: some("route"), volume: none, n: none, at: none, flow: "Parcels" } }],
456
+ ]),
457
+ indexes: (index) => ({ flowchart_move_cards_by_group: index.on(["group"]) }),
216
458
  });
217
- /**
218
- * THE Flowchart configurator — ONE live flowchart in its frame; every axis is
219
- * an expression-fed prop on that single instance: the legend, the minimap and
220
- * read only. Its flows are the host's (`data`): the depot's flows, read from
221
- * their e3 record, and Save hands `onApply` the session's request id with the
222
- * open flow's patch, which it commits through the record's patch mutation
223
- * under that id and answers with what e3 said — committed, refused, out of
224
- * time or beaten by another write. A write that got no answer throws, so the
225
- * session's Retry sends the same request id again, and e3 answers it with the
226
- * first write's commit rather than writing twice (#1275). The host hears what is selected — a
227
- * state, a transition, a decision — and a path ⌥-clicked in the reactive
228
- * aside, so it is given no inspector; its library is the Flows tab over the
229
- * host's flows. Its panes are fixed when it is built, so they are no axis
230
- * here. The configurator's axes are the viewer's own state.
231
- */
232
- export const flowchartVariants = example({
233
- keywords: ["Flowchart", "configurator", "Configurator", "legend", "minimap", "readOnly", "read only", "onSelectState", "onSelectLink", "onSelectTrigger", "onTracePath", "selection", "trace", "callbacks", "data", "onApply", "commit", "requestId", "request id", "Retry", "Record.bind", "commit.patch", "Editing.Types.ApplyResult", "Flows tab", "Flowchart.library.flows", "many flows", "inspector={false}", "library", "Switch", "State", "Reactive"],
234
- description: "Flowchart configurator — the legend, the minimap and read only, each expression-fed into one live flowchart in its frame over the host's flows by name (data, from the depot's e3 record), its Flows tab over them, Save committed by the host's onApply through the record's patch mutation under the session's request id, a Retry safe to repeat; onSelectState, onSelectLink, onSelectTrigger and onTracePath heard in the aside, with no inspector",
459
+ // The Lanes tab's cards: one dropped between two lanes adds a lane there, from its values — a lane's every field but its place.
460
+ export const LaneCard = StructType({ name: StringType, group: StringType, values: StructType({ label: StringType }) });
461
+ export const laneCards = e3.record("flowchart_lane_cards", DictType(StringType, LaneCard), {
462
+ initial: new Map([
463
+ ["returns", { name: "Returns", group: "Lanes", values: { label: "Returns" } }],
464
+ ["check", { name: "Quality check", group: "Lanes", values: { label: "Quality check" } }],
465
+ ]),
466
+ indexes: (index) => ({ flowchart_lane_cards_by_group: index.on(["group"]) }),
467
+ });
468
+ // The people who own the depot's decisions: an owner's card dropped on a decision's diamond makes them its owner.
469
+ export const DecisionOwner = StructType({ name: StringType, desk: StringType });
470
+ export const decisionOwners = e3.input("flowchart_decision_owners", DictType(StringType, DecisionOwner), variant("value", new Map([
471
+ ["sp", { name: "sort-planner", desk: "Sort office" }],
472
+ ["cd", { name: "customs-desk", desk: "Customs" }],
473
+ ["ns", { name: "night-supervisor", desk: "Night shift" }],
474
+ ])));
475
+ // The time each parcel spent in each state, keyed as the states are: its parcels counted into bins by how
476
+ // long they stayed, each key a bin's lower edge, in hours.
477
+ export const StateDwell = StructType({ hours: DictType(FloatType, IntegerType) });
478
+ export const stateDwell = e3.input("flowchart_depot_dwell", DictType(StringType, StateDwell), variant("value", new Map([
479
+ ["ARV", { hours: new Map([[0, 7752n], [0.25, 6092n], [0.5, 2769n], [1, 1108n], [2, 554n], [4, 185n]]) }],
480
+ ["SCN", { hours: new Map([[0, 9195n], [0.25, 5517n], [0.5, 2391n], [1, 920n], [2, 367n]]) }],
481
+ ["IND", { hours: new Map([[0, 2207n], [0.25, 4781n], [0.5, 5517n], [1, 3310n], [2, 1655n], [4, 736n], [8, 184n]]) }],
482
+ ["LBL", { hours: new Map([[0.25, 59n], [0.5, 137n], [1, 255n], [2, 273n], [4, 157n], [8, 79n], [12, 20n]]) }],
483
+ ["CH*", { hours: new Map([[0, 1457n], [0.25, 4007n], [0.5, 6192n], [1, 4007n], [2, 1639n], [4, 728n], [8, 180n]]) }],
484
+ ["SRD", { hours: new Map([[0, 861n], [0.25, 2065n], [0.5, 4303n], [1, 4818n], [2, 3098n], [4, 1377n], [8, 516n], [12, 172n]]) }],
485
+ ["HLD", { hours: new Map([[0.25, 84n], [0.5, 167n], [1, 418n], [2, 752n], [4, 1169n], [8, 1417n],
486
+ [12, 1253n], [24, 1336n], [48, 1002n], [96, 501n], [168, 251n]]) }],
487
+ ["CLR", { hours: new Map([[0, 824n], [0.25, 1648n], [0.5, 2060n], [1, 1648n], [2, 989n], [4, 659n], [8, 330n], [12, 82n]]) }],
488
+ ["LDD", { hours: new Map([[0, 681n], [0.25, 1362n], [0.5, 2725n], [1, 4088n], [2, 3747n], [4, 2384n], [8, 1362n], [12, 511n], [24, 170n]]) }],
489
+ // Dispatched has no row: the app counts no time in it once a parcel has left, and its card says no data.
490
+ ["RCV", { hours: new Map([[0, 64n], [0.25, 115n], [0.5, 154n], [1, 141n], [2, 90n], [4, 51n], [8, 19n], [12, 6n]]) }],
491
+ ["INS", { hours: new Map([[0.25, 12n], [0.5, 37n], [1, 73n], [2, 122n], [4, 146n], [8, 110n], [12, 61n], [24, 37n], [48, 12n]]) }],
492
+ ["RSD", { hours: new Map([[0, 122n], [0.25, 183n], [0.5, 159n], [1, 85n], [2, 43n], [4, 18n]]) }],
493
+ ])));
494
+ export const flowchartDwell = example({
495
+ keywords: ["Flowchart", "Flowchart.states", "Flowchart.transitions", "Flowchart.lanes", "records", "Data.bind", "read only",
496
+ "details", "Flowchart.details", "Flowchart.histogram", "time in state", "histogram", "card", "minimal"],
497
+ description: "The depot's states, transitions and lanes, three records of the app's read whole, read only, each state's time in state drawn on its card — one histogram, read from the app's own rows",
235
498
  fn: East.function([], UIComponentType, (_$) => (_jsx(Reactive, { children: $ => {
236
- const flows = $.let(Record.bind(depotFlows));
237
- // The host's commit: the open flow's patch through the record's patch mutation under the session's request id, e3's outcome as Save's answer.
238
- const onApply = $.const(East.asyncFunction([StringType, PatchType(Flowchart.Types.Flows)], Editing.Types.ApplyResult, ($2, requestId, patch) => {
239
- const outcome = $2.let(flows.commit.patch(requestId, patch));
240
- const answer = $2.let(variant("rejected", [{ entry: "", row: none, field: none, message: "The write was refused" }]), Editing.Types.ApplyResult);
241
- $2.match(outcome, {
242
- committed: ($3, done) => { $3.assign(answer, variant("applied", { revision: some(done.stateHash) })); },
243
- invalid: ($3, refused) => { $3.assign(answer, variant("rejected", [{ entry: "", row: none, field: none, message: refused.message }])); },
244
- failed: ($3, refused) => { $3.assign(answer, variant("rejected", [{ entry: "", row: none, field: none, message: East.str `The write failed: ${refused.stderr}` }])); },
245
- timed_out: ($3, refused) => { $3.assign(answer, variant("rejected", [{ entry: "", row: none, field: none, message: East.str `The write ran out of time after ${refused.ms} ms and wrote nothing` }])); },
246
- conflict: ($3, lost) => {
247
- const why = $3.let(lost.detail.match({ some: (_$4, detail) => detail, none: (_$4) => "Another write changed the flows first" }));
248
- $3.assign(answer, variant("conflict", [{ entry: "", row: none, field: none, message: why }]));
249
- },
250
- // No answer: it may have committed, so the session's Retry sends the same request id, which resolves to that commit.
251
- transport: ($3, lost) => { $3.error(East.str `The write got no answer, so it may have committed — retry to find out: ${lost.message}`); },
252
- });
253
- return answer;
254
- }));
255
- const legendBind = $.let(State.bind([BooleanType], "flowchart_variants_legend", true));
256
- const minimapBind = $.let(State.bind([BooleanType], "flowchart_variants_minimap", false));
257
- const readOnlyBind = $.let(State.bind([BooleanType], "flowchart_variants_readonly", false));
258
- const heardBind = $.let(State.bind([StringType], "flowchart_variants_heard", ""));
259
- const legendOn = $.let(legendBind.read());
260
- const minimapOn = $.let(minimapBind.read());
261
- const readOnly = $.let(readOnlyBind.read());
262
- const heard = $.let(heardBind.read());
263
- const onLegend = $.const(East.function([BooleanType], NullType, ($2, next) => { $2(legendBind.write(next)); }));
264
- const onMinimap = $.const(East.function([BooleanType], NullType, ($2, next) => { $2(minimapBind.write(next)); }));
265
- const onReadOnly = $.const(East.function([BooleanType], NullType, ($2, next) => { $2(readOnlyBind.write(next)); }));
266
- // What the host hears: a state, a transition or a decision selected, and a path ⌥-clicked.
267
- const onSelectState = $.const(East.function([StringType], NullType, ($2, key) => { $2(heardBind.write(East.str `onSelectState: ${key}`)); }));
268
- const onSelectLink = $.const(East.function([StringType], NullType, ($2, key) => { $2(heardBind.write(East.str `onSelectLink: ${key}`)); }));
269
- const onSelectTrigger = $.const(East.function([StringType], NullType, ($2, key) => { $2(heardBind.write(East.str `onSelectTrigger: ${key}`)); }));
270
- const onTracePath = $.const(East.function([StringType], NullType, ($2, key) => { $2(heardBind.write(East.str `onTracePath: ${key}`)); }));
271
- return (_jsx(Configurator, { controls: [
272
- Configurator.Slot("Canvas", _jsxs(HStack, { gap: "5", align: "center", wrap: "wrap", children: [_jsx(Switch, { checked: legendOn, label: "Legend", onChange: onLegend }), _jsx(Switch, { checked: minimapOn, label: "Minimap", onChange: onMinimap }), _jsx(Switch, { checked: readOnly, label: "Read-only", onChange: onReadOnly })] })),
273
- ], preview: _jsx(Box, { width: "100%", height: "480px", children: _jsx(Flowchart, { data: flows.read(), flow: "Inbound parcels", onApply: onApply, library: [Flowchart.library.flows()], inspector: false, legend: legendOn, minimap: minimapOn, readOnly: readOnly, onSelectState: onSelectState, onSelectLink: onSelectLink, onSelectTrigger: onSelectTrigger, onTracePath: onTracePath, name: "variants" }) }), aside: {
274
- label: "Heard · Reactive",
275
- body: (_jsx(Badge, { colorPalette: "brand", variant: "outline", children: East.equal(heard.length(), 0n).ifElse((_$2) => "Select a state, a transition or a decision", (_$2) => heard) })),
276
- }, spec: [
277
- Configurator.Spec("Legend", legendOn.ifElse((_$2) => "shown", (_$2) => "hidden")),
278
- Configurator.Spec("Minimap", minimapOn.ifElse((_$2) => "shown", (_$2) => "hidden")),
279
- Configurator.Spec("Read only", readOnly.ifElse((_$2) => "yes", (_$2) => "no")),
280
- Configurator.Spec("Flows", East.str `${flows.read().size()} by name`),
281
- ] }));
499
+ const states = $.let(Data.bind(depotStates));
500
+ const transitions = $.let(Data.bind(depotTransitions));
501
+ const lanes = $.let(Data.bind(depotLanes));
502
+ const dwell = $.let(Data.bind(stateDwell));
503
+ return (_jsx(Box, { height: "600px", children: _jsx(Flowchart, { states: Flowchart.states(states, {
504
+ label: "name", lane: "phase", order: "seq",
505
+ // Keyed as the states are, and read as they are: whole.
506
+ details: Flowchart.details(dwell, {
507
+ details: [Flowchart.histogram("hours", { unit: "hours", label: "Time in state" })],
508
+ }),
509
+ }), transitions: Flowchart.transitions(transitions, { from: "src", to: "dst" }), lanes: Flowchart.lanes(lanes, { label: "label", order: "seq" }), name: "dwell" }) }));
282
510
  } }))),
283
511
  inputs: [],
284
512
  });
285
- /**
286
- * The library (#1248, #1346): the Flows tab, then the step types, the
287
- * transition types and the roles that own a decision — each tab its own
288
- * bound data, apart from the flows and from the other tabs: a templates
289
- * record by code, one by name, and a record of roles. One rail narrows them,
290
- * a source each: each templates list and the Owners tab follow the source
291
- * they name, counting what they show (`2 of 5`) and saying so, with Clear
292
- * filters, when the rail leaves them none. Each template card is a drag
293
- * source, as is each of the author's cards, whose tab declares a `drop`; a
294
- * click selects a card, and a click on the selected card lets it go.
295
- */
296
- export const flowchartLibrary = example({
297
- keywords: ["Flowchart", "library", "Flowchart.library.states", "Flowchart.library.transitions", "Flowchart.library.tab", "templates", "state templates", "transition templates", "templates records", "author's tab", "bound data", "Data.bind", "Data.bindPaged", "indexes", "Slice.bindRecords", "source", "narrowing", "Record.bind", "drag", "cards", "Flowchart.patch"],
298
- description: "A record of flows with its library — the Flows tab, step types and transition types from templates records, and the author's own cards from a record of roles — each tab its own bound data, one Slice.bindRecords rail narrowing each through the source it names, each card a drag source a click selects",
513
+ export const flowchartDepot = example({
514
+ keywords: [
515
+ "Flowchart", "Flowchart.states", "Flowchart.transitions", "Flowchart.lanes", "Flowchart.decisions", "Flowchart.details",
516
+ "Flowchart.templates", "Flowchart.library", "Flowchart.library.lanes", "Flowchart.library.tab", "Flowchart.patch", "Record.bind", "Data.bindPaged",
517
+ "Slice.bindRecords", "presets", "records", "entries", "details", "Flowchart.tags", "Flowchart.histogram", "Flowchart.list",
518
+ "Flowchart.figure", "show", "tag lists", "colorPalette", "legend", "bins", "ticks", "inspector", "editing", "Save",
519
+ "source", "weigh", "weighed", "index.entries", "picks", "byService",
520
+ ],
521
+ description: "A parcel depot's flowchart over four records of the app's: its states and transitions read through their sources of the rail and edited through their patch doors, a preset narrowing both to one flow; its lanes and decisions, small records read whole; each state's details on its card in the app's order — its parcels, its flags, equipment and shifts as tag lists in the app's colours, two of them in the legend, its time in state over the app's bins and its top services — each transition's top region under its evidence, and every read in full in the inspector; the Steps, Transitions and Lanes tabs listing each kind's cards, and an owners tab whose card dropped on a decision makes it the decision's owner; and the services the rail picks weighing the states' details, their own figures added up by kind — the parcels, still in state, flags, time in state and exceptions — while the equipment, the shifts and the Service list draw the state's own",
299
522
  fn: East.function([], UIComponentType, (_$) => (_jsx(Reactive, { children: $ => {
300
- const flows = $.let(Record.bind(depotFlows));
301
- // What a tab reads whole binds with Data.bind, which keeps it loaded beside its pages.
302
- const steps = $.let(Data.bind(stepTemplates));
303
- const moves = $.let(Data.bind(moveTemplates));
523
+ // The states and the transitions: editable through their patch doors, read through their sources of the rail.
524
+ const states = $.let(Record.bind(depotStates));
525
+ const stateEntries = $.let(Data.bindPaged(depotStates));
526
+ const transitions = $.let(Record.bind(depotTransitions));
527
+ const transitionEntries = $.let(Data.bindPaged(depotTransitions));
528
+ // The lanes and the decisions: small records, read whole.
529
+ const lanes = $.let(Record.bind(depotLanes));
530
+ const decisions = $.let(Record.bind(depotDecisions));
531
+ // The details, read by the drawn rows' keys, as their kinds are read through their sources. The states'
532
+ // evidence is bound once, its entries index listed: the rail's evidence source, and the details its picks weigh.
533
+ const evidence = $.let(Data.bindPaged(stateEvidence, { indexes: ["flowchart_evidence_by_service"] }));
534
+ const moveRows = $.let(Data.bindPaged(moveEvidence));
535
+ const steps = $.let(Data.bind(stepCards));
536
+ const moves = $.let(Data.bind(moveCards));
537
+ const laneRows = $.let(Data.bind(laneCards));
304
538
  const owners = $.let(Data.bind(decisionOwners));
305
- // One rail over the library's records, a source each (#1346): each tab follows the source it names.
539
+ // One rail: the states and the transitions by their flow — the states by their lane too — and each list of
540
+ // cards by its group. The flowchart opens on the parcels' flow; a preset picks a flow for both at once.
306
541
  const slice = $.let(Slice.bindRecords("flowchart.depot", {
307
- steps: { source: Data.bindPaged(stepTemplates, { indexes: ["flowchart_steps_by_kind"] }), label: "Steps", icon: { prefix: "fas", name: "box" },
308
- fields: { kind: { label: "Step kind", hints: ["Intake", "Sort", "Hold", "Load"] } } },
309
- moves: { source: Data.bindPaged(moveTemplates, { indexes: ["flowchart_moves_by_kind"] }), label: "Transitions", icon: { prefix: "fas", name: "arrow-right" },
310
- fields: { kind: { label: "Transition kind" } } },
311
- owners: { source: Data.bindPaged(decisionOwners, { indexes: ["flowchart_owners_by_desk"] }), label: "Owners", icon: { prefix: "fas", name: "user-tie" },
312
- fields: { desk: { label: "Desk", hints: ["Sort hall", "Hold bay"] } } },
313
- }));
314
- return (_jsx(Box, { height: "560px", children: _jsx(Flowchart, { record: flows, flow: "Inbound parcels", name: "depot", slice: { slice }, library: [
315
- Flowchart.library.flows(),
316
- // Step types, a templates record by code: a card dropped on a lane adds a state seeded with what its drop sets.
317
- Flowchart.library.states(steps.read(), {
318
- name: "Steps", icon: "box", source: "steps",
319
- label: s => s.name, meta: (_s, code) => some(code), group: s => s.kind,
320
- drop: (s, code) => Flowchart.patch(Flowchart.Types.State, { key: code, label: some(s.name), members: s.slots }),
542
+ states: {
543
+ source: Data.bindPaged(depotStates, { indexes: ["flowchart_states_by_flow", "flowchart_states_by_lane"] }),
544
+ icon: { prefix: "fas", name: "circle-nodes" },
545
+ // Each field the rail offers is one an index answers: the flow, and the lane after it.
546
+ fields: { flow: { label: "Flow", hints: ["Parcels", "Returns"] }, phase: { label: "Lane" } },
547
+ initial: { flow: ["Parcels"] },
548
+ },
549
+ transitions: {
550
+ source: Data.bindPaged(depotTransitions, { indexes: ["flowchart_transitions_by_flow"] }),
551
+ icon: { prefix: "fas", name: "arrow-right-long" },
552
+ fields: { flow: { label: "Flow", hints: ["Parcels", "Returns"] } },
553
+ initial: { flow: ["Parcels"] },
554
+ },
555
+ // Each service's own figures: the services picked weigh the states' details, and narrow no row.
556
+ evidence: {
557
+ source: evidence,
558
+ icon: { prefix: "fas", name: "boxes-stacked" },
559
+ fields: { byService: { label: "Service", hints: ["Standard", "Priority", "Economy", "International"] } },
560
+ },
561
+ stepCards: { source: Data.bindPaged(stepCards, { indexes: ["flowchart_step_cards_by_group"] }), fields: { group: { label: "Group" } } },
562
+ moveCards: { source: Data.bindPaged(moveCards, { indexes: ["flowchart_move_cards_by_group"] }), fields: { group: { label: "Group" } } },
563
+ laneCards: { source: Data.bindPaged(laneCards, { indexes: ["flowchart_lane_cards_by_group"] }), fields: { group: { label: "Group" } } },
564
+ }, { presets: [
565
+ { id: "parcels", name: "Parcels", where: { states: { flow: ["Parcels"] }, transitions: { flow: ["Parcels"] } } },
566
+ { id: "returns", name: "Returns", where: { states: { flow: ["Returns"] }, transitions: { flow: ["Returns"] } } },
567
+ ] }));
568
+ return (_jsx(Box, { height: "640px", children: _jsx(Flowchart, { slice: { slice }, states: Flowchart.states(states, {
569
+ name: "State", icon: "circle-nodes", entries: stateEntries,
570
+ label: "name", lane: "phase", order: "seq",
571
+ members: (s) => s.slots,
572
+ // Drawn in this order on each state's card and in the inspector, each where its show says — "all" unless given.
573
+ // The services the rail picks weigh each read their figures hold, added up by kind; the equipment, the
574
+ // shifts and the Service list, which they lack, draw the state's own.
575
+ details: Flowchart.details(evidence, {
576
+ source: "evidence",
577
+ details: [
578
+ Flowchart.figure("parcels", { label: "Parcels", unit: "parcels" }),
579
+ Flowchart.figure("waiting", { label: "Still in state", show: "inspector" }),
580
+ // each tag's look, as a Tag takes it — first defined, first shown
581
+ Flowchart.tags("flags", {
582
+ label: "Flags",
583
+ colors: {
584
+ "Hazmat": { colorPalette: "danger", variant: "solid" },
585
+ "At risk": { colorPalette: "warning", variant: "subtle" },
586
+ "Customs": { colorPalette: "brand", variant: "outline" },
587
+ "Oversize": { colorPalette: "orange", variant: "subtle" },
588
+ "Fragile": { colorPalette: "purple", variant: "subtle" },
589
+ "Cold chain": { colorPalette: "info", variant: "subtle" },
590
+ },
591
+ legend: true, // the legend lists them, under "Flags"
592
+ }),
593
+ Flowchart.tags("equipment", {
594
+ label: "Equipment",
595
+ colors: {
596
+ "Conveyor": { colorPalette: "teal" }, // subtle unless given
597
+ "Scanner": { colorPalette: "blue" },
598
+ "Forklift": { colorPalette: "gray", variant: "outline" },
599
+ "Label printer": { colorPalette: "purple", variant: "outline" },
600
+ "X-ray": { colorPalette: "info", variant: "outline" },
601
+ },
602
+ legend: true,
603
+ }),
604
+ Flowchart.tags("shifts", {
605
+ label: "Shifts",
606
+ colors: {
607
+ "Early": { colorPalette: "yellow" },
608
+ "Late": { colorPalette: "orange" },
609
+ "Night": { colorPalette: "purple", variant: "solid" },
610
+ "Weekend": { colorPalette: "gray" },
611
+ },
612
+ }),
613
+ // the app's bins, in hours — a quarter hour apiece at first, then hours, days and a
614
+ // week — a bar each whatever its span, on an axis naming 1h, 12h, 2d and 1w
615
+ Flowchart.histogram("hours", {
616
+ unit: "hours", label: "Time in state", counts: "parcels",
617
+ bins: [0, 0.25, 0.5, 1, 2, 4, 8, 12, 24, 48, 96, 168],
618
+ ticks: [1, 12, 48, 168],
619
+ }),
620
+ Flowchart.list("service", { label: "Service", top: 2, unit: "parcels" }),
621
+ Flowchart.list("exceptions", { label: "Exceptions", unit: "parcels", show: "inspector" }),
622
+ ],
623
+ }),
624
+ // the Steps tab's cards: a card dropped on a lane adds a state there, from its values
625
+ templates: Flowchart.templates(steps.read(), {
626
+ name: (c) => c.name, group: (c) => some(c.group), values: (c) => c.values, source: "stepCards",
627
+ }),
628
+ }), transitions: Flowchart.transitions(transitions, {
629
+ name: "Transition", icon: "arrow-right-long", entries: transitionEntries,
630
+ from: "src", to: "dst", decision: "trigger",
631
+ kind: (t) => t.kind,
632
+ evidence: (t) => some({ volume: t.volume, count: t.n, measuredAt: t.at, unit: some("parcels") }),
633
+ // Evidence shows them, so the form leaves them out.
634
+ fields: { volume: Fields.hidden(), n: Fields.hidden(), at: Fields.hidden() },
635
+ // The label draws the region under its evidence; the inspector shows all three.
636
+ details: Flowchart.details(moveRows, {
637
+ details: [
638
+ Flowchart.list("region", { label: "Region", top: 1, unit: "parcels" }),
639
+ Flowchart.list("service", { label: "Service", unit: "parcels", show: "inspector" }),
640
+ // a Dict of structs: its draw says which number is the value, and a note
641
+ Flowchart.list("origins", { label: "Origin", unit: "parcels", show: "inspector" }, (o) => ({ value: o.parcels, note: some(East.str `${o.late} late`) })),
642
+ ],
643
+ }),
644
+ // the Transitions tab's cards: a card dropped on a transition gives it its values
645
+ templates: Flowchart.templates(moves.read(), {
646
+ name: (c) => c.name, group: (c) => some(c.group), values: (c) => c.values, source: "moveCards",
321
647
  }),
322
- // Transition types, a templates record by name: a card dropped on a transition retypes it.
323
- Flowchart.library.transitions(moves.read(), {
324
- icon: "arrow-right", source: "moves",
325
- label: (_m, name) => name, meta: m => some(m.note),
326
- drop: m => Flowchart.patch(Flowchart.Types.Link, { kind: some(m.kind), trigger: m.decision }),
648
+ }), lanes: Flowchart.lanes(lanes, {
649
+ label: "label", order: "seq",
650
+ // the Lanes tab's cards: one dropped between two lanes adds a lane there, from its values
651
+ templates: Flowchart.templates(laneRows.read(), {
652
+ name: (c) => c.name, group: (c) => some(c.group), values: (c) => c.values, source: "laneCards",
327
653
  }),
328
- // The author's own cards, a record of roles: a role dropped on a decision owns it.
654
+ }), decisions: Flowchart.decisions(decisions, { label: (d) => d.name, owner: (d) => some(d.owner) }), library: [
655
+ Flowchart.library.states(), // Steps: the states' cards, by group
656
+ Flowchart.library.transitions(), // Transitions: the transitions' cards
657
+ Flowchart.library.lanes(), // Lanes: the lanes' cards
329
658
  Flowchart.library.tab(owners.read(), {
330
- name: "Owners", icon: "user-tie", source: "owners",
331
- key: (_o, role) => role, label: o => o.name, meta: o => some(o.desk),
332
- drop: (_o, role) => Flowchart.patch(Flowchart.Types.Trigger, { owner: some(role) }),
659
+ name: "Owners", icon: "user-tie", label: (o) => o.name, meta: (o) => some(o.desk),
660
+ // its patch is over a decision's row: dropped on a diamond, the card sets the decision's owner
661
+ drop: (o) => Flowchart.patch(DepotDecision, { owner: o.name }),
333
662
  }),
334
- ] }) }));
663
+ ], freshness: { label: "evidence-2026.06", date: new Date("2026-06-30T00:00:00Z") }, name: "depot" }) }));
335
664
  } }))),
336
665
  inputs: [],
337
666
  });
338
- /**
339
- * A flow from the host's tables (§3.4) — the depot's steps by phase, the
340
- * transitions mined from its scans and its decisions, each an e3 input of the
341
- * app's own rows, built into one flow by `Flowchart.over` through their row
342
- * mappers and shown read only: decision triggers, evidence-weighted links, a
343
- * ×14 state class, an ↻ in-place loop and an unresolved ghost. The freshness
344
- * chip names the evidence. Its one pane is the inspector, every field of what
345
- * is selected printed, its Issues the unresolved transition.
346
- */
347
- export const flowchartDepot = example({
348
- keywords: ["Flowchart", "Flowchart.over", "data", "states", "links", "lanes", "tables", "row mappers", "minimal", "planned", "observed", "triggers", "evidence", "Data.bind", "e3.input", "scans", "inspector", "Details", "Issues", "read only", "state class", "in-place", "unresolved", "freshness"],
349
- description: "Parcel-depot flowchart over the host's tables, each an e3 input bound with Data.bind and built into one flow by Flowchart.over, read only — decision triggers, evidence-weighted links, a ×14 state class, an ↻ in-place loop, an unresolved ghost, the freshness chip, and the inspector showing the selected state, transition or decision read only, its Issues the unresolved transition",
667
+ export const flowchartDepotEditing = example({
668
+ keywords: ["Flowchart", "records", "Record.bind", "editing", "Save", "undo", "add lane", "add state", "move", "rename",
669
+ "Connect", "Del", "keys", "ready", "patch door"],
670
+ description: "The depot's four records bound editable and read whole: a lane added and renamed, a state added in its lane's editor and moved between two others, a transition connected, a state deleted with the transitions naming it, a drafted state held back until it names its flow, and Save writing each record through its own patch door",
350
671
  fn: East.function([], UIComponentType, (_$) => (_jsx(Reactive, { children: $ => {
351
- const states = $.let(Data.bind(depotStates));
352
- const scans = $.let(Data.bind(scanTransitions));
353
- const decisions = $.let(Data.bind(depotDecisions));
354
- return (_jsx(Box, { height: "600px", children: _jsx(Flowchart, { data: Flowchart.over(states.read(), {
355
- state: s => ({ key: s.code, label: s.name, lane: s.phase, members: s.slots }),
356
- links: scans.read(),
357
- link: l => ({
358
- key: l.id, from: l.src, to: l.dst, kind: l.kind, trigger: l.trigger,
359
- evidence: { volume: l.parcels, count: l.n, measuredAt: some(l.at), unit: "parcels" },
360
- }),
361
- lanes: [
362
- { key: "intake", label: "Intake" }, { key: "induct", label: "Induct" },
363
- { key: "sort", label: "Sort" }, { key: "hold", label: "Hold" },
364
- { key: "dispatch", label: "Dispatch" },
365
- ],
366
- triggers: decisions.read(),
367
- trigger: t => ({ key: t.id, label: t.name, owner: t.who }),
368
- }), freshness: { label: "evidence-2026.06", date: new Date("2026-06-30T00:00:00Z") }, name: "scans" }) }));
672
+ const states = $.let(Record.bind(depotStates));
673
+ const transitions = $.let(Record.bind(depotTransitions));
674
+ const lanes = $.let(Record.bind(depotLanes));
675
+ const decisions = $.let(Record.bind(depotDecisions));
676
+ return (_jsx(Box, { height: "600px", children: _jsx(Flowchart, { states: Flowchart.states(states, {
677
+ label: "name", lane: "phase", order: "seq", members: (s) => s.slots,
678
+ // The app's check on a drafted state: Save waits until it names its flow, and Issues says why.
679
+ ready: (s) => s.flow.equal("").ifElse(() => variant("incomplete", [{ field: "flow", message: "Give the state its flow" }]), () => variant("ready", null)),
680
+ }), transitions: Flowchart.transitions(transitions, { from: "src", to: "dst", decision: "trigger", kind: (t) => t.kind }), lanes: Flowchart.lanes(lanes, { label: "label", order: "seq" }), decisions: Flowchart.decisions(decisions, { label: (d) => d.name, owner: (d) => some(d.owner) }), name: "depotEditing" }) }));
369
681
  } }))),
370
682
  inputs: [],
371
683
  });
372
- /**
373
- * One flow of the host's — the hand-over from the last scan to the door — an
374
- * input of one flow, its value written with `Flowchart.value`, bound with
375
- * `Data.bind` and shown read only, top down. It is given no pane: no
376
- * library, and `inspector={false}` — its toolbar, its canvas and its footer.
377
- */
378
- export const flowchartHandover = example({
379
- keywords: ["Flowchart", "data", "Flow", "Flowchart.value", "Data.bind", "one flow", "e3.input", "read only", "orientation", "TD", "top down", "inspector={false}", "no pane", "toolbar", "footer"],
380
- description: "One flow of the host's — the hand-over from the last scan to the door — an input bound with Data.bind and shown read only, top down, with no pane: its toolbar, its canvas and its footer",
684
+ export const flowchartDepotDimmed = example({
685
+ keywords: ["Flowchart", "Slice.bindRecords", "narrowed", "dim", "Data.bindPaged", "read only", "records", "context",
686
+ "source", "weigh", "weighed", "index.entries", "initial", "no data"],
687
+ description: "The depot's states and transitions read only through their sources of the rail, the narrowing drawn as context: every row read, the states and transitions it leaves out faded and selected by no path, their details read by key and weighed by the one service the rail opens on — Held's time in state its international parcels' own, and the returns' states, which hold none, saying no data",
381
688
  fn: East.function([], UIComponentType, (_$) => (_jsx(Reactive, { children: $ => {
382
- const handover = $.let(Data.bind(handoverFlow));
383
- return (_jsx(Box, { height: "500px", children: _jsx(Flowchart, { data: handover, orientation: "TD", inspector: false, name: "handover" }) }));
689
+ // Read only, through their sources: bound with Data.bindPaged alone.
690
+ const states = $.let(Data.bindPaged(depotStates));
691
+ const transitions = $.let(Data.bindPaged(depotTransitions));
692
+ const lanes = $.let(Data.bind(depotLanes));
693
+ // The states' evidence, its entries index listed: the rail's evidence source, and the details its picks weigh.
694
+ const evidence = $.let(Data.bindPaged(stateEvidence, { indexes: ["flowchart_evidence_by_service"] }));
695
+ // The parcels' Hold lane in focus: an index on the flow and the lane answers the two together. The international
696
+ // parcels' own figures weigh the details: the one service picked.
697
+ const slice = $.let(Slice.bindRecords("flowchart.depotDimmed", {
698
+ states: {
699
+ source: Data.bindPaged(depotStates, { indexes: ["flowchart_states_by_flow", "flowchart_states_by_lane"] }),
700
+ fields: { flow: { label: "Flow", hints: ["Parcels", "Returns"] }, phase: { label: "Lane" } },
701
+ initial: { flow: ["Parcels"], phase: ["hold"] },
702
+ },
703
+ transitions: {
704
+ source: Data.bindPaged(depotTransitions, { indexes: ["flowchart_transitions_by_flow"] }),
705
+ fields: { flow: { label: "Flow", hints: ["Parcels", "Returns"] } },
706
+ },
707
+ evidence: {
708
+ source: evidence,
709
+ fields: { byService: { label: "Service", hints: ["Standard", "Priority", "Economy", "International"] } },
710
+ initial: { byService: ["International"] },
711
+ },
712
+ }));
713
+ return (_jsx(Box, { height: "640px", children: _jsx(Flowchart, { slice: { slice }, narrowed: "dim", states: Flowchart.states(states, {
714
+ label: "name", lane: "phase", order: "seq", members: (s) => s.slots,
715
+ // Time in state weighed by the service picked; the Service list, which the entries lack, the state's own mix.
716
+ details: Flowchart.details(evidence, {
717
+ source: "evidence",
718
+ details: [
719
+ Flowchart.histogram("hours", { unit: "hours", label: "Time in state", counts: "parcels",
720
+ bins: [0, 0.25, 0.5, 1, 2, 4, 8, 12, 24, 48, 96, 168], ticks: [1, 12, 48, 168] }),
721
+ Flowchart.list("service", { label: "Service", top: 2 }),
722
+ ],
723
+ }),
724
+ }), transitions: Flowchart.transitions(transitions, { from: "src", to: "dst", kind: (t) => t.kind }), lanes: Flowchart.lanes(lanes, { label: "label", order: "seq" }), name: "depotDimmed" }) }));
384
725
  } }))),
385
726
  inputs: [],
386
727
  });
387
- /**
388
- * A record's one flow, edited, with its own Details (#1247, #1250): the
389
- * collections, a record of flows with one entry bound with its patch
390
- * mutation. Every gesture on the canvas is a draft of its editing session —
391
- * "+ LANE", a lane's header renamed and its ×, the "+ STATE" ghost, a state
392
- * double-clicked into its editor or dragged across lanes, a handle dragged to
393
- * another state, Del on the selection — which the history item undoes,
394
- * redoes and discards, and Save commits as one patch through the record's
395
- * patch mutation. `canConnect` keeps every transition out of the booking: a
396
- * draft never snaps onto BKD from another state. The inspector shows a
397
- * state's own Details — its key and label, its lane, and a button that gives
398
- * it one more member — and a transition's own — its ends, its kind, and a
399
- * button that marks it observed — each in place of its kind's form, each
400
- * button's `update` one transaction of the flow's session. A decision's and a
401
- * lane's Details are their forms, and Issues lists the flow's issues.
402
- */
403
- export const flowchartDetail = example({
404
- keywords: ["Flowchart", "record", "Record.bind", "one flow", "one entry", "lone flow", "editing", "builder", "Save", "undo", "redo", "history", "+ LANE", "+ STATE", "connect", "canConnect", "Del", "rename", "move", "authoring", "interactive", "edit", "inspector", "Details", "own Details", "update", "one transaction", "state", "transition", "Button", "Issues"],
405
- description: "A record's one flow — the collections, from the booking to the depot's door — edited on the canvas: + LANE, lane rename and ×, the + STATE ghost, double-click edit, cross-lane drag, handle-drag connecting and Del, each a draft the history item undoes and Save commits through the record's patch mutation, a canConnect veto keeping transitions out of the booking; and the inspector's own Details by kind — a state's, whose button gives it one more member, and a transition's, whose button marks it observed — each in place of its form, each button's update one transaction",
728
+ export const flowchartDepotPhone = example({
729
+ keywords: ["Flowchart", "records", "details", "mobile", "phone", "narrow", "390px", "Find state", "inspector"],
730
+ description: "The depot's flowchart at a phone's width: cards keep their bars and lines and the canvas pans; Find state selects a state, the inspector shows its reads and its form, and its lane is chosen there",
406
731
  fn: East.function([], UIComponentType, (_$) => (_jsx(Reactive, { children: $ => {
407
- const flows = $.let(Record.bind(collectionFlows));
408
- // The connection veto: nothing comes back to the booking, though a
409
- // drop on BKD from BKD is its in-place transition.
410
- const canConnect = $.const(East.function([StringType, StringType], BooleanType, (_$2, from, to) => East.equal(to, "BKD").not().or(() => East.equal(from, to))));
411
- // A state's own Details: its key, its label and its lane, and one more member — the edited state goes back through `update`.
412
- const state = $.const(East.function([Flowchart.Types.State, FunctionType([Flowchart.Types.State], NullType)], UIComponentType, ($2, s, update) => {
413
- const label = $2.let(s.label.match({ none: () => s.key, some: (_$3, l) => l }));
414
- const members = $2.let(s.members.match({ none: () => 1n, some: (_$3, n) => n.add(1n) }));
415
- const grow = $2.const(East.function([], NullType, ($3) => {
416
- // East has no struct spread: the state, rebuilt with its new members.
417
- const edited = $3.const({ key: s.key, label: s.label, lane: s.lane, members: some(members), notes: s.notes }, Flowchart.Types.State);
418
- $3(update(edited));
419
- }));
420
- return (_jsxs(VStack, { gap: "2", align: "stretch", children: [_jsx(Text, { fontFamily: "mono", fontWeight: "bold", children: East.str `${s.key} · ${label}` }), _jsx(Text, { color: "fg.muted", children: East.str `In the ${s.lane} lane` }), _jsx(Button, { variant: "outline", onClick: grow, children: "One more member" })] }));
421
- }));
422
- // A transition's own Details: its ends and its kind, and a mark of it observed — the edited transition goes back through `update`.
423
- const transition = $.const(East.function([Flowchart.Types.Link, FunctionType([Flowchart.Types.Link], NullType)], UIComponentType, ($2, l, update) => {
424
- const kind = $2.let(l.kind.match({ none: () => "planned", some: (_$3, k) => k.getTag() }));
425
- const observe = $2.const(East.function([], NullType, ($3) => {
426
- const edited = $3.const({ key: l.key, from: l.from, to: l.to, kind: some(variant("observed", null)), trigger: l.trigger, evidence: l.evidence }, Flowchart.Types.Link);
427
- $3(update(edited));
428
- }));
429
- return (_jsxs(VStack, { gap: "2", align: "stretch", children: [_jsx(Text, { fontFamily: "mono", fontWeight: "bold", children: East.str `${l.from} → ${l.to}` }), _jsx(Text, { color: "fg.muted", children: East.str `Its kind: ${kind}` }), _jsx(Button, { variant: "outline", onClick: observe, children: "Mark it observed" })] }));
430
- }));
431
- return (_jsx(Box, { height: "560px", children: _jsx(Flowchart, { record: flows, canConnect: canConnect, inspector: { state, transition }, name: "detail" }) }));
732
+ const states = $.let(Record.bind(depotStates));
733
+ const transitions = $.let(Record.bind(depotTransitions));
734
+ const lanes = $.let(Data.bind(depotLanes));
735
+ const stateRows = $.let(Data.bind(stateEvidence));
736
+ return (_jsx(Box, { width: "390px", maxWidth: "100%", height: "720px", children: _jsx(Flowchart, { states: Flowchart.states(states, {
737
+ label: "name", lane: "phase", order: "seq", members: (s) => s.slots,
738
+ details: Flowchart.details(stateRows, {
739
+ details: [
740
+ Flowchart.histogram("hours", { unit: "hours", label: "Time in state", counts: "parcels",
741
+ bins: [0, 0.25, 0.5, 1, 2, 4, 8, 12, 24, 48, 96, 168], ticks: [1, 12, 48, 168] }),
742
+ Flowchart.list("service", { label: "Service", top: 2 }),
743
+ ],
744
+ }),
745
+ }), transitions: Flowchart.transitions(transitions, { from: "src", to: "dst", kind: (t) => t.kind }), lanes: Flowchart.lanes(lanes, { label: "label", order: "seq" }), name: "depotPhone" }) }));
432
746
  } }))),
433
747
  inputs: [],
434
748
  });
435
- // A network's route flowcharts: enough independent record entries to exercise
436
- // multiple pages and eviction. Each entry remains one complete graph.
437
- export const indexedFlows = e3.record("flowchart_indexed_flows", Flowchart.Types.Flows, {
438
- initial: Flowchart.values(Object.fromEntries(Array.from({ length: 2048 }, (_, i) => {
439
- const checks = [
440
- { key: "CHK", label: "Checked", lane: "review" },
441
- { key: "HLD", label: "Held", lane: "review" },
442
- { key: "REL", label: "Released", lane: "review" },
443
- ].slice(0, i % 4);
444
- const states = [
445
- { key: "ARV", label: "Arrived", lane: "intake" },
446
- { key: "SCN", label: "Scanned", lane: "intake" },
447
- ...checks,
448
- { key: "LDD", label: "Loaded", lane: "dispatch" },
449
- ];
450
- return [`FLOW-${10000 + i}`, {
451
- description: ["Inbound parcels", "Returns", "Collections"][i % 3],
452
- lanes: [{ key: "intake", label: "Intake" },
453
- ...(checks.length ? [{ key: "review", label: "Review" }] : []),
454
- { key: "dispatch", label: "Dispatch" }],
455
- states,
456
- links: states.slice(1).map((state, j) => ({ from: states[j].key, to: state.key,
457
- ...(j === 0 && i % 5 !== 0 ? { trigger: "route" } : {}) })),
458
- triggers: i % 5 === 0 ? [] : [{ key: "route", label: "Route", owner: ["sort-planner", "customs-desk", "shift-lead"][Math.floor(i / 4) % 3] }],
459
- }];
460
- }))),
461
- indexes: (index) => ({
462
- // A flow's name is its record's key: an index of its own, so the Flows tab's
463
- // search finds a flow by its name (#1346), alone and after a description.
464
- name: index.key(East.function([StringType, Flowchart.Types.Flow], StringType, (_$, name, _flow) => name)),
465
- flowchart_by_description: index.on(["description"]),
466
- flowchart_by_description_name: index.key(East.function([StringType, Flowchart.Types.Flow], StructType({ description: OptionType(StringType), name: StringType }), (_$, name, flow) => ({ description: flow.description, name }))),
467
- // Slice derives controls from each computed index’s declared key type. Scalar
468
- // keys use the index name; a composite key supplies its field names.
469
- stateCount: index.key(East.function([StringType, Flowchart.Types.Flow], IntegerType, (_$, _id, flow) => flow.states.size())),
470
- flowchart_by_description_state_count: index.key(East.function([StringType, Flowchart.Types.Flow], StructType({ description: OptionType(StringType), stateCount: IntegerType }), (_$, _id, flow) => ({ description: flow.description, stateCount: flow.states.size() }))),
471
- lane: index.keys(East.function([StringType, Flowchart.Types.Flow], SetType(StringType), (_$, _id, flow) => flow.lanes.toSet((_$2, lane) => lane.key))),
472
- decisionOwner: index.keys(East.function([StringType, Flowchart.Types.Flow], SetType(OptionType(StringType)), (_$, _id, flow) => flow.triggers.toSet((_$2, trigger) => trigger.owner))),
473
- }),
474
- mutations: (mutation) => ({
475
- patch: mutation.patch(),
476
- }),
749
+ export const flowchartDepotTopDown = example({
750
+ keywords: ["Flowchart", "orientation", "TD", "top down", "minimap", "legend", "readOnly", "read only", "inspector={false}", "no pane",
751
+ "onSelectState", "onSelectLink", "onSelectTrigger", "onTracePath", "selection", "trace", "State.bind", "records"],
752
+ description: "The depot's four records shown read only and top down — its lanes stacked down the canvas, the minimap drawn and the legend left out, with no inspector and no library — the host hearing each state, transition and decision selected and each path traced by an ⌥-click, and showing what it heard last",
753
+ fn: East.function([], UIComponentType, (_$) => (_jsx(Reactive, { children: $ => {
754
+ // Bound editable, shown read only: `readOnly` turns every gesture off, whatever the bindings could write.
755
+ const states = $.let(Record.bind(depotStates));
756
+ const transitions = $.let(Record.bind(depotTransitions));
757
+ const lanes = $.let(Record.bind(depotLanes));
758
+ const decisions = $.let(Record.bind(depotDecisions));
759
+ // What the host heard last: the viewer's own, kept under its key.
760
+ const heardBind = $.let(State.bind([StringType], "flowchart_depot_heard", ""));
761
+ const heard = $.let(heardBind.read());
762
+ const onSelectState = $.const(East.function([StringType], NullType, ($2, key) => { $2(heardBind.write(East.str `onSelectState: ${key}`)); }));
763
+ const onSelectLink = $.const(East.function([StringType], NullType, ($2, key) => { $2(heardBind.write(East.str `onSelectLink: ${key}`)); }));
764
+ const onSelectTrigger = $.const(East.function([StringType], NullType, ($2, key) => { $2(heardBind.write(East.str `onSelectTrigger: ${key}`)); }));
765
+ const onTracePath = $.const(East.function([StringType], NullType, ($2, key) => { $2(heardBind.write(East.str `onTracePath: ${key}`)); }));
766
+ return (_jsxs(VStack, { align: "stretch", gap: "3", children: [_jsx(Badge, { colorPalette: "brand", variant: "outline", children: East.equal(heard.length(), 0n).ifElse((_$2) => "Select a state, a transition or a decision", (_$2) => heard) }), _jsx(Box, { height: "640px", children: _jsx(Flowchart, { states: Flowchart.states(states, { label: "name", lane: "phase", order: "seq", members: (s) => s.slots }), transitions: Flowchart.transitions(transitions, { from: "src", to: "dst", decision: "trigger", kind: (t) => t.kind }), lanes: Flowchart.lanes(lanes, { label: "label", order: "seq" }), decisions: Flowchart.decisions(decisions, { label: (d) => d.name, owner: (d) => some(d.owner) }), orientation: "TD", minimap: true, legend: false, readOnly: true, inspector: false, onSelectState: onSelectState, onSelectLink: onSelectLink, onSelectTrigger: onSelectTrigger, onTracePath: onTracePath, name: "depotTopDown" }) })] }));
767
+ } }))),
768
+ inputs: [],
477
769
  });
478
- export const flowchartRecordIndexes = example({
479
- keywords: ["Flowchart", "record", "indexes", "computed indexes", "state count", "lane", "decision owner", "Slice.bindRecords", "flows", "Data.bindPaged", "paging", "Flows tab", "count", "search", "mobile", "Save"],
480
- description: "2,048 route flowcharts in a paged record, narrowed through the rail's flows source by maintained indexes on name, description, computed state count, lane and decision owner. Choose an exact description plus a state-count range together; lane and owner use exact membership. The Flows tab pages and counts what the rail narrows to, its search box finds a flow by name within it, and drafts keep their original record ID through filtering and Save.",
770
+ export const flowchartWording = example({
771
+ keywords: ["Flowchart", "name", "vocabulary", "planned", "observed", "words", "Flowchart.states", "Flowchart.transitions",
772
+ "Flowchart.lanes", "Flowchart.decisions", "Flowchart.library", "Slice.bindRecords", "records"],
773
+ description: "The depot in its own words (#1516): each kind named by its own `name` — a stop, a hop, a stage and a choice — and `vocabulary` naming a transition's planned and observed kinds, wherever the flowchart draws them: its tabs, canvas, legend, inspector, footer, find box and refusals",
481
774
  fn: East.function([], UIComponentType, (_$) => (_jsx(Reactive, { children: $ => {
482
- const flows = $.let(Record.bind(indexedFlows));
483
- // One rail over the flows (#1346): its `flows` source narrows the Flows tab, which pages and counts what it narrows to.
484
- const slice = $.let(Slice.bindRecords("flowchart.recordIndexes", {
485
- flows: {
486
- source: Data.bindPaged(indexedFlows, { indexes: ["name", "flowchart_by_description", "flowchart_by_description_name", "stateCount", "flowchart_by_description_state_count", "lane", "decisionOwner"] }),
487
- fields: {
488
- description: { label: "Flows" },
489
- stateCount: { label: "State count" },
490
- lane: { label: "Lane" },
491
- decisionOwner: { label: "Decision owner" },
492
- name: { label: "Name" },
493
- },
494
- search: ["name", "description", "lane", "decisionOwner"],
775
+ const states = $.let(Record.bind(depotStates));
776
+ const stateEntries = $.let(Data.bindPaged(depotStates));
777
+ const transitions = $.let(Record.bind(depotTransitions));
778
+ const transitionEntries = $.let(Data.bindPaged(depotTransitions));
779
+ const lanes = $.let(Record.bind(depotLanes));
780
+ const decisions = $.let(Record.bind(depotDecisions));
781
+ const steps = $.let(Data.bind(stepCards));
782
+ const moves = $.let(Data.bind(moveCards));
783
+ const laneRows = $.let(Data.bind(laneCards));
784
+ // The rail is the app's to word: each source's label, and its fields'.
785
+ const slice = $.let(Slice.bindRecords("flowchart.wording", {
786
+ states: {
787
+ source: Data.bindPaged(depotStates, { indexes: ["flowchart_states_by_flow"] }), label: "Stops",
788
+ fields: { flow: { label: "Route", hints: ["Parcels", "Returns"] } },
789
+ initial: { flow: ["Parcels"] },
790
+ },
791
+ transitions: {
792
+ source: Data.bindPaged(depotTransitions, { indexes: ["flowchart_transitions_by_flow"] }), label: "Hops",
793
+ fields: { flow: { label: "Route", hints: ["Parcels", "Returns"] } },
794
+ initial: { flow: ["Parcels"] },
495
795
  },
496
- }, {
497
- presets: [
498
- { id: "inbound", name: "Inbound", where: { flows: { description: ["Inbound parcels"] } } },
499
- { id: "inbound-review", name: "Inbound · 4–6 states", where: { flows: { description: ["Inbound parcels"], stateCount: { from: 4n, to: 7n } } } },
500
- { id: "review", name: "Review lane", where: { flows: { lane: ["review"] } } },
501
- { id: "customs", name: "Customs decisions", where: { flows: { decisionOwner: ["customs-desk"] } } },
502
- ],
796
+ stepCards: { source: Data.bindPaged(stepCards, { indexes: ["flowchart_step_cards_by_group"] }), label: "Stop cards", fields: { group: { label: "Group" } } },
797
+ moveCards: { source: Data.bindPaged(moveCards, { indexes: ["flowchart_move_cards_by_group"] }), label: "Hop cards", fields: { group: { label: "Group" } } },
798
+ laneCards: { source: Data.bindPaged(laneCards, { indexes: ["flowchart_lane_cards_by_group"] }), label: "Stage cards", fields: { group: { label: "Group" } } },
503
799
  }));
504
- return (_jsx(Box, { width: "100%", height: "640px", children: _jsx(Flowchart, { record: flows, slice: { slice, affordances: ["fields", "search", "presets", "summary"] }, library: [Flowchart.library.flows()], name: "recordIndexes" }) }));
800
+ return (_jsx(Box, { height: "640px", children: _jsx(Flowchart, { slice: { slice },
801
+ // Each kind's name is the app's word for it, which the flowchart says wherever it speaks of one.
802
+ states: Flowchart.states(states, {
803
+ name: "Stop", entries: stateEntries,
804
+ label: "name", lane: "phase", order: "seq", members: (s) => s.slots,
805
+ templates: Flowchart.templates(steps.read(), {
806
+ name: (c) => c.name, group: (c) => some(c.group), values: (c) => c.values, source: "stepCards",
807
+ }),
808
+ }), transitions: Flowchart.transitions(transitions, {
809
+ name: "Hop", entries: transitionEntries,
810
+ from: "src", to: "dst", decision: "trigger", kind: (t) => t.kind,
811
+ templates: Flowchart.templates(moves.read(), {
812
+ name: (c) => c.name, group: (c) => some(c.group), values: (c) => c.values, source: "moveCards",
813
+ }),
814
+ }), lanes: Flowchart.lanes(lanes, {
815
+ name: "Stage", label: "label", order: "seq",
816
+ templates: Flowchart.templates(laneRows.read(), {
817
+ name: (c) => c.name, group: (c) => some(c.group), values: (c) => c.values, source: "laneCards",
818
+ }),
819
+ }), decisions: Flowchart.decisions(decisions, { name: "Choice", label: (d) => d.name, owner: (d) => some(d.owner) }),
820
+ // What no kind names: a transition's two kinds.
821
+ vocabulary: { planned: "Designed", observed: "Seen" },
822
+ // The Steps tab keeps its name; the Hops and Stages tabs are named by their kinds.
823
+ library: [Flowchart.library.states(), Flowchart.library.transitions(), Flowchart.library.lanes()], name: "wording" }) }));
505
824
  } }))),
506
825
  inputs: [],
507
826
  });
508
- // ============================================================================
509
- // flowchartConflicts — your edits meeting someone else's save
510
- // ============================================================================
511
- /** The flows the conflicts example edits, in a record of their own, so no other example's edits meet them. */
512
- export const conflictFlows = e3.record("flowchart_conflict_flows", Flowchart.Types.Flows, {
513
- initial: Flowchart.values({
514
- "Inbound parcels": {
515
- description: "From the trailer to the van",
516
- lanes: [{ key: "intake", label: "Intake" }, { key: "sort", label: "Sort" }, { key: "load", label: "Load" }],
517
- states: [
518
- { key: "ARV", label: "Arrived", lane: "intake" },
519
- { key: "SCN", label: "Scanned", lane: "intake" },
520
- { key: "CH*", label: "Sort chutes", lane: "sort", members: 12n },
521
- { key: "LDD", label: "Loaded", lane: "load" },
522
- ],
523
- links: [
524
- { from: "ARV", to: "SCN" },
525
- { from: "SCN", to: "CH*", trigger: "route" },
526
- { from: "CH*", to: "LDD" },
527
- ],
528
- triggers: [{ key: "route", label: "route", owner: "sort-planner" }],
529
- },
530
- "Returns": {
531
- description: "From the counter back to the sender",
532
- lanes: [{ key: "counter", label: "Counter" }, { key: "check", label: "Check" }, { key: "out", label: "Out" }],
533
- states: [
534
- { key: "RCV", label: "Received", lane: "counter" },
535
- { key: "INS", label: "Inspected", lane: "check" },
536
- { key: "RSD", label: "Resent", lane: "out" },
537
- ],
538
- links: [{ from: "RCV", to: "INS" }, { from: "INS", to: "RSD" }],
539
- },
540
- }),
541
- mutations: (mutation) => ({
542
- // The flows' patch door — every Save commits through it.
543
- patch: mutation.patch(),
544
- // Someone else's save: every step of every flow renamed, " (theirs)" put on its name, or taken off again; its lane
545
- // and its other fields as they were.
546
- elsewhere: mutation.reduce(East.function([Flowchart.Types.Flows], Flowchart.Types.Flows, (_$, flows) => flows.map((_$2, flow) => ({
547
- description: flow.description,
548
- lanes: flow.lanes,
549
- states: flow.states.map(($3, state) => {
550
- const named = $3.let(state.label.match({ some: (_$4, label) => label, none: (_$4) => state.key }));
551
- return {
552
- key: state.key,
553
- label: East.value(some(named.endsWith(" (theirs)").ifElse(() => named.replace(" (theirs)", ""), () => named.concat(" (theirs)"))), OptionType(StringType)),
554
- lane: state.lane,
555
- members: state.members,
556
- notes: state.notes,
557
- };
558
- }),
559
- links: flow.links,
560
- triggers: flow.triggers,
561
- })))),
562
- }),
827
+ // The app's own tag looks, kept as data its users edit: a row a tag, the first ranked first.
828
+ export const flagColors = e3.input("flowchart_depot_flag_colors", ArrayType(Flowchart.Types.TagColor), variant("value", [
829
+ { tag: "Hazmat", colorPalette: variant("danger", null), variant: variant("solid", null) },
830
+ { tag: "At risk", colorPalette: variant("warning", null), variant: variant("subtle", null) },
831
+ { tag: "Customs", colorPalette: variant("brand", null), variant: variant("outline", null) },
832
+ ]));
833
+ export const flowchartFlagColors = example({
834
+ keywords: ["Flowchart", "details", "Flowchart.tags", "tags", "colors", "colorPalette", "StyleVariant", "legend", "Data.bind"],
835
+ description: "Each state's flags as tags on its card and in the legend, their looks read from the app's own data",
836
+ fn: East.function([], UIComponentType, (_$) => (_jsx(Reactive, { children: $ => {
837
+ const states = $.let(Data.bind(depotStates));
838
+ const transitions = $.let(Data.bind(depotTransitions));
839
+ const lanes = $.let(Data.bind(depotLanes));
840
+ const stateRows = $.let(Data.bind(stateEvidence));
841
+ const looks = $.let(Data.bind(flagColors));
842
+ return (_jsx(Box, { height: "600px", children: _jsx(Flowchart, { states: Flowchart.states(states, {
843
+ label: "name", lane: "phase", order: "seq",
844
+ details: Flowchart.details(stateRows, {
845
+ details: [Flowchart.tags("flags", { label: "Flags", colors: looks.read(), legend: true })],
846
+ }),
847
+ }), transitions: Flowchart.transitions(transitions, { from: "src", to: "dst" }), lanes: Flowchart.lanes(lanes, { label: "label", order: "seq" }), name: "flagColors" }) }));
848
+ } }))),
849
+ inputs: [],
563
850
  });
564
- /**
565
- * Your edits meeting someone else's save, in one window: edit, then press
566
- * Someone else saves, which saves another person's change to the same flows —
567
- * every step renamed. A step you renamed too is a conflict, waiting for you to
568
- * choose; a step you moved to another lane combines with theirs. Each press
569
- * saves their change again.
570
- */
571
- export const flowchartConflicts = example({
572
- keywords: ["Flowchart", "conflict", "conflicts", "combine", "someone else", "Choose", "rename", "step", "Record.bind", "mutate", "Button", "Save"],
573
- description: "Your edits meeting someone else's save, in one window — rename a step, then press Someone else saves, which saves another person's change to the same flows (every step renamed, \"(theirs)\" put on its name or taken off), so yours conflict and wait to be chosen; a step moved to another lane combines with theirs",
851
+ // A support desk's tickets: the states they pass through, the transitions between them, and the minutes
852
+ // each spent in each state. The app's task counts each state's tickets into the app's own bins — minutes at
853
+ // first, then hours, a shift and a day — an Array of counts, one a bin, keyed as the states are.
854
+ export const DeskState = StructType({ name: StringType, stage: StringType });
855
+ export const DeskTransition = StructType({ from: StringType, to: StringType });
856
+ export const DeskStage = StructType({ label: StringType, seq: IntegerType });
857
+ export const deskStates = e3.input("flowchart_desk_states", DictType(StringType, DeskState), variant("value", new Map([
858
+ ["NEW", { name: "New", stage: "open" }], ["TRI", { name: "Triaged", stage: "open" }],
859
+ ["WIP", { name: "In progress", stage: "work" }], ["WAI", { name: "Waiting on customer", stage: "work" }],
860
+ ["RES", { name: "Resolved", stage: "close" }],
861
+ ])));
862
+ export const deskTransitions = e3.input("flowchart_desk_transitions", DictType(StringType, DeskTransition), variant("value", new Map([
863
+ ["t1", { from: "NEW", to: "TRI" }], ["t2", { from: "TRI", to: "WIP" }], ["t3", { from: "WIP", to: "WAI" }],
864
+ ["t4", { from: "WAI", to: "WIP" }], ["t5", { from: "WIP", to: "RES" }],
865
+ ])));
866
+ export const deskStages = e3.input("flowchart_desk_stages", DictType(StringType, DeskStage), variant("value", new Map([
867
+ ["open", { label: "Open", seq: 1n }], ["work", { label: "Work", seq: 2n }], ["close", { label: "Close", seq: 3n }],
868
+ ])));
869
+ export const TicketMinutes = StructType({ minutes: ArrayType(IntegerType) });
870
+ export const ticketMinutes = e3.input("flowchart_ticket_minutes", DictType(StringType, TicketMinutes), variant("value", new Map([
871
+ ["NEW", { minutes: [140n, 96n, 120n, 64n, 30n, 22n, 9n, 4n, 2n, 1n, 0n, 0n] }],
872
+ ["TRI", { minutes: [62n, 88n, 131n, 90n, 41n, 25n, 12n, 6n, 3n, 1n, 0n, 0n] }],
873
+ ["WIP", { minutes: [3n, 8n, 41n, 96n, 120n, 150n, 132n, 88n, 40n, 18n, 9n, 4n] }],
874
+ ["WAI", { minutes: [0n, 1n, 2n, 6n, 9n, 14n, 30n, 58n, 74n, 66n, 41n, 22n] }],
875
+ // A resolved ticket stays resolved: the app counts no time in it, so its row is absent and its card says no data.
876
+ ])));
877
+ export const flowchartTicketMinutes = example({
878
+ keywords: ["Flowchart", "details", "Flowchart.histogram", "bins", "scale", "band", "linear", "ticks", "axis", "minutes", "time in state"],
879
+ description: "A support desk's flowchart with each state's minutes in state on its card, counted into the app's own uneven bins — a bar a bin — and the axis naming the edges the app lists, the last two in its own words",
574
880
  fn: East.function([], UIComponentType, (_$) => (_jsx(Reactive, { children: $ => {
575
- const flows = $.let(Record.bind(conflictFlows, ["patch"]));
576
- const others = $.let(Record.bind(conflictFlows, ["elsewhere"]));
577
- const theirs = $.const(East.function([], NullType, ($) => { $(others.mutate.elsewhere()); }));
578
- return (_jsxs(VStack, { gap: "3", align: "stretch", children: [_jsxs(HStack, { gap: "3", children: [_jsx(Button, { variant: "outline", onClick: theirs, loading: others.mutate.pending(), children: "Someone else saves" }), _jsx(Text, { color: "fg.muted", children: "Their change: every step renamed" })] }), _jsx(Box, { height: "500px", children: _jsx(Flowchart, { name: "conflicts", record: flows, flow: "Inbound parcels", library: [Flowchart.library.flows()] }) })] }));
881
+ const states = $.let(Data.bind(deskStates));
882
+ const transitions = $.let(Data.bind(deskTransitions));
883
+ const stages = $.let(Data.bind(deskStages));
884
+ const minutes = $.let(Data.bind(ticketMinutes));
885
+ return (_jsx(Box, { height: "560px", children: _jsx(Flowchart, { states: Flowchart.states(states, {
886
+ label: "name", lane: "stage",
887
+ details: Flowchart.details(minutes, {
888
+ details: [Flowchart.histogram("minutes", {
889
+ unit: "minutes",
890
+ label: "Time in state",
891
+ counts: "tickets",
892
+ // The edges, in minutes: an Array of counts is a bin each, in this order.
893
+ bins: [0, 1, 2, 5, 10, 15, 30, 60, 120, 240, 480, 1440],
894
+ // A bar a bin, whatever its span — the default; "linear" draws them to scale.
895
+ scale: "band",
896
+ // The edges the axis names besides 0: 5m and 1h printed from the unit,
897
+ // the last two in the app's own words.
898
+ ticks: [5, 60, { at: 480, label: "a shift" }, { at: 1440, label: "a day" }],
899
+ })],
900
+ }),
901
+ }), transitions: Flowchart.transitions(transitions, { from: "from", to: "to" }), lanes: Flowchart.lanes(stages, { label: "label", order: "seq" }), name: "ticketMinutes" }) }));
902
+ } }))),
903
+ inputs: [],
904
+ });
905
+ export const flowchartTicketMinutesLinear = example({
906
+ keywords: ["Flowchart", "details", "Flowchart.histogram", "bins", "scale", "linear", "to scale", "ticks", "axis", "minutes", "time in state"],
907
+ description: "The support desk's minutes in state drawn to scale: the same uneven bins, each bar as wide as its span and as tall as its count over it — so its area is its count — the open last bin as wide as the one before it",
908
+ fn: East.function([], UIComponentType, (_$) => (_jsx(Reactive, { children: $ => {
909
+ const states = $.let(Data.bind(deskStates));
910
+ const transitions = $.let(Data.bind(deskTransitions));
911
+ const stages = $.let(Data.bind(deskStages));
912
+ const minutes = $.let(Data.bind(ticketMinutes));
913
+ return (_jsx(Box, { height: "560px", children: _jsx(Flowchart, { states: Flowchart.states(states, {
914
+ label: "name", lane: "stage",
915
+ details: Flowchart.details(minutes, {
916
+ details: [Flowchart.histogram("minutes", {
917
+ unit: "minutes",
918
+ label: "Time in state",
919
+ counts: "tickets",
920
+ bins: [0, 1, 2, 5, 10, 15, 30, 60, 120, 240, 480, 1440],
921
+ // Each bar as wide as its span: the first hour is a sliver, the shift and the day most of the axis.
922
+ scale: "linear",
923
+ // The same ticks: to scale, 5m and 1h crowd 0 at the start and are left out.
924
+ ticks: [5, 60, { at: 480, label: "a shift" }, { at: 1440, label: "a day" }],
925
+ })],
926
+ }),
927
+ }), transitions: Flowchart.transitions(transitions, { from: "from", to: "to" }), lanes: Flowchart.lanes(stages, { label: "label", order: "seq" }), name: "ticketMinutesLinear" }) }));
579
928
  } }))),
580
929
  inputs: [],
581
930
  });