scratch-blocks 2.0.1 → 2.0.3

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 (276) hide show
  1. package/AGENTS.md +140 -0
  2. package/commitlint.config.js +2 -2
  3. package/dist/main.mjs +1 -2
  4. package/dist/types/msg/scratch_msgs.d.ts.map +1 -1
  5. package/dist/types/src/block_reporting.d.ts.map +1 -1
  6. package/dist/types/src/blocks/colour.d.ts +0 -19
  7. package/dist/types/src/blocks/colour.d.ts.map +1 -1
  8. package/dist/types/src/blocks/control.d.ts +0 -19
  9. package/dist/types/src/blocks/control.d.ts.map +1 -1
  10. package/dist/types/src/blocks/data.d.ts +0 -19
  11. package/dist/types/src/blocks/data.d.ts.map +1 -1
  12. package/dist/types/src/blocks/event.d.ts +0 -19
  13. package/dist/types/src/blocks/event.d.ts.map +1 -1
  14. package/dist/types/src/blocks/looks.d.ts +0 -19
  15. package/dist/types/src/blocks/looks.d.ts.map +1 -1
  16. package/dist/types/src/blocks/math.d.ts +0 -19
  17. package/dist/types/src/blocks/math.d.ts.map +1 -1
  18. package/dist/types/src/blocks/matrix.d.ts +0 -19
  19. package/dist/types/src/blocks/matrix.d.ts.map +1 -1
  20. package/dist/types/src/blocks/motion.d.ts +0 -19
  21. package/dist/types/src/blocks/motion.d.ts.map +1 -1
  22. package/dist/types/src/blocks/note.d.ts +0 -19
  23. package/dist/types/src/blocks/note.d.ts.map +1 -1
  24. package/dist/types/src/blocks/operators.d.ts +0 -19
  25. package/dist/types/src/blocks/operators.d.ts.map +1 -1
  26. package/dist/types/src/blocks/procedures.d.ts +6 -9
  27. package/dist/types/src/blocks/procedures.d.ts.map +1 -1
  28. package/dist/types/src/blocks/sensing.d.ts +0 -19
  29. package/dist/types/src/blocks/sensing.d.ts.map +1 -1
  30. package/dist/types/src/blocks/sound.d.ts +0 -19
  31. package/dist/types/src/blocks/sound.d.ts.map +1 -1
  32. package/dist/types/src/blocks/text.d.ts +0 -19
  33. package/dist/types/src/blocks/text.d.ts.map +1 -1
  34. package/dist/types/src/blocks/vertical_extensions.d.ts +0 -19
  35. package/dist/types/src/blocks/vertical_extensions.d.ts.map +1 -1
  36. package/dist/types/src/checkable_continuous_flyout.d.ts +2 -7
  37. package/dist/types/src/checkable_continuous_flyout.d.ts.map +1 -1
  38. package/dist/types/src/checkbox_bubble.d.ts +13 -12
  39. package/dist/types/src/checkbox_bubble.d.ts.map +1 -1
  40. package/dist/types/src/colours.d.ts.map +1 -1
  41. package/dist/types/src/constants.d.ts +0 -7
  42. package/dist/types/src/constants.d.ts.map +1 -1
  43. package/dist/types/src/context_menu_items.d.ts +0 -5
  44. package/dist/types/src/context_menu_items.d.ts.map +1 -1
  45. package/dist/types/src/data_category.d.ts +2 -4
  46. package/dist/types/src/data_category.d.ts.map +1 -1
  47. package/dist/types/src/events/events_block_comment_base.d.ts +2 -3
  48. package/dist/types/src/events/events_block_comment_base.d.ts.map +1 -1
  49. package/dist/types/src/events/events_block_comment_change.d.ts +0 -5
  50. package/dist/types/src/events/events_block_comment_change.d.ts.map +1 -1
  51. package/dist/types/src/events/events_block_comment_collapse.d.ts +0 -5
  52. package/dist/types/src/events/events_block_comment_collapse.d.ts.map +1 -1
  53. package/dist/types/src/events/events_block_comment_create.d.ts +0 -5
  54. package/dist/types/src/events/events_block_comment_create.d.ts.map +1 -1
  55. package/dist/types/src/events/events_block_comment_delete.d.ts +0 -5
  56. package/dist/types/src/events/events_block_comment_delete.d.ts.map +1 -1
  57. package/dist/types/src/events/events_block_comment_move.d.ts +0 -5
  58. package/dist/types/src/events/events_block_comment_move.d.ts.map +1 -1
  59. package/dist/types/src/events/events_block_comment_resize.d.ts +0 -5
  60. package/dist/types/src/events/events_block_comment_resize.d.ts.map +1 -1
  61. package/dist/types/src/events/events_block_drag_end.d.ts +1 -2
  62. package/dist/types/src/events/events_block_drag_end.d.ts.map +1 -1
  63. package/dist/types/src/events/events_block_drag_outside.d.ts +1 -2
  64. package/dist/types/src/events/events_block_drag_outside.d.ts.map +1 -1
  65. package/dist/types/src/events/events_scratch_variable_create.d.ts +0 -5
  66. package/dist/types/src/events/events_scratch_variable_create.d.ts.map +1 -1
  67. package/dist/types/src/fields/field_colour_slider.d.ts +7 -31
  68. package/dist/types/src/fields/field_colour_slider.d.ts.map +1 -1
  69. package/dist/types/src/fields/field_matrix.d.ts +0 -19
  70. package/dist/types/src/fields/field_matrix.d.ts.map +1 -1
  71. package/dist/types/src/fields/field_note.d.ts +8 -23
  72. package/dist/types/src/fields/field_note.d.ts.map +1 -1
  73. package/dist/types/src/fields/field_textinput_removable.d.ts +2 -4
  74. package/dist/types/src/fields/field_textinput_removable.d.ts.map +1 -1
  75. package/dist/types/src/fields/field_variable_getter.d.ts +0 -19
  76. package/dist/types/src/fields/field_variable_getter.d.ts.map +1 -1
  77. package/dist/types/src/fields/field_vertical_separator.d.ts +0 -19
  78. package/dist/types/src/fields/field_vertical_separator.d.ts.map +1 -1
  79. package/dist/types/src/fields/scratch_field_angle.d.ts +0 -19
  80. package/dist/types/src/fields/scratch_field_angle.d.ts.map +1 -1
  81. package/dist/types/src/fields/scratch_field_dropdown.d.ts +0 -5
  82. package/dist/types/src/fields/scratch_field_dropdown.d.ts.map +1 -1
  83. package/dist/types/src/fields/scratch_field_number.d.ts +0 -19
  84. package/dist/types/src/fields/scratch_field_number.d.ts.map +1 -1
  85. package/dist/types/src/fields/scratch_field_variable.d.ts +5 -8
  86. package/dist/types/src/fields/scratch_field_variable.d.ts.map +1 -1
  87. package/dist/types/src/flyout_checkbox_icon.d.ts +2 -3
  88. package/dist/types/src/flyout_checkbox_icon.d.ts.map +1 -1
  89. package/dist/types/src/glows.d.ts +1 -3
  90. package/dist/types/src/glows.d.ts.map +1 -1
  91. package/dist/types/src/index.d.ts +50 -51
  92. package/dist/types/src/index.d.ts.map +1 -1
  93. package/dist/types/src/procedures.d.ts +6 -8
  94. package/dist/types/src/procedures.d.ts.map +1 -1
  95. package/dist/types/src/recyclable_block_flyout_inflater.d.ts +3 -5
  96. package/dist/types/src/recyclable_block_flyout_inflater.d.ts.map +1 -1
  97. package/dist/types/src/renderer/bowler_hat.d.ts +2 -3
  98. package/dist/types/src/renderer/bowler_hat.d.ts.map +1 -1
  99. package/dist/types/src/renderer/cat/cat_face.d.ts +6 -5
  100. package/dist/types/src/renderer/cat/cat_face.d.ts.map +1 -1
  101. package/dist/types/src/renderer/cat/constants.d.ts +2 -2
  102. package/dist/types/src/renderer/cat/constants.d.ts.map +1 -1
  103. package/dist/types/src/renderer/cat/drawer.d.ts +4 -5
  104. package/dist/types/src/renderer/cat/drawer.d.ts.map +1 -1
  105. package/dist/types/src/renderer/cat/path_object.d.ts +2 -3
  106. package/dist/types/src/renderer/cat/path_object.d.ts.map +1 -1
  107. package/dist/types/src/renderer/cat/render_info.d.ts +3 -4
  108. package/dist/types/src/renderer/cat/render_info.d.ts.map +1 -1
  109. package/dist/types/src/renderer/cat/renderer.d.ts +7 -8
  110. package/dist/types/src/renderer/cat/renderer.d.ts.map +1 -1
  111. package/dist/types/src/renderer/constants.d.ts +41 -0
  112. package/dist/types/src/renderer/constants.d.ts.map +1 -0
  113. package/dist/types/src/renderer/drawer.d.ts +7 -6
  114. package/dist/types/src/renderer/drawer.d.ts.map +1 -1
  115. package/dist/types/src/renderer/path_object.d.ts +1 -3
  116. package/dist/types/src/renderer/path_object.d.ts.map +1 -1
  117. package/dist/types/src/renderer/render_info.d.ts +3 -4
  118. package/dist/types/src/renderer/render_info.d.ts.map +1 -1
  119. package/dist/types/src/renderer/renderer.d.ts +9 -16
  120. package/dist/types/src/renderer/renderer.d.ts.map +1 -1
  121. package/dist/types/src/scratch_block_paster.d.ts +0 -5
  122. package/dist/types/src/scratch_block_paster.d.ts.map +1 -1
  123. package/dist/types/src/scratch_blocks_utils.d.ts +0 -20
  124. package/dist/types/src/scratch_blocks_utils.d.ts.map +1 -1
  125. package/dist/types/src/scratch_comment_bubble.d.ts +3 -6
  126. package/dist/types/src/scratch_comment_bubble.d.ts.map +1 -1
  127. package/dist/types/src/scratch_comment_icon.d.ts +3 -4
  128. package/dist/types/src/scratch_comment_icon.d.ts.map +1 -1
  129. package/dist/types/src/scratch_connection_checker.d.ts +0 -5
  130. package/dist/types/src/scratch_connection_checker.d.ts.map +1 -1
  131. package/dist/types/src/scratch_continuous_category.d.ts +5 -5
  132. package/dist/types/src/scratch_continuous_category.d.ts.map +1 -1
  133. package/dist/types/src/scratch_continuous_toolbox.d.ts +3 -6
  134. package/dist/types/src/scratch_continuous_toolbox.d.ts.map +1 -1
  135. package/dist/types/src/scratch_dragger.d.ts +2 -11
  136. package/dist/types/src/scratch_dragger.d.ts.map +1 -1
  137. package/dist/types/src/scratch_insertion_marker_previewer.d.ts +0 -5
  138. package/dist/types/src/scratch_insertion_marker_previewer.d.ts.map +1 -1
  139. package/dist/types/src/scratch_variable_map.d.ts +0 -5
  140. package/dist/types/src/scratch_variable_map.d.ts.map +1 -1
  141. package/dist/types/src/scratch_variable_model.d.ts +2 -3
  142. package/dist/types/src/scratch_variable_model.d.ts.map +1 -1
  143. package/dist/types/src/scratch_zoom_controls.d.ts +4 -6
  144. package/dist/types/src/scratch_zoom_controls.d.ts.map +1 -1
  145. package/dist/types/src/shadows.d.ts +2 -2
  146. package/dist/types/src/shadows.d.ts.map +1 -1
  147. package/dist/types/src/status_indicator_label.d.ts +4 -6
  148. package/dist/types/src/status_indicator_label.d.ts.map +1 -1
  149. package/dist/types/src/status_indicator_label_flyout_inflater.d.ts +1 -6
  150. package/dist/types/src/status_indicator_label_flyout_inflater.d.ts.map +1 -1
  151. package/dist/types/src/variables.d.ts +4 -8
  152. package/dist/types/src/variables.d.ts.map +1 -1
  153. package/dist/types/src/xml.d.ts +2 -3
  154. package/dist/types/src/xml.d.ts.map +1 -1
  155. package/dist/types/tests/jsunit/block_test.d.ts.map +1 -1
  156. package/dist/types/tests/jsunit/connection_db_test.d.ts +3 -3
  157. package/dist/types/tests/jsunit/connection_db_test.d.ts.map +1 -1
  158. package/dist/types/tests/jsunit/connection_test.d.ts.map +1 -1
  159. package/dist/types/tests/jsunit/event_test.d.ts.map +1 -1
  160. package/dist/types/tests/jsunit/extensions_test.d.ts.map +1 -1
  161. package/dist/types/tests/jsunit/field_number_test.d.ts.map +1 -1
  162. package/dist/types/tests/jsunit/field_test.d.ts.map +1 -1
  163. package/dist/types/tests/jsunit/field_variable_getter_test.d.ts.map +1 -1
  164. package/dist/types/tests/jsunit/field_variable_test.d.ts.map +1 -1
  165. package/dist/types/tests/jsunit/gesture_test.d.ts.map +1 -1
  166. package/dist/types/tests/jsunit/input_test.d.ts +1 -0
  167. package/dist/types/tests/jsunit/input_test.d.ts.map +1 -1
  168. package/dist/types/tests/jsunit/json_test.d.ts.map +1 -1
  169. package/dist/types/tests/jsunit/names_test.d.ts.map +1 -1
  170. package/dist/types/tests/jsunit/procedure_test.d.ts.map +1 -1
  171. package/dist/types/tests/jsunit/scratch_block_comment_test.d.ts.map +1 -1
  172. package/dist/types/tests/jsunit/svg_test.d.ts.map +1 -1
  173. package/dist/types/tests/jsunit/test_utilities.d.ts.map +1 -1
  174. package/dist/types/tests/jsunit/utils_test.d.ts.map +1 -1
  175. package/dist/types/tests/jsunit/variable_map_test.d.ts.map +1 -1
  176. package/dist/types/tests/jsunit/variable_model_test.d.ts.map +1 -1
  177. package/dist/types/tests/jsunit/widget_div_test.d.ts.map +1 -1
  178. package/dist/types/tests/jsunit/workspace_comment_test.d.ts.map +1 -1
  179. package/dist/types/tests/jsunit/workspace_test.d.ts.map +1 -1
  180. package/dist/types/tests/jsunit/workspace_undo_redo_test.d.ts.map +1 -1
  181. package/dist/types/tests/jsunit/xml_test.d.ts.map +1 -1
  182. package/dist/types/tests/workspace_svg/workspace_svg_test.d.ts.map +1 -1
  183. package/eslint.config.mjs +69 -0
  184. package/i18n/create_scratch_msgs.js +44 -45
  185. package/i18n/js_to_json.js +40 -32
  186. package/i18n/json_to_js.js +37 -37
  187. package/i18n/sync_tx_translations.js +64 -65
  188. package/i18n/test_scratch_msgs.js +66 -63
  189. package/msg/js/en.js +289 -287
  190. package/msg/json/en.json +284 -284
  191. package/msg/messages.js +289 -287
  192. package/msg/scratch_msgs.js +22959 -22970
  193. package/package.json +13 -10
  194. package/prettier.config.mjs +3 -0
  195. package/release.config.js +7 -7
  196. package/renovate.json5 +7 -9
  197. package/src/block_reporting.ts +16 -19
  198. package/src/blocks/colour.ts +12 -15
  199. package/src/blocks/control.ts +171 -174
  200. package/src/blocks/data.ts +233 -272
  201. package/src/blocks/event.ts +121 -123
  202. package/src/blocks/looks.ts +165 -167
  203. package/src/blocks/math.ts +44 -46
  204. package/src/blocks/matrix.ts +11 -13
  205. package/src/blocks/motion.ts +151 -153
  206. package/src/blocks/note.ts +11 -13
  207. package/src/blocks/operators.ts +158 -160
  208. package/src/blocks/procedures.ts +421 -511
  209. package/src/blocks/sensing.ts +163 -165
  210. package/src/blocks/sound.ts +58 -60
  211. package/src/blocks/text.ts +10 -12
  212. package/src/blocks/vertical_extensions.ts +86 -102
  213. package/src/checkable_continuous_flyout.ts +25 -42
  214. package/src/checkbox_bubble.ts +83 -100
  215. package/src/colours.ts +35 -37
  216. package/src/constants.ts +22 -29
  217. package/src/context_menu_items.ts +59 -84
  218. package/src/css.ts +3 -4
  219. package/src/data_category.ts +137 -251
  220. package/src/events/events_block_comment_base.ts +23 -30
  221. package/src/events/events_block_comment_change.ts +21 -42
  222. package/src/events/events_block_comment_collapse.ts +27 -36
  223. package/src/events/events_block_comment_create.ts +32 -46
  224. package/src/events/events_block_comment_delete.ts +12 -19
  225. package/src/events/events_block_comment_move.ts +27 -52
  226. package/src/events/events_block_comment_resize.ts +28 -55
  227. package/src/events/events_block_drag_end.ts +16 -26
  228. package/src/events/events_block_drag_outside.ts +12 -22
  229. package/src/events/events_scratch_variable_create.ts +37 -42
  230. package/src/fields/field_colour_slider.ts +186 -216
  231. package/src/fields/field_matrix.ts +202 -270
  232. package/src/fields/field_note.ts +277 -375
  233. package/src/fields/field_textinput_removable.ts +25 -40
  234. package/src/fields/field_variable_getter.ts +26 -31
  235. package/src/fields/field_vertical_separator.ts +19 -24
  236. package/src/fields/scratch_field_angle.ts +151 -187
  237. package/src/fields/scratch_field_dropdown.ts +15 -19
  238. package/src/fields/scratch_field_number.ts +125 -181
  239. package/src/fields/scratch_field_variable.ts +57 -75
  240. package/src/flyout_checkbox_icon.ts +18 -28
  241. package/src/glows.ts +52 -59
  242. package/src/index.ts +119 -133
  243. package/src/procedures.ts +150 -209
  244. package/src/recyclable_block_flyout_inflater.ts +14 -25
  245. package/src/renderer/bowler_hat.ts +6 -8
  246. package/src/renderer/cat/cat_face.ts +98 -99
  247. package/src/renderer/cat/constants.ts +67 -87
  248. package/src/renderer/cat/drawer.ts +21 -27
  249. package/src/renderer/cat/path_object.ts +3 -5
  250. package/src/renderer/cat/render_info.ts +5 -8
  251. package/src/renderer/cat/renderer.ts +12 -16
  252. package/src/renderer/constants.ts +34 -49
  253. package/src/renderer/drawer.ts +35 -51
  254. package/src/renderer/path_object.ts +4 -10
  255. package/src/renderer/render_info.ts +39 -56
  256. package/src/renderer/renderer.ts +17 -30
  257. package/src/scratch_block_paster.ts +12 -20
  258. package/src/scratch_blocks_utils.ts +4 -7
  259. package/src/scratch_comment_bubble.ts +76 -105
  260. package/src/scratch_comment_icon.ts +75 -124
  261. package/src/scratch_connection_checker.ts +7 -17
  262. package/src/scratch_continuous_category.ts +24 -28
  263. package/src/scratch_continuous_toolbox.ts +20 -27
  264. package/src/scratch_dragger.ts +42 -81
  265. package/src/scratch_insertion_marker_previewer.ts +6 -11
  266. package/src/scratch_variable_map.ts +5 -12
  267. package/src/scratch_variable_model.ts +6 -13
  268. package/src/scratch_zoom_controls.ts +101 -156
  269. package/src/shadows.ts +32 -37
  270. package/src/status_indicator_label.ts +54 -67
  271. package/src/status_indicator_label_flyout_inflater.ts +11 -21
  272. package/src/variables.ts +92 -141
  273. package/src/xml.ts +21 -35
  274. package/tsconfig.json +3 -7
  275. package/types/continuous-toolbox.d.ts +1 -1
  276. package/dist/main.mjs.LICENSE.txt +0 -163
