sb-edit
Version:
Import, edit, and export Scratch project files
606 lines (605 loc) • 31.8 kB
JavaScript
"use strict";
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
if (ar || !(i in from)) {
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
ar[i] = from[i];
}
}
return to.concat(ar || Array.prototype.slice.call(from));
};
Object.defineProperty(exports, "__esModule", { value: true });
var OpCode_1 = require("../../OpCode");
function toScratchblocks(project, inOptions) {
if (inOptions === void 0) { inOptions = {}; }
var defaultOptions = {
indent: "\t"
};
var options = __assign(__assign({}, defaultOptions), inOptions);
function indent(str) {
return str
.split("\n")
.map(function (l) { return options.indent + l; })
.join("\n");
}
function input(inp, target, flag) {
if (flag === void 0) { flag = false; }
if (!inp) {
return "";
}
var escape = function (value) { return (value || "").toString().replace(/[()[\]]|v$/g, function (m) { return "\\" + m; }); };
switch (inp.type) {
case "number":
if (typeof inp.value === "number" || inp.value.trim().length === 0) {
return "(".concat(inp.value, ")");
}
else {
return "[".concat(escape(inp.value), "]");
}
case "angle":
return "(".concat(inp.value || "", ")");
case "string":
return "[".concat(escape(inp.value), "]");
case "graphicEffect":
case "soundEffect":
case "currentMenu":
case "greaterThanMenu": {
var value = inp.value === "PAN" || inp.value === "DAYOFWEEK"
? {
PAN: "pan left/right",
DAYOFWEEK: "day of week"
}[inp.value]
: (inp.value || "").toLowerCase();
return "[".concat(escape(value), " v]");
}
case "variable":
case "list":
return "[".concat(escape(inp.value.name), " v]");
case "rotationStyle":
case "scrollAlignment":
case "stopMenu":
case "dragModeMenu":
case "propertyOfMenu":
case "mathopMenu":
case "frontBackMenu":
case "forwardBackwardMenu":
case "costumeNumberName":
return "[".concat(escape(inp.value), " v]");
case "goToTarget":
case "pointTowardsTarget":
case "cloneTarget":
case "distanceToMenu":
case "touchingTarget":
case "target": {
var value = {
_mouse_: "mouse-pointer",
_myself_: "myself",
_random_: "random position",
_stage_: "Stage"
}[inp.value] || inp.value;
return "(".concat(escape(value), " v)");
}
case "costume":
case "sound":
case "penColorParam":
case "musicDrum":
case "musicInstrument":
case "videoSensingAttribute":
case "videoSensingSubject":
case "videoSensingVideoState":
return "(".concat(escape(inp.value), " v)");
case "broadcast":
case "backdrop":
case "key":
if (flag) {
return "[".concat(escape(inp.value), " v]");
}
else {
return "(".concat(escape(inp.value), " v)");
}
case "color": {
var hex = function (k) {
return (inp.value || { r: 0, g: 0, b: 0 })[k].toString(16).padStart(2, "0");
};
return "[#".concat(hex("r") + hex("g") + hex("b"), "]");
}
case "block":
if (flag) {
if (inp.value) {
return "\n" + indent(blockToScratchblocks(inp.value, target)) + "\n";
}
else {
return "\n";
}
}
else {
if (inp.value) {
var ret = blockToScratchblocks(inp.value, target);
if (ret[0] === "(" || ret[0] === "<") {
return ret;
}
else {
return "(" + ret + ")";
}
}
else {
return "()";
}
}
case "blocks":
if (inp.value) {
return "\n" + indent(blocksToScratchblocks(inp.value, target)) + "\n";
}
else {
return "\n";
}
default:
return "(unknown input type [".concat(inp.type, "])");
}
}
function blockToScratchblocks(block, target) {
if (!target) {
throw new Error("expected target");
}
var i = function (key, flag) {
// TODO: type this function properly and remove this type assertion
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-unsafe-member-access
return input(block.inputs[key], target, flag);
};
var operator = function (op) { return "(".concat(i("NUM1"), " ").concat(op, " ").concat(i("NUM2"), ")"); };
var boolop = function (op, flag) {
if (flag === void 0) { flag = false; }
if (flag) {
return "<".concat(i("OPERAND1") || "<>", " ").concat(op, " ").concat(i("OPERAND2") || "<>", ">");
}
else {
return "<".concat(i("OPERAND1"), " ").concat(op, " ").concat(i("OPERAND2"), ">");
}
};
switch (block.opcode) {
// motion ------------------------------------------------------ //
case OpCode_1.OpCode.motion_movesteps:
return "move ".concat(i("STEPS"), " steps");
case OpCode_1.OpCode.motion_turnright:
return "turn cw ".concat(i("DEGREES"), " degrees");
case OpCode_1.OpCode.motion_turnleft:
return "turn ccw ".concat(i("DEGREES"), " degrees");
case OpCode_1.OpCode.motion_goto:
return "go to ".concat(i("TO"));
case OpCode_1.OpCode.motion_gotoxy:
return "go to x: ".concat(i("X"), " y: ").concat(i("Y"));
case OpCode_1.OpCode.motion_glideto:
return "glide ".concat(i("SECS"), " secs to ").concat(i("TO"));
case OpCode_1.OpCode.motion_glidesecstoxy:
return "glide ".concat(i("SECS"), " secs to x: ").concat(i("X"), " y: ").concat(i("Y"));
case OpCode_1.OpCode.motion_pointindirection:
return "point in direction ".concat(i("DIRECTION"));
case OpCode_1.OpCode.motion_pointtowards:
return "point towards ".concat(i("TOWARDS"));
case OpCode_1.OpCode.motion_changexby:
return "change x by ".concat(i("DX"));
case OpCode_1.OpCode.motion_setx:
return "set x to ".concat(i("X"));
case OpCode_1.OpCode.motion_changeyby:
return "change y by ".concat(i("DY"));
case OpCode_1.OpCode.motion_sety:
return "set y to ".concat(i("Y"));
case OpCode_1.OpCode.motion_ifonedgebounce:
return "if on edge, bounce";
case OpCode_1.OpCode.motion_setrotationstyle:
return "set rotation style ".concat(i("STYLE"));
case OpCode_1.OpCode.motion_xposition:
return "(x position)";
case OpCode_1.OpCode.motion_yposition:
return "(y position)";
case OpCode_1.OpCode.motion_direction:
return "(direction)";
case OpCode_1.OpCode.motion_scroll_right:
return "scroll right ".concat(i("DISTANCE"), " :: motion");
case OpCode_1.OpCode.motion_scroll_up:
return "scroll up ".concat(i("DISTANCE"), " :: motion");
case OpCode_1.OpCode.motion_align_scene:
return "align scene ".concat(i("ALIGNMENT"), " :: motion");
case OpCode_1.OpCode.motion_xscroll:
return "(x scroll)";
case OpCode_1.OpCode.motion_yscroll:
return "(y scroll)";
// looks ------------------------------------------------------- //
case OpCode_1.OpCode.looks_sayforsecs:
return "say ".concat(i("MESSAGE"), " for ").concat(i("SECS"), " seconds");
case OpCode_1.OpCode.looks_say:
return "say ".concat(i("MESSAGE"));
case OpCode_1.OpCode.looks_thinkforsecs:
return "think ".concat(i("MESSAGE"), " for ").concat(i("SECS"), " seconds");
case OpCode_1.OpCode.looks_think:
return "think ".concat(i("MESSAGE"));
case OpCode_1.OpCode.looks_switchcostumeto:
return "switch costume to ".concat(i("COSTUME"));
case OpCode_1.OpCode.looks_nextcostume:
return "next costume";
case OpCode_1.OpCode.looks_switchbackdropto:
return "switch backdrop to ".concat(i("BACKDROP"));
case OpCode_1.OpCode.looks_nextbackdrop:
return "next backdrop";
case OpCode_1.OpCode.looks_changesizeby:
return "change size by ".concat(i("CHANGE"));
case OpCode_1.OpCode.looks_setsizeto:
return "set size to ".concat(i("SIZE"), "%");
case OpCode_1.OpCode.looks_changeeffectby:
return "change ".concat(i("EFFECT"), " effect by ").concat(i("CHANGE"), " :: looks");
case OpCode_1.OpCode.looks_seteffectto:
return "set ".concat(i("EFFECT"), " effect to ").concat(i("VALUE"), " :: looks");
case OpCode_1.OpCode.looks_cleargraphiceffects:
return "clear graphic effects";
case OpCode_1.OpCode.looks_show:
return "show";
case OpCode_1.OpCode.looks_hide:
return "hide";
case OpCode_1.OpCode.looks_gotofrontback:
return "go to ".concat(i("FRONT_BACK"), " layer");
case OpCode_1.OpCode.looks_goforwardbackwardlayers:
return "go ".concat(i("FORWARD_BACKWARD"), " ").concat(i("NUM"), " layers");
case OpCode_1.OpCode.looks_costumenumbername:
return "(costume ".concat(i("NUMBER_NAME"), ")");
case OpCode_1.OpCode.looks_backdropnumbername:
return "(backdrop ".concat(i("NUMBER_NAME"), ")");
case OpCode_1.OpCode.looks_size:
return "(size)";
case OpCode_1.OpCode.looks_hideallsprites:
return "hide all sprites :: looks";
case OpCode_1.OpCode.looks_switchbackdroptoandwait:
return "switch backdrop to ".concat(i("BACKDROP"), " and wait");
case OpCode_1.OpCode.looks_changestretchby:
return "change stretch by ".concat(i("CHANGE"), " :: looks");
case OpCode_1.OpCode.looks_setstretchto:
return "set stretch to ".concat(i("STRETCH"), " % :: looks");
// sound ------------------------------------------------------- //
case OpCode_1.OpCode.sound_playuntildone:
return "play sound ".concat(i("SOUND_MENU"), " until done");
case OpCode_1.OpCode.sound_play:
return "start sound ".concat(i("SOUND_MENU"));
case OpCode_1.OpCode.sound_stopallsounds:
return "stop all sounds";
case OpCode_1.OpCode.sound_changeeffectby:
return "change ".concat(i("EFFECT"), " effect by ").concat(i("VALUE"), " :: sound");
case OpCode_1.OpCode.sound_seteffectto:
return "set ".concat(i("EFFECT"), " effect to ").concat(i("VALUE"), " :: sound");
case OpCode_1.OpCode.sound_cleareffects:
return "clear sound effects";
case OpCode_1.OpCode.sound_changevolumeby:
return "change volume by ".concat(i("VOLUME"));
case OpCode_1.OpCode.sound_setvolumeto:
return "set volume to ".concat(i("VOLUME"), " %");
case OpCode_1.OpCode.sound_volume:
return "(volume)";
// events ------------------------------------------------------ //
case OpCode_1.OpCode.event_whenflagclicked:
return "when green flag clicked";
case OpCode_1.OpCode.event_whenkeypressed:
return "when ".concat(i("KEY_OPTION", true), " key pressed");
case OpCode_1.OpCode.event_whenthisspriteclicked:
return "when this sprite clicked";
case OpCode_1.OpCode.event_whenstageclicked:
return "when stage clicked :: control hat";
case OpCode_1.OpCode.event_whenbackdropswitchesto:
return "when backdrop switches to ".concat(i("BACKDROP", true));
case OpCode_1.OpCode.event_whengreaterthan:
return "when ".concat(i("WHENGREATERTHANMENU"), " > ").concat(i("VALUE"));
case OpCode_1.OpCode.event_whenbroadcastreceived:
return "when I receive ".concat(i("BROADCAST_OPTION", true));
case OpCode_1.OpCode.event_broadcast:
return "broadcast ".concat(i("BROADCAST_INPUT"));
case OpCode_1.OpCode.event_broadcastandwait:
return "broadcast ".concat(i("BROADCAST_INPUT"), " and wait");
// control ----------------------------------------------------- //
case OpCode_1.OpCode.control_wait:
return "wait ".concat(i("DURATION"), " seconds");
case OpCode_1.OpCode.control_repeat:
return "repeat ".concat(i("TIMES")) + (i("SUBSTACK", true) || "\n") + "end";
case OpCode_1.OpCode.control_forever:
return "forever" + (i("SUBSTACK", true) || "\n") + "end";
case OpCode_1.OpCode.control_if:
return "if ".concat(i("CONDITION") || "<>", " then") + (i("SUBSTACK", true) || "\n") + "end";
case OpCode_1.OpCode.control_if_else:
return ("if ".concat(i("CONDITION") || "<>", " then") +
(i("SUBSTACK", true) || "\n") +
"else" +
(i("SUBSTACK2", true) || "\n") +
"end");
case OpCode_1.OpCode.control_wait_until:
return "wait until ".concat(i("CONDITION") || "<>");
case OpCode_1.OpCode.control_repeat_until:
return "repeat until ".concat(i("CONDITION") || "<>") + (i("SUBSTACK", true) || "\n") + "end";
case OpCode_1.OpCode.control_while:
return "while ".concat(i("CONDITION") || "<>", " {") + (i("SUBSTACK", true) || "\n") + "} :: control";
case OpCode_1.OpCode.control_for_each:
return "for each ".concat(i("VARIABLE"), " in ").concat(i("VALUE"), " {") + (i("SUBSTACK", true) || "\n") + "} :: control";
case OpCode_1.OpCode.control_all_at_once:
return "all at once {" + (i("SUBSTACK", true) || "\n") + "} :: control";
case OpCode_1.OpCode.control_stop:
return "stop ".concat(i("STOP_OPTION"));
case OpCode_1.OpCode.control_start_as_clone:
return "when I start as a clone";
case OpCode_1.OpCode.control_create_clone_of:
return "create clone of ".concat(i("CLONE_OPTION"));
case OpCode_1.OpCode.control_delete_this_clone:
return "delete this clone";
case OpCode_1.OpCode.control_get_counter:
return "(counter :: control)";
case OpCode_1.OpCode.control_incr_counter:
return "increment counter :: control";
case OpCode_1.OpCode.control_clear_counter:
return "clear coutner :: control";
// sensing ----------------------------------------------------- //
case OpCode_1.OpCode.sensing_touchingobject:
return "<touching ".concat(i("TOUCHINGOBJECTMENU"), " ?>");
case OpCode_1.OpCode.sensing_touchingcolor:
return "<touching ".concat(i("COLOR"), " ?>");
case OpCode_1.OpCode.sensing_coloristouchingcolor:
return "<color ".concat(i("COLOR"), " is touching ").concat(i("COLOR2"), " ?>");
case OpCode_1.OpCode.sensing_distanceto:
return "(distance to ".concat(i("DISTANCETOMENU"), ")");
case OpCode_1.OpCode.sensing_askandwait:
return "ask ".concat(i("QUESTION"), " and wait");
case OpCode_1.OpCode.sensing_answer:
return "(answer)";
case OpCode_1.OpCode.sensing_keypressed:
return "<key ".concat(i("KEY_OPTION"), " pressed?>");
case OpCode_1.OpCode.sensing_mousedown:
return "<mouse down?>";
case OpCode_1.OpCode.sensing_mousex:
return "(mouse x)";
case OpCode_1.OpCode.sensing_mousey:
return "(mouse y)";
case OpCode_1.OpCode.sensing_setdragmode:
return "set drag mode ".concat(i("DRAG_MODE"));
case OpCode_1.OpCode.sensing_loudness:
return "(loudness)";
case OpCode_1.OpCode.sensing_loud:
return "<loud? :: sensing>";
case OpCode_1.OpCode.sensing_timer:
return "(timer)";
case OpCode_1.OpCode.sensing_resettimer:
return "reset timer";
case OpCode_1.OpCode.sensing_of:
return "(".concat(i("PROPERTY"), " of ").concat(i("OBJECT"), ")");
case OpCode_1.OpCode.sensing_current:
return "(current ".concat(i("CURRENTMENU"), ")");
case OpCode_1.OpCode.sensing_dayssince2000:
return "(days since 2000)";
case OpCode_1.OpCode.sensing_username:
return "(username)";
case OpCode_1.OpCode.sensing_userid:
return "(user id :: sensing)";
// operators --------------------------------------------------- //
case OpCode_1.OpCode.operator_add:
return operator("+");
case OpCode_1.OpCode.operator_subtract:
return operator("-");
case OpCode_1.OpCode.operator_multiply:
return operator("*");
case OpCode_1.OpCode.operator_divide:
return operator("/");
case OpCode_1.OpCode.operator_random:
return "(pick random ".concat(i("FROM"), " to ").concat(i("TO"), ")");
case OpCode_1.OpCode.operator_gt:
return boolop(">");
case OpCode_1.OpCode.operator_lt:
return boolop("<");
case OpCode_1.OpCode.operator_equals:
return boolop("=");
case OpCode_1.OpCode.operator_and:
return boolop("and", true);
case OpCode_1.OpCode.operator_or:
return boolop("or", true);
case OpCode_1.OpCode.operator_not:
return "<not ".concat(i("OPERAND") || "<>", ">");
case OpCode_1.OpCode.operator_join:
return "(join ".concat(i("STRING1"), " ").concat(i("STRING2"), ")");
case OpCode_1.OpCode.operator_letter_of:
return "(letter ".concat(i("LETTER"), " of ").concat(i("STRING"), ")");
case OpCode_1.OpCode.operator_length:
return "(length of ".concat(i("STRING"), ")");
case OpCode_1.OpCode.operator_contains:
return "<".concat(i("STRING1"), " contains ").concat(i("STRING2"), " ? :: operators>");
case OpCode_1.OpCode.operator_mod:
return operator("mod");
case OpCode_1.OpCode.operator_round:
return "(round ".concat(i("NUM"), ")");
case OpCode_1.OpCode.operator_mathop:
return "(".concat(i("OPERATOR"), " of ").concat(i("NUM"), ")");
// data -------------------------------------------------------- //
case OpCode_1.OpCode.data_variable:
return "(".concat(block.inputs.VARIABLE.value.name, " :: variables)");
case OpCode_1.OpCode.data_setvariableto:
return "set ".concat(i("VARIABLE"), " to ").concat(i("VALUE"));
case OpCode_1.OpCode.data_changevariableby:
return "change ".concat(i("VARIABLE"), " by ").concat(i("VALUE"));
case OpCode_1.OpCode.data_showvariable:
return "show variable ".concat(i("VARIABLE"));
case OpCode_1.OpCode.data_hidevariable:
return "hide variable ".concat(i("VARIABLE"));
case OpCode_1.OpCode.data_listcontents:
return "(".concat(block.inputs.LIST.value.name, " :: list)");
case OpCode_1.OpCode.data_addtolist:
return "add ".concat(i("ITEM"), " to ").concat(i("LIST"));
case OpCode_1.OpCode.data_deleteoflist:
return "delete ".concat(i("INDEX"), " of ").concat(i("LIST"));
case OpCode_1.OpCode.data_deletealloflist:
return "delete all of ".concat(i("LIST"));
case OpCode_1.OpCode.data_insertatlist:
return "insert ".concat(i("ITEM"), " at ").concat(i("INDEX"), " of ").concat(i("LIST"));
case OpCode_1.OpCode.data_replaceitemoflist:
return "replace item ".concat(i("INDEX"), " of ").concat(i("LIST"), " with ").concat(i("ITEM"));
case OpCode_1.OpCode.data_itemoflist:
return "(item ".concat(i("INDEX"), " of ").concat(i("LIST"), ")");
case OpCode_1.OpCode.data_itemnumoflist:
return "(item # of ".concat(i("ITEM"), " in ").concat(i("LIST"), ")");
case OpCode_1.OpCode.data_lengthoflist:
return "(length of ".concat(i("LIST"), ")");
case OpCode_1.OpCode.data_listcontainsitem:
return "<".concat(i("LIST"), " contains ").concat(i("ITEM"), " ? :: list>");
case OpCode_1.OpCode.data_showlist:
return "show list ".concat(i("LIST"));
case OpCode_1.OpCode.data_hidelist:
return "hide list ".concat(i("LIST"));
// custom blocks ----------------------------------------------- //
case OpCode_1.OpCode.procedures_definition: {
var spec = block.inputs.ARGUMENTS.value
.map(function (_a) {
var type = _a.type, name = _a.name;
switch (type) {
case "label":
return name.replace(/\//g, "\\/");
case "numberOrString":
return "(".concat(name, ")");
case "boolean":
return "<".concat(name, ">");
}
})
.join(" ");
return "define ".concat(spec) + (block.inputs.WARP.value ? " // run without screen refresh" : "");
}
case OpCode_1.OpCode.procedures_call: {
var definition = target.scripts
.map(function (s) { return s.blocks[0]; })
.find(function (b) { return b.opcode === OpCode_1.OpCode.procedures_definition && b.inputs.PROCCODE.value === block.inputs.PROCCODE.value; });
// we guarantee the opcode check is true already by checking it in find(), but typescript doesn't seem to notice that, so we include this assert here
if (definition && definition.opcode === OpCode_1.OpCode.procedures_definition) {
var index_1 = 0;
return (definition.inputs.ARGUMENTS.value
.map(function (_a) {
var type = _a.type, name = _a.name;
switch (type) {
case "label":
return name.replace(/\//g, "\\/");
default:
// TODO: deal with empty boolean inputs, which can't even load yet
return input(block.inputs.INPUTS.value[index_1++], target);
}
})
.join(" ") + " :: custom");
}
else {
return "... // missing custom block definition for ".concat(block.inputs.PROCCODE.value);
}
}
case OpCode_1.OpCode.argument_reporter_string_number:
return "(".concat(block.inputs.VALUE.value, " :: custom-arg)");
case OpCode_1.OpCode.argument_reporter_boolean:
return "<".concat(block.inputs.VALUE.value, " :: custom-arg>");
// extension: music -------------------------------------------- //
case OpCode_1.OpCode.music_playDrumForBeats:
return "play drum ".concat(i("DRUM"), " for ").concat(i("BEATS"), " beats");
case OpCode_1.OpCode.music_midiPlayDrumForBeats:
return "play (old midi) drum ".concat(i("DRUM"), " for ").concat(i("BEATS"), " beats :: music");
case OpCode_1.OpCode.music_restForBeats:
return "rest for ".concat(i("BEATS"), " beats");
case OpCode_1.OpCode.music_playNoteForBeats:
return "play note ".concat(i("NOTE"), " for ").concat(i("BEATS"), " beats");
case OpCode_1.OpCode.music_setInstrument:
return "set instrument to ".concat(i("INSTRUMENT"));
case OpCode_1.OpCode.music_midiSetInstrument:
return "set (old midi) instrument to ".concat(i("INSTRUMENT"), " :: music");
case OpCode_1.OpCode.music_setTempo:
return "set tempo to ".concat(i("TEMPO"));
case OpCode_1.OpCode.music_changeTempo:
return "change tempo by ".concat(i("TEMPO"));
case OpCode_1.OpCode.music_getTempo:
return "(tempo)";
// extension: pen ---------------------------------------------- //
case OpCode_1.OpCode.pen_clear:
return "erase all";
case OpCode_1.OpCode.pen_stamp:
return "stamp";
case OpCode_1.OpCode.pen_penDown:
return "pen down";
case OpCode_1.OpCode.pen_penUp:
return "pen up";
case OpCode_1.OpCode.pen_setPenColorToColor:
return "set pen color to ".concat(i("COLOR"));
case OpCode_1.OpCode.pen_changePenColorParamBy:
return "change pen ".concat(i("COLOR_PARAM"), " by ").concat(i("VALUE"));
case OpCode_1.OpCode.pen_setPenColorParamTo:
return "set pen ".concat(i("COLOR_PARAM"), " to ").concat(i("VALUE"));
case OpCode_1.OpCode.pen_changePenSizeBy:
return "change pen size by ".concat(i("SIZE"));
case OpCode_1.OpCode.pen_setPenSizeTo:
return "set pen size to ".concat(i("SIZE"));
case OpCode_1.OpCode.pen_changePenShadeBy:
return "change pen shade by ".concat(i("SHADE"));
case OpCode_1.OpCode.pen_setPenShadeToNumber:
return "set pen shade to ".concat(i("SHADE"));
case OpCode_1.OpCode.pen_changePenHueBy:
return "change pen color by ".concat(i("HUE"));
case OpCode_1.OpCode.pen_setPenHueToNumber:
return "set pen hue to ".concat(i("HUE"));
// extension: video sensing ----------------------------------- //
case OpCode_1.OpCode.videoSensing_whenMotionGreaterThan:
return "when video motion > ".concat(i("REFERENCE"));
case OpCode_1.OpCode.videoSensing_videoOn:
return "(video ".concat(i("ATTRIBUTE"), " on ").concat(i("SUBJECT"), ")");
case OpCode_1.OpCode.videoSensing_videoToggle:
return "turn video ".concat(i("VIDEO_STATE"));
case OpCode_1.OpCode.videoSensing_setVideoTransparency:
return "set video transparency to ".concat(i("TRANSPARENCY"));
// leftover menu "blocks" ----------------------------------- //
case OpCode_1.OpCode.motion_pointtowards_menu:
case OpCode_1.OpCode.motion_glideto_menu:
case OpCode_1.OpCode.motion_goto_menu:
case OpCode_1.OpCode.looks_costume:
case OpCode_1.OpCode.looks_backdrops:
case OpCode_1.OpCode.sound_sounds_menu:
case OpCode_1.OpCode.control_create_clone_of_menu:
case OpCode_1.OpCode.sensing_touchingobjectmenu:
case OpCode_1.OpCode.sensing_distancetomenu:
case OpCode_1.OpCode.sensing_keyoptions:
case OpCode_1.OpCode.sensing_of_object_menu:
case OpCode_1.OpCode.pen_menu_colorParam:
case OpCode_1.OpCode.music_menu_DRUM:
case OpCode_1.OpCode.music_menu_INSTRUMENT:
case OpCode_1.OpCode.videoSensing_menu_ATTRIBUTE:
case OpCode_1.OpCode.videoSensing_menu_SUBJECT:
case OpCode_1.OpCode.videoSensing_menu_VIDEO_STATE:
case OpCode_1.OpCode.wedo2_menu_MOTOR_ID:
case OpCode_1.OpCode.wedo2_menu_MOTOR_DIRECTION:
case OpCode_1.OpCode.wedo2_menu_TILT_DIRECTION:
case OpCode_1.OpCode.wedo2_menu_TILT_DIRECTION_ANY:
return "";
default:
return "unknown block [".concat(block.opcode, "] \\(").concat(Object.keys(block.inputs)
.map(function (k) { return "[".concat(k, "]"); })
.join(", "), "\\)");
}
}
function blocksToScratchblocks(blocks, target) {
return blocks.map(function (b) { return blockToScratchblocks(b, target); }).join("\n");
}
function scriptToScratchblocks(script, target) {
return blocksToScratchblocks(script.blocks, target);
}
var targets = {};
var _loop_1 = function (target) {
targets[target.name] = target.scripts
.map(function (script) { return scriptToScratchblocks(script, target); })
.filter(function (scratchblocks) { return scratchblocks.length > 0; })
.join("\n\n");
};
for (var _i = 0, _a = __spreadArray([project.stage], project.sprites, true); _i < _a.length; _i++) {
var target = _a[_i];
_loop_1(target);
}
return targets;
}
exports.default = toScratchblocks;