scratchattach 2.1.14__py3-none-any.whl → 3.0.0b0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. scratchattach/__init__.py +14 -6
  2. scratchattach/__main__.py +93 -0
  3. {scratchattach-2.1.14.dist-info → scratchattach-3.0.0b0.dist-info}/METADATA +7 -11
  4. scratchattach-3.0.0b0.dist-info/RECORD +8 -0
  5. {scratchattach-2.1.14.dist-info → scratchattach-3.0.0b0.dist-info}/WHEEL +1 -1
  6. scratchattach-3.0.0b0.dist-info/entry_points.txt +2 -0
  7. scratchattach/cloud/__init__.py +0 -2
  8. scratchattach/cloud/_base.py +0 -458
  9. scratchattach/cloud/cloud.py +0 -183
  10. scratchattach/editor/__init__.py +0 -21
  11. scratchattach/editor/asset.py +0 -253
  12. scratchattach/editor/backpack_json.py +0 -117
  13. scratchattach/editor/base.py +0 -193
  14. scratchattach/editor/block.py +0 -579
  15. scratchattach/editor/blockshape.py +0 -357
  16. scratchattach/editor/build_defaulting.py +0 -51
  17. scratchattach/editor/code_translation/__init__.py +0 -0
  18. scratchattach/editor/code_translation/parse.py +0 -177
  19. scratchattach/editor/comment.py +0 -80
  20. scratchattach/editor/commons.py +0 -306
  21. scratchattach/editor/extension.py +0 -50
  22. scratchattach/editor/field.py +0 -99
  23. scratchattach/editor/inputs.py +0 -135
  24. scratchattach/editor/meta.py +0 -114
  25. scratchattach/editor/monitor.py +0 -183
  26. scratchattach/editor/mutation.py +0 -324
  27. scratchattach/editor/pallete.py +0 -90
  28. scratchattach/editor/prim.py +0 -170
  29. scratchattach/editor/project.py +0 -279
  30. scratchattach/editor/sprite.py +0 -599
  31. scratchattach/editor/twconfig.py +0 -114
  32. scratchattach/editor/vlb.py +0 -134
  33. scratchattach/eventhandlers/__init__.py +0 -0
  34. scratchattach/eventhandlers/_base.py +0 -100
  35. scratchattach/eventhandlers/cloud_events.py +0 -110
  36. scratchattach/eventhandlers/cloud_recorder.py +0 -26
  37. scratchattach/eventhandlers/cloud_requests.py +0 -459
  38. scratchattach/eventhandlers/cloud_server.py +0 -246
  39. scratchattach/eventhandlers/cloud_storage.py +0 -136
  40. scratchattach/eventhandlers/combine.py +0 -30
  41. scratchattach/eventhandlers/filterbot.py +0 -161
  42. scratchattach/eventhandlers/message_events.py +0 -42
  43. scratchattach/other/__init__.py +0 -0
  44. scratchattach/other/other_apis.py +0 -284
  45. scratchattach/other/project_json_capabilities.py +0 -475
  46. scratchattach/site/__init__.py +0 -0
  47. scratchattach/site/_base.py +0 -66
  48. scratchattach/site/activity.py +0 -382
  49. scratchattach/site/alert.py +0 -227
  50. scratchattach/site/backpack_asset.py +0 -118
  51. scratchattach/site/browser_cookie3_stub.py +0 -17
  52. scratchattach/site/browser_cookies.py +0 -61
  53. scratchattach/site/classroom.py +0 -447
  54. scratchattach/site/cloud_activity.py +0 -107
  55. scratchattach/site/comment.py +0 -242
  56. scratchattach/site/forum.py +0 -432
  57. scratchattach/site/project.py +0 -825
  58. scratchattach/site/session.py +0 -1238
  59. scratchattach/site/studio.py +0 -611
  60. scratchattach/site/user.py +0 -956
  61. scratchattach/utils/__init__.py +0 -0
  62. scratchattach/utils/commons.py +0 -255
  63. scratchattach/utils/encoder.py +0 -158
  64. scratchattach/utils/enums.py +0 -236
  65. scratchattach/utils/exceptions.py +0 -243
  66. scratchattach/utils/requests.py +0 -93
  67. scratchattach-2.1.14.dist-info/RECORD +0 -66
  68. {scratchattach-2.1.14.dist-info → scratchattach-3.0.0b0.dist-info}/licenses/LICENSE +0 -0
  69. {scratchattach-2.1.14.dist-info → scratchattach-3.0.0b0.dist-info}/top_level.txt +0 -0