package/src/procedures.ts CHANGED
@@ -1,5 +1,4 @@
1
1
  /**
2
- * @license
3
2
  * Visual Blocks Editor
4
3
  *
5
4
  * Copyright 2012 Google Inc.
@@ -17,66 +16,64 @@
17
16
  * See the License for the specific language governing permissions and
18
17
  * limitations under the License.
19
18
  */
20
-
21
19
  /**
22
- * @fileoverview Utility functions for handling procedures.
20
+ * @file Utility functions for handling procedures.
23
21
  * @author fraser@google.com (Neil Fraser)
24
22
  */
25
-
26
- import * as Blockly from "blockly/core";
27
- import * as Constants from "./constants";
28
- import * as scratchBlocksUtils from "../src/scratch_blocks_utils";
23
+ import * as Blockly from 'blockly/core'
24
+ import * as scratchBlocksUtils from '../src/scratch_blocks_utils'
25
+ import * as Constants from './constants'
29
26
 
30
27
  /**
31
28
  * Find all user-created procedure definition mutations in a workspace.
32
29
  * @param root Root workspace.
33
- * @return Array of mutation xml elements.
30
+ * @returns Array of mutation xml elements.
34
31
  */
35
32
  function allProcedureMutations(root: Blockly.WorkspaceSvg): Element[] {
36
- const blocks = root.getAllBlocks();
33
+ const blocks = root.getAllBlocks()
37
34
  return blocks
38
- .filter((b) => b.type === Constants.PROCEDURES_PROTOTYPE_BLOCK_TYPE)
39
- .map((b) => b.mutationToDom(/* opt_generateShadows */ true));
35
+ .filter(b => b.type === Constants.PROCEDURES_PROTOTYPE_BLOCK_TYPE)
36
+ .map(b => b.mutationToDom!(/* opt_generateShadows */ true))
40
37
  }
