@almadar/std 16.173.0 → 16.174.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (203) hide show
  1. package/behaviors/lolo/infra/atoms/std-cross-reference.lolo +2 -4
  2. package/behaviors/lolo/ui/core/atoms/std-board.lolo +5 -9
  3. package/behaviors/lolo/ui/core/atoms/std-browse.lolo +8 -1
  4. package/behaviors/lolo/ui/core/atoms/std-esign-flow.lolo +2 -2
  5. package/behaviors/lolo/ui/core/atoms/std-event-log.lolo +3 -7
  6. package/behaviors/lolo/ui/core/atoms/std-form-advanced.lolo +1 -1
  7. package/behaviors/lolo/ui/core/atoms/std-image-upload-multi.lolo +1 -1
  8. package/behaviors/lolo/ui/core/atoms/std-list.lolo +3 -3
  9. package/behaviors/lolo/ui/core/atoms/std-modal.lolo +2 -2
  10. package/behaviors/lolo/ui/core/atoms/std-multi-party-flow.lolo +2 -4
  11. package/behaviors/lolo/ui/core/atoms/std-rating-review.lolo +5 -13
  12. package/behaviors/lolo/ui/core/atoms/std-recurrence.lolo +3 -7
  13. package/behaviors/lolo/ui/core/atoms/std-saved-search.lolo +1 -1
  14. package/behaviors/lolo/ui/core/atoms/std-signature-capture.lolo +2 -2
  15. package/behaviors/lolo/ui/core/atoms/std-step-flow.lolo +2 -4
  16. package/behaviors/lolo/ui/core/atoms/std-tag-taxonomy.lolo +1 -1
  17. package/behaviors/lolo/ui/core/atoms/std-thread.lolo +2 -2
  18. package/behaviors/lolo/ui/core/atoms/std-vote.lolo +2 -2
  19. package/behaviors/lolo/ui/core/atoms/std-wizard.lolo +3 -7
  20. package/behaviors/lolo/ui/core/atoms/ui-atlas-image.lolo +1 -1
  21. package/behaviors/lolo/ui/core/atoms/ui-atlas-panel.lolo +1 -1
  22. package/behaviors/lolo/ui/core/atoms/ui-center.lolo +1 -1
  23. package/behaviors/lolo/ui/core/atoms/ui-hstack.lolo +1 -1
  24. package/behaviors/lolo/ui/core/atoms/ui-icon.lolo +1 -1
  25. package/behaviors/lolo/ui/core/atoms/ui-stack.lolo +1 -1
  26. package/behaviors/lolo/ui/core/atoms/ui-typography.lolo +1 -1
  27. package/behaviors/lolo/ui/core/atoms/ui-vstack.lolo +1 -1
  28. package/behaviors/lolo/ui/core/molecules/ui-content-renderer.lolo +1 -1
  29. package/behaviors/lolo/ui/core/molecules/ui-form-layout.lolo +1 -1
  30. package/behaviors/lolo/ui/core/molecules/ui-grid.lolo +1 -1
  31. package/behaviors/lolo/ui/core/organisms/ui-chat-bar.lolo +1 -1
  32. package/behaviors/lolo/ui/core/organisms/ui-dashboard-grid.lolo +1 -1
  33. package/behaviors/lolo/ui/core/organisms/ui-detail-panel.lolo +1 -1
  34. package/behaviors/lolo/ui/core/organisms/ui-entity-cards.lolo +1 -1
  35. package/behaviors/lolo/ui/core/organisms/ui-entity-list.lolo +1 -1
  36. package/behaviors/lolo/ui/core/organisms/ui-entity-table.lolo +1 -1
  37. package/behaviors/lolo/ui/core/organisms/ui-form-section.lolo +9 -3
  38. package/behaviors/lolo/ui/core/organisms/ui-form.lolo +9 -3
  39. package/behaviors/lolo/ui/core/organisms/ui-master-detail.lolo +1 -1
  40. package/behaviors/lolo/ui/core/organisms/ui-media-gallery.lolo +1 -1
  41. package/behaviors/lolo/ui/core/organisms/ui-segment-renderer.lolo +7 -1
  42. package/behaviors/lolo/ui/core/organisms/ui-stat-card.lolo +1 -1
  43. package/behaviors/lolo/ui/core/organisms/ui-subagent-trace-panel.lolo +1 -1
  44. package/behaviors/lolo/ui/game/atoms/ui-action-tile.lolo +1 -1
  45. package/behaviors/lolo/ui/game/atoms/ui-draw-shape-layer.lolo +41 -9
  46. package/behaviors/lolo/ui/game/atoms/ui-draw-shape.lolo +40 -8
  47. package/behaviors/lolo/ui/game/atoms/ui-draw-sprite-layer.lolo +13 -3
  48. package/behaviors/lolo/ui/game/atoms/ui-draw-sprite.lolo +12 -2
  49. package/behaviors/lolo/ui/game/atoms/ui-draw-text-layer.lolo +3 -3
  50. package/behaviors/lolo/ui/game/atoms/ui-draw-text.lolo +2 -2
  51. package/behaviors/lolo/ui/game/organisms/std-tactics-board-3d.lolo +32 -2
  52. package/behaviors/lolo/ui/learning/atoms/std-learn-classify.lolo +1 -1
  53. package/behaviors/lolo/ui/learning/atoms/std-learn-compare.lolo +397 -0
  54. package/behaviors/lolo/ui/learning/atoms/std-learn-coupled-sim.lolo +537 -0
  55. package/behaviors/lolo/ui/learning/atoms/std-learn-estimate.lolo +419 -0
  56. package/behaviors/lolo/ui/learning/atoms/std-learn-goal-seek.lolo +591 -0
  57. package/behaviors/lolo/ui/learning/atoms/std-learn-grid-sim.lolo +425 -0
  58. package/behaviors/lolo/ui/learning/atoms/std-learn-hotspot.lolo +398 -0
  59. package/behaviors/lolo/ui/learning/atoms/std-learn-measure.lolo +325 -0
  60. package/behaviors/lolo/ui/learning/atoms/std-learn-perturb.lolo +494 -0
  61. package/behaviors/lolo/ui/learning/atoms/std-learn-predict.lolo +408 -0
  62. package/behaviors/lolo/ui/learning/atoms/std-learn-scenario.lolo +307 -0
  63. package/behaviors/lolo/ui/learning/atoms/std-learn-sim-3d.lolo +318 -0
  64. package/behaviors/lolo/ui/learning/atoms/std-learn-speed-drill.lolo +336 -0
  65. package/behaviors/lolo/ui/learning/atoms/std-learn-tour-3d.lolo +380 -0
  66. package/behaviors/lolo/ui/learning/atoms/ui-biology-canvas.lolo +43 -4
  67. package/behaviors/lolo/ui/learning/atoms/ui-chemistry-canvas.lolo +41 -4
  68. package/behaviors/lolo/ui/learning/atoms/ui-physics-canvas.lolo +43 -4
  69. package/behaviors/lolo/ui/marketing/organisms/ui-book-viewer.lolo +1 -1
  70. package/behaviors/lolo/ui/marketing/organisms/ui-case-study-organism.lolo +1 -1
  71. package/behaviors/lolo/ui/marketing/organisms/ui-feature-grid-organism.lolo +1 -1
  72. package/behaviors/lolo/ui/marketing/organisms/ui-hero-organism.lolo +1 -1
  73. package/behaviors/lolo/ui/marketing/organisms/ui-pricing-organism.lolo +1 -1
  74. package/behaviors/lolo/ui/marketing/organisms/ui-showcase-organism.lolo +1 -1
  75. package/behaviors/lolo/ui/marketing/organisms/ui-stats-organism.lolo +1 -1
  76. package/behaviors/lolo/ui/marketing/organisms/ui-step-flow-organism.lolo +1 -1
  77. package/behaviors/lolo/ui/marketing/organisms/ui-team-organism.lolo +1 -1
  78. package/behaviors/registry/agent/atoms/std-agent-session.orb +22 -1
  79. package/behaviors/registry/agent/atoms/std-agent-tool-call.orb +38 -2
  80. package/behaviors/registry/agent/atoms/std-agent-tool-loop.orb +38 -2
  81. package/behaviors/registry/agent/organisms/std-agent-rabit.orb +23 -1
  82. package/behaviors/registry/infra/atoms/std-approval-gate.orb +8 -16
  83. package/behaviors/registry/infra/atoms/std-cache-aside.orb +31 -62
  84. package/behaviors/registry/infra/atoms/std-circuit-breaker.orb +16 -32
  85. package/behaviors/registry/infra/atoms/std-cross-reference.orb +32 -4
  86. package/behaviors/registry/infra/atoms/std-data-erasure.orb +8 -16
  87. package/behaviors/registry/infra/atoms/std-mod-queue.orb +8 -16
  88. package/behaviors/registry/infra/atoms/std-rate-limiter.orb +14 -28
  89. package/behaviors/registry/infra/atoms/std-row-access-control.orb +30 -2
  90. package/behaviors/registry/ui/core/atoms/std-billable-hour.orb +1 -2
  91. package/behaviors/registry/ui/core/atoms/std-board.orb +19 -5
  92. package/behaviors/registry/ui/core/atoms/std-browse.orb +29 -7
  93. package/behaviors/registry/ui/core/atoms/std-dashboard-grid-embedded.orb +1 -2
  94. package/behaviors/registry/ui/core/atoms/std-esign-flow.orb +3 -5
  95. package/behaviors/registry/ui/core/atoms/std-esign-request.orb +3 -6
  96. package/behaviors/registry/ui/core/atoms/std-event-log.orb +17 -3
  97. package/behaviors/registry/ui/core/atoms/std-export.orb +2 -4
  98. package/behaviors/registry/ui/core/atoms/std-form-advanced.orb +1 -1
  99. package/behaviors/registry/ui/core/atoms/std-gallery.orb +9 -18
  100. package/behaviors/registry/ui/core/atoms/std-graphs.orb +15 -1
  101. package/behaviors/registry/ui/core/atoms/std-import.orb +2 -4
  102. package/behaviors/registry/ui/core/atoms/std-list.orb +4 -6
  103. package/behaviors/registry/ui/core/atoms/std-modal.orb +2 -2
  104. package/behaviors/registry/ui/core/atoms/std-multi-party-flow.orb +16 -2
  105. package/behaviors/registry/ui/core/atoms/std-pagination.orb +15 -1
  106. package/behaviors/registry/ui/core/atoms/std-rating-review.orb +19 -5
  107. package/behaviors/registry/ui/core/atoms/std-recurrence.orb +17 -3
  108. package/behaviors/registry/ui/core/atoms/std-rich-editor.orb +15 -1
  109. package/behaviors/registry/ui/core/atoms/std-scatter.orb +15 -1
  110. package/behaviors/registry/ui/core/atoms/std-signature-capture.orb +2 -2
  111. package/behaviors/registry/ui/core/atoms/std-stats.orb +15 -1
  112. package/behaviors/registry/ui/core/atoms/std-step-flow.orb +16 -2
  113. package/behaviors/registry/ui/core/atoms/std-thread.orb +2 -2
  114. package/behaviors/registry/ui/core/atoms/std-vote.orb +2 -2
  115. package/behaviors/registry/ui/core/atoms/std-wizard.orb +17 -3
  116. package/behaviors/registry/ui/core/atoms/ui-atlas-image.orb +4 -1
  117. package/behaviors/registry/ui/core/atoms/ui-atlas-panel.orb +4 -1
  118. package/behaviors/registry/ui/core/atoms/ui-center.orb +4 -1
  119. package/behaviors/registry/ui/core/atoms/ui-hstack.orb +4 -1
  120. package/behaviors/registry/ui/core/atoms/ui-icon.orb +4 -1
  121. package/behaviors/registry/ui/core/atoms/ui-stack.orb +4 -1
  122. package/behaviors/registry/ui/core/atoms/ui-typography.orb +4 -1
  123. package/behaviors/registry/ui/core/atoms/ui-vstack.orb +4 -1
  124. package/behaviors/registry/ui/core/molecules/ui-accordion.orb +3 -3
  125. package/behaviors/registry/ui/core/molecules/ui-content-renderer.orb +4 -1
  126. package/behaviors/registry/ui/core/molecules/ui-form-layout.orb +4 -1
  127. package/behaviors/registry/ui/core/molecules/ui-grid.orb +4 -1
  128. package/behaviors/registry/ui/core/molecules/ui-tabs.orb +2 -2
  129. package/behaviors/registry/ui/core/molecules/ui-wizard-container.orb +1 -1
  130. package/behaviors/registry/ui/core/organisms/ui-chat-bar.orb +4 -1
  131. package/behaviors/registry/ui/core/organisms/ui-dashboard-grid.orb +5 -2
  132. package/behaviors/registry/ui/core/organisms/ui-detail-panel.orb +5 -2
  133. package/behaviors/registry/ui/core/organisms/ui-entity-cards.orb +4 -1
  134. package/behaviors/registry/ui/core/organisms/ui-entity-list.orb +4 -1
  135. package/behaviors/registry/ui/core/organisms/ui-entity-table.orb +4 -1
  136. package/behaviors/registry/ui/core/organisms/ui-form-section.orb +34 -2
  137. package/behaviors/registry/ui/core/organisms/ui-form.orb +34 -2
  138. package/behaviors/registry/ui/core/organisms/ui-master-detail.orb +4 -1
  139. package/behaviors/registry/ui/core/organisms/ui-media-gallery.orb +4 -1
  140. package/behaviors/registry/ui/core/organisms/ui-segment-renderer.orb +24 -2
  141. package/behaviors/registry/ui/core/organisms/ui-stat-card.orb +4 -1
  142. package/behaviors/registry/ui/core/organisms/ui-subagent-trace-panel.orb +4 -1
  143. package/behaviors/registry/ui/core/organisms/ui-tabbed-container.orb +1 -1
  144. package/behaviors/registry/ui/core/organisms/ui-ui-slot-renderer.orb +1 -1
  145. package/behaviors/registry/ui/game/atoms/std-fx-particles.orb +35 -1
  146. package/behaviors/registry/ui/game/atoms/ui-action-tile.orb +4 -1
  147. package/behaviors/registry/ui/game/atoms/ui-draw-shape-layer.orb +183 -13
  148. package/behaviors/registry/ui/game/atoms/ui-draw-shape.orb +104 -9
  149. package/behaviors/registry/ui/game/atoms/ui-draw-sprite-layer.orb +56 -2
  150. package/behaviors/registry/ui/game/atoms/ui-draw-sprite.orb +36 -4
  151. package/behaviors/registry/ui/game/atoms/ui-draw-text-layer.orb +21 -2
  152. package/behaviors/registry/ui/game/atoms/ui-draw-text.orb +19 -4
  153. package/behaviors/registry/ui/game/organisms/std-tactics-board-3d.orb +173 -2
  154. package/behaviors/registry/ui/learning/atoms/std-learn-classify.orb +1 -1
  155. package/behaviors/registry/ui/learning/atoms/std-learn-compare.orb +2814 -0
  156. package/behaviors/registry/ui/learning/atoms/std-learn-coupled-sim.orb +3183 -0
  157. package/behaviors/registry/ui/learning/atoms/std-learn-estimate.orb +2394 -0
  158. package/behaviors/registry/ui/learning/atoms/std-learn-goal-seek.orb +3951 -0
  159. package/behaviors/registry/ui/learning/atoms/std-learn-grid-sim.orb +3458 -0
  160. package/behaviors/registry/ui/learning/atoms/std-learn-hotspot.orb +2646 -0
  161. package/behaviors/registry/ui/learning/atoms/std-learn-measure.orb +1979 -0
  162. package/behaviors/registry/ui/learning/atoms/std-learn-perturb.orb +2994 -0
  163. package/behaviors/registry/ui/learning/atoms/std-learn-predict.orb +2682 -0
  164. package/behaviors/registry/ui/learning/atoms/std-learn-scenario.orb +1842 -0
  165. package/behaviors/registry/ui/learning/atoms/std-learn-sim-3d.orb +1648 -0
  166. package/behaviors/registry/ui/learning/atoms/std-learn-speed-drill.orb +2307 -0
  167. package/behaviors/registry/ui/learning/atoms/std-learn-tour-3d.orb +2947 -0
  168. package/behaviors/registry/ui/learning/atoms/ui-algorithm-canvas.orb +173 -4
  169. package/behaviors/registry/ui/learning/atoms/ui-biology-canvas.orb +267 -7
  170. package/behaviors/registry/ui/learning/atoms/ui-chemistry-canvas.orb +263 -8
  171. package/behaviors/registry/ui/learning/atoms/ui-learning-canvas.orb +116 -1
  172. package/behaviors/registry/ui/learning/atoms/ui-math-canvas.orb +200 -4
  173. package/behaviors/registry/ui/learning/atoms/ui-physics-canvas.orb +264 -7
  174. package/behaviors/registry/ui/marketing/atoms/std-marketing-article.orb +1 -2
  175. package/behaviors/registry/ui/marketing/atoms/std-marketing-footer.orb +1 -2
  176. package/behaviors/registry/ui/marketing/atoms/std-marketing-split.orb +1 -2
  177. package/behaviors/registry/ui/marketing/atoms/std-marketing-stats.orb +1 -2
  178. package/behaviors/registry/ui/marketing/atoms/std-marketing-steps.orb +1 -2
  179. package/behaviors/registry/ui/marketing/atoms/std-marketing-team.orb +1 -2
  180. package/behaviors/registry/ui/marketing/organisms/ui-book-viewer.orb +4 -1
  181. package/behaviors/registry/ui/marketing/organisms/ui-case-study-organism.orb +4 -1
  182. package/behaviors/registry/ui/marketing/organisms/ui-feature-grid-organism.orb +4 -1
  183. package/behaviors/registry/ui/marketing/organisms/ui-hero-organism.orb +4 -1
  184. package/behaviors/registry/ui/marketing/organisms/ui-pricing-organism.orb +4 -1
  185. package/behaviors/registry/ui/marketing/organisms/ui-showcase-organism.orb +4 -1
  186. package/behaviors/registry/ui/marketing/organisms/ui-stats-organism.orb +4 -1
  187. package/behaviors/registry/ui/marketing/organisms/ui-step-flow-organism.orb +4 -1
  188. package/behaviors/registry/ui/marketing/organisms/ui-team-organism.orb +4 -1
  189. package/dist/behaviors/exports-reader.js +3440 -2189
  190. package/dist/behaviors/functions/index.d.ts +1751 -154
  191. package/dist/behaviors/functions/index.js +3402 -2190
  192. package/dist/behaviors/index.d.ts +1 -1
  193. package/dist/behaviors/index.js +3441 -2190
  194. package/dist/behaviors/query.js +3440 -2189
  195. package/dist/behaviors-embeddings.hash.json +3 -3
  196. package/dist/behaviors-embeddings.json +230 -178
  197. package/dist/behaviors-registry.json +4397 -171
  198. package/dist/index.d.ts +1 -1
  199. package/dist/index.js +3441 -2190
  200. package/dist/knob-embeddings.hash.json +3 -3
  201. package/dist/knob-embeddings.json +1 -1
  202. package/dist/registry/factory-signatures.json +1 -1
  203. package/package.json +2 -2
