WebashalarForML commited on
Commit
638b051
·
verified ·
1 Parent(s): 1da2474

Upload 86 files

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. .gitattributes +2 -0
  2. v2/scratch_agent/.gitignore +1 -0
  3. v2/scratch_agent/README.md +0 -0
  4. v2/scratch_agent/__pycache__/agent.cpython-312.pyc +0 -0
  5. v2/scratch_agent/__pycache__/retry_groq.cpython-312.pyc +0 -0
  6. v2/scratch_agent/action_node.py +452 -0
  7. v2/scratch_agent/agent.py +1647 -0
  8. v2/scratch_agent/agent2.py +259 -0
  9. v2/scratch_agent/all_prompts.py +108 -0
  10. v2/scratch_agent/app.py +0 -0
  11. v2/scratch_agent/block_function.py +1147 -0
  12. v2/scratch_agent/block_function_v1.py +759 -0
  13. v2/scratch_agent/blocks.zip +3 -0
  14. v2/scratch_agent/blocks/blocks.json +2221 -0
  15. v2/scratch_agent/blocks/boolean_blocks.json +281 -0
  16. v2/scratch_agent/blocks/c_blocks.json +105 -0
  17. v2/scratch_agent/blocks/cap_blocks.json +53 -0
  18. v2/scratch_agent/blocks/classwise_blocks/control_block.json +168 -0
  19. v2/scratch_agent/blocks/classwise_blocks/data_block.json +328 -0
  20. v2/scratch_agent/blocks/classwise_blocks/event_block.json +136 -0
  21. v2/scratch_agent/blocks/classwise_blocks/look_block.json +365 -0
  22. v2/scratch_agent/blocks/classwise_blocks/motion_block.json +370 -0
  23. v2/scratch_agent/blocks/classwise_blocks/operator_block.json +409 -0
  24. v2/scratch_agent/blocks/classwise_blocks/sensing_block.json +292 -0
  25. v2/scratch_agent/blocks/classwise_blocks/sound_block.json +167 -0
  26. v2/scratch_agent/blocks/excel_contetn/hat_block.xlsx +0 -0
  27. v2/scratch_agent/blocks/excel_contetn/stack_block.xlsx +0 -0
  28. v2/scratch_agent/blocks/hat_blocks.json +217 -0
  29. v2/scratch_agent/blocks/reporter_blocks.json +709 -0
  30. v2/scratch_agent/blocks/stack_blocks.json +1321 -0
  31. v2/scratch_agent/blocks_content.json +1367 -0
  32. v2/scratch_agent/blocks_defination.py +274 -0
  33. v2/scratch_agent/blocks_v1/blocks.json +2221 -0
  34. v2/scratch_agent/blocks_v1/boolean_blocks.json +277 -0
  35. v2/scratch_agent/blocks_v1/c_blocks.json +105 -0
  36. v2/scratch_agent/blocks_v1/cap_blocks.json +53 -0
  37. v2/scratch_agent/blocks_v1/excel_contetn/hat_block.xlsx +0 -0
  38. v2/scratch_agent/blocks_v1/excel_contetn/stack_block.xlsx +0 -0
  39. v2/scratch_agent/blocks_v1/hat_blocks.json +217 -0
  40. v2/scratch_agent/blocks_v1/reporter_blocks.json +709 -0
  41. v2/scratch_agent/blocks_v1/stack_blocks.json +1316 -0
  42. v2/scratch_agent/debug_combine_blocks.json +419 -0
  43. v2/scratch_agent/debug_combine_state.json +2070 -0
  44. v2/scratch_agent/debug_declaration.json +80 -0
  45. v2/scratch_agent/debug_declaration_build.json +222 -0
  46. v2/scratch_agent/debug_declaration_builder.json +327 -0
  47. v2/scratch_agent/debug_declaration_plan.json +85 -0
  48. v2/scratch_agent/debug_state.json +478 -0
  49. v2/scratch_agent/debugs.txt +0 -0
  50. v2/scratch_agent/errors_node.txt +531 -0
.gitattributes CHANGED
@@ -40,3 +40,5 @@ scratch_VLM/Documentation_Scratch/Scratch[[:space:]]3.0[[:space:]]BlocK_shape_ex
40
  scratch_VLM/game_samples/Duck-Pocalypse.sb3 filter=lfs diff=lfs merge=lfs -text
41
  scratch_VLM/game_samples/Pong[[:space:]]Game.sb3 filter=lfs diff=lfs merge=lfs -text
42
  scratch_VLM/scratch_agent/uploads/documents/LLM_based_QA_chatbot_builder.pdf filter=lfs diff=lfs merge=lfs -text
 
 
 
40
  scratch_VLM/game_samples/Duck-Pocalypse.sb3 filter=lfs diff=lfs merge=lfs -text
41
  scratch_VLM/game_samples/Pong[[:space:]]Game.sb3 filter=lfs diff=lfs merge=lfs -text
42
  scratch_VLM/scratch_agent/uploads/documents/LLM_based_QA_chatbot_builder.pdf filter=lfs diff=lfs merge=lfs -text
43
+ v2/scratch_agent/static/assets/backdrops/ef9973bcff6d4cbc558e946028ec7d23.png filter=lfs diff=lfs merge=lfs -text
44
+ v2/scratch_agent/uploads/documents/LLM_based_QA_chatbot_builder.pdf filter=lfs diff=lfs merge=lfs -text
v2/scratch_agent/.gitignore ADDED
@@ -0,0 +1 @@
 
 
1
+ a
v2/scratch_agent/README.md ADDED
File without changes
v2/scratch_agent/__pycache__/agent.cpython-312.pyc ADDED
Binary file (65.8 kB). View file
 
v2/scratch_agent/__pycache__/retry_groq.cpython-312.pyc ADDED
Binary file (9.73 kB). View file
 
v2/scratch_agent/action_node.py ADDED
@@ -0,0 +1,452 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import json
2
+ import uuid
3
+ import logging
4
+ from typing import Dict, Any, List
5
+
6
+ # Assume GameState is a TypedDict or similar for clarity
7
+ # from typing import TypedDict
8
+ # class GameState(TypedDict):
9
+ # description: str
10
+ # project_json: Dict[str, Any]
11
+ # action_plan: Dict[str, Any]
12
+ # sprite_initial_positions: Dict[str, Any]
13
+
14
+ # Placeholder for actual GameState in your application
15
+ GameState = Dict[str, Any]
16
+
17
+ logger = logging.getLogger(__name__)
18
+
19
+ # --- Mock Agent for demonstration ---
20
+ class MockAgent:
21
+ def invoke(self, payload: Dict[str, Any]) -> Dict[str, Any]:
22
+ """
23
+ Mocks an LLM agent invocation. In a real scenario, this would call your
24
+ actual LLM API (e.g., through LangChain, LlamaIndex, etc.).
25
+ """
26
+ user_message = payload["messages"][-1]["content"]
27
+ print(f"\n--- Mock Agent Received Prompt (partial) ---\n{user_message[:500]}...\n------------------------------------------")
28
+
29
+ # Simplified mock responses for demonstration purposes
30
+ # In a real scenario, the LLM would generate actual Scratch block JSON
31
+ if "Propose a high-level action flow" in user_message:
32
+ return {
33
+ "messages": [{
34
+ "content": json.dumps({
35
+ "action_overall_flow": {
36
+ "Sprite1": {
37
+ "description": "Basic movement and interaction",
38
+ "plans": [
39
+ {
40
+ "event": "when flag clicked",
41
+ "logic": "forever loop: move 10 steps, if touching Edge then turn 15 degrees"
42
+ },
43
+ {
44
+ "event": "when space key pressed",
45
+ "logic": "say Hello! for 2 seconds"
46
+ }
47
+ ]
48
+ },
49
+ "Ball": {
50
+ "description": "Simple bouncing behavior",
51
+ "plans": [
52
+ {
53
+ "event": "when flag clicked",
54
+ "logic": "move 5 steps, if on edge bounce"
55
+ }
56
+ ]
57
+ }
58
+ }
59
+ })
60
+ }]
61
+ }
62
+ elif "You are an AI assistant generating Scratch 3.0 block JSON" in user_message:
63
+ # This mock response is highly simplified. A real LLM would generate
64
+ # valid Scratch blocks based on the provided relevant catalog and plan.
65
+ # We're just demonstrating the *mechanism* of filtering the catalog.
66
+ if "Sprite1" in user_message:
67
+ return {
68
+ "messages": [{
69
+ "content": json.dumps({
70
+ f"block_id_{generate_block_id()}": {
71
+ "opcode": "event_whenflagclicked",
72
+ "next": f"block_id_{generate_block_id()}_forever",
73
+ "parent": None,
74
+ "inputs": {}, "fields": {}, "shadow": False, "topLevel": True, "x": 100, "y": 100
75
+ },
76
+ f"block_id_{generate_block_id()}_forever": {
77
+ "opcode": "control_forever",
78
+ "next": None,
79
+ "parent": f"block_id_{generate_block_id()}",
80
+ "inputs": {
81
+ "SUBSTACK": [2, f"block_id_{generate_block_id()}_move"]
82
+ }, "fields": {}, "shadow": False, "topLevel": False
83
+ },
84
+ f"block_id_{generate_block_id()}_move": {
85
+ "opcode": "motion_movesteps",
86
+ "next": f"block_id_{generate_block_id()}_if",
87
+ "parent": f"block_id_{generate_block_id()}_forever",
88
+ "inputs": {
89
+ "STEPS": [1, [4, "10"]]
90
+ }, "fields": {}, "shadow": False, "topLevel": False
91
+ },
92
+ f"block_id_{generate_block_id()}_if": {
93
+ "opcode": "control_if",
94
+ "next": None,
95
+ "parent": f"block_id_{generate_block_id()}_forever",
96
+ "inputs": {
97
+ "CONDITION": [2, f"block_id_{generate_block_id()}_touching"],
98
+ "SUBSTACK": [2, f"block_id_{generate_block_id()}_turn"]
99
+ }, "fields": {}, "shadow": False, "topLevel": False
100
+ },
101
+ f"block_id_{generate_block_id()}_touching": {
102
+ "opcode": "sensing_touchingobject",
103
+ "next": None,
104
+ "parent": f"block_id_{generate_block_id()}_if",
105
+ "inputs": {
106
+ "TOUCHINGOBJECTMENU": [1, f"block_id_{generate_block_id()}_touching_menu"]
107
+ }, "fields": {}, "shadow": False, "topLevel": False
108
+ },
109
+ f"block_id_{generate_block_id()}_touching_menu": {
110
+ "opcode": "sensing_touchingobjectmenu",
111
+ "next": None,
112
+ "parent": f"block_id_{generate_block_id()}_touching",
113
+ "inputs": {},
114
+ "fields": {"TOUCHINGOBJECTMENU": ["_edge_", None]},
115
+ "shadow": True, "topLevel": False
116
+ },
117
+ f"block_id_{generate_block_id()}_turn": {
118
+ "opcode": "motion_turnright",
119
+ "next": None,
120
+ "parent": f"block_id_{generate_block_id()}_if",
121
+ "inputs": {
122
+ "DEGREES": [1, [4, "15"]]
123
+ }, "fields": {}, "shadow": False, "topLevel": False
124
+ },
125
+ f"block_id_{generate_block_id()}_say": {
126
+ "opcode": "looks_sayforsecs",
127
+ "next": None,
128
+ "parent": None, # This block would typically be part of a separate script
129
+ "inputs": {
130
+ "MESSAGE": [1, [10, "Hello!"]],
131
+ "SECS": [1, [4, "2"]]
132
+ }, "fields": {}, "shadow": False, "topLevel": True, "x": 300, "y": 100
133
+ }
134
+ })
135
+ }]
136
+ }
137
+ elif "Ball" in user_message:
138
+ return {
139
+ "messages": [{
140
+ "content": json.dumps({
141
+ f"block_id_{generate_block_id()}": {
142
+ "opcode": "event_whenflagclicked",
143
+ "next": f"block_id_{generate_block_id()}_moveball",
144
+ "parent": None,
145
+ "inputs": {}, "fields": {}, "shadow": False, "topLevel": True, "x": 100, "y": 100
146
+ },
147
+ f"block_id_{generate_block_id()}_moveball": {
148
+ "opcode": "motion_movesteps",
149
+ "next": f"block_id_{generate_block_id()}_edgebounce",
150
+ "parent": f"block_id_{generate_block_id()}",
151
+ "inputs": {
152
+ "STEPS": [1, [4, "5"]]
153
+ }, "fields": {}, "shadow": False, "topLevel": False
154
+ },
155
+ f"block_id_{generate_block_id()}_edgebounce": {
156
+ "opcode": "motion_ifonedgebounce",
157
+ "next": None,
158
+ "parent": f"block_id_{generate_block_id()}_moveball",
159
+ "inputs": {}, "fields": {}, "shadow": False, "topLevel": False
160
+ }
161
+ })
162
+ }]
163
+ }
164
+ return {"messages": [{"content": "[]"}]} # Default empty response
165
+
166
+ agent = MockAgent()
167
+
168
+ # Helper function to generate a unique block ID
169
+ def generate_block_id():
170
+ return str(uuid.uuid4())[:10].replace('-', '') # Shorten for readability, ensure uniqueness
171
+
172
+ # Placeholder for your extract_json_from_llm_response function
173
+ def extract_json_from_llm_response(response_string):
174
+ try:
175
+ # Assuming the LLM response is ONLY the JSON string within triple backticks
176
+ json_match = response_string.strip().replace("```json", "").replace("```", "").strip()
177
+ return json.loads(json_match)
178
+ except json.JSONDecodeError as e:
179
+ logger.error(f"Failed to decode JSON from LLM response: {e}")
180
+ logger.error(f"Raw response: {response_string}")
181
+ raise ValueError("Invalid JSON response from LLM")
182
+
183
+ # --- GLOBAL CATALOG OF ALL SCRATCH BLOCKS ---
184
+ # This is where you would load your block_content.json
185
+ # For demonstration, I'm using your provided snippets and adding some common ones.
186
+ # In a real application, you'd load this once at startup.
187
+ ALL_SCRATCH_BLOCKS_CATALOG = {
188
+ "motion_movesteps": {
189
+ "opcode": "motion_movesteps", "next": None, "parent": None,
190
+ "inputs": {"STEPS": [1, [4, "10"]]}, "fields": {}, "shadow": False, "topLevel": True, "x": 464, "y": -416
191
+ },
192
+ "motion_turnright": {
193
+ "opcode": "motion_turnright", "next": None, "parent": None,
194
+ "inputs": {"DEGREES": [1, [4, "15"]]}, "fields": {}, "shadow": False, "topLevel": True, "x": 467, "y": -316
195
+ },
196
+ "motion_ifonedgebounce": {
197
+ "opcode": "motion_ifonedgebounce", "next": None, "parent": None,
198
+ "inputs": {}, "fields": {}, "shadow": False, "topLevel": True, "x": 467, "y": -316
199
+ },
200
+ "event_whenflagclicked": {
201
+ "opcode": "event_whenflagclicked", "next": None, "parent": None,
202
+ "inputs": {}, "fields": {}, "shadow": False, "topLevel": True, "x": 10, "y": 10
203
+ },
204
+ "event_whenkeypressed": {
205
+ "opcode": "event_whenkeypressed", "next": None, "parent": None,
206
+ "inputs": {}, "fields": {"KEY_OPTION": ["space", None]}, "shadow": False, "topLevel": True, "x": 10, "y": 10
207
+ },
208
+ "control_forever": {
209
+ "opcode": "control_forever", "next": None, "parent": None,
210
+ "inputs": {"SUBSTACK": [2, "some_id"]}, "fields": {}, "shadow": False, "topLevel": True, "x": 10, "y": 10
211
+ },
212
+ "control_if": {
213
+ "opcode": "control_if", "next": None, "parent": None,
214
+ "inputs": {"CONDITION": [2, "some_id"], "SUBSTACK": [2, "some_id_2"]}, "fields": {}, "shadow": False, "topLevel": True, "x": 10, "y": 10
215
+ },
216
+ "looks_sayforsecs": {
217
+ "opcode": "looks_sayforsecs", "next": None, "parent": None,
218
+ "inputs": {"MESSAGE": [1, [10, "Hello!"]], "SECS": [1, [4, "2"]]}, "fields": {}, "shadow": False, "topLevel": True, "x": 10, "y": 10
219
+ },
220
+ "looks_say": {
221
+ "opcode": "looks_say", "next": None, "parent": None,
222
+ "inputs": {"MESSAGE": [1, [10, "Hello!"]]}, "fields": {}, "shadow": False, "topLevel": True, "x": 10, "y": 10
223
+ },
224
+ "sensing_touchingobject": {
225
+ "opcode": "sensing_touchingobject", "next": None, "parent": None,
226
+ "inputs": {"TOUCHINGOBJECTMENU": [1, "some_id"]}, "fields": {}, "shadow": False, "topLevel": True, "x": 10, "y": 10
227
+ },
228
+ "sensing_touchingobjectmenu": {
229
+ "opcode": "sensing_touchingobjectmenu", "next": None, "parent": None,
230
+ "inputs": {}, "fields": {"TOUCHINGOBJECTMENU": ["_mouse_", None]}, "shadow": True, "topLevel": True, "x": 10, "y": 10
231
+ },
232
+ # Add more blocks from your block_content.json here...
233
+ }
234
+
235
+ # --- Heuristic-based block selection ---
236
+ def get_relevant_blocks_for_plan(action_plan: Dict[str, Any], all_blocks_catalog: Dict[str, Any]) -> Dict[str, Any]:
237
+ """
238
+ Analyzes the natural language action plan and selects relevant Scratch blocks
239
+ from the comprehensive catalog. This is a heuristic approach and might need
240
+ to be refined based on your specific use cases and LLM capabilities.
241
+ """
242
+ relevant_opcodes = set()
243
+
244
+ # Always include common event blocks
245
+ relevant_opcodes.add("event_whenflagclicked")
246
+ relevant_opcodes.add("event_whenkeypressed") # Could be more specific if key is mentioned
247
+
248
+ # Keyword to opcode mapping (can be expanded)
249
+ keyword_map = {
250
+ "move": "motion_movesteps",
251
+ "steps": "motion_movesteps",
252
+ "turn": "motion_turnright",
253
+ "rotate": "motion_turnright",
254
+ "bounce": "motion_ifonedgebounce",
255
+ "edge": "motion_ifonedgebounce",
256
+ "forever": "control_forever",
257
+ "loop": "control_forever",
258
+ "if": "control_if",
259
+ "condition": "control_if",
260
+ "say": "looks_say",
261
+ "hello": "looks_say", # Simple example, might need more context
262
+ "touching": "sensing_touchingobject",
263
+ "mouse pointer": "sensing_touchingobjectmenu",
264
+ "edge": "sensing_touchingobjectmenu", # For touching edge
265
+ }
266
+
267
+ # Iterate through the action plan to find keywords
268
+ for sprite_name, sprite_actions in action_plan.get("action_overall_flow", {}).items():
269
+ for plan in sprite_actions.get("plans", []):
270
+ event_logic = plan.get("event", "").lower() + " " + plan.get("logic", "").lower()
271
+
272
+ # Check for direct opcode matches (if the LLM somehow outputs opcodes in its plan)
273
+ for opcode in all_blocks_catalog.keys():
274
+ if opcode in event_logic:
275
+ relevant_opcodes.add(opcode)
276
+
277
+ # Check for keywords
278
+ for keyword, opcode in keyword_map.items():
279
+ if keyword in event_logic:
280
+ relevant_opcodes.add(opcode)
281
+ # Add associated shadow blocks if known
282
+ if opcode == "sensing_touchingobject":
283
+ relevant_opcodes.add("sensing_touchingobjectmenu")
284
+ if opcode == "event_whenkeypressed":
285
+ relevant_opcodes.add("event_whenkeypressed") # It's already there but good to be explicit
286
+
287
+ # Construct the filtered catalog
288
+ relevant_blocks_catalog = {
289
+ opcode: all_blocks_catalog[opcode]
290
+ for opcode in relevant_opcodes if opcode in all_blocks_catalog
291
+ }
292
+ return relevant_blocks_catalog
293
+
294
+ # --- New Action Planning Node ---
295
+ def plan_sprite_actions(state: GameState):
296
+ logger.info("--- Running PlanSpriteActionsNode ---")
297
+
298
+ planning_prompt = (
299
+ f"You are an AI assistant tasked with planning Scratch 3.0 block code for a game. "
300
+ f"The game description is: '{state['description']}'.\n\n"
301
+ f"Here are the sprites currently in the project: {', '.join(target['name'] for target in state['project_json']['targets'] if not target['isStage']) if len(state['project_json']['targets']) > 1 else 'None'}.\n"
302
+ f"Initial positions: {json.dumps(state.get('sprite_initial_positions', {}), indent=2)}\n\n"
303
+ f"Consider the main actions and interactions required for each sprite. "
304
+ f"Think step-by-step about what each sprite needs to *do*, *when* it needs to do it (events), "
305
+ f"and if any actions need to *repeat* or depend on *conditions*.\n\n"
306
+ f"Propose a high-level action flow for each sprite in the following JSON format. "
307
+ f"Do NOT generate Scratch block JSON yet. Only describe the logic using natural language or simplified pseudo-code.\n\n"
308
+ f"Example format:\n"
309
+ f"```json\n"
310
+ f"{{\n"
311
+ f" \"action_overall_flow\": {{\n"
312
+ f" \"Sprite1\": {{\n"
313
+ f" \"description\": \"Main character actions\",\n"
314
+ f" \"plans\": [\n"
315
+ f" {{\n"
316
+ f" \"event\": \"when flag clicked\",\n"
317
+ f" \"logic\": \"forever loop: move 10 steps, if on edge bounce\"\n"
318
+ f" }},\n"
319
+ f" {{\n"
320
+ f" \"event\": \"when space key pressed\",\n"
321
+ f" \"logic\": \"change y by 10, wait 0.1 seconds, change y by -10\"\n"
322
+ f" }}\n"
323
+ f" ]\n"
324
+ f" }},\n"
325
+ f" \"Ball\": {{\n"
326
+ f" \"description\": \"Projectile movement\",\n"
327
+ f" \"plans\": [\n"
328
+ f" {{\n"
329
+ f" \"event\": \"when I start as a clone\",\n"
330
+ f" \"logic\": \"glide 1 sec to random position, if touching Sprite1 then stop this script\"\n"
331
+ f" }}\n"
332
+ f" ]\n"
333
+ f" }}\n"
334
+ f" }}\n"
335
+ f"}}\n"
336
+ f"```\n\n"
337
+ f"Return ONLY the JSON object for the action overall flow."
338
+ )
339
+
340
+ try:
341
+ response = agent.invoke({"messages": [{"role": "user", "content": planning_prompt}]})
342
+ raw_response = response["messages"][-1].content
343
+ print("Raw response from LLM [PlanSpriteActionsNode]:", raw_response)
344
+ action_plan = extract_json_from_llm_response(raw_response)
345
+ logger.info("Sprite action plan generated by PlanSpriteActionsNode.")
346
+ return {"action_plan": action_plan}
347
+ except Exception as e:
348
+ logger.error(f"Error in PlanSpriteActionsNode: {e}")
349
+ raise
350
+
351
+ # --- Updated Action Node Builder (to consume the plan and build blocks) ---
352
+ def build_action_nodes(state: GameState):
353
+ logger.info("--- Running ActionNodeBuilder ---")
354
+
355
+ action_plan = state.get("action_plan", {})
356
+ if not action_plan:
357
+ raise ValueError("No action plan found in state. Run PlanSpriteActionsNode first.")
358
+
359
+ # Convert the Scratch project JSON to a mutable Python object
360
+ project_json = state["project_json"]
361
+ targets = project_json["targets"]
362
+
363
+ # We need a way to map sprite names to their actual target objects in project_json
364
+ sprite_map = {target["name"]: target for target in targets if not target["isStage"]}
365
+
366
+ # --- NEW: Get only the relevant blocks for the entire action plan ---
367
+ relevant_scratch_blocks_catalog = get_relevant_blocks_for_plan(action_plan, ALL_SCRATCH_BLOCKS_CATALOG)
368
+ logger.info(f"Filtered {len(relevant_scratch_blocks_catalog)} relevant blocks out of {len(ALL_SCRATCH_BLOCKS_CATALOG)} total.")
369
+
370
+
371
+ # Iterate through the planned actions for each sprite
372
+ for sprite_name, sprite_actions in action_plan.get("action_overall_flow", {}).items():
373
+ if sprite_name in sprite_map:
374
+ current_sprite_target = sprite_map[sprite_name]
375
+ # Ensure 'blocks' field exists for the sprite
376
+ if "blocks" not in current_sprite_target:
377
+ current_sprite_target["blocks"] = {}
378
+
379
+ # Generate block JSON based on the detailed action plan for this sprite
380
+ # This is where the LLM's role becomes crucial: translating logic to blocks
381
+ llm_block_generation_prompt = (
382
+ f"You are an AI assistant generating Scratch 3.0 block JSON based on a provided plan. "
383
+ f"The current sprite is '{sprite_name}'.\n"
384
+ f"Its planned actions are:\n"
385
+ f"```json\n{json.dumps(sprite_actions, indent=2)}\n```\n\n"
386
+ f"Here is a **curated catalog of only the most relevant Scratch 3.0 blocks** for this plan:\n"
387
+ f"```json\n{json.dumps(relevant_scratch_blocks_catalog, indent=2)}\n```\n\n"
388
+ f"Current Scratch project JSON (for context, specifically this sprite's existing blocks if any):\n"
389
+ f"```json\n{json.dumps(current_sprite_target, indent=2)}\n```\n\n"
390
+ f"**Instructions:**\n"
391
+ f"1. For each planned event and its associated logic, generate the corresponding Scratch 3.0 block JSON.\n"
392
+ f"2. **Generate unique block IDs** for every new block. Use a format like 'block_id_abcdef12'.\n" # Updated ID format hint
393
+ f"3. Properly link blocks using `next` and `parent` fields to form execution stacks. Hat blocks (`topLevel: true`, `parent: null`).\n"
394
+ f"4. Correctly fill `inputs` and `fields` based on the catalog and the plan's logic (e.g., specific values for motion, keys for events, conditions for controls).\n"
395
+ f"5. For C-blocks (like `control_repeat`, `control_forever`, `control_if`), use the `SUBSTACK` input to link to the first block inside its loop/conditional.\n"
396
+ f"6. If the plan involves operators (e.g., 'if touching Sprite1'), use the appropriate operator blocks from the catalog and link them correctly as `CONDITION` inputs.\n"
397
+ f"7. Ensure that any shadow blocks (e.g., for dropdowns like `motion_goto_menu`, `sensing_touchingobjectmenu`) are generated with `shadow: true` and linked correctly as inputs to their parent block.\n"
398
+ f"8. Return ONLY the **updated 'blocks' dictionary** for this specific sprite. Do NOT return the full project JSON. ONLY the `blocks` dictionary."
399
+ )
400
+
401
+ try:
402
+ response = agent.invoke({"messages": [{"role": "user", "content": llm_block_generation_prompt}]})
403
+ raw_response = response["messages"][-1].content
404
+ print(f"Raw response from LLM [ActionNodeBuilder - {sprite_name}]:", raw_response)
405
+ generated_blocks = extract_json_from_llm_response(raw_response)
406
+ current_sprite_target["blocks"].update(generated_blocks) # Merge new blocks
407
+ logger.info(f"Action blocks added for sprite '{sprite_name}' by ActionNodeBuilder.")
408
+ except Exception as e:
409
+ logger.error(f"Error generating blocks for sprite '{sprite_name}': {e}")
410
+ # Depending on robustness needed, you might continue or re-raise
411
+ raise
412
+
413
+ return {"project_json": project_json}
414
+
415
+ # --- Example Usage (to demonstrate the flow) ---
416
+ if __name__ == "__main__":
417
+ # Initialize a mock game state
418
+ initial_game_state = {
419
+ "description": "A simple game where a sprite moves and says hello.",
420
+ "project_json": {
421
+ "targets": [
422
+ {"isStage": True, "name": "Stage", "blocks": {}},
423
+ {"isStage": False, "name": "Sprite1", "blocks": {}},
424
+ {"isStage": False, "name": "Ball", "blocks": {}}
425
+ ]
426
+ },
427
+ "sprite_initial_positions": {}
428
+ }
429
+
430
+ # Step 1: Plan Sprite Actions
431
+ try:
432
+ state_after_planning = plan_sprite_actions(initial_game_state)
433
+ initial_game_state.update(state_after_planning)
434
+ print("\n--- Game State After Planning ---")
435
+ print(json.dumps(initial_game_state, indent=2))
436
+ except Exception as e:
437
+ print(f"Planning failed: {e}")
438
+ exit()
439
+
440
+ # Step 2: Build Action Nodes (Generate Blocks)
441
+ try:
442
+ state_after_building = build_action_nodes(initial_game_state)
443
+ initial_game_state.update(state_after_building)
444
+ print("\n--- Game State After Building Blocks ---")
445
+ # Print only the blocks for a specific sprite to keep output manageable
446
+ for target in initial_game_state["project_json"]["targets"]:
447
+ if not target["isStage"]:
448
+ print(f"\nBlocks for {target['name']}:")
449
+ print(json.dumps(target.get('blocks', {}), indent=2))
450
+
451
+ except Exception as e:
452
+ print(f"Building blocks failed: {e}")
v2/scratch_agent/agent.py ADDED
@@ -0,0 +1,1647 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #─── Basic imports ─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
2
+ import os
3
+ import math
4
+ import sqlite3
5
+ import fitz # PyMuPDF for PDF parsing
6
+ import re
7
+
8
+ from dotenv import load_dotenv
9
+ # Load environment variables from .env file
10
+ load_dotenv() # This line ensures .env variables are loaded
11
+
12
+ from langgraph.graph import START, StateGraph, MessagesState, END
13
+ from langgraph.prebuilt import tools_condition
14
+ from langgraph.prebuilt import ToolNode
15
+ from langgraph.constants import START
16
+ from langchain_core.tools import tool
17
+ from langchain.schema import SystemMessage
18
+ #from langchain.chat_models import init_chat_model
19
+ #from langgraph.prebuilt import create_react_agent
20
+
21
+ from langchain.embeddings import HuggingFaceEmbeddings
22
+ #from langchain.vectorstores import Pinecone
23
+ from langchain.tools.retriever import create_retriever_tool
24
+ #import pinecone
25
+ #from pinecone import Pinecone as PineconeClient, ServerlessSpec
26
+ #from pinecone import Index # the blocking‐call client constructor
27
+ #from pinecone import Pinecone as PineconeClient, ServerlessSpec
28
+ from langchain.embeddings import HuggingFaceEmbeddings
29
+ from langchain_community.vectorstores.pinecone import Pinecone as LC_Pinecone
30
+
31
+ # ─── Langchain Frameworks ─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
32
+ #from langchain.tools import Tool
33
+ from langchain.chat_models import ChatOpenAI
34
+ from langchain_groq import ChatGroq
35
+ from langchain_mistralai import ChatMistralAI
36
+ from langchain.agents import initialize_agent, AgentType
37
+ from langchain.schema import Document
38
+ from langchain.chains import RetrievalQA
39
+ from langchain.embeddings import OpenAIEmbeddings
40
+ from langchain_community.embeddings import HuggingFaceEmbeddings
41
+ from langchain.vectorstores import FAISS
42
+ from langchain.text_splitter import RecursiveCharacterTextSplitter
43
+ from langchain.prompts import PromptTemplate
44
+ from langchain_community.document_loaders import TextLoader, PyMuPDFLoader
45
+ from langchain_community.document_loaders.wikipedia import WikipediaLoader
46
+ from langchain_community.document_loaders.arxiv import ArxivLoader
47
+ from langchain_experimental.tools.python.tool import PythonREPLTool
48
+
49
+
50
+ # ─── Memory ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
51
+ from langchain.agents import initialize_agent, AgentType
52
+ from langchain.tools import Tool
53
+ from typing import List, Callable
54
+ from langchain.schema import BaseMemory, AIMessage, HumanMessage, SystemMessage
55
+ from langchain.schema import HumanMessage, SystemMessage
56
+ from langchain.llms.base import LLM
57
+ from langchain.memory.chat_memory import BaseChatMemory
58
+ from pydantic import PrivateAttr
59
+ from langchain_core.messages import get_buffer_string
60
+
61
+ # ─── Image Processing ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
62
+
63
+ from PIL import Image
64
+ import pytesseract
65
+ from transformers import pipeline
66
+ from groq import Groq
67
+ import requests
68
+ from io import BytesIO
69
+ from transformers import pipeline, TrOCRProcessor, VisionEncoderDecoderModel
70
+ import requests
71
+ import base64
72
+ from PIL import UnidentifiedImageError
73
+
74
+ # ─── Browser var ─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
75
+ from typing import List, Dict
76
+ import json
77
+ from io import BytesIO
78
+ #from langchain.tools import tool # or langchain_core.tools
79
+ from playwright.sync_api import sync_playwright
80
+ from duckduckgo_search import DDGS
81
+ import time
82
+ import random
83
+ import logging
84
+ from functools import lru_cache, wraps
85
+ import requests
86
+ from playwright.sync_api import sync_playwright
87
+ from bs4 import BeautifulSoup
88
+ import tenacity
89
+ from tenacity import retry, stop_after_attempt, wait_exponential
90
+
91
+ # Initialize logger
92
+ logger = logging.getLogger(__name__)
93
+ logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
94
+
95
+ # Additional imports for new functionality
96
+ import pandas as pd
97
+ from PyPDF2 import PdfReader
98
+ import docx
99
+ import pytesseract
100
+ import speech_recognition as sr
101
+ from pydub import AudioSegment
102
+ from pytube import YouTube
103
+ from newspaper import Article
104
+ from langchain.document_loaders import ArxivLoader
105
+ from langchain_community.document_loaders.youtube import YoutubeLoader, TranscriptFormat
106
+
107
+ from playwright.sync_api import sync_playwright
108
+ # Attempt to import Playwright for dynamic page rendering
109
+ try:
110
+ from playwright.sync_api import sync_playwright
111
+ _playwright_available = True
112
+ except ImportError:
113
+ _playwright_available = False
114
+
115
+ # Define forbidden keywords for basic NSFW filtering
116
+ _forbidden = ["porn", "sex", "xxx", "nude", "erotic"]
117
+
118
+ # ─── LLM Setup ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
119
+ # Load OpenAI API key from environment (required for LLM and embeddings)
120
+
121
+ # API Keys from .env file
122
+ os.environ.setdefault("OPENAI_API_KEY", "<YOUR_OPENAI_KEY>") # Set your own key or env var
123
+ os.environ["GROQ_API_KEY"] = os.getenv("GROQ_API_KEY", "default_key_or_placeholder")
124
+ os.environ["MISTRAL_API_KEY"] = os.getenv("MISTRAL_API_KEY", "default_key_or_placeholder")
125
+
126
+ # Tavily API Key
127
+ TAVILY_API_KEY = os.getenv("TAVILY_API_KEY", "default_key_or_placeholder")
128
+ _forbidden = ["nsfw", "porn", "sex", "explicit"]
129
+ _playwright_available = True # set False to disable Playwright
130
+
131
+ # Globals for RAG system
132
+ vector_store = None
133
+ rag_chain = None
134
+ DB_PATH = None # will be set when a .db is uploaded
135
+ DOC_PATH = None # will be set when a document is uploaded
136
+ IMG_PATH = None # will be set when an image is uploaded
137
+ OTH_PATH = None # will be set when an other file is uploaded
138
+
139
+
140
+ # ─── LLMS ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
141
+ #llm = ChatOpenAI(model_name="gpt-3.5-turbo", streaming=True, temperature=0)
142
+ from tenacity import retry, stop_after_attempt, wait_exponential
143
+
144
+ # Import the RetryingChatGroq client
145
+ from retry_groq import RetryingChatGroq
146
+
147
+ # Use the retrying version instead
148
+ llm = RetryingChatGroq(model="deepseek-r1-distill-llama-70b", streaming=False, temperature=0)
149
+ #llm = ChatMistralAI(model="mistral-large-latest", streaming=True, temperature=0)
150
+
151
+ # ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
152
+ # ─────────────────────────────────────────────── Tool for multiply ──────────────────────────────────────────────────────────────────────
153
+ # ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
154
+ @tool(parse_docstring=True)
155
+ def multiply(a: int, b: int) -> int:
156
+ """
157
+ Multiply two numbers.
158
+
159
+ Args:
160
+ a (int): The first factor.
161
+ b (int): The second factor.
162
+
163
+ Returns:
164
+ int: The product of a and b.
165
+ """
166
+ try:
167
+ # Direct calculation without relying on LangChain handling
168
+ result = a * b
169
+ return result
170
+ except Exception as e:
171
+ return f"Error in multiplication: {str(e)}"
172
+
173
+ # ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
174
+ # ─────────────────────────────────────────────── Tool for add ──────────────────────────────────────────────────────────────────────────
175
+ # ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
176
+ @tool(parse_docstring=True)
177
+ def add(a: int, b: int) -> int:
178
+ """
179
+ Add two numbers.
180
+
181
+ Args:
182
+ a (int): The first factor.
183
+ b (int): The second factor.
184
+
185
+ Returns:
186
+ int: The addition of a and b.
187
+ """
188
+ try:
189
+ # Direct calculation without relying on LangChain handling
190
+ result = a + b
191
+ return result
192
+ except Exception as e:
193
+ return f"Error in addition: {str(e)}"
194
+
195
+ # ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
196
+ # ─────────────────────────────────────────────── Tool for subtract ──────────────────────────────────────────────────────────────────────
197
+ # ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
198
+ @tool(parse_docstring=True)
199
+ def subtract(a: int, b: int) -> int:
200
+ """
201
+ Subtract two numbers.
202
+
203
+ Args:
204
+ a (int): The first factor.
205
+ b (int): The second factor.
206
+
207
+ Returns:
208
+ int: The subtraction of a and b.
209
+ """
210
+ try:
211
+ # Direct calculation without relying on LangChain handling
212
+ result = a - b
213
+ return result
214
+ except Exception as e:
215
+ return f"Error in subtraction: {str(e)}"
216
+
217
+ # ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
218
+ # ─────────────────────────────────────────────── Tool for divide ──────────────────────────────────────────────────────────────────────
219
+ # ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
220
+ @tool(parse_docstring=True)
221
+ def divide(a: int, b: int) -> int:
222
+ """
223
+ Divide two numbers.
224
+
225
+ Args:
226
+ a (int): The numerator.
227
+ b (int): The denominator.
228
+
229
+ Returns:
230
+ float: The result of a divided by b.
231
+
232
+ Raises:
233
+ ValueError: If b is zero.
234
+ """
235
+ try:
236
+ if b == 0:
237
+ return "Error: Cannot divide by zero."
238
+ # Direct calculation without relying on LangChain handling
239
+ result = a / b
240
+ return result
241
+ except Exception as e:
242
+ return f"Error in division: {str(e)}"
243
+
244
+ # ──────────────────────────────────────────────────────────────────────────────────────────────────���───────────────────────────────────────
245
+ # ─────────────────────────────────────────────── Tool for modulus ──────────────────────────────────────────────────────────────────────
246
+ # ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
247
+ @tool(parse_docstring=True)
248
+ def modulus(a: int, b: int) -> int:
249
+ """
250
+ Get the modulus (remainder) of two numbers.
251
+
252
+ Args:
253
+ a (int): The dividend.
254
+ b (int): The divisor.
255
+
256
+ Returns:
257
+ int: The remainder when a is divided by b.
258
+ """
259
+ try:
260
+ if b == 0:
261
+ return "Error: Cannot calculate modulus with zero divisor."
262
+ # Direct calculation without relying on LangChain handling
263
+ result = a % b
264
+ return result
265
+ except Exception as e:
266
+ return f"Error in modulus calculation: {str(e)}"
267
+
268
+ # ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
269
+ # ─────────────────────────────────────────────── Tool for browsing ──────────────────────────────────────────────────────────────────────
270
+ # ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
271
+ def with_retry(max_attempts: int = 3, backoff_base: int = 2):
272
+ """
273
+ Decorator for retrying a function with exponential backoff on exception.
274
+ """
275
+ def decorator(fn):
276
+ @wraps(fn)
277
+ def wrapper(*args, **kwargs):
278
+ for attempt in range(max_attempts):
279
+ try:
280
+ return fn(*args, **kwargs)
281
+ except Exception as e:
282
+ wait = backoff_base ** attempt + random.uniform(0, 1)
283
+ logger.warning(f"{fn.__name__} failed (attempt {attempt+1}/{max_attempts}): {e}")
284
+ if attempt < max_attempts - 1:
285
+ time.sleep(wait)
286
+ logger.error(f"{fn.__name__} failed after {max_attempts} attempts.")
287
+ return []
288
+ return wrapper
289
+ return decorator
290
+
291
+ @with_retry()
292
+ @lru_cache(maxsize=128)
293
+ def tavily_search(query: str, top_k: int = 3) -> List[Dict]:
294
+ """Call Tavily API and return a list of result dicts."""
295
+ if not TAVILY_API_KEY:
296
+ logger.info("[Tavily] No API key set. Skipping Tavily search.")
297
+ return []
298
+ url = "https://api.tavily.com/search"
299
+ headers = {
300
+ "Authorization": f"Bearer {TAVILY_API_KEY}",
301
+ "Content-Type": "application/json",
302
+ }
303
+ payload = {"query": query, "num_results": top_k}
304
+ resp = requests.post(url, headers=headers, json=payload, timeout=10)
305
+ resp.raise_for_status()
306
+ data = resp.json()
307
+ results = []
308
+ for item in data.get("results", []):
309
+ results.append({
310
+ "title": item.get("title", ""),
311
+ "url": item.get("url", ""),
312
+ "content": item.get("content", "")[:200],
313
+ "source": "Tavily"
314
+ })
315
+ return results
316
+
317
+ @with_retry()
318
+ @lru_cache(maxsize=128)
319
+ def duckduckgo_search(query: str, top_k: int = 3) -> List[Dict]:
320
+ """Query DuckDuckGo and return up to top_k raw SERP hits."""
321
+ results = []
322
+ try:
323
+ with DDGS(timeout=15) as ddgs: # Increase timeout from default
324
+ for hit in ddgs.text(query, safesearch="On", max_results=top_k, timeout=15):
325
+ results.append({
326
+ "title": hit.get("title", ""),
327
+ "url": hit.get("href") or hit.get("url", ""),
328
+ "content": hit.get("body", ""),
329
+ "source": "DuckDuckGo"
330
+ })
331
+ if len(results) >= top_k:
332
+ break
333
+ except Exception as e:
334
+ logger.warning(f"DuckDuckGo search failed: {e}")
335
+ # Don't re-raise - just return empty results to allow fallbacks to work
336
+
337
+ return results
338
+
339
+ # Additional fallback search alternative
340
+ def simple_google_search(query: str, top_k: int = 3) -> List[Dict]:
341
+ """Simplified Google search as a fallback when other methods fail."""
342
+ try:
343
+ # Encode the query
344
+ import urllib.parse
345
+ import bs4
346
+
347
+ encoded_query = urllib.parse.quote(query)
348
+ url = f"https://www.google.com/search?q={encoded_query}"
349
+
350
+ headers = {
351
+ "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36",
352
+ "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
353
+ "Accept-Language": "en-US,en;q=0.5",
354
+ "Referer": "https://www.google.com/",
355
+ "Connection": "keep-alive",
356
+ }
357
+
358
+ response = requests.get(url, headers=headers, timeout=20)
359
+ response.raise_for_status()
360
+
361
+ soup = bs4.BeautifulSoup(response.text, "html.parser")
362
+ results = []
363
+
364
+ # Extract search results
365
+ for result in soup.select("div.g")[:top_k]:
366
+ title_elem = result.select_one("h3")
367
+ link_elem = result.select_one("a")
368
+ snippet_elem = result.select_one("div.VwiC3b")
369
+
370
+ if title_elem and link_elem and snippet_elem and "href" in link_elem.attrs:
371
+ href = link_elem["href"]
372
+ if href.startswith("/url?q="):
373
+ href = href.split("/url?q=")[1].split("&")[0]
374
+
375
+ if href.startswith("http"):
376
+ results.append({
377
+ "title": title_elem.get_text(),
378
+ "url": href,
379
+ "content": snippet_elem.get_text(),
380
+ "source": "Google"
381
+ })
382
+
383
+ return results
384
+
385
+ except Exception as e:
386
+ logger.warning(f"Simple Google search failed: {e}")
387
+ return []
388
+
389
+ def hybrid_search(query: str, top_k: int = 3) -> List[Dict]:
390
+ """Combine multiple search sources with fallbacks."""
391
+ # Try primary search methods first
392
+ results = []
393
+
394
+ # Start with Tavily if API key is available
395
+ if TAVILY_API_KEY and TAVILY_API_KEY != "default_key_or_placeholder":
396
+ try:
397
+ tavily_results = tavily_search(query, top_k)
398
+ results.extend(tavily_results)
399
+ logger.info(f"Retrieved {len(tavily_results)} results from Tavily")
400
+ except Exception as e:
401
+ logger.warning(f"Tavily search failed: {e}")
402
+
403
+ # If we don't have enough results, try DuckDuckGo
404
+ if len(results) < top_k:
405
+ try:
406
+ ddg_results = duckduckgo_search(query, top_k - len(results))
407
+ results.extend(ddg_results)
408
+ logger.info(f"Retrieved {len(ddg_results)} results from DuckDuckGo")
409
+ except Exception as e:
410
+ logger.warning(f"DuckDuckGo search failed: {e}")
411
+
412
+ # If we still don't have enough results, try Google
413
+ if len(results) < top_k:
414
+ try:
415
+ google_results = simple_google_search(query, top_k - len(results))
416
+ results.extend(google_results)
417
+ logger.info(f"Retrieved {len(google_results)} results from Google")
418
+ except Exception as e:
419
+ logger.warning(f"Google search failed: {e}")
420
+
421
+ # If all search methods failed, return a dummy result
422
+ if not results:
423
+ results.append({
424
+ "title": "Search Failed",
425
+ "url": "",
426
+ "content": f"Sorry, I couldn't find results for '{query}'. Please try refining your search terms or check your internet connection.",
427
+ "source": "No results"
428
+ })
429
+
430
+ return results[:top_k] # Ensure we only return top_k results
431
+
432
+ def format_search_docs(search_docs: List[Dict]) -> Dict[str, str]:
433
+ """
434
+ Turn a list of {source, page, content} dicts into one big
435
+ string with <Document ...>…</Document> entries separated by `---`.
436
+ """
437
+ formatted_search_docs = "\n\n---\n\n".join(
438
+ [
439
+ f'<Document source="{doc["source"]}" page="{doc.get("page", "")}"/>\n'
440
+ f'{doc.get("content", "")}\n'
441
+ f'</Document>'
442
+ for doc in search_docs
443
+ ]
444
+ )
445
+ return {"web_results": formatted_search_docs}
446
+
447
+
448
+ @tool(parse_docstring=True)
449
+ def web_search(query: str, top_k: int = 3) -> Dict[str, str]:
450
+ """
451
+ Perform a hybrid web search combining multiple search engines with robust fallbacks.
452
+
453
+ Args:
454
+ query: The search query string to look up.
455
+ top_k: The maximum number of search results to return (default is 3).
456
+
457
+ Returns:
458
+ A dictionary mapping result indices to XML-like <Document> blocks, each containing:
459
+ - source: The URL of the webpage.
460
+ - page: Placeholder for page identifier (empty string by default).
461
+ - content: The first 200 words of the page text, cleaned of HTML tags.
462
+ """
463
+ try:
464
+ # Use our robust hybrid search to get initial results
465
+ search_results = hybrid_search(query, top_k)
466
+ results = []
467
+
468
+ # Process each search result to get better content
469
+ for hit in search_results:
470
+ url = hit.get("url")
471
+ if not url:
472
+ continue
473
+
474
+ # Start with the snippet from search
475
+ content = hit.get("content", "")
476
+ title = hit.get("title", "")
477
+
478
+ # Try to scrape additional content if possible
479
+ try:
480
+ # Use a random user agent to avoid blocking
481
+ headers = {
482
+ "User-Agent": random.choice([
483
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36",
484
+ "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.0 Safari/605.1.15",
485
+ "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Safari/537.36",
486
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36 Edg/97.0.1072.62"
487
+ ]),
488
+ "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
489
+ "Accept-Language": "en-US,en;q=0.5",
490
+ "Referer": "https://www.google.com/",
491
+ "DNT": "1",
492
+ "Connection": "keep-alive"
493
+ }
494
+
495
+ # Higher timeout for better reliability
496
+ resp = requests.get(url, timeout=15, headers=headers)
497
+
498
+ # Only process if successful
499
+ if resp.status_code == 200:
500
+ soup = BeautifulSoup(resp.text, "html.parser")
501
+
502
+ # Try to find main content
503
+ main_content = soup.find('main') or soup.find('article') or soup.find('div', class_='content')
504
+
505
+ # If we found main content, use it
506
+ if main_content:
507
+ extracted_text = main_content.get_text(separator=" ", strip=True)
508
+ # Take first 200 words
509
+ content = " ".join(extracted_text.split()[:200])
510
+ else:
511
+ # Otherwise use all text
512
+ all_text = soup.get_text(separator=" ", strip=True)
513
+ content = " ".join(all_text.split()[:200])
514
+
515
+ # Use content from page only if it's substantial
516
+ if len(content) < 50:
517
+ content = hit.get("content", "")[:200]
518
+
519
+ # Random delay between 0.5-1.5 seconds to avoid rate limits
520
+ time.sleep(0.5 + random.random())
521
+
522
+ except requests.exceptions.HTTPError as e:
523
+ logger.warning(f"HTTP error when scraping {url}: {e}")
524
+ # Keep the search snippet as a fallback
525
+ except requests.exceptions.RequestException as e:
526
+ logger.warning(f"Request error when scraping {url}: {e}")
527
+ # Keep the search snippet as a fallback
528
+ except Exception as e:
529
+ logger.warning(f"Unexpected error when scraping {url}: {e}")
530
+ # Keep the search snippet as a fallback
531
+
532
+ # Filter out inappropriate content
533
+ if any(f in content.lower() for f in _forbidden):
534
+ continue
535
+
536
+ # Add to results
537
+ results.append({
538
+ "source": url,
539
+ "page": "",
540
+ "content": content
541
+ })
542
+
543
+ # Return formatted search docs
544
+ return format_search_docs(results[:top_k])
545
+ except Exception as e:
546
+ logger.error(f"Web search failed: {e}")
547
+ # Return a helpful error message
548
+ return format_search_docs([{
549
+ "source": "Error",
550
+ "page": "",
551
+ "content": f"Search failed with error: {e}. Please try again with different search terms."
552
+ }])
553
+
554
+ # ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
555
+ # ─────────────────────────────────────────────── Tool for File System ───────────────────────────────────────────────────────────────────
556
+ # ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
557
+ @tool(parse_docstring=True)
558
+ def download_file(url: str, dest_path: str) -> str:
559
+ """
560
+ Download a file from a given URL and save it locally.
561
+
562
+ Args:
563
+ url: The direct URL of the file to download.
564
+ dest_path: The local path to save the downloaded file.
565
+
566
+ Returns:
567
+ The destination path where the file was saved.
568
+ """
569
+ r = requests.get(url, stream=True)
570
+ r.raise_for_status()
571
+ with open(dest_path, 'wb') as f:
572
+ for chunk in r.iter_content(8192):
573
+ f.write(chunk)
574
+ return dest_path
575
+
576
+ @tool(parse_docstring=True)
577
+ def process_excel_to_text(file_path: str) -> str:
578
+ """
579
+ Convert an Excel file into CSV-formatted text.
580
+
581
+ Args:
582
+ file_path: Path to the Excel (.xlsx) file.
583
+
584
+ Returns:
585
+ A string of CSV-formatted content extracted from the Excel file.
586
+ """
587
+ try:
588
+ # Check if file exists
589
+ import os
590
+ if not os.path.exists(file_path):
591
+ return f"Error: Excel file '{file_path}' does not exist."
592
+
593
+ # Try different engines
594
+ engines = ['openpyxl', 'xlrd', None]
595
+
596
+ for engine in engines:
597
+ try:
598
+ # For engine=None, pandas will try to auto-detect
599
+ if engine:
600
+ df = pd.read_excel(file_path, engine=engine)
601
+ else:
602
+ df = pd.read_excel(file_path)
603
+ return df.to_csv(index=False)
604
+ except Exception as e:
605
+ print(f"Excel engine {engine} failed: {e}")
606
+ last_error = e
607
+ continue
608
+
609
+ # If we got here, all engines failed
610
+ return f"Error processing Excel file: {str(last_error)}"
611
+ except Exception as e:
612
+ return f"Error with Excel file: {str(e)}"
613
+
614
+ @tool(parse_docstring=True)
615
+ def read_text_from_pdf(file_path: str, question: str = None) -> str:
616
+ """
617
+ Extract text from a PDF file, chunking large documents if needed.
618
+
619
+ Args:
620
+ file_path: Path to the PDF file.
621
+ question: Optional question to help retrieve relevant parts of long documents.
622
+
623
+ Returns:
624
+ The extracted text content, potentially chunked if the document is large.
625
+ """
626
+ try:
627
+ # Check if file exists
628
+ import os
629
+ if not os.path.exists(file_path):
630
+ return f"Error: PDF file '{file_path}' does not exist."
631
+
632
+ reader = PdfReader(file_path)
633
+ full_text = "\n".join([page.extract_text() or "" for page in reader.pages])
634
+
635
+ # If a question is provided, use retrieval to get relevant parts
636
+ if question and len(full_text) > 5000: # Only chunk if text is large
637
+ return process_large_document(full_text, question)
638
+
639
+ return full_text
640
+ except Exception as e:
641
+ return f"Error reading PDF: {str(e)}"
642
+
643
+ @tool(parse_docstring=True)
644
+ def read_text_from_docx(file_path: str, question: str = None) -> str:
645
+ """
646
+ Extract text from a DOCX (Word) document, chunking large documents if needed.
647
+
648
+ Args:
649
+ file_path: Path to the DOCX file.
650
+ question: Optional question to help retrieve relevant parts of long documents.
651
+
652
+ Returns:
653
+ The extracted text, potentially chunked if the document is large.
654
+ """
655
+ try:
656
+ # Check if file exists
657
+ import os
658
+ if not os.path.exists(file_path):
659
+ return f"Error: File '{file_path}' does not exist."
660
+
661
+ try:
662
+ doc = docx.Document(file_path)
663
+ full_text = "\n".join([para.text for para in doc.paragraphs])
664
+ except Exception as docx_err:
665
+ # Handle "Package not found" error specifically
666
+ if "Package not found" in str(docx_err):
667
+ # Try to read raw text if possible
668
+ try:
669
+ import zipfile
670
+ from xml.etree.ElementTree import XML
671
+
672
+ WORD_NAMESPACE = '{http://schemas.openxmlformats.org/wordprocessingml/2006/main}'
673
+ PARA = WORD_NAMESPACE + 'p'
674
+ TEXT = WORD_NAMESPACE + 't'
675
+
676
+ with zipfile.ZipFile(file_path) as docx_file:
677
+ with docx_file.open('word/document.xml') as document:
678
+ tree = XML(document.read())
679
+ paragraphs = []
680
+ for paragraph in tree.iter(PARA):
681
+ texts = [node.text for node in paragraph.iter(TEXT) if node.text]
682
+ if texts:
683
+ paragraphs.append(''.join(texts))
684
+ full_text = '\n'.join(paragraphs)
685
+ except Exception as e:
686
+ return f"Error reading DOCX file: {str(e)}"
687
+ else:
688
+ return f"Error reading DOCX file: {str(docx_err)}"
689
+
690
+ # If a question is provided, use retrieval to get relevant parts
691
+ if question and len(full_text) > 5000: # Only chunk if text is large
692
+ return process_large_document(full_text, question)
693
+
694
+ return full_text
695
+ except Exception as e:
696
+ return f"Error reading DOCX file: {str(e)}"
697
+
698
+
699
+ @tool(parse_docstring=True)
700
+ def transcribe_audio(file_path: str) -> str:
701
+ """
702
+ Transcribe speech from a local audio file to text.
703
+
704
+ Args:
705
+ file_path: Path to the audio file.
706
+
707
+ Returns:
708
+ Transcribed text using Google Web Speech API.
709
+ """
710
+ try:
711
+ # Check if file exists
712
+ import os
713
+ if not os.path.exists(file_path):
714
+ return f"Error: Audio file '{file_path}' does not exist."
715
+
716
+ # For non-WAV files, convert to WAV first
717
+ if not file_path.lower().endswith('.wav'):
718
+ try:
719
+ from pydub import AudioSegment
720
+ temp_wav = os.path.splitext(file_path)[0] + "_temp.wav"
721
+ audio = AudioSegment.from_file(file_path)
722
+ audio.export(temp_wav, format="wav")
723
+ file_path = temp_wav
724
+ except Exception as e:
725
+ return f"Failed to convert audio to WAV format: {str(e)}"
726
+
727
+ recognizer = sr.Recognizer()
728
+ with sr.AudioFile(file_path) as src:
729
+ audio = recognizer.record(src)
730
+ return recognizer.recognize_google(audio)
731
+ except Exception as e:
732
+ if "Audio file could not be read" in str(e):
733
+ return f"Error: Audio format not supported. Try converting to WAV, MP3, OGG, or FLAC."
734
+ return f"Error transcribing audio: {str(e)}"
735
+
736
+ @tool(parse_docstring=True)
737
+ def youtube_audio_processing(youtube_url: str) -> str:
738
+ """
739
+ Download and transcribe audio from a YouTube video.
740
+
741
+ Args:
742
+ youtube_url: URL of the YouTube video.
743
+
744
+ Returns:
745
+ Transcription text extracted from the video's audio.
746
+ """
747
+ yt = YouTube(youtube_url)
748
+ audio_stream = yt.streams.filter(only_audio=True).first()
749
+ out_file = audio_stream.download(output_path='.', filename='yt_audio')
750
+ wav_path = 'yt_audio.wav'
751
+ AudioSegment.from_file(out_file).export(wav_path, format='wav')
752
+ return transcribe_audio(wav_path)
753
+
754
+ @tool(parse_docstring=True)
755
+ def extract_article_text(url: str, question: str = None) -> str:
756
+ """
757
+ Download and extract the main article content from a webpage, chunking large articles if needed.
758
+
759
+ Args:
760
+ url: The URL of the article to extract.
761
+ question: Optional question to help retrieve relevant parts of long articles.
762
+
763
+ Returns:
764
+ The article's textual content, potentially chunked if large.
765
+ """
766
+ try:
767
+ art = Article(url)
768
+ art.download()
769
+ art.parse()
770
+ full_text = art.text
771
+
772
+ # If a question is provided, use retrieval to get relevant parts
773
+ if question and len(full_text) > 5000: # Only chunk if text is large
774
+ return process_large_document(full_text, question)
775
+
776
+ return full_text
777
+ except Exception as e:
778
+ return f"Error extracting article: {str(e)}"
779
+
780
+ # ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
781
+ # ───────────────────────────────────────────────────────────── Tool for ArXiv ────────────────────────────────────────────────────────────
782
+ # ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
783
+
784
+ @tool(parse_docstring=True)
785
+ def arvix_search(query: str) -> Dict[str, str]:
786
+ """
787
+ Search for academic papers on ArXiv.
788
+
789
+ Args:
790
+ query: The search term to look for in ArXiv.
791
+
792
+ Returns:
793
+ A dictionary of up to 3 relevant paper entries in JSON format.
794
+ """
795
+ papers = ArxivLoader(query=query, load_max_docs=3).load()
796
+ results = []
797
+ for doc in papers:
798
+ try:
799
+ # Handle different metadata formats that might be returned
800
+ source = doc.metadata.get("source", "ArXiv")
801
+ doc_id = doc.metadata.get("id", doc.metadata.get("entry_id", ""))
802
+ result = {
803
+ "source": source,
804
+ "id": doc_id,
805
+ "summary": doc.page_content[:1000] if hasattr(doc, "page_content") else str(doc)[:1000],
806
+ }
807
+ results.append(result)
808
+ except Exception as e:
809
+ # Add error information as a fallback
810
+ results.append({
811
+ "source": "ArXiv Error",
812
+ "id": "error",
813
+ "summary": f"Error processing paper: {str(e)}"
814
+ })
815
+
816
+ return {"arvix_results": json.dumps(results)}
817
+
818
+ @tool(parse_docstring=True)
819
+ def answer_youtube_video_question(
820
+ youtube_url: str,
821
+ question: str,
822
+ chunk_size_seconds: int = 30
823
+ ) -> str:
824
+ """
825
+ Answer a question based on a YouTube video's transcript.
826
+
827
+ Args:
828
+ youtube_url: URL of the YouTube video.
829
+ question: The question to be answered using video content.
830
+ chunk_size_seconds: Duration of each transcript chunk.
831
+
832
+ Returns:
833
+ The answer to the question generated from the video transcript.
834
+ """
835
+ loader = YoutubeLoader.from_youtube_url(
836
+ youtube_url,
837
+ add_video_info=True,
838
+ transcript_format=TranscriptFormat.CHUNKS,
839
+ chunk_size_seconds=chunk_size_seconds,
840
+ )
841
+ documents = loader.load()
842
+ embeddings = HuggingFaceEmbeddings(model_name='sentence-transformers/all-mpnet-base-v2')
843
+ vectorstore = FAISS.from_documents(documents, embeddings)
844
+ llm = RetryingChatGroq(model="deepseek-r1-distill-llama-70b", streaming=False)
845
+ qa_chain = RetrievalQA.from_chain_type(llm=llm, retriever=vectorstore.as_retriever())
846
+ return qa_chain.run(question)
847
+
848
+ # ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
849
+ # ───────────────────────────────────────────────────────────── Tool for Python REPL tool ────────────────────────────────────────────────
850
+ # ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
851
+
852
+ python_repl = PythonREPLTool()
853
+
854
+ # ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
855
+ # ───────────────────────────────────────────────────────────── Tool for Wiki ────────────────────────────────────────────────────────────
856
+ # ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
857
+
858
+ @tool(parse_docstring=True)
859
+ def wiki_search(query: str) -> str:
860
+ """
861
+ Search Wikipedia for information on a given topic.
862
+
863
+ Args:
864
+ query: The search term for Wikipedia.
865
+
866
+ Returns:
867
+ A JSON string with up to 3 summary results.
868
+ """
869
+ # load up to top_k pages
870
+ pages = WikipediaLoader(query=query, load_max_docs=3).load()
871
+ results: List[Dict] = []
872
+ for doc in pages:
873
+ results.append({
874
+ "source": doc.metadata["source"],
875
+ "page": doc.metadata.get("page", ""),
876
+ "content": doc.page_content[:1000], # truncate if you like
877
+ })
878
+ return {"wiki_results": format_search_docs(results)}
879
+
880
+ # ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
881
+ # ───────────────────────────────────── Tool for Image (understading, captioning & classification) ─────────────────────────────────────────
882
+ # ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
883
+
884
+ def _load_image(img_path: str, resize_to=(512, 512)) -> Image.Image:
885
+ """
886
+ Load, verify, convert, and resize an image.
887
+ Raises ValueError on failure.
888
+ """
889
+ if not img_path:
890
+ raise ValueError("No image path provided.")
891
+ try:
892
+ with Image.open(img_path) as img:
893
+ img.verify()
894
+ img = Image.open(img_path).convert("RGB")
895
+ img = img.resize(resize_to)
896
+ return img
897
+ except UnidentifiedImageError:
898
+ raise ValueError(f"File at {img_path} is not a valid image.")
899
+ except Exception as e:
900
+ raise ValueError(f"Failed to load image at {img_path}: {e}")
901
+
902
+ def _encode_image_to_base64(img_path: str) -> str:
903
+ """
904
+ Load an image, save optimized PNG into memory, and base64‑encode it.
905
+ """
906
+ img = _load_image(img_path)
907
+ buffer = BytesIO()
908
+ img.save(buffer, format="PNG", optimize=True)
909
+ return base64.b64encode(buffer.getvalue()).decode("utf-8")
910
+
911
+ @tool
912
+ def image_processing(prompt: str, img_path: str) -> str:
913
+ """Process an image using a vision LLM, with OCR fallback.
914
+
915
+ Args:
916
+ prompt: Instruction or question related to the image.
917
+ img_path: Path to the image file.
918
+
919
+ Returns:
920
+ The model's response or fallback OCR result.
921
+ """
922
+ try:
923
+ import os
924
+ # Check if file exists
925
+ if not os.path.exists(img_path):
926
+ return f"Error: Image file '{img_path}' does not exist."
927
+
928
+ try:
929
+ b64 = _encode_image_to_base64(img_path)
930
+ # Build a single markdown string with inline base64 image
931
+ md = f"{prompt}\n\n![](data:image/png;base64,{b64})"
932
+ message = HumanMessage(content=md)
933
+ # Use RetryingChatGroq with Llama 4 Maverick for vision
934
+ llm = RetryingChatGroq(model="meta-llama/llama-4-maverick-17b-128e-instruct", streaming=False, temperature=0)
935
+ try:
936
+ resp = llm.invoke([message])
937
+ if hasattr(resp, 'content'):
938
+ return resp.content.strip()
939
+ elif isinstance(resp, str):
940
+ return resp.strip()
941
+ else:
942
+ # Handle dictionary or other response types
943
+ return str(resp)
944
+ except Exception as invoke_err:
945
+ print(f"[LLM invoke error] {invoke_err}")
946
+ # Fall back to OCR
947
+ raise ValueError("LLM invocation failed")
948
+ except Exception as llama_err:
949
+ print(f"[LLM vision failed] {llama_err}")
950
+ try:
951
+ img = _load_image(img_path)
952
+ return pytesseract.image_to_string(img).strip()
953
+ except Exception as ocr_err:
954
+ print(f"[OCR fallback failed] {ocr_err}")
955
+ return "Unable to process the image. Please check the file and try again."
956
+ except Exception as e:
957
+ # Catch any other errors
958
+ print(f"[image_processing error] {e}")
959
+ return f"Error processing image: {str(e)}"
960
+
961
+ python_repl_tool = PythonREPLTool()
962
+
963
+ @tool
964
+ def echo(text: str) -> str:
965
+ """Echo back the input text.
966
+
967
+ Args:
968
+ text: The string to be echoed.
969
+
970
+ Returns:
971
+ The same text that was provided as input.
972
+ """
973
+ return text
974
+
975
+ # ─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────��───────────────────
976
+ # ─────────────────────────────────────────────── Langgraph Agent ───────────────────────────────────────────────────────────────────────
977
+ # ─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
978
+
979
+
980
+ # Build graph function
981
+ from langchain_core.tools import tool
982
+ from langchain.chat_models import ChatOpenAI
983
+ from langgraph.prebuilt.chat_agent_executor import create_react_agent, AgentState
984
+ from langchain.chat_models import init_chat_model
985
+
986
+
987
+
988
+ def build_graph(provider: str = "groq"):
989
+ """Construct and compile the multi‑agent GAIA workflow StateGraph.
990
+
991
+ This graph wires together three React‑style agents into a streamlined pipeline:
992
+ PerceptionAgent → ActionAgent → EvaluationAgent (with appropriate entry/exit points)
993
+
994
+ The agents have the following responsibilities:
995
+ - PerceptionAgent: Handles web searches, Wikipedia, ArXiv, and image processing
996
+ - ActionAgent: Performs calculations, file operations, and code analysis
997
+ - EvaluationAgent: Reviews results and ensures the final answer is properly formatted
998
+
999
+ Args:
1000
+ provider: The name of the LLM provider. Must be "groq".
1001
+
1002
+ Returns:
1003
+ CompiledGraph: A compiled LangGraph state machine ready for invocation.
1004
+
1005
+ Raises:
1006
+ ValueError: If `provider` is anything other than "groq".
1007
+ """
1008
+ try:
1009
+ if provider != "groq":
1010
+ raise ValueError("Invalid provider. Expected 'groq'.")
1011
+
1012
+ # Initialize LLM
1013
+ try:
1014
+ logger.info("Initializing LLM with model: deepseek-r1-distill-llama-70b")
1015
+ api_key = os.getenv("GROQ_API_KEY")
1016
+ if not api_key or api_key == "default_key_or_placeholder":
1017
+ logger.error("GROQ_API_KEY is not set or is using placeholder value")
1018
+ raise ValueError("GROQ_API_KEY environment variable is not set properly. Please set a valid API key.")
1019
+
1020
+ llm = RetryingChatGroq(model="deepseek-r1-distill-llama-70b", temperature=0)
1021
+ logger.info("LLM initialized successfully")
1022
+ except Exception as e:
1023
+ logger.error(f"Error initializing LLM: {str(e)}")
1024
+ raise
1025
+
1026
+ # General system message for agents
1027
+ sys_msg = SystemMessage(content="""
1028
+ You are a general AI assistant. I will ask you a question. Report your thoughts, and finish your answer with the following template:
1029
+
1030
+ FINAL ANSWER: [YOUR FINAL ANSWER]
1031
+
1032
+ YOUR FINAL ANSWER should be a number OR as few words as possible OR a comma-separated list of numbers and/or strings.
1033
+
1034
+ If you are asked for a number, don't use commas or units (e.g., $, %, kg) unless specified otherwise.
1035
+
1036
+ If you are asked for a string, don't use articles (a, an, the), and don't use abbreviations (e.g., for states).
1037
+
1038
+ If you are asked for a comma-separated list, apply the above rules to each element in the list.
1039
+ """.strip())
1040
+
1041
+ # Special system message for the evaluation agent with stricter formatting requirements
1042
+ eval_sys_msg = SystemMessage(content="""
1043
+ You are a specialized evaluation agent. Your job is to review the work done by other agents
1044
+ and provide a final, properly formatted answer.
1045
+
1046
+ IMPORTANT: You MUST ALWAYS format your answer using this exact template:
1047
+
1048
+ FINAL ANSWER: [concise answer]
1049
+
1050
+ Rules for formatting the answer:
1051
+ 1. The answer must be extremely concise - use as few words as possible
1052
+ 2. For numeric answers, provide only the number without units unless units are specifically requested
1053
+ 3. For text answers, avoid articles (a, an, the) and unnecessary words
1054
+ 4. For list answers, use a comma-separated format
1055
+ 5. NEVER explain your reasoning in the FINAL ANSWER section
1056
+ 6. NEVER skip the "FINAL ANSWER:" prefix
1057
+
1058
+ Example good answers:
1059
+ FINAL ANSWER: 42
1060
+ FINAL ANSWER: Paris
1061
+ FINAL ANSWER: 1912, 1945, 1989
1062
+
1063
+ Example bad answers (don't do these):
1064
+ - Based on my analysis, the answer is 42.
1065
+ - I think it's Paris because that's the capital of France.
1066
+ - The years were 1912, 1945, and 1989.
1067
+
1068
+ Remember: ALWAYS include "FINAL ANSWER:" followed by the most concise answer possible.
1069
+ """.strip())
1070
+
1071
+ # Define tools for each agent
1072
+ logger.info("Setting up agent tools")
1073
+ perception_tools = [web_search, wiki_search, news_article_search, arvix_search, image_processing, echo]
1074
+ execution_tools = [
1075
+ multiply, add, subtract, divide, modulus,
1076
+ download_file, process_excel_to_text,
1077
+ read_text_from_pdf, read_text_from_docx,
1078
+ transcribe_audio, youtube_audio_processing,
1079
+ extract_article_text, answer_youtube_video_question,
1080
+ python_repl_tool, analyze_code, read_code_file, analyze_python_function
1081
+ ]
1082
+
1083
+ # ─────────────── Agent Creation ───────────────
1084
+ logger.info("Creating agents")
1085
+ try:
1086
+ # Create agents with proper error handling
1087
+ PerceptionAgent = create_react_agent(
1088
+ model=llm,
1089
+ tools=perception_tools,
1090
+ prompt=sys_msg,
1091
+ state_schema=AgentState,
1092
+ name="PerceptionAgent"
1093
+ )
1094
+ logger.info("Created PerceptionAgent successfully")
1095
+
1096
+ # Combined Planning and Execution agent for better efficiency
1097
+ ActionAgent = create_react_agent(
1098
+ model=llm,
1099
+ tools=execution_tools, # Has access to all execution tools
1100
+ prompt=sys_msg,
1101
+ state_schema=AgentState,
1102
+ name="ActionAgent"
1103
+ )
1104
+ logger.info("Created ActionAgent successfully")
1105
+
1106
+ # Evaluation agent with stricter prompt
1107
+ EvaluationAgent = create_react_agent(
1108
+ model=llm,
1109
+ tools=[], # No tools needed for evaluation
1110
+ prompt=eval_sys_msg, # Use the specialized evaluation prompt
1111
+ state_schema=AgentState,
1112
+ name="EvaluationAgent"
1113
+ )
1114
+ logger.info("Created EvaluationAgent successfully")
1115
+ except Exception as e:
1116
+ logger.error(f"Error creating agent: {str(e)}")
1117
+ import traceback
1118
+ logger.error(f"Traceback: {traceback.format_exc()}")
1119
+ raise
1120
+
1121
+ # Build the StateGraph
1122
+ logger.info("Building StateGraph")
1123
+ try:
1124
+ builder = StateGraph(AgentState)
1125
+
1126
+ # Add agent nodes first
1127
+ builder.add_node("PerceptionAgent", PerceptionAgent)
1128
+ builder.add_node("ActionAgent", ActionAgent)
1129
+ builder.add_node("EvaluationAgent", EvaluationAgent)
1130
+
1131
+ # Define the flow with a starting edge
1132
+ builder.set_entry_point("PerceptionAgent")
1133
+
1134
+ # Add the edges for the simpler linear flow
1135
+ builder.add_edge("PerceptionAgent", "ActionAgent")
1136
+ builder.add_edge("ActionAgent", "EvaluationAgent")
1137
+
1138
+ # Set EvaluationAgent as the end node
1139
+ builder.set_finish_point("EvaluationAgent")
1140
+
1141
+ logger.info("Compiling StateGraph")
1142
+ return builder.compile()
1143
+ except Exception as e:
1144
+ logger.error(f"Error building graph: {str(e)}")
1145
+ import traceback
1146
+ logger.error(f"Traceback: {traceback.format_exc()}")
1147
+ raise
1148
+ except Exception as e:
1149
+ logger.error(f"Overall error in build_graph: {str(e)}")
1150
+ import traceback
1151
+ logger.error(f"Traceback: {traceback.format_exc()}")
1152
+ raise
1153
+
1154
+ def get_final_answer(text):
1155
+ """Extract just the FINAL ANSWER from the model's response.
1156
+
1157
+ Args:
1158
+ text: The full text response from the LLM
1159
+
1160
+ Returns:
1161
+ str: The extracted answer without the "FINAL ANSWER:" prefix
1162
+ """
1163
+ # Log the raw text for debugging if needed
1164
+ logger.debug(f"Extracting answer from: {text[:200]}...")
1165
+
1166
+ if not text:
1167
+ logger.warning("Empty response received")
1168
+ return "No answer provided."
1169
+
1170
+ # Method 1: Look for "FINAL ANSWER:" with most comprehensive pattern matching
1171
+ pattern = r'(?:^|\n)FINAL ANSWER:\s*(.*?)(?:\n\s*$|$)'
1172
+ match = re.search(pattern, text, re.DOTALL | re.IGNORECASE)
1173
+ if match:
1174
+ # Return just the answer part, cleaned up
1175
+ logger.debug("Found answer using pattern 1")
1176
+ return match.group(1).strip()
1177
+
1178
+ # Method 2: Try looking for variations on the final answer format
1179
+ for variant in ["FINAL ANSWER:", "FINAL_ANSWER:", "Final Answer:", "Answer:"]:
1180
+ lines = text.split('\n')
1181
+ for i, line in enumerate(reversed(lines)):
1182
+ if variant in line:
1183
+ # Extract everything after the variant text
1184
+ logger.debug(f"Found answer using variant: {variant}")
1185
+ answer = line[line.find(variant) + len(variant):].strip()
1186
+ if answer:
1187
+ return answer
1188
+ # If the answer is on the next line, return that
1189
+ if i > 0:
1190
+ next_line = lines[len(lines) - i]
1191
+ if next_line.strip():
1192
+ return next_line.strip()
1193
+
1194
+ # Method 3: Look for phrases that suggest an answer
1195
+ for phrase in ["The answer is", "The result is", "We get", "Therefore,", "In conclusion,"]:
1196
+ phrase_pos = text.find(phrase)
1197
+ if phrase_pos != -1:
1198
+ # Try to extract everything after the phrase until the end of the sentence
1199
+ sentence_end = text.find(".", phrase_pos)
1200
+ if sentence_end != -1:
1201
+ logger.debug(f"Found answer using phrase: {phrase}")
1202
+ return text[phrase_pos + len(phrase):sentence_end].strip()
1203
+
1204
+ # Method 4: Fall back to taking the last paragraph with actual content
1205
+ paragraphs = text.strip().split('\n\n')
1206
+ for para in reversed(paragraphs):
1207
+ para = para.strip()
1208
+ if para and not para.startswith("I ") and not para.lower().startswith("to "):
1209
+ logger.debug("Using last meaningful paragraph")
1210
+ # If paragraph is very long, try to extract a concise answer
1211
+ if len(para) > 100:
1212
+ sentences = re.split(r'[.!?]', para)
1213
+ for sentence in reversed(sentences):
1214
+ sent = sentence.strip()
1215
+ if sent and len(sent) > 5 and not sent.startswith("I "):
1216
+ return sent
1217
+ return para
1218
+
1219
+ # Method 5: Last resort - just return the last line with content
1220
+ lines = text.strip().split('\n')
1221
+ for line in reversed(lines):
1222
+ line = line.strip()
1223
+ if line and len(line) > 3:
1224
+ logger.debug("Using last line with content")
1225
+ return line
1226
+
1227
+ # If everything fails, warn and return the truncated response
1228
+ logger.warning("Could not find a properly formatted answer")
1229
+ return text[:100] + "..." if len(text) > 100 else text
1230
+
1231
+ # test
1232
+ if __name__ == "__main__":
1233
+ question = "When was a picture of St. Thomas Aquinas first added to the Wikipedia page on the Principle of double effect?"
1234
+ # Build the graph
1235
+ graph = build_graph(provider="groq")
1236
+ # Run the graph
1237
+ messages = [HumanMessage(content=question)]
1238
+ messages = graph.invoke({"messages": messages})
1239
+ for m in messages["messages"]:
1240
+ m.pretty_print()
1241
+
1242
+ # ─────────────────────────────────────────────── Tool for Code Analysis ───────────────────────────────────────────────────────────────
1243
+ @tool
1244
+ def analyze_code(code_string: str) -> str:
1245
+ """Analyze a string of code to understand its structure, functionality, and potential issues.
1246
+
1247
+ Args:
1248
+ code_string: The code to analyze as a string.
1249
+
1250
+ Returns:
1251
+ A structured analysis of the code including functions, classes, and key operations.
1252
+ """
1253
+ try:
1254
+ import ast
1255
+
1256
+ # Try to parse with Python's AST module
1257
+ try:
1258
+ parsed = ast.parse(code_string)
1259
+
1260
+ # Extract functions and classes
1261
+ functions = [node.name for node in ast.walk(parsed) if isinstance(node, ast.FunctionDef)]
1262
+ classes = [node.name for node in ast.walk(parsed) if isinstance(node, ast.ClassDef)]
1263
+ imports = [node.names[0].name for node in ast.walk(parsed) if isinstance(node, ast.Import)]
1264
+ imports.extend([f"{node.module}.{name.name}" if node.module else name.name
1265
+ for node in ast.walk(parsed) if isinstance(node, ast.ImportFrom)
1266
+ for name in node.names])
1267
+
1268
+ # Count various node types for complexity assessment
1269
+ num_loops = len([node for node in ast.walk(parsed)
1270
+ if isinstance(node, (ast.For, ast.While))])
1271
+ num_conditionals = len([node for node in ast.walk(parsed)
1272
+ if isinstance(node, (ast.If, ast.IfExp))])
1273
+
1274
+ analysis = {
1275
+ "language": "Python",
1276
+ "functions": functions,
1277
+ "classes": classes,
1278
+ "imports": imports,
1279
+ "complexity": {
1280
+ "functions": len(functions),
1281
+ "classes": len(classes),
1282
+ "loops": num_loops,
1283
+ "conditionals": num_conditionals
1284
+ }
1285
+ }
1286
+ return str(analysis)
1287
+ except SyntaxError:
1288
+ # If not valid Python, try some simple pattern matching
1289
+ if "{" in code_string and "}" in code_string:
1290
+ if "function" in code_string or "=>" in code_string:
1291
+ language = "JavaScript/TypeScript"
1292
+ elif "func" in code_string or "struct" in code_string:
1293
+ language = "Go or Rust"
1294
+ elif "public" in code_string or "private" in code_string or "class" in code_string:
1295
+ language = "Java/C#/C++"
1296
+ else:
1297
+ language = "Unknown C-like language"
1298
+ elif "<" in code_string and ">" in code_string and ("/>" in code_string or "</"):
1299
+ language = "HTML/XML/JSX"
1300
+ else:
1301
+ language = "Unknown"
1302
+
1303
+ return f"Non-Python code detected ({language}). Basic code structure analysis not available."
1304
+ except Exception as e:
1305
+ return f"Error analyzing code: {str(e)}"
1306
+
1307
+ @tool
1308
+ def read_code_file(file_path: str) -> str:
1309
+ """Read a code file and return its contents with proper syntax detection.
1310
+
1311
+ Args:
1312
+ file_path: Path to the code file.
1313
+
1314
+ Returns:
1315
+ The file contents and detected language.
1316
+ """
1317
+ try:
1318
+ # Check if file exists
1319
+ import os
1320
+ if not os.path.exists(file_path):
1321
+ return f"Error: File '{file_path}' does not exist."
1322
+
1323
+ with open(file_path, 'r', encoding='utf-8') as f:
1324
+ content = f.read()
1325
+
1326
+ # Try to detect language from extension
1327
+ ext = os.path.splitext(file_path)[1].lower()
1328
+
1329
+ language_map = {
1330
+ '.py': 'Python',
1331
+ '.js': 'JavaScript',
1332
+ '.ts': 'TypeScript',
1333
+ '.html': 'HTML',
1334
+ '.css': 'CSS',
1335
+ '.java': 'Java',
1336
+ '.c': 'C',
1337
+ '.cpp': 'C++',
1338
+ '.cs': 'C#',
1339
+ '.go': 'Go',
1340
+ '.rs': 'Rust',
1341
+ '.php': 'PHP',
1342
+ '.rb': 'Ruby',
1343
+ '.sh': 'Shell',
1344
+ '.bat': 'Batch',
1345
+ '.ps1': 'PowerShell',
1346
+ '.sql': 'SQL',
1347
+ '.json': 'JSON',
1348
+ '.xml': 'XML',
1349
+ '.yaml': 'YAML',
1350
+ '.yml': 'YAML',
1351
+ }
1352
+
1353
+ language = language_map.get(ext, 'Unknown')
1354
+
1355
+ return f"File content ({language}):\n\n{content}"
1356
+ except Exception as e:
1357
+ return f"Error reading file: {str(e)}"
1358
+
1359
+ @tool
1360
+ def analyze_python_function(function_name: str, code_string: str) -> str:
1361
+ """Extract and analyze a specific function from Python code.
1362
+
1363
+ Args:
1364
+ function_name: The name of the function to analyze.
1365
+ code_string: The complete code containing the function.
1366
+
1367
+ Returns:
1368
+ Analysis of the function including parameters, return type, and docstring.
1369
+ """
1370
+ try:
1371
+ import ast
1372
+ import inspect
1373
+ from types import CodeType, FunctionType
1374
+
1375
+ # Parse the code string
1376
+ parsed = ast.parse(code_string)
1377
+
1378
+ # Find the function definition
1379
+ function_def = None
1380
+ for node in ast.walk(parsed):
1381
+ if isinstance(node, ast.FunctionDef) and node.name == function_name:
1382
+ function_def = node
1383
+ break
1384
+
1385
+ if not function_def:
1386
+ return f"Function '{function_name}' not found in the provided code."
1387
+
1388
+ # Extract parameters
1389
+ params = []
1390
+ for arg in function_def.args.args:
1391
+ param_name = arg.arg
1392
+ # Get annotation if it exists
1393
+ if arg.annotation:
1394
+ if isinstance(arg.annotation, ast.Name):
1395
+ param_type = arg.annotation.id
1396
+ elif isinstance(arg.annotation, ast.Attribute):
1397
+ param_type = f"{arg.annotation.value.id}.{arg.annotation.attr}"
1398
+ else:
1399
+ param_type = "complex_type"
1400
+ params.append(f"{param_name}: {param_type}")
1401
+ else:
1402
+ params.append(param_name)
1403
+
1404
+ # Extract return type if it exists
1405
+ return_type = None
1406
+ if function_def.returns:
1407
+ if isinstance(function_def.returns, ast.Name):
1408
+ return_type = function_def.returns.id
1409
+ elif isinstance(function_def.returns, ast.Attribute):
1410
+ return_type = f"{function_def.returns.value.id}.{function_def.returns.attr}"
1411
+ else:
1412
+ return_type = "complex_return_type"
1413
+
1414
+ # Extract docstring
1415
+ docstring = ast.get_docstring(function_def)
1416
+
1417
+ # Create a summary
1418
+ summary = {
1419
+ "function_name": function_name,
1420
+ "parameters": params,
1421
+ "return_type": return_type,
1422
+ "docstring": docstring,
1423
+ "decorators": [d.id if isinstance(d, ast.Name) else "complex_decorator" for d in function_def.decorator_list],
1424
+ "line_count": len(function_def.body)
1425
+ }
1426
+
1427
+ # Create a more explicit string representation that ensures key terms are included
1428
+ result = f"Function '{function_name}' analysis:\n"
1429
+ result += f"- Parameters: {', '.join(params)}\n"
1430
+ result += f"- Return type: {return_type or 'None specified'}\n"
1431
+ result += f"- Docstring: {docstring or 'None'}\n"
1432
+ result += f"- Line count: {len(function_def.body)}"
1433
+
1434
+ return result
1435
+ except Exception as e:
1436
+ return f"Error analyzing function: {str(e)}"
1437
+
1438
+ # ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
1439
+ # ─────────────────────────────────────────────── Tool for News Article Retrieval ──────────────────────────────────────────────────────────────────────
1440
+ # ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
1441
+
1442
+ @tool
1443
+ def news_article_search(query: str, top_k: int = 3) -> Dict[str, str]:
1444
+ """Search for and retrieve news articles with robust error handling for news sites.
1445
+
1446
+ Args:
1447
+ query: The news topic or keywords to search for.
1448
+ top_k: Maximum number of articles to retrieve.
1449
+
1450
+ Returns:
1451
+ A dictionary with search results formatted as XML-like document entries.
1452
+ """
1453
+ # First, get URLs from DuckDuckGo with "news" focus
1454
+ results = []
1455
+ news_sources = [
1456
+ "bbc.com", "reuters.com", "apnews.com", "nasa.gov",
1457
+ "space.com", "universetoday.com", "nature.com", "science.org",
1458
+ "scientificamerican.com", "nytimes.com", "theguardian.com"
1459
+ ]
1460
+
1461
+ # Find news from reliable sources
1462
+ try:
1463
+ with DDGS() as ddgs:
1464
+ search_query = f"{query} site:{' OR site:'.join(news_sources)}"
1465
+ for hit in ddgs.text(search_query, safesearch="On", max_results=top_k*2):
1466
+ url = hit.get("href") or hit.get("url", "")
1467
+ if not url:
1468
+ continue
1469
+
1470
+ # Add the search snippet first as a fallback
1471
+ result = {
1472
+ "source": url,
1473
+ "page": "",
1474
+ "content": hit.get("body", "")[:250],
1475
+ "title": hit.get("title", "")
1476
+ }
1477
+
1478
+ # Try to get better content via a more robust method
1479
+ try:
1480
+ headers = {
1481
+ "User-Agent": random.choice([
1482
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36",
1483
+ "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.0 Safari/605.1.15",
1484
+ "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Safari/537.36"
1485
+ ]),
1486
+ "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
1487
+ "Accept-Language": "en-US,en;q=0.5",
1488
+ "Referer": "https://www.google.com/",
1489
+ "DNT": "1",
1490
+ "Connection": "keep-alive",
1491
+ "Upgrade-Insecure-Requests": "1"
1492
+ }
1493
+
1494
+ # Add a short delay between requests
1495
+ time.sleep(1 + random.random())
1496
+
1497
+ # Try to use newspaper3k for more reliable article extraction
1498
+ from newspaper import Article
1499
+ article = Article(url)
1500
+ article.download()
1501
+ article.parse()
1502
+
1503
+ # If we got meaningful content, update the result
1504
+ if article.text and len(article.text) > 100:
1505
+ # Get a summary - first paragraph + some highlights
1506
+ paragraphs = article.text.split('\n\n')
1507
+ first_para = paragraphs[0] if paragraphs else ""
1508
+ summary = first_para[:300]
1509
+ if len(paragraphs) > 1:
1510
+ summary += "... " + paragraphs[1][:200]
1511
+
1512
+ result["content"] = summary
1513
+ if article.title:
1514
+ result["title"] = article.title
1515
+
1516
+ except Exception as article_err:
1517
+ logger.warning(f"Article extraction failed for {url}: {article_err}")
1518
+ # Fallback to simple requests-based extraction
1519
+ try:
1520
+ resp = requests.get(url, timeout=12, headers=headers)
1521
+ resp.raise_for_status()
1522
+ soup = BeautifulSoup(resp.text, "html.parser")
1523
+
1524
+ # Try to get main content
1525
+ main_content = soup.find('main') or soup.find('article') or soup.find('div', class_='content')
1526
+
1527
+ if main_content:
1528
+ content = " ".join(main_content.get_text(separator=" ", strip=True).split()[:250])
1529
+ result["content"] = content
1530
+ except Exception as req_err:
1531
+ logger.warning(f"Fallback extraction failed for {url}: {req_err}")
1532
+ # Keep the original snippet as fallback
1533
+
1534
+ results.append(result)
1535
+ if len(results) >= top_k:
1536
+ break
1537
+
1538
+ except Exception as e:
1539
+ logger.error(f"News search failed: {e}")
1540
+ return format_search_docs([{
1541
+ "source": "Error",
1542
+ "page": "",
1543
+ "content": f"Failed to retrieve news articles for '{query}': {str(e)}"
1544
+ }])
1545
+
1546
+ if not results:
1547
+ # Fallback to regular web search
1548
+ logger.info(f"No news results found, falling back to web_search for {query}")
1549
+ return web_search(query, top_k)
1550
+
1551
+ return format_search_docs(results[:top_k])
1552
+
1553
+ # ───────────────────────────────────────────────────────────── Document Chunking Utilities ──────────────────────────────────────────────────────────
1554
+ def chunk_document(text: str, chunk_size: int = 1000, overlap: int = 100) -> List[str]:
1555
+ """
1556
+ Split a large document into smaller chunks with overlap to maintain context across chunks.
1557
+
1558
+ Args:
1559
+ text: The document text to split into chunks
1560
+ chunk_size: Maximum size of each chunk in characters
1561
+ overlap: Number of characters to overlap between chunks
1562
+
1563
+ Returns:
1564
+ List of text chunks
1565
+ """
1566
+ # If text is smaller than chunk_size, return it as is
1567
+ if len(text) <= chunk_size:
1568
+ return [text]
1569
+
1570
+ chunks = []
1571
+ start = 0
1572
+
1573
+ while start < len(text):
1574
+ # Get chunk with overlap
1575
+ end = min(start + chunk_size, len(text))
1576
+
1577
+ # Try to find sentence boundary for cleaner breaks
1578
+ if end < len(text):
1579
+ # Look for sentence endings: period, question mark, or exclamation followed by space
1580
+ for sentence_end in ['. ', '? ', '! ']:
1581
+ last_period = text[start:end].rfind(sentence_end)
1582
+ if last_period != -1:
1583
+ end = start + last_period + 2 # +2 to include the period and space
1584
+ break
1585
+
1586
+ # Add chunk to list
1587
+ chunks.append(text[start:end])
1588
+
1589
+ # Move start position, accounting for overlap
1590
+ start = end - overlap if end < len(text) else len(text)
1591
+
1592
+ return chunks
1593
+
1594
+ # Document processing utility that uses chunking
1595
+ def process_large_document(text: str, question: str, llm=None) -> str:
1596
+ """
1597
+ Process a large document by chunking it and using retrieval to find relevant parts.
1598
+
1599
+ Args:
1600
+ text: The document text to process
1601
+ question: The question being asked about the document
1602
+ llm: Optional language model to use (defaults to agent's LLM)
1603
+
1604
+ Returns:
1605
+ Summarized answer based on relevant chunks
1606
+ """
1607
+ if not llm:
1608
+ llm = RetryingChatGroq(model="deepseek-r1-distill-llama-70b", streaming=False, temperature=0)
1609
+
1610
+ # Split document into chunks
1611
+ chunks = chunk_document(text)
1612
+
1613
+ # If document is small enough, don't bother with retrieval
1614
+ if len(chunks) <= 1:
1615
+ return text
1616
+
1617
+ # For larger documents, create embeddings to find relevant chunks
1618
+ try:
1619
+ from langchain_community.embeddings import HuggingFaceEmbeddings
1620
+ from langchain.vectorstores import FAISS
1621
+ from langchain.schema import Document
1622
+
1623
+ # Create documents with chunk content
1624
+ documents = [Document(page_content=chunk, metadata={"chunk_id": i}) for i, chunk in enumerate(chunks)]
1625
+
1626
+ # Create embeddings and vector store
1627
+ embeddings = HuggingFaceEmbeddings(model_name="sentence-transformers/all-mpnet-base-v2")
1628
+ vectorstore = FAISS.from_documents(documents, embeddings)
1629
+
1630
+ # Get most relevant chunks
1631
+ relevant_chunks = vectorstore.similarity_search(question, k=2) # Get top 2 most relevant chunks
1632
+
1633
+ # Join the relevant chunks
1634
+ relevant_text = "\n\n".join([doc.page_content for doc in relevant_chunks])
1635
+
1636
+ # Option 1: Return relevant chunks directly
1637
+ return relevant_text
1638
+
1639
+ # Option 2: Summarize with LLM (commented out for now)
1640
+ # prompt = f"Using only the following information, answer the question: '{question}'\n\nInformation:\n{relevant_text}"
1641
+ # response = llm.invoke([HumanMessage(content=prompt)])
1642
+ # return response.content
1643
+
1644
+ except Exception as e:
1645
+ # Fall back to first chunk if retrieval fails
1646
+ logger.warning(f"Retrieval failed: {e}. Falling back to first chunk.")
1647
+ return chunks[0]
v2/scratch_agent/agent2.py ADDED
@@ -0,0 +1,259 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ from dotenv import load_dotenv
3
+
4
+ from langchain_core.tools import tool
5
+ from langgraph.prebuilt import tools_condition, ToolNode
6
+ from langgraph.graph import START, StateGraph, MessagesState
7
+
8
+ from langchain_community.tools.tavily_search import TavilySearchResults
9
+ from langchain_community.document_loaders import WikipediaLoader, ArxivLoader
10
+ from langchain_core.messages import SystemMessage, HumanMessage
11
+ from langchain_community.vectorstores import FAISS
12
+ from langchain_huggingface import HuggingFaceEmbeddings
13
+ from langchain_groq import ChatGroq
14
+ from langchain.tools.retriever import create_retriever_tool
15
+
16
+ """LangGraph Agent"""
17
+ import os
18
+ from dotenv import load_dotenv
19
+ from langgraph.graph import START, StateGraph, MessagesState
20
+ from langgraph.prebuilt import tools_condition
21
+ from langgraph.prebuilt import ToolNode
22
+ from langchain_google_genai import ChatGoogleGenerativeAI
23
+ from langchain_groq import ChatGroq
24
+ from langchain_huggingface import ChatHuggingFace, HuggingFaceEndpoint, HuggingFaceEmbeddings
25
+ from langchain_community.tools.tavily_search import TavilySearchResults
26
+ from langchain_community.document_loaders import WikipediaLoader
27
+ from langchain_community.document_loaders import ArxivLoader
28
+ from langchain_community.vectorstores import SupabaseVectorStore,FAISS
29
+ from langchain_core.messages import SystemMessage, HumanMessage
30
+ from langchain_core.tools import tool
31
+ from langchain.tools.retriever import create_retriever_tool
32
+ #from supabase.client import Client, create_client
33
+
34
+ # ──────────────────────────────────────────────────────────
35
+ # ENV
36
+ # ──────────────────────────────────────────────────────────
37
+ load_dotenv()
38
+ # API Keys from .env file
39
+ os.environ.setdefault("OPENAI_API_KEY", "<YOUR_OPENAI_KEY>") # Set your own key or env var
40
+ os.environ["GROQ_API_KEY"] = os.getenv("GROQ_API_KEY", "default_key_or_placeholder")
41
+ os.environ["MISTRAL_API_KEY"] = os.getenv("MISTRAL_API_KEY", "default_key_or_placeholder")
42
+
43
+ # Tavily API Key
44
+ TAVILY_API_KEY = os.getenv("TAVILY_API_KEY", "default_key_or_placeholder")
45
+ _forbidden = ["nsfw", "porn", "sex", "explicit"]
46
+ _playwright_available = True # set False to disable Playwright
47
+
48
+ embeddings = HuggingFaceEmbeddings(model_name="sentence-transformers/all-mpnet-base-v2") # dim = 768
49
+
50
+ @tool
51
+ def multiply(a: int, b: int) -> int:
52
+ """Multiply two numbers.
53
+
54
+ Args:
55
+ a: first int
56
+ b: second int
57
+ """
58
+ return a * b
59
+
60
+ @tool
61
+ def add(a: int, b: int) -> int:
62
+ """Add two numbers.
63
+
64
+ Args:
65
+ a: first int
66
+ b: second int
67
+ """
68
+ return a + b
69
+
70
+ @tool
71
+ def subtract(a: int, b: int) -> int:
72
+ """Subtract two numbers.
73
+
74
+ Args:
75
+ a: first int
76
+ b: second int
77
+ """
78
+ return a - b
79
+
80
+ @tool
81
+ def divide(a: int, b: int) -> int:
82
+ """Divide two numbers.
83
+
84
+ Args:
85
+ a: first int
86
+ b: second int
87
+ """
88
+ if b == 0:
89
+ raise ValueError("Cannot divide by zero.")
90
+ return a / b
91
+
92
+ @tool
93
+ def modulus(a: int, b: int) -> int:
94
+ """Get the modulus of two numbers.
95
+
96
+ Args:
97
+ a: first int
98
+ b: second int
99
+ """
100
+ return a % b
101
+
102
+ @tool
103
+ def wiki_search(query: str) -> str:
104
+ """Search Wikipedia for a query and return maximum 2 results.
105
+
106
+ Args:
107
+ query: The search query."""
108
+ search_docs = WikipediaLoader(query=query, load_max_docs=2).load()
109
+ formatted_search_docs = "\n\n---\n\n".join(
110
+ [
111
+ f'<Document source="{doc.metadata["source"]}" page="{doc.metadata.get("page", "")}"/>\n{doc.page_content}\n</Document>'
112
+ for doc in search_docs
113
+ ])
114
+ return {"wiki_results": formatted_search_docs}
115
+
116
+ @tool
117
+ def web_search(query: str) -> str:
118
+ """Search Tavily for a query and return maximum 3 results.
119
+
120
+ Args:
121
+ query: The search query."""
122
+ search_docs = TavilySearchResults(max_results=3).invoke(query=query)
123
+ formatted_search_docs = "\n\n---\n\n".join(
124
+ [
125
+ f'<Document source="{doc.metadata["source"]}" page="{doc.metadata.get("page", "")}"/>\n{doc.page_content}\n</Document>'
126
+ for doc in search_docs
127
+ ])
128
+ return {"web_results": formatted_search_docs}
129
+
130
+ @tool
131
+ def arvix_search(query: str) -> str:
132
+ """Search Arxiv for a query and return maximum 3 result.
133
+
134
+ Args:
135
+ query: The search query."""
136
+ search_docs = ArxivLoader(query=query, load_max_docs=3).load()
137
+ formatted_search_docs = "\n\n---\n\n".join(
138
+ [
139
+ f'<Document source="{doc.metadata["source"]}" page="{doc.metadata.get("page", "")}"/>\n{doc.page_content[:1000]}\n</Document>'
140
+ for doc in search_docs
141
+ ])
142
+ return {"arvix_results": formatted_search_docs}
143
+
144
+
145
+
146
+ # load the system prompt from the file
147
+ with open("system_prompt.txt", "r", encoding="utf-8") as f:
148
+ system_prompt = f.read()
149
+
150
+ # System message
151
+ sys_msg = SystemMessage(content=system_prompt)
152
+
153
+ # build a retriever
154
+ embeddings = HuggingFaceEmbeddings(model_name="sentence-transformers/all-mpnet-base-v2") # dim=768
155
+
156
+ INDEX_PATH = "faiss_index"
157
+ if os.path.exists(INDEX_PATH):
158
+ vector_store = FAISS.load_local(INDEX_PATH, embeddings, allow_dangerous_deserialization=True)
159
+ else:
160
+ vector_store = FAISS.from_texts(["__init__"], embeddings)
161
+ vector_store.save_local(INDEX_PATH)
162
+
163
+ create_retriever_tool = create_retriever_tool(
164
+ retriever=vector_store.as_retriever(),
165
+ name="Question Search",
166
+ description="A tool to retrieve similar questions from a local FAISS vector store."
167
+ )
168
+
169
+
170
+
171
+ tools = [
172
+ multiply,
173
+ add,
174
+ subtract,
175
+ divide,
176
+ modulus,
177
+ wiki_search,
178
+ web_search,
179
+ arvix_search,
180
+ ]
181
+
182
+ # Build graph function
183
+ def build_graph(provider: str = "groq"):
184
+ """Build the graph"""
185
+ # Load environment variables from .env file
186
+ if provider == "google":
187
+ # Google Gemini
188
+ llm = ChatGoogleGenerativeAI(model="gemini-2.0-flash", temperature=0)
189
+ elif provider == "groq":
190
+ # Groq https://console.groq.com/docs/models
191
+ try:
192
+ llm = ChatGroq(model="deepseek-r1-distill-llama-70b", temperature=0) # optional : qwen-qwq-32b gemma2-9b-it
193
+ except Exception as e:
194
+ print(f"Error initializing Groq: {str(e)}")
195
+ raise
196
+ elif provider == "huggingface":
197
+ # TODO: Add huggingface endpoint
198
+ llm = ChatHuggingFace(
199
+ llm=HuggingFaceEndpoint(
200
+ url="https://api-inference.huggingface.co/models/Meta-DeepLearning/llama-2-7b-chat-hf",
201
+ temperature=0,
202
+ ),
203
+ )
204
+ else:
205
+ raise ValueError("Invalid provider. Choose 'google', 'groq' or 'huggingface'.")
206
+
207
+ # Bind tools to LLM
208
+ llm_with_tools = llm.bind_tools(tools)
209
+
210
+ # Node
211
+ def assistant(state: MessagesState):
212
+ """Assistant node"""
213
+ try:
214
+ if not state["messages"] or not state["messages"][-1].content:
215
+ raise ValueError("Empty message content")
216
+ return {"messages": [llm_with_tools.invoke(state["messages"])]}
217
+ except Exception as e:
218
+ print(f"Error in assistant node: {str(e)}")
219
+ raise
220
+
221
+ def retriever(state: MessagesState):
222
+ """Retriever node"""
223
+ try:
224
+ if not state["messages"] or not state["messages"][0].content:
225
+ raise ValueError("Empty message content")
226
+ similar_question = vector_store.similarity_search(state["messages"][0].content)
227
+ example_msg = HumanMessage(
228
+ content=f"Here I provide a similar question and answer for reference: \n\n{similar_question[0].page_content}",
229
+ )
230
+ return {"messages": [sys_msg] + state["messages"] + [example_msg]}
231
+ except Exception as e:
232
+ print(f"Error in retriever node: {str(e)}")
233
+ raise
234
+
235
+ builder = StateGraph(MessagesState)
236
+ builder.add_node("retriever", retriever)
237
+ builder.add_node("assistant", assistant)
238
+ builder.add_node("tools", ToolNode(tools))
239
+ builder.add_edge(START, "retriever")
240
+ builder.add_edge("retriever", "assistant")
241
+ builder.add_conditional_edges(
242
+ "assistant",
243
+ tools_condition,
244
+ )
245
+ builder.add_edge("tools", "assistant")
246
+
247
+ # Compile graph
248
+ return builder.compile()
249
+
250
+ # test
251
+ if __name__ == "__main__":
252
+ question = "When was a picture of St. Thomas Aquinas first added to the Wikipedia page on the Principle of double effect?"
253
+ # Build the graph
254
+ graph = build_graph(provider="groq")
255
+ # Run the graph
256
+ messages = [HumanMessage(content=question)]
257
+ messages = graph.invoke({"messages": messages})
258
+ for m in messages["messages"]:
259
+ m.pretty_print()
v2/scratch_agent/all_prompts.py ADDED
@@ -0,0 +1,108 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # import os
2
+
3
+
4
+ # SYSTEM_PROMPT = """
5
+ # You are an expert AI assistant named GameScratchAgent, specialized in generating and modifying Scratch-VM 3.x game project JSON.
6
+ # Your core task is to process game descriptions and existing Scratch JSON structures, then produce or update JSON segments accurately.
7
+ # You possess deep knowledge of Scratch 3.0 project schema, informed by comprehensive reference materials. When generating or modifying the `blocks` section, pay extremely close attention to the following:
8
+
9
+ # **Scratch Project JSON Schema Rules:**
10
+
11
+ # 1. **Target Structure (`project.json`'s `targets` array):**
12
+ # * Each object in the `targets` array represents a Stage or a Sprite.
13
+ # * `isStage`: A boolean indicating if the target is the Stage (`true`) or a Sprite (`false`).
14
+ # * `name`: The name of the Stage (e.g., `"Stage"`) or the Sprite (e.g., `"Cat"`). This property replaces `objName` found in older Scratch versions.
15
+ # * `variables` dictionary: This dictionary maps unique variable IDs to arrays `[variable_name, initial_value, isCloudVariable?]`.
16
+ # * `variable_name`: The user-defined name of the variable.
17
+ # * `initial_value`: The variable's initial value, which can be a number or a string.
18
+ # * `isCloudVariable?`: (Optional) A boolean indicating if it's a cloud variable (`true`) or a local variable (`false` or absent for regular variables).
19
+ # * Example: `"myVarId123": ["score", 0]`, `"cloudVarId456": ["☁ High Score", "54", true]`
20
+ # * `lists` dictionary: This dictionary maps unique list IDs to arrays `[list_name, [item1, item2, ...]]`.
21
+ # * Example: `"myListId789": ["my list", ["apple", "banana"]]`
22
+ # * `broadcasts` dictionary: This dictionary maps unique broadcast IDs to their names.
23
+ # * Example: `"myBroadcastId": "Game Over"`
24
+ # * `blocks` dictionary: This dictionary contains all the blocks belonging to this target. Keys are block IDs, values are block objects.
25
+
26
+ # 2. **Block Structure (within a `target`'s `blocks` dictionary):**
27
+ # * Every block object must have the following core properties:
28
+ # * [cite_start]`opcode`: A unique internal identifier for the block's specific functionality (e.g., `"motion_movesteps"`, `"event_whenflagclicked"`)[cite: 31, 18, 439, 452].
29
+ # * `parent`: The ID of the block directly above it in the script stack (or `null` for a top-level block).
30
+ # * `next`: The ID of the block directly below it in the script stack (or `null` for the end of a stack).
31
+ # * `inputs`: An object defining values or blocks plugged into the block's input slots. Values are **arrays**.
32
+ # * `fields`: An object defining dropdown menu selections or direct internal values within the block. Values are **arrays**.
33
+ # * `shadow`: `true` if it's a shadow block (e.g., a default number input that can be replaced by another block), `false` otherwise.
34
+ # * `topLevel`: `true` if it's a hat block or a standalone block (not connected to a parent), `false` otherwise.
35
+
36
+ # 3. **`inputs` Property Details (for blocks plugged into input slots):**
37
+ # * **Direct Block Connection (Reporter/Boolean block plugged in):**
38
+ # * Format: `"<INPUT_NAME>": [1, "<blockId_of_plugged_block>"]`
39
+ # * Example: `"CONDITION": [1, "someBooleanBlockId"]` (e.g., for an `if` block).
40
+ # * **Literal Value Input (Shadow block with a literal):**
41
+ # * Format: `"<INPUT_NAME>": [1, [<type_code>, "<value_string>"]]`
42
+ # * `type_code`: A numeric code representing the data type. Common codes include: `4` for number, `7` for string/text, `10` for string/message.
43
+ # * `value_string`: The literal value as a string.
44
+ # * Examples:
45
+ # * Number: `"STEPS": [1, [4, "10"]]` (for `move 10 steps` block).
46
+ # * String/Text: `"MESSAGE": [1, [7, "Hello"]]` (for `say Hello` block).
47
+ # * String/Message (common for text inputs): `"MESSAGE": [1, [10, "Hello!"]]` (for `say Hello! for 2 secs`).
48
+ # * **C-Block Substack (blocks within a loop or conditional):**
49
+ # * Format: `"<SUBSTACK_NAME>": [2, "<blockId_of_first_block_in_substack>"]`
50
+ # * Common `SUBSTACK_NAME` values are `SUBSTACK` (for `if`, `forever`, `repeat`) and `SUBSTACK2` (for `else` in `if else`).
51
+ # * Example: `"SUBSTACK": [2, "firstBlockInLoopId"]`
52
+
53
+ # 4. **`fields` Property Details (for dropdowns or direct internal values):**
54
+ # * Used for dropdown menus, variable names, list names, or other static selections directly within the block.
55
+ # * Format: `"<FIELD_NAME>": ["<selected_value>", null]`
56
+ # * Examples:
57
+ # * Dropdown: `"KEY_OPTION": ["space", null]` (for `when space key pressed`).
58
+ # * Variable Name: `"VARIABLE": ["score", null]` (for `set score to 0`).
59
+ # * Direction (specific motion block): `"FORWARD_BACKWARD": ["forward", null]` (for `go forward layers`).
60
+
61
+ # 5. **Unique IDs:**
62
+ # * All block IDs, variable IDs, and list IDs must be unique strings (e.g., "myBlock123", "myVarId456", "myListId789"). Do NOT use placeholder strings like "block_id_here".
63
+
64
+ # 6. **No Nested `blocks` Dictionary:**
65
+ # * The `blocks` dictionary should only appear once per `target` (sprite/stage). Do NOT nest a `blocks` dictionary inside an individual block definition. Blocks that are part of a substack are linked via the `SUBSTACK` input.
66
+
67
+ # 7. **Asset Properties (for Costumes/Sounds):**
68
+ # * `assetId`, `md5ext`, `bitmapResolution`, `rotationCenterX`/`rotationCenterY` should be correctly associated with costume and sound objects within the `costumes` and `sounds` arrays.
69
+
70
+ # **General Principles and Important Considerations:**
71
+ # * **Backward Compatibility:** Adhere strictly to existing Scratch 3.0 opcodes and schema to ensure backward compatibility with older projects. [cite_start]Opcodes must remain consistent to prevent previously saved projects from failing to load or behaving unexpectedly[cite: 18, 19, 25, 65].
72
+ # * **Forgiving Inputs:** Recognize that Scratch is designed to be "forgiving in its interpretation of inputs." [cite_start]The Scratch VM handles potentially "invalid" inputs gracefully (e.g., converting a number to a string if expected, returning default values like zero or empty strings, or performing no action) rather than crashing[cite: 20, 21, 22, 38, 39, 41]. This implies that precise type matching for inputs might be handled internally by Scratch, allowing for some flexibility in how values are provided, but the agent should aim for the most common and logical type.
73
+ # """
74
+
75
+ # SYSTEM_PROMPT_JSON_CORRECTOR ="""
76
+ # You are an assistant that outputs JSON responses strictly following the given schema.
77
+ # If the JSON you produce has any formatting errors, missing required fields, or invalid structure, you must identify the problems and correct them.
78
+ # Always return only valid JSON that fully conforms to the schema below, enclosed in triple backticks (```), without any extra text or explanation.
79
+
80
+ # If you receive an invalid or incomplete JSON response, fix it by:
81
+ # - Adding any missing required fields with appropriate values.
82
+ # - Correcting syntax errors such as missing commas, brackets, or quotes.
83
+ # - Ensuring the JSON structure matches the schema exactly.
84
+
85
+ # Remember: Your output must be valid JSON only, ready to be parsed without errors.
86
+ # """
87
+
88
+ # llm_query_prompt = f"""Based on the user's game description: '{state['description']}', \
89
+ # and the current Scratch project JSON below, \
90
+ # determine the most appropriate initial 'x' and 'y' coordinates for each sprite. \
91
+ # Return ONLY a JSON object with a single key 'sprite_initial_positions' mapping sprite names to their {{'x': int, 'y': int}} coordinates.
92
+
93
+ # The current Scratch project JSON is:
94
+ # ```json
95
+ # {json.dumps(state['project_json'], indent=2)}
96
+ # ```
97
+
98
+ # Example Json output:
99
+
100
+ # ```json
101
+ # {{
102
+ # "sprite_initial_positions": {{
103
+ # "Sprite1": {{"x": -160, "y": -110}},
104
+ # "Sprite2": {{"x": 240, "y": -135}}
105
+ # }}
106
+ # }}
107
+ # ```
108
+ # """
v2/scratch_agent/app.py ADDED
The diff for this file is too large to render. See raw diff
 
v2/scratch_agent/block_function.py ADDED
@@ -0,0 +1,1147 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import json
2
+ import copy
3
+ import re
4
+
5
+ def generate_blocks_from_opcodes(opcode_counts, all_block_definitions):
6
+ """
7
+ Generates a dictionary of Scratch-like blocks based on a list of opcodes and a reference block definition.
8
+ It now correctly links parent and menu blocks using their generated unique keys, and handles various block categories.
9
+ It ensures that menu blocks are only generated as children of their respective parent blocks.
10
+
11
+ Args:
12
+ opcode_counts (list): An array of objects, each with an 'opcode' and 'count' property.
13
+ Example: [{"opcode": "motion_gotoxy", "count": 1}]
14
+ all_block_definitions (dict): A comprehensive dictionary containing definitions for all block types.
15
+
16
+ Returns:
17
+ tuple: A tuple containing:
18
+ - dict: A JSON object where keys are generated block IDs and values are the block definitions.
19
+ - dict: The opcode_occurrences dictionary for consistent unique key generation across functions.
20
+ """
21
+ generated_blocks = {}
22
+ opcode_occurrences = {} # To keep track of how many times each opcode (main or menu) has been used for unique keys
23
+
24
+ # Define explicit parent-menu relationships for linking purposes
25
+ # This maps main_opcode -> list of (input_field_name, menu_opcode)
26
+ explicit_menu_links = {
27
+ "motion_goto": [("TO", "motion_goto_menu")],
28
+ "motion_glideto": [("TO", "motion_glideto_menu")],
29
+ "motion_pointtowards": [("TOWARDS", "motion_pointtowards_menu")],
30
+ "sensing_keypressed": [("KEY_OPTION", "sensing_keyoptions")],
31
+ "sensing_of": [("OBJECT", "sensing_of_object_menu")],
32
+ "sensing_touchingobject": [("TOUCHINGOBJECTMENU", "sensing_touchingobjectmenu")],
33
+ "control_create_clone_of": [("CLONE_OPTION", "control_create_clone_of_menu")],
34
+ "sound_play": [("SOUND_MENU", "sound_sounds_menu")],
35
+ "sound_playuntildone": [("SOUND_MENU", "sound_sounds_menu")],
36
+ "looks_switchcostumeto": [("COSTUME", "looks_costume")],
37
+ "looks_switchbackdropto": [("BACKDROP", "looks_backdrops")],
38
+ }
39
+
40
+ # --- Step 1: Process explicitly requested opcodes and generate their instances and associated menus ---
41
+ for item in opcode_counts:
42
+ opcode = item.get("opcode")
43
+ count = item.get("count", 1)
44
+
45
+ if not opcode:
46
+ print("Warning: Skipping item with missing 'opcode'.")
47
+ continue
48
+
49
+ if opcode not in all_block_definitions:
50
+ print(f"Warning: Opcode '{opcode}' not found in all_block_definitions. Skipping.")
51
+ continue
52
+
53
+ for _ in range(count):
54
+ # Increment occurrence count for the current main opcode
55
+ opcode_occurrences[opcode] = opcode_occurrences.get(opcode, 0) + 1
56
+ main_block_instance_num = opcode_occurrences[opcode]
57
+
58
+ main_block_unique_key = f"{opcode}_{main_block_instance_num}"
59
+
60
+ # Create a deep copy of the main block definition
61
+ main_block_data = copy.deepcopy(all_block_definitions[opcode])
62
+
63
+ # Set properties for a top-level main block
64
+ main_block_data["parent"] = None
65
+ main_block_data["next"] = None
66
+ main_block_data["topLevel"] = True
67
+ main_block_data["shadow"] = False # Main blocks are typically not shadows
68
+
69
+ generated_blocks[main_block_unique_key] = main_block_data
70
+
71
+ # If this main block has associated menus, generate and link them now
72
+ if opcode in explicit_menu_links:
73
+ for input_field_name, menu_opcode_type in explicit_menu_links[opcode]:
74
+ if menu_opcode_type in all_block_definitions:
75
+ # Increment the occurrence for the menu block type
76
+ opcode_occurrences[menu_opcode_type] = opcode_occurrences.get(menu_opcode_type, 0) + 1
77
+ menu_block_instance_num = opcode_occurrences[menu_opcode_type]
78
+
79
+ menu_block_data = copy.deepcopy(all_block_definitions[menu_opcode_type])
80
+
81
+ # Generate a unique key for this specific menu instance
82
+ menu_unique_key = f"{menu_opcode_type}_{menu_block_instance_num}"
83
+
84
+ # Set properties for a shadow menu block
85
+ menu_block_data["shadow"] = True
86
+ menu_block_data["topLevel"] = False
87
+ menu_block_data["next"] = None
88
+ menu_block_data["parent"] = main_block_unique_key # Link menu to its parent instance
89
+
90
+ # Update the main block's input to point to this unique menu instance
91
+ if input_field_name in main_block_data.get("inputs", {}) and \
92
+ isinstance(main_block_data["inputs"][input_field_name], list) and \
93
+ len(main_block_data["inputs"][input_field_name]) > 1 and \
94
+ main_block_data["inputs"][input_field_name][0] == 1:
95
+
96
+ main_block_data["inputs"][input_field_name][1] = menu_unique_key
97
+
98
+ generated_blocks[menu_unique_key] = menu_block_data
99
+
100
+ return generated_blocks, opcode_occurrences
101
+
102
+ def interpret_pseudo_code_and_update_blocks(generated_blocks_json, pseudo_code, all_block_definitions, opcode_occurrences):
103
+ """
104
+ Interprets pseudo-code to update the generated Scratch blocks, replacing static values
105
+ with dynamic values and establishing stacking/nesting logic.
106
+
107
+ Args:
108
+ generated_blocks_json (dict): The JSON object of pre-generated blocks.
109
+ pseudo_code (str): The pseudo-code string to interpret.
110
+ all_block_definitions (dict): A comprehensive dictionary containing definitions for all block types.
111
+ opcode_occurrences (dict): A dictionary to keep track of opcode occurrences for unique key generation.
112
+
113
+ Returns:
114
+ dict: The updated JSON object of Scratch blocks.
115
+ """
116
+ updated_blocks = copy.deepcopy(generated_blocks_json)
117
+
118
+ # Helper to find a block by opcode and optionally by a unique part of its key
119
+ def find_block_by_opcode(opcode_to_find, instance_num=None, parent_key=None):
120
+ for key, block in updated_blocks.items():
121
+ if block["opcode"] == opcode_to_find:
122
+ if instance_num is not None:
123
+ # Check if the key ends with the instance number
124
+ if key.endswith(f"_{instance_num}"):
125
+ return key, block
126
+ elif parent_key is not None:
127
+ # For menu blocks, check if their parent matches
128
+ if block.get("shadow") and block.get("parent") == parent_key:
129
+ return key, block
130
+ else:
131
+ # Return the first one found if no specific instance is needed
132
+ return key, block
133
+ return None, None
134
+
135
+ # Helper to get a unique key for a new block if needed
136
+ def get_unique_key(opcode_prefix):
137
+ count = 1
138
+ while f"{opcode_prefix}_{count}" in updated_blocks:
139
+ count += 1
140
+ return f"{opcode_prefix}_{count}"
141
+
142
+ lines = [line.strip() for line in pseudo_code.strip().split('\n') if line.strip()]
143
+
144
+ # Track the current script and nesting
145
+ current_script_head = None
146
+ current_parent_stack = [] # Stores (parent_block_key, indent_level, last_child_key)
147
+ indent_level = 0
148
+
149
+ # Create a mapping from block name patterns to their opcodes and input details
150
+ # Prioritize more specific patterns first
151
+ pseudo_code_to_opcode_map = {
152
+ re.compile(r"when green flag clicked"): {"opcode": "event_whenflagclicked"},
153
+ re.compile(r"go to x: \((.+?)\) y: \((.+?)\)"): {"opcode": "motion_gotoxy", "input_names": ["X", "Y"]},
154
+ re.compile(r"set \[(.+?) v\] to (.+)"): {"opcode": "data_setvariableto", "field_name": "VARIABLE", "input_name": "VALUE"},
155
+ re.compile(r"change \[(.+?) v\] by \((.+)\)"): {"opcode": "data_changevariableby", "field_name": "VARIABLE", "input_name": "VALUE"},
156
+ re.compile(r"show variable \[(.+?) v\]"): {"opcode": "data_showvariable", "field_name": "VARIABLE"},
157
+ re.compile(r"hide variable \[(.+?) v\]"): {"opcode": "data_hidevariable", "field_name": "VARIABLE"},
158
+ re.compile(r"forever"): {"opcode": "control_forever"},
159
+ re.compile(r"glide \((.+?)\) seconds to x: \((.+?)\) y: \((.+?)\)"): {"opcode": "motion_glidesecstoxy", "input_names": ["SECS", "X", "Y"]},
160
+ re.compile(r"if <\((.+)\) < \((.+)\)> then"): {"opcode": "control_if", "input_names": ["OPERAND1", "OPERAND2"], "condition_opcode": "operator_lt"},
161
+ re.compile(r"if <touching \[(.+?) v\]\?> then"): {"opcode": "control_if", "input_name": "TOUCHINGOBJECTMENU", "condition_opcode": "sensing_touchingobject"},
162
+ re.compile(r"set x to \((.+?)\)"): {"opcode": "motion_setx", "input_name": "X"},
163
+ re.compile(r"broadcast \[(.+?) v\]"): {"opcode": "event_broadcast", "input_name": "BROADCAST_INPUT"},
164
+ re.compile(r"stop \[(.+?) v\]"): {"opcode": "control_stop", "field_name": "STOP_OPTION"},
165
+ re.compile(r"end"): {"opcode": "end_block"}, # Special marker for script end/C-block end
166
+ }
167
+
168
+ # Create a reverse lookup for reporter block opcodes based on their pseudo-code representation
169
+ reporter_opcode_lookup = {}
170
+ for opcode, definition in all_block_definitions.items():
171
+ if definition.get("block_shape") == "Reporter Block":
172
+ block_name = definition.get("block_name")
173
+ if block_name:
174
+ # Remove parentheses for matching
175
+ clean_name = block_name.replace("(", "").replace(")", "").strip()
176
+ reporter_opcode_lookup[clean_name] = opcode
177
+ # Handle cases like "x position" vs "(x position)"
178
+ if clean_name not in reporter_opcode_lookup:
179
+ reporter_opcode_lookup[clean_name] = opcode
180
+
181
+ # Function to create a new block instance
182
+ def create_block_instance(opcode, opcode_occurrences, parent_key=None, is_shadow=False, is_top_level=False):
183
+ # Ensure unique key generation is consistent
184
+ opcode_occurrences[opcode] = opcode_occurrences.get(opcode, 0) + 1
185
+ unique_key = f"{opcode}_{opcode_occurrences[opcode]}"
186
+
187
+ new_block = copy.deepcopy(all_block_definitions.get(opcode, {}))
188
+ if not new_block:
189
+ print(f"Error: Definition for opcode '{opcode}' not found.")
190
+ return None, None
191
+
192
+ new_block["parent"] = parent_key
193
+ new_block["next"] = None # Will be set by stacking logic
194
+ new_block["topLevel"] = is_top_level
195
+ new_block["shadow"] = is_shadow
196
+
197
+ # Clear inputs/fields to be populated by pseudo-code parsing
198
+ if "inputs" in new_block:
199
+ new_block["inputs"] = {k: copy.deepcopy(v) for k, v in new_block["inputs"].items()} # Deep copy inputs
200
+ for input_name in new_block["inputs"]:
201
+ if isinstance(new_block["inputs"][input_name], list) and len(new_block["inputs"][input_name]) > 1:
202
+ # Reset input value, keep type 1 for block reference or type 4/10 for literal
203
+ if new_block["inputs"][input_name][0] == 1:
204
+ new_block["inputs"][input_name][1] = None # Placeholder for linked block ID
205
+ else:
206
+ new_block["inputs"][input_name][1] = ["", ""] # Default empty value
207
+ if "fields" in new_block:
208
+ new_block["fields"] = {k: copy.deepcopy(v) for k, v in new_block["fields"].items()} # Deep copy fields
209
+ for field_name in new_block["fields"]:
210
+ if isinstance(new_block["fields"][field_name], list) and len(new_block["fields"][field_name]) > 0:
211
+ new_block["fields"][field_name][0] = "" # Reset field value
212
+
213
+ updated_blocks[unique_key] = new_block
214
+ return unique_key, new_block
215
+
216
+ # Helper to parse input values
217
+ def parse_input_value(value_str):
218
+ value_str = value_str.strip()
219
+ # Handle numeric values (including those with + or - prefix)
220
+ if re.fullmatch(r"[-+]?\d+(\.\d+)?", value_str):
221
+ return [4, value_str] # Type 4 for number
222
+ # Handle string literals (e.g., "Hello!")
223
+ if value_str.startswith('"') and value_str.endswith('"'):
224
+ return [10, value_str.strip('"')] # Type 10 for string
225
+ # Handle variable/list names (e.g., [score v], [my list v])
226
+ if value_str.startswith('[') and value_str.endswith(']'):
227
+ var_name = value_str[1:-1].replace(' v', '').strip()
228
+ # For inputs that expect a variable, we might need a data_variable block
229
+ # For now, if it's a variable reference in an input, we'll return its name.
230
+ # The calling context (e.g., set variable's field vs. an input) will determine type.
231
+ return [12, var_name] # Custom type 12 for variable name, to be resolved later
232
+
233
+ # Handle nested reporter blocks (e.g., (x position))
234
+ if value_str.startswith('(') and value_str.endswith(')'):
235
+ inner_content = value_str[1:-1].strip()
236
+ # Check if it's a known reporter block
237
+ if inner_content in reporter_opcode_lookup:
238
+ return [3, reporter_opcode_lookup[inner_content]] # Type 3 for reporter block reference
239
+ # If not a known reporter, treat as a number or string
240
+ if re.fullmatch(r"[-+]?\d+(\.\d+)?", inner_content):
241
+ return [4, inner_content]
242
+ return [10, inner_content] # Default to string if not found in reporters
243
+
244
+ # Handle boolean conditions (e.g., <(x position) < (-235)>) - these are usually handled by parent regex
245
+ if value_str.startswith('<') and value_str.endswith('>'):
246
+ inner_condition = value_str[1:-1].strip()
247
+ # This is typically handled by the regex that matched the 'if' block itself.
248
+ # If this is called for a standalone boolean, it would be a reporter.
249
+ for op, def_ in all_block_definitions.items():
250
+ if def_.get("block_shape") == "Boolean Block" and def_.get("block_name") and \
251
+ def_["block_name"].replace("<", "").replace(">", "").strip() == inner_condition:
252
+ return [2, op] # Type 2 for boolean block reference
253
+ return [10, inner_condition] # Default to string if not found
254
+
255
+ return [10, value_str] # Default to string literal
256
+
257
+
258
+ # Main parsing loop
259
+ block_stack = [] # (block_key, indent_level, last_child_key_in_scope) for tracking nesting
260
+
261
+ for line_idx, raw_line in enumerate(lines):
262
+ current_line_indent = len(raw_line) - len(raw_line.lstrip())
263
+ line = raw_line.strip()
264
+
265
+ # Adjust block_stack based on current indent level
266
+ while block_stack and current_line_indent <= block_stack[-1][1]:
267
+ block_stack.pop()
268
+
269
+ matched_block_info = None
270
+ matched_values = None
271
+
272
+ # Try to match the line against known block patterns
273
+ for pattern_regex, info in pseudo_code_to_opcode_map.items():
274
+ match = pattern_regex.match(line)
275
+ if match:
276
+ matched_block_info = info
277
+ matched_values = match.groups()
278
+ break
279
+
280
+ if not matched_block_info:
281
+ print(f"Warning: Could not interpret line: '{line}'")
282
+ continue
283
+
284
+ opcode = matched_block_info["opcode"]
285
+
286
+ # Handle 'end' block separately as it signifies closing a C-block
287
+ if opcode == "end_block":
288
+ if block_stack:
289
+ block_stack.pop() # Pop the C-block parent
290
+ continue
291
+
292
+ parent_key = None
293
+ if block_stack:
294
+ parent_key = block_stack[-1][0] # The last block on the stack is the parent
295
+
296
+ # Create the new block instance
297
+ new_block_key, new_block_data = create_block_instance(
298
+ opcode,
299
+ opcode_occurrences,
300
+ parent_key=parent_key,
301
+ is_top_level=(parent_key is None)
302
+ )
303
+ if not new_block_key:
304
+ continue
305
+
306
+ # Link to previous block in the same script/nesting level
307
+ if block_stack:
308
+ # Update the 'next' of the previous block in the current scope
309
+ last_child_key_in_scope = block_stack[-1][2] if len(block_stack[-1]) > 2 else None
310
+ if last_child_key_in_scope and last_child_key_in_scope in updated_blocks:
311
+ updated_blocks[last_child_key_in_scope]["next"] = new_block_key
312
+
313
+ # Update the last child in the current scope
314
+ block_stack[-1] = (block_stack[-1][0], block_stack[-1][1], new_block_key)
315
+
316
+ # Populate inputs and fields
317
+ if matched_values:
318
+ # Handle specific block types with their inputs/fields
319
+ if opcode == "motion_gotoxy":
320
+ x_val = parse_input_value(matched_values[0])
321
+ y_val = parse_input_value(matched_values[1])
322
+ new_block_data["inputs"]["X"][1] = x_val[1]
323
+ new_block_data["inputs"]["Y"][1] = y_val[1]
324
+ new_block_data["inputs"]["X"][0] = x_val[0]
325
+ new_block_data["inputs"]["Y"][0] = y_val[0]
326
+ elif opcode == "data_setvariableto":
327
+ var_name = matched_values[0].replace(' v', '').strip()
328
+ value_parsed = parse_input_value(matched_values[1])
329
+ new_block_data["fields"]["VARIABLE"][0] = var_name
330
+ # Assuming variable ID is generated elsewhere or can be looked up
331
+ new_block_data["fields"]["VARIABLE"][1] = f"`var_{var_name}" # Placeholder for variable ID
332
+ new_block_data["inputs"]["VALUE"][0] = value_parsed[0]
333
+ new_block_data["inputs"]["VALUE"][1] = value_parsed[1]
334
+ elif opcode == "data_showvariable":
335
+ var_name = matched_values[0].replace(' v', '').strip()
336
+ new_block_data["fields"]["VARIABLE"][0] = var_name
337
+ new_block_data["fields"]["VARIABLE"][1] = f"`var_{var_name}" # Placeholder for variable ID
338
+ elif opcode == "motion_glidesecstoxy":
339
+ secs_val = parse_input_value(matched_values[0])
340
+ x_val = parse_input_value(matched_values[1])
341
+ y_val = parse_input_value(matched_values[2])
342
+ new_block_data["inputs"]["SECS"][1] = secs_val[1]
343
+ new_block_data["inputs"]["X"][1] = x_val[1]
344
+ new_block_data["inputs"]["Y"][1] = y_val[1]
345
+ new_block_data["inputs"]["SECS"][0] = secs_val[0]
346
+ new_block_data["inputs"]["X"][0] = x_val[0]
347
+ new_block_data["inputs"]["Y"][0] = y_val[0]
348
+ elif opcode == "motion_setx":
349
+ x_val = parse_input_value(matched_values[0])
350
+ new_block_data["inputs"]["X"][1] = x_val[1]
351
+ new_block_data["inputs"]["X"][0] = x_val[0]
352
+ elif opcode == "control_if":
353
+ condition_opcode = matched_block_info["condition_opcode"]
354
+
355
+ if condition_opcode == "operator_lt":
356
+ op1_str = matched_values[0].strip()
357
+ op2_str = matched_values[1].strip()
358
+
359
+ op1_parsed = parse_input_value(op1_str)
360
+ op2_parsed = parse_input_value(op2_str)
361
+
362
+ # Create operator_lt block as a shadow input for the IF condition
363
+ lt_block_key, lt_block_data = create_block_instance(
364
+ "operator_lt",
365
+ opcode_occurrences,
366
+ parent_key=new_block_key,
367
+ is_shadow=True,
368
+ is_top_level=False
369
+ )
370
+ if lt_block_key:
371
+ new_block_data["inputs"]["CONDITION"][1] = lt_block_key
372
+ new_block_data["inputs"]["CONDITION"][0] = 2 # Type 2 for boolean block reference
373
+
374
+ # Populate operator_lt inputs
375
+ if op1_parsed[0] == 3: # If it's a reporter block
376
+ op1_reporter_key, op1_reporter_data = create_block_instance(
377
+ op1_parsed[1], # Opcode of the reporter
378
+ opcode_occurrences,
379
+ parent_key=lt_block_key,
380
+ is_shadow=True,
381
+ is_top_level=False
382
+ )
383
+ if op1_reporter_key:
384
+ lt_block_data["inputs"]["OPERAND1"][1] = op1_reporter_key
385
+ lt_block_data["inputs"]["OPERAND1"][0] = 3
386
+ else: # Literal value
387
+ lt_block_data["inputs"]["OPERAND1"][1] = op1_parsed[1]
388
+ lt_block_data["inputs"]["OPERAND1"][0] = op1_parsed[0]
389
+
390
+ lt_block_data["inputs"]["OPERAND2"][1] = op2_parsed[1]
391
+ lt_block_data["inputs"]["OPERAND2"][0] = op2_parsed[0]
392
+
393
+ elif condition_opcode == "sensing_touchingobject":
394
+ sprite_name = matched_values[0].replace(' v', '').strip()
395
+ touching_opcode = "sensing_touchingobject"
396
+
397
+ touching_block_key, touching_block_data = create_block_instance(
398
+ touching_opcode,
399
+ opcode_occurrences,
400
+ parent_key=new_block_key,
401
+ is_shadow=True,
402
+ is_top_level=False
403
+ )
404
+ if touching_block_key:
405
+ new_block_data["inputs"]["CONDITION"][1] = touching_block_key
406
+ new_block_data["inputs"]["CONDITION"][0] = 2 # Type 2 for boolean block reference
407
+
408
+ # Create the menu block for TOUCHINGOBJECTMENU
409
+ menu_opcode = "sensing_touchingobjectmenu"
410
+ menu_key, menu_data = create_block_instance(
411
+ menu_opcode,
412
+ opcode_occurrences,
413
+ parent_key=touching_block_key,
414
+ is_shadow=True,
415
+ is_top_level=False
416
+ )
417
+ if menu_key:
418
+ touching_block_data["inputs"]["TOUCHINGOBJECTMENU"][1] = menu_key
419
+ touching_block_data["inputs"]["TOUCHINGOBJECTMENU"][0] = 1 # Type 1 for block reference
420
+ menu_data["fields"]["TOUCHINGOBJECTMENU"][0] = sprite_name
421
+ else:
422
+ print(f"Warning: Could not create touching object block for condition: '{line}'")
423
+
424
+
425
+ elif opcode == "control_forever":
426
+ # Forever blocks are C-blocks, so push them onto the stack
427
+ block_stack.append((new_block_key, current_line_indent, None)) # (parent_key, indent, last_child_key)
428
+ elif opcode == "control_stop":
429
+ option = matched_values[0].replace(' v', '').strip()
430
+ new_block_data["fields"]["STOP_OPTION"][0] = option
431
+ elif opcode == "event_broadcast":
432
+ message = matched_values[0].replace(' v', '').strip()
433
+ # For broadcast, the input is usually a string literal or a variable
434
+ new_block_data["inputs"]["BROADCAST_INPUT"][0] = 11 # Type 11 for broadcast input (string or variable)
435
+ new_block_data["inputs"]["BROADCAST_INPUT"][1] = [10, message] # Assume string literal for now
436
+ # A more robust solution would create a data_variable block if it's a variable.
437
+
438
+ # For C-blocks, push onto stack to track nesting
439
+ if all_block_definitions[opcode].get("block_shape") == "C-Block" and opcode != "control_if": # if is handled above
440
+ block_stack.append((new_block_key, current_line_indent, None)) # (parent_key, indent, last_child_key)
441
+
442
+
443
+ return updated_blocks
444
+
445
+ # --- Consolidated Block Definitions from all provided JSONs ---
446
+ all_block_definitions = {
447
+ # motion_block.json
448
+ "motion_movesteps": {
449
+ "opcode": "motion_movesteps", "next": None, "parent": None,
450
+ "inputs": {"STEPS": [1, [4, "10"]]}, "fields": {}, "shadow": False, "topLevel": True,
451
+ "x": 464, "y": -416
452
+ },
453
+ "motion_turnright": {
454
+ "opcode": "motion_turnright", "next": None, "parent": None,
455
+ "inputs": {"DEGREES": [1, [4, "15"]]}, "fields": {}, "shadow": False, "topLevel": True,
456
+ "x": 467, "y": -316
457
+ },
458
+ "motion_turnleft": {
459
+ "opcode": "motion_turnleft", "next": None, "parent": None,
460
+ "inputs": {"DEGREES": [1, [4, "15"]]}, "fields": {}, "shadow": False, "topLevel": True,
461
+ "x": 464, "y": -210
462
+ },
463
+ "motion_goto": {
464
+ "opcode": "motion_goto", "next": None, "parent": None,
465
+ "inputs": {"TO": [1, "motion_goto_menu"]}, "fields": {}, "shadow": False, "topLevel": True,
466
+ "x": 465, "y": -95
467
+ },
468
+ "motion_goto_menu": {
469
+ "opcode": "motion_goto_menu", "next": None, "parent": "motion_goto",
470
+ "inputs": {}, "fields": {"TO": ["_random_", None]}, "shadow": True, "topLevel": False
471
+ },
472
+ "motion_gotoxy": {
473
+ "opcode": "motion_gotoxy", "next": None, "parent": None,
474
+ "inputs": {"X": [1, [4, "0"]], "Y": [1, [4, "0"]]}, "fields": {}, "shadow": False, "topLevel": True,
475
+ "x": 468, "y": 12
476
+ },
477
+ "motion_glideto": {
478
+ "opcode": "motion_glideto", "next": None, "parent": None,
479
+ "inputs": {"SECS": [1, [4, "1"]], "TO": [1, "motion_glideto_menu"]}, "fields": {}, "shadow": False, "topLevel": True,
480
+ "x": 470, "y": 129
481
+ },
482
+ "motion_glideto_menu": {
483
+ "opcode": "motion_glideto_menu", "next": None, "parent": "motion_glideto",
484
+ "inputs": {}, "fields": {"TO": ["_random_", None]}, "shadow": True, "topLevel": False
485
+ },
486
+ "motion_glidesecstoxy": {
487
+ "opcode": "motion_glidesecstoxy", "next": None, "parent": None,
488
+ "inputs": {"SECS": [1, [4, "1"]], "X": [1, [4, "0"]], "Y": [1, [4, "0"]]}, "fields": {}, "shadow": False, "topLevel": True,
489
+ "x": 476, "y": 239
490
+ },
491
+ "motion_pointindirection": {
492
+ "opcode": "motion_pointindirection", "next": None, "parent": None,
493
+ "inputs": {"DIRECTION": [1, [8, "90"]]}, "fields": {}, "shadow": False, "topLevel": True,
494
+ "x": 493, "y": 361
495
+ },
496
+ "motion_pointtowards": {
497
+ "opcode": "motion_pointtowards", "next": None, "parent": None,
498
+ "inputs": {"TOWARDS": [1, "motion_pointtowards_menu"]}, "fields": {}, "shadow": False, "topLevel": True,
499
+ "x": 492, "y": 463
500
+ },
501
+ "motion_pointtowards_menu": {
502
+ "opcode": "motion_pointtowards_menu", "next": None, "parent": "motion_pointtowards",
503
+ "inputs": {}, "fields": {"TOWARDS": ["_mouse_", None]}, "shadow": True, "topLevel": False
504
+ },
505
+ "motion_changexby": {
506
+ "opcode": "motion_changexby", "next": None, "parent": None,
507
+ "inputs": {"DX": [1, [4, "10"]]}, "fields": {}, "shadow": False, "topLevel": True,
508
+ "x": 851, "y": -409
509
+ },
510
+ "motion_setx": {
511
+ "opcode": "motion_setx", "next": None, "parent": None,
512
+ "inputs": {"X": [1, [4, "0"]]}, "fields": {}, "shadow": False, "topLevel": True,
513
+ "x": 864, "y": -194
514
+ },
515
+ "motion_changeyby": {
516
+ "opcode": "motion_changeyby", "next": None, "parent": None,
517
+ "inputs": {"DY": [1, [4, "10"]]}, "fields": {}, "shadow": False, "topLevel": True,
518
+ "x": 861, "y": -61
519
+ },
520
+ "motion_sety": {
521
+ "opcode": "motion_sety", "next": None, "parent": None,
522
+ "inputs": {"Y": [1, [4, "0"]]}, "fields": {}, "shadow": False, "topLevel": True,
523
+ "x": 864, "y": 66
524
+ },
525
+ "motion_ifonedgebounce": {
526
+ "opcode": "motion_ifonedgebounce", "next": None, "parent": None,
527
+ "inputs": {}, "fields": {}, "shadow": False, "topLevel": True,
528
+ "x": 1131, "y": -397
529
+ },
530
+ "motion_setrotationstyle": {
531
+ "opcode": "motion_setrotationstyle", "next": None, "parent": None,
532
+ "inputs": {}, "fields": {"STYLE": ["left-right", None]}, "shadow": False, "topLevel": True,
533
+ "x": 1128, "y": -287
534
+ },
535
+ "motion_xposition": {
536
+ "opcode": "motion_xposition", "next": None, "parent": None,
537
+ "inputs": {}, "fields": {}, "shadow": False, "topLevel": True,
538
+ "x": 1193, "y": -136
539
+ },
540
+ "motion_yposition": {
541
+ "opcode": "motion_yposition", "next": None, "parent": None,
542
+ "inputs": {}, "fields": {}, "shadow": False, "topLevel": True,
543
+ "x": 1181, "y": -64
544
+ },
545
+ "motion_direction": {
546
+ "opcode": "motion_direction", "next": None, "parent": None,
547
+ "inputs": {}, "fields": {}, "shadow": False, "topLevel": True,
548
+ "x": 1188, "y": 21
549
+ },
550
+
551
+ # control_block.json
552
+ "control_wait": {
553
+ "opcode": "control_wait", "next": None, "parent": None,
554
+ "inputs": {"DURATION": [1, [5, "1"]]}, "fields": {}, "shadow": False, "topLevel": True,
555
+ "x": 337, "y": 129
556
+ },
557
+ "control_repeat": {
558
+ "opcode": "control_repeat", "next": None, "parent": None,
559
+ "inputs": {"TIMES": [1, [6, "10"]]}, "fields": {}, "shadow": False, "topLevel": True,
560
+ "x": 348, "y": 265
561
+ },
562
+ "control_forever": {
563
+ "opcode": "control_forever", "next": None, "parent": None,
564
+ "inputs": {}, "fields": {}, "shadow": False, "topLevel": True,
565
+ "x": 334, "y": 439
566
+ },
567
+ "control_if": {
568
+ "opcode": "control_if", "next": None, "parent": None,
569
+ "inputs": {}, "fields": {}, "shadow": False, "topLevel": True,
570
+ "x": 331, "y": 597
571
+ },
572
+ "control_if_else": {
573
+ "opcode": "control_if_else", "next": None, "parent": None,
574
+ "inputs": {}, "fields": {}, "shadow": False, "topLevel": True,
575
+ "x": 335, "y": 779
576
+ },
577
+ "control_wait_until": {
578
+ "opcode": "control_wait_until", "next": None, "parent": None,
579
+ "inputs": {}, "fields": {}, "shadow": False, "topLevel": True,
580
+ "x": 676, "y": 285
581
+ },
582
+ "control_repeat_until": {
583
+ "opcode": "control_repeat_until", "next": None, "parent": None,
584
+ "inputs": {}, "fields": {}, "shadow": False, "topLevel": True,
585
+ "x": 692, "y": 381
586
+ },
587
+ "control_stop": {
588
+ "opcode": "control_stop", "next": None, "parent": None,
589
+ "inputs": {}, "fields": {"STOP_OPTION": ["all", None]}, "shadow": False, "topLevel": True,
590
+ "x": 708, "y": 545, "mutation": {"tagName": "mutation", "children": [], "hasnext": "false"}
591
+ },
592
+ "control_start_as_clone": {
593
+ "opcode": "control_start_as_clone", "next": None, "parent": None,
594
+ "inputs": {}, "fields": {}, "shadow": False, "topLevel": True,
595
+ "x": 665, "y": 672
596
+ },
597
+ "control_create_clone_of": {
598
+ "opcode": "control_create_clone_of", "next": None, "parent": None,
599
+ "inputs": {"CLONE_OPTION": [1, "control_create_clone_of_menu"]}, "fields": {}, "shadow": False, "topLevel": True,
600
+ "x": 648, "y": 797
601
+ },
602
+ "control_create_clone_of_menu": {
603
+ "opcode": "control_create_clone_of_menu", "next": None, "parent": "control_create_clone_of",
604
+ "inputs": {}, "fields": {"CLONE_OPTION": ["_myself_", None]}, "shadow": True, "topLevel": False
605
+ },
606
+ "control_delete_this_clone": {
607
+ "opcode": "control_delete_this_clone", "next": None, "parent": None,
608
+ "inputs": {}, "fields": {}, "shadow": False, "topLevel": True,
609
+ "x": 642, "y": 914
610
+ },
611
+
612
+ # data_block.json
613
+ "data_setvariableto": {
614
+ "opcode": "data_setvariableto", "next": None, "parent": None,
615
+ "inputs": {"VALUE": [1, [10, "0"]]}, "fields": {"VARIABLE": ["my variable", "`jEk@4|i[#Fk?(8x)AV.-my variable"]}, "shadow": False, "topLevel": True,
616
+ "x": 348, "y": 241
617
+ },
618
+ "data_changevariableby": {
619
+ "opcode": "data_changevariableby", "next": None, "parent": None,
620
+ "inputs": {"VALUE": [1, [4, "1"]]}, "fields": {"VARIABLE": ["my variable", "`jEk@4|i[#Fk?(8x)AV.-my variable"]}, "shadow": False, "topLevel": True,
621
+ "x": 313, "y": 363
622
+ },
623
+ "data_showvariable": {
624
+ "opcode": "data_showvariable", "next": None, "parent": None,
625
+ "inputs": {}, "fields": {"VARIABLE": ["my variable", "`jEk@4|i[#Fk?(8x)AV.-my variable"]}, "shadow": False, "topLevel": True,
626
+ "x": 415, "y": 473
627
+ },
628
+ "data_hidevariable": {
629
+ "opcode": "data_hidevariable", "next": None, "parent": None,
630
+ "inputs": {}, "fields": {"VARIABLE": ["my variable", "`jEk@4|i[#Fk?(8x)AV.-my variable"]}, "shadow": False, "topLevel": True,
631
+ "x": 319, "y": 587
632
+ },
633
+ "data_addtolist": {
634
+ "opcode": "data_addtolist", "next": None, "parent": None,
635
+ "inputs": {"ITEM": [1, [10, "thing"]]}, "fields": {"LIST": ["MY_LIST", "o6`kIhtT{xWH+rX(5d,A"]}, "shadow": False, "topLevel": True,
636
+ "x": 385, "y": 109
637
+ },
638
+ "data_deleteoflist": {
639
+ "opcode": "data_deleteoflist", "next": None, "parent": None,
640
+ "inputs": {"INDEX": [1, [7, "1"]]}, "fields": {"LIST": ["MY_LIST", "o6`kIhtT{xWH+rX(5d,A"]}, "shadow": False, "topLevel": True,
641
+ "x": 384, "y": 244
642
+ },
643
+ "data_deletealloflist": {
644
+ "opcode": "data_deletealloflist", "next": None, "parent": None,
645
+ "inputs": {}, "fields": {"LIST": ["MY_LIST", "o6`kIhtT{xWH+rX(5d,A"]}, "shadow": False, "topLevel": True,
646
+ "x": 387, "y": 374
647
+ },
648
+ "data_insertatlist": {
649
+ "opcode": "data_insertatlist", "next": None, "parent": None,
650
+ "inputs": {"ITEM": [1, [10, "thing"]], "INDEX": [1, [7, "1"]]}, "fields": {"LIST": ["MY_LIST", "o6`kIhtT{xWH+rX(5d,A"]}, "shadow": False, "topLevel": True,
651
+ "x": 366, "y": 527
652
+ },
653
+ "data_replaceitemoflist": {
654
+ "opcode": "data_replaceitemoflist", "next": None, "parent": None,
655
+ "inputs": {"INDEX": [1, [7, "1"]], "ITEM": [1, [10, "thing"]]}, "fields": {"LIST": ["MY_LIST", "o6`kIhtT{xWH+rX(5d,A"]}, "shadow": False, "topLevel": True,
656
+ "x": 365, "y": 657
657
+ },
658
+ "data_itemoflist": {
659
+ "opcode": "data_itemoflist", "next": None, "parent": None,
660
+ "inputs": {"INDEX": [1, [7, "1"]]}, "fields": {"LIST": ["MY_LIST", "o6`kIhtT{xWH+rX(5d,A"]}, "shadow": False, "topLevel": True,
661
+ "x": 862, "y": 117
662
+ },
663
+ "data_itemnumoflist": {
664
+ "opcode": "data_itemnumoflist", "next": None, "parent": None,
665
+ "inputs": {"ITEM": [1, [10, "thing"]]}, "fields": {"LIST": ["MY_LIST", "o6`kIhtT{xWH+rX(5d,A"]}, "shadow": False, "topLevel": True,
666
+ "x": 883, "y": 238
667
+ },
668
+ "data_lengthoflist": {
669
+ "opcode": "data_lengthoflist", "next": None, "parent": None,
670
+ "inputs": {}, "fields": {"LIST": ["MY_LIST", "o6`kIhtT{xWH+rX(5d,A"]}, "shadow": False, "topLevel": True,
671
+ "x": 876, "y": 342
672
+ },
673
+ "data_listcontainsitem": {
674
+ "opcode": "data_listcontainsitem", "next": None, "parent": None,
675
+ "inputs": {"ITEM": [1, [10, "thing"]]}, "fields": {"LIST": ["MY_LIST", "o6`kIhtT{xWH+rX(5d,A"]}, "shadow": False, "topLevel": True,
676
+ "x": 871, "y": 463
677
+ },
678
+ "data_showlist": {
679
+ "opcode": "data_showlist", "next": None, "parent": None,
680
+ "inputs": {}, "fields": {"LIST": ["MY_LIST", "o6`kIhtT{xWH+rX(5d,A"]}, "shadow": False, "topLevel": True,
681
+ "x": 931, "y": 563
682
+ },
683
+ "data_hidelist": {
684
+ "opcode": "data_hidelist", "next": None, "parent": None,
685
+ "inputs": {}, "fields": {"LIST": ["MY_LIST", "o6`kIhtT{xWH+rX(5d,A"]}, "shadow": False, "topLevel": True,
686
+ "x": 962, "y": 716
687
+ },
688
+
689
+ # event_block.json
690
+ "event_whenflagclicked": {
691
+ "opcode": "event_whenflagclicked", "next": None, "parent": None,
692
+ "inputs": {}, "fields": {}, "shadow": False, "topLevel": True,
693
+ "x": 166, "y": -422
694
+ },
695
+ "event_whenkeypressed": {
696
+ "opcode": "event_whenkeypressed", "next": None, "parent": None,
697
+ "inputs": {}, "fields": {"KEY_OPTION": ["space", None]}, "shadow": False, "topLevel": True,
698
+ "x": 151, "y": -329
699
+ },
700
+ "event_whenthisspriteclicked": {
701
+ "opcode": "event_whenthisspriteclicked", "next": None, "parent": None,
702
+ "inputs": {}, "fields": {}, "shadow": False, "topLevel": True,
703
+ "x": 156, "y": -223
704
+ },
705
+ "event_whenbackdropswitchesto": {
706
+ "opcode": "event_whenbackdropswitchesto", "next": None, "parent": None,
707
+ "inputs": {}, "fields": {"BACKDROP": ["backdrop1", None]}, "shadow": False, "topLevel": True,
708
+ "x": 148, "y": -101
709
+ },
710
+ "event_whengreaterthan": {
711
+ "opcode": "event_whengreaterthan", "next": None, "parent": None,
712
+ "inputs": {"VALUE": [1, [4, "10"]]}, "fields": {"WHENGREATERTHANMENU": ["LOUDNESS", None]}, "shadow": False, "topLevel": True,
713
+ "x": 150, "y": 10
714
+ },
715
+ "event_whenbroadcastreceived": {
716
+ "opcode": "event_whenbroadcastreceived", "next": None, "parent": None,
717
+ "inputs": {}, "fields": {"BROADCAST_OPTION": ["message1", "5O!nei;S$!c!=hCT}0:a"]}, "shadow": False, "topLevel": True,
718
+ "x": 141, "y": 118
719
+ },
720
+ "event_broadcast": {
721
+ "opcode": "event_broadcast", "next": None, "parent": None,
722
+ "inputs": {"BROADCAST_INPUT": [1, [11, "message1", "5O!nei;S$!c!=hCT}0:a"]]}, "fields": {}, "shadow": False, "topLevel": True,
723
+ "x": 151, "y": 229
724
+ },
725
+ "event_broadcastandwait": {
726
+ "opcode": "event_broadcastandwait", "next": None, "parent": None,
727
+ "inputs": {"BROADCAST_INPUT": [1, [11, "message1", "5O!nei;S$!c!=hCT}0:a"]]}, "fields": {}, "shadow": False, "topLevel": True,
728
+ "x": 157, "y": 340
729
+ },
730
+
731
+ # look_block.json
732
+ "looks_sayforsecs": {
733
+ "opcode": "looks_sayforsecs", "next": None, "parent": None,
734
+ "inputs": {"MESSAGE": [1, [10, "Hello!"]], "SECS": [1, [4, "2"]]}, "fields": {}, "shadow": False, "topLevel": True,
735
+ "x": 408, "y": 91
736
+ },
737
+ "looks_say": {
738
+ "opcode": "looks_say", "next": None, "parent": None,
739
+ "inputs": {"MESSAGE": [1, [10, "Hello!"]]}, "fields": {}, "shadow": False, "topLevel": True,
740
+ "x": 413, "y": 213
741
+ },
742
+ "looks_thinkforsecs": {
743
+ "opcode": "looks_thinkforsecs", "next": None, "parent": None,
744
+ "inputs": {"MESSAGE": [1, [10, "Hmm..."]], "SECS": [1, [4, "2"]]}, "fields": {}, "shadow": False, "topLevel": True,
745
+ "x": 413, "y": 317
746
+ },
747
+ "looks_think": {
748
+ "opcode": "looks_think", "next": None, "parent": None,
749
+ "inputs": {"MESSAGE": [1, [10, "Hmm..."]]}, "fields": {}, "shadow": False, "topLevel": True,
750
+ "x": 412, "y": 432
751
+ },
752
+ "looks_switchcostumeto": {
753
+ "opcode": "looks_switchcostumeto", "next": None, "parent": None,
754
+ "inputs": {"COSTUME": [1, "8;bti4wv(iH9nkOacCJ|"]}, "fields": {}, "shadow": False, "topLevel": True,
755
+ "x": 411, "y": 555
756
+ },
757
+ "looks_costume": {
758
+ "opcode": "looks_costume", "next": None, "parent": "Q#a,6LPWHqo9-0Nu*[SV",
759
+ "inputs": {}, "fields": {"COSTUME": ["costume2", None]}, "shadow": True, "topLevel": False
760
+ },
761
+ "looks_nextcostume": {
762
+ "opcode": "looks_nextcostume", "next": None, "parent": None,
763
+ "inputs": {}, "fields": {}, "shadow": False, "topLevel": True,
764
+ "x": 419, "y": 687
765
+ },
766
+ "looks_switchbackdropto": {
767
+ "opcode": "looks_switchbackdropto", "next": None, "parent": None,
768
+ "inputs": {"BACKDROP": [1, "-?yeX}29V*wd6W:unW0i"]}, "fields": {}, "shadow": False, "topLevel": True,
769
+ "x": 901, "y": 91
770
+ },
771
+ "looks_backdrops": {
772
+ "opcode": "looks_backdrops", "next": None, "parent": "`Wm^p~l[(IWzc1|wNv*.",
773
+ "inputs": {}, "fields": {"BACKDROP": ["backdrop1", None]}, "shadow": True, "topLevel": False
774
+ },
775
+ "looks_changesizeby": {
776
+ "opcode": "looks_changesizeby", "next": None, "parent": None,
777
+ "inputs": {"CHANGE": [1, [4, "10"]]}, "fields": {}, "shadow": False, "topLevel": True,
778
+ "x": 895, "y": 192
779
+ },
780
+ "looks_setsizeto": {
781
+ "opcode": "looks_setsizeto", "next": None, "parent": None,
782
+ "inputs": {"SIZE": [1, [4, "100"]]}, "fields": {}, "shadow": False, "topLevel": True,
783
+ "x": 896, "y": 303
784
+ },
785
+ "looks_changeeffectby": {
786
+ "opcode": "looks_changeeffectby", "next": None, "parent": None,
787
+ "inputs": {"CHANGE": [1, [4, "25"]]}, "fields": {"EFFECT": ["COLOR", None]}, "shadow": False, "topLevel": True,
788
+ "x": 892, "y": 416
789
+ },
790
+ "looks_seteffectto": {
791
+ "opcode": "looks_seteffectto", "next": None, "parent": None,
792
+ "inputs": {"VALUE": [1, [4, "0"]]}, "fields": {"EFFECT": ["COLOR", None]}, "shadow": False, "topLevel": True,
793
+ "x": 902, "y": 527
794
+ },
795
+ "looks_cleargraphiceffects": {
796
+ "opcode": "looks_cleargraphiceffects", "next": None, "parent": None,
797
+ "inputs": {}, "fields": {}, "shadow": False, "topLevel": True,
798
+ "x": 902, "y": 638
799
+ },
800
+ "looks_show": {
801
+ "opcode": "looks_show", "next": None, "parent": None,
802
+ "inputs": {}, "fields": {}, "shadow": False, "topLevel": True,
803
+ "x": 908, "y": 758
804
+ },
805
+ "looks_hide": {
806
+ "opcode": "looks_hide", "next": None, "parent": None,
807
+ "inputs": {}, "fields": {}, "shadow": False, "topLevel": True,
808
+ "x": 455, "y": 861
809
+ },
810
+ "looks_gotofrontback": {
811
+ "opcode": "looks_gotofrontback", "next": None, "parent": None,
812
+ "inputs": {}, "fields": {"FRONT_BACK": ["front", None]}, "shadow": False, "topLevel": True,
813
+ "x": 853, "y": 878
814
+ },
815
+ "looks_goforwardbackwardlayers": {
816
+ "opcode": "looks_goforwardbackwardlayers", "next": None, "parent": None,
817
+ "inputs": {"NUM": [1, [7, "1"]]}, "fields": {"FORWARD_BACKWARD": ["forward", None]}, "shadow": False, "topLevel": True,
818
+ "x": 851, "y": 999
819
+ },
820
+ "looks_costumenumbername": {
821
+ "opcode": "looks_costumenumbername", "next": None, "parent": None,
822
+ "inputs": {}, "fields": {"NUMBER_NAME": ["number", None]}, "shadow": False, "topLevel": True,
823
+ "x": 458, "y": 1007
824
+ },
825
+ "looks_backdropnumbername": {
826
+ "opcode": "looks_backdropnumbername", "next": None, "parent": None,
827
+ "inputs": {}, "fields": {"NUMBER_NAME": ["number", None]}, "shadow": False, "topLevel": True,
828
+ "x": 1242, "y": 753
829
+ },
830
+ "looks_size": {
831
+ "opcode": "looks_size", "next": None, "parent": None,
832
+ "inputs": {}, "fields": {}, "shadow": False, "topLevel": True,
833
+ "x": 1249, "y": 876
834
+ },
835
+
836
+ # operator_block.json
837
+ "operator_add": {
838
+ "opcode": "operator_add", "next": None, "parent": None,
839
+ "inputs": {"NUM1": [1, [4, ""]], "NUM2": [1, [4, ""]]}, "fields": {}, "shadow": False, "topLevel": True,
840
+ "x": 128, "y": 153
841
+ },
842
+ "operator_subtract": {
843
+ "opcode": "operator_subtract", "next": None, "parent": None,
844
+ "inputs": {"NUM1": [1, [4, ""]], "NUM2": [1, [4, ""]]}, "fields": {}, "shadow": False, "topLevel": True,
845
+ "x": 134, "y": 214
846
+ },
847
+ "operator_multiply": {
848
+ "opcode": "operator_multiply", "next": None, "parent": None,
849
+ "inputs": {"NUM1": [1, [4, ""]], "NUM2": [1, [4, ""]]}, "fields": {}, "shadow": False, "topLevel": True,
850
+ "x": 134, "y": 278
851
+ },
852
+ "operator_divide": {
853
+ "opcode": "operator_divide", "next": None, "parent": None,
854
+ "inputs": {"NUM1": [1, [4, ""]], "NUM2": [1, [4, ""]]}, "fields": {}, "shadow": False, "topLevel": True,
855
+ "x": 138, "y": 359
856
+ },
857
+ "operator_random": {
858
+ "opcode": "operator_random", "next": None, "parent": None,
859
+ "inputs": {"FROM": [1, [4, "1"]], "TO": [1, [4, "10"]]}, "fields": {}, "shadow": False, "topLevel": True,
860
+ "x": 311, "y": 157
861
+ },
862
+ "operator_gt": {
863
+ "opcode": "operator_gt", "next": None, "parent": None,
864
+ "inputs": {"OPERAND1": [1, [10, ""]], "OPERAND2": [1, [10, "50"]]}, "fields": {}, "shadow": False, "topLevel": True,
865
+ "x": 348, "y": 217
866
+ },
867
+ "operator_lt": {
868
+ "opcode": "operator_lt", "next": None, "parent": None,
869
+ "inputs": {"OPERAND1": [1, [10, ""]], "OPERAND2": [1, [10, "50"]]}, "fields": {}, "shadow": False, "topLevel": True,
870
+ "x": 345, "y": 286
871
+ },
872
+ "operator_equals": {
873
+ "opcode": "operator_equals", "next": None, "parent": None,
874
+ "inputs": {"OPERAND1": [1, [10, ""]], "OPERAND2": [1, [10, "50"]]}, "fields": {}, "shadow": False, "topLevel": True,
875
+ "x": 345, "y": 372
876
+ },
877
+ "operator_and": {
878
+ "opcode": "operator_and", "next": None, "parent": None,
879
+ "inputs": {}, "fields": {}, "shadow": False, "topLevel": True,
880
+ "x": 701, "y": 158
881
+ },
882
+ "operator_or": {
883
+ "opcode": "operator_or", "next": None, "parent": None,
884
+ "inputs": {}, "fields": {}, "shadow": False, "topLevel": True,
885
+ "x": 705, "y": 222
886
+ },
887
+ "operator_not": {
888
+ "opcode": "operator_not", "next": None, "parent": None,
889
+ "inputs": {}, "fields": {}, "shadow": False, "topLevel": True,
890
+ "x": 734, "y": 283
891
+ },
892
+ "operator_join": {
893
+ "opcode": "operator_join", "next": None, "parent": None,
894
+ "inputs": {"STRING1": [1, [10, "apple "]], "STRING2": [1, [10, "banana"]]}, "fields": {}, "shadow": False, "topLevel": True,
895
+ "x": 663, "y": 378
896
+ },
897
+ "operator_letter_of": {
898
+ "opcode": "operator_letter_of", "next": None, "parent": None,
899
+ "inputs": {"LETTER": [1, [6, "1"]], "STRING": [1, [10, "apple"]]}, "fields": {}, "shadow": False, "topLevel": True,
900
+ "x": 664, "y": 445
901
+ },
902
+ "operator_length": {
903
+ "opcode": "operator_length", "next": None, "parent": None,
904
+ "inputs": {"STRING": [1, [10, "apple"]]}, "fields": {}, "shadow": False, "topLevel": True,
905
+ "x": 664, "y": 521
906
+ },
907
+ "operator_contains": {
908
+ "opcode": "operator_contains", "next": None, "parent": None,
909
+ "inputs": {"STRING1": [1, [10, "apple"]], "STRING2": [1, [10, "a"]]}, "fields": {}, "shadow": False, "topLevel": True,
910
+ "x": 634, "y": 599
911
+ },
912
+ "operator_mod": {
913
+ "opcode": "operator_mod", "next": None, "parent": None,
914
+ "inputs": {"NUM1": [1, [4, ""]], "NUM2": [1, [4, ""]]}, "fields": {}, "shadow": False, "topLevel": True,
915
+ "x": 295, "y": 594
916
+ },
917
+ "operator_round": {
918
+ "opcode": "operator_round", "next": None, "parent": None,
919
+ "inputs": {"NUM": [1, [4, ""]]}, "fields": {}, "shadow": False, "topLevel": True,
920
+ "x": 307, "y": 674
921
+ },
922
+ "operator_mathop": {
923
+ "opcode": "operator_mathop", "next": None, "parent": None,
924
+ "inputs": {"NUM": [1, [4, ""]]}, "fields": {"OPERATOR": ["abs", None]}, "shadow": False, "topLevel": True,
925
+ "x": 280, "y": 754
926
+ },
927
+
928
+ # sensing_block.json
929
+ "sensing_touchingobject": {
930
+ "opcode": "sensing_touchingobject", "next": None, "parent": None,
931
+ "inputs": {"TOUCHINGOBJECTMENU": [1, "sensing_touchingobjectmenu"]}, "fields": {}, "shadow": False, "topLevel": True,
932
+ "x": 359, "y": 116
933
+ },
934
+ "sensing_touchingobjectmenu": {
935
+ "opcode": "sensing_touchingobjectmenu", "next": None, "parent": "sensing_touchingobject",
936
+ "inputs": {}, "fields": {"TOUCHINGOBJECTMENU": ["_mouse_", None]}, "shadow": True, "topLevel": False
937
+ },
938
+ "sensing_touchingcolor": {
939
+ "opcode": "sensing_touchingcolor", "next": None, "parent": None,
940
+ "inputs": {"COLOR": [1, [9, "#55b888"]]}, "fields": {}, "shadow": False, "topLevel": True,
941
+ "x": 360, "y": 188
942
+ },
943
+ "sensing_coloristouchingcolor": {
944
+ "opcode": "sensing_coloristouchingcolor", "next": None, "parent": None,
945
+ "inputs": {"COLOR": [1, [9, "#d019f2"]], "COLOR2": [1, [9, "#2b0de3"]]}, "fields": {}, "shadow": False, "topLevel": True,
946
+ "x": 348, "y": 277
947
+ },
948
+ "sensing_askandwait": {
949
+ "opcode": "sensing_askandwait", "next": None, "parent": None,
950
+ "inputs": {"QUESTION": [1, [10, "What's your name?"]]}, "fields": {}, "shadow": False, "topLevel": True,
951
+ "x": 338, "y": 354
952
+ },
953
+ "sensing_answer": {
954
+ "opcode": "sensing_answer", "next": None, "parent": None,
955
+ "inputs": {}, "fields": {}, "shadow": False, "topLevel": True,
956
+ "x": 782, "y": 111
957
+ },
958
+ "sensing_keypressed": {
959
+ "opcode": "sensing_keypressed", "next": None, "parent": None,
960
+ "inputs": {"KEY_OPTION": [1, "sensing_keyoptions"]}, "fields": {}, "shadow": False, "topLevel": True,
961
+ "x": 762, "y": 207
962
+ },
963
+ "sensing_keyoptions": {
964
+ "opcode": "sensing_keyoptions", "next": None, "parent": "sensing_keypressed",
965
+ "inputs": {}, "fields": {"KEY_OPTION": ["space", None]}, "shadow": True, "topLevel": False
966
+ },
967
+ "sensing_mousedown": {
968
+ "opcode": "sensing_mousedown", "next": None, "parent": None,
969
+ "inputs": {}, "fields": {}, "shadow": False, "topLevel": True,
970
+ "x": 822, "y": 422
971
+ },
972
+ "sensing_mousex": {
973
+ "opcode": "sensing_mousex", "next": None, "parent": None,
974
+ "inputs": {}, "fields": {}, "shadow": False, "topLevel": True,
975
+ "x": 302, "y": 528
976
+ },
977
+ "sensing_mousey": {
978
+ "opcode": "sensing_mousey", "next": None, "parent": None,
979
+ "inputs": {}, "fields": {}, "shadow": False, "topLevel": True,
980
+ "x": 668, "y": 547
981
+ },
982
+ "sensing_setdragmode": {
983
+ "opcode": "sensing_setdragmode", "next": None, "parent": None,
984
+ "inputs": {}, "fields": {"DRAG_MODE": ["draggable", None]}, "shadow": False, "topLevel": True,
985
+ "x": 950, "y": 574
986
+ },
987
+ "sensing_loudness": {
988
+ "opcode": "sensing_loudness", "next": None, "parent": None,
989
+ "inputs": {}, "fields": {}, "shadow": False, "topLevel": True,
990
+ "x": 658, "y": 703
991
+ },
992
+ "sensing_timer": {
993
+ "opcode": "sensing_timer", "next": None, "parent": None,
994
+ "inputs": {}, "fields": {}, "shadow": False, "topLevel": True,
995
+ "x": 459, "y": 671
996
+ },
997
+ "sensing_resettimer": {
998
+ "opcode": "sensing_resettimer", "next": None, "parent": None,
999
+ "inputs": {}, "fields": {}, "shadow": False, "topLevel": True,
1000
+ "x": 462, "y": 781
1001
+ },
1002
+ "sensing_of": {
1003
+ "opcode": "sensing_of", "next": None, "parent": None,
1004
+ "inputs": {"OBJECT": [1, "sensing_of_object_menu"]}, "fields": {"PROPERTY": ["backdrop #", None]}, "shadow": False, "topLevel": True,
1005
+ "x": 997, "y": 754
1006
+ },
1007
+ "sensing_of_object_menu": {
1008
+ "opcode": "sensing_of_object_menu", "next": None, "parent": "sensing_of",
1009
+ "inputs": {}, "fields": {"OBJECT": ["_stage_", None]}, "shadow": True, "topLevel": False
1010
+ },
1011
+ "sensing_current": {
1012
+ "opcode": "sensing_current", "next": None, "parent": None,
1013
+ "inputs": {}, "fields": {"CURRENTMENU": ["YEAR", None]}, "shadow": False, "topLevel": True,
1014
+ "x": 627, "y": 884
1015
+ },
1016
+ "sensing_dayssince2000": {
1017
+ "opcode": "sensing_dayssince2000", "next": None, "parent": None,
1018
+ "inputs": {}, "fields": {}, "shadow": False, "topLevel": True,
1019
+ "x": 959, "y": 903
1020
+ },
1021
+ "sensing_username": {
1022
+ "opcode": "sensing_username", "next": None, "parent": None,
1023
+ "inputs": {}, "fields": {}, "shadow": False, "topLevel": True,
1024
+ "x": 833, "y": 757
1025
+ },
1026
+
1027
+ # sound_block.json
1028
+ "sound_playuntildone": {
1029
+ "opcode": "sound_playuntildone", "next": None, "parent": None,
1030
+ "inputs": {"SOUND_MENU": [1, "sound_sounds_menu"]}, "fields": {}, "shadow": False, "topLevel": True,
1031
+ "x": 253, "y": 17
1032
+ },
1033
+ "sound_sounds_menu": {
1034
+ "opcode": "sound_sounds_menu", "next": None, "parent": "sound_playuntildone and sound_play",
1035
+ "inputs": {}, "fields": {"SOUND_MENU": ["Meow", None]}, "shadow": True, "topLevel": False
1036
+ },
1037
+ "sound_play": {
1038
+ "opcode": "sound_play", "next": None, "parent": None,
1039
+ "inputs": {"SOUND_MENU": [1, "sound_sounds_menu"]}, "fields": {}, "shadow": False, "topLevel": True,
1040
+ "x": 245, "y": 122
1041
+ },
1042
+ "sound_stopallsounds": {
1043
+ "opcode": "sound_stopallsounds", "next": None, "parent": None,
1044
+ "inputs": {}, "fields": {}, "shadow": False, "topLevel": True,
1045
+ "x": 253, "y": 245
1046
+ },
1047
+ "sound_changeeffectby": {
1048
+ "opcode": "sound_changeeffectby", "next": None, "parent": None,
1049
+ "inputs": {"VALUE": [1, [4, "10"]]}, "fields": {"EFFECT": ["PITCH", None]}, "shadow": False, "topLevel": True,
1050
+ "x": 653, "y": 14
1051
+ },
1052
+ "sound_seteffectto": {
1053
+ "opcode": "sound_seteffectto", "next": None, "parent": None,
1054
+ "inputs": {"VALUE": [1, [4, "100"]]}, "fields": {"EFFECT": ["PITCH", None]}, "shadow": False, "topLevel": True,
1055
+ "x": 653, "y": 139
1056
+ },
1057
+ "sound_cleareffects": {
1058
+ "opcode": "sound_cleareffects", "next": None, "parent": None,
1059
+ "inputs": {}, "fields": {}, "shadow": False, "topLevel": True,
1060
+ "x": 651, "y": 242
1061
+ },
1062
+ "sound_changevolumeby": {
1063
+ "opcode": "sound_changevolumeby", "next": None, "parent": None,
1064
+ "inputs": {"VOLUME": [1, [4, "-10"]]}, "fields": {}, "shadow": False, "topLevel": True,
1065
+ "x": 645, "y": 353
1066
+ },
1067
+ "sound_setvolumeto": {
1068
+ "opcode": "sound_setvolumeto", "next": None, "parent": None,
1069
+ "inputs": {"VOLUME": [1, [4, "100"]]}, "fields": {}, "shadow": False, "topLevel": True,
1070
+ "x": 1108, "y": 5
1071
+ },
1072
+ "sound_volume": {
1073
+ "opcode": "sound_volume", "next": None, "parent": None,
1074
+ "inputs": {}, "fields": {}, "shadow": False, "topLevel": True,
1075
+ "x": 1136, "y": 123
1076
+ },
1077
+ }
1078
+
1079
+ # #Example input with opcodes from various categories
1080
+ # input_opcodes = [
1081
+ # {"opcode": "sound_play", "count": 2}, # New: Sound block with menu
1082
+ # {"opcode": "sound_playuntildone", "count": 2}, # New: Sound block with menu
1083
+ # ]
1084
+
1085
+ # Example input with opcodes from various categories
1086
+ # input_opcodes = [
1087
+ # {"opcode": "sound_play", "count": 2},
1088
+ # {"opcode": "sound_playuntildone", "count": 2},
1089
+ # {"opcode":"motion_goto","count":2},
1090
+ # {"opcode":"motion_glideto","count":2},
1091
+ # {"opcode":"looks_switchbackdropto","count":2},
1092
+ # {"opcode":"looks_switchcostumeto","count":2},
1093
+ # {"opcode":"control_create_clone_of","count":2},
1094
+ # {"opcode":"sensing_touchingobject","count":2},
1095
+ # {"opcode":"sensing_of","count":2},
1096
+ # {"opcode":"sensing_keypressed","count":2},
1097
+ # {"opcode":"motion_pointtowards","count":2},
1098
+ # ]
1099
+
1100
+ # generated_output = generate_blocks_from_opcodes(input_opcodes, all_block_definitions)
1101
+ # print(json.dumps(generated_output, indent=2))
1102
+
1103
+ initial_opcode_counts = [
1104
+ {"opcode":"event_whenflagclicked","count":1},
1105
+ {"opcode":"motion_gotoxy","count":1},
1106
+ {"opcode":"motion_glidesecstoxy","count":1},
1107
+ {"opcode":"motion_xposition","count":1},
1108
+ {"opcode":"motion_setx","count":1},
1109
+ {"opcode":"control_forever","count":1},
1110
+ {"opcode":"control_if","count":1},
1111
+ {"opcode":"control_stop","count":1},
1112
+ {"opcode":"operator_lt","count":1},
1113
+ {"opcode":"sensing_istouching","count":1},
1114
+ {"opcode":"sensing_touchingobjectmenu","count":1}, # This will now be generated as a child of sensing_touchingobject
1115
+ {"opcode":"event_broadcast","count":1},
1116
+ {"opcode":"data_setvariableto","count":2},
1117
+ {"opcode":"data_showvariable","count":2},
1118
+ ]
1119
+
1120
+ # Generate the initial blocks and get the opcode_occurrences
1121
+ generated_output_json, initial_opcode_occurrences = generate_blocks_from_opcodes(initial_opcode_counts, all_block_definitions)
1122
+
1123
+ # Pseudo-code to interpret
1124
+ pseudo_code_input = """
1125
+ when green flag clicked
1126
+ go to x: (240) y: (-135)
1127
+ set [score v] to +1
1128
+ set [speed v] to +1
1129
+ show variable [score v]
1130
+ show variable [speed v]
1131
+ forever
1132
+ glide (2) seconds to x: (-240) y: (-135)
1133
+ if <((x position)) < (-235)> then
1134
+ set x to (240)
1135
+ end
1136
+ if <touching [Sprite1 v]?> then
1137
+ broadcast [Game Over v]
1138
+ stop [all v]
1139
+ end
1140
+ end
1141
+ end
1142
+ """
1143
+
1144
+ # Interpret the pseudo-code and update the blocks, passing opcode_occurrences
1145
+ final_generated_blocks = interpret_pseudo_code_and_update_blocks(generated_output_json, pseudo_code_input, all_block_definitions, initial_opcode_occurrences)
1146
+
1147
+ print(json.dumps(final_generated_blocks, indent=2))
v2/scratch_agent/block_function_v1.py ADDED
@@ -0,0 +1,759 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import json
2
+ import copy
3
+
4
+ import json
5
+ import copy
6
+
7
+ def generate_blocks_from_opcodes(opcode_counts, all_block_definitions):
8
+ """
9
+ Generates a dictionary of Scratch-like blocks based on a list of opcodes and a reference block definition.
10
+ It now correctly links parent and menu blocks using their generated unique keys, and handles various block categories.
11
+ It ensures that menu blocks are only generated as children of their respective parent blocks.
12
+
13
+ Args:
14
+ opcode_counts (list): An array of objects, each with an 'opcode' and 'count' property.
15
+ Example: [{"opcode": "motion_gotoxy", "count": 1}]
16
+ all_block_definitions (dict): A comprehensive dictionary containing definitions for all block types.
17
+
18
+ Returns:
19
+ dict: A JSON object where keys are generated block IDs and values are the block definitions.
20
+ """
21
+ generated_blocks = {}
22
+ opcode_occurrences = {} # To keep track of how many times each opcode (main or menu) has been used for unique keys
23
+
24
+ # Define explicit parent-menu relationships for linking purposes
25
+ # This maps main_opcode -> list of (input_field_name, menu_opcode)
26
+ explicit_menu_links = {
27
+ "motion_goto": [("TO", "motion_goto_menu")],
28
+ "motion_glideto": [("TO", "motion_glideto_menu")],
29
+ "motion_pointtowards": [("TOWARDS", "motion_pointtowards_menu")],
30
+ "sensing_keypressed": [("KEY_OPTION", "sensing_keyoptions")],
31
+ "sensing_of": [("OBJECT", "sensing_of_object_menu")],
32
+ "sensing_touchingobject": [("TOUCHINGOBJECTMENU", "sensing_touchingobjectmenu")],
33
+ "control_create_clone_of": [("CLONE_OPTION", "control_create_clone_of_menu")],
34
+ "sound_play": [("SOUND_MENU", "sound_sounds_menu")],
35
+ "sound_playuntildone": [("SOUND_MENU", "sound_sounds_menu")],
36
+ "looks_switchcostumeto": [("COSTUME", "looks_costume")],
37
+ "looks_switchbackdropto": [("BACKDROP", "looks_backdrops")],
38
+ }
39
+
40
+ # --- Step 1: Process explicitly requested opcodes and generate their instances and associated menus ---
41
+ for item in opcode_counts:
42
+ opcode = item.get("opcode")
43
+ count = item.get("count", 1)
44
+
45
+ if not opcode:
46
+ print("Warning: Skipping item with missing 'opcode'.")
47
+ continue
48
+
49
+ if opcode not in all_block_definitions:
50
+ print(f"Warning: Opcode '{opcode}' not found in all_block_definitions. Skipping.")
51
+ continue
52
+
53
+ for _ in range(count):
54
+ # Increment occurrence count for the current main opcode
55
+ opcode_occurrences[opcode] = opcode_occurrences.get(opcode, 0) + 1
56
+ main_block_instance_num = opcode_occurrences[opcode]
57
+
58
+ main_block_unique_key = f"{opcode}_{main_block_instance_num}"
59
+
60
+ # Create a deep copy of the main block definition
61
+ main_block_data = copy.deepcopy(all_block_definitions[opcode])
62
+
63
+ # Set properties for a top-level main block
64
+ main_block_data["parent"] = None
65
+ main_block_data["next"] = None
66
+ main_block_data["topLevel"] = True
67
+ main_block_data["shadow"] = False # Main blocks are typically not shadows
68
+
69
+ generated_blocks[main_block_unique_key] = main_block_data
70
+
71
+ # If this main block has associated menus, generate and link them now
72
+ if opcode in explicit_menu_links:
73
+ for input_field_name, menu_opcode_type in explicit_menu_links[opcode]:
74
+ if menu_opcode_type in all_block_definitions:
75
+ # Increment the occurrence for the menu block type
76
+ opcode_occurrences[menu_opcode_type] = opcode_occurrences.get(menu_opcode_type, 0) + 1
77
+ menu_block_instance_num = opcode_occurrences[menu_opcode_type]
78
+
79
+ menu_block_data = copy.deepcopy(all_block_definitions[menu_opcode_type])
80
+
81
+ # Generate a unique key for this specific menu instance
82
+ menu_unique_key = f"{menu_opcode_type}_{menu_block_instance_num}"
83
+
84
+ # Set properties for a shadow menu block
85
+ menu_block_data["shadow"] = True
86
+ menu_block_data["topLevel"] = False
87
+ menu_block_data["next"] = None
88
+ menu_block_data["parent"] = main_block_unique_key # Link menu to its parent instance
89
+
90
+ # Update the main block's input to point to this unique menu instance
91
+ if input_field_name in main_block_data.get("inputs", {}) and \
92
+ isinstance(main_block_data["inputs"][input_field_name], list) and \
93
+ len(main_block_data["inputs"][input_field_name]) > 1 and \
94
+ main_block_data["inputs"][input_field_name][0] == 1:
95
+
96
+ main_block_data["inputs"][input_field_name][1] = menu_unique_key
97
+
98
+ generated_blocks[menu_unique_key] = menu_block_data
99
+
100
+ return generated_blocks
101
+
102
+
103
+ # --- Consolidated Block Definitions from all provided JSONs ---
104
+ all_block_definitions = {
105
+ # motion_block.json
106
+ "motion_movesteps": {
107
+ "opcode": "motion_movesteps", "next": None, "parent": None,
108
+ "inputs": {"STEPS": [1, [4, "10"]]}, "fields": {}, "shadow": False, "topLevel": True,
109
+ "x": 464, "y": -416
110
+ },
111
+ "motion_turnright": {
112
+ "opcode": "motion_turnright", "next": None, "parent": None,
113
+ "inputs": {"DEGREES": [1, [4, "15"]]}, "fields": {}, "shadow": False, "topLevel": True,
114
+ "x": 467, "y": -316
115
+ },
116
+ "motion_turnleft": {
117
+ "opcode": "motion_turnleft", "next": None, "parent": None,
118
+ "inputs": {"DEGREES": [1, [4, "15"]]}, "fields": {}, "shadow": False, "topLevel": True,
119
+ "x": 464, "y": -210
120
+ },
121
+ "motion_goto": {
122
+ "opcode": "motion_goto", "next": None, "parent": None,
123
+ "inputs": {"TO": [1, "motion_goto_menu"]}, "fields": {}, "shadow": False, "topLevel": True,
124
+ "x": 465, "y": -95
125
+ },
126
+ "motion_goto_menu": {
127
+ "opcode": "motion_goto_menu", "next": None, "parent": "motion_goto",
128
+ "inputs": {}, "fields": {"TO": ["_random_", None]}, "shadow": True, "topLevel": False
129
+ },
130
+ "motion_gotoxy": {
131
+ "opcode": "motion_gotoxy", "next": None, "parent": None,
132
+ "inputs": {"X": [1, [4, "0"]], "Y": [1, [4, "0"]]}, "fields": {}, "shadow": False, "topLevel": True,
133
+ "x": 468, "y": 12
134
+ },
135
+ "motion_glideto": {
136
+ "opcode": "motion_glideto", "next": None, "parent": None,
137
+ "inputs": {"SECS": [1, [4, "1"]], "TO": [1, "motion_glideto_menu"]}, "fields": {}, "shadow": False, "topLevel": True,
138
+ "x": 470, "y": 129
139
+ },
140
+ "motion_glideto_menu": {
141
+ "opcode": "motion_glideto_menu", "next": None, "parent": "motion_glideto",
142
+ "inputs": {}, "fields": {"TO": ["_random_", None]}, "shadow": True, "topLevel": False
143
+ },
144
+ "motion_glidesecstoxy": {
145
+ "opcode": "motion_glidesecstoxy", "next": None, "parent": None,
146
+ "inputs": {"SECS": [1, [4, "1"]], "X": [1, [4, "0"]], "Y": [1, [4, "0"]]}, "fields": {}, "shadow": False, "topLevel": True,
147
+ "x": 476, "y": 239
148
+ },
149
+ "motion_pointindirection": {
150
+ "opcode": "motion_pointindirection", "next": None, "parent": None,
151
+ "inputs": {"DIRECTION": [1, [8, "90"]]}, "fields": {}, "shadow": False, "topLevel": True,
152
+ "x": 493, "y": 361
153
+ },
154
+ "motion_pointtowards": {
155
+ "opcode": "motion_pointtowards", "next": None, "parent": None,
156
+ "inputs": {"TOWARDS": [1, "motion_pointtowards_menu"]}, "fields": {}, "shadow": False, "topLevel": True,
157
+ "x": 492, "y": 463
158
+ },
159
+ "motion_pointtowards_menu": {
160
+ "opcode": "motion_pointtowards_menu", "next": None, "parent": "motion_pointtowards",
161
+ "inputs": {}, "fields": {"TOWARDS": ["_mouse_", None]}, "shadow": True, "topLevel": False
162
+ },
163
+ "motion_changexby": {
164
+ "opcode": "motion_changexby", "next": None, "parent": None,
165
+ "inputs": {"DX": [1, [4, "10"]]}, "fields": {}, "shadow": False, "topLevel": True,
166
+ "x": 851, "y": -409
167
+ },
168
+ "motion_setx": {
169
+ "opcode": "motion_setx", "next": None, "parent": None,
170
+ "inputs": {"X": [1, [4, "0"]]}, "fields": {}, "shadow": False, "topLevel": True,
171
+ "x": 864, "y": -194
172
+ },
173
+ "motion_changeyby": {
174
+ "opcode": "motion_changeyby", "next": None, "parent": None,
175
+ "inputs": {"DY": [1, [4, "10"]]}, "fields": {}, "shadow": False, "topLevel": True,
176
+ "x": 861, "y": -61
177
+ },
178
+ "motion_sety": {
179
+ "opcode": "motion_sety", "next": None, "parent": None,
180
+ "inputs": {"Y": [1, [4, "0"]]}, "fields": {}, "shadow": False, "topLevel": True,
181
+ "x": 864, "y": 66
182
+ },
183
+ "motion_ifonedgebounce": {
184
+ "opcode": "motion_ifonedgebounce", "next": None, "parent": None,
185
+ "inputs": {}, "fields": {}, "shadow": False, "topLevel": True,
186
+ "x": 1131, "y": -397
187
+ },
188
+ "motion_setrotationstyle": {
189
+ "opcode": "motion_setrotationstyle", "next": None, "parent": None,
190
+ "inputs": {}, "fields": {"STYLE": ["left-right", None]}, "shadow": False, "topLevel": True,
191
+ "x": 1128, "y": -287
192
+ },
193
+ "motion_xposition": {
194
+ "opcode": "motion_xposition", "next": None, "parent": None,
195
+ "inputs": {}, "fields": {}, "shadow": False, "topLevel": True,
196
+ "x": 1193, "y": -136
197
+ },
198
+ "motion_yposition": {
199
+ "opcode": "motion_yposition", "next": None, "parent": None,
200
+ "inputs": {}, "fields": {}, "shadow": False, "topLevel": True,
201
+ "x": 1181, "y": -64
202
+ },
203
+ "motion_direction": {
204
+ "opcode": "motion_direction", "next": None, "parent": None,
205
+ "inputs": {}, "fields": {}, "shadow": False, "topLevel": True,
206
+ "x": 1188, "y": 21
207
+ },
208
+
209
+ # control_block.json
210
+ "control_wait": {
211
+ "opcode": "control_wait", "next": None, "parent": None,
212
+ "inputs": {"DURATION": [1, [5, "1"]]}, "fields": {}, "shadow": False, "topLevel": True,
213
+ "x": 337, "y": 129
214
+ },
215
+ "control_repeat": {
216
+ "opcode": "control_repeat", "next": None, "parent": None,
217
+ "inputs": {"TIMES": [1, [6, "10"]]}, "fields": {}, "shadow": False, "topLevel": True,
218
+ "x": 348, "y": 265
219
+ },
220
+ "control_forever": {
221
+ "opcode": "control_forever", "next": None, "parent": None,
222
+ "inputs": {}, "fields": {}, "shadow": False, "topLevel": True,
223
+ "x": 334, "y": 439
224
+ },
225
+ "control_if": {
226
+ "opcode": "control_if", "next": None, "parent": None,
227
+ "inputs": {}, "fields": {}, "shadow": False, "topLevel": True,
228
+ "x": 331, "y": 597
229
+ },
230
+ "control_if_else": {
231
+ "opcode": "control_if_else", "next": None, "parent": None,
232
+ "inputs": {}, "fields": {}, "shadow": False, "topLevel": True,
233
+ "x": 335, "y": 779
234
+ },
235
+ "control_wait_until": {
236
+ "opcode": "control_wait_until", "next": None, "parent": None,
237
+ "inputs": {}, "fields": {}, "shadow": False, "topLevel": True,
238
+ "x": 676, "y": 285
239
+ },
240
+ "control_repeat_until": {
241
+ "opcode": "control_repeat_until", "next": None, "parent": None,
242
+ "inputs": {}, "fields": {}, "shadow": False, "topLevel": True,
243
+ "x": 692, "y": 381
244
+ },
245
+ "control_stop": {
246
+ "opcode": "control_stop", "next": None, "parent": None,
247
+ "inputs": {}, "fields": {"STOP_OPTION": ["all", None]}, "shadow": False, "topLevel": True,
248
+ "x": 708, "y": 545, "mutation": {"tagName": "mutation", "children": [], "hasnext": "false"}
249
+ },
250
+ "control_start_as_clone": {
251
+ "opcode": "control_start_as_clone", "next": None, "parent": None,
252
+ "inputs": {}, "fields": {}, "shadow": False, "topLevel": True,
253
+ "x": 665, "y": 672
254
+ },
255
+ "control_create_clone_of": {
256
+ "opcode": "control_create_clone_of", "next": None, "parent": None,
257
+ "inputs": {"CLONE_OPTION": [1, "control_create_clone_of_menu"]}, "fields": {}, "shadow": False, "topLevel": True,
258
+ "x": 648, "y": 797
259
+ },
260
+ "control_create_clone_of_menu": {
261
+ "opcode": "control_create_clone_of_menu", "next": None, "parent": "control_create_clone_of",
262
+ "inputs": {}, "fields": {"CLONE_OPTION": ["_myself_", None]}, "shadow": True, "topLevel": False
263
+ },
264
+ "control_delete_this_clone": {
265
+ "opcode": "control_delete_this_clone", "next": None, "parent": None,
266
+ "inputs": {}, "fields": {}, "shadow": False, "topLevel": True,
267
+ "x": 642, "y": 914
268
+ },
269
+
270
+ # data_block.json
271
+ "data_setvariableto": {
272
+ "opcode": "data_setvariableto", "next": None, "parent": None,
273
+ "inputs": {"VALUE": [1, [10, "0"]]}, "fields": {"VARIABLE": ["my variable", "`jEk@4|i[#Fk?(8x)AV.-my variable"]}, "shadow": False, "topLevel": True,
274
+ "x": 348, "y": 241
275
+ },
276
+ "data_changevariableby": {
277
+ "opcode": "data_changevariableby", "next": None, "parent": None,
278
+ "inputs": {"VALUE": [1, [4, "1"]]}, "fields": {"VARIABLE": ["my variable", "`jEk@4|i[#Fk?(8x)AV.-my variable"]}, "shadow": False, "topLevel": True,
279
+ "x": 313, "y": 363
280
+ },
281
+ "data_showvariable": {
282
+ "opcode": "data_showvariable", "next": None, "parent": None,
283
+ "inputs": {}, "fields": {"VARIABLE": ["my variable", "`jEk@4|i[#Fk?(8x)AV.-my variable"]}, "shadow": False, "topLevel": True,
284
+ "x": 415, "y": 473
285
+ },
286
+ "data_hidevariable": {
287
+ "opcode": "data_hidevariable", "next": None, "parent": None,
288
+ "inputs": {}, "fields": {"VARIABLE": ["my variable", "`jEk@4|i[#Fk?(8x)AV.-my variable"]}, "shadow": False, "topLevel": True,
289
+ "x": 319, "y": 587
290
+ },
291
+ "data_addtolist": {
292
+ "opcode": "data_addtolist", "next": None, "parent": None,
293
+ "inputs": {"ITEM": [1, [10, "thing"]]}, "fields": {"LIST": ["MY_LIST", "o6`kIhtT{xWH+rX(5d,A"]}, "shadow": False, "topLevel": True,
294
+ "x": 385, "y": 109
295
+ },
296
+ "data_deleteoflist": {
297
+ "opcode": "data_deleteoflist", "next": None, "parent": None,
298
+ "inputs": {"INDEX": [1, [7, "1"]]}, "fields": {"LIST": ["MY_LIST", "o6`kIhtT{xWH+rX(5d,A"]}, "shadow": False, "topLevel": True,
299
+ "x": 384, "y": 244
300
+ },
301
+ "data_deletealloflist": {
302
+ "opcode": "data_deletealloflist", "next": None, "parent": None,
303
+ "inputs": {}, "fields": {"LIST": ["MY_LIST", "o6`kIhtT{xWH+rX(5d,A"]}, "shadow": False, "topLevel": True,
304
+ "x": 387, "y": 374
305
+ },
306
+ "data_insertatlist": {
307
+ "opcode": "data_insertatlist", "next": None, "parent": None,
308
+ "inputs": {"ITEM": [1, [10, "thing"]], "INDEX": [1, [7, "1"]]}, "fields": {"LIST": ["MY_LIST", "o6`kIhtT{xWH+rX(5d,A"]}, "shadow": False, "topLevel": True,
309
+ "x": 366, "y": 527
310
+ },
311
+ "data_replaceitemoflist": {
312
+ "opcode": "data_replaceitemoflist", "next": None, "parent": None,
313
+ "inputs": {"INDEX": [1, [7, "1"]], "ITEM": [1, [10, "thing"]]}, "fields": {"LIST": ["MY_LIST", "o6`kIhtT{xWH+rX(5d,A"]}, "shadow": False, "topLevel": True,
314
+ "x": 365, "y": 657
315
+ },
316
+ "data_itemoflist": {
317
+ "opcode": "data_itemoflist", "next": None, "parent": None,
318
+ "inputs": {"INDEX": [1, [7, "1"]]}, "fields": {"LIST": ["MY_LIST", "o6`kIhtT{xWH+rX(5d,A"]}, "shadow": False, "topLevel": True,
319
+ "x": 862, "y": 117
320
+ },
321
+ "data_itemnumoflist": {
322
+ "opcode": "data_itemnumoflist", "next": None, "parent": None,
323
+ "inputs": {"ITEM": [1, [10, "thing"]]}, "fields": {"LIST": ["MY_LIST", "o6`kIhtT{xWH+rX(5d,A"]}, "shadow": False, "topLevel": True,
324
+ "x": 883, "y": 238
325
+ },
326
+ "data_lengthoflist": {
327
+ "opcode": "data_lengthoflist", "next": None, "parent": None,
328
+ "inputs": {}, "fields": {"LIST": ["MY_LIST", "o6`kIhtT{xWH+rX(5d,A"]}, "shadow": False, "topLevel": True,
329
+ "x": 876, "y": 342
330
+ },
331
+ "data_listcontainsitem": {
332
+ "opcode": "data_listcontainsitem", "next": None, "parent": None,
333
+ "inputs": {"ITEM": [1, [10, "thing"]]}, "fields": {"LIST": ["MY_LIST", "o6`kIhtT{xWH+rX(5d,A"]}, "shadow": False, "topLevel": True,
334
+ "x": 871, "y": 463
335
+ },
336
+ "data_showlist": {
337
+ "opcode": "data_showlist", "next": None, "parent": None,
338
+ "inputs": {}, "fields": {"LIST": ["MY_LIST", "o6`kIhtT{xWH+rX(5d,A"]}, "shadow": False, "topLevel": True,
339
+ "x": 931, "y": 563
340
+ },
341
+ "data_hidelist": {
342
+ "opcode": "data_hidelist", "next": None, "parent": None,
343
+ "inputs": {}, "fields": {"LIST": ["MY_LIST", "o6`kIhtT{xWH+rX(5d,A"]}, "shadow": False, "topLevel": True,
344
+ "x": 962, "y": 716
345
+ },
346
+
347
+ # event_block.json
348
+ "event_whenflagclicked": {
349
+ "opcode": "event_whenflagclicked", "next": None, "parent": None,
350
+ "inputs": {}, "fields": {}, "shadow": False, "topLevel": True,
351
+ "x": 166, "y": -422
352
+ },
353
+ "event_whenkeypressed": {
354
+ "opcode": "event_whenkeypressed", "next": None, "parent": None,
355
+ "inputs": {}, "fields": {"KEY_OPTION": ["space", None]}, "shadow": False, "topLevel": True,
356
+ "x": 151, "y": -329
357
+ },
358
+ "event_whenthisspriteclicked": {
359
+ "opcode": "event_whenthisspriteclicked", "next": None, "parent": None,
360
+ "inputs": {}, "fields": {}, "shadow": False, "topLevel": True,
361
+ "x": 156, "y": -223
362
+ },
363
+ "event_whenbackdropswitchesto": {
364
+ "opcode": "event_whenbackdropswitchesto", "next": None, "parent": None,
365
+ "inputs": {}, "fields": {"BACKDROP": ["backdrop1", None]}, "shadow": False, "topLevel": True,
366
+ "x": 148, "y": -101
367
+ },
368
+ "event_whengreaterthan": {
369
+ "opcode": "event_whengreaterthan", "next": None, "parent": None,
370
+ "inputs": {"VALUE": [1, [4, "10"]]}, "fields": {"WHENGREATERTHANMENU": ["LOUDNESS", None]}, "shadow": False, "topLevel": True,
371
+ "x": 150, "y": 10
372
+ },
373
+ "event_whenbroadcastreceived": {
374
+ "opcode": "event_whenbroadcastreceived", "next": None, "parent": None,
375
+ "inputs": {}, "fields": {"BROADCAST_OPTION": ["message1", "5O!nei;S$!c!=hCT}0:a"]}, "shadow": False, "topLevel": True,
376
+ "x": 141, "y": 118
377
+ },
378
+ "event_broadcast": {
379
+ "opcode": "event_broadcast", "next": None, "parent": None,
380
+ "inputs": {"BROADCAST_INPUT": [1, [11, "message1", "5O!nei;S$!c!=hCT}0:a"]]}, "fields": {}, "shadow": False, "topLevel": True,
381
+ "x": 151, "y": 229
382
+ },
383
+ "event_broadcastandwait": {
384
+ "opcode": "event_broadcastandwait", "next": None, "parent": None,
385
+ "inputs": {"BROADCAST_INPUT": [1, [11, "message1", "5O!nei;S$!c!=hCT}0:a"]]}, "fields": {}, "shadow": False, "topLevel": True,
386
+ "x": 157, "y": 340
387
+ },
388
+
389
+ # look_block.json
390
+ "looks_sayforsecs": {
391
+ "opcode": "looks_sayforsecs", "next": None, "parent": None,
392
+ "inputs": {"MESSAGE": [1, [10, "Hello!"]], "SECS": [1, [4, "2"]]}, "fields": {}, "shadow": False, "topLevel": True,
393
+ "x": 408, "y": 91
394
+ },
395
+ "looks_say": {
396
+ "opcode": "looks_say", "next": None, "parent": None,
397
+ "inputs": {"MESSAGE": [1, [10, "Hello!"]]}, "fields": {}, "shadow": False, "topLevel": True,
398
+ "x": 413, "y": 213
399
+ },
400
+ "looks_thinkforsecs": {
401
+ "opcode": "looks_thinkforsecs", "next": None, "parent": None,
402
+ "inputs": {"MESSAGE": [1, [10, "Hmm..."]], "SECS": [1, [4, "2"]]}, "fields": {}, "shadow": False, "topLevel": True,
403
+ "x": 413, "y": 317
404
+ },
405
+ "looks_think": {
406
+ "opcode": "looks_think", "next": None, "parent": None,
407
+ "inputs": {"MESSAGE": [1, [10, "Hmm..."]]}, "fields": {}, "shadow": False, "topLevel": True,
408
+ "x": 412, "y": 432
409
+ },
410
+ "looks_switchcostumeto": {
411
+ "opcode": "looks_switchcostumeto", "next": None, "parent": None,
412
+ "inputs": {"COSTUME": [1, "8;bti4wv(iH9nkOacCJ|"]}, "fields": {}, "shadow": False, "topLevel": True,
413
+ "x": 411, "y": 555
414
+ },
415
+ "looks_costume": {
416
+ "opcode": "looks_costume", "next": None, "parent": "Q#a,6LPWHqo9-0Nu*[SV",
417
+ "inputs": {}, "fields": {"COSTUME": ["costume2", None]}, "shadow": True, "topLevel": False
418
+ },
419
+ "looks_nextcostume": {
420
+ "opcode": "looks_nextcostume", "next": None, "parent": None,
421
+ "inputs": {}, "fields": {}, "shadow": False, "topLevel": True,
422
+ "x": 419, "y": 687
423
+ },
424
+ "looks_switchbackdropto": {
425
+ "opcode": "looks_switchbackdropto", "next": None, "parent": None,
426
+ "inputs": {"BACKDROP": [1, "-?yeX}29V*wd6W:unW0i"]}, "fields": {}, "shadow": False, "topLevel": True,
427
+ "x": 901, "y": 91
428
+ },
429
+ "looks_backdrops": {
430
+ "opcode": "looks_backdrops", "next": None, "parent": "`Wm^p~l[(IWzc1|wNv*.",
431
+ "inputs": {}, "fields": {"BACKDROP": ["backdrop1", None]}, "shadow": True, "topLevel": False
432
+ },
433
+ "looks_changesizeby": {
434
+ "opcode": "looks_changesizeby", "next": None, "parent": None,
435
+ "inputs": {"CHANGE": [1, [4, "10"]]}, "fields": {}, "shadow": False, "topLevel": True,
436
+ "x": 895, "y": 192
437
+ },
438
+ "looks_setsizeto": {
439
+ "opcode": "looks_setsizeto", "next": None, "parent": None,
440
+ "inputs": {"SIZE": [1, [4, "100"]]}, "fields": {}, "shadow": False, "topLevel": True,
441
+ "x": 896, "y": 303
442
+ },
443
+ "looks_changeeffectby": {
444
+ "opcode": "looks_changeeffectby", "next": None, "parent": None,
445
+ "inputs": {"CHANGE": [1, [4, "25"]]}, "fields": {"EFFECT": ["COLOR", None]}, "shadow": False, "topLevel": True,
446
+ "x": 892, "y": 416
447
+ },
448
+ "looks_seteffectto": {
449
+ "opcode": "looks_seteffectto", "next": None, "parent": None,
450
+ "inputs": {"VALUE": [1, [4, "0"]]}, "fields": {"EFFECT": ["COLOR", None]}, "shadow": False, "topLevel": True,
451
+ "x": 902, "y": 527
452
+ },
453
+ "looks_cleargraphiceffects": {
454
+ "opcode": "looks_cleargraphiceffects", "next": None, "parent": None,
455
+ "inputs": {}, "fields": {}, "shadow": False, "topLevel": True,
456
+ "x": 902, "y": 638
457
+ },
458
+ "looks_show": {
459
+ "opcode": "looks_show", "next": None, "parent": None,
460
+ "inputs": {}, "fields": {}, "shadow": False, "topLevel": True,
461
+ "x": 908, "y": 758
462
+ },
463
+ "looks_hide": {
464
+ "opcode": "looks_hide", "next": None, "parent": None,
465
+ "inputs": {}, "fields": {}, "shadow": False, "topLevel": True,
466
+ "x": 455, "y": 861
467
+ },
468
+ "looks_gotofrontback": {
469
+ "opcode": "looks_gotofrontback", "next": None, "parent": None,
470
+ "inputs": {}, "fields": {"FRONT_BACK": ["front", None]}, "shadow": False, "topLevel": True,
471
+ "x": 853, "y": 878
472
+ },
473
+ "looks_goforwardbackwardlayers": {
474
+ "opcode": "looks_goforwardbackwardlayers", "next": None, "parent": None,
475
+ "inputs": {"NUM": [1, [7, "1"]]}, "fields": {"FORWARD_BACKWARD": ["forward", None]}, "shadow": False, "topLevel": True,
476
+ "x": 851, "y": 999
477
+ },
478
+ "looks_costumenumbername": {
479
+ "opcode": "looks_costumenumbername", "next": None, "parent": None,
480
+ "inputs": {}, "fields": {"NUMBER_NAME": ["number", None]}, "shadow": False, "topLevel": True,
481
+ "x": 458, "y": 1007
482
+ },
483
+ "looks_backdropnumbername": {
484
+ "opcode": "looks_backdropnumbername", "next": None, "parent": None,
485
+ "inputs": {}, "fields": {"NUMBER_NAME": ["number", None]}, "shadow": False, "topLevel": True,
486
+ "x": 1242, "y": 753
487
+ },
488
+ "looks_size": {
489
+ "opcode": "looks_size", "next": None, "parent": None,
490
+ "inputs": {}, "fields": {}, "shadow": False, "topLevel": True,
491
+ "x": 1249, "y": 876
492
+ },
493
+
494
+ # operator_block.json
495
+ "operator_add": {
496
+ "opcode": "operator_add", "next": None, "parent": None,
497
+ "inputs": {"NUM1": [1, [4, ""]], "NUM2": [1, [4, ""]]}, "fields": {}, "shadow": False, "topLevel": True,
498
+ "x": 128, "y": 153
499
+ },
500
+ "operator_subtract": {
501
+ "opcode": "operator_subtract", "next": None, "parent": None,
502
+ "inputs": {"NUM1": [1, [4, ""]], "NUM2": [1, [4, ""]]}, "fields": {}, "shadow": False, "topLevel": True,
503
+ "x": 134, "y": 214
504
+ },
505
+ "operator_multiply": {
506
+ "opcode": "operator_multiply", "next": None, "parent": None,
507
+ "inputs": {"NUM1": [1, [4, ""]], "NUM2": [1, [4, ""]]}, "fields": {}, "shadow": False, "topLevel": True,
508
+ "x": 134, "y": 278
509
+ },
510
+ "operator_divide": {
511
+ "opcode": "operator_divide", "next": None, "parent": None,
512
+ "inputs": {"NUM1": [1, [4, ""]], "NUM2": [1, [4, ""]]}, "fields": {}, "shadow": False, "topLevel": True,
513
+ "x": 138, "y": 359
514
+ },
515
+ "operator_random": {
516
+ "opcode": "operator_random", "next": None, "parent": None,
517
+ "inputs": {"FROM": [1, [4, "1"]], "TO": [1, [4, "10"]]}, "fields": {}, "shadow": False, "topLevel": True,
518
+ "x": 311, "y": 157
519
+ },
520
+ "operator_gt": {
521
+ "opcode": "operator_gt", "next": None, "parent": None,
522
+ "inputs": {"OPERAND1": [1, [10, ""]], "OPERAND2": [1, [10, "50"]]}, "fields": {}, "shadow": False, "topLevel": True,
523
+ "x": 348, "y": 217
524
+ },
525
+ "operator_lt": {
526
+ "opcode": "operator_lt", "next": None, "parent": None,
527
+ "inputs": {"OPERAND1": [1, [10, ""]], "OPERAND2": [1, [10, "50"]]}, "fields": {}, "shadow": False, "topLevel": True,
528
+ "x": 345, "y": 286
529
+ },
530
+ "operator_equals": {
531
+ "opcode": "operator_equals", "next": None, "parent": None,
532
+ "inputs": {"OPERAND1": [1, [10, ""]], "OPERAND2": [1, [10, "50"]]}, "fields": {}, "shadow": False, "topLevel": True,
533
+ "x": 345, "y": 372
534
+ },
535
+ "operator_and": {
536
+ "opcode": "operator_and", "next": None, "parent": None,
537
+ "inputs": {}, "fields": {}, "shadow": False, "topLevel": True,
538
+ "x": 701, "y": 158
539
+ },
540
+ "operator_or": {
541
+ "opcode": "operator_or", "next": None, "parent": None,
542
+ "inputs": {}, "fields": {}, "shadow": False, "topLevel": True,
543
+ "x": 705, "y": 222
544
+ },
545
+ "operator_not": {
546
+ "opcode": "operator_not", "next": None, "parent": None,
547
+ "inputs": {}, "fields": {}, "shadow": False, "topLevel": True,
548
+ "x": 734, "y": 283
549
+ },
550
+ "operator_join": {
551
+ "opcode": "operator_join", "next": None, "parent": None,
552
+ "inputs": {"STRING1": [1, [10, "apple "]], "STRING2": [1, [10, "banana"]]}, "fields": {}, "shadow": False, "topLevel": True,
553
+ "x": 663, "y": 378
554
+ },
555
+ "operator_letter_of": {
556
+ "opcode": "operator_letter_of", "next": None, "parent": None,
557
+ "inputs": {"LETTER": [1, [6, "1"]], "STRING": [1, [10, "apple"]]}, "fields": {}, "shadow": False, "topLevel": True,
558
+ "x": 664, "y": 445
559
+ },
560
+ "operator_length": {
561
+ "opcode": "operator_length", "next": None, "parent": None,
562
+ "inputs": {"STRING": [1, [10, "apple"]]}, "fields": {}, "shadow": False, "topLevel": True,
563
+ "x": 664, "y": 521
564
+ },
565
+ "operator_contains": {
566
+ "opcode": "operator_contains", "next": None, "parent": None,
567
+ "inputs": {"STRING1": [1, [10, "apple"]], "STRING2": [1, [10, "a"]]}, "fields": {}, "shadow": False, "topLevel": True,
568
+ "x": 634, "y": 599
569
+ },
570
+ "operator_mod": {
571
+ "opcode": "operator_mod", "next": None, "parent": None,
572
+ "inputs": {"NUM1": [1, [4, ""]], "NUM2": [1, [4, ""]]}, "fields": {}, "shadow": False, "topLevel": True,
573
+ "x": 295, "y": 594
574
+ },
575
+ "operator_round": {
576
+ "opcode": "operator_round", "next": None, "parent": None,
577
+ "inputs": {"NUM": [1, [4, ""]]}, "fields": {}, "shadow": False, "topLevel": True,
578
+ "x": 307, "y": 674
579
+ },
580
+ "operator_mathop": {
581
+ "opcode": "operator_mathop", "next": None, "parent": None,
582
+ "inputs": {"NUM": [1, [4, ""]]}, "fields": {"OPERATOR": ["abs", None]}, "shadow": False, "topLevel": True,
583
+ "x": 280, "y": 754
584
+ },
585
+
586
+ # sensing_block.json
587
+ "sensing_touchingobject": {
588
+ "opcode": "sensing_touchingobject", "next": None, "parent": None,
589
+ "inputs": {"TOUCHINGOBJECTMENU": [1, "sensing_touchingobjectmenu"]}, "fields": {}, "shadow": False, "topLevel": True,
590
+ "x": 359, "y": 116
591
+ },
592
+ "sensing_touchingobjectmenu": {
593
+ "opcode": "sensing_touchingobjectmenu", "next": None, "parent": "sensing_touchingobject",
594
+ "inputs": {}, "fields": {"TOUCHINGOBJECTMENU": ["_mouse_", None]}, "shadow": True, "topLevel": False
595
+ },
596
+ "sensing_touchingcolor": {
597
+ "opcode": "sensing_touchingcolor", "next": None, "parent": None,
598
+ "inputs": {"COLOR": [1, [9, "#55b888"]]}, "fields": {}, "shadow": False, "topLevel": True,
599
+ "x": 360, "y": 188
600
+ },
601
+ "sensing_coloristouchingcolor": {
602
+ "opcode": "sensing_coloristouchingcolor", "next": None, "parent": None,
603
+ "inputs": {"COLOR": [1, [9, "#d019f2"]], "COLOR2": [1, [9, "#2b0de3"]]}, "fields": {}, "shadow": False, "topLevel": True,
604
+ "x": 348, "y": 277
605
+ },
606
+ "sensing_askandwait": {
607
+ "opcode": "sensing_askandwait", "next": None, "parent": None,
608
+ "inputs": {"QUESTION": [1, [10, "What's your name?"]]}, "fields": {}, "shadow": False, "topLevel": True,
609
+ "x": 338, "y": 354
610
+ },
611
+ "sensing_answer": {
612
+ "opcode": "sensing_answer", "next": None, "parent": None,
613
+ "inputs": {}, "fields": {}, "shadow": False, "topLevel": True,
614
+ "x": 782, "y": 111
615
+ },
616
+ "sensing_keypressed": {
617
+ "opcode": "sensing_keypressed", "next": None, "parent": None,
618
+ "inputs": {"KEY_OPTION": [1, "sensing_keyoptions"]}, "fields": {}, "shadow": False, "topLevel": True,
619
+ "x": 762, "y": 207
620
+ },
621
+ "sensing_keyoptions": {
622
+ "opcode": "sensing_keyoptions", "next": None, "parent": "sensing_keypressed",
623
+ "inputs": {}, "fields": {"KEY_OPTION": ["space", None]}, "shadow": True, "topLevel": False
624
+ },
625
+ "sensing_mousedown": {
626
+ "opcode": "sensing_mousedown", "next": None, "parent": None,
627
+ "inputs": {}, "fields": {}, "shadow": False, "topLevel": True,
628
+ "x": 822, "y": 422
629
+ },
630
+ "sensing_mousex": {
631
+ "opcode": "sensing_mousex", "next": None, "parent": None,
632
+ "inputs": {}, "fields": {}, "shadow": False, "topLevel": True,
633
+ "x": 302, "y": 528
634
+ },
635
+ "sensing_mousey": {
636
+ "opcode": "sensing_mousey", "next": None, "parent": None,
637
+ "inputs": {}, "fields": {}, "shadow": False, "topLevel": True,
638
+ "x": 668, "y": 547
639
+ },
640
+ "sensing_setdragmode": {
641
+ "opcode": "sensing_setdragmode", "next": None, "parent": None,
642
+ "inputs": {}, "fields": {"DRAG_MODE": ["draggable", None]}, "shadow": False, "topLevel": True,
643
+ "x": 950, "y": 574
644
+ },
645
+ "sensing_loudness": {
646
+ "opcode": "sensing_loudness", "next": None, "parent": None,
647
+ "inputs": {}, "fields": {}, "shadow": False, "topLevel": True,
648
+ "x": 658, "y": 703
649
+ },
650
+ "sensing_timer": {
651
+ "opcode": "sensing_timer", "next": None, "parent": None,
652
+ "inputs": {}, "fields": {}, "shadow": False, "topLevel": True,
653
+ "x": 459, "y": 671
654
+ },
655
+ "sensing_resettimer": {
656
+ "opcode": "sensing_resettimer", "next": None, "parent": None,
657
+ "inputs": {}, "fields": {}, "shadow": False, "topLevel": True,
658
+ "x": 462, "y": 781
659
+ },
660
+ "sensing_of": {
661
+ "opcode": "sensing_of", "next": None, "parent": None,
662
+ "inputs": {"OBJECT": [1, "sensing_of_object_menu"]}, "fields": {"PROPERTY": ["backdrop #", None]}, "shadow": False, "topLevel": True,
663
+ "x": 997, "y": 754
664
+ },
665
+ "sensing_of_object_menu": {
666
+ "opcode": "sensing_of_object_menu", "next": None, "parent": "sensing_of",
667
+ "inputs": {}, "fields": {"OBJECT": ["_stage_", None]}, "shadow": True, "topLevel": False
668
+ },
669
+ "sensing_current": {
670
+ "opcode": "sensing_current", "next": None, "parent": None,
671
+ "inputs": {}, "fields": {"CURRENTMENU": ["YEAR", None]}, "shadow": False, "topLevel": True,
672
+ "x": 627, "y": 884
673
+ },
674
+ "sensing_dayssince2000": {
675
+ "opcode": "sensing_dayssince2000", "next": None, "parent": None,
676
+ "inputs": {}, "fields": {}, "shadow": False, "topLevel": True,
677
+ "x": 959, "y": 903
678
+ },
679
+ "sensing_username": {
680
+ "opcode": "sensing_username", "next": None, "parent": None,
681
+ "inputs": {}, "fields": {}, "shadow": False, "topLevel": True,
682
+ "x": 833, "y": 757
683
+ },
684
+
685
+ # sound_block.json
686
+ "sound_playuntildone": {
687
+ "opcode": "sound_playuntildone", "next": None, "parent": None,
688
+ "inputs": {"SOUND_MENU": [1, "sound_sounds_menu"]}, "fields": {}, "shadow": False, "topLevel": True,
689
+ "x": 253, "y": 17
690
+ },
691
+ "sound_sounds_menu": {
692
+ "opcode": "sound_sounds_menu", "next": None, "parent": "sound_playuntildone and sound_play",
693
+ "inputs": {}, "fields": {"SOUND_MENU": ["Meow", None]}, "shadow": True, "topLevel": False
694
+ },
695
+ "sound_play": {
696
+ "opcode": "sound_play", "next": None, "parent": None,
697
+ "inputs": {"SOUND_MENU": [1, "sound_sounds_menu"]}, "fields": {}, "shadow": False, "topLevel": True,
698
+ "x": 245, "y": 122
699
+ },
700
+ "sound_stopallsounds": {
701
+ "opcode": "sound_stopallsounds", "next": None, "parent": None,
702
+ "inputs": {}, "fields": {}, "shadow": False, "topLevel": True,
703
+ "x": 253, "y": 245
704
+ },
705
+ "sound_changeeffectby": {
706
+ "opcode": "sound_changeeffectby", "next": None, "parent": None,
707
+ "inputs": {"VALUE": [1, [4, "10"]]}, "fields": {"EFFECT": ["PITCH", None]}, "shadow": False, "topLevel": True,
708
+ "x": 653, "y": 14
709
+ },
710
+ "sound_seteffectto": {
711
+ "opcode": "sound_seteffectto", "next": None, "parent": None,
712
+ "inputs": {"VALUE": [1, [4, "100"]]}, "fields": {"EFFECT": ["PITCH", None]}, "shadow": False, "topLevel": True,
713
+ "x": 653, "y": 139
714
+ },
715
+ "sound_cleareffects": {
716
+ "opcode": "sound_cleareffects", "next": None, "parent": None,
717
+ "inputs": {}, "fields": {}, "shadow": False, "topLevel": True,
718
+ "x": 651, "y": 242
719
+ },
720
+ "sound_changevolumeby": {
721
+ "opcode": "sound_changevolumeby", "next": None, "parent": None,
722
+ "inputs": {"VOLUME": [1, [4, "-10"]]}, "fields": {}, "shadow": False, "topLevel": True,
723
+ "x": 645, "y": 353
724
+ },
725
+ "sound_setvolumeto": {
726
+ "opcode": "sound_setvolumeto", "next": None, "parent": None,
727
+ "inputs": {"VOLUME": [1, [4, "100"]]}, "fields": {}, "shadow": False, "topLevel": True,
728
+ "x": 1108, "y": 5
729
+ },
730
+ "sound_volume": {
731
+ "opcode": "sound_volume", "next": None, "parent": None,
732
+ "inputs": {}, "fields": {}, "shadow": False, "topLevel": True,
733
+ "x": 1136, "y": 123
734
+ },
735
+ }
736
+
737
+ # #Example input with opcodes from various categories
738
+ # input_opcodes = [
739
+ # {"opcode": "sound_play", "count": 2}, # New: Sound block with menu
740
+ # {"opcode": "sound_playuntildone", "count": 2}, # New: Sound block with menu
741
+ # ]
742
+
743
+ # Example input with opcodes from various categories
744
+ input_opcodes = [
745
+ {"opcode": "sound_play", "count": 2},
746
+ {"opcode": "sound_playuntildone", "count": 2},
747
+ {"opcode":"motion_goto","count":2},
748
+ {"opcode":"motion_glideto","count":2},
749
+ {"opcode":"looks_switchbackdropto","count":2},
750
+ {"opcode":"looks_switchcostumeto","count":2},
751
+ {"opcode":"control_create_clone_of","count":2},
752
+ {"opcode":"sensing_touchingobject","count":2},
753
+ {"opcode":"sensing_of","count":2},
754
+ {"opcode":"sensing_keypressed","count":2},
755
+ {"opcode":"motion_pointtowards","count":2},
756
+ ]
757
+
758
+ generated_output = generate_blocks_from_opcodes(input_opcodes, all_block_definitions)
759
+ print(json.dumps(generated_output, indent=2))
v2/scratch_agent/blocks.zip ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:28e1cf98ef07d0563762f629b4cf7300384743d7ae2733a11b4646d362a27571
3
+ size 41036
v2/scratch_agent/blocks/blocks.json ADDED
@@ -0,0 +1,2221 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "motion_movesteps": {
3
+ "opcode": "motion_movesteps",
4
+ "next": null,
5
+ "parent": null,
6
+ "inputs": {
7
+ "STEPS": [
8
+ 1,
9
+ [
10
+ 4,
11
+ "10"
12
+ ]
13
+ ]
14
+ },
15
+ "fields": {},
16
+ "shadow": false,
17
+ "topLevel": true,
18
+ "x": 464,
19
+ "y": -416
20
+ },
21
+ "motion_turnright": {
22
+ "opcode": "motion_turnright",
23
+ "next": null,
24
+ "parent": null,
25
+ "inputs": {
26
+ "DEGREES": [
27
+ 1,
28
+ [
29
+ 4,
30
+ "15"
31
+ ]
32
+ ]
33
+ },
34
+ "fields": {},
35
+ "shadow": false,
36
+ "topLevel": true,
37
+ "x": 467,
38
+ "y": -316
39
+ },
40
+ "motion_turnleft": {
41
+ "opcode": "motion_turnleft",
42
+ "next": null,
43
+ "parent": null,
44
+ "inputs": {
45
+ "DEGREES": [
46
+ 1,
47
+ [
48
+ 4,
49
+ "15"
50
+ ]
51
+ ]
52
+ },
53
+ "fields": {},
54
+ "shadow": false,
55
+ "topLevel": true,
56
+ "x": 464,
57
+ "y": -210
58
+ },
59
+ "motion_goto": {
60
+ "opcode": "motion_goto",
61
+ "next": null,
62
+ "parent": null,
63
+ "inputs": {
64
+ "TO": [
65
+ 1,
66
+ "@iM=Z?~GCbpC}gT7KAKY"
67
+ ]
68
+ },
69
+ "fields": {},
70
+ "shadow": false,
71
+ "topLevel": true,
72
+ "x": 465,
73
+ "y": -95
74
+ },
75
+ "motion_goto_menu": {
76
+ "opcode": "motion_goto_menu",
77
+ "next": null,
78
+ "parent": "d|J?C902/xy6tD5,|dmB",
79
+ "inputs": {},
80
+ "fields": {
81
+ "TO": [
82
+ "_random_",
83
+ null
84
+ ]
85
+ },
86
+ "shadow": true,
87
+ "topLevel": false
88
+ },
89
+ "motion_gotoxy": {
90
+ "opcode": "motion_gotoxy",
91
+ "next": null,
92
+ "parent": null,
93
+ "inputs": {
94
+ "X": [
95
+ 1,
96
+ [
97
+ 4,
98
+ "0"
99
+ ]
100
+ ],
101
+ "Y": [
102
+ 1,
103
+ [
104
+ 4,
105
+ "0"
106
+ ]
107
+ ]
108
+ },
109
+ "fields": {},
110
+ "shadow": false,
111
+ "topLevel": true,
112
+ "x": 468,
113
+ "y": 12
114
+ },
115
+ "motion_glideto": {
116
+ "opcode": "motion_glideto",
117
+ "next": null,
118
+ "parent": null,
119
+ "inputs": {
120
+ "SECS": [
121
+ 1,
122
+ [
123
+ 4,
124
+ "1"
125
+ ]
126
+ ],
127
+ "TO": [
128
+ 1,
129
+ "{id to destination position}"
130
+ ]
131
+ },
132
+ "fields": {},
133
+ "shadow": false,
134
+ "topLevel": true,
135
+ "x": 470,
136
+ "y": 129
137
+ },
138
+ "motion_glideto_menu": {
139
+ "opcode": "motion_glideto_menu",
140
+ "next": null,
141
+ "parent": null,
142
+ "inputs": {},
143
+ "fields": {
144
+ "TO": [
145
+ "_random_",
146
+ null
147
+ ]
148
+ },
149
+ "shadow": true,
150
+ "topLevel": false
151
+ },
152
+ "motion_glidesecstoxy": {
153
+ "opcode": "motion_glidesecstoxy",
154
+ "next": null,
155
+ "parent": null,
156
+ "inputs": {
157
+ "SECS": [
158
+ 1,
159
+ [
160
+ 4,
161
+ "1"
162
+ ]
163
+ ],
164
+ "X": [
165
+ 1,
166
+ [
167
+ 4,
168
+ "0"
169
+ ]
170
+ ],
171
+ "Y": [
172
+ 1,
173
+ [
174
+ 4,
175
+ "0"
176
+ ]
177
+ ]
178
+ },
179
+ "fields": {},
180
+ "shadow": false,
181
+ "topLevel": true,
182
+ "x": 476,
183
+ "y": 239
184
+ },
185
+ "motion_pointindirection": {
186
+ "opcode": "motion_pointindirection",
187
+ "next": null,
188
+ "parent": null,
189
+ "inputs": {
190
+ "DIRECTION": [
191
+ 1,
192
+ [
193
+ 8,
194
+ "90"
195
+ ]
196
+ ]
197
+ },
198
+ "fields": {},
199
+ "shadow": false,
200
+ "topLevel": true,
201
+ "x": 493,
202
+ "y": 361
203
+ },
204
+ "motion_pointtowards": {
205
+ "opcode": "motion_pointtowards",
206
+ "next": null,
207
+ "parent": null,
208
+ "inputs": {
209
+ "TOWARDS": [
210
+ 1,
211
+ "6xQl1pPk%9E~Znhm*:ng"
212
+ ]
213
+ },
214
+ "fields": {},
215
+ "shadow": false,
216
+ "topLevel": true,
217
+ "x": 492,
218
+ "y": 463
219
+ },
220
+ "motion_pointtowards_menu": {
221
+ "opcode": "motion_pointtowards_menu",
222
+ "next": null,
223
+ "parent": "Ucm$YBs*^9GFTGXCbal@",
224
+ "inputs": {},
225
+ "fields": {
226
+ "TOWARDS": [
227
+ "_mouse_",
228
+ null
229
+ ]
230
+ },
231
+ "shadow": true,
232
+ "topLevel": false
233
+ },
234
+ "motion_changexby": {
235
+ "opcode": "motion_changexby",
236
+ "next": null,
237
+ "parent": null,
238
+ "inputs": {
239
+ "DX": [
240
+ 1,
241
+ [
242
+ 4,
243
+ "10"
244
+ ]
245
+ ]
246
+ },
247
+ "fields": {},
248
+ "shadow": false,
249
+ "topLevel": true,
250
+ "x": 851,
251
+ "y": -409
252
+ },
253
+ "motion_setx": {
254
+ "opcode": "motion_setx",
255
+ "next": null,
256
+ "parent": null,
257
+ "inputs": {
258
+ "X": [
259
+ 1,
260
+ [
261
+ 4,
262
+ "0"
263
+ ]
264
+ ]
265
+ },
266
+ "fields": {},
267
+ "shadow": false,
268
+ "topLevel": true,
269
+ "x": 864,
270
+ "y": -194
271
+ },
272
+ "motion_changeyby": {
273
+ "opcode": "motion_changeyby",
274
+ "next": null,
275
+ "parent": null,
276
+ "inputs": {
277
+ "DY": [
278
+ 1,
279
+ [
280
+ 4,
281
+ "10"
282
+ ]
283
+ ]
284
+ },
285
+ "fields": {},
286
+ "shadow": false,
287
+ "topLevel": true,
288
+ "x": 861,
289
+ "y": -61
290
+ },
291
+ "motion_sety": {
292
+ "opcode": "motion_sety",
293
+ "next": null,
294
+ "parent": null,
295
+ "inputs": {
296
+ "Y": [
297
+ 1,
298
+ [
299
+ 4,
300
+ "0"
301
+ ]
302
+ ]
303
+ },
304
+ "fields": {},
305
+ "shadow": false,
306
+ "topLevel": true,
307
+ "x": 864,
308
+ "y": 66
309
+ },
310
+ "motion_ifonedgebounce": {
311
+ "opcode": "motion_ifonedgebounce",
312
+ "next": null,
313
+ "parent": null,
314
+ "inputs": {},
315
+ "fields": {},
316
+ "shadow": false,
317
+ "topLevel": true,
318
+ "x": 1131,
319
+ "y": -397
320
+ },
321
+ "motion_setrotationstyle": {
322
+ "opcode": "motion_setrotationstyle",
323
+ "next": null,
324
+ "parent": null,
325
+ "inputs": {},
326
+ "fields": {
327
+ "STYLE": [
328
+ "left-right",
329
+ null
330
+ ]
331
+ },
332
+ "shadow": false,
333
+ "topLevel": true,
334
+ "x": 1128,
335
+ "y": -287
336
+ },
337
+ "motion_xposition": {
338
+ "opcode": "motion_xposition",
339
+ "next": null,
340
+ "parent": null,
341
+ "inputs": {},
342
+ "fields": {},
343
+ "shadow": false,
344
+ "topLevel": true,
345
+ "x": 1193,
346
+ "y": -136
347
+ },
348
+ "motion_yposition": {
349
+ "opcode": "motion_yposition",
350
+ "next": null,
351
+ "parent": null,
352
+ "inputs": {},
353
+ "fields": {},
354
+ "shadow": false,
355
+ "topLevel": true,
356
+ "x": 1181,
357
+ "y": -64
358
+ },
359
+ "motion_direction": {
360
+ "opcode": "motion_direction",
361
+ "next": null,
362
+ "parent": null,
363
+ "inputs": {},
364
+ "fields": {},
365
+ "shadow": false,
366
+ "topLevel": true,
367
+ "x": 1188,
368
+ "y": 21
369
+ },
370
+ "control_wait": {
371
+ "opcode": "control_wait",
372
+ "next": null,
373
+ "parent": null,
374
+ "inputs": {
375
+ "DURATION": [
376
+ 1,
377
+ [
378
+ 5,
379
+ "1"
380
+ ]
381
+ ]
382
+ },
383
+ "fields": {},
384
+ "shadow": false,
385
+ "topLevel": true,
386
+ "x": 337,
387
+ "y": 129
388
+ },
389
+ "control_repeat": {
390
+ "opcode": "control_repeat",
391
+ "next": null,
392
+ "parent": null,
393
+ "inputs": {
394
+ "TIMES": [
395
+ 1,
396
+ [
397
+ 6,
398
+ "10"
399
+ ]
400
+ ]
401
+ },
402
+ "fields": {},
403
+ "shadow": false,
404
+ "topLevel": true,
405
+ "x": 348,
406
+ "y": 265
407
+ },
408
+ "control_forever": {
409
+ "opcode": "control_forever",
410
+ "next": null,
411
+ "parent": null,
412
+ "inputs": {},
413
+ "fields": {},
414
+ "shadow": false,
415
+ "topLevel": true,
416
+ "x": 334,
417
+ "y": 439
418
+ },
419
+ "control_if": {
420
+ "opcode": "control_if",
421
+ "next": null,
422
+ "parent": null,
423
+ "inputs": {},
424
+ "fields": {},
425
+ "shadow": false,
426
+ "topLevel": true,
427
+ "x": 331,
428
+ "y": 597
429
+ },
430
+ "control_if_else": {
431
+ "opcode": "control_if_else",
432
+ "next": null,
433
+ "parent": null,
434
+ "inputs": {},
435
+ "fields": {},
436
+ "shadow": false,
437
+ "topLevel": true,
438
+ "x": 335,
439
+ "y": 779
440
+ },
441
+ "control_wait_until": {
442
+ "opcode": "control_wait_until",
443
+ "next": null,
444
+ "parent": null,
445
+ "inputs": {},
446
+ "fields": {},
447
+ "shadow": false,
448
+ "topLevel": true,
449
+ "x": 676,
450
+ "y": 285
451
+ },
452
+ "control_repeat_until": {
453
+ "opcode": "control_repeat_until",
454
+ "next": null,
455
+ "parent": null,
456
+ "inputs": {},
457
+ "fields": {},
458
+ "shadow": false,
459
+ "topLevel": true,
460
+ "x": 692,
461
+ "y": 381
462
+ },
463
+ "control_stop": {
464
+ "opcode": "control_stop",
465
+ "next": null,
466
+ "parent": null,
467
+ "inputs": {},
468
+ "fields": {
469
+ "STOP_OPTION": [
470
+ "all",
471
+ null
472
+ ]
473
+ },
474
+ "shadow": false,
475
+ "topLevel": true,
476
+ "x": 708,
477
+ "y": 545,
478
+ "mutation": {
479
+ "tagName": "mutation",
480
+ "children": [],
481
+ "hasnext": "false"
482
+ }
483
+ },
484
+ "control_start_as_clone": {
485
+ "opcode": "control_start_as_clone",
486
+ "next": null,
487
+ "parent": null,
488
+ "inputs": {},
489
+ "fields": {},
490
+ "shadow": false,
491
+ "topLevel": true,
492
+ "x": 665,
493
+ "y": 672
494
+ },
495
+ "control_create_clone_of": {
496
+ "opcode": "control_create_clone_of",
497
+ "next": null,
498
+ "parent": null,
499
+ "inputs": {
500
+ "CLONE_OPTION": [
501
+ 1,
502
+ "t))DW9(QSKB]3C/3Ou+J"
503
+ ]
504
+ },
505
+ "fields": {},
506
+ "shadow": false,
507
+ "topLevel": true,
508
+ "x": 648,
509
+ "y": 797
510
+ },
511
+ "control_create_clone_of_menu": {
512
+ "opcode": "control_create_clone_of_menu",
513
+ "next": null,
514
+ "parent": "80yo/}Cw++Z.;x[ohh|7",
515
+ "inputs": {},
516
+ "fields": {
517
+ "CLONE_OPTION": [
518
+ "_myself_",
519
+ null
520
+ ]
521
+ },
522
+ "shadow": true,
523
+ "topLevel": false
524
+ },
525
+ "control_delete_this_clone": {
526
+ "opcode": "control_delete_this_clone",
527
+ "next": null,
528
+ "parent": null,
529
+ "inputs": {},
530
+ "fields": {},
531
+ "shadow": false,
532
+ "topLevel": true,
533
+ "x": 642,
534
+ "y": 914
535
+ },
536
+ "event_whenflagclicked": {
537
+ "opcode": "event_whenflagclicked",
538
+ "next": null,
539
+ "parent": null,
540
+ "inputs": {},
541
+ "fields": {},
542
+ "shadow": false,
543
+ "topLevel": true,
544
+ "x": 166,
545
+ "y": -422
546
+ },
547
+ "event_whenkeypressed": {
548
+ "opcode": "event_whenkeypressed",
549
+ "next": null,
550
+ "parent": null,
551
+ "inputs": {},
552
+ "fields": {
553
+ "KEY_OPTION": [
554
+ "space",
555
+ null
556
+ ]
557
+ },
558
+ "shadow": false,
559
+ "topLevel": true,
560
+ "x": 151,
561
+ "y": -329
562
+ },
563
+ "event_whenthisspriteclicked": {
564
+ "opcode": "event_whenthisspriteclicked",
565
+ "next": null,
566
+ "parent": null,
567
+ "inputs": {},
568
+ "fields": {},
569
+ "shadow": false,
570
+ "topLevel": true,
571
+ "x": 156,
572
+ "y": -223
573
+ },
574
+ "event_whenbackdropswitchesto": {
575
+ "opcode": "event_whenbackdropswitchesto",
576
+ "next": null,
577
+ "parent": null,
578
+ "inputs": {},
579
+ "fields": {
580
+ "BACKDROP": [
581
+ "backdrop1",
582
+ null
583
+ ]
584
+ },
585
+ "shadow": false,
586
+ "topLevel": true,
587
+ "x": 148,
588
+ "y": -101
589
+ },
590
+ "event_whengreaterthan": {
591
+ "opcode": "event_whengreaterthan",
592
+ "next": null,
593
+ "parent": null,
594
+ "inputs": {
595
+ "VALUE": [
596
+ 1,
597
+ [
598
+ 4,
599
+ "10"
600
+ ]
601
+ ]
602
+ },
603
+ "fields": {
604
+ "WHENGREATERTHANMENU": [
605
+ "LOUDNESS",
606
+ null
607
+ ]
608
+ },
609
+ "shadow": false,
610
+ "topLevel": true,
611
+ "x": 150,
612
+ "y": 10
613
+ },
614
+ "event_whenbroadcastreceived": {
615
+ "opcode": "event_whenbroadcastreceived",
616
+ "next": null,
617
+ "parent": null,
618
+ "inputs": {},
619
+ "fields": {
620
+ "BROADCAST_OPTION": [
621
+ "message1",
622
+ "5O!nei;S$!c!=hCT}0:a"
623
+ ]
624
+ },
625
+ "shadow": false,
626
+ "topLevel": true,
627
+ "x": 141,
628
+ "y": 118
629
+ },
630
+ "event_broadcast": {
631
+ "opcode": "event_broadcast",
632
+ "next": null,
633
+ "parent": null,
634
+ "inputs": {
635
+ "BROADCAST_INPUT": [
636
+ 1,
637
+ [
638
+ 11,
639
+ "message1",
640
+ "5O!nei;S$!c!=hCT}0:a"
641
+ ]
642
+ ]
643
+ },
644
+ "fields": {},
645
+ "shadow": false,
646
+ "topLevel": true,
647
+ "x": 151,
648
+ "y": 229
649
+ },
650
+ "event_broadcastandwait": {
651
+ "opcode": "event_broadcastandwait",
652
+ "next": null,
653
+ "parent": null,
654
+ "inputs": {
655
+ "BROADCAST_INPUT": [
656
+ 1,
657
+ [
658
+ 11,
659
+ "message1",
660
+ "5O!nei;S$!c!=hCT}0:a"
661
+ ]
662
+ ]
663
+ },
664
+ "fields": {},
665
+ "shadow": false,
666
+ "topLevel": true,
667
+ "x": 157,
668
+ "y": 340
669
+ },
670
+ "sensing_touchingobject": {
671
+ "opcode": "sensing_touchingobject",
672
+ "next": null,
673
+ "parent": null,
674
+ "inputs": {
675
+ "TOUCHINGOBJECTMENU": [
676
+ 1,
677
+ "xSKW9a+wTnM~h~So8Jc]"
678
+ ]
679
+ },
680
+ "fields": {},
681
+ "shadow": false,
682
+ "topLevel": true,
683
+ "x": 359,
684
+ "y": 116
685
+ },
686
+ "sensing_touchingobjectmenu": {
687
+ "opcode": "sensing_touchingobjectmenu",
688
+ "next": null,
689
+ "parent": "Y(n,F@BYzwd4CiN|Bh[P",
690
+ "inputs": {},
691
+ "fields": {
692
+ "TOUCHINGOBJECTMENU": [
693
+ "_mouse_",
694
+ null
695
+ ]
696
+ },
697
+ "shadow": true,
698
+ "topLevel": false
699
+ },
700
+ "sensing_touchingcolor": {
701
+ "opcode": "sensing_touchingcolor",
702
+ "next": null,
703
+ "parent": null,
704
+ "inputs": {
705
+ "COLOR": [
706
+ 1,
707
+ [
708
+ 9,
709
+ "#55b888"
710
+ ]
711
+ ]
712
+ },
713
+ "fields": {},
714
+ "shadow": false,
715
+ "topLevel": true,
716
+ "x": 360,
717
+ "y": 188
718
+ },
719
+ "sensing_coloristouchingcolor": {
720
+ "opcode": "sensing_coloristouchingcolor",
721
+ "next": null,
722
+ "parent": null,
723
+ "inputs": {
724
+ "COLOR": [
725
+ 1,
726
+ [
727
+ 9,
728
+ "#d019f2"
729
+ ]
730
+ ],
731
+ "COLOR2": [
732
+ 1,
733
+ [
734
+ 9,
735
+ "#2b0de3"
736
+ ]
737
+ ]
738
+ },
739
+ "fields": {},
740
+ "shadow": false,
741
+ "topLevel": true,
742
+ "x": 348,
743
+ "y": 277
744
+ },
745
+ "sensing_askandwait": {
746
+ "opcode": "sensing_askandwait",
747
+ "next": null,
748
+ "parent": null,
749
+ "inputs": {
750
+ "QUESTION": [
751
+ 1,
752
+ [
753
+ 10,
754
+ "What's your name?"
755
+ ]
756
+ ]
757
+ },
758
+ "fields": {},
759
+ "shadow": false,
760
+ "topLevel": true,
761
+ "x": 338,
762
+ "y": 354
763
+ },
764
+ "sensing_answer": {
765
+ "opcode": "sensing_answer",
766
+ "next": null,
767
+ "parent": null,
768
+ "inputs": {},
769
+ "fields": {},
770
+ "shadow": false,
771
+ "topLevel": true,
772
+ "x": 782,
773
+ "y": 111
774
+ },
775
+ "sensing_keypressed": {
776
+ "opcode": "sensing_keypressed",
777
+ "next": null,
778
+ "parent": null,
779
+ "inputs": {
780
+ "KEY_OPTION": [
781
+ 1,
782
+ "SNlf@Im$sv%.6ULi-f3i"
783
+ ]
784
+ },
785
+ "fields": {},
786
+ "shadow": false,
787
+ "topLevel": true,
788
+ "x": 762,
789
+ "y": 207
790
+ },
791
+ "sensing_keyoptions": {
792
+ "opcode": "sensing_keyoptions",
793
+ "next": null,
794
+ "parent": "7$xEUO.2hH2R6vh!$(Uj",
795
+ "inputs": {},
796
+ "fields": {
797
+ "KEY_OPTION": [
798
+ "space",
799
+ null
800
+ ]
801
+ },
802
+ "shadow": true,
803
+ "topLevel": false
804
+ },
805
+ "sensing_mousedown": {
806
+ "opcode": "sensing_mousedown",
807
+ "next": null,
808
+ "parent": null,
809
+ "inputs": {},
810
+ "fields": {},
811
+ "shadow": false,
812
+ "topLevel": true,
813
+ "x": 822,
814
+ "y": 422
815
+ },
816
+ "sensing_mousex": {
817
+ "opcode": "sensing_mousex",
818
+ "next": null,
819
+ "parent": null,
820
+ "inputs": {},
821
+ "fields": {},
822
+ "shadow": false,
823
+ "topLevel": true,
824
+ "x": 302,
825
+ "y": 528
826
+ },
827
+ "sensing_mousey": {
828
+ "opcode": "sensing_mousey",
829
+ "next": null,
830
+ "parent": null,
831
+ "inputs": {},
832
+ "fields": {},
833
+ "shadow": false,
834
+ "topLevel": true,
835
+ "x": 668,
836
+ "y": 547
837
+ },
838
+ "sensing_setdragmode": {
839
+ "opcode": "sensing_setdragmode",
840
+ "next": null,
841
+ "parent": null,
842
+ "inputs": {},
843
+ "fields": {
844
+ "DRAG_MODE": [
845
+ "draggable",
846
+ null
847
+ ]
848
+ },
849
+ "shadow": false,
850
+ "topLevel": true,
851
+ "x": 950,
852
+ "y": 574
853
+ },
854
+ "sensing_loudness": {
855
+ "opcode": "sensing_loudness",
856
+ "next": null,
857
+ "parent": null,
858
+ "inputs": {},
859
+ "fields": {},
860
+ "shadow": false,
861
+ "topLevel": true,
862
+ "x": 658,
863
+ "y": 703
864
+ },
865
+ "sensing_timer": {
866
+ "opcode": "sensing_timer",
867
+ "next": null,
868
+ "parent": null,
869
+ "inputs": {},
870
+ "fields": {},
871
+ "shadow": false,
872
+ "topLevel": true,
873
+ "x": 459,
874
+ "y": 671
875
+ },
876
+ "sensing_resettimer": {
877
+ "opcode": "sensing_resettimer",
878
+ "next": null,
879
+ "parent": null,
880
+ "inputs": {},
881
+ "fields": {},
882
+ "shadow": false,
883
+ "topLevel": true,
884
+ "x": 462,
885
+ "y": 781
886
+ },
887
+ "sensing_of": {
888
+ "opcode": "sensing_of",
889
+ "next": null,
890
+ "parent": null,
891
+ "inputs": {
892
+ "OBJECT": [
893
+ 1,
894
+ "t+o*y;iz,!O#aT|qM_+O"
895
+ ]
896
+ },
897
+ "fields": {
898
+ "PROPERTY": [
899
+ "backdrop #",
900
+ null
901
+ ]
902
+ },
903
+ "shadow": false,
904
+ "topLevel": true,
905
+ "x": 997,
906
+ "y": 754
907
+ },
908
+ "sensing_of_object_menu": {
909
+ "opcode": "sensing_of_object_menu",
910
+ "next": null,
911
+ "parent": "[4I2wIG/tNc@LQ-;FbsB",
912
+ "inputs": {},
913
+ "fields": {
914
+ "OBJECT": [
915
+ "_stage_",
916
+ null
917
+ ]
918
+ },
919
+ "shadow": true,
920
+ "topLevel": false
921
+ },
922
+ "sensing_current": {
923
+ "opcode": "sensing_current",
924
+ "next": null,
925
+ "parent": null,
926
+ "inputs": {},
927
+ "fields": {
928
+ "CURRENTMENU": [
929
+ "YEAR",
930
+ null
931
+ ]
932
+ },
933
+ "shadow": false,
934
+ "topLevel": true,
935
+ "x": 627,
936
+ "y": 884
937
+ },
938
+ "sensing_dayssince2000": {
939
+ "opcode": "sensing_dayssince2000",
940
+ "next": null,
941
+ "parent": null,
942
+ "inputs": {},
943
+ "fields": {},
944
+ "shadow": false,
945
+ "topLevel": true,
946
+ "x": 959,
947
+ "y": 903
948
+ },
949
+ "sensing_username": {
950
+ "opcode": "sensing_username",
951
+ "next": null,
952
+ "parent": null,
953
+ "inputs": {},
954
+ "fields": {},
955
+ "shadow": false,
956
+ "topLevel": true,
957
+ "x": 833,
958
+ "y": 757
959
+ },
960
+ "operator_add": {
961
+ "opcode": "operator_add",
962
+ "next": null,
963
+ "parent": null,
964
+ "inputs": {
965
+ "NUM1": [
966
+ 1,
967
+ [
968
+ 4,
969
+ ""
970
+ ]
971
+ ],
972
+ "NUM2": [
973
+ 1,
974
+ [
975
+ 4,
976
+ ""
977
+ ]
978
+ ]
979
+ },
980
+ "fields": {},
981
+ "shadow": false,
982
+ "topLevel": true,
983
+ "x": 128,
984
+ "y": 153
985
+ },
986
+ "operator_subtract": {
987
+ "opcode": "operator_subtract",
988
+ "next": null,
989
+ "parent": null,
990
+ "inputs": {
991
+ "NUM1": [
992
+ 1,
993
+ [
994
+ 4,
995
+ ""
996
+ ]
997
+ ],
998
+ "NUM2": [
999
+ 1,
1000
+ [
1001
+ 4,
1002
+ ""
1003
+ ]
1004
+ ]
1005
+ },
1006
+ "fields": {},
1007
+ "shadow": false,
1008
+ "topLevel": true,
1009
+ "x": 134,
1010
+ "y": 214
1011
+ },
1012
+ "operator_multiply": {
1013
+ "opcode": "operator_multiply",
1014
+ "next": null,
1015
+ "parent": null,
1016
+ "inputs": {
1017
+ "NUM1": [
1018
+ 1,
1019
+ [
1020
+ 4,
1021
+ ""
1022
+ ]
1023
+ ],
1024
+ "NUM2": [
1025
+ 1,
1026
+ [
1027
+ 4,
1028
+ ""
1029
+ ]
1030
+ ]
1031
+ },
1032
+ "fields": {},
1033
+ "shadow": false,
1034
+ "topLevel": true,
1035
+ "x": 134,
1036
+ "y": 278
1037
+ },
1038
+ "operator_divide": {
1039
+ "opcode": "operator_divide",
1040
+ "next": null,
1041
+ "parent": null,
1042
+ "inputs": {
1043
+ "NUM1": [
1044
+ 1,
1045
+ [
1046
+ 4,
1047
+ ""
1048
+ ]
1049
+ ],
1050
+ "NUM2": [
1051
+ 1,
1052
+ [
1053
+ 4,
1054
+ ""
1055
+ ]
1056
+ ]
1057
+ },
1058
+ "fields": {},
1059
+ "shadow": false,
1060
+ "topLevel": true,
1061
+ "x": 138,
1062
+ "y": 359
1063
+ },
1064
+ "operator_random": {
1065
+ "opcode": "operator_random",
1066
+ "next": null,
1067
+ "parent": null,
1068
+ "inputs": {
1069
+ "FROM": [
1070
+ 1,
1071
+ [
1072
+ 4,
1073
+ "1"
1074
+ ]
1075
+ ],
1076
+ "TO": [
1077
+ 1,
1078
+ [
1079
+ 4,
1080
+ "10"
1081
+ ]
1082
+ ]
1083
+ },
1084
+ "fields": {},
1085
+ "shadow": false,
1086
+ "topLevel": true,
1087
+ "x": 311,
1088
+ "y": 157
1089
+ },
1090
+ "operator_gt": {
1091
+ "opcode": "operator_gt",
1092
+ "next": null,
1093
+ "parent": null,
1094
+ "inputs": {
1095
+ "OPERAND1": [
1096
+ 1,
1097
+ [
1098
+ 10,
1099
+ ""
1100
+ ]
1101
+ ],
1102
+ "OPERAND2": [
1103
+ 1,
1104
+ [
1105
+ 10,
1106
+ "50"
1107
+ ]
1108
+ ]
1109
+ },
1110
+ "fields": {},
1111
+ "shadow": false,
1112
+ "topLevel": true,
1113
+ "x": 348,
1114
+ "y": 217
1115
+ },
1116
+ "operator_lt": {
1117
+ "opcode": "operator_lt",
1118
+ "next": null,
1119
+ "parent": null,
1120
+ "inputs": {
1121
+ "OPERAND1": [
1122
+ 1,
1123
+ [
1124
+ 10,
1125
+ ""
1126
+ ]
1127
+ ],
1128
+ "OPERAND2": [
1129
+ 1,
1130
+ [
1131
+ 10,
1132
+ "50"
1133
+ ]
1134
+ ]
1135
+ },
1136
+ "fields": {},
1137
+ "shadow": false,
1138
+ "topLevel": true,
1139
+ "x": 345,
1140
+ "y": 286
1141
+ },
1142
+ "operator_equals": {
1143
+ "opcode": "operator_equals",
1144
+ "next": null,
1145
+ "parent": null,
1146
+ "inputs": {
1147
+ "OPERAND1": [
1148
+ 1,
1149
+ [
1150
+ 10,
1151
+ ""
1152
+ ]
1153
+ ],
1154
+ "OPERAND2": [
1155
+ 1,
1156
+ [
1157
+ 10,
1158
+ "50"
1159
+ ]
1160
+ ]
1161
+ },
1162
+ "fields": {},
1163
+ "shadow": false,
1164
+ "topLevel": true,
1165
+ "x": 345,
1166
+ "y": 372
1167
+ },
1168
+ "operator_and": {
1169
+ "opcode": "operator_and",
1170
+ "next": null,
1171
+ "parent": null,
1172
+ "inputs": {},
1173
+ "fields": {},
1174
+ "shadow": false,
1175
+ "topLevel": true,
1176
+ "x": 701,
1177
+ "y": 158
1178
+ },
1179
+ "operator_or": {
1180
+ "opcode": "operator_or",
1181
+ "next": null,
1182
+ "parent": null,
1183
+ "inputs": {},
1184
+ "fields": {},
1185
+ "shadow": false,
1186
+ "topLevel": true,
1187
+ "x": 705,
1188
+ "y": 222
1189
+ },
1190
+ "operator_not": {
1191
+ "opcode": "operator_not",
1192
+ "next": null,
1193
+ "parent": null,
1194
+ "inputs": {},
1195
+ "fields": {},
1196
+ "shadow": false,
1197
+ "topLevel": true,
1198
+ "x": 734,
1199
+ "y": 283
1200
+ },
1201
+ "operator_join": {
1202
+ "opcode": "operator_join",
1203
+ "next": null,
1204
+ "parent": null,
1205
+ "inputs": {
1206
+ "STRING1": [
1207
+ 1,
1208
+ [
1209
+ 10,
1210
+ "apple "
1211
+ ]
1212
+ ],
1213
+ "STRING2": [
1214
+ 1,
1215
+ [
1216
+ 10,
1217
+ "banana"
1218
+ ]
1219
+ ]
1220
+ },
1221
+ "fields": {},
1222
+ "shadow": false,
1223
+ "topLevel": true,
1224
+ "x": 663,
1225
+ "y": 378
1226
+ },
1227
+ "operator_letter_of": {
1228
+ "opcode": "operator_letter_of",
1229
+ "next": null,
1230
+ "parent": null,
1231
+ "inputs": {
1232
+ "LETTER": [
1233
+ 1,
1234
+ [
1235
+ 6,
1236
+ "1"
1237
+ ]
1238
+ ],
1239
+ "STRING": [
1240
+ 1,
1241
+ [
1242
+ 10,
1243
+ "apple"
1244
+ ]
1245
+ ]
1246
+ },
1247
+ "fields": {},
1248
+ "shadow": false,
1249
+ "topLevel": true,
1250
+ "x": 664,
1251
+ "y": 445
1252
+ },
1253
+ "operator_length": {
1254
+ "opcode": "operator_length",
1255
+ "next": null,
1256
+ "parent": null,
1257
+ "inputs": {
1258
+ "STRING": [
1259
+ 1,
1260
+ [
1261
+ 10,
1262
+ "apple"
1263
+ ]
1264
+ ]
1265
+ },
1266
+ "fields": {},
1267
+ "shadow": false,
1268
+ "topLevel": true,
1269
+ "x": 664,
1270
+ "y": 521
1271
+ },
1272
+ "operator_contains": {
1273
+ "opcode": "operator_contains",
1274
+ "next": null,
1275
+ "parent": null,
1276
+ "inputs": {
1277
+ "STRING1": [
1278
+ 1,
1279
+ [
1280
+ 10,
1281
+ "apple"
1282
+ ]
1283
+ ],
1284
+ "STRING2": [
1285
+ 1,
1286
+ [
1287
+ 10,
1288
+ "a"
1289
+ ]
1290
+ ]
1291
+ },
1292
+ "fields": {},
1293
+ "shadow": false,
1294
+ "topLevel": true,
1295
+ "x": 634,
1296
+ "y": 599
1297
+ },
1298
+ "operator_mod": {
1299
+ "opcode": "operator_mod",
1300
+ "next": null,
1301
+ "parent": null,
1302
+ "inputs": {
1303
+ "NUM1": [
1304
+ 1,
1305
+ [
1306
+ 4,
1307
+ ""
1308
+ ]
1309
+ ],
1310
+ "NUM2": [
1311
+ 1,
1312
+ [
1313
+ 4,
1314
+ ""
1315
+ ]
1316
+ ]
1317
+ },
1318
+ "fields": {},
1319
+ "shadow": false,
1320
+ "topLevel": true,
1321
+ "x": 295,
1322
+ "y": 594
1323
+ },
1324
+ "operator_round": {
1325
+ "opcode": "operator_round",
1326
+ "next": null,
1327
+ "parent": null,
1328
+ "inputs": {
1329
+ "NUM": [
1330
+ 1,
1331
+ [
1332
+ 4,
1333
+ ""
1334
+ ]
1335
+ ]
1336
+ },
1337
+ "fields": {},
1338
+ "shadow": false,
1339
+ "topLevel": true,
1340
+ "x": 307,
1341
+ "y": 674
1342
+ },
1343
+ "operator_mathop": {
1344
+ "opcode": "operator_mathop",
1345
+ "next": null,
1346
+ "parent": null,
1347
+ "inputs": {
1348
+ "NUM": [
1349
+ 1,
1350
+ [
1351
+ 4,
1352
+ ""
1353
+ ]
1354
+ ]
1355
+ },
1356
+ "fields": {
1357
+ "OPERATOR": [
1358
+ "abs",
1359
+ null
1360
+ ]
1361
+ },
1362
+ "shadow": false,
1363
+ "topLevel": true,
1364
+ "x": 280,
1365
+ "y": 754
1366
+ },
1367
+ "data_setvariableto": {
1368
+ "opcode": "data_setvariableto",
1369
+ "next": null,
1370
+ "parent": null,
1371
+ "inputs": {
1372
+ "VALUE": [
1373
+ 1,
1374
+ [
1375
+ 10,
1376
+ "0"
1377
+ ]
1378
+ ]
1379
+ },
1380
+ "fields": {
1381
+ "VARIABLE": [
1382
+ "my variable",
1383
+ "`jEk@4|i[#Fk?(8x)AV.-my variable"
1384
+ ]
1385
+ },
1386
+ "shadow": false,
1387
+ "topLevel": true,
1388
+ "x": 348,
1389
+ "y": 241
1390
+ },
1391
+ "data_changevariableby": {
1392
+ "opcode": "data_changevariableby",
1393
+ "next": null,
1394
+ "parent": null,
1395
+ "inputs": {
1396
+ "VALUE": [
1397
+ 1,
1398
+ [
1399
+ 4,
1400
+ "1"
1401
+ ]
1402
+ ]
1403
+ },
1404
+ "fields": {
1405
+ "VARIABLE": [
1406
+ "my variable",
1407
+ "`jEk@4|i[#Fk?(8x)AV.-my variable"
1408
+ ]
1409
+ },
1410
+ "shadow": false,
1411
+ "topLevel": true,
1412
+ "x": 313,
1413
+ "y": 363
1414
+ },
1415
+ "data_showvariable": {
1416
+ "opcode": "data_showvariable",
1417
+ "next": null,
1418
+ "parent": null,
1419
+ "inputs": {},
1420
+ "fields": {
1421
+ "VARIABLE": [
1422
+ "my variable",
1423
+ "`jEk@4|i[#Fk?(8x)AV.-my variable"
1424
+ ]
1425
+ },
1426
+ "shadow": false,
1427
+ "topLevel": true,
1428
+ "x": 415,
1429
+ "y": 473
1430
+ },
1431
+ "data_hidevariable": {
1432
+ "opcode": "data_hidevariable",
1433
+ "next": null,
1434
+ "parent": null,
1435
+ "inputs": {},
1436
+ "fields": {
1437
+ "VARIABLE": [
1438
+ "my variable",
1439
+ "`jEk@4|i[#Fk?(8x)AV.-my variable"
1440
+ ]
1441
+ },
1442
+ "shadow": false,
1443
+ "topLevel": true,
1444
+ "x": 319,
1445
+ "y": 587
1446
+ },
1447
+ "data_addtolist": {
1448
+ "opcode": "data_addtolist",
1449
+ "next": null,
1450
+ "parent": null,
1451
+ "inputs": {
1452
+ "ITEM": [
1453
+ 1,
1454
+ [
1455
+ 10,
1456
+ "thing"
1457
+ ]
1458
+ ]
1459
+ },
1460
+ "fields": {
1461
+ "LIST": [
1462
+ "MY_LIST",
1463
+ "o6`kIhtT{xWH+rX(5d,A"
1464
+ ]
1465
+ },
1466
+ "shadow": false,
1467
+ "topLevel": true,
1468
+ "x": 385,
1469
+ "y": 109
1470
+ },
1471
+ "data_deleteoflist": {
1472
+ "opcode": "data_deleteoflist",
1473
+ "next": null,
1474
+ "parent": null,
1475
+ "inputs": {
1476
+ "INDEX": [
1477
+ 1,
1478
+ [
1479
+ 7,
1480
+ "1"
1481
+ ]
1482
+ ]
1483
+ },
1484
+ "fields": {
1485
+ "LIST": [
1486
+ "MY_LIST",
1487
+ "o6`kIhtT{xWH+rX(5d,A"
1488
+ ]
1489
+ },
1490
+ "shadow": false,
1491
+ "topLevel": true,
1492
+ "x": 384,
1493
+ "y": 244
1494
+ },
1495
+ "data_deletealloflist": {
1496
+ "opcode": "data_deletealloflist",
1497
+ "next": null,
1498
+ "parent": null,
1499
+ "inputs": {},
1500
+ "fields": {
1501
+ "LIST": [
1502
+ "MY_LIST",
1503
+ "o6`kIhtT{xWH+rX(5d,A"
1504
+ ]
1505
+ },
1506
+ "shadow": false,
1507
+ "topLevel": true,
1508
+ "x": 387,
1509
+ "y": 374
1510
+ },
1511
+ "data_insertatlist": {
1512
+ "opcode": "data_insertatlist",
1513
+ "next": null,
1514
+ "parent": null,
1515
+ "inputs": {
1516
+ "ITEM": [
1517
+ 1,
1518
+ [
1519
+ 10,
1520
+ "thing"
1521
+ ]
1522
+ ],
1523
+ "INDEX": [
1524
+ 1,
1525
+ [
1526
+ 7,
1527
+ "1"
1528
+ ]
1529
+ ]
1530
+ },
1531
+ "fields": {
1532
+ "LIST": [
1533
+ "MY_LIST",
1534
+ "o6`kIhtT{xWH+rX(5d,A"
1535
+ ]
1536
+ },
1537
+ "shadow": false,
1538
+ "topLevel": true,
1539
+ "x": 366,
1540
+ "y": 527
1541
+ },
1542
+ "data_replaceitemoflist": {
1543
+ "opcode": "data_replaceitemoflist",
1544
+ "next": null,
1545
+ "parent": null,
1546
+ "inputs": {
1547
+ "INDEX": [
1548
+ 1,
1549
+ [
1550
+ 7,
1551
+ "1"
1552
+ ]
1553
+ ],
1554
+ "ITEM": [
1555
+ 1,
1556
+ [
1557
+ 10,
1558
+ "thing"
1559
+ ]
1560
+ ]
1561
+ },
1562
+ "fields": {
1563
+ "LIST": [
1564
+ "MY_LIST",
1565
+ "o6`kIhtT{xWH+rX(5d,A"
1566
+ ]
1567
+ },
1568
+ "shadow": false,
1569
+ "topLevel": true,
1570
+ "x": 365,
1571
+ "y": 657
1572
+ },
1573
+ "data_itemoflist": {
1574
+ "opcode": "data_itemoflist",
1575
+ "next": null,
1576
+ "parent": null,
1577
+ "inputs": {
1578
+ "INDEX": [
1579
+ 1,
1580
+ [
1581
+ 7,
1582
+ "1"
1583
+ ]
1584
+ ]
1585
+ },
1586
+ "fields": {
1587
+ "LIST": [
1588
+ "MY_LIST",
1589
+ "o6`kIhtT{xWH+rX(5d,A"
1590
+ ]
1591
+ },
1592
+ "shadow": false,
1593
+ "topLevel": true,
1594
+ "x": 862,
1595
+ "y": 117
1596
+ },
1597
+ "data_itemnumoflist": {
1598
+ "opcode": "data_itemnumoflist",
1599
+ "next": null,
1600
+ "parent": null,
1601
+ "inputs": {
1602
+ "ITEM": [
1603
+ 1,
1604
+ [
1605
+ 10,
1606
+ "thing"
1607
+ ]
1608
+ ]
1609
+ },
1610
+ "fields": {
1611
+ "LIST": [
1612
+ "MY_LIST",
1613
+ "o6`kIhtT{xWH+rX(5d,A"
1614
+ ]
1615
+ },
1616
+ "shadow": false,
1617
+ "topLevel": true,
1618
+ "x": 883,
1619
+ "y": 238
1620
+ },
1621
+ "data_lengthoflist": {
1622
+ "opcode": "data_lengthoflist",
1623
+ "next": null,
1624
+ "parent": null,
1625
+ "inputs": {},
1626
+ "fields": {
1627
+ "LIST": [
1628
+ "MY_LIST",
1629
+ "o6`kIhtT{xWH+rX(5d,A"
1630
+ ]
1631
+ },
1632
+ "shadow": false,
1633
+ "topLevel": true,
1634
+ "x": 876,
1635
+ "y": 342
1636
+ },
1637
+ "data_listcontainsitem": {
1638
+ "opcode": "data_listcontainsitem",
1639
+ "next": null,
1640
+ "parent": null,
1641
+ "inputs": {
1642
+ "ITEM": [
1643
+ 1,
1644
+ [
1645
+ 10,
1646
+ "thing"
1647
+ ]
1648
+ ]
1649
+ },
1650
+ "fields": {
1651
+ "LIST": [
1652
+ "MY_LIST",
1653
+ "o6`kIhtT{xWH+rX(5d,A"
1654
+ ]
1655
+ },
1656
+ "shadow": false,
1657
+ "topLevel": true,
1658
+ "x": 871,
1659
+ "y": 463
1660
+ },
1661
+ "data_showlist": {
1662
+ "opcode": "data_showlist",
1663
+ "next": null,
1664
+ "parent": null,
1665
+ "inputs": {},
1666
+ "fields": {
1667
+ "LIST": [
1668
+ "MY_LIST",
1669
+ "o6`kIhtT{xWH+rX(5d,A"
1670
+ ]
1671
+ },
1672
+ "shadow": false,
1673
+ "topLevel": true,
1674
+ "x": 931,
1675
+ "y": 563
1676
+ },
1677
+ "data_hidelist": {
1678
+ "opcode": "data_hidelist",
1679
+ "next": null,
1680
+ "parent": null,
1681
+ "inputs": {},
1682
+ "fields": {
1683
+ "LIST": [
1684
+ "MY_LIST",
1685
+ "o6`kIhtT{xWH+rX(5d,A"
1686
+ ]
1687
+ },
1688
+ "shadow": false,
1689
+ "topLevel": true,
1690
+ "x": 962,
1691
+ "y": 716
1692
+ },
1693
+ "sound_playuntildone": {
1694
+ "opcode": "sound_playuntildone",
1695
+ "next": null,
1696
+ "parent": null,
1697
+ "inputs": {
1698
+ "SOUND_MENU": [
1699
+ 1,
1700
+ "4w%pR8G.yD%g-BwCj=uK"
1701
+ ]
1702
+ },
1703
+ "fields": {},
1704
+ "shadow": false,
1705
+ "topLevel": true,
1706
+ "x": 253,
1707
+ "y": 17
1708
+ },
1709
+ "sound_sounds_menu": {
1710
+ "opcode": "sound_sounds_menu",
1711
+ "next": null,
1712
+ "parent": "Pdc$U;s8e_uUfTX`}jOo",
1713
+ "inputs": {},
1714
+ "fields": {
1715
+ "SOUND_MENU": [
1716
+ "Meow",
1717
+ null
1718
+ ]
1719
+ },
1720
+ "shadow": true,
1721
+ "topLevel": false
1722
+ },
1723
+ "sound_play": {
1724
+ "opcode": "sound_play",
1725
+ "next": null,
1726
+ "parent": null,
1727
+ "inputs": {
1728
+ "SOUND_MENU": [
1729
+ 1,
1730
+ "i1U{^VHb*2`9?l}=:L)/"
1731
+ ]
1732
+ },
1733
+ "fields": {},
1734
+ "shadow": false,
1735
+ "topLevel": true,
1736
+ "x": 245,
1737
+ "y": 122
1738
+ },
1739
+ "sound_stopallsounds": {
1740
+ "opcode": "sound_stopallsounds",
1741
+ "next": null,
1742
+ "parent": null,
1743
+ "inputs": {},
1744
+ "fields": {},
1745
+ "shadow": false,
1746
+ "topLevel": true,
1747
+ "x": 253,
1748
+ "y": 245
1749
+ },
1750
+ "sound_changeeffectby": {
1751
+ "opcode": "sound_changeeffectby",
1752
+ "next": null,
1753
+ "parent": null,
1754
+ "inputs": {
1755
+ "VALUE": [
1756
+ 1,
1757
+ [
1758
+ 4,
1759
+ "10"
1760
+ ]
1761
+ ]
1762
+ },
1763
+ "fields": {
1764
+ "EFFECT": [
1765
+ "PITCH",
1766
+ null
1767
+ ]
1768
+ },
1769
+ "shadow": false,
1770
+ "topLevel": true,
1771
+ "x": 653,
1772
+ "y": 14
1773
+ },
1774
+ "sound_seteffectto": {
1775
+ "opcode": "sound_seteffectto",
1776
+ "next": null,
1777
+ "parent": null,
1778
+ "inputs": {
1779
+ "VALUE": [
1780
+ 1,
1781
+ [
1782
+ 4,
1783
+ "100"
1784
+ ]
1785
+ ]
1786
+ },
1787
+ "fields": {
1788
+ "EFFECT": [
1789
+ "PITCH",
1790
+ null
1791
+ ]
1792
+ },
1793
+ "shadow": false,
1794
+ "topLevel": true,
1795
+ "x": 653,
1796
+ "y": 139
1797
+ },
1798
+ "sound_cleareffects": {
1799
+ "opcode": "sound_cleareffects",
1800
+ "next": null,
1801
+ "parent": null,
1802
+ "inputs": {},
1803
+ "fields": {},
1804
+ "shadow": false,
1805
+ "topLevel": true,
1806
+ "x": 651,
1807
+ "y": 242
1808
+ },
1809
+ "sound_changevolumeby": {
1810
+ "opcode": "sound_changevolumeby",
1811
+ "next": null,
1812
+ "parent": null,
1813
+ "inputs": {
1814
+ "VOLUME": [
1815
+ 1,
1816
+ [
1817
+ 4,
1818
+ "-10"
1819
+ ]
1820
+ ]
1821
+ },
1822
+ "fields": {},
1823
+ "shadow": false,
1824
+ "topLevel": true,
1825
+ "x": 645,
1826
+ "y": 353
1827
+ },
1828
+ "sound_setvolumeto": {
1829
+ "opcode": "sound_setvolumeto",
1830
+ "next": null,
1831
+ "parent": null,
1832
+ "inputs": {
1833
+ "VOLUME": [
1834
+ 1,
1835
+ [
1836
+ 4,
1837
+ "100"
1838
+ ]
1839
+ ]
1840
+ },
1841
+ "fields": {},
1842
+ "shadow": false,
1843
+ "topLevel": true,
1844
+ "x": 1108,
1845
+ "y": 5
1846
+ },
1847
+ "sound_volume": {
1848
+ "opcode": "sound_volume",
1849
+ "next": null,
1850
+ "parent": null,
1851
+ "inputs": {},
1852
+ "fields": {},
1853
+ "shadow": false,
1854
+ "topLevel": true,
1855
+ "x": 1136,
1856
+ "y": 123
1857
+ },
1858
+ "looks_sayforsecs": {
1859
+ "opcode": "looks_sayforsecs",
1860
+ "next": null,
1861
+ "parent": null,
1862
+ "inputs": {
1863
+ "MESSAGE": [
1864
+ 1,
1865
+ [
1866
+ 10,
1867
+ "Hello!"
1868
+ ]
1869
+ ],
1870
+ "SECS": [
1871
+ 1,
1872
+ [
1873
+ 4,
1874
+ "2"
1875
+ ]
1876
+ ]
1877
+ },
1878
+ "fields": {},
1879
+ "shadow": false,
1880
+ "topLevel": true,
1881
+ "x": 408,
1882
+ "y": 91
1883
+ },
1884
+ "looks_say": {
1885
+ "opcode": "looks_say",
1886
+ "next": null,
1887
+ "parent": null,
1888
+ "inputs": {
1889
+ "MESSAGE": [
1890
+ 1,
1891
+ [
1892
+ 10,
1893
+ "Hello!"
1894
+ ]
1895
+ ]
1896
+ },
1897
+ "fields": {},
1898
+ "shadow": false,
1899
+ "topLevel": true,
1900
+ "x": 413,
1901
+ "y": 213
1902
+ },
1903
+ "looks_thinkforsecs": {
1904
+ "opcode": "looks_thinkforsecs",
1905
+ "next": null,
1906
+ "parent": null,
1907
+ "inputs": {
1908
+ "MESSAGE": [
1909
+ 1,
1910
+ [
1911
+ 10,
1912
+ "Hmm..."
1913
+ ]
1914
+ ],
1915
+ "SECS": [
1916
+ 1,
1917
+ [
1918
+ 4,
1919
+ "2"
1920
+ ]
1921
+ ]
1922
+ },
1923
+ "fields": {},
1924
+ "shadow": false,
1925
+ "topLevel": true,
1926
+ "x": 413,
1927
+ "y": 317
1928
+ },
1929
+ "looks_think": {
1930
+ "opcode": "looks_think",
1931
+ "next": null,
1932
+ "parent": null,
1933
+ "inputs": {
1934
+ "MESSAGE": [
1935
+ 1,
1936
+ [
1937
+ 10,
1938
+ "Hmm..."
1939
+ ]
1940
+ ]
1941
+ },
1942
+ "fields": {},
1943
+ "shadow": false,
1944
+ "topLevel": true,
1945
+ "x": 412,
1946
+ "y": 432
1947
+ },
1948
+ "looks_switchcostumeto": {
1949
+ "opcode": "looks_switchcostumeto",
1950
+ "next": null,
1951
+ "parent": null,
1952
+ "inputs": {
1953
+ "COSTUME": [
1954
+ 1,
1955
+ "8;bti4wv(iH9nkOacCJ|"
1956
+ ]
1957
+ },
1958
+ "fields": {},
1959
+ "shadow": false,
1960
+ "topLevel": true,
1961
+ "x": 411,
1962
+ "y": 555
1963
+ },
1964
+ "looks_costume": {
1965
+ "opcode": "looks_costume",
1966
+ "next": null,
1967
+ "parent": "Q#a,6LPWHqo9-0Nu*[SV",
1968
+ "inputs": {},
1969
+ "fields": {
1970
+ "COSTUME": [
1971
+ "costume2",
1972
+ null
1973
+ ]
1974
+ },
1975
+ "shadow": true,
1976
+ "topLevel": false
1977
+ },
1978
+ "looks_nextcostume": {
1979
+ "opcode": "looks_nextcostume",
1980
+ "next": null,
1981
+ "parent": null,
1982
+ "inputs": {},
1983
+ "fields": {},
1984
+ "shadow": false,
1985
+ "topLevel": true,
1986
+ "x": 419,
1987
+ "y": 687
1988
+ },
1989
+ "looks_switchbackdropto": {
1990
+ "opcode": "looks_switchbackdropto",
1991
+ "next": null,
1992
+ "parent": null,
1993
+ "inputs": {
1994
+ "BACKDROP": [
1995
+ 1,
1996
+ "-?yeX}29V*wd6W:unW0i"
1997
+ ]
1998
+ },
1999
+ "fields": {},
2000
+ "shadow": false,
2001
+ "topLevel": true,
2002
+ "x": 901,
2003
+ "y": 91
2004
+ },
2005
+ "looks_backdrops": {
2006
+ "opcode": "looks_backdrops",
2007
+ "next": null,
2008
+ "parent": "`Wm^p~l[(IWzc1|wNv*.",
2009
+ "inputs": {},
2010
+ "fields": {
2011
+ "BACKDROP": [
2012
+ "backdrop1",
2013
+ null
2014
+ ]
2015
+ },
2016
+ "shadow": true,
2017
+ "topLevel": false
2018
+ },
2019
+ "looks_changesizeby": {
2020
+ "opcode": "looks_changesizeby",
2021
+ "next": null,
2022
+ "parent": null,
2023
+ "inputs": {
2024
+ "CHANGE": [
2025
+ 1,
2026
+ [
2027
+ 4,
2028
+ "10"
2029
+ ]
2030
+ ]
2031
+ },
2032
+ "fields": {},
2033
+ "shadow": false,
2034
+ "topLevel": true,
2035
+ "x": 895,
2036
+ "y": 192
2037
+ },
2038
+ "looks_setsizeto": {
2039
+ "opcode": "looks_setsizeto",
2040
+ "next": null,
2041
+ "parent": null,
2042
+ "inputs": {
2043
+ "SIZE": [
2044
+ 1,
2045
+ [
2046
+ 4,
2047
+ "100"
2048
+ ]
2049
+ ]
2050
+ },
2051
+ "fields": {},
2052
+ "shadow": false,
2053
+ "topLevel": true,
2054
+ "x": 896,
2055
+ "y": 303
2056
+ },
2057
+ "looks_changeeffectby": {
2058
+ "opcode": "looks_changeeffectby",
2059
+ "next": null,
2060
+ "parent": null,
2061
+ "inputs": {
2062
+ "CHANGE": [
2063
+ 1,
2064
+ [
2065
+ 4,
2066
+ "25"
2067
+ ]
2068
+ ]
2069
+ },
2070
+ "fields": {
2071
+ "EFFECT": [
2072
+ "COLOR",
2073
+ null
2074
+ ]
2075
+ },
2076
+ "shadow": false,
2077
+ "topLevel": true,
2078
+ "x": 892,
2079
+ "y": 416
2080
+ },
2081
+ "looks_seteffectto": {
2082
+ "opcode": "looks_seteffectto",
2083
+ "next": null,
2084
+ "parent": null,
2085
+ "inputs": {
2086
+ "VALUE": [
2087
+ 1,
2088
+ [
2089
+ 4,
2090
+ "0"
2091
+ ]
2092
+ ]
2093
+ },
2094
+ "fields": {
2095
+ "EFFECT": [
2096
+ "COLOR",
2097
+ null
2098
+ ]
2099
+ },
2100
+ "shadow": false,
2101
+ "topLevel": true,
2102
+ "x": 902,
2103
+ "y": 527
2104
+ },
2105
+ "looks_cleargraphiceffects": {
2106
+ "opcode": "looks_cleargraphiceffects",
2107
+ "next": null,
2108
+ "parent": null,
2109
+ "inputs": {},
2110
+ "fields": {},
2111
+ "shadow": false,
2112
+ "topLevel": true,
2113
+ "x": 902,
2114
+ "y": 638
2115
+ },
2116
+ "looks_show": {
2117
+ "opcode": "looks_show",
2118
+ "next": null,
2119
+ "parent": null,
2120
+ "inputs": {},
2121
+ "fields": {},
2122
+ "shadow": false,
2123
+ "topLevel": true,
2124
+ "x": 908,
2125
+ "y": 758
2126
+ },
2127
+ "looks_hide": {
2128
+ "opcode": "looks_hide",
2129
+ "next": null,
2130
+ "parent": null,
2131
+ "inputs": {},
2132
+ "fields": {},
2133
+ "shadow": false,
2134
+ "topLevel": true,
2135
+ "x": 455,
2136
+ "y": 861
2137
+ },
2138
+ "looks_gotofrontback": {
2139
+ "opcode": "looks_gotofrontback",
2140
+ "next": null,
2141
+ "parent": null,
2142
+ "inputs": {},
2143
+ "fields": {
2144
+ "FRONT_BACK": [
2145
+ "front",
2146
+ null
2147
+ ]
2148
+ },
2149
+ "shadow": false,
2150
+ "topLevel": true,
2151
+ "x": 853,
2152
+ "y": 878
2153
+ },
2154
+ "looks_goforwardbackwardlayers": {
2155
+ "opcode": "looks_goforwardbackwardlayers",
2156
+ "next": null,
2157
+ "parent": null,
2158
+ "inputs": {
2159
+ "NUM": [
2160
+ 1,
2161
+ [
2162
+ 7,
2163
+ "1"
2164
+ ]
2165
+ ]
2166
+ },
2167
+ "fields": {
2168
+ "FORWARD_BACKWARD": [
2169
+ "forward",
2170
+ null
2171
+ ]
2172
+ },
2173
+ "shadow": false,
2174
+ "topLevel": true,
2175
+ "x": 851,
2176
+ "y": 999
2177
+ },
2178
+ "looks_costumenumbername": {
2179
+ "opcode": "looks_costumenumbername",
2180
+ "next": null,
2181
+ "parent": null,
2182
+ "inputs": {},
2183
+ "fields": {
2184
+ "NUMBER_NAME": [
2185
+ "number",
2186
+ null
2187
+ ]
2188
+ },
2189
+ "shadow": false,
2190
+ "topLevel": true,
2191
+ "x": 458,
2192
+ "y": 1007
2193
+ },
2194
+ "looks_backdropnumbername": {
2195
+ "opcode": "looks_backdropnumbername",
2196
+ "next": null,
2197
+ "parent": null,
2198
+ "inputs": {},
2199
+ "fields": {
2200
+ "NUMBER_NAME": [
2201
+ "number",
2202
+ null
2203
+ ]
2204
+ },
2205
+ "shadow": false,
2206
+ "topLevel": true,
2207
+ "x": 1242,
2208
+ "y": 753
2209
+ },
2210
+ "looks_size": {
2211
+ "opcode": "looks_size",
2212
+ "next": null,
2213
+ "parent": null,
2214
+ "inputs": {},
2215
+ "fields": {},
2216
+ "shadow": false,
2217
+ "topLevel": true,
2218
+ "x": 1249,
2219
+ "y": 876
2220
+ }
2221
+ }
v2/scratch_agent/blocks/boolean_blocks.json ADDED
@@ -0,0 +1,281 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "block_category": "Boolean Blocks",
3
+ "description": "Boolean blocks are hexagonal in shape. They represent conditions that evaluate to either 'true' or 'false' and are typically used as inputs for control flow blocks.",
4
+ "blocks": [
5
+ {
6
+ "block_name": "<() < ()>",
7
+ "block_type": "operator",
8
+ "op_code": "operator_lt",
9
+ "block_shape": "Boolean Block",
10
+ "functionality": "Checks if the first value is less than the second.",
11
+ "inputs": [
12
+ {"name": "OPERAND1", "type": "any"},
13
+ {"name": "OPERAND2", "type": "any"}
14
+ ],
15
+ "example_standalone": "<(score) < (10)>",
16
+ "example_with_other_blocks": [
17
+ {
18
+ "script": "if <(score) < (10)> then\n say [Keep trying!]",
19
+ "explanation": "This script causes the sprite to say 'Keep trying!' if the 'score' variable is less than 10."
20
+ }
21
+ ]
22
+ },
23
+ {
24
+ "block_name": "<() = ()>",
25
+ "block_type": "operator",
26
+ "op_code": "operator_equals",
27
+ "block_shape": "Boolean Block",
28
+ "functionality": "Checks if two values are equal.",
29
+ "inputs": [
30
+ {"name": "OPERAND1", "type": "any"},
31
+ {"name": "OPERAND2", "type": "any"}
32
+ ],
33
+ "example_standalone": "<(answer) = (5)>",
34
+ "example_with_other_blocks": [
35
+ {
36
+ "script": "if <(answer) = (5)> then\n say [Correct!]",
37
+ "explanation": "This script makes the sprite say 'Correct!' if the value of the 'answer' variable is exactly 5."
38
+ }
39
+ ]
40
+ },
41
+ {
42
+ "block_name": "<() > ()>",
43
+ "block_type": "operator",
44
+ "op_code": "operator_gt",
45
+ "block_shape": "Boolean Block",
46
+ "functionality": "Checks if the first value is greater than the second.",
47
+ "inputs": [
48
+ {"name": "OPERAND1", "type": "any"},
49
+ {"name": "OPERAND2", "type": "any"}
50
+ ],
51
+ "example_standalone": "<([health v]) > (0)>",
52
+ "example_with_other_blocks": [
53
+ {
54
+ "script": "if <([health v]) > (0)> then\n move (10) steps\nelse\n stop [all v]\nend",
55
+ "explanation": "This script moves the sprite if its 'health' is greater than 0; otherwise, it stops all scripts."
56
+ }
57
+ ]
58
+ },
59
+ {
60
+ "block_name": "<<> and <>>",
61
+ "block_type": "operator",
62
+ "op_code": "operator_and",
63
+ "block_shape": "Boolean Block",
64
+ "functionality": "Returns 'true' if both provided Boolean conditions are 'true'.",
65
+ "inputs": [
66
+ {"name": "OPERAND1", "type": "boolean"},
67
+ {"name": "OPERAND2", "type": "boolean"}
68
+ ],
69
+ "example_standalone": "<<mouse down?> and <touching [mouse-pointer]?> >",
70
+ "example_with_other_blocks": [
71
+ {
72
+ "script": "if <<mouse down?> and <touching [mouse-pointer]?> > then\n say [You're clicking me!]\nend",
73
+ "explanation": "This script makes the sprite say 'You're clicking me!' only if the mouse button is pressed AND the mouse pointer is touching the sprite."
74
+ }
75
+ ]
76
+ },
77
+ {
78
+ "block_name": "<<> or <>>",
79
+ "block_type": "operator",
80
+ "op_code": "operator_or",
81
+ "block_shape": "Boolean Block",
82
+ "functionality": "Returns 'true' if at least one of the provided Boolean conditions is 'true'.",
83
+ "inputs": [
84
+ {"name": "OPERAND1", "type": "boolean"},
85
+ {"name": "OPERAND2", "type": "boolean"}
86
+ ],
87
+ "example_standalone": "<<key [left arrow v] pressed?> or <key [a v] pressed?>>",
88
+ "example_with_other_blocks": [
89
+ {
90
+ "script": "if <<key [left arrow v] pressed?> or <key [a v] pressed?>> then\n change x by (-10)\nend",
91
+ "explanation": "This script moves the sprite left if either the left arrow key OR the 'a' key is pressed."
92
+ }
93
+ ]
94
+ },
95
+ {
96
+ "block_name": "<not <>>",
97
+ "block_type": "operator",
98
+ "op_code": "operator_not",
99
+ "block_shape": "Boolean Block",
100
+ "functionality": "Returns 'true' if the provided Boolean condition is 'false', and 'false' if it is 'true'.",
101
+ "inputs": [
102
+ {"name": "OPERAND", "type": "boolean"}
103
+ ],
104
+ "example_standalone": "<not <mouse down?>>",
105
+ "example_with_other_blocks": [
106
+ {
107
+ "script": "if <not <touching [Sprite2 v]?>> then\n say [I'm safe!]\nend",
108
+ "explanation": "This script makes the sprite say 'I'm safe!' if it is NOT touching 'Sprite2'."
109
+ }
110
+ ]
111
+ },
112
+ {
113
+ "block_name": "<() contains ()?>",
114
+ "block_type": "operator",
115
+ "op_code": "operator_contains",
116
+ "block_shape": "Boolean Block",
117
+ "functionality": "Checks if one string contains another string.",
118
+ "inputs": [
119
+ {"name": "STRING1", "type": "string"},
120
+ {"name": "STRING2", "type": "string"}
121
+ ],
122
+ "example_standalone": "<[apple v] contains [a v]?>",
123
+ "example_with_other_blocks": [
124
+ {
125
+ "script": "if <[answer] contains [yes]?> then\n say [Great!]\nend",
126
+ "explanation": "This script makes the sprite say 'Great!' if the 'answer' variable contains the substring 'yes'."
127
+ }
128
+ ]
129
+ },
130
+ {
131
+ "block_name": "<touching [edge v]?>",
132
+ "block_type": "Sensing",
133
+ "op_code": "sensing_touchingobject",
134
+ "block_shape": "Boolean Block",
135
+ "functionality": "Checks if its sprite is touching the mouse-pointer, edge, or another specified sprite.",
136
+ "inputs": [
137
+ {"name": "TOUCHINGOBJECTMENU", "type": "dropdown", "options": ["mouse-pointer", "edge", "Sprite1", "..." ]}
138
+ ],
139
+ "example_standalone": "<touching [edge v]?>",
140
+ "example_with_other_blocks": [
141
+ {
142
+ "script": "if <touching [Sprite v]?> then\n broadcast [Game Over v] \nend",
143
+ "explanation": "This script makes the broadcast message 'Game Over' in script if it comes into contact with the sprite."
144
+ },
145
+ {
146
+ "script": "if <touching [edge v]?> then\n bounce off edge\nend",
147
+ "explanation": "This script makes the sprite reverse direction if it comes into contact with the edge of the stage."
148
+ }
149
+ ]
150
+ },
151
+ {
152
+ "block_name": "<touching color ()?>",
153
+ "block_type": "Sensing",
154
+ "op_code": "sensing_touchingcolor",
155
+ "block_shape": "Boolean Block",
156
+ "functionality": "Checks whether its sprite is touching a specified color.",
157
+ "inputs": [
158
+ {"name": "COLOR", "type": "color"}
159
+ ],
160
+ "example_standalone": "<touching color [#FF0000]?>",
161
+ "example_with_other_blocks": [
162
+ {
163
+ "script": "if <touching color [#FF0000]?> then\n change [health v] by (-1)\nend",
164
+ "explanation": "This script decreases the 'health' variable by 1 if the sprite touches any red color on the stage."
165
+ }
166
+ ]
167
+ },
168
+ {
169
+ "block_name": "<color () is touching ()?>",
170
+ "block_type": "Sensing",
171
+ "op_code": "sensing_coloristouchingcolor",
172
+ "block_shape": "Boolean Block",
173
+ "functionality": "Checks whether a specific color on its sprite is touching another specified color on the stage or another sprite.",
174
+ "inputs": [
175
+ {"name": "COLOR1", "type": "color"},
176
+ {"name": "COLOR2", "type": "color"}
177
+ ],
178
+ "example_standalone": "<color [#00FF00] is touching [#FF0000]?>",
179
+ "example_with_other_blocks": [
180
+ {
181
+ "script": "if <color [#00FF00] is touching [#FF0000]?> then\n say [Collision!]\nend",
182
+ "explanation": "This script makes the sprite say 'Collision!' if a green part of the sprite touches a red color elsewhere in the project."
183
+ }
184
+ ]
185
+ },
186
+ {
187
+ "block_name": "<key () pressed?>",
188
+ "block_type": "Sensing",
189
+ "op_code": "sensing_keypressed",
190
+ "block_shape": "Boolean Block",
191
+ "functionality": "Checks if a specified keyboard key is currently being pressed.",
192
+ "inputs": [
193
+ {"name": "KEY_OPTION", "type": "dropdown",
194
+ "options": [
195
+ "space",
196
+ "up arrow",
197
+ "down arrow",
198
+ "right arrow",
199
+ "left arrow",
200
+ "any",
201
+ "a",
202
+ "b",
203
+ "c",
204
+ "d",
205
+ "e",
206
+ "f",
207
+ "g",
208
+ "h",
209
+ "i",
210
+ "j",
211
+ "k",
212
+ "l",
213
+ "m",
214
+ "n",
215
+ "o",
216
+ "p",
217
+ "q",
218
+ "r",
219
+ "s",
220
+ "t",
221
+ "u",
222
+ "v",
223
+ "w",
224
+ "x",
225
+ "y",
226
+ "z",
227
+ "0",
228
+ "1",
229
+ "2",
230
+ "3",
231
+ "4",
232
+ "5",
233
+ "6",
234
+ "7",
235
+ "8",
236
+ "9"
237
+ ]}
238
+ ],
239
+ "example_standalone": "<key [space v] pressed?>",
240
+ "example_with_other_blocks": [
241
+ {
242
+ "script": "forever\n if <key [space v] pressed?> then\n broadcast [shoot v]\n end\nend",
243
+ "explanation": "This script continuously checks if the space key is pressed and, if so, sends a 'shoot' broadcast."
244
+ }
245
+ ]
246
+ },
247
+ {
248
+ "block_name": "<mouse down?>",
249
+ "block_type": "Sensing",
250
+ "op_code": "sensing_mousedown",
251
+ "block_shape": "Boolean Block",
252
+ "functionality": "Checks if the computer mouse's primary button is being clicked while the cursor is over the stage.",
253
+ "inputs": null,
254
+ "example_standalone": "<mouse down?>",
255
+ "example_with_other_blocks": [
256
+ {
257
+ "script": "if <mouse down?> then\n go to mouse-pointer\nend",
258
+ "explanation": "This script makes the sprite follow the mouse pointer only when the mouse button is held down."
259
+ }
260
+ ]
261
+ },
262
+ {
263
+ "block_name": "<[my list v] contains ()?>",
264
+ "block_type": "Data",
265
+ "op_code": "data_listcontainsitem",
266
+ "block_shape": "Boolean Block",
267
+ "functionality": "Checks if a list includes a specific item.",
268
+ "inputs": [
269
+ {"name": "LIST", "type": "dropdown"},
270
+ {"name": "ITEM", "type": "any"}
271
+ ],
272
+ "example_standalone": "<[inventory v] contains [key]?>",
273
+ "example_with_other_blocks": [
274
+ {
275
+ "script": "if <[inventory v] contains [key]?> then\n say [You have the key!]\nend",
276
+ "explanation": "This script makes the sprite say 'You have the key!' if the 'inventory' list contains the item 'key'."
277
+ }
278
+ ]
279
+ }
280
+ ]
281
+ }
v2/scratch_agent/blocks/c_blocks.json ADDED
@@ -0,0 +1,105 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "block_category": "C Blocks",
3
+ "description": "C blocks are shaped like the letter 'C'. They are used to loop or conditionally execute blocks that are placed within their opening, managing the flow of scripts.",
4
+ "blocks": [
5
+ {
6
+ "block_name": "repeat ()",
7
+ "block_type": "Control",
8
+ "block_shape": "C-Block",
9
+ "op_code": "control_repeat",
10
+ "functionality": "Repeats the blocks inside it a specified number of times.",
11
+ "inputs": [
12
+ {
13
+ "name": "times",
14
+ "type": "number"
15
+ }
16
+ ],
17
+ "example_standalone": "repeat (10)",
18
+ "example_with_other_blocks": [
19
+ {
20
+ "script": "when [space v] key pressed\n repeat (10)\n move (10) steps\n wait (0.1) seconds\n end",
21
+ "explanation": "This script makes the sprite move 10 steps Ten times, with a short pause after each movement on spacebar pressed."
22
+ },
23
+ {
24
+ "script": "when [up arrow v] key pressed\n repeat (10)\n change y by (10)\n wait (0.1) seconds\n change y by (10)\n end",
25
+ "explanation": "This script makes the sprite jump, with a short pause after each movement on up arrow pressed."
26
+ }
27
+ ]
28
+ },
29
+ {
30
+ "block_name": "forever",
31
+ "block_type": "Control",
32
+ "block_shape": "C-Block",
33
+ "op_code": "control_forever",
34
+ "functionality": "Continuously runs the blocks inside it.",
35
+ "inputs": null,
36
+ "example_standalone": "forever",
37
+ "example_with_other_blocks": [
38
+ {
39
+ "script": "when green flag clicked\n forever\n move (5) steps\n if on edge, bounce\n end",
40
+ "explanation": "This script makes the sprite move endlessly and bounce off the edges of the stage, creating continuous motion."
41
+ }
42
+ ]
43
+ },
44
+ {
45
+ "block_name": "if <> then",
46
+ "block_type": "Control",
47
+ "block_shape": "C-Block",
48
+ "op_code": "control_if",
49
+ "functionality": "Executes the blocks inside it only if the specified boolean condition is true. [NOTE: it takes boolean blocks as input]",
50
+ "inputs": [
51
+ {
52
+ "name": "condition",
53
+ "type": "boolean"
54
+ }
55
+ ],
56
+ "example_standalone": "if <touching [mouse-pointer v]?> then",
57
+ "example_with_other_blocks": [
58
+ {
59
+ "script": "forever\n if <touching [color (red) v]?> then\n stop [this script v]\n end",
60
+ "explanation": "This script continuously checks if the sprite is touching a red color, and if so, it stops the current script."
61
+ }
62
+ ]
63
+ },
64
+ {
65
+ "block_name": "if <> then else",
66
+ "block_type": "Control",
67
+ "block_shape": "C-Block",
68
+ "op_code": "control_if_else",
69
+ "functionality": "Executes one set of blocks if the specified boolean condition is true, and a different set of blocks if the condition is false. [NOTE: it takes boolean blocks as input]",
70
+ "inputs": [
71
+ {
72
+ "name": "condition",
73
+ "type": "boolean"
74
+ }
75
+ ],
76
+ "example_standalone": "if <score > (10)> then else",
77
+ "example_with_other_blocks": [
78
+ {
79
+ "script": "if <(score) > (10)> then\n say [You win!] for (2) seconds\nelse\n say [Keep trying!] for (2) seconds\nend",
80
+ "explanation": "This script checks the 'score'. If the score is greater than 10, it says 'You win!'; otherwise, it says 'Keep trying!'."
81
+ }
82
+ ]
83
+ },
84
+ {
85
+ "block_name": "repeat until <>",
86
+ "block_type": "Control",
87
+ "block_shape": "C-Block",
88
+ "op_code": "control_repeat_until",
89
+ "functionality": "Repeats the blocks inside it until the specified boolean condition becomes true. [NOTE: it takes boolean blocks as input]",
90
+ "inputs": [
91
+ {
92
+ "name": "condition",
93
+ "type": "boolean"
94
+ }
95
+ ],
96
+ "example_standalone": "repeat until <touching [edge v]?>",
97
+ "example_with_other_blocks": [
98
+ {
99
+ "script": "repeat until <touching [edge v]?>\n move (5) steps\nend",
100
+ "explanation": "This script makes the sprite move 5 steps repeatedly until it touches the edge of the stage."
101
+ }
102
+ ]
103
+ }
104
+ ]
105
+ }
v2/scratch_agent/blocks/cap_blocks.json ADDED
@@ -0,0 +1,53 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "block_category": "Cap Blocks",
3
+ "description": "Cap blocks have a notch at the top and a flat bottom. They signify the end of a script, preventing any further blocks from being placed below them, and are used to terminate scripts or specific actions.",
4
+ "blocks": [
5
+ {
6
+ "block_name": "stop [v]",
7
+ "block_type": "Control",
8
+ "block_shape": "Cap Block (dynamic: can be Stack)",
9
+ "op_code": "control_stop",
10
+ "functionality": "Halts all scripts, only the current script, or other scripts within the same sprite. Its shape can dynamically change based on the selected option.",
11
+ "inputs": [
12
+ {"name": "option", "type": "dropdown", "options": ["all"]}
13
+ ],
14
+ "example_standalone": "stop [all v]",
15
+ "example_with_other_blocks": [
16
+ {
17
+ "script": "if <(health) = (0)> then\n stop [all v]\nend",
18
+ "explanation": "This script stops all running scripts in the project if the 'health' variable reaches 0, typically signifying a game over condition. [9, 15]"
19
+ }
20
+ ]
21
+ },
22
+ {
23
+ "block_name": "delete this clone",
24
+ "block_type": "Control",
25
+ "block_shape": "Cap Block",
26
+ "op_code": "control_delete_this_clone",
27
+ "functionality": "Removes the clone that is executing it from the stage.",
28
+ "inputs":null,
29
+ "example_standalone": "delete this clone",
30
+ "example_with_other_blocks": [
31
+ {
32
+ "script": "when I start as a clone\n wait until <touching [edge v]?>\n delete this clone\nend",
33
+ "explanation": "This script, run by a clone, causes the clone to disappear from the stage once it touches the edge. [1]"
34
+ }
35
+ ]
36
+ },
37
+ {
38
+ "block_name": "forever",
39
+ "block_type": "Control",
40
+ "block_shape": "Cap Block",
41
+ "op_code": "control_forever",
42
+ "functionality": "Continuously runs the blocks inside it.",
43
+ "inputs": null,
44
+ "example_standalone": "forever",
45
+ "example_with_other_blocks": [
46
+ {
47
+ "script": "when green flag clicked\n forever\n move (5) steps\n if on edge, bounce\n end",
48
+ "explanation": "This script makes the sprite move endlessly and bounce off the edges of the stage, creating continuous motion."
49
+ }
50
+ ]
51
+ }
52
+ ]
53
+ }
v2/scratch_agent/blocks/classwise_blocks/control_block.json ADDED
@@ -0,0 +1,168 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "control_wait": {
3
+ "opcode": "control_wait",
4
+ "next": null,
5
+ "parent": null,
6
+ "inputs": {
7
+ "DURATION": [
8
+ 1,
9
+ [
10
+ 5,
11
+ "1"
12
+ ]
13
+ ]
14
+ },
15
+ "fields": {},
16
+ "shadow": false,
17
+ "topLevel": true,
18
+ "x": 337,
19
+ "y": 129
20
+ },
21
+ "control_repeat": {
22
+ "opcode": "control_repeat",
23
+ "next": null,
24
+ "parent": null,
25
+ "inputs": {
26
+ "TIMES": [
27
+ 1,
28
+ [
29
+ 6,
30
+ "10"
31
+ ]
32
+ ]
33
+ },
34
+ "fields": {},
35
+ "shadow": false,
36
+ "topLevel": true,
37
+ "x": 348,
38
+ "y": 265
39
+ },
40
+ "control_forever": {
41
+ "opcode": "control_forever",
42
+ "next": null,
43
+ "parent": null,
44
+ "inputs": {},
45
+ "fields": {},
46
+ "shadow": false,
47
+ "topLevel": true,
48
+ "x": 334,
49
+ "y": 439
50
+ },
51
+ "control_if": {
52
+ "opcode": "control_if",
53
+ "next": null,
54
+ "parent": null,
55
+ "inputs": {},
56
+ "fields": {},
57
+ "shadow": false,
58
+ "topLevel": true,
59
+ "x": 331,
60
+ "y": 597
61
+ },
62
+ "control_if_else": {
63
+ "opcode": "control_if_else",
64
+ "next": null,
65
+ "parent": null,
66
+ "inputs": {},
67
+ "fields": {},
68
+ "shadow": false,
69
+ "topLevel": true,
70
+ "x": 335,
71
+ "y": 779
72
+ },
73
+ "control_wait_until": {
74
+ "opcode": "control_wait_until",
75
+ "next": null,
76
+ "parent": null,
77
+ "inputs": {},
78
+ "fields": {},
79
+ "shadow": false,
80
+ "topLevel": true,
81
+ "x": 676,
82
+ "y": 285
83
+ },
84
+ "control_repeat_until": {
85
+ "opcode": "control_repeat_until",
86
+ "next": null,
87
+ "parent": null,
88
+ "inputs": {},
89
+ "fields": {},
90
+ "shadow": false,
91
+ "topLevel": true,
92
+ "x": 692,
93
+ "y": 381
94
+ },
95
+ "control_stop": {
96
+ "opcode": "control_stop",
97
+ "next": null,
98
+ "parent": null,
99
+ "inputs": {},
100
+ "fields": {
101
+ "STOP_OPTION": [
102
+ "all",
103
+ null
104
+ ]
105
+ },
106
+ "shadow": false,
107
+ "topLevel": true,
108
+ "x": 708,
109
+ "y": 545,
110
+ "mutation": {
111
+ "tagName": "mutation",
112
+ "children": [],
113
+ "hasnext": "false"
114
+ }
115
+ },
116
+ "control_start_as_clone": {
117
+ "opcode": "control_start_as_clone",
118
+ "next": null,
119
+ "parent": null,
120
+ "inputs": {},
121
+ "fields": {},
122
+ "shadow": false,
123
+ "topLevel": true,
124
+ "x": 665,
125
+ "y": 672
126
+ },
127
+ "control_create_clone_of": {
128
+ "opcode": "control_create_clone_of",
129
+ "next": null,
130
+ "parent": null,
131
+ "inputs": {
132
+ "CLONE_OPTION": [
133
+ 1,
134
+ "control_create_clone_of_menu"
135
+ ]
136
+ },
137
+ "fields": {},
138
+ "shadow": false,
139
+ "topLevel": true,
140
+ "x": 648,
141
+ "y": 797
142
+ },
143
+ "control_create_clone_of_menu": {
144
+ "opcode": "control_create_clone_of_menu",
145
+ "next": null,
146
+ "parent": "control_create_clone_of",
147
+ "inputs": {},
148
+ "fields": {
149
+ "CLONE_OPTION": [
150
+ "_myself_",
151
+ null
152
+ ]
153
+ },
154
+ "shadow": true,
155
+ "topLevel": false
156
+ },
157
+ "control_delete_this_clone": {
158
+ "opcode": "control_delete_this_clone",
159
+ "next": null,
160
+ "parent": null,
161
+ "inputs": {},
162
+ "fields": {},
163
+ "shadow": false,
164
+ "topLevel": true,
165
+ "x": 642,
166
+ "y": 914
167
+ }
168
+ }
v2/scratch_agent/blocks/classwise_blocks/data_block.json ADDED
@@ -0,0 +1,328 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "data_setvariableto": {
3
+ "opcode": "data_setvariableto",
4
+ "next": null,
5
+ "parent": null,
6
+ "inputs": {
7
+ "VALUE": [
8
+ 1,
9
+ [
10
+ 10,
11
+ "0"
12
+ ]
13
+ ]
14
+ },
15
+ "fields": {
16
+ "VARIABLE": [
17
+ "my variable",
18
+ "`jEk@4|i[#Fk?(8x)AV.-my variable"
19
+ ]
20
+ },
21
+ "shadow": false,
22
+ "topLevel": true,
23
+ "x": 348,
24
+ "y": 241
25
+ },
26
+ "data_changevariableby": {
27
+ "opcode": "data_changevariableby",
28
+ "next": null,
29
+ "parent": null,
30
+ "inputs": {
31
+ "VALUE": [
32
+ 1,
33
+ [
34
+ 4,
35
+ "1"
36
+ ]
37
+ ]
38
+ },
39
+ "fields": {
40
+ "VARIABLE": [
41
+ "my variable",
42
+ "`jEk@4|i[#Fk?(8x)AV.-my variable"
43
+ ]
44
+ },
45
+ "shadow": false,
46
+ "topLevel": true,
47
+ "x": 313,
48
+ "y": 363
49
+ },
50
+ "data_showvariable": {
51
+ "opcode": "data_showvariable",
52
+ "next": null,
53
+ "parent": null,
54
+ "inputs": {},
55
+ "fields": {
56
+ "VARIABLE": [
57
+ "my variable",
58
+ "`jEk@4|i[#Fk?(8x)AV.-my variable"
59
+ ]
60
+ },
61
+ "shadow": false,
62
+ "topLevel": true,
63
+ "x": 415,
64
+ "y": 473
65
+ },
66
+ "data_hidevariable": {
67
+ "opcode": "data_hidevariable",
68
+ "next": null,
69
+ "parent": null,
70
+ "inputs": {},
71
+ "fields": {
72
+ "VARIABLE": [
73
+ "my variable",
74
+ "`jEk@4|i[#Fk?(8x)AV.-my variable"
75
+ ]
76
+ },
77
+ "shadow": false,
78
+ "topLevel": true,
79
+ "x": 319,
80
+ "y": 587
81
+ },
82
+ "data_addtolist": {
83
+ "opcode": "data_addtolist",
84
+ "next": null,
85
+ "parent": null,
86
+ "inputs": {
87
+ "ITEM": [
88
+ 1,
89
+ [
90
+ 10,
91
+ "thing"
92
+ ]
93
+ ]
94
+ },
95
+ "fields": {
96
+ "LIST": [
97
+ "MY_LIST",
98
+ "o6`kIhtT{xWH+rX(5d,A"
99
+ ]
100
+ },
101
+ "shadow": false,
102
+ "topLevel": true,
103
+ "x": 385,
104
+ "y": 109
105
+ },
106
+ "data_deleteoflist": {
107
+ "opcode": "data_deleteoflist",
108
+ "next": null,
109
+ "parent": null,
110
+ "inputs": {
111
+ "INDEX": [
112
+ 1,
113
+ [
114
+ 7,
115
+ "1"
116
+ ]
117
+ ]
118
+ },
119
+ "fields": {
120
+ "LIST": [
121
+ "MY_LIST",
122
+ "o6`kIhtT{xWH+rX(5d,A"
123
+ ]
124
+ },
125
+ "shadow": false,
126
+ "topLevel": true,
127
+ "x": 384,
128
+ "y": 244
129
+ },
130
+ "data_deletealloflist": {
131
+ "opcode": "data_deletealloflist",
132
+ "next": null,
133
+ "parent": null,
134
+ "inputs": {},
135
+ "fields": {
136
+ "LIST": [
137
+ "MY_LIST",
138
+ "o6`kIhtT{xWH+rX(5d,A"
139
+ ]
140
+ },
141
+ "shadow": false,
142
+ "topLevel": true,
143
+ "x": 387,
144
+ "y": 374
145
+ },
146
+ "data_insertatlist": {
147
+ "opcode": "data_insertatlist",
148
+ "next": null,
149
+ "parent": null,
150
+ "inputs": {
151
+ "ITEM": [
152
+ 1,
153
+ [
154
+ 10,
155
+ "thing"
156
+ ]
157
+ ],
158
+ "INDEX": [
159
+ 1,
160
+ [
161
+ 7,
162
+ "1"
163
+ ]
164
+ ]
165
+ },
166
+ "fields": {
167
+ "LIST": [
168
+ "MY_LIST",
169
+ "o6`kIhtT{xWH+rX(5d,A"
170
+ ]
171
+ },
172
+ "shadow": false,
173
+ "topLevel": true,
174
+ "x": 366,
175
+ "y": 527
176
+ },
177
+ "data_replaceitemoflist": {
178
+ "opcode": "data_replaceitemoflist",
179
+ "next": null,
180
+ "parent": null,
181
+ "inputs": {
182
+ "INDEX": [
183
+ 1,
184
+ [
185
+ 7,
186
+ "1"
187
+ ]
188
+ ],
189
+ "ITEM": [
190
+ 1,
191
+ [
192
+ 10,
193
+ "thing"
194
+ ]
195
+ ]
196
+ },
197
+ "fields": {
198
+ "LIST": [
199
+ "MY_LIST",
200
+ "o6`kIhtT{xWH+rX(5d,A"
201
+ ]
202
+ },
203
+ "shadow": false,
204
+ "topLevel": true,
205
+ "x": 365,
206
+ "y": 657
207
+ },
208
+ "data_itemoflist": {
209
+ "opcode": "data_itemoflist",
210
+ "next": null,
211
+ "parent": null,
212
+ "inputs": {
213
+ "INDEX": [
214
+ 1,
215
+ [
216
+ 7,
217
+ "1"
218
+ ]
219
+ ]
220
+ },
221
+ "fields": {
222
+ "LIST": [
223
+ "MY_LIST",
224
+ "o6`kIhtT{xWH+rX(5d,A"
225
+ ]
226
+ },
227
+ "shadow": false,
228
+ "topLevel": true,
229
+ "x": 862,
230
+ "y": 117
231
+ },
232
+ "data_itemnumoflist": {
233
+ "opcode": "data_itemnumoflist",
234
+ "next": null,
235
+ "parent": null,
236
+ "inputs": {
237
+ "ITEM": [
238
+ 1,
239
+ [
240
+ 10,
241
+ "thing"
242
+ ]
243
+ ]
244
+ },
245
+ "fields": {
246
+ "LIST": [
247
+ "MY_LIST",
248
+ "o6`kIhtT{xWH+rX(5d,A"
249
+ ]
250
+ },
251
+ "shadow": false,
252
+ "topLevel": true,
253
+ "x": 883,
254
+ "y": 238
255
+ },
256
+ "data_lengthoflist": {
257
+ "opcode": "data_lengthoflist",
258
+ "next": null,
259
+ "parent": null,
260
+ "inputs": {},
261
+ "fields": {
262
+ "LIST": [
263
+ "MY_LIST",
264
+ "o6`kIhtT{xWH+rX(5d,A"
265
+ ]
266
+ },
267
+ "shadow": false,
268
+ "topLevel": true,
269
+ "x": 876,
270
+ "y": 342
271
+ },
272
+ "data_listcontainsitem": {
273
+ "opcode": "data_listcontainsitem",
274
+ "next": null,
275
+ "parent": null,
276
+ "inputs": {
277
+ "ITEM": [
278
+ 1,
279
+ [
280
+ 10,
281
+ "thing"
282
+ ]
283
+ ]
284
+ },
285
+ "fields": {
286
+ "LIST": [
287
+ "MY_LIST",
288
+ "o6`kIhtT{xWH+rX(5d,A"
289
+ ]
290
+ },
291
+ "shadow": false,
292
+ "topLevel": true,
293
+ "x": 871,
294
+ "y": 463
295
+ },
296
+ "data_showlist": {
297
+ "opcode": "data_showlist",
298
+ "next": null,
299
+ "parent": null,
300
+ "inputs": {},
301
+ "fields": {
302
+ "LIST": [
303
+ "MY_LIST",
304
+ "o6`kIhtT{xWH+rX(5d,A"
305
+ ]
306
+ },
307
+ "shadow": false,
308
+ "topLevel": true,
309
+ "x": 931,
310
+ "y": 563
311
+ },
312
+ "data_hidelist": {
313
+ "opcode": "data_hidelist",
314
+ "next": null,
315
+ "parent": null,
316
+ "inputs": {},
317
+ "fields": {
318
+ "LIST": [
319
+ "MY_LIST",
320
+ "o6`kIhtT{xWH+rX(5d,A"
321
+ ]
322
+ },
323
+ "shadow": false,
324
+ "topLevel": true,
325
+ "x": 962,
326
+ "y": 716
327
+ }
328
+ }
v2/scratch_agent/blocks/classwise_blocks/event_block.json ADDED
@@ -0,0 +1,136 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "event_whenflagclicked": {
3
+ "opcode": "event_whenflagclicked",
4
+ "next": null,
5
+ "parent": null,
6
+ "inputs": {},
7
+ "fields": {},
8
+ "shadow": false,
9
+ "topLevel": true,
10
+ "x": 166,
11
+ "y": -422
12
+ },
13
+ "event_whenkeypressed": {
14
+ "opcode": "event_whenkeypressed",
15
+ "next": null,
16
+ "parent": null,
17
+ "inputs": {},
18
+ "fields": {
19
+ "KEY_OPTION": [
20
+ "space",
21
+ null
22
+ ]
23
+ },
24
+ "shadow": false,
25
+ "topLevel": true,
26
+ "x": 151,
27
+ "y": -329
28
+ },
29
+ "event_whenthisspriteclicked": {
30
+ "opcode": "event_whenthisspriteclicked",
31
+ "next": null,
32
+ "parent": null,
33
+ "inputs": {},
34
+ "fields": {},
35
+ "shadow": false,
36
+ "topLevel": true,
37
+ "x": 156,
38
+ "y": -223
39
+ },
40
+ "event_whenbackdropswitchesto": {
41
+ "opcode": "event_whenbackdropswitchesto",
42
+ "next": null,
43
+ "parent": null,
44
+ "inputs": {},
45
+ "fields": {
46
+ "BACKDROP": [
47
+ "backdrop1",
48
+ null
49
+ ]
50
+ },
51
+ "shadow": false,
52
+ "topLevel": true,
53
+ "x": 148,
54
+ "y": -101
55
+ },
56
+ "event_whengreaterthan": {
57
+ "opcode": "event_whengreaterthan",
58
+ "next": null,
59
+ "parent": null,
60
+ "inputs": {
61
+ "VALUE": [
62
+ 1,
63
+ [
64
+ 4,
65
+ "10"
66
+ ]
67
+ ]
68
+ },
69
+ "fields": {
70
+ "WHENGREATERTHANMENU": [
71
+ "LOUDNESS",
72
+ null
73
+ ]
74
+ },
75
+ "shadow": false,
76
+ "topLevel": true,
77
+ "x": 150,
78
+ "y": 10
79
+ },
80
+ "event_whenbroadcastreceived": {
81
+ "opcode": "event_whenbroadcastreceived",
82
+ "next": null,
83
+ "parent": null,
84
+ "inputs": {},
85
+ "fields": {
86
+ "BROADCAST_OPTION": [
87
+ "message1",
88
+ "5O!nei;S$!c!=hCT}0:a"
89
+ ]
90
+ },
91
+ "shadow": false,
92
+ "topLevel": true,
93
+ "x": 141,
94
+ "y": 118
95
+ },
96
+ "event_broadcast": {
97
+ "opcode": "event_broadcast",
98
+ "next": null,
99
+ "parent": null,
100
+ "inputs": {
101
+ "BROADCAST_INPUT": [
102
+ 1,
103
+ [
104
+ 11,
105
+ "message1",
106
+ "5O!nei;S$!c!=hCT}0:a"
107
+ ]
108
+ ]
109
+ },
110
+ "fields": {},
111
+ "shadow": false,
112
+ "topLevel": true,
113
+ "x": 151,
114
+ "y": 229
115
+ },
116
+ "event_broadcastandwait": {
117
+ "opcode": "event_broadcastandwait",
118
+ "next": null,
119
+ "parent": null,
120
+ "inputs": {
121
+ "BROADCAST_INPUT": [
122
+ 1,
123
+ [
124
+ 11,
125
+ "message1",
126
+ "5O!nei;S$!c!=hCT}0:a"
127
+ ]
128
+ ]
129
+ },
130
+ "fields": {},
131
+ "shadow": false,
132
+ "topLevel": true,
133
+ "x": 157,
134
+ "y": 340
135
+ }
136
+ }
v2/scratch_agent/blocks/classwise_blocks/look_block.json ADDED
@@ -0,0 +1,365 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "looks_sayforsecs": {
3
+ "opcode": "looks_sayforsecs",
4
+ "next": null,
5
+ "parent": null,
6
+ "inputs": {
7
+ "MESSAGE": [
8
+ 1,
9
+ [
10
+ 10,
11
+ "Hello!"
12
+ ]
13
+ ],
14
+ "SECS": [
15
+ 1,
16
+ [
17
+ 4,
18
+ "2"
19
+ ]
20
+ ]
21
+ },
22
+ "fields": {},
23
+ "shadow": false,
24
+ "topLevel": true,
25
+ "x": 408,
26
+ "y": 91
27
+ },
28
+ "looks_say": {
29
+ "opcode": "looks_say",
30
+ "next": null,
31
+ "parent": null,
32
+ "inputs": {
33
+ "MESSAGE": [
34
+ 1,
35
+ [
36
+ 10,
37
+ "Hello!"
38
+ ]
39
+ ]
40
+ },
41
+ "fields": {},
42
+ "shadow": false,
43
+ "topLevel": true,
44
+ "x": 413,
45
+ "y": 213
46
+ },
47
+ "looks_thinkforsecs": {
48
+ "opcode": "looks_thinkforsecs",
49
+ "next": null,
50
+ "parent": null,
51
+ "inputs": {
52
+ "MESSAGE": [
53
+ 1,
54
+ [
55
+ 10,
56
+ "Hmm..."
57
+ ]
58
+ ],
59
+ "SECS": [
60
+ 1,
61
+ [
62
+ 4,
63
+ "2"
64
+ ]
65
+ ]
66
+ },
67
+ "fields": {},
68
+ "shadow": false,
69
+ "topLevel": true,
70
+ "x": 413,
71
+ "y": 317
72
+ },
73
+ "looks_think": {
74
+ "opcode": "looks_think",
75
+ "next": null,
76
+ "parent": null,
77
+ "inputs": {
78
+ "MESSAGE": [
79
+ 1,
80
+ [
81
+ 10,
82
+ "Hmm..."
83
+ ]
84
+ ]
85
+ },
86
+ "fields": {},
87
+ "shadow": false,
88
+ "topLevel": true,
89
+ "x": 412,
90
+ "y": 432
91
+ },
92
+ "looks_switchcostumeto": {
93
+ "opcode": "looks_switchcostumeto",
94
+ "next": null,
95
+ "parent": null,
96
+ "inputs": {
97
+ "COSTUME": [
98
+ 1,
99
+ "looks_costume"
100
+ ]
101
+ },
102
+ "fields": {},
103
+ "shadow": false,
104
+ "topLevel": true,
105
+ "x": 411,
106
+ "y": 555
107
+ },
108
+ "looks_costume": {
109
+ "opcode": "looks_costume",
110
+ "next": null,
111
+ "parent": "looks_switchcostumeto",
112
+ "inputs": {},
113
+ "fields": {
114
+ "COSTUME": [
115
+ "costume2",
116
+ null
117
+ ]
118
+ },
119
+ "shadow": true,
120
+ "topLevel": false
121
+ },
122
+ "looks_nextcostume": {
123
+ "opcode": "looks_nextcostume",
124
+ "next": null,
125
+ "parent": null,
126
+ "inputs": {},
127
+ "fields": {},
128
+ "shadow": false,
129
+ "topLevel": true,
130
+ "x": 419,
131
+ "y": 687
132
+ },
133
+ "looks_switchbackdropto": {
134
+ "opcode": "looks_switchbackdropto",
135
+ "next": null,
136
+ "parent": null,
137
+ "inputs": {
138
+ "BACKDROP": [
139
+ 1,
140
+ "looks_backdrops"
141
+ ]
142
+ },
143
+ "fields": {},
144
+ "shadow": false,
145
+ "topLevel": true,
146
+ "x": 901,
147
+ "y": 91
148
+ },
149
+ "looks_backdrops": {
150
+ "opcode": "looks_backdrops",
151
+ "next": null,
152
+ "parent": "looks_switchbackdropto",
153
+ "inputs": {},
154
+ "fields": {
155
+ "BACKDROP": [
156
+ "backdrop1",
157
+ null
158
+ ]
159
+ },
160
+ "shadow": true,
161
+ "topLevel": false
162
+ },
163
+ "looks_changesizeby": {
164
+ "opcode": "looks_changesizeby",
165
+ "next": null,
166
+ "parent": null,
167
+ "inputs": {
168
+ "CHANGE": [
169
+ 1,
170
+ [
171
+ 4,
172
+ "10"
173
+ ]
174
+ ]
175
+ },
176
+ "fields": {},
177
+ "shadow": false,
178
+ "topLevel": true,
179
+ "x": 895,
180
+ "y": 192
181
+ },
182
+ "looks_setsizeto": {
183
+ "opcode": "looks_setsizeto",
184
+ "next": null,
185
+ "parent": null,
186
+ "inputs": {
187
+ "SIZE": [
188
+ 1,
189
+ [
190
+ 4,
191
+ "100"
192
+ ]
193
+ ]
194
+ },
195
+ "fields": {},
196
+ "shadow": false,
197
+ "topLevel": true,
198
+ "x": 896,
199
+ "y": 303
200
+ },
201
+ "looks_changeeffectby": {
202
+ "opcode": "looks_changeeffectby",
203
+ "next": null,
204
+ "parent": null,
205
+ "inputs": {
206
+ "CHANGE": [
207
+ 1,
208
+ [
209
+ 4,
210
+ "25"
211
+ ]
212
+ ]
213
+ },
214
+ "fields": {
215
+ "EFFECT": [
216
+ "COLOR",
217
+ null
218
+ ]
219
+ },
220
+ "shadow": false,
221
+ "topLevel": true,
222
+ "x": 892,
223
+ "y": 416
224
+ },
225
+ "looks_seteffectto": {
226
+ "opcode": "looks_seteffectto",
227
+ "next": null,
228
+ "parent": null,
229
+ "inputs": {
230
+ "VALUE": [
231
+ 1,
232
+ [
233
+ 4,
234
+ "0"
235
+ ]
236
+ ]
237
+ },
238
+ "fields": {
239
+ "EFFECT": [
240
+ "COLOR",
241
+ null
242
+ ]
243
+ },
244
+ "shadow": false,
245
+ "topLevel": true,
246
+ "x": 902,
247
+ "y": 527
248
+ },
249
+ "looks_cleargraphiceffects": {
250
+ "opcode": "looks_cleargraphiceffects",
251
+ "next": null,
252
+ "parent": null,
253
+ "inputs": {},
254
+ "fields": {},
255
+ "shadow": false,
256
+ "topLevel": true,
257
+ "x": 902,
258
+ "y": 638
259
+ },
260
+ "looks_show": {
261
+ "opcode": "looks_show",
262
+ "next": null,
263
+ "parent": null,
264
+ "inputs": {},
265
+ "fields": {},
266
+ "shadow": false,
267
+ "topLevel": true,
268
+ "x": 908,
269
+ "y": 758
270
+ },
271
+ "looks_hide": {
272
+ "opcode": "looks_hide",
273
+ "next": null,
274
+ "parent": null,
275
+ "inputs": {},
276
+ "fields": {},
277
+ "shadow": false,
278
+ "topLevel": true,
279
+ "x": 455,
280
+ "y": 861
281
+ },
282
+ "looks_gotofrontback": {
283
+ "opcode": "looks_gotofrontback",
284
+ "next": null,
285
+ "parent": null,
286
+ "inputs": {},
287
+ "fields": {
288
+ "FRONT_BACK": [
289
+ "front",
290
+ null
291
+ ]
292
+ },
293
+ "shadow": false,
294
+ "topLevel": true,
295
+ "x": 853,
296
+ "y": 878
297
+ },
298
+ "looks_goforwardbackwardlayers": {
299
+ "opcode": "looks_goforwardbackwardlayers",
300
+ "next": null,
301
+ "parent": null,
302
+ "inputs": {
303
+ "NUM": [
304
+ 1,
305
+ [
306
+ 7,
307
+ "1"
308
+ ]
309
+ ]
310
+ },
311
+ "fields": {
312
+ "FORWARD_BACKWARD": [
313
+ "forward",
314
+ null
315
+ ]
316
+ },
317
+ "shadow": false,
318
+ "topLevel": true,
319
+ "x": 851,
320
+ "y": 999
321
+ },
322
+ "looks_costumenumbername": {
323
+ "opcode": "looks_costumenumbername",
324
+ "next": null,
325
+ "parent": null,
326
+ "inputs": {},
327
+ "fields": {
328
+ "NUMBER_NAME": [
329
+ "number",
330
+ null
331
+ ]
332
+ },
333
+ "shadow": false,
334
+ "topLevel": true,
335
+ "x": 458,
336
+ "y": 1007
337
+ },
338
+ "looks_backdropnumbername": {
339
+ "opcode": "looks_backdropnumbername",
340
+ "next": null,
341
+ "parent": null,
342
+ "inputs": {},
343
+ "fields": {
344
+ "NUMBER_NAME": [
345
+ "number",
346
+ null
347
+ ]
348
+ },
349
+ "shadow": false,
350
+ "topLevel": true,
351
+ "x": 1242,
352
+ "y": 753
353
+ },
354
+ "looks_size": {
355
+ "opcode": "looks_size",
356
+ "next": null,
357
+ "parent": null,
358
+ "inputs": {},
359
+ "fields": {},
360
+ "shadow": false,
361
+ "topLevel": true,
362
+ "x": 1249,
363
+ "y": 876
364
+ }
365
+ }
v2/scratch_agent/blocks/classwise_blocks/motion_block.json ADDED
@@ -0,0 +1,370 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "motion_movesteps": {
3
+ "opcode": "motion_movesteps",
4
+ "next": null,
5
+ "parent": null,
6
+ "inputs": {
7
+ "STEPS": [
8
+ 1,
9
+ [
10
+ 4,
11
+ "10"
12
+ ]
13
+ ]
14
+ },
15
+ "fields": {},
16
+ "shadow": false,
17
+ "topLevel": true,
18
+ "x": 464,
19
+ "y": -416
20
+ },
21
+ "motion_turnright": {
22
+ "opcode": "motion_turnright",
23
+ "next": null,
24
+ "parent": null,
25
+ "inputs": {
26
+ "DEGREES": [
27
+ 1,
28
+ [
29
+ 4,
30
+ "15"
31
+ ]
32
+ ]
33
+ },
34
+ "fields": {},
35
+ "shadow": false,
36
+ "topLevel": true,
37
+ "x": 467,
38
+ "y": -316
39
+ },
40
+ "motion_turnleft": {
41
+ "opcode": "motion_turnleft",
42
+ "next": null,
43
+ "parent": null,
44
+ "inputs": {
45
+ "DEGREES": [
46
+ 1,
47
+ [
48
+ 4,
49
+ "15"
50
+ ]
51
+ ]
52
+ },
53
+ "fields": {},
54
+ "shadow": false,
55
+ "topLevel": true,
56
+ "x": 464,
57
+ "y": -210
58
+ },
59
+ "motion_goto": {
60
+ "opcode": "motion_goto",
61
+ "next": null,
62
+ "parent": null,
63
+ "inputs": {
64
+ "TO": [
65
+ 1,
66
+ "motion_goto_menu"
67
+ ]
68
+ },
69
+ "fields": {},
70
+ "shadow": false,
71
+ "topLevel": true,
72
+ "x": 465,
73
+ "y": -95
74
+ },
75
+ "motion_goto_menu": {
76
+ "opcode": "motion_goto_menu",
77
+ "next": null,
78
+ "parent": "motion_goto",
79
+ "inputs": {},
80
+ "fields": {
81
+ "TO": [
82
+ "_random_",
83
+ null
84
+ ]
85
+ },
86
+ "shadow": true,
87
+ "topLevel": false
88
+ },
89
+ "motion_gotoxy": {
90
+ "opcode": "motion_gotoxy",
91
+ "next": null,
92
+ "parent": null,
93
+ "inputs": {
94
+ "X": [
95
+ 1,
96
+ [
97
+ 4,
98
+ "0"
99
+ ]
100
+ ],
101
+ "Y": [
102
+ 1,
103
+ [
104
+ 4,
105
+ "0"
106
+ ]
107
+ ]
108
+ },
109
+ "fields": {},
110
+ "shadow": false,
111
+ "topLevel": true,
112
+ "x": 468,
113
+ "y": 12
114
+ },
115
+ "motion_glideto": {
116
+ "opcode": "motion_glideto",
117
+ "next": null,
118
+ "parent": null,
119
+ "inputs": {
120
+ "SECS": [
121
+ 1,
122
+ [
123
+ 4,
124
+ "1"
125
+ ]
126
+ ],
127
+ "TO": [
128
+ 1,
129
+ "motion_glideto_menu"
130
+ ]
131
+ },
132
+ "fields": {},
133
+ "shadow": false,
134
+ "topLevel": true,
135
+ "x": 470,
136
+ "y": 129
137
+ },
138
+ "motion_glideto_menu": {
139
+ "opcode": "motion_glideto_menu",
140
+ "next": null,
141
+ "parent": "motion_glideto",
142
+ "inputs": {},
143
+ "fields": {
144
+ "TO": [
145
+ "_random_",
146
+ null
147
+ ]
148
+ },
149
+ "shadow": true,
150
+ "topLevel": false
151
+ },
152
+ "motion_glidesecstoxy": {
153
+ "opcode": "motion_glidesecstoxy",
154
+ "next": null,
155
+ "parent": null,
156
+ "inputs": {
157
+ "SECS": [
158
+ 1,
159
+ [
160
+ 4,
161
+ "1"
162
+ ]
163
+ ],
164
+ "X": [
165
+ 1,
166
+ [
167
+ 4,
168
+ "0"
169
+ ]
170
+ ],
171
+ "Y": [
172
+ 1,
173
+ [
174
+ 4,
175
+ "0"
176
+ ]
177
+ ]
178
+ },
179
+ "fields": {},
180
+ "shadow": false,
181
+ "topLevel": true,
182
+ "x": 476,
183
+ "y": 239
184
+ },
185
+ "motion_pointindirection": {
186
+ "opcode": "motion_pointindirection",
187
+ "next": null,
188
+ "parent": null,
189
+ "inputs": {
190
+ "DIRECTION": [
191
+ 1,
192
+ [
193
+ 8,
194
+ "90"
195
+ ]
196
+ ]
197
+ },
198
+ "fields": {},
199
+ "shadow": false,
200
+ "topLevel": true,
201
+ "x": 493,
202
+ "y": 361
203
+ },
204
+ "motion_pointtowards": {
205
+ "opcode": "motion_pointtowards",
206
+ "next": null,
207
+ "parent": null,
208
+ "inputs": {
209
+ "TOWARDS": [
210
+ 1,
211
+ "6xQl1pPk%9E~Znhm*:ng"
212
+ ]
213
+ },
214
+ "fields": {},
215
+ "shadow": false,
216
+ "topLevel": true,
217
+ "x": 492,
218
+ "y": 463
219
+ },
220
+ "motion_pointtowards_menu": {
221
+ "opcode": "motion_pointtowards_menu",
222
+ "next": null,
223
+ "parent": "Ucm$YBs*^9GFTGXCbal@",
224
+ "inputs": {},
225
+ "fields": {
226
+ "TOWARDS": [
227
+ "_mouse_",
228
+ null
229
+ ]
230
+ },
231
+ "shadow": true,
232
+ "topLevel": false
233
+ },
234
+ "motion_changexby": {
235
+ "opcode": "motion_changexby",
236
+ "next": null,
237
+ "parent": null,
238
+ "inputs": {
239
+ "DX": [
240
+ 1,
241
+ [
242
+ 4,
243
+ "10"
244
+ ]
245
+ ]
246
+ },
247
+ "fields": {},
248
+ "shadow": false,
249
+ "topLevel": true,
250
+ "x": 851,
251
+ "y": -409
252
+ },
253
+ "motion_setx": {
254
+ "opcode": "motion_setx",
255
+ "next": null,
256
+ "parent": null,
257
+ "inputs": {
258
+ "X": [
259
+ 1,
260
+ [
261
+ 4,
262
+ "0"
263
+ ]
264
+ ]
265
+ },
266
+ "fields": {},
267
+ "shadow": false,
268
+ "topLevel": true,
269
+ "x": 864,
270
+ "y": -194
271
+ },
272
+ "motion_changeyby": {
273
+ "opcode": "motion_changeyby",
274
+ "next": null,
275
+ "parent": null,
276
+ "inputs": {
277
+ "DY": [
278
+ 1,
279
+ [
280
+ 4,
281
+ "10"
282
+ ]
283
+ ]
284
+ },
285
+ "fields": {},
286
+ "shadow": false,
287
+ "topLevel": true,
288
+ "x": 861,
289
+ "y": -61
290
+ },
291
+ "motion_sety": {
292
+ "opcode": "motion_sety",
293
+ "next": null,
294
+ "parent": null,
295
+ "inputs": {
296
+ "Y": [
297
+ 1,
298
+ [
299
+ 4,
300
+ "0"
301
+ ]
302
+ ]
303
+ },
304
+ "fields": {},
305
+ "shadow": false,
306
+ "topLevel": true,
307
+ "x": 864,
308
+ "y": 66
309
+ },
310
+ "motion_ifonedgebounce": {
311
+ "opcode": "motion_ifonedgebounce",
312
+ "next": null,
313
+ "parent": null,
314
+ "inputs": {},
315
+ "fields": {},
316
+ "shadow": false,
317
+ "topLevel": true,
318
+ "x": 1131,
319
+ "y": -397
320
+ },
321
+ "motion_setrotationstyle": {
322
+ "opcode": "motion_setrotationstyle",
323
+ "next": null,
324
+ "parent": null,
325
+ "inputs": {},
326
+ "fields": {
327
+ "STYLE": [
328
+ "left-right",
329
+ null
330
+ ]
331
+ },
332
+ "shadow": false,
333
+ "topLevel": true,
334
+ "x": 1128,
335
+ "y": -287
336
+ },
337
+ "motion_xposition": {
338
+ "opcode": "motion_xposition",
339
+ "next": null,
340
+ "parent": null,
341
+ "inputs": {},
342
+ "fields": {},
343
+ "shadow": false,
344
+ "topLevel": true,
345
+ "x": 1193,
346
+ "y": -136
347
+ },
348
+ "motion_yposition": {
349
+ "opcode": "motion_yposition",
350
+ "next": null,
351
+ "parent": null,
352
+ "inputs": {},
353
+ "fields": {},
354
+ "shadow": false,
355
+ "topLevel": true,
356
+ "x": 1181,
357
+ "y": -64
358
+ },
359
+ "motion_direction": {
360
+ "opcode": "motion_direction",
361
+ "next": null,
362
+ "parent": null,
363
+ "inputs": {},
364
+ "fields": {},
365
+ "shadow": false,
366
+ "topLevel": true,
367
+ "x": 1188,
368
+ "y": 21
369
+ }
370
+ }
v2/scratch_agent/blocks/classwise_blocks/operator_block.json ADDED
@@ -0,0 +1,409 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "operator_add": {
3
+ "opcode": "operator_add",
4
+ "next": null,
5
+ "parent": null,
6
+ "inputs": {
7
+ "NUM1": [
8
+ 1,
9
+ [
10
+ 4,
11
+ ""
12
+ ]
13
+ ],
14
+ "NUM2": [
15
+ 1,
16
+ [
17
+ 4,
18
+ ""
19
+ ]
20
+ ]
21
+ },
22
+ "fields": {},
23
+ "shadow": false,
24
+ "topLevel": true,
25
+ "x": 128,
26
+ "y": 153
27
+ },
28
+ "operator_subtract": {
29
+ "opcode": "operator_subtract",
30
+ "next": null,
31
+ "parent": null,
32
+ "inputs": {
33
+ "NUM1": [
34
+ 1,
35
+ [
36
+ 4,
37
+ ""
38
+ ]
39
+ ],
40
+ "NUM2": [
41
+ 1,
42
+ [
43
+ 4,
44
+ ""
45
+ ]
46
+ ]
47
+ },
48
+ "fields": {},
49
+ "shadow": false,
50
+ "topLevel": true,
51
+ "x": 134,
52
+ "y": 214
53
+ },
54
+ "operator_multiply": {
55
+ "opcode": "operator_multiply",
56
+ "next": null,
57
+ "parent": null,
58
+ "inputs": {
59
+ "NUM1": [
60
+ 1,
61
+ [
62
+ 4,
63
+ ""
64
+ ]
65
+ ],
66
+ "NUM2": [
67
+ 1,
68
+ [
69
+ 4,
70
+ ""
71
+ ]
72
+ ]
73
+ },
74
+ "fields": {},
75
+ "shadow": false,
76
+ "topLevel": true,
77
+ "x": 134,
78
+ "y": 278
79
+ },
80
+ "operator_divide": {
81
+ "opcode": "operator_divide",
82
+ "next": null,
83
+ "parent": null,
84
+ "inputs": {
85
+ "NUM1": [
86
+ 1,
87
+ [
88
+ 4,
89
+ ""
90
+ ]
91
+ ],
92
+ "NUM2": [
93
+ 1,
94
+ [
95
+ 4,
96
+ ""
97
+ ]
98
+ ]
99
+ },
100
+ "fields": {},
101
+ "shadow": false,
102
+ "topLevel": true,
103
+ "x": 138,
104
+ "y": 359
105
+ },
106
+ "operator_random": {
107
+ "opcode": "operator_random",
108
+ "next": null,
109
+ "parent": null,
110
+ "inputs": {
111
+ "FROM": [
112
+ 1,
113
+ [
114
+ 4,
115
+ "1"
116
+ ]
117
+ ],
118
+ "TO": [
119
+ 1,
120
+ [
121
+ 4,
122
+ "10"
123
+ ]
124
+ ]
125
+ },
126
+ "fields": {},
127
+ "shadow": false,
128
+ "topLevel": true,
129
+ "x": 311,
130
+ "y": 157
131
+ },
132
+ "operator_gt": {
133
+ "opcode": "operator_gt",
134
+ "next": null,
135
+ "parent": null,
136
+ "inputs": {
137
+ "OPERAND1": [
138
+ 1,
139
+ [
140
+ 10,
141
+ ""
142
+ ]
143
+ ],
144
+ "OPERAND2": [
145
+ 1,
146
+ [
147
+ 10,
148
+ "50"
149
+ ]
150
+ ]
151
+ },
152
+ "fields": {},
153
+ "shadow": false,
154
+ "topLevel": true,
155
+ "x": 348,
156
+ "y": 217
157
+ },
158
+ "operator_lt": {
159
+ "opcode": "operator_lt",
160
+ "next": null,
161
+ "parent": null,
162
+ "inputs": {
163
+ "OPERAND1": [
164
+ 1,
165
+ [
166
+ 10,
167
+ ""
168
+ ]
169
+ ],
170
+ "OPERAND2": [
171
+ 1,
172
+ [
173
+ 10,
174
+ "50"
175
+ ]
176
+ ]
177
+ },
178
+ "fields": {},
179
+ "shadow": false,
180
+ "topLevel": true,
181
+ "x": 345,
182
+ "y": 286
183
+ },
184
+ "operator_equals": {
185
+ "opcode": "operator_equals",
186
+ "next": null,
187
+ "parent": null,
188
+ "inputs": {
189
+ "OPERAND1": [
190
+ 1,
191
+ [
192
+ 10,
193
+ ""
194
+ ]
195
+ ],
196
+ "OPERAND2": [
197
+ 1,
198
+ [
199
+ 10,
200
+ "50"
201
+ ]
202
+ ]
203
+ },
204
+ "fields": {},
205
+ "shadow": false,
206
+ "topLevel": true,
207
+ "x": 345,
208
+ "y": 372
209
+ },
210
+ "operator_and": {
211
+ "opcode": "operator_and",
212
+ "next": null,
213
+ "parent": null,
214
+ "inputs": {},
215
+ "fields": {},
216
+ "shadow": false,
217
+ "topLevel": true,
218
+ "x": 701,
219
+ "y": 158
220
+ },
221
+ "operator_or": {
222
+ "opcode": "operator_or",
223
+ "next": null,
224
+ "parent": null,
225
+ "inputs": {},
226
+ "fields": {},
227
+ "shadow": false,
228
+ "topLevel": true,
229
+ "x": 705,
230
+ "y": 222
231
+ },
232
+ "operator_not": {
233
+ "opcode": "operator_not",
234
+ "next": null,
235
+ "parent": null,
236
+ "inputs": {},
237
+ "fields": {},
238
+ "shadow": false,
239
+ "topLevel": true,
240
+ "x": 734,
241
+ "y": 283
242
+ },
243
+ "operator_join": {
244
+ "opcode": "operator_join",
245
+ "next": null,
246
+ "parent": null,
247
+ "inputs": {
248
+ "STRING1": [
249
+ 1,
250
+ [
251
+ 10,
252
+ "apple "
253
+ ]
254
+ ],
255
+ "STRING2": [
256
+ 1,
257
+ [
258
+ 10,
259
+ "banana"
260
+ ]
261
+ ]
262
+ },
263
+ "fields": {},
264
+ "shadow": false,
265
+ "topLevel": true,
266
+ "x": 663,
267
+ "y": 378
268
+ },
269
+ "operator_letter_of": {
270
+ "opcode": "operator_letter_of",
271
+ "next": null,
272
+ "parent": null,
273
+ "inputs": {
274
+ "LETTER": [
275
+ 1,
276
+ [
277
+ 6,
278
+ "1"
279
+ ]
280
+ ],
281
+ "STRING": [
282
+ 1,
283
+ [
284
+ 10,
285
+ "apple"
286
+ ]
287
+ ]
288
+ },
289
+ "fields": {},
290
+ "shadow": false,
291
+ "topLevel": true,
292
+ "x": 664,
293
+ "y": 445
294
+ },
295
+ "operator_length": {
296
+ "opcode": "operator_length",
297
+ "next": null,
298
+ "parent": null,
299
+ "inputs": {
300
+ "STRING": [
301
+ 1,
302
+ [
303
+ 10,
304
+ "apple"
305
+ ]
306
+ ]
307
+ },
308
+ "fields": {},
309
+ "shadow": false,
310
+ "topLevel": true,
311
+ "x": 664,
312
+ "y": 521
313
+ },
314
+ "operator_contains": {
315
+ "opcode": "operator_contains",
316
+ "next": null,
317
+ "parent": null,
318
+ "inputs": {
319
+ "STRING1": [
320
+ 1,
321
+ [
322
+ 10,
323
+ "apple"
324
+ ]
325
+ ],
326
+ "STRING2": [
327
+ 1,
328
+ [
329
+ 10,
330
+ "a"
331
+ ]
332
+ ]
333
+ },
334
+ "fields": {},
335
+ "shadow": false,
336
+ "topLevel": true,
337
+ "x": 634,
338
+ "y": 599
339
+ },
340
+ "operator_mod": {
341
+ "opcode": "operator_mod",
342
+ "next": null,
343
+ "parent": null,
344
+ "inputs": {
345
+ "NUM1": [
346
+ 1,
347
+ [
348
+ 4,
349
+ ""
350
+ ]
351
+ ],
352
+ "NUM2": [
353
+ 1,
354
+ [
355
+ 4,
356
+ ""
357
+ ]
358
+ ]
359
+ },
360
+ "fields": {},
361
+ "shadow": false,
362
+ "topLevel": true,
363
+ "x": 295,
364
+ "y": 594
365
+ },
366
+ "operator_round": {
367
+ "opcode": "operator_round",
368
+ "next": null,
369
+ "parent": null,
370
+ "inputs": {
371
+ "NUM": [
372
+ 1,
373
+ [
374
+ 4,
375
+ ""
376
+ ]
377
+ ]
378
+ },
379
+ "fields": {},
380
+ "shadow": false,
381
+ "topLevel": true,
382
+ "x": 307,
383
+ "y": 674
384
+ },
385
+ "operator_mathop": {
386
+ "opcode": "operator_mathop",
387
+ "next": null,
388
+ "parent": null,
389
+ "inputs": {
390
+ "NUM": [
391
+ 1,
392
+ [
393
+ 4,
394
+ ""
395
+ ]
396
+ ]
397
+ },
398
+ "fields": {
399
+ "OPERATOR": [
400
+ "abs",
401
+ null
402
+ ]
403
+ },
404
+ "shadow": false,
405
+ "topLevel": true,
406
+ "x": 280,
407
+ "y": 754
408
+ }
409
+ }
v2/scratch_agent/blocks/classwise_blocks/sensing_block.json ADDED
@@ -0,0 +1,292 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "sensing_touchingobject": {
3
+ "opcode": "sensing_touchingobject",
4
+ "next": null,
5
+ "parent": null,
6
+ "inputs": {
7
+ "TOUCHINGOBJECTMENU": [
8
+ 1,
9
+ "sensing_touchingobjectmenu"
10
+ ]
11
+ },
12
+ "fields": {},
13
+ "shadow": false,
14
+ "topLevel": true,
15
+ "x": 359,
16
+ "y": 116
17
+ },
18
+ "sensing_touchingobjectmenu": {
19
+ "opcode": "sensing_touchingobjectmenu",
20
+ "next": null,
21
+ "parent": "sensing_touchingobject",
22
+ "inputs": {},
23
+ "fields": {
24
+ "TOUCHINGOBJECTMENU": [
25
+ "_mouse_",
26
+ null
27
+ ]
28
+ },
29
+ "shadow": true,
30
+ "topLevel": false
31
+ },
32
+ "sensing_touchingcolor": {
33
+ "opcode": "sensing_touchingcolor",
34
+ "next": null,
35
+ "parent": null,
36
+ "inputs": {
37
+ "COLOR": [
38
+ 1,
39
+ [
40
+ 9,
41
+ "#55b888"
42
+ ]
43
+ ]
44
+ },
45
+ "fields": {},
46
+ "shadow": false,
47
+ "topLevel": true,
48
+ "x": 360,
49
+ "y": 188
50
+ },
51
+ "sensing_coloristouchingcolor": {
52
+ "opcode": "sensing_coloristouchingcolor",
53
+ "next": null,
54
+ "parent": null,
55
+ "inputs": {
56
+ "COLOR": [
57
+ 1,
58
+ [
59
+ 9,
60
+ "#d019f2"
61
+ ]
62
+ ],
63
+ "COLOR2": [
64
+ 1,
65
+ [
66
+ 9,
67
+ "#2b0de3"
68
+ ]
69
+ ]
70
+ },
71
+ "fields": {},
72
+ "shadow": false,
73
+ "topLevel": true,
74
+ "x": 348,
75
+ "y": 277
76
+ },
77
+ "sensing_askandwait": {
78
+ "opcode": "sensing_askandwait",
79
+ "next": null,
80
+ "parent": null,
81
+ "inputs": {
82
+ "QUESTION": [
83
+ 1,
84
+ [
85
+ 10,
86
+ "What's your name?"
87
+ ]
88
+ ]
89
+ },
90
+ "fields": {},
91
+ "shadow": false,
92
+ "topLevel": true,
93
+ "x": 338,
94
+ "y": 354
95
+ },
96
+ "sensing_answer": {
97
+ "opcode": "sensing_answer",
98
+ "next": null,
99
+ "parent": null,
100
+ "inputs": {},
101
+ "fields": {},
102
+ "shadow": false,
103
+ "topLevel": true,
104
+ "x": 782,
105
+ "y": 111
106
+ },
107
+ "sensing_keypressed": {
108
+ "opcode": "sensing_keypressed",
109
+ "next": null,
110
+ "parent": null,
111
+ "inputs": {
112
+ "KEY_OPTION": [
113
+ 1,
114
+ "sensing_keyoptions"
115
+ ]
116
+ },
117
+ "fields": {},
118
+ "shadow": false,
119
+ "topLevel": true,
120
+ "x": 762,
121
+ "y": 207
122
+ },
123
+ "sensing_keyoptions": {
124
+ "opcode": "sensing_keyoptions",
125
+ "next": null,
126
+ "parent": "sensing_keypressed",
127
+ "inputs": {},
128
+ "fields": {
129
+ "KEY_OPTION": [
130
+ "space",
131
+ null
132
+ ]
133
+ },
134
+ "shadow": true,
135
+ "topLevel": false
136
+ },
137
+ "sensing_mousedown": {
138
+ "opcode": "sensing_mousedown",
139
+ "next": null,
140
+ "parent": null,
141
+ "inputs": {},
142
+ "fields": {},
143
+ "shadow": false,
144
+ "topLevel": true,
145
+ "x": 822,
146
+ "y": 422
147
+ },
148
+ "sensing_mousex": {
149
+ "opcode": "sensing_mousex",
150
+ "next": null,
151
+ "parent": null,
152
+ "inputs": {},
153
+ "fields": {},
154
+ "shadow": false,
155
+ "topLevel": true,
156
+ "x": 302,
157
+ "y": 528
158
+ },
159
+ "sensing_mousey": {
160
+ "opcode": "sensing_mousey",
161
+ "next": null,
162
+ "parent": null,
163
+ "inputs": {},
164
+ "fields": {},
165
+ "shadow": false,
166
+ "topLevel": true,
167
+ "x": 668,
168
+ "y": 547
169
+ },
170
+ "sensing_setdragmode": {
171
+ "opcode": "sensing_setdragmode",
172
+ "next": null,
173
+ "parent": null,
174
+ "inputs": {},
175
+ "fields": {
176
+ "DRAG_MODE": [
177
+ "draggable",
178
+ null
179
+ ]
180
+ },
181
+ "shadow": false,
182
+ "topLevel": true,
183
+ "x": 950,
184
+ "y": 574
185
+ },
186
+ "sensing_loudness": {
187
+ "opcode": "sensing_loudness",
188
+ "next": null,
189
+ "parent": null,
190
+ "inputs": {},
191
+ "fields": {},
192
+ "shadow": false,
193
+ "topLevel": true,
194
+ "x": 658,
195
+ "y": 703
196
+ },
197
+ "sensing_timer": {
198
+ "opcode": "sensing_timer",
199
+ "next": null,
200
+ "parent": null,
201
+ "inputs": {},
202
+ "fields": {},
203
+ "shadow": false,
204
+ "topLevel": true,
205
+ "x": 459,
206
+ "y": 671
207
+ },
208
+ "sensing_resettimer": {
209
+ "opcode": "sensing_resettimer",
210
+ "next": null,
211
+ "parent": null,
212
+ "inputs": {},
213
+ "fields": {},
214
+ "shadow": false,
215
+ "topLevel": true,
216
+ "x": 462,
217
+ "y": 781
218
+ },
219
+ "sensing_of": {
220
+ "opcode": "sensing_of",
221
+ "next": null,
222
+ "parent": null,
223
+ "inputs": {
224
+ "OBJECT": [
225
+ 1,
226
+ "sensing_of_object_menu"
227
+ ]
228
+ },
229
+ "fields": {
230
+ "PROPERTY": [
231
+ "backdrop #",
232
+ null
233
+ ]
234
+ },
235
+ "shadow": false,
236
+ "topLevel": true,
237
+ "x": 997,
238
+ "y": 754
239
+ },
240
+ "sensing_of_object_menu": {
241
+ "opcode": "sensing_of_object_menu",
242
+ "next": null,
243
+ "parent": "sensing_of",
244
+ "inputs": {},
245
+ "fields": {
246
+ "OBJECT": [
247
+ "_stage_",
248
+ null
249
+ ]
250
+ },
251
+ "shadow": true,
252
+ "topLevel": false
253
+ },
254
+ "sensing_current": {
255
+ "opcode": "sensing_current",
256
+ "next": null,
257
+ "parent": null,
258
+ "inputs": {},
259
+ "fields": {
260
+ "CURRENTMENU": [
261
+ "YEAR",
262
+ null
263
+ ]
264
+ },
265
+ "shadow": false,
266
+ "topLevel": true,
267
+ "x": 627,
268
+ "y": 884
269
+ },
270
+ "sensing_dayssince2000": {
271
+ "opcode": "sensing_dayssince2000",
272
+ "next": null,
273
+ "parent": null,
274
+ "inputs": {},
275
+ "fields": {},
276
+ "shadow": false,
277
+ "topLevel": true,
278
+ "x": 959,
279
+ "y": 903
280
+ },
281
+ "sensing_username": {
282
+ "opcode": "sensing_username",
283
+ "next": null,
284
+ "parent": null,
285
+ "inputs": {},
286
+ "fields": {},
287
+ "shadow": false,
288
+ "topLevel": true,
289
+ "x": 833,
290
+ "y": 757
291
+ }
292
+ }
v2/scratch_agent/blocks/classwise_blocks/sound_block.json ADDED
@@ -0,0 +1,167 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "sound_playuntildone": {
3
+ "opcode": "sound_playuntildone",
4
+ "next": null,
5
+ "parent": null,
6
+ "inputs": {
7
+ "SOUND_MENU": [
8
+ 1,
9
+ "sound_sounds_menu"
10
+ ]
11
+ },
12
+ "fields": {},
13
+ "shadow": false,
14
+ "topLevel": true,
15
+ "x": 253,
16
+ "y": 17
17
+ },
18
+ "sound_sounds_menu": {
19
+ "opcode": "sound_sounds_menu",
20
+ "next": null,
21
+ "parent": "sound_playuntildone and sound_play",
22
+ "inputs": {},
23
+ "fields": {
24
+ "SOUND_MENU": [
25
+ "Meow",
26
+ null
27
+ ]
28
+ },
29
+ "shadow": true,
30
+ "topLevel": false
31
+ },
32
+ "sound_play": {
33
+ "opcode": "sound_play",
34
+ "next": null,
35
+ "parent": null,
36
+ "inputs": {
37
+ "SOUND_MENU": [
38
+ 1,
39
+ "sound_sounds_menu"
40
+ ]
41
+ },
42
+ "fields": {},
43
+ "shadow": false,
44
+ "topLevel": true,
45
+ "x": 245,
46
+ "y": 122
47
+ },
48
+ "sound_stopallsounds": {
49
+ "opcode": "sound_stopallsounds",
50
+ "next": null,
51
+ "parent": null,
52
+ "inputs": {},
53
+ "fields": {},
54
+ "shadow": false,
55
+ "topLevel": true,
56
+ "x": 253,
57
+ "y": 245
58
+ },
59
+ "sound_changeeffectby": {
60
+ "opcode": "sound_changeeffectby",
61
+ "next": null,
62
+ "parent": null,
63
+ "inputs": {
64
+ "VALUE": [
65
+ 1,
66
+ [
67
+ 4,
68
+ "10"
69
+ ]
70
+ ]
71
+ },
72
+ "fields": {
73
+ "EFFECT": [
74
+ "PITCH",
75
+ null
76
+ ]
77
+ },
78
+ "shadow": false,
79
+ "topLevel": true,
80
+ "x": 653,
81
+ "y": 14
82
+ },
83
+ "sound_seteffectto": {
84
+ "opcode": "sound_seteffectto",
85
+ "next": null,
86
+ "parent": null,
87
+ "inputs": {
88
+ "VALUE": [
89
+ 1,
90
+ [
91
+ 4,
92
+ "100"
93
+ ]
94
+ ]
95
+ },
96
+ "fields": {
97
+ "EFFECT": [
98
+ "PITCH",
99
+ null
100
+ ]
101
+ },
102
+ "shadow": false,
103
+ "topLevel": true,
104
+ "x": 653,
105
+ "y": 139
106
+ },
107
+ "sound_cleareffects": {
108
+ "opcode": "sound_cleareffects",
109
+ "next": null,
110
+ "parent": null,
111
+ "inputs": {},
112
+ "fields": {},
113
+ "shadow": false,
114
+ "topLevel": true,
115
+ "x": 651,
116
+ "y": 242
117
+ },
118
+ "sound_changevolumeby": {
119
+ "opcode": "sound_changevolumeby",
120
+ "next": null,
121
+ "parent": null,
122
+ "inputs": {
123
+ "VOLUME": [
124
+ 1,
125
+ [
126
+ 4,
127
+ "-10"
128
+ ]
129
+ ]
130
+ },
131
+ "fields": {},
132
+ "shadow": false,
133
+ "topLevel": true,
134
+ "x": 645,
135
+ "y": 353
136
+ },
137
+ "sound_setvolumeto": {
138
+ "opcode": "sound_setvolumeto",
139
+ "next": null,
140
+ "parent": null,
141
+ "inputs": {
142
+ "VOLUME": [
143
+ 1,
144
+ [
145
+ 4,
146
+ "100"
147
+ ]
148
+ ]
149
+ },
150
+ "fields": {},
151
+ "shadow": false,
152
+ "topLevel": true,
153
+ "x": 1108,
154
+ "y": 5
155
+ },
156
+ "sound_volume": {
157
+ "opcode": "sound_volume",
158
+ "next": null,
159
+ "parent": null,
160
+ "inputs": {},
161
+ "fields": {},
162
+ "shadow": false,
163
+ "topLevel": true,
164
+ "x": 1136,
165
+ "y": 123
166
+ }
167
+ }
v2/scratch_agent/blocks/excel_contetn/hat_block.xlsx ADDED
Binary file (10.5 kB). View file
 
v2/scratch_agent/blocks/excel_contetn/stack_block.xlsx ADDED
Binary file (12.5 kB). View file
 
v2/scratch_agent/blocks/hat_blocks.json ADDED
@@ -0,0 +1,217 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "block_category": "Hat Blocks",
3
+ "description": "Hat blocks are characterized by a rounded top and a bump at the bottom. They initiate scripts, meaning they are the starting point for a sequence of interconnected blocks.",
4
+ "blocks": [
5
+ {
6
+ "block_name": "when green flag pressed",
7
+ "block_type": "Events",
8
+ "op_code": "event_whenflagclicked",
9
+ "block_shape": "Hat Block",
10
+ "functionality": "This Hat block initiates the script when the green flag is clicked, serving as the common starting point for most Scratch projects.",
11
+ "inputs": null,
12
+ "example_standalone": "when green flag clicked",
13
+ "example_with_other_blocks": [
14
+ {
15
+ "script": "when green flag clicked\n go to x: (0) y: (0)\n say [Hello!] for (2) seconds\nend",
16
+ "explanation": "This script makes the sprite go to the center of the stage and then say 'Hello!' for 2 seconds when the green flag is clicked."
17
+ }
18
+ ]
19
+ },
20
+ {
21
+ "block_name": "when () key pressed",
22
+ "block_type": "Events",
23
+ "op_code": "event_whenkeypressed",
24
+ "block_shape": "Hat Block",
25
+ "functionality": "This Hat block initiates the script when a specified keyboard key is pressed.",
26
+ "inputs": [
27
+ {
28
+ "name": "key",
29
+ "type": "dropdown",
30
+ "options": [
31
+ "space",
32
+ "up arrow",
33
+ "down arrow",
34
+ "right arrow",
35
+ "left arrow",
36
+ "any",
37
+ "a",
38
+ "b",
39
+ "c",
40
+ "d",
41
+ "e",
42
+ "f",
43
+ "g",
44
+ "h",
45
+ "i",
46
+ "j",
47
+ "k",
48
+ "l",
49
+ "m",
50
+ "n",
51
+ "o",
52
+ "p",
53
+ "q",
54
+ "r",
55
+ "s",
56
+ "t",
57
+ "u",
58
+ "v",
59
+ "w",
60
+ "x",
61
+ "y",
62
+ "z",
63
+ "0",
64
+ "1",
65
+ "2",
66
+ "3",
67
+ "4",
68
+ "5",
69
+ "6",
70
+ "7",
71
+ "8",
72
+ "9"
73
+ ]
74
+ }
75
+ ],
76
+ "example_standalone": "when [space v] key pressed",
77
+ "example_with_other_blocks": [
78
+ {
79
+ "script": "when [space v] key pressed\n repeat (10)\n change y by (10)\n wait (0.1) seconds\n change y by (-10)\n end",
80
+ "explanation": "This script makes the sprite jump when the spacebar is pressed."
81
+ },
82
+ {
83
+ "script": "when [right arrow v] key pressed\n point in direction (90)\n move (10) steps\nend",
84
+ "explanation": "This script moves the sprite right when the right arrow key is pressed."
85
+ }
86
+ ]
87
+ },
88
+ {
89
+ "block_name": "when this sprite clicked",
90
+ "block_type": "Events",
91
+ "op_code": "event_whenthisspriteclicked",
92
+ "block_shape": "Hat Block",
93
+ "functionality": "This Hat block starts the script when the sprite itself is clicked.",
94
+ "inputs": null,
95
+ "example_standalone": "when this sprite clicked",
96
+ "example_with_other_blocks": [
97
+ {
98
+ "script": "when this sprite clicked\n say [Ouch!] for (1) seconds\n change [score v] by (-1)\nend",
99
+ "explanation": "This script makes the sprite say 'Ouch!' and decreases the score by 1 when the sprite is clicked."
100
+ }
101
+ ]
102
+ },
103
+ {
104
+ "block_name": "when backdrop switches to ()",
105
+ "block_type": "Events",
106
+ "op_code": "event_whenbackdropswitchesto",
107
+ "block_shape": "Hat Block",
108
+ "functionality": "This Hat block triggers the script when the stage backdrop changes to a specified backdrop.",
109
+ "inputs": [
110
+ {
111
+ "name": "backdrop name",
112
+ "type": "dropdown",
113
+ "options": ["backdrop1", "backdrop2", "..."]
114
+ }
115
+ ],
116
+ "example_standalone": "when backdrop switches to [game over v]",
117
+ "example_with_other_blocks": [
118
+ {
119
+ "script": "when backdrop switches to [game over v]\n stop [all v]\nend",
120
+ "explanation": "This script stops all running processes when the backdrop changes to 'game over'."
121
+ },
122
+ {
123
+ "script": "when backdrop switches to [level completed v]\n stop [all v]\nend",
124
+ "explanation": "This script stops all running processes when the backdrop changes to 'level completed'."
125
+ }
126
+ ]
127
+ },
128
+ {
129
+ "block_name": "when () > ()",
130
+ "block_type": "Events",
131
+ "op_code": "event_whengreaterthan",
132
+ "block_shape": "Hat Block",
133
+ "functionality": "This Hat block starts the script when a certain value (e.g., loudness from a microphone, or the timer) exceeds a defined threshold.",
134
+ "inputs": [
135
+ {
136
+ "name": "value type",
137
+ "type": "dropdown",
138
+ "options": [
139
+ "loudness",
140
+ "timer"
141
+ ]
142
+ },
143
+ {
144
+ "name": "threshold",
145
+ "type": "number"
146
+ }
147
+ ],
148
+ "example_standalone": "when [loudness v] > (70)",
149
+ "example_with_other_blocks": [
150
+ {
151
+ "script": "when [loudness v] > (70)\n start sound [scream v]\nend",
152
+ "explanation": "This script starts a 'scream' sound when the microphone loudness exceeds 70."
153
+ }
154
+ ]
155
+ },
156
+ {
157
+ "block_name": "when I receive ()",
158
+ "block_type": "Events",
159
+ "op_code": "event_whenbroadcastreceived",
160
+ "block_shape": "Hat Block",
161
+ "functionality": "This Hat block initiates the script upon the reception of a specific broadcast message. This mechanism facilitates indirect communication between sprites or the stage.",
162
+ "inputs": [
163
+ {
164
+ "name": "message name",
165
+ "type": "dropdown",
166
+ "options": ["message1", "message2", "new message..."]
167
+ }
168
+ ],
169
+ "example_standalone": "when I receive [start game v]",
170
+ "example_with_other_blocks": [
171
+ {
172
+ "script": "when I receive [start game v]\n show\n go to x: (0) y: (0)\nend",
173
+ "explanation": "This script makes the sprite visible and moves it to the center of the stage when it receives the 'start game' broadcast."
174
+ },
175
+ {
176
+ "script": "when I receive [game over v]\n set score to 0\n stop [all v]\nend",
177
+ "explanation": "This script stops all and resets the score on stage when it receives the 'game over' broadcast."
178
+ }
179
+ ]
180
+ },
181
+ {
182
+ "block_name": "When I Start as a Clone",
183
+ "block_type": "Control",
184
+ "op_code": "control_start_as_clone",
185
+ "block_shape": "Hat Block",
186
+ "functionality": "This Hat block initiates the script when a clone of the sprite is created. It defines the behavior of individual clones.",
187
+ "inputs": null,
188
+ "example_standalone": "When I Start as a Clone",
189
+ "example_with_other_blocks": [
190
+ {
191
+ "script": "when I start as a clone\n go to x: (pick random -240 to 240) y: (pick random -180 to 180)\n show\n forever\n move (10) steps\n if on edge, bounce\n end\nend",
192
+ "explanation": "This script makes a newly created clone appear at a random position, become visible, and then continuously move 10 steps, bouncing if it hits an edge."
193
+ }
194
+ ]
195
+ },
196
+ {
197
+ "block_name": "define [my custom block]",
198
+ "block_type": "My Blocks",
199
+ "op_code": "procedures_definition",
200
+ "block_shape": "Hat Block",
201
+ "functionality": "This Hat block serves as the definition header for a custom block's script. It allows users to define reusable sequences of code by specifying the block's name and any input parameters it will accept. This promotes modularity and abstraction in projects.",
202
+ "inputs": [
203
+ {
204
+ "name": "PROCCONTAINER",
205
+ "type": "block_prototype"
206
+ }
207
+ ],
208
+ "example_standalone": "define jump (height)",
209
+ "example_with_other_blocks": [
210
+ {
211
+ "script": "define jump (height)\n change y by (height)\n wait (0.5) seconds\n change y by (0 - (height))\nend\n\nwhen green flag clicked\n jump (50)\nend",
212
+ "explanation": "This script first defines a custom block named 'jump' that takes a numerical input 'height'. The definition outlines the actions for jumping up and then down. Later, 'jump (50)' is called to make the sprite jump 50 units."
213
+ }
214
+ ]
215
+ }
216
+ ]
217
+ }
v2/scratch_agent/blocks/reporter_blocks.json ADDED
@@ -0,0 +1,709 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "block_category": "Reporter Blocks",
3
+ "description": "Reporter blocks have rounded edges. Their purpose is to report values, which can be numbers or strings, and are designed to fit into input slots of other blocks.",
4
+ "blocks": [
5
+ {
6
+ "block_name": "(x position)",
7
+ "block_type": "Motion",
8
+ "op_code": "motion_xposition",
9
+ "block_shape": "Reporter Block",
10
+ "functionality": "Reports the current X-coordinate of the sprite.[NOTE: not used in stage/backdrops]",
11
+ "inputs": null,
12
+ "example_standalone": "x position",
13
+ "example_with_other_blocks": [
14
+ {
15
+ "script": "when green flag clicked\n say (x position) for (2) seconds\nend",
16
+ "explanation": "This script makes the sprite say its current X-coordinate for 2 seconds."
17
+ }
18
+ ]
19
+ },
20
+ {
21
+ "block_name": "(y position)",
22
+ "block_type": "Motion",
23
+ "op_code": "motion_yposition",
24
+ "block_shape": "Reporter Block",
25
+ "functionality": "Reports the current Y coordinate of the sprite on the stage.[NOTE: not used in stage/backdrops]",
26
+ "inputs": null,
27
+ "example_standalone": "y position",
28
+ "example_with_other_blocks": [
29
+ {
30
+ "script": "set [worms v] to (y position)",
31
+ "explanation": "This script assigns the sprite's current Y position to the 'worms' variable."
32
+ }
33
+ ]
34
+ },
35
+ {
36
+ "block_name": "(direction)",
37
+ "block_type": "Motion",
38
+ "op_code": "motion_direction",
39
+ "block_shape": "Reporter Block",
40
+ "functionality": "Reports the current direction of the sprite in degrees (0 = up, 90 = right, 180 = down, -90 = left).[NOTE: not used in stage/backdrops]",
41
+ "inputs": null,
42
+ "example_standalone": "direction",
43
+ "example_with_other_blocks": [
44
+ {
45
+ "script": "when green flag clicked\n say (direction) for (2) seconds\nend",
46
+ "explanation": "This script makes the sprite say its current direction in degrees for 2 seconds."
47
+ }
48
+ ]
49
+ },
50
+ {
51
+ "block_name": "(costume ())",
52
+ "block_type": "Looks",
53
+ "op_code": "looks_costumenumbername",
54
+ "block_shape": "Reporter Block",
55
+ "functionality": "Reports the current costume's number or name.",
56
+ "inputs": [
57
+ {
58
+ "name": "NUMBER_NAME",
59
+ "type": "dropdown",
60
+ "options": [
61
+ "number",
62
+ "name"
63
+ ]
64
+ }
65
+ ],
66
+ "example_standalone": "costume [number v]",
67
+ "example_with_other_blocks": [
68
+ {
69
+ "script": "say join [I am costume ] (costume [name v])",
70
+ "explanation": "This script makes the sprite display its current costume name in a speech bubble."
71
+ }
72
+ ]
73
+ },
74
+ {
75
+ "block_name": "(size)",
76
+ "block_type": "Looks",
77
+ "op_code": "looks_size",
78
+ "block_shape": "Reporter Block",
79
+ "functionality": "Reports the current size of the sprite as a percentage.",
80
+ "inputs": null,
81
+ "example_standalone": "size",
82
+ "example_with_other_blocks": [
83
+ {
84
+ "script": "set size to ( (size) + (10) )",
85
+ "explanation": "This script increases the sprite's size by 10% from its current size."
86
+ }
87
+ ]
88
+ },
89
+ {
90
+ "block_name": "(backdrop ())",
91
+ "block_type": "Looks",
92
+ "op_code": "looks_backdropnumbername",
93
+ "block_shape": "Reporter Block",
94
+ "functionality": "Reports the current backdrop's number or name.",
95
+ "inputs": [
96
+ {
97
+ "name": "NUMBER_NAME",
98
+ "type": "dropdown",
99
+ "options": [
100
+ "number",
101
+ "name"
102
+ ]
103
+ }
104
+ ],
105
+ "example_standalone": "(backdrop [number v])",
106
+ "example_with_other_blocks": [
107
+ {
108
+ "script": "say join [Current backdrop: ] (backdrop [name v]) for (2) seconds",
109
+ "explanation": "This script makes the sprite say the name of the current stage backdrop for 2 seconds."
110
+ }
111
+ ]
112
+ },
113
+ {
114
+ "block_name": "(volume)",
115
+ "block_type": "Sound",
116
+ "op_code": "sound_volume",
117
+ "block_shape": "Reporter Block",
118
+ "functionality": "Reports the current volume level of the sprite.",
119
+ "inputs": null,
120
+ "example_standalone": "volume",
121
+ "example_with_other_blocks": [
122
+ {
123
+ "script": "say join [Current volume: ] (volume)",
124
+ "explanation": "This script makes the sprite display its current volume level in a speech bubble."
125
+ }
126
+ ]
127
+ },
128
+ {
129
+ "block_name": "(distance to ())",
130
+ "block_type": "Sensing",
131
+ "op_code": "sensing_distanceto",
132
+ "block_shape": "Reporter Block",
133
+ "functionality": "Reports the distance from the current sprite to the mouse-pointer or another specified sprite.",
134
+ "inputs": [
135
+ {
136
+ "name": "target",
137
+ "type": "dropdown",
138
+ "options": ["mouse-pointer", "Sprite1", "Sprite2", "...", "_edge_"]
139
+ }
140
+ ],
141
+ "example_standalone": "distance to [mouse-pointer v]",
142
+ "example_with_other_blocks": [
143
+ {
144
+ "script": "if <(distance to [Sprite2 v]) < (50)> then\n say [Too close!]\nend",
145
+ "explanation": "This script makes the sprite say 'Too close!' if it is less than 50 steps away from 'Sprite2'."
146
+ }
147
+ ]
148
+ },
149
+ {
150
+ "block_name": "(answer)",
151
+ "block_type": "Sensing",
152
+ "op_code": "sensing_answer",
153
+ "block_shape": "Reporter Block",
154
+ "functionality": "Holds the most recent text inputted using the 'Ask () and Wait' block.",
155
+ "inputs": null,
156
+ "example_standalone": "answer",
157
+ "example_with_other_blocks": [
158
+ {
159
+ "script": "ask [What is your name?] and wait\n say join [Hello ] (answer)",
160
+ "explanation": "This script prompts the user for their name and then uses the 'answer' block to incorporate their input into a greeting."
161
+ }
162
+ ]
163
+ },
164
+ {
165
+ "block_name": "(mouse x)",
166
+ "block_type": "Sensing",
167
+ "op_code": "sensing_mousex",
168
+ "block_shape": "Reporter Block",
169
+ "functionality": "Reports the mouse-pointer’s current X position on the stage.",
170
+ "inputs": null,
171
+ "example_standalone": "mouse x",
172
+ "example_with_other_blocks": [
173
+ {
174
+ "script": "go to x: (mouse x) y: (mouse y)",
175
+ "explanation": "This script makes the sprite follow the mouse pointer's X and Y coordinates."
176
+ }
177
+ ]
178
+ },
179
+ {
180
+ "block_name": "(mouse y)",
181
+ "block_type": "Sensing",
182
+ "op_code": "sensing_mousey",
183
+ "block_shape": "Reporter Block",
184
+ "functionality": "Reports the mouse-pointer’s current Y position on the stage.",
185
+ "inputs": null,
186
+ "example_standalone": "mouse y",
187
+ "example_with_other_blocks": [
188
+ {
189
+ "script": "if <(mouse y) < (0)> then\n say [Below center]",
190
+ "explanation": "This script makes the sprite say 'Below center' if the mouse pointer is in the lower half of the stage."
191
+ }
192
+ ]
193
+ },
194
+ {
195
+ "block_name": "(loudness)",
196
+ "block_type": "Sensing",
197
+ "op_code": "sensing_loudness",
198
+ "block_shape": "Reporter Block",
199
+ "functionality": "Reports the loudness of noise received by a microphone on a scale of 0 to 100.",
200
+ "inputs": null,
201
+ "example_standalone": "loudness",
202
+ "example_with_other_blocks": [
203
+ {
204
+ "script": "when green flag clicked\n forever\n if <(loudness) > (30)> then\n start sound [pop v]\nend",
205
+ "explanation": "This script continuously checks the microphone loudness and plays a 'pop' sound if it exceeds 30."
206
+ }
207
+ ]
208
+ },
209
+ {
210
+ "block_name": "(timer)",
211
+ "block_type": "Sensing",
212
+ "op_code": "sensing_timer",
213
+ "block_shape": "Reporter Block",
214
+ "functionality": "Reports the elapsed time since Scratch was launched or the timer was reset, increasing by 1 every second.",
215
+ "inputs": null,
216
+ "example_standalone": "timer",
217
+ "example_with_other_blocks": [
218
+ {
219
+ "script": "when green flag clicked\n reset timer\n wait (5) seconds\n say join [Time elapsed: ] (timer)",
220
+ "explanation": "This script resets the timer when the green flag is clicked, waits for 5 seconds, and then reports the elapsed time."
221
+ }
222
+ ]
223
+ },
224
+ {
225
+ "block_name": "(() of ())",
226
+ "block_type": "Sensing",
227
+ "op_code": "sensing_of",
228
+ "block_shape": "Reporter Block",
229
+ "functionality": "Reports a specified value (e.g., x position, direction, costume number) of a specified sprite or the Stage to be accessed in current sprite or stage.",
230
+ "inputs": [
231
+ {
232
+ "name": "value to report",
233
+ "type": "dropdown",
234
+ "options": [
235
+ "x position",
236
+ "y position",
237
+ "direction",
238
+ "costume #",
239
+ "costume name",
240
+ "size",
241
+ "volume",
242
+ "backdrop #",
243
+ "backdrop name"
244
+ ]
245
+ },
246
+ {
247
+ "name": "sprite/stage",
248
+ "type": "dropdown",
249
+ "options": ["Stage", "Sprite1", "Sprite2", "...", "_edge_"]
250
+ }
251
+ ],
252
+ "example_standalone": "x position of [Sprite1 v]",
253
+ "example_with_other_blocks": [
254
+ {
255
+ "script": "set [other sprite X v] to ( (x position) of [Sprite2 v] )",
256
+ "explanation": "This script sets the 'other sprite X' variable to the current X-position of 'Sprite2'."
257
+ }
258
+ ]
259
+ },
260
+ {
261
+ "block_name": "(current ())",
262
+ "block_type": "Sensing",
263
+ "op_code": "sensing_current",
264
+ "block_shape": "Reporter Block",
265
+ "functionality": "Reports the current local year, month, date, day of the week, hour, minutes, or seconds.",
266
+ "inputs": [
267
+ {
268
+ "name": "time unit",
269
+ "type": "dropdown",
270
+ "options": [
271
+ "year",
272
+ "month",
273
+ "date",
274
+ "day of week",
275
+ "hour",
276
+ "minute",
277
+ "second"
278
+ ]
279
+ }
280
+ ],
281
+ "example_standalone": "current [hour v]",
282
+ "example_with_other_blocks": [
283
+ {
284
+ "script": "say join [The current hour is ] (current [hour v])",
285
+ "explanation": "This script makes the sprite say the current hour."
286
+ }
287
+ ]
288
+ },
289
+ {
290
+ "block_name": "(days since 2000)",
291
+ "block_type": "Sensing",
292
+ "op_code": "sensing_dayssince2000",
293
+ "block_shape": "Reporter Block",
294
+ "functionality": "Reports the number of days (and fractions of a day) since 00:00:00 UTC on January 1, 2000.",
295
+ "inputs": null,
296
+ "example_standalone": "days since 2000",
297
+ "example_with_other_blocks": [
298
+ {
299
+ "script": "say join [Days passed: ] (days since 2000)",
300
+ "explanation": "This script makes the sprite display the number of days that have passed since January 1, 2000."
301
+ }
302
+ ]
303
+ },
304
+ {
305
+ "block_name": "(username)",
306
+ "block_type": "Sensing",
307
+ "op_code": "sensing_username",
308
+ "block_shape": "Reporter Block",
309
+ "functionality": "Reports the username of the user currently logged into Scratch. If no user is logged in, it reports nothing.",
310
+ "inputs": null,
311
+ "example_standalone": "username",
312
+ "example_with_other_blocks": [
313
+ {
314
+ "script": "say join [Hello, ] (username)",
315
+ "explanation": "This script makes the sprite greet the user by their Scratch username."
316
+ }
317
+ ]
318
+ },
319
+ {
320
+ "block_name": "(() + ())",
321
+ "block_type": "operator",
322
+ "op_code": "operator_add",
323
+ "block_shape": "Reporter Block",
324
+ "functionality": "Adds two numerical values.",
325
+ "inputs": [
326
+ {
327
+ "name": "number1",
328
+ "type": "number"
329
+ },
330
+ {
331
+ "name": "number2",
332
+ "type": "number"
333
+ }
334
+ ],
335
+ "example_standalone": "(5) + (3)",
336
+ "example_with_other_blocks": [
337
+ {
338
+ "script": "set [total v] to ( (number 1) + (number 2) )",
339
+ "explanation": "This script calculates the sum of 'number 1' and 'number 2' and stores the result in the 'total' variable."
340
+ }
341
+ ]
342
+ },
343
+ {
344
+ "block_name": "(() - ())",
345
+ "block_type": "operator",
346
+ "op_code": "operator_subtract",
347
+ "block_shape": "Reporter Block",
348
+ "functionality": "Subtracts the second numerical value from the first.",
349
+ "inputs": [
350
+ {
351
+ "name": "number1",
352
+ "type": "number"
353
+ },
354
+ {
355
+ "name": "number2",
356
+ "type": "number"
357
+ }
358
+ ],
359
+ "example_standalone": "((10) - (4))",
360
+ "example_with_other_blocks": [
361
+ {
362
+ "script": "set [difference v] to ( (number 1) - (number 2) )",
363
+ "explanation": "This script calculates the subtraction of 'number 2' from 'number 1' and stores the result in the 'difference' variable."
364
+ }
365
+ ]
366
+ },
367
+ {
368
+ "block_name": "(() * ())",
369
+ "block_type": "operator",
370
+ "op_code": "operator_multiply",
371
+ "block_shape": "Reporter Block",
372
+ "functionality": "Multiplies two numerical values.",
373
+ "inputs": [
374
+ {
375
+ "name": "number1",
376
+ "type": "number"
377
+ },
378
+ {
379
+ "name": "number2",
380
+ "type": "number"
381
+ }
382
+ ],
383
+ "example_standalone": "(6) * (7)",
384
+ "example_with_other_blocks": [
385
+ {
386
+ "script": "set [area v] to ( (length) * (width) )",
387
+ "explanation": "This script calculates the area by multiplying 'length' and 'width' variables and stores it in the 'area' variable."
388
+ }
389
+ ]
390
+ },
391
+ {
392
+ "block_name": "(() / ())",
393
+ "block_type": "operator",
394
+ "op_code": "operator_divide",
395
+ "block_shape": "Reporter Block",
396
+ "functionality": "Divides the first numerical value by the second.",
397
+ "inputs": [
398
+ {
399
+ "name": "number1",
400
+ "type": "number"
401
+ },
402
+ {
403
+ "name": "number2",
404
+ "type": "number"
405
+ }
406
+ ],
407
+ "example_standalone": "((20) / (5))",
408
+ "example_with_other_blocks": [
409
+ {
410
+ "script": "set [average v] to ( (total score) / (number of students) )",
411
+ "explanation": "This script calculates the average by dividing 'total score' by 'number of students' and stores it in the 'average' variable."
412
+ }
413
+ ]
414
+ },
415
+ {
416
+ "block_name": "(pick random () to ())",
417
+ "block_type": "operator",
418
+ "op_code": "operator_random",
419
+ "block_shape": "Reporter Block",
420
+ "functionality": "Generates a random integer within a specified inclusive range.",
421
+ "inputs": [
422
+ {
423
+ "name": "min",
424
+ "type": "number"
425
+ },
426
+ {
427
+ "name": "max",
428
+ "type": "number"
429
+ }
430
+ ],
431
+ "example_standalone": "(pick random (1) to (10))",
432
+ "example_with_other_blocks": [
433
+ {
434
+ "script": "go to x: (pick random -240 to 240) y: (pick random -180 to 180)",
435
+ "explanation": "This script moves the sprite to a random position on the stage."
436
+ }
437
+ ]
438
+ },
439
+ {
440
+ "block_name": "(join ()())",
441
+ "block_type": "operator",
442
+ "op_code": "operator_join",
443
+ "block_shape": "Reporter Block",
444
+ "functionality": "Concatenates two strings or values into a single string.",
445
+ "inputs": [
446
+ {
447
+ "name": "string1",
448
+ "type": "string/number"
449
+ },
450
+ {
451
+ "name": "string2",
452
+ "type": "string/number"
453
+ }
454
+ ],
455
+ "example_standalone": "(join [Hello ][World!])",
456
+ "example_with_other_blocks": [
457
+ {
458
+ "script": "say (join [Hello ][World!])",
459
+ "explanation": "This script makes the sprite display 'Hello World!' in a speech bubble by joining two string literals."
460
+ }
461
+ ]
462
+ },
463
+ {
464
+ "block_name": "letter () of ()",
465
+ "block_type": "operator",
466
+ "op_code": "operator_letterof",
467
+ "block_shape": "Reporter Block",
468
+ "functionality": "Reports the character at a specific numerical position within a string.",
469
+ "inputs": [
470
+ {
471
+ "name": "index",
472
+ "type": "number"
473
+ },
474
+ {
475
+ "name": "text",
476
+ "type": "string"
477
+ }
478
+ ],
479
+ "example_standalone": "(letter (1) of [apple])",
480
+ "example_with_other_blocks": [
481
+ {
482
+ "script": "say (letter (1) of [apple])",
483
+ "explanation": "This script makes the sprite display the first character of the string 'apple', which is 'a'."
484
+ }
485
+ ]
486
+ },
487
+ {
488
+ "block_name": "(length of ())",
489
+ "block_type": "operator",
490
+ "op_code": "operator_length",
491
+ "block_shape": "Reporter Block",
492
+ "functionality": "Reports the total number of characters in a given string.",
493
+ "inputs": [
494
+ {
495
+ "name": "text",
496
+ "type": "string"
497
+ }
498
+ ],
499
+ "example_standalone": "(length of [banana])",
500
+ "example_with_other_blocks": [
501
+ {
502
+ "script": "say (length of [banana])",
503
+ "explanation": "This script makes the sprite display the length of the string 'banana', which is 6."
504
+ }
505
+ ]
506
+ },
507
+ {
508
+ "block_name": "(() mod ())",
509
+ "block_type": "operator",
510
+ "op_code": "operator_mod",
511
+ "block_shape": "Reporter Block",
512
+ "functionality": "Reports the remainder when the first number is divided by the second.",
513
+ "inputs": [
514
+ {
515
+ "name": "number1",
516
+ "type": "number"
517
+ },
518
+ {
519
+ "name": "number2",
520
+ "type": "number"
521
+ }
522
+ ],
523
+ "example_standalone": "((10) mod (3))",
524
+ "example_with_other_blocks": [
525
+ {
526
+ "script": "if <([number v] mod (2) = (0))> then\n say [Even number]",
527
+ "explanation": "This script checks if a 'number' variable is even by checking if its remainder when divided by 2 is 0."
528
+ }
529
+ ]
530
+ },
531
+ {
532
+ "block_name": "(round ())",
533
+ "block_type": "operator",
534
+ "op_code": "operator_round",
535
+ "block_shape": "Reporter Block",
536
+ "functionality": "Rounds a numerical value to the nearest integer.",
537
+ "inputs": [
538
+ {
539
+ "name": "number",
540
+ "type": "number"
541
+ }
542
+ ],
543
+ "example_standalone": "(round (3.7))",
544
+ "example_with_other_blocks": [
545
+ {
546
+ "script": "set [rounded score v] to (round (score))",
547
+ "explanation": "This script rounds the 'score' variable to the nearest whole number and stores it in 'rounded score'."
548
+ }
549
+ ]
550
+ },
551
+ {
552
+ "block_name": "(() of ())",
553
+ "block_type": "operator",
554
+ "op_code": "operator_mathop",
555
+ "block_shape": "Reporter Block",
556
+ "functionality": "Performs various mathematical functions (e.g., absolute value, square root, trigonometric functions).",
557
+ "inputs": [
558
+ {
559
+ "name": "function type",
560
+ "type": "dropdown",
561
+ "options": [
562
+ "abs",
563
+ "floor",
564
+ "ceiling",
565
+ "sqrt",
566
+ "sin",
567
+ "cos",
568
+ "tan",
569
+ "asin",
570
+ "acos",
571
+ "atan",
572
+ "ln",
573
+ "log",
574
+ "e ^",
575
+ "10 ^"
576
+ ]
577
+ },
578
+ {
579
+ "name": "value",
580
+ "type": "number"
581
+ }
582
+ ],
583
+ "example_standalone": "([sqrt v] of (25))",
584
+ "example_with_other_blocks": [
585
+ {
586
+ "script": "set [distance v] to ([sqrt v] of ( ( (x position) * (x position) ) + ( (y position) * (y position) ) ))",
587
+ "explanation": "This script calculates the distance from the origin (0,0) using the Pythagorean theorem and stores it in 'distance'."
588
+ }
589
+ ]
590
+ },
591
+ {
592
+ "block_name": "[variable v]",
593
+ "block_type": "Data",
594
+ "op_code": "data_variable",
595
+ "block_shape": "Reporter Block",
596
+ "functionality": "Provides the current value stored in a variable.",
597
+ "inputs": [
598
+ {
599
+ "name": "variable name",
600
+ "type": "dropdown",
601
+ "options": ["my variable", "score", "..."]
602
+ }
603
+ ],
604
+ "example_standalone": "[score v]",
605
+ "example_with_other_blocks": [
606
+ {
607
+ "script": "say ([score v]) for (2) seconds",
608
+ "explanation": "This script makes the sprite say the current value of the 'score' variable for 2 seconds."
609
+ }
610
+ ]
611
+ },
612
+ {
613
+ "block_name": "[list v]",
614
+ "block_type": "Data",
615
+ "op_code": "data_list",
616
+ "block_shape": "Reporter Block",
617
+ "functionality": "Reports the entire content of a specified list. When clicked in the editor, it displays the list as a monitor.",
618
+ "inputs": [
619
+ {
620
+ "name": "list name",
621
+ "type": "dropdown",
622
+ "options": ["my list", "list2", "..."]
623
+ }
624
+ ],
625
+ "example_standalone": "[my list v]",
626
+ "example_with_other_blocks": [
627
+ {
628
+ "script": "say ([my list v]) ",
629
+ "explanation": "This script makes the sprite say all the contents of 'my list'."
630
+ }
631
+ ]
632
+ },
633
+ {
634
+ "block_name": "(item (2) of [myList v])",
635
+ "block_type": "Data",
636
+ "op_code": "data_itemoflist",
637
+ "block_shape": "Reporter Block",
638
+ "functionality": "Reports the item located at a specific position in a list.",
639
+ "inputs": [
640
+ {
641
+ "name": "index/option",
642
+ "type": "number or dropdown",
643
+ "options": [
644
+ "last",
645
+ "random"
646
+ ]
647
+ },
648
+ {
649
+ "name": "list name",
650
+ "type": "dropdown",
651
+ "options": ["shopping list", "my list", "..."]
652
+ }
653
+ ],
654
+ "example_standalone": "item (1) of [shopping list v]",
655
+ "example_with_other_blocks": [
656
+ {
657
+ "script": "say (item (2) of [myList v]) for 2 seconds ",
658
+ "explanation": "This script makes the sprite display the first item from the 'shopping list'."
659
+ }
660
+ ]
661
+ },
662
+ {
663
+ "block_name": "(length of [myList v])",
664
+ "block_type": "Data",
665
+ "op_code": "data_lengthoflist",
666
+ "block_shape": "Reporter Block",
667
+ "functionality": "Provides the total number of items contained in a list.",
668
+ "inputs": [
669
+ {
670
+ "name": "list name",
671
+ "type": "dropdown",
672
+ "options": ["my list", "shopping list", "..."]
673
+ }
674
+ ],
675
+ "example_standalone": "(length of [myList v])",
676
+ "example_with_other_blocks": [
677
+ {
678
+ "script": "say join (length of [shopping list v]) [ items in the list.]",
679
+ "explanation": "This script makes the sprite display the total number of items currently in the 'shopping list'."
680
+ }
681
+ ]
682
+ },
683
+ {
684
+ "block_name": "(item # of [Dog] in [myList v])",
685
+ "block_type": "Data",
686
+ "op_code": "data_itemnumoflist",
687
+ "block_shape": "Reporter Block",
688
+ "functionality": "Reports the index number of the first occurrence of a specified item in a list. If the item is not found, it reports 0.",
689
+ "inputs": [
690
+ {
691
+ "name": "item",
692
+ "type": "string/number"
693
+ },
694
+ {
695
+ "name": "list name",
696
+ "type": "dropdown",
697
+ "options": ["my list", "shopping list", "..."]
698
+ }
699
+ ],
700
+ "example_standalone": "(item # of [apple] in [shopping list v])",
701
+ "example_with_other_blocks": [
702
+ {
703
+ "script": "if <(item # of [Dog] in [myList v])> (0)> then\n say join [Dog found at position ] (item # of [Dog] in [my list v])",
704
+ "explanation": "This script checks if 'banana' is in 'my list' and, if so, reports its position."
705
+ }
706
+ ]
707
+ }
708
+ ]
709
+ }
v2/scratch_agent/blocks/stack_blocks.json ADDED
@@ -0,0 +1,1321 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "block_category": "Stack Blocks",
3
+ "description": "Stack blocks are the most common block shape, featuring a notch at the top and a bump at the bottom. They perform the main commands within a script and can connect both above and below them.",
4
+ "blocks": [
5
+ {
6
+ "block_name": "move () steps",
7
+ "block_type": "Motion",
8
+ "block_shape": "Stack Block",
9
+ "op_code": "motion_movesteps",
10
+ "functionality": "Moves the sprite forward by the specified number of steps in the direction it is currently facing. A positive value moves it forward, and a negative value moves it backward.",
11
+ "inputs": [
12
+ {
13
+ "name": "STEPS",
14
+ "type": "number"
15
+ }
16
+ ],
17
+ "example_standalone": "move () steps",
18
+ "example_with_other_blocks": [
19
+ {
20
+ "script": "when green flag clicked\n go to x: (0) y: (0)\n point in direction (90)\n move (50) steps\nend",
21
+ "explanation": "This script first places the sprite at the center of the stage, points it to the right (90 degrees), and then moves it 50 steps in that direction."
22
+ }
23
+ ]
24
+ },
25
+ {
26
+ "block_name": "turn right () degrees",
27
+ "block_type": "Motion",
28
+ "block_shape": "Stack Block",
29
+ "op_code": "motion_turnright",
30
+ "functionality": "Turns the sprite clockwise by the specified number of degrees.",
31
+ "inputs": [
32
+ {
33
+ "name": "DEGREES",
34
+ "type": "number"
35
+ }
36
+ ],
37
+ "example_standalone": "turn (clockwise icon) (15) degrees",
38
+ "example_with_other_blocks": [
39
+ {
40
+ "script": "when [right arrow v] key pressed\n turn (clockwise icon) (15) degrees\nend",
41
+ "explanation": "This script makes the sprite turn clockwise by 15 degrees every time the right arrow key is pressed."
42
+ },
43
+ {
44
+ "script": "when green flag clicked\n forever\n turn (clockwise icon) (15) degrees\n wait (0.5) seconds\n end",
45
+ "explanation": "This script makes the sprite continuously spin clockwise by 15 degrees every half second."
46
+ }
47
+ ]
48
+ },
49
+ {
50
+ "block_name": "turn left () degrees",
51
+ "block_type": "Motion",
52
+ "block_shape": "Stack Block",
53
+ "op_code": "motion_turnleft",
54
+ "functionality": "Turns the sprite counter-clockwise by the specified number of degrees.",
55
+ "inputs": [
56
+ {
57
+ "name": "DEGREES",
58
+ "type": "number"
59
+ }
60
+ ],
61
+ "example_standalone": "turn (counter-clockwise icon) (15) degrees",
62
+ "example_with_other_blocks": [
63
+ {
64
+ "script": "when [left arrow v] key pressed\n turn (counter-clockwise icon) (15) degrees\nend",
65
+ "explanation": "This script makes the sprite turn counter-clockwise by 15 degrees every time the left arrow key is pressed."
66
+ },
67
+ {
68
+ "script": "when green flag clicked\n forever\n turn (counter-clockwise icon) (15) degrees\n wait (0.5) seconds\n end\nend",
69
+ "explanation": "This script makes the sprite continuously spin counter-clockwise by 15 degrees every half second."
70
+ }
71
+ ]
72
+ },
73
+ {
74
+ "block_name": "go to ()",
75
+ "block_type": "Motion",
76
+ "block_shape": "Stack Block",
77
+ "op_code": "motion_goto",
78
+ "functionality": "Moves the sprite to a specified location, which can be a random position or at the mouse pointer or another to the sprite.",
79
+ "inputs": [
80
+ {
81
+ "name": "TO",
82
+ "type": "dropdown",
83
+ "options": [
84
+ "random position",
85
+ "mouse-pointer",
86
+ "sprite1",
87
+ "..."
88
+ ]
89
+ }
90
+ ],
91
+ "example_standalone": "go to [random position v]",
92
+ "example_with_other_blocks": [
93
+ {
94
+ "script": "when this sprite clicked\n go to [mouse-pointer v]",
95
+ "explanation": "This script moves the sprite to the current position of the mouse pointer whenever the sprite is clicked."
96
+ },
97
+ {
98
+ "script": "when this sprite clicked\n go to [sprite v]",
99
+ "explanation": "This script moves the sprite to the another sprite's position whenever the sprite is clicked."
100
+ }
101
+ ]
102
+ },
103
+ {
104
+ "block_name": "go to x: () y: ()",
105
+ "block_type": "Motion",
106
+ "block_shape": "Stack Block",
107
+ "op_code": "motion_gotoxy",
108
+ "functionality": "Moves the sprite to the specified X and Y coordinates on the stage.",
109
+ "inputs": [
110
+ {
111
+ "name": "X",
112
+ "type": "number"
113
+ },
114
+ {
115
+ "name": "Y",
116
+ "type": "number"
117
+ }
118
+ ],
119
+ "example_standalone": "go to x: (0) y: (0)",
120
+ "example_with_other_blocks": [
121
+ {
122
+ "script": "when green flag clicked\n go to x: (120) y: (0)\n say [Ready to start! v] for (1) seconds\nend",
123
+ "explanation": "This script positions the sprite at the center of the stage at the beginning of the project and then makes it say 'Ready to start!'."
124
+ }
125
+ ]
126
+ },
127
+ {
128
+ "block_name": "glide () secs to ()",
129
+ "block_type": "Motion",
130
+ "block_shape": "Stack Block",
131
+ "op_code": "motion_glideto",
132
+ "functionality": "Glides the sprite smoothly to a specified location (random position, mouse pointer, or another sprite) over a given number of seconds.",
133
+ "inputs": [
134
+ {
135
+ "name": "SECS",
136
+ "type": "number"
137
+ },
138
+ {
139
+ "name": "TO",
140
+ "type": "dropdown",
141
+ "options": [
142
+ "random position",
143
+ "mouse-pointer",
144
+ "sprite1",
145
+ "sprite2",
146
+ "..."
147
+ ]
148
+ }
149
+ ],
150
+ "example_standalone": "glide (1) secs to ([random position v])",
151
+ "example_with_other_blocks": [
152
+ {
153
+ "script": "when green flag clicked\n glide (1) secs to ([mouse-pointer v])\nend",
154
+ "explanation": "This script makes the sprite glide smoothly to the mouse pointer's position over 1 second when the green flag is clicked."
155
+ }
156
+ ]
157
+ },
158
+ {
159
+ "block_name": "glide () secs to x: () y: ()",
160
+ "block_type": "Motion",
161
+ "block_shape": "Stack Block",
162
+ "op_code": "motion_glidesecstoxy",
163
+ "functionality": "Glides the sprite smoothly to the specified X and Y coordinates over a given number of seconds.",
164
+ "inputs": [
165
+ {
166
+ "name": "SECS",
167
+ "type": "number"
168
+ },
169
+ {
170
+ "name": "X",
171
+ "type": "number"
172
+ },
173
+ {
174
+ "name": "Y",
175
+ "type": "number"
176
+ }
177
+ ],
178
+ "example_standalone": "glide (1) secs to x: (100) y: (50)",
179
+ "example_with_other_blocks": [
180
+ {
181
+ "script": "when green flag clicked\n glide (2) secs to x: (150) y: (-100)\n glide (2) secs to x: (-150) y: (100)\nend",
182
+ "explanation": "This script makes the sprite glide to two different points on the stage, taking 2 seconds for each movement."
183
+ }
184
+ ]
185
+ },
186
+ {
187
+ "block_name": "point in direction ()",
188
+ "block_type": "Motion",
189
+ "block_shape": "Stack Block",
190
+ "op_code": "motion_pointindirection",
191
+ "functionality": "Sets the sprite's direction to a specified angle in degrees (0 = up, 90 = right, 180 = down, -90 = left).",
192
+ "inputs": [
193
+ {
194
+ "name": "DIRECTION",
195
+ "type": "number"
196
+ }
197
+ ],
198
+ "example_standalone": "point in direction (90)",
199
+ "example_with_other_blocks": [
200
+ {
201
+ "script": "when green flag clicked\n point in direction (0)\n move (100) steps\nend",
202
+ "explanation": "This script makes the sprite point upwards (0 degrees) and then move 100 steps in that direction."
203
+ }
204
+ ]
205
+ },
206
+ {
207
+ "block_name": "point towards ()",
208
+ "block_type": "Motion",
209
+ "block_shape": "Stack Block",
210
+ "op_code": "motion_pointtowards",
211
+ "functionality": "Points the sprite towards the mouse pointer or another specified sprite.",
212
+ "inputs": [
213
+ {
214
+ "name": "TOWARDS",
215
+ "type": "dropdown",
216
+ "options": [
217
+ "mouse-pointer",
218
+ "sprite1",
219
+ "..."
220
+ ]
221
+ }
222
+ ],
223
+ "example_standalone": "point towards [mouse-pointer v]",
224
+ "example_with_other_blocks": [
225
+ {
226
+ "script": "when this sprite clicked\n point towards [mouse-pointer v]\n move (10) steps\nend",
227
+ "explanation": "When the sprite is clicked, it will point towards the mouse pointer and then move 10 steps in that direction."
228
+ },
229
+ {
230
+ "script": "when green flag clicked\n forever\n point towards [mouse-pointer v]\n move (5) steps\n end\nend",
231
+ "explanation": "This script makes the sprite continuously follow the mouse pointer."
232
+ }
233
+ ]
234
+ },
235
+ {
236
+ "block_name": "change x by ()",
237
+ "block_type": "Motion",
238
+ "block_shape": "Stack Block",
239
+ "op_code": "motion_changexby",
240
+ "functionality": "Changes the sprite's X-coordinate by the specified amount, moving it horizontally.",
241
+ "inputs": [
242
+ {
243
+ "name": "DX",
244
+ "type": "number"
245
+ }
246
+ ],
247
+ "example_standalone": "change x by (10)",
248
+ "example_with_other_blocks": [
249
+ {
250
+ "script": "when [right arrow v] key pressed\n change x by (10)\nend",
251
+ "explanation": "This script moves the sprite 10 steps to the right when the right arrow key is pressed."
252
+ }
253
+ ]
254
+ },
255
+ {
256
+ "block_name": "set x to ()",
257
+ "block_type": "Motion",
258
+ "block_shape": "Stack Block",
259
+ "op_code": "motion_setx",
260
+ "functionality": "Sets the sprite's X-coordinate to a specific value, placing it at a precise horizontal position.",
261
+ "inputs": [
262
+ {
263
+ "name": "X",
264
+ "type": "number"
265
+ }
266
+ ],
267
+ "example_standalone": "set x to (0)",
268
+ "example_with_other_blocks": [
269
+ {
270
+ "script": "when green flag clicked\n set x to (0)\n set y to (0)\nend",
271
+ "explanation": "This script centers the sprite horizontally at the start of the project."
272
+ }
273
+ ]
274
+ },
275
+ {
276
+ "block_name": "change y by ()",
277
+ "block_type": "Motion",
278
+ "block_shape": "Stack Block",
279
+ "op_code": "motion_changeyby",
280
+ "functionality": "Changes the sprite's Y-coordinate by the specified amount, moving it vertically.",
281
+ "inputs": [
282
+ {
283
+ "name": "DY",
284
+ "type": "number"
285
+ }
286
+ ],
287
+ "example_standalone": "change y by (10)",
288
+ "example_with_other_blocks": [
289
+ {
290
+ "script": "when [up arrow v] key pressed\n change y by (10)\nend",
291
+ "explanation": "This script moves the sprite 10 steps up when the up arrow key is pressed."
292
+ }
293
+ ]
294
+ },
295
+ {
296
+ "block_name": "set y to ()",
297
+ "block_type": "Motion",
298
+ "block_shape": "Stack Block",
299
+ "op_code": "motion_sety",
300
+ "functionality": "Sets the sprite's Y-coordinate to a specific value, placing it at a precise vertical position.",
301
+ "inputs": [
302
+ {
303
+ "name": "Y",
304
+ "type": "number"
305
+ }
306
+ ],
307
+ "example_standalone": "set y to (0)",
308
+ "example_with_other_blocks": [
309
+ {
310
+ "script": "when green flag clicked\n set x to (0)\n set y to (0)\nend",
311
+ "explanation": "This script centers the sprite vertically at the start of the project."
312
+ }
313
+ ]
314
+ },
315
+ {
316
+ "block_name": "if on edge, bounce",
317
+ "block_type": "Motion",
318
+ "block_shape": "Stack Block",
319
+ "op_code": "motion_ifonedgebounce",
320
+ "functionality": "Reverses the sprite's direction if it touches the edge of the stage.",
321
+ "inputs": null,
322
+ "example_standalone": "if on edge, bounce",
323
+ "example_with_other_blocks": [
324
+ {
325
+ "script": "when I receive [start moving v]\n repeat (50)\n move (5) steps\n if on edge, bounce\n end\nend",
326
+ "explanation": "Upon receiving the 'start moving' broadcast, the sprite will move 5 steps repeatedly for 50 times, bouncing off edges if it touches them."
327
+ },
328
+ {
329
+ "script": "when green flag clicked\n forever\n move (10) steps\n if on edge, bounce\n end\nend",
330
+ "explanation": "This script makes the sprite move continuously and bounce off the edges of the stage."
331
+ }
332
+ ]
333
+ },
334
+ {
335
+ "block_name": "set rotation style ()",
336
+ "block_type": "Motion",
337
+ "block_shape": "Stack Block",
338
+ "op_code": "motion_setrotationstyle",
339
+ "functionality": "Determines how the sprite rotates: 'left-right' (flips horizontally), 'don't rotate' (stays facing one direction), or 'all around' (rotates freely).",
340
+ "inputs": [
341
+ {
342
+ "name": "STYLE",
343
+ "type": "dropdown",
344
+ "options": [
345
+ "left-right",
346
+ "don't rotate",
347
+ "all around"
348
+ ]
349
+ }
350
+ ],
351
+ "example_standalone": "set rotation style [left-right v]",
352
+ "example_with_other_blocks": [
353
+ {
354
+ "script": "when backdrop switches to [game level 1 v]\n set rotation style [all around v]\nend",
355
+ "explanation": "When the backdrop changes to 'game level 1', the sprite's rotation style will be set to 'all around', allowing it to rotate freely."
356
+ },
357
+ {
358
+ "script": "when green flag clicked\n set rotation style [left-right v]\n forever\n move (10) steps\n if on edge, bounce\n end \nend",
359
+ "explanation": "This script makes the sprite move horizontally and flip its costume when it hits an edge, instead of rotating."
360
+ }
361
+ ]
362
+ },
363
+ {
364
+ "block_name": "say () for () seconds",
365
+ "block_type": "Looks",
366
+ "block_shape": "Stack Block",
367
+ "op_code": "looks_sayforsecs",
368
+ "functionality": "Displays a speech bubble containing specified text for a set duration.",
369
+ "inputs": [
370
+ {
371
+ "name": "MESSAGE",
372
+ "type": "string"
373
+ },
374
+ {
375
+ "name": "SECS",
376
+ "type": "number"
377
+ }
378
+ ],
379
+ "example_standalone": "say [Hello!] for (2) seconds",
380
+ "example_with_other_blocks": [
381
+ {
382
+ "script": "when green flag clicked\n say [Grr] for (3) seconds\n say [Have you seen my honey? v] for (3) seconds\nend",
383
+ "explanation": "This script makes the sprite display two sequential speech bubbles with different messages and durations. First, it says 'Grr' for 3 seconds, then 'Have you seen my honey?' for another 3 seconds."
384
+ }
385
+ ]
386
+ },
387
+ {
388
+ "block_name": "say ()",
389
+ "block_type": "Looks",
390
+ "block_shape": "Stack Block",
391
+ "op_code": "looks_say",
392
+ "functionality": "Displays a speech bubble with the specified text indefinitely until another 'say' or 'think' block is activated.",
393
+ "inputs": [
394
+ {
395
+ "name": "MESSAGE",
396
+ "type": "string"
397
+ }
398
+ ],
399
+ "example_standalone": "say [Hello! v]",
400
+ "example_with_other_blocks": [
401
+ {
402
+ "script": "when green flag clicked\n say [Welcome to my game! v]\n wait (2) seconds\n say [] \nend",
403
+ "explanation": "This script makes the sprite say 'Welcome to my game!' for 2 seconds, then clears the speech bubble."
404
+ }
405
+ ]
406
+ },
407
+ {
408
+ "block_name": "think () for () seconds",
409
+ "block_type": "Looks",
410
+ "block_shape": "Stack Block",
411
+ "op_code": "looks_thinkforsecs",
412
+ "functionality": "Displays a thought bubble containing specified text for a set duration.",
413
+ "inputs": [
414
+ {
415
+ "name": "MESSAGE",
416
+ "type": "string"
417
+ },
418
+ {
419
+ "name": "SECS",
420
+ "type": "number"
421
+ }
422
+ ],
423
+ "example_standalone": "think [Hmm... v] for (2) seconds",
424
+ "example_with_other_blocks": [
425
+ {
426
+ "script": "when this sprite clicked\n think [What should I do? v] for (2) seconds\nend",
427
+ "explanation": "This script makes the sprite display a thought bubble saying 'What should I do?' for 2 seconds when clicked."
428
+ }
429
+ ]
430
+ },
431
+ {
432
+ "block_name": "think ()",
433
+ "block_type": "Looks",
434
+ "block_shape": "Stack Block",
435
+ "op_code": "looks_think",
436
+ "functionality": "Displays a thought bubble with the specified text indefinitely until another 'say' or 'think' block is activated.",
437
+ "inputs": [
438
+ {
439
+ "name": "MESSAGE",
440
+ "type": "string"
441
+ }
442
+ ],
443
+ "example_standalone": "think [Got it! v]",
444
+ "example_with_other_blocks": [
445
+ {
446
+ "script": "when I receive [correct answer v]\n think [That's right! v]\n wait (1) seconds\n think [good v] \nend",
447
+ "explanation": "This script makes the sprite think 'That's right!' for 1 second when a 'correct answer' broadcast is received, then clears the thought bubble."
448
+ }
449
+ ]
450
+ },
451
+ {
452
+ "block_name": "switch costume to ()",
453
+ "block_type": "Looks",
454
+ "block_shape": "Stack Block",
455
+ "op_code": "looks_switchcostumeto",
456
+ "functionality": "Alters the sprite's appearance to a designated costume.",
457
+ "inputs": [
458
+ {
459
+ "name": "COSTUME",
460
+ "type": "dropdown/number"
461
+ }
462
+ ],
463
+ "example_standalone": "switch costume to [costume1 v]",
464
+ "example_with_other_blocks": [
465
+ {
466
+ "script": "when I receive [explosion v]\n repeat (5)\n next costume\n end\n hide[costume1 v] \nend",
467
+ "explanation": "This script animates an explosion by rapidly switching costumes, then hides the sprite. [3]"
468
+ }
469
+ ]
470
+ },
471
+ {
472
+ "block_name": "next costume",
473
+ "block_type": "Looks",
474
+ "block_shape": "Stack Block",
475
+ "op_code": "looks_nextcostume",
476
+ "functionality": "Switches the sprite's costume to the next one in its costume list. If it's the last costume, it cycles back to the first.",
477
+ "inputs": null,
478
+ "example_standalone": "next costume",
479
+ "example_with_other_blocks": [
480
+ {
481
+ "script": "when [space v] key pressed\n repeat (3)\n next costume\n wait (0.1) seconds\n end \nend",
482
+ "explanation": "When the space key is pressed, the sprite will cycle through its next three costumes with a short delay between each change."
483
+ },
484
+ {
485
+ "script": "when green flag clicked\n forever\n next costume\n wait (0.2) seconds\n end \nend",
486
+ "explanation": "This script continuously animates the sprite by switching to the next costume every 0.2 seconds, creating a walking or flying effect."
487
+ }
488
+ ]
489
+ },
490
+ {
491
+ "block_name": "switch backdrop to ()",
492
+ "block_type": "Looks",
493
+ "block_shape": "Stack Block",
494
+ "op_code": "looks_switchbackdropto",
495
+ "functionality": "Changes the stage's backdrop to a specified backdrop.",
496
+ "inputs": [
497
+ {
498
+ "name": "BACKDROP",
499
+ "type": "dropdown/number"
500
+ }
501
+ ],
502
+ "example_standalone": "switch backdrop to [backdrop1 v]",
503
+ "example_with_other_blocks": [
504
+ {
505
+ "script": "when green flag clicked\n switch backdrop to [start screen v]\nend ",
506
+ "explanation": "This script sets the stage to a 'start screen' backdrop when the project begins."
507
+ }
508
+ ]
509
+ },
510
+ {
511
+ "block_name": "switch backdrop to () and wait",
512
+ "block_type": "Looks",
513
+ "block_shape": "Stack Block",
514
+ "op_code": "looks_switchbackdroptowait",
515
+ "functionality": "Changes the stage's backdrop to a specified backdrop and pauses the script until any 'When backdrop switches to' scripts for that backdrop have finished.",
516
+ "inputs": [
517
+ {
518
+ "name": "BACKDROP",
519
+ "type": "dropdown/number"
520
+ }
521
+ ],
522
+ "example_standalone": "switch backdrop to [game over v] and wait",
523
+ "example_with_other_blocks": [
524
+ {
525
+ "script": "broadcast [game over v]\n switch backdrop to [game over v] and wait\n stop [all v] \nend",
526
+ "explanation": "This script broadcasts a 'game over' message, then changes the backdrop to 'game over' and waits for any associated scripts to finish before stopping all processes."
527
+ }
528
+ ]
529
+ },
530
+ {
531
+ "block_name": "next backdrop",
532
+ "block_type": "Looks",
533
+ "block_shape": "Stack Block",
534
+ "op_code": "looks_nextbackdrop",
535
+ "functionality": "Switches the stage's backdrop to the next one in its backdrop list. If it's the last backdrop, it cycles back to the first.",
536
+ "inputs": null,
537
+ "example_standalone": "next backdrop",
538
+ "example_with_other_blocks": [
539
+ {
540
+ "script": "when [space v] key pressed\n next backdrop\nend",
541
+ "explanation": "This script changes the stage to the next backdrop in the list each time the space key is pressed."
542
+ }
543
+ ]
544
+ },
545
+ {
546
+ "block_name": "change size by ()",
547
+ "block_type": "Looks",
548
+ "block_shape": "Stack Block",
549
+ "op_code": "looks_changesizeby",
550
+ "functionality": "Changes the sprite's size by a specified percentage. Positive values make it larger, negative values make it smaller.",
551
+ "inputs": [
552
+ {
553
+ "name": "CHANGE",
554
+ "type": "number"
555
+ }
556
+ ],
557
+ "example_standalone": "change size by (10)",
558
+ "example_with_other_blocks": [
559
+ {
560
+ "script": "when green flag clicked\n repeat (10)\n change size by (5)\n wait (0.1) seconds\n end \nend ",
561
+ "explanation": "This script makes the sprite gradually grow larger over 10 steps, with a short pause between each size change."
562
+ }
563
+ ]
564
+ },
565
+ {
566
+ "block_name": "set size to () %",
567
+ "block_type": "Looks",
568
+ "block_shape": "Stack Block",
569
+ "op_code": "looks_setsizeto",
570
+ "functionality": "Sets the sprite's size to a specific percentage of its original size.",
571
+ "inputs": [
572
+ {
573
+ "name": "SIZE",
574
+ "type": "number"
575
+ }
576
+ ],
577
+ "example_standalone": "set size to (100) %",
578
+ "example_with_other_blocks": [
579
+ {
580
+ "script": "when green flag clicked\n set size to (50) %\n wait (1) seconds\n set size to (100) %\nend ",
581
+ "explanation": "This script makes the sprite shrink to half its original size at the start, waits for 1 second, then returns to its original size."
582
+ }
583
+ ]
584
+ },
585
+ {
586
+ "block_name": "change () effect by ()",
587
+ "block_type": "Looks",
588
+ "block_shape": "Stack Block",
589
+ "op_code": "looks_changeeffectby",
590
+ "functionality": "Changes a visual effect on the sprite by a specified amount (e.g., color, fisheye, whirl, pixelate, mosaic, brightness, ghost).",
591
+ "inputs": [
592
+ {
593
+ "name": "EFFECT",
594
+ "type": "dropdown",
595
+ "options": [
596
+ "color",
597
+ "fisheye",
598
+ "whirl",
599
+ "pixelate",
600
+ "mosaic",
601
+ "brightness",
602
+ "ghost"
603
+ ]
604
+ },
605
+ {
606
+ "name": "CHANGE",
607
+ "type": "number"
608
+ }
609
+ ],
610
+ "example_standalone": "change [color v] effect by (25)",
611
+ "example_with_other_blocks": [
612
+ {
613
+ "script": "when loudness > (10)\n change [fisheye v] effect by (5)\nend",
614
+ "explanation": "When the loudness detected by the microphone is greater than 10, the sprite's fisheye effect will increase by 5."
615
+ },
616
+ {
617
+ "script": "when green flag clicked\n forever\n change [color v] effect by (5)\n wait (0.1) seconds\n end \nend",
618
+ "explanation": "This script makes the sprite continuously cycle through different colors."
619
+ }
620
+ ]
621
+ },
622
+ {
623
+ "block_name": "set () effect to ()",
624
+ "block_type": "Looks",
625
+ "block_shape": "Stack Block",
626
+ "op_code": "looks_seteffectto",
627
+ "functionality": "Sets a visual effect on the sprite to a specific value.",
628
+ "inputs": [
629
+ {
630
+ "name": "EFFECT",
631
+ "type": "dropdown",
632
+ "options": [
633
+ "color",
634
+ "fisheye",
635
+ "whirl",
636
+ "pixelate",
637
+ "mosaic",
638
+ "brightness",
639
+ "ghost"
640
+ ]
641
+ },
642
+ {
643
+ "name": "VALUE",
644
+ "type": "number"
645
+ }
646
+ ],
647
+ "example_standalone": "set [ghost v] effect to (50)",
648
+ "example_with_other_blocks": [
649
+ {
650
+ "script": "when green flag clicked\n set [ghost v] effect to (75)\nend",
651
+ "explanation": "This script makes the sprite 75% transparent at the start of the project."
652
+ }
653
+ ]
654
+ },
655
+ {
656
+ "block_name": "clear graphic effects",
657
+ "block_type": "Looks",
658
+ "block_shape": "Stack Block",
659
+ "op_code": "looks_cleargraphiceffects",
660
+ "functionality": "Removes all visual effects applied to the sprite.",
661
+ "inputs": null,
662
+ "example_standalone": "clear graphic effects",
663
+ "example_with_other_blocks": [
664
+ {
665
+ "script": "when green flag clicked\n change [color v] effect by (50)\n wait (2) seconds\n clear graphic effects\nend",
666
+ "explanation": "This script changes the sprite's color effect, waits 2 seconds, then resets all graphic effects."
667
+ }
668
+ ]
669
+ },
670
+ {
671
+ "block_name": "show",
672
+ "block_type": "Looks",
673
+ "block_shape": "Stack Block",
674
+ "op_code": "looks_show",
675
+ "functionality": "Makes the sprite visible on the stage.",
676
+ "inputs": null,
677
+ "example_standalone": "show",
678
+ "example_with_other_blocks": [
679
+ {
680
+ "script": "when green flag clicked\n hide[start game v]\nwhen I receive [start game v]\n show [start game v] \nend",
681
+ "explanation": "This script hides the sprite at the beginning of the project and makes it visible when a 'start game' broadcast is received."
682
+ }
683
+ ]
684
+ },
685
+ {
686
+ "block_name": "hide",
687
+ "block_type": "Looks",
688
+ "block_shape": "Stack Block",
689
+ "op_code": "looks_hide",
690
+ "functionality": "Makes the sprite invisible on the stage.",
691
+ "inputs": null,
692
+ "example_standalone": "hide",
693
+ "example_with_other_blocks": [
694
+ {
695
+ "script": "when green flag clicked\n hide \nend",
696
+ "explanation": "This script hides the sprite from the stage when the green flag is clicked."
697
+ }
698
+ ]
699
+ },
700
+ {
701
+ "block_name": "go to () layer",
702
+ "block_type": "Looks",
703
+ "block_shape": "Stack Block",
704
+ "op_code": "looks_gotofrontback",
705
+ "functionality": "Moves the sprite to the front-most or back-most layer of other sprites on the stage.",
706
+ "inputs": [
707
+ {
708
+ "name": "FRONT_BACK",
709
+ "type": "dropdown",
710
+ "options": [
711
+ "front",
712
+ "back"
713
+ ]
714
+ }
715
+ ],
716
+ "example_standalone": "go to [front v] layer",
717
+ "example_with_other_blocks": [
718
+ {
719
+ "script": "when green flag clicked\n go to [front v] layer\nend",
720
+ "explanation": "This script ensures the sprite is always visible on top of other sprites at the start of the project."
721
+ }
722
+ ]
723
+ },
724
+ {
725
+ "block_name": "go () layers",
726
+ "block_type": "Looks",
727
+ "block_shape": "Stack Block",
728
+ "op_code": "looks_goforwardbackwardlayers",
729
+ "functionality": "Moves the sprite forward or backward a specified number of layers in relation to other sprites.",
730
+ "inputs": [
731
+ {
732
+ "name": "FORWARD_BACKWARD",
733
+ "type": "dropdown",
734
+ "options": [
735
+ "forward",
736
+ "backward"
737
+ ]
738
+ },
739
+ {
740
+ "name": "NUM",
741
+ "type": "number"
742
+ }
743
+ ],
744
+ "example_standalone": "go [forward v] (1) layers",
745
+ "example_with_other_blocks": [
746
+ {
747
+ "script": "when this sprite clicked go [forward v] (1) layers\nend",
748
+ "explanation": "This script brings the clicked sprite one layer closer to the front."
749
+ }
750
+ ]
751
+ },
752
+ {
753
+ "block_name": "play sound () until done",
754
+ "block_type": "Sound",
755
+ "block_shape": "Stack Block",
756
+ "op_code": "sound_playuntildone",
757
+ "functionality": "Plays a specified sound and pauses the script's execution until the sound has completed.",
758
+ "inputs": [
759
+ {
760
+ "name": "sound name",
761
+ "type": "dropdown"
762
+ }
763
+ ],
764
+ "example_standalone": "play sound [Meow v] until done",
765
+ "example_with_other_blocks": [
766
+ {
767
+ "script": "when backdrop switches to [winning screen v]\n play sound [fanfare v] until done\n say [You won!] for (2) seconds\nend",
768
+ "explanation": "When the backdrop changes to the 'winning screen', a 'fanfare' sound will play until it finishes, and then the sprite will say 'You won!' for 2 seconds."
769
+ },
770
+ {
771
+ "script": "forever\n play sound [Music v] until done \nend",
772
+ "explanation": "This script creates a continuous loop for background music, playing the 'Music' sound repeatedly."
773
+ }
774
+ ]
775
+ },
776
+ {
777
+ "block_name": "start sound ()",
778
+ "block_type": "Sound",
779
+ "block_shape": "Stack Block",
780
+ "op_code": "sound_start",
781
+ "functionality": "Initiates playback of a specified sound without pausing the script, allowing other actions to proceed concurrently.",
782
+ "inputs": [
783
+ {
784
+ "name": "sound name",
785
+ "type": "dropdown"
786
+ }
787
+ ],
788
+ "example_standalone": "start sound [Pop v]",
789
+ "example_with_other_blocks": [
790
+ {
791
+ "script": "when this sprite clicked\n start sound [Pop v]\n change [score v] by (1)\nend",
792
+ "explanation": "This script plays a 'Pop' sound and increments the score simultaneously when the sprite is clicked."
793
+ }
794
+ ]
795
+ },
796
+ {
797
+ "block_name": "stop all sounds",
798
+ "block_type": "Sound",
799
+ "block_shape": "Stack Block",
800
+ "op_code": "sound_stopallsounds",
801
+ "functionality": "Stops all currently playing sounds.",
802
+ "inputs": null,
803
+ "example_standalone": "stop all sounds",
804
+ "example_with_other_blocks": [
805
+ {
806
+ "script": "when I receive [game over v]\n stop all sounds\nend",
807
+ "explanation": "This script stops any sounds currently playing when the 'game over' broadcast is received."
808
+ }
809
+ ]
810
+ },
811
+ {
812
+ "block_name": "change volume by ()",
813
+ "block_type": "Sound",
814
+ "block_shape": "Stack Block",
815
+ "op_code": "sound_changevolumeby",
816
+ "functionality": "Changes the project's sound volume by a specified amount.",
817
+ "inputs": [
818
+ {
819
+ "name": "change",
820
+ "type": "number"
821
+ }
822
+ ],
823
+ "example_standalone": "change volume by (-10)",
824
+ "example_with_other_blocks": [
825
+ {
826
+ "script": "when [down arrow v] key pressed\n change volume by (-5)\nend",
827
+ "explanation": "This script decreases the project's volume by 5 when the down arrow key is pressed."
828
+ }
829
+ ]
830
+ },
831
+ {
832
+ "block_name": "set volume to () %",
833
+ "block_type": "Sound",
834
+ "block_shape": "Stack Block",
835
+ "op_code": "sound_setvolumeto",
836
+ "functionality": "Sets the sound volume to a specific percentage (0-100).",
837
+ "inputs": [
838
+ {
839
+ "name": "percentage",
840
+ "type": "number"
841
+ }
842
+ ],
843
+ "example_standalone": "set volume to (100) %",
844
+ "example_with_other_blocks": [
845
+ {
846
+ "script": "when green flag clicked\n set volume to (50) %\nend",
847
+ "explanation": "This script sets the project's volume to 50% when the green flag is clicked."
848
+ }
849
+ ]
850
+ },
851
+ {
852
+ "block_name": "broadcast ()",
853
+ "block_type": "Events",
854
+ "block_shape": "Stack Block",
855
+ "op_code": "event_broadcast",
856
+ "functionality": "Sends a broadcast message throughout the Scratch program, activating any 'when I receive ()' blocks that are set to listen for that message, enabling indirect communication.",
857
+ "inputs": [
858
+ {
859
+ "name": "message name",
860
+ "type": "string/dropdown"
861
+ }
862
+ ],
863
+ "example_standalone": "broadcast [start game v]",
864
+ "example_with_other_blocks": [
865
+ {
866
+ "script": "if <key [space v] pressed?> then\n broadcast [jump v]\nend",
867
+ "explanation": "This script sends a 'jump' message to other scripts or sprites when the space key is pressed."
868
+ }
869
+ ]
870
+ },
871
+ {
872
+ "block_name": "broadcast () and wait",
873
+ "block_type": "Events",
874
+ "block_shape": "Stack Block",
875
+ "op_code": "event_broadcastandwait",
876
+ "functionality": "Sends a broadcast message and pauses the current script until all other scripts activated by that broadcast have completed their execution, ensuring sequential coordination.",
877
+ "inputs": [
878
+ {
879
+ "name": "message name",
880
+ "type": "string/dropdown"
881
+ }
882
+ ],
883
+ "example_standalone": "broadcast [initialize sprites v] and wait",
884
+ "example_with_other_blocks": [
885
+ {
886
+ "script": "broadcast [initialize sprites v] and wait\n say [Game Started!] for (2) seconds",
887
+ "explanation": "This script ensures all sprite initialization routines complete before displaying 'Game Started!' for 2 seconds."
888
+ }
889
+ ]
890
+ },
891
+ {
892
+ "block_name": "wait () seconds",
893
+ "block_type": "Control",
894
+ "block_shape": "Stack Block",
895
+ "op_code": "control_wait",
896
+ "functionality": "Pauses the script for a specified duration.",
897
+ "inputs": [
898
+ {
899
+ "name": "seconds",
900
+ "type": "number"
901
+ }
902
+ ],
903
+ "example_standalone": "wait (1) seconds",
904
+ "example_with_other_blocks": [
905
+ {
906
+ "script": "say [Hello!] for (1) seconds\n wait (0.5) seconds\n say [Goodbye!] for (1) seconds",
907
+ "explanation": "This script creates a timed dialogue sequence, pausing for 0.5 seconds between two speech bubbles."
908
+ }
909
+ ]
910
+ },
911
+ {
912
+ "block_name": "wait until <>",
913
+ "block_type": "Control",
914
+ "block_shape": "Stack Block",
915
+ "op_code": "control_wait_until",
916
+ "functionality": "Pauses the script until the specified boolean condition becomes true. [NOTE: it takes boolean blocks as input]",
917
+ "inputs": [
918
+ {
919
+ "name": "condition",
920
+ "type": "boolean"
921
+ }
922
+ ],
923
+ "example_standalone": "wait until <key [space v] pressed?>",
924
+ "example_with_other_blocks": [
925
+ {
926
+ "script": "wait until <key [space v] pressed?>\n start sound [pop v]\nend",
927
+ "explanation": "This script pauses until the space key is pressed, then plays a 'pop' sound."
928
+ }
929
+ ]
930
+ },
931
+ {
932
+ "block_name": "stop ()",
933
+ "block_type": "Control",
934
+ "block_shape": "Stack Block",
935
+ "op_code": "control_stop",
936
+ "functionality": "Stops all scripts, this script, or other scripts in the sprite. Becomes a Cap Block if 'all' or 'this script' is selected in the dropdown menu.",
937
+ "inputs": [
938
+ {
939
+ "name": "option",
940
+ "type": "dropdown",
941
+ "options": [
942
+ "all",
943
+ "this script",
944
+ "other scripts in sprite"
945
+ ]
946
+ }
947
+ ],
948
+ "example_standalone": "stop [all v]",
949
+ "example_with_other_blocks": [
950
+ {
951
+ "script": "if <score = (0)> then\n stop [all v]\nend",
952
+ "explanation": "This script stops the entire project if the 'score' variable becomes 0."
953
+ }
954
+ ]
955
+ },
956
+ {
957
+ "block_name": "create clone of ()",
958
+ "block_type": "Control",
959
+ "block_shape": "Stack Block",
960
+ "op_code": "control_create_clone_of",
961
+ "functionality": "Generates a copy, or clone, of a specified sprite (or 'myself' for the current sprite).",
962
+ "inputs": [
963
+ {
964
+ "name": "sprite_name",
965
+ "type": "dropdown",
966
+ "options": [
967
+ "myself",
968
+ "sprite1",
969
+ "..."
970
+ ]
971
+ }
972
+ ],
973
+ "example_standalone": "create clone of [myself v]",
974
+ "example_with_other_blocks": [
975
+ {
976
+ "script": "when I start as a clone\n show\n go to random position\n wait (2) seconds\n delete this clone\nend",
977
+ "explanation": "When a clone is created, it will show itself, go to a random position, wait for 2 seconds, and then delete itself."
978
+ }
979
+ ]
980
+ },
981
+ {
982
+ "block_name": "delete this clone",
983
+ "block_type": "Control",
984
+ "block_shape": "Stack Block",
985
+ "op_code": "control_delete_this_clone",
986
+ "functionality": "Deletes the clone that is currently running the script.",
987
+ "inputs": null,
988
+ "example_standalone": "delete this clone",
989
+ "example_with_other_blocks": [
990
+ {
991
+ "script": "when I start as a clone\n wait (5) seconds\n delete this clone\nend",
992
+ "explanation": "This script makes each clone wait for 5 seconds after it's created, then deletes itself."
993
+ }
994
+ ]
995
+ },
996
+ {
997
+ "block_name": "set [my variable v] to ()",
998
+ "block_type": "Data",
999
+ "block_shape": "Stack Block",
1000
+ "op_code": "data_setvariableto",
1001
+ "functionality": "Assigns a specific value (number, string, or boolean) to a variable.",
1002
+ "inputs": [
1003
+ {
1004
+ "name": "variable name",
1005
+ "type": "dropdown"
1006
+ },
1007
+ {
1008
+ "name": "value",
1009
+ "type": "any"
1010
+ }
1011
+ ],
1012
+ "example_standalone": "set [score v] to (0)",
1013
+ "example_with_other_blocks": [
1014
+ {
1015
+ "script": "when green flag clicked\n set [score v] to (0)\n set [player name v] to [Guest]\nend",
1016
+ "explanation": "This script initializes the 'score' variable to 0 and the 'player name' variable to 'Guest' when the project starts."
1017
+ }
1018
+ ]
1019
+ },
1020
+ {
1021
+ "block_name": "change [my variable v] by ()",
1022
+ "block_type": "Data",
1023
+ "block_shape": "Stack Block",
1024
+ "op_code": "data_changevariableby",
1025
+ "functionality": "Increases or decreases a variable's numerical value by a specified amount.",
1026
+ "inputs": [
1027
+ {
1028
+ "name": "variable name",
1029
+ "type": "dropdown"
1030
+ },
1031
+ {
1032
+ "name": "value",
1033
+ "type": "number"
1034
+ }
1035
+ ],
1036
+ "example_standalone": "change [score v] by (1)",
1037
+ "example_with_other_blocks": [
1038
+ {
1039
+ "script": "when this sprite clicked\n change [score v] by (1)\nend",
1040
+ "explanation": "This script increments the 'score' variable by 1 each time the sprite is clicked."
1041
+ }
1042
+ ]
1043
+ },
1044
+ {
1045
+ "block_name": "add () to [my list v]",
1046
+ "block_type": "Data",
1047
+ "block_shape": "Stack Block",
1048
+ "op_code": "data_addtolist",
1049
+ "functionality": "Appends an item to the end of a list.",
1050
+ "inputs": [
1051
+ {
1052
+ "name": "item",
1053
+ "type": "any"
1054
+ },
1055
+ {
1056
+ "name": "list name",
1057
+ "type": "dropdown"
1058
+ }
1059
+ ],
1060
+ "example_standalone": "add [apple] to [shopping list v]",
1061
+ "example_with_other_blocks": [
1062
+ {
1063
+ "script": "when green flag clicked\n add [apple] to [shopping list v]\n add [banana] to [shopping list v]\nend",
1064
+ "explanation": "This script adds 'apple' and 'banana' as new items to the 'shopping list' when the project starts."
1065
+ }
1066
+ ]
1067
+ },
1068
+ {
1069
+ "block_name": "delete () of [my list v]",
1070
+ "block_type": "Data",
1071
+ "block_shape": "Stack Block",
1072
+ "op_code": "data_deleteoflist",
1073
+ "functionality": "Removes an item from a list by its index or by selecting 'all' items.",
1074
+ "inputs": [
1075
+ {
1076
+ "name": "index/option",
1077
+ "type": "number/dropdown",
1078
+ "options": [
1079
+ "all",
1080
+ "last",
1081
+ "random"
1082
+ ]
1083
+ },
1084
+ {
1085
+ "name": "list name",
1086
+ "type": "dropdown"
1087
+ }
1088
+ ],
1089
+ "example_standalone": "delete (1) of [my list v]",
1090
+ "example_with_other_blocks": [
1091
+ {
1092
+ "script": "when green flag clicked\n delete (all) of [my list v]\nend",
1093
+ "explanation": "This script clears all items from 'my list' when the green flag is clicked."
1094
+ }
1095
+ ]
1096
+ },
1097
+ {
1098
+ "block_name": "insert () at () of [my list v]",
1099
+ "block_type": "Data",
1100
+ "block_shape": "Stack Block",
1101
+ "op_code": "data_insertatlist",
1102
+ "functionality": "Inserts an item at a specific position within a list.",
1103
+ "inputs": [
1104
+ {
1105
+ "name": "item",
1106
+ "type": "any"
1107
+ },
1108
+ {
1109
+ "name": "index",
1110
+ "type": "number"
1111
+ },
1112
+ {
1113
+ "name": "list name",
1114
+ "type": "dropdown"
1115
+ }
1116
+ ],
1117
+ "example_standalone": "insert [orange] at (2) of [fruits v]",
1118
+ "example_with_other_blocks": [
1119
+ {
1120
+ "script": "insert [orange] at (2) of [fruits v]",
1121
+ "explanation": "This script inserts 'orange' as the second item in the 'fruits' list, shifting subsequent items."
1122
+ }
1123
+ ]
1124
+ },
1125
+ {
1126
+ "block_name": "replace item () of [my list v] with ()",
1127
+ "block_type": "Data",
1128
+ "block_shape": "Stack Block",
1129
+ "op_code": "data_replaceitemoflist",
1130
+ "functionality": "Replaces an item at a specific position in a list with a new value.",
1131
+ "inputs": [
1132
+ {
1133
+ "name": "index",
1134
+ "type": "number"
1135
+ },
1136
+ {
1137
+ "name": "list name",
1138
+ "type": "dropdown"
1139
+ },
1140
+ {
1141
+ "name": "new item",
1142
+ "type": "any"
1143
+ }
1144
+ ],
1145
+ "example_standalone": "replace item (1) of [colors v] with [blue]",
1146
+ "example_with_other_blocks": [
1147
+ {
1148
+ "script": "replace item (1) of [colors v] with [blue]",
1149
+ "explanation": "This script changes the first item in the 'colors' list to 'blue'."
1150
+ }
1151
+ ]
1152
+ },
1153
+ {
1154
+ "block_name": "show variable [my variable v]",
1155
+ "block_type": "Data",
1156
+ "block_shape": "Stack Block",
1157
+ "op_code": "data_showvariable",
1158
+ "functionality": "Makes a variable's monitor visible on the stage.",
1159
+ "inputs": [
1160
+ {
1161
+ "name": "variable name",
1162
+ "type": "dropdown"
1163
+ }
1164
+ ],
1165
+ "example_standalone": "show variable [score v]",
1166
+ "example_with_other_blocks": [
1167
+ {
1168
+ "script": "when green flag clicked\n show variable [score v]\nend",
1169
+ "explanation": "This script displays the 'score' variable on the stage when the project starts."
1170
+ }
1171
+ ]
1172
+ },
1173
+ {
1174
+ "block_name": "hide variable [my variable v]",
1175
+ "block_type": "Data",
1176
+ "block_shape": "Stack Block",
1177
+ "op_code": "data_hidevariable",
1178
+ "functionality": "Hides a variable's monitor from the stage.",
1179
+ "inputs": [
1180
+ {
1181
+ "name": "variable name",
1182
+ "type": "dropdown"
1183
+ }
1184
+ ],
1185
+ "example_standalone": "hide variable [score v]",
1186
+ "example_with_other_blocks": [
1187
+ {
1188
+ "script": "when I receive [game over v]\n hide variable [score v]\nend",
1189
+ "explanation": "This script hides the 'score' variable when the 'game over' broadcast is received."
1190
+ }
1191
+ ]
1192
+ },
1193
+ {
1194
+ "block_name": "show list [my list v]",
1195
+ "block_type": "Data",
1196
+ "block_shape": "Stack Block",
1197
+ "op_code": "data_showlist",
1198
+ "functionality": "Makes a list's monitor visible on the stage.",
1199
+ "inputs": [
1200
+ {
1201
+ "name": "list name",
1202
+ "type": "dropdown"
1203
+ }
1204
+ ],
1205
+ "example_standalone": "show list [shopping list v]",
1206
+ "example_with_other_blocks": [
1207
+ {
1208
+ "script": "when green flag clicked\n show list [shopping list v]\nend",
1209
+ "explanation": "This script displays the 'shopping list' on the stage when the project starts."
1210
+ }
1211
+ ]
1212
+ },
1213
+ {
1214
+ "block_name": "hide list [my list v]",
1215
+ "block_type": "Data",
1216
+ "block_shape": "Stack Block",
1217
+ "op_code": "data_hidelist",
1218
+ "functionality": "Hides a list's monitor from the stage.",
1219
+ "inputs": [
1220
+ {
1221
+ "name": "list name",
1222
+ "type": "dropdown"
1223
+ }
1224
+ ],
1225
+ "example_standalone": "hide list [shopping list v]",
1226
+ "example_with_other_blocks": [
1227
+ {
1228
+ "script": "when I receive [game over v]\n hide list [shopping list v]\nend",
1229
+ "explanation": "This script hides the 'shopping list' when the 'game over' broadcast is received."
1230
+ }
1231
+ ]
1232
+ },
1233
+ {
1234
+ "block_name": "Ask () and Wait",
1235
+ "block_type": "Sensing",
1236
+ "block_shape": "Stack Block",
1237
+ "op_code": "sensing_askandwait",
1238
+ "functionality": "Displays an input box with specified text at the bottom of the screen, allowing users to input text, which is stored in the 'Answer' block.",
1239
+ "inputs": [
1240
+ {
1241
+ "name": "question",
1242
+ "type": "text"
1243
+ }
1244
+ ],
1245
+ "example_standalone": "ask [What is your name? v] and wait",
1246
+ "example_with_other_blocks": [
1247
+ {
1248
+ "script": "ask [What is your name? v] and wait\n say join [Hello v] (answer) for (2) seconds \nend",
1249
+ "explanation": "This script prompts the user for their name, waits for input, then greets them using the provided answer."
1250
+ }
1251
+ ]
1252
+ },
1253
+ {
1254
+ "block_name": "Reset Timer",
1255
+ "block_type": "Sensing",
1256
+ "block_shape": "Stack Block",
1257
+ "op_code": "sensing_resettimer",
1258
+ "functionality": "Sets the timer’s value back to 0.0.",
1259
+ "inputs": null,
1260
+ "example_standalone": "reset timer",
1261
+ "example_with_other_blocks": [
1262
+ {
1263
+ "script": "when green flag clicked\n reset timer\n wait (5) seconds\n say timer for (2) seconds\nend",
1264
+ "explanation": "This script resets the timer at the start, waits for 5 seconds, then says the current timer value."
1265
+ }
1266
+ ]
1267
+ },
1268
+ {
1269
+ "block_name": "set drag mode [draggable v]",
1270
+ "block_type": "Sensing",
1271
+ "block_shape": "Stack Block",
1272
+ "op_code": "sensing_setdragmode",
1273
+ "functionality": "Sets whether the sprite can be dragged by the mouse on the stage.",
1274
+ "inputs": null,
1275
+ "fields": {
1276
+ "DRAG_MODE": {
1277
+ "type": "dropdown",
1278
+ "options": [
1279
+ "draggable",
1280
+ "not draggable"
1281
+ ]
1282
+ }
1283
+ },
1284
+ "example_standalone": "set drag mode [draggable v]",
1285
+ "example_with_other_blocks": [
1286
+ {
1287
+ "script": "when green flag clicked\n set drag mode [not draggable v]\nend when this sprite clicked\n set drag mode [draggable v] \nend",
1288
+ "explanation": "This script makes the sprite not draggable when the project starts, but allows it to be dragged once it's clicked."
1289
+ }
1290
+ ]
1291
+ },
1292
+ {
1293
+ "block_name": "[my custom block]",
1294
+ "block_type": "My Blocks",
1295
+ "block_shape": "Stack Block",
1296
+ "op_code": "procedures_call",
1297
+ "functionality": "Executes the script defined by a corresponding 'define' Hat block. This block allows users to call and reuse custom code sequences by simply dragging and dropping it into their scripts, optionally providing required input values.",
1298
+ "inputs": [
1299
+ {
1300
+ "name": "argument_name_1",
1301
+ "type": "any"
1302
+ },
1303
+ {
1304
+ "name": "argument_name_2",
1305
+ "type": "any"
1306
+ }
1307
+ ],
1308
+ "example_standalone": "jump (50)",
1309
+ "example_with_other_blocks": [
1310
+ {
1311
+ "script": "when green flag clicked\n go to x: (0) y: (0)\n jump (50)\n wait (1) seconds\n say [I jumped!] for (2) seconds",
1312
+ "explanation": "This script moves the sprite to a starting position, then calls the 'jump' custom block with an input of 50 (assuming 'jump' is a custom block that moves the sprite up and down). After the jump, the sprite says 'I jumped!'."
1313
+ },
1314
+ {
1315
+ "script": "when green flag clicked\n hide\n forever\n create clone of [myself v]\n wait (1) seconds\n end",
1316
+ "explanation": "This script continuously creates new clones of the current sprite every second after the original sprite hides itself."
1317
+ }
1318
+ ]
1319
+ }
1320
+ ]
1321
+ }
v2/scratch_agent/blocks_content.json ADDED
@@ -0,0 +1,1367 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "motion_movesteps": {
3
+ "opcode": "motion_movesteps",
4
+ "next": null,
5
+ "parent": null,
6
+ "inputs": {
7
+ "STEPS": [
8
+ 1,
9
+ [
10
+ 4,
11
+ "10"
12
+ ]
13
+ ]
14
+ },
15
+ "fields": {},
16
+ "shadow": false,
17
+ "topLevel": true,
18
+ "x": 464,
19
+ "y": -416
20
+ },
21
+ "motion_turnright": {
22
+ "opcode": "motion_turnright",
23
+ "next": null,
24
+ "parent": null,
25
+ "inputs": {
26
+ "DEGREES": [
27
+ 1,
28
+ [
29
+ 4,
30
+ "15"
31
+ ]
32
+ ]
33
+ },
34
+ "fields": {},
35
+ "shadow": false,
36
+ "topLevel": true,
37
+ "x": 467,
38
+ "y": -316
39
+ },
40
+ "motion_turnleft": {
41
+ "opcode": "motion_turnleft",
42
+ "next": null,
43
+ "parent": null,
44
+ "inputs": {
45
+ "DEGREES": [
46
+ 1,
47
+ [
48
+ 4,
49
+ "15"
50
+ ]
51
+ ]
52
+ },
53
+ "fields": {},
54
+ "shadow": false,
55
+ "topLevel": true,
56
+ "x": 464,
57
+ "y": -210
58
+ },
59
+ "motion_goto": {
60
+ "opcode": "motion_goto",
61
+ "next": null,
62
+ "parent": null,
63
+ "inputs": {
64
+ "TO": [
65
+ 1,
66
+ "@iM=Z?~GCbpC}gT7KAKY"
67
+ ]
68
+ },
69
+ "fields": {},
70
+ "shadow": false,
71
+ "topLevel": true,
72
+ "x": 465,
73
+ "y": -95
74
+ },
75
+ "motion_goto_menu": {
76
+ "opcode": "motion_goto_menu",
77
+ "next": null,
78
+ "parent": "d|J?C902/xy6tD5,|dmB",
79
+ "inputs": {},
80
+ "fields": {
81
+ "TO": [
82
+ "_random_",
83
+ null
84
+ ]
85
+ },
86
+ "shadow": true,
87
+ "topLevel": false
88
+ },
89
+ "motion_gotoxy": {
90
+ "opcode": "motion_gotoxy",
91
+ "next": null,
92
+ "parent": null,
93
+ "inputs": {
94
+ "X": [
95
+ 1,
96
+ [
97
+ 4,
98
+ "0"
99
+ ]
100
+ ],
101
+ "Y": [
102
+ 1,
103
+ [
104
+ 4,
105
+ "0"
106
+ ]
107
+ ]
108
+ },
109
+ "fields": {},
110
+ "shadow": false,
111
+ "topLevel": true,
112
+ "x": 468,
113
+ "y": 12
114
+ },
115
+ "motion_glideto": {
116
+ "opcode": "motion_glideto",
117
+ "next": null,
118
+ "parent": null,
119
+ "inputs": {
120
+ "SECS": [
121
+ 1,
122
+ [
123
+ 4,
124
+ "1"
125
+ ]
126
+ ],
127
+ "TO": [
128
+ 1,
129
+ "{id to destination position}"
130
+ ]
131
+ },
132
+ "fields": {},
133
+ "shadow": false,
134
+ "topLevel": true,
135
+ "x": 470,
136
+ "y": 129
137
+ },
138
+ "motion_glideto_menu": {
139
+ "opcode": "motion_glideto_menu",
140
+ "next": null,
141
+ "parent": null,
142
+ "inputs": {},
143
+ "fields": {
144
+ "TO": [
145
+ "_random_",
146
+ null
147
+ ]
148
+ },
149
+ "shadow": true,
150
+ "topLevel": false
151
+ },
152
+ "motion_glidesecstoxy": {
153
+ "opcode": "motion_glidesecstoxy",
154
+ "next": null,
155
+ "parent": null,
156
+ "inputs": {
157
+ "SECS": [
158
+ 1,
159
+ [
160
+ 4,
161
+ "1"
162
+ ]
163
+ ],
164
+ "X": [
165
+ 1,
166
+ [
167
+ 4,
168
+ "0"
169
+ ]
170
+ ],
171
+ "Y": [
172
+ 1,
173
+ [
174
+ 4,
175
+ "0"
176
+ ]
177
+ ]
178
+ },
179
+ "fields": {},
180
+ "shadow": false,
181
+ "topLevel": true,
182
+ "x": 476,
183
+ "y": 239
184
+ },
185
+ "motion_pointindirection": {
186
+ "opcode": "motion_pointindirection",
187
+ "next": null,
188
+ "parent": null,
189
+ "inputs": {
190
+ "DIRECTION": [
191
+ 1,
192
+ [
193
+ 8,
194
+ "90"
195
+ ]
196
+ ]
197
+ },
198
+ "fields": {},
199
+ "shadow": false,
200
+ "topLevel": true,
201
+ "x": 493,
202
+ "y": 361
203
+ },
204
+ "motion_pointtowards": {
205
+ "opcode": "motion_pointtowards",
206
+ "next": null,
207
+ "parent": null,
208
+ "inputs": {
209
+ "TOWARDS": [
210
+ 1,
211
+ "6xQl1pPk%9E~Znhm*:ng"
212
+ ]
213
+ },
214
+ "fields": {},
215
+ "shadow": false,
216
+ "topLevel": true,
217
+ "x": 492,
218
+ "y": 463
219
+ },
220
+ "motion_pointtowards_menu": {
221
+ "opcode": "motion_pointtowards_menu",
222
+ "next": null,
223
+ "parent": "Ucm$YBs*^9GFTGXCbal@",
224
+ "inputs": {},
225
+ "fields": {
226
+ "TOWARDS": [
227
+ "_mouse_",
228
+ null
229
+ ]
230
+ },
231
+ "shadow": true,
232
+ "topLevel": false
233
+ },
234
+ "motion_changexby": {
235
+ "opcode": "motion_changexby",
236
+ "next": null,
237
+ "parent": null,
238
+ "inputs": {
239
+ "DX": [
240
+ 1,
241
+ [
242
+ 4,
243
+ "10"
244
+ ]
245
+ ]
246
+ },
247
+ "fields": {},
248
+ "shadow": false,
249
+ "topLevel": true,
250
+ "x": 851,
251
+ "y": -409
252
+ },
253
+ "motion_setx": {
254
+ "opcode": "motion_setx",
255
+ "next": null,
256
+ "parent": null,
257
+ "inputs": {
258
+ "X": [
259
+ 1,
260
+ [
261
+ 4,
262
+ "0"
263
+ ]
264
+ ]
265
+ },
266
+ "fields": {},
267
+ "shadow": false,
268
+ "topLevel": true,
269
+ "x": 864,
270
+ "y": -194
271
+ },
272
+ "motion_changeyby": {
273
+ "opcode": "motion_changeyby",
274
+ "next": null,
275
+ "parent": null,
276
+ "inputs": {
277
+ "DY": [
278
+ 1,
279
+ [
280
+ 4,
281
+ "10"
282
+ ]
283
+ ]
284
+ },
285
+ "fields": {},
286
+ "shadow": false,
287
+ "topLevel": true,
288
+ "x": 861,
289
+ "y": -61
290
+ },
291
+ "motion_sety": {
292
+ "opcode": "motion_sety",
293
+ "next": null,
294
+ "parent": null,
295
+ "inputs": {
296
+ "Y": [
297
+ 1,
298
+ [
299
+ 4,
300
+ "0"
301
+ ]
302
+ ]
303
+ },
304
+ "fields": {},
305
+ "shadow": false,
306
+ "topLevel": true,
307
+ "x": 864,
308
+ "y": 66
309
+ },
310
+ "motion_ifonedgebounce": {
311
+ "opcode": "motion_ifonedgebounce",
312
+ "next": null,
313
+ "parent": null,
314
+ "inputs": {},
315
+ "fields": {},
316
+ "shadow": false,
317
+ "topLevel": true,
318
+ "x": 1131,
319
+ "y": -397
320
+ },
321
+ "motion_setrotationstyle": {
322
+ "opcode": "motion_setrotationstyle",
323
+ "next": null,
324
+ "parent": null,
325
+ "inputs": {},
326
+ "fields": {
327
+ "STYLE": [
328
+ "left-right",
329
+ null
330
+ ]
331
+ },
332
+ "shadow": false,
333
+ "topLevel": true,
334
+ "x": 1128,
335
+ "y": -287
336
+ },
337
+ "motion_xposition": {
338
+ "opcode": "motion_xposition",
339
+ "next": null,
340
+ "parent": null,
341
+ "inputs": {},
342
+ "fields": {},
343
+ "shadow": false,
344
+ "topLevel": true,
345
+ "x": 1193,
346
+ "y": -136
347
+ },
348
+ "motion_yposition": {
349
+ "opcode": "motion_yposition",
350
+ "next": null,
351
+ "parent": null,
352
+ "inputs": {},
353
+ "fields": {},
354
+ "shadow": false,
355
+ "topLevel": true,
356
+ "x": 1181,
357
+ "y": -64
358
+ },
359
+ "motion_direction": {
360
+ "opcode": "motion_direction",
361
+ "next": null,
362
+ "parent": null,
363
+ "inputs": {},
364
+ "fields": {},
365
+ "shadow": false,
366
+ "topLevel": true,
367
+ "x": 1188,
368
+ "y": 21
369
+ },
370
+ "control_wait": {
371
+ "opcode": "control_wait",
372
+ "next": null,
373
+ "parent": null,
374
+ "inputs": {
375
+ "DURATION": [
376
+ 1,
377
+ [
378
+ 5,
379
+ "1"
380
+ ]
381
+ ]
382
+ },
383
+ "fields": {},
384
+ "shadow": false,
385
+ "topLevel": true,
386
+ "x": 337,
387
+ "y": 129
388
+ },
389
+ "control_repeat": {
390
+ "opcode": "control_repeat",
391
+ "next": null,
392
+ "parent": null,
393
+ "inputs": {
394
+ "TIMES": [
395
+ 1,
396
+ [
397
+ 6,
398
+ "10"
399
+ ]
400
+ ]
401
+ },
402
+ "fields": {},
403
+ "shadow": false,
404
+ "topLevel": true,
405
+ "x": 348,
406
+ "y": 265
407
+ },
408
+ "control_forever": {
409
+ "opcode": "control_forever",
410
+ "next": null,
411
+ "parent": null,
412
+ "inputs": {},
413
+ "fields": {},
414
+ "shadow": false,
415
+ "topLevel": true,
416
+ "x": 334,
417
+ "y": 439
418
+ },
419
+ "control_if": {
420
+ "opcode": "control_if",
421
+ "next": null,
422
+ "parent": null,
423
+ "inputs": {},
424
+ "fields": {},
425
+ "shadow": false,
426
+ "topLevel": true,
427
+ "x": 331,
428
+ "y": 597
429
+ },
430
+ "control_if_else": {
431
+ "opcode": "control_if_else",
432
+ "next": null,
433
+ "parent": null,
434
+ "inputs": {},
435
+ "fields": {},
436
+ "shadow": false,
437
+ "topLevel": true,
438
+ "x": 335,
439
+ "y": 779
440
+ },
441
+ "control_wait_until": {
442
+ "opcode": "control_wait_until",
443
+ "next": null,
444
+ "parent": null,
445
+ "inputs": {},
446
+ "fields": {},
447
+ "shadow": false,
448
+ "topLevel": true,
449
+ "x": 676,
450
+ "y": 285
451
+ },
452
+ "control_repeat_until": {
453
+ "opcode": "control_repeat_until",
454
+ "next": null,
455
+ "parent": null,
456
+ "inputs": {},
457
+ "fields": {},
458
+ "shadow": false,
459
+ "topLevel": true,
460
+ "x": 692,
461
+ "y": 381
462
+ },
463
+ "control_stop": {
464
+ "opcode": "control_stop",
465
+ "next": null,
466
+ "parent": null,
467
+ "inputs": {},
468
+ "fields": {
469
+ "STOP_OPTION": [
470
+ "all",
471
+ null
472
+ ]
473
+ },
474
+ "shadow": false,
475
+ "topLevel": true,
476
+ "x": 708,
477
+ "y": 545,
478
+ "mutation": {
479
+ "tagName": "mutation",
480
+ "children": [],
481
+ "hasnext": "false"
482
+ }
483
+ },
484
+ "control_start_as_clone": {
485
+ "opcode": "control_start_as_clone",
486
+ "next": null,
487
+ "parent": null,
488
+ "inputs": {},
489
+ "fields": {},
490
+ "shadow": false,
491
+ "topLevel": true,
492
+ "x": 665,
493
+ "y": 672
494
+ },
495
+ "control_create_clone_of": {
496
+ "opcode": "control_create_clone_of",
497
+ "next": null,
498
+ "parent": null,
499
+ "inputs": {
500
+ "CLONE_OPTION": [
501
+ 1,
502
+ "t))DW9(QSKB]3C/3Ou+J"
503
+ ]
504
+ },
505
+ "fields": {},
506
+ "shadow": false,
507
+ "topLevel": true,
508
+ "x": 648,
509
+ "y": 797
510
+ },
511
+ "control_create_clone_of_menu": {
512
+ "opcode": "control_create_clone_of_menu",
513
+ "next": null,
514
+ "parent": "80yo/}Cw++Z.;x[ohh|7",
515
+ "inputs": {},
516
+ "fields": {
517
+ "CLONE_OPTION": [
518
+ "_myself_",
519
+ null
520
+ ]
521
+ },
522
+ "shadow": true,
523
+ "topLevel": false
524
+ },
525
+ "control_delete_this_clone": {
526
+ "opcode": "control_delete_this_clone",
527
+ "next": null,
528
+ "parent": null,
529
+ "inputs": {},
530
+ "fields": {},
531
+ "shadow": false,
532
+ "topLevel": true,
533
+ "x": 642,
534
+ "y": 914
535
+ },
536
+ "event_whenflagclicked": {
537
+ "opcode": "event_whenflagclicked",
538
+ "next": null,
539
+ "parent": null,
540
+ "inputs": {},
541
+ "fields": {},
542
+ "shadow": false,
543
+ "topLevel": true,
544
+ "x": 166,
545
+ "y": -422
546
+ },
547
+ "event_whenkeypressed": {
548
+ "opcode": "event_whenkeypressed",
549
+ "next": null,
550
+ "parent": null,
551
+ "inputs": {},
552
+ "fields": {
553
+ "KEY_OPTION": [
554
+ "space",
555
+ null
556
+ ]
557
+ },
558
+ "shadow": false,
559
+ "topLevel": true,
560
+ "x": 151,
561
+ "y": -329
562
+ },
563
+ "event_whenthisspriteclicked": {
564
+ "opcode": "event_whenthisspriteclicked",
565
+ "next": null,
566
+ "parent": null,
567
+ "inputs": {},
568
+ "fields": {},
569
+ "shadow": false,
570
+ "topLevel": true,
571
+ "x": 156,
572
+ "y": -223
573
+ },
574
+ "event_whenbackdropswitchesto": {
575
+ "opcode": "event_whenbackdropswitchesto",
576
+ "next": null,
577
+ "parent": null,
578
+ "inputs": {},
579
+ "fields": {
580
+ "BACKDROP": [
581
+ "backdrop1",
582
+ null
583
+ ]
584
+ },
585
+ "shadow": false,
586
+ "topLevel": true,
587
+ "x": 148,
588
+ "y": -101
589
+ },
590
+ "event_whengreaterthan": {
591
+ "opcode": "event_whengreaterthan",
592
+ "next": null,
593
+ "parent": null,
594
+ "inputs": {
595
+ "VALUE": [
596
+ 1,
597
+ [
598
+ 4,
599
+ "10"
600
+ ]
601
+ ]
602
+ },
603
+ "fields": {
604
+ "WHENGREATERTHANMENU": [
605
+ "LOUDNESS",
606
+ null
607
+ ]
608
+ },
609
+ "shadow": false,
610
+ "topLevel": true,
611
+ "x": 150,
612
+ "y": 10
613
+ },
614
+ "event_whenbroadcastreceived": {
615
+ "opcode": "event_whenbroadcastreceived",
616
+ "next": null,
617
+ "parent": null,
618
+ "inputs": {},
619
+ "fields": {
620
+ "BROADCAST_OPTION": [
621
+ "message1",
622
+ "5O!nei;S$!c!=hCT}0:a"
623
+ ]
624
+ },
625
+ "shadow": false,
626
+ "topLevel": true,
627
+ "x": 141,
628
+ "y": 118
629
+ },
630
+ "event_broadcast": {
631
+ "opcode": "event_broadcast",
632
+ "next": null,
633
+ "parent": null,
634
+ "inputs": {
635
+ "BROADCAST_INPUT": [
636
+ 1,
637
+ [
638
+ 11,
639
+ "message1",
640
+ "5O!nei;S$!c!=hCT}0:a"
641
+ ]
642
+ ]
643
+ },
644
+ "fields": {},
645
+ "shadow": false,
646
+ "topLevel": true,
647
+ "x": 151,
648
+ "y": 229
649
+ },
650
+ "event_broadcastandwait": {
651
+ "opcode": "event_broadcastandwait",
652
+ "next": null,
653
+ "parent": null,
654
+ "inputs": {
655
+ "BROADCAST_INPUT": [
656
+ 1,
657
+ [
658
+ 11,
659
+ "message1",
660
+ "5O!nei;S$!c!=hCT}0:a"
661
+ ]
662
+ ]
663
+ },
664
+ "fields": {},
665
+ "shadow": false,
666
+ "topLevel": true,
667
+ "x": 157,
668
+ "y": 340
669
+ },
670
+ "sensing_touchingobject": {
671
+ "opcode": "sensing_touchingobject",
672
+ "next": null,
673
+ "parent": null,
674
+ "inputs": {
675
+ "TOUCHINGOBJECTMENU": [
676
+ 1,
677
+ "xSKW9a+wTnM~h~So8Jc]"
678
+ ]
679
+ },
680
+ "fields": {},
681
+ "shadow": false,
682
+ "topLevel": true,
683
+ "x": 359,
684
+ "y": 116
685
+ },
686
+ "sensing_touchingobjectmenu": {
687
+ "opcode": "sensing_touchingobjectmenu",
688
+ "next": null,
689
+ "parent": "Y(n,F@BYzwd4CiN|Bh[P",
690
+ "inputs": {},
691
+ "fields": {
692
+ "TOUCHINGOBJECTMENU": [
693
+ "_mouse_",
694
+ null
695
+ ]
696
+ },
697
+ "shadow": true,
698
+ "topLevel": false
699
+ },
700
+ "sensing_touchingcolor": {
701
+ "opcode": "sensing_touchingcolor",
702
+ "next": null,
703
+ "parent": null,
704
+ "inputs": {
705
+ "COLOR": [
706
+ 1,
707
+ [
708
+ 9,
709
+ "#55b888"
710
+ ]
711
+ ]
712
+ },
713
+ "fields": {},
714
+ "shadow": false,
715
+ "topLevel": true,
716
+ "x": 360,
717
+ "y": 188
718
+ },
719
+ "sensing_coloristouchingcolor": {
720
+ "opcode": "sensing_coloristouchingcolor",
721
+ "next": null,
722
+ "parent": null,
723
+ "inputs": {
724
+ "COLOR": [
725
+ 1,
726
+ [
727
+ 9,
728
+ "#d019f2"
729
+ ]
730
+ ],
731
+ "COLOR2": [
732
+ 1,
733
+ [
734
+ 9,
735
+ "#2b0de3"
736
+ ]
737
+ ]
738
+ },
739
+ "fields": {},
740
+ "shadow": false,
741
+ "topLevel": true,
742
+ "x": 348,
743
+ "y": 277
744
+ },
745
+ "sensing_askandwait": {
746
+ "opcode": "sensing_askandwait",
747
+ "next": null,
748
+ "parent": null,
749
+ "inputs": {
750
+ "QUESTION": [
751
+ 1,
752
+ [
753
+ 10,
754
+ "What's your name?"
755
+ ]
756
+ ]
757
+ },
758
+ "fields": {},
759
+ "shadow": false,
760
+ "topLevel": true,
761
+ "x": 338,
762
+ "y": 354
763
+ },
764
+ "sensing_answer": {
765
+ "opcode": "sensing_answer",
766
+ "next": null,
767
+ "parent": null,
768
+ "inputs": {},
769
+ "fields": {},
770
+ "shadow": false,
771
+ "topLevel": true,
772
+ "x": 782,
773
+ "y": 111
774
+ },
775
+ "sensing_keypressed": {
776
+ "opcode": "sensing_keypressed",
777
+ "next": null,
778
+ "parent": null,
779
+ "inputs": {
780
+ "KEY_OPTION": [
781
+ 1,
782
+ "SNlf@Im$sv%.6ULi-f3i"
783
+ ]
784
+ },
785
+ "fields": {},
786
+ "shadow": false,
787
+ "topLevel": true,
788
+ "x": 762,
789
+ "y": 207
790
+ },
791
+ "sensing_keyoptions": {
792
+ "opcode": "sensing_keyoptions",
793
+ "next": null,
794
+ "parent": "7$xEUO.2hH2R6vh!$(Uj",
795
+ "inputs": {},
796
+ "fields": {
797
+ "KEY_OPTION": [
798
+ "space",
799
+ null
800
+ ]
801
+ },
802
+ "shadow": true,
803
+ "topLevel": false
804
+ },
805
+ "sensing_mousedown": {
806
+ "opcode": "sensing_mousedown",
807
+ "next": null,
808
+ "parent": null,
809
+ "inputs": {},
810
+ "fields": {},
811
+ "shadow": false,
812
+ "topLevel": true,
813
+ "x": 822,
814
+ "y": 422
815
+ },
816
+ "sensing_mousex": {
817
+ "opcode": "sensing_mousex",
818
+ "next": null,
819
+ "parent": null,
820
+ "inputs": {},
821
+ "fields": {},
822
+ "shadow": false,
823
+ "topLevel": true,
824
+ "x": 302,
825
+ "y": 528
826
+ },
827
+ "sensing_mousey": {
828
+ "opcode": "sensing_mousey",
829
+ "next": null,
830
+ "parent": null,
831
+ "inputs": {},
832
+ "fields": {},
833
+ "shadow": false,
834
+ "topLevel": true,
835
+ "x": 668,
836
+ "y": 547
837
+ },
838
+ "sensing_setdragmode": {
839
+ "opcode": "sensing_setdragmode",
840
+ "next": null,
841
+ "parent": null,
842
+ "inputs": {},
843
+ "fields": {
844
+ "DRAG_MODE": [
845
+ "draggable",
846
+ null
847
+ ]
848
+ },
849
+ "shadow": false,
850
+ "topLevel": true,
851
+ "x": 950,
852
+ "y": 574
853
+ },
854
+ "sensing_loudness": {
855
+ "opcode": "sensing_loudness",
856
+ "next": null,
857
+ "parent": null,
858
+ "inputs": {},
859
+ "fields": {},
860
+ "shadow": false,
861
+ "topLevel": true,
862
+ "x": 658,
863
+ "y": 703
864
+ },
865
+ "sensing_timer": {
866
+ "opcode": "sensing_timer",
867
+ "next": null,
868
+ "parent": null,
869
+ "inputs": {},
870
+ "fields": {},
871
+ "shadow": false,
872
+ "topLevel": true,
873
+ "x": 459,
874
+ "y": 671
875
+ },
876
+ "sensing_resettimer": {
877
+ "opcode": "sensing_resettimer",
878
+ "next": null,
879
+ "parent": null,
880
+ "inputs": {},
881
+ "fields": {},
882
+ "shadow": false,
883
+ "topLevel": true,
884
+ "x": 462,
885
+ "y": 781
886
+ },
887
+ "sensing_of": {
888
+ "opcode": "sensing_of",
889
+ "next": null,
890
+ "parent": null,
891
+ "inputs": {
892
+ "OBJECT": [
893
+ 1,
894
+ "t+o*y;iz,!O#aT|qM_+O"
895
+ ]
896
+ },
897
+ "fields": {
898
+ "PROPERTY": [
899
+ "backdrop #",
900
+ null
901
+ ]
902
+ },
903
+ "shadow": false,
904
+ "topLevel": true,
905
+ "x": 997,
906
+ "y": 754
907
+ },
908
+ "sensing_of_object_menu": {
909
+ "opcode": "sensing_of_object_menu",
910
+ "next": null,
911
+ "parent": "[4I2wIG/tNc@LQ-;FbsB",
912
+ "inputs": {},
913
+ "fields": {
914
+ "OBJECT": [
915
+ "_stage_",
916
+ null
917
+ ]
918
+ },
919
+ "shadow": true,
920
+ "topLevel": false
921
+ },
922
+ "sensing_current": {
923
+ "opcode": "sensing_current",
924
+ "next": null,
925
+ "parent": null,
926
+ "inputs": {},
927
+ "fields": {
928
+ "CURRENTMENU": [
929
+ "YEAR",
930
+ null
931
+ ]
932
+ },
933
+ "shadow": false,
934
+ "topLevel": true,
935
+ "x": 627,
936
+ "y": 884
937
+ },
938
+ "sensing_dayssince2000": {
939
+ "opcode": "sensing_dayssince2000",
940
+ "next": null,
941
+ "parent": null,
942
+ "inputs": {},
943
+ "fields": {},
944
+ "shadow": false,
945
+ "topLevel": true,
946
+ "x": 959,
947
+ "y": 903
948
+ },
949
+ "sensing_username": {
950
+ "opcode": "sensing_username",
951
+ "next": null,
952
+ "parent": null,
953
+ "inputs": {},
954
+ "fields": {},
955
+ "shadow": false,
956
+ "topLevel": true,
957
+ "x": 833,
958
+ "y": 757
959
+ },
960
+ "operator_add": {
961
+ "opcode": "operator_add",
962
+ "next": null,
963
+ "parent": null,
964
+ "inputs": {
965
+ "NUM1": [
966
+ 1,
967
+ [
968
+ 4,
969
+ ""
970
+ ]
971
+ ],
972
+ "NUM2": [
973
+ 1,
974
+ [
975
+ 4,
976
+ ""
977
+ ]
978
+ ]
979
+ },
980
+ "fields": {},
981
+ "shadow": false,
982
+ "topLevel": true,
983
+ "x": 128,
984
+ "y": 153
985
+ },
986
+ "operator_subtract": {
987
+ "opcode": "operator_subtract",
988
+ "next": null,
989
+ "parent": null,
990
+ "inputs": {
991
+ "NUM1": [
992
+ 1,
993
+ [
994
+ 4,
995
+ ""
996
+ ]
997
+ ],
998
+ "NUM2": [
999
+ 1,
1000
+ [
1001
+ 4,
1002
+ ""
1003
+ ]
1004
+ ]
1005
+ },
1006
+ "fields": {},
1007
+ "shadow": false,
1008
+ "topLevel": true,
1009
+ "x": 134,
1010
+ "y": 214
1011
+ },
1012
+ "operator_multiply": {
1013
+ "opcode": "operator_multiply",
1014
+ "next": null,
1015
+ "parent": null,
1016
+ "inputs": {
1017
+ "NUM1": [
1018
+ 1,
1019
+ [
1020
+ 4,
1021
+ ""
1022
+ ]
1023
+ ],
1024
+ "NUM2": [
1025
+ 1,
1026
+ [
1027
+ 4,
1028
+ ""
1029
+ ]
1030
+ ]
1031
+ },
1032
+ "fields": {},
1033
+ "shadow": false,
1034
+ "topLevel": true,
1035
+ "x": 134,
1036
+ "y": 278
1037
+ },
1038
+ "operator_divide": {
1039
+ "opcode": "operator_divide",
1040
+ "next": null,
1041
+ "parent": null,
1042
+ "inputs": {
1043
+ "NUM1": [
1044
+ 1,
1045
+ [
1046
+ 4,
1047
+ ""
1048
+ ]
1049
+ ],
1050
+ "NUM2": [
1051
+ 1,
1052
+ [
1053
+ 4,
1054
+ ""
1055
+ ]
1056
+ ]
1057
+ },
1058
+ "fields": {},
1059
+ "shadow": false,
1060
+ "topLevel": true,
1061
+ "x": 138,
1062
+ "y": 359
1063
+ },
1064
+ "operator_random": {
1065
+ "opcode": "operator_random",
1066
+ "next": null,
1067
+ "parent": null,
1068
+ "inputs": {
1069
+ "FROM": [
1070
+ 1,
1071
+ [
1072
+ 4,
1073
+ "1"
1074
+ ]
1075
+ ],
1076
+ "TO": [
1077
+ 1,
1078
+ [
1079
+ 4,
1080
+ "10"
1081
+ ]
1082
+ ]
1083
+ },
1084
+ "fields": {},
1085
+ "shadow": false,
1086
+ "topLevel": true,
1087
+ "x": 311,
1088
+ "y": 157
1089
+ },
1090
+ "operator_gt": {
1091
+ "opcode": "operator_gt",
1092
+ "next": null,
1093
+ "parent": null,
1094
+ "inputs": {
1095
+ "OPERAND1": [
1096
+ 1,
1097
+ [
1098
+ 10,
1099
+ ""
1100
+ ]
1101
+ ],
1102
+ "OPERAND2": [
1103
+ 1,
1104
+ [
1105
+ 10,
1106
+ "50"
1107
+ ]
1108
+ ]
1109
+ },
1110
+ "fields": {},
1111
+ "shadow": false,
1112
+ "topLevel": true,
1113
+ "x": 348,
1114
+ "y": 217
1115
+ },
1116
+ "operator_lt": {
1117
+ "opcode": "operator_lt",
1118
+ "next": null,
1119
+ "parent": null,
1120
+ "inputs": {
1121
+ "OPERAND1": [
1122
+ 1,
1123
+ [
1124
+ 10,
1125
+ ""
1126
+ ]
1127
+ ],
1128
+ "OPERAND2": [
1129
+ 1,
1130
+ [
1131
+ 10,
1132
+ "50"
1133
+ ]
1134
+ ]
1135
+ },
1136
+ "fields": {},
1137
+ "shadow": false,
1138
+ "topLevel": true,
1139
+ "x": 345,
1140
+ "y": 286
1141
+ },
1142
+ "operator_equals": {
1143
+ "opcode": "operator_equals",
1144
+ "next": null,
1145
+ "parent": null,
1146
+ "inputs": {
1147
+ "OPERAND1": [
1148
+ 1,
1149
+ [
1150
+ 10,
1151
+ ""
1152
+ ]
1153
+ ],
1154
+ "OPERAND2": [
1155
+ 1,
1156
+ [
1157
+ 10,
1158
+ "50"
1159
+ ]
1160
+ ]
1161
+ },
1162
+ "fields": {},
1163
+ "shadow": false,
1164
+ "topLevel": true,
1165
+ "x": 345,
1166
+ "y": 372
1167
+ },
1168
+ "operator_and": {
1169
+ "opcode": "operator_and",
1170
+ "next": null,
1171
+ "parent": null,
1172
+ "inputs": {},
1173
+ "fields": {},
1174
+ "shadow": false,
1175
+ "topLevel": true,
1176
+ "x": 701,
1177
+ "y": 158
1178
+ },
1179
+ "operator_or": {
1180
+ "opcode": "operator_or",
1181
+ "next": null,
1182
+ "parent": null,
1183
+ "inputs": {},
1184
+ "fields": {},
1185
+ "shadow": false,
1186
+ "topLevel": true,
1187
+ "x": 705,
1188
+ "y": 222
1189
+ },
1190
+ "operator_not": {
1191
+ "opcode": "operator_not",
1192
+ "next": null,
1193
+ "parent": null,
1194
+ "inputs": {},
1195
+ "fields": {},
1196
+ "shadow": false,
1197
+ "topLevel": true,
1198
+ "x": 734,
1199
+ "y": 283
1200
+ },
1201
+ "operator_join": {
1202
+ "opcode": "operator_join",
1203
+ "next": null,
1204
+ "parent": null,
1205
+ "inputs": {
1206
+ "STRING1": [
1207
+ 1,
1208
+ [
1209
+ 10,
1210
+ "apple "
1211
+ ]
1212
+ ],
1213
+ "STRING2": [
1214
+ 1,
1215
+ [
1216
+ 10,
1217
+ "banana"
1218
+ ]
1219
+ ]
1220
+ },
1221
+ "fields": {},
1222
+ "shadow": false,
1223
+ "topLevel": true,
1224
+ "x": 663,
1225
+ "y": 378
1226
+ },
1227
+ "operator_letter_of": {
1228
+ "opcode": "operator_letter_of",
1229
+ "next": null,
1230
+ "parent": null,
1231
+ "inputs": {
1232
+ "LETTER": [
1233
+ 1,
1234
+ [
1235
+ 6,
1236
+ "1"
1237
+ ]
1238
+ ],
1239
+ "STRING": [
1240
+ 1,
1241
+ [
1242
+ 10,
1243
+ "apple"
1244
+ ]
1245
+ ]
1246
+ },
1247
+ "fields": {},
1248
+ "shadow": false,
1249
+ "topLevel": true,
1250
+ "x": 664,
1251
+ "y": 445
1252
+ },
1253
+ "operator_length": {
1254
+ "opcode": "operator_length",
1255
+ "next": null,
1256
+ "parent": null,
1257
+ "inputs": {
1258
+ "STRING": [
1259
+ 1,
1260
+ [
1261
+ 10,
1262
+ "apple"
1263
+ ]
1264
+ ]
1265
+ },
1266
+ "fields": {},
1267
+ "shadow": false,
1268
+ "topLevel": true,
1269
+ "x": 664,
1270
+ "y": 521
1271
+ },
1272
+ "operator_contains": {
1273
+ "opcode": "operator_contains",
1274
+ "next": null,
1275
+ "parent": null,
1276
+ "inputs": {
1277
+ "STRING1": [
1278
+ 1,
1279
+ [
1280
+ 10,
1281
+ "apple"
1282
+ ]
1283
+ ],
1284
+ "STRING2": [
1285
+ 1,
1286
+ [
1287
+ 10,
1288
+ "a"
1289
+ ]
1290
+ ]
1291
+ },
1292
+ "fields": {},
1293
+ "shadow": false,
1294
+ "topLevel": true,
1295
+ "x": 634,
1296
+ "y": 599
1297
+ },
1298
+ "operator_mod": {
1299
+ "opcode": "operator_mod",
1300
+ "next": null,
1301
+ "parent": null,
1302
+ "inputs": {
1303
+ "NUM1": [
1304
+ 1,
1305
+ [
1306
+ 4,
1307
+ ""
1308
+ ]
1309
+ ],
1310
+ "NUM2": [
1311
+ 1,
1312
+ [
1313
+ 4,
1314
+ ""
1315
+ ]
1316
+ ]
1317
+ },
1318
+ "fields": {},
1319
+ "shadow": false,
1320
+ "topLevel": true,
1321
+ "x": 295,
1322
+ "y": 594
1323
+ },
1324
+ "operator_round": {
1325
+ "opcode": "operator_round",
1326
+ "next": null,
1327
+ "parent": null,
1328
+ "inputs": {
1329
+ "NUM": [
1330
+ 1,
1331
+ [
1332
+ 4,
1333
+ ""
1334
+ ]
1335
+ ]
1336
+ },
1337
+ "fields": {},
1338
+ "shadow": false,
1339
+ "topLevel": true,
1340
+ "x": 307,
1341
+ "y": 674
1342
+ },
1343
+ "operator_mathop": {
1344
+ "opcode": "operator_mathop",
1345
+ "next": null,
1346
+ "parent": null,
1347
+ "inputs": {
1348
+ "NUM": [
1349
+ 1,
1350
+ [
1351
+ 4,
1352
+ ""
1353
+ ]
1354
+ ]
1355
+ },
1356
+ "fields": {
1357
+ "OPERATOR": [
1358
+ "abs",
1359
+ null
1360
+ ]
1361
+ },
1362
+ "shadow": false,
1363
+ "topLevel": true,
1364
+ "x": 280,
1365
+ "y": 754
1366
+ }
1367
+ }
v2/scratch_agent/blocks_defination.py ADDED
@@ -0,0 +1,274 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ALL_SCRATCH_BLOCKS_CATALOG = {
2
+ "motion_movesteps": {
3
+ "opcode": "motion_movesteps",
4
+ "next": null,
5
+ "parent": null,
6
+ "inputs": {
7
+ "STEPS": [
8
+ 1,
9
+ [
10
+ 4,
11
+ "10"
12
+ ]
13
+ ]
14
+ },
15
+ "fields": {},
16
+ "shadow": False,
17
+ "topLevel": True,
18
+ "x": 464,
19
+ "y": -416
20
+ },
21
+ "motion_turnright": {
22
+ "opcode": "motion_turnright",
23
+ "inputs": {"DEGREES": [1, [4, "15"]]},
24
+ "fields": {},
25
+ "shadow": False
26
+ },
27
+ "motion_turnleft": {
28
+ "opcode": "motion_turnleft",
29
+ "inputs": {"DEGREES": [1, [4, "15"]]},
30
+ "fields": {},
31
+ "shadow": False
32
+ },
33
+ "motion_goto": {
34
+ "opcode": "motion_goto",
35
+ "inputs": {"TO": [1, None]}, # TO input will be filled by a menu block ID
36
+ "fields": {},
37
+ "shadow": False
38
+ },
39
+ "motion_goto_menu": { # Shadow block for motion_goto
40
+ "opcode": "motion_goto_menu",
41
+ "inputs": {},
42
+ "fields": {"TO": ["_random_", None]},
43
+ "shadow": True
44
+ },
45
+ "motion_gotoxy": {
46
+ "opcode": "motion_gotoxy",
47
+ "inputs": {"X": [1, [4, "0"]], "Y": [1, [4, "0"]]},
48
+ "fields": {},
49
+ "shadow": False
50
+ },
51
+ "motion_glideto": {
52
+ "opcode": "motion_glideto",
53
+ "inputs": {"SECS": [1, [4, "1"]], "TO": [1, None]}, # TO input will be filled by a menu block ID
54
+ "fields": {},
55
+ "shadow": False
56
+ },
57
+ "motion_glideto_menu": { # Shadow block for motion_glideto
58
+ "opcode": "motion_glideto_menu",
59
+ "inputs": {},
60
+ "fields": {"TO": ["_random_", None]},
61
+ "shadow": True
62
+ },
63
+ "motion_glidesecstoxy": {
64
+ "opcode": "motion_glidesecstoxy",
65
+ "inputs": {"SECS": [1, [4, "1"]], "X": [1, [4, "0"]], "Y": [1, [4, "0"]]},
66
+ "fields": {},
67
+ "shadow": False
68
+ },
69
+ "motion_pointindirection": {
70
+ "opcode": "motion_pointindirection",
71
+ "inputs": {"DIRECTION": [1, [8, "90"]]},
72
+ "fields": {},
73
+ "shadow": False
74
+ },
75
+ "motion_pointtowards": {
76
+ "opcode": "motion_pointtowards",
77
+ "inputs": {"TOWARDS": [1, None]}, # TOWARDS input will be filled by a menu block ID
78
+ "fields": {},
79
+ "shadow": False
80
+ },
81
+ "motion_pointtowards_menu": { # Shadow block for motion_pointtowards
82
+ "opcode": "motion_pointtowards_menu",
83
+ "inputs": {},
84
+ "fields": {"TOWARDS": ["_mouse_", None]},
85
+ "shadow": True
86
+ },
87
+ "motion_changexby": {
88
+ "opcode": "motion_changexby",
89
+ "inputs": {"DX": [1, [4, "10"]]},
90
+ "fields": {},
91
+ "shadow": False
92
+ },
93
+ "motion_setx": {
94
+ "opcode": "motion_setx",
95
+ "inputs": {"X": [1, [4, "0"]]},
96
+ "fields": {},
97
+ "shadow": False
98
+ },
99
+ "motion_changeyby": {
100
+ "opcode": "motion_changeyby",
101
+ "inputs": {"DY": [1, [4, "10"]]},
102
+ "fields": {},
103
+ "shadow": False
104
+ },
105
+ "motion_sety": {
106
+ "opcode": "motion_sety",
107
+ "inputs": {"Y": [1, [4, "0"]]},
108
+ "fields": {},
109
+ "shadow": False
110
+ },
111
+ "motion_ifonedgebounce": {
112
+ "opcode": "motion_ifonedgebounce",
113
+ "next": None, "parent": None, "inputs": {}, "fields": {}, "shadow": False
114
+ },
115
+ "motion_setrotationstyle": {
116
+ "opcode": "motion_setrotationstyle",
117
+ "inputs": {},
118
+ "fields": {"STYLE": ["left-right", None]},
119
+ "shadow": False
120
+ },
121
+ "motion_xposition": {
122
+ "opcode": "motion_xposition",
123
+ "inputs": {}, "fields": {}, "shadow": False
124
+ },
125
+ "motion_yposition": {
126
+ "opcode": "motion_yposition",
127
+ "inputs": {}, "fields": {}, "shadow": False
128
+ },
129
+ "motion_direction": {
130
+ "opcode": "motion_direction",
131
+ "inputs": {}, "fields": {}, "shadow": False
132
+ },
133
+ # Control Blocks
134
+ "control_wait": {
135
+ "opcode": "control_wait",
136
+ "inputs": {"DURATION": [1, [5, "1"]]},
137
+ "fields": {},
138
+ "shadow": False
139
+ },
140
+ "control_repeat": {
141
+ "opcode": "control_repeat",
142
+ "inputs": {"TIMES": [1, [6, "10"]], "SUBSTACK": [2, None]}, # SUBSTACK to be filled
143
+ "fields": {},
144
+ "shadow": False
145
+ },
146
+ "control_forever": {
147
+ "opcode": "control_forever",
148
+ "inputs": {"SUBSTACK": [2, None]}, # SUBSTACK to be filled
149
+ "fields": {},
150
+ "shadow": False
151
+ },
152
+ "control_if": {
153
+ "opcode": "control_if",
154
+ "inputs": {"CONDITION": [2, None], "SUBSTACK": [2, None]}, # CONDITION and SUBSTACK to be filled
155
+ "fields": {},
156
+ "shadow": False
157
+ },
158
+ "control_if_else": {
159
+ "opcode": "control_if_else",
160
+ "inputs": {"CONDITION": [2, None], "SUBSTACK": [2, None], "SUBSTACK2": [2, None]}, # All to be filled
161
+ "fields": {},
162
+ "shadow": False
163
+ },
164
+ "control_wait_until": {
165
+ "opcode": "control_wait_until",
166
+ "inputs": {"CONDITION": [2, None]},
167
+ "fields": {},
168
+ "shadow": False
169
+ },
170
+ "control_repeat_until": {
171
+ "opcode": "control_repeat_until",
172
+ "inputs": {"CONDITION": [2, None], "SUBSTACK": [2, None]},
173
+ "fields": {},
174
+ "shadow": False
175
+ },
176
+ "control_stop": {
177
+ "opcode": "control_stop",
178
+ "inputs": {},
179
+ "fields": {"STOP_OPTION": ["all", None]},
180
+ "shadow": False,
181
+ "mutation": {"tagName": "mutation", "children": [], "hasnext": "false"}
182
+ },
183
+ "control_start_as_clone": {
184
+ "opcode": "control_start_as_clone",
185
+ "inputs": {}, "fields": {}, "shadow": False
186
+ },
187
+ "control_create_clone_of": {
188
+ "opcode": "control_create_clone_of",
189
+ "inputs": {"CLONE_OPTION": [1, None]}, # CLONE_OPTION to be filled by menu block ID
190
+ "fields": {},
191
+ "shadow": False
192
+ },
193
+ "control_create_clone_of_menu": { # Shadow block for control_create_clone_of
194
+ "opcode": "control_create_clone_of_menu",
195
+ "inputs": {},
196
+ "fields": {"CLONE_OPTION": ["_myself_", None]},
197
+ "shadow": True
198
+ },
199
+ "control_delete_this_clone": {
200
+ "opcode": "control_delete_this_clone",
201
+ "inputs": {}, "fields": {}, "shadow": False
202
+ },
203
+ # Event Blocks
204
+ "event_whenflagclicked": {
205
+ "opcode": "event_whenflagclicked",
206
+ "inputs": {}, "fields": {}, "shadow": False
207
+ },
208
+ "event_whenkeypressed": {
209
+ "opcode": "event_whenkeypressed",
210
+ "inputs": {},
211
+ "fields": {"KEY_OPTION": ["space", None]},
212
+ "shadow": False
213
+ },
214
+ "event_whenthisspriteclicked": {
215
+ "opcode": "event_whenthisspriteclicked",
216
+ "inputs": {}, "fields": {}, "shadow": False
217
+ },
218
+ "event_whenbackdropswitchesto": {
219
+ "opcode": "event_whenbackdropswitchesto",
220
+ "inputs": {},
221
+ "fields": {"BACKDROP": ["backdrop1", None]},
222
+ "shadow": False
223
+ },
224
+ "event_whengreaterthan": {
225
+ "opcode": "event_whengreaterthan",
226
+ "inputs": {"VALUE": [1, [4, "10"]]},
227
+ "fields": {"WHENGREATERTHANMENU": ["LOUDNESS", None]},
228
+ "shadow": False
229
+ },
230
+ "event_whenbroadcastreceived": {
231
+ "opcode": "event_whenbroadcastreceived",
232
+ "inputs": {},
233
+ "fields": {"BROADCAST_OPTION": ["message1", None]},
234
+ "shadow": False
235
+ },
236
+ "event_broadcast": {
237
+ "opcode": "event_broadcast",
238
+ "inputs": {"BROADCAST_INPUT": [1, None]}, # BROADCAST_INPUT to be filled by menu or text block
239
+ "fields": {},
240
+ "shadow": False
241
+ },
242
+ "event_broadcastandwait": {
243
+ "opcode": "event_broadcastandwait",
244
+ "inputs": {"BROADCAST_INPUT": [1, None]},
245
+ "fields": {},
246
+ "shadow": False
247
+ },
248
+ # Sensing Blocks (example, can be expanded)
249
+ "sensing_touchingobject": {
250
+ "opcode": "sensing_touchingobject",
251
+ "inputs": {"TOUCHINGOBJECTMENU": [1, None]}, # Input for menu block ID
252
+ "fields": {},
253
+ "shadow": False
254
+ },
255
+ "sensing_touchingobjectmenu": { # Shadow block for sensing_touchingobject
256
+ "opcode": "sensing_touchingobjectmenu",
257
+ "inputs": {},
258
+ "fields": {"TOUCHINGOBJECTMENU": ["_mouse_", None]},
259
+ "shadow": True
260
+ },
261
+ # Operators (example, can be expanded)
262
+ "operator_add": {
263
+ "opcode": "operator_add",
264
+ "inputs": {"NUM1": [1, [4, "0"]], "NUM2": [1, [4, "0"]]},
265
+ "fields": {},
266
+ "shadow": False
267
+ },
268
+ "operator_equals": {
269
+ "opcode": "operator_equals",
270
+ "inputs": {"OPERAND1": [1, [10, ""]], "OPERAND2": [1, [10, ""]]},
271
+ "fields": {},
272
+ "shadow": False
273
+ }
274
+ }
v2/scratch_agent/blocks_v1/blocks.json ADDED
@@ -0,0 +1,2221 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "motion_movesteps": {
3
+ "opcode": "motion_movesteps",
4
+ "next": null,
5
+ "parent": null,
6
+ "inputs": {
7
+ "STEPS": [
8
+ 1,
9
+ [
10
+ 4,
11
+ "10"
12
+ ]
13
+ ]
14
+ },
15
+ "fields": {},
16
+ "shadow": false,
17
+ "topLevel": true,
18
+ "x": 464,
19
+ "y": -416
20
+ },
21
+ "motion_turnright": {
22
+ "opcode": "motion_turnright",
23
+ "next": null,
24
+ "parent": null,
25
+ "inputs": {
26
+ "DEGREES": [
27
+ 1,
28
+ [
29
+ 4,
30
+ "15"
31
+ ]
32
+ ]
33
+ },
34
+ "fields": {},
35
+ "shadow": false,
36
+ "topLevel": true,
37
+ "x": 467,
38
+ "y": -316
39
+ },
40
+ "motion_turnleft": {
41
+ "opcode": "motion_turnleft",
42
+ "next": null,
43
+ "parent": null,
44
+ "inputs": {
45
+ "DEGREES": [
46
+ 1,
47
+ [
48
+ 4,
49
+ "15"
50
+ ]
51
+ ]
52
+ },
53
+ "fields": {},
54
+ "shadow": false,
55
+ "topLevel": true,
56
+ "x": 464,
57
+ "y": -210
58
+ },
59
+ "motion_goto": {
60
+ "opcode": "motion_goto",
61
+ "next": null,
62
+ "parent": null,
63
+ "inputs": {
64
+ "TO": [
65
+ 1,
66
+ "@iM=Z?~GCbpC}gT7KAKY"
67
+ ]
68
+ },
69
+ "fields": {},
70
+ "shadow": false,
71
+ "topLevel": true,
72
+ "x": 465,
73
+ "y": -95
74
+ },
75
+ "motion_goto_menu": {
76
+ "opcode": "motion_goto_menu",
77
+ "next": null,
78
+ "parent": "d|J?C902/xy6tD5,|dmB",
79
+ "inputs": {},
80
+ "fields": {
81
+ "TO": [
82
+ "_random_",
83
+ null
84
+ ]
85
+ },
86
+ "shadow": true,
87
+ "topLevel": false
88
+ },
89
+ "motion_gotoxy": {
90
+ "opcode": "motion_gotoxy",
91
+ "next": null,
92
+ "parent": null,
93
+ "inputs": {
94
+ "X": [
95
+ 1,
96
+ [
97
+ 4,
98
+ "0"
99
+ ]
100
+ ],
101
+ "Y": [
102
+ 1,
103
+ [
104
+ 4,
105
+ "0"
106
+ ]
107
+ ]
108
+ },
109
+ "fields": {},
110
+ "shadow": false,
111
+ "topLevel": true,
112
+ "x": 468,
113
+ "y": 12
114
+ },
115
+ "motion_glideto": {
116
+ "opcode": "motion_glideto",
117
+ "next": null,
118
+ "parent": null,
119
+ "inputs": {
120
+ "SECS": [
121
+ 1,
122
+ [
123
+ 4,
124
+ "1"
125
+ ]
126
+ ],
127
+ "TO": [
128
+ 1,
129
+ "{id to destination position}"
130
+ ]
131
+ },
132
+ "fields": {},
133
+ "shadow": false,
134
+ "topLevel": true,
135
+ "x": 470,
136
+ "y": 129
137
+ },
138
+ "motion_glideto_menu": {
139
+ "opcode": "motion_glideto_menu",
140
+ "next": null,
141
+ "parent": null,
142
+ "inputs": {},
143
+ "fields": {
144
+ "TO": [
145
+ "_random_",
146
+ null
147
+ ]
148
+ },
149
+ "shadow": true,
150
+ "topLevel": false
151
+ },
152
+ "motion_glidesecstoxy": {
153
+ "opcode": "motion_glidesecstoxy",
154
+ "next": null,
155
+ "parent": null,
156
+ "inputs": {
157
+ "SECS": [
158
+ 1,
159
+ [
160
+ 4,
161
+ "1"
162
+ ]
163
+ ],
164
+ "X": [
165
+ 1,
166
+ [
167
+ 4,
168
+ "0"
169
+ ]
170
+ ],
171
+ "Y": [
172
+ 1,
173
+ [
174
+ 4,
175
+ "0"
176
+ ]
177
+ ]
178
+ },
179
+ "fields": {},
180
+ "shadow": false,
181
+ "topLevel": true,
182
+ "x": 476,
183
+ "y": 239
184
+ },
185
+ "motion_pointindirection": {
186
+ "opcode": "motion_pointindirection",
187
+ "next": null,
188
+ "parent": null,
189
+ "inputs": {
190
+ "DIRECTION": [
191
+ 1,
192
+ [
193
+ 8,
194
+ "90"
195
+ ]
196
+ ]
197
+ },
198
+ "fields": {},
199
+ "shadow": false,
200
+ "topLevel": true,
201
+ "x": 493,
202
+ "y": 361
203
+ },
204
+ "motion_pointtowards": {
205
+ "opcode": "motion_pointtowards",
206
+ "next": null,
207
+ "parent": null,
208
+ "inputs": {
209
+ "TOWARDS": [
210
+ 1,
211
+ "6xQl1pPk%9E~Znhm*:ng"
212
+ ]
213
+ },
214
+ "fields": {},
215
+ "shadow": false,
216
+ "topLevel": true,
217
+ "x": 492,
218
+ "y": 463
219
+ },
220
+ "motion_pointtowards_menu": {
221
+ "opcode": "motion_pointtowards_menu",
222
+ "next": null,
223
+ "parent": "Ucm$YBs*^9GFTGXCbal@",
224
+ "inputs": {},
225
+ "fields": {
226
+ "TOWARDS": [
227
+ "_mouse_",
228
+ null
229
+ ]
230
+ },
231
+ "shadow": true,
232
+ "topLevel": false
233
+ },
234
+ "motion_changexby": {
235
+ "opcode": "motion_changexby",
236
+ "next": null,
237
+ "parent": null,
238
+ "inputs": {
239
+ "DX": [
240
+ 1,
241
+ [
242
+ 4,
243
+ "10"
244
+ ]
245
+ ]
246
+ },
247
+ "fields": {},
248
+ "shadow": false,
249
+ "topLevel": true,
250
+ "x": 851,
251
+ "y": -409
252
+ },
253
+ "motion_setx": {
254
+ "opcode": "motion_setx",
255
+ "next": null,
256
+ "parent": null,
257
+ "inputs": {
258
+ "X": [
259
+ 1,
260
+ [
261
+ 4,
262
+ "0"
263
+ ]
264
+ ]
265
+ },
266
+ "fields": {},
267
+ "shadow": false,
268
+ "topLevel": true,
269
+ "x": 864,
270
+ "y": -194
271
+ },
272
+ "motion_changeyby": {
273
+ "opcode": "motion_changeyby",
274
+ "next": null,
275
+ "parent": null,
276
+ "inputs": {
277
+ "DY": [
278
+ 1,
279
+ [
280
+ 4,
281
+ "10"
282
+ ]
283
+ ]
284
+ },
285
+ "fields": {},
286
+ "shadow": false,
287
+ "topLevel": true,
288
+ "x": 861,
289
+ "y": -61
290
+ },
291
+ "motion_sety": {
292
+ "opcode": "motion_sety",
293
+ "next": null,
294
+ "parent": null,
295
+ "inputs": {
296
+ "Y": [
297
+ 1,
298
+ [
299
+ 4,
300
+ "0"
301
+ ]
302
+ ]
303
+ },
304
+ "fields": {},
305
+ "shadow": false,
306
+ "topLevel": true,
307
+ "x": 864,
308
+ "y": 66
309
+ },
310
+ "motion_ifonedgebounce": {
311
+ "opcode": "motion_ifonedgebounce",
312
+ "next": null,
313
+ "parent": null,
314
+ "inputs": {},
315
+ "fields": {},
316
+ "shadow": false,
317
+ "topLevel": true,
318
+ "x": 1131,
319
+ "y": -397
320
+ },
321
+ "motion_setrotationstyle": {
322
+ "opcode": "motion_setrotationstyle",
323
+ "next": null,
324
+ "parent": null,
325
+ "inputs": {},
326
+ "fields": {
327
+ "STYLE": [
328
+ "left-right",
329
+ null
330
+ ]
331
+ },
332
+ "shadow": false,
333
+ "topLevel": true,
334
+ "x": 1128,
335
+ "y": -287
336
+ },
337
+ "motion_xposition": {
338
+ "opcode": "motion_xposition",
339
+ "next": null,
340
+ "parent": null,
341
+ "inputs": {},
342
+ "fields": {},
343
+ "shadow": false,
344
+ "topLevel": true,
345
+ "x": 1193,
346
+ "y": -136
347
+ },
348
+ "motion_yposition": {
349
+ "opcode": "motion_yposition",
350
+ "next": null,
351
+ "parent": null,
352
+ "inputs": {},
353
+ "fields": {},
354
+ "shadow": false,
355
+ "topLevel": true,
356
+ "x": 1181,
357
+ "y": -64
358
+ },
359
+ "motion_direction": {
360
+ "opcode": "motion_direction",
361
+ "next": null,
362
+ "parent": null,
363
+ "inputs": {},
364
+ "fields": {},
365
+ "shadow": false,
366
+ "topLevel": true,
367
+ "x": 1188,
368
+ "y": 21
369
+ },
370
+ "control_wait": {
371
+ "opcode": "control_wait",
372
+ "next": null,
373
+ "parent": null,
374
+ "inputs": {
375
+ "DURATION": [
376
+ 1,
377
+ [
378
+ 5,
379
+ "1"
380
+ ]
381
+ ]
382
+ },
383
+ "fields": {},
384
+ "shadow": false,
385
+ "topLevel": true,
386
+ "x": 337,
387
+ "y": 129
388
+ },
389
+ "control_repeat": {
390
+ "opcode": "control_repeat",
391
+ "next": null,
392
+ "parent": null,
393
+ "inputs": {
394
+ "TIMES": [
395
+ 1,
396
+ [
397
+ 6,
398
+ "10"
399
+ ]
400
+ ]
401
+ },
402
+ "fields": {},
403
+ "shadow": false,
404
+ "topLevel": true,
405
+ "x": 348,
406
+ "y": 265
407
+ },
408
+ "control_forever": {
409
+ "opcode": "control_forever",
410
+ "next": null,
411
+ "parent": null,
412
+ "inputs": {},
413
+ "fields": {},
414
+ "shadow": false,
415
+ "topLevel": true,
416
+ "x": 334,
417
+ "y": 439
418
+ },
419
+ "control_if": {
420
+ "opcode": "control_if",
421
+ "next": null,
422
+ "parent": null,
423
+ "inputs": {},
424
+ "fields": {},
425
+ "shadow": false,
426
+ "topLevel": true,
427
+ "x": 331,
428
+ "y": 597
429
+ },
430
+ "control_if_else": {
431
+ "opcode": "control_if_else",
432
+ "next": null,
433
+ "parent": null,
434
+ "inputs": {},
435
+ "fields": {},
436
+ "shadow": false,
437
+ "topLevel": true,
438
+ "x": 335,
439
+ "y": 779
440
+ },
441
+ "control_wait_until": {
442
+ "opcode": "control_wait_until",
443
+ "next": null,
444
+ "parent": null,
445
+ "inputs": {},
446
+ "fields": {},
447
+ "shadow": false,
448
+ "topLevel": true,
449
+ "x": 676,
450
+ "y": 285
451
+ },
452
+ "control_repeat_until": {
453
+ "opcode": "control_repeat_until",
454
+ "next": null,
455
+ "parent": null,
456
+ "inputs": {},
457
+ "fields": {},
458
+ "shadow": false,
459
+ "topLevel": true,
460
+ "x": 692,
461
+ "y": 381
462
+ },
463
+ "control_stop": {
464
+ "opcode": "control_stop",
465
+ "next": null,
466
+ "parent": null,
467
+ "inputs": {},
468
+ "fields": {
469
+ "STOP_OPTION": [
470
+ "all",
471
+ null
472
+ ]
473
+ },
474
+ "shadow": false,
475
+ "topLevel": true,
476
+ "x": 708,
477
+ "y": 545,
478
+ "mutation": {
479
+ "tagName": "mutation",
480
+ "children": [],
481
+ "hasnext": "false"
482
+ }
483
+ },
484
+ "control_start_as_clone": {
485
+ "opcode": "control_start_as_clone",
486
+ "next": null,
487
+ "parent": null,
488
+ "inputs": {},
489
+ "fields": {},
490
+ "shadow": false,
491
+ "topLevel": true,
492
+ "x": 665,
493
+ "y": 672
494
+ },
495
+ "control_create_clone_of": {
496
+ "opcode": "control_create_clone_of",
497
+ "next": null,
498
+ "parent": null,
499
+ "inputs": {
500
+ "CLONE_OPTION": [
501
+ 1,
502
+ "t))DW9(QSKB]3C/3Ou+J"
503
+ ]
504
+ },
505
+ "fields": {},
506
+ "shadow": false,
507
+ "topLevel": true,
508
+ "x": 648,
509
+ "y": 797
510
+ },
511
+ "control_create_clone_of_menu": {
512
+ "opcode": "control_create_clone_of_menu",
513
+ "next": null,
514
+ "parent": "80yo/}Cw++Z.;x[ohh|7",
515
+ "inputs": {},
516
+ "fields": {
517
+ "CLONE_OPTION": [
518
+ "_myself_",
519
+ null
520
+ ]
521
+ },
522
+ "shadow": true,
523
+ "topLevel": false
524
+ },
525
+ "control_delete_this_clone": {
526
+ "opcode": "control_delete_this_clone",
527
+ "next": null,
528
+ "parent": null,
529
+ "inputs": {},
530
+ "fields": {},
531
+ "shadow": false,
532
+ "topLevel": true,
533
+ "x": 642,
534
+ "y": 914
535
+ },
536
+ "event_whenflagclicked": {
537
+ "opcode": "event_whenflagclicked",
538
+ "next": null,
539
+ "parent": null,
540
+ "inputs": {},
541
+ "fields": {},
542
+ "shadow": false,
543
+ "topLevel": true,
544
+ "x": 166,
545
+ "y": -422
546
+ },
547
+ "event_whenkeypressed": {
548
+ "opcode": "event_whenkeypressed",
549
+ "next": null,
550
+ "parent": null,
551
+ "inputs": {},
552
+ "fields": {
553
+ "KEY_OPTION": [
554
+ "space",
555
+ null
556
+ ]
557
+ },
558
+ "shadow": false,
559
+ "topLevel": true,
560
+ "x": 151,
561
+ "y": -329
562
+ },
563
+ "event_whenthisspriteclicked": {
564
+ "opcode": "event_whenthisspriteclicked",
565
+ "next": null,
566
+ "parent": null,
567
+ "inputs": {},
568
+ "fields": {},
569
+ "shadow": false,
570
+ "topLevel": true,
571
+ "x": 156,
572
+ "y": -223
573
+ },
574
+ "event_whenbackdropswitchesto": {
575
+ "opcode": "event_whenbackdropswitchesto",
576
+ "next": null,
577
+ "parent": null,
578
+ "inputs": {},
579
+ "fields": {
580
+ "BACKDROP": [
581
+ "backdrop1",
582
+ null
583
+ ]
584
+ },
585
+ "shadow": false,
586
+ "topLevel": true,
587
+ "x": 148,
588
+ "y": -101
589
+ },
590
+ "event_whengreaterthan": {
591
+ "opcode": "event_whengreaterthan",
592
+ "next": null,
593
+ "parent": null,
594
+ "inputs": {
595
+ "VALUE": [
596
+ 1,
597
+ [
598
+ 4,
599
+ "10"
600
+ ]
601
+ ]
602
+ },
603
+ "fields": {
604
+ "WHENGREATERTHANMENU": [
605
+ "LOUDNESS",
606
+ null
607
+ ]
608
+ },
609
+ "shadow": false,
610
+ "topLevel": true,
611
+ "x": 150,
612
+ "y": 10
613
+ },
614
+ "event_whenbroadcastreceived": {
615
+ "opcode": "event_whenbroadcastreceived",
616
+ "next": null,
617
+ "parent": null,
618
+ "inputs": {},
619
+ "fields": {
620
+ "BROADCAST_OPTION": [
621
+ "message1",
622
+ "5O!nei;S$!c!=hCT}0:a"
623
+ ]
624
+ },
625
+ "shadow": false,
626
+ "topLevel": true,
627
+ "x": 141,
628
+ "y": 118
629
+ },
630
+ "event_broadcast": {
631
+ "opcode": "event_broadcast",
632
+ "next": null,
633
+ "parent": null,
634
+ "inputs": {
635
+ "BROADCAST_INPUT": [
636
+ 1,
637
+ [
638
+ 11,
639
+ "message1",
640
+ "5O!nei;S$!c!=hCT}0:a"
641
+ ]
642
+ ]
643
+ },
644
+ "fields": {},
645
+ "shadow": false,
646
+ "topLevel": true,
647
+ "x": 151,
648
+ "y": 229
649
+ },
650
+ "event_broadcastandwait": {
651
+ "opcode": "event_broadcastandwait",
652
+ "next": null,
653
+ "parent": null,
654
+ "inputs": {
655
+ "BROADCAST_INPUT": [
656
+ 1,
657
+ [
658
+ 11,
659
+ "message1",
660
+ "5O!nei;S$!c!=hCT}0:a"
661
+ ]
662
+ ]
663
+ },
664
+ "fields": {},
665
+ "shadow": false,
666
+ "topLevel": true,
667
+ "x": 157,
668
+ "y": 340
669
+ },
670
+ "sensing_touchingobject": {
671
+ "opcode": "sensing_touchingobject",
672
+ "next": null,
673
+ "parent": null,
674
+ "inputs": {
675
+ "TOUCHINGOBJECTMENU": [
676
+ 1,
677
+ "xSKW9a+wTnM~h~So8Jc]"
678
+ ]
679
+ },
680
+ "fields": {},
681
+ "shadow": false,
682
+ "topLevel": true,
683
+ "x": 359,
684
+ "y": 116
685
+ },
686
+ "sensing_touchingobjectmenu": {
687
+ "opcode": "sensing_touchingobjectmenu",
688
+ "next": null,
689
+ "parent": "Y(n,F@BYzwd4CiN|Bh[P",
690
+ "inputs": {},
691
+ "fields": {
692
+ "TOUCHINGOBJECTMENU": [
693
+ "_mouse_",
694
+ null
695
+ ]
696
+ },
697
+ "shadow": true,
698
+ "topLevel": false
699
+ },
700
+ "sensing_touchingcolor": {
701
+ "opcode": "sensing_touchingcolor",
702
+ "next": null,
703
+ "parent": null,
704
+ "inputs": {
705
+ "COLOR": [
706
+ 1,
707
+ [
708
+ 9,
709
+ "#55b888"
710
+ ]
711
+ ]
712
+ },
713
+ "fields": {},
714
+ "shadow": false,
715
+ "topLevel": true,
716
+ "x": 360,
717
+ "y": 188
718
+ },
719
+ "sensing_coloristouchingcolor": {
720
+ "opcode": "sensing_coloristouchingcolor",
721
+ "next": null,
722
+ "parent": null,
723
+ "inputs": {
724
+ "COLOR": [
725
+ 1,
726
+ [
727
+ 9,
728
+ "#d019f2"
729
+ ]
730
+ ],
731
+ "COLOR2": [
732
+ 1,
733
+ [
734
+ 9,
735
+ "#2b0de3"
736
+ ]
737
+ ]
738
+ },
739
+ "fields": {},
740
+ "shadow": false,
741
+ "topLevel": true,
742
+ "x": 348,
743
+ "y": 277
744
+ },
745
+ "sensing_askandwait": {
746
+ "opcode": "sensing_askandwait",
747
+ "next": null,
748
+ "parent": null,
749
+ "inputs": {
750
+ "QUESTION": [
751
+ 1,
752
+ [
753
+ 10,
754
+ "What's your name?"
755
+ ]
756
+ ]
757
+ },
758
+ "fields": {},
759
+ "shadow": false,
760
+ "topLevel": true,
761
+ "x": 338,
762
+ "y": 354
763
+ },
764
+ "sensing_answer": {
765
+ "opcode": "sensing_answer",
766
+ "next": null,
767
+ "parent": null,
768
+ "inputs": {},
769
+ "fields": {},
770
+ "shadow": false,
771
+ "topLevel": true,
772
+ "x": 782,
773
+ "y": 111
774
+ },
775
+ "sensing_keypressed": {
776
+ "opcode": "sensing_keypressed",
777
+ "next": null,
778
+ "parent": null,
779
+ "inputs": {
780
+ "KEY_OPTION": [
781
+ 1,
782
+ "SNlf@Im$sv%.6ULi-f3i"
783
+ ]
784
+ },
785
+ "fields": {},
786
+ "shadow": false,
787
+ "topLevel": true,
788
+ "x": 762,
789
+ "y": 207
790
+ },
791
+ "sensing_keyoptions": {
792
+ "opcode": "sensing_keyoptions",
793
+ "next": null,
794
+ "parent": "7$xEUO.2hH2R6vh!$(Uj",
795
+ "inputs": {},
796
+ "fields": {
797
+ "KEY_OPTION": [
798
+ "space",
799
+ null
800
+ ]
801
+ },
802
+ "shadow": true,
803
+ "topLevel": false
804
+ },
805
+ "sensing_mousedown": {
806
+ "opcode": "sensing_mousedown",
807
+ "next": null,
808
+ "parent": null,
809
+ "inputs": {},
810
+ "fields": {},
811
+ "shadow": false,
812
+ "topLevel": true,
813
+ "x": 822,
814
+ "y": 422
815
+ },
816
+ "sensing_mousex": {
817
+ "opcode": "sensing_mousex",
818
+ "next": null,
819
+ "parent": null,
820
+ "inputs": {},
821
+ "fields": {},
822
+ "shadow": false,
823
+ "topLevel": true,
824
+ "x": 302,
825
+ "y": 528
826
+ },
827
+ "sensing_mousey": {
828
+ "opcode": "sensing_mousey",
829
+ "next": null,
830
+ "parent": null,
831
+ "inputs": {},
832
+ "fields": {},
833
+ "shadow": false,
834
+ "topLevel": true,
835
+ "x": 668,
836
+ "y": 547
837
+ },
838
+ "sensing_setdragmode": {
839
+ "opcode": "sensing_setdragmode",
840
+ "next": null,
841
+ "parent": null,
842
+ "inputs": {},
843
+ "fields": {
844
+ "DRAG_MODE": [
845
+ "draggable",
846
+ null
847
+ ]
848
+ },
849
+ "shadow": false,
850
+ "topLevel": true,
851
+ "x": 950,
852
+ "y": 574
853
+ },
854
+ "sensing_loudness": {
855
+ "opcode": "sensing_loudness",
856
+ "next": null,
857
+ "parent": null,
858
+ "inputs": {},
859
+ "fields": {},
860
+ "shadow": false,
861
+ "topLevel": true,
862
+ "x": 658,
863
+ "y": 703
864
+ },
865
+ "sensing_timer": {
866
+ "opcode": "sensing_timer",
867
+ "next": null,
868
+ "parent": null,
869
+ "inputs": {},
870
+ "fields": {},
871
+ "shadow": false,
872
+ "topLevel": true,
873
+ "x": 459,
874
+ "y": 671
875
+ },
876
+ "sensing_resettimer": {
877
+ "opcode": "sensing_resettimer",
878
+ "next": null,
879
+ "parent": null,
880
+ "inputs": {},
881
+ "fields": {},
882
+ "shadow": false,
883
+ "topLevel": true,
884
+ "x": 462,
885
+ "y": 781
886
+ },
887
+ "sensing_of": {
888
+ "opcode": "sensing_of",
889
+ "next": null,
890
+ "parent": null,
891
+ "inputs": {
892
+ "OBJECT": [
893
+ 1,
894
+ "t+o*y;iz,!O#aT|qM_+O"
895
+ ]
896
+ },
897
+ "fields": {
898
+ "PROPERTY": [
899
+ "backdrop #",
900
+ null
901
+ ]
902
+ },
903
+ "shadow": false,
904
+ "topLevel": true,
905
+ "x": 997,
906
+ "y": 754
907
+ },
908
+ "sensing_of_object_menu": {
909
+ "opcode": "sensing_of_object_menu",
910
+ "next": null,
911
+ "parent": "[4I2wIG/tNc@LQ-;FbsB",
912
+ "inputs": {},
913
+ "fields": {
914
+ "OBJECT": [
915
+ "_stage_",
916
+ null
917
+ ]
918
+ },
919
+ "shadow": true,
920
+ "topLevel": false
921
+ },
922
+ "sensing_current": {
923
+ "opcode": "sensing_current",
924
+ "next": null,
925
+ "parent": null,
926
+ "inputs": {},
927
+ "fields": {
928
+ "CURRENTMENU": [
929
+ "YEAR",
930
+ null
931
+ ]
932
+ },
933
+ "shadow": false,
934
+ "topLevel": true,
935
+ "x": 627,
936
+ "y": 884
937
+ },
938
+ "sensing_dayssince2000": {
939
+ "opcode": "sensing_dayssince2000",
940
+ "next": null,
941
+ "parent": null,
942
+ "inputs": {},
943
+ "fields": {},
944
+ "shadow": false,
945
+ "topLevel": true,
946
+ "x": 959,
947
+ "y": 903
948
+ },
949
+ "sensing_username": {
950
+ "opcode": "sensing_username",
951
+ "next": null,
952
+ "parent": null,
953
+ "inputs": {},
954
+ "fields": {},
955
+ "shadow": false,
956
+ "topLevel": true,
957
+ "x": 833,
958
+ "y": 757
959
+ },
960
+ "operator_add": {
961
+ "opcode": "operator_add",
962
+ "next": null,
963
+ "parent": null,
964
+ "inputs": {
965
+ "NUM1": [
966
+ 1,
967
+ [
968
+ 4,
969
+ ""
970
+ ]
971
+ ],
972
+ "NUM2": [
973
+ 1,
974
+ [
975
+ 4,
976
+ ""
977
+ ]
978
+ ]
979
+ },
980
+ "fields": {},
981
+ "shadow": false,
982
+ "topLevel": true,
983
+ "x": 128,
984
+ "y": 153
985
+ },
986
+ "operator_subtract": {
987
+ "opcode": "operator_subtract",
988
+ "next": null,
989
+ "parent": null,
990
+ "inputs": {
991
+ "NUM1": [
992
+ 1,
993
+ [
994
+ 4,
995
+ ""
996
+ ]
997
+ ],
998
+ "NUM2": [
999
+ 1,
1000
+ [
1001
+ 4,
1002
+ ""
1003
+ ]
1004
+ ]
1005
+ },
1006
+ "fields": {},
1007
+ "shadow": false,
1008
+ "topLevel": true,
1009
+ "x": 134,
1010
+ "y": 214
1011
+ },
1012
+ "operator_multiply": {
1013
+ "opcode": "operator_multiply",
1014
+ "next": null,
1015
+ "parent": null,
1016
+ "inputs": {
1017
+ "NUM1": [
1018
+ 1,
1019
+ [
1020
+ 4,
1021
+ ""
1022
+ ]
1023
+ ],
1024
+ "NUM2": [
1025
+ 1,
1026
+ [
1027
+ 4,
1028
+ ""
1029
+ ]
1030
+ ]
1031
+ },
1032
+ "fields": {},
1033
+ "shadow": false,
1034
+ "topLevel": true,
1035
+ "x": 134,
1036
+ "y": 278
1037
+ },
1038
+ "operator_divide": {
1039
+ "opcode": "operator_divide",
1040
+ "next": null,
1041
+ "parent": null,
1042
+ "inputs": {
1043
+ "NUM1": [
1044
+ 1,
1045
+ [
1046
+ 4,
1047
+ ""
1048
+ ]
1049
+ ],
1050
+ "NUM2": [
1051
+ 1,
1052
+ [
1053
+ 4,
1054
+ ""
1055
+ ]
1056
+ ]
1057
+ },
1058
+ "fields": {},
1059
+ "shadow": false,
1060
+ "topLevel": true,
1061
+ "x": 138,
1062
+ "y": 359
1063
+ },
1064
+ "operator_random": {
1065
+ "opcode": "operator_random",
1066
+ "next": null,
1067
+ "parent": null,
1068
+ "inputs": {
1069
+ "FROM": [
1070
+ 1,
1071
+ [
1072
+ 4,
1073
+ "1"
1074
+ ]
1075
+ ],
1076
+ "TO": [
1077
+ 1,
1078
+ [
1079
+ 4,
1080
+ "10"
1081
+ ]
1082
+ ]
1083
+ },
1084
+ "fields": {},
1085
+ "shadow": false,
1086
+ "topLevel": true,
1087
+ "x": 311,
1088
+ "y": 157
1089
+ },
1090
+ "operator_gt": {
1091
+ "opcode": "operator_gt",
1092
+ "next": null,
1093
+ "parent": null,
1094
+ "inputs": {
1095
+ "OPERAND1": [
1096
+ 1,
1097
+ [
1098
+ 10,
1099
+ ""
1100
+ ]
1101
+ ],
1102
+ "OPERAND2": [
1103
+ 1,
1104
+ [
1105
+ 10,
1106
+ "50"
1107
+ ]
1108
+ ]
1109
+ },
1110
+ "fields": {},
1111
+ "shadow": false,
1112
+ "topLevel": true,
1113
+ "x": 348,
1114
+ "y": 217
1115
+ },
1116
+ "operator_lt": {
1117
+ "opcode": "operator_lt",
1118
+ "next": null,
1119
+ "parent": null,
1120
+ "inputs": {
1121
+ "OPERAND1": [
1122
+ 1,
1123
+ [
1124
+ 10,
1125
+ ""
1126
+ ]
1127
+ ],
1128
+ "OPERAND2": [
1129
+ 1,
1130
+ [
1131
+ 10,
1132
+ "50"
1133
+ ]
1134
+ ]
1135
+ },
1136
+ "fields": {},
1137
+ "shadow": false,
1138
+ "topLevel": true,
1139
+ "x": 345,
1140
+ "y": 286
1141
+ },
1142
+ "operator_equals": {
1143
+ "opcode": "operator_equals",
1144
+ "next": null,
1145
+ "parent": null,
1146
+ "inputs": {
1147
+ "OPERAND1": [
1148
+ 1,
1149
+ [
1150
+ 10,
1151
+ ""
1152
+ ]
1153
+ ],
1154
+ "OPERAND2": [
1155
+ 1,
1156
+ [
1157
+ 10,
1158
+ "50"
1159
+ ]
1160
+ ]
1161
+ },
1162
+ "fields": {},
1163
+ "shadow": false,
1164
+ "topLevel": true,
1165
+ "x": 345,
1166
+ "y": 372
1167
+ },
1168
+ "operator_and": {
1169
+ "opcode": "operator_and",
1170
+ "next": null,
1171
+ "parent": null,
1172
+ "inputs": {},
1173
+ "fields": {},
1174
+ "shadow": false,
1175
+ "topLevel": true,
1176
+ "x": 701,
1177
+ "y": 158
1178
+ },
1179
+ "operator_or": {
1180
+ "opcode": "operator_or",
1181
+ "next": null,
1182
+ "parent": null,
1183
+ "inputs": {},
1184
+ "fields": {},
1185
+ "shadow": false,
1186
+ "topLevel": true,
1187
+ "x": 705,
1188
+ "y": 222
1189
+ },
1190
+ "operator_not": {
1191
+ "opcode": "operator_not",
1192
+ "next": null,
1193
+ "parent": null,
1194
+ "inputs": {},
1195
+ "fields": {},
1196
+ "shadow": false,
1197
+ "topLevel": true,
1198
+ "x": 734,
1199
+ "y": 283
1200
+ },
1201
+ "operator_join": {
1202
+ "opcode": "operator_join",
1203
+ "next": null,
1204
+ "parent": null,
1205
+ "inputs": {
1206
+ "STRING1": [
1207
+ 1,
1208
+ [
1209
+ 10,
1210
+ "apple "
1211
+ ]
1212
+ ],
1213
+ "STRING2": [
1214
+ 1,
1215
+ [
1216
+ 10,
1217
+ "banana"
1218
+ ]
1219
+ ]
1220
+ },
1221
+ "fields": {},
1222
+ "shadow": false,
1223
+ "topLevel": true,
1224
+ "x": 663,
1225
+ "y": 378
1226
+ },
1227
+ "operator_letter_of": {
1228
+ "opcode": "operator_letter_of",
1229
+ "next": null,
1230
+ "parent": null,
1231
+ "inputs": {
1232
+ "LETTER": [
1233
+ 1,
1234
+ [
1235
+ 6,
1236
+ "1"
1237
+ ]
1238
+ ],
1239
+ "STRING": [
1240
+ 1,
1241
+ [
1242
+ 10,
1243
+ "apple"
1244
+ ]
1245
+ ]
1246
+ },
1247
+ "fields": {},
1248
+ "shadow": false,
1249
+ "topLevel": true,
1250
+ "x": 664,
1251
+ "y": 445
1252
+ },
1253
+ "operator_length": {
1254
+ "opcode": "operator_length",
1255
+ "next": null,
1256
+ "parent": null,
1257
+ "inputs": {
1258
+ "STRING": [
1259
+ 1,
1260
+ [
1261
+ 10,
1262
+ "apple"
1263
+ ]
1264
+ ]
1265
+ },
1266
+ "fields": {},
1267
+ "shadow": false,
1268
+ "topLevel": true,
1269
+ "x": 664,
1270
+ "y": 521
1271
+ },
1272
+ "operator_contains": {
1273
+ "opcode": "operator_contains",
1274
+ "next": null,
1275
+ "parent": null,
1276
+ "inputs": {
1277
+ "STRING1": [
1278
+ 1,
1279
+ [
1280
+ 10,
1281
+ "apple"
1282
+ ]
1283
+ ],
1284
+ "STRING2": [
1285
+ 1,
1286
+ [
1287
+ 10,
1288
+ "a"
1289
+ ]
1290
+ ]
1291
+ },
1292
+ "fields": {},
1293
+ "shadow": false,
1294
+ "topLevel": true,
1295
+ "x": 634,
1296
+ "y": 599
1297
+ },
1298
+ "operator_mod": {
1299
+ "opcode": "operator_mod",
1300
+ "next": null,
1301
+ "parent": null,
1302
+ "inputs": {
1303
+ "NUM1": [
1304
+ 1,
1305
+ [
1306
+ 4,
1307
+ ""
1308
+ ]
1309
+ ],
1310
+ "NUM2": [
1311
+ 1,
1312
+ [
1313
+ 4,
1314
+ ""
1315
+ ]
1316
+ ]
1317
+ },
1318
+ "fields": {},
1319
+ "shadow": false,
1320
+ "topLevel": true,
1321
+ "x": 295,
1322
+ "y": 594
1323
+ },
1324
+ "operator_round": {
1325
+ "opcode": "operator_round",
1326
+ "next": null,
1327
+ "parent": null,
1328
+ "inputs": {
1329
+ "NUM": [
1330
+ 1,
1331
+ [
1332
+ 4,
1333
+ ""
1334
+ ]
1335
+ ]
1336
+ },
1337
+ "fields": {},
1338
+ "shadow": false,
1339
+ "topLevel": true,
1340
+ "x": 307,
1341
+ "y": 674
1342
+ },
1343
+ "operator_mathop": {
1344
+ "opcode": "operator_mathop",
1345
+ "next": null,
1346
+ "parent": null,
1347
+ "inputs": {
1348
+ "NUM": [
1349
+ 1,
1350
+ [
1351
+ 4,
1352
+ ""
1353
+ ]
1354
+ ]
1355
+ },
1356
+ "fields": {
1357
+ "OPERATOR": [
1358
+ "abs",
1359
+ null
1360
+ ]
1361
+ },
1362
+ "shadow": false,
1363
+ "topLevel": true,
1364
+ "x": 280,
1365
+ "y": 754
1366
+ },
1367
+ "data_setvariableto": {
1368
+ "opcode": "data_setvariableto",
1369
+ "next": null,
1370
+ "parent": null,
1371
+ "inputs": {
1372
+ "VALUE": [
1373
+ 1,
1374
+ [
1375
+ 10,
1376
+ "0"
1377
+ ]
1378
+ ]
1379
+ },
1380
+ "fields": {
1381
+ "VARIABLE": [
1382
+ "my variable",
1383
+ "`jEk@4|i[#Fk?(8x)AV.-my variable"
1384
+ ]
1385
+ },
1386
+ "shadow": false,
1387
+ "topLevel": true,
1388
+ "x": 348,
1389
+ "y": 241
1390
+ },
1391
+ "data_changevariableby": {
1392
+ "opcode": "data_changevariableby",
1393
+ "next": null,
1394
+ "parent": null,
1395
+ "inputs": {
1396
+ "VALUE": [
1397
+ 1,
1398
+ [
1399
+ 4,
1400
+ "1"
1401
+ ]
1402
+ ]
1403
+ },
1404
+ "fields": {
1405
+ "VARIABLE": [
1406
+ "my variable",
1407
+ "`jEk@4|i[#Fk?(8x)AV.-my variable"
1408
+ ]
1409
+ },
1410
+ "shadow": false,
1411
+ "topLevel": true,
1412
+ "x": 313,
1413
+ "y": 363
1414
+ },
1415
+ "data_showvariable": {
1416
+ "opcode": "data_showvariable",
1417
+ "next": null,
1418
+ "parent": null,
1419
+ "inputs": {},
1420
+ "fields": {
1421
+ "VARIABLE": [
1422
+ "my variable",
1423
+ "`jEk@4|i[#Fk?(8x)AV.-my variable"
1424
+ ]
1425
+ },
1426
+ "shadow": false,
1427
+ "topLevel": true,
1428
+ "x": 415,
1429
+ "y": 473
1430
+ },
1431
+ "data_hidevariable": {
1432
+ "opcode": "data_hidevariable",
1433
+ "next": null,
1434
+ "parent": null,
1435
+ "inputs": {},
1436
+ "fields": {
1437
+ "VARIABLE": [
1438
+ "my variable",
1439
+ "`jEk@4|i[#Fk?(8x)AV.-my variable"
1440
+ ]
1441
+ },
1442
+ "shadow": false,
1443
+ "topLevel": true,
1444
+ "x": 319,
1445
+ "y": 587
1446
+ },
1447
+ "data_addtolist": {
1448
+ "opcode": "data_addtolist",
1449
+ "next": null,
1450
+ "parent": null,
1451
+ "inputs": {
1452
+ "ITEM": [
1453
+ 1,
1454
+ [
1455
+ 10,
1456
+ "thing"
1457
+ ]
1458
+ ]
1459
+ },
1460
+ "fields": {
1461
+ "LIST": [
1462
+ "MY_LIST",
1463
+ "o6`kIhtT{xWH+rX(5d,A"
1464
+ ]
1465
+ },
1466
+ "shadow": false,
1467
+ "topLevel": true,
1468
+ "x": 385,
1469
+ "y": 109
1470
+ },
1471
+ "data_deleteoflist": {
1472
+ "opcode": "data_deleteoflist",
1473
+ "next": null,
1474
+ "parent": null,
1475
+ "inputs": {
1476
+ "INDEX": [
1477
+ 1,
1478
+ [
1479
+ 7,
1480
+ "1"
1481
+ ]
1482
+ ]
1483
+ },
1484
+ "fields": {
1485
+ "LIST": [
1486
+ "MY_LIST",
1487
+ "o6`kIhtT{xWH+rX(5d,A"
1488
+ ]
1489
+ },
1490
+ "shadow": false,
1491
+ "topLevel": true,
1492
+ "x": 384,
1493
+ "y": 244
1494
+ },
1495
+ "data_deletealloflist": {
1496
+ "opcode": "data_deletealloflist",
1497
+ "next": null,
1498
+ "parent": null,
1499
+ "inputs": {},
1500
+ "fields": {
1501
+ "LIST": [
1502
+ "MY_LIST",
1503
+ "o6`kIhtT{xWH+rX(5d,A"
1504
+ ]
1505
+ },
1506
+ "shadow": false,
1507
+ "topLevel": true,
1508
+ "x": 387,
1509
+ "y": 374
1510
+ },
1511
+ "data_insertatlist": {
1512
+ "opcode": "data_insertatlist",
1513
+ "next": null,
1514
+ "parent": null,
1515
+ "inputs": {
1516
+ "ITEM": [
1517
+ 1,
1518
+ [
1519
+ 10,
1520
+ "thing"
1521
+ ]
1522
+ ],
1523
+ "INDEX": [
1524
+ 1,
1525
+ [
1526
+ 7,
1527
+ "1"
1528
+ ]
1529
+ ]
1530
+ },
1531
+ "fields": {
1532
+ "LIST": [
1533
+ "MY_LIST",
1534
+ "o6`kIhtT{xWH+rX(5d,A"
1535
+ ]
1536
+ },
1537
+ "shadow": false,
1538
+ "topLevel": true,
1539
+ "x": 366,
1540
+ "y": 527
1541
+ },
1542
+ "data_replaceitemoflist": {
1543
+ "opcode": "data_replaceitemoflist",
1544
+ "next": null,
1545
+ "parent": null,
1546
+ "inputs": {
1547
+ "INDEX": [
1548
+ 1,
1549
+ [
1550
+ 7,
1551
+ "1"
1552
+ ]
1553
+ ],
1554
+ "ITEM": [
1555
+ 1,
1556
+ [
1557
+ 10,
1558
+ "thing"
1559
+ ]
1560
+ ]
1561
+ },
1562
+ "fields": {
1563
+ "LIST": [
1564
+ "MY_LIST",
1565
+ "o6`kIhtT{xWH+rX(5d,A"
1566
+ ]
1567
+ },
1568
+ "shadow": false,
1569
+ "topLevel": true,
1570
+ "x": 365,
1571
+ "y": 657
1572
+ },
1573
+ "data_itemoflist": {
1574
+ "opcode": "data_itemoflist",
1575
+ "next": null,
1576
+ "parent": null,
1577
+ "inputs": {
1578
+ "INDEX": [
1579
+ 1,
1580
+ [
1581
+ 7,
1582
+ "1"
1583
+ ]
1584
+ ]
1585
+ },
1586
+ "fields": {
1587
+ "LIST": [
1588
+ "MY_LIST",
1589
+ "o6`kIhtT{xWH+rX(5d,A"
1590
+ ]
1591
+ },
1592
+ "shadow": false,
1593
+ "topLevel": true,
1594
+ "x": 862,
1595
+ "y": 117
1596
+ },
1597
+ "data_itemnumoflist": {
1598
+ "opcode": "data_itemnumoflist",
1599
+ "next": null,
1600
+ "parent": null,
1601
+ "inputs": {
1602
+ "ITEM": [
1603
+ 1,
1604
+ [
1605
+ 10,
1606
+ "thing"
1607
+ ]
1608
+ ]
1609
+ },
1610
+ "fields": {
1611
+ "LIST": [
1612
+ "MY_LIST",
1613
+ "o6`kIhtT{xWH+rX(5d,A"
1614
+ ]
1615
+ },
1616
+ "shadow": false,
1617
+ "topLevel": true,
1618
+ "x": 883,
1619
+ "y": 238
1620
+ },
1621
+ "data_lengthoflist": {
1622
+ "opcode": "data_lengthoflist",
1623
+ "next": null,
1624
+ "parent": null,
1625
+ "inputs": {},
1626
+ "fields": {
1627
+ "LIST": [
1628
+ "MY_LIST",
1629
+ "o6`kIhtT{xWH+rX(5d,A"
1630
+ ]
1631
+ },
1632
+ "shadow": false,
1633
+ "topLevel": true,
1634
+ "x": 876,
1635
+ "y": 342
1636
+ },
1637
+ "data_listcontainsitem": {
1638
+ "opcode": "data_listcontainsitem",
1639
+ "next": null,
1640
+ "parent": null,
1641
+ "inputs": {
1642
+ "ITEM": [
1643
+ 1,
1644
+ [
1645
+ 10,
1646
+ "thing"
1647
+ ]
1648
+ ]
1649
+ },
1650
+ "fields": {
1651
+ "LIST": [
1652
+ "MY_LIST",
1653
+ "o6`kIhtT{xWH+rX(5d,A"
1654
+ ]
1655
+ },
1656
+ "shadow": false,
1657
+ "topLevel": true,
1658
+ "x": 871,
1659
+ "y": 463
1660
+ },
1661
+ "data_showlist": {
1662
+ "opcode": "data_showlist",
1663
+ "next": null,
1664
+ "parent": null,
1665
+ "inputs": {},
1666
+ "fields": {
1667
+ "LIST": [
1668
+ "MY_LIST",
1669
+ "o6`kIhtT{xWH+rX(5d,A"
1670
+ ]
1671
+ },
1672
+ "shadow": false,
1673
+ "topLevel": true,
1674
+ "x": 931,
1675
+ "y": 563
1676
+ },
1677
+ "data_hidelist": {
1678
+ "opcode": "data_hidelist",
1679
+ "next": null,
1680
+ "parent": null,
1681
+ "inputs": {},
1682
+ "fields": {
1683
+ "LIST": [
1684
+ "MY_LIST",
1685
+ "o6`kIhtT{xWH+rX(5d,A"
1686
+ ]
1687
+ },
1688
+ "shadow": false,
1689
+ "topLevel": true,
1690
+ "x": 962,
1691
+ "y": 716
1692
+ },
1693
+ "sound_playuntildone": {
1694
+ "opcode": "sound_playuntildone",
1695
+ "next": null,
1696
+ "parent": null,
1697
+ "inputs": {
1698
+ "SOUND_MENU": [
1699
+ 1,
1700
+ "4w%pR8G.yD%g-BwCj=uK"
1701
+ ]
1702
+ },
1703
+ "fields": {},
1704
+ "shadow": false,
1705
+ "topLevel": true,
1706
+ "x": 253,
1707
+ "y": 17
1708
+ },
1709
+ "sound_sounds_menu": {
1710
+ "opcode": "sound_sounds_menu",
1711
+ "next": null,
1712
+ "parent": "Pdc$U;s8e_uUfTX`}jOo",
1713
+ "inputs": {},
1714
+ "fields": {
1715
+ "SOUND_MENU": [
1716
+ "Meow",
1717
+ null
1718
+ ]
1719
+ },
1720
+ "shadow": true,
1721
+ "topLevel": false
1722
+ },
1723
+ "sound_play": {
1724
+ "opcode": "sound_play",
1725
+ "next": null,
1726
+ "parent": null,
1727
+ "inputs": {
1728
+ "SOUND_MENU": [
1729
+ 1,
1730
+ "i1U{^VHb*2`9?l}=:L)/"
1731
+ ]
1732
+ },
1733
+ "fields": {},
1734
+ "shadow": false,
1735
+ "topLevel": true,
1736
+ "x": 245,
1737
+ "y": 122
1738
+ },
1739
+ "sound_stopallsounds": {
1740
+ "opcode": "sound_stopallsounds",
1741
+ "next": null,
1742
+ "parent": null,
1743
+ "inputs": {},
1744
+ "fields": {},
1745
+ "shadow": false,
1746
+ "topLevel": true,
1747
+ "x": 253,
1748
+ "y": 245
1749
+ },
1750
+ "sound_changeeffectby": {
1751
+ "opcode": "sound_changeeffectby",
1752
+ "next": null,
1753
+ "parent": null,
1754
+ "inputs": {
1755
+ "VALUE": [
1756
+ 1,
1757
+ [
1758
+ 4,
1759
+ "10"
1760
+ ]
1761
+ ]
1762
+ },
1763
+ "fields": {
1764
+ "EFFECT": [
1765
+ "PITCH",
1766
+ null
1767
+ ]
1768
+ },
1769
+ "shadow": false,
1770
+ "topLevel": true,
1771
+ "x": 653,
1772
+ "y": 14
1773
+ },
1774
+ "sound_seteffectto": {
1775
+ "opcode": "sound_seteffectto",
1776
+ "next": null,
1777
+ "parent": null,
1778
+ "inputs": {
1779
+ "VALUE": [
1780
+ 1,
1781
+ [
1782
+ 4,
1783
+ "100"
1784
+ ]
1785
+ ]
1786
+ },
1787
+ "fields": {
1788
+ "EFFECT": [
1789
+ "PITCH",
1790
+ null
1791
+ ]
1792
+ },
1793
+ "shadow": false,
1794
+ "topLevel": true,
1795
+ "x": 653,
1796
+ "y": 139
1797
+ },
1798
+ "sound_cleareffects": {
1799
+ "opcode": "sound_cleareffects",
1800
+ "next": null,
1801
+ "parent": null,
1802
+ "inputs": {},
1803
+ "fields": {},
1804
+ "shadow": false,
1805
+ "topLevel": true,
1806
+ "x": 651,
1807
+ "y": 242
1808
+ },
1809
+ "sound_changevolumeby": {
1810
+ "opcode": "sound_changevolumeby",
1811
+ "next": null,
1812
+ "parent": null,
1813
+ "inputs": {
1814
+ "VOLUME": [
1815
+ 1,
1816
+ [
1817
+ 4,
1818
+ "-10"
1819
+ ]
1820
+ ]
1821
+ },
1822
+ "fields": {},
1823
+ "shadow": false,
1824
+ "topLevel": true,
1825
+ "x": 645,
1826
+ "y": 353
1827
+ },
1828
+ "sound_setvolumeto": {
1829
+ "opcode": "sound_setvolumeto",
1830
+ "next": null,
1831
+ "parent": null,
1832
+ "inputs": {
1833
+ "VOLUME": [
1834
+ 1,
1835
+ [
1836
+ 4,
1837
+ "100"
1838
+ ]
1839
+ ]
1840
+ },
1841
+ "fields": {},
1842
+ "shadow": false,
1843
+ "topLevel": true,
1844
+ "x": 1108,
1845
+ "y": 5
1846
+ },
1847
+ "sound_volume": {
1848
+ "opcode": "sound_volume",
1849
+ "next": null,
1850
+ "parent": null,
1851
+ "inputs": {},
1852
+ "fields": {},
1853
+ "shadow": false,
1854
+ "topLevel": true,
1855
+ "x": 1136,
1856
+ "y": 123
1857
+ },
1858
+ "looks_sayforsecs": {
1859
+ "opcode": "looks_sayforsecs",
1860
+ "next": null,
1861
+ "parent": null,
1862
+ "inputs": {
1863
+ "MESSAGE": [
1864
+ 1,
1865
+ [
1866
+ 10,
1867
+ "Hello!"
1868
+ ]
1869
+ ],
1870
+ "SECS": [
1871
+ 1,
1872
+ [
1873
+ 4,
1874
+ "2"
1875
+ ]
1876
+ ]
1877
+ },
1878
+ "fields": {},
1879
+ "shadow": false,
1880
+ "topLevel": true,
1881
+ "x": 408,
1882
+ "y": 91
1883
+ },
1884
+ "looks_say": {
1885
+ "opcode": "looks_say",
1886
+ "next": null,
1887
+ "parent": null,
1888
+ "inputs": {
1889
+ "MESSAGE": [
1890
+ 1,
1891
+ [
1892
+ 10,
1893
+ "Hello!"
1894
+ ]
1895
+ ]
1896
+ },
1897
+ "fields": {},
1898
+ "shadow": false,
1899
+ "topLevel": true,
1900
+ "x": 413,
1901
+ "y": 213
1902
+ },
1903
+ "looks_thinkforsecs": {
1904
+ "opcode": "looks_thinkforsecs",
1905
+ "next": null,
1906
+ "parent": null,
1907
+ "inputs": {
1908
+ "MESSAGE": [
1909
+ 1,
1910
+ [
1911
+ 10,
1912
+ "Hmm..."
1913
+ ]
1914
+ ],
1915
+ "SECS": [
1916
+ 1,
1917
+ [
1918
+ 4,
1919
+ "2"
1920
+ ]
1921
+ ]
1922
+ },
1923
+ "fields": {},
1924
+ "shadow": false,
1925
+ "topLevel": true,
1926
+ "x": 413,
1927
+ "y": 317
1928
+ },
1929
+ "looks_think": {
1930
+ "opcode": "looks_think",
1931
+ "next": null,
1932
+ "parent": null,
1933
+ "inputs": {
1934
+ "MESSAGE": [
1935
+ 1,
1936
+ [
1937
+ 10,
1938
+ "Hmm..."
1939
+ ]
1940
+ ]
1941
+ },
1942
+ "fields": {},
1943
+ "shadow": false,
1944
+ "topLevel": true,
1945
+ "x": 412,
1946
+ "y": 432
1947
+ },
1948
+ "looks_switchcostumeto": {
1949
+ "opcode": "looks_switchcostumeto",
1950
+ "next": null,
1951
+ "parent": null,
1952
+ "inputs": {
1953
+ "COSTUME": [
1954
+ 1,
1955
+ "8;bti4wv(iH9nkOacCJ|"
1956
+ ]
1957
+ },
1958
+ "fields": {},
1959
+ "shadow": false,
1960
+ "topLevel": true,
1961
+ "x": 411,
1962
+ "y": 555
1963
+ },
1964
+ "looks_costume": {
1965
+ "opcode": "looks_costume",
1966
+ "next": null,
1967
+ "parent": "Q#a,6LPWHqo9-0Nu*[SV",
1968
+ "inputs": {},
1969
+ "fields": {
1970
+ "COSTUME": [
1971
+ "costume2",
1972
+ null
1973
+ ]
1974
+ },
1975
+ "shadow": true,
1976
+ "topLevel": false
1977
+ },
1978
+ "looks_nextcostume": {
1979
+ "opcode": "looks_nextcostume",
1980
+ "next": null,
1981
+ "parent": null,
1982
+ "inputs": {},
1983
+ "fields": {},
1984
+ "shadow": false,
1985
+ "topLevel": true,
1986
+ "x": 419,
1987
+ "y": 687
1988
+ },
1989
+ "looks_switchbackdropto": {
1990
+ "opcode": "looks_switchbackdropto",
1991
+ "next": null,
1992
+ "parent": null,
1993
+ "inputs": {
1994
+ "BACKDROP": [
1995
+ 1,
1996
+ "-?yeX}29V*wd6W:unW0i"
1997
+ ]
1998
+ },
1999
+ "fields": {},
2000
+ "shadow": false,
2001
+ "topLevel": true,
2002
+ "x": 901,
2003
+ "y": 91
2004
+ },
2005
+ "looks_backdrops": {
2006
+ "opcode": "looks_backdrops",
2007
+ "next": null,
2008
+ "parent": "`Wm^p~l[(IWzc1|wNv*.",
2009
+ "inputs": {},
2010
+ "fields": {
2011
+ "BACKDROP": [
2012
+ "backdrop1",
2013
+ null
2014
+ ]
2015
+ },
2016
+ "shadow": true,
2017
+ "topLevel": false
2018
+ },
2019
+ "looks_changesizeby": {
2020
+ "opcode": "looks_changesizeby",
2021
+ "next": null,
2022
+ "parent": null,
2023
+ "inputs": {
2024
+ "CHANGE": [
2025
+ 1,
2026
+ [
2027
+ 4,
2028
+ "10"
2029
+ ]
2030
+ ]
2031
+ },
2032
+ "fields": {},
2033
+ "shadow": false,
2034
+ "topLevel": true,
2035
+ "x": 895,
2036
+ "y": 192
2037
+ },
2038
+ "looks_setsizeto": {
2039
+ "opcode": "looks_setsizeto",
2040
+ "next": null,
2041
+ "parent": null,
2042
+ "inputs": {
2043
+ "SIZE": [
2044
+ 1,
2045
+ [
2046
+ 4,
2047
+ "100"
2048
+ ]
2049
+ ]
2050
+ },
2051
+ "fields": {},
2052
+ "shadow": false,
2053
+ "topLevel": true,
2054
+ "x": 896,
2055
+ "y": 303
2056
+ },
2057
+ "looks_changeeffectby": {
2058
+ "opcode": "looks_changeeffectby",
2059
+ "next": null,
2060
+ "parent": null,
2061
+ "inputs": {
2062
+ "CHANGE": [
2063
+ 1,
2064
+ [
2065
+ 4,
2066
+ "25"
2067
+ ]
2068
+ ]
2069
+ },
2070
+ "fields": {
2071
+ "EFFECT": [
2072
+ "COLOR",
2073
+ null
2074
+ ]
2075
+ },
2076
+ "shadow": false,
2077
+ "topLevel": true,
2078
+ "x": 892,
2079
+ "y": 416
2080
+ },
2081
+ "looks_seteffectto": {
2082
+ "opcode": "looks_seteffectto",
2083
+ "next": null,
2084
+ "parent": null,
2085
+ "inputs": {
2086
+ "VALUE": [
2087
+ 1,
2088
+ [
2089
+ 4,
2090
+ "0"
2091
+ ]
2092
+ ]
2093
+ },
2094
+ "fields": {
2095
+ "EFFECT": [
2096
+ "COLOR",
2097
+ null
2098
+ ]
2099
+ },
2100
+ "shadow": false,
2101
+ "topLevel": true,
2102
+ "x": 902,
2103
+ "y": 527
2104
+ },
2105
+ "looks_cleargraphiceffects": {
2106
+ "opcode": "looks_cleargraphiceffects",
2107
+ "next": null,
2108
+ "parent": null,
2109
+ "inputs": {},
2110
+ "fields": {},
2111
+ "shadow": false,
2112
+ "topLevel": true,
2113
+ "x": 902,
2114
+ "y": 638
2115
+ },
2116
+ "looks_show": {
2117
+ "opcode": "looks_show",
2118
+ "next": null,
2119
+ "parent": null,
2120
+ "inputs": {},
2121
+ "fields": {},
2122
+ "shadow": false,
2123
+ "topLevel": true,
2124
+ "x": 908,
2125
+ "y": 758
2126
+ },
2127
+ "looks_hide": {
2128
+ "opcode": "looks_hide",
2129
+ "next": null,
2130
+ "parent": null,
2131
+ "inputs": {},
2132
+ "fields": {},
2133
+ "shadow": false,
2134
+ "topLevel": true,
2135
+ "x": 455,
2136
+ "y": 861
2137
+ },
2138
+ "looks_gotofrontback": {
2139
+ "opcode": "looks_gotofrontback",
2140
+ "next": null,
2141
+ "parent": null,
2142
+ "inputs": {},
2143
+ "fields": {
2144
+ "FRONT_BACK": [
2145
+ "front",
2146
+ null
2147
+ ]
2148
+ },
2149
+ "shadow": false,
2150
+ "topLevel": true,
2151
+ "x": 853,
2152
+ "y": 878
2153
+ },
2154
+ "looks_goforwardbackwardlayers": {
2155
+ "opcode": "looks_goforwardbackwardlayers",
2156
+ "next": null,
2157
+ "parent": null,
2158
+ "inputs": {
2159
+ "NUM": [
2160
+ 1,
2161
+ [
2162
+ 7,
2163
+ "1"
2164
+ ]
2165
+ ]
2166
+ },
2167
+ "fields": {
2168
+ "FORWARD_BACKWARD": [
2169
+ "forward",
2170
+ null
2171
+ ]
2172
+ },
2173
+ "shadow": false,
2174
+ "topLevel": true,
2175
+ "x": 851,
2176
+ "y": 999
2177
+ },
2178
+ "looks_costumenumbername": {
2179
+ "opcode": "looks_costumenumbername",
2180
+ "next": null,
2181
+ "parent": null,
2182
+ "inputs": {},
2183
+ "fields": {
2184
+ "NUMBER_NAME": [
2185
+ "number",
2186
+ null
2187
+ ]
2188
+ },
2189
+ "shadow": false,
2190
+ "topLevel": true,
2191
+ "x": 458,
2192
+ "y": 1007
2193
+ },
2194
+ "looks_backdropnumbername": {
2195
+ "opcode": "looks_backdropnumbername",
2196
+ "next": null,
2197
+ "parent": null,
2198
+ "inputs": {},
2199
+ "fields": {
2200
+ "NUMBER_NAME": [
2201
+ "number",
2202
+ null
2203
+ ]
2204
+ },
2205
+ "shadow": false,
2206
+ "topLevel": true,
2207
+ "x": 1242,
2208
+ "y": 753
2209
+ },
2210
+ "looks_size": {
2211
+ "opcode": "looks_size",
2212
+ "next": null,
2213
+ "parent": null,
2214
+ "inputs": {},
2215
+ "fields": {},
2216
+ "shadow": false,
2217
+ "topLevel": true,
2218
+ "x": 1249,
2219
+ "y": 876
2220
+ }
2221
+ }
v2/scratch_agent/blocks_v1/boolean_blocks.json ADDED
@@ -0,0 +1,277 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "block_category": "Boolean Blocks",
3
+ "description": "Boolean blocks are hexagonal in shape. They represent conditions that evaluate to either 'true' or 'false' and are typically used as inputs for control flow blocks.",
4
+ "blocks": [
5
+ {
6
+ "block_name": "<() < ()>",
7
+ "block_type": "operator",
8
+ "op_code": "operator_lt",
9
+ "block_shape": "Boolean Block",
10
+ "functionality": "Checks if the first value is less than the second.",
11
+ "inputs": [
12
+ {"name": "OPERAND1", "type": "any"},
13
+ {"name": "OPERAND2", "type": "any"}
14
+ ],
15
+ "example_standalone": "<(score) < (10)>",
16
+ "example_with_other_blocks": [
17
+ {
18
+ "script": "if <(score) < (10)> then\n say [Keep trying!]",
19
+ "explanation": "This script causes the sprite to say 'Keep trying!' if the 'score' variable is less than 10."
20
+ }
21
+ ]
22
+ },
23
+ {
24
+ "block_name": "<() = ()>",
25
+ "block_type": "operator",
26
+ "op_code": "operator_equals",
27
+ "block_shape": "Boolean Block",
28
+ "functionality": "Checks if two values are equal.",
29
+ "inputs": [
30
+ {"name": "OPERAND1", "type": "any"},
31
+ {"name": "OPERAND2", "type": "any"}
32
+ ],
33
+ "example_standalone": "<(answer) = (5)>",
34
+ "example_with_other_blocks": [
35
+ {
36
+ "script": "if <(answer) = (5)> then\n say [Correct!]",
37
+ "explanation": "This script makes the sprite say 'Correct!' if the value of the 'answer' variable is exactly 5."
38
+ }
39
+ ]
40
+ },
41
+ {
42
+ "block_name": "<() > ()>",
43
+ "block_type": "operator",
44
+ "op_code": "operator_gt",
45
+ "block_shape": "Boolean Block",
46
+ "functionality": "Checks if the first value is greater than the second.",
47
+ "inputs": [
48
+ {"name": "OPERAND1", "type": "any"},
49
+ {"name": "OPERAND2", "type": "any"}
50
+ ],
51
+ "example_standalone": "<(health) > (0)>",
52
+ "example_with_other_blocks": [
53
+ {
54
+ "script": "if <(health) > (0)> then\n move (10) steps\nelse\n stop [all v]\nend",
55
+ "explanation": "This script moves the sprite if its 'health' is greater than 0; otherwise, it stops all scripts."
56
+ }
57
+ ]
58
+ },
59
+ {
60
+ "block_name": "<<> and <>>",
61
+ "block_type": "operator",
62
+ "op_code": "operator_and",
63
+ "block_shape": "Boolean Block",
64
+ "functionality": "Returns 'true' if both provided Boolean conditions are 'true'.",
65
+ "inputs": [
66
+ {"name": "OPERAND1", "type": "boolean"},
67
+ {"name": "OPERAND2", "type": "boolean"}
68
+ ],
69
+ "example_standalone": "<<mouse down?> and <touching [mouse-pointer]?> >",
70
+ "example_with_other_blocks": [
71
+ {
72
+ "script": "if <<mouse down?> and <touching [mouse-pointer]?> > then\n say [You're clicking me!]\nend",
73
+ "explanation": "This script makes the sprite say 'You're clicking me!' only if the mouse button is pressed AND the mouse pointer is touching the sprite."
74
+ }
75
+ ]
76
+ },
77
+ {
78
+ "block_name": "<<> or <>>",
79
+ "block_type": "operator",
80
+ "op_code": "operator_or",
81
+ "block_shape": "Boolean Block",
82
+ "functionality": "Returns 'true' if at least one of the provided Boolean conditions is 'true'.",
83
+ "inputs": [
84
+ {"name": "OPERAND1", "type": "boolean"},
85
+ {"name": "OPERAND2", "type": "boolean"}
86
+ ],
87
+ "example_standalone": "<<key [left arrow v] pressed?> or <key [a v] pressed?>>",
88
+ "example_with_other_blocks": [
89
+ {
90
+ "script": "if <<key [left arrow v] pressed?> or <key [a v] pressed?>> then\n change x by (-10)\nend",
91
+ "explanation": "This script moves the sprite left if either the left arrow key OR the 'a' key is pressed."
92
+ }
93
+ ]
94
+ },
95
+ {
96
+ "block_name": "<not <>>",
97
+ "block_type": "operator",
98
+ "op_code": "operator_not",
99
+ "block_shape": "Boolean Block",
100
+ "functionality": "Returns 'true' if the provided Boolean condition is 'false', and 'false' if it is 'true'.",
101
+ "inputs": [
102
+ {"name": "OPERAND", "type": "boolean"}
103
+ ],
104
+ "example_standalone": "<not <mouse down?>>",
105
+ "example_with_other_blocks": [
106
+ {
107
+ "script": "if <not <touching [Sprite2 v]?>> then\n say [I'm safe!]\nend",
108
+ "explanation": "This script makes the sprite say 'I'm safe!' if it is NOT touching 'Sprite2'."
109
+ }
110
+ ]
111
+ },
112
+ {
113
+ "block_name": "<() contains ()?>",
114
+ "block_type": "operator",
115
+ "op_code": "operator_contains",
116
+ "block_shape": "Boolean Block",
117
+ "functionality": "Checks if one string contains another string.",
118
+ "inputs": [
119
+ {"name": "STRING1", "type": "string"},
120
+ {"name": "STRING2", "type": "string"}
121
+ ],
122
+ "example_standalone": "<[apple] contains [a]?>",
123
+ "example_with_other_blocks": [
124
+ {
125
+ "script": "if <[answer] contains [yes]?> then\n say [Great!]\nend",
126
+ "explanation": "This script makes the sprite say 'Great!' if the 'answer' variable contains the substring 'yes'."
127
+ }
128
+ ]
129
+ },
130
+ {
131
+ "block_name": "<touching ()?>",
132
+ "block_type": "Sensing",
133
+ "op_code": "sensing_touchingobject",
134
+ "block_shape": "Boolean Block",
135
+ "functionality": "Checks if its sprite is touching the mouse-pointer, edge, or another specified sprite.",
136
+ "inputs": [
137
+ {"name": "TOUCHINGOBJECTMENU", "type": "dropdown", "options": ["mouse-pointer", "edge", "Sprite1", "..." ]}
138
+ ],
139
+ "example_standalone": "<touching [edge v]?>",
140
+ "example_with_other_blocks": [
141
+ {
142
+ "script": "if <touching [edge v]?> then\n bounce off edge\nend",
143
+ "explanation": "This script makes the sprite reverse direction if it comes into contact with the edge of the stage."
144
+ }
145
+ ]
146
+ },
147
+ {
148
+ "block_name": "<touching color ()?>",
149
+ "block_type": "Sensing",
150
+ "op_code": "sensing_touchingcolor",
151
+ "block_shape": "Boolean Block",
152
+ "functionality": "Checks whether its sprite is touching a specified color.",
153
+ "inputs": [
154
+ {"name": "COLOR", "type": "color"}
155
+ ],
156
+ "example_standalone": "<touching color [#FF0000]?>",
157
+ "example_with_other_blocks": [
158
+ {
159
+ "script": "if <touching color [#FF0000]?> then\n change [health v] by (-1)\nend",
160
+ "explanation": "This script decreases the 'health' variable by 1 if the sprite touches any red color on the stage."
161
+ }
162
+ ]
163
+ },
164
+ {
165
+ "block_name": "<color () is touching ()?>",
166
+ "block_type": "Sensing",
167
+ "op_code": "sensing_coloristouchingcolor",
168
+ "block_shape": "Boolean Block",
169
+ "functionality": "Checks whether a specific color on its sprite is touching another specified color on the stage or another sprite.",
170
+ "inputs": [
171
+ {"name": "COLOR1", "type": "color"},
172
+ {"name": "COLOR2", "type": "color"}
173
+ ],
174
+ "example_standalone": "<color [#00FF00] is touching [#FF0000]?>",
175
+ "example_with_other_blocks": [
176
+ {
177
+ "script": "if <color [#00FF00] is touching [#FF0000]?> then\n say [Collision!]\nend",
178
+ "explanation": "This script makes the sprite say 'Collision!' if a green part of the sprite touches a red color elsewhere in the project."
179
+ }
180
+ ]
181
+ },
182
+ {
183
+ "block_name": "<key () pressed?>",
184
+ "block_type": "Sensing",
185
+ "op_code": "sensing_keypressed",
186
+ "block_shape": "Boolean Block",
187
+ "functionality": "Checks if a specified keyboard key is currently being pressed.",
188
+ "inputs": [
189
+ {"name": "KEY_OPTION", "type": "dropdown",
190
+ "options": [
191
+ "space",
192
+ "up arrow",
193
+ "down arrow",
194
+ "right arrow",
195
+ "left arrow",
196
+ "any",
197
+ "a",
198
+ "b",
199
+ "c",
200
+ "d",
201
+ "e",
202
+ "f",
203
+ "g",
204
+ "h",
205
+ "i",
206
+ "j",
207
+ "k",
208
+ "l",
209
+ "m",
210
+ "n",
211
+ "o",
212
+ "p",
213
+ "q",
214
+ "r",
215
+ "s",
216
+ "t",
217
+ "u",
218
+ "v",
219
+ "w",
220
+ "x",
221
+ "y",
222
+ "z",
223
+ "0",
224
+ "1",
225
+ "2",
226
+ "3",
227
+ "4",
228
+ "5",
229
+ "6",
230
+ "7",
231
+ "8",
232
+ "9"
233
+ ]}
234
+ ],
235
+ "example_standalone": "<key [space v] pressed?>",
236
+ "example_with_other_blocks": [
237
+ {
238
+ "script": "forever\n if <key [space v] pressed?> then\n broadcast [shoot v]\n end\nend",
239
+ "explanation": "This script continuously checks if the space key is pressed and, if so, sends a 'shoot' broadcast."
240
+ }
241
+ ]
242
+ },
243
+ {
244
+ "block_name": "<mouse down?>",
245
+ "block_type": "Sensing",
246
+ "op_code": "sensing_mousedown",
247
+ "block_shape": "Boolean Block",
248
+ "functionality": "Checks if the computer mouse's primary button is being clicked while the cursor is over the stage.",
249
+ "inputs": null,
250
+ "example_standalone": "<mouse down?>",
251
+ "example_with_other_blocks": [
252
+ {
253
+ "script": "if <mouse down?> then\n go to mouse-pointer\nend",
254
+ "explanation": "This script makes the sprite follow the mouse pointer only when the mouse button is held down."
255
+ }
256
+ ]
257
+ },
258
+ {
259
+ "block_name": "<[my list v] contains ()?>",
260
+ "block_type": "Data",
261
+ "op_code": "data_listcontainsitem",
262
+ "block_shape": "Boolean Block",
263
+ "functionality": "Checks if a list includes a specific item.",
264
+ "inputs": [
265
+ {"name": "LIST", "type": "dropdown"},
266
+ {"name": "ITEM", "type": "any"}
267
+ ],
268
+ "example_standalone": "<[inventory v] contains [key]?>",
269
+ "example_with_other_blocks": [
270
+ {
271
+ "script": "if <[inventory v] contains [key]?> then\n say [You have the key!]\nend",
272
+ "explanation": "This script makes the sprite say 'You have the key!' if the 'inventory' list contains the item 'key'."
273
+ }
274
+ ]
275
+ }
276
+ ]
277
+ }
v2/scratch_agent/blocks_v1/c_blocks.json ADDED
@@ -0,0 +1,105 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "block_category": "C Blocks",
3
+ "description": "C blocks are shaped like the letter 'C'. They are used to loop or conditionally execute blocks that are placed within their opening, managing the flow of scripts.",
4
+ "blocks": [
5
+ {
6
+ "block_name": "repeat ()",
7
+ "block_type": "Control",
8
+ "block_shape": "C-Block",
9
+ "op_code": "control_repeat",
10
+ "functionality": "Repeats the blocks inside it a specified number of times.",
11
+ "inputs": [
12
+ {
13
+ "name": "times",
14
+ "type": "number"
15
+ }
16
+ ],
17
+ "example_standalone": "repeat (10)",
18
+ "example_with_other_blocks": [
19
+ {
20
+ "script": "when [space v] key pressed\n repeat (10)\n move (10) steps\n wait (0.1) seconds\n end",
21
+ "explanation": "This script makes the sprite move 10 steps Ten times, with a short pause after each movement on spacebar pressed."
22
+ },
23
+ {
24
+ "script": "when [up arrow v] key pressed\n repeat (10)\n change y by (10)\n wait (0.1) seconds\n change y by (10)\n end",
25
+ "explanation": "This script makes the sprite jump, with a short pause after each movement on up arrow pressed."
26
+ }
27
+ ]
28
+ },
29
+ {
30
+ "block_name": "forever",
31
+ "block_type": "Control",
32
+ "block_shape": "C-Block",
33
+ "op_code": "control_forever",
34
+ "functionality": "Continuously runs the blocks inside it.",
35
+ "inputs": null,
36
+ "example_standalone": "forever",
37
+ "example_with_other_blocks": [
38
+ {
39
+ "script": "when green flag clicked\n forever\n move (5) steps\n if on edge, bounce\n end",
40
+ "explanation": "This script makes the sprite move endlessly and bounce off the edges of the stage, creating continuous motion."
41
+ }
42
+ ]
43
+ },
44
+ {
45
+ "block_name": "if () then",
46
+ "block_type": "Control",
47
+ "block_shape": "C-Block",
48
+ "op_code": "control_if",
49
+ "functionality": "Executes the blocks inside it only if the specified boolean condition is true.",
50
+ "inputs": [
51
+ {
52
+ "name": "condition",
53
+ "type": "boolean"
54
+ }
55
+ ],
56
+ "example_standalone": "if <touching [mouse-pointer v]?> then",
57
+ "example_with_other_blocks": [
58
+ {
59
+ "script": "forever\n if <touching [color (red) v]?> then\n stop [this script v]\n end",
60
+ "explanation": "This script continuously checks if the sprite is touching a red color, and if so, it stops the current script."
61
+ }
62
+ ]
63
+ },
64
+ {
65
+ "block_name": "if () then else",
66
+ "block_type": "Control",
67
+ "block_shape": "C-Block",
68
+ "op_code": "control_if_else",
69
+ "functionality": "Executes one set of blocks if the specified boolean condition is true, and a different set of blocks if the condition is false.",
70
+ "inputs": [
71
+ {
72
+ "name": "condition",
73
+ "type": "boolean"
74
+ }
75
+ ],
76
+ "example_standalone": "if <score > (10)> then else",
77
+ "example_with_other_blocks": [
78
+ {
79
+ "script": "if <score > (10)> then\n say [You win!] for (2) seconds\nelse\n say [Keep trying!] for (2) seconds\nend",
80
+ "explanation": "This script checks the 'score'. If the score is greater than 10, it says 'You win!'; otherwise, it says 'Keep trying!'."
81
+ }
82
+ ]
83
+ },
84
+ {
85
+ "block_name": "repeat until ()",
86
+ "block_type": "Control",
87
+ "block_shape": "C-Block",
88
+ "op_code": "control_repeat_until",
89
+ "functionality": "Repeats the blocks inside it until the specified boolean condition becomes true.",
90
+ "inputs": [
91
+ {
92
+ "name": "condition",
93
+ "type": "boolean"
94
+ }
95
+ ],
96
+ "example_standalone": "repeat until <touching [edge v]?>",
97
+ "example_with_other_blocks": [
98
+ {
99
+ "script": "repeat until <touching [edge v]?>\n move (5) steps\nend",
100
+ "explanation": "This script makes the sprite move 5 steps repeatedly until it touches the edge of the stage."
101
+ }
102
+ ]
103
+ }
104
+ ]
105
+ }
v2/scratch_agent/blocks_v1/cap_blocks.json ADDED
@@ -0,0 +1,53 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "block_category": "Cap Blocks",
3
+ "description": "Cap blocks have a notch at the top and a flat bottom. They signify the end of a script, preventing any further blocks from being placed below them, and are used to terminate scripts or specific actions.",
4
+ "blocks": [
5
+ {
6
+ "block_name": "stop [v]",
7
+ "block_type": "Control",
8
+ "block_shape": "Cap Block (dynamic: can be Stack)",
9
+ "op_code": "control_stop",
10
+ "functionality": "Halts all scripts, only the current script, or other scripts within the same sprite. Its shape can dynamically change based on the selected option.",
11
+ "inputs": [
12
+ {"name": "option", "type": "dropdown", "options": ["all"]}
13
+ ],
14
+ "example_standalone": "stop [all v]",
15
+ "example_with_other_blocks": [
16
+ {
17
+ "script": "if <(health) = (0)> then\n stop [all v]\nend",
18
+ "explanation": "This script stops all running scripts in the project if the 'health' variable reaches 0, typically signifying a game over condition. [9, 15]"
19
+ }
20
+ ]
21
+ },
22
+ {
23
+ "block_name": "delete this clone",
24
+ "block_type": "Control",
25
+ "block_shape": "Cap Block",
26
+ "op_code": "control_delete_this_clone",
27
+ "functionality": "Removes the clone that is executing it from the stage.",
28
+ "inputs":null,
29
+ "example_standalone": "delete this clone",
30
+ "example_with_other_blocks": [
31
+ {
32
+ "script": "when I start as a clone\n wait until <touching [edge v]?>\n delete this clone \nend \nend",
33
+ "explanation": "This script, run by a clone, causes the clone to disappear from the stage once it touches the edge. [1]"
34
+ }
35
+ ]
36
+ },
37
+ {
38
+ "block_name": "forever",
39
+ "block_type": "Control",
40
+ "block_shape": "Cap Block",
41
+ "op_code": "control_forever",
42
+ "functionality": "Continuously runs the blocks inside it.",
43
+ "inputs": null,
44
+ "example_standalone": "forever",
45
+ "example_with_other_blocks": [
46
+ {
47
+ "script": "when green flag clicked\n forever\n move (5) steps\n if on edge, bounce\n end",
48
+ "explanation": "This script makes the sprite move endlessly and bounce off the edges of the stage, creating continuous motion."
49
+ }
50
+ ]
51
+ }
52
+ ]
53
+ }
v2/scratch_agent/blocks_v1/excel_contetn/hat_block.xlsx ADDED
Binary file (10.5 kB). View file
 
v2/scratch_agent/blocks_v1/excel_contetn/stack_block.xlsx ADDED
Binary file (12.5 kB). View file
 
v2/scratch_agent/blocks_v1/hat_blocks.json ADDED
@@ -0,0 +1,217 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "block_category": "Hat Blocks",
3
+ "description": "Hat blocks are characterized by a rounded top and a bump at the bottom. They initiate scripts, meaning they are the starting point for a sequence of interconnected blocks.",
4
+ "blocks": [
5
+ {
6
+ "block_name": "when green flag pressed",
7
+ "block_type": "Events",
8
+ "op_code": "event_whenflagclicked",
9
+ "block_shape": "Hat Block",
10
+ "functionality": "This Hat block initiates the script when the green flag is clicked, serving as the common starting point for most Scratch projects.",
11
+ "inputs": null,
12
+ "example_standalone": "when green flag clicked",
13
+ "example_with_other_blocks": [
14
+ {
15
+ "script": "when green flag clicked\n go to x: (0) y: (0)\n say [Hello!] for (2) seconds",
16
+ "explanation": "This script makes the sprite go to the center of the stage and then say 'Hello!' for 2 seconds when the green flag is clicked."
17
+ }
18
+ ]
19
+ },
20
+ {
21
+ "block_name": "when () key pressed",
22
+ "block_type": "Events",
23
+ "op_code": "event_whenkeypressed",
24
+ "block_shape": "Hat Block",
25
+ "functionality": "This Hat block initiates the script when a specified keyboard key is pressed.",
26
+ "inputs": [
27
+ {
28
+ "name": "key",
29
+ "type": "dropdown",
30
+ "options": [
31
+ "space",
32
+ "up arrow",
33
+ "down arrow",
34
+ "right arrow",
35
+ "left arrow",
36
+ "any",
37
+ "a",
38
+ "b",
39
+ "c",
40
+ "d",
41
+ "e",
42
+ "f",
43
+ "g",
44
+ "h",
45
+ "i",
46
+ "j",
47
+ "k",
48
+ "l",
49
+ "m",
50
+ "n",
51
+ "o",
52
+ "p",
53
+ "q",
54
+ "r",
55
+ "s",
56
+ "t",
57
+ "u",
58
+ "v",
59
+ "w",
60
+ "x",
61
+ "y",
62
+ "z",
63
+ "0",
64
+ "1",
65
+ "2",
66
+ "3",
67
+ "4",
68
+ "5",
69
+ "6",
70
+ "7",
71
+ "8",
72
+ "9"
73
+ ]
74
+ }
75
+ ],
76
+ "example_standalone": "when [space v] key pressed",
77
+ "example_with_other_blocks": [
78
+ {
79
+ "script": "when [space v] key pressed\n repeat(10)\n change y by (10)\n wait (0.1) seconds\n change y by (-10)",
80
+ "explanation": "This script made jump the sprite right when the spacebar is pressed."
81
+ },
82
+ {
83
+ "script": "when [right arrow v] key pressed\n point in direction (90)\n move (10) steps",
84
+ "explanation": "This script moves the sprite right when the right arrow key is pressed."
85
+ }
86
+ ]
87
+ },
88
+ {
89
+ "block_name": "when this sprite clicked",
90
+ "block_type": "Events",
91
+ "op_code": "event_whenthisspriteclicked",
92
+ "block_shape": "Hat Block",
93
+ "functionality": "This Hat block starts the script when the sprite itself is clicked.",
94
+ "inputs": null,
95
+ "example_standalone": "when this sprite clicked",
96
+ "example_with_other_blocks": [
97
+ {
98
+ "script": "when this sprite clicked\n say [Ouch!] for (1) seconds\n change [score v] by (-1)",
99
+ "explanation": "This script makes the sprite say 'Ouch!' and decreases the score by 1 when the sprite is clicked."
100
+ }
101
+ ]
102
+ },
103
+ {
104
+ "block_name": "when backdrop switches to ()",
105
+ "block_type": "Events",
106
+ "op_code": "event_whenbackdropswitchesto",
107
+ "block_shape": "Hat Block",
108
+ "functionality": "This Hat block triggers the script when the stage backdrop changes to a specified backdrop.",
109
+ "inputs": [
110
+ {
111
+ "name": "backdrop name",
112
+ "type": "dropdown",
113
+ "options": ["backdrop1", "backdrop2", "..."]
114
+ }
115
+ ],
116
+ "example_standalone": "when backdrop switches to [game over v]",
117
+ "example_with_other_blocks": [
118
+ {
119
+ "script": "when backdrop switches to [game over v]\n stop [all v]",
120
+ "explanation": "This script stops all running processes when the backdrop changes to 'game over'."
121
+ },
122
+ {
123
+ "script": "when backdrop switches to [level completed v]\n stop [all v]",
124
+ "explanation": "This script stops all running processes when the backdrop changes to 'level completed'."
125
+ }
126
+ ]
127
+ },
128
+ {
129
+ "block_name": "when () > ()",
130
+ "block_type": "Events",
131
+ "op_code": "event_whengreaterthan",
132
+ "block_shape": "Hat Block",
133
+ "functionality": "This Hat block starts the script when a certain value (e.g., loudness from a microphone, or the timer) exceeds a defined threshold.",
134
+ "inputs": [
135
+ {
136
+ "name": "value type",
137
+ "type": "dropdown",
138
+ "options": [
139
+ "loudness",
140
+ "timer"
141
+ ]
142
+ },
143
+ {
144
+ "name": "threshold",
145
+ "type": "number"
146
+ }
147
+ ],
148
+ "example_standalone": "when [loudness v] > (70)",
149
+ "example_with_other_blocks": [
150
+ {
151
+ "script": "when [loudness v] > (70)\n start sound [scream v]",
152
+ "explanation": "This script starts a 'scream' sound when the microphone loudness exceeds 70."
153
+ }
154
+ ]
155
+ },
156
+ {
157
+ "block_name": "when I receive ()",
158
+ "block_type": "Events",
159
+ "op_code": "event_whenbroadcastreceived",
160
+ "block_shape": "Hat Block",
161
+ "functionality": "This Hat block initiates the script upon the reception of a specific broadcast message. This mechanism facilitates indirect communication between sprites or the stage.",
162
+ "inputs": [
163
+ {
164
+ "name": "message name",
165
+ "type": "dropdown",
166
+ "options": ["message1", "message2", "new message..."]
167
+ }
168
+ ],
169
+ "example_standalone": "when I receive [start game v]",
170
+ "example_with_other_blocks": [
171
+ {
172
+ "script": "when I receive [start game v]\n show\n go to x: (0) y: (0)",
173
+ "explanation": "This script makes the sprite visible and moves it to the center of the stage when it receives the 'start game' broadcast."
174
+ },
175
+ {
176
+ "script": "when I receive [game over v]\n set score to 0 \n stop [all v]",
177
+ "explanation": "This script stop all reset score on stage when it receives the 'game over' broadcast."
178
+ }
179
+ ]
180
+ },
181
+ {
182
+ "block_name": "When I Start as a Clone",
183
+ "block_type": "Control",
184
+ "op_code": "control_start_as_clone",
185
+ "block_shape": "Hat Block",
186
+ "functionality": "This Hat block initiates the script when a clone of the sprite is created. It defines the behavior of individual clones.",
187
+ "inputs": null,
188
+ "example_standalone": "When I Start as a Clone",
189
+ "example_with_other_blocks": [
190
+ {
191
+ "script": "when I start as a clone\n go to x: (pick random -240 to 240) y: (pick random -180 to 180)\n show\n forever\n move (10) steps\n if on edge, bounce",
192
+ "explanation": "This script makes a newly created clone appear at a random position, become visible, and then continuously move 10 steps, bouncing if it hits an edge."
193
+ }
194
+ ]
195
+ },
196
+ {
197
+ "block_name": "define [my custom block]",
198
+ "block_type": "My Blocks",
199
+ "op_code": "procedures_definition",
200
+ "block_shape": "Hat Block",
201
+ "functionality": "This Hat block serves as the definition header for a custom block's script. It allows users to define reusable sequences of code by specifying the block's name and any input parameters it will accept. This promotes modularity and abstraction in projects.",
202
+ "inputs": [
203
+ {
204
+ "name": "PROCCONTAINER",
205
+ "type": "block_prototype"
206
+ }
207
+ ],
208
+ "example_standalone": "define jump (height)",
209
+ "example_with_other_blocks": [
210
+ {
211
+ "script": "define jump (height)\n change y by (height)\n wait (0.5) seconds\n change y by (0 - (height))\n\nwhen green flag clicked\n jump (50)",
212
+ "explanation": "This script first defines a custom block named 'jump' that takes a numerical input 'height'. The definition outlines the actions for jumping up and then down. Later, 'jump (50)' is called to make the sprite jump 50 units."
213
+ }
214
+ ]
215
+ }
216
+ ]
217
+ }
v2/scratch_agent/blocks_v1/reporter_blocks.json ADDED
@@ -0,0 +1,709 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "block_category": "Reporter Blocks",
3
+ "description": "Reporter blocks have rounded edges. Their purpose is to report values, which can be numbers or strings, and are designed to fit into input slots of other blocks.",
4
+ "blocks": [
5
+ {
6
+ "block_name": "x position",
7
+ "block_type": "Motion",
8
+ "op_code": "motion_xposition",
9
+ "block_shape": "Reporter Block",
10
+ "functionality": "Reports the current X-coordinate of the sprite.[NOTE: not used in stage/backdrops]",
11
+ "inputs": null,
12
+ "example_standalone": "x position",
13
+ "example_with_other_blocks": [
14
+ {
15
+ "script": "when green flag clicked\n say (x position) for (2) seconds",
16
+ "explanation": "This script makes the sprite say its current X-coordinate for 2 seconds."
17
+ }
18
+ ]
19
+ },
20
+ {
21
+ "block_name": "y position",
22
+ "block_type": "Motion",
23
+ "op_code": "motion_yposition",
24
+ "block_shape": "Reporter Block",
25
+ "functionality": "Reports the current Y coordinate of the sprite on the stage.[NOTE: not used in stage/backdrops]",
26
+ "inputs": null,
27
+ "example_standalone": "y position",
28
+ "example_with_other_blocks": [
29
+ {
30
+ "script": "set [worms v] to (y position)",
31
+ "explanation": "This script assigns the sprite's current Y position to the 'worms' variable."
32
+ }
33
+ ]
34
+ },
35
+ {
36
+ "block_name": "direction",
37
+ "block_type": "Motion",
38
+ "op_code": "motion_direction",
39
+ "block_shape": "Reporter Block",
40
+ "functionality": "Reports the current direction of the sprite in degrees (0 = up, 90 = right, 180 = down, -90 = left).[NOTE: not used in stage/backdrops]",
41
+ "inputs": null,
42
+ "example_standalone": "direction",
43
+ "example_with_other_blocks": [
44
+ {
45
+ "script": "when green flag clicked\n say (direction) for (2) seconds",
46
+ "explanation": "This script makes the sprite say its current direction in degrees for 2 seconds."
47
+ }
48
+ ]
49
+ },
50
+ {
51
+ "block_name": "costume ()",
52
+ "block_type": "Looks",
53
+ "op_code": "looks_costumenumbername",
54
+ "block_shape": "Reporter Block",
55
+ "functionality": "Reports the current costume's number or name.",
56
+ "inputs": [
57
+ {
58
+ "name": "NUMBER_NAME",
59
+ "type": "dropdown",
60
+ "options": [
61
+ "number",
62
+ "name"
63
+ ]
64
+ }
65
+ ],
66
+ "example_standalone": "costume [number v]",
67
+ "example_with_other_blocks": [
68
+ {
69
+ "script": "say join [I am costume ] (costume [name v])",
70
+ "explanation": "This script makes the sprite display its current costume name in a speech bubble."
71
+ }
72
+ ]
73
+ },
74
+ {
75
+ "block_name": "size",
76
+ "block_type": "Looks",
77
+ "op_code": "looks_size",
78
+ "block_shape": "Reporter Block",
79
+ "functionality": "Reports the current size of the sprite as a percentage.",
80
+ "inputs": null,
81
+ "example_standalone": "size",
82
+ "example_with_other_blocks": [
83
+ {
84
+ "script": "set size to ( (size) + (10) )",
85
+ "explanation": "This script increases the sprite's size by 10% from its current size."
86
+ }
87
+ ]
88
+ },
89
+ {
90
+ "block_name": "backdrop ()",
91
+ "block_type": "Looks",
92
+ "op_code": "looks_backdropnumbername",
93
+ "block_shape": "Reporter Block",
94
+ "functionality": "Reports the current backdrop's number or name.",
95
+ "inputs": [
96
+ {
97
+ "name": "NUMBER_NAME",
98
+ "type": "dropdown",
99
+ "options": [
100
+ "number",
101
+ "name"
102
+ ]
103
+ }
104
+ ],
105
+ "example_standalone": "backdrop [number v]",
106
+ "example_with_other_blocks": [
107
+ {
108
+ "script": "say join [Current backdrop: ] (backdrop [name v]) for (2) seconds",
109
+ "explanation": "This script makes the sprite say the name of the current stage backdrop for 2 seconds."
110
+ }
111
+ ]
112
+ },
113
+ {
114
+ "block_name": "volume",
115
+ "block_type": "Sound",
116
+ "op_code": "sound_volume",
117
+ "block_shape": "Reporter Block",
118
+ "functionality": "Reports the current volume level of the sprite.",
119
+ "inputs": null,
120
+ "example_standalone": "volume",
121
+ "example_with_other_blocks": [
122
+ {
123
+ "script": "say join [Current volume: ] (volume)",
124
+ "explanation": "This script makes the sprite display its current volume level in a speech bubble."
125
+ }
126
+ ]
127
+ },
128
+ {
129
+ "block_name": "distance to ()",
130
+ "block_type": "Sensing",
131
+ "op_code": "sensing_distanceto",
132
+ "block_shape": "Reporter Block",
133
+ "functionality": "Reports the distance from the current sprite to the mouse-pointer or another specified sprite.",
134
+ "inputs": [
135
+ {
136
+ "name": "target",
137
+ "type": "dropdown",
138
+ "options": ["mouse-pointer", "Sprite1", "Sprite2", "...", "_edge_"]
139
+ }
140
+ ],
141
+ "example_standalone": "distance to [mouse-pointer v]",
142
+ "example_with_other_blocks": [
143
+ {
144
+ "script": "if <(distance to [Sprite2 v]) < (50)> then\n say [Too close!]",
145
+ "explanation": "This script makes the sprite say 'Too close!' if it is less than 50 steps away from 'Sprite2'."
146
+ }
147
+ ]
148
+ },
149
+ {
150
+ "block_name": "answer",
151
+ "block_type": "Sensing",
152
+ "op_code": "sensing_answer",
153
+ "block_shape": "Reporter Block",
154
+ "functionality": "Holds the most recent text inputted using the 'Ask () and Wait' block.",
155
+ "inputs": null,
156
+ "example_standalone": "answer",
157
+ "example_with_other_blocks": [
158
+ {
159
+ "script": "ask [What is your name?] and wait\n say join [Hello ] (answer)",
160
+ "explanation": "This script prompts the user for their name and then uses the 'answer' block to incorporate their input into a greeting."
161
+ }
162
+ ]
163
+ },
164
+ {
165
+ "block_name": "mouse x",
166
+ "block_type": "Sensing",
167
+ "op_code": "sensing_mousex",
168
+ "block_shape": "Reporter Block",
169
+ "functionality": "Reports the mouse-pointer’s current X position on the stage.",
170
+ "inputs": null,
171
+ "example_standalone": "mouse x",
172
+ "example_with_other_blocks": [
173
+ {
174
+ "script": "go to x: (mouse x) y: (mouse y)",
175
+ "explanation": "This script makes the sprite follow the mouse pointer's X and Y coordinates."
176
+ }
177
+ ]
178
+ },
179
+ {
180
+ "block_name": "mouse y",
181
+ "block_type": "Sensing",
182
+ "op_code": "sensing_mousey",
183
+ "block_shape": "Reporter Block",
184
+ "functionality": "Reports the mouse-pointer’s current Y position on the stage.",
185
+ "inputs": null,
186
+ "example_standalone": "mouse y",
187
+ "example_with_other_blocks": [
188
+ {
189
+ "script": "if <(mouse y) < (0)> then\n say [Below center]",
190
+ "explanation": "This script makes the sprite say 'Below center' if the mouse pointer is in the lower half of the stage."
191
+ }
192
+ ]
193
+ },
194
+ {
195
+ "block_name": "loudness",
196
+ "block_type": "Sensing",
197
+ "op_code": "sensing_loudness",
198
+ "block_shape": "Reporter Block",
199
+ "functionality": "Reports the loudness of noise received by a microphone on a scale of 0 to 100.",
200
+ "inputs": null,
201
+ "example_standalone": "loudness",
202
+ "example_with_other_blocks": [
203
+ {
204
+ "script": "when green flag clicked\n forever\n if <(loudness) > (30)> then\n start sound [pop v]",
205
+ "explanation": "This script continuously checks the microphone loudness and plays a 'pop' sound if it exceeds 30."
206
+ }
207
+ ]
208
+ },
209
+ {
210
+ "block_name": "timer",
211
+ "block_type": "Sensing",
212
+ "op_code": "sensing_timer",
213
+ "block_shape": "Reporter Block",
214
+ "functionality": "Reports the elapsed time since Scratch was launched or the timer was reset, increasing by 1 every second.",
215
+ "inputs": null,
216
+ "example_standalone": "timer",
217
+ "example_with_other_blocks": [
218
+ {
219
+ "script": "when green flag clicked\n reset timer\n wait (5) seconds\n say join [Time elapsed: ] (timer)",
220
+ "explanation": "This script resets the timer when the green flag is clicked, waits for 5 seconds, and then reports the elapsed time."
221
+ }
222
+ ]
223
+ },
224
+ {
225
+ "block_name": "() of ()",
226
+ "block_type": "Sensing",
227
+ "op_code": "sensing_of",
228
+ "block_shape": "Reporter Block",
229
+ "functionality": "Reports a specified value (e.g., x position, direction, costume number) of a specified sprite or the Stage.",
230
+ "inputs": [
231
+ {
232
+ "name": "value to report",
233
+ "type": "dropdown",
234
+ "options": [
235
+ "x position",
236
+ "y position",
237
+ "direction",
238
+ "costume #",
239
+ "costume name",
240
+ "size",
241
+ "volume",
242
+ "backdrop #",
243
+ "backdrop name"
244
+ ]
245
+ },
246
+ {
247
+ "name": "sprite/stage",
248
+ "type": "dropdown",
249
+ "options": ["Stage", "Sprite1", "Sprite2", "...", "_edge_"]
250
+ }
251
+ ],
252
+ "example_standalone": "x position of [Sprite1 v]",
253
+ "example_with_other_blocks": [
254
+ {
255
+ "script": "set [other sprite X v] to ( (x position) of [Sprite2 v] )",
256
+ "explanation": "This script sets the 'other sprite X' variable to the current X-position of 'Sprite2'."
257
+ }
258
+ ]
259
+ },
260
+ {
261
+ "block_name": "current ()",
262
+ "block_type": "Sensing",
263
+ "op_code": "sensing_current",
264
+ "block_shape": "Reporter Block",
265
+ "functionality": "Reports the current local year, month, date, day of the week, hour, minutes, or seconds.",
266
+ "inputs": [
267
+ {
268
+ "name": "time unit",
269
+ "type": "dropdown",
270
+ "options": [
271
+ "year",
272
+ "month",
273
+ "date",
274
+ "day of week",
275
+ "hour",
276
+ "minute",
277
+ "second"
278
+ ]
279
+ }
280
+ ],
281
+ "example_standalone": "current [hour v]",
282
+ "example_with_other_blocks": [
283
+ {
284
+ "script": "say join [The current hour is ] (current [hour v])",
285
+ "explanation": "This script makes the sprite say the current hour."
286
+ }
287
+ ]
288
+ },
289
+ {
290
+ "block_name": "days since 2000",
291
+ "block_type": "Sensing",
292
+ "op_code": "sensing_dayssince2000",
293
+ "block_shape": "Reporter Block",
294
+ "functionality": "Reports the number of days (and fractions of a day) since 00:00:00 UTC on January 1, 2000.",
295
+ "inputs": null,
296
+ "example_standalone": "days since 2000",
297
+ "example_with_other_blocks": [
298
+ {
299
+ "script": "say join [Days passed: ] (days since 2000)",
300
+ "explanation": "This script makes the sprite display the number of days that have passed since January 1, 2000."
301
+ }
302
+ ]
303
+ },
304
+ {
305
+ "block_name": "username",
306
+ "block_type": "Sensing",
307
+ "op_code": "sensing_username",
308
+ "block_shape": "Reporter Block",
309
+ "functionality": "Reports the username of the user currently logged into Scratch. If no user is logged in, it reports nothing.",
310
+ "inputs": null,
311
+ "example_standalone": "username",
312
+ "example_with_other_blocks": [
313
+ {
314
+ "script": "say join [Hello, ] (username)",
315
+ "explanation": "This script makes the sprite greet the user by their Scratch username."
316
+ }
317
+ ]
318
+ },
319
+ {
320
+ "block_name": "() + ()",
321
+ "block_type": "operator",
322
+ "op_code": "operator_add",
323
+ "block_shape": "Reporter Block",
324
+ "functionality": "Adds two numerical values.",
325
+ "inputs": [
326
+ {
327
+ "name": "number1",
328
+ "type": "number"
329
+ },
330
+ {
331
+ "name": "number2",
332
+ "type": "number"
333
+ }
334
+ ],
335
+ "example_standalone": "(5) + (3)",
336
+ "example_with_other_blocks": [
337
+ {
338
+ "script": "set [total v] to ( (number 1) + (number 2) )",
339
+ "explanation": "This script calculates the sum of 'number 1' and 'number 2' and stores the result in the 'total' variable."
340
+ }
341
+ ]
342
+ },
343
+ {
344
+ "block_name": "() - ()",
345
+ "block_type": "operator",
346
+ "op_code": "operator_subtract",
347
+ "block_shape": "Reporter Block",
348
+ "functionality": "Subtracts the second numerical value from the first.",
349
+ "inputs": [
350
+ {
351
+ "name": "number1",
352
+ "type": "number"
353
+ },
354
+ {
355
+ "name": "number2",
356
+ "type": "number"
357
+ }
358
+ ],
359
+ "example_standalone": "(10) - (4)",
360
+ "example_with_other_blocks": [
361
+ {
362
+ "script": "set [difference v] to ( (number 1) - (number 2) )",
363
+ "explanation": "This script calculates the subtraction of 'number 2' from 'number 1' and stores the result in the 'difference' variable."
364
+ }
365
+ ]
366
+ },
367
+ {
368
+ "block_name": "() * ()",
369
+ "block_type": "operator",
370
+ "op_code": "operator_multiply",
371
+ "block_shape": "Reporter Block",
372
+ "functionality": "Multiplies two numerical values.",
373
+ "inputs": [
374
+ {
375
+ "name": "number1",
376
+ "type": "number"
377
+ },
378
+ {
379
+ "name": "number2",
380
+ "type": "number"
381
+ }
382
+ ],
383
+ "example_standalone": "(6) * (7)",
384
+ "example_with_other_blocks": [
385
+ {
386
+ "script": "set [area v] to ( (length) * (width) )",
387
+ "explanation": "This script calculates the area by multiplying 'length' and 'width' variables and stores it in the 'area' variable."
388
+ }
389
+ ]
390
+ },
391
+ {
392
+ "block_name": "() / ()",
393
+ "block_type": "operator",
394
+ "op_code": "operator_divide",
395
+ "block_shape": "Reporter Block",
396
+ "functionality": "Divides the first numerical value by the second.",
397
+ "inputs": [
398
+ {
399
+ "name": "number1",
400
+ "type": "number"
401
+ },
402
+ {
403
+ "name": "number2",
404
+ "type": "number"
405
+ }
406
+ ],
407
+ "example_standalone": "(20) / (5)",
408
+ "example_with_other_blocks": [
409
+ {
410
+ "script": "set [average v] to ( (total score) / (number of students) )",
411
+ "explanation": "This script calculates the average by dividing 'total score' by 'number of students' and stores it in the 'average' variable."
412
+ }
413
+ ]
414
+ },
415
+ {
416
+ "block_name": "pick random () to ()",
417
+ "block_type": "operator",
418
+ "op_code": "operator_random",
419
+ "block_shape": "Reporter Block",
420
+ "functionality": "Generates a random integer within a specified inclusive range.",
421
+ "inputs": [
422
+ {
423
+ "name": "min",
424
+ "type": "number"
425
+ },
426
+ {
427
+ "name": "max",
428
+ "type": "number"
429
+ }
430
+ ],
431
+ "example_standalone": "pick random (1) to (10)",
432
+ "example_with_other_blocks": [
433
+ {
434
+ "script": "go to x: (pick random -240 to 240) y: (pick random -180 to 180)",
435
+ "explanation": "This script moves the sprite to a random position on the stage."
436
+ }
437
+ ]
438
+ },
439
+ {
440
+ "block_name": "join ()()",
441
+ "block_type": "operator",
442
+ "op_code": "operator_join",
443
+ "block_shape": "Reporter Block",
444
+ "functionality": "Concatenates two strings or values into a single string.",
445
+ "inputs": [
446
+ {
447
+ "name": "string1",
448
+ "type": "string/number"
449
+ },
450
+ {
451
+ "name": "string2",
452
+ "type": "string/number"
453
+ }
454
+ ],
455
+ "example_standalone": "join [Hello ][World!]",
456
+ "example_with_other_blocks": [
457
+ {
458
+ "script": "say join [Hello ][World!]",
459
+ "explanation": "This script makes the sprite display 'Hello World!' in a speech bubble by joining two string literals."
460
+ }
461
+ ]
462
+ },
463
+ {
464
+ "block_name": "letter () of ()",
465
+ "block_type": "operator",
466
+ "op_code": "operator_letterof",
467
+ "block_shape": "Reporter Block",
468
+ "functionality": "Reports the character at a specific numerical position within a string.",
469
+ "inputs": [
470
+ {
471
+ "name": "index",
472
+ "type": "number"
473
+ },
474
+ {
475
+ "name": "text",
476
+ "type": "string"
477
+ }
478
+ ],
479
+ "example_standalone": "letter (1) of [apple]",
480
+ "example_with_other_blocks": [
481
+ {
482
+ "script": "say letter (1) of [apple]",
483
+ "explanation": "This script makes the sprite display the first character of the string 'apple', which is 'a'."
484
+ }
485
+ ]
486
+ },
487
+ {
488
+ "block_name": "length of ()",
489
+ "block_type": "operator",
490
+ "op_code": "operator_length",
491
+ "block_shape": "Reporter Block",
492
+ "functionality": "Reports the total number of characters in a given string.",
493
+ "inputs": [
494
+ {
495
+ "name": "text",
496
+ "type": "string"
497
+ }
498
+ ],
499
+ "example_standalone": "length of [banana]",
500
+ "example_with_other_blocks": [
501
+ {
502
+ "script": "say length of [banana]",
503
+ "explanation": "This script makes the sprite display the length of the string 'banana', which is 6."
504
+ }
505
+ ]
506
+ },
507
+ {
508
+ "block_name": "() mod ()",
509
+ "block_type": "operator",
510
+ "op_code": "operator_mod",
511
+ "block_shape": "Reporter Block",
512
+ "functionality": "Reports the remainder when the first number is divided by the second.",
513
+ "inputs": [
514
+ {
515
+ "name": "number1",
516
+ "type": "number"
517
+ },
518
+ {
519
+ "name": "number2",
520
+ "type": "number"
521
+ }
522
+ ],
523
+ "example_standalone": "(10) mod (3)",
524
+ "example_with_other_blocks": [
525
+ {
526
+ "script": "if <(number) mod (2) = (0)> then\n say [Even number]",
527
+ "explanation": "This script checks if a 'number' variable is even by checking if its remainder when divided by 2 is 0."
528
+ }
529
+ ]
530
+ },
531
+ {
532
+ "block_name": "round ()",
533
+ "block_type": "operator",
534
+ "op_code": "operator_round",
535
+ "block_shape": "Reporter Block",
536
+ "functionality": "Rounds a numerical value to the nearest integer.",
537
+ "inputs": [
538
+ {
539
+ "name": "number",
540
+ "type": "number"
541
+ }
542
+ ],
543
+ "example_standalone": "round (3.7)",
544
+ "example_with_other_blocks": [
545
+ {
546
+ "script": "set [rounded score v] to (round (score))",
547
+ "explanation": "This script rounds the 'score' variable to the nearest whole number and stores it in 'rounded score'."
548
+ }
549
+ ]
550
+ },
551
+ {
552
+ "block_name": "() of ()",
553
+ "block_type": "operator",
554
+ "op_code": "operator_mathop",
555
+ "block_shape": "Reporter Block",
556
+ "functionality": "Performs various mathematical functions (e.g., absolute value, square root, trigonometric functions).",
557
+ "inputs": [
558
+ {
559
+ "name": "function type",
560
+ "type": "dropdown",
561
+ "options": [
562
+ "abs",
563
+ "floor",
564
+ "ceiling",
565
+ "sqrt",
566
+ "sin",
567
+ "cos",
568
+ "tan",
569
+ "asin",
570
+ "acos",
571
+ "atan",
572
+ "ln",
573
+ "log",
574
+ "e ^",
575
+ "10 ^"
576
+ ]
577
+ },
578
+ {
579
+ "name": "value",
580
+ "type": "number"
581
+ }
582
+ ],
583
+ "example_standalone": "([sqrt v] of (25))",
584
+ "example_with_other_blocks": [
585
+ {
586
+ "script": "set [distance v] to ([sqrt v] of ( ( (x position) * (x position) ) + ( (y position) * (y position) ) ))",
587
+ "explanation": "This script calculates the distance from the origin (0,0) using the Pythagorean theorem and stores it in 'distance'."
588
+ }
589
+ ]
590
+ },
591
+ {
592
+ "block_name": "variable",
593
+ "block_type": "Data",
594
+ "op_code": "data_variable",
595
+ "block_shape": "Reporter Block",
596
+ "functionality": "Provides the current value stored in a variable.",
597
+ "inputs": [
598
+ {
599
+ "name": "variable name",
600
+ "type": "dropdown",
601
+ "options": ["my variable", "score", "..."]
602
+ }
603
+ ],
604
+ "example_standalone": "score",
605
+ "example_with_other_blocks": [
606
+ {
607
+ "script": "say (score) for (2) seconds",
608
+ "explanation": "This script makes the sprite say the current value of the 'score' variable for 2 seconds."
609
+ }
610
+ ]
611
+ },
612
+ {
613
+ "block_name": "list",
614
+ "block_type": "Data",
615
+ "op_code": "data_list",
616
+ "block_shape": "Reporter Block",
617
+ "functionality": "Reports the entire content of a specified list. When clicked in the editor, it displays the list as a monitor.",
618
+ "inputs": [
619
+ {
620
+ "name": "list name",
621
+ "type": "dropdown",
622
+ "options": ["my list", "list2", "..."]
623
+ }
624
+ ],
625
+ "example_standalone": "my list",
626
+ "example_with_other_blocks": [
627
+ {
628
+ "script": "say (my list)",
629
+ "explanation": "This script makes the sprite say all the contents of 'my list'."
630
+ }
631
+ ]
632
+ },
633
+ {
634
+ "block_name": "item () of ()",
635
+ "block_type": "Data",
636
+ "op_code": "data_itemoflist",
637
+ "block_shape": "Reporter Block",
638
+ "functionality": "Reports the item located at a specific position in a list.",
639
+ "inputs": [
640
+ {
641
+ "name": "index/option",
642
+ "type": "number or dropdown",
643
+ "options": [
644
+ "last",
645
+ "random"
646
+ ]
647
+ },
648
+ {
649
+ "name": "list name",
650
+ "type": "dropdown",
651
+ "options": ["shopping list", "my list", "..."]
652
+ }
653
+ ],
654
+ "example_standalone": "item (1) of [shopping list v]",
655
+ "example_with_other_blocks": [
656
+ {
657
+ "script": "say item (1) of [shopping list v]",
658
+ "explanation": "This script makes the sprite display the first item from the 'shopping list'."
659
+ }
660
+ ]
661
+ },
662
+ {
663
+ "block_name": "length of () (list)",
664
+ "block_type": "Data",
665
+ "op_code": "data_lengthoflist",
666
+ "block_shape": "Reporter Block",
667
+ "functionality": "Provides the total number of items contained in a list.",
668
+ "inputs": [
669
+ {
670
+ "name": "list name",
671
+ "type": "dropdown",
672
+ "options": ["my list", "shopping list", "..."]
673
+ }
674
+ ],
675
+ "example_standalone": "length of [my list v]",
676
+ "example_with_other_blocks": [
677
+ {
678
+ "script": "say join (length of [shopping list v]) [ items in the list.]",
679
+ "explanation": "This script makes the sprite display the total number of items currently in the 'shopping list'."
680
+ }
681
+ ]
682
+ },
683
+ {
684
+ "block_name": "item # of () in ()",
685
+ "block_type": "Data",
686
+ "op_code": "data_itemnumoflist",
687
+ "block_shape": "Reporter Block",
688
+ "functionality": "Reports the index number of the first occurrence of a specified item in a list. If the item is not found, it reports 0.",
689
+ "inputs": [
690
+ {
691
+ "name": "item",
692
+ "type": "string/number"
693
+ },
694
+ {
695
+ "name": "list name",
696
+ "type": "dropdown",
697
+ "options": ["my list", "shopping list", "..."]
698
+ }
699
+ ],
700
+ "example_standalone": "item # of [apple] in [shopping list v]",
701
+ "example_with_other_blocks": [
702
+ {
703
+ "script": "if <(item # of [banana] in [my list v]) > (0)> then\n say join [Banana found at position ] (item # of [banana] in [my list v])",
704
+ "explanation": "This script checks if 'banana' is in 'my list' and, if so, reports its position."
705
+ }
706
+ ]
707
+ }
708
+ ]
709
+ }
v2/scratch_agent/blocks_v1/stack_blocks.json ADDED
@@ -0,0 +1,1316 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "block_category": "Stack Blocks",
3
+ "description": "Stack blocks are the most common block shape, featuring a notch at the top and a bump at the bottom. They perform the main commands within a script and can connect both above and below them.",
4
+ "blocks": [
5
+ {
6
+ "block_name": "move () steps",
7
+ "block_type": "Motion",
8
+ "block_shape": "Stack Block",
9
+ "op_code": "motion_movesteps",
10
+ "functionality": "Moves the sprite forward by the specified number of steps in the direction it is currently facing. A positive value moves it forward, and a negative value moves it backward.",
11
+ "inputs": [
12
+ {
13
+ "name": "STEPS",
14
+ "type": "number"
15
+ }
16
+ ],
17
+ "example_standalone": "move () steps",
18
+ "example_with_other_blocks": [
19
+ {
20
+ "script": "when green flag clicked\n go to x: (0) y: (0)\n point in direction (90)\n move (50) steps",
21
+ "explanation": "This script first places the sprite at the center of the stage, points it to the right (90 degrees), and then moves it 50 steps in that direction."
22
+ }
23
+ ]
24
+ },
25
+ {
26
+ "block_name": "turn right () degrees",
27
+ "block_type": "Motion",
28
+ "block_shape": "Stack Block",
29
+ "op_code": "motion_turnright",
30
+ "functionality": "Turns the sprite clockwise by the specified number of degrees.",
31
+ "inputs": [
32
+ {
33
+ "name": "DEGREES",
34
+ "type": "number"
35
+ }
36
+ ],
37
+ "example_standalone": "turn (clockwise icon) (15) degrees",
38
+ "example_with_other_blocks": [
39
+ {
40
+ "script": "when [right arrow v] key pressed\n turn (clockwise icon) (15) degrees",
41
+ "explanation": "This script makes the sprite turn clockwise by 15 degrees every time the right arrow key is pressed."
42
+ },
43
+ {
44
+ "script": "when green flag clicked\n forever\n turn (clockwise icon) (15) degrees\n wait (0.5) seconds\n end",
45
+ "explanation": "This script makes the sprite continuously spin clockwise by 15 degrees every half second."
46
+ }
47
+ ]
48
+ },
49
+ {
50
+ "block_name": "turn left () degrees",
51
+ "block_type": "Motion",
52
+ "block_shape": "Stack Block",
53
+ "op_code": "motion_turnleft",
54
+ "functionality": "Turns the sprite counter-clockwise by the specified number of degrees.",
55
+ "inputs": [
56
+ {
57
+ "name": "DEGREES",
58
+ "type": "number"
59
+ }
60
+ ],
61
+ "example_standalone": "turn (counter-clockwise icon) (15) degrees",
62
+ "example_with_other_blocks": [
63
+ {
64
+ "script": "when [left arrow v] key pressed\n turn (counter-clockwise icon) (15) degrees",
65
+ "explanation": "This script makes the sprite turn counter-clockwise by 15 degrees every time the left arrow key is pressed."
66
+ },
67
+ {
68
+ "script": "when green flag clicked\n forever\n turn (counter-clockwise icon) (15) degrees\n wait (0.5) seconds\n end",
69
+ "explanation": "This script makes the sprite continuously spin counter-clockwise by 15 degrees every half second."
70
+ }
71
+ ]
72
+ },
73
+ {
74
+ "block_name": "go to ()",
75
+ "block_type": "Motion",
76
+ "block_shape": "Stack Block",
77
+ "op_code": "motion_goto",
78
+ "functionality": "Moves the sprite to a specified location, which can be a random position, the mouse pointer, or another sprite.",
79
+ "inputs": [
80
+ {
81
+ "name": "TO",
82
+ "type": "dropdown",
83
+ "options": [
84
+ "random position",
85
+ "mouse-pointer",
86
+ "sprite1",
87
+ "..."
88
+ ]
89
+ }
90
+ ],
91
+ "example_standalone": "go to [random position v]",
92
+ "example_with_other_blocks": [
93
+ {
94
+ "script": "when this sprite clicked\n go to [mouse-pointer v]",
95
+ "explanation": "This script moves the sprite to the current position of the mouse pointer whenever the sprite is clicked."
96
+ }
97
+ ]
98
+ },
99
+ {
100
+ "block_name": "go to x: () y: ()",
101
+ "block_type": "Motion",
102
+ "block_shape": "Stack Block",
103
+ "op_code": "motion_gotoxy",
104
+ "functionality": "Moves the sprite to the specified X and Y coordinates on the stage.",
105
+ "inputs": [
106
+ {
107
+ "name": "X",
108
+ "type": "number"
109
+ },
110
+ {
111
+ "name": "Y",
112
+ "type": "number"
113
+ }
114
+ ],
115
+ "example_standalone": "go to x: (0) y: (0)",
116
+ "example_with_other_blocks": [
117
+ {
118
+ "script": "when green flag clicked\n go to x: (0) y: (0)\n say [Ready to start!] for (1) seconds",
119
+ "explanation": "This script positions the sprite at the center of the stage at the beginning of the project and then makes it say 'Ready to start!'."
120
+ }
121
+ ]
122
+ },
123
+ {
124
+ "block_name": "glide () secs to ()",
125
+ "block_type": "Motion",
126
+ "block_shape": "Stack Block",
127
+ "op_code": "motion_glideto",
128
+ "functionality": "Glides the sprite smoothly to a specified location (random position, mouse pointer, or another sprite) over a given number of seconds.",
129
+ "inputs": [
130
+ {
131
+ "name": "SECS",
132
+ "type": "number"
133
+ },
134
+ {
135
+ "name": "TO",
136
+ "type": "dropdown",
137
+ "options": [
138
+ "random position",
139
+ "mouse-pointer",
140
+ "sprite1",
141
+ "..."
142
+ ]
143
+ }
144
+ ],
145
+ "example_standalone": "glide (1) secs to [random position v]",
146
+ "example_with_other_blocks": [
147
+ {
148
+ "script": "when green flag clicked\n glide (1) secs to [mouse-pointer v]",
149
+ "explanation": "This script makes the sprite glide smoothly to the mouse pointer's position over 1 second when the green flag is clicked."
150
+ }
151
+ ]
152
+ },
153
+ {
154
+ "block_name": "glide () secs to x: () y: ()",
155
+ "block_type": "Motion",
156
+ "block_shape": "Stack Block",
157
+ "op_code": "motion_glidesecstoxy",
158
+ "functionality": "Glides the sprite smoothly to the specified X and Y coordinates over a given number of seconds.",
159
+ "inputs": [
160
+ {
161
+ "name": "SECS",
162
+ "type": "number"
163
+ },
164
+ {
165
+ "name": "X",
166
+ "type": "number"
167
+ },
168
+ {
169
+ "name": "Y",
170
+ "type": "number"
171
+ }
172
+ ],
173
+ "example_standalone": "glide (1) secs to x: (100) y: (50)",
174
+ "example_with_other_blocks": [
175
+ {
176
+ "script": "when green flag clicked\n glide (2) secs to x: (150) y: (-100)\n glide (2) secs to x: (-150) y: (100)",
177
+ "explanation": "This script makes the sprite glide to two different points on the stage, taking 2 seconds for each movement."
178
+ }
179
+ ]
180
+ },
181
+ {
182
+ "block_name": "point in direction ()",
183
+ "block_type": "Motion",
184
+ "block_shape": "Stack Block",
185
+ "op_code": "motion_pointindirection",
186
+ "functionality": "Sets the sprite's direction to a specified angle in degrees (0 = up, 90 = right, 180 = down, -90 = left).",
187
+ "inputs": [
188
+ {
189
+ "name": "DIRECTION",
190
+ "type": "number"
191
+ }
192
+ ],
193
+ "example_standalone": "point in direction (90)",
194
+ "example_with_other_blocks": [
195
+ {
196
+ "script": "when green flag clicked\n point in direction (0)\n move (100) steps",
197
+ "explanation": "This script makes the sprite point upwards (0 degrees) and then move 100 steps in that direction."
198
+ }
199
+ ]
200
+ },
201
+ {
202
+ "block_name": "point towards ()",
203
+ "block_type": "Motion",
204
+ "block_shape": "Stack Block",
205
+ "op_code": "motion_pointtowards",
206
+ "functionality": "Points the sprite towards the mouse pointer or another specified sprite.",
207
+ "inputs": [
208
+ {
209
+ "name": "TOWARDS",
210
+ "type": "dropdown",
211
+ "options": [
212
+ "mouse-pointer",
213
+ "sprite1",
214
+ "..."
215
+ ]
216
+ }
217
+ ],
218
+ "example_standalone": "point towards [mouse-pointer v]",
219
+ "example_with_other_blocks": [
220
+ {
221
+ "script": "when this sprite clicked\n point towards [mouse-pointer v]\n move (10) steps",
222
+ "explanation": "When the sprite is clicked, it will point towards the mouse pointer and then move 10 steps in that direction."
223
+ },
224
+ {
225
+ "script": "when green flag clicked\n forever\n point towards [mouse-pointer v]\n move (5) steps\n end",
226
+ "explanation": "This script makes the sprite continuously follow the mouse pointer."
227
+ }
228
+ ]
229
+ },
230
+ {
231
+ "block_name": "change x by ()",
232
+ "block_type": "Motion",
233
+ "block_shape": "Stack Block",
234
+ "op_code": "motion_changexby",
235
+ "functionality": "Changes the sprite's X-coordinate by the specified amount, moving it horizontally.",
236
+ "inputs": [
237
+ {
238
+ "name": "DX",
239
+ "type": "number"
240
+ }
241
+ ],
242
+ "example_standalone": "change x by (10)",
243
+ "example_with_other_blocks": [
244
+ {
245
+ "script": "when [right arrow v] key pressed\n change x by (10)",
246
+ "explanation": "This script moves the sprite 10 steps to the right when the right arrow key is pressed."
247
+ }
248
+ ]
249
+ },
250
+ {
251
+ "block_name": "set x to ()",
252
+ "block_type": "Motion",
253
+ "block_shape": "Stack Block",
254
+ "op_code": "motion_setx",
255
+ "functionality": "Sets the sprite's X-coordinate to a specific value, placing it at a precise horizontal position.",
256
+ "inputs": [
257
+ {
258
+ "name": "X",
259
+ "type": "number"
260
+ }
261
+ ],
262
+ "example_standalone": "set x to (0)",
263
+ "example_with_other_blocks": [
264
+ {
265
+ "script": "when green flag clicked\n set x to (0)\n set y to (0)",
266
+ "explanation": "This script centers the sprite horizontally at the start of the project."
267
+ }
268
+ ]
269
+ },
270
+ {
271
+ "block_name": "change y by ()",
272
+ "block_type": "Motion",
273
+ "block_shape": "Stack Block",
274
+ "op_code": "motion_changeyby",
275
+ "functionality": "Changes the sprite's Y-coordinate by the specified amount, moving it vertically.",
276
+ "inputs": [
277
+ {
278
+ "name": "DY",
279
+ "type": "number"
280
+ }
281
+ ],
282
+ "example_standalone": "change y by (10)",
283
+ "example_with_other_blocks": [
284
+ {
285
+ "script": "when [up arrow v] key pressed\n change y by (10)",
286
+ "explanation": "This script moves the sprite 10 steps up when the up arrow key is pressed."
287
+ }
288
+ ]
289
+ },
290
+ {
291
+ "block_name": "set y to ()",
292
+ "block_type": "Motion",
293
+ "block_shape": "Stack Block",
294
+ "op_code": "motion_sety",
295
+ "functionality": "Sets the sprite's Y-coordinate to a specific value, placing it at a precise vertical position.",
296
+ "inputs": [
297
+ {
298
+ "name": "Y",
299
+ "type": "number"
300
+ }
301
+ ],
302
+ "example_standalone": "set y to (0)",
303
+ "example_with_other_blocks": [
304
+ {
305
+ "script": "when green flag clicked\n set x to (0)\n set y to (0)",
306
+ "explanation": "This script centers the sprite vertically at the start of the project."
307
+ }
308
+ ]
309
+ },
310
+ {
311
+ "block_name": "if on edge, bounce",
312
+ "block_type": "Motion",
313
+ "block_shape": "Stack Block",
314
+ "op_code": "motion_ifonedgebounce",
315
+ "functionality": "Reverses the sprite's direction if it touches the edge of the stage.",
316
+ "inputs": null,
317
+ "example_standalone": "if on edge, bounce",
318
+ "example_with_other_blocks": [
319
+ {
320
+ "script": "when I receive [start moving v]\n repeat (50)\n move (5) steps\n if on edge, bounce\n end",
321
+ "explanation": "Upon receiving the 'start moving' broadcast, the sprite will move 5 steps repeatedly for 50 times, bouncing off edges if it touches them."
322
+ },
323
+ {
324
+ "script": "when green flag clicked\n forever\n move (10) steps\n if on edge, bounce\n end",
325
+ "explanation": "This script makes the sprite move continuously and bounce off the edges of the stage."
326
+ }
327
+ ]
328
+ },
329
+ {
330
+ "block_name": "set rotation style ()",
331
+ "block_type": "Motion",
332
+ "block_shape": "Stack Block",
333
+ "op_code": "motion_setrotationstyle",
334
+ "functionality": "Determines how the sprite rotates: 'left-right' (flips horizontally), 'don't rotate' (stays facing one direction), or 'all around' (rotates freely).",
335
+ "inputs": [
336
+ {
337
+ "name": "STYLE",
338
+ "type": "dropdown",
339
+ "options": [
340
+ "left-right",
341
+ "don't rotate",
342
+ "all around"
343
+ ]
344
+ }
345
+ ],
346
+ "example_standalone": "set rotation style [left-right v]",
347
+ "example_with_other_blocks": [
348
+ {
349
+ "script": "when backdrop switches to [game level 1 v]\n set rotation style [all around v]",
350
+ "explanation": "When the backdrop changes to 'game level 1', the sprite's rotation style will be set to 'all around', allowing it to rotate freely."
351
+ },
352
+ {
353
+ "script": "when green flag clicked\n set rotation style [left-right v]\n forever\n move (10) steps\n if on edge, bounce\n end",
354
+ "explanation": "This script makes the sprite move horizontally and flip its costume when it hits an edge, instead of rotating."
355
+ }
356
+ ]
357
+ },
358
+ {
359
+ "block_name": "say () for () seconds",
360
+ "block_type": "Looks",
361
+ "block_shape": "Stack Block",
362
+ "op_code": "looks_sayforsecs",
363
+ "functionality": "Displays a speech bubble containing specified text for a set duration.",
364
+ "inputs": [
365
+ {
366
+ "name": "MESSAGE",
367
+ "type": "string"
368
+ },
369
+ {
370
+ "name": "SECS",
371
+ "type": "number"
372
+ }
373
+ ],
374
+ "example_standalone": "say [Hello!] for (2) seconds",
375
+ "example_with_other_blocks": [
376
+ {
377
+ "script": "when green flag clicked\n say [Grr] for (3) seconds\n say [Have you seen my honey?] for (3) seconds",
378
+ "explanation": "This script makes the sprite display two sequential speech bubbles with different messages and durations. First, it says 'Grr' for 3 seconds, then 'Have you seen my honey?' for another 3 seconds."
379
+ }
380
+ ]
381
+ },
382
+ {
383
+ "block_name": "say ()",
384
+ "block_type": "Looks",
385
+ "block_shape": "Stack Block",
386
+ "op_code": "looks_say",
387
+ "functionality": "Displays a speech bubble with the specified text indefinitely until another 'say' or 'think' block is activated.",
388
+ "inputs": [
389
+ {
390
+ "name": "MESSAGE",
391
+ "type": "string"
392
+ }
393
+ ],
394
+ "example_standalone": "say [Hello!]",
395
+ "example_with_other_blocks": [
396
+ {
397
+ "script": "when green flag clicked\n say [Welcome to my game!]\n wait (2) seconds\n say []",
398
+ "explanation": "This script makes the sprite say 'Welcome to my game!' for 2 seconds, then clears the speech bubble."
399
+ }
400
+ ]
401
+ },
402
+ {
403
+ "block_name": "think () for () seconds",
404
+ "block_type": "Looks",
405
+ "block_shape": "Stack Block",
406
+ "op_code": "looks_thinkforsecs",
407
+ "functionality": "Displays a thought bubble containing specified text for a set duration.",
408
+ "inputs": [
409
+ {
410
+ "name": "MESSAGE",
411
+ "type": "string"
412
+ },
413
+ {
414
+ "name": "SECS",
415
+ "type": "number"
416
+ }
417
+ ],
418
+ "example_standalone": "think [Hmm...] for (2) seconds",
419
+ "example_with_other_blocks": [
420
+ {
421
+ "script": "when this sprite clicked\n think [What should I do?] for (2) seconds",
422
+ "explanation": "This script makes the sprite display a thought bubble saying 'What should I do?' for 2 seconds when clicked."
423
+ }
424
+ ]
425
+ },
426
+ {
427
+ "block_name": "think ()",
428
+ "block_type": "Looks",
429
+ "block_shape": "Stack Block",
430
+ "op_code": "looks_think",
431
+ "functionality": "Displays a thought bubble with the specified text indefinitely until another 'say' or 'think' block is activated.",
432
+ "inputs": [
433
+ {
434
+ "name": "MESSAGE",
435
+ "type": "string"
436
+ }
437
+ ],
438
+ "example_standalone": "think [Got it!]",
439
+ "example_with_other_blocks": [
440
+ {
441
+ "script": "when I receive [correct answer v]\n think [That's right!]\n wait (1) seconds\n think []",
442
+ "explanation": "This script makes the sprite think 'That's right!' for 1 second when a 'correct answer' broadcast is received, then clears the thought bubble."
443
+ }
444
+ ]
445
+ },
446
+ {
447
+ "block_name": "switch costume to ()",
448
+ "block_type": "Looks",
449
+ "block_shape": "Stack Block",
450
+ "op_code": "looks_switchcostumeto",
451
+ "functionality": "Alters the sprite's appearance to a designated costume.",
452
+ "inputs": [
453
+ {
454
+ "name": "COSTUME",
455
+ "type": "dropdown/number"
456
+ }
457
+ ],
458
+ "example_standalone": "switch costume to [costume1 v]",
459
+ "example_with_other_blocks": [
460
+ {
461
+ "script": "when I receive [explosion v]\n repeat (5)\n next costume\n end\n hide",
462
+ "explanation": "This script animates an explosion by rapidly switching costumes, then hides the sprite. [3]"
463
+ }
464
+ ]
465
+ },
466
+ {
467
+ "block_name": "next costume",
468
+ "block_type": "Looks",
469
+ "block_shape": "Stack Block",
470
+ "op_code": "looks_nextcostume",
471
+ "functionality": "Switches the sprite's costume to the next one in its costume list. If it's the last costume, it cycles back to the first.",
472
+ "inputs": null,
473
+ "example_standalone": "next costume",
474
+ "example_with_other_blocks": [
475
+ {
476
+ "script": "when [space v] key pressed\n repeat (3)\n next costume\n wait (0.1) seconds\n end",
477
+ "explanation": "When the space key is pressed, the sprite will cycle through its next three costumes with a short delay between each change."
478
+ },
479
+ {
480
+ "script": "when green flag clicked\n forever\n next costume\n wait (0.2) seconds\n end",
481
+ "explanation": "This script continuously animates the sprite by switching to the next costume every 0.2 seconds, creating a walking or flying effect."
482
+ }
483
+ ]
484
+ },
485
+ {
486
+ "block_name": "switch backdrop to ()",
487
+ "block_type": "Looks",
488
+ "block_shape": "Stack Block",
489
+ "op_code": "looks_switchbackdropto",
490
+ "functionality": "Changes the stage's backdrop to a specified backdrop.",
491
+ "inputs": [
492
+ {
493
+ "name": "BACKDROP",
494
+ "type": "dropdown/number"
495
+ }
496
+ ],
497
+ "example_standalone": "switch backdrop to [backdrop1 v]",
498
+ "example_with_other_blocks": [
499
+ {
500
+ "script": "when green flag clicked\n switch backdrop to [start screen v]",
501
+ "explanation": "This script sets the stage to a 'start screen' backdrop when the project begins."
502
+ }
503
+ ]
504
+ },
505
+ {
506
+ "block_name": "switch backdrop to () and wait",
507
+ "block_type": "Looks",
508
+ "block_shape": "Stack Block",
509
+ "op_code": "looks_switchbackdroptowait",
510
+ "functionality": "Changes the stage's backdrop to a specified backdrop and pauses the script until any 'When backdrop switches to' scripts for that backdrop have finished.",
511
+ "inputs": [
512
+ {
513
+ "name": "BACKDROP",
514
+ "type": "dropdown/number"
515
+ }
516
+ ],
517
+ "example_standalone": "switch backdrop to [game over v] and wait",
518
+ "example_with_other_blocks": [
519
+ {
520
+ "script": "broadcast [game over v]\n switch backdrop to [game over v] and wait\n stop [all v]",
521
+ "explanation": "This script broadcasts a 'game over' message, then changes the backdrop to 'game over' and waits for any associated scripts to finish before stopping all processes."
522
+ }
523
+ ]
524
+ },
525
+ {
526
+ "block_name": "next backdrop",
527
+ "block_type": "Looks",
528
+ "block_shape": "Stack Block",
529
+ "op_code": "looks_nextbackdrop",
530
+ "functionality": "Switches the stage's backdrop to the next one in its backdrop list. If it's the last backdrop, it cycles back to the first.",
531
+ "inputs": null,
532
+ "example_standalone": "next backdrop",
533
+ "example_with_other_blocks": [
534
+ {
535
+ "script": "when [space v] key pressed\n next backdrop",
536
+ "explanation": "This script changes the stage to the next backdrop in the list each time the space key is pressed."
537
+ }
538
+ ]
539
+ },
540
+ {
541
+ "block_name": "change size by ()",
542
+ "block_type": "Looks",
543
+ "block_shape": "Stack Block",
544
+ "op_code": "looks_changesizeby",
545
+ "functionality": "Changes the sprite's size by a specified percentage. Positive values make it larger, negative values make it smaller.",
546
+ "inputs": [
547
+ {
548
+ "name": "CHANGE",
549
+ "type": "number"
550
+ }
551
+ ],
552
+ "example_standalone": "change size by (10)",
553
+ "example_with_other_blocks": [
554
+ {
555
+ "script": "when green flag clicked\n repeat (10)\n change size by (5)\n wait (0.1) seconds\n end",
556
+ "explanation": "This script makes the sprite gradually grow larger over 10 steps, with a short pause between each size change."
557
+ }
558
+ ]
559
+ },
560
+ {
561
+ "block_name": "set size to () %",
562
+ "block_type": "Looks",
563
+ "block_shape": "Stack Block",
564
+ "op_code": "looks_setsizeto",
565
+ "functionality": "Sets the sprite's size to a specific percentage of its original size.",
566
+ "inputs": [
567
+ {
568
+ "name": "SIZE",
569
+ "type": "number"
570
+ }
571
+ ],
572
+ "example_standalone": "set size to (100) %",
573
+ "example_with_other_blocks": [
574
+ {
575
+ "script": "when green flag clicked\n set size to (50) %\n wait (1) seconds\n set size to (100) %",
576
+ "explanation": "This script makes the sprite shrink to half its original size at the start, waits for 1 second, then returns to its original size."
577
+ }
578
+ ]
579
+ },
580
+ {
581
+ "block_name": "change () effect by ()",
582
+ "block_type": "Looks",
583
+ "block_shape": "Stack Block",
584
+ "op_code": "looks_changeeffectby",
585
+ "functionality": "Changes a visual effect on the sprite by a specified amount (e.g., color, fisheye, whirl, pixelate, mosaic, brightness, ghost).",
586
+ "inputs": [
587
+ {
588
+ "name": "EFFECT",
589
+ "type": "dropdown",
590
+ "options": [
591
+ "color",
592
+ "fisheye",
593
+ "whirl",
594
+ "pixelate",
595
+ "mosaic",
596
+ "brightness",
597
+ "ghost"
598
+ ]
599
+ },
600
+ {
601
+ "name": "CHANGE",
602
+ "type": "number"
603
+ }
604
+ ],
605
+ "example_standalone": "change [color v] effect by (25)",
606
+ "example_with_other_blocks": [
607
+ {
608
+ "script": "when loudness > (10)\n change [fisheye v] effect by (5)",
609
+ "explanation": "When the loudness detected by the microphone is greater than 10, the sprite's fisheye effect will increase by 5."
610
+ },
611
+ {
612
+ "script": "when green flag clicked\n forever\n change [color v] effect by (5)\n wait (0.1) seconds\n end",
613
+ "explanation": "This script makes the sprite continuously cycle through different colors."
614
+ }
615
+ ]
616
+ },
617
+ {
618
+ "block_name": "set () effect to ()",
619
+ "block_type": "Looks",
620
+ "block_shape": "Stack Block",
621
+ "op_code": "looks_seteffectto",
622
+ "functionality": "Sets a visual effect on the sprite to a specific value.",
623
+ "inputs": [
624
+ {
625
+ "name": "EFFECT",
626
+ "type": "dropdown",
627
+ "options": [
628
+ "color",
629
+ "fisheye",
630
+ "whirl",
631
+ "pixelate",
632
+ "mosaic",
633
+ "brightness",
634
+ "ghost"
635
+ ]
636
+ },
637
+ {
638
+ "name": "VALUE",
639
+ "type": "number"
640
+ }
641
+ ],
642
+ "example_standalone": "set [ghost v] effect to (50)",
643
+ "example_with_other_blocks": [
644
+ {
645
+ "script": "when green flag clicked\n set [ghost v] effect to (75)",
646
+ "explanation": "This script makes the sprite 75% transparent at the start of the project."
647
+ }
648
+ ]
649
+ },
650
+ {
651
+ "block_name": "clear graphic effects",
652
+ "block_type": "Looks",
653
+ "block_shape": "Stack Block",
654
+ "op_code": "looks_cleargraphiceffects",
655
+ "functionality": "Removes all visual effects applied to the sprite.",
656
+ "inputs": null,
657
+ "example_standalone": "clear graphic effects",
658
+ "example_with_other_blocks": [
659
+ {
660
+ "script": "when green flag clicked\n change [color v] effect by (50)\n wait (2) seconds\n clear graphic effects",
661
+ "explanation": "This script changes the sprite's color effect, waits 2 seconds, then resets all graphic effects."
662
+ }
663
+ ]
664
+ },
665
+ {
666
+ "block_name": "show",
667
+ "block_type": "Looks",
668
+ "block_shape": "Stack Block",
669
+ "op_code": "looks_show",
670
+ "functionality": "Makes the sprite visible on the stage.",
671
+ "inputs": null,
672
+ "example_standalone": "show",
673
+ "example_with_other_blocks": [
674
+ {
675
+ "script": "when green flag clicked\n hide\nwhen I receive [start game v]\n show",
676
+ "explanation": "This script hides the sprite at the beginning of the project and makes it visible when a 'start game' broadcast is received."
677
+ }
678
+ ]
679
+ },
680
+ {
681
+ "block_name": "hide",
682
+ "block_type": "Looks",
683
+ "block_shape": "Stack Block",
684
+ "op_code": "looks_hide",
685
+ "functionality": "Makes the sprite invisible on the stage.",
686
+ "inputs": null,
687
+ "example_standalone": "hide",
688
+ "example_with_other_blocks": [
689
+ {
690
+ "script": "when green flag clicked\n hide",
691
+ "explanation": "This script hides the sprite from the stage when the green flag is clicked."
692
+ }
693
+ ]
694
+ },
695
+ {
696
+ "block_name": "go to () layer",
697
+ "block_type": "Looks",
698
+ "block_shape": "Stack Block",
699
+ "op_code": "looks_gotofrontback",
700
+ "functionality": "Moves the sprite to the front-most or back-most layer of other sprites on the stage.",
701
+ "inputs": [
702
+ {
703
+ "name": "FRONT_BACK",
704
+ "type": "dropdown",
705
+ "options": [
706
+ "front",
707
+ "back"
708
+ ]
709
+ }
710
+ ],
711
+ "example_standalone": "go to [front v] layer",
712
+ "example_with_other_blocks": [
713
+ {
714
+ "script": "when green flag clicked\n go to [front v] layer",
715
+ "explanation": "This script ensures the sprite is always visible on top of other sprites at the start of the project."
716
+ }
717
+ ]
718
+ },
719
+ {
720
+ "block_name": "go () layers",
721
+ "block_type": "Looks",
722
+ "block_shape": "Stack Block",
723
+ "op_code": "looks_goforwardbackwardlayers",
724
+ "functionality": "Moves the sprite forward or backward a specified number of layers in relation to other sprites.",
725
+ "inputs": [
726
+ {
727
+ "name": "FORWARD_BACKWARD",
728
+ "type": "dropdown",
729
+ "options": [
730
+ "forward",
731
+ "backward"
732
+ ]
733
+ },
734
+ {
735
+ "name": "NUM",
736
+ "type": "number"
737
+ }
738
+ ],
739
+ "example_standalone": "go [forward v] (1) layers",
740
+ "example_with_other_blocks": [
741
+ {
742
+ "script": "when this sprite clicked go [forward v] (1) layers",
743
+ "explanation": "This script brings the clicked sprite one layer closer to the front."
744
+ }
745
+ ]
746
+ },
747
+ {
748
+ "block_name": "play sound () until done",
749
+ "block_type": "Sound",
750
+ "block_shape": "Stack Block",
751
+ "op_code": "sound_playuntildone",
752
+ "functionality": "Plays a specified sound and pauses the script's execution until the sound has completed.",
753
+ "inputs": [
754
+ {
755
+ "name": "sound name",
756
+ "type": "dropdown"
757
+ }
758
+ ],
759
+ "example_standalone": "play sound [Meow v] until done",
760
+ "example_with_other_blocks": [
761
+ {
762
+ "script": "when backdrop switches to [winning screen v]\n play sound [fanfare v] until done\n say [You won!] for (2) seconds",
763
+ "explanation": "When the backdrop changes to the 'winning screen', a 'fanfare' sound will play until it finishes, and then the sprite will say 'You won!' for 2 seconds."
764
+ },
765
+ {
766
+ "script": "forever\n play sound [Music v] until done",
767
+ "explanation": "This script creates a continuous loop for background music, playing the 'Music' sound repeatedly."
768
+ }
769
+ ]
770
+ },
771
+ {
772
+ "block_name": "start sound ()",
773
+ "block_type": "Sound",
774
+ "block_shape": "Stack Block",
775
+ "op_code": "sound_start",
776
+ "functionality": "Initiates playback of a specified sound without pausing the script, allowing other actions to proceed concurrently.",
777
+ "inputs": [
778
+ {
779
+ "name": "sound name",
780
+ "type": "dropdown"
781
+ }
782
+ ],
783
+ "example_standalone": "start sound [Pop v]",
784
+ "example_with_other_blocks": [
785
+ {
786
+ "script": "when this sprite clicked\n start sound [Pop v]\n change [score v] by (1)",
787
+ "explanation": "This script plays a 'Pop' sound and increments the score simultaneously when the sprite is clicked."
788
+ }
789
+ ]
790
+ },
791
+ {
792
+ "block_name": "stop all sounds",
793
+ "block_type": "Sound",
794
+ "block_shape": "Stack Block",
795
+ "op_code": "sound_stopallsounds",
796
+ "functionality": "Stops all currently playing sounds.",
797
+ "inputs": null,
798
+ "example_standalone": "stop all sounds",
799
+ "example_with_other_blocks": [
800
+ {
801
+ "script": "when I receive [game over v]\n stop all sounds",
802
+ "explanation": "This script stops any sounds currently playing when the 'game over' broadcast is received."
803
+ }
804
+ ]
805
+ },
806
+ {
807
+ "block_name": "change volume by ()",
808
+ "block_type": "Sound",
809
+ "block_shape": "Stack Block",
810
+ "op_code": "sound_changevolumeby",
811
+ "functionality": "Changes the project's sound volume by a specified amount.",
812
+ "inputs": [
813
+ {
814
+ "name": "change",
815
+ "type": "number"
816
+ }
817
+ ],
818
+ "example_standalone": "change volume by (-10)",
819
+ "example_with_other_blocks": [
820
+ {
821
+ "script": "when [down arrow v] key pressed\n change volume by (-5)",
822
+ "explanation": "This script decreases the project's volume by 5 when the down arrow key is pressed."
823
+ }
824
+ ]
825
+ },
826
+ {
827
+ "block_name": "set volume to () %",
828
+ "block_type": "Sound",
829
+ "block_shape": "Stack Block",
830
+ "op_code": "sound_setvolumeto",
831
+ "functionality": "Sets the sound volume to a specific percentage (0-100).",
832
+ "inputs": [
833
+ {
834
+ "name": "percentage",
835
+ "type": "number"
836
+ }
837
+ ],
838
+ "example_standalone": "set volume to (100) %",
839
+ "example_with_other_blocks": [
840
+ {
841
+ "script": "when green flag clicked\n set volume to (50) %",
842
+ "explanation": "This script sets the project's volume to 50% when the green flag is clicked."
843
+ }
844
+ ]
845
+ },
846
+ {
847
+ "block_name": "broadcast ()",
848
+ "block_type": "Events",
849
+ "block_shape": "Stack Block",
850
+ "op_code": "event_broadcast",
851
+ "functionality": "Sends a broadcast message throughout the Scratch program, activating any 'when I receive ()' blocks that are set to listen for that message, enabling indirect communication.",
852
+ "inputs": [
853
+ {
854
+ "name": "message name",
855
+ "type": "string/dropdown"
856
+ }
857
+ ],
858
+ "example_standalone": "broadcast [start game v]",
859
+ "example_with_other_blocks": [
860
+ {
861
+ "script": "if <key [space v] pressed?> then\n broadcast [jump v]\nend",
862
+ "explanation": "This script sends a 'jump' message to other scripts or sprites when the space key is pressed."
863
+ }
864
+ ]
865
+ },
866
+ {
867
+ "block_name": "broadcast () and wait",
868
+ "block_type": "Events",
869
+ "block_shape": "Stack Block",
870
+ "op_code": "event_broadcastandwait",
871
+ "functionality": "Sends a broadcast message and pauses the current script until all other scripts activated by that broadcast have completed their execution, ensuring sequential coordination.",
872
+ "inputs": [
873
+ {
874
+ "name": "message name",
875
+ "type": "string/dropdown"
876
+ }
877
+ ],
878
+ "example_standalone": "broadcast [initialize sprites v] and wait",
879
+ "example_with_other_blocks": [
880
+ {
881
+ "script": "broadcast [initialize sprites v] and wait\n say [Game Started!] for (2) seconds",
882
+ "explanation": "This script ensures all sprite initialization routines complete before displaying 'Game Started!' for 2 seconds."
883
+ }
884
+ ]
885
+ },
886
+ {
887
+ "block_name": "wait () seconds",
888
+ "block_type": "Control",
889
+ "block_shape": "Stack Block",
890
+ "op_code": "control_wait",
891
+ "functionality": "Pauses the script for a specified duration.",
892
+ "inputs": [
893
+ {
894
+ "name": "seconds",
895
+ "type": "number"
896
+ }
897
+ ],
898
+ "example_standalone": "wait (1) seconds",
899
+ "example_with_other_blocks": [
900
+ {
901
+ "script": "say [Hello!] for (1) seconds\n wait (0.5) seconds\n say [Goodbye!] for (1) seconds",
902
+ "explanation": "This script creates a timed dialogue sequence, pausing for 0.5 seconds between two speech bubbles."
903
+ }
904
+ ]
905
+ },
906
+ {
907
+ "block_name": "wait until ()",
908
+ "block_type": "Control",
909
+ "block_shape": "Stack Block",
910
+ "op_code": "control_wait_until",
911
+ "functionality": "Pauses the script until the specified boolean condition becomes true.",
912
+ "inputs": [
913
+ {
914
+ "name": "condition",
915
+ "type": "boolean"
916
+ }
917
+ ],
918
+ "example_standalone": "wait until <key [space v] pressed?>",
919
+ "example_with_other_blocks": [
920
+ {
921
+ "script": "wait until <key [space v] pressed?>\n start sound [pop v]",
922
+ "explanation": "This script pauses until the space key is pressed, then plays a 'pop' sound."
923
+ }
924
+ ]
925
+ },
926
+ {
927
+ "block_name": "stop ()",
928
+ "block_type": "Control",
929
+ "block_shape": "Stack Block",
930
+ "op_code": "control_stop",
931
+ "functionality": "Stops all scripts, this script, or other scripts in the sprite. Becomes a Cap Block if 'all' or 'this script' is selected in the dropdown menu.",
932
+ "inputs": [
933
+ {
934
+ "name": "option",
935
+ "type": "dropdown",
936
+ "options": [
937
+ "all",
938
+ "this script",
939
+ "other scripts in sprite"
940
+ ]
941
+ }
942
+ ],
943
+ "example_standalone": "stop [all v]",
944
+ "example_with_other_blocks": [
945
+ {
946
+ "script": "if <score = (0)> then\n stop [all v]\nend",
947
+ "explanation": "This script stops the entire project if the 'score' variable becomes 0."
948
+ }
949
+ ]
950
+ },
951
+ {
952
+ "block_name": "create clone of ()",
953
+ "block_type": "Control",
954
+ "block_shape": "Stack Block",
955
+ "op_code": "control_create_clone_of",
956
+ "functionality": "Generates a copy, or clone, of a specified sprite (or 'myself' for the current sprite).",
957
+ "inputs": [
958
+ {
959
+ "name": "sprite_name",
960
+ "type": "dropdown",
961
+ "options": [
962
+ "myself",
963
+ "sprite1",
964
+ "..."
965
+ ]
966
+ }
967
+ ],
968
+ "example_standalone": "create clone of [myself v]",
969
+ "example_with_other_blocks": [
970
+ {
971
+ "script": "when I start as a clone\n show\n go to random position\n wait (2) seconds\n delete this clone",
972
+ "explanation": "When a clone is created, it will show itself, go to a random position, wait for 2 seconds, and then delete itself."
973
+ }
974
+ ]
975
+ },
976
+ {
977
+ "block_name": "delete this clone",
978
+ "block_type": "Control",
979
+ "block_shape": "Stack Block",
980
+ "op_code": "control_delete_this_clone",
981
+ "functionality": "Deletes the clone that is currently running the script.",
982
+ "inputs": null,
983
+ "example_standalone": "delete this clone",
984
+ "example_with_other_blocks": [
985
+ {
986
+ "script": "when I start as a clone\n wait (5) seconds\n delete this clone",
987
+ "explanation": "This script makes each clone wait for 5 seconds after it's created, then deletes itself."
988
+ }
989
+ ]
990
+ },
991
+ {
992
+ "block_name": "set [my variable v] to ()",
993
+ "block_type": "Data",
994
+ "block_shape": "Stack Block",
995
+ "op_code": "data_setvariableto",
996
+ "functionality": "Assigns a specific value (number, string, or boolean) to a variable.",
997
+ "inputs": [
998
+ {
999
+ "name": "variable name",
1000
+ "type": "dropdown"
1001
+ },
1002
+ {
1003
+ "name": "value",
1004
+ "type": "any"
1005
+ }
1006
+ ],
1007
+ "example_standalone": "set [score v] to (0)",
1008
+ "example_with_other_blocks": [
1009
+ {
1010
+ "script": "when green flag clicked\n set [score v] to (0)\n set [player name v] to [Guest]",
1011
+ "explanation": "This script initializes the 'score' variable to 0 and the 'player name' variable to 'Guest' when the project starts."
1012
+ }
1013
+ ]
1014
+ },
1015
+ {
1016
+ "block_name": "change [my variable v] by ()",
1017
+ "block_type": "Data",
1018
+ "block_shape": "Stack Block",
1019
+ "op_code": "data_changevariableby",
1020
+ "functionality": "Increases or decreases a variable's numerical value by a specified amount.",
1021
+ "inputs": [
1022
+ {
1023
+ "name": "variable name",
1024
+ "type": "dropdown"
1025
+ },
1026
+ {
1027
+ "name": "value",
1028
+ "type": "number"
1029
+ }
1030
+ ],
1031
+ "example_standalone": "change [score v] by (1)",
1032
+ "example_with_other_blocks": [
1033
+ {
1034
+ "script": "when this sprite clicked\n change [score v] by (1)",
1035
+ "explanation": "This script increments the 'score' variable by 1 each time the sprite is clicked."
1036
+ }
1037
+ ]
1038
+ },
1039
+ {
1040
+ "block_name": "add () to [my list v]",
1041
+ "block_type": "Data",
1042
+ "block_shape": "Stack Block",
1043
+ "op_code": "data_addtolist",
1044
+ "functionality": "Appends an item to the end of a list.",
1045
+ "inputs": [
1046
+ {
1047
+ "name": "item",
1048
+ "type": "any"
1049
+ },
1050
+ {
1051
+ "name": "list name",
1052
+ "type": "dropdown"
1053
+ }
1054
+ ],
1055
+ "example_standalone": "add [apple] to [shopping list v]",
1056
+ "example_with_other_blocks": [
1057
+ {
1058
+ "script": "when green flag clicked\n add [apple] to [shopping list v]\n add [banana] to [shopping list v]",
1059
+ "explanation": "This script adds 'apple' and 'banana' as new items to the 'shopping list' when the project starts."
1060
+ }
1061
+ ]
1062
+ },
1063
+ {
1064
+ "block_name": "delete () of [my list v]",
1065
+ "block_type": "Data",
1066
+ "block_shape": "Stack Block",
1067
+ "op_code": "data_deleteoflist",
1068
+ "functionality": "Removes an item from a list by its index or by selecting 'all' items.",
1069
+ "inputs": [
1070
+ {
1071
+ "name": "index/option",
1072
+ "type": "number/dropdown",
1073
+ "options": [
1074
+ "all",
1075
+ "last",
1076
+ "random"
1077
+ ]
1078
+ },
1079
+ {
1080
+ "name": "list name",
1081
+ "type": "dropdown"
1082
+ }
1083
+ ],
1084
+ "example_standalone": "delete (1) of [my list v]",
1085
+ "example_with_other_blocks": [
1086
+ {
1087
+ "script": "when green flag clicked\n delete (all) of [my list v]",
1088
+ "explanation": "This script clears all items from 'my list' when the green flag is clicked."
1089
+ }
1090
+ ]
1091
+ },
1092
+ {
1093
+ "block_name": "insert () at () of [my list v]",
1094
+ "block_type": "Data",
1095
+ "block_shape": "Stack Block",
1096
+ "op_code": "data_insertatlist",
1097
+ "functionality": "Inserts an item at a specific position within a list.",
1098
+ "inputs": [
1099
+ {
1100
+ "name": "item",
1101
+ "type": "any"
1102
+ },
1103
+ {
1104
+ "name": "index",
1105
+ "type": "number"
1106
+ },
1107
+ {
1108
+ "name": "list name",
1109
+ "type": "dropdown"
1110
+ }
1111
+ ],
1112
+ "example_standalone": "insert [orange] at (2) of [fruits v]",
1113
+ "example_with_other_blocks": [
1114
+ {
1115
+ "script": "insert [orange] at (2) of [fruits v]",
1116
+ "explanation": "This script inserts 'orange' as the second item in the 'fruits' list, shifting subsequent items."
1117
+ }
1118
+ ]
1119
+ },
1120
+ {
1121
+ "block_name": "replace item () of [my list v] with ()",
1122
+ "block_type": "Data",
1123
+ "block_shape": "Stack Block",
1124
+ "op_code": "data_replaceitemoflist",
1125
+ "functionality": "Replaces an item at a specific position in a list with a new value.",
1126
+ "inputs": [
1127
+ {
1128
+ "name": "index",
1129
+ "type": "number"
1130
+ },
1131
+ {
1132
+ "name": "list name",
1133
+ "type": "dropdown"
1134
+ },
1135
+ {
1136
+ "name": "new item",
1137
+ "type": "any"
1138
+ }
1139
+ ],
1140
+ "example_standalone": "replace item (1) of [colors v] with [blue]",
1141
+ "example_with_other_blocks": [
1142
+ {
1143
+ "script": "replace item (1) of [colors v] with [blue]",
1144
+ "explanation": "This script changes the first item in the 'colors' list to 'blue'."
1145
+ }
1146
+ ]
1147
+ },
1148
+ {
1149
+ "block_name": "show variable [my variable v]",
1150
+ "block_type": "Data",
1151
+ "block_shape": "Stack Block",
1152
+ "op_code": "data_showvariable",
1153
+ "functionality": "Makes a variable's monitor visible on the stage.",
1154
+ "inputs": [
1155
+ {
1156
+ "name": "variable name",
1157
+ "type": "dropdown"
1158
+ }
1159
+ ],
1160
+ "example_standalone": "show variable [score v]",
1161
+ "example_with_other_blocks": [
1162
+ {
1163
+ "script": "when green flag clicked\n show variable [score v]",
1164
+ "explanation": "This script displays the 'score' variable on the stage when the project starts."
1165
+ }
1166
+ ]
1167
+ },
1168
+ {
1169
+ "block_name": "hide variable [my variable v]",
1170
+ "block_type": "Data",
1171
+ "block_shape": "Stack Block",
1172
+ "op_code": "data_hidevariable",
1173
+ "functionality": "Hides a variable's monitor from the stage.",
1174
+ "inputs": [
1175
+ {
1176
+ "name": "variable name",
1177
+ "type": "dropdown"
1178
+ }
1179
+ ],
1180
+ "example_standalone": "hide variable [score v]",
1181
+ "example_with_other_blocks": [
1182
+ {
1183
+ "script": "when I receive [game over v]\n hide variable [score v]",
1184
+ "explanation": "This script hides the 'score' variable when the 'game over' broadcast is received."
1185
+ }
1186
+ ]
1187
+ },
1188
+ {
1189
+ "block_name": "show list [my list v]",
1190
+ "block_type": "Data",
1191
+ "block_shape": "Stack Block",
1192
+ "op_code": "data_showlist",
1193
+ "functionality": "Makes a list's monitor visible on the stage.",
1194
+ "inputs": [
1195
+ {
1196
+ "name": "list name",
1197
+ "type": "dropdown"
1198
+ }
1199
+ ],
1200
+ "example_standalone": "show list [shopping list v]",
1201
+ "example_with_other_blocks": [
1202
+ {
1203
+ "script": "when green flag clicked\n show list [shopping list v]",
1204
+ "explanation": "This script displays the 'shopping list' on the stage when the project starts."
1205
+ }
1206
+ ]
1207
+ },
1208
+ {
1209
+ "block_name": "hide list [my list v]",
1210
+ "block_type": "Data",
1211
+ "block_shape": "Stack Block",
1212
+ "op_code": "data_hidelist",
1213
+ "functionality": "Hides a list's monitor from the stage.",
1214
+ "inputs": [
1215
+ {
1216
+ "name": "list name",
1217
+ "type": "dropdown"
1218
+ }
1219
+ ],
1220
+ "example_standalone": "hide list [shopping list v]",
1221
+ "example_with_other_blocks": [
1222
+ {
1223
+ "script": "when I receive [game over v]\n hide list [shopping list v]",
1224
+ "explanation": "This script hides the 'shopping list' when the 'game over' broadcast is received."
1225
+ }
1226
+ ]
1227
+ },
1228
+ {
1229
+ "block_name": "Ask () and Wait",
1230
+ "block_type": "Sensing",
1231
+ "block_shape": "Stack Block",
1232
+ "op_code": "sensing_askandwait",
1233
+ "functionality": "Displays an input box with specified text at the bottom of the screen, allowing users to input text, which is stored in the 'Answer' block.",
1234
+ "inputs": [
1235
+ {
1236
+ "name": "question",
1237
+ "type": "text"
1238
+ }
1239
+ ],
1240
+ "example_standalone": "ask [What is your name?] and wait",
1241
+ "example_with_other_blocks": [
1242
+ {
1243
+ "script": "ask [What is your name?] and wait\n say join [Hello ] (answer) for (2) seconds",
1244
+ "explanation": "This script prompts the user for their name, waits for input, then greets them using the provided answer."
1245
+ }
1246
+ ]
1247
+ },
1248
+ {
1249
+ "block_name": "Reset Timer",
1250
+ "block_type": "Sensing",
1251
+ "block_shape": "Stack Block",
1252
+ "op_code": "sensing_resettimer",
1253
+ "functionality": "Sets the timer’s value back to 0.0.",
1254
+ "inputs": null,
1255
+ "example_standalone": "reset timer",
1256
+ "example_with_other_blocks": [
1257
+ {
1258
+ "script": "when green flag clicked\n reset timer\n wait (5) seconds\n say timer for (2) seconds",
1259
+ "explanation": "This script resets the timer at the start, waits for 5 seconds, then says the current timer value."
1260
+ }
1261
+ ]
1262
+ },
1263
+ {
1264
+ "block_name": "set drag mode [draggable v]",
1265
+ "block_type": "Sensing",
1266
+ "block_shape": "Stack Block",
1267
+ "op_code": "sensing_setdragmode",
1268
+ "functionality": "Sets whether the sprite can be dragged by the mouse on the stage.",
1269
+ "inputs": null,
1270
+ "fields": {
1271
+ "DRAG_MODE": {
1272
+ "type": "dropdown",
1273
+ "options": [
1274
+ "draggable",
1275
+ "not draggable"
1276
+ ]
1277
+ }
1278
+ },
1279
+ "example_standalone": "set drag mode [draggable v]",
1280
+ "example_with_other_blocks": [
1281
+ {
1282
+ "script": "when green flag clicked\n set drag mode [not draggable v]\nwhen this sprite clicked\n set drag mode [draggable v]",
1283
+ "explanation": "This script makes the sprite not draggable when the project starts, but allows it to be dragged once it's clicked."
1284
+ }
1285
+ ]
1286
+ },
1287
+ {
1288
+ "block_name": "[my custom block]",
1289
+ "block_type": "My Blocks",
1290
+ "block_shape": "Stack Block",
1291
+ "op_code": "procedures_call",
1292
+ "functionality": "Executes the script defined by a corresponding 'define' Hat block. This block allows users to call and reuse custom code sequences by simply dragging and dropping it into their scripts, optionally providing required input values.",
1293
+ "inputs": [
1294
+ {
1295
+ "name": "argument_name_1",
1296
+ "type": "any"
1297
+ },
1298
+ {
1299
+ "name": "argument_name_2",
1300
+ "type": "any"
1301
+ }
1302
+ ],
1303
+ "example_standalone": "jump (50)",
1304
+ "example_with_other_blocks": [
1305
+ {
1306
+ "script": "when green flag clicked\n go to x: (0) y: (0)\n jump (50)\n wait (1) seconds\n say [I jumped!] for (2) seconds",
1307
+ "explanation": "This script moves the sprite to a starting position, then calls the 'jump' custom block with an input of 50 (assuming 'jump' is a custom block that moves the sprite up and down). After the jump, the sprite says 'I jumped!'."
1308
+ },
1309
+ {
1310
+ "script": "when green flag clicked\n hide\n forever\n create clone of [myself v]\n wait (1) seconds\n end",
1311
+ "explanation": "This script continuously creates new clones of the current sprite every second after the original sprite hides itself."
1312
+ }
1313
+ ]
1314
+ }
1315
+ ]
1316
+ }
v2/scratch_agent/debug_combine_blocks.json ADDED
@@ -0,0 +1,419 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "d": {},
3
+ "g": {},
4
+ "operator_random": {
5
+ "block_name": "pick random () to ()",
6
+ "block_type": "operator",
7
+ "op_code": "operator_random",
8
+ "block_shape": "Reporter Block",
9
+ "functionality": "Generates a random integer within a specified inclusive range.",
10
+ "inputs": {
11
+ "FROM": [
12
+ 1,
13
+ [
14
+ 4,
15
+ "1"
16
+ ]
17
+ ],
18
+ "TO": [
19
+ 1,
20
+ [
21
+ 4,
22
+ "10"
23
+ ]
24
+ ]
25
+ },
26
+ "example_standalone": "pick random (1) to (10)",
27
+ "example_with_other_blocks": [
28
+ {
29
+ "script": "go to x: (pick random -240 to 240) y: (pick random -180 to 180)",
30
+ "explanation": "This script moves the sprite to a random position on the stage."
31
+ }
32
+ ],
33
+ "opcode": "operator_random",
34
+ "next": null,
35
+ "parent": null,
36
+ "fields": {},
37
+ "shadow": false,
38
+ "topLevel": true,
39
+ "x": 311,
40
+ "y": 157
41
+ },
42
+ "control_forever": {
43
+ "block_name": "forever",
44
+ "block_type": "Control",
45
+ "block_shape": "C-Block",
46
+ "op_code": "control_forever",
47
+ "functionality": "Continuously runs the blocks inside it.",
48
+ "inputs": {},
49
+ "example_standalone": "forever",
50
+ "example_with_other_blocks": [
51
+ {
52
+ "script": "when green flag clicked\n forever\n move (5) steps\n if on edge, bounce\n end",
53
+ "explanation": "This script makes the sprite move endlessly and bounce off the edges of the stage, creating continuous motion."
54
+ }
55
+ ],
56
+ "opcode": "control_forever",
57
+ "next": null,
58
+ "parent": null,
59
+ "fields": {},
60
+ "shadow": false,
61
+ "topLevel": true,
62
+ "x": 334,
63
+ "y": 439
64
+ },
65
+ "operator_equals": {
66
+ "block_name": "<() = ()>",
67
+ "block_type": "operator",
68
+ "op_code": "operator_equals",
69
+ "block_shape": "Boolean Block",
70
+ "functionality": "Checks if two values are equal.",
71
+ "inputs": {
72
+ "OPERAND1": [
73
+ 1,
74
+ [
75
+ 10,
76
+ ""
77
+ ]
78
+ ],
79
+ "OPERAND2": [
80
+ 1,
81
+ [
82
+ 10,
83
+ "50"
84
+ ]
85
+ ]
86
+ },
87
+ "example_standalone": "<(answer) = (5)>",
88
+ "example_with_other_blocks": [
89
+ {
90
+ "script": "if <(answer) = (5)> then\n say [Correct!]",
91
+ "explanation": "This script makes the sprite say 'Correct!' if the value of the 'answer' variable is exactly 5."
92
+ }
93
+ ],
94
+ "opcode": "operator_equals",
95
+ "next": null,
96
+ "parent": null,
97
+ "fields": {},
98
+ "shadow": false,
99
+ "topLevel": true,
100
+ "x": 345,
101
+ "y": 372
102
+ },
103
+ "t": {},
104
+ "operator_multiply": {
105
+ "block_name": "() * ()",
106
+ "block_type": "operator",
107
+ "op_code": "operator_multiply",
108
+ "block_shape": "Reporter Block",
109
+ "functionality": "Multiplies two numerical values.",
110
+ "inputs": {
111
+ "NUM1": [
112
+ 1,
113
+ [
114
+ 4,
115
+ ""
116
+ ]
117
+ ],
118
+ "NUM2": [
119
+ 1,
120
+ [
121
+ 4,
122
+ ""
123
+ ]
124
+ ]
125
+ },
126
+ "example_standalone": "(6) * (7)",
127
+ "example_with_other_blocks": [
128
+ {
129
+ "script": "set [area v] to ( (length) * (width) )",
130
+ "explanation": "This script calculates the area by multiplying 'length' and 'width' variables and stores it in the 'area' variable."
131
+ }
132
+ ],
133
+ "opcode": "operator_multiply",
134
+ "next": null,
135
+ "parent": null,
136
+ "fields": {},
137
+ "shadow": false,
138
+ "topLevel": true,
139
+ "x": 134,
140
+ "y": 278
141
+ },
142
+ "motion_turnright": {
143
+ "block_name": "turn right () degrees",
144
+ "block_type": "Motion",
145
+ "block_shape": "Stack Block",
146
+ "op_code": "motion_turnright",
147
+ "functionality": "Turns the sprite clockwise by the specified number of degrees.",
148
+ "inputs": {
149
+ "DEGREES": [
150
+ 1,
151
+ [
152
+ 4,
153
+ "15"
154
+ ]
155
+ ]
156
+ },
157
+ "example_standalone": "turn (clockwise icon) (15) degrees",
158
+ "example_with_other_blocks": [
159
+ {
160
+ "script": "when [right arrow v] key pressed\n turn (clockwise icon) (15) degrees\nend",
161
+ "explanation": "This script makes the sprite turn clockwise by 15 degrees every time the right arrow key is pressed."
162
+ },
163
+ {
164
+ "script": "when green flag clicked\n forever\n turn (clockwise icon) (15) degrees\n wait (0.5) seconds\n end",
165
+ "explanation": "This script makes the sprite continuously spin clockwise by 15 degrees every half second."
166
+ }
167
+ ],
168
+ "opcode": "motion_turnright",
169
+ "next": null,
170
+ "parent": null,
171
+ "fields": {},
172
+ "shadow": false,
173
+ "topLevel": true,
174
+ "x": 467,
175
+ "y": -316
176
+ },
177
+ "motion_gotoxy": {
178
+ "block_name": "go to x: () y: ()",
179
+ "block_type": "Motion",
180
+ "block_shape": "Stack Block",
181
+ "op_code": "motion_gotoxy",
182
+ "functionality": "Moves the sprite to the specified X and Y coordinates on the stage.",
183
+ "inputs": {
184
+ "X": [
185
+ 1,
186
+ [
187
+ 4,
188
+ "0"
189
+ ]
190
+ ],
191
+ "Y": [
192
+ 1,
193
+ [
194
+ 4,
195
+ "0"
196
+ ]
197
+ ]
198
+ },
199
+ "example_standalone": "go to x: (0) y: (0)",
200
+ "example_with_other_blocks": [
201
+ {
202
+ "script": "when green flag clicked\n go to x: (0) y: (0)\n say [Ready to start! v] for (1) seconds\nend",
203
+ "explanation": "This script positions the sprite at the center of the stage at the beginning of the project and then makes it say 'Ready to start!'."
204
+ }
205
+ ],
206
+ "opcode": "motion_gotoxy",
207
+ "next": null,
208
+ "parent": null,
209
+ "fields": {},
210
+ "shadow": false,
211
+ "topLevel": true,
212
+ "x": 468,
213
+ "y": 12
214
+ },
215
+ "sensing_backdropnumbername": {},
216
+ "operator_mod": {
217
+ "block_name": "() mod ()",
218
+ "block_type": "operator",
219
+ "op_code": "operator_mod",
220
+ "block_shape": "Reporter Block",
221
+ "functionality": "Reports the remainder when the first number is divided by the second.",
222
+ "inputs": {
223
+ "NUM1": [
224
+ 1,
225
+ [
226
+ 4,
227
+ ""
228
+ ]
229
+ ],
230
+ "NUM2": [
231
+ 1,
232
+ [
233
+ 4,
234
+ ""
235
+ ]
236
+ ]
237
+ },
238
+ "example_standalone": "(10) mod (3)",
239
+ "example_with_other_blocks": [
240
+ {
241
+ "script": "if <(number) mod (2) = (0)> then\n say [Even number]",
242
+ "explanation": "This script checks if a 'number' variable is even by checking if its remainder when divided by 2 is 0."
243
+ }
244
+ ],
245
+ "opcode": "operator_mod",
246
+ "next": null,
247
+ "parent": null,
248
+ "fields": {},
249
+ "shadow": false,
250
+ "topLevel": true,
251
+ "x": 295,
252
+ "y": 594
253
+ },
254
+ "_": {},
255
+ "sound_playuntildone": {
256
+ "block_name": "play sound () until done",
257
+ "block_type": "Sound",
258
+ "block_shape": "Stack Block",
259
+ "op_code": "sound_playuntildone",
260
+ "functionality": "Plays a specified sound and pauses the script's execution until the sound has completed.",
261
+ "inputs": {
262
+ "SOUND_MENU": [
263
+ 1,
264
+ "4w%pR8G.yD%g-BwCj=uK"
265
+ ]
266
+ },
267
+ "example_standalone": "play sound [Meow v] until done",
268
+ "example_with_other_blocks": [
269
+ {
270
+ "script": "when backdrop switches to [winning screen v]\n play sound [fanfare v] until done\n say [You won!] for (2) seconds\nend",
271
+ "explanation": "When the backdrop changes to the 'winning screen', a 'fanfare' sound will play until it finishes, and then the sprite will say 'You won!' for 2 seconds."
272
+ },
273
+ {
274
+ "script": "forever\n play sound [Music v] until done \nend",
275
+ "explanation": "This script creates a continuous loop for background music, playing the 'Music' sound repeatedly."
276
+ }
277
+ ],
278
+ "opcode": "sound_playuntildone",
279
+ "next": null,
280
+ "parent": null,
281
+ "fields": {},
282
+ "shadow": false,
283
+ "topLevel": true,
284
+ "x": 253,
285
+ "y": 17
286
+ },
287
+ "h": {},
288
+ "l": {},
289
+ "k": {},
290
+ "f": {},
291
+ "motion_changexby": {
292
+ "block_name": "change x by ()",
293
+ "block_type": "Motion",
294
+ "block_shape": "Stack Block",
295
+ "op_code": "motion_changexby",
296
+ "functionality": "Changes the sprite's X-coordinate by the specified amount, moving it horizontally.",
297
+ "inputs": {
298
+ "DX": [
299
+ 1,
300
+ [
301
+ 4,
302
+ "10"
303
+ ]
304
+ ]
305
+ },
306
+ "example_standalone": "change x by (10)",
307
+ "example_with_other_blocks": [
308
+ {
309
+ "script": "when [right arrow v] key pressed\n change x by (10)\nend",
310
+ "explanation": "This script moves the sprite 10 steps to the right when the right arrow key is pressed."
311
+ }
312
+ ],
313
+ "opcode": "motion_changexby",
314
+ "next": null,
315
+ "parent": null,
316
+ "fields": {},
317
+ "shadow": false,
318
+ "topLevel": true,
319
+ "x": 851,
320
+ "y": -409
321
+ },
322
+ "data_changevariableby": {
323
+ "block_name": "change [my variable v] by ()",
324
+ "block_type": "Data",
325
+ "block_shape": "Stack Block",
326
+ "op_code": "data_changevariableby",
327
+ "functionality": "Increases or decreases a variable's numerical value by a specified amount.",
328
+ "inputs": {
329
+ "VALUE": [
330
+ 1,
331
+ [
332
+ 4,
333
+ "1"
334
+ ]
335
+ ]
336
+ },
337
+ "example_standalone": "change [score v] by (1)",
338
+ "example_with_other_blocks": [
339
+ {
340
+ "script": "when this sprite clicked\n change [score v] by (1)\nend",
341
+ "explanation": "This script increments the 'score' variable by 1 each time the sprite is clicked."
342
+ }
343
+ ],
344
+ "opcode": "data_changevariableby",
345
+ "next": null,
346
+ "parent": null,
347
+ "fields": {
348
+ "VARIABLE": [
349
+ "my variable",
350
+ "`jEk@4|i[#Fk?(8x)AV.-my variable"
351
+ ]
352
+ },
353
+ "shadow": false,
354
+ "topLevel": true,
355
+ "x": 313,
356
+ "y": 363
357
+ },
358
+ "motion_setx": {
359
+ "block_name": "set x to ()",
360
+ "block_type": "Motion",
361
+ "block_shape": "Stack Block",
362
+ "op_code": "motion_setx",
363
+ "functionality": "Sets the sprite's X-coordinate to a specific value, placing it at a precise horizontal position.",
364
+ "inputs": {
365
+ "X": [
366
+ 1,
367
+ [
368
+ 4,
369
+ "0"
370
+ ]
371
+ ]
372
+ },
373
+ "example_standalone": "set x to (0)",
374
+ "example_with_other_blocks": [
375
+ {
376
+ "script": "when green flag clicked\n set x to (0)\n set y to (0)\nend",
377
+ "explanation": "This script centers the sprite horizontally at the start of the project."
378
+ }
379
+ ],
380
+ "opcode": "motion_setx",
381
+ "next": null,
382
+ "parent": null,
383
+ "fields": {},
384
+ "shadow": false,
385
+ "topLevel": true,
386
+ "x": 864,
387
+ "y": -194
388
+ },
389
+ "c": {},
390
+ "control_if": {
391
+ "block_name": "if () then",
392
+ "block_type": "Control",
393
+ "block_shape": "C-Block",
394
+ "op_code": "control_if",
395
+ "functionality": "Executes the blocks inside it only if the specified boolean condition is true.",
396
+ "inputs": {},
397
+ "example_standalone": "if <touching [mouse-pointer v]?> then",
398
+ "example_with_other_blocks": [
399
+ {
400
+ "script": "forever\n if <touching [color (red) v]?> then\n stop [this script v]\n end",
401
+ "explanation": "This script continuously checks if the sprite is touching a red color, and if so, it stops the current script."
402
+ }
403
+ ],
404
+ "opcode": "control_if",
405
+ "next": null,
406
+ "parent": null,
407
+ "fields": {},
408
+ "shadow": false,
409
+ "topLevel": true,
410
+ "x": 331,
411
+ "y": 597
412
+ },
413
+ "v": {},
414
+ "a": {},
415
+ "w": {},
416
+ "e": {},
417
+ "i": {},
418
+ "n": {}
419
+ }
v2/scratch_agent/debug_combine_state.json ADDED
@@ -0,0 +1,2070 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "project_json": {
3
+ "targets": [
4
+ {
5
+ "isStage": true,
6
+ "name": "Stage",
7
+ "objName": "Stage",
8
+ "variables": {
9
+ "score_73fce27a": [
10
+ "score",
11
+ "0"
12
+ ],
13
+ "☁ High Score_2b744c35": [
14
+ "☁ High Score",
15
+ "0",
16
+ true
17
+ ],
18
+ "speed_c110710a": [
19
+ "speed",
20
+ "0"
21
+ ],
22
+ "lives_9019623c": [
23
+ "lives",
24
+ "3"
25
+ ],
26
+ "level_000d70bb": [
27
+ "level",
28
+ "1"
29
+ ]
30
+ },
31
+ "lists": {
32
+ "recent_scores_c4c10267": [
33
+ "recent_scores",
34
+ []
35
+ ],
36
+ "obstacle_speeds_b690a1ee": [
37
+ "obstacle_speeds",
38
+ []
39
+ ],
40
+ "power_ups_efcd2ef7": [
41
+ "power_ups",
42
+ []
43
+ ]
44
+ },
45
+ "broadcasts": {
46
+ "Game Over_9032e357": "Game Over",
47
+ "Game Start_ba9be238": "Game Start",
48
+ "Level Up_6e23a340": "Level Up",
49
+ "Power Up Collected_bd804925": "Power Up Collected"
50
+ },
51
+ "blocks": {
52
+ "hatBlockID": {
53
+ "opcode": "event_whenflagclicked",
54
+ "next": "switchBackdropBlockID",
55
+ "parent": null,
56
+ "shadow": false,
57
+ "topLevel": true,
58
+ "x": 0,
59
+ "y": 0
60
+ },
61
+ "switchBackdropBlockID": {
62
+ "opcode": "looks_switchbackdropto",
63
+ "inputs": {
64
+ "BACKDROP": [
65
+ 1,
66
+ "blueSkyBackdropShadowID"
67
+ ]
68
+ },
69
+ "next": "setScoreBlockID",
70
+ "parent": "hatBlockID",
71
+ "shadow": false,
72
+ "topLevel": false,
73
+ "x": 100,
74
+ "y": 0
75
+ },
76
+ "blueSkyBackdropShadowID": {
77
+ "opcode": "looks_backdrops",
78
+ "fields": {
79
+ "BACKDROP": [
80
+ "Blue Sky",
81
+ "e7c147730f19d284bcd7b3f00af19bb6"
82
+ ]
83
+ },
84
+ "shadow": true,
85
+ "parent": "switchBackdropBlockID",
86
+ "topLevel": false
87
+ },
88
+ "setScoreBlockID": {
89
+ "opcode": "data_setvariableto",
90
+ "fields": {
91
+ "VARIABLE": [
92
+ "score",
93
+ "score_73fce27a"
94
+ ]
95
+ },
96
+ "inputs": {
97
+ "VALUE": [
98
+ 1,
99
+ "zeroShadowID"
100
+ ]
101
+ },
102
+ "next": "showScoreBlockID",
103
+ "parent": "switchBackdropBlockID",
104
+ "shadow": false,
105
+ "topLevel": false,
106
+ "x": 100,
107
+ "y": 50
108
+ },
109
+ "zeroShadowID": {
110
+ "opcode": "math_number",
111
+ "fields": {
112
+ "NUM": [
113
+ "0",
114
+ null
115
+ ]
116
+ },
117
+ "shadow": true,
118
+ "parent": "setScoreBlockID",
119
+ "topLevel": false
120
+ },
121
+ "showScoreBlockID": {
122
+ "opcode": "data_showvariable",
123
+ "fields": {
124
+ "VARIABLE": [
125
+ "score",
126
+ "score_73fce27a"
127
+ ]
128
+ },
129
+ "next": "broadcastBlockID",
130
+ "parent": "setScoreBlockID",
131
+ "shadow": false,
132
+ "topLevel": false,
133
+ "x": 100,
134
+ "y": 100
135
+ },
136
+ "broadcastBlockID": {
137
+ "opcode": "event_broadcast",
138
+ "inputs": {
139
+ "BROADCAST_INPUT": [
140
+ 1,
141
+ "gameStartBroadcastShadowID"
142
+ ]
143
+ },
144
+ "next": null,
145
+ "parent": "showScoreBlockID",
146
+ "shadow": false,
147
+ "topLevel": false,
148
+ "x": 100,
149
+ "y": 150
150
+ },
151
+ "gameStartBroadcastShadowID": {
152
+ "opcode": "event_broadcast_menu",
153
+ "fields": {
154
+ "BROADCAST": [
155
+ "Game Start",
156
+ "Game Start_ba9be238"
157
+ ]
158
+ },
159
+ "shadow": true,
160
+ "parent": "broadcastBlockID",
161
+ "topLevel": false
162
+ }
163
+ },
164
+ "comments": {},
165
+ "currentCostume": 0,
166
+ "costumes": [
167
+ {
168
+ "name": "Blue Sky",
169
+ "bitmapResolution": 1,
170
+ "dataFormat": "svg",
171
+ "assetId": "e7c147730f19d284bcd7b3f00af19bb6",
172
+ "md5ext": "e7c147730f19d284bcd7b3f00af19bb6.svg",
173
+ "rotationCenterX": 240,
174
+ "rotationCenterY": 180
175
+ }
176
+ ],
177
+ "sounds": [
178
+ {
179
+ "name": "button",
180
+ "dataFormat": "wav",
181
+ "rate": 44100,
182
+ "sampleCount": 0,
183
+ "assetId": "83a9787d4cb6f3b7632b4ddfebf74367",
184
+ "md5ext": "83a9787d4cb6f3b7632b4ddfebf74367.wav"
185
+ }
186
+ ],
187
+ "volume": 100,
188
+ "layerOrder": 0,
189
+ "tempo": 60,
190
+ "videoTransparency": 50,
191
+ "videoState": "on",
192
+ "textToSpeechLanguage": null
193
+ },
194
+ {
195
+ "isStage": false,
196
+ "name": "Sprite1",
197
+ "objName": "Sprite1",
198
+ "variables": {},
199
+ "lists": {},
200
+ "broadcasts": {},
201
+ "blocks": {
202
+ "hat_block_id": {
203
+ "opcode": "event_whenflagclicked",
204
+ "next": "goto_xy_block_id",
205
+ "parent": null,
206
+ "inputs": {},
207
+ "fields": {},
208
+ "shadow": false,
209
+ "topLevel": true,
210
+ "x": 0,
211
+ "y": 0
212
+ },
213
+ "goto_xy_block_id": {
214
+ "opcode": "motion_gotoxy",
215
+ "next": "set_lives_block_id",
216
+ "parent": "hat_block_id",
217
+ "inputs": {
218
+ "X": [
219
+ 1,
220
+ "x_shadow_block_id"
221
+ ],
222
+ "Y": [
223
+ 1,
224
+ "y_shadow_block_id"
225
+ ]
226
+ },
227
+ "fields": {},
228
+ "shadow": false,
229
+ "topLevel": false,
230
+ "x": 10,
231
+ "y": -50
232
+ },
233
+ "x_shadow_block_id": {
234
+ "opcode": "math_number",
235
+ "fields": {
236
+ "NUM": [
237
+ "0",
238
+ null
239
+ ]
240
+ },
241
+ "shadow": true,
242
+ "parent": "goto_xy_block_id",
243
+ "topLevel": false
244
+ },
245
+ "y_shadow_block_id": {
246
+ "opcode": "math_number",
247
+ "fields": {
248
+ "NUM": [
249
+ "-120",
250
+ null
251
+ ]
252
+ },
253
+ "shadow": true,
254
+ "parent": "goto_xy_block_id",
255
+ "topLevel": false
256
+ },
257
+ "set_lives_block_id": {
258
+ "opcode": "data_setvariableto",
259
+ "next": "set_score_block_id",
260
+ "parent": "goto_xy_block_id",
261
+ "inputs": {
262
+ "VARIABLE": [
263
+ 1,
264
+ "lives_variable_shadow_block_id"
265
+ ],
266
+ "VALUE": [
267
+ 1,
268
+ "lives_value_shadow_block_id"
269
+ ]
270
+ },
271
+ "fields": {},
272
+ "shadow": false,
273
+ "topLevel": false,
274
+ "x": 20,
275
+ "y": -100
276
+ },
277
+ "lives_variable_shadow_block_id": {
278
+ "opcode": "data_variable",
279
+ "fields": {
280
+ "VARIABLE": [
281
+ "lives",
282
+ "lives_9019623c"
283
+ ]
284
+ },
285
+ "shadow": true,
286
+ "parent": "set_lives_block_id",
287
+ "topLevel": false
288
+ },
289
+ "lives_value_shadow_block_id": {
290
+ "opcode": "math_number",
291
+ "fields": {
292
+ "NUM": [
293
+ "3",
294
+ null
295
+ ]
296
+ },
297
+ "shadow": true,
298
+ "parent": "set_lives_block_id",
299
+ "topLevel": false
300
+ },
301
+ "set_score_block_id": {
302
+ "opcode": "data_setvariableto",
303
+ "next": "show_score_block_id",
304
+ "parent": "set_lives_block_id",
305
+ "inputs": {
306
+ "VARIABLE": [
307
+ 1,
308
+ "score_variable_shadow_block_id"
309
+ ],
310
+ "VALUE": [
311
+ 1,
312
+ "score_value_shadow_block_id"
313
+ ]
314
+ },
315
+ "fields": {},
316
+ "shadow": false,
317
+ "topLevel": false,
318
+ "x": 30,
319
+ "y": -150
320
+ },
321
+ "score_variable_shadow_block_id": {
322
+ "opcode": "data_variable",
323
+ "fields": {
324
+ "VARIABLE": [
325
+ "score",
326
+ "score_73fce27a"
327
+ ]
328
+ },
329
+ "shadow": true,
330
+ "parent": "set_score_block_id",
331
+ "topLevel": false
332
+ },
333
+ "score_value_shadow_block_id": {
334
+ "opcode": "math_number",
335
+ "fields": {
336
+ "NUM": [
337
+ "0",
338
+ null
339
+ ]
340
+ },
341
+ "shadow": true,
342
+ "parent": "set_score_block_id",
343
+ "topLevel": false
344
+ },
345
+ "show_score_block_id": {
346
+ "opcode": "data_showvariable",
347
+ "next": "show_lives_block_id",
348
+ "parent": "set_score_block_id",
349
+ "inputs": {},
350
+ "fields": {
351
+ "VARIABLE": [
352
+ "score",
353
+ "score_73fce27a"
354
+ ]
355
+ },
356
+ "shadow": false,
357
+ "topLevel": false,
358
+ "x": 40,
359
+ "y": -200
360
+ },
361
+ "show_lives_block_id": {
362
+ "opcode": "data_showvariable",
363
+ "next": "broadcast_game_start_block_id",
364
+ "parent": "show_score_block_id",
365
+ "inputs": {},
366
+ "fields": {
367
+ "VARIABLE": [
368
+ "lives",
369
+ "lives_9019623c"
370
+ ]
371
+ },
372
+ "shadow": false,
373
+ "topLevel": false,
374
+ "x": 50,
375
+ "y": -250
376
+ },
377
+ "broadcast_game_start_block_id": {
378
+ "opcode": "event_broadcast",
379
+ "next": null,
380
+ "parent": "show_lives_block_id",
381
+ "inputs": {
382
+ "BROADCAST_INPUT": [
383
+ 1,
384
+ "game_start_broadcast_shadow_block_id"
385
+ ]
386
+ },
387
+ "fields": {},
388
+ "shadow": false,
389
+ "topLevel": false,
390
+ "x": 60,
391
+ "y": -300
392
+ },
393
+ "game_start_broadcast_shadow_block_id": {
394
+ "opcode": "event_broadcast_menu",
395
+ "fields": {
396
+ "BROADCAST": [
397
+ "Game Start",
398
+ "Game Start_ba9be238"
399
+ ]
400
+ },
401
+ "shadow": true,
402
+ "parent": "broadcast_game_start_block_id",
403
+ "topLevel": false
404
+ },
405
+ "event_whenkeypressed_1": {
406
+ "opcode": "event_whenkeypressed",
407
+ "next": "control_forever_2",
408
+ "parent": null,
409
+ "inputs": {},
410
+ "fields": {
411
+ "KEY_OPTION": [
412
+ "space",
413
+ null
414
+ ]
415
+ },
416
+ "shadow": false,
417
+ "topLevel": true,
418
+ "x": 0,
419
+ "y": 150
420
+ },
421
+ "control_forever_2": {
422
+ "opcode": "control_forever",
423
+ "next": null,
424
+ "parent": "event_whenkeypressed_1",
425
+ "inputs": {
426
+ "SUBSTACK": [
427
+ 2,
428
+ "sensing_keypressed_3"
429
+ ]
430
+ },
431
+ "shadow": false,
432
+ "topLevel": false,
433
+ "x": 10,
434
+ "y": -50
435
+ },
436
+ "sensing_keypressed_3": {
437
+ "opcode": "sensing_keypressed",
438
+ "next": "control_if_5",
439
+ "parent": "control_forever_2",
440
+ "inputs": {
441
+ "KEY": [
442
+ 1,
443
+ "space_shadow_4"
444
+ ]
445
+ },
446
+ "shadow": false,
447
+ "topLevel": false,
448
+ "x": 20,
449
+ "y": -100
450
+ },
451
+ "space_shadow_4": {
452
+ "opcode": "sensing_keypressed_menu",
453
+ "fields": {
454
+ "KEY": [
455
+ "space",
456
+ null
457
+ ]
458
+ },
459
+ "shadow": true,
460
+ "parent": "sensing_keypressed_3",
461
+ "topLevel": false
462
+ },
463
+ "control_if_5": {
464
+ "opcode": "control_if",
465
+ "next": "motion_changeyby_6",
466
+ "parent": "sensing_keypressed_3",
467
+ "inputs": {
468
+ "CONDITION": [
469
+ 1,
470
+ "operator_equals_7"
471
+ ],
472
+ "SUBSTACK": [
473
+ 2,
474
+ "motion_changeyby_6"
475
+ ]
476
+ },
477
+ "shadow": false,
478
+ "topLevel": false,
479
+ "x": 30,
480
+ "y": -150
481
+ },
482
+ "operator_equals_7": {
483
+ "opcode": "operator_equals",
484
+ "next": null,
485
+ "parent": "control_if_5",
486
+ "inputs": {
487
+ "OPERAND1": [
488
+ 1,
489
+ "data_variable_8"
490
+ ],
491
+ "OPERAND2": [
492
+ 1,
493
+ "literal_0_9"
494
+ ]
495
+ },
496
+ "shadow": false,
497
+ "topLevel": false,
498
+ "x": 40,
499
+ "y": -200
500
+ },
501
+ "data_variable_8": {
502
+ "opcode": "data_variable",
503
+ "fields": {
504
+ "VARIABLE": [
505
+ "lives",
506
+ "lives_9019623c"
507
+ ]
508
+ },
509
+ "shadow": true,
510
+ "parent": "operator_equals_7",
511
+ "topLevel": false
512
+ },
513
+ "literal_0_9": {
514
+ "opcode": "math_number",
515
+ "fields": {
516
+ "NUM": [
517
+ "0",
518
+ null
519
+ ]
520
+ },
521
+ "shadow": true,
522
+ "parent": "operator_equals_7",
523
+ "topLevel": false
524
+ },
525
+ "motion_changeyby_6": {
526
+ "opcode": "motion_changeyby",
527
+ "next": "wait_10",
528
+ "parent": "control_if_5",
529
+ "inputs": {
530
+ "DY": [
531
+ 1,
532
+ "literal_20_11"
533
+ ]
534
+ },
535
+ "shadow": false,
536
+ "topLevel": false,
537
+ "x": 40,
538
+ "y": -200
539
+ },
540
+ "literal_20_11": {
541
+ "opcode": "math_number",
542
+ "fields": {
543
+ "NUM": [
544
+ "20",
545
+ null
546
+ ]
547
+ },
548
+ "shadow": true,
549
+ "parent": "motion_changeyby_6",
550
+ "topLevel": false
551
+ },
552
+ "wait_10": {
553
+ "opcode": "wait",
554
+ "next": "motion_changeyby_12",
555
+ "parent": "motion_changeyby_6",
556
+ "inputs": {
557
+ "DURATION": [
558
+ 1,
559
+ "literal_0_1_13"
560
+ ]
561
+ },
562
+ "shadow": false,
563
+ "topLevel": false,
564
+ "x": 50,
565
+ "y": -250
566
+ },
567
+ "literal_0_1_13": {
568
+ "opcode": "math_number",
569
+ "fields": {
570
+ "NUM": [
571
+ "0.1",
572
+ null
573
+ ]
574
+ },
575
+ "shadow": true,
576
+ "parent": "wait_10",
577
+ "topLevel": false
578
+ },
579
+ "motion_changeyby_12": {
580
+ "opcode": "motion_changeyby",
581
+ "next": null,
582
+ "parent": "wait_10",
583
+ "inputs": {
584
+ "DY": [
585
+ 1,
586
+ "literal_-20_14"
587
+ ]
588
+ },
589
+ "shadow": false,
590
+ "topLevel": false,
591
+ "x": 60,
592
+ "y": -300
593
+ },
594
+ "literal_-20_14": {
595
+ "opcode": "math_number",
596
+ "fields": {
597
+ "NUM": [
598
+ "-20",
599
+ null
600
+ ]
601
+ },
602
+ "shadow": true,
603
+ "parent": "motion_changeyby_12",
604
+ "topLevel": false
605
+ },
606
+ "event_broadcast_15": {
607
+ "opcode": "event_broadcast",
608
+ "next": "control_stop_16",
609
+ "parent": "control_if_5",
610
+ "inputs": {
611
+ "BROADCAST_INPUT": [
612
+ 1,
613
+ "broadcast_game_over_17"
614
+ ]
615
+ },
616
+ "shadow": false,
617
+ "topLevel": false,
618
+ "x": 70,
619
+ "y": -350
620
+ },
621
+ "broadcast_game_over_17": {
622
+ "opcode": "event_broadcast_menu",
623
+ "fields": {
624
+ "BROADCAST": [
625
+ "Game Over",
626
+ "Game Over_9032e357"
627
+ ]
628
+ },
629
+ "shadow": true,
630
+ "parent": "event_broadcast_15",
631
+ "topLevel": false
632
+ },
633
+ "control_stop_16": {
634
+ "opcode": "control_stop",
635
+ "next": null,
636
+ "parent": "event_broadcast_15",
637
+ "inputs": {},
638
+ "fields": {
639
+ "STOP_OPTION": [
640
+ "all",
641
+ null
642
+ ]
643
+ },
644
+ "shadow": false,
645
+ "topLevel": false,
646
+ "x": 80,
647
+ "y": -400
648
+ }
649
+ },
650
+ "comments": {},
651
+ "currentCostume": 0,
652
+ "costumes": [
653
+ {
654
+ "name": "Sprite1",
655
+ "bitmapResolution": 1,
656
+ "dataFormat": "svg",
657
+ "assetId": "bcf454acf82e4504149f7ffe07081dbc",
658
+ "md5ext": "bcf454acf82e4504149f7ffe07081dbc.svg",
659
+ "rotationCenterX": 0,
660
+ "rotationCenterY": 0
661
+ }
662
+ ],
663
+ "sounds": [
664
+ {
665
+ "name": "meow",
666
+ "dataFormat": "wav",
667
+ "rate": 44100,
668
+ "sampleCount": 0,
669
+ "assetId": "83c36d806dc92327b9e7049a565c6bff",
670
+ "md5ext": "83c36d806dc92327b9e7049a565c6bff.wav"
671
+ }
672
+ ],
673
+ "volume": 100,
674
+ "layerOrder": 2,
675
+ "visible": true,
676
+ "x": 0,
677
+ "y": -120,
678
+ "size": 100,
679
+ "direction": 90,
680
+ "draggable": false,
681
+ "rotationStyle": "all around"
682
+ },
683
+ {
684
+ "isStage": false,
685
+ "name": "soccer ball",
686
+ "objName": "soccer ball",
687
+ "variables": {},
688
+ "lists": {},
689
+ "broadcasts": {},
690
+ "blocks": {
691
+ "event_whenflagclicked_1": {
692
+ "opcode": "event_whenflagclicked",
693
+ "next": "motion_gotoxy_2",
694
+ "parent": null,
695
+ "fields": {},
696
+ "shadow": false,
697
+ "topLevel": true,
698
+ "x": 0,
699
+ "y": 0
700
+ },
701
+ "motion_gotoxy_2": {
702
+ "opcode": "motion_gotoxy",
703
+ "inputs": {
704
+ "X": [
705
+ 1,
706
+ "motion_gotoxy_x_3"
707
+ ],
708
+ "Y": [
709
+ 1,
710
+ "motion_gotoxy_y_4"
711
+ ]
712
+ },
713
+ "next": "control_forever_5",
714
+ "parent": "event_whenflagclicked_1",
715
+ "fields": {},
716
+ "shadow": false,
717
+ "topLevel": false,
718
+ "x": 10,
719
+ "y": 50
720
+ },
721
+ "motion_gotoxy_x_3": {
722
+ "opcode": "math_number",
723
+ "fields": {
724
+ "NUM": [
725
+ "240",
726
+ null
727
+ ]
728
+ },
729
+ "shadow": true,
730
+ "parent": "motion_gotoxy_2",
731
+ "topLevel": false
732
+ },
733
+ "motion_gotoxy_y_4": {
734
+ "opcode": "math_number",
735
+ "fields": {
736
+ "NUM": [
737
+ "0",
738
+ null
739
+ ]
740
+ },
741
+ "shadow": true,
742
+ "parent": "motion_gotoxy_2",
743
+ "topLevel": false
744
+ },
745
+ "control_forever_5": {
746
+ "opcode": "control_forever",
747
+ "inputs": {
748
+ "SUBSTACK": [
749
+ 2,
750
+ "motion_glidesecstoxy_6"
751
+ ]
752
+ },
753
+ "next": null,
754
+ "parent": "motion_gotoxy_2",
755
+ "fields": {},
756
+ "shadow": false,
757
+ "topLevel": false,
758
+ "x": 20,
759
+ "y": 100
760
+ },
761
+ "motion_glidesecstoxy_6": {
762
+ "opcode": "motion_glidesecstoxy",
763
+ "inputs": {
764
+ "SECS": [
765
+ 1,
766
+ "motion_glidesecstoxy_secs_7"
767
+ ],
768
+ "X": [
769
+ 1,
770
+ "motion_glidesecstoxy_x_8"
771
+ ],
772
+ "Y": [
773
+ 1,
774
+ "motion_glidesecstoxy_y_9"
775
+ ]
776
+ },
777
+ "next": "control_if_10",
778
+ "parent": "control_forever_5",
779
+ "fields": {},
780
+ "shadow": false,
781
+ "topLevel": false,
782
+ "x": 30,
783
+ "y": 150
784
+ },
785
+ "motion_glidesecstoxy_secs_7": {
786
+ "opcode": "math_number",
787
+ "fields": {
788
+ "NUM": [
789
+ "2",
790
+ null
791
+ ]
792
+ },
793
+ "shadow": true,
794
+ "parent": "motion_glidesecstoxy_6",
795
+ "topLevel": false
796
+ },
797
+ "motion_glidesecstoxy_x_8": {
798
+ "opcode": "math_number",
799
+ "fields": {
800
+ "NUM": [
801
+ "-240",
802
+ null
803
+ ]
804
+ },
805
+ "shadow": true,
806
+ "parent": "motion_glidesecstoxy_6",
807
+ "topLevel": false
808
+ },
809
+ "motion_glidesecstoxy_y_9": {
810
+ "opcode": "math_number",
811
+ "fields": {
812
+ "NUM": [
813
+ "0",
814
+ null
815
+ ]
816
+ },
817
+ "shadow": true,
818
+ "parent": "motion_glidesecstoxy_6",
819
+ "topLevel": false
820
+ },
821
+ "control_if_10": {
822
+ "opcode": "control_if",
823
+ "inputs": {
824
+ "CONDITION": [
825
+ 1,
826
+ "sensing_touchingobject_11"
827
+ ],
828
+ "SUBSTACK": [
829
+ 2,
830
+ "control_if_12"
831
+ ]
832
+ },
833
+ "next": "data_changevariableby_13",
834
+ "parent": "motion_glidesecstoxy_6",
835
+ "fields": {},
836
+ "shadow": false,
837
+ "topLevel": false,
838
+ "x": 40,
839
+ "y": 200
840
+ },
841
+ "sensing_touchingobject_11": {
842
+ "opcode": "sensing_touchingobject",
843
+ "inputs": {
844
+ "TOUCHINGOBJECTMENU": [
845
+ 1,
846
+ "sensing_touchingobject_menu_14"
847
+ ]
848
+ },
849
+ "next": null,
850
+ "parent": "control_if_10",
851
+ "fields": {},
852
+ "shadow": false,
853
+ "topLevel": false
854
+ },
855
+ "sensing_touchingobject_menu_14": {
856
+ "opcode": "sensing_touchingobjectmenu",
857
+ "fields": {
858
+ "TOUCHINGOBJECTMENU": [
859
+ "Sprite1",
860
+ "Sprite1_15"
861
+ ]
862
+ },
863
+ "shadow": true,
864
+ "parent": "sensing_touchingobject_11",
865
+ "topLevel": false
866
+ },
867
+ "Sprite1_15": {
868
+ "isStage": false,
869
+ "name": "Sprite1",
870
+ "objName": "Sprite1",
871
+ "variables": {},
872
+ "lists": {},
873
+ "broadcasts": {},
874
+ "blocks": {},
875
+ "comments": {},
876
+ "currentCostume": 0,
877
+ "costumes": [
878
+ {
879
+ "name": "costume1",
880
+ "bitmapResolution": 1,
881
+ "dataFormat": "svg",
882
+ "assetId": "89f55f38-2e0a-40d6-8e8e-45d6d167cd2c",
883
+ "md5ext": "89f55f38-2e0a-40d6-8e8e-45d6d167cd2c.svg",
884
+ "rotationCenterX": 0,
885
+ "rotationCenterY": 0
886
+ }
887
+ ],
888
+ "sounds": [],
889
+ "volume": 100,
890
+ "layerOrder": 3,
891
+ "visible": true,
892
+ "x": 0,
893
+ "y": 0,
894
+ "size": 100,
895
+ "direction": 90,
896
+ "draggable": false,
897
+ "rotationStyle": "all around"
898
+ },
899
+ "control_if_12": {
900
+ "opcode": "control_if",
901
+ "inputs": {
902
+ "CONDITION": [
903
+ 1,
904
+ "operator_lt_16"
905
+ ],
906
+ "SUBSTACK": [
907
+ 2,
908
+ "data_changevariableby_17"
909
+ ]
910
+ },
911
+ "next": "event_broadcast_20",
912
+ "parent": "control_if_10",
913
+ "fields": {},
914
+ "shadow": false,
915
+ "topLevel": false,
916
+ "x": 50,
917
+ "y": 250
918
+ },
919
+ "operator_lt_16": {
920
+ "opcode": "operator_lt",
921
+ "inputs": {
922
+ "OPERAND1": [
923
+ 1,
924
+ "data_variable_18"
925
+ ],
926
+ "OPERAND2": [
927
+ 1,
928
+ "operator_lt_operand2_19"
929
+ ]
930
+ },
931
+ "next": null,
932
+ "parent": "control_if_12",
933
+ "fields": {},
934
+ "shadow": false,
935
+ "topLevel": false
936
+ },
937
+ "data_variable_18": {
938
+ "opcode": "data_variable",
939
+ "fields": {
940
+ "VARIABLE": [
941
+ "lives",
942
+ "lives_9019623c"
943
+ ]
944
+ },
945
+ "shadow": true,
946
+ "parent": "operator_lt_16",
947
+ "topLevel": false
948
+ },
949
+ "operator_lt_operand2_19": {
950
+ "opcode": "math_number",
951
+ "fields": {
952
+ "NUM": [
953
+ "0",
954
+ null
955
+ ]
956
+ },
957
+ "shadow": true,
958
+ "parent": "operator_lt_16",
959
+ "topLevel": false
960
+ },
961
+ "data_changevariableby_17": {
962
+ "opcode": "data_changevariableby",
963
+ "inputs": {
964
+ "VARIABLE": [
965
+ 1,
966
+ "data_changevariableby_variable_21"
967
+ ],
968
+ "VALUE": [
969
+ 1,
970
+ "data_changevariableby_value_22"
971
+ ]
972
+ },
973
+ "next": null,
974
+ "parent": "control_if_12",
975
+ "fields": {},
976
+ "shadow": false,
977
+ "topLevel": false,
978
+ "x": 60,
979
+ "y": 300
980
+ },
981
+ "data_changevariableby_variable_21": {
982
+ "opcode": "data_variable",
983
+ "fields": {
984
+ "VARIABLE": [
985
+ "lives",
986
+ "lives_9019623c"
987
+ ]
988
+ },
989
+ "shadow": true,
990
+ "parent": "data_changevariableby_17",
991
+ "topLevel": false
992
+ },
993
+ "data_changevariableby_value_22": {
994
+ "opcode": "math_number",
995
+ "fields": {
996
+ "NUM": [
997
+ "-1",
998
+ null
999
+ ]
1000
+ },
1001
+ "shadow": true,
1002
+ "parent": "data_changevariableby_17",
1003
+ "topLevel": false
1004
+ },
1005
+ "event_broadcast_20": {
1006
+ "opcode": "event_broadcast",
1007
+ "inputs": {
1008
+ "BROADCAST_INPUT": [
1009
+ 1,
1010
+ "event_broadcast_menu_23"
1011
+ ]
1012
+ },
1013
+ "next": "control_stop_24",
1014
+ "parent": "control_if_12",
1015
+ "fields": {},
1016
+ "shadow": false,
1017
+ "topLevel": false,
1018
+ "x": 70,
1019
+ "y": 350
1020
+ },
1021
+ "event_broadcast_menu_23": {
1022
+ "opcode": "event_broadcast_menu",
1023
+ "fields": {
1024
+ "BROADCAST": [
1025
+ "Game Over",
1026
+ "Game Over_9032e357"
1027
+ ]
1028
+ },
1029
+ "shadow": true,
1030
+ "parent": "event_broadcast_20",
1031
+ "topLevel": false
1032
+ },
1033
+ "control_stop_24": {
1034
+ "opcode": "control_stop",
1035
+ "inputs": {},
1036
+ "next": null,
1037
+ "parent": "event_broadcast_20",
1038
+ "fields": {
1039
+ "STOP_OPTION": [
1040
+ "all",
1041
+ null
1042
+ ]
1043
+ },
1044
+ "shadow": false,
1045
+ "topLevel": false,
1046
+ "x": 80,
1047
+ "y": 400
1048
+ }
1049
+ },
1050
+ "comments": {},
1051
+ "currentCostume": 0,
1052
+ "costumes": [
1053
+ {
1054
+ "name": "soccer ball",
1055
+ "bitmapResolution": 1,
1056
+ "dataFormat": "svg",
1057
+ "assetId": "5d973d7a3a8be3f3bd6e1cd0f73c32b5",
1058
+ "md5ext": "5d973d7a3a8be3f3bd6e1cd0f73c32b5.svg",
1059
+ "rotationCenterX": 0,
1060
+ "rotationCenterY": 0
1061
+ }
1062
+ ],
1063
+ "sounds": [],
1064
+ "volume": 100,
1065
+ "layerOrder": 3,
1066
+ "visible": true,
1067
+ "x": 130,
1068
+ "y": 0,
1069
+ "size": 100,
1070
+ "direction": 90,
1071
+ "draggable": false,
1072
+ "rotationStyle": "all around"
1073
+ }
1074
+ ],
1075
+ "monitors": [
1076
+ {
1077
+ "id": "monitor_123e456",
1078
+ "opcode": "data_variable",
1079
+ "spriteName": "Stage",
1080
+ "params": {
1081
+ "VARIABLE": "score"
1082
+ },
1083
+ "value": "0",
1084
+ "x": 5,
1085
+ "y": 5,
1086
+ "visible": true,
1087
+ "mode": "default",
1088
+ "sliderMin": 0,
1089
+ "sliderMax": 100,
1090
+ "isDiscrete": true
1091
+ },
1092
+ {
1093
+ "id": "monitor_987654321",
1094
+ "opcode": "data_variable",
1095
+ "spriteName": "Stage",
1096
+ "params": {
1097
+ "VARIABLE": "☁ High Score"
1098
+ },
1099
+ "value": "0",
1100
+ "x": 325,
1101
+ "y": 5,
1102
+ "visible": true,
1103
+ "mode": "default",
1104
+ "sliderMin": 0,
1105
+ "sliderMax": 100,
1106
+ "isDiscrete": true
1107
+ }
1108
+ ],
1109
+ "extensions": [],
1110
+ "meta": {
1111
+ "semver": "3.0.0",
1112
+ "vm": "11.1.0",
1113
+ "agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36"
1114
+ }
1115
+ },
1116
+ "description": "**Game Title: Whisker Wonders - Cat Jump**\n\nIn **Whisker Wonders - Cat Jump**, you control a nimble cat named **Sprite1** as it navigates through a vibrant, obstacle-filled world set against the beautiful backdrop of a **Blue Sky**. Your goal is to guide your feline friend, **Sprite1**, through the sky, jumping over incoming obstacles to reach the highest score possible.\n\n**Gameplay Overview:**\n\n- **Objective:** Control **Sprite1** to jump over obstacles, such as a rolling **soccer ball**, to survive and accumulate points.\n- **Environment:** The game takes place on the **Stage**, which features a serene **Blue Sky** backdrop. The sky transitions through different times of day or weather conditions could be added for variety.\n- **Game Mechanics:** \n - **Sprite1** can move left and right and jump over obstacles.\n - The **soccer ball** obstacle moves across the screen from right to left at varying speeds, requiring precise timing for **Sprite1** to jump over.\n - Points are awarded for each obstacle successfully jumped over.\n\n**Potential Gameplay Elements:**\n\n- **Score System:** Implement a scoring system where points are awarded for each obstacle cleared. Higher scores could unlock new costumes for **Sprite1** or background changes for the **Stage**.\n- **Power-Ups:** Introduce power-ups like temporary invincibility, increased jump height, or score multipliers that **Sprite1** can collect by jumping into them.\n- **Levels:** Design multiple levels with increasing difficulty, such as changing obstacle speeds, introducing multiple obstacles at once, or altering the **Stage**'s background to simulate different environments (e.g., night, clouds).\n- **Sound Effects and Music:** Utilize the provided sound effects (`\"meow\"`, `\"button\"`) and consider adding background music to enhance the game's atmosphere. Sound effects could be triggered for actions like jumping, collecting power-ups, or hitting an obstacle.\n\n**Objectives:**\n\n- Survive as long as possible by jumping over obstacles.\n- Achieve the highest score by clearing obstacles efficiently.\n- Unlock new content (costumes, backgrounds) through high scores or achievements.\n\n**Overall Feel:**\n\n- **Whisker Wonders - Cat Jump** aims to be a fun, challenging platformer with simple controls and progressively increasing difficulty.\n- The game's colorful graphics, coupled with engaging sound effects and music, create an inviting atmosphere for players of all ages.\n- The simplicity of the game makes it accessible, while the challenge of achieving high scores encourages replayability.\n\n**Future Enhancements:**\n\n- **User-Created Content:** Allow players to create and share their own levels or obstacle courses.\n- **Multiplayer:** Introduce a competitive mode where players can compete to achieve the highest score or survive the longest.\n- **Customization:** Enable players to customize **Sprite1**'s appearance with various costumes and accessories.\n\n**Whisker Wonders - Cat Jump** combines classic platforming elements with engaging gameplay and cute, memorable characters, making it a delightful experience for players looking for a fun challenge.",
1117
+ "project_id": "148cec44-05b5-4562-b06e-b92c64d1ca9e",
1118
+ "sprite_initial_positions": {},
1119
+ "action_plan": {
1120
+ "Sprite1": {
1121
+ "description": "Main character (cat) actions",
1122
+ "plans": [
1123
+ {
1124
+ "event": "event_whenflagclicked",
1125
+ "logic": "go to x:0 y:-120; set lives to 3; set score to 0; show variable score; show variable lives; broadcast Game Start;",
1126
+ "motion": [
1127
+ "motion_gotoxy",
1128
+ "motion_setx",
1129
+ "motion_sety"
1130
+ ],
1131
+ "control": [],
1132
+ "operator": [],
1133
+ "sensing": [],
1134
+ "looks": [],
1135
+ "sounds": [],
1136
+ "events": [
1137
+ "event_broadcast"
1138
+ ],
1139
+ "data": [
1140
+ "data_setvariableto",
1141
+ "data_showvariable"
1142
+ ],
1143
+ "block_relationships": [
1144
+ {
1145
+ "type": "stacked",
1146
+ "blocks": [
1147
+ "event_whenflagclicked",
1148
+ "motion_gotoxy",
1149
+ "data_setvariableto",
1150
+ "data_setvariableto",
1151
+ "looks_showvariable",
1152
+ "looks_showvariable",
1153
+ "events_broadcast"
1154
+ ]
1155
+ },
1156
+ {
1157
+ "type": "nested_literal_input",
1158
+ "parent_opcode": "motion_gotoxy",
1159
+ "input_slot_name": "X",
1160
+ "value": "0"
1161
+ },
1162
+ {
1163
+ "type": "nested_literal_input",
1164
+ "parent_opcode": "motion_gotoxy",
1165
+ "input_slot_name": "Y",
1166
+ "value": "-120"
1167
+ },
1168
+ {
1169
+ "type": "nested_literal_input",
1170
+ "parent_opcode": "data_setvariableto",
1171
+ "input_slot_name": "VALUE",
1172
+ "value": "3"
1173
+ },
1174
+ {
1175
+ "type": "nested_literal_input",
1176
+ "parent_opcode": "data_setvariableto",
1177
+ "input_slot_name": "VARIABLE",
1178
+ "value": "lives"
1179
+ },
1180
+ {
1181
+ "type": "nested_literal_input",
1182
+ "parent_opcode": "data_setvariableto",
1183
+ "input_slot_name": "VALUE",
1184
+ "value": "0"
1185
+ },
1186
+ {
1187
+ "type": "nested_literal_input",
1188
+ "parent_opcode": "data_setvariableto",
1189
+ "input_slot_name": "VARIABLE",
1190
+ "value": "score"
1191
+ },
1192
+ {
1193
+ "type": "nested_literal_input",
1194
+ "parent_opcode": "events_broadcast",
1195
+ "input_slot_name": "BROADCAST",
1196
+ "value": "Game Start"
1197
+ }
1198
+ ]
1199
+ },
1200
+ {
1201
+ "event": "event_whenkeypressed",
1202
+ "logic": "forever: if key space is pressed, then change y by 20; wait 0.1 seconds; change y by -20; if lives = 0, then broadcast Game Over; stop all;",
1203
+ "motion": [
1204
+ "motion_changeyby"
1205
+ ],
1206
+ "control": [
1207
+ "control_forever",
1208
+ "control_if",
1209
+ "control_stop"
1210
+ ],
1211
+ "operator": [
1212
+ "operator_equals"
1213
+ ],
1214
+ "sensing": [
1215
+ "sensing_keypressed"
1216
+ ],
1217
+ "looks": [],
1218
+ "sounds": [],
1219
+ "events": [
1220
+ "event_broadcast"
1221
+ ],
1222
+ "data": [
1223
+ "data_variable"
1224
+ ],
1225
+ "block_relationships": [
1226
+ {
1227
+ "type": "stacked",
1228
+ "blocks": [
1229
+ "event_whenkeypressed",
1230
+ "control_forever"
1231
+ ]
1232
+ },
1233
+ {
1234
+ "type": "nested_c_block_body",
1235
+ "parent": "control_forever",
1236
+ "child_opcodes": [
1237
+ "sensing_keypressed",
1238
+ "control_if"
1239
+ ]
1240
+ },
1241
+ {
1242
+ "type": "nested_input",
1243
+ "parent_opcode": "sensing_keypressed",
1244
+ "input_slot_name": "KEY",
1245
+ "value": "space"
1246
+ },
1247
+ {
1248
+ "type": "stacked",
1249
+ "blocks": [
1250
+ "motion_changeyby",
1251
+ "wait",
1252
+ "motion_changeyby"
1253
+ ]
1254
+ },
1255
+ {
1256
+ "type": "nested_literal_input",
1257
+ "parent_opcode": "motion_changeyby",
1258
+ "input_slot_name": "DISTANCE",
1259
+ "value": "20"
1260
+ },
1261
+ {
1262
+ "type": "nested_literal_input",
1263
+ "parent_opcode": "wait",
1264
+ "input_slot_name": "DURATION",
1265
+ "value": "0.1"
1266
+ },
1267
+ {
1268
+ "type": "nested_literal_input",
1269
+ "parent_opcode": "motion_changeyby",
1270
+ "input_slot_name": "DISTANCE",
1271
+ "value": "-20"
1272
+ },
1273
+ {
1274
+ "type": "nested_c_block_body",
1275
+ "parent": "control_if",
1276
+ "child_opcodes": [
1277
+ "operator_equals",
1278
+ "data_variable"
1279
+ ]
1280
+ },
1281
+ {
1282
+ "type": "nested_input",
1283
+ "parent_opcode": "operator_equals",
1284
+ "input_slot_name": "OPERAND1",
1285
+ "child_opcode": "data_variable"
1286
+ },
1287
+ {
1288
+ "type": "nested_literal_input",
1289
+ "parent_opcode": "operator_equals",
1290
+ "input_slot_name": "OPERAND2",
1291
+ "value": "0"
1292
+ },
1293
+ {
1294
+ "type": "stacked",
1295
+ "blocks": [
1296
+ "event_broadcast",
1297
+ "control_stop"
1298
+ ]
1299
+ },
1300
+ {
1301
+ "type": "nested_literal_input",
1302
+ "parent_opcode": "event_broadcast",
1303
+ "input_slot_name": "BROADCAST",
1304
+ "value": "Game Over"
1305
+ }
1306
+ ]
1307
+ }
1308
+ ]
1309
+ },
1310
+ "soccer ball": {
1311
+ "description": "Obstacle movement and interaction",
1312
+ "plans": [
1313
+ {
1314
+ "event": "event_whenflagclicked",
1315
+ "logic": "go to x:240 y:0; forever: glide 2 seconds to x:-240 y:0; if touching Sprite1, then change lives by -1; if lives < 0, then broadcast Game Over; stop all;",
1316
+ "motion": [
1317
+ "motion_gotoxy",
1318
+ "motion_glidesecstoxy"
1319
+ ],
1320
+ "control": [
1321
+ "control_forever",
1322
+ "control_if",
1323
+ "control_stop"
1324
+ ],
1325
+ "operator": [
1326
+ "operator_lt"
1327
+ ],
1328
+ "sensing": [
1329
+ "sensing_touchingobject"
1330
+ ],
1331
+ "looks": [],
1332
+ "sounds": [],
1333
+ "events": [
1334
+ "event_broadcast"
1335
+ ],
1336
+ "data": [
1337
+ "data_changevariableby"
1338
+ ],
1339
+ "block_relationships": [
1340
+ {
1341
+ "type": "stacked",
1342
+ "blocks": [
1343
+ "event_whenflagclicked",
1344
+ "motion_gotoxy",
1345
+ "control_forever"
1346
+ ]
1347
+ },
1348
+ {
1349
+ "type": "nested_c_block_body",
1350
+ "parent": "control_forever",
1351
+ "child_opcodes": [
1352
+ "motion_glidesecstoxy",
1353
+ "control_if",
1354
+ "control_if",
1355
+ "event_broadcast",
1356
+ "control_stop"
1357
+ ]
1358
+ },
1359
+ {
1360
+ "type": "nested_input",
1361
+ "parent_opcode": "motion_glidesecstoxy",
1362
+ "input_slot_name": "X",
1363
+ "value": "-240"
1364
+ },
1365
+ {
1366
+ "type": "nested_input",
1367
+ "parent_opcode": "motion_glidesecstoxy",
1368
+ "input_slot_name": "Y",
1369
+ "value": "0"
1370
+ },
1371
+ {
1372
+ "type": "nested_input",
1373
+ "parent_opcode": "motion_glidesecstoxy",
1374
+ "input_slot_name": "SECS",
1375
+ "value": "2"
1376
+ },
1377
+ {
1378
+ "type": "nested_input",
1379
+ "parent_opcode": "control_if",
1380
+ "input_slot_name": "CONDITION",
1381
+ "child_opcode": "sensing_touchingobject"
1382
+ },
1383
+ {
1384
+ "type": "nested_input",
1385
+ "parent_opcode": "control_if",
1386
+ "input_slot_name": "CONDITION",
1387
+ "child_opcode": "operator_lt"
1388
+ },
1389
+ {
1390
+ "type": "nested_c_block_body",
1391
+ "parent": "control_if",
1392
+ "child_opcodes": [
1393
+ "data_changevariableby"
1394
+ ]
1395
+ },
1396
+ {
1397
+ "type": "nested_input",
1398
+ "parent_opcode": "data_changevariableby",
1399
+ "input_slot_name": "VARIABLE",
1400
+ "value": "lives"
1401
+ },
1402
+ {
1403
+ "type": "nested_input",
1404
+ "parent_opcode": "data_changevariableby",
1405
+ "input_slot_name": "VALUE",
1406
+ "value": "-1"
1407
+ },
1408
+ {
1409
+ "type": "nested_input",
1410
+ "parent_opcode": "operator_lt",
1411
+ "input_slot_name": "OPERAND1",
1412
+ "value": "lives"
1413
+ },
1414
+ {
1415
+ "type": "nested_input",
1416
+ "parent_opcode": "operator_lt",
1417
+ "input_slot_name": "OPERAND2",
1418
+ "value": "0"
1419
+ },
1420
+ {
1421
+ "type": "nested_input",
1422
+ "parent_opcode": "event_broadcast",
1423
+ "input_slot_name": "BROADCAST",
1424
+ "value": "Game Over"
1425
+ }
1426
+ ]
1427
+ }
1428
+ ]
1429
+ },
1430
+ "Stage": {
1431
+ "description": "Background and global game state management, including broadcasts, rewards, and score.",
1432
+ "plans": [
1433
+ {
1434
+ "event": "event_whenflagclicked",
1435
+ "logic": "switch backdrop to Blue Sky; set score to 0; show variable score; broadcast Game Start;",
1436
+ "motion": [],
1437
+ "control": [],
1438
+ "operator": [],
1439
+ "sensing": [],
1440
+ "looks": [
1441
+ "looks_switchbackdropto"
1442
+ ],
1443
+ "sounds": [],
1444
+ "events": [
1445
+ "event_broadcast"
1446
+ ],
1447
+ "data": [
1448
+ "data_setvariableto",
1449
+ "data_showvariable"
1450
+ ],
1451
+ "block_relationships": [
1452
+ {
1453
+ "type": "stacked",
1454
+ "blocks": [
1455
+ "event_whenflagclicked",
1456
+ "looks_switchbackdropto",
1457
+ "data_setvariableto",
1458
+ "data_showvariable",
1459
+ "event_broadcast"
1460
+ ]
1461
+ },
1462
+ {
1463
+ "type": "nested_literal_input",
1464
+ "parent_opcode": "looks_switchbackdropto",
1465
+ "input_slot_name": "BACKDROP",
1466
+ "value": "Blue Sky"
1467
+ },
1468
+ {
1469
+ "type": "nested_literal_input",
1470
+ "parent_opcode": "data_setvariableto",
1471
+ "input_slot_name": "VALUE",
1472
+ "value": "0"
1473
+ },
1474
+ {
1475
+ "type": "nested_literal_input",
1476
+ "parent_opcode": "event_broadcast",
1477
+ "input_slot_name": "BROADCAST",
1478
+ "value": "Game Start"
1479
+ }
1480
+ ]
1481
+ },
1482
+ {
1483
+ "event": "event_whenbroadcastreceived",
1484
+ "logic": "if score > High Score, then set High Score to score; switch backdrop to congratulatory backdrop; broadcast Level Up;",
1485
+ "motion": [],
1486
+ "control": [
1487
+ "control_if"
1488
+ ],
1489
+ "operator": [
1490
+ "operator_gt"
1491
+ ],
1492
+ "sensing": [],
1493
+ "looks": [
1494
+ "looks_switchbackdropto"
1495
+ ],
1496
+ "sounds": [],
1497
+ "events": [
1498
+ "event_broadcast"
1499
+ ],
1500
+ "data": [
1501
+ "data_setvariableto"
1502
+ ],
1503
+ "block_relationships": [
1504
+ {
1505
+ "type": "stacked",
1506
+ "blocks": [
1507
+ "event_whenbroadcastreceived",
1508
+ "control_if"
1509
+ ]
1510
+ },
1511
+ {
1512
+ "type": "nested_c_block_body",
1513
+ "parent": "control_if",
1514
+ "child_opcodes": [
1515
+ "operator_gt",
1516
+ "data_setvariableto",
1517
+ "looks_switchbackdropto",
1518
+ "event_broadcast"
1519
+ ]
1520
+ },
1521
+ {
1522
+ "type": "nested_input",
1523
+ "parent_opcode": "operator_gt",
1524
+ "input_slot_name": "",
1525
+ "child_opcodes": [
1526
+ "data_variable",
1527
+ "data_variable"
1528
+ ]
1529
+ },
1530
+ {
1531
+ "type": "nested_literal_input",
1532
+ "parent_opcode": "event_broadcast",
1533
+ "input_slot_name": "BROADCAST",
1534
+ "value": "Level Up"
1535
+ },
1536
+ {
1537
+ "type": "nested_input",
1538
+ "parent_opcode": "control_if",
1539
+ "input_slot_name": "CONDITION",
1540
+ "child_opcode": "operator_gt"
1541
+ },
1542
+ {
1543
+ "type": "nested_input",
1544
+ "parent_opcode": "data_setvariableto",
1545
+ "input_slot_name": "VALUE",
1546
+ "child_opcode": "data_variable"
1547
+ }
1548
+ ]
1549
+ }
1550
+ ]
1551
+ },
1552
+ "action_overall_flow": {
1553
+ "Sprite1": {
1554
+ "description": "Main character (cat) actions",
1555
+ "plans": [
1556
+ {
1557
+ "event": "event_whenflagclicked",
1558
+ "logic": "go to x:0 y:-120; set lives to 3; set score to 0; show variable score; show variable lives; broadcast Game Start;",
1559
+ "motion": [
1560
+ "motion_gotoxy",
1561
+ "motion_setx",
1562
+ "motion_sety"
1563
+ ],
1564
+ "control": [],
1565
+ "operator": [],
1566
+ "sensing": [],
1567
+ "looks": [],
1568
+ "sounds": [],
1569
+ "events": [
1570
+ "event_broadcast"
1571
+ ],
1572
+ "data": [
1573
+ "data_setvariableto",
1574
+ "data_showvariable"
1575
+ ],
1576
+ "block_relationships": [
1577
+ {
1578
+ "type": "stacked",
1579
+ "blocks": [
1580
+ "event_whenflagclicked",
1581
+ "motion_gotoxy",
1582
+ "data_setvariableto",
1583
+ "data_setvariableto",
1584
+ "looks_showvariable",
1585
+ "looks_showvariable",
1586
+ "events_broadcast"
1587
+ ]
1588
+ },
1589
+ {
1590
+ "type": "nested_literal_input",
1591
+ "parent_opcode": "motion_gotoxy",
1592
+ "input_slot_name": "X",
1593
+ "value": "0"
1594
+ },
1595
+ {
1596
+ "type": "nested_literal_input",
1597
+ "parent_opcode": "motion_gotoxy",
1598
+ "input_slot_name": "Y",
1599
+ "value": "-120"
1600
+ },
1601
+ {
1602
+ "type": "nested_literal_input",
1603
+ "parent_opcode": "data_setvariableto",
1604
+ "input_slot_name": "VALUE",
1605
+ "value": "3"
1606
+ },
1607
+ {
1608
+ "type": "nested_literal_input",
1609
+ "parent_opcode": "data_setvariableto",
1610
+ "input_slot_name": "VARIABLE",
1611
+ "value": "lives"
1612
+ },
1613
+ {
1614
+ "type": "nested_literal_input",
1615
+ "parent_opcode": "data_setvariableto",
1616
+ "input_slot_name": "VALUE",
1617
+ "value": "0"
1618
+ },
1619
+ {
1620
+ "type": "nested_literal_input",
1621
+ "parent_opcode": "data_setvariableto",
1622
+ "input_slot_name": "VARIABLE",
1623
+ "value": "score"
1624
+ },
1625
+ {
1626
+ "type": "nested_literal_input",
1627
+ "parent_opcode": "events_broadcast",
1628
+ "input_slot_name": "BROADCAST",
1629
+ "value": "Game Start"
1630
+ }
1631
+ ]
1632
+ },
1633
+ {
1634
+ "event": "event_whenkeypressed",
1635
+ "logic": "forever: if key space is pressed, then change y by 20; wait 0.1 seconds; change y by -20; if lives = 0, then broadcast Game Over; stop all;",
1636
+ "motion": [
1637
+ "motion_changeyby"
1638
+ ],
1639
+ "control": [
1640
+ "control_forever",
1641
+ "control_if",
1642
+ "control_stop"
1643
+ ],
1644
+ "operator": [
1645
+ "operator_equals"
1646
+ ],
1647
+ "sensing": [
1648
+ "sensing_keypressed"
1649
+ ],
1650
+ "looks": [],
1651
+ "sounds": [],
1652
+ "events": [
1653
+ "event_broadcast"
1654
+ ],
1655
+ "data": [
1656
+ "data_variable"
1657
+ ],
1658
+ "block_relationships": [
1659
+ {
1660
+ "type": "stacked",
1661
+ "blocks": [
1662
+ "event_whenkeypressed",
1663
+ "control_forever"
1664
+ ]
1665
+ },
1666
+ {
1667
+ "type": "nested_c_block_body",
1668
+ "parent": "control_forever",
1669
+ "child_opcodes": [
1670
+ "sensing_keypressed",
1671
+ "control_if"
1672
+ ]
1673
+ },
1674
+ {
1675
+ "type": "nested_input",
1676
+ "parent_opcode": "sensing_keypressed",
1677
+ "input_slot_name": "KEY",
1678
+ "value": "space"
1679
+ },
1680
+ {
1681
+ "type": "stacked",
1682
+ "blocks": [
1683
+ "motion_changeyby",
1684
+ "wait",
1685
+ "motion_changeyby"
1686
+ ]
1687
+ },
1688
+ {
1689
+ "type": "nested_literal_input",
1690
+ "parent_opcode": "motion_changeyby",
1691
+ "input_slot_name": "DISTANCE",
1692
+ "value": "20"
1693
+ },
1694
+ {
1695
+ "type": "nested_literal_input",
1696
+ "parent_opcode": "wait",
1697
+ "input_slot_name": "DURATION",
1698
+ "value": "0.1"
1699
+ },
1700
+ {
1701
+ "type": "nested_literal_input",
1702
+ "parent_opcode": "motion_changeyby",
1703
+ "input_slot_name": "DISTANCE",
1704
+ "value": "-20"
1705
+ },
1706
+ {
1707
+ "type": "nested_c_block_body",
1708
+ "parent": "control_if",
1709
+ "child_opcodes": [
1710
+ "operator_equals",
1711
+ "data_variable"
1712
+ ]
1713
+ },
1714
+ {
1715
+ "type": "nested_input",
1716
+ "parent_opcode": "operator_equals",
1717
+ "input_slot_name": "OPERAND1",
1718
+ "child_opcode": "data_variable"
1719
+ },
1720
+ {
1721
+ "type": "nested_literal_input",
1722
+ "parent_opcode": "operator_equals",
1723
+ "input_slot_name": "OPERAND2",
1724
+ "value": "0"
1725
+ },
1726
+ {
1727
+ "type": "stacked",
1728
+ "blocks": [
1729
+ "event_broadcast",
1730
+ "control_stop"
1731
+ ]
1732
+ },
1733
+ {
1734
+ "type": "nested_literal_input",
1735
+ "parent_opcode": "event_broadcast",
1736
+ "input_slot_name": "BROADCAST",
1737
+ "value": "Game Over"
1738
+ }
1739
+ ]
1740
+ }
1741
+ ]
1742
+ },
1743
+ "soccer ball": {
1744
+ "description": "Obstacle movement and interaction",
1745
+ "plans": [
1746
+ {
1747
+ "event": "event_whenflagclicked",
1748
+ "logic": "go to x:240 y:0; forever: glide 2 seconds to x:-240 y:0; if touching Sprite1, then change lives by -1; if lives < 0, then broadcast Game Over; stop all;",
1749
+ "motion": [
1750
+ "motion_gotoxy",
1751
+ "motion_glidesecstoxy"
1752
+ ],
1753
+ "control": [
1754
+ "control_forever",
1755
+ "control_if",
1756
+ "control_stop"
1757
+ ],
1758
+ "operator": [
1759
+ "operator_lt"
1760
+ ],
1761
+ "sensing": [
1762
+ "sensing_touchingobject"
1763
+ ],
1764
+ "looks": [],
1765
+ "sounds": [],
1766
+ "events": [
1767
+ "event_broadcast"
1768
+ ],
1769
+ "data": [
1770
+ "data_changevariableby"
1771
+ ],
1772
+ "block_relationships": [
1773
+ {
1774
+ "type": "stacked",
1775
+ "blocks": [
1776
+ "event_whenflagclicked",
1777
+ "motion_gotoxy",
1778
+ "control_forever"
1779
+ ]
1780
+ },
1781
+ {
1782
+ "type": "nested_c_block_body",
1783
+ "parent": "control_forever",
1784
+ "child_opcodes": [
1785
+ "motion_glidesecstoxy",
1786
+ "control_if",
1787
+ "control_if",
1788
+ "event_broadcast",
1789
+ "control_stop"
1790
+ ]
1791
+ },
1792
+ {
1793
+ "type": "nested_input",
1794
+ "parent_opcode": "motion_glidesecstoxy",
1795
+ "input_slot_name": "X",
1796
+ "value": "-240"
1797
+ },
1798
+ {
1799
+ "type": "nested_input",
1800
+ "parent_opcode": "motion_glidesecstoxy",
1801
+ "input_slot_name": "Y",
1802
+ "value": "0"
1803
+ },
1804
+ {
1805
+ "type": "nested_input",
1806
+ "parent_opcode": "motion_glidesecstoxy",
1807
+ "input_slot_name": "SECS",
1808
+ "value": "2"
1809
+ },
1810
+ {
1811
+ "type": "nested_input",
1812
+ "parent_opcode": "control_if",
1813
+ "input_slot_name": "CONDITION",
1814
+ "child_opcode": "sensing_touchingobject"
1815
+ },
1816
+ {
1817
+ "type": "nested_input",
1818
+ "parent_opcode": "control_if",
1819
+ "input_slot_name": "CONDITION",
1820
+ "child_opcode": "operator_lt"
1821
+ },
1822
+ {
1823
+ "type": "nested_c_block_body",
1824
+ "parent": "control_if",
1825
+ "child_opcodes": [
1826
+ "data_changevariableby"
1827
+ ]
1828
+ },
1829
+ {
1830
+ "type": "nested_input",
1831
+ "parent_opcode": "data_changevariableby",
1832
+ "input_slot_name": "VARIABLE",
1833
+ "value": "lives"
1834
+ },
1835
+ {
1836
+ "type": "nested_input",
1837
+ "parent_opcode": "data_changevariableby",
1838
+ "input_slot_name": "VALUE",
1839
+ "value": "-1"
1840
+ },
1841
+ {
1842
+ "type": "nested_input",
1843
+ "parent_opcode": "operator_lt",
1844
+ "input_slot_name": "OPERAND1",
1845
+ "value": "lives"
1846
+ },
1847
+ {
1848
+ "type": "nested_input",
1849
+ "parent_opcode": "operator_lt",
1850
+ "input_slot_name": "OPERAND2",
1851
+ "value": "0"
1852
+ },
1853
+ {
1854
+ "type": "nested_input",
1855
+ "parent_opcode": "event_broadcast",
1856
+ "input_slot_name": "BROADCAST",
1857
+ "value": "Game Over"
1858
+ }
1859
+ ]
1860
+ }
1861
+ ]
1862
+ },
1863
+ "Stage": {
1864
+ "description": "Background and global game state management, including broadcasts, rewards, and score.",
1865
+ "plans": [
1866
+ {
1867
+ "event": "event_whenflagclicked",
1868
+ "logic": "switch backdrop to Blue Sky; set score to 0; show variable score; broadcast Game Start;",
1869
+ "motion": [],
1870
+ "control": [],
1871
+ "operator": [],
1872
+ "sensing": [],
1873
+ "looks": [
1874
+ "looks_switchbackdropto"
1875
+ ],
1876
+ "sounds": [],
1877
+ "events": [
1878
+ "event_broadcast"
1879
+ ],
1880
+ "data": [
1881
+ "data_setvariableto",
1882
+ "data_showvariable"
1883
+ ],
1884
+ "block_relationships": [
1885
+ {
1886
+ "type": "stacked",
1887
+ "blocks": [
1888
+ "event_whenflagclicked",
1889
+ "looks_switchbackdropto",
1890
+ "data_setvariableto",
1891
+ "data_showvariable",
1892
+ "event_broadcast"
1893
+ ]
1894
+ },
1895
+ {
1896
+ "type": "nested_literal_input",
1897
+ "parent_opcode": "looks_switchbackdropto",
1898
+ "input_slot_name": "BACKDROP",
1899
+ "value": "Blue Sky"
1900
+ },
1901
+ {
1902
+ "type": "nested_literal_input",
1903
+ "parent_opcode": "data_setvariableto",
1904
+ "input_slot_name": "VALUE",
1905
+ "value": "0"
1906
+ },
1907
+ {
1908
+ "type": "nested_literal_input",
1909
+ "parent_opcode": "event_broadcast",
1910
+ "input_slot_name": "BROADCAST",
1911
+ "value": "Game Start"
1912
+ }
1913
+ ]
1914
+ },
1915
+ {
1916
+ "event": "event_whenbroadcastreceived",
1917
+ "logic": "if score > High Score, then set High Score to score; switch backdrop to congratulatory backdrop; broadcast Level Up;",
1918
+ "motion": [],
1919
+ "control": [
1920
+ "control_if"
1921
+ ],
1922
+ "operator": [
1923
+ "operator_gt"
1924
+ ],
1925
+ "sensing": [],
1926
+ "looks": [
1927
+ "looks_switchbackdropto"
1928
+ ],
1929
+ "sounds": [],
1930
+ "events": [
1931
+ "event_broadcast"
1932
+ ],
1933
+ "data": [
1934
+ "data_setvariableto"
1935
+ ],
1936
+ "block_relationships": [
1937
+ {
1938
+ "type": "stacked",
1939
+ "blocks": [
1940
+ "event_whenbroadcastreceived",
1941
+ "control_if"
1942
+ ]
1943
+ },
1944
+ {
1945
+ "type": "nested_c_block_body",
1946
+ "parent": "control_if",
1947
+ "child_opcodes": [
1948
+ "operator_gt",
1949
+ "data_setvariableto",
1950
+ "looks_switchbackdropto",
1951
+ "event_broadcast"
1952
+ ]
1953
+ },
1954
+ {
1955
+ "type": "nested_input",
1956
+ "parent_opcode": "operator_gt",
1957
+ "input_slot_name": "",
1958
+ "child_opcodes": [
1959
+ "data_variable",
1960
+ "data_variable"
1961
+ ]
1962
+ },
1963
+ {
1964
+ "type": "nested_literal_input",
1965
+ "parent_opcode": "event_broadcast",
1966
+ "input_slot_name": "BROADCAST",
1967
+ "value": "Level Up"
1968
+ },
1969
+ {
1970
+ "type": "nested_input",
1971
+ "parent_opcode": "control_if",
1972
+ "input_slot_name": "CONDITION",
1973
+ "child_opcode": "operator_gt"
1974
+ },
1975
+ {
1976
+ "type": "nested_input",
1977
+ "parent_opcode": "data_setvariableto",
1978
+ "input_slot_name": "VALUE",
1979
+ "child_opcode": "data_variable"
1980
+ }
1981
+ ]
1982
+ }
1983
+ ]
1984
+ }
1985
+ }
1986
+ },
1987
+ "improvement_plan": {},
1988
+ "needs_improvement": false,
1989
+ "plan_validation_feedback": "The game plan and block structure show a good start but have several areas needing improvement. The 'soccer ball' obstacle's movement speed is not defined, and its interaction with 'Sprite1' could be more detailed. The scoring system and high score tracking are present but lack a clear implementation of how points are awarded per obstacle cleared. The block logic for 'Sprite1' movement and jumping seems incomplete, particularly in handling edge cases and ensuring smooth gameplay. Additionally, power-ups, levels, and sound effects are mentioned but not implemented in the provided JSON.\n(Note: Max iterations reached, stopping further improvements.)",
1990
+ "iteration_count": 0,
1991
+ "review_block_feedback": {},
1992
+ "declaration_plan": {
1993
+ "declaration_plan": {
1994
+ "variables": [
1995
+ {
1996
+ "name": "score",
1997
+ "default": 0,
1998
+ "cloud": false
1999
+ },
2000
+ {
2001
+ "name": "☁ High Score",
2002
+ "default": 0,
2003
+ "cloud": true
2004
+ },
2005
+ {
2006
+ "name": "speed",
2007
+ "default": 0,
2008
+ "cloud": false
2009
+ },
2010
+ {
2011
+ "name": "lives",
2012
+ "default": 3,
2013
+ "cloud": false
2014
+ },
2015
+ {
2016
+ "name": "level",
2017
+ "default": 1,
2018
+ "cloud": false
2019
+ }
2020
+ ],
2021
+ "lists": [
2022
+ {
2023
+ "name": "recent_scores",
2024
+ "default": []
2025
+ },
2026
+ {
2027
+ "name": "obstacle_speeds",
2028
+ "default": []
2029
+ },
2030
+ {
2031
+ "name": "power_ups",
2032
+ "default": []
2033
+ }
2034
+ ],
2035
+ "broadcasts": [
2036
+ "Game Over",
2037
+ "Game Start",
2038
+ "Level Up",
2039
+ "Power Up Collected"
2040
+ ],
2041
+ "monitors": [
2042
+ {
2043
+ "target": "Stage",
2044
+ "variable": "score",
2045
+ "visible": true,
2046
+ "opcode_hint": "data_variable"
2047
+ },
2048
+ {
2049
+ "target": "Stage",
2050
+ "variable": "☁ High Score",
2051
+ "visible": true,
2052
+ "opcode_hint": "data_variable"
2053
+ },
2054
+ {
2055
+ "target": "Stage",
2056
+ "reporter_name": "backdrop #",
2057
+ "visible": false,
2058
+ "opcode_hint": "looks_backdropnumbername",
2059
+ "param_name": "NUMBER_NAME"
2060
+ },
2061
+ {
2062
+ "target": "Stage",
2063
+ "reporter_name": "time",
2064
+ "visible": false,
2065
+ "opcode_hint": "sensing_timer"
2066
+ }
2067
+ ]
2068
+ }
2069
+ }
2070
+ }
v2/scratch_agent/debug_declaration.json ADDED
@@ -0,0 +1,80 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "declaration_plan": {
3
+ "variables": [
4
+ {
5
+ "name": "score",
6
+ "default": 0,
7
+ "cloud": false
8
+ },
9
+ {
10
+ "name": "☁ High Score",
11
+ "default": 0,
12
+ "cloud": true
13
+ },
14
+ {
15
+ "name": "speed",
16
+ "default": 0,
17
+ "cloud": false
18
+ },
19
+ {
20
+ "name": "health",
21
+ "default": 1,
22
+ "cloud": false
23
+ },
24
+ {
25
+ "name": "shieldActive",
26
+ "default": false,
27
+ "cloud": false
28
+ },
29
+ {
30
+ "name": "combo",
31
+ "default": 0,
32
+ "cloud": false
33
+ }
34
+ ],
35
+ "lists": [
36
+ {
37
+ "name": "recent_scores",
38
+ "default": []
39
+ },
40
+ {
41
+ "name": "obstacleSpeeds",
42
+ "default": []
43
+ },
44
+ {
45
+ "name": "powerUps",
46
+ "default": []
47
+ }
48
+ ],
49
+ "broadcasts": [
50
+ "Game Over",
51
+ "Game Start",
52
+ "Jump",
53
+ "Power-Up",
54
+ "Obstacle Spawned"
55
+ ],
56
+ "monitors": [
57
+ {
58
+ "target": "Stage",
59
+ "variable": "score",
60
+ "visible": true
61
+ },
62
+ {
63
+ "target": "Stage",
64
+ "variable": "☁ High Score",
65
+ "visible": true
66
+ },
67
+ {
68
+ "target": "Sprite1",
69
+ "reporter": "looks_costumenumbername",
70
+ "param": "number",
71
+ "visible": false
72
+ },
73
+ {
74
+ "target": "Stage",
75
+ "variable": "health",
76
+ "visible": true
77
+ }
78
+ ]
79
+ }
80
+ }
v2/scratch_agent/debug_declaration_build.json ADDED
@@ -0,0 +1,222 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "targets": [
3
+ {
4
+ "isStage": true,
5
+ "name": "Stage",
6
+ "objName": "Stage",
7
+ "variables": {
8
+ "7dcb660865ba476ebdaa": [
9
+ "score",
10
+ 0
11
+ ],
12
+ "3c8be35cce194775a4a3": [
13
+ "☁ High Score",
14
+ 0,
15
+ true
16
+ ],
17
+ "2f82959a49654440b68b": [
18
+ "speed",
19
+ 0
20
+ ],
21
+ "64d7513596744243ab31": [
22
+ "health",
23
+ 1
24
+ ],
25
+ "03e90317245140799586": [
26
+ "shieldActive",
27
+ false
28
+ ],
29
+ "4b4d2e1a6d9a4be19f3c": [
30
+ "combo",
31
+ 0
32
+ ]
33
+ },
34
+ "lists": {
35
+ "41e1392f5ef542f889ba": {
36
+ "name": "recent_scores",
37
+ "contents": []
38
+ },
39
+ "3e2ffe7c93c14dd88489": {
40
+ "name": "obstacleSpeeds",
41
+ "contents": []
42
+ },
43
+ "efa4d9f299f9490789a4": {
44
+ "name": "powerUps",
45
+ "contents": []
46
+ }
47
+ },
48
+ "broadcasts": {
49
+ "c67672b23e944564a20a": "Game Over",
50
+ "e3634bf80cec481086b2": "Game Start",
51
+ "e1924b50715b4002a7eb": "Jump",
52
+ "8694255df85e43b894fb": "Power-Up",
53
+ "80356261553347a9a74b": "Obstacle Spawned"
54
+ },
55
+ "blocks": {},
56
+ "comments": {},
57
+ "currentCostume": 0,
58
+ "costumes": [
59
+ {
60
+ "name": "Blue sky",
61
+ "bitmapResolution": 1,
62
+ "dataFormat": "svg",
63
+ "assetId": "e7c147730f19d284bcd7b3f00af19bb6",
64
+ "md5ext": "e7c147730f19d284bcd7b3f00af19bb6.svg",
65
+ "rotationCenterX": 240,
66
+ "rotationCenterY": 180
67
+ }
68
+ ],
69
+ "sounds": [],
70
+ "volume": 100,
71
+ "layerOrder": 0,
72
+ "tempo": 60,
73
+ "videoTransparency": 50,
74
+ "videoState": "on",
75
+ "textToSpeechLanguage": null
76
+ },
77
+ {
78
+ "isStage": false,
79
+ "name": "Sprite1",
80
+ "objName": "Sprite1",
81
+ "variables": {},
82
+ "lists": {},
83
+ "broadcasts": {},
84
+ "blocks": {},
85
+ "comments": {},
86
+ "currentCostume": 0,
87
+ "costumes": [
88
+ {
89
+ "name": "Sprite1",
90
+ "bitmapResolution": 1,
91
+ "dataFormat": "svg",
92
+ "assetId": "bcf454acf82e4504149f7ffe07081dbc",
93
+ "md5ext": "bcf454acf82e4504149f7ffe07081dbc.svg",
94
+ "rotationCenterX": 0,
95
+ "rotationCenterY": 0
96
+ }
97
+ ],
98
+ "sounds": [],
99
+ "volume": 100,
100
+ "layerOrder": 2,
101
+ "visible": true,
102
+ "x": 240,
103
+ "y": -150,
104
+ "size": 100,
105
+ "direction": 90,
106
+ "draggable": false,
107
+ "rotationStyle": "all around"
108
+ },
109
+ {
110
+ "isStage": false,
111
+ "name": "soccer ball",
112
+ "objName": "soccer ball",
113
+ "variables": {},
114
+ "lists": {},
115
+ "broadcasts": {},
116
+ "blocks": {},
117
+ "comments": {},
118
+ "currentCostume": 0,
119
+ "costumes": [
120
+ {
121
+ "name": "soccer ball",
122
+ "bitmapResolution": 1,
123
+ "dataFormat": "svg",
124
+ "assetId": "0fb9be3e8397c983338cb71dc84d0b25",
125
+ "md5ext": "0fb9be3e8397c983338cb71dc84d0b25.svg",
126
+ "rotationCenterX": 0,
127
+ "rotationCenterY": 0
128
+ }
129
+ ],
130
+ "sounds": [],
131
+ "volume": 100,
132
+ "layerOrder": 3,
133
+ "visible": true,
134
+ "x": 500,
135
+ "y": 0,
136
+ "size": 100,
137
+ "direction": 90,
138
+ "draggable": false,
139
+ "rotationStyle": "all around"
140
+ }
141
+ ],
142
+ "monitors": [
143
+ {
144
+ "id": "c6146b7101d74c44bd60",
145
+ "mode": "default",
146
+ "opcode": "data_variable",
147
+ "params": {
148
+ "VARIABLE": "score"
149
+ },
150
+ "spriteName": null,
151
+ "value": "0",
152
+ "width": 0,
153
+ "height": 0,
154
+ "x": 0,
155
+ "y": 0,
156
+ "visible": true,
157
+ "sliderMin": 0,
158
+ "sliderMax": 100,
159
+ "isDiscrete": true
160
+ },
161
+ {
162
+ "id": "1603633d73134e17b5c2",
163
+ "mode": "default",
164
+ "opcode": "data_variable",
165
+ "params": {
166
+ "VARIABLE": "☁ High Score"
167
+ },
168
+ "spriteName": null,
169
+ "value": "0",
170
+ "width": 0,
171
+ "height": 0,
172
+ "x": 0,
173
+ "y": 0,
174
+ "visible": true,
175
+ "sliderMin": 0,
176
+ "sliderMax": 100,
177
+ "isDiscrete": true
178
+ },
179
+ {
180
+ "id": "f919c711bc8d40ebb6dc",
181
+ "mode": "default",
182
+ "opcode": "looks_costumenumbername",
183
+ "params": {
184
+ "number": "number"
185
+ },
186
+ "spriteName": "Sprite1",
187
+ "value": 0,
188
+ "width": 0,
189
+ "height": 0,
190
+ "x": 0,
191
+ "y": 0,
192
+ "visible": false,
193
+ "sliderMin": 0,
194
+ "sliderMax": 100,
195
+ "isDiscrete": true
196
+ },
197
+ {
198
+ "id": "7bbe5ec8cd254dafa936",
199
+ "mode": "default",
200
+ "opcode": "data_variable",
201
+ "params": {
202
+ "VARIABLE": "health"
203
+ },
204
+ "spriteName": null,
205
+ "value": "0",
206
+ "width": 0,
207
+ "height": 0,
208
+ "x": 0,
209
+ "y": 0,
210
+ "visible": true,
211
+ "sliderMin": 0,
212
+ "sliderMax": 100,
213
+ "isDiscrete": true
214
+ }
215
+ ],
216
+ "extensions": [],
217
+ "meta": {
218
+ "semver": "3.0.0",
219
+ "vm": "11.1.0",
220
+ "agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36"
221
+ }
222
+ }
v2/scratch_agent/debug_declaration_builder.json ADDED
@@ -0,0 +1,327 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "project_json": {
3
+ "targets": [
4
+ {
5
+ "isStage": true,
6
+ "name": "Stage",
7
+ "objName": "Stage",
8
+ "variables": {
9
+ "score_72ab5419": [
10
+ "score",
11
+ "0"
12
+ ],
13
+ "highScore_6ce0673b": [
14
+ "highScore",
15
+ "0",
16
+ true
17
+ ],
18
+ "speed_cd8f138a": [
19
+ "speed",
20
+ "5"
21
+ ],
22
+ "jumpForce_bbc24da6": [
23
+ "jumpForce",
24
+ "10"
25
+ ],
26
+ "gravity_1891d30f": [
27
+ "gravity",
28
+ "0.5"
29
+ ],
30
+ "obstacleSpeed_64bb2fef": [
31
+ "obstacleSpeed",
32
+ "3"
33
+ ]
34
+ },
35
+ "lists": {
36
+ "recent_scores_c9d81b19": [
37
+ "recent_scores",
38
+ []
39
+ ],
40
+ "obstacle_positions_a3be8d3d": [
41
+ "obstacle_positions",
42
+ []
43
+ ]
44
+ },
45
+ "broadcasts": {
46
+ "Game Over_94869dc4": "Game Over",
47
+ "Game Start_fa3b7008": "Game Start",
48
+ "Jump_1fe96dd3": "Jump",
49
+ "Reset Game_277b990f": "Reset Game"
50
+ },
51
+ "blocks": {},
52
+ "comments": {},
53
+ "currentCostume": 0,
54
+ "costumes": [
55
+ {
56
+ "name": "Blue sky",
57
+ "bitmapResolution": 1,
58
+ "dataFormat": "svg",
59
+ "assetId": "e7c147730f19d284bcd7b3f00af19bb6",
60
+ "md5ext": "e7c147730f19d284bcd7b3f00af19bb6.svg",
61
+ "rotationCenterX": 240,
62
+ "rotationCenterY": 180
63
+ }
64
+ ],
65
+ "sounds": [
66
+ {
67
+ "name": "button",
68
+ "dataFormat": "wav",
69
+ "rate": 44100,
70
+ "sampleCount": 0,
71
+ "assetId": "83a9787d4cb6f3b7632b4ddfebf74367",
72
+ "md5ext": "83a9787d4cb6f3b7632b4ddfebf74367.wav"
73
+ }
74
+ ],
75
+ "volume": 100,
76
+ "layerOrder": 0,
77
+ "tempo": 60,
78
+ "videoTransparency": 50,
79
+ "videoState": "on",
80
+ "textToSpeechLanguage": null
81
+ },
82
+ {
83
+ "isStage": false,
84
+ "name": "Sprite1",
85
+ "objName": "Sprite1",
86
+ "variables": {},
87
+ "lists": {},
88
+ "broadcasts": {},
89
+ "blocks": {},
90
+ "comments": {},
91
+ "currentCostume": 0,
92
+ "costumes": [
93
+ {
94
+ "name": "Sprite1",
95
+ "bitmapResolution": 1,
96
+ "dataFormat": "svg",
97
+ "assetId": "bcf454acf82e4504149f7ffe07081dbc",
98
+ "md5ext": "bcf454acf82e4504149f7ffe07081dbc.svg",
99
+ "rotationCenterX": 0,
100
+ "rotationCenterY": 0
101
+ }
102
+ ],
103
+ "sounds": [
104
+ {
105
+ "name": "meow",
106
+ "dataFormat": "wav",
107
+ "rate": 44100,
108
+ "sampleCount": 0,
109
+ "assetId": "83c36d806dc92327b9e7049a565c6bff",
110
+ "md5ext": "83c36d806dc92327b9e7049a565c6bff.wav"
111
+ }
112
+ ],
113
+ "volume": 100,
114
+ "layerOrder": 2,
115
+ "visible": true,
116
+ "x": -200,
117
+ "y": -100,
118
+ "size": 100,
119
+ "direction": 90,
120
+ "draggable": false,
121
+ "rotationStyle": "all around"
122
+ },
123
+ {
124
+ "isStage": false,
125
+ "name": "soccer ball",
126
+ "objName": "soccer ball",
127
+ "variables": {},
128
+ "lists": {},
129
+ "broadcasts": {},
130
+ "blocks": {},
131
+ "comments": {},
132
+ "currentCostume": 0,
133
+ "costumes": [
134
+ {
135
+ "name": "soccer ball",
136
+ "bitmapResolution": 1,
137
+ "dataFormat": "svg",
138
+ "assetId": "0fb9be3e8397c983338cb71dc84d0b25",
139
+ "md5ext": "0fb9be3e8397c983338cb71dc84d0b25.svg",
140
+ "rotationCenterX": 0,
141
+ "rotationCenterY": 0
142
+ }
143
+ ],
144
+ "sounds": [],
145
+ "volume": 100,
146
+ "layerOrder": 3,
147
+ "visible": true,
148
+ "x": 200,
149
+ "y": 0,
150
+ "size": 100,
151
+ "direction": 90,
152
+ "draggable": false,
153
+ "rotationStyle": "all around"
154
+ }
155
+ ],
156
+ "monitors": [
157
+ {
158
+ "id": "monitor_123e4567",
159
+ "opcode": "data_variable",
160
+ "spriteName": "Stage",
161
+ "params": {
162
+ "VARIABLE": "score"
163
+ },
164
+ "value": "0",
165
+ "visible": true,
166
+ "x": 5,
167
+ "y": 5,
168
+ "mode": "default",
169
+ "sliderMin": 0,
170
+ "sliderMax": 100,
171
+ "isDiscrete": true
172
+ },
173
+ {
174
+ "id": "monitor_8f4e5678",
175
+ "opcode": "data_variable",
176
+ "spriteName": "Stage",
177
+ "params": {
178
+ "VARIABLE": "highScore"
179
+ },
180
+ "value": "0",
181
+ "visible": true,
182
+ "x": 325,
183
+ "y": 5,
184
+ "mode": "default",
185
+ "sliderMin": 0,
186
+ "sliderMax": 100,
187
+ "isDiscrete": true
188
+ },
189
+ {
190
+ "id": "monitor_456e7890",
191
+ "opcode": "looks_costumenumbername",
192
+ "spriteName": "Sprite1",
193
+ "params": {
194
+ "NUMBER_NAME": "number"
195
+ },
196
+ "value": "1",
197
+ "visible": false,
198
+ "x": 5,
199
+ "y": 55,
200
+ "mode": "default",
201
+ "sliderMin": 0,
202
+ "sliderMax": 100,
203
+ "isDiscrete": true
204
+ },
205
+ {
206
+ "id": "monitor_9f4e5678",
207
+ "opcode": "motion_yposition",
208
+ "spriteName": "Sprite1",
209
+ "params": {},
210
+ "value": "0",
211
+ "visible": false,
212
+ "x": 325,
213
+ "y": 55,
214
+ "mode": "default",
215
+ "sliderMin": 0,
216
+ "sliderMax": 100,
217
+ "isDiscrete": true
218
+ }
219
+ ],
220
+ "extensions": [],
221
+ "meta": {
222
+ "semver": "3.0.0",
223
+ "vm": "11.1.0",
224
+ "agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36"
225
+ }
226
+ },
227
+ "description": "In \"Cat's Obstacle Dash,\" a thrilling adventure unfolds on the Scratch Stage, where a nimble cat, represented by Sprite1, must navigate through a challenging course while avoiding or jumping over obstacles. The game takes place in a vibrant blue sky, setting the stage for an exhilarating experience.\n\n**Gameplay Overview:**\n\n- The player's objective is to control the cat, guiding it through the course while avoiding collisions with moving obstacles, in this case, a soccer ball that will be programmed to move across the screen.\n- The game starts with the cat positioned at the beginning of the course. As the game progresses, the soccer ball obstacle will start moving from one side of the screen to the other, requiring the player to time their jumps carefully.\n- The cat can jump over the soccer ball by pressing a specific key, adding an element of timing and precision to the gameplay.\n\n**Game Elements and Mechanics:**\n\n- **Cat (Sprite1):** The main character that the player controls. It can move left and right and jump over obstacles.\n- **Soccer Ball:** Acts as the obstacle. It moves horizontally across the screen at a constant speed, and the player must time the cat's jump to avoid collision.\n- **Stage:** The blue sky backdrop provides a visually appealing setting for the game. \n\n**Potential Gameplay Enhancements:**\n\n- **Score System:** Implement a scoring system where players earn points for successfully jumping over the soccer ball. The score could increase with each successful jump or based on the distance covered without hitting an obstacle.\n- **Power-Ups:** Introduce power-ups or special abilities, such as increased jump height or temporary invincibility, to enhance gameplay and strategy.\n- **Level Progression:** Design multiple levels with increasing difficulty, such as faster-moving obstacles, narrower platforms, or additional obstacles.\n\n**Objectives:**\n\n- Guide the cat through the course, avoiding the soccer ball obstacle.\n- Achieve the highest score possible by successfully navigating through the course.\n\n**Overall Feel:**\n\n- The game aims to provide a fun, challenging experience that tests the player's timing and reflexes.\n- The colorful backdrop and simple yet engaging gameplay mechanics are designed to appeal to players of all ages.\n\nBy incorporating these elements, \"Cat's Obstacle Dash\" promises to deliver an engaging and entertaining Scratch game that leverages the platform's capabilities to create a dynamic and interactive experience.",
228
+ "project_id": "ddb6a76e-58b0-48ed-ac7a-80dcfd98126d",
229
+ "sprite_initial_positions": {},
230
+ "action_plan": {},
231
+ "improvement_plan": {},
232
+ "needs_improvement": false,
233
+ "plan_validation_feedback": {},
234
+ "iteration_count": 0,
235
+ "review_block_feedback": {},
236
+ "declaration_plan": {
237
+ "declaration_plan": {
238
+ "variables": [
239
+ {
240
+ "name": "score",
241
+ "default": 0,
242
+ "cloud": false
243
+ },
244
+ {
245
+ "name": "highScore",
246
+ "default": 0,
247
+ "cloud": true
248
+ },
249
+ {
250
+ "name": "speed",
251
+ "default": 5,
252
+ "cloud": false
253
+ },
254
+ {
255
+ "name": "jumpForce",
256
+ "default": 10,
257
+ "cloud": false
258
+ },
259
+ {
260
+ "name": "gravity",
261
+ "default": 0.5,
262
+ "cloud": false
263
+ },
264
+ {
265
+ "name": "obstacleSpeed",
266
+ "default": 3,
267
+ "cloud": false
268
+ }
269
+ ],
270
+ "lists": [
271
+ {
272
+ "name": "recent_scores",
273
+ "default": []
274
+ },
275
+ {
276
+ "name": "obstacle_positions",
277
+ "default": []
278
+ }
279
+ ],
280
+ "broadcasts": [
281
+ "Game Over",
282
+ "Game Start",
283
+ "Jump",
284
+ "Reset Game"
285
+ ],
286
+ "monitors": [
287
+ {
288
+ "target": "Stage",
289
+ "variable": "score",
290
+ "visible": true,
291
+ "opcode_hint": "data_variable"
292
+ },
293
+ {
294
+ "target": "Stage",
295
+ "variable": "highScore",
296
+ "visible": true,
297
+ "opcode_hint": "data_variable"
298
+ },
299
+ {
300
+ "target": "Sprite1",
301
+ "reporter_name": "costume #",
302
+ "visible": false,
303
+ "opcode_hint": "looks_costumenumbername",
304
+ "param_name": "NUMBER_NAME"
305
+ },
306
+ {
307
+ "target": "Sprite1",
308
+ "reporter_name": "x position",
309
+ "visible": false,
310
+ "opcode_hint": "motion_xposition"
311
+ },
312
+ {
313
+ "target": "Sprite1",
314
+ "reporter_name": "y position",
315
+ "visible": false,
316
+ "opcode_hint": "motion_yposition"
317
+ },
318
+ {
319
+ "target": "Soccer Ball",
320
+ "reporter_name": "x position",
321
+ "visible": false,
322
+ "opcode_hint": "motion_xposition"
323
+ }
324
+ ]
325
+ }
326
+ }
327
+ }
v2/scratch_agent/debug_declaration_plan.json ADDED
@@ -0,0 +1,85 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "declaration_plan": {
3
+ "variables": [
4
+ {
5
+ "name": "score",
6
+ "default": 0,
7
+ "cloud": false
8
+ },
9
+ {
10
+ "name": "☁ High Score",
11
+ "default": 0,
12
+ "cloud": true
13
+ },
14
+ {
15
+ "name": "speed",
16
+ "default": 0,
17
+ "cloud": false
18
+ },
19
+ {
20
+ "name": "lives",
21
+ "default": 3,
22
+ "cloud": false
23
+ },
24
+ {
25
+ "name": "level",
26
+ "default": 1,
27
+ "cloud": false
28
+ }
29
+ ],
30
+ "lists": [
31
+ {
32
+ "name": "recent_scores",
33
+ "default": []
34
+ },
35
+ {
36
+ "name": "obstacle_sizes",
37
+ "default": []
38
+ },
39
+ {
40
+ "name": "obstacle_speeds",
41
+ "default": []
42
+ }
43
+ ],
44
+ "broadcasts": [
45
+ "Game Over",
46
+ "Game Start",
47
+ "Level Up",
48
+ "Reset Game"
49
+ ],
50
+ "monitors": [
51
+ {
52
+ "target": "Stage",
53
+ "variable": "score",
54
+ "visible": true,
55
+ "opcode_hint": "data_variable"
56
+ },
57
+ {
58
+ "target": "Stage",
59
+ "variable": "☁ High Score",
60
+ "visible": true,
61
+ "opcode_hint": "data_variable"
62
+ },
63
+ {
64
+ "target": "Stage",
65
+ "variable": "lives",
66
+ "visible": true,
67
+ "opcode_hint": "data_variable"
68
+ },
69
+ {
70
+ "target": "Stage",
71
+ "reporter_name": "costume #",
72
+ "visible": false,
73
+ "opcode_hint": "looks_costumenumbername",
74
+ "param_name": "NUMBER_NAME"
75
+ },
76
+ {
77
+ "target": "Stage",
78
+ "reporter_name": "backdrop #",
79
+ "visible": false,
80
+ "opcode_hint": "looks_backdropnumbername",
81
+ "param_name": "NUMBER_NAME"
82
+ }
83
+ ]
84
+ }
85
+ }
v2/scratch_agent/debug_state.json ADDED
@@ -0,0 +1,478 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "project_json": {
3
+ "targets": [
4
+ {
5
+ "isStage": true,
6
+ "name": "Stage",
7
+ "objName": "Stage",
8
+ "variables": {
9
+ "score_9c11a348": [
10
+ "score",
11
+ "0"
12
+ ],
13
+ "☁ High Score_1da2aedb": [
14
+ "☁ High Score",
15
+ "0",
16
+ true
17
+ ],
18
+ "speed_d988ac30": [
19
+ "speed",
20
+ "0"
21
+ ],
22
+ "lives_45581a71": [
23
+ "lives",
24
+ "3"
25
+ ],
26
+ "level_9cef21ff": [
27
+ "level",
28
+ "1"
29
+ ]
30
+ },
31
+ "lists": {
32
+ "recent_scores_d16ebefa": [
33
+ "recent_scores",
34
+ []
35
+ ],
36
+ "obstacle_sizes_bac2d8a1": [
37
+ "obstacle_sizes",
38
+ []
39
+ ],
40
+ "obstacle_speeds_d0d95af7": [
41
+ "obstacle_speeds",
42
+ []
43
+ ]
44
+ },
45
+ "broadcasts": {
46
+ "Game Over_a59c2858": "Game Over",
47
+ "Game Start_98c95fc0": "Game Start",
48
+ "Level Up_6ff1c194": "Level Up",
49
+ "Reset Game_789e84e5": "Reset Game"
50
+ },
51
+ "blocks": {},
52
+ "comments": {},
53
+ "currentCostume": 0,
54
+ "costumes": [
55
+ {
56
+ "name": "Blue sky",
57
+ "bitmapResolution": 1,
58
+ "dataFormat": "svg",
59
+ "assetId": "e7c147730f19d284bcd7b3f00af19bb6",
60
+ "md5ext": "e7c147730f19d284bcd7b3f00af19bb6.svg",
61
+ "rotationCenterX": 240,
62
+ "rotationCenterY": 180
63
+ }
64
+ ],
65
+ "sounds": [
66
+ {
67
+ "name": "button",
68
+ "dataFormat": "wav",
69
+ "rate": 44100,
70
+ "sampleCount": 0,
71
+ "assetId": "83a9787d4cb6f3b7632b4ddfebf74367",
72
+ "md5ext": "83a9787d4cb6f3b7632b4ddfebf74367.wav"
73
+ }
74
+ ],
75
+ "volume": 100,
76
+ "layerOrder": 0,
77
+ "tempo": 60,
78
+ "videoTransparency": 50,
79
+ "videoState": "on",
80
+ "textToSpeechLanguage": null
81
+ },
82
+ {
83
+ "isStage": false,
84
+ "name": "Cat",
85
+ "objName": "Cat",
86
+ "variables": {},
87
+ "lists": {},
88
+ "broadcasts": {},
89
+ "blocks": {},
90
+ "comments": {},
91
+ "currentCostume": 0,
92
+ "costumes": [
93
+ {
94
+ "name": "Cat",
95
+ "bitmapResolution": 1,
96
+ "dataFormat": "svg",
97
+ "assetId": "bcf454acf82e4504149f7ffe07081dbc",
98
+ "md5ext": "bcf454acf82e4504149f7ffe07081dbc.svg",
99
+ "rotationCenterX": 0,
100
+ "rotationCenterY": 0
101
+ }
102
+ ],
103
+ "sounds": [
104
+ {
105
+ "name": "Meow",
106
+ "dataFormat": "wav",
107
+ "rate": 44100,
108
+ "sampleCount": 0,
109
+ "assetId": "83c36d806dc92327b9e7049a565c6bff",
110
+ "md5ext": "83c36d806dc92327b9e7049a565c6bff.wav"
111
+ }
112
+ ],
113
+ "volume": 100,
114
+ "layerOrder": 2,
115
+ "visible": true,
116
+ "x": 0,
117
+ "y": 0,
118
+ "size": 100,
119
+ "direction": 90,
120
+ "draggable": false,
121
+ "rotationStyle": "all around"
122
+ },
123
+ {
124
+ "isStage": false,
125
+ "name": "ball",
126
+ "objName": "ball",
127
+ "variables": {},
128
+ "lists": {},
129
+ "broadcasts": {},
130
+ "blocks": {},
131
+ "comments": {},
132
+ "currentCostume": 0,
133
+ "costumes": [
134
+ {
135
+ "name": "ball",
136
+ "bitmapResolution": 1,
137
+ "dataFormat": "svg",
138
+ "assetId": "5d973d7a3a8be3f3bd6e1cd0f73c32b5",
139
+ "md5ext": "5d973d7a3a8be3f3bd6e1cd0f73c32b5.svg",
140
+ "rotationCenterX": 0,
141
+ "rotationCenterY": 0
142
+ }
143
+ ],
144
+ "sounds": [],
145
+ "volume": 100,
146
+ "layerOrder": 3,
147
+ "visible": true,
148
+ "x": 130,
149
+ "y": 0,
150
+ "size": 100,
151
+ "direction": 90,
152
+ "draggable": false,
153
+ "rotationStyle": "all around"
154
+ }
155
+ ],
156
+ "monitors": [
157
+ {
158
+ "id": "monitor_123e4567",
159
+ "opcode": "data_variable",
160
+ "mode": "default",
161
+ "params": {
162
+ "VARIABLE": "score"
163
+ },
164
+ "spriteName": "Stage",
165
+ "value": "0",
166
+ "visible": true,
167
+ "x": 5,
168
+ "y": 5,
169
+ "sliderMin": 0,
170
+ "sliderMax": 100,
171
+ "isDiscrete": true
172
+ },
173
+ {
174
+ "id": "monitor_8f4e3210",
175
+ "opcode": "data_variable",
176
+ "mode": "default",
177
+ "params": {
178
+ "VARIABLE": "☁ High Score"
179
+ },
180
+ "spriteName": "Stage",
181
+ "value": "0",
182
+ "visible": true,
183
+ "x": 325,
184
+ "y": 5,
185
+ "sliderMin": 0,
186
+ "sliderMax": 100,
187
+ "isDiscrete": true
188
+ },
189
+ {
190
+ "id": "monitor_455a2312",
191
+ "opcode": "data_variable",
192
+ "mode": "default",
193
+ "params": {
194
+ "VARIABLE": "lives"
195
+ },
196
+ "spriteName": "Stage",
197
+ "value": "3",
198
+ "visible": true,
199
+ "x": 5,
200
+ "y": 55,
201
+ "sliderMin": 0,
202
+ "sliderMax": 10,
203
+ "isDiscrete": true
204
+ },
205
+ {
206
+ "id": "monitor_4d6e649d",
207
+ "opcode": "looks_costumenumbername",
208
+ "mode": "default",
209
+ "params": {
210
+ "NUMBER_NAME": "number"
211
+ },
212
+ "spriteName": "Stage",
213
+ "value": "1",
214
+ "visible": false,
215
+ "x": 325,
216
+ "y": 55,
217
+ "sliderMin": 0,
218
+ "sliderMax": 100,
219
+ "isDiscrete": true
220
+ },
221
+ {
222
+ "id": "monitor_8f5e9012",
223
+ "opcode": "looks_backdropnumbername",
224
+ "mode": "default",
225
+ "params": {
226
+ "NUMBER_NAME": "number"
227
+ },
228
+ "spriteName": "Stage",
229
+ "value": "1",
230
+ "visible": false,
231
+ "x": 5,
232
+ "y": 105,
233
+ "sliderMin": 0,
234
+ "sliderMax": 100,
235
+ "isDiscrete": true
236
+ }
237
+ ],
238
+ "extensions": [],
239
+ "meta": {
240
+ "semver": "3.0.0",
241
+ "vm": "11.1.0",
242
+ "agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36"
243
+ }
244
+ },
245
+ "description": "**Game Title: Cat's Obstacle Dash**\n\n**Overview:** In \"Cat's Obstacle Dash,\" a fast-paced and engaging game, the player controls a curious cat named Cat as it navigates through a challenging obstacle course set against the backdrop of a serene blue sky. The game's objective is to guide Cat as it jumps over incoming obstacles, represented by balls, to achieve the highest score possible.\n\n**Gameplay:**\n\n* The game starts with Cat positioned at the center of the screen, ready to begin its journey.\n* As the game progresses, balls of various sizes will start rolling from the right side of the screen towards Cat.\n* The player must time Cat's jumps perfectly to avoid colliding with the incoming balls.\n* Each successful jump over a ball earns the player points.\n* The game ends when Cat collides with a ball, and the player's final score is displayed.\n\n**Game Mechanics:**\n\n* Cat can move left and right using the arrow keys or 'a' and 'd' keys.\n* Cat can jump using the space bar or the up arrow key.\n* The jump mechanic is physics-based, allowing Cat to jump over obstacles with precision.\n* Balls will have varying speeds and sizes, increasing the challenge as the game progresses.\n\n**Visuals and Audio:**\n\n* The game features a vibrant blue sky as the background, creating a cheerful and uplifting atmosphere.\n* Cat, the protagonist, is a cute and agile sprite with a range of animations to bring its movements to life.\n* The balls are visually distinct, with different colors and sizes to add variety to the obstacles.\n* The game includes sound effects for Cat's movements, such as meowing and pouncing sounds, as well as a fun and upbeat background music.\n\n**Scoring and Progression:**\n\n* The player earns points for each successful jump over a ball.\n* As the player progresses through the game, the balls will increase in speed and size, making it more challenging to achieve high scores.\n* The game features a leaderboard to track the player's progress and compete with friends.\n\n**Overall Feel:**\n\n* \"Cat's Obstacle Dash\" is a fast-paced and engaging game that requires precision and timing to succeed.\n* The game's colorful visuals, fun sound effects, and upbeat music create a lively and entertaining atmosphere.\n* The game's objective is simple yet challenging, making it accessible to players of all ages and skill levels.\n\n**Potential Gameplay Elements:**\n\n* Power-ups: Introduce power-ups, such as a \"shield\" that protects Cat from one ball or a \"boost\" that increases Cat's jump height.\n* Obstacle variations: Add different types of obstacles, such as moving platforms or spinning blades, to increase the game's difficulty and variety.\n* Leveling system: Introduce levels with increasing difficulty, featuring different obstacle patterns and challenges.\n\nBy incorporating these elements, \"Cat's Obstacle Dash\" can become a highly engaging and addictive game that challenges players to improve their skills and compete for the highest scores.",
246
+ "project_id": "c2d1aa31-17c3-4886-8718-ccbd0a157145",
247
+ "sprite_initial_positions": {},
248
+ "action_plan": {
249
+ "Stage": {
250
+ "description": "Background and global game state management, including broadcasts, rewards, and score.",
251
+ "plans": [
252
+ {
253
+ "event": "event_whenflagclicked",
254
+ "logic": "when green flag clicked\n set [score v] to 0\n set [speed v] to 2\n set [lives v] to 3\n broadcast [Game Start v]",
255
+ "control": [],
256
+ "operator": [],
257
+ "sensing": [],
258
+ "looks": [],
259
+ "sounds": [],
260
+ "events": [
261
+ "event_broadcast"
262
+ ],
263
+ "data": [
264
+ "data_setvariableto"
265
+ ]
266
+ },
267
+ {
268
+ "event": "event_whenbroadcastreceived",
269
+ "logic": "when I receive [Game Over v]\n if <(score) > (High Score)> then\n set [High Score v] to (score)\n end\n broadcast [Reset Game v]",
270
+ "control": [
271
+ "control_if"
272
+ ],
273
+ "operator": [
274
+ "operator_gt"
275
+ ],
276
+ "sensing": [],
277
+ "looks": [],
278
+ "sounds": [],
279
+ "events": [
280
+ "event_broadcast"
281
+ ],
282
+ "data": [
283
+ "data_setvariableto"
284
+ ]
285
+ },
286
+ {
287
+ "event": "event_whenbroadcastreceived",
288
+ "logic": "when I receive [Reset Game v]\n set [score v] to 0\n set [lives v] to 3\n set [speed v] to 2",
289
+ "control": [],
290
+ "operator": [],
291
+ "sensing": [],
292
+ "looks": [],
293
+ "sounds": [],
294
+ "events": [
295
+ "event_broadcast"
296
+ ],
297
+ "data": [
298
+ "data_setvariableto"
299
+ ]
300
+ }
301
+ ]
302
+ },
303
+ "Cat": {
304
+ "description": "Main character (cat) actions",
305
+ "plans": [
306
+ {
307
+ "event": "event_whenflagclicked",
308
+ "logic": "when green flag clicked\n go to x: 0 y: 0",
309
+ "motion": [
310
+ "motion_gotoxy"
311
+ ],
312
+ "control": [],
313
+ "operator": [],
314
+ "sensing": [],
315
+ "looks": [],
316
+ "sounds": [],
317
+ "events": [],
318
+ "data": []
319
+ },
320
+ {
321
+ "event": "event_whenkeypressed",
322
+ "logic": "when [space v] key pressed\n if <([y position] = 0)> then\n change y by 10\n end",
323
+ "motion": [
324
+ "motion_changeyby"
325
+ ],
326
+ "control": [
327
+ "control_if"
328
+ ],
329
+ "operator": [],
330
+ "sensing": [
331
+ "sensing_keypressed"
332
+ ],
333
+ "looks": [],
334
+ "sounds": [],
335
+ "events": [],
336
+ "data": []
337
+ },
338
+ {
339
+ "event": "event_whenbroadcastreceived",
340
+ "logic": "when I receive [Game Over v]\n hide",
341
+ "control": [],
342
+ "operator": [],
343
+ "sensing": [],
344
+ "looks": [
345
+ "looks_hide"
346
+ ],
347
+ "sounds": [],
348
+ "events": [
349
+ "event_broadcast"
350
+ ],
351
+ "data": []
352
+ }
353
+ ]
354
+ },
355
+ "ball": {
356
+ "description": "Obstacle movement and interaction",
357
+ "plans": [
358
+ {
359
+ "event": "event_whenflagclicked",
360
+ "logic": "when green flag clicked\n go to x: 240 y: -100\n forever\n glide 2 seconds to x: -240 y: -100\n if <(x position) < -235> then\n set x to 240\n end\n if <touching [Cat v]?> then\n broadcast [Game Over v]\n end\n end",
361
+ "motion": [
362
+ "motion_gotoxy",
363
+ "motion_glidesecstoxy",
364
+ "motion_xposition",
365
+ "motion_setx"
366
+ ],
367
+ "control": [
368
+ "control_forever",
369
+ "control_if"
370
+ ],
371
+ "operator": [
372
+ "operator_lt"
373
+ ],
374
+ "sensing": [
375
+ "sensing_touchingobject"
376
+ ],
377
+ "looks": [],
378
+ "sounds": [],
379
+ "events": [
380
+ "event_broadcast"
381
+ ],
382
+ "data": []
383
+ }
384
+ ]
385
+ }
386
+ },
387
+ "improvement_plan": {},
388
+ "needs_improvement": false,
389
+ "plan_validation_feedback": "Max iterations reached, stopping further improvements.",
390
+ "iteration_count": 0,
391
+ "review_block_feedback": {},
392
+ "declaration_plan": {
393
+ "declaration_plan": {
394
+ "variables": [
395
+ {
396
+ "name": "score",
397
+ "default": 0,
398
+ "cloud": false
399
+ },
400
+ {
401
+ "name": "☁ High Score",
402
+ "default": 0,
403
+ "cloud": true
404
+ },
405
+ {
406
+ "name": "speed",
407
+ "default": 0,
408
+ "cloud": false
409
+ },
410
+ {
411
+ "name": "lives",
412
+ "default": 3,
413
+ "cloud": false
414
+ },
415
+ {
416
+ "name": "level",
417
+ "default": 1,
418
+ "cloud": false
419
+ }
420
+ ],
421
+ "lists": [
422
+ {
423
+ "name": "recent_scores",
424
+ "default": []
425
+ },
426
+ {
427
+ "name": "obstacle_sizes",
428
+ "default": []
429
+ },
430
+ {
431
+ "name": "obstacle_speeds",
432
+ "default": []
433
+ }
434
+ ],
435
+ "broadcasts": [
436
+ "Game Over",
437
+ "Game Start",
438
+ "Level Up",
439
+ "Reset Game"
440
+ ],
441
+ "monitors": [
442
+ {
443
+ "target": "Stage",
444
+ "variable": "score",
445
+ "visible": true,
446
+ "opcode_hint": "data_variable"
447
+ },
448
+ {
449
+ "target": "Stage",
450
+ "variable": "☁ High Score",
451
+ "visible": true,
452
+ "opcode_hint": "data_variable"
453
+ },
454
+ {
455
+ "target": "Stage",
456
+ "variable": "lives",
457
+ "visible": true,
458
+ "opcode_hint": "data_variable"
459
+ },
460
+ {
461
+ "target": "Stage",
462
+ "reporter_name": "costume #",
463
+ "visible": false,
464
+ "opcode_hint": "looks_costumenumbername",
465
+ "param_name": "NUMBER_NAME"
466
+ },
467
+ {
468
+ "target": "Stage",
469
+ "reporter_name": "backdrop #",
470
+ "visible": false,
471
+ "opcode_hint": "looks_backdropnumbername",
472
+ "param_name": "NUMBER_NAME"
473
+ }
474
+ ]
475
+ }
476
+ },
477
+ "temporary_node": {}
478
+ }
v2/scratch_agent/debugs.txt ADDED
File without changes
v2/scratch_agent/errors_node.txt ADDED
@@ -0,0 +1,531 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #helper function to identify the shape of block utilized by the block verifier
2
+ def get_block_type(opcode: str) -> str:
3
+ """Determines the general type of a Scratch block based on its opcode."""
4
+ if not opcode:
5
+ return "unknown"
6
+ if opcode.startswith("event_when") or opcode == "control_start_as_clone":
7
+ return "hat"
8
+ elif opcode.startswith("control_") and ("if" in opcode or "repeat" in opcode or "forever" in opcode):
9
+ return "c_block"
10
+ elif opcode in ["operator_equals", "operator_gt", "operator_lt", "operator_and", "operator_or", "operator_not"] or \
11
+ (opcode.startswith("sensing_") and ("mousedown" in opcode or "keypressed" in opcode or "touching" in opcode)):
12
+ return "boolean"
13
+ elif opcode.endswith("menu"): # For dropdown shadow blocks, treat as reporter for type checking
14
+ return "reporter"
15
+ elif any(s in opcode for s in ["position", "direction", "size", "volume", "costume", "backdrop", "random", "add", "subtract", "multiply", "divide", "length", "item", "of"]):
16
+ # A more comprehensive check for reporters
17
+ return "reporter"
18
+ elif "stop_all" in opcode or "delete_this_clone" in opcode or "procedures_definition" in opcode:
19
+ return "cap"
20
+ # Default to stack for most command blocks if not explicitly defined
21
+ return ALL_SCRATCH_BLOCKS_CATALOG.get(opcode, {}).get("blockType", "stack")
22
+
23
+ def filter_script_blocks(all_blocks: dict, hat_block_id: str) -> dict:
24
+ """
25
+ Filters and returns only the blocks that are part of a specific script
26
+ starting from the given hat_block_id, including connected reporters/shadows.
27
+ """
28
+ script_blocks = {}
29
+ q = [hat_block_id]
30
+ visited = set()
31
+
32
+ while q:
33
+ current_block_id = q.pop(0)
34
+ if current_block_id in visited:
35
+ continue
36
+ visited.add(current_block_id)
37
+
38
+ block_data = all_blocks.get(current_block_id)
39
+ if not block_data:
40
+ continue
41
+
42
+ script_blocks[current_block_id] = block_data
43
+
44
+ # Add next block in sequence (only for stack/c-blocks)
45
+ if get_block_type(block_data.get("opcode")) in ["stack", "c_block", "hat"]: # Hat blocks have next too!
46
+ next_id = block_data.get("next")
47
+ if next_id and next_id in all_blocks:
48
+ q.append(next_id)
49
+
50
+ # Add blocks connected via inputs (e.g., reporters, shadow blocks, substacks)
51
+ if "inputs" in block_data:
52
+ for input_name, input_value in block_data["inputs"].items():
53
+ if isinstance(input_value, list) and len(input_value) >= 2:
54
+ value_or_block_id = input_value[1]
55
+ if isinstance(value_or_block_id, str) and value_or_block_id in all_blocks:
56
+ q.append(value_or_block_id)
57
+ # For type code 3 (reporter with default value), the third element might be a connected block
58
+ if len(input_value) >= 3 and isinstance(input_value[2], str) and input_value[2] in all_blocks:
59
+ q.append(input_value[2])
60
+
61
+ # For C-blocks, add blocks in substacks (if present)
62
+ if get_block_type(block_data.get("opcode")) == "c_block":
63
+ for input_key, input_val in block_data.get("inputs", {}).items():
64
+ # Check for substack inputs (type code 2, typically starts with SUBSTACK)
65
+ if isinstance(input_val, list) and len(input_val) >= 2 and input_val[0] == 2 and isinstance(input_val[1], str) and input_val[1] in all_blocks:
66
+ q.append(input_val[1])
67
+ return script_blocks
68
+
69
+
70
+ def analyze_script_structure(
71
+ script_blocks: dict,
72
+ hat_block_id: str,
73
+ sprite_name: str,
74
+ sprite_variables: dict,
75
+ sprite_lists: dict,
76
+ sprite_broadcasts: dict,
77
+ sprite_custom_blocks: dict # proccode -> block_id mapping
78
+ ) -> list:
79
+ """
80
+ Analyzes the structure of a single Scratch script for common errors.
81
+ Returns a list of issue strings.
82
+ """
83
+ issues = []
84
+
85
+ # 1. Validate the hat block
86
+ hat_block = script_blocks.get(hat_block_id)
87
+ if not hat_block:
88
+ issues.append(f"Script for sprite '{sprite_name}' (hat ID: {hat_block_id}) has no hat block data.")
89
+ return issues # Cannot proceed without a hat block
90
+
91
+ if not hat_block.get("topLevel") or hat_block.get("parent") is not None:
92
+ issues.append(f"Hat block '{hat_block_id}' for sprite '{sprite_name}' is not marked as topLevel or has a parent, which is incorrect for a script start.")
93
+
94
+ # Hat blocks can and do have a 'next' connection to the first block in their script.
95
+ # The previous check was a false positive. Removed the explicit "should not have next" check for hat blocks.
96
+
97
+ # 2. Check all blocks within the script
98
+ for block_id, block_data in script_blocks.items():
99
+ opcode = block_data.get("opcode")
100
+ if not opcode:
101
+ issues.append(f"Block '{block_id}' for sprite '{sprite_name}' is missing an opcode.")
102
+ continue
103
+
104
+ # Check if opcode exists in the catalog
105
+ if opcode not in ALL_SCRATCH_BLOCKS_CATALOG:
106
+ issues.append(f"Block '{block_id}' for sprite '{sprite_name}' has unknown opcode '{opcode}'. Recommendation: Verify against Scratch 3.0 block reference.")
107
+
108
+ # Parent-Child and Next-Previous Linkage
109
+ parent_id = block_data.get("parent")
110
+ next_id = block_data.get("next")
111
+ current_block_type = get_block_type(opcode)
112
+
113
+ if parent_id:
114
+ parent_block = script_blocks.get(parent_id)
115
+ if not parent_block:
116
+ issues.append(f"Block '{block_id}' (opcode: {opcode}) for sprite '{sprite_name}' references non-existent parent '{parent_id}'.")
117
+ else:
118
+ # Validate the parent-child connection type based on block types
119
+ parent_block_type = get_block_type(parent_block.get("opcode"))
120
+
121
+ if parent_block_type in ["stack", "hat", "c_block"]:
122
+ # If parent is a stack/hat/C-block, this block should be its 'next' or an input/substack
123
+ if parent_block.get("next") == block_id:
124
+ # Correct sequential connection
125
+ pass
126
+ else:
127
+ found_as_input = False
128
+ for input_name, input_value in parent_block.get("inputs", {}).items():
129
+ if isinstance(input_value, list) and len(input_value) >= 2 and input_value[1] == block_id:
130
+ found_as_input = True
131
+ break
132
+ if not found_as_input:
133
+ issues.append(f"Block '{block_id}' (opcode: {opcode}) has parent '{parent_id}' but is not a sequential 'next' block nor connected via an input slot. Potential broken linkage.")
134
+ elif parent_block_type in ["reporter", "boolean"]:
135
+ # If parent is a reporter/boolean, this block must be its child (e.g., a shadow block or another reporter)
136
+ # and connected via an input.
137
+ found_as_input = False
138
+ for input_name, input_value in parent_block.get("inputs", {}).items():
139
+ if isinstance(input_value, list) and len(input_value) >= 2 and input_value[1] == block_id:
140
+ found_as_input = True
141
+ break
142
+ if not found_as_input:
143
+ issues.append(f"Block '{block_id}' (opcode: {opcode}) has reporter/boolean parent '{parent_id}' but is not linked via an input. Potential broken linkage.")
144
+ else:
145
+ issues.append(f"Block '{block_id}' (opcode: {opcode}) has an unexpected parent block type '{parent_block_type}' for parent '{parent_id}'.")
146
+
147
+ # Check next linkage: only cap blocks should not have a next. Shadow blocks also shouldn't have next.
148
+ if next_id:
149
+ next_block = script_blocks.get(next_id)
150
+ if not next_block:
151
+ issues.append(f"Block '{block_id}' (opcode: {opcode}) for sprite '{sprite_name}' references non-existent next block '{next_id}'.")
152
+ elif next_block.get("parent") != block_id:
153
+ issues.append(f"Block '{block_id}' (opcode: {opcode})'s next block '{next_id}' does not link back to it via 'parent'.")
154
+
155
+ # Cap blocks should not have 'next'
156
+ if current_block_type == "cap":
157
+ issues.append(f"Cap block '{block_id}' (opcode: {opcode}) for sprite '{sprite_name}' should not have a 'next' connection as it ends a script.")
158
+ # Shadow blocks should not have 'next'
159
+ if block_data.get("shadow"):
160
+ issues.append(f"Shadow block '{block_id}' (opcode: {opcode}) for sprite '{sprite_name}' should not have a 'next' connection.")
161
+
162
+ # Input validation
163
+ if "inputs" in block_data:
164
+ for input_name, input_value in block_data["inputs"].items():
165
+ if not isinstance(input_value, list) or len(input_value) < 2:
166
+ issues.append(f"Block '{block_id}' (opcode: {opcode}) for sprite '{sprite_name}' has malformed input '{input_name}': {input_value}.")
167
+ continue
168
+
169
+ type_code = input_value[0]
170
+ value_or_block_id = input_value[1]
171
+
172
+ # Check type code validity
173
+ if type_code not in [1, 2, 3]:
174
+ issues.append(f"Block '{block_id}' (opcode: {opcode}) input '{input_name}' has invalid type code: {type_code}. Expected 1, 2, or 3.")
175
+
176
+ if isinstance(value_or_block_id, str):
177
+ # It's a block ID, check if it exists and its parent link is correct
178
+ connected_block = script_blocks.get(value_or_block_id)
179
+ if not connected_block:
180
+ issues.append(f"Block '{block_id}' (opcode: {opcode}) input '{input_name}' references non-existent block ID '{value_or_block_id}'.")
181
+ elif connected_block.get("parent") != block_id:
182
+ issues.append(f"Block '{block_id}' (opcode: {opcode}) input '{input_name}' connects to '{value_or_block_id}', but '{value_or_block_id}'s parent is not '{block_id}'.")
183
+
184
+ connected_block_type = get_block_type(connected_block.get("opcode"))
185
+
186
+ # Refined type code consistency checks
187
+ if type_code == 2: # Block ID (substack or reporter/boolean plugged in, without shadow)
188
+ if input_name.startswith("SUBSTACK"):
189
+ if connected_block_type != "stack":
190
+ issues.append(f"Block '{block_id}' (opcode: {opcode}) input '{input_name}' (type 2, SUBSTACK) expects a stack block, but connected block '{value_or_block_id}' is of type '{connected_block_type}'.")
191
+ elif connected_block_type not in ["reporter", "boolean"]:
192
+ issues.append(f"Block '{block_id}' (opcode: {opcode}) input '{input_name}' (type 2, non-SUBSTACK) expects a reporter/boolean, but connected block '{value_or_block_id}' is of type '{connected_block_type}'.")
193
+ elif type_code == 1: # Literal value or shadow block ID (possibly with an attached block)
194
+ if isinstance(value_or_block_id, str) and connected_block_type not in ["reporter", "boolean"] and not connected_block.get("shadow"):
195
+ issues.append(f"Block '{block_id}' (opcode: {opcode}) input '{input_name}' (type 1) expects a literal or reporter/boolean/shadow, but connected block '{value_or_block_id}' is of type '{connected_block_type}' and not a shadow.")
196
+ elif type_code == 3: # Shadow block ID with default value, possibly with attached block
197
+ if isinstance(value_or_block_id, str) and not connected_block.get("shadow"):
198
+ issues.append(f"Block '{block_id}' (opcode: {opcode}) input '{input_name}' (type 3) expects a shadow block, but connected block '{value_or_block_id}' is not a shadow.")
199
+
200
+
201
+ # Specific checks for C-blocks' SUBSTACK
202
+ if get_block_type(opcode) == "c_block" and input_name.startswith("SUBSTACK"):
203
+ # For a C-block, SUBSTACK input must have type code 2 and link to a valid block ID
204
+ if not (isinstance(value_or_block_id, str) and script_blocks.get(value_or_block_id) and type_code == 2):
205
+ issues.append(f"C-block '{block_id}' (opcode: {opcode}) for sprite '{sprite_name}' has an invalid or missing SUBSTACK input configuration.")
206
+
207
+ # Shadow block specific checks
208
+ if block_data.get("shadow"):
209
+ if block_data.get("topLevel"):
210
+ issues.append(f"Shadow block '{block_id}' (opcode: {opcode}) for sprite '{sprite_name}' is incorrectly marked as topLevel.")
211
+ if not block_data.get("parent"):
212
+ issues.append(f"Shadow block '{block_id}' (opcode: {opcode}) for sprite '{sprite_name}' is missing a parent.")
213
+ if block_data.get("next"): # Shadow blocks should never have 'next'
214
+ issues.append(f"Shadow block '{block_id}' (opcode: {opcode}) for sprite '{sprite_name}' should not have a 'next' connection.")
215
+
216
+ # Enhanced field validation for specific shadow block opcodes
217
+ if opcode == "math_number":
218
+ num_field = block_data.get("fields", {}).get("NUM")
219
+ if not (isinstance(num_field, list) and len(num_field) >= 1 and isinstance(num_field[0], (str, int, float))):
220
+ issues.append(f"Math_number shadow block '{block_id}' has malformed 'NUM' field: {num_field}. Expected [value, ID_or_null].")
221
+ elif opcode == "event_broadcast_menu":
222
+ broadcast_field = block_data.get("fields", {}).get("BROADCAST_OPTION") # Standard field name for broadcast menu
223
+ if not (isinstance(broadcast_field, list) and len(broadcast_field) >= 1 and isinstance(broadcast_field[0], str) and broadcast_field[0]): # Ensure broadcast name is a non-empty string
224
+ issues.append(f"Broadcast menu shadow block '{block_id}' has malformed or empty 'BROADCAST_OPTION' field: {broadcast_field}. Expected ['message name', 'ID_or_null'].")
225
+ if broadcast_field and len(broadcast_field) > 1 and broadcast_field[1] is None:
226
+ # This indicates a 'default option' is null, which is often a problem if it's meant to be a pre-defined ID.
227
+ # Flag this as a potential issue, indicating a missing default option.
228
+ issues.append(f"Broadcast menu shadow block '{block_id}' has a 'BROADCAST_OPTION' field with a null default ID: {broadcast_field}. This might indicate a missing pre-defined broadcast ID.")
229
+ elif opcode == "sensing_touchingobjectmenu":
230
+ touching_field = block_data.get("fields", {}).get("TOUCHINGOBJECTMENU")
231
+ if not (isinstance(touching_field, list) and len(touching_field) >= 1 and isinstance(touching_field[0], str) and touching_field[0]):
232
+ issues.append(f"Touching object menu shadow block '{block_id}' has malformed or empty 'TOUCHINGOBJECTMENU' field: {touching_field}. Expected ['object name', 'ID_or_null'].")
233
+ if touching_field and len(touching_field) > 1 and touching_field[1] is None:
234
+ issues.append(f"Touching object menu shadow block '{block_id}' has a 'TOUCHINGOBJECTMENU' field with a null default ID: {touching_field}. This might indicate a missing pre-defined object ID for 'edge', 'mouse-pointer', or a sprite.")
235
+ # Add more specific checks for other menu-type shadow blocks if needed
236
+
237
+ # Validate references to variables, lists, and broadcasts
238
+ if "fields" in block_data:
239
+ # Variable references (data_setvariableto, data_changevariableby, data_variable)
240
+ if opcode in ["data_setvariableto", "data_changevariableby", "data_variable"]:
241
+ var_name_field = block_data["fields"].get("VARIABLE")
242
+ if var_name_field and isinstance(var_name_field, list) and len(var_name_field) >= 1 and isinstance(var_name_field[0], str):
243
+ var_name = var_name_field[0]
244
+ if var_name not in sprite_variables:
245
+ issues.append(f"Block '{block_id}' (opcode: {opcode}) references non-existent variable '{var_name}'. Recommendation: Ensure '{var_name}' is defined.")
246
+ else:
247
+ issues.append(f"Block '{block_id}' (opcode: {opcode}) has malformed 'VARIABLE' field: {var_name_field}.")
248
+
249
+ # List references (data_addtolist, data_deleteoflist, data_itemoflist, data_listcontents)
250
+ if opcode in ["data_addtolist", "data_deleteoflist", "data_itemoflist", "data_listcontents"]:
251
+ list_name_field = block_data["fields"].get("LIST")
252
+ if list_name_field and isinstance(list_name_field, list) and len(list_name_field) >= 1 and isinstance(list_name_field[0], str):
253
+ list_name = list_name_field[0]
254
+ if list_name not in sprite_lists:
255
+ issues.append(f"Block '{block_id}' (opcode: {opcode}) references non-existent list '{list_name}'. Recommendation: Ensure '{list_name}' is defined.")
256
+ else:
257
+ issues.append(f"Block '{block_id}' (opcode: {opcode}) has malformed 'LIST' field: {list_name_field}.")
258
+
259
+ # Broadcast references in 'when I receive' hat blocks
260
+ if opcode == "event_whenbroadcastreceived":
261
+ broadcast_name_field = block_data["fields"].get("BROADCAST_OPTION")
262
+ if broadcast_name_field and isinstance(broadcast_name_field, list) and len(broadcast_name_field) >= 1 and isinstance(broadcast_name_field[0], str):
263
+ broadcast_name = broadcast_name_field[0]
264
+ if broadcast_name not in sprite_broadcasts:
265
+ issues.append(f"Hat block '{block_id}' (opcode: {opcode}) listens for non-existent broadcast message '{broadcast_name}'. Recommendation: Ensure '{broadcast_name}' is broadcast elsewhere.")
266
+ else:
267
+ issues.append(f"Hat block '{block_id}' (opcode: {opcode}) has malformed 'BROADCAST_OPTION' field: {broadcast_name_field}.")
268
+
269
+ # Custom block call validation
270
+ if opcode == "procedures_call" and "mutation" in block_data:
271
+ proccode = block_data["mutation"].get("proccode")
272
+ if proccode and proccode not in sprite_custom_blocks:
273
+ issues.append(f"Custom block call '{block_id}' (proccode: {proccode}) references non-existent custom block definition. Recommendation: Define custom block '{proccode}'.")
274
+ if not proccode:
275
+ issues.append(f"Custom block call '{block_id}' is missing 'proccode' in its mutation.")
276
+
277
+ # Check for event_broadcast blocks having empty message (via malformed shadow)
278
+ if opcode == "event_broadcast" or opcode == "event_broadcastandwait":
279
+ broadcast_input = block_data.get("inputs", {}).get("BROADCAST_INPUT")
280
+ if broadcast_input and isinstance(broadcast_input, list) and len(broadcast_input) >= 2:
281
+ # If connected to a shadow block
282
+ if isinstance(broadcast_input[1], str) and script_blocks.get(broadcast_input[1]) and script_blocks[broadcast_input[1]].get("shadow"):
283
+ shadow_block = script_blocks[broadcast_input[1]]
284
+ if shadow_block.get("opcode") == "event_broadcast_menu":
285
+ broadcast_field = shadow_block.get("fields", {}).get("BROADCAST_OPTION")
286
+ if not (broadcast_field and isinstance(broadcast_field, list) and len(broadcast_field) >= 1 and isinstance(broadcast_field[0], str) and broadcast_field[0].strip()):
287
+ issues.append(f"Broadcast block '{block_id}' uses a shadow block '{shadow_block.get('id', 'unknown')}' that has an empty or malformed broadcast message. Recommendation: Ensure the broadcast message is a non-empty string.")
288
+ # If connected to a literal string (less common for broadcast but possible)
289
+ elif isinstance(broadcast_input[1], list) and len(broadcast_input[1]) >= 2 and isinstance(broadcast_input[1][1], str) and not broadcast_input[1][1].strip():
290
+ issues.append(f"Broadcast block '{block_id}' has an empty literal broadcast message. Recommendation: Provide a non-empty message.")
291
+ else:
292
+ issues.append(f"Broadcast block '{block_id}' has a missing or malformed 'BROADCAST_INPUT'. Recommendation: Ensure a valid message or shadow block is connected.")
293
+
294
+ return issues
295
+
296
+ # Node 5: Verification Node
297
+ def block_verification_node(state: dict) -> dict:
298
+ """
299
+ The block verifier check for any improvements needed through logical if-else
300
+ and then adds them to the improvement_plan.
301
+ After the improvement plan, the LLM reviewer node also checks for other
302
+ errors or issues, if any, and finally provides the review as feedback.
303
+
304
+ Args:
305
+ state (dict): The current state dictionary containing project_json, etc.
306
+
307
+ Returns:
308
+ dict: The updated state dictionary with verification feedback.
309
+ """
310
+ logger.info(f"--- Running BlockVerificationNode (Iteration: {state.get('iteration_count', 0)}) ---")
311
+
312
+ # Increased MAX_IMPROVEMENT_ITERATIONS to allow for more verification and improvement cycles.
313
+ # Set to 5 to allow multiple detection-improvement loops.
314
+ MAX_IMPROVEMENT_ITERATIONS = 3
315
+ current_iteration = state.get("iteration_count", 0)
316
+ project_json = state["project_json"]
317
+ targets = project_json["targets"]
318
+
319
+ # Initialize needs_improvement for the current run
320
+ state["needs_improvement"] = False
321
+ block_validation_feedback_overall = []
322
+
323
+ improvement_plan = {"sprite_issues": {}}
324
+ state["improvement_plan"] = improvement_plan # Ensure it's in state even if empty
325
+
326
+ for target in targets:
327
+ sprite_name = target["name"]
328
+ all_blocks_for_sprite = target.get("blocks", {})
329
+
330
+ # Correctly extract variables (name -> ID mapping)
331
+ sprite_variables = {var_data[0]: var_id for var_id, var_data in target.get("variables", {}).items()}
332
+ # Correctly extract lists (name -> ID mapping)
333
+ sprite_lists = {list_data[0]: list_id for list_id, list_data in target.get("lists", {}).items()}
334
+
335
+ # Broadcasts are typically collected from the 'event_whenbroadcastreceived' blocks
336
+ # and potentially from the 'event_broadcast_menu' shadow blocks.
337
+ sprite_broadcasts = set()
338
+ for block_id, block_data in all_blocks_for_sprite.items():
339
+ if block_data.get("opcode") == "event_whenbroadcastreceived" and "BROADCAST_OPTION" in block_data.get("fields", {}):
340
+ broadcast_name_field = block_data["fields"]["BROADCAST_OPTION"]
341
+ if isinstance(broadcast_name_field, list) and len(broadcast_name_field) >= 1 and isinstance(broadcast_name_field[0], str):
342
+ sprite_broadcasts.add(broadcast_name_field[0])
343
+ elif block_data.get("opcode") == "event_broadcast_menu" and "BROADCAST_OPTION" in block_data.get("fields", {}) and block_data.get("shadow"):
344
+ broadcast_name_field = block_data["fields"]["BROADCAST_OPTION"]
345
+ if isinstance(broadcast_name_field, list) and len(broadcast_name_field) >= 1 and isinstance(broadcast_name_field[0], str):
346
+ sprite_broadcasts.add(broadcast_name_field[0])
347
+
348
+ # Extract custom block definitions (proccodes)
349
+ sprite_custom_blocks = {}
350
+ for block_id, block_data in all_blocks_for_sprite.items():
351
+ if block_data.get("opcode") == "procedures_definition" and "mutation" in block_data:
352
+ proccode = block_data["mutation"].get("proccode")
353
+ if proccode:
354
+ sprite_custom_blocks[proccode] = block_id
355
+
356
+ if not all_blocks_for_sprite:
357
+ logger.info(f"Sprite '{sprite_name}' has no blocks. Skipping verification.")
358
+ continue
359
+
360
+ sprite_issues = []
361
+ hat_block_ids = [
362
+ block_id for block_id, block_data in all_blocks_for_sprite.items()
363
+ if block_data.get("topLevel") and get_block_type(block_data.get("opcode")) == "hat"
364
+ ]
365
+
366
+ processed_script_blocks = set()
367
+
368
+ if not hat_block_ids:
369
+ sprite_issues.append("No top-level hat blocks found for this sprite. Scripts may not run automatically.")
370
+
371
+ for hat_id in hat_block_ids:
372
+ logger.info(f"Verifying script starting with hat block '{hat_id}' for sprite '{sprite_name}'.")
373
+
374
+ current_script_blocks = filter_script_blocks(all_blocks_for_sprite, hat_id)
375
+ processed_script_blocks.update(current_script_blocks.keys())
376
+
377
+ script_issues = analyze_script_structure(
378
+ current_script_blocks,
379
+ hat_id,
380
+ sprite_name,
381
+ sprite_variables,
382
+ sprite_lists,
383
+ sprite_broadcasts,
384
+ sprite_custom_blocks
385
+ )
386
+ if script_issues:
387
+ sprite_issues.append(f"Issues in script starting with '{hat_id}':")
388
+ sprite_issues.extend([f" - {issue}" for issue in script_issues])
389
+ else:
390
+ logger.info(f"Script starting with '{hat_id}' for sprite '{sprite_name}' passed basic verification.")
391
+
392
+ # Identify truly orphaned blocks (not top-level, not part of any script, no parent, not shadow)
393
+ orphaned_blocks_overall = {
394
+ block_id for block_id in all_blocks_for_sprite.keys()
395
+ if block_id not in processed_script_blocks
396
+ and not all_blocks_for_sprite[block_id].get("topLevel")
397
+ and not all_blocks_for_sprite[block_id].get("parent")
398
+ and not all_blocks_for_sprite[block_id].get("shadow")
399
+ }
400
+
401
+ if orphaned_blocks_overall:
402
+ sprite_issues.append(f"Found {len(orphaned_blocks_overall)} truly orphaned blocks not connected to any valid script: {', '.join(list(orphaned_blocks_overall)[:5])}{'...' if len(orphaned_blocks_overall) > 5 else ''}.")
403
+ # Also check for top-level blocks that are not hat blocks and are not processed
404
+ for block_id in all_blocks_for_sprite.keys():
405
+ block_data = all_blocks_for_sprite[block_id]
406
+ if block_data.get("topLevel") and get_block_type(block_data.get("opcode")) != "hat" and block_id not in processed_script_blocks:
407
+ sprite_issues.append(f"Top-level block '{block_id}' (opcode: {block_data.get('opcode')}) is not a hat block and is not part of any script, so it will not run automatically.")
408
+
409
+
410
+ if sprite_issues:
411
+ improvement_plan["sprite_issues"][sprite_name] = sprite_issues
412
+ logger.warning(f"Verification found issues for sprite '{sprite_name}'.")
413
+ block_validation_feedback_overall.append(f"Issues for {sprite_name}:\n" + "\n".join([f"- {issue}" for issue in sprite_issues]))
414
+ state["needs_improvement"] = True
415
+ print(f"\n--- Verification Report (Issues Found for {sprite_name}) ---")
416
+ print(json.dumps({sprite_name: sprite_issues}, indent=2))
417
+ else:
418
+ logger.info(f"Sprite '{sprite_name}' passed all verification checks.")
419
+
420
+ # Consolidate feedback for the LLM
421
+ state["block_validation_feedback"] = "\n\n".join(block_validation_feedback_overall)
422
+
423
+ print(f"[OVERALL IMPROVEMENT PLAN ON ITERATION {current_iteration}]: {improvement_plan}")
424
+
425
+ if state["needs_improvement"]:
426
+ llm_reviewer_prompt = f"""You are an expert Scratch project reviewer. Your task is to analyze the provided \
427
+ structural issues found in a Scratch project's sprites and suggest improvements or \
428
+ further insights. Focus on clarity, accuracy, and actionable advice.
429
+
430
+ Here are the detected structural issues:
431
+ {json.dumps(improvement_plan['sprite_issues'], indent=2)}
432
+
433
+ Here are the block validation feedback:
434
+ {json.dumps(state["block_validation_feedback"], indent=2)}
435
+
436
+
437
+
438
+ Please review these issues and provide a consolidated report with potential causes \
439
+ and recommendations for fixing them. If an issue is minor or expected in certain \
440
+ scenarios (e.g., hidden blocks for backward compatibility), please note that.
441
+ Structure your response as a JSON object with 'review_summary' as the key, \
442
+ containing a dictionary where keys are sprite names and values are lists of suggested improvements.
443
+ Example:
444
+ ```json
445
+ {{
446
+ "review_summary": {{
447
+ "Sprite1": [
448
+ "Issue: Hat block 'abc' is not topLevel. Recommendation: Ensure all scripts start with a top-level hat block that has no parent.",
449
+ "Issue: Block 'xyz' has unknown opcode 'motion_nonexistent'. Recommendation: Verify the opcode against the Scratch 3.0 block reference. This might be a typo or a deprecated block.",
450
+ "Issue: Block 'var_block_id' references non-existent variable 'myVariable'. Recommendation: Ensure all variables used in blocks are defined in the sprite's variable list."
451
+ ],
452
+ "Sprite2": [
453
+ "Issue: Found 3 orphaned blocks. Recommendation: Reconnect these blocks to existing scripts or remove them if no longer needed."
454
+ ]
455
+ }}
456
+ }}
457
+ ```
458
+ """
459
+ try:
460
+ response = agent.invoke({"messages": [{"role": "user", "content": llm_reviewer_prompt}]})
461
+ raw_review_response = response["messages"][-1].content
462
+ try:
463
+ state["review_block_feedback"] = extract_json_from_llm_response(raw_review_response)
464
+ except json.JSONDecodeError as error_json:
465
+ logger.error("Failed to extract JSON from LLM response. Attempting to correct the response.")
466
+ # Use the JSON resolver agent to fix the response
467
+ correction_prompt = (
468
+ "Your task is to correct the provided JSON string to ensure it is **syntactically perfect and adheres strictly to JSON rules**.\n"
469
+ "Carefully review the JSON for any errors, especially focusing on the reported error at:\n"
470
+ f"- **Error Details**: {error_json}\n\n"
471
+ "**Strict Instructions for your response:**\n"
472
+ "1. **ONLY** output the corrected JSON. Do not include any other text, comments, or explanations outside the JSON.\n"
473
+ "2. Ensure all property names (keys) are enclosed in **double quotes**.\n"
474
+ "3. Ensure string values are correctly enclosed in **double quotes** and any internal special characters (like newlines `\\n`, tabs `\\t`, backslashes `\\\\`, or double quotes `\\`) are properly **escaped**.\n"
475
+ "4. Verify that there are **no extra commas**, especially between key-value pairs or after the last element in an object or array.\n"
476
+ "5. Ensure proper nesting and matching of curly braces `{}` and square brackets `[]`.\n"
477
+ "6. **Crucially, remove any extraneous characters or duplicate closing braces outside the main JSON object.**\n"
478
+ "7. The corrected JSON must be a **complete and valid** JSON object.\n\n"
479
+ "Here is the problematic JSON string to correct:\n"
480
+ "```json\n"
481
+ f"{raw_review_response}\n"
482
+ "```\n"
483
+ "Corrected JSON:\n"
484
+ )
485
+ correction_response = agent_json_resolver.invoke({"messages": [{"role": "user", "content": correction_prompt}]})
486
+ print(f"[JSON CORRECTOR RESPONSE AT BLOCKVERFIER ]: {correction_response["messages"][-1].content}")
487
+ state["review_block_feedback"] = extract_json_from_llm_response(correction_response["messages"][-1].content)
488
+
489
+ logger.info("Agent review feedback added to the state.")
490
+ print("\n--- Agent Review Feedback ---")
491
+ print(json.dumps(state["review_block_feedback"], indent=2))
492
+
493
+ except Exception as e:
494
+ logger.error(f"Error invoking agent for review in BlockVerificationNode: {e}")
495
+ # Fallback for LLM error: populate with a general error message
496
+ state["review_block_feedback"] = {"review_summary": {"Overall": [f"Error during LLM review: {e}"]}}
497
+ else:
498
+ logger.info("BlockVerificationNode completed: No issues found in any sprite blocks.")
499
+ print("\n--- Verification Report (No Issues Found) ---")
500
+ state["block_validation_feedback"] = "No issues found in sprite blocks."
501
+ state["review_block_feedback"] = {"review_summary": {"Overall": ["No issues found in sprite blocks. All good!"]}}
502
+
503
+ # Manage iteration count based on overall needs_improvement flag
504
+ if state["needs_improvement"]:
505
+ # Increment iteration count *only if* improvements are needed for the next cycle
506
+ state["iteration_count"] = current_iteration + 1
507
+ if state["iteration_count"] >= MAX_IMPROVEMENT_ITERATIONS:
508
+ logger.warning(f"Max improvement iterations ({MAX_IMPROVEMENT_ITERATIONS}) reached for block verification. Forcing 'needs_improvement' to False.")
509
+ state["needs_improvement"] = False
510
+ state["block_validation_feedback"] += "\n(Note: Max iterations reached for block verification, stopping further improvements.)"
511
+
512
+ # Ensure 'Overall' key exists before attempting to append
513
+ if "review_summary" not in state["review_block_feedback"]:
514
+ state["review_block_feedback"]["review_summary"] = {}
515
+ if "Overall" not in state["review_block_feedback"]["review_summary"]:
516
+ state["review_block_feedback"]["review_summary"]["Overall"] = []
517
+
518
+ state["review_block_feedback"]["review_summary"]["Overall"].append("Max iterations reached for block verification, stopping further improvements based on this run.")
519
+ else:
520
+ # Reset if no more improvement needed for blocks, indicating successful verification
521
+ state["iteration_count"] = 0
522
+
523
+ logger.info(f"Block verification completed. Needs Improvement: {state['needs_improvement']}. Feedback: {state['block_validation_feedback'][:100]}...")
524
+ print("===========================================================================")
525
+ print(f"[BLOCK VERIFICATION NODE: (improvement_plan)]:{state.get("improvement_plan")}")
526
+ print(f"[BLOCK VERIFICATION NODE: (review_block_feedback)]:{state.get("review_block_feedback")}")
527
+
528
+ with open("debug_state.json", "w", encoding="utf-8") as f:
529
+ json.dump(state, f, indent=2, ensure_ascii=False)
530
+
531
+ return state