41
38
 
42
39
  /**
43
40
  * Sorts an array of procedure definition mutations alphabetically.
44
41
  * (Does not mutate the given array.)
45
42
  * @param mutations Array of mutation xml elements.
46
- * @return Sorted array of mutation xml elements.
43
+ * @returns Sorted array of mutation xml elements.
47
44
  */
48
45
  function sortProcedureMutations(mutations: Element[]): Element[] {
49
- return mutations.slice().sort(function (a, b) {
50
- const procCodeA = a.getAttribute("proccode");
51
- const procCodeB = b.getAttribute("proccode");
46
+ return mutations.slice().sort((a, b) => {
47
+ const procCodeA = a.getAttribute('proccode')!
48
+ const procCodeB = b.getAttribute('proccode')!
52
49
 
53
- return scratchBlocksUtils.compareStrings(procCodeA, procCodeB);
54
- });
50
+ return scratchBlocksUtils.compareStrings(procCodeA, procCodeB)
51
+ })
55
52
  }
56
53
 
57
54
  /**
58
55
  * Construct the blocks required by the flyout for the procedure category.
59
56
  * @param workspace The workspace containing procedures.
60
- * @return Array of XML block elements.
57
+ * @returns Array of XML block elements.
61
58
  */
62
59
  function getProceduresCategory(workspace: Blockly.WorkspaceSvg): Element[] {
63
- var xmlList: Element[] = [];
60
+ const xmlList: Element[] = []
64
61
 
65
- addCreateButton(workspace, xmlList);
62
+ addCreateButton(workspace, xmlList)
66
63
 
67
64
  // Create call blocks for each procedure defined in the workspace
68
- const mutations = sortProcedureMutations(allProcedureMutations(workspace));
65
+ const mutations = sortProcedureMutations(allProcedureMutations(workspace))
69
66
  for (const mutation of mutations) {
70
67
  // <block type="procedures_call">
71
68
  // <mutation ...></mutation>
72
69
  // </block>
73
- const block = document.createElement("block");
74
- block.setAttribute("type", "procedures_call");
75
- block.setAttribute("gap", "16");
76
- block.appendChild(mutation);
77
- xmlList.push(block);
70
+ const block = document.createElement('block')
71
+ block.setAttribute('type', 'procedures_call')
72
+ block.setAttribute('gap', '16')
73
+ block.appendChild(mutation)
74
+ xmlList.push(block)
78
75
  }
79
- return xmlList;
76
+ return xmlList
80
77
  }