@@ -1,357 +0,0 @@
1
- """
2
- Enums stating the shape of a block from its opcode (i.e: stack, c-mouth, cap, hat etc)
3
- """
4
- from __future__ import annotations
5
-
6
- # Perhaps this should be merged with pallete.py
7
- from dataclasses import dataclass
8
- from typing import Final
9
-
10
- from . import commons
11
- from scratchattach.utils.enums import _EnumWrapper
12
-
13
-
14
- class _MutationDependent(commons.Singleton):
15
- """
16
- Singleton value that represents the uncertainty of a vablue because it depends on block mutation data.
17
- """
18
- INSTANCE = 0
19
- def __bool__(self):
20
- raise TypeError("Need mutation data to work out attribute value.")
21
-
22
-
23
- MUTATION_DEPENDENT: Final[_MutationDependent] = _MutationDependent()
24
- """Value used when mutation data is required to work out the attribute value"""
25
-
26
-
27
- @dataclass(init=True, repr=True)
28
- class BlockShape:
29
- """
30
- The shape of a block; e.g. is it a stack, c-mouth, cap, hat reporter, boolean or menu block?
31
- """
32
- is_stack: bool | _MutationDependent = False # Most blocks - e.g. move [10] steps
33
- is_c_mouth: bool | _MutationDependent = False # Has substack - e.g. repeat
34
- is_cap: bool | _MutationDependent = False # No next - e.g. forever
35
- is_hat: bool | _MutationDependent = False # No parent - e.g. when gf clicked
36
- is_reporter: bool | _MutationDependent = False # (reporter)
37
- is_boolean: bool | _MutationDependent = False # <reporter>
38
- is_menu: bool | _MutationDependent = False # Shadow reporters, e.g. costume menu
39
- opcode: str = None
40
-
41
- @property
42
- def is_attachable(self):
43
- if self.is_cap is MUTATION_DEPENDENT:
44
- raise TypeError(
45
- "Can't tell if the block is attachable because we can't be sure if it is a cap block or not (stop block)")
46
- return not self.is_cap and not self.is_reporter
47
-
48
-
49
- class BlockShapes(_EnumWrapper):
50
- MOTION_MOVESTEPS = BlockShape(is_stack=True, opcode="motion_movesteps")
51
- MOTION_TURNRIGHT = BlockShape(is_stack=True, opcode="motion_turnright")
52
- MOTION_TURNLEFT = BlockShape(is_stack=True, opcode="motion_turnleft")
53
- MOTION_GOTO = BlockShape(is_stack=True, opcode="motion_goto")
54
- MOTION_GOTOXY = BlockShape(is_stack=True, opcode="motion_gotoxy")
55
- MOTION_GLIDETO = BlockShape(is_stack=True, opcode="motion_glideto")
56
- MOTION_GLIDESECSTOXY = BlockShape(is_stack=True, opcode="motion_glidesecstoxy")
57
- MOTION_POINTINDIRECTION = BlockShape(is_stack=True, opcode="motion_pointindirection")
58
- MOTION_POINTTOWARDS = BlockShape(is_stack=True, opcode="motion_pointtowards")
59
- MOTION_CHANGEXBY = BlockShape(is_stack=True, opcode="motion_changexby")
60
- MOTION_SETX = BlockShape(is_stack=True, opcode="motion_setx")
61
- MOTION_CHANGEYBY = BlockShape(is_stack=True, opcode="motion_changeyby")
62
- MOTION_SETY = BlockShape(is_stack=True, opcode="motion_sety")
63
- MOTION_IFONEDGEBOUNCE = BlockShape(is_stack=True, opcode="motion_ifonedgebounce")
64
- MOTION_SETROTATIONSTYLE = BlockShape(is_stack=True, opcode="motion_setrotationstyle")
65
- MOTION_XPOSITION = BlockShape(is_reporter=True, opcode="motion_xposition")
66
- MOTION_YPOSITION = BlockShape(is_reporter=True, opcode="motion_yposition")
67
- MOTION_DIRECTION = BlockShape(is_reporter=True, opcode="motion_direction")
68
- MOTION_SCROLL_RIGHT = BlockShape(is_stack=True, opcode="motion_scroll_right")
69
- MOTION_SCROLL_UP = BlockShape(is_stack=True, opcode="motion_scroll_up")
70
- MOTION_ALIGN_SCENE = BlockShape(is_stack=True, opcode="motion_align_scene")
71
- MOTION_XSCROLL = BlockShape(is_reporter=True, opcode="motion_xscroll")
72
- MOTION_YSCROLL = BlockShape(is_reporter=True, opcode="motion_yscroll")
73
- MOTION_GOTO_MENU = BlockShape(is_reporter=True, is_menu=True, opcode="motion_goto_menu")
74
- MOTION_GLIDETO_MENU = BlockShape(is_reporter=True, is_menu=True, opcode="motion_glideto_menu")
75
- MOTION_POINTTOWARDS_MENU = BlockShape(is_reporter=True, is_menu=True, opcode="motion_pointtowards_menu")
76
-
77
- LOOKS_SAYFORSECS = BlockShape(is_stack=True, opcode="looks_sayforsecs")
78
- LOOKS_SAY = BlockShape(is_stack=True, opcode="looks_say")
79
- LOOKS_THINKFORSECS = BlockShape(is_stack=True, opcode="looks_thinkforsecs")
80
- LOOKS_THINK = BlockShape(is_stack=True, opcode="looks_think")
81
- LOOKS_SWITCHCOSTUMETO = BlockShape(is_stack=True, opcode="looks_switchcostumeto")
82
- LOOKS_NEXTCOSTUME = BlockShape(is_stack=True, opcode="looks_nextcostume")
83
- LOOKS_SWITCHBACKDROPTO = BlockShape(is_stack=True, opcode="looks_switchbackdropto")
84
- LOOKS_SWITCHBACKDROPTOANDWAIT = BlockShape(is_stack=True, opcode="looks_switchbackdroptoandwait")
85
- LOOKS_NEXTBACKDROP = BlockShape(is_stack=True, opcode="looks_nextbackdrop")
86
- LOOKS_CHANGESIZEBY = BlockShape(is_stack=True, opcode="looks_changesizeby")
87
- LOOKS_SETSIZETO = BlockShape(is_stack=True, opcode="looks_setsizeto")
88
- LOOKS_CHANGEEFFECTBY = BlockShape(is_stack=True, opcode="looks_changeeffectby")
89
- LOOKS_SETEFFECTTO = BlockShape(is_stack=True, opcode="looks_seteffectto")
90
- LOOKS_CLEARGRAPHICEFFECTS = BlockShape(is_stack=True, opcode="looks_cleargraphiceffects")
91
- LOOKS_SHOW = BlockShape(is_stack=True, opcode="looks_show")
92
- LOOKS_HIDE = BlockShape(is_stack=True, opcode="looks_hide")
93
- LOOKS_GOTOFRONTBACK = BlockShape(is_stack=True, opcode="looks_gotofrontback")
94
- LOOKS_GOFORWARDBACKWARDLAYERS = BlockShape(is_stack=True, opcode="looks_goforwardbackwardlayers")
95
- LOOKS_COSTUMENUMBERNAME = BlockShape(is_reporter=True, opcode="looks_costumenumbername")
96
- LOOKS_BACKDROPNUMBERNAME = BlockShape(is_reporter=True, opcode="looks_backdropnumbername")
97
- LOOKS_SIZE = BlockShape(is_reporter=True, opcode="looks_size")
98
- LOOKS_HIDEALLSPRITES = BlockShape(is_stack=True, opcode="looks_hideallsprites")
99
- LOOKS_SETSTRETCHTO = BlockShape(is_stack=True, opcode="looks_setstretchto")
100
- LOOKS_CHANGESTRETCHBY = BlockShape(is_stack=True, opcode="looks_changestretchby")
101
- LOOKS_COSTUME = BlockShape(is_reporter=True, is_menu=True, opcode="looks_costume")
102
- LOOKS_BACKDROPS = BlockShape(is_reporter=True, is_menu=True, opcode="looks_backdrops")
103
-
104
- SOUND_PLAYUNTILDONE = BlockShape(is_stack=True, opcode="sound_playuntildone")
105
- SOUND_PLAY = BlockShape(is_stack=True, opcode="sound_play")
106
- SOUND_STOPALLSOUNDS = BlockShape(is_stack=True, opcode="sound_stopallsounds")
107
- SOUND_CHANGEEFFECTBY = BlockShape(is_stack=True, opcode="sound_changeeffectby")
108
- SOUND_SETEFFECTTO = BlockShape(is_stack=True, opcode="sound_seteffectto")
109
- SOUND_CLEAREFFECTS = BlockShape(is_stack=True, opcode="sound_cleareffects")
110
- SOUND_CHANGEVOLUMEBY = BlockShape(is_stack=True, opcode="sound_changevolumeby")
111
- SOUND_SETVOLUMETO = BlockShape(is_stack=True, opcode="sound_setvolumeto")
112
- SOUND_VOLUME = BlockShape(is_reporter=True, opcode="sound_volume")
113
- SOUND_SOUNDS_MENU = BlockShape(is_reporter=True, is_menu=True, opcode="sound_sounds_menu")
114
-
115
- EVENT_WHENFLAGCLICKED = BlockShape(is_hat=True, opcode="event_whenflagclicked")
116
- EVENT_WHENKEYPRESSED = BlockShape(is_hat=True, opcode="event_whenkeypressed")
117
- EVENT_WHENTHISSPRITECLICKED = BlockShape(is_hat=True, opcode="event_whenthisspriteclicked")
118
- EVENT_WHENSTAGECLICKED = BlockShape(is_hat=True, opcode="event_whenstageclicked")
119
- EVENT_WHENBACKDROPSWITCHESTO = BlockShape(is_hat=True, opcode="event_whenbackdropswitchesto")
120
- EVENT_WHENGREATERTHAN = BlockShape(is_hat=True, opcode="event_whengreaterthan")
121
- EVENT_WHENBROADCASTRECEIVED = BlockShape(is_hat=True, opcode="event_whenbroadcastreceived")
122
- EVENT_BROADCAST = BlockShape(is_stack=True, opcode="event_broadcast")
123
- EVENT_BROADCASTANDWAIT = BlockShape(is_stack=True, opcode="event_broadcastandwait")
124
- EVENT_WHENTOUCHINGOBJECT = BlockShape(is_hat=True, opcode="event_whentouchingobject")
125
- EVENT_BROADCAST_MENU = BlockShape(is_reporter=True, is_menu=True, opcode="event_broadcast_menu")
126
- EVENT_TOUCHINGOBJECTMENU = BlockShape(is_reporter=True, is_menu=True, opcode="event_touchingobjectmenu")
127
-
128
- CONTROL_WAIT = BlockShape(is_stack=True, opcode="control_wait")
129
- CONTROL_FOREVER = BlockShape(is_c_mouth=True, is_stack=True, is_cap=True, opcode="control_forever")
130
- CONTROL_IF = BlockShape(is_c_mouth=True, is_stack=True, opcode="control_if")
131
- CONTROL_IF_ELSE = BlockShape(is_c_mouth=True, is_stack=True, opcode="control_if_else")
132
- CONTROL_WAIT_UNTIL = BlockShape(is_stack=True, opcode="control_wait_until")
133
- CONTROL_REPEAT_UNTIL = BlockShape(is_c_mouth=True, is_stack=True, opcode="control_repeat_until")
134
- CONTROL_STOP = BlockShape(is_stack=True, is_cap=MUTATION_DEPENDENT, opcode="control_stop")
135
- CONTROL_START_AS_CLONE = BlockShape(is_hat=True, opcode="control_start_as_clone")
136
- CONTROL_CREATE_CLONE_OF = BlockShape(is_stack=True, opcode="control_create_clone_of")
137
- CONTROL_DELETE_THIS_CLONE = BlockShape(is_stack=True, is_cap=True, opcode="control_delete_this_clone")
138
- CONTROL_FOR_EACH = BlockShape(is_c_mouth=True, is_stack=True, opcode="control_for_each")
139
- CONTROL_WHILE = BlockShape(is_c_mouth=True, is_stack=True, opcode="control_while")
140
- CONTROL_GET_COUNTER = BlockShape(is_reporter=True, opcode="control_get_counter")
141
- CONTROL_INCR_COUNTER = BlockShape(is_stack=True, opcode="control_incr_counter")
142
- CONTROL_CLEAR_COUNTER = BlockShape(is_stack=True, opcode="control_clear_counter")
143
- CONTROL_ALL_AT_ONCE = BlockShape(is_c_mouth=True, is_stack=True, opcode="control_all_at_once")
144
- CONTROL_CREATE_CLONE_OF_MENU = BlockShape(is_reporter=True, is_menu=True, opcode="control_create_clone_of_menu")
145
-
146
- SENSING_TOUCHINGOBJECT = BlockShape(is_reporter=True, is_boolean=True, opcode="sensing_touchingobject")
147
- SENSING_TOUCHINGCOLOR = BlockShape(is_reporter=True, is_boolean=True, opcode="sensing_touchingcolor")
148
- SENSING_COLORISTOUCHINGCOLOR = BlockShape(is_reporter=True, is_boolean=True, opcode="sensing_coloristouchingcolor")
149
- SENSING_DISTANCETO = BlockShape(is_reporter=True, opcode="sensing_distanceto")
150
- SENSING_ASKANDWAIT = BlockShape(is_stack=True, opcode="sensing_askandwait")
151
- SENSING_ANSWER = BlockShape(is_reporter=True, opcode="sensing_answer")
152
- SENSING_KEYPRESSED = BlockShape(is_reporter=True, is_boolean=True, opcode="sensing_keypressed")
153
- SENSING_MOUSEDOWN = BlockShape(is_reporter=True, is_boolean=True, opcode="sensing_mousedown")
154
- SENSING_MOUSEX = BlockShape(is_reporter=True, opcode="sensing_mousex")
155
- SENSING_MOUSEY = BlockShape(is_reporter=True, opcode="sensing_mousey")
156
- SENSING_SETDRAGMODE = BlockShape(is_stack=True, opcode="sensing_setdragmode")
157
- SENSING_LOUDNESS = BlockShape(is_reporter=True, opcode="sensing_loudness")
158
- SENSING_TIMER = BlockShape(is_reporter=True, opcode="sensing_timer")
159
- SENSING_RESETTIMER = BlockShape(is_stack=True, opcode="sensing_resettimer")
160
- SENSING_OF = BlockShape(is_reporter=True, opcode="sensing_of")
161
- SENSING_CURRENT = BlockShape(is_reporter=True, opcode="sensing_current")
162
- SENSING_DAYSSINCE2000 = BlockShape(is_reporter=True, opcode="sensing_dayssince2000")
163
- SENSING_USERNAME = BlockShape(is_reporter=True, opcode="sensing_username")
164
- SENSING_LOUD = BlockShape(is_reporter=True, is_boolean=True, opcode="sensing_loud")
165
- SENSING_USERID = BlockShape(is_reporter=True, opcode="sensing_userid")
166
- SENSING_TOUCHINGOBJECTMENU = BlockShape(is_reporter=True, is_menu=True, opcode="sensing_touchingobjectmenu")
167
- SENSING_DISTANCETOMENU = BlockShape(is_reporter=True, is_menu=True, opcode="sensing_distancetomenu")
168
- SENSING_KEYOPTIONS = BlockShape(is_reporter=True, is_menu=True, opcode="sensing_keyoptions")
169
- SENSING_OF_OBJECT_MENU = BlockShape(is_reporter=True, is_menu=True, opcode="sensing_of_object_menu")
170
-
171
- OPERATOR_ADD = BlockShape(is_reporter=True, opcode="operator_add")
172
- OPERATOR_SUBTRACT = BlockShape(is_reporter=True, opcode="operator_subtract")
173
- OPERATOR_MULTIPLY = BlockShape(is_reporter=True, opcode="operator_multiply")
174
- OPERATOR_DIVIDE = BlockShape(is_reporter=True, opcode="operator_divide")
175
- OPERATOR_RANDOM = BlockShape(is_reporter=True, opcode="operator_random")
176
- OPERATOR_GT = BlockShape(is_reporter=True, is_boolean=True, opcode="operator_gt")
177
- OPERATOR_LT = BlockShape(is_reporter=True, is_boolean=True, opcode="operator_lt")
178
- OPERATOR_EQUALS = BlockShape(is_reporter=True, is_boolean=True, opcode="operator_equals")
179
- OPERATOR_AND = BlockShape(is_reporter=True, is_boolean=True, opcode="operator_and")
180
- OPERATOR_OR = BlockShape(is_reporter=True, is_boolean=True, opcode="operator_or")
181
- OPERATOR_NOT = BlockShape(is_reporter=True, is_boolean=True, opcode="operator_not")
182
- OPERATOR_JOIN = BlockShape(is_reporter=True, opcode="operator_join")
183
- OPERATOR_LETTER_OF = BlockShape(is_reporter=True, opcode="operator_letter_of")
184
- OPERATOR_LENGTH = BlockShape(is_reporter=True, opcode="operator_length")
185
- OPERATOR_CONTAINS = BlockShape(is_reporter=True, is_boolean=True, opcode="operator_contains")
186
- OPERATOR_MOD = BlockShape(is_reporter=True, opcode="operator_mod")
187
- OPERATOR_ROUND = BlockShape(is_reporter=True, opcode="operator_round")
188
- OPERATOR_MATHOP = BlockShape(is_reporter=True, opcode="operator_mathop")
189
-
190
- DATA_VARIABLE = BlockShape(is_reporter=True, opcode="data_variable")
191
- DATA_SETVARIABLETO = BlockShape(is_stack=True, opcode="data_setvariableto")
192
- DATA_CHANGEVARIABLEBY = BlockShape(is_stack=True, opcode="data_changevariableby")
193
- DATA_SHOWVARIABLE = BlockShape(is_stack=True, opcode="data_showvariable")
194
- DATA_HIDEVARIABLE = BlockShape(is_stack=True, opcode="data_hidevariable")
195
- DATA_LISTCONTENTS = BlockShape(is_reporter=True, opcode="data_listcontents")
196
- DATA_ADDTOLIST = BlockShape(is_stack=True, opcode="data_addtolist")
197
- DATA_DELETEOFLIST = BlockShape(is_stack=True, opcode="data_deleteoflist")
198
- DATA_DELETEALLOFLIST = BlockShape(is_stack=True, opcode="data_deletealloflist")
199
- DATA_INSERTATLIST = BlockShape(is_stack=True, opcode="data_insertatlist")
200
- DATA_REPLACEITEMOFLIST = BlockShape(is_stack=True, opcode="data_replaceitemoflist")
201
- DATA_ITEMOFLIST = BlockShape(is_reporter=True, is_boolean=True, opcode="data_itemoflist")
202
- DATA_ITEMNUMOFLIST = BlockShape(is_reporter=True, opcode="data_itemnumoflist")
203
- DATA_LENGTHOFLIST = BlockShape(is_reporter=True, opcode="data_lengthoflist")
204
- DATA_LISTCONTAINSITEM = BlockShape(is_reporter=True, is_boolean=True, opcode="data_listcontainsitem")
205
- DATA_SHOWLIST = BlockShape(is_stack=True, opcode="data_showlist")
206
- DATA_HIDELIST = BlockShape(is_stack=True, opcode="data_hidelist")
207
- DATA_LISTINDEXALL = BlockShape(is_reporter=True, is_menu=True, opcode="data_listindexall")
208
- DATA_LISTINDEXRANDOM = BlockShape(is_reporter=True, is_menu=True, opcode="data_listindexrandom")
209
-
210
- PROCEDURES_DEFINITION = BlockShape(is_hat=True, opcode="procedures_definition")
211
- PROCEDURES_CALL = BlockShape(is_stack=True, opcode="procedures_call")
212
- PROCEDURES_DECLARATION = BlockShape(is_stack=True, opcode="procedures_declaration")
213
- PROCEDURES_PROTOTYPE = BlockShape(is_stack=True, opcode="procedures_prototype")
214
-
215
- ARGUMENT_REPORTER_STRING_NUMBER = BlockShape(is_reporter=True, opcode="argument_reporter_string_number")
216
- ARGUMENT_REPORTER_BOOLEAN = BlockShape(is_reporter=True, is_boolean=True, opcode="argument_reporter_boolean")
217
- ARGUMENT_EDITOR_REPORTER = BlockShape(is_reporter=True, is_boolean=True, opcode="argument_editor_reporter")
218
- ARGUMENT_EDITOR_STRING_NUMBER = BlockShape(is_reporter=True, opcode="argument_editor_string_number")
219
-
220
- MUSIC_PLAYDRUMFORBEATS = BlockShape(is_stack=True, opcode="music_playDrumForBeats")
221
- MUSIC_RESTFORBEATS = BlockShape(is_stack=True, opcode="music_restForBeats")
222
- MUSIC_PLAYNOTEFORBEATS = BlockShape(is_stack=True, opcode="music_playNoteForBeats")
223
- MUSIC_SETINSTRUMENT = BlockShape(is_stack=True, opcode="music_setInstrument")
224
- MUSIC_SETTEMPO = BlockShape(is_stack=True, opcode="music_setTempo")
225
- MUSIC_CHANGETEMPO = BlockShape(is_stack=True, opcode="music_changeTempo")
226
- MUSIC_GETTEMPO = BlockShape(is_reporter=True, opcode="music_getTempo")
227
- MUSIC_MIDIPLAYDRUMFORBEATS = BlockShape(is_stack=True, opcode="music_midiPlayDrumForBeats")
228
- MUSIC_MIDISETINSTRUMENT = BlockShape(is_stack=True, opcode="music_midiSetInstrument")
229
- MUSIC_MENU_DRUM = BlockShape(is_reporter=True, is_menu=True, opcode="music_menu_DRUM")
230
- MUSIC_MENU_INSTRUMENT = BlockShape(is_reporter=True, is_menu=True, opcode="music_menu_INSTRUMENT")
231
-
232
- PEN_CLEAR = BlockShape(is_stack=True, opcode="pen_clear")
233
- PEN_STAMP = BlockShape(is_stack=True, opcode="pen_stamp")
234
- PEN_PENDOWN = BlockShape(is_stack=True, opcode="pen_penDown")
235
- PEN_PENUP = BlockShape(is_stack=True, opcode="pen_penUp")
236
- PEN_SETPENCOLORTOCOLOR = BlockShape(is_stack=True, opcode="pen_setPenColorToColor")
237
- PEN_CHANGEPENCOLORPARAMBY = BlockShape(is_stack=True, opcode="pen_changePenColorParamBy")
238
- PEN_SETPENCOLORPARAMTO = BlockShape(is_stack=True, opcode="pen_setPenColorParamTo")
239
- PEN_CHANGEPENSIZEBY = BlockShape(is_stack=True, opcode="pen_changePenSizeBy")
240
- PEN_SETPENSIZETO = BlockShape(is_stack=True, opcode="pen_setPenSizeTo")
241
- PEN_SETPENHUETONUMBER = BlockShape(is_stack=True, opcode="pen_setPenHueToNumber")
242
- PEN_CHANGEPENHUEBY = BlockShape(is_stack=True, opcode="pen_changePenHueBy")
243
- PEN_SETPENSHADETONUMBER = BlockShape(is_stack=True, opcode="pen_setPenShadeToNumber")
244
- PEN_CHANGEPENSHADEBY = BlockShape(is_stack=True, opcode="pen_changePenShadeBy")
245
- PEN_MENU_COLORPARAM = BlockShape(is_reporter=True, is_menu=True, opcode="pen_menu_colorParam")
246
-
247
- VIDEOSENSING_WHENMOTIONGREATERTHAN = BlockShape(is_hat=True, opcode="videoSensing_whenMotionGreaterThan")
248
- VIDEOSENSING_VIDEOON = BlockShape(is_reporter=True, opcode="videoSensing_videoOn")
249
- VIDEOSENSING_VIDEOTOGGLE = BlockShape(is_stack=True, opcode="videoSensing_videoToggle")
250
- VIDEOSENSING_SETVIDEOTRANSPARENCY = BlockShape(is_stack=True, opcode="videoSensing_setVideoTransparency")
251
- VIDEOSENSING_MENU_ATTRIBUTE = BlockShape(is_reporter=True, is_menu=True, opcode="videoSensing_menu_ATTRIBUTE")
252
- VIDEOSENSING_MENU_SUBJECT = BlockShape(is_reporter=True, is_menu=True, opcode="videoSensing_menu_SUBJECT")
253
- VIDEOSENSING_MENU_VIDEO_STATE = BlockShape(is_reporter=True, is_menu=True, opcode="videoSensing_menu_VIDEO_STATE")
254
-
255
- TEXT2SPEECH_SPEAKANDWAIT = BlockShape(is_stack=True, opcode="text2speech_speakAndWait")
256
- TEXT2SPEECH_SETVOICE = BlockShape(is_stack=True, opcode="text2speech_setVoice")
257
- TEXT2SPEECH_SETLANGUAGE = BlockShape(is_stack=True, opcode="text2speech_setLanguage")
258
- TEXT2SPEECH_MENU_VOICES = BlockShape(is_reporter=True, is_menu=True, opcode="text2speech_menu_voices")
259
- TEXT2SPEECH_MENU_LANGUAGES = BlockShape(is_reporter=True, is_menu=True, opcode="text2speech_menu_languages")
260
- TRANSLATE_GETTRANSLATE = BlockShape(is_reporter=True, opcode="translate_getTranslate")
261
- TRANSLATE_GETVIEWERLANGUAGE = BlockShape(is_reporter=True, opcode="translate_getViewerLanguage")
262
- TRANSLATE_MENU_LANGUAGES = BlockShape(is_reporter=True, is_menu=True, opcode="translate_menu_languages")
263
-
264
- MAKEYMAKEY_WHENMAKEYKEYPRESSED = BlockShape(is_hat=True, opcode="makeymakey_whenMakeyKeyPressed")
265
- MAKEYMAKEY_WHENCODEPRESSED = BlockShape(is_hat=True, opcode="makeymakey_whenCodePressed")
266
- MAKEYMAKEY_MENU_KEY = BlockShape(is_reporter=True, is_menu=True, opcode="makeymakey_menu_KEY")
267
- MAKEYMAKEY_MENU_SEQUENCE = BlockShape(is_reporter=True, is_menu=True, opcode="makeymakey_menu_SEQUENCE")
268
-
269
- MICROBIT_WHENBUTTONPRESSED = BlockShape(opcode="microbit_whenButtonPressed") # todo: finish this
270
- MICROBIT_ISBUTTONPRESSED = BlockShape(opcode="microbit_isButtonPressed")
271
- MICROBIT_WHENGESTURE = BlockShape(opcode="microbit_whenGesture")
272
- MICROBIT_DISPLAYSYMBOL = BlockShape(opcode="microbit_displaySymbol")
273
- MICROBIT_DISPLAYTEXT = BlockShape(opcode="microbit_displayText")
274
- MICROBIT_DISPLAYCLEAR = BlockShape(opcode="microbit_displayClear")
275
- MICROBIT_WHENTILTED = BlockShape(opcode="microbit_whenTilted")
276
- MICROBIT_ISTILTED = BlockShape(opcode="microbit_isTilted")
277
- MICROBIT_GETTILTANGLE = BlockShape(opcode="microbit_getTiltAngle")
278
- MICROBIT_WHENPINCONNECTED = BlockShape(opcode="microbit_whenPinConnected")
279
- MICROBIT_MENU_BUTTONS = BlockShape(opcode="microbit_menu_buttons")
280
- MICROBIT_MENU_GESTURES = BlockShape(opcode="microbit_menu_gestures")
281
- MICROBIT_MENU_TILTDIRECTIONANY = BlockShape(opcode="microbit_menu_tiltDirectionAny")
282
- MICROBIT_MENU_TILTDIRECTION = BlockShape(opcode="microbit_menu_tiltDirection")
283
- MICROBIT_MENU_TOUCHPINS = BlockShape(opcode="microbit_menu_touchPins")
284
- MICROBIT_MENU_PINSTATE = BlockShape(opcode="microbit_menu_pinState")
285
-
286
- EV3_MOTORTURNCLOCKWISE = BlockShape(opcode="ev3_motorTurnClockwise")
287
- EV3_MOTORTURNCOUNTERCLOCKWISE = BlockShape(opcode="ev3_motorTurnCounterClockwise")
288
- EV3_MOTORSETPOWER = BlockShape(opcode="ev3_motorSetPower")
289
- EV3_GETMOTORPOSITION = BlockShape(opcode="ev3_getMotorPosition")
290
- EV3_WHENBUTTONPRESSED = BlockShape(opcode="ev3_whenButtonPressed")
291
- EV3_WHENDISTANCELESSTHAN = BlockShape(opcode="ev3_whenDistanceLessThan")
292
- EV3_WHENBRIGHTNESSLESSTHAN = BlockShape(opcode="ev3_whenBrightnessLessThan")
293
- EV3_BUTTONPRESSED = BlockShape(opcode="ev3_buttonPressed")
294
- EV3_GETDISTANCE = BlockShape(opcode="ev3_getDistance")
295
- EV3_GETBRIGHTNESS = BlockShape(opcode="ev3_getBrightness")
296
- EV3_BEEP = BlockShape(opcode="ev3_beep")
297
- EV3_MENU_MOTORPORTS = BlockShape(opcode="ev3_menu_motorPorts")
298
- EV3_MENU_SENSORPORTS = BlockShape(opcode="ev3_menu_sensorPorts")
299
-
300
- BOOST_MOTORONFOR = BlockShape(opcode="boost_motorOnFor")
301
- BOOST_MOTORONFORROTATION = BlockShape(opcode="boost_motorOnForRotation")
302
- BOOST_MOTORON = BlockShape(opcode="boost_motorOn")
303
- BOOST_MOTOROFF = BlockShape(opcode="boost_motorOff")
304
- BOOST_SETMOTORPOWER = BlockShape(opcode="boost_setMotorPower")
305
- BOOST_SETMOTORDIRECTION = BlockShape(opcode="boost_setMotorDirection")
306
- BOOST_GETMOTORPOSITION = BlockShape(opcode="boost_getMotorPosition")
307
- BOOST_WHENCOLOR = BlockShape(opcode="boost_whenColor")
308
- BOOST_SEEINGCOLOR = BlockShape(opcode="boost_seeingColor")
309
- BOOST_WHENTILTED = BlockShape(opcode="boost_whenTilted")
310
- BOOST_GETTILTANGLE = BlockShape(opcode="boost_getTiltAngle")
311
- BOOST_SETLIGHTHUE = BlockShape(opcode="boost_setLightHue")
312
- BOOST_MENU_MOTOR_ID = BlockShape(opcode="boost_menu_MOTOR_ID")
313
- BOOST_MENU_MOTOR_DIRECTION = BlockShape(opcode="boost_menu_MOTOR_DIRECTION")
314
- BOOST_MENU_MOTOR_REPORTER_ID = BlockShape(opcode="boost_menu_MOTOR_REPORTER_ID")
315
- BOOST_MENU_COLOR = BlockShape(opcode="boost_menu_COLOR")
316
- BOOST_MENU_TILT_DIRECTION_ANY = BlockShape(opcode="boost_menu_TILT_DIRECTION_ANY")
317
- BOOST_MENU_TILT_DIRECTION = BlockShape(opcode="boost_menu_TILT_DIRECTION")
318
-
319
- WEDO2_MOTORONFOR = BlockShape(opcode="wedo2_motorOnFor")
320
- WEDO2_MOTORON = BlockShape(opcode="wedo2_motorOn")
321
- WEDO2_MOTOROFF = BlockShape(opcode="wedo2_motorOff")
322
- WEDO2_STARTMOTORPOWER = BlockShape(opcode="wedo2_startMotorPower")
323
- WEDO2_SETMOTORDIRECTION = BlockShape(opcode="wedo2_setMotorDirection")
324
- WEDO2_SETLIGHTHUE = BlockShape(opcode="wedo2_setLightHue")
325
- WEDO2_WHENDISTANCE = BlockShape(opcode="wedo2_whenDistance")
326
- WEDO2_WHENTILTED = BlockShape(opcode="wedo2_whenTilted")
327
- WEDO2_GETDISTANCE = BlockShape(opcode="wedo2_getDistance")
328
- WEDO2_ISTILTED = BlockShape(opcode="wedo2_isTilted")
329
- WEDO2_GETTILTANGLE = BlockShape(opcode="wedo2_getTiltAngle")
330
- WEDO2_PLAYNOTEFOR = BlockShape(opcode="wedo2_playNoteFor")
331
- WEDO2_MENU_MOTOR_ID = BlockShape(opcode="wedo2_menu_MOTOR_ID")
332
- WEDO2_MENU_MOTOR_DIRECTION = BlockShape(opcode="wedo2_menu_MOTOR_DIRECTION")
333
- WEDO2_MENU_OP = BlockShape(opcode="wedo2_menu_OP")
334
- WEDO2_MENU_TILT_DIRECTION_ANY = BlockShape(opcode="wedo2_menu_TILT_DIRECTION_ANY")
335
- WEDO2_MENU_TILT_DIRECTION = BlockShape(opcode="wedo2_menu_TILT_DIRECTION")
336
-
337
- GDXFOR_WHENGESTURE = BlockShape(opcode="gdxfor_whenGesture")
338
- GDXFOR_WHENFORCEPUSHEDORPULLED = BlockShape(opcode="gdxfor_whenForcePushedOrPulled")
339
- GDXFOR_GETFORCE = BlockShape(opcode="gdxfor_getForce")
340
- GDXFOR_WHENTILTED = BlockShape(opcode="gdxfor_whenTilted")
341
- GDXFOR_ISTILTED = BlockShape(opcode="gdxfor_isTilted")
342
- GDXFOR_GETTILT = BlockShape(opcode="gdxfor_getTilt")
343
- GDXFOR_ISFREEFALLING = BlockShape(opcode="gdxfor_isFreeFalling")
344
- GDXFOR_GETSPINSPEED = BlockShape(opcode="gdxfor_getSpinSpeed")
345
- GDXFOR_GETACCELERATION = BlockShape(opcode="gdxfor_getAcceleration")
346
- GDXFOR_MENU_GESTUREOPTIONS = BlockShape(opcode="gdxfor_menu_gestureOptions")
347
- GDXFOR_MENU_PUSHPULLOPTIONS = BlockShape(opcode="gdxfor_menu_pushPullOptions")
348
- GDXFOR_MENU_TILTANYOPTIONS = BlockShape(opcode="gdxfor_menu_tiltAnyOptions")
349
- GDXFOR_MENU_TILTOPTIONS = BlockShape(opcode="gdxfor_menu_tiltOptions")
350
- GDXFOR_MENU_AXISOPTIONS = BlockShape(opcode="gdxfor_menu_axisOptions")
351
-
352
- COREEXAMPLE_EXAMPLEOPCODE = BlockShape(is_reporter=True, opcode="coreExample_exampleOpcode")
353
- COREEXAMPLE_EXAMPLEWITHINLINEIMAGE = BlockShape(is_stack=True, opcode="coreExample_exampleWithInlineImage")
354
-
355
- NOTE = BlockShape(is_reporter=True, is_menu=True, opcode="note")
356
- MATRIX = BlockShape(is_reporter=True, is_menu=True, opcode="matrix")
357
- UNDEFINED = BlockShape(is_hat=True, is_cap=True, opcode="red_hat_block")
@@ -1,51 +0,0 @@
1
- """
2
- Module which stores the 'default' or 'current' selected Sprite/project (stored as a stack) which makes it easier to write scratch code directly in Python
3
- """
4
- from __future__ import annotations
5
-
6
- from typing import Iterable, TYPE_CHECKING, Final, Literal
7
-
8
- if TYPE_CHECKING:
9
- from . import sprite, block, prim, comment
10
- from . import commons
11
-
12
-
13
- class _SetSprite(commons.Singleton):
14
- INSTANCE = 0
15
- def __repr__(self):
16
- return f'<Reminder to default your sprite to {current_sprite()}>'
17
-
18
-
19
- SPRITE_DEFAULT: Final[Literal[_SetSprite.INSTANCE]] = _SetSprite.INSTANCE
20
-
21
- _sprite_stack: list[sprite.Sprite] = []
22
-
23
-
24
- def stack_add_sprite(_sprite: sprite.Sprite):
25
- _sprite_stack.append(_sprite)
26
-
27
-
28
- def current_sprite() -> sprite.Sprite | None:
29
- """
30
- Retrieve the default sprite from the top of the sprite stack
31
- """
32
- if len(_sprite_stack) == 0:
33
- return None
34
- return _sprite_stack[-1]
35
-
36
-
37
- def pop_sprite(_sprite: sprite.Sprite) -> sprite.Sprite | None:
38
- assert _sprite_stack.pop() == _sprite
39
- return _sprite
40
-
41
-
42
- def add_block(_block: block.Block | prim.Prim) -> block.Block | prim.Prim:
43
- return current_sprite().add_block(_block)
44
-
45
-
46
- def add_chain(*chain: Iterable[block.Block, prim.Prim]) -> block.Block | prim.Prim:
47
- return current_sprite().add_chain(*chain)
48
-
49
-
50
- def add_comment(_comment: comment.Comment):
51
- return current_sprite().add_comment(_comment)
File without changes
@@ -1,177 +0,0 @@
1
- from __future__ import annotations
2
- from pathlib import Path
3
- from typing import Union, Generic, TypeVar
4
- from abc import ABC, abstractmethod
5
- from collections.abc import Sequence
6
-
7
- from lark import Lark, Transformer, Tree, Token, v_args
8
- from lark.reconstruct import Reconstructor
9
-
10
- R = TypeVar("R")
11
- class SupportsRead(ABC, Generic[R]):
12
- @abstractmethod
13
- def read(self, size: int | None = -1) -> R:
14
- pass
15
-
16
- LANG_PATH = Path(__file__).parent / "language.lark"
17
-
18
- lang = Lark(LANG_PATH.read_text(), maybe_placeholders=False)
19
- reconstructor = Reconstructor(lang)
20
-
21
- def parse(script: Union[str, bytes, SupportsRead[str], Path]) -> Tree:
22
- if isinstance(script, Path):
23
- script = script.read_text()
24
- if isinstance(script, SupportsRead):
25
- read_data = script.read()
26
- assert isinstance(read_data, str)
27
- script = read_data
28
- if isinstance(script, bytes):
29
- script = script.decode("utf-8")
30
- return lang.parse(script)
31
-
32
- def unparse(tree: Tree) -> str:
33
- return reconstructor.reconstruct(tree)
34
-
35
- class PrettyUnparser(Transformer):
36
- INDENT_STRING = " "
37
-
38
- @classmethod
39
- def _indent(cls, text):
40
- if not text:
41
- return ""
42
- return "\n".join(cls.INDENT_STRING + line for line in text.splitlines())
43
-
44
- def PARAM_NAME(self, token):
45
- return token.value
46
-
47
- def BLOCK_NAME(self, token):
48
- return token.value
49
-
50
- def EVENT(self, token):
51
- return token.value
52
-
53
- def CONTROL_BLOCK_NAME(self, token):
54
- return token.value
55
-
56
- def _PREPROC_INSTR_CONTENT(self, token):
57
- return token.value
58
-
59
- def _COMMMENT_CONTENT(self, token):
60
- return token.value
61
-
62
- @v_args(inline=True)
63
- def hat(self, child):
64
- return child
65
-
66
- @v_args(inline=True)
67
- def param(self, child):
68
- return child
69
-
70
- @v_args(inline=True)
71
- def value_param(self, name):
72
- return name
73
-
74
- @v_args(inline=True)
75
- def bool_param(self, name):
76
- return f"<{name}>"
77
-
78
- @v_args(inline=True)
79
- def event_hat(self, event_name):
80
- return f"when ({event_name})"
81
-
82
- def block_hat(self, items):
83
- name, *params = items
84
- params_str = ", ".join(params)
85
- return f"custom_block {name} ({params_str})"
86
-
87
- @v_args(inline=True)
88
- def PREPROC_INSTR(self, content):
89
- return f"{content}"
90
-
91
- @v_args(inline=True)
92
- def COMMMENT(self, content):
93
- return f"{content}"
94
-
95
- def block(self, items):
96
- params = []
97
- inner_blocks = []
98
- comments = []
99
- for i in items[1:]:
100
- if not isinstance(i, Tree):
101
- continue
102
- if str(i.data) == "block_content":
103
- inner_blocks.extend(i.children)
104
- if str(i.data) == "block_params":
105
- params.extend(i.children)
106
- if str(i.data) == "comments":
107
- comments.extend(i.children)
108
- block_name = items[0]
109
- block_text = f"{block_name}({', '.join(params)})" if params or not inner_blocks else f"{block_name}"
110
- if inner_blocks:
111
- blocks_content = "\n".join(inner_blocks)
112
- indented_content = self._indent(blocks_content)
113
- block_text += f" {{\n{indented_content}\n}}"
114
- if comments:
115
- block_text += f" {' '.join(comments)}"
116
- return block_text
117
-
118
- def LITERAL_NUMBER(self, number: str):
119
- return number
120
-
121
- def expr(self, items):
122
- text = items[0]
123
- if len(items) > 1:
124
- text += f" {' '.join(items[1].children)}"
125
- return text
126
-
127
- def low_expr1(self, items):
128
- text = f"({items[0]})" if " " in items[0] else items[0]
129
- if len(items) > 1:
130
- text += f" {' '.join(items[1].children)}"
131
- return text
132
-
133
- @v_args(inline=True)
134
- def low_expr2(self, item):
135
- return item
136
-
137
- def addition(self, items):
138
- return items[0] + " + " + items[1]
139
-
140
- def subtraction(self, items):
141
- return items[0] + " - " + items[1]
142
-
143
- def multiplication(self, items):
144
- return items[0] + " * " + items[1]
145
-
146
- def division(self, items):
147
- return items[0] + " / " + items[1]
148
-
149
- def top_level_block(self, items):
150
- first_item = items[0]
151
- if first_item.startswith("%%") or first_item.startswith("##"):
152
- return first_item
153
-
154
- hat, *blocks = items
155
- blocks_content = "\n".join(blocks)
156
- indented_content = self._indent(blocks_content)
157
- return f"{hat} {{\n{indented_content}\n}}"
158
-
159
- def start(self, items):
160
- return "\n\n".join(items)
161
-
162
- def pretty_unparse(tree: Tree):
163
- return PrettyUnparser().transform(tree)
164
-
165
- if __name__ == "__main__":
166
- EXAMPLE_FILE = Path(__file__).parent / "example.txt"
167
- tree = parse(EXAMPLE_FILE)
168
- print(tree.pretty())
169
- print()
170
- print()
171
- print(tree)
172
- print()
173
- print()
174
- print(unparse(tree))
175
- print()
176
- print()
177
- print(pretty_unparse(tree))
@@ -1,80 +0,0 @@
1
- from __future__ import annotations
2
-
3
- from . import base, block, sprite, build_defaulting
4
- from typing import Optional
5
-
6
-
7
- class Comment(base.IDComponent):
8
- """
9
- Represents a comment in the scratch editor.
10
- """
11
- def __init__(self, _id: Optional[str] = None, _block: Optional[block.Block] = None, x: int = 0, y: int = 0, width: int = 200,
12
- height: int = 200, minimized: bool = False, text: str = '', *, _block_id: Optional[str] = None,
13
- _sprite: sprite.Sprite = build_defaulting.SPRITE_DEFAULT, pos: Optional[tuple[int, int]] = None):
14
- self.block = _block
15
- self._block_id = _block_id
16
- """
17
- ID of connected block. Will be set to None upon sprite initialization when the block attribute is updated to the relevant Block.
18
- """
19
- if pos is not None:
20
- x, y = pos
21
-
22
- self.x = x
23
- self.y = y
24
-
25
- self.width = width
26
- self.height = height
27
-
28
- self.minimized = minimized
29
- self.text = text
30
-
31
- super().__init__(_id, _sprite)
32
-
33
- def __repr__(self):
34
- return f"Comment<{self.text[:10]!r}...>"
35
-
36
- @property
37
- def block_id(self):
38
- """
39
- Retrieve the id of the associateed block (if applicable)
40
- """
41
- if self.block is not None:
42
- return self.block.id
43
- elif self._block_id is not None:
44
- return self._block_id
45
- else:
46
- return None
47
-
48
- @staticmethod
49
- def from_json(data: tuple[str, dict]):
50
- assert len(data) == 2
51
- _id, data = data
52
-
53
- _block_id = data.get("blockId")
54
-
55
- x = data.get("x", 0)
56
- y = data.get("y", 0)
57
-
58
- width = data.get("width", 100)
59
- height = data.get("height", 100)
60
-
61
- minimized = data.get("minimized", False)
62
- text = data.get("text")
63
-
64
- ret = Comment(_id, None, x, y, width, height, minimized, text, _block_id=_block_id)
65
- return ret
66
-
67
- def to_json(self) -> dict:
68
- return {
69
- "blockId": self.block_id,
70
- "x": self.x, "y": self.y,
71
- "width": self.width, "height": self.height,
72
- "minimized": self.minimized,
73
- "text": self.text,
74
- }
75
-
76
- def link_using_sprite(self):
77
- if self._block_id is not None:
78
- self.block = self.sprite.find_block(self._block_id, "id")
79
- if self.block is not None:
80
- self._block_id = None