diff --git a/src/engine/blocks.js b/src/engine/blocks.js
index cf1b2b7c4..5a0bbd965 100644
--- a/src/engine/blocks.js
+++ b/src/engine/blocks.js
@@ -45,7 +45,10 @@ class Blocks {
          * @type {{inputs: {}, procedureParamNames: {}, procedureDefinitions: {}}}
          * @private
          */
-        Object.defineProperty(this, '_cache', {writable: true, enumerable: false});
+        Object.defineProperty(this, '_cache', {
+            writable: true,
+            enumerable: false
+        });
         this._cache = {
             /**
              * Cache block inputs by block id
@@ -123,13 +126,13 @@ class Blocks {
     }
 
     /**
-      * Get the next block for a particular block
-      * @param {?string} id ID of block to get the next block for
-      * @return {?string} ID of next block in the sequence
-      */
+     * Get the next block for a particular block
+     * @param {?string} id ID of block to get the next block for
+     * @return {?string} ID of next block in the sequence
+     */
     getNextBlock (id) {
         const block = this._blocks[id];
-        return (typeof block === 'undefined') ? null : block.next;
+        return typeof block === 'undefined' ? null : block.next;
     }
 
     /**
@@ -150,7 +153,7 @@ class Blocks {
 
         // Empty C-block?
         const input = block.inputs[inputName];
-        return (typeof input === 'undefined') ? null : input.block;
+        return typeof input === 'undefined' ? null : input.block;
     }
 
     /**
@@ -159,7 +162,7 @@ class Blocks {
      * @return {?string} the opcode corresponding to that block
      */
     getOpcode (block) {
-        return (typeof block === 'undefined') ? null : block.opcode;
+        return typeof block === 'undefined' ? null : block.opcode;
     }
 
     /**
@@ -168,7 +171,7 @@ class Blocks {
      * @return {?object} All fields and their values.
      */
     getFields (block) {
-        return (typeof block === 'undefined') ? null : block.fields;
+        return typeof block === 'undefined' ? null : block.fields;
     }
 
     /**
@@ -186,8 +189,10 @@ class Blocks {
         inputs = {};
         for (const input in block.inputs) {
             // Ignore blocks prefixed with branch prefix.
-            if (input.substring(0, Blocks.BRANCH_INPUT_PREFIX.length) !==
-                Blocks.BRANCH_INPUT_PREFIX) {
+            if (
+                input.substring(0, Blocks.BRANCH_INPUT_PREFIX.length) !==
+                Blocks.BRANCH_INPUT_PREFIX
+            ) {
                 inputs[input] = block.inputs[input];
             }
         }
@@ -202,7 +207,7 @@ class Blocks {
      * @return {?object} Mutation for the block.
      */
     getMutation (block) {
-        return (typeof block === 'undefined') ? null : block.mutation;
+        return typeof block === 'undefined' ? null : block.mutation;
     }
 
     /**
@@ -231,7 +236,9 @@ class Blocks {
         }
 
         for (const id in this._blocks) {
-            if (!Object.prototype.hasOwnProperty.call(this._blocks, id)) continue;
+            if (!Object.prototype.hasOwnProperty.call(this._blocks, id)) {
+                continue;
+            }
             const block = this._blocks[id];
             if (block.opcode === 'procedures_definition') {
                 const internal = this._getCustomBlockInternal(block);
@@ -267,10 +274,14 @@ class Blocks {
         }
 
         for (const id in this._blocks) {
-            if (!Object.prototype.hasOwnProperty.call(this._blocks, id)) continue;
+            if (!Object.prototype.hasOwnProperty.call(this._blocks, id)) {
+                continue;
+            }
             const block = this._blocks[id];
-            if (block.opcode === 'procedures_prototype' &&
-                block.mutation.proccode === name) {
+            if (
+                block.opcode === 'procedures_prototype' &&
+                block.mutation.proccode === name
+            ) {
                 const names = JSON.parse(block.mutation.argumentnames);
                 const ids = JSON.parse(block.mutation.argumentids);
                 const defaults = JSON.parse(block.mutation.argumentdefaults);
@@ -301,8 +312,11 @@ class Blocks {
     blocklyListen (e) {
         // Validate event
         if (typeof e !== 'object') return;
-        if (typeof e.blockId !== 'string' && typeof e.varId !== 'string' &&
-            typeof e.commentId !== 'string') {
+        if (
+            typeof e.blockId !== 'string' &&
+            typeof e.varId !== 'string' &&
+            typeof e.commentId !== 'string'
+        ) {
             return;
         }
         const stage = this.runtime.getTargetForStage();
@@ -357,8 +371,13 @@ class Blocks {
         case 'delete':
             // Don't accept delete events for missing blocks,
             // or shadow blocks being obscured.
-            if (!Object.prototype.hasOwnProperty.call(this._blocks, e.blockId) ||
-                this._blocks[e.blockId].shadow) {
+            if (
+                !Object.prototype.hasOwnProperty.call(
+                    this._blocks,
+                    e.blockId
+                ) ||
+                    this._blocks[e.blockId].shadow
+            ) {
                 return;
             }
             // Inform any runtime to forget about glows on this script.
@@ -375,9 +394,18 @@ class Blocks {
             // into a state where a local var was requested for the stage,
             // create a stage (global) var after checking for name conflicts
             // on all the sprites.
-            if (e.isLocal && editingTarget && !editingTarget.isStage && !e.isCloud) {
+            if (
+                e.isLocal &&
+                    editingTarget &&
+                    !editingTarget.isStage &&
+                    !e.isCloud
+            ) {
                 if (!editingTarget.lookupVariableById(e.varId)) {
-                    editingTarget.createVariable(e.varId, e.varName, e.varType);
+                    editingTarget.createVariable(
+                        e.varId,
+                        e.varName,
+                        e.varType
+                    );
                     this.emitProjectChanged();
                 }
             } else {
@@ -386,23 +414,45 @@ class Blocks {
                     return;
                 }
                 // Check for name conflicts in all of the targets
-                const allTargets = this.runtime.targets.filter(t => t.isOriginal);
+                const allTargets = this.runtime.targets.filter(
+                    t => t.isOriginal
+                );
                 for (const target of allTargets) {
-                    if (target.lookupVariableByNameAndType(e.varName, e.varType, true)) {
+                    if (
+                        target.lookupVariableByNameAndType(
+                            e.varName,
+                            e.varType,
+                            true
+                        )
+                    ) {
                         return;
                     }
                 }
-                stage.createVariable(e.varId, e.varName, e.varType, e.isCloud);
+                stage.createVariable(
+                    e.varId,
+                    e.varName,
+                    e.varType,
+                    e.isCloud
+                );
                 this.emitProjectChanged();
             }
             break;
         case 'var_rename':
-            if (editingTarget && Object.prototype.hasOwnProperty.call(editingTarget.variables, e.varId)) {
+            if (
+                editingTarget &&
+                    Object.prototype.hasOwnProperty.call(
+                        editingTarget.variables,
+                        e.varId
+                    )
+            ) {
                 // This is a local variable, rename on the current target
                 editingTarget.renameVariable(e.varId, e.newName);
                 // Update all the blocks on the current target that use
                 // this variable
-                editingTarget.blocks.updateBlocksAfterVarRename(e.varId, e.newName);
+                editingTarget.blocks.updateBlocksAfterVarRename(
+                    e.varId,
+                    e.newName
+                );
             } else {
                 // This is a global variable
                 stage.renameVariable(e.varId, e.newName);
@@ -410,14 +460,23 @@ class Blocks {
                 const targets = this.runtime.targets;
                 for (let i = 0; i < targets.length; i++) {
                     const currTarget = targets[i];
-                    currTarget.blocks.updateBlocksAfterVarRename(e.varId, e.newName);
+                    currTarget.blocks.updateBlocksAfterVarRename(
+                        e.varId,
+                        e.newName
+                    );
                 }
             }
             this.emitProjectChanged();
             break;
         case 'var_delete': {
-            const target = (editingTarget && Object.prototype.hasOwnProperty.call(editingTarget.variables, e.varId)) ?
-                editingTarget : stage;
+            const target =
+                    editingTarget &&
+                    Object.prototype.hasOwnProperty.call(
+                        editingTarget.variables,
+                        e.varId
+                    ) ?
+                        editingTarget :
+                        stage;
             target.deleteVariable(e.varId);
             this.emitProjectChanged();
             break;
@@ -425,11 +484,21 @@ class Blocks {
         case 'comment_create':
             if (this.runtime.getEditingTarget()) {
                 const currTarget = this.runtime.getEditingTarget();
-                currTarget.createComment(e.commentId, e.blockId, e.text,
-                    e.xy.x, e.xy.y, e.width, e.height, e.minimized);
+                currTarget.createComment(
+                    e.commentId,
+                    e.blockId,
+                    e.text,
+                    e.xy.x,
+                    e.xy.y,
+                    e.width,
+                    e.height,
+                    e.minimized
+                );
 
-                if (currTarget.comments[e.commentId].x === null &&
-                    currTarget.comments[e.commentId].y === null) {
+                if (
+                    currTarget.comments[e.commentId].x === null &&
+                        currTarget.comments[e.commentId].y === null
+                ) {
                     // Block comments imported from 2.0 projects are imported with their
                     // x and y coordinates set to null so that scratch-blocks can
                     // auto-position them. If we are receiving a create event for these
@@ -445,8 +514,15 @@ class Blocks {
         case 'comment_change':
             if (this.runtime.getEditingTarget()) {
                 const currTarget = this.runtime.getEditingTarget();
-                if (!Object.prototype.hasOwnProperty.call(currTarget.comments, e.commentId)) {
-                    log.warn(`Cannot change comment with id ${e.commentId} because it does not exist.`);
+                if (
+                    !Object.prototype.hasOwnProperty.call(
+                        currTarget.comments,
+                        e.commentId
+                    )
+                ) {
+                    log.warn(
+                        `Cannot change comment with id ${e.commentId} because it does not exist.`
+                    );
                     return;
                 }
                 const comment = currTarget.comments[e.commentId];
@@ -468,8 +544,16 @@ class Blocks {
         case 'comment_move':
             if (this.runtime.getEditingTarget()) {
                 const currTarget = this.runtime.getEditingTarget();
-                if (currTarget && !Object.prototype.hasOwnProperty.call(currTarget.comments, e.commentId)) {
-                    log.warn(`Cannot change comment with id ${e.commentId} because it does not exist.`);
+                if (
+                    currTarget &&
+                        !Object.prototype.hasOwnProperty.call(
+                            currTarget.comments,
+                            e.commentId
+                        )
+                ) {
+                    log.warn(
+                        `Cannot move comment with id ${e.commentId} because it does not exist.`
+                    );
                     return;
                 }
                 const comment = currTarget.comments[e.commentId];
@@ -483,7 +567,12 @@ class Blocks {
         case 'comment_delete':
             if (this.runtime.getEditingTarget()) {
                 const currTarget = this.runtime.getEditingTarget();
-                if (!Object.prototype.hasOwnProperty.call(currTarget.comments, e.commentId)) {
+                if (
+                    !Object.prototype.hasOwnProperty.call(
+                        currTarget.comments,
+                        e.commentId
+                    )
+                ) {
                     // If we're in this state, we have probably received
                     // a delete event from a workspace that we switched from
                     // (e.g. a delete event for a comment on sprite a's workspace
@@ -494,7 +583,9 @@ class Blocks {
                 if (e.blockId) {
                     const block = currTarget.blocks.getBlock(e.blockId);
                     if (!block) {
-                        log.warn(`Could not find block referenced by comment with id: ${e.commentId}`);
+                        log.warn(
+                            `Could not find block referenced by comment with id: ${e.commentId}`
+                        );
                         return;
                     }
                     delete block.comment;
@@ -562,7 +653,9 @@ class Blocks {
      */
     changeBlock (args) {
         // Validate
-        if (['field', 'mutation', 'checkbox'].indexOf(args.element) === -1) return;
+        if (['field', 'mutation', 'checkbox'].indexOf(args.element) === -1) {
+            return;
+        }
         let block = this._blocks[args.id];
         if (typeof block === 'undefined') return;
         switch (args.element) {
@@ -576,13 +669,17 @@ class Blocks {
             // 3. the checkbox should become unchecked if we're not already
             //    monitoring current minute
 
-
             // Update block value
             if (!block.fields[args.name]) return;
-            if (args.name === 'VARIABLE' || args.name === 'LIST' ||
-                args.name === 'BROADCAST_OPTION') {
+            if (
+                args.name === 'VARIABLE' ||
+                    args.name === 'LIST' ||
+                    args.name === 'BROADCAST_OPTION'
+            ) {
                 // Get variable name using the id in args.value.
-                const variable = this.runtime.getEditingTarget().lookupVariableById(args.value);
+                const variable = this.runtime
+                    .getEditingTarget()
+                    .lookupVariableById(args.value);
                 if (variable) {
                     block.fields[args.name].value = variable.name;
                     block.fields[args.name].id = args.value;
@@ -596,19 +693,26 @@ class Blocks {
                 // TODO: (#1787)
                 if (block.opcode === 'sensing_of_object_menu') {
                     if (block.fields.OBJECT.value === '_stage_') {
-                        this._blocks[block.parent].fields.PROPERTY.value = 'backdrop #';
+                        this._blocks[block.parent].fields.PROPERTY.value =
+                                'backdrop #';
                     } else {
-                        this._blocks[block.parent].fields.PROPERTY.value = 'x position';
+                        this._blocks[block.parent].fields.PROPERTY.value =
+                                'x position';
                     }
                     this.runtime.requestBlocksUpdate();
                 }
 
-                const flyoutBlock = block.shadow && block.parent ? this._blocks[block.parent] : block;
+                const flyoutBlock =
+                        block.shadow && block.parent ?
+                            this._blocks[block.parent] :
+                            block;
                 if (flyoutBlock.isMonitored) {
-                    this.runtime.requestUpdateMonitor(Map({
-                        id: flyoutBlock.id,
-                        params: this._getBlockParams(flyoutBlock)
-                    }));
+                    this.runtime.requestUpdateMonitor(
+                        Map({
+                            id: flyoutBlock.id,
+                            params: this._getBlockParams(flyoutBlock)
+                        })
+                    );
                 }
             }
             break;
@@ -619,14 +723,20 @@ class Blocks {
             // A checkbox usually has a one to one correspondence with the monitor
             // block but in the case of monitored reporters that have arguments,
             // map the old id to a new id, creating a new monitor block if necessary
-            if (block.fields && Object.keys(block.fields).length > 0 &&
-                block.opcode !== 'data_variable' && block.opcode !== 'data_listcontents') {
-
+            if (
+                block.fields &&
+                    Object.keys(block.fields).length > 0 &&
+                    block.opcode !== 'data_variable' &&
+                    block.opcode !== 'data_listcontents'
+            ) {
                 // This block has an argument which needs to get separated out into
                 // multiple monitor blocks with ids based on the selected argument
-                const newId = getMonitorIdForBlockWithArgs(block.id, block.fields);
                 // Note: we're not just constantly creating a longer and longer id everytime we check
                 // the checkbox because we're using the id of the block in the flyout as the base
+                const newId = getMonitorIdForBlockWithArgs(
+                    block.id,
+                    block.fields
+                );
 
                 // check if a block with the new id already exists, otherwise create
                 let newBlock = this.runtime.monitorBlocks.getBlock(newId);
@@ -645,19 +755,31 @@ class Blocks {
             // Variable blocks may be sprite specific depending on the owner of the variable
             let isSpriteLocalVariable = false;
             if (block.opcode === 'data_variable') {
-                isSpriteLocalVariable = !(this.runtime.getTargetForStage().variables[block.fields.VARIABLE.id]);
+                isSpriteLocalVariable =
+                        !this.runtime.getTargetForStage().variables[
+                            block.fields.VARIABLE.id
+                        ];
             } else if (block.opcode === 'data_listcontents') {
-                isSpriteLocalVariable = !(this.runtime.getTargetForStage().variables[block.fields.LIST.id]);
+                isSpriteLocalVariable =
+                        !this.runtime.getTargetForStage().variables[
+                            block.fields.LIST.id
+                        ];
             }
 
-            const isSpriteSpecific = isSpriteLocalVariable ||
-                (Object.prototype.hasOwnProperty.call(this.runtime.monitorBlockInfo, block.opcode) &&
-                this.runtime.monitorBlockInfo[block.opcode].isSpriteSpecific);
+            const isSpriteSpecific =
+                    isSpriteLocalVariable ||
+                    (Object.prototype.hasOwnProperty.call(
+                        this.runtime.monitorBlockInfo,
+                        block.opcode
+                    ) &&
+                        this.runtime.monitorBlockInfo[block.opcode]
+                            .isSpriteSpecific);
             if (isSpriteSpecific) {
                 // If creating a new sprite specific monitor, the only possible target is
                 // the current editing one b/c you cannot dynamically create monitors.
                 // Also, do not change the targetId if it has already been assigned
-                block.targetId = block.targetId || this.runtime.getEditingTarget().id;
+                block.targetId =
+                        block.targetId || this.runtime.getEditingTarget().id;
             } else {
                 block.targetId = null;
             }
@@ -667,16 +789,25 @@ class Blocks {
             } else if (!wasMonitored && block.isMonitored) {
                 // Tries to show the monitor for specified block. If it doesn't exist, add the monitor.
                 if (!this.runtime.requestShowMonitor(block.id)) {
-                    this.runtime.requestAddMonitor(MonitorRecord({
-                        id: block.id,
-                        targetId: block.targetId,
-                        spriteName: block.targetId ? this.runtime.getTargetById(block.targetId).getName() : null,
-                        opcode: block.opcode,
-                        params: this._getBlockParams(block),
-                        // @todo(vm#565) for numerical values with decimals, some countries use comma
-                        value: '',
-                        mode: block.opcode === 'data_listcontents' ? 'list' : 'default'
-                    }));
+                    this.runtime.requestAddMonitor(
+                        MonitorRecord({
+                            id: block.id,
+                            targetId: block.targetId,
+                            spriteName: block.targetId ?
+                                this.runtime
+                                    .getTargetById(block.targetId)
+                                    .getName() :
+                                null,
+                            opcode: block.opcode,
+                            params: this._getBlockParams(block),
+                            // @todo(vm#565) for numerical values with decimals, some countries use comma
+                            value: '',
+                            mode:
+                                    block.opcode === 'data_listcontents' ?
+                                        'list' :
+                                        'default'
+                        })
+                    );
                 }
             }
             break;
@@ -705,8 +836,8 @@ class Blocks {
 
         // Move coordinate changes.
         if (e.newCoordinate) {
-
-            didChange = (block.x !== e.newCoordinate.x) || (block.y !== e.newCoordinate.y);
+            didChange =
+                block.x !== e.newCoordinate.x || block.y !== e.newCoordinate.y;
 
             block.x = e.newCoordinate.x;
             block.y = e.newCoordinate.y;
@@ -715,8 +846,10 @@ class Blocks {
         // Remove from any old parent.
         if (typeof e.oldParent !== 'undefined') {
             const oldParent = this._blocks[e.oldParent];
-            if (typeof e.oldInput !== 'undefined' &&
-                oldParent.inputs[e.oldInput].block === e.id) {
+            if (
+                typeof e.oldInput !== 'undefined' &&
+                oldParent.inputs[e.oldInput].block === e.id
+            ) {
                 // This block was connected to the old parent's input.
                 oldParent.inputs[e.oldInput].block = null;
             } else if (oldParent.next === e.id) {
@@ -741,8 +874,14 @@ class Blocks {
                 // Moved to the new parent's input.
                 // Don't obscure the shadow block.
                 let oldShadow = null;
-                if (Object.prototype.hasOwnProperty.call(this._blocks[e.newParent].inputs, e.newInput)) {
-                    oldShadow = this._blocks[e.newParent].inputs[e.newInput].shadow;
+                if (
+                    Object.prototype.hasOwnProperty.call(
+                        this._blocks[e.newParent].inputs,
+                        e.newInput
+                    )
+                ) {
+                    oldShadow =
+                        this._blocks[e.newParent].inputs[e.newInput].shadow;
                 }
 
                 // If the block being attached is itself a shadow, make sure to set
@@ -764,7 +903,6 @@ class Blocks {
         if (didChange) this.emitProjectChanged();
     }
 
-
     /**
      * Block management: run all blocks.
      * @param {!object} runtime Runtime to run all blocks in.
@@ -777,7 +915,9 @@ class Blocks {
                     const targetId = this.getBlock(blockId).targetId;
                     return {
                         blockId,
-                        target: targetId ? runtime.getTargetById(targetId) : null
+                        target: targetId ?
+                            runtime.getTargetById(targetId) :
+                            null
                     };
                 });
         }
@@ -816,8 +956,10 @@ class Blocks {
                 this.deleteBlock(block.inputs[input].block);
             }
             // Delete obscured shadow blocks.
-            if (block.inputs[input].shadow !== null &&
-                block.inputs[input].shadow !== block.inputs[input].block) {
+            if (
+                block.inputs[input].shadow !== null &&
+                block.inputs[input].shadow !== block.inputs[input].block
+            ) {
                 this.deleteBlock(block.inputs[input].shadow);
             }
         }
@@ -863,7 +1005,10 @@ class Blocks {
             } else if (blocks[blockId].fields.LIST) {
                 varOrListField = blocks[blockId].fields.LIST;
                 varType = Variable.LIST_TYPE;
-            } else if (optIncludeBroadcast && blocks[blockId].fields.BROADCAST_OPTION) {
+            } else if (
+                optIncludeBroadcast &&
+                blocks[blockId].fields.BROADCAST_OPTION
+            ) {
                 varOrListField = blocks[blockId].fields.BROADCAST_OPTION;
                 varType = Variable.BROADCAST_MESSAGE_TYPE;
             }
@@ -875,10 +1020,12 @@ class Blocks {
                         type: varType
                     });
                 } else {
-                    allReferences[currVarId] = [{
-                        referencingField: varOrListField,
-                        type: varType
-                    }];
+                    allReferences[currVarId] = [
+                        {
+                            referencingField: varOrListField,
+                            type: varType
+                        }
+                    ];
                 }
             }
         }
@@ -915,9 +1062,15 @@ class Blocks {
     updateTargetSpecificBlocks (isStage) {
         const blocks = this._blocks;
         for (const blockId in blocks) {
-            if (isStage && blocks[blockId].opcode === 'event_whenthisspriteclicked') {
+            if (
+                isStage &&
+                blocks[blockId].opcode === 'event_whenthisspriteclicked'
+            ) {
                 blocks[blockId].opcode = 'event_whenstageclicked';
-            } else if (!isStage && blocks[blockId].opcode === 'event_whenstageclicked') {
+            } else if (
+                !isStage &&
+                blocks[blockId].opcode === 'event_whenstageclicked'
+            ) {
                 blocks[blockId].opcode = 'event_whenthisspriteclicked';
             }
         }
@@ -967,10 +1120,12 @@ class Blocks {
         let blockUpdated = false;
         for (const blockId in blocks) {
             const block = blocks[blockId];
-            if (block.opcode === 'sensing_of' &&
+            if (
+                block.opcode === 'sensing_of' &&
                 block.fields.PROPERTY.value === oldName &&
                 // If block and shadow are different, it means a block is inserted to OBJECT, and should be ignored.
-                block.inputs.OBJECT.block === block.inputs.OBJECT.shadow) {
+                block.inputs.OBJECT.block === block.inputs.OBJECT.shadow
+            ) {
                 const inputBlock = this.getBlock(block.inputs.OBJECT.block);
                 if (inputBlock.fields.OBJECT.value === targetName) {
                     block.fields.PROPERTY.value = newName;
@@ -991,7 +1146,10 @@ class Blocks {
      */
     _getCostumeField (blockId) {
         const block = this.getBlock(blockId);
-        if (block && Object.prototype.hasOwnProperty.call(block.fields, 'COSTUME')) {
+        if (
+            block &&
+            Object.prototype.hasOwnProperty.call(block.fields, 'COSTUME')
+        ) {
             return block.fields.COSTUME;
         }
         return null;
@@ -1006,7 +1164,10 @@ class Blocks {
      */
     _getSoundField (blockId) {
         const block = this.getBlock(blockId);
-        if (block && Object.prototype.hasOwnProperty.call(block.fields, 'SOUND_MENU')) {
+        if (
+            block &&
+            Object.prototype.hasOwnProperty.call(block.fields, 'SOUND_MENU')
+        ) {
             return block.fields.SOUND_MENU;
         }
         return null;
@@ -1021,7 +1182,10 @@ class Blocks {
      */
     _getBackdropField (blockId) {
         const block = this.getBlock(blockId);
-        if (block && Object.prototype.hasOwnProperty.call(block.fields, 'BACKDROP')) {
+        if (
+            block &&
+            Object.prototype.hasOwnProperty.call(block.fields, 'BACKDROP')
+        ) {
             return block.fields.BACKDROP;
         }
         return null;
@@ -1039,8 +1203,15 @@ class Blocks {
         if (!block) {
             return null;
         }
-        const spriteMenuNames = ['TOWARDS', 'TO', 'OBJECT', 'VIDEOONMENU2',
-            'DISTANCETOMENU', 'TOUCHINGOBJECTMENU', 'CLONE_OPTION'];
+        const spriteMenuNames = [
+            'TOWARDS',
+            'TO',
+            'OBJECT',
+            'VIDEOONMENU2',
+            'DISTANCETOMENU',
+            'TOUCHINGOBJECTMENU',
+            'CLONE_OPTION'
+        ];
         for (let i = 0; i < spriteMenuNames.length; i++) {
             const menuName = spriteMenuNames[i];
             if (Object.prototype.hasOwnProperty.call(block.fields, menuName)) {
@@ -1059,7 +1230,9 @@ class Blocks {
      * @return {string} String of XML representing this object's blocks.
      */
     toXML (comments) {
-        return this._scripts.map(script => this.blockToXML(script, comments)).join();
+        return this._scripts
+            .map(script => this.blockToXML(script, comments))
+            .join();
     }
 
     /**
@@ -1076,9 +1249,8 @@ class Blocks {
         // this early exit allows the project to load.
         if (!block) return;
         // Encode properties of this block.
-        const tagName = (block.shadow) ? 'shadow' : 'block';
-        let xmlString =
-            `<${tagName}
+        const tagName = block.shadow ? 'shadow' : 'block';
+        let xmlString = `<${tagName}
                 id="${block.id}"
                 type="${block.opcode}"
                 ${block.topLevel ? `x="${block.x}" y="${block.y}"` : ''}
@@ -1089,10 +1261,14 @@ class Blocks {
                 if (Object.prototype.hasOwnProperty.call(comments, commentId)) {
                     xmlString += comments[commentId].toXML();
                 } else {
-                    log.warn(`Could not find comment with id: ${commentId} in provided comment descriptions.`);
+                    log.warn(
+                        `Could not find comment with id: ${commentId} in provided comment descriptions.`
+                    );
                 }
             } else {
-                log.warn(`Cannot serialize comment with id: ${commentId}; no comment descriptions provided.`);
+                log.warn(
+                    `Cannot serialize comment with id: ${commentId}; no comment descriptions provided.`
+                );
             }
         }
         // Add any mutation. Must come before inputs.
@@ -1101,7 +1277,9 @@ class Blocks {
         }
         // Add any inputs on this block.
         for (const input in block.inputs) {
-            if (!Object.prototype.hasOwnProperty.call(block.inputs, input)) continue;
+            if (!Object.prototype.hasOwnProperty.call(block.inputs, input)) {
+                continue;
+            }
             const blockInput = block.inputs[input];
             // Only encode a value tag if the value input is occupied.
             if (blockInput.block || blockInput.shadow) {
@@ -1109,7 +1287,10 @@ class Blocks {
                 if (blockInput.block) {
                     xmlString += this.blockToXML(blockInput.block, comments);
                 }
-                if (blockInput.shadow && blockInput.shadow !== blockInput.block) {
+                if (
+                    blockInput.shadow &&
+                    blockInput.shadow !== blockInput.block
+                ) {
                     // Obscured shadow.
                     xmlString += this.blockToXML(blockInput.shadow, comments);
                 }
@@ -1118,7 +1299,9 @@ class Blocks {
         }
         // Add any fields on this block.
         for (const field in block.fields) {
-            if (!Object.prototype.hasOwnProperty.call(block.fields, field)) continue;
+            if (!Object.prototype.hasOwnProperty.call(block.fields, field)) {
+                continue;
+            }
             const blockField = block.fields[field];
             xmlString += `<field name="${blockField.name}"`;
             const fieldId = blockField.id;
@@ -1137,7 +1320,10 @@ class Blocks {
         }
         // Add blocks connected to the next connection.
         if (block.next) {
-            xmlString += `<next>${this.blockToXML(block.next, comments)}</next>`;
+            xmlString += `<next>${this.blockToXML(
+                block.next,
+                comments
+            )}</next>`;
         }
         xmlString += `</${tagName}>`;
         return xmlString;
@@ -1152,8 +1338,10 @@ class Blocks {
         let mutationString = `<${mutation.tagName}`;
         for (const prop in mutation) {
             if (prop === 'children' || prop === 'tagName') continue;
-            let mutationValue = (typeof mutation[prop] === 'string') ?
-                xmlEscape(mutation[prop]) : mutation[prop];
+            let mutationValue =
+                typeof mutation[prop] === 'string' ?
+                    xmlEscape(mutation[prop]) :
+                    mutation[prop];
 
             // Handle dynamic extension blocks
             if (prop === 'blockInfo') {
diff --git a/src/engine/runtime.js b/src/engine/runtime.js
index 452ff51c2..4a34e3cb8 100644
--- a/src/engine/runtime.js
+++ b/src/engine/runtime.js
@@ -385,7 +385,8 @@ class Runtime extends EventEmitter {
          * being added.
          * @type {function}
          */
-        this.addCloudVariable = this._initializeAddCloudVariable(newCloudDataManager);
+        this.addCloudVariable =
+            this._initializeAddCloudVariable(newCloudDataManager);
 
         /**
          * A function which updates the runtime's cloud variable limit
@@ -393,7 +394,8 @@ class Runtime extends EventEmitter {
          * if the last of the cloud variables is being removed.
          * @type {function}
          */
-        this.removeCloudVariable = this._initializeRemoveCloudVariable(newCloudDataManager);
+        this.removeCloudVariable =
+            this._initializeRemoveCloudVariable(newCloudDataManager);
 
         /**
          * A string representing the origin of the current project from outside of the
@@ -737,24 +739,24 @@ class Runtime extends EventEmitter {
     // Helper function for initializing the addCloudVariable function
     _initializeAddCloudVariable (newCloudDataManager) {
         // The addCloudVariable function
-        return (() => {
+        return () => {
             const hadCloudVarsBefore = this.hasCloudData();
             newCloudDataManager.addCloudVariable();
             if (!hadCloudVarsBefore && this.hasCloudData()) {
                 this.emit(Runtime.HAS_CLOUD_DATA_UPDATE, true);
             }
-        });
+        };
     }
 
     // Helper function for initializing the removeCloudVariable function
     _initializeRemoveCloudVariable (newCloudDataManager) {
-        return (() => {
+        return () => {
             const hadCloudVarsBefore = this.hasCloudData();
             newCloudDataManager.removeCloudVariable();
             if (hadCloudVarsBefore && !this.hasCloudData()) {
                 this.emit(Runtime.HAS_CLOUD_DATA_UPDATE, false);
             }
-        });
+        };
     }
 
     /**
@@ -764,14 +766,26 @@ class Runtime extends EventEmitter {
      */
     _registerBlockPackages () {
         for (const packageName in defaultBlockPackages) {
-            if (Object.prototype.hasOwnProperty.call(defaultBlockPackages, packageName)) {
+            if (
+                Object.prototype.hasOwnProperty.call(
+                    defaultBlockPackages,
+                    packageName
+                )
+            ) {
                 // @todo pass a different runtime depending on package privilege?
-                const packageObject = new (defaultBlockPackages[packageName])(this);
+                const packageObject = new defaultBlockPackages[packageName](
+                    this
+                );
                 // Collect primitives from package.
                 if (packageObject.getPrimitives) {
                     const packagePrimitives = packageObject.getPrimitives();
                     for (const op in packagePrimitives) {
-                        if (Object.prototype.hasOwnProperty.call(packagePrimitives, op)) {
+                        if (
+                            Object.prototype.hasOwnProperty.call(
+                                packagePrimitives,
+                                op
+                            )
+                        ) {
                             this._primitives[op] =
                                 packagePrimitives[op].bind(packageObject);
                         }
@@ -781,14 +795,23 @@ class Runtime extends EventEmitter {
                 if (packageObject.getHats) {
                     const packageHats = packageObject.getHats();
                     for (const hatName in packageHats) {
-                        if (Object.prototype.hasOwnProperty.call(packageHats, hatName)) {
+                        if (
+                            Object.prototype.hasOwnProperty.call(
+                                packageHats,
+                                hatName
+                            )
+                        ) {
                             this._hats[hatName] = packageHats[hatName];
                         }
                     }
                 }
                 // Collect monitored from package.
                 if (packageObject.getMonitored) {
-                    this.monitorBlockInfo = Object.assign({}, this.monitorBlockInfo, packageObject.getMonitored());
+                    this.monitorBlockInfo = Object.assign(
+                        {},
+                        this.monitorBlockInfo,
+                        packageObject.getMonitored()
+                    );
                 }
             }
         }
@@ -818,7 +841,9 @@ class Runtime extends EventEmitter {
         const context = {};
         target = target || this.getEditingTarget() || this.getTargetForStage();
         if (target) {
-            context.targetType = (target.isStage ? TargetType.STAGE : TargetType.SPRITE);
+            context.targetType = target.isStage ?
+                TargetType.STAGE :
+                TargetType.SPRITE;
         }
     }
 
@@ -851,8 +876,14 @@ class Runtime extends EventEmitter {
         this._fillExtensionCategory(categoryInfo, extensionInfo);
 
         for (const fieldTypeName in categoryInfo.customFieldTypes) {
-            if (Object.prototype.hasOwnProperty.call(extensionInfo.customFieldTypes, fieldTypeName)) {
-                const fieldTypeInfo = categoryInfo.customFieldTypes[fieldTypeName];
+            if (
+                Object.prototype.hasOwnProperty.call(
+                    extensionInfo.customFieldTypes,
+                    fieldTypeName
+                )
+            ) {
+                const fieldTypeInfo =
+                    categoryInfo.customFieldTypes[fieldTypeName];
 
                 // Emit events for custom field types from extension
                 this.emit(Runtime.EXTENSION_FIELD_ADDED, {
@@ -871,7 +902,9 @@ class Runtime extends EventEmitter {
      * @private
      */
     _refreshExtensionPrimitives (extensionInfo) {
-        const categoryInfo = this._blockInfo.find(info => info.id === extensionInfo.id);
+        const categoryInfo = this._blockInfo.find(
+            info => info.id === extensionInfo.id
+        );
         if (categoryInfo) {
             categoryInfo.name = maybeFormatMessage(extensionInfo.name);
             this._fillExtensionCategory(categoryInfo, extensionInfo);
@@ -894,15 +927,29 @@ class Runtime extends EventEmitter {
         categoryInfo.menuInfo = {};
 
         for (const menuName in extensionInfo.menus) {
-            if (Object.prototype.hasOwnProperty.call(extensionInfo.menus, menuName)) {
+            if (
+                Object.prototype.hasOwnProperty.call(
+                    extensionInfo.menus,
+                    menuName
+                )
+            ) {
                 const menuInfo = extensionInfo.menus[menuName];
-                const convertedMenu = this._buildMenuForScratchBlocks(menuName, menuInfo, categoryInfo);
+                const convertedMenu = this._buildMenuForScratchBlocks(
+                    menuName,
+                    menuInfo,
+                    categoryInfo
+                );
                 categoryInfo.menus.push(convertedMenu);
                 categoryInfo.menuInfo[menuName] = menuInfo;
             }
         }
         for (const fieldTypeName in extensionInfo.customFieldTypes) {
-            if (Object.prototype.hasOwnProperty.call(extensionInfo.customFieldTypes, fieldTypeName)) {
+            if (
+                Object.prototype.hasOwnProperty.call(
+                    extensionInfo.customFieldTypes,
+                    fieldTypeName
+                )
+            ) {
                 const fieldType = extensionInfo.customFieldTypes[fieldTypeName];
                 const fieldTypeInfo = this._buildCustomFieldInfo(
                     fieldTypeName,
@@ -917,22 +964,32 @@ class Runtime extends EventEmitter {
 
         for (const blockInfo of extensionInfo.blocks) {
             try {
-                const convertedBlock = this._convertForScratchBlocks(blockInfo, categoryInfo);
+                const convertedBlock = this._convertForScratchBlocks(
+                    blockInfo,
+                    categoryInfo
+                );
                 categoryInfo.blocks.push(convertedBlock);
                 if (convertedBlock.json) {
                     const opcode = convertedBlock.json.type;
                     if (blockInfo.blockType !== BlockType.EVENT) {
                         this._primitives[opcode] = convertedBlock.info.func;
                     }
-                    if (blockInfo.blockType === BlockType.EVENT || blockInfo.blockType === BlockType.HAT) {
+                    if (
+                        blockInfo.blockType === BlockType.EVENT ||
+                        blockInfo.blockType === BlockType.HAT
+                    ) {
                         this._hats[opcode] = {
                             edgeActivated: blockInfo.isEdgeActivated,
-                            restartExistingThreads: blockInfo.shouldRestartExistingThreads
+                            restartExistingThreads:
+                                blockInfo.shouldRestartExistingThreads
                         };
                     }
                 }
             } catch (e) {
-                log.error('Error parsing block: ', {block: blockInfo, error: e});
+                log.error('Error parsing block: ', {
+                    block: blockInfo,
+                    error: e
+                });
             }
         }
     }
@@ -948,14 +1005,25 @@ class Runtime extends EventEmitter {
         if (typeof menuItems !== 'function') {
             const extensionMessageContext = this.makeMessageContextForTarget();
             return menuItems.map(item => {
-                const formattedItem = maybeFormatMessage(item, extensionMessageContext);
+                const formattedItem = maybeFormatMessage(
+                    item,
+                    extensionMessageContext
+                );
                 switch (typeof formattedItem) {
                 case 'string':
                     return [formattedItem, formattedItem];
                 case 'object':
-                    return [maybeFormatMessage(item.text, extensionMessageContext), item.value];
+                    return [
+                        maybeFormatMessage(
+                            item.text,
+                            extensionMessageContext
+                        ),
+                        item.value
+                    ];
                 default:
-                    throw new Error(`Can't interpret menu item: ${JSON.stringify(item)}`);
+                    throw new Error(
+                        `Can't interpret menu item: ${JSON.stringify(item)}`
+                    );
                 }
             });
         }
@@ -985,7 +1053,8 @@ class Runtime extends EventEmitter {
                 colourSecondary: categoryInfo.color2,
                 colourTertiary: categoryInfo.color3,
                 outputShape: menuInfo.acceptReporters ?
-                    ScratchBlocksConstants.OUTPUT_SHAPE_ROUND : ScratchBlocksConstants.OUTPUT_SHAPE_SQUARE,
+                    ScratchBlocksConstants.OUTPUT_SHAPE_ROUND :
+                    ScratchBlocksConstants.OUTPUT_SHAPE_SQUARE,
                 args0: [
                     {
                         type: 'field_dropdown',
@@ -1027,7 +1096,12 @@ class Runtime extends EventEmitter {
      * @param {object} categoryInfo - The category the field belongs to (Used to set its colors)
      * @returns {object} - Object to be inserted into scratch-blocks
      */
-    _buildCustomFieldTypeForScratchBlocks (fieldName, output, outputShape, categoryInfo) {
+    _buildCustomFieldTypeForScratchBlocks (
+        fieldName,
+        output,
+        outputShape,
+        categoryInfo
+    ) {
         return {
             json: {
                 type: fieldName,
@@ -1114,15 +1188,13 @@ class Runtime extends EventEmitter {
             const separatorJSON = {
                 type: 'field_vertical_separator'
             };
-            blockJSON.args0 = [
-                iconJSON,
-                separatorJSON
-            ];
+            blockJSON.args0 = [iconJSON, separatorJSON];
         }
 
         switch (blockInfo.blockType) {
         case BlockType.COMMAND:
-            blockJSON.outputShape = ScratchBlocksConstants.OUTPUT_SHAPE_SQUARE;
+            blockJSON.outputShape =
+                    ScratchBlocksConstants.OUTPUT_SHAPE_SQUARE;
             blockJSON.previousStatement = null; // null = available connection; undefined = hat
             if (!blockInfo.isTerminal) {
                 blockJSON.nextStatement = null; // null = available connection; undefined = terminal
@@ -1130,25 +1202,34 @@ class Runtime extends EventEmitter {
             break;
         case BlockType.REPORTER:
             blockJSON.output = 'String'; // TODO: distinguish number & string here?
-            blockJSON.outputShape = ScratchBlocksConstants.OUTPUT_SHAPE_ROUND;
+            blockJSON.outputShape =
+                    ScratchBlocksConstants.OUTPUT_SHAPE_ROUND;
             break;
         case BlockType.BOOLEAN:
             blockJSON.output = 'Boolean';
-            blockJSON.outputShape = ScratchBlocksConstants.OUTPUT_SHAPE_HEXAGONAL;
+            blockJSON.outputShape =
+                    ScratchBlocksConstants.OUTPUT_SHAPE_HEXAGONAL;
             break;
         case BlockType.HAT:
         case BlockType.EVENT:
-            if (!Object.prototype.hasOwnProperty.call(blockInfo, 'isEdgeActivated')) {
+            if (
+                !Object.prototype.hasOwnProperty.call(
+                    blockInfo,
+                    'isEdgeActivated'
+                )
+            ) {
                 // if absent, this property defaults to true
                 blockInfo.isEdgeActivated = true;
             }
-            blockJSON.outputShape = ScratchBlocksConstants.OUTPUT_SHAPE_SQUARE;
+            blockJSON.outputShape =
+                    ScratchBlocksConstants.OUTPUT_SHAPE_SQUARE;
             blockJSON.nextStatement = null; // null = available connection; undefined = terminal
             break;
         case BlockType.CONDITIONAL:
         case BlockType.LOOP:
             blockInfo.branchCount = blockInfo.branchCount || 1;
-            blockJSON.outputShape = ScratchBlocksConstants.OUTPUT_SHAPE_SQUARE;
+            blockJSON.outputShape =
+                    ScratchBlocksConstants.OUTPUT_SHAPE_SQUARE;
             blockJSON.previousStatement = null; // null = available connection; undefined = hat
             if (!blockInfo.isTerminal) {
                 blockJSON.nextStatement = null; // null = available connection; undefined = terminal
@@ -1156,19 +1237,33 @@ class Runtime extends EventEmitter {
             break;
         }
 
-        const blockText = Array.isArray(blockInfo.text) ? blockInfo.text : [blockInfo.text];
+        const blockText = Array.isArray(blockInfo.text) ?
+            blockInfo.text :
+            [blockInfo.text];
         let inTextNum = 0; // text for the next block "arm" is blockText[inTextNum]
         let inBranchNum = 0; // how many branches have we placed into the JSON so far?
         let outLineNum = 0; // used for scratch-blocks `message${outLineNum}` and `args${outLineNum}`
-        const convertPlaceholders = this._convertPlaceholders.bind(this, context);
+        const convertPlaceholders = this._convertPlaceholders.bind(
+            this,
+            context
+        );
         const extensionMessageContext = this.makeMessageContextForTarget();
 
         // alternate between a block "arm" with text on it and an open slot for a substack
-        while (inTextNum < blockText.length || inBranchNum < blockInfo.branchCount) {
+        while (
+            inTextNum < blockText.length ||
+            inBranchNum < blockInfo.branchCount
+        ) {
             if (inTextNum < blockText.length) {
                 context.outLineNum = outLineNum;
-                const lineText = maybeFormatMessage(blockText[inTextNum], extensionMessageContext);
-                const convertedText = lineText.replace(/\[(.+?)]/g, convertPlaceholders);
+                const lineText = maybeFormatMessage(
+                    blockText[inTextNum],
+                    extensionMessageContext
+                );
+                const convertedText = lineText.replace(
+                    /\[(.+?)]/g,
+                    convertPlaceholders
+                );
                 if (blockJSON[`message${outLineNum}`]) {
                     blockJSON[`message${outLineNum}`] += convertedText;
                 } else {
@@ -1179,10 +1274,14 @@ class Runtime extends EventEmitter {
             }
             if (inBranchNum < blockInfo.branchCount) {
                 blockJSON[`message${outLineNum}`] = '%1';
-                blockJSON[`args${outLineNum}`] = [{
-                    type: 'input_statement',
-                    name: `SUBSTACK${inBranchNum > 0 ? inBranchNum + 1 : ''}`
-                }];
+                blockJSON[`args${outLineNum}`] = [
+                    {
+                        type: 'input_statement',
+                        name: `SUBSTACK${
+                            inBranchNum > 0 ? inBranchNum + 1 : ''
+                        }`
+                    }
+                ];
                 ++inBranchNum;
                 ++outLineNum;
             }
@@ -1196,18 +1295,22 @@ class Runtime extends EventEmitter {
             // Add icon to the bottom right of a loop block
             blockJSON[`lastDummyAlign${outLineNum}`] = 'RIGHT';
             blockJSON[`message${outLineNum}`] = '%1';
-            blockJSON[`args${outLineNum}`] = [{
-                type: 'field_image',
-                src: './static/blocks-media/repeat.svg', // TODO: use a constant or make this configurable?
-                width: 24,
-                height: 24,
-                alt: '*', // TODO remove this since we don't use collapsed blocks in scratch
-                flip_rtl: true
-            }];
+            blockJSON[`args${outLineNum}`] = [
+                {
+                    type: 'field_image',
+                    src: './static/blocks-media/repeat.svg', // TODO: use a constant or make this configurable?
+                    width: 24,
+                    height: 24,
+                    alt: '*', // TODO remove this since we don't use collapsed blocks in scratch
+                    flip_rtl: true
+                }
+            ];
             ++outLineNum;
         }
 
-        const mutation = blockInfo.isDynamic ? `<mutation blockInfo="${xmlEscape(JSON.stringify(blockInfo))}"/>` : '';
+        const mutation = blockInfo.isDynamic ?
+            `<mutation blockInfo="${xmlEscape(JSON.stringify(blockInfo))}"/>` :
+            '';
         const inputs = context.inputList.join('');
         const blockXML = `<block type="${extendedOpcode}">${mutation}${inputs}</block>`;
 
@@ -1242,13 +1345,22 @@ class Runtime extends EventEmitter {
      */
     _convertButtonForScratchBlocks (buttonInfo) {
         // for now we only support these pre-defined callbacks handled in scratch-blocks
-        const supportedCallbackKeys = ['MAKE_A_LIST', 'MAKE_A_PROCEDURE', 'MAKE_A_VARIABLE'];
+        const supportedCallbackKeys = [
+            'MAKE_A_LIST',
+            'MAKE_A_PROCEDURE',
+            'MAKE_A_VARIABLE'
+        ];
         if (supportedCallbackKeys.indexOf(buttonInfo.func) < 0) {
-            log.error(`Custom button callbacks not supported yet: ${buttonInfo.func}`);
+            log.error(
+                `Custom button callbacks not supported yet: ${buttonInfo.func}`
+            );
         }
 
         const extensionMessageContext = this.makeMessageContextForTarget();
-        const buttonText = maybeFormatMessage(buttonInfo.text, extensionMessageContext);
+        const buttonText = maybeFormatMessage(
+            buttonInfo.text,
+            extensionMessageContext
+        );
         return {
             info: buttonInfo,
             xml: `<button text="${buttonText}" callbackKey="${buttonInfo.func}"></button>`
@@ -1263,7 +1375,9 @@ class Runtime extends EventEmitter {
      */
     _constructInlineImageJson (argInfo) {
         if (!argInfo.dataURI) {
-            log.warn('Missing data URI in extension block with argument type IMAGE');
+            log.warn(
+                'Missing data URI in extension block with argument type IMAGE'
+            );
         }
         return {
             type: 'field_image',
@@ -1296,8 +1410,13 @@ class Runtime extends EventEmitter {
         let argTypeInfo = ArgumentTypeMap[argInfo.type] || {};
 
         // Field type not a standard field type, see if extension has registered custom field type
-        if (!ArgumentTypeMap[argInfo.type] && context.categoryInfo.customFieldTypes[argInfo.type]) {
-            argTypeInfo = context.categoryInfo.customFieldTypes[argInfo.type].argumentTypeInfo;
+        if (
+            !ArgumentTypeMap[argInfo.type] &&
+            context.categoryInfo.customFieldTypes[argInfo.type]
+        ) {
+            argTypeInfo =
+                context.categoryInfo.customFieldTypes[argInfo.type]
+                    .argumentTypeInfo;
         }
 
         // Start to construct the scratch-blocks style JSON defining how the block should be
@@ -1318,8 +1437,14 @@ class Runtime extends EventEmitter {
             };
 
             const defaultValue =
-                typeof argInfo.defaultValue === 'undefined' ? '' :
-                    xmlEscape(maybeFormatMessage(argInfo.defaultValue, this.makeMessageContextForTarget()).toString());
+                typeof argInfo.defaultValue === 'undefined' ?
+                    '' :
+                    xmlEscape(
+                        maybeFormatMessage(
+                            argInfo.defaultValue,
+                            this.makeMessageContextForTarget()
+                        ).toString()
+                    );
 
             if (argTypeInfo.check) {
                 // Right now the only type of 'check' we have specifies that the
@@ -1335,7 +1460,10 @@ class Runtime extends EventEmitter {
                 const menuInfo = context.categoryInfo.menuInfo[argInfo.menu];
                 if (menuInfo.acceptReporters) {
                     valueName = placeholder;
-                    shadowType = this._makeExtensionMenuId(argInfo.menu, context.categoryInfo.id);
+                    shadowType = this._makeExtensionMenuId(
+                        argInfo.menu,
+                        context.categoryInfo.id
+                    );
                     fieldName = argInfo.menu;
                 } else {
                     argJSON.type = 'field_dropdown';
@@ -1346,8 +1474,11 @@ class Runtime extends EventEmitter {
                 }
             } else {
                 valueName = placeholder;
-                shadowType = (argTypeInfo.shadow && argTypeInfo.shadow.type) || null;
-                fieldName = (argTypeInfo.shadow && argTypeInfo.shadow.fieldName) || null;
+                shadowType =
+                    (argTypeInfo.shadow && argTypeInfo.shadow.type) || null;
+                fieldName =
+                    (argTypeInfo.shadow && argTypeInfo.shadow.fieldName) ||
+                    null;
             }
 
             // <value> is the ScratchBlocks name for a block input.
@@ -1364,7 +1495,9 @@ class Runtime extends EventEmitter {
             // A <field> displays a dynamic value: a user-editable text field, a drop-down menu, etc.
             // Leave out the field if defaultValue or fieldName are not specified
             if (defaultValue && fieldName) {
-                context.inputList.push(`<field name="${fieldName}">${defaultValue}</field>`);
+                context.inputList.push(
+                    `<field name="${fieldName}">${defaultValue}</field>`
+                );
             }
 
             if (shadowType) {
@@ -1377,7 +1510,8 @@ class Runtime extends EventEmitter {
         }
 
         const argsName = `args${context.outLineNum}`;
-        const blockArgs = (context.blockJSON[argsName] = context.blockJSON[argsName] || []);
+        const blockArgs = (context.blockJSON[argsName] =
+            context.blockJSON[argsName] || []);
         if (argJSON) blockArgs.push(argJSON);
         const argNum = blockArgs.length;
         context.argsMap[placeholder] = argNum;
@@ -1419,8 +1553,7 @@ class Runtime extends EventEmitter {
             } else if (categoryInfo.blockIconURI) {
                 menuIconURI = categoryInfo.blockIconURI;
             }
-            const menuIconXML = menuIconURI ?
-                `iconURI="${menuIconURI}"` : '';
+            const menuIconXML = menuIconURI ? `iconURI="${menuIconURI}"` : '';
 
             let statusButtonXML = '';
             if (categoryInfo.showStatusButton) {
@@ -1429,8 +1562,11 @@ class Runtime extends EventEmitter {
 
             return {
                 id: categoryInfo.id,
-                xml: `<category name="${name}" id="${categoryInfo.id}" ${statusButtonXML} ${colorXML} ${menuIconXML}>${
-                    paletteBlocks.map(block => block.xml).join('')}</category>`
+                xml: `<category name="${name}" id="${
+                    categoryInfo.id
+                }" ${statusButtonXML} ${colorXML} ${menuIconXML}>${paletteBlocks
+                    .map(block => block.xml)
+                    .join('')}</category>`
             };
         });
     }
@@ -1440,7 +1576,12 @@ class Runtime extends EventEmitter {
      */
     getBlocksJSON () {
         return this._blockInfo.reduce(
-            (result, categoryInfo) => result.concat(categoryInfo.blocks.map(blockInfo => blockInfo.json)), []);
+            (result, categoryInfo) =>
+                result.concat(
+                    categoryInfo.blocks.map(blockInfo => blockInfo.json)
+                ),
+            []
+        );
     }
 
     /**
@@ -1449,7 +1590,8 @@ class Runtime extends EventEmitter {
     _initScratchLink () {
         // Check that we're actually in a real browser, not Node.js or JSDOM, and we have a valid-looking origin.
         // note that `if (self?....)` will throw if `self` is undefined, so check for that first!
-        if (typeof self !== 'undefined' &&
+        if (
+            typeof self !== 'undefined' &&
             typeof document !== 'undefined' &&
             document.getElementById &&
             self.origin &&
@@ -1462,7 +1604,9 @@ class Runtime extends EventEmitter {
             )
         ) {
             // Create a script tag for the Scratch Link browser extension, unless one already exists
-            const scriptElement = document.getElementById('scratch-link-extension-script');
+            const scriptElement = document.getElementById(
+                'scratch-link-extension-script'
+            );
             if (!scriptElement) {
                 const script = document.createElement('script');
                 script.id = 'scratch-link-extension-script';
@@ -1481,7 +1625,8 @@ class Runtime extends EventEmitter {
      * @returns {ScratchLinkSocket} The scratch link socket.
      */
     getScratchLinkSocket (type) {
-        const factory = this._linkSocketFactory || this._defaultScratchLinkSocketFactory;
+        const factory =
+            this._linkSocketFactory || this._defaultScratchLinkSocketFactory;
         return factory(type);
     }
 
@@ -1501,10 +1646,15 @@ class Runtime extends EventEmitter {
      */
     _defaultScratchLinkSocketFactory (type) {
         const Scratch = self.Scratch;
-        const ScratchLinkSafariSocket = Scratch && Scratch.ScratchLinkSafariSocket;
+        const ScratchLinkSafariSocket =
+            Scratch && Scratch.ScratchLinkSafariSocket;
         // detect this every time in case the user turns on the extension after loading the page
-        const useSafariSocket = ScratchLinkSafariSocket && ScratchLinkSafariSocket.isSafariHelperCompatible();
-        return useSafariSocket ? new ScratchLinkSafariSocket(type) : new ScratchLinkWebSocket(type);
+        const useSafariSocket =
+            ScratchLinkSafariSocket &&
+            ScratchLinkSafariSocket.isSafariHelperCompatible();
+        return useSafariSocket ?
+            new ScratchLinkSafariSocket(type) :
+            new ScratchLinkWebSocket(type);
     }
 
     /**
@@ -1593,11 +1743,12 @@ class Runtime extends EventEmitter {
      * @return {boolean} True if the op is known to be a edge-activated hat.
      */
     getIsEdgeActivatedHat (opcode) {
-        return Object.prototype.hasOwnProperty.call(this._hats, opcode) &&
-            this._hats[opcode].edgeActivated;
+        return (
+            Object.prototype.hasOwnProperty.call(this._hats, opcode) &&
+            this._hats[opcode].edgeActivated
+        );
     }
 
-
     /**
      * Attach the audio engine
      * @param {!AudioEngine} audioEngine The audio engine to attach
@@ -1701,10 +1852,10 @@ class Runtime extends EventEmitter {
      */
     isActiveThread (thread) {
         return (
-            (
-                thread.stack.length > 0 &&
-                thread.status !== Thread.STATUS_DONE) &&
-            this.threads.indexOf(thread) > -1);
+            thread.stack.length > 0 &&
+            thread.status !== Thread.STATUS_DONE &&
+            this.threads.indexOf(thread) > -1
+        );
     }
 
     /**
@@ -1729,18 +1880,29 @@ class Runtime extends EventEmitter {
      *     determines whether we show a visual report when turning on the script.
      */
     toggleScript (topBlockId, opts) {
-        opts = Object.assign({
-            target: this._editingTarget,
-            stackClick: false
-        }, opts);
+        opts = Object.assign(
+            {
+                target: this._editingTarget,
+                stackClick: false
+            },
+            opts
+        );
         // Remove any existing thread.
         for (let i = 0; i < this.threads.length; i++) {
             // Toggling a script that's already running turns it off
-            if (this.threads[i].topBlock === topBlockId && this.threads[i].status !== Thread.STATUS_DONE) {
+            if (
+                this.threads[i].topBlock === topBlockId &&
+                this.threads[i].status !== Thread.STATUS_DONE
+            ) {
                 const blockContainer = opts.target.blocks;
-                const opcode = blockContainer.getOpcode(blockContainer.getBlock(topBlockId));
+                const opcode = blockContainer.getOpcode(
+                    blockContainer.getBlock(topBlockId)
+                );
 
-                if (this.getIsEdgeActivatedHat(opcode) && this.threads[i].stackClick !== opts.stackClick) {
+                if (
+                    this.getIsEdgeActivatedHat(opcode) &&
+                    this.threads[i].stackClick !== opts.stackClick
+                ) {
                     // Allow edge activated hat thread stack click to coexist with
                     // edge activated hat thread that runs every frame
                     continue;
@@ -1762,8 +1924,11 @@ class Runtime extends EventEmitter {
         if (!optTarget) optTarget = this._editingTarget;
         for (let i = 0; i < this.threads.length; i++) {
             // Don't re-add the script if it's already running
-            if (this.threads[i].topBlock === topBlockId && this.threads[i].status !== Thread.STATUS_DONE &&
-                    this.threads[i].updateMonitor) {
+            if (
+                this.threads[i].topBlock === topBlockId &&
+                this.threads[i].status !== Thread.STATUS_DONE &&
+                this.threads[i].updateMonitor
+            ) {
                 return;
             }
         }
@@ -1801,7 +1966,10 @@ class Runtime extends EventEmitter {
         }
         for (let t = targets.length - 1; t >= 0; t--) {
             const target = targets[t];
-            const scripts = BlocksRuntimeCache.getScripts(target.blocks, opcode);
+            const scripts = BlocksRuntimeCache.getScripts(
+                target.blocks,
+                opcode
+            );
             for (let j = 0; j < scripts.length; j++) {
                 f(scripts[j], target);
             }
@@ -1815,9 +1983,13 @@ class Runtime extends EventEmitter {
      * @param {Target=} optTarget Optionally, a target to restrict to.
      * @return {Array.<Thread>} List of threads started by this function.
      */
-    startHats (requestedHatOpcode,
-        optMatchFields, optTarget) {
-        if (!Object.prototype.hasOwnProperty.call(this._hats, requestedHatOpcode)) {
+    startHats (requestedHatOpcode, optMatchFields, optTarget) {
+        if (
+            !Object.prototype.hasOwnProperty.call(
+                this._hats,
+                requestedHatOpcode
+            )
+        ) {
             // No known hat with this opcode.
             return;
         }
@@ -1827,58 +1999,71 @@ class Runtime extends EventEmitter {
         const hatMeta = instance._hats[requestedHatOpcode];
 
         for (const opts in optMatchFields) {
-            if (!Object.prototype.hasOwnProperty.call(optMatchFields, opts)) continue;
+            if (!Object.prototype.hasOwnProperty.call(optMatchFields, opts)) {
+                continue;
+            }
             optMatchFields[opts] = optMatchFields[opts].toUpperCase();
         }
 
         // Consider all scripts, looking for hats with opcode `requestedHatOpcode`.
-        this.allScriptsByOpcodeDo(requestedHatOpcode, (script, target) => {
-            const {
-                blockId: topBlockId,
-                fieldsOfInputs: hatFields
-            } = script;
+        this.allScriptsByOpcodeDo(
+            requestedHatOpcode,
+            (script, target) => {
+                const {blockId: topBlockId, fieldsOfInputs: hatFields} =
+                    script;
 
-            // Match any requested fields.
-            // For example: ensures that broadcasts match.
-            // This needs to happen before the block is evaluated
-            // (i.e., before the predicate can be run) because "broadcast and wait"
-            // needs to have a precise collection of started threads.
-            for (const matchField in optMatchFields) {
-                if (hatFields[matchField].value !== optMatchFields[matchField]) {
-                    // Field mismatch.
-                    return;
-                }
-            }
-
-            if (hatMeta.restartExistingThreads) {
-                // If `restartExistingThreads` is true, we should stop
-                // any existing threads starting with the top block.
-                for (let i = 0; i < this.threads.length; i++) {
-                    if (this.threads[i].target === target &&
-                        this.threads[i].topBlock === topBlockId &&
-                        // stack click threads and hat threads can coexist
-                        !this.threads[i].stackClick) {
-                        newThreads.push(this._restartThread(this.threads[i]));
+                // Match any requested fields.
+                // For example: ensures that broadcasts match.
+                // This needs to happen before the block is evaluated
+                // (i.e., before the predicate can be run) because "broadcast and wait"
+                // needs to have a precise collection of started threads.
+                for (const matchField in optMatchFields) {
+                    if (
+                        hatFields[matchField].value !==
+                        optMatchFields[matchField]
+                    ) {
+                        // Field mismatch.
                         return;
                     }
                 }
-            } else {
-                // If `restartExistingThreads` is false, we should
-                // give up if any threads with the top block are running.
-                for (let j = 0; j < this.threads.length; j++) {
-                    if (this.threads[j].target === target &&
-                        this.threads[j].topBlock === topBlockId &&
-                        // stack click threads and hat threads can coexist
-                        !this.threads[j].stackClick &&
-                        this.threads[j].status !== Thread.STATUS_DONE) {
-                        // Some thread is already running.
-                        return;
+
+                if (hatMeta.restartExistingThreads) {
+                    // If `restartExistingThreads` is true, we should stop
+                    // any existing threads starting with the top block.
+                    for (let i = 0; i < this.threads.length; i++) {
+                        if (
+                            this.threads[i].target === target &&
+                            this.threads[i].topBlock === topBlockId &&
+                            // stack click threads and hat threads can coexist
+                            !this.threads[i].stackClick
+                        ) {
+                            newThreads.push(
+                                this._restartThread(this.threads[i])
+                            );
+                            return;
+                        }
+                    }
+                } else {
+                    // If `restartExistingThreads` is false, we should
+                    // give up if any threads with the top block are running.
+                    for (let j = 0; j < this.threads.length; j++) {
+                        if (
+                            this.threads[j].target === target &&
+                            this.threads[j].topBlock === topBlockId &&
+                            // stack click threads and hat threads can coexist
+                            !this.threads[j].stackClick &&
+                            this.threads[j].status !== Thread.STATUS_DONE
+                        ) {
+                            // Some thread is already running.
+                            return;
+                        }
                     }
                 }
-            }
-            // Start the thread with this top block.
-            newThreads.push(this._pushThread(topBlockId, target));
-        }, optTarget);
+                // Start the thread with this top block.
+                newThreads.push(this._pushThread(topBlockId, target));
+            },
+            optTarget
+        );
         // For compatibility with Scratch 2, edge triggered hats need to be processed before
         // threads are stepped. See ScratchRuntime.as for original implementation
         newThreads.forEach(thread => {
@@ -1888,7 +2073,6 @@ class Runtime extends EventEmitter {
         return newThreads;
     }
 
-
     /**
      * Dispose all targets. Return to clean state.
      */
@@ -1920,8 +2104,10 @@ class Runtime extends EventEmitter {
         const newCloudDataManager = cloudDataManager();
         this.hasCloudData = newCloudDataManager.hasCloudVariables;
         this.canAddCloudVariable = newCloudDataManager.canAddCloudVariable;
-        this.addCloudVariable = this._initializeAddCloudVariable(newCloudDataManager);
-        this.removeCloudVariable = this._initializeRemoveCloudVariable(newCloudDataManager);
+        this.addCloudVariable =
+            this._initializeAddCloudVariable(newCloudDataManager);
+        this.removeCloudVariable =
+            this._initializeRemoveCloudVariable(newCloudDataManager);
     }
 
     /**
@@ -1953,7 +2139,10 @@ class Runtime extends EventEmitter {
             newIndex = this.executableTargets.length;
         }
         if (newIndex <= 0) {
-            if (this.executableTargets.length > 0 && this.executableTargets[0].isStage) {
+            if (
+                this.executableTargets.length > 0 &&
+                this.executableTargets[0].isStage
+            ) {
                 newIndex = 1;
             } else {
                 newIndex = 0;
@@ -2033,7 +2222,10 @@ class Runtime extends EventEmitter {
         }
 
         const newRunId = uuid.v1();
-        this.storage.scratchFetch.setMetadata(this.storage.scratchFetch.RequestMetadata.RunId, newRunId);
+        this.storage.scratchFetch.setMetadata(
+            this.storage.scratchFetch.RequestMetadata.RunId,
+            newRunId
+        );
     }
 
     /**
@@ -2062,8 +2254,13 @@ class Runtime extends EventEmitter {
         const newTargets = [];
         for (let i = 0; i < this.targets.length; i++) {
             this.targets[i].onStopAll();
-            if (Object.prototype.hasOwnProperty.call(this.targets[i], 'isOriginal') &&
-                !this.targets[i].isOriginal) {
+            if (
+                Object.prototype.hasOwnProperty.call(
+                    this.targets[i],
+                    'isOriginal'
+                ) &&
+                !this.targets[i].isOriginal
+            ) {
                 this.targets[i].dispose();
             } else {
                 newTargets.push(this.targets[i]);
@@ -2097,7 +2294,9 @@ class Runtime extends EventEmitter {
 
         // Find all edge-activated hats, and add them to threads to be evaluated.
         for (const hatType in this._hats) {
-            if (!Object.prototype.hasOwnProperty.call(this._hats, hatType)) continue;
+            if (!Object.prototype.hasOwnProperty.call(this._hats, hatType)) {
+                continue;
+            }
             const hat = this._hats[hatType];
             if (hat.edgeActivated) {
                 this.startHats(hatType);
@@ -2107,7 +2306,9 @@ class Runtime extends EventEmitter {
         this._pushMonitors();
         if (this.profiler !== null) {
             if (stepThreadsProfilerId === -1) {
-                stepThreadsProfilerId = this.profiler.idByName('Sequencer.stepThreads');
+                stepThreadsProfilerId = this.profiler.idByName(
+                    'Sequencer.stepThreads'
+                );
             }
             this.profiler.start(stepThreadsProfilerId);
         }
@@ -2119,8 +2320,10 @@ class Runtime extends EventEmitter {
         // Add done threads so that even if a thread finishes within 1 frame, the green
         // flag will still indicate that a script ran.
         this._emitProjectRunStatus(
-            this.threads.length + doneThreads.length -
-                this._getMonitorThreadCount([...this.threads, ...doneThreads]));
+            this.threads.length +
+                doneThreads.length -
+                this._getMonitorThreadCount([...this.threads, ...doneThreads])
+        );
         // Store threads that completed this iteration for testing and other
         // internal purposes.
         this._lastStepDoneThreads = doneThreads;
@@ -2128,7 +2331,8 @@ class Runtime extends EventEmitter {
             // @todo: Only render when this.redrawRequested or clones rendered.
             if (this.profiler !== null) {
                 if (rendererDrawProfilerId === -1) {
-                    rendererDrawProfilerId = this.profiler.idByName('RenderWebGL.draw');
+                    rendererDrawProfilerId =
+                        this.profiler.idByName('RenderWebGL.draw');
                 }
                 this.profiler.start(rendererDrawProfilerId);
             }
@@ -2139,7 +2343,10 @@ class Runtime extends EventEmitter {
         }
 
         if (this._refreshTargets) {
-            this.emit(Runtime.TARGETS_UPDATE, false /* Don't emit project changed */);
+            this.emit(
+                Runtime.TARGETS_UPDATE,
+                false /* Don't emit project changed */
+            );
             this._refreshTargets = false;
         }
 
@@ -2226,12 +2433,12 @@ class Runtime extends EventEmitter {
             if (target === this._editingTarget) {
                 const blockForThread = thread.blockGlowInFrame;
                 if (thread.requestScriptGlowInFrame || thread.stackClick) {
-                    let script = target.blocks.getTopLevelScript(blockForThread);
+                    let script =
+                        target.blocks.getTopLevelScript(blockForThread);
                     if (!script) {
                         // Attempt to find in flyout blocks.
-                        script = this.flyoutBlocks.getTopLevelScript(
-                            blockForThread
-                        );
+                        script =
+                            this.flyoutBlocks.getTopLevelScript(blockForThread);
                     }
                     if (script) {
                         requestedGlowsThisFrame.push(script);
@@ -2349,7 +2556,8 @@ class Runtime extends EventEmitter {
      */
     requestAddMonitor (monitor) {
         const id = monitor.get('id');
-        if (!this.requestUpdateMonitor(monitor)) { // update monitor if it exists in the state
+        if (!this.requestUpdateMonitor(monitor)) {
+            // update monitor if it exists in the state
             // if the monitor did not exist in the state, add it
             this._monitorState = this._monitorState.set(id, monitor);
         }
@@ -2367,12 +2575,15 @@ class Runtime extends EventEmitter {
         if (this._monitorState.has(id)) {
             this._monitorState =
                 // Use mergeWith here to prevent undefined values from overwriting existing ones
-                this._monitorState.set(id, this._monitorState.get(id).mergeWith((prev, next) => {
-                    if (typeof next === 'undefined' || next === null) {
-                        return prev;
-                    }
-                    return next;
-                }, monitor));
+                this._monitorState.set(
+                    id,
+                    this._monitorState.get(id).mergeWith((prev, next) => {
+                        if (typeof next === 'undefined' || next === null) {
+                            return prev;
+                        }
+                        return next;
+                    }, monitor)
+                );
             return true;
         }
         return false;
@@ -2393,10 +2604,12 @@ class Runtime extends EventEmitter {
      * @return {boolean} true if monitor exists and was updated, false otherwise
      */
     requestHideMonitor (monitorId) {
-        return this.requestUpdateMonitor(new Map([
-            ['id', monitorId],
-            ['visible', false]
-        ]));
+        return this.requestUpdateMonitor(
+            new Map([
+                ['id', monitorId],
+                ['visible', false]
+            ])
+        );
     }
 
     /**
@@ -2406,10 +2619,12 @@ class Runtime extends EventEmitter {
      * @return {boolean} true if monitor exists and was updated, false otherwise
      */
     requestShowMonitor (monitorId) {
-        return this.requestUpdateMonitor(new Map([
-            ['id', monitorId],
-            ['visible', true]
-        ]));
+        return this.requestUpdateMonitor(
+            new Map([
+                ['id', monitorId],
+                ['visible', true]
+            ])
+        );
     }
 
     /**
@@ -2418,7 +2633,9 @@ class Runtime extends EventEmitter {
      * @param {!string} targetId Remove all monitors with given target ID.
      */
     requestRemoveMonitorByTargetId (targetId) {
-        this._monitorState = this._monitorState.filterNot(value => value.targetId === targetId);
+        this._monitorState = this._monitorState.filterNot(
+            value => value.targetId === targetId
+        );
     }
 
     /**
@@ -2538,7 +2755,10 @@ class Runtime extends EventEmitter {
     getAllVarNamesOfType (varType) {
         let varNames = [];
         for (const target of this.targets) {
-            const targetVarNames = target.getAllVariableNamesInScopeByType(varType, true);
+            const targetVarNames = target.getAllVariableNamesInScopeByType(
+                varType,
+                true
+            );
             varNames = varNames.concat(targetVarNames);
         }
         return varNames;
@@ -2579,7 +2799,8 @@ class Runtime extends EventEmitter {
      * @return {Variable} The new variable that was created.
      */
     createNewGlobalVariable (variableName, optVarId, optVarType) {
-        const varType = (typeof optVarType === 'string') ? optVarType : Variable.SCALAR_TYPE;
+        const varType =
+            typeof optVarType === 'string' ? optVarType : Variable.SCALAR_TYPE;
         const allVariableNames = this.getAllVarNamesOfType(varType);
         const newName = StringUtil.unusedName(variableName, allVariableNames);
         const variable = new Variable(optVarId || uid(), newName, varType);