81
78
 
82
79
  /**
@@ -85,23 +82,23 @@ function getProceduresCategory(workspace: Blockly.WorkspaceSvg): Element[] {
85
82
  * @param xmlList Array of XML block elements to add to.
86
83
  */
87
84
  function addCreateButton(workspace: Blockly.WorkspaceSvg, xmlList: Element[]) {
88
- const button = document.createElement("button");
89
- const msg = Blockly.Msg.NEW_PROCEDURE;
90
- const callbackKey = "CREATE_PROCEDURE";
85
+ const button = document.createElement('button')
86
+ const msg = Blockly.Msg.NEW_PROCEDURE
87
+ const callbackKey = 'CREATE_PROCEDURE'
91
88
  const callback = function () {
92
89
  // Run the callback after a delay to avoid it getting captured by the React
93
90
  // modal in scratch-gui and being registered as a click on the scrim that
94
91
  // dismisses the dialog.
95
92
  requestAnimationFrame(() => {
96
93
  setTimeout(() => {
97
- createProcedureDefCallback(workspace);
98
- });
99
- });
100
- };
101
- button.setAttribute("text", msg);
102
- button.setAttribute("callbackKey", callbackKey);
103
- workspace.registerButtonCallback(callbackKey, callback);
104
- xmlList.push(button);
94
+ createProcedureDefCallback(workspace)
95
+ })
96
+ })
97
+ }
98
+ button.setAttribute('text', msg)
99
+ button.setAttribute('callbackKey', callbackKey)
100
+ workspace.registerButtonCallback(callbackKey, callback)
101
+ xmlList.push(button)
105
102
  }
