@almadar/std 16.243.0 → 16.244.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.
- package/behaviors/behaviors-registry.json +4470 -513
- package/behaviors/lolo/agent/atoms/std-agent-context.lolo +24 -4
- package/behaviors/lolo/agent/atoms/std-agent-memory.lolo +20 -5
- package/behaviors/lolo/agent/atoms/std-agent-proposal.lolo +550 -0
- package/behaviors/lolo/agent/atoms/std-agent-session.lolo +284 -25
- package/behaviors/lolo/agent/atoms/std-agent-suggestions.lolo +841 -0
- package/behaviors/lolo/agent/atoms/std-agent-tool-loop.lolo +58 -8
- package/behaviors/lolo/agent/organisms/std-agent-assistant.lolo +1 -0
- package/behaviors/lolo/infra/atoms/std-page-treat.lolo +28 -1
- package/behaviors/lolo/ui/avl/atoms/ui-avl-state-machine.lolo +22 -0
- package/behaviors/lolo/ui/avl/atoms/ui-avl-transition-explainer.lolo +175 -0
- package/behaviors/lolo/ui/avl/atoms/ui-module-card.lolo +22 -0
- package/behaviors/lolo/ui/core/atoms/std-app-layout.lolo +23 -4
- package/behaviors/lolo/ui/core/atoms/std-hero.lolo +72 -33
- package/behaviors/lolo/ui/core/molecules/ui-agent-chat-feed.lolo +1 -1
- package/behaviors/lolo/ui/core/molecules/ui-markdown-content.lolo +54 -0
- package/behaviors/lolo/ui/core/molecules/ui-upload-drop-zone.lolo +5 -0
- package/behaviors/lolo/ui/core/organisms/ui-segment-renderer.lolo +127 -3
- package/behaviors/lolo/ui/core/organisms/ui-state-machine-view.lolo +22 -0
- package/behaviors/lolo/ui/core/templates/ui-dashboard-layout.lolo +2 -2
- package/behaviors/lolo/ui/learning/atoms/std-learn-arrangement.lolo +87 -17
- package/behaviors/lolo/ui/learning/atoms/std-learn-classify.lolo +172 -37
- package/behaviors/lolo/ui/learning/atoms/std-learn-coupled-sim.lolo +183 -70
- package/behaviors/lolo/ui/learning/atoms/std-learn-derivation.lolo +78 -13
- package/behaviors/lolo/ui/learning/atoms/std-learn-diagram.lolo +58 -2
- package/behaviors/lolo/ui/learning/atoms/std-learn-doser.lolo +107 -12
- package/behaviors/lolo/ui/learning/atoms/std-learn-estimate.lolo +83 -10
- package/behaviors/lolo/ui/learning/atoms/std-learn-goal-seek.lolo +130 -9
- package/behaviors/lolo/ui/learning/atoms/std-learn-grid-sim.lolo +143 -59
- package/behaviors/lolo/ui/learning/atoms/std-learn-hotspot.lolo +96 -22
- package/behaviors/lolo/ui/learning/atoms/std-learn-live-sim.lolo +66 -5
- package/behaviors/lolo/ui/learning/atoms/std-learn-predict.lolo +84 -6
- package/behaviors/lolo/ui/learning/atoms/std-learn-sandbox.lolo +80 -14
- package/behaviors/lolo/ui/learning/atoms/std-learn-scatter-fit.lolo +99 -5
- package/behaviors/lolo/ui/learning/atoms/std-learn-scenario.lolo +81 -7
- package/behaviors/lolo/ui/learning/atoms/std-learn-speed-drill.lolo +83 -7
- package/behaviors/lolo/ui/learning/atoms/std-learn-stepper.lolo +224 -99
- package/behaviors/lolo/ui/learning/atoms/std-learn-tour-3d.lolo +63 -2
- package/behaviors/lolo/ui/learning/atoms/std-learn-trace-player.lolo +99 -38
- package/behaviors/lolo/ui/learning/atoms/std-learn-transport.lolo +7 -7
- package/behaviors/lolo/ui/learning/atoms/std-learn-tree.lolo +69 -4
- package/behaviors/lolo-behavior-contracts.json +1 -1
- package/behaviors/registry/agent/atoms/std-agent-context.orb +205 -6
- package/behaviors/registry/agent/atoms/std-agent-memory.orb +146 -4
- package/behaviors/registry/agent/atoms/std-agent-proposal.orb +1972 -0
- package/behaviors/registry/agent/atoms/std-agent-session.orb +2021 -597
- package/behaviors/registry/agent/atoms/std-agent-suggestions.orb +5079 -0
- package/behaviors/registry/agent/atoms/std-agent-tool-loop.orb +287 -5
- package/behaviors/registry/agent/organisms/std-agent-assistant.orb +7 -0
- package/behaviors/registry/factory-signatures.json +1 -1
- package/behaviors/registry/infra/atoms/std-page-treat.orb +327 -2
- package/behaviors/registry/ui/avl/atoms/ui-avl-state-machine.orb +134 -0
- package/behaviors/registry/ui/avl/atoms/ui-avl-transition-explainer.orb +678 -0
- package/behaviors/registry/ui/avl/atoms/ui-module-card.orb +122 -0
- package/behaviors/registry/ui/core/atoms/std-app-layout.orb +73 -4
- package/behaviors/registry/ui/core/atoms/std-hero.orb +174 -97
- package/behaviors/registry/ui/core/molecules/ui-markdown-content.orb +204 -1
- package/behaviors/registry/ui/core/molecules/ui-upload-drop-zone.orb +12 -0
- package/behaviors/registry/ui/core/organisms/ui-segment-renderer.orb +683 -30
- package/behaviors/registry/ui/learning/atoms/std-learn-arrangement.orb +748 -21
- package/behaviors/registry/ui/learning/atoms/std-learn-classify.orb +1429 -41
- package/behaviors/registry/ui/learning/atoms/std-learn-coupled-sim.orb +1031 -185
- package/behaviors/registry/ui/learning/atoms/std-learn-derivation.orb +807 -132
- package/behaviors/registry/ui/learning/atoms/std-learn-diagram.orb +553 -6
- package/behaviors/registry/ui/learning/atoms/std-learn-doser.orb +987 -21
- package/behaviors/registry/ui/learning/atoms/std-learn-estimate.orb +582 -16
- package/behaviors/registry/ui/learning/atoms/std-learn-goal-seek.orb +954 -13
- package/behaviors/registry/ui/learning/atoms/std-learn-grid-sim.orb +828 -88
- package/behaviors/registry/ui/learning/atoms/std-learn-hotspot.orb +730 -28
- package/behaviors/registry/ui/learning/atoms/std-learn-live-sim.orb +479 -9
- package/behaviors/registry/ui/learning/atoms/std-learn-predict.orb +797 -46
- package/behaviors/registry/ui/learning/atoms/std-learn-sandbox.orb +757 -58
- package/behaviors/registry/ui/learning/atoms/std-learn-scatter-fit.orb +1176 -164
- package/behaviors/registry/ui/learning/atoms/std-learn-scenario.orb +599 -12
- package/behaviors/registry/ui/learning/atoms/std-learn-speed-drill.orb +832 -150
- package/behaviors/registry/ui/learning/atoms/std-learn-stepper.orb +1561 -127
- package/behaviors/registry/ui/learning/atoms/std-learn-tour-3d.orb +655 -6
- package/behaviors/registry/ui/learning/atoms/std-learn-trace-player.orb +634 -43
- package/behaviors/registry/ui/learning/atoms/std-learn-transport.orb +85 -31
- package/behaviors/registry/ui/learning/atoms/std-learn-tree.orb +425 -9
- package/canonical-operators.json +45 -2
- package/dist/behaviors/exports-reader.js +16667 -7868
- package/dist/behaviors/functions/index.d.ts +711 -32
- package/dist/behaviors/functions/index.js +16651 -7869
- package/dist/behaviors/index.d.ts +1 -1
- package/dist/behaviors/index.js +16668 -7869
- package/dist/behaviors/query.js +16667 -7868
- package/dist/behaviors-embeddings.hash.json +3 -3
- package/dist/behaviors-embeddings.json +77 -53
- package/dist/behaviors-registry.json +4470 -513
- package/dist/index.d.ts +3 -3
- package/dist/index.js +16101 -7275
- package/dist/knob-embeddings.hash.json +3 -3
- package/dist/knob-embeddings.json +1309 -685
- package/dist/modules/anim.d.ts +1 -1
- package/dist/modules/array.d.ts +1 -1
- package/dist/modules/async.d.ts +1 -1
- package/dist/modules/behavior.d.ts +1 -1
- package/dist/modules/browser.d.ts +1 -1
- package/dist/modules/composition.d.ts +1 -1
- package/dist/modules/contract.d.ts +1 -1
- package/dist/modules/core.d.ts +1 -1
- package/dist/modules/core.js +29 -2
- package/dist/modules/data.d.ts +1 -1
- package/dist/modules/ease.d.ts +1 -1
- package/dist/modules/format.d.ts +1 -1
- package/dist/modules/geo.d.ts +1 -1
- package/dist/modules/graph.d.ts +1 -1
- package/dist/modules/grid.d.ts +1 -1
- package/dist/modules/i18n.d.ts +1 -1
- package/dist/modules/index.d.ts +1 -1
- package/dist/modules/index.js +29 -2
- package/dist/modules/integration.d.ts +1 -1
- package/dist/modules/json.d.ts +1 -1
- package/dist/modules/llm.d.ts +1 -1
- package/dist/modules/math.d.ts +1 -1
- package/dist/modules/memory.d.ts +1 -1
- package/dist/modules/nn.d.ts +1 -1
- package/dist/modules/noise.d.ts +1 -1
- package/dist/modules/object.d.ts +1 -1
- package/dist/modules/os.d.ts +1 -1
- package/dist/modules/path.d.ts +1 -1
- package/dist/modules/prob.d.ts +1 -1
- package/dist/modules/session.d.ts +1 -1
- package/dist/modules/str.d.ts +1 -1
- package/dist/modules/tensor.d.ts +1 -1
- package/dist/modules/time.d.ts +1 -1
- package/dist/modules/trace.d.ts +1 -1
- package/dist/modules/train.d.ts +1 -1
- package/dist/modules/validate.d.ts +1 -1
- package/dist/modules/vector.d.ts +1 -1
- package/dist/modules/workspace.d.ts +1 -1
- package/dist/registry/factory-signatures.json +1 -1
- package/dist/registry.d.ts +2 -2
- package/dist/registry.js +29 -2
- package/dist/{types-Cdb321uM.d.ts → types-Y-yYWEOX.d.ts} +1 -1
- package/i18n/ar.json +3 -1
- package/i18n/en.json +2 -0
- package/i18n/sl.json +3 -1
- package/package.json +3 -3
|
@@ -16,6 +16,11 @@ orbital GridSimOrbital {
|
|
|
16
16
|
id : string!
|
|
17
17
|
active : boolean = false
|
|
18
18
|
title : string
|
|
19
|
+
taskText : string
|
|
20
|
+
rule : string
|
|
21
|
+
rows : number
|
|
22
|
+
cols : number
|
|
23
|
+
seeds : [number]
|
|
19
24
|
cells : [number]
|
|
20
25
|
generation : number = 0
|
|
21
26
|
aliveCount : number = 0
|
|
@@ -29,17 +34,22 @@ orbital GridSimOrbital {
|
|
|
29
34
|
initial: idle
|
|
30
35
|
|
|
31
36
|
state idle {
|
|
32
|
-
INIT -> idle when (== @config.matchMode "")
|
|
37
|
+
INIT -> idle when (and (== @config.matchMode "") (== @config.rosterSource "config"))
|
|
33
38
|
(set @entity.active true)
|
|
34
39
|
(set @entity.title @config.title)
|
|
40
|
+
(set @entity.seeds @config.seeds)
|
|
41
|
+
(set @entity.rule @config.rule)
|
|
42
|
+
(set @entity.rows @config.rows)
|
|
43
|
+
(set @entity.cols @config.cols)
|
|
44
|
+
(set @entity.taskText @config.taskText)
|
|
35
45
|
(set @entity.generation 0)
|
|
36
46
|
(set @entity.running @config.autoRun)
|
|
37
|
-
(set @entity.cells (array/map (array/range 0 (* @
|
|
47
|
+
(set @entity.cells (array/map (array/range 0 (* @entity.rows @entity.cols)) (fn (i) (if (array/includes @entity.seeds @i) 1 0))))
|
|
38
48
|
(set @entity.aliveCount (array/len (array/filter @entity.cells (fn v (> @v 0.05)))))
|
|
39
|
-
(set @entity.cellShapes (array/map (array/range 0 (* @
|
|
49
|
+
(set @entity.cellShapes (array/map (array/range 0 (* @entity.rows @entity.cols)) (fn (i)
|
|
40
50
|
(let (
|
|
41
|
-
(r (math/floor (/ @i @
|
|
42
|
-
(c (math/mod @i @
|
|
51
|
+
(r (math/floor (/ @i @entity.cols)))
|
|
52
|
+
(c (math/mod @i @entity.cols))
|
|
43
53
|
(v (array/nth @entity.cells @i))
|
|
44
54
|
(cellColor (if (> @v 0.66) @config.onColor (if (> @v 0.33) @config.midColor (if (> @v 0.05) @config.lowColor @config.offColor))))
|
|
45
55
|
)
|
|
@@ -69,7 +79,7 @@ orbital GridSimOrbital {
|
|
|
69
79
|
{ type: typography, variant: caption, color: muted, content: (str/concat "Generation " @entity.generation " · " @entity.aliveCount " active") }
|
|
70
80
|
] },
|
|
71
81
|
{ type: learning-canvas, keyMap: { Space: TOGGLE_RUN, ArrowRight: STEP, KeyR: RESET }, width: @config.width, height: @config.height, backgroundColor: @config.backgroundColor, shapes: @entity.cellShapes, interactive: true, animate: false, onShapeClick: "TAP_CELL" },
|
|
72
|
-
{ type: typography, variant: body, content: @
|
|
82
|
+
{ type: typography, variant: body, content: @entity.taskText }
|
|
73
83
|
] }
|
|
74
84
|
]
|
|
75
85
|
})
|
|
@@ -79,17 +89,22 @@ orbital GridSimOrbital {
|
|
|
79
89
|
(set @entity.running false)
|
|
80
90
|
(render-ui main null)
|
|
81
91
|
|
|
82
|
-
MODE_SELECTED -> idle when (== ?mode @config.matchMode)
|
|
92
|
+
MODE_SELECTED -> idle when (and (== ?mode @config.matchMode) (== @config.rosterSource "config"))
|
|
83
93
|
(set @entity.active true)
|
|
84
94
|
(set @entity.title @config.title)
|
|
95
|
+
(set @entity.seeds @config.seeds)
|
|
96
|
+
(set @entity.rule @config.rule)
|
|
97
|
+
(set @entity.rows @config.rows)
|
|
98
|
+
(set @entity.cols @config.cols)
|
|
99
|
+
(set @entity.taskText @config.taskText)
|
|
85
100
|
(set @entity.generation 0)
|
|
86
101
|
(set @entity.running @config.autoRun)
|
|
87
|
-
(set @entity.cells (array/map (array/range 0 (* @
|
|
102
|
+
(set @entity.cells (array/map (array/range 0 (* @entity.rows @entity.cols)) (fn (i) (if (array/includes @entity.seeds @i) 1 0))))
|
|
88
103
|
(set @entity.aliveCount (array/len (array/filter @entity.cells (fn v (> @v 0.05)))))
|
|
89
|
-
(set @entity.cellShapes (array/map (array/range 0 (* @
|
|
104
|
+
(set @entity.cellShapes (array/map (array/range 0 (* @entity.rows @entity.cols)) (fn (i)
|
|
90
105
|
(let (
|
|
91
|
-
(r (math/floor (/ @i @
|
|
92
|
-
(c (math/mod @i @
|
|
106
|
+
(r (math/floor (/ @i @entity.cols)))
|
|
107
|
+
(c (math/mod @i @entity.cols))
|
|
93
108
|
(v (array/nth @entity.cells @i))
|
|
94
109
|
(cellColor (if (> @v 0.66) @config.onColor (if (> @v 0.33) @config.midColor (if (> @v 0.05) @config.lowColor @config.offColor))))
|
|
95
110
|
)
|
|
@@ -119,11 +134,66 @@ orbital GridSimOrbital {
|
|
|
119
134
|
{ type: typography, variant: caption, color: muted, content: (str/concat "Generation " @entity.generation " · " @entity.aliveCount " active") }
|
|
120
135
|
] },
|
|
121
136
|
{ type: learning-canvas, keyMap: { Space: TOGGLE_RUN, ArrowRight: STEP, KeyR: RESET }, width: @config.width, height: @config.height, backgroundColor: @config.backgroundColor, shapes: @entity.cellShapes, interactive: true, animate: false, onShapeClick: "TAP_CELL" },
|
|
122
|
-
{ type: typography, variant: body, content: @
|
|
137
|
+
{ type: typography, variant: body, content: @entity.taskText }
|
|
123
138
|
] }
|
|
124
139
|
]
|
|
125
140
|
})
|
|
126
141
|
|
|
142
|
+
ROSTER_LOADED -> idle when (and (== @config.rosterSource "event") (and (== ?mode @config.matchMode) (and (> ?rows 0) (> ?cols 0))))
|
|
143
|
+
(set @entity.active true)
|
|
144
|
+
(set @entity.title @config.title)
|
|
145
|
+
(set @entity.seeds ?seeds)
|
|
146
|
+
(set @entity.rule ?rule)
|
|
147
|
+
(set @entity.rows ?rows)
|
|
148
|
+
(set @entity.cols ?cols)
|
|
149
|
+
(set @entity.taskText ?taskText)
|
|
150
|
+
(set @entity.generation 0)
|
|
151
|
+
(set @entity.running @config.autoRun)
|
|
152
|
+
(set @entity.cells (array/map (array/range 0 (* @entity.rows @entity.cols)) (fn (i) (if (array/includes @entity.seeds @i) 1 0))))
|
|
153
|
+
(set @entity.aliveCount (array/len (array/filter @entity.cells (fn v (> @v 0.05)))))
|
|
154
|
+
(set @entity.cellShapes (array/map (array/range 0 (* @entity.rows @entity.cols)) (fn (i)
|
|
155
|
+
(let (
|
|
156
|
+
(r (math/floor (/ @i @entity.cols)))
|
|
157
|
+
(c (math/mod @i @entity.cols))
|
|
158
|
+
(v (array/nth @entity.cells @i))
|
|
159
|
+
(cellColor (if (> @v 0.66) @config.onColor (if (> @v 0.33) @config.midColor (if (> @v 0.05) @config.lowColor @config.offColor))))
|
|
160
|
+
)
|
|
161
|
+
{ type: rect, id: (str/concat "cell-" @i), x: (+ 10 (* @c @config.cellSize)), y: (+ 10 (* @r @config.cellSize)), width: (- @config.cellSize 2), height: (- @config.cellSize 2), color: @cellColor, fill: @cellColor }))))
|
|
162
|
+
(render-ui main {
|
|
163
|
+
type: box
|
|
164
|
+
padding: md
|
|
165
|
+
children: [
|
|
166
|
+
{ type: stack, direction: vertical, gap: md, children: [
|
|
167
|
+
{ type: stack, direction: horizontal, justify: between, align: start, gap: md, children: [
|
|
168
|
+
{ type: stack, direction: vertical, gap: xs, children: [
|
|
169
|
+
{ type: typography, variant: h4, content: @entity.title },
|
|
170
|
+
(if (== @config.summary "") null { type: typography, variant: body2, color: muted, content: @config.summary })
|
|
171
|
+
] },
|
|
172
|
+
{ type: badge, label: (if @entity.running "Running" "Paused"), variant: (if @entity.running "primary" "neutral") }
|
|
173
|
+
] },
|
|
174
|
+
{ type: stack, direction: horizontal, align: center, gap: sm, wrap: true, children: [
|
|
175
|
+
(if @entity.running { type: button, action: TOGGLE_RUN, label: "Pause", icon: "pause", variant: primary, aria-pressed: "true" } { type: button, action: TOGGLE_RUN, label: "Play", icon: "play", variant: primary, aria-pressed: "false" }),
|
|
176
|
+
{ type: button, action: STEP, label: @config.stepLabel, icon: "step-forward", variant: secondary, disabled: @entity.running },
|
|
177
|
+
{ type: button, action: RESET, label: "Reset", icon: "rotate-ccw", variant: ghost },
|
|
178
|
+
{ type: stack, direction: horizontal, align: center, gap: xs, role: "group", aria-label: "Speed", children: [
|
|
179
|
+
{ type: button, action: SPEED_SET, actionPayload: { speed: 0.5 }, label: "0.5×", size: sm, variant: (if (== @entity.speed 0.5) "secondary" "ghost"), aria-pressed: (if (== @entity.speed 0.5) "true" "false") },
|
|
180
|
+
{ type: button, action: SPEED_SET, actionPayload: { speed: 1 }, label: "1×", size: sm, variant: (if (== @entity.speed 1) "secondary" "ghost"), aria-pressed: (if (== @entity.speed 1) "true" "false") },
|
|
181
|
+
{ type: button, action: SPEED_SET, actionPayload: { speed: 2 }, label: "2×", size: sm, variant: (if (== @entity.speed 2) "secondary" "ghost"), aria-pressed: (if (== @entity.speed 2) "true" "false") },
|
|
182
|
+
{ type: button, action: SPEED_SET, actionPayload: { speed: 4 }, label: "4×", size: sm, variant: (if (== @entity.speed 4) "secondary" "ghost"), aria-pressed: (if (== @entity.speed 4) "true" "false") }
|
|
183
|
+
] },
|
|
184
|
+
{ type: typography, variant: caption, color: muted, content: (str/concat "Generation " @entity.generation " · " @entity.aliveCount " active") }
|
|
185
|
+
] },
|
|
186
|
+
{ type: learning-canvas, keyMap: { Space: TOGGLE_RUN, ArrowRight: STEP, KeyR: RESET }, width: @config.width, height: @config.height, backgroundColor: @config.backgroundColor, shapes: @entity.cellShapes, interactive: true, animate: false, onShapeClick: "TAP_CELL" },
|
|
187
|
+
{ type: typography, variant: body, content: @entity.taskText }
|
|
188
|
+
] }
|
|
189
|
+
]
|
|
190
|
+
})
|
|
191
|
+
|
|
192
|
+
ROSTER_LOADED -> idle when (and (== @config.rosterSource "event") (not (== ?mode @config.matchMode)))
|
|
193
|
+
(set @entity.active false)
|
|
194
|
+
(set @entity.running false)
|
|
195
|
+
(render-ui main null)
|
|
196
|
+
|
|
127
197
|
TOGGLE_RUN -> idle when (== @entity.active true)
|
|
128
198
|
(set @entity.running (not @entity.running))
|
|
129
199
|
(render-ui main {
|
|
@@ -151,7 +221,7 @@ orbital GridSimOrbital {
|
|
|
151
221
|
{ type: typography, variant: caption, color: muted, content: (str/concat "Generation " @entity.generation " · " @entity.aliveCount " active") }
|
|
152
222
|
] },
|
|
153
223
|
{ type: learning-canvas, keyMap: { Space: TOGGLE_RUN, ArrowRight: STEP, KeyR: RESET }, width: @config.width, height: @config.height, backgroundColor: @config.backgroundColor, shapes: @entity.cellShapes, interactive: true, animate: false, onShapeClick: "TAP_CELL" },
|
|
154
|
-
{ type: typography, variant: body, content: @
|
|
224
|
+
{ type: typography, variant: body, content: @entity.taskText }
|
|
155
225
|
] }
|
|
156
226
|
]
|
|
157
227
|
})
|
|
@@ -184,7 +254,7 @@ orbital GridSimOrbital {
|
|
|
184
254
|
{ type: typography, variant: caption, color: muted, content: (str/concat "Generation " @entity.generation " · " @entity.aliveCount " active") }
|
|
185
255
|
] },
|
|
186
256
|
{ type: learning-canvas, keyMap: { Space: TOGGLE_RUN, ArrowRight: STEP, KeyR: RESET }, width: @config.width, height: @config.height, backgroundColor: @config.backgroundColor, shapes: @entity.cellShapes, interactive: true, animate: false, onShapeClick: "TAP_CELL" },
|
|
187
|
-
{ type: typography, variant: body, content: @
|
|
257
|
+
{ type: typography, variant: body, content: @entity.taskText }
|
|
188
258
|
] }
|
|
189
259
|
]
|
|
190
260
|
})
|
|
@@ -216,7 +286,7 @@ orbital GridSimOrbital {
|
|
|
216
286
|
{ type: typography, variant: caption, color: muted, content: (str/concat "Generation " @entity.generation " · " @entity.aliveCount " active") }
|
|
217
287
|
] },
|
|
218
288
|
{ type: learning-canvas, keyMap: { Space: TOGGLE_RUN, ArrowRight: STEP, KeyR: RESET }, width: @config.width, height: @config.height, backgroundColor: @config.backgroundColor, shapes: @entity.cellShapes, interactive: true, animate: false, onShapeClick: "TAP_CELL" },
|
|
219
|
-
{ type: typography, variant: body, content: @
|
|
289
|
+
{ type: typography, variant: body, content: @entity.taskText }
|
|
220
290
|
] }
|
|
221
291
|
]
|
|
222
292
|
})
|
|
@@ -249,42 +319,42 @@ orbital GridSimOrbital {
|
|
|
249
319
|
{ type: typography, variant: caption, color: muted, content: (str/concat "Generation " @entity.generation " · " @entity.aliveCount " active") }
|
|
250
320
|
] },
|
|
251
321
|
{ type: learning-canvas, keyMap: { Space: TOGGLE_RUN, ArrowRight: STEP, KeyR: RESET }, width: @config.width, height: @config.height, backgroundColor: @config.backgroundColor, shapes: @entity.cellShapes, interactive: true, animate: false, onShapeClick: "TAP_CELL" },
|
|
252
|
-
{ type: typography, variant: body, content: @
|
|
322
|
+
{ type: typography, variant: body, content: @entity.taskText }
|
|
253
323
|
] }
|
|
254
324
|
]
|
|
255
325
|
})
|
|
256
326
|
(emit RUN_TOGGLED { running: @entity.running })
|
|
257
327
|
|
|
258
328
|
STEP -> idle when (and (== @entity.active true) (== @entity.running false))
|
|
259
|
-
(set @entity.cells (array/map (array/range 0 (* @
|
|
329
|
+
(set @entity.cells (array/map (array/range 0 (* @entity.rows @entity.cols)) (fn (i)
|
|
260
330
|
(let (
|
|
261
|
-
(r (math/floor (/ @i @
|
|
262
|
-
(c (math/mod @i @
|
|
331
|
+
(r (math/floor (/ @i @entity.cols)))
|
|
332
|
+
(c (math/mod @i @entity.cols))
|
|
263
333
|
(v (array/nth @entity.cells @i))
|
|
264
|
-
(up (if (> @r 0) (array/nth @entity.cells (- @i @
|
|
265
|
-
(down (if (< @r (- @
|
|
334
|
+
(up (if (> @r 0) (array/nth @entity.cells (- @i @entity.cols)) 0))
|
|
335
|
+
(down (if (< @r (- @entity.rows 1)) (array/nth @entity.cells (+ @i @entity.cols)) 0))
|
|
266
336
|
(left (if (> @c 0) (array/nth @entity.cells (- @i 1)) 0))
|
|
267
|
-
(right (if (< @c (- @
|
|
268
|
-
(ul (if (and (> @r 0) (> @c 0)) (array/nth @entity.cells (- (- @i @
|
|
269
|
-
(ur (if (and (> @r 0) (< @c (- @
|
|
270
|
-
(dl (if (and (< @r (- @
|
|
271
|
-
(dr (if (and (< @r (- @
|
|
337
|
+
(right (if (< @c (- @entity.cols 1)) (array/nth @entity.cells (+ @i 1)) 0))
|
|
338
|
+
(ul (if (and (> @r 0) (> @c 0)) (array/nth @entity.cells (- (- @i @entity.cols) 1)) 0))
|
|
339
|
+
(ur (if (and (> @r 0) (< @c (- @entity.cols 1))) (array/nth @entity.cells (+ (- @i @entity.cols) 1)) 0))
|
|
340
|
+
(dl (if (and (< @r (- @entity.rows 1)) (> @c 0)) (array/nth @entity.cells (- (+ @i @entity.cols) 1)) 0))
|
|
341
|
+
(dr (if (and (< @r (- @entity.rows 1)) (< @c (- @entity.cols 1))) (array/nth @entity.cells (+ @i @entity.cols 1)) 0))
|
|
272
342
|
(n4 (+ @up @down @left @right))
|
|
273
343
|
(n8 (+ @n4 @ul @ur @dl @dr))
|
|
274
344
|
)
|
|
275
|
-
(if (== @
|
|
345
|
+
(if (== @entity.rule "life")
|
|
276
346
|
(if (if (> @v 0.5)
|
|
277
347
|
(if (== (math/round @n8 0) 2) true (== (math/round @n8 0) 3))
|
|
278
348
|
(== (math/round @n8 0) 3)) 1 0)
|
|
279
|
-
(if (== @
|
|
349
|
+
(if (== @entity.rule "spread")
|
|
280
350
|
(if (if (> @v 0.5) true (> @n4 0.5)) 1 0)
|
|
281
351
|
(math/max 0 (* @config.decay (+ @v (* @config.diffuseRate (- (/ @n4 4) @v)))))))))))
|
|
282
352
|
(set @entity.generation (+ @entity.generation 1))
|
|
283
353
|
(set @entity.aliveCount (array/len (array/filter @entity.cells (fn v (> @v 0.05)))))
|
|
284
|
-
(set @entity.cellShapes (array/map (array/range 0 (* @
|
|
354
|
+
(set @entity.cellShapes (array/map (array/range 0 (* @entity.rows @entity.cols)) (fn (i)
|
|
285
355
|
(let (
|
|
286
|
-
(r (math/floor (/ @i @
|
|
287
|
-
(c (math/mod @i @
|
|
356
|
+
(r (math/floor (/ @i @entity.cols)))
|
|
357
|
+
(c (math/mod @i @entity.cols))
|
|
288
358
|
(v (array/nth @entity.cells @i))
|
|
289
359
|
(cellColor (if (> @v 0.66) @config.onColor (if (> @v 0.33) @config.midColor (if (> @v 0.05) @config.lowColor @config.offColor))))
|
|
290
360
|
)
|
|
@@ -314,19 +384,19 @@ orbital GridSimOrbital {
|
|
|
314
384
|
{ type: typography, variant: caption, color: muted, content: (str/concat "Generation " @entity.generation " · " @entity.aliveCount " active") }
|
|
315
385
|
] },
|
|
316
386
|
{ type: learning-canvas, keyMap: { Space: TOGGLE_RUN, ArrowRight: STEP, KeyR: RESET }, width: @config.width, height: @config.height, backgroundColor: @config.backgroundColor, shapes: @entity.cellShapes, interactive: true, animate: false, onShapeClick: "TAP_CELL" },
|
|
317
|
-
{ type: typography, variant: body, content: @
|
|
387
|
+
{ type: typography, variant: body, content: @entity.taskText }
|
|
318
388
|
] }
|
|
319
389
|
]
|
|
320
390
|
})
|
|
321
391
|
(emit GRID_STEPPED { generation: @entity.generation, aliveCount: @entity.aliveCount })
|
|
322
392
|
|
|
323
393
|
TAP_CELL -> idle when (== @entity.active true)
|
|
324
|
-
(set @entity.cells (array/map (array/range 0 (* @
|
|
394
|
+
(set @entity.cells (array/map (array/range 0 (* @entity.rows @entity.cols)) (fn (j) (if (== @j (object/get ?payload index)) (if (> (array/nth @entity.cells @j) 0.5) 0 1) (array/nth @entity.cells @j)))))
|
|
325
395
|
(set @entity.aliveCount (array/len (array/filter @entity.cells (fn v (> @v 0.05)))))
|
|
326
|
-
(set @entity.cellShapes (array/map (array/range 0 (* @
|
|
396
|
+
(set @entity.cellShapes (array/map (array/range 0 (* @entity.rows @entity.cols)) (fn (i)
|
|
327
397
|
(let (
|
|
328
|
-
(r (math/floor (/ @i @
|
|
329
|
-
(c (math/mod @i @
|
|
398
|
+
(r (math/floor (/ @i @entity.cols)))
|
|
399
|
+
(c (math/mod @i @entity.cols))
|
|
330
400
|
(v (array/nth @entity.cells @i))
|
|
331
401
|
(cellColor (if (> @v 0.66) @config.onColor (if (> @v 0.33) @config.midColor (if (> @v 0.05) @config.lowColor @config.offColor))))
|
|
332
402
|
)
|
|
@@ -356,7 +426,7 @@ orbital GridSimOrbital {
|
|
|
356
426
|
{ type: typography, variant: caption, color: muted, content: (str/concat "Generation " @entity.generation " · " @entity.aliveCount " active") }
|
|
357
427
|
] },
|
|
358
428
|
{ type: learning-canvas, keyMap: { Space: TOGGLE_RUN, ArrowRight: STEP, KeyR: RESET }, width: @config.width, height: @config.height, backgroundColor: @config.backgroundColor, shapes: @entity.cellShapes, interactive: true, animate: false, onShapeClick: "TAP_CELL" },
|
|
359
|
-
{ type: typography, variant: body, content: @
|
|
429
|
+
{ type: typography, variant: body, content: @entity.taskText }
|
|
360
430
|
] }
|
|
361
431
|
]
|
|
362
432
|
})
|
|
@@ -365,12 +435,12 @@ orbital GridSimOrbital {
|
|
|
365
435
|
RESET -> idle when (== @entity.active true)
|
|
366
436
|
(set @entity.generation 0)
|
|
367
437
|
(set @entity.running false)
|
|
368
|
-
(set @entity.cells (array/map (array/range 0 (* @
|
|
438
|
+
(set @entity.cells (array/map (array/range 0 (* @entity.rows @entity.cols)) (fn (i) (if (array/includes @entity.seeds @i) 1 0))))
|
|
369
439
|
(set @entity.aliveCount (array/len (array/filter @entity.cells (fn v (> @v 0.05)))))
|
|
370
|
-
(set @entity.cellShapes (array/map (array/range 0 (* @
|
|
440
|
+
(set @entity.cellShapes (array/map (array/range 0 (* @entity.rows @entity.cols)) (fn (i)
|
|
371
441
|
(let (
|
|
372
|
-
(r (math/floor (/ @i @
|
|
373
|
-
(c (math/mod @i @
|
|
442
|
+
(r (math/floor (/ @i @entity.cols)))
|
|
443
|
+
(c (math/mod @i @entity.cols))
|
|
374
444
|
(v (array/nth @entity.cells @i))
|
|
375
445
|
(cellColor (if (> @v 0.66) @config.onColor (if (> @v 0.33) @config.midColor (if (> @v 0.05) @config.lowColor @config.offColor))))
|
|
376
446
|
)
|
|
@@ -400,11 +470,11 @@ orbital GridSimOrbital {
|
|
|
400
470
|
{ type: typography, variant: caption, color: muted, content: (str/concat "Generation " @entity.generation " · " @entity.aliveCount " active") }
|
|
401
471
|
] },
|
|
402
472
|
{ type: learning-canvas, keyMap: { Space: TOGGLE_RUN, ArrowRight: STEP, KeyR: RESET }, width: @config.width, height: @config.height, backgroundColor: @config.backgroundColor, shapes: @entity.cellShapes, interactive: true, animate: false, onShapeClick: "TAP_CELL" },
|
|
403
|
-
{ type: typography, variant: body, content: @
|
|
473
|
+
{ type: typography, variant: body, content: @entity.taskText }
|
|
404
474
|
] }
|
|
405
475
|
]
|
|
406
476
|
})
|
|
407
|
-
(emit GRID_RESET { seedCount: (array/len @
|
|
477
|
+
(emit GRID_RESET { seedCount: (array/len @entity.seeds) })
|
|
408
478
|
}
|
|
409
479
|
|
|
410
480
|
ticks {
|
|
@@ -414,35 +484,35 @@ orbital GridSimOrbital {
|
|
|
414
484
|
(when (>= (* @entity.elapsedMs @entity.speed) 300)
|
|
415
485
|
(do
|
|
416
486
|
(set @entity.elapsedMs 0)
|
|
417
|
-
(set @entity.cells (array/map (array/range 0 (* @
|
|
487
|
+
(set @entity.cells (array/map (array/range 0 (* @entity.rows @entity.cols)) (fn (i)
|
|
418
488
|
(let (
|
|
419
|
-
(r (math/floor (/ @i @
|
|
420
|
-
(c (math/mod @i @
|
|
489
|
+
(r (math/floor (/ @i @entity.cols)))
|
|
490
|
+
(c (math/mod @i @entity.cols))
|
|
421
491
|
(v (array/nth @entity.cells @i))
|
|
422
|
-
(up (if (> @r 0) (array/nth @entity.cells (- @i @
|
|
423
|
-
(down (if (< @r (- @
|
|
492
|
+
(up (if (> @r 0) (array/nth @entity.cells (- @i @entity.cols)) 0))
|
|
493
|
+
(down (if (< @r (- @entity.rows 1)) (array/nth @entity.cells (+ @i @entity.cols)) 0))
|
|
424
494
|
(left (if (> @c 0) (array/nth @entity.cells (- @i 1)) 0))
|
|
425
|
-
(right (if (< @c (- @
|
|
426
|
-
(ul (if (and (> @r 0) (> @c 0)) (array/nth @entity.cells (- (- @i @
|
|
427
|
-
(ur (if (and (> @r 0) (< @c (- @
|
|
428
|
-
(dl (if (and (< @r (- @
|
|
429
|
-
(dr (if (and (< @r (- @
|
|
495
|
+
(right (if (< @c (- @entity.cols 1)) (array/nth @entity.cells (+ @i 1)) 0))
|
|
496
|
+
(ul (if (and (> @r 0) (> @c 0)) (array/nth @entity.cells (- (- @i @entity.cols) 1)) 0))
|
|
497
|
+
(ur (if (and (> @r 0) (< @c (- @entity.cols 1))) (array/nth @entity.cells (+ (- @i @entity.cols) 1)) 0))
|
|
498
|
+
(dl (if (and (< @r (- @entity.rows 1)) (> @c 0)) (array/nth @entity.cells (- (+ @i @entity.cols) 1)) 0))
|
|
499
|
+
(dr (if (and (< @r (- @entity.rows 1)) (< @c (- @entity.cols 1))) (array/nth @entity.cells (+ @i @entity.cols 1)) 0))
|
|
430
500
|
(n4 (+ @up @down @left @right))
|
|
431
501
|
(n8 (+ @n4 @ul @ur @dl @dr))
|
|
432
502
|
)
|
|
433
|
-
(if (== @
|
|
503
|
+
(if (== @entity.rule "life")
|
|
434
504
|
(if (if (> @v 0.5)
|
|
435
505
|
(if (== (math/round @n8 0) 2) true (== (math/round @n8 0) 3))
|
|
436
506
|
(== (math/round @n8 0) 3)) 1 0)
|
|
437
|
-
(if (== @
|
|
507
|
+
(if (== @entity.rule "spread")
|
|
438
508
|
(if (if (> @v 0.5) true (> @n4 0.5)) 1 0)
|
|
439
509
|
(math/max 0 (* @config.decay (+ @v (* @config.diffuseRate (- (/ @n4 4) @v)))))))))))
|
|
440
510
|
(set @entity.generation (+ @entity.generation 1))
|
|
441
511
|
(set @entity.aliveCount (array/len (array/filter @entity.cells (fn v (> @v 0.05)))))
|
|
442
|
-
(set @entity.cellShapes (array/map (array/range 0 (* @
|
|
512
|
+
(set @entity.cellShapes (array/map (array/range 0 (* @entity.rows @entity.cols)) (fn (i)
|
|
443
513
|
(let (
|
|
444
|
-
(r (math/floor (/ @i @
|
|
445
|
-
(c (math/mod @i @
|
|
514
|
+
(r (math/floor (/ @i @entity.cols)))
|
|
515
|
+
(c (math/mod @i @entity.cols))
|
|
446
516
|
(v (array/nth @entity.cells @i))
|
|
447
517
|
(cellColor (if (> @v 0.66) @config.onColor (if (> @v 0.33) @config.midColor (if (> @v 0.05) @config.lowColor @config.offColor))))
|
|
448
518
|
)
|
|
@@ -456,6 +526,16 @@ orbital GridSimOrbital {
|
|
|
456
526
|
}
|
|
457
527
|
@description "Lab router broadcast naming the active mode; this instrument renders when the mode equals matchMode, otherwise renders null."
|
|
458
528
|
@tier "domain"
|
|
529
|
+
ROSTER_LOADED {
|
|
530
|
+
mode : string!
|
|
531
|
+
taskText : string!
|
|
532
|
+
rule : string!
|
|
533
|
+
rows : number!
|
|
534
|
+
cols : number!
|
|
535
|
+
seeds : [number]!
|
|
536
|
+
}
|
|
537
|
+
@description "Runtime content feed, honoured only when rosterSource is event — mode names the instrument it is for (the matchMode it carries, blank when standalone) and taskText, rule, rows, cols and seeds define the world; a matching instrument re-initialises from it exactly as INIT does from config, any other instrument hides."
|
|
538
|
+
@tier "domain"
|
|
459
539
|
TOGGLE_RUN {
|
|
460
540
|
}
|
|
461
541
|
@description "Learner pressed the Play/Pause toggle — starts or freezes the evolution."
|
|
@@ -517,8 +597,12 @@ orbital GridSimOrbital {
|
|
|
517
597
|
config {
|
|
518
598
|
matchMode : string = ""
|
|
519
599
|
@label "Match Mode"
|
|
520
|
-
@description "When composed behind a lab router, the MODE_SELECTED mode value this instrument responds to. Empty string means standalone — render immediately on INIT."
|
|
600
|
+
@description "When composed behind a lab router, the MODE_SELECTED mode value this instrument responds to. Empty string means standalone — render immediately on INIT (or on ROSTER_LOADED when rosterSource is event)."
|
|
521
601
|
@tier "presentation"
|
|
602
|
+
rosterSource : "config" | "event" = "config"
|
|
603
|
+
@label "Roster Source"
|
|
604
|
+
@description "Where the world definition (taskText, rule, rows, cols, seeds) comes from: config reads those knobs at INIT; event waits for ROSTER_LOADED and takes them from its payload."
|
|
605
|
+
@tier "domain"
|
|
522
606
|
title : string = "Grid World"
|
|
523
607
|
@label "Title"
|
|
524
608
|
@description "The instrument's name, the header's one hero."
|
|
@@ -33,6 +33,8 @@ orbital HotspotOrbital {
|
|
|
33
33
|
id : string!
|
|
34
34
|
active : boolean = false
|
|
35
35
|
title : string
|
|
36
|
+
shapes : [HotspotShape]
|
|
37
|
+
prompts : [HotspotPrompt]
|
|
36
38
|
promptIndex : number = 0
|
|
37
39
|
totalPrompts : number = 0
|
|
38
40
|
score : number = 0
|
|
@@ -51,17 +53,19 @@ orbital HotspotOrbital {
|
|
|
51
53
|
initial: idle
|
|
52
54
|
|
|
53
55
|
state idle {
|
|
54
|
-
INIT -> idle when (== @config.matchMode "")
|
|
56
|
+
INIT -> idle when (and (== @config.matchMode "") (== @config.rosterSource "config"))
|
|
57
|
+
(set @entity.shapes @config.shapes)
|
|
58
|
+
(set @entity.prompts @config.prompts)
|
|
55
59
|
(let (
|
|
56
|
-
(first (array/nth @
|
|
57
|
-
(circles (array/map @
|
|
58
|
-
(labels (array/map @
|
|
60
|
+
(first (array/nth @entity.prompts 0))
|
|
61
|
+
(circles (array/map @entity.shapes (fn s { type: circle, id: (object/get @s id), x: (object/get @s x), y: (object/get @s y), radius: (object/get @s radius 22), tone: (object/get @s color "series-1"), fillTone: (object/get @s color "series-1"), fillStyle: "solid" })))
|
|
62
|
+
(labels (array/map @entity.shapes (fn s { type: text, id: (str/concat "label-" (object/get @s id)), x: (object/get @s x), y: (+ (object/get @s y) (object/get @s radius 22) 14), text: (object/get @s label), textSize: "xs", align: "center", tone: "label" })))
|
|
59
63
|
)
|
|
60
64
|
(do
|
|
61
65
|
(set @entity.active true)
|
|
62
66
|
(set @entity.title @config.title)
|
|
63
67
|
(set @entity.promptIndex 0)
|
|
64
|
-
(set @entity.totalPrompts (array/len @
|
|
68
|
+
(set @entity.totalPrompts (array/len @entity.prompts))
|
|
65
69
|
(set @entity.score 0)
|
|
66
70
|
(set @entity.tries 0)
|
|
67
71
|
(set @entity.found false)
|
|
@@ -106,17 +110,19 @@ orbital HotspotOrbital {
|
|
|
106
110
|
(set @entity.active false)
|
|
107
111
|
(render-ui main null)
|
|
108
112
|
|
|
109
|
-
MODE_SELECTED -> idle when (== ?mode @config.matchMode)
|
|
113
|
+
MODE_SELECTED -> idle when (and (== ?mode @config.matchMode) (== @config.rosterSource "config"))
|
|
114
|
+
(set @entity.shapes @config.shapes)
|
|
115
|
+
(set @entity.prompts @config.prompts)
|
|
110
116
|
(let (
|
|
111
|
-
(first (array/nth @
|
|
112
|
-
(circles (array/map @
|
|
113
|
-
(labels (array/map @
|
|
117
|
+
(first (array/nth @entity.prompts 0))
|
|
118
|
+
(circles (array/map @entity.shapes (fn s { type: circle, id: (object/get @s id), x: (object/get @s x), y: (object/get @s y), radius: (object/get @s radius 22), tone: (object/get @s color "series-1"), fillTone: (object/get @s color "series-1"), fillStyle: "solid" })))
|
|
119
|
+
(labels (array/map @entity.shapes (fn s { type: text, id: (str/concat "label-" (object/get @s id)), x: (object/get @s x), y: (+ (object/get @s y) (object/get @s radius 22) 14), text: (object/get @s label), textSize: "xs", align: "center", tone: "label" })))
|
|
114
120
|
)
|
|
115
121
|
(do
|
|
116
122
|
(set @entity.active true)
|
|
117
123
|
(set @entity.title @config.title)
|
|
118
124
|
(set @entity.promptIndex 0)
|
|
119
|
-
(set @entity.totalPrompts (array/len @
|
|
125
|
+
(set @entity.totalPrompts (array/len @entity.prompts))
|
|
120
126
|
(set @entity.score 0)
|
|
121
127
|
(set @entity.tries 0)
|
|
122
128
|
(set @entity.found false)
|
|
@@ -157,15 +163,72 @@ orbital HotspotOrbital {
|
|
|
157
163
|
]
|
|
158
164
|
})
|
|
159
165
|
|
|
166
|
+
ROSTER_LOADED -> idle when (and (== @config.rosterSource "event") (and (== ?mode @config.matchMode) (and (> (array/len ?shapes) 0) (> (array/len ?prompts) 0))))
|
|
167
|
+
(set @entity.shapes ?shapes)
|
|
168
|
+
(set @entity.prompts ?prompts)
|
|
169
|
+
(let (
|
|
170
|
+
(first (array/nth @entity.prompts 0))
|
|
171
|
+
(circles (array/map @entity.shapes (fn s { type: circle, id: (object/get @s id), x: (object/get @s x), y: (object/get @s y), radius: (object/get @s radius 22), tone: (object/get @s color "series-1"), fillTone: (object/get @s color "series-1"), fillStyle: "solid" })))
|
|
172
|
+
(labels (array/map @entity.shapes (fn s { type: text, id: (str/concat "label-" (object/get @s id)), x: (object/get @s x), y: (+ (object/get @s y) (object/get @s radius 22) 14), text: (object/get @s label), textSize: "xs", align: "center", tone: "label" })))
|
|
173
|
+
)
|
|
174
|
+
(do
|
|
175
|
+
(set @entity.active true)
|
|
176
|
+
(set @entity.title @config.title)
|
|
177
|
+
(set @entity.promptIndex 0)
|
|
178
|
+
(set @entity.totalPrompts (array/len @entity.prompts))
|
|
179
|
+
(set @entity.score 0)
|
|
180
|
+
(set @entity.tries 0)
|
|
181
|
+
(set @entity.found false)
|
|
182
|
+
(set @entity.done false)
|
|
183
|
+
(set @entity.promptText (object/get @first prompt))
|
|
184
|
+
(set @entity.targetId (object/get @first targetId))
|
|
185
|
+
(set @entity.explanation (object/get @first explanation ""))
|
|
186
|
+
(set @entity.feedback "")
|
|
187
|
+
(set @entity.canvasShapes (array/concat @circles @labels))
|
|
188
|
+
(set @entity.view [
|
|
189
|
+
{ type: card, variant: bordered, padding: md, children: [
|
|
190
|
+
{ type: typography, variant: body, content: @entity.promptText }
|
|
191
|
+
] },
|
|
192
|
+
{ type: learning-canvas, width: @config.width, height: @config.height, backgroundColor: @config.backgroundColor, shapes: @entity.canvasShapes, interactive: true, animate: false, onShapeClick: "TAP_SHAPE", keyMap: { Space: NEXT, ArrowRight: NEXT, KeyR: RETRY } },
|
|
193
|
+
{ type: stack, direction: horizontal, gap: xs, children: [
|
|
194
|
+
{ type: typography, variant: body, content: @entity.feedback }
|
|
195
|
+
] },
|
|
196
|
+
{ type: stack, direction: horizontal, align: center, gap: sm, wrap: true, children: [
|
|
197
|
+
{ type: button, action: NEXT, label: @config.nextLabel, icon: "chevron-right", variant: primary, disabled: (if @entity.found false true) },
|
|
198
|
+
{ type: typography, variant: caption, color: muted, content: (str/concat "First-try " @entity.score " of " @entity.totalPrompts) }
|
|
199
|
+
] }
|
|
200
|
+
])))
|
|
201
|
+
(render-ui main {
|
|
202
|
+
type: box
|
|
203
|
+
padding: md
|
|
204
|
+
children: [
|
|
205
|
+
{ type: stack, direction: vertical, gap: md, children: [
|
|
206
|
+
{ type: stack, direction: horizontal, justify: between, align: start, gap: md, children: [
|
|
207
|
+
{ type: stack, direction: vertical, gap: xs, children: [
|
|
208
|
+
{ type: typography, variant: h4, content: @entity.title },
|
|
209
|
+
(if (== @config.summary "") null { type: typography, variant: body2, color: muted, content: @config.summary })
|
|
210
|
+
] },
|
|
211
|
+
{ type: badge, label: (if @entity.done "Round complete" (if @entity.found "Correct" (if (> @entity.tries 0) "Try again" (str/concat "Score " @entity.score " / " @entity.totalPrompts)))), variant: (if @entity.done "primary" (if @entity.found "success" (if (> @entity.tries 0) "error" "neutral"))) }
|
|
212
|
+
] },
|
|
213
|
+
{ type: progress-bar, value: (+ @entity.promptIndex 1), max: @entity.totalPrompts, showPercentage: false, label: (str/concat "Prompt " (str/concat "" (+ @entity.promptIndex 1)) " of " (str/concat "" @entity.totalPrompts)) },
|
|
214
|
+
{ type: stack, direction: vertical, gap: md, children: @entity.view }
|
|
215
|
+
] }
|
|
216
|
+
]
|
|
217
|
+
})
|
|
218
|
+
|
|
219
|
+
ROSTER_LOADED -> idle when (and (== @config.rosterSource "event") (not (== ?mode @config.matchMode)))
|
|
220
|
+
(set @entity.active false)
|
|
221
|
+
(render-ui main null)
|
|
222
|
+
|
|
160
223
|
TAP_SHAPE -> idle when (and (== @entity.active true) (and (== @entity.found false) (== @entity.done false)))
|
|
161
224
|
(let (
|
|
162
225
|
(tappedId (str/replace (object/get ?payload id "") "label-" ""))
|
|
163
226
|
(hit (== @tappedId @entity.targetId))
|
|
164
|
-
(tapped (array/find @
|
|
227
|
+
(tapped (array/find @entity.shapes (fn s (== (object/get @s id) @tappedId))))
|
|
165
228
|
(tappedLabel (object/get @tapped label ""))
|
|
166
|
-
(target (array/find @
|
|
167
|
-
(circles (array/map @
|
|
168
|
-
(labels (array/map @
|
|
229
|
+
(target (array/find @entity.shapes (fn s (== (object/get @s id) @entity.targetId))))
|
|
230
|
+
(circles (array/map @entity.shapes (fn s { type: circle, id: (object/get @s id), x: (object/get @s x), y: (object/get @s y), radius: (object/get @s radius 22), tone: (object/get @s color "series-1"), fillTone: (object/get @s color "series-1"), fillStyle: "solid" })))
|
|
231
|
+
(labels (array/map @entity.shapes (fn s { type: text, id: (str/concat "label-" (object/get @s id)), x: (object/get @s x), y: (+ (object/get @s y) (object/get @s radius 22) 14), text: (object/get @s label), textSize: "xs", align: "center", tone: "label" })))
|
|
169
232
|
(ring (if @hit
|
|
170
233
|
[ { type: circle, id: "hit-ring", x: (object/get @target x), y: (object/get @target y), radius: (+ (object/get @target radius 22) 6), tone: @config.hitColor, fillStyle: "outline", stroke: "bold" } ]
|
|
171
234
|
[]))
|
|
@@ -229,13 +292,13 @@ orbital HotspotOrbital {
|
|
|
229
292
|
(emit TAP_JUDGED { correct: @entity.found, promptIndex: @entity.promptIndex, tries: @entity.tries })
|
|
230
293
|
|
|
231
294
|
NEXT -> idle when (and (== @entity.active true) (and (== @entity.found true) (== @entity.done false)))
|
|
232
|
-
(if (>= (+ @entity.promptIndex 1) (array/len @
|
|
295
|
+
(if (>= (+ @entity.promptIndex 1) (array/len @entity.prompts)) (emit LEARN_ROUND_COMPLETE { score: @entity.score, total: (array/len @entity.prompts) }) null)
|
|
233
296
|
(let (
|
|
234
297
|
(nextIndex (+ @entity.promptIndex 1))
|
|
235
|
-
(finished (>= @nextIndex (array/len @
|
|
236
|
-
(next (array/nth @
|
|
237
|
-
(circles (array/map @
|
|
238
|
-
(labels (array/map @
|
|
298
|
+
(finished (>= @nextIndex (array/len @entity.prompts)))
|
|
299
|
+
(next (array/nth @entity.prompts (math/min @nextIndex (- (array/len @entity.prompts) 1))))
|
|
300
|
+
(circles (array/map @entity.shapes (fn s { type: circle, id: (object/get @s id), x: (object/get @s x), y: (object/get @s y), radius: (object/get @s radius 22), tone: (object/get @s color "series-1"), fillTone: (object/get @s color "series-1"), fillStyle: "solid" })))
|
|
301
|
+
(labels (array/map @entity.shapes (fn s { type: text, id: (str/concat "label-" (object/get @s id)), x: (object/get @s x), y: (+ (object/get @s y) (object/get @s radius 22) 14), text: (object/get @s label), textSize: "xs", align: "center", tone: "label" })))
|
|
239
302
|
)
|
|
240
303
|
(do
|
|
241
304
|
(set @entity.promptIndex (if @finished @entity.promptIndex @nextIndex))
|
|
@@ -288,9 +351,9 @@ orbital HotspotOrbital {
|
|
|
288
351
|
|
|
289
352
|
RETRY -> idle when (and (== @entity.active true) (== @entity.done true))
|
|
290
353
|
(let (
|
|
291
|
-
(first (array/nth @
|
|
292
|
-
(circles (array/map @
|
|
293
|
-
(labels (array/map @
|
|
354
|
+
(first (array/nth @entity.prompts 0))
|
|
355
|
+
(circles (array/map @entity.shapes (fn s { type: circle, id: (object/get @s id), x: (object/get @s x), y: (object/get @s y), radius: (object/get @s radius 22), tone: (object/get @s color "series-1"), fillTone: (object/get @s color "series-1"), fillStyle: "solid" })))
|
|
356
|
+
(labels (array/map @entity.shapes (fn s { type: text, id: (str/concat "label-" (object/get @s id)), x: (object/get @s x), y: (+ (object/get @s y) (object/get @s radius 22) 14), text: (object/get @s label), textSize: "xs", align: "center", tone: "label" })))
|
|
294
357
|
)
|
|
295
358
|
(do
|
|
296
359
|
(set @entity.promptIndex 0)
|
|
@@ -342,6 +405,13 @@ orbital HotspotOrbital {
|
|
|
342
405
|
}
|
|
343
406
|
@description "Lab router broadcast naming the active mode; this instrument renders when the mode equals matchMode, otherwise renders null."
|
|
344
407
|
@tier "domain"
|
|
408
|
+
ROSTER_LOADED {
|
|
409
|
+
mode : string!
|
|
410
|
+
shapes : [HotspotShape]!
|
|
411
|
+
prompts : [HotspotPrompt]!
|
|
412
|
+
}
|
|
413
|
+
@description "Runtime content feed, honoured only when rosterSource is event — mode names the instrument it is for (the matchMode it carries, blank when standalone), shapes is the hotspot roster and prompts the prompt list; a matching instrument re-initialises from it exactly as INIT does from config, any other instrument hides."
|
|
414
|
+
@tier "domain"
|
|
345
415
|
TAP_SHAPE {
|
|
346
416
|
payload : { id : string type : string index : number! }
|
|
347
417
|
}
|
|
@@ -400,6 +470,10 @@ orbital HotspotOrbital {
|
|
|
400
470
|
@label "Concept"
|
|
401
471
|
@description "One line under the title saying what is being identified (keep it under ~65 characters). Empty shows no line."
|
|
402
472
|
@tier "presentation"
|
|
473
|
+
rosterSource : "config" | "event" = "config"
|
|
474
|
+
@label "Roster Source"
|
|
475
|
+
@description "Where the shapes and prompts roster comes from: config reads the shapes and prompts knobs at INIT; event waits for ROSTER_LOADED and takes the roster from its payload."
|
|
476
|
+
@tier "domain"
|
|
403
477
|
shapes : [HotspotShape] = [
|
|
404
478
|
{ id: "nucleus", label: "Nucleus", x: 300, y: 170, radius: 34, color: "series-1" },
|
|
405
479
|
{ id: "membrane", label: "Membrane", x: 130, y: 120, radius: 26, color: "series-2" },
|