@@ -0,0 +1,408 @@
1
+ app std-learn-predict "1.0.0"
2
+ "Generic predict-then-reveal instrument — each config-declared scenario states a setup and a question, the learner commits to one of the predicted outcomes, and only then does the outcome play out: a timed reveal draws the scenario's declared value frames one by one as a growing curve with per-frame captions, ending in a verdict against the committed prediction and the scenario's explanation, with a running score across scenarios. All vocabulary is config-declared, so the same mechanism serves any commit-before-you-see teaching beat: what happens to the population, which way does the price move, does the reaction speed up, where does the phase go next. Standalone by default; behind a lab router set matchMode and it renders only when MODE_SELECTED matches."
3
+ orbital PredictOrbital {
4
+ type PredictFrame = {
5
+ caption : string!
6
+ value : number!
7
+ }
8
+ type PredictScenario = {
9
+ setup : string!
10
+ question : string!
11
+ options : [string]!
12
+ correctIndex : number!
13
+ explanation : string
14
+ frames : [PredictFrame]!
15
+ }
16
+ type PredictSample = {
17
+ x : number!
18
+ y : number!
19
+ }
20
+ type PredictCurve = {
21
+ label : string
22
+ color : string
23
+ samples : [PredictSample]!
24
+ }
25
+
26
+ entity PredictScene [runtime] {
27
+ id : string!
28
+ active : boolean = false
29
+ title : string
30
+ scenarioIndex : number = 0
31
+ totalScenarios : number = 0
32
+ phase : string
33
+ chosenIndex : number = 0
34
+ frames : [PredictFrame]
35
+ frameIndex : number = 0
36
+ frameCaption : string
37
+ frameValue : number = 0
38
+ revealSamples : [PredictSample]
39
+ revealCurves : [PredictCurve]
40
+ score : number = 0
41
+ done : boolean = false
42
+ setupText : string
43
+ question : string
44
+ options : [string]
45
+ correctIndex : number = 0
46
+ explanation : string
47
+ feedback : string
48
+ view : [node]
49
+ }
50
+
51
+ trait PredictSim -> @rebindable PredictScene [interaction, instance] {
52
+ initial: idle
53
+
54
+ state idle {
55
+ INIT -> idle when (== @config.matchMode "")
56
+ (let (
57
+ (first (array/nth @config.scenarios 0))
58
+ )
59
+ (do
60
+ (set @entity.active true)
61
+ (set @entity.title @config.title)
62
+ (set @entity.scenarioIndex 0)
63
+ (set @entity.totalScenarios (array/len @config.scenarios))
64
+ (set @entity.phase "commit")
65
+ (set @entity.chosenIndex 0)
66
+ (set @entity.frames (object/get @first frames))
67
+ (set @entity.frameIndex 0)
68
+ (set @entity.frameCaption "")
69
+ (set @entity.frameValue 0)
70
+ (set @entity.revealSamples [])
71
+ (set @entity.revealCurves [])
72
+ (set @entity.score 0)
73
+ (set @entity.done false)
74
+ (set @entity.setupText (object/get @first setup))
75
+ (set @entity.question (object/get @first question))
76
+ (set @entity.options (object/get @first options))
77
+ (set @entity.correctIndex (object/get @first correctIndex))
78
+ (set @entity.explanation (object/get @first explanation ""))
79
+ (set @entity.feedback "")
80
+ (set @entity.view [
81
+ { type: card, variant: bordered, padding: md, children: [
82
+ { type: typography, variant: body, content: @entity.setupText },
83
+ { type: typography, variant: h4, content: @entity.question }
84
+ ] }
85
+ ])))
86
+ (render-ui main {
87
+ type: box
88
+ padding: md
89
+ children: [
90
+ { type: stack, direction: vertical, gap: md, children: [
91
+ { type: typography, variant: h4, content: @entity.title },
92
+ { type: progress-bar, value: (+ @entity.scenarioIndex 1), max: @entity.totalScenarios, showPercentage: false, label: (str/concat "Scenario " (str/concat "" (+ @entity.scenarioIndex 1)) " of " (str/concat "" @entity.totalScenarios)) },
93
+ { type: stack, direction: vertical, gap: md, children: @entity.view },
94
+ { type: stack, direction: horizontal, gap: xs, children: (array/map (array/range 0 (array/len @entity.options)) (fn (i)
95
+ { type: button, action: PREDICT, actionPayload: { index: @i }, label: (array/nth @entity.options @i), variant: (if (and (!= @entity.phase "commit") (== @entity.chosenIndex @i)) "primary" "secondary"), size: sm, disabled: (if (== @entity.phase "commit") false true) })) },
96
+ { type: math-canvas, width: @config.width, height: @config.height, title: "", xMin: 0, xMax: (math/max 1 (- (array/len @entity.frames) 1)), yMin: @config.valueMin, yMax: @config.valueMax, showAxes: true, showGrid: true, gridStep: @config.gridStep, curves: @entity.revealCurves, points: [], vectors: [], shapes: [], interactive: false, animate: false },
97
+ { type: typography, variant: body, content: @entity.frameCaption },
98
+ { type: typography, variant: caption, content: @entity.feedback },
99
+ { type: stack, direction: horizontal, gap: sm, children: [
100
+ { type: button, action: NEXT, label: @config.nextLabel, variant: primary, disabled: (if (and (== @entity.phase "judged") (== @entity.done false)) false true) },
101
+ { type: button, action: RETRY, label: @config.retryLabel, variant: ghost, disabled: (if @entity.done false true) }
102
+ ] },
103
+ { type: stat-display, label: "Correct predictions", value: @entity.score, max: @entity.totalScenarios }
104
+ ] }
105
+ ]
106
+ })
107
+
108
+ MODE_SELECTED -> idle when (== ?mode @config.matchMode)
109
+ (let (
110
+ (first (array/nth @config.scenarios 0))
111
+ )
112
+ (do
113
+ (set @entity.active true)
114
+ (set @entity.title @config.title)
115
+ (set @entity.scenarioIndex 0)
116
+ (set @entity.totalScenarios (array/len @config.scenarios))
117
+ (set @entity.phase "commit")
118
+ (set @entity.chosenIndex 0)
119
+ (set @entity.frames (object/get @first frames))
120
+ (set @entity.frameIndex 0)
121
+ (set @entity.frameCaption "")
122
+ (set @entity.frameValue 0)
123
+ (set @entity.revealSamples [])
124
+ (set @entity.revealCurves [])
125
+ (set @entity.score 0)
126
+ (set @entity.done false)
127
+ (set @entity.setupText (object/get @first setup))
128
+ (set @entity.question (object/get @first question))
129
+ (set @entity.options (object/get @first options))
130
+ (set @entity.correctIndex (object/get @first correctIndex))
131
+ (set @entity.explanation (object/get @first explanation ""))
132
+ (set @entity.feedback "")
133
+ (set @entity.view [
134
+ { type: card, variant: bordered, padding: md, children: [
135
+ { type: typography, variant: body, content: @entity.setupText },
136
+ { type: typography, variant: h4, content: @entity.question }
137
+ ] }
138
+ ])))
139
+ (render-ui main {
140
+ type: box
141
+ padding: md
142
+ children: [
143
+ { type: stack, direction: vertical, gap: md, children: [
144
+ { type: typography, variant: h4, content: @entity.title },
145
+ { type: progress-bar, value: (+ @entity.scenarioIndex 1), max: @entity.totalScenarios, showPercentage: false, label: (str/concat "Scenario " (str/concat "" (+ @entity.scenarioIndex 1)) " of " (str/concat "" @entity.totalScenarios)) },
146
+ { type: stack, direction: vertical, gap: md, children: @entity.view },
147
+ { type: stack, direction: horizontal, gap: xs, children: (array/map (array/range 0 (array/len @entity.options)) (fn (i)
148
+ { type: button, action: PREDICT, actionPayload: { index: @i }, label: (array/nth @entity.options @i), variant: (if (and (!= @entity.phase "commit") (== @entity.chosenIndex @i)) "primary" "secondary"), size: sm, disabled: (if (== @entity.phase "commit") false true) })) },
149
+ { type: math-canvas, width: @config.width, height: @config.height, title: "", xMin: 0, xMax: (math/max 1 (- (array/len @entity.frames) 1)), yMin: @config.valueMin, yMax: @config.valueMax, showAxes: true, showGrid: true, gridStep: @config.gridStep, curves: @entity.revealCurves, points: [], vectors: [], shapes: [], interactive: false, animate: false },
150
+ { type: typography, variant: body, content: @entity.frameCaption },
151
+ { type: typography, variant: caption, content: @entity.feedback },
152
+ { type: stack, direction: horizontal, gap: sm, children: [
153
+ { type: button, action: NEXT, label: @config.nextLabel, variant: primary, disabled: (if (and (== @entity.phase "judged") (== @entity.done false)) false true) },
154
+ { type: button, action: RETRY, label: @config.retryLabel, variant: ghost, disabled: (if @entity.done false true) }
155
+ ] },
156
+ { type: stat-display, label: "Correct predictions", value: @entity.score, max: @entity.totalScenarios }
157
+ ] }
158
+ ]
159
+ })
160
+
161
+ PREDICT -> idle when (and (== @entity.active true) (and (== @entity.phase "commit") (== @entity.done false)))
162
+ (let (
163
+ (frame0 (array/nth @entity.frames 0))
164
+ )
165
+ (do
166
+ (set @entity.chosenIndex ?index)
167
+ (set @entity.phase "reveal")
168
+ (set @entity.frameIndex 0)
169
+ (set @entity.frameCaption (object/get @frame0 caption))
170
+ (set @entity.frameValue (object/get @frame0 value))
171
+ (set @entity.revealSamples [ { x: 0, y: (object/get @frame0 value) } ])
172
+ (set @entity.revealCurves [ { label: @config.revealLabel, color: @config.revealColor, samples: @entity.revealSamples } ])
173
+ (set @entity.feedback (str/concat "Prediction locked: " (array/nth @entity.options ?index) " — watch what happens."))))
174
+ (emit PREDICTION_COMMITTED { scenarioIndex: @entity.scenarioIndex, chosenIndex: @entity.chosenIndex })
175
+
176
+ NEXT -> idle when (and (== @entity.active true) (and (== @entity.phase "judged") (== @entity.done false)))
177
+ (let (
178
+ (nextIndex (+ @entity.scenarioIndex 1))
179
+ (finished (>= @nextIndex (array/len @config.scenarios)))
180
+ (next (array/nth @config.scenarios (math/min @nextIndex (- (array/len @config.scenarios) 1))))
181
+ )
182
+ (do
183
+ (set @entity.scenarioIndex (if @finished @entity.scenarioIndex @nextIndex))
184
+ (set @entity.done (if @finished true false))
185
+ (set @entity.phase (if @finished "judged" "commit"))
186
+ (set @entity.chosenIndex 0)
187
+ (set @entity.frames (if @finished @entity.frames (object/get @next frames)))
188
+ (set @entity.frameIndex 0)
189
+ (set @entity.frameCaption "")
190
+ (set @entity.frameValue 0)
191
+ (set @entity.revealSamples [])
192
+ (set @entity.revealCurves [])
193
+ (set @entity.setupText (if @finished @entity.setupText (object/get @next setup)))
194
+ (set @entity.question (if @finished @entity.question (object/get @next question)))
195
+ (set @entity.options (if @finished [] (object/get @next options)))
196
+ (set @entity.correctIndex (if @finished @entity.correctIndex (object/get @next correctIndex)))
197
+ (set @entity.explanation (if @finished @entity.explanation (object/get @next explanation "")))
198
+ (set @entity.feedback (if @finished (str/concat "Round complete — " (str/concat "" @entity.score) " of " (str/concat "" @entity.totalScenarios) " predictions correct.") ""))
199
+ (set @entity.view (if @finished
200
+ [
201
+ { type: typography, variant: h4, content: "Round Complete" },
202
+ { type: stat-display, label: "Correct predictions", value: @entity.score, max: @entity.totalScenarios }
203
+ ]
204
+ [
205
+ { type: card, variant: bordered, padding: md, children: [
206
+ { type: typography, variant: body, content: @entity.setupText },
207
+ { type: typography, variant: h4, content: @entity.question }
208
+ ] }
209
+ ])))
210
+ )
211
+ (render-ui main {
212
+ type: box
213
+ padding: md
214
+ children: [
215
+ { type: stack, direction: vertical, gap: md, children: [
216
+ { type: typography, variant: h4, content: @entity.title },
217
+ { type: progress-bar, value: (+ @entity.scenarioIndex 1), max: @entity.totalScenarios, showPercentage: false, label: (str/concat "Scenario " (str/concat "" (+ @entity.scenarioIndex 1)) " of " (str/concat "" @entity.totalScenarios)) },
218
+ { type: stack, direction: vertical, gap: md, children: @entity.view },
219
+ { type: stack, direction: horizontal, gap: xs, children: (array/map (array/range 0 (array/len @entity.options)) (fn (i)
220
+ { type: button, action: PREDICT, actionPayload: { index: @i }, label: (array/nth @entity.options @i), variant: (if (and (!= @entity.phase "commit") (== @entity.chosenIndex @i)) "primary" "secondary"), size: sm, disabled: (if (== @entity.phase "commit") false true) })) },
221
+ { type: math-canvas, width: @config.width, height: @config.height, title: "", xMin: 0, xMax: (math/max 1 (- (array/len @entity.frames) 1)), yMin: @config.valueMin, yMax: @config.valueMax, showAxes: true, showGrid: true, gridStep: @config.gridStep, curves: @entity.revealCurves, points: [], vectors: [], shapes: [], interactive: false, animate: false },
222
+ { type: typography, variant: body, content: @entity.frameCaption },
223
+ { type: typography, variant: caption, content: @entity.feedback },
224
+ { type: stack, direction: horizontal, gap: sm, children: [
225
+ { type: button, action: NEXT, label: @config.nextLabel, variant: primary, disabled: (if (and (== @entity.phase "judged") (== @entity.done false)) false true) },
226
+ { type: button, action: RETRY, label: @config.retryLabel, variant: ghost, disabled: (if @entity.done false true) }
227
+ ] },
228
+ { type: stat-display, label: "Correct predictions", value: @entity.score, max: @entity.totalScenarios }
229
+ ] }
230
+ ]
231
+ })
232
+ (emit SCENARIO_ADVANCED { scenarioIndex: @entity.scenarioIndex, done: @entity.done, score: @entity.score })
233
+
234
+ RETRY -> idle when (and (== @entity.active true) (== @entity.done true))
235
+ (let (
236
+ (first (array/nth @config.scenarios 0))
237
+ )
238
+ (do
239
+ (set @entity.scenarioIndex 0)
240
+ (set @entity.phase "commit")
241
+ (set @entity.chosenIndex 0)
242
+ (set @entity.frames (object/get @first frames))
243
+ (set @entity.frameIndex 0)
244
+ (set @entity.frameCaption "")
245
+ (set @entity.frameValue 0)
246
+ (set @entity.revealSamples [])
247
+ (set @entity.revealCurves [])
248
+ (set @entity.score 0)
249
+ (set @entity.done false)
250
+ (set @entity.setupText (object/get @first setup))
251
+ (set @entity.question (object/get @first question))
252
+ (set @entity.options (object/get @first options))
253
+ (set @entity.correctIndex (object/get @first correctIndex))
254
+ (set @entity.explanation (object/get @first explanation ""))
255
+ (set @entity.feedback "")
256
+ (set @entity.view [
257
+ { type: card, variant: bordered, padding: md, children: [
258
+ { type: typography, variant: body, content: @entity.setupText },
259
+ { type: typography, variant: h4, content: @entity.question }
260
+ ] }
261
+ ])))
262
+ (render-ui main {
263
+ type: box
264
+ padding: md
265
+ children: [
266
+ { type: stack, direction: vertical, gap: md, children: [
267
+ { type: typography, variant: h4, content: @entity.title },
268
+ { type: progress-bar, value: (+ @entity.scenarioIndex 1), max: @entity.totalScenarios, showPercentage: false, label: (str/concat "Scenario " (str/concat "" (+ @entity.scenarioIndex 1)) " of " (str/concat "" @entity.totalScenarios)) },
269
+ { type: stack, direction: vertical, gap: md, children: @entity.view },
270
+ { type: stack, direction: horizontal, gap: xs, children: (array/map (array/range 0 (array/len @entity.options)) (fn (i)
271
+ { type: button, action: PREDICT, actionPayload: { index: @i }, label: (array/nth @entity.options @i), variant: (if (and (!= @entity.phase "commit") (== @entity.chosenIndex @i)) "primary" "secondary"), size: sm, disabled: (if (== @entity.phase "commit") false true) })) },
272
+ { type: math-canvas, width: @config.width, height: @config.height, title: "", xMin: 0, xMax: (math/max 1 (- (array/len @entity.frames) 1)), yMin: @config.valueMin, yMax: @config.valueMax, showAxes: true, showGrid: true, gridStep: @config.gridStep, curves: @entity.revealCurves, points: [], vectors: [], shapes: [], interactive: false, animate: false },
273
+ { type: typography, variant: body, content: @entity.frameCaption },
274
+ { type: typography, variant: caption, content: @entity.feedback },
275
+ { type: stack, direction: horizontal, gap: sm, children: [
276
+ { type: button, action: NEXT, label: @config.nextLabel, variant: primary, disabled: (if (and (== @entity.phase "judged") (== @entity.done false)) false true) },
277
+ { type: button, action: RETRY, label: @config.retryLabel, variant: ghost, disabled: (if @entity.done false true) }
278
+ ] },
279
+ { type: stat-display, label: "Correct predictions", value: @entity.score, max: @entity.totalScenarios }
280
+ ] }
281
+ ]
282
+ })
283
+ (emit ROUND_RESTARTED { totalScenarios: @entity.totalScenarios })
284
+ }
285
+
286
+ ticks {
287
+ revealTick every 600ms
288
+ when (and (== @entity.active true) (== @entity.phase "reveal"))
289
+ (set @entity.frameIndex (math/min (+ @entity.frameIndex 1) (- (array/len @entity.frames) 1)))
290
+ (set @entity.frameCaption (object/get (array/nth @entity.frames @entity.frameIndex) caption))
291
+ (set @entity.frameValue (object/get (array/nth @entity.frames @entity.frameIndex) value))
292
+ (set @entity.revealSamples (array/append @entity.revealSamples { x: @entity.frameIndex, y: @entity.frameValue }))
293
+ (set @entity.revealCurves [ { label: @config.revealLabel, color: @config.revealColor, samples: @entity.revealSamples } ])
294
+ (set @entity.phase (if (>= @entity.frameIndex (- (array/len @entity.frames) 1)) "judged" @entity.phase))
295
+ (set @entity.score (if (and (== @entity.phase "judged") (== @entity.chosenIndex @entity.correctIndex)) (+ @entity.score 1) @entity.score))
296
+ (set @entity.feedback (if (== @entity.phase "judged")
297
+ (if (== @entity.chosenIndex @entity.correctIndex)
298
+ (str/concat "Your prediction was right. " @entity.explanation)
299
+ (str/concat "Not this time — the outcome was: " (array/nth @entity.options @entity.correctIndex) ". " @entity.explanation))
300
+ @entity.feedback))
301
+ }
302
+
303
+ listens {
304
+ MODE_SELECTED {
305
+ mode : string
306
+ }
307
+ @description "Lab router broadcast naming the active mode; this instrument renders when the mode equals matchMode, otherwise renders null."
308
+ @tier "domain"
309
+ PREDICT {
310
+ index : number
311
+ }
312
+ @description "Learner committed to one of the predicted outcomes before seeing the reveal — index is the chosen option; the reveal then plays out."
313
+ @tier "domain"
314
+ NEXT {
315
+ }
316
+ @description "Learner advanced to the next scenario after the reveal was judged; past the last scenario this completes the round."
317
+ @tier "domain"
318
+ RETRY {
319
+ }
320
+ @description "Learner restarted the round from the first scenario with a cleared score."
321
+ @tier "domain"
322
+ }
323
+
324
+ emits {
325
+ PREDICTION_COMMITTED -> external {
326
+ scenarioIndex : number
327
+ chosenIndex : number
328
+ }
329
+ @description "The learner locked in a prediction and the reveal started — a composed listener (coach, grader) can subscribe; a harmless no-op when the atom runs standalone."
330
+ @synonyms "predict then reveal, commit prediction, hypothesis first, what happens next"
331
+ @tier "domain"
332
+ SCENARIO_ADVANCED -> external {
333
+ scenarioIndex : number
334
+ done : boolean
335
+ score : number
336
+ }
337
+ @description "The learner moved to the next scenario (or completed the round) with the running score."
338
+ @tier "domain"
339
+ ROUND_RESTARTED -> external {
340
+ totalScenarios : number
341
+ }
342
+ @description "The learner restarted the round from scratch."
343
+ @tier "domain"
344
+ }
345
+
346
+ config {
347
+ matchMode : string = ""
348
+ @label "Match Mode"
349
+ @description "When composed behind a lab router, the MODE_SELECTED mode value this instrument responds to. Empty string means standalone — render immediately on INIT."
350
+ @tier "presentation"
351
+ title : string = "Predict, Then Watch"
352
+ @label "Title"
353
+ @description "Title shown above the instrument."
354
+ @tier "presentation"
355
+ scenarios : [PredictScenario] = [
356
+ { setup: "A small island hosts 40 rabbits with unlimited grass and no predators.", question: "What happens to the population over the next six seasons?", options: ["It levels off", "It keeps accelerating", "It collapses"], correctIndex: 1, explanation: "With no limiting factor yet, growth compounds each season.", frames: [
357
+ { caption: "Season 1: 40 rabbits", value: 40 },
358
+ { caption: "Season 2: 52 rabbits", value: 52 },
359
+ { caption: "Season 3: 68 rabbits", value: 68 },
360
+ { caption: "Season 4: 88 rabbits", value: 88 },
361
+ { caption: "Season 5: 114 rabbits", value: 114 },
362
+ { caption: "Season 6: 148 rabbits — still accelerating", value: 148 }
363
+ ] },
364
+ { setup: "The same island now has foxes, and grass is running short.", question: "What happens to the rabbit population now?", options: ["It keeps accelerating", "It levels off near a ceiling", "It grows linearly"], correctIndex: 1, explanation: "Predation and food limits impose a carrying capacity.", frames: [
365
+ { caption: "Season 1: 148 rabbits", value: 148 },
366
+ { caption: "Season 2: 160 rabbits", value: 160 },
367
+ { caption: "Season 3: 166 rabbits", value: 166 },
368
+ { caption: "Season 4: 169 rabbits", value: 169 },
369
+ { caption: "Season 5: 170 rabbits — the curve flattens", value: 170 }
370
+ ] }
371
+ ]
372
+ @label "Scenarios"
373
+ @description "The scenario roster; each carries a setup, the question, the offered predictions with the correct index, an explanation, and the reveal frames (caption + value) that play out after the learner commits. Realizations declare their own subject's scenarios here."
374
+ @tier "domain"
375
+ valueMin : number = 0
376
+ @label "Value Min"
377
+ @description "Lower bound of the reveal chart's y axis."
378
+ @tier "presentation"
379
+ valueMax : number = 200
380
+ @label "Value Max"
381
+ @description "Upper bound of the reveal chart's y axis."
382
+ @tier "presentation"
383
+ gridStep : number = 25
384
+ @label "Grid Step"
385
+ @tier "presentation"
386
+ revealLabel : string = "Outcome"
387
+ @label "Reveal Label"
388
+ @tier "presentation"
389
+ revealColor : string = "#3b82f6"
390
+ @label "Reveal Color"
391
+ @tier "presentation"
392
+ nextLabel : string = "Next"
393
+ @label "Next Label"
394
+ @tier "presentation"
395
+ retryLabel : string = "Try Again"
396
+ @label "Retry Label"
397
+ @tier "presentation"
398
+ width : number = 600
399
+ @label "Width"
400
+ @tier "presentation"
401
+ height : number = 320
402
+ @label "Height"
403
+ @tier "presentation"
404
+ }
405
+ }
406
+
407
+ page "/learn-predict" as PredictPage -> PredictSim
408
+ }