106
103
 
107
104
  /**
@@ -113,27 +110,28 @@ function addCreateButton(workspace: Blockly.WorkspaceSvg, xmlList: Element[]) {
113
110
  * @param allowRecursive True if the search should include recursive
114
111
  * procedure calls. False if the search should ignore the stack starting
115
112
  * with definitionRoot.
116
- * @return Array of caller blocks.
113
+ * @returns Array of caller blocks.
117
114
  */
118
115
  export function getCallers(
119
116
  name: string,
120
117
  workspace: Blockly.WorkspaceSvg,
121
118
  definitionRoot: Blockly.BlockSvg,
122
- allowRecursive: boolean
119
+ allowRecursive: boolean,
123
120
  ): Blockly.BlockSvg[] {
124
- return workspace.getTopBlocks().flatMap((block) => {
121
+ return workspace.getTopBlocks().flatMap(block => {
125
122
  if (block.id === definitionRoot.id && !allowRecursive) {
126
- return [];
123
+ return []
127
124
  }
128
125
 
129
- return block.getDescendants(false).filter((descendant) => {
130
- return (
131
- isProcedureBlock(descendant) &&
132
- descendant.type === Constants.PROCEDURES_CALL_BLOCK_TYPE &&
133
- descendant.getProcCode() === name
134
- );
135
- });
136
- });
126
+ return block
127
+ .getDescendants(false)
128
+ .filter(
129
+ descendant =>
130
+ isProcedureBlock(descendant) &&
131
+ descendant.type === Constants.PROCEDURES_CALL_BLOCK_TYPE &&
132
+ descendant.getProcCode() === name,
133
+ )
134
+ })
137
135
  }
138
136
 
139
137
  /**
@@ -142,108 +140,80 @@ export function getCallers(
142
140
  * @param workspace The workspace to find callers in.
143
141
  * @param mutation New mutation for the callers.
144
142
  */
145
- function mutateCallersAndPrototype(
146
- name: string,
147
- workspace: Blockly.WorkspaceSvg,
148
- mutation: Element
149
- ) {
150
- const defineBlock = getDefineBlock(name, workspace);
151
- const prototypeBlock = getPrototypeBlock(name, workspace);
143
+ function mutateCallersAndPrototype(name: string, workspace: Blockly.WorkspaceSvg, mutation: Element) {
144
+ const defineBlock = getDefineBlock(name, workspace)
145
+ const prototypeBlock = getPrototypeBlock(name, workspace)
152
146
  if (!(defineBlock && prototypeBlock)) {
153
- alert("No define block on workspace"); // TODO decide what to do about this.
154
- return;
147
+ alert('No define block on workspace') // TODO decide what to do about this.
148
+ return
155
149
  }
156
150
 
157
- const callers = getCallers(
158
- name,
159
- defineBlock.workspace,
160
- defineBlock,
161
- true /* allowRecursive */
162
- );
163
- callers.push(prototypeBlock);
164
- Blockly.Events.setGroup(true);
165
- callers.forEach((caller) => {
166
- const oldMutationDom = caller.mutationToDom();
167
- const oldMutation = oldMutationDom && Blockly.Xml.domToText(oldMutationDom);
168
- caller.domToMutation(mutation);
169
- const newMutationDom = caller.mutationToDom();
170
- const newMutation = newMutationDom && Blockly.Xml.domToText(newMutationDom);
151
+ const callers = getCallers(name, defineBlock.workspace, defineBlock, true /* allowRecursive */)
152
+ callers.push(prototypeBlock)
153
+ Blockly.Events.setGroup(true)
154
+ callers.forEach(caller => {
155
+ const oldMutationDom = caller.mutationToDom!()
156
+ const oldMutation = oldMutationDom && Blockly.Xml.domToText(oldMutationDom)
157
+ caller.domToMutation!(mutation)
158
+ const newMutationDom = caller.mutationToDom!()
159
+ const newMutation = newMutationDom && Blockly.Xml.domToText(newMutationDom)
171
160
  if (oldMutation !== newMutation) {
172
161
  Blockly.Events.fire(
173
- new (Blockly.Events.get(Blockly.Events.BLOCK_CHANGE))(
174
- caller,
175
- "mutation",
176
- null,
177
- oldMutation,
178
- newMutation
179
- )
180
- );
162
+ new (Blockly.Events.get(Blockly.Events.BLOCK_CHANGE))(caller, 'mutation', null, oldMutation, newMutation),
163
+ )
181
164
  }
182
- });
183
- Blockly.Events.setGroup(false);
165
+ })
166
+ Blockly.Events.setGroup(false)
184
167
  }
185
168
 
186
169
  /**
187
170
  * Find the definition block for the named procedure.
188
171
  * @param procCode The identifier of the procedure.
189
172
  * @param workspace The workspace to search.
190
- * @return The procedure definition block, or undefined if not found.
173
+ * @returns The procedure definition block, or undefined if not found.
191
174
  */
