editor.js 149 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566
  1. /**
  2. * An object that manages the various editors, where users can edit their program. Also manages the
  3. * movement between editors.
  4. * There are currently four editors:
  5. * - Blocks: A Blockly instance
  6. * - Text: A CodeMirror instance
  7. * - Instructor: Features for changing the assignment and environment settings
  8. *
  9. * @constructor
  10. * @this {BlockPyEditor}
  11. * @param {Object} main - The main BlockPy instance
  12. * @param {HTMLElement} tag - The HTML object this is attached to.
  13. */
  14. function BlockPyEditor(main, tag) {
  15. this.main = main;
  16. this.tag = tag;
  17. // This tool is what actually converts text to blocks!
  18. this.converter = new PythonToBlocks();
  19. // HTML DOM accessors
  20. this.blockTag = tag.find('.blockpy-blocks');
  21. this.blocklyDiv = this.blockTag.find('.blockly-div');
  22. this.textTag = tag.find('.blockpy-text');
  23. this.instructorTag = tag.find('.blockpy-instructor');
  24. this.textSidebarTag = this.textTag.find(".blockpy-text-sidebar");
  25. // Blockly and CodeMirror instances
  26. this.blockly = null;
  27. this.codeMirror = null;
  28. // The updateStack keeps track of whether an update is percolating, to prevent duplicate update events.
  29. this.silenceBlock = false;
  30. this.silenceBlockTimer = null;
  31. this.silenceText = false;
  32. this.silenceModel = 0;
  33. this.blocksFailed = false;
  34. this.blocksFailedTimeout = null;
  35. // Hack to prevent chrome errors. Forces audio to load on demand.
  36. // See: https://github.com/google/blockly/issues/299
  37. Blockly.WorkspaceSvg.prototype.preloadAudio_ = function () { };
  38. // Keep track of the toolbox width
  39. this.blocklyToolboxWidth = 0;
  40. // Initialize subcomponents
  41. this.initText();
  42. this.initBlockly();
  43. this.initInstructor();
  44. this.triggerOnChange = null;
  45. var editor = this;
  46. var firstEdit = true;
  47. this.main.model.program.subscribe(function () {
  48. editor.updateBlocksFromModel();
  49. editor.updateTextFromModel();
  50. if (editor.main.model.settings.filename() == "__main__" &&
  51. !firstEdit) {
  52. // if (editor.triggerOnChange) {
  53. // clearTimeout(editor.triggerOnChange);
  54. // }
  55. // var engine = editor.main.components.engine;
  56. // editor.triggerOnChange = setTimeout(engine.on_change.bind(engine), 1000);
  57. }
  58. firstEdit = false;
  59. });
  60. // Handle mode switching
  61. var settings = this.main.model.settings;
  62. settings.editor.subscribe(function () { editor.setMode() });
  63. var updateReadOnly = function () {
  64. var newValue = !!(settings.read_only() && !settings.instructor());
  65. //editor.codeMirror.setOption('readOnly', newValue);
  66. tag.toggleClass("blockpy-read-only", newValue);
  67. };
  68. settings.read_only.subscribe(updateReadOnly);
  69. settings.instructor.subscribe(updateReadOnly);
  70. // Handle filename switching
  71. this.main.model.settings.filename.subscribe(function (name) {
  72. if (name == 'give_feedback') {
  73. editor.setMode('Text');
  74. }
  75. });
  76. // Handle Upload mode turned on
  77. this.main.model.assignment.upload.subscribe(function (uploadsMode) {
  78. if (uploadsMode) {
  79. editor.setMode('Text');
  80. }
  81. });
  82. // Have to force a manual block update
  83. //this.updateText();
  84. this.updateBlocksFromModel();
  85. this.updateTextFromModel();
  86. }
  87. /**
  88. * Initializes the Blockly instance (handles all the blocks). This includes
  89. * attaching a number of ChangeListeners that can keep the internal code
  90. * representation updated and enforce type checking.
  91. */
  92. BlockPyEditor.prototype.initBlockly = function () {
  93. this.blockly = Blockly.inject(this.blocklyDiv[0], {
  94. path: this.main.model.constants.blocklyPath,
  95. scrollbars: this.main.model.constants.blocklyScrollbars,
  96. readOnly: this.main.model.settings.read_only(), //"nocursor", //
  97. oneBasedIndex: false,
  98. comments: false,
  99. toolbox: this.updateToolbox(false),
  100. collapse: true,
  101. css: true,
  102. disable: true,
  103. grid: false,
  104. maxBlocks: Infinity,
  105. //media: blocklyPath + '/media/',
  106. rtl: false,
  107. sounds: true,
  108. trashcan: true,
  109. zoom: {
  110. controls: true,
  111. wheel: false,
  112. startScale: 1.0,
  113. maxScale: 2,
  114. minScale: 0.2,
  115. scaleSpeed: 1.2
  116. }
  117. });
  118. // Register model changer
  119. var editor = this;
  120. this.blockly.addChangeListener(function (evt) {
  121. //editor.main.components.feedback.clearEditorErrors();
  122. editor.blockly.highlightBlock(null);
  123. editor.updateBlocks();
  124. });
  125. this.main.model.settings.filename.subscribe(function () {
  126. /*if (editor.main.model.settings.editor() == "Blocks") {
  127. editor.updateBlocksFromModel()
  128. }*/
  129. });
  130. this.main.model.assignment.modules.subscribe(function () { editor.updateToolbox(true) });
  131. // Force the proper window size
  132. this.blockly.resize();
  133. // Keep the toolbox width set
  134. this.blocklyToolboxWidth = this.getToolbarWidth();
  135. Blockly.captureDialog_ = this.copyImage.bind(this);
  136. // Enable static type checking!
  137. /*
  138. this.blockly.addChangeListener(function() {
  139. if (!editor.main.model.settings.disable_variable_types()) {
  140. var variables = editor.main.components.engine.analyzeVariables()
  141. editor.blockly.getAllBlocks().filter(function(r) {return r.type == 'variables_get'}).forEach(function(block) {
  142. var name = block.inputList[0].fieldRow[0].value_;
  143. if (name in variables) {
  144. var type = variables[name];
  145. if (type.type == "Num") {
  146. block.setOutput(true, "Number");
  147. } else if (type.type == "List") {
  148. block.setOutput(true, "Array");
  149. } else if (type.type == "Str") {
  150. block.setOutput(true, "String");
  151. } else {
  152. block.setOutput(true, null);
  153. }
  154. }
  155. })
  156. }
  157. });
  158. */
  159. };
  160. /**
  161. * Retrieves the current width of the Blockly Toolbox, unless
  162. * we're in read-only mode (when there is no toolbox).
  163. * @returns {Number} The current width of the toolbox.
  164. */
  165. BlockPyEditor.prototype.getToolbarWidth = function () {
  166. if (this.main.model.settings.read_only()) {
  167. return 0;
  168. }
  169. else if (this.blockly.toolbox_) {
  170. return this.blockly.toolbox_.width;
  171. }
  172. else {
  173. return 0;
  174. }
  175. }
  176. /**
  177. * Initializes the CodeMirror instance. This handles text editing (with syntax highlighting)
  178. * and also attaches a listener for change events to update the internal code represntation.
  179. */
  180. BlockPyEditor.prototype.initText = function () {
  181. var codeMirrorDiv = this.textTag.find('.codemirror-div')[0];
  182. this.codeMirror = CodeMirror.fromTextArea(codeMirrorDiv, {
  183. mode: {
  184. name: "python",
  185. version: 3,
  186. singleLineStringErrors: false
  187. },
  188. readOnly: this.main.model.settings.read_only(),//"nocursor", //
  189. showCursorWhenSelecting: true,
  190. lineNumbers: true,
  191. firstLineNumber: 1,
  192. indentUnit: 4,
  193. //tabSize: 4,
  194. indentWithTabs: false,
  195. matchBrackets: true,
  196. extraKeys: {
  197. "Tab": "indentMore",
  198. "Shift-Tab": "indentLess"
  199. },
  200. });
  201. // Register model changer
  202. var editor = this;
  203. this.codeMirror.on("change", function () {
  204. //editor.main.components.feedback.clearEditorErrors();
  205. editor.updateText()
  206. editor.unhighlightLines();
  207. });
  208. // Ensure that it fills the editor area
  209. this.codeMirror.setSize(null, "100%");
  210. };
  211. BlockPyEditor.prototype.reloadIntroduction = function () {
  212. var introductionEditor = this.tag.find('.blockpy-presentation-body-editor');
  213. var model = this.main.model;
  214. introductionEditor.code(model.assignment.introduction());
  215. }
  216. /**
  217. * Initializes the Instructor tab, which has a number of buttons and menus for
  218. * manipulating assignments and the environment. One important job is to register the
  219. * SummerNote instance used for editing the Introduction of the assignment.
  220. */
  221. BlockPyEditor.prototype.initInstructor = function () {
  222. var introductionEditor = this.tag.find('.blockpy-presentation-body-editor');
  223. var model = this.main.model;
  224. introductionEditor.summernote({
  225. codemirror: { // codemirror options
  226. theme: 'monokai'
  227. },
  228. onChange: model.assignment.introduction,
  229. toolbar: [
  230. ['style', ['bold', 'italic', 'underline', 'clear']],
  231. ['font', ['fontname', 'fontsize']],
  232. ['insert', ['link', 'table', 'ul', 'ol', 'image']],
  233. ['misc', ['codeview', 'help']]
  234. ]
  235. });
  236. this.reloadIntroduction();
  237. this.availableModules = this.tag.find('.blockpy-available-modules');
  238. this.availableModules.multiSelect({ selectableOptgroup: true });
  239. }
  240. /**
  241. * Makes the module available in the availableModules multi-select menu by adding
  242. * it to the list.
  243. *
  244. * @param {String} name - The name of the module (human-friendly version, as opposed to the slug) to be added.
  245. */
  246. BlockPyEditor.prototype.addAvailableModule = function (name) {
  247. this.availableModules.multiSelect('addOption', {
  248. 'value': name,
  249. 'text': name
  250. });
  251. this.availableModules.multiSelect('select', name);
  252. };
  253. /**
  254. * Hides the Text tab, which involves shrinking it and hiding its CodeMirror too.
  255. */
  256. BlockPyEditor.prototype.hideSplitMenu = function () {
  257. this.hideTextMenu();
  258. this.hideBlockMenu();
  259. }
  260. /**
  261. * Shows the Text tab, which requires restoring its height, showing AND refreshing
  262. * the CodeMirror instance.
  263. */
  264. BlockPyEditor.prototype.showSplitMenu = function () {
  265. this.showBlockMenu();
  266. this.showTextMenu();
  267. this.textTag.css('width', '100%');
  268. this.blockTag.css('width', '100%');
  269. this.textSidebarTag.css('width', '0px');
  270. // this.textTag.addClass('col-md-12');
  271. // this.blockTag.addClass('col-md-12');
  272. Blockly.svgResize(this.blockly);
  273. }
  274. /**
  275. * Hides the Text tab, which involves shrinking it and hiding its CodeMirror too.
  276. */
  277. BlockPyEditor.prototype.hideTextMenu = function () {
  278. this.textTag.css('height', '0%');
  279. $(this.codeMirror.getWrapperElement()).hide();
  280. this.textSidebarTag.hide();
  281. this.textTag.hide();
  282. }
  283. /**
  284. * Shows the Text tab, which requires restoring its height, showing AND refreshing
  285. * the CodeMirror instance.
  286. */
  287. BlockPyEditor.prototype.showTextMenu = function () {
  288. this.textTag.show();
  289. // Adjust height
  290. this.textTag.css('height', '100%');
  291. this.textTag.css('width', '100%');
  292. // Show CodeMirror
  293. $(this.codeMirror.getWrapperElement()).show();
  294. // CodeMirror doesn't know its changed size
  295. this.codeMirror.refresh();
  296. // Resize sidebar
  297. var codemirrorGutterWidth = $('.CodeMirror-gutters').width();
  298. var sideBarWidth = this.blocklyToolboxWidth - codemirrorGutterWidth - 2;
  299. this.textSidebarTag.css('width', sideBarWidth + 'px');
  300. this.textSidebarTag.show();
  301. // this.textTag.removeClass('col-md-6');
  302. }
  303. /**
  304. * Hides the Block tab, which involves shrinking it and hiding the Blockly instance.
  305. */
  306. BlockPyEditor.prototype.hideBlockMenu = function () {
  307. this.blocklyToolboxWidth = this.getToolbarWidth();
  308. this.blockTag.css('height', '0%');
  309. this.blocklyDiv.css("width", "0");
  310. this.blockly.setVisible(false);
  311. }
  312. /**
  313. * Shows the Block tab, which involves restoring its height and showing the Blockly instance.
  314. */
  315. BlockPyEditor.prototype.showBlockMenu = function () {
  316. this.blockTag.css('height', '100%');
  317. this.blockTag.css('width', '100%');
  318. this.blocklyDiv.css("width", "100%");
  319. this.blockly.resize();
  320. this.blockly.setVisible(true);
  321. this.blockTag.removeClass('col-md-6');
  322. Blockly.svgResize(this.blockly);
  323. }
  324. /**
  325. * Hides the Instructor tab, which shrinking it.
  326. */
  327. BlockPyEditor.prototype.hideInstructorMenu = function () {
  328. this.instructorTag.hide();
  329. this.instructorTag.css('height', '0%');
  330. }
  331. /**
  332. * Shows the Instructor tab, which involves restoring its height.
  333. */
  334. BlockPyEditor.prototype.showInstructorMenu = function () {
  335. this.instructorTag.css('height', '100%');
  336. this.instructorTag.show();
  337. }
  338. /**
  339. * Sets the current editor mode to Text, hiding the other menus.
  340. * Also forces the text side to update.
  341. */
  342. BlockPyEditor.prototype.setModeToText = function () {
  343. this.hideBlockMenu();
  344. this.hideInstructorMenu();
  345. this.showTextMenu();
  346. // Update the text model from the blocks
  347. }
  348. /**
  349. * Sets the current editor mode to Blocks, hiding the other menus.
  350. * Also forces the block side to update.
  351. * There is a chance this could fail, if the text side is irredeemably
  352. * awful. So then the editor bounces back to the text side.
  353. */
  354. BlockPyEditor.prototype.setModeToBlocks = function () {
  355. this.hideTextMenu();
  356. this.hideInstructorMenu();
  357. this.showBlockMenu();
  358. if (this.blocksFailed !== false) {
  359. this.showConversionError();
  360. var main = this.main;
  361. main.model.settings.editor("Text");
  362. setTimeout(function () {
  363. main.components.toolbar.tags.mode_set_text.click();
  364. }, 0);
  365. }
  366. // Update the blocks model from the text
  367. /*
  368. success = this.updateBlocksFromModel();
  369. if (!success) {
  370. var main = this.main;
  371. main.components.editor.updateTextFromModel();
  372. main.model.settings.editor("Text");
  373. setTimeout(function() {
  374. main.components.toolbar.tags.mode_set_text.click();
  375. }, 0);
  376. }*/
  377. }
  378. /**
  379. * Sets the current editor mode to Split mode, hiding the other menus.
  380. */
  381. BlockPyEditor.prototype.setModeToSplit = function () {
  382. this.hideTextMenu();
  383. this.hideInstructorMenu();
  384. this.hideBlockMenu();
  385. this.showSplitMenu();
  386. if (this.blocksFailed !== false) {
  387. this.showConversionError();
  388. }
  389. }
  390. /**
  391. * Sets the current editor mode to the Instructor mode, hiding the other menus.
  392. */
  393. BlockPyEditor.prototype.setModeToInstructor = function () {
  394. this.hideTextMenu();
  395. this.hideBlockMenu();
  396. this.showInstructorMenu();
  397. //TODO: finish upload mode
  398. //this.main.reportError("editor", "Instructor mode has not been implemented");
  399. }
  400. BlockPyEditor.prototype.changeMode = function () {
  401. if (main.model.settings.editor() == "Blocks") {
  402. main.model.settings.editor("Text");
  403. } else {
  404. main.model.settings.editor("Blocks");
  405. }
  406. }
  407. /**
  408. * Dispatch method to set the mode to the given argument.
  409. * If the mode is invalid, an editor error is reported. If the
  410. *
  411. * @param {String} mode - The new mode to set to ("Blocks", "Text", or "Instructor")
  412. */
  413. BlockPyEditor.prototype.setMode = function (mode) {
  414. // Either update the model, or go with the model's
  415. if (mode === undefined) {
  416. mode = this.main.model.settings.editor();
  417. } else {
  418. this.main.model.settings.editor(mode);
  419. }
  420. // Dispatch according to new mode
  421. if (mode == 'Blocks') {
  422. this.setModeToBlocks();
  423. } else if (mode == 'Text') {
  424. this.setModeToText();
  425. } else if (mode == 'Split') {
  426. this.setModeToSplit();
  427. } else if (mode == 'Instructor') {
  428. this.setModeToInstructor();
  429. } else if (mode == 'Upload') {
  430. this.setModeToText();
  431. }
  432. // else {
  433. // this.main.components.feedback.internalError("" + mode, "Invalid Mode", "The editor attempted to change to an invalid mode.")
  434. // }
  435. }
  436. /**
  437. * Actually changes the value of the CodeMirror instance
  438. *
  439. * @param {String} code - The new code for the CodeMirror
  440. */
  441. BlockPyEditor.prototype.setText = function (code) {
  442. if (code == undefined || code.trim() == "") {
  443. this.codeMirror.setValue("\n");
  444. } else {
  445. this.codeMirror.setValue(code);
  446. }
  447. // Ensure that we maintain proper highlighting
  448. this.refreshHighlight();
  449. }
  450. BlockPyEditor.prototype.showConversionError = function () {
  451. var error = this.blocksFailed;
  452. //this.main.components.feedback.convertSkulptSyntax(error);
  453. }
  454. BlockPyEditor.prototype.setBlocks = function (python_code) {
  455. if (!(!this.main.model.assignment.upload() &&
  456. (this.main.model.settings.filename() == "__main__" ||
  457. this.main.model.settings.filename() == "starting_code"))) {
  458. return false;
  459. }
  460. var xml_code = "";
  461. if (python_code !== '' && python_code !== undefined && python_code.trim().charAt(0) !== '<') {
  462. var result = this.converter.convertSource(python_code);
  463. xml_code = result.xml;
  464. window.clearTimeout(this.blocksFailedTimeout);
  465. if (result.error !== null) {
  466. this.blocksFailed = result.error;
  467. var editor = this;
  468. this.blocksFailedTimeout = window.setTimeout(function () {
  469. if (editor.main.model.settings.editor() != 'Text') {
  470. editor.showConversionError();
  471. }
  472. }, 500)
  473. } else {
  474. this.blocksFailed = false;
  475. //this.main.components.feedback.clearEditorErrors();
  476. }
  477. }
  478. var error_code = this.converter.convertSourceToCodeBlock(python_code);
  479. var errorXml = Blockly.Xml.textToDom(error_code);
  480. if (python_code == '' || python_code == undefined || python_code.trim() == '') {
  481. this.blockly.clear();
  482. } else if (xml_code !== '' && xml_code !== undefined) {
  483. var blocklyXml = Blockly.Xml.textToDom(xml_code);
  484. try {
  485. this.setBlocksFromXml(blocklyXml);
  486. pythonnewcode = python_code;
  487. } catch (e) {
  488. console.error(e);
  489. this.setBlocksFromXml(errorXml);
  490. }
  491. } else {
  492. this.setBlocksFromXml(errorXml);
  493. }
  494. Blockly.Events.disable();
  495. /*
  496. // Parsons shuffling
  497. if (this.main.model.assignment.parsons()) {
  498. this.blockly.shuffle();
  499. } else {
  500. this.blockly.align();
  501. }
  502. */
  503. Blockly.Events.enable();
  504. if (this.previousLine !== null) {
  505. this.refreshBlockHighlight(this.previousLine);
  506. }
  507. }
  508. BlockPyEditor.prototype.clearDeadBlocks = function () {
  509. var all_blocks = this.blockly.getAllBlocks();
  510. all_blocks.forEach(function (elem) {
  511. if (!Blockly.Python[elem.type]) {
  512. elem.dispose(true);
  513. }
  514. });
  515. }
  516. /**
  517. * Attempts to update the model for the current code file from the
  518. * block workspace. Might be prevented if an update event was already
  519. * percolating.
  520. */
  521. BlockPyEditor.prototype.updateBlocks = function () {
  522. if (!this.silenceBlock) {
  523. try {
  524. var newCode = Blockly.Python.workspaceToCode(this.blockly);
  525. pythonnewcode = newCode;
  526. } catch (e) {
  527. this.clearDeadBlocks();
  528. //this.main.components.feedback.editorError("Unknown Block", "It looks like you attempted to paste or load some blocks that were not known. Typically, this is because you failed to load in the dataset before trying to paste in a data block. If there are any black blocks on the canvas, delete them before continuing.", "Unknown Block");
  529. }
  530. // Update Model
  531. this.silenceModel = 2;
  532. var changed = this.main.setCode(newCode);
  533. if (!changed) {
  534. this.silenceModel = 0;
  535. } else {
  536. // Update Text
  537. this.silenceText = true;
  538. this.setText(newCode);
  539. }
  540. }
  541. }
  542. /**
  543. * Attempts to update the model for the current code file from the
  544. * text editor. Might be prevented if an update event was already
  545. * percolating. Also unhighlights any lines.
  546. */
  547. var timerGuard = null;
  548. BlockPyEditor.prototype.updateText = function (code) {
  549. if (!this.silenceText) {
  550. var newCode = code || this.codeMirror.getValue();
  551. // Update Model
  552. this.silenceModel = 2;
  553. this.main.setCode(newCode);
  554. // Update Blocks
  555. this.silenceBlock = true;
  556. this.setBlocks(newCode);
  557. this.unhighlightLines();
  558. this.resetBlockSilence();
  559. }
  560. this.silenceText = false;
  561. }
  562. /**
  563. * Resets the silenceBlock after a short delay
  564. */
  565. BlockPyEditor.prototype.resetBlockSilence = function () {
  566. var editor = this;
  567. if (editor.silenceBlockTimer != null) {
  568. clearTimeout(editor.silenceBlockTimer);
  569. }
  570. this.silenceBlockTimer = window.setTimeout(function () {
  571. editor.silenceBlock = false;
  572. editor.silenceBlockTimer = null;
  573. }, 40);
  574. };
  575. /**
  576. * Updates the text editor from the current code file in the
  577. * model. Might be prevented if an update event was already
  578. * percolating.
  579. */
  580. BlockPyEditor.prototype.updateTextFromModel = function () {
  581. if (this.silenceModel == 0) {
  582. var code = this.main.model.program();
  583. this.silenceText = true;
  584. this.setText(code);
  585. } else {
  586. this.silenceModel -= 1;
  587. }
  588. }
  589. /**
  590. * Updates the block editor from the current code file in the
  591. * model. Might be prevented if an update event was already
  592. * percolating. This can also report an error if one occurs.
  593. *
  594. * @returns {Boolean} Returns true upon success.
  595. */
  596. BlockPyEditor.prototype.updateBlocksFromModel = function () {
  597. if (this.silenceModel == 0) {
  598. var code = this.main.model.program().trim();
  599. this.silenceBlock = true;
  600. this.setBlocks(code);
  601. this.resetBlockSilence();
  602. } else {
  603. this.silenceModel -= 1;
  604. }
  605. }
  606. /**
  607. * Helper function for retrieving the current Blockly workspace as
  608. * an XML DOM object.
  609. *
  610. * @returns {XMLDom} The blocks in the current workspace.
  611. */
  612. BlockPyEditor.prototype.getBlocksFromXml = function () {
  613. return Blockly.Xml.workspaceToDom(this.blockly);
  614. }
  615. /**
  616. * Helper function for setting the current Blockly workspace to
  617. * whatever XML DOM is given. This clears out any existing blocks.
  618. */
  619. BlockPyEditor.prototype.setBlocksFromXml = function (xml) {
  620. //this.blockly.clear();
  621. Blockly.Xml.domToWorkspaceDestructive(xml, this.blockly);
  622. //console.log(this.blockly.getAllBlocks());
  623. }
  624. BlockPyEditor.prototype.clearBlocksFromXml = function () {
  625. this.blockly.clear();
  626. }
  627. /**
  628. * @property {Number} previousLine - Keeps track of the previously highlighted line.
  629. */
  630. BlockPyEditor.prototype.previousLine = null;
  631. /**
  632. * Assuming that a line has been highlighted previously, this will set the
  633. * line to be highlighted again. Used when we need to restore a highlight.
  634. */
  635. BlockPyEditor.prototype.refreshHighlight = function () {
  636. if (this.previousLine !== null) {
  637. if (this.previousLine < this.codeMirror.lineCount()) {
  638. this.codeMirror.addLineClass(this.previousLine, 'text', 'editor-error-line');
  639. }
  640. }
  641. // TODO: Shouldn't this refresh the highlight in the block side too?
  642. }
  643. /**
  644. * Highlights a line of code in the CodeMirror instance. This applies the "active" style
  645. * which is meant to bring attention to a line, but not suggest it is wrong.
  646. *
  647. * @param {Number} line - The line of code to highlight. I think this is zero indexed?
  648. */
  649. BlockPyEditor.prototype.highlightLine = function (line) {
  650. if (this.previousLine !== null) {
  651. if (this.previousLine < this.codeMirror.lineCount()) {
  652. this.codeMirror.removeLineClass(this.previousLine, 'text', 'editor-active-line');
  653. this.codeMirror.removeLineClass(this.previousLine, 'text', 'editor-error-line');
  654. }
  655. }
  656. if (line < this.codeMirror.lineCount()) {
  657. this.codeMirror.addLineClass(line, 'text', 'editor-active-line');
  658. }
  659. this.previousLine = line;
  660. }
  661. /**
  662. * Highlights a line of code in the CodeMirror instance. This applies the "error" style
  663. * which is meant to suggest that a line is wrong.
  664. *
  665. * @param {Number} line - The line of code to highlight. I think this is zero indexed?
  666. */
  667. BlockPyEditor.prototype.highlightError = function (line) {
  668. if (this.previousLine !== null) {
  669. if (this.previousLine < this.codeMirror.lineCount()) {
  670. this.codeMirror.removeLineClass(this.previousLine, 'text', 'editor-active-line');
  671. this.codeMirror.removeLineClass(this.previousLine, 'text', 'editor-error-line');
  672. }
  673. }
  674. if (line < this.codeMirror.lineCount()) {
  675. this.codeMirror.addLineClass(line, 'text', 'editor-error-line');
  676. }
  677. this.refreshBlockHighlight(line);
  678. this.previousLine = line;
  679. }
  680. /**
  681. * Highlights a block in Blockly. Unfortunately, this is the same as selecting it.
  682. *
  683. * @param {Number} block - The ID of the block object to highlight.
  684. */
  685. BlockPyEditor.prototype.highlightBlock = function (block) {
  686. //this.blockly.highlightBlock(block);
  687. }
  688. /**
  689. * Used to restore a block's highlight when travelling from the code tab. This
  690. * uses a mapping between the blocks and text that is generated from the parser.
  691. * The parser has stored the relevant line numbers for each block in the XML of the
  692. * block. Very sophisticated, and sadly fairly fragile.
  693. * TODO: I believe there's some kind of off-by-one error here...
  694. *
  695. * @param {Number} line - The line of code to highlight. I think this is zero indexed?
  696. */
  697. BlockPyEditor.prototype.refreshBlockHighlight = function (line) {
  698. if (this.blocksFailed) {
  699. this.blocksFailed = false;
  700. return;
  701. }
  702. if (this.main.model.settings.editor() != "Blocks" &&
  703. this.main.model.settings.editor() != "Split") {
  704. return;
  705. }
  706. var all_blocks = this.blockly.getAllBlocks();
  707. //console.log(all_blocks.map(function(e) { return e.lineNumber }));
  708. var blockMap = {};
  709. all_blocks.forEach(function (elem) {
  710. var lineNumber = parseInt(elem.lineNumber, 10);
  711. if (lineNumber in blockMap) {
  712. blockMap[lineNumber].push(elem);
  713. } else {
  714. blockMap[lineNumber] = [elem];
  715. }
  716. });
  717. if (1 + line in blockMap) {
  718. var hblocks = blockMap[1 + line];
  719. var blockly = this.blockly;
  720. hblocks.forEach(function (elem) {
  721. //elem.addSelect();
  722. blockly.highlightBlock(elem.id, true);
  723. });
  724. /*if (hblocks.length > 0) {
  725. this.blockly.highlightBlock(hblocks[0].id, true);
  726. }*/
  727. }
  728. }
  729. /**
  730. * Removes the outline around a block. Currently unused.
  731. */
  732. BlockPyEditor.prototype.unhighlightBlock = function () {
  733. // TODO:
  734. }
  735. /**
  736. * Removes any highlight in the text code editor.
  737. *
  738. */
  739. BlockPyEditor.prototype.unhighlightLines = function () {
  740. if (this.previousLine !== null) {
  741. if (this.previousLine < this.codeMirror.lineCount()) {
  742. this.codeMirror.removeLineClass(this.previousLine, 'text', 'editor-active-line');
  743. this.codeMirror.removeLineClass(this.previousLine, 'text', 'editor-error-line');
  744. }
  745. }
  746. this.previousLine = null;
  747. }
  748. /**
  749. * Removes any highlight in the text code editor.
  750. *
  751. */
  752. BlockPyEditor.prototype.unhighlightAllLines = function () {
  753. var editor = this.codeMirror;
  754. var count = editor.lineCount(),
  755. i;
  756. for (i = 0; i < count; i++) {
  757. editor.removeLineClass(i, 'text', 'editor-error-line');
  758. }
  759. }
  760. /**
  761. * DEPRECATED, thankfully
  762. * Builds up an array indicating the relevant block ID for a given step.
  763. * Operates on the current this.blockly instance
  764. * It works by injecting __HIGHLIGHT__(id); at the start of every line of code
  765. * and then extracting that with regular expressions. This makes it vulnerable
  766. * if someone decides to use __HIGHLIGHT__ in their code. I'm betting on that
  767. * never being a problem, though. Still, this was a miserable way of accomplishing
  768. * the desired behavior.
  769. */
  770. BlockPyEditor.prototype.getHighlightMap = function () {
  771. // Protect the current STATEMENT_PREFIX
  772. var backup = Blockly.Python.STATEMENT_PREFIX;
  773. Blockly.Python.STATEMENT_PREFIX = '__HIGHLIGHT__(%1);';
  774. Blockly.Python.addReservedWords('__HIGHLIGHT__');
  775. // Get the source code, injected with __HIGHLIGHT__(id)
  776. var highlightedCode = Blockly.Python.workspaceToCode(this.blockly);
  777. Blockly.Python.STATEMENT_PREFIX = backup;
  778. // Build up the array by processing the highlighted code line-by-line
  779. var highlightMap = [];
  780. var lines = highlightedCode.split("\n");
  781. for (var i = 0; i < lines.length; i++) {
  782. // Get the block ID from the line
  783. var id = lines[i].match(/\W*__HIGHLIGHT__\(\'(.+?)\'\)/);
  784. if (id !== null) {
  785. // Convert it into a base-10 number, because JavaScript.
  786. highlightMap[i] = parseInt(id[1], 10);
  787. }
  788. }
  789. return highlightMap;
  790. }
  791. /**
  792. * Updates the current file being edited in the editors.
  793. * This appears to be deprecated.
  794. *
  795. * @param {String} name - The name of the file being edited (e.g, "__main__", "starting_code")
  796. */
  797. /*
  798. BlockPyEditor.prototype.changeProgram = function(name) {
  799. console.log("TEST")
  800. this.silentChange_ = true;
  801. if (name == 'give_feedback') {
  802. this.setMode('Text');
  803. }
  804. this.model.settings.filename = name;
  805. this.editor.setPython(this.model.programs[name]);
  806. this.toolbar.elements.programs.find("[data-name="+name+"]").click();
  807. }*/
  808. /**
  809. * Eventually will be used to update "levels" of sophistication of the code interface.
  810. * Currently unimplemented and unused.
  811. */
  812. BlockPyEditor.prototype.setLevel = function () {
  813. var level = this.main.model.settings.level();
  814. }
  815. /**
  816. * Maps short category names in the toolbox to the full XML used to
  817. * represent that category as usual. This is kind of a clunky mechanism
  818. * for managing the different categories, and doesn't allow us to specify
  819. * individual blocks.
  820. */
  821. BlockPyEditor.CATEGORY_MAP = {
  822. 'Decisions': '<category id="catLogic" name="Logic" colour="#4c97ff">' +
  823. '<block type="controls_if"></block>' +
  824. '<block type="logic_compare">' +
  825. '</block>' +
  826. '<block type="logic_operation"></block>' +
  827. '<block type="logic_negate"></block>' +
  828. '<block type="logic_boolean"></block>' +
  829. '<block type="logic_null"></block>' +
  830. '<block type="logic_ternary"></block>' +
  831. '<block type="CocoRobo_return"></block>' +
  832. '<block type="CocoRobo_try_except"></block>' +
  833. '<block type="CocoRobo_try_except_finally"></block>' +
  834. '<block type="CocoRobo_type"></block>' +
  835. '<block type="CocoRobo_type_is"></block>' +
  836. '<block type="CocoRobo_eval"></block>' +
  837. '</category>',
  838. 'Iteration': '<category id="catLoops" name="Loops" colour="#9d64fd">' +
  839. '<block type="controls_repeat_forever"></block>' +
  840. '<block type="controls_repeat_ext">' +
  841. '<value name="TIMES">' +
  842. '<shadow type="math_number">' +
  843. ' <field name="NUM">10</field>' +
  844. '</shadow>' +
  845. '</value>' +
  846. '</block>' +
  847. '<block type="controls_whileUntil"></block>' +
  848. '<block type="controls_for">' +
  849. '<value name="FROM">' +
  850. '<shadow type="math_number">' +
  851. '<field name="NUM">1</field>' +
  852. '</shadow>' +
  853. '</value>' +
  854. '<value name="TO">' +
  855. '<shadow type="math_number">' +
  856. '<field name="NUM">10</field>' +
  857. '</shadow>' +
  858. '</value>' +
  859. '<value name="BY">' +
  860. '<shadow type="math_number">' +
  861. '<field name="NUM">1</field>' +
  862. '</shadow>' +
  863. '</value>' +
  864. '</block>' +
  865. '<block type="controls_forEach"></block>' +
  866. '<block type="controls_flow_statements"></block>' +
  867. '</category>',
  868. 'Calculation': '<category id="catMath" name="Math" colour="#5472ea">' +
  869. '<block type="math_number" gap="32"></block>' +
  870. '<block type="math_arithmetic">' +
  871. ' <value name="A">' +
  872. '<shadow type="math_number">' +
  873. ' <field name="NUM">1</field>' +
  874. '</shadow>' +
  875. '</value>' +
  876. '<value name="B">' +
  877. '<shadow type="math_number">' +
  878. ' <field name="NUM">1</field>' +
  879. '</shadow>' +
  880. '</value>' +
  881. '</block>' +
  882. '<block type="math_degrad"></block>' +
  883. '<block type="math_single">' +
  884. '<value name="NUM">' +
  885. '<shadow type="math_number">' +
  886. ' <field name="NUM">9</field>' +
  887. '</shadow>' +
  888. '</value>' +
  889. '</block>' +
  890. '<block type="math_trig">' +
  891. '<value name="NUM">' +
  892. '<shadow type="math_angle">' +
  893. ' <field name="angle">45</field>' +
  894. '</shadow>' +
  895. '</value>' +
  896. '</block>' +
  897. '<!--block type="math_trig">' +
  898. ' <value name="NUM">' +
  899. '<shadow type="math_number">' +
  900. ' <field name="NUM">45</field>' +
  901. '</shadow>' +
  902. '</value>' +
  903. '</block-->' +
  904. '<block type="math_constant"></block>' +
  905. '<block type="math_number_property">' +
  906. '<value name="NUMBER_TO_CHECK">' +
  907. '<shadow type="math_number">' +
  908. ' <field name="NUM">0</field>' +
  909. '</shadow>' +
  910. '</value>' +
  911. '</block>' +
  912. '<block type="math_round">' +
  913. '<value name="NUM">' +
  914. ' <shadow type="math_number">' +
  915. ' <field name="NUM">3.1</field>' +
  916. '</shadow>' +
  917. '</value>' +
  918. '</block>' +
  919. '<block type="math_keep_decimal">' +
  920. '<value name="NUM">' +
  921. ' <shadow type="math_number">' +
  922. ' <field name="NUM">3.1415926</field>' +
  923. '</shadow>' +
  924. '</value>' +
  925. '<value name="PLACE">' +
  926. ' <shadow type="math_number">' +
  927. ' <field name="NUM">2</field>' +
  928. '</shadow>' +
  929. '</value>' +
  930. '</block>' +
  931. '<block type="math_on_list"></block>' +
  932. '<block type="math_modulo">' +
  933. '<value name="DIVIDEND">' +
  934. '<shadow type="math_number">' +
  935. ' <field name="NUM">64</field>' +
  936. '</shadow>' +
  937. '</value>' +
  938. ' <value name="DIVISOR">' +
  939. '<shadow type="math_number">' +
  940. ' <field name="NUM">10</field>' +
  941. '</shadow>' +
  942. '</value>' +
  943. ' </block>' +
  944. '<block type="math_division_consult">' +
  945. ' <value name="DIVIDEND">' +
  946. '<shadow type="math_number">' +
  947. ' <field name="NUM">64</field>' +
  948. '</shadow>' +
  949. '</value>' +
  950. '<value name="DIVISOR">' +
  951. '<shadow type="math_number">' +
  952. ' <field name="NUM">10</field>' +
  953. '</shadow>' +
  954. '</value>' +
  955. '</block>' +
  956. '<block type="math_constrain">' +
  957. ' <value name="VALUE">' +
  958. '<shadow type="math_number">' +
  959. ' <field name="NUM">50</field>' +
  960. '</shadow>' +
  961. '</value>' +
  962. '<value name="LOW">' +
  963. '<shadow type="math_number">' +
  964. ' <field name="NUM">1</field>' +
  965. '</shadow>' +
  966. '</value>' +
  967. ' <value name="HIGH">' +
  968. '<shadow type="math_number">' +
  969. ' <field name="NUM">100</field>' +
  970. '</shadow>' +
  971. ' </value>' +
  972. '</block>' +
  973. ' <block type="labplus_mapping">' +
  974. '<value name="inputNum"><shadow type="math_number"><field name="NUM">10</field></shadow></value>' +
  975. '<value name="bMin"><shadow type="math_number"><field name="NUM">0</field></shadow></value>' +
  976. '<value name="bMax"><shadow type="math_number"><field name="NUM">100</field></shadow></value>' +
  977. '<value name="cMin"><shadow type="math_number"><field name="NUM">0</field></shadow></value>' +
  978. '<value name="cMax"><shadow type="math_number"><field name="NUM">200</field></shadow></value>' +
  979. '</block>' +
  980. '<block type="math_random_int">' +
  981. '<value name="FROM">' +
  982. '<shadow type="math_number">' +
  983. ' <field name="NUM">1</field>' +
  984. '</shadow>' +
  985. '</value>' +
  986. '<value name="TO">' +
  987. '<shadow type="math_number">' +
  988. ' <field name="NUM">100</field>' +
  989. '</shadow>' +
  990. '</value>' +
  991. '</block>' +
  992. '<block type="math_random_randrange">' +
  993. '<value name="start"><shadow type="math_number"><field name="NUM">0</field></shadow></value>' +
  994. ' <value name="stop"><shadow type="math_number"><field name="NUM">10</field></shadow></value>' +
  995. '<value name="step"><shadow type="math_number"><field name="NUM">2</field></shadow></value>' +
  996. '</block>' +
  997. '<block type="math_random_float"></block>' +
  998. '<block type="math_convert"></block>' +
  999. '<block type="math_number_bits_ops">' +
  1000. '<value name="A">' +
  1001. '<shadow type="math_number">' +
  1002. ' <field name="NUM">1</field>' +
  1003. '</shadow>' +
  1004. '</value>' +
  1005. '<value name="B">' +
  1006. '<shadow type="math_number">' +
  1007. ' <field name="NUM">1</field>' +
  1008. '</shadow>' +
  1009. '</value>' +
  1010. '</block>' +
  1011. '<block type="bit_inversion">' +
  1012. '<value name="data"><shadow type="math_number"><field name="NUM">60</field></shadow></value>' +
  1013. '</block>' +
  1014. '<block type="CocoRobo_ten_convert_to">' +
  1015. ' <value name="int_num"><shadow type="math_number"><field name="NUM">10</field></shadow></value>' +
  1016. '</block>' +
  1017. '<block type="CocoRobo_convert_to_ten">' +
  1018. ' <value name="convert_str"><shadow type="text"><field name="TEXT">11</field></shadow></value>' +
  1019. '</block>' +
  1020. '<block type="CocoRobo_ten_converted_to_bytes">' +
  1021. ' <value name="convert_num"><shadow type="math_number"><field name="NUM">11</field></shadow></value>' +
  1022. '</block>' +
  1023. '<block type="CocoRobo_int_to_chr">' +
  1024. ' <value name="convert_num"><shadow type="math_number"><field name="NUM">97</field></shadow></value>' +
  1025. '</block>' +
  1026. '<block type="CocoRobo_chr_to_int">' +
  1027. ' <value name="convert_chr"><shadow type="text"><field name="TEXT">a</field></shadow></value>' +
  1028. ' </block>' +
  1029. ' <block type="CocoRobo_str_to_hex">' +
  1030. '<value name="convert_chr"><shadow type="text"><field name="TEXT">abcdfg</field></shadow></value>' +
  1031. '</block>' +
  1032. '<block type="CocoRobo_hex_to_bin_str">' +
  1033. '<value name="convert_chr"><shadow type="text"><field name="TEXT">313233</field></shadow></value>' +
  1034. ' </block>' +
  1035. '<block type="CocoRobo_data_to_base64">' +
  1036. ' <value name="data"><shadow type="text"><field name="TEXT">cocorobo</field></shadow></value>' +
  1037. '</block>' +
  1038. '<block type="CocoRobo_base64_to_data">' +
  1039. ' <value name="data"><shadow type="text"><field name="TEXT">bXB5dGhvbg==</field></shadow></value>' +
  1040. '</block>' +
  1041. '</category>',
  1042. 'Variables': '<category id="catVariables" name="Variables" custom="VARIABLE" colour="#ffab2f">' +
  1043. '</category>',
  1044. 'Values': '<category id="catText" name="Text" colour="#33cc99">' +
  1045. // '<block type="esp32_main_controller_text_print">' +
  1046. // '<value name="TEXT">' +
  1047. // '<shadow type="esp32_main_controller_text">' +
  1048. // '<field name="TEXT"></field>' +
  1049. // '</shadow>' +
  1050. // ' </value>' +
  1051. // '</block>' +
  1052. ' <block type="text"><field name="TEXT"></field></block>' +
  1053. // '<block type="esp32_main_controller_text"></block>' +
  1054. '<block type="text_join"><mutation items="1"></mutation></block>' +
  1055. ' <block type="text_join"></block>' +
  1056. '<block type="text_split_string_by_delimiter">' +
  1057. '</block>' +
  1058. ' <block type="text_format">' +
  1059. ' <value name="FORMAT">' +
  1060. ' <shadow type="text"><field name="TEXT">Value: %.2f</field></shadow>' +
  1061. ' </value>' +
  1062. ' <value name="CONTENT">' +
  1063. ' <block type="tuple_create_with_items_insert">' +
  1064. ' <mutation items="1"></mutation>' +
  1065. ' <value name="ADD0">' +
  1066. ' <block type="math_number">' +
  1067. ' <field name="NUM">3.1415926</field>' +
  1068. ' </block>' +
  1069. ' </value>' +
  1070. ' </block>' +
  1071. ' </value>' +
  1072. ' </block>' +
  1073. ' <block type="text_format2">' +
  1074. ' <value name="FORMAT">' +
  1075. ' <shadow type="text"><field name="TEXT">Value: {:.3}</field></shadow>' +
  1076. ' </value>' +
  1077. ' <value name="CONTENT">' +
  1078. ' <block type="tuple_create_with_items_insert">' +
  1079. ' <mutation items="1"></mutation>' +
  1080. ' <value name="ADD0">' +
  1081. ' <block type="math_number">' +
  1082. ' <field name="NUM">3.1415926</field>' +
  1083. ' </block>' +
  1084. ' </value>' +
  1085. '</block>' +
  1086. '</value>' +
  1087. ' </block>' +
  1088. '<block type="CocoRobo_text_ESC">' +
  1089. '</block>' +
  1090. '<block type="text_append_text">' +
  1091. '<value name="text_abc"><shadow type="text"><field name="TEXT">abc</field></shadow></value>' +
  1092. '<value name="append_text"><shadow type="text"><field name="TEXT">def</field></shadow></value>' +
  1093. '</block>' +
  1094. '<block type="text_is_number">' +
  1095. '<value name="TEXT">' +
  1096. ' <shadow type="text">' +
  1097. '<field name="TEXT"></field>' +
  1098. '</shadow>' +
  1099. '</value>' +
  1100. '</block>' +
  1101. '<block type="text_length">' +
  1102. '<value name="VALUE">' +
  1103. '<shadow type="text">' +
  1104. ' <field name="TEXT"></field>' +
  1105. '</shadow>' +
  1106. '</value>' +
  1107. '</block>' +
  1108. '<block type="text_isEmpty">' +
  1109. '<value name="VALUE">' +
  1110. '<shadow type="text">' +
  1111. ' <field name="TEXT"></field>' +
  1112. '</shadow>' +
  1113. '</value>' +
  1114. '</block>' +
  1115. '<block type="text_indexOf">' +
  1116. '<value name="VALUE">' +
  1117. ' <shadow type="text">' +
  1118. '<field name="TEXT">abc</field>' +
  1119. '</shadow>' +
  1120. '</value>' +
  1121. '<value name="FIND">' +
  1122. ' <shadow type="text">' +
  1123. '<field name="TEXT">b</field>' +
  1124. ' </shadow>' +
  1125. '</value>' +
  1126. '</block>' +
  1127. '<block type="text_charAt">' +
  1128. '<value name="VALUE">' +
  1129. '<shadow type="text">' +
  1130. '<field name="TEXT">abc</field>' +
  1131. ' </shadow>' +
  1132. '</value>' +
  1133. ' </block>' +
  1134. ' <block type="text_getSubstring">' +
  1135. '<value name="STRING">' +
  1136. ' <shadow type="text">' +
  1137. '<field name="TEXT">abc</field>' +
  1138. ' </shadow>' +
  1139. '</value>' +
  1140. ' </block>' +
  1141. ' <block type="text_changeCase">' +
  1142. '<value name="TEXT">' +
  1143. ' <shadow type="text">' +
  1144. ' <field name="TEXT"></field>' +
  1145. ' </shadow>' +
  1146. ' </value>' +
  1147. ' </block>' +
  1148. ' <block type="text_trim">' +
  1149. ' <value name="TEXT">' +
  1150. ' <shadow type="text">' +
  1151. ' <field name="TEXT"></field>' +
  1152. ' </shadow>' +
  1153. ' </value>' +
  1154. ' </block>' +
  1155. ' <block type="text_to_byte">' +
  1156. ' <value name="TEXT">' +
  1157. ' <shadow type="text">' +
  1158. ' <field name="TEXT">abc</field>' +
  1159. ' </shadow>' +
  1160. ' </value>' +
  1161. ' </block>' +
  1162. ' <block type="CocoRobo_bytes_decode">' +
  1163. ' <value name="bytes_decode"></value>' +
  1164. '</block>' +
  1165. '<block type="CocoRobo_ujson_dumps">' +
  1166. ' <value name="data"><shadow type="text_dict"><field name="TEXT">"Age":8</field></shadow></value>' +
  1167. '</block>' +
  1168. '<block type="CocoRobo_ujson_loads">' +
  1169. '<value name="data"><shadow type="text"><field name="TEXT">{"Age":8}</field></shadow></value>' +
  1170. '</block>' +
  1171. '<block type="CocoRobo_code_annotation">' +
  1172. '<value name="data"><shadow type="text"><field name="TEXT"></field></shadow></value>' +
  1173. '</block>' +
  1174. '</category>',
  1175. 'Lists': '<category id="catLists" name="Lists" colour="#40bfe4">' +
  1176. '<block type="lists_create_with"><mutation items="0"></mutation></block>' +
  1177. '<block type="lists_create_with"></block>' +
  1178. ' <block type="text_list"><field name="TEXT">0, 0, 0</field></block>' +
  1179. ' <!--block type="file_to_list">' +
  1180. ' <value name="file_path"><shadow type="text"><field name="TEXT">1.txt</field></shadow></value>' +
  1181. ' </block-->' +
  1182. ' <block type="CocoRobo_return_list">' +
  1183. ' <value name="list_name"><block type="variables_get"><field name="VAR">my_list</field></block></value>' +
  1184. ' <value name="list_items"><shadow type="text_list"><field name="TEXT">0, 0, 0</field></shadow></value>' +
  1185. ' </block>' +
  1186. ' <block type="list_order_item">' +
  1187. ' <value name="list_name"><shadow type="text_list"><field name="TEXT"></field></shadow></value>' +
  1188. ' <value name="list_order_item"><shadow type="math_number"><field name="NUM">0</field></shadow></value>' +
  1189. ' </block>' +
  1190. ' <block type="lists_append">' +
  1191. ' <value name="list_name"><shadow type="text_list"><field name="TEXT"></field></shadow></value>' +
  1192. ' </block>' +
  1193. ' <block type="list_item_exist">' +
  1194. ' <value name="list_name"><shadow type="text_list"><field name="TEXT"></field></shadow></value>' +
  1195. ' <value name="list_item"><shadow type="text"><field name="TEXT">cocorobo</field></shadow></value>' +
  1196. ' </block>' +
  1197. ' <block type="lists_extend">' +
  1198. ' <value name="list_name"><shadow type="text_list"><field name="TEXT"></field></shadow></value>' +
  1199. ' <value name="extend_list"><shadow type="text_list"><field name="TEXT"></field></shadow></value>' +
  1200. ' </block>' +
  1201. ' <block type="lists_clear">' +
  1202. ' <value name="list_name"><shadow type="text_list"><field name="TEXT"></field></shadow></value>' +
  1203. ' </block>' +
  1204. ' <block type="lists_repeat">' +
  1205. '<value name="NUM">' +
  1206. ' <shadow type="math_number">' +
  1207. ' <field name="NUM">5</field>' +
  1208. ' </shadow>' +
  1209. '</value>' +
  1210. ' </block>' +
  1211. ' <block type="lists_length"></block>' +
  1212. ' <block type="lists_isEmpty"></block>' +
  1213. ' <block type="list_first_index">' +
  1214. ' <value name="elem"><shadow type="text"><field name="TEXT">cocorobo</field></shadow></value>' +
  1215. ' <value name="my_list"><shadow type="text_list"><field name="TEXT"></field></shadow></value>' +
  1216. ' </block>' +
  1217. ' <block type="set_list_order_item">' +
  1218. ' <value name="list_name"><shadow type="text_list"><field name="TEXT"></field></shadow></value>' +
  1219. ' <value name="list_order_item"><shadow type="math_number"><field name="NUM">0</field></shadow></value>' +
  1220. ' <value name="set_value"><shadow type="math_number"><field name="NUM">0</field></shadow></value>' +
  1221. ' </block>' +
  1222. ' <block type="insert_list_order_item">' +
  1223. ' <value name="list_name"><shadow type="text_list"><field name="TEXT"></field></shadow></value>' +
  1224. ' <value name="list_order_item"><shadow type="math_number"><field name="NUM">0</field></shadow></value>' +
  1225. ' <value name="set_value"><shadow type="math_number"><field name="NUM">0</field></shadow></value>' +
  1226. ' </block>' +
  1227. ' <block type="parts_of_list">' +
  1228. ' <value name="list_name"><shadow type="text_list"><field name="TEXT"></field></shadow></value>' +
  1229. ' <value name="start_item"><shadow type="math_number"><field name="NUM">0</field></shadow></value>' +
  1230. ' <value name="end_item"><shadow type="math_number"><field name="NUM">2</field></shadow></value>' +
  1231. ' </block>' +
  1232. '<block type="lists_getIndex">' +
  1233. ' <mutation statement="true" at="true"></mutation>' +
  1234. ' <field name="MODE">REMOVE</field>' +
  1235. ' <field name="WHERE">FROM_START</field>' +
  1236. ' <value name="VALUE">' +
  1237. ' <shadow type="text_list"><field name="TEXT"></field></shadow>' +
  1238. ' </value>' +
  1239. '</block>' +
  1240. '<block type="lists_getIndex">' +
  1241. ' <mutation statement="false" at="true"></mutation>' +
  1242. ' <field name="MODE">GET_REMOVE</field>' +
  1243. ' <field name="WHERE">FROM_START</field>' +
  1244. ' <value name="VALUE">' +
  1245. ' <shadow type="text_list"><field name="TEXT"></field></shadow>' +
  1246. ' </value>' +
  1247. '</block>' +
  1248. ' <block type="lists_split">' +
  1249. ' <value name="DELIM"><shadow type="text"><field name="TEXT">,</field></shadow></value>' +
  1250. ' </block>' +
  1251. ' <block type="lists_sort"></block>' +
  1252. '</category>',
  1253. 'Dictionary': '<category id="catDictionary" name="Dictionary" colour="32">' +
  1254. ' <block type="dict_create_with_items_insert"></block>' +
  1255. ' <block type="text_dict"><field name="TEXT">"Age":8</field></block>' +
  1256. ' <block type="dict_create_with">' +
  1257. ' <value name="dict_name"><block type="variables_get"><field name="VAR">my_dict</field></block></value>' +
  1258. ' <value name="dict_items"><shadow type="text_dict"><field name="TEXT">"Age":8</field></shadow></value>' +
  1259. ' </block>' +
  1260. ' <block type="add_dict_key_value">' +
  1261. ' <value name="dict_name"><shadow type="text_dict"><field name="TEXT"></field></shadow></value>' +
  1262. ' <value name="dict_items"><shadow type="text"><field name="TEXT">Age</field></shadow></value>' +
  1263. ' <value name="add_value"><shadow type="math_number"><field name="NUM">10</field></shadow></value>' +
  1264. ' </block>' +
  1265. ' <block type="dict_key_value">' +
  1266. ' <value name="dict_name"><shadow type="text_dict"><field name="TEXT"></field></shadow></value>' +
  1267. ' <value name="dict_items"><shadow type="text"><field name="TEXT">Age</field></shadow></value>' +
  1268. ' </block>' +
  1269. ' <block type="dict_length">' +
  1270. ' <value name="dict_name"><shadow type="text_dict"><field name="TEXT"></field></shadow></value>' +
  1271. ' </block>' +
  1272. ' <block type="dict_key_exist">' +
  1273. ' <value name="dict_name"><shadow type="text_dict"><field name="TEXT"></field></shadow></value>' +
  1274. ' <value name="dict_items"><shadow type="text"><field name="TEXT">Age</field></shadow></value>' +
  1275. ' </block>' +
  1276. ' <block type="dict_key_or_val_list">' +
  1277. ' <value name="dict_name"><shadow type="text_dict"><field name="TEXT"></field></shadow></value>' +
  1278. ' </block>' +
  1279. '</category>',
  1280. // 'Tuples': '<category id="catTuples" name="Tuples" colour="#0090d1">' +
  1281. // '</category>',
  1282. 'Tuples': '<category id="catTuples" name="Tuples" colour="192">' +
  1283. ' <block type="tuple_create_with_items_insert"></block>' +
  1284. '<block type="text_tuple"><field name="TEXT">"cocorobo",</field></block>' +
  1285. '<block type="tuple_create_with">' +
  1286. ' <value name="tuple_name"><block type="variables_get"><field name="VAR">my_tuple</field></block></value>' +
  1287. ' <value name="tuple_items"><shadow type="text_tuple"><field name="TEXT">"cocorobo",</field></shadow></value>' +
  1288. ' </block>' +
  1289. ' <block type="tuple_order_item">' +
  1290. ' <value name="tuple_name"><shadow type="text_tuple"><field name="TEXT"></field></shadow></value>' +
  1291. ' <value name="tuple_order_item"><shadow type="math_number"><field name="NUM">0</field></shadow></value>' +
  1292. '</block>' +
  1293. '<block type="tuple_min_max_len">' +
  1294. ' <value name="tuple_name"><shadow type="text_tuple"><field name="TEXT"></field></shadow></value>' +
  1295. ' </block>' +
  1296. '<block type="tuple_item_exist">' +
  1297. ' <value name="tuple_name"><shadow type="text_tuple"><field name="TEXT"></field></shadow></value>' +
  1298. ' <value name="tuple_item"><shadow type="text"><field name="TEXT">cocorobo</field></shadow></value>' +
  1299. '</block>' +
  1300. '<block type="parts_of_tuple">' +
  1301. ' <value name="tuple_name"><shadow type="text_tuple"><field name="TEXT"></field></shadow></value>' +
  1302. ' <value name="tuple_item"><shadow type="math_number"><field name="NUM">2</field></shadow></value>' +
  1303. '</block>' +
  1304. ' <block type="parts_of_tuple2">' +
  1305. ' <value name="tuple_name"><shadow type="text_tuple"><field name="TEXT"></field></shadow></value>' +
  1306. ' <value name="start_item"><shadow type="math_number"><field name="NUM">0</field></shadow></value>' +
  1307. ' <value name="end_item"><shadow type="math_number"><field name="NUM">2</field></shadow></value>' +
  1308. '</block>' +
  1309. '<block type="list_to_tuple">' +
  1310. ' <value name="list_name"><shadow type="text_list"><field name="TEXT"></field></shadow></value>' +
  1311. '</block>' +
  1312. '</category>',
  1313. 'Set': '<category id="catSet" name="Set" colour="160">' +
  1314. '<block type="set_create_with_items_insert"></block>' +
  1315. ' <block type="text_set"><field name="TEXT">"string", 0.9, ("tuple",)</field></block>' +
  1316. ' <block type="set_create_with">' +
  1317. ' <value name="set_name"><block type="variables_get"><field name="VAR">my_set</field></block></value>' +
  1318. ' <value name="set_items"><shadow type="text_set"></shadow></value>' +
  1319. ' </block>' +
  1320. ' <block type="sets_update_ways">' +
  1321. ' <value name="set_name"><block type="variables_get"><field name="VAR">my_set</field></block></value>' +
  1322. ' <value name="set_1_name"><shadow type="text_set"></shadow></value>' +
  1323. ' </block>' +
  1324. ' <block type="set_update_with">' +
  1325. ' <value name="set_name"><shadow type="text_set"></shadow></value>' +
  1326. ' <value name="set_items"></value>' +
  1327. ' </block>' +
  1328. ' <block type="set_subset_superset">' +
  1329. ' <value name="set_name"><shadow type="text_set"></shadow></value>' +
  1330. ' <value name="set_1_name"><shadow type="text_set"></shadow></value>' +
  1331. ' </block>' +
  1332. ' <block type="intersection_of_sets">' +
  1333. ' <value name="set_name"><shadow type="text_set"></shadow></value>' +
  1334. ' <value name="set_1_name"><shadow type="text_set"></shadow></value>' +
  1335. ' </block>' +
  1336. ' <block type="len_of_sets">' +
  1337. ' <value name="set_name"><shadow type="text_set"></shadow></value>' +
  1338. '</block>' +
  1339. ' <block type="get_sets_pop">' +
  1340. ' <value name="set_name"><shadow type="text_set"></shadow></value>' +
  1341. '</block>' +
  1342. '</category>',
  1343. 'Functionsa': '<category id="catFunctions" name="Functions" custom="PROCEDURE" colour="#ff6381">' +
  1344. '</category>',
  1345. 'Python': '<category name="Python" colour="180">' +
  1346. '<block type="raw_block"></block>' +
  1347. '<block type="raw_expression"></block>' +
  1348. '</category>',
  1349. 'Output': '<category id="catOutput" name="Output" colour="#ff8b2c">' +
  1350. // '<block type="esp32_main_controller_io_from_digital_pin">' +
  1351. // ' <value name="digital_pin_input">' +
  1352. // '<shadow type="math_number">' +
  1353. // ' <field name="NUM">1</field>' +
  1354. // '</shadow>' +
  1355. // '</value>' +
  1356. // '</block>' +
  1357. // '<block type="esp32_main_controller_io_set_digital_pin">' +
  1358. // ' <value name="digital_pin_input">' +
  1359. // '<shadow type="math_number">' +
  1360. // ' <field name="NUM">1</field>' +
  1361. // '</shadow>' +
  1362. // '</value>' +
  1363. // ' <value name="high_low">' +
  1364. // '<shadow type="esp32_main_controller_io_high_low">' +
  1365. // '</shadow>' +
  1366. // '</value>' +
  1367. // '</block>' +
  1368. // '<block type="esp32_main_controller_io_set_analog_pin">' +
  1369. // ' <value name="analog_pin_input">' +
  1370. // '</value>' +
  1371. // ' <value name="pwm">' +
  1372. // '</value>' +
  1373. // '</block>' +
  1374. // // PWM ai
  1375. // '<block type="ai_main_controller_io_set_analog_pin">' +
  1376. // ' <value name="analog_pin_input">' +
  1377. // '</value>' +
  1378. // ' <value name="pwm">' +
  1379. // '</value>' +
  1380. // '</block>' +
  1381. // '<block type="esp32_main_controller_io_from_analog_pin">' +
  1382. // '</block>' +
  1383. // '<block type="esp32_main_controller_io_out_pwm"></block>' +
  1384. // '<block type="esp32_main_controller_io_high_low"></block>' +
  1385. // '<block type="esp32_main_controller_io_analog_pin_1"></block>' +
  1386. // '<block type="esp32_main_controller_io_analog_pin_2"></block>' +
  1387. '</category>',
  1388. 'Files': '<category id="catFiles" name="Files" colour="32">' +
  1389. '<block type="iot_system_run">' +
  1390. ' <value name="PATH">' +
  1391. ' <shadow type="text">' +
  1392. ' <field name="TEXT">/your_python_code.py</field>' +
  1393. ' </shadow>' +
  1394. ' </value>' +
  1395. '</block>' +
  1396. '<block type="iot_system_create_file">' +
  1397. ' <value name="filename">' +
  1398. ' <shadow type="text">' +
  1399. ' <field name="TEXT">cocorobo.txt</field>' +
  1400. ' </shadow>' +
  1401. ' </value>' +
  1402. ' <value name="PATH">' +
  1403. ' <shadow type="text">' +
  1404. ' <field name="TEXT">/</field>' +
  1405. ' </shadow>' +
  1406. ' </value>' +
  1407. '</block>' +
  1408. '<block type="iot_system_open_file">' +
  1409. ' <value name="filename">' +
  1410. ' <shadow type="text">' +
  1411. ' <field name="TEXT">cocorobo.txt</field>' +
  1412. ' </shadow>' +
  1413. ' </value>' +
  1414. ' <value name="PATH">' +
  1415. ' <shadow type="text">' +
  1416. ' <field name="TEXT">/</field>' +
  1417. ' </shadow>' +
  1418. ' </value>' +
  1419. '</block>' +
  1420. '<block type="iot_system_write_file">' +
  1421. ' <value name="WPATH">' +
  1422. ' <shadow type="text">' +
  1423. ' <field name="TEXT"></field>' +
  1424. ' </shadow>' +
  1425. ' </value>' +
  1426. '</block>' +
  1427. '<block type="iot_system_close_file"></block>' +
  1428. '<block type="iot_system_input_file">' +
  1429. ' <value name="filename">' +
  1430. ' <shadow type="text">' +
  1431. ' <field name="TEXT">cocorobo.txt</field>' +
  1432. ' </shadow>' +
  1433. ' </value>' +
  1434. ' <value name="PATH">' +
  1435. ' <shadow type="text">' +
  1436. ' <field name="TEXT">/</field>' +
  1437. ' </shadow>' +
  1438. ' </value>' + '</block>' +
  1439. '<block type="iot_system_delete_file">' +
  1440. ' <value name="PATH">' +
  1441. ' <shadow type="text">' +
  1442. ' <field name="TEXT">/cocorobo.txt</field>' +
  1443. ' </shadow>' +
  1444. ' </value>' +
  1445. '</block>' +
  1446. '</category>',
  1447. 'Time': '<category id="catTime" name="Time" colour="#fabe23">' +
  1448. ' <block type="time_delay">' +
  1449. ' <value name="DELAY_TIME_MILI">' +
  1450. ' <block type="math_number">' +
  1451. ' <field name="NUM">1000</field>' +
  1452. ' </block>' +
  1453. ' </value>' +
  1454. ' </block>' +
  1455. // ' <block type="time_delay">' +
  1456. // ' <value name="DELAY_TIME_MICRO">' +
  1457. // ' <block type="math_number">' +
  1458. // ' <field name="NUM">1000</field>' +
  1459. // ' </block>' +
  1460. // ' </value>' +
  1461. // ' </block>' +
  1462. ' <block type="time_delayseconds">' +
  1463. ' <value name="DELAY_TIME_MICRO">' +
  1464. ' <block type="math_number">' +
  1465. ' <field name="NUM">1</field>' +
  1466. ' </block>' +
  1467. ' </value>' +
  1468. ' </block>' +
  1469. // ' <block type="time_millis"></block>' +
  1470. // ' <block type="time_micros"></block>' +
  1471. ' <block type="esp32_get_current_date"></block>' +
  1472. ' <block type="esp32_main_controller_time_timer_init"></block>' +
  1473. ' <block type="esp32_main_controller_time_timer_get_current"></block>' +
  1474. ' <block type="esp32_main_controller_time_timer_clear"></block>' +
  1475. ' <block type="esp32_main_controller_time_period_timer"></block>' +
  1476. ' <block type="esp32_main_controller_time_period_timer_clear"></block>' +
  1477. '</category>',
  1478. 'Serial Comm.': '<category id="catSerialComm" name="SerialComm" colour="#22b845">' +
  1479. '<block type="serial_comm_print">' +
  1480. ' <value name="serial_comm_input">' +
  1481. ' <shadow type="text">' +
  1482. ' <field name="TEXT">Hello World!</field>' +
  1483. ' </shadow>' +
  1484. ' </value>' +
  1485. '</block>' +
  1486. '<block type="serial_write_data_coco">' +
  1487. ' <value name="ADD0">' +
  1488. ' <shadow type="text">' +
  1489. ' <field name="TEXT">Data</field>' +
  1490. ' </shadow>' +
  1491. ' </value>' +
  1492. '</block>' +
  1493. '<block type="serial_write_data">' +
  1494. ' <value name="ADD1">' +
  1495. ' <shadow type="text">' +
  1496. ' <field name="TEXT">Data</field>' +
  1497. ' </shadow>' +
  1498. ' </value>' +
  1499. '</block>' +
  1500. '<block type="serial_read_data_setup"></block>' +
  1501. '<block type="serial_read_data_setup_arduino"></block>' +
  1502. '<block type="serial_read_data_all"></block>' +
  1503. // '<block type="serial_read_data_all_usb"></block>' +
  1504. '<block type="serial_read_data"></block>' +
  1505. '<block type="serial_send_data_to_microbit">' +
  1506. ' <value name="NAME">' +
  1507. ' <shadow type="text">' +
  1508. ' <field name="TEXT">Data</field>' +
  1509. ' </shadow>' +
  1510. ' </value>' +
  1511. '</block>' +
  1512. '<block type="serial_send_data_to_control_panel">' +
  1513. ' <value name="NAME">' +
  1514. ' <shadow type="text">' +
  1515. ' <field name="TEXT">Data</field>' +
  1516. ' </shadow>' +
  1517. ' </value>' +
  1518. '</block>' +
  1519. '<block type="serial_send_data_to_arduino">' +
  1520. ' <value name="NAME">' +
  1521. ' <shadow type="text">' +
  1522. ' <field name="TEXT">Data</field>' +
  1523. ' </shadow>' +
  1524. ' </value>' +
  1525. '</block>' +
  1526. '</category>',
  1527. 'MainBoard':
  1528. '<category id="catMainBoard" name="Main Board" colour="#3163ed">' +
  1529. '<category id="catBasics" name="Basics" colour="#d42b03">' +
  1530. '</category>' +
  1531. '<category id="catMainWifi" name="Wi-Fi" colour="#386dc8">' +
  1532. '</category>' +
  1533. '<category id="catWeb" name="Web" colour="#183895">' +
  1534. '</category>' +
  1535. '<category id="catIoTService" name="IoT Service" colour="#3c7683">' +
  1536. '</category>' +
  1537. '</category>',
  1538. 'A.I.Board': '<category id="catAI" name="基础硬件" colour="#f76734">' +
  1539. /*
  1540. _ ___ ____ _
  1541. / \ |_ _| | __ ) __ _ ___(_) ___
  1542. / _ \ | | | _ \ / _` / __| |/ __|
  1543. / ___ \ | | | |_) | (_| \__ \ | (__
  1544. /_/ \_\___| |____/ \__,_|___/_|\___|
  1545. */
  1546. '<category id="catAIBasic" name="Basic" colour="#d42b03">' +//基础
  1547. '<label id="basis_button" text="Basis button" web-class="myLabelStyle" style="font-size:20px;"></label>' +
  1548. '<block type="ai_v831_button_read_pressed"></block>' +
  1549. '<block type="ai_v831_button_read_released"></block>' +
  1550. '<block type="ai_v831_button_loosen"></block>' +
  1551. // '<block type="ai_v831_button_del"></block>' +
  1552. '<label id="catFASTLED" text="灯光" web-class="myLabelStyle" style="font-size:20px;"></label>' +
  1553. '<block type="ai_v831_led_light_up"></block>' +
  1554. '<block type="ai_v831_led_light_off"></block>' +
  1555. // '<block type="ai_v831_button_read_released_to"></block>' +
  1556. '<label id="rgb_light" text="RGB灯光" web-class="myLabelStyle" style="font-size:20px;"></label>' +
  1557. '<block type="ai_v831_rgb_light_up">' +
  1558. ' <value name="rgb_value">' +
  1559. ' <block type="ai_lcd_rgb_value_input">' +
  1560. ' <value name="rgb_value_r">' +
  1561. ' <shadow type="math_number">' +
  1562. ' <field name="NUM">0</field>' +
  1563. ' </shadow>' +
  1564. ' </value>' +
  1565. ' <value name="rgb_value_g">' +
  1566. ' <shadow type="math_number">' +
  1567. ' <field name="NUM">0</field>' +
  1568. ' </shadow>' +
  1569. ' </value>' +
  1570. ' <value name="rgb_value_b">' +
  1571. ' <shadow type="math_number">' +
  1572. ' <field name="NUM">0</field>' +
  1573. ' </shadow>' +
  1574. ' </value>' +
  1575. ' </block>' +
  1576. ' </value>' +
  1577. '</block>' +
  1578. '<block type="ai_v831_rgb_light_off"></block>' +
  1579. '</category>' +
  1580. '<category id="catOutput" name="输入 / 输出" colour="#ff8b2c">' +
  1581. '<block type="esp32_main_controller_io_from_digital_pin">' +
  1582. '</block>' +
  1583. '<block type="esp32_main_controller_io_set_digital_pin">' +
  1584. ' <value name="digital_pin_input">' +
  1585. '<shadow type="math_number">' +
  1586. ' <field name="NUM">1</field>' +
  1587. '</shadow>' +
  1588. '</value>' +
  1589. ' <value name="high_low">' +
  1590. '<shadow type="esp32_main_controller_io_high_low">' +
  1591. '</shadow>' +
  1592. '</value>' +
  1593. '</block>' +
  1594. '<block type="esp32_main_controller_io_set_analog_pin">' +
  1595. ' <value name="analog_pin_input">' +
  1596. // '<shadow type="math_number">' +
  1597. // ' <field name="NUM">1</field>' +
  1598. // '</shadow>' +
  1599. ' <block type="esp32_main_controller_io_set_pin"></block>' +
  1600. '</value>' +
  1601. ' <value name="pwm">' +
  1602. '<shadow type="math_number">' +
  1603. ' <field name="NUM">1</field>' +
  1604. '</shadow>' +
  1605. '</value>' +
  1606. '</block>' +
  1607. // // PWM ai
  1608. // '<block type="ai_main_controller_io_set_analog_pin">' +
  1609. // ' <value name="analog_pin_input">' +
  1610. // '</value>' +
  1611. // ' <value name="pwm">' +
  1612. // '</value>' +
  1613. // '</block>' +
  1614. '<block type="esp32_main_controller_io_from_analog_pin">' +
  1615. '</block>' +
  1616. // '<block type="esp32_main_controller_io_out_pwm"></block>' +
  1617. // '<block type="esp32_main_controller_io_high_low"></block>' +
  1618. // '<block type="esp32_main_controller_io_analog_pin_1"></block>' +
  1619. // '<block type="esp32_main_controller_io_analog_pin_2"></block>' +
  1620. '</category>' +
  1621. /*
  1622. _ ___ __ __ _ _
  1623. / \ |_ _| | \/ (_) ___ _ __ ___ _ __ | |__ ___ _ __ ___
  1624. / _ \ | | | |\/| | |/ __| '__/ _ \| '_ \| '_ \ / _ \| '_ \ / _ \
  1625. / ___ \ | | | | | | | (__| | | (_) | |_) | | | | (_) | | | | __/
  1626. /_/ \_\___| |_| |_|_|\___|_| \___/| .__/|_| |_|\___/|_| |_|\___|
  1627. |_|
  1628. */
  1629. // 传感器
  1630. '<category id="catSensor" name="传感器" colour="#5fcd8e">' +
  1631. '<label id="basis_light" text="光照传感器" web-class="myLabelStyle" style="font-size:20px;"></label>' +
  1632. '<block type="esp32_main_controller_get_light"></block>' +
  1633. '<label id="basis_environmental" text="温湿度传感器" web-class="myLabelStyle" style="font-size:20px;"></label>' +
  1634. '<block type="esp32_main_controller_get_environmental_value"></block>' +
  1635. '<label id="" text="QMI8658" web-class="myLabelStyle" style="font-size:20px;"></label>' +
  1636. '<block type="esp32_main_controller_motion_acceleration"></block>' +
  1637. // '<block type="esp32_main_controller_motion_rotation_measurement"></block>' +
  1638. '<block type="esp32_main_controller_motion_tilt_angle"></block>' +
  1639. '<block type="esp32_main_controller_motion_when_tilting_STATEMENT"></block>' +
  1640. '</category>' +
  1641. '<category id="catPower" name="动力" colour="#386dc8">' +
  1642. '<label id="catServo" text="舵机" web-class="myLabelStyle" style="font-size:20px;"></label>' +
  1643. // '<block type="extension_servo_setup_on_ai"></block>' +
  1644. '<block type="extension_servo_write_on_ai">' +
  1645. ' <value name="degree">' +
  1646. ' <shadow type="math_number">' +
  1647. ' <field name="NUM">90</field>' +
  1648. ' </shadow>' +
  1649. ' </value>' +
  1650. '</block>' +
  1651. '<label id="catMOTOR" text="电机" web-class="myLabelStyle" style="font-size:20px;"></label>' +
  1652. // '<block type="ai_motor_setup"></block>' +
  1653. '<block type="ai_motor_run">' +
  1654. ' <value name="speed">' +
  1655. ' <shadow type="math_number">' +
  1656. ' <field name="NUM">150</field>' +
  1657. ' </shadow>' +
  1658. ' </value>' +
  1659. '</block>' +
  1660. '<block type="ai_motor_stop">' +
  1661. '</block>' +
  1662. '</category>' +
  1663. '<category id="catAIScreen" name="Screen" colour="#5cb2d6">' +
  1664. '<label id="basis_function" text="Basis function" web-class="myLabelStyle" style="font-size:20px;"></label>' +
  1665. '<block type="ai_lcd_screeninit"></block>' +
  1666. // '<block type="ai_lcd_rotation"></block>' +
  1667. // '<block type="ai_lcd_filp"></block>' +
  1668. // '<block type="ai_lcd_screen"></block>' +
  1669. // '<block type="ai_lcd_clear"></block>' +
  1670. // '<block type="ai_lcd_rgb_value_input">' +
  1671. // ' <value name="rgb_value_r">' +
  1672. // ' <shadow type="math_number">' +
  1673. // ' <field name="NUM">0</field>' +
  1674. // ' </shadow>' +
  1675. // ' </value>' +
  1676. // ' <value name="rgb_value_g">' +
  1677. // ' <shadow type="math_number">' +
  1678. // ' <field name="NUM">0</field>' +
  1679. // ' </shadow>' +
  1680. // ' </value>' +
  1681. // ' <value name="rgb_value_b">' +
  1682. // ' <shadow type="math_number">' +
  1683. // ' <field name="NUM">0</field>' +
  1684. // ' </shadow>' +
  1685. // ' </value>' +
  1686. // '</block>' +
  1687. // '<block type="ai_lcd_XY">' +
  1688. // ' <value name="A">' +
  1689. // ' <shadow type="math_number">' +
  1690. // ' <field name="NUM">0</field>' +
  1691. // ' </shadow>' +
  1692. // ' </value>' +
  1693. // ' <value name="B">' +
  1694. // ' <shadow type="math_number">' +
  1695. // ' <field name="NUM">0</field>' +
  1696. // ' </shadow>' +
  1697. // ' </value>' +
  1698. // '</block>' +
  1699. // ' <block type="lcd_set_width_height">' +
  1700. // ' <value name="WIDTH">' +
  1701. // ' <shadow type="math_number">' +
  1702. // ' <field name="NUM">320</field>' +
  1703. // ' </shadow>' +
  1704. // ' </value>' +
  1705. // ' <value name="HEIGHT">' +
  1706. // ' <shadow type="math_number">' +
  1707. // ' <field name="NUM">240</field>' +
  1708. // ' </shadow>' +
  1709. // ' </value>' +
  1710. // ' </block>' +
  1711. '<block type="ai_lcd_font">' +
  1712. ' <value name="save_path">' +
  1713. ' <shadow type="text">' +
  1714. ' <field name="TEXT">/root/preset/fonts/CascadiaCodePL-Italic.ttf</field>' +
  1715. ' </shadow>' +
  1716. ' </value>' +
  1717. '</block>' +
  1718. '<label id="basis_carvas_draw" text="Basis carvas drawing" web-class="myLabelStyle" style="font-size:20px;"></label>' +
  1719. '<block type="ai_lcd_showcarvas_set_cord">' +
  1720. ' <value name="xy">' +
  1721. ' <block type="lcd_set_position">' +
  1722. ' <value name="POSX">' +
  1723. ' <shadow type="math_number">' +
  1724. ' <field name="NUM">0</field>' +
  1725. ' </shadow>' +
  1726. ' </value>' +
  1727. ' <value name="POSY">' +
  1728. ' <shadow type="math_number">' +
  1729. ' <field name="NUM">0</field>' +
  1730. ' </shadow>' +
  1731. ' </value>' +
  1732. ' </block>' +
  1733. ' </value>' +
  1734. '</block>' +
  1735. // '<block type="ai_lcd_createnonecarvas">' +
  1736. // ' <value name="wh">' +
  1737. // ' <block type="lcd_set_width_height">' +
  1738. // ' <value name="WIDTH">' +
  1739. // ' <shadow type="math_number">' +
  1740. // ' <field name="NUM">320</field>' +
  1741. // ' </shadow>' +
  1742. // ' </value>' +
  1743. // ' <value name="HEIGHT">' +
  1744. // ' <shadow type="math_number">' +
  1745. // ' <field name="NUM">240</field>' +
  1746. // ' </shadow>' +
  1747. // ' </value>' +
  1748. // '</block>' +
  1749. // ' </value>' +
  1750. // '</block>' +
  1751. '<block type="ai_lcd_fill_screen_with_rgb">' +
  1752. ' <value name="rgb_value">' +
  1753. ' <block type="ai_lcd_rgb_value_input">' +
  1754. ' <value name="rgb_value_r">' +
  1755. ' <shadow type="math_number">' +
  1756. ' <field name="NUM">0</field>' +
  1757. ' </shadow>' +
  1758. ' </value>' +
  1759. ' <value name="rgb_value_g">' +
  1760. ' <shadow type="math_number">' +
  1761. ' <field name="NUM">0</field>' +
  1762. ' </shadow>' +
  1763. ' </value>' +
  1764. ' <value name="rgb_value_b">' +
  1765. ' <shadow type="math_number">' +
  1766. ' <field name="NUM">0</field>' +
  1767. ' </shadow>' +
  1768. ' </value>' +
  1769. ' </block>' +
  1770. ' </value>' +
  1771. '</block>' +
  1772. '<block type="ai_lcd_textcarvas">' +
  1773. ' <value name="POSA">' +
  1774. ' <block type="lcd_set_position">' +
  1775. ' <value name="POSX">' +
  1776. ' <shadow type="math_number">' +
  1777. ' <field name="NUM">0</field>' +
  1778. ' </shadow>' +
  1779. ' </value>' +
  1780. ' <value name="POSY">' +
  1781. ' <shadow type="math_number">' +
  1782. ' <field name="NUM">0</field>' +
  1783. ' </shadow>' +
  1784. ' </value>' +
  1785. ' </block>' +
  1786. ' </value>' +
  1787. ' <value name="CONTENT">' +
  1788. ' <shadow type="text">' +
  1789. ' <field name="TEXT"></field>' +
  1790. ' </shadow>' +
  1791. ' </value>' +
  1792. ' <value name="COLOR">' +
  1793. ' <block type="lcd_set_color">' +
  1794. ' </block>' +
  1795. ' </value>' +
  1796. ' <value name="Scale">' +
  1797. ' <shadow type="math_number">' +
  1798. ' <field name="NUM">1</field>' +
  1799. ' </shadow>' +
  1800. ' </value>' +
  1801. '</block>' +
  1802. '<block type="ai_lcd_textcarvas_new_line">' +
  1803. ' <value name="POSA">' +
  1804. ' <block type="lcd_set_position">' +
  1805. ' <value name="POSX">' +
  1806. ' <shadow type="math_number">' +
  1807. ' <field name="NUM">0</field>' +
  1808. ' </shadow>' +
  1809. ' </value>' +
  1810. ' <value name="POSY">' +
  1811. ' <shadow type="math_number">' +
  1812. ' <field name="NUM">0</field>' +
  1813. ' </shadow>' +
  1814. ' </value>' +
  1815. ' </block>' +
  1816. ' </value>' +
  1817. ' <value name="CONTENT">' +
  1818. ' <shadow type="text">' +
  1819. ' <field name="TEXT">假如我是一只鸟, 我也应该用嘶哑的喉咙歌唱: 这被暴风雨所打击着的土地, 这永远汹涌着我们的悲愤的河流, 这无止息地吹刮着的激怒的风, 和那来自林间的无比温柔的黎明…… ——然后我死了, 连羽毛也腐烂在土地里面。 为什么我的眼里常含泪水? 因为我对这土地爱得深沉……</field>' +
  1820. ' </shadow>' +
  1821. ' </value>' +
  1822. ' <value name="dispalyStr">' +
  1823. ' <shadow type="math_number">' +
  1824. ' <field name="NUM">20</field>' +
  1825. ' </shadow>' +
  1826. ' </value>' +
  1827. ' <value name="buttonUp">' +
  1828. ' <shadow type="text">' +
  1829. ' <field name="TEXT"></field>' +
  1830. ' </shadow>' +
  1831. ' <block type="ai_v831_button_read_pressed_canvas">' +
  1832. ' <field name="button_type">C</field>' +
  1833. ' </block>' +
  1834. ' </value>' +
  1835. ' <value name="buttonDown">' +
  1836. ' <shadow type="text">' +
  1837. ' <field name="TEXT"></field>' +
  1838. ' </shadow>' +
  1839. ' <block type="ai_v831_button_read_pressed_canvas">' +
  1840. ' <field name="button_type">D</field>' +
  1841. ' </block>' +
  1842. ' </value>' +
  1843. ' <value name="COLOR">' +
  1844. ' <block type="lcd_set_color">' +
  1845. ' </block>' +
  1846. ' </value>' +
  1847. ' <value name="Scale">' +
  1848. ' <shadow type="math_number">' +
  1849. ' <field name="NUM">1</field>' +
  1850. ' </shadow>' +
  1851. ' </value>' +
  1852. ' <value name="LineNum">' +
  1853. ' <shadow type="math_number">' +
  1854. ' <field name="NUM">20</field>' +
  1855. ' </shadow>' +
  1856. ' </value>' +
  1857. '</block>' +
  1858. ' <block type="ai_lcd_linecarvas">' +
  1859. ' <value name="POSA">' +
  1860. ' <block type="lcd_set_position">' +
  1861. ' <value name="POSX">' +
  1862. ' <shadow type="math_number">' +
  1863. ' <field name="NUM">0</field>' +
  1864. ' </shadow>' +
  1865. ' </value>' +
  1866. ' <value name="POSY">' +
  1867. ' <shadow type="math_number">' +
  1868. ' <field name="NUM">0</field>' +
  1869. ' </shadow>' +
  1870. ' </value>' +
  1871. ' </block>' +
  1872. ' </value>' +
  1873. ' <value name="POSB">' +
  1874. ' <block type="lcd_set_position">' +
  1875. ' <value name="POSX">' +
  1876. ' <shadow type="math_number">' +
  1877. ' <field name="NUM">0</field>' +
  1878. ' </shadow>' +
  1879. ' </value>' +
  1880. ' <value name="POSY">' +
  1881. ' <shadow type="math_number">' +
  1882. ' <field name="NUM">0</field>' +
  1883. ' </shadow>' +
  1884. ' </value>' +
  1885. ' </block>' +
  1886. ' </value>' +
  1887. ' <value name="COLOR">' +
  1888. ' <block type="lcd_set_color">' +
  1889. ' </block>' +
  1890. ' </value>' +
  1891. ' <value name="Scale">' +
  1892. ' <shadow type="math_number">' +
  1893. ' <field name="NUM">1</field>' +
  1894. ' </shadow>' +
  1895. ' </value>' +
  1896. ' </block>' +
  1897. ' <block type="ai_lcd_draw_rectangle">' +
  1898. ' <value name="POSA">' +
  1899. ' <block type="lcd_set_position">' +
  1900. ' <value name="POSX">' +
  1901. ' <shadow type="math_number">' +
  1902. ' <field name="NUM">0</field>' +
  1903. ' </shadow>' +
  1904. ' </value>' +
  1905. ' <value name="POSY">' +
  1906. ' <shadow type="math_number">' +
  1907. ' <field name="NUM">0</field>' +
  1908. ' </shadow>' +
  1909. ' </value>' +
  1910. ' </block>' +
  1911. ' </value>' +
  1912. ' <value name="POSB">' +
  1913. ' <block type="lcd_set_width_height">' +
  1914. ' <value name="WIDTH">' +
  1915. ' <shadow type="math_number">' +
  1916. ' <field name="NUM">320</field>' +
  1917. ' </shadow>' +
  1918. ' </value>' +
  1919. ' <value name="HEIGHT">' +
  1920. ' <shadow type="math_number">' +
  1921. ' <field name="NUM">240</field>' +
  1922. ' </shadow>' +
  1923. ' </value>' +
  1924. ' </block>' +
  1925. ' </value>' +
  1926. ' <value name="COLOR">' +
  1927. ' <block type="lcd_set_color">' +
  1928. ' </block>' +
  1929. ' </value>' +
  1930. ' <value name="Scale">' +
  1931. ' <shadow type="math_number">' +
  1932. ' <field name="NUM">1</field>' +
  1933. ' </shadow>' +
  1934. ' </value>' +
  1935. ' </block>' +
  1936. ' <block type="ai_lcd_drawcirclecarvas">' +
  1937. ' <value name="POSA">' +
  1938. ' <block type="lcd_set_position">' +
  1939. ' <value name="POSX">' +
  1940. ' <shadow type="math_number">' +
  1941. ' <field name="NUM">0</field>' +
  1942. ' </shadow>' +
  1943. ' </value>' +
  1944. ' <value name="POSY">' +
  1945. ' <shadow type="math_number">' +
  1946. ' <field name="NUM">0</field>' +
  1947. ' </shadow>' +
  1948. ' </value>' +
  1949. ' </block>' +
  1950. ' </value>' +
  1951. ' <value name="Scale">' +
  1952. ' <shadow type="math_number">' +
  1953. ' <field name="NUM">2</field>' +
  1954. ' </shadow>' +
  1955. ' </value>' +
  1956. ' <value name="COLOR">' +
  1957. ' <block type="lcd_set_color">' +
  1958. ' </block>' +
  1959. ' </value>' +
  1960. ' <value name="Scale_0">' +
  1961. ' <shadow type="math_number">' +
  1962. ' <field name="NUM">1</field>' +
  1963. ' </shadow>' +
  1964. ' </value>' +
  1965. ' </block>' +
  1966. ' <block type="ai_lcd_draw_image_on_canvas">' +
  1967. ' <value name="image_path">' +
  1968. ' <block type="v831_img_open">' +
  1969. ' <value name="save_path">' +
  1970. ' <shadow type="text">' +
  1971. ' <field name="TEXT">/root/preset/img/cocorobo_logo.jpg</field>' +
  1972. ' </shadow>' +
  1973. ' </value>' +
  1974. ' </block>' +
  1975. ' </value>' +
  1976. ' <value name="alpha">' +
  1977. ' <shadow type="math_number">' +
  1978. ' <field name="NUM">1</field>' +
  1979. ' </shadow>' +
  1980. ' </value>' +
  1981. ' <value name="scale_y">' +
  1982. ' <block type="lcd_set_position">' +
  1983. ' <value name="POSX">' +
  1984. ' <shadow type="math_number">' +
  1985. ' <field name="NUM">0</field>' +
  1986. ' </shadow>' +
  1987. ' </value>' +
  1988. ' <value name="POSY">' +
  1989. ' <shadow type="math_number">' +
  1990. ' <field name="NUM">0</field>' +
  1991. ' </shadow>' +
  1992. ' </value>' +
  1993. ' </block>' +
  1994. ' </value>' +
  1995. ' </block>' +
  1996. '<block type="ai_lcd_rotation"></block>' +
  1997. '<block type="ai_lcd_showcarvas_set_display">' +
  1998. '</block>' +
  1999. '<block type="ai_lcd_clearcanvas"></block>' +
  2000. '</category>' +
  2001. '<category id="catCamera" name="Camera" colour="#60c1bb">' +
  2002. // '<block type="ai_camera_init"></block>' +
  2003. '<block type="ai_camera_fit_to_screen_size"></block>' +
  2004. // '<block type="ai_camera_windows">' +
  2005. // '</block>' +
  2006. '<block type="ai_camera_snapshot"></block>' +
  2007. // '<block type="ai_model_class_start_load"></block>' +
  2008. '<block type="v831_camera_graph_transmission">' +
  2009. '</block>' +
  2010. '<block type="v831_camera_internet_transmission">' +
  2011. '</block>' +
  2012. // '<block type="ai_camera_vflip"></block>' +
  2013. // '<block type="ai_camera_hmirror"></block>' +
  2014. // '<block type="ai_camera_auto_whitebal">' +
  2015. // '</block>' +
  2016. // '<block type="ai_camera_auto_gain"></block>' +
  2017. // '<block type="ai_camera_auto_exposure"></block>' +
  2018. '</category>' +
  2019. '<category id="catMicrophone" name="Camera" colour="#5fcd8e">' +
  2020. '<label id="catMicrophone" text="麦克风" web-class="myLabelStyle" style="font-size:20px;"></label>' +
  2021. // '<block type="ai_mphone_record_init"></block>' +
  2022. '<block type="ai_mphone_record_setting">' +
  2023. ' <value name="path">' +
  2024. ' <shadow type="text">' +
  2025. ' <field name="TEXT">/root/user/audio/record.wav</field>' +
  2026. ' </shadow>' +
  2027. ' </value>' +
  2028. ' <value name="record_time">' +
  2029. ' <shadow type="math_number">' +
  2030. ' <field name="NUM">4</field>' +
  2031. ' </shadow>' +
  2032. ' </value>' +
  2033. '</block>' +
  2034. // '<block type="ai_mphone_Record_audio_start">' +
  2035. // '</block>' +
  2036. '</category>' +
  2037. '<category id="catAISpeaker" name="Camera" colour="#603ea0">' +
  2038. '<label id="catAISpeaker" text="扬声器" web-class="myLabelStyle" style="font-size:20px;"></label>' +
  2039. // '<block type="ai_audio_play_init"></block>' +
  2040. // '<block type="ai_audio_play_volume"></block>' +
  2041. '<block type="ai_audio_play_song" inline="false">' +
  2042. ' <value name="path">' +
  2043. ' <shadow type="text">' +
  2044. ' <field name="TEXT">/root/preset/audio/luckystar.wav</field>' +
  2045. ' </shadow>' +
  2046. ' </value>' +
  2047. '</block>' +
  2048. // '<block type="ai_audio_play_start"></block>' +
  2049. // '<block type="ai_audio_play_finish"></block>' +
  2050. // '<block type="ai_audio_get_play_status"></block>' +
  2051. '</category>' +
  2052. '<category id="catSystem" name="系統" colour="#22398e">' +
  2053. ' <block type="ai_system_off"></block>' +
  2054. ' <block type="ai_system_restart"></block>' +
  2055. ' <block type="ai_system_refresh"></block>' +
  2056. ' <block type="ai_system_volume"></block>' +
  2057. '<block type="ai_system_thread">' +
  2058. '<field name="thread">1</field>' +
  2059. '<value name="callBack">' +
  2060. ' <shadow type="math_number">' +
  2061. ' <field name="NUM">1</field>' +
  2062. ' </shadow>' +
  2063. ' <block type="procedures_callNothirdreturn">' +
  2064. ' <mutation name="做点什么">' +
  2065. ' <arg name="x"></arg>' +
  2066. ' </mutation>' +
  2067. ' <value name="ARG0">' +
  2068. ' <block type="text">' +
  2069. ' <field name="TEXT"></field>' +
  2070. ' </block>' +
  2071. ' </value>' +
  2072. ' </block>' +
  2073. '</value>' +
  2074. '<value name="ADD0">' +
  2075. ' <shadow type="math_number">' +
  2076. ' <field name="NUM">1</field>' +
  2077. ' </shadow>' +
  2078. '</value>' +
  2079. '</block>' +
  2080. '<block type="ai_system_thread_set_setDaemon"></block>' +
  2081. '<block type="ai_system_thread_set_join"></block>' +
  2082. ' <block type="ai_system_thread_start"></block>' +
  2083. ' <block type="ai_system_set_queue">' +
  2084. ' <value name="queueVaritem">' +
  2085. ' <shadow type="math_number">' +
  2086. ' <field name="NUM">""</field>' +
  2087. ' </shadow>' +
  2088. ' </value>' +
  2089. '</block>' +
  2090. ' <block type="ai_system_get_queue"></block>' +
  2091. '</category>' +
  2092. '</category>',
  2093. 'ExtendedFunctions':
  2094. '<category id="ExtendedFunction" name="媒体处理" colour="#2fc67b">' +
  2095. /*
  2096. _ ___ ____
  2097. / \ |_ _| / ___| ___ _ __ ___ ___ _ __
  2098. / _ \ | | \___ \ / __| '__/ _ \/ _ \ '_ \
  2099. / ___ \ _ | | _ ___) | (__| | | __/ __/ | | |
  2100. /_/ \_(_)___(_) |____/ \___|_| \___|\___|_| |_|
  2101. */
  2102. '<category id="catVision" name="Vision" colour="#f2a247">' +
  2103. '<label id="basis_function" text="Basis function" web-class="myLabelStyle" style="font-size:20px;"></label>' +
  2104. '<block type="v831_img_save">' +
  2105. ' <value name="save_path">' +
  2106. ' <shadow type="text">' +
  2107. ' <field name="TEXT">saved</field>' +
  2108. ' </shadow>' +
  2109. ' </value>' +
  2110. '</block>' +
  2111. '<block type="v831_img_text"><field name="TEXT">/root/user/img/</field></block>' +
  2112. '<block type="v831_img_open">' +
  2113. ' <value name="save_path">' +
  2114. ' <shadow type="text">' +
  2115. ' <field name="TEXT">/root/user/img/saved.jpg</field>' +
  2116. ' </shadow>' +
  2117. ' </value>' +
  2118. '</block>' +
  2119. '<block type="v831_lcd_invert"></block>' +
  2120. '<block type="v831_lcd_rotating">' +
  2121. ' <value name="spend">' +
  2122. ' <shadow type="math_number">' +
  2123. ' <field name="NUM">50</field>' +
  2124. ' </shadow>' +
  2125. ' </value>' +
  2126. '</block>' +
  2127. // '<block type="ai_lcd_invert_color"></block>' +
  2128. '<block type="v831_lcd_resizecanvas">' +
  2129. ' <value name="wh">' +
  2130. ' <block type="ai_lcd_WH_vision">' +
  2131. ' <value name="A">' +
  2132. ' <shadow type="math_number">' +
  2133. ' <field name="NUM">0</field>' +
  2134. ' </shadow>' +
  2135. ' </value>' +
  2136. ' <value name="B">' +
  2137. ' <shadow type="math_number">' +
  2138. ' <field name="NUM">0</field>' +
  2139. ' </shadow>' +
  2140. ' </value>' +
  2141. ' </block>' +
  2142. ' </value>' +
  2143. '</block>' +
  2144. // '<block type="ai_lcd_color_scheme"></block>' +
  2145. // '<block type="ai_lcd_ai_pix"></block>' +
  2146. '<block type="v831_lcd_img_cut">' +
  2147. ' <value name="xy">' +
  2148. ' <block type="ai_lcd_XY_vision">' +
  2149. ' <value name="A">' +
  2150. ' <shadow type="math_number">' +
  2151. ' <field name="NUM">0</field>' +
  2152. ' </shadow>' +
  2153. ' </value>' +
  2154. ' <value name="B">' +
  2155. ' <shadow type="math_number">' +
  2156. ' <field name="NUM">0</field>' +
  2157. ' </shadow>' +
  2158. ' </value>' +
  2159. ' </block>' +
  2160. ' </value>' +
  2161. ' <value name="wh">' +
  2162. ' <block type="ai_lcd_WH_vision">' +
  2163. ' <value name="A">' +
  2164. ' <shadow type="math_number">' +
  2165. ' <field name="NUM">0</field>' +
  2166. ' </shadow>' +
  2167. ' </value>' +
  2168. ' <value name="B">' +
  2169. ' <shadow type="math_number">' +
  2170. ' <field name="NUM">0</field>' +
  2171. ' </shadow>' +
  2172. ' </value>' +
  2173. ' </block>' +
  2174. ' </value>' +
  2175. '</block>' +
  2176. '<label id="advanced_function" text="进阶功能" web-class="myLabelStyle" style="font-size:20px;"></label>' +
  2177. '<block type="ai_vision_get_threshold_default"></block>' +
  2178. '<block type="ai_lane_tracking_run">' +
  2179. ' <value name="rgb_value">' +
  2180. ' <block type="ai_lcd_rgb_value_input">' +
  2181. ' <value name="rgb_value_r">' +
  2182. ' <shadow type="math_number">' +
  2183. ' <field name="NUM">0</field>' +
  2184. ' </shadow>' +
  2185. ' </value>' +
  2186. ' <value name="rgb_value_g">' +
  2187. ' <shadow type="math_number">' +
  2188. ' <field name="NUM">0</field>' +
  2189. ' </shadow>' +
  2190. ' </value>' +
  2191. ' <value name="rgb_value_b">' +
  2192. ' <shadow type="math_number">' +
  2193. ' <field name="NUM">0</field>' +
  2194. ' </shadow>' +
  2195. ' </value>' +
  2196. ' </block>' +
  2197. ' </value>' +
  2198. '</block>' +
  2199. // '<block type="ai_vision_find_rects">' +
  2200. // ' <value name="xy">' +
  2201. // ' <block type="ai_lcd_XY_vision">' +
  2202. // ' <value name="A">' +
  2203. // ' <shadow type="math_number">' +
  2204. // ' <field name="NUM">0</field>' +
  2205. // ' </shadow>' +
  2206. // ' </value>' +
  2207. // ' <value name="B">' +
  2208. // ' <shadow type="math_number">' +
  2209. // ' <field name="NUM">0</field>' +
  2210. // ' </shadow>' +
  2211. // ' </value>' +
  2212. // ' </block>' +
  2213. // ' </value>' +
  2214. // ' <value name="wh">' +
  2215. // ' <block type="ai_lcd_WH_vision">' +
  2216. // ' <value name="A">' +
  2217. // ' <shadow type="math_number">' +
  2218. // ' <field name="NUM">0</field>' +
  2219. // ' </shadow>' +
  2220. // ' </value>' +
  2221. // ' <value name="B">' +
  2222. // ' <shadow type="math_number">' +
  2223. // ' <field name="NUM">0</field>' +
  2224. // ' </shadow>' +
  2225. // ' </value>' +
  2226. // ' </block>' +
  2227. // ' </value>' +
  2228. // '</block>' +
  2229. '<block type="ai_vision_find_lines">' +
  2230. ' <value name="color">' +
  2231. ' <block type="ai_vision_get_threshold_default">' +
  2232. ' </block>' +
  2233. ' </value>' +
  2234. ' <value name="xy">' +
  2235. ' <block type="ai_lcd_XY_vision">' +
  2236. ' <value name="A">' +
  2237. ' <shadow type="math_number">' +
  2238. ' <field name="NUM">0</field>' +
  2239. ' </shadow>' +
  2240. ' </value>' +
  2241. ' <value name="B">' +
  2242. ' <shadow type="math_number">' +
  2243. ' <field name="NUM">0</field>' +
  2244. ' </shadow>' +
  2245. ' </value>' +
  2246. ' </block>' +
  2247. ' </value>' +
  2248. ' <value name="wh">' +
  2249. ' <block type="ai_lcd_WH_vision">' +
  2250. ' <value name="A">' +
  2251. ' <shadow type="math_number">' +
  2252. ' <field name="NUM">0</field>' +
  2253. ' </shadow>' +
  2254. ' </value>' +
  2255. ' <value name="B">' +
  2256. ' <shadow type="math_number">' +
  2257. ' <field name="NUM">0</field>' +
  2258. ' </shadow>' +
  2259. ' </value>' +
  2260. ' </block>' +
  2261. ' </value>' +
  2262. ' <value name="area_threshold">' +
  2263. ' <shadow type="math_number">' +
  2264. ' <field name="NUM">10</field>' +
  2265. ' </shadow>' +
  2266. ' </value>' +
  2267. ' <value name="pixels_threshold">' +
  2268. ' <shadow type="math_number">' +
  2269. ' <field name="NUM">10</field>' +
  2270. ' </shadow>' +
  2271. ' </value>' +
  2272. ' <value name="margin">' +
  2273. ' <shadow type="math_number">' +
  2274. ' <field name="NUM">10</field>' +
  2275. ' </shadow>' +
  2276. ' </value>' +
  2277. '</block>' +
  2278. '<block type="ai_vision_get_blobs"></block>' +
  2279. '<block type="ai_vision_find_blobs">' +
  2280. ' <value name="color">' +
  2281. ' <block type="ai_vision_get_threshold_default">' +
  2282. ' </block>' +
  2283. ' </value>' +
  2284. ' <value name="xy">' +
  2285. ' <block type="ai_lcd_XY_vision">' +
  2286. ' <value name="A">' +
  2287. ' <shadow type="math_number">' +
  2288. ' <field name="NUM">0</field>' +
  2289. ' </shadow>' +
  2290. ' </value>' +
  2291. ' <value name="B">' +
  2292. ' <shadow type="math_number">' +
  2293. ' <field name="NUM">0</field>' +
  2294. ' </shadow>' +
  2295. ' </value>' +
  2296. ' </block>' +
  2297. ' </value>' +
  2298. ' <value name="wh">' +
  2299. ' <block type="ai_lcd_WH_vision">' +
  2300. ' <value name="A">' +
  2301. ' <shadow type="math_number">' +
  2302. ' <field name="NUM">0</field>' +
  2303. ' </shadow>' +
  2304. ' </value>' +
  2305. ' <value name="B">' +
  2306. ' <shadow type="math_number">' +
  2307. ' <field name="NUM">0</field>' +
  2308. ' </shadow>' +
  2309. ' </value>' +
  2310. ' </block>' +
  2311. ' </value>' +
  2312. ' <value name="area_threshold">' +
  2313. ' <shadow type="math_number">' +
  2314. ' <field name="NUM">10</field>' +
  2315. ' </shadow>' +
  2316. ' </value>' +
  2317. ' <value name="pixels_threshold">' +
  2318. ' <shadow type="math_number">' +
  2319. ' <field name="NUM">10</field>' +
  2320. ' </shadow>' +
  2321. ' </value>' +
  2322. ' <value name="margin">' +
  2323. ' <shadow type="math_number">' +
  2324. ' <field name="NUM">10</field>' +
  2325. ' </shadow>' +
  2326. ' </value>' +
  2327. '</block>' +
  2328. '<block type="ai_vision_find_blobs_result"></block>' +
  2329. '<block type="ai_lane_tracking_setup">' +
  2330. ' <value name="color">' +
  2331. ' <block type="ai_vision_get_threshold_default">' +
  2332. ' </block>' +
  2333. ' </value>' +
  2334. ' <value name="lsize">' +
  2335. '<block type="ai_canvas_area_tuple">' +
  2336. ' <value name="xy">' +
  2337. ' <block type="ai_lcd_XY_vision">' +
  2338. ' <value name="A">' +
  2339. ' <shadow type="math_number">' +
  2340. ' <field name="NUM">0</field>' +
  2341. ' </shadow>' +
  2342. ' </value>' +
  2343. ' <value name="B">' +
  2344. ' <shadow type="math_number">' +
  2345. ' <field name="NUM">140</field>' +
  2346. ' </shadow>' +
  2347. ' </value>' +
  2348. ' </block>' +
  2349. ' </value>' +
  2350. ' <value name="wh">' +
  2351. ' <block type="ai_lcd_WH_vision">' +
  2352. ' <value name="A">' +
  2353. ' <shadow type="math_number">' +
  2354. ' <field name="NUM">100</field>' +
  2355. ' </shadow>' +
  2356. ' </value>' +
  2357. ' <value name="B">' +
  2358. ' <shadow type="math_number">' +
  2359. ' <field name="NUM">240</field>' +
  2360. ' </shadow>' +
  2361. ' </value>' +
  2362. ' </block>' +
  2363. ' </value>' +
  2364. '</block>' +
  2365. ' </value>' +
  2366. ' <value name="rsize">' +
  2367. '<block type="ai_canvas_area_tuple">' +
  2368. ' <value name="xy">' +
  2369. ' <block type="ai_lcd_XY_vision">' +
  2370. ' <value name="A">' +
  2371. ' <shadow type="math_number">' +
  2372. ' <field name="NUM">220</field>' +
  2373. ' </shadow>' +
  2374. ' </value>' +
  2375. ' <value name="B">' +
  2376. ' <shadow type="math_number">' +
  2377. ' <field name="NUM">140</field>' +
  2378. ' </shadow>' +
  2379. ' </value>' +
  2380. ' </block>' +
  2381. ' </value>' +
  2382. ' <value name="wh">' +
  2383. ' <block type="ai_lcd_WH_vision">' +
  2384. ' <value name="A">' +
  2385. ' <shadow type="math_number">' +
  2386. ' <field name="NUM">320</field>' +
  2387. ' </shadow>' +
  2388. ' </value>' +
  2389. ' <value name="B">' +
  2390. ' <shadow type="math_number">' +
  2391. ' <field name="NUM">240</field>' +
  2392. ' </shadow>' +
  2393. ' </value>' +
  2394. ' </block>' +
  2395. ' </value>' +
  2396. '</block>' +
  2397. ' </value>' +
  2398. ' <value name="axis">' +
  2399. ' <block type="math_number"><field name="NUM">112</field></block>' +
  2400. ' </value>' +
  2401. '</block>' +
  2402. '<block type="ai_vision_color_analyze">' +
  2403. ' <value name="xy">' +
  2404. ' <block type="ai_lcd_XY_vision">' +
  2405. ' <value name="A">' +
  2406. ' <shadow type="math_number">' +
  2407. ' <field name="NUM">0</field>' +
  2408. ' </shadow>' +
  2409. ' </value>' +
  2410. ' <value name="B">' +
  2411. ' <shadow type="math_number">' +
  2412. ' <field name="NUM">0</field>' +
  2413. ' </shadow>' +
  2414. ' </value>' +
  2415. ' </block>' +
  2416. ' </value>' +
  2417. ' <value name="wh">' +
  2418. ' <block type="ai_lcd_WH_vision">' +
  2419. ' <value name="A">' +
  2420. ' <shadow type="math_number">' +
  2421. ' <field name="NUM">0</field>' +
  2422. ' </shadow>' +
  2423. ' </value>' +
  2424. ' <value name="B">' +
  2425. ' <shadow type="math_number">' +
  2426. ' <field name="NUM">0</field>' +
  2427. ' </shadow>' +
  2428. ' </value>' +
  2429. ' </block>' +
  2430. ' </value>' +
  2431. '</block>' +
  2432. '<label id="graphics_decoding" text="Graphics decoding" web-class="myLabelStyle" style="font-size:20px;"></label>' +
  2433. '<block type="ai_vision_find_qrcode"></block>' +
  2434. '<block type="ai_vision_find_qrcode_result"></block>' +
  2435. '<block type="ai_vision_qrcode_get_info"></block>' +
  2436. '<block type="ai_vision_find_apriltag"></block>' +
  2437. '<block type="ai_vision_apriltag_get_info"></block>' +
  2438. '<block type="ai_vision_find_datamatrices"></block>' +
  2439. // '<block type="ai_vision_datamatrices_get_info"></block>' +
  2440. '<block type="ai_vision_find_barcodes"></block>' +
  2441. '<block type="ai_vision_barcodes_get_info"></block>' +
  2442. '<block type="ai_vision_barcodes_get_info_result"></block>' +
  2443. '</category>' +
  2444. /*
  2445. _ ___ __ ___ _
  2446. / \ |_ _| \ \ / (_) __| | ___ ___
  2447. / _ \ | | \ \ / /| |/ _` |/ _ \/ _ \
  2448. / ___ \ | | \ V / | | (_| | __/ (_) |
  2449. /_/ \_\___| \_/ |_|\__,_|\___|\___/
  2450. */
  2451. '<category id="catIV" name="Video" colour="#4d9994">' +
  2452. '<block type="ai_video_set_init"></block>' +
  2453. '<block type="ai_video_set">' +
  2454. ' <value name="path">' +
  2455. ' <shadow type="text">' +
  2456. ' <field name="TEXT">/root/user/video/record.mp4</field>' +
  2457. ' </shadow>' +
  2458. ' </value>' +
  2459. '</block>' +
  2460. '<block type="ai_video_set_play"></block>' +
  2461. '<block type="ai_video_set_stats"></block>' +
  2462. '<block type="ai_video_stop_play"></block>' +
  2463. '<block type="ai_video_record_init">' +
  2464. ' <value name="save_path">' +
  2465. ' <shadow type="text">' +
  2466. ' <field name="TEXT">/root/user/video/record.mp4</field>' +
  2467. ' </shadow>' +
  2468. ' </value>' +
  2469. ' <value name="w">' +
  2470. ' <shadow type="math_number">' +
  2471. ' <field name="NUM">320</field>' +
  2472. ' </shadow>' +
  2473. ' </value>' +
  2474. ' <value name="h">' +
  2475. ' <shadow type="math_number">' +
  2476. ' <field name="NUM">240</field>' +
  2477. ' </shadow>' +
  2478. ' </value>' +
  2479. '</block>' +
  2480. '<block type="ai_video_record_get"></block>' +
  2481. '<block type="ai_video_record_stop"></block>' +
  2482. '</category>' +
  2483. '</category>',
  2484. 'AI':
  2485. '<category id="AI" name="人工智能" colour="#ee783a">' +
  2486. '<category id="catModels" name="Models" colour="#ee783a">' +//模型
  2487. '<label id="edge_detection" text="边缘检测" web-class="myLabelStyle" style="font-size:20px;"></label>' +
  2488. // '<block type="ai_model_edge_init"></block>' +
  2489. '<block type="ai_model_edge_loading"></block>' +
  2490. '<block type="ai_model_edge_result"></block>' +
  2491. '<label id="basis_number_recognition" text="Basis number recognition" web-class="myLabelStyle" style="font-size:20px;"></label>' +
  2492. // '<block type="ai_model_digital_init"></block>' +
  2493. '<block type="ai_model_digital_init_loding"></block>' +
  2494. // '<block type="ai_model_digital_attribute"></block>' +
  2495. '<block type="ai_model_digital"></block>' +
  2496. '<block type="ai_model_digital_new"></block>' +
  2497. '<block type="ai_model_digital_result"></block>' +
  2498. '<label id="basis_object_recognition" text="Basis object recognition" web-class="myLabelStyle" style="font-size:20px;"></label>' +
  2499. // '<block type="ai_model_object_init">' +
  2500. // '</block>' +
  2501. '<block type="ai_model_object_load"></block>' +
  2502. '<block type="ai_model_look_attribute"></block>' +
  2503. // '<block type="ai_model_look"></block>' +
  2504. '<block type="ai_model_look_new"></block>' +
  2505. '<block type="ai_model_get"></block>' +
  2506. '<label id="Guesswork_recognition" text="猜拳识别" web-class="myLabelStyle" style="font-size:20px;"></label>' +
  2507. // '<block type="ai_model_Guesswork_init">' +
  2508. // '</block>' +
  2509. '<block type="ai_model_Guesswork_load"></block>' +
  2510. '<block type="ai_model_Guesswork_look"></block>' +
  2511. '<block type="ai_model_Guesswork_look_new"></block>' +
  2512. '<block type="ai_model_Guesswork_get"></block>' +
  2513. // '<block type="ai_model_Guesswork_look_attribute"></block>' +
  2514. '<label id="basis_face_recognition" text="Basis face recognition" web-class="myLabelStyle" style="font-size:20px;"></label>' +
  2515. // '<block type="ai_model_face_recognition_init"></block>' +
  2516. '<block type="ai_model_face_recognition_load"></block>' +
  2517. '<block type="ai_model_face"></block>' +
  2518. '<block type="ai_model_face_new"></block>' +
  2519. '<block type="ai_model_xy"></block>' +
  2520. // '<block type="ai_model_face_attribute"></block>' +
  2521. // 车牌识别
  2522. '<label id="basis_card_recognition" text="车牌识别" web-class="myLabelStyle" style="font-size:20px;"></label>' +
  2523. // '<block type="ai_model_card_recognition_init"></block>' +
  2524. '<block type="ai_model_card_recognition_load"></block>' +
  2525. '<block type="ai_model_card_xy"></block>' +
  2526. '<block type="ai_model_card_xy_new"></block>' +
  2527. '<block type="ai_model_card_get"></block>' +
  2528. // '<block type="ai_model_card_result"></block>' +
  2529. '<label id="basis_face_recognition_1" text="人脸识别" web-class="myLabelStyle" style="font-size:20px;"></label>' +
  2530. '<block type="face_recognition_load">' +
  2531. ' <value name="class_input">' +
  2532. ' <block type="lists_create_with">' +
  2533. ' <value name="ADD0">' +
  2534. ' <block type="text"><field name="TEXT">Name1</field></block>' +
  2535. ' </value>' +
  2536. ' <value name="ADD1">' +
  2537. ' <block type="text"><field name="TEXT">Name2</field></block>' +
  2538. ' </value>' +
  2539. ' <value name="ADD2">' +
  2540. ' <block type="text"><field name="TEXT">Name3</field></block>' +
  2541. ' </value>' +
  2542. ' </block>' +
  2543. ' </value>' +
  2544. '</block>' +
  2545. '<block type="face_recognition_if_face"></block>' +
  2546. '<block type="face_recognition_if_face_new"></block>' +
  2547. '<block type="face_recognition_detection_rectangle"></block>' +
  2548. // '<block type="face_recognition_map_face"></block>' +
  2549. // '<block type="face_recognition_face_result"></block>' +
  2550. '<block type="face_recognition_add"></block>' +
  2551. '<block type="face_recognition_remove"></block>' +
  2552. '<block type="face_recognition_data_load">' +
  2553. ' <value name="class_input">' +
  2554. ' <block type="text"><field name="TEXT">/root/user/model/recorded_face_features.py</field></block>' +
  2555. ' </value>' +
  2556. '</block>' +
  2557. // '<block type="face_recognition_data_results"></block>' +
  2558. // '<block type="ai_model_self_learning_result"></block>' +
  2559. '<label id="self_learning" text="自我学习" web-class="myLabelStyle" style="font-size:20px;"></label>' +
  2560. // '<block type="ai_model_self_learning_init">' +
  2561. // ' <value name="class_input">' +
  2562. // ' <block type="lists_create_with">' +
  2563. // ' <value name="ADD0">' +
  2564. // ' <block type="text"><field name="TEXT">Object 1 Name</field></block>' +
  2565. // ' </value>' +
  2566. // ' <value name="ADD1">' +
  2567. // ' <block type="text"><field name="TEXT">Object 2 Name</field></block>' +
  2568. // ' </value>' +
  2569. // ' <value name="ADD2">' +
  2570. // ' <block type="text"><field name="TEXT">Object 3 Name</field></block>' +
  2571. // ' </value>' +
  2572. // ' </block>' +
  2573. // ' </value>' +
  2574. // '</block>' +
  2575. '<block type="ai_model_self_learning_load">' +
  2576. ' <value name="class_input">' +
  2577. ' <block type="lists_create_with">' +
  2578. ' <value name="ADD0">' +
  2579. ' <block type="text"><field name="TEXT">Object 1 Name</field></block>' +
  2580. ' </value>' +
  2581. ' <value name="ADD1">' +
  2582. ' <block type="text"><field name="TEXT">Object 2 Name</field></block>' +
  2583. ' </value>' +
  2584. ' <value name="ADD2">' +
  2585. ' <block type="text"><field name="TEXT">Object 3 Name</field></block>' +
  2586. ' </value>' +
  2587. ' </block>' +
  2588. ' </value>' +
  2589. '</block>' +
  2590. '<block type="ai_model_self_learning_recognize_load">' +
  2591. ' <value name="class_input">' +
  2592. ' <block type="lists_create_with">' +
  2593. ' <value name="ADD0">' +
  2594. ' <block type="text"><field name="TEXT">Object 1 Name</field></block>' +
  2595. ' </value>' +
  2596. ' <value name="ADD1">' +
  2597. ' <block type="text"><field name="TEXT">Object 2 Name</field></block>' +
  2598. ' </value>' +
  2599. ' <value name="ADD2">' +
  2600. ' <block type="text"><field name="TEXT">Object 3 Name</field></block>' +
  2601. ' </value>' +
  2602. ' </block>' +
  2603. ' </value>' +
  2604. '</block>' +
  2605. '<block type="ai_model_self_learning_add_class"></block>' +
  2606. // '<block type="ai_model_self_learning_make_data_set"></block>' +
  2607. '<block type="ai_model_self_learning_picture"></block>' +
  2608. // '<block type="ai_model_self_learning_save_modal"></block>' +
  2609. '<block type="ai_model_self_learning_class_verification"></block>' +
  2610. '<block type="ai_model_self_learning_result"></block>' +
  2611. // '<block type="ai_model_card_attribute_new"></block>' +
  2612. '<label id="basis_model_recognition" text="Basis model recognition" web-class="myLabelStyle" style="font-size:20px;"></label>' +
  2613. // '<block type="ai_model_customized_init_setup_definition"></block>' +
  2614. // '<block type="ai_model_customized_init_setup">' +
  2615. // ' <value name="class_input">' +
  2616. // ' <block type="lists_create_with">' +
  2617. // ' <value name="ADD0">' +
  2618. // ' <block type="text"><field name="TEXT">Object 1 Name</field></block>' +
  2619. // ' </value>' +
  2620. // ' <value name="ADD1">' +
  2621. // ' <block type="text"><field name="TEXT">Object 2 Name</field></block>' +
  2622. // ' </value>' +
  2623. // ' <value name="ADD2">' +
  2624. // ' <block type="text"><field name="TEXT">Object 3 Name</field></block>' +
  2625. // ' </value>' +
  2626. // ' </block>' +
  2627. // ' </value>' +
  2628. // '</block>' +
  2629. '<block type="ai_model_customized_load_setup">' +
  2630. ' <value name="class_input">' +
  2631. ' <block type="lists_create_with">' +
  2632. ' <value name="ADD0">' +
  2633. ' <block type="text"><field name="TEXT">Object 1 Name</field></block>' +
  2634. ' </value>' +
  2635. ' <value name="ADD1">' +
  2636. ' <block type="text"><field name="TEXT">Object 2 Name</field></block>' +
  2637. ' </value>' +
  2638. ' <value name="ADD2">' +
  2639. ' <block type="text"><field name="TEXT">Object 3 Name</field></block>' +
  2640. ' </value>' +
  2641. ' </block>' +
  2642. ' </value>' +
  2643. '</block>' +
  2644. '<block type="ai_model_customized_if_got"></block>' +
  2645. '<block type="ai_model_customized_if_got_new"></block>' +
  2646. // '<block type="ai_model_customized_if_got"></block>' +
  2647. '<block type="ai_model_customized_get_result">' +
  2648. '</block>' +
  2649. // '<label id="basis_speech_recognition" text="Speech Recording Recognition" web-class="myLabelStyle" style="font-size:20px;"></label>' +
  2650. // '<block type="speech_recognition_new_setup"></block>' +
  2651. // '<block type="speech_recognition_record_start_result"></block>' +
  2652. // '<block type="speech_recognition_new_start_recognition"></block>' +
  2653. // '<block type="speech_recognition_new_recognition_get_any_result"></block>' +
  2654. // '<block type="speech_recognition_new_recognition_get_result"></block>' +
  2655. // yuyin zhuan pinyin blocks
  2656. '<label id="basis_speech_pinyin_recognition" text="Speech Phonetic Recognition" web-class="myLabelStyle" style="font-size:20px;"></label>' +
  2657. // '<block type="speech_recognition_phonetic_to_pinyin_setup"></block>' +
  2658. '<block type="speech_recognition_phonetic_to_pinyin_set_param">' +
  2659. ' <mutation items="3"></mutation>' +
  2660. ' <value name="PINYIN0">'+
  2661. ' <shadow type="math_number">'+
  2662. ' <field name="NUM">0</field>'+
  2663. ' </shadow>'+
  2664. ' <block type="set_pinyin_dict_create_with_items_insert">'+
  2665. ' <mutation items="2"></mutation>'+
  2666. ' <field name="KEY0">ni</field>'+
  2667. ' <field name="toneADD00">1</field>'+
  2668. ' <field name="KEY1">hao</field>'+
  2669. ' <field name="toneADD11">3</field>'+
  2670. ' </block>'+
  2671. ' </value>'+
  2672. ' <value name="PINYIN1">'+
  2673. ' <block type="set_pinyin_dict_create_with_items_insert">'+
  2674. ' <mutation items="2"></mutation>'+
  2675. ' <field name="KEY0">hao</field>'+
  2676. ' <field name="toneADD00">3</field>'+
  2677. ' <field name="KEY1">de</field>'+
  2678. ' <field name="toneADD11">1</field>'+
  2679. ' </block>'+
  2680. ' </value>'+
  2681. ' <value name="PINYIN2">'+
  2682. ' <block type="set_pinyin_dict_create_with_items_insert">'+
  2683. ' <mutation items="3"></mutation>'+
  2684. ' <field name="KEY0">wan</field>'+
  2685. ' <field name="toneADD00">1</field>'+
  2686. ' <field name="KEY1">shang</field>'+
  2687. ' <field name="toneADD11">4</field>'+
  2688. ' <field name="KEY2">hao</field>'+
  2689. ' <field name="toneADD22">3</field>'+
  2690. ' </block>'+
  2691. ' </value>' +
  2692. '</block>' +
  2693. '<block type="speech_recognition_set_pinyin_tone"></block>' +
  2694. '<block type="speech_recognition_phonetic_to_pinyin_start_recognition"></block>' +
  2695. '<block type="speech_recognition_phonetic_to_pinyin_stop_recognition"></block>' +
  2696. '<block type="speech_recognition_phonetic_to_pinyin_pause_recognition"></block>' +
  2697. '<block type="speech_recognition_phonetic_to_pinyin_get_result"></block>' +
  2698. '<label id="" text="Numpy 神经网络" web-class="myLabelStyle" style="font-size:20px;"></label>' +
  2699. '<block type="Numpy_Neural_Network_init">' +
  2700. '</block>' +
  2701. '<block type="Numpy_Neural_Network_load">' +
  2702. '</block>' +
  2703. '<block type="Numpy_Neural_Network_LOading_test_train">' +
  2704. ' <value name="class_input">' +
  2705. ' <block type="text"><field name="TEXT">/root/preset/training/res/mnist_train_100.csv</field></block>' +
  2706. ' </value>' +
  2707. ' <value name="class_input1">' +
  2708. ' <block type="text"><field name="TEXT">/root/preset/training/res/mnist_test_10.csv</field></block>' +
  2709. ' </value>' +
  2710. '</block>' +
  2711. '<block type="Numpy_Neural_Network_numpy_isStart">' +
  2712. '</block>' +
  2713. '<block type="Numpy_Neural_Network_setting_training_argument">' +
  2714. ' <value name="class_input">' +
  2715. ' <block type="text"><field name="TEXT">784</field></block>' +
  2716. ' </value>' +
  2717. ' <value name="class_input1">' +
  2718. ' <block type="text"><field name="TEXT">128</field></block>' +
  2719. ' </value>' +
  2720. ' <value name="class_input2">' +
  2721. ' <block type="text"><field name="TEXT">10</field></block>' +
  2722. ' </value>' +
  2723. ' <value name="class_input3">' +
  2724. ' <block type="text"><field name="TEXT">0.1</field></block>' +
  2725. ' </value>' +
  2726. ' <value name="class_input4">' +
  2727. ' <block type="text"><field name="TEXT">10</field></block>' +
  2728. ' </value>' +
  2729. ' <value name="class_input5">' +
  2730. ' <block type="text"><field name="TEXT">/root/user/model/NN.pkl</field></block>' +
  2731. ' </value>' +
  2732. '</block>' +
  2733. '<block type="Numpy_Neural_Network_numpy_loading_model">' +
  2734. ' <value name="class_input">' +
  2735. ' <block type="text"><field name="TEXT">/root/user/model/NN.pkl</field></block>' +
  2736. ' </value>' +
  2737. '</block>' +
  2738. '<block type="Numpy_Neural_Network_numpy_loading_model_fun">' +
  2739. '</block>' +
  2740. '<block type="Numpy_Neural_Network_numpy_loading_model_result">' +
  2741. '</block>' +
  2742. '<block type="Numpy_Neural_Network_numpy_clear">' +
  2743. '</block>' +
  2744. '</category>' +
  2745. // 讯飞在线识别
  2746. '<category id="OnlineIdentify" name="Motor" colour="#0000FF">' +
  2747. '<label id="online_face_recognition" text="在线人脸识别" web-class="myLabelStyle" style="font-size:20px;"></label>' +
  2748. // '<block type="ai_online_ident_init">' +
  2749. // ' <value name="A">' +
  2750. // ' <shadow type="text">' +
  2751. // ' <field name="TEXT">2a588b52</field>' +
  2752. // ' </shadow>' +
  2753. // ' </value>' +
  2754. // ' <value name="B">' +
  2755. // ' <shadow type="text">' +
  2756. // ' <field name="TEXT">MzQyZDE3MmQ1ZThhNjBiODI3ZDEzY2Nk</field>' +
  2757. // ' </shadow>' +
  2758. // ' </value>' +
  2759. // ' <value name="C">' +
  2760. // ' <shadow type="text">' +
  2761. // ' <field name="TEXT">a61f7532ed97cb4506752047c9221f6c</field>' +
  2762. // ' </shadow>' +
  2763. // ' </value>' +
  2764. // '</block>' +
  2765. '<block type="ai_online_ident_loading">' +
  2766. ' <value name="A">' +
  2767. ' <shadow type="text">' +
  2768. ' <field name="TEXT">2a588b52</field>' +
  2769. ' </shadow>' +
  2770. ' </value>' +
  2771. ' <value name="B">' +
  2772. ' <shadow type="text">' +
  2773. ' <field name="TEXT">MzQyZDE3MmQ1ZThhNjBiODI3ZDEzY2Nk</field>' +
  2774. ' </shadow>' +
  2775. ' </value>' +
  2776. ' <value name="C">' +
  2777. ' <shadow type="text">' +
  2778. ' <field name="TEXT">a61f7532ed97cb4506752047c9221f6c</field>' +
  2779. ' </shadow>' +
  2780. ' </value>' +
  2781. ' <value name="path">' +
  2782. ' <shadow type="text">' +
  2783. ' <field name="TEXT">/root/preset/img/cocorobo_logo.jpg</field>' +
  2784. ' </shadow>' +
  2785. ' </value>' +
  2786. '</block>' +
  2787. '<block type="ai_online_ident_result"></block>' +
  2788. '<block type="ai_online_ident_result_people"></block>' +
  2789. '<label id="online_text_to_voice" text="在线文本转语音" web-class="myLabelStyle" style="font-size:20px;"></label>' +
  2790. // '<block type="ai_audio_init">' +
  2791. // ' <value name="A">' +
  2792. // ' <shadow type="text">' +
  2793. // ' <field name="TEXT">2a588b52</field>' +
  2794. // ' </shadow>' +
  2795. // ' </value>' +
  2796. // ' <value name="B">' +
  2797. // ' <shadow type="text">' +
  2798. // ' <field name="TEXT">MzQyZDE3MmQ1ZThhNjBiODI3ZDEzY2Nk</field>' +
  2799. // ' </shadow>' +
  2800. // ' </value>' +
  2801. // ' <value name="C">' +
  2802. // ' <shadow type="text">' +
  2803. // ' <field name="TEXT">a61f7532ed97cb4506752047c9221f6c</field>' +
  2804. // ' </shadow>' +
  2805. // ' </value>' +
  2806. // '</block>' +
  2807. '<block type="ai_audio_play_state">' +
  2808. ' <value name="A">' +
  2809. ' <shadow type="text">' +
  2810. ' <field name="TEXT">2a588b52</field>' +
  2811. ' </shadow>' +
  2812. ' </value>' +
  2813. ' <value name="B">' +
  2814. ' <shadow type="text">' +
  2815. ' <field name="TEXT">MzQyZDE3MmQ1ZThhNjBiODI3ZDEzY2Nk</field>' +
  2816. ' </shadow>' +
  2817. ' </value>' +
  2818. ' <value name="C">' +
  2819. ' <shadow type="text">' +
  2820. ' <field name="TEXT">a61f7532ed97cb4506752047c9221f6c</field>' +
  2821. ' </shadow>' +
  2822. ' </value>' +
  2823. ' <value name="NAME">' +
  2824. ' <shadow type="text">' +
  2825. ' <field name="TEXT">hello world</field>' +
  2826. ' </shadow>' +
  2827. ' </value>' +
  2828. ' <value name="path">' +
  2829. ' <shadow type="text">' +
  2830. ' <field name="TEXT">/demo.pcm</field>' +
  2831. ' </shadow>' +
  2832. ' </value>' +
  2833. '</block>' +
  2834. '<label id="online_speech_recognition" text="在线语音识别" web-class="myLabelStyle" style="font-size:20px;"></label>' +
  2835. // '<block type="ai_online_voice_init">' +
  2836. // '</block>' +
  2837. '<block type="ai_online_voice_loading">' +
  2838. ' <value name="A">' +
  2839. ' <shadow type="text">' +
  2840. ' <field name="TEXT">2a588b52</field>' +
  2841. ' </shadow>' +
  2842. ' </value>' +
  2843. ' <value name="B">' +
  2844. ' <shadow type="text">' +
  2845. ' <field name="TEXT">MzQyZDE3MmQ1ZThhNjBiODI3ZDEzY2Nk</field>' +
  2846. ' </shadow>' +
  2847. ' </value>' +
  2848. ' <value name="C">' +
  2849. ' <shadow type="text">' +
  2850. ' <field name="TEXT">a61f7532ed97cb4506752047c9221f6c</field>' +
  2851. ' </shadow>' +
  2852. ' </value>' +
  2853. ' <value name="path">' +
  2854. ' <shadow type="text">' +
  2855. ' <field name="TEXT">/root/user/audio/record.wav</field>' +
  2856. ' </shadow>' +
  2857. ' </value>' +
  2858. '</block>' +
  2859. '<block type="ai_online_voice_result"></block>' +
  2860. '<label id="machine_translation" text="机器翻译" web-class="myLabelStyle" style="font-size:20px;"></label>' +
  2861. // '<block type="ai_online_machine_translation_init">' +
  2862. // '</block>' +
  2863. '<block type="ai_online_machine_translation_loading">' +
  2864. ' <value name="A">' +
  2865. ' <shadow type="text">' +
  2866. ' <field name="TEXT">8810558b</field>' +
  2867. ' </shadow>' +
  2868. ' </value>' +
  2869. ' <value name="B">' +
  2870. ' <shadow type="text">' +
  2871. ' <field name="TEXT">ZTIzYjM5NmIzMmRiZWNiMzk4MzkzZjk2</field>' +
  2872. ' </shadow>' +
  2873. ' </value>' +
  2874. ' <value name="C">' +
  2875. ' <shadow type="text">' +
  2876. ' <field name="TEXT">14975be8b286996b1f9002e81e0a4f3c</field>' +
  2877. ' </shadow>' +
  2878. ' </value>' +
  2879. ' <value name="NAME">' +
  2880. ' <shadow type="text">' +
  2881. ' <field name="TEXT">hello world</field>' +
  2882. ' </shadow>' +
  2883. ' </value>' +
  2884. '</block>' +
  2885. '<block type="ai_online_machine_translation_result"></block>' +
  2886. '<label id="handwritten_text" text="手写文字识别" web-class="myLabelStyle" style="font-size:20px;"></label>' +
  2887. // '<block type="ai_online_handwritten_text_init">' +
  2888. // ' <value name="A">' +
  2889. // ' <shadow type="text">' +
  2890. // ' <field name="TEXT">2a588b52</field>' +
  2891. // ' </shadow>' +
  2892. // ' </value>' +
  2893. // ' <value name="C">' +
  2894. // ' <shadow type="text">' +
  2895. // ' <field name="TEXT">a92e45658833435660a5b4eb16495bbf</field>' +
  2896. // ' </shadow>' +
  2897. // ' </value>' +
  2898. // '</block>' +
  2899. '<block type="ai_online_handwritten_text_loading">' +
  2900. ' <value name="A">' +
  2901. ' <shadow type="text">' +
  2902. ' <field name="TEXT">2a588b52</field>' +
  2903. ' </shadow>' +
  2904. ' </value>' +
  2905. ' <value name="C">' +
  2906. ' <shadow type="text">' +
  2907. ' <field name="TEXT">a92e45658833435660a5b4eb16495bbf</field>' +
  2908. ' </shadow>' +
  2909. ' </value>' +
  2910. ' <value name="path">' +
  2911. ' <shadow type="text">' +
  2912. ' <field name="TEXT">/root/preset/img/cocorobo_logo.jpg</field>' +
  2913. ' </shadow>' +
  2914. ' </value>' +
  2915. '</block>' +
  2916. '<block type="ai_online_handwritten_text_result"></block>' +
  2917. '<label id="formula" text="公式识别" web-class="myLabelStyle" style="font-size:20px;"></label>' +
  2918. // '<block type="ai_online_formula_init">' +
  2919. // '</block>' +
  2920. '<block type="ai_online_formula_loading">' +
  2921. ' <value name="A">' +
  2922. ' <shadow type="text">' +
  2923. ' <field name="TEXT">2a588b52</field>' +
  2924. ' </shadow>' +
  2925. ' </value>' +
  2926. ' <value name="B">' +
  2927. ' <shadow type="text">' +
  2928. ' <field name="TEXT">MzQyZDE3MmQ1ZThhNjBiODI3ZDEzY2Nk</field>' +
  2929. ' </shadow>' +
  2930. ' </value>' +
  2931. ' <value name="C">' +
  2932. ' <shadow type="text">' +
  2933. ' <field name="TEXT">a61f7532ed97cb4506752047c9221f6c</field>' +
  2934. ' </shadow>' +
  2935. ' </value>' +
  2936. ' <value name="path">' +
  2937. ' <shadow type="text">' +
  2938. ' <field name="TEXT">/root/preset/img/cocorobo_logo.jpg</field>' +
  2939. ' </shadow>' +
  2940. ' </value>' +
  2941. '</block>' +
  2942. '<block type="ai_online_formula_result"></block>' +
  2943. '<label id="AI_emotion" text="情绪识别" web-class="myLabelStyle" style="font-size:20px;"></label>' +
  2944. // '<block type="ai_online_emotion_init">' +
  2945. // '</block>' +
  2946. '<block type="ai_online_emotion_loading">' +
  2947. ' <value name="path">' +
  2948. ' <shadow type="text">' +
  2949. ' <field name="TEXT">/root/preset/img/cocorobo_logo.jpg</field>' +
  2950. ' </shadow>' +
  2951. ' </value>' +
  2952. '</block>' +
  2953. '<block type="ai_online_emotion_result"></block>' +
  2954. '<label id="gesturesTitle" text="手势识别" web-class="myLabelStyle" style="font-size:20px;"></label>' +
  2955. // '<block type="ai_online_gesture_init">' +
  2956. // '</block>' +
  2957. '<block type="ai_online_gesture_loading">' +
  2958. ' <value name="path">' +
  2959. ' <shadow type="text">' +
  2960. ' <field name="TEXT">/root/preset/img/cocorobo_logo.jpg</field>' +
  2961. ' </shadow>' +
  2962. ' </value>' +
  2963. '</block>' +
  2964. '<block type="ai_online_gesture_result"></block>' +
  2965. '</category>' +
  2966. '<category id="" name="AIGC" colour="#7e3cca">' +
  2967. // '<block type="cocopi_chatGpt_init">' +
  2968. // '</block>' +
  2969. // '<block type="cocopi_chatGpt_result"></block>' +
  2970. '<label id="text_to_img" text="文字转图片" web-class="myLabelStyle" style="font-size:20px;"></label>' +
  2971. '<block type="cocopi_chatGpt_text_to_img_loading">' +
  2972. ' <value name="NAME">' +
  2973. ' <shadow type="text">' +
  2974. ' <field name="TEXT">Smile</field>' +
  2975. ' </shadow>' +
  2976. ' </value>' +
  2977. '</block>' +
  2978. // '<block type="cocopi_chatGpt_text_to_img_result"></block>' +
  2979. '<label id="img_to_text" text="图片转文字" web-class="myLabelStyle" style="font-size:20px;"></label>' +
  2980. '<block type="cocopi_chatGpt_image_to_text_loading">' +
  2981. ' <value name="NAME">' +
  2982. ' <shadow type="text">' +
  2983. ' <field name="TEXT">/root/preset/img/face/face21.jpg</field>' +
  2984. ' </shadow>' +
  2985. ' </value>' +
  2986. ' <value name="NAME1">' +
  2987. ' <shadow type="text">' +
  2988. ' <field name="TEXT">图片什么内容</field>' +
  2989. ' </shadow>' +
  2990. ' </value>' +
  2991. '</block>' +
  2992. '<label id="text_to_voice" text="文字转语音" web-class="myLabelStyle" style="font-size:20px;"></label>' +
  2993. '<block type="cocopi_chatGpt_text_to_voice_loading">' +
  2994. ' <value name="NAME">' +
  2995. ' <shadow type="text">' +
  2996. ' <field name="TEXT">hello world</field>' +
  2997. ' </shadow>' +
  2998. ' </value>' +
  2999. '</block>' +
  3000. '<label id="voice_to_text" text="语音转文字" web-class="myLabelStyle" style="font-size:20px;"></label>' +
  3001. '<block type="cocopi_chatGpt_voice_to_text_loading">' +
  3002. ' <value name="NAME">' +
  3003. ' <shadow type="text">' +
  3004. ' <field name="TEXT">/root/user/audio/record.wav</field>' +
  3005. ' </shadow>' +
  3006. ' </value>' +
  3007. '</block>' +
  3008. // '<block type="cocopi_chatGpt_voice_to_text_result"></block>' +
  3009. '<label id="gpt_answer" text="文字对话" web-class="myLabelStyle" style="font-size:20px;"></label>' +
  3010. '<block type="cocopi_chatGpt_post_chatgpt_loading">' +
  3011. ' <value name="NAME">' +
  3012. ' <shadow type="text">' +
  3013. ' <field name="TEXT">who are you</field>' +
  3014. ' </shadow>' +
  3015. ' </value>' +
  3016. '</block>' +
  3017. '<label id="ai_agent_chat" text="AI 智能体" web-class="myLabelStyle" style="font-size:20px;"></label>' +
  3018. '<block type="cocopi_chatGpt_AI_loading">' +
  3019. ' <value name="NAME">' +
  3020. ' <shadow type="text">' +
  3021. ' <field name="TEXT">ENTER_YOUR_EVENT_API_KEY</field>' +
  3022. ' </shadow>' +
  3023. ' </value>' +
  3024. ' <value name="NAME1">' +
  3025. ' <shadow type="text">' +
  3026. ' <field name="TEXT">Problem</field>' +
  3027. ' </shadow>' +
  3028. ' </value>' +
  3029. '</block>' +
  3030. '<block type="cocopi_chatGpt_AI_loading_more">' +
  3031. ' <value name="NAME">' +
  3032. ' <shadow type="text">' +
  3033. ' <field name="TEXT">ENTER_YOUR_EVENT_API_KEY</field>' +
  3034. ' </shadow>' +
  3035. ' </value>' +
  3036. ' <value name="NAME1">' +
  3037. ' <shadow type="text">' +
  3038. ' <field name="TEXT">Problem</field>' +
  3039. ' </shadow>' +
  3040. ' </value>' +
  3041. '</block>' +
  3042. // '<block type="cocopi_chatGpt_post_chatgpt_result"></block>' +
  3043. '</category>' +
  3044. '</category>',
  3045. 'IOT':
  3046. '<category id="IOT" name="IOT" colour="#7e3cca">' +
  3047. '<category id="" name="Wi-Fi" colour="#3062c1">' +
  3048. '<block type="V831_code_scanning_network"></block>' +
  3049. '<block type="esp32_main_controller_wifi_connect_internet">' +
  3050. ' <value name="ssid">' +
  3051. ' <shadow type="text">' +
  3052. ' <field name="TEXT">ENTER_YOUR_SSID</field>' +
  3053. ' </shadow>' +
  3054. ' </value>' +
  3055. ' <value name="password">' +
  3056. ' <shadow type="text">' +
  3057. ' <field name="TEXT">ENTER_YOUR_PASSWORD</field>' +
  3058. ' </shadow>' +
  3059. ' </value>' +
  3060. '</block>' +
  3061. '<block type="esp32_main_controller_get_wifi_connection_status"></block>' +
  3062. '<block type="esp32_main_controller_wifi_get_info"></block>' +
  3063. '<block type="esp32_main_controller_wifi_disconnect"></block>' +
  3064. '<block type="esp32_main_controller_wifi_ntptime"></block>' +
  3065. '</category>' +
  3066. '<category id="" name="Web" colour="#3062c1">' +
  3067. '<label id="Get_weather" text="获取天气信息" web-class="myLabelStyle" style="font-size:20px;"></label>' +
  3068. '<block type="v831_get_weather_init"></block>' +
  3069. '<block type="v831_set_city_and_time"></block>' +
  3070. '<block type="v831_set_city_and_time_new"></block>' +
  3071. '<block type="v831_get_weather_result"></block>' +
  3072. '<label id="basis_ifttt" text="ifttt" web-class="myLabelStyle" style="font-size:20px;"></label>' +
  3073. '<block type="esp32_main_controller_ifttt_send_data">' +
  3074. ' <value name="ifttt_data_1">' +
  3075. ' <shadow type="math_number">' +
  3076. ' <field name="NUM">0</field>' +
  3077. ' </shadow>' +
  3078. ' </value>' +
  3079. ' <value name="ifttt_data_2">' +
  3080. ' <shadow type="math_number">' +
  3081. ' <field name="NUM">0</field>' +
  3082. ' </shadow>' +
  3083. ' </value>' +
  3084. ' <value name="ifttt_data_3">' +
  3085. ' <shadow type="math_number">' +
  3086. ' <field name="NUM">0</field>' +
  3087. ' </shadow>' +
  3088. ' </value>' +
  3089. '</block>' +
  3090. '<block type="esp32_main_controller_ifttt_touched"></block>' +
  3091. '<label id="basis_service_thingspeak" text="Basis service thingspeak" web-class="myLabelStyle" style="font-size:20px;"></label>' +
  3092. '<block type="iot_service_thingspeak">' +
  3093. ' <value name="ADD0">' +
  3094. ' <shadow type="math_number">' +
  3095. ' <field name="NUM">0</field>' +
  3096. ' </shadow>' +
  3097. ' </value>' +
  3098. '</block>' +
  3099. '<block type="iot_service_thingspeak_read"></block>' +
  3100. '<block type="iot_service_thingspeak_read_total"></block>' +
  3101. '<block type="iot_service_thingspeak_read_specific">' +
  3102. ' <value name="entry">' +
  3103. ' <shadow type="math_number">' +
  3104. ' <field name="NUM">1</field>' +
  3105. ' </shadow>' +
  3106. ' </value>' +
  3107. ' <value name="field">' +
  3108. ' <shadow type="math_number">' +
  3109. ' <field name="NUM">1</field>' +
  3110. ' </shadow>' +
  3111. ' </value>' +
  3112. '</block>' +
  3113. '<label id="basis_http" text="Basis http" web-class="myLabelStyle" style="font-size:20px;"></label>' +
  3114. '<block type="esp32_network_http_get">' +
  3115. ' <value name="http_get_url">' +
  3116. ' <shadow type="text">' +
  3117. ' <field name="TEXT">HTTP://ENTER_AN_URL</field>' +
  3118. ' </shadow>' +
  3119. ' </value>' +
  3120. '</block>' +
  3121. '<block type="esp32_network_http_post">' +
  3122. ' <value name="http_post_url">' +
  3123. ' <shadow type="text">' +
  3124. ' <field name="TEXT">HTTP://ENTER_AN_URL</field>' +
  3125. ' </shadow>' +
  3126. ' </value>' +
  3127. ' <value name="data">' +
  3128. ' <block type="dict_create_with_items_insert"></block>' +
  3129. ' </value>' +
  3130. '</block>' +
  3131. '<block type="CocoRobo_get"></block>' +
  3132. '<block type="esp32_network_http_get_data_from_local_server"></block>' +
  3133. '</category>' +
  3134. '<category id="catCloudData" name="云端" colour="#3062c1">' +
  3135. '<label id="basis_service_cococloud" text="Basis service cococloud" web-class="myLabelStyle" style="font-size:20px;"></label>' +
  3136. // '<block type="iot_service_cococloud">' +
  3137. // ' <value name="ADD0">' +
  3138. // ' <shadow type="math_number">' +
  3139. // ' <field name="NUM">0</field>' +
  3140. // ' </shadow>' +
  3141. // ' </value>' +
  3142. // '</block>' +
  3143. '<block type="v831_service_cococloud">' +
  3144. ' <value name="KEY0">' +
  3145. ' <shadow type="text">' +
  3146. ' <field name="TEXT">Property</field>' +
  3147. ' </shadow>' +
  3148. ' </value>' +
  3149. ' <value name="ADD0">' +
  3150. ' <shadow type="text">' +
  3151. ' <field name="TEXT">value</field>' +
  3152. ' </shadow>' +
  3153. ' </value>' +
  3154. '</block>' +
  3155. '<block type="iot_service_cococloud_read"></block>' +
  3156. '<block type="iot_service_cococloud_read_data">' +
  3157. ' <value name="property">' +
  3158. ' <shadow type="text">' +
  3159. ' <field name="TEXT">property</field>' +
  3160. ' </shadow>' +
  3161. ' </value>' +
  3162. '</block>' +
  3163. '</category>' +
  3164. '</category>',
  3165. 'ExtendedFunction':
  3166. '<category id="extension_module" name="extension_module" colour="#3163ed">' +
  3167. '<category id="LEDstrip" name="LED strip" colour="#e8795b">' +
  3168. // '<block type="esp32_main_controller_led_strip_setup">' +
  3169. // ' <value name="io">' +
  3170. // ' <shadow type="math_number">' +
  3171. // ' <field name="NUM">1</field>' +
  3172. // ' </shadow>' +
  3173. // ' </value>' +
  3174. // ' <value name="count">' +
  3175. // ' <shadow type="math_number">' +
  3176. // ' <field name="NUM">16</field>' +
  3177. // ' </shadow>' +
  3178. // ' </value>' +
  3179. // '</block>' +
  3180. '<block type="esp32_main_controller_led_strip_set">' +
  3181. ' <value name="location">' +
  3182. ' <shadow type="math_number">' +
  3183. ' <field name="NUM">1</field>' +
  3184. ' </shadow>' +
  3185. ' </value>' +
  3186. ' <value name="color">' +
  3187. ' <block type="iot_led_matrix_color_picker"></block>' +
  3188. ' </value>' +
  3189. ' <value name="brightness">' +
  3190. ' <shadow type="math_number">' +
  3191. ' <field name="NUM">50</field>' +
  3192. ' </shadow>' +
  3193. ' </value>' +
  3194. '</block>' +
  3195. '<block type="esp32_main_controller_led_strip_set_one">' +
  3196. ' <value name="location">' +
  3197. ' <shadow type="math_number">' +
  3198. ' <field name="NUM">1</field>' +
  3199. ' </shadow>' +
  3200. ' </value>' +
  3201. ' <value name="location1">' +
  3202. ' <shadow type="math_number">' +
  3203. ' <field name="NUM">5</field>' +
  3204. ' </shadow>' +
  3205. ' </value>' +
  3206. ' <value name="color">' +
  3207. ' <block type="iot_led_matrix_color_picker"></block>' +
  3208. ' </value>' +
  3209. ' <value name="brightness">' +
  3210. ' <shadow type="math_number">' +
  3211. ' <field name="NUM">50</field>' +
  3212. ' </shadow>' +
  3213. ' </value>' +
  3214. '</block>' +
  3215. '<block type="esp32_main_controller_led_strip_set_all">' +
  3216. ' <value name="color">' +
  3217. ' <block type="iot_led_matrix_color_picker"></block>' +
  3218. ' </value>' +
  3219. ' <value name="brightness">' +
  3220. ' <shadow type="math_number">' +
  3221. ' <field name="NUM">50</field>' +
  3222. ' </shadow>' +
  3223. ' </value>' +
  3224. '</block>' +
  3225. '<block type="esp32_main_controller_led_strip_set_all_off"></block>' +
  3226. '<block type="iot_led_matrix_color_picker"></block>' +
  3227. '<block type="led_strip_color_rgb">' +
  3228. ' <value name="rgb_value_r">' +
  3229. ' <shadow type="math_number">' +
  3230. ' <field name="NUM">0</field>' +
  3231. ' </shadow>' +
  3232. ' </value>' +
  3233. ' <value name="rgb_value_g">' +
  3234. ' <shadow type="math_number">' +
  3235. ' <field name="NUM">0</field>' +
  3236. ' </shadow>' +
  3237. ' </value>' +
  3238. ' <value name="rgb_value_b">' +
  3239. ' <shadow type="math_number">' +
  3240. ' <field name="NUM">0</field>' +
  3241. ' </shadow>' +
  3242. ' </value>' +
  3243. '</block>' +
  3244. '</category>' +
  3245. '<category id="" name="第三方传感器" colour="#d42b03">' +
  3246. '<label id="basis_buzzer" text="蜂鸣器" web-class="myLabelStyle" style="font-size:20px;"></label>' +
  3247. '<block type="esp32_main_controller_set_buzzer_init"></block>' +
  3248. '<block type="esp32_main_controller_set_buzzer">' +
  3249. ' <value name="esp32_var_num">' +
  3250. ' <shadow type="math_number">' +
  3251. ' <field name="NUM">31</field>' +
  3252. ' </shadow>' +
  3253. ' </value>' +
  3254. '</block>' +
  3255. '<block type="esp32_main_controller_turn_off_buzzer"></block>' +
  3256. '<block type="esp32_main_controller_turn_off_buzzer_music">' +
  3257. ' <value name="beat">' +
  3258. ' <shadow type="esp32_main_controller_buzzer_set_beat_lite">' +
  3259. ' </shadow>' +
  3260. ' </value>' +
  3261. '</block>' +
  3262. '<label id="" text="室温/水温" web-class="myLabelStyle" style="font-size:20px;"></label>' +
  3263. '<block type="v831_room_water_temperature"></block>' +
  3264. '<label id="" text="实时时钟" web-class="myLabelStyle" style="font-size:20px;"></label>' +
  3265. '<block type="v831_set_real_time_clock"></block>' +
  3266. '<block type="v831_real_time_clock"></block>' +
  3267. '</category>' +
  3268. '</category>',
  3269. };
  3270. /**
  3271. * Creates an updated representation of the Toolboxes XML as currently specified in the
  3272. * model, using whatever modules have been added or removed. This method can either set it
  3273. * or just retrieve it for future use.
  3274. *
  3275. * @param {Boolean} only_set - Whether to return the XML string or to actually set the XML. False means that it will not update the toolbox!
  3276. * @returns {String?} Possibly returns the XML of the toolbox as a string.
  3277. */
  3278. BlockPyEditor.prototype.updateToolbox = function (only_set) {
  3279. // let blocklyXml = Blockly.Xml.textToDom(BlockPyEditor.CATEGORY_MAP)
  3280. // var categoryNodes = blocklyXml.getElementsByTagName('category');
  3281. // for (var i = 0, cat; cat = categoryNodes[i]; i++) {
  3282. // var catId = cat.getAttribute('id');
  3283. // var catText = Ardublockly.getLocalStr(catId);
  3284. // if (catText) {
  3285. // cat.setAttribute('name', catText);
  3286. // }
  3287. // }
  3288. var xml = '<xml id="toolbox" style="display: none">';
  3289. var modules = this.main.model.assignment.modules();
  3290. var started_misc = false,
  3291. started_values = false,
  3292. started_data = false;
  3293. for (var i = 0, length = modules.length; i < length; i = i + 1) {
  3294. var module = modules[i];
  3295. if (!started_misc && ['Calculation', 'Output', 'Python'].indexOf(module) != -1) {
  3296. started_misc = true;
  3297. // xml += BlockPyEditor.CATEGORY_MAP['Separator'];
  3298. }
  3299. if (!started_values && ['Values', 'Lists', 'Dictionaries'].indexOf(module) != -1) {
  3300. started_values = true;
  3301. // xml += BlockPyEditor.CATEGORY_MAP['Separator'];
  3302. }
  3303. if (!started_data && module.slice(0, 6) == 'Data -') {
  3304. started_data = true;
  3305. // xml += BlockPyEditor.CATEGORY_MAP['Separator'];
  3306. }
  3307. if (typeof module == 'string') {
  3308. xml += BlockPyEditor.CATEGORY_MAP[module];
  3309. } else {
  3310. var category = '<category name="' + module.name + '" colour="' + module.color + '">';
  3311. for (var j = 0; category_length = module.blocks.length; j = j + 1) {
  3312. var block = module.blocks[j];
  3313. category += '<block type="' + block + '"></block>';
  3314. }
  3315. category += '</category>';
  3316. }
  3317. //'<sep></sep>'+
  3318. }
  3319. xml += '</xml>';
  3320. Ardublockly.initLanguage();
  3321. Ardublockly.updateToolboxLanguage(xml);
  3322. xml = Ardublockly.xmlTree;
  3323. if (only_set && !this.main.model.settings.read_only()) {
  3324. this.blockly.updateToolbox(xml);
  3325. this.blockly.resize();
  3326. } else {
  3327. return xml;
  3328. }
  3329. };
  3330. BlockPyEditor.prototype.DOCTYPE = '<?xml version="1.0" standalone="no"?>' + '<' + '!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">';
  3331. BlockPyEditor.prototype.cssData = null;
  3332. BlockPyEditor.prototype.loadCss = function () {
  3333. if (this.cssData == null) {
  3334. var txt = '.blocklyDraggable {}\n';
  3335. txt += Blockly.Css.CONTENT.join('\n');
  3336. if (Blockly.FieldDate) {
  3337. txt += Blockly.FieldDate.CSS.join('\n');
  3338. }
  3339. // Strip off any trailing slash (either Unix or Windows).
  3340. this.cssData = txt.replace(/<<<PATH>>>/g, Blockly.Css.mediaPath_);
  3341. }
  3342. }
  3343. /**
  3344. * Generates a PNG version of the current workspace. This PNG is stored in a Base-64 encoded
  3345. * string as part of a data URL (e.g., "data:image/png;base64,...").
  3346. * TODO: There seems to be some problems capturing blocks that don't start with
  3347. * statement level blocks (e.g., expression blocks).
  3348. *
  3349. * @param {Function} callback - A function to be called with the results. This function should take two parameters, the URL (as a string) of the generated base64-encoded PNG and the IMG tag.
  3350. */
  3351. BlockPyEditor.prototype.getPngFromBlocks = function (callback) {
  3352. this.loadCss();
  3353. try {
  3354. // Retreive the entire canvas, strip some unnecessary tags
  3355. var blocks = this.blockly.svgBlockCanvas_.cloneNode(true);
  3356. blocks.removeAttribute("width");
  3357. blocks.removeAttribute("height");
  3358. // Ensure that we have some content
  3359. if (blocks.childNodes[0] !== undefined) {
  3360. // Remove tags that offset
  3361. blocks.removeAttribute("transform");
  3362. blocks.childNodes[0].removeAttribute("transform");
  3363. blocks.childNodes[0].childNodes[0].removeAttribute("transform");
  3364. // Add in styles
  3365. var linkElm = document.createElementNS("http://www.w3.org/1999/xhtml", "style");
  3366. linkElm.textContent = this.cssData + '\n\n';
  3367. blocks.insertBefore(linkElm, blocks.firstChild);
  3368. // Get the bounding box
  3369. var bbox = document.getElementsByClassName("blocklyBlockCanvas")[0].getBBox();
  3370. // Create the XML representation of the SVG
  3371. var xml = new XMLSerializer().serializeToString(blocks);
  3372. xml = '<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="' + bbox.width + '" height="' + bbox.height + '" viewBox="0 0 ' + bbox.width + ' ' + bbox.height + '"><rect width="100%" height="100%" fill="white"></rect>' + xml + '</svg>';
  3373. // create a file blob of our SVG.
  3374. // Unfortunately, this crashes modern chrome for unknown reasons.
  3375. //var blob = new Blob([ this.DOCTYPE + xml], { type: 'image/svg+xml' });
  3376. //var url = window.URL.createObjectURL(blob);
  3377. // Old method: this failed on IE
  3378. var url = "data:image/svg+xml;base64," + btoa(unescape(encodeURIComponent(xml)));
  3379. // Create an IMG tag to hold the new element
  3380. var img = document.createElement("img");
  3381. img.style.display = 'block';
  3382. img.onload = function () {
  3383. var canvas = document.createElement('canvas');
  3384. canvas.width = bbox.width;
  3385. canvas.height = bbox.height;
  3386. var ctx = canvas.getContext('2d');
  3387. ctx.drawImage(img, 0, 0);
  3388. var canvasUrl;
  3389. try {
  3390. canvasUrl = canvas.toDataURL("image/png");
  3391. } catch (e) {
  3392. canvasUrl = url;
  3393. }
  3394. img.onload = null;
  3395. callback(canvasUrl, img);
  3396. }
  3397. img.onerror = function () {
  3398. callback("", img);
  3399. }
  3400. img.setAttribute('src', url);
  3401. } else {
  3402. callback("", document.createElement("img"))
  3403. }
  3404. } catch (e) {
  3405. callback("", document.createElement("img"));
  3406. console.error("PNG image creation not supported!", e);
  3407. }
  3408. }
  3409. /**
  3410. * Shows a dialog window with the current block workspace encoded as a
  3411. * downloadable PNG image.
  3412. */
  3413. BlockPyEditor.prototype.copyImage = function () {
  3414. var dialog = this.main.components.dialog;
  3415. this.getPngFromBlocks(function (canvasUrl, img) {
  3416. img.onload = function () {
  3417. var p = document.createElement('p');
  3418. p.textContent = "Right click the image below and choose to copy or save it."
  3419. var div = document.createElement('div');
  3420. div.appendChild(p);
  3421. div.appendChild(img);
  3422. dialog.show("Save Blocks As Image", div);
  3423. };
  3424. img.src = canvasUrl;
  3425. });
  3426. }