@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,325 @@
1
+ app std-learn-measure "1.0.0"
2
+ "Generic measurement lab — a config-declared signal (sine A·sin(B·t), growth A·(1+B)ᵗ, or half-life decay A·(1/2)^(t/B)) evolves live while Run is engaged, drawing its trace across the chart, and the learner presses Probe to record the instantaneous value as a data point: recorded points accumulate on the chart with a running sample count and mean, teaching the discipline of sampling a changing quantity rather than reading a printed table. Pause freezes time mid-run and Reset clears the experiment. All vocabulary and dynamics are config-declared, so the same mechanism serves any measure-the-system exercise: temperature during a reaction, voltage on a discharging capacitor, population through a season, a pendulum's displacement. Standalone by default; behind a lab router set matchMode and it renders only when MODE_SELECTED matches."
3
+ orbital MeasureOrbital {
4
+ type MeasureSample = {
5
+ x : number!
6
+ y : number!
7
+ }
8
+ type MeasureCurve = {
9
+ label : string
10
+ color : string
11
+ samples : [MeasureSample]!
12
+ }
13
+ type MeasurePoint = {
14
+ x : number!
15
+ y : number!
16
+ color : string
17
+ }
18
+
19
+ entity MeasureScene [runtime] {
20
+ id : string!
21
+ active : boolean = false
22
+ title : string
23
+ t : number = 0
24
+ value : number = 0
25
+ running : boolean = false
26
+ traceSamples : [MeasureSample]
27
+ traceCurves : [MeasureCurve]
28
+ points : [MeasurePoint]
29
+ sampleCount : number = 0
30
+ meanValue : number = 0
31
+ }
32
+
33
+ trait MeasureSim -> @rebindable MeasureScene [interaction, instance] {
34
+ initial: idle
35
+
36
+ state idle {
37
+ INIT -> idle when (== @config.matchMode "")
38
+ (set @entity.active true)
39
+ (set @entity.title @config.title)
40
+ (set @entity.t 0)
41
+ (set @entity.value (if (== @config.signalKind "sine") 0 @config.amplitude))
42
+ (set @entity.running false)
43
+ (set @entity.traceSamples [])
44
+ (set @entity.traceCurves [])
45
+ (set @entity.points [])
46
+ (set @entity.sampleCount 0)
47
+ (set @entity.meanValue 0)
48
+ (render-ui main {
49
+ type: box
50
+ padding: md
51
+ children: [
52
+ { type: stack, direction: vertical, gap: md, children: [
53
+ { type: typography, variant: h4, content: @entity.title },
54
+ { type: typography, variant: body, content: @config.taskText },
55
+ { type: stack, direction: horizontal, gap: sm, children: [
56
+ { type: button, action: RUN, label: "Run", variant: primary, disabled: (if (and (== @entity.running false) (< @entity.t @config.duration)) false true) },
57
+ { type: button, action: PAUSE, label: "Pause", variant: secondary, disabled: (if @entity.running false true) },
58
+ { type: button, action: PROBE, label: @config.probeLabel, variant: primary, disabled: (if (> @entity.t 0) false true) },
59
+ { type: button, action: RESET, label: "Reset", variant: ghost }
60
+ ] },
61
+ { type: math-canvas, width: @config.width, height: @config.height, title: "", xMin: 0, xMax: @config.duration, yMin: @config.valueMin, yMax: @config.valueMax, showAxes: true, showGrid: true, gridStep: @config.gridStep, curves: @entity.traceCurves, points: @entity.points, vectors: [], shapes: [], interactive: false, animate: false },
62
+ { type: typography, variant: body, content: (str/concat "t = " (math/round @entity.t 1) "s · " @config.valueLabel " = " (math/round @entity.value 3)) },
63
+ { type: typography, variant: caption, content: (str/concat "Samples recorded: " (str/concat "" @entity.sampleCount) " · mean " @config.valueLabel ": " (math/round @entity.meanValue 3)) }
64
+ ] }
65
+ ]
66
+ })
67
+
68
+ MODE_SELECTED -> idle when (== ?mode @config.matchMode)
69
+ (set @entity.active true)
70
+ (set @entity.title @config.title)
71
+ (set @entity.t 0)
72
+ (set @entity.value (if (== @config.signalKind "sine") 0 @config.amplitude))
73
+ (set @entity.running false)
74
+ (set @entity.traceSamples [])
75
+ (set @entity.traceCurves [])
76
+ (set @entity.points [])
77
+ (set @entity.sampleCount 0)
78
+ (set @entity.meanValue 0)
79
+ (render-ui main {
80
+ type: box
81
+ padding: md
82
+ children: [
83
+ { type: stack, direction: vertical, gap: md, children: [
84
+ { type: typography, variant: h4, content: @entity.title },
85
+ { type: typography, variant: body, content: @config.taskText },
86
+ { type: stack, direction: horizontal, gap: sm, children: [
87
+ { type: button, action: RUN, label: "Run", variant: primary, disabled: (if (and (== @entity.running false) (< @entity.t @config.duration)) false true) },
88
+ { type: button, action: PAUSE, label: "Pause", variant: secondary, disabled: (if @entity.running false true) },
89
+ { type: button, action: PROBE, label: @config.probeLabel, variant: primary, disabled: (if (> @entity.t 0) false true) },
90
+ { type: button, action: RESET, label: "Reset", variant: ghost }
91
+ ] },
92
+ { type: math-canvas, width: @config.width, height: @config.height, title: "", xMin: 0, xMax: @config.duration, yMin: @config.valueMin, yMax: @config.valueMax, showAxes: true, showGrid: true, gridStep: @config.gridStep, curves: @entity.traceCurves, points: @entity.points, vectors: [], shapes: [], interactive: false, animate: false },
93
+ { type: typography, variant: body, content: (str/concat "t = " (math/round @entity.t 1) "s · " @config.valueLabel " = " (math/round @entity.value 3)) },
94
+ { type: typography, variant: caption, content: (str/concat "Samples recorded: " (str/concat "" @entity.sampleCount) " · mean " @config.valueLabel ": " (math/round @entity.meanValue 3)) }
95
+ ] }
96
+ ]
97
+ })
98
+
99
+ RUN -> idle when (and (== @entity.active true) (and (== @entity.running false) (< @entity.t @config.duration)))
100
+ (set @entity.running true)
101
+ (render-ui main {
102
+ type: box
103
+ padding: md
104
+ children: [
105
+ { type: stack, direction: vertical, gap: md, children: [
106
+ { type: typography, variant: h4, content: @entity.title },
107
+ { type: typography, variant: body, content: @config.taskText },
108
+ { type: stack, direction: horizontal, gap: sm, children: [
109
+ { type: button, action: RUN, label: "Run", variant: primary, disabled: (if (and (== @entity.running false) (< @entity.t @config.duration)) false true) },
110
+ { type: button, action: PAUSE, label: "Pause", variant: secondary, disabled: (if @entity.running false true) },
111
+ { type: button, action: PROBE, label: @config.probeLabel, variant: primary, disabled: (if (> @entity.t 0) false true) },
112
+ { type: button, action: RESET, label: "Reset", variant: ghost }
113
+ ] },
114
+ { type: math-canvas, width: @config.width, height: @config.height, title: "", xMin: 0, xMax: @config.duration, yMin: @config.valueMin, yMax: @config.valueMax, showAxes: true, showGrid: true, gridStep: @config.gridStep, curves: @entity.traceCurves, points: @entity.points, vectors: [], shapes: [], interactive: false, animate: false },
115
+ { type: typography, variant: body, content: (str/concat "t = " (math/round @entity.t 1) "s · " @config.valueLabel " = " (math/round @entity.value 3)) },
116
+ { type: typography, variant: caption, content: (str/concat "Samples recorded: " (str/concat "" @entity.sampleCount) " · mean " @config.valueLabel ": " (math/round @entity.meanValue 3)) }
117
+ ] }
118
+ ]
119
+ })
120
+ (emit RUN_TOGGLED { running: @entity.running })
121
+
122
+ PAUSE -> idle when (and (== @entity.active true) (== @entity.running true))
123
+ (set @entity.running false)
124
+ (render-ui main {
125
+ type: box
126
+ padding: md
127
+ children: [
128
+ { type: stack, direction: vertical, gap: md, children: [
129
+ { type: typography, variant: h4, content: @entity.title },
130
+ { type: typography, variant: body, content: @config.taskText },
131
+ { type: stack, direction: horizontal, gap: sm, children: [
132
+ { type: button, action: RUN, label: "Run", variant: primary, disabled: (if (and (== @entity.running false) (< @entity.t @config.duration)) false true) },
133
+ { type: button, action: PAUSE, label: "Pause", variant: secondary, disabled: (if @entity.running false true) },
134
+ { type: button, action: PROBE, label: @config.probeLabel, variant: primary, disabled: (if (> @entity.t 0) false true) },
135
+ { type: button, action: RESET, label: "Reset", variant: ghost }
136
+ ] },
137
+ { type: math-canvas, width: @config.width, height: @config.height, title: "", xMin: 0, xMax: @config.duration, yMin: @config.valueMin, yMax: @config.valueMax, showAxes: true, showGrid: true, gridStep: @config.gridStep, curves: @entity.traceCurves, points: @entity.points, vectors: [], shapes: [], interactive: false, animate: false },
138
+ { type: typography, variant: body, content: (str/concat "t = " (math/round @entity.t 1) "s · " @config.valueLabel " = " (math/round @entity.value 3)) },
139
+ { type: typography, variant: caption, content: (str/concat "Samples recorded: " (str/concat "" @entity.sampleCount) " · mean " @config.valueLabel ": " (math/round @entity.meanValue 3)) }
140
+ ] }
141
+ ]
142
+ })
143
+ (emit RUN_TOGGLED { running: @entity.running })
144
+
145
+ PROBE -> idle when (and (== @entity.active true) (> @entity.t 0))
146
+ (set @entity.points (array/append @entity.points { x: @entity.t, y: @entity.value, color: @config.probeColor }))
147
+ (set @entity.sampleCount (array/len @entity.points))
148
+ (set @entity.meanValue (array/avg (array/map @entity.points (fn p (object/get @p y)))))
149
+ (render-ui main {
150
+ type: box
151
+ padding: md
152
+ children: [
153
+ { type: stack, direction: vertical, gap: md, children: [
154
+ { type: typography, variant: h4, content: @entity.title },
155
+ { type: typography, variant: body, content: @config.taskText },
156
+ { type: stack, direction: horizontal, gap: sm, children: [
157
+ { type: button, action: RUN, label: "Run", variant: primary, disabled: (if (and (== @entity.running false) (< @entity.t @config.duration)) false true) },
158
+ { type: button, action: PAUSE, label: "Pause", variant: secondary, disabled: (if @entity.running false true) },
159
+ { type: button, action: PROBE, label: @config.probeLabel, variant: primary, disabled: (if (> @entity.t 0) false true) },
160
+ { type: button, action: RESET, label: "Reset", variant: ghost }
161
+ ] },
162
+ { type: math-canvas, width: @config.width, height: @config.height, title: "", xMin: 0, xMax: @config.duration, yMin: @config.valueMin, yMax: @config.valueMax, showAxes: true, showGrid: true, gridStep: @config.gridStep, curves: @entity.traceCurves, points: @entity.points, vectors: [], shapes: [], interactive: false, animate: false },
163
+ { type: typography, variant: body, content: (str/concat "t = " (math/round @entity.t 1) "s · " @config.valueLabel " = " (math/round @entity.value 3)) },
164
+ { type: typography, variant: caption, content: (str/concat "Samples recorded: " (str/concat "" @entity.sampleCount) " · mean " @config.valueLabel ": " (math/round @entity.meanValue 3)) }
165
+ ] }
166
+ ]
167
+ })
168
+ (emit PROBE_RECORDED { t: @entity.t, value: @entity.value, count: @entity.sampleCount, mean: @entity.meanValue })
169
+
170
+ RESET -> idle when (== @entity.active true)
171
+ (set @entity.t 0)
172
+ (set @entity.value (if (== @config.signalKind "sine") 0 @config.amplitude))
173
+ (set @entity.running false)
174
+ (set @entity.traceSamples [])
175
+ (set @entity.traceCurves [])
176
+ (set @entity.points [])
177
+ (set @entity.sampleCount 0)
178
+ (set @entity.meanValue 0)
179
+ (render-ui main {
180
+ type: box
181
+ padding: md
182
+ children: [
183
+ { type: stack, direction: vertical, gap: md, children: [
184
+ { type: typography, variant: h4, content: @entity.title },
185
+ { type: typography, variant: body, content: @config.taskText },
186
+ { type: stack, direction: horizontal, gap: sm, children: [
187
+ { type: button, action: RUN, label: "Run", variant: primary, disabled: (if (and (== @entity.running false) (< @entity.t @config.duration)) false true) },
188
+ { type: button, action: PAUSE, label: "Pause", variant: secondary, disabled: (if @entity.running false true) },
189
+ { type: button, action: PROBE, label: @config.probeLabel, variant: primary, disabled: (if (> @entity.t 0) false true) },
190
+ { type: button, action: RESET, label: "Reset", variant: ghost }
191
+ ] },
192
+ { type: math-canvas, width: @config.width, height: @config.height, title: "", xMin: 0, xMax: @config.duration, yMin: @config.valueMin, yMax: @config.valueMax, showAxes: true, showGrid: true, gridStep: @config.gridStep, curves: @entity.traceCurves, points: @entity.points, vectors: [], shapes: [], interactive: false, animate: false },
193
+ { type: typography, variant: body, content: (str/concat "t = " (math/round @entity.t 1) "s · " @config.valueLabel " = " (math/round @entity.value 3)) },
194
+ { type: typography, variant: caption, content: (str/concat "Samples recorded: " (str/concat "" @entity.sampleCount) " · mean " @config.valueLabel ": " (math/round @entity.meanValue 3)) }
195
+ ] }
196
+ ]
197
+ })
198
+ (emit MEASURE_RESET { duration: @config.duration })
199
+ }
200
+
201
+ ticks {
202
+ measureTick every 100ms
203
+ when (and (== @entity.active true) (== @entity.running true))
204
+ (set @entity.t (math/min @config.duration (+ @entity.t 0.1)))
205
+ (set @entity.value (if (== @config.signalKind "sine")
206
+ (* @config.amplitude (math/sin (* @config.rate @entity.t)))
207
+ (if (== @config.signalKind "growth")
208
+ (* @config.amplitude (math/pow (+ 1 @config.rate) @entity.t))
209
+ (* @config.amplitude (math/pow 0.5 (/ @entity.t @config.rate))))))
210
+ (set @entity.traceSamples (array/append @entity.traceSamples { x: @entity.t, y: @entity.value }))
211
+ (set @entity.traceCurves [ { label: @config.valueLabel, color: @config.signalColor, samples: @entity.traceSamples } ])
212
+ (set @entity.running (if (>= @entity.t @config.duration) false true))
213
+ }
214
+
215
+ listens {
216
+ MODE_SELECTED {
217
+ mode : string
218
+ }
219
+ @description "Lab router broadcast naming the active mode; this instrument renders when the mode equals matchMode, otherwise renders null."
220
+ @tier "domain"
221
+ RUN {
222
+ }
223
+ @description "Learner started (or resumed) the signal's evolution; the trace draws live until Pause or the configured duration."
224
+ @tier "domain"
225
+ PAUSE {
226
+ }
227
+ @description "Learner froze the signal mid-run; Probe still works on the frozen value."
228
+ @tier "domain"
229
+ PROBE {
230
+ }
231
+ @description "Learner recorded the signal's instantaneous value as a data point; the sample count and running mean update."
232
+ @tier "domain"
233
+ RESET {
234
+ }
235
+ @description "Learner cleared the experiment — time, trace, and all recorded samples return to zero."
236
+ @tier "domain"
237
+ }
238
+
239
+ emits {
240
+ RUN_TOGGLED -> external {
241
+ running : boolean
242
+ }
243
+ @description "The experiment was started or paused — a composed listener (readout, grader) can subscribe; a harmless no-op when the atom runs standalone."
244
+ @tier "domain"
245
+ PROBE_RECORDED -> external {
246
+ t : number
247
+ value : number
248
+ count : number
249
+ mean : number
250
+ }
251
+ @description "A measurement was taken: the probed time and value plus the running sample count and mean."
252
+ @synonyms "measurement lab, probe, sample the signal, record data points, running mean"
253
+ @tier "domain"
254
+ MEASURE_RESET -> external {
255
+ duration : number
256
+ }
257
+ @description "The learner reset the experiment to a clean slate."
258
+ @tier "domain"
259
+ }
260
+
261
+ config {
262
+ matchMode : string = ""
263
+ @label "Match Mode"
264
+ @description "When composed behind a lab router, the MODE_SELECTED mode value this instrument responds to. Empty string means standalone — render immediately on INIT."
265
+ @tier "presentation"
266
+ title : string = "Measurement Lab"
267
+ @label "Title"
268
+ @description "Title shown above the experiment."
269
+ @tier "presentation"
270
+ taskText : string = "Run the signal, then press Probe to record measurements. Watch the running mean settle."
271
+ @label "Task Text"
272
+ @description "One-sentence statement of the measuring task."
273
+ @tier "domain"
274
+ signalKind : string = "sine"
275
+ @label "Signal Kind"
276
+ @description "How the measured quantity evolves: sine (A·sin(B·t)), growth (A·(1+B)ᵗ), or decay (half-life A·(1/2)^(t/B))."
277
+ @synonyms "signal family, oscillation, exponential growth, half-life decay"
278
+ @tier "domain"
279
+ amplitude : number = 5
280
+ @label "Amplitude"
281
+ @description "The A parameter: the signal's scale."
282
+ @tier "domain"
283
+ rate : number = 1.2
284
+ @label "Rate"
285
+ @description "The B parameter: angular rate for sine, growth rate for growth, half-life in seconds for decay."
286
+ @tier "domain"
287
+ duration : number = 12
288
+ @label "Duration"
289
+ @description "Seconds the signal runs before stopping automatically."
290
+ @tier "domain"
291
+ valueLabel : string = "value"
292
+ @label "Value Label"
293
+ @description "Display name of the measured quantity."
294
+ @tier "presentation"
295
+ valueMin : number = -6
296
+ @label "Value Min"
297
+ @description "Lower bound of the chart's y axis."
298
+ @tier "presentation"
299
+ valueMax : number = 6
300
+ @label "Value Max"
301
+ @description "Upper bound of the chart's y axis."
302
+ @tier "presentation"
303
+ gridStep : number = 1
304
+ @label "Grid Step"
305
+ @tier "presentation"
306
+ probeLabel : string = "Probe"
307
+ @label "Probe Label"
308
+ @tier "presentation"
309
+ signalColor : string = "#94a3b8"
310
+ @label "Signal Color"
311
+ @tier "presentation"
312
+ probeColor : string = "#dc2626"
313
+ @label "Probe Color"
314
+ @tier "presentation"
315
+ width : number = 600
316
+ @label "Width"
317
+ @tier "presentation"
318
+ height : number = 360
319
+ @label "Height"
320
+ @tier "presentation"
321
+ }
322
+ }
323
+
324
+ page "/learn-measure" as MeasurePage -> MeasureSim
325
+ }