192
- function getDefineBlock(
193
- procCode: string,
194
- workspace: Blockly.WorkspaceSvg
195
- ): Blockly.BlockSvg | undefined {
175
+ function getDefineBlock(procCode: string, workspace: Blockly.WorkspaceSvg): Blockly.BlockSvg | undefined {
196
176
  // Assume that a procedure definition is a top block.
197
- return workspace.getTopBlocks(false).find((block) => {
177
+ return workspace.getTopBlocks(false).find(block => {
198
178
  if (block.type === Constants.PROCEDURES_DEFINITION_BLOCK_TYPE) {
199
- const prototypeBlock = block
200
- .getInput("custom_block")
201
- .connection.targetBlock() as Blockly.BlockSvg;
202
- return (
203
- isProcedureBlock(prototypeBlock) &&
204
- prototypeBlock.getProcCode() === procCode
205
- );
179
+ const prototypeBlock = block.getInput('custom_block')!.connection!.targetBlock() as Blockly.BlockSvg
180
+ return isProcedureBlock(prototypeBlock) && prototypeBlock.getProcCode() === procCode
206
181
  }
207
182
 
208
- return false;
209
- });
183
+ return false
184
+ })
210
185
  }
211
186
 
212
187
  /**
213
188
  * Find the prototype block for the named procedure.
214
189
  * @param procCode The identifier of the procedure.
215
190
  * @param workspace The workspace to search.
216
- * @return The procedure prototype block, or undefined if not found.
191
+ * @returns The procedure prototype block, or undefined if not found.
217
192
  */
218
- function getPrototypeBlock(
219
- procCode: string,
220
- workspace: Blockly.WorkspaceSvg
221
- ): Blockly.BlockSvg | undefined {
222
- const defineBlock = getDefineBlock(procCode, workspace);
193
+ function getPrototypeBlock(procCode: string, workspace: Blockly.WorkspaceSvg): Blockly.BlockSvg | undefined {
194
+ const defineBlock = getDefineBlock(procCode, workspace)
223
195
  if (defineBlock) {
224
- return defineBlock
225
- .getInput("custom_block")
226
- .connection.targetBlock() as Blockly.BlockSvg;
196
+ return defineBlock.getInput('custom_block')!.connection!.targetBlock() as Blockly.BlockSvg
227
197
  }
228
- return undefined;
198
+ return undefined
229
199
  }
230
200
 
231
201
  /**
232
202
  * Create a mutation for a brand new custom procedure.
233
- * @return The mutation for a new custom procedure
203
+ * @returns The mutation for a new custom procedure
234
204
  */
235
205
  function newProcedureMutation(): Element {
236
206
  const mutationText = `
237
207
  <xml>
238
208
  <mutation
239
- proccode="${Blockly.Msg["PROCEDURE_DEFAULT_NAME"]}"
209
+ proccode="${Blockly.Msg.PROCEDURE_DEFAULT_NAME}"
240
210
  argumentids="[]"
241
211
  argumentnames="[]"
242
212
  argumentdefaults="[]"
243
213
  warp="false">
244
214
  </mutation>
245
- </xml>`;
246
- return Blockly.utils.xml.textToDom(mutationText).firstElementChild;
215
+ </xml>`
216
+ return Blockly.utils.xml.textToDom(mutationText).firstElementChild!
247
217
  }
248
218
 
249
219
  /**
@@ -251,22 +221,17 @@ function newProcedureMutation(): Element {
251
221
  * @param workspace The workspace to create the new procedure on.
252
222
  */
253
223
  function createProcedureDefCallback(workspace: Blockly.WorkspaceSvg) {
254
- ScratchProcedures.externalProcedureDefCallback(
255
- newProcedureMutation(),
256
- createProcedureCallbackFactory(workspace)
257
- );
224
+ ScratchProcedures.externalProcedureDefCallback!(newProcedureMutation(), createProcedureCallbackFactory(workspace))
258
225
  }
259
226
 
260
227
  /**
261
228
  * Callback factory for adding a new custom procedure from a mutation.
262
229
  * @param workspace The workspace to create the new procedure on.
263
- * @return callback for creating the new custom procedure.
230
+ * @returns callback for creating the new custom procedure.
264
231
  */
265
- function createProcedureCallbackFactory(
266
- workspace: Blockly.WorkspaceSvg
267
- ): (mutation?: Element) => void {
232
+ function createProcedureCallbackFactory(workspace: Blockly.WorkspaceSvg): (mutation?: Element) => void {
268
233
  return (mutation?: Element) => {
269
- if (!mutation) return;
234
+ if (!mutation) return
270
235
 
271
236
  const blockText = `
272
237
  <xml>
@@ -277,30 +242,27 @@ function createProcedureCallbackFactory(
277
242
  </shadow>
278
243
  </statement>
279
244
  </block>
280
- </xml>`;
281
- const blockDom = Blockly.utils.xml.textToDom(blockText).firstElementChild;
282
- Blockly.Events.setGroup(true);
283
- const block = Blockly.Xml.domToBlock(
284
- blockDom,
285
- workspace
286
- ) as Blockly.BlockSvg;
245
+ </xml>`
246
+ const blockDom = Blockly.utils.xml.textToDom(blockText).firstElementChild!
247
+ Blockly.Events.setGroup(true)
248
+ const block = Blockly.Xml.domToBlock(blockDom, workspace) as Blockly.BlockSvg
287
249
  Blockly.renderManagement.finishQueuedRenders().then(() => {
288
250
  // To convert from pixel units to workspace units
289
- const scale = workspace.scale;
251
+ const scale = workspace.scale
290
252
  // Position the block so that it is at the top left of the visible
291
253
  // workspace, padded from the edge by 30 units. Position in the top right
292
254
  // if RTL.
293
- let posX = -workspace.scrollX;
255
+ let posX = -workspace.scrollX
294
256
  if (workspace.RTL) {
295
- posX += workspace.getMetrics().contentWidth - 30;
257
+ posX += workspace.getMetrics().contentWidth - 30
296
258
  } else {
297
- posX += 30;
259
+ posX += 30
298
260
  }
299
- block.moveBy(posX / scale, (-workspace.scrollY + 30) / scale);
300
- block.scheduleSnapAndBump();
301
- Blockly.Events.setGroup(false);
302
- });
303
- };
261
+ block.moveBy(posX / scale, (-workspace.scrollY + 30) / scale)
262
+ block.scheduleSnapAndBump()
263
+ Blockly.Events.setGroup(false)
264
+ })
265
+ }
304
266
  }
305
267
 
306
268
  /**
@@ -310,60 +272,55 @@ function createProcedureCallbackFactory(
310
272
  function editProcedureCallback(block: Blockly.BlockSvg) {
311
273
  // Edit can come from one of three block types (call, define, prototype)
312
274
  // Normalize by setting the block to the prototype block for the procedure.
313
- let prototypeBlock: Blockly.BlockSvg;
275
+ let prototypeBlock: Blockly.BlockSvg
314
276
  if (block.type === Constants.PROCEDURES_DEFINITION_BLOCK_TYPE) {
315
- const input = block.getInput("custom_block");
277
+ const input = block.getInput('custom_block')
316
278
  if (!input) {
317
- alert("Bad input"); // TODO: Decide what to do about this.
318
- return;
279
+ alert('Bad input') // TODO: Decide what to do about this.
280
+ return
319
281
  }
320
- const conn = input.connection;
282
+ const conn = input.connection
321
283
  if (!conn) {
322
- alert("Bad connection"); // TODO: Decide what to do about this.
323
- return;
284
+ alert('Bad connection') // TODO: Decide what to do about this.
285
+ return
324
286
  }
325
- const innerBlock = conn.targetBlock();
326
- if (
327
- !innerBlock ||
328
- innerBlock.type !== Constants.PROCEDURES_PROTOTYPE_BLOCK_TYPE
329
- ) {
330
- alert("Bad inner block"); // TODO: Decide what to do about this.
331
- return;
287
+ const innerBlock = conn.targetBlock()
288
+ if (!innerBlock || innerBlock.type !== Constants.PROCEDURES_PROTOTYPE_BLOCK_TYPE) {
289
+ alert('Bad inner block') // TODO: Decide what to do about this.
290
+ return
332
291
  }
333
- prototypeBlock = innerBlock as Blockly.BlockSvg;
334
- } else if (
335
- block.type === Constants.PROCEDURES_CALL_BLOCK_TYPE &&
336
- isProcedureBlock(block)
337
- ) {
292
+ prototypeBlock = innerBlock as Blockly.BlockSvg
293
+ } else if (block.type === Constants.PROCEDURES_CALL_BLOCK_TYPE && isProcedureBlock(block)) {
338
294
  // This is a call block, find the prototype corresponding to the procCode.
339
295
  // Make sure to search the correct workspace, call block can be in flyout.
340
- const workspaceToSearch = block.workspace.isFlyout
341
- ? block.workspace.targetWorkspace
342
- : block.workspace;
343
- prototypeBlock = getPrototypeBlock(block.getProcCode(), workspaceToSearch);
296
+ const workspaceToSearch = block.workspace.isFlyout ? block.workspace.targetWorkspace! : block.workspace
297
+ const foundBlock = getPrototypeBlock(block.getProcCode(), workspaceToSearch)
298
+ if (!foundBlock) {
299
+ console.warn('editProcedureCallback: could not find prototype for', block.getProcCode())
300
+ return
301
+ }
302
+ prototypeBlock = foundBlock
344
303
  } else {
345
- prototypeBlock = block;
304
+ prototypeBlock = block
346
305
  }
347
306
  // Block now refers to the procedure prototype block, it is safe to proceed.
348
- ScratchProcedures.externalProcedureDefCallback(
349
- prototypeBlock.mutationToDom(),
350
- editProcedureCallbackFactory(prototypeBlock)
351
- );
307
+ ScratchProcedures.externalProcedureDefCallback!(
308
+ prototypeBlock.mutationToDom!(),
309
+ editProcedureCallbackFactory(prototypeBlock),
310
+ )
352
311
  }
353
312
 
354
313
  /**
355
314
  * Callback factory for editing an existing custom procedure.
356
315
  * @param block The procedure prototype block being edited.
357
- * @return Callback for editing the custom procedure.
316
+ * @returns Callback for editing the custom procedure.
358
317
  */
359
- function editProcedureCallbackFactory(
360
- block: Blockly.BlockSvg
361
- ): (mutation?: Element) => void {
318
+ function editProcedureCallbackFactory(block: Blockly.BlockSvg): (mutation?: Element) => void {
362
319
  return (mutation?: Element) => {
363
320
  if (mutation && isProcedureBlock(block)) {
364
- mutateCallersAndPrototype(block.getProcCode(), block.workspace, mutation);
321
+ mutateCallersAndPrototype(block.getProcCode(), block.workspace, mutation)
365
322
  }
366
- };
323
+ }
367
324
  }
368
325
 
369
326
  /**
@@ -371,20 +328,18 @@ function editProcedureCallbackFactory(
371
328
  * This appears in the context menu for procedure definitions and procedure
372
329
  * calls.
373
330
  * @param block The block where the right-click originated.
374
- * @return A menu option, containing text, enabled, and a callback.
331
+ * @returns A menu option, containing text, enabled, and a callback.
375
332
  */
376
- function makeEditOption(
377
- block: Blockly.BlockSvg
378
- ): Blockly.ContextMenuRegistry.ContextMenuOption {
333
+ function makeEditOption(block: Blockly.BlockSvg): Blockly.ContextMenuRegistry.ContextMenuOption {
379
334
  return {
380
335
  enabled: true,
381
336
  text: Blockly.Msg.EDIT_PROCEDURE,
382
337
  callback: () => {
383
- editProcedureCallback(block);
338
+ editProcedureCallback(block)
384
339
  },
385
340
  scope: block,
386
341
  weight: 7,
387
- };
342
+ }
388
343
  }
389
344
 
390
345
  /**
@@ -392,42 +347,31 @@ function makeEditOption(
392
347
  * @param procCode The identifier of the procedure to delete.
393
348
  * @param definitionRoot The root block of the stack that defines the custom
394
349
  * procedure.
395
- * @return True if the custom procedure was deleted, false otherwise.
350
+ * @returns True if the custom procedure was deleted, false otherwise.
396
351
  */
397
- function deleteProcedureDefCallback(
398
- procCode: string,
399
- definitionRoot: Blockly.BlockSvg
400
- ): boolean {
401
- const callers = getCallers(
402
- procCode,
403
- definitionRoot.workspace,
404
- definitionRoot,
405
- false /* allowRecursive */
406
- );
352
+ function deleteProcedureDefCallback(procCode: string, definitionRoot: Blockly.BlockSvg): boolean {
353
+ const callers = getCallers(procCode, definitionRoot.workspace, definitionRoot, false /* allowRecursive */)
407
354
  if (callers.length > 0) {
408
- return false;
355
+ return false
409
356
  }
410
357
 
411
- const workspace = definitionRoot.workspace;
358
+ const workspace = definitionRoot.workspace
412
359
  // Bypass the checkAndDelete provided by the procedure block mixin
413
- Blockly.BlockSvg.prototype.checkAndDelete.call(definitionRoot);
414
- return true;
360
+ Blockly.BlockSvg.prototype.checkAndDelete.call(definitionRoot)
361
+ return true
415
362
  }
416
363
 
417
364
  /**
418
365
  * Returns whether the given block is a procedure block and narrows its type.
419
- *
420
366
  * @param block The block to check.
421
367
  * @returns True if the block is a procedure block, otherwise false.
422
368
  */
423
- export function isProcedureBlock(
424
- block: Blockly.BlockSvg
425
- ): block is ProcedureBlock {
369
+ export function isProcedureBlock(block: Blockly.BlockSvg): block is ProcedureBlock {
426
370
  return (
427
371
  block.type === Constants.PROCEDURES_CALL_BLOCK_TYPE ||
428
372
  block.type === Constants.PROCEDURES_DECLARATION_BLOCK_TYPE ||
429
373
  block.type === Constants.PROCEDURES_PROTOTYPE_BLOCK_TYPE
430
- );
374
+ )
431
375
  }
432
376
 
433
377
  /**
@@ -435,28 +379,25 @@ export function isProcedureBlock(
435
379
  * through an extension.
436
380
  */
437
381
  interface ProcedureBlock extends Blockly.BlockSvg {
438
- getProcCode(): string;
382
+ getProcCode(): string
439
383
  }
440
384
 
441
385
  /**
442
386
  * Type for a callback function invoked after a procedure is modified.
443
387
  */
444
- type ProcedureDefCallback = (
445
- mutation: Element,
446
- postEditCallback: (mutation?: Element) => void
447
- ) => void;
388
+ type ProcedureDefCallback = (mutation: Element, postEditCallback: (mutation?: Element) => void) => void
448
389
 
449
390
  const ScratchProcedures: {
450
- externalProcedureDefCallback: ProcedureDefCallback | undefined;
451
- createProcedureDefCallback: typeof createProcedureDefCallback;
452
- deleteProcedureDefCallback: typeof deleteProcedureDefCallback;
453
- getProceduresCategory: typeof getProceduresCategory;
454
- makeEditOption: typeof makeEditOption;
391
+ externalProcedureDefCallback: ProcedureDefCallback | undefined
392
+ createProcedureDefCallback: typeof createProcedureDefCallback
393
+ deleteProcedureDefCallback: typeof deleteProcedureDefCallback
394
+ getProceduresCategory: typeof getProceduresCategory
395
+ makeEditOption: typeof makeEditOption
455
396
  } = {
456
397
  externalProcedureDefCallback: undefined,
457
398
  createProcedureDefCallback,
458
399
  deleteProcedureDefCallback,
459
400
  getProceduresCategory,
460
401
  makeEditOption,
461
- };
462
- export { ScratchProcedures };
402
+ }
403
+ export { ScratchProcedures }
@@ -1,12 +1,10 @@
1
1
  /**
2
- * @license
3
2
  * Copyright 2024 Google LLC
4
3
  * SPDX-License-Identifier: Apache-2.0
5
4
  */
6
-
7
- import * as Blockly from "blockly/core";
8
- import { CheckboxBubble } from "./checkbox_bubble";
9
- import { RecyclableBlockFlyoutInflater as BlocklyRecyclableBlockFlyoutInflater } from "@blockly/continuous-toolbox";
5
+ import * as Blockly from 'blockly/core'
6
+ import { RecyclableBlockFlyoutInflater as BlocklyRecyclableBlockFlyoutInflater } from '@blockly/continuous-toolbox'
7
+ import { CheckboxBubble } from './checkbox_bubble'
10
8
 
11
9
  /**
12
10
  * A block inflater that caches and reuses blocks to improve performance.
@@ -14,26 +12,21 @@ import { RecyclableBlockFlyoutInflater as BlocklyRecyclableBlockFlyoutInflater }
14
12
  export class RecyclableBlockFlyoutInflater extends BlocklyRecyclableBlockFlyoutInflater {
15
13
  /**
16
14
  * Creates a block on the flyout workspace from the given block definition.
17
- *
18
15
  * @param state A JSON representation of a block to load.
19
- * @param flyoutWorkspace The flyout's workspace.
16
+ * @param flyoutWorkspace The workspace on which the block will be inflated.
20
17
  * @returns The newly created block.
21
18
  */
22
- load(
23
- state: Blockly.utils.toolbox.BlockInfo,
24
- flyoutWorkspace: Blockly.WorkspaceSvg
25
- ): Blockly.FlyoutItem {
26
- const flyoutItem = super.load(state, flyoutWorkspace);
27
- const block = flyoutItem.getElement();
28
- if ("checkboxInFlyout" in block && block.checkboxInFlyout) {
19
+ load(state: Blockly.utils.toolbox.BlockInfo, flyoutWorkspace: Blockly.WorkspaceSvg): Blockly.FlyoutItem {
20
+ const flyoutItem = super.load(state, flyoutWorkspace)
21
+ const block = flyoutItem.getElement()
22
+ if ('checkboxInFlyout' in block && block.checkboxInFlyout) {
29
23
  block.moveBy(
30
- (flyoutWorkspace.RTL ? -1 : 1) *
31
- (CheckboxBubble.CHECKBOX_SIZE + CheckboxBubble.CHECKBOX_MARGIN),
32
- 0
33
- );
24
+ (flyoutWorkspace.RTL ? -1 : 1) * (CheckboxBubble.CHECKBOX_SIZE + CheckboxBubble.CHECKBOX_MARGIN),
25
+ 0,
26
+ )
34
27
  }
35
28
 
36
- return flyoutItem;
29
+ return flyoutItem
37
30
  }
38
31
  }
39
32
 
@@ -42,10 +35,6 @@ export class RecyclableBlockFlyoutInflater extends BlocklyRecyclableBlockFlyoutI
42
35
  * block flyout inflater.
43
36
  */
44
37
  export function registerRecyclableBlockFlyoutInflater() {
45
- Blockly.registry.unregister(Blockly.registry.Type.FLYOUT_INFLATER, "block");
46
- Blockly.registry.register(
47
- Blockly.registry.Type.FLYOUT_INFLATER,
48
- "block",
49
- RecyclableBlockFlyoutInflater
50
- );
38
+ Blockly.registry.unregister(Blockly.registry.Type.FLYOUT_INFLATER, 'block')
39
+ Blockly.registry.register(Blockly.registry.Type.FLYOUT_INFLATER, 'block', RecyclableBlockFlyoutInflater)
51